summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJiyoung Yun <jy910.yun@samsung.com>2017-04-13 14:17:19 +0900
committerJiyoung Yun <jy910.yun@samsung.com>2017-04-13 14:17:19 +0900
commita56e30c8d33048216567753d9d3fefc2152af8ac (patch)
tree7e5d979695fc4a431740982eb1cfecc2898b23a5 /src
parent4b11dc566a5bbfa1378d6266525c281b028abcc8 (diff)
downloadcoreclr-a56e30c8d33048216567753d9d3fefc2152af8ac.tar.gz
coreclr-a56e30c8d33048216567753d9d3fefc2152af8ac.tar.bz2
coreclr-a56e30c8d33048216567753d9d3fefc2152af8ac.zip
Imported Upstream version 2.0.0.11353upstream/2.0.0.11353
Diffstat (limited to 'src')
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.builds90
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.pkgproj78
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/alpine/3.4.3/Microsoft.NETCore.ILAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/debian/Microsoft.NETCore.ILAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/fedora/23/Microsoft.NETCore.ILAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/fedora/24/Microsoft.NETCore.ILAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/linux/Microsoft.NETCore.ILAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/opensuse/13.2/Microsoft.NETCore.ILAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/opensuse/42.1/Microsoft.NETCore.ILAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/osx/Microsoft.NETCore.ILAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/rhel/Microsoft.NETCore.ILAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/runtime.Linux.Microsoft.NETCore.ILAsm.props6
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/runtime.OSX.Microsoft.NETCore.ILAsm.props6
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/runtime.Windows_NT.Microsoft.NETCore.ILAsm.props9
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/tizen/4.0.0/Microsoft.NETCore.ILAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/ubuntu/14.04/Microsoft.NETCore.ILAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/ubuntu/16.04/Microsoft.NETCore.ILAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/ubuntu/16.10/Microsoft.NETCore.ILAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILAsm/win/Microsoft.NETCore.ILAsm.pkgproj24
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.builds94
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.pkgproj77
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/alpine/3.4.3/Microsoft.NETCore.ILDAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/debian/Microsoft.NETCore.ILDAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/fedora/23/Microsoft.NETCore.ILDAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/fedora/24/Microsoft.NETCore.ILDAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/linux/Microsoft.NETCore.ILDAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/opensuse/13.2/Microsoft.NETCore.ILDAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/opensuse/42.1/Microsoft.NETCore.ILDAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/osx/Microsoft.NETCore.ILDAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/rhel/Microsoft.NETCore.ILDAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/runtime.Linux.Microsoft.NETCore.ILDAsm.props6
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/runtime.OSX.Microsoft.NETCore.ILDAsm.props6
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/runtime.Windows_NT.Microsoft.NETCore.ILDAsm.props10
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/tizen/4.0.0/Microsoft.NETCore.ILDAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/ubuntu/14.04/Microsoft.NETCore.ILDAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/ubuntu/16.04/Microsoft.NETCore.ILDAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/ubuntu/16.10/Microsoft.NETCore.ILDAsm.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.ILDAsm/win/Microsoft.NETCore.ILDAsm.pkgproj25
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.builds96
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.pkgproj81
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/alpine/3.4.3/Microsoft.NETCore.Jit.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/debian/Microsoft.NETCore.Jit.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/fedora/23/Microsoft.NETCore.Jit.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/fedora/24/Microsoft.NETCore.Jit.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/linux/Microsoft.NETCore.Jit.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/opensuse/13.2/Microsoft.NETCore.Jit.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/opensuse/42.1/Microsoft.NETCore.Jit.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/osx/Microsoft.NETCore.Jit.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/rhel/Microsoft.NETCore.Jit.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/runtime.Linux.Microsoft.NETCore.Jit.props6
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/runtime.OSX.Microsoft.NETCore.Jit.props6
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/runtime.Windows_NT.Microsoft.NETCore.Jit.props13
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/tizen/4.0.0/Microsoft.NETCore.Jit.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/ubuntu/14.04/Microsoft.NETCore.Jit.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/ubuntu/16.04/Microsoft.NETCore.Jit.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/ubuntu/16.10/Microsoft.NETCore.Jit.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/win/Microsoft.NETCore.Jit.pkgproj40
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.builds64
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.pkgproj53
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.props6
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/alpine/3.4.3/Microsoft.NETCore.Native.pkgproj30
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/debian/Microsoft.NETCore.Native.pkgproj30
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/fedora/23/Microsoft.NETCore.Native.pkgproj30
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/fedora/24/Microsoft.NETCore.Native.pkgproj30
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/linux/Microsoft.NETCore.Native.pkgproj30
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/opensuse/13.2/Microsoft.NETCore.Native.pkgproj30
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/opensuse/42.1/Microsoft.NETCore.Native.pkgproj30
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/osx/Microsoft.NETCore.Native.pkgproj30
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/rhel/Microsoft.NETCore.Native.pkgproj30
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/runtime.Linux.Microsoft.NETCore.Native.props7
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/runtime.OSX.Microsoft.NETCore.Native.props7
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/ubuntu/14.04/Microsoft.NETCore.Native.pkgproj30
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/ubuntu/16.04/Microsoft.NETCore.Native.pkgproj30
-rw-r--r--src/.nuget/Microsoft.NETCore.Native/ubuntu/16.10/Microsoft.NETCore.Native.pkgproj30
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.builds95
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.pkgproj80
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.props9
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/alpine/3.4.3/Microsoft.NETCore.Runtime.CoreCLR.pkgproj56
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/debian/Microsoft.NETCore.Runtime.CoreCLR.pkgproj56
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/fedora/23/Microsoft.NETCore.Runtime.CoreCLR.pkgproj56
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/fedora/24/Microsoft.NETCore.Runtime.CoreCLR.pkgproj56
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/linux/Microsoft.NETCore.Runtime.CoreCLR.pkgproj56
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/opensuse/13.2/Microsoft.NETCore.Runtime.CoreCLR.pkgproj56
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/opensuse/42.1/Microsoft.NETCore.Runtime.CoreCLR.pkgproj56
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/osx/Microsoft.NETCore.Runtime.CoreCLR.pkgproj54
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/rhel/Microsoft.NETCore.Runtime.CoreCLR.pkgproj56
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Linux.Microsoft.NETCore.Runtime.CoreCLR.props26
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.OSX.Microsoft.NETCore.Runtime.CoreCLR.props16
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Windows_NT.Microsoft.NETCore.Runtime.CoreCLR.props51
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/tizen/4.0.0/Microsoft.NETCore.Runtime.CoreCLR.pkgproj57
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/ubuntu/14.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj56
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/ubuntu/16.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj56
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/ubuntu/16.10/Microsoft.NETCore.Runtime.CoreCLR.pkgproj56
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/win/Microsoft.NETCore.Runtime.CoreCLR.pkgproj99
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.builds92
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.pkgproj74
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/alpine/3.4.3/Microsoft.NETCore.TestHost.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/debian/Microsoft.NETCore.TestHost.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/fedora/23/Microsoft.NETCore.TestHost.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/fedora/24/Microsoft.NETCore.TestHost.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/linux/Microsoft.NETCore.TestHost.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/opensuse/13.2/Microsoft.NETCore.TestHost.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/opensuse/42.1/Microsoft.NETCore.TestHost.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/osx/Microsoft.NETCore.TestHost.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/rhel/Microsoft.NETCore.TestHost.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/runtime.Linux.Microsoft.NETCore.TestHost.props6
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/runtime.OSX.Microsoft.NETCore.TestHost.props6
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/runtime.Windows_NT.Microsoft.NETCore.TestHost.props9
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/tizen/4.0.0/Microsoft.NETCore.TestHost.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/ubuntu/14.04/Microsoft.NETCore.TestHost.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/ubuntu/16.04/Microsoft.NETCore.TestHost.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/ubuntu/16.10/Microsoft.NETCore.TestHost.pkgproj29
-rw-r--r--src/.nuget/Microsoft.NETCore.TestHost/win/Microsoft.NETCore.TestHost.pkgproj24
-rw-r--r--src/.nuget/Microsoft.TargetingPack.Private.CoreCLR/Microsoft.TargetingPack.Private.CoreCLR.pkgproj4
-rw-r--r--src/.nuget/dir.props193
-rw-r--r--src/.nuget/dir.targets88
-rw-r--r--src/.nuget/dir.traversal.targets19
-rw-r--r--src/.nuget/init/project.json2
-rw-r--r--src/.nuget/packageIndex.json2
-rw-r--r--src/.nuget/packages.builds19
-rw-r--r--src/ToolBox/PdbTypeMatch/PdbTypeMatch.cpp2023
-rw-r--r--src/ToolBox/PdbTypeMatch/PdbTypeMatch.h69
-rw-r--r--src/ToolBox/PdbTypeMatch/PrintSymbol.cpp2254
-rw-r--r--src/ToolBox/PdbTypeMatch/PrintSymbol.h66
-rw-r--r--src/ToolBox/PdbTypeMatch/callback.h96
-rw-r--r--src/ToolBox/PdbTypeMatch/include/cvconst.h3181
-rw-r--r--src/ToolBox/PdbTypeMatch/include/dia2.h7854
-rw-r--r--src/ToolBox/PdbTypeMatch/include/diacreate.h40
-rw-r--r--src/ToolBox/PdbTypeMatch/native.rc8
-rw-r--r--src/ToolBox/PdbTypeMatch/regs.cpp1708
-rw-r--r--src/ToolBox/PdbTypeMatch/regs.h23
-rw-r--r--src/ToolBox/PdbTypeMatch/stdafx.cpp9
-rw-r--r--src/ToolBox/PdbTypeMatch/stdafx.h25
-rw-r--r--src/ToolBox/SOS/NETCore/SOS.NETCore.csproj10
-rw-r--r--src/ToolBox/SOS/NETCore/SymbolReader.cs37
-rw-r--r--src/ToolBox/SOS/NETCore/project.json6
-rw-r--r--src/ToolBox/SOS/Strike/disasm.h3
-rw-r--r--src/ToolBox/SOS/Strike/gcroot.cpp4
-rw-r--r--src/ToolBox/SOS/Strike/sos.cpp2
-rw-r--r--src/ToolBox/SOS/Strike/sos_md.h2
-rw-r--r--src/ToolBox/SOS/Strike/strike.cpp12
-rw-r--r--src/ToolBox/SOS/Strike/util.cpp4
-rw-r--r--src/ToolBox/SOS/lldbplugin/CMakeLists.txt13
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h4
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h44
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/lwmlist.h1
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp50
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.h20
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp20
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp18
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp17
-rw-r--r--src/ToolBox/superpmi/superpmi/icorjitinfo.cpp19
-rw-r--r--src/binder/applicationcontext.cpp2
-rw-r--r--src/binder/assemblybinder.cpp16
-rw-r--r--src/binder/bindinglog.cpp2
-rw-r--r--src/binder/clrprivbinderassemblyloadcontext.cpp4
-rw-r--r--src/binder/clrprivbindercoreclr.cpp12
-rw-r--r--src/binder/coreclrbindercommon.cpp4
-rw-r--r--src/binder/inc/applicationcontext.hpp2
-rw-r--r--src/binder/inc/assembly.hpp12
-rw-r--r--src/binder/inc/assemblybinder.hpp12
-rw-r--r--src/binder/inc/clrprivbinderassemblyloadcontext.h4
-rw-r--r--src/binder/inc/clrprivbindercoreclr.h4
-rw-r--r--src/binder/inc/fusionhelpers.hpp6
-rw-r--r--src/binder/inc/list.hpp2
-rw-r--r--src/build.proj7
-rw-r--r--src/classlibnative/bcltype/arraynative.cpp99
-rw-r--r--src/classlibnative/bcltype/arraynative.inl329
-rw-r--r--src/classlibnative/bcltype/number.cpp53
-rw-r--r--src/classlibnative/bcltype/number.h3
-rw-r--r--src/classlibnative/bcltype/objectnative.cpp11
-rw-r--r--src/classlibnative/bcltype/stringnative.cpp5
-rw-r--r--src/classlibnative/bcltype/system.cpp306
-rw-r--r--src/classlibnative/bcltype/system.h24
-rw-r--r--src/classlibnative/float/floatdouble.cpp27
-rw-r--r--src/classlibnative/float/floatsingle.cpp69
-rw-r--r--src/classlibnative/inc/calendardata.h165
-rw-r--r--src/classlibnative/inc/floatsingle.h38
-rw-r--r--src/classlibnative/inc/nlsinfo.h169
-rw-r--r--src/classlibnative/inc/nlstable.h121
-rw-r--r--src/classlibnative/nls/CMakeLists.txt2
-rw-r--r--src/classlibnative/nls/calendardata.cpp985
-rw-r--r--src/classlibnative/nls/encodingdata.cpp579
-rw-r--r--src/classlibnative/nls/nlsinfo.cpp3203
-rw-r--r--src/classlibnative/nls/nlstable.cpp259
-rw-r--r--src/coreclr/hosts/unixcoreconsole/CMakeLists.txt4
-rw-r--r--src/coreclr/hosts/unixcoreconsole/coreconsole.cpp13
-rw-r--r--src/coreclr/hosts/unixcorerun/CMakeLists.txt4
-rw-r--r--src/coreclr/hosts/unixcorerun/corerun.cpp2
-rw-r--r--src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp21
-rw-r--r--src/corefx/System.Globalization.Native/CMakeLists.txt36
-rw-r--r--src/corefx/System.Globalization.Native/collation.cpp10
-rw-r--r--src/corefx/System.Globalization.Native/icushim.cpp93
-rw-r--r--src/corefx/System.Globalization.Native/icushim.h9
-rw-r--r--src/debug/daccess/CMakeLists.txt25
-rw-r--r--src/debug/daccess/daccess.cpp9
-rw-r--r--src/debug/daccess/dacdbiimpl.cpp113
-rw-r--r--src/debug/daccess/dacdbiimplstackwalk.cpp6
-rw-r--r--src/debug/daccess/dacfn.cpp8
-rw-r--r--src/debug/daccess/enummem.cpp22
-rw-r--r--src/debug/daccess/gcinterface.dac.h5
-rw-r--r--src/debug/daccess/inspect.cpp10
-rw-r--r--src/debug/daccess/nidump.cpp310
-rw-r--r--src/debug/daccess/request.cpp172
-rw-r--r--src/debug/daccess/request_common.h58
-rw-r--r--src/debug/daccess/request_svr.cpp171
-rw-r--r--src/debug/daccess/stdafx.h3
-rw-r--r--src/debug/debug-pal/unix/twowaypipe.cpp5
-rw-r--r--src/debug/di/cordb.cpp10
-rw-r--r--src/debug/di/platformspecific.cpp2
-rw-r--r--src/debug/di/process.cpp115
-rw-r--r--src/debug/di/rsmain.cpp10
-rw-r--r--src/debug/di/rsmda.cpp23
-rw-r--r--src/debug/di/rspriv.h2
-rw-r--r--src/debug/di/shimprocess.cpp4
-rw-r--r--src/debug/ee/arm64/dbghelpers.S55
-rw-r--r--src/debug/ee/controller.h2
-rw-r--r--src/debug/ee/dactable.cpp12
-rw-r--r--src/debug/ee/debugger.cpp124
-rw-r--r--src/debug/ee/debugger.h6
-rw-r--r--src/debug/ee/debugger.inl2
-rw-r--r--src/debug/ee/frameinfo.cpp23
-rw-r--r--src/debug/ee/funceval.cpp3
-rw-r--r--src/debug/ee/stdafx.h4
-rw-r--r--src/debug/ee/wks/CMakeLists.txt2
-rw-r--r--src/debug/inc/dacdbiinterface.h3
-rw-r--r--src/debug/inc/dbgappdomain.h8
-rw-r--r--src/dlls/dbgshim/dbgshim.cpp4
-rw-r--r--src/dlls/mscordac/CMakeLists.txt33
-rw-r--r--src/dlls/mscordac/GetFileVersion.dllbin5120 -> 0 bytes
-rw-r--r--src/dlls/mscordbi/mscordbi.src2
-rw-r--r--src/dlls/mscoree/coreclr/CMakeLists.txt21
-rw-r--r--src/dlls/mscoree/coreclr/README.md7
-rw-r--r--src/dlls/mscoree/coreclr/dump_helper_resource.binbin0 -> 17 bytes
-rw-r--r--src/dlls/mscoree/mscoree.cpp24
-rw-r--r--src/dlls/mscoree/mscorwks_ntdef.src168
-rw-r--r--src/dlls/mscorrc/fuslog.rc290
-rw-r--r--src/dlls/mscorrc/fusres.h249
-rw-r--r--src/dlls/mscorrc/include.rc1
-rw-r--r--src/dlls/mscorrc/mscorrc.rc41
-rw-r--r--src/dlls/mscorrc/nativelog.rc32
-rw-r--r--src/dlls/mscorrc/nativeres.h35
-rw-r--r--src/dlls/mscorrc/resource.h13
-rw-r--r--src/gc/CMakeLists.txt1
-rw-r--r--src/gc/env/gcenv.base.h13
-rw-r--r--src/gc/env/gcenv.ee.h6
-rw-r--r--src/gc/env/gcenv.structs.h2
-rw-r--r--src/gc/gc.cpp1520
-rw-r--r--src/gc/gc.h90
-rw-r--r--src/gc/gccommon.cpp73
-rw-r--r--src/gc/gcee.cpp25
-rw-r--r--src/gc/gceesvr.cpp2
-rw-r--r--src/gc/gceewks.cpp1
-rw-r--r--src/gc/gcenv.ee.standalone.inl29
-rw-r--r--src/gc/gchandletable.cpp111
-rw-r--r--src/gc/gchandletableimpl.h48
-rw-r--r--src/gc/gcimpl.h54
-rw-r--r--src/gc/gcinterface.dac.h156
-rw-r--r--src/gc/gcinterface.dacvars.def66
-rw-r--r--src/gc/gcinterface.ee.h33
-rw-r--r--src/gc/gcinterface.h320
-rw-r--r--src/gc/gcpriv.h271
-rw-r--r--src/gc/gcscan.cpp17
-rw-r--r--src/gc/gcscan.h12
-rw-r--r--src/gc/handletable.cpp22
-rw-r--r--src/gc/handletable.h23
-rw-r--r--src/gc/objecthandle.cpp91
-rw-r--r--src/gc/objecthandle.h537
-rw-r--r--src/gc/sample/CMakeLists.txt1
-rw-r--r--src/gc/sample/GCSample.cpp34
-rw-r--r--src/gc/sample/gcenv.ee.cpp32
-rw-r--r--src/gc/unix/CMakeLists.txt3
-rw-r--r--src/gc/unix/cgroup.cpp342
-rw-r--r--src/gc/unix/gcenv.unix.cpp25
-rw-r--r--src/gc/windows/gcenv.windows.cpp3
-rw-r--r--src/gcdump/i386/gcdumpx86.cpp3
-rw-r--r--src/ilasm/asmman.cpp265
-rw-r--r--src/ilasm/asmman.hpp10
-rw-r--r--src/ilasm/asmtemplates.h49
-rw-r--r--src/ilasm/assem.cpp14
-rw-r--r--src/ilasm/assembler.cpp38
-rw-r--r--src/ilasm/assembler.h9
-rw-r--r--src/ilasm/grammar_after.cpp12
-rw-r--r--src/ilasm/grammar_before.cpp12
-rw-r--r--src/ilasm/main.cpp38
-rw-r--r--src/ilasm/method.cpp20
-rw-r--r--src/ilasm/writer.cpp285
-rw-r--r--src/ilasm/writer_enc.cpp59
-rw-r--r--src/ildasm/dasm.cpp57
-rw-r--r--src/inc/CMakeLists.txt1
-rw-r--r--src/inc/CrstTypes.def6
-rw-r--r--src/inc/MSCOREE.IDL1353
-rw-r--r--src/inc/apithreadstress.h33
-rw-r--r--src/inc/appxutil.h93
-rw-r--r--src/inc/binderngen.idl1
-rw-r--r--src/inc/clrconfig.h10
-rw-r--r--src/inc/clrconfigvalues.h50
-rw-r--r--src/inc/clrhost.h2
-rw-r--r--src/inc/clrinternal.idl195
-rw-r--r--src/inc/clrnt.h2
-rw-r--r--src/inc/clrprivbinderutil.h125
-rw-r--r--src/inc/clrtypes.h2
-rw-r--r--src/inc/cor.h15
-rw-r--r--src/inc/corbbtprof.h27
-rw-r--r--src/inc/corcompile.h107
-rw-r--r--src/inc/coregen.h1
-rw-r--r--src/inc/corhdr.h1
-rw-r--r--src/inc/corhost.h697
-rw-r--r--src/inc/corinfo.h149
-rw-r--r--src/inc/corjit.h93
-rw-r--r--src/inc/corpolicy.h40
-rw-r--r--src/inc/corpriv.h171
-rw-r--r--src/inc/corprof.idl9
-rw-r--r--src/inc/crosscomp.h4
-rw-r--r--src/inc/crsttypes.h260
-rw-r--r--src/inc/daccess.h9
-rw-r--r--src/inc/dacprivate.h23
-rw-r--r--src/inc/dacvars.h72
-rw-r--r--src/inc/eetwain.h5
-rw-r--r--src/inc/eventtracebase.h10
-rw-r--r--src/inc/formattype.cpp2
-rw-r--r--src/inc/fusion.idl288
-rw-r--r--src/inc/fusionbind.h316
-rw-r--r--src/inc/fusionpriv.idl970
-rw-r--r--src/inc/fusionsink.h129
-rw-r--r--src/inc/gchost.idl95
-rw-r--r--src/inc/holder.h31
-rw-r--r--src/inc/jithelpers.h44
-rw-r--r--src/inc/legacyactivationshim.h1382
-rw-r--r--src/inc/legacyactivationshimdelayload.h13
-rw-r--r--src/inc/loglf.h66
-rw-r--r--src/inc/longfilepathwrappers.h115
-rw-r--r--src/inc/metadatatracker.h2
-rw-r--r--src/inc/mscoruef.idl117
-rw-r--r--src/inc/newapis.h16
-rw-r--r--src/inc/palclr_win.h61
-rw-r--r--src/inc/profilepriv.h4
-rw-r--r--src/inc/readytorun.h15
-rw-r--r--src/inc/readytorunhelpers.h2
-rw-r--r--src/inc/regdisp.h67
-rw-r--r--src/inc/registrywrapper.h28
-rw-r--r--src/inc/shimload.h11
-rw-r--r--src/inc/stacktrace.h6
-rw-r--r--src/inc/stdmacros.h2
-rw-r--r--src/inc/stgpool.h15
-rw-r--r--src/inc/switches.h37
-rw-r--r--src/inc/tlbutils.h52
-rw-r--r--src/inc/utilcode.h250
-rw-r--r--src/inc/volatile.h2
-rw-r--r--src/inc/vptr_list.h30
-rw-r--r--src/inc/winrt/windowsruntime.h17
-rw-r--r--src/inc/winwrap.h13
-rw-r--r--src/inc/zapper.h116
-rw-r--r--src/ipcman/ipcfunccallimpl.cpp618
-rw-r--r--src/ipcman/ipcsharedsrc.cpp75
-rw-r--r--src/ipcman/ipcwriterimpl.cpp56
-rw-r--r--src/jit/CMakeLists.txt166
-rw-r--r--src/jit/DIRS.proj4
-rw-r--r--src/jit/ICorJitInfo_API_wrapper.hpp48
-rwxr-xr-xsrc/jit/_typeinfo.h51
-rw-r--r--src/jit/assertionprop.cpp355
-rw-r--r--src/jit/bitset.cpp4
-rw-r--r--src/jit/bitsetasshortlong.h137
-rw-r--r--src/jit/block.h226
-rwxr-xr-xsrc/jit/codegen.h74
-rw-r--r--src/jit/codegenarm.cpp1728
-rw-r--r--src/jit/codegenarm64.cpp1824
-rw-r--r--src/jit/codegenarmarch.cpp1687
-rw-r--r--src/jit/codegenclassic.h8
-rw-r--r--src/jit/codegencommon.cpp265
-rw-r--r--src/jit/codegeninterface.h2
-rw-r--r--src/jit/codegenlegacy.cpp232
-rw-r--r--src/jit/codegenlinear.cpp72
-rw-r--r--src/jit/codegenlinear.h62
-rw-r--r--src/jit/codegenxarch.cpp345
-rw-r--r--src/jit/compatjit/.gitmirror1
-rw-r--r--src/jit/compatjit/CMakeLists.txt66
-rw-r--r--src/jit/compiler.cpp126
-rw-r--r--src/jit/compiler.h333
-rw-r--r--src/jit/compiler.hpp61
-rw-r--r--src/jit/compilerbitsettraits.h8
-rw-r--r--src/jit/compilerbitsettraits.hpp16
-rw-r--r--src/jit/compphases.h125
-rw-r--r--src/jit/crossgen/CMakeLists.txt2
-rw-r--r--src/jit/decomposelongs.cpp210
-rw-r--r--src/jit/dll/CMakeLists.txt20
-rw-r--r--src/jit/ee_il_dll.cpp185
-rw-r--r--src/jit/ee_il_dll.hpp4
-rw-r--r--src/jit/emit.cpp81
-rw-r--r--src/jit/emit.h53
-rw-r--r--src/jit/emitarm.cpp349
-rw-r--r--src/jit/emitarm.h17
-rw-r--r--src/jit/emitarm64.cpp18
-rw-r--r--src/jit/emitarm64.h4
-rw-r--r--src/jit/emitinl.h6
-rw-r--r--src/jit/emitxarch.cpp354
-rw-r--r--src/jit/emitxarch.h53
-rw-r--r--src/jit/flowgraph.cpp1491
-rw-r--r--src/jit/gcencode.cpp102
-rw-r--r--src/jit/gentree.cpp1379
-rw-r--r--src/jit/gentree.h288
-rw-r--r--src/jit/gtlist.h10
-rw-r--r--src/jit/importer.cpp1101
-rw-r--r--src/jit/inline.def2
-rw-r--r--src/jit/inline.h52
-rw-r--r--src/jit/instr.cpp92
-rw-r--r--src/jit/instrsxarch.h16
-rw-r--r--src/jit/jit.h60
-rw-r--r--src/jit/jit.settings.targets6
-rw-r--r--src/jit/jitconfigvalues.h50
-rw-r--r--src/jit/jitee.h72
-rw-r--r--src/jit/jitgcinfo.h6
-rw-r--r--src/jit/jitpch.h4
-rw-r--r--src/jit/jitstd/type_traits.h5
-rw-r--r--src/jit/lclvars.cpp596
-rw-r--r--src/jit/legacyjit/CMakeLists.txt62
-rw-r--r--src/jit/legacynonjit/.gitmirror (renamed from src/ToolBox/PdbTypeMatch/.gitmirror)0
-rw-r--r--src/jit/legacynonjit/CMakeLists.txt67
-rw-r--r--src/jit/legacynonjit/legacynonjit.def7
-rw-r--r--src/jit/linuxnonjit/CMakeLists.txt71
-rw-r--r--src/jit/liveness.cpp18
-rw-r--r--src/jit/lower.cpp205
-rw-r--r--src/jit/lower.h2
-rw-r--r--src/jit/lowerarm.cpp183
-rw-r--r--src/jit/lowerarm64.cpp298
-rw-r--r--src/jit/lowerarmarch.cpp346
-rw-r--r--src/jit/lsra.cpp218
-rw-r--r--src/jit/lsra.h7
-rw-r--r--src/jit/lsraarm.cpp836
-rw-r--r--src/jit/lsraarm64.cpp765
-rw-r--r--src/jit/lsraarmarch.cpp868
-rw-r--r--src/jit/lsraxarch.cpp221
-rw-r--r--src/jit/morph.cpp629
-rw-r--r--src/jit/optcse.cpp200
-rw-r--r--src/jit/optimizer.cpp22
-rw-r--r--src/jit/protojit/CMakeLists.txt1
-rw-r--r--src/jit/protononjit/.gitmirror (renamed from src/ToolBox/PdbTypeMatch/include/.gitmirror)0
-rw-r--r--src/jit/protononjit/CMakeLists.txt84
-rw-r--r--src/jit/protononjit/SOURCES10
-rw-r--r--src/jit/protononjit/makefile7
-rw-r--r--src/jit/protononjit/protononjit.def7
-rw-r--r--src/jit/protononjit/protononjit.nativeproj86
-rw-r--r--src/jit/rangecheck.cpp17
-rw-r--r--src/jit/rationalize.cpp29
-rw-r--r--src/jit/regalloc.cpp2
-rw-r--r--src/jit/registerfp.cpp2
-rw-r--r--src/jit/regset.cpp11
-rw-r--r--src/jit/regset.h2
-rw-r--r--src/jit/simd.cpp15
-rw-r--r--src/jit/simdcodegenxarch.cpp38
-rw-r--r--src/jit/stackfp.cpp2
-rw-r--r--src/jit/standalone/CMakeLists.txt1
-rw-r--r--src/jit/target.h51
-rw-r--r--src/jit/unwind.h24
-rw-r--r--src/jit/unwindamd64.cpp12
-rw-r--r--src/jit/utils.cpp75
-rw-r--r--src/jit/utils.h11
-rw-r--r--src/jit/valuenum.cpp375
-rw-r--r--src/jit/valuenum.h23
-rw-r--r--src/jit/valuenumfuncs.h1
-rw-r--r--src/md/compiler/classfactory.cpp8
-rw-r--r--src/md/compiler/disp.cpp36
-rw-r--r--src/md/compiler/mdperf.h1
-rw-r--r--src/md/compiler/mdsighelper.h6
-rw-r--r--src/md/compiler/mdutil.cpp4
-rw-r--r--src/md/compiler/mdutil.h4
-rw-r--r--src/md/compiler/mdvalidator.cpp152
-rw-r--r--src/md/compiler/newmerger.cpp6303
-rw-r--r--src/md/compiler/newmerger.h256
-rw-r--r--src/md/compiler/regmeta.cpp32
-rw-r--r--src/md/compiler/regmeta.h21
-rw-r--r--src/md/compiler/regmeta_compilersupport.cpp274
-rw-r--r--src/md/compiler/regmeta_emit.cpp75
-rw-r--r--src/md/compiler/regmeta_vm.cpp179
-rw-r--r--src/md/compiler/wks/CMakeLists.txt4
-rw-r--r--src/md/enc/imptlb.cpp8057
-rw-r--r--src/md/enc/liteweightstgdbrw.cpp28
-rw-r--r--src/md/enc/metamodelenc.cpp25
-rw-r--r--src/md/enc/metamodelrw.cpp25
-rw-r--r--src/md/enc/rwutil.cpp143
-rw-r--r--src/md/enc/stgio.cpp38
-rw-r--r--src/md/enc/stgtiggerstorage.cpp4
-rw-r--r--src/md/enc/wks/CMakeLists.txt2
-rw-r--r--src/md/hotdata/hotdataformat.h2
-rw-r--r--src/md/inc/assemblymdinternaldisp.h705
-rw-r--r--src/md/inc/imptlb.h777
-rw-r--r--src/md/inc/liteweightstgdb.h2
-rw-r--r--src/md/inc/metamodelrw.h4
-rw-r--r--src/md/inc/rwutil.h24
-rw-r--r--src/md/inc/stgio.h4
-rw-r--r--src/md/inc/winmdinterfaces.h8
-rw-r--r--src/md/md_wks.cmake2
-rw-r--r--src/md/runtime/mdfileformat.cpp2
-rw-r--r--src/md/runtime/mdinternaldisp.cpp1614
-rw-r--r--src/md/runtime/metamodel.cpp2
-rw-r--r--src/md/runtime/wks/CMakeLists.txt2
-rw-r--r--src/md/winmd/adapter.cpp2
-rw-r--r--src/md/winmd/inc/adapter.h6
-rw-r--r--src/md/winmd/wks/CMakeLists.txt4
-rw-r--r--src/mscorlib/Common/NotImplemented.cs34
-rw-r--r--src/mscorlib/Common/PinnableBufferCache.cs34
-rw-r--r--src/mscorlib/Common/Preprocessed/AssemblyRefs.g.cs18
-rw-r--r--src/mscorlib/Common/System/SR.cs197
-rw-r--r--src/mscorlib/GenerateSplitStringResources.targets8
-rw-r--r--src/mscorlib/PinvokeAnalyzerExceptionList.analyzerdata3
-rw-r--r--src/mscorlib/Resources/Strings.resx3611
-rw-r--r--src/mscorlib/System.Private.CoreLib.csproj1731
-rw-r--r--src/mscorlib/System.Private.CoreLib.sln26
-rw-r--r--src/mscorlib/corefx/Debug.cs29
-rw-r--r--src/mscorlib/corefx/Interop/Unix/Interop.Libraries.cs12
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs69
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.GetCwd.cs74
-rw-r--r--src/mscorlib/corefx/Interop/Unix/System.Native/Interop.GetUnixName.cs21
-rw-r--r--src/mscorlib/corefx/Interop/Windows/BCrypt/Interop.BCryptGenRandom.cs26
-rw-r--r--src/mscorlib/corefx/Interop/Windows/BCrypt/Interop.NTSTATUS.cs19
-rw-r--r--src/mscorlib/corefx/Interop/Windows/Interop.Errors.cs71
-rw-r--r--src/mscorlib/corefx/Interop/Windows/Interop.Libraries.cs15
-rw-r--r--src/mscorlib/corefx/Interop/Windows/NtDll/Interop.ZeroMemory.cs17
-rw-r--r--src/mscorlib/corefx/Interop/Windows/kernel32/Interop.CreateFile.cs40
-rw-r--r--src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FileOperations.cs12
-rw-r--r--src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetFileInformationByHandleEx.cs26
-rw-r--r--src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetLongPathNameW.cs18
-rw-r--r--src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetTempFileNameW.cs16
-rw-r--r--src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetTempPathW.cs16
-rw-r--r--src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SafeCreateFile.cs45
-rw-r--r--src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetErrorMode.cs14
-rw-r--r--src/mscorlib/corefx/Interop/Windows/kernel32/Interop.UnsafeCreateFile.cs25
-rw-r--r--src/mscorlib/corefx/Interop/Windows/kernel32/Interop.WideCharToMultiByte.cs22
-rw-r--r--src/mscorlib/corefx/Interop/Windows/kernel32/Interop.WriteFile_SafeHandle_IntPtr.cs24
-rw-r--r--src/mscorlib/corefx/Interop/Windows/oleaut32/Interop.SysAllocStringLen.cs16
-rw-r--r--src/mscorlib/corefx/Interop/Windows/oleaut32/Interop.SysStringLen.cs22
-rw-r--r--src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeThreadPoolIOHandle.cs28
-rw-r--r--src/mscorlib/corefx/SR.cs818
-rw-r--r--src/mscorlib/corefx/System/Buffers/Utilities.cs35
-rw-r--r--src/mscorlib/corefx/System/Globalization/Calendar.cs859
-rw-r--r--src/mscorlib/corefx/System/Globalization/CalendarAlgorithmType.cs20
-rw-r--r--src/mscorlib/corefx/System/Globalization/CalendarData.Unix.cs335
-rw-r--r--src/mscorlib/corefx/System/Globalization/CalendarData.Windows.cs469
-rw-r--r--src/mscorlib/corefx/System/Globalization/CalendarData.cs377
-rw-r--r--src/mscorlib/corefx/System/Globalization/CalendarWeekRule.cs18
-rw-r--r--src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs391
-rw-r--r--src/mscorlib/corefx/System/Globalization/ChineseLunisolarCalendar.cs395
-rw-r--r--src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs397
-rw-r--r--src/mscorlib/corefx/System/Globalization/CompareInfo.Windows.cs415
-rw-r--r--src/mscorlib/corefx/System/Globalization/CompareInfo.cs1094
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureData.Unix.cs419
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureData.Windows.cs672
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureData.cs2470
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureInfo.Unix.cs31
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureInfo.Windows.cs57
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureInfo.cs1558
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureNotFoundException.cs122
-rw-r--r--src/mscorlib/corefx/System/Globalization/CultureTypes.cs28
-rw-r--r--src/mscorlib/corefx/System/Globalization/DateTimeFormatInfo.cs3087
-rw-r--r--src/mscorlib/corefx/System/Globalization/DateTimeFormatInfoScanner.cs742
-rw-r--r--src/mscorlib/corefx/System/Globalization/DayLightTime.cs53
-rw-r--r--src/mscorlib/corefx/System/Globalization/DigitShapes.cs18
-rw-r--r--src/mscorlib/corefx/System/Globalization/EastAsianLunisolarCalendar.cs717
-rw-r--r--src/mscorlib/corefx/System/Globalization/GregorianCalendar.cs666
-rw-r--r--src/mscorlib/corefx/System/Globalization/GregorianCalendarHelper.cs668
-rw-r--r--src/mscorlib/corefx/System/Globalization/GregorianCalendarTypes.cs21
-rw-r--r--src/mscorlib/corefx/System/Globalization/HebrewNumber.cs458
-rw-r--r--src/mscorlib/corefx/System/Globalization/HijriCalendar.Win32.cs96
-rw-r--r--src/mscorlib/corefx/System/Globalization/HijriCalendar.cs679
-rw-r--r--src/mscorlib/corefx/System/Globalization/IdnMapping.Unix.cs134
-rw-r--r--src/mscorlib/corefx/System/Globalization/IdnMapping.Windows.cs113
-rw-r--r--src/mscorlib/corefx/System/Globalization/IdnMapping.cs152
-rw-r--r--src/mscorlib/corefx/System/Globalization/InternalGlobalizationHelper.cs50
-rw-r--r--src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Unix.cs88
-rw-r--r--src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Win32.cs209
-rw-r--r--src/mscorlib/corefx/System/Globalization/JapaneseCalendar.cs411
-rw-r--r--src/mscorlib/corefx/System/Globalization/JapaneseLunisolarCalendar.cs311
-rw-r--r--src/mscorlib/corefx/System/Globalization/JulianCalendar.cs444
-rw-r--r--src/mscorlib/corefx/System/Globalization/KoreanCalendar.cs267
-rw-r--r--src/mscorlib/corefx/System/Globalization/KoreanLunisolarCalendar.cs1329
-rw-r--r--src/mscorlib/corefx/System/Globalization/NumberFormatInfo.cs900
-rw-r--r--src/mscorlib/corefx/System/Globalization/PersianCalendar.cs611
-rw-r--r--src/mscorlib/corefx/System/Globalization/RegionInfo.cs421
-rw-r--r--src/mscorlib/corefx/System/Globalization/SortKey.cs208
-rw-r--r--src/mscorlib/corefx/System/Globalization/SortVersion.cs101
-rw-r--r--src/mscorlib/corefx/System/Globalization/StringInfo.cs374
-rw-r--r--src/mscorlib/corefx/System/Globalization/TaiwanLunisolarCalendar.cs330
-rw-r--r--src/mscorlib/corefx/System/Globalization/TextElementEnumerator.cs153
-rw-r--r--src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs126
-rw-r--r--src/mscorlib/corefx/System/Globalization/TextInfo.Windows.cs121
-rw-r--r--src/mscorlib/corefx/System/Globalization/TextInfo.cs746
-rw-r--r--src/mscorlib/corefx/System/Globalization/UmAlQuraCalendar.cs870
-rw-r--r--src/mscorlib/corefx/System/Globalization/UnicodeCategory.cs70
-rw-r--r--src/mscorlib/corefx/System/IO/Error.cs44
-rw-r--r--src/mscorlib/corefx/System/IO/FileStream.Unix.cs934
-rw-r--r--src/mscorlib/corefx/System/IO/FileStream.Win32.cs1770
-rw-r--r--src/mscorlib/corefx/System/IO/FileStreamCompletionSource.Win32.cs221
-rw-r--r--src/mscorlib/corefx/System/IO/Path.Unix.cs216
-rw-r--r--src/mscorlib/corefx/System/IO/Path.Win32.cs36
-rw-r--r--src/mscorlib/corefx/System/IO/Path.Windows.cs155
-rw-r--r--src/mscorlib/corefx/System/IO/Path.cs575
-rw-r--r--src/mscorlib/corefx/System/IO/PathInternal.Windows.cs442
-rw-r--r--src/mscorlib/corefx/System/IO/PathInternal.cs172
-rw-r--r--src/mscorlib/corefx/System/Security/SafeBSTRHandle.cs81
-rw-r--r--src/mscorlib/corefx/System/Security/SecureString.Windows.cs310
-rw-r--r--src/mscorlib/facade/mscorlib.csproj110
-rw-r--r--src/mscorlib/facade/project.json16
-rw-r--r--src/mscorlib/ref/mscorlib.cs13779
-rw-r--r--src/mscorlib/ref/mscorlib.csproj86
-rw-r--r--src/mscorlib/ref/mscorlib.manual.cs785
-rw-r--r--src/mscorlib/shared/Interop/Unix/Interop.Errors.cs (renamed from src/mscorlib/corefx/Interop/Unix/Interop.Errors.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/Interop.IOErrors.cs (renamed from src/mscorlib/corefx/Interop/Unix/Interop.IOErrors.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/Interop.Libraries.cs12
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Casing.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Casing.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Idna.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Idna.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Locale.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Locale.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Utils.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Utils.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.Close.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Close.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.FLock.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FLock.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.FSync.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FSync.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.FTruncate.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FTruncate.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.GetCwd.cs74
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.GetRandomBytes.cs21
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.LSeek.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.LSeek.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.LockFileRegion.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Fcntl.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.MksTemps.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.MksTemps.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.Open.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Open.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.OpenFlags.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.OpenFlags.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.PathConf.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.PathConf.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.Permissions.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Permissions.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.PosixFAdvise.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.PosixFAdvise.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.Read.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Read.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.Stat.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Stat.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.SysLog.cs58
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.Unlink.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Unlink.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Native/Interop.Write.cs (renamed from src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Write.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/BCrypt/Interop.BCryptGenRandom.cs44
-rw-r--r--src/mscorlib/shared/Interop/Windows/Crypt32/Interop.CryptProtectMemory.cs (renamed from src/mscorlib/corefx/Interop/Windows/Crypt32/Interop.CryptProtectMemory.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Interop.BOOL.cs (renamed from src/mscorlib/corefx/Interop/Windows/Interop.BOOL.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Interop.Errors.cs44
-rw-r--r--src/mscorlib/shared/Interop/Windows/Interop.Libraries.cs15
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.CancelIoEx.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.CancelIoEx.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.CloseHandle.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.CloseHandle.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.CreateFile.cs40
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.CreateFile2.cs31
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.FILE_INFO_BY_HANDLE_CLASS.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetFileInformationByHandle.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.FileTypes.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FileTypes.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.FlushFileBuffers.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FlushFileBuffers.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.FormatMessage.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FormatMessage.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFileInformationByHandleEx.cs25
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFileType_SafeHandle.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetFileType_SafeHandle.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFullPathNameW.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetFullPathNameW.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetLongPathNameW.cs18
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetTempFileNameW.cs16
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetTempPathW.cs16
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.LockFile.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.LockFile.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.OutputDebugString.cs14
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.ReadFile_SafeHandle_IntPtr.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.ReadFile_SafeHandle_IntPtr.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.ReadFile_SafeHandle_NativeOverlapped.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.ReadFile_SafeHandle_NativeOverlapped.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SECURITY_ATTRIBUTES.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SECURITY_ATTRIBUTES.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SecurityOptions.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SecurityOptions.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SetEndOfFile.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetEndOfFile.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SetErrorMode.cs16
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SetFilePointerEx.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetFilePointerEx.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.WideCharToMultiByte.cs22
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.WriteFile_SafeHandle_IntPtr.cs23
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.WriteFile_SafeHandle_NativeOverlapped.cs (renamed from src/mscorlib/corefx/Interop/Windows/kernel32/Interop.WriteFile_SafeHandle_NativeOverlapped.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/NtDll/Interop.ZeroMemory.cs16
-rw-r--r--src/mscorlib/shared/Interop/Windows/OleAut32/Interop.SysAllocStringLen.cs19
-rw-r--r--src/mscorlib/shared/Interop/Windows/OleAut32/Interop.SysFreeString.cs15
-rw-r--r--src/mscorlib/shared/Interop/Windows/OleAut32/Interop.SysStringLen.cs19
-rw-r--r--src/mscorlib/shared/Microsoft/Win32/SafeHandles/CriticalHandleMinusOneIsInvalid.cs20
-rw-r--r--src/mscorlib/shared/Microsoft/Win32/SafeHandles/CriticalHandleZeroOrMinusOneIsInvalid.cs20
-rw-r--r--src/mscorlib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs (renamed from src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs)0
-rw-r--r--src/mscorlib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Windows.cs (renamed from src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeFileHandle.Windows.cs)0
-rw-r--r--src/mscorlib/shared/README.md19
-rw-r--r--src/mscorlib/shared/System.Private.CoreLib.Shared.projitems534
-rw-r--r--src/mscorlib/shared/System.Private.CoreLib.Shared.shproj19
-rw-r--r--src/mscorlib/shared/System/Action.cs35
-rw-r--r--src/mscorlib/shared/System/ApplicationException.cs (renamed from src/mscorlib/src/System/ApplicationException.cs)0
-rw-r--r--src/mscorlib/shared/System/ArgumentException.cs97
-rw-r--r--src/mscorlib/shared/System/ArgumentNullException.cs (renamed from src/mscorlib/src/System/ArgumentNullException.cs)0
-rw-r--r--src/mscorlib/shared/System/ArithmeticException.cs (renamed from src/mscorlib/src/System/ArithmeticException.cs)0
-rw-r--r--src/mscorlib/shared/System/ArrayTypeMismatchException.cs (renamed from src/mscorlib/src/System/ArrayTypeMismatchException.cs)0
-rw-r--r--src/mscorlib/shared/System/AssemblyLoadEventArgs.cs18
-rw-r--r--src/mscorlib/shared/System/AssemblyLoadEventHandler.cs8
-rw-r--r--src/mscorlib/shared/System/AsyncCallback.cs (renamed from src/mscorlib/src/System/AsyncCallback.cs)0
-rw-r--r--src/mscorlib/shared/System/AttributeTargets.cs (renamed from src/mscorlib/src/System/AttributeTargets.cs)0
-rw-r--r--src/mscorlib/shared/System/AttributeUsageAttribute.cs58
-rw-r--r--src/mscorlib/shared/System/Buffers/ArrayPool.cs (renamed from src/mscorlib/corefx/System/Buffers/ArrayPool.cs)0
-rw-r--r--src/mscorlib/shared/System/Buffers/ConfigurableArrayPool.cs (renamed from src/mscorlib/corefx/System/Buffers/ConfigurableArrayPool.cs)0
-rw-r--r--src/mscorlib/shared/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs (renamed from src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs)0
-rw-r--r--src/mscorlib/shared/System/Buffers/Utilities.cs35
-rw-r--r--src/mscorlib/shared/System/CLSCompliantAttribute.cs (renamed from src/mscorlib/src/System/CLSCompliantAttribute.cs)0
-rw-r--r--src/mscorlib/shared/System/Char.cs1122
-rw-r--r--src/mscorlib/shared/System/CharEnumerator.cs80
-rw-r--r--src/mscorlib/shared/System/Collections/DictionaryEntry.cs58
-rw-r--r--src/mscorlib/shared/System/Collections/Generic/ICollection.cs35
-rw-r--r--src/mscorlib/shared/System/Collections/Generic/IComparer.cs20
-rw-r--r--src/mscorlib/shared/System/Collections/Generic/IDictionary.cs51
-rw-r--r--src/mscorlib/shared/System/Collections/Generic/IEnumerable.cs21
-rw-r--r--src/mscorlib/shared/System/Collections/Generic/IEnumerator.cs26
-rw-r--r--src/mscorlib/shared/System/Collections/Generic/IEqualityComparer.cs18
-rw-r--r--src/mscorlib/shared/System/Collections/Generic/IList.cs37
-rw-r--r--src/mscorlib/shared/System/Collections/Generic/IReadOnlyCollection.cs16
-rw-r--r--src/mscorlib/shared/System/Collections/Generic/IReadOnlyDictionary.cs20
-rw-r--r--src/mscorlib/shared/System/Collections/Generic/IReadOnlyList.cs16
-rw-r--r--src/mscorlib/shared/System/Collections/Generic/KeyNotFoundException.cs33
-rw-r--r--src/mscorlib/shared/System/Collections/Generic/KeyValuePair.cs82
-rw-r--r--src/mscorlib/shared/System/Collections/ICollection.cs70
-rw-r--r--src/mscorlib/shared/System/Collections/IComparer.cs22
-rw-r--r--src/mscorlib/shared/System/Collections/IDictionary.cs61
-rw-r--r--src/mscorlib/shared/System/Collections/IDictionaryEnumerator.cs68
-rw-r--r--src/mscorlib/shared/System/Collections/IEnumerable.cs18
-rw-r--r--src/mscorlib/shared/System/Collections/IEnumerator.cs41
-rw-r--r--src/mscorlib/shared/System/Collections/IEqualityComparer.cs16
-rw-r--r--src/mscorlib/shared/System/Collections/IList.cs60
-rw-r--r--src/mscorlib/shared/System/Collections/IStructuralComparable.cs13
-rw-r--r--src/mscorlib/shared/System/Collections/IStructuralEquatable.cs12
-rw-r--r--src/mscorlib/shared/System/ComponentModel/DefaultValueAttribute.cs228
-rw-r--r--src/mscorlib/shared/System/ComponentModel/EditorBrowsableAttribute.cs48
-rw-r--r--src/mscorlib/shared/System/Configuration/Assemblies/AssemblyHashAlgorithm.cs16
-rw-r--r--src/mscorlib/shared/System/Configuration/Assemblies/AssemblyVersionCompatibility.cs13
-rw-r--r--src/mscorlib/shared/System/Convert.cs3031
-rw-r--r--src/mscorlib/shared/System/CurrentSystemTimeZone.cs199
-rw-r--r--src/mscorlib/shared/System/DBNull.cs119
-rw-r--r--src/mscorlib/shared/System/DataMisalignedException.cs39
-rw-r--r--src/mscorlib/shared/System/DateTime.cs1516
-rw-r--r--src/mscorlib/shared/System/DateTimeKind.cs (renamed from src/mscorlib/src/System/DateTimeKind.cs)0
-rw-r--r--src/mscorlib/shared/System/DateTimeOffset.cs921
-rw-r--r--src/mscorlib/shared/System/DayOfWeek.cs (renamed from src/mscorlib/src/System/DayOfWeek.cs)0
-rw-r--r--src/mscorlib/shared/System/DefaultBinder.cs1201
-rw-r--r--src/mscorlib/shared/System/Diagnostics/CodeAnalysis/SuppressMessageAttribute.cs39
-rw-r--r--src/mscorlib/shared/System/Diagnostics/ConditionalAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Debug.cs323
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/ActivityTracker.cs665
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/EventActivityOptions.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/EventActivityOptions.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/EventCounter.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/EventCounter.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/EventDescriptor.cs209
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/EventProvider.cs1207
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/EventSource.cs6942
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/EventSourceException.cs53
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/StubEnvironment.cs381
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/ArrayTypeInfo.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/ArrayTypeInfo.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/ConcurrentSet.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/ConcurrentSet.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/ConcurrentSetItem.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/ConcurrentSetItem.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs318
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EmptyStruct.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EmptyStruct.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EnumHelper.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumHelper.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EnumerableTypeInfo.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumerableTypeInfo.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventDataAttribute.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventDataAttribute.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventFieldAttribute.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventFieldAttribute.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventFieldFormat.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventFieldFormat.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventIgnoreAttribute.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventIgnoreAttribute.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventPayload.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceActivity.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceActivity.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceOptions.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceOptions.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/FieldMetadata.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/FieldMetadata.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/InvokeTypeInfo.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/InvokeTypeInfo.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/NameInfo.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyAnalysis.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyAnalysis.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleEventTypes.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleEventTypes.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleTypeInfos.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/Statics.cs727
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataCollector.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataCollector.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataType.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataType.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs890
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventTraits.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTraits.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventTypes.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTypes.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingMetadataCollector.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingTypeInfo.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TypeAnalysis.cs (renamed from src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TypeAnalysis.cs)0
-rw-r--r--src/mscorlib/shared/System/Diagnostics/Tracing/Winmeta.cs196
-rw-r--r--src/mscorlib/shared/System/DivideByZeroException.cs (renamed from src/mscorlib/src/System/DivideByZeroException.cs)0
-rw-r--r--src/mscorlib/shared/System/DuplicateWaitObjectException.cs (renamed from src/mscorlib/src/System/DuplicateWaitObjectException.cs)0
-rw-r--r--src/mscorlib/shared/System/EntryPointNotFoundException.cs (renamed from src/mscorlib/src/System/EntryPointNotFoundException.cs)0
-rw-r--r--src/mscorlib/shared/System/EventArgs.cs (renamed from src/mscorlib/src/System/EventArgs.cs)0
-rw-r--r--src/mscorlib/shared/System/EventHandler.cs (renamed from src/mscorlib/src/System/EventHandler.cs)0
-rw-r--r--src/mscorlib/shared/System/ExecutionEngineException.cs (renamed from src/mscorlib/src/System/ExecutionEngineException.cs)0
-rw-r--r--src/mscorlib/shared/System/FieldAccessException.cs (renamed from src/mscorlib/src/System/FieldAccessException.cs)0
-rw-r--r--src/mscorlib/shared/System/FlagsAttribute.cs (renamed from src/mscorlib/src/System/FlagsAttribute.cs)0
-rw-r--r--src/mscorlib/shared/System/FormatException.cs (renamed from src/mscorlib/src/System/FormatException.cs)0
-rw-r--r--src/mscorlib/shared/System/FormattableString.cs (renamed from src/mscorlib/src/System/FormattableString.cs)0
-rw-r--r--src/mscorlib/shared/System/Globalization/CalendarAlgorithmType.cs18
-rw-r--r--src/mscorlib/shared/System/Globalization/CalendarWeekRule.cs16
-rw-r--r--src/mscorlib/shared/System/Globalization/CalendricalCalculationsHelper.cs (renamed from src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs)0
-rw-r--r--src/mscorlib/shared/System/Globalization/ChineseLunisolarCalendar.cs390
-rw-r--r--src/mscorlib/shared/System/Globalization/CultureNotFoundException.cs120
-rw-r--r--src/mscorlib/shared/System/Globalization/CultureTypes.cs27
-rw-r--r--src/mscorlib/shared/System/Globalization/DateTimeFormat.cs1206
-rw-r--r--src/mscorlib/shared/System/Globalization/DateTimeFormatInfo.cs3028
-rw-r--r--src/mscorlib/shared/System/Globalization/DateTimeFormatInfoScanner.cs739
-rw-r--r--src/mscorlib/shared/System/Globalization/DateTimeParse.cs5672
-rw-r--r--src/mscorlib/shared/System/Globalization/DateTimeStyles.cs49
-rw-r--r--src/mscorlib/shared/System/Globalization/DaylightTime.cs50
-rw-r--r--src/mscorlib/shared/System/Globalization/DigitShapes.cs13
-rw-r--r--src/mscorlib/shared/System/Globalization/EastAsianLunisolarCalendar.cs710
-rw-r--r--src/mscorlib/shared/System/Globalization/GregorianCalendarTypes.cs19
-rw-r--r--src/mscorlib/shared/System/Globalization/HebrewCalendar.cs (renamed from src/mscorlib/corefx/System/Globalization/HebrewCalendar.cs)0
-rw-r--r--src/mscorlib/shared/System/Globalization/HebrewNumber.cs457
-rw-r--r--src/mscorlib/shared/System/Globalization/HijriCalendar.cs677
-rw-r--r--src/mscorlib/shared/System/Globalization/InternalGlobalizationHelper.cs48
-rw-r--r--src/mscorlib/shared/System/Globalization/JapaneseCalendar.cs409
-rw-r--r--src/mscorlib/shared/System/Globalization/JapaneseLunisolarCalendar.cs305
-rw-r--r--src/mscorlib/shared/System/Globalization/JulianCalendar.cs443
-rw-r--r--src/mscorlib/shared/System/Globalization/KoreanCalendar.cs266
-rw-r--r--src/mscorlib/shared/System/Globalization/KoreanLunisolarCalendar.cs1323
-rw-r--r--src/mscorlib/shared/System/Globalization/LocaleData.Unix.cs (renamed from src/mscorlib/corefx/System/Globalization/LocaleData.Unix.cs)0
-rw-r--r--src/mscorlib/shared/System/Globalization/NumberStyles.cs65
-rw-r--r--src/mscorlib/shared/System/Globalization/PersianCalendar.cs606
-rw-r--r--src/mscorlib/shared/System/Globalization/SortVersion.cs98
-rw-r--r--src/mscorlib/shared/System/Globalization/TaiwanCalendar.cs (renamed from src/mscorlib/corefx/System/Globalization/TaiwanCalendar.cs)0
-rw-r--r--src/mscorlib/shared/System/Globalization/TaiwanLunisolarCalendar.cs325
-rw-r--r--src/mscorlib/shared/System/Globalization/ThaiBuddhistCalendar.cs (renamed from src/mscorlib/corefx/System/Globalization/ThaiBuddhistCalendar.cs)0
-rw-r--r--src/mscorlib/shared/System/Globalization/TimeSpanStyles.cs (renamed from src/mscorlib/corefx/System/Globalization/TimeSpanStyles.cs)0
-rw-r--r--src/mscorlib/shared/System/Globalization/UmAlQuraCalendar.cs865
-rw-r--r--src/mscorlib/shared/System/Globalization/UnicodeCategory.cs40
-rw-r--r--src/mscorlib/shared/System/IAsyncResult.cs (renamed from src/mscorlib/src/System/IAsyncResult.cs)0
-rw-r--r--src/mscorlib/shared/System/ICloneable.cs11
-rw-r--r--src/mscorlib/shared/System/IComparable.cs (renamed from src/mscorlib/src/System/IComparable.cs)0
-rw-r--r--src/mscorlib/shared/System/IConvertible.cs (renamed from src/mscorlib/src/System/IConvertible.cs)0
-rw-r--r--src/mscorlib/shared/System/ICustomFormatter.cs (renamed from src/mscorlib/src/System/ICustomFormatter.cs)0
-rw-r--r--src/mscorlib/shared/System/IDisposable.cs (renamed from src/mscorlib/src/System/IDisposable.cs)0
-rw-r--r--src/mscorlib/shared/System/IEquatable.cs (renamed from src/mscorlib/src/System/IEquatable.cs)0
-rw-r--r--src/mscorlib/shared/System/IFormatProvider.cs (renamed from src/mscorlib/src/System/IFormatProvider.cs)0
-rw-r--r--src/mscorlib/shared/System/IFormattable.cs (renamed from src/mscorlib/src/System/IFormattable.cs)0
-rw-r--r--src/mscorlib/shared/System/IO/DirectoryNotFoundException.cs41
-rw-r--r--src/mscorlib/shared/System/IO/EndOfStreamException.cs35
-rw-r--r--src/mscorlib/shared/System/IO/Error.cs49
-rw-r--r--src/mscorlib/shared/System/IO/FileAccess.cs29
-rw-r--r--src/mscorlib/shared/System/IO/FileLoadException.cs102
-rw-r--r--src/mscorlib/shared/System/IO/FileMode.cs38
-rw-r--r--src/mscorlib/shared/System/IO/FileNotFoundException.cs114
-rw-r--r--src/mscorlib/shared/System/IO/FileOptions.cs33
-rw-r--r--src/mscorlib/shared/System/IO/FileShare.cs45
-rw-r--r--src/mscorlib/shared/System/IO/FileStream.Linux.cs30
-rw-r--r--src/mscorlib/shared/System/IO/FileStream.OSX.cs19
-rw-r--r--src/mscorlib/shared/System/IO/FileStream.Unix.cs933
-rw-r--r--src/mscorlib/shared/System/IO/FileStream.Win32.cs77
-rw-r--r--src/mscorlib/shared/System/IO/FileStream.WinRT.cs78
-rw-r--r--src/mscorlib/shared/System/IO/FileStream.Windows.cs1717
-rw-r--r--src/mscorlib/shared/System/IO/FileStream.cs (renamed from src/mscorlib/corefx/System/IO/FileStream.cs)0
-rw-r--r--src/mscorlib/shared/System/IO/FileStreamCompletionSource.Win32.cs222
-rw-r--r--src/mscorlib/shared/System/IO/Path.Unix.cs215
-rw-r--r--src/mscorlib/shared/System/IO/Path.Windows.cs155
-rw-r--r--src/mscorlib/shared/System/IO/Path.cs574
-rw-r--r--src/mscorlib/shared/System/IO/PathHelper.Windows.cs (renamed from src/mscorlib/corefx/System/IO/PathHelper.Windows.cs)0
-rw-r--r--src/mscorlib/shared/System/IO/PathInternal.Unix.cs (renamed from src/mscorlib/corefx/System/IO/PathInternal.Unix.cs)0
-rw-r--r--src/mscorlib/shared/System/IO/PathInternal.Windows.StringBuffer.cs (renamed from src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs)0
-rw-r--r--src/mscorlib/shared/System/IO/PathInternal.Windows.cs442
-rw-r--r--src/mscorlib/shared/System/IO/PathInternal.cs171
-rw-r--r--src/mscorlib/shared/System/IO/PathTooLongException.cs37
-rw-r--r--src/mscorlib/shared/System/IO/SeekOrigin.cs16
-rw-r--r--src/mscorlib/shared/System/IO/StreamHelpers.CopyValidation.cs46
-rw-r--r--src/mscorlib/shared/System/IO/Win32Marshal.cs (renamed from src/mscorlib/corefx/System/IO/Win32Marshal.cs)0
-rw-r--r--src/mscorlib/shared/System/IObservable.cs (renamed from src/mscorlib/src/System/IObservable.cs)0
-rw-r--r--src/mscorlib/shared/System/IObserver.cs (renamed from src/mscorlib/src/System/IObserver.cs)0
-rw-r--r--src/mscorlib/shared/System/IProgress.cs (renamed from src/mscorlib/src/System/IProgress.cs)0
-rw-r--r--src/mscorlib/shared/System/IndexOutOfRangeException.cs (renamed from src/mscorlib/src/System/IndexOutOfRangeException.cs)0
-rw-r--r--src/mscorlib/shared/System/InsufficientExecutionStackException.cs (renamed from src/mscorlib/src/System/InsufficientExecutionStackException.cs)0
-rw-r--r--src/mscorlib/shared/System/InvalidCastException.cs (renamed from src/mscorlib/src/System/InvalidCastException.cs)0
-rw-r--r--src/mscorlib/shared/System/InvalidOperationException.cs (renamed from src/mscorlib/src/System/InvalidOperationException.cs)0
-rw-r--r--src/mscorlib/shared/System/InvalidProgramException.cs (renamed from src/mscorlib/src/System/InvalidProgramException.cs)0
-rw-r--r--src/mscorlib/shared/System/InvalidTimeZoneException.cs (renamed from src/mscorlib/src/System/InvalidTimeZoneException.cs)0
-rw-r--r--src/mscorlib/shared/System/Lazy.cs561
-rw-r--r--src/mscorlib/shared/System/MarshalByRefObject.cs30
-rw-r--r--src/mscorlib/shared/System/MemberAccessException.cs (renamed from src/mscorlib/src/System/MemberAccessException.cs)0
-rw-r--r--src/mscorlib/shared/System/MethodAccessException.cs (renamed from src/mscorlib/src/System/MethodAccessException.cs)0
-rw-r--r--src/mscorlib/shared/System/MidpointRounding.cs (renamed from src/mscorlib/src/System/MidpointRounding.cs)0
-rw-r--r--src/mscorlib/shared/System/MissingMethodException.cs60
-rw-r--r--src/mscorlib/shared/System/MulticastNotSupportedException.cs (renamed from src/mscorlib/src/System/MulticastNotSupportedException.cs)0
-rw-r--r--src/mscorlib/shared/System/NotFiniteNumberException.cs71
-rw-r--r--src/mscorlib/shared/System/NotImplementedException.cs (renamed from src/mscorlib/src/System/NotImplementedException.cs)0
-rw-r--r--src/mscorlib/shared/System/NotSupportedException.cs (renamed from src/mscorlib/src/System/NotSupportedException.cs)0
-rw-r--r--src/mscorlib/shared/System/NullReferenceException.cs (renamed from src/mscorlib/src/System/NullReferenceException.cs)0
-rw-r--r--src/mscorlib/shared/System/ObjectDisposedException.cs82
-rw-r--r--src/mscorlib/shared/System/ObsoleteAttribute.cs (renamed from src/mscorlib/src/System/ObsoleteAttribute.cs)0
-rw-r--r--src/mscorlib/shared/System/OverflowException.cs (renamed from src/mscorlib/src/System/OverflowException.cs)0
-rw-r--r--src/mscorlib/shared/System/ParamArrayAttribute.cs (renamed from src/mscorlib/src/System/ParamArrayAttribute.cs)0
-rw-r--r--src/mscorlib/shared/System/ParamsArray.cs82
-rw-r--r--src/mscorlib/shared/System/PlatformNotSupportedException.cs (renamed from src/mscorlib/src/System/PlatformNotSupportedException.cs)0
-rw-r--r--src/mscorlib/shared/System/Progress.cs (renamed from src/mscorlib/src/System/Progress.cs)0
-rw-r--r--src/mscorlib/shared/System/Random.cs274
-rw-r--r--src/mscorlib/shared/System/RankException.cs (renamed from src/mscorlib/src/System/RankException.cs)0
-rw-r--r--src/mscorlib/shared/System/Reflection/AmbiguousMatchException.cs35
-rw-r--r--src/mscorlib/shared/System/Reflection/Assembly.cs200
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyAlgorithmIdAttribute.cs27
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyCompanyAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyConfigurationAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyContentType.cs13
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyCopyrightAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyCultureAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyDefaultAliasAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyDelaySignAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyDescriptionAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyFileVersionAttribute.cs20
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyFlagsAttribute.cs43
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyInformationalVersionAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyKeyFileAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyKeyNameAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyMetadataAttribute.cs21
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyNameFlags.cs21
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyProductAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblySignatureKeyAttribute.cs21
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyTitleAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyTrademarkAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Reflection/AssemblyVersionAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Reflection/Binder.cs19
-rw-r--r--src/mscorlib/shared/System/Reflection/BindingFlags.cs50
-rw-r--r--src/mscorlib/shared/System/Reflection/CallingConventions.cs20
-rw-r--r--src/mscorlib/shared/System/Reflection/ConstructorInfo.cs40
-rw-r--r--src/mscorlib/shared/System/Reflection/CustomAttributeFormatException.cs33
-rw-r--r--src/mscorlib/shared/System/Reflection/DefaultMemberAttribute.cs22
-rw-r--r--src/mscorlib/shared/System/Reflection/EventAttributes.cs22
-rw-r--r--src/mscorlib/shared/System/Reflection/EventInfo.cs115
-rw-r--r--src/mscorlib/shared/System/Reflection/ExceptionHandlingClauseOptions.cs16
-rw-r--r--src/mscorlib/shared/System/Reflection/FieldAttributes.cs40
-rw-r--r--src/mscorlib/shared/System/Reflection/FieldInfo.cs72
-rw-r--r--src/mscorlib/shared/System/Reflection/GenericParameterAttributes.cs20
-rw-r--r--src/mscorlib/shared/System/Reflection/ICustomAttributeProvider.cs13
-rw-r--r--src/mscorlib/shared/System/Reflection/IReflect.cs76
-rw-r--r--src/mscorlib/shared/System/Reflection/IReflectableType.cs12
-rw-r--r--src/mscorlib/shared/System/Reflection/ImageFileMachine.cs15
-rw-r--r--src/mscorlib/shared/System/Reflection/InterfaceMapping.cs14
-rw-r--r--src/mscorlib/shared/System/Reflection/IntrospectionExtensions.cs20
-rw-r--r--src/mscorlib/shared/System/Reflection/InvalidFilterCriteriaException.cs33
-rw-r--r--src/mscorlib/shared/System/Reflection/ManifestResourceInfo.cs23
-rw-r--r--src/mscorlib/shared/System/Reflection/MemberFilter.cs8
-rw-r--r--src/mscorlib/shared/System/Reflection/MemberInfo.cs75
-rw-r--r--src/mscorlib/shared/System/Reflection/MemberInfoSerializationHolder.cs315
-rw-r--r--src/mscorlib/shared/System/Reflection/MemberTypes.cs20
-rw-r--r--src/mscorlib/shared/System/Reflection/MethodAttributes.cs50
-rw-r--r--src/mscorlib/shared/System/Reflection/MethodBase.cs86
-rw-r--r--src/mscorlib/shared/System/Reflection/MethodImplAttributes.cs37
-rw-r--r--src/mscorlib/shared/System/Reflection/MethodInfo.cs43
-rw-r--r--src/mscorlib/shared/System/Reflection/Missing.cs24
-rw-r--r--src/mscorlib/shared/System/Reflection/Module.cs182
-rw-r--r--src/mscorlib/shared/System/Reflection/ModuleResolveEventHandler.cs9
-rw-r--r--src/mscorlib/shared/System/Reflection/ObfuscateAssemblyAttribute.cs19
-rw-r--r--src/mscorlib/shared/System/Reflection/ObfuscationAttribute.cs21
-rw-r--r--src/mscorlib/shared/System/Reflection/ParameterAttributes.cs29
-rw-r--r--src/mscorlib/shared/System/Reflection/ParameterInfo.cs110
-rw-r--r--src/mscorlib/shared/System/Reflection/ParameterModifier.cs36
-rw-r--r--src/mscorlib/shared/System/Reflection/Pointer.cs61
-rw-r--r--src/mscorlib/shared/System/Reflection/PortableExecutableKinds.cs18
-rw-r--r--src/mscorlib/shared/System/Reflection/ProcessorArchitecture.cs16
-rw-r--r--src/mscorlib/shared/System/Reflection/PropertyAttributes.cs25
-rw-r--r--src/mscorlib/shared/System/Reflection/PropertyInfo.cs74
-rw-r--r--src/mscorlib/shared/System/Reflection/ReflectionContext.cs24
-rw-r--r--src/mscorlib/shared/System/Reflection/ReflectionTypeLoadException.cs46
-rw-r--r--src/mscorlib/shared/System/Reflection/ResourceAttributes.cs14
-rw-r--r--src/mscorlib/shared/System/Reflection/ResourceLocation.cs15
-rw-r--r--src/mscorlib/shared/System/Reflection/StrongNameKeyPair.cs74
-rw-r--r--src/mscorlib/shared/System/Reflection/TargetException.cs33
-rw-r--r--src/mscorlib/shared/System/Reflection/TargetInvocationException.cs29
-rw-r--r--src/mscorlib/shared/System/Reflection/TargetParameterCountException.cs35
-rw-r--r--src/mscorlib/shared/System/Reflection/TypeAttributes.cs63
-rw-r--r--src/mscorlib/shared/System/Reflection/TypeDelegator.cs124
-rw-r--r--src/mscorlib/shared/System/Reflection/TypeFilter.cs8
-rw-r--r--src/mscorlib/shared/System/Reflection/TypeInfo.cs84
-rw-r--r--src/mscorlib/shared/System/ResolveEventArgs.cs25
-rw-r--r--src/mscorlib/shared/System/ResolveEventHandler.cs10
-rw-r--r--src/mscorlib/shared/System/Resources/IResourceReader.cs30
-rw-r--r--src/mscorlib/shared/System/Resources/MissingManifestResourceException.cs36
-rw-r--r--src/mscorlib/shared/System/Resources/MissingSatelliteAssemblyException.cs63
-rw-r--r--src/mscorlib/shared/System/Resources/NeutralResourcesLanguageAttribute.cs33
-rw-r--r--src/mscorlib/shared/System/Resources/ResourceTypeCode.cs58
-rw-r--r--src/mscorlib/shared/System/Resources/SatelliteContractVersionAttribute.cs31
-rw-r--r--src/mscorlib/shared/System/Resources/UltimateResourceFallbackLocation.cs25
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs17
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs16
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/CallerFilePathAttribute.cs14
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/CallerLineNumberAttribute.cs14
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/CallerMemberNameAttribute.cs14
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/CompilationRelaxations.cs16
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/CompilationRelaxationsAttribute.cs23
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs13
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs16
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/DefaultDependencyAttribute.cs18
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/DependencyAttribute.cs20
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs13
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/DiscardableAttribute.cs13
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/ExtensionAttribute.cs14
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs13
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/FixedBufferAttribute.cs32
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/FormattableStringFactory.cs58
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/IAsyncStateMachine.cs (renamed from src/mscorlib/src/System/Runtime/CompilerServices/IAsyncStateMachine.cs)0
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/INotifyCompletion.cs (renamed from src/mscorlib/src/System/Runtime/CompilerServices/INotifyCompletion.cs)0
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/ITuple.cs (renamed from src/mscorlib/src/System/Runtime/CompilerServices/ITuple.cs)0
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/IndexerNameAttribute.cs15
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs21
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/IsConst.cs10
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/IsVolatile.cs12
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs16
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/LoadHint.cs14
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/MethodCodeType.cs17
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/MethodImplOptions.cs21
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/ReadOnlyAttribute.cs21
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs33
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs31
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/RuntimeFeature.cs19
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/SpecialNameAttribute.cs12
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/StateMachineAttribute.cs20
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/StringFreezingAttribute.cs15
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/StrongBox.cs59
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs13
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs57
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs17
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs17
-rw-r--r--src/mscorlib/shared/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs12
-rw-r--r--src/mscorlib/shared/System/Runtime/ConstrainedExecution/Cer.cs14
-rw-r--r--src/mscorlib/shared/System/Runtime/ConstrainedExecution/Consistency.cs15
-rw-r--r--src/mscorlib/shared/System/Runtime/ConstrainedExecution/ReliabilityContractAttribute.cs33
-rw-r--r--src/mscorlib/shared/System/Runtime/InteropServices/CallingConvention.cs16
-rw-r--r--src/mscorlib/shared/System/Runtime/InteropServices/CharSet.cs21
-rw-r--r--src/mscorlib/shared/System/Runtime/InteropServices/ComVisibleAttribute.cs17
-rw-r--r--src/mscorlib/shared/System/Runtime/InteropServices/ExternalException.cs89
-rw-r--r--src/mscorlib/shared/System/Runtime/InteropServices/LayoutKind.cs14
-rw-r--r--src/mscorlib/shared/System/Runtime/InteropServices/StringBuffer.cs (renamed from src/mscorlib/corefx/System/Runtime/InteropServices/StringBuffer.cs)0
-rw-r--r--src/mscorlib/shared/System/Runtime/InteropServices/UnmanagedFunctionPointerAttribute.cs27
-rw-r--r--src/mscorlib/shared/System/Runtime/InteropServices/UnmanagedType.cs48
-rw-r--r--src/mscorlib/shared/System/Runtime/InteropServices/VarEnum.cs54
-rw-r--r--src/mscorlib/shared/System/Runtime/Serialization/IDeserializationCallback.cs11
-rw-r--r--src/mscorlib/shared/System/Runtime/Serialization/IFormatterConverter.cs28
-rw-r--r--src/mscorlib/shared/System/Runtime/Serialization/IObjectReference.cs11
-rw-r--r--src/mscorlib/shared/System/Runtime/Serialization/ISafeSerializationData.cs207
-rw-r--r--src/mscorlib/shared/System/Runtime/Serialization/ISerializable.cs11
-rw-r--r--src/mscorlib/shared/System/Runtime/Serialization/OnDeserializedAttribute.cs11
-rw-r--r--src/mscorlib/shared/System/Runtime/Serialization/OnDeserializingAttribute.cs11
-rw-r--r--src/mscorlib/shared/System/Runtime/Serialization/OnSerializedAttribute.cs11
-rw-r--r--src/mscorlib/shared/System/Runtime/Serialization/OnSerializingAttribute.cs11
-rw-r--r--src/mscorlib/shared/System/Runtime/Serialization/OptionalFieldAttribute.cs25
-rw-r--r--src/mscorlib/shared/System/Runtime/Serialization/SafeSerializationEventArgs.cs31
-rw-r--r--src/mscorlib/shared/System/Runtime/Serialization/SerializationException.cs39
-rw-r--r--src/mscorlib/shared/System/Runtime/Serialization/SerializationInfoEnumerator.cs127
-rw-r--r--src/mscorlib/shared/System/Runtime/Serialization/StreamingContext.cs53
-rw-r--r--src/mscorlib/shared/System/Runtime/Versioning/NonVersionableAttribute.cs36
-rw-r--r--src/mscorlib/shared/System/Runtime/Versioning/TargetFrameworkAttribute.cs48
-rw-r--r--src/mscorlib/shared/System/Security/AllowPartiallyTrustedCallersAttribute.cs19
-rw-r--r--src/mscorlib/shared/System/Security/CryptographicException.cs (renamed from src/mscorlib/corefx/System/Security/CryptographicException.cs)0
-rw-r--r--src/mscorlib/shared/System/Security/PartialTrustVisibilityLevel.cs13
-rw-r--r--src/mscorlib/shared/System/Security/SafeBSTRHandle.cs81
-rw-r--r--src/mscorlib/shared/System/Security/SecureString.Unix.cs (renamed from src/mscorlib/corefx/System/Security/SecureString.Unix.cs)0
-rw-r--r--src/mscorlib/shared/System/Security/SecureString.Windows.cs311
-rw-r--r--src/mscorlib/shared/System/Security/SecureString.cs (renamed from src/mscorlib/corefx/System/Security/SecureString.cs)0
-rw-r--r--src/mscorlib/shared/System/Security/SecurityCriticalAttribute.cs36
-rw-r--r--src/mscorlib/shared/System/Security/SecurityCriticalScope.cs14
-rw-r--r--src/mscorlib/shared/System/Security/SecurityException.cs66
-rw-r--r--src/mscorlib/shared/System/Security/SecurityRuleSet.cs14
-rw-r--r--src/mscorlib/shared/System/Security/SecurityRulesAttribute.cs28
-rw-r--r--src/mscorlib/shared/System/Security/SecuritySafeCriticalAttribute.cs30
-rw-r--r--src/mscorlib/shared/System/Security/SecurityTransparentAttribute.cs19
-rw-r--r--src/mscorlib/shared/System/Security/SecurityTreatAsSafeAttribute.cs32
-rw-r--r--src/mscorlib/shared/System/Security/SuppressUnmanagedCodeSecurityAttribute.cs16
-rw-r--r--src/mscorlib/shared/System/Security/UnverifiableCodeAttribute.cs15
-rw-r--r--src/mscorlib/shared/System/Security/VerificationException.cs35
-rw-r--r--src/mscorlib/shared/System/StackOverflowException.cs (renamed from src/mscorlib/src/System/StackOverflowException.cs)0
-rw-r--r--src/mscorlib/shared/System/StringComparer.cs274
-rw-r--r--src/mscorlib/shared/System/StringComparison.cs17
-rw-r--r--src/mscorlib/shared/System/StringSplitOptions.cs13
-rw-r--r--src/mscorlib/shared/System/SystemException.cs (renamed from src/mscorlib/src/System/SystemException.cs)0
-rw-r--r--src/mscorlib/shared/System/Text/ASCIIEncoding.cs973
-rw-r--r--src/mscorlib/shared/System/Text/Decoder.cs339
-rw-r--r--src/mscorlib/shared/System/Text/Encoder.cs333
-rw-r--r--src/mscorlib/shared/System/Text/EncodingInfo.cs72
-rw-r--r--src/mscorlib/shared/System/Text/EncodingNLS.cs322
-rw-r--r--src/mscorlib/shared/System/Text/EncodingProvider.cs136
-rw-r--r--src/mscorlib/shared/System/Text/Normalization.cs29
-rw-r--r--src/mscorlib/shared/System/Text/StringBuilder.cs2409
-rw-r--r--src/mscorlib/shared/System/Text/UTF32Encoding.cs1234
-rw-r--r--src/mscorlib/shared/System/Text/UTF8Encoding.cs2668
-rw-r--r--src/mscorlib/shared/System/Text/UnicodeEncoding.cs2058
-rw-r--r--src/mscorlib/shared/System/ThreadAttributes.cs (renamed from src/mscorlib/src/System/ThreadAttributes.cs)0
-rw-r--r--src/mscorlib/shared/System/ThreadStaticAttribute.cs (renamed from src/mscorlib/src/System/ThreadStaticAttribute.cs)0
-rw-r--r--src/mscorlib/shared/System/Threading/AbandonedMutexException.cs77
-rw-r--r--src/mscorlib/shared/System/Threading/ApartmentState.cs16
-rw-r--r--src/mscorlib/shared/System/Threading/AsyncLocal.cs484
-rw-r--r--src/mscorlib/shared/System/Threading/AutoResetEvent.cs12
-rw-r--r--src/mscorlib/shared/System/Threading/DeferredDisposableLifetime.cs (renamed from src/mscorlib/corefx/System/Threading/DeferredDisposableLifetime.cs)0
-rw-r--r--src/mscorlib/shared/System/Threading/EventResetMode.cs22
-rw-r--r--src/mscorlib/shared/System/Threading/ExecutionContext.cs370
-rw-r--r--src/mscorlib/shared/System/Threading/LazyThreadSafetyMode.cs44
-rw-r--r--src/mscorlib/shared/System/Threading/LockRecursionException.cs29
-rw-r--r--src/mscorlib/shared/System/Threading/ManualResetEvent.cs12
-rw-r--r--src/mscorlib/shared/System/Threading/ParameterizedThreadStart.cs18
-rw-r--r--src/mscorlib/shared/System/Threading/SemaphoreFullException.cs29
-rw-r--r--src/mscorlib/shared/System/Threading/SendOrPostCallback.cs8
-rw-r--r--src/mscorlib/shared/System/Threading/SynchronizationLockException.cs44
-rw-r--r--src/mscorlib/shared/System/Threading/Tasks/TaskCanceledException.cs89
-rw-r--r--src/mscorlib/shared/System/Threading/Tasks/TaskExtensions.cs48
-rw-r--r--src/mscorlib/shared/System/Threading/Tasks/TaskSchedulerException.cs77
-rw-r--r--src/mscorlib/shared/System/Threading/ThreadAbortException.cs36
-rw-r--r--src/mscorlib/shared/System/Threading/ThreadPriority.cs18
-rw-r--r--src/mscorlib/shared/System/Threading/ThreadStart.cs18
-rw-r--r--src/mscorlib/shared/System/Threading/ThreadStartException.cs29
-rw-r--r--src/mscorlib/shared/System/Threading/ThreadState.cs24
-rw-r--r--src/mscorlib/shared/System/Threading/ThreadStateException.cs45
-rw-r--r--src/mscorlib/shared/System/Threading/Timeout.cs20
-rw-r--r--src/mscorlib/shared/System/Threading/TimeoutHelper.cs54
-rw-r--r--src/mscorlib/shared/System/Threading/WaitHandleCannotBeOpenedException.cs31
-rw-r--r--src/mscorlib/shared/System/TimeZone.cs281
-rw-r--r--src/mscorlib/shared/System/TimeZoneNotFoundException.cs (renamed from src/mscorlib/src/System/TimeZoneNotFoundException.cs)0
-rw-r--r--src/mscorlib/shared/System/TimeoutException.cs (renamed from src/mscorlib/src/System/TimeoutException.cs)0
-rw-r--r--src/mscorlib/shared/System/TupleExtensions.cs930
-rw-r--r--src/mscorlib/shared/System/Type.Enum.cs186
-rw-r--r--src/mscorlib/shared/System/Type.Helpers.cs527
-rw-r--r--src/mscorlib/shared/System/Type.cs358
-rw-r--r--src/mscorlib/shared/System/TypeAccessException.cs (renamed from src/mscorlib/src/System/TypeAccessException.cs)0
-rw-r--r--src/mscorlib/shared/System/TypeCode.cs (renamed from src/mscorlib/src/System/TypeCode.cs)0
-rw-r--r--src/mscorlib/shared/System/TypeInitializationException.cs (renamed from src/mscorlib/src/System/TypeInitializationException.cs)0
-rw-r--r--src/mscorlib/shared/System/TypeUnloadedException.cs39
-rw-r--r--src/mscorlib/shared/System/UnauthorizedAccessException.cs (renamed from src/mscorlib/src/System/UnauthorizedAccessException.cs)0
-rw-r--r--src/mscorlib/shared/System/UnhandledExceptionEventArgs.cs (renamed from src/mscorlib/src/System/UnhandledExceptionEventArgs.cs)0
-rw-r--r--src/mscorlib/shared/System/UnhandledExceptionEventHandler.cs (renamed from src/mscorlib/src/System/UnhandledExceptionEventHandler.cs)0
-rw-r--r--src/mscorlib/shared/System/UnitySerializationHolder.cs329
-rw-r--r--src/mscorlib/shared/System/ValueTuple.cs2324
-rw-r--r--src/mscorlib/shared/System/Version.cs495
-rw-r--r--src/mscorlib/shared/System/Void.cs (renamed from src/mscorlib/src/System/Void.cs)0
-rw-r--r--src/mscorlib/src/Internal/Console.cs44
-rw-r--r--src/mscorlib/src/Internal/Runtime/Augments/EnvironmentAugments.cs12
-rw-r--r--src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs2
-rw-r--r--src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Collation.cs72
-rw-r--r--src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.ICU.cs16
-rw-r--r--src/mscorlib/src/Interop/Windows/Normaliz/Interop.Idna.cs38
-rw-r--r--src/mscorlib/src/Interop/Windows/Normaliz/Interop.Normalization.cs24
-rw-r--r--src/mscorlib/src/Interop/Windows/kernel32/Interop.Globalization.cs131
-rw-r--r--src/mscorlib/src/Microsoft/Win32/OAVariantLib.cs43
-rw-r--r--src/mscorlib/src/Microsoft/Win32/Registry.cs133
-rw-r--r--src/mscorlib/src/Microsoft/Win32/RegistryKey.cs1290
-rw-r--r--src/mscorlib/src/Microsoft/Win32/RegistryValueKind.cs26
-rw-r--r--src/mscorlib/src/Microsoft/Win32/RegistryView.cs19
-rw-r--r--src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs5
-rw-r--r--src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLibraryHandle.cs10
-rw-r--r--src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs29
-rw-r--r--src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeWaitHandle.cs4
-rw-r--r--src/mscorlib/src/Microsoft/Win32/SafeHandles/Win32SafeHandles.cs42
-rw-r--r--src/mscorlib/src/Microsoft/Win32/UnsafeNativeMethods.cs26
-rw-r--r--src/mscorlib/src/Microsoft/Win32/Win32Native.cs516
-rw-r--r--src/mscorlib/src/System.Private.CoreLib.txt2235
-rw-r--r--src/mscorlib/src/System/Action.cs35
-rw-r--r--src/mscorlib/src/System/Activator.cs133
-rw-r--r--src/mscorlib/src/System/AggregateException.cs25
-rw-r--r--src/mscorlib/src/System/AppContext/AppContext.cs28
-rw-r--r--src/mscorlib/src/System/AppContext/AppContextDefaultValues.Defaults.cs1
-rw-r--r--src/mscorlib/src/System/AppContext/AppContextSwitches.cs6
-rw-r--r--src/mscorlib/src/System/AppDomain.cs490
-rw-r--r--src/mscorlib/src/System/AppDomainAttributes.cs18
-rw-r--r--src/mscorlib/src/System/AppDomainManager.cs31
-rw-r--r--src/mscorlib/src/System/AppDomainSetup.cs401
-rw-r--r--src/mscorlib/src/System/AppDomainUnloadedException.cs18
-rw-r--r--src/mscorlib/src/System/ArgIterator.cs42
-rw-r--r--src/mscorlib/src/System/ArgumentException.cs97
-rw-r--r--src/mscorlib/src/System/ArgumentOutOfRangeException.cs101
-rw-r--r--src/mscorlib/src/System/Array.cs1052
-rw-r--r--src/mscorlib/src/System/ArraySegment.cs178
-rw-r--r--src/mscorlib/src/System/Attribute.cs204
-rw-r--r--src/mscorlib/src/System/AttributeUsageAttribute.cs56
-rw-r--r--src/mscorlib/src/System/BCLDebug.cs195
-rw-r--r--src/mscorlib/src/System/BadImageFormatException.cs87
-rw-r--r--src/mscorlib/src/System/BitConverter.cs462
-rw-r--r--src/mscorlib/src/System/Boolean.cs351
-rw-r--r--src/mscorlib/src/System/Buffer.cs485
-rw-r--r--src/mscorlib/src/System/Buffers/ArrayPoolEventSource.cs (renamed from src/mscorlib/corefx/System/Buffers/ArrayPoolEventSource.cs)0
-rw-r--r--src/mscorlib/src/System/Byte.cs185
-rw-r--r--src/mscorlib/src/System/CLRConfig.cs17
-rw-r--r--src/mscorlib/src/System/Char.cs1000
-rw-r--r--src/mscorlib/src/System/CharEnumerator.cs81
-rw-r--r--src/mscorlib/src/System/Collections/ArrayList.cs453
-rw-r--r--src/mscorlib/src/System/Collections/CollectionBase.cs199
-rw-r--r--src/mscorlib/src/System/Collections/Comparer.cs64
-rw-r--r--src/mscorlib/src/System/Collections/CompatibleComparer.cs44
-rw-r--r--src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs10
-rw-r--r--src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs6
-rw-r--r--src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs18
-rw-r--r--src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs2
-rw-r--r--src/mscorlib/src/System/Collections/DictionaryEntry.cs62
-rw-r--r--src/mscorlib/src/System/Collections/EmptyReadOnlyDictionaryInternal.cs182
-rw-r--r--src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs113
-rw-r--r--src/mscorlib/src/System/Collections/Generic/Comparer.cs127
-rw-r--r--src/mscorlib/src/System/Collections/Generic/ComparerHelpers.cs210
-rw-r--r--src/mscorlib/src/System/Collections/Generic/DebugView.cs120
-rw-r--r--src/mscorlib/src/System/Collections/Generic/Dictionary.cs1060
-rw-r--r--src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs290
-rw-r--r--src/mscorlib/src/System/Collections/Generic/ICollection.cs52
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IComparer.cs30
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IDictionary.cs58
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IEnumerable.cs38
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IEnumerator.cs35
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IEqualityComparer.cs19
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IList.cs54
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IReadOnlyCollection.cs34
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IReadOnlyDictionary.cs29
-rw-r--r--src/mscorlib/src/System/Collections/Generic/IReadOnlyList.cs34
-rw-r--r--src/mscorlib/src/System/Collections/Generic/KeyNotFoundException.cs44
-rw-r--r--src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs74
-rw-r--r--src/mscorlib/src/System/Collections/Generic/List.cs754
-rw-r--r--src/mscorlib/src/System/Collections/Hashtable.cs970
-rw-r--r--src/mscorlib/src/System/Collections/ICollection.cs80
-rw-r--r--src/mscorlib/src/System/Collections/IComparer.cs31
-rw-r--r--src/mscorlib/src/System/Collections/IDictionary.cs68
-rw-r--r--src/mscorlib/src/System/Collections/IDictionaryEnumerator.cs78
-rw-r--r--src/mscorlib/src/System/Collections/IEnumerable.cs33
-rw-r--r--src/mscorlib/src/System/Collections/IEnumerator.cs52
-rw-r--r--src/mscorlib/src/System/Collections/IEqualityComparer.cs26
-rw-r--r--src/mscorlib/src/System/Collections/IHashCodeProvider.cs12
-rw-r--r--src/mscorlib/src/System/Collections/IList.cs70
-rw-r--r--src/mscorlib/src/System/Collections/IStructuralComparable.cs11
-rw-r--r--src/mscorlib/src/System/Collections/IStructuralEquatable.cs10
-rw-r--r--src/mscorlib/src/System/Collections/ListDictionaryInternal.cs404
-rw-r--r--src/mscorlib/src/System/Collections/ObjectModel/Collection.cs303
-rw-r--r--src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs244
-rw-r--r--src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs196
-rw-r--r--src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs371
-rw-r--r--src/mscorlib/src/System/Collections/StructuralComparisons.cs89
-rw-r--r--src/mscorlib/src/System/ComponentModel/EditorBrowsableAttribute.cs48
-rw-r--r--src/mscorlib/src/System/Configuration/Assemblies/AssemblyHashAlgorithm.cs28
-rw-r--r--src/mscorlib/src/System/Configuration/Assemblies/AssemblyVersionCompatibility.cs23
-rw-r--r--src/mscorlib/src/System/Convert.cs2703
-rw-r--r--src/mscorlib/src/System/Currency.cs39
-rw-r--r--src/mscorlib/src/System/CurrentSystemTimeZone.Cache.cs35
-rw-r--r--src/mscorlib/src/System/CurrentTimeZone.cs214
-rw-r--r--src/mscorlib/src/System/DBNull.cs119
-rw-r--r--src/mscorlib/src/System/DataMisalignedException.cs39
-rw-r--r--src/mscorlib/src/System/DateTime.CoreCLR.cs29
-rw-r--r--src/mscorlib/src/System/DateTime.cs1360
-rw-r--r--src/mscorlib/src/System/DateTimeOffset.cs830
-rw-r--r--src/mscorlib/src/System/Decimal.cs883
-rw-r--r--src/mscorlib/src/System/DefaultBinder.CanConvert.cs30
-rw-r--r--src/mscorlib/src/System/DefaultBinder.cs1162
-rw-r--r--src/mscorlib/src/System/Delegate.cs220
-rw-r--r--src/mscorlib/src/System/DelegateSerializationHolder.cs48
-rw-r--r--src/mscorlib/src/System/Diagnostics/Assert.cs45
-rw-r--r--src/mscorlib/src/System/Diagnostics/AssertFilter.cs37
-rw-r--r--src/mscorlib/src/System/Diagnostics/AssertFilters.cs33
-rw-r--r--src/mscorlib/src/System/Diagnostics/CodeAnalysis/SuppressMessageAttribute.cs76
-rw-r--r--src/mscorlib/src/System/Diagnostics/ConditionalAttribute.cs25
-rw-r--r--src/mscorlib/src/System/Diagnostics/Contracts/Contracts.cs48
-rw-r--r--src/mscorlib/src/System/Diagnostics/Contracts/ContractsBCL.cs59
-rw-r--r--src/mscorlib/src/System/Diagnostics/Debug.Unix.cs95
-rw-r--r--src/mscorlib/src/System/Diagnostics/Debug.Windows.cs63
-rw-r--r--src/mscorlib/src/System/Diagnostics/Debugger.cs21
-rw-r--r--src/mscorlib/src/System/Diagnostics/DebuggerAttributes.cs110
-rw-r--r--src/mscorlib/src/System/Diagnostics/EditAndContinueHelper.cs11
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/ActivityTracker.cs665
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventDescriptor.cs195
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs1207
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs6912
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventSourceException.cs53
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs16
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/FrameworkEventSource.cs239
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/StubEnvironment.cs373
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/DataCollector.cs318
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/Statics.cs727
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventSource.cs890
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/Winmeta.cs196
-rw-r--r--src/mscorlib/src/System/Diagnostics/ICustomDebuggerNotification.cs8
-rw-r--r--src/mscorlib/src/System/Diagnostics/LogSwitch.cs90
-rw-r--r--src/mscorlib/src/System/Diagnostics/LoggingLevels.cs61
-rw-r--r--src/mscorlib/src/System/Diagnostics/Stackframe.cs104
-rw-r--r--src/mscorlib/src/System/Diagnostics/Stacktrace.cs224
-rw-r--r--src/mscorlib/src/System/Diagnostics/SymbolStore/ISymDocumentWriter.cs11
-rw-r--r--src/mscorlib/src/System/Diagnostics/SymbolStore/ISymWriter.cs33
-rw-r--r--src/mscorlib/src/System/Diagnostics/SymbolStore/SymAddressKind.cs24
-rw-r--r--src/mscorlib/src/System/Diagnostics/SymbolStore/Token.cs25
-rw-r--r--src/mscorlib/src/System/Diagnostics/log.cs80
-rw-r--r--src/mscorlib/src/System/DllNotFoundException.cs42
-rw-r--r--src/mscorlib/src/System/Double.cs226
-rw-r--r--src/mscorlib/src/System/Empty.cs27
-rw-r--r--src/mscorlib/src/System/Enum.cs208
-rw-r--r--src/mscorlib/src/System/Environment.cs476
-rw-r--r--src/mscorlib/src/System/Exception.cs267
-rw-r--r--src/mscorlib/src/System/GC.cs167
-rw-r--r--src/mscorlib/src/System/Globalization/BidiCategory.cs9
-rw-r--r--src/mscorlib/src/System/Globalization/Calendar.cs297
-rw-r--r--src/mscorlib/src/System/Globalization/CalendarAlgorithmType.cs19
-rw-r--r--src/mscorlib/src/System/Globalization/CalendarData.Unix.cs339
-rw-r--r--src/mscorlib/src/System/Globalization/CalendarData.Windows.cs502
-rw-r--r--src/mscorlib/src/System/Globalization/CalendarData.cs274
-rw-r--r--src/mscorlib/src/System/Globalization/CalendarWeekRule.cs19
-rw-r--r--src/mscorlib/src/System/Globalization/CalendricalCalculationsHelper.cs414
-rw-r--r--src/mscorlib/src/System/Globalization/CharUnicodeInfo.cs360
-rw-r--r--src/mscorlib/src/System/Globalization/CharUnicodeInfoData.cs (renamed from src/mscorlib/corefx/System/Globalization/CharUnicodeInfoData.cs)0
-rw-r--r--src/mscorlib/src/System/Globalization/ChineseLunisolarCalendar.cs397
-rw-r--r--src/mscorlib/src/System/Globalization/CompareInfo.Invariant.cs238
-rw-r--r--src/mscorlib/src/System/Globalization/CompareInfo.Unix.cs439
-rw-r--r--src/mscorlib/src/System/Globalization/CompareInfo.Windows.cs486
-rw-r--r--src/mscorlib/src/System/Globalization/CompareInfo.cs897
-rw-r--r--src/mscorlib/src/System/Globalization/CultureData.Unix.cs431
-rw-r--r--src/mscorlib/src/System/Globalization/CultureData.Windows.cs830
-rw-r--r--src/mscorlib/src/System/Globalization/CultureData.cs2503
-rw-r--r--src/mscorlib/src/System/Globalization/CultureInfo.Unix.cs128
-rw-r--r--src/mscorlib/src/System/Globalization/CultureInfo.Windows.cs278
-rw-r--r--src/mscorlib/src/System/Globalization/CultureInfo.cs1357
-rw-r--r--src/mscorlib/src/System/Globalization/CultureNotFoundException.cs129
-rw-r--r--src/mscorlib/src/System/Globalization/CultureTypes.cs30
-rw-r--r--src/mscorlib/src/System/Globalization/DateTimeFormat.cs1130
-rw-r--r--src/mscorlib/src/System/Globalization/DateTimeFormatInfo.cs2858
-rw-r--r--src/mscorlib/src/System/Globalization/DateTimeFormatInfoScanner.cs747
-rw-r--r--src/mscorlib/src/System/Globalization/DateTimeParse.cs5035
-rw-r--r--src/mscorlib/src/System/Globalization/DateTimeStyles.cs49
-rw-r--r--src/mscorlib/src/System/Globalization/DaylightTime.cs63
-rw-r--r--src/mscorlib/src/System/Globalization/DigitShapes.cs21
-rw-r--r--src/mscorlib/src/System/Globalization/EastAsianLunisolarCalendar.cs643
-rw-r--r--src/mscorlib/src/System/Globalization/EncodingDataItem.Unix.cs2
-rw-r--r--src/mscorlib/src/System/Globalization/EncodingDataItem.cs77
-rw-r--r--src/mscorlib/src/System/Globalization/EncodingTable.Unix.cs4
-rw-r--r--src/mscorlib/src/System/Globalization/EncodingTable.cs134
-rw-r--r--src/mscorlib/src/System/Globalization/GlobalizationAssembly.cs52
-rw-r--r--src/mscorlib/src/System/Globalization/GlobalizationMode.Unix.cs24
-rw-r--r--src/mscorlib/src/System/Globalization/GlobalizationMode.Windows.cs14
-rw-r--r--src/mscorlib/src/System/Globalization/GlobalizationMode.cs12
-rw-r--r--src/mscorlib/src/System/Globalization/GregorianCalendar.cs266
-rw-r--r--src/mscorlib/src/System/Globalization/GregorianCalendarHelper.cs419
-rw-r--r--src/mscorlib/src/System/Globalization/GregorianCalendarTypes.cs17
-rw-r--r--src/mscorlib/src/System/Globalization/HebrewCalendar.cs1084
-rw-r--r--src/mscorlib/src/System/Globalization/HebrewNumber.cs403
-rw-r--r--src/mscorlib/src/System/Globalization/HijriCalendar.Unix.cs (renamed from src/mscorlib/corefx/System/Globalization/HijriCalendar.Unix.cs)0
-rw-r--r--src/mscorlib/src/System/Globalization/HijriCalendar.Win32.cs83
-rw-r--r--src/mscorlib/src/System/Globalization/HijriCalendar.WinRT.cs (renamed from src/mscorlib/corefx/System/Globalization/HijriCalendar.WinRT.cs)0
-rw-r--r--src/mscorlib/src/System/Globalization/HijriCalendar.cs716
-rw-r--r--src/mscorlib/src/System/Globalization/IdnMapping.Unix.cs142
-rw-r--r--src/mscorlib/src/System/Globalization/IdnMapping.Windows.cs121
-rw-r--r--src/mscorlib/src/System/Globalization/IdnMapping.cs929
-rw-r--r--src/mscorlib/src/System/Globalization/JapaneseCalendar.Unix.cs96
-rw-r--r--src/mscorlib/src/System/Globalization/JapaneseCalendar.Win32.cs209
-rw-r--r--src/mscorlib/src/System/Globalization/JapaneseCalendar.WinRT.cs (renamed from src/mscorlib/corefx/System/Globalization/JapaneseCalendar.WinRT.cs)0
-rw-r--r--src/mscorlib/src/System/Globalization/JapaneseCalendar.cs581
-rw-r--r--src/mscorlib/src/System/Globalization/JapaneseLunisolarCalendar.cs293
-rw-r--r--src/mscorlib/src/System/Globalization/JulianCalendar.cs436
-rw-r--r--src/mscorlib/src/System/Globalization/KoreanCalendar.cs259
-rw-r--r--src/mscorlib/src/System/Globalization/KoreanLunisolarCalendar.cs1334
-rw-r--r--src/mscorlib/src/System/Globalization/NumberFormatInfo.cs542
-rw-r--r--src/mscorlib/src/System/Globalization/NumberStyles.cs66
-rw-r--r--src/mscorlib/src/System/Globalization/PersianCalendar.cs578
-rw-r--r--src/mscorlib/src/System/Globalization/RegionInfo.cs201
-rw-r--r--src/mscorlib/src/System/Globalization/SortKey.cs109
-rw-r--r--src/mscorlib/src/System/Globalization/SortVersion.cs102
-rw-r--r--src/mscorlib/src/System/Globalization/StringInfo.cs240
-rw-r--r--src/mscorlib/src/System/Globalization/Tables/charinfo.nlpbin36992 -> 0 bytes
-rw-r--r--src/mscorlib/src/System/Globalization/TaiwanCalendar.cs256
-rw-r--r--src/mscorlib/src/System/Globalization/TaiwanLunisolarCalendar.cs330
-rw-r--r--src/mscorlib/src/System/Globalization/TextElementEnumerator.cs136
-rw-r--r--src/mscorlib/src/System/Globalization/TextInfo.Unix.cs117
-rw-r--r--src/mscorlib/src/System/Globalization/TextInfo.Windows.cs113
-rw-r--r--src/mscorlib/src/System/Globalization/TextInfo.cs860
-rw-r--r--src/mscorlib/src/System/Globalization/ThaiBuddhistCalendar.cs219
-rw-r--r--src/mscorlib/src/System/Globalization/TimeSpanFormat.cs246
-rw-r--r--src/mscorlib/src/System/Globalization/TimeSpanParse.cs1074
-rw-r--r--src/mscorlib/src/System/Globalization/TimeSpanStyles.cs12
-rw-r--r--src/mscorlib/src/System/Globalization/UmAlQuraCalendar.cs850
-rw-r--r--src/mscorlib/src/System/Globalization/UnicodeCategory.cs78
-rw-r--r--src/mscorlib/src/System/Guid.cs873
-rw-r--r--src/mscorlib/src/System/HResults.cs (renamed from src/mscorlib/corefx/System/HResults.cs)0
-rw-r--r--src/mscorlib/src/System/IAppDomainPauseManager.cs22
-rw-r--r--src/mscorlib/src/System/ICloneable.cs28
-rw-r--r--src/mscorlib/src/System/IO/BinaryReader.cs347
-rw-r--r--src/mscorlib/src/System/IO/BinaryWriter.cs211
-rw-r--r--src/mscorlib/src/System/IO/Directory.cs28
-rw-r--r--src/mscorlib/src/System/IO/DirectoryNotFoundException.cs45
-rw-r--r--src/mscorlib/src/System/IO/DriveNotFoundException.cs29
-rw-r--r--src/mscorlib/src/System/IO/EndOfStreamException.cs42
-rw-r--r--src/mscorlib/src/System/IO/File.cs81
-rw-r--r--src/mscorlib/src/System/IO/FileAccess.cs41
-rw-r--r--src/mscorlib/src/System/IO/FileLoadException.CoreCLR.cs43
-rw-r--r--src/mscorlib/src/System/IO/FileLoadException.cs175
-rw-r--r--src/mscorlib/src/System/IO/FileMode.cs53
-rw-r--r--src/mscorlib/src/System/IO/FileNotFoundException.CoreCLR.cs20
-rw-r--r--src/mscorlib/src/System/IO/FileNotFoundException.cs157
-rw-r--r--src/mscorlib/src/System/IO/FileOptions.cs46
-rw-r--r--src/mscorlib/src/System/IO/FileShare.cs59
-rw-r--r--src/mscorlib/src/System/IO/IOException.cs46
-rw-r--r--src/mscorlib/src/System/IO/MemoryStream.cs393
-rw-r--r--src/mscorlib/src/System/IO/PathTooLongException.cs43
-rw-r--r--src/mscorlib/src/System/IO/PinnedBufferMemoryStream.cs17
-rw-r--r--src/mscorlib/src/System/IO/SearchOption.cs5
-rw-r--r--src/mscorlib/src/System/IO/SeekOrigin.cs31
-rw-r--r--src/mscorlib/src/System/IO/Stream.cs355
-rw-r--r--src/mscorlib/src/System/IO/StreamHelpers.CopyValidation.cs46
-rw-r--r--src/mscorlib/src/System/IO/StreamReader.cs249
-rw-r--r--src/mscorlib/src/System/IO/TextReader.cs32
-rw-r--r--src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs1132
-rw-r--r--src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs481
-rw-r--r--src/mscorlib/src/System/IO/UnmanagedMemoryStreamWrapper.cs153
-rw-r--r--src/mscorlib/src/System/IO/__Error.cs196
-rw-r--r--src/mscorlib/src/System/IO/__HResults.cs7
-rw-r--r--src/mscorlib/src/System/IServiceObjectProvider.cs16
-rw-r--r--src/mscorlib/src/System/InsufficientMemoryException.cs37
-rw-r--r--src/mscorlib/src/System/Int16.cs220
-rw-r--r--src/mscorlib/src/System/Int32.cs153
-rw-r--r--src/mscorlib/src/System/Int64.cs151
-rw-r--r--src/mscorlib/src/System/IntPtr.cs100
-rw-r--r--src/mscorlib/src/System/Internal.cs49
-rw-r--r--src/mscorlib/src/System/Lazy.cs506
-rw-r--r--src/mscorlib/src/System/LowLevelConsole.cs65
-rw-r--r--src/mscorlib/src/System/MarshalByRefObject.cs30
-rw-r--r--src/mscorlib/src/System/Math.cs921
-rw-r--r--src/mscorlib/src/System/MathF.cs38
-rw-r--r--src/mscorlib/src/System/MissingFieldException.cs71
-rw-r--r--src/mscorlib/src/System/MissingMemberException.cs96
-rw-r--r--src/mscorlib/src/System/MissingMethodException.cs65
-rw-r--r--src/mscorlib/src/System/MulticastDelegate.cs176
-rw-r--r--src/mscorlib/src/System/NonSerializedAttribute.cs19
-rw-r--r--src/mscorlib/src/System/NotFiniteNumberException.cs71
-rw-r--r--src/mscorlib/src/System/Nullable.cs105
-rw-r--r--src/mscorlib/src/System/Number.cs782
-rw-r--r--src/mscorlib/src/System/Object.cs320
-rw-r--r--src/mscorlib/src/System/ObjectDisposedException.cs82
-rw-r--r--src/mscorlib/src/System/OleAutBinder.cs28
-rw-r--r--src/mscorlib/src/System/OperatingSystem.cs91
-rw-r--r--src/mscorlib/src/System/OperationCanceledException.cs44
-rw-r--r--src/mscorlib/src/System/OutOfMemoryException.cs40
-rw-r--r--src/mscorlib/src/System/ParamsArray.cs81
-rw-r--r--src/mscorlib/src/System/ParseNumbers.cs71
-rw-r--r--src/mscorlib/src/System/PlatformID.cs18
-rw-r--r--src/mscorlib/src/System/Random.cs249
-rw-r--r--src/mscorlib/src/System/ReadOnlySpan.cs31
-rw-r--r--src/mscorlib/src/System/Reflection/AmbiguousMatchException.cs41
-rw-r--r--src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs211
-rw-r--r--src/mscorlib/src/System/Reflection/Assembly.cs1680
-rw-r--r--src/mscorlib/src/System/Reflection/AssemblyAttributes.cs387
-rw-r--r--src/mscorlib/src/System/Reflection/AssemblyName.cs191
-rw-r--r--src/mscorlib/src/System/Reflection/AssemblyNameFlags.cs53
-rw-r--r--src/mscorlib/src/System/Reflection/Associates.cs35
-rw-r--r--src/mscorlib/src/System/Reflection/Binder.cs49
-rw-r--r--src/mscorlib/src/System/Reflection/BindingFlags.cs63
-rw-r--r--src/mscorlib/src/System/Reflection/CallingConventions.cs28
-rw-r--r--src/mscorlib/src/System/Reflection/ConstructorInfo.CoreCLR.cs11
-rw-r--r--src/mscorlib/src/System/Reflection/ConstructorInfo.cs614
-rw-r--r--src/mscorlib/src/System/Reflection/CustomAttribute.cs166
-rw-r--r--src/mscorlib/src/System/Reflection/CustomAttributeExtensions.cs1
-rw-r--r--src/mscorlib/src/System/Reflection/CustomAttributeFormatException.cs37
-rw-r--r--src/mscorlib/src/System/Reflection/DefaultMemberAttribute.cs39
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/AQNBuilder.cs18
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs155
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderAccess.cs5
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderData.cs126
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/ConstructorBuilder.cs92
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/CustomAttributeBuilder.cs88
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/DynamicILGenerator.cs126
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs484
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/EnumBuilder.cs223
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/EventBuilder.cs54
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/EventToken.cs37
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/FieldBuilder.cs77
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/FieldToken.cs34
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/FlowControl.cs30
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs55
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs774
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/ISymWrapperCore.cs188
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/Label.cs38
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/LocalBuilder.cs44
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/MethodBuilder.cs304
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/MethodBuilderInstantiation.cs28
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/MethodToken.cs30
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs267
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs36
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/OpCodes.cs5063
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/Opcode.cs271
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/OpcodeType.cs24
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/OperandType.cs48
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/PEFileKinds.cs10
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/ParameterBuilder.cs93
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/ParameterToken.cs36
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/PropertyBuilder.cs130
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/PropertyToken.cs34
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/SignatureHelper.cs308
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/SignatureToken.cs36
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/StackBehaviour.cs68
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/StringToken.cs46
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/SymbolMethod.cs66
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/SymbolType.cs269
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs614
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs60
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/TypeToken.cs40
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs56
-rw-r--r--src/mscorlib/src/System/Reflection/EventAttributes.cs29
-rw-r--r--src/mscorlib/src/System/Reflection/EventInfo.cs401
-rw-r--r--src/mscorlib/src/System/Reflection/ExceptionHandlingClause.cs93
-rw-r--r--src/mscorlib/src/System/Reflection/FieldAttributes.cs42
-rw-r--r--src/mscorlib/src/System/Reflection/FieldInfo.CoreCLR.cs35
-rw-r--r--src/mscorlib/src/System/Reflection/FieldInfo.cs862
-rw-r--r--src/mscorlib/src/System/Reflection/GenericParameterAttributes.cs22
-rw-r--r--src/mscorlib/src/System/Reflection/ICustomAttributeProvider.cs33
-rw-r--r--src/mscorlib/src/System/Reflection/INVOCATION_FLAGS.cs38
-rw-r--r--src/mscorlib/src/System/Reflection/IReflect.cs116
-rw-r--r--src/mscorlib/src/System/Reflection/IReflectableType.cs20
-rw-r--r--src/mscorlib/src/System/Reflection/InterfaceMapping.cs22
-rw-r--r--src/mscorlib/src/System/Reflection/IntrospectionExtensions.cs28
-rw-r--r--src/mscorlib/src/System/Reflection/InvalidFilterCriteriaException.cs39
-rw-r--r--src/mscorlib/src/System/Reflection/LoaderAllocator.cs11
-rw-r--r--src/mscorlib/src/System/Reflection/LocalVariableInfo.cs40
-rw-r--r--src/mscorlib/src/System/Reflection/ManifestResourceInfo.cs65
-rw-r--r--src/mscorlib/src/System/Reflection/MdConstant.cs35
-rw-r--r--src/mscorlib/src/System/Reflection/MdFieldInfo.cs141
-rw-r--r--src/mscorlib/src/System/Reflection/MdImport.cs476
-rw-r--r--src/mscorlib/src/System/Reflection/MemberFilter.cs18
-rw-r--r--src/mscorlib/src/System/Reflection/MemberInfo.Internal.cs11
-rw-r--r--src/mscorlib/src/System/Reflection/MemberInfo.cs113
-rw-r--r--src/mscorlib/src/System/Reflection/MemberInfoSerializationHolder.cs285
-rw-r--r--src/mscorlib/src/System/Reflection/MemberSerializationStringGenerator.cs39
-rw-r--r--src/mscorlib/src/System/Reflection/MemberTypes.cs33
-rw-r--r--src/mscorlib/src/System/Reflection/MethodAttributes.cs55
-rw-r--r--src/mscorlib/src/System/Reflection/MethodBase.CoreCLR.cs157
-rw-r--r--src/mscorlib/src/System/Reflection/MethodBase.cs330
-rw-r--r--src/mscorlib/src/System/Reflection/MethodBody.cs136
-rw-r--r--src/mscorlib/src/System/Reflection/MethodImplAttributes.cs43
-rw-r--r--src/mscorlib/src/System/Reflection/MethodInfo.cs926
-rw-r--r--src/mscorlib/src/System/Reflection/Missing.cs35
-rw-r--r--src/mscorlib/src/System/Reflection/Module.cs1120
-rw-r--r--src/mscorlib/src/System/Reflection/ObfuscateAssemblyAttribute.cs45
-rw-r--r--src/mscorlib/src/System/Reflection/ObfuscationAttribute.cs74
-rw-r--r--src/mscorlib/src/System/Reflection/ParameterAttributes.cs35
-rw-r--r--src/mscorlib/src/System/Reflection/ParameterInfo.cs733
-rw-r--r--src/mscorlib/src/System/Reflection/ParameterModifier.cs45
-rw-r--r--src/mscorlib/src/System/Reflection/Pointer.cs75
-rw-r--r--src/mscorlib/src/System/Reflection/PropertyAttributes.cs32
-rw-r--r--src/mscorlib/src/System/Reflection/PropertyInfo.cs613
-rw-r--r--src/mscorlib/src/System/Reflection/ReflectionContext.cs36
-rw-r--r--src/mscorlib/src/System/Reflection/ReflectionTypeLoadException.cs72
-rw-r--r--src/mscorlib/src/System/Reflection/ResourceAttributes.cs23
-rw-r--r--src/mscorlib/src/System/Reflection/RtFieldInfo.cs390
-rw-r--r--src/mscorlib/src/System/Reflection/RuntimeAssembly.cs931
-rw-r--r--src/mscorlib/src/System/Reflection/RuntimeConstructorInfo.cs481
-rw-r--r--src/mscorlib/src/System/Reflection/RuntimeEventInfo.cs220
-rw-r--r--src/mscorlib/src/System/Reflection/RuntimeFieldInfo.cs136
-rw-r--r--src/mscorlib/src/System/Reflection/RuntimeMethodInfo.cs803
-rw-r--r--src/mscorlib/src/System/Reflection/RuntimeModule.cs602
-rw-r--r--src/mscorlib/src/System/Reflection/RuntimeParameterInfo.cs528
-rw-r--r--src/mscorlib/src/System/Reflection/RuntimePropertyInfo.cs467
-rw-r--r--src/mscorlib/src/System/Reflection/RuntimeReflectionExtensions.cs88
-rw-r--r--src/mscorlib/src/System/Reflection/StrongNameKeyPair.cs95
-rw-r--r--src/mscorlib/src/System/Reflection/TargetException.cs37
-rw-r--r--src/mscorlib/src/System/Reflection/TargetInvocationException.cs46
-rw-r--r--src/mscorlib/src/System/Reflection/TargetParameterCountException.cs40
-rw-r--r--src/mscorlib/src/System/Reflection/TypeAttributes.cs64
-rw-r--r--src/mscorlib/src/System/Reflection/TypeDelegator.cs257
-rw-r--r--src/mscorlib/src/System/Reflection/TypeFilter.cs18
-rw-r--r--src/mscorlib/src/System/Reflection/TypeInfo.cs194
-rw-r--r--src/mscorlib/src/System/Reflection/__Filters.cs67
-rw-r--r--src/mscorlib/src/System/ResId.cs156
-rw-r--r--src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs16
-rw-r--r--src/mscorlib/src/System/Resources/IResourceGroveler.cs16
-rw-r--r--src/mscorlib/src/System/Resources/IResourceReader.cs30
-rw-r--r--src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs6
-rw-r--r--src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs57
-rw-r--r--src/mscorlib/src/System/Resources/MissingManifestResourceException.cs41
-rw-r--r--src/mscorlib/src/System/Resources/MissingSatelliteAssemblyException.cs55
-rw-r--r--src/mscorlib/src/System/Resources/NeutralResourcesLanguageAttribute.cs64
-rw-r--r--src/mscorlib/src/System/Resources/ResourceFallbackManager.cs172
-rw-r--r--src/mscorlib/src/System/Resources/ResourceManager.cs396
-rw-r--r--src/mscorlib/src/System/Resources/ResourceReader.cs671
-rw-r--r--src/mscorlib/src/System/Resources/ResourceSet.cs62
-rw-r--r--src/mscorlib/src/System/Resources/ResourceTypeCode.cs57
-rw-r--r--src/mscorlib/src/System/Resources/RuntimeResourceSet.cs122
-rw-r--r--src/mscorlib/src/System/Resources/SatelliteContractVersionAttribute.cs38
-rw-r--r--src/mscorlib/src/System/Resources/UltimateResourceFallbackLocation.cs28
-rw-r--r--src/mscorlib/src/System/Resources/__FastResourceComparer.cs36
-rw-r--r--src/mscorlib/src/System/Resources/__HResults.cs3
-rw-r--r--src/mscorlib/src/System/RtType.cs980
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs30
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/AssemblySettingAttributes.cs94
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs112
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs18
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CallerFilePathAttribute.cs17
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CallerLineNumberAttribute.cs17
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CallerMemberNameAttribute.cs17
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CompilationRelaxations.cs50
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs16
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs26
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CompilerMarshalOverride.cs23
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CustomConstantAttribute.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/DateTimeConstantAttribute.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/DecimalConstantAttribute.cs4
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs18
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/DiscardableAttribute.cs18
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/ExtensionAttribute.cs13
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs14
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/FixedBufferAttribute.cs43
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/FormattableStringFactory.cs58
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/FriendAccessAllowedAttribute.cs26
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/ICastable.cs12
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IndexerNameAttribute.cs16
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs58
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsVolatile.cs12
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs18
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/MethodImplAttribute.cs61
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs39
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs48
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs34
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/RuntimeWrappedException.cs32
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/SpecialNameAttribute.cs27
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/StateMachineAttribute.cs20
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs19
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/SuppressMergeCheckAttribute.cs23
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/TaskAwaiter.cs26
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs57
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/TypeDependencyAttribute.cs18
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs35
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs34
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs61
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs14
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/YieldAwaitable.cs3
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs28
-rw-r--r--src/mscorlib/src/System/Runtime/ExceptionServices/CorruptingExceptionCommon.cs7
-rw-r--r--src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionNotification.cs13
-rw-r--r--src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionServicesCommon.cs36
-rw-r--r--src/mscorlib/src/System/Runtime/GcSettings.cs40
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ArrayWithOffset.cs36
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/Attributes.cs188
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/BStrWrapper.cs13
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/COMException.cs60
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/CallingConvention.cs21
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/CharSet.cs23
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComEventsHelper.cs220
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComEventsInfo.cs50
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComEventsMethod.cs100
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComEventsSink.cs104
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComMemberType.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IBindCtx.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPoint.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPointContainer.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnectionPoints.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnections.cs10
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumMoniker.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumString.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumVARIANT.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IMoniker.cs12
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IPersistFile.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IRunningObjectTable.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IStream.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeComp.cs18
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo.cs230
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo2.cs4
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib.cs40
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib2.cs12
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/CriticalHandle.cs224
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/CurrencyWrapper.cs15
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/DispatchWrapper.cs13
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ErrorWrapper.cs15
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/Expando/IExpando.cs9
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ExternalException.cs77
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/GCHandleCookieTable.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/GcHandle.cs18
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/HandleRef.cs27
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ICustomAdapter.cs9
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ICustomFactory.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ICustomMarshaler.cs15
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ICustomQueryInterface.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/ITypeLibConverter.cs12
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/InvalidComObjectException.cs38
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/InvalidOleVariantTypeException.cs40
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/LayoutKind.cs17
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs458
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/MarshalDirectiveException.cs38
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/NativeCallableAttribute.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/NativeMethods.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/NonPortable.cs64
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/PInvokeMap.cs60
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/RuntimeEnvironment.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/SEHException.cs45
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/SafeArrayRankMismatchException.cs40
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/SafeArrayTypeMismatchException.cs40
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs67
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/SafeHandle.cs515
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/UnknownWrapper.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/VariantWrapper.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/Attributes.cs5
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToCollectionAdapter.cs12
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToListAdapter.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIKeyValuePairImpl.cs3
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs210
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIReferenceImpl.cs55
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ConstantSplittableMap.cs48
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs20
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryKeyCollection.cs24
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryToMapAdapter.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryValueCollection.cs27
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EnumeratorToIteratorAdapter.cs10
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EventRegistrationTokenTable.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IClosable.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomProperty.cs30
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomPropertyProvider.cs126
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IIterable.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMap.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMapViewToIReadOnlyDictionaryAdapter.cs27
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IPropertyValue.cs10
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyDictionaryToIMapViewAdapter.cs7
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyListToIVectorViewAdapter.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVector.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVectorViewToIReadOnlyListAdapter.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IteratorToEnumeratorAdapter.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorAdapter.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorViewAdapter.cs3
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToVectorAdapter.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ManagedActivationFactory.cs4
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToCollectionAdapter.cs10
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToDictionaryAdapter.cs6
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapViewToReadOnlyCollectionAdapter.cs4
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/NativeMethods.cs10
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/PropertyValue.cs24
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/RuntimeClass.cs48
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToCollectionAdapter.cs8
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToListAdapter.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorViewToReadOnlyCollectionAdapter.cs2
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeBufferHelper.cs41
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs249
-rw-r--r--src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMetadata.cs65
-rw-r--r--src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs161
-rw-r--r--src/mscorlib/src/System/Runtime/MemoryFailPoint.cs180
-rw-r--r--src/mscorlib/src/System/Runtime/Reliability/PrePrepareMethodAttribute.cs7
-rw-r--r--src/mscorlib/src/System/Runtime/Reliability/ReliabilityContractAttribute.cs67
-rw-r--r--src/mscorlib/src/System/Runtime/Remoting/ObjectHandle.cs10
-rw-r--r--src/mscorlib/src/System/Runtime/RuntimeImports.cs35
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs121
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs75
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/IDeserializationCallback.cs22
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/IFormatterConverter.cs39
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs27
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs30
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs240
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationAttributes.cs59
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationException.cs44
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs41
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs145
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/StreamingContext.cs72
-rw-r--r--src/mscorlib/src/System/Runtime/Versioning/NonVersionableAttribute.cs33
-rw-r--r--src/mscorlib/src/System/Runtime/Versioning/TargetFrameworkAttribute.cs45
-rw-r--r--src/mscorlib/src/System/RuntimeArgumentHandle.cs9
-rw-r--r--src/mscorlib/src/System/RuntimeHandles.cs380
-rw-r--r--src/mscorlib/src/System/SByte.cs218
-rw-r--r--src/mscorlib/src/System/Security/Attributes.cs199
-rw-r--r--src/mscorlib/src/System/Security/DynamicSecurityMethodAttribute.cs21
-rw-r--r--src/mscorlib/src/System/Security/SecurityException.cs110
-rw-r--r--src/mscorlib/src/System/Security/SecurityState.cs25
-rw-r--r--src/mscorlib/src/System/Security/Util/URLString.cs138
-rw-r--r--src/mscorlib/src/System/Security/VerificationException.cs32
-rw-r--r--src/mscorlib/src/System/SerializableAttribute.cs24
-rw-r--r--src/mscorlib/src/System/SharedStatics.cs34
-rw-r--r--src/mscorlib/src/System/Single.cs220
-rw-r--r--src/mscorlib/src/System/Span.cs587
-rw-r--r--src/mscorlib/src/System/String.Comparison.cs383
-rw-r--r--src/mscorlib/src/System/String.Manipulation.cs634
-rw-r--r--src/mscorlib/src/System/String.Searching.cs180
-rw-r--r--src/mscorlib/src/System/String.cs408
-rw-r--r--src/mscorlib/src/System/StringComparer.cs300
-rw-r--r--src/mscorlib/src/System/StringComparison.cs29
-rw-r--r--src/mscorlib/src/System/StringFreezingAttribute.cs25
-rw-r--r--src/mscorlib/src/System/StringSplitOptions.cs13
-rw-r--r--src/mscorlib/src/System/StubHelpers.cs289
-rw-r--r--src/mscorlib/src/System/Text/ASCIIEncoding.cs757
-rw-r--r--src/mscorlib/src/System/Text/Decoder.cs338
-rw-r--r--src/mscorlib/src/System/Text/DecoderBestFitFallback.cs33
-rw-r--r--src/mscorlib/src/System/Text/DecoderExceptionFallback.cs28
-rw-r--r--src/mscorlib/src/System/Text/DecoderFallback.cs41
-rw-r--r--src/mscorlib/src/System/Text/DecoderNLS.cs87
-rw-r--r--src/mscorlib/src/System/Text/DecoderReplacementFallback.cs30
-rw-r--r--src/mscorlib/src/System/Text/Encoder.cs332
-rw-r--r--src/mscorlib/src/System/Text/EncoderBestFitFallback.cs39
-rw-r--r--src/mscorlib/src/System/Text/EncoderExceptionFallback.cs46
-rw-r--r--src/mscorlib/src/System/Text/EncoderFallback.cs30
-rw-r--r--src/mscorlib/src/System/Text/EncoderNLS.cs86
-rw-r--r--src/mscorlib/src/System/Text/EncoderReplacementFallback.cs44
-rw-r--r--src/mscorlib/src/System/Text/Encoding.cs428
-rw-r--r--src/mscorlib/src/System/Text/EncodingForwarder.cs329
-rw-r--r--src/mscorlib/src/System/Text/EncodingInfo.cs74
-rw-r--r--src/mscorlib/src/System/Text/EncodingNLS.cs125
-rw-r--r--src/mscorlib/src/System/Text/EncodingProvider.cs136
-rw-r--r--src/mscorlib/src/System/Text/Latin1Encoding.cs62
-rw-r--r--src/mscorlib/src/System/Text/Normalization.Unix.cs25
-rw-r--r--src/mscorlib/src/System/Text/Normalization.Windows.cs272
-rw-r--r--src/mscorlib/src/System/Text/Normalization.cs29
-rw-r--r--src/mscorlib/src/System/Text/StringBuilder.CoreCLR.cs48
-rw-r--r--src/mscorlib/src/System/Text/StringBuilder.cs2286
-rw-r--r--src/mscorlib/src/System/Text/StringBuilderCache.cs5
-rw-r--r--src/mscorlib/src/System/Text/UTF32Encoding.cs1003
-rw-r--r--src/mscorlib/src/System/Text/UTF7Encoding.cs372
-rw-r--r--src/mscorlib/src/System/Text/UTF8Encoding.cs2286
-rw-r--r--src/mscorlib/src/System/Text/UnicodeEncoding.cs1826
-rw-r--r--src/mscorlib/src/System/Threading/AbandonedMutexException.cs85
-rw-r--r--src/mscorlib/src/System/Threading/ApartmentState.cs27
-rw-r--r--src/mscorlib/src/System/Threading/AsyncLocal.cs487
-rw-r--r--src/mscorlib/src/System/Threading/AutoResetEvent.cs24
-rw-r--r--src/mscorlib/src/System/Threading/CancellationToken.cs32
-rw-r--r--src/mscorlib/src/System/Threading/CancellationTokenRegistration.cs6
-rw-r--r--src/mscorlib/src/System/Threading/CancellationTokenSource.cs48
-rw-r--r--src/mscorlib/src/System/Threading/ClrThreadPoolBoundHandle.cs (renamed from src/mscorlib/corefx/System/Threading/ClrThreadPoolBoundHandle.cs)0
-rw-r--r--src/mscorlib/src/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs (renamed from src/mscorlib/corefx/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs)0
-rw-r--r--src/mscorlib/src/System/Threading/ClrThreadPoolPreAllocatedOverlapped.cs (renamed from src/mscorlib/corefx/System/Threading/ClrThreadPoolPreAllocatedOverlapped.cs)0
-rw-r--r--src/mscorlib/src/System/Threading/CountdownEvent.cs589
-rw-r--r--src/mscorlib/src/System/Threading/EventResetMode.cs26
-rw-r--r--src/mscorlib/src/System/Threading/EventWaitHandle.cs59
-rw-r--r--src/mscorlib/src/System/Threading/ExecutionContext.cs380
-rw-r--r--src/mscorlib/src/System/Threading/Interlocked.cs45
-rw-r--r--src/mscorlib/src/System/Threading/LazyInitializer.cs131
-rw-r--r--src/mscorlib/src/System/Threading/LockRecursionException.cs30
-rw-r--r--src/mscorlib/src/System/Threading/ManualResetEvent.cs24
-rw-r--r--src/mscorlib/src/System/Threading/ManualResetEventSlim.cs16
-rw-r--r--src/mscorlib/src/System/Threading/Monitor.cs35
-rw-r--r--src/mscorlib/src/System/Threading/Mutex.cs92
-rw-r--r--src/mscorlib/src/System/Threading/Overlapped.cs100
-rw-r--r--src/mscorlib/src/System/Threading/ParameterizedThreadStart.cs23
-rw-r--r--src/mscorlib/src/System/Threading/ReaderWriterLockSlim.cs1311
-rw-r--r--src/mscorlib/src/System/Threading/Semaphore.cs32
-rw-r--r--src/mscorlib/src/System/Threading/SemaphoreFullException.cs27
-rw-r--r--src/mscorlib/src/System/Threading/SemaphoreSlim.cs37
-rw-r--r--src/mscorlib/src/System/Threading/SendOrPostCallback.cs16
-rw-r--r--src/mscorlib/src/System/Threading/SpinWait.cs59
-rw-r--r--src/mscorlib/src/System/Threading/SynchronizationContext.cs46
-rw-r--r--src/mscorlib/src/System/Threading/SynchronizationLockException.cs43
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/AsyncCausalityTracer.cs34
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs30
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/FutureFactory.cs39
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/IAsyncCausalityTracerStatics.cs10
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs14
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TPLETWProvider.cs196
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/Task.cs511
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskCanceledException.cs93
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs8
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskContinuation.cs33
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskExceptionHolder.cs38
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs73
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs75
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskSchedulerException.cs81
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/TaskToApm.cs6
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs24
-rw-r--r--src/mscorlib/src/System/Threading/Tasks/future.cs43
-rw-r--r--src/mscorlib/src/System/Threading/Thread.cs251
-rw-r--r--src/mscorlib/src/System/Threading/ThreadAbortException.cs39
-rw-r--r--src/mscorlib/src/System/Threading/ThreadInterruptedException.cs41
-rw-r--r--src/mscorlib/src/System/Threading/ThreadLocal.cs23
-rw-r--r--src/mscorlib/src/System/Threading/ThreadPool.cs259
-rw-r--r--src/mscorlib/src/System/Threading/ThreadPriority.cs31
-rw-r--r--src/mscorlib/src/System/Threading/ThreadStart.cs23
-rw-r--r--src/mscorlib/src/System/Threading/ThreadStartException.cs37
-rw-r--r--src/mscorlib/src/System/Threading/ThreadState.cs35
-rw-r--r--src/mscorlib/src/System/Threading/ThreadStateException.cs40
-rw-r--r--src/mscorlib/src/System/Threading/Timeout.cs19
-rw-r--r--src/mscorlib/src/System/Threading/Timer.cs159
-rw-r--r--src/mscorlib/src/System/Threading/Volatile.cs53
-rw-r--r--src/mscorlib/src/System/Threading/WaitHandle.cs203
-rw-r--r--src/mscorlib/src/System/Threading/WaitHandleCannotBeOpenedException.cs36
-rw-r--r--src/mscorlib/src/System/ThrowHelper.cs311
-rw-r--r--src/mscorlib/src/System/TimeSpan.cs302
-rw-r--r--src/mscorlib/src/System/TimeZone.cs246
-rw-r--r--src/mscorlib/src/System/TimeZoneInfo.AdjustmentRule.cs20
-rw-r--r--src/mscorlib/src/System/TimeZoneInfo.StringSerializer.cs62
-rw-r--r--src/mscorlib/src/System/TimeZoneInfo.TransitionTime.cs16
-rw-r--r--src/mscorlib/src/System/TimeZoneInfo.Unix.cs68
-rw-r--r--src/mscorlib/src/System/TimeZoneInfo.Win32.cs38
-rw-r--r--src/mscorlib/src/System/TimeZoneInfo.cs74
-rw-r--r--src/mscorlib/src/System/Tuple.cs28
-rw-r--r--src/mscorlib/src/System/TupleExtensions.cs930
-rw-r--r--src/mscorlib/src/System/Type.CoreCLR.cs206
-rw-r--r--src/mscorlib/src/System/Type.cs1764
-rw-r--r--src/mscorlib/src/System/TypeLoadException.cs106
-rw-r--r--src/mscorlib/src/System/TypeNameParser.cs19
-rw-r--r--src/mscorlib/src/System/TypeUnloadedException.cs42
-rw-r--r--src/mscorlib/src/System/TypedReference.cs49
-rw-r--r--src/mscorlib/src/System/UInt16.cs180
-rw-r--r--src/mscorlib/src/System/UInt32.cs148
-rw-r--r--src/mscorlib/src/System/UInt64.cs156
-rw-r--r--src/mscorlib/src/System/UIntPtr.cs80
-rw-r--r--src/mscorlib/src/System/UnitySerializationHolder.cs357
-rw-r--r--src/mscorlib/src/System/ValueTuple.cs2324
-rw-r--r--src/mscorlib/src/System/ValueType.cs38
-rw-r--r--src/mscorlib/src/System/Variant.cs395
-rw-r--r--src/mscorlib/src/System/Version.cs448
-rw-r--r--src/mscorlib/src/System/WeakReference.cs63
-rw-r--r--src/mscorlib/src/System/WeakReferenceOfT.cs25
-rw-r--r--src/mscorlib/src/System/XmlIgnoreMemberAttribute.cs21
-rw-r--r--src/mscorlib/src/System/__ComObject.cs36
-rw-r--r--src/mscorlib/src/System/__Filters.cs155
-rw-r--r--src/mscorlib/src/System/__HResults.cs153
-rw-r--r--src/mscorlib/src/mscorlib.Friends.cs8
-rw-r--r--src/pal/inc/pal.h39
-rw-r--r--src/pal/inc/pal_mstypes.h4
-rw-r--r--src/pal/inc/palprivate.h6
-rw-r--r--src/pal/inc/rt/palrt.h25
-rw-r--r--src/pal/inc/rt/xmmintrin.h113
-rw-r--r--src/pal/inc/unixasmmacrosamd64.inc9
-rw-r--r--src/pal/inc/unixasmmacrosarm64.inc120
-rw-r--r--src/pal/inc/unixasmmacrosx86.inc31
-rw-r--r--src/pal/prebuilt/inc/asm_version.h2
-rw-r--r--src/pal/prebuilt/inc/clrinternal.h2
-rw-r--r--src/pal/prebuilt/inc/fusionpriv.h2919
-rw-r--r--src/pal/prebuilt/inc/gchost.h2
-rw-r--r--src/pal/src/CMakeLists.txt70
-rw-r--r--src/pal/src/arch/amd64/callsignalhandlerwrapper.S31
-rw-r--r--src/pal/src/arch/amd64/optimizedtls.cpp237
-rw-r--r--src/pal/src/arch/amd64/signalhandlerhelper.cpp70
-rw-r--r--src/pal/src/arch/arm/callsignalhandlerwrapper.S32
-rw-r--r--src/pal/src/arch/arm/signalhandlerhelper.cpp70
-rw-r--r--src/pal/src/arch/arm64/asmconstants.h95
-rw-r--r--src/pal/src/arch/arm64/callsignalhandlerwrapper.S32
-rw-r--r--src/pal/src/arch/arm64/context2.S114
-rw-r--r--src/pal/src/arch/arm64/exceptionhelper.S25
-rw-r--r--src/pal/src/arch/arm64/signalhandlerhelper.cpp67
-rw-r--r--src/pal/src/arch/i386/asmconstants.h1
-rw-r--r--src/pal/src/arch/i386/callsignalhandlerwrapper.S47
-rw-r--r--src/pal/src/arch/i386/context2.S5
-rw-r--r--src/pal/src/arch/i386/exceptionhelper.S19
-rw-r--r--src/pal/src/arch/i386/signalhandlerhelper.cpp78
-rw-r--r--src/pal/src/config.h.in3
-rw-r--r--src/pal/src/configure.cmake31
-rw-r--r--src/pal/src/cruntime/math.cpp34
-rw-r--r--src/pal/src/cruntime/misctls.cpp308
-rw-r--r--src/pal/src/exception/seh-unwind.cpp2
-rw-r--r--src/pal/src/exception/seh.cpp11
-rw-r--r--src/pal/src/exception/signal.cpp206
-rw-r--r--src/pal/src/exception/signal.hpp52
-rw-r--r--src/pal/src/file/filetime.cpp28
-rw-r--r--src/pal/src/include/pal/context.h18
-rw-r--r--src/pal/src/include/pal/module.h2
-rw-r--r--src/pal/src/include/pal/signal.hpp140
-rw-r--r--src/pal/src/init/pal.cpp302
-rw-r--r--src/pal/src/init/sxs.cpp15
-rw-r--r--src/pal/src/loader/module.cpp20
-rw-r--r--src/pal/src/locale/unicode.cpp2
-rw-r--r--src/pal/src/misc/cgroup.cpp335
-rw-r--r--src/pal/src/misc/dbgmsg.cpp4
-rw-r--r--src/pal/src/misc/environ.cpp8
-rw-r--r--src/pal/src/misc/errorstrings.cpp2
-rw-r--r--src/pal/src/misc/sysinfo.cpp75
-rw-r--r--src/pal/src/misc/time.cpp32
-rw-r--r--src/pal/src/misc/utils.cpp7
-rw-r--r--src/pal/src/misc/version.cpp119
-rw-r--r--src/pal/src/thread/context.cpp36
-rw-r--r--src/pal/src/thread/process.cpp9
-rw-r--r--src/pal/src/thread/thread.cpp13
-rw-r--r--src/pal/tests/palsuite/c_runtime/pow/test1/test1.cpp12
-rw-r--r--src/pal/tests/palsuite/c_runtime/powf/test1/test1.c14
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/dlltest.cpp4
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/dlltest.cpp4
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/test1.cpp2
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/testlib.cpp4
-rw-r--r--src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/testlib.cpp4
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test6/dlltest.cpp4
-rw-r--r--src/pal/tests/palsuite/loader/LoadLibraryA/test8/dlltest.cpp4
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CGroup/CMakeLists.txt (renamed from src/pal/tests/palsuite/miscellaneous/GetVersionExA/CMakeLists.txt)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CGroup/test1/CMakeLists.txt17
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CGroup/test1/test.cpp53
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CGroup/test1/testinfo.dat12
-rw-r--r--src/pal/tests/palsuite/miscellaneous/CMakeLists.txt2
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/CMakeLists.txt17
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/test.cpp83
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/CMakeLists.txt17
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/test.cpp88
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GlobalMemoryStatusEx/CMakeLists.txt (renamed from src/pal/tests/palsuite/miscellaneous/GetVersionExW/CMakeLists.txt)0
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GlobalMemoryStatusEx/test1/CMakeLists.txt17
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GlobalMemoryStatusEx/test1/test.cpp55
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GlobalMemoryStatusEx/test1/testinfo.dat14
-rw-r--r--src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/palstartup.h9
-rw-r--r--src/pal/tests/palsuite/paltestlist.txt5
-rw-r--r--src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt6
-rw-r--r--src/pal/tests/palsuite/palverify.dat1
-rw-r--r--src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CreateMutexA.cpp5
-rw-r--r--src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CreateMutexW.cpp5
-rw-r--r--src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/test1.cpp4
-rw-r--r--src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/testlib.cpp6
-rw-r--r--src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain1.cpp2
-rw-r--r--src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain2.cpp2
-rw-r--r--src/pal/tests/palsuite/threading/ExitThread/test3/dllmain.cpp2
-rwxr-xr-xsrc/pal/tools/gen-buildsys-clang.sh23
-rw-r--r--src/pal/tools/gen-buildsys-win.bat3
-rw-r--r--src/pal/tools/probe-win.ps18
-rw-r--r--src/strongname/api/strongname.cpp4571
-rw-r--r--src/strongname/api/strongnamecoreclr.cpp3
-rw-r--r--src/strongname/api/strongnameinternal.cpp14
-rw-r--r--src/strongname/inc/sncoreclr.h3
-rw-r--r--src/strongname/inc/strongnameholders.h4
-rw-r--r--src/strongname/inc/strongnameinternal.h6
-rw-r--r--src/strongname/inc/thekey.h2
-rw-r--r--src/tools/crossgen/crossgen.cpp65
-rw-r--r--src/tools/metainfo/mdinfo.cpp11
-rw-r--r--src/unwinder/arm64/unwinder_arm64.cpp53
-rw-r--r--src/unwinder/i386/unwinder_i386.cpp17
-rw-r--r--src/utilcode/CMakeLists.txt5
-rw-r--r--src/utilcode/apithreadstress.cpp183
-rw-r--r--src/utilcode/appxutil.cpp820
-rw-r--r--src/utilcode/ccomprc.cpp83
-rw-r--r--src/utilcode/clrconfig.cpp159
-rw-r--r--src/utilcode/clrhost.cpp8
-rw-r--r--src/utilcode/dlwrap.cpp152
-rw-r--r--src/utilcode/downlevel.cpp4
-rw-r--r--src/utilcode/ex.cpp10
-rw-r--r--src/utilcode/longfilepathwrappers.cpp2
-rw-r--r--src/utilcode/makepath.cpp203
-rw-r--r--src/utilcode/newapis.cpp78
-rw-r--r--src/utilcode/pedecoder.cpp75
-rw-r--r--src/utilcode/peinformation.cpp94
-rw-r--r--src/utilcode/prettyprintsig.cpp4
-rw-r--r--src/utilcode/registrywrapper.cpp285
-rw-r--r--src/utilcode/regutil.cpp697
-rw-r--r--src/utilcode/safewrap.cpp5
-rw-r--r--src/utilcode/sortversioning.cpp244
-rw-r--r--src/utilcode/stacktrace.cpp4
-rw-r--r--src/utilcode/stresslog.cpp27
-rw-r--r--src/utilcode/tlbutils.cpp221
-rw-r--r--src/utilcode/util.cpp246
-rw-r--r--src/utilcode/utilmessagebox.cpp186
-rw-r--r--src/utilcode/utsem.cpp4
-rw-r--r--src/vm/CMakeLists.txt18
-rw-r--r--src/vm/amd64/GenericComPlusCallStubs.asm93
-rw-r--r--src/vm/amd64/JitHelpers_Slow.asm68
-rw-r--r--src/vm/amd64/PInvokeStubs.asm144
-rw-r--r--src/vm/amd64/RemotingThunksAMD64.asm303
-rw-r--r--src/vm/amd64/UMThunkStub.asm159
-rw-r--r--src/vm/amd64/asmconstants.h22
-rw-r--r--src/vm/amd64/cgenamd64.cpp29
-rw-r--r--src/vm/amd64/cgencpu.h4
-rw-r--r--src/vm/amd64/jithelpers_fast.S61
-rw-r--r--src/vm/amd64/jithelpers_fastwritebarriers.S150
-rw-r--r--src/vm/amd64/jithelpers_slow.S24
-rw-r--r--src/vm/amd64/jitinterfaceamd64.cpp136
-rw-r--r--src/vm/amd64/remotingamd64.cpp672
-rw-r--r--src/vm/amd64/unixstubs.cpp15
-rw-r--r--src/vm/appdomain.cpp2910
-rw-r--r--src/vm/appdomain.hpp227
-rw-r--r--src/vm/appdomain.inl9
-rw-r--r--src/vm/appdomainhelper.cpp546
-rw-r--r--src/vm/appdomainhelper.h371
-rw-r--r--src/vm/appdomainnative.cpp505
-rw-r--r--src/vm/appdomainnative.hpp40
-rw-r--r--src/vm/appdomainstack.cpp4
-rw-r--r--src/vm/appxutil.cpp40
-rw-r--r--src/vm/aptca.cpp1363
-rw-r--r--src/vm/aptca.h110
-rw-r--r--src/vm/arm/asmconstants.h17
-rw-r--r--src/vm/arm/asmhelpers.asm524
-rw-r--r--src/vm/arm/cgencpu.h3
-rw-r--r--src/vm/arm/ehhelpers.S21
-rw-r--r--src/vm/arm/exceparm.cpp32
-rw-r--r--src/vm/arm/excepcpu.h1
-rw-r--r--src/vm/arm/stubs.cpp184
-rw-r--r--src/vm/arm/unixstubs.cpp5
-rw-r--r--src/vm/arm/virtualcallstubcpu.hpp3
-rw-r--r--src/vm/arm64/asmhelpers.S514
-rw-r--r--src/vm/arm64/asmhelpers.asm40
-rw-r--r--src/vm/arm64/calldescrworkerarm64.S42
-rw-r--r--src/vm/arm64/cgencpu.h12
-rw-r--r--src/vm/arm64/gmscpu.h33
-rw-r--r--src/vm/arm64/pinvokestubs.S45
-rw-r--r--src/vm/arm64/stubs.cpp105
-rw-r--r--src/vm/assembly.cpp2203
-rw-r--r--src/vm/assembly.hpp158
-rw-r--r--src/vm/assemblyname.cpp108
-rw-r--r--src/vm/assemblyname.hpp1
-rw-r--r--src/vm/assemblynamesconfigfactory.cpp264
-rw-r--r--src/vm/assemblynamesconfigfactory.h72
-rw-r--r--src/vm/assemblynative.cpp766
-rw-r--r--src/vm/assemblynative.hpp44
-rw-r--r--src/vm/assemblysink.cpp153
-rw-r--r--src/vm/assemblysink.h59
-rw-r--r--src/vm/assemblyspec.cpp647
-rw-r--r--src/vm/assemblyspec.hpp78
-rw-r--r--src/vm/assemblyspecbase.h2
-rw-r--r--src/vm/baseassemblyspec.cpp30
-rw-r--r--src/vm/baseassemblyspec.h63
-rw-r--r--src/vm/baseassemblyspec.inl80
-rw-r--r--src/vm/binder.cpp8
-rw-r--r--src/vm/callcounter.cpp98
-rw-r--r--src/vm/callcounter.h87
-rw-r--r--src/vm/callhelpers.cpp15
-rw-r--r--src/vm/callingconvention.h11
-rw-r--r--src/vm/ceeload.cpp1749
-rw-r--r--src/vm/ceeload.h123
-rw-r--r--src/vm/ceemain.cpp1830
-rw-r--r--src/vm/ceemain.h45
-rw-r--r--src/vm/class.cpp18
-rw-r--r--src/vm/class.h71
-rw-r--r--src/vm/class.inl4
-rw-r--r--src/vm/classcompat.cpp3
-rw-r--r--src/vm/classfactory.cpp3
-rw-r--r--src/vm/classnames.h17
-rw-r--r--src/vm/clrconfignative.cpp21
-rw-r--r--src/vm/clrconfignative.h14
-rw-r--r--src/vm/clrex.cpp166
-rw-r--r--src/vm/clrex.h14
-rw-r--r--src/vm/clrprivbinderappx.cpp1057
-rw-r--r--src/vm/clrprivbinderappx.h364
-rw-r--r--src/vm/clrprivbinderfusion.cpp819
-rw-r--r--src/vm/clrprivbinderfusion.h228
-rw-r--r--src/vm/clrprivbinderloadfile.cpp264
-rw-r--r--src/vm/clrprivbinderreflectiononlywinrt.cpp497
-rw-r--r--src/vm/clrprivbinderreflectiononlywinrt.h295
-rw-r--r--src/vm/clrprivbinderutil.cpp461
-rw-r--r--src/vm/clrprivbinderwinrt.cpp477
-rw-r--r--src/vm/clrprivbinderwinrt.h49
-rw-r--r--src/vm/clrprivtypecachereflectiononlywinrt.cpp260
-rw-r--r--src/vm/clrprivtypecachereflectiononlywinrt.h58
-rw-r--r--src/vm/clrtocomcall.cpp234
-rw-r--r--src/vm/clsload.cpp240
-rw-r--r--src/vm/clsload.hpp17
-rw-r--r--src/vm/clsload.inl6
-rw-r--r--src/vm/codeman.cpp67
-rw-r--r--src/vm/comcache.cpp15
-rw-r--r--src/vm/comcallablewrapper.cpp100
-rw-r--r--src/vm/comcallablewrapper.h7
-rw-r--r--src/vm/comdelegate.cpp275
-rw-r--r--src/vm/comdelegate.h8
-rw-r--r--src/vm/comdynamic.cpp442
-rw-r--r--src/vm/comdynamic.h15
-rw-r--r--src/vm/cominterfacemarshaler.cpp146
-rw-r--r--src/vm/comisolatedstorage.cpp1073
-rw-r--r--src/vm/comisolatedstorage.h202
-rw-r--r--src/vm/commemoryfailpoint.cpp4
-rw-r--r--src/vm/commethodrental.cpp120
-rw-r--r--src/vm/commethodrental.h29
-rw-r--r--src/vm/commodule.cpp114
-rw-r--r--src/vm/commodule.h13
-rw-r--r--src/vm/common.h15
-rw-r--r--src/vm/compile.cpp1036
-rw-r--r--src/vm/compile.h65
-rw-r--r--src/vm/comsynchronizable.cpp482
-rw-r--r--src/vm/comsynchronizable.h31
-rw-r--r--src/vm/comthreadpool.cpp47
-rw-r--r--src/vm/comthreadpool.h2
-rw-r--r--src/vm/comtoclrcall.cpp30
-rw-r--r--src/vm/comtypelibconverter.cpp791
-rw-r--r--src/vm/comtypelibconverter.h107
-rw-r--r--src/vm/comutilnative.cpp146
-rw-r--r--src/vm/comutilnative.h45
-rw-r--r--src/vm/comwaithandle.cpp125
-rw-r--r--src/vm/constrainedexecutionregion.cpp2265
-rw-r--r--src/vm/constrainedexecutionregion.h566
-rw-r--r--src/vm/context.h180
-rw-r--r--src/vm/contexts.cpp911
-rw-r--r--src/vm/coreassemblyspec.cpp107
-rw-r--r--src/vm/corebindresult.cpp2
-rw-r--r--src/vm/corhost.cpp4376
-rw-r--r--src/vm/crossdomaincalls.cpp2587
-rw-r--r--src/vm/crossdomaincalls.h272
-rw-r--r--src/vm/crossgen/CMakeLists.txt6
-rw-r--r--src/vm/crossgencompile.cpp18
-rw-r--r--src/vm/crst.cpp213
-rw-r--r--src/vm/crst.h3
-rw-r--r--src/vm/customattribute.cpp87
-rw-r--r--src/vm/dangerousapis.h14
-rw-r--r--src/vm/dataimage.cpp10
-rw-r--r--src/vm/debugdebugger.cpp133
-rw-r--r--src/vm/debugdebugger.h10
-rw-r--r--src/vm/debughelp.cpp2
-rw-r--r--src/vm/disassembler.h5
-rw-r--r--src/vm/dllimport.cpp1047
-rw-r--r--src/vm/dllimport.h44
-rw-r--r--src/vm/dllimportcallback.cpp259
-rw-r--r--src/vm/dllimportcallback.h22
-rw-r--r--src/vm/domainfile.cpp1377
-rw-r--r--src/vm/domainfile.h138
-rw-r--r--src/vm/domainfile.inl8
-rw-r--r--src/vm/dwbucketmanager.hpp43
-rw-r--r--src/vm/dwreport.cpp88
-rw-r--r--src/vm/dwreport.h2
-rw-r--r--src/vm/ecall.h8
-rw-r--r--src/vm/ecalllist.h526
-rw-r--r--src/vm/eeconfig.cpp464
-rw-r--r--src/vm/eeconfig.h45
-rw-r--r--src/vm/eeconfigfactory.cpp398
-rw-r--r--src/vm/eeconfigfactory.h149
-rw-r--r--src/vm/eedbginterfaceimpl.cpp11
-rw-r--r--src/vm/eepolicy.cpp85
-rw-r--r--src/vm/eetoprofinterfaceimpl.cpp134
-rw-r--r--src/vm/eetwain.cpp158
-rw-r--r--src/vm/eventpipe.cpp234
-rw-r--r--src/vm/eventpipe.h154
-rw-r--r--src/vm/eventpipejsonfile.cpp131
-rw-r--r--src/vm/eventpipejsonfile.h40
-rw-r--r--src/vm/eventreporter.cpp26
-rw-r--r--src/vm/eventreporter.h2
-rw-r--r--src/vm/eventtrace.cpp76
-rw-r--r--src/vm/excep.cpp340
-rw-r--r--src/vm/excep.h15
-rw-r--r--src/vm/exceptionhandling.cpp389
-rw-r--r--src/vm/exceptionhandling.h22
-rw-r--r--src/vm/exinfo.cpp2
-rw-r--r--src/vm/exinfo.h4
-rw-r--r--src/vm/exstate.cpp6
-rw-r--r--src/vm/exstate.h6
-rw-r--r--src/vm/fcall.h148
-rw-r--r--src/vm/field.cpp98
-rw-r--r--src/vm/field.h15
-rw-r--r--src/vm/fieldmarshaler.h5
-rw-r--r--src/vm/finalizerthread.cpp341
-rw-r--r--src/vm/finalizerthread.h2
-rw-r--r--src/vm/fptrstubs.cpp15
-rw-r--r--src/vm/frames.cpp215
-rw-r--r--src/vm/frames.h170
-rw-r--r--src/vm/fusionbind.cpp661
-rw-r--r--src/vm/fusioninit.cpp624
-rw-r--r--src/vm/fusionsink.cpp215
-rw-r--r--src/vm/gccover.cpp5
-rw-r--r--src/vm/gcenv.ee.cpp116
-rw-r--r--src/vm/gcenv.ee.h7
-rw-r--r--src/vm/gcenv.h9
-rw-r--r--src/vm/gcenv.os.cpp62
-rw-r--r--src/vm/gchandletableutilities.h354
-rw-r--r--src/vm/gcheaputilities.cpp50
-rw-r--r--src/vm/gcheaputilities.h81
-rw-r--r--src/vm/gchelpers.cpp232
-rw-r--r--src/vm/gchelpers.inl108
-rw-r--r--src/vm/gchost.cpp276
-rw-r--r--src/vm/gcinfodecoder.cpp60
-rw-r--r--src/vm/gcscan.h5
-rw-r--r--src/vm/gcstress.h7
-rw-r--r--src/vm/gdbjit.cpp905
-rw-r--r--src/vm/gdbjit.h174
-rw-r--r--src/vm/gdbjithelpers.h14
-rw-r--r--src/vm/generics.cpp44
-rw-r--r--src/vm/hostexecutioncontext.cpp230
-rw-r--r--src/vm/hostexecutioncontext.h29
-rw-r--r--src/vm/hosting.cpp1027
-rw-r--r--src/vm/i386/asmconstants.h42
-rw-r--r--src/vm/i386/asmhelpers.S182
-rw-r--r--src/vm/i386/asmhelpers.asm429
-rw-r--r--src/vm/i386/cgencpu.h11
-rw-r--r--src/vm/i386/cgenx86.cpp590
-rw-r--r--src/vm/i386/ehhelpers.S103
-rw-r--r--src/vm/i386/excepx86.cpp9
-rw-r--r--src/vm/i386/jithelp.S36
-rw-r--r--src/vm/i386/jithelp.asm78
-rw-r--r--src/vm/i386/jitinterfacex86.cpp174
-rw-r--r--src/vm/i386/remotingx86.cpp225
-rw-r--r--src/vm/i386/stublinkerx86.cpp77
-rw-r--r--src/vm/i386/stublinkerx86.h4
-rw-r--r--src/vm/i386/umthunkstub.S71
-rw-r--r--src/vm/i386/unixstubs.cpp31
-rw-r--r--src/vm/i386/virtualcallstubcpu.hpp117
-rw-r--r--src/vm/ilmarshalers.cpp129
-rw-r--r--src/vm/ilmarshalers.h41
-rw-r--r--src/vm/ilstubcache.cpp41
-rw-r--r--src/vm/inlinetracking.cpp390
-rw-r--r--src/vm/inlinetracking.h221
-rw-r--r--src/vm/interopconverter.cpp359
-rw-r--r--src/vm/interopconverter.h15
-rw-r--r--src/vm/interoputil.cpp209
-rw-r--r--src/vm/interpreter.cpp23
-rw-r--r--src/vm/invokeutil.cpp142
-rw-r--r--src/vm/invokeutil.h10
-rw-r--r--src/vm/jithelpers.cpp179
-rw-r--r--src/vm/jitinterface.cpp744
-rw-r--r--src/vm/jitinterface.h86
-rw-r--r--src/vm/jitinterfacegen.cpp5
-rw-r--r--src/vm/marshalnative.cpp83
-rw-r--r--src/vm/mda.cpp4017
-rw-r--r--src/vm/mda.h1
-rw-r--r--src/vm/mdaassistants.cpp2
-rw-r--r--src/vm/mdadac.cpp48
-rw-r--r--src/vm/memberload.cpp6
-rw-r--r--src/vm/message.cpp1171
-rw-r--r--src/vm/message.h200
-rw-r--r--src/vm/metasig.h62
-rw-r--r--src/vm/method.cpp285
-rw-r--r--src/vm/method.hpp133
-rw-r--r--src/vm/method.inl2
-rw-r--r--src/vm/methodtable.cpp191
-rw-r--r--src/vm/methodtable.h128
-rw-r--r--src/vm/methodtable.inl88
-rw-r--r--src/vm/methodtablebuilder.cpp748
-rw-r--r--src/vm/methodtablebuilder.h57
-rw-r--r--src/vm/mixedmode.cpp236
-rw-r--r--src/vm/mixedmode.hpp139
-rw-r--r--src/vm/mlinfo.cpp81
-rw-r--r--src/vm/mlinfo.h41
-rw-r--r--src/vm/mngstdinterfaces.cpp26
-rw-r--r--src/vm/mscorlib.cpp22
-rw-r--r--src/vm/mscorlib.h495
-rw-r--r--src/vm/mscoruefwrapper.h19
-rw-r--r--src/vm/mtypes.h7
-rw-r--r--src/vm/multicorejit.cpp212
-rw-r--r--src/vm/multicorejit.h11
-rw-r--r--src/vm/multicorejitimpl.h16
-rw-r--r--src/vm/multicorejitplayer.cpp47
-rw-r--r--src/vm/namespace.h6
-rw-r--r--src/vm/nativeoverlapped.cpp23
-rw-r--r--src/vm/ngenoptout.cpp37
-rw-r--r--src/vm/ngenoptout.h34
-rw-r--r--src/vm/object.cpp34
-rw-r--r--src/vm/object.h706
-rw-r--r--src/vm/objectclone.cpp3865
-rw-r--r--src/vm/objectclone.h1268
-rw-r--r--src/vm/olevariant.cpp6
-rw-r--r--src/vm/pefile.cpp2302
-rw-r--r--src/vm/pefile.h322
-rw-r--r--src/vm/pefile.inl289
-rw-r--r--src/vm/pefingerprint.cpp557
-rw-r--r--src/vm/pefingerprint.h89
-rw-r--r--src/vm/peimage.cpp810
-rw-r--r--src/vm/peimage.h110
-rw-r--r--src/vm/peimage.inl178
-rw-r--r--src/vm/peimagelayout.cpp174
-rw-r--r--src/vm/peimagelayout.h17
-rw-r--r--src/vm/precode.cpp56
-rw-r--r--src/vm/precode.h11
-rw-r--r--src/vm/prestub.cpp154
-rw-r--r--src/vm/profattach.cpp17
-rw-r--r--src/vm/profilinghelper.cpp43
-rw-r--r--src/vm/proftoeeinterfaceimpl.cpp118
-rw-r--r--src/vm/qcall.h4
-rw-r--r--src/vm/rcwwalker.cpp2
-rw-r--r--src/vm/readytoruninfo.cpp45
-rw-r--r--src/vm/readytoruninfo.h11
-rw-r--r--src/vm/reflectclasswriter.h5
-rw-r--r--src/vm/reflectioninvocation.cpp619
-rw-r--r--src/vm/reflectioninvocation.h6
-rw-r--r--src/vm/rejit.cpp6
-rw-r--r--src/vm/remoting.cpp3773
-rw-r--r--src/vm/remoting.h957
-rw-r--r--src/vm/rexcep.h40
-rw-r--r--src/vm/runtimecallablewrapper.cpp78
-rw-r--r--src/vm/runtimehandles.cpp100
-rw-r--r--src/vm/runtimehandles.h17
-rw-r--r--src/vm/rwlock.cpp2952
-rw-r--r--src/vm/rwlock.h287
-rw-r--r--src/vm/sampleprofiler.cpp155
-rw-r--r--src/vm/sampleprofiler.h44
-rw-r--r--src/vm/security.cpp18
-rw-r--r--src/vm/security.h64
-rw-r--r--src/vm/security.inl219
-rw-r--r--src/vm/securityattributes.cpp98
-rw-r--r--src/vm/securityattributes.h20
-rw-r--r--src/vm/securityconfig.cpp2181
-rw-r--r--src/vm/securityconfig.h122
-rw-r--r--src/vm/securitydeclarative.cpp889
-rw-r--r--src/vm/securitydeclarative.h23
-rw-r--r--src/vm/securitydeclarativecache.cpp58
-rw-r--r--src/vm/securitydescriptor.cpp288
-rw-r--r--src/vm/securitydescriptor.h48
-rw-r--r--src/vm/securitydescriptor.inl25
-rw-r--r--src/vm/securitydescriptorappdomain.cpp155
-rw-r--r--src/vm/securitydescriptorappdomain.h35
-rw-r--r--src/vm/securitydescriptorappdomain.inl51
-rw-r--r--src/vm/securitydescriptorassembly.cpp333
-rw-r--r--src/vm/securitydescriptorassembly.h37
-rw-r--r--src/vm/securitydescriptorassembly.inl31
-rw-r--r--src/vm/securitymeta.cpp383
-rw-r--r--src/vm/securitymeta.h18
-rw-r--r--src/vm/securitymeta.inl45
-rw-r--r--src/vm/securitypolicy.cpp854
-rw-r--r--src/vm/securitypolicy.h77
-rw-r--r--src/vm/securitystackwalk.h35
-rw-r--r--src/vm/securitytransparentassembly.cpp420
-rw-r--r--src/vm/sha1.h4
-rw-r--r--src/vm/spinlock.cpp92
-rw-r--r--src/vm/spinlock.h13
-rw-r--r--src/vm/stackbuildersink.cpp702
-rw-r--r--src/vm/stackbuildersink.h49
-rw-r--r--src/vm/stackprobe.h16
-rw-r--r--src/vm/stackwalk.cpp58
-rw-r--r--src/vm/stdinterfaces.cpp348
-rw-r--r--src/vm/stubhelpers.cpp230
-rw-r--r--src/vm/stubhelpers.h6
-rw-r--r--src/vm/stubmgr.cpp15
-rw-r--r--src/vm/syncblk.cpp21
-rw-r--r--src/vm/synch.cpp500
-rw-r--r--src/vm/synch.h5
-rw-r--r--src/vm/synchronizationcontextnative.cpp2
-rw-r--r--src/vm/synchronizationcontextnative.h2
-rw-r--r--src/vm/testhookmgr.cpp1
-rw-r--r--src/vm/threadpoolrequest.cpp19
-rw-r--r--src/vm/threads.cpp2371
-rw-r--r--src/vm/threads.h477
-rw-r--r--src/vm/threadsuspend.cpp813
-rw-r--r--src/vm/threadsuspend.h3
-rw-r--r--src/vm/tieredcompilation.cpp377
-rw-r--r--src/vm/tieredcompilation.h51
-rw-r--r--src/vm/tlbexport.cpp6344
-rw-r--r--src/vm/typehandle.cpp4
-rw-r--r--src/vm/typeparse.cpp51
-rw-r--r--src/vm/typeparse.h3
-rw-r--r--src/vm/umthunkhash.cpp171
-rw-r--r--src/vm/umthunkhash.h87
-rw-r--r--src/vm/util.cpp83
-rw-r--r--src/vm/util.hpp188
-rw-r--r--src/vm/validator.cpp946
-rw-r--r--src/vm/vars.cpp14
-rw-r--r--src/vm/vars.hpp48
-rw-r--r--src/vm/virtualcallstub.cpp214
-rw-r--r--src/vm/virtualcallstub.h14
-rw-r--r--src/vm/win32threadpool.cpp538
-rw-r--r--src/vm/win32threadpool.h92
-rw-r--r--src/vm/wks/CMakeLists.txt14
-rw-r--r--src/zap/common.h6
-rw-r--r--src/zap/svcworker.cpp823
-rw-r--r--src/zap/zapcode.cpp22
-rw-r--r--src/zap/zapheaders.cpp12
-rw-r--r--src/zap/zapimage.cpp542
-rw-r--r--src/zap/zapimage.h63
-rw-r--r--src/zap/zapimport.cpp65
-rw-r--r--src/zap/zapinfo.cpp53
-rw-r--r--src/zap/zapinfo.h8
-rw-r--r--src/zap/zapper.cpp2336
-rw-r--r--src/zap/zapreadytorun.cpp17
2395 files changed, 148059 insertions, 341184 deletions
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.builds b/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.builds
index f84ccd07c8..b14c6b29ab 100644
--- a/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.builds
+++ b/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.builds
@@ -2,95 +2,9 @@
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <!-- This property must be set to the same value as $(PackageOutputPath) for the nuspecs and nupkgs to be binplaced to the intended location. -->
- <OutputPath>$(PackageOutputPath)</OutputPath>
- </PropertyGroup>
-
- <!-- We always build the identity/redirection package. However, the platform specific runtime-*.nupkg is built based upon the target OS we are building the product for. -->
<ItemGroup>
- <Project Include="Microsoft.NETCore.ILAsm.pkgproj">
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>arm64</Platform>
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>x86</Platform>
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>arm</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'linux-x64'" Include="linux/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'debian.8-x64'" Include="debian/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'debian.8-armel'" Include="debian/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>armel</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'fedora.23-x64'" Include="fedora/23/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'fedora.24-x64'" Include="fedora/24/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'opensuse.13.2-x64'" Include="opensuse/13.2/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'opensuse.42.1-x64'" Include="opensuse/42.1/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and $(DistroRid.StartsWith('rhel.7'))" Include="rhel/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.14.04-x64'" Include="ubuntu/14.04/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.14.04-arm'" Include="ubuntu/14.04/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>arm</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.04-x64'" Include="ubuntu/16.04/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.04-arm'" Include="ubuntu/16.04/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>arm</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.10-x64'" Include="ubuntu/16.10/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'alpine.3.4.3-x64'" Include="alpine/3.4.3/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'tizen.4.0.0-armel'" Include="tizen/4.0.0/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>armel</Platform>
- </Project>
- <Project Condition="'$(TargetsOSX)' == 'true'" Include="osx/Microsoft.NETCore.ILAsm.pkgproj">
- <OSGroup>OSX</OSGroup>
- <Platform>amd64</Platform>
- </Project>
+ <!-- identity project, runtime specific projects are included by props above -->
+ <Project Include="$(MSBuildProjectName).pkgproj" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.pkgproj
index 4a5b1ad584..c36aa5b2ec 100644
--- a/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.pkgproj
+++ b/src/.nuget/Microsoft.NETCore.ILAsm/Microsoft.NETCore.ILAsm.pkgproj
@@ -1,75 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <SkipValidatePackage>true</SkipValidatePackage>
- <PackagePlatforms>x64;x86;arm64;arm;armel;</PackagePlatforms>
- <OutputPath>$(PackagesOutputPath)</OutputPath>
- <IncludeRuntimeJson>true</IncludeRuntimeJson>
+
+ <PropertyGroup Condition="'$(PackageTargetRuntime)' == ''">
+ <IsLineupPackage Condition="'$(IsLineupPackage)' == ''">true</IsLineupPackage>
</PropertyGroup>
- <ItemGroup>
- <ProjectReference Include="..\Microsoft.NETCore.Runtime.CoreCLR\Microsoft.NETCore.Runtime.CoreCLR.pkgproj" />
- <ProjectReference Include="win\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="win\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>arm64</Platform>
- </ProjectReference>
- <ProjectReference Include="win\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>x86</Platform>
- </ProjectReference>
- <ProjectReference Include="win\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>arm</Platform>
- </ProjectReference>
- <ProjectReference Include="linux\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="debian\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="debian\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>armel</Platform>
- </ProjectReference>
- <ProjectReference Include="fedora\23\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="fedora\24\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="opensuse\13.2\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="opensuse\42.1\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="rhel\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\14.04\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\14.04\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>arm</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.04\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.04\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>arm</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.10\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="alpine\3.4.3\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="tizen\4.0.0\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>armel</Platform>
- </ProjectReference>
- <ProjectReference Include="osx\Microsoft.NETCore.ILAsm.pkgproj">
- <Platform>amd64</Platform>
+
+ <ItemGroup Condition="'$(IsLineupPackage)' == 'true'">
+ <ProjectReference Include="..\Microsoft.NETCore.Runtime.CoreCLR\Microsoft.NETCore.Runtime.CoreCLR.pkgproj" >
+ <!-- we should look at moving this into packaging.targets instead of having to carry this around for every pkgproj project reference -->
+ <AdditionalProperties>%(ProjectReference.AdditionalProperties);IsLineupPackage=false</AdditionalProperties>
</ProjectReference>
</ItemGroup>
+
+ <Import Condition="'$(_packageTargetOSGroup)' != ''" Project="$(MSBuildThisFileDirectory)runtime.$(_packageTargetOSGroup).$(MSBuildProjectName).props" />
+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/alpine/3.4.3/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/alpine/3.4.3/Microsoft.NETCore.ILAsm.pkgproj
deleted file mode 100644
index 41a5b4c301..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILAsm/alpine/3.4.3/Microsoft.NETCore.ILAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>alpine.3.4.3-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ilasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/debian/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/debian/Microsoft.NETCore.ILAsm.pkgproj
deleted file mode 100644
index 99c782c01d..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILAsm/debian/Microsoft.NETCore.ILAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>debian.8-$(PackagePlatform)</PackageTargetRuntime>
- <!-- build for x64, armel -->
- <PackagePlatforms>x64;armel;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ilasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/fedora/23/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/fedora/23/Microsoft.NETCore.ILAsm.pkgproj
deleted file mode 100644
index ac8f53b4fe..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILAsm/fedora/23/Microsoft.NETCore.ILAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>fedora.23-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ilasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/fedora/24/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/fedora/24/Microsoft.NETCore.ILAsm.pkgproj
deleted file mode 100644
index 3ad08a9b77..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILAsm/fedora/24/Microsoft.NETCore.ILAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>fedora.24-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ilasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/linux/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/linux/Microsoft.NETCore.ILAsm.pkgproj
deleted file mode 100644
index ce3bf6320e..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILAsm/linux/Microsoft.NETCore.ILAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>linux-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ilasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/opensuse/13.2/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/opensuse/13.2/Microsoft.NETCore.ILAsm.pkgproj
deleted file mode 100644
index 6181ab366e..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILAsm/opensuse/13.2/Microsoft.NETCore.ILAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>opensuse.13.2-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ilasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/opensuse/42.1/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/opensuse/42.1/Microsoft.NETCore.ILAsm.pkgproj
deleted file mode 100644
index 85adbd6092..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILAsm/opensuse/42.1/Microsoft.NETCore.ILAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>opensuse.42.1-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ilasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/osx/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/osx/Microsoft.NETCore.ILAsm.pkgproj
deleted file mode 100644
index bee340b23c..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILAsm/osx/Microsoft.NETCore.ILAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>osx.10.10-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ilasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dwarf')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dwarf" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dylib" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/rhel/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/rhel/Microsoft.NETCore.ILAsm.pkgproj
deleted file mode 100644
index 6410798f63..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILAsm/rhel/Microsoft.NETCore.ILAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>rhel.7-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ilasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/runtime.Linux.Microsoft.NETCore.ILAsm.props b/src/.nuget/Microsoft.NETCore.ILAsm/runtime.Linux.Microsoft.NETCore.ILAsm.props
new file mode 100644
index 0000000000..a8019b21e6
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.ILAsm/runtime.Linux.Microsoft.NETCore.ILAsm.props
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)ilasm" />
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/runtime.OSX.Microsoft.NETCore.ILAsm.props b/src/.nuget/Microsoft.NETCore.ILAsm/runtime.OSX.Microsoft.NETCore.ILAsm.props
new file mode 100644
index 0000000000..a8019b21e6
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.ILAsm/runtime.OSX.Microsoft.NETCore.ILAsm.props
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)ilasm" />
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/runtime.Windows_NT.Microsoft.NETCore.ILAsm.props b/src/.nuget/Microsoft.NETCore.ILAsm/runtime.Windows_NT.Microsoft.NETCore.ILAsm.props
new file mode 100644
index 0000000000..e08b0241c5
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.ILAsm/runtime.Windows_NT.Microsoft.NETCore.ILAsm.props
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <PackageTargetRuntime>$(MinOSForArch)-$(PackagePlatform)</PackageTargetRuntime>
+ </PropertyGroup>
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)ilasm.exe" />
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/tizen/4.0.0/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/tizen/4.0.0/Microsoft.NETCore.ILAsm.pkgproj
deleted file mode 100644
index 1d235b6f59..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILAsm/tizen/4.0.0/Microsoft.NETCore.ILAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>tizen.4.0.0-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for armel -->
- <PackagePlatforms>armel;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ilasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/ubuntu/14.04/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/ubuntu/14.04/Microsoft.NETCore.ILAsm.pkgproj
deleted file mode 100644
index cacadc78b1..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILAsm/ubuntu/14.04/Microsoft.NETCore.ILAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.14.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- build for x64, arm -->
- <PackagePlatforms>x64;arm;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ilasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/ubuntu/16.04/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/ubuntu/16.04/Microsoft.NETCore.ILAsm.pkgproj
deleted file mode 100644
index 818495e6e2..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILAsm/ubuntu/16.04/Microsoft.NETCore.ILAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.16.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- build for x64, arm -->
- <PackagePlatforms>x64;arm;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ilasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/ubuntu/16.10/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/ubuntu/16.10/Microsoft.NETCore.ILAsm.pkgproj
deleted file mode 100644
index 91ee7f3503..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILAsm/ubuntu/16.10/Microsoft.NETCore.ILAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.16.10-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ilasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILAsm/win/Microsoft.NETCore.ILAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILAsm/win/Microsoft.NETCore.ILAsm.pkgproj
deleted file mode 100644
index 57364df706..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILAsm/win/Microsoft.NETCore.ILAsm.pkgproj
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <PackageTargetRuntime>$(MinOSForArch)-$(PackagePlatform)</PackageTargetRuntime>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- </PropertyGroup>
- <ItemGroup>
- <ArchitectureSpecificNativeFile Include="$(BinDir)ilasm.exe" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup>
- <ArchitectureSpecificNativeSymbol Include="@(ArchitectureSpecificNativeFile -> '%(RelativeDir)PDB\%(FileName).pdb')" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.builds b/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.builds
index b312b3bc99..679fffeadd 100644
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.builds
+++ b/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.builds
@@ -2,96 +2,10 @@
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <!-- This property must be set to the same value as $(PackageOutputPath) for the nuspecs and nupkgs to be binplaced to the intended location. -->
- <OutputPath>$(PackageOutputPath)</OutputPath>
- </PropertyGroup>
-
- <!-- We always build the identity/redirection package. However, the platform specific runtime-*.nupkg is built based upon the target OS we are building the product for. -->
<ItemGroup>
- <Project Include="Microsoft.NETCore.ILDAsm.pkgproj">
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>arm64</Platform>
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>x86</Platform>
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>arm</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'linux-x64'" Include="linux/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'debian.8-x64'" Include="debian/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'debian.8-armel'" Include="debian/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>armel</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'fedora.23-x64'" Include="fedora/23/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'fedora.24-x64'" Include="fedora/24/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'opensuse.13.2-x64'" Include="opensuse/13.2/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'opensuse.42.1-x64'" Include="opensuse/42.1/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and $(DistroRid.StartsWith('rhel.7'))" Include="rhel/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.14.04-x64'" Include="ubuntu/14.04/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.14.04-arm'" Include="ubuntu/14.04/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>arm</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.04-x64'" Include="ubuntu/16.04/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.04-arm'" Include="ubuntu/16.04/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>arm</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.10-x64'" Include="ubuntu/16.10/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'alpine.3.4.3-x64'" Include="alpine/3.4.3/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'tizen.4.0.0-armel'" Include="tizen/4.0.0/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>armel</Platform>
- </Project>
- <Project Condition="'$(TargetsOSX)' == 'true'" Include="osx/Microsoft.NETCore.ILDAsm.pkgproj">
- <OSGroup>OSX</OSGroup>
- <Platform>amd64</Platform>
- </Project>
+ <!-- identity project, runtime specific projects are included by props above -->
+ <Project Include="$(MSBuildProjectName).pkgproj" />
</ItemGroup>
-
+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.pkgproj
index cdfee45ce4..b5fe3cb308 100644
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.pkgproj
+++ b/src/.nuget/Microsoft.NETCore.ILDAsm/Microsoft.NETCore.ILDAsm.pkgproj
@@ -1,75 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <SkipValidatePackage>true</SkipValidatePackage>
- <PackagePlatforms>x64;x86;arm64;arm;armel;</PackagePlatforms>
- <OutputPath>$(PackagesOutputPath)</OutputPath>
- <IncludeRuntimeJson>true</IncludeRuntimeJson>
+
+ <PropertyGroup Condition="'$(PackageTargetRuntime)' == ''">
+ <IsLineupPackage Condition="'$(IsLineupPackage)' == ''">true</IsLineupPackage>
</PropertyGroup>
- <ItemGroup>
- <ProjectReference Include="..\Microsoft.NETCore.Runtime.CoreCLR\Microsoft.NETCore.Runtime.CoreCLR.pkgproj" />
- <ProjectReference Include="win\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="win\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>arm64</Platform>
- </ProjectReference>
- <ProjectReference Include="win\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>x86</Platform>
- </ProjectReference>
- <ProjectReference Include="win\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>arm</Platform>
- </ProjectReference>
- <ProjectReference Include="linux\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="debian\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="debian\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>armel</Platform>
- </ProjectReference>
- <ProjectReference Include="fedora\23\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="fedora\24\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="opensuse\13.2\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="opensuse\42.1\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="rhel\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\14.04\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\14.04\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>arm</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.04\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.04\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>arm</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.10\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="alpine\3.4.3\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="tizen\4.0.0\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>armel</Platform>
- </ProjectReference>
- <ProjectReference Include="osx\Microsoft.NETCore.ILDAsm.pkgproj">
- <Platform>amd64</Platform>
+
+ <ItemGroup Condition="'$(PackageTargetRuntime)' == ''">
+ <ProjectReference Include="..\Microsoft.NETCore.Runtime.CoreCLR\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
+ <AdditionalProperties>%(ProjectReference.AdditionalProperties);IsLineupPackage=false</AdditionalProperties>
</ProjectReference>
</ItemGroup>
+
+ <Import Condition="'$(_packageTargetOSGroup)' != ''" Project="$(MSBuildThisFileDirectory)runtime.$(_packageTargetOSGroup).$(MSBuildProjectName).props" />
+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/alpine/3.4.3/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/alpine/3.4.3/Microsoft.NETCore.ILDAsm.pkgproj
deleted file mode 100644
index b27fe08767..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/alpine/3.4.3/Microsoft.NETCore.ILDAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>alpine.3.4.3-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ildasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/debian/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/debian/Microsoft.NETCore.ILDAsm.pkgproj
deleted file mode 100644
index f73e785d4b..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/debian/Microsoft.NETCore.ILDAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>debian.8-$(PackagePlatform)</PackageTargetRuntime>
- <!-- build for x64, armel -->
- <PackagePlatforms>x64;armel;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ildasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/fedora/23/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/fedora/23/Microsoft.NETCore.ILDAsm.pkgproj
deleted file mode 100644
index 8385c5d55a..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/fedora/23/Microsoft.NETCore.ILDAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>fedora.23-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ildasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/fedora/24/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/fedora/24/Microsoft.NETCore.ILDAsm.pkgproj
deleted file mode 100644
index 20ad52225b..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/fedora/24/Microsoft.NETCore.ILDAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>fedora.24-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ildasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/linux/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/linux/Microsoft.NETCore.ILDAsm.pkgproj
deleted file mode 100644
index 7a7f82ddd5..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/linux/Microsoft.NETCore.ILDAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>linux-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ildasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/opensuse/13.2/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/opensuse/13.2/Microsoft.NETCore.ILDAsm.pkgproj
deleted file mode 100644
index d91ef02df3..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/opensuse/13.2/Microsoft.NETCore.ILDAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>opensuse.13.2-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ildasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/opensuse/42.1/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/opensuse/42.1/Microsoft.NETCore.ILDAsm.pkgproj
deleted file mode 100644
index 07370b4915..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/opensuse/42.1/Microsoft.NETCore.ILDAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>opensuse.42.1-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ildasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/osx/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/osx/Microsoft.NETCore.ILDAsm.pkgproj
deleted file mode 100644
index 9a17267a66..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/osx/Microsoft.NETCore.ILDAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>osx.10.10-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ildasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dwarf')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dwarf" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dylib" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/rhel/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/rhel/Microsoft.NETCore.ILDAsm.pkgproj
deleted file mode 100644
index 355c1c9162..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/rhel/Microsoft.NETCore.ILDAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>rhel.7-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ildasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/runtime.Linux.Microsoft.NETCore.ILDAsm.props b/src/.nuget/Microsoft.NETCore.ILDAsm/runtime.Linux.Microsoft.NETCore.ILDAsm.props
new file mode 100644
index 0000000000..f7ab15b664
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.ILDAsm/runtime.Linux.Microsoft.NETCore.ILDAsm.props
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)ildasm" />
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/runtime.OSX.Microsoft.NETCore.ILDAsm.props b/src/.nuget/Microsoft.NETCore.ILDAsm/runtime.OSX.Microsoft.NETCore.ILDAsm.props
new file mode 100644
index 0000000000..f7ab15b664
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.ILDAsm/runtime.OSX.Microsoft.NETCore.ILDAsm.props
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)ildasm" />
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/runtime.Windows_NT.Microsoft.NETCore.ILDAsm.props b/src/.nuget/Microsoft.NETCore.ILDAsm/runtime.Windows_NT.Microsoft.NETCore.ILDAsm.props
new file mode 100644
index 0000000000..2f0e944982
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.ILDAsm/runtime.Windows_NT.Microsoft.NETCore.ILDAsm.props
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <PackageTargetRuntime>$(MinOSForArch)-$(PackagePlatform)</PackageTargetRuntime>
+ </PropertyGroup>
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)ildasm.exe" />
+ <NativeBinary Include="$(BinDir)ildasmrc.dll" />
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/tizen/4.0.0/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/tizen/4.0.0/Microsoft.NETCore.ILDAsm.pkgproj
deleted file mode 100644
index 9ede1eb2e4..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/tizen/4.0.0/Microsoft.NETCore.ILDAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>tizen.4.0.0-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for armel -->
- <PackagePlatforms>armel;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ildasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/ubuntu/14.04/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/ubuntu/14.04/Microsoft.NETCore.ILDAsm.pkgproj
deleted file mode 100644
index e087645962..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/ubuntu/14.04/Microsoft.NETCore.ILDAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.14.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- build for x64, arm -->
- <PackagePlatforms>x64;arm;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ildasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/ubuntu/16.04/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/ubuntu/16.04/Microsoft.NETCore.ILDAsm.pkgproj
deleted file mode 100644
index 776e59ba16..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/ubuntu/16.04/Microsoft.NETCore.ILDAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.16.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- build for x64, arm -->
- <PackagePlatforms>x64;arm;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ildasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/ubuntu/16.10/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/ubuntu/16.10/Microsoft.NETCore.ILDAsm.pkgproj
deleted file mode 100644
index 6c73eba240..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/ubuntu/16.10/Microsoft.NETCore.ILDAsm.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.16.10-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)ildasm" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.ILDAsm/win/Microsoft.NETCore.ILDAsm.pkgproj b/src/.nuget/Microsoft.NETCore.ILDAsm/win/Microsoft.NETCore.ILDAsm.pkgproj
deleted file mode 100644
index d32b540b0b..0000000000
--- a/src/.nuget/Microsoft.NETCore.ILDAsm/win/Microsoft.NETCore.ILDAsm.pkgproj
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <PackageTargetRuntime>$(MinOSForArch)-$(PackagePlatform)</PackageTargetRuntime>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- </PropertyGroup>
- <ItemGroup>
- <ArchitectureSpecificNativeFile Include="$(BinDir)ildasm.exe" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)ildasmrc.dll" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup>
- <ArchitectureSpecificNativeSymbol Include="@(ArchitectureSpecificNativeFile -> '%(RelativeDir)PDB\%(FileName).pdb')" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.builds b/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.builds
index 5f75a74196..dd00e039a6 100644
--- a/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.builds
+++ b/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.builds
@@ -1,97 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <!-- This property must be set to the same value as $(PackageOutputPath) for the nuspecs and nupkgs to be binplaced to the intended location. -->
- <OutputPath>$(PackageOutputPath)</OutputPath>
- </PropertyGroup>
-
- <!-- We always build the identity/redirection package. However, the platform specific runtime-*.nupkg is built based upon the target OS we are building the product for. -->
<ItemGroup>
- <Project Include="Microsoft.NETCore.Jit.pkgproj">
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>arm64</Platform>
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>x86</Platform>
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>arm</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'linux-x64'" Include="linux/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'debian.8-x64'" Include="debian/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'debian.8-armel'" Include="debian/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>armel</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'fedora.23-x64'" Include="fedora/23/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'fedora.24-x64'" Include="fedora/24/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'opensuse.13.2-x64'" Include="opensuse/13.2/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'opensuse.42.1-x64'" Include="opensuse/42.1/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and $(DistroRid.StartsWith('rhel.7'))" Include="rhel/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.14.04-x64'" Include="ubuntu/14.04/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.14.04-arm'" Include="ubuntu/14.04/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>arm</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.04-x64'" Include="ubuntu/16.04/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.04-arm'" Include="ubuntu/16.04/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>arm</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.10-x64'" Include="ubuntu/16.10/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'alpine.3.4.3-x64'" Include="alpine/3.4.3/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'tizen.4.0.0-armel'" Include="tizen/4.0.0/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>armel</Platform>
- </Project>
- <Project Condition="'$(TargetsOSX)' == 'true'" Include="osx/Microsoft.NETCore.Jit.pkgproj">
- <OSGroup>OSX</OSGroup>
- <Platform>amd64</Platform>
- </Project>
+ <!-- identity project, runtime specific projects are included by props above -->
+ <Project Include="$(MSBuildProjectName).pkgproj" />
</ItemGroup>
-
+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.pkgproj
index dd39f77b2b..a9ebe1cda4 100644
--- a/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.pkgproj
+++ b/src/.nuget/Microsoft.NETCore.Jit/Microsoft.NETCore.Jit.pkgproj
@@ -1,74 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+
+ <PropertyGroup Condition="'$(PackageTargetRuntime)' == ''">
+ <IsLineupPackage Condition="'$(IsLineupPackage)' == ''">true</IsLineupPackage>
+ </PropertyGroup>
+
<PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <SkipValidatePackage>true</SkipValidatePackage>
- <PackagePlatforms>x64;x86;arm64;arm;armel;</PackagePlatforms>
- <OutputPath>$(PackagesOutputPath)</OutputPath>
- <IncludeRuntimeJson>true</IncludeRuntimeJson>
+ <LongNamePlatform>$(PackagePlatform)</LongNamePlatform>
+ <LongNamePlatform Condition="'$(LongNamePlatform)'=='x64'">amd64</LongNamePlatform>
+ <CrossTargetPlatform>$(CrossTargetComponentFolder)</CrossTargetPlatform>
+ <CrossTargetPlatform Condition="'$(CrossTargetPlatform)'=='x64'">amd64</CrossTargetPlatform>
+ <LongNameSuffix>_$(LongNamePlatform)_$(LongNamePlatform)_$(MajorVersion).$(MinorVersion).$(BuildNumberMajor).0$(BuildNumberMinor)</LongNameSuffix>
+ <CrossTargetLongNameSuffix>_$(CrossTargetPlatform)_$(LongNamePlatform)_$(MajorVersion).$(MinorVersion).$(BuildNumberMajor).0$(BuildNumberMinor)</CrossTargetLongNameSuffix>
</PropertyGroup>
- <ItemGroup>
- <ProjectReference Include="win\Microsoft.NETCore.Jit.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="win\Microsoft.NETCore.Jit.pkgproj">
- <Platform>arm64</Platform>
- </ProjectReference>
- <ProjectReference Include="win\Microsoft.NETCore.Jit.pkgproj">
- <Platform>x86</Platform>
- </ProjectReference>
- <ProjectReference Include="win\Microsoft.NETCore.Jit.pkgproj">
- <Platform>arm</Platform>
- </ProjectReference>
- <ProjectReference Include="linux\Microsoft.NETCore.Jit.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="debian\Microsoft.NETCore.Jit.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="debian\Microsoft.NETCore.Jit.pkgproj">
- <Platform>armel</Platform>
- </ProjectReference>
- <ProjectReference Include="fedora\23\Microsoft.NETCore.Jit.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="fedora\24\Microsoft.NETCore.Jit.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="opensuse\13.2\Microsoft.NETCore.Jit.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="opensuse\42.1\Microsoft.NETCore.Jit.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="rhel\Microsoft.NETCore.Jit.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\14.04\Microsoft.NETCore.Jit.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\14.04\Microsoft.NETCore.Jit.pkgproj">
- <Platform>arm</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.04\Microsoft.NETCore.Jit.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.04\Microsoft.NETCore.Jit.pkgproj">
- <Platform>arm</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.10\Microsoft.NETCore.Jit.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="alpine\3.4.3\Microsoft.NETCore.Jit.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="tizen\4.0.0\Microsoft.NETCore.Jit.pkgproj">
- <Platform>armel</Platform>
- </ProjectReference>
- <ProjectReference Include="osx\Microsoft.NETCore.Jit.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- </ItemGroup>
+
+ <Import Condition="'$(_packageTargetOSGroup)' != ''" Project="$(MSBuildThisFileDirectory)runtime.$(_packageTargetOSGroup).$(MSBuildProjectName).props" />
+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Jit/alpine/3.4.3/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/alpine/3.4.3/Microsoft.NETCore.Jit.pkgproj
deleted file mode 100644
index 96851ff3ac..0000000000
--- a/src/.nuget/Microsoft.NETCore.Jit/alpine/3.4.3/Microsoft.NETCore.Jit.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>alpine.3.4.3-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libclrjit.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.Jit/debian/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/debian/Microsoft.NETCore.Jit.pkgproj
deleted file mode 100644
index db2a57c8c7..0000000000
--- a/src/.nuget/Microsoft.NETCore.Jit/debian/Microsoft.NETCore.Jit.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>debian.8-$(PackagePlatform)</PackageTargetRuntime>
- <!-- build for x64, armel -->
- <PackagePlatforms>x64;armel;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libclrjit.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Jit/fedora/23/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/fedora/23/Microsoft.NETCore.Jit.pkgproj
deleted file mode 100644
index 1dea18c33d..0000000000
--- a/src/.nuget/Microsoft.NETCore.Jit/fedora/23/Microsoft.NETCore.Jit.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>fedora.23-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libclrjit.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.Jit/fedora/24/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/fedora/24/Microsoft.NETCore.Jit.pkgproj
deleted file mode 100644
index 42f974ab96..0000000000
--- a/src/.nuget/Microsoft.NETCore.Jit/fedora/24/Microsoft.NETCore.Jit.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>fedora.24-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libclrjit.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.Jit/linux/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/linux/Microsoft.NETCore.Jit.pkgproj
deleted file mode 100644
index 541b81e4ab..0000000000
--- a/src/.nuget/Microsoft.NETCore.Jit/linux/Microsoft.NETCore.Jit.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>linux-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libclrjit.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.Jit/opensuse/13.2/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/opensuse/13.2/Microsoft.NETCore.Jit.pkgproj
deleted file mode 100644
index 28a8769d5e..0000000000
--- a/src/.nuget/Microsoft.NETCore.Jit/opensuse/13.2/Microsoft.NETCore.Jit.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>opensuse.13.2-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libclrjit.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.Jit/opensuse/42.1/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/opensuse/42.1/Microsoft.NETCore.Jit.pkgproj
deleted file mode 100644
index 930606c175..0000000000
--- a/src/.nuget/Microsoft.NETCore.Jit/opensuse/42.1/Microsoft.NETCore.Jit.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>opensuse.42.1-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libclrjit.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.Jit/osx/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/osx/Microsoft.NETCore.Jit.pkgproj
deleted file mode 100644
index 87e7e2bffd..0000000000
--- a/src/.nuget/Microsoft.NETCore.Jit/osx/Microsoft.NETCore.Jit.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>osx.10.10-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libclrjit.dylib" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dwarf')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dwarf" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dylib" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.Jit/rhel/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/rhel/Microsoft.NETCore.Jit.pkgproj
deleted file mode 100644
index fa9f58c81b..0000000000
--- a/src/.nuget/Microsoft.NETCore.Jit/rhel/Microsoft.NETCore.Jit.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>rhel.7-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libclrjit.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.Jit/runtime.Linux.Microsoft.NETCore.Jit.props b/src/.nuget/Microsoft.NETCore.Jit/runtime.Linux.Microsoft.NETCore.Jit.props
new file mode 100644
index 0000000000..b92d11ae59
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.Jit/runtime.Linux.Microsoft.NETCore.Jit.props
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)libclrjit.so" />
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Jit/runtime.OSX.Microsoft.NETCore.Jit.props b/src/.nuget/Microsoft.NETCore.Jit/runtime.OSX.Microsoft.NETCore.Jit.props
new file mode 100644
index 0000000000..99cee0e68b
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.Jit/runtime.OSX.Microsoft.NETCore.Jit.props
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)libclrjit.dylib" />
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Jit/runtime.Windows_NT.Microsoft.NETCore.Jit.props b/src/.nuget/Microsoft.NETCore.Jit/runtime.Windows_NT.Microsoft.NETCore.Jit.props
new file mode 100644
index 0000000000..c45358dec7
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.Jit/runtime.Windows_NT.Microsoft.NETCore.Jit.props
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)clrjit.dll" />
+ <NativeBinary Condition="'$(Platform)' == 'x86' and '$(PackageCompatJit)' != ''" Include="$(BinDir)compatjit.dll" />
+ <CrossArchitectureSpecificNativeFileAndSymbol Include="$(BinDir)$(CrossTargetComponentFolder)\clrjit.dll" />
+
+ <!-- prevent accidental inclusion in AOT projects. -->
+ <File Include="$(PlaceholderFile)">
+ <TargetPath>runtimes/$(PackageTargetRuntime)-aot/native</TargetPath>
+ </File>
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Jit/tizen/4.0.0/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/tizen/4.0.0/Microsoft.NETCore.Jit.pkgproj
deleted file mode 100644
index f2eaa55f3c..0000000000
--- a/src/.nuget/Microsoft.NETCore.Jit/tizen/4.0.0/Microsoft.NETCore.Jit.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>tizen.4.0.0-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for armel -->
- <PackagePlatforms>armel;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libclrjit.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Jit/ubuntu/14.04/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/ubuntu/14.04/Microsoft.NETCore.Jit.pkgproj
deleted file mode 100644
index 50d343f977..0000000000
--- a/src/.nuget/Microsoft.NETCore.Jit/ubuntu/14.04/Microsoft.NETCore.Jit.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.14.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- build for x64, arm -->
- <PackagePlatforms>x64;arm;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libclrjit.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Jit/ubuntu/16.04/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/ubuntu/16.04/Microsoft.NETCore.Jit.pkgproj
deleted file mode 100644
index e57b7c51d5..0000000000
--- a/src/.nuget/Microsoft.NETCore.Jit/ubuntu/16.04/Microsoft.NETCore.Jit.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.16.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- build for x64, arm -->
- <PackagePlatforms>x64;arm;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libclrjit.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Jit/ubuntu/16.10/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/ubuntu/16.10/Microsoft.NETCore.Jit.pkgproj
deleted file mode 100644
index 338d23372f..0000000000
--- a/src/.nuget/Microsoft.NETCore.Jit/ubuntu/16.10/Microsoft.NETCore.Jit.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.16.10-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libclrjit.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.Jit/win/Microsoft.NETCore.Jit.pkgproj b/src/.nuget/Microsoft.NETCore.Jit/win/Microsoft.NETCore.Jit.pkgproj
deleted file mode 100644
index 66106c30dc..0000000000
--- a/src/.nuget/Microsoft.NETCore.Jit/win/Microsoft.NETCore.Jit.pkgproj
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>$(MinOSForArch)-$(PackagePlatform)</PackageTargetRuntime>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- </PropertyGroup>
- <ItemGroup>
- <ArchitectureSpecificNativeFile Include="$(BinDir)clrjit.dll" />
- <ArchitectureSpecificNativeFile Condition="'$(PackagePlatform)' == 'x86'" Include="$(BinDir)compatjit.dll" />
- <CrossArchitectureSpecificNativeFile Include="$(BinDir)$(CrossTargetComponentFolder)\clrjit.dll" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- <File Condition="'$(HasCrossTargetComponents)' == 'true'" Include="@(CrossArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(CrossTargetComponentFolder)_$(PackagePlatform)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup>
- <!-- prevent accidental inclusion in AOT projects. -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)-aot/native</TargetPath>
- </File>
-
- <ArchitectureSpecificNativeSymbol Include="@(ArchitectureSpecificNativeFile -> '%(RelativeDir)PDB\%(FileName).pdb')" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <CrossArchitectureSpecificNativeSymbol Condition="'$(HasCrossTargetComponents)' == 'true'" Include="@(CrossArchitectureSpecificNativeFile -> '%(RelativeDir)PDB\%(FileName).pdb')" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- <File Condition="'$(HasCrossTargetComponents)' == 'true'" Include="@(CrossArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(CrossTargetComponentFolder)_$(PackagePlatform)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.builds b/src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.builds
index a178ddb961..6318c1c0d1 100644
--- a/src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.builds
+++ b/src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.builds
@@ -1,65 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <Import Project="Microsoft.NETCore.Native.props" />
- <PropertyGroup>
- <!-- This property must be set to the same value as $(PackageOutputPath) for the nuspecs and nupkgs to be binplaced to the intended location. -->
- <OutputPath>$(PackageOutputPath)</OutputPath>
- </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <!-- We always build the identity/redirection package. However, the platform specific runtime-*.nupkg is built based upon the target OS we are building the product for. -->
<ItemGroup>
- <Project Include="Microsoft.NETCore.Native.pkgproj">
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'linux-x64'" Include="linux/Microsoft.NETCore.Native.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'debian.8-x64'" Include="debian/Microsoft.NETCore.Native.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'fedora.23-x64'" Include="fedora/23/Microsoft.NETCore.Native.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'fedora.24-x64'" Include="fedora/24/Microsoft.NETCore.Native.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'opensuse.13.2-x64'" Include="opensuse/13.2/Microsoft.NETCore.Native.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'opensuse.42.1-x64'" Include="opensuse/42.1/Microsoft.NETCore.Native.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and $(DistroRid.StartsWith('rhel.7'))" Include="rhel/Microsoft.NETCore.Native.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.14.04-x64'" Include="ubuntu/14.04/Microsoft.NETCore.Native.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.04-x64'" Include="ubuntu/16.04/Microsoft.NETCore.Native.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.10-x64'" Include="ubuntu/16.10/Microsoft.NETCore.Native.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'alpine.3.4.3-x64'" Include="alpine/3.4.3/Microsoft.NETCore.Native.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsOSX)' == 'true'" Include="osx/Microsoft.NETCore.Native.pkgproj">
- <OSGroup>OSX</OSGroup>
- <Platform>amd64</Platform>
- </Project>
+ <!-- identity project, runtime specific projects are included by props above -->
+ <Project Include="$(MSBuildProjectName).pkgproj" />
</ItemGroup>
-
+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.pkgproj
index 51b524a1c8..42ddfc9137 100644
--- a/src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.pkgproj
+++ b/src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.pkgproj
@@ -1,50 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <Import Project="Microsoft.NETCore.Native.props" />
+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <SkipValidatePackage>true</SkipValidatePackage>
- <PackagePlatforms>x64;x86;arm64;arm;</PackagePlatforms>
- <OutputPath>$(PackagesOutputPath)</OutputPath>
- <IncludeRuntimeJson>true</IncludeRuntimeJson>
+
+ <PropertyGroup Condition="'$(PackageTargetRuntime)' == ''">
+ <IsLineupPackage Condition="'$(IsLineupPackage)' == ''">true</IsLineupPackage>
</PropertyGroup>
- <ItemGroup>
- <ProjectReference Include="linux\Microsoft.NETCore.Native.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="debian\Microsoft.NETCore.Native.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="fedora\23\Microsoft.NETCore.Native.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="fedora\24\Microsoft.NETCore.Native.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="opensuse\13.2\Microsoft.NETCore.Native.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="opensuse\42.1\Microsoft.NETCore.Native.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="rhel\Microsoft.NETCore.Native.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\14.04\Microsoft.NETCore.Native.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.04\Microsoft.NETCore.Native.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.10\Microsoft.NETCore.Native.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="alpine\3.4.3\Microsoft.NETCore.Native.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="osx\Microsoft.NETCore.Native.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- </ItemGroup>
+
+ <Import Condition="'$(_packageTargetOSGroup)' != ''" Project="$(MSBuildThisFileDirectory)runtime.$(_packageTargetOSGroup).$(MSBuildProjectName).props" />
+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.props b/src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.props
new file mode 100644
index 0000000000..ff2f587a1c
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.props
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <SupportedPackageOSGroups>Linux;OSX</SupportedPackageOSGroups>
+ </PropertyGroup>
+</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.Native/alpine/3.4.3/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/alpine/3.4.3/Microsoft.NETCore.Native.pkgproj
deleted file mode 100644
index 90545a9001..0000000000
--- a/src/.nuget/Microsoft.NETCore.Native/alpine/3.4.3/Microsoft.NETCore.Native.pkgproj
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>alpine.3.4.3-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/debian/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/debian/Microsoft.NETCore.Native.pkgproj
deleted file mode 100644
index c136a2c057..0000000000
--- a/src/.nuget/Microsoft.NETCore.Native/debian/Microsoft.NETCore.Native.pkgproj
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>debian.8-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/fedora/23/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/fedora/23/Microsoft.NETCore.Native.pkgproj
deleted file mode 100644
index 8547114cdd..0000000000
--- a/src/.nuget/Microsoft.NETCore.Native/fedora/23/Microsoft.NETCore.Native.pkgproj
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>fedora.23-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/fedora/24/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/fedora/24/Microsoft.NETCore.Native.pkgproj
deleted file mode 100644
index f4987de01d..0000000000
--- a/src/.nuget/Microsoft.NETCore.Native/fedora/24/Microsoft.NETCore.Native.pkgproj
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>fedora.24-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/linux/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/linux/Microsoft.NETCore.Native.pkgproj
deleted file mode 100644
index 8b1064f081..0000000000
--- a/src/.nuget/Microsoft.NETCore.Native/linux/Microsoft.NETCore.Native.pkgproj
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>linux-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/opensuse/13.2/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/opensuse/13.2/Microsoft.NETCore.Native.pkgproj
deleted file mode 100644
index bf8307a0b3..0000000000
--- a/src/.nuget/Microsoft.NETCore.Native/opensuse/13.2/Microsoft.NETCore.Native.pkgproj
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>opensuse.13.2-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/opensuse/42.1/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/opensuse/42.1/Microsoft.NETCore.Native.pkgproj
deleted file mode 100644
index 19ac91cd88..0000000000
--- a/src/.nuget/Microsoft.NETCore.Native/opensuse/42.1/Microsoft.NETCore.Native.pkgproj
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>opensuse.42.1-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/osx/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/osx/Microsoft.NETCore.Native.pkgproj
deleted file mode 100644
index b358c86799..0000000000
--- a/src/.nuget/Microsoft.NETCore.Native/osx/Microsoft.NETCore.Native.pkgproj
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>osx.10.10-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.dylib" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dwarf')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dwarf" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dylib" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/rhel/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/rhel/Microsoft.NETCore.Native.pkgproj
deleted file mode 100644
index f9dc309a6b..0000000000
--- a/src/.nuget/Microsoft.NETCore.Native/rhel/Microsoft.NETCore.Native.pkgproj
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>rhel.7-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/runtime.Linux.Microsoft.NETCore.Native.props b/src/.nuget/Microsoft.NETCore.Native/runtime.Linux.Microsoft.NETCore.Native.props
new file mode 100644
index 0000000000..87db2a7bd2
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.Native/runtime.Linux.Microsoft.NETCore.Native.props
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
+ <NativeBinary Include="$(BinDir)System.Globalization.Native.so" />
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/runtime.OSX.Microsoft.NETCore.Native.props b/src/.nuget/Microsoft.NETCore.Native/runtime.OSX.Microsoft.NETCore.Native.props
new file mode 100644
index 0000000000..8ce70300e5
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.Native/runtime.OSX.Microsoft.NETCore.Native.props
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
+ <NativeBinary Include="$(BinDir)System.Globalization.Native.dylib" />
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/ubuntu/14.04/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/ubuntu/14.04/Microsoft.NETCore.Native.pkgproj
deleted file mode 100644
index d1c5be74ff..0000000000
--- a/src/.nuget/Microsoft.NETCore.Native/ubuntu/14.04/Microsoft.NETCore.Native.pkgproj
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.14.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/ubuntu/16.04/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/ubuntu/16.04/Microsoft.NETCore.Native.pkgproj
deleted file mode 100644
index b2b0f96587..0000000000
--- a/src/.nuget/Microsoft.NETCore.Native/ubuntu/16.04/Microsoft.NETCore.Native.pkgproj
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.16.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/ubuntu/16.10/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/ubuntu/16.10/Microsoft.NETCore.Native.pkgproj
deleted file mode 100644
index da4a03d668..0000000000
--- a/src/.nuget/Microsoft.NETCore.Native/ubuntu/16.10/Microsoft.NETCore.Native.pkgproj
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.16.10-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.builds b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.builds
index 99bbbef6a1..dd00e039a6 100644
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.builds
+++ b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.builds
@@ -1,96 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <!-- This property must be set to the same value as $(PackageOutputPath) for the nuspecs and nupkgs to be binplaced to the intended location. -->
- <OutputPath>$(PackageOutputPath)</OutputPath>
- </PropertyGroup>
- <!-- We always build the identity/redirection package. However, the platform specific runtime-*.nupkg is built based upon the target OS we are building the product for. -->
<ItemGroup>
- <Project Include="Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>arm64</Platform>
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>x86</Platform>
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>arm</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'linux-x64'" Include="linux/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'debian.8-x64'" Include="debian/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'debian.8-armel'" Include="debian/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>armel</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'fedora.23-x64'" Include="fedora/23/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'fedora.24-x64'" Include="fedora/24/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'opensuse.13.2-x64'" Include="opensuse/13.2/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'opensuse.42.1-x64'" Include="opensuse/42.1/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and $(DistroRid.StartsWith('rhel.7'))" Include="rhel/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.14.04-x64'" Include="ubuntu/14.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.14.04-arm'" Include="ubuntu/14.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>arm</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.04-x64'" Include="ubuntu/16.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.04-arm'" Include="ubuntu/16.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>arm</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.10-x64'" Include="ubuntu/16.10/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'alpine.3.4.3-x64'" Include="alpine/3.4.3/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'tizen.4.0.0-armel'" Include="tizen/4.0.0/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>armel</Platform>
- </Project>
- <Project Condition="'$(TargetsOSX)' == 'true'" Include="osx/Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <OSGroup>OSX</OSGroup>
- <Platform>amd64</Platform>
- </Project>
+ <!-- identity project, runtime specific projects are included by props above -->
+ <Project Include="$(MSBuildProjectName).pkgproj" />
</ItemGroup>
-
+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
index bc4b86242b..f6f6a73bc9 100644
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
+++ b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
@@ -1,75 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <Import Project="Microsoft.NETCore.Runtime.CoreCLR.props" />
+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <SkipValidatePackage>true</SkipValidatePackage>
- <PackagePlatforms>x64;x86;arm64;arm;armel;</PackagePlatforms>
- <OutputPath>$(PackagesOutputPath)</OutputPath>
- <IncludeRuntimeJson>true</IncludeRuntimeJson>
+
+ <PropertyGroup Condition="'$(PackageTargetRuntime)' == ''">
+ <IsLineupPackage Condition="'$(IsLineupPackage)' == ''">true</IsLineupPackage>
</PropertyGroup>
- <ItemGroup>
- <ProjectReference Include="..\Microsoft.NETCore.Jit\Microsoft.NETCore.Jit.pkgproj" />
- <ProjectReference Include="win\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="win\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>arm64</Platform>
- </ProjectReference>
- <ProjectReference Include="win\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>x86</Platform>
- </ProjectReference>
- <ProjectReference Include="win\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>arm</Platform>
- </ProjectReference>
- <ProjectReference Include="linux\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="debian\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="debian\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>armel</Platform>
- </ProjectReference>
- <ProjectReference Include="fedora\23\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="fedora\24\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="opensuse\13.2\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="opensuse\42.1\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="rhel\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\14.04\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\14.04\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>arm</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.04\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.04\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>arm</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.10\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="alpine\3.4.3\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="tizen\4.0.0\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>armel</Platform>
- </ProjectReference>
- <ProjectReference Include="osx\Microsoft.NETCore.Runtime.CoreCLR.pkgproj">
- <Platform>amd64</Platform>
+
+ <ItemGroup Condition="'$(IsLineupPackage)' == 'true'">
+ <ProjectReference Include="..\Microsoft.NETCore.Jit\Microsoft.NETCore.Jit.pkgproj">
+ <AdditionalProperties>%(ProjectReference.AdditionalProperties);IsLineupPackage=false</AdditionalProperties>
</ProjectReference>
</ItemGroup>
+
+ <Import Condition="'$(_packageTargetOSGroup)' != ''" Project="$(MSBuildThisFileDirectory)runtime.$(_packageTargetOSGroup).$(MSBuildProjectName).props" />
+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.props b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.props
new file mode 100644
index 0000000000..0e1f9db1c5
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/Microsoft.NETCore.Runtime.CoreCLR.props
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <!-- No reference: don't permit reference to the implementation from lib -->
+ <File Include="$(PlaceholderFile)">
+ <TargetPath>ref/netstandard1.0</TargetPath>
+ </File>
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/alpine/3.4.3/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/alpine/3.4.3/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
deleted file mode 100644
index c779349b7c..0000000000
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/alpine/3.4.3/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>alpine.3.4.3-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libcoreclr.so" />
- <NativeSplittableBinary Include="$(BinDir)libcoreclrtraceptprovider.so" />
- <NativeSplittableBinary Include="$(BinDir)libdbgshim.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordaccore.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordbi.so" />
- <NativeSplittableBinary Include="$(BinDir)libsos.so" />
- <NativeSplittableBinary Include="$(BinDir)libsosplugin.so" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)sosdocsunix.txt" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)mscorlib.ni.dll" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)System.Private.CoreLib.ni.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)mscorlib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
- <ArchitectureSpecificToolFile Include="$(BinDir)crossgen" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- <!-- Using lib/netstandard1.0 here. There is no TFM for this since it is a runtime itself. -->
- <File Include="@(ArchitectureSpecificLibFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/lib/netstandard1.0</TargetPath>
- </File>
- <!-- No reference: don't permit reference to the implementation from lib -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>ref/netstandard1.0</TargetPath>
- </File>
- <File Include="@(ArchitectureSpecificToolFile)">
- <TargetPath>tools</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\sosdocsunix.txt" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\crossgen" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/debian/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/debian/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
deleted file mode 100644
index f982188fb3..0000000000
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/debian/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>debian.8-$(PackagePlatform)</PackageTargetRuntime>
- <!-- build for x64, armel -->
- <PackagePlatforms>x64;armel;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libcoreclr.so" />
- <NativeSplittableBinary Condition="'$(PackagePlatform)' != 'armel'" Include="$(BinDir)libcoreclrtraceptprovider.so" />
- <NativeSplittableBinary Include="$(BinDir)libdbgshim.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordaccore.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordbi.so" />
- <NativeSplittableBinary Include="$(BinDir)libsos.so" />
- <NativeSplittableBinary Include="$(BinDir)libsosplugin.so" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)sosdocsunix.txt" />
- <ArchitectureSpecificNativeFile Condition="'$(PackagePlatform)' != 'armel'" Include="$(BinDir)mscorlib.ni.dll" />
- <ArchitectureSpecificNativeFile Condition="'$(PackagePlatform)' != 'armel'" Include="$(BinDir)System.Private.CoreLib.ni.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)mscorlib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
- <ArchitectureSpecificToolFile Include="$(BinDir)crossgen" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- <!-- Using lib/netstandard1.0 here. There is no TFM for this since it is a runtime itself. -->
- <File Include="@(ArchitectureSpecificLibFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/lib/netstandard1.0</TargetPath>
- </File>
- <!-- No reference: don't permit reference to the implementation from lib -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>ref/netstandard1.0</TargetPath>
- </File>
- <File Include="@(ArchitectureSpecificToolFile)">
- <TargetPath>tools</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\sosdocsunix.txt" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\crossgen" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/fedora/23/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/fedora/23/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
deleted file mode 100644
index a68fe2c0c6..0000000000
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/fedora/23/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>fedora.23-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libcoreclr.so" />
- <NativeSplittableBinary Include="$(BinDir)libcoreclrtraceptprovider.so" />
- <NativeSplittableBinary Include="$(BinDir)libdbgshim.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordaccore.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordbi.so" />
- <NativeSplittableBinary Include="$(BinDir)libsos.so" />
- <NativeSplittableBinary Include="$(BinDir)libsosplugin.so" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)sosdocsunix.txt" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)mscorlib.ni.dll" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)System.Private.CoreLib.ni.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)mscorlib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
- <ArchitectureSpecificToolFile Include="$(BinDir)crossgen" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- <!-- Using lib/netstandard1.0 here. There is no TFM for this since it is a runtime itself. -->
- <File Include="@(ArchitectureSpecificLibFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/lib/netstandard1.0</TargetPath>
- </File>
- <!-- No reference: don't permit reference to the implementation from lib -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>ref/netstandard1.0</TargetPath>
- </File>
- <File Include="@(ArchitectureSpecificToolFile)">
- <TargetPath>tools</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\sosdocsunix.txt" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\crossgen" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/fedora/24/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/fedora/24/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
deleted file mode 100644
index d19a1dd80f..0000000000
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/fedora/24/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>fedora.24-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libcoreclr.so" />
- <NativeSplittableBinary Include="$(BinDir)libcoreclrtraceptprovider.so" />
- <NativeSplittableBinary Include="$(BinDir)libdbgshim.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordaccore.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordbi.so" />
- <NativeSplittableBinary Include="$(BinDir)libsos.so" />
- <NativeSplittableBinary Include="$(BinDir)libsosplugin.so" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)sosdocsunix.txt" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)mscorlib.ni.dll" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)System.Private.CoreLib.ni.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)mscorlib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
- <ArchitectureSpecificToolFile Include="$(BinDir)crossgen" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- <!-- Using lib/netstandard1.0 here. There is no TFM for this since it is a runtime itself. -->
- <File Include="@(ArchitectureSpecificLibFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/lib/netstandard1.0</TargetPath>
- </File>
- <!-- No reference: don't permit reference to the implementation from lib -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>ref/netstandard1.0</TargetPath>
- </File>
- <File Include="@(ArchitectureSpecificToolFile)">
- <TargetPath>tools</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\sosdocsunix.txt" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\crossgen" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/linux/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/linux/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
deleted file mode 100644
index 31e719601d..0000000000
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/linux/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>linux-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libcoreclr.so" />
- <NativeSplittableBinary Include="$(BinDir)libcoreclrtraceptprovider.so" />
- <NativeSplittableBinary Include="$(BinDir)libdbgshim.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordaccore.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordbi.so" />
- <NativeSplittableBinary Include="$(BinDir)libsos.so" />
- <NativeSplittableBinary Include="$(BinDir)libsosplugin.so" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)sosdocsunix.txt" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)mscorlib.ni.dll" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)System.Private.CoreLib.ni.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)mscorlib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
- <ArchitectureSpecificToolFile Include="$(BinDir)crossgen" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- <!-- Using lib/netstandard1.0 here. There is no TFM for this since it is a runtime itself. -->
- <File Include="@(ArchitectureSpecificLibFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/lib/netstandard1.0</TargetPath>
- </File>
- <!-- No reference: don't permit reference to the implementation from lib -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>ref/netstandard1.0</TargetPath>
- </File>
- <File Include="@(ArchitectureSpecificToolFile)">
- <TargetPath>tools</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\sosdocsunix.txt" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\crossgen" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/opensuse/13.2/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/opensuse/13.2/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
deleted file mode 100644
index e5c70c93da..0000000000
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/opensuse/13.2/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>opensuse.13.2-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libcoreclr.so" />
- <NativeSplittableBinary Include="$(BinDir)libcoreclrtraceptprovider.so" />
- <NativeSplittableBinary Include="$(BinDir)libdbgshim.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordaccore.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordbi.so" />
- <NativeSplittableBinary Include="$(BinDir)libsos.so" />
- <NativeSplittableBinary Include="$(BinDir)libsosplugin.so" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)sosdocsunix.txt" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)mscorlib.ni.dll" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)System.Private.CoreLib.ni.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)mscorlib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
- <ArchitectureSpecificToolFile Include="$(BinDir)crossgen" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- <!-- Using lib/netstandard1.0 here. There is no TFM for this since it is a runtime itself. -->
- <File Include="@(ArchitectureSpecificLibFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/lib/netstandard1.0</TargetPath>
- </File>
- <!-- No reference: don't permit reference to the implementation from lib -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>ref/netstandard1.0</TargetPath>
- </File>
- <File Include="@(ArchitectureSpecificToolFile)">
- <TargetPath>tools</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\sosdocsunix.txt" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\crossgen" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/opensuse/42.1/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/opensuse/42.1/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
deleted file mode 100644
index 990a0526c5..0000000000
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/opensuse/42.1/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>opensuse.42.1-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libcoreclr.so" />
- <NativeSplittableBinary Include="$(BinDir)libcoreclrtraceptprovider.so" />
- <NativeSplittableBinary Include="$(BinDir)libdbgshim.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordaccore.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordbi.so" />
- <NativeSplittableBinary Include="$(BinDir)libsos.so" />
- <NativeSplittableBinary Include="$(BinDir)libsosplugin.so" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)sosdocsunix.txt" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)mscorlib.ni.dll" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)System.Private.CoreLib.ni.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)mscorlib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
- <ArchitectureSpecificToolFile Include="$(BinDir)crossgen" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- <!-- Using lib/netstandard1.0 here. There is no TFM for this since it is a runtime itself. -->
- <File Include="@(ArchitectureSpecificLibFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/lib/netstandard1.0</TargetPath>
- </File>
- <!-- No reference: don't permit reference to the implementation from lib -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>ref/netstandard1.0</TargetPath>
- </File>
- <File Include="@(ArchitectureSpecificToolFile)">
- <TargetPath>tools</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\sosdocsunix.txt" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\crossgen" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/osx/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/osx/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
deleted file mode 100644
index 6425e8b6f1..0000000000
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/osx/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
+++ /dev/null
@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>osx.10.10-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libcoreclr.dylib" />
- <NativeSplittableBinary Include="$(BinDir)libdbgshim.dylib" />
- <NativeSplittableBinary Include="$(BinDir)libmscordaccore.dylib" />
- <NativeSplittableBinary Include="$(BinDir)libmscordbi.dylib" />
- <NativeSplittableBinary Include="$(BinDir)libsos.dylib" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.dylib" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)sosdocsunix.txt" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)mscorlib.ni.dll" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)System.Private.CoreLib.ni.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)mscorlib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
- <ArchitectureSpecificToolFile Include="$(BinDir)crossgen" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- <!-- Using lib/netstandard1.0 here. There is no TFM for this since it is a runtime itself. -->
- <File Include="@(ArchitectureSpecificLibFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/lib/netstandard1.0</TargetPath>
- </File>
- <!-- No reference: don't permit reference to the implementation from lib -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>ref/netstandard1.0</TargetPath>
- </File>
- <File Include="@(ArchitectureSpecificToolFile)">
- <TargetPath>tools</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dwarf')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dwarf" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dylib" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\sosdocsunix.txt" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\crossgen" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/rhel/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/rhel/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
deleted file mode 100644
index f12793fe73..0000000000
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/rhel/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>rhel.7-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libcoreclr.so" />
- <NativeSplittableBinary Include="$(BinDir)libcoreclrtraceptprovider.so" />
- <NativeSplittableBinary Include="$(BinDir)libdbgshim.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordaccore.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordbi.so" />
- <NativeSplittableBinary Include="$(BinDir)libsos.so" />
- <NativeSplittableBinary Include="$(BinDir)libsosplugin.so" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)sosdocsunix.txt" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)mscorlib.ni.dll" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)System.Private.CoreLib.ni.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)mscorlib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
- <ArchitectureSpecificToolFile Include="$(BinDir)crossgen" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- <!-- Using lib/netstandard1.0 here. There is no TFM for this since it is a runtime itself. -->
- <File Include="@(ArchitectureSpecificLibFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/lib/netstandard1.0</TargetPath>
- </File>
- <!-- No reference: don't permit reference to the implementation from lib -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>ref/netstandard1.0</TargetPath>
- </File>
- <File Include="@(ArchitectureSpecificToolFile)">
- <TargetPath>tools</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\sosdocsunix.txt" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\crossgen" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Linux.Microsoft.NETCore.Runtime.CoreCLR.props b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Linux.Microsoft.NETCore.Runtime.CoreCLR.props
new file mode 100644
index 0000000000..db8b03173b
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Linux.Microsoft.NETCore.Runtime.CoreCLR.props
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <_PlatformDoesNotSupportNiFiles Condition="'$(Platform)' == 'arm'">true</_PlatformDoesNotSupportNiFiles>
+ <_PlatformDoesNotSupportNiFiles Condition="'$(Platform)' == 'armel'">true</_PlatformDoesNotSupportNiFiles>
+ <_PlatformDoesNotSupportNiFiles Condition="'$(Platform)' == 'x86'">true</_PlatformDoesNotSupportNiFiles>
+ <_PlatformDoesNotSupportEventTrace Condition="'$(Platform)' == 'arm'">true</_PlatformDoesNotSupportEventTrace>
+ <_PlatformDoesNotSupportEventTrace Condition="'$(Platform)' == 'armel'">true</_PlatformDoesNotSupportEventTrace>
+ <_PlatformDoesNotSupportEventTrace Condition="'$(Platform)' == 'x86'">true</_PlatformDoesNotSupportEventTrace>
+ </PropertyGroup>
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)libcoreclr.so" />
+ <NativeBinary Condition="'$(_PlatformDoesNotSupportEventTrace)' != 'true'" Include="$(BinDir)libcoreclrtraceptprovider.so" />
+ <NativeBinary Include="$(BinDir)libdbgshim.so" />
+ <NativeBinary Include="$(BinDir)libmscordaccore.so" />
+ <NativeBinary Include="$(BinDir)libmscordbi.so" />
+ <NativeBinary Include="$(BinDir)libsos.so" />
+ <NativeBinary Include="$(BinDir)libsosplugin.so" />
+ <NativeBinary Include="$(BinDir)System.Globalization.Native.so" />
+ <NativeBinary Include="$(BinDir)sosdocsunix.txt" />
+ <NativeBinary Condition="'$(_PlatformDoesNotSupportNiFiles)' != 'true'" Include="$(BinDir)System.Private.CoreLib.ni.dll" />
+ <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
+ <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
+ <ArchitectureSpecificToolFile Include="$(BinDir)crossgen" />
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.OSX.Microsoft.NETCore.Runtime.CoreCLR.props b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.OSX.Microsoft.NETCore.Runtime.CoreCLR.props
new file mode 100644
index 0000000000..b988a40745
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.OSX.Microsoft.NETCore.Runtime.CoreCLR.props
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)libcoreclr.dylib" />
+ <NativeBinary Include="$(BinDir)libdbgshim.dylib" />
+ <NativeBinary Include="$(BinDir)libmscordaccore.dylib" />
+ <NativeBinary Include="$(BinDir)libmscordbi.dylib" />
+ <NativeBinary Include="$(BinDir)libsos.dylib" />
+ <NativeBinary Include="$(BinDir)System.Globalization.Native.dylib" />
+ <NativeBinary Include="$(BinDir)sosdocsunix.txt" />
+ <NativeBinary Include="$(BinDir)System.Private.CoreLib.ni.dll" />
+ <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
+ <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
+ <ArchitectureSpecificToolFile Include="$(BinDir)crossgen" />
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Windows_NT.Microsoft.NETCore.Runtime.CoreCLR.props b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Windows_NT.Microsoft.NETCore.Runtime.CoreCLR.props
new file mode 100644
index 0000000000..436901ebd2
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Windows_NT.Microsoft.NETCore.Runtime.CoreCLR.props
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <PackageTargetRuntime>$(MinOSForArch)-$(PackagePlatform)</PackageTargetRuntime>
+ <LongNamePlatform>$(PackagePlatform)</LongNamePlatform>
+ <LongNamePlatform Condition="'$(LongNamePlatform)'=='x64'">amd64</LongNamePlatform>
+ <CrossTargetPlatform>$(CrossTargetComponentFolder)</CrossTargetPlatform>
+ <CrossTargetPlatform Condition="'$(CrossTargetPlatform)'=='x64'">amd64</CrossTargetPlatform>
+ <LongNameSuffix>_$(LongNamePlatform)_$(LongNamePlatform)_$(MajorVersion).$(MinorVersion).$(BuildNumberMajor).0$(BuildNumberMinor)</LongNameSuffix>
+ <CrossTargetLongNameSuffix>_$(CrossTargetPlatform)_$(LongNamePlatform)_$(MajorVersion).$(MinorVersion).$(BuildNumberMajor).0$(BuildNumberMinor)</CrossTargetLongNameSuffix>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)clretwrc.dll" />
+ <NativeBinary Include="$(BinDir)coreclr.dll" />
+ <NativeBinary Include="$(BinDir)dbgshim.dll" />
+ <NativeBinary Include="$(BinDir)mscordaccore.dll" />
+ <NativeBinary Include="$(BinDir)mscordbi.dll" />
+ <NativeBinary Include="$(BinDir)mscorrc.debug.dll" />
+ <NativeBinary Include="$(BinDir)mscorrc.dll" />
+ <NativeBinary Include="$(BinDir)sos.dll" />
+ <NativeBinary Include="$(BinDir)System.Private.CoreLib.ni.dll" />
+ <NativeBinary Include="$(UniversalCRTSDKDir)Redist\ucrt\DLLs\$(BuildArch)\*.dll" Condition="'$(BuildType)'=='Release' AND '$(BuildArch)' != 'arm64'" />
+ <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
+ <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
+ <ArchitectureSpecificToolFile Include="$(BinDir)crossgen.exe" />
+ <CrossArchitectureSpecificToolFile Include="$(BinDir)$(CrossTargetComponentFolder)\crossgen.exe" />
+ <CrossArchitectureSpecificToolFile Include="$(BinDir)$(CrossTargetComponentFolder)\mscordaccore.dll" />
+ <CrossArchitectureSpecificToolFile Include="$(BinDir)$(CrossTargetComponentFolder)\mscordbi.dll" />
+ <CrossArchitectureSpecificToolFile Include="$(BinDir)$(CrossTargetComponentFolder)\sos.dll" />
+
+ <!-- prevent accidental inclusion in AOT projects. -->
+ <File Include="$(PlaceholderFile)">
+ <TargetPath>runtimes/$(PackageTargetRuntime)-aot/lib/netstandard1.0</TargetPath>
+ </File>
+ <File Include="$(PlaceholderFile)">
+ <TargetPath>runtimes/$(PackageTargetRuntime)-aot/native</TargetPath>
+ </File>
+
+ <!-- Create long-name files by including the same files again with a different target path. -->
+ <LongNameFile Include="$(BinDir)mscordaccore.dll;
+ $(BinDir)sos.dll">
+ <TargetPath>runtimes\$(PackageTargetRuntime)\native\%(FileName)$(LongNameSuffix)%(Extension)</TargetPath>
+ </LongNameFile>
+ <LongNameFile Include="$(BinDir)$(CrossTargetComponentFolder)\mscordaccore.dll;
+ $(BinDir)$(CrossTargetComponentFolder)\sos.dll"
+ Condition="'$(HasCrossTargetComponents)'=='true'">
+ <TargetPath>tools\$(CrossTargetComponentFolder)_$(PackagePlatform)\%(FileName)$(CrossTargetLongNameSuffix)%(Extension)</TargetPath>
+ </LongNameFile>
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/tizen/4.0.0/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/tizen/4.0.0/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
deleted file mode 100644
index dd2c46b077..0000000000
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/tizen/4.0.0/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>tizen.4.0.0-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for armel -->
- <PackagePlatforms>armel;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libcoreclr.so" />
- <NativeSplittableBinary Include="$(BinDir)libdbgshim.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordaccore.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordbi.so" />
- <NativeSplittableBinary Include="$(BinDir)libsos.so" />
- <NativeSplittableBinary Include="$(BinDir)libsosplugin.so" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)sosdocsunix.txt" />
- <!-- cannot generate in build now
- <ArchitectureSpecificNativeFile Include="$(BinDir)mscorlib.ni.dll" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)System.Private.CoreLib.ni.dll" />
- -->
- <ArchitectureSpecificLibFile Include="$(BinDir)mscorlib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
- <ArchitectureSpecificToolFile Include="$(BinDir)crossgen" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- <!-- Using lib/netstandard1.0 here. There is no TFM for this since it is a runtime itself. -->
- <File Include="@(ArchitectureSpecificLibFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/lib/netstandard1.0</TargetPath>
- </File>
- <!-- No reference: don't permit reference to the implementation from lib -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>ref/netstandard1.0</TargetPath>
- </File>
- <File Include="@(ArchitectureSpecificToolFile)">
- <TargetPath>tools</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\sosdocsunix.txt" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\crossgen" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/ubuntu/14.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/ubuntu/14.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
deleted file mode 100644
index 86cb61a264..0000000000
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/ubuntu/14.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.14.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- build for x64, arm -->
- <PackagePlatforms>x64;arm;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libcoreclr.so" />
- <NativeSplittableBinary Condition="'$(PackagePlatform)' != 'arm'" Include="$(BinDir)libcoreclrtraceptprovider.so" />
- <NativeSplittableBinary Include="$(BinDir)libdbgshim.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordaccore.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordbi.so" />
- <NativeSplittableBinary Include="$(BinDir)libsos.so" />
- <NativeSplittableBinary Include="$(BinDir)libsosplugin.so" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)sosdocsunix.txt" />
- <ArchitectureSpecificNativeFile Condition="'$(PackagePlatform)'!='arm'" Include="$(BinDir)mscorlib.ni.dll" />
- <ArchitectureSpecificNativeFile Condition="'$(PackagePlatform)'!='arm'" Include="$(BinDir)System.Private.CoreLib.ni.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)mscorlib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
- <ArchitectureSpecificToolFile Include="$(BinDir)crossgen" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- <!-- Using lib/netstandard1.0 here. There is no TFM for this since it is a runtime itself. -->
- <File Include="@(ArchitectureSpecificLibFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/lib/netstandard1.0</TargetPath>
- </File>
- <!-- No reference: don't permit reference to the implementation from lib -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>ref/netstandard1.0</TargetPath>
- </File>
- <File Include="@(ArchitectureSpecificToolFile)">
- <TargetPath>tools</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\sosdocsunix.txt" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\crossgen" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/ubuntu/16.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/ubuntu/16.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
deleted file mode 100644
index 72c48ee459..0000000000
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/ubuntu/16.04/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.16.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- build for x64, arm -->
- <PackagePlatforms>x64;arm;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libcoreclr.so" />
- <NativeSplittableBinary Condition="'$(PackagePlatform)' != 'arm'" Include="$(BinDir)libcoreclrtraceptprovider.so" />
- <NativeSplittableBinary Include="$(BinDir)libdbgshim.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordaccore.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordbi.so" />
- <NativeSplittableBinary Include="$(BinDir)libsos.so" />
- <NativeSplittableBinary Include="$(BinDir)libsosplugin.so" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)sosdocsunix.txt" />
- <ArchitectureSpecificNativeFile Condition="'$(PackagePlatform)' != 'arm'" Include="$(BinDir)mscorlib.ni.dll" />
- <ArchitectureSpecificNativeFile Condition="'$(PackagePlatform)' != 'arm'" Include="$(BinDir)System.Private.CoreLib.ni.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)mscorlib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
- <ArchitectureSpecificToolFile Include="$(BinDir)crossgen" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- <!-- Using lib/netstandard1.0 here. There is no TFM for this since it is a runtime itself. -->
- <File Include="@(ArchitectureSpecificLibFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/lib/netstandard1.0</TargetPath>
- </File>
- <!-- No reference: don't permit reference to the implementation from lib -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>ref/netstandard1.0</TargetPath>
- </File>
- <File Include="@(ArchitectureSpecificToolFile)">
- <TargetPath>tools</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\sosdocsunix.txt" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\crossgen" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/ubuntu/16.10/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/ubuntu/16.10/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
deleted file mode 100644
index 9f226f8530..0000000000
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/ubuntu/16.10/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.16.10-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)libcoreclr.so" />
- <NativeSplittableBinary Include="$(BinDir)libcoreclrtraceptprovider.so" />
- <NativeSplittableBinary Include="$(BinDir)libdbgshim.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordaccore.so" />
- <NativeSplittableBinary Include="$(BinDir)libmscordbi.so" />
- <NativeSplittableBinary Include="$(BinDir)libsos.so" />
- <NativeSplittableBinary Include="$(BinDir)libsosplugin.so" />
- <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)sosdocsunix.txt" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)mscorlib.ni.dll" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)System.Private.CoreLib.ni.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)mscorlib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
- <ArchitectureSpecificToolFile Include="$(BinDir)crossgen" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- <!-- Using lib/netstandard1.0 here. There is no TFM for this since it is a runtime itself. -->
- <File Include="@(ArchitectureSpecificLibFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/lib/netstandard1.0</TargetPath>
- </File>
- <!-- No reference: don't permit reference to the implementation from lib -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>ref/netstandard1.0</TargetPath>
- </File>
- <File Include="@(ArchitectureSpecificToolFile)">
- <TargetPath>tools</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\sosdocsunix.txt" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\crossgen" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/win/Microsoft.NETCore.Runtime.CoreCLR.pkgproj b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/win/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
deleted file mode 100644
index 844fb0b10f..0000000000
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/win/Microsoft.NETCore.Runtime.CoreCLR.pkgproj
+++ /dev/null
@@ -1,99 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-
- <PropertyGroup>
- <PackageTargetRuntime>$(MinOSForArch)-$(PackagePlatform)</PackageTargetRuntime>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <LongNamePlatform>$(PackagePlatform)</LongNamePlatform>
- <LongNamePlatform Condition="'$(LongNamePlatform)'=='x64'">amd64</LongNamePlatform>
- <CrossTargetPlatform>$(CrossTargetComponentFolder)</CrossTargetPlatform>
- <CrossTargetPlatform Condition="'$(CrossTargetPlatform)'=='x64'">amd64</CrossTargetPlatform>
- <LongNameSuffix>_$(LongNamePlatform)_$(LongNamePlatform)_$(MajorVersion).$(MinorVersion).$(BuildNumberMajor).0$(BuildNumberMinor)</LongNameSuffix>
- <CrossTargetLongNameSuffix>_$(CrossTargetPlatform)_$(LongNamePlatform)_$(MajorVersion).$(MinorVersion).$(BuildNumberMajor).0$(BuildNumberMinor)</CrossTargetLongNameSuffix>
- </PropertyGroup>
-
- <ItemGroup>
- <LongNameFiles Include="mscordaccore.dll"/>
- <LongNameFiles Include="sos.dll"/>
- </ItemGroup>
-
- <Target Name="CopyLongNamedBinaries" BeforeTargets="CreatePackage">
- <Copy
- SourceFiles="@(LongNameFiles -> '$(BinDir)%(Identity)')"
- DestinationFiles="@(LongNameFiles -> '$(BinDir)%(FileName)$(LongNameSuffix)%(Extension)')">
- </Copy>
- <Copy Condition="'$(HasCrossTargetComponents)' == 'true'"
- SourceFiles="@(LongNameFiles -> '$(BinDir)$(CrossTargetComponentFolder)\%(Identity)')"
- DestinationFiles="@(LongNameFiles -> '$(BinDir)$(CrossTargetComponentFolder)\%(FileName)$(CrossTargetLongNameSuffix)%(Extension)')">
- </Copy>
- </Target>
-
- <ItemGroup>
- <ArchitectureSpecificNativeFileAndSymbol Include="$(BinDir)clretwrc.dll" />
- <ArchitectureSpecificNativeFileAndSymbol Include="$(BinDir)coreclr.dll" />
- <ArchitectureSpecificNativeFileAndSymbol Include="$(BinDir)dbgshim.dll" />
- <ArchitectureSpecificNativeFileAndSymbol Include="$(BinDir)mscordaccore.dll" />
- <ArchitectureSpecificNativeFileAndSymbol Include="$(BinDir)mscordbi.dll" />
- <ArchitectureSpecificNativeFileAndSymbol Include="$(BinDir)mscorrc.debug.dll" />
- <ArchitectureSpecificNativeFileAndSymbol Include="$(BinDir)mscorrc.dll" />
- <ArchitectureSpecificNativeFileAndSymbol Include="$(BinDir)sos.dll" />
- <ArchitectureSpecificNativeFile Include="$(BinDir)mscorlib.ni.dll" />
- <ArchitectureSpecificNativeFileAndSymbol Include="$(BinDir)System.Private.CoreLib.ni.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)mscorlib.dll" />
- <ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
- <ArchitectureSpecificToolFile Include="$(BinDir)crossgen.exe" />
- <CrossArchitectureSpecificToolFile Include="$(BinDir)$(CrossTargetComponentFolder)\crossgen.exe" />
- <CrossArchitectureSpecificToolFile Include="$(BinDir)$(CrossTargetComponentFolder)\mscordaccore.dll" />
- <CrossArchitectureSpecificToolFile Include="$(BinDir)$(CrossTargetComponentFolder)\mscordbi.dll" />
- <CrossArchitectureSpecificToolFile Include="$(BinDir)$(CrossTargetComponentFolder)\sos.dll" />
- <ArchitectureSpecificNativeFile Include="@(ArchitectureSpecificNativeFileAndSymbol)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes\$(PackageTargetRuntime)\native</TargetPath>
- </File>
- <!-- Using lib/netstandard1.0 here. There is no TFM for this since it is a runtime itself. -->
- <File Include="@(ArchitectureSpecificLibFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/lib/netstandard1.0</TargetPath>
- </File>
- <File Include="@(ArchitectureSpecificToolFile)">
- <TargetPath>tools</TargetPath>
- </File>
- <File Condition="'$(HasCrossTargetComponents)' == 'true'" Include="@(CrossArchitectureSpecificToolFile)">
- <TargetPath>tools/$(CrossTargetComponentFolder)_$(PackagePlatform)</TargetPath>
- </File>
- <!-- prevent accidental inclusion in AOT projects. -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)-aot/lib/netstandard1.0</TargetPath>
- </File>
- <File Include="$(PlaceholderFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)-aot/native</TargetPath>
- </File>
- <!-- No reference: don't permit reference to the implementation from lib -->
- <File Include="$(PlaceholderFile)">
- <TargetPath>ref/netstandard1.0</TargetPath>
- </File>
- <!-- Symbols -->
- <ArchitectureSpecificNativeSymbol Include="@(ArchitectureSpecificNativeFileAndSymbol -> '%(RelativeDir)PDB\%(FileName).pdb')" />
- <ArchitectureSpecificNativeSymbol Include="@(ArchitectureSpecificLibFile -> '%(RelativeDir)PDB\%(FileName).pdb')" />
- <ArchitectureSpecificNativeSymbol Include="@(ArchitectureSpecificToolFile -> '%(RelativeDir)PDB\%(FileName).pdb')" />
- <ArchitectureSpecificNativeSymbol Include="@(LongNameFiles -> '$(BinDir)%(FileName)$(LongNameSuffix)%(Extension)')" />
- <AdditionalLibPackageExcludes Include="@(LongNameFiles -> 'runtimes\$(PackageTargetRuntime)\native\%(FileName)$(LongNameSuffix)%(Extension)')" />
- <CrossArchitectureSpecificNativeSymbol Condition="'$(HasCrossTargetComponents)' == 'true'"
- Include="@(CrossArchitectureSpecificToolFile -> '%(RelativeDir)PDB\%(FileName).pdb')" />
- <CrossArchitectureSpecificNativeSymbol Condition="'$(HasCrossTargetComponents)' == 'true'"
- Include="@(LongNameFiles -> '$(BinDir)$(CrossTargetComponentFolder)\%(FileName)$(CrossTargetLongNameSuffix)%(Extension)')" />
- <AdditionalLibPackageExcludes Condition="'$(HasCrossTargetComponents)' == 'true'"
- Include="@(LongNameFiles -> 'tools\$(CrossTargetComponentFolder)_$(PackagePlatform)\%(FileName)$(CrossTargetLongNameSuffix)%(Extension)')" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes\$(PackageTargetRuntime)\native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- <File Condition="'$(HasCrossTargetComponents)' == 'true'" Include="@(CrossArchitectureSpecificNativeSymbol)">
- <TargetPath>tools\$(CrossTargetComponentFolder)_$(PackagePlatform)</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
-
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.builds b/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.builds
index 67b105ba76..c55af3a6d3 100644
--- a/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.builds
+++ b/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.builds
@@ -2,96 +2,10 @@
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <!-- This property must be set to the same value as $(PackageOutputPath) for the nuspecs and nupkgs to be binplaced to the intended location. -->
- <OutputPath>$(PackageOutputPath)</OutputPath>
- </PropertyGroup>
-
- <!-- We always build the identity/redirection package. However, the platform specific runtime-*.nupkg is built based upon the target OS we are building the product for. -->
<ItemGroup>
- <Project Include="Microsoft.NETCore.TestHost.pkgproj">
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>arm64</Platform>
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>x86</Platform>
- </Project>
- <Project Condition="'$(TargetsWindows)' == 'true'" Include="win/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Windows_NT</OSGroup>
- <Platform>arm</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'linux-x64'" Include="linux/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'debian.8-x64'" Include="debian/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'debian.8-armel'" Include="debian/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>armel</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'fedora.23-x64'" Include="fedora/23/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'fedora.24-x64'" Include="fedora/24/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'opensuse.13.2-x64'" Include="opensuse/13.2/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'opensuse.42.1-x64'" Include="opensuse/42.1/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and $(DistroRid.StartsWith('rhel.7'))" Include="rhel/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.14.04-x64'" Include="ubuntu/14.04/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.14.04-arm'" Include="ubuntu/14.04/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>arm</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.04-x64'" Include="ubuntu/16.04/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.04-arm'" Include="ubuntu/16.04/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>arm</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.10-x64'" Include="ubuntu/16.10/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'alpine.3.4.3-x64'" Include="alpine/3.4.3/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>amd64</Platform>
- </Project>
- <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'tizen.4.0.0-armel'" Include="tizen/4.0.0/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>Linux</OSGroup>
- <Platform>armel</Platform>
- </Project>
- <Project Condition="'$(TargetsOSX)' == 'true'" Include="osx/Microsoft.NETCore.TestHost.pkgproj">
- <OSGroup>OSX</OSGroup>
- <Platform>amd64</Platform>
- </Project>
+ <!-- identity project, runtime specific projects are included by props above -->
+ <Project Include="$(MSBuildProjectName).pkgproj" />
</ItemGroup>
-
+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
</Project>
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.pkgproj
index ee8f6a94c4..909206b58b 100644
--- a/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.pkgproj
+++ b/src/.nuget/Microsoft.NETCore.TestHost/Microsoft.NETCore.TestHost.pkgproj
@@ -1,74 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <SkipValidatePackage>true</SkipValidatePackage>
- <PackagePlatforms>x64;x86;arm64;arm;armel;</PackagePlatforms>
- <OutputPath>$(PackagesOutputPath)</OutputPath>
- <IncludeRuntimeJson>true</IncludeRuntimeJson>
+
+ <PropertyGroup Condition="'$(PackageTargetRuntime)' == ''">
+ <IsLineupPackage Condition="'$(IsLineupPackage)' == ''">true</IsLineupPackage>
</PropertyGroup>
- <ItemGroup>
- <ProjectReference Include="win\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="win\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>arm64</Platform>
- </ProjectReference>
- <ProjectReference Include="win\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>x86</Platform>
- </ProjectReference>
- <ProjectReference Include="win\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>arm</Platform>
- </ProjectReference>
- <ProjectReference Include="linux\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="debian\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="debian\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>armel</Platform>
- </ProjectReference>
- <ProjectReference Include="fedora\23\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="fedora\24\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="opensuse\13.2\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="opensuse\42.1\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="rhel\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\14.04\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\14.04\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>arm</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.04\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.04\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>arm</Platform>
- </ProjectReference>
- <ProjectReference Include="ubuntu\16.10\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="alpine\3.4.3\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- <ProjectReference Include="tizen\4.0.0\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>armel</Platform>
- </ProjectReference>
- <ProjectReference Include="osx\Microsoft.NETCore.TestHost.pkgproj">
- <Platform>amd64</Platform>
- </ProjectReference>
- </ItemGroup>
+
+ <Import Condition="'$(_packageTargetOSGroup)' != ''" Project="$(MSBuildThisFileDirectory)runtime.$(_packageTargetOSGroup).$(MSBuildProjectName).props" />
+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/alpine/3.4.3/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/alpine/3.4.3/Microsoft.NETCore.TestHost.pkgproj
deleted file mode 100644
index dd142f6711..0000000000
--- a/src/.nuget/Microsoft.NETCore.TestHost/alpine/3.4.3/Microsoft.NETCore.TestHost.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>alpine.3.4.3-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)corerun" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/debian/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/debian/Microsoft.NETCore.TestHost.pkgproj
deleted file mode 100644
index 5d739bd58d..0000000000
--- a/src/.nuget/Microsoft.NETCore.TestHost/debian/Microsoft.NETCore.TestHost.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>debian.8-$(PackagePlatform)</PackageTargetRuntime>
- <!-- build for x64, armel -->
- <PackagePlatforms>x64;armel;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)corerun" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/fedora/23/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/fedora/23/Microsoft.NETCore.TestHost.pkgproj
deleted file mode 100644
index 2edb86a28a..0000000000
--- a/src/.nuget/Microsoft.NETCore.TestHost/fedora/23/Microsoft.NETCore.TestHost.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>fedora.23-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)corerun" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/fedora/24/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/fedora/24/Microsoft.NETCore.TestHost.pkgproj
deleted file mode 100644
index 219026c703..0000000000
--- a/src/.nuget/Microsoft.NETCore.TestHost/fedora/24/Microsoft.NETCore.TestHost.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>fedora.24-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)corerun" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/linux/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/linux/Microsoft.NETCore.TestHost.pkgproj
deleted file mode 100644
index 06a6f4ce10..0000000000
--- a/src/.nuget/Microsoft.NETCore.TestHost/linux/Microsoft.NETCore.TestHost.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>linux-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)corerun" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/opensuse/13.2/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/opensuse/13.2/Microsoft.NETCore.TestHost.pkgproj
deleted file mode 100644
index 31740920e0..0000000000
--- a/src/.nuget/Microsoft.NETCore.TestHost/opensuse/13.2/Microsoft.NETCore.TestHost.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>opensuse.13.2-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)corerun" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/opensuse/42.1/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/opensuse/42.1/Microsoft.NETCore.TestHost.pkgproj
deleted file mode 100644
index 8aaec62373..0000000000
--- a/src/.nuget/Microsoft.NETCore.TestHost/opensuse/42.1/Microsoft.NETCore.TestHost.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>opensuse.42.1-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)corerun" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/osx/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/osx/Microsoft.NETCore.TestHost.pkgproj
deleted file mode 100644
index cbcc805d8d..0000000000
--- a/src/.nuget/Microsoft.NETCore.TestHost/osx/Microsoft.NETCore.TestHost.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>osx.10.10-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)corerun" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dwarf')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dwarf" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dylib" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/rhel/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/rhel/Microsoft.NETCore.TestHost.pkgproj
deleted file mode 100644
index 1cfaf50d5d..0000000000
--- a/src/.nuget/Microsoft.NETCore.TestHost/rhel/Microsoft.NETCore.TestHost.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>rhel.7-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)corerun" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/runtime.Linux.Microsoft.NETCore.TestHost.props b/src/.nuget/Microsoft.NETCore.TestHost/runtime.Linux.Microsoft.NETCore.TestHost.props
new file mode 100644
index 0000000000..ce004bdac4
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.TestHost/runtime.Linux.Microsoft.NETCore.TestHost.props
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)corerun" />
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/runtime.OSX.Microsoft.NETCore.TestHost.props b/src/.nuget/Microsoft.NETCore.TestHost/runtime.OSX.Microsoft.NETCore.TestHost.props
new file mode 100644
index 0000000000..ce004bdac4
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.TestHost/runtime.OSX.Microsoft.NETCore.TestHost.props
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)corerun" />
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/runtime.Windows_NT.Microsoft.NETCore.TestHost.props b/src/.nuget/Microsoft.NETCore.TestHost/runtime.Windows_NT.Microsoft.NETCore.TestHost.props
new file mode 100644
index 0000000000..96c2595cf9
--- /dev/null
+++ b/src/.nuget/Microsoft.NETCore.TestHost/runtime.Windows_NT.Microsoft.NETCore.TestHost.props
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <PackageTargetRuntime>$(MinOSForArch)-$(PackagePlatform)</PackageTargetRuntime>
+ </PropertyGroup>
+ <ItemGroup>
+ <NativeBinary Include="$(BinDir)CoreRun.exe" />
+ </ItemGroup>
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/tizen/4.0.0/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/tizen/4.0.0/Microsoft.NETCore.TestHost.pkgproj
deleted file mode 100644
index b7620b9806..0000000000
--- a/src/.nuget/Microsoft.NETCore.TestHost/tizen/4.0.0/Microsoft.NETCore.TestHost.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>tizen.4.0.0-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for armel -->
- <PackagePlatforms>armel;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)corerun" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/ubuntu/14.04/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/ubuntu/14.04/Microsoft.NETCore.TestHost.pkgproj
deleted file mode 100644
index 8750e16817..0000000000
--- a/src/.nuget/Microsoft.NETCore.TestHost/ubuntu/14.04/Microsoft.NETCore.TestHost.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.14.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- build for x64, arm -->
- <PackagePlatforms>x64;arm;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)corerun" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/ubuntu/16.04/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/ubuntu/16.04/Microsoft.NETCore.TestHost.pkgproj
deleted file mode 100644
index 3f1397f92f..0000000000
--- a/src/.nuget/Microsoft.NETCore.TestHost/ubuntu/16.04/Microsoft.NETCore.TestHost.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.16.04-$(PackagePlatform)</PackageTargetRuntime>
- <!-- build for x64, arm -->
- <PackagePlatforms>x64;arm;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)corerun" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/ubuntu/16.10/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/ubuntu/16.10/Microsoft.NETCore.TestHost.pkgproj
deleted file mode 100644
index 88ad98a4db..0000000000
--- a/src/.nuget/Microsoft.NETCore.TestHost/ubuntu/16.10/Microsoft.NETCore.TestHost.pkgproj
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- <PackageTargetRuntime>ubuntu.16.10-$(PackagePlatform)</PackageTargetRuntime>
- <!-- only build for x64 -->
- <PackagePlatforms>x64;</PackagePlatforms>
- </PropertyGroup>
- <ItemGroup>
- <NativeSplittableBinary Include="$(BinDir)corerun" />
- <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup Condition="'$(__BuildType)' == 'Release'">
- <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
- <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.NETCore.TestHost/win/Microsoft.NETCore.TestHost.pkgproj b/src/.nuget/Microsoft.NETCore.TestHost/win/Microsoft.NETCore.TestHost.pkgproj
deleted file mode 100644
index 33ab15fb62..0000000000
--- a/src/.nuget/Microsoft.NETCore.TestHost/win/Microsoft.NETCore.TestHost.pkgproj
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
- <PropertyGroup>
- <PackageTargetRuntime>$(MinOSForArch)-$(PackagePlatform)</PackageTargetRuntime>
- <SkipPackageFileCheck>true</SkipPackageFileCheck>
- </PropertyGroup>
- <ItemGroup>
- <ArchitectureSpecificNativeFile Include="$(BinDir)CoreRun.exe" />
- <File Include="@(ArchitectureSpecificNativeFile)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- </File>
- </ItemGroup>
- <ItemGroup>
- <ArchitectureSpecificNativeSymbol Include="@(ArchitectureSpecificNativeFile -> '%(RelativeDir)PDB\%(FileName).pdb')" />
- <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
- <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
- <File Include="@(ArchitectureSpecificNativeSymbol)">
- <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
- <IsSymbolFile>true</IsSymbolFile>
- </File>
- </ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project> \ No newline at end of file
diff --git a/src/.nuget/Microsoft.TargetingPack.Private.CoreCLR/Microsoft.TargetingPack.Private.CoreCLR.pkgproj b/src/.nuget/Microsoft.TargetingPack.Private.CoreCLR/Microsoft.TargetingPack.Private.CoreCLR.pkgproj
index 253cba083d..ecc1e491a0 100644
--- a/src/.nuget/Microsoft.TargetingPack.Private.CoreCLR/Microsoft.TargetingPack.Private.CoreCLR.pkgproj
+++ b/src/.nuget/Microsoft.TargetingPack.Private.CoreCLR/Microsoft.TargetingPack.Private.CoreCLR.pkgproj
@@ -4,13 +4,9 @@
<PropertyGroup>
<SkipPackageFileCheck>true</SkipPackageFileCheck>
<SkipValidatePackage>true</SkipValidatePackage>
- <PackagePlatforms>x64;</PackagePlatforms>
<OutputPath>$(PackagesOutputPath)</OutputPath>
</PropertyGroup>
<ItemGroup>
- <File Include="$(BinDir)/ref/mscorlib.dll">
- <TargetPath>lib/netstandard1.0</TargetPath>
- </File>
<File Include="$(BinDir)/System.Private.CoreLib.dll">
<TargetPath>lib/netstandard1.0</TargetPath>
</File>
diff --git a/src/.nuget/dir.props b/src/.nuget/dir.props
new file mode 100644
index 0000000000..59b94f75b2
--- /dev/null
+++ b/src/.nuget/dir.props
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildThisFileDirectory)..\..\dir.props" />
+
+ <PropertyGroup>
+ <!-- defined in buildtools packaging.targets, but we need this before targets are imported -->
+ <PackagePlatform>AnyCPU</PackagePlatform>
+
+ <!-- build the transport package which includes product and symbols in addition to standard packages -->
+ <CreatePackedPackage Condition="'$(CreatePackedPackage)' == ''">true</CreatePackedPackage>
+
+ <!-- Distro rid is passed as runtimeos-arch-->
+ <_parseDistroRid>$(__DistroRid)</_parseDistroRid>
+ <_parseDistroRid Condition="'$(_parseDistroRid)' == '' and '$(__BuildOS)' == 'OSX'">osx.10.12-x64</_parseDistroRid>
+ <_distroRidIndex>$(_parseDistroRid.IndexOfAny("-"))</_distroRidIndex>
+ <_archRidIndex>$([MSBuild]::Add($(_distroRidIndex), 1))</_archRidIndex>
+ <OSRid Condition="'$(OSRid)' == '' and '$(_distroRidIndex)' != '-1'">$(_parseDistroRid.SubString(0, $(_distroRidIndex)))</OSRid>
+ <OSRid Condition="'$(OSRid)' == ''">win10</OSRid>
+
+ <ArchGroup Condition="'$(ArchGroup)' == '' and '$(_archRidIndex)' != '0'">$(_parseDistroRid.SubString($(_archRidIndex)))</ArchGroup>
+ <ArchGroup Condition="'$(ArchGroup)' == '' and '$(Platform)' != ''">$(Platform)</ArchGroup>
+ <ArchGroup Condition="'$(ArchGroup)' == ''">$(BuildArch)</ArchGroup>
+
+ <RuntimeOS Condition="'$(RuntimeOS)' == ''">$(OSRid)</RuntimeOS>
+
+ <SupportedPackageOSGroups Condition="'$(SupportedPackageOSGroups)' == ''">Windows_NT;OSX;Linux</SupportedPackageOSGroups>
+ <SupportedPackageOSGroups>;$(SupportedPackageOSGroups);</SupportedPackageOSGroups>
+
+ <_runtimeOSVersionIndex>$(RuntimeOS.IndexOfAny(".-0123456789"))</_runtimeOSVersionIndex>
+ <_runtimeOSFamily Condition="'$(_runtimeOSVersionIndex)' != '-1'">$(RuntimeOS.SubString(0, $(_runtimeOSVersionIndex)))</_runtimeOSFamily>
+ <_isSupportedOSGroup>true</_isSupportedOSGroup>
+ </PropertyGroup>
+
+ <!-- derive an OS Group based on the OS Family -->
+ <PropertyGroup>
+ <_derivedPackageTargetOSGroup Condition="'$(_derivedPackageTargetOSGroup)' == '' and '$(_runtimeOSFamily)' == 'osx'">OSX</_derivedPackageTargetOSGroup>
+ <_derivedPackageTargetOSGroup Condition="'$(_derivedPackageTargetOSGroup)' == '' and '$(_runtimeOSFamily)' == 'win'">Windows_NT</_derivedPackageTargetOSGroup>
+ <_derivedPackageTargetOSGroup Condition="'$(_derivedPackageTargetOSGroup)' == '' and '$(__BuildOS)' != ''">$(__BuildOS)</_derivedPackageTargetOSGroup>
+ <_derivedPackageTargetOSGroup Condition="'$(_derivedPackageTargetOSGroup)' == ''">Linux</_derivedPackageTargetOSGroup>
+
+ <_isSupportedOSGroup Condition="!$(SupportedPackageOSGroups.Contains(';$(_derivedPackageTargetOSGroup);'))">false</_isSupportedOSGroup>
+ </PropertyGroup>
+
+ <!-- _packageTargetOSGroup is used to control the runtime package imports, don't import runtime package targets for
+ an unsupported OS Group -->
+ <PropertyGroup Condition="'$(PackageTargetRuntime)' != '' and '$(_isSupportedOSGroup)' == 'true'">
+ <_packageTargetOSGroup>$(_derivedPackageTargetOSGroup)</_packageTargetOSGroup>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <SkipPackageFileCheck>true</SkipPackageFileCheck>
+ <OutputPath>$(PackageOutputPath)</OutputPath>
+ </PropertyGroup>
+
+ <PropertyGroup Condition="'$(IsLineupPackage)' == 'true'">
+ <SkipValidatePackage>true</SkipValidatePackage>
+ <IncludeRuntimeJson>true</IncludeRuntimeJson>
+ </PropertyGroup>
+
+ <Choose>
+ <When Condition="'$(PackageRID)' != ''" />
+ <When Condition="'$(_runtimeOSFamily)' == 'win'">
+ <PropertyGroup>
+ <RIDPlatform>win7</RIDPlatform>
+ <RIDPlatform Condition="'$(ArchGroup)' == 'arm'">win8</RIDPlatform>
+ <RIDPlatform Condition="'$(ArchGroup)' == 'arm64'">win10</RIDPlatform>
+
+ <!-- Set the platform part of the RID if we are doing a portable build -->
+ <RIDPlatform Condition="'$(PortableBuild)' == '1'">win</RIDPlatform>
+ <PackageRID>$(RIDPlatform)-$(ArchGroup)</PackageRID>
+ </PropertyGroup>
+ </When>
+ <When Condition="'$(_runtimeOSFamily)' == 'osx'">
+ <PropertyGroup>
+ <PackageRID>osx.10.12-$(ArchGroup)</PackageRID>
+ <!-- Set the platform part of the RID if we are doing a portable build -->
+ <PackageRID Condition="'$(PortableBuild)' == '1'">osx-$(ArchGroup)</PackageRID>
+ </PropertyGroup>
+ </When>
+ <When Condition="'$(_runtimeOSFamily)' == 'rhel'">
+ <PropertyGroup>
+ <PackageRID>rhel.7-$(ArchGroup)</PackageRID>
+ <!-- Set the platform part of the RID if we are doing a portable build -->
+ <PackageRID Condition="'$(PortableBuild)' == '1'">linux-$(ArchGroup)</PackageRID>
+ </PropertyGroup>
+ </When>
+ <Otherwise>
+ <PropertyGroup>
+ <PackageRID>$(RuntimeOS)-$(ArchGroup)</PackageRID>
+ <!-- Set the platform part of the RID if we are doing a portable build -->
+ <PackageRID Condition="'$(PortableBuild)' == '1'">linux-$(ArchGroup)</PackageRID>
+ </PropertyGroup>
+ </Otherwise>
+ </Choose>
+
+ <!-- Determine per-platform native binary extensions. -->
+ <Choose>
+ <When Condition="'$(_runtimeOSFamily)' == 'win'" />
+ <When Condition="'$(_runtimeOSFamily)' == 'osx'">
+ <PropertyGroup>
+ <LibraryFileExtension>.dylib</LibraryFileExtension>
+ <SymbolFileExtension>.dwarf</SymbolFileExtension>
+ </PropertyGroup>
+ </When>
+ <Otherwise>
+ <PropertyGroup>
+ <LibraryFileExtension>.so</LibraryFileExtension>
+ <SymbolFileExtension>.dbg</SymbolFileExtension>
+ </PropertyGroup>
+ </Otherwise>
+ </Choose>
+
+ <ItemGroup Condition="$(SupportedPackageOSGroups.Contains(';Linux;'))">
+ <OfficialBuildRID Include="alpine.3.4.3-x64" />
+ <OfficialBuildRID Include="debian.8-armel">
+ <Platform>armel</Platform>
+ </OfficialBuildRID>
+ <OfficialBuildRID Include="debian.8-x64" />
+ <OfficialBuildRID Include="fedora.23-x64" />
+ <OfficialBuildRID Include="fedora.24-x64" />
+ <OfficialBuildRID Include="linux-x64" />
+ <OfficialBuildRID Include="linux-arm">
+ <Platform>arm</Platform>
+ </OfficialBuildRID>
+ <OfficialBuildRID Include="opensuse.42.1-x64" />
+ <OfficialBuildRID Include="rhel.7-x64" />
+ <OfficialBuildRID Include="tizen.4.0.0-armel">
+ <Platform>armel</Platform>
+ </OfficialBuildRID>
+ <OfficialBuildRID Include="ubuntu.14.04-arm">
+ <Platform>arm</Platform>
+ </OfficialBuildRID>
+ <OfficialBuildRID Include="ubuntu.14.04-x64" />
+ <OfficialBuildRID Include="ubuntu.16.04-arm">
+ <Platform>arm</Platform>
+ </OfficialBuildRID>
+ <OfficialBuildRID Include="ubuntu.16.04-x64" />
+ <OfficialBuildRID Include="ubuntu.16.10-x64" />
+ </ItemGroup>
+ <ItemGroup Condition="$(SupportedPackageOSGroups.Contains(';OSX;'))">
+ <OfficialBuildRID Include="osx.10.12-x64" />
+ <OfficialBuildRID Include="osx-x64" />
+ </ItemGroup>
+ <ItemGroup Condition="$(SupportedPackageOSGroups.Contains(';Windows_NT;'))">
+ <OfficialBuildRID Include="win7-x86">
+ <Platform>x86</Platform>
+ </OfficialBuildRID>
+ <OfficialBuildRID Include="win-x86">
+ <Platform>x86</Platform>
+ </OfficialBuildRID>
+ <OfficialBuildRID Include="win7-x64" />
+ <OfficialBuildRID Include="win-x64" />
+ <OfficialBuildRID Include="win8-arm">
+ <Platform>arm</Platform>
+ </OfficialBuildRID>
+ <OfficialBuildRID Include="win10-arm64">
+ <Platform>arm64</Platform>
+ </OfficialBuildRID>
+ <OfficialBuildRID Include="win-arm">
+ <Platform>arm</Platform>
+ </OfficialBuildRID>
+ <OfficialBuildRID Include="win-arm64">
+ <Platform>arm64</Platform>
+ </OfficialBuildRID>
+ </ItemGroup>
+ <ItemGroup>
+ <!-- Ensure we have a RID-specific package for the current build, even if it isn't in our official set, but
+ don't build the RID-specific package if we're in an unsupported os family -->
+ <BuildRID Include="@(OfficialBuildRID)" Exclude="$(PackageRID)"/>
+ <BuildRID Include="$(PackageRID)"
+ Condition="'$(_isSupportedOSGroup)' == 'true'">
+ <Platform Condition="'$(ArchGroup)' == 'x64'">amd64</Platform>
+ <Platform Condition="'$(ArchGroup)' != 'x64'">$(ArchGroup)</Platform>
+ </BuildRID>
+ </ItemGroup>
+
+ <ItemGroup>
+ <_project Include="@(BuildRID)">
+ <Platform Condition="'%(Platform)' == ''">amd64</Platform>
+ <PackageTargetRuntime>%(Identity)</PackageTargetRuntime>
+ <AdditionalProperties>PackageTargetRuntime=%(Identity);Platform=%(Platform)</AdditionalProperties>
+ </_project>
+
+ <_buildRidProjects Include="@(_project->'$(MSBuildProjectName).pkgproj')" />
+ <!-- Only include rid projects for a builds file, not for a lineup package -->
+ <Project Condition="'$(IsLineupPackage)' != 'true'" Include="@(_buildRidProjects)" />
+ </ItemGroup>
+
+ <ItemGroup Condition="'$(IsLineupPackage)' == 'true'">
+ <!-- Include project references for a lineup package to generate the runtime.json file -->
+ <ProjectReference Include="@(_buildRidProjects)" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/src/.nuget/dir.targets b/src/.nuget/dir.targets
new file mode 100644
index 0000000000..49e550a4b7
--- /dev/null
+++ b/src/.nuget/dir.targets
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+
+ <Target Name="VerifyVCRedist" BeforeTargets="GetSymbolPackageFiles" Condition="'$(_runtimeOSFamily)' == 'win'">
+ <Error Condition="'$(UniversalCRTSDKDir)' == ''" Text="Unable to find VC Redist binaries - check that UniversalCRTSDKDir environment variable is set" />
+ </Target>
+ <!--
+ Finds symbol files and injects them into the package build.
+ -->
+ <Target Name="GetSymbolPackageFiles" BeforeTargets="GetPackageFiles">
+ <ItemGroup Condition="'$(SymbolFileExtension)' != ''">
+ <AdditionalLibPackageExcludes Include="%2A%2A\%2A$(SymbolFileExtension)"/>
+ </ItemGroup>
+
+ <ItemGroup>
+ <AdditionalLibPackageExcludes Include="@(LongNameFile -> '%(TargetPath)')" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <NativeWithSymbolFile Include="@(NativeBinary)">
+ <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+ </NativeWithSymbolFile>
+ <!-- Using lib/netstandard1.0 here. There is no TFM for this since it is a runtime itself. -->
+ <NativeWithSymbolFile Include="@(ArchitectureSpecificLibFile)">
+ <TargetPath>runtimes/$(PackageTargetRuntime)/lib/netstandard1.0</TargetPath>
+ </NativeWithSymbolFile>
+ <NativeWithSymbolFile Include="@(ArchitectureSpecificToolFile)">
+ <TargetPath>tools</TargetPath>
+ </NativeWithSymbolFile>
+ </ItemGroup>
+
+ <ItemGroup Condition="'$(HasCrossTargetComponents)'=='true'">
+ <NativeWithSymbolFile Include="@(CrossArchitectureSpecificNativeFileAndSymbol)">
+ <TargetPath>runtimes/$(CrossTargetComponentFolder)_$(PackagePlatform)/native</TargetPath>
+ </NativeWithSymbolFile>
+ <NativeWithSymbolFile Include="@(CrossArchitectureSpecificToolFile)">
+ <TargetPath>tools/$(CrossTargetComponentFolder)_$(PackagePlatform)</TargetPath>
+ </NativeWithSymbolFile>
+ </ItemGroup>
+
+ <ItemGroup>
+ <File Include="@(NativeWithSymbolFile)" />
+ <File Include="@(LongNameFile)">
+ <IsSymbolFile>true</IsSymbolFile>
+ </File>
+ </ItemGroup>
+
+ <ItemGroup>
+ <!-- On Windows, trim ".dll" before adding ".pdb". -->
+ <WindowsNativeFile Include="@(NativeWithSymbolFile)"
+ Condition="'%(NativeWithSymbolFile.Extension)'=='.dll' OR '%(NativeWithSymbolFile.Extension)'=='.exe'" />
+ <WindowsSymbolFile Include="@(WindowsNativeFile -> '%(RootDir)%(Directory)PDB\%(Filename).pdb')" />
+
+ <!--
+ Search for all xplat symbol file extensions on every xplat native binary. Some binaries have
+ no ".so" or ".dylib" extension, so we can't tell which convention its symbol files would
+ use. On xplat, the symbol extension is simply appended.
+ -->
+ <NonWindowsNativeFile Include="@(NativeWithSymbolFile)"
+ Exclude="@(WindowsNativeFile)" />
+
+ <NonWindowsSymbolFile Include="@(NonWindowsNativeFile -> '%(Identity)$(SymbolFileExtension)')" />
+
+ <ExistingWindowsSymbolFile Include="@(WindowsSymbolFile)" Condition="Exists('%(Identity)')" />
+ <ExistingNonWindowsSymbolFile Include="@(NonWindowsSymbolFile)" Condition="Exists('%(Identity)') AND '$(SkipPackagingXplatSymbols)'!='true'" />
+
+ <!-- Include all found symbols. -->
+ <File Include="@(ExistingWindowsSymbolFile);@(ExistingNonWindowsSymbolFile)">
+ <IsSymbolFile>true</IsSymbolFile>
+ </File>
+ </ItemGroup>
+
+ <PropertyGroup>
+ <NeedsPlaceholderPdb Condition="'@(ExistingNonWindowsSymbolFile)'!='' AND '@(ExistingWindowsSymbolFile)'==''">true</NeedsPlaceholderPdb>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <File Include="$(MSBuildThisFileDirectory)\_.pdb"
+ Condition="'$(NeedsPlaceholderPdb)'=='true' AND '$(PackageTargetRuntime)'!=''">
+ <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+ <IsSymbolFile>true</IsSymbolFile>
+ </File>
+ </ItemGroup>
+ </Target>
+
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)\.., dir.targets))\dir.targets" />
+</Project>
diff --git a/src/.nuget/dir.traversal.targets b/src/.nuget/dir.traversal.targets
new file mode 100644
index 0000000000..686ae749a7
--- /dev/null
+++ b/src/.nuget/dir.traversal.targets
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <Import Project="$(MSBuildThisFileDirectory)..\..\dir.traversal.targets" />
+
+ <Target Name="FilterProjects" BeforeTargets="Build">
+ <Error Condition="'$(PackageRID)' == ''" Text="'PackageRID' property must be specified."/>
+
+ <!-- Only build packages for current RID or non-RID-specific -->
+ <ItemGroup>
+ <_projectsToBuild Include="@(Project)" Condition="'%(Project.PackageTargetRuntime)' == '$(PackageRID)' OR '%(Project.PackageTargetRuntime)' == ''" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Project Remove="@(Project)" />
+ <Project Include="@(_projectsToBuild)" />
+ </ItemGroup>
+ </Target>
+</Project> \ No newline at end of file
diff --git a/src/.nuget/init/project.json b/src/.nuget/init/project.json
index 5440fde0de..5908fcc3f9 100644
--- a/src/.nuget/init/project.json
+++ b/src/.nuget/init/project.json
@@ -1,6 +1,6 @@
{
"dependencies": {
- "Microsoft.NETCore.Platforms": "1.0.2-beta-24224-02",
+ "Microsoft.NETCore.Platforms": "1.0.2-beta-24224-02"
},
"frameworks": {
"dnxcore50": {
diff --git a/src/.nuget/packageIndex.json b/src/.nuget/packageIndex.json
new file mode 100644
index 0000000000..7a73a41bfd
--- /dev/null
+++ b/src/.nuget/packageIndex.json
@@ -0,0 +1,2 @@
+{
+} \ No newline at end of file
diff --git a/src/.nuget/packages.builds b/src/.nuget/packages.builds
index 5d1d025100..f57b9a9b50 100644
--- a/src/.nuget/packages.builds
+++ b/src/.nuget/packages.builds
@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <Import Project="$(MSBuildThisFileDirectory)..\..\dir.props" />
<PropertyGroup>
<!-- This property must be set to the same value as $(PackageOutputPath) for the nuspecs and nupkgs to be binplaced to the intended location. -->
@@ -8,23 +7,23 @@
</PropertyGroup>
<ItemGroup Condition="'$(__SkipCoreLibBuild)'==''">
- <Project Include="Microsoft.NETCore.Runtime.CoreCLR\Microsoft.NETCore.Runtime.CoreCLR.builds" />
+ <Project Include="Microsoft.NETCore.Runtime.CoreCLR\Microsoft.NETCore.Runtime.CoreCLR.builds" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsWindows)'=='true'">
- <Project Include="Microsoft.TargetingPack.Private.CoreCLR\Microsoft.TargetingPack.Private.CoreCLR.pkgproj" />
+ <Project Include="Microsoft.TargetingPack.Private.CoreCLR\Microsoft.TargetingPack.Private.CoreCLR.pkgproj" />
</ItemGroup>
<ItemGroup Condition="'$(__SkipNativeBuild)'==''">
- <Project Include="Microsoft.NETCore.Jit\Microsoft.NETCore.Jit.builds" />
- <Project Include="Microsoft.NETCore.TestHost\Microsoft.NETCore.TestHost.builds" />
- <Project Include="Microsoft.NETCore.Native\Microsoft.NETCore.Native.builds" />
+ <Project Include="Microsoft.NETCore.Jit\Microsoft.NETCore.Jit.builds" />
+ <Project Include="Microsoft.NETCore.TestHost\Microsoft.NETCore.TestHost.builds" />
+ <Project Include="Microsoft.NETCore.Native\Microsoft.NETCore.Native.builds" />
</ItemGroup>
<ItemGroup>
- <Project Include="Microsoft.NETCore.ILAsm\Microsoft.NETCore.ILAsm.builds" />
- <Project Include="Microsoft.NETCore.ILDAsm\Microsoft.NETCore.ILDAsm.builds" />
+ <Project Include="Microsoft.NETCore.ILAsm\Microsoft.NETCore.ILAsm.builds" />
+ <Project Include="Microsoft.NETCore.ILDAsm\Microsoft.NETCore.ILDAsm.builds" />
</ItemGroup>
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
+ <Import Project="$(MSBuildThisFileDirectory)..\..\dir.traversal.targets" />
</Project>
diff --git a/src/ToolBox/PdbTypeMatch/PdbTypeMatch.cpp b/src/ToolBox/PdbTypeMatch/PdbTypeMatch.cpp
deleted file mode 100644
index 052e9e0d1d..0000000000
--- a/src/ToolBox/PdbTypeMatch/PdbTypeMatch.cpp
+++ /dev/null
@@ -1,2023 +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 "stdafx.h"
-#include "PdbTypeMatch.h"
-#include "PrintSymbol.h"
-
-#include "Callback.h"
-
-#include <fstream>
-#include <iostream>
-#include <sstream>
-#include <sys/stat.h>
-#include <algorithm>
-#include "Shlwapi.h"
-
-#define DEBUG_VERBOSE 0
-
-#pragma warning (disable : 4100)
-
-const wchar_t *g_szFilename1, *g_szFilename2;
-IDiaDataSource *g_pDiaDataSource1, *g_pDiaDataSource2;
-IDiaSession *g_pDiaSession1, *g_pDiaSession2;
-IDiaSymbol *g_pGlobalSymbol1, *g_pGlobalSymbol2;
-DWORD g_dwMachineType = CV_CFL_80386;
-IDiaSymbolSet g_excludedTypes;
-IDiaSymbolSet g_excludedTypePatterns;
-
-////////////////////////////////////////////////////////////
-//
-int __cdecl wmain(int argc, wchar_t *argv[])
-{
- FILE *pFile;
-
- if (argc < 3) {
- PrintHelpOptions();
- return -1;
- }
-
- if (!_wcsicmp(argv[1], L"-type")) {
-
- // -type <symbolname> <pdbfilename>: dump this type in detail
-
- if (argc < 4) {
- PrintHelpOptions();
- return -1;
- }
-
- if ((argc > 1) && (*argv[2] != L'-')) {
-
- if (_wfopen_s(&pFile, argv[3], L"r") || !pFile) {
- // invalid file name or file does not exist
-
- PrintHelpOptions();
- return -1;
- }
- fclose(pFile);
- // CoCreate() and initialize COM objects
- if (!InitDiaSource(&g_pDiaDataSource1))
- {
- return -1;
- }
- if (!LoadDataFromPdb(argv[3], g_pDiaDataSource1, &g_pDiaSession1, &g_pGlobalSymbol1)) {
- return -1;
- }
-
- DumpType(g_pGlobalSymbol1, argv[2]);
-
- // release COM objects and CoUninitialize()
- Cleanup();
-
- return 0;
- }
- }
-
- if (argc < 3) {
- PrintHelpOptions();
- return -1;
- }
-
- if (_wfopen_s(&pFile, argv[1], L"r") || !pFile) {
- // invalid file name or file does not exist
-
- PrintHelpOptions();
- return -1;
- }
-
- fclose(pFile);
-
- if (_wfopen_s(&pFile, argv[2], L"r") || !pFile) {
- // invalid file name or file does not exist
-
- PrintHelpOptions();
- return -1;
- }
-
- fclose(pFile);
-
- g_szFilename1 = argv[1];
-
- // CoCreate() and initialize COM objects
- if (!InitDiaSource(&g_pDiaDataSource1))
- {
- return -1;
- }
- if (!LoadDataFromPdb(g_szFilename1, g_pDiaDataSource1, &g_pDiaSession1, &g_pGlobalSymbol1)) {
- return -1;
- }
-
- g_szFilename2 = argv[2];
-
- InitDiaSource(&g_pDiaDataSource2);
- if (!LoadDataFromPdb(g_szFilename2, g_pDiaDataSource2, &g_pDiaSession2, &g_pGlobalSymbol2)) {
- return -1;
- }
-
- // Read exclusion list.
- struct stat fileStatus;
- if (stat(UnicodeToAnsi(argv[3]), &fileStatus) != 0)
- {
- wprintf(L"Could not open type_exclusion_list file!\n");
- return -1;
- }
-
- char linec[2048];
- FILE *file = fopen(UnicodeToAnsi(argv[3]), "r");
- while (fgets (linec, sizeof(linec), file) != NULL)
- {
- std::string line(linec);
- line.erase(std::remove_if(line.begin(), line.end(), isspace), line.end());
- if (line.empty() || line.length() <= 1)
- {
- continue;
- }
- if (line.front() == '#') continue;
- int len;
- int slength = (int)line.length() + 1;
- len = MultiByteToWideChar(CP_ACP, 0, line.c_str(), slength, 0, 0);
- wchar_t* buf = new wchar_t[len];
- MultiByteToWideChar(CP_ACP, 0, line.c_str(), slength, buf, len);
- std::wstring wLine(buf);
- delete[] buf;
-
- /// Add *str in the patterns list.
- if (line.front() == '*')
- {
- g_excludedTypePatterns.insert((std::wstring)(wLine.substr(1, wLine.size()-1)));
- }
- else
- {
- g_excludedTypes.insert((std::wstring)(wLine));
- }
- }
- fclose(file);
-
- IDiaSymbolSet types1;
- IDiaSymbolSet types2;
- if (!EnumTypesInPdb(&types1, g_pDiaSession1, g_pGlobalSymbol1))
- {
- return -1;
- }
-
- if (!EnumTypesInPdb(&types2, g_pDiaSession2, g_pGlobalSymbol2))
- {
- return -1;
- }
-
- IDiaSymbolSet commonTypes;
-
- // Intersect types
- for (IDiaSymbolSet::iterator i = types1.begin(); i != types1.end(); i++)
- {
- std::wstring typeName = *i;
-
- /// Skip excluded types
- if (g_excludedTypes.find(typeName) != g_excludedTypes.end())
- {
- continue;
- }
- bool skipType = false;
- /// Skip if includes one pattern string.
- for (IDiaSymbolSet::iterator j = g_excludedTypePatterns.begin(); j != g_excludedTypePatterns.end(); j++)
- {
- std::wstring patternStr = *j;
- if (wcsstr(typeName.c_str(), patternStr.c_str()) != NULL)
- {
- skipType = true;
- break;
- }
- }
-
- if (skipType) continue;
-
- if (types2.find(typeName) != types2.end())
- {
- commonTypes.insert(typeName);
- }
- }
-
- bool matchedSymbols = true;
- ULONG failuresNb = 0;
-
-
- // Compare layout for common types
- for (IDiaSymbolSet::iterator i = commonTypes.begin(); i != commonTypes.end(); i++)
- {
- std::wstring typeName = *i;
-
- IDiaEnumSymbols *pEnumSymbols1;
- BSTR pwstrTypeName = SysAllocString(typeName.c_str());
- if (FAILED(g_pGlobalSymbol1->findChildren(SymTagUDT, pwstrTypeName, nsNone, &pEnumSymbols1))) {
- SysFreeString(pwstrTypeName);
- return false;
- }
-
- IDiaEnumSymbols *pEnumSymbols2;
- if (FAILED(g_pGlobalSymbol2->findChildren(SymTagUDT, pwstrTypeName, nsNone, &pEnumSymbols2))) {
- SysFreeString(pwstrTypeName);
- return false;
- }
-
- IDiaSymbol *pSymbol1;
- IDiaSymbol *pSymbol2;
- ULONG celt = 0;
-
-
- while (SUCCEEDED(pEnumSymbols1->Next(1, &pSymbol1, &celt)) && (celt == 1)) {
- if (SUCCEEDED(pEnumSymbols2->Next(1, &pSymbol2, &celt)) && (celt == 1))
- {
-
- BSTR bstrSymbol1Name;
- if (pSymbol1->get_name(&bstrSymbol1Name) != S_OK)
- {
- bstrSymbol1Name = NULL;
- pSymbol2->Release();
- continue;
- }
- BSTR bstrSymbol2Name;
- if (pSymbol2->get_name(&bstrSymbol2Name) != S_OK)
- {
- bstrSymbol2Name = NULL;
- pSymbol2->Release();
- continue;
- }
- if (_wcsicmp(bstrSymbol1Name, bstrSymbol2Name) != 0)
- {
- pSymbol2->Release();
- continue;
- }
- ULONGLONG sym1Size;
- ULONGLONG sym2Size;
- if (pSymbol1->get_length(&sym1Size) != S_OK)
- {
- wprintf(L"ERROR - can't retrieve the symbol's length\n");
- pSymbol2->Release();
- continue;
- }
- //wprintf(L"sym1Size = %x\n", sym1Size);
- if (pSymbol2->get_length(&sym2Size) != S_OK)
- {
- wprintf(L"ERROR - can't retrieve the symbol's length\n");
- pSymbol2->Release();
- continue;
- }
- //wprintf(L"sym2Size = %x\n", sym2Size);
- if (sym1Size == 0 || sym2Size == 2)
- {
- pSymbol2->Release();
- continue;
- }
-
- if (!LayoutMatches(pSymbol1, pSymbol2))
- {
- wprintf(L"Type \"%s\" is not matching in %s and %s\n", pwstrTypeName, g_szFilename1, g_szFilename2);
- pSymbol2->Release();
-
- matchedSymbols = false;
- failuresNb++;
- // Continue to compare and report all inconsistencies.
- continue;
- }
- else
- {
-#if DEBUG_VERBOSE
- wprintf(L"Matched type: %s\n", pwstrTypeName);
-#endif
- }
-
- pSymbol2->Release();
- }
-
- pSymbol1->Release();
- }
-
- SysFreeString(pwstrTypeName);
- pEnumSymbols1->Release();
- pEnumSymbols2->Release();
- }
-
- // release COM objects and CoUninitialize()
- Cleanup();
-
- if (matchedSymbols)
- {
- wprintf(L"OK: All %d common types of %s and %s match!\n", commonTypes.size(), g_szFilename1, g_szFilename2);
- return 0;
- }
- else
- {
- wprintf(L"FAIL: Failed to match %d common types of %s and %s!\n", failuresNb, g_szFilename1, g_szFilename2);
- wprintf(L"Matched %d common types!\n", commonTypes.size() - failuresNb);
- return -1;
- }
-}
-
-LPSTR UnicodeToAnsi(LPCWSTR s)
-{
- if (s==NULL) return NULL;
- int cw=lstrlenW(s);
- if (cw==0)
- {
- CHAR *psz=new CHAR[1];*psz='\0';return psz;
- }
- int cc=WideCharToMultiByte(CP_ACP,0,s,cw,NULL,0,NULL,NULL);
- if (cc==0) return NULL;
- CHAR *psz=new CHAR[cc+1];
- cc=WideCharToMultiByte(CP_ACP,0,s,cw,psz,cc,NULL,NULL);
- if (cc==0) {delete[] psz;return NULL;}
- psz[cc]='\0';
- return psz;
-}
-
-
-bool InitDiaSource(IDiaDataSource **ppSource)
-{
- HRESULT hr = CoInitialize(NULL);
-
- // Obtain access to the provider
-
- hr = CoCreateInstance(__uuidof(DiaSource),
- NULL,
- CLSCTX_INPROC_SERVER,
- __uuidof(IDiaDataSource),
- (void **) ppSource);
-
- if (FAILED(hr)) {
- ACTCTX actCtx;
- memset((void*)&actCtx, 0, sizeof(ACTCTX));
- actCtx.cbSize = sizeof(ACTCTX);
- CHAR dllPath[MAX_PATH*2];
- GetModuleFileName(NULL, dllPath, _countof(dllPath));
- PathRemoveFileSpec(dllPath);
- strcat(dllPath, "\\msdia100.sxs.manifest");
- actCtx.lpSource = dllPath;
-
- HANDLE hCtx = ::CreateActCtx(&actCtx);
- if (hCtx == INVALID_HANDLE_VALUE)
- wprintf(L"CreateActCtx returned: INVALID_HANDLE_VALUE\n");
- else
- {
- ULONG_PTR cookie;
- if (::ActivateActCtx(hCtx, &cookie))
- {
- hr = CoCreateInstance(__uuidof(DiaSource),
- NULL,
- CLSCTX_INPROC_SERVER,
- __uuidof(IDiaDataSource),
- (void **) ppSource);
- ::DeactivateActCtx(0, cookie);
- if (FAILED(hr)) {
- wprintf(L"CoCreateInstance failed - HRESULT = %08X\n", hr);
- return false;
- }
- }
- }
- }
- if (FAILED(hr)) {
- wprintf(L"CoCreateInstance failed - HRESULT = %08X\n", hr);
-
- return false;
- }
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Create an IDiaData source and open a PDB file
-//
-bool LoadDataFromPdb(
- const wchar_t *szFilename,
- IDiaDataSource *ppSource,
- IDiaSession **ppSession,
- IDiaSymbol **ppGlobal)
-{
- wchar_t wszExt[MAX_PATH];
- wchar_t *wszSearchPath = L"SRV**\\\\symbols\\symbols"; // Alternate path to search for debug data
- DWORD dwMachType = 0;
- HRESULT hr;
-
- _wsplitpath_s(szFilename, NULL, 0, NULL, 0, NULL, 0, wszExt, MAX_PATH);
-
- if (!_wcsicmp(wszExt, L".pdb")) {
- // Open and prepare a program database (.pdb) file as a debug data source
-
- hr = (ppSource)->loadDataFromPdb(szFilename);
-
- if (FAILED(hr)) {
- wprintf(L"loadDataFromPdb failed - HRESULT = %08X\n", hr);
-
- return false;
- }
- }
-
- else {
- CCallback callback; // Receives callbacks from the DIA symbol locating procedure,
- // thus enabling a user interface to report on the progress of
- // the location attempt. The client application may optionally
- // provide a reference to its own implementation of this
- // virtual base class to the IDiaDataSource::loadDataForExe method.
- callback.AddRef();
-
- // Open and prepare the debug data associated with the executable
-
- hr = (ppSource)->loadDataForExe(szFilename, wszSearchPath, &callback);
-
- if (FAILED(hr)) {
- wprintf(L"loadDataForExe failed - HRESULT = %08X\n", hr);
-
- return false;
- }
- }
-
- // Open a session for querying symbols
-
- hr = (ppSource)->openSession(ppSession);
-
- if (FAILED(hr)) {
- wprintf(L"openSession failed - HRESULT = %08X\n", hr);
-
- return false;
- }
-
- // Retrieve a reference to the global scope
-
- hr = (*ppSession)->get_globalScope(ppGlobal);
-
- if (hr != S_OK) {
- wprintf(L"get_globalScope failed\n");
-
- return false;
- }
-
- // Set Machine type for getting correct register names
-
- if ((*ppGlobal)->get_machineType(&dwMachType) == S_OK) {
- switch (dwMachType) {
- case IMAGE_FILE_MACHINE_I386 : g_dwMachineType = CV_CFL_80386; break;
- case IMAGE_FILE_MACHINE_IA64 : g_dwMachineType = CV_CFL_IA64; break;
- case IMAGE_FILE_MACHINE_AMD64 : g_dwMachineType = CV_CFL_AMD64; break;
- case IMAGE_FILE_MACHINE_ARMNT : g_dwMachineType = CV_CFL_ARM7; break;
- }
- }
-
- return true;
-}
-
-bool LayoutMatches(IDiaSymbol* pSymbol1, IDiaSymbol* pSymbol2)
-{
- DWORD dwTag1, dwTag2;
- DWORD dwLocType1, dwLocType2;
- LONG lOffset1, lOffset2;
-
- if (pSymbol1->get_symTag(&dwTag1) != S_OK)
- {
- wprintf(L"ERROR - can't retrieve the symbol's SymTag\n");
- return false;
- }
- if (pSymbol2->get_symTag(&dwTag2) != S_OK)
- {
- wprintf(L"ERROR - can't retrieve the symbol's SymTag\n");
- return false;
- }
-
- if (dwTag1 == SymTagUDT)
- {
- if (dwTag2 != SymTagUDT)
- {
-
- wprintf(L"ERROR - symbols don't match\n");
- wprintf(L"Symbol 1:\n");
- PrintTypeInDetail(pSymbol1, 0);
- wprintf(L"Symbol 2:\n");
- PrintTypeInDetail(pSymbol2, 0);
- return false;
- }
-
- // First check that types size match
- ULONGLONG sym1Size;
- ULONGLONG sym2Size;
- if (pSymbol1->get_length(&sym1Size) != S_OK)
- {
- wprintf(L"ERROR - can't retrieve the symbol's length\n");
- return false;
- }
- if (pSymbol2->get_length(&sym2Size) != S_OK)
- {
- wprintf(L"ERROR - can't retrieve the symbol's length\n");
- return false;
- }
- if (sym1Size == 0 || sym2Size == 0)
- {
- return true;
- }
- if (sym1Size != sym2Size)
- {
- wprintf(L"Failed to match type size: (sizeof(sym1)=%x) != (sizeof(sym2)=%x)\n", sym1Size, sym2Size);
- return false;
- }
- IDiaEnumSymbols *pEnumChildren1, *pEnumChildren2;
- IDiaSymbol *pChild1, *pChild2;
- ULONG celt = 0;
- BSTR bstrName1, bstrName2;
- if (SUCCEEDED(pSymbol1->findChildren(SymTagNull, NULL, nsNone, &pEnumChildren1)))
- {
- while (SUCCEEDED(pEnumChildren1->Next(1, &pChild1, &celt)) && (celt == 1))
- {
- if (pChild1->get_symTag(&dwTag1) != S_OK)
- {
- wprintf(L"ERROR - can't retrieve the symbol's SymTag\n");
- pChild1->Release();
- return false;
- }
- if (dwTag1 != SymTagData) { pChild1->Release(); continue; }
- if (pChild1->get_locationType(&dwLocType1) != S_OK)
- {
- wprintf(L"symbol in optmized code");
- pChild1->Release();
- return false;
- }
- if (dwLocType1 != LocIsThisRel) { pChild1->Release(); continue; }
- if (pChild1->get_offset(&lOffset1) != S_OK)
- {
- wprintf(L"ERROR - geting field offset\n");
- pChild1->Release();
- return false;
- }
- if (pChild1->get_name(&bstrName1) != S_OK)
- {
- bstrName1 = NULL;
- }
- /// Search in the second symbol the field at lOffset1
- bool fieldMatched = false;
- if (SUCCEEDED(pSymbol2->findChildren(SymTagNull, NULL, nsNone, &pEnumChildren2)))
- {
- while (SUCCEEDED(pEnumChildren2->Next(1, &pChild2, &celt)) && (celt == 1))
- {
- if (pChild2->get_symTag(&dwTag2) != S_OK)
- {
- wprintf(L"ERROR - can't retrieve the symbol's SymTag\n");
- pChild2->Release();
- return false;
- }
- if (dwTag2 != SymTagData) { pChild2->Release(); continue; }
- if (pChild2->get_locationType(&dwLocType2) != S_OK)
- {
- wprintf(L"symbol in optmized code");
- pChild2->Release();
- return false;
- }
- if (dwLocType2 != LocIsThisRel) { pChild2->Release(); continue; }
- if (pChild2->get_offset(&lOffset2) != S_OK)
- {
- wprintf(L"ERROR - geting field offset\n");
- pChild2->Release();
- return false;
- }
- if (pChild2->get_name(&bstrName2) != S_OK)
- {
- bstrName2 = NULL;
- }
- if (lOffset2 == lOffset1)
- {
- if (_wcsicmp(bstrName1, bstrName2) == 0
- || wcsstr(bstrName1, bstrName2) == bstrName1
- || wcsstr(bstrName2, bstrName1) == bstrName2)
- {
- //wprintf(L"Matched field %s at offset %x\n", bstrName1, lOffset2);
- fieldMatched = true;
- pChild2->Release();
- break;
- }
- }
- pChild2->Release();
- }
- pEnumChildren2->Release();
- }
- if (!fieldMatched)
- {
- BSTR bstrSymbol1Name;
- if (pSymbol1->get_name(&bstrSymbol1Name) != S_OK)
- {
- bstrSymbol1Name = NULL;
- }
- wprintf(L"Failed to match %s field %s at offset %x\n", bstrSymbol1Name, bstrName1, lOffset1);
- pChild1->Release();
- return false;
- }
- pChild1->Release();
- }
-
- pEnumChildren1->Release();
- }
- }
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Release DIA objects and CoUninitialize
-//
-void Cleanup()
-{
- if (g_pGlobalSymbol1) {
- g_pGlobalSymbol1->Release();
- g_pGlobalSymbol1 = NULL;
- }
-
- if (g_pGlobalSymbol2) {
- g_pGlobalSymbol2->Release();
- g_pGlobalSymbol2 = NULL;
- }
-
- if (g_pDiaSession1) {
- g_pDiaSession1->Release();
- g_pDiaSession1 = NULL;
- }
-
- if (g_pDiaSession2) {
- g_pDiaSession2->Release();
- g_pDiaSession2 = NULL;
- }
-
- CoUninitialize();
-}
-
-
-////////////////////////////////////////////////////////////
-// Display the usage
-//
-void PrintHelpOptions()
-{
- static const wchar_t * const helpString = L"usage: PdbTypeMatch.exe <pdb_filename_1> <pdb_filename_2> <type_exclusion_list_file> : compare all common types by size and fields\n"
- L" PdbTypeMatch.exe -type <symbolname> <pdb_filename_1>: dump this type in detail\n";
-
- wprintf(helpString);
-}
-
-bool EnumTypesInPdb(IDiaSymbolSet* types, IDiaSession *pSession, IDiaSymbol *pGlobal)
-{
- IDiaEnumSymbols *pEnumSymbols;
-
- if (FAILED(pGlobal->findChildren(SymTagUDT, NULL, nsNone, &pEnumSymbols)))
- {
- wprintf(L"ERROR - EnumTypesInPdb() returned no symbols\n");
-
- return false;
- }
-
- IDiaSymbol *pSymbol;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1))
- {
- std::wstring typeName;
- GetSymbolName(typeName, pSymbol);
- types->insert(std::wstring(typeName));
- pSymbol->Release();
- }
-
- pEnumSymbols->Release();
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the data stored in a PDB
-//
-void DumpAllPdbInfo(IDiaSession *pSession, IDiaSymbol *pGlobal)
-{
- DumpAllMods(pGlobal);
- DumpAllPublics(pGlobal);
- DumpAllSymbols(pGlobal);
- DumpAllGlobals(pGlobal);
- DumpAllTypes(pGlobal);
- DumpAllFiles(pSession, pGlobal);
- DumpAllLines(pSession, pGlobal);
- DumpAllSecContribs(pSession);
- DumpAllDebugStreams(pSession);
- DumpAllInjectedSources(pSession);
- DumpAllFPO(pSession);
- DumpAllOEMs(pGlobal);
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the modules information
-//
-bool DumpAllMods(IDiaSymbol *pGlobal)
-{
- wprintf(L"\n\n*** MODULES\n\n");
-
- // Retrieve all the compiland symbols
-
- IDiaEnumSymbols *pEnumSymbols;
-
- if (FAILED(pGlobal->findChildren(SymTagCompiland, NULL, nsNone, &pEnumSymbols))) {
- return false;
- }
-
- IDiaSymbol *pCompiland;
- ULONG celt = 0;
- ULONG iMod = 1;
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pCompiland, &celt)) && (celt == 1)) {
- BSTR bstrName;
-
- if (pCompiland->get_name(&bstrName) != S_OK) {
- wprintf(L"ERROR - Failed to get the compiland's name\n");
-
- pCompiland->Release();
- pEnumSymbols->Release();
-
- return false;
- }
-
- wprintf(L"%04X %s\n", iMod++, bstrName);
-
- // Deallocate the string allocated previously by the call to get_name
-
- SysFreeString(bstrName);
-
- pCompiland->Release();
- }
-
- pEnumSymbols->Release();
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the public symbols - SymTagPublicSymbol
-//
-bool DumpAllPublics(IDiaSymbol *pGlobal)
-{
- wprintf(L"\n\n*** PUBLICS\n\n");
-
- // Retrieve all the public symbols
-
- IDiaEnumSymbols *pEnumSymbols;
-
- if (FAILED(pGlobal->findChildren(SymTagPublicSymbol, NULL, nsNone, &pEnumSymbols))) {
- return false;
- }
-
- IDiaSymbol *pSymbol;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
- PrintPublicSymbol(pSymbol);
-
- pSymbol->Release();
- }
-
- pEnumSymbols->Release();
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the symbol information stored in the compilands
-//
-bool DumpAllSymbols(IDiaSymbol *pGlobal)
-{
- wprintf(L"\n\n*** SYMBOLS\n\n\n");
-
- // Retrieve the compilands first
-
- IDiaEnumSymbols *pEnumSymbols;
-
- if (FAILED(pGlobal->findChildren(SymTagCompiland, NULL, nsNone, &pEnumSymbols))) {
- return false;
- }
-
- IDiaSymbol *pCompiland;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pCompiland, &celt)) && (celt == 1)) {
- wprintf(L"\n** Module: ");
-
- // Retrieve the name of the module
-
- BSTR bstrName;
-
- if (pCompiland->get_name(&bstrName) != S_OK) {
- wprintf(L"(???)\n\n");
- }
-
- else {
- wprintf(L"%s\n\n", bstrName);
-
- SysFreeString(bstrName);
- }
-
- // Find all the symbols defined in this compiland and print their info
-
- IDiaEnumSymbols *pEnumChildren;
-
- if (SUCCEEDED(pCompiland->findChildren(SymTagNull, NULL, nsNone, &pEnumChildren))) {
- IDiaSymbol *pSymbol;
- ULONG celtChildren = 0;
-
- while (SUCCEEDED(pEnumChildren->Next(1, &pSymbol, &celtChildren)) && (celtChildren == 1)) {
- PrintSymbol(pSymbol, 0);
- pSymbol->Release();
- }
-
- pEnumChildren->Release();
- }
-
- pCompiland->Release();
- }
-
- pEnumSymbols->Release();
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the global symbols - SymTagFunction,
-// SymTagThunk and SymTagData
-//
-bool DumpAllGlobals(IDiaSymbol *pGlobal)
-{
- IDiaEnumSymbols *pEnumSymbols;
- IDiaSymbol *pSymbol;
- enum SymTagEnum dwSymTags[] = { SymTagFunction, SymTagThunk, SymTagData };
- ULONG celt = 0;
-
- wprintf(L"\n\n*** GLOBALS\n\n");
-
- for (size_t i = 0; i < _countof(dwSymTags); i++, pEnumSymbols = NULL) {
- if (SUCCEEDED(pGlobal->findChildren(dwSymTags[i], NULL, nsNone, &pEnumSymbols))) {
- while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
- PrintGlobalSymbol(pSymbol);
-
- pSymbol->Release();
- }
-
- pEnumSymbols->Release();
- }
-
- else {
- wprintf(L"ERROR - DumpAllGlobals() returned no symbols\n");
-
- return false;
- }
- }
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the types information
-// (type symbols can be UDTs, enums or typedefs)
-//
-bool DumpAllTypes(IDiaSymbol *pGlobal)
-{
- wprintf(L"\n\n*** TYPES\n");
-
- return DumpAllUDTs(pGlobal) || DumpAllEnums(pGlobal) || DumpAllTypedefs(pGlobal);
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the user defined types (UDT)
-//
-bool DumpAllUDTs(IDiaSymbol *pGlobal)
-{
- wprintf(L"\n\n** User Defined Types\n\n");
-
- IDiaEnumSymbols *pEnumSymbols;
-
- if (FAILED(pGlobal->findChildren(SymTagUDT, NULL, nsNone, &pEnumSymbols))) {
- wprintf(L"ERROR - DumpAllUDTs() returned no symbols\n");
-
- return false;
- }
-
- IDiaSymbol *pSymbol;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
- PrintTypeInDetail(pSymbol, 0);
-
- pSymbol->Release();
- }
-
- pEnumSymbols->Release();
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the enum types from the pdb
-//
-bool DumpAllEnums(IDiaSymbol *pGlobal)
-{
- wprintf(L"\n\n** ENUMS\n\n");
-
- IDiaEnumSymbols *pEnumSymbols;
-
- if (FAILED(pGlobal->findChildren(SymTagEnum, NULL, nsNone, &pEnumSymbols))) {
- wprintf(L"ERROR - DumpAllEnums() returned no symbols\n");
-
- return false;
- }
-
- IDiaSymbol *pSymbol;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
- PrintTypeInDetail(pSymbol, 0);
-
- pSymbol->Release();
- }
-
- pEnumSymbols->Release();
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the typedef types from the pdb
-//
-bool DumpAllTypedefs(IDiaSymbol *pGlobal)
-{
- wprintf(L"\n\n** TYPEDEFS\n\n");
-
- IDiaEnumSymbols *pEnumSymbols;
-
- if (FAILED(pGlobal->findChildren(SymTagTypedef, NULL, nsNone, &pEnumSymbols))) {
- wprintf(L"ERROR - DumpAllTypedefs() returned no symbols\n");
-
- return false;
- }
-
- IDiaSymbol *pSymbol;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
- PrintTypeInDetail(pSymbol, 0);
-
- pSymbol->Release();
- }
-
- pEnumSymbols->Release();
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump OEM specific types
-//
-bool DumpAllOEMs(IDiaSymbol *pGlobal)
-{
- wprintf(L"\n\n*** OEM Specific types\n\n");
-
- IDiaEnumSymbols *pEnumSymbols;
-
- if (FAILED(pGlobal->findChildren(SymTagCustomType, NULL, nsNone, &pEnumSymbols))) {
- wprintf(L"ERROR - DumpAllOEMs() returned no symbols\n");
-
- return false;
- }
-
- IDiaSymbol *pSymbol;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
- PrintTypeInDetail(pSymbol, 0);
-
- pSymbol->Release();
- }
-
- pEnumSymbols->Release();
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// For each compiland in the PDB dump all the source files
-//
-bool DumpAllFiles(IDiaSession *pSession, IDiaSymbol *pGlobal)
-{
- wprintf(L"\n\n*** FILES\n\n");
-
- // In order to find the source files, we have to look at the image's compilands/modules
-
- IDiaEnumSymbols *pEnumSymbols;
-
- if (FAILED(pGlobal->findChildren(SymTagCompiland, NULL, nsNone, &pEnumSymbols))) {
- return false;
- }
-
- IDiaSymbol *pCompiland;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pCompiland, &celt)) && (celt == 1)) {
- BSTR bstrName;
-
- if (pCompiland->get_name(&bstrName) == S_OK) {
- wprintf(L"\nCompiland = %s\n\n", bstrName);
-
- SysFreeString(bstrName);
- }
-
- // Every compiland could contain multiple references to the source files which were used to build it
- // Retrieve all source files by compiland by passing NULL for the name of the source file
-
- IDiaEnumSourceFiles *pEnumSourceFiles;
-
- if (SUCCEEDED(pSession->findFile(pCompiland, NULL, nsNone, &pEnumSourceFiles))) {
- IDiaSourceFile *pSourceFile;
-
- while (SUCCEEDED(pEnumSourceFiles->Next(1, &pSourceFile, &celt)) && (celt == 1)) {
- PrintSourceFile(pSourceFile);
- putwchar(L'\n');
-
- pSourceFile->Release();
- }
-
- pEnumSourceFiles->Release();
- }
-
- putwchar(L'\n');
-
- pCompiland->Release();
- }
-
- pEnumSymbols->Release();
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the line numbering information contained in the PDB
-// Only function symbols have corresponding line numbering information
-bool DumpAllLines(IDiaSession *pSession, IDiaSymbol *pGlobal)
-{
- wprintf(L"\n\n*** LINES\n\n");
-
- // First retrieve the compilands/modules
-
- IDiaEnumSymbols *pEnumSymbols;
-
- if (FAILED(pGlobal->findChildren(SymTagCompiland, NULL, nsNone, &pEnumSymbols))) {
- return false;
- }
-
- IDiaSymbol *pCompiland;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pCompiland, &celt)) && (celt == 1)) {
- IDiaEnumSymbols *pEnumFunction;
-
- // For every function symbol defined in the compiland, retrieve and print the line numbering info
-
- if (SUCCEEDED(pCompiland->findChildren(SymTagFunction, NULL, nsNone, &pEnumFunction))) {
- IDiaSymbol *pFunction;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumFunction->Next(1, &pFunction, &celt)) && (celt == 1)) {
- PrintLines(pSession, pFunction);
-
- pFunction->Release();
- }
-
- pEnumFunction->Release();
- }
-
- pCompiland->Release();
- }
-
- pEnumSymbols->Release();
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the line numbering information for a given RVA
-// and a given range
-//
-bool DumpAllLines(IDiaSession *pSession, DWORD dwRVA, DWORD dwRange)
-{
- // Retrieve and print the lines that corresponds to a specified RVA
-
- IDiaEnumLineNumbers *pLines;
-
- if (FAILED(pSession->findLinesByRVA(dwRVA, dwRange, &pLines))) {
- return false;
- }
-
- PrintLines(pLines);
-
- pLines->Release();
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the section contributions from the PDB
-//
-// Section contributions are stored in a table which will
-// be retrieved via IDiaSession->getEnumTables through
-// QueryInterface()using the REFIID of the IDiaEnumSectionContribs
-//
-bool DumpAllSecContribs(IDiaSession *pSession)
-{
- wprintf(L"\n\n*** SECTION CONTRIBUTION\n\n");
-
- IDiaEnumSectionContribs *pEnumSecContribs;
-
- if (FAILED(GetTable(pSession, __uuidof(IDiaEnumSectionContribs), (void **) &pEnumSecContribs))) {
- return false;
- }
-
- wprintf(L" RVA Address Size Module\n");
-
- IDiaSectionContrib *pSecContrib;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSecContribs->Next(1, &pSecContrib, &celt)) && (celt == 1)) {
- PrintSecContribs(pSecContrib);
-
- pSecContrib->Release();
- }
-
- pEnumSecContribs->Release();
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump all debug data streams contained in the PDB
-//
-bool DumpAllDebugStreams(IDiaSession *pSession)
-{
- IDiaEnumDebugStreams *pEnumStreams;
-
- wprintf(L"\n\n*** DEBUG STREAMS\n\n");
-
- // Retrieve an enumerated sequence of debug data streams
-
- if (FAILED(pSession->getEnumDebugStreams(&pEnumStreams))) {
- return false;
- }
-
- IDiaEnumDebugStreamData *pStream;
- ULONG celt = 0;
-
- for (; SUCCEEDED(pEnumStreams->Next(1, &pStream, &celt)) && (celt == 1); pStream = NULL) {
- PrintStreamData(pStream);
-
- pStream->Release();
- }
-
- pEnumStreams->Release();
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the injected source from the PDB
-//
-// Injected sources data is stored in a table which will
-// be retrieved via IDiaSession->getEnumTables through
-// QueryInterface()using the REFIID of the IDiaEnumSectionContribs
-//
-bool DumpAllInjectedSources(IDiaSession *pSession)
-{
- wprintf(L"\n\n*** INJECTED SOURCES TABLE\n\n");
-
- IDiaEnumInjectedSources *pEnumInjSources;
-
- if (SUCCEEDED(GetTable(pSession, __uuidof(IDiaEnumInjectedSources), (void **) &pEnumInjSources))) {
- return false;
- }
-
- IDiaInjectedSource *pInjSource;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumInjSources->Next(1, &pInjSource, &celt)) && (celt == 1)) {
- PrintGeneric(pInjSource);
-
- pInjSource->Release();
- }
-
- pEnumInjSources->Release();
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump info corresponing to a given injected source filename
-//
-bool DumpInjectedSource(IDiaSession *pSession, const wchar_t *szName)
-{
- // Retrieve a source that has been placed into the symbol store by attribute providers or
- // other components of the compilation process
-
- IDiaEnumInjectedSources *pEnumInjSources;
-
- if (FAILED(pSession->findInjectedSource(szName, &pEnumInjSources))) {
- wprintf(L"ERROR - DumpInjectedSources() could not find %s\n", szName);
-
- return false;
- }
-
- IDiaInjectedSource *pInjSource;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumInjSources->Next(1, &pInjSource, &celt)) && (celt == 1)) {
- PrintGeneric(pInjSource);
-
- pInjSource->Release();
- }
-
- pEnumInjSources->Release();
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the source file information stored in the PDB
-// We have to go through every compiland in order to retrieve
-// all the information otherwise checksums for instance
-// will not be available
-// Compilands can have multiple source files with the same
-// name but different content which produces diffrent
-// checksums
-//
-bool DumpAllSourceFiles(IDiaSession *pSession, IDiaSymbol *pGlobal)
-{
- wprintf(L"\n\n*** SOURCE FILES\n\n");
-
- // To get the complete source file info we must go through the compiland first
- // by passing NULL instead all the source file names only will be retrieved
-
- IDiaEnumSymbols *pEnumSymbols;
-
- if (FAILED(pGlobal->findChildren(SymTagCompiland, NULL, nsNone, &pEnumSymbols))) {
- return false;
- }
-
- IDiaSymbol *pCompiland;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pCompiland, &celt)) && (celt == 1)) {
- BSTR bstrName;
-
- if (pCompiland->get_name(&bstrName) == S_OK) {
- wprintf(L"\nCompiland = %s\n\n", bstrName);
-
- SysFreeString(bstrName);
- }
-
- // Every compiland could contain multiple references to the source files which were used to build it
- // Retrieve all source files by compiland by passing NULL for the name of the source file
-
- IDiaEnumSourceFiles *pEnumSourceFiles;
-
- if (SUCCEEDED(pSession->findFile(pCompiland, NULL, nsNone, &pEnumSourceFiles))) {
- IDiaSourceFile *pSourceFile;
-
- while (SUCCEEDED(pEnumSourceFiles->Next(1, &pSourceFile, &celt)) && (celt == 1)) {
- PrintSourceFile(pSourceFile);
- putwchar(L'\n');
-
- pSourceFile->Release();
- }
-
- pEnumSourceFiles->Release();
- }
-
- putwchar(L'\n');
-
- pCompiland->Release();
- }
-
- pEnumSymbols->Release();
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the FPO info
-//
-// FPO data stored in a table which will be retrieved via
-// IDiaSession->getEnumTables through QueryInterface()
-// using the REFIID of the IDiaEnumFrameData
-//
-bool DumpAllFPO(IDiaSession *pSession)
-{
- IDiaEnumFrameData *pEnumFrameData;
-
- wprintf(L"\n\n*** FPO\n\n");
-
- if (FAILED(GetTable(pSession, __uuidof(IDiaEnumFrameData), (void **) &pEnumFrameData))) {
- return false;
- }
-
- IDiaFrameData *pFrameData;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumFrameData->Next(1, &pFrameData, &celt)) && (celt == 1)) {
- PrintFrameData(pFrameData);
-
- pFrameData->Release();
- }
-
- pEnumFrameData->Release();
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump FPO info for a function at the specified RVA
-//
-bool DumpFPO(IDiaSession *pSession, DWORD dwRVA)
-{
- IDiaEnumFrameData *pEnumFrameData;
-
- // Retrieve first the table holding all the FPO info
-
- if ((dwRVA != 0) && SUCCEEDED(GetTable(pSession, __uuidof(IDiaEnumFrameData), (void **) &pEnumFrameData))) {
- IDiaFrameData *pFrameData;
-
- // Retrieve the frame data corresponding to the given RVA
-
- if (SUCCEEDED(pEnumFrameData->frameByRVA(dwRVA, &pFrameData))) {
- PrintGeneric(pFrameData);
-
- pFrameData->Release();
- }
-
- else {
- // Some function might not have FPO data available (see ASM funcs like strcpy)
-
- wprintf(L"ERROR - DumpFPO() frameByRVA invalid RVA: 0x%08X\n", dwRVA);
-
- pEnumFrameData->Release();
-
- return false;
- }
-
- pEnumFrameData->Release();
- }
-
- else {
- wprintf(L"ERROR - DumpFPO() GetTable\n");
-
- return false;
- }
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump FPO info for a specified function symbol using its
-// name (a regular expression string is used for the search)
-//
-bool DumpFPO(IDiaSession *pSession, IDiaSymbol *pGlobal, const wchar_t *szSymbolName)
-{
- IDiaEnumSymbols *pEnumSymbols;
- IDiaSymbol *pSymbol;
- ULONG celt = 0;
- DWORD dwRVA;
-
- // Find first all the function symbols that their names matches the search criteria
-
- if (FAILED(pGlobal->findChildren(SymTagFunction, szSymbolName, nsRegularExpression, &pEnumSymbols))) {
- wprintf(L"ERROR - DumpFPO() findChildren could not find symol %s\n", szSymbolName);
-
- return false;
- }
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
- if (pSymbol->get_relativeVirtualAddress(&dwRVA) == S_OK) {
- PrintPublicSymbol(pSymbol);
-
- DumpFPO(pSession, dwRVA);
- }
-
- pSymbol->Release();
- }
-
- pEnumSymbols->Release();
-
- putwchar(L'\n');
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump a specified compiland and all the symbols defined in it
-//
-bool DumpCompiland(IDiaSymbol *pGlobal, const wchar_t *szCompName)
-{
- IDiaEnumSymbols *pEnumSymbols;
-
- if (FAILED(pGlobal->findChildren(SymTagCompiland, szCompName, nsCaseInsensitive, &pEnumSymbols))) {
- return false;
- }
-
- IDiaSymbol *pCompiland;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pCompiland, &celt)) && (celt == 1)) {
- wprintf(L"\n** Module: ");
-
- // Retrieve the name of the module
-
- BSTR bstrName;
-
- if (pCompiland->get_name(&bstrName) != S_OK) {
- wprintf(L"(???)\n\n");
- }
-
- else {
- wprintf(L"%s\n\n", bstrName);
-
- SysFreeString(bstrName);
- }
-
- IDiaEnumSymbols *pEnumChildren;
-
- if (SUCCEEDED(pCompiland->findChildren(SymTagNull, NULL, nsNone, &pEnumChildren))) {
- IDiaSymbol *pSymbol;
- ULONG celt_ = 0;
-
- while (SUCCEEDED(pEnumChildren->Next(1, &pSymbol, &celt_)) && (celt_ == 1)) {
- PrintSymbol(pSymbol, 0);
-
- pSymbol->Release();
- }
-
- pEnumChildren->Release();
- }
-
- pCompiland->Release();
- }
-
- pEnumSymbols->Release();
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump the line numbering information for a specified RVA
-//
-bool DumpLines(IDiaSession *pSession, DWORD dwRVA)
-{
- IDiaEnumLineNumbers *pLines;
-
- if (FAILED(pSession->findLinesByRVA(dwRVA, MAX_RVA_LINES_BYTES_RANGE, &pLines))) {
- return false;
- }
-
- PrintLines(pLines);
-
- pLines->Release();
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump the all line numbering information for a specified
-// function symbol name (as a regular expression string)
-//
-bool DumpLines(IDiaSession *pSession, IDiaSymbol *pGlobal, const wchar_t *szFuncName)
-{
- IDiaEnumSymbols *pEnumSymbols;
-
- if (FAILED(pGlobal->findChildren(SymTagFunction, szFuncName, nsRegularExpression, &pEnumSymbols))) {
- return false;
- }
-
- IDiaSymbol *pFunction;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pFunction, &celt)) && (celt == 1)) {
- PrintLines(pSession, pFunction);
-
- pFunction->Release();
- }
-
- pEnumSymbols->Release();
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump the symbol information corresponding to a specified RVA
-//
-bool DumpSymbolWithRVA(IDiaSession *pSession, DWORD dwRVA, const wchar_t *szChildname)
-{
- IDiaSymbol *pSymbol;
- LONG lDisplacement;
-
- if (FAILED(pSession->findSymbolByRVAEx(dwRVA, SymTagNull, &pSymbol, &lDisplacement))) {
- return false;
- }
-
- wprintf(L"Displacement = 0x%X\n", lDisplacement);
-
- PrintGeneric(pSymbol);
-
- bool bReturn = DumpSymbolWithChildren(pSymbol, szChildname);
-
- while (pSymbol != NULL) {
- IDiaSymbol *pParent;
-
- if ((pSymbol->get_lexicalParent(&pParent) == S_OK) && pParent) {
- wprintf(L"\nParent\n");
-
- PrintSymbol(pParent, 0);
-
- pSymbol->Release();
-
- pSymbol = pParent;
- }
-
- else {
- pSymbol->Release();
- break;
- }
- }
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump the symbols information where their names matches a
-// specified regular expression string
-//
-bool DumpSymbolsWithRegEx(IDiaSymbol *pGlobal, const wchar_t *szRegEx, const wchar_t *szChildname)
-{
- IDiaEnumSymbols *pEnumSymbols;
-
- if (FAILED(pGlobal->findChildren(SymTagNull, szRegEx, nsRegularExpression, &pEnumSymbols))) {
- return false;
- }
-
- bool bReturn = true;
-
- IDiaSymbol *pSymbol;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
- PrintGeneric(pSymbol);
-
- bReturn = DumpSymbolWithChildren(pSymbol, szChildname);
-
- pSymbol->Release();
- }
-
- pEnumSymbols->Release();
-
- return bReturn;
-}
-
-////////////////////////////////////////////////////////////
-// Dump the information corresponding to a symbol name which
-// is a children of the specified parent symbol
-//
-bool DumpSymbolWithChildren(IDiaSymbol *pSymbol, const wchar_t *szChildname)
-{
- if (szChildname != NULL) {
- IDiaEnumSymbols *pEnumSyms;
-
- if (FAILED(pSymbol->findChildren(SymTagNull, szChildname, nsRegularExpression, &pEnumSyms))) {
- return false;
- }
-
- IDiaSymbol *pChild;
- DWORD celt = 1;
-
- while (SUCCEEDED(pEnumSyms->Next(celt, &pChild, &celt)) && (celt == 1)) {
- PrintGeneric(pChild);
- PrintSymbol(pChild, 0);
-
- pChild->Release();
- }
-
- pEnumSyms->Release();
- }
-
- else {
- // If the specified name is NULL then only the parent symbol data is displayed
-
- DWORD dwSymTag;
-
- if ((pSymbol->get_symTag(&dwSymTag) == S_OK) && (dwSymTag == SymTagPublicSymbol)) {
- PrintPublicSymbol(pSymbol);
- }
-
- else {
- PrintSymbol(pSymbol, 0);
- }
- }
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump all the type symbols information that matches their
-// names to a specified regular expression string
-//
-bool DumpType(IDiaSymbol *pGlobal, const wchar_t *szRegEx)
-{
- IDiaEnumSymbols *pEnumSymbols;
-
- if (FAILED(pGlobal->findChildren(SymTagUDT, szRegEx, nsRegularExpression, &pEnumSymbols))) {
- return false;
- }
-
- IDiaSymbol *pSymbol;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSymbols->Next(1, &pSymbol, &celt)) && (celt == 1)) {
- PrintTypeInDetail(pSymbol, 0);
-
- pSymbol->Release();
- }
-
- pEnumSymbols->Release();
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump line numbering information for a given file name and
-// an optional line number
-//
-bool DumpLinesForSourceFile(IDiaSession *pSession, const wchar_t *szFileName, DWORD dwLine)
-{
- IDiaEnumSourceFiles *pEnumSrcFiles;
-
- if (FAILED(pSession->findFile(NULL, szFileName, nsFNameExt, &pEnumSrcFiles))) {
- return false;
- }
-
- IDiaSourceFile *pSrcFile;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumSrcFiles->Next(1, &pSrcFile, &celt)) && (celt == 1)) {
- IDiaEnumSymbols *pEnumCompilands;
-
- if (pSrcFile->get_compilands(&pEnumCompilands) == S_OK) {
- IDiaSymbol *pCompiland;
-
- celt = 0;
- while (SUCCEEDED(pEnumCompilands->Next(1, &pCompiland, &celt)) && (celt == 1)) {
- BSTR bstrName;
-
- if (pCompiland->get_name(&bstrName) == S_OK) {
- wprintf(L"Compiland = %s\n", bstrName);
-
- SysFreeString(bstrName);
- }
-
- else {
- wprintf(L"Compiland = (???)\n");
- }
-
- IDiaEnumLineNumbers *pLines;
-
- if (dwLine != 0) {
- if (SUCCEEDED(pSession->findLinesByLinenum(pCompiland, pSrcFile, dwLine, 0, &pLines))) {
- PrintLines(pLines);
-
- pLines->Release();
- }
- }
-
- else {
- if (SUCCEEDED(pSession->findLines(pCompiland, pSrcFile, &pLines))) {
- PrintLines(pLines);
-
- pLines->Release();
- }
- }
-
- pCompiland->Release();
- }
-
- pEnumCompilands->Release();
- }
-
- pSrcFile->Release();
- }
-
- pEnumSrcFiles->Release();
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump public symbol information for a given number of
-// symbols around a given RVA address
-//
-bool DumpPublicSymbolsSorted(IDiaSession *pSession, DWORD dwRVA, DWORD dwRange, bool bReverse)
-{
- IDiaEnumSymbolsByAddr *pEnumSymsByAddr;
-
- if (FAILED(pSession->getSymbolsByAddr(&pEnumSymsByAddr))) {
- return false;
- }
-
- IDiaSymbol *pSymbol;
-
- if (SUCCEEDED(pEnumSymsByAddr->symbolByRVA(dwRVA, &pSymbol))) {
- if (dwRange == 0) {
- PrintPublicSymbol(pSymbol);
- }
-
- ULONG celt;
- ULONG i;
-
- if (bReverse) {
- pSymbol->Release();
-
- i = 0;
-
- for (pSymbol = NULL; (i < dwRange) && SUCCEEDED(pEnumSymsByAddr->Next(1, &pSymbol, &celt)) && (celt == 1); i++) {
- PrintPublicSymbol(pSymbol);
-
- pSymbol->Release();
- }
- }
-
- else {
- PrintPublicSymbol(pSymbol);
-
- pSymbol->Release();
-
- i = 1;
-
- for (pSymbol = NULL; (i < dwRange) && SUCCEEDED(pEnumSymsByAddr->Prev(1, &pSymbol, &celt)) && (celt == 1); i++) {
- PrintPublicSymbol(pSymbol);
- }
- }
- }
-
- pEnumSymsByAddr->Release();
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump label symbol information at a given RVA
-//
-bool DumpLabel(IDiaSession *pSession, DWORD dwRVA)
-{
- IDiaSymbol *pSymbol;
- LONG lDisplacement;
-
- if (FAILED(pSession->findSymbolByRVAEx(dwRVA, SymTagLabel, &pSymbol, &lDisplacement)) || (pSymbol == NULL)) {
- return false;
- }
-
- wprintf(L"Displacement = 0x%X\n", lDisplacement);
-
- PrintGeneric(pSymbol);
-
- pSymbol->Release();
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Dump annotation symbol information at a given RVA
-//
-bool DumpAnnotations(IDiaSession *pSession, DWORD dwRVA)
-{
- IDiaSymbol *pSymbol;
- LONG lDisplacement;
-
- if (FAILED(pSession->findSymbolByRVAEx(dwRVA, SymTagAnnotation, &pSymbol, &lDisplacement)) || (pSymbol == NULL)) {
- return false;
- }
-
- wprintf(L"Displacement = 0x%X\n", lDisplacement);
-
- PrintGeneric(pSymbol);
-
- pSymbol->Release();
-
- return true;
-}
-
-struct OMAP_DATA
-{
- DWORD dwRVA;
- DWORD dwRVATo;
-};
-
-////////////////////////////////////////////////////////////
-//
-bool DumpMapToSrc(IDiaSession *pSession, DWORD dwRVA)
-{
- IDiaEnumDebugStreams *pEnumStreams;
- IDiaEnumDebugStreamData *pStream;
- ULONG celt;
-
- if (FAILED(pSession->getEnumDebugStreams(&pEnumStreams))) {
- return false;
- }
-
- celt = 0;
-
- for (; SUCCEEDED(pEnumStreams->Next(1, &pStream, &celt)) && (celt == 1); pStream = NULL) {
- BSTR bstrName;
-
- if (pStream->get_name(&bstrName) != S_OK) {
- bstrName = NULL;
- }
-
- if (bstrName && wcscmp(bstrName, L"OMAPTO") == 0) {
- OMAP_DATA data, datasav;
- DWORD cbData, celt;
- DWORD dwRVATo = 0;
- unsigned int i;
-
- datasav.dwRVATo = 0;
- datasav.dwRVA = 0;
-
- while (SUCCEEDED(pStream->Next(1, sizeof(data), &cbData, (BYTE*) &data, &celt)) && (celt == 1)) {
- if (dwRVA > data.dwRVA) {
- datasav = data;
- continue;
- }
-
- else if (dwRVA == data.dwRVA) {
- dwRVATo = data.dwRVATo;
- }
-
- else if (datasav.dwRVATo) {
- dwRVATo = datasav.dwRVATo + (dwRVA - datasav.dwRVA);
- }
- break;
- }
-
- wprintf(L"image rva = %08X ==> source rva = %08X\n\nRelated OMAP entries:\n", dwRVA, dwRVATo);
- wprintf(L"image rva ==> source rva\n");
- wprintf(L"%08X ==> %08X\n", datasav.dwRVA, datasav.dwRVATo);
-
- i = 0;
-
- do {
- wprintf(L"%08X ==> %08X\n", data.dwRVA, data.dwRVATo);
- }
- while ((++i) < 5 && SUCCEEDED(pStream->Next(1, sizeof(data), &cbData, (BYTE*) &data, &celt)) && (celt == 1));
- }
-
- if (bstrName != NULL) {
- SysFreeString(bstrName);
- }
-
- pStream->Release();
- }
-
- pEnumStreams->Release();
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-//
-bool DumpMapFromSrc(IDiaSession *pSession, DWORD dwRVA)
-{
- IDiaEnumDebugStreams *pEnumStreams;
-
- if (FAILED(pSession->getEnumDebugStreams(&pEnumStreams))) {
- return false;
- }
-
- IDiaEnumDebugStreamData *pStream;
- ULONG celt = 0;
-
- for (; SUCCEEDED(pEnumStreams->Next(1, &pStream, &celt)) && (celt == 1); pStream = NULL) {
- BSTR bstrName;
-
- if (pStream->get_name(&bstrName) != S_OK) {
- bstrName = NULL;
- }
-
- if (bstrName && wcscmp(bstrName, L"OMAPFROM") == 0) {
- OMAP_DATA data;
- OMAP_DATA datasav;
- DWORD cbData;
- DWORD celt;
- DWORD dwRVATo = 0;
- unsigned int i;
-
- datasav.dwRVATo = 0;
- datasav.dwRVA = 0;
-
- while (SUCCEEDED(pStream->Next(1, sizeof(data), &cbData, (BYTE*) &data, &celt)) && (celt == 1)) {
- if (dwRVA > data.dwRVA) {
- datasav = data;
- continue;
- }
-
- else if (dwRVA == data.dwRVA) {
- dwRVATo = data.dwRVATo;
- }
-
- else if (datasav.dwRVATo) {
- dwRVATo = datasav.dwRVATo + (dwRVA - datasav.dwRVA);
- }
- break;
- }
-
- wprintf(L"source rva = %08X ==> image rva = %08X\n\nRelated OMAP entries:\n", dwRVA, dwRVATo);
- wprintf(L"source rva ==> image rva\n");
- wprintf(L"%08X ==> %08X\n", datasav.dwRVA, datasav.dwRVATo);
-
- i = 0;
-
- do {
- wprintf(L"%08X ==> %08X\n", data.dwRVA, data.dwRVATo);
- }
- while ((++i) < 5 && SUCCEEDED(pStream->Next(1, sizeof(data), &cbData, (BYTE*) &data, &celt)) && (celt == 1));
- }
-
- if (bstrName != NULL) {
- SysFreeString(bstrName);
- }
-
- pStream->Release();
- }
-
- pEnumStreams->Release();
-
- return true;
-}
-
-////////////////////////////////////////////////////////////
-// Retreive the table that matches the given iid
-//
-// A PDB table could store the section contributions, the frame data,
-// the injected sources
-//
-HRESULT GetTable(IDiaSession *pSession, REFIID iid, void **ppUnk)
-{
- IDiaEnumTables *pEnumTables;
-
- if (FAILED(pSession->getEnumTables(&pEnumTables))) {
- wprintf(L"ERROR - GetTable() getEnumTables\n");
-
- return E_FAIL;
- }
-
- IDiaTable *pTable;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumTables->Next(1, &pTable, &celt)) && (celt == 1)) {
- // There's only one table that matches the given IID
-
- if (SUCCEEDED(pTable->QueryInterface(iid, (void **) ppUnk))) {
- pTable->Release();
- pEnumTables->Release();
-
- return S_OK;
- }
-
- pTable->Release();
- }
-
- pEnumTables->Release();
-
- return E_FAIL;
-}
diff --git a/src/ToolBox/PdbTypeMatch/PdbTypeMatch.h b/src/ToolBox/PdbTypeMatch/PdbTypeMatch.h
deleted file mode 100644
index 2da38cf2b5..0000000000
--- a/src/ToolBox/PdbTypeMatch/PdbTypeMatch.h
+++ /dev/null
@@ -1,69 +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 "dia2.h"
-#include <set>
-
-extern const wchar_t *g_szFilename;
-extern IDiaDataSource *g_pDiaDataSource;
-extern IDiaSession *g_pDiaSession1, *g_pDiaSession2;
-extern IDiaSymbol *g_pGlobalSymbol1, *g_pGlobalSymbol2;
-extern DWORD g_dwMachineType;
-
-typedef std::set<std::wstring> IDiaSymbolSet;
-
-
-void PrintHelpOptions();
-bool ParseArg(int , wchar_t *[]);
-
-bool InitDiaSource(IDiaDataSource **ppSource);
-void Cleanup();
-bool LoadDataFromPdb(const wchar_t *, IDiaDataSource *, IDiaSession **, IDiaSymbol **);
-
-
-bool EnumTypesInPdb(IDiaSymbolSet* types, IDiaSession *pSession, IDiaSymbol *pGlobal);
-bool LayoutMatches(IDiaSymbol* pSymbol1, IDiaSymbol* pSymbol2);
-
-LPSTR UnicodeToAnsi(LPCWSTR s);
-void DumpAllPdbInfo(IDiaSession *, IDiaSymbol *);
-bool DumpAllMods(IDiaSymbol *);
-bool DumpAllPublics(IDiaSymbol *);
-bool DumpCompiland(IDiaSymbol *, const wchar_t *);
-bool DumpAllSymbols(IDiaSymbol *);
-bool DumpAllGlobals(IDiaSymbol *);
-bool DumpAllTypes(IDiaSymbol *);
-bool DumpAllUDTs(IDiaSymbol *);
-bool DumpAllEnums(IDiaSymbol *);
-bool DumpAllTypedefs(IDiaSymbol *);
-bool DumpAllOEMs(IDiaSymbol *);
-bool DumpAllFiles(IDiaSession *, IDiaSymbol *);
-bool DumpAllLines(IDiaSession *, IDiaSymbol *);
-bool DumpAllLines(IDiaSession *, DWORD, DWORD);
-bool DumpAllSecContribs(IDiaSession *);
-bool DumpAllDebugStreams(IDiaSession *);
-bool DumpAllInjectedSources(IDiaSession *);
-bool DumpInjectedSource(IDiaSession *, const wchar_t *);
-bool DumpAllSourceFiles(IDiaSession *, IDiaSymbol *);
-bool DumpAllFPO(IDiaSession *);
-bool DumpFPO(IDiaSession *, DWORD);
-bool DumpFPO(IDiaSession *, IDiaSymbol *, const wchar_t *);
-bool DumpSymbolWithRVA(IDiaSession *, DWORD, const wchar_t *);
-bool DumpSymbolsWithRegEx(IDiaSymbol *, const wchar_t *, const wchar_t *);
-bool DumpSymbolWithChildren(IDiaSymbol *, const wchar_t *);
-bool DumpLines(IDiaSession *, DWORD);
-bool DumpLines(IDiaSession *, IDiaSymbol *, const wchar_t *);
-bool DumpType(IDiaSymbol *, const wchar_t *);
-bool DumpLinesForSourceFile(IDiaSession *, const wchar_t *, DWORD);
-bool DumpPublicSymbolsSorted(IDiaSession *, DWORD, DWORD, bool);
-bool DumpLabel(IDiaSession *, DWORD);
-bool DumpAnnotations(IDiaSession *, DWORD);
-bool DumpMapToSrc(IDiaSession *, DWORD);
-bool DumpMapFromSrc(IDiaSession *, DWORD);
-
-HRESULT GetTable(IDiaSession *, REFIID, void **);
-
-///////////////////////////////////////////////////////////////////
-// Functions defined in regs.cpp
-const wchar_t *SzNameC7Reg(USHORT, DWORD);
-const wchar_t *SzNameC7Reg(USHORT);
diff --git a/src/ToolBox/PdbTypeMatch/PrintSymbol.cpp b/src/ToolBox/PdbTypeMatch/PrintSymbol.cpp
deleted file mode 100644
index 41e3d4cf0e..0000000000
--- a/src/ToolBox/PdbTypeMatch/PrintSymbol.cpp
+++ /dev/null
@@ -1,2254 +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.
-
-// PrintSymbol.cpp : Defines the printing procedures for the symbols
-//
-// This is a part of the Debug Interface Access SDK
-//
-// This source code is only intended as a supplement to the
-// Debug Interface Access SDK and related electronic documentation
-// provided with the library.
-// See these sources for detailed information regarding the
-// Debug Interface Access SDK API.
-//
-
-#include "stdafx.h"
-
-#include <malloc.h>
-
-#include "dia2.h"
-#include "regs.h"
-#include "PrintSymbol.h"
-#include <comdef.h>
-
-
-// Basic types
-const wchar_t * const rgBaseType[] =
-{
- L"<NoType>", // btNoType = 0,
- L"void", // btVoid = 1,
- L"char", // btChar = 2,
- L"wchar_t", // btWChar = 3,
- L"signed char",
- L"unsigned char",
- L"int", // btInt = 6,
- L"unsigned int", // btUInt = 7,
- L"float", // btFloat = 8,
- L"<BCD>", // btBCD = 9,
- L"bool", // btBool = 10,
- L"short",
- L"unsigned short",
- L"long", // btLong = 13,
- L"unsigned long", // btULong = 14,
- L"__int8",
- L"__int16",
- L"__int32",
- L"__int64",
- L"__int128",
- L"unsigned __int8",
- L"unsigned __int16",
- L"unsigned __int32",
- L"unsigned __int64",
- L"unsigned __int128",
- L"<currency>", // btCurrency = 25,
- L"<date>", // btDate = 26,
- L"VARIANT", // btVariant = 27,
- L"<complex>", // btComplex = 28,
- L"<bit>", // btBit = 29,
- L"BSTR", // btBSTR = 30,
- L"HRESULT" // btHresult = 31
-};
-
-// Tags returned by Dia
-const wchar_t * const rgTags[] =
-{
- L"(SymTagNull)", // SymTagNull
- L"Executable (Global)", // SymTagExe
- L"Compiland", // SymTagCompiland
- L"CompilandDetails", // SymTagCompilandDetails
- L"CompilandEnv", // SymTagCompilandEnv
- L"Function", // SymTagFunction
- L"Block", // SymTagBlock
- L"Data", // SymTagData
- L"Annotation", // SymTagAnnotation
- L"Label", // SymTagLabel
- L"PublicSymbol", // SymTagPublicSymbol
- L"UserDefinedType", // SymTagUDT
- L"Enum", // SymTagEnum
- L"FunctionType", // SymTagFunctionType
- L"PointerType", // SymTagPointerType
- L"ArrayType", // SymTagArrayType
- L"BaseType", // SymTagBaseType
- L"Typedef", // SymTagTypedef
- L"BaseClass", // SymTagBaseClass
- L"Friend", // SymTagFriend
- L"FunctionArgType", // SymTagFunctionArgType
- L"FuncDebugStart", // SymTagFuncDebugStart
- L"FuncDebugEnd", // SymTagFuncDebugEnd
- L"UsingNamespace", // SymTagUsingNamespace
- L"VTableShape", // SymTagVTableShape
- L"VTable", // SymTagVTable
- L"Custom", // SymTagCustom
- L"Thunk", // SymTagThunk
- L"CustomType", // SymTagCustomType
- L"ManagedType", // SymTagManagedType
- L"Dimension", // SymTagDimension
- L"CallSite", // SymTagCallSite
-};
-
-
-// Processors
-const wchar_t * const rgFloatPackageStrings[] =
-{
- L"hardware processor (80x87 for Intel processors)", // CV_CFL_NDP
- L"emulator", // CV_CFL_EMU
- L"altmath", // CV_CFL_ALT
- L"???"
-};
-
-const wchar_t * const rgProcessorStrings[] =
-{
- L"8080", // CV_CFL_8080
- L"8086", // CV_CFL_8086
- L"80286", // CV_CFL_80286
- L"80386", // CV_CFL_80386
- L"80486", // CV_CFL_80486
- L"Pentium", // CV_CFL_PENTIUM
- L"Pentium Pro/Pentium II", // CV_CFL_PENTIUMII/CV_CFL_PENTIUMPRO
- L"Pentium III", // CV_CFL_PENTIUMIII
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"MIPS (Generic)", // CV_CFL_MIPSR4000
- L"MIPS16", // CV_CFL_MIPS16
- L"MIPS32", // CV_CFL_MIPS32
- L"MIPS64", // CV_CFL_MIPS64
- L"MIPS I", // CV_CFL_MIPSI
- L"MIPS II", // CV_CFL_MIPSII
- L"MIPS III", // CV_CFL_MIPSIII
- L"MIPS IV", // CV_CFL_MIPSIV
- L"MIPS V", // CV_CFL_MIPSV
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"M68000", // CV_CFL_M68000
- L"M68010", // CV_CFL_M68010
- L"M68020", // CV_CFL_M68020
- L"M68030", // CV_CFL_M68030
- L"M68040", // CV_CFL_M68040
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"Alpha 21064", // CV_CFL_ALPHA, CV_CFL_ALPHA_21064
- L"Alpha 21164", // CV_CFL_ALPHA_21164
- L"Alpha 21164A", // CV_CFL_ALPHA_21164A
- L"Alpha 21264", // CV_CFL_ALPHA_21264
- L"Alpha 21364", // CV_CFL_ALPHA_21364
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"PPC 601", // CV_CFL_PPC601
- L"PPC 603", // CV_CFL_PPC603
- L"PPC 604", // CV_CFL_PPC604
- L"PPC 620", // CV_CFL_PPC620
- L"PPC w/FP", // CV_CFL_PPCFP
- L"PPC (Big Endian)", // CV_CFL_PPCBE
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"SH3", // CV_CFL_SH3
- L"SH3E", // CV_CFL_SH3E
- L"SH3DSP", // CV_CFL_SH3DSP
- L"SH4", // CV_CFL_SH4
- L"SHmedia", // CV_CFL_SHMEDIA
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"ARM3", // CV_CFL_ARM3
- L"ARM4", // CV_CFL_ARM4
- L"ARM4T", // CV_CFL_ARM4T
- L"ARM5", // CV_CFL_ARM5
- L"ARM5T", // CV_CFL_ARM5T
- L"ARM6", // CV_CFL_ARM6
- L"ARM (XMAC)", // CV_CFL_ARM_XMAC
- L"ARM (WMMX)", // CV_CFL_ARM_WMMX
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"Omni", // CV_CFL_OMNI
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"Itanium", // CV_CFL_IA64, CV_CFL_IA64_1
- L"Itanium (McKinley)", // CV_CFL_IA64_2
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"CEE", // CV_CFL_CEE
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"AM33", // CV_CFL_AM33
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"M32R", // CV_CFL_M32R
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"TriCore", // CV_CFL_TRICORE
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"x64", // CV_CFL_X64
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"EBC", // CV_CFL_EBC
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"???",
- L"Thumb", // CV_CFL_THUMB
-};
-
-const wchar_t * const rgDataKind[] =
-{
- L"Unknown",
- L"Local",
- L"Static Local",
- L"Param",
- L"Object Ptr",
- L"File Static",
- L"Global",
- L"Member",
- L"Static Member",
- L"Constant",
-};
-
-const wchar_t * const rgUdtKind[] =
-{
- L"struct",
- L"class",
- L"union",
- L"enum",
-};
-
-const wchar_t * const rgAccess[] =
-{
- L"", // No access specifier
- L"private",
- L"protected",
- L"public"
-};
-
-const wchar_t * const rgCallingConvention[] =
-{
- L"CV_CALL_NEAR_C ",
- L"CV_CALL_FAR_C ",
- L"CV_CALL_NEAR_PASCAL ",
- L"CV_CALL_FAR_PASCAL ",
- L"CV_CALL_NEAR_FAST ",
- L"CV_CALL_FAR_FAST ",
- L"CV_CALL_SKIPPED ",
- L"CV_CALL_NEAR_STD ",
- L"CV_CALL_FAR_STD ",
- L"CV_CALL_NEAR_SYS ",
- L"CV_CALL_FAR_SYS ",
- L"CV_CALL_THISCALL ",
- L"CV_CALL_MIPSCALL ",
- L"CV_CALL_GENERIC ",
- L"CV_CALL_ALPHACALL ",
- L"CV_CALL_PPCCALL ",
- L"CV_CALL_SHCALL ",
- L"CV_CALL_ARMCALL ",
- L"CV_CALL_AM33CALL ",
- L"CV_CALL_TRICALL ",
- L"CV_CALL_SH5CALL ",
- L"CV_CALL_M32RCALL ",
- L"CV_CALL_RESERVED "
-};
-
-const wchar_t * const rgLanguage[] =
-{
- L"C", // CV_CFL_C
- L"C++", // CV_CFL_CXX
- L"FORTRAN", // CV_CFL_FORTRAN
- L"MASM", // CV_CFL_MASM
- L"Pascal", // CV_CFL_PASCAL
- L"Basic", // CV_CFL_BASIC
- L"COBOL", // CV_CFL_COBOL
- L"LINK", // CV_CFL_LINK
- L"CVTRES", // CV_CFL_CVTRES
- L"CVTPGD", // CV_CFL_CVTPGD
- L"C#", // CV_CFL_CSHARP
- L"Visual Basic", // CV_CFL_VB
- L"ILASM", // CV_CFL_ILASM
- L"Java", // CV_CFL_JAVA
- L"JScript", // CV_CFL_JSCRIPT
- L"MSIL", // CV_CFL_MSIL
-};
-
-const wchar_t * const rgLocationTypeString[] =
-{
- L"NULL",
- L"static",
- L"TLS",
- L"RegRel",
- L"ThisRel",
- L"Enregistered",
- L"BitField",
- L"Slot",
- L"IL Relative",
- L"In MetaData",
- L"Constant"
-};
-
-
-////////////////////////////////////////////////////////////
-// Print a public symbol info: name, VA, RVA, SEG:OFF
-//
-void PrintPublicSymbol(IDiaSymbol *pSymbol)
-{
- DWORD dwSymTag;
- DWORD dwRVA;
- DWORD dwSeg;
- DWORD dwOff;
- BSTR bstrName;
-
- if (pSymbol->get_symTag(&dwSymTag) != S_OK) {
- return;
- }
-
- if (pSymbol->get_relativeVirtualAddress(&dwRVA) != S_OK) {
- dwRVA = 0xFFFFFFFF;
- }
-
- pSymbol->get_addressSection(&dwSeg);
- pSymbol->get_addressOffset(&dwOff);
-
- wprintf(L"%s: [%08X][%04X:%08X] ", rgTags[dwSymTag], dwRVA, dwSeg, dwOff);
-
- if (dwSymTag == SymTagThunk) {
- if (pSymbol->get_name(&bstrName) == S_OK) {
- wprintf(L"%s\n", bstrName);
-
- SysFreeString(bstrName);
- }
-
- else {
- if (pSymbol->get_targetRelativeVirtualAddress(&dwRVA) != S_OK) {
- dwRVA = 0xFFFFFFFF;
- }
-
- pSymbol->get_targetSection(&dwSeg);
- pSymbol->get_targetOffset(&dwOff);
-
- wprintf(L"target -> [%08X][%04X:%08X]\n", dwRVA, dwSeg, dwOff);
- }
- }
-
- else {
- // must be a function or a data symbol
-
- BSTR bstrUndname;
-
- if (pSymbol->get_name(&bstrName) == S_OK) {
- if (pSymbol->get_undecoratedName(&bstrUndname) == S_OK) {
- wprintf(L"%s(%s)\n", bstrName, bstrUndname);
-
- SysFreeString(bstrUndname);
- }
-
- else {
- wprintf(L"%s\n", bstrName);
- }
-
- SysFreeString(bstrName);
- }
- }
-}
-
-////////////////////////////////////////////////////////////
-// Print a global symbol info: name, VA, RVA, SEG:OFF
-//
-void PrintGlobalSymbol(IDiaSymbol *pSymbol)
-{
- DWORD dwSymTag;
- DWORD dwRVA;
- DWORD dwSeg;
- DWORD dwOff;
-
- if (pSymbol->get_symTag(&dwSymTag) != S_OK) {
- return;
- }
-
- if (pSymbol->get_relativeVirtualAddress(&dwRVA) != S_OK) {
- dwRVA = 0xFFFFFFFF;
- }
-
- pSymbol->get_addressSection(&dwSeg);
- pSymbol->get_addressOffset(&dwOff);
-
- wprintf(L"%s: [%08X][%04X:%08X] ", rgTags[dwSymTag], dwRVA, dwSeg, dwOff);
-
- if (dwSymTag == SymTagThunk) {
- BSTR bstrName;
-
- if (pSymbol->get_name(&bstrName) == S_OK) {
- wprintf(L"%s\n", bstrName);
-
- SysFreeString(bstrName);
- }
-
- else {
- if (pSymbol->get_targetRelativeVirtualAddress(&dwRVA) != S_OK) {
- dwRVA = 0xFFFFFFFF;
- }
-
- pSymbol->get_targetSection(&dwSeg);
- pSymbol->get_targetOffset(&dwOff);
- wprintf(L"target -> [%08X][%04X:%08X]\n", dwRVA, dwSeg, dwOff);
- }
- }
-
- else {
- BSTR bstrName;
- BSTR bstrUndname;
-
- if (pSymbol->get_name(&bstrName) == S_OK) {
- if (pSymbol->get_undecoratedName(&bstrUndname) == S_OK) {
- wprintf(L"%s(%s)\n", bstrName, bstrUndname);
-
- SysFreeString(bstrUndname);
- }
-
- else {
- wprintf(L"%s\n", bstrName);
- }
-
- SysFreeString(bstrName);
- }
- }
-}
-
-////////////////////////////////////////////////////////////
-// Print a callsite symbol info: SEG:OFF, RVA, type
-//
-void PrintCallSiteInfo(IDiaSymbol *pSymbol)
-{
- DWORD dwISect, dwOffset;
- if (pSymbol->get_addressSection(&dwISect) == S_OK &&
- pSymbol->get_addressOffset(&dwOffset) == S_OK) {
- wprintf(L"[0x%04x:0x%08x] ", dwISect, dwOffset);
- }
-
- DWORD rva;
- if (pSymbol->get_relativeVirtualAddress(&rva) == S_OK) {
- wprintf(L"0x%08X ", rva);
- }
-
- IDiaSymbol *pFuncType;
- if (pSymbol->get_type(&pFuncType) == S_OK) {
- DWORD tag;
- if (pFuncType->get_symTag(&tag) == S_OK) {
- switch(tag)
- {
- case SymTagFunctionType:
- PrintFunctionType(pSymbol);
- break;
- case SymTagPointerType:
- PrintFunctionType(pFuncType);
- break;
- default:
- wprintf(L"???\n");
- break;
- }
- }
- pFuncType->Release();
- }
-}
-
-////////////////////////////////////////////////////////////
-// Print a symbol info: name, type etc.
-//
-void PrintSymbol(IDiaSymbol *pSymbol, DWORD dwIndent)
-{
- IDiaSymbol *pType;
- DWORD dwSymTag;
- ULONGLONG ulLen;
-
- if (pSymbol->get_symTag(&dwSymTag) != S_OK) {
- wprintf(L"ERROR - PrintSymbol get_symTag() failed\n");
- return;
- }
-
- if (dwSymTag == SymTagFunction) {
- putwchar(L'\n');
- }
-
- PrintSymTag(dwSymTag);
-
- for (DWORD i = 0; i < dwIndent; i++) {
- putwchar(L' ');
- }
-
- switch (dwSymTag) {
- case SymTagCompilandDetails:
- PrintCompilandDetails(pSymbol);
- break;
-
- case SymTagCompilandEnv:
- PrintCompilandEnv(pSymbol);
- break;
-
- case SymTagData:
- PrintData(pSymbol, dwIndent + 2);
- break;
-
- case SymTagFunction:
- case SymTagBlock:
- PrintLocation(pSymbol);
-
- if (pSymbol->get_length(&ulLen) == S_OK) {
- wprintf(L", len = %08X, ", ulLen);
- }
-
- if (dwSymTag == SymTagFunction) {
- DWORD dwCall;
-
- if (pSymbol->get_callingConvention(&dwCall) == S_OK) {
- wprintf(L", %s", SafeDRef(rgCallingConvention, dwCall));
- }
- }
-
- PrintUndName(pSymbol);
- putwchar(L'\n');
-
- if (dwSymTag == SymTagFunction)
- {
- BOOL f;
-
- for (DWORD i = 0; i < dwIndent; i++) {
- putwchar(L' ');
- }
- wprintf(L" Function attribute:");
-
- if ((pSymbol->get_isCxxReturnUdt(&f) == S_OK) && f) {
- wprintf(L" return user defined type (C++ style)");
- }
- if ((pSymbol->get_constructor(&f) == S_OK) && f) {
- wprintf(L" instance constructor");
- }
- if ((pSymbol->get_isConstructorVirtualBase(&f) == S_OK) && f) {
- wprintf(L" instance constructor of a class with virtual base");
- }
- putwchar (L'\n');
-
- for (DWORD i = 0; i < dwIndent; i++) {
- putwchar(L' ');
- }
- wprintf(L" Function info:");
-
- if ((pSymbol->get_hasAlloca(&f) == S_OK) && f) {
- wprintf(L" alloca");
- }
-
- if ((pSymbol->get_hasSetJump(&f) == S_OK) && f) {
- wprintf(L" setjmp");
- }
-
- if ((pSymbol->get_hasLongJump(&f) == S_OK) && f) {
- wprintf(L" longjmp");
- }
-
- if ((pSymbol->get_hasInlAsm(&f) == S_OK) && f) {
- wprintf(L" inlasm");
- }
-
- if ((pSymbol->get_hasEH(&f) == S_OK) && f) {
- wprintf(L" eh");
- }
-
- if ((pSymbol->get_inlSpec(&f) == S_OK) && f) {
- wprintf(L" inl_specified");
- }
-
- if ((pSymbol->get_hasSEH(&f) == S_OK) && f) {
- wprintf(L" seh");
- }
-
- if ((pSymbol->get_isNaked(&f) == S_OK) && f) {
- wprintf(L" naked");
- }
-
- if ((pSymbol->get_hasSecurityChecks(&f) == S_OK) && f) {
- wprintf(L" gschecks");
- }
-
- if ((pSymbol->get_isSafeBuffers(&f) == S_OK) && f) {
- wprintf(L" safebuffers");
- }
-
- if ((pSymbol->get_hasEHa(&f) == S_OK) && f) {
- wprintf(L" asyncheh");
- }
-
- if ((pSymbol->get_noStackOrdering(&f) == S_OK) && f) {
- wprintf(L" gsnostackordering");
- }
-
- if ((pSymbol->get_wasInlined(&f) == S_OK) && f) {
- wprintf(L" wasinlined");
- }
-
- if ((pSymbol->get_strictGSCheck(&f) == S_OK) && f) {
- wprintf(L" strict_gs_check");
- }
-
- putwchar(L'\n');
- }
-
- IDiaEnumSymbols *pEnumChildren;
-
- if (SUCCEEDED(pSymbol->findChildren(SymTagNull, NULL, nsNone, &pEnumChildren))) {
- IDiaSymbol *pChild;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumChildren->Next(1, &pChild, &celt)) && (celt == 1)) {
- PrintSymbol(pChild, dwIndent + 2);
- pChild->Release();
- }
-
- pEnumChildren->Release();
- }
- return;
-
- case SymTagAnnotation:
- PrintLocation(pSymbol);
- putwchar(L'\n');
- break;
-
- case SymTagLabel:
- PrintLocation(pSymbol);
- wprintf(L", ");
- PrintName(pSymbol);
- break;
-
- case SymTagEnum:
- case SymTagTypedef:
- case SymTagUDT:
- case SymTagBaseClass:
- PrintUDT(pSymbol);
- break;
-
- case SymTagFuncDebugStart:
- case SymTagFuncDebugEnd:
- PrintLocation(pSymbol);
- break;
-
- case SymTagFunctionArgType:
- case SymTagFunctionType:
- case SymTagPointerType:
- case SymTagArrayType:
- case SymTagBaseType:
- if (pSymbol->get_type(&pType) == S_OK) {
- PrintType(pType);
- pType->Release();
- }
-
- putwchar(L'\n');
- break;
-
- case SymTagThunk:
- PrintThunk(pSymbol);
- break;
-
- case SymTagCallSite:
- PrintCallSiteInfo(pSymbol);
- break;
-
- default:
- PrintName(pSymbol);
-
- IDiaSymbol *pType;
-
- if (pSymbol->get_type(&pType) == S_OK) {
- wprintf(L" has type ");
- PrintType(pType);
- pType->Release();
- }
- }
-
- if ((dwSymTag == SymTagUDT) || (dwSymTag == SymTagAnnotation)) {
- IDiaEnumSymbols *pEnumChildren;
-
- putwchar(L'\n');
-
- if (SUCCEEDED(pSymbol->findChildren(SymTagNull, NULL, nsNone, &pEnumChildren))) {
- IDiaSymbol *pChild;
- ULONG celt = 0;
-
- while (SUCCEEDED(pEnumChildren->Next(1, &pChild, &celt)) && (celt == 1)) {
- PrintSymbol(pChild, dwIndent + 2);
- pChild->Release();
- }
-
- pEnumChildren->Release();
- }
- }
- putwchar(L'\n');
-}
-
-////////////////////////////////////////////////////////////
-// Print the string coresponding to the symbol's tag property
-//
-void PrintSymTag(DWORD dwSymTag)
-{
- wprintf(L"%-15s: ", SafeDRef(rgTags, dwSymTag));
-}
-
-////////////////////////////////////////////////////////////
-// Print the name of the symbol
-//
-void PrintName(IDiaSymbol *pSymbol)
-{
- BSTR bstrName;
- BSTR bstrUndName;
-
- if (pSymbol->get_name(&bstrName) != S_OK) {
- wprintf(L"(none)");
- return;
- }
-
- if (pSymbol->get_undecoratedName(&bstrUndName) == S_OK) {
- if (wcscmp(bstrName, bstrUndName) == 0) {
- wprintf(L"%s", bstrName);
- }
-
- else {
- wprintf(L"%s(%s)", bstrUndName, bstrName);
- }
-
- SysFreeString(bstrUndName);
- }
-
- else {
- wprintf(L"%s", bstrName);
- }
-
- SysFreeString(bstrName);
-}
-
-void GetSymbolName(std::wstring& symbolName, IDiaSymbol *pSymbol)
-{
- BSTR bstrName;
- BSTR bstrUndName;
-
- if (pSymbol->get_name(&bstrName) != S_OK) {
- symbolName.clear();
- return;
- }
-
- if (pSymbol->get_undecoratedName(&bstrUndName) == S_OK) {
- if (wcscmp(bstrName, bstrUndName) == 0)
- {
- symbolName= _bstr_t(bstrName);
- }
- else
- {
- symbolName= _bstr_t(bstrUndName);
- }
-
- SysFreeString(bstrUndName);
- }
-
- else
- {
- symbolName= _bstr_t(bstrName);
- }
-
- SysFreeString(bstrName);
-}
-
-////////////////////////////////////////////////////////////
-// Print the undecorated name of the symbol
-// - only SymTagFunction, SymTagData and SymTagPublicSymbol
-// can have this property set
-//
-void PrintUndName(IDiaSymbol *pSymbol)
-{
- BSTR bstrName;
-
- if (pSymbol->get_undecoratedName(&bstrName) != S_OK) {
- if (pSymbol->get_name(&bstrName) == S_OK) {
- // Print the name of the symbol instead
-
- wprintf(L"%s", (bstrName[0] != L'\0') ? bstrName : L"(none)");
-
- SysFreeString(bstrName);
- }
-
- else {
- wprintf(L"(none)");
- }
-
- return;
- }
-
- if (bstrName[0] != L'\0') {
- wprintf(L"%s", bstrName);
- }
-
- SysFreeString(bstrName);
-}
-
-////////////////////////////////////////////////////////////
-// Print a SymTagThunk symbol's info
-//
-void PrintThunk(IDiaSymbol *pSymbol)
-{
- DWORD dwRVA;
- DWORD dwISect;
- DWORD dwOffset;
-
- if ((pSymbol->get_relativeVirtualAddress(&dwRVA) == S_OK) &&
- (pSymbol->get_addressSection(&dwISect) == S_OK) &&
- (pSymbol->get_addressOffset(&dwOffset) == S_OK)) {
- wprintf(L"[%08X][%04X:%08X]", dwRVA, dwISect, dwOffset);
- }
-
- if ((pSymbol->get_targetSection(&dwISect) == S_OK) &&
- (pSymbol->get_targetOffset(&dwOffset) == S_OK) &&
- (pSymbol->get_targetRelativeVirtualAddress(&dwRVA) == S_OK)) {
- wprintf(L", target [%08X][%04X:%08X] ", dwRVA, dwISect, dwOffset);
- }
-
- else {
- wprintf(L", target ");
-
- PrintName(pSymbol);
- }
-}
-
-////////////////////////////////////////////////////////////
-// Print the compiland/module details: language, platform...
-//
-void PrintCompilandDetails(IDiaSymbol *pSymbol)
-{
- DWORD dwLanguage;
-
- if (pSymbol->get_language(&dwLanguage) == S_OK) {
- wprintf(L"\n\tLanguage: %s\n", SafeDRef(rgLanguage, dwLanguage));
- }
-
- DWORD dwPlatform;
-
- if (pSymbol->get_platform(&dwPlatform) == S_OK) {
- wprintf(L"\tTarget processor: %s\n", SafeDRef(rgProcessorStrings, dwPlatform));
- }
-
- BOOL fEC;
-
- if (pSymbol->get_editAndContinueEnabled(&fEC) == S_OK) {
- if (fEC) {
- wprintf(L"\tCompiled for edit and continue: yes\n");
- }
-
- else {
- wprintf(L"\tCompiled for edit and continue: no\n");
- }
- }
-
- BOOL fDbgInfo;
-
- if (pSymbol->get_hasDebugInfo(&fDbgInfo) == S_OK) {
- if (fDbgInfo) {
- wprintf(L"\tCompiled without debugging info: no\n");
- }
-
- else {
- wprintf(L"\tCompiled without debugging info: yes\n");
- }
- }
-
- BOOL fLTCG;
-
- if (pSymbol->get_isLTCG(&fLTCG) == S_OK) {
- if (fLTCG) {
- wprintf(L"\tCompiled with LTCG: yes\n");
- }
-
- else {
- wprintf(L"\tCompiled with LTCG: no\n");
- }
- }
-
- BOOL fDataAlign;
-
- if (pSymbol->get_isDataAligned(&fDataAlign) == S_OK) {
- if (fDataAlign) {
- wprintf(L"\tCompiled with /bzalign: no\n");
- }
-
- else {
- wprintf(L"\tCompiled with /bzalign: yes\n");
- }
- }
-
- BOOL fManagedPresent;
-
- if (pSymbol->get_hasManagedCode(&fManagedPresent) == S_OK) {
- if (fManagedPresent) {
- wprintf(L"\tManaged code present: yes\n");
- }
-
- else {
- wprintf(L"\tManaged code present: no\n");
- }
- }
-
- BOOL fSecurityChecks;
-
- if (pSymbol->get_hasSecurityChecks(&fSecurityChecks) == S_OK) {
- if (fSecurityChecks) {
- wprintf(L"\tCompiled with /GS: yes\n");
- }
-
- else {
- wprintf(L"\tCompiled with /GS: no\n");
- }
- }
-
- BOOL fHotPatch;
-
- if (pSymbol->get_isHotpatchable(&fHotPatch) == S_OK) {
- if (fHotPatch) {
- wprintf(L"\tCompiled with /hotpatch: yes\n");
- }
-
- else {
- wprintf(L"\tCompiled with /hotpatch: no\n");
- }
- }
-
- BOOL fCVTCIL;
-
- if (pSymbol->get_isCVTCIL(&fCVTCIL) == S_OK) {
- if (fCVTCIL) {
- wprintf(L"\tConverted by CVTCIL: yes\n");
- }
-
- else {
- wprintf(L"\tConverted by CVTCIL: no\n");
- }
- }
-
- BOOL fMSILModule;
-
- if (pSymbol->get_isMSILNetmodule(&fMSILModule) == S_OK) {
- if (fMSILModule) {
- wprintf(L"\tMSIL module: yes\n");
- }
-
- else {
- wprintf(L"\tMSIL module: no\n");
- }
- }
-
- DWORD dwVerMajor;
- DWORD dwVerMinor;
- DWORD dwVerBuild;
- DWORD dwVerQFE;
-
- if ((pSymbol->get_frontEndMajor(&dwVerMajor) == S_OK) &&
- (pSymbol->get_frontEndMinor(&dwVerMinor) == S_OK) &&
- (pSymbol->get_frontEndBuild(&dwVerBuild) == S_OK)) {
- wprintf(L"\tFrontend Version: Major = %u, Minor = %u, Build = %u",
- dwVerMajor,
- dwVerMinor,
- dwVerBuild);
-
- if (pSymbol->get_frontEndQFE(&dwVerQFE) == S_OK) {
- wprintf(L", QFE = %u", dwVerQFE);
- }
-
- putwchar(L'\n');
- }
-
- if ((pSymbol->get_backEndMajor(&dwVerMajor) == S_OK) &&
- (pSymbol->get_backEndMinor(&dwVerMinor) == S_OK) &&
- (pSymbol->get_backEndBuild(&dwVerBuild) == S_OK)) {
- wprintf(L"\tBackend Version: Major = %u, Minor = %u, Build = %u",
- dwVerMajor,
- dwVerMinor,
- dwVerBuild);
-
- if (pSymbol->get_backEndQFE(&dwVerQFE) == S_OK) {
- wprintf(L", QFE = %u", dwVerQFE);
- }
-
- putwchar(L'\n');
- }
-
- BSTR bstrCompilerName;
-
- if (pSymbol->get_compilerName(&bstrCompilerName) == S_OK) {
- if (bstrCompilerName != NULL) {
- wprintf(L"\tVersion string: %s", bstrCompilerName);
-
- SysFreeString(bstrCompilerName);
- }
- }
-
- putwchar(L'\n');
-}
-
-////////////////////////////////////////////////////////////
-// Print the compilan/module env
-//
-void PrintCompilandEnv(IDiaSymbol *pSymbol)
-{
- PrintName(pSymbol);
- wprintf(L" =");
-
- VARIANT vt = { VT_EMPTY };
-
- if (pSymbol->get_value(&vt) == S_OK) {
- PrintVariant(vt);
- VariantClear((VARIANTARG *) &vt);
- }
-}
-
-////////////////////////////////////////////////////////////
-// Print a string corespondig to a location type
-//
-void PrintLocation(IDiaSymbol *pSymbol)
-{
- DWORD dwLocType;
- DWORD dwRVA, dwSect, dwOff, dwReg, dwBitPos, dwSlot;
- LONG lOffset;
- ULONGLONG ulLen;
- VARIANT vt = { VT_EMPTY };
-
- if (pSymbol->get_locationType(&dwLocType) != S_OK) {
- // It must be a symbol in optimized code
-
- wprintf(L"symbol in optmized code");
- return;
- }
-
- switch (dwLocType) {
- case LocIsStatic:
- if ((pSymbol->get_relativeVirtualAddress(&dwRVA) == S_OK) &&
- (pSymbol->get_addressSection(&dwSect) == S_OK) &&
- (pSymbol->get_addressOffset(&dwOff) == S_OK)) {
- wprintf(L"%s, [%08X][%04X:%08X]", SafeDRef(rgLocationTypeString, dwLocType), dwRVA, dwSect, dwOff);
- }
- break;
-
- case LocIsTLS:
- case LocInMetaData:
- case LocIsIlRel:
- if ((pSymbol->get_relativeVirtualAddress(&dwRVA) == S_OK) &&
- (pSymbol->get_addressSection(&dwSect) == S_OK) &&
- (pSymbol->get_addressOffset(&dwOff) == S_OK)) {
- wprintf(L"%s, [%08X][%04X:%08X]", SafeDRef(rgLocationTypeString, dwLocType), dwRVA, dwSect, dwOff);
- }
- break;
-
- case LocIsRegRel:
- if ((pSymbol->get_registerId(&dwReg) == S_OK) &&
- (pSymbol->get_offset(&lOffset) == S_OK)) {
- wprintf(L"%s Relative, [%08X]", SzNameC7Reg((USHORT) dwReg), lOffset);
- }
- break;
-
- case LocIsThisRel:
- if (pSymbol->get_offset(&lOffset) == S_OK) {
- wprintf(L"this+0x%X", lOffset);
- }
- break;
-
- case LocIsBitField:
- if ((pSymbol->get_offset(&lOffset) == S_OK) &&
- (pSymbol->get_bitPosition(&dwBitPos) == S_OK) &&
- (pSymbol->get_length(&ulLen) == S_OK)) {
- wprintf(L"this(bf)+0x%X:0x%X len(0x%X)", lOffset, dwBitPos, ulLen);
- }
- break;
-
- case LocIsEnregistered:
- if (pSymbol->get_registerId(&dwReg) == S_OK) {
- wprintf(L"enregistered %s", SzNameC7Reg((USHORT) dwReg));
- }
- break;
-
- case LocIsSlot:
- if (pSymbol->get_slot(&dwSlot) == S_OK) {
- wprintf(L"%s, [%08X]", SafeDRef(rgLocationTypeString, dwLocType), dwSlot);
- }
- break;
-
- case LocIsConstant:
- wprintf(L"constant");
-
- if (pSymbol->get_value(&vt) == S_OK) {
- PrintVariant(vt);
- VariantClear((VARIANTARG *) &vt);
- }
- break;
-
- case LocIsNull:
- break;
-
- default :
- wprintf(L"Error - invalid location type: 0x%X", dwLocType);
- break;
- }
-}
-
-////////////////////////////////////////////////////////////
-// Print the type, value and the name of a const symbol
-//
-void PrintConst(IDiaSymbol *pSymbol)
-{
- PrintSymbolType(pSymbol);
-
- VARIANT vt = { VT_EMPTY };
-
- if (pSymbol->get_value(&vt) == S_OK) {
- PrintVariant(vt);
- VariantClear((VARIANTARG *) &vt);
- }
-
- PrintName(pSymbol);
-}
-
-////////////////////////////////////////////////////////////
-// Print the name and the type of an user defined type
-//
-void PrintUDT(IDiaSymbol *pSymbol)
-{
- PrintName(pSymbol);
- PrintSymbolType(pSymbol);
-}
-
-////////////////////////////////////////////////////////////
-// Print a string representing the type of a symbol
-//
-void PrintSymbolType(IDiaSymbol *pSymbol)
-{
- IDiaSymbol *pType;
-
- if (pSymbol->get_type(&pType) == S_OK) {
- wprintf(L", Type: ");
- PrintType(pType);
- pType->Release();
- }
-}
-
-////////////////////////////////////////////////////////////
-// Print the information details for a type symbol
-//
-void PrintType(IDiaSymbol *pSymbol)
-{
- IDiaSymbol *pBaseType;
- IDiaEnumSymbols *pEnumSym;
- IDiaSymbol *pSym;
- DWORD dwTag;
- BSTR bstrName;
- DWORD dwInfo;
- BOOL bSet;
- DWORD dwRank;
- LONG lCount = 0;
- ULONG celt = 1;
-
- if (pSymbol->get_symTag(&dwTag) != S_OK) {
- wprintf(L"ERROR - can't retrieve the symbol's SymTag\n");
- return;
- }
-
- if (pSymbol->get_name(&bstrName) != S_OK) {
- bstrName = NULL;
- }
-
- if (dwTag != SymTagPointerType) {
- if ((pSymbol->get_constType(&bSet) == S_OK) && bSet) {
- wprintf(L"const ");
- }
-
- if ((pSymbol->get_volatileType(&bSet) == S_OK) && bSet) {
- wprintf(L"volatile ");
- }
-
- if ((pSymbol->get_unalignedType(&bSet) == S_OK) && bSet) {
- wprintf(L"__unaligned ");
- }
- }
-
- ULONGLONG ulLen;
-
- pSymbol->get_length(&ulLen);
-
- switch (dwTag) {
- case SymTagUDT:
- PrintUdtKind(pSymbol);
- PrintName(pSymbol);
- break;
-
- case SymTagEnum:
- wprintf(L"enum ");
- PrintName(pSymbol);
- break;
-
- case SymTagFunctionType:
- wprintf(L"function ");
- break;
-
- case SymTagPointerType:
- if (pSymbol->get_type(&pBaseType) != S_OK) {
- wprintf(L"ERROR - SymTagPointerType get_type");
- if (bstrName != NULL) {
- SysFreeString(bstrName);
- }
- return;
- }
-
- PrintType(pBaseType);
- pBaseType->Release();
-
- if ((pSymbol->get_reference(&bSet) == S_OK) && bSet) {
- wprintf(L" &");
- }
-
- else {
- wprintf(L" *");
- }
-
- if ((pSymbol->get_constType(&bSet) == S_OK) && bSet) {
- wprintf(L" const");
- }
-
- if ((pSymbol->get_volatileType(&bSet) == S_OK) && bSet) {
- wprintf(L" volatile");
- }
-
- if ((pSymbol->get_unalignedType(&bSet) == S_OK) && bSet) {
- wprintf(L" __unaligned");
- }
- break;
-
- case SymTagArrayType:
- if (pSymbol->get_type(&pBaseType) == S_OK) {
- PrintType(pBaseType);
-
- if (pSymbol->get_rank(&dwRank) == S_OK) {
- if (SUCCEEDED(pSymbol->findChildren(SymTagDimension, NULL, nsNone, &pEnumSym)) && (pEnumSym != NULL)) {
- while (SUCCEEDED(pEnumSym->Next(1, &pSym, &celt)) && (celt == 1)) {
- IDiaSymbol *pBound;
-
- wprintf(L"[");
-
- if (pSym->get_lowerBound(&pBound) == S_OK) {
- PrintBound(pBound);
-
- wprintf(L"..");
-
- pBound->Release();
- }
-
- pBound = NULL;
-
- if (pSym->get_upperBound(&pBound) == S_OK) {
- PrintBound(pBound);
-
- pBound->Release();
- }
-
- pSym->Release();
- pSym = NULL;
-
- wprintf(L"]");
- }
-
- pEnumSym->Release();
- }
- }
-
- else if (SUCCEEDED(pSymbol->findChildren(SymTagCustomType, NULL, nsNone, &pEnumSym)) &&
- (pEnumSym != NULL) &&
- (pEnumSym->get_Count(&lCount) == S_OK) &&
- (lCount > 0)) {
- while (SUCCEEDED(pEnumSym->Next(1, &pSym, &celt)) && (celt == 1)) {
- wprintf(L"[");
- PrintType(pSym);
- wprintf(L"]");
-
- pSym->Release();
- }
-
- pEnumSym->Release();
- }
-
- else {
- DWORD dwCountElems;
- ULONGLONG ulLenArray;
- ULONGLONG ulLenElem;
-
- if (pSymbol->get_count(&dwCountElems) == S_OK) {
- wprintf(L"[0x%X]", dwCountElems);
- }
-
- else if ((pSymbol->get_length(&ulLenArray) == S_OK) &&
- (pBaseType->get_length(&ulLenElem) == S_OK)) {
- if (ulLenElem == 0) {
- wprintf(L"[0x%lX]", ulLenArray);
- }
-
- else {
- wprintf(L"[0x%lX]", ulLenArray/ulLenElem);
- }
- }
- }
-
- pBaseType->Release();
- }
-
- else {
- wprintf(L"ERROR - SymTagArrayType get_type\n");
- if (bstrName != NULL) {
- SysFreeString(bstrName);
- }
- return;
- }
- break;
-
- case SymTagBaseType:
- if (pSymbol->get_baseType(&dwInfo) != S_OK) {
- wprintf(L"SymTagBaseType get_baseType\n");
- if (bstrName != NULL) {
- SysFreeString(bstrName);
- }
- return;
- }
-
- switch (dwInfo) {
- case btUInt :
- wprintf(L"unsigned ");
-
- // Fall through
-
- case btInt :
- switch (ulLen) {
- case 1:
- if (dwInfo == btInt) {
- wprintf(L"signed ");
- }
-
- wprintf(L"char");
- break;
-
- case 2:
- wprintf(L"short");
- break;
-
- case 4:
- wprintf(L"int");
- break;
-
- case 8:
- wprintf(L"__int64");
- break;
- }
-
- dwInfo = 0xFFFFFFFF;
- break;
-
- case btFloat :
- switch (ulLen) {
- case 4:
- wprintf(L"float");
- break;
-
- case 8:
- wprintf(L"double");
- break;
- }
-
- dwInfo = 0xFFFFFFFF;
- break;
- }
-
- if (dwInfo == 0xFFFFFFFF) {
- break;
- }
-
- wprintf(L"%s", rgBaseType[dwInfo]);
- break;
-
- case SymTagTypedef:
- PrintName(pSymbol);
- break;
-
- case SymTagCustomType:
- {
- DWORD idOEM, idOEMSym;
- DWORD cbData = 0;
- DWORD count;
-
- if (pSymbol->get_oemId(&idOEM) == S_OK) {
- wprintf(L"OEMId = %X, ", idOEM);
- }
-
- if (pSymbol->get_oemSymbolId(&idOEMSym) == S_OK) {
- wprintf(L"SymbolId = %X, ", idOEMSym);
- }
-
- if (pSymbol->get_types(0, &count, NULL) == S_OK) {
- IDiaSymbol** rgpDiaSymbols = (IDiaSymbol**) _alloca(sizeof(IDiaSymbol *) * count);
-
- if (pSymbol->get_types(count, &count, rgpDiaSymbols) == S_OK) {
- for (ULONG i = 0; i < count; i++) {
- PrintType(rgpDiaSymbols[i]);
- rgpDiaSymbols[i]->Release();
- }
- }
- }
-
- // print custom data
-
- if ((pSymbol->get_dataBytes(cbData, &cbData, NULL) == S_OK) && (cbData != 0)) {
- wprintf(L", Data: ");
-
- BYTE *pbData = new BYTE[cbData];
-
- pSymbol->get_dataBytes(cbData, &cbData, pbData);
-
- for (ULONG i = 0; i < cbData; i++) {
- wprintf(L"0x%02X ", pbData[i]);
- }
-
- delete [] pbData;
- }
- }
- break;
-
- case SymTagData: // This really is member data, just print its location
- PrintLocation(pSymbol);
- break;
- }
-
- if (bstrName != NULL) {
- SysFreeString(bstrName);
- }
-}
-
-////////////////////////////////////////////////////////////
-// Print bound information
-//
-void PrintBound(IDiaSymbol *pSymbol)
-{
- DWORD dwTag = 0;
- DWORD dwKind;
-
- if (pSymbol->get_symTag(&dwTag) != S_OK) {
- wprintf(L"ERROR - PrintBound() get_symTag");
- return;
- }
-
- if (pSymbol->get_locationType(&dwKind) != S_OK) {
- wprintf(L"ERROR - PrintBound() get_locationType");
- return;
- }
-
- if (dwTag == SymTagData && dwKind == LocIsConstant) {
- VARIANT v;
-
- if (pSymbol->get_value(&v) == S_OK) {
- PrintVariant(v);
- VariantClear((VARIANTARG *) &v);
- }
- }
-
- else {
- PrintName(pSymbol);
- }
-}
-
-////////////////////////////////////////////////////////////
-//
-void PrintData(IDiaSymbol *pSymbol, DWORD dwIndent)
-{
- PrintLocation(pSymbol);
-
- DWORD dwDataKind;
- if (pSymbol->get_dataKind(&dwDataKind) != S_OK) {
- wprintf(L"ERROR - PrintData() get_dataKind");
- return;
- }
-
- wprintf(L", %s", SafeDRef(rgDataKind, dwDataKind));
- PrintSymbolType(pSymbol);
-
- wprintf(L", ");
- PrintName(pSymbol);
-}
-
-////////////////////////////////////////////////////////////
-// Print a VARIANT
-//
-void PrintVariant(VARIANT var)
-{
- switch (var.vt) {
- case VT_UI1:
- case VT_I1:
- wprintf(L" 0x%X", var.bVal);
- break;
-
- case VT_I2:
- case VT_UI2:
- case VT_BOOL:
- wprintf(L" 0x%X", var.iVal);
- break;
-
- case VT_I4:
- case VT_UI4:
- case VT_INT:
- case VT_UINT:
- case VT_ERROR:
- wprintf(L" 0x%X", var.lVal);
- break;
-
- case VT_R4:
- wprintf(L" %g", var.fltVal);
- break;
-
- case VT_R8:
- wprintf(L" %g", var.dblVal);
- break;
-
- case VT_BSTR:
- wprintf(L" \"%s\"", var.bstrVal);
- break;
-
- default:
- wprintf(L" ??");
- }
-}
-
-////////////////////////////////////////////////////////////
-// Print a string corresponding to a UDT kind
-//
-void PrintUdtKind(IDiaSymbol *pSymbol)
-{
- DWORD dwKind = 0;
-
- if (pSymbol->get_udtKind(&dwKind) == S_OK) {
- wprintf(L"%s ", rgUdtKind[dwKind]);
- }
-}
-
-////////////////////////////////////////////////////////////
-// Print type informations is details
-//
-void PrintTypeInDetail(IDiaSymbol *pSymbol, DWORD dwIndent)
-{
- IDiaEnumSymbols *pEnumChildren;
- IDiaSymbol *pType;
- IDiaSymbol *pChild;
- DWORD dwSymTag;
- DWORD dwSymTagType;
- ULONG celt = 0;
- BOOL bFlag;
-
- if (dwIndent > MAX_TYPE_IN_DETAIL) {
- return;
- }
-
- if (pSymbol->get_symTag(&dwSymTag) != S_OK) {
- wprintf(L"ERROR - PrintTypeInDetail() get_symTag\n");
- return;
- }
-
- PrintSymTag(dwSymTag);
-
- for (DWORD i = 0;i < dwIndent; i++) {
- putwchar(L' ');
- }
-
- switch (dwSymTag) {
- case SymTagData:
- PrintData(pSymbol, dwIndent);
-
- if (pSymbol->get_type(&pType) == S_OK) {
- if (pType->get_symTag(&dwSymTagType) == S_OK) {
- if (dwSymTagType == SymTagUDT) {
- putwchar(L'\n');
- PrintTypeInDetail(pType, dwIndent + 2);
- }
- }
- pType->Release();
- }
- break;
-
- case SymTagTypedef:
- case SymTagVTable:
- PrintSymbolType(pSymbol);
- break;
-
- case SymTagEnum:
- case SymTagUDT:
- PrintUDT(pSymbol);
- putwchar(L'\n');
-
- if (SUCCEEDED(pSymbol->findChildren(SymTagNull, NULL, nsNone, &pEnumChildren))) {
- while (SUCCEEDED(pEnumChildren->Next(1, &pChild, &celt)) && (celt == 1)) {
- PrintTypeInDetail(pChild, dwIndent + 2);
-
- pChild->Release();
- }
-
- pEnumChildren->Release();
- }
- return;
- break;
-
- case SymTagFunction:
- PrintFunctionType(pSymbol);
- return;
- break;
-
- case SymTagPointerType:
- PrintName(pSymbol);
- wprintf(L" has type ");
- PrintType(pSymbol);
- break;
-
- case SymTagArrayType:
- case SymTagBaseType:
- case SymTagFunctionArgType:
- case SymTagUsingNamespace:
- case SymTagCustom:
- case SymTagFriend:
- PrintName(pSymbol);
- PrintSymbolType(pSymbol);
- break;
-
- case SymTagVTableShape:
- case SymTagBaseClass:
- PrintName(pSymbol);
-
- if ((pSymbol->get_virtualBaseClass(&bFlag) == S_OK) && bFlag) {
- IDiaSymbol *pVBTableType;
- LONG ptrOffset;
- DWORD dispIndex;
-
- if ((pSymbol->get_virtualBaseDispIndex(&dispIndex) == S_OK) &&
- (pSymbol->get_virtualBasePointerOffset(&ptrOffset) == S_OK)) {
- wprintf(L" virtual, offset = 0x%X, pointer offset = %ld, virtual base pointer type = ", dispIndex, ptrOffset);
-
- if (pSymbol->get_virtualBaseTableType(&pVBTableType) == S_OK) {
- PrintType(pVBTableType);
- pVBTableType->Release();
- }
-
- else {
- wprintf(L"(unknown)");
- }
- }
- }
-
- else {
- LONG offset;
-
- if (pSymbol->get_offset(&offset) == S_OK) {
- wprintf(L", offset = 0x%X", offset);
- }
- }
-
- putwchar(L'\n');
-
- if (SUCCEEDED(pSymbol->findChildren(SymTagNull, NULL, nsNone, &pEnumChildren))) {
- while (SUCCEEDED(pEnumChildren->Next(1, &pChild, &celt)) && (celt == 1)) {
- PrintTypeInDetail(pChild, dwIndent + 2);
- pChild->Release();
- }
-
- pEnumChildren->Release();
- }
- break;
-
- case SymTagFunctionType:
- if (pSymbol->get_type(&pType) == S_OK) {
- PrintType(pType);
- }
- break;
-
- case SymTagThunk:
- // Happens for functions which only have S_PROCREF
- PrintThunk(pSymbol);
- break;
-
- default:
- wprintf(L"ERROR - PrintTypeInDetail() invalid SymTag\n");
- }
-
- putwchar(L'\n');
-}
-
-////////////////////////////////////////////////////////////
-// Print a function type
-//
-void PrintFunctionType(IDiaSymbol *pSymbol)
-{
- DWORD dwAccess = 0;
-
- if (pSymbol->get_access(&dwAccess) == S_OK) {
- wprintf(L"%s ", SafeDRef(rgAccess, dwAccess));
- }
-
- BOOL bIsStatic = FALSE;
-
- if ((pSymbol->get_isStatic(&bIsStatic) == S_OK) && bIsStatic) {
- wprintf(L"static ");
- }
-
- IDiaSymbol *pFuncType;
-
- if (pSymbol->get_type(&pFuncType) == S_OK) {
- IDiaSymbol *pReturnType;
-
- if (pFuncType->get_type(&pReturnType) == S_OK) {
- PrintType(pReturnType);
- putwchar(L' ');
-
- BSTR bstrName;
-
- if (pSymbol->get_name(&bstrName) == S_OK) {
- wprintf(L"%s", bstrName);
-
- SysFreeString(bstrName);
- }
-
- IDiaEnumSymbols *pEnumChildren;
-
- if (SUCCEEDED(pFuncType->findChildren(SymTagNull, NULL, nsNone, &pEnumChildren))) {
- IDiaSymbol *pChild;
- ULONG celt = 0;
- ULONG nParam = 0;
-
- wprintf(L"(");
-
- while (SUCCEEDED(pEnumChildren->Next(1, &pChild, &celt)) && (celt == 1)) {
- IDiaSymbol *pType;
-
- if (pChild->get_type(&pType) == S_OK) {
- if (nParam++) {
- wprintf(L", ");
- }
-
- PrintType(pType);
- pType->Release();
- }
-
- pChild->Release();
- }
-
- pEnumChildren->Release();
-
- wprintf(L")\n");
- }
-
- pReturnType->Release();
- }
-
- pFuncType->Release();
- }
-}
-
-////////////////////////////////////////////////////////////
-//
-void PrintSourceFile(IDiaSourceFile *pSource)
-{
- BSTR bstrSourceName;
-
- if (pSource->get_fileName(&bstrSourceName) == S_OK) {
- wprintf(L"\t%s", bstrSourceName);
-
- SysFreeString(bstrSourceName);
- }
-
- else {
- wprintf(L"ERROR - PrintSourceFile() get_fileName");
- return;
- }
-
- BYTE checksum[256];
- DWORD cbChecksum = sizeof(checksum);
-
- if (pSource->get_checksum(cbChecksum, &cbChecksum, checksum) == S_OK) {
- wprintf(L" (");
-
- DWORD checksumType;
-
- if (pSource->get_checksumType(&checksumType) == S_OK) {
- switch (checksumType) {
- case CHKSUM_TYPE_NONE :
- wprintf(L"None");
- break;
-
- case CHKSUM_TYPE_MD5 :
- wprintf(L"MD5");
- break;
-
- case CHKSUM_TYPE_SHA1 :
- wprintf(L"SHA1");
- break;
-
- default :
- wprintf(L"0x%X", checksumType);
- break;
- }
-
- if (cbChecksum != 0) {
- wprintf(L": ");
- }
- }
-
- for (DWORD ib = 0; ib < cbChecksum; ib++) {
- wprintf(L"%02X", checksum[ib]);
- }
-
- wprintf(L")");
- }
-}
-
-////////////////////////////////////////////////////////////
-//
-void PrintLines(IDiaSession *pSession, IDiaSymbol *pFunction)
-{
- DWORD dwSymTag;
-
- if ((pFunction->get_symTag(&dwSymTag) != S_OK) || (dwSymTag != SymTagFunction)) {
- wprintf(L"ERROR - PrintLines() dwSymTag != SymTagFunction");
- return;
- }
-
- BSTR bstrName;
-
- if (pFunction->get_name(&bstrName) == S_OK) {
- wprintf(L"\n** %s\n\n", bstrName);
-
- SysFreeString(bstrName);
- }
-
- ULONGLONG ulLength;
-
- if (pFunction->get_length(&ulLength) != S_OK) {
- wprintf(L"ERROR - PrintLines() get_length");
- return;
- }
-
- DWORD dwRVA;
- IDiaEnumLineNumbers *pLines;
-
- if (pFunction->get_relativeVirtualAddress(&dwRVA) == S_OK) {
- if (SUCCEEDED(pSession->findLinesByRVA(dwRVA, static_cast<DWORD>(ulLength), &pLines))) {
- PrintLines(pLines);
- pLines->Release();
- }
- }
-
- else {
- DWORD dwSect;
- DWORD dwOffset;
-
- if ((pFunction->get_addressSection(&dwSect) == S_OK) &&
- (pFunction->get_addressOffset(&dwOffset) == S_OK)) {
- if (SUCCEEDED(pSession->findLinesByAddr(dwSect, dwOffset, static_cast<DWORD>(ulLength), &pLines))) {
- PrintLines(pLines);
- pLines->Release();
- }
- }
- }
-}
-
-////////////////////////////////////////////////////////////
-//
-void PrintLines(IDiaEnumLineNumbers *pLines)
-{
- IDiaLineNumber *pLine;
- DWORD celt;
- DWORD dwRVA;
- DWORD dwSeg;
- DWORD dwOffset;
- DWORD dwLinenum;
- DWORD dwSrcId;
- DWORD dwLength;
-
- DWORD dwSrcIdLast = (DWORD)(-1);
-
- while (SUCCEEDED(pLines->Next(1, &pLine, &celt)) && (celt == 1)) {
- if ((pLine->get_relativeVirtualAddress(&dwRVA) == S_OK) &&
- (pLine->get_addressSection(&dwSeg) == S_OK) &&
- (pLine->get_addressOffset(&dwOffset) == S_OK) &&
- (pLine->get_lineNumber(&dwLinenum) == S_OK) &&
- (pLine->get_sourceFileId(&dwSrcId) == S_OK) &&
- (pLine->get_length(&dwLength) == S_OK)) {
- wprintf(L"\tline %u at [%08X][%04X:%08X], len = 0x%X", dwLinenum, dwRVA, dwSeg, dwOffset, dwLength);
-
- if (dwSrcId != dwSrcIdLast) {
- IDiaSourceFile *pSource;
-
- if (pLine->get_sourceFile(&pSource) == S_OK) {
- PrintSourceFile(pSource);
-
- dwSrcIdLast = dwSrcId;
-
- pSource->Release();
- }
- }
-
- pLine->Release();
-
- putwchar(L'\n');
- }
- }
-}
-
-////////////////////////////////////////////////////////////
-// Print the section contribution data: name, Sec::Off, length
-void PrintSecContribs(IDiaSectionContrib *pSegment)
-{
- DWORD dwRVA;
- DWORD dwSect;
- DWORD dwOffset;
- DWORD dwLen;
- IDiaSymbol *pCompiland;
- BSTR bstrName;
-
- if ((pSegment->get_relativeVirtualAddress(&dwRVA) == S_OK) &&
- (pSegment->get_addressSection(&dwSect) == S_OK) &&
- (pSegment->get_addressOffset(&dwOffset) == S_OK) &&
- (pSegment->get_length(&dwLen) == S_OK) &&
- (pSegment->get_compiland(&pCompiland) == S_OK) &&
- (pCompiland->get_name(&bstrName) == S_OK)) {
- wprintf(L" %08X %04X:%08X %08X %s\n", dwRVA, dwSect, dwOffset, dwLen, bstrName);
-
- pCompiland->Release();
-
- SysFreeString(bstrName);
- }
-}
-
-////////////////////////////////////////////////////////////
-// Print a debug stream data
-//
-void PrintStreamData(IDiaEnumDebugStreamData *pStream)
-{
- BSTR bstrName;
-
- if (pStream->get_name(&bstrName) != S_OK) {
- wprintf(L"ERROR - PrintStreamData() get_name\n");
- }
-
- else {
- wprintf(L"Stream: %s", bstrName);
-
- SysFreeString(bstrName);
- }
-
- LONG dwElem;
-
- if (pStream->get_Count(&dwElem) != S_OK) {
- wprintf(L"ERROR - PrintStreamData() get_Count\n");
- }
-
- else {
- wprintf(L"(%u)\n", dwElem);
- }
-
- DWORD cbTotal = 0;
-
- BYTE data[1024];
- DWORD cbData;
- ULONG celt = 0;
-
- while (SUCCEEDED(pStream->Next(1, sizeof(data), &cbData, (BYTE *) &data, &celt)) && (celt == 1)) {
- DWORD i;
-
- for (i = 0; i < cbData; i++) {
- wprintf(L"%02X ", data[i]);
-
- if (i && (i % 8 == 7) && (i+1 < cbData)) {
- wprintf(L"- ");
- }
- }
-
- wprintf(L"| ");
-
- for (i = 0; i < cbData; i++) {
- wprintf(L"%c", iswprint(data[i]) ? data[i] : '.');
- }
-
- putwchar(L'\n');
-
- cbTotal += cbData;
- }
-
- wprintf(L"Summary :\n\tNo of Elems = %u\n", dwElem);
- if (dwElem != 0) {
- wprintf(L"\tSizeof(Elem) = %u\n", cbTotal / dwElem);
- }
- putwchar(L'\n');
-}
-
-////////////////////////////////////////////////////////////
-// Print the FPO info for a given symbol;
-//
-void PrintFrameData(IDiaFrameData *pFrameData)
-{
- DWORD dwSect;
- DWORD dwOffset;
- DWORD cbBlock;
- DWORD cbLocals; // Number of bytes reserved for the function locals
- DWORD cbParams; // Number of bytes reserved for the function arguments
- DWORD cbMaxStack;
- DWORD cbProlog;
- DWORD cbSavedRegs;
- BOOL bSEH;
- BOOL bEH;
- BOOL bStart;
-
- if ((pFrameData->get_addressSection(&dwSect) == S_OK) &&
- (pFrameData->get_addressOffset(&dwOffset) == S_OK) &&
- (pFrameData->get_lengthBlock(&cbBlock) == S_OK) &&
- (pFrameData->get_lengthLocals(&cbLocals) == S_OK) &&
- (pFrameData->get_lengthParams(&cbParams) == S_OK) &&
- (pFrameData->get_maxStack(&cbMaxStack) == S_OK) &&
- (pFrameData->get_lengthProlog(&cbProlog) == S_OK) &&
- (pFrameData->get_lengthSavedRegisters(&cbSavedRegs) == S_OK) &&
- (pFrameData->get_systemExceptionHandling(&bSEH) == S_OK) &&
- (pFrameData->get_cplusplusExceptionHandling(&bEH) == S_OK) &&
- (pFrameData->get_functionStart(&bStart) == S_OK)) {
- wprintf(L"%04X:%08X %8X %8X %8X %8X %8X %8X %c %c %c",
- dwSect, dwOffset, cbBlock, cbLocals, cbParams, cbMaxStack, cbProlog, cbSavedRegs,
- bSEH ? L'Y' : L'N',
- bEH ? L'Y' : L'N',
- bStart ? L'Y' : L'N');
-
- BSTR bstrProgram;
-
- if (pFrameData->get_program(&bstrProgram) == S_OK) {
- wprintf(L" %s", bstrProgram);
-
- SysFreeString(bstrProgram);
- }
-
- putwchar(L'\n');
- }
-}
-
-////////////////////////////////////////////////////////////
-// Print all the valid properties associated to a symbol
-//
-void PrintPropertyStorage(IDiaPropertyStorage *pPropertyStorage)
-{
- IEnumSTATPROPSTG *pEnumProps;
-
- if (SUCCEEDED(pPropertyStorage->Enum(&pEnumProps))) {
- STATPROPSTG prop;
- DWORD celt = 1;
-
- while (SUCCEEDED(pEnumProps->Next(celt, &prop, &celt)) && (celt == 1)) {
- PROPSPEC pspec = { PRSPEC_PROPID, prop.propid };
- PROPVARIANT vt = { VT_EMPTY };
-
- if (SUCCEEDED(pPropertyStorage->ReadMultiple(1, &pspec, &vt))) {
- switch (vt.vt) {
- case VT_BOOL:
- wprintf(L"%32s:\t %s\n", prop.lpwstrName, vt.bVal ? L"true" : L"false");
- break;
-
- case VT_I2:
- wprintf(L"%32s:\t %d\n", prop.lpwstrName, vt.iVal);
- break;
-
- case VT_UI2:
- wprintf(L"%32s:\t %u\n", prop.lpwstrName, vt.uiVal);
- break;
-
- case VT_I4:
- wprintf(L"%32s:\t %d\n", prop.lpwstrName, vt.intVal);
- break;
-
- case VT_UI4:
- wprintf(L"%32s:\t 0x%0X\n", prop.lpwstrName, vt.uintVal);
- break;
-
- case VT_UI8:
- wprintf(L"%32s:\t 0x%X\n", prop.lpwstrName, vt.uhVal.QuadPart);
- break;
-
- case VT_BSTR:
- wprintf(L"%32s:\t %s\n", prop.lpwstrName, vt.bstrVal);
- break;
-
- case VT_UNKNOWN:
- wprintf(L"%32s:\t %p\n", prop.lpwstrName, vt.punkVal);
- break;
-
- case VT_SAFEARRAY:
- break;
- }
-
- VariantClear((VARIANTARG *) &vt);
- }
-
- SysFreeString( prop.lpwstrName );
- }
-
- pEnumProps->Release();
- }
-}
diff --git a/src/ToolBox/PdbTypeMatch/PrintSymbol.h b/src/ToolBox/PdbTypeMatch/PrintSymbol.h
deleted file mode 100644
index 5a39460f3f..0000000000
--- a/src/ToolBox/PdbTypeMatch/PrintSymbol.h
+++ /dev/null
@@ -1,66 +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 <string>
-
-inline int myDebugBreak( int ){
- DebugBreak();
- return 0;
-}
-#define MAXELEMS(x) (sizeof(x)/sizeof(x[0]))
-#define SafeDRef(a, i) ((i < MAXELEMS(a)) ? a[i] : a[myDebugBreak(i)])
-
-#define MAX_TYPE_IN_DETAIL 5
-#define MAX_RVA_LINES_BYTES_RANGE 0x100
-
-extern const wchar_t * const rgBaseType[];
-extern const wchar_t * const rgTags[];
-extern const wchar_t * const rgFloatPackageStrings[];
-extern const wchar_t * const rgProcessorStrings[];
-extern const wchar_t * const rgDataKind[];
-extern const wchar_t * const rgUdtKind[];
-extern const wchar_t * const rgAccess[];
-extern const wchar_t * const rgCallingConvention[];
-extern const wchar_t * const rgLanguage[];
-extern const wchar_t * const rgLocationTypeString[];
-
-void PrintPublicSymbol( IDiaSymbol* );
-void PrintGlobalSymbol( IDiaSymbol* );
-void PrintSymbol( IDiaSymbol* , DWORD );
-void GetSymbolName(std::wstring& symbolName, IDiaSymbol *pSymbol);
-void PrintSymTag( DWORD );
-void PrintName( IDiaSymbol* );
-void PrintUndName( IDiaSymbol* );
-void PrintThunk( IDiaSymbol* );
-void PrintCompilandDetails( IDiaSymbol* );
-void PrintCompilandEnv( IDiaSymbol* );
-void PrintLocation( IDiaSymbol* );
-void PrintConst( IDiaSymbol* );
-void PrintUDT( IDiaSymbol* );
-void PrintSymbolType( IDiaSymbol* );
-void PrintType( IDiaSymbol* );
-void PrintBound( IDiaSymbol* );
-void PrintData( IDiaSymbol* , DWORD );
-void PrintVariant( VARIANT );
-void PrintUdtKind( IDiaSymbol* );
-void PrintTypeInDetail( IDiaSymbol* , DWORD );
-void PrintFunctionType( IDiaSymbol* );
-void PrintSourceFile( IDiaSourceFile* );
-void PrintLines( IDiaSession* , IDiaSymbol* );
-void PrintLines( IDiaEnumLineNumbers* );
-void PrintSource( IDiaSourceFile* );
-void PrintSecContribs( IDiaSectionContrib* );
-void PrintStreamData( IDiaEnumDebugStreamData* );
-void PrintFrameData( IDiaFrameData* );
-
-void PrintPropertyStorage( IDiaPropertyStorage* );
-
-template<class T> void PrintGeneric( T t ){
- IDiaPropertyStorage* pPropertyStorage;
-
- if(t->QueryInterface( __uuidof(IDiaPropertyStorage), (void **)&pPropertyStorage ) == S_OK){
- PrintPropertyStorage(pPropertyStorage);
- pPropertyStorage->Release();
- }
-}
diff --git a/src/ToolBox/PdbTypeMatch/callback.h b/src/ToolBox/PdbTypeMatch/callback.h
deleted file mode 100644
index 34ea3d80c0..0000000000
--- a/src/ToolBox/PdbTypeMatch/callback.h
+++ /dev/null
@@ -1,96 +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 "dia2.h"
-
-#pragma warning ( disable : 4100)
-
-class CCallback : public IDiaLoadCallback2{
- int m_nRefCount;
-public:
- CCallback() { m_nRefCount = 0; }
-
- //IUnknown
- ULONG STDMETHODCALLTYPE AddRef() {
- m_nRefCount++;
- return m_nRefCount;
- }
- ULONG STDMETHODCALLTYPE Release() {
- ULONG newRefCount = --m_nRefCount;
- if ( newRefCount == 0 )
- delete this;
- return newRefCount;
- }
- HRESULT STDMETHODCALLTYPE QueryInterface( REFIID rid, void **ppUnk ) {
- if ( ppUnk == NULL ) {
- return E_POINTER;
- }
- if (rid == __uuidof( IDiaLoadCallback2 ) )
- *ppUnk = (IDiaLoadCallback2 *)this;
- else if (rid == __uuidof( IDiaLoadCallback ) )
- *ppUnk = (IDiaLoadCallback *)this;
- else if (rid == __uuidof( IUnknown ) )
- *ppUnk = (IUnknown *)this;
- else
- *ppUnk = NULL;
- if ( *ppUnk != NULL ) {
- AddRef();
- return S_OK;
- }
- return E_NOINTERFACE;
- }
-
- HRESULT STDMETHODCALLTYPE NotifyDebugDir(
- BOOL fExecutable,
- DWORD cbData,
- BYTE data[]) // really a const struct _IMAGE_DEBUG_DIRECTORY *
- {
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE NotifyOpenDBG(
- LPCOLESTR dbgPath,
- HRESULT resultCode)
- {
- // wprintf(L"opening %s...\n", dbgPath);
- return S_OK;
- }
-
- HRESULT STDMETHODCALLTYPE NotifyOpenPDB(
- LPCOLESTR pdbPath,
- HRESULT resultCode)
- {
- // wprintf(L"opening %s...\n", pdbPath);
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE RestrictRegistryAccess()
- {
- // return hr != S_OK to prevent querying the registry for symbol search paths
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE RestrictSymbolServerAccess()
- {
- // return hr != S_OK to prevent accessing a symbol server
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE RestrictOriginalPathAccess()
- {
- // return hr != S_OK to prevent querying the registry for symbol search paths
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE RestrictReferencePathAccess()
- {
- // return hr != S_OK to prevent accessing a symbol server
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE RestrictDBGAccess()
- {
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE RestrictSystemRootAccess()
- {
- return S_OK;
- }
-};
-
-#pragma warning ( default : 4100 )
diff --git a/src/ToolBox/PdbTypeMatch/include/cvconst.h b/src/ToolBox/PdbTypeMatch/include/cvconst.h
deleted file mode 100644
index 6356197c81..0000000000
--- a/src/ToolBox/PdbTypeMatch/include/cvconst.h
+++ /dev/null
@@ -1,3181 +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.
-// cvconst.h - codeview constant definitions
-
-#ifndef _CVCONST_H_
-#define _CVCONST_H_
-
-
-
-// Enumeration for function call type
-
-
-typedef enum CV_call_e {
- CV_CALL_NEAR_C = 0x00, // near right to left push, caller pops stack
- CV_CALL_FAR_C = 0x01, // far right to left push, caller pops stack
- CV_CALL_NEAR_PASCAL = 0x02, // near left to right push, callee pops stack
- CV_CALL_FAR_PASCAL = 0x03, // far left to right push, callee pops stack
- CV_CALL_NEAR_FAST = 0x04, // near left to right push with regs, callee pops stack
- CV_CALL_FAR_FAST = 0x05, // far left to right push with regs, callee pops stack
- CV_CALL_SKIPPED = 0x06, // skipped (unused) call index
- CV_CALL_NEAR_STD = 0x07, // near standard call
- CV_CALL_FAR_STD = 0x08, // far standard call
- CV_CALL_NEAR_SYS = 0x09, // near sys call
- CV_CALL_FAR_SYS = 0x0a, // far sys call
- CV_CALL_THISCALL = 0x0b, // this call (this passed in register)
- CV_CALL_MIPSCALL = 0x0c, // Mips call
- CV_CALL_GENERIC = 0x0d, // Generic call sequence
- CV_CALL_ALPHACALL = 0x0e, // Alpha call
- CV_CALL_PPCCALL = 0x0f, // PPC call
- CV_CALL_SHCALL = 0x10, // Hitachi SuperH call
- CV_CALL_ARMCALL = 0x11, // ARM call
- CV_CALL_AM33CALL = 0x12, // AM33 call
- CV_CALL_TRICALL = 0x13, // TriCore Call
- CV_CALL_SH5CALL = 0x14, // Hitachi SuperH-5 call
- CV_CALL_M32RCALL = 0x15, // M32R Call
- CV_CALL_CLRCALL = 0x16, // clr call
- CV_CALL_RESERVED = 0x17 // first unused call enumeration
-
- // Do NOT add any more machine specific conventions. This is to be used for
- // calling conventions in the source only (e.g. __cdecl, __stdcall).
-} CV_call_e;
-
-
-// Values for the access protection of class attributes
-
-
-typedef enum CV_access_e {
- CV_private = 1,
- CV_protected = 2,
- CV_public = 3
-} CV_access_e;
-
-typedef enum THUNK_ORDINAL {
- THUNK_ORDINAL_NOTYPE, // standard thunk
- THUNK_ORDINAL_ADJUSTOR, // "this" adjustor thunk
- THUNK_ORDINAL_VCALL, // virtual call thunk
- THUNK_ORDINAL_PCODE, // pcode thunk
- THUNK_ORDINAL_LOAD, // thunk which loads the address to jump to
- // via unknown means...
-
- // trampoline thunk ordinals - only for use in Trampoline thunk symbols
- THUNK_ORDINAL_TRAMP_INCREMENTAL,
- THUNK_ORDINAL_TRAMP_BRANCHISLAND,
-
-} THUNK_ORDINAL;
-
-
-enum CV_SourceChksum_t {
- CHKSUM_TYPE_NONE = 0, // indicates no checksum is available
- CHKSUM_TYPE_MD5,
- CHKSUM_TYPE_SHA1
-};
-
-//
-// DIA enums
-//
-
-enum SymTagEnum
-{
- SymTagNull,
- SymTagExe,
- SymTagCompiland,
- SymTagCompilandDetails,
- SymTagCompilandEnv,
- SymTagFunction,
- SymTagBlock,
- SymTagData,
- SymTagAnnotation,
- SymTagLabel,
- SymTagPublicSymbol,
- SymTagUDT,
- SymTagEnum,
- SymTagFunctionType,
- SymTagPointerType,
- SymTagArrayType,
- SymTagBaseType,
- SymTagTypedef,
- SymTagBaseClass,
- SymTagFriend,
- SymTagFunctionArgType,
- SymTagFuncDebugStart,
- SymTagFuncDebugEnd,
- SymTagUsingNamespace,
- SymTagVTableShape,
- SymTagVTable,
- SymTagCustom,
- SymTagThunk,
- SymTagCustomType,
- SymTagManagedType,
- SymTagDimension,
- SymTagCallSite,
- SymTagMax
-};
-
-enum LocationType
-{
- LocIsNull,
- LocIsStatic,
- LocIsTLS,
- LocIsRegRel,
- LocIsThisRel,
- LocIsEnregistered,
- LocIsBitField,
- LocIsSlot,
- LocIsIlRel,
- LocInMetaData,
- LocIsConstant,
- LocTypeMax
-};
-
-enum DataKind
-{
- DataIsUnknown,
- DataIsLocal,
- DataIsStaticLocal,
- DataIsParam,
- DataIsObjectPtr,
- DataIsFileStatic,
- DataIsGlobal,
- DataIsMember,
- DataIsStaticMember,
- DataIsConstant
-};
-
-enum UdtKind
-{
- UdtStruct,
- UdtClass,
- UdtUnion
-};
-
-enum BasicType
-{
- btNoType = 0,
- btVoid = 1,
- btChar = 2,
- btWChar = 3,
- btInt = 6,
- btUInt = 7,
- btFloat = 8,
- btBCD = 9,
- btBool = 10,
- btLong = 13,
- btULong = 14,
- btCurrency = 25,
- btDate = 26,
- btVariant = 27,
- btComplex = 28,
- btBit = 29,
- btBSTR = 30,
- btHresult = 31
-};
-
-
-// enum describing the compile flag source language
-
-
-typedef enum CV_CFL_LANG {
- CV_CFL_C = 0x00,
- CV_CFL_CXX = 0x01,
- CV_CFL_FORTRAN = 0x02,
- CV_CFL_MASM = 0x03,
- CV_CFL_PASCAL = 0x04,
- CV_CFL_BASIC = 0x05,
- CV_CFL_COBOL = 0x06,
- CV_CFL_LINK = 0x07,
- CV_CFL_CVTRES = 0x08,
- CV_CFL_CVTPGD = 0x09,
- CV_CFL_CSHARP = 0x0A, // C#
- CV_CFL_VB = 0x0B, // Visual Basic
- CV_CFL_ILASM = 0x0C, // IL (as in CLR) ASM
- CV_CFL_JAVA = 0x0D,
- CV_CFL_JSCRIPT = 0x0E,
- CV_CFL_MSIL = 0x0F, // Unknown MSIL (LTCG of .NETMODULE)
-} CV_CFL_LANG;
-
-
-// enum describing target processor
-
-
-typedef enum CV_CPU_TYPE_e {
- CV_CFL_8080 = 0x00,
- CV_CFL_8086 = 0x01,
- CV_CFL_80286 = 0x02,
- CV_CFL_80386 = 0x03,
- CV_CFL_80486 = 0x04,
- CV_CFL_PENTIUM = 0x05,
- CV_CFL_PENTIUMII = 0x06,
- CV_CFL_PENTIUMPRO = CV_CFL_PENTIUMII,
- CV_CFL_PENTIUMIII = 0x07,
- CV_CFL_MIPS = 0x10,
- CV_CFL_MIPSR4000 = CV_CFL_MIPS, // don't break current code
- CV_CFL_MIPS16 = 0x11,
- CV_CFL_MIPS32 = 0x12,
- CV_CFL_MIPS64 = 0x13,
- CV_CFL_MIPSI = 0x14,
- CV_CFL_MIPSII = 0x15,
- CV_CFL_MIPSIII = 0x16,
- CV_CFL_MIPSIV = 0x17,
- CV_CFL_MIPSV = 0x18,
- CV_CFL_M68000 = 0x20,
- CV_CFL_M68010 = 0x21,
- CV_CFL_M68020 = 0x22,
- CV_CFL_M68030 = 0x23,
- CV_CFL_M68040 = 0x24,
- CV_CFL_ALPHA = 0x30,
- CV_CFL_ALPHA_21064 = 0x30,
- CV_CFL_ALPHA_21164 = 0x31,
- CV_CFL_ALPHA_21164A = 0x32,
- CV_CFL_ALPHA_21264 = 0x33,
- CV_CFL_ALPHA_21364 = 0x34,
- CV_CFL_PPC601 = 0x40,
- CV_CFL_PPC603 = 0x41,
- CV_CFL_PPC604 = 0x42,
- CV_CFL_PPC620 = 0x43,
- CV_CFL_PPCFP = 0x44,
- CV_CFL_PPCBE = 0x45,
- CV_CFL_SH3 = 0x50,
- CV_CFL_SH3E = 0x51,
- CV_CFL_SH3DSP = 0x52,
- CV_CFL_SH4 = 0x53,
- CV_CFL_SHMEDIA = 0x54,
- CV_CFL_ARM3 = 0x60,
- CV_CFL_ARM4 = 0x61,
- CV_CFL_ARM4T = 0x62,
- CV_CFL_ARM5 = 0x63,
- CV_CFL_ARM5T = 0x64,
- CV_CFL_ARM6 = 0x65,
- CV_CFL_ARM_XMAC = 0x66,
- CV_CFL_ARM_WMMX = 0x67,
- CV_CFL_ARM7 = 0x68,
- CV_CFL_OMNI = 0x70,
- CV_CFL_IA64 = 0x80,
- CV_CFL_IA64_1 = 0x80,
- CV_CFL_IA64_2 = 0x81,
- CV_CFL_CEE = 0x90,
- CV_CFL_AM33 = 0xA0,
- CV_CFL_M32R = 0xB0,
- CV_CFL_TRICORE = 0xC0,
- CV_CFL_X64 = 0xD0,
- CV_CFL_AMD64 = CV_CFL_X64,
- CV_CFL_EBC = 0xE0,
- CV_CFL_THUMB = 0xF0,
-} CV_CPU_TYPE_e;
-
-typedef enum CV_HREG_e {
- // Register subset shared by all processor types,
- // must not overlap with any of the ranges below, hence the high values
-
- CV_ALLREG_ERR = 30000,
- CV_ALLREG_TEB = 30001,
- CV_ALLREG_TIMER = 30002,
- CV_ALLREG_EFAD1 = 30003,
- CV_ALLREG_EFAD2 = 30004,
- CV_ALLREG_EFAD3 = 30005,
- CV_ALLREG_VFRAME= 30006,
- CV_ALLREG_HANDLE= 30007,
- CV_ALLREG_PARAMS= 30008,
- CV_ALLREG_LOCALS= 30009,
- CV_ALLREG_TID = 30010,
- CV_ALLREG_ENV = 30011,
- CV_ALLREG_CMDLN = 30012,
-
-
- // Register set for the Intel 80x86 and ix86 processor series
- // (plus PCODE registers)
-
- CV_REG_NONE = 0,
- CV_REG_AL = 1,
- CV_REG_CL = 2,
- CV_REG_DL = 3,
- CV_REG_BL = 4,
- CV_REG_AH = 5,
- CV_REG_CH = 6,
- CV_REG_DH = 7,
- CV_REG_BH = 8,
- CV_REG_AX = 9,
- CV_REG_CX = 10,
- CV_REG_DX = 11,
- CV_REG_BX = 12,
- CV_REG_SP = 13,
- CV_REG_BP = 14,
- CV_REG_SI = 15,
- CV_REG_DI = 16,
- CV_REG_EAX = 17,
- CV_REG_ECX = 18,
- CV_REG_EDX = 19,
- CV_REG_EBX = 20,
- CV_REG_ESP = 21,
- CV_REG_EBP = 22,
- CV_REG_ESI = 23,
- CV_REG_EDI = 24,
- CV_REG_ES = 25,
- CV_REG_CS = 26,
- CV_REG_SS = 27,
- CV_REG_DS = 28,
- CV_REG_FS = 29,
- CV_REG_GS = 30,
- CV_REG_IP = 31,
- CV_REG_FLAGS = 32,
- CV_REG_EIP = 33,
- CV_REG_EFLAGS = 34,
- CV_REG_TEMP = 40, // PCODE Temp
- CV_REG_TEMPH = 41, // PCODE TempH
- CV_REG_QUOTE = 42, // PCODE Quote
- CV_REG_PCDR3 = 43, // PCODE reserved
- CV_REG_PCDR4 = 44, // PCODE reserved
- CV_REG_PCDR5 = 45, // PCODE reserved
- CV_REG_PCDR6 = 46, // PCODE reserved
- CV_REG_PCDR7 = 47, // PCODE reserved
- CV_REG_CR0 = 80, // CR0 -- control registers
- CV_REG_CR1 = 81,
- CV_REG_CR2 = 82,
- CV_REG_CR3 = 83,
- CV_REG_CR4 = 84, // Pentium
- CV_REG_DR0 = 90, // Debug register
- CV_REG_DR1 = 91,
- CV_REG_DR2 = 92,
- CV_REG_DR3 = 93,
- CV_REG_DR4 = 94,
- CV_REG_DR5 = 95,
- CV_REG_DR6 = 96,
- CV_REG_DR7 = 97,
- CV_REG_GDTR = 110,
- CV_REG_GDTL = 111,
- CV_REG_IDTR = 112,
- CV_REG_IDTL = 113,
- CV_REG_LDTR = 114,
- CV_REG_TR = 115,
-
- CV_REG_PSEUDO1 = 116,
- CV_REG_PSEUDO2 = 117,
- CV_REG_PSEUDO3 = 118,
- CV_REG_PSEUDO4 = 119,
- CV_REG_PSEUDO5 = 120,
- CV_REG_PSEUDO6 = 121,
- CV_REG_PSEUDO7 = 122,
- CV_REG_PSEUDO8 = 123,
- CV_REG_PSEUDO9 = 124,
-
- CV_REG_ST0 = 128,
- CV_REG_ST1 = 129,
- CV_REG_ST2 = 130,
- CV_REG_ST3 = 131,
- CV_REG_ST4 = 132,
- CV_REG_ST5 = 133,
- CV_REG_ST6 = 134,
- CV_REG_ST7 = 135,
- CV_REG_CTRL = 136,
- CV_REG_STAT = 137,
- CV_REG_TAG = 138,
- CV_REG_FPIP = 139,
- CV_REG_FPCS = 140,
- CV_REG_FPDO = 141,
- CV_REG_FPDS = 142,
- CV_REG_ISEM = 143,
- CV_REG_FPEIP = 144,
- CV_REG_FPEDO = 145,
-
- CV_REG_MM0 = 146,
- CV_REG_MM1 = 147,
- CV_REG_MM2 = 148,
- CV_REG_MM3 = 149,
- CV_REG_MM4 = 150,
- CV_REG_MM5 = 151,
- CV_REG_MM6 = 152,
- CV_REG_MM7 = 153,
-
- CV_REG_XMM0 = 154, // KATMAI registers
- CV_REG_XMM1 = 155,
- CV_REG_XMM2 = 156,
- CV_REG_XMM3 = 157,
- CV_REG_XMM4 = 158,
- CV_REG_XMM5 = 159,
- CV_REG_XMM6 = 160,
- CV_REG_XMM7 = 161,
-
- CV_REG_XMM00 = 162, // KATMAI sub-registers
- CV_REG_XMM01 = 163,
- CV_REG_XMM02 = 164,
- CV_REG_XMM03 = 165,
- CV_REG_XMM10 = 166,
- CV_REG_XMM11 = 167,
- CV_REG_XMM12 = 168,
- CV_REG_XMM13 = 169,
- CV_REG_XMM20 = 170,
- CV_REG_XMM21 = 171,
- CV_REG_XMM22 = 172,
- CV_REG_XMM23 = 173,
- CV_REG_XMM30 = 174,
- CV_REG_XMM31 = 175,
- CV_REG_XMM32 = 176,
- CV_REG_XMM33 = 177,
- CV_REG_XMM40 = 178,
- CV_REG_XMM41 = 179,
- CV_REG_XMM42 = 180,
- CV_REG_XMM43 = 181,
- CV_REG_XMM50 = 182,
- CV_REG_XMM51 = 183,
- CV_REG_XMM52 = 184,
- CV_REG_XMM53 = 185,
- CV_REG_XMM60 = 186,
- CV_REG_XMM61 = 187,
- CV_REG_XMM62 = 188,
- CV_REG_XMM63 = 189,
- CV_REG_XMM70 = 190,
- CV_REG_XMM71 = 191,
- CV_REG_XMM72 = 192,
- CV_REG_XMM73 = 193,
-
- CV_REG_XMM0L = 194,
- CV_REG_XMM1L = 195,
- CV_REG_XMM2L = 196,
- CV_REG_XMM3L = 197,
- CV_REG_XMM4L = 198,
- CV_REG_XMM5L = 199,
- CV_REG_XMM6L = 200,
- CV_REG_XMM7L = 201,
-
- CV_REG_XMM0H = 202,
- CV_REG_XMM1H = 203,
- CV_REG_XMM2H = 204,
- CV_REG_XMM3H = 205,
- CV_REG_XMM4H = 206,
- CV_REG_XMM5H = 207,
- CV_REG_XMM6H = 208,
- CV_REG_XMM7H = 209,
-
- CV_REG_MXCSR = 211, // XMM status register
-
- CV_REG_EDXEAX = 212, // EDX:EAX pair
-
- CV_REG_EMM0L = 220, // XMM sub-registers (WNI integer)
- CV_REG_EMM1L = 221,
- CV_REG_EMM2L = 222,
- CV_REG_EMM3L = 223,
- CV_REG_EMM4L = 224,
- CV_REG_EMM5L = 225,
- CV_REG_EMM6L = 226,
- CV_REG_EMM7L = 227,
-
- CV_REG_EMM0H = 228,
- CV_REG_EMM1H = 229,
- CV_REG_EMM2H = 230,
- CV_REG_EMM3H = 231,
- CV_REG_EMM4H = 232,
- CV_REG_EMM5H = 233,
- CV_REG_EMM6H = 234,
- CV_REG_EMM7H = 235,
-
- // do not change the order of these regs, first one must be even too
- CV_REG_MM00 = 236,
- CV_REG_MM01 = 237,
- CV_REG_MM10 = 238,
- CV_REG_MM11 = 239,
- CV_REG_MM20 = 240,
- CV_REG_MM21 = 241,
- CV_REG_MM30 = 242,
- CV_REG_MM31 = 243,
- CV_REG_MM40 = 244,
- CV_REG_MM41 = 245,
- CV_REG_MM50 = 246,
- CV_REG_MM51 = 247,
- CV_REG_MM60 = 248,
- CV_REG_MM61 = 249,
- CV_REG_MM70 = 250,
- CV_REG_MM71 = 251,
-
- CV_REG_YMM0 = 252, // AVX registers
- CV_REG_YMM1 = 253,
- CV_REG_YMM2 = 254,
- CV_REG_YMM3 = 255,
- CV_REG_YMM4 = 256,
- CV_REG_YMM5 = 257,
- CV_REG_YMM6 = 258,
- CV_REG_YMM7 = 259,
-
- CV_REG_YMM0H = 260,
- CV_REG_YMM1H = 261,
- CV_REG_YMM2H = 262,
- CV_REG_YMM3H = 263,
- CV_REG_YMM4H = 264,
- CV_REG_YMM5H = 265,
- CV_REG_YMM6H = 266,
- CV_REG_YMM7H = 267,
-
- CV_REG_YMM0I0 = 268, // AVX integer registers
- CV_REG_YMM0I1 = 269,
- CV_REG_YMM0I2 = 270,
- CV_REG_YMM0I3 = 271,
- CV_REG_YMM1I0 = 272,
- CV_REG_YMM1I1 = 273,
- CV_REG_YMM1I2 = 274,
- CV_REG_YMM1I3 = 275,
- CV_REG_YMM2I0 = 276,
- CV_REG_YMM2I1 = 277,
- CV_REG_YMM2I2 = 278,
- CV_REG_YMM2I3 = 279,
- CV_REG_YMM3I0 = 280,
- CV_REG_YMM3I1 = 281,
- CV_REG_YMM3I2 = 282,
- CV_REG_YMM3I3 = 283,
- CV_REG_YMM4I0 = 284,
- CV_REG_YMM4I1 = 285,
- CV_REG_YMM4I2 = 286,
- CV_REG_YMM4I3 = 287,
- CV_REG_YMM5I0 = 288,
- CV_REG_YMM5I1 = 289,
- CV_REG_YMM5I2 = 290,
- CV_REG_YMM5I3 = 291,
- CV_REG_YMM6I0 = 292,
- CV_REG_YMM6I1 = 293,
- CV_REG_YMM6I2 = 294,
- CV_REG_YMM6I3 = 295,
- CV_REG_YMM7I0 = 296,
- CV_REG_YMM7I1 = 297,
- CV_REG_YMM7I2 = 298,
- CV_REG_YMM7I3 = 299,
-
- CV_REG_YMM0F0 = 300, // AVX floating-point single precise registers
- CV_REG_YMM0F1 = 301,
- CV_REG_YMM0F2 = 302,
- CV_REG_YMM0F3 = 303,
- CV_REG_YMM0F4 = 304,
- CV_REG_YMM0F5 = 305,
- CV_REG_YMM0F6 = 306,
- CV_REG_YMM0F7 = 307,
- CV_REG_YMM1F0 = 308,
- CV_REG_YMM1F1 = 309,
- CV_REG_YMM1F2 = 310,
- CV_REG_YMM1F3 = 311,
- CV_REG_YMM1F4 = 312,
- CV_REG_YMM1F5 = 313,
- CV_REG_YMM1F6 = 314,
- CV_REG_YMM1F7 = 315,
- CV_REG_YMM2F0 = 316,
- CV_REG_YMM2F1 = 317,
- CV_REG_YMM2F2 = 318,
- CV_REG_YMM2F3 = 319,
- CV_REG_YMM2F4 = 320,
- CV_REG_YMM2F5 = 321,
- CV_REG_YMM2F6 = 322,
- CV_REG_YMM2F7 = 323,
- CV_REG_YMM3F0 = 324,
- CV_REG_YMM3F1 = 325,
- CV_REG_YMM3F2 = 326,
- CV_REG_YMM3F3 = 327,
- CV_REG_YMM3F4 = 328,
- CV_REG_YMM3F5 = 329,
- CV_REG_YMM3F6 = 330,
- CV_REG_YMM3F7 = 331,
- CV_REG_YMM4F0 = 332,
- CV_REG_YMM4F1 = 333,
- CV_REG_YMM4F2 = 334,
- CV_REG_YMM4F3 = 335,
- CV_REG_YMM4F4 = 336,
- CV_REG_YMM4F5 = 337,
- CV_REG_YMM4F6 = 338,
- CV_REG_YMM4F7 = 339,
- CV_REG_YMM5F0 = 340,
- CV_REG_YMM5F1 = 341,
- CV_REG_YMM5F2 = 342,
- CV_REG_YMM5F3 = 343,
- CV_REG_YMM5F4 = 344,
- CV_REG_YMM5F5 = 345,
- CV_REG_YMM5F6 = 346,
- CV_REG_YMM5F7 = 347,
- CV_REG_YMM6F0 = 348,
- CV_REG_YMM6F1 = 349,
- CV_REG_YMM6F2 = 350,
- CV_REG_YMM6F3 = 351,
- CV_REG_YMM6F4 = 352,
- CV_REG_YMM6F5 = 353,
- CV_REG_YMM6F6 = 354,
- CV_REG_YMM6F7 = 355,
- CV_REG_YMM7F0 = 356,
- CV_REG_YMM7F1 = 357,
- CV_REG_YMM7F2 = 358,
- CV_REG_YMM7F3 = 359,
- CV_REG_YMM7F4 = 360,
- CV_REG_YMM7F5 = 361,
- CV_REG_YMM7F6 = 362,
- CV_REG_YMM7F7 = 363,
-
- CV_REG_YMM0D0 = 364, // AVX floating-point double precise registers
- CV_REG_YMM0D1 = 365,
- CV_REG_YMM0D2 = 366,
- CV_REG_YMM0D3 = 367,
- CV_REG_YMM1D0 = 368,
- CV_REG_YMM1D1 = 369,
- CV_REG_YMM1D2 = 370,
- CV_REG_YMM1D3 = 371,
- CV_REG_YMM2D0 = 372,
- CV_REG_YMM2D1 = 373,
- CV_REG_YMM2D2 = 374,
- CV_REG_YMM2D3 = 375,
- CV_REG_YMM3D0 = 376,
- CV_REG_YMM3D1 = 377,
- CV_REG_YMM3D2 = 378,
- CV_REG_YMM3D3 = 379,
- CV_REG_YMM4D0 = 380,
- CV_REG_YMM4D1 = 381,
- CV_REG_YMM4D2 = 382,
- CV_REG_YMM4D3 = 383,
- CV_REG_YMM5D0 = 384,
- CV_REG_YMM5D1 = 385,
- CV_REG_YMM5D2 = 386,
- CV_REG_YMM5D3 = 387,
- CV_REG_YMM6D0 = 388,
- CV_REG_YMM6D1 = 389,
- CV_REG_YMM6D2 = 390,
- CV_REG_YMM6D3 = 391,
- CV_REG_YMM7D0 = 392,
- CV_REG_YMM7D1 = 393,
- CV_REG_YMM7D2 = 394,
- CV_REG_YMM7D3 = 395,
-
- // registers for the 68K processors
-
- CV_R68_D0 = 0,
- CV_R68_D1 = 1,
- CV_R68_D2 = 2,
- CV_R68_D3 = 3,
- CV_R68_D4 = 4,
- CV_R68_D5 = 5,
- CV_R68_D6 = 6,
- CV_R68_D7 = 7,
- CV_R68_A0 = 8,
- CV_R68_A1 = 9,
- CV_R68_A2 = 10,
- CV_R68_A3 = 11,
- CV_R68_A4 = 12,
- CV_R68_A5 = 13,
- CV_R68_A6 = 14,
- CV_R68_A7 = 15,
- CV_R68_CCR = 16,
- CV_R68_SR = 17,
- CV_R68_USP = 18,
- CV_R68_MSP = 19,
- CV_R68_SFC = 20,
- CV_R68_DFC = 21,
- CV_R68_CACR = 22,
- CV_R68_VBR = 23,
- CV_R68_CAAR = 24,
- CV_R68_ISP = 25,
- CV_R68_PC = 26,
- //reserved 27
- CV_R68_FPCR = 28,
- CV_R68_FPSR = 29,
- CV_R68_FPIAR = 30,
- //reserved 31
- CV_R68_FP0 = 32,
- CV_R68_FP1 = 33,
- CV_R68_FP2 = 34,
- CV_R68_FP3 = 35,
- CV_R68_FP4 = 36,
- CV_R68_FP5 = 37,
- CV_R68_FP6 = 38,
- CV_R68_FP7 = 39,
- //reserved 40
- CV_R68_MMUSR030 = 41,
- CV_R68_MMUSR = 42,
- CV_R68_URP = 43,
- CV_R68_DTT0 = 44,
- CV_R68_DTT1 = 45,
- CV_R68_ITT0 = 46,
- CV_R68_ITT1 = 47,
- //reserved 50
- CV_R68_PSR = 51,
- CV_R68_PCSR = 52,
- CV_R68_VAL = 53,
- CV_R68_CRP = 54,
- CV_R68_SRP = 55,
- CV_R68_DRP = 56,
- CV_R68_TC = 57,
- CV_R68_AC = 58,
- CV_R68_SCC = 59,
- CV_R68_CAL = 60,
- CV_R68_TT0 = 61,
- CV_R68_TT1 = 62,
- //reserved 63
- CV_R68_BAD0 = 64,
- CV_R68_BAD1 = 65,
- CV_R68_BAD2 = 66,
- CV_R68_BAD3 = 67,
- CV_R68_BAD4 = 68,
- CV_R68_BAD5 = 69,
- CV_R68_BAD6 = 70,
- CV_R68_BAD7 = 71,
- CV_R68_BAC0 = 72,
- CV_R68_BAC1 = 73,
- CV_R68_BAC2 = 74,
- CV_R68_BAC3 = 75,
- CV_R68_BAC4 = 76,
- CV_R68_BAC5 = 77,
- CV_R68_BAC6 = 78,
- CV_R68_BAC7 = 79,
-
- // Register set for the MIPS 4000
-
- CV_M4_NOREG = CV_REG_NONE,
-
- CV_M4_IntZERO = 10, /* CPU REGISTER */
- CV_M4_IntAT = 11,
- CV_M4_IntV0 = 12,
- CV_M4_IntV1 = 13,
- CV_M4_IntA0 = 14,
- CV_M4_IntA1 = 15,
- CV_M4_IntA2 = 16,
- CV_M4_IntA3 = 17,
- CV_M4_IntT0 = 18,
- CV_M4_IntT1 = 19,
- CV_M4_IntT2 = 20,
- CV_M4_IntT3 = 21,
- CV_M4_IntT4 = 22,
- CV_M4_IntT5 = 23,
- CV_M4_IntT6 = 24,
- CV_M4_IntT7 = 25,
- CV_M4_IntS0 = 26,
- CV_M4_IntS1 = 27,
- CV_M4_IntS2 = 28,
- CV_M4_IntS3 = 29,
- CV_M4_IntS4 = 30,
- CV_M4_IntS5 = 31,
- CV_M4_IntS6 = 32,
- CV_M4_IntS7 = 33,
- CV_M4_IntT8 = 34,
- CV_M4_IntT9 = 35,
- CV_M4_IntKT0 = 36,
- CV_M4_IntKT1 = 37,
- CV_M4_IntGP = 38,
- CV_M4_IntSP = 39,
- CV_M4_IntS8 = 40,
- CV_M4_IntRA = 41,
- CV_M4_IntLO = 42,
- CV_M4_IntHI = 43,
-
- CV_M4_Fir = 50,
- CV_M4_Psr = 51,
-
- CV_M4_FltF0 = 60, /* Floating point registers */
- CV_M4_FltF1 = 61,
- CV_M4_FltF2 = 62,
- CV_M4_FltF3 = 63,
- CV_M4_FltF4 = 64,
- CV_M4_FltF5 = 65,
- CV_M4_FltF6 = 66,
- CV_M4_FltF7 = 67,
- CV_M4_FltF8 = 68,
- CV_M4_FltF9 = 69,
- CV_M4_FltF10 = 70,
- CV_M4_FltF11 = 71,
- CV_M4_FltF12 = 72,
- CV_M4_FltF13 = 73,
- CV_M4_FltF14 = 74,
- CV_M4_FltF15 = 75,
- CV_M4_FltF16 = 76,
- CV_M4_FltF17 = 77,
- CV_M4_FltF18 = 78,
- CV_M4_FltF19 = 79,
- CV_M4_FltF20 = 80,
- CV_M4_FltF21 = 81,
- CV_M4_FltF22 = 82,
- CV_M4_FltF23 = 83,
- CV_M4_FltF24 = 84,
- CV_M4_FltF25 = 85,
- CV_M4_FltF26 = 86,
- CV_M4_FltF27 = 87,
- CV_M4_FltF28 = 88,
- CV_M4_FltF29 = 89,
- CV_M4_FltF30 = 90,
- CV_M4_FltF31 = 91,
- CV_M4_FltFsr = 92,
-
-
- // Register set for the ALPHA AXP
-
- CV_ALPHA_NOREG = CV_REG_NONE,
-
- CV_ALPHA_FltF0 = 10, // Floating point registers
- CV_ALPHA_FltF1 = 11,
- CV_ALPHA_FltF2 = 12,
- CV_ALPHA_FltF3 = 13,
- CV_ALPHA_FltF4 = 14,
- CV_ALPHA_FltF5 = 15,
- CV_ALPHA_FltF6 = 16,
- CV_ALPHA_FltF7 = 17,
- CV_ALPHA_FltF8 = 18,
- CV_ALPHA_FltF9 = 19,
- CV_ALPHA_FltF10 = 20,
- CV_ALPHA_FltF11 = 21,
- CV_ALPHA_FltF12 = 22,
- CV_ALPHA_FltF13 = 23,
- CV_ALPHA_FltF14 = 24,
- CV_ALPHA_FltF15 = 25,
- CV_ALPHA_FltF16 = 26,
- CV_ALPHA_FltF17 = 27,
- CV_ALPHA_FltF18 = 28,
- CV_ALPHA_FltF19 = 29,
- CV_ALPHA_FltF20 = 30,
- CV_ALPHA_FltF21 = 31,
- CV_ALPHA_FltF22 = 32,
- CV_ALPHA_FltF23 = 33,
- CV_ALPHA_FltF24 = 34,
- CV_ALPHA_FltF25 = 35,
- CV_ALPHA_FltF26 = 36,
- CV_ALPHA_FltF27 = 37,
- CV_ALPHA_FltF28 = 38,
- CV_ALPHA_FltF29 = 39,
- CV_ALPHA_FltF30 = 40,
- CV_ALPHA_FltF31 = 41,
-
- CV_ALPHA_IntV0 = 42, // Integer registers
- CV_ALPHA_IntT0 = 43,
- CV_ALPHA_IntT1 = 44,
- CV_ALPHA_IntT2 = 45,
- CV_ALPHA_IntT3 = 46,
- CV_ALPHA_IntT4 = 47,
- CV_ALPHA_IntT5 = 48,
- CV_ALPHA_IntT6 = 49,
- CV_ALPHA_IntT7 = 50,
- CV_ALPHA_IntS0 = 51,
- CV_ALPHA_IntS1 = 52,
- CV_ALPHA_IntS2 = 53,
- CV_ALPHA_IntS3 = 54,
- CV_ALPHA_IntS4 = 55,
- CV_ALPHA_IntS5 = 56,
- CV_ALPHA_IntFP = 57,
- CV_ALPHA_IntA0 = 58,
- CV_ALPHA_IntA1 = 59,
- CV_ALPHA_IntA2 = 60,
- CV_ALPHA_IntA3 = 61,
- CV_ALPHA_IntA4 = 62,
- CV_ALPHA_IntA5 = 63,
- CV_ALPHA_IntT8 = 64,
- CV_ALPHA_IntT9 = 65,
- CV_ALPHA_IntT10 = 66,
- CV_ALPHA_IntT11 = 67,
- CV_ALPHA_IntRA = 68,
- CV_ALPHA_IntT12 = 69,
- CV_ALPHA_IntAT = 70,
- CV_ALPHA_IntGP = 71,
- CV_ALPHA_IntSP = 72,
- CV_ALPHA_IntZERO = 73,
-
-
- CV_ALPHA_Fpcr = 74, // Control registers
- CV_ALPHA_Fir = 75,
- CV_ALPHA_Psr = 76,
- CV_ALPHA_FltFsr = 77,
- CV_ALPHA_SoftFpcr = 78,
-
- // Register Set for Motorola/IBM PowerPC
-
- /*
- ** PowerPC General Registers ( User Level )
- */
- CV_PPC_GPR0 = 1,
- CV_PPC_GPR1 = 2,
- CV_PPC_GPR2 = 3,
- CV_PPC_GPR3 = 4,
- CV_PPC_GPR4 = 5,
- CV_PPC_GPR5 = 6,
- CV_PPC_GPR6 = 7,
- CV_PPC_GPR7 = 8,
- CV_PPC_GPR8 = 9,
- CV_PPC_GPR9 = 10,
- CV_PPC_GPR10 = 11,
- CV_PPC_GPR11 = 12,
- CV_PPC_GPR12 = 13,
- CV_PPC_GPR13 = 14,
- CV_PPC_GPR14 = 15,
- CV_PPC_GPR15 = 16,
- CV_PPC_GPR16 = 17,
- CV_PPC_GPR17 = 18,
- CV_PPC_GPR18 = 19,
- CV_PPC_GPR19 = 20,
- CV_PPC_GPR20 = 21,
- CV_PPC_GPR21 = 22,
- CV_PPC_GPR22 = 23,
- CV_PPC_GPR23 = 24,
- CV_PPC_GPR24 = 25,
- CV_PPC_GPR25 = 26,
- CV_PPC_GPR26 = 27,
- CV_PPC_GPR27 = 28,
- CV_PPC_GPR28 = 29,
- CV_PPC_GPR29 = 30,
- CV_PPC_GPR30 = 31,
- CV_PPC_GPR31 = 32,
-
- /*
- ** PowerPC Condition Register ( User Level )
- */
- CV_PPC_CR = 33,
- CV_PPC_CR0 = 34,
- CV_PPC_CR1 = 35,
- CV_PPC_CR2 = 36,
- CV_PPC_CR3 = 37,
- CV_PPC_CR4 = 38,
- CV_PPC_CR5 = 39,
- CV_PPC_CR6 = 40,
- CV_PPC_CR7 = 41,
-
- /*
- ** PowerPC Floating Point Registers ( User Level )
- */
- CV_PPC_FPR0 = 42,
- CV_PPC_FPR1 = 43,
- CV_PPC_FPR2 = 44,
- CV_PPC_FPR3 = 45,
- CV_PPC_FPR4 = 46,
- CV_PPC_FPR5 = 47,
- CV_PPC_FPR6 = 48,
- CV_PPC_FPR7 = 49,
- CV_PPC_FPR8 = 50,
- CV_PPC_FPR9 = 51,
- CV_PPC_FPR10 = 52,
- CV_PPC_FPR11 = 53,
- CV_PPC_FPR12 = 54,
- CV_PPC_FPR13 = 55,
- CV_PPC_FPR14 = 56,
- CV_PPC_FPR15 = 57,
- CV_PPC_FPR16 = 58,
- CV_PPC_FPR17 = 59,
- CV_PPC_FPR18 = 60,
- CV_PPC_FPR19 = 61,
- CV_PPC_FPR20 = 62,
- CV_PPC_FPR21 = 63,
- CV_PPC_FPR22 = 64,
- CV_PPC_FPR23 = 65,
- CV_PPC_FPR24 = 66,
- CV_PPC_FPR25 = 67,
- CV_PPC_FPR26 = 68,
- CV_PPC_FPR27 = 69,
- CV_PPC_FPR28 = 70,
- CV_PPC_FPR29 = 71,
- CV_PPC_FPR30 = 72,
- CV_PPC_FPR31 = 73,
-
- /*
- ** PowerPC Floating Point Status and Control Register ( User Level )
- */
- CV_PPC_FPSCR = 74,
-
- /*
- ** PowerPC Machine State Register ( Supervisor Level )
- */
- CV_PPC_MSR = 75,
-
- /*
- ** PowerPC Segment Registers ( Supervisor Level )
- */
- CV_PPC_SR0 = 76,
- CV_PPC_SR1 = 77,
- CV_PPC_SR2 = 78,
- CV_PPC_SR3 = 79,
- CV_PPC_SR4 = 80,
- CV_PPC_SR5 = 81,
- CV_PPC_SR6 = 82,
- CV_PPC_SR7 = 83,
- CV_PPC_SR8 = 84,
- CV_PPC_SR9 = 85,
- CV_PPC_SR10 = 86,
- CV_PPC_SR11 = 87,
- CV_PPC_SR12 = 88,
- CV_PPC_SR13 = 89,
- CV_PPC_SR14 = 90,
- CV_PPC_SR15 = 91,
-
- /*
- ** For all of the special purpose registers add 100 to the SPR# that the
- ** Motorola/IBM documentation gives with the exception of any imaginary
- ** registers.
- */
-
- /*
- ** PowerPC Special Purpose Registers ( User Level )
- */
- CV_PPC_PC = 99, // PC (imaginary register)
-
- CV_PPC_MQ = 100, // MPC601
- CV_PPC_XER = 101,
- CV_PPC_RTCU = 104, // MPC601
- CV_PPC_RTCL = 105, // MPC601
- CV_PPC_LR = 108,
- CV_PPC_CTR = 109,
-
- CV_PPC_COMPARE = 110, // part of XER (internal to the debugger only)
- CV_PPC_COUNT = 111, // part of XER (internal to the debugger only)
-
- /*
- ** PowerPC Special Purpose Registers ( Supervisor Level )
- */
- CV_PPC_DSISR = 118,
- CV_PPC_DAR = 119,
- CV_PPC_DEC = 122,
- CV_PPC_SDR1 = 125,
- CV_PPC_SRR0 = 126,
- CV_PPC_SRR1 = 127,
- CV_PPC_SPRG0 = 372,
- CV_PPC_SPRG1 = 373,
- CV_PPC_SPRG2 = 374,
- CV_PPC_SPRG3 = 375,
- CV_PPC_ASR = 280, // 64-bit implementations only
- CV_PPC_EAR = 382,
- CV_PPC_PVR = 287,
- CV_PPC_BAT0U = 628,
- CV_PPC_BAT0L = 629,
- CV_PPC_BAT1U = 630,
- CV_PPC_BAT1L = 631,
- CV_PPC_BAT2U = 632,
- CV_PPC_BAT2L = 633,
- CV_PPC_BAT3U = 634,
- CV_PPC_BAT3L = 635,
- CV_PPC_DBAT0U = 636,
- CV_PPC_DBAT0L = 637,
- CV_PPC_DBAT1U = 638,
- CV_PPC_DBAT1L = 639,
- CV_PPC_DBAT2U = 640,
- CV_PPC_DBAT2L = 641,
- CV_PPC_DBAT3U = 642,
- CV_PPC_DBAT3L = 643,
-
- /*
- ** PowerPC Special Purpose Registers Implementation Dependent ( Supervisor Level )
- */
-
- /*
- ** Doesn't appear that IBM/Motorola has finished defining these.
- */
-
- CV_PPC_PMR0 = 1044, // MPC620,
- CV_PPC_PMR1 = 1045, // MPC620,
- CV_PPC_PMR2 = 1046, // MPC620,
- CV_PPC_PMR3 = 1047, // MPC620,
- CV_PPC_PMR4 = 1048, // MPC620,
- CV_PPC_PMR5 = 1049, // MPC620,
- CV_PPC_PMR6 = 1050, // MPC620,
- CV_PPC_PMR7 = 1051, // MPC620,
- CV_PPC_PMR8 = 1052, // MPC620,
- CV_PPC_PMR9 = 1053, // MPC620,
- CV_PPC_PMR10 = 1054, // MPC620,
- CV_PPC_PMR11 = 1055, // MPC620,
- CV_PPC_PMR12 = 1056, // MPC620,
- CV_PPC_PMR13 = 1057, // MPC620,
- CV_PPC_PMR14 = 1058, // MPC620,
- CV_PPC_PMR15 = 1059, // MPC620,
-
- CV_PPC_DMISS = 1076, // MPC603
- CV_PPC_DCMP = 1077, // MPC603
- CV_PPC_HASH1 = 1078, // MPC603
- CV_PPC_HASH2 = 1079, // MPC603
- CV_PPC_IMISS = 1080, // MPC603
- CV_PPC_ICMP = 1081, // MPC603
- CV_PPC_RPA = 1082, // MPC603
-
- CV_PPC_HID0 = 1108, // MPC601, MPC603, MPC620
- CV_PPC_HID1 = 1109, // MPC601
- CV_PPC_HID2 = 1110, // MPC601, MPC603, MPC620 ( IABR )
- CV_PPC_HID3 = 1111, // Not Defined
- CV_PPC_HID4 = 1112, // Not Defined
- CV_PPC_HID5 = 1113, // MPC601, MPC604, MPC620 ( DABR )
- CV_PPC_HID6 = 1114, // Not Defined
- CV_PPC_HID7 = 1115, // Not Defined
- CV_PPC_HID8 = 1116, // MPC620 ( BUSCSR )
- CV_PPC_HID9 = 1117, // MPC620 ( L2CSR )
- CV_PPC_HID10 = 1118, // Not Defined
- CV_PPC_HID11 = 1119, // Not Defined
- CV_PPC_HID12 = 1120, // Not Defined
- CV_PPC_HID13 = 1121, // MPC604 ( HCR )
- CV_PPC_HID14 = 1122, // Not Defined
- CV_PPC_HID15 = 1123, // MPC601, MPC604, MPC620 ( PIR )
-
- //
- // JAVA VM registers
- //
-
- CV_JAVA_PC = 1,
-
- //
- // Register set for the Hitachi SH3
- //
-
- CV_SH3_NOREG = CV_REG_NONE,
-
- CV_SH3_IntR0 = 10, // CPU REGISTER
- CV_SH3_IntR1 = 11,
- CV_SH3_IntR2 = 12,
- CV_SH3_IntR3 = 13,
- CV_SH3_IntR4 = 14,
- CV_SH3_IntR5 = 15,
- CV_SH3_IntR6 = 16,
- CV_SH3_IntR7 = 17,
- CV_SH3_IntR8 = 18,
- CV_SH3_IntR9 = 19,
- CV_SH3_IntR10 = 20,
- CV_SH3_IntR11 = 21,
- CV_SH3_IntR12 = 22,
- CV_SH3_IntR13 = 23,
- CV_SH3_IntFp = 24,
- CV_SH3_IntSp = 25,
- CV_SH3_Gbr = 38,
- CV_SH3_Pr = 39,
- CV_SH3_Mach = 40,
- CV_SH3_Macl = 41,
-
- CV_SH3_Pc = 50,
- CV_SH3_Sr = 51,
-
- CV_SH3_BarA = 60,
- CV_SH3_BasrA = 61,
- CV_SH3_BamrA = 62,
- CV_SH3_BbrA = 63,
- CV_SH3_BarB = 64,
- CV_SH3_BasrB = 65,
- CV_SH3_BamrB = 66,
- CV_SH3_BbrB = 67,
- CV_SH3_BdrB = 68,
- CV_SH3_BdmrB = 69,
- CV_SH3_Brcr = 70,
-
- //
- // Additional registers for Hitachi SH processors
- //
-
- CV_SH_Fpscr = 75, // floating point status/control register
- CV_SH_Fpul = 76, // floating point communication register
-
- CV_SH_FpR0 = 80, // Floating point registers
- CV_SH_FpR1 = 81,
- CV_SH_FpR2 = 82,
- CV_SH_FpR3 = 83,
- CV_SH_FpR4 = 84,
- CV_SH_FpR5 = 85,
- CV_SH_FpR6 = 86,
- CV_SH_FpR7 = 87,
- CV_SH_FpR8 = 88,
- CV_SH_FpR9 = 89,
- CV_SH_FpR10 = 90,
- CV_SH_FpR11 = 91,
- CV_SH_FpR12 = 92,
- CV_SH_FpR13 = 93,
- CV_SH_FpR14 = 94,
- CV_SH_FpR15 = 95,
-
- CV_SH_XFpR0 = 96,
- CV_SH_XFpR1 = 97,
- CV_SH_XFpR2 = 98,
- CV_SH_XFpR3 = 99,
- CV_SH_XFpR4 = 100,
- CV_SH_XFpR5 = 101,
- CV_SH_XFpR6 = 102,
- CV_SH_XFpR7 = 103,
- CV_SH_XFpR8 = 104,
- CV_SH_XFpR9 = 105,
- CV_SH_XFpR10 = 106,
- CV_SH_XFpR11 = 107,
- CV_SH_XFpR12 = 108,
- CV_SH_XFpR13 = 109,
- CV_SH_XFpR14 = 110,
- CV_SH_XFpR15 = 111,
-
- //
- // Register set for the ARM processor.
- //
-
- CV_ARM_NOREG = CV_REG_NONE,
-
- CV_ARM_R0 = 10,
- CV_ARM_R1 = 11,
- CV_ARM_R2 = 12,
- CV_ARM_R3 = 13,
- CV_ARM_R4 = 14,
- CV_ARM_R5 = 15,
- CV_ARM_R6 = 16,
- CV_ARM_R7 = 17,
- CV_ARM_R8 = 18,
- CV_ARM_R9 = 19,
- CV_ARM_R10 = 20,
- CV_ARM_R11 = 21, // Frame pointer, if allocated
- CV_ARM_R12 = 22,
- CV_ARM_SP = 23, // Stack pointer
- CV_ARM_LR = 24, // Link Register
- CV_ARM_PC = 25, // Program counter
- CV_ARM_CPSR = 26, // Current program status register
-
- //
- // Register set for Intel IA64
- //
-
- CV_IA64_NOREG = CV_REG_NONE,
-
- // Branch Registers
-
- CV_IA64_Br0 = 512,
- CV_IA64_Br1 = 513,
- CV_IA64_Br2 = 514,
- CV_IA64_Br3 = 515,
- CV_IA64_Br4 = 516,
- CV_IA64_Br5 = 517,
- CV_IA64_Br6 = 518,
- CV_IA64_Br7 = 519,
-
- // Predicate Registers
-
- CV_IA64_P0 = 704,
- CV_IA64_P1 = 705,
- CV_IA64_P2 = 706,
- CV_IA64_P3 = 707,
- CV_IA64_P4 = 708,
- CV_IA64_P5 = 709,
- CV_IA64_P6 = 710,
- CV_IA64_P7 = 711,
- CV_IA64_P8 = 712,
- CV_IA64_P9 = 713,
- CV_IA64_P10 = 714,
- CV_IA64_P11 = 715,
- CV_IA64_P12 = 716,
- CV_IA64_P13 = 717,
- CV_IA64_P14 = 718,
- CV_IA64_P15 = 719,
- CV_IA64_P16 = 720,
- CV_IA64_P17 = 721,
- CV_IA64_P18 = 722,
- CV_IA64_P19 = 723,
- CV_IA64_P20 = 724,
- CV_IA64_P21 = 725,
- CV_IA64_P22 = 726,
- CV_IA64_P23 = 727,
- CV_IA64_P24 = 728,
- CV_IA64_P25 = 729,
- CV_IA64_P26 = 730,
- CV_IA64_P27 = 731,
- CV_IA64_P28 = 732,
- CV_IA64_P29 = 733,
- CV_IA64_P30 = 734,
- CV_IA64_P31 = 735,
- CV_IA64_P32 = 736,
- CV_IA64_P33 = 737,
- CV_IA64_P34 = 738,
- CV_IA64_P35 = 739,
- CV_IA64_P36 = 740,
- CV_IA64_P37 = 741,
- CV_IA64_P38 = 742,
- CV_IA64_P39 = 743,
- CV_IA64_P40 = 744,
- CV_IA64_P41 = 745,
- CV_IA64_P42 = 746,
- CV_IA64_P43 = 747,
- CV_IA64_P44 = 748,
- CV_IA64_P45 = 749,
- CV_IA64_P46 = 750,
- CV_IA64_P47 = 751,
- CV_IA64_P48 = 752,
- CV_IA64_P49 = 753,
- CV_IA64_P50 = 754,
- CV_IA64_P51 = 755,
- CV_IA64_P52 = 756,
- CV_IA64_P53 = 757,
- CV_IA64_P54 = 758,
- CV_IA64_P55 = 759,
- CV_IA64_P56 = 760,
- CV_IA64_P57 = 761,
- CV_IA64_P58 = 762,
- CV_IA64_P59 = 763,
- CV_IA64_P60 = 764,
- CV_IA64_P61 = 765,
- CV_IA64_P62 = 766,
- CV_IA64_P63 = 767,
-
- CV_IA64_Preds = 768,
-
- // Banked General Registers
-
- CV_IA64_IntH0 = 832,
- CV_IA64_IntH1 = 833,
- CV_IA64_IntH2 = 834,
- CV_IA64_IntH3 = 835,
- CV_IA64_IntH4 = 836,
- CV_IA64_IntH5 = 837,
- CV_IA64_IntH6 = 838,
- CV_IA64_IntH7 = 839,
- CV_IA64_IntH8 = 840,
- CV_IA64_IntH9 = 841,
- CV_IA64_IntH10 = 842,
- CV_IA64_IntH11 = 843,
- CV_IA64_IntH12 = 844,
- CV_IA64_IntH13 = 845,
- CV_IA64_IntH14 = 846,
- CV_IA64_IntH15 = 847,
-
- // Special Registers
-
- CV_IA64_Ip = 1016,
- CV_IA64_Umask = 1017,
- CV_IA64_Cfm = 1018,
- CV_IA64_Psr = 1019,
-
- // Banked General Registers
-
- CV_IA64_Nats = 1020,
- CV_IA64_Nats2 = 1021,
- CV_IA64_Nats3 = 1022,
-
- // General-Purpose Registers
-
- // Integer registers
- CV_IA64_IntR0 = 1024,
- CV_IA64_IntR1 = 1025,
- CV_IA64_IntR2 = 1026,
- CV_IA64_IntR3 = 1027,
- CV_IA64_IntR4 = 1028,
- CV_IA64_IntR5 = 1029,
- CV_IA64_IntR6 = 1030,
- CV_IA64_IntR7 = 1031,
- CV_IA64_IntR8 = 1032,
- CV_IA64_IntR9 = 1033,
- CV_IA64_IntR10 = 1034,
- CV_IA64_IntR11 = 1035,
- CV_IA64_IntR12 = 1036,
- CV_IA64_IntR13 = 1037,
- CV_IA64_IntR14 = 1038,
- CV_IA64_IntR15 = 1039,
- CV_IA64_IntR16 = 1040,
- CV_IA64_IntR17 = 1041,
- CV_IA64_IntR18 = 1042,
- CV_IA64_IntR19 = 1043,
- CV_IA64_IntR20 = 1044,
- CV_IA64_IntR21 = 1045,
- CV_IA64_IntR22 = 1046,
- CV_IA64_IntR23 = 1047,
- CV_IA64_IntR24 = 1048,
- CV_IA64_IntR25 = 1049,
- CV_IA64_IntR26 = 1050,
- CV_IA64_IntR27 = 1051,
- CV_IA64_IntR28 = 1052,
- CV_IA64_IntR29 = 1053,
- CV_IA64_IntR30 = 1054,
- CV_IA64_IntR31 = 1055,
-
- // Register Stack
- CV_IA64_IntR32 = 1056,
- CV_IA64_IntR33 = 1057,
- CV_IA64_IntR34 = 1058,
- CV_IA64_IntR35 = 1059,
- CV_IA64_IntR36 = 1060,
- CV_IA64_IntR37 = 1061,
- CV_IA64_IntR38 = 1062,
- CV_IA64_IntR39 = 1063,
- CV_IA64_IntR40 = 1064,
- CV_IA64_IntR41 = 1065,
- CV_IA64_IntR42 = 1066,
- CV_IA64_IntR43 = 1067,
- CV_IA64_IntR44 = 1068,
- CV_IA64_IntR45 = 1069,
- CV_IA64_IntR46 = 1070,
- CV_IA64_IntR47 = 1071,
- CV_IA64_IntR48 = 1072,
- CV_IA64_IntR49 = 1073,
- CV_IA64_IntR50 = 1074,
- CV_IA64_IntR51 = 1075,
- CV_IA64_IntR52 = 1076,
- CV_IA64_IntR53 = 1077,
- CV_IA64_IntR54 = 1078,
- CV_IA64_IntR55 = 1079,
- CV_IA64_IntR56 = 1080,
- CV_IA64_IntR57 = 1081,
- CV_IA64_IntR58 = 1082,
- CV_IA64_IntR59 = 1083,
- CV_IA64_IntR60 = 1084,
- CV_IA64_IntR61 = 1085,
- CV_IA64_IntR62 = 1086,
- CV_IA64_IntR63 = 1087,
- CV_IA64_IntR64 = 1088,
- CV_IA64_IntR65 = 1089,
- CV_IA64_IntR66 = 1090,
- CV_IA64_IntR67 = 1091,
- CV_IA64_IntR68 = 1092,
- CV_IA64_IntR69 = 1093,
- CV_IA64_IntR70 = 1094,
- CV_IA64_IntR71 = 1095,
- CV_IA64_IntR72 = 1096,
- CV_IA64_IntR73 = 1097,
- CV_IA64_IntR74 = 1098,
- CV_IA64_IntR75 = 1099,
- CV_IA64_IntR76 = 1100,
- CV_IA64_IntR77 = 1101,
- CV_IA64_IntR78 = 1102,
- CV_IA64_IntR79 = 1103,
- CV_IA64_IntR80 = 1104,
- CV_IA64_IntR81 = 1105,
- CV_IA64_IntR82 = 1106,
- CV_IA64_IntR83 = 1107,
- CV_IA64_IntR84 = 1108,
- CV_IA64_IntR85 = 1109,
- CV_IA64_IntR86 = 1110,
- CV_IA64_IntR87 = 1111,
- CV_IA64_IntR88 = 1112,
- CV_IA64_IntR89 = 1113,
- CV_IA64_IntR90 = 1114,
- CV_IA64_IntR91 = 1115,
- CV_IA64_IntR92 = 1116,
- CV_IA64_IntR93 = 1117,
- CV_IA64_IntR94 = 1118,
- CV_IA64_IntR95 = 1119,
- CV_IA64_IntR96 = 1120,
- CV_IA64_IntR97 = 1121,
- CV_IA64_IntR98 = 1122,
- CV_IA64_IntR99 = 1123,
- CV_IA64_IntR100 = 1124,
- CV_IA64_IntR101 = 1125,
- CV_IA64_IntR102 = 1126,
- CV_IA64_IntR103 = 1127,
- CV_IA64_IntR104 = 1128,
- CV_IA64_IntR105 = 1129,
- CV_IA64_IntR106 = 1130,
- CV_IA64_IntR107 = 1131,
- CV_IA64_IntR108 = 1132,
- CV_IA64_IntR109 = 1133,
- CV_IA64_IntR110 = 1134,
- CV_IA64_IntR111 = 1135,
- CV_IA64_IntR112 = 1136,
- CV_IA64_IntR113 = 1137,
- CV_IA64_IntR114 = 1138,
- CV_IA64_IntR115 = 1139,
- CV_IA64_IntR116 = 1140,
- CV_IA64_IntR117 = 1141,
- CV_IA64_IntR118 = 1142,
- CV_IA64_IntR119 = 1143,
- CV_IA64_IntR120 = 1144,
- CV_IA64_IntR121 = 1145,
- CV_IA64_IntR122 = 1146,
- CV_IA64_IntR123 = 1147,
- CV_IA64_IntR124 = 1148,
- CV_IA64_IntR125 = 1149,
- CV_IA64_IntR126 = 1150,
- CV_IA64_IntR127 = 1151,
-
- // Floating-Point Registers
-
- // Low Floating Point Registers
- CV_IA64_FltF0 = 2048,
- CV_IA64_FltF1 = 2049,
- CV_IA64_FltF2 = 2050,
- CV_IA64_FltF3 = 2051,
- CV_IA64_FltF4 = 2052,
- CV_IA64_FltF5 = 2053,
- CV_IA64_FltF6 = 2054,
- CV_IA64_FltF7 = 2055,
- CV_IA64_FltF8 = 2056,
- CV_IA64_FltF9 = 2057,
- CV_IA64_FltF10 = 2058,
- CV_IA64_FltF11 = 2059,
- CV_IA64_FltF12 = 2060,
- CV_IA64_FltF13 = 2061,
- CV_IA64_FltF14 = 2062,
- CV_IA64_FltF15 = 2063,
- CV_IA64_FltF16 = 2064,
- CV_IA64_FltF17 = 2065,
- CV_IA64_FltF18 = 2066,
- CV_IA64_FltF19 = 2067,
- CV_IA64_FltF20 = 2068,
- CV_IA64_FltF21 = 2069,
- CV_IA64_FltF22 = 2070,
- CV_IA64_FltF23 = 2071,
- CV_IA64_FltF24 = 2072,
- CV_IA64_FltF25 = 2073,
- CV_IA64_FltF26 = 2074,
- CV_IA64_FltF27 = 2075,
- CV_IA64_FltF28 = 2076,
- CV_IA64_FltF29 = 2077,
- CV_IA64_FltF30 = 2078,
- CV_IA64_FltF31 = 2079,
-
- // High Floating Point Registers
- CV_IA64_FltF32 = 2080,
- CV_IA64_FltF33 = 2081,
- CV_IA64_FltF34 = 2082,
- CV_IA64_FltF35 = 2083,
- CV_IA64_FltF36 = 2084,
- CV_IA64_FltF37 = 2085,
- CV_IA64_FltF38 = 2086,
- CV_IA64_FltF39 = 2087,
- CV_IA64_FltF40 = 2088,
- CV_IA64_FltF41 = 2089,
- CV_IA64_FltF42 = 2090,
- CV_IA64_FltF43 = 2091,
- CV_IA64_FltF44 = 2092,
- CV_IA64_FltF45 = 2093,
- CV_IA64_FltF46 = 2094,
- CV_IA64_FltF47 = 2095,
- CV_IA64_FltF48 = 2096,
- CV_IA64_FltF49 = 2097,
- CV_IA64_FltF50 = 2098,
- CV_IA64_FltF51 = 2099,
- CV_IA64_FltF52 = 2100,
- CV_IA64_FltF53 = 2101,
- CV_IA64_FltF54 = 2102,
- CV_IA64_FltF55 = 2103,
- CV_IA64_FltF56 = 2104,
- CV_IA64_FltF57 = 2105,
- CV_IA64_FltF58 = 2106,
- CV_IA64_FltF59 = 2107,
- CV_IA64_FltF60 = 2108,
- CV_IA64_FltF61 = 2109,
- CV_IA64_FltF62 = 2110,
- CV_IA64_FltF63 = 2111,
- CV_IA64_FltF64 = 2112,
- CV_IA64_FltF65 = 2113,
- CV_IA64_FltF66 = 2114,
- CV_IA64_FltF67 = 2115,
- CV_IA64_FltF68 = 2116,
- CV_IA64_FltF69 = 2117,
- CV_IA64_FltF70 = 2118,
- CV_IA64_FltF71 = 2119,
- CV_IA64_FltF72 = 2120,
- CV_IA64_FltF73 = 2121,
- CV_IA64_FltF74 = 2122,
- CV_IA64_FltF75 = 2123,
- CV_IA64_FltF76 = 2124,
- CV_IA64_FltF77 = 2125,
- CV_IA64_FltF78 = 2126,
- CV_IA64_FltF79 = 2127,
- CV_IA64_FltF80 = 2128,
- CV_IA64_FltF81 = 2129,
- CV_IA64_FltF82 = 2130,
- CV_IA64_FltF83 = 2131,
- CV_IA64_FltF84 = 2132,
- CV_IA64_FltF85 = 2133,
- CV_IA64_FltF86 = 2134,
- CV_IA64_FltF87 = 2135,
- CV_IA64_FltF88 = 2136,
- CV_IA64_FltF89 = 2137,
- CV_IA64_FltF90 = 2138,
- CV_IA64_FltF91 = 2139,
- CV_IA64_FltF92 = 2140,
- CV_IA64_FltF93 = 2141,
- CV_IA64_FltF94 = 2142,
- CV_IA64_FltF95 = 2143,
- CV_IA64_FltF96 = 2144,
- CV_IA64_FltF97 = 2145,
- CV_IA64_FltF98 = 2146,
- CV_IA64_FltF99 = 2147,
- CV_IA64_FltF100 = 2148,
- CV_IA64_FltF101 = 2149,
- CV_IA64_FltF102 = 2150,
- CV_IA64_FltF103 = 2151,
- CV_IA64_FltF104 = 2152,
- CV_IA64_FltF105 = 2153,
- CV_IA64_FltF106 = 2154,
- CV_IA64_FltF107 = 2155,
- CV_IA64_FltF108 = 2156,
- CV_IA64_FltF109 = 2157,
- CV_IA64_FltF110 = 2158,
- CV_IA64_FltF111 = 2159,
- CV_IA64_FltF112 = 2160,
- CV_IA64_FltF113 = 2161,
- CV_IA64_FltF114 = 2162,
- CV_IA64_FltF115 = 2163,
- CV_IA64_FltF116 = 2164,
- CV_IA64_FltF117 = 2165,
- CV_IA64_FltF118 = 2166,
- CV_IA64_FltF119 = 2167,
- CV_IA64_FltF120 = 2168,
- CV_IA64_FltF121 = 2169,
- CV_IA64_FltF122 = 2170,
- CV_IA64_FltF123 = 2171,
- CV_IA64_FltF124 = 2172,
- CV_IA64_FltF125 = 2173,
- CV_IA64_FltF126 = 2174,
- CV_IA64_FltF127 = 2175,
-
- // Application Registers
-
- CV_IA64_ApKR0 = 3072,
- CV_IA64_ApKR1 = 3073,
- CV_IA64_ApKR2 = 3074,
- CV_IA64_ApKR3 = 3075,
- CV_IA64_ApKR4 = 3076,
- CV_IA64_ApKR5 = 3077,
- CV_IA64_ApKR6 = 3078,
- CV_IA64_ApKR7 = 3079,
- CV_IA64_AR8 = 3080,
- CV_IA64_AR9 = 3081,
- CV_IA64_AR10 = 3082,
- CV_IA64_AR11 = 3083,
- CV_IA64_AR12 = 3084,
- CV_IA64_AR13 = 3085,
- CV_IA64_AR14 = 3086,
- CV_IA64_AR15 = 3087,
- CV_IA64_RsRSC = 3088,
- CV_IA64_RsBSP = 3089,
- CV_IA64_RsBSPSTORE = 3090,
- CV_IA64_RsRNAT = 3091,
- CV_IA64_AR20 = 3092,
- CV_IA64_StFCR = 3093,
- CV_IA64_AR22 = 3094,
- CV_IA64_AR23 = 3095,
- CV_IA64_EFLAG = 3096,
- CV_IA64_CSD = 3097,
- CV_IA64_SSD = 3098,
- CV_IA64_CFLG = 3099,
- CV_IA64_StFSR = 3100,
- CV_IA64_StFIR = 3101,
- CV_IA64_StFDR = 3102,
- CV_IA64_AR31 = 3103,
- CV_IA64_ApCCV = 3104,
- CV_IA64_AR33 = 3105,
- CV_IA64_AR34 = 3106,
- CV_IA64_AR35 = 3107,
- CV_IA64_ApUNAT = 3108,
- CV_IA64_AR37 = 3109,
- CV_IA64_AR38 = 3110,
- CV_IA64_AR39 = 3111,
- CV_IA64_StFPSR = 3112,
- CV_IA64_AR41 = 3113,
- CV_IA64_AR42 = 3114,
- CV_IA64_AR43 = 3115,
- CV_IA64_ApITC = 3116,
- CV_IA64_AR45 = 3117,
- CV_IA64_AR46 = 3118,
- CV_IA64_AR47 = 3119,
- CV_IA64_AR48 = 3120,
- CV_IA64_AR49 = 3121,
- CV_IA64_AR50 = 3122,
- CV_IA64_AR51 = 3123,
- CV_IA64_AR52 = 3124,
- CV_IA64_AR53 = 3125,
- CV_IA64_AR54 = 3126,
- CV_IA64_AR55 = 3127,
- CV_IA64_AR56 = 3128,
- CV_IA64_AR57 = 3129,
- CV_IA64_AR58 = 3130,
- CV_IA64_AR59 = 3131,
- CV_IA64_AR60 = 3132,
- CV_IA64_AR61 = 3133,
- CV_IA64_AR62 = 3134,
- CV_IA64_AR63 = 3135,
- CV_IA64_RsPFS = 3136,
- CV_IA64_ApLC = 3137,
- CV_IA64_ApEC = 3138,
- CV_IA64_AR67 = 3139,
- CV_IA64_AR68 = 3140,
- CV_IA64_AR69 = 3141,
- CV_IA64_AR70 = 3142,
- CV_IA64_AR71 = 3143,
- CV_IA64_AR72 = 3144,
- CV_IA64_AR73 = 3145,
- CV_IA64_AR74 = 3146,
- CV_IA64_AR75 = 3147,
- CV_IA64_AR76 = 3148,
- CV_IA64_AR77 = 3149,
- CV_IA64_AR78 = 3150,
- CV_IA64_AR79 = 3151,
- CV_IA64_AR80 = 3152,
- CV_IA64_AR81 = 3153,
- CV_IA64_AR82 = 3154,
- CV_IA64_AR83 = 3155,
- CV_IA64_AR84 = 3156,
- CV_IA64_AR85 = 3157,
- CV_IA64_AR86 = 3158,
- CV_IA64_AR87 = 3159,
- CV_IA64_AR88 = 3160,
- CV_IA64_AR89 = 3161,
- CV_IA64_AR90 = 3162,
- CV_IA64_AR91 = 3163,
- CV_IA64_AR92 = 3164,
- CV_IA64_AR93 = 3165,
- CV_IA64_AR94 = 3166,
- CV_IA64_AR95 = 3167,
- CV_IA64_AR96 = 3168,
- CV_IA64_AR97 = 3169,
- CV_IA64_AR98 = 3170,
- CV_IA64_AR99 = 3171,
- CV_IA64_AR100 = 3172,
- CV_IA64_AR101 = 3173,
- CV_IA64_AR102 = 3174,
- CV_IA64_AR103 = 3175,
- CV_IA64_AR104 = 3176,
- CV_IA64_AR105 = 3177,
- CV_IA64_AR106 = 3178,
- CV_IA64_AR107 = 3179,
- CV_IA64_AR108 = 3180,
- CV_IA64_AR109 = 3181,
- CV_IA64_AR110 = 3182,
- CV_IA64_AR111 = 3183,
- CV_IA64_AR112 = 3184,
- CV_IA64_AR113 = 3185,
- CV_IA64_AR114 = 3186,
- CV_IA64_AR115 = 3187,
- CV_IA64_AR116 = 3188,
- CV_IA64_AR117 = 3189,
- CV_IA64_AR118 = 3190,
- CV_IA64_AR119 = 3191,
- CV_IA64_AR120 = 3192,
- CV_IA64_AR121 = 3193,
- CV_IA64_AR122 = 3194,
- CV_IA64_AR123 = 3195,
- CV_IA64_AR124 = 3196,
- CV_IA64_AR125 = 3197,
- CV_IA64_AR126 = 3198,
- CV_IA64_AR127 = 3199,
-
- // CPUID Registers
-
- CV_IA64_CPUID0 = 3328,
- CV_IA64_CPUID1 = 3329,
- CV_IA64_CPUID2 = 3330,
- CV_IA64_CPUID3 = 3331,
- CV_IA64_CPUID4 = 3332,
-
- // Control Registers
-
- CV_IA64_ApDCR = 4096,
- CV_IA64_ApITM = 4097,
- CV_IA64_ApIVA = 4098,
- CV_IA64_CR3 = 4099,
- CV_IA64_CR4 = 4100,
- CV_IA64_CR5 = 4101,
- CV_IA64_CR6 = 4102,
- CV_IA64_CR7 = 4103,
- CV_IA64_ApPTA = 4104,
- CV_IA64_ApGPTA = 4105,
- CV_IA64_CR10 = 4106,
- CV_IA64_CR11 = 4107,
- CV_IA64_CR12 = 4108,
- CV_IA64_CR13 = 4109,
- CV_IA64_CR14 = 4110,
- CV_IA64_CR15 = 4111,
- CV_IA64_StIPSR = 4112,
- CV_IA64_StISR = 4113,
- CV_IA64_CR18 = 4114,
- CV_IA64_StIIP = 4115,
- CV_IA64_StIFA = 4116,
- CV_IA64_StITIR = 4117,
- CV_IA64_StIIPA = 4118,
- CV_IA64_StIFS = 4119,
- CV_IA64_StIIM = 4120,
- CV_IA64_StIHA = 4121,
- CV_IA64_CR26 = 4122,
- CV_IA64_CR27 = 4123,
- CV_IA64_CR28 = 4124,
- CV_IA64_CR29 = 4125,
- CV_IA64_CR30 = 4126,
- CV_IA64_CR31 = 4127,
- CV_IA64_CR32 = 4128,
- CV_IA64_CR33 = 4129,
- CV_IA64_CR34 = 4130,
- CV_IA64_CR35 = 4131,
- CV_IA64_CR36 = 4132,
- CV_IA64_CR37 = 4133,
- CV_IA64_CR38 = 4134,
- CV_IA64_CR39 = 4135,
- CV_IA64_CR40 = 4136,
- CV_IA64_CR41 = 4137,
- CV_IA64_CR42 = 4138,
- CV_IA64_CR43 = 4139,
- CV_IA64_CR44 = 4140,
- CV_IA64_CR45 = 4141,
- CV_IA64_CR46 = 4142,
- CV_IA64_CR47 = 4143,
- CV_IA64_CR48 = 4144,
- CV_IA64_CR49 = 4145,
- CV_IA64_CR50 = 4146,
- CV_IA64_CR51 = 4147,
- CV_IA64_CR52 = 4148,
- CV_IA64_CR53 = 4149,
- CV_IA64_CR54 = 4150,
- CV_IA64_CR55 = 4151,
- CV_IA64_CR56 = 4152,
- CV_IA64_CR57 = 4153,
- CV_IA64_CR58 = 4154,
- CV_IA64_CR59 = 4155,
- CV_IA64_CR60 = 4156,
- CV_IA64_CR61 = 4157,
- CV_IA64_CR62 = 4158,
- CV_IA64_CR63 = 4159,
- CV_IA64_SaLID = 4160,
- CV_IA64_SaIVR = 4161,
- CV_IA64_SaTPR = 4162,
- CV_IA64_SaEOI = 4163,
- CV_IA64_SaIRR0 = 4164,
- CV_IA64_SaIRR1 = 4165,
- CV_IA64_SaIRR2 = 4166,
- CV_IA64_SaIRR3 = 4167,
- CV_IA64_SaITV = 4168,
- CV_IA64_SaPMV = 4169,
- CV_IA64_SaCMCV = 4170,
- CV_IA64_CR75 = 4171,
- CV_IA64_CR76 = 4172,
- CV_IA64_CR77 = 4173,
- CV_IA64_CR78 = 4174,
- CV_IA64_CR79 = 4175,
- CV_IA64_SaLRR0 = 4176,
- CV_IA64_SaLRR1 = 4177,
- CV_IA64_CR82 = 4178,
- CV_IA64_CR83 = 4179,
- CV_IA64_CR84 = 4180,
- CV_IA64_CR85 = 4181,
- CV_IA64_CR86 = 4182,
- CV_IA64_CR87 = 4183,
- CV_IA64_CR88 = 4184,
- CV_IA64_CR89 = 4185,
- CV_IA64_CR90 = 4186,
- CV_IA64_CR91 = 4187,
- CV_IA64_CR92 = 4188,
- CV_IA64_CR93 = 4189,
- CV_IA64_CR94 = 4190,
- CV_IA64_CR95 = 4191,
- CV_IA64_CR96 = 4192,
- CV_IA64_CR97 = 4193,
- CV_IA64_CR98 = 4194,
- CV_IA64_CR99 = 4195,
- CV_IA64_CR100 = 4196,
- CV_IA64_CR101 = 4197,
- CV_IA64_CR102 = 4198,
- CV_IA64_CR103 = 4199,
- CV_IA64_CR104 = 4200,
- CV_IA64_CR105 = 4201,
- CV_IA64_CR106 = 4202,
- CV_IA64_CR107 = 4203,
- CV_IA64_CR108 = 4204,
- CV_IA64_CR109 = 4205,
- CV_IA64_CR110 = 4206,
- CV_IA64_CR111 = 4207,
- CV_IA64_CR112 = 4208,
- CV_IA64_CR113 = 4209,
- CV_IA64_CR114 = 4210,
- CV_IA64_CR115 = 4211,
- CV_IA64_CR116 = 4212,
- CV_IA64_CR117 = 4213,
- CV_IA64_CR118 = 4214,
- CV_IA64_CR119 = 4215,
- CV_IA64_CR120 = 4216,
- CV_IA64_CR121 = 4217,
- CV_IA64_CR122 = 4218,
- CV_IA64_CR123 = 4219,
- CV_IA64_CR124 = 4220,
- CV_IA64_CR125 = 4221,
- CV_IA64_CR126 = 4222,
- CV_IA64_CR127 = 4223,
-
- // Protection Key Registers
-
- CV_IA64_Pkr0 = 5120,
- CV_IA64_Pkr1 = 5121,
- CV_IA64_Pkr2 = 5122,
- CV_IA64_Pkr3 = 5123,
- CV_IA64_Pkr4 = 5124,
- CV_IA64_Pkr5 = 5125,
- CV_IA64_Pkr6 = 5126,
- CV_IA64_Pkr7 = 5127,
- CV_IA64_Pkr8 = 5128,
- CV_IA64_Pkr9 = 5129,
- CV_IA64_Pkr10 = 5130,
- CV_IA64_Pkr11 = 5131,
- CV_IA64_Pkr12 = 5132,
- CV_IA64_Pkr13 = 5133,
- CV_IA64_Pkr14 = 5134,
- CV_IA64_Pkr15 = 5135,
-
- // Region Registers
-
- CV_IA64_Rr0 = 6144,
- CV_IA64_Rr1 = 6145,
- CV_IA64_Rr2 = 6146,
- CV_IA64_Rr3 = 6147,
- CV_IA64_Rr4 = 6148,
- CV_IA64_Rr5 = 6149,
- CV_IA64_Rr6 = 6150,
- CV_IA64_Rr7 = 6151,
-
- // Performance Monitor Data Registers
-
- CV_IA64_PFD0 = 7168,
- CV_IA64_PFD1 = 7169,
- CV_IA64_PFD2 = 7170,
- CV_IA64_PFD3 = 7171,
- CV_IA64_PFD4 = 7172,
- CV_IA64_PFD5 = 7173,
- CV_IA64_PFD6 = 7174,
- CV_IA64_PFD7 = 7175,
- CV_IA64_PFD8 = 7176,
- CV_IA64_PFD9 = 7177,
- CV_IA64_PFD10 = 7178,
- CV_IA64_PFD11 = 7179,
- CV_IA64_PFD12 = 7180,
- CV_IA64_PFD13 = 7181,
- CV_IA64_PFD14 = 7182,
- CV_IA64_PFD15 = 7183,
- CV_IA64_PFD16 = 7184,
- CV_IA64_PFD17 = 7185,
-
- // Performance Monitor Config Registers
-
- CV_IA64_PFC0 = 7424,
- CV_IA64_PFC1 = 7425,
- CV_IA64_PFC2 = 7426,
- CV_IA64_PFC3 = 7427,
- CV_IA64_PFC4 = 7428,
- CV_IA64_PFC5 = 7429,
- CV_IA64_PFC6 = 7430,
- CV_IA64_PFC7 = 7431,
- CV_IA64_PFC8 = 7432,
- CV_IA64_PFC9 = 7433,
- CV_IA64_PFC10 = 7434,
- CV_IA64_PFC11 = 7435,
- CV_IA64_PFC12 = 7436,
- CV_IA64_PFC13 = 7437,
- CV_IA64_PFC14 = 7438,
- CV_IA64_PFC15 = 7439,
-
- // Instruction Translation Registers
-
- CV_IA64_TrI0 = 8192,
- CV_IA64_TrI1 = 8193,
- CV_IA64_TrI2 = 8194,
- CV_IA64_TrI3 = 8195,
- CV_IA64_TrI4 = 8196,
- CV_IA64_TrI5 = 8197,
- CV_IA64_TrI6 = 8198,
- CV_IA64_TrI7 = 8199,
-
- // Data Translation Registers
-
- CV_IA64_TrD0 = 8320,
- CV_IA64_TrD1 = 8321,
- CV_IA64_TrD2 = 8322,
- CV_IA64_TrD3 = 8323,
- CV_IA64_TrD4 = 8324,
- CV_IA64_TrD5 = 8325,
- CV_IA64_TrD6 = 8326,
- CV_IA64_TrD7 = 8327,
-
- // Instruction Breakpoint Registers
-
- CV_IA64_DbI0 = 8448,
- CV_IA64_DbI1 = 8449,
- CV_IA64_DbI2 = 8450,
- CV_IA64_DbI3 = 8451,
- CV_IA64_DbI4 = 8452,
- CV_IA64_DbI5 = 8453,
- CV_IA64_DbI6 = 8454,
- CV_IA64_DbI7 = 8455,
-
- // Data Breakpoint Registers
-
- CV_IA64_DbD0 = 8576,
- CV_IA64_DbD1 = 8577,
- CV_IA64_DbD2 = 8578,
- CV_IA64_DbD3 = 8579,
- CV_IA64_DbD4 = 8580,
- CV_IA64_DbD5 = 8581,
- CV_IA64_DbD6 = 8582,
- CV_IA64_DbD7 = 8583,
-
- //
- // Register set for the TriCore processor.
- //
-
- CV_TRI_NOREG = CV_REG_NONE,
-
- // General Purpose Data Registers
-
- CV_TRI_D0 = 10,
- CV_TRI_D1 = 11,
- CV_TRI_D2 = 12,
- CV_TRI_D3 = 13,
- CV_TRI_D4 = 14,
- CV_TRI_D5 = 15,
- CV_TRI_D6 = 16,
- CV_TRI_D7 = 17,
- CV_TRI_D8 = 18,
- CV_TRI_D9 = 19,
- CV_TRI_D10 = 20,
- CV_TRI_D11 = 21,
- CV_TRI_D12 = 22,
- CV_TRI_D13 = 23,
- CV_TRI_D14 = 24,
- CV_TRI_D15 = 25,
-
- // General Purpose Address Registers
-
- CV_TRI_A0 = 26,
- CV_TRI_A1 = 27,
- CV_TRI_A2 = 28,
- CV_TRI_A3 = 29,
- CV_TRI_A4 = 30,
- CV_TRI_A5 = 31,
- CV_TRI_A6 = 32,
- CV_TRI_A7 = 33,
- CV_TRI_A8 = 34,
- CV_TRI_A9 = 35,
- CV_TRI_A10 = 36,
- CV_TRI_A11 = 37,
- CV_TRI_A12 = 38,
- CV_TRI_A13 = 39,
- CV_TRI_A14 = 40,
- CV_TRI_A15 = 41,
-
- // Extended (64-bit) data registers
-
- CV_TRI_E0 = 42,
- CV_TRI_E2 = 43,
- CV_TRI_E4 = 44,
- CV_TRI_E6 = 45,
- CV_TRI_E8 = 46,
- CV_TRI_E10 = 47,
- CV_TRI_E12 = 48,
- CV_TRI_E14 = 49,
-
- // Extended (64-bit) address registers
-
- CV_TRI_EA0 = 50,
- CV_TRI_EA2 = 51,
- CV_TRI_EA4 = 52,
- CV_TRI_EA6 = 53,
- CV_TRI_EA8 = 54,
- CV_TRI_EA10 = 55,
- CV_TRI_EA12 = 56,
- CV_TRI_EA14 = 57,
-
- CV_TRI_PSW = 58,
- CV_TRI_PCXI = 59,
- CV_TRI_PC = 60,
- CV_TRI_FCX = 61,
- CV_TRI_LCX = 62,
- CV_TRI_ISP = 63,
- CV_TRI_ICR = 64,
- CV_TRI_BIV = 65,
- CV_TRI_BTV = 66,
- CV_TRI_SYSCON = 67,
- CV_TRI_DPRx_0 = 68,
- CV_TRI_DPRx_1 = 69,
- CV_TRI_DPRx_2 = 70,
- CV_TRI_DPRx_3 = 71,
- CV_TRI_CPRx_0 = 68,
- CV_TRI_CPRx_1 = 69,
- CV_TRI_CPRx_2 = 70,
- CV_TRI_CPRx_3 = 71,
- CV_TRI_DPMx_0 = 68,
- CV_TRI_DPMx_1 = 69,
- CV_TRI_DPMx_2 = 70,
- CV_TRI_DPMx_3 = 71,
- CV_TRI_CPMx_0 = 68,
- CV_TRI_CPMx_1 = 69,
- CV_TRI_CPMx_2 = 70,
- CV_TRI_CPMx_3 = 71,
- CV_TRI_DBGSSR = 72,
- CV_TRI_EXEVT = 73,
- CV_TRI_SWEVT = 74,
- CV_TRI_CREVT = 75,
- CV_TRI_TRnEVT = 76,
- CV_TRI_MMUCON = 77,
- CV_TRI_ASI = 78,
- CV_TRI_TVA = 79,
- CV_TRI_TPA = 80,
- CV_TRI_TPX = 81,
- CV_TRI_TFA = 82,
-
- //
- // Register set for the AM33 and related processors.
- //
-
- CV_AM33_NOREG = CV_REG_NONE,
-
- // "Extended" (general purpose integer) registers
- CV_AM33_E0 = 10,
- CV_AM33_E1 = 11,
- CV_AM33_E2 = 12,
- CV_AM33_E3 = 13,
- CV_AM33_E4 = 14,
- CV_AM33_E5 = 15,
- CV_AM33_E6 = 16,
- CV_AM33_E7 = 17,
-
- // Address registers
- CV_AM33_A0 = 20,
- CV_AM33_A1 = 21,
- CV_AM33_A2 = 22,
- CV_AM33_A3 = 23,
-
- // Integer data registers
- CV_AM33_D0 = 30,
- CV_AM33_D1 = 31,
- CV_AM33_D2 = 32,
- CV_AM33_D3 = 33,
-
- // (Single-precision) floating-point registers
- CV_AM33_FS0 = 40,
- CV_AM33_FS1 = 41,
- CV_AM33_FS2 = 42,
- CV_AM33_FS3 = 43,
- CV_AM33_FS4 = 44,
- CV_AM33_FS5 = 45,
- CV_AM33_FS6 = 46,
- CV_AM33_FS7 = 47,
- CV_AM33_FS8 = 48,
- CV_AM33_FS9 = 49,
- CV_AM33_FS10 = 50,
- CV_AM33_FS11 = 51,
- CV_AM33_FS12 = 52,
- CV_AM33_FS13 = 53,
- CV_AM33_FS14 = 54,
- CV_AM33_FS15 = 55,
- CV_AM33_FS16 = 56,
- CV_AM33_FS17 = 57,
- CV_AM33_FS18 = 58,
- CV_AM33_FS19 = 59,
- CV_AM33_FS20 = 60,
- CV_AM33_FS21 = 61,
- CV_AM33_FS22 = 62,
- CV_AM33_FS23 = 63,
- CV_AM33_FS24 = 64,
- CV_AM33_FS25 = 65,
- CV_AM33_FS26 = 66,
- CV_AM33_FS27 = 67,
- CV_AM33_FS28 = 68,
- CV_AM33_FS29 = 69,
- CV_AM33_FS30 = 70,
- CV_AM33_FS31 = 71,
-
- // Special purpose registers
-
- // Stack pointer
- CV_AM33_SP = 80,
-
- // Program counter
- CV_AM33_PC = 81,
-
- // Multiply-divide/accumulate registers
- CV_AM33_MDR = 82,
- CV_AM33_MDRQ = 83,
- CV_AM33_MCRH = 84,
- CV_AM33_MCRL = 85,
- CV_AM33_MCVF = 86,
-
- // CPU status words
- CV_AM33_EPSW = 87,
- CV_AM33_FPCR = 88,
-
- // Loop buffer registers
- CV_AM33_LIR = 89,
- CV_AM33_LAR = 90,
-
- //
- // Register set for the Mitsubishi M32R
- //
-
- CV_M32R_NOREG = CV_REG_NONE,
-
- CV_M32R_R0 = 10,
- CV_M32R_R1 = 11,
- CV_M32R_R2 = 12,
- CV_M32R_R3 = 13,
- CV_M32R_R4 = 14,
- CV_M32R_R5 = 15,
- CV_M32R_R6 = 16,
- CV_M32R_R7 = 17,
- CV_M32R_R8 = 18,
- CV_M32R_R9 = 19,
- CV_M32R_R10 = 20,
- CV_M32R_R11 = 21,
- CV_M32R_R12 = 22, // Gloabal Pointer, if used
- CV_M32R_R13 = 23, // Frame Pointer, if allocated
- CV_M32R_R14 = 24, // Link Register
- CV_M32R_R15 = 25, // Stack Pointer
- CV_M32R_PSW = 26, // Preocessor Status Register
- CV_M32R_CBR = 27, // Condition Bit Register
- CV_M32R_SPI = 28, // Interrupt Stack Pointer
- CV_M32R_SPU = 29, // User Stack Pointer
- CV_M32R_SPO = 30, // OS Stack Pointer
- CV_M32R_BPC = 31, // Backup Program Counter
- CV_M32R_ACHI = 32, // Accumulator High
- CV_M32R_ACLO = 33, // Accumulator Low
- CV_M32R_PC = 34, // Program Counter
-
- //
- // Register set for the SuperH SHMedia processor including compact
- // mode
- //
-
- // Integer - 64 bit general registers
- CV_SHMEDIA_NOREG = CV_REG_NONE,
- CV_SHMEDIA_R0 = 10,
- CV_SHMEDIA_R1 = 11,
- CV_SHMEDIA_R2 = 12,
- CV_SHMEDIA_R3 = 13,
- CV_SHMEDIA_R4 = 14,
- CV_SHMEDIA_R5 = 15,
- CV_SHMEDIA_R6 = 16,
- CV_SHMEDIA_R7 = 17,
- CV_SHMEDIA_R8 = 18,
- CV_SHMEDIA_R9 = 19,
- CV_SHMEDIA_R10 = 20,
- CV_SHMEDIA_R11 = 21,
- CV_SHMEDIA_R12 = 22,
- CV_SHMEDIA_R13 = 23,
- CV_SHMEDIA_R14 = 24,
- CV_SHMEDIA_R15 = 25,
- CV_SHMEDIA_R16 = 26,
- CV_SHMEDIA_R17 = 27,
- CV_SHMEDIA_R18 = 28,
- CV_SHMEDIA_R19 = 29,
- CV_SHMEDIA_R20 = 30,
- CV_SHMEDIA_R21 = 31,
- CV_SHMEDIA_R22 = 32,
- CV_SHMEDIA_R23 = 33,
- CV_SHMEDIA_R24 = 34,
- CV_SHMEDIA_R25 = 35,
- CV_SHMEDIA_R26 = 36,
- CV_SHMEDIA_R27 = 37,
- CV_SHMEDIA_R28 = 38,
- CV_SHMEDIA_R29 = 39,
- CV_SHMEDIA_R30 = 40,
- CV_SHMEDIA_R31 = 41,
- CV_SHMEDIA_R32 = 42,
- CV_SHMEDIA_R33 = 43,
- CV_SHMEDIA_R34 = 44,
- CV_SHMEDIA_R35 = 45,
- CV_SHMEDIA_R36 = 46,
- CV_SHMEDIA_R37 = 47,
- CV_SHMEDIA_R38 = 48,
- CV_SHMEDIA_R39 = 49,
- CV_SHMEDIA_R40 = 50,
- CV_SHMEDIA_R41 = 51,
- CV_SHMEDIA_R42 = 52,
- CV_SHMEDIA_R43 = 53,
- CV_SHMEDIA_R44 = 54,
- CV_SHMEDIA_R45 = 55,
- CV_SHMEDIA_R46 = 56,
- CV_SHMEDIA_R47 = 57,
- CV_SHMEDIA_R48 = 58,
- CV_SHMEDIA_R49 = 59,
- CV_SHMEDIA_R50 = 60,
- CV_SHMEDIA_R51 = 61,
- CV_SHMEDIA_R52 = 62,
- CV_SHMEDIA_R53 = 63,
- CV_SHMEDIA_R54 = 64,
- CV_SHMEDIA_R55 = 65,
- CV_SHMEDIA_R56 = 66,
- CV_SHMEDIA_R57 = 67,
- CV_SHMEDIA_R58 = 68,
- CV_SHMEDIA_R59 = 69,
- CV_SHMEDIA_R60 = 70,
- CV_SHMEDIA_R61 = 71,
- CV_SHMEDIA_R62 = 72,
- CV_SHMEDIA_R63 = 73,
-
- // Target Registers - 32 bit
- CV_SHMEDIA_TR0 = 74,
- CV_SHMEDIA_TR1 = 75,
- CV_SHMEDIA_TR2 = 76,
- CV_SHMEDIA_TR3 = 77,
- CV_SHMEDIA_TR4 = 78,
- CV_SHMEDIA_TR5 = 79,
- CV_SHMEDIA_TR6 = 80,
- CV_SHMEDIA_TR7 = 81,
- CV_SHMEDIA_TR8 = 82, // future-proof
- CV_SHMEDIA_TR9 = 83, // future-proof
- CV_SHMEDIA_TR10 = 84, // future-proof
- CV_SHMEDIA_TR11 = 85, // future-proof
- CV_SHMEDIA_TR12 = 86, // future-proof
- CV_SHMEDIA_TR13 = 87, // future-proof
- CV_SHMEDIA_TR14 = 88, // future-proof
- CV_SHMEDIA_TR15 = 89, // future-proof
-
- // Single - 32 bit fp registers
- CV_SHMEDIA_FR0 = 128,
- CV_SHMEDIA_FR1 = 129,
- CV_SHMEDIA_FR2 = 130,
- CV_SHMEDIA_FR3 = 131,
- CV_SHMEDIA_FR4 = 132,
- CV_SHMEDIA_FR5 = 133,
- CV_SHMEDIA_FR6 = 134,
- CV_SHMEDIA_FR7 = 135,
- CV_SHMEDIA_FR8 = 136,
- CV_SHMEDIA_FR9 = 137,
- CV_SHMEDIA_FR10 = 138,
- CV_SHMEDIA_FR11 = 139,
- CV_SHMEDIA_FR12 = 140,
- CV_SHMEDIA_FR13 = 141,
- CV_SHMEDIA_FR14 = 142,
- CV_SHMEDIA_FR15 = 143,
- CV_SHMEDIA_FR16 = 144,
- CV_SHMEDIA_FR17 = 145,
- CV_SHMEDIA_FR18 = 146,
- CV_SHMEDIA_FR19 = 147,
- CV_SHMEDIA_FR20 = 148,
- CV_SHMEDIA_FR21 = 149,
- CV_SHMEDIA_FR22 = 150,
- CV_SHMEDIA_FR23 = 151,
- CV_SHMEDIA_FR24 = 152,
- CV_SHMEDIA_FR25 = 153,
- CV_SHMEDIA_FR26 = 154,
- CV_SHMEDIA_FR27 = 155,
- CV_SHMEDIA_FR28 = 156,
- CV_SHMEDIA_FR29 = 157,
- CV_SHMEDIA_FR30 = 158,
- CV_SHMEDIA_FR31 = 159,
- CV_SHMEDIA_FR32 = 160,
- CV_SHMEDIA_FR33 = 161,
- CV_SHMEDIA_FR34 = 162,
- CV_SHMEDIA_FR35 = 163,
- CV_SHMEDIA_FR36 = 164,
- CV_SHMEDIA_FR37 = 165,
- CV_SHMEDIA_FR38 = 166,
- CV_SHMEDIA_FR39 = 167,
- CV_SHMEDIA_FR40 = 168,
- CV_SHMEDIA_FR41 = 169,
- CV_SHMEDIA_FR42 = 170,
- CV_SHMEDIA_FR43 = 171,
- CV_SHMEDIA_FR44 = 172,
- CV_SHMEDIA_FR45 = 173,
- CV_SHMEDIA_FR46 = 174,
- CV_SHMEDIA_FR47 = 175,
- CV_SHMEDIA_FR48 = 176,
- CV_SHMEDIA_FR49 = 177,
- CV_SHMEDIA_FR50 = 178,
- CV_SHMEDIA_FR51 = 179,
- CV_SHMEDIA_FR52 = 180,
- CV_SHMEDIA_FR53 = 181,
- CV_SHMEDIA_FR54 = 182,
- CV_SHMEDIA_FR55 = 183,
- CV_SHMEDIA_FR56 = 184,
- CV_SHMEDIA_FR57 = 185,
- CV_SHMEDIA_FR58 = 186,
- CV_SHMEDIA_FR59 = 187,
- CV_SHMEDIA_FR60 = 188,
- CV_SHMEDIA_FR61 = 189,
- CV_SHMEDIA_FR62 = 190,
- CV_SHMEDIA_FR63 = 191,
-
- // Double - 64 bit synonyms for 32bit fp register pairs
- // subtract 128 to find first base single register
- CV_SHMEDIA_DR0 = 256,
- CV_SHMEDIA_DR2 = 258,
- CV_SHMEDIA_DR4 = 260,
- CV_SHMEDIA_DR6 = 262,
- CV_SHMEDIA_DR8 = 264,
- CV_SHMEDIA_DR10 = 266,
- CV_SHMEDIA_DR12 = 268,
- CV_SHMEDIA_DR14 = 270,
- CV_SHMEDIA_DR16 = 272,
- CV_SHMEDIA_DR18 = 274,
- CV_SHMEDIA_DR20 = 276,
- CV_SHMEDIA_DR22 = 278,
- CV_SHMEDIA_DR24 = 280,
- CV_SHMEDIA_DR26 = 282,
- CV_SHMEDIA_DR28 = 284,
- CV_SHMEDIA_DR30 = 286,
- CV_SHMEDIA_DR32 = 288,
- CV_SHMEDIA_DR34 = 290,
- CV_SHMEDIA_DR36 = 292,
- CV_SHMEDIA_DR38 = 294,
- CV_SHMEDIA_DR40 = 296,
- CV_SHMEDIA_DR42 = 298,
- CV_SHMEDIA_DR44 = 300,
- CV_SHMEDIA_DR46 = 302,
- CV_SHMEDIA_DR48 = 304,
- CV_SHMEDIA_DR50 = 306,
- CV_SHMEDIA_DR52 = 308,
- CV_SHMEDIA_DR54 = 310,
- CV_SHMEDIA_DR56 = 312,
- CV_SHMEDIA_DR58 = 314,
- CV_SHMEDIA_DR60 = 316,
- CV_SHMEDIA_DR62 = 318,
-
- // Vector - 128 bit synonyms for 32bit fp register quads
- // subtract 384 to find first base single register
- CV_SHMEDIA_FV0 = 512,
- CV_SHMEDIA_FV4 = 516,
- CV_SHMEDIA_FV8 = 520,
- CV_SHMEDIA_FV12 = 524,
- CV_SHMEDIA_FV16 = 528,
- CV_SHMEDIA_FV20 = 532,
- CV_SHMEDIA_FV24 = 536,
- CV_SHMEDIA_FV28 = 540,
- CV_SHMEDIA_FV32 = 544,
- CV_SHMEDIA_FV36 = 548,
- CV_SHMEDIA_FV40 = 552,
- CV_SHMEDIA_FV44 = 556,
- CV_SHMEDIA_FV48 = 560,
- CV_SHMEDIA_FV52 = 564,
- CV_SHMEDIA_FV56 = 568,
- CV_SHMEDIA_FV60 = 572,
-
- // Matrix - 512 bit synonyms for 16 adjacent 32bit fp registers
- // subtract 896 to find first base single register
- CV_SHMEDIA_MTRX0 = 1024,
- CV_SHMEDIA_MTRX16 = 1040,
- CV_SHMEDIA_MTRX32 = 1056,
- CV_SHMEDIA_MTRX48 = 1072,
-
- // Control - Implementation defined 64bit control registers
- CV_SHMEDIA_CR0 = 2000,
- CV_SHMEDIA_CR1 = 2001,
- CV_SHMEDIA_CR2 = 2002,
- CV_SHMEDIA_CR3 = 2003,
- CV_SHMEDIA_CR4 = 2004,
- CV_SHMEDIA_CR5 = 2005,
- CV_SHMEDIA_CR6 = 2006,
- CV_SHMEDIA_CR7 = 2007,
- CV_SHMEDIA_CR8 = 2008,
- CV_SHMEDIA_CR9 = 2009,
- CV_SHMEDIA_CR10 = 2010,
- CV_SHMEDIA_CR11 = 2011,
- CV_SHMEDIA_CR12 = 2012,
- CV_SHMEDIA_CR13 = 2013,
- CV_SHMEDIA_CR14 = 2014,
- CV_SHMEDIA_CR15 = 2015,
- CV_SHMEDIA_CR16 = 2016,
- CV_SHMEDIA_CR17 = 2017,
- CV_SHMEDIA_CR18 = 2018,
- CV_SHMEDIA_CR19 = 2019,
- CV_SHMEDIA_CR20 = 2020,
- CV_SHMEDIA_CR21 = 2021,
- CV_SHMEDIA_CR22 = 2022,
- CV_SHMEDIA_CR23 = 2023,
- CV_SHMEDIA_CR24 = 2024,
- CV_SHMEDIA_CR25 = 2025,
- CV_SHMEDIA_CR26 = 2026,
- CV_SHMEDIA_CR27 = 2027,
- CV_SHMEDIA_CR28 = 2028,
- CV_SHMEDIA_CR29 = 2029,
- CV_SHMEDIA_CR30 = 2030,
- CV_SHMEDIA_CR31 = 2031,
- CV_SHMEDIA_CR32 = 2032,
- CV_SHMEDIA_CR33 = 2033,
- CV_SHMEDIA_CR34 = 2034,
- CV_SHMEDIA_CR35 = 2035,
- CV_SHMEDIA_CR36 = 2036,
- CV_SHMEDIA_CR37 = 2037,
- CV_SHMEDIA_CR38 = 2038,
- CV_SHMEDIA_CR39 = 2039,
- CV_SHMEDIA_CR40 = 2040,
- CV_SHMEDIA_CR41 = 2041,
- CV_SHMEDIA_CR42 = 2042,
- CV_SHMEDIA_CR43 = 2043,
- CV_SHMEDIA_CR44 = 2044,
- CV_SHMEDIA_CR45 = 2045,
- CV_SHMEDIA_CR46 = 2046,
- CV_SHMEDIA_CR47 = 2047,
- CV_SHMEDIA_CR48 = 2048,
- CV_SHMEDIA_CR49 = 2049,
- CV_SHMEDIA_CR50 = 2050,
- CV_SHMEDIA_CR51 = 2051,
- CV_SHMEDIA_CR52 = 2052,
- CV_SHMEDIA_CR53 = 2053,
- CV_SHMEDIA_CR54 = 2054,
- CV_SHMEDIA_CR55 = 2055,
- CV_SHMEDIA_CR56 = 2056,
- CV_SHMEDIA_CR57 = 2057,
- CV_SHMEDIA_CR58 = 2058,
- CV_SHMEDIA_CR59 = 2059,
- CV_SHMEDIA_CR60 = 2060,
- CV_SHMEDIA_CR61 = 2061,
- CV_SHMEDIA_CR62 = 2062,
- CV_SHMEDIA_CR63 = 2063,
-
- CV_SHMEDIA_FPSCR = 2064,
-
- // Compact mode synonyms
- CV_SHMEDIA_GBR = CV_SHMEDIA_R16,
- CV_SHMEDIA_MACL = 90, // synonym for lower 32bits of media R17
- CV_SHMEDIA_MACH = 91, // synonym for upper 32bits of media R17
- CV_SHMEDIA_PR = CV_SHMEDIA_R18,
- CV_SHMEDIA_T = 92, // synonym for lowest bit of media R19
- CV_SHMEDIA_FPUL = CV_SHMEDIA_FR32,
- CV_SHMEDIA_PC = 93,
- CV_SHMEDIA_SR = CV_SHMEDIA_CR0,
-
- //
- // AMD64 registers
- //
-
- CV_AMD64_AL = 1,
- CV_AMD64_CL = 2,
- CV_AMD64_DL = 3,
- CV_AMD64_BL = 4,
- CV_AMD64_AH = 5,
- CV_AMD64_CH = 6,
- CV_AMD64_DH = 7,
- CV_AMD64_BH = 8,
- CV_AMD64_AX = 9,
- CV_AMD64_CX = 10,
- CV_AMD64_DX = 11,
- CV_AMD64_BX = 12,
- CV_AMD64_SP = 13,
- CV_AMD64_BP = 14,
- CV_AMD64_SI = 15,
- CV_AMD64_DI = 16,
- CV_AMD64_EAX = 17,
- CV_AMD64_ECX = 18,
- CV_AMD64_EDX = 19,
- CV_AMD64_EBX = 20,
- CV_AMD64_ESP = 21,
- CV_AMD64_EBP = 22,
- CV_AMD64_ESI = 23,
- CV_AMD64_EDI = 24,
- CV_AMD64_ES = 25,
- CV_AMD64_CS = 26,
- CV_AMD64_SS = 27,
- CV_AMD64_DS = 28,
- CV_AMD64_FS = 29,
- CV_AMD64_GS = 30,
- CV_AMD64_FLAGS = 32,
- CV_AMD64_RIP = 33,
- CV_AMD64_EFLAGS = 34,
-
- // Control registers
- CV_AMD64_CR0 = 80,
- CV_AMD64_CR1 = 81,
- CV_AMD64_CR2 = 82,
- CV_AMD64_CR3 = 83,
- CV_AMD64_CR4 = 84,
- CV_AMD64_CR8 = 88,
-
- // Debug registers
- CV_AMD64_DR0 = 90,
- CV_AMD64_DR1 = 91,
- CV_AMD64_DR2 = 92,
- CV_AMD64_DR3 = 93,
- CV_AMD64_DR4 = 94,
- CV_AMD64_DR5 = 95,
- CV_AMD64_DR6 = 96,
- CV_AMD64_DR7 = 97,
- CV_AMD64_DR8 = 98,
- CV_AMD64_DR9 = 99,
- CV_AMD64_DR10 = 100,
- CV_AMD64_DR11 = 101,
- CV_AMD64_DR12 = 102,
- CV_AMD64_DR13 = 103,
- CV_AMD64_DR14 = 104,
- CV_AMD64_DR15 = 105,
-
- CV_AMD64_GDTR = 110,
- CV_AMD64_GDTL = 111,
- CV_AMD64_IDTR = 112,
- CV_AMD64_IDTL = 113,
- CV_AMD64_LDTR = 114,
- CV_AMD64_TR = 115,
-
- CV_AMD64_ST0 = 128,
- CV_AMD64_ST1 = 129,
- CV_AMD64_ST2 = 130,
- CV_AMD64_ST3 = 131,
- CV_AMD64_ST4 = 132,
- CV_AMD64_ST5 = 133,
- CV_AMD64_ST6 = 134,
- CV_AMD64_ST7 = 135,
- CV_AMD64_CTRL = 136,
- CV_AMD64_STAT = 137,
- CV_AMD64_TAG = 138,
- CV_AMD64_FPIP = 139,
- CV_AMD64_FPCS = 140,
- CV_AMD64_FPDO = 141,
- CV_AMD64_FPDS = 142,
- CV_AMD64_ISEM = 143,
- CV_AMD64_FPEIP = 144,
- CV_AMD64_FPEDO = 145,
-
- CV_AMD64_MM0 = 146,
- CV_AMD64_MM1 = 147,
- CV_AMD64_MM2 = 148,
- CV_AMD64_MM3 = 149,
- CV_AMD64_MM4 = 150,
- CV_AMD64_MM5 = 151,
- CV_AMD64_MM6 = 152,
- CV_AMD64_MM7 = 153,
-
- CV_AMD64_XMM0 = 154, // KATMAI registers
- CV_AMD64_XMM1 = 155,
- CV_AMD64_XMM2 = 156,
- CV_AMD64_XMM3 = 157,
- CV_AMD64_XMM4 = 158,
- CV_AMD64_XMM5 = 159,
- CV_AMD64_XMM6 = 160,
- CV_AMD64_XMM7 = 161,
-
- CV_AMD64_XMM0_0 = 162, // KATMAI sub-registers
- CV_AMD64_XMM0_1 = 163,
- CV_AMD64_XMM0_2 = 164,
- CV_AMD64_XMM0_3 = 165,
- CV_AMD64_XMM1_0 = 166,
- CV_AMD64_XMM1_1 = 167,
- CV_AMD64_XMM1_2 = 168,
- CV_AMD64_XMM1_3 = 169,
- CV_AMD64_XMM2_0 = 170,
- CV_AMD64_XMM2_1 = 171,
- CV_AMD64_XMM2_2 = 172,
- CV_AMD64_XMM2_3 = 173,
- CV_AMD64_XMM3_0 = 174,
- CV_AMD64_XMM3_1 = 175,
- CV_AMD64_XMM3_2 = 176,
- CV_AMD64_XMM3_3 = 177,
- CV_AMD64_XMM4_0 = 178,
- CV_AMD64_XMM4_1 = 179,
- CV_AMD64_XMM4_2 = 180,
- CV_AMD64_XMM4_3 = 181,
- CV_AMD64_XMM5_0 = 182,
- CV_AMD64_XMM5_1 = 183,
- CV_AMD64_XMM5_2 = 184,
- CV_AMD64_XMM5_3 = 185,
- CV_AMD64_XMM6_0 = 186,
- CV_AMD64_XMM6_1 = 187,
- CV_AMD64_XMM6_2 = 188,
- CV_AMD64_XMM6_3 = 189,
- CV_AMD64_XMM7_0 = 190,
- CV_AMD64_XMM7_1 = 191,
- CV_AMD64_XMM7_2 = 192,
- CV_AMD64_XMM7_3 = 193,
-
- CV_AMD64_XMM0L = 194,
- CV_AMD64_XMM1L = 195,
- CV_AMD64_XMM2L = 196,
- CV_AMD64_XMM3L = 197,
- CV_AMD64_XMM4L = 198,
- CV_AMD64_XMM5L = 199,
- CV_AMD64_XMM6L = 200,
- CV_AMD64_XMM7L = 201,
-
- CV_AMD64_XMM0H = 202,
- CV_AMD64_XMM1H = 203,
- CV_AMD64_XMM2H = 204,
- CV_AMD64_XMM3H = 205,
- CV_AMD64_XMM4H = 206,
- CV_AMD64_XMM5H = 207,
- CV_AMD64_XMM6H = 208,
- CV_AMD64_XMM7H = 209,
-
- CV_AMD64_MXCSR = 211, // XMM status register
-
- CV_AMD64_EMM0L = 220, // XMM sub-registers (WNI integer)
- CV_AMD64_EMM1L = 221,
- CV_AMD64_EMM2L = 222,
- CV_AMD64_EMM3L = 223,
- CV_AMD64_EMM4L = 224,
- CV_AMD64_EMM5L = 225,
- CV_AMD64_EMM6L = 226,
- CV_AMD64_EMM7L = 227,
-
- CV_AMD64_EMM0H = 228,
- CV_AMD64_EMM1H = 229,
- CV_AMD64_EMM2H = 230,
- CV_AMD64_EMM3H = 231,
- CV_AMD64_EMM4H = 232,
- CV_AMD64_EMM5H = 233,
- CV_AMD64_EMM6H = 234,
- CV_AMD64_EMM7H = 235,
-
- // do not change the order of these regs, first one must be even too
- CV_AMD64_MM00 = 236,
- CV_AMD64_MM01 = 237,
- CV_AMD64_MM10 = 238,
- CV_AMD64_MM11 = 239,
- CV_AMD64_MM20 = 240,
- CV_AMD64_MM21 = 241,
- CV_AMD64_MM30 = 242,
- CV_AMD64_MM31 = 243,
- CV_AMD64_MM40 = 244,
- CV_AMD64_MM41 = 245,
- CV_AMD64_MM50 = 246,
- CV_AMD64_MM51 = 247,
- CV_AMD64_MM60 = 248,
- CV_AMD64_MM61 = 249,
- CV_AMD64_MM70 = 250,
- CV_AMD64_MM71 = 251,
-
- // Extended KATMAI registers
- CV_AMD64_XMM8 = 252, // KATMAI registers
- CV_AMD64_XMM9 = 253,
- CV_AMD64_XMM10 = 254,
- CV_AMD64_XMM11 = 255,
- CV_AMD64_XMM12 = 256,
- CV_AMD64_XMM13 = 257,
- CV_AMD64_XMM14 = 258,
- CV_AMD64_XMM15 = 259,
-
- CV_AMD64_XMM8_0 = 260, // KATMAI sub-registers
- CV_AMD64_XMM8_1 = 261,
- CV_AMD64_XMM8_2 = 262,
- CV_AMD64_XMM8_3 = 263,
- CV_AMD64_XMM9_0 = 264,
- CV_AMD64_XMM9_1 = 265,
- CV_AMD64_XMM9_2 = 266,
- CV_AMD64_XMM9_3 = 267,
- CV_AMD64_XMM10_0 = 268,
- CV_AMD64_XMM10_1 = 269,
- CV_AMD64_XMM10_2 = 270,
- CV_AMD64_XMM10_3 = 271,
- CV_AMD64_XMM11_0 = 272,
- CV_AMD64_XMM11_1 = 273,
- CV_AMD64_XMM11_2 = 274,
- CV_AMD64_XMM11_3 = 275,
- CV_AMD64_XMM12_0 = 276,
- CV_AMD64_XMM12_1 = 277,
- CV_AMD64_XMM12_2 = 278,
- CV_AMD64_XMM12_3 = 279,
- CV_AMD64_XMM13_0 = 280,
- CV_AMD64_XMM13_1 = 281,
- CV_AMD64_XMM13_2 = 282,
- CV_AMD64_XMM13_3 = 283,
- CV_AMD64_XMM14_0 = 284,
- CV_AMD64_XMM14_1 = 285,
- CV_AMD64_XMM14_2 = 286,
- CV_AMD64_XMM14_3 = 287,
- CV_AMD64_XMM15_0 = 288,
- CV_AMD64_XMM15_1 = 289,
- CV_AMD64_XMM15_2 = 290,
- CV_AMD64_XMM15_3 = 291,
-
- CV_AMD64_XMM8L = 292,
- CV_AMD64_XMM9L = 293,
- CV_AMD64_XMM10L = 294,
- CV_AMD64_XMM11L = 295,
- CV_AMD64_XMM12L = 296,
- CV_AMD64_XMM13L = 297,
- CV_AMD64_XMM14L = 298,
- CV_AMD64_XMM15L = 299,
-
- CV_AMD64_XMM8H = 300,
- CV_AMD64_XMM9H = 301,
- CV_AMD64_XMM10H = 302,
- CV_AMD64_XMM11H = 303,
- CV_AMD64_XMM12H = 304,
- CV_AMD64_XMM13H = 305,
- CV_AMD64_XMM14H = 306,
- CV_AMD64_XMM15H = 307,
-
- CV_AMD64_EMM8L = 308, // XMM sub-registers (WNI integer)
- CV_AMD64_EMM9L = 309,
- CV_AMD64_EMM10L = 310,
- CV_AMD64_EMM11L = 311,
- CV_AMD64_EMM12L = 312,
- CV_AMD64_EMM13L = 313,
- CV_AMD64_EMM14L = 314,
- CV_AMD64_EMM15L = 315,
-
- CV_AMD64_EMM8H = 316,
- CV_AMD64_EMM9H = 317,
- CV_AMD64_EMM10H = 318,
- CV_AMD64_EMM11H = 319,
- CV_AMD64_EMM12H = 320,
- CV_AMD64_EMM13H = 321,
- CV_AMD64_EMM14H = 322,
- CV_AMD64_EMM15H = 323,
-
- // Low byte forms of some standard registers
- CV_AMD64_SIL = 324,
- CV_AMD64_DIL = 325,
- CV_AMD64_BPL = 326,
- CV_AMD64_SPL = 327,
-
- // 64-bit regular registers
- CV_AMD64_RAX = 328,
- CV_AMD64_RBX = 329,
- CV_AMD64_RCX = 330,
- CV_AMD64_RDX = 331,
- CV_AMD64_RSI = 332,
- CV_AMD64_RDI = 333,
- CV_AMD64_RBP = 334,
- CV_AMD64_RSP = 335,
-
- // 64-bit integer registers with 8-, 16-, and 32-bit forms (B, W, and D)
- CV_AMD64_R8 = 336,
- CV_AMD64_R9 = 337,
- CV_AMD64_R10 = 338,
- CV_AMD64_R11 = 339,
- CV_AMD64_R12 = 340,
- CV_AMD64_R13 = 341,
- CV_AMD64_R14 = 342,
- CV_AMD64_R15 = 343,
-
- CV_AMD64_R8B = 344,
- CV_AMD64_R9B = 345,
- CV_AMD64_R10B = 346,
- CV_AMD64_R11B = 347,
- CV_AMD64_R12B = 348,
- CV_AMD64_R13B = 349,
- CV_AMD64_R14B = 350,
- CV_AMD64_R15B = 351,
-
- CV_AMD64_R8W = 352,
- CV_AMD64_R9W = 353,
- CV_AMD64_R10W = 354,
- CV_AMD64_R11W = 355,
- CV_AMD64_R12W = 356,
- CV_AMD64_R13W = 357,
- CV_AMD64_R14W = 358,
- CV_AMD64_R15W = 359,
-
- CV_AMD64_R8D = 360,
- CV_AMD64_R9D = 361,
- CV_AMD64_R10D = 362,
- CV_AMD64_R11D = 363,
- CV_AMD64_R12D = 364,
- CV_AMD64_R13D = 365,
- CV_AMD64_R14D = 366,
- CV_AMD64_R15D = 367,
-
- // AVX registers 256 bits
- CV_AMD64_YMM0 = 368,
- CV_AMD64_YMM1 = 369,
- CV_AMD64_YMM2 = 370,
- CV_AMD64_YMM3 = 371,
- CV_AMD64_YMM4 = 372,
- CV_AMD64_YMM5 = 373,
- CV_AMD64_YMM6 = 374,
- CV_AMD64_YMM7 = 375,
- CV_AMD64_YMM8 = 376,
- CV_AMD64_YMM9 = 377,
- CV_AMD64_YMM10 = 378,
- CV_AMD64_YMM11 = 379,
- CV_AMD64_YMM12 = 380,
- CV_AMD64_YMM13 = 381,
- CV_AMD64_YMM14 = 382,
- CV_AMD64_YMM15 = 383,
-
- // AVX registers upper 128 bits
- CV_AMD64_YMM0H = 384,
- CV_AMD64_YMM1H = 385,
- CV_AMD64_YMM2H = 386,
- CV_AMD64_YMM3H = 387,
- CV_AMD64_YMM4H = 388,
- CV_AMD64_YMM5H = 389,
- CV_AMD64_YMM6H = 390,
- CV_AMD64_YMM7H = 391,
- CV_AMD64_YMM8H = 392,
- CV_AMD64_YMM9H = 393,
- CV_AMD64_YMM10H = 394,
- CV_AMD64_YMM11H = 395,
- CV_AMD64_YMM12H = 396,
- CV_AMD64_YMM13H = 397,
- CV_AMD64_YMM14H = 398,
- CV_AMD64_YMM15H = 399,
-
- //Lower/upper 8 bytes of XMM registers. Unlike CV_AMD64_XMM<regnum><H/L>, these
- //values reprsesent the bit patterns of the registers as 64-bit integers, not
- //the representation of these registers as a double.
- CV_AMD64_XMM0IL = 400,
- CV_AMD64_XMM1IL = 401,
- CV_AMD64_XMM2IL = 402,
- CV_AMD64_XMM3IL = 403,
- CV_AMD64_XMM4IL = 404,
- CV_AMD64_XMM5IL = 405,
- CV_AMD64_XMM6IL = 406,
- CV_AMD64_XMM7IL = 407,
- CV_AMD64_XMM8IL = 408,
- CV_AMD64_XMM9IL = 409,
- CV_AMD64_XMM10IL = 410,
- CV_AMD64_XMM11IL = 411,
- CV_AMD64_XMM12IL = 412,
- CV_AMD64_XMM13IL = 413,
- CV_AMD64_XMM14IL = 414,
- CV_AMD64_XMM15IL = 415,
-
- CV_AMD64_XMM0IH = 416,
- CV_AMD64_XMM1IH = 417,
- CV_AMD64_XMM2IH = 418,
- CV_AMD64_XMM3IH = 419,
- CV_AMD64_XMM4IH = 420,
- CV_AMD64_XMM5IH = 421,
- CV_AMD64_XMM6IH = 422,
- CV_AMD64_XMM7IH = 423,
- CV_AMD64_XMM8IH = 424,
- CV_AMD64_XMM9IH = 425,
- CV_AMD64_XMM10IH = 426,
- CV_AMD64_XMM11IH = 427,
- CV_AMD64_XMM12IH = 428,
- CV_AMD64_XMM13IH = 429,
- CV_AMD64_XMM14IH = 430,
- CV_AMD64_XMM15IH = 431,
-
- CV_AMD64_YMM0I0 = 432, // AVX integer registers
- CV_AMD64_YMM0I1 = 433,
- CV_AMD64_YMM0I2 = 434,
- CV_AMD64_YMM0I3 = 435,
- CV_AMD64_YMM1I0 = 436,
- CV_AMD64_YMM1I1 = 437,
- CV_AMD64_YMM1I2 = 438,
- CV_AMD64_YMM1I3 = 439,
- CV_AMD64_YMM2I0 = 440,
- CV_AMD64_YMM2I1 = 441,
- CV_AMD64_YMM2I2 = 442,
- CV_AMD64_YMM2I3 = 443,
- CV_AMD64_YMM3I0 = 444,
- CV_AMD64_YMM3I1 = 445,
- CV_AMD64_YMM3I2 = 446,
- CV_AMD64_YMM3I3 = 447,
- CV_AMD64_YMM4I0 = 448,
- CV_AMD64_YMM4I1 = 449,
- CV_AMD64_YMM4I2 = 450,
- CV_AMD64_YMM4I3 = 451,
- CV_AMD64_YMM5I0 = 452,
- CV_AMD64_YMM5I1 = 453,
- CV_AMD64_YMM5I2 = 454,
- CV_AMD64_YMM5I3 = 455,
- CV_AMD64_YMM6I0 = 456,
- CV_AMD64_YMM6I1 = 457,
- CV_AMD64_YMM6I2 = 458,
- CV_AMD64_YMM6I3 = 459,
- CV_AMD64_YMM7I0 = 460,
- CV_AMD64_YMM7I1 = 461,
- CV_AMD64_YMM7I2 = 462,
- CV_AMD64_YMM7I3 = 463,
- CV_AMD64_YMM8I0 = 464,
- CV_AMD64_YMM8I1 = 465,
- CV_AMD64_YMM8I2 = 466,
- CV_AMD64_YMM8I3 = 467,
- CV_AMD64_YMM9I0 = 468,
- CV_AMD64_YMM9I1 = 469,
- CV_AMD64_YMM9I2 = 470,
- CV_AMD64_YMM9I3 = 471,
- CV_AMD64_YMM10I0 = 472,
- CV_AMD64_YMM10I1 = 473,
- CV_AMD64_YMM10I2 = 474,
- CV_AMD64_YMM10I3 = 475,
- CV_AMD64_YMM11I0 = 476,
- CV_AMD64_YMM11I1 = 477,
- CV_AMD64_YMM11I2 = 478,
- CV_AMD64_YMM11I3 = 479,
- CV_AMD64_YMM12I0 = 480,
- CV_AMD64_YMM12I1 = 481,
- CV_AMD64_YMM12I2 = 482,
- CV_AMD64_YMM12I3 = 483,
- CV_AMD64_YMM13I0 = 484,
- CV_AMD64_YMM13I1 = 485,
- CV_AMD64_YMM13I2 = 486,
- CV_AMD64_YMM13I3 = 487,
- CV_AMD64_YMM14I0 = 488,
- CV_AMD64_YMM14I1 = 489,
- CV_AMD64_YMM14I2 = 490,
- CV_AMD64_YMM14I3 = 491,
- CV_AMD64_YMM15I0 = 492,
- CV_AMD64_YMM15I1 = 493,
- CV_AMD64_YMM15I2 = 494,
- CV_AMD64_YMM15I3 = 495,
-
- CV_AMD64_YMM0F0 = 496, // AVX floating-point single precise registers
- CV_AMD64_YMM0F1 = 497,
- CV_AMD64_YMM0F2 = 498,
- CV_AMD64_YMM0F3 = 499,
- CV_AMD64_YMM0F4 = 500,
- CV_AMD64_YMM0F5 = 501,
- CV_AMD64_YMM0F6 = 502,
- CV_AMD64_YMM0F7 = 503,
- CV_AMD64_YMM1F0 = 504,
- CV_AMD64_YMM1F1 = 505,
- CV_AMD64_YMM1F2 = 506,
- CV_AMD64_YMM1F3 = 507,
- CV_AMD64_YMM1F4 = 508,
- CV_AMD64_YMM1F5 = 509,
- CV_AMD64_YMM1F6 = 510,
- CV_AMD64_YMM1F7 = 511,
- CV_AMD64_YMM2F0 = 512,
- CV_AMD64_YMM2F1 = 513,
- CV_AMD64_YMM2F2 = 514,
- CV_AMD64_YMM2F3 = 515,
- CV_AMD64_YMM2F4 = 516,
- CV_AMD64_YMM2F5 = 517,
- CV_AMD64_YMM2F6 = 518,
- CV_AMD64_YMM2F7 = 519,
- CV_AMD64_YMM3F0 = 520,
- CV_AMD64_YMM3F1 = 521,
- CV_AMD64_YMM3F2 = 522,
- CV_AMD64_YMM3F3 = 523,
- CV_AMD64_YMM3F4 = 524,
- CV_AMD64_YMM3F5 = 525,
- CV_AMD64_YMM3F6 = 526,
- CV_AMD64_YMM3F7 = 527,
- CV_AMD64_YMM4F0 = 528,
- CV_AMD64_YMM4F1 = 529,
- CV_AMD64_YMM4F2 = 530,
- CV_AMD64_YMM4F3 = 531,
- CV_AMD64_YMM4F4 = 532,
- CV_AMD64_YMM4F5 = 533,
- CV_AMD64_YMM4F6 = 534,
- CV_AMD64_YMM4F7 = 535,
- CV_AMD64_YMM5F0 = 536,
- CV_AMD64_YMM5F1 = 537,
- CV_AMD64_YMM5F2 = 538,
- CV_AMD64_YMM5F3 = 539,
- CV_AMD64_YMM5F4 = 540,
- CV_AMD64_YMM5F5 = 541,
- CV_AMD64_YMM5F6 = 542,
- CV_AMD64_YMM5F7 = 543,
- CV_AMD64_YMM6F0 = 544,
- CV_AMD64_YMM6F1 = 545,
- CV_AMD64_YMM6F2 = 546,
- CV_AMD64_YMM6F3 = 547,
- CV_AMD64_YMM6F4 = 548,
- CV_AMD64_YMM6F5 = 549,
- CV_AMD64_YMM6F6 = 550,
- CV_AMD64_YMM6F7 = 551,
- CV_AMD64_YMM7F0 = 552,
- CV_AMD64_YMM7F1 = 553,
- CV_AMD64_YMM7F2 = 554,
- CV_AMD64_YMM7F3 = 555,
- CV_AMD64_YMM7F4 = 556,
- CV_AMD64_YMM7F5 = 557,
- CV_AMD64_YMM7F6 = 558,
- CV_AMD64_YMM7F7 = 559,
- CV_AMD64_YMM8F0 = 560,
- CV_AMD64_YMM8F1 = 561,
- CV_AMD64_YMM8F2 = 562,
- CV_AMD64_YMM8F3 = 563,
- CV_AMD64_YMM8F4 = 564,
- CV_AMD64_YMM8F5 = 565,
- CV_AMD64_YMM8F6 = 566,
- CV_AMD64_YMM8F7 = 567,
- CV_AMD64_YMM9F0 = 568,
- CV_AMD64_YMM9F1 = 569,
- CV_AMD64_YMM9F2 = 570,
- CV_AMD64_YMM9F3 = 571,
- CV_AMD64_YMM9F4 = 572,
- CV_AMD64_YMM9F5 = 573,
- CV_AMD64_YMM9F6 = 574,
- CV_AMD64_YMM9F7 = 575,
- CV_AMD64_YMM10F0 = 576,
- CV_AMD64_YMM10F1 = 577,
- CV_AMD64_YMM10F2 = 578,
- CV_AMD64_YMM10F3 = 579,
- CV_AMD64_YMM10F4 = 580,
- CV_AMD64_YMM10F5 = 581,
- CV_AMD64_YMM10F6 = 582,
- CV_AMD64_YMM10F7 = 583,
- CV_AMD64_YMM11F0 = 584,
- CV_AMD64_YMM11F1 = 585,
- CV_AMD64_YMM11F2 = 586,
- CV_AMD64_YMM11F3 = 587,
- CV_AMD64_YMM11F4 = 588,
- CV_AMD64_YMM11F5 = 589,
- CV_AMD64_YMM11F6 = 590,
- CV_AMD64_YMM11F7 = 591,
- CV_AMD64_YMM12F0 = 592,
- CV_AMD64_YMM12F1 = 593,
- CV_AMD64_YMM12F2 = 594,
- CV_AMD64_YMM12F3 = 595,
- CV_AMD64_YMM12F4 = 596,
- CV_AMD64_YMM12F5 = 597,
- CV_AMD64_YMM12F6 = 598,
- CV_AMD64_YMM12F7 = 599,
- CV_AMD64_YMM13F0 = 600,
- CV_AMD64_YMM13F1 = 601,
- CV_AMD64_YMM13F2 = 602,
- CV_AMD64_YMM13F3 = 603,
- CV_AMD64_YMM13F4 = 604,
- CV_AMD64_YMM13F5 = 605,
- CV_AMD64_YMM13F6 = 606,
- CV_AMD64_YMM13F7 = 607,
- CV_AMD64_YMM14F0 = 608,
- CV_AMD64_YMM14F1 = 609,
- CV_AMD64_YMM14F2 = 610,
- CV_AMD64_YMM14F3 = 611,
- CV_AMD64_YMM14F4 = 612,
- CV_AMD64_YMM14F5 = 613,
- CV_AMD64_YMM14F6 = 614,
- CV_AMD64_YMM14F7 = 615,
- CV_AMD64_YMM15F0 = 616,
- CV_AMD64_YMM15F1 = 617,
- CV_AMD64_YMM15F2 = 618,
- CV_AMD64_YMM15F3 = 619,
- CV_AMD64_YMM15F4 = 620,
- CV_AMD64_YMM15F5 = 621,
- CV_AMD64_YMM15F6 = 622,
- CV_AMD64_YMM15F7 = 623,
-
- CV_AMD64_YMM0D0 = 624, // AVX floating-point double precise registers
- CV_AMD64_YMM0D1 = 625,
- CV_AMD64_YMM0D2 = 626,
- CV_AMD64_YMM0D3 = 627,
- CV_AMD64_YMM1D0 = 628,
- CV_AMD64_YMM1D1 = 629,
- CV_AMD64_YMM1D2 = 630,
- CV_AMD64_YMM1D3 = 631,
- CV_AMD64_YMM2D0 = 632,
- CV_AMD64_YMM2D1 = 633,
- CV_AMD64_YMM2D2 = 634,
- CV_AMD64_YMM2D3 = 635,
- CV_AMD64_YMM3D0 = 636,
- CV_AMD64_YMM3D1 = 637,
- CV_AMD64_YMM3D2 = 638,
- CV_AMD64_YMM3D3 = 639,
- CV_AMD64_YMM4D0 = 640,
- CV_AMD64_YMM4D1 = 641,
- CV_AMD64_YMM4D2 = 642,
- CV_AMD64_YMM4D3 = 643,
- CV_AMD64_YMM5D0 = 644,
- CV_AMD64_YMM5D1 = 645,
- CV_AMD64_YMM5D2 = 646,
- CV_AMD64_YMM5D3 = 647,
- CV_AMD64_YMM6D0 = 648,
- CV_AMD64_YMM6D1 = 649,
- CV_AMD64_YMM6D2 = 650,
- CV_AMD64_YMM6D3 = 651,
- CV_AMD64_YMM7D0 = 652,
- CV_AMD64_YMM7D1 = 653,
- CV_AMD64_YMM7D2 = 654,
- CV_AMD64_YMM7D3 = 655,
- CV_AMD64_YMM8D0 = 656,
- CV_AMD64_YMM8D1 = 657,
- CV_AMD64_YMM8D2 = 658,
- CV_AMD64_YMM8D3 = 659,
- CV_AMD64_YMM9D0 = 660,
- CV_AMD64_YMM9D1 = 661,
- CV_AMD64_YMM9D2 = 662,
- CV_AMD64_YMM9D3 = 663,
- CV_AMD64_YMM10D0 = 664,
- CV_AMD64_YMM10D1 = 665,
- CV_AMD64_YMM10D2 = 666,
- CV_AMD64_YMM10D3 = 667,
- CV_AMD64_YMM11D0 = 668,
- CV_AMD64_YMM11D1 = 669,
- CV_AMD64_YMM11D2 = 670,
- CV_AMD64_YMM11D3 = 671,
- CV_AMD64_YMM12D0 = 672,
- CV_AMD64_YMM12D1 = 673,
- CV_AMD64_YMM12D2 = 674,
- CV_AMD64_YMM12D3 = 675,
- CV_AMD64_YMM13D0 = 676,
- CV_AMD64_YMM13D1 = 677,
- CV_AMD64_YMM13D2 = 678,
- CV_AMD64_YMM13D3 = 679,
- CV_AMD64_YMM14D0 = 680,
- CV_AMD64_YMM14D1 = 681,
- CV_AMD64_YMM14D2 = 682,
- CV_AMD64_YMM14D3 = 683,
- CV_AMD64_YMM15D0 = 684,
- CV_AMD64_YMM15D1 = 685,
- CV_AMD64_YMM15D2 = 686,
- CV_AMD64_YMM15D3 = 687
-
-
- // Note: Next set of platform registers need to go into a new enum...
- // this one is above 44K now.
-
-} CV_HREG_e;
-
-enum StackFrameTypeEnum
-{
- FrameTypeFPO, // Frame pointer omitted, FPO info available
- FrameTypeTrap, // Kernel Trap frame
- FrameTypeTSS, // Kernel Trap frame
- FrameTypeStandard, // Standard EBP stackframe
- FrameTypeFrameData, // Frame pointer omitted, FrameData info available
-
- FrameTypeUnknown = -1, // Frame which does not have any debug info
-};
-
-enum MemoryTypeEnum
-{
- MemTypeCode, // Read only code memory
- MemTypeData, // Read only data/stack memory
- MemTypeStack, // Read only stack memory
-
- MemTypeAny = -1,
-};
-
-#endif
diff --git a/src/ToolBox/PdbTypeMatch/include/dia2.h b/src/ToolBox/PdbTypeMatch/include/dia2.h
deleted file mode 100644
index 3f400b0575..0000000000
--- a/src/ToolBox/PdbTypeMatch/include/dia2.h
+++ /dev/null
@@ -1,7854 +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.
-
-/* this ALWAYS GENERATED file contains the definitions for the interfaces */
-
-
- /* File created by MIDL compiler version 7.00.0499 */
-/* Compiler settings for dia2.idl:
- Oicf, W1, Zp8, env=Win32 (32b run)
- protocol : dce , ms_ext, c_ext, robust
- error checks: allocation ref bounds_check enum stub_data
- VC __declspec() decoration level:
- __declspec(uuid()), __declspec(selectany), __declspec(novtable)
- DECLSPEC_UUID(), MIDL_INTERFACE()
-*/
-//@@MIDL_FILE_HEADING( )
-
-#pragma warning( disable: 4049 ) /* more than 64k source lines */
-
-
-/* verify that the <rpcndr.h> version is high enough to compile this file*/
-#ifndef __REQUIRED_RPCNDR_H_VERSION__
-#define __REQUIRED_RPCNDR_H_VERSION__ 475
-#endif
-
-/* verify that the <rpcsal.h> version is high enough to compile this file*/
-#ifndef __REQUIRED_RPCSAL_H_VERSION__
-#define __REQUIRED_RPCSAL_H_VERSION__ 100
-#endif
-
-#include "rpc.h"
-#include "rpcndr.h"
-
-#ifndef __RPCNDR_H_VERSION__
-#error this stub requires an updated version of <rpcndr.h>
-#endif // __RPCNDR_H_VERSION__
-
-#ifndef COM_NO_WINDOWS_H
-#include "windows.h"
-#include "ole2.h"
-#endif /*COM_NO_WINDOWS_H*/
-
-#ifndef __dia2_h__
-#define __dia2_h__
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-#pragma once
-#endif
-
-/* Forward Declarations */
-
-#ifndef __IDiaLoadCallback_FWD_DEFINED__
-#define __IDiaLoadCallback_FWD_DEFINED__
-typedef interface IDiaLoadCallback IDiaLoadCallback;
-#endif /* __IDiaLoadCallback_FWD_DEFINED__ */
-
-
-#ifndef __IDiaLoadCallback2_FWD_DEFINED__
-#define __IDiaLoadCallback2_FWD_DEFINED__
-typedef interface IDiaLoadCallback2 IDiaLoadCallback2;
-#endif /* __IDiaLoadCallback2_FWD_DEFINED__ */
-
-
-#ifndef __IDiaReadExeAtOffsetCallback_FWD_DEFINED__
-#define __IDiaReadExeAtOffsetCallback_FWD_DEFINED__
-typedef interface IDiaReadExeAtOffsetCallback IDiaReadExeAtOffsetCallback;
-#endif /* __IDiaReadExeAtOffsetCallback_FWD_DEFINED__ */
-
-
-#ifndef __IDiaReadExeAtRVACallback_FWD_DEFINED__
-#define __IDiaReadExeAtRVACallback_FWD_DEFINED__
-typedef interface IDiaReadExeAtRVACallback IDiaReadExeAtRVACallback;
-#endif /* __IDiaReadExeAtRVACallback_FWD_DEFINED__ */
-
-
-#ifndef __IDiaDataSource_FWD_DEFINED__
-#define __IDiaDataSource_FWD_DEFINED__
-typedef interface IDiaDataSource IDiaDataSource;
-#endif /* __IDiaDataSource_FWD_DEFINED__ */
-
-
-#ifndef __IDiaEnumSymbols_FWD_DEFINED__
-#define __IDiaEnumSymbols_FWD_DEFINED__
-typedef interface IDiaEnumSymbols IDiaEnumSymbols;
-#endif /* __IDiaEnumSymbols_FWD_DEFINED__ */
-
-
-#ifndef __IDiaEnumSymbolsByAddr_FWD_DEFINED__
-#define __IDiaEnumSymbolsByAddr_FWD_DEFINED__
-typedef interface IDiaEnumSymbolsByAddr IDiaEnumSymbolsByAddr;
-#endif /* __IDiaEnumSymbolsByAddr_FWD_DEFINED__ */
-
-
-#ifndef __IDiaEnumSourceFiles_FWD_DEFINED__
-#define __IDiaEnumSourceFiles_FWD_DEFINED__
-typedef interface IDiaEnumSourceFiles IDiaEnumSourceFiles;
-#endif /* __IDiaEnumSourceFiles_FWD_DEFINED__ */
-
-
-#ifndef __IDiaEnumLineNumbers_FWD_DEFINED__
-#define __IDiaEnumLineNumbers_FWD_DEFINED__
-typedef interface IDiaEnumLineNumbers IDiaEnumLineNumbers;
-#endif /* __IDiaEnumLineNumbers_FWD_DEFINED__ */
-
-
-#ifndef __IDiaEnumInjectedSources_FWD_DEFINED__
-#define __IDiaEnumInjectedSources_FWD_DEFINED__
-typedef interface IDiaEnumInjectedSources IDiaEnumInjectedSources;
-#endif /* __IDiaEnumInjectedSources_FWD_DEFINED__ */
-
-
-#ifndef __IDiaEnumSegments_FWD_DEFINED__
-#define __IDiaEnumSegments_FWD_DEFINED__
-typedef interface IDiaEnumSegments IDiaEnumSegments;
-#endif /* __IDiaEnumSegments_FWD_DEFINED__ */
-
-
-#ifndef __IDiaEnumSectionContribs_FWD_DEFINED__
-#define __IDiaEnumSectionContribs_FWD_DEFINED__
-typedef interface IDiaEnumSectionContribs IDiaEnumSectionContribs;
-#endif /* __IDiaEnumSectionContribs_FWD_DEFINED__ */
-
-
-#ifndef __IDiaEnumFrameData_FWD_DEFINED__
-#define __IDiaEnumFrameData_FWD_DEFINED__
-typedef interface IDiaEnumFrameData IDiaEnumFrameData;
-#endif /* __IDiaEnumFrameData_FWD_DEFINED__ */
-
-
-#ifndef __IDiaEnumDebugStreamData_FWD_DEFINED__
-#define __IDiaEnumDebugStreamData_FWD_DEFINED__
-typedef interface IDiaEnumDebugStreamData IDiaEnumDebugStreamData;
-#endif /* __IDiaEnumDebugStreamData_FWD_DEFINED__ */
-
-
-#ifndef __IDiaEnumDebugStreams_FWD_DEFINED__
-#define __IDiaEnumDebugStreams_FWD_DEFINED__
-typedef interface IDiaEnumDebugStreams IDiaEnumDebugStreams;
-#endif /* __IDiaEnumDebugStreams_FWD_DEFINED__ */
-
-
-#ifndef __IDiaAddressMap_FWD_DEFINED__
-#define __IDiaAddressMap_FWD_DEFINED__
-typedef interface IDiaAddressMap IDiaAddressMap;
-#endif /* __IDiaAddressMap_FWD_DEFINED__ */
-
-
-#ifndef __IDiaSession_FWD_DEFINED__
-#define __IDiaSession_FWD_DEFINED__
-typedef interface IDiaSession IDiaSession;
-#endif /* __IDiaSession_FWD_DEFINED__ */
-
-
-#ifndef __IDiaSymbol_FWD_DEFINED__
-#define __IDiaSymbol_FWD_DEFINED__
-typedef interface IDiaSymbol IDiaSymbol;
-#endif /* __IDiaSymbol_FWD_DEFINED__ */
-
-
-#ifndef __IDiaSourceFile_FWD_DEFINED__
-#define __IDiaSourceFile_FWD_DEFINED__
-typedef interface IDiaSourceFile IDiaSourceFile;
-#endif /* __IDiaSourceFile_FWD_DEFINED__ */
-
-
-#ifndef __IDiaLineNumber_FWD_DEFINED__
-#define __IDiaLineNumber_FWD_DEFINED__
-typedef interface IDiaLineNumber IDiaLineNumber;
-#endif /* __IDiaLineNumber_FWD_DEFINED__ */
-
-
-#ifndef __IDiaSectionContrib_FWD_DEFINED__
-#define __IDiaSectionContrib_FWD_DEFINED__
-typedef interface IDiaSectionContrib IDiaSectionContrib;
-#endif /* __IDiaSectionContrib_FWD_DEFINED__ */
-
-
-#ifndef __IDiaSegment_FWD_DEFINED__
-#define __IDiaSegment_FWD_DEFINED__
-typedef interface IDiaSegment IDiaSegment;
-#endif /* __IDiaSegment_FWD_DEFINED__ */
-
-
-#ifndef __IDiaInjectedSource_FWD_DEFINED__
-#define __IDiaInjectedSource_FWD_DEFINED__
-typedef interface IDiaInjectedSource IDiaInjectedSource;
-#endif /* __IDiaInjectedSource_FWD_DEFINED__ */
-
-
-#ifndef __IDiaStackWalkFrame_FWD_DEFINED__
-#define __IDiaStackWalkFrame_FWD_DEFINED__
-typedef interface IDiaStackWalkFrame IDiaStackWalkFrame;
-#endif /* __IDiaStackWalkFrame_FWD_DEFINED__ */
-
-
-#ifndef __IDiaFrameData_FWD_DEFINED__
-#define __IDiaFrameData_FWD_DEFINED__
-typedef interface IDiaFrameData IDiaFrameData;
-#endif /* __IDiaFrameData_FWD_DEFINED__ */
-
-
-#ifndef __IDiaImageData_FWD_DEFINED__
-#define __IDiaImageData_FWD_DEFINED__
-typedef interface IDiaImageData IDiaImageData;
-#endif /* __IDiaImageData_FWD_DEFINED__ */
-
-
-#ifndef __IDiaTable_FWD_DEFINED__
-#define __IDiaTable_FWD_DEFINED__
-typedef interface IDiaTable IDiaTable;
-#endif /* __IDiaTable_FWD_DEFINED__ */
-
-
-#ifndef __IDiaEnumTables_FWD_DEFINED__
-#define __IDiaEnumTables_FWD_DEFINED__
-typedef interface IDiaEnumTables IDiaEnumTables;
-#endif /* __IDiaEnumTables_FWD_DEFINED__ */
-
-
-#ifndef __DiaSource_FWD_DEFINED__
-#define __DiaSource_FWD_DEFINED__
-
-#ifdef __cplusplus
-typedef class DiaSource DiaSource;
-#else
-typedef struct DiaSource DiaSource;
-#endif /* __cplusplus */
-
-#endif /* __DiaSource_FWD_DEFINED__ */
-
-
-#ifndef __DiaSourceAlt_FWD_DEFINED__
-#define __DiaSourceAlt_FWD_DEFINED__
-
-#ifdef __cplusplus
-typedef class DiaSourceAlt DiaSourceAlt;
-#else
-typedef struct DiaSourceAlt DiaSourceAlt;
-#endif /* __cplusplus */
-
-#endif /* __DiaSourceAlt_FWD_DEFINED__ */
-
-
-#ifndef __DiaStackWalker_FWD_DEFINED__
-#define __DiaStackWalker_FWD_DEFINED__
-
-#ifdef __cplusplus
-typedef class DiaStackWalker DiaStackWalker;
-#else
-typedef struct DiaStackWalker DiaStackWalker;
-#endif /* __cplusplus */
-
-#endif /* __DiaStackWalker_FWD_DEFINED__ */
-
-
-#ifndef __IDiaPropertyStorage_FWD_DEFINED__
-#define __IDiaPropertyStorage_FWD_DEFINED__
-typedef interface IDiaPropertyStorage IDiaPropertyStorage;
-#endif /* __IDiaPropertyStorage_FWD_DEFINED__ */
-
-
-#ifndef __IDiaStackFrame_FWD_DEFINED__
-#define __IDiaStackFrame_FWD_DEFINED__
-typedef interface IDiaStackFrame IDiaStackFrame;
-#endif /* __IDiaStackFrame_FWD_DEFINED__ */
-
-
-#ifndef __IDiaEnumStackFrames_FWD_DEFINED__
-#define __IDiaEnumStackFrames_FWD_DEFINED__
-typedef interface IDiaEnumStackFrames IDiaEnumStackFrames;
-#endif /* __IDiaEnumStackFrames_FWD_DEFINED__ */
-
-
-#ifndef __IDiaStackWalkHelper_FWD_DEFINED__
-#define __IDiaStackWalkHelper_FWD_DEFINED__
-typedef interface IDiaStackWalkHelper IDiaStackWalkHelper;
-#endif /* __IDiaStackWalkHelper_FWD_DEFINED__ */
-
-
-#ifndef __IDiaStackWalker_FWD_DEFINED__
-#define __IDiaStackWalker_FWD_DEFINED__
-typedef interface IDiaStackWalker IDiaStackWalker;
-#endif /* __IDiaStackWalker_FWD_DEFINED__ */
-
-
-#ifndef __IDiaStackWalkHelper2_FWD_DEFINED__
-#define __IDiaStackWalkHelper2_FWD_DEFINED__
-typedef interface IDiaStackWalkHelper2 IDiaStackWalkHelper2;
-#endif /* __IDiaStackWalkHelper2_FWD_DEFINED__ */
-
-
-#ifndef __IDiaStackWalker2_FWD_DEFINED__
-#define __IDiaStackWalker2_FWD_DEFINED__
-typedef interface IDiaStackWalker2 IDiaStackWalker2;
-#endif /* __IDiaStackWalker2_FWD_DEFINED__ */
-
-
-/* header files for imported files */
-#include "objidl.h"
-#include "oaidl.h"
-#include "propidl.h"
-#include "cvconst.h"
-
-#ifdef __cplusplus
-extern "C"{
-#endif
-
-
-/* interface __MIDL_itf_dia2_0000_0000 */
-/* [local] */
-
-
-enum NameSearchOptions
- { nsNone = 0,
- nsfCaseSensitive = 0x1,
- nsfCaseInsensitive = 0x2,
- nsfFNameExt = 0x4,
- nsfRegularExpression = 0x8,
- nsfUndecoratedName = 0x10,
- nsCaseSensitive = nsfCaseSensitive,
- nsCaseInsensitive = nsfCaseInsensitive,
- nsFNameExt = ( nsfCaseInsensitive | nsfFNameExt ) ,
- nsRegularExpression = ( nsfRegularExpression | nsfCaseSensitive ) ,
- nsCaseInRegularExpression = ( nsfRegularExpression | nsfCaseInsensitive )
- } ;
-
-enum __MIDL___MIDL_itf_dia2_0000_0000_0001
- { E_PDB_OK = ( HRESULT )(( ( ( ( unsigned long )1 << 31 ) | ( ( unsigned long )( LONG )0x6d << 16 ) ) | ( unsigned long )1 ) ),
- E_PDB_USAGE = ( E_PDB_OK + 1 ) ,
- E_PDB_OUT_OF_MEMORY = ( E_PDB_USAGE + 1 ) ,
- E_PDB_FILE_SYSTEM = ( E_PDB_OUT_OF_MEMORY + 1 ) ,
- E_PDB_NOT_FOUND = ( E_PDB_FILE_SYSTEM + 1 ) ,
- E_PDB_INVALID_SIG = ( E_PDB_NOT_FOUND + 1 ) ,
- E_PDB_INVALID_AGE = ( E_PDB_INVALID_SIG + 1 ) ,
- E_PDB_PRECOMP_REQUIRED = ( E_PDB_INVALID_AGE + 1 ) ,
- E_PDB_OUT_OF_TI = ( E_PDB_PRECOMP_REQUIRED + 1 ) ,
- E_PDB_NOT_IMPLEMENTED = ( E_PDB_OUT_OF_TI + 1 ) ,
- E_PDB_V1_PDB = ( E_PDB_NOT_IMPLEMENTED + 1 ) ,
- E_PDB_FORMAT = ( E_PDB_V1_PDB + 1 ) ,
- E_PDB_LIMIT = ( E_PDB_FORMAT + 1 ) ,
- E_PDB_CORRUPT = ( E_PDB_LIMIT + 1 ) ,
- E_PDB_TI16 = ( E_PDB_CORRUPT + 1 ) ,
- E_PDB_ACCESS_DENIED = ( E_PDB_TI16 + 1 ) ,
- E_PDB_ILLEGAL_TYPE_EDIT = ( E_PDB_ACCESS_DENIED + 1 ) ,
- E_PDB_INVALID_EXECUTABLE = ( E_PDB_ILLEGAL_TYPE_EDIT + 1 ) ,
- E_PDB_DBG_NOT_FOUND = ( E_PDB_INVALID_EXECUTABLE + 1 ) ,
- E_PDB_NO_DEBUG_INFO = ( E_PDB_DBG_NOT_FOUND + 1 ) ,
- E_PDB_INVALID_EXE_TIMESTAMP = ( E_PDB_NO_DEBUG_INFO + 1 ) ,
- E_PDB_RESERVED = ( E_PDB_INVALID_EXE_TIMESTAMP + 1 ) ,
- E_PDB_DEBUG_INFO_NOT_IN_PDB = ( E_PDB_RESERVED + 1 ) ,
- E_PDB_SYMSRV_BAD_CACHE_PATH = ( E_PDB_DEBUG_INFO_NOT_IN_PDB + 1 ) ,
- E_PDB_SYMSRV_CACHE_FULL = ( E_PDB_SYMSRV_BAD_CACHE_PATH + 1 ) ,
- E_PDB_MAX = ( E_PDB_SYMSRV_CACHE_FULL + 1 )
- } ;
-typedef void ( __cdecl *PfnPDBDebugDirV )(
- BOOL __MIDL____MIDL_itf_dia2_0000_00000000,
- void *__MIDL____MIDL_itf_dia2_0000_00000001);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0000_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0000_v0_0_s_ifspec;
-
-#ifndef __IDiaLoadCallback_INTERFACE_DEFINED__
-#define __IDiaLoadCallback_INTERFACE_DEFINED__
-
-/* interface IDiaLoadCallback */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaLoadCallback;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("C32ADB82-73F4-421b-95D5-A4706EDF5DBE")
- IDiaLoadCallback : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE NotifyDebugDir(
- /* [in] */ BOOL fExecutable,
- /* [in] */ DWORD cbData,
- /* [size_is][in] */ BYTE *pbData) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE NotifyOpenDBG(
- /* [in] */ LPCOLESTR dbgPath,
- /* [in] */ HRESULT resultCode) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE NotifyOpenPDB(
- /* [in] */ LPCOLESTR pdbPath,
- /* [in] */ HRESULT resultCode) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE RestrictRegistryAccess( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE RestrictSymbolServerAccess( void) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaLoadCallbackVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaLoadCallback * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaLoadCallback * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaLoadCallback * This);
-
- HRESULT ( STDMETHODCALLTYPE *NotifyDebugDir )(
- IDiaLoadCallback * This,
- /* [in] */ BOOL fExecutable,
- /* [in] */ DWORD cbData,
- /* [size_is][in] */ BYTE *pbData);
-
- HRESULT ( STDMETHODCALLTYPE *NotifyOpenDBG )(
- IDiaLoadCallback * This,
- /* [in] */ LPCOLESTR dbgPath,
- /* [in] */ HRESULT resultCode);
-
- HRESULT ( STDMETHODCALLTYPE *NotifyOpenPDB )(
- IDiaLoadCallback * This,
- /* [in] */ LPCOLESTR pdbPath,
- /* [in] */ HRESULT resultCode);
-
- HRESULT ( STDMETHODCALLTYPE *RestrictRegistryAccess )(
- IDiaLoadCallback * This);
-
- HRESULT ( STDMETHODCALLTYPE *RestrictSymbolServerAccess )(
- IDiaLoadCallback * This);
-
- END_INTERFACE
- } IDiaLoadCallbackVtbl;
-
- interface IDiaLoadCallback
- {
- CONST_VTBL struct IDiaLoadCallbackVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaLoadCallback_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaLoadCallback_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaLoadCallback_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaLoadCallback_NotifyDebugDir(This,fExecutable,cbData,pbData) \
- ( (This)->lpVtbl -> NotifyDebugDir(This,fExecutable,cbData,pbData) )
-
-#define IDiaLoadCallback_NotifyOpenDBG(This,dbgPath,resultCode) \
- ( (This)->lpVtbl -> NotifyOpenDBG(This,dbgPath,resultCode) )
-
-#define IDiaLoadCallback_NotifyOpenPDB(This,pdbPath,resultCode) \
- ( (This)->lpVtbl -> NotifyOpenPDB(This,pdbPath,resultCode) )
-
-#define IDiaLoadCallback_RestrictRegistryAccess(This) \
- ( (This)->lpVtbl -> RestrictRegistryAccess(This) )
-
-#define IDiaLoadCallback_RestrictSymbolServerAccess(This) \
- ( (This)->lpVtbl -> RestrictSymbolServerAccess(This) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaLoadCallback_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaLoadCallback2_INTERFACE_DEFINED__
-#define __IDiaLoadCallback2_INTERFACE_DEFINED__
-
-/* interface IDiaLoadCallback2 */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaLoadCallback2;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("4688a074-5a4d-4486-aea8-7b90711d9f7c")
- IDiaLoadCallback2 : public IDiaLoadCallback
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE RestrictOriginalPathAccess( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE RestrictReferencePathAccess( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE RestrictDBGAccess( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE RestrictSystemRootAccess( void) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaLoadCallback2Vtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaLoadCallback2 * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaLoadCallback2 * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaLoadCallback2 * This);
-
- HRESULT ( STDMETHODCALLTYPE *NotifyDebugDir )(
- IDiaLoadCallback2 * This,
- /* [in] */ BOOL fExecutable,
- /* [in] */ DWORD cbData,
- /* [size_is][in] */ BYTE *pbData);
-
- HRESULT ( STDMETHODCALLTYPE *NotifyOpenDBG )(
- IDiaLoadCallback2 * This,
- /* [in] */ LPCOLESTR dbgPath,
- /* [in] */ HRESULT resultCode);
-
- HRESULT ( STDMETHODCALLTYPE *NotifyOpenPDB )(
- IDiaLoadCallback2 * This,
- /* [in] */ LPCOLESTR pdbPath,
- /* [in] */ HRESULT resultCode);
-
- HRESULT ( STDMETHODCALLTYPE *RestrictRegistryAccess )(
- IDiaLoadCallback2 * This);
-
- HRESULT ( STDMETHODCALLTYPE *RestrictSymbolServerAccess )(
- IDiaLoadCallback2 * This);
-
- HRESULT ( STDMETHODCALLTYPE *RestrictOriginalPathAccess )(
- IDiaLoadCallback2 * This);
-
- HRESULT ( STDMETHODCALLTYPE *RestrictReferencePathAccess )(
- IDiaLoadCallback2 * This);
-
- HRESULT ( STDMETHODCALLTYPE *RestrictDBGAccess )(
- IDiaLoadCallback2 * This);
-
- HRESULT ( STDMETHODCALLTYPE *RestrictSystemRootAccess )(
- IDiaLoadCallback2 * This);
-
- END_INTERFACE
- } IDiaLoadCallback2Vtbl;
-
- interface IDiaLoadCallback2
- {
- CONST_VTBL struct IDiaLoadCallback2Vtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaLoadCallback2_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaLoadCallback2_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaLoadCallback2_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaLoadCallback2_NotifyDebugDir(This,fExecutable,cbData,pbData) \
- ( (This)->lpVtbl -> NotifyDebugDir(This,fExecutable,cbData,pbData) )
-
-#define IDiaLoadCallback2_NotifyOpenDBG(This,dbgPath,resultCode) \
- ( (This)->lpVtbl -> NotifyOpenDBG(This,dbgPath,resultCode) )
-
-#define IDiaLoadCallback2_NotifyOpenPDB(This,pdbPath,resultCode) \
- ( (This)->lpVtbl -> NotifyOpenPDB(This,pdbPath,resultCode) )
-
-#define IDiaLoadCallback2_RestrictRegistryAccess(This) \
- ( (This)->lpVtbl -> RestrictRegistryAccess(This) )
-
-#define IDiaLoadCallback2_RestrictSymbolServerAccess(This) \
- ( (This)->lpVtbl -> RestrictSymbolServerAccess(This) )
-
-
-#define IDiaLoadCallback2_RestrictOriginalPathAccess(This) \
- ( (This)->lpVtbl -> RestrictOriginalPathAccess(This) )
-
-#define IDiaLoadCallback2_RestrictReferencePathAccess(This) \
- ( (This)->lpVtbl -> RestrictReferencePathAccess(This) )
-
-#define IDiaLoadCallback2_RestrictDBGAccess(This) \
- ( (This)->lpVtbl -> RestrictDBGAccess(This) )
-
-#define IDiaLoadCallback2_RestrictSystemRootAccess(This) \
- ( (This)->lpVtbl -> RestrictSystemRootAccess(This) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaLoadCallback2_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaReadExeAtOffsetCallback_INTERFACE_DEFINED__
-#define __IDiaReadExeAtOffsetCallback_INTERFACE_DEFINED__
-
-/* interface IDiaReadExeAtOffsetCallback */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaReadExeAtOffsetCallback;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("587A461C-B80B-4f54-9194-5032589A6319")
- IDiaReadExeAtOffsetCallback : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE ReadExecutableAt(
- /* [in] */ DWORDLONG fileOffset,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaReadExeAtOffsetCallbackVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaReadExeAtOffsetCallback * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaReadExeAtOffsetCallback * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaReadExeAtOffsetCallback * This);
-
- HRESULT ( STDMETHODCALLTYPE *ReadExecutableAt )(
- IDiaReadExeAtOffsetCallback * This,
- /* [in] */ DWORDLONG fileOffset,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData);
-
- END_INTERFACE
- } IDiaReadExeAtOffsetCallbackVtbl;
-
- interface IDiaReadExeAtOffsetCallback
- {
- CONST_VTBL struct IDiaReadExeAtOffsetCallbackVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaReadExeAtOffsetCallback_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaReadExeAtOffsetCallback_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaReadExeAtOffsetCallback_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaReadExeAtOffsetCallback_ReadExecutableAt(This,fileOffset,cbData,pcbData,pbData) \
- ( (This)->lpVtbl -> ReadExecutableAt(This,fileOffset,cbData,pcbData,pbData) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaReadExeAtOffsetCallback_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaReadExeAtRVACallback_INTERFACE_DEFINED__
-#define __IDiaReadExeAtRVACallback_INTERFACE_DEFINED__
-
-/* interface IDiaReadExeAtRVACallback */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaReadExeAtRVACallback;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("8E3F80CA-7517-432a-BA07-285134AAEA8E")
- IDiaReadExeAtRVACallback : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE ReadExecutableAtRVA(
- /* [in] */ DWORD relativeVirtualAddress,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaReadExeAtRVACallbackVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaReadExeAtRVACallback * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaReadExeAtRVACallback * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaReadExeAtRVACallback * This);
-
- HRESULT ( STDMETHODCALLTYPE *ReadExecutableAtRVA )(
- IDiaReadExeAtRVACallback * This,
- /* [in] */ DWORD relativeVirtualAddress,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData);
-
- END_INTERFACE
- } IDiaReadExeAtRVACallbackVtbl;
-
- interface IDiaReadExeAtRVACallback
- {
- CONST_VTBL struct IDiaReadExeAtRVACallbackVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaReadExeAtRVACallback_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaReadExeAtRVACallback_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaReadExeAtRVACallback_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaReadExeAtRVACallback_ReadExecutableAtRVA(This,relativeVirtualAddress,cbData,pcbData,pbData) \
- ( (This)->lpVtbl -> ReadExecutableAtRVA(This,relativeVirtualAddress,cbData,pcbData,pbData) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaReadExeAtRVACallback_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaDataSource_INTERFACE_DEFINED__
-#define __IDiaDataSource_INTERFACE_DEFINED__
-
-/* interface IDiaDataSource */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaDataSource;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("79F1BB5F-B66E-48e5-B6A9-1545C323CA3D")
- IDiaDataSource : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lastError(
- /* [retval][out] */ BSTR *pRetVal) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE loadDataFromPdb(
- /* [in] */ LPCOLESTR pdbPath) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE loadAndValidateDataFromPdb(
- /* [in] */ LPCOLESTR pdbPath,
- /* [in] */ GUID *pcsig70,
- /* [in] */ DWORD sig,
- /* [in] */ DWORD age) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE loadDataForExe(
- /* [in] */ LPCOLESTR executable,
- /* [in] */ LPCOLESTR searchPath,
- /* [in] */ IUnknown *pCallback) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE loadDataFromIStream(
- /* [in] */ IStream *pIStream) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE openSession(
- /* [out] */ IDiaSession **ppSession) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaDataSourceVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaDataSource * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaDataSource * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaDataSource * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lastError )(
- IDiaDataSource * This,
- /* [retval][out] */ BSTR *pRetVal);
-
- HRESULT ( STDMETHODCALLTYPE *loadDataFromPdb )(
- IDiaDataSource * This,
- /* [in] */ LPCOLESTR pdbPath);
-
- HRESULT ( STDMETHODCALLTYPE *loadAndValidateDataFromPdb )(
- IDiaDataSource * This,
- /* [in] */ LPCOLESTR pdbPath,
- /* [in] */ GUID *pcsig70,
- /* [in] */ DWORD sig,
- /* [in] */ DWORD age);
-
- HRESULT ( STDMETHODCALLTYPE *loadDataForExe )(
- IDiaDataSource * This,
- /* [in] */ LPCOLESTR executable,
- /* [in] */ LPCOLESTR searchPath,
- /* [in] */ IUnknown *pCallback);
-
- HRESULT ( STDMETHODCALLTYPE *loadDataFromIStream )(
- IDiaDataSource * This,
- /* [in] */ IStream *pIStream);
-
- HRESULT ( STDMETHODCALLTYPE *openSession )(
- IDiaDataSource * This,
- /* [out] */ IDiaSession **ppSession);
-
- END_INTERFACE
- } IDiaDataSourceVtbl;
-
- interface IDiaDataSource
- {
- CONST_VTBL struct IDiaDataSourceVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaDataSource_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaDataSource_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaDataSource_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaDataSource_get_lastError(This,pRetVal) \
- ( (This)->lpVtbl -> get_lastError(This,pRetVal) )
-
-#define IDiaDataSource_loadDataFromPdb(This,pdbPath) \
- ( (This)->lpVtbl -> loadDataFromPdb(This,pdbPath) )
-
-#define IDiaDataSource_loadAndValidateDataFromPdb(This,pdbPath,pcsig70,sig,age) \
- ( (This)->lpVtbl -> loadAndValidateDataFromPdb(This,pdbPath,pcsig70,sig,age) )
-
-#define IDiaDataSource_loadDataForExe(This,executable,searchPath,pCallback) \
- ( (This)->lpVtbl -> loadDataForExe(This,executable,searchPath,pCallback) )
-
-#define IDiaDataSource_loadDataFromIStream(This,pIStream) \
- ( (This)->lpVtbl -> loadDataFromIStream(This,pIStream) )
-
-#define IDiaDataSource_openSession(This,ppSession) \
- ( (This)->lpVtbl -> openSession(This,ppSession) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaDataSource_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaEnumSymbols_INTERFACE_DEFINED__
-#define __IDiaEnumSymbols_INTERFACE_DEFINED__
-
-/* interface IDiaEnumSymbols */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaEnumSymbols;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("CAB72C48-443B-48f5-9B0B-42F0820AB29A")
- IDiaEnumSymbols : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
- /* [retval][out] */ IUnknown **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
- /* [retval][out] */ LONG *pRetVal) = 0;
-
- virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item(
- /* [in] */ DWORD index,
- /* [retval][out] */ IDiaSymbol **symbol) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Next(
- /* [in] */ ULONG celt,
- /* [out] */ IDiaSymbol **rgelt,
- /* [out] */ ULONG *pceltFetched) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Skip(
- /* [in] */ ULONG celt) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Clone(
- /* [out] */ IDiaEnumSymbols **ppenum) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaEnumSymbolsVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaEnumSymbols * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaEnumSymbols * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaEnumSymbols * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )(
- IDiaEnumSymbols * This,
- /* [retval][out] */ IUnknown **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )(
- IDiaEnumSymbols * This,
- /* [retval][out] */ LONG *pRetVal);
-
- /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )(
- IDiaEnumSymbols * This,
- /* [in] */ DWORD index,
- /* [retval][out] */ IDiaSymbol **symbol);
-
- HRESULT ( STDMETHODCALLTYPE *Next )(
- IDiaEnumSymbols * This,
- /* [in] */ ULONG celt,
- /* [out] */ IDiaSymbol **rgelt,
- /* [out] */ ULONG *pceltFetched);
-
- HRESULT ( STDMETHODCALLTYPE *Skip )(
- IDiaEnumSymbols * This,
- /* [in] */ ULONG celt);
-
- HRESULT ( STDMETHODCALLTYPE *Reset )(
- IDiaEnumSymbols * This);
-
- HRESULT ( STDMETHODCALLTYPE *Clone )(
- IDiaEnumSymbols * This,
- /* [out] */ IDiaEnumSymbols **ppenum);
-
- END_INTERFACE
- } IDiaEnumSymbolsVtbl;
-
- interface IDiaEnumSymbols
- {
- CONST_VTBL struct IDiaEnumSymbolsVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaEnumSymbols_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaEnumSymbols_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaEnumSymbols_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaEnumSymbols_get__NewEnum(This,pRetVal) \
- ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) )
-
-#define IDiaEnumSymbols_get_Count(This,pRetVal) \
- ( (This)->lpVtbl -> get_Count(This,pRetVal) )
-
-#define IDiaEnumSymbols_Item(This,index,symbol) \
- ( (This)->lpVtbl -> Item(This,index,symbol) )
-
-#define IDiaEnumSymbols_Next(This,celt,rgelt,pceltFetched) \
- ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) )
-
-#define IDiaEnumSymbols_Skip(This,celt) \
- ( (This)->lpVtbl -> Skip(This,celt) )
-
-#define IDiaEnumSymbols_Reset(This) \
- ( (This)->lpVtbl -> Reset(This) )
-
-#define IDiaEnumSymbols_Clone(This,ppenum) \
- ( (This)->lpVtbl -> Clone(This,ppenum) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaEnumSymbols_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaEnumSymbolsByAddr_INTERFACE_DEFINED__
-#define __IDiaEnumSymbolsByAddr_INTERFACE_DEFINED__
-
-/* interface IDiaEnumSymbolsByAddr */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaEnumSymbolsByAddr;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("624B7D9C-24EA-4421-9D06-3B577471C1FA")
- IDiaEnumSymbolsByAddr : public IUnknown
- {
- public:
- virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE symbolByAddr(
- /* [in] */ DWORD isect,
- /* [in] */ DWORD offset,
- /* [retval][out] */ IDiaSymbol **ppSymbol) = 0;
-
- virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE symbolByRVA(
- /* [in] */ DWORD relativeVirtualAddress,
- /* [retval][out] */ IDiaSymbol **ppSymbol) = 0;
-
- virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE symbolByVA(
- /* [in] */ ULONGLONG virtualAddress,
- /* [retval][out] */ IDiaSymbol **ppSymbol) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Next(
- /* [in] */ ULONG celt,
- /* [out] */ IDiaSymbol **rgelt,
- /* [out] */ ULONG *pceltFetched) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Prev(
- /* [in] */ ULONG celt,
- /* [out] */ IDiaSymbol **rgelt,
- /* [out] */ ULONG *pceltFetched) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Clone(
- /* [out] */ IDiaEnumSymbolsByAddr **ppenum) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaEnumSymbolsByAddrVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaEnumSymbolsByAddr * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaEnumSymbolsByAddr * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaEnumSymbolsByAddr * This);
-
- /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *symbolByAddr )(
- IDiaEnumSymbolsByAddr * This,
- /* [in] */ DWORD isect,
- /* [in] */ DWORD offset,
- /* [retval][out] */ IDiaSymbol **ppSymbol);
-
- /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *symbolByRVA )(
- IDiaEnumSymbolsByAddr * This,
- /* [in] */ DWORD relativeVirtualAddress,
- /* [retval][out] */ IDiaSymbol **ppSymbol);
-
- /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *symbolByVA )(
- IDiaEnumSymbolsByAddr * This,
- /* [in] */ ULONGLONG virtualAddress,
- /* [retval][out] */ IDiaSymbol **ppSymbol);
-
- HRESULT ( STDMETHODCALLTYPE *Next )(
- IDiaEnumSymbolsByAddr * This,
- /* [in] */ ULONG celt,
- /* [out] */ IDiaSymbol **rgelt,
- /* [out] */ ULONG *pceltFetched);
-
- HRESULT ( STDMETHODCALLTYPE *Prev )(
- IDiaEnumSymbolsByAddr * This,
- /* [in] */ ULONG celt,
- /* [out] */ IDiaSymbol **rgelt,
- /* [out] */ ULONG *pceltFetched);
-
- HRESULT ( STDMETHODCALLTYPE *Clone )(
- IDiaEnumSymbolsByAddr * This,
- /* [out] */ IDiaEnumSymbolsByAddr **ppenum);
-
- END_INTERFACE
- } IDiaEnumSymbolsByAddrVtbl;
-
- interface IDiaEnumSymbolsByAddr
- {
- CONST_VTBL struct IDiaEnumSymbolsByAddrVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaEnumSymbolsByAddr_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaEnumSymbolsByAddr_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaEnumSymbolsByAddr_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaEnumSymbolsByAddr_symbolByAddr(This,isect,offset,ppSymbol) \
- ( (This)->lpVtbl -> symbolByAddr(This,isect,offset,ppSymbol) )
-
-#define IDiaEnumSymbolsByAddr_symbolByRVA(This,relativeVirtualAddress,ppSymbol) \
- ( (This)->lpVtbl -> symbolByRVA(This,relativeVirtualAddress,ppSymbol) )
-
-#define IDiaEnumSymbolsByAddr_symbolByVA(This,virtualAddress,ppSymbol) \
- ( (This)->lpVtbl -> symbolByVA(This,virtualAddress,ppSymbol) )
-
-#define IDiaEnumSymbolsByAddr_Next(This,celt,rgelt,pceltFetched) \
- ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) )
-
-#define IDiaEnumSymbolsByAddr_Prev(This,celt,rgelt,pceltFetched) \
- ( (This)->lpVtbl -> Prev(This,celt,rgelt,pceltFetched) )
-
-#define IDiaEnumSymbolsByAddr_Clone(This,ppenum) \
- ( (This)->lpVtbl -> Clone(This,ppenum) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaEnumSymbolsByAddr_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaEnumSourceFiles_INTERFACE_DEFINED__
-#define __IDiaEnumSourceFiles_INTERFACE_DEFINED__
-
-/* interface IDiaEnumSourceFiles */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaEnumSourceFiles;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("10F3DBD9-664F-4469-B808-9471C7A50538")
- IDiaEnumSourceFiles : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
- /* [retval][out] */ IUnknown **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
- /* [retval][out] */ LONG *pRetVal) = 0;
-
- virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item(
- /* [in] */ DWORD index,
- /* [retval][out] */ IDiaSourceFile **sourceFile) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Next(
- /* [in] */ ULONG celt,
- /* [out] */ IDiaSourceFile **rgelt,
- /* [out] */ ULONG *pceltFetched) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Skip(
- /* [in] */ ULONG celt) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Clone(
- /* [out] */ IDiaEnumSourceFiles **ppenum) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaEnumSourceFilesVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaEnumSourceFiles * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaEnumSourceFiles * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaEnumSourceFiles * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )(
- IDiaEnumSourceFiles * This,
- /* [retval][out] */ IUnknown **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )(
- IDiaEnumSourceFiles * This,
- /* [retval][out] */ LONG *pRetVal);
-
- /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )(
- IDiaEnumSourceFiles * This,
- /* [in] */ DWORD index,
- /* [retval][out] */ IDiaSourceFile **sourceFile);
-
- HRESULT ( STDMETHODCALLTYPE *Next )(
- IDiaEnumSourceFiles * This,
- /* [in] */ ULONG celt,
- /* [out] */ IDiaSourceFile **rgelt,
- /* [out] */ ULONG *pceltFetched);
-
- HRESULT ( STDMETHODCALLTYPE *Skip )(
- IDiaEnumSourceFiles * This,
- /* [in] */ ULONG celt);
-
- HRESULT ( STDMETHODCALLTYPE *Reset )(
- IDiaEnumSourceFiles * This);
-
- HRESULT ( STDMETHODCALLTYPE *Clone )(
- IDiaEnumSourceFiles * This,
- /* [out] */ IDiaEnumSourceFiles **ppenum);
-
- END_INTERFACE
- } IDiaEnumSourceFilesVtbl;
-
- interface IDiaEnumSourceFiles
- {
- CONST_VTBL struct IDiaEnumSourceFilesVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaEnumSourceFiles_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaEnumSourceFiles_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaEnumSourceFiles_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaEnumSourceFiles_get__NewEnum(This,pRetVal) \
- ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) )
-
-#define IDiaEnumSourceFiles_get_Count(This,pRetVal) \
- ( (This)->lpVtbl -> get_Count(This,pRetVal) )
-
-#define IDiaEnumSourceFiles_Item(This,index,sourceFile) \
- ( (This)->lpVtbl -> Item(This,index,sourceFile) )
-
-#define IDiaEnumSourceFiles_Next(This,celt,rgelt,pceltFetched) \
- ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) )
-
-#define IDiaEnumSourceFiles_Skip(This,celt) \
- ( (This)->lpVtbl -> Skip(This,celt) )
-
-#define IDiaEnumSourceFiles_Reset(This) \
- ( (This)->lpVtbl -> Reset(This) )
-
-#define IDiaEnumSourceFiles_Clone(This,ppenum) \
- ( (This)->lpVtbl -> Clone(This,ppenum) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaEnumSourceFiles_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaEnumLineNumbers_INTERFACE_DEFINED__
-#define __IDiaEnumLineNumbers_INTERFACE_DEFINED__
-
-/* interface IDiaEnumLineNumbers */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaEnumLineNumbers;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("FE30E878-54AC-44f1-81BA-39DE940F6052")
- IDiaEnumLineNumbers : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
- /* [retval][out] */ IUnknown **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
- /* [retval][out] */ LONG *pRetVal) = 0;
-
- virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item(
- /* [in] */ DWORD index,
- /* [retval][out] */ IDiaLineNumber **lineNumber) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Next(
- /* [in] */ ULONG celt,
- /* [out] */ IDiaLineNumber **rgelt,
- /* [out] */ ULONG *pceltFetched) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Skip(
- /* [in] */ ULONG celt) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Clone(
- /* [out] */ IDiaEnumLineNumbers **ppenum) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaEnumLineNumbersVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaEnumLineNumbers * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaEnumLineNumbers * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaEnumLineNumbers * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )(
- IDiaEnumLineNumbers * This,
- /* [retval][out] */ IUnknown **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )(
- IDiaEnumLineNumbers * This,
- /* [retval][out] */ LONG *pRetVal);
-
- /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )(
- IDiaEnumLineNumbers * This,
- /* [in] */ DWORD index,
- /* [retval][out] */ IDiaLineNumber **lineNumber);
-
- HRESULT ( STDMETHODCALLTYPE *Next )(
- IDiaEnumLineNumbers * This,
- /* [in] */ ULONG celt,
- /* [out] */ IDiaLineNumber **rgelt,
- /* [out] */ ULONG *pceltFetched);
-
- HRESULT ( STDMETHODCALLTYPE *Skip )(
- IDiaEnumLineNumbers * This,
- /* [in] */ ULONG celt);
-
- HRESULT ( STDMETHODCALLTYPE *Reset )(
- IDiaEnumLineNumbers * This);
-
- HRESULT ( STDMETHODCALLTYPE *Clone )(
- IDiaEnumLineNumbers * This,
- /* [out] */ IDiaEnumLineNumbers **ppenum);
-
- END_INTERFACE
- } IDiaEnumLineNumbersVtbl;
-
- interface IDiaEnumLineNumbers
- {
- CONST_VTBL struct IDiaEnumLineNumbersVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaEnumLineNumbers_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaEnumLineNumbers_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaEnumLineNumbers_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaEnumLineNumbers_get__NewEnum(This,pRetVal) \
- ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) )
-
-#define IDiaEnumLineNumbers_get_Count(This,pRetVal) \
- ( (This)->lpVtbl -> get_Count(This,pRetVal) )
-
-#define IDiaEnumLineNumbers_Item(This,index,lineNumber) \
- ( (This)->lpVtbl -> Item(This,index,lineNumber) )
-
-#define IDiaEnumLineNumbers_Next(This,celt,rgelt,pceltFetched) \
- ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) )
-
-#define IDiaEnumLineNumbers_Skip(This,celt) \
- ( (This)->lpVtbl -> Skip(This,celt) )
-
-#define IDiaEnumLineNumbers_Reset(This) \
- ( (This)->lpVtbl -> Reset(This) )
-
-#define IDiaEnumLineNumbers_Clone(This,ppenum) \
- ( (This)->lpVtbl -> Clone(This,ppenum) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaEnumLineNumbers_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaEnumInjectedSources_INTERFACE_DEFINED__
-#define __IDiaEnumInjectedSources_INTERFACE_DEFINED__
-
-/* interface IDiaEnumInjectedSources */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaEnumInjectedSources;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("D5612573-6925-4468-8883-98CDEC8C384A")
- IDiaEnumInjectedSources : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
- /* [retval][out] */ IUnknown **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
- /* [retval][out] */ LONG *pRetVal) = 0;
-
- virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item(
- /* [in] */ DWORD index,
- /* [retval][out] */ IDiaInjectedSource **injectedSource) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Next(
- /* [in] */ ULONG celt,
- /* [out] */ IDiaInjectedSource **rgelt,
- /* [out] */ ULONG *pceltFetched) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Skip(
- /* [in] */ ULONG celt) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Clone(
- /* [out] */ IDiaEnumInjectedSources **ppenum) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaEnumInjectedSourcesVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaEnumInjectedSources * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaEnumInjectedSources * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaEnumInjectedSources * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )(
- IDiaEnumInjectedSources * This,
- /* [retval][out] */ IUnknown **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )(
- IDiaEnumInjectedSources * This,
- /* [retval][out] */ LONG *pRetVal);
-
- /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )(
- IDiaEnumInjectedSources * This,
- /* [in] */ DWORD index,
- /* [retval][out] */ IDiaInjectedSource **injectedSource);
-
- HRESULT ( STDMETHODCALLTYPE *Next )(
- IDiaEnumInjectedSources * This,
- /* [in] */ ULONG celt,
- /* [out] */ IDiaInjectedSource **rgelt,
- /* [out] */ ULONG *pceltFetched);
-
- HRESULT ( STDMETHODCALLTYPE *Skip )(
- IDiaEnumInjectedSources * This,
- /* [in] */ ULONG celt);
-
- HRESULT ( STDMETHODCALLTYPE *Reset )(
- IDiaEnumInjectedSources * This);
-
- HRESULT ( STDMETHODCALLTYPE *Clone )(
- IDiaEnumInjectedSources * This,
- /* [out] */ IDiaEnumInjectedSources **ppenum);
-
- END_INTERFACE
- } IDiaEnumInjectedSourcesVtbl;
-
- interface IDiaEnumInjectedSources
- {
- CONST_VTBL struct IDiaEnumInjectedSourcesVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaEnumInjectedSources_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaEnumInjectedSources_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaEnumInjectedSources_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaEnumInjectedSources_get__NewEnum(This,pRetVal) \
- ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) )
-
-#define IDiaEnumInjectedSources_get_Count(This,pRetVal) \
- ( (This)->lpVtbl -> get_Count(This,pRetVal) )
-
-#define IDiaEnumInjectedSources_Item(This,index,injectedSource) \
- ( (This)->lpVtbl -> Item(This,index,injectedSource) )
-
-#define IDiaEnumInjectedSources_Next(This,celt,rgelt,pceltFetched) \
- ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) )
-
-#define IDiaEnumInjectedSources_Skip(This,celt) \
- ( (This)->lpVtbl -> Skip(This,celt) )
-
-#define IDiaEnumInjectedSources_Reset(This) \
- ( (This)->lpVtbl -> Reset(This) )
-
-#define IDiaEnumInjectedSources_Clone(This,ppenum) \
- ( (This)->lpVtbl -> Clone(This,ppenum) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaEnumInjectedSources_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaEnumSegments_INTERFACE_DEFINED__
-#define __IDiaEnumSegments_INTERFACE_DEFINED__
-
-/* interface IDiaEnumSegments */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaEnumSegments;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("E8368CA9-01D1-419d-AC0C-E31235DBDA9F")
- IDiaEnumSegments : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
- /* [retval][out] */ IUnknown **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
- /* [retval][out] */ LONG *pRetVal) = 0;
-
- virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item(
- /* [in] */ DWORD index,
- /* [retval][out] */ IDiaSegment **segment) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Next(
- /* [in] */ ULONG celt,
- /* [out] */ IDiaSegment **rgelt,
- /* [out] */ ULONG *pceltFetched) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Skip(
- /* [in] */ ULONG celt) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Clone(
- /* [out] */ IDiaEnumSegments **ppenum) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaEnumSegmentsVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaEnumSegments * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaEnumSegments * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaEnumSegments * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )(
- IDiaEnumSegments * This,
- /* [retval][out] */ IUnknown **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )(
- IDiaEnumSegments * This,
- /* [retval][out] */ LONG *pRetVal);
-
- /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )(
- IDiaEnumSegments * This,
- /* [in] */ DWORD index,
- /* [retval][out] */ IDiaSegment **segment);
-
- HRESULT ( STDMETHODCALLTYPE *Next )(
- IDiaEnumSegments * This,
- /* [in] */ ULONG celt,
- /* [out] */ IDiaSegment **rgelt,
- /* [out] */ ULONG *pceltFetched);
-
- HRESULT ( STDMETHODCALLTYPE *Skip )(
- IDiaEnumSegments * This,
- /* [in] */ ULONG celt);
-
- HRESULT ( STDMETHODCALLTYPE *Reset )(
- IDiaEnumSegments * This);
-
- HRESULT ( STDMETHODCALLTYPE *Clone )(
- IDiaEnumSegments * This,
- /* [out] */ IDiaEnumSegments **ppenum);
-
- END_INTERFACE
- } IDiaEnumSegmentsVtbl;
-
- interface IDiaEnumSegments
- {
- CONST_VTBL struct IDiaEnumSegmentsVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaEnumSegments_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaEnumSegments_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaEnumSegments_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaEnumSegments_get__NewEnum(This,pRetVal) \
- ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) )
-
-#define IDiaEnumSegments_get_Count(This,pRetVal) \
- ( (This)->lpVtbl -> get_Count(This,pRetVal) )
-
-#define IDiaEnumSegments_Item(This,index,segment) \
- ( (This)->lpVtbl -> Item(This,index,segment) )
-
-#define IDiaEnumSegments_Next(This,celt,rgelt,pceltFetched) \
- ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) )
-
-#define IDiaEnumSegments_Skip(This,celt) \
- ( (This)->lpVtbl -> Skip(This,celt) )
-
-#define IDiaEnumSegments_Reset(This) \
- ( (This)->lpVtbl -> Reset(This) )
-
-#define IDiaEnumSegments_Clone(This,ppenum) \
- ( (This)->lpVtbl -> Clone(This,ppenum) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaEnumSegments_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaEnumSectionContribs_INTERFACE_DEFINED__
-#define __IDiaEnumSectionContribs_INTERFACE_DEFINED__
-
-/* interface IDiaEnumSectionContribs */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaEnumSectionContribs;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("1994DEB2-2C82-4b1d-A57F-AFF424D54A68")
- IDiaEnumSectionContribs : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
- /* [retval][out] */ IUnknown **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
- /* [retval][out] */ LONG *pRetVal) = 0;
-
- virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item(
- /* [in] */ DWORD index,
- /* [retval][out] */ IDiaSectionContrib **section) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Next(
- /* [in] */ ULONG celt,
- /* [out] */ IDiaSectionContrib **rgelt,
- /* [out] */ ULONG *pceltFetched) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Skip(
- /* [in] */ ULONG celt) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Clone(
- /* [out] */ IDiaEnumSectionContribs **ppenum) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaEnumSectionContribsVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaEnumSectionContribs * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaEnumSectionContribs * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaEnumSectionContribs * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )(
- IDiaEnumSectionContribs * This,
- /* [retval][out] */ IUnknown **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )(
- IDiaEnumSectionContribs * This,
- /* [retval][out] */ LONG *pRetVal);
-
- /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )(
- IDiaEnumSectionContribs * This,
- /* [in] */ DWORD index,
- /* [retval][out] */ IDiaSectionContrib **section);
-
- HRESULT ( STDMETHODCALLTYPE *Next )(
- IDiaEnumSectionContribs * This,
- /* [in] */ ULONG celt,
- /* [out] */ IDiaSectionContrib **rgelt,
- /* [out] */ ULONG *pceltFetched);
-
- HRESULT ( STDMETHODCALLTYPE *Skip )(
- IDiaEnumSectionContribs * This,
- /* [in] */ ULONG celt);
-
- HRESULT ( STDMETHODCALLTYPE *Reset )(
- IDiaEnumSectionContribs * This);
-
- HRESULT ( STDMETHODCALLTYPE *Clone )(
- IDiaEnumSectionContribs * This,
- /* [out] */ IDiaEnumSectionContribs **ppenum);
-
- END_INTERFACE
- } IDiaEnumSectionContribsVtbl;
-
- interface IDiaEnumSectionContribs
- {
- CONST_VTBL struct IDiaEnumSectionContribsVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaEnumSectionContribs_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaEnumSectionContribs_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaEnumSectionContribs_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaEnumSectionContribs_get__NewEnum(This,pRetVal) \
- ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) )
-
-#define IDiaEnumSectionContribs_get_Count(This,pRetVal) \
- ( (This)->lpVtbl -> get_Count(This,pRetVal) )
-
-#define IDiaEnumSectionContribs_Item(This,index,section) \
- ( (This)->lpVtbl -> Item(This,index,section) )
-
-#define IDiaEnumSectionContribs_Next(This,celt,rgelt,pceltFetched) \
- ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) )
-
-#define IDiaEnumSectionContribs_Skip(This,celt) \
- ( (This)->lpVtbl -> Skip(This,celt) )
-
-#define IDiaEnumSectionContribs_Reset(This) \
- ( (This)->lpVtbl -> Reset(This) )
-
-#define IDiaEnumSectionContribs_Clone(This,ppenum) \
- ( (This)->lpVtbl -> Clone(This,ppenum) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaEnumSectionContribs_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaEnumFrameData_INTERFACE_DEFINED__
-#define __IDiaEnumFrameData_INTERFACE_DEFINED__
-
-/* interface IDiaEnumFrameData */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaEnumFrameData;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("9FC77A4B-3C1C-44ed-A798-6C1DEEA53E1F")
- IDiaEnumFrameData : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
- /* [retval][out] */ IUnknown **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
- /* [retval][out] */ LONG *pRetVal) = 0;
-
- virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item(
- /* [in] */ DWORD index,
- /* [retval][out] */ IDiaFrameData **frame) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Next(
- /* [in] */ ULONG celt,
- /* [out] */ IDiaFrameData **rgelt,
- /* [out] */ ULONG *pceltFetched) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Skip(
- /* [in] */ ULONG celt) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Clone(
- /* [out] */ IDiaEnumFrameData **ppenum) = 0;
-
- virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE frameByRVA(
- /* [in] */ DWORD relativeVirtualAddress,
- /* [retval][out] */ IDiaFrameData **frame) = 0;
-
- virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE frameByVA(
- /* [in] */ ULONGLONG virtualAddress,
- /* [retval][out] */ IDiaFrameData **frame) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaEnumFrameDataVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaEnumFrameData * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaEnumFrameData * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaEnumFrameData * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )(
- IDiaEnumFrameData * This,
- /* [retval][out] */ IUnknown **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )(
- IDiaEnumFrameData * This,
- /* [retval][out] */ LONG *pRetVal);
-
- /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )(
- IDiaEnumFrameData * This,
- /* [in] */ DWORD index,
- /* [retval][out] */ IDiaFrameData **frame);
-
- HRESULT ( STDMETHODCALLTYPE *Next )(
- IDiaEnumFrameData * This,
- /* [in] */ ULONG celt,
- /* [out] */ IDiaFrameData **rgelt,
- /* [out] */ ULONG *pceltFetched);
-
- HRESULT ( STDMETHODCALLTYPE *Skip )(
- IDiaEnumFrameData * This,
- /* [in] */ ULONG celt);
-
- HRESULT ( STDMETHODCALLTYPE *Reset )(
- IDiaEnumFrameData * This);
-
- HRESULT ( STDMETHODCALLTYPE *Clone )(
- IDiaEnumFrameData * This,
- /* [out] */ IDiaEnumFrameData **ppenum);
-
- /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *frameByRVA )(
- IDiaEnumFrameData * This,
- /* [in] */ DWORD relativeVirtualAddress,
- /* [retval][out] */ IDiaFrameData **frame);
-
- /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE *frameByVA )(
- IDiaEnumFrameData * This,
- /* [in] */ ULONGLONG virtualAddress,
- /* [retval][out] */ IDiaFrameData **frame);
-
- END_INTERFACE
- } IDiaEnumFrameDataVtbl;
-
- interface IDiaEnumFrameData
- {
- CONST_VTBL struct IDiaEnumFrameDataVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaEnumFrameData_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaEnumFrameData_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaEnumFrameData_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaEnumFrameData_get__NewEnum(This,pRetVal) \
- ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) )
-
-#define IDiaEnumFrameData_get_Count(This,pRetVal) \
- ( (This)->lpVtbl -> get_Count(This,pRetVal) )
-
-#define IDiaEnumFrameData_Item(This,index,frame) \
- ( (This)->lpVtbl -> Item(This,index,frame) )
-
-#define IDiaEnumFrameData_Next(This,celt,rgelt,pceltFetched) \
- ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) )
-
-#define IDiaEnumFrameData_Skip(This,celt) \
- ( (This)->lpVtbl -> Skip(This,celt) )
-
-#define IDiaEnumFrameData_Reset(This) \
- ( (This)->lpVtbl -> Reset(This) )
-
-#define IDiaEnumFrameData_Clone(This,ppenum) \
- ( (This)->lpVtbl -> Clone(This,ppenum) )
-
-#define IDiaEnumFrameData_frameByRVA(This,relativeVirtualAddress,frame) \
- ( (This)->lpVtbl -> frameByRVA(This,relativeVirtualAddress,frame) )
-
-#define IDiaEnumFrameData_frameByVA(This,virtualAddress,frame) \
- ( (This)->lpVtbl -> frameByVA(This,virtualAddress,frame) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaEnumFrameData_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaEnumDebugStreamData_INTERFACE_DEFINED__
-#define __IDiaEnumDebugStreamData_INTERFACE_DEFINED__
-
-/* interface IDiaEnumDebugStreamData */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaEnumDebugStreamData;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("486943E8-D187-4a6b-A3C4-291259FFF60D")
- IDiaEnumDebugStreamData : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
- /* [retval][out] */ IUnknown **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
- /* [retval][out] */ LONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_name(
- /* [retval][out] */ BSTR *pRetVal) = 0;
-
- virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item(
- /* [in] */ DWORD index,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Next(
- /* [in] */ ULONG celt,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData,
- /* [out] */ ULONG *pceltFetched) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Skip(
- /* [in] */ ULONG celt) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Clone(
- /* [out] */ IDiaEnumDebugStreamData **ppenum) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaEnumDebugStreamDataVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaEnumDebugStreamData * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaEnumDebugStreamData * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaEnumDebugStreamData * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )(
- IDiaEnumDebugStreamData * This,
- /* [retval][out] */ IUnknown **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )(
- IDiaEnumDebugStreamData * This,
- /* [retval][out] */ LONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_name )(
- IDiaEnumDebugStreamData * This,
- /* [retval][out] */ BSTR *pRetVal);
-
- /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )(
- IDiaEnumDebugStreamData * This,
- /* [in] */ DWORD index,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData);
-
- HRESULT ( STDMETHODCALLTYPE *Next )(
- IDiaEnumDebugStreamData * This,
- /* [in] */ ULONG celt,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData,
- /* [out] */ ULONG *pceltFetched);
-
- HRESULT ( STDMETHODCALLTYPE *Skip )(
- IDiaEnumDebugStreamData * This,
- /* [in] */ ULONG celt);
-
- HRESULT ( STDMETHODCALLTYPE *Reset )(
- IDiaEnumDebugStreamData * This);
-
- HRESULT ( STDMETHODCALLTYPE *Clone )(
- IDiaEnumDebugStreamData * This,
- /* [out] */ IDiaEnumDebugStreamData **ppenum);
-
- END_INTERFACE
- } IDiaEnumDebugStreamDataVtbl;
-
- interface IDiaEnumDebugStreamData
- {
- CONST_VTBL struct IDiaEnumDebugStreamDataVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaEnumDebugStreamData_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaEnumDebugStreamData_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaEnumDebugStreamData_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaEnumDebugStreamData_get__NewEnum(This,pRetVal) \
- ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) )
-
-#define IDiaEnumDebugStreamData_get_Count(This,pRetVal) \
- ( (This)->lpVtbl -> get_Count(This,pRetVal) )
-
-#define IDiaEnumDebugStreamData_get_name(This,pRetVal) \
- ( (This)->lpVtbl -> get_name(This,pRetVal) )
-
-#define IDiaEnumDebugStreamData_Item(This,index,cbData,pcbData,pbData) \
- ( (This)->lpVtbl -> Item(This,index,cbData,pcbData,pbData) )
-
-#define IDiaEnumDebugStreamData_Next(This,celt,cbData,pcbData,pbData,pceltFetched) \
- ( (This)->lpVtbl -> Next(This,celt,cbData,pcbData,pbData,pceltFetched) )
-
-#define IDiaEnumDebugStreamData_Skip(This,celt) \
- ( (This)->lpVtbl -> Skip(This,celt) )
-
-#define IDiaEnumDebugStreamData_Reset(This) \
- ( (This)->lpVtbl -> Reset(This) )
-
-#define IDiaEnumDebugStreamData_Clone(This,ppenum) \
- ( (This)->lpVtbl -> Clone(This,ppenum) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaEnumDebugStreamData_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaEnumDebugStreams_INTERFACE_DEFINED__
-#define __IDiaEnumDebugStreams_INTERFACE_DEFINED__
-
-/* interface IDiaEnumDebugStreams */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaEnumDebugStreams;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("08CBB41E-47A6-4f87-92F1-1C9C87CED044")
- IDiaEnumDebugStreams : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
- /* [retval][out] */ IUnknown **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
- /* [retval][out] */ LONG *pRetVal) = 0;
-
- virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item(
- /* [in] */ VARIANT index,
- /* [retval][out] */ IDiaEnumDebugStreamData **stream) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Next(
- /* [in] */ ULONG celt,
- /* [out] */ IDiaEnumDebugStreamData **rgelt,
- /* [out] */ ULONG *pceltFetched) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Skip(
- /* [in] */ ULONG celt) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Clone(
- /* [out] */ IDiaEnumDebugStreams **ppenum) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaEnumDebugStreamsVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaEnumDebugStreams * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaEnumDebugStreams * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaEnumDebugStreams * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )(
- IDiaEnumDebugStreams * This,
- /* [retval][out] */ IUnknown **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )(
- IDiaEnumDebugStreams * This,
- /* [retval][out] */ LONG *pRetVal);
-
- /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )(
- IDiaEnumDebugStreams * This,
- /* [in] */ VARIANT index,
- /* [retval][out] */ IDiaEnumDebugStreamData **stream);
-
- HRESULT ( STDMETHODCALLTYPE *Next )(
- IDiaEnumDebugStreams * This,
- /* [in] */ ULONG celt,
- /* [out] */ IDiaEnumDebugStreamData **rgelt,
- /* [out] */ ULONG *pceltFetched);
-
- HRESULT ( STDMETHODCALLTYPE *Skip )(
- IDiaEnumDebugStreams * This,
- /* [in] */ ULONG celt);
-
- HRESULT ( STDMETHODCALLTYPE *Reset )(
- IDiaEnumDebugStreams * This);
-
- HRESULT ( STDMETHODCALLTYPE *Clone )(
- IDiaEnumDebugStreams * This,
- /* [out] */ IDiaEnumDebugStreams **ppenum);
-
- END_INTERFACE
- } IDiaEnumDebugStreamsVtbl;
-
- interface IDiaEnumDebugStreams
- {
- CONST_VTBL struct IDiaEnumDebugStreamsVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaEnumDebugStreams_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaEnumDebugStreams_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaEnumDebugStreams_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaEnumDebugStreams_get__NewEnum(This,pRetVal) \
- ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) )
-
-#define IDiaEnumDebugStreams_get_Count(This,pRetVal) \
- ( (This)->lpVtbl -> get_Count(This,pRetVal) )
-
-#define IDiaEnumDebugStreams_Item(This,index,stream) \
- ( (This)->lpVtbl -> Item(This,index,stream) )
-
-#define IDiaEnumDebugStreams_Next(This,celt,rgelt,pceltFetched) \
- ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) )
-
-#define IDiaEnumDebugStreams_Skip(This,celt) \
- ( (This)->lpVtbl -> Skip(This,celt) )
-
-#define IDiaEnumDebugStreams_Reset(This) \
- ( (This)->lpVtbl -> Reset(This) )
-
-#define IDiaEnumDebugStreams_Clone(This,ppenum) \
- ( (This)->lpVtbl -> Clone(This,ppenum) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaEnumDebugStreams_INTERFACE_DEFINED__ */
-
-
-/* interface __MIDL_itf_dia2_0000_0015 */
-/* [local] */
-
-struct DiaAddressMapEntry
- {
- DWORD rva;
- DWORD rvaTo;
- } ;
-
-
-extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0015_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0015_v0_0_s_ifspec;
-
-#ifndef __IDiaAddressMap_INTERFACE_DEFINED__
-#define __IDiaAddressMap_INTERFACE_DEFINED__
-
-/* interface IDiaAddressMap */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaAddressMap;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("B62A2E7A-067A-4ea3-B598-04C09717502C")
- IDiaAddressMap : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressMapEnabled(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_addressMapEnabled(
- /* [in] */ BOOL NewVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relativeVirtualAddressEnabled(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_relativeVirtualAddressEnabled(
- /* [in] */ BOOL NewVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_imageAlign(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_imageAlign(
- /* [in] */ DWORD NewVal) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE set_imageHeaders(
- /* [in] */ DWORD cbData,
- /* [size_is][in] */ BYTE *pbData,
- /* [in] */ BOOL originalHeaders) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE set_addressMap(
- /* [in] */ DWORD cData,
- /* [size_is][in] */ struct DiaAddressMapEntry *pData,
- /* [in] */ BOOL imageToSymbols) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaAddressMapVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaAddressMap * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaAddressMap * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaAddressMap * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressMapEnabled )(
- IDiaAddressMap * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE *put_addressMapEnabled )(
- IDiaAddressMap * This,
- /* [in] */ BOOL NewVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddressEnabled )(
- IDiaAddressMap * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE *put_relativeVirtualAddressEnabled )(
- IDiaAddressMap * This,
- /* [in] */ BOOL NewVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_imageAlign )(
- IDiaAddressMap * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE *put_imageAlign )(
- IDiaAddressMap * This,
- /* [in] */ DWORD NewVal);
-
- HRESULT ( STDMETHODCALLTYPE *set_imageHeaders )(
- IDiaAddressMap * This,
- /* [in] */ DWORD cbData,
- /* [size_is][in] */ BYTE *pbData,
- /* [in] */ BOOL originalHeaders);
-
- HRESULT ( STDMETHODCALLTYPE *set_addressMap )(
- IDiaAddressMap * This,
- /* [in] */ DWORD cData,
- /* [size_is][in] */ struct DiaAddressMapEntry *pData,
- /* [in] */ BOOL imageToSymbols);
-
- END_INTERFACE
- } IDiaAddressMapVtbl;
-
- interface IDiaAddressMap
- {
- CONST_VTBL struct IDiaAddressMapVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaAddressMap_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaAddressMap_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaAddressMap_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaAddressMap_get_addressMapEnabled(This,pRetVal) \
- ( (This)->lpVtbl -> get_addressMapEnabled(This,pRetVal) )
-
-#define IDiaAddressMap_put_addressMapEnabled(This,NewVal) \
- ( (This)->lpVtbl -> put_addressMapEnabled(This,NewVal) )
-
-#define IDiaAddressMap_get_relativeVirtualAddressEnabled(This,pRetVal) \
- ( (This)->lpVtbl -> get_relativeVirtualAddressEnabled(This,pRetVal) )
-
-#define IDiaAddressMap_put_relativeVirtualAddressEnabled(This,NewVal) \
- ( (This)->lpVtbl -> put_relativeVirtualAddressEnabled(This,NewVal) )
-
-#define IDiaAddressMap_get_imageAlign(This,pRetVal) \
- ( (This)->lpVtbl -> get_imageAlign(This,pRetVal) )
-
-#define IDiaAddressMap_put_imageAlign(This,NewVal) \
- ( (This)->lpVtbl -> put_imageAlign(This,NewVal) )
-
-#define IDiaAddressMap_set_imageHeaders(This,cbData,pbData,originalHeaders) \
- ( (This)->lpVtbl -> set_imageHeaders(This,cbData,pbData,originalHeaders) )
-
-#define IDiaAddressMap_set_addressMap(This,cData,pData,imageToSymbols) \
- ( (This)->lpVtbl -> set_addressMap(This,cData,pData,imageToSymbols) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaAddressMap_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaSession_INTERFACE_DEFINED__
-#define __IDiaSession_INTERFACE_DEFINED__
-
-/* interface IDiaSession */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaSession;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("67138B34-79CD-4b42-B74A-A18ADBB799DF")
- IDiaSession : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_loadAddress(
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_loadAddress(
- /* [in] */ ULONGLONG NewVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_globalScope(
- /* [retval][out] */ IDiaSymbol **pRetVal) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE getEnumTables(
- /* [out] */ IDiaEnumTables **ppEnumTables) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE getSymbolsByAddr(
- /* [out] */ IDiaEnumSymbolsByAddr **ppEnumbyAddr) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findChildren(
- /* [in] */ IDiaSymbol *parent,
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [out] */ IDiaEnumSymbols **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findChildrenEx(
- /* [in] */ IDiaSymbol *parent,
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [out] */ IDiaEnumSymbols **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findChildrenExByAddr(
- /* [in] */ IDiaSymbol *parent,
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [in] */ DWORD isect,
- /* [in] */ DWORD offset,
- /* [out] */ IDiaEnumSymbols **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findChildrenExByVA(
- /* [in] */ IDiaSymbol *parent,
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [in] */ ULONGLONG va,
- /* [out] */ IDiaEnumSymbols **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findChildrenExByRVA(
- /* [in] */ IDiaSymbol *parent,
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [in] */ DWORD rva,
- /* [out] */ IDiaEnumSymbols **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findSymbolByAddr(
- /* [in] */ DWORD isect,
- /* [in] */ DWORD offset,
- /* [in] */ enum SymTagEnum symtag,
- /* [out] */ IDiaSymbol **ppSymbol) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findSymbolByRVA(
- /* [in] */ DWORD rva,
- /* [in] */ enum SymTagEnum symtag,
- /* [out] */ IDiaSymbol **ppSymbol) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findSymbolByVA(
- /* [in] */ ULONGLONG va,
- /* [in] */ enum SymTagEnum symtag,
- /* [out] */ IDiaSymbol **ppSymbol) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findSymbolByToken(
- /* [in] */ ULONG token,
- /* [in] */ enum SymTagEnum symtag,
- /* [out] */ IDiaSymbol **ppSymbol) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE symsAreEquiv(
- /* [in] */ IDiaSymbol *symbolA,
- /* [in] */ IDiaSymbol *symbolB) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE symbolById(
- /* [in] */ DWORD id,
- /* [out] */ IDiaSymbol **ppSymbol) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findSymbolByRVAEx(
- /* [in] */ DWORD rva,
- /* [in] */ enum SymTagEnum symtag,
- /* [out] */ IDiaSymbol **ppSymbol,
- /* [out] */ long *displacement) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findSymbolByVAEx(
- /* [in] */ ULONGLONG va,
- /* [in] */ enum SymTagEnum symtag,
- /* [out] */ IDiaSymbol **ppSymbol,
- /* [out] */ long *displacement) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findFile(
- /* [in] */ IDiaSymbol *pCompiland,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [out] */ IDiaEnumSourceFiles **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findFileById(
- /* [in] */ DWORD uniqueId,
- /* [out] */ IDiaSourceFile **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findLines(
- /* [in] */ IDiaSymbol *compiland,
- /* [in] */ IDiaSourceFile *file,
- /* [out] */ IDiaEnumLineNumbers **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findLinesByAddr(
- /* [in] */ DWORD seg,
- /* [in] */ DWORD offset,
- /* [in] */ DWORD length,
- /* [out] */ IDiaEnumLineNumbers **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findLinesByRVA(
- /* [in] */ DWORD rva,
- /* [in] */ DWORD length,
- /* [out] */ IDiaEnumLineNumbers **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findLinesByVA(
- /* [in] */ ULONGLONG va,
- /* [in] */ DWORD length,
- /* [out] */ IDiaEnumLineNumbers **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findLinesByLinenum(
- /* [in] */ IDiaSymbol *compiland,
- /* [in] */ IDiaSourceFile *file,
- /* [in] */ DWORD linenum,
- /* [in] */ DWORD column,
- /* [out] */ IDiaEnumLineNumbers **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findInjectedSource(
- /* [in] */ LPCOLESTR srcFile,
- /* [out] */ IDiaEnumInjectedSources **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE getEnumDebugStreams(
- /* [out] */ IDiaEnumDebugStreams **ppEnumDebugStreams) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaSessionVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaSession * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaSession * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaSession * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_loadAddress )(
- IDiaSession * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE *put_loadAddress )(
- IDiaSession * This,
- /* [in] */ ULONGLONG NewVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_globalScope )(
- IDiaSession * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
- HRESULT ( STDMETHODCALLTYPE *getEnumTables )(
- IDiaSession * This,
- /* [out] */ IDiaEnumTables **ppEnumTables);
-
- HRESULT ( STDMETHODCALLTYPE *getSymbolsByAddr )(
- IDiaSession * This,
- /* [out] */ IDiaEnumSymbolsByAddr **ppEnumbyAddr);
-
- HRESULT ( STDMETHODCALLTYPE *findChildren )(
- IDiaSession * This,
- /* [in] */ IDiaSymbol *parent,
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [out] */ IDiaEnumSymbols **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findChildrenEx )(
- IDiaSession * This,
- /* [in] */ IDiaSymbol *parent,
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [out] */ IDiaEnumSymbols **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findChildrenExByAddr )(
- IDiaSession * This,
- /* [in] */ IDiaSymbol *parent,
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [in] */ DWORD isect,
- /* [in] */ DWORD offset,
- /* [out] */ IDiaEnumSymbols **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findChildrenExByVA )(
- IDiaSession * This,
- /* [in] */ IDiaSymbol *parent,
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [in] */ ULONGLONG va,
- /* [out] */ IDiaEnumSymbols **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findChildrenExByRVA )(
- IDiaSession * This,
- /* [in] */ IDiaSymbol *parent,
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [in] */ DWORD rva,
- /* [out] */ IDiaEnumSymbols **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findSymbolByAddr )(
- IDiaSession * This,
- /* [in] */ DWORD isect,
- /* [in] */ DWORD offset,
- /* [in] */ enum SymTagEnum symtag,
- /* [out] */ IDiaSymbol **ppSymbol);
-
- HRESULT ( STDMETHODCALLTYPE *findSymbolByRVA )(
- IDiaSession * This,
- /* [in] */ DWORD rva,
- /* [in] */ enum SymTagEnum symtag,
- /* [out] */ IDiaSymbol **ppSymbol);
-
- HRESULT ( STDMETHODCALLTYPE *findSymbolByVA )(
- IDiaSession * This,
- /* [in] */ ULONGLONG va,
- /* [in] */ enum SymTagEnum symtag,
- /* [out] */ IDiaSymbol **ppSymbol);
-
- HRESULT ( STDMETHODCALLTYPE *findSymbolByToken )(
- IDiaSession * This,
- /* [in] */ ULONG token,
- /* [in] */ enum SymTagEnum symtag,
- /* [out] */ IDiaSymbol **ppSymbol);
-
- HRESULT ( STDMETHODCALLTYPE *symsAreEquiv )(
- IDiaSession * This,
- /* [in] */ IDiaSymbol *symbolA,
- /* [in] */ IDiaSymbol *symbolB);
-
- HRESULT ( STDMETHODCALLTYPE *symbolById )(
- IDiaSession * This,
- /* [in] */ DWORD id,
- /* [out] */ IDiaSymbol **ppSymbol);
-
- HRESULT ( STDMETHODCALLTYPE *findSymbolByRVAEx )(
- IDiaSession * This,
- /* [in] */ DWORD rva,
- /* [in] */ enum SymTagEnum symtag,
- /* [out] */ IDiaSymbol **ppSymbol,
- /* [out] */ long *displacement);
-
- HRESULT ( STDMETHODCALLTYPE *findSymbolByVAEx )(
- IDiaSession * This,
- /* [in] */ ULONGLONG va,
- /* [in] */ enum SymTagEnum symtag,
- /* [out] */ IDiaSymbol **ppSymbol,
- /* [out] */ long *displacement);
-
- HRESULT ( STDMETHODCALLTYPE *findFile )(
- IDiaSession * This,
- /* [in] */ IDiaSymbol *pCompiland,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [out] */ IDiaEnumSourceFiles **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findFileById )(
- IDiaSession * This,
- /* [in] */ DWORD uniqueId,
- /* [out] */ IDiaSourceFile **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findLines )(
- IDiaSession * This,
- /* [in] */ IDiaSymbol *compiland,
- /* [in] */ IDiaSourceFile *file,
- /* [out] */ IDiaEnumLineNumbers **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findLinesByAddr )(
- IDiaSession * This,
- /* [in] */ DWORD seg,
- /* [in] */ DWORD offset,
- /* [in] */ DWORD length,
- /* [out] */ IDiaEnumLineNumbers **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findLinesByRVA )(
- IDiaSession * This,
- /* [in] */ DWORD rva,
- /* [in] */ DWORD length,
- /* [out] */ IDiaEnumLineNumbers **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findLinesByVA )(
- IDiaSession * This,
- /* [in] */ ULONGLONG va,
- /* [in] */ DWORD length,
- /* [out] */ IDiaEnumLineNumbers **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findLinesByLinenum )(
- IDiaSession * This,
- /* [in] */ IDiaSymbol *compiland,
- /* [in] */ IDiaSourceFile *file,
- /* [in] */ DWORD linenum,
- /* [in] */ DWORD column,
- /* [out] */ IDiaEnumLineNumbers **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findInjectedSource )(
- IDiaSession * This,
- /* [in] */ LPCOLESTR srcFile,
- /* [out] */ IDiaEnumInjectedSources **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *getEnumDebugStreams )(
- IDiaSession * This,
- /* [out] */ IDiaEnumDebugStreams **ppEnumDebugStreams);
-
- END_INTERFACE
- } IDiaSessionVtbl;
-
- interface IDiaSession
- {
- CONST_VTBL struct IDiaSessionVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaSession_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaSession_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaSession_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaSession_get_loadAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_loadAddress(This,pRetVal) )
-
-#define IDiaSession_put_loadAddress(This,NewVal) \
- ( (This)->lpVtbl -> put_loadAddress(This,NewVal) )
-
-#define IDiaSession_get_globalScope(This,pRetVal) \
- ( (This)->lpVtbl -> get_globalScope(This,pRetVal) )
-
-#define IDiaSession_getEnumTables(This,ppEnumTables) \
- ( (This)->lpVtbl -> getEnumTables(This,ppEnumTables) )
-
-#define IDiaSession_getSymbolsByAddr(This,ppEnumbyAddr) \
- ( (This)->lpVtbl -> getSymbolsByAddr(This,ppEnumbyAddr) )
-
-#define IDiaSession_findChildren(This,parent,symtag,name,compareFlags,ppResult) \
- ( (This)->lpVtbl -> findChildren(This,parent,symtag,name,compareFlags,ppResult) )
-
-#define IDiaSession_findChildrenEx(This,parent,symtag,name,compareFlags,ppResult) \
- ( (This)->lpVtbl -> findChildrenEx(This,parent,symtag,name,compareFlags,ppResult) )
-
-#define IDiaSession_findChildrenExByAddr(This,parent,symtag,name,compareFlags,isect,offset,ppResult) \
- ( (This)->lpVtbl -> findChildrenExByAddr(This,parent,symtag,name,compareFlags,isect,offset,ppResult) )
-
-#define IDiaSession_findChildrenExByVA(This,parent,symtag,name,compareFlags,va,ppResult) \
- ( (This)->lpVtbl -> findChildrenExByVA(This,parent,symtag,name,compareFlags,va,ppResult) )
-
-#define IDiaSession_findChildrenExByRVA(This,parent,symtag,name,compareFlags,rva,ppResult) \
- ( (This)->lpVtbl -> findChildrenExByRVA(This,parent,symtag,name,compareFlags,rva,ppResult) )
-
-#define IDiaSession_findSymbolByAddr(This,isect,offset,symtag,ppSymbol) \
- ( (This)->lpVtbl -> findSymbolByAddr(This,isect,offset,symtag,ppSymbol) )
-
-#define IDiaSession_findSymbolByRVA(This,rva,symtag,ppSymbol) \
- ( (This)->lpVtbl -> findSymbolByRVA(This,rva,symtag,ppSymbol) )
-
-#define IDiaSession_findSymbolByVA(This,va,symtag,ppSymbol) \
- ( (This)->lpVtbl -> findSymbolByVA(This,va,symtag,ppSymbol) )
-
-#define IDiaSession_findSymbolByToken(This,token,symtag,ppSymbol) \
- ( (This)->lpVtbl -> findSymbolByToken(This,token,symtag,ppSymbol) )
-
-#define IDiaSession_symsAreEquiv(This,symbolA,symbolB) \
- ( (This)->lpVtbl -> symsAreEquiv(This,symbolA,symbolB) )
-
-#define IDiaSession_symbolById(This,id,ppSymbol) \
- ( (This)->lpVtbl -> symbolById(This,id,ppSymbol) )
-
-#define IDiaSession_findSymbolByRVAEx(This,rva,symtag,ppSymbol,displacement) \
- ( (This)->lpVtbl -> findSymbolByRVAEx(This,rva,symtag,ppSymbol,displacement) )
-
-#define IDiaSession_findSymbolByVAEx(This,va,symtag,ppSymbol,displacement) \
- ( (This)->lpVtbl -> findSymbolByVAEx(This,va,symtag,ppSymbol,displacement) )
-
-#define IDiaSession_findFile(This,pCompiland,name,compareFlags,ppResult) \
- ( (This)->lpVtbl -> findFile(This,pCompiland,name,compareFlags,ppResult) )
-
-#define IDiaSession_findFileById(This,uniqueId,ppResult) \
- ( (This)->lpVtbl -> findFileById(This,uniqueId,ppResult) )
-
-#define IDiaSession_findLines(This,compiland,file,ppResult) \
- ( (This)->lpVtbl -> findLines(This,compiland,file,ppResult) )
-
-#define IDiaSession_findLinesByAddr(This,seg,offset,length,ppResult) \
- ( (This)->lpVtbl -> findLinesByAddr(This,seg,offset,length,ppResult) )
-
-#define IDiaSession_findLinesByRVA(This,rva,length,ppResult) \
- ( (This)->lpVtbl -> findLinesByRVA(This,rva,length,ppResult) )
-
-#define IDiaSession_findLinesByVA(This,va,length,ppResult) \
- ( (This)->lpVtbl -> findLinesByVA(This,va,length,ppResult) )
-
-#define IDiaSession_findLinesByLinenum(This,compiland,file,linenum,column,ppResult) \
- ( (This)->lpVtbl -> findLinesByLinenum(This,compiland,file,linenum,column,ppResult) )
-
-#define IDiaSession_findInjectedSource(This,srcFile,ppResult) \
- ( (This)->lpVtbl -> findInjectedSource(This,srcFile,ppResult) )
-
-#define IDiaSession_getEnumDebugStreams(This,ppEnumDebugStreams) \
- ( (This)->lpVtbl -> getEnumDebugStreams(This,ppEnumDebugStreams) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaSession_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaSymbol_INTERFACE_DEFINED__
-#define __IDiaSymbol_INTERFACE_DEFINED__
-
-/* interface IDiaSymbol */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaSymbol;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("cb787b2f-bd6c-4635-ba52-933126bd2dcd")
- IDiaSymbol : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_symIndexId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_symTag(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_name(
- /* [retval][out] */ BSTR *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lexicalParent(
- /* [retval][out] */ IDiaSymbol **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_classParent(
- /* [retval][out] */ IDiaSymbol **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_type(
- /* [retval][out] */ IDiaSymbol **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_dataKind(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_locationType(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressSection(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressOffset(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualAddress(
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_registerId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_offset(
- /* [retval][out] */ LONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_length(
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_slot(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_volatileType(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_constType(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_unalignedType(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_access(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_libraryName(
- /* [retval][out] */ BSTR *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_platform(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_language(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_editAndContinueEnabled(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_frontEndMajor(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_frontEndMinor(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_frontEndBuild(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_backEndMajor(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_backEndMinor(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_backEndBuild(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_sourceFileName(
- /* [retval][out] */ BSTR *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_unused(
- /* [retval][out] */ BSTR *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_thunkOrdinal(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_thisAdjust(
- /* [retval][out] */ LONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualBaseOffset(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtual(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_intro(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_pure(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_callingConvention(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_value(
- /* [retval][out] */ VARIANT *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_baseType(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_token(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_timeStamp(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_guid(
- /* [retval][out] */ GUID *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_symbolsFileName(
- /* [retval][out] */ BSTR *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_reference(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_count(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_bitPosition(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_arrayIndexType(
- /* [retval][out] */ IDiaSymbol **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_packed(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_constructor(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_overloadedOperator(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_nested(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasNestedTypes(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasAssignmentOperator(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasCastOperator(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_scoped(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualBaseClass(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_indirectVirtualBaseClass(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualBasePointerOffset(
- /* [retval][out] */ LONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualTableShape(
- /* [retval][out] */ IDiaSymbol **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lexicalParentId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_classParentId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_typeId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_arrayIndexTypeId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualTableShapeId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_code(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_function(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_managed(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_msil(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualBaseDispIndex(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_undecoratedName(
- /* [retval][out] */ BSTR *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_age(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_signature(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_compilerGenerated(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressTaken(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_rank(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lowerBound(
- /* [retval][out] */ IDiaSymbol **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_upperBound(
- /* [retval][out] */ IDiaSymbol **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lowerBoundId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_upperBoundId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE get_dataBytes(
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findChildren(
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [out] */ IDiaEnumSymbols **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findChildrenEx(
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [out] */ IDiaEnumSymbols **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findChildrenExByAddr(
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [in] */ DWORD isect,
- /* [in] */ DWORD offset,
- /* [out] */ IDiaEnumSymbols **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findChildrenExByVA(
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [in] */ ULONGLONG va,
- /* [out] */ IDiaEnumSymbols **ppResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE findChildrenExByRVA(
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [in] */ DWORD rva,
- /* [out] */ IDiaEnumSymbols **ppResult) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_targetSection(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_targetOffset(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_targetRelativeVirtualAddress(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_targetVirtualAddress(
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_machineType(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_oemId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_oemSymbolId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE get_types(
- /* [in] */ DWORD cTypes,
- /* [out] */ DWORD *pcTypes,
- /* [size_is][size_is][out] */ IDiaSymbol **pTypes) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE get_typeIds(
- /* [in] */ DWORD cTypeIds,
- /* [out] */ DWORD *pcTypeIds,
- /* [size_is][out] */ DWORD *pdwTypeIds) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_objectPointerType(
- /* [retval][out] */ IDiaSymbol **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_udtKind(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE get_undecoratedNameEx(
- /* [in] */ DWORD undecorateOptions,
- /* [out] */ BSTR *name) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_noReturn(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_customCallingConvention(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_noInline(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_optimizedCodeDebugInfo(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_notReached(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_interruptReturn(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_farReturn(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isStatic(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasDebugInfo(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isLTCG(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isDataAligned(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasSecurityChecks(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_compilerName(
- /* [retval][out] */ BSTR *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasAlloca(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasSetJump(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasLongJump(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasInlAsm(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasEH(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasSEH(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasEHa(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isNaked(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isAggregated(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isSplitted(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_container(
- /* [retval][out] */ IDiaSymbol **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_inlSpec(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_noStackOrdering(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualBaseTableType(
- /* [retval][out] */ IDiaSymbol **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hasManagedCode(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isHotpatchable(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isCVTCIL(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isMSILNetmodule(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isCTypes(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isStripped(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_frontEndQFE(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_backEndQFE(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_wasInlined(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_strictGSCheck(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isCxxReturnUdt(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isConstructorVirtualBase(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_RValueReference(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_unmodifiedType(
- /* [retval][out] */ IDiaSymbol **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_framePointerPresent(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_isSafeBuffers(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_intrinsic(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_sealed(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hfaFloat(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_hfaDouble(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_liveRangeStartAddressSection(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_liveRangeStartAddressOffset(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_liveRangeStartRelativeVirtualAddress(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_countLiveRanges(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_liveRangeLength(
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_offsetInUdt(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_paramBasePointerRegisterId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_localBasePointerRegisterId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaSymbolVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaSymbol * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaSymbol * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaSymbol * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symIndexId )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symTag )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_name )(
- IDiaSymbol * This,
- /* [retval][out] */ BSTR *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParent )(
- IDiaSymbol * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParent )(
- IDiaSymbol * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_type )(
- IDiaSymbol * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataKind )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_locationType )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressOffset )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )(
- IDiaSymbol * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerId )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offset )(
- IDiaSymbol * This,
- /* [retval][out] */ LONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )(
- IDiaSymbol * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_slot )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_volatileType )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constType )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unalignedType )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_access )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_libraryName )(
- IDiaSymbol * This,
- /* [retval][out] */ BSTR *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_platform )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_language )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_editAndContinueEnabled )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMajor )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndMinor )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndBuild )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMajor )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndMinor )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndBuild )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sourceFileName )(
- IDiaSymbol * This,
- /* [retval][out] */ BSTR *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unused )(
- IDiaSymbol * This,
- /* [retval][out] */ BSTR *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thunkOrdinal )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_thisAdjust )(
- IDiaSymbol * This,
- /* [retval][out] */ LONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseOffset )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtual )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intro )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_pure )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_callingConvention )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_value )(
- IDiaSymbol * This,
- /* [retval][out] */ VARIANT *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_baseType )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_token )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_timeStamp )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_guid )(
- IDiaSymbol * This,
- /* [retval][out] */ GUID *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_symbolsFileName )(
- IDiaSymbol * This,
- /* [retval][out] */ BSTR *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_reference )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_count )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_bitPosition )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexType )(
- IDiaSymbol * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_packed )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_constructor )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_overloadedOperator )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_nested )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasNestedTypes )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAssignmentOperator )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasCastOperator )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_scoped )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseClass )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_indirectVirtualBaseClass )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBasePointerOffset )(
- IDiaSymbol * This,
- /* [retval][out] */ LONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShape )(
- IDiaSymbol * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lexicalParentId )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_classParentId )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_typeId )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_arrayIndexTypeId )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualTableShapeId )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_code )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_function )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_managed )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_msil )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseDispIndex )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_undecoratedName )(
- IDiaSymbol * This,
- /* [retval][out] */ BSTR *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_age )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_signature )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerGenerated )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressTaken )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_rank )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBound )(
- IDiaSymbol * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBound )(
- IDiaSymbol * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lowerBoundId )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_upperBoundId )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- HRESULT ( STDMETHODCALLTYPE *get_dataBytes )(
- IDiaSymbol * This,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData);
-
- HRESULT ( STDMETHODCALLTYPE *findChildren )(
- IDiaSymbol * This,
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [out] */ IDiaEnumSymbols **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findChildrenEx )(
- IDiaSymbol * This,
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [out] */ IDiaEnumSymbols **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findChildrenExByAddr )(
- IDiaSymbol * This,
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [in] */ DWORD isect,
- /* [in] */ DWORD offset,
- /* [out] */ IDiaEnumSymbols **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findChildrenExByVA )(
- IDiaSymbol * This,
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [in] */ ULONGLONG va,
- /* [out] */ IDiaEnumSymbols **ppResult);
-
- HRESULT ( STDMETHODCALLTYPE *findChildrenExByRVA )(
- IDiaSymbol * This,
- /* [in] */ enum SymTagEnum symtag,
- /* [in] */ LPCOLESTR name,
- /* [in] */ DWORD compareFlags,
- /* [in] */ DWORD rva,
- /* [out] */ IDiaEnumSymbols **ppResult);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetSection )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetOffset )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetRelativeVirtualAddress )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_targetVirtualAddress )(
- IDiaSymbol * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_machineType )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemId )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_oemSymbolId )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- HRESULT ( STDMETHODCALLTYPE *get_types )(
- IDiaSymbol * This,
- /* [in] */ DWORD cTypes,
- /* [out] */ DWORD *pcTypes,
- /* [size_is][size_is][out] */ IDiaSymbol **pTypes);
-
- HRESULT ( STDMETHODCALLTYPE *get_typeIds )(
- IDiaSymbol * This,
- /* [in] */ DWORD cTypeIds,
- /* [out] */ DWORD *pcTypeIds,
- /* [size_is][out] */ DWORD *pdwTypeIds);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectPointerType )(
- IDiaSymbol * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_udtKind )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- HRESULT ( STDMETHODCALLTYPE *get_undecoratedNameEx )(
- IDiaSymbol * This,
- /* [in] */ DWORD undecorateOptions,
- /* [out] */ BSTR *name);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noReturn )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_customCallingConvention )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noInline )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_optimizedCodeDebugInfo )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_notReached )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_interruptReturn )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_farReturn )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStatic )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasDebugInfo )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isLTCG )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isDataAligned )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSecurityChecks )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilerName )(
- IDiaSymbol * This,
- /* [retval][out] */ BSTR *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasAlloca )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSetJump )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasLongJump )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasInlAsm )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEH )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasSEH )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasEHa )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isNaked )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isAggregated )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSplitted )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_container )(
- IDiaSymbol * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_inlSpec )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_noStackOrdering )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualBaseTableType )(
- IDiaSymbol * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hasManagedCode )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isHotpatchable )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCVTCIL )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isMSILNetmodule )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCTypes )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isStripped )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frontEndQFE )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_backEndQFE )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_wasInlined )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_strictGSCheck )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isCxxReturnUdt )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isConstructorVirtualBase )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_RValueReference )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_unmodifiedType )(
- IDiaSymbol * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_framePointerPresent )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_isSafeBuffers )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_intrinsic )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sealed )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaFloat )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_hfaDouble )(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressSection )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartAddressOffset )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeStartRelativeVirtualAddress )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_countLiveRanges )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_liveRangeLength )(
- IDiaSymbol * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offsetInUdt )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_paramBasePointerRegisterId )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_localBasePointerRegisterId )(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- END_INTERFACE
- } IDiaSymbolVtbl;
-
- interface IDiaSymbol
- {
- CONST_VTBL struct IDiaSymbolVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaSymbol_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaSymbol_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaSymbol_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaSymbol_get_symIndexId(This,pRetVal) \
- ( (This)->lpVtbl -> get_symIndexId(This,pRetVal) )
-
-#define IDiaSymbol_get_symTag(This,pRetVal) \
- ( (This)->lpVtbl -> get_symTag(This,pRetVal) )
-
-#define IDiaSymbol_get_name(This,pRetVal) \
- ( (This)->lpVtbl -> get_name(This,pRetVal) )
-
-#define IDiaSymbol_get_lexicalParent(This,pRetVal) \
- ( (This)->lpVtbl -> get_lexicalParent(This,pRetVal) )
-
-#define IDiaSymbol_get_classParent(This,pRetVal) \
- ( (This)->lpVtbl -> get_classParent(This,pRetVal) )
-
-#define IDiaSymbol_get_type(This,pRetVal) \
- ( (This)->lpVtbl -> get_type(This,pRetVal) )
-
-#define IDiaSymbol_get_dataKind(This,pRetVal) \
- ( (This)->lpVtbl -> get_dataKind(This,pRetVal) )
-
-#define IDiaSymbol_get_locationType(This,pRetVal) \
- ( (This)->lpVtbl -> get_locationType(This,pRetVal) )
-
-#define IDiaSymbol_get_addressSection(This,pRetVal) \
- ( (This)->lpVtbl -> get_addressSection(This,pRetVal) )
-
-#define IDiaSymbol_get_addressOffset(This,pRetVal) \
- ( (This)->lpVtbl -> get_addressOffset(This,pRetVal) )
-
-#define IDiaSymbol_get_relativeVirtualAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) )
-
-#define IDiaSymbol_get_virtualAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) )
-
-#define IDiaSymbol_get_registerId(This,pRetVal) \
- ( (This)->lpVtbl -> get_registerId(This,pRetVal) )
-
-#define IDiaSymbol_get_offset(This,pRetVal) \
- ( (This)->lpVtbl -> get_offset(This,pRetVal) )
-
-#define IDiaSymbol_get_length(This,pRetVal) \
- ( (This)->lpVtbl -> get_length(This,pRetVal) )
-
-#define IDiaSymbol_get_slot(This,pRetVal) \
- ( (This)->lpVtbl -> get_slot(This,pRetVal) )
-
-#define IDiaSymbol_get_volatileType(This,pRetVal) \
- ( (This)->lpVtbl -> get_volatileType(This,pRetVal) )
-
-#define IDiaSymbol_get_constType(This,pRetVal) \
- ( (This)->lpVtbl -> get_constType(This,pRetVal) )
-
-#define IDiaSymbol_get_unalignedType(This,pRetVal) \
- ( (This)->lpVtbl -> get_unalignedType(This,pRetVal) )
-
-#define IDiaSymbol_get_access(This,pRetVal) \
- ( (This)->lpVtbl -> get_access(This,pRetVal) )
-
-#define IDiaSymbol_get_libraryName(This,pRetVal) \
- ( (This)->lpVtbl -> get_libraryName(This,pRetVal) )
-
-#define IDiaSymbol_get_platform(This,pRetVal) \
- ( (This)->lpVtbl -> get_platform(This,pRetVal) )
-
-#define IDiaSymbol_get_language(This,pRetVal) \
- ( (This)->lpVtbl -> get_language(This,pRetVal) )
-
-#define IDiaSymbol_get_editAndContinueEnabled(This,pRetVal) \
- ( (This)->lpVtbl -> get_editAndContinueEnabled(This,pRetVal) )
-
-#define IDiaSymbol_get_frontEndMajor(This,pRetVal) \
- ( (This)->lpVtbl -> get_frontEndMajor(This,pRetVal) )
-
-#define IDiaSymbol_get_frontEndMinor(This,pRetVal) \
- ( (This)->lpVtbl -> get_frontEndMinor(This,pRetVal) )
-
-#define IDiaSymbol_get_frontEndBuild(This,pRetVal) \
- ( (This)->lpVtbl -> get_frontEndBuild(This,pRetVal) )
-
-#define IDiaSymbol_get_backEndMajor(This,pRetVal) \
- ( (This)->lpVtbl -> get_backEndMajor(This,pRetVal) )
-
-#define IDiaSymbol_get_backEndMinor(This,pRetVal) \
- ( (This)->lpVtbl -> get_backEndMinor(This,pRetVal) )
-
-#define IDiaSymbol_get_backEndBuild(This,pRetVal) \
- ( (This)->lpVtbl -> get_backEndBuild(This,pRetVal) )
-
-#define IDiaSymbol_get_sourceFileName(This,pRetVal) \
- ( (This)->lpVtbl -> get_sourceFileName(This,pRetVal) )
-
-#define IDiaSymbol_get_unused(This,pRetVal) \
- ( (This)->lpVtbl -> get_unused(This,pRetVal) )
-
-#define IDiaSymbol_get_thunkOrdinal(This,pRetVal) \
- ( (This)->lpVtbl -> get_thunkOrdinal(This,pRetVal) )
-
-#define IDiaSymbol_get_thisAdjust(This,pRetVal) \
- ( (This)->lpVtbl -> get_thisAdjust(This,pRetVal) )
-
-#define IDiaSymbol_get_virtualBaseOffset(This,pRetVal) \
- ( (This)->lpVtbl -> get_virtualBaseOffset(This,pRetVal) )
-
-#define IDiaSymbol_get_virtual(This,pRetVal) \
- ( (This)->lpVtbl -> get_virtual(This,pRetVal) )
-
-#define IDiaSymbol_get_intro(This,pRetVal) \
- ( (This)->lpVtbl -> get_intro(This,pRetVal) )
-
-#define IDiaSymbol_get_pure(This,pRetVal) \
- ( (This)->lpVtbl -> get_pure(This,pRetVal) )
-
-#define IDiaSymbol_get_callingConvention(This,pRetVal) \
- ( (This)->lpVtbl -> get_callingConvention(This,pRetVal) )
-
-#define IDiaSymbol_get_value(This,pRetVal) \
- ( (This)->lpVtbl -> get_value(This,pRetVal) )
-
-#define IDiaSymbol_get_baseType(This,pRetVal) \
- ( (This)->lpVtbl -> get_baseType(This,pRetVal) )
-
-#define IDiaSymbol_get_token(This,pRetVal) \
- ( (This)->lpVtbl -> get_token(This,pRetVal) )
-
-#define IDiaSymbol_get_timeStamp(This,pRetVal) \
- ( (This)->lpVtbl -> get_timeStamp(This,pRetVal) )
-
-#define IDiaSymbol_get_guid(This,pRetVal) \
- ( (This)->lpVtbl -> get_guid(This,pRetVal) )
-
-#define IDiaSymbol_get_symbolsFileName(This,pRetVal) \
- ( (This)->lpVtbl -> get_symbolsFileName(This,pRetVal) )
-
-#define IDiaSymbol_get_reference(This,pRetVal) \
- ( (This)->lpVtbl -> get_reference(This,pRetVal) )
-
-#define IDiaSymbol_get_count(This,pRetVal) \
- ( (This)->lpVtbl -> get_count(This,pRetVal) )
-
-#define IDiaSymbol_get_bitPosition(This,pRetVal) \
- ( (This)->lpVtbl -> get_bitPosition(This,pRetVal) )
-
-#define IDiaSymbol_get_arrayIndexType(This,pRetVal) \
- ( (This)->lpVtbl -> get_arrayIndexType(This,pRetVal) )
-
-#define IDiaSymbol_get_packed(This,pRetVal) \
- ( (This)->lpVtbl -> get_packed(This,pRetVal) )
-
-#define IDiaSymbol_get_constructor(This,pRetVal) \
- ( (This)->lpVtbl -> get_constructor(This,pRetVal) )
-
-#define IDiaSymbol_get_overloadedOperator(This,pRetVal) \
- ( (This)->lpVtbl -> get_overloadedOperator(This,pRetVal) )
-
-#define IDiaSymbol_get_nested(This,pRetVal) \
- ( (This)->lpVtbl -> get_nested(This,pRetVal) )
-
-#define IDiaSymbol_get_hasNestedTypes(This,pRetVal) \
- ( (This)->lpVtbl -> get_hasNestedTypes(This,pRetVal) )
-
-#define IDiaSymbol_get_hasAssignmentOperator(This,pRetVal) \
- ( (This)->lpVtbl -> get_hasAssignmentOperator(This,pRetVal) )
-
-#define IDiaSymbol_get_hasCastOperator(This,pRetVal) \
- ( (This)->lpVtbl -> get_hasCastOperator(This,pRetVal) )
-
-#define IDiaSymbol_get_scoped(This,pRetVal) \
- ( (This)->lpVtbl -> get_scoped(This,pRetVal) )
-
-#define IDiaSymbol_get_virtualBaseClass(This,pRetVal) \
- ( (This)->lpVtbl -> get_virtualBaseClass(This,pRetVal) )
-
-#define IDiaSymbol_get_indirectVirtualBaseClass(This,pRetVal) \
- ( (This)->lpVtbl -> get_indirectVirtualBaseClass(This,pRetVal) )
-
-#define IDiaSymbol_get_virtualBasePointerOffset(This,pRetVal) \
- ( (This)->lpVtbl -> get_virtualBasePointerOffset(This,pRetVal) )
-
-#define IDiaSymbol_get_virtualTableShape(This,pRetVal) \
- ( (This)->lpVtbl -> get_virtualTableShape(This,pRetVal) )
-
-#define IDiaSymbol_get_lexicalParentId(This,pRetVal) \
- ( (This)->lpVtbl -> get_lexicalParentId(This,pRetVal) )
-
-#define IDiaSymbol_get_classParentId(This,pRetVal) \
- ( (This)->lpVtbl -> get_classParentId(This,pRetVal) )
-
-#define IDiaSymbol_get_typeId(This,pRetVal) \
- ( (This)->lpVtbl -> get_typeId(This,pRetVal) )
-
-#define IDiaSymbol_get_arrayIndexTypeId(This,pRetVal) \
- ( (This)->lpVtbl -> get_arrayIndexTypeId(This,pRetVal) )
-
-#define IDiaSymbol_get_virtualTableShapeId(This,pRetVal) \
- ( (This)->lpVtbl -> get_virtualTableShapeId(This,pRetVal) )
-
-#define IDiaSymbol_get_code(This,pRetVal) \
- ( (This)->lpVtbl -> get_code(This,pRetVal) )
-
-#define IDiaSymbol_get_function(This,pRetVal) \
- ( (This)->lpVtbl -> get_function(This,pRetVal) )
-
-#define IDiaSymbol_get_managed(This,pRetVal) \
- ( (This)->lpVtbl -> get_managed(This,pRetVal) )
-
-#define IDiaSymbol_get_msil(This,pRetVal) \
- ( (This)->lpVtbl -> get_msil(This,pRetVal) )
-
-#define IDiaSymbol_get_virtualBaseDispIndex(This,pRetVal) \
- ( (This)->lpVtbl -> get_virtualBaseDispIndex(This,pRetVal) )
-
-#define IDiaSymbol_get_undecoratedName(This,pRetVal) \
- ( (This)->lpVtbl -> get_undecoratedName(This,pRetVal) )
-
-#define IDiaSymbol_get_age(This,pRetVal) \
- ( (This)->lpVtbl -> get_age(This,pRetVal) )
-
-#define IDiaSymbol_get_signature(This,pRetVal) \
- ( (This)->lpVtbl -> get_signature(This,pRetVal) )
-
-#define IDiaSymbol_get_compilerGenerated(This,pRetVal) \
- ( (This)->lpVtbl -> get_compilerGenerated(This,pRetVal) )
-
-#define IDiaSymbol_get_addressTaken(This,pRetVal) \
- ( (This)->lpVtbl -> get_addressTaken(This,pRetVal) )
-
-#define IDiaSymbol_get_rank(This,pRetVal) \
- ( (This)->lpVtbl -> get_rank(This,pRetVal) )
-
-#define IDiaSymbol_get_lowerBound(This,pRetVal) \
- ( (This)->lpVtbl -> get_lowerBound(This,pRetVal) )
-
-#define IDiaSymbol_get_upperBound(This,pRetVal) \
- ( (This)->lpVtbl -> get_upperBound(This,pRetVal) )
-
-#define IDiaSymbol_get_lowerBoundId(This,pRetVal) \
- ( (This)->lpVtbl -> get_lowerBoundId(This,pRetVal) )
-
-#define IDiaSymbol_get_upperBoundId(This,pRetVal) \
- ( (This)->lpVtbl -> get_upperBoundId(This,pRetVal) )
-
-#define IDiaSymbol_get_dataBytes(This,cbData,pcbData,pbData) \
- ( (This)->lpVtbl -> get_dataBytes(This,cbData,pcbData,pbData) )
-
-#define IDiaSymbol_findChildren(This,symtag,name,compareFlags,ppResult) \
- ( (This)->lpVtbl -> findChildren(This,symtag,name,compareFlags,ppResult) )
-
-#define IDiaSymbol_findChildrenEx(This,symtag,name,compareFlags,ppResult) \
- ( (This)->lpVtbl -> findChildrenEx(This,symtag,name,compareFlags,ppResult) )
-
-#define IDiaSymbol_findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) \
- ( (This)->lpVtbl -> findChildrenExByAddr(This,symtag,name,compareFlags,isect,offset,ppResult) )
-
-#define IDiaSymbol_findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) \
- ( (This)->lpVtbl -> findChildrenExByVA(This,symtag,name,compareFlags,va,ppResult) )
-
-#define IDiaSymbol_findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) \
- ( (This)->lpVtbl -> findChildrenExByRVA(This,symtag,name,compareFlags,rva,ppResult) )
-
-#define IDiaSymbol_get_targetSection(This,pRetVal) \
- ( (This)->lpVtbl -> get_targetSection(This,pRetVal) )
-
-#define IDiaSymbol_get_targetOffset(This,pRetVal) \
- ( (This)->lpVtbl -> get_targetOffset(This,pRetVal) )
-
-#define IDiaSymbol_get_targetRelativeVirtualAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_targetRelativeVirtualAddress(This,pRetVal) )
-
-#define IDiaSymbol_get_targetVirtualAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_targetVirtualAddress(This,pRetVal) )
-
-#define IDiaSymbol_get_machineType(This,pRetVal) \
- ( (This)->lpVtbl -> get_machineType(This,pRetVal) )
-
-#define IDiaSymbol_get_oemId(This,pRetVal) \
- ( (This)->lpVtbl -> get_oemId(This,pRetVal) )
-
-#define IDiaSymbol_get_oemSymbolId(This,pRetVal) \
- ( (This)->lpVtbl -> get_oemSymbolId(This,pRetVal) )
-
-#define IDiaSymbol_get_types(This,cTypes,pcTypes,pTypes) \
- ( (This)->lpVtbl -> get_types(This,cTypes,pcTypes,pTypes) )
-
-#define IDiaSymbol_get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) \
- ( (This)->lpVtbl -> get_typeIds(This,cTypeIds,pcTypeIds,pdwTypeIds) )
-
-#define IDiaSymbol_get_objectPointerType(This,pRetVal) \
- ( (This)->lpVtbl -> get_objectPointerType(This,pRetVal) )
-
-#define IDiaSymbol_get_udtKind(This,pRetVal) \
- ( (This)->lpVtbl -> get_udtKind(This,pRetVal) )
-
-#define IDiaSymbol_get_undecoratedNameEx(This,undecorateOptions,name) \
- ( (This)->lpVtbl -> get_undecoratedNameEx(This,undecorateOptions,name) )
-
-#define IDiaSymbol_get_noReturn(This,pRetVal) \
- ( (This)->lpVtbl -> get_noReturn(This,pRetVal) )
-
-#define IDiaSymbol_get_customCallingConvention(This,pRetVal) \
- ( (This)->lpVtbl -> get_customCallingConvention(This,pRetVal) )
-
-#define IDiaSymbol_get_noInline(This,pRetVal) \
- ( (This)->lpVtbl -> get_noInline(This,pRetVal) )
-
-#define IDiaSymbol_get_optimizedCodeDebugInfo(This,pRetVal) \
- ( (This)->lpVtbl -> get_optimizedCodeDebugInfo(This,pRetVal) )
-
-#define IDiaSymbol_get_notReached(This,pRetVal) \
- ( (This)->lpVtbl -> get_notReached(This,pRetVal) )
-
-#define IDiaSymbol_get_interruptReturn(This,pRetVal) \
- ( (This)->lpVtbl -> get_interruptReturn(This,pRetVal) )
-
-#define IDiaSymbol_get_farReturn(This,pRetVal) \
- ( (This)->lpVtbl -> get_farReturn(This,pRetVal) )
-
-#define IDiaSymbol_get_isStatic(This,pRetVal) \
- ( (This)->lpVtbl -> get_isStatic(This,pRetVal) )
-
-#define IDiaSymbol_get_hasDebugInfo(This,pRetVal) \
- ( (This)->lpVtbl -> get_hasDebugInfo(This,pRetVal) )
-
-#define IDiaSymbol_get_isLTCG(This,pRetVal) \
- ( (This)->lpVtbl -> get_isLTCG(This,pRetVal) )
-
-#define IDiaSymbol_get_isDataAligned(This,pRetVal) \
- ( (This)->lpVtbl -> get_isDataAligned(This,pRetVal) )
-
-#define IDiaSymbol_get_hasSecurityChecks(This,pRetVal) \
- ( (This)->lpVtbl -> get_hasSecurityChecks(This,pRetVal) )
-
-#define IDiaSymbol_get_compilerName(This,pRetVal) \
- ( (This)->lpVtbl -> get_compilerName(This,pRetVal) )
-
-#define IDiaSymbol_get_hasAlloca(This,pRetVal) \
- ( (This)->lpVtbl -> get_hasAlloca(This,pRetVal) )
-
-#define IDiaSymbol_get_hasSetJump(This,pRetVal) \
- ( (This)->lpVtbl -> get_hasSetJump(This,pRetVal) )
-
-#define IDiaSymbol_get_hasLongJump(This,pRetVal) \
- ( (This)->lpVtbl -> get_hasLongJump(This,pRetVal) )
-
-#define IDiaSymbol_get_hasInlAsm(This,pRetVal) \
- ( (This)->lpVtbl -> get_hasInlAsm(This,pRetVal) )
-
-#define IDiaSymbol_get_hasEH(This,pRetVal) \
- ( (This)->lpVtbl -> get_hasEH(This,pRetVal) )
-
-#define IDiaSymbol_get_hasSEH(This,pRetVal) \
- ( (This)->lpVtbl -> get_hasSEH(This,pRetVal) )
-
-#define IDiaSymbol_get_hasEHa(This,pRetVal) \
- ( (This)->lpVtbl -> get_hasEHa(This,pRetVal) )
-
-#define IDiaSymbol_get_isNaked(This,pRetVal) \
- ( (This)->lpVtbl -> get_isNaked(This,pRetVal) )
-
-#define IDiaSymbol_get_isAggregated(This,pRetVal) \
- ( (This)->lpVtbl -> get_isAggregated(This,pRetVal) )
-
-#define IDiaSymbol_get_isSplitted(This,pRetVal) \
- ( (This)->lpVtbl -> get_isSplitted(This,pRetVal) )
-
-#define IDiaSymbol_get_container(This,pRetVal) \
- ( (This)->lpVtbl -> get_container(This,pRetVal) )
-
-#define IDiaSymbol_get_inlSpec(This,pRetVal) \
- ( (This)->lpVtbl -> get_inlSpec(This,pRetVal) )
-
-#define IDiaSymbol_get_noStackOrdering(This,pRetVal) \
- ( (This)->lpVtbl -> get_noStackOrdering(This,pRetVal) )
-
-#define IDiaSymbol_get_virtualBaseTableType(This,pRetVal) \
- ( (This)->lpVtbl -> get_virtualBaseTableType(This,pRetVal) )
-
-#define IDiaSymbol_get_hasManagedCode(This,pRetVal) \
- ( (This)->lpVtbl -> get_hasManagedCode(This,pRetVal) )
-
-#define IDiaSymbol_get_isHotpatchable(This,pRetVal) \
- ( (This)->lpVtbl -> get_isHotpatchable(This,pRetVal) )
-
-#define IDiaSymbol_get_isCVTCIL(This,pRetVal) \
- ( (This)->lpVtbl -> get_isCVTCIL(This,pRetVal) )
-
-#define IDiaSymbol_get_isMSILNetmodule(This,pRetVal) \
- ( (This)->lpVtbl -> get_isMSILNetmodule(This,pRetVal) )
-
-#define IDiaSymbol_get_isCTypes(This,pRetVal) \
- ( (This)->lpVtbl -> get_isCTypes(This,pRetVal) )
-
-#define IDiaSymbol_get_isStripped(This,pRetVal) \
- ( (This)->lpVtbl -> get_isStripped(This,pRetVal) )
-
-#define IDiaSymbol_get_frontEndQFE(This,pRetVal) \
- ( (This)->lpVtbl -> get_frontEndQFE(This,pRetVal) )
-
-#define IDiaSymbol_get_backEndQFE(This,pRetVal) \
- ( (This)->lpVtbl -> get_backEndQFE(This,pRetVal) )
-
-#define IDiaSymbol_get_wasInlined(This,pRetVal) \
- ( (This)->lpVtbl -> get_wasInlined(This,pRetVal) )
-
-#define IDiaSymbol_get_strictGSCheck(This,pRetVal) \
- ( (This)->lpVtbl -> get_strictGSCheck(This,pRetVal) )
-
-#define IDiaSymbol_get_isCxxReturnUdt(This,pRetVal) \
- ( (This)->lpVtbl -> get_isCxxReturnUdt(This,pRetVal) )
-
-#define IDiaSymbol_get_isConstructorVirtualBase(This,pRetVal) \
- ( (This)->lpVtbl -> get_isConstructorVirtualBase(This,pRetVal) )
-
-#define IDiaSymbol_get_RValueReference(This,pRetVal) \
- ( (This)->lpVtbl -> get_RValueReference(This,pRetVal) )
-
-#define IDiaSymbol_get_unmodifiedType(This,pRetVal) \
- ( (This)->lpVtbl -> get_unmodifiedType(This,pRetVal) )
-
-#define IDiaSymbol_get_framePointerPresent(This,pRetVal) \
- ( (This)->lpVtbl -> get_framePointerPresent(This,pRetVal) )
-
-#define IDiaSymbol_get_isSafeBuffers(This,pRetVal) \
- ( (This)->lpVtbl -> get_isSafeBuffers(This,pRetVal) )
-
-#define IDiaSymbol_get_intrinsic(This,pRetVal) \
- ( (This)->lpVtbl -> get_intrinsic(This,pRetVal) )
-
-#define IDiaSymbol_get_sealed(This,pRetVal) \
- ( (This)->lpVtbl -> get_sealed(This,pRetVal) )
-
-#define IDiaSymbol_get_hfaFloat(This,pRetVal) \
- ( (This)->lpVtbl -> get_hfaFloat(This,pRetVal) )
-
-#define IDiaSymbol_get_hfaDouble(This,pRetVal) \
- ( (This)->lpVtbl -> get_hfaDouble(This,pRetVal) )
-
-#define IDiaSymbol_get_liveRangeStartAddressSection(This,pRetVal) \
- ( (This)->lpVtbl -> get_liveRangeStartAddressSection(This,pRetVal) )
-
-#define IDiaSymbol_get_liveRangeStartAddressOffset(This,pRetVal) \
- ( (This)->lpVtbl -> get_liveRangeStartAddressOffset(This,pRetVal) )
-
-#define IDiaSymbol_get_liveRangeStartRelativeVirtualAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_liveRangeStartRelativeVirtualAddress(This,pRetVal) )
-
-#define IDiaSymbol_get_countLiveRanges(This,pRetVal) \
- ( (This)->lpVtbl -> get_countLiveRanges(This,pRetVal) )
-
-#define IDiaSymbol_get_liveRangeLength(This,pRetVal) \
- ( (This)->lpVtbl -> get_liveRangeLength(This,pRetVal) )
-
-#define IDiaSymbol_get_offsetInUdt(This,pRetVal) \
- ( (This)->lpVtbl -> get_offsetInUdt(This,pRetVal) )
-
-#define IDiaSymbol_get_paramBasePointerRegisterId(This,pRetVal) \
- ( (This)->lpVtbl -> get_paramBasePointerRegisterId(This,pRetVal) )
-
-#define IDiaSymbol_get_localBasePointerRegisterId(This,pRetVal) \
- ( (This)->lpVtbl -> get_localBasePointerRegisterId(This,pRetVal) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_virtualBaseTableType_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_virtualBaseTableType_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_hasManagedCode_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_hasManagedCode_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isHotpatchable_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_isHotpatchable_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isCVTCIL_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_isCVTCIL_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isMSILNetmodule_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_isMSILNetmodule_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isCTypes_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_isCTypes_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isStripped_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_isStripped_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_frontEndQFE_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_frontEndQFE_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_backEndQFE_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_backEndQFE_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_wasInlined_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_wasInlined_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_strictGSCheck_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_strictGSCheck_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isCxxReturnUdt_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_isCxxReturnUdt_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isConstructorVirtualBase_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_isConstructorVirtualBase_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_RValueReference_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_RValueReference_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_unmodifiedType_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_unmodifiedType_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_framePointerPresent_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_framePointerPresent_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_isSafeBuffers_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_isSafeBuffers_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_intrinsic_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_intrinsic_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_sealed_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_sealed_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_hfaFloat_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_hfaFloat_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_hfaDouble_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ BOOL *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_hfaDouble_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_liveRangeStartAddressSection_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_liveRangeStartAddressSection_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_liveRangeStartAddressOffset_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_liveRangeStartAddressOffset_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_liveRangeStartRelativeVirtualAddress_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_liveRangeStartRelativeVirtualAddress_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_countLiveRanges_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_countLiveRanges_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_liveRangeLength_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_liveRangeLength_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_offsetInUdt_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_offsetInUdt_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_paramBasePointerRegisterId_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_paramBasePointerRegisterId_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-/* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE IDiaSymbol_get_localBasePointerRegisterId_Proxy(
- IDiaSymbol * This,
- /* [retval][out] */ DWORD *pRetVal);
-
-
-void __RPC_STUB IDiaSymbol_get_localBasePointerRegisterId_Stub(
- IRpcStubBuffer *This,
- IRpcChannelBuffer *_pRpcChannelBuffer,
- PRPC_MESSAGE _pRpcMessage,
- DWORD *_pdwStubPhase);
-
-
-
-#endif /* __IDiaSymbol_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaSourceFile_INTERFACE_DEFINED__
-#define __IDiaSourceFile_INTERFACE_DEFINED__
-
-/* interface IDiaSourceFile */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaSourceFile;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("A2EF5353-F5A8-4eb3-90D2-CB526ACB3CDD")
- IDiaSourceFile : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_uniqueId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_fileName(
- /* [retval][out] */ BSTR *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_checksumType(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_compilands(
- /* [retval][out] */ IDiaEnumSymbols **pRetVal) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE get_checksum(
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaSourceFileVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaSourceFile * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaSourceFile * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaSourceFile * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_uniqueId )(
- IDiaSourceFile * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_fileName )(
- IDiaSourceFile * This,
- /* [retval][out] */ BSTR *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_checksumType )(
- IDiaSourceFile * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilands )(
- IDiaSourceFile * This,
- /* [retval][out] */ IDiaEnumSymbols **pRetVal);
-
- HRESULT ( STDMETHODCALLTYPE *get_checksum )(
- IDiaSourceFile * This,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData);
-
- END_INTERFACE
- } IDiaSourceFileVtbl;
-
- interface IDiaSourceFile
- {
- CONST_VTBL struct IDiaSourceFileVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaSourceFile_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaSourceFile_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaSourceFile_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaSourceFile_get_uniqueId(This,pRetVal) \
- ( (This)->lpVtbl -> get_uniqueId(This,pRetVal) )
-
-#define IDiaSourceFile_get_fileName(This,pRetVal) \
- ( (This)->lpVtbl -> get_fileName(This,pRetVal) )
-
-#define IDiaSourceFile_get_checksumType(This,pRetVal) \
- ( (This)->lpVtbl -> get_checksumType(This,pRetVal) )
-
-#define IDiaSourceFile_get_compilands(This,pRetVal) \
- ( (This)->lpVtbl -> get_compilands(This,pRetVal) )
-
-#define IDiaSourceFile_get_checksum(This,cbData,pcbData,pbData) \
- ( (This)->lpVtbl -> get_checksum(This,cbData,pcbData,pbData) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaSourceFile_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaLineNumber_INTERFACE_DEFINED__
-#define __IDiaLineNumber_INTERFACE_DEFINED__
-
-/* interface IDiaLineNumber */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaLineNumber;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("B388EB14-BE4D-421d-A8A1-6CF7AB057086")
- IDiaLineNumber : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_compiland(
- /* [retval][out] */ IDiaSymbol **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_sourceFile(
- /* [retval][out] */ IDiaSourceFile **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lineNumber(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lineNumberEnd(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_columnNumber(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_columnNumberEnd(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressSection(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressOffset(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualAddress(
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_length(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_sourceFileId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_statement(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_compilandId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaLineNumberVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaLineNumber * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaLineNumber * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaLineNumber * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compiland )(
- IDiaLineNumber * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sourceFile )(
- IDiaLineNumber * This,
- /* [retval][out] */ IDiaSourceFile **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lineNumber )(
- IDiaLineNumber * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lineNumberEnd )(
- IDiaLineNumber * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_columnNumber )(
- IDiaLineNumber * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_columnNumberEnd )(
- IDiaLineNumber * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )(
- IDiaLineNumber * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressOffset )(
- IDiaLineNumber * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )(
- IDiaLineNumber * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )(
- IDiaLineNumber * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )(
- IDiaLineNumber * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sourceFileId )(
- IDiaLineNumber * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_statement )(
- IDiaLineNumber * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilandId )(
- IDiaLineNumber * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- END_INTERFACE
- } IDiaLineNumberVtbl;
-
- interface IDiaLineNumber
- {
- CONST_VTBL struct IDiaLineNumberVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaLineNumber_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaLineNumber_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaLineNumber_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaLineNumber_get_compiland(This,pRetVal) \
- ( (This)->lpVtbl -> get_compiland(This,pRetVal) )
-
-#define IDiaLineNumber_get_sourceFile(This,pRetVal) \
- ( (This)->lpVtbl -> get_sourceFile(This,pRetVal) )
-
-#define IDiaLineNumber_get_lineNumber(This,pRetVal) \
- ( (This)->lpVtbl -> get_lineNumber(This,pRetVal) )
-
-#define IDiaLineNumber_get_lineNumberEnd(This,pRetVal) \
- ( (This)->lpVtbl -> get_lineNumberEnd(This,pRetVal) )
-
-#define IDiaLineNumber_get_columnNumber(This,pRetVal) \
- ( (This)->lpVtbl -> get_columnNumber(This,pRetVal) )
-
-#define IDiaLineNumber_get_columnNumberEnd(This,pRetVal) \
- ( (This)->lpVtbl -> get_columnNumberEnd(This,pRetVal) )
-
-#define IDiaLineNumber_get_addressSection(This,pRetVal) \
- ( (This)->lpVtbl -> get_addressSection(This,pRetVal) )
-
-#define IDiaLineNumber_get_addressOffset(This,pRetVal) \
- ( (This)->lpVtbl -> get_addressOffset(This,pRetVal) )
-
-#define IDiaLineNumber_get_relativeVirtualAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) )
-
-#define IDiaLineNumber_get_virtualAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) )
-
-#define IDiaLineNumber_get_length(This,pRetVal) \
- ( (This)->lpVtbl -> get_length(This,pRetVal) )
-
-#define IDiaLineNumber_get_sourceFileId(This,pRetVal) \
- ( (This)->lpVtbl -> get_sourceFileId(This,pRetVal) )
-
-#define IDiaLineNumber_get_statement(This,pRetVal) \
- ( (This)->lpVtbl -> get_statement(This,pRetVal) )
-
-#define IDiaLineNumber_get_compilandId(This,pRetVal) \
- ( (This)->lpVtbl -> get_compilandId(This,pRetVal) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaLineNumber_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaSectionContrib_INTERFACE_DEFINED__
-#define __IDiaSectionContrib_INTERFACE_DEFINED__
-
-/* interface IDiaSectionContrib */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaSectionContrib;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("0CF4B60E-35B1-4c6c-BDD8-854B9C8E3857")
- IDiaSectionContrib : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_compiland(
- /* [retval][out] */ IDiaSymbol **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressSection(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressOffset(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualAddress(
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_length(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_notPaged(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_code(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_initializedData(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_uninitializedData(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_remove(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_comdat(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_discardable(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_notCached(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_share(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_execute(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_read(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_write(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_dataCrc(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relocationsCrc(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_compilandId(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_code16bit(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaSectionContribVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaSectionContrib * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaSectionContrib * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaSectionContrib * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compiland )(
- IDiaSectionContrib * This,
- /* [retval][out] */ IDiaSymbol **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )(
- IDiaSectionContrib * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressOffset )(
- IDiaSectionContrib * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )(
- IDiaSectionContrib * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )(
- IDiaSectionContrib * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )(
- IDiaSectionContrib * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_notPaged )(
- IDiaSectionContrib * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_code )(
- IDiaSectionContrib * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_initializedData )(
- IDiaSectionContrib * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_uninitializedData )(
- IDiaSectionContrib * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_remove )(
- IDiaSectionContrib * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_comdat )(
- IDiaSectionContrib * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_discardable )(
- IDiaSectionContrib * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_notCached )(
- IDiaSectionContrib * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_share )(
- IDiaSectionContrib * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_execute )(
- IDiaSectionContrib * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_read )(
- IDiaSectionContrib * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_write )(
- IDiaSectionContrib * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_dataCrc )(
- IDiaSectionContrib * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relocationsCrc )(
- IDiaSectionContrib * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_compilandId )(
- IDiaSectionContrib * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_code16bit )(
- IDiaSectionContrib * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- END_INTERFACE
- } IDiaSectionContribVtbl;
-
- interface IDiaSectionContrib
- {
- CONST_VTBL struct IDiaSectionContribVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaSectionContrib_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaSectionContrib_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaSectionContrib_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaSectionContrib_get_compiland(This,pRetVal) \
- ( (This)->lpVtbl -> get_compiland(This,pRetVal) )
-
-#define IDiaSectionContrib_get_addressSection(This,pRetVal) \
- ( (This)->lpVtbl -> get_addressSection(This,pRetVal) )
-
-#define IDiaSectionContrib_get_addressOffset(This,pRetVal) \
- ( (This)->lpVtbl -> get_addressOffset(This,pRetVal) )
-
-#define IDiaSectionContrib_get_relativeVirtualAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) )
-
-#define IDiaSectionContrib_get_virtualAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) )
-
-#define IDiaSectionContrib_get_length(This,pRetVal) \
- ( (This)->lpVtbl -> get_length(This,pRetVal) )
-
-#define IDiaSectionContrib_get_notPaged(This,pRetVal) \
- ( (This)->lpVtbl -> get_notPaged(This,pRetVal) )
-
-#define IDiaSectionContrib_get_code(This,pRetVal) \
- ( (This)->lpVtbl -> get_code(This,pRetVal) )
-
-#define IDiaSectionContrib_get_initializedData(This,pRetVal) \
- ( (This)->lpVtbl -> get_initializedData(This,pRetVal) )
-
-#define IDiaSectionContrib_get_uninitializedData(This,pRetVal) \
- ( (This)->lpVtbl -> get_uninitializedData(This,pRetVal) )
-
-#define IDiaSectionContrib_get_remove(This,pRetVal) \
- ( (This)->lpVtbl -> get_remove(This,pRetVal) )
-
-#define IDiaSectionContrib_get_comdat(This,pRetVal) \
- ( (This)->lpVtbl -> get_comdat(This,pRetVal) )
-
-#define IDiaSectionContrib_get_discardable(This,pRetVal) \
- ( (This)->lpVtbl -> get_discardable(This,pRetVal) )
-
-#define IDiaSectionContrib_get_notCached(This,pRetVal) \
- ( (This)->lpVtbl -> get_notCached(This,pRetVal) )
-
-#define IDiaSectionContrib_get_share(This,pRetVal) \
- ( (This)->lpVtbl -> get_share(This,pRetVal) )
-
-#define IDiaSectionContrib_get_execute(This,pRetVal) \
- ( (This)->lpVtbl -> get_execute(This,pRetVal) )
-
-#define IDiaSectionContrib_get_read(This,pRetVal) \
- ( (This)->lpVtbl -> get_read(This,pRetVal) )
-
-#define IDiaSectionContrib_get_write(This,pRetVal) \
- ( (This)->lpVtbl -> get_write(This,pRetVal) )
-
-#define IDiaSectionContrib_get_dataCrc(This,pRetVal) \
- ( (This)->lpVtbl -> get_dataCrc(This,pRetVal) )
-
-#define IDiaSectionContrib_get_relocationsCrc(This,pRetVal) \
- ( (This)->lpVtbl -> get_relocationsCrc(This,pRetVal) )
-
-#define IDiaSectionContrib_get_compilandId(This,pRetVal) \
- ( (This)->lpVtbl -> get_compilandId(This,pRetVal) )
-
-#define IDiaSectionContrib_get_code16bit(This,pRetVal) \
- ( (This)->lpVtbl -> get_code16bit(This,pRetVal) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaSectionContrib_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaSegment_INTERFACE_DEFINED__
-#define __IDiaSegment_INTERFACE_DEFINED__
-
-/* interface IDiaSegment */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaSegment;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("0775B784-C75B-4449-848B-B7BD3159545B")
- IDiaSegment : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_frame(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_offset(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_length(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_read(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_write(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_execute(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressSection(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualAddress(
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaSegmentVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaSegment * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaSegment * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaSegment * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_frame )(
- IDiaSegment * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_offset )(
- IDiaSegment * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )(
- IDiaSegment * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_read )(
- IDiaSegment * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_write )(
- IDiaSegment * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_execute )(
- IDiaSegment * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )(
- IDiaSegment * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )(
- IDiaSegment * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )(
- IDiaSegment * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- END_INTERFACE
- } IDiaSegmentVtbl;
-
- interface IDiaSegment
- {
- CONST_VTBL struct IDiaSegmentVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaSegment_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaSegment_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaSegment_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaSegment_get_frame(This,pRetVal) \
- ( (This)->lpVtbl -> get_frame(This,pRetVal) )
-
-#define IDiaSegment_get_offset(This,pRetVal) \
- ( (This)->lpVtbl -> get_offset(This,pRetVal) )
-
-#define IDiaSegment_get_length(This,pRetVal) \
- ( (This)->lpVtbl -> get_length(This,pRetVal) )
-
-#define IDiaSegment_get_read(This,pRetVal) \
- ( (This)->lpVtbl -> get_read(This,pRetVal) )
-
-#define IDiaSegment_get_write(This,pRetVal) \
- ( (This)->lpVtbl -> get_write(This,pRetVal) )
-
-#define IDiaSegment_get_execute(This,pRetVal) \
- ( (This)->lpVtbl -> get_execute(This,pRetVal) )
-
-#define IDiaSegment_get_addressSection(This,pRetVal) \
- ( (This)->lpVtbl -> get_addressSection(This,pRetVal) )
-
-#define IDiaSegment_get_relativeVirtualAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) )
-
-#define IDiaSegment_get_virtualAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaSegment_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaInjectedSource_INTERFACE_DEFINED__
-#define __IDiaInjectedSource_INTERFACE_DEFINED__
-
-/* interface IDiaInjectedSource */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaInjectedSource;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("AE605CDC-8105-4a23-B710-3259F1E26112")
- IDiaInjectedSource : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_crc(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_length(
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_filename(
- /* [retval][out] */ BSTR *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_objectFilename(
- /* [retval][out] */ BSTR *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualFilename(
- /* [retval][out] */ BSTR *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_sourceCompression(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE get_source(
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaInjectedSourceVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaInjectedSource * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaInjectedSource * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaInjectedSource * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_crc )(
- IDiaInjectedSource * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_length )(
- IDiaInjectedSource * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_filename )(
- IDiaInjectedSource * This,
- /* [retval][out] */ BSTR *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_objectFilename )(
- IDiaInjectedSource * This,
- /* [retval][out] */ BSTR *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualFilename )(
- IDiaInjectedSource * This,
- /* [retval][out] */ BSTR *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_sourceCompression )(
- IDiaInjectedSource * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- HRESULT ( STDMETHODCALLTYPE *get_source )(
- IDiaInjectedSource * This,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData);
-
- END_INTERFACE
- } IDiaInjectedSourceVtbl;
-
- interface IDiaInjectedSource
- {
- CONST_VTBL struct IDiaInjectedSourceVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaInjectedSource_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaInjectedSource_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaInjectedSource_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaInjectedSource_get_crc(This,pRetVal) \
- ( (This)->lpVtbl -> get_crc(This,pRetVal) )
-
-#define IDiaInjectedSource_get_length(This,pRetVal) \
- ( (This)->lpVtbl -> get_length(This,pRetVal) )
-
-#define IDiaInjectedSource_get_filename(This,pRetVal) \
- ( (This)->lpVtbl -> get_filename(This,pRetVal) )
-
-#define IDiaInjectedSource_get_objectFilename(This,pRetVal) \
- ( (This)->lpVtbl -> get_objectFilename(This,pRetVal) )
-
-#define IDiaInjectedSource_get_virtualFilename(This,pRetVal) \
- ( (This)->lpVtbl -> get_virtualFilename(This,pRetVal) )
-
-#define IDiaInjectedSource_get_sourceCompression(This,pRetVal) \
- ( (This)->lpVtbl -> get_sourceCompression(This,pRetVal) )
-
-#define IDiaInjectedSource_get_source(This,cbData,pcbData,pbData) \
- ( (This)->lpVtbl -> get_source(This,cbData,pcbData,pbData) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaInjectedSource_INTERFACE_DEFINED__ */
-
-
-/* interface __MIDL_itf_dia2_0000_0023 */
-/* [local] */
-
-
-enum __MIDL___MIDL_itf_dia2_0000_0023_0001
- { E_DIA_INPROLOG = ( HRESULT )(( ( ( ( unsigned long )1 << 31 ) | ( ( unsigned long )( LONG )0x6d << 16 ) ) | ( unsigned long )100 ) ),
- E_DIA_SYNTAX = ( E_DIA_INPROLOG + 1 ) ,
- E_DIA_FRAME_ACCESS = ( E_DIA_SYNTAX + 1 ) ,
- E_DIA_VALUE = ( E_DIA_FRAME_ACCESS + 1 )
- } ;
-
-
-extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0023_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0023_v0_0_s_ifspec;
-
-#ifndef __IDiaStackWalkFrame_INTERFACE_DEFINED__
-#define __IDiaStackWalkFrame_INTERFACE_DEFINED__
-
-/* interface IDiaStackWalkFrame */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaStackWalkFrame;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("97F0F1A6-E04E-4ea4-B4F9-B0D0E8D90F5D")
- IDiaStackWalkFrame : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_registerValue(
- /* [in] */ DWORD index,
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_registerValue(
- /* [in] */ DWORD index,
- /* [in] */ ULONGLONG NewVal) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE readMemory(
- /* [in] */ ULONGLONG va,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE searchForReturnAddress(
- /* [in] */ IDiaFrameData *frame,
- /* [out] */ ULONGLONG *returnAddress) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE searchForReturnAddressStart(
- /* [in] */ IDiaFrameData *frame,
- /* [in] */ ULONGLONG startAddress,
- /* [out] */ ULONGLONG *returnAddress) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaStackWalkFrameVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaStackWalkFrame * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaStackWalkFrame * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaStackWalkFrame * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerValue )(
- IDiaStackWalkFrame * This,
- /* [in] */ DWORD index,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE *put_registerValue )(
- IDiaStackWalkFrame * This,
- /* [in] */ DWORD index,
- /* [in] */ ULONGLONG NewVal);
-
- HRESULT ( STDMETHODCALLTYPE *readMemory )(
- IDiaStackWalkFrame * This,
- /* [in] */ ULONGLONG va,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData);
-
- HRESULT ( STDMETHODCALLTYPE *searchForReturnAddress )(
- IDiaStackWalkFrame * This,
- /* [in] */ IDiaFrameData *frame,
- /* [out] */ ULONGLONG *returnAddress);
-
- HRESULT ( STDMETHODCALLTYPE *searchForReturnAddressStart )(
- IDiaStackWalkFrame * This,
- /* [in] */ IDiaFrameData *frame,
- /* [in] */ ULONGLONG startAddress,
- /* [out] */ ULONGLONG *returnAddress);
-
- END_INTERFACE
- } IDiaStackWalkFrameVtbl;
-
- interface IDiaStackWalkFrame
- {
- CONST_VTBL struct IDiaStackWalkFrameVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaStackWalkFrame_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaStackWalkFrame_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaStackWalkFrame_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaStackWalkFrame_get_registerValue(This,index,pRetVal) \
- ( (This)->lpVtbl -> get_registerValue(This,index,pRetVal) )
-
-#define IDiaStackWalkFrame_put_registerValue(This,index,NewVal) \
- ( (This)->lpVtbl -> put_registerValue(This,index,NewVal) )
-
-#define IDiaStackWalkFrame_readMemory(This,va,cbData,pcbData,pbData) \
- ( (This)->lpVtbl -> readMemory(This,va,cbData,pcbData,pbData) )
-
-#define IDiaStackWalkFrame_searchForReturnAddress(This,frame,returnAddress) \
- ( (This)->lpVtbl -> searchForReturnAddress(This,frame,returnAddress) )
-
-#define IDiaStackWalkFrame_searchForReturnAddressStart(This,frame,startAddress,returnAddress) \
- ( (This)->lpVtbl -> searchForReturnAddressStart(This,frame,startAddress,returnAddress) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaStackWalkFrame_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaFrameData_INTERFACE_DEFINED__
-#define __IDiaFrameData_INTERFACE_DEFINED__
-
-/* interface IDiaFrameData */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaFrameData;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("A39184B7-6A36-42de-8EEC-7DF9F3F59F33")
- IDiaFrameData : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressSection(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_addressOffset(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualAddress(
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthBlock(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthLocals(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthParams(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_maxStack(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthProlog(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthSavedRegisters(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_program(
- /* [retval][out] */ BSTR *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_systemExceptionHandling(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_cplusplusExceptionHandling(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_functionStart(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_allocatesBasePointer(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_type(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_functionParent(
- /* [retval][out] */ IDiaFrameData **pRetVal) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE execute(
- IDiaStackWalkFrame *frame) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaFrameDataVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaFrameData * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaFrameData * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaFrameData * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressSection )(
- IDiaFrameData * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_addressOffset )(
- IDiaFrameData * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )(
- IDiaFrameData * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )(
- IDiaFrameData * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthBlock )(
- IDiaFrameData * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthLocals )(
- IDiaFrameData * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthParams )(
- IDiaFrameData * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_maxStack )(
- IDiaFrameData * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthProlog )(
- IDiaFrameData * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthSavedRegisters )(
- IDiaFrameData * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_program )(
- IDiaFrameData * This,
- /* [retval][out] */ BSTR *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_systemExceptionHandling )(
- IDiaFrameData * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_cplusplusExceptionHandling )(
- IDiaFrameData * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_functionStart )(
- IDiaFrameData * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_allocatesBasePointer )(
- IDiaFrameData * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_type )(
- IDiaFrameData * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_functionParent )(
- IDiaFrameData * This,
- /* [retval][out] */ IDiaFrameData **pRetVal);
-
- HRESULT ( STDMETHODCALLTYPE *execute )(
- IDiaFrameData * This,
- IDiaStackWalkFrame *frame);
-
- END_INTERFACE
- } IDiaFrameDataVtbl;
-
- interface IDiaFrameData
- {
- CONST_VTBL struct IDiaFrameDataVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaFrameData_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaFrameData_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaFrameData_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaFrameData_get_addressSection(This,pRetVal) \
- ( (This)->lpVtbl -> get_addressSection(This,pRetVal) )
-
-#define IDiaFrameData_get_addressOffset(This,pRetVal) \
- ( (This)->lpVtbl -> get_addressOffset(This,pRetVal) )
-
-#define IDiaFrameData_get_relativeVirtualAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) )
-
-#define IDiaFrameData_get_virtualAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) )
-
-#define IDiaFrameData_get_lengthBlock(This,pRetVal) \
- ( (This)->lpVtbl -> get_lengthBlock(This,pRetVal) )
-
-#define IDiaFrameData_get_lengthLocals(This,pRetVal) \
- ( (This)->lpVtbl -> get_lengthLocals(This,pRetVal) )
-
-#define IDiaFrameData_get_lengthParams(This,pRetVal) \
- ( (This)->lpVtbl -> get_lengthParams(This,pRetVal) )
-
-#define IDiaFrameData_get_maxStack(This,pRetVal) \
- ( (This)->lpVtbl -> get_maxStack(This,pRetVal) )
-
-#define IDiaFrameData_get_lengthProlog(This,pRetVal) \
- ( (This)->lpVtbl -> get_lengthProlog(This,pRetVal) )
-
-#define IDiaFrameData_get_lengthSavedRegisters(This,pRetVal) \
- ( (This)->lpVtbl -> get_lengthSavedRegisters(This,pRetVal) )
-
-#define IDiaFrameData_get_program(This,pRetVal) \
- ( (This)->lpVtbl -> get_program(This,pRetVal) )
-
-#define IDiaFrameData_get_systemExceptionHandling(This,pRetVal) \
- ( (This)->lpVtbl -> get_systemExceptionHandling(This,pRetVal) )
-
-#define IDiaFrameData_get_cplusplusExceptionHandling(This,pRetVal) \
- ( (This)->lpVtbl -> get_cplusplusExceptionHandling(This,pRetVal) )
-
-#define IDiaFrameData_get_functionStart(This,pRetVal) \
- ( (This)->lpVtbl -> get_functionStart(This,pRetVal) )
-
-#define IDiaFrameData_get_allocatesBasePointer(This,pRetVal) \
- ( (This)->lpVtbl -> get_allocatesBasePointer(This,pRetVal) )
-
-#define IDiaFrameData_get_type(This,pRetVal) \
- ( (This)->lpVtbl -> get_type(This,pRetVal) )
-
-#define IDiaFrameData_get_functionParent(This,pRetVal) \
- ( (This)->lpVtbl -> get_functionParent(This,pRetVal) )
-
-#define IDiaFrameData_execute(This,frame) \
- ( (This)->lpVtbl -> execute(This,frame) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaFrameData_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaImageData_INTERFACE_DEFINED__
-#define __IDiaImageData_INTERFACE_DEFINED__
-
-/* interface IDiaImageData */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaImageData;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("C8E40ED2-A1D9-4221-8692-3CE661184B44")
- IDiaImageData : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_relativeVirtualAddress(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_virtualAddress(
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_imageBase(
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaImageDataVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaImageData * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaImageData * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaImageData * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_relativeVirtualAddress )(
- IDiaImageData * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_virtualAddress )(
- IDiaImageData * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_imageBase )(
- IDiaImageData * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- END_INTERFACE
- } IDiaImageDataVtbl;
-
- interface IDiaImageData
- {
- CONST_VTBL struct IDiaImageDataVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaImageData_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaImageData_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaImageData_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaImageData_get_relativeVirtualAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_relativeVirtualAddress(This,pRetVal) )
-
-#define IDiaImageData_get_virtualAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_virtualAddress(This,pRetVal) )
-
-#define IDiaImageData_get_imageBase(This,pRetVal) \
- ( (This)->lpVtbl -> get_imageBase(This,pRetVal) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaImageData_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaTable_INTERFACE_DEFINED__
-#define __IDiaTable_INTERFACE_DEFINED__
-
-/* interface IDiaTable */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaTable;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("4A59FB77-ABAC-469b-A30B-9ECC85BFEF14")
- IDiaTable : public IEnumUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
- /* [retval][out] */ IUnknown **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_name(
- /* [retval][out] */ BSTR *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
- /* [retval][out] */ LONG *pRetVal) = 0;
-
- virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item(
- /* [in] */ DWORD index,
- /* [retval][out] */ IUnknown **element) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaTableVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaTable * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaTable * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaTable * This);
-
- /* [local] */ HRESULT ( STDMETHODCALLTYPE *Next )(
- IDiaTable * This,
- /* [in] */
- __in ULONG celt,
- /* [out] */
- __out_ecount_part(celt,*pceltFetched) IUnknown **rgelt,
- /* [out] */
- __out_opt ULONG *pceltFetched);
-
- HRESULT ( STDMETHODCALLTYPE *Skip )(
- IDiaTable * This,
- /* [in] */ ULONG celt);
-
- HRESULT ( STDMETHODCALLTYPE *Reset )(
- IDiaTable * This);
-
- HRESULT ( STDMETHODCALLTYPE *Clone )(
- IDiaTable * This,
- /* [out] */ IEnumUnknown **ppenum);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )(
- IDiaTable * This,
- /* [retval][out] */ IUnknown **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_name )(
- IDiaTable * This,
- /* [retval][out] */ BSTR *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )(
- IDiaTable * This,
- /* [retval][out] */ LONG *pRetVal);
-
- /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )(
- IDiaTable * This,
- /* [in] */ DWORD index,
- /* [retval][out] */ IUnknown **element);
-
- END_INTERFACE
- } IDiaTableVtbl;
-
- interface IDiaTable
- {
- CONST_VTBL struct IDiaTableVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaTable_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaTable_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaTable_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaTable_Next(This,celt,rgelt,pceltFetched) \
- ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) )
-
-#define IDiaTable_Skip(This,celt) \
- ( (This)->lpVtbl -> Skip(This,celt) )
-
-#define IDiaTable_Reset(This) \
- ( (This)->lpVtbl -> Reset(This) )
-
-#define IDiaTable_Clone(This,ppenum) \
- ( (This)->lpVtbl -> Clone(This,ppenum) )
-
-
-#define IDiaTable_get__NewEnum(This,pRetVal) \
- ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) )
-
-#define IDiaTable_get_name(This,pRetVal) \
- ( (This)->lpVtbl -> get_name(This,pRetVal) )
-
-#define IDiaTable_get_Count(This,pRetVal) \
- ( (This)->lpVtbl -> get_Count(This,pRetVal) )
-
-#define IDiaTable_Item(This,index,element) \
- ( (This)->lpVtbl -> Item(This,index,element) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaTable_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaEnumTables_INTERFACE_DEFINED__
-#define __IDiaEnumTables_INTERFACE_DEFINED__
-
-/* interface IDiaEnumTables */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaEnumTables;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("C65C2B0A-1150-4d7a-AFCC-E05BF3DEE81E")
- IDiaEnumTables : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
- /* [retval][out] */ IUnknown **pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_Count(
- /* [retval][out] */ LONG *pRetVal) = 0;
-
- virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE Item(
- /* [in] */ VARIANT index,
- /* [retval][out] */ IDiaTable **table) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Next(
- ULONG celt,
- IDiaTable **rgelt,
- ULONG *pceltFetched) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Skip(
- /* [in] */ ULONG celt) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Clone(
- /* [out] */ IDiaEnumTables **ppenum) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaEnumTablesVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaEnumTables * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaEnumTables * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaEnumTables * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get__NewEnum )(
- IDiaEnumTables * This,
- /* [retval][out] */ IUnknown **pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_Count )(
- IDiaEnumTables * This,
- /* [retval][out] */ LONG *pRetVal);
-
- /* [helpstring][id] */ HRESULT ( STDMETHODCALLTYPE *Item )(
- IDiaEnumTables * This,
- /* [in] */ VARIANT index,
- /* [retval][out] */ IDiaTable **table);
-
- HRESULT ( STDMETHODCALLTYPE *Next )(
- IDiaEnumTables * This,
- ULONG celt,
- IDiaTable **rgelt,
- ULONG *pceltFetched);
-
- HRESULT ( STDMETHODCALLTYPE *Skip )(
- IDiaEnumTables * This,
- /* [in] */ ULONG celt);
-
- HRESULT ( STDMETHODCALLTYPE *Reset )(
- IDiaEnumTables * This);
-
- HRESULT ( STDMETHODCALLTYPE *Clone )(
- IDiaEnumTables * This,
- /* [out] */ IDiaEnumTables **ppenum);
-
- END_INTERFACE
- } IDiaEnumTablesVtbl;
-
- interface IDiaEnumTables
- {
- CONST_VTBL struct IDiaEnumTablesVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaEnumTables_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaEnumTables_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaEnumTables_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaEnumTables_get__NewEnum(This,pRetVal) \
- ( (This)->lpVtbl -> get__NewEnum(This,pRetVal) )
-
-#define IDiaEnumTables_get_Count(This,pRetVal) \
- ( (This)->lpVtbl -> get_Count(This,pRetVal) )
-
-#define IDiaEnumTables_Item(This,index,table) \
- ( (This)->lpVtbl -> Item(This,index,table) )
-
-#define IDiaEnumTables_Next(This,celt,rgelt,pceltFetched) \
- ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) )
-
-#define IDiaEnumTables_Skip(This,celt) \
- ( (This)->lpVtbl -> Skip(This,celt) )
-
-#define IDiaEnumTables_Reset(This) \
- ( (This)->lpVtbl -> Reset(This) )
-
-#define IDiaEnumTables_Clone(This,ppenum) \
- ( (This)->lpVtbl -> Clone(This,ppenum) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaEnumTables_INTERFACE_DEFINED__ */
-
-
-
-#ifndef __Dia2Lib_LIBRARY_DEFINED__
-#define __Dia2Lib_LIBRARY_DEFINED__
-
-/* library Dia2Lib */
-/* [helpstring][version][uuid] */
-
-
-EXTERN_C const IID LIBID_Dia2Lib;
-
-EXTERN_C const CLSID CLSID_DiaSource;
-
-#ifdef __cplusplus
-
-class DECLSPEC_UUID("B86AE24D-BF2F-4ac9-B5A2-34B14E4CE11D")
-DiaSource;
-#endif
-
-EXTERN_C const CLSID CLSID_DiaSourceAlt;
-
-#ifdef __cplusplus
-
-class DECLSPEC_UUID("E3E90253-8E14-49a5-AA30-2E7B798AB839")
-DiaSourceAlt;
-#endif
-
-EXTERN_C const CLSID CLSID_DiaStackWalker;
-
-#ifdef __cplusplus
-
-class DECLSPEC_UUID("EBA05B6F-BD22-490e-A7B0-32D821C9046C")
-DiaStackWalker;
-#endif
-#endif /* __Dia2Lib_LIBRARY_DEFINED__ */
-
-/* interface __MIDL_itf_dia2_0000_0028 */
-/* [local] */
-
-#define DiaTable_Symbols ( L"Symbols" )
-
-#define DiaTable_Sections ( L"Sections" )
-
-#define DiaTable_SrcFiles ( L"SourceFiles" )
-
-#define DiaTable_LineNums ( L"LineNumbers" )
-
-#define DiaTable_SegMap ( L"SegmentMap" )
-
-#define DiaTable_Dbg ( L"Dbg" )
-
-#define DiaTable_InjSrc ( L"InjectedSource" )
-
-#define DiaTable_FrameData ( L"FrameData" )
-
-
-
-extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0028_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0028_v0_0_s_ifspec;
-
-#ifndef __IDiaPropertyStorage_INTERFACE_DEFINED__
-#define __IDiaPropertyStorage_INTERFACE_DEFINED__
-
-/* interface IDiaPropertyStorage */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaPropertyStorage;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("9d416f9c-e184-45b2-a4f0-ce517f719e9b")
- IDiaPropertyStorage : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE ReadMultiple(
- /* [in] */ ULONG cpspec,
- /* [size_is][in] */ const PROPSPEC *rgpspec,
- /* [size_is][out] */ PROPVARIANT *rgvar) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE ReadPropertyNames(
- /* [in] */ ULONG cpropid,
- /* [size_is][in] */ const PROPID *rgpropid,
- /* [size_is][out][in] */ BSTR *rglpwstrName) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Enum(
- /* [out] */ IEnumSTATPROPSTG **ppenum) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE ReadDWORD(
- /* [in] */ PROPID id,
- /* [out] */ DWORD *pValue) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE ReadLONG(
- /* [in] */ PROPID id,
- /* [out] */ LONG *pValue) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE ReadBOOL(
- /* [in] */ PROPID id,
- /* [out] */ BOOL *pValue) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE ReadULONGLONG(
- /* [in] */ PROPID id,
- /* [out] */ ULONGLONG *pValue) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE ReadBSTR(
- /* [in] */ PROPID id,
- /* [out] */ BSTR *pValue) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaPropertyStorageVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaPropertyStorage * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaPropertyStorage * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaPropertyStorage * This);
-
- HRESULT ( STDMETHODCALLTYPE *ReadMultiple )(
- IDiaPropertyStorage * This,
- /* [in] */ ULONG cpspec,
- /* [size_is][in] */ const PROPSPEC *rgpspec,
- /* [size_is][out] */ PROPVARIANT *rgvar);
-
- HRESULT ( STDMETHODCALLTYPE *ReadPropertyNames )(
- IDiaPropertyStorage * This,
- /* [in] */ ULONG cpropid,
- /* [size_is][in] */ const PROPID *rgpropid,
- /* [size_is][out][in] */ BSTR *rglpwstrName);
-
- HRESULT ( STDMETHODCALLTYPE *Enum )(
- IDiaPropertyStorage * This,
- /* [out] */ IEnumSTATPROPSTG **ppenum);
-
- HRESULT ( STDMETHODCALLTYPE *ReadDWORD )(
- IDiaPropertyStorage * This,
- /* [in] */ PROPID id,
- /* [out] */ DWORD *pValue);
-
- HRESULT ( STDMETHODCALLTYPE *ReadLONG )(
- IDiaPropertyStorage * This,
- /* [in] */ PROPID id,
- /* [out] */ LONG *pValue);
-
- HRESULT ( STDMETHODCALLTYPE *ReadBOOL )(
- IDiaPropertyStorage * This,
- /* [in] */ PROPID id,
- /* [out] */ BOOL *pValue);
-
- HRESULT ( STDMETHODCALLTYPE *ReadULONGLONG )(
- IDiaPropertyStorage * This,
- /* [in] */ PROPID id,
- /* [out] */ ULONGLONG *pValue);
-
- HRESULT ( STDMETHODCALLTYPE *ReadBSTR )(
- IDiaPropertyStorage * This,
- /* [in] */ PROPID id,
- /* [out] */ BSTR *pValue);
-
- END_INTERFACE
- } IDiaPropertyStorageVtbl;
-
- interface IDiaPropertyStorage
- {
- CONST_VTBL struct IDiaPropertyStorageVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaPropertyStorage_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaPropertyStorage_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaPropertyStorage_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaPropertyStorage_ReadMultiple(This,cpspec,rgpspec,rgvar) \
- ( (This)->lpVtbl -> ReadMultiple(This,cpspec,rgpspec,rgvar) )
-
-#define IDiaPropertyStorage_ReadPropertyNames(This,cpropid,rgpropid,rglpwstrName) \
- ( (This)->lpVtbl -> ReadPropertyNames(This,cpropid,rgpropid,rglpwstrName) )
-
-#define IDiaPropertyStorage_Enum(This,ppenum) \
- ( (This)->lpVtbl -> Enum(This,ppenum) )
-
-#define IDiaPropertyStorage_ReadDWORD(This,id,pValue) \
- ( (This)->lpVtbl -> ReadDWORD(This,id,pValue) )
-
-#define IDiaPropertyStorage_ReadLONG(This,id,pValue) \
- ( (This)->lpVtbl -> ReadLONG(This,id,pValue) )
-
-#define IDiaPropertyStorage_ReadBOOL(This,id,pValue) \
- ( (This)->lpVtbl -> ReadBOOL(This,id,pValue) )
-
-#define IDiaPropertyStorage_ReadULONGLONG(This,id,pValue) \
- ( (This)->lpVtbl -> ReadULONGLONG(This,id,pValue) )
-
-#define IDiaPropertyStorage_ReadBSTR(This,id,pValue) \
- ( (This)->lpVtbl -> ReadBSTR(This,id,pValue) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaPropertyStorage_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaStackFrame_INTERFACE_DEFINED__
-#define __IDiaStackFrame_INTERFACE_DEFINED__
-
-/* interface IDiaStackFrame */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaStackFrame;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("5edbc96d-cdd6-4792-afbe-cc89007d9610")
- IDiaStackFrame : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_type(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_base(
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_size(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_returnAddress(
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_localsBase(
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthLocals(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthParams(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthProlog(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_lengthSavedRegisters(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_systemExceptionHandling(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_cplusplusExceptionHandling(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_functionStart(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_allocatesBasePointer(
- /* [retval][out] */ BOOL *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_maxStack(
- /* [retval][out] */ DWORD *pRetVal) = 0;
-
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_registerValue(
- /* [in] */ DWORD index,
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaStackFrameVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaStackFrame * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaStackFrame * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaStackFrame * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_type )(
- IDiaStackFrame * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_base )(
- IDiaStackFrame * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_size )(
- IDiaStackFrame * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_returnAddress )(
- IDiaStackFrame * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_localsBase )(
- IDiaStackFrame * This,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthLocals )(
- IDiaStackFrame * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthParams )(
- IDiaStackFrame * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthProlog )(
- IDiaStackFrame * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_lengthSavedRegisters )(
- IDiaStackFrame * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_systemExceptionHandling )(
- IDiaStackFrame * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_cplusplusExceptionHandling )(
- IDiaStackFrame * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_functionStart )(
- IDiaStackFrame * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_allocatesBasePointer )(
- IDiaStackFrame * This,
- /* [retval][out] */ BOOL *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_maxStack )(
- IDiaStackFrame * This,
- /* [retval][out] */ DWORD *pRetVal);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerValue )(
- IDiaStackFrame * This,
- /* [in] */ DWORD index,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- END_INTERFACE
- } IDiaStackFrameVtbl;
-
- interface IDiaStackFrame
- {
- CONST_VTBL struct IDiaStackFrameVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaStackFrame_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaStackFrame_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaStackFrame_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaStackFrame_get_type(This,pRetVal) \
- ( (This)->lpVtbl -> get_type(This,pRetVal) )
-
-#define IDiaStackFrame_get_base(This,pRetVal) \
- ( (This)->lpVtbl -> get_base(This,pRetVal) )
-
-#define IDiaStackFrame_get_size(This,pRetVal) \
- ( (This)->lpVtbl -> get_size(This,pRetVal) )
-
-#define IDiaStackFrame_get_returnAddress(This,pRetVal) \
- ( (This)->lpVtbl -> get_returnAddress(This,pRetVal) )
-
-#define IDiaStackFrame_get_localsBase(This,pRetVal) \
- ( (This)->lpVtbl -> get_localsBase(This,pRetVal) )
-
-#define IDiaStackFrame_get_lengthLocals(This,pRetVal) \
- ( (This)->lpVtbl -> get_lengthLocals(This,pRetVal) )
-
-#define IDiaStackFrame_get_lengthParams(This,pRetVal) \
- ( (This)->lpVtbl -> get_lengthParams(This,pRetVal) )
-
-#define IDiaStackFrame_get_lengthProlog(This,pRetVal) \
- ( (This)->lpVtbl -> get_lengthProlog(This,pRetVal) )
-
-#define IDiaStackFrame_get_lengthSavedRegisters(This,pRetVal) \
- ( (This)->lpVtbl -> get_lengthSavedRegisters(This,pRetVal) )
-
-#define IDiaStackFrame_get_systemExceptionHandling(This,pRetVal) \
- ( (This)->lpVtbl -> get_systemExceptionHandling(This,pRetVal) )
-
-#define IDiaStackFrame_get_cplusplusExceptionHandling(This,pRetVal) \
- ( (This)->lpVtbl -> get_cplusplusExceptionHandling(This,pRetVal) )
-
-#define IDiaStackFrame_get_functionStart(This,pRetVal) \
- ( (This)->lpVtbl -> get_functionStart(This,pRetVal) )
-
-#define IDiaStackFrame_get_allocatesBasePointer(This,pRetVal) \
- ( (This)->lpVtbl -> get_allocatesBasePointer(This,pRetVal) )
-
-#define IDiaStackFrame_get_maxStack(This,pRetVal) \
- ( (This)->lpVtbl -> get_maxStack(This,pRetVal) )
-
-#define IDiaStackFrame_get_registerValue(This,index,pRetVal) \
- ( (This)->lpVtbl -> get_registerValue(This,index,pRetVal) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaStackFrame_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaEnumStackFrames_INTERFACE_DEFINED__
-#define __IDiaEnumStackFrames_INTERFACE_DEFINED__
-
-/* interface IDiaEnumStackFrames */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaEnumStackFrames;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("ec9d461d-ce74-4711-a020-7d8f9a1dd255")
- IDiaEnumStackFrames : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE Next(
- /* [in] */ ULONG celt,
- /* [out] */ IDiaStackFrame **rgelt,
- /* [out] */ ULONG *pceltFetched) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaEnumStackFramesVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaEnumStackFrames * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaEnumStackFrames * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaEnumStackFrames * This);
-
- HRESULT ( STDMETHODCALLTYPE *Next )(
- IDiaEnumStackFrames * This,
- /* [in] */ ULONG celt,
- /* [out] */ IDiaStackFrame **rgelt,
- /* [out] */ ULONG *pceltFetched);
-
- HRESULT ( STDMETHODCALLTYPE *Reset )(
- IDiaEnumStackFrames * This);
-
- END_INTERFACE
- } IDiaEnumStackFramesVtbl;
-
- interface IDiaEnumStackFrames
- {
- CONST_VTBL struct IDiaEnumStackFramesVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaEnumStackFrames_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaEnumStackFrames_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaEnumStackFrames_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaEnumStackFrames_Next(This,celt,rgelt,pceltFetched) \
- ( (This)->lpVtbl -> Next(This,celt,rgelt,pceltFetched) )
-
-#define IDiaEnumStackFrames_Reset(This) \
- ( (This)->lpVtbl -> Reset(This) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaEnumStackFrames_INTERFACE_DEFINED__ */
-
-
-/* interface __MIDL_itf_dia2_0000_0031 */
-/* [local] */
-
-typedef /* [public] */ struct __MIDL___MIDL_itf_dia2_0000_0031_0001
- {
- DWORD ulOffStart;
- DWORD cbProcSize;
- DWORD cdwLocals;
- WORD cdwParams;
- WORD cdwFlags;
- } FPODATA;
-
-
-
-extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0031_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_dia2_0000_0031_v0_0_s_ifspec;
-
-#ifndef __IDiaStackWalkHelper_INTERFACE_DEFINED__
-#define __IDiaStackWalkHelper_INTERFACE_DEFINED__
-
-/* interface IDiaStackWalkHelper */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaStackWalkHelper;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("feb0155d-35a8-42d4-8328-bf458f429a3a")
- IDiaStackWalkHelper : public IUnknown
- {
- public:
- virtual /* [id][helpstring][propget] */ HRESULT STDMETHODCALLTYPE get_registerValue(
- /* [in] */ DWORD index,
- /* [retval][out] */ ULONGLONG *pRetVal) = 0;
-
- virtual /* [id][helpstring][propput] */ HRESULT STDMETHODCALLTYPE put_registerValue(
- /* [in] */ DWORD index,
- /* [in] */ ULONGLONG NewVal) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE readMemory(
- /* [in] */ enum MemoryTypeEnum type,
- /* [in] */ ULONGLONG va,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE searchForReturnAddress(
- /* [in] */ IDiaFrameData *frame,
- /* [out] */ ULONGLONG *returnAddress) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE searchForReturnAddressStart(
- /* [in] */ IDiaFrameData *frame,
- /* [in] */ ULONGLONG startAddress,
- /* [out] */ ULONGLONG *returnAddress) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE frameForVA(
- /* [in] */ ULONGLONG va,
- /* [out] */ IDiaFrameData **ppFrame) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE symbolForVA(
- /* [in] */ ULONGLONG va,
- /* [out] */ IDiaSymbol **ppSymbol) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE pdataForVA(
- /* [in] */ ULONGLONG va,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE imageForVA(
- /* [in] */ ULONGLONG vaContext,
- /* [out] */ ULONGLONG *pvaImageStart) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaStackWalkHelperVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaStackWalkHelper * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaStackWalkHelper * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaStackWalkHelper * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerValue )(
- IDiaStackWalkHelper * This,
- /* [in] */ DWORD index,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE *put_registerValue )(
- IDiaStackWalkHelper * This,
- /* [in] */ DWORD index,
- /* [in] */ ULONGLONG NewVal);
-
- HRESULT ( STDMETHODCALLTYPE *readMemory )(
- IDiaStackWalkHelper * This,
- /* [in] */ enum MemoryTypeEnum type,
- /* [in] */ ULONGLONG va,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData);
-
- HRESULT ( STDMETHODCALLTYPE *searchForReturnAddress )(
- IDiaStackWalkHelper * This,
- /* [in] */ IDiaFrameData *frame,
- /* [out] */ ULONGLONG *returnAddress);
-
- HRESULT ( STDMETHODCALLTYPE *searchForReturnAddressStart )(
- IDiaStackWalkHelper * This,
- /* [in] */ IDiaFrameData *frame,
- /* [in] */ ULONGLONG startAddress,
- /* [out] */ ULONGLONG *returnAddress);
-
- HRESULT ( STDMETHODCALLTYPE *frameForVA )(
- IDiaStackWalkHelper * This,
- /* [in] */ ULONGLONG va,
- /* [out] */ IDiaFrameData **ppFrame);
-
- HRESULT ( STDMETHODCALLTYPE *symbolForVA )(
- IDiaStackWalkHelper * This,
- /* [in] */ ULONGLONG va,
- /* [out] */ IDiaSymbol **ppSymbol);
-
- HRESULT ( STDMETHODCALLTYPE *pdataForVA )(
- IDiaStackWalkHelper * This,
- /* [in] */ ULONGLONG va,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData);
-
- HRESULT ( STDMETHODCALLTYPE *imageForVA )(
- IDiaStackWalkHelper * This,
- /* [in] */ ULONGLONG vaContext,
- /* [out] */ ULONGLONG *pvaImageStart);
-
- END_INTERFACE
- } IDiaStackWalkHelperVtbl;
-
- interface IDiaStackWalkHelper
- {
- CONST_VTBL struct IDiaStackWalkHelperVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaStackWalkHelper_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaStackWalkHelper_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaStackWalkHelper_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaStackWalkHelper_get_registerValue(This,index,pRetVal) \
- ( (This)->lpVtbl -> get_registerValue(This,index,pRetVal) )
-
-#define IDiaStackWalkHelper_put_registerValue(This,index,NewVal) \
- ( (This)->lpVtbl -> put_registerValue(This,index,NewVal) )
-
-#define IDiaStackWalkHelper_readMemory(This,type,va,cbData,pcbData,pbData) \
- ( (This)->lpVtbl -> readMemory(This,type,va,cbData,pcbData,pbData) )
-
-#define IDiaStackWalkHelper_searchForReturnAddress(This,frame,returnAddress) \
- ( (This)->lpVtbl -> searchForReturnAddress(This,frame,returnAddress) )
-
-#define IDiaStackWalkHelper_searchForReturnAddressStart(This,frame,startAddress,returnAddress) \
- ( (This)->lpVtbl -> searchForReturnAddressStart(This,frame,startAddress,returnAddress) )
-
-#define IDiaStackWalkHelper_frameForVA(This,va,ppFrame) \
- ( (This)->lpVtbl -> frameForVA(This,va,ppFrame) )
-
-#define IDiaStackWalkHelper_symbolForVA(This,va,ppSymbol) \
- ( (This)->lpVtbl -> symbolForVA(This,va,ppSymbol) )
-
-#define IDiaStackWalkHelper_pdataForVA(This,va,cbData,pcbData,pbData) \
- ( (This)->lpVtbl -> pdataForVA(This,va,cbData,pcbData,pbData) )
-
-#define IDiaStackWalkHelper_imageForVA(This,vaContext,pvaImageStart) \
- ( (This)->lpVtbl -> imageForVA(This,vaContext,pvaImageStart) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaStackWalkHelper_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaStackWalker_INTERFACE_DEFINED__
-#define __IDiaStackWalker_INTERFACE_DEFINED__
-
-/* interface IDiaStackWalker */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaStackWalker;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("5485216b-a54c-469f-9670-52b24d5229bb")
- IDiaStackWalker : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE getEnumFrames(
- /* [in] */ IDiaStackWalkHelper *pHelper,
- /* [out] */ IDiaEnumStackFrames **ppEnum) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE getEnumFrames2(
- /* [in] */ enum CV_CPU_TYPE_e cpuid,
- /* [in] */ IDiaStackWalkHelper *pHelper,
- /* [out] */ IDiaEnumStackFrames **ppEnum) = 0;
-
- };
-
-#else /* C style interface */
-
- typedef struct IDiaStackWalkerVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaStackWalker * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaStackWalker * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaStackWalker * This);
-
- HRESULT ( STDMETHODCALLTYPE *getEnumFrames )(
- IDiaStackWalker * This,
- /* [in] */ IDiaStackWalkHelper *pHelper,
- /* [out] */ IDiaEnumStackFrames **ppEnum);
-
- HRESULT ( STDMETHODCALLTYPE *getEnumFrames2 )(
- IDiaStackWalker * This,
- /* [in] */ enum CV_CPU_TYPE_e cpuid,
- /* [in] */ IDiaStackWalkHelper *pHelper,
- /* [out] */ IDiaEnumStackFrames **ppEnum);
-
- END_INTERFACE
- } IDiaStackWalkerVtbl;
-
- interface IDiaStackWalker
- {
- CONST_VTBL struct IDiaStackWalkerVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaStackWalker_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaStackWalker_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaStackWalker_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaStackWalker_getEnumFrames(This,pHelper,ppEnum) \
- ( (This)->lpVtbl -> getEnumFrames(This,pHelper,ppEnum) )
-
-#define IDiaStackWalker_getEnumFrames2(This,cpuid,pHelper,ppEnum) \
- ( (This)->lpVtbl -> getEnumFrames2(This,cpuid,pHelper,ppEnum) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaStackWalker_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaStackWalkHelper2_INTERFACE_DEFINED__
-#define __IDiaStackWalkHelper2_INTERFACE_DEFINED__
-
-/* interface IDiaStackWalkHelper2 */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaStackWalkHelper2;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("8222c490-507b-4bef-b3bd-41dca7b5934c")
- IDiaStackWalkHelper2 : public IDiaStackWalkHelper
- {
- public:
- };
-
-#else /* C style interface */
-
- typedef struct IDiaStackWalkHelper2Vtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaStackWalkHelper2 * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaStackWalkHelper2 * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaStackWalkHelper2 * This);
-
- /* [id][helpstring][propget] */ HRESULT ( STDMETHODCALLTYPE *get_registerValue )(
- IDiaStackWalkHelper2 * This,
- /* [in] */ DWORD index,
- /* [retval][out] */ ULONGLONG *pRetVal);
-
- /* [id][helpstring][propput] */ HRESULT ( STDMETHODCALLTYPE *put_registerValue )(
- IDiaStackWalkHelper2 * This,
- /* [in] */ DWORD index,
- /* [in] */ ULONGLONG NewVal);
-
- HRESULT ( STDMETHODCALLTYPE *readMemory )(
- IDiaStackWalkHelper2 * This,
- /* [in] */ enum MemoryTypeEnum type,
- /* [in] */ ULONGLONG va,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData);
-
- HRESULT ( STDMETHODCALLTYPE *searchForReturnAddress )(
- IDiaStackWalkHelper2 * This,
- /* [in] */ IDiaFrameData *frame,
- /* [out] */ ULONGLONG *returnAddress);
-
- HRESULT ( STDMETHODCALLTYPE *searchForReturnAddressStart )(
- IDiaStackWalkHelper2 * This,
- /* [in] */ IDiaFrameData *frame,
- /* [in] */ ULONGLONG startAddress,
- /* [out] */ ULONGLONG *returnAddress);
-
- HRESULT ( STDMETHODCALLTYPE *frameForVA )(
- IDiaStackWalkHelper2 * This,
- /* [in] */ ULONGLONG va,
- /* [out] */ IDiaFrameData **ppFrame);
-
- HRESULT ( STDMETHODCALLTYPE *symbolForVA )(
- IDiaStackWalkHelper2 * This,
- /* [in] */ ULONGLONG va,
- /* [out] */ IDiaSymbol **ppSymbol);
-
- HRESULT ( STDMETHODCALLTYPE *pdataForVA )(
- IDiaStackWalkHelper2 * This,
- /* [in] */ ULONGLONG va,
- /* [in] */ DWORD cbData,
- /* [out] */ DWORD *pcbData,
- /* [size_is][out] */ BYTE *pbData);
-
- HRESULT ( STDMETHODCALLTYPE *imageForVA )(
- IDiaStackWalkHelper2 * This,
- /* [in] */ ULONGLONG vaContext,
- /* [out] */ ULONGLONG *pvaImageStart);
-
- END_INTERFACE
- } IDiaStackWalkHelper2Vtbl;
-
- interface IDiaStackWalkHelper2
- {
- CONST_VTBL struct IDiaStackWalkHelper2Vtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaStackWalkHelper2_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaStackWalkHelper2_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaStackWalkHelper2_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaStackWalkHelper2_get_registerValue(This,index,pRetVal) \
- ( (This)->lpVtbl -> get_registerValue(This,index,pRetVal) )
-
-#define IDiaStackWalkHelper2_put_registerValue(This,index,NewVal) \
- ( (This)->lpVtbl -> put_registerValue(This,index,NewVal) )
-
-#define IDiaStackWalkHelper2_readMemory(This,type,va,cbData,pcbData,pbData) \
- ( (This)->lpVtbl -> readMemory(This,type,va,cbData,pcbData,pbData) )
-
-#define IDiaStackWalkHelper2_searchForReturnAddress(This,frame,returnAddress) \
- ( (This)->lpVtbl -> searchForReturnAddress(This,frame,returnAddress) )
-
-#define IDiaStackWalkHelper2_searchForReturnAddressStart(This,frame,startAddress,returnAddress) \
- ( (This)->lpVtbl -> searchForReturnAddressStart(This,frame,startAddress,returnAddress) )
-
-#define IDiaStackWalkHelper2_frameForVA(This,va,ppFrame) \
- ( (This)->lpVtbl -> frameForVA(This,va,ppFrame) )
-
-#define IDiaStackWalkHelper2_symbolForVA(This,va,ppSymbol) \
- ( (This)->lpVtbl -> symbolForVA(This,va,ppSymbol) )
-
-#define IDiaStackWalkHelper2_pdataForVA(This,va,cbData,pcbData,pbData) \
- ( (This)->lpVtbl -> pdataForVA(This,va,cbData,pcbData,pbData) )
-
-#define IDiaStackWalkHelper2_imageForVA(This,vaContext,pvaImageStart) \
- ( (This)->lpVtbl -> imageForVA(This,vaContext,pvaImageStart) )
-
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaStackWalkHelper2_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDiaStackWalker2_INTERFACE_DEFINED__
-#define __IDiaStackWalker2_INTERFACE_DEFINED__
-
-/* interface IDiaStackWalker2 */
-/* [unique][helpstring][local][uuid][object] */
-
-
-EXTERN_C const IID IID_IDiaStackWalker2;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("7c185885-a015-4cac-9411-0f4fb39b1f3a")
- IDiaStackWalker2 : public IDiaStackWalker
- {
- public:
- };
-
-#else /* C style interface */
-
- typedef struct IDiaStackWalker2Vtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDiaStackWalker2 * This,
- /* [in] */ REFIID riid,
- /* [iid_is][out] */
- __RPC__deref_out void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDiaStackWalker2 * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDiaStackWalker2 * This);
-
- HRESULT ( STDMETHODCALLTYPE *getEnumFrames )(
- IDiaStackWalker2 * This,
- /* [in] */ IDiaStackWalkHelper *pHelper,
- /* [out] */ IDiaEnumStackFrames **ppEnum);
-
- HRESULT ( STDMETHODCALLTYPE *getEnumFrames2 )(
- IDiaStackWalker2 * This,
- /* [in] */ enum CV_CPU_TYPE_e cpuid,
- /* [in] */ IDiaStackWalkHelper *pHelper,
- /* [out] */ IDiaEnumStackFrames **ppEnum);
-
- END_INTERFACE
- } IDiaStackWalker2Vtbl;
-
- interface IDiaStackWalker2
- {
- CONST_VTBL struct IDiaStackWalker2Vtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDiaStackWalker2_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDiaStackWalker2_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDiaStackWalker2_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDiaStackWalker2_getEnumFrames(This,pHelper,ppEnum) \
- ( (This)->lpVtbl -> getEnumFrames(This,pHelper,ppEnum) )
-
-#define IDiaStackWalker2_getEnumFrames2(This,cpuid,pHelper,ppEnum) \
- ( (This)->lpVtbl -> getEnumFrames2(This,cpuid,pHelper,ppEnum) )
-
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDiaStackWalker2_INTERFACE_DEFINED__ */
-
-
-/* Additional Prototypes for ALL interfaces */
-
-/* end of Additional Prototypes */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-
diff --git a/src/ToolBox/PdbTypeMatch/include/diacreate.h b/src/ToolBox/PdbTypeMatch/include/diacreate.h
deleted file mode 100644
index 8ed82d2ff6..0000000000
--- a/src/ToolBox/PdbTypeMatch/include/diacreate.h
+++ /dev/null
@@ -1,40 +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.
-// diacreate.h - creation helper functions for DIA initialization
-#ifndef _DIACREATE_H_
-#define _DIACREATE_H_
-
-//
-// Create a dia data source object from the dia dll (by dll name - does not access the registry).
-//
-
-HRESULT STDMETHODCALLTYPE NoRegCoCreate( const __wchar_t *dllName,
- REFCLSID rclsid,
- REFIID riid,
- void **ppv);
-
-#ifndef _NATIVE_WCHAR_T_DEFINED
-#ifdef __cplusplus
-
-HRESULT STDMETHODCALLTYPE NoRegCoCreate( const wchar_t *dllName,
- REFCLSID rclsid,
- REFIID riid,
- void **ppv)
-{
- return NoRegCoCreate( (const __wchar_t *)dllName, rclsid, riid, ppv );
-}
-
-#endif
-#endif
-
-
-
-//
-// Create a dia data source object from the dia dll (looks up the class id in the registry).
-//
-HRESULT STDMETHODCALLTYPE NoOleCoCreate( REFCLSID rclsid,
- REFIID riid,
- void **ppv);
-
-#endif
diff --git a/src/ToolBox/PdbTypeMatch/native.rc b/src/ToolBox/PdbTypeMatch/native.rc
deleted file mode 100644
index 31e9f49b36..0000000000
--- a/src/ToolBox/PdbTypeMatch/native.rc
+++ /dev/null
@@ -1,8 +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.
-
-#define FX_VER_FILEDESCRIPTION_STR "Microsoft\0"
-
-#include <fxver.h>
-#include <fxver.rc>
diff --git a/src/ToolBox/PdbTypeMatch/regs.cpp b/src/ToolBox/PdbTypeMatch/regs.cpp
deleted file mode 100644
index aa56cbd3f7..0000000000
--- a/src/ToolBox/PdbTypeMatch/regs.cpp
+++ /dev/null
@@ -1,1708 +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 "stdafx.h"
-#include "cvconst.h"
-#include "regs.h"
-
-const wchar_t * const rgRegX86[] = {
- L"None", // 0 CV_REG_NONE
- L"al", // 1 CV_REG_AL
- L"cl", // 2 CV_REG_CL
- L"dl", // 3 CV_REG_DL
- L"bl", // 4 CV_REG_BL
- L"ah", // 5 CV_REG_AH
- L"ch", // 6 CV_REG_CH
- L"dh", // 7 CV_REG_DH
- L"bh", // 8 CV_REG_BH
- L"ax", // 9 CV_REG_AX
- L"cx", // 10 CV_REG_CX
- L"dx", // 11 CV_REG_DX
- L"bx", // 12 CV_REG_BX
- L"sp", // 13 CV_REG_SP
- L"bp", // 14 CV_REG_BP
- L"si", // 15 CV_REG_SI
- L"di", // 16 CV_REG_DI
- L"eax", // 17 CV_REG_EAX
- L"ecx", // 18 CV_REG_ECX
- L"edx", // 19 CV_REG_EDX
- L"ebx", // 20 CV_REG_EBX
- L"esp", // 21 CV_REG_ESP
- L"ebp", // 22 CV_REG_EBP
- L"esi", // 23 CV_REG_ESI
- L"edi", // 24 CV_REG_EDI
- L"es", // 25 CV_REG_ES
- L"cs", // 26 CV_REG_CS
- L"ss", // 27 CV_REG_SS
- L"ds", // 28 CV_REG_DS
- L"fs", // 29 CV_REG_FS
- L"gs", // 30 CV_REG_GS
- L"IP", // 31 CV_REG_IP
- L"FLAGS", // 32 CV_REG_FLAGS
- L"EIP", // 33 CV_REG_EIP
- L"EFLAGS", // 34 CV_REG_EFLAG
- L"???", // 35
- L"???", // 36
- L"???", // 37
- L"???", // 38
- L"???", // 39
- L"TEMP", // 40 CV_REG_TEMP
- L"TEMPH" // 41 CV_REG_TEMPH
- L"QUOTE", // 42 CV_REG_QUOTE
- L"PCDR3", // 43 CV_REG_PCDR3
- L"PCDR4", // 44 CV_REG_PCDR4
- L"PCDR5", // 45 CV_REG_PCDR5
- L"PCDR6", // 46 CV_REG_PCDR6
- L"PCDR7", // 47 CV_REG_PCDR7
- L"???", // 48
- L"???", // 49
- L"???", // 50
- L"???", // 51
- L"???", // 52
- L"???", // 53
- L"???", // 54
- L"???", // 55
- L"???", // 56
- L"???", // 57
- L"???", // 58
- L"???", // 59
- L"???", // 60
- L"???", // 61
- L"???", // 62
- L"???", // 63
- L"???", // 64
- L"???", // 65
- L"???", // 66
- L"???", // 67
- L"???", // 68
- L"???", // 69
- L"???", // 70
- L"???", // 71
- L"???", // 72
- L"???", // 73
- L"???", // 74
- L"???", // 75
- L"???", // 76
- L"???", // 77
- L"???", // 78
- L"???", // 79
- L"cr0", // 80 CV_REG_CR0
- L"cr1", // 81 CV_REG_CR1
- L"cr2", // 82 CV_REG_CR2
- L"cr3", // 83 CV_REG_CR3
- L"cr4", // 84 CV_REG_CR4
- L"???", // 85
- L"???", // 86
- L"???", // 87
- L"???", // 88
- L"???", // 89
- L"dr0", // 90 CV_REG_DR0
- L"dr1", // 91 CV_REG_DR1
- L"dr2", // 92 CV_REG_DR2
- L"dr3", // 93 CV_REG_DR3
- L"dr4", // 94 CV_REG_DR4
- L"dr5", // 95 CV_REG_DR5
- L"dr6", // 96 CV_REG_DR6
- L"dr7", // 97 CV_REG_DR7
- L"???", // 98
- L"???", // 99
- L"???", // 10
- L"???", // 101
- L"???", // 102
- L"???", // 103
- L"???", // 104
- L"???", // 105
- L"???", // 106
- L"???", // 107
- L"???", // 108
- L"???", // 109
- L"GDTR", // 110 CV_REG_GDTR
- L"GDTL", // 111 CV_REG_GDTL
- L"IDTR", // 112 CV_REG_IDTR
- L"IDTL", // 113 CV_REG_IDTL
- L"LDTR", // 114 CV_REG_LDTR
- L"TR", // 115 CV_REG_TR
- L"???", // 116
- L"???", // 117
- L"???", // 118
- L"???", // 119
- L"???", // 120
- L"???", // 121
- L"???", // 122
- L"???", // 123
- L"???", // 124
- L"???", // 125
- L"???", // 126
- L"???", // 127
- L"st(0)", // 128 CV_REG_ST0
- L"st(1)", // 129 CV_REG_ST1
- L"st(2)", // 130 CV_REG_ST2
- L"st(3)", // 131 CV_REG_ST3
- L"st(4)", // 132 CV_REG_ST4
- L"st(5)", // 133 CV_REG_ST5
- L"st(6)", // 134 CV_REG_ST6
- L"st(7)", // 135 CV_REG_ST7
- L"CTRL", // 136 CV_REG_CTRL
- L"STAT", // 137 CV_REG_STAT
- L"TAG", // 138 CV_REG_TAG
- L"FPIP", // 139 CV_REG_FPIP
- L"FPCS", // 140 CV_REG_FPCS
- L"FPDO", // 141 CV_REG_FPDO
- L"FPDS", // 142 CV_REG_FPDS
- L"ISEM", // 143 CV_REG_ISEM
- L"FPEIP", // 144 CV_REG_FPEIP
- L"FPED0" // 145 CV_REG_FPEDO
-};
-
-const wchar_t * const rgRegAMD64[] = {
- L"None", // 0 CV_REG_NONE
- L"al", // 1 CV_AMD64_AL
- L"cl", // 2 CV_AMD64_CL
- L"dl", // 3 CV_AMD64_DL
- L"bl", // 4 CV_AMD64_BL
- L"ah", // 5 CV_AMD64_AH
- L"ch", // 6 CV_AMD64_CH
- L"dh", // 7 CV_AMD64_DH
- L"bh", // 8 CV_AMD64_BH
- L"ax", // 9 CV_AMD64_AX
- L"cx", // 10 CV_AMD64_CX
- L"dx", // 11 CV_AMD64_DX
- L"bx", // 12 CV_AMD64_BX
- L"sp", // 13 CV_AMD64_SP
- L"bp", // 14 CV_AMD64_BP
- L"si", // 15 CV_AMD64_SI
- L"di", // 16 CV_AMD64_DI
- L"eax", // 17 CV_AMD64_EAX
- L"ecx", // 18 CV_AMD64_ECX
- L"edx", // 19 CV_AMD64_EDX
- L"ebx", // 20 CV_AMD64_EBX
- L"esp", // 21 CV_AMD64_ESP
- L"ebp", // 22 CV_AMD64_EBP
- L"esi", // 23 CV_AMD64_ESI
- L"edi", // 24 CV_AMD64_EDI
- L"es", // 25 CV_AMD64_ES
- L"cs", // 26 CV_AMD64_CS
- L"ss", // 27 CV_AMD64_SS
- L"ds", // 28 CV_AMD64_DS
- L"fs", // 29 CV_AMD64_FS
- L"gs", // 30 CV_AMD64_GS
- L"???", // 31 Not filled up
- L"flags", // 32 CV_AMD64_FLAGS
- L"rip", // 33 CV_AMD64_RIP
- L"eflags", // 34 CV_AMD64_EFLAGS
- L"???", // 35
- L"???", // 36
- L"???", // 37
- L"???", // 38
- L"???", // 39
- L"???", // 40
- L"???", // 41
- L"???", // 42
- L"???", // 43
- L"???", // 44
- L"???", // 45
- L"???", // 46
- L"???", // 47
- L"???", // 48
- L"???", // 49
- L"???", // 50
- L"???", // 51
- L"???", // 52
- L"???", // 53
- L"???", // 54
- L"???", // 55
- L"???", // 56
- L"???", // 57
- L"???", // 58
- L"???", // 59
- L"???", // 60
- L"???", // 61
- L"???", // 62
- L"???", // 63
- L"???", // 64
- L"???", // 65
- L"???", // 66
- L"???", // 67
- L"???", // 68
- L"???", // 69
- L"???", // 70
- L"???", // 71
- L"???", // 72
- L"???", // 73
- L"???", // 74
- L"???", // 75
- L"???", // 76
- L"???", // 77
- L"???", // 78
- L"???", // 79
- L"cr0", // 80 CV_AMD64_CR0
- L"cr1", // 81 CV_AMD64_CR1
- L"cr2", // 82 CV_AMD64_CR2
- L"cr3", // 83 CV_AMD64_CR3
- L"cr4", // 84 CV_AMD64_CR4
- L"???", // 85
- L"???", // 86
- L"???", // 87
- L"cr8", // 88 CV_AMD64_CR8
- L"???", // 89
- L"dr0", // 90 CV_AMD64_DR0
- L"dr1", // 91 CV_AMD64_DR1
- L"dr2", // 92 CV_AMD64_DR2
- L"dr3", // 93 CV_AMD64_DR3
- L"dr4", // 94 CV_AMD64_DR4
- L"dr5", // 95 CV_AMD64_DR5
- L"dr6", // 96 CV_AMD64_DR6
- L"dr7", // 97 CV_AMD64_DR7
- L"dr8", // 98 CV_AMD64_DR8
- L"dr9", // 99 CV_AMD64_DR9
- L"dr10", // 100 CV_AMD64_DR10
- L"dr11", // 101 CV_AMD64_DR11
- L"dr12", // 102 CV_AMD64_DR12
- L"dr13", // 103 CV_AMD64_DR13
- L"dr14", // 104 CV_AMD64_DR14
- L"dr15", // 105 CV_AMD64_DR15
- L"???", // 106
- L"???", // 107
- L"???", // 108
- L"???", // 109
- L"gdtr", // 110 CV_AMD64_GDTR
- L"gdt", // 111 CV_AMD64_GDTL
- L"idtr", // 112 CV_AMD64_IDTR
- L"idt", // 113 CV_AMD64_IDTL
- L"ldtr", // 114 CV_AMD64_LDTR
- L"tr", // 115 CV_AMD64_TR
- L"???", // 116
- L"???", // 117
- L"???", // 118
- L"???", // 119
- L"???", // 120
- L"???", // 121
- L"???", // 122
- L"???", // 123
- L"???", // 124
- L"???", // 125
- L"???", // 126
- L"???", // 127
- L"st(0)", // 128 CV_AMD64_ST0
- L"st(1)", // 129 CV_AMD64_ST1
- L"st(2)", // 130 CV_AMD64_ST2
- L"st(3)", // 131 CV_AMD64_ST3
- L"st(4)", // 132 CV_AMD64_ST4
- L"st(5)", // 133 CV_AMD64_ST5
- L"st(6)", // 134 CV_AMD64_ST6
- L"st(7)", // 135 CV_AMD64_ST7
- L"ctr", // 136 CV_AMD64_CTRL
- L"stat", // 137 CV_AMD64_STAT
- L"tag", // 138 CV_AMD64_TAG
- L"fpip", // 139 CV_AMD64_FPIP
- L"fpcs", // 140 CV_AMD64_FPCS
- L"fpdo", // 141 CV_AMD64_FPDO
- L"fpds", // 142 CV_AMD64_FPDS
- L"isem", // 143 CV_AMD64_ISEM
- L"fpeip", // 144 CV_AMD64_FPEIP
- L"fped0", // 145 CV_AMD64_FPEDO
- L"mm0", // 146 CV_AMD64_MM0
- L"mm1", // 147 CV_AMD64_MM1
- L"mm2", // 148 CV_AMD64_MM2
- L"mm3", // 149 CV_AMD64_MM3
- L"mm4", // 150 CV_AMD64_MM4
- L"mm5", // 151 CV_AMD64_MM5
- L"mm6", // 152 CV_AMD64_MM6
- L"mm7", // 153 CV_AMD64_MM7
- L"xmm0", // 154 CV_AMD64_XMM0
- L"xmm1", // 155 CV_AMD64_XMM1
- L"xmm2", // 156 CV_AMD64_XMM2
- L"xmm3", // 157 CV_AMD64_XMM3
- L"xmm4", // 158 CV_AMD64_XMM4
- L"xmm5", // 159 CV_AMD64_XMM5
- L"xmm6", // 160 CV_AMD64_XMM6
- L"xmm7", // 161 CV_AMD64_XMM7
- L"xmm0_0", // 162 CV_AMD64_XMM0_0
- L"xmm0_1", // 163 CV_AMD64_XMM0_1
- L"xmm0_2", // 164 CV_AMD64_XMM0_2
- L"xmm0_3", // 165 CV_AMD64_XMM0_3
- L"xmm1_0", // 166 CV_AMD64_XMM1_0
- L"xmm1_1", // 167 CV_AMD64_XMM1_1
- L"xmm1_2", // 168 CV_AMD64_XMM1_2
- L"xmm1_3", // 169 CV_AMD64_XMM1_3
- L"xmm2_0", // 170 CV_AMD64_XMM2_0
- L"xmm2_1", // 171 CV_AMD64_XMM2_1
- L"xmm2_2", // 172 CV_AMD64_XMM2_2
- L"xmm2_3", // 173 CV_AMD64_XMM2_3
- L"xmm3_0", // 174 CV_AMD64_XMM3_0
- L"xmm3_1", // 175 CV_AMD64_XMM3_1
- L"xmm3_2", // 176 CV_AMD64_XMM3_2
- L"xmm3_3", // 177 CV_AMD64_XMM3_3
- L"xmm4_0", // 178 CV_AMD64_XMM4_0
- L"xmm4_1", // 179 CV_AMD64_XMM4_1
- L"xmm4_2", // 180 CV_AMD64_XMM4_2
- L"xmm4_3", // 181 CV_AMD64_XMM4_3
- L"xmm5_0", // 182 CV_AMD64_XMM5_0
- L"xmm5_1", // 183 CV_AMD64_XMM5_1
- L"xmm5_2", // 184 CV_AMD64_XMM5_2
- L"xmm5_3", // 185 CV_AMD64_XMM5_3
- L"xmm6_0", // 186 CV_AMD64_XMM6_0
- L"xmm6_1", // 187 CV_AMD64_XMM6_1
- L"xmm6_2", // 188 CV_AMD64_XMM6_2
- L"xmm6_3", // 189 CV_AMD64_XMM6_3
- L"xmm7_0", // 190 CV_AMD64_XMM7_0
- L"xmm7_1", // 191 CV_AMD64_XMM7_1
- L"xmm7_2", // 192 CV_AMD64_XMM7_2
- L"xmm7_3", // 193 CV_AMD64_XMM7_3
- L"xmm0", // 194 CV_AMD64_XMM0L
- L"xmm1", // 195 CV_AMD64_XMM1L
- L"xmm2", // 196 CV_AMD64_XMM2L
- L"xmm3", // 197 CV_AMD64_XMM3L
- L"xmm4", // 198 CV_AMD64_XMM4L
- L"xmm5", // 199 CV_AMD64_XMM5L
- L"xmm6", // 200 CV_AMD64_XMM6L
- L"xmm7", // 201 CV_AMD64_XMM7L
- L"xmm0h", // 202 CV_AMD64_XMM0H
- L"xmm1h", // 203 CV_AMD64_XMM1H
- L"xmm2h", // 204 CV_AMD64_XMM2H
- L"xmm3h", // 205 CV_AMD64_XMM3H
- L"xmm4h", // 206 CV_AMD64_XMM4H
- L"xmm5h", // 207 CV_AMD64_XMM5H
- L"xmm6h", // 208 CV_AMD64_XMM6H
- L"xmm7h", // 209 CV_AMD64_XMM7H
- L"???", // 210
- L"mxcsr", // 211 CV_AMD64_MXCSR
- L"???", // 212
- L"???", // 213
- L"???", // 214
- L"???", // 215
- L"???", // 216
- L"???", // 217
- L"???", // 218
- L"???", // 219
- L"emm0", // 220 CV_AMD64_EMM0L
- L"emm1", // 221 CV_AMD64_EMM1L
- L"emm2", // 222 CV_AMD64_EMM2L
- L"emm3", // 223 CV_AMD64_EMM3L
- L"emm4", // 224 CV_AMD64_EMM4L
- L"emm5", // 225 CV_AMD64_EMM5L
- L"emm6", // 226 CV_AMD64_EMM6L
- L"emm7", // 227 CV_AMD64_EMM7L
- L"emm0h", // 228 CV_AMD64_EMM0H
- L"emm1h", // 229 CV_AMD64_EMM1H
- L"emm2h", // 230 CV_AMD64_EMM2H
- L"emm3h", // 231 CV_AMD64_EMM3H
- L"emm4h", // 232 CV_AMD64_EMM4H
- L"emm5h", // 233 CV_AMD64_EMM5H
- L"emm6h", // 234 CV_AMD64_EMM6H
- L"emm7h", // 235 CV_AMD64_EMM7H
- L"mm00", // 236 CV_AMD64_MM00
- L"mm01", // 237 CV_AMD64_MM01
- L"mm10", // 238 CV_AMD64_MM10
- L"mm11", // 239 CV_AMD64_MM11
- L"mm20", // 240 CV_AMD64_MM20
- L"mm21", // 241 CV_AMD64_MM21
- L"mm30", // 242 CV_AMD64_MM30
- L"mm31", // 243 CV_AMD64_MM31
- L"mm40", // 244 CV_AMD64_MM40
- L"mm41", // 245 CV_AMD64_MM41
- L"mm50", // 246 CV_AMD64_MM50
- L"mm51", // 247 CV_AMD64_MM51
- L"mm60", // 248 CV_AMD64_MM60
- L"mm61", // 249 CV_AMD64_MM61
- L"mm70", // 250 CV_AMD64_MM70
- L"mm71", // 251 CV_AMD64_MM71
- L"xmm8", // 252 CV_AMD64_XMM8
- L"xmm9", // 253 CV_AMD64_XMM9
- L"xmm10", // 254 CV_AMD64_XMM10
- L"xmm11", // 255 CV_AMD64_XMM11
- L"xmm12", // 256 CV_AMD64_XMM12
- L"xmm13", // 257 CV_AMD64_XMM13
- L"xmm14", // 258 CV_AMD64_XMM14
- L"xmm15", // 259 CV_AMD64_XMM15
- L"xmm8_0", // 260 CV_AMD64_XMM8_0
- L"xmm8_1", // 261 CV_AMD64_XMM8_1
- L"xmm8_2", // 262 CV_AMD64_XMM8_2
- L"xmm8_3", // 263 CV_AMD64_XMM8_3
- L"xmm9_0", // 264 CV_AMD64_XMM9_0
- L"xmm9_1", // 265 CV_AMD64_XMM9_1
- L"xmm9_2", // 266 CV_AMD64_XMM9_2
- L"xmm9_3", // 267 CV_AMD64_XMM9_3
- L"xmm10_0", // 268 CV_AMD64_XMM10_0
- L"xmm10_1", // 269 CV_AMD64_XMM10_1
- L"xmm10_2", // 270 CV_AMD64_XMM10_2
- L"xmm10_3", // 271 CV_AMD64_XMM10_3
- L"xmm11_0", // 272 CV_AMD64_XMM11_0
- L"xmm11_1", // 273 CV_AMD64_XMM11_1
- L"xmm11_2", // 274 CV_AMD64_XMM11_2
- L"xmm11_3", // 275 CV_AMD64_XMM11_3
- L"xmm12_0", // 276 CV_AMD64_XMM12_0
- L"xmm12_1", // 277 CV_AMD64_XMM12_1
- L"xmm12_2", // 278 CV_AMD64_XMM12_2
- L"xmm12_3", // 279 CV_AMD64_XMM12_3
- L"xmm13_0", // 280 CV_AMD64_XMM13_0
- L"xmm13_1", // 281 CV_AMD64_XMM13_1
- L"xmm13_2", // 282 CV_AMD64_XMM13_2
- L"xmm13_3", // 283 CV_AMD64_XMM13_3
- L"xmm14_0", // 284 CV_AMD64_XMM14_0
- L"xmm14_1", // 285 CV_AMD64_XMM14_1
- L"xmm14_2", // 286 CV_AMD64_XMM14_2
- L"xmm14_3", // 287 CV_AMD64_XMM14_3
- L"xmm15_0", // 288 CV_AMD64_XMM15_0
- L"xmm15_1", // 289 CV_AMD64_XMM15_1
- L"xmm15_2", // 290 CV_AMD64_XMM15_2
- L"xmm15_3", // 291 CV_AMD64_XMM15_3
- L"xmm8", // 292 CV_AMD64_XMM8L
- L"xmm9", // 293 CV_AMD64_XMM9L
- L"xmm10", // 294 CV_AMD64_XMM10L
- L"xmm11", // 295 CV_AMD64_XMM11L
- L"xmm12", // 296 CV_AMD64_XMM12L
- L"xmm13", // 297 CV_AMD64_XMM13L
- L"xmm14", // 298 CV_AMD64_XMM14L
- L"xmm15", // 299 CV_AMD64_XMM15L
- L"xmm8h", // 300 CV_AMD64_XMM8H
- L"xmm9h", // 301 CV_AMD64_XMM9H
- L"xmm10h", // 302 CV_AMD64_XMM10H
- L"xmm11h", // 303 CV_AMD64_XMM11H
- L"xmm12h", // 304 CV_AMD64_XMM12H
- L"xmm13h", // 305 CV_AMD64_XMM13H
- L"xmm14h", // 306 CV_AMD64_XMM14H
- L"xmm15h", // 307 CV_AMD64_XMM15H
- L"emm8", // 308 CV_AMD64_EMM8L
- L"emm9", // 309 CV_AMD64_EMM9L
- L"emm10", // 310 CV_AMD64_EMM10L
- L"emm11", // 311 CV_AMD64_EMM11L
- L"emm12", // 312 CV_AMD64_EMM12L
- L"emm13", // 313 CV_AMD64_EMM13L
- L"emm14", // 314 CV_AMD64_EMM14L
- L"emm15", // 315 CV_AMD64_EMM15L
- L"emm8h", // 316 CV_AMD64_EMM8H
- L"emm9h", // 317 CV_AMD64_EMM9H
- L"emm10h", // 318 CV_AMD64_EMM10H
- L"emm11h", // 319 CV_AMD64_EMM11H
- L"emm12h", // 320 CV_AMD64_EMM12H
- L"emm13h", // 321 CV_AMD64_EMM13H
- L"emm14h", // 322 CV_AMD64_EMM14H
- L"emm15h", // 323 CV_AMD64_EMM15H
- L"si", // 324 CV_AMD64_SIL
- L"di", // 325 CV_AMD64_DIL
- L"bp", // 326 CV_AMD64_BPL
- L"sp", // 327 CV_AMD64_SPL
- L"rax", // 328 CV_AMD64_RAX
- L"rbx", // 329 CV_AMD64_RBX
- L"rcx", // 330 CV_AMD64_RCX
- L"rdx", // 331 CV_AMD64_RDX
- L"rsi", // 332 CV_AMD64_RSI
- L"rdi", // 333 CV_AMD64_RDI
- L"rbp", // 334 CV_AMD64_RBP
- L"rsp", // 335 CV_AMD64_RSP
- L"r8", // 336 CV_AMD64_R8
- L"r9", // 337 CV_AMD64_R9
- L"r10", // 338 CV_AMD64_R10
- L"r11", // 339 CV_AMD64_R11
- L"r12", // 340 CV_AMD64_R12
- L"r13", // 341 CV_AMD64_R13
- L"r14", // 342 CV_AMD64_R14
- L"r15", // 343 CV_AMD64_R15
- L"r8b", // 344 CV_AMD64_R8B
- L"r9b", // 345 CV_AMD64_R9B
- L"r10b", // 346 CV_AMD64_R10B
- L"r11b", // 347 CV_AMD64_R11B
- L"r12b", // 348 CV_AMD64_R12B
- L"r13b", // 349 CV_AMD64_R13B
- L"r14b", // 350 CV_AMD64_R14B
- L"r15b", // 351 CV_AMD64_R15B
- L"r8w", // 352 CV_AMD64_R8W
- L"r9w", // 353 CV_AMD64_R9W
- L"r10w", // 354 CV_AMD64_R10W
- L"r11w", // 355 CV_AMD64_R11W
- L"r12w", // 356 CV_AMD64_R12W
- L"r13w", // 357 CV_AMD64_R13W
- L"r14w", // 358 CV_AMD64_R14W
- L"r15w", // 359 CV_AMD64_R15W
- L"r8d", // 360 CV_AMD64_R8D
- L"r9d", // 361 CV_AMD64_R9D
- L"r10d", // 362 CV_AMD64_R10D
- L"r11d", // 363 CV_AMD64_R11D
- L"r12d", // 364 CV_AMD64_R12D
- L"r13d", // 365 CV_AMD64_R13D
- L"r14d", // 366 CV_AMD64_R14D
- L"r15d" // 367 CV_AMD64_R15D
-};
-
-const wchar_t * const rgRegMips[] = {
- L"None", // 0 CV_M4_NOREG
- L"???", // 1
- L"???", // 2
- L"???", // 3
- L"???", // 4
- L"???", // 5
- L"???", // 6
- L"???", // 7
- L"???", // 8
- L"???", // 9
- L"zero", // 10 CV_M4_IntZERO
- L"at", // 11 CV_M4_IntAT
- L"v0", // 12 CV_M4_IntV0
- L"v1", // 13 CV_M4_IntV1
- L"a0", // 14 CV_M4_IntA0
- L"a1", // 15 CV_M4_IntA1
- L"a2", // 16 CV_M4_IntA2
- L"a3", // 17 CV_M4_IntA3
- L"t0", // 18 CV_M4_IntT0
- L"t1", // 19 CV_M4_IntT1
- L"t2", // 20 CV_M4_IntT2
- L"t3", // 21 CV_M4_IntT3
- L"t4", // 22 CV_M4_IntT4
- L"t5", // 23 CV_M4_IntT5
- L"t6", // 24 CV_M4_IntT6
- L"t7", // 25 CV_M4_IntT7
- L"s0", // 26 CV_M4_IntS0
- L"s1", // 27 CV_M4_IntS1
- L"s2", // 28 CV_M4_IntS2
- L"s3", // 29 CV_M4_IntS3
- L"s4", // 30 CV_M4_IntS4
- L"s5", // 31 CV_M4_IntS5
- L"s6", // 32 CV_M4_IntS6
- L"s7", // 33 CV_M4_IntS7
- L"t8", // 34 CV_M4_IntT8
- L"t9", // 35 CV_M4_IntT9
- L"k0", // 36 CV_M4_IntKT0
- L"k1", // 37 CV_M4_IntKT1
- L"gp", // 38 CV_M4_IntGP
- L"sp", // 39 CV_M4_IntSP
- L"s8", // 40 CV_M4_IntS8
- L"ra", // 41 CV_M4_IntRA
- L"lo", // 42 CV_M4_IntLO
- L"hi", // 43 CV_M4_IntHI
- L"???", // 44
- L"???", // 45
- L"???", // 46
- L"???", // 47
- L"???", // 48
- L"???", // 49
- L"Fir", // 50 CV_M4_Fir
- L"Psr", // 51 CV_M4_Psr
- L"???", // 52
- L"???", // 53
- L"???", // 54
- L"???", // 55
- L"???", // 56
- L"???", // 57
- L"???", // 58
- L"???", // 59
- L"$f0", // 60 CV_M4_FltF0
- L"$f1", // 61 CV_M4_FltF1
- L"$f2", // 62 CV_M4_FltF2
- L"$f3", // 63 CV_M4_FltF3
- L"$f4", // 64 CV_M4_FltF4
- L"$f5", // 65 CV_M4_FltF5
- L"$f6", // 66 CV_M4_FltF6
- L"$f7", // 67 CV_M4_FltF7
- L"$f8", // 68 CV_M4_FltF8
- L"$f9", // 69 CV_M4_FltF9
- L"$f10", // 70 CV_M4_FltF10
- L"$f11", // 71 CV_M4_FltF11
- L"$f12", // 72 CV_M4_FltF12
- L"$f13", // 73 CV_M4_FltF13
- L"$f14", // 74 CV_M4_FltF14
- L"$f15", // 75 CV_M4_FltF15
- L"$f16", // 76 CV_M4_FltF16
- L"$f17", // 77 CV_M4_FltF17
- L"$f18", // 78 CV_M4_FltF18
- L"$f19", // 79 CV_M4_FltF19
- L"$f20", // 80 CV_M4_FltF20
- L"$f21", // 81 CV_M4_FltF21
- L"$f22", // 82 CV_M4_FltF22
- L"$f23", // 83 CV_M4_FltF23
- L"$f24", // 84 CV_M4_FltF24
- L"$f25", // 85 CV_M4_FltF25
- L"$f26", // 86 CV_M4_FltF26
- L"$f27", // 87 CV_M4_FltF27
- L"$f28", // 88 CV_M4_FltF28
- L"$f29", // 89 CV_M4_FltF29
- L"$f30", // 90 CV_M4_FltF30
- L"$f31", // 91 CV_M4_FltF31
- L"Fsr" // 92 CV_M4_FltFsr
-};
-
-const wchar_t * const rgReg68k[] = {
- L"D0", // 0 CV_R68_D0
- L"D1", // 1 CV_R68_D1
- L"D2", // 2 CV_R68_D2
- L"D3", // 3 CV_R68_D3
- L"D4", // 4 CV_R68_D4
- L"D5", // 5 CV_R68_D5
- L"D6", // 6 CV_R68_D6
- L"D7", // 7 CV_R68_D7
- L"A0", // 8 CV_R68_A0
- L"A1", // 9 CV_R68_A1
- L"A2", // 10 CV_R68_A2
- L"A3", // 11 CV_R68_A3
- L"A4", // 12 CV_R68_A4
- L"A5", // 13 CV_R68_A5
- L"A6", // 14 CV_R68_A6
- L"A7", // 15 CV_R68_A7
- L"CCR", // 16 CV_R68_CCR
- L"SR", // 17 CV_R68_SR
- L"USP", // 18 CV_R68_USP
- L"MSP", // 19 CV_R68_MSP
- L"SFC", // 20 CV_R68_SFC
- L"DFC", // 21 CV_R68_DFC
- L"CACR", // 22 CV_R68_CACR
- L"VBR", // 23 CV_R68_VBR
- L"CAAR", // 24 CV_R68_CAAR
- L"ISP", // 25 CV_R68_ISP
- L"PC", // 26 CV_R68_PC
- L"???", // 27
- L"FPCR", // 28 CV_R68_FPCR
- L"FPSR", // 29 CV_R68_FPSR
- L"FPIAR", // 30 CV_R68_FPIAR
- L"???", // 31
- L"FP0", // 32 CV_R68_FP0
- L"FP1", // 33 CV_R68_FP1
- L"FP2", // 34 CV_R68_FP2
- L"FP3", // 35 CV_R68_FP3
- L"FP4", // 36 CV_R68_FP4
- L"FP5", // 37 CV_R68_FP5
- L"FP6", // 38 CV_R68_FP6
- L"FP7", // 39 CV_R68_FP7
- L"???", // 40
- L"???", // 41 CV_R68_MMUSR030
- L"???", // 42 CV_R68_MMUSR
- L"???", // 43 CV_R68_URP
- L"???", // 44 CV_R68_DTT0
- L"???", // 45 CV_R68_DTT1
- L"???", // 46 CV_R68_ITT0
- L"???", // 47 CV_R68_ITT1
- L"???", // 48
- L"???", // 49
- L"???", // 50
- L"PSR", // 51 CV_R68_PSR
- L"PCSR", // 52 CV_R68_PCSR
- L"VAL", // 53 CV_R68_VAL
- L"CRP", // 54 CV_R68_CRP
- L"SRP", // 55 CV_R68_SRP
- L"DRP", // 56 CV_R68_DRP
- L"TC", // 57 CV_R68_TC
- L"AC", // 58 CV_R68_AC
- L"SCC", // 59 CV_R68_SCC
- L"CAL", // 60 CV_R68_CAL
- L"TT0", // 61 CV_R68_TT0
- L"TT1", // 62 CV_R68_TT1
- L"???", // 63
- L"BAD0", // 64 CV_R68_BAD0
- L"BAD1", // 65 CV_R68_BAD1
- L"BAD2", // 66 CV_R68_BAD2
- L"BAD3", // 67 CV_R68_BAD3
- L"BAD4", // 68 CV_R68_BAD4
- L"BAD5", // 69 CV_R68_BAD5
- L"BAD6", // 70 CV_R68_BAD6
- L"BAD7", // 71 CV_R68_BAD7
- L"BAC0", // 72 CV_R68_BAC0
- L"BAC1", // 73 CV_R68_BAC1
- L"BAC2", // 74 CV_R68_BAC2
- L"BAC3", // 75 CV_R68_BAC3
- L"BAC4", // 76 CV_R68_BAC4
- L"BAC5", // 77 CV_R68_BAC5
- L"BAC6", // 78 CV_R68_BAC6
- L"BAC7" // 79 CV_R68_BAC7
-};
-
-const wchar_t * const rgRegAlpha[] = {
- L"None", // 0 CV_ALPHA_NOREG
- L"???", // 1
- L"???", // 2
- L"???", // 3
- L"???", // 4
- L"???", // 5
- L"???", // 6
- L"???", // 7
- L"???", // 8
- L"???", // 9
- L"$f0", // 10 CV_ALPHA_FltF0
- L"$f1", // 11 CV_ALPHA_FltF1
- L"$f2", // 12 CV_ALPHA_FltF2
- L"$f3", // 13 CV_ALPHA_FltF3
- L"$f4", // 14 CV_ALPHA_FltF4
- L"$f5", // 15 CV_ALPHA_FltF5
- L"$f6", // 16 CV_ALPHA_FltF6
- L"$f7", // 17 CV_ALPHA_FltF7
- L"$f8", // 18 CV_ALPHA_FltF8
- L"$f9", // 19 CV_ALPHA_FltF9
- L"$f10", // 20 CV_ALPHA_FltF10
- L"$f11", // 21 CV_ALPHA_FltF11
- L"$f12", // 22 CV_ALPHA_FltF12
- L"$f13", // 23 CV_ALPHA_FltF13
- L"$f14", // 24 CV_ALPHA_FltF14
- L"$f15", // 25 CV_ALPHA_FltF15
- L"$f16", // 26 CV_ALPHA_FltF16
- L"$f17", // 27 CV_ALPHA_FltF17
- L"$f18", // 28 CV_ALPHA_FltF18
- L"$f19", // 29 CV_ALPHA_FltF19
- L"$f20", // 30 CV_ALPHA_FltF20
- L"$f21", // 31 CV_ALPHA_FltF21
- L"$f22", // 32 CV_ALPHA_FltF22
- L"$f23", // 33 CV_ALPHA_FltF23
- L"$f24", // 34 CV_ALPHA_FltF24
- L"$f25", // 35 CV_ALPHA_FltF25
- L"$f26", // 36 CV_ALPHA_FltF26
- L"$f27", // 37 CV_ALPHA_FltF27
- L"$f28", // 38 CV_ALPHA_FltF28
- L"$f29", // 39 CV_ALPHA_FltF29
- L"$f30", // 40 CV_ALPHA_FltF30
- L"$f31", // 41 CV_ALPHA_FltF31
- L"v0", // 42 CV_ALPHA_IntV0
- L"t0", // 43 CV_ALPHA_IntT0
- L"t1", // 44 CV_ALPHA_IntT1
- L"t2", // 45 CV_ALPHA_IntT2
- L"t3", // 46 CV_ALPHA_IntT3
- L"t4", // 47 CV_ALPHA_IntT4
- L"t5", // 48 CV_ALPHA_IntT5
- L"t6", // 49 CV_ALPHA_IntT6
- L"t7", // 50 CV_ALPHA_IntT7
- L"s0", // 51 CV_ALPHA_IntS0
- L"s1", // 52 CV_ALPHA_IntS1
- L"s2", // 53 CV_ALPHA_IntS2
- L"s3", // 54 CV_ALPHA_IntS3
- L"s4", // 55 CV_ALPHA_IntS4
- L"s5", // 56 CV_ALPHA_IntS5
- L"fp", // 57 CV_ALPHA_IntFP
- L"a0", // 58 CV_ALPHA_IntA0
- L"a1", // 59 CV_ALPHA_IntA1
- L"a2", // 60 CV_ALPHA_IntA2
- L"a3", // 61 CV_ALPHA_IntA3
- L"a4", // 62 CV_ALPHA_IntA4
- L"a5", // 63 CV_ALPHA_IntA5
- L"t8", // 64 CV_ALPHA_IntT8
- L"t9", // 65 CV_ALPHA_IntT9
- L"t10", // 66 CV_ALPHA_IntT10
- L"t11", // 67 CV_ALPHA_IntT11
- L"ra", // 68 CV_ALPHA_IntRA
- L"t12", // 69 CV_ALPHA_IntT12
- L"at", // 70 CV_ALPHA_IntAT
- L"gp", // 71 CV_ALPHA_IntGP
- L"sp", // 72 CV_ALPHA_IntSP
- L"zero", // 73 CV_ALPHA_IntZERO
- L"Fpcr", // 74 CV_ALPHA_Fpcr
- L"Fir", // 75 CV_ALPHA_Fir
- L"Psr", // 76 CV_ALPHA_Psr
- L"FltFsr" // 77 CV_ALPHA_FltFsr
-};
-
-const wchar_t * const rgRegPpc[] = {
- L"None", // 0
- L"r0", // 1 CV_PPC_GPR0
- L"r1", // 2 CV_PPC_GPR1
- L"r2", // 3 CV_PPC_GPR2
- L"r3", // 4 CV_PPC_GPR3
- L"r4", // 5 CV_PPC_GPR4
- L"r5", // 6 CV_PPC_GPR5
- L"r6", // 7 CV_PPC_GPR6
- L"r7", // 8 CV_PPC_GPR7
- L"r8", // 9 CV_PPC_GPR8
- L"r9", // 10 CV_PPC_GPR9
- L"r10", // 11 CV_PPC_GPR10
- L"r11", // 12 CV_PPC_GPR11
- L"r12", // 13 CV_PPC_GPR12
- L"r13", // 14 CV_PPC_GPR13
- L"r14", // 15 CV_PPC_GPR14
- L"r15", // 16 CV_PPC_GPR15
- L"r16", // 17 CV_PPC_GPR16
- L"r17", // 18 CV_PPC_GPR17
- L"r18", // 19 CV_PPC_GPR18
- L"r19", // 20 CV_PPC_GPR19
- L"r20", // 21 CV_PPC_GPR20
- L"r21", // 22 CV_PPC_GPR21
- L"r22", // 23 CV_PPC_GPR22
- L"r23", // 24 CV_PPC_GPR23
- L"r24", // 25 CV_PPC_GPR24
- L"r25", // 26 CV_PPC_GPR25
- L"r26", // 27 CV_PPC_GPR26
- L"r27", // 28 CV_PPC_GPR27
- L"r28", // 29 CV_PPC_GPR28
- L"r29", // 30 CV_PPC_GPR29
- L"r30", // 31 CV_PPC_GPR30
- L"r31", // 32 CV_PPC_GPR31
- L"cr", // 33 CV_PPC_CR
- L"cr0", // 34 CV_PPC_CR0
- L"cr1", // 35 CV_PPC_CR1
- L"cr2", // 36 CV_PPC_CR2
- L"cr3", // 37 CV_PPC_CR3
- L"cr4", // 38 CV_PPC_CR4
- L"cr5", // 39 CV_PPC_CR5
- L"cr6", // 40 CV_PPC_CR6
- L"cr7", // 41 CV_PPC_CR7
- L"f0", // 42 CV_PPC_FPR0
- L"f1", // 43 CV_PPC_FPR1
- L"f2", // 44 CV_PPC_FPR2
- L"f3", // 45 CV_PPC_FPR3
- L"f4", // 46 CV_PPC_FPR4
- L"f5", // 47 CV_PPC_FPR5
- L"f6", // 48 CV_PPC_FPR6
- L"f7", // 49 CV_PPC_FPR7
- L"f8", // 50 CV_PPC_FPR8
- L"f9", // 51 CV_PPC_FPR9
- L"f10", // 52 CV_PPC_FPR10
- L"f11", // 53 CV_PPC_FPR11
- L"f12", // 54 CV_PPC_FPR12
- L"f13", // 55 CV_PPC_FPR13
- L"f14", // 56 CV_PPC_FPR14
- L"f15", // 57 CV_PPC_FPR15
- L"f16", // 58 CV_PPC_FPR16
- L"f17", // 59 CV_PPC_FPR17
- L"f18", // 60 CV_PPC_FPR18
- L"f19", // 61 CV_PPC_FPR19
- L"f20", // 62 CV_PPC_FPR20
- L"f21", // 63 CV_PPC_FPR21
- L"f22", // 64 CV_PPC_FPR22
- L"f23", // 65 CV_PPC_FPR23
- L"f24", // 66 CV_PPC_FPR24
- L"f25", // 67 CV_PPC_FPR25
- L"f26", // 68 CV_PPC_FPR26
- L"f27", // 69 CV_PPC_FPR27
- L"f28", // 70 CV_PPC_FPR28
- L"f29", // 71 CV_PPC_FPR29
- L"f30", // 72 CV_PPC_FPR30
- L"f31", // 73 CV_PPC_FPR31
- L"Fpscr", // 74 CV_PPC_FPSCR
- L"Msr" // 75 CV_PPC_MSR
-};
-
-const wchar_t * const rgRegSh[] = {
- L"None", // 0 CV_SH3_NOREG
- L"???", // 1
- L"???", // 2
- L"???", // 3
- L"???", // 4
- L"???", // 5
- L"???", // 6
- L"???", // 7
- L"???", // 8
- L"???", // 9
- L"r0", // 10 CV_SH3_IntR0
- L"r1", // 11 CV_SH3_IntR1
- L"r2", // 12 CV_SH3_IntR2
- L"r3", // 13 CV_SH3_IntR3
- L"r4", // 14 CV_SH3_IntR4
- L"r5", // 15 CV_SH3_IntR5
- L"r6", // 16 CV_SH3_IntR6
- L"r7", // 17 CV_SH3_IntR7
- L"r8", // 18 CV_SH3_IntR8
- L"r9", // 19 CV_SH3_IntR9
- L"r10", // 20 CV_SH3_IntR10
- L"r11", // 21 CV_SH3_IntR11
- L"r12", // 22 CV_SH3_IntR12
- L"r13", // 23 CV_SH3_IntR13
- L"fp", // 24 CV_SH3_IntFp
- L"sp", // 25 CV_SH3_IntSp
- L"???", // 26
- L"???", // 27
- L"???", // 28
- L"???", // 29
- L"???", // 30
- L"???", // 31
- L"???", // 32
- L"???", // 33
- L"???", // 34
- L"???", // 35
- L"???", // 36
- L"???", // 37
- L"gbr", // 38 CV_SH3_Gbr
- L"pr", // 39 CV_SH3_Pr
- L"mach", // 40 CV_SH3_Mach
- L"macl", // 41 CV_SH3_Macl
- L"???", // 42
- L"???", // 43
- L"???", // 44
- L"???", // 45
- L"???", // 46
- L"???", // 47
- L"???", // 48
- L"???", // 49
- L"pc", // 50
- L"sr", // 51
- L"???", // 52
- L"???", // 53
- L"???", // 54
- L"???", // 55
- L"???", // 56
- L"???", // 57
- L"???", // 58
- L"???", // 59
- L"bara", // 60 CV_SH3_BarA
- L"basra", // 61 CV_SH3_BasrA
- L"bamra", // 62 CV_SH3_BamrA
- L"bbra", // 63 CV_SH3_BbrA
- L"barb", // 64 CV_SH3_BarB
- L"basrb", // 65 CV_SH3_BasrB
- L"bamrb", // 66 CV_SH3_BamrB
- L"bbrb", // 67 CV_SH3_BbrB
- L"bdrb", // 68 CV_SH3_BdrB
- L"bdmrb", // 69 CV_SH3_BdmrB
- L"brcr" // 70 CV_SH3_Brcr
-};
-
-const wchar_t * const rgRegArm[] = {
- L"None", // 0 CV_ARM_NOREG
- L"???", // 1
- L"???", // 2
- L"???", // 3
- L"???", // 4
- L"???", // 5
- L"???", // 6
- L"???", // 7
- L"???", // 8
- L"???", // 9
- L"r0", // 10 CV_ARM_R0
- L"r1", // 11 CV_ARM_R1
- L"r2", // 12 CV_ARM_R2
- L"r3", // 13 CV_ARM_R3
- L"r4", // 14 CV_ARM_R4
- L"r5", // 15 CV_ARM_R5
- L"r6", // 16 CV_ARM_R6
- L"r7", // 17 CV_ARM_R7
- L"r8", // 18 CV_ARM_R8
- L"r9", // 19 CV_ARM_R9
- L"r10", // 20 CV_ARM_R10
- L"r11", // 21 CV_ARM_R11
- L"r12", // 22 CV_ARM_R12
- L"sp", // 23 CV_ARM_SP
- L"lr", // 24 CV_ARM_LR
- L"pc", // 25 CV_ARM_PC
- L"cpsr" // 26 CV_ARM_CPSR
-};
-
-const MapIa64Reg mpIa64regSz[] = {
- { CV_IA64_Br0, L"Br0" },
- { CV_IA64_Br1, L"Br1" },
- { CV_IA64_Br2, L"Br2" },
- { CV_IA64_Br3, L"Br3" },
- { CV_IA64_Br4, L"Br4" },
- { CV_IA64_Br5, L"Br5" },
- { CV_IA64_Br6, L"Br6" },
- { CV_IA64_Br7, L"Br7" },
- { CV_IA64_Preds, L"Preds" },
- { CV_IA64_IntH0, L"IntH0" },
- { CV_IA64_IntH1, L"IntH1" },
- { CV_IA64_IntH2, L"IntH2" },
- { CV_IA64_IntH3, L"IntH3" },
- { CV_IA64_IntH4, L"IntH4" },
- { CV_IA64_IntH5, L"IntH5" },
- { CV_IA64_IntH6, L"IntH6" },
- { CV_IA64_IntH7, L"IntH7" },
- { CV_IA64_IntH8, L"IntH8" },
- { CV_IA64_IntH9, L"IntH9" },
- { CV_IA64_IntH10, L"IntH10" },
- { CV_IA64_IntH11, L"IntH11" },
- { CV_IA64_IntH12, L"IntH12" },
- { CV_IA64_IntH13, L"IntH13" },
- { CV_IA64_IntH14, L"IntH14" },
- { CV_IA64_IntH15, L"IntH15" },
- { CV_IA64_Ip, L"Ip" },
- { CV_IA64_Umask, L"Umask" },
- { CV_IA64_Cfm, L"Cfm" },
- { CV_IA64_Psr, L"Psr" },
- { CV_IA64_Nats, L"Nats" },
- { CV_IA64_Nats2, L"Nats2" },
- { CV_IA64_Nats3, L"Nats3" },
- { CV_IA64_IntR0, L"IntR0" },
- { CV_IA64_IntR1, L"IntR1" },
- { CV_IA64_IntR2, L"IntR2" },
- { CV_IA64_IntR3, L"IntR3" },
- { CV_IA64_IntR4, L"IntR4" },
- { CV_IA64_IntR5, L"IntR5" },
- { CV_IA64_IntR6, L"IntR6" },
- { CV_IA64_IntR7, L"IntR7" },
- { CV_IA64_IntR8, L"IntR8" },
- { CV_IA64_IntR9, L"IntR9" },
- { CV_IA64_IntR10, L"IntR10" },
- { CV_IA64_IntR11, L"IntR11" },
- { CV_IA64_IntR12, L"IntR12" },
- { CV_IA64_IntR13, L"IntR13" },
- { CV_IA64_IntR14, L"IntR14" },
- { CV_IA64_IntR15, L"IntR15" },
- { CV_IA64_IntR16, L"IntR16" },
- { CV_IA64_IntR17, L"IntR17" },
- { CV_IA64_IntR18, L"IntR18" },
- { CV_IA64_IntR19, L"IntR19" },
- { CV_IA64_IntR20, L"IntR20" },
- { CV_IA64_IntR21, L"IntR21" },
- { CV_IA64_IntR22, L"IntR22" },
- { CV_IA64_IntR23, L"IntR23" },
- { CV_IA64_IntR24, L"IntR24" },
- { CV_IA64_IntR25, L"IntR25" },
- { CV_IA64_IntR26, L"IntR26" },
- { CV_IA64_IntR27, L"IntR27" },
- { CV_IA64_IntR28, L"IntR28" },
- { CV_IA64_IntR29, L"IntR29" },
- { CV_IA64_IntR30, L"IntR30" },
- { CV_IA64_IntR31, L"IntR31" },
- { CV_IA64_IntR32, L"IntR32" },
- { CV_IA64_IntR33, L"IntR33" },
- { CV_IA64_IntR34, L"IntR34" },
- { CV_IA64_IntR35, L"IntR35" },
- { CV_IA64_IntR36, L"IntR36" },
- { CV_IA64_IntR37, L"IntR37" },
- { CV_IA64_IntR38, L"IntR38" },
- { CV_IA64_IntR39, L"IntR39" },
- { CV_IA64_IntR40, L"IntR40" },
- { CV_IA64_IntR41, L"IntR41" },
- { CV_IA64_IntR42, L"IntR42" },
- { CV_IA64_IntR43, L"IntR43" },
- { CV_IA64_IntR44, L"IntR44" },
- { CV_IA64_IntR45, L"IntR45" },
- { CV_IA64_IntR46, L"IntR46" },
- { CV_IA64_IntR47, L"IntR47" },
- { CV_IA64_IntR48, L"IntR48" },
- { CV_IA64_IntR49, L"IntR49" },
- { CV_IA64_IntR50, L"IntR50" },
- { CV_IA64_IntR51, L"IntR51" },
- { CV_IA64_IntR52, L"IntR52" },
- { CV_IA64_IntR53, L"IntR53" },
- { CV_IA64_IntR54, L"IntR54" },
- { CV_IA64_IntR55, L"IntR55" },
- { CV_IA64_IntR56, L"IntR56" },
- { CV_IA64_IntR57, L"IntR57" },
- { CV_IA64_IntR58, L"IntR58" },
- { CV_IA64_IntR59, L"IntR59" },
- { CV_IA64_IntR60, L"IntR60" },
- { CV_IA64_IntR61, L"IntR61" },
- { CV_IA64_IntR62, L"IntR62" },
- { CV_IA64_IntR63, L"IntR63" },
- { CV_IA64_IntR64, L"IntR64" },
- { CV_IA64_IntR65, L"IntR65" },
- { CV_IA64_IntR66, L"IntR66" },
- { CV_IA64_IntR67, L"IntR67" },
- { CV_IA64_IntR68, L"IntR68" },
- { CV_IA64_IntR69, L"IntR69" },
- { CV_IA64_IntR70, L"IntR70" },
- { CV_IA64_IntR71, L"IntR71" },
- { CV_IA64_IntR72, L"IntR72" },
- { CV_IA64_IntR73, L"IntR73" },
- { CV_IA64_IntR74, L"IntR74" },
- { CV_IA64_IntR75, L"IntR75" },
- { CV_IA64_IntR76, L"IntR76" },
- { CV_IA64_IntR77, L"IntR77" },
- { CV_IA64_IntR78, L"IntR78" },
- { CV_IA64_IntR79, L"IntR79" },
- { CV_IA64_IntR80, L"IntR80" },
- { CV_IA64_IntR81, L"IntR81" },
- { CV_IA64_IntR82, L"IntR82" },
- { CV_IA64_IntR83, L"IntR83" },
- { CV_IA64_IntR84, L"IntR84" },
- { CV_IA64_IntR85, L"IntR85" },
- { CV_IA64_IntR86, L"IntR86" },
- { CV_IA64_IntR87, L"IntR87" },
- { CV_IA64_IntR88, L"IntR88" },
- { CV_IA64_IntR89, L"IntR89" },
- { CV_IA64_IntR90, L"IntR90" },
- { CV_IA64_IntR91, L"IntR91" },
- { CV_IA64_IntR92, L"IntR92" },
- { CV_IA64_IntR93, L"IntR93" },
- { CV_IA64_IntR94, L"IntR94" },
- { CV_IA64_IntR95, L"IntR95" },
- { CV_IA64_IntR96, L"IntR96" },
- { CV_IA64_IntR97, L"IntR97" },
- { CV_IA64_IntR98, L"IntR98" },
- { CV_IA64_IntR99, L"IntR99" },
- { CV_IA64_IntR100, L"IntR100" },
- { CV_IA64_IntR101, L"IntR101" },
- { CV_IA64_IntR102, L"IntR102" },
- { CV_IA64_IntR103, L"IntR103" },
- { CV_IA64_IntR104, L"IntR104" },
- { CV_IA64_IntR105, L"IntR105" },
- { CV_IA64_IntR106, L"IntR106" },
- { CV_IA64_IntR107, L"IntR107" },
- { CV_IA64_IntR108, L"IntR108" },
- { CV_IA64_IntR109, L"IntR109" },
- { CV_IA64_IntR110, L"IntR110" },
- { CV_IA64_IntR111, L"IntR111" },
- { CV_IA64_IntR112, L"IntR112" },
- { CV_IA64_IntR113, L"IntR113" },
- { CV_IA64_IntR114, L"IntR114" },
- { CV_IA64_IntR115, L"IntR115" },
- { CV_IA64_IntR116, L"IntR116" },
- { CV_IA64_IntR117, L"IntR117" },
- { CV_IA64_IntR118, L"IntR118" },
- { CV_IA64_IntR119, L"IntR119" },
- { CV_IA64_IntR120, L"IntR120" },
- { CV_IA64_IntR121, L"IntR121" },
- { CV_IA64_IntR122, L"IntR122" },
- { CV_IA64_IntR123, L"IntR123" },
- { CV_IA64_IntR124, L"IntR124" },
- { CV_IA64_IntR125, L"IntR125" },
- { CV_IA64_IntR126, L"IntR126" },
- { CV_IA64_IntR127, L"IntR127" },
- { CV_IA64_FltF0, L"FltF0" },
- { CV_IA64_FltF1, L"FltF1" },
- { CV_IA64_FltF2, L"FltF2" },
- { CV_IA64_FltF3, L"FltF3" },
- { CV_IA64_FltF4, L"FltF4" },
- { CV_IA64_FltF5, L"FltF5" },
- { CV_IA64_FltF6, L"FltF6" },
- { CV_IA64_FltF7, L"FltF7" },
- { CV_IA64_FltF8, L"FltF8" },
- { CV_IA64_FltF9, L"FltF9" },
- { CV_IA64_FltF10, L"FltF10" },
- { CV_IA64_FltF11, L"FltF11" },
- { CV_IA64_FltF12, L"FltF12" },
- { CV_IA64_FltF13, L"FltF13" },
- { CV_IA64_FltF14, L"FltF14" },
- { CV_IA64_FltF15, L"FltF15" },
- { CV_IA64_FltF16, L"FltF16" },
- { CV_IA64_FltF17, L"FltF17" },
- { CV_IA64_FltF18, L"FltF18" },
- { CV_IA64_FltF19, L"FltF19" },
- { CV_IA64_FltF20, L"FltF20" },
- { CV_IA64_FltF21, L"FltF21" },
- { CV_IA64_FltF22, L"FltF22" },
- { CV_IA64_FltF23, L"FltF23" },
- { CV_IA64_FltF24, L"FltF24" },
- { CV_IA64_FltF25, L"FltF25" },
- { CV_IA64_FltF26, L"FltF26" },
- { CV_IA64_FltF27, L"FltF27" },
- { CV_IA64_FltF28, L"FltF28" },
- { CV_IA64_FltF29, L"FltF29" },
- { CV_IA64_FltF30, L"FltF30" },
- { CV_IA64_FltF31, L"FltF31" },
- { CV_IA64_FltF32, L"FltF32" },
- { CV_IA64_FltF33, L"FltF33" },
- { CV_IA64_FltF34, L"FltF34" },
- { CV_IA64_FltF35, L"FltF35" },
- { CV_IA64_FltF36, L"FltF36" },
- { CV_IA64_FltF37, L"FltF37" },
- { CV_IA64_FltF38, L"FltF38" },
- { CV_IA64_FltF39, L"FltF39" },
- { CV_IA64_FltF40, L"FltF40" },
- { CV_IA64_FltF41, L"FltF41" },
- { CV_IA64_FltF42, L"FltF42" },
- { CV_IA64_FltF43, L"FltF43" },
- { CV_IA64_FltF44, L"FltF44" },
- { CV_IA64_FltF45, L"FltF45" },
- { CV_IA64_FltF46, L"FltF46" },
- { CV_IA64_FltF47, L"FltF47" },
- { CV_IA64_FltF48, L"FltF48" },
- { CV_IA64_FltF49, L"FltF49" },
- { CV_IA64_FltF50, L"FltF50" },
- { CV_IA64_FltF51, L"FltF51" },
- { CV_IA64_FltF52, L"FltF52" },
- { CV_IA64_FltF53, L"FltF53" },
- { CV_IA64_FltF54, L"FltF54" },
- { CV_IA64_FltF55, L"FltF55" },
- { CV_IA64_FltF56, L"FltF56" },
- { CV_IA64_FltF57, L"FltF57" },
- { CV_IA64_FltF58, L"FltF58" },
- { CV_IA64_FltF59, L"FltF59" },
- { CV_IA64_FltF60, L"FltF60" },
- { CV_IA64_FltF61, L"FltF61" },
- { CV_IA64_FltF62, L"FltF62" },
- { CV_IA64_FltF63, L"FltF63" },
- { CV_IA64_FltF64, L"FltF64" },
- { CV_IA64_FltF65, L"FltF65" },
- { CV_IA64_FltF66, L"FltF66" },
- { CV_IA64_FltF67, L"FltF67" },
- { CV_IA64_FltF68, L"FltF68" },
- { CV_IA64_FltF69, L"FltF69" },
- { CV_IA64_FltF70, L"FltF70" },
- { CV_IA64_FltF71, L"FltF71" },
- { CV_IA64_FltF72, L"FltF72" },
- { CV_IA64_FltF73, L"FltF73" },
- { CV_IA64_FltF74, L"FltF74" },
- { CV_IA64_FltF75, L"FltF75" },
- { CV_IA64_FltF76, L"FltF76" },
- { CV_IA64_FltF77, L"FltF77" },
- { CV_IA64_FltF78, L"FltF78" },
- { CV_IA64_FltF79, L"FltF79" },
- { CV_IA64_FltF80, L"FltF80" },
- { CV_IA64_FltF81, L"FltF81" },
- { CV_IA64_FltF82, L"FltF82" },
- { CV_IA64_FltF83, L"FltF83" },
- { CV_IA64_FltF84, L"FltF84" },
- { CV_IA64_FltF85, L"FltF85" },
- { CV_IA64_FltF86, L"FltF86" },
- { CV_IA64_FltF87, L"FltF87" },
- { CV_IA64_FltF88, L"FltF88" },
- { CV_IA64_FltF89, L"FltF89" },
- { CV_IA64_FltF90, L"FltF90" },
- { CV_IA64_FltF91, L"FltF91" },
- { CV_IA64_FltF92, L"FltF92" },
- { CV_IA64_FltF93, L"FltF93" },
- { CV_IA64_FltF94, L"FltF94" },
- { CV_IA64_FltF95, L"FltF95" },
- { CV_IA64_FltF96, L"FltF96" },
- { CV_IA64_FltF97, L"FltF97" },
- { CV_IA64_FltF98, L"FltF98" },
- { CV_IA64_FltF99, L"FltF99" },
- { CV_IA64_FltF100, L"FltF100" },
- { CV_IA64_FltF101, L"FltF101" },
- { CV_IA64_FltF102, L"FltF102" },
- { CV_IA64_FltF103, L"FltF103" },
- { CV_IA64_FltF104, L"FltF104" },
- { CV_IA64_FltF105, L"FltF105" },
- { CV_IA64_FltF106, L"FltF106" },
- { CV_IA64_FltF107, L"FltF107" },
- { CV_IA64_FltF108, L"FltF108" },
- { CV_IA64_FltF109, L"FltF109" },
- { CV_IA64_FltF110, L"FltF110" },
- { CV_IA64_FltF111, L"FltF111" },
- { CV_IA64_FltF112, L"FltF112" },
- { CV_IA64_FltF113, L"FltF113" },
- { CV_IA64_FltF114, L"FltF114" },
- { CV_IA64_FltF115, L"FltF115" },
- { CV_IA64_FltF116, L"FltF116" },
- { CV_IA64_FltF117, L"FltF117" },
- { CV_IA64_FltF118, L"FltF118" },
- { CV_IA64_FltF119, L"FltF119" },
- { CV_IA64_FltF120, L"FltF120" },
- { CV_IA64_FltF121, L"FltF121" },
- { CV_IA64_FltF122, L"FltF122" },
- { CV_IA64_FltF123, L"FltF123" },
- { CV_IA64_FltF124, L"FltF124" },
- { CV_IA64_FltF125, L"FltF125" },
- { CV_IA64_FltF126, L"FltF126" },
- { CV_IA64_FltF127, L"FltF127" },
- { CV_IA64_ApKR0, L"ApKR0" },
- { CV_IA64_ApKR1, L"ApKR1" },
- { CV_IA64_ApKR2, L"ApKR2" },
- { CV_IA64_ApKR3, L"ApKR3" },
- { CV_IA64_ApKR4, L"ApKR4" },
- { CV_IA64_ApKR5, L"ApKR5" },
- { CV_IA64_ApKR6, L"ApKR6" },
- { CV_IA64_ApKR7, L"ApKR7" },
- { CV_IA64_AR8, L"AR8" },
- { CV_IA64_AR9, L"AR9" },
- { CV_IA64_AR10, L"AR10" },
- { CV_IA64_AR11, L"AR11" },
- { CV_IA64_AR12, L"AR12" },
- { CV_IA64_AR13, L"AR13" },
- { CV_IA64_AR14, L"AR14" },
- { CV_IA64_AR15, L"AR15" },
- { CV_IA64_RsRSC, L"RsRSC" },
- { CV_IA64_RsBSP, L"RsBSP" },
- { CV_IA64_RsBSPSTORE, L"RsBSPSTORE" },
- { CV_IA64_RsRNAT, L"RsRNAT" },
- { CV_IA64_AR20, L"AR20" },
- { CV_IA64_StFCR, L"StFCR" },
- { CV_IA64_AR22, L"AR22" },
- { CV_IA64_AR23, L"AR23" },
- { CV_IA64_EFLAG, L"EFLAG" },
- { CV_IA64_CSD, L"CSD" },
- { CV_IA64_SSD, L"SSD" },
- { CV_IA64_CFLG, L"CFLG" },
- { CV_IA64_StFSR, L"StFSR" },
- { CV_IA64_StFIR, L"StFIR" },
- { CV_IA64_StFDR, L"StFDR" },
- { CV_IA64_AR31, L"AR31" },
- { CV_IA64_ApCCV, L"ApCCV" },
- { CV_IA64_AR33, L"AR33" },
- { CV_IA64_AR34, L"AR34" },
- { CV_IA64_AR35, L"AR35" },
- { CV_IA64_ApUNAT, L"ApUNAT" },
- { CV_IA64_AR37, L"AR37" },
- { CV_IA64_AR38, L"AR38" },
- { CV_IA64_AR39, L"AR39" },
- { CV_IA64_StFPSR, L"StFPSR" },
- { CV_IA64_AR41, L"AR41" },
- { CV_IA64_AR42, L"AR42" },
- { CV_IA64_AR43, L"AR43" },
- { CV_IA64_ApITC, L"ApITC" },
- { CV_IA64_AR45, L"AR45" },
- { CV_IA64_AR46, L"AR46" },
- { CV_IA64_AR47, L"AR47" },
- { CV_IA64_AR48, L"AR48" },
- { CV_IA64_AR49, L"AR49" },
- { CV_IA64_AR50, L"AR50" },
- { CV_IA64_AR51, L"AR51" },
- { CV_IA64_AR52, L"AR52" },
- { CV_IA64_AR53, L"AR53" },
- { CV_IA64_AR54, L"AR54" },
- { CV_IA64_AR55, L"AR55" },
- { CV_IA64_AR56, L"AR56" },
- { CV_IA64_AR57, L"AR57" },
- { CV_IA64_AR58, L"AR58" },
- { CV_IA64_AR59, L"AR59" },
- { CV_IA64_AR60, L"AR60" },
- { CV_IA64_AR61, L"AR61" },
- { CV_IA64_AR62, L"AR62" },
- { CV_IA64_AR63, L"AR63" },
- { CV_IA64_RsPFS, L"RsPFS" },
- { CV_IA64_ApLC, L"ApLC" },
- { CV_IA64_ApEC, L"ApEC" },
- { CV_IA64_AR67, L"AR67" },
- { CV_IA64_AR68, L"AR68" },
- { CV_IA64_AR69, L"AR69" },
- { CV_IA64_AR70, L"AR70" },
- { CV_IA64_AR71, L"AR71" },
- { CV_IA64_AR72, L"AR72" },
- { CV_IA64_AR73, L"AR73" },
- { CV_IA64_AR74, L"AR74" },
- { CV_IA64_AR75, L"AR75" },
- { CV_IA64_AR76, L"AR76" },
- { CV_IA64_AR77, L"AR77" },
- { CV_IA64_AR78, L"AR78" },
- { CV_IA64_AR79, L"AR79" },
- { CV_IA64_AR80, L"AR80" },
- { CV_IA64_AR81, L"AR81" },
- { CV_IA64_AR82, L"AR82" },
- { CV_IA64_AR83, L"AR83" },
- { CV_IA64_AR84, L"AR84" },
- { CV_IA64_AR85, L"AR85" },
- { CV_IA64_AR86, L"AR86" },
- { CV_IA64_AR87, L"AR87" },
- { CV_IA64_AR88, L"AR88" },
- { CV_IA64_AR89, L"AR89" },
- { CV_IA64_AR90, L"AR90" },
- { CV_IA64_AR91, L"AR91" },
- { CV_IA64_AR92, L"AR92" },
- { CV_IA64_AR93, L"AR93" },
- { CV_IA64_AR94, L"AR94" },
- { CV_IA64_AR95, L"AR95" },
- { CV_IA64_AR96, L"AR96" },
- { CV_IA64_AR97, L"AR97" },
- { CV_IA64_AR98, L"AR98" },
- { CV_IA64_AR99, L"AR99" },
- { CV_IA64_AR100, L"AR100" },
- { CV_IA64_AR101, L"AR101" },
- { CV_IA64_AR102, L"AR102" },
- { CV_IA64_AR103, L"AR103" },
- { CV_IA64_AR104, L"AR104" },
- { CV_IA64_AR105, L"AR105" },
- { CV_IA64_AR106, L"AR106" },
- { CV_IA64_AR107, L"AR107" },
- { CV_IA64_AR108, L"AR108" },
- { CV_IA64_AR109, L"AR109" },
- { CV_IA64_AR110, L"AR110" },
- { CV_IA64_AR111, L"AR111" },
- { CV_IA64_AR112, L"AR112" },
- { CV_IA64_AR113, L"AR113" },
- { CV_IA64_AR114, L"AR114" },
- { CV_IA64_AR115, L"AR115" },
- { CV_IA64_AR116, L"AR116" },
- { CV_IA64_AR117, L"AR117" },
- { CV_IA64_AR118, L"AR118" },
- { CV_IA64_AR119, L"AR119" },
- { CV_IA64_AR120, L"AR120" },
- { CV_IA64_AR121, L"AR121" },
- { CV_IA64_AR122, L"AR122" },
- { CV_IA64_AR123, L"AR123" },
- { CV_IA64_AR124, L"AR124" },
- { CV_IA64_AR125, L"AR125" },
- { CV_IA64_AR126, L"AR126" },
- { CV_IA64_AR127, L"AR127" },
- { CV_IA64_ApDCR, L"ApDCR" },
- { CV_IA64_ApITM, L"ApITM" },
- { CV_IA64_ApIVA, L"ApIVA" },
- { CV_IA64_CR3, L"CR3" },
- { CV_IA64_CR4, L"CR4" },
- { CV_IA64_CR5, L"CR5" },
- { CV_IA64_CR6, L"CR6" },
- { CV_IA64_CR7, L"CR7" },
- { CV_IA64_ApPTA, L"ApPTA" },
- { CV_IA64_ApGPTA, L"ApGPTA" },
- { CV_IA64_CR10, L"CR10" },
- { CV_IA64_CR11, L"CR11" },
- { CV_IA64_CR12, L"CR12" },
- { CV_IA64_CR13, L"CR13" },
- { CV_IA64_CR14, L"CR14" },
- { CV_IA64_CR15, L"CR15" },
- { CV_IA64_StIPSR, L"StIPSR" },
- { CV_IA64_StISR, L"StISR" },
- { CV_IA64_CR18, L"CR18" },
- { CV_IA64_StIIP, L"StIIP" },
- { CV_IA64_StIFA, L"StIFA" },
- { CV_IA64_StITIR, L"StITIR" },
- { CV_IA64_StIIPA, L"StIIPA" },
- { CV_IA64_StIFS, L"StIFS" },
- { CV_IA64_StIIM, L"StIIM" },
- { CV_IA64_StIHA, L"StIHA" },
- { CV_IA64_CR26, L"CR26" },
- { CV_IA64_CR27, L"CR27" },
- { CV_IA64_CR28, L"CR28" },
- { CV_IA64_CR29, L"CR29" },
- { CV_IA64_CR30, L"CR30" },
- { CV_IA64_CR31, L"CR31" },
- { CV_IA64_CR32, L"CR32" },
- { CV_IA64_CR33, L"CR33" },
- { CV_IA64_CR34, L"CR34" },
- { CV_IA64_CR35, L"CR35" },
- { CV_IA64_CR36, L"CR36" },
- { CV_IA64_CR37, L"CR37" },
- { CV_IA64_CR38, L"CR38" },
- { CV_IA64_CR39, L"CR39" },
- { CV_IA64_CR40, L"CR40" },
- { CV_IA64_CR41, L"CR41" },
- { CV_IA64_CR42, L"CR42" },
- { CV_IA64_CR43, L"CR43" },
- { CV_IA64_CR44, L"CR44" },
- { CV_IA64_CR45, L"CR45" },
- { CV_IA64_CR46, L"CR46" },
- { CV_IA64_CR47, L"CR47" },
- { CV_IA64_CR48, L"CR48" },
- { CV_IA64_CR49, L"CR49" },
- { CV_IA64_CR50, L"CR50" },
- { CV_IA64_CR51, L"CR51" },
- { CV_IA64_CR52, L"CR52" },
- { CV_IA64_CR53, L"CR53" },
- { CV_IA64_CR54, L"CR54" },
- { CV_IA64_CR55, L"CR55" },
- { CV_IA64_CR56, L"CR56" },
- { CV_IA64_CR57, L"CR57" },
- { CV_IA64_CR58, L"CR58" },
- { CV_IA64_CR59, L"CR59" },
- { CV_IA64_CR60, L"CR60" },
- { CV_IA64_CR61, L"CR61" },
- { CV_IA64_CR62, L"CR62" },
- { CV_IA64_CR63, L"CR63" },
- { CV_IA64_SaLID, L"SaLID" },
- { CV_IA64_SaIVR, L"SaIVR" },
- { CV_IA64_SaTPR, L"SaTPR" },
- { CV_IA64_SaEOI, L"SaEOI" },
- { CV_IA64_SaIRR0, L"SaIRR0" },
- { CV_IA64_SaIRR1, L"SaIRR1" },
- { CV_IA64_SaIRR2, L"SaIRR2" },
- { CV_IA64_SaIRR3, L"SaIRR3" },
- { CV_IA64_SaITV, L"SaITV" },
- { CV_IA64_SaPMV, L"SaPMV" },
- { CV_IA64_SaCMCV, L"SaCMCV" },
- { CV_IA64_CR75, L"CR75" },
- { CV_IA64_CR76, L"CR76" },
- { CV_IA64_CR77, L"CR77" },
- { CV_IA64_CR78, L"CR78" },
- { CV_IA64_CR79, L"CR79" },
- { CV_IA64_SaLRR0, L"SaLRR0" },
- { CV_IA64_SaLRR1, L"SaLRR1" },
- { CV_IA64_CR82, L"CR82" },
- { CV_IA64_CR83, L"CR83" },
- { CV_IA64_CR84, L"CR84" },
- { CV_IA64_CR85, L"CR85" },
- { CV_IA64_CR86, L"CR86" },
- { CV_IA64_CR87, L"CR87" },
- { CV_IA64_CR88, L"CR88" },
- { CV_IA64_CR89, L"CR89" },
- { CV_IA64_CR90, L"CR90" },
- { CV_IA64_CR91, L"CR91" },
- { CV_IA64_CR92, L"CR92" },
- { CV_IA64_CR93, L"CR93" },
- { CV_IA64_CR94, L"CR94" },
- { CV_IA64_CR95, L"CR95" },
- { CV_IA64_SaIRR0, L"SaIRR0" },
- { CV_IA64_CR97, L"CR97" },
- { CV_IA64_SaIRR1, L"SaIRR1" },
- { CV_IA64_CR99, L"CR99" },
- { CV_IA64_SaIRR2, L"SaIRR2" },
- { CV_IA64_CR101, L"CR101" },
- { CV_IA64_SaIRR3, L"SaIRR3" },
- { CV_IA64_CR103, L"CR103" },
- { CV_IA64_CR104, L"CR104" },
- { CV_IA64_CR105, L"CR105" },
- { CV_IA64_CR106, L"CR106" },
- { CV_IA64_CR107, L"CR107" },
- { CV_IA64_CR108, L"CR108" },
- { CV_IA64_CR109, L"CR109" },
- { CV_IA64_CR110, L"CR110" },
- { CV_IA64_CR111, L"CR111" },
- { CV_IA64_CR112, L"CR112" },
- { CV_IA64_CR113, L"CR113" },
- { CV_IA64_SaITV, L"SaITV" },
- { CV_IA64_CR115, L"CR115" },
- { CV_IA64_SaPMV, L"SaPMV" },
- { CV_IA64_SaLRR0, L"SaLRR0" },
- { CV_IA64_SaLRR1, L"SaLRR1" },
- { CV_IA64_SaCMCV, L"SaCMCV" },
- { CV_IA64_CR120, L"CR120" },
- { CV_IA64_CR121, L"CR121" },
- { CV_IA64_CR122, L"CR122" },
- { CV_IA64_CR123, L"CR123" },
- { CV_IA64_CR124, L"CR124" },
- { CV_IA64_CR125, L"CR125" },
- { CV_IA64_CR126, L"CR126" },
- { CV_IA64_CR127, L"CR127" },
- { CV_IA64_Pkr0, L"Pkr0" },
- { CV_IA64_Pkr1, L"Pkr1" },
- { CV_IA64_Pkr2, L"Pkr2" },
- { CV_IA64_Pkr3, L"Pkr3" },
- { CV_IA64_Pkr4, L"Pkr4" },
- { CV_IA64_Pkr5, L"Pkr5" },
- { CV_IA64_Pkr6, L"Pkr6" },
- { CV_IA64_Pkr7, L"Pkr7" },
- { CV_IA64_Pkr8, L"Pkr8" },
- { CV_IA64_Pkr9, L"Pkr9" },
- { CV_IA64_Pkr10, L"Pkr10" },
- { CV_IA64_Pkr11, L"Pkr11" },
- { CV_IA64_Pkr12, L"Pkr12" },
- { CV_IA64_Pkr13, L"Pkr13" },
- { CV_IA64_Pkr14, L"Pkr14" },
- { CV_IA64_Pkr15, L"Pkr15" },
- { CV_IA64_Rr0, L"Rr0" },
- { CV_IA64_Rr1, L"Rr1" },
- { CV_IA64_Rr2, L"Rr2" },
- { CV_IA64_Rr3, L"Rr3" },
- { CV_IA64_Rr4, L"Rr4" },
- { CV_IA64_Rr5, L"Rr5" },
- { CV_IA64_Rr6, L"Rr6" },
- { CV_IA64_Rr7, L"Rr7" },
- { CV_IA64_PFD0, L"PFD0" },
- { CV_IA64_PFD1, L"PFD1" },
- { CV_IA64_PFD2, L"PFD2" },
- { CV_IA64_PFD3, L"PFD3" },
- { CV_IA64_PFD4, L"PFD4" },
- { CV_IA64_PFD5, L"PFD5" },
- { CV_IA64_PFD6, L"PFD6" },
- { CV_IA64_PFD7, L"PFD7" },
- { CV_IA64_PFC0, L"PFC0" },
- { CV_IA64_PFC1, L"PFC1" },
- { CV_IA64_PFC2, L"PFC2" },
- { CV_IA64_PFC3, L"PFC3" },
- { CV_IA64_PFC4, L"PFC4" },
- { CV_IA64_PFC5, L"PFC5" },
- { CV_IA64_PFC6, L"PFC6" },
- { CV_IA64_PFC7, L"PFC7" },
- { CV_IA64_TrI0, L"TrI0" },
- { CV_IA64_TrI1, L"TrI1" },
- { CV_IA64_TrI2, L"TrI2" },
- { CV_IA64_TrI3, L"TrI3" },
- { CV_IA64_TrI4, L"TrI4" },
- { CV_IA64_TrI5, L"TrI5" },
- { CV_IA64_TrI6, L"TrI6" },
- { CV_IA64_TrI7, L"TrI7" },
- { CV_IA64_TrD0, L"TrD0" },
- { CV_IA64_TrD1, L"TrD1" },
- { CV_IA64_TrD2, L"TrD2" },
- { CV_IA64_TrD3, L"TrD3" },
- { CV_IA64_TrD4, L"TrD4" },
- { CV_IA64_TrD5, L"TrD5" },
- { CV_IA64_TrD6, L"TrD6" },
- { CV_IA64_TrD7, L"TrD7" },
- { CV_IA64_DbI0, L"DbI0" },
- { CV_IA64_DbI1, L"DbI1" },
- { CV_IA64_DbI2, L"DbI2" },
- { CV_IA64_DbI3, L"DbI3" },
- { CV_IA64_DbI4, L"DbI4" },
- { CV_IA64_DbI5, L"DbI5" },
- { CV_IA64_DbI6, L"DbI6" },
- { CV_IA64_DbI7, L"DbI7" },
- { CV_IA64_DbD0, L"DbD0" },
- { CV_IA64_DbD1, L"DbD1" },
- { CV_IA64_DbD2, L"DbD2" },
- { CV_IA64_DbD3, L"DbD3" },
- { CV_IA64_DbD4, L"DbD4" },
- { CV_IA64_DbD5, L"DbD5" },
- { CV_IA64_DbD6, L"DbD6" },
- { CV_IA64_DbD7, L"DbD7" }
-};
-
-////////////////////////////////////////////////////////////
-// Map an IA64 registry ID with the corresponding string name
-//
-int __cdecl cmpIa64regSz(const void *pv1, const void *pv2) {
- const MapIa64Reg *p1 = (MapIa64Reg *) pv1;
- const MapIa64Reg *p2 = (MapIa64Reg *) pv2;
-
- if(p1->iCvReg < p2->iCvReg){
- return -1;
- }
- if(p1->iCvReg > p2->iCvReg){
- return 1;
- }
- return 0;
-}
-
-////////////////////////////////////////////////////////////
-// Map a registry id code with the corresponding string name
-//
-const wchar_t* SzNameC7Reg(USHORT reg, DWORD MachineType){
- static wchar_t wszRegNum[64];
-
- switch(reg){
- case CV_ALLREG_LOCALS : return L"BaseOfLocals";
- case CV_ALLREG_PARAMS : return L"BaseOfParams";
- case CV_ALLREG_VFRAME : return L"VFrame";
- }
- swprintf_s(wszRegNum, L"???(0x%x)", reg);
- switch(MachineType) {
- case CV_CFL_8080:
- case CV_CFL_8086:
- case CV_CFL_80286:
- case CV_CFL_80386:
- case CV_CFL_80486:
- case CV_CFL_PENTIUM:
- if(reg < (sizeof(rgRegX86)/sizeof(*rgRegX86))){
- return(rgRegX86[reg]);
- }
- return wszRegNum;
- break;
- case CV_CFL_ALPHA:
- if(reg < (sizeof(rgRegAlpha)/sizeof(*rgRegAlpha))){
- return(rgRegAlpha[reg]);
- }
- return wszRegNum;
- break;
- case CV_CFL_MIPSR4000:
- case CV_CFL_MIPS16:
- if(reg < (sizeof(rgRegMips)/sizeof(*rgRegMips))) {
- return(rgRegMips[reg]);
- }
- return wszRegNum;
- break;
- case CV_CFL_M68000:
- case CV_CFL_M68010:
- case CV_CFL_M68020:
- case CV_CFL_M68030:
- case CV_CFL_M68040:
- if(reg < (sizeof(rgReg68k)/sizeof(*rgReg68k))){
- return(rgReg68k[reg]);
- }
- return wszRegNum;
- break;
- case CV_CFL_PPC601:
- case CV_CFL_PPC603:
- case CV_CFL_PPC604:
- case CV_CFL_PPC620:
- if(reg < (sizeof(rgRegPpc)/sizeof(*rgRegPpc))){
- return(rgRegPpc[reg]);
- }
- return wszRegNum;
- break;
- case CV_CFL_SH3:
- if(reg < (sizeof(rgRegSh)/sizeof(*rgRegSh))){
- return(rgRegSh[reg]);
- }
- return wszRegNum;
- break;
- case CV_CFL_ARM3:
- case CV_CFL_ARM4:
- case CV_CFL_ARM4T:
- if(reg < (sizeof(rgRegArm)/sizeof(*rgRegArm))){
- return(rgRegArm[reg]);
- }
- return wszRegNum;
- break;
- case CV_CFL_IA64: {
- MapIa64Reg *p;
- MapIa64Reg m = {(CV_HREG_e) reg};
- p = (MapIa64Reg *) bsearch(&m,
- mpIa64regSz,
- sizeof(mpIa64regSz)/sizeof(*mpIa64regSz),
- sizeof(MapIa64Reg),
- cmpIa64regSz);
- if (p) {
- return p->wszRegName;
- }else{
- return wszRegNum;
- }
- break;
- }
- case CV_CFL_AMD64 :
- if (reg < sizeof(rgRegAMD64)/sizeof(*rgRegAMD64)) {
- return rgRegAMD64[reg];
- }else{
- return wszRegNum;
- }
- break;
- default:
- return wszRegNum;
- break;
- }
-}
-
-const wchar_t* SzNameC7Reg(USHORT reg){
- return SzNameC7Reg(reg, g_dwMachineType);
-}
-
diff --git a/src/ToolBox/PdbTypeMatch/regs.h b/src/ToolBox/PdbTypeMatch/regs.h
deleted file mode 100644
index 946d5b8f49..0000000000
--- a/src/ToolBox/PdbTypeMatch/regs.h
+++ /dev/null
@@ -1,23 +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.
-
-extern const wchar_t * const rgRegX86[];
-extern const wchar_t * const rgRegAMD64[];
-extern const wchar_t * const rgRegMips[];
-extern const wchar_t * const rgReg68k[];
-extern const wchar_t * const rgRegAlpha[];
-extern const wchar_t * const rgRegPpc[];
-extern const wchar_t * const rgRegSh[];
-extern const wchar_t * const rgRegArm[];
-
-typedef struct MapIa64Reg{
- CV_HREG_e iCvReg;
- const wchar_t* wszRegName;
-}MapIa64Reg;
-extern const MapIa64Reg mpIa64regSz[];
-int __cdecl cmpIa64regSz( const void* , const void* );
-
-extern DWORD g_dwMachineType;
-const wchar_t* SzNameC7Reg( USHORT , DWORD );
-const wchar_t* SzNameC7Reg( USHORT );
diff --git a/src/ToolBox/PdbTypeMatch/stdafx.cpp b/src/ToolBox/PdbTypeMatch/stdafx.cpp
deleted file mode 100644
index f6da4386ea..0000000000
--- a/src/ToolBox/PdbTypeMatch/stdafx.cpp
+++ /dev/null
@@ -1,9 +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.
-// stdafx.obj will contain the pre-compiled type information
-
-#include "stdafx.h"
-
-// TODO: reference any additional headers you need in STDAFX.H
-// and not in this file
diff --git a/src/ToolBox/PdbTypeMatch/stdafx.h b/src/ToolBox/PdbTypeMatch/stdafx.h
deleted file mode 100644
index 7d1423147d..0000000000
--- a/src/ToolBox/PdbTypeMatch/stdafx.h
+++ /dev/null
@@ -1,25 +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.
-// stdafx.h : include file for standard system include files,
-// or project specific include files that are used frequently, but
-// are changed infrequently
-//
-
-#pragma once
-
-
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
-#endif
-
-#include <stdio.h>
-#include <tchar.h>
-#include <string.h>
-#include <comdef.h>
-
-#define _WIN32_FUSION 0x0100 // this causes activation context
-
-// TODO: reference additional headers your program requires here
-#include "dia2.h"
-
diff --git a/src/ToolBox/SOS/NETCore/SOS.NETCore.csproj b/src/ToolBox/SOS/NETCore/SOS.NETCore.csproj
index bd9d2395f8..440cff5d82 100644
--- a/src/ToolBox/SOS/NETCore/SOS.NETCore.csproj
+++ b/src/ToolBox/SOS/NETCore/SOS.NETCore.csproj
@@ -12,6 +12,12 @@
<NoStdLib>true</NoStdLib>
<NoCompilerStandardLib>true</NoCompilerStandardLib>
<UseOpenKey Condition="'$(UseOpenKey)'==''">true</UseOpenKey>
+
+ <!-- We don't use any of MSBuild's resolution logic for resolving the framework, so just set these two properties to any folder that exists to skip
+ the GenerateReferenceAssemblyPaths task (not target) and to prevent it from outputting a warning (MSB3644). -->
+ <_TargetFrameworkDirectories>$(MSBuildThisFileDirectory)/Documentation</_TargetFrameworkDirectories>
+ <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory)/Documentation</_FullFrameworkReferenceAssemblyPaths>
+
</PropertyGroup>
<!-- Default configurations to help VS understand the options -->
@@ -26,8 +32,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(OsEnvironment)' == 'Unix'">
- <DebugSymbols>false</DebugSymbols>
- <DebugType>none</DebugType>
+ <DebugType>portable</DebugType>
</PropertyGroup>
<ItemGroup>
@@ -48,7 +53,6 @@
</Copy>
<Copy
- Condition="'$(OsEnvironment)' != 'Unix'"
SourceFiles="$(OutputPath)$(AssemblyName).pdb"
DestinationFolder="$(BinDir)\PDB"
SkipUnchangedFiles="false"
diff --git a/src/ToolBox/SOS/NETCore/SymbolReader.cs b/src/ToolBox/SOS/NETCore/SymbolReader.cs
index 492f7cbd1f..e0fcdb517d 100644
--- a/src/ToolBox/SOS/NETCore/SymbolReader.cs
+++ b/src/ToolBox/SOS/NETCore/SymbolReader.cs
@@ -23,6 +23,14 @@ namespace SOS
public string fileName;
}
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ internal struct LocalVarInfo
+ {
+ public int startOffset;
+ public int endOffset;
+ public string name;
+ }
+
[StructLayout(LayoutKind.Sequential)]
internal struct MethodDebugInfo
{
@@ -296,6 +304,9 @@ namespace SOS
return false;
MethodDebugInformationHandle methodDebugHandle = ((MethodDefinitionHandle)handle).ToDebugInformationHandle();
+ if (methodDebugHandle.IsNil)
+ return false;
+
MethodDebugInformation methodDebugInfo = reader.GetMethodDebugInformation(methodDebugHandle);
SequencePointCollection sequencePoints = methodDebugInfo.GetSequencePoints();
@@ -394,7 +405,7 @@ namespace SOS
}
return false;
}
- internal static bool GetLocalsInfoForMethod(string assemblyPath, int methodToken, out List<string> locals)
+ internal static bool GetLocalsInfoForMethod(string assemblyPath, int methodToken, out List<LocalVarInfo> locals)
{
locals = null;
@@ -410,7 +421,7 @@ namespace SOS
if (handle.Kind != HandleKind.MethodDefinition)
return false;
- locals = new List<string>();
+ locals = new List<LocalVarInfo>();
MethodDebugInformationHandle methodDebugHandle =
((MethodDefinitionHandle)handle).ToDebugInformationHandle();
@@ -424,7 +435,11 @@ namespace SOS
LocalVariable localVar = openedReader.Reader.GetLocalVariable(varHandle);
if (localVar.Attributes == LocalVariableAttributes.DebuggerHidden)
continue;
- locals.Add(openedReader.Reader.GetString(localVar.Name));
+ LocalVarInfo info = new LocalVarInfo();
+ info.startOffset = scope.StartOffset;
+ info.endOffset = scope.EndOffset;
+ info.name = openedReader.Reader.GetString(localVar.Name);
+ locals.Add(info);
}
}
}
@@ -449,7 +464,7 @@ namespace SOS
try
{
List<DebugInfo> points = null;
- List<string> locals = null;
+ List<LocalVarInfo> locals = null;
if (!GetDebugInfoForMethod(assemblyPath, methodToken, out points))
{
@@ -470,14 +485,18 @@ namespace SOS
Marshal.StructureToPtr(info, ptr, false);
ptr = (IntPtr)(ptr.ToInt64() + structSize);
}
+
+ structSize = Marshal.SizeOf<LocalVarInfo>();
+
debugInfo.localsSize = locals.Count;
- debugInfo.locals = Marshal.AllocHGlobal(debugInfo.localsSize * Marshal.SizeOf<IntPtr>());
- IntPtr ptrLocals = debugInfo.locals;
- foreach (string s in locals)
+ ptr = debugInfo.locals;
+
+ foreach (var info in locals)
{
- Marshal.WriteIntPtr(ptrLocals, Marshal.StringToHGlobalUni(s));
- ptrLocals += Marshal.SizeOf<IntPtr>();
+ Marshal.StructureToPtr(info, ptr, false);
+ ptr = (IntPtr)(ptr.ToInt64() + structSize);
}
+
return true;
}
catch
diff --git a/src/ToolBox/SOS/NETCore/project.json b/src/ToolBox/SOS/NETCore/project.json
index 7a3cf4fe1d..6b2061a577 100644
--- a/src/ToolBox/SOS/NETCore/project.json
+++ b/src/ToolBox/SOS/NETCore/project.json
@@ -6,7 +6,11 @@
"System.Reflection.Metadata": "1.4.1"
},
"frameworks": {
- "netcoreapp1.0": {}
+ "netcoreapp1.0": {
+ "imports": [
+ "portable-net45+win8"
+ ]
+ }
},
"runtimes": {
"win7-x86": {},
diff --git a/src/ToolBox/SOS/Strike/disasm.h b/src/ToolBox/SOS/Strike/disasm.h
index 59fc168a6e..2a2d9f7779 100644
--- a/src/ToolBox/SOS/Strike/disasm.h
+++ b/src/ToolBox/SOS/Strike/disasm.h
@@ -54,9 +54,6 @@ LPCWSTR EHTypedClauseTypeName(const DACEHInfo* pEHInfo);
struct SOSEHInfo
{
-#ifndef FEATURE_CORECLR
- __field_ecount(EHCount)
-#endif
DACEHInfo *m_pInfos;
UINT EHCount;
CLRDATA_ADDRESS methodStart;
diff --git a/src/ToolBox/SOS/Strike/gcroot.cpp b/src/ToolBox/SOS/Strike/gcroot.cpp
index f68b935e21..86080989ec 100644
--- a/src/ToolBox/SOS/Strike/gcroot.cpp
+++ b/src/ToolBox/SOS/Strike/gcroot.cpp
@@ -40,18 +40,14 @@
#include "safemath.h"
-#ifdef _ASSERTE
#undef _ASSERTE
-#endif
-#ifndef _ASSERTE
#ifdef _DEBUG
#define _ASSERTE(expr) \
do { if (!(expr) ) { ExtErr("_ASSERTE fired:\n\t%s\n", #expr); if (IsDebuggerPresent()) DebugBreak(); } } while (0)
#else
#define _ASSERTE(x)
#endif
-#endif // ASSERTE
inline size_t ALIGN_DOWN( size_t val, size_t alignment )
{
diff --git a/src/ToolBox/SOS/Strike/sos.cpp b/src/ToolBox/SOS/Strike/sos.cpp
index 351199c058..64ee4b9a0c 100644
--- a/src/ToolBox/SOS/Strike/sos.cpp
+++ b/src/ToolBox/SOS/Strike/sos.cpp
@@ -17,9 +17,7 @@
#include "gcdesc.h"
-#ifdef _ASSERTE
#undef _ASSERTE
-#endif
namespace sos
{
diff --git a/src/ToolBox/SOS/Strike/sos_md.h b/src/ToolBox/SOS/Strike/sos_md.h
index f1a34cd706..b589109986 100644
--- a/src/ToolBox/SOS/Strike/sos_md.h
+++ b/src/ToolBox/SOS/Strike/sos_md.h
@@ -33,7 +33,7 @@ class CQuickBytes;
* Always keep the definitions below in sync with the originals.
* NOTES:
* Since SOS runs in a native debugger session, since it does not use EnC,
- * and in roder to minimize the amount of duplication we changed the
+ * and in order to minimize the amount of duplication we changed the
* method definitions that deal with UTSemReadWrite* arguments to take
* void* arguments instead.
* Also, some of the interface methods take CQuickBytes as arguments.
diff --git a/src/ToolBox/SOS/Strike/strike.cpp b/src/ToolBox/SOS/Strike/strike.cpp
index 3bb3f50200..2b54b4f037 100644
--- a/src/ToolBox/SOS/Strike/strike.cpp
+++ b/src/ToolBox/SOS/Strike/strike.cpp
@@ -2090,11 +2090,9 @@ struct StackTraceElement
UINT_PTR ip;
UINT_PTR sp;
DWORD_PTR pFunc; // MethodDesc
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
// TRUE if this element represents the last frame of the foreign
// exception stack trace.
BOOL fIsLastFrameFromForeignStackTrace;
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
};
@@ -8840,28 +8838,28 @@ void PrintInterestingGCInfo(DacpGCInterestingInfoData* dataPerHeap)
{
ExtOut("Interesting data points\n");
size_t* data = dataPerHeap->interestingDataPoints;
- for (int i = 0; i < NUM_GC_DATA_POINTS; i++)
+ for (int i = 0; i < DAC_NUM_GC_DATA_POINTS; i++)
{
ExtOut("%20s: %d\n", str_interesting_data_points[i], data[i]);
}
ExtOut("\nCompacting reasons\n");
data = dataPerHeap->compactReasons;
- for (int i = 0; i < MAX_COMPACT_REASONS_COUNT; i++)
+ for (int i = 0; i < DAC_MAX_COMPACT_REASONS_COUNT; i++)
{
ExtOut("[%s]%35s: %d\n", (gc_heap_compact_reason_mandatory_p[i] ? "M" : "W"), str_heap_compact_reasons[i], data[i]);
}
ExtOut("\nExpansion mechanisms\n");
data = dataPerHeap->expandMechanisms;
- for (int i = 0; i < MAX_EXPAND_MECHANISMS_COUNT; i++)
+ for (int i = 0; i < DAC_MAX_EXPAND_MECHANISMS_COUNT; i++)
{
ExtOut("%30s: %d\n", str_heap_expand_mechanisms[i], data[i]);
}
ExtOut("\nOther mechanisms enabled\n");
data = dataPerHeap->bitMechanisms;
- for (int i = 0; i < MAX_GC_MECHANISM_BITS_COUNT; i++)
+ for (int i = 0; i < DAC_MAX_GC_MECHANISM_BITS_COUNT; i++)
{
ExtOut("%20s: %d\n", str_bit_mechanisms[i], data[i]);
}
@@ -8883,7 +8881,7 @@ DECLARE_API(DumpGCData)
DacpGCInterestingInfoData interestingInfo;
interestingInfo.RequestGlobal(g_sos);
- for (int i = 0; i < MAX_GLOBAL_GC_MECHANISMS_COUNT; i++)
+ for (int i = 0; i < DAC_MAX_GLOBAL_GC_MECHANISMS_COUNT; i++)
{
ExtOut("%-30s: %d\n", str_gc_global_mechanisms[i], interestingInfo.globalMechanisms[i]);
}
diff --git a/src/ToolBox/SOS/Strike/util.cpp b/src/ToolBox/SOS/Strike/util.cpp
index b6336fb143..3cdebcf0f4 100644
--- a/src/ToolBox/SOS/Strike/util.cpp
+++ b/src/ToolBox/SOS/Strike/util.cpp
@@ -4793,10 +4793,8 @@ HRESULT InitCorDebugInterface()
// Need to pick the appropriate SKU of CLR to detect
#if defined(FEATURE_CORESYSTEM)
GUID skuId = CLR_ID_ONECORE_CLR;
-#elif defined(FEATURE_CORECLR)
- GUID skuId = CLR_ID_CORECLR;
#else
- GUID skuId = CLR_ID_V4_DESKTOP;
+ GUID skuId = CLR_ID_CORECLR;
#endif
CLRDebuggingImpl* pDebuggingImpl = new CLRDebuggingImpl(skuId);
hr = pDebuggingImpl->QueryInterface(IID_ICLRDebugging, (LPVOID *)&pClrDebugging);
diff --git a/src/ToolBox/SOS/lldbplugin/CMakeLists.txt b/src/ToolBox/SOS/lldbplugin/CMakeLists.txt
index 29b36e8fa2..247c70033b 100644
--- a/src/ToolBox/SOS/lldbplugin/CMakeLists.txt
+++ b/src/ToolBox/SOS/lldbplugin/CMakeLists.txt
@@ -15,6 +15,13 @@ endif (CORECLR_SET_RPATH)
add_definitions(-DPAL_STDCPP_COMPAT)
+set(ENABLE_LLDBPLUGIN ${CLR_CMAKE_PLATFORM_UNIX} CACHE BOOL "Enable building the SOS plugin for LLDB.")
+set(REQUIRE_LLDBPLUGIN ${CLR_CMAKE_PLATFORM_LINUX} CACHE BOOL "Require building the SOS plugin for LLDB.")
+
+if(SKIP_LLDBPLUGIN)
+ SET(REQUIRE_LLDBPLUGIN false)
+endif()
+
if(CLR_CMAKE_PLATFORM_ARCH_AMD64)
add_definitions(-D_TARGET_AMD64_=1)
add_definitions(-DDBG_TARGET_64BIT=1)
@@ -35,14 +42,10 @@ elseif(CLR_CMAKE_PLATFORM_ARCH_ARM64)
add_definitions(-DDBG_TARGET_ARM64=1)
add_definitions(-DDBG_TARGET_WIN64=1)
add_definitions(-DBIT64)
+ SET(REQUIRE_LLDBPLUGIN false)
endif()
-set(ENABLE_LLDBPLUGIN ${CLR_CMAKE_PLATFORM_UNIX} CACHE BOOL "Enable building the SOS plugin for LLDB.")
-set(REQUIRE_LLDBPLUGIN ${CLR_CMAKE_PLATFORM_LINUX} CACHE BOOL "Require building the SOS plugin for LLDB.")
-if(SKIP_LLDBPLUGIN)
- SET(REQUIRE_LLDBPLUGIN false)
-endif()
set(LLVM_HOST_DIR "$ENV{LLVM_HOME}")
set(WITH_LLDB_LIBS "${LLVM_HOST_DIR}/lib" CACHE PATH "Path to LLDB libraries")
set(WITH_LLDB_INCLUDES "${LLVM_HOST_DIR}/include" CACHE PATH "Path to LLDB headers")
diff --git a/src/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h b/src/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h
index e1190d7ab6..0e36562076 100644
--- a/src/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h
+++ b/src/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h
@@ -57,11 +57,7 @@ public:
// When the EE loads the System.Numerics.Vectors assembly, it asks the JIT what length (in bytes) of
// SIMD vector it supports as an intrinsic type. Zero means that the JIT does not support SIMD
// intrinsics, so the EE should use the default size (i.e. the size of the IL implementation).
-#if COR_JIT_EE_VERSION > 460
unsigned getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags); /* { return 0; } */
-#else
- unsigned getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags); /* { return 0; } */
-#endif
// IL obfuscators sometimes interpose on the EE-JIT interface. This function allows the VM to
// tell the JIT to use a particular ICorJitCompiler to implement the methods of this interface,
diff --git a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
index b847d9bc50..0c5b269899 100644
--- a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
+++ b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
@@ -125,19 +125,21 @@ public:
unsigned* offsetAfterIndirection /* OUT */
);
+ // Find the virtual method in implementingClass that overrides virtualMethod.
+ // Return null if devirtualization is not possible.
+ CORINFO_METHOD_HANDLE resolveVirtualMethod(
+ CORINFO_METHOD_HANDLE virtualMethod,
+ CORINFO_CLASS_HANDLE implementingClass,
+ CORINFO_CONTEXT_HANDLE ownerType
+ );
+
// If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set,
// getIntrinsicID() returns the intrinsic ID.
// *pMustExpand tells whether or not JIT must expand the intrinsic.
-#if COR_JIT_EE_VERSION > 460
CorInfoIntrinsics getIntrinsicID(
CORINFO_METHOD_HANDLE method,
bool* pMustExpand = NULL /* OUT */
);
-#else
- CorInfoIntrinsics getIntrinsicID(
- CORINFO_METHOD_HANDLE method
- );
-#endif
// Is the given module the System.Numerics.Vectors module?
// This defaults to false.
@@ -229,13 +231,11 @@ public:
// failures during token resolution.
void resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken);
-#if COR_JIT_EE_VERSION > 460
// Attempt to resolve a metadata token into a runtime method handle. Returns true
// if resolution succeeded and false otherwise (e.g. if it encounters invalid metadata
// during token reoslution). This method should be used instead of `resolveToken` in
// situations that need to be resilient to invalid metadata.
bool tryResolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken);
-#endif
// Signature information about the call sig
void findSig (
@@ -382,7 +382,7 @@ public:
// in representing of 'cls' from a GC perspective. The class is
// assumed to be an array of machine words
// (of length // getClassSize(cls) / sizeof(void*)),
- // 'gcPtrs' is a poitner to an array of BYTEs of this length.
+ // 'gcPtrs' is a pointer to an array of BYTEs of this length.
// getClassGClayout fills in this array so that gcPtrs[i] is set
// to one of the CorInfoGCType values which is the GC type of
// the i-th machine word of an object of type 'cls'
@@ -454,7 +454,7 @@ public:
// value into a particular location and thus has the signature
// void unboxHelper(void* dest, CORINFO_CLASS_HANDLE cls, Object* obj)
// Otherwise (it is null or points at a FALSE value) it is requesting
- // a helper that returns a poitner to the unboxed data
+ // a helper that returns a pointer to the unboxed data
// void* unboxHelper(CORINFO_CLASS_HANDLE cls, Object* obj)
// The EE has the option of NOT returning the copy style helper
// (But must be able to always honor the non-copy style helper)
@@ -465,7 +465,6 @@ public:
CORINFO_CLASS_HANDLE cls
);
-#if COR_JIT_EE_VERSION > 460
bool getReadyToRunHelper(
CORINFO_RESOLVED_TOKEN * pResolvedToken,
CORINFO_LOOKUP_KIND * pGenericLookupKind,
@@ -476,16 +475,8 @@ public:
void getReadyToRunDelegateCtorHelper(
CORINFO_RESOLVED_TOKEN * pTargetMethod,
CORINFO_CLASS_HANDLE delegateType,
- CORINFO_CONST_LOOKUP * pLookup
+ CORINFO_LOOKUP * pLookup
);
-#else
- void getReadyToRunHelper(
- CORINFO_RESOLVED_TOKEN * pResolvedToken,
- CorInfoHelpFunc id,
- CORINFO_CONST_LOOKUP * pLookup
- );
-#endif
-
const char* getHelperName(
CorInfoHelpFunc
@@ -802,7 +793,6 @@ public:
void ThrowExceptionForHelper(
const CORINFO_HELPER_DESC * throwHelper);
-#if COR_JIT_EE_VERSION > 460
// Runs the given function under an error trap. This allows the JIT to make calls
// to interface functions that may throw exceptions without needing to be aware of
// the EH ABI, exception types, etc. Returns true if the given function completed
@@ -811,7 +801,6 @@ public:
void (*function)(void*), // The function to run
void* parameter // The context parameter that will be passed to the function and the handler
);
-#endif
/*****************************************************************************
* ICorStaticInfo contains EE interface methods which return values that are
@@ -863,16 +852,12 @@ public:
size_t FQNameCapacity /* IN */
);
-#if COR_JIT_EE_VERSION > 460
-
// returns whether the struct is enregisterable. Only valid on a System V VM. Returns true on success, false on failure.
bool getSystemVAmd64PassStructInRegisterDescriptor(
/* IN */ CORINFO_CLASS_HANDLE structHnd,
/* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr
);
-#endif // COR_JIT_EE_VERSION
-
/*****************************************************************************
* ICorDynamicInfo contains EE interface methods which return values that may
* change from invocation to invocation. They cannot be embedded in persisted
@@ -992,8 +977,7 @@ public:
);
// NOTE: the two methods below--getPInvokeUnmanagedTarget and getAddressOfPInvokeFixup--are
- // deprecated. New code (i.e. anything that can depend on COR_JIT_EE_VERSION being
- // greater than 460) should instead use getAddressOfPInvokeTarget, which subsumes the
+ // deprecated. New code should instead use getAddressOfPInvokeTarget, which subsumes the
// functionality of these methods.
// return the unmanaged target *if method has already been prelinked.*
@@ -1008,14 +992,12 @@ public:
void **ppIndirection = NULL
);
-#if COR_JIT_EE_VERSION > 460
// return the address of the PInvoke target. May be a fixup area in the
// case of late-bound PInvoke calls.
void getAddressOfPInvokeTarget(
CORINFO_METHOD_HANDLE method,
CORINFO_CONST_LOOKUP *pLookup
);
-#endif
// Generate a cookie based on the signature that would needs to be passed
// to CORINFO_HELP_PINVOKE_CALLI
@@ -1303,7 +1285,6 @@ public:
//
DWORD getExpectedTargetArchitecture();
-#if COR_JIT_EE_VERSION > 460
// Fetches extended flags for a particular compilation instance. Returns
// the number of bytes written to the provided buffer.
DWORD getJitFlags(
@@ -1311,6 +1292,5 @@ public:
DWORD sizeInBytes /* IN: The size of the buffer. Note that this is effectively a
version number for the CORJIT_FLAGS value. */
);
-#endif
#endif // _ICorJitInfoImpl
diff --git a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
index de0db3a9bb..6e5f0168fd 100644
--- a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
+++ b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
@@ -141,6 +141,7 @@ LWM(IsWriteBarrierHelperRequired, DWORDLONG, DWORD)
LWM(MergeClasses, DLDL, DWORDLONG)
LWM(PInvokeMarshalingRequired, Agnostic_PInvokeMarshalingRequired, DWORD)
LWM(ResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, Agnostic_CORINFO_RESOLVED_TOKENout)
+LWM(ResolveVirtualMethod, Agnostic_ResolveVirtualMethod, DWORDLONG)
LWM(TryResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, Agnostic_CORINFO_RESOLVED_TOKENout)
LWM(SatisfiesClassConstraints, DWORDLONG, DWORD)
LWM(SatisfiesMethodConstraints, DLDL, DWORD)
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
index 5768d38569..8638e0d825 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
@@ -2283,7 +2283,7 @@ bool MethodContext::repGetReadyToRunHelper(
void MethodContext::recGetReadyToRunDelegateCtorHelper(
CORINFO_RESOLVED_TOKEN * pTargetMethod,
CORINFO_CLASS_HANDLE delegateType,
- CORINFO_CONST_LOOKUP * pLookup
+ CORINFO_LOOKUP * pLookup
)
{
LogError("GetReadyToRunDelegateCtorHelper NYI");
@@ -2302,7 +2302,7 @@ void MethodContext::dmpGetReadyToRunDelegateCtorHelper(DWORDLONG key, DWORD valu
void MethodContext::repGetReadyToRunDelegateCtorHelper(
CORINFO_RESOLVED_TOKEN * pTargetMethod,
CORINFO_CLASS_HANDLE delegateType,
- CORINFO_CONST_LOOKUP * pLookup
+ CORINFO_LOOKUP * pLookup
)
{
LogError("getReadyToRunDelegateCtorHelper NYI");
@@ -3296,6 +3296,47 @@ void MethodContext::repGetMethodVTableOffset(CORINFO_METHOD_HANDLE method, unsig
DEBUG_REP(dmpGetMethodVTableOffset((DWORDLONG)method, value));
}
+void MethodContext::recResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod, CORINFO_CLASS_HANDLE implClass,
+ CORINFO_CONTEXT_HANDLE ownerType, CORINFO_METHOD_HANDLE result)
+{
+ if (ResolveVirtualMethod == nullptr)
+ {
+ ResolveVirtualMethod = new LightWeightMap<Agnostic_ResolveVirtualMethod, DWORDLONG>();
+ }
+
+ Agnostic_ResolveVirtualMethod key;
+ key.virtualMethod = (DWORDLONG)virtMethod;
+ key.implementingClass = (DWORDLONG)implClass;
+ key.ownerType = (DWORDLONG)ownerType;
+ ResolveVirtualMethod->Add(key, (DWORDLONG) result);
+ DEBUG_REC(dmpResolveVirtualMethod(key, result));
+}
+
+void MethodContext::dmpResolveVirtualMethod(const Agnostic_ResolveVirtualMethod& key, DWORDLONG value)
+{
+ printf("ResolveVirtualMethod virtMethod-%016llX, implClass-%016llX, ownerType--%01611X, result-%016llX",
+ key.virtualMethod, key.implementingClass, key.ownerType, value);
+}
+
+CORINFO_METHOD_HANDLE MethodContext::repResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod, CORINFO_CLASS_HANDLE implClass,
+ CORINFO_CONTEXT_HANDLE ownerType)
+{
+ Agnostic_ResolveVirtualMethod key;
+ key.virtualMethod = (DWORDLONG)virtMethod;
+ key.implementingClass = (DWORDLONG)implClass;
+ key.ownerType = (DWORDLONG)ownerType;
+
+ AssertCodeMsg(ResolveVirtualMethod != nullptr, EXCEPTIONCODE_MC, "No ResolveVirtualMap map for %016llX-%016llX-%016llX",
+ key.virtualMethod, key.implementingClass, key.ownerType);
+ AssertCodeMsg(ResolveVirtualMethod->GetIndex(key) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX-%016llx-%016llX",
+ key.virtualMethod, key.implementingClass, key.ownerType);
+ DWORDLONG result = ResolveVirtualMethod->Get(key);
+
+ DEBUG_REP(dmpResolveVirtualMethod(key, result));
+
+ return (CORINFO_METHOD_HANDLE)result;
+}
+
void MethodContext::recGetTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_CLASS_HANDLE result)
{
if (GetTokenTypeAsHandle == nullptr)
@@ -4191,9 +4232,6 @@ void MethodContext::repGetEEInfo(CORINFO_EE_INFO *pEEInfoOut)
pEEInfoOut->osMajor = (unsigned)0;
pEEInfoOut->osMinor = (unsigned)0;
pEEInfoOut->osBuild = (unsigned)0;
-#ifdef DEBUG_REP
- printf("repGetEEInfo - fell to default params\n");
-#endif
}
}
@@ -6165,7 +6203,7 @@ mdMethodDef MethodContext::repGetMethodDefFromMethod(CORINFO_METHOD_HANDLE hMeth
int index = GetMethodDefFromMethod->GetIndex((DWORDLONG)hMethod);
if (index < 0)
- return (mdMethodDef)0x06000001;
+ return (mdMethodDef)0x06000001;
return (mdMethodDef)GetMethodDefFromMethod->Get((DWORDLONG)hMethod);
}
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
index 0d49666e5c..b2224d91ae 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
@@ -436,6 +436,13 @@ public:
DWORD result;
};
+ struct Agnostic_ResolveVirtualMethod
+ {
+ DWORDLONG virtualMethod;
+ DWORDLONG implementingClass;
+ DWORDLONG ownerType;
+ };
+
#pragma pack(pop)
MethodContext();
@@ -632,9 +639,9 @@ public:
void dmpGetReadyToRunHelper(DWORDLONG key, DWORD value);
bool repGetReadyToRunHelper(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_LOOKUP_KIND* pGenericLookupKind, CorInfoHelpFunc id, CORINFO_CONST_LOOKUP* pLookup);
- void recGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, CORINFO_CLASS_HANDLE delegateType, CORINFO_CONST_LOOKUP* pLookup);
+ void recGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, CORINFO_CLASS_HANDLE delegateType, CORINFO_LOOKUP* pLookup);
void dmpGetReadyToRunDelegateCtorHelper(DWORDLONG key, DWORD value);
- void repGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, CORINFO_CLASS_HANDLE delegateType, CORINFO_CONST_LOOKUP* pLookup);
+ void repGetReadyToRunDelegateCtorHelper(CORINFO_RESOLVED_TOKEN* pTargetMethod, CORINFO_CLASS_HANDLE delegateType, CORINFO_LOOKUP* pLookup);
void recGetHelperFtn(CorInfoHelpFunc ftnNum, void **ppIndirection, void *result);
void dmpGetHelperFtn(DWORD key, DLDL value);
@@ -698,6 +705,12 @@ public:
void dmpGetMethodVTableOffset(DWORDLONG key, DD value);
void repGetMethodVTableOffset(CORINFO_METHOD_HANDLE method, unsigned *offsetOfIndirection, unsigned* offsetAfterIndirection);
+ void recResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod, CORINFO_CLASS_HANDLE implClass,
+ CORINFO_CONTEXT_HANDLE ownerType, CORINFO_METHOD_HANDLE result);
+ void dmpResolveVirtualMethod(const Agnostic_ResolveVirtualMethod& key, DWORDLONG value);
+ CORINFO_METHOD_HANDLE repResolveVirtualMethod(CORINFO_METHOD_HANDLE virtMethod, CORINFO_CLASS_HANDLE implClass,
+ CORINFO_CONTEXT_HANDLE ownerType);
+
void recGetTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_CLASS_HANDLE result);
void dmpGetTokenTypeAsHandle(const Agnostic_CORINFO_RESOLVED_TOKEN& key, DWORDLONG value);
CORINFO_CLASS_HANDLE repGetTokenTypeAsHandle(CORINFO_RESOLVED_TOKEN * pResolvedToken);
@@ -1016,7 +1029,7 @@ private:
// ********************* Please keep this up-to-date to ease adding more ***************
-// Highest packet number: 159
+// Highest packet number: 160
// *************************************************************************************
enum mcPackets
{
@@ -1151,6 +1164,7 @@ enum mcPackets
Packet_MergeClasses = 107,
Packet_PInvokeMarshalingRequired = 108,
Packet_ResolveToken = 109,
+ Packet_ResolveVirtualMethod = 160, // Added 2/13/17
Packet_TryResolveToken = 158, //Added 4/26/2016
Packet_SatisfiesClassConstraints = 110,
Packet_SatisfiesMethodConstraints = 111,
diff --git a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
index 1813ed29ff..6d64442a21 100644
--- a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
@@ -236,6 +236,20 @@ void interceptor_ICJI::getMethodVTableOffset (
mc->recGetMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection);
}
+// Find the virtual method in implementingClass that overrides virtualMethod.
+// Return null if devirtualization is not possible.
+CORINFO_METHOD_HANDLE interceptor_ICJI::resolveVirtualMethod(
+ CORINFO_METHOD_HANDLE virtualMethod,
+ CORINFO_CLASS_HANDLE implementingClass,
+ CORINFO_CONTEXT_HANDLE ownerType
+ )
+{
+ mc->cr->AddCall("resolveVirtualMethod");
+ CORINFO_METHOD_HANDLE result = original_ICorJitInfo->resolveVirtualMethod(virtualMethod, implementingClass, ownerType);
+ mc->recResolveVirtualMethod(virtualMethod, implementingClass, ownerType, result);
+ return result;
+}
+
// If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set,
// getIntrinsicID() returns the intrinsic ID.
CorInfoIntrinsics interceptor_ICJI::getIntrinsicID(
@@ -699,7 +713,7 @@ unsigned interceptor_ICJI::getClassAlignmentRequirement (
// in representing of 'cls' from a GC perspective. The class is
// assumed to be an array of machine words
// (of length // getClassSize(cls) / sizeof(void*)),
-// 'gcPtrs' is a poitner to an array of BYTEs of this length.
+// 'gcPtrs' is a pointer to an array of BYTEs of this length.
// getClassGClayout fills in this array so that gcPtrs[i] is set
// to one of the CorInfoGCType values which is the GC type of
// the i-th machine word of an object of type 'cls'
@@ -838,7 +852,7 @@ CorInfoHelpFunc interceptor_ICJI::getBoxHelper(
// value into a particular location and thus has the signature
// void unboxHelper(void* dest, CORINFO_CLASS_HANDLE cls, Object* obj)
// Otherwise (it is null or points at a FALSE value) it is requesting
-// a helper that returns a poitner to the unboxed data
+// a helper that returns a pointer to the unboxed data
// void* unboxHelper(CORINFO_CLASS_HANDLE cls, Object* obj)
// The EE has the option of NOT returning the copy style helper
// (But must be able to always honor the non-copy style helper)
@@ -870,7 +884,7 @@ bool interceptor_ICJI::getReadyToRunHelper(
void interceptor_ICJI::getReadyToRunDelegateCtorHelper(
CORINFO_RESOLVED_TOKEN * pTargetMethod,
CORINFO_CLASS_HANDLE delegateType,
- CORINFO_CONST_LOOKUP * pLookup
+ CORINFO_LOOKUP * pLookup
)
{
mc->cr->AddCall("getReadyToRunDelegateCtorHelper");
diff --git a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
index 448fb1f686..492d08908d 100644
--- a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
@@ -165,6 +165,18 @@ void interceptor_ICJI::getMethodVTableOffset (
original_ICorJitInfo->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection);
}
+// Find the virtual method in implementingClass that overrides virtualMethod.
+// Return null if devirtualization is not possible.
+CORINFO_METHOD_HANDLE interceptor_ICJI::resolveVirtualMethod(
+ CORINFO_METHOD_HANDLE virtualMethod,
+ CORINFO_CLASS_HANDLE implementingClass,
+ CORINFO_CONTEXT_HANDLE ownerType
+ )
+{
+ mcs->AddCall("resolveVirtualMethod");
+ return original_ICorJitInfo->resolveVirtualMethod(virtualMethod, implementingClass, ownerType);
+}
+
// If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set,
// getIntrinsicID() returns the intrinsic ID.
CorInfoIntrinsics interceptor_ICJI::getIntrinsicID(
@@ -555,7 +567,7 @@ unsigned interceptor_ICJI::getClassAlignmentRequirement (
// in representing of 'cls' from a GC perspective. The class is
// assumed to be an array of machine words
// (of length // getClassSize(cls) / sizeof(void*)),
-// 'gcPtrs' is a poitner to an array of BYTEs of this length.
+// 'gcPtrs' is a pointer to an array of BYTEs of this length.
// getClassGClayout fills in this array so that gcPtrs[i] is set
// to one of the CorInfoGCType values which is the GC type of
// the i-th machine word of an object of type 'cls'
@@ -671,7 +683,7 @@ CorInfoHelpFunc interceptor_ICJI::getBoxHelper(
// value into a particular location and thus has the signature
// void unboxHelper(void* dest, CORINFO_CLASS_HANDLE cls, Object* obj)
// Otherwise (it is null or points at a FALSE value) it is requesting
-// a helper that returns a poitner to the unboxed data
+// a helper that returns a pointer to the unboxed data
// void* unboxHelper(CORINFO_CLASS_HANDLE cls, Object* obj)
// The EE has the option of NOT returning the copy style helper
// (But must be able to always honor the non-copy style helper)
@@ -700,7 +712,7 @@ bool interceptor_ICJI::getReadyToRunHelper(
void interceptor_ICJI::getReadyToRunDelegateCtorHelper(
CORINFO_RESOLVED_TOKEN * pTargetMethod,
CORINFO_CLASS_HANDLE delegateType,
- CORINFO_CONST_LOOKUP * pLookup
+ CORINFO_LOOKUP * pLookup
)
{
mcs->AddCall("getReadyToRunDelegateCtorHelper");
diff --git a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
index 4d145f6a41..8941685fe3 100644
--- a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
@@ -153,6 +153,17 @@ void interceptor_ICJI::getMethodVTableOffset (
original_ICorJitInfo->getMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection);
}
+// Find the virtual method in implementingClass that overrides virtualMethod.
+// Return null if devirtualization is not possible.
+CORINFO_METHOD_HANDLE interceptor_ICJI::resolveVirtualMethod(
+ CORINFO_METHOD_HANDLE virtualMethod,
+ CORINFO_CLASS_HANDLE implementingClass,
+ CORINFO_CONTEXT_HANDLE ownerType
+ )
+{
+ return original_ICorJitInfo->resolveVirtualMethod(virtualMethod, implementingClass, ownerType);
+}
+
// If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set,
// getIntrinsicID() returns the intrinsic ID.
CorInfoIntrinsics interceptor_ICJI::getIntrinsicID(
@@ -504,7 +515,7 @@ unsigned interceptor_ICJI::getClassAlignmentRequirement (
// in representing of 'cls' from a GC perspective. The class is
// assumed to be an array of machine words
// (of length // getClassSize(cls) / sizeof(void*)),
-// 'gcPtrs' is a poitner to an array of BYTEs of this length.
+// 'gcPtrs' is a pointer to an array of BYTEs of this length.
// getClassGClayout fills in this array so that gcPtrs[i] is set
// to one of the CorInfoGCType values which is the GC type of
// the i-th machine word of an object of type 'cls'
@@ -609,7 +620,7 @@ CorInfoHelpFunc interceptor_ICJI::getBoxHelper(
// value into a particular location and thus has the signature
// void unboxHelper(void* dest, CORINFO_CLASS_HANDLE cls, Object* obj)
// Otherwise (it is null or points at a FALSE value) it is requesting
-// a helper that returns a poitner to the unboxed data
+// a helper that returns a pointer to the unboxed data
// void* unboxHelper(CORINFO_CLASS_HANDLE cls, Object* obj)
// The EE has the option of NOT returning the copy style helper
// (But must be able to always honor the non-copy style helper)
@@ -636,7 +647,7 @@ bool interceptor_ICJI::getReadyToRunHelper(
void interceptor_ICJI::getReadyToRunDelegateCtorHelper(
CORINFO_RESOLVED_TOKEN * pTargetMethod,
CORINFO_CLASS_HANDLE delegateType,
- CORINFO_CONST_LOOKUP * pLookup
+ CORINFO_LOOKUP * pLookup
)
{
original_ICorJitInfo->getReadyToRunDelegateCtorHelper(pTargetMethod, delegateType, pLookup);
diff --git a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
index b746d3f6f7..6478b3c684 100644
--- a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
@@ -185,6 +185,19 @@ void MyICJI::getMethodVTableOffset (
jitInstance->mc->repGetMethodVTableOffset(method, offsetOfIndirection, offsetAfterIndirection);
}
+// Find the virtual method in implementingClass that overrides virtualMethod.
+// Return null if devirtualization is not possible.
+CORINFO_METHOD_HANDLE MyICJI::resolveVirtualMethod(
+ CORINFO_METHOD_HANDLE virtualMethod,
+ CORINFO_CLASS_HANDLE implementingClass,
+ CORINFO_CONTEXT_HANDLE ownerType
+ )
+{
+ jitInstance->mc->cr->AddCall("resolveVirtualMethod");
+ CORINFO_METHOD_HANDLE result = jitInstance->mc->repResolveVirtualMethod(virtualMethod, implementingClass, ownerType);
+ return result;
+}
+
// If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set,
// getIntrinsicID() returns the intrinsic ID.
CorInfoIntrinsics MyICJI::getIntrinsicID(
@@ -609,7 +622,7 @@ unsigned MyICJI::getClassAlignmentRequirement (
// in representing of 'cls' from a GC perspective. The class is
// assumed to be an array of machine words
// (of length // getClassSize(cls) / sizeof(void*)),
-// 'gcPtrs' is a poitner to an array of BYTEs of this length.
+// 'gcPtrs' is a pointer to an array of BYTEs of this length.
// getClassGClayout fills in this array so that gcPtrs[i] is set
// to one of the CorInfoGCType values which is the GC type of
// the i-th machine word of an object of type 'cls'
@@ -726,7 +739,7 @@ CorInfoHelpFunc MyICJI::getBoxHelper(
// value into a particular location and thus has the signature
// void unboxHelper(void* dest, CORINFO_CLASS_HANDLE cls, Object* obj)
// Otherwise (it is null or points at a FALSE value) it is requesting
-// a helper that returns a poitner to the unboxed data
+// a helper that returns a pointer to the unboxed data
// void* unboxHelper(CORINFO_CLASS_HANDLE cls, Object* obj)
// The EE has the option of NOT returning the copy style helper
// (But must be able to always honor the non-copy style helper)
@@ -756,7 +769,7 @@ bool MyICJI::getReadyToRunHelper(
void MyICJI::getReadyToRunDelegateCtorHelper(
CORINFO_RESOLVED_TOKEN * pTargetMethod,
CORINFO_CLASS_HANDLE delegateType,
- CORINFO_CONST_LOOKUP * pLookup
+ CORINFO_LOOKUP * pLookup
)
{
jitInstance->mc->cr->AddCall("getReadyToRunDelegateCtorHelper");
diff --git a/src/binder/applicationcontext.cpp b/src/binder/applicationcontext.cpp
index e5c3025787..d395f4ddc1 100644
--- a/src/binder/applicationcontext.cpp
+++ b/src/binder/applicationcontext.cpp
@@ -143,9 +143,7 @@ namespace BINDER_SPACE
m_pFailureCache = pFailureCache;
}
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
m_fCanExplicitlyBindToNativeImages = false;
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
Exit:
BINDER_LOG_LEAVE_HR(W("ApplicationContext::Init"), hr);
diff --git a/src/binder/assemblybinder.cpp b/src/binder/assemblybinder.cpp
index 517eac99d6..a73f79fb65 100644
--- a/src/binder/assemblybinder.cpp
+++ b/src/binder/assemblybinder.cpp
@@ -46,7 +46,7 @@
BOOL IsCompilationProcess();
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
#include "clrprivbindercoreclr.h"
#include "clrprivbinderassemblyloadcontext.h"
// Helper function in the VM, invoked by the Binder, to invoke the host assembly resolver
@@ -57,7 +57,7 @@ extern HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadCon
// Helper to check if we have a host assembly resolver set
extern BOOL RuntimeCanUseAppPathAssemblyResolver(DWORD adid);
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
namespace BINDER_SPACE
{
@@ -1073,12 +1073,12 @@ namespace BINDER_SPACE
// Dynamic binds need to be always considered a failure for binding closures
IF_FAIL_GO(FUSION_E_APP_DOMAIN_LOCKED);
}
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
else if (IgnoreRefDefMatch(dwBindFlags))
{
// Skip RefDef matching if we have been asked to.
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
else
{
// Can't give higher serciving than already bound
@@ -1393,13 +1393,13 @@ namespace BINDER_SPACE
bool fUseAppPathsBasedResolver = !excludeAppPaths;
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
// If Host Assembly Resolver is specified, then we will use that as the override for the default resolution mechanism (that uses AppPath probing).
if (fUseAppPathsBasedResolver && !RuntimeCanUseAppPathAssemblyResolver(pApplicationContext->GetAppDomainId()))
{
fUseAppPathsBasedResolver = false;
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
// This loop executes twice max. First time through we probe AppNiPaths, the second time we probe AppPaths
bool parseNiPaths = true;
@@ -1812,7 +1812,7 @@ namespace BINDER_SPACE
#endif //CROSSGEN_COMPILE
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
HRESULT AssemblyBinder::BindUsingHostAssemblyResolver (/* in */ INT_PTR pManagedAssemblyLoadContextToBindWithin,
/* in */ AssemblyName *pAssemblyName,
/* in */ IAssemblyName *pIAssemblyName,
@@ -1947,7 +1947,7 @@ Exit:
BINDER_LOG_LEAVE_HR(W("AssemblyBinder::BindUsingPEImage"), hr);
return hr;
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
};
diff --git a/src/binder/bindinglog.cpp b/src/binder/bindinglog.cpp
index 4466fcea28..87c0c289eb 100644
--- a/src/binder/bindinglog.cpp
+++ b/src/binder/bindinglog.cpp
@@ -41,8 +41,6 @@ namespace BINDER_SPACE
{
namespace
{
- // Ripped from Fusion
-
inline UINT GetPreBindStateName(AssemblyName *pAssemblyName)
{
if (pAssemblyName->HaveAssemblyVersion())
diff --git a/src/binder/clrprivbinderassemblyloadcontext.cpp b/src/binder/clrprivbinderassemblyloadcontext.cpp
index 8f3a3eef49..e6f957aabe 100644
--- a/src/binder/clrprivbinderassemblyloadcontext.cpp
+++ b/src/binder/clrprivbinderassemblyloadcontext.cpp
@@ -8,7 +8,7 @@
#include "clrprivbinderassemblyloadcontext.h"
#include "clrprivbinderutil.h"
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
using namespace BINDER_SPACE;
@@ -256,4 +256,4 @@ CLRPrivBinderAssemblyLoadContext::CLRPrivBinderAssemblyLoadContext()
m_pTPABinder = NULL;
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
diff --git a/src/binder/clrprivbindercoreclr.cpp b/src/binder/clrprivbindercoreclr.cpp
index d62af867ef..d756454edb 100644
--- a/src/binder/clrprivbindercoreclr.cpp
+++ b/src/binder/clrprivbindercoreclr.cpp
@@ -62,7 +62,7 @@ HRESULT CLRPrivBinderCoreCLR::BindAssemblyByName(IAssemblyName *pIAssemblyNa
hr = BindAssemblyByNameWorker(pAssemblyName, &pCoreCLRFoundAssembly, false /* excludeAppPaths */);
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
if ((hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) ||
(hr == FUSION_E_APP_DOMAIN_LOCKED) || (hr == FUSION_E_REF_DEF_MISMATCH))
{
@@ -94,7 +94,7 @@ HRESULT CLRPrivBinderCoreCLR::BindAssemblyByName(IAssemblyName *pIAssemblyNa
}
}
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
IF_FAIL_GO(hr);
@@ -107,7 +107,7 @@ Exit:;
return hr;
}
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
HRESULT CLRPrivBinderCoreCLR::BindUsingPEImage( /* in */ PEImage *pPEImage,
/* in */ BOOL fIsNativeImage,
/* [retval][out] */ ICLRPrivAssembly **ppAssembly)
@@ -159,8 +159,8 @@ HRESULT CLRPrivBinderCoreCLR::BindUsingPEImage( /* in */ PEImage *pPEImage,
{
if (pCoreCLRFoundAssembly->GetIsInGAC())
{
- // If we were able to bind to a TPA assembly, then fail the load
- IF_FAIL_GO(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
+ *ppAssembly = pCoreCLRFoundAssembly.Extract();
+ goto Exit;
}
}
}
@@ -179,7 +179,7 @@ Exit:;
return hr;
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
HRESULT CLRPrivBinderCoreCLR::VerifyBind(IAssemblyName *AssemblyName,
ICLRPrivAssembly *pAssembly,
diff --git a/src/binder/coreclrbindercommon.cpp b/src/binder/coreclrbindercommon.cpp
index 86540fcfd5..e788c15488 100644
--- a/src/binder/coreclrbindercommon.cpp
+++ b/src/binder/coreclrbindercommon.cpp
@@ -107,12 +107,8 @@ HRESULT CCoreCLRBinderHelper::BindToSystem(ICLRPrivAssembly **ppSystemAssembly,
EX_TRY
{
ReleaseHolder<BINDER_SPACE::Assembly> pAsm;
-#ifdef FEATURE_CORECLR
StackSString systemPath(SystemDomain::System()->SystemDirectory());
hr = AssemblyBinder::BindToSystem(systemPath, &pAsm, fBindToNativeImage);
-#else
- AssemblySpec::BindToSystem(&pAsm);
-#endif
if(SUCCEEDED(hr))
{
_ASSERTE(pAsm != NULL);
diff --git a/src/binder/inc/applicationcontext.hpp b/src/binder/inc/applicationcontext.hpp
index 4c256771eb..9c8926207c 100644
--- a/src/binder/inc/applicationcontext.hpp
+++ b/src/binder/inc/applicationcontext.hpp
@@ -174,7 +174,6 @@ namespace BINDER_SPACE
SimpleNameToFileNameMap * m_pTrustedPlatformAssemblyMap;
TpaFileNameHash * m_pFileNameHash;
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
bool m_fCanExplicitlyBindToNativeImages;
public:
inline void SetExplicitBindToNativeImages(bool fCanExplicitlyBindToNativeImages)
@@ -187,7 +186,6 @@ public:
return m_fCanExplicitlyBindToNativeImages;
}
protected:
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
};
#include "applicationcontext.inl"
diff --git a/src/binder/inc/assembly.hpp b/src/binder/inc/assembly.hpp
index 5b8425a3d1..425e80567e 100644
--- a/src/binder/inc/assembly.hpp
+++ b/src/binder/inc/assembly.hpp
@@ -21,13 +21,11 @@
#include "corpriv.h"
#include "clrprivbinding.h"
-#if !defined(FEATURE_FUSION)
#include "clrprivbindercoreclr.h"
-#endif // !defined(FEATURE_FUSION)
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
#include "clrprivbinderassemblyloadcontext.h"
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
STDAPI BinderAcquirePEImage(LPCTSTR szAssemblyPath,
PEImage **ppPEImage,
@@ -203,13 +201,11 @@ public:
return m_pBinder;
}
-#if !defined(FEATURE_FUSION)
friend class ::CLRPrivBinderCoreCLR;
-#endif // !defined(FEATURE_FUSION)
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
friend class ::CLRPrivBinderAssemblyLoadContext;
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
};
// This is a fast version which goes around the COM interfaces and directly
diff --git a/src/binder/inc/assemblybinder.hpp b/src/binder/inc/assemblybinder.hpp
index 3a1f1e45fd..fa2f8b409a 100644
--- a/src/binder/inc/assemblybinder.hpp
+++ b/src/binder/inc/assemblybinder.hpp
@@ -74,7 +74,7 @@ namespace BINDER_SPACE
/* out */ Assembly **ppAssembly,
/* in */ LPCTSTR szMDAssemblyPath = NULL);
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
static HRESULT BindUsingHostAssemblyResolver (/* in */ INT_PTR pManagedAssemblyLoadContextToBindWithin,
/* in */ AssemblyName *pAssemblyName,
/* in */ IAssemblyName *pIAssemblyName,
@@ -87,7 +87,7 @@ namespace BINDER_SPACE
/* in */ PEKIND peKind,
/* in */ IMDInternalImport *pIMetaDataAssemblyImport,
/* [retval] [out] */ Assembly **ppAssembly);
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
static HRESULT TranslatePEToArchitectureType(DWORD *pdwPAFlags, PEKIND *PeKind);
@@ -98,10 +98,10 @@ namespace BINDER_SPACE
BIND_CACHE_FAILURES = 0x01,
BIND_CACHE_RERUN_BIND = 0x02,
BIND_IGNORE_DYNAMIC_BINDS = 0x04
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
,
BIND_IGNORE_REFDEF_MATCH = 0x8
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
};
static BOOL IgnoreDynamicBinds(DWORD dwBindFlags)
@@ -119,12 +119,12 @@ namespace BINDER_SPACE
return ((dwBindFlags & BIND_CACHE_RERUN_BIND) != 0);
}
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
static BOOL IgnoreRefDefMatch(DWORD dwBindFlags)
{
return ((dwBindFlags & BIND_IGNORE_REFDEF_MATCH) != 0);
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
static HRESULT BindByName(/* in */ ApplicationContext *pApplicationContext,
/* in */ AssemblyName *pAssemblyName,
diff --git a/src/binder/inc/clrprivbinderassemblyloadcontext.h b/src/binder/inc/clrprivbinderassemblyloadcontext.h
index 83113f4633..9c772338d6 100644
--- a/src/binder/inc/clrprivbinderassemblyloadcontext.h
+++ b/src/binder/inc/clrprivbinderassemblyloadcontext.h
@@ -10,7 +10,7 @@
#include "applicationcontext.hpp"
#include "clrprivbindercoreclr.h"
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
namespace BINDER_SPACE
{
@@ -82,5 +82,5 @@ private:
INT_PTR m_ptrManagedAssemblyLoadContext;
};
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
#endif // __CLRPRIVBINDERASSEMBLYLOADCONTEXT_H__
diff --git a/src/binder/inc/clrprivbindercoreclr.h b/src/binder/inc/clrprivbindercoreclr.h
index e906e01b12..9338fad3df 100644
--- a/src/binder/inc/clrprivbindercoreclr.h
+++ b/src/binder/inc/clrprivbindercoreclr.h
@@ -67,11 +67,11 @@ public:
HRESULT PreBindByteArray(PEImage *pPEImage, BOOL fInspectionOnly);
#endif // CROSSGEN_COMPILE
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
HRESULT BindUsingPEImage( /* in */ PEImage *pPEImage,
/* in */ BOOL fIsNativeImage,
/* [retval][out] */ ICLRPrivAssembly **ppAssembly);
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
HRESULT BindAssemblyByNameWorker(
BINDER_SPACE::AssemblyName *pAssemblyName,
diff --git a/src/binder/inc/fusionhelpers.hpp b/src/binder/inc/fusionhelpers.hpp
index 229ebe6c4e..7b81e8589c 100644
--- a/src/binder/inc/fusionhelpers.hpp
+++ b/src/binder/inc/fusionhelpers.hpp
@@ -21,12 +21,6 @@
#include "ex.h"
#include "fusion.h"
-#ifndef FEATURE_VERSIONING
-// Rename the fusion bind result to avoid collision with core bind result
-#define IBindResult IBindResult_Fusion
-#include "binderngen.h"
-#undef IBindResult
-#endif
#include "peinformation.h"
diff --git a/src/binder/inc/list.hpp b/src/binder/inc/list.hpp
index 91ecd1752b..2125924986 100644
--- a/src/binder/inc/list.hpp
+++ b/src/binder/inc/list.hpp
@@ -20,8 +20,6 @@
namespace BINDER_SPACE
{
- // Ripped from Fusion
-
//
// ListNode
//
diff --git a/src/build.proj b/src/build.proj
index 8b9e3922b8..5da94e44c1 100644
--- a/src/build.proj
+++ b/src/build.proj
@@ -5,25 +5,18 @@
<ItemGroup>
<Project Include="ToolBox\SOS\NETCore\SOS.NETCore.csproj" />
<Project Include="mscorlib\System.Private.CoreLib.csproj" />
- <Project Include="mscorlib\facade\mscorlib.csproj" />
- <Project Include="mscorlib\ref\mscorlib.csproj" />
</ItemGroup>
<Import Project="..\dir.targets" />
<Import Project="..\dir.traversal.targets" />
- <ItemGroup>
- <BinariesToMove Include="$(BinDir)\facade\mscorlib.dll"/>
- </ItemGroup>
-
<Target Name="MovePostBuildBinaries" AfterTargets="Build">
<Move SourceFiles="@(BinariesToMove)"
DestinationFolder="$(BinDir)" />
</Target>
<ItemGroup>
- <PDBSToMove Include="$(BinDir)\facade\mscorlib.pdb"/>
<PDBSToMove Include="$(BinDir)System.Private.CoreLib.pdb"/>
</ItemGroup>
diff --git a/src/classlibnative/bcltype/arraynative.cpp b/src/classlibnative/bcltype/arraynative.cpp
index 0eae8b2d07..c54d2f3c31 100644
--- a/src/classlibnative/bcltype/arraynative.cpp
+++ b/src/classlibnative/bcltype/arraynative.cpp
@@ -17,6 +17,8 @@
#include "security.h"
#include "invokeutil.h"
+#include "arraynative.inl"
+
FCIMPL1(INT32, ArrayNative::GetRank, ArrayBase* array)
{
FCALL_CONTRACT;
@@ -173,7 +175,7 @@ void ArrayInitializeWorker(ARRAYBASEREF * arrayRef,
PCODE ctorFtn = pCanonMT->GetSlot(slot);
-#ifdef _X86_
+#if defined(_TARGET_X86_) && !defined(FEATURE_PAL)
BEGIN_CALL_TO_MANAGED();
@@ -204,7 +206,7 @@ void ArrayInitializeWorker(ARRAYBASEREF * arrayRef,
}
END_CALL_TO_MANAGED();
-#else // _X86_
+#else // _TARGET_X86_ && !FEATURE_PAL
//
// This is quite a bit slower, but it is portable.
//
@@ -228,7 +230,7 @@ void ArrayInitializeWorker(ARRAYBASEREF * arrayRef,
offset += size;
}
-#endif // _X86_
+#endif // !_TARGET_X86_ || FEATURE_PAL
}
@@ -883,85 +885,25 @@ void memmoveGCRefs(void *dest, const void *src, size_t len)
NOTHROW;
GC_NOTRIGGER;
MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(dest));
- PRECONDITION(CheckPointer(src));
- PRECONDITION(len >= 0);
SO_TOLERANT;
}
CONTRACTL_END;
+ _ASSERTE(dest != nullptr);
+ _ASSERTE(src != nullptr);
+
// Make sure everything is pointer aligned
_ASSERTE(IS_ALIGNED(dest, sizeof(SIZE_T)));
_ASSERTE(IS_ALIGNED(src, sizeof(SIZE_T)));
_ASSERTE(IS_ALIGNED(len, sizeof(SIZE_T)));
- size_t size = len;
- BYTE * dmem = (BYTE *)dest;
- BYTE * smem = (BYTE *)src;
-
- GCHeapMemoryBarrier();
-
- if (dmem <= smem || smem + size <= dmem)
- {
- // copy 16 bytes at a time
- while (size >= 4 * sizeof(SIZE_T))
- {
- size -= 4 * sizeof(SIZE_T);
- ((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
- ((SIZE_T *)dmem)[1] = ((SIZE_T *)smem)[1];
- ((SIZE_T *)dmem)[2] = ((SIZE_T *)smem)[2];
- ((SIZE_T *)dmem)[3] = ((SIZE_T *)smem)[3];
- smem += 4 * sizeof(SIZE_T);
- dmem += 4 * sizeof(SIZE_T);
- }
-
- if ((size & (2 * sizeof(SIZE_T))) != 0)
- {
- ((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
- ((SIZE_T *)dmem)[1] = ((SIZE_T *)smem)[1];
- smem += 2 * sizeof(SIZE_T);
- dmem += 2 * sizeof(SIZE_T);
- }
+ _ASSERTE(CheckPointer(dest));
+ _ASSERTE(CheckPointer(src));
- if ((size & sizeof(SIZE_T)) != 0)
- {
- ((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
- }
- }
- else
+ if (len != 0 && dest != src)
{
- smem += size;
- dmem += size;
-
- // copy 16 bytes at a time
- while (size >= 4 * sizeof(SIZE_T))
- {
- size -= 4 * sizeof(SIZE_T);
- smem -= 4 * sizeof(SIZE_T);
- dmem -= 4 * sizeof(SIZE_T);
- ((SIZE_T *)dmem)[3] = ((SIZE_T *)smem)[3];
- ((SIZE_T *)dmem)[2] = ((SIZE_T *)smem)[2];
- ((SIZE_T *)dmem)[1] = ((SIZE_T *)smem)[1];
- ((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
- }
-
- if ((size & (2 * sizeof(SIZE_T))) != 0)
- {
- smem -= 2 * sizeof(SIZE_T);
- dmem -= 2 * sizeof(SIZE_T);
- ((SIZE_T *)dmem)[1] = ((SIZE_T *)smem)[1];
- ((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
- }
-
- if ((size & sizeof(SIZE_T)) != 0)
- {
- smem -= sizeof(SIZE_T);
- dmem -= sizeof(SIZE_T);
- ((SIZE_T *)dmem)[0] = ((SIZE_T *)smem)[0];
- }
+ InlinedMemmoveGCRefsHelper(dest, src, len);
}
-
- SetCardsAfterBulkCopy((Object**)dest, len);
}
void ArrayNative::ArrayCopyNoTypeCheck(BASEARRAYREF pSrc, unsigned int srcIndex, BASEARRAYREF pDest, unsigned int destIndex, unsigned int length)
@@ -1186,18 +1128,6 @@ void ArrayNative::CheckElementType(TypeHandle elementType)
// TODO: We also should check for type/member visibility here. To do that we can replace
// the following chunk of code with a simple InvokeUtil::CanAccessClass call.
// But it's too late to make this change in Dev10 and we want SL4 to be compatible with Dev10.
-#ifndef FEATURE_CORECLR
- // Make sure security allows us access to the array type - if it is critical, convert that to a
- // demand for full trust
- if (!SecurityStackWalk::HasFlagsOrFullyTrusted(0))
- {
- if (Security::TypeRequiresTransparencyCheck(pMT, true))
- {
- // If we're creating a critical type, convert the critical check into a demand for full trust
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_FULL_TRUST);
- }
- }
-#else
if (Security::TypeRequiresTransparencyCheck(pMT))
{
// The AccessCheckOptions flag doesn't matter because we just need to get the caller.
@@ -1210,11 +1140,10 @@ void ArrayNative::CheckElementType(TypeHandle elementType)
accessCheckOptions.DemandMemberAccessOrFail(&sCtx, pMT, FALSE /*visibilityCheck*/);
}
-#endif // !FEATURE_CORECLR
// Check for byref-like types.
if (pMT->IsByRefLike())
- COMPlusThrow(kNotSupportedException, W("NotSupported_ByRefLike[]"));
+ COMPlusThrow(kNotSupportedException, W("NotSupported_ByRefLikeArray"));
// Check for open generic types.
if (pMT->IsGenericTypeDefinition() || pMT->ContainsGenericVariables())
@@ -1222,7 +1151,7 @@ void ArrayNative::CheckElementType(TypeHandle elementType)
// Check for Void.
if (elementType.GetSignatureCorElementType() == ELEMENT_TYPE_VOID)
- COMPlusThrow(kNotSupportedException, W("NotSupported_Void[]"));
+ COMPlusThrow(kNotSupportedException, W("NotSupported_VoidArray"));
// That's all the dangerous simple types we know, it must be OK.
return;
diff --git a/src/classlibnative/bcltype/arraynative.inl b/src/classlibnative/bcltype/arraynative.inl
new file mode 100644
index 0000000000..b29e1a9b73
--- /dev/null
+++ b/src/classlibnative/bcltype/arraynative.inl
@@ -0,0 +1,329 @@
+// 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.
+//
+// File: ArrayNative.cpp
+//
+
+//
+// This file contains the native methods that support the Array class
+//
+
+#ifndef _ARRAYNATIVE_INL_
+#define _ARRAYNATIVE_INL_
+
+#include "gchelpers.inl"
+
+FORCEINLINE void InlinedForwardGCSafeCopyHelper(void *dest, const void *src, size_t len)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_COOPERATIVE;
+ SO_TOLERANT;
+ }
+ CONTRACTL_END;
+
+ _ASSERTE(dest != nullptr);
+ _ASSERTE(src != nullptr);
+ _ASSERTE(dest != src);
+ _ASSERTE(len != 0);
+
+ // To be able to copy forwards, the destination buffer cannot start inside the source buffer
+ _ASSERTE((SIZE_T)dest - (SIZE_T)src >= len);
+
+ // Make sure everything is pointer aligned
+ _ASSERTE(IS_ALIGNED(dest, sizeof(SIZE_T)));
+ _ASSERTE(IS_ALIGNED(src, sizeof(SIZE_T)));
+ _ASSERTE(IS_ALIGNED(len, sizeof(SIZE_T)));
+
+ _ASSERTE(CheckPointer(dest));
+ _ASSERTE(CheckPointer(src));
+
+ SIZE_T *dptr = (SIZE_T *)dest;
+ SIZE_T *sptr = (SIZE_T *)src;
+
+ while (true)
+ {
+ if ((len & sizeof(SIZE_T)) != 0)
+ {
+ *dptr = *sptr;
+
+ len ^= sizeof(SIZE_T);
+ if (len == 0)
+ {
+ return;
+ }
+ ++sptr;
+ ++dptr;
+ }
+
+#if defined(_AMD64_) && (defined(_MSC_VER) || defined(__clang__))
+ if ((len & (2 * sizeof(SIZE_T))) != 0)
+ {
+ __m128 v = _mm_loadu_ps((float *)sptr);
+ _mm_storeu_ps((float *)dptr, v);
+
+ len ^= 2 * sizeof(SIZE_T);
+ if (len == 0)
+ {
+ return;
+ }
+ sptr += 2;
+ dptr += 2;
+ }
+
+ // Align the destination pointer to 16 bytes for the next set of 16-byte copies
+ if (((SIZE_T)dptr & sizeof(SIZE_T)) != 0)
+ {
+ *dptr = *sptr;
+
+ ++sptr;
+ ++dptr;
+ len -= sizeof(SIZE_T);
+ if (len < 4 * sizeof(SIZE_T))
+ {
+ continue;
+ }
+ }
+
+ // Copy 32 bytes at a time
+ _ASSERTE(len >= 4 * sizeof(SIZE_T));
+ do
+ {
+ __m128 v = _mm_loadu_ps((float *)sptr);
+ _mm_store_ps((float *)dptr, v);
+ v = _mm_loadu_ps((float *)(sptr + 2));
+ _mm_store_ps((float *)(dptr + 2), v);
+
+ sptr += 4;
+ dptr += 4;
+ len -= 4 * sizeof(SIZE_T);
+ } while (len >= 4 * sizeof(SIZE_T));
+ if (len == 0)
+ {
+ return;
+ }
+#else // !(defined(_AMD64_) && (defined(_MSC_VER) || defined(__clang__)))
+ if ((len & (2 * sizeof(SIZE_T))) != 0)
+ {
+ // Read two values and write two values to hint the use of wide loads and stores
+ SIZE_T p0 = sptr[0];
+ SIZE_T p1 = sptr[1];
+ dptr[0] = p0;
+ dptr[1] = p1;
+
+ len ^= 2 * sizeof(SIZE_T);
+ if (len == 0)
+ {
+ return;
+ }
+ sptr += 2;
+ dptr += 2;
+ }
+
+ // Copy 16 (on 32-bit systems) or 32 (on 64-bit systems) bytes at a time
+ _ASSERTE(len >= 4 * sizeof(SIZE_T));
+ while (true)
+ {
+ // Read two values and write two values to hint the use of wide loads and stores
+ SIZE_T p0 = sptr[0];
+ SIZE_T p1 = sptr[1];
+ dptr[0] = p0;
+ dptr[1] = p1;
+ p0 = sptr[2];
+ p1 = sptr[3];
+ dptr[2] = p0;
+ dptr[3] = p1;
+
+ len -= 4 * sizeof(SIZE_T);
+ if (len == 0)
+ {
+ return;
+ }
+ sptr += 4;
+ dptr += 4;
+ }
+#endif // defined(_AMD64_) && (defined(_MSC_VER) || defined(__clang__))
+ }
+}
+
+FORCEINLINE void InlinedBackwardGCSafeCopyHelper(void *dest, const void *src, size_t len)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_COOPERATIVE;
+ SO_TOLERANT;
+ }
+ CONTRACTL_END;
+
+ _ASSERTE(dest != nullptr);
+ _ASSERTE(src != nullptr);
+ _ASSERTE(dest != src);
+ _ASSERTE(len != 0);
+
+ // To be able to copy backwards, the source buffer cannot start inside the destination buffer
+ _ASSERTE((SIZE_T)src - (SIZE_T)dest >= len);
+
+ // Make sure everything is pointer aligned
+ _ASSERTE(IS_ALIGNED(dest, sizeof(SIZE_T)));
+ _ASSERTE(IS_ALIGNED(src, sizeof(SIZE_T)));
+ _ASSERTE(IS_ALIGNED(len, sizeof(SIZE_T)));
+
+ _ASSERTE(CheckPointer(dest));
+ _ASSERTE(CheckPointer(src));
+
+ SIZE_T *dptr = (SIZE_T *)((BYTE *)dest + len);
+ SIZE_T *sptr = (SIZE_T *)((BYTE *)src + len);
+
+ while (true)
+ {
+ if ((len & sizeof(SIZE_T)) != 0)
+ {
+ --sptr;
+ --dptr;
+
+ *dptr = *sptr;
+
+ len ^= sizeof(SIZE_T);
+ if (len == 0)
+ {
+ return;
+ }
+ }
+
+#if defined(_AMD64_) && (defined(_MSC_VER) || defined(__clang__))
+ if ((len & (2 * sizeof(SIZE_T))) != 0)
+ {
+ sptr -= 2;
+ dptr -= 2;
+
+ __m128 v = _mm_loadu_ps((float *)sptr);
+ _mm_storeu_ps((float *)dptr, v);
+
+ len ^= 2 * sizeof(SIZE_T);
+ if (len == 0)
+ {
+ return;
+ }
+ }
+
+ // Align the destination pointer to 16 bytes for the next set of 16-byte copies
+ if (((SIZE_T)dptr & sizeof(SIZE_T)) != 0)
+ {
+ --sptr;
+ --dptr;
+
+ *dptr = *sptr;
+
+ len -= sizeof(SIZE_T);
+ if (len < 4 * sizeof(SIZE_T))
+ {
+ continue;
+ }
+ }
+
+ // Copy 32 bytes at a time
+ _ASSERTE(len >= 4 * sizeof(SIZE_T));
+ do
+ {
+ sptr -= 4;
+ dptr -= 4;
+
+ __m128 v = _mm_loadu_ps((float *)(sptr + 2));
+ _mm_store_ps((float *)(dptr + 2), v);
+ v = _mm_loadu_ps((float *)sptr);
+ _mm_store_ps((float *)dptr, v);
+
+ len -= 4 * sizeof(SIZE_T);
+ } while (len >= 4 * sizeof(SIZE_T));
+ if (len == 0)
+ {
+ return;
+ }
+#else // !(defined(_AMD64_) && (defined(_MSC_VER) || defined(__clang__)))
+ if ((len & (2 * sizeof(SIZE_T))) != 0)
+ {
+ sptr -= 2;
+ dptr -= 2;
+
+ // Read two values and write two values to hint the use of wide loads and stores
+ SIZE_T p1 = sptr[1];
+ SIZE_T p0 = sptr[0];
+ dptr[1] = p1;
+ dptr[0] = p0;
+
+ len ^= 2 * sizeof(SIZE_T);
+ if (len == 0)
+ {
+ return;
+ }
+ }
+
+ // Copy 16 (on 32-bit systems) or 32 (on 64-bit systems) bytes at a time
+ _ASSERTE(len >= 4 * sizeof(SIZE_T));
+ do
+ {
+ sptr -= 4;
+ dptr -= 4;
+
+ // Read two values and write two values to hint the use of wide loads and stores
+ SIZE_T p0 = sptr[2];
+ SIZE_T p1 = sptr[3];
+ dptr[2] = p0;
+ dptr[3] = p1;
+ p0 = sptr[0];
+ p1 = sptr[1];
+ dptr[0] = p0;
+ dptr[1] = p1;
+
+ len -= 4 * sizeof(SIZE_T);
+ } while (len != 0);
+ return;
+#endif // defined(_AMD64_) && (defined(_MSC_VER) || defined(__clang__))
+ }
+}
+
+FORCEINLINE void InlinedMemmoveGCRefsHelper(void *dest, const void *src, size_t len)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_COOPERATIVE;
+ SO_TOLERANT;
+ }
+ CONTRACTL_END;
+
+ _ASSERTE(dest != nullptr);
+ _ASSERTE(src != nullptr);
+ _ASSERTE(dest != src);
+ _ASSERTE(len != 0);
+
+ // Make sure everything is pointer aligned
+ _ASSERTE(IS_ALIGNED(dest, sizeof(SIZE_T)));
+ _ASSERTE(IS_ALIGNED(src, sizeof(SIZE_T)));
+ _ASSERTE(IS_ALIGNED(len, sizeof(SIZE_T)));
+
+ _ASSERTE(CheckPointer(dest));
+ _ASSERTE(CheckPointer(src));
+
+ GCHeapMemoryBarrier();
+
+ // To be able to copy forwards, the destination buffer cannot start inside the source buffer
+ if ((size_t)dest - (size_t)src >= len)
+ {
+ InlinedForwardGCSafeCopyHelper(dest, src, len);
+ }
+ else
+ {
+ InlinedBackwardGCSafeCopyHelper(dest, src, len);
+ }
+
+ InlinedSetCardsAfterBulkCopyHelper((Object**)dest, len);
+}
+
+#endif // !_ARRAYNATIVE_INL_
diff --git a/src/classlibnative/bcltype/number.cpp b/src/classlibnative/bcltype/number.cpp
index 3f2d63c70e..34169a77ed 100644
--- a/src/classlibnative/bcltype/number.cpp
+++ b/src/classlibnative/bcltype/number.cpp
@@ -1294,14 +1294,6 @@ STRINGREF NumberToString(NUMBER* number, wchar format, int nMaxDigits, NUMFMTREF
STRINGREF sZero=NULL;
// @TODO what if not sequential?
-#ifndef FEATURE_CORECLR
- if (numfmt->iDigitSubstitution == 2) // native digits
- {
- PTRARRAYREF aDigits = numfmt->sNativeDigits;
- if (aDigits!=NULL && aDigits->GetNumComponents()>0)
- sZero=(STRINGREF)aDigits->GetAt(0);
- }
-#endif
// Do the worst case calculation
/* US English - for Double.MinValue.ToString("C99"); we require 514 characters
@@ -2557,51 +2549,6 @@ FCIMPL3_VII(Object*, COMNumber::FormatUInt64, UINT64 value, StringObject* format
}
FCIMPLEND
-#if !defined(FEATURE_CORECLR)
-//
-// Used by base types that are not in mscorlib.dll (such as System.Numerics.BigInteger in System.Core.dll)
-// Note that the allDigits buffer must be fixed across this call or you will introduce a GC Hole.
-//
-FCIMPL4(Object*, COMNumber::FormatNumberBuffer, BYTE* number, StringObject* formatUNSAFE, NumberFormatInfo* numfmtUNSAFE, __in_z wchar_t* allDigits)
-{
- FCALL_CONTRACT;
-
- wchar fmt;
- int digits;
- NUMBER* pNumber;
-
- struct _gc
- {
- STRINGREF refFormat;
- NUMFMTREF refNumFmt;
- STRINGREF refRetString;
- } gc;
-
- gc.refFormat = ObjectToSTRINGREF(formatUNSAFE);
- gc.refNumFmt = (NUMFMTREF)numfmtUNSAFE;
- gc.refRetString = NULL;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
- if (gc.refNumFmt == 0) COMPlusThrowArgumentNull(W("NumberFormatInfo"));
-
- pNumber = (NUMBER*) number;
-
- pNumber->allDigits = allDigits;
-
- fmt = ParseFormatSpecifier(gc.refFormat, &digits);
- if (fmt != 0) {
- gc.refRetString = NumberToString(pNumber, fmt, digits, gc.refNumFmt);
- }
- else {
- gc.refRetString = NumberToStringFormat(pNumber, gc.refFormat, gc.refNumFmt);
- }
- HELPER_METHOD_FRAME_END();
-
- return OBJECTREFToObject(gc.refRetString);
-}
-FCIMPLEND
-
-#endif // !FEATURE_CORECLR
FCIMPL2(FC_BOOL_RET, COMNumber::NumberBufferToDecimal, BYTE* number, DECIMAL* value)
{
diff --git a/src/classlibnative/bcltype/number.h b/src/classlibnative/bcltype/number.h
index 87bab3b9f6..db66435117 100644
--- a/src/classlibnative/bcltype/number.h
+++ b/src/classlibnative/bcltype/number.h
@@ -33,9 +33,6 @@ public:
static FCDECL3(Object*, FormatUInt32, UINT32 value, StringObject* formatUNSAFE, NumberFormatInfo* numfmtUNSAFE);
static FCDECL3_VII(Object*, FormatInt64, INT64 value, StringObject* formatUNSAFE, NumberFormatInfo* numfmtUNSAFE);
static FCDECL3_VII(Object*, FormatUInt64, UINT64 value, StringObject* formatUNSAFE, NumberFormatInfo* numfmtUNSAFE);
-#if !defined(FEATURE_CORECLR)
- static FCDECL4(Object*, FormatNumberBuffer, BYTE* number, StringObject* formatUNSAFE, NumberFormatInfo* numfmtUNSAFE, __in_z wchar_t* allDigits);
-#endif // !FEATURE_CORECLR
static FCDECL2(FC_BOOL_RET, NumberBufferToDecimal, BYTE* number, DECIMAL* value);
static FCDECL2(FC_BOOL_RET, NumberBufferToDouble, BYTE* number, double* value);
diff --git a/src/classlibnative/bcltype/objectnative.cpp b/src/classlibnative/bcltype/objectnative.cpp
index bf65ad1ff5..82b189d5c8 100644
--- a/src/classlibnative/bcltype/objectnative.cpp
+++ b/src/classlibnative/bcltype/objectnative.cpp
@@ -18,13 +18,7 @@
#include "field.h"
#include "object.h"
#include "comsynchronizable.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "eeconfig.h"
-#ifdef FEATURE_REMOTING
-#include "objectclone.h"
-#endif
#include "mdaassistants.h"
@@ -212,11 +206,6 @@ NOINLINE static Object* GetClassHelper(OBJECTREF objRef)
HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, refType);
-#ifdef FEATURE_REMOTING
- if (objRef->IsTransparentProxy())
- refType = CRemotingServices::GetClass(objRef);
- else
-#endif
refType = typeHandle.GetManagedClassObject();
HELPER_METHOD_FRAME_END();
diff --git a/src/classlibnative/bcltype/stringnative.cpp b/src/classlibnative/bcltype/stringnative.cpp
index 1e6b132b17..af6593a6be 100644
--- a/src/classlibnative/bcltype/stringnative.cpp
+++ b/src/classlibnative/bcltype/stringnative.cpp
@@ -160,12 +160,7 @@ FCIMPLEND
inline COMNlsHashProvider * GetCurrentNlsHashProvider()
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
- return curDomain->m_pNlsHashProvider;
-#else
return &COMNlsHashProvider::s_NlsHashProvider;
-#endif // FEATURE_CORECLR
}
FCIMPL3(INT32, COMString::Marvin32HashString, StringObject* thisRefUNSAFE, INT32 strLen, INT64 additionalEntropy) {
diff --git a/src/classlibnative/bcltype/system.cpp b/src/classlibnative/bcltype/system.cpp
index 8bb3409974..c36d2e1066 100644
--- a/src/classlibnative/bcltype/system.cpp
+++ b/src/classlibnative/bcltype/system.cpp
@@ -31,9 +31,6 @@
#include "array.h"
#include "eepolicy.h"
-#if !defined(FEATURE_CORECLR)
-#include "metahost.h"
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_WINDOWSPHONE
Volatile<BOOL> g_fGetPhoneVersionInitialized;
@@ -44,14 +41,37 @@ typedef BOOL (*pfnGetPhoneVersion)(LPOSVERSIONINFO lpVersionInformation);
pfnGetPhoneVersion g_pfnGetPhoneVersion = NULL;
#endif
+typedef void(WINAPI *pfnGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime);
+extern pfnGetSystemTimeAsFileTime g_pfnGetSystemTimeAsFileTime;
+
+void WINAPI InitializeGetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
+{
+ pfnGetSystemTimeAsFileTime func = NULL;
+
+#ifndef FEATURE_PAL
+ HMODULE hKernel32 = WszLoadLibrary(W("kernel32.dll"));
+ if (hKernel32 != NULL)
+ {
+ func = (pfnGetSystemTimeAsFileTime)GetProcAddress(hKernel32, "GetSystemTimePreciseAsFileTime");
+ }
+ if (func == NULL)
+#endif
+ {
+ func = &::GetSystemTimeAsFileTime;
+ }
+
+ g_pfnGetSystemTimeAsFileTime = func;
+ func(lpSystemTimeAsFileTime);
+}
+
+pfnGetSystemTimeAsFileTime g_pfnGetSystemTimeAsFileTime = &InitializeGetSystemTimeAsFileTime;
FCIMPL0(INT64, SystemNative::__GetSystemTimeAsFileTime)
{
FCALL_CONTRACT;
INT64 timestamp;
-
- ::GetSystemTimeAsFileTime((FILETIME*)&timestamp);
+ g_pfnGetSystemTimeAsFileTime((FILETIME*)&timestamp);
#if BIGENDIAN
timestamp = (INT64)(((UINT64)timestamp >> 32) | ((UINT64)timestamp << 32));
@@ -83,20 +103,6 @@ FCIMPLEND;
-#ifndef FEATURE_CORECLR
-INT64 QCALLTYPE SystemNative::GetWorkingSet()
-{
- QCALL_CONTRACT;
-
- DWORD memUsage = 0;
-
- BEGIN_QCALL;
- memUsage = WszGetWorkingSet();
- END_QCALL;
-
- return memUsage;
-}
-#endif // !FEATURE_CORECLR
VOID QCALLTYPE SystemNative::Exit(INT32 exitcode)
{
@@ -312,24 +318,7 @@ FCIMPLEND
FCIMPL0(StringObject*, SystemNative::GetDeveloperPath)
{
-#ifdef FEATURE_FUSION
- FCALL_CONTRACT;
-
- STRINGREF refDevPath = NULL;
- LPWSTR pPath = NULL;
- DWORD lgth = 0;
-
- HELPER_METHOD_FRAME_BEGIN_RET_1(refDevPath);
-
- SystemDomain::System()->GetDevpathW(&pPath, &lgth);
- if(lgth)
- refDevPath = StringObject::NewString(pPath, lgth);
-
- HELPER_METHOD_FRAME_END();
- return (StringObject*)OBJECTREFToObject(refDevPath);
-#else
return NULL;
-#endif
}
FCIMPLEND
@@ -377,24 +366,6 @@ FCIMPL0(StringObject*, SystemNative::GetHostBindingFile);
}
FCIMPLEND
-#ifndef FEATURE_CORECLR
-
-void QCALLTYPE SystemNative::_GetSystemVersion(QCall::StringHandleOnStack retVer)
-{
- QCALL_CONTRACT;
- BEGIN_QCALL;
-
- WCHAR wszVersion[_MAX_PATH];
- DWORD dwVersion = _MAX_PATH;
-
- // Get the version
- IfFailThrow(g_pCLRRuntime->GetVersionString(wszVersion, &dwVersion));
- retVer.Set(wszVersion);
-
- END_QCALL;
-}
-
-#endif
INT32 QCALLTYPE SystemNative::GetProcessorCount()
{
@@ -439,16 +410,7 @@ LPVOID QCALLTYPE SystemNative::GetRuntimeInterfaceImpl(
BEGIN_QCALL;
-#ifdef FEATURE_CORECLR
IfFailThrow(E_NOINTERFACE);
-#else
- HRESULT hr = g_pCLRRuntime->GetInterface(clsid, riid, &pUnk);
-
- if (FAILED(hr))
- hr = g_pCLRRuntime->QueryInterface(riid, &pUnk);
-
- IfFailThrow(hr);
-#endif
END_QCALL;
@@ -560,11 +522,9 @@ void SystemNative::GenericFailFast(STRINGREF refMesgString, EXCEPTIONREF refExce
#ifndef FEATURE_PAL
// If we have the exception object, then try to setup
// the watson bucket if it has any details.
-#ifdef FEATURE_CORECLR
// On CoreCLR, Watson may not be enabled. Thus, we should
// skip this, if required.
if (IsWatsonEnabled())
-#endif // FEATURE_CORECLR
{
BEGIN_SO_INTOLERANT_CODE(pThread);
if ((gc.refExceptionForWatsonBucketing == NULL) || !SetupWatsonBucketsForFailFast(gc.refExceptionForWatsonBucketing))
@@ -649,36 +609,6 @@ FCIMPL2(VOID, SystemNative::FailFastWithException, StringObject* refMessageUNSAF
}
FCIMPLEND
-
-#ifndef FEATURE_CORECLR
-BOOL QCALLTYPE SystemNative::IsCLRHosted()
-{
- QCALL_CONTRACT;
-
- BOOL retVal = false;
- BEGIN_QCALL;
- retVal = (CLRHosted() & CLRHOSTED) != 0;
- END_QCALL;
-
- return retVal;
-}
-
-void QCALLTYPE SystemNative::TriggerCodeContractFailure(ContractFailureKind failureKind, LPCWSTR pMessage, LPCWSTR pCondition, LPCWSTR exceptionAsString)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- GCX_COOP();
-
- EEPolicy::HandleCodeContractFailure(pMessage, pCondition, exceptionAsString);
- // Note: if the host chose to throw an exception, we've returned from this method and
- // will throw that exception in managed code, because it's easier to pass the right parameters there.
-
- END_QCALL;
-}
-#endif // !FEATURE_CORECLR
-
FCIMPL0(FC_BOOL_RET, SystemNative::IsServerGC)
{
FCALL_CONTRACT;
@@ -704,195 +634,9 @@ BOOL QCALLTYPE SystemNative::WinRTSupported()
#endif // FEATURE_COMINTEROP
-// Helper method to retrieve OS Version based on the environment.
-BOOL GetOSVersionForEnvironment(LPOSVERSIONINFO lpVersionInformation)
-{
-#ifdef FEATURE_WINDOWSPHONE
- // Return phone version information if it is available
- if (!g_fGetPhoneVersionInitialized)
- {
- HMODULE hPhoneInfo = WszLoadLibrary(W("phoneinfo.dll"));
- if(hPhoneInfo != NULL)
- g_pfnGetPhoneVersion = (pfnGetPhoneVersion)GetProcAddress(hPhoneInfo, "GetPhoneVersion");
-
- g_fGetPhoneVersionInitialized = true;
- }
-
- if (g_pfnGetPhoneVersion!= NULL)
- return g_pfnGetPhoneVersion(lpVersionInformation);
-#endif // FEATURE_WINDOWSPHONE
-
- return ::GetOSVersion(lpVersionInformation);
-}
-
-
-/*
- * SystemNative::GetOSVersion - Fcall corresponding to System.Environment.GetVersion
- * It calls clr!GetOSVersion to get the real OS version even when running in
- * app compat. Calling kernel32!GetVersionEx() directly will be shimmed and will return the
- * fake OS version. In order to avoid this the call to getVersionEx is made via mscoree.dll.
- * Mscoree.dll resides in system32 dir and is never lied about OS version.
- */
-
-FCIMPL1(FC_BOOL_RET, SystemNative::GetOSVersion, OSVERSIONINFOObject *osVer)
-{
- FCALL_CONTRACT;
-
- OSVERSIONINFO ver;
- ver.dwOSVersionInfoSize = osVer->dwOSVersionInfoSize;
-
- BOOL ret = GetOSVersionForEnvironment(&ver);
-
- if(ret)
- {
- osVer->dwMajorVersion = ver.dwMajorVersion;
- osVer->dwMinorVersion = ver.dwMinorVersion;
- osVer->dwBuildNumber = ver.dwBuildNumber;
- osVer->dwPlatformId = ver.dwPlatformId;
-
- HELPER_METHOD_FRAME_BEGIN_RET_1(osVer);
- SetObjectReference((OBJECTREF*)&(osVer->szCSDVersion), StringObject::NewString(ver.szCSDVersion), GetAppDomain());
- HELPER_METHOD_FRAME_END();
- }
-
- FC_RETURN_BOOL(ret);
-}
-FCIMPLEND
-
-/*
- * SystemNative::GetOSVersionEx - Fcall implementation for System.Environment.GetVersionEx
- * Similar as above except this takes OSVERSIONINFOEX structure as input
- */
-
-FCIMPL1(FC_BOOL_RET, SystemNative::GetOSVersionEx, OSVERSIONINFOEXObject *osVer)
-{
- FCALL_CONTRACT;
-
- OSVERSIONINFOEX ver;
- ver.dwOSVersionInfoSize = osVer->dwOSVersionInfoSize;
-
- BOOL ret = GetOSVersionForEnvironment((OSVERSIONINFO *)&ver);
-
- if(ret)
- {
- osVer->dwMajorVersion = ver.dwMajorVersion;
- osVer->dwMinorVersion = ver.dwMinorVersion;
- osVer->dwBuildNumber = ver.dwBuildNumber;
- osVer->dwPlatformId = ver.dwPlatformId;
- osVer->wServicePackMajor = ver.wServicePackMajor;
- osVer->wServicePackMinor = ver.wServicePackMinor;
- osVer->wSuiteMask = ver.wSuiteMask;
- osVer->wProductType = ver.wProductType;
- osVer->wReserved = ver.wReserved;
-
- HELPER_METHOD_FRAME_BEGIN_RET_1(osVer);
- SetObjectReference((OBJECTREF*)&(osVer->szCSDVersion), StringObject::NewString(ver.szCSDVersion), GetAppDomain());
- HELPER_METHOD_FRAME_END();
- }
-
- FC_RETURN_BOOL(ret);
-}
-FCIMPLEND
-
-
-#ifndef FEATURE_CORECLR
-//
-// SystemNative::LegacyFormatMode - Fcall implementation for System.TimeSpan.LegacyFormatMode
-// checks for the DWORD "TimeSpan_LegacyFormatMode" CLR config option
-//
-FCIMPL0(FC_BOOL_RET, SystemNative::LegacyFormatMode)
-{
- FCALL_CONTRACT;
-
- DWORD flag = 0;
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
- flag = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_TimeSpan_LegacyFormatMode);
- END_SO_INTOLERANT_CODE;
- if (flag)
- FC_RETURN_BOOL(TRUE);
- else
- FC_RETURN_BOOL(FALSE);
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
-#ifndef FEATURE_CORECLR
-//
-// SystemNative::CheckLegacyManagedDeflateStream - Fcall implementation for System.IO.Compression.DeflateStream
-// checks for the DWORD "NetFx45_LegacyManagedDeflateStream" CLR config option
-//
-// Move this into a separate CLRConfigQCallWrapper class once CLRConfig has been refactored!
-//
-FCIMPL0(FC_BOOL_RET, SystemNative::CheckLegacyManagedDeflateStream)
-{
- FCALL_CONTRACT;
-
- DWORD flag = 0;
-
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
- flag = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_NetFx45_LegacyManagedDeflateStream);
- END_SO_INTOLERANT_CODE;
-
- if (flag)
- FC_RETURN_BOOL(TRUE);
- else
- FC_RETURN_BOOL(FALSE);
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
-
-#ifndef FEATURE_CORECLR
-//
-// SystemNative::CheckThrowUnobservedTaskExceptions - Fcall implementation for System.Threading.Tasks.TaskExceptionHolder
-// checks for the DWORD "ThrowUnobservedTaskExceptions" CLR config option
-//
-FCIMPL0(FC_BOOL_RET, SystemNative::CheckThrowUnobservedTaskExceptions)
-{
- FCALL_CONTRACT;
-
- DWORD flag = 0;
-
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
- flag = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_ThrowUnobservedTaskExceptions);
- END_SO_INTOLERANT_CODE;
-
- if (flag)
- FC_RETURN_BOOL(TRUE);
- else
- FC_RETURN_BOOL(FALSE);
-}
-FCIMPLEND
-
-BOOL QCALLTYPE SystemNative::LegacyDateTimeParseMode()
-{
- QCALL_CONTRACT;
-
- BOOL retVal = false;
- BEGIN_QCALL;
- retVal = (BOOL) CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DateTime_NetFX35ParseMode);
- END_QCALL;
-
- return retVal;
-}
-
-//
-// This method used with DateTimeParse to fix the parsing of AM/PM like "1/10 5 AM" case
-//
-BOOL QCALLTYPE SystemNative::EnableAmPmParseAdjustment()
-{
- QCALL_CONTRACT;
-
- BOOL retVal = false;
- BEGIN_QCALL;
- retVal = (BOOL) CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DateTime_NetFX40AmPmParseAdjustment);
- END_QCALL;
-
- return retVal;
-}
-
-#endif // !FEATURE_CORECLR
diff --git a/src/classlibnative/bcltype/system.h b/src/classlibnative/bcltype/system.h
index 9edc595039..986c55b31e 100644
--- a/src/classlibnative/bcltype/system.h
+++ b/src/classlibnative/bcltype/system.h
@@ -74,13 +74,6 @@ public:
static FCDECL0(INT64, __GetSystemTimeAsFileTime);
static FCDECL0(UINT32, GetCurrentProcessorNumber);
static FCDECL0(UINT32, GetTickCount);
- static FCDECL1(FC_BOOL_RET, GetOSVersion, OSVERSIONINFOObject *osVer);
- static FCDECL1(FC_BOOL_RET, GetOSVersionEx, OSVERSIONINFOEXObject *osVer);
-
-#ifndef FEATURE_CORECLR
- static
- INT64 QCALLTYPE GetWorkingSet();
-#endif // !FEATURE_CORECLR
static
void QCALLTYPE Exit(INT32 exitcode);
@@ -96,10 +89,6 @@ public:
static FCDECL1(VOID, FailFast, StringObject* refMessageUNSAFE);
static FCDECL2(VOID, FailFastWithExitCode, StringObject* refMessageUNSAFE, UINT exitCode);
static FCDECL2(VOID, FailFastWithException, StringObject* refMessageUNSAFE, ExceptionObject* refExceptionUNSAFE);
-#ifndef FEATURE_CORECLR
- static void QCALLTYPE TriggerCodeContractFailure(ContractFailureKind failureKind, LPCWSTR pMessage, LPCWSTR pCondition, LPCWSTR exceptionAsText);
- static BOOL QCALLTYPE IsCLRHosted();
-#endif // !FEATURE_CORECLR
static FCDECL0(StringObject*, GetDeveloperPath);
static FCDECL1(Object*, _GetEnvironmentVariable, StringObject* strVar);
@@ -123,23 +112,10 @@ public:
// Return a method info for the method were the exception was thrown
static FCDECL1(ReflectMethodObject*, GetMethodFromStackTrace, ArrayBase* pStackTraceUNSAFE);
-#ifndef FEATURE_CORECLR
- // Functions on the System.TimeSpan class
- static FCDECL0(FC_BOOL_RET, LegacyFormatMode);
- // Function on the DateTime
- static BOOL QCALLTYPE EnableAmPmParseAdjustment();
- static BOOL QCALLTYPE LegacyDateTimeParseMode();
-#endif // !FEATURE_CORECLR
// Move this into a separate CLRConfigQCallWrapper class once CLRConfif has been refactored:
-#ifndef FEATURE_CORECLR
- static FCDECL0(FC_BOOL_RET, CheckLegacyManagedDeflateStream);
-#endif // !FEATURE_CORECLR
-#ifndef FEATURE_CORECLR
- static FCDECL0(FC_BOOL_RET, CheckThrowUnobservedTaskExceptions);
-#endif // !FEATURE_CORECLR
private:
// Common processing code for FailFast
diff --git a/src/classlibnative/float/floatdouble.cpp b/src/classlibnative/float/floatdouble.cpp
index d9603c0636..6f593e503c 100644
--- a/src/classlibnative/float/floatdouble.cpp
+++ b/src/classlibnative/float/floatdouble.cpp
@@ -9,8 +9,6 @@
#include "floatdouble.h"
-#define IS_DBL_INFINITY(x) (((*((INT64*)((void*)&x))) & I64(0x7FFFFFFFFFFFFFFF)) == I64(0x7FF0000000000000))
-
// The default compilation mode is /fp:precise, which disables floating-point intrinsics. This
// default compilation mode has previously caused performance regressions in floating-point code.
// We enable /fp:fast semantics for the majority of the math functions, as it will speed up performance
@@ -86,13 +84,6 @@ FCIMPLEND
FCIMPL2_VV(double, COMDouble::Atan2, double y, double x)
FCALL_CONTRACT;
- // atan2(+/-INFINITY, +/-INFINITY) produces +/-0.78539816339744828 (x is +INFINITY) and
- // +/-2.3561944901923448 (x is -INFINITY) instead of the expected value of NaN. We handle
- // that case here ourselves.
- if (IS_DBL_INFINITY(y) && IS_DBL_INFINITY(x)) {
- return (double)(y / x);
- }
-
return (double)atan2(y, x);
FCIMPLEND
@@ -174,24 +165,6 @@ FCIMPLEND
FCIMPL2_VV(double, COMDouble::Pow, double x, double y)
FCALL_CONTRACT;
- // The CRT version of pow preserves the NaN payload of x over the NaN payload of y.
-
- if(_isnan(y)) {
- return y; // IEEE 754-2008: NaN payload must be preserved
- }
-
- if(_isnan(x)) {
- return x; // IEEE 754-2008: NaN payload must be preserved
- }
-
- // The CRT version of pow does not return NaN for pow(-1.0, +/-INFINITY) and
- // instead returns +1.0.
-
- if(IS_DBL_INFINITY(y) && (x == -1.0)) {
- INT64 result = CLR_NAN_64;
- return (*((double*)((INT64*)&result)));
- }
-
return (double)pow(x, y);
FCIMPLEND
diff --git a/src/classlibnative/float/floatsingle.cpp b/src/classlibnative/float/floatsingle.cpp
index 7e2ea0adc6..c7b7d4126b 100644
--- a/src/classlibnative/float/floatsingle.cpp
+++ b/src/classlibnative/float/floatsingle.cpp
@@ -9,18 +9,12 @@
#include "floatsingle.h"
-#define IS_FLT_INFINITY(x) (((*((INT32*)((void*)&x))) & 0x7FFFFFFF) == 0x7F800000)
-
// Windows x86 and Windows ARM/ARM64 may not define _isnanf() or _copysignf() but they do
// define _isnan() and _copysign(). We will redirect the macros to these other functions if
// the macro is not defined for the platform. This has the side effect of a possible implicit
// upcasting for arguments passed in and an explicit downcasting for the _copysign() call.
#if (defined(_TARGET_X86_) || defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)) && !defined(FEATURE_PAL)
-#if !defined(_isnanf)
-#define _isnanf _isnan
-#endif
-
#if !defined(_copysignf)
#define _copysignf (float)_copysign
#endif
@@ -49,7 +43,7 @@
/*=====================================Abs=====================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Abs, float x)
+FCIMPL1_V(float, COMSingle::Abs, float x)
FCALL_CONTRACT;
return (float)fabsf(x);
@@ -58,7 +52,7 @@ FCIMPLEND
/*=====================================Acos=====================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Acos, float x)
+FCIMPL1_V(float, COMSingle::Acos, float x)
FCALL_CONTRACT;
return (float)acosf(x);
@@ -67,7 +61,7 @@ FCIMPLEND
/*=====================================Asin=====================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Asin, float x)
+FCIMPL1_V(float, COMSingle::Asin, float x)
FCALL_CONTRACT;
return (float)asinf(x);
@@ -76,7 +70,7 @@ FCIMPLEND
/*=====================================Atan=====================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Atan, float x)
+FCIMPL1_V(float, COMSingle::Atan, float x)
FCALL_CONTRACT;
return (float)atanf(x);
@@ -85,23 +79,16 @@ FCIMPLEND
/*=====================================Atan2====================================
**
==============================================================================*/
-FCIMPL2(float, COMSingle::Atan2, float y, float x)
+FCIMPL2_VV(float, COMSingle::Atan2, float y, float x)
FCALL_CONTRACT;
- // atan2f(+/-INFINITY, +/-INFINITY) produces +/-0.785398163f (x is +INFINITY) and
- // +/-2.35619449f (x is -INFINITY) instead of the expected value of NaN. We handle
- // that case here ourselves.
- if (IS_FLT_INFINITY(y) && IS_FLT_INFINITY(x)) {
- return (float)(y / x);
- }
-
return (float)atan2f(y, x);
FCIMPLEND
/*====================================Ceil======================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Ceil, float x)
+FCIMPL1_V(float, COMSingle::Ceil, float x)
FCALL_CONTRACT;
return (float)ceilf(x);
@@ -110,7 +97,7 @@ FCIMPLEND
/*=====================================Cos======================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Cos, float x)
+FCIMPL1_V(float, COMSingle::Cos, float x)
FCALL_CONTRACT;
return (float)cosf(x);
@@ -119,7 +106,7 @@ FCIMPLEND
/*=====================================Cosh=====================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Cosh, float x)
+FCIMPL1_V(float, COMSingle::Cosh, float x)
FCALL_CONTRACT;
return (float)coshf(x);
@@ -128,7 +115,7 @@ FCIMPLEND
/*=====================================Exp======================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Exp, float x)
+FCIMPL1_V(float, COMSingle::Exp, float x)
FCALL_CONTRACT;
return (float)expf(x);
@@ -137,7 +124,7 @@ FCIMPLEND
/*====================================Floor=====================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Floor, float x)
+FCIMPL1_V(float, COMSingle::Floor, float x)
FCALL_CONTRACT;
return (float)floorf(x);
@@ -146,7 +133,7 @@ FCIMPLEND
/*=====================================Log======================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Log, float x)
+FCIMPL1_V(float, COMSingle::Log, float x)
FCALL_CONTRACT;
return (float)logf(x);
@@ -155,7 +142,7 @@ FCIMPLEND
/*====================================Log10=====================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Log10, float x)
+FCIMPL1_V(float, COMSingle::Log10, float x)
FCALL_CONTRACT;
return (float)log10f(x);
@@ -173,34 +160,16 @@ FCIMPLEND
/*=====================================Pow======================================
**
==============================================================================*/
-FCIMPL2(float, COMSingle::Pow, float x, float y)
+FCIMPL2_VV(float, COMSingle::Pow, float x, float y)
FCALL_CONTRACT;
- // The CRT version of pow preserves the NaN payload of x over the NaN payload of y.
-
- if(_isnanf(y)) {
- return y; // IEEE 754-2008: NaN payload must be preserved
- }
-
- if(_isnanf(x)) {
- return x; // IEEE 754-2008: NaN payload must be preserved
- }
-
- // The CRT version of powf does not return NaN for powf(-1.0f, +/-INFINITY) and
- // instead returns +1.0f.
-
- if(IS_FLT_INFINITY(y) && (x == -1.0f)) {
- INT32 result = CLR_NAN_32;
- return (*((float*)((INT32*)&result)));
- }
-
return (float)powf(x, y);
FCIMPLEND
/*====================================Round=====================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Round, float x)
+FCIMPL1_V(float, COMSingle::Round, float x)
FCALL_CONTRACT;
// If the number has no fractional part do nothing
@@ -225,7 +194,7 @@ FCIMPLEND
/*=====================================Sin======================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Sin, float x)
+FCIMPL1_V(float, COMSingle::Sin, float x)
FCALL_CONTRACT;
return (float)sinf(x);
@@ -234,7 +203,7 @@ FCIMPLEND
/*=====================================Sinh=====================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Sinh, float x)
+FCIMPL1_V(float, COMSingle::Sinh, float x)
FCALL_CONTRACT;
return (float)sinhf(x);
@@ -243,7 +212,7 @@ FCIMPLEND
/*=====================================Sqrt=====================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Sqrt, float x)
+FCIMPL1_V(float, COMSingle::Sqrt, float x)
FCALL_CONTRACT;
return (float)sqrtf(x);
@@ -252,7 +221,7 @@ FCIMPLEND
/*=====================================Tan======================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Tan, float x)
+FCIMPL1_V(float, COMSingle::Tan, float x)
FCALL_CONTRACT;
return (float)tanf(x);
@@ -261,7 +230,7 @@ FCIMPLEND
/*=====================================Tanh=====================================
**
==============================================================================*/
-FCIMPL1(float, COMSingle::Tanh, float x)
+FCIMPL1_V(float, COMSingle::Tanh, float x)
FCALL_CONTRACT;
return (float)tanhf(x);
diff --git a/src/classlibnative/inc/calendardata.h b/src/classlibnative/inc/calendardata.h
deleted file mode 100644
index f30660ee99..0000000000
--- a/src/classlibnative/inc/calendardata.h
+++ /dev/null
@@ -1,165 +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.
-////////////////////////////////////////////////////////////////////////////
-//
-// Class: CalendarData
-//
-
-//
-// Purpose: This module implements the methods of the CalendarData
-// class. These methods are the helper functions for the
-// Locale class.
-//
-// Date: July 4, 2007
-//
-////////////////////////////////////////////////////////////////////////////
-
-#ifndef _CALENDARDATA_H
-#define _CALENDARDATA_H
-
-//
-// Data store for the calendar data.
-//
-class CalendarData : Object
-{
-
- //
- // WARNING: These properties should stay in-sync with CalendarData.cs
- //
-private:
- // Identity
- STRINGREF sNativeName ; // Calendar Name for the locale (fallback for calendar only records)
-
- // Formats
- PTRARRAYREF saShortDates ; // Short Data format, default first
- PTRARRAYREF saYearMonths ; // Year/Month Data format, default first
- PTRARRAYREF saLongDates ; // Long Data format, default first
- STRINGREF sMonthDay ; // Month/Day format
-
- // Calendar Parts Names
- PTRARRAYREF saEraNames ; // Names of Eras
- PTRARRAYREF saAbbrevEraNames ; // Abbreviated Era Names
- PTRARRAYREF saAbbrevEnglishEraNames ; // Abbreviated Era Names in English
- PTRARRAYREF saDayNames ; // Day Names, null to use locale data, starts on Sunday
- PTRARRAYREF saAbbrevDayNames ; // Abbrev Day Names, null to use locale data, starts on Sunday
- PTRARRAYREF saSuperShortDayNames ; // Super short Day of week names
- PTRARRAYREF saMonthNames ; // Month Names (13)
- PTRARRAYREF saAbbrevMonthNames ; // Abbrev Month Names (13)
- PTRARRAYREF saMonthGenitiveNames ; // Genitive Month Names (13)
- PTRARRAYREF saAbbrevMonthGenitiveNames; // Genitive Abbrev Month Names (13)
- PTRARRAYREF saLeapYearMonthNames ; // Multiple strings for the month names in a leap year.
-
- // Year, digits have to be at end to make marshaller happy?
- INT32 iTwoDigitYearMax ; // Max 2 digit year (for Y2K bug data entry)
- INT32 iCurrentEra ; // our current era #
-
- // Use overrides?
- CLR_BOOL bUseUserOverrides ; // True if we want user overrides.
-
- //
- // Helpers
- //
- static BOOL CallGetCalendarInfoEx(LPCWSTR localeName, int calendar, int calType, STRINGREF* pOutputStrRef);
- static BOOL CallGetCalendarInfoEx(LPCWSTR localeName, int calendar, int calType, INT32* pOutputInt32);
- static BOOL GetCalendarDayInfo(LPCWSTR localeName, int calendar, int calType, PTRARRAYREF* pOutputStrings);
- static BOOL GetCalendarMonthInfo(LPCWSTR localeName, int calendar, int calType, PTRARRAYREF* pOutputStrings);
-// TODO: NLS Arrowhead -Windows 7 If the OS had data this could use it, but Windows doesn't expose data for eras in enough detail
-// static BOOL GetCalendarEraInfo(LPCWSTR localeName, int calendar, PTRARRAYREF* pOutputEras);
- static BOOL CallEnumCalendarInfo(__in_z LPCWSTR localeName, __in int calendar, __in int calType,
- __in int lcType, __inout PTRARRAYREF* pOutputStrings);
-
- static void CheckSpecialCalendar(INT32* pCalendarInt, StackSString* pLocaleNameStackBuffer);
-public:
- //
- // ecall function for methods in CalendarData
- //
- static FCDECL1(INT32, nativeGetTwoDigitYearMax, INT32 nValue);
- static FCDECL3(FC_BOOL_RET, nativeGetCalendarData, CalendarData* calendarDataUNSAFE, StringObject* pLocaleNameUNSAFE, INT32 calendar);
- static FCDECL3(INT32, nativeGetCalendars, StringObject* pLocaleNameUNSAFE, CLR_BOOL bUseOverrides, I4Array* calendars);
- static FCDECL3(Object*, nativeEnumTimeFormats, StringObject* pLocaleNameUNSAFE, INT32 dwFlags, CLR_BOOL useUserOverride);
-};
-
-typedef CalendarData* CALENDARDATAREF;
-
-#ifndef LOCALE_RETURN_GENITIVE_NAMES
-#define LOCALE_RETURN_GENITIVE_NAMES 0x10000000 //Flag to return the Genitive forms of month names
-#endif
-
-#ifndef CAL_RETURN_GENITIVE_NAMES
-#define CAL_RETURN_GENITIVE_NAMES LOCALE_RETURN_GENITIVE_NAMES // return genitive forms of month names
-#endif
-
-#ifndef CAL_SERASTRING
-#define CAL_SERASTRING 0x00000004 // era name for IYearOffsetRanges, eg A.D.
-#endif
-
-#ifndef CAL_SMONTHDAY
-#define CAL_SMONTHDAY 0x00000038 // Month/day pattern (reserve for potential inclusion in a future version)
-#define CAL_SABBREVERASTRING 0x00000039 // Abbreviated era string (eg: AD)
-#endif
-
-#define RESERVED_CAL_JULIAN 13 // Julian calendar (data looks like GREGORIAN_US)
-#define RESERVED_CAL_JAPANESELUNISOLAR 14 // Japaenese Lunisolar calendar (data looks like CAL_JAPANESE)
-#define RESERVED_CAL_CHINESELUNISOLAR 15 // Algorithmic
-#define RESERVED_CAL_SAKA 16 // reserved to match Office but not implemented in our code
-#define RESERVED_CAL_LUNAR_ETO_CHN 17 // reserved to match Office but not implemented in our code
-#define RESERVED_CAL_LUNAR_ETO_KOR 18 // reserved to match Office but not implemented in our code
-#define RESERVED_CAL_LUNAR_ETO_ROKUYOU 19 // reserved to match Office but not implemented in our code
-#define RESERVED_CAL_KOREANLUNISOLAR 20 // Algorithmic
-#define RESERVED_CAL_TAIWANLUNISOLAR 21 // Algorithmic
-#define RESERVED_CAL_PERSIAN 22 // Algorithmic
-
-// These are vista properties
-#ifndef CAL_UMALQURA
-#define CAL_UMALQURA 23
-#endif
-
-#ifndef CAL_SSHORTESTDAYNAME1
-#define CAL_SSHORTESTDAYNAME1 0x00000031
-#define CAL_SSHORTESTDAYNAME2 0x00000032
-#define CAL_SSHORTESTDAYNAME3 0x00000033
-#define CAL_SSHORTESTDAYNAME4 0x00000034
-#define CAL_SSHORTESTDAYNAME5 0x00000035
-#define CAL_SSHORTESTDAYNAME6 0x00000036
-#define CAL_SSHORTESTDAYNAME7 0x00000037
-#endif
-
-#ifndef CAL_ITWODIGITYEARMAX
- #define CAL_ITWODIGITYEARMAX 0x00000030 // two digit year max
-#endif // CAL_ITWODIGITYEARMAX
-#ifndef CAL_RETURN_NUMBER
- #define CAL_RETURN_NUMBER 0x20000000 // return number instead of string
-#endif // CAL_RETURN_NUMBER
-
-#ifndef LOCALE_SNAME
-#define LOCALE_SNAME 0x0000005c // locale name (ie: en-us)
-#define LOCALE_SDURATION 0x0000005d // time duration format
-#define LOCALE_SKEYBOARDSTOINSTALL 0x0000005e
-#define LOCALE_SSHORTESTDAYNAME1 0x00000060 // Shortest day name for Monday
-#define LOCALE_SSHORTESTDAYNAME2 0x00000061 // Shortest day name for Tuesday
-#define LOCALE_SSHORTESTDAYNAME3 0x00000062 // Shortest day name for Wednesday
-#define LOCALE_SSHORTESTDAYNAME4 0x00000063 // Shortest day name for Thursday
-#define LOCALE_SSHORTESTDAYNAME5 0x00000064 // Shortest day name for Friday
-#define LOCALE_SSHORTESTDAYNAME6 0x00000065 // Shortest day name for Saturday
-#define LOCALE_SSHORTESTDAYNAME7 0x00000066 // Shortest day name for Sunday
-#define LOCALE_SISO639LANGNAME2 0x00000067 // 3 character ISO abbreviated language name
-#define LOCALE_SISO3166CTRYNAME2 0x00000068 // 3 character ISO country name
-#define LOCALE_SNAN 0x00000069 // Not a Number
-#define LOCALE_SPOSINFINITY 0x0000006a // + Infinity
-#define LOCALE_SNEGINFINITY 0x0000006b // - Infinity
-#define LOCALE_SSCRIPTS 0x0000006c // Typical scripts in the locale
-#define LOCALE_SPARENT 0x0000006d // Fallback name for resources
-#define LOCALE_SCONSOLEFALLBACKNAME 0x0000006e // Fallback name for within the console
-#define LOCALE_SLANGDISPLAYNAME 0x0000006f // Lanugage Display Name for a language
-#endif // LOCALE_SNAME
-#ifndef LOCALE_SSHORTTIME
-#define LOCALE_SSHORTTIME 0x00000079 // short time format (ie: no seconds, just h:mm)
-#endif // LOCALE_SSHORTTIME
-
-#ifndef TIME_NOSECONDS
-#define TIME_NOSECONDS 0x00000002 // do not use seconds
-#endif
-
-#endif
-
diff --git a/src/classlibnative/inc/floatsingle.h b/src/classlibnative/inc/floatsingle.h
index f8a1dda0fd..8296e2d37a 100644
--- a/src/classlibnative/inc/floatsingle.h
+++ b/src/classlibnative/inc/floatsingle.h
@@ -10,26 +10,26 @@
class COMSingle {
public:
- FCDECL1(static float, Abs, float x);
- FCDECL1(static float, Acos, float x);
- FCDECL1(static float, Asin, float x);
- FCDECL1(static float, Atan, float x);
- FCDECL2(static float, Atan2, float y, float x);
- FCDECL1(static float, Ceil, float x);
- FCDECL1(static float, Cos, float x);
- FCDECL1(static float, Cosh, float x);
- FCDECL1(static float, Exp, float x);
- FCDECL1(static float, Floor, float x);
- FCDECL1(static float, Log, float x);
- FCDECL1(static float, Log10, float x);
+ FCDECL1_V(static float, Abs, float x);
+ FCDECL1_V(static float, Acos, float x);
+ FCDECL1_V(static float, Asin, float x);
+ FCDECL1_V(static float, Atan, float x);
+ FCDECL2_VV(static float, Atan2, float y, float x);
+ FCDECL1_V(static float, Ceil, float x);
+ FCDECL1_V(static float, Cos, float x);
+ FCDECL1_V(static float, Cosh, float x);
+ FCDECL1_V(static float, Exp, float x);
+ FCDECL1_V(static float, Floor, float x);
+ FCDECL1_V(static float, Log, float x);
+ FCDECL1_V(static float, Log10, float x);
FCDECL1(static float, ModF, float* iptr);
- FCDECL2(static float, Pow, float x, float y);
- FCDECL1(static float, Round, float x);
- FCDECL1(static float, Sin, float x);
- FCDECL1(static float, Sinh, float x);
- FCDECL1(static float, Sqrt, float x);
- FCDECL1(static float, Tan, float x);
- FCDECL1(static float, Tanh, float x);
+ FCDECL2_VV(static float, Pow, float x, float y);
+ FCDECL1_V(static float, Round, float x);
+ FCDECL1_V(static float, Sin, float x);
+ FCDECL1_V(static float, Sinh, float x);
+ FCDECL1_V(static float, Sqrt, float x);
+ FCDECL1_V(static float, Tan, float x);
+ FCDECL1_V(static float, Tanh, float x);
};
#endif // _FLOATSINGLE_H_
diff --git a/src/classlibnative/inc/nlsinfo.h b/src/classlibnative/inc/nlsinfo.h
index a5dc13f9a8..505827bc90 100644
--- a/src/classlibnative/inc/nlsinfo.h
+++ b/src/classlibnative/inc/nlsinfo.h
@@ -18,10 +18,6 @@
#ifndef _NLSINFO_H_
#define _NLSINFO_H_
-#define DEFAULT_SORT_VERSION 0
-#define SORT_VERSION_WHIDBEY 0x00001000
-#define SORT_VERSION_V4 0x00060101
-
//
//This structure must map 1-for-1 with the InternalDataItem structure in
//System.Globalization.EncodingTable.
@@ -43,80 +39,22 @@ struct CodePageDataItem {
const char * names;
};
-// Normalization
-typedef BOOL (*PFN_NORMALIZATION_IS_NORMALIZED_STRING)
- ( int NormForm, LPCWSTR lpInString, int cchInString);
-
-typedef int (*PFN_NORMALIZATION_NORMALIZE_STRING)
- ( int NormForm, LPCWSTR lpInString, int cchInString, LPWSTR lpOutString, int cchOutString);
-
-typedef BYTE* (*PFN_NORMALIZATION_INIT_NORMALIZATION)
- ( int NormForm, BYTE* pTableData);
-
-////////////////////////////////////////////////////////////////////////////
-//
-// Forward declarations
-//
-////////////////////////////////////////////////////////////////////////////
-
-class CharTypeTable;
-class CasingTable;
-class SortingTable;
-class NativeTextInfo;
-class CultureDataBaseObject;
-
-class COMNlsInfo {
-
+class COMNlsInfo
+{
public:
-#ifdef FEATURE_SYNTHETIC_CULTURES
- static INT32 WstrToInteger4(__in_z LPCWSTR wstrLocale, __in int Radix);
-#endif // FEATURE_SYNTHETIC_CULTURES
- static INT32 GetCHTLanguage();
- static INT32 CallGetSystemDefaultUILanguage();
static INT32 CallGetUserDefaultUILanguage();
- static LANGID GetDownLevelSystemDefaultUILanguage();
-
- //
- // Native helper functions for methods in CultureInfo.
- //
- static BOOL QCALLTYPE InternalGetDefaultLocaleName(INT32 langType, QCall::StringHandleOnStack defaultLocaleName);
- static BOOL QCALLTYPE InternalGetUserDefaultUILanguage(QCall::StringHandleOnStack userDefaultUiLanguage);
- static BOOL QCALLTYPE InternalGetSystemDefaultUILanguage(QCall::StringHandleOnStack systemDefaultUiLanguage);
-
-// Added but disabled from desktop in .NET 4.0, stayed disabled in .NET 4.5
-#ifdef FEATURE_CORECLR
- static FCDECL0(Object*, nativeGetResourceFallbackArray);
-#endif
//
// Native helper functions for methods in DateTimeFormatInfo
//
static FCDECL1(FC_BOOL_RET, nativeSetThreadLocale, StringObject* localeNameUNSAFE);
- static FCDECL2(Object*, nativeGetLocaleInfoEx, StringObject* localeNameUNSAFE, INT32 lcType);
- static FCDECL2(INT32, nativeGetLocaleInfoExInt, StringObject* localeNameUNSAFE, INT32 lcType);
//
// Native helper functions for CultureData
//
- static FCDECL1(FC_BOOL_RET, nativeInitCultureData, CultureDataBaseObject *data);
- static FCDECL3(FC_BOOL_RET, nativeGetNumberFormatInfoValues, StringObject* localeNameUNSAFE, NumberFormatInfo* nfi, CLR_BOOL useUserOverride);
- static FCDECL1(Object*, LCIDToLocaleName, LCID lcid);
- static FCDECL1(INT32, LocaleNameToLCID, StringObject* localeNameUNSAFE);
- static INT32 QCALLTYPE InternalCompareString (INT_PTR handle, INT_PTR handleOrigin, LPCWSTR localeName, LPCWSTR string1, INT32 offset1, INT32 length1, LPCWSTR string2, INT32 offset2, INT32 length2, INT32 flags);
- static INT32 QCALLTYPE InternalGetGlobalizedHashCode(INT_PTR handle, INT_PTR handleOrigin, LPCWSTR localeName, LPCWSTR pString, INT32 length, INT32 dwFlagsIn, BOOL bForceRandomizedHashing, INT64 additionalEntropy);
-
- static BOOL QCALLTYPE InternalIsSortable(INT_PTR handle, INT_PTR handleOrigin, LPCWSTR localeName, LPCWSTR pString, INT32 length);
- static INT_PTR QCALLTYPE InternalInitSortHandle(LPCWSTR localeName, INT_PTR* handleOrigin);
- static INT_PTR InitSortHandleHelper(LPCWSTR localeName, INT_PTR* handleOrigin);
- static INT_PTR InternalInitOsSortHandle(LPCWSTR localeName, INT_PTR* handleOrigin);
-#ifndef FEATURE_CORECLR
- static INT_PTR InternalInitVersionedSortHandle(LPCWSTR localeName, INT_PTR* handleOrigin);
- static INT_PTR InternalInitVersionedSortHandle(LPCWSTR localeName, INT_PTR* handleOrigin, DWORD sortVersion);
- static DWORD QCALLTYPE InternalGetSortVersion();
-#endif
- static BOOL QCALLTYPE InternalGetNlsVersionEx(INT_PTR handle, INT_PTR handleOrigin, LPCWSTR lpLocaleName, NLSVERSIONINFOEX * lpVersionInformation);
+ static INT32 QCALLTYPE InternalGetGlobalizedHashCode(INT_PTR handle, LPCWSTR localeName, LPCWSTR pString, INT32 length, INT32 dwFlagsIn, INT64 additionalEntropy);
//
// Native helper function for methods in EncodingTable
@@ -124,103 +62,6 @@ public:
static FCDECL0(INT32, nativeGetNumEncodingItems);
static FCDECL0(EncodingDataItem *, nativeGetEncodingTableDataPointer);
static FCDECL0(CodePageDataItem *, nativeGetCodePageTableDataPointer);
-#if FEATURE_CODEPAGES_FILE
- static FCDECL3(LPVOID, nativeCreateOpenFileMapping,
- StringObject* inSectionNameUNSAFE, int inBytesToAllocate, HANDLE *mappedFile);
-#endif // FEATURE_CODEPAGES_FILE
-
- //
- // Native helper function for methods in CharacterInfo
- //
- static FCDECL0(void, AllocateCharTypeTable);
-
- //
- // Native helper function for methods in TextInfo
- //
- static FCDECL5(FC_CHAR_RET, InternalChangeCaseChar, INT_PTR handle, INT_PTR handleOrigin, StringObject* localeNameUNSAFE, CLR_CHAR wch, CLR_BOOL bIsToUpper);
- static FCDECL5(Object*, InternalChangeCaseString, INT_PTR handle, INT_PTR handleOrigin, StringObject* localeNameUNSAFE, StringObject* pString, CLR_BOOL bIsToUpper);
- static FCDECL6(INT32, InternalGetCaseInsHash, INT_PTR handle, INT_PTR handleOrigin, StringObject* localeNameUNSAFE, LPVOID strA, CLR_BOOL bForceRandomizedHashing, INT64 additionalEntropy);
- static INT32 QCALLTYPE InternalCompareStringOrdinalIgnoreCase(LPCWSTR string1, INT32 index1, LPCWSTR string2, INT32 index2, INT32 length1, INT32 length2);
-
- static BOOL QCALLTYPE InternalTryFindStringOrdinalIgnoreCase(
- __in DWORD dwFindNLSStringFlags, // mutually exclusive flags: FIND_FROMSTART, FIND_STARTSWITH, FIND_FROMEND, FIND_ENDSWITH
- __in_ecount(cchSource) LPCWSTR lpStringSource, // the string we search in
- __in int cchSource, // number of characters lpStringSource after sourceIndex
- __in int sourceIndex, // index from where the search will start in lpStringSource
- __in_ecount(cchValue) LPCWSTR lpStringValue, // the string we search for
- __in int cchValue,
- __out int* foundIndex); // the index in lpStringSource where we found lpStringValue
-
- //
- // Native helper function for methods in Normalization
- //
- static FCDECL6(int, nativeNormalizationNormalizeString,
- int NormForm, int& iError,
- StringObject* inString, int inLength,
- CHARArray* outChars, int outLength);
- static FCDECL4(FC_BOOL_RET, nativeNormalizationIsNormalizedString,
- int NormForm, int& iError,
- StringObject* inString, int cwLength);
-
- static void QCALLTYPE nativeNormalizationInitNormalization(int NormForm, BYTE* pTableData);
-
- //
- // QCalls prototype
- //
-
- static int QCALLTYPE nativeEnumCultureNames(INT32 cultureTypes, QCall::ObjectHandleOnStack retStringArray);
-
- static int QCALLTYPE InternalFindNLSStringEx(
- __in_opt INT_PTR handle, // optional sort handle
- __in_opt INT_PTR handleOrigin, // optional pointer to the native function that created the sort handle
- __in_z LPCWSTR lpLocaleName, // locale name
- __in int dwFindNLSStringFlags, // search falg
- __in_ecount(cchSource) LPCWSTR lpStringSource, // the string we search in
- __in int cchSource, // number of characters lpStringSource after sourceIndex
- __in int sourceIndex, // index from where the search will start in lpStringSource
- __in_ecount(cchValue) LPCWSTR lpStringValue, // the string we search for
- __in int cchValue); // length of the string we search for
-
- static int QCALLTYPE InternalGetSortKey(
- __in_opt INT_PTR handle, // PSORTHANDLE
- __in_opt INT_PTR handleOrigin, // optional pointer to the native function that created the sort handle
- __in_z LPCWSTR pLocaleName, // locale name
- __in int flags, // flags
- __in_ecount(cchSource) LPCWSTR pStringSource, // Source string
- __in int cchSource, // number of characters in lpStringSource
- __in_ecount(cchTarget) PBYTE pTarget, // Target data buffer (may be null to count)
- __in int cchTarget); // Character count for target buffer
-
-
-private:
-
- //
- // Internal helper functions.
- //
- static LPVOID internalEnumSystemLocales(DWORD dwFlags);
- static INT32 CompareOrdinal(__in_ecount(Length1) WCHAR* strAChars, int Length1, __in_ecount(Length2) WCHAR* strBChars, int Length2 );
- static INT32 FastIndexOfString(__in WCHAR *sourceString, INT32 startIndex, INT32 endIndex, __in_ecount(patternLength) WCHAR *pattern, INT32 patternLength);
- static INT32 FastIndexOfStringInsensitive(__in WCHAR *sourceString, INT32 startIndex, INT32 endIndex, __in_ecount(patternLength) WCHAR *pattern, INT32 patternLength);
- static INT32 FastLastIndexOfString(__in WCHAR *sourceString, INT32 startIndex, INT32 endIndex, __in_ecount(patternLength) WCHAR *pattern, INT32 patternLength);
- static INT32 FastLastIndexOfStringInsensitive(__in WCHAR *sourceString, INT32 startIndex, INT32 endIndex, __in_ecount(patternLength) WCHAR *pattern, INT32 patternLength);
-
- static BOOL GetNativeDigitsFromWin32(LPCWSTR locale, PTRARRAYREF* pOutputStrAry, BOOL useUserOverride);
- static BOOL CallGetLocaleInfoEx(LPCWSTR locale, int lcType, STRINGREF* pOutputStrRef, BOOL useUserOverride);
- static BOOL CallGetLocaleInfoEx(LPCWSTR locale, int lcType, INT32* pOutputInt32, BOOL useUserOverride);
-
- static BOOL IsWindows7();
-
- //
- // Definitions.
- //
-
-#ifndef FEATURE_COREFX_GLOBALIZATION
- // Normalization
- static HMODULE m_hNormalization;
- static PFN_NORMALIZATION_IS_NORMALIZED_STRING m_pfnNormalizationIsNormalizedStringFunc;
- static PFN_NORMALIZATION_NORMALIZE_STRING m_pfnNormalizationNormalizeStringFunc;
- static PFN_NORMALIZATION_INIT_NORMALIZATION m_pfnNormalizationInitNormalizationFunc;
-#endif
private:
//
@@ -231,8 +72,6 @@ private:
const static int m_nCodePageTableItems;
const static CodePageDataItem CodePageDataTable[];
-
- static INT_PTR EnsureValidSortHandle(INT_PTR handle, INT_PTR handleOrigin, LPCWSTR localeName);
};
-#endif // _NLSINFO_H_
+#endif // _NLSINFO_H_ \ No newline at end of file
diff --git a/src/classlibnative/inc/nlstable.h b/src/classlibnative/inc/nlstable.h
deleted file mode 100644
index b5f5a4bca6..0000000000
--- a/src/classlibnative/inc/nlstable.h
+++ /dev/null
@@ -1,121 +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.
-
-// ==++==
-//
-
-//
-
-//
-// TODO: NLS Arrowhead - when we have win7 unicode support this can "go away"
-// ==--==
-#ifndef _NLSTABLE_H
-#define _NLSTABLE_H
-
-////////////////////////////////////////////////////////////////////////////
-//
-// Class: NLSTable
-//
-// Purpose: The base class for NLS+ table. This class provides the utility
-// functions to open and map a view of NLS+ data files.
-//
-// Date: August 31, 1999
-//
-////////////////////////////////////////////////////////////////////////////
-
-typedef LPWORD P844_TABLE; // ptr to 8:4:4 table
-
-//
-// Macros For High and Low Nibbles of a BYTE.
-//
-#define LO_NIBBLE(b) ((BYTE)((BYTE)(b) & 0xF))
-#define HI_NIBBLE(b) ((BYTE)(((BYTE)(b) >> 4) & 0xF))
-
-//
-// Macros for Extracting the 8:4:4 Index Values.
-//
-#define GET8(w) (HIBYTE(w))
-#define GETHI4(w) (HI_NIBBLE(LOBYTE(w)))
-#define GETLO4(w) (LO_NIBBLE(LOBYTE(w)))
-
-////////////////////////////////////////////////////////////////////////////
-//
-// Traverse844Byte
-//
-// Traverses the 8:4:4 translation table for the given wide character. It
-// returns the final value of the 8:4:4 table, which is a BYTE in length.
-//
-// NOTE: Offsets in table are in BYTES.
-//
-// Broken Down Version:
-// --------------------
-// Incr = pTable[GET8(wch)] / sizeof(WORD);
-// Incr = pTable[Incr + GETHI4(wch)];
-// Value = (BYTE *)pTable[Incr + GETLO4(wch)];
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
-inline BYTE& Traverse844Byte(const WORD * pTable, WCHAR wch)
-{
- return (
- ((BYTE *)pTable)[
- pTable[
- (pTable[GET8(wch)] / sizeof(WORD)) + GETHI4(wch)
- ] + GETLO4(wch)
- ]
- );
-}
-
-////////////////////////////////////////////////////////////////////////////
-//
-// Traverse844Word
-//
-// Traverses the 8:4:4 translation table for the given wide character. It
-// returns the final value of the 8:4:4 table, which is a WORD in length.
-//
-// Broken Down Version:
-// --------------------
-// Incr = pTable[GET8(wch)];
-// Incr = pTable[Incr + GETHI4(wch)];
-// Value = pTable[Incr + GETLO4(wch)];
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
-inline WORD Traverse844Word(const WORD * pTable, WCHAR wch)
-{
- return (pTable[pTable[pTable[GET8(wch)] + GETHI4(wch)] + GETLO4(wch)]);
-}
-
-////////////////////////////////////////////////////////////////////////////
-//
-// GET_INCR_VALUE
-//
-// Gets the value of a given wide character from the given 8:4:4 table. It
-// then uses the value as an increment by adding it to the given wide
-// character code point.
-//
-// NOTE: Whenever there is no translation for the given code point, the
-// tables will return an increment value of 0. This way, the
-// wide character passed in is the same value that is returned.
-//
-// DEFINED AS A MACRO.
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
-inline WCHAR GetIncrValue(const WORD * p844Tbl, WCHAR wch)
-{
- return ((WCHAR)(wch + Traverse844Word(p844Tbl, wch)));
-}
-
-class NLSTable
-{
- public:
- static HANDLE CreateSharedMemoryMapping(const LPCWSTR pMappingName, const int iSize );
- static PBYTE OpenOrCreateMemoryMapping(const LPCWSTR pMappingName, const int iSize , HANDLE *mappedFile);
-};
-
-#endif // _NLSTABLE_H
diff --git a/src/classlibnative/nls/CMakeLists.txt b/src/classlibnative/nls/CMakeLists.txt
index d109ec2eb0..d6451b96b7 100644
--- a/src/classlibnative/nls/CMakeLists.txt
+++ b/src/classlibnative/nls/CMakeLists.txt
@@ -1,8 +1,6 @@
set( COMMLS_WKS_SOURCES
- calendardata.cpp
encodingdata.cpp
nlsinfo.cpp
- nlstable.cpp
)
add_library_clr(comnls_wks ${COMMLS_WKS_SOURCES})
diff --git a/src/classlibnative/nls/calendardata.cpp b/src/classlibnative/nls/calendardata.cpp
deleted file mode 100644
index 95d071cc93..0000000000
--- a/src/classlibnative/nls/calendardata.cpp
+++ /dev/null
@@ -1,985 +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.
-////////////////////////////////////////////////////////////////////////////
-//
-// Class: CalendarData
-//
-
-//
-// Purpose: This module implements the methods of the CalendarData
-// class. These methods are the helper functions for the
-// Locale class.
-//
-// Date: July 4, 2007
-//
-////////////////////////////////////////////////////////////////////////////
-
-#include "common.h"
-#include "object.h"
-#include "excep.h"
-#include "vars.hpp"
-#include "interoputil.h"
-#include "corhost.h"
-
-#include <winnls.h>
-
-#include "calendardata.h"
-#include "nlsinfo.h"
-#include "newapis.h"
-
-////////////////////////////////////////////////////////////////////////
-//
-// Call the Win32 GetCalendarInfoEx() using the specified calendar and LCTYPE.
-// The return value can be INT32 or an allocated managed string object, depending on
-// which version's called.
-//
-// Parameters:
-// OUT pOutputInt32 The output int32 value.
-// OUT pOutputRef The output string value.
-//
-////////////////////////////////////////////////////////////////////////
-BOOL CalendarData::CallGetCalendarInfoEx(LPCWSTR localeName, int calendar, int calType, INT32* pOutputInt32)
-{
- CONTRACTL
- {
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- } CONTRACTL_END;
-
- int result = 0;
-
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), return result; )
-
- // Just stick it right into the output int
- _ASSERT((calType & CAL_RETURN_NUMBER) != 0);
- result = NewApis::GetCalendarInfoEx(localeName, calendar, NULL, calType, NULL, 0, (LPDWORD)pOutputInt32);
-
- END_SO_INTOLERANT_CODE
-
- return (result != 0);
-}
-
-BOOL CalendarData::CallGetCalendarInfoEx(LPCWSTR localeName, int calendar, int calType, STRINGREF* pOutputStrRef)
-{
- CONTRACTL
- {
- THROWS; // We can throw since we are allocating managed string.
- DISABLED(GC_TRIGGERS); // Disabled 'cause it don't work right now
- MODE_ANY;
- SO_TOLERANT;
- } CONTRACTL_END;
-
- // The maximum size for values returned from GetLocaleInfo is 80 characters.
- WCHAR buffer[80];
- int result = 0;
-
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), return result; )
-
- _ASSERT((calType & CAL_RETURN_NUMBER) == 0);
- result = NewApis::GetCalendarInfoEx(localeName, calendar, NULL, calType, buffer, 80, NULL);
-
- if (result != 0)
- {
- _ASSERTE(pOutputStrRef != NULL);
- *pOutputStrRef = StringObject::NewString(buffer, result - 1);
- }
-
- END_SO_INTOLERANT_CODE
-
- return (result != 0);
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// Get the native day names
-//
-// NOTE: There's a disparity between .Net & windows day orders, the input day should
-// start with Sunday
-//
-// Parameters:
-// OUT pOutputStrings The output string[] value.
-//
-////////////////////////////////////////////////////////////////////////
-BOOL CalendarData::GetCalendarDayInfo(LPCWSTR localeName, int calendar, int calType, PTRARRAYREF* pOutputStrings)
-{
- CONTRACTL
- {
- THROWS; // We can throw since we are allocating managed string.
- INJECT_FAULT(COMPlusThrowOM());
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- SO_TOLERANT;
- } CONTRACTL_END;
-
- // The maximum size for values returned from GetLocaleInfo is 80 characters.
- WCHAR buffer[80];
- int result = 0;
-
- _ASSERT((calType & CAL_RETURN_NUMBER) == 0);
-
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), return result;)
-
- //
- // We'll need a new array of 7 items
- //
- // Allocate the array of STRINGREFs. We don't need to check for null because the GC will throw
- // an OutOfMemoryException if there's not enough memory.
- //
- PTRARRAYREF ResultArray = (PTRARRAYREF)AllocateObjectArray(7, g_pStringClass);
-
- GCPROTECT_BEGIN(ResultArray);
-
- // Get each one of them
- for (int i = 0; i < 7; i++, calType++)
- {
- result = NewApis::GetCalendarInfoEx(localeName, calendar, NULL, calType, buffer, 80, NULL);
-
- // Note that the returned string is null terminated, so even an empty string will be 1
- if (result != 0)
- {
- // Make a string for this entry
- STRINGREF stringResult = StringObject::NewString(buffer, result - 1);
- ResultArray->SetAt(i, (OBJECTREF)stringResult);
- }
-
- // On the first iteration we need to go from CAL_SDAYNAME7 to CAL_SDAYNAME1, so subtract 7 before the ++ happens
- // This is because the framework starts on sunday and windows starts on monday when counting days
- if (i == 0) calType -= 7;
- }
- GCPROTECT_END();
-
- _ASSERTE(pOutputStrings != NULL);
- *pOutputStrings = ResultArray;
-
- END_SO_INTOLERANT_CODE
-
- return (result != 0);
-}
-
-
-
-////////////////////////////////////////////////////////////////////////
-//
-// Get the native month names
-//
-// Parameters:
-// OUT pOutputStrings The output string[] value.
-//
-////////////////////////////////////////////////////////////////////////
-BOOL CalendarData::GetCalendarMonthInfo(LPCWSTR localeName, int calendar, int calType, PTRARRAYREF* pOutputStrings)
-{
- CONTRACTL
- {
- THROWS; // We can throw since we are allocating managed string.
- INJECT_FAULT(COMPlusThrowOM());
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- SO_TOLERANT;
- } CONTRACTL_END;
-
- // The maximum size for values returned from GetLocaleInfo is 80 characters.
- WCHAR buffer[80];
- int result = 0;
-
- _ASSERT((calType & CAL_RETURN_NUMBER) == 0);
-
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), return result;)
-
- //
- // We'll need a new array of 13 items
- //
- // Allocate the array of STRINGREFs. We don't need to check for null because the GC will throw
- // an OutOfMemoryException if there's not enough memory.
- //
- PTRARRAYREF ResultArray = (PTRARRAYREF)AllocateObjectArray(13, g_pStringClass);
-
- GCPROTECT_BEGIN(ResultArray);
-
- // Get each one of them
- for (int i = 0; i < 13; i++, calType++)
- {
- result = NewApis::GetCalendarInfoEx(localeName, calendar, NULL, calType, buffer, 80, NULL);
-
- // If we still have failure, then mark as empty string
- if (result == 0)
- {
- buffer[0] = W('0');
- result = 1;
-
-
- }
-
- // Note that the returned string is null terminated, so even an empty string will be 1
- // Make a string for this entry
- STRINGREF stringResult = StringObject::NewString(buffer, result - 1);
- ResultArray->SetAt(i, (OBJECTREF)stringResult);
- }
- GCPROTECT_END();
-
- _ASSERTE(pOutputStrings != NULL);
- *pOutputStrings = ResultArray;
-
- END_SO_INTOLERANT_CODE
-
- return (result != 0);
-}
-
-//
-// struct to help our calendar data enumaration callback
-//
-struct enumData
-{
- int count; // # of strings found so far
- LPWSTR userOverride; // pointer to user override string if used
- LPWSTR stringsBuffer; // pointer to a buffer to use for the strings.
- LPWSTR endOfBuffer; // pointer to the end of the stringsBuffer ( must be < this to write)
-};
-
-//
-// callback itself
-//
-BOOL CALLBACK EnumCalendarInfoCallback(__in_z LPWSTR lpCalendarInfoString, __in CALID Calendar, __in_opt LPWSTR pReserved, __in LPARAM lParam)
-{
- CONTRACTL
- {
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- SO_TOLERANT;
- PRECONDITION(CheckPointer(lpCalendarInfoString));
- PRECONDITION(CheckPointer((LPVOID)lParam));
- } CONTRACTL_END;
-
- // Cast our data to the right type
- enumData* pData = (enumData*)lParam;
-
- // If we had a user override, check to make sure this differs
- if (pData->userOverride == NULL ||
- wcscmp(pData->userOverride, lpCalendarInfoString) != 0)
- {
- // They're different, add it to our buffer
- LPWSTR pStart = pData->stringsBuffer;
- LPCWSTR pEnd = pData->endOfBuffer;
- while (pStart < pEnd && *lpCalendarInfoString != 0)
- {
- *(pStart++) = *(lpCalendarInfoString++);
- }
-
- // Add a \0
- if (pStart < pEnd)
- {
- *(pStart++) = 0;
-
- // Did it finish?
- if (pStart <= pEnd)
- {
- // It finished, use it
- pData->count++;
- pData->stringsBuffer = pStart;
- }
- }
- }
-
- return TRUE;
-}
-
-//
-// CallEnumCalendarInfo
-//
-// Get the list of whichever calendar property from the OS. If user override is passed in, then check GetLocaleInfo as well
-// to see if a user override is set.
-//
-// We build a list of strings, first calling getlocaleinfo if necessary, and then the enums. The strings are null terminated,
-// with a double null ending the list. Once we have the list we can allocate our COMStrings and arrays from the count.
-//
-// We need a helper structure to pass as an lParam
-//
-BOOL CalendarData::CallEnumCalendarInfo(__in_z LPCWSTR localeName, __in int calendar, __in int calType,
- __in int lcType, __inout PTRARRAYREF* pOutputStrings)
-{
- CONTRACTL
- {
- THROWS; // We can throw since we are allocating managed string.
- INJECT_FAULT(COMPlusThrowOM());
- DISABLED(GC_TRIGGERS); // Disabled 'cause it don't work right now
- MODE_COOPERATIVE;
- SO_TOLERANT;
- } CONTRACTL_END;
-
- BOOL result = TRUE;
-
- // Our longest string in culture.xml is shorter than this and it has lots of \x type characters, so this should be long enough by far.
- WCHAR stringBuffer[512];
-
- struct enumData data;
- data.count = 0;
- data.userOverride = NULL;
- data.stringsBuffer = stringBuffer;
- data.endOfBuffer = stringBuffer + 512; // We're adding WCHAR sizes
-
- // First call GetLocaleInfo if necessary
- if ((lcType && ((lcType & LOCALE_NOUSEROVERRIDE) == 0)) &&
- // Get user locale, see if it matches localeName.
- // Note that they should match exactly, including letter case
- NewApis::GetUserDefaultLocaleName(stringBuffer, 512) && wcscmp(localeName, stringBuffer) == 0)
- {
- // They want user overrides, see if the user calendar matches the input calendar
- CALID userCalendar = 0;
- NewApis::GetLocaleInfoEx(localeName, LOCALE_ICALENDARTYPE | LOCALE_RETURN_NUMBER, (LPWSTR)&userCalendar,
- sizeof(userCalendar) / sizeof(WCHAR) );
-
- // If the calendars were the same, see if the locales were the same
- if ((int)userCalendar == calendar) // todo: cast to compile on MAC
- {
- // They matched, get the user override since locale & calendar match
- int i = NewApis::GetLocaleInfoEx(localeName, lcType, stringBuffer, 512);
-
- // if it succeeded, advance the pointer and remember the override for the later callers
- if (i > 0)
- {
- // Remember this was the override (so we can look for duplicates later in the enum function)
- data.userOverride = data.stringsBuffer;
-
- // Advance to the next free spot (i includes counting the \0)
- data.stringsBuffer += i;
-
- // And our count...
- data.count++;
- }
- }
- }
-
- // Now call the enumeration API. Work is done by our callback function
- NewApis::EnumCalendarInfoExEx(EnumCalendarInfoCallback, localeName, calendar, calType, (LPARAM)&data);
-
- // Now we have a list of data, fail if we didn't find anything.
- if (data.count == 0) return FALSE;
-
- // Now we need to allocate our stringarray and populate it
- STATIC_CONTRACT_SO_TOLERANT;
-
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), return (result); )
-
- // Get our array object (will throw, don't have to check it)
- PTRARRAYREF dataArray = (PTRARRAYREF) AllocateObjectArray(data.count, g_pStringClass);
-
- GCPROTECT_BEGIN(dataArray);
- LPCWSTR buffer = stringBuffer; // Restart @ buffer beginning
- for(DWORD i = 0; i < (DWORD)data.count; i++)
- {
- OBJECTREF o = (OBJECTREF) StringObject::NewString(buffer);
-
- if (calType == CAL_SABBREVERASTRING || calType == CAL_SERASTRING)
- {
- // Eras are enumerated backwards. (oldest era name first, but
- // Japanese calendar has newest era first in array, and is only
- // calendar with multiple eras)
- dataArray->SetAt((DWORD)data.count - i - 1, o);
- }
- else
- {
- dataArray->SetAt(i, o);
- }
-
- buffer += (lstrlenW(buffer) + 1);
- }
- GCPROTECT_END();
-
- _ASSERTE(pOutputStrings != NULL);
- *pOutputStrings = dataArray;
-
- END_SO_INTOLERANT_CODE
-
- return result;
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// For calendars like Gregorain US/Taiwan/UmAlQura, they are not available
-// in all OS or all localized versions of OS.
-// If OS does not support these calendars, we will fallback by using the
-// appropriate fallback calendar and locale combination to retrieve data from OS.
-//
-// Parameters:
-// __deref_inout pCalendarInt:
-// Pointer to the calendar ID. This will be updated to new fallback calendar ID if needed.
-// __in_out pLocaleNameStackBuffer
-// Pointer to the StackSString object which holds the locale name to be checked.
-// This will be updated to new fallback locale name if needed.
-//
-////////////////////////////////////////////////////////////////////////
-
-void CalendarData::CheckSpecialCalendar(INT32* pCalendarInt, StackSString* pLocaleNameStackBuffer)
-{
- // Gregorian-US isn't always available in the OS, however it is the same for all locales
- switch (*pCalendarInt)
- {
- case CAL_GREGORIAN_US:
- // See if this works
- if (0 == NewApis::GetCalendarInfoEx(*pLocaleNameStackBuffer, *pCalendarInt, NULL, CAL_SCALNAME, NULL, 0, NULL))
- {
- // Failed, set it to a locale (fa-IR) that's alway has Gregorian US available in the OS
- pLocaleNameStackBuffer->Set(W("fa-IR"), 5);
- }
- // See if that works
- if (0 == NewApis::GetCalendarInfoEx(*pLocaleNameStackBuffer, *pCalendarInt, NULL, CAL_SCALNAME, NULL, 0, NULL))
- {
- // Failed again, just use en-US with the gregorian calendar
- pLocaleNameStackBuffer->Set(W("en-US"), 5);
- *pCalendarInt = CAL_GREGORIAN;
- }
- break;
- case CAL_TAIWAN:
- // Taiwan calendar data is not always in all language version of OS due to Geopolical reasons.
- // It is only available in zh-TW localized versions of Windows.
- // Let's check if OS supports it. If not, fallback to Greogrian localized for Taiwan calendar.
- if (0 == NewApis::GetCalendarInfoEx(*pLocaleNameStackBuffer, *pCalendarInt, NULL, CAL_SCALNAME, NULL, 0, NULL))
- {
- *pCalendarInt = CAL_GREGORIAN;
- }
- break;
- case CAL_UMALQURA:
- // UmAlQura is only available in Vista and above, so we will need to fallback to Hijri if it is not available in the OS.
- if (0 == NewApis::GetCalendarInfoEx(*pLocaleNameStackBuffer, *pCalendarInt, NULL, CAL_SCALNAME, NULL, 0, NULL))
- {
- // There are no differences in DATA between UmAlQura and Hijri, and
- // UmAlQura isn't available before Vista, so just use Hijri..
- *pCalendarInt = CAL_HIJRI;
- }
- break;
- }
-}
-
-////////////////////////////////////////////////////////////////////////
-//
-// Implementation for CalendarInfo.nativeGetCalendarData
-//
-// Retrieve calendar properties from the native side
-//
-// Parameters:
-// pCalendarData: This is passed from a managed structure CalendarData.cs
-// pLocaleNameUNSAFE: Locale name associated with the locale for this calendar
-// calendar: Calendar ID
-//
-// NOTE: Calendars depend on the locale name that creates it. Only a few
-// properties are available without locales using CalendarData.GetCalendar(int)
-//
-////////////////////////////////////////////////////////////////////////
-
-FCIMPL3(FC_BOOL_RET, CalendarData::nativeGetCalendarData, CalendarData* calendarDataUNSAFE, StringObject* pLocaleNameUNSAFE, INT32 calendar)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(pLocaleNameUNSAFE));
- } CONTRACTL_END;
-
-
- // The maximum allowed string length in GetLocaleInfo is 80 WCHARs.
- BOOL ret = TRUE;
-
- struct _gc
- {
- STRINGREF localeName;
- CALENDARDATAREF calendarData;
- } gc;
-
- // Dereference our gc objects
- gc.localeName = (STRINGREF)pLocaleNameUNSAFE;
- gc.calendarData = (CALENDARDATAREF)calendarDataUNSAFE;
-
- // Need to set up the frame since we will be allocating managed strings.
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
-
- // create a local copy of the string in order to pass it to helper methods that trigger GCs like GetCalendarDayInfo and GetCalendarMonthInfo
- StackSString localeNameStackBuffer( gc.localeName->GetBuffer() );
-
- // Conveniently this is the same as LOCALE_NOUSEROVERRIDE, so we can use this for both
- int useOverrides = (gc.calendarData->bUseUserOverrides) ? 0 : CAL_NOUSEROVERRIDE;
-
- // Helper string
- STRINGREF stringResult = NULL;
-
- //
- // Windows doesn't support some calendars right now, so remap those.
- //
- if (calendar >= 13 && calendar < 23)
- {
- switch (calendar)
- {
- case RESERVED_CAL_PERSIAN: // don't change if we have Persian calendar
- break;
-
- case RESERVED_CAL_JAPANESELUNISOLAR: // Data looks like Japanese
- calendar=CAL_JAPAN;
- break;
- case RESERVED_CAL_JULIAN: // Data looks like gregorian US
- case RESERVED_CAL_CHINESELUNISOLAR: // Algorithmic, so actual data is irrelevent
- case RESERVED_CAL_SAKA: // reserved to match Office but not implemented in our code, so data is irrelevent
- case RESERVED_CAL_LUNAR_ETO_CHN: // reserved to match Office but not implemented in our code, so data is irrelevent
- case RESERVED_CAL_LUNAR_ETO_KOR: // reserved to match Office but not implemented in our code, so data is irrelevent
- case RESERVED_CAL_LUNAR_ETO_ROKUYOU: // reserved to match Office but not implemented in our code, so data is irrelevent
- case RESERVED_CAL_KOREANLUNISOLAR: // Algorithmic, so actual data is irrelevent
- case RESERVED_CAL_TAIWANLUNISOLAR: // Algorithmic, so actual data is irrelevent
- default:
- calendar = CAL_GREGORIAN_US;
- break;
- }
- }
-
- //
- // Speical handling for some special calendar due to OS limitation.
- // This includes calendar like Taiwan calendar, UmAlQura calendar, etc.
- //
- CheckSpecialCalendar(&calendar, &localeNameStackBuffer);
-
-
- // Numbers
- ret &= CallGetCalendarInfoEx(localeNameStackBuffer, calendar,
- CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER | useOverrides,
- &(gc.calendarData->iTwoDigitYearMax));
-
- if (ret == FALSE) // failed call
- {
- _ASSERTE(!"nativeGetCalendarData could not read CAL_ITWODIGITYEARMAX");
- }
-
- _ASSERTE(ret == TRUE);
-
- // Strings
- if (CallGetCalendarInfoEx(localeNameStackBuffer, calendar, CAL_SCALNAME , &stringResult))
- SetObjectReference((OBJECTREF*)&(gc.calendarData->sNativeName), stringResult, NULL);
- else
- {
- _ASSERTE(!"nativeGetCalendarData could not read CAL_SCALNAME");
- ret = FALSE;
- }
- if (CallGetCalendarInfoEx(localeNameStackBuffer, calendar, CAL_SMONTHDAY | useOverrides, &stringResult))
- SetObjectReference((OBJECTREF*)&(gc.calendarData->sMonthDay), stringResult, NULL);
- else
- {
- _ASSERTE(!"nativeGetCalendarData could not read RESERVED_CAL_SMONTHDAY");
- ret = FALSE;
- }
-
- // String Arrays
- // Formats
- PTRARRAYREF array = NULL;
- if (CallEnumCalendarInfo(localeNameStackBuffer, calendar, CAL_SSHORTDATE, LOCALE_SSHORTDATE | useOverrides, &array))
- SetObjectReference((OBJECTREF*)&(gc.calendarData->saShortDates), array, NULL);
- else
- {
- _ASSERTE(!"nativeGetCalendarData could not read CAL_SSHORTDATE");
- ret = FALSE;
- }
- if (CallEnumCalendarInfo(localeNameStackBuffer, calendar, CAL_SLONGDATE, LOCALE_SLONGDATE | useOverrides, &array))
- SetObjectReference((OBJECTREF*)&(gc.calendarData->saLongDates), array, NULL);
- else
- {
- _ASSERTE(!"nativeGetCalendarData could not read CAL_SLONGDATE");
- ret = FALSE;
- }
-
- // Get the YearMonth pattern.
- // Before Windows Vista, NLS would not write the Year/Month pattern into the reg key.
- // This causes GetLocaleInfo() to retrieve the Gregorian localized calendar pattern even when the calendar is not Gregorian localized.
- // So we will call GetLocaleInfo() only when the reg key for sYearMonth is there.
- //
- // If the key does not exist, leave yearMonthPattern to be null, so that we will pick up the default table value.
-
- int useOverridesForYearMonthPattern = useOverrides;
- if (useOverridesForYearMonthPattern == 0)
- {
- HKEY hkey = NULL;
- useOverridesForYearMonthPattern = CAL_NOUSEROVERRIDE;
- if (WszRegOpenKeyEx(HKEY_CURRENT_USER, W("Control Panel\\International"), 0, KEY_READ, &hkey) == ERROR_SUCCESS)
- {
- if (WszRegQueryValueEx(hkey, W("sYearMonth"), 0, NULL, NULL, NULL) == ERROR_SUCCESS)
- {
- // The sYearMonth key exists. Call GetLocaleInfo() to read it.
- useOverridesForYearMonthPattern = 0; // now we can use the overrides
- }
- RegCloseKey(hkey);
- }
- }
-
- if (CallEnumCalendarInfo(localeNameStackBuffer, calendar, CAL_SYEARMONTH, LOCALE_SYEARMONTH | useOverridesForYearMonthPattern, &array))
- SetObjectReference((OBJECTREF*)&(gc.calendarData->saYearMonths), array, NULL);
- else
- {
- _ASSERTE(!"nativeGetCalendarData could not read CAL_SYEARMONTH");
- ret = FALSE;
- }
-
- // Day & Month Names
- // These are all single calType entries, 1 per day, so we have to make 7 or 13 calls to collect all the names
-
- // Day
- // Note that we're off-by-one since managed starts on sunday and windows starts on monday
- if (GetCalendarDayInfo(localeNameStackBuffer, calendar, CAL_SDAYNAME7, &array))
- SetObjectReference((OBJECTREF*)&(gc.calendarData->saDayNames), array, NULL);
- else
- {
- _ASSERTE(!"nativeGetCalendarData could not read CAL_SDAYNAME7");
- ret = FALSE;
- }
- if (GetCalendarDayInfo(localeNameStackBuffer, calendar, CAL_SABBREVDAYNAME7, &array))
- SetObjectReference((OBJECTREF*)&(gc.calendarData->saAbbrevDayNames), array, NULL);
- else
- {
- _ASSERTE(!"nativeGetCalendarData could not read CAL_SABBREVDAYNAME7");
- ret = FALSE;
- }
-
- // Month names
- if (GetCalendarMonthInfo(localeNameStackBuffer, calendar, CAL_SMONTHNAME1, &array))
- SetObjectReference((OBJECTREF*)&(gc.calendarData->saMonthNames), array, NULL);
- else
- {
- _ASSERTE(!"nativeGetCalendarData could not read CAL_SMONTHNAME1");
- ret = FALSE;
- }
-
- if (GetCalendarMonthInfo(localeNameStackBuffer, calendar, CAL_SABBREVMONTHNAME1, &array))
- SetObjectReference((OBJECTREF*)&(gc.calendarData->saAbbrevMonthNames), array, NULL);
- else
- {
- _ASSERTE(!"nativeGetCalendarData could not read CAL_SABBREVMONTHNAME1");
- ret = FALSE;
- }
-
- //
- // The following LCTYPE are not supported in some platforms. If the call fails,
- // don't return a failure.
- //
- if (GetCalendarDayInfo(localeNameStackBuffer, calendar, CAL_SSHORTESTDAYNAME7, &array))
- SetObjectReference((OBJECTREF*)&(gc.calendarData->saSuperShortDayNames), array, NULL);
-
-
- // Gregorian may have genitive month names
- if (calendar == CAL_GREGORIAN)
- {
- if (GetCalendarMonthInfo(localeNameStackBuffer, calendar, CAL_SMONTHNAME1 | CAL_RETURN_GENITIVE_NAMES, &array))
- SetObjectReference((OBJECTREF*)&(gc.calendarData->saMonthGenitiveNames), array, NULL);
- // else we ignore the error and let managed side copy the normal month names
- if (GetCalendarMonthInfo(localeNameStackBuffer, calendar, CAL_SABBREVMONTHNAME1 | CAL_RETURN_GENITIVE_NAMES, &array))
- SetObjectReference((OBJECTREF*)&(gc.calendarData->saAbbrevMonthGenitiveNames), array, NULL);
- // else we ignore the error and let managed side copy the normal month names
- }
-
-// leap year names are only different for month 6 in Hebrew calendar
-// PTRARRAYREF saLeapYearMonthNames ; // Multiple strings for the month names in a leap year. (Hebrew's the only one that has these)
-
- // Calendar Parts Names
- if (CallEnumCalendarInfo(localeNameStackBuffer, calendar, CAL_SERASTRING, NULL, &array))
- SetObjectReference((OBJECTREF*)&(gc.calendarData->saEraNames), array, NULL);
- // else we set the era in managed code
- if (CallEnumCalendarInfo(localeNameStackBuffer, calendar, CAL_SABBREVERASTRING, NULL, &array))
- SetObjectReference((OBJECTREF*)&(gc.calendarData->saAbbrevEraNames), array, NULL);
- // else we set the era in managed code
-
- // PTRARRAYREF saAbbrevEnglishEraNames ; // Abbreviated Era Names in English
-
- //
- // Calendar Era Info
- // Note that calendar era data (offsets, etc) is hard coded for each calendar since this
- // data is implementation specific and not dynamic (except perhaps Japanese)
- //
-
- HELPER_METHOD_FRAME_END();
-
- FC_RETURN_BOOL(ret);
-}
-FCIMPLEND
-
-//
-// Get the system two digit year max value for the specified calendar
-//
-FCIMPL1(INT32, CalendarData::nativeGetTwoDigitYearMax, INT32 calendar)
-{
- FCALL_CONTRACT;
-
- DWORD dwTwoDigitYearMax = (DWORD) -1;
-
- HELPER_METHOD_FRAME_BEGIN_RET_0();
-
- WCHAR strName[LOCALE_NAME_MAX_LENGTH];
-
- // Really we should just be able to pass NULL for the locale name since that
- // causes the OS to look up the user default locale name. The downlevel APIS could
- // emulate this as necessary
- if (NewApis::GetUserDefaultLocaleName(strName,NumItems(strName)) == 0 ||
- NewApis::GetCalendarInfoEx(strName, calendar, NULL, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER, NULL, 0,&dwTwoDigitYearMax) == 0)
- {
- dwTwoDigitYearMax = (DWORD) -1;
- goto lExit;
- }
-
-lExit: ;
- HELPER_METHOD_FRAME_END();
-
- return (dwTwoDigitYearMax);
-}
-FCIMPLEND
-
-//
-// nativeGetCalendars
-//
-// Get the list of acceptable calendars for this user/locale
-//
-// Might be a better way to marshal the int[] for calendars
-// We expect the input array to be 23 ints long. We then fill up the first "count" ints and return the count.
-// The caller should then make it a smaller array.
-//
-
-// Perhaps we could do something more like this...
-//U1ARRAYREF rgbOut = (U1ARRAYREF) AllocatePrimitiveArray(ELEMENT_TYPE_U1, cb);
-//memcpyNoGCRefs(rgbOut->GetDirectPointerToNonObjectElements(), rgbKey, cb * sizeof(BYTE));
-//
-//refRetVal = rgbOut;
-//
-//HELPER_METHOD_FRAME_END();
-//return (U1Array*) OBJECTREFToObject(refRetVal);
-
-//
-// struct to help our calendar data enumaration callback
-//
-struct enumCalendarsData
-{
- int count; // # of strings found so far
- CALID userOverride; // user override value (if found)
- INT32* calendarList; // list of calendars found so far
-};
-
-//
-// callback itself
-//
-BOOL CALLBACK EnumCalendarsCallback(__in_z LPWSTR lpCalendarInfoString, __in CALID Calendar, __in_opt LPWSTR pReserved, __in LPARAM lParam)
-{
- CONTRACTL
- {
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- SO_TOLERANT;
- PRECONDITION(CheckPointer(lpCalendarInfoString));
- PRECONDITION(CheckPointer((LPVOID)lParam));
- } CONTRACTL_END;
-
- // Cast our data to the right type
- enumCalendarsData* pData = (enumCalendarsData*)lParam;
-
- // If we had a user override, check to make sure this differs
- if (pData->userOverride == Calendar)
- {
- // Its the same, just return
- return TRUE;
- }
-
- // They're different, add it to our buffer, check we have room
- if (pData->count < 23)
- {
- pData->calendarList[pData->count++] = Calendar;
- }
-
- return TRUE;
-}
-
-FCIMPL3(INT32, CalendarData::nativeGetCalendars, StringObject* pLocaleNameUNSAFE, CLR_BOOL useOverrides, I4Array* calendarsUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(pLocaleNameUNSAFE));
- } CONTRACTL_END;
-
- int ret = 0;
-
- struct _gc
- {
- STRINGREF localeName;
- I4ARRAYREF calendarsRef;
- } gc;
-
- // Dereference our string
- gc.localeName = (STRINGREF)pLocaleNameUNSAFE;
- gc.calendarsRef = (I4ARRAYREF)calendarsUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
-
- int calendarBuffer[23];
- struct enumCalendarsData data;
- data.count = 0;
- data.userOverride = 0;
- data.calendarList = calendarBuffer;
-
- // First call GetLocaleInfo if necessary
- if (useOverrides)
- {
- // They want user overrides, see if the user calendar matches the input calendar
-
- CALID userCalendar = 0;
- NewApis::GetLocaleInfoEx( gc.localeName->GetBuffer(), LOCALE_ICALENDARTYPE | LOCALE_RETURN_NUMBER,
- (LPWSTR)&userCalendar, sizeof(userCalendar) / sizeof(WCHAR) );
-
- // If we got a default, then use it as the first calendar
- if (userCalendar != 0)
- {
- data.userOverride = userCalendar;
- data.calendarList[data.count++] = userCalendar;
- }
- }
-
- // Now call the enumeration API. Work is done by our callback function
- NewApis::EnumCalendarInfoExEx(EnumCalendarsCallback, gc.localeName->GetBuffer(), ENUM_ALL_CALENDARS, CAL_ICALINTVALUE, (LPARAM)&(data));
-
- // Copy to the output array
- for (int i = 0; i < data.count; i++)
- {
- (gc.calendarsRef->GetDirectPointerToNonObjectElements())[i] = calendarBuffer[i];
- }
-
- ret = data.count;
- HELPER_METHOD_FRAME_END();
-
- // Now we have a list of data, return the count
- return ret;
-}
-FCIMPLEND
-
-//
-// nativeEnumTimeFormats
-//
-// Enumerate all of the time formats (long times) on the system.
-// Windows only has 1 time format so there's nothing like an LCTYPE here.
-//
-// Note that if the locale is the user default locale windows ALWAYS returns the user override value first.
-// (ie: there's no no-user-override option for this API)
-//
-// We reuse the enumData structure since it works for us.
-//
-
-//
-// callback itself
-//
-BOOL CALLBACK EnumTimeFormatsCallback(__in_z LPCWSTR lpTimeFormatString, __in LPARAM lParam)
-{
- CONTRACTL
- {
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- SO_TOLERANT;
- PRECONDITION(CheckPointer(lpTimeFormatString));
- PRECONDITION(CheckPointer((LPVOID)lParam));
- } CONTRACTL_END;
-
- // Cast our data to the right type
- enumData* pData = (enumData*)lParam;
-
- // Don't have to worry about user overrides (the enum adds them)
- // add it to our buffer
- LPWSTR pStart = pData->stringsBuffer;
- LPCWSTR pEnd = pData->endOfBuffer;
- while (pStart < pEnd && *lpTimeFormatString != 0)
- {
- *(pStart++) = *(lpTimeFormatString++);
- }
-
- // Add a \0
- if (pStart < pEnd)
- {
- *(pStart++) = 0;
-
- // Did it finish?
- if (pStart <= pEnd)
- {
- // It finished, use it
- pData->count++;
- pData->stringsBuffer = pStart;
- }
- }
-
- return TRUE;
-}
-
-//
-// nativeEnumTimeFormats that calls the callback above
-//
-FCIMPL3(Object*, CalendarData::nativeEnumTimeFormats,
- StringObject* pLocaleNameUNSAFE, INT32 dwFlags, CLR_BOOL useUserOverride)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(pLocaleNameUNSAFE));
- } CONTRACTL_END;
-
-
- struct _gc
- {
- STRINGREF localeName;
- PTRARRAYREF timeFormatsArray;
- } gc;
-
- // Dereference our gc objects
- gc.localeName = (STRINGREF)pLocaleNameUNSAFE;
- gc.timeFormatsArray = NULL;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
-
- // Our longest string in culture.xml is shorter than this and it has lots of \x type characters, so this should be long enough by far.
- WCHAR stringBuffer[512];
- struct enumData data;
- data.count = 0;
- data.userOverride = NULL;
- data.stringsBuffer = stringBuffer;
- data.endOfBuffer = stringBuffer + 512; // We're adding WCHAR sizes
-
- // Now call the enumeration API. Work is done by our callback function
- NewApis::EnumTimeFormatsEx((TIMEFMT_ENUMPROCEX)EnumTimeFormatsCallback, gc.localeName->GetBuffer(), dwFlags, (LPARAM)&data);
-
- if (data.count > 0)
- {
- // Now we need to allocate our stringarray and populate it
- // Get our array object (will throw, don't have to check it)
- gc.timeFormatsArray = (PTRARRAYREF) AllocateObjectArray(data.count, g_pStringClass);
-
- LPCWSTR buffer = stringBuffer; // Restart @ buffer beginning
- for(DWORD i = 0; i < (DWORD)data.count; i++) // todo: cast to compile on Mac
- {
- OBJECTREF o = (OBJECTREF) StringObject::NewString(buffer);
- gc.timeFormatsArray->SetAt(i, o);
-
- buffer += (lstrlenW(buffer) + 1);
- }
-
- if(!useUserOverride && data.count > 1)
- {
- // Since there is no "NoUserOverride" aware EnumTimeFormatsEx, we always get an override
- // The override is the first entry if it is overriden.
- // We can check if we have overrides by checking the GetLocaleInfo with no override
- // If we do have an override, we don't know if it is a user defined override or if the
- // user has just selected one of the predefined formats so we can't just remove it
- // but we can move it down.
- WCHAR timeFormatNoUserOverride[LOCALE_NAME_MAX_LENGTH];
- DWORD lcType = (dwFlags == TIME_NOSECONDS) ? LOCALE_SSHORTTIME : LOCALE_STIMEFORMAT;
- lcType |= LOCALE_NOUSEROVERRIDE;
- int result = NewApis::GetLocaleInfoEx(gc.localeName->GetBuffer(), lcType, timeFormatNoUserOverride, LOCALE_NAME_MAX_LENGTH);
- if(result != 0)
- {
- STRINGREF firstTimeFormat = (STRINGREF)gc.timeFormatsArray->GetAt(0);
- if(wcscmp(timeFormatNoUserOverride, firstTimeFormat->GetBuffer())!=0)
- {
- gc.timeFormatsArray->SetAt(0, gc.timeFormatsArray->GetAt(1));
- gc.timeFormatsArray->SetAt(1, firstTimeFormat);
- }
- }
- }
-
- }
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(gc.timeFormatsArray);
-}
-FCIMPLEND
-
-
diff --git a/src/classlibnative/nls/encodingdata.cpp b/src/classlibnative/nls/encodingdata.cpp
index bf5c73fd63..c6021256be 100644
--- a/src/classlibnative/nls/encodingdata.cpp
+++ b/src/classlibnative/nls/encodingdata.cpp
@@ -17,7 +17,6 @@
//
// Please KEEP this table SORTED ALPHABETICALLY! We do a binary search on this array.
const EncodingDataItem COMNlsInfo::EncodingDataTable[] = {
-#ifdef FEATURE_CORECLR
// encoding name, codepage.
{"ANSI_X3.4-1968", 20127 },
{"ANSI_X3.4-1986", 20127 },
@@ -63,429 +62,6 @@ const EncodingDataItem COMNlsInfo::EncodingDataTable[] = {
{"x-unicode-1-1-utf-8", 65001 },
{"x-unicode-2-0-utf-7", 65000 },
{"x-unicode-2-0-utf-8", 65001 },
-#else
- // Total Items: 455
-// encoding name, codepage.
-{"437", 437},
-{"ANSI_X3.4-1968", 20127},
-{"ANSI_X3.4-1986", 20127},
-// {L"_autodetect", 50932},
-// {L"_autodetect_all", 50001},
-// {L"_autodetect_kr", 50949},
-{"arabic", 28596},
-{"ascii", 20127},
-{"ASMO-708", 708},
-{"Big5", 950},
-{"Big5-HKSCS", 950},
-{"CCSID00858", 858},
-{"CCSID00924", 20924},
-{"CCSID01140", 1140},
-{"CCSID01141", 1141},
-{"CCSID01142", 1142},
-{"CCSID01143", 1143},
-{"CCSID01144", 1144},
-{"CCSID01145", 1145},
-{"CCSID01146", 1146},
-{"CCSID01147", 1147},
-{"CCSID01148", 1148},
-{"CCSID01149", 1149},
-{"chinese", 936},
-{"cn-big5", 950},
-{"CN-GB", 936},
-{"CP00858", 858},
-{"CP00924", 20924},
-{"CP01140", 1140},
-{"CP01141", 1141},
-{"CP01142", 1142},
-{"CP01143", 1143},
-{"CP01144", 1144},
-{"CP01145", 1145},
-{"CP01146", 1146},
-{"CP01147", 1147},
-{"CP01148", 1148},
-{"CP01149", 1149},
-{"cp037", 37},
-{"cp1025", 21025},
-{"CP1026", 1026},
-{"cp1256", 1256},
-{"CP273", 20273},
-{"CP278", 20278},
-{"CP280", 20280},
-{"CP284", 20284},
-{"CP285", 20285},
-{"cp290", 20290},
-{"cp297", 20297},
-{"cp367", 20127},
-{"cp420", 20420},
-{"cp423", 20423},
-{"cp424", 20424},
-{"cp437", 437},
-{"CP500", 500},
-{"cp50227", 50227},
- //{L"cp50229", 50229},
-{"cp819", 28591},
-{"cp850", 850},
-{"cp852", 852},
-{"cp855", 855},
-{"cp857", 857},
-{"cp858", 858},
-{"cp860", 860},
-{"cp861", 861},
-{"cp862", 862},
-{"cp863", 863},
-{"cp864", 864},
-{"cp865", 865},
-{"cp866", 866},
-{"cp869", 869},
-{"CP870", 870},
-{"CP871", 20871},
-{"cp875", 875},
-{"cp880", 20880},
-{"CP905", 20905},
-//{L"cp930", 50930},
-//{L"cp933", 50933},
-//{L"cp935", 50935},
-//{L"cp937", 50937},
-//{L"cp939", 50939},
-{"csASCII", 20127},
-{"csbig5", 950},
-{"csEUCKR", 51949},
-{"csEUCPkdFmtJapanese", 51932},
-{"csGB2312", 936},
-{"csGB231280", 936},
-{"csIBM037", 37},
-{"csIBM1026", 1026},
-{"csIBM273", 20273},
-{"csIBM277", 20277},
-{"csIBM278", 20278},
-{"csIBM280", 20280},
-{"csIBM284", 20284},
-{"csIBM285", 20285},
-{"csIBM290", 20290},
-{"csIBM297", 20297},
-{"csIBM420", 20420},
-{"csIBM423", 20423},
-{"csIBM424", 20424},
-{"csIBM500", 500},
-{"csIBM870", 870},
-{"csIBM871", 20871},
-{"csIBM880", 20880},
-{"csIBM905", 20905},
-{"csIBMThai", 20838},
-{"csISO2022JP", 50221},
-{"csISO2022KR", 50225},
-{"csISO58GB231280", 936},
-{"csISOLatin1", 28591},
-{"csISOLatin2", 28592},
-{"csISOLatin3", 28593},
-{"csISOLatin4", 28594},
-{"csISOLatin5", 28599},
-{"csISOLatin9", 28605},
-{"csISOLatinArabic", 28596},
-{"csISOLatinCyrillic", 28595},
-{"csISOLatinGreek", 28597},
-{"csISOLatinHebrew", 28598},
-{"csKOI8R", 20866},
-{"csKSC56011987", 949},
-{"csPC8CodePage437", 437},
-{"csShiftJIS", 932},
-{"csUnicode11UTF7", 65000},
-{"csWindows31J", 932},
-{"cyrillic", 28595},
-{"DIN_66003", 20106},
-{"DOS-720", 720},
-{"DOS-862", 862},
-{"DOS-874", 874},
-{"ebcdic-cp-ar1", 20420},
-{"ebcdic-cp-be", 500},
-{"ebcdic-cp-ca", 37},
-{"ebcdic-cp-ch", 500},
-{"EBCDIC-CP-DK", 20277},
-{"ebcdic-cp-es", 20284},
-{"ebcdic-cp-fi", 20278},
-{"ebcdic-cp-fr", 20297},
-{"ebcdic-cp-gb", 20285},
-{"ebcdic-cp-gr", 20423},
-{"ebcdic-cp-he", 20424},
-{"ebcdic-cp-is", 20871},
-{"ebcdic-cp-it", 20280},
-{"ebcdic-cp-nl", 37},
-{"EBCDIC-CP-NO", 20277},
-{"ebcdic-cp-roece", 870},
-{"ebcdic-cp-se", 20278},
-{"ebcdic-cp-tr", 20905},
-{"ebcdic-cp-us", 37},
-{"ebcdic-cp-wt", 37},
-{"ebcdic-cp-yu", 870},
-{"EBCDIC-Cyrillic", 20880},
-{"ebcdic-de-273+euro", 1141},
-{"ebcdic-dk-277+euro", 1142},
-{"ebcdic-es-284+euro", 1145},
-{"ebcdic-fi-278+euro", 1143},
-{"ebcdic-fr-297+euro", 1147},
-{"ebcdic-gb-285+euro", 1146},
-{"ebcdic-international-500+euro", 1148},
-{"ebcdic-is-871+euro", 1149},
-{"ebcdic-it-280+euro", 1144},
-{"EBCDIC-JP-kana", 20290},
-{"ebcdic-Latin9--euro", 20924},
-{"ebcdic-no-277+euro", 1142},
-{"ebcdic-se-278+euro", 1143},
-{"ebcdic-us-37+euro", 1140},
-{"ECMA-114", 28596},
-{"ECMA-118", 28597},
-{"ELOT_928", 28597},
-{"euc-cn", 51936},
-{"euc-jp", 51932},
-{"euc-kr", 51949},
-{"Extended_UNIX_Code_Packed_Format_for_Japanese", 51932},
-{"GB18030", 54936},
-{"GB2312", 936},
-{"GB2312-80", 936},
-{"GB231280", 936},
-{"GBK", 936},
-{"GB_2312-80", 936},
-{"German", 20106},
-{"greek", 28597},
-{"greek8", 28597},
-{"hebrew", 28598},
-{"hz-gb-2312", 52936},
-{"IBM-Thai", 20838},
-{"IBM00858", 858},
-{"IBM00924", 20924},
-{"IBM01047", 1047},
-{"IBM01140", 1140},
-{"IBM01141", 1141},
-{"IBM01142", 1142},
-{"IBM01143", 1143},
-{"IBM01144", 1144},
-{"IBM01145", 1145},
-{"IBM01146", 1146},
-{"IBM01147", 1147},
-{"IBM01148", 1148},
-{"IBM01149", 1149},
-{"IBM037", 37},
-{"IBM1026", 1026},
-{"IBM273", 20273},
-{"IBM277", 20277},
-{"IBM278", 20278},
-{"IBM280", 20280},
-{"IBM284", 20284},
-{"IBM285", 20285},
-{"IBM290", 20290},
-{"IBM297", 20297},
-{"IBM367", 20127},
-{"IBM420", 20420},
-{"IBM423", 20423},
-{"IBM424", 20424},
-{"IBM437", 437},
-{"IBM500", 500},
-{"ibm737", 737},
-{"ibm775", 775},
-{"ibm819", 28591},
-{"IBM850", 850},
-{"IBM852", 852},
-{"IBM855", 855},
-{"IBM857", 857},
-{"IBM860", 860},
-{"IBM861", 861},
-{"IBM862", 862},
-{"IBM863", 863},
-{"IBM864", 864},
-{"IBM865", 865},
-{"IBM866", 866},
-{"IBM869", 869},
-{"IBM870", 870},
-{"IBM871", 20871},
-{"IBM880", 20880},
-{"IBM905", 20905},
-{"irv", 20105},
-{"ISO-10646-UCS-2", 1200},
-{"iso-2022-jp", 50220},
-{"iso-2022-jpeuc", 51932},
-{"iso-2022-kr", 50225},
-{"iso-2022-kr-7", 50225},
-{"iso-2022-kr-7bit", 50225},
-{"iso-2022-kr-8", 51949},
-{"iso-2022-kr-8bit", 51949},
-{"iso-8859-1", 28591},
-{"iso-8859-11", 874},
-{"iso-8859-13", 28603},
-{"iso-8859-15", 28605},
-{"iso-8859-2", 28592},
-{"iso-8859-3", 28593},
-{"iso-8859-4", 28594},
-{"iso-8859-5", 28595},
-{"iso-8859-6", 28596},
-{"iso-8859-7", 28597},
-{"iso-8859-8", 28598},
-{"ISO-8859-8 Visual", 28598},
-{"iso-8859-8-i", 38598},
-{"iso-8859-9", 28599},
-{"iso-ir-100", 28591},
-{"iso-ir-101", 28592},
-{"iso-ir-109", 28593},
-{"iso-ir-110", 28594},
-{"iso-ir-126", 28597},
-{"iso-ir-127", 28596},
-{"iso-ir-138", 28598},
-{"iso-ir-144", 28595},
-{"iso-ir-148", 28599},
-{"iso-ir-149", 949},
-{"iso-ir-58", 936},
-{"iso-ir-6", 20127},
-{"ISO646-US", 20127},
-{"iso8859-1", 28591},
-{"iso8859-2", 28592},
-{"ISO_646.irv:1991", 20127},
-{"iso_8859-1", 28591},
-{"ISO_8859-15", 28605},
-{"iso_8859-1:1987", 28591},
-{"iso_8859-2", 28592},
-{"iso_8859-2:1987", 28592},
-{"ISO_8859-3", 28593},
-{"ISO_8859-3:1988", 28593},
-{"ISO_8859-4", 28594},
-{"ISO_8859-4:1988", 28594},
-{"ISO_8859-5", 28595},
-{"ISO_8859-5:1988", 28595},
-{"ISO_8859-6", 28596},
-{"ISO_8859-6:1987", 28596},
-{"ISO_8859-7", 28597},
-{"ISO_8859-7:1987", 28597},
-{"ISO_8859-8", 28598},
-{"ISO_8859-8:1988", 28598},
-{"ISO_8859-9", 28599},
-{"ISO_8859-9:1989", 28599},
-{"Johab", 1361},
-{"koi", 20866},
-{"koi8", 20866},
-{"koi8-r", 20866},
-{"koi8-ru", 21866},
-{"koi8-u", 21866},
-{"koi8r", 20866},
-{"korean", 949},
-{"ks-c-5601", 949},
-{"ks-c5601", 949},
-{"KSC5601", 949},
-{"KSC_5601", 949},
-{"ks_c_5601", 949},
-{"ks_c_5601-1987", 949},
-{"ks_c_5601-1989", 949},
-{"ks_c_5601_1987", 949},
-{"l1", 28591},
-{"l2", 28592},
-{"l3", 28593},
-{"l4", 28594},
-{"l5", 28599},
-{"l9", 28605},
-{"latin1", 28591},
-{"latin2", 28592},
-{"latin3", 28593},
-{"latin4", 28594},
-{"latin5", 28599},
-{"latin9", 28605},
-{"logical", 28598},
-{"macintosh", 10000},
-{"ms_Kanji", 932},
-{"Norwegian", 20108},
-{"NS_4551-1", 20108},
-{"PC-Multilingual-850+euro", 858},
-{"SEN_850200_B", 20107},
-{"shift-jis", 932},
-{"shift_jis", 932},
-{"sjis", 932},
-{"Swedish", 20107},
-{"TIS-620", 874},
-{"ucs-2", 1200},
-{"unicode", 1200},
-{"unicode-1-1-utf-7", 65000},
-{"unicode-1-1-utf-8", 65001},
-{"unicode-2-0-utf-7", 65000},
-{"unicode-2-0-utf-8", 65001},
-// People get confused about the FFFE here. We can't change this because it'd break existing apps.
-// This has been this way for a long time, including in Mlang.
-{"unicodeFFFE", 1201}, // Big Endian, BOM seems backwards, think of the BOM in little endian order.
-{"us", 20127},
-{"us-ascii", 20127},
-{"utf-16", 1200},
-{"UTF-16BE", 1201},
-{"UTF-16LE", 1200},
-{"utf-32", 12000},
-{"UTF-32BE", 12001},
-{"UTF-32LE", 12000},
-{"utf-7", 65000},
-{"utf-8", 65001},
-{"visual", 28598},
-{"windows-1250", 1250},
-{"windows-1251", 1251},
-{"windows-1252", 1252},
-{"windows-1253", 1253},
-{"Windows-1254", 1254},
-{"windows-1255", 1255},
-{"windows-1256", 1256},
-{"windows-1257", 1257},
-{"windows-1258", 1258},
-{"windows-874", 874},
-{"x-ansi", 1252},
-{"x-Chinese-CNS", 20000},
-{"x-Chinese-Eten", 20002},
-{"x-cp1250", 1250},
-{"x-cp1251", 1251},
-{"x-cp20001", 20001},
-{"x-cp20003", 20003},
-{"x-cp20004", 20004},
-{"x-cp20005", 20005},
-{"x-cp20261", 20261},
-{"x-cp20269", 20269},
-{"x-cp20936", 20936},
-{"x-cp20949", 20949},
-{"x-cp50227", 50227},
-//{L"x-cp50229", 50229},
-//{L"X-EBCDIC-JapaneseAndUSCanada", 50931},
-{"X-EBCDIC-KoreanExtended", 20833},
-{"x-euc", 51932},
-{"x-euc-cn", 51936},
-{"x-euc-jp", 51932},
-{"x-Europa", 29001},
-{"x-IA5", 20105},
-{"x-IA5-German", 20106},
-{"x-IA5-Norwegian", 20108},
-{"x-IA5-Swedish", 20107},
-{"x-iscii-as", 57006},
-{"x-iscii-be", 57003},
-{"x-iscii-de", 57002},
-{"x-iscii-gu", 57010},
-{"x-iscii-ka", 57008},
-{"x-iscii-ma", 57009},
-{"x-iscii-or", 57007},
-{"x-iscii-pa", 57011},
-{"x-iscii-ta", 57004},
-{"x-iscii-te", 57005},
-{"x-mac-arabic", 10004},
-{"x-mac-ce", 10029},
-{"x-mac-chinesesimp", 10008},
-{"x-mac-chinesetrad", 10002},
-{"x-mac-croatian", 10082},
-{"x-mac-cyrillic", 10007},
-{"x-mac-greek", 10006},
-{"x-mac-hebrew", 10005},
-{"x-mac-icelandic", 10079},
-{"x-mac-japanese", 10001},
-{"x-mac-korean", 10003},
-{"x-mac-romanian", 10010},
-{"x-mac-thai", 10021},
-{"x-mac-turkish", 10081},
-{"x-mac-ukrainian", 10017},
-{"x-ms-cp932", 932},
-{"x-sjis", 932},
-{"x-unicode-1-1-utf-7", 65000},
-{"x-unicode-1-1-utf-8", 65001},
-{"x-unicode-2-0-utf-7", 65000},
-{"x-unicode-2-0-utf-8", 65001},
-{"x-x-big5", 950},
-
-#endif // FEATURE_CORECLR
};
@@ -503,7 +79,6 @@ const int COMNlsInfo::m_nEncodingDataTableItems =
//
const CodePageDataItem COMNlsInfo::CodePageDataTable[] = {
-#ifdef FEATURE_CORECLR
// Total Items:
// code page, family code page, web name, header name, body name, flags
@@ -517,160 +92,6 @@ const CodePageDataItem COMNlsInfo::CodePageDataTable[] = {
MapCodePageDataItem( 65000, 1200, "utf-7", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS), // "Unicode (UTF-7)"
MapCodePageDataItem( 65001, 1200, "utf-8", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Unicode (UTF-8)"
-#else //FEATURE_CORECLR
-
-// Total Items: 146
-// code page, family code page, web name, header name, body name, flags
-
-
- MapCodePageDataItem( 37, 1252, "IBM037", 0), // "IBM EBCDIC (US-Canada)"
- MapCodePageDataItem( 437, 1252, "IBM437", 0), // "OEM United States"
- MapCodePageDataItem( 500, 1252, "IBM500", 0), // "IBM EBCDIC (International)"
- MapCodePageDataItem( 708, 1256, "ASMO-708", MIMECONTF_BROWSER | MIMECONTF_SAVABLE_BROWSER), // "Arabic (ASMO 708)"
- MapCodePageDataItem( 720, 1256, "DOS-720", MIMECONTF_BROWSER | MIMECONTF_SAVABLE_BROWSER), // "Arabic (DOS)"
- MapCodePageDataItem( 737, 1253, "ibm737", 0), // "Greek (DOS)"
- MapCodePageDataItem( 775, 1257, "ibm775", 0), // "Baltic (DOS)"
- MapCodePageDataItem( 850, 1252, "ibm850", 0), // "Western European (DOS)"
- MapCodePageDataItem( 852, 1250, "ibm852", MIMECONTF_BROWSER | MIMECONTF_SAVABLE_BROWSER), // "Central European (DOS)"
- MapCodePageDataItem( 855, 1252, "IBM855", 0), // "OEM Cyrillic"
- MapCodePageDataItem( 857, 1254, "ibm857", 0), // "Turkish (DOS)"
- MapCodePageDataItem( 858, 1252, "IBM00858", 0), // "OEM Multilingual Latin I"
- MapCodePageDataItem( 860, 1252, "IBM860", 0), // "Portuguese (DOS)"
- MapCodePageDataItem( 861, 1252, "ibm861", 0), // "Icelandic (DOS)"
- MapCodePageDataItem( 862, 1255, "DOS-862", MIMECONTF_BROWSER | MIMECONTF_SAVABLE_BROWSER), // "Hebrew (DOS)"
- MapCodePageDataItem( 863, 1252, "IBM863", 0), // "French Canadian (DOS)"
- MapCodePageDataItem( 864, 1256, "IBM864", 0), // "Arabic (864)"
- MapCodePageDataItem( 865, 1252, "IBM865", 0), // "Nordic (DOS)"
- MapCodePageDataItem( 866, 1251, "cp866", MIMECONTF_BROWSER | MIMECONTF_SAVABLE_BROWSER), // "Cyrillic (DOS)"
- MapCodePageDataItem( 869, 1253, "ibm869", 0), // "Greek, Modern (DOS)"
- MapCodePageDataItem( 870, 1250, "IBM870", 0), // "IBM EBCDIC (Multilingual Latin-2)"
- MapCodePageDataItem( 874, 874, "windows-874", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Thai (Windows)"
- MapCodePageDataItem( 875, 1253, "cp875", 0), // "IBM EBCDIC (Greek Modern)"
- MapCodePageDataItem( 932, 932, "|shift_jis|iso-2022-jp|iso-2022-jp", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Japanese (Shift-JIS)"
- MapCodePageDataItem( 936, 936, "gb2312", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Chinese Simplified (GB2312)"
- MapCodePageDataItem( 949, 949, "ks_c_5601-1987", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Korean"
- MapCodePageDataItem( 950, 950, "big5", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Chinese Traditional (Big5)"
- MapCodePageDataItem( 1026, 1254, "IBM1026", 0), // "IBM EBCDIC (Turkish Latin-5)"
- MapCodePageDataItem( 1047, 1252, "IBM01047", 0), // "IBM Latin-1"
- MapCodePageDataItem( 1140, 1252, "IBM01140", 0), // "IBM EBCDIC (US-Canada-Euro)"
- MapCodePageDataItem( 1141, 1252, "IBM01141", 0), // "IBM EBCDIC (Germany-Euro)"
- MapCodePageDataItem( 1142, 1252, "IBM01142", 0), // "IBM EBCDIC (Denmark-Norway-Euro)"
- MapCodePageDataItem( 1143, 1252, "IBM01143", 0), // "IBM EBCDIC (Finland-Sweden-Euro)"
- MapCodePageDataItem( 1144, 1252, "IBM01144", 0), // "IBM EBCDIC (Italy-Euro)"
- MapCodePageDataItem( 1145, 1252, "IBM01145", 0), // "IBM EBCDIC (Spain-Euro)"
- MapCodePageDataItem( 1146, 1252, "IBM01146", 0), // "IBM EBCDIC (UK-Euro)"
- MapCodePageDataItem( 1147, 1252, "IBM01147", 0), // "IBM EBCDIC (France-Euro)"
- MapCodePageDataItem( 1148, 1252, "IBM01148", 0), // "IBM EBCDIC (International-Euro)"
- MapCodePageDataItem( 1149, 1252, "IBM01149", 0), // "IBM EBCDIC (Icelandic-Euro)"
- MapCodePageDataItem( 1200, 1200, "utf-16", MIMECONTF_SAVABLE_BROWSER), // "Unicode"
- MapCodePageDataItem( 1201, 1200, "utf-16BE", 0), // Big Endian, old FFFE BOM seems backwards, think of the BOM in little endian order.
- MapCodePageDataItem( 1250, 1250, "|windows-1250|windows-1250|iso-8859-2", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Central European (Windows)"
- MapCodePageDataItem( 1251, 1251, "|windows-1251|windows-1251|koi8-r", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Cyrillic (Windows)"
- MapCodePageDataItem( 1252, 1252, "|Windows-1252|Windows-1252|iso-8859-1", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Western European (Windows)"
- MapCodePageDataItem( 1253, 1253, "|windows-1253|windows-1253|iso-8859-7", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Greek (Windows)"
- MapCodePageDataItem( 1254, 1254, "|windows-1254|windows-1254|iso-8859-9", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Turkish (Windows)"
- MapCodePageDataItem( 1255, 1255, "windows-1255", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Hebrew (Windows)"
- MapCodePageDataItem( 1256, 1256, "windows-1256", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Arabic (Windows)"
- MapCodePageDataItem( 1257, 1257, "windows-1257", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Baltic (Windows)"
- MapCodePageDataItem( 1258, 1258, "windows-1258", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Vietnamese (Windows)"
- MapCodePageDataItem( 1361, 949, "Johab", 0), // "Korean (Johab)"
- MapCodePageDataItem( 10000, 1252, "macintosh", 0), // "Western European (Mac)"
- MapCodePageDataItem( 10001, 932, "x-mac-japanese", 0), // "Japanese (Mac)"
- MapCodePageDataItem( 10002, 950, "x-mac-chinesetrad", 0), // "Chinese Traditional (Mac)"
- MapCodePageDataItem( 10003, 949, "x-mac-korean", 0), // "Korean (Mac)"
- MapCodePageDataItem( 10004, 1256, "x-mac-arabic", 0), // "Arabic (Mac)"
- MapCodePageDataItem( 10005, 1255, "x-mac-hebrew", 0), // "Hebrew (Mac)"
- MapCodePageDataItem( 10006, 1253, "x-mac-greek", 0), // "Greek (Mac)"
- MapCodePageDataItem( 10007, 1251, "x-mac-cyrillic", 0), // "Cyrillic (Mac)"
- MapCodePageDataItem( 10008, 936, "x-mac-chinesesimp", 0), // "Chinese Simplified (Mac)"
- MapCodePageDataItem( 10010, 1250, "x-mac-romanian", 0), // "Romanian (Mac)"
- MapCodePageDataItem( 10017, 1251, "x-mac-ukrainian", 0), // "Ukrainian (Mac)"
- MapCodePageDataItem( 10021, 874, "x-mac-thai", 0), // "Thai (Mac)"
- MapCodePageDataItem( 10029, 1250, "x-mac-ce", 0), // "Central European (Mac)"
- MapCodePageDataItem( 10079, 1252, "x-mac-icelandic", 0), // "Icelandic (Mac)"
- MapCodePageDataItem( 10081, 1254, "x-mac-turkish", 0), // "Turkish (Mac)"
- MapCodePageDataItem( 10082, 1250, "x-mac-croatian", 0), // "Croatian (Mac)"
- MapCodePageDataItem( 12000, 1200, "utf-32", 0), // "Unicode (UTF-32)"
- MapCodePageDataItem( 12001, 1200, "utf-32BE", 0), // "Unicode (UTF-32 Big Endian)"
- MapCodePageDataItem( 20000, 950, "x-Chinese-CNS", 0), // "Chinese Traditional (CNS)"
- MapCodePageDataItem( 20001, 950, "x-cp20001", 0), // "TCA Taiwan"
- MapCodePageDataItem( 20002, 950, "x-Chinese-Eten", 0), // "Chinese Traditional (Eten)"
- MapCodePageDataItem( 20003, 950, "x-cp20003", 0), // "IBM5550 Taiwan"
- MapCodePageDataItem( 20004, 950, "x-cp20004", 0), // "TeleText Taiwan"
- MapCodePageDataItem( 20005, 950, "x-cp20005", 0), // "Wang Taiwan"
- MapCodePageDataItem( 20105, 1252, "x-IA5", 0), // "Western European (IA5)"
- MapCodePageDataItem( 20106, 1252, "x-IA5-German", 0), // "German (IA5)"
- MapCodePageDataItem( 20107, 1252, "x-IA5-Swedish", 0), // "Swedish (IA5)"
- MapCodePageDataItem( 20108, 1252, "x-IA5-Norwegian", 0), // "Norwegian (IA5)"
- MapCodePageDataItem( 20127, 1252, "us-ascii", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS), // "US-ASCII"
- MapCodePageDataItem( 20261, 1252, "x-cp20261", 0), // "T.61"
- MapCodePageDataItem( 20269, 1252, "x-cp20269", 0), // "ISO-6937"
- MapCodePageDataItem( 20273, 1252, "IBM273", 0), // "IBM EBCDIC (Germany)"
- MapCodePageDataItem( 20277, 1252, "IBM277", 0), // "IBM EBCDIC (Denmark-Norway)"
- MapCodePageDataItem( 20278, 1252, "IBM278", 0), // "IBM EBCDIC (Finland-Sweden)"
- MapCodePageDataItem( 20280, 1252, "IBM280", 0), // "IBM EBCDIC (Italy)"
- MapCodePageDataItem( 20284, 1252, "IBM284", 0), // "IBM EBCDIC (Spain)"
- MapCodePageDataItem( 20285, 1252, "IBM285", 0), // "IBM EBCDIC (UK)"
- MapCodePageDataItem( 20290, 932, "IBM290", 0), // "IBM EBCDIC (Japanese katakana)"
- MapCodePageDataItem( 20297, 1252, "IBM297", 0), // "IBM EBCDIC (France)"
- MapCodePageDataItem( 20420, 1256, "IBM420", 0), // "IBM EBCDIC (Arabic)"
- MapCodePageDataItem( 20423, 1253, "IBM423", 0), // "IBM EBCDIC (Greek)"
- MapCodePageDataItem( 20424, 1255, "IBM424", 0), // "IBM EBCDIC (Hebrew)"
- MapCodePageDataItem( 20833, 949, "x-EBCDIC-KoreanExtended", 0), // "IBM EBCDIC (Korean Extended)"
- MapCodePageDataItem( 20838, 874, "IBM-Thai", 0), // "IBM EBCDIC (Thai)"
- MapCodePageDataItem( 20866, 1251, "koi8-r", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Cyrillic (KOI8-R)"
- MapCodePageDataItem( 20871, 1252, "IBM871", 0), // "IBM EBCDIC (Icelandic)"
- MapCodePageDataItem( 20880, 1251, "IBM880", 0), // "IBM EBCDIC (Cyrillic Russian)"
- MapCodePageDataItem( 20905, 1254, "IBM905", 0), // "IBM EBCDIC (Turkish)"
- MapCodePageDataItem( 20924, 1252, "IBM00924", 0), // "IBM Latin-1"
- MapCodePageDataItem( 20932, 932, "EUC-JP", 0), // "Japanese (JIS 0208-1990 and 0212-1990)"
- MapCodePageDataItem( 20936, 936, "x-cp20936", 0), // "Chinese Simplified (GB2312-80)"
- MapCodePageDataItem( 20949, 949, "x-cp20949", 0), // "Korean Wansung"
- MapCodePageDataItem( 21025, 1251, "cp1025", 0), // "IBM EBCDIC (Cyrillic Serbian-Bulgarian)"
- MapCodePageDataItem( 21866, 1251, "koi8-u", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Cyrillic (KOI8-U)"
- MapCodePageDataItem( 28591, 1252, "iso-8859-1", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Western European (ISO)"
- MapCodePageDataItem( 28592, 1250, "iso-8859-2", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Central European (ISO)"
- MapCodePageDataItem( 28593, 1254, "iso-8859-3", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS), // "Latin 3 (ISO)"
- MapCodePageDataItem( 28594, 1257, "iso-8859-4", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Baltic (ISO)"
- MapCodePageDataItem( 28595, 1251, "iso-8859-5", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Cyrillic (ISO)"
- MapCodePageDataItem( 28596, 1256, "iso-8859-6", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Arabic (ISO)"
- MapCodePageDataItem( 28597, 1253, "iso-8859-7", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Greek (ISO)"
- MapCodePageDataItem( 28598, 1255, "iso-8859-8", MIMECONTF_BROWSER | MIMECONTF_SAVABLE_BROWSER), // "Hebrew (ISO-Visual)"
- MapCodePageDataItem( 28599, 1254, "iso-8859-9", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Turkish (ISO)"
- MapCodePageDataItem( 28603, 1257, "iso-8859-13", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS), // "Estonian (ISO)"
- MapCodePageDataItem( 28605, 1252, "iso-8859-15", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Latin 9 (ISO)"
- MapCodePageDataItem( 29001, 1252, "x-Europa", 0), // "Europa"
- MapCodePageDataItem( 38598, 1255, "iso-8859-8-i", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Hebrew (ISO-Logical)"
- MapCodePageDataItem( 50220, 932, "iso-2022-jp", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS), // "Japanese (JIS)"
- MapCodePageDataItem( 50221, 932, "|csISO2022JP|iso-2022-jp|iso-2022-jp", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Japanese (JIS-Allow 1 byte Kana)"
- MapCodePageDataItem( 50222, 932, "iso-2022-jp", 0), // "Japanese (JIS-Allow 1 byte Kana - SO/SI)"
- MapCodePageDataItem( 50225, 949, "|iso-2022-kr|euc-kr|iso-2022-kr", MIMECONTF_MAILNEWS), // "Korean (ISO)"
- MapCodePageDataItem( 50227, 936, "x-cp50227", 0), // "Chinese Simplified (ISO-2022)"
-//MapCodePageDataItem( 50229, 950, L"x-cp50229", L"x-cp50229", L"x-cp50229", 0}, // "Chinese Traditional (ISO-2022)"
-//MapCodePageDataItem( 50930, 932, L"cp930", L"cp930", L"cp930", 0}, // "IBM EBCDIC (Japanese and Japanese Katakana)"
-//MapCodePageDataItem( 50931, 932, L"x-EBCDIC-JapaneseAndUSCanada", L"x-EBCDIC-JapaneseAndUSCanada", L"x-EBCDIC-JapaneseAndUSCanada", 0}, // "IBM EBCDIC (Japanese and US-Canada)"
-//MapCodePageDataItem( 50933, 949, L"cp933", L"cp933", L"cp933", 0}, // "IBM EBCDIC (Korean and Korean Extended)"
-//MapCodePageDataItem( 50935, 936, L"cp935", L"cp935", L"cp935", 0}, // "IBM EBCDIC (Simplified Chinese)"
-//MapCodePageDataItem( 50937, 950, L"cp937", L"cp937", L"cp937", 0}, // "IBM EBCDIC (Traditional Chinese)"
-//MapCodePageDataItem( 50939, 932, L"cp939", L"cp939", L"cp939", 0}, // "IBM EBCDIC (Japanese and Japanese-Latin)"
- MapCodePageDataItem( 51932, 932, "euc-jp", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Japanese (EUC)"
- MapCodePageDataItem( 51936, 936, "EUC-CN", 0), // "Chinese Simplified (EUC)"
- MapCodePageDataItem( 51949, 949, "euc-kr", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS), // "Korean (EUC)"
- MapCodePageDataItem( 52936, 936, "hz-gb-2312", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Chinese Simplified (HZ)"
- MapCodePageDataItem( 54936, 936, "GB18030", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Chinese Simplified (GB18030)"
- MapCodePageDataItem( 57002, 57002, "x-iscii-de", 0), // "ISCII Devanagari"
- MapCodePageDataItem( 57003, 57003, "x-iscii-be", 0), // "ISCII Bengali"
- MapCodePageDataItem( 57004, 57004, "x-iscii-ta", 0), // "ISCII Tamil"
- MapCodePageDataItem( 57005, 57005, "x-iscii-te", 0), // "ISCII Telugu"
- MapCodePageDataItem( 57006, 57006, "x-iscii-as", 0), // "ISCII Assamese"
- MapCodePageDataItem( 57007, 57007, "x-iscii-or", 0), // "ISCII Oriya"
- MapCodePageDataItem( 57008, 57008, "x-iscii-ka", 0), // "ISCII Kannada"
- MapCodePageDataItem( 57009, 57009, "x-iscii-ma", 0), // "ISCII Malayalam"
- MapCodePageDataItem( 57010, 57010, "x-iscii-gu", 0), // "ISCII Gujarati"
- MapCodePageDataItem( 57011, 57011, "x-iscii-pa", 0), // "ISCII Punjabi"
- MapCodePageDataItem( 65000, 1200, "utf-7", MIMECONTF_MAILNEWS | MIMECONTF_SAVABLE_MAILNEWS), // "Unicode (UTF-7)"
- MapCodePageDataItem( 65001, 1200, "utf-8", MIMECONTF_MAILNEWS | MIMECONTF_BROWSER | MIMECONTF_SAVABLE_MAILNEWS | MIMECONTF_SAVABLE_BROWSER), // "Unicode (UTF-8)"
-#endif // FEATURE_CORECLR
// End of data.
MapCodePageDataItem( 0, 0, NULL, 0),
diff --git a/src/classlibnative/nls/nlsinfo.cpp b/src/classlibnative/nls/nlsinfo.cpp
index 0e034c4a0c..fa288c0e0a 100644
--- a/src/classlibnative/nls/nlsinfo.cpp
+++ b/src/classlibnative/nls/nlsinfo.cpp
@@ -33,7 +33,6 @@
#include "metasig.h"
#include "nls.h"
#include "nlsinfo.h"
-#include "nlstable.h"
//#include <mlang.h>
#include "sortversioning.h"
@@ -44,70 +43,6 @@
// Constant Declarations.
//
-#ifndef COMPARE_OPTIONS_IGNORECASE
-#define COMPARE_OPTIONS_IGNORECASE 0x00000001
-#endif
-
-#ifndef LOCALE_SNAME
-#define LOCALE_SNAME 0x0000005c
-#endif
-
-#ifndef LOCALE_SNAN
-#define LOCALE_SNAN 0x00000069
-#endif
-
-#ifndef LOCALE_SPOSINFINITY
-#define LOCALE_SPOSINFINITY 0x0000006a
-#endif
-
-#ifndef LOCALE_SNEGINFINITY
-#define LOCALE_SNEGINFINITY 0x0000006b
-#endif
-
-#ifndef LOCALE_SPARENT
-#define LOCALE_SPARENT 0x0000006d
-#endif
-
-#ifndef LOCALE_SCONSOLEFALLBACKNAME
-#define LOCALE_SCONSOLEFALLBACKNAME 0x0000006e // Fallback name for within the console
-#endif
-
-#ifndef LOCALE_SISO3166CTRYNAME2
-#define LOCALE_SISO3166CTRYNAME2 0x00000068
-#endif
-
-#ifndef LOCALE_SISO639LANGNAME2
-#define LOCALE_SISO639LANGNAME2 0x00000067
-#endif
-
-#ifndef LOCALE_SSHORTESTDAYNAME1
-#define LOCALE_SSHORTESTDAYNAME1 0x00000060
-#endif
-
-// Windows 7 LCTypes
-#ifndef LOCALE_INEUTRAL
-#define LOCALE_INEUTRAL 0x00000071 // Returns 0 for specific cultures, 1 for neutral cultures.
-#endif
-
-#ifndef LCMAP_TITLECASE
-#define LCMAP_TITLECASE 0x00000300 // Title Case Letters
-#endif
-
-// Windows 8 LCTypes
-#ifndef LCMAP_SORTHANDLE
-#define LCMAP_SORTHANDLE 0x20000000
-#endif
-
-#ifndef LCMAP_HASH
-#define LCMAP_HASH 0x00040000
-#endif
-
-#ifndef LOCALE_REPLACEMENT
-#define LOCALE_REPLACEMENT 0x00000008 // locales that replace shipped locales (callback flag only)
-#endif // LOCALE_REPLACEMENT
-
-#define LOCALE_MAX_STRING_SIZE 530 // maximum sice of LOCALE_SKEYBOARDSTOINSTALL, currently 5 "long" + 2 "short" keyboard signatures (YI + 3).
-
#define MAX_STRING_VALUE 512
// TODO: NLS Arrowhead -Be nice if we could depend more on the OS for this
@@ -115,344 +50,7 @@
#define LANGID_ZH_TW 0x0404
// Language ID for CHT (Hong-Kong)
#define LANGID_ZH_HK 0x0c04
-#define REGION_NAME_0404 W("\x53f0\x7063")
-#if BIGENDIAN
-#define INTERNATIONAL_CURRENCY_SYMBOL W("\x00a4")
-#else
-#define INTERNATIONAL_CURRENCY_SYMBOL W("\xa400")
-#endif
-
-inline BOOL IsCustomCultureId(LCID lcid)
-{
- return (lcid == LOCALE_CUSTOM_DEFAULT || lcid == LOCALE_CUSTOM_UNSPECIFIED);
-}
-
-#ifndef FEATURE_COREFX_GLOBALIZATION
-//
-// Normalization Implementation
-//
-#define NORMALIZATION_DLL MAKEDLLNAME(W("normalization"))
-HMODULE COMNlsInfo::m_hNormalization = NULL;
-PFN_NORMALIZATION_IS_NORMALIZED_STRING COMNlsInfo::m_pfnNormalizationIsNormalizedStringFunc = NULL;
-PFN_NORMALIZATION_NORMALIZE_STRING COMNlsInfo::m_pfnNormalizationNormalizeStringFunc = NULL;
-PFN_NORMALIZATION_INIT_NORMALIZATION COMNlsInfo::m_pfnNormalizationInitNormalizationFunc = NULL;
-#endif // FEATURE_COREFX_GLOBALIZATION
-
-#if FEATURE_CODEPAGES_FILE
-/*============================nativeCreateOpenFileMapping============================
-**Action: Create or open a named memory file mapping.
-**Returns: Pointer to named section, or NULL if failed
-**Arguments:
-** StringObject* inSectionName - name of section to open/create
-** int inBytesToAllocate - desired size of memory section in bytes
-** We use the last 4 bytes (must be aligned, so only choose
-** inBytesToAllocate in multiples of 4) to indicate if the
-** section is set or not. AFTER section is initialized, set
-** those 4 bytes to non-0, otherwise you'll get get new
-** heap memory all the time.
-** HANDLE* mappedFile - is the handle of the memory mapped file. this is
-** out parameter.
-**
-** NOTE: We'll try to open the same object, so we can share names. We don't lock
-** though, so 2 thread could get the same object, but thread 1 might not
-** have initialized it yet.
-**
-** NOTE: For NT you should add a Global\ to the beginning of the name if you
-** want to share it machine wide.
-**
-==============================================================================*/
-FCIMPL3(LPVOID, COMNlsInfo::nativeCreateOpenFileMapping,
- StringObject* inSectionNameUNSAFE, int inBytesToAllocate, HANDLE *mappedFile)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(inSectionNameUNSAFE));
- PRECONDITION(inBytesToAllocate % 4 == 0);
- PRECONDITION(inBytesToAllocate > 0);
- PRECONDITION(CheckPointer(mappedFile));
- } CONTRACTL_END;
-
- // Need a place for our result
- LPVOID pResult = NULL;
-
- STRINGREF inString(inSectionNameUNSAFE);
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(inString);
-
- _ASSERTE(inBytesToAllocate % 4 == 0); // Expected 4 bytes boundaries so we don't get unaligned
- _ASSERTE(inBytesToAllocate > 0); // Pointless to have <=0 allocation
-
- StackSString inNameStackBuffer (inString->GetBuffer());
- pResult = NLSTable::OpenOrCreateMemoryMapping((LPCWSTR)inNameStackBuffer, inBytesToAllocate, mappedFile);
-
- // Worst case allocate some memory, use holder
- // if (pResult == NULL) pResult = new BYTE[inBytesToAllocate];
- if (pResult == NULL)
- {
- // Need to use a NewHolder
- NewArrayHolder<BYTE> holder (new BYTE[inBytesToAllocate]);
- pResult = holder;
- // Zero out the mapCodePageCached field (an int value, and it's used to check if the section is initialized or not.)
- BYTE* pByte = (BYTE*)pResult;
- FillMemory(pByte + inBytesToAllocate - sizeof(int), sizeof(int), 0);
- holder.SuppressRelease();
- }
-
- HELPER_METHOD_FRAME_END();
-
- return pResult;
-}
-FCIMPLEND
-#endif // FEATURE_CODEPAGES_FILE
-
-// InternalIsSortable
-//
-// Called by CompareInfo.IsSortable() to determine if a string has entirely sortable (ie: defined) code points.
-BOOL QCALLTYPE COMNlsInfo::InternalIsSortable(INT_PTR handle, INT_PTR handleOrigin, LPCWSTR localeName, LPCWSTR string, INT32 length)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(CheckPointer(string));
- } CONTRACTL_END;
- BOOL result = FALSE;
- BEGIN_QCALL;
-
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
- if(!(curDomain->m_bUseOsSorting))
- {
- handle = EnsureValidSortHandle(handle, handleOrigin, localeName);
- result = SortVersioning::SortDllIsDefinedString((SortVersioning::PSORTHANDLE) handle, COMPARE_STRING, 0, string, length);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- result = (curDomain->m_pCustomSortLibrary->pIsNLSDefinedString)(COMPARE_STRING, 0, NULL, string, length);
- }
- else
-#endif
- {
- // Function should be COMPARE_STRING, dwFlags should be NULL, lpVersionInfo should be NULL for now
- result = NewApis::IsNLSDefinedString(COMPARE_STRING, 0, NULL, string, length);
- }
-
- END_QCALL;
- return result;
-}
-
-////////////////////////////////////////////////////////////////////////////
-//
-// InternalGetUserDefaultLocaleName
-//
-// Returns a string with the name of our LCID and returns 0 in LCID.
-// If we cant return
-//
-////////////////////////////////////////////////////////////////////////////
-// This is new to longhorn
-BOOL QCALLTYPE COMNlsInfo::InternalGetDefaultLocaleName(INT32 langType, QCall::StringHandleOnStack defaultLocaleName)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION((langType == LOCALE_SYSTEM_DEFAULT) || (langType == LOCALE_USER_DEFAULT));
- } CONTRACTL_END;
-
- BOOL result;
- BEGIN_QCALL;
-
- WCHAR strName[LOCALE_NAME_MAX_LENGTH];
- int size = 0;
-
- if (langType == LOCALE_SYSTEM_DEFAULT)
- {
- size = NewApis::GetSystemDefaultLocaleName(strName,NumItems(strName));
- }
- else
- {
- _ASSERT(langType == LOCALE_USER_DEFAULT);
- size = NewApis::GetUserDefaultLocaleName(strName,NumItems(strName));
- }
-
- // Not found, either not longhorn (no LOCALE_SNAME) or not a valid name
- if (size == 0)
- {
- result = false;
- }
- else
- {
- defaultLocaleName.Set(strName);
- result = true;
- }
- END_QCALL;
- return result;
-}
-
-BOOL QCALLTYPE COMNlsInfo::InternalGetSystemDefaultUILanguage(QCall::StringHandleOnStack systemDefaultUiLanguage)
-{
- QCALL_CONTRACT;
- BOOL result;
- BEGIN_QCALL;
-
- WCHAR localeName[LOCALE_NAME_MAX_LENGTH];
-
- int systemDefaultUiLcid = GetSystemDefaultUILanguage();
- if(systemDefaultUiLcid == LANGID_ZH_TW)
- {
- if (!NewApis::IsZhTwSku())
- {
- systemDefaultUiLcid = LANGID_ZH_HK;
- }
- }
-
- int length = NewApis::LCIDToLocaleName(systemDefaultUiLcid, localeName, NumItems(localeName), 0);
- if (length == 0)
- {
- result = false;
- }
- else
- {
- systemDefaultUiLanguage.Set(localeName);
- result = true;
- }
-
- END_QCALL;
- return result;
-}
-
-/*
- */
-BOOL QCALLTYPE COMNlsInfo::InternalGetUserDefaultUILanguage(QCall::StringHandleOnStack userDefaultUiLanguage)
-{
- QCALL_CONTRACT;
- BOOL result;
- BEGIN_QCALL;
-
- WCHAR wszBuffer[LOCALE_NAME_MAX_LENGTH];
- LPCWSTR wszLangName=NULL;
-
- int res= 0;
- ULONG uLangCount=0;
- ULONG uBufLen=0;
- res= NewApis::GetUserPreferredUILanguages (MUI_LANGUAGE_NAME,&uLangCount,NULL,&uBufLen);
- if (res == 0)
- ThrowLastError();
-
-
- NewArrayHolder<WCHAR> sPreferredLanguages(NULL);
-
- if (uBufLen > 0 && uLangCount > 0 )
- {
- sPreferredLanguages = new WCHAR[uBufLen];
- res= NewApis::GetUserPreferredUILanguages (MUI_LANGUAGE_NAME,&uLangCount,sPreferredLanguages,&uBufLen);
-
- if (res == 0)
- ThrowLastError();
-
- wszLangName=sPreferredLanguages;
-// Review size_t to int conversion (possible loss of data).
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4267)
-#endif
- res=wcslen(wszLangName)+1;
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
- }
- else
- {
- res=0;
- }
-
- if (res == 0) {
- res = NewApis::GetUserDefaultLocaleName(wszBuffer,NumItems(wszBuffer));
- wszLangName=wszBuffer;
- }
-
-
- // If not found, either not longhorn (no LOCALE_SNAME) or not a valid name
- if (res == 0)
- {
- // Didn't find string, return an empty string.
- result = false;
- }
- else
- {
- userDefaultUiLanguage.Set(wszLangName);
- result = true;
- }
-
- // Return the found language name. LCID should be found one already.
- END_QCALL;
- return result;
-}
-
-// Added but disabled from desktop in .NET 4.0, stayed disabled in .NET 4.5
-#ifdef FEATURE_CORECLR
-FCIMPL0(Object*, COMNlsInfo::nativeGetResourceFallbackArray)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- } CONTRACTL_END;
-
- DWORD dwFlags = MUI_MERGE_USER_FALLBACK | MUI_MERGE_SYSTEM_FALLBACK;
- ULONG cchLanguagesBuffer = 0;
- ULONG ulNumLanguages = 0;
- BOOL result = FALSE;
-
- struct _gc
- {
- PTRARRAYREF resourceFallbackArray;
- } gc;
-
- gc.resourceFallbackArray = NULL;
-
- // If the resource lookups we're planning on doing are going to be written to a non-Unicode console,
- // then we should ideally only return languages that can be displayed correctly on the console. The
- // trick is guessing at whether we're writing this data to the console, which we can't do well.
- // Instead, we ask new apps to call GetConsoleFallbackUICulture & fall back to en-US.
- bool disableUserFallback;
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException));
- disableUserFallback = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Resources_DisableUserPreferredFallback) == 1
- END_SO_INTOLERANT_CODE;
-
- if (disableUserFallback)
- return NULL;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
-
- // first call with null buffer to get size
- result = NewApis::GetThreadPreferredUILanguages(dwFlags, &ulNumLanguages, NULL, &cchLanguagesBuffer);
- if (cchLanguagesBuffer > 0)
- {
- NewArrayHolder<WCHAR> stringBuffer = new (nothrow) WCHAR[cchLanguagesBuffer];
- if (stringBuffer != NULL)
- {
- result = NewApis::GetThreadPreferredUILanguages(dwFlags, &ulNumLanguages, stringBuffer, &cchLanguagesBuffer);
- _ASSERTE(result);
-
- // now string into strings
- gc.resourceFallbackArray = (PTRARRAYREF) AllocateObjectArray(ulNumLanguages, g_pStringClass);
-
- LPCWSTR buffer = stringBuffer; // Restart @ buffer beginning
- for(DWORD i = 0; i < ulNumLanguages; i++)
- {
- OBJECTREF o = (OBJECTREF) StringObject::NewString(buffer);
- gc.resourceFallbackArray->SetAt(i, o);
- buffer += (lstrlenW(buffer) + 1);
- }
- }
- }
- HELPER_METHOD_FRAME_END();
-
- return OBJECTREFToObject(gc.resourceFallbackArray);
-
-}
-FCIMPLEND
-#endif // FEATURE_CORECLR
INT32 COMNlsInfo::CallGetUserDefaultUILanguage()
{
@@ -488,1267 +86,12 @@ INT32 COMNlsInfo::CallGetUserDefaultUILanguage()
return s_lcid;
}
-INT_PTR COMNlsInfo::EnsureValidSortHandle(INT_PTR handle, INT_PTR handleOrigin, LPCWSTR localeName)
-{
- LIMITED_METHOD_CONTRACT;
-
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
- if(!(curDomain->m_bUseOsSorting) && handleOrigin == (INT_PTR) SortVersioning::GetSortHandle && ((SortVersioning::PSORTHANDLE) handle)->dwNLSVersion == curDomain->m_sortVersion)
- {
- return handle;
- }
-
- if(curDomain->m_bUseOsSorting && curDomain->m_pCustomSortLibrary == NULL && handleOrigin == (INT_PTR) NewApis::LCMapStringEx)
- {
- return handle;
- }
-
- if(curDomain->m_bUseOsSorting && curDomain->m_pCustomSortLibrary != NULL && handleOrigin == (INT_PTR) curDomain->m_pCustomSortLibrary->pLCMapStringEx)
- {
- return handle;
- }
-
- // At this point, we can't reuse the sort handle (it has different sort semantics than this domain) so we need to get a new one.
- INT_PTR newHandleOrigin;
- return InitSortHandleHelper(localeName, &newHandleOrigin);
-#else
- // For CoreCLR, on Windows 8 and up the handle will be valid. on downlevels the handle will be null
- return handle;
-#endif
-}
-
-#ifdef FEATURE_SYNTHETIC_CULTURES
-////////////////////////////////////////////////////////////////////////////
-//
-// WstrToInteger4
-//
-////////////////////////////////////////////////////////////////////////////
-
-/*=================================WstrToInteger4==================================
-**Action: Convert a Unicode string to an integer. Error checking is ignored.
-**Returns: The integer value of wstr
-**Arguments:
-** wstr: NULL terminated wide string. Can have character 0'-'9', 'a'-'f', and 'A' - 'F'
-** Radix: radix to be used in the conversion.
-**Exceptions: None.
-==============================================================================*/
-
-INT32 COMNlsInfo::WstrToInteger4(
- __in_z LPCWSTR wstr,
- __in int Radix)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- PRECONDITION(CheckPointer(wstr));
- PRECONDITION(Radix > 1 && Radix <= 16);
- } CONTRACTL_END;
- INT32 Value = 0;
- int Base = 1;
-
- for (int Length = Wszlstrlen(wstr) - 1; Length >= 0; Length--)
-
- {
- WCHAR ch = wstr[Length];
- _ASSERTE((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'));
- if (ch >= 'a')
- {
- ch = ch - 'a' + 'A';
- }
-
- Value += ((ch >= 'A') ? (ch - 'A' + 10) : (ch - '0')) * Base;
- Base *= Radix;
- }
-
- return (Value);
-}
-#endif // FEATURE_SYNTHETIC_CULTURES
-
-
-#ifndef FEATURE_CORECLR
-FCIMPL1(FC_BOOL_RET, COMNlsInfo::nativeSetThreadLocale, StringObject* localeNameUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(localeNameUNSAFE));
- } CONTRACTL_END;
-
- LCID lcid = 0;
-
- // TODO: NLS Arrowhead -A bit scary becausue Set ThreadLocale can't handle custom cultures?
- STRINGREF localeName = (STRINGREF)localeNameUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(localeName);
- lcid=NewApis::LocaleNameToLCID(localeName->GetBuffer(),0);
- if (lcid == 0)
- {
- ThrowHR(HRESULT_FROM_WIN32(GetLastError()));
- }
- HELPER_METHOD_FRAME_END();
-
-
- BOOL result = TRUE;
-
- // SetThreadLocale doesn't handle names/custom cultures
-#ifdef _MSC_VER
-// Get rid of the SetThreadLocale warning in OACR:
-#pragma warning(push)
-#pragma warning(disable:38010)
-#endif
- result = ::SetThreadLocale(lcid);
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
- FC_RETURN_BOOL(result);
-}
-FCIMPLEND
-#endif
-
-
-FCIMPL2(Object*, COMNlsInfo::nativeGetLocaleInfoEx, StringObject* localeNameUNSAFE, INT32 lcType)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(localeNameUNSAFE));
- } CONTRACTL_END;
-
- struct _gc
- {
- STRINGREF localeName;
- STRINGREF refRetVal;
- } gc;
-
- // Dereference our string
- gc.refRetVal = NULL;
- gc.localeName = (STRINGREF)localeNameUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
- StackSString localeNameStackBuffer( gc.localeName->GetBuffer() );
-
- WCHAR buffer[LOCALE_MAX_STRING_SIZE];
- int result = NewApis::GetLocaleInfoEx(localeNameStackBuffer, lcType, buffer, NumItems(buffer));
-
- // Make a string out of it
- if (result != 0)
- {
- // Exclude the NULL char at the end, except that LOCALE_FONTSIGNATURE isn't
- // really a string, so we need the last character too.
- gc.refRetVal = StringObject::NewString(buffer, ((lcType & ~LOCALE_NOUSEROVERRIDE) == LOCALE_FONTSIGNATURE) ? result : result-1);
- }
- else
- {
- }
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(gc.refRetVal);
-}
-FCIMPLEND
-
-
-FCIMPL2(INT32, COMNlsInfo::nativeGetLocaleInfoExInt, StringObject* localeNameUNSAFE, INT32 lcType)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(localeNameUNSAFE));
- } CONTRACTL_END;
-
- INT32 result = 0;
-
- // Dereference our string
- STRINGREF localeName = (STRINGREF)localeNameUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(localeName);
-
- lcType |= LOCALE_RETURN_NUMBER;
-
- if (NewApis::GetLocaleInfoEx(localeName->GetBuffer(), lcType, (LPWSTR)&result, sizeof(INT32) / sizeof (WCHAR)) == 0)
- {
- // return value of 0 indicates failure and error value is supposed to be set.
- // shouldn't ever really happen
- _ASSERTE(!"catastrophic failure calling NewApis::nativeGetLocaleInfoExInt! This could be a CultureInfo bug (bad localeName string) or maybe a GCHole.");
- }
-
- HELPER_METHOD_FRAME_END();
-
- return result;
-}
-FCIMPLEND
-
-
-
-////////////////////////////////////////////////////////////////////////
-//
-// Call the Win32 GetLocaleInfo() using the specified lcid to retrieve
-// the native digits, probably from the registry override. The return
-// indicates whether the call was successful.
-//
-// Parameters:
-// IN lcid the LCID to make the Win32 call with
-// OUT pOutputStrAry The output managed string array.
-//
-////////////////////////////////////////////////////////////////////////
-BOOL COMNlsInfo::GetNativeDigitsFromWin32(LPCWSTR locale, PTRARRAYREF * pOutputStrAry, BOOL useUserOverride)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- } CONTRACTL_END;
-
- WCHAR buffer[11];
- int result = 0;
-
- DWORD lcType = LOCALE_SNATIVEDIGITS;
- if(!useUserOverride)
- {
- lcType |= LOCALE_NOUSEROVERRIDE;
- }
- result = NewApis::GetLocaleInfoEx(locale, lcType, buffer, 11);
- // Be very unforgiving and only support strings of size 10 plus the NULL
- if (result == 11)
- {
- // Break up the unmanaged ten-character ZLS into what NFI wants (a managed
- // ten-string array).
- //
- // Allocate the array of STRINGREFs. We don't need to check for null because the GC will throw
- // an OutOfMemoryException if there's not enough memory.
- //
- PTRARRAYREF DigitArray = (PTRARRAYREF) AllocateObjectArray(10, g_pStringClass);
-
- GCPROTECT_BEGIN(DigitArray);
- for(DWORD i = 0; i < 10; i++) {
- OBJECTREF o = (OBJECTREF) StringObject::NewString(buffer + i, 1);
- DigitArray->SetAt(i, o);
- }
- GCPROTECT_END();
-
- _ASSERTE(pOutputStrAry != NULL);
- *pOutputStrAry = DigitArray;
- }
-
- return (result == 11);
-}
-
-
-////////////////////////////////////////////////////////////////////////
-//
-// Call the Win32 GetLocaleInfoEx() using the specified lcid and LCTYPE.
-// The return value can be INT32 or an allocated managed string object, depending on
-// which version's called.
-//
-// Parameters:
-// OUT pOutputInt32 The output int32 value.
-// OUT pOutputRef The output string value.
-//
-////////////////////////////////////////////////////////////////////////
-BOOL COMNlsInfo::CallGetLocaleInfoEx(LPCWSTR localeName, int lcType, INT32* pOutputInt32, BOOL useUserOverride)
-{
- CONTRACTL
- {
- GC_NOTRIGGER;
- MODE_ANY;
- NOTHROW;
- } CONTRACTL_END;
-
- int result = 0;
-
- _ASSERT((lcType & LOCALE_RETURN_NUMBER) != 0);
- if(!useUserOverride)
- {
- lcType |= LOCALE_NOUSEROVERRIDE;
- }
- result = NewApis::GetLocaleInfoEx(localeName, lcType, (LPWSTR)pOutputInt32, sizeof(*pOutputInt32));
-
- return (result != 0);
-}
-
-BOOL COMNlsInfo::CallGetLocaleInfoEx(LPCWSTR localeName, int lcType, STRINGREF* pOutputStrRef, BOOL useUserOverride)
-{
- CONTRACTL
- {
- THROWS; // We can throw since we are allocating managed string.
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- } CONTRACTL_END;
-
- WCHAR buffer[LOCALE_NAME_MAX_LENGTH];
- int result = 0;
-
- _ASSERT((lcType & LOCALE_RETURN_NUMBER) == 0);
- if(!useUserOverride)
- {
- lcType |= LOCALE_NOUSEROVERRIDE;
- }
- result = NewApis::GetLocaleInfoEx(localeName, lcType, buffer, LOCALE_NAME_MAX_LENGTH);
-
- if (result != 0)
- {
- _ASSERTE(pOutputStrRef != NULL);
- *pOutputStrRef = StringObject::NewString(buffer, result - 1);
- }
-
- return (result != 0);
-}
-
-FCIMPL1(Object*, COMNlsInfo::LCIDToLocaleName, LCID lcid)
-{
- FCALL_CONTRACT;
-
- STRINGREF refRetVal = NULL;
-
- // The maximum size for locale name is 85 characters.
- WCHAR localeName[LOCALE_NAME_MAX_LENGTH];
- int result = 0;
-
- HELPER_METHOD_FRAME_BEGIN_RET_0();
-
- // Note that this'll return neutral names (unlike native Vista APIs)
- result = NewApis::LCIDToLocaleName(lcid, localeName, LOCALE_NAME_MAX_LENGTH, 0);
-
- if (result != 0)
- {
- refRetVal = StringObject::NewString(localeName, result - 1);
- }
- else
- {
- refRetVal = StringObject::GetEmptyString();
- }
-
- HELPER_METHOD_FRAME_END();
-
- return OBJECTREFToObject(refRetVal);
-}
-FCIMPLEND
-
-FCIMPL1(INT32, COMNlsInfo::LocaleNameToLCID, StringObject* localeNameUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(localeNameUNSAFE));
- } CONTRACTL_END;
-
- INT32 result = 0;
-
- // Dereference our string
- STRINGREF localeName = (STRINGREF)localeNameUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(localeName);
-
- // Note that this'll return neutral names (unlike native Vista APIs)
- result = NewApis::LocaleNameToLCID(localeName->GetBuffer(), 0);
-
- HELPER_METHOD_FRAME_END();
-
- return result;
-}
-FCIMPLEND
-
-////////////////////////////////////////////////////////////////////////
-//
-// Implementation of CultureInfo.nativeGetNumberFormatInfoValues.
-//
-// Retrieve NumberFormatInfo (NFI) properties from windows
-//
-// Parameters:
-// IN/OUT pNumfmtUNSAFE
-// The pointer of the managed NumberFormatInfo passed
-// from the managed side.
-// Note that the native NumberFormatInfo* is defined
-// in COMNumber.h
-// Note:
-// Managed string will be allocated and assign to the string fields in
-// the managed NumberFormatInfo passed in pNumftUNSAFE
-//
-////////////////////////////////////////////////////////////////////////
-
-
-/*
- This is the list of the data members in the managed NumberFormatInfo and their
- corresponding LCTYPE().
-
- Win32 GetLocaleInfo() constants Data members in NumberFormatInfo in the defined order.
- LOCALE_SPOSITIVE // String positiveSign
- LOCALE_SNEGATIVE // String negativeSign
- LOCALE_SDECIMAL // String numberDecimalSeparator
- LOCALE_SGROUPING // String numberGroupSeparator
- LOCALE_SMONGROUPING // String currencyGroupSeparator
- LOCALE_SMONDECIMALSEP // String currencyDecimalSeparator
- LOCALE_SCURRENCY // String currencySymbol
- N/A // String ansiCurrencySymbol
- N/A // String nanSymbol
- N/A // String positiveInfinitySymbol
- N/A // String negativeInfinitySymbol
- N/A // String percentDecimalSeparator
- N/A // String percentGroupSeparator
- N/A // String percentSymbol
- N/A // String perMilleSymbol
-
- N/A // int m_dataItem
-
- LOCALE_IDIGITS | LOCALE_RETURN_NUMBER, // int numberDecimalDigits
- LOCALE_ICURRDIGITS | LOCALE_RETURN_NUMBER, // int currencyDecimalDigits
- LOCALE_ICURRENCY | LOCALE_RETURN_NUMBER, // int currencyPositivePattern
- LOCALE_INEGCURR | LOCALE_RETURN_NUMBER, // int currencyNegativePattern
- LOCALE_INEGNUMBER| LOCALE_RETURN_NUMBER, // int numberNegativePattern
- N/A // int percentPositivePattern
- N/A // int percentNegativePattern
- N/A // int percentDecimalDigits
- N/A // bool isReadOnly=false;
- N/A // internal bool m_useUserOverride;
-*/
-FCIMPL3(FC_BOOL_RET, COMNlsInfo::nativeGetNumberFormatInfoValues,
- StringObject* localeNameUNSAFE, NumberFormatInfo* pNumfmtUNSAFE, CLR_BOOL useUserOverride) {
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(localeNameUNSAFE));
- } CONTRACTL_END;
-
- BOOL ret = TRUE;
-
- struct _gc
- {
- STRINGREF localeName;
- STRINGREF stringResult;
- NUMFMTREF numfmt;
- PTRARRAYREF tempArray;
- } gc;
-
- // Dereference our string
- gc.localeName = (STRINGREF)localeNameUNSAFE;
- gc.numfmt = (NUMFMTREF) pNumfmtUNSAFE;
- gc.stringResult = NULL;
- gc.tempArray = NULL;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
- StackSString localeNameStackBuffer( gc.localeName->GetBuffer() );
-
- // Calling SString::ConvertToUnicode once
- LPCWSTR pLocaleName = localeNameStackBuffer;
-
- //
- // NOTE: We pass the stringResult allocated in the stack and assign it to the fields
- // in numfmt after calling CallGetLocaleInfo(). The reason for this is that CallGetLocaleInfo()
- // allocates a string object, and it may trigger a GC and cause numfmt to be moved.
- // That's why we use the stringResult allocated in the stack since it will not be moved.
- // After CallGetLocaleInfo(), we know that numfmt will not be moved, and it's safe to assign
- // the stringResult to its field.
- //
-
- // String values
- if (CallGetLocaleInfoEx(pLocaleName, LOCALE_SPOSITIVESIGN , &gc.stringResult, useUserOverride)) {
- SetObjectReference((OBJECTREF*)&(gc.numfmt->sPositive), gc.stringResult, NULL);
- }
- else {
- ret = FALSE;
- _ASSERT(FALSE);
- }
-
- if (CallGetLocaleInfoEx(pLocaleName, LOCALE_SNEGATIVESIGN , &gc.stringResult, useUserOverride)) {
- SetObjectReference((OBJECTREF*)&(gc.numfmt->sNegative), gc.stringResult, NULL);
- }
- else {
- ret = FALSE;
- _ASSERT(FALSE);
- }
- if (CallGetLocaleInfoEx(pLocaleName, LOCALE_SDECIMAL , &gc.stringResult, useUserOverride)) {
- SetObjectReference((OBJECTREF*)&(gc.numfmt->sNumberDecimal), gc.stringResult, NULL);
- }
- else {
- ret = FALSE;
- _ASSERT(FALSE);
- }
- if (CallGetLocaleInfoEx(pLocaleName, LOCALE_STHOUSAND , &gc.stringResult, useUserOverride)) {
- SetObjectReference((OBJECTREF*)&(gc.numfmt->sNumberGroup), gc.stringResult, NULL);
- }
- else {
- ret = FALSE;
- _ASSERT(FALSE);
- }
- if (CallGetLocaleInfoEx(pLocaleName, LOCALE_SMONTHOUSANDSEP , &gc.stringResult, useUserOverride)) {
- SetObjectReference((OBJECTREF*)&(gc.numfmt->sCurrencyGroup), gc.stringResult, NULL);
- }
- else {
- ret = FALSE;
- _ASSERT(FALSE);
- }
- if (CallGetLocaleInfoEx(pLocaleName, LOCALE_SMONDECIMALSEP , &gc.stringResult, useUserOverride)) {
- SetObjectReference((OBJECTREF*)&(gc.numfmt->sCurrencyDecimal), gc.stringResult, NULL);
- }
- else {
- ret = FALSE;
- _ASSERT(FALSE);
- }
- if (CallGetLocaleInfoEx(pLocaleName, LOCALE_SCURRENCY , &gc.stringResult, useUserOverride)) {
- SetObjectReference((OBJECTREF*)&(gc.numfmt->sCurrency), gc.stringResult, NULL);
- }
- else {
- ret = FALSE;
- _ASSERT(FALSE);
- }
-
-
- // Numeric values
- ret &= CallGetLocaleInfoEx(pLocaleName, LOCALE_IDIGITS | LOCALE_RETURN_NUMBER , &(gc.numfmt->cNumberDecimals), useUserOverride);
- _ASSERT(ret == TRUE);
- ret &= CallGetLocaleInfoEx(pLocaleName, LOCALE_ICURRDIGITS | LOCALE_RETURN_NUMBER , &(gc.numfmt->cCurrencyDecimals), useUserOverride);
- _ASSERT(ret == TRUE);
- ret &= CallGetLocaleInfoEx(pLocaleName, LOCALE_ICURRENCY | LOCALE_RETURN_NUMBER , &(gc.numfmt->cPosCurrencyFormat), useUserOverride);
- _ASSERT(ret == TRUE);
- ret &= CallGetLocaleInfoEx(pLocaleName, LOCALE_INEGCURR | LOCALE_RETURN_NUMBER , &(gc.numfmt->cNegCurrencyFormat), useUserOverride);
- _ASSERT(ret == TRUE);
- ret &= CallGetLocaleInfoEx(pLocaleName, LOCALE_INEGNUMBER| LOCALE_RETURN_NUMBER , &(gc.numfmt->cNegativeNumberFormat), useUserOverride);
- _ASSERT(ret == TRUE);
- ret &= CallGetLocaleInfoEx(pLocaleName, LOCALE_IDIGITSUBSTITUTION | LOCALE_RETURN_NUMBER, &(gc.numfmt->iDigitSubstitution), useUserOverride);
- _ASSERT(ret == TRUE);
-
- // LOCALE_SNATIVEDIGITS (gc.tempArray of strings)
- if (GetNativeDigitsFromWin32(pLocaleName, &gc.tempArray, useUserOverride)) {
- SetObjectReference((OBJECTREF*)&(gc.numfmt->sNativeDigits), gc.tempArray, NULL);
- }
- else {
- ret = FALSE;
- _ASSERT(FALSE);
- }
-
- HELPER_METHOD_FRAME_END();
- FC_RETURN_BOOL(ret);
-}
-FCIMPLEND
-
-
-////////////////////////////////////////////////////////////////////////
-//
-// Culture enumeration helper functions
-//
-////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////
-//
-// Enum values for System.Globalization.CultureTypes
-//
-////////////////////////////////////////////////////////////////////////////
-
-// Neutral cultures are cultures like "en", "de", "zh", etc, for enumeration this includes ALL neutrals regardless of other flags
-#define CULTURETYPES_NEUTRALCULTURES 0x0001
-
-// Non-netural cultuers. Examples are "en-us", "zh-tw", etc., for enumeration this includes ALL specifics regardless of other flags
-#define CULTURETYPES_SPECIFICCULTURES 0x0002
-
-// Win32 installed cultures in the system and exists in the framework too., this is effectively all cultures
-#define CULTURETYPES_INSTALLEDWIN32CULTURES 0x0004
-
-// User defined custom culture
-#define CULTURETYPES_USERCUSTOMCULTURE 0x0008
-
-// User defined replacement custom culture.
-#define CULTURETYPES_REPLACEMENTCULTURES 0x0010
-// [Obsolete("This value has been deprecated. Please use other values in CultureTypes.")]
-// Culture exists in Win32 but not in the Framework. // TODO: All cultures or no cultures?
-#define CULTURETYPES_WINDOWSONLYCULTURES 0x0020
-// [Obsolete("This value has been deprecated. Please use other values in CultureTypes.")]
-// the language tag match a culture that ships with the .NET framework, effectively all cultures since we get them from windows
-#define CULTURETYPES_FRAMEWORKCULTURES 0x0040
-
-
-const LPCWSTR WHIDBEY_FRAMEWORK_CULTURE_LIST [] =
-{
- W(""),
- W("af"),
- W("af-za"),
- W("ar"),
- W("ar-ae"),
- W("ar-bh"),
- W("ar-dz"),
- W("ar-eg"),
- W("ar-iq"),
- W("ar-jo"),
- W("ar-kw"),
- W("ar-lb"),
- W("ar-ly"),
- W("ar-ma"),
- W("ar-om"),
- W("ar-qa"),
- W("ar-sa"),
- W("ar-sy"),
- W("ar-tn"),
- W("ar-ye"),
- W("az"),
- W("az-cyrl-az"),
- W("az-latn-az"),
- W("be"),
- W("be-by"),
- W("bg"),
- W("bg-bg"),
- W("ca"),
- W("ca-es"),
- W("cs"),
- W("cs-cz"),
- W("da"),
- W("da-dk"),
- W("de"),
- W("de-at"),
- W("de-ch"),
- W("de-de"),
- W("de-li"),
- W("de-lu"),
- W("dv"),
- W("dv-mv"),
- W("el"),
- W("el-gr"),
- W("en"),
- W("en-029"),
- W("en-au"),
- W("en-bz"),
- W("en-ca"),
- W("en-gb"),
- W("en-ie"),
- W("en-jm"),
- W("en-nz"),
- W("en-ph"),
- W("en-tt"),
- W("en-us"),
- W("en-za"),
- W("en-zw"),
- W("es"),
- W("es-ar"),
- W("es-bo"),
- W("es-cl"),
- W("es-co"),
- W("es-cr"),
- W("es-do"),
- W("es-ec"),
- W("es-es"),
- W("es-gt"),
- W("es-hn"),
- W("es-mx"),
- W("es-ni"),
- W("es-pa"),
- W("es-pe"),
- W("es-pr"),
- W("es-py"),
- W("es-sv"),
- W("es-uy"),
- W("es-ve"),
- W("et"),
- W("et-ee"),
- W("eu"),
- W("eu-es"),
- W("fa"),
- W("fa-ir"),
- W("fi"),
- W("fi-fi"),
- W("fo"),
- W("fo-fo"),
- W("fr"),
- W("fr-be"),
- W("fr-ca"),
- W("fr-ch"),
- W("fr-fr"),
- W("fr-lu"),
- W("fr-mc"),
- W("gl"),
- W("gl-es"),
- W("gu"),
- W("gu-in"),
- W("he"),
- W("he-il"),
- W("hi"),
- W("hi-in"),
- W("hr"),
- W("hr-hr"),
- W("hu"),
- W("hu-hu"),
- W("hy"),
- W("hy-am"),
- W("id"),
- W("id-id"),
- W("is"),
- W("is-is"),
- W("it"),
- W("it-ch"),
- W("it-it"),
- W("ja"),
- W("ja-jp"),
- W("ka"),
- W("ka-ge"),
- W("kk"),
- W("kk-kz"),
- W("kn"),
- W("kn-in"),
- W("ko"),
- W("ko-kr"),
- W("kok"),
- W("kok-in"),
- W("ky"),
- W("ky-kg"),
- W("lt"),
- W("lt-lt"),
- W("lv"),
- W("lv-lv"),
- W("mk"),
- W("mk-mk"),
- W("mn"),
- W("mn-mn"),
- W("mr"),
- W("mr-in"),
- W("ms"),
- W("ms-bn"),
- W("ms-my"),
- W("nb-no"),
- W("nl"),
- W("nl-be"),
- W("nl-nl"),
- W("nn-no"),
- W("no"),
- W("pa"),
- W("pa-in"),
- W("pl"),
- W("pl-pl"),
- W("pt"),
- W("pt-br"),
- W("pt-pt"),
- W("ro"),
- W("ro-ro"),
- W("ru"),
- W("ru-ru"),
- W("sa"),
- W("sa-in"),
- W("sk"),
- W("sk-sk"),
- W("sl"),
- W("sl-si"),
- W("sq"),
- W("sq-al"),
- W("sr"),
- W("sr-cyrl-cs"),
- W("sr-latn-cs"),
- W("sv"),
- W("sv-fi"),
- W("sv-se"),
- W("sw"),
- W("sw-ke"),
- W("syr"),
- W("syr-sy"),
- W("ta"),
- W("ta-in"),
- W("te"),
- W("te-in"),
- W("th"),
- W("th-th"),
- W("tr"),
- W("tr-tr"),
- W("tt"),
- W("tt-ru"),
- W("uk"),
- W("uk-ua"),
- W("ur"),
- W("ur-pk"),
- W("uz"),
- W("uz-cyrl-uz"),
- W("uz-latn-uz"),
- W("vi"),
- W("vi-vn"),
- W("zh-chs"),
- W("zh-cht"),
- W("zh-cn"),
- W("zh-hans"),
- W("zh-hant"),
- W("zh-hk"),
- W("zh-mo"),
- W("zh-sg"),
- W("zh-tw")
-};
-#define WHIDBEY_FRAMEWORK_CULTURE_LIST_LENGTH (sizeof(WHIDBEY_FRAMEWORK_CULTURE_LIST) / sizeof(WHIDBEY_FRAMEWORK_CULTURE_LIST[0]))
-
-////////////////////////////////////////////////////////////////////////////
-//
-// NlsCompareInvariantNoCase
-//
-// This routine does fast caseless comparison without needing the tables.
-// This helps us do the comparisons we need to load the tables :-)
-//
-// Returns 0 if identical, <0 if pFirst if first string sorts first.
-//
-// This is only intended to help with our locale name comparisons,
-// which are effectively limited to A-Z, 0-9, a-z and - where A-Z and a-z
-// compare as equal.
-//
-// WARNING: [\]^_` will be less than A-Z because we make everything lower
-// case before comparing them.
-//
-// When bNullEnd is TRUE, both of the strings should be null-terminator to be considered equal.
-// When bNullEnd is FALSE, the strings are considered equal when we reach the number of characters specifed by size
-// or when null terminators are reached, whichever happens first (strncmp-like behavior)
-//
-////////////////////////////////////////////////////////////////////////////
-
-int NlsCompareInvariantNoCase(
- LPCWSTR pFirst,
- LPCWSTR pSecond,
- int size,
- BOOL bNullEnd)
-{
- int i=0;
- WCHAR first;
- WCHAR second;
-
- for (;
- size > 0 && (first = *pFirst) != 0 && (second = *pSecond) != 0;
- size--, pFirst++, pSecond++)
- {
- // Make them lower case
- if ((first >= 'A') && (first <= 'Z')) first |= 0x20;
- if ((second >= 'A') && (second <= 'Z')) second |= 0x20;
-
- // Get the diff
- i = (first - second);
-
- // Are they the same?
- if (i == 0)
- continue;
-
- // Otherwise the difference. Remember we made A-Z into lower case, so
- // the characters [\]^_` will sort < A-Z and also < a-z. (Those are the
- // characters between A-Z and a-Z in ascii)
- return i;
- }
-
- // When we are here, one of these holds:
- // size == 0
- // or one of the strings has a null terminator
- // or both of the string reaches null terminator
-
- if (bNullEnd || size != 0)
- {
- // If bNullEnd is TRUE, always check for null terminator.
- // If bNullEnd is FALSE, we still have to check if one of the strings is terminated eariler
- // than another (hense the size != 0 check).
-
- // See if one string ended first
- if (*pFirst != 0 || *pSecond != 0)
- {
- // Which one?
- return *pFirst == 0 ? -1 : 1;
- }
- }
-
- // Return our difference (0)
- return i;
-}
-
-BOOL IsWhidbeyFrameworkCulture(__in LPCWSTR lpLocaleString)
-{
- int iBottom = 0;
- int iTop = WHIDBEY_FRAMEWORK_CULTURE_LIST_LENGTH - 1;
-
- // Do a binary search for our name
- while (iBottom <= iTop)
- {
- int iMiddle = (iBottom + iTop) / 2;
- int result = NlsCompareInvariantNoCase(lpLocaleString, WHIDBEY_FRAMEWORK_CULTURE_LIST[iMiddle], LOCALE_NAME_MAX_LENGTH, TRUE);
- if (result == 0)
- {
- return TRUE;
- }
- if (result < 0)
- {
- // pLocaleName was < pTest
- iTop = iMiddle - 1;
- }
- else
- {
- // pLocaleName was > pTest
- iBottom = iMiddle + 1;
- }
- }
-
- return FALSE;
-}
-
-// Just Check to see if the OS thinks it is a valid locle
-BOOL WINAPI IsOSValidLocaleName(__in LPCWSTR lpLocaleName, bool bIsNeutralLocale)
-{
-#ifndef ENABLE_DOWNLEVEL_FOR_NLS
- return ::IsValidLocaleName(lpLocaleName);
-#else
- BOOL IsWindows7 = NewApis::IsWindows7Platform();
- // if we're < Win7, we didn't know about neutrals or the invariant.
- if (!IsWindows7 && (bIsNeutralLocale || (lpLocaleName[0] == 0)))
- {
- return false;
- }
-
- // Work around the name/lcid thingy (can't just link to ::IsValidLocaleName())
- LCID lcid = NewApis::LocaleNameToLCID(lpLocaleName, 0);
-
- if (IsCustomCultureId(lcid))
- {
- return false;
- }
-
- if (bIsNeutralLocale)
- {
- // In this case, we're running on Windows 7.
- // For neutral locales, use GetLocaleInfoW.
- // If GetLocaleInfoW works, then the OS knows about it.
- return (::GetLocaleInfoW(lcid, LOCALE_ILANGUAGE, NULL, 0) != 0);
- }
-
- // This is not a custom locale.
- // Call IsValidLocale() to check if the LCID is installed.
- // IsValidLocale doesn't work for neutral locales.
- return IsValidLocale(lcid, LCID_INSTALLED);
-#endif
-}
-
-
-////////////////////////////////////////////////////////////////////////////
-//
-// Check the dwFlags, which has the 'attributes' of the locale, and decide
-// if the locale should be included in the enumeration based on
-// the desired CultureTypes.
-//
-////////////////////////////////////////////////////////////////////////////
-
-BOOL ShouldIncludeByCultureType(INT32 cultureTypes, LPCWSTR lpLocaleString, INT32 dwFlags)
-{
-
- if ((cultureTypes & CULTURETYPES_NEUTRALCULTURES) &&
- ((dwFlags & LOCALE_NEUTRALDATA) || (lpLocaleString[0] == 0))) // Invariant culture get enumerated with the neutrals
- {
- return TRUE;
- }
-
- if ((cultureTypes & CULTURETYPES_SPECIFICCULTURES) &&
- ((dwFlags & LOCALE_SPECIFICDATA) && (lpLocaleString[0] != 0))) // Invariant culture does not get enumerated with the specifics
- {
- return TRUE;
- }
-
- if (cultureTypes & CULTURETYPES_INSTALLEDWIN32CULTURES)
- {
- // The user asks for installed Win32 culture, so check
- // if this locale is installed. In W7 and above, when ::IsValidLocaleName()
- // returns true, it means that it is installed.
- // In downlevel (including Vista), we will convert the name to LCID.
- // When the LCID is not a custom locale, we will call ::IsValidLocale(.., LCID_INSTALLED)
- // to verify if the locale is installed.
- // In Vista, we treat custom locale as installed.
- if (IsOSValidLocaleName(lpLocaleString, (dwFlags & LOCALE_NEUTRALDATA) == LOCALE_NEUTRALDATA))
- {
- return TRUE;
- }
- }
-
- if ((cultureTypes & CULTURETYPES_USERCUSTOMCULTURE) &&
- (dwFlags & LOCALE_SUPPLEMENTAL))
- {
- return TRUE;
- }
-
- if ((cultureTypes & CULTURETYPES_REPLACEMENTCULTURES) &&
- (dwFlags & LOCALE_REPLACEMENT))
- {
- return TRUE;
- }
-
- if ((cultureTypes & CULTURETYPES_FRAMEWORKCULTURES) &&
- IsWhidbeyFrameworkCulture(lpLocaleString))
- {
- return TRUE;
- }
-
- //
- // No need to check CULTURETYPES_WINDOWSONLYCULTURES and CULTURETYPES_FRAMEWORKCULTURES
- // since they are deprecated, and they are handled in the managed code before calling
- // nativeEnumCultureNames.
- //
-
- return FALSE;
-}
-
-////////////////////////////////////////////////////////////////////////////
-//
-// Struct to hold context to be used in the callback for
-// EnumLocaleProcessingCallback
-//
-////////////////////////////////////////////////////////////////////////////
-
-typedef struct
-{
- PTRARRAYREF pCultureNamesArray;
- INT32 count;
- INT32 cultureTypes;
-} ENUM_LOCALE_DATA;
-
-////////////////////////////////////////////////////////////////////////////
-//
-// Callback for NewApis::EnumSystemLocalesEx to count the number of
-// locales to be enumerated.
-//
-////////////////////////////////////////////////////////////////////////////
-
-BOOL CALLBACK EnumLocaleCountCallback(__in_z LPCWSTR lpLocaleString, __in DWORD dwFlags, __in LPARAM lParam)
-{
- ENUM_LOCALE_DATA* pData = (ENUM_LOCALE_DATA*)lParam;
-
- if (ShouldIncludeByCultureType(pData->cultureTypes, lpLocaleString, dwFlags))
- {
- (pData->count)++;
- }
- return TRUE;
-}
-
-
-////////////////////////////////////////////////////////////////////////////
-//
-// Callback for NewApis::EnumSystemLocalesEx to add the locale name
-// into the allocated managed string array.
-//
-////////////////////////////////////////////////////////////////////////////
-
-BOOL CALLBACK EnumLocaleProcessingCallback(__in_z LPCWSTR lpLocaleString, __in DWORD dwFlags, __in LPARAM lParam)
-{
- ENUM_LOCALE_DATA* pData = (ENUM_LOCALE_DATA*)lParam;
-
- if (ShouldIncludeByCultureType(pData->cultureTypes, lpLocaleString, dwFlags))
- {
- GCX_COOP();
-
- GCPROTECT_BEGIN(pData->pCultureNamesArray);
-
- OBJECTREF cultureString = (OBJECTREF) StringObject::NewString(lpLocaleString);
- pData->pCultureNamesArray->SetAt(pData->count, cultureString);
- pData->count++;
-
- GCPROTECT_END();
- }
-
- return TRUE;
-}
-
-
-////////////////////////////////////////////////////////////////////////////
-//
-// Called by CultureData.GetCultures() to enumerate the names of cultures.
-// It first calls NewApis::EnumSystemLocalesEx to count the number of
-// locales to be enumerated. And it will allocate an managed string
-// array with the count. And fill the array with the culture names in
-// the 2nd call to NewAPis::EnumSystemLocalesEx.
-//
-////////////////////////////////////////////////////////////////////////////
-
-
-int QCALLTYPE COMNlsInfo::nativeEnumCultureNames(INT32 cultureTypes, QCall::ObjectHandleOnStack retStringArray)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- // Check CultureTypes.WindowsOnlyCultures and CultureTYpes.FrameworkCultures are deprecated and is
- // handled in the managed code side to provide fallback behavior.
- //PRECONDITION((cultureTypes & (CULTURETYPES_WINDOWSONLYCULTURES | CULTURETYPES_FRAMEWORKCULTURES) == 0));
- } CONTRACTL_END;
-
-
- int result;
- DWORD dwFlags = 0;
- PTRARRAYREF cultureNamesArray = NULL;
- ENUM_LOCALE_DATA enumData = { NULL, 0, cultureTypes};
-
- BEGIN_QCALL;
-
- //
- // if CultureTypes.FrameworkCulture is specified we'll enumerate all cultures
- // and filter according to the Whidbey framework culture list (for compatibility)
- //
-
- if (cultureTypes & CULTURETYPES_FRAMEWORKCULTURES)
- {
- dwFlags |= LOCALE_NEUTRALDATA | LOCALE_SPECIFICDATA;
- }
-
- // Map CultureTypes to Windows enumeration values.
- if (cultureTypes & CULTURETYPES_NEUTRALCULTURES)
- {
- dwFlags |= LOCALE_NEUTRALDATA;
- }
-
- if (cultureTypes & CULTURETYPES_SPECIFICCULTURES)
- {
- dwFlags |= LOCALE_SPECIFICDATA;
- }
-
- if (cultureTypes & CULTURETYPES_INSTALLEDWIN32CULTURES)
- {
- // Windows 7 knows about neutrals, whereas Vista and lower don't.
- if (NewApis::IsWindows7Platform())
- {
- dwFlags |= LOCALE_SPECIFICDATA | LOCALE_NEUTRALDATA;
- }
- else
- {
- dwFlags |= LOCALE_SPECIFICDATA;
- }
- }
-
- dwFlags |= (cultureTypes & CULTURETYPES_USERCUSTOMCULTURE) ? LOCALE_SUPPLEMENTAL: 0;
-
- // We need special handling for Replacement cultures because Windows does not have a way to enumerate it directly.
- // Replacement locale check will be only used when CultureTypes.SpecificCultures is NOT used.
- dwFlags |= (cultureTypes & CULTURETYPES_REPLACEMENTCULTURES) ? LOCALE_SPECIFICDATA | LOCALE_NEUTRALDATA: 0;
-
-
- result = NewApis::EnumSystemLocalesEx((LOCALE_ENUMPROCEX)EnumLocaleCountCallback, dwFlags, (LPARAM)&enumData, NULL) == TRUE ? 1 : 0;
-
- if (result)
- {
-
- GCX_COOP();
-
- GCPROTECT_BEGIN(cultureNamesArray);
-
- // Now we need to allocate our culture names string array and populate it
- // Get our array object (will throw, don't have to check it)
- cultureNamesArray = (PTRARRAYREF) AllocateObjectArray(enumData.count, g_pStringClass);
-
- // In the context struct passed to EnumSystemLocalesEx, reset the count and assign the newly allocated string array
- // to hold culture names to be enumerated.
- enumData.count = 0;
- enumData.pCultureNamesArray = cultureNamesArray;
-
- result = NewApis::EnumSystemLocalesEx((LOCALE_ENUMPROCEX)EnumLocaleProcessingCallback, dwFlags, (LPARAM)&enumData, NULL);
-
- if (result)
- {
- retStringArray.Set(cultureNamesArray);
- }
- GCPROTECT_END();
- }
- END_QCALL
-
- return result;
-
-}
-
-//
-// InternalCompareString is used in the managed side to handle the synthetic CompareInfo methods (IndexOf, LastIndexOf, IsPrfix, and IsSuffix)
-//
-INT32 QCALLTYPE COMNlsInfo::InternalCompareString(
- INT_PTR handle,
- INT_PTR handleOrigin,
- LPCWSTR localeName,
- LPCWSTR string1, INT32 offset1, INT32 length1,
- LPCWSTR string2, INT32 offset2, INT32 length2,
- INT32 flags)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(CheckPointer(string1));
- PRECONDITION(CheckPointer(string2));
- PRECONDITION(CheckPointer(localeName));
- } CONTRACTL_END;
-
- INT32 result = 1;
- BEGIN_QCALL;
-
- handle = EnsureValidSortHandle(handle, handleOrigin, localeName);
-
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
- if(!(curDomain->m_bUseOsSorting))
- {
- result = SortVersioning::SortDllCompareString((SortVersioning::PSORTHANDLE) handle, flags, &string1[offset1], length1, &string2[offset2], length2, NULL, 0);
- }
- else if (curDomain->m_pCustomSortLibrary != NULL) {
- result = (curDomain->m_pCustomSortLibrary->pCompareStringEx)(handle != NULL ? NULL : localeName, flags, &string1[offset1], length1, &string2[offset2], length2, NULL, NULL, (LPARAM) handle);
- }
- else
-#endif
- {
- result = NewApis::CompareStringEx(handle != NULL ? NULL : localeName, flags, &string1[offset1], length1, &string2[offset2], length2,NULL,NULL, (LPARAM) handle);
- }
-
- switch (result)
- {
- case CSTR_LESS_THAN:
- result = -1;
- break;
-
- case CSTR_EQUAL:
- result = 0;
- break;
-
- case CSTR_GREATER_THAN:
- result = 1;
- break;
-
- case 0:
- default:
- _ASSERTE(!"catastrophic failure calling NewApis::CompareStringEx! This could be a CultureInfo, RegionInfo, or Calendar bug (bad localeName string) or maybe a GCHole.");
- break;
- }
-
- END_QCALL;
- return result;
-}
-
-////////////////////////////////////////////////////////////////////////////
-//
-// UseConstantSpaceHashAlgorithm
-// Check for the DWORD "NetFx45_CultureAwareComparerGetHashCode_LongStrings" CLR config option.
-//
-// .Net 4.5 introduces an opt-in algorithm for determining the hash code of strings that
-// uses a constant amount of memory instead of memory proportional to the size of the string
-//
-// A non-zero value will enable the new algorithm:
-//
-// 1) Config file (MyApp.exe.config)
-// <?xml version ="1.0"?>
-// <configuration>
-// <runtime>
-// <NetFx45_CultureAwareComparerGetHashCode_LongStrings enabled="1"/>
-// </runtime>
-// </configuration>
-// 2) Environment variable
-// set NetFx45_CultureAwareComparerGetHashCode_LongStrings=1
-// 3) RegistryKey
-// [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
-// "NetFx45_CultureAwareComparerGetHashCode_LongStrings"=dword:00000001
-//
-////////////////////////////////////////////////////////////////////////////
-BOOL UseConstantSpaceHashAlgorithm()
-{
- static bool configChecked = false;
- static BOOL useConstantSpaceHashAlgorithm = FALSE;
-
- if(!configChecked)
- {
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return false);
- useConstantSpaceHashAlgorithm = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_NetFx45_CultureAwareComparerGetHashCode_LongStrings) != 0;
- END_SO_INTOLERANT_CODE;
-
- configChecked = true;
- }
- return useConstantSpaceHashAlgorithm;
-}
-
-
-
////////////////////////////////////////////////////////////////////////////
//
// InternalGetGlobalizedHashCode
//
////////////////////////////////////////////////////////////////////////////
-INT32 QCALLTYPE COMNlsInfo::InternalGetGlobalizedHashCode(INT_PTR handle, INT_PTR handleOrigin, LPCWSTR localeName, LPCWSTR string, INT32 length, INT32 dwFlagsIn, BOOL bForceRandomizedHashing, INT64 additionalEntropy)
+INT32 QCALLTYPE COMNlsInfo::InternalGetGlobalizedHashCode(INT_PTR handle, LPCWSTR localeName, LPCWSTR string, INT32 length, INT32 dwFlagsIn, INT64 additionalEntropy)
{
CONTRACTL
{
@@ -1760,7 +103,6 @@ INT32 QCALLTYPE COMNlsInfo::InternalGetGlobalizedHashCode(INT_PTR handle, INT_PT
INT32 iReturnHash = 0;
BEGIN_QCALL;
- handle = EnsureValidSortHandle(handle, handleOrigin, localeName);
int byteCount = 0;
//
@@ -1770,706 +112,38 @@ INT32 QCALLTYPE COMNlsInfo::InternalGetGlobalizedHashCode(INT_PTR handle, INT_PT
COMPlusThrowArgumentNull(W("string"),W("ArgumentNull_String"));
}
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-#endif // FEATURE_CORECLR
-
- if(length > 0 && UseConstantSpaceHashAlgorithm()
- // Note that we can't simply do the hash without the entropy and then try to add it after the fact we need the hash function itself to pass entropy to its inputs.
-#ifdef FEATURE_RANDOMIZED_STRING_HASHING
- && !bForceRandomizedHashing
-#ifndef FEATURE_CORECLR
- && !curDomain->m_pNlsHashProvider->GetUseRandomHashing()
-#else
- && !COMNlsHashProvider::s_NlsHashProvider.GetUseRandomHashing()
-#endif // FEATURE_CORECLR
-#endif // FEATURE_RANDOMIZED_STRING_HASHING
- )
- {
-#ifndef FEATURE_CORECLR
- if(!(curDomain->m_bUseOsSorting))
- {
- iReturnHash=SortVersioning::SortDllGetHashCode((SortVersioning::PSORTHANDLE) handle, dwFlagsIn, string, length, NULL, 0);
- }
- else
-#endif
- {
- int iRes = 0;
- int iHashValue = 0;
-
-#ifndef FEATURE_CORECLR
- if (curDomain->m_pCustomSortLibrary != NULL)
- {
- iRes = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(localeName, dwFlagsIn | LCMAP_HASH, string, length, (LPWSTR) &iHashValue, sizeof(INT32), NULL, NULL, 0);
- }
- else
-#endif
- {
- iRes = NewApis::LCMapStringEx(localeName, dwFlagsIn | LCMAP_HASH, string, length, (LPWSTR) &iHashValue, sizeof(INT32), NULL, NULL, 0);
- }
-
- if(iRes != 0)
- {
- iReturnHash = iHashValue;
- }
- }
- }
-
- if(iReturnHash == 0)
- {
- DWORD dwFlags = (LCMAP_SORTKEY | dwFlagsIn);
-
- //
- // Caller has already verified that the string is not of zero length
- //
- // Assert if we might hit an AV in LCMapStringEx for the invariant culture.
- _ASSERTE(length > 0 || (dwFlags & LCMAP_LINGUISTIC_CASING) == 0);
-#ifndef FEATURE_CORECLR
- if(!(curDomain->m_bUseOsSorting))
- {
- byteCount=SortVersioning::SortDllGetSortKey((SortVersioning::PSORTHANDLE) handle, dwFlagsIn, string, length, NULL, 0, NULL, 0);
- }
- else if (curDomain->m_pCustomSortLibrary != NULL)
- {
- byteCount = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : localeName, dwFlags, string, length, NULL, 0, NULL, NULL, (LPARAM) handle);
- }
- else
-#endif
- {
- byteCount=NewApis::LCMapStringEx(handle != NULL ? NULL : localeName, dwFlags, string, length, NULL, 0, NULL, NULL, (LPARAM) handle);
- }
-
- //A count of 0 indicates that we either had an error or had a zero length string originally.
- if (byteCount==0) {
- COMPlusThrow(kArgumentException, W("Arg_MustBeString"));
- }
-
- // We used to use a NewArrayHolder here, but it turns out that hurts our large # process
- // scalability in ASP.Net hosting scenarios, using the quick bytes instead mostly stack
- // allocates and ups throughput by 8% in 100 process case, 5% in 1000 process case
- {
- CQuickBytesSpecifySize<MAX_STRING_VALUE * sizeof(WCHAR)> qbBuffer;
- BYTE* pByte = (BYTE*)qbBuffer.AllocThrows(byteCount);
-
-#ifndef FEATURE_CORECLR
- if(!(curDomain->m_bUseOsSorting))
- {
- SortVersioning::SortDllGetSortKey((SortVersioning::PSORTHANDLE) handle, dwFlagsIn, string, length, pByte, byteCount, NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : localeName, dwFlags, string, length, (LPWSTR)pByte, byteCount, NULL, NULL, (LPARAM) handle);
- }
- else
-#endif
- {
- NewApis::LCMapStringEx(handle != NULL ? NULL : localeName, dwFlags, string, length, (LPWSTR)pByte, byteCount, NULL,NULL, (LPARAM) handle);
- }
-
-#ifndef FEATURE_CORECLR
- iReturnHash = curDomain->m_pNlsHashProvider->HashSortKey(pByte, byteCount, bForceRandomizedHashing, additionalEntropy);
-#else
- iReturnHash = COMNlsHashProvider::s_NlsHashProvider.HashSortKey(pByte, byteCount, bForceRandomizedHashing, additionalEntropy);
-#endif // FEATURE_CORECLR
- }
- }
- END_QCALL;
- return(iReturnHash);
-}
-
-inline BOOL IsInvariantLocale(STRINGREF localeName)
-{
- return localeName->GetStringLength() == 0;
-}
-
-// InternalChangeCaseChar
-//
-// Call LCMapStringEx with a char to make it upper or lower case
-// Note that if the locale is English or Invariant we'll try just mapping it if its < 0x7f
-FCIMPL5(FC_CHAR_RET, COMNlsInfo::InternalChangeCaseChar,
- INT_PTR handle, // optional sort handle
- INT_PTR handleOrigin, StringObject* localeNameUNSAFE, CLR_CHAR wch, CLR_BOOL bIsToUpper)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(localeNameUNSAFE));
- } CONTRACTL_END;
-
- CLR_CHAR retVal = '\0';
- int ret_LCMapStringEx = -1;
-
- // Dereference our string
- STRINGREF localeName(localeNameUNSAFE);
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(localeName);
-
- BOOL isInvariantLocale = IsInvariantLocale(localeName);
- // Check for Invariant to avoid A/V in LCMapStringEx
- DWORD linguisticCasing = (isInvariantLocale) ? 0 : LCMAP_LINGUISTIC_CASING;
-
- handle = EnsureValidSortHandle(handle, handleOrigin, localeName->GetBuffer());
-
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
- //For a versioned sort, Invariant should still use the OS
- if(!(curDomain->m_bUseOsSorting) && !isInvariantLocale)
- {
- ret_LCMapStringEx = SortVersioning::SortDllChangeCase((SortVersioning::PSORTHANDLE) handle,
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing:
- LCMAP_LOWERCASE | linguisticCasing,
- &wch,
- 1,
- &retVal,
- 1,
- NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- ret_LCMapStringEx = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : localeName->GetBuffer(),
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing:
- LCMAP_LOWERCASE | linguisticCasing,
- &wch,
- 1,
- &retVal,
- 1,
- NULL,
- NULL,
- (LPARAM) handle);
- }
- else
-#endif
- {
- ret_LCMapStringEx = NewApis::LCMapStringEx(handle != NULL ? NULL : localeName->GetBuffer(),
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing:
- LCMAP_LOWERCASE | linguisticCasing,
- &wch,
- 1,
- &retVal,
- 1,
- NULL,
- NULL,
- (LPARAM) handle);
- }
-
- if (0 == ret_LCMapStringEx)
- {
- // return value of 0 indicates failure and error value is supposed to be set.
- // shouldn't ever really happen
- _ASSERTE(!"catastrophic failure calling NewApis::InternalChangeCaseChar! This could be a CultureInfo or CompareInfo bug (bad localeName string) or maybe a GCHole.");
- }
-
- HELPER_METHOD_FRAME_END(); // localeName is now unprotected
- return retVal;
-}
-FCIMPLEND
-
-// InternalChangeCaseString
-//
-// Call LCMapStringEx with a string to make it upper or lower case
-// Note that if the locale is English or Invariant we'll try just mapping it if its < 0x7f
-//
-// We typically expect the output string to be the same size as the input. If not
-// we have to count, reallocate the output buffer, and try again.
-FCIMPL5(Object*, COMNlsInfo::InternalChangeCaseString,
- INT_PTR handle, // optional sort handle
- INT_PTR handleOrigin, StringObject* localeNameUNSAFE, StringObject* pStringUNSAFE, CLR_BOOL bIsToUpper)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(pStringUNSAFE));
- PRECONDITION(CheckPointer(localeNameUNSAFE));
- } CONTRACTL_END;
-
- struct _gc
- {
- STRINGREF pResult;
- STRINGREF pString;
- STRINGREF pLocale;
- } gc;
-
- gc.pResult = NULL;
- gc.pString = ObjectToSTRINGREF(pStringUNSAFE);
- gc.pLocale = ObjectToSTRINGREF(localeNameUNSAFE);
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc)
-
- handle = EnsureValidSortHandle(handle, handleOrigin, gc.pLocale->GetBuffer());
-
- //
- // Get the length of the string.
- //
- int nLengthInput = gc.pString->GetStringLength();
- int nLengthOutput = nLengthInput; // initially we assume the string length does not change.
-
- BOOL isInvariantLocale = IsInvariantLocale(gc.pLocale);
- // Check for Invariant to avoid A/V in LCMapStringEx
- DWORD linguisticCasing = (isInvariantLocale) ? 0 : LCMAP_LINGUISTIC_CASING;
- // Check for Invariant to avoid A/V in LCMapStringEx
+ DWORD dwFlags = (LCMAP_SORTKEY | dwFlagsIn);
//
- // Check if we have the empty string.
+ // Caller has already verified that the string is not of zero length
//
- if (nLengthInput == 0)
+ // Assert if we might hit an AV in LCMapStringEx for the invariant culture.
+ _ASSERTE(length > 0 || (dwFlags & LCMAP_LINGUISTIC_CASING) == 0);
{
- gc.pResult = ObjectToSTRINGREF(gc.pString);
+ byteCount=NewApis::LCMapStringEx(handle != NULL ? NULL : localeName, dwFlags, string, length, NULL, 0, NULL, NULL, (LPARAM) handle);
}
- else
- {
- //
- // Create the result string.
- //
- gc.pResult = StringObject::NewString(nLengthOutput);
- LPWSTR pResultStr = gc.pResult->GetBuffer();
-
- int result;
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
- //Invariant should always use OS
- if(!(curDomain->m_bUseOsSorting) && !isInvariantLocale)
- {
- result = SortVersioning::SortDllChangeCase((SortVersioning::PSORTHANDLE) handle,
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing:
- LCMAP_LOWERCASE | linguisticCasing,
- gc.pString->GetBuffer(),
- nLengthInput,
- pResultStr,
- nLengthOutput,
- NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- result = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : (gc.pLocale)->GetBuffer(),
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing :
- LCMAP_LOWERCASE | linguisticCasing,
- gc.pString->GetBuffer(),
- nLengthInput,
- pResultStr,
- nLengthOutput,
- NULL,
- NULL,
- (LPARAM) handle);
- }
- else
-#endif
- {
- result = NewApis::LCMapStringEx(handle != NULL ? NULL : (gc.pLocale)->GetBuffer(),
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing :
- LCMAP_LOWERCASE | linguisticCasing,
- gc.pString->GetBuffer(),
- nLengthInput,
- pResultStr,
- nLengthOutput,
- NULL,
- NULL,
- (LPARAM) handle);
- }
- if(0 == result)
- {
- // Failure: Detect if that's due to insufficient buffer
- if (GetLastError()!= ERROR_INSUFFICIENT_BUFFER)
- {
- ThrowLastError();
- }
- // need to update buffer
-#ifndef FEATURE_CORECLR
- //Invariant should always use OS
- if(!(curDomain->m_bUseOsSorting) && !IsInvariantLocale(gc.pLocale))
- {
- nLengthOutput = SortVersioning::SortDllChangeCase((SortVersioning::PSORTHANDLE) handle,
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing:
- LCMAP_LOWERCASE | linguisticCasing,
- gc.pString->GetBuffer(),
- nLengthInput,
- NULL,
- 0,
- NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- nLengthOutput = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : (gc.pLocale)->GetBuffer(),
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing :
- LCMAP_LOWERCASE | linguisticCasing,
- gc.pString->GetBuffer(),
- nLengthInput,
- NULL,
- 0,
- NULL,
- NULL,
- (LPARAM) handle);
- }
- else
-#endif
- {
- nLengthOutput = NewApis::LCMapStringEx(handle != NULL ? NULL : (gc.pLocale)->GetBuffer(),
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing :
- LCMAP_LOWERCASE | linguisticCasing,
- gc.pString->GetBuffer(),
- nLengthInput,
- NULL,
- 0,
- NULL,
- NULL,
- (LPARAM) handle);
- }
- if (nLengthOutput == 0)
- {
- // return value of 0 indicates failure and error value is supposed to be set.
- // shouldn't ever really happen
- _ASSERTE(!"catastrophic failure calling NewApis::InternalChangeCaseString! This could be a CultureInfo or CompareInfo bug (bad localeName string) or maybe a GCHole.");
- }
- _ASSERTE(nLengthOutput > 0);
- // NOTE: The length of the required buffer does not include the terminating null character.
- // So it can be used as-is for our calculations -- the length we pass in to NewString also does
- // not include the terminating null character.
- // MSDN documentation could be interpreted to mean that the length returned includes the terminating
- // NULL character, but that's not the case.
-
- // NOTE: Also note that we let the GC take care of the previously allocated pResult.
-
- gc.pResult = StringObject::NewString(nLengthOutput);
- pResultStr = gc.pResult->GetBuffer();
-#ifndef FEATURE_CORECLR
- //Invariant should always use OS
- if(!(curDomain->m_bUseOsSorting) && !IsInvariantLocale(gc.pLocale))
- {
- result = SortVersioning::SortDllChangeCase((SortVersioning::PSORTHANDLE) handle,
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing:
- LCMAP_LOWERCASE | linguisticCasing,
- gc.pString->GetBuffer(),
- nLengthInput,
- pResultStr,
- nLengthOutput,
- NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- result = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : (gc.pLocale)->GetBuffer(),
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing :
- LCMAP_LOWERCASE | linguisticCasing,
- gc.pString->GetBuffer(),
- nLengthInput,
- pResultStr,
- nLengthOutput,
- NULL,
- NULL,
- (LPARAM) handle);
- }
- else
-#endif
- {
- result = NewApis::LCMapStringEx(handle != NULL ? NULL : (gc.pLocale)->GetBuffer(),
- bIsToUpper?LCMAP_UPPERCASE | linguisticCasing :
- LCMAP_LOWERCASE | linguisticCasing,
- gc.pString->GetBuffer(),
- nLengthInput,
- pResultStr,
- nLengthOutput,
- NULL,
- NULL,
- (LPARAM) handle);
- }
-
- if(0 == result)
- {
- // return value of 0 indicates failure and error value is supposed to be set.
- // shouldn't ever really happen
- _ASSERTE(!"catastrophic failure calling NewApis::InternalChangeCaseString! This could be a CultureInfo or CompareInfo bug (bad localeName string) or maybe a GCHole.");
- }
- }
-
- pResultStr[nLengthOutput] = 0;
- }
-
- HELPER_METHOD_FRAME_END();
-
- return OBJECTREFToObject(gc.pResult);
-}
-FCIMPLEND
-
-/*================================InternalGetCaseInsHash================================
-**Action:
-**Returns:
-**Arguments:
-**Exceptions:
-==============================================================================*/
-FCIMPL6(INT32, COMNlsInfo::InternalGetCaseInsHash,
- INT_PTR handle, // optional sort handle
- INT_PTR handleOrigin, StringObject* localeNameUNSAFE, LPVOID pvStrA, CLR_BOOL bForceRandomizedHashing, INT64 additionalEntropy)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(localeNameUNSAFE));
- PRECONDITION(CheckPointer(pvStrA));
- } CONTRACTL_END;
-
- STRINGREF localeName = ObjectToSTRINGREF(localeNameUNSAFE);
- STRINGREF strA;
-
- INT32 result;
-
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), FCThrow(kStackOverflowException))
-
- *((LPVOID *)&strA)=pvStrA;
-
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-#endif
-
- //
- // If we know that we don't have any high characters (the common case) we can
- // call a hash function that knows how to do a very fast case conversion. If
- // we find characters above 0x80, it's much faster to convert the entire string
- // to Uppercase and then call the standard hash function on it.
- //
- // TODO: NLS Arrowhead -We aren't consistent with the fast casing cultures (any en? fr? de?)
- if (IsCultureEnglishOrInvariant((localeName)->GetBuffer()) && // If we're en-US or Invariant
- ((IS_STRING_STATE_UNDETERMINED(strA->GetHighCharState()) && // and we're undetermined
- IS_FAST_CASING(strA->InternalCheckHighChars())) || // and its fast casing when determined
- IS_FAST_CASING(strA->GetHighCharState()))) // or we're fast casing that's already determined
+ //A count of 0 indicates that we either had an error or had a zero length string originally.
+ if (byteCount==0)
{
- // Notice that for Turkish and Azeri we don't get here and shouldn't use this
- // fast path because of their special Latin casing rules.
-#ifndef FEATURE_CORECLR
- result = curDomain->m_pNlsHashProvider->HashiStringKnownLower80(strA->GetBuffer(), strA->GetStringLength(), bForceRandomizedHashing, additionalEntropy);
-#else
- result = COMNlsHashProvider::s_NlsHashProvider.HashiStringKnownLower80(strA->GetBuffer(), strA->GetStringLength(), bForceRandomizedHashing, additionalEntropy);
-#endif // FEATURE_CORECLR
+ COMPlusThrow(kArgumentException, W("Arg_MustBeString"));
}
- else
- {
- handle = EnsureValidSortHandle(handle, handleOrigin, localeName->GetBuffer());
-
- // Make it upper case
- CQuickBytes newBuffer;
- INT32 length = strA->GetStringLength();
- WCHAR *pNewStr = (WCHAR *)newBuffer.AllocThrows((length + 1) * sizeof(WCHAR));
-
- // Work around an A/V in LCMapStringEx for the invariant culture.
- // Revisit this after Vista SP2 has been deployed everywhere.
- DWORD linguisticCasing = 0;
- if (localeName->GetStringLength() > 0) // if not the invariant culture...
- {
- linguisticCasing = LCMAP_LINGUISTIC_CASING;
- }
-
- int lcmapResult;
-#ifndef FEATURE_CORECLR
- if(!(curDomain->m_bUseOsSorting))
- {
- lcmapResult = SortVersioning::SortDllChangeCase((SortVersioning::PSORTHANDLE) handle,
- LCMAP_UPPERCASE | linguisticCasing,
- strA->GetBuffer(),
- length,
- pNewStr,
- length,
- NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- lcmapResult = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : localeName->GetBuffer(),
- LCMAP_UPPERCASE | linguisticCasing,
- strA->GetBuffer(),
- length,
- pNewStr,
- length,
- NULL, NULL, (LPARAM) handle);
- }
- else
-#endif
- {
- lcmapResult = NewApis::LCMapStringEx(handle != NULL ? NULL : localeName->GetBuffer(),
- LCMAP_UPPERCASE | linguisticCasing,
- strA->GetBuffer(),
- length,
- pNewStr,
- length,
- NULL, NULL, (LPARAM) handle);
- }
-
- if (lcmapResult == 0)
- {
- // return value of 0 indicates failure and error value is supposed to be set.
- // shouldn't ever really happen
- _ASSERTE(!"catastrophic failure calling NewApis::InternalGetCaseInsHash! This could be a CultureInfo or CompareInfo bug (bad localeName string) or maybe a GCHole.");
- }
- pNewStr[length]='\0';
- // Get hash for the upper case of the new string
-
-#ifndef FEATURE_CORECLR
- result = curDomain->m_pNlsHashProvider->HashString(pNewStr, length, (BOOL)bForceRandomizedHashing, additionalEntropy);
-#else
- result = COMNlsHashProvider::s_NlsHashProvider.HashString(pNewStr, length, (BOOL)bForceRandomizedHashing, additionalEntropy);
-#endif // FEATURE_CORECLR
- }
-
- END_SO_INTOLERANT_CODE
-
- return result;
-}
-FCIMPLEND
-
-// Fast path for finding a String using OrdinalIgnoreCase rules
-// returns true if the fast path succeeded, with foundIndex set to the location where the String was found or -1
-// Returns false when FindStringOrdinal isn't handled (we don't have our own general version of this function to fall back on)
-// Note for future optimizations: kernel32!FindStringOrdinal(ignoreCase=TRUE) uses per-character table lookup
-// to map to upper case before comparison, but isn't otherwise optimized
-BOOL QCALLTYPE COMNlsInfo::InternalTryFindStringOrdinalIgnoreCase(
- __in DWORD dwFindNLSStringFlags, // mutually exclusive flags: FIND_FROMSTART, FIND_STARTSWITH, FIND_FROMEND, FIND_ENDSWITH
- __in_ecount(cchSource) LPCWSTR lpStringSource, // the string we search in
- __in int cchSource, // number of characters lpStringSource after sourceIndex
- __in int sourceIndex, // index from where the search will start in lpStringSource
- __in_ecount(cchValue) LPCWSTR lpStringValue, // the string we search for
- __in int cchValue,
- __out int* foundIndex) // the index in lpStringSource where we found lpStringValue
-{
- CONTRACTL
+ // We used to use a NewArrayHolder here, but it turns out that hurts our large # process
+ // scalability in ASP.Net hosting scenarios, using the quick bytes instead mostly stack
+ // allocates and ups throughput by 8% in 100 process case, 5% in 1000 process case
{
- QCALL_CHECK;
- PRECONDITION(lpStringSource != NULL);
- PRECONDITION(lpStringValue != NULL);
- PRECONDITION(cchSource>=0);
- PRECONDITION(cchValue>=0);
- PRECONDITION((dwFindNLSStringFlags & FIND_NLS_STRING_FLAGS_NEGATION) == 0);
- } CONTRACTL_END;
-
- BOOL result = FALSE;
-
- BEGIN_QCALL;
-
- LPCWSTR lpSearchStart = NULL;
- if (dwFindNLSStringFlags & (FIND_FROMEND | FIND_ENDSWITH))
- {
- lpSearchStart = &lpStringSource[sourceIndex - cchSource + 1];
- }
- else {
- lpSearchStart = &lpStringSource[sourceIndex];
- }
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
+ CQuickBytesSpecifySize<MAX_STRING_VALUE * sizeof(WCHAR)> qbBuffer;
+ BYTE* pByte = (BYTE*)qbBuffer.AllocThrows(byteCount);
- // Check if the default sorting is overridden
- if (curDomain->m_pCustomSortLibrary != NULL)
- {
- *foundIndex = (curDomain->m_pCustomSortLibrary->pFindStringOrdinal)(
- dwFindNLSStringFlags,
- lpSearchStart,
- cchSource,
- lpStringValue,
- cchValue,
- TRUE);
- result = TRUE;
- }
- else
-#endif
- {
-#ifndef FEATURE_CORESYSTEM
- // kernel function pointer
- typedef int (WINAPI *PFNFindStringOrdinal)(DWORD, LPCWSTR, INT, LPCWSTR, INT, BOOL);
- static PFNFindStringOrdinal FindStringOrdinal = NULL;
-
- // initizalize kernel32!FindStringOrdinal
- if (FindStringOrdinal == NULL)
{
- PFNFindStringOrdinal result = NULL;
-
- HMODULE hMod=WszGetModuleHandle(WINDOWS_KERNEL32_DLLNAME_W);
- if(hMod != NULL)
- result=(PFNFindStringOrdinal)GetProcAddress(hMod,"FindStringOrdinal");
-
- FindStringOrdinal = (result != NULL) ? result : (PFNFindStringOrdinal)-1;
+ NewApis::LCMapStringEx(handle != NULL ? NULL : localeName, dwFlags, string, length, (LPWSTR)pByte, byteCount, NULL,NULL, (LPARAM) handle);
}
- // call into the kernel
- if (FindStringOrdinal != (PFNFindStringOrdinal)-1)
-#endif
- {
- *foundIndex = FindStringOrdinal(
- dwFindNLSStringFlags,
- lpSearchStart,
- cchSource,
- lpStringValue,
- cchValue,
- TRUE);
- result = TRUE;
- }
- }
- // if we found the pattern string, fixup the index before we return
- if (*foundIndex >= 0)
- {
- if (dwFindNLSStringFlags & (FIND_FROMEND | FIND_ENDSWITH))
- *foundIndex += (sourceIndex - cchSource + 1);
- else
- *foundIndex += sourceIndex;
+ iReturnHash = COMNlsHashProvider::s_NlsHashProvider.HashSortKey(pByte, byteCount, true, additionalEntropy);
}
END_QCALL;
-
- return result;
-}
-
-
-// InternalCompareStringOrdinalIgnoreCase
-//
-// Call ::CompareStringOrdinal for native ordinal behavior
-INT32 QCALLTYPE COMNlsInfo::InternalCompareStringOrdinalIgnoreCase(
- LPCWSTR string1, INT32 index1,
- LPCWSTR string2, INT32 index2,
- INT32 length1,
- INT32 length2)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(CheckPointer(string1));
- PRECONDITION(CheckPointer(string2));
- } CONTRACTL_END;
-
- INT32 result = 0;
-
- BEGIN_QCALL;
- //
- // Get the arguments.
- // We assume the caller checked them before calling us
- //
-
- // We don't allow the -1 that native code allows
- _ASSERT(length1 >= 0);
- _ASSERT(length2 >= 0);
-
- // Do the comparison
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
- if (curDomain->m_pCustomSortLibrary != NULL) {
- result = (curDomain->m_pCustomSortLibrary->pCompareStringOrdinal)(string1 + index1, length1, string2 + index2, length2, TRUE);
- }
- else
-#endif
- {
- result = NewApis::CompareStringOrdinal(string1 + index1, length1, string2 + index2, length2, TRUE);
- }
-
- // The native call shouldn't fail
- _ASSERT(result != 0);
- if (result == 0)
- {
- // return value of 0 indicates failure and error value is supposed to be set.
- // shouldn't ever really happen
- _ASSERTE(!"catastrophic failure calling NewApis::CompareStringOrdinal! This is usually due to bad arguments.");
- }
-
- // Adjust the result to the expected -1, 0, 1 result
- result -= 2;
-
- END_QCALL;
-
- return result;
+ return(iReturnHash);
}
/**
@@ -2501,163 +175,6 @@ FCIMPL0(CodePageDataItem *, COMNlsInfo::nativeGetCodePageTableDataPointer)
}
FCIMPLEND
-
-#ifndef FEATURE_COREFX_GLOBALIZATION
-//
-// Normalization
-//
-
-FCIMPL6(int, COMNlsInfo::nativeNormalizationNormalizeString,
- int NormForm, int& iError,
- StringObject* inChars, int inLength,
- CHARArray* outChars, int outLength )
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(inChars));
- PRECONDITION(CheckPointer(outChars, NULL_OK));
- } CONTRACTL_END;
-
- // Dereference our string
- STRINGREF inString(inChars);
- LPWSTR inCharsBuffer = inString->GetBuffer();
-
- CHARARRAYREF outCharArray(outChars);
- LPWSTR outCharsBuffer = (outCharArray != NULL) ? ((LPWSTR) (outCharArray->GetDirectPointerToNonObjectElements())) : NULL;
-
- // The OS APIs do not always set last error in success, so we have to do it explicitly
- SetLastError(ERROR_SUCCESS);
-
- int iResult = m_pfnNormalizationNormalizeStringFunc(
- NormForm, inCharsBuffer, inLength, outCharsBuffer, outLength);
-
- // Get our error if necessary
- if (iResult <= 0)
- {
- // if the length is <= 0 there was an error
- iError = GetLastError();
-
- // Go ahead and return positive lengths/indexes so we don't get confused
- iResult = -iResult;
- }
- else
- {
- iError = 0; // ERROR_SUCCESS
- }
-
- return iResult;
-}
-FCIMPLEND
-
-FCIMPL4( FC_BOOL_RET, COMNlsInfo::nativeNormalizationIsNormalizedString,
- int NormForm, int& iError,
- StringObject* chars, int inLength )
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(chars));
- } CONTRACTL_END;
-
- STRINGREF inString(chars);
- LPWSTR charsBuffer = inString->GetBuffer();
-
- // The OS APIs do not always set last error in success, so we have to do it explicitly
- SetLastError(ERROR_SUCCESS);
-
- // Ask if its normalized
- BOOL bResult = m_pfnNormalizationIsNormalizedStringFunc( NormForm, charsBuffer, inLength);
-
- // May need an error
- if (bResult == false)
- {
- // If its false there may have been an error
- iError = GetLastError();
- }
- else
- {
- iError = 0; // ERROR_SUCCESS
- }
-
- FC_RETURN_BOOL(bResult);
-}
-FCIMPLEND
-
-void QCALLTYPE COMNlsInfo::nativeNormalizationInitNormalization(int NormForm, BYTE* pTableData)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- if (m_hNormalization == NULL)
- {
- HMODULE hNormalization = NULL;
-
- if (pTableData == NULL)
- {
- // Use OS implementation
- hNormalization = GetModuleHandleW(W("kernel32.dll"));
- if (!hNormalization)
- ThrowLastError();
- }
-#ifndef FEATURE_CORECLR
- // in coreclr we should always find the normalization in kernel32 as it supports Win7 and up
- else
- {
- HRESULT hr = g_pCLRRuntime->LoadLibrary(NORMALIZATION_DLL, &hNormalization);
- if (FAILED(hr))
- ThrowHR(hr);
- }
-#endif // FEATURE_CORECLR
-
- _ASSERTE(hNormalization != NULL);
- m_hNormalization = hNormalization;
- }
-
- if (m_pfnNormalizationIsNormalizedStringFunc == NULL)
- {
- FARPROC pfn = GetProcAddress(m_hNormalization, "IsNormalizedString");
- if (pfn == NULL)
- ThrowLastError();
- m_pfnNormalizationIsNormalizedStringFunc = (PFN_NORMALIZATION_IS_NORMALIZED_STRING)pfn;
- }
-
- if (m_pfnNormalizationNormalizeStringFunc == NULL)
- {
- FARPROC pfn = GetProcAddress(m_hNormalization, "NormalizeString");
- if (pfn == NULL)
- ThrowLastError();
- m_pfnNormalizationNormalizeStringFunc = (PFN_NORMALIZATION_NORMALIZE_STRING)pfn;
- }
-
- if (pTableData != NULL)
- {
- if (m_pfnNormalizationInitNormalizationFunc == NULL)
- {
- FARPROC pfn = GetProcAddress(m_hNormalization, "InitNormalization");
- if (pfn == NULL)
- ThrowLastError();
- m_pfnNormalizationInitNormalizationFunc = (PFN_NORMALIZATION_INIT_NORMALIZATION)pfn;
- }
-
- BYTE* pResult = m_pfnNormalizationInitNormalizationFunc( NormForm, pTableData);
- if (pResult == NULL)
- ThrowOutOfMemory();
- }
-
- END_QCALL;
-}
-
-#endif // FEATURE_COREFX_GLOBALIZATION
-
-
-//
-// This table should be sorted using case-insensitive ordinal order.
-// In the managed code, String.CompareStringOrdinalWC() is used to sort this.
-//
-
-
/**
* This function returns the number of items in EncodingDataTable.
*/
@@ -2669,689 +186,3 @@ FCIMPL0(INT32, COMNlsInfo::nativeGetNumEncodingItems)
return (m_nEncodingDataTableItems);
}
FCIMPLEND
-
-
-
-typedef CultureDataBaseObject* CULTUREDATAREF;
-
-// nativeInitCultureData checks with the OS to see if this is a valid culture.
-// If so we populate a limited number of fields. If its not valid we return false.
-//
-// The fields we populate:
-//
-// sWindowsName -- The name that windows thinks this culture is, ie:
-// en-US if you pass in en-US
-// de-DE_phoneb if you pass in de-DE_phoneb
-// fj-FJ if you pass in fj (neutral, on a pre-Windows 7 machine)
-// fj if you pass in fj (neutral, post-Windows 7 machine)
-//
-// sRealName -- The name you used to construct the culture, in pretty form
-// en-US if you pass in EN-us
-// en if you pass in en
-// de-DE_phoneb if you pass in de-DE_phoneb
-//
-// sSpecificCulture -- The specific culture for this culture
-// en-US for en-US
-// en-US for en
-// de-DE_phoneb for alt sort
-// fj-FJ for fj (neutral)
-//
-// sName -- The IETF name of this culture (ie: no sort info, could be neutral)
-// en-US if you pass in en-US
-// en if you pass in en
-// de-DE if you pass in de-DE_phoneb
-//
-// bNeutral -- TRUE if it is a neutral locale
-//
-// For a neutral we just populate the neutral name, but we leave the windows name pointing to the
-// windows locale that's going to provide data for us.
-//
-FCIMPL1(FC_BOOL_RET, COMNlsInfo::nativeInitCultureData, CultureDataBaseObject *cultureDataUNSAFE)
-{
- FCALL_CONTRACT;
-
- BOOL success=FALSE;
-
- struct _gc
- {
- STRINGREF stringResult;
- CULTUREDATAREF cultureData;
- } gc;
-
- gc.stringResult = NULL;
- gc.cultureData = (CULTUREDATAREF) cultureDataUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
-
- WCHAR buffer[LOCALE_NAME_MAX_LENGTH];
- int result;
-
- StackSString realNameBuffer( ((STRINGREF)gc.cultureData->sRealName)->GetBuffer() );
-
- // Call GetLocaleInfoEx and see if the OS knows about it.
- // Note that GetLocaleInfoEx has variations:
- // * Pre-Vista it fails and has to go downlevel
- // * Vista succeeds, but not for neutrals
- // * Win7 succeeds for all locales.
- // * Mac does ???
- // The differences should be handled by the NewApis wrapper
- result = NewApis::GetLocaleInfoEx(realNameBuffer, LOCALE_SNAME, buffer, NumItems(buffer));
-
- // Did it fail?
- if (result == 0)
- {
- // Not a real locale, fail
- goto Exit;
- }
-
- // It worked, note that the name is the locale name, so use that (even for neutrals)
- // We need to clean up our "real" name, which should look like the windows name right now
- // so overwrite the input with the cleaned up name
- gc.stringResult = StringObject::NewString(buffer, result-1);
- SetObjectReference((OBJECTREF*)&(gc.cultureData->sRealName), gc.stringResult, NULL);
-
- // Check for neutrality, don't expect to fail
- // (buffer has our name in it, so we don't have to do the gc. stuff)
- DWORD bNeutral;
- if (0 == NewApis::GetLocaleInfoEx(buffer, LOCALE_INEUTRAL | LOCALE_RETURN_NUMBER, (LPWSTR)&bNeutral, sizeof(bNeutral)/sizeof(WCHAR)))
- goto Exit;
-
- // Remember our neutrality
- gc.cultureData->bNeutral = (bNeutral != 0);
-
- gc.cultureData->bWin32Installed = (IsOSValidLocaleName(buffer, gc.cultureData->bNeutral) != 0);
- gc.cultureData->bFramework = (IsWhidbeyFrameworkCulture(buffer) != 0);
-
-
- // Note: Parents will be set dynamically
-
- // Start by assuming the windows name'll be the same as the specific name since windows knows
- // about specifics on all versions. For macs it also works. Only for downlevel Neutral locales
- // does this have to change.
- gc.stringResult = StringObject::NewString(buffer, result-1);
- SetObjectReference((OBJECTREF*)&(gc.cultureData->sWindowsName), gc.stringResult, NULL);
-
- // Neutrals and non-neutrals are slightly different
- if (gc.cultureData->bNeutral)
- {
- // Neutral Locale
-
- // IETF name looks like neutral name
- gc.stringResult = StringObject::NewString(buffer, result-1);
- SetObjectReference((OBJECTREF*)&(gc.cultureData->sName), gc.stringResult, NULL);
-
- // Specific locale name is whatever ResolveLocaleName (win7+) returns.
- // (Buffer has our name in it, and we can recycle that because windows resolves it before writing to the buffer)
- result = NewApis::ResolveLocaleName(buffer, buffer, NumItems(buffer));
-
- // 0 is failure, 1 is invariant (""), which we expect
- if (result < 1) goto Exit;
-
- // We found a locale name, so use it.
- // In vista this should look like a sort name (de-DE_phoneb) or a specific culture (en-US) and be in the "pretty" form
- gc.stringResult = StringObject::NewString(buffer, result - 1);
- SetObjectReference((OBJECTREF*)&(gc.cultureData->sSpecificCulture), gc.stringResult, NULL);
-
-#ifdef FEATURE_CORECLR
- if (!IsWindows7())
- {
- // For neutrals on Windows 7 + the neutral windows name can be the same as the neutral name,
- // but on pre windows 7 names it has to be the specific, so we have to fix it in that case.
- gc.stringResult = StringObject::NewString(buffer, result - 1);
- SetObjectReference((OBJECTREF*)&(gc.cultureData->sWindowsName), gc.stringResult, NULL);
- }
-#endif
-
-
- }
- else
- {
- // Specific Locale
-
- // Specific culture's the same as the locale name since we know its not neutral
- // On mac we'll use this as well, even for neutrals. There's no obvious specific
- // culture to use and this isn't exposed, but behaviorally this is correct on mac.
- // Note that specifics include the sort name (de-DE_phoneb)
- gc.stringResult = StringObject::NewString(buffer, result-1);
- SetObjectReference((OBJECTREF*)&(gc.cultureData->sSpecificCulture), gc.stringResult, NULL);
-
- // We need the IETF name (sname)
- // If we aren't an alt sort locale then this is the same as the windows name.
- // If we are an alt sort locale then this is the same as the part before the _ in the windows name
- // This is for like de-DE_phoneb and es-ES_tradnl that hsouldn't have the _ part
-
- int localeNameLength = result - 1;
-
- LCID lcid = NewApis::LocaleNameToLCID(buffer, 0);
- if (!IsCustomCultureId(lcid))
- {
- LPCWSTR index = wcschr(buffer, W('_'));
- if(index) // Not a custom culture and looks like an alt sort name
- {
- // Looks like an alt sort, and has a appropriate sort LCID (so not custom), make it smaller for the RFC 4646 style name
- localeNameLength = static_cast<int>(index - buffer);
- }
- }
-
- gc.stringResult = StringObject::NewString(buffer, localeNameLength);
- _ASSERTE(gc.stringResult != NULL);
-
- // Now use that name
- SetObjectReference((OBJECTREF*)&(gc.cultureData->sName), gc.stringResult, NULL);
- }
-
-#ifdef FEATURE_CORECLR
- // For Silverlight make sure that the sorting tables are available (< Vista may not have east asian installed)
- result = NewApis::CompareStringEx(((STRINGREF)gc.cultureData->sWindowsName)->GetBuffer(),
- 0, W("A"), 1, W("B"), 1, NULL, NULL, 0);
- if (result == 0) goto Exit;
-#endif
-
- // It succeeded.
- success = TRUE;
-
-Exit: {}
-
- HELPER_METHOD_FRAME_END();
-
- FC_RETURN_BOOL(success);
-}
-FCIMPLEND
-
-
-// Return true if we're on Windows 7 (ie: if we have neutral native support)
-BOOL COMNlsInfo::IsWindows7()
-{
- static BOOL bChecked=FALSE;
- static BOOL bIsWindows7=FALSE;
-
- if (!bChecked)
- {
- // LOCALE_INEUTRAL is first supported on Windows 7
- if (GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_INEUTRAL, NULL, 0) != 0)
- {
- // Success, we're win7
- bIsWindows7 = TRUE;
- }
-
- // Either way we checked now
- bChecked = TRUE;
- }
-
- return bIsWindows7;
-}
-
-//
-// QCall implementation
-//
-int QCALLTYPE COMNlsInfo::InternalFindNLSStringEx(
- __in_opt INT_PTR handle, // optional sort handle
- __in_opt INT_PTR handleOrigin,
- __in_z LPCWSTR lpLocaleName, // locale name
- __in int dwFindNLSStringFlags, // search falg
- __in_ecount(cchSource) LPCWSTR lpStringSource, // the string we search in
- __in int cchSource, // number of characters lpStringSource after sourceIndex
- __in int sourceIndex, // index from where the search will start in lpStringSource
- __in_ecount(cchValue) LPCWSTR lpStringValue, // the string we search for
- __in int cchValue) // length of the string we search for
-{
- CONTRACTL {
- QCALL_CHECK;
- PRECONDITION(lpLocaleName != NULL);
- PRECONDITION(lpStringSource != NULL);
- PRECONDITION(lpStringValue != NULL);
- PRECONDITION(cchSource>=0);
- PRECONDITION(cchValue>=0);
- } CONTRACTL_END;
-
- int retValue = -1;
-
- BEGIN_QCALL;
-
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
- handle = EnsureValidSortHandle(handle, handleOrigin, lpLocaleName);
-#endif
-
- #define RESERVED_FIND_ASCII_STRING 0x20000000 // This flag used only to tell the sorting DLL can assume the string characters are in ASCII.
-
-#ifndef FEATURE_CORECLR
- int asciiFlag = (dwFindNLSStringFlags & RESERVED_FIND_ASCII_STRING);
-#endif // FEATURE_CORECLR
-
- dwFindNLSStringFlags &= ~RESERVED_FIND_ASCII_STRING;
-
- if (cchValue == 0)
- {
- retValue = sourceIndex; // keep Whidbey compatibility
- goto lExit;
- }
-
- if (sourceIndex<0 || cchSource<0 ||
- ((dwFindNLSStringFlags & (FIND_FROMEND | FIND_ENDSWITH)) && (sourceIndex+1<cchSource)))
- {
- goto lExit;
- }
-
- if (dwFindNLSStringFlags & COMPARE_OPTIONS_ORDINAL)
- {
- if (dwFindNLSStringFlags & (FIND_FROMEND | FIND_ENDSWITH))
- {
- retValue = NewApis::LastIndexOfString(
- lpLocaleName,
- &lpStringSource[sourceIndex - cchSource + 1],
- cchSource,
- lpStringValue,
- cchValue,
- dwFindNLSStringFlags & FIND_NLS_STRING_FLAGS_NEGATION,
- dwFindNLSStringFlags & FIND_ENDSWITH);
- if (retValue >= 0)
- {
- retValue += sourceIndex - cchSource + 1;
- }
- }
- else
- {
- retValue = NewApis::IndexOfString(
- lpLocaleName,
- &lpStringSource[sourceIndex],
- cchSource,
- lpStringValue,
- cchValue,
- dwFindNLSStringFlags & FIND_NLS_STRING_FLAGS_NEGATION,
- dwFindNLSStringFlags & FIND_STARTSWITH);
-
- if (retValue >= 0)
- {
- retValue += sourceIndex;
- }
- }
- }
- else
- {
- if (dwFindNLSStringFlags & (FIND_FROMEND | FIND_ENDSWITH))
- {
-#ifndef FEATURE_CORECLR
- if(!(curDomain->m_bUseOsSorting))
- {
- retValue = SortVersioning::SortDllFindString((SortVersioning::PSORTHANDLE) handle,
- dwFindNLSStringFlags | asciiFlag,
- &lpStringSource[sourceIndex - cchSource + 1],
- cchSource,
- lpStringValue,
- cchValue,
- NULL, NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- retValue = (curDomain->m_pCustomSortLibrary->pFindNLSStringEx)(
- handle != NULL ? NULL : lpLocaleName,
- dwFindNLSStringFlags,
- &lpStringSource[sourceIndex - cchSource + 1],
- cchSource,
- lpStringValue,
- cchValue, NULL, NULL, NULL, (LPARAM) handle);
- }
- else
-#endif
- {
- retValue = NewApis::FindNLSStringEx(
- handle != NULL ? NULL : lpLocaleName,
- dwFindNLSStringFlags,
- &lpStringSource[sourceIndex - cchSource + 1],
- cchSource,
- lpStringValue,
- cchValue, NULL, NULL, NULL, (LPARAM) handle);
- }
-
- if (retValue >= 0)
- {
- retValue += sourceIndex - cchSource + 1;
- }
- }
- else
- {
-#ifndef FEATURE_CORECLR
- if(!(curDomain->m_bUseOsSorting))
- {
- retValue = SortVersioning::SortDllFindString((SortVersioning::PSORTHANDLE) handle,
- dwFindNLSStringFlags | asciiFlag,
- &lpStringSource[sourceIndex],
- cchSource,
- lpStringValue,
- cchValue,
- NULL, NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- retValue = (curDomain->m_pCustomSortLibrary->pFindNLSStringEx)(
- handle != NULL ? NULL : lpLocaleName,
- dwFindNLSStringFlags,
- &lpStringSource[sourceIndex],
- cchSource,
- lpStringValue,
- cchValue, NULL, NULL, NULL, (LPARAM) handle);
- }
- else
-#endif
- {
- retValue = NewApis::FindNLSStringEx(
- handle != NULL ? NULL : lpLocaleName,
- dwFindNLSStringFlags,
- &lpStringSource[sourceIndex],
- cchSource,
- lpStringValue,
- cchValue, NULL, NULL, NULL, (LPARAM) handle);
- }
-
- if (retValue >= 0)
- {
- retValue += sourceIndex;
- }
- }
- }
-
-lExit:
-
- END_QCALL;
-
- return retValue;
-}
-
-
-int QCALLTYPE COMNlsInfo::InternalGetSortKey(
- __in_opt INT_PTR handle, // PSORTHANDLE
- __in_opt INT_PTR handleOrigin,
- __in_z LPCWSTR pLocaleName, // locale name
- __in int flags, // flags
- __in_ecount(cchSource) LPCWSTR pStringSource, // Source string
- __in int cchSource, // number of characters in lpStringSource
- __in_ecount(cchTarget) PBYTE pTarget, // Target data buffer (may be null to count)
- __in int cchTarget) // Character count for target buffer
-{
- CONTRACTL {
- QCALL_CHECK;
- PRECONDITION(pLocaleName != NULL);
- PRECONDITION(pStringSource != NULL);
-// PRECONDITION(pTarget != NULL);
- PRECONDITION(cchSource>=0);
-// PRECONDITION(cchTarget>=0);
- } CONTRACTL_END;
-
- int retValue = 0;
-
- BEGIN_QCALL;
-
-
-#ifndef FEATURE_CORECLR
- handle = EnsureValidSortHandle(handle, handleOrigin, pLocaleName);
-
- AppDomain* curDomain = GetAppDomain();
-
- if(!(curDomain->m_bUseOsSorting))
- {
- retValue = SortVersioning::SortDllGetSortKey((SortVersioning::PSORTHANDLE) handle,
- flags,
- pStringSource,
- cchSource,
- pTarget,
- cchTarget,
- NULL, 0);
- }
- else if(curDomain->m_pCustomSortLibrary != NULL)
- {
- retValue = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(handle != NULL ? NULL : pLocaleName,
- flags | LCMAP_SORTKEY,
- pStringSource,
- cchSource,
- (LPWSTR)pTarget,
- cchTarget,
- NULL,
- NULL,
- (LPARAM) handle);
- }
- else
-#endif
- {
- // Just call NewApis::LCMapStringEx to do our work
- retValue = NewApis::LCMapStringEx(handle != NULL ? NULL : pLocaleName,
- flags | LCMAP_SORTKEY,
- pStringSource,
- cchSource,
- (LPWSTR)pTarget,
- cchTarget,
- NULL,
- NULL,
- (LPARAM) handle);
- }
- END_QCALL;
-
- return retValue;
-}
-
-
-// We allow InternalInitSortHandle to return a NULL value
-// this is the case for Silverlight or when the appdomain has custom sorting.
-// So all the methods that take a SortHandle, also have to
-// be able to just call the slower api that looks up the tables based on the locale name
-INT_PTR QCALLTYPE COMNlsInfo::InternalInitSortHandle(LPCWSTR localeName, __out INT_PTR* handleOrigin)
-{
- CONTRACTL {
- QCALL_CHECK;
- PRECONDITION(localeName != NULL);
- } CONTRACTL_END;
-
- INT_PTR pSort = NULL;
-
- BEGIN_QCALL;
-
- pSort = InitSortHandleHelper(localeName, handleOrigin);
-
- END_QCALL;
-
- return pSort;
-}
-
-INT_PTR COMNlsInfo::InitSortHandleHelper(LPCWSTR localeName, __out INT_PTR* handleOrigin)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- CANNOT_TAKE_LOCK;
- PRECONDITION(localeName != NULL);
- } CONTRACTL_END;
-
- INT_PTR pSort = NULL;
-
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
-#if _DEBUG
- _ASSERTE(curDomain->m_bSortingInitialized);
-#endif
-
- if(curDomain->m_bUseOsSorting)
- {
- pSort = InternalInitOsSortHandle(localeName, handleOrigin);
- }
- else
- {
- pSort = InternalInitVersionedSortHandle(localeName, handleOrigin);
- }
-#else
- // coreclr will try to initialize the handle and if running on downlevel it'll just return null
- pSort = InternalInitOsSortHandle(localeName, handleOrigin);
-#endif // FEATURE_CORECLR
- return pSort;
-}
-
-#ifndef FEATURE_CORECLR
-INT_PTR COMNlsInfo::InternalInitVersionedSortHandle(LPCWSTR localeName, __out INT_PTR* handleOrigin)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- CANNOT_TAKE_LOCK;
- PRECONDITION(localeName != NULL);
- } CONTRACTL_END;
-
- AppDomain* curDomain = GetAppDomain();
-
- if(curDomain->m_pCustomSortLibrary != NULL)
- {
- return NULL;
- }
-
- return InternalInitVersionedSortHandle(localeName, handleOrigin, curDomain->m_sortVersion);
-}
-
-INT_PTR COMNlsInfo::InternalInitVersionedSortHandle(LPCWSTR localeName, __out INT_PTR* handleOrigin, DWORD sortVersion)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- CANNOT_TAKE_LOCK;
- PRECONDITION(localeName != NULL);
- } CONTRACTL_END;
-
- INT_PTR pSort = NULL;
-
- _ASSERTE(NewApis::NotLeakingFrameworkOnlyCultures(localeName));
-
- *handleOrigin = (INT_PTR) SortVersioning::GetSortHandle;
-
- // try the requested version
- if(sortVersion != DEFAULT_SORT_VERSION)
- {
- NLSVERSIONINFO sortVersionInfo;
- sortVersionInfo.dwNLSVersionInfoSize = sizeof(NLSVERSIONINFO);
- sortVersionInfo.dwNLSVersion = sortVersion;
- sortVersionInfo.dwDefinedVersion = sortVersion;
- pSort = (INT_PTR) SortVersioning::GetSortHandle(localeName, &sortVersionInfo);
- }
-
- // fallback to default version
- if(pSort == NULL)
- {
- pSort = (INT_PTR) SortVersioning::GetSortHandle(localeName, NULL);
- }
-
- _ASSERTE(RunningOnWin8() || pSort != NULL);
-
- return pSort;
-}
-#endif //FEATURE_CORECLR
-
-// Can return NULL
-INT_PTR COMNlsInfo::InternalInitOsSortHandle(LPCWSTR localeName, __out INT_PTR* handleOrigin)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- CANNOT_TAKE_LOCK;
- PRECONDITION(localeName != NULL);
- } CONTRACTL_END;
-
- INT_PTR pSort = NULL;
-
- AppDomain* curDomain = GetAppDomain();
-
-#ifndef FEATURE_CORECLR
- if (RunningOnWin8() || curDomain->m_pCustomSortLibrary != NULL)
-#else
- if (RunningOnWin8())
-#endif //FEATURE_CORECLR
- {
- LPARAM lSortHandle;
- int ret;
-
-#ifndef FEATURE_CORECLR
- if (curDomain->m_pCustomSortLibrary != NULL)
- {
- ret = (curDomain->m_pCustomSortLibrary->pLCMapStringEx)(localeName, LCMAP_SORTHANDLE, NULL, 0, (LPWSTR) &lSortHandle, sizeof(LPARAM), NULL, NULL, 0);
- *handleOrigin = (INT_PTR) curDomain->m_pCustomSortLibrary->pLCMapStringEx;
- }
- else
-#endif //FEATURE_CORECLR
- {
- ret = NewApis::LCMapStringEx(localeName, LCMAP_SORTHANDLE, NULL, 0, (LPWSTR) &lSortHandle, sizeof(LPARAM), NULL, NULL, 0);
- *handleOrigin = (INT_PTR) NewApis::LCMapStringEx;
- }
-
- if (ret != 0)
- {
- pSort = (INT_PTR) lSortHandle;
- }
- }
-
- return pSort;
-}
-
-BOOL QCALLTYPE COMNlsInfo::InternalGetNlsVersionEx(INT_PTR handle, INT_PTR handleOrigin, LPCWSTR lpLocaleName, NLSVERSIONINFOEX * lpVersionInformation)
-{
- CONTRACTL {
- QCALL_CHECK;
- } CONTRACTL_END;
-
- BOOL ret = FALSE;
-
- BEGIN_QCALL;
-#ifndef FEATURE_CORECLR
- AppDomain* curDomain = GetAppDomain();
-
- if(curDomain->m_bUseOsSorting)
- {
- if(curDomain->m_pCustomSortLibrary != NULL)
- {
- ret = (curDomain->m_pCustomSortLibrary->pGetNLSVersionEx)(COMPARE_STRING, lpLocaleName, lpVersionInformation);
- }
- else
- {
- ret = GetNLSVersionEx(COMPARE_STRING, lpLocaleName, lpVersionInformation);
- }
- }
- else
- {
- handle = EnsureValidSortHandle(handle, handleOrigin, lpLocaleName);
-
- NLSVERSIONINFO nlsVersion;
- nlsVersion.dwNLSVersionInfoSize = sizeof(NLSVERSIONINFO);
-
- ret = SortVersioning::SortGetNLSVersion((SortVersioning::PSORTHANDLE) handle, COMPARE_STRING, &nlsVersion);
-
- lpVersionInformation->dwNLSVersion = nlsVersion.dwNLSVersion;
- lpVersionInformation->dwDefinedVersion = nlsVersion.dwDefinedVersion;
- lpVersionInformation->dwEffectiveId = 0;
- ZeroMemory(&(lpVersionInformation->guidCustomVersion), sizeof(GUID));
- }
-#else
- ret = GetNLSVersionEx(COMPARE_STRING, lpLocaleName, lpVersionInformation);
-#endif // FEATURE_CORECLR
- END_QCALL;
-
- return ret;
-}
-
-#ifndef FEATURE_CORECLR
-DWORD QCALLTYPE COMNlsInfo::InternalGetSortVersion()
-{
- CONTRACTL {
- QCALL_CHECK;
- } CONTRACTL_END;
-
- DWORD version = DEFAULT_SORT_VERSION;
-
- BEGIN_QCALL;
-
- AppDomain* curDomain = GetAppDomain();
- version = curDomain->m_sortVersion;
-
- END_QCALL;
-
- return version;
-}
-
-#endif //FEATURE_CORECLR
diff --git a/src/classlibnative/nls/nlstable.cpp b/src/classlibnative/nls/nlstable.cpp
deleted file mode 100644
index dd395153d4..0000000000
--- a/src/classlibnative/nls/nlstable.cpp
+++ /dev/null
@@ -1,259 +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 "common.h"
-#include <winwrap.h>
-#include <excep.h> // For COMPlusThrow
-#include <appdomain.hpp>
-#include <assembly.hpp>
-#include "nlstable.h" // Class declaration
-
-#if FEATURE_CODEPAGES_FILE
-
-/*=================================CreateSharedMemoryMapping==================================
-**Action: Create a file mapping object which can be shared among different users under Windows NT/2000.
-** Actually its just a memory mapped section of the swapfile.
-**Returns: The file mapping handle. NULL if any error happens.
-**Arguments:
-** pMappingName the name of the file mapping object.
-** iSize Size to use
-**Exceptions:
-**Note:
-** This function creates a DACL which grants GENERIC_ALL access to members of the "Everyone" group.
-** Then create a security descriptor using this DACL. Finally, use this SA to create the file mapping object.
-** WARNING:
-** This creates a shared file or shared paged memory section (if hFile == INVALID_HANDLE_VALUE) that is shared machine-wide
-** Therefore for side-by-side to work, the mapping names must be unique per version!
-** We utilize this feature for code pages in case it hasn't changed across versions we can still reuse the
-** tables, but it seems suspicious for other applications (as commented in MapDataFile below)
-==============================================================================*/
-// static method
-HANDLE NLSTable::CreateSharedMemoryMapping(const LPCWSTR pMappingName, const int iSize ) {
- CONTRACTL {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(iSize > 0);
- PRECONDITION(CheckPointer(pMappingName));
- } CONTRACTL_END;
-
- HANDLE hFileMap = NULL;
-
- SECURITY_DESCRIPTOR sd ;
- SECURITY_ATTRIBUTES sa ;
-
- //
- // Create the sid for the Everyone group.
- //
- SID_IDENTIFIER_AUTHORITY siaWorld = SECURITY_WORLD_SID_AUTHORITY;
- PSID pSID = NULL;
- int nSidSize;
-
- PACL pDACL = NULL;
- int nAclSize;
-
- CQuickBytes newBuffer;
-
- if (!AllocateAndInitializeSid(&siaWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pSID)) {
- goto ErrorExit;
- }
-
- nSidSize = GetLengthSid(pSID);
-
- //
- // Create Discretionary Access Control List (DACL).
- //
-
- // First calculate the size of the DACL, since this is a linked-list like structure which contains one or more
- // ACE (access control entry)
- nAclSize = sizeof(ACL) // the header structure of ACL
- + sizeof(ACCESS_ALLOWED_ACE) + nSidSize; // and one "access allowed ACE".
-
- // We know the size needed for DACL now, so create it.
- // An exception is thrown if OOM happens.
- pDACL = (PACL) (newBuffer.AllocThrows(nAclSize));
- if(!InitializeAcl( pDACL, nAclSize, ACL_REVISION ))
- goto ErrorExit;
-
- // Add the "access allowed ACE", meaning:
- // we will allow members of the "Everyone" group to have SECTION_MAP_READ | SECTION_QUERY access to the file mapping object.
- // for memory sections the creator will still be allowed to create it.
- if(!AddAccessAllowedAce( pDACL, ACL_REVISION, SECTION_MAP_READ | SECTION_QUERY, pSID ))
- goto ErrorExit;
-
- //
- // Create Security descriptor (SD).
- //
- if(!InitializeSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION ))
- goto ErrorExit;
- // Set the previously created DACL to this SD.
- if(!SetSecurityDescriptorDacl( &sd, TRUE, pDACL, FALSE ))
- goto ErrorExit;
-
- // Create Security Attribute (SA).
- sa.nLength = sizeof( sa ) ;
- sa.bInheritHandle = TRUE ;
- sa.lpSecurityDescriptor = &sd ;
-
- //
- // Finally, create the file mapping using the SA.
- //
-
- // If we are on Windows 2000 or later, try to open it in global namespace. The \global namespace is ignored if
- // Terminal service is not running.
- WCHAR globalSectionName[MAX_LONGPATH];
- wcscpy_s(globalSectionName, COUNTOF(globalSectionName), W("Global\\"));
- if (wcslen(pMappingName) + wcslen(globalSectionName) >= MAX_LONGPATH) {
- goto ErrorExit;
- }
- wcscat_s(globalSectionName, COUNTOF(globalSectionName), pMappingName);
-
- // Try to create the section in the Global\ namespace. The CreateFileMapping() will ignore Global\ namespace if Terminal Service
- // is not running.
- hFileMap = WszCreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, iSize, globalSectionName);
-
- // If not allowed to be global (like terminal server) or not WinNT, then open it in local namespace.
- if (hFileMap == NULL)
- {
- // Not WinNT or access denied for Global\ namespace, try the local namespace. When Terminal service is running, the Local\ namespace
- // means the namespace "Sessions\<n>\BasedNamedObjects".
- hFileMap = WszCreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, iSize, pMappingName);
- }
-
-ErrorExit:
- if(pSID)
- FreeSid( pSID );
-
- // If still not allowed, try building one with no name
- if (hFileMap == NULL)
- {
- hFileMap = WszCreateFileMapping(
- INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, iSize, NULL);
- }
-
- return (hFileMap) ;
-}
-
-/*=================================OpenOrCreateMemoryMapping==================================
-**Action: Opens an existing memory mapped object, or creates a new one (by calling above fn).
-** Worst case just allocate some memory.
-**Returns: The pointer to our memory. NULL if any error happens.
-**Arguments:
-** pMappingName the name of the file mapping object.
-** iSize Size to use
-**Exceptions:
-**
-**IMPORTANT:
-** Memory mapped sections are cleared when set. We expect the caller to set the last int
-** to a non-zero value, so we test this flag. If it is still zero when we open it, we
-** assume that we've gotten a result in an unfinished state and allocate a new one instead
-** of trying to use the one with the zeros.
-**
-**Note:
-** This function creates a DACL which grants GENERIC_ALL access to members of the "Everyone" group.
-** Then create a security descriptor using this DACL. Finally, use this SA to create the file mapping object.
-** WARNING:
-** This creates a shared file or shared paged memory section (if hFile == INVALID_HANDLE_VALUE) that is shared machine-wide
-** Therefore for side-by-side to work, the mapping names must be unique per version!
-** We utilize this feature for code pages in case it hasn't changed across versions we can still reuse the
-** tables, but it seems suspicious for other applications (as commented in MapDataFile below)
-==============================================================================*/
-PBYTE NLSTable::OpenOrCreateMemoryMapping(const LPCWSTR pMappingName, const int iSize, HANDLE* mappedFile)
-{
- CONTRACTL
- {
- THROWS;
- DISABLED(GC_TRIGGERS); //
- MODE_ANY;
- PRECONDITION(iSize % 4 == 0);
- PRECONDITION(iSize > 0);
- PRECONDITION(CheckPointer(pMappingName));
- PRECONDITION(CheckPointer(mappedFile));
- } CONTRACTL_END;
-
- _ASSERTE(pMappingName != NULL); // Must have a string name.
- _ASSERTE(iSize > 0); // Pointless to have <= 0 allocation
- _ASSERTE(iSize % 4 == 0); // Need 4 byte alignment for flag check
-
- LPVOID pResult = NULL;
-
- // Try creating/opening it.
- HANDLE hMap = NULL;
-
- *mappedFile = hMap;
- // Calls into OS a lot, should switch to preemp mode
- GCX_PREEMP();
-
- // First try opening it. It might already be in existence
- // The assumption here is that it's rare that we will hit the cases where two or more threads are trying to create
- // the named section at the same time. Therefore, the following code does not use critical section or mutex trying
- // to synchornize different threads.
-
- // Try to open it in global namespace. The global\ namespace is ignored if terminal service is not running.
- WCHAR globalSectionName[MAX_LONGPATH];
- wcscpy_s(globalSectionName, COUNTOF(globalSectionName), W("Global\\"));
- if (wcslen(pMappingName) + wcslen(globalSectionName) >= MAX_LONGPATH)
- return NULL;
-
- wcscat_s(globalSectionName, COUNTOF(globalSectionName), pMappingName);
-
- hMap = WszOpenFileMapping(FILE_MAP_READ, TRUE, globalSectionName);
- if (hMap == NULL) {
- // If access is denied for global\namespace or the name is not opened in global namespace, try the local namespace.
- // Also if we're rotor or win 9x.
- hMap = WszOpenFileMapping(FILE_MAP_READ, TRUE, pMappingName);
- }
-
- if (hMap != NULL) {
- // We got a section, map a view, READ ONLY!
- pResult = MapViewOfFile( hMap, FILE_MAP_READ, 0, 0, 0);
-
- // Anything found?
- if (pResult != NULL)
- {
- // Make sure our result is allocated. We expect a non-0 flag to be set for last int of our section
- const int* pFlag = (int*)(((BYTE*)pResult) + iSize - 4);
- if (*pFlag != 0)
- {
- *mappedFile = hMap;
- // Found a valid already opened section!
- return (PBYTE)pResult;
- }
-
- // Couldn't find it, unmap it.
- UnmapViewOfFile(pResult);
- pResult = NULL;
- }
-
- // We can't use this one, so close it
- CloseHandle(hMap);
- hMap = NULL;
- }
-
- // Didn't get a section, try to create one, NT/XP/.Net gets security permissions, 9X doesn't,
- // but our helper fn takes care of that for us.
- hMap = NLSTable::CreateSharedMemoryMapping(pMappingName, iSize);
-
- // Were we successfull?
- if (hMap != NULL)
- {
- // We have hMap, try to get our section
- pResult = MapViewOfFile( hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
-
- // Don't close hMap unless we aren't using it.
- // That confuses the mapping stuff and we lose the name, it'll close when runtime shuts down.
- if (pResult == NULL)
- {
- CloseHandle(hMap);
- hMap = NULL;
- }
- // There is no need to zero out the mapCodePageCached field, since the initial contents of the pages in the file mapping object are zero.
-
- *mappedFile = hMap;
- }
-
- return (PBYTE)pResult;
-}
-
-#endif
diff --git a/src/coreclr/hosts/unixcoreconsole/CMakeLists.txt b/src/coreclr/hosts/unixcoreconsole/CMakeLists.txt
index 94587b5374..2daeaabfa3 100644
--- a/src/coreclr/hosts/unixcoreconsole/CMakeLists.txt
+++ b/src/coreclr/hosts/unixcoreconsole/CMakeLists.txt
@@ -31,8 +31,4 @@ if(NOT CLR_CMAKE_PLATFORM_ANDROID)
)
endif()
-add_dependencies(coreconsole
- coreclr
-)
-
install_clr(coreconsole)
diff --git a/src/coreclr/hosts/unixcoreconsole/coreconsole.cpp b/src/coreclr/hosts/unixcoreconsole/coreconsole.cpp
index e43124d0f2..d46f6ef5bb 100644
--- a/src/coreclr/hosts/unixcoreconsole/coreconsole.cpp
+++ b/src/coreclr/hosts/unixcoreconsole/coreconsole.cpp
@@ -93,7 +93,6 @@ bool ParseArguments(
int main(const int argc, const char* argv[])
{
// Make sure we have a full path for argv[0].
- std::string argv0AbsolutePath;
std::string entryPointExecutablePath;
if (!GetEntrypointExecutableAbsolutePath(entryPointExecutablePath))
@@ -102,15 +101,9 @@ int main(const int argc, const char* argv[])
return -1;
}
- if (!GetAbsolutePath(entryPointExecutablePath.c_str(), argv0AbsolutePath))
- {
- perror("Could not normalize full path to current executable");
- return -1;
- }
-
// We will try to load the managed assembly with the same name as this executable
// but with the .dll extension.
- std::string programPath(argv0AbsolutePath);
+ std::string programPath(entryPointExecutablePath);
programPath.append(".dll");
const char* managedAssemblyAbsolutePath = programPath.c_str();
@@ -146,13 +139,13 @@ int main(const int argc, const char* argv[])
}
std::string clrFilesAbsolutePath;
- if(!GetClrFilesAbsolutePath(argv0AbsolutePath.c_str(), clrFilesPath, clrFilesAbsolutePath))
+ if(!GetClrFilesAbsolutePath(entryPointExecutablePath.c_str(), clrFilesPath, clrFilesAbsolutePath))
{
return -1;
}
int exitCode = ExecuteManagedAssembly(
- argv0AbsolutePath.c_str(),
+ entryPointExecutablePath.c_str(),
clrFilesAbsolutePath.c_str(),
managedAssemblyAbsolutePath,
managedAssemblyArgc,
diff --git a/src/coreclr/hosts/unixcorerun/CMakeLists.txt b/src/coreclr/hosts/unixcorerun/CMakeLists.txt
index b5dc730aaf..07beaae1df 100644
--- a/src/coreclr/hosts/unixcorerun/CMakeLists.txt
+++ b/src/coreclr/hosts/unixcorerun/CMakeLists.txt
@@ -32,8 +32,4 @@ if(NOT CLR_CMAKE_PLATFORM_ANDROID)
)
endif()
-add_dependencies(corerun
- coreclr
-)
-
install_clr(corerun)
diff --git a/src/coreclr/hosts/unixcorerun/corerun.cpp b/src/coreclr/hosts/unixcorerun/corerun.cpp
index da886d4338..4e5c9d9839 100644
--- a/src/coreclr/hosts/unixcorerun/corerun.cpp
+++ b/src/coreclr/hosts/unixcorerun/corerun.cpp
@@ -127,7 +127,7 @@ int corerun(const int argc, const char* argv[])
// Make sure we have a full path for argv[0].
std::string argv0AbsolutePath;
- if (!GetAbsolutePath(argv[0], argv0AbsolutePath))
+ if (!GetEntrypointExecutableAbsolutePath(argv0AbsolutePath))
{
perror("Could not get full path");
return -1;
diff --git a/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp b/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp
index 5ac7654780..d40fb424e6 100644
--- a/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp
+++ b/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp
@@ -49,21 +49,7 @@ bool GetEntrypointExecutableAbsolutePath(std::string& entrypointExecutable)
// Get path to the executable for the current process using
// platform specific means.
-#if defined(__linux__) || (defined(__NetBSD__) && !defined(KERN_PROC_PATHNAME))
- // On Linux, fetch the entry point EXE absolute path, inclusive of filename.
- char exe[PATH_MAX];
- ssize_t res = readlink(symlinkEntrypointExecutable, exe, PATH_MAX - 1);
- if (res != -1)
- {
- exe[res] = '\0';
- entrypointExecutable.assign(exe);
- result = true;
- }
- else
- {
- result = false;
- }
-#elif defined(__APPLE__)
+#if defined(__APPLE__)
// On Mac, we ask the OS for the absolute path to the entrypoint executable
uint32_t lenActualPath = 0;
@@ -115,10 +101,9 @@ bool GetEntrypointExecutableAbsolutePath(std::string& entrypointExecutable)
result = false;
}
#else
- // On non-Mac OS, return the symlink that will be resolved by GetAbsolutePath
+ // On other OSs, return the symlink that will be resolved by GetAbsolutePath
// to fetch the entrypoint EXE absolute path, inclusive of filename.
- entrypointExecutable.assign(symlinkEntrypointExecutable);
- result = true;
+ result = GetAbsolutePath(symlinkEntrypointExecutable, entrypointExecutable);
#endif
return result;
diff --git a/src/corefx/System.Globalization.Native/CMakeLists.txt b/src/corefx/System.Globalization.Native/CMakeLists.txt
index 9ecb0e08b9..55c6854497 100644
--- a/src/corefx/System.Globalization.Native/CMakeLists.txt
+++ b/src/corefx/System.Globalization.Native/CMakeLists.txt
@@ -10,11 +10,11 @@ set(ICU_HOMEBREW_INC_PATH "/usr/local/opt/icu4c/include")
find_path(UTYPES_H "unicode/utypes.h" PATHS ${ICU_HOMEBREW_INC_PATH})
if(UTYPES_H STREQUAL UTYPES_H-NOTFOUND)
- message(FATAL_ERROR "Cannont find utypes.h, try installing libicu-dev (or the appropriate package for your platform)")
+ message(FATAL_ERROR "Cannot find utypes.h, try installing libicu-dev (or the appropriate package for your platform)")
return()
endif()
-if (FEATURE_FIXED_ICU_VERSION AND NOT CLR_CMAKE_PLATFORM_DARWIN)
+if (NOT CLR_CMAKE_PLATFORM_DARWIN)
find_library(ICUUC icuuc)
if(ICUUC STREQUAL ICUUC-NOTFOUND)
message(FATAL_ERROR "Cannot find libicuuc, try installing libicu-dev (or the appropriate package for your platform)")
@@ -26,16 +26,14 @@ if (FEATURE_FIXED_ICU_VERSION AND NOT CLR_CMAKE_PLATFORM_DARWIN)
message(FATAL_ERROR "Cannot find libicui18n, try installing libicu-dev (or the appropriate package for your platform)")
return()
endif()
-endif()
-
-if(CLR_CMAKE_PLATFORM_DARWIN)
+else()
find_library(ICUCORE icucore)
if(ICUI18N STREQUAL ICUCORE-NOTFOUND)
message(FATAL_ERROR "Cannot find libicucore, skipping build for System.Globalization.Native. .NET globalization is not expected to function.")
return()
endif()
- # On Darwin, we always use the OS provided ICU
- SET(FEATURE_FIXED_ICU_VERSION 1)
+
+ add_definitions(-DOSX_ICU_LIBRARY_PATH=\"${ICUCORE}\")
endif()
include(configure.cmake)
@@ -52,14 +50,9 @@ set(NATIVEGLOBALIZATION_SOURCES
localeStringData.cpp
normalization.cpp
timeZoneInfo.cpp
+ icushim.cpp
)
-if (NOT FEATURE_FIXED_ICU_VERSION)
- list(APPEND NATIVEGLOBALIZATION_SOURCES
- icushim.cpp
- )
-endif()
-
include_directories(${UTYPES_H})
_add_library(System.Globalization.Native
@@ -78,21 +71,8 @@ set_target_properties(System.Globalization.Native_Static PROPERTIES OUTPUT_NAME
# Disable the "lib" prefix.
set_target_properties(System.Globalization.Native PROPERTIES PREFIX "")
-if (FEATURE_FIXED_ICU_VERSION)
- add_definitions(-DFEATURE_FIXED_ICU_VERSION)
-endif()
-
if(NOT CLR_CMAKE_PLATFORM_DARWIN)
- if (FEATURE_FIXED_ICU_VERSION)
- target_link_libraries(System.Globalization.Native
- ${ICUUC}
- ${ICUI18N}
- )
- target_link_libraries(System.Globalization.Native_Static
- ${ICUUC}
- ${ICUI18N}
- )
- elseif(NOT CMAKE_SYSTEM_NAME STREQUAL FreeBSD AND NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+ if (NOT CMAKE_SYSTEM_NAME STREQUAL FreeBSD AND NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD)
target_link_libraries(System.Globalization.Native
dl
)
@@ -102,7 +82,7 @@ if(NOT CLR_CMAKE_PLATFORM_DARWIN)
endif()
else()
target_link_libraries(System.Globalization.Native
- ${ICUCORE}
+ dl
)
add_definitions(-DU_DISABLE_RENAMING=1)
diff --git a/src/corefx/System.Globalization.Native/collation.cpp b/src/corefx/System.Globalization.Native/collation.cpp
index f37211208e..a8c24e16ad 100644
--- a/src/corefx/System.Globalization.Native/collation.cpp
+++ b/src/corefx/System.Globalization.Native/collation.cpp
@@ -440,7 +440,8 @@ extern "C" int32_t GlobalizationNative_IndexOf(
int32_t cwTargetLength,
const UChar* lpSource,
int32_t cwSourceLength,
- int32_t options)
+ int32_t options,
+ int32_t* pMatchedLength)
{
static_assert(USEARCH_DONE == -1, "managed side requires -1 for not found");
@@ -455,6 +456,13 @@ extern "C" int32_t GlobalizationNative_IndexOf(
if (U_SUCCESS(err))
{
result = usearch_first(pSearch, &err);
+
+ // if the search was successful,
+ // we'll try to get the matched string length.
+ if(result != USEARCH_DONE && pMatchedLength != NULL)
+ {
+ *pMatchedLength = usearch_getMatchedLength(pSearch);
+ }
usearch_close(pSearch);
}
}
diff --git a/src/corefx/System.Globalization.Native/icushim.cpp b/src/corefx/System.Globalization.Native/icushim.cpp
index 63f111b8b1..6e7817e85f 100644
--- a/src/corefx/System.Globalization.Native/icushim.cpp
+++ b/src/corefx/System.Globalization.Native/icushim.cpp
@@ -19,6 +19,33 @@ FOR_ALL_ICU_FUNCTIONS
static void* libicuuc = nullptr;
static void* libicui18n = nullptr;
+// .x.x.x, considering the max number of decimal digits for each component
+static const int MaxICUVersionStringLength = 33;
+
+#ifdef __APPLE__
+
+bool FindICULibs(char* symbolName, char* symbolVersion)
+{
+#ifndef OSX_ICU_LIBRARY_PATH
+ static_assert(false, "The ICU Library path is not defined");
+#endif // OSX_ICU_LIBRARY_PATH
+
+ // Usually OSX_ICU_LIBRARY_PATH is "/usr/lib/libicucore.dylib"
+ libicuuc = dlopen(OSX_ICU_LIBRARY_PATH, RTLD_LAZY);
+
+ if (libicuuc == nullptr)
+ {
+ return false;
+ }
+
+ // in OSX all ICU APIs exist in the same library libicucore.A.dylib
+ libicui18n = libicuuc;
+
+ return true;
+}
+
+#else // __APPLE__
+
// Version ranges to search for each of the three version components
// The rationale for major version range is that we support versions higher or
// equal to the version we are built against and less or equal to that version
@@ -31,9 +58,6 @@ static const int MaxMinorICUVersion = 5;
static const int MinSubICUVersion = 1;
static const int MaxSubICUVersion = 5;
-// .x.x.x, considering the max number of decimal digits for each component
-static const int MaxICUVersionStringLength = 33;
-
// Get filename of an ICU library with the requested version in the name
// There are three possible cases of the version components values:
// 1. Only majorVer is not equal to -1 => result is baseFileName.majorver
@@ -111,6 +135,22 @@ bool FindLibUsingOverride(int* majorVer, int* minorVer, int* subVer)
}
// Select the highest supported version of ICU present on the local machine
+// Search for library files with names including the major version.
+bool FindLibWithMajorVersion(int* majorVer)
+{
+ for (int i = MaxICUVersion; i >= MinICUVersion; i--)
+ {
+ if (OpenICULibraries(i, -1, -1))
+ {
+ *majorVer = i;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Select the highest supported version of ICU present on the local machine
// Search for library files with names including the major and minor version.
bool FindLibWithMajorMinorVersion(int* majorVer, int* minorVer)
{
@@ -154,9 +194,7 @@ bool FindLibWithMajorMinorSubVersion(int* majorVer, int* minorVer, int* subVer)
return false;
}
-// This function is ran at the end of dlopen for the current shared library
-__attribute__((constructor))
-void InitializeICUShim()
+bool FindICULibs(char* symbolName, char* symbolVersion)
{
int majorVer = -1;
int minorVer = -1;
@@ -164,16 +202,13 @@ void InitializeICUShim()
if (!FindLibUsingOverride(&majorVer, &minorVer, &subVer) &&
!FindLibWithMajorMinorVersion(&majorVer, &minorVer) &&
- !FindLibWithMajorMinorSubVersion(&majorVer, &minorVer, &subVer))
+ !FindLibWithMajorMinorSubVersion(&majorVer, &minorVer, &subVer) &&
+ // This is a fallback for the rare case when there are only lib files with major version
+ !FindLibWithMajorVersion(&majorVer))
{
// No usable ICU version found
- fprintf(stderr, "No usable version of the ICU libraries was found\n");
- abort();
+ return false;
}
-
- char symbolName[128];
- char symbolVersion[MaxICUVersionStringLength + 1] = "";
-
// Find out the format of the version string added to each symbol
// First try just the unversioned symbol
if (dlsym(libicuuc, "u_strlen") == nullptr)
@@ -181,25 +216,42 @@ void InitializeICUShim()
// Now try just the _majorVer added
sprintf(symbolVersion, "_%d", majorVer);
sprintf(symbolName, "u_strlen%s", symbolVersion);
- if (dlsym(libicuuc, symbolName) == nullptr)
+ if ((dlsym(libicuuc, symbolName) == nullptr) && (minorVer != -1))
{
// Now try the _majorVer_minorVer added
sprintf(symbolVersion, "_%d_%d", majorVer, minorVer);
sprintf(symbolName, "u_strlen%s", symbolVersion);
- if (dlsym(libicuuc, symbolName) == nullptr)
+ if ((dlsym(libicuuc, symbolName) == nullptr) && (subVer != -1))
{
// Finally, try the _majorVer_minorVer_subVer added
sprintf(symbolVersion, "_%d_%d_%d", majorVer, minorVer, subVer);
sprintf(symbolName, "u_strlen%s", symbolVersion);
if (dlsym(libicuuc, symbolName) == nullptr)
{
- fprintf(stderr, "ICU libraries use unknown symbol versioning\n");
- abort();
+ return false;
}
}
}
}
+ return true;
+
+}
+
+#endif // __APPLE__
+
+// GlobalizationNative_LoadICU
+// This method get called from the managed side during the globalization initialization.
+// This method shouldn't get called at all if we are running in globalization invariant mode
+// return 0 if failed to load ICU and 1 otherwise
+extern "C" int32_t GlobalizationNative_LoadICU()
+{
+ char symbolName[128];
+ char symbolVersion[MaxICUVersionStringLength + 1] = "";
+
+ if (!FindICULibs(symbolName, symbolVersion))
+ return 0;
+
// Get pointers to all the ICU functions that are needed
#define PER_FUNCTION_BLOCK(fn, lib) \
static_assert((sizeof(#fn) + MaxICUVersionStringLength + 1) <= sizeof(symbolName), "The symbolName is too small for symbol " #fn); \
@@ -209,6 +261,13 @@ void InitializeICUShim()
FOR_ALL_ICU_FUNCTIONS
#undef PER_FUNCTION_BLOCK
+
+#ifdef __APPLE__
+ // libicui18n initialized with libicuuc so we null it to avoid double closing same handle
+ libicui18n = nullptr;
+#endif // __APPLE__
+
+ return 1;
}
__attribute__((destructor))
diff --git a/src/corefx/System.Globalization.Native/icushim.h b/src/corefx/System.Globalization.Native/icushim.h
index 8ec13d5737..408ec15edd 100644
--- a/src/corefx/System.Globalization.Native/icushim.h
+++ b/src/corefx/System.Globalization.Native/icushim.h
@@ -4,17 +4,14 @@
//
// Enable calling ICU functions through shims to enable support for
-// multiple versions of ICU if the FEATURE_FIXED_ICU_VERSION is
-// not defined.
+// multiple versions of ICU.
#ifndef __ICUSHIM_H__
#define __ICUSHIM_H__
#include "config.h"
-#ifndef FEATURE_FIXED_ICU_VERSION
#define U_DISABLE_RENAMING 1
-#endif
// All ICU headers need to be included here so that all function prototypes are
// available before the function pointers are declared below.
@@ -36,8 +33,6 @@
#include <unicode/utf16.h>
#include <unicode/utypes.h>
-#ifndef FEATURE_FIXED_ICU_VERSION
-
// List of all functions from the ICU libraries that are used in the System.Globalization.Native.so
#define FOR_ALL_UNCONDITIONAL_ICU_FUNCTIONS \
PER_FUNCTION_BLOCK(u_charsToUChars, libicuuc) \
@@ -238,6 +233,4 @@ FOR_ALL_ICU_FUNCTIONS
#define usearch_last(...) usearch_last_ptr(__VA_ARGS__)
#define usearch_openFromCollator(...) usearch_openFromCollator_ptr(__VA_ARGS__)
-#endif // !FEATURE_ICU_VERSION_RESILIENT
-
#endif // __ICUSHIM_H__
diff --git a/src/debug/daccess/CMakeLists.txt b/src/debug/daccess/CMakeLists.txt
index 30068450b4..aab3f81ac6 100644
--- a/src/debug/daccess/CMakeLists.txt
+++ b/src/debug/daccess/CMakeLists.txt
@@ -7,12 +7,11 @@ include_directories(BEFORE ${VM_DIR})
include_directories(BEFORE ${VM_DIR}/${ARCH_SOURCES_DIR})
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CLR_DIR}/src/debug/ee)
-include_directories(${CLR_DIR}/src/gc)
include_directories(${CLR_DIR}/src/gcdump)
if(CLR_CMAKE_PLATFORM_UNIX)
- include_directories(${GENERATED_INCLUDE_DIR})
- add_compile_options(-fPIC)
+ include_directories(${GENERATED_INCLUDE_DIR})
+ add_compile_options(-fPIC)
endif(CLR_CMAKE_PLATFORM_UNIX)
set(DACCESS_SOURCES
@@ -45,5 +44,23 @@ add_precompiled_header(stdafx.h stdafx.cpp DACCESS_SOURCES)
add_library_clr(daccess ${DACCESS_SOURCES})
if(CLR_CMAKE_PLATFORM_UNIX)
- add_dependencies(daccess coreclr)
+ add_custom_command(
+ OUTPUT ${GENERATED_INCLUDE_DIR}/dactablerva.h
+ DEPENDS coreclr
+ VERBATIM
+ COMMAND sh ${CLR_DIR}/src/pal/tools/gen-dactable-rva.sh $<TARGET_FILE:coreclr> ${GENERATED_INCLUDE_DIR}/dactablerva.h
+ COMMENT Generating ${GENERATED_INCLUDE_DIR}/dactablerva.h
+ )
+
+ set_source_files_properties(
+ ${GENERATED_INCLUDE_DIR}/dactablerva.h
+ PROPERTIES GENERATED TRUE
+ )
+
+ add_custom_target(
+ dactablerva_header
+ DEPENDS ${GENERATED_INCLUDE_DIR}/dactablerva.h
+ )
+
+ add_dependencies(daccess dactablerva_header)
endif(CLR_CMAKE_PLATFORM_UNIX)
diff --git a/src/debug/daccess/daccess.cpp b/src/debug/daccess/daccess.cpp
index 69167ab07e..dcf6314549 100644
--- a/src/debug/daccess/daccess.cpp
+++ b/src/debug/daccess/daccess.cpp
@@ -5235,7 +5235,7 @@ ClrDataAccess::FollowStubStep(
// this and redirect to the actual code.
methodDesc = trace.GetMethodDesc();
if (methodDesc->IsPreImplemented() &&
- !methodDesc->IsPointingToNativeCode() &&
+ !methodDesc->IsPointingToStableNativeCode() &&
!methodDesc->IsGenericMethodDefinition() &&
methodDesc->HasNativeCode())
{
@@ -7934,7 +7934,8 @@ STDAPI OutOfProcessExceptionEventDebuggerLaunchCallback(__in PDWORD pContext,
// DacHandleEnum
-#include "handletablepriv.h"
+// TODO(Local GC) - The DAC should not include GC headers
+#include "../../gc/handletablepriv.h"
#include "comcallablewrapper.h"
DacHandleWalker::DacHandleWalker()
@@ -7976,7 +7977,7 @@ HRESULT DacHandleWalker::Init(ClrDataAccess *dac, UINT types[], UINT typeCount,
{
SUPPORTS_DAC;
- if (gen < 0 || gen > (int)GCHeapUtilities::GetMaxGeneration())
+ if (gen < 0 || gen > (int)*g_gcDacGlobals->max_gen)
return E_INVALIDARG;
mGenerationFilter = gen;
@@ -8091,7 +8092,7 @@ bool DacHandleWalker::FetchMoreHandles(HANDLESCANPROC callback)
HndScanHandlesForGC(hTable, callback,
(LPARAM)&param, 0,
&handleType, 1,
- mGenerationFilter, GCHeapUtilities::GetMaxGeneration(), 0);
+ mGenerationFilter, *g_gcDacGlobals->max_gen, 0);
else
HndEnumHandles(hTable, &handleType, 1, callback, (LPARAM)&param, 0, FALSE);
}
diff --git a/src/debug/daccess/dacdbiimpl.cpp b/src/debug/daccess/dacdbiimpl.cpp
index ae266e8a6f..605d5c7cee 100644
--- a/src/debug/daccess/dacdbiimpl.cpp
+++ b/src/debug/daccess/dacdbiimpl.cpp
@@ -25,15 +25,14 @@
#include "stackwalk.h"
#include "dacdbiimpl.h"
-#ifndef FEATURE_CORECLR
-#include "assemblyusagelogmanager.h"
-#endif
#ifdef FEATURE_COMINTEROP
#include "runtimecallablewrapper.h"
#include "comcallablewrapper.h"
#endif // FEATURE_COMINTEROP
+#include "request_common.h"
+
//-----------------------------------------------------------------------------
// Have standard enter and leave macros at the DacDbi boundary to enforce
// standard behavior.
@@ -3249,12 +3248,6 @@ CORDB_ADDRESS DacDbiInterfaceImpl::GetThreadOrContextStaticAddress(VMPTR_FieldDe
{
fieldAddress = pRuntimeThread->GetStaticFieldAddrNoCreate(pFieldDesc, NULL);
}
-#ifdef FEATURE_REMOTING
- else if (pFieldDesc->IsContextStatic())
- {
- fieldAddress = PTR_TO_TADDR(pRuntimeThread->GetContext()->GetStaticFieldAddrNoCreate(pFieldDesc));
- }
-#endif
else
{
// In case we have more special cases added later, this will allow us to notice the need to
@@ -3473,12 +3466,7 @@ void DacDbiInterfaceImpl::GetStackFramesFromException(VMPTR_Object vmObject, Dac
currentFrame.vmDomainFile.SetHostPtr(pDomainFile);
currentFrame.ip = currentElement.ip;
currentFrame.methodDef = currentElement.pFunc->GetMemberDef();
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
currentFrame.isLastForeignExceptionFrame = currentElement.fIsLastFrameFromForeignStackTrace;
-#else
- // for CLRs lacking exception dispatch info just set it to 0
- currentFrame.isLastForeignExceptionFrame = 0;
-#endif
}
}
}
@@ -4541,29 +4529,6 @@ void DacDbiInterfaceImpl::MarkDebuggerAttached(BOOL fAttached)
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-// Enumerate all the Connections in the process.
-void DacDbiInterfaceImpl::EnumerateConnections(FP_CONNECTION_CALLBACK fpCallback, void * pUserData)
-{
- DD_ENTER_MAY_THROW;
-
- ConnectionNameHashEntry * pConnection;
-
- HASHFIND hashfind;
-
- pConnection = CCLRDebugManager::FindFirst(&hashfind);
- while (pConnection)
- {
- DWORD id = pConnection->m_dwConnectionId;
- LPCWSTR pName = pConnection->m_pwzName;
-
- fpCallback(id, pName, pUserData);
-
- // now get the next connection record
- pConnection = CCLRDebugManager::FindNext(&hashfind);
- }
-}
-#endif
// Enumerate all threads in the process.
@@ -4783,14 +4748,7 @@ DWORD DacDbiInterfaceImpl::GetUniqueThreadID(VMPTR_Thread vmThread)
Thread * pThread = vmThread.GetDacPtr();
_ASSERTE(pThread != NULL);
- if (CLRTaskHosted())
- {
- return pThread->GetThreadId();
- }
- else
- {
- return pThread->GetOSThreadId();
- }
+ return pThread->GetOSThreadId();
}
// Return the object handle to the managed Exception object of the current exception
@@ -5494,15 +5452,8 @@ CorDebugUserState DacDbiInterfaceImpl::GetPartialUserState(VMPTR_Thread vmThread
result |= USER_WAIT_SLEEP_JOIN;
}
- // Don't report a SuspendRequested if the thread has actually Suspended.
- if ((ts & Thread::TS_UserSuspendPending) && (ts & Thread::TS_SyncSuspended))
- {
- result |= USER_SUSPENDED;
- }
- else if (ts & Thread::TS_UserSuspendPending)
- {
- result |= USER_SUSPEND_REQUESTED;
- }
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(ts & Thread::TS_UserSuspendPending));
if (pThread->IsThreadPoolThread())
{
@@ -5684,28 +5635,7 @@ VMPTR_Object DacDbiInterfaceImpl::GetObject(CORDB_ADDRESS ptr)
HRESULT DacDbiInterfaceImpl::EnableNGENPolicy(CorDebugNGENPolicy ePolicy)
{
-#ifndef FEATURE_CORECLR
- DD_ENTER_MAY_THROW;
-
- // translate from our publicly exposed enum to the appropriate internal value
- AssemblyUsageLogManager::ASSEMBLY_USAGE_LOG_FLAGS asmFlag = AssemblyUsageLogManager::ASSEMBLY_USAGE_LOG_FLAGS_NONE;
-
- switch (ePolicy)
- {
- case DISABLE_LOCAL_NIC:
- asmFlag = AssemblyUsageLogManager::ASSEMBLY_USAGE_LOG_FLAGS_APPLOCALNGENDISABLED;
- break;
- default:
- return E_INVALIDARG;
- }
-
- // we should have made some selection
- _ASSERTE(asmFlag != AssemblyUsageLogManager::ASSEMBLY_USAGE_LOG_FLAGS_NONE);
-
- return AssemblyUsageLogManager::SetUsageLogFlag(asmFlag, TRUE);
-#else
return E_NOTIMPL;
-#endif // FEATURE_CORECLR
}
HRESULT DacDbiInterfaceImpl::SetNGENCompilerFlags(DWORD dwFlags)
@@ -5788,9 +5718,9 @@ BOOL DacDbiInterfaceImpl::IsVmObjectHandleValid(VMPTR_OBJECTHANDLE vmHandle)
// SEH exceptions will be caught
EX_TRY
{
- OBJECTREF objRef = ObjectFromHandle((OBJECTHANDLE)vmHandle.GetDacPtr());
+ OBJECTREF objRef = HndFetchHandle((OBJECTHANDLE)vmHandle.GetDacPtr());
- // NULL is certinally valid...
+ // NULL is certainly valid...
if (objRef != NULL)
{
if (objRef->ValidateObjectWithPossibleAV())
@@ -6636,7 +6566,6 @@ HRESULT DacHeapWalker::ListNearObjects(CORDB_ADDRESS obj, CORDB_ADDRESS *pPrev,
return hr;
}
-#include "gceewks.cpp"
HRESULT DacHeapWalker::InitHeapDataWks(HeapData *&pHeaps, size_t &pCount)
{
// Scrape basic heap details
@@ -6645,16 +6574,20 @@ HRESULT DacHeapWalker::InitHeapDataWks(HeapData *&pHeaps, size_t &pCount)
if (pHeaps == NULL)
return E_OUTOFMEMORY;
- pHeaps[0].YoungestGenPtr = (CORDB_ADDRESS)WKS::generation_table[0].allocation_context.alloc_ptr;
- pHeaps[0].YoungestGenLimit = (CORDB_ADDRESS)WKS::generation_table[0].allocation_context.alloc_limit;
+ dac_generation gen0 = *GenerationTableIndex(g_gcDacGlobals->generation_table, 0);
+ dac_generation gen1 = *GenerationTableIndex(g_gcDacGlobals->generation_table, 1);
+ dac_generation gen2 = *GenerationTableIndex(g_gcDacGlobals->generation_table, 2);
+ dac_generation loh = *GenerationTableIndex(g_gcDacGlobals->generation_table, 3);
+ pHeaps[0].YoungestGenPtr = (CORDB_ADDRESS)gen0.allocation_context.alloc_ptr;
+ pHeaps[0].YoungestGenLimit = (CORDB_ADDRESS)gen0.allocation_context.alloc_limit;
- pHeaps[0].Gen0Start = (CORDB_ADDRESS)WKS::generation_table[0].allocation_start;
- pHeaps[0].Gen0End = (CORDB_ADDRESS)WKS::gc_heap::alloc_allocated.GetAddr();
- pHeaps[0].Gen1Start = (CORDB_ADDRESS)WKS::generation_table[1].allocation_start;
+ pHeaps[0].Gen0Start = (CORDB_ADDRESS)gen0.allocation_start;
+ pHeaps[0].Gen0End = (CORDB_ADDRESS)*g_gcDacGlobals->alloc_allocated;
+ pHeaps[0].Gen1Start = (CORDB_ADDRESS)gen1.allocation_start;
// Segments
- int count = GetSegmentCount(WKS::generation_table[NUMBERGENERATIONS-1].start_segment);
- count += GetSegmentCount(WKS::generation_table[NUMBERGENERATIONS-2].start_segment);
+ int count = GetSegmentCount(loh.start_segment);
+ count += GetSegmentCount(gen2.start_segment);
pHeaps[0].SegmentCount = count;
pHeaps[0].Segments = new (nothrow) SegmentData[count];
@@ -6662,14 +6595,14 @@ HRESULT DacHeapWalker::InitHeapDataWks(HeapData *&pHeaps, size_t &pCount)
return E_OUTOFMEMORY;
// Small object heap segments
- WKS::heap_segment *seg = WKS::generation_table[NUMBERGENERATIONS-2].start_segment;
+ DPTR(dac_heap_segment) seg = gen2.start_segment;
int i = 0;
for (; seg && (i < count); ++i)
{
pHeaps[0].Segments[i].Start = (CORDB_ADDRESS)seg->mem;
- if (seg == WKS::gc_heap::ephemeral_heap_segment)
+ if (seg.GetAddr() == (TADDR)*g_gcDacGlobals->ephemeral_heap_segment)
{
- pHeaps[0].Segments[i].End = (CORDB_ADDRESS)WKS::gc_heap::alloc_allocated.GetAddr();
+ pHeaps[0].Segments[i].End = (CORDB_ADDRESS)*g_gcDacGlobals->alloc_allocated;
pHeaps[0].Segments[i].Generation = 1;
pHeaps[0].EphemeralSegment = i;
}
@@ -6683,7 +6616,7 @@ HRESULT DacHeapWalker::InitHeapDataWks(HeapData *&pHeaps, size_t &pCount)
}
// Large object heap segments
- seg = WKS::generation_table[NUMBERGENERATIONS-1].start_segment;
+ seg = loh.start_segment;
for (; seg && (i < count); ++i)
{
pHeaps[0].Segments[i].Generation = 3;
@@ -7185,7 +7118,7 @@ void DacDbiInterfaceImpl::GetGCHeapInformation(COR_HEAPINFO * pHeapInfo)
DD_ENTER_MAY_THROW;
size_t heapCount = 0;
- pHeapInfo->areGCStructuresValid = GCScan::GetGcRuntimeStructuresValid();
+ pHeapInfo->areGCStructuresValid = *g_gcDacGlobals->gc_structures_invalid_cnt == 0;
#ifdef FEATURE_SVR_GC
if (GCHeapUtilities::IsServerHeap())
diff --git a/src/debug/daccess/dacdbiimplstackwalk.cpp b/src/debug/daccess/dacdbiimplstackwalk.cpp
index 29c9626db8..3bb2b9fdec 100644
--- a/src/debug/daccess/dacdbiimplstackwalk.cpp
+++ b/src/debug/daccess/dacdbiimplstackwalk.cpp
@@ -1152,7 +1152,7 @@ CorDebugInternalFrameType DacDbiInterfaceImpl::GetInternalFrameType(Frame * pFra
void DacDbiInterfaceImpl::UpdateContextFromRegDisp(REGDISPLAY * pRegDisp,
T_CONTEXT * pContext)
{
-#if defined(_TARGET_X86_)
+#if defined(_TARGET_X86_) && !defined(WIN64EXCEPTIONS)
// Do a partial copy first.
pContext->ContextFlags = (CONTEXT_INTEGER | CONTEXT_CONTROL);
@@ -1174,9 +1174,9 @@ void DacDbiInterfaceImpl::UpdateContextFromRegDisp(REGDISPLAY * pRegDisp,
{
*pContext = *pRegDisp->pContext;
}
-#else
+#else // _TARGET_X86_ && !WIN64EXCEPTIONS
*pContext = *pRegDisp->pCurrentContext;
-#endif
+#endif // !_TARGET_X86_ || WIN64EXCEPTIONS
}
//---------------------------------------------------------------------------------------
diff --git a/src/debug/daccess/dacfn.cpp b/src/debug/daccess/dacfn.cpp
index 33dfa10b54..0a167418a1 100644
--- a/src/debug/daccess/dacfn.cpp
+++ b/src/debug/daccess/dacfn.cpp
@@ -16,13 +16,13 @@
#ifdef FEATURE_PREJIT
#include "compile.h"
#endif // FEATURE_PREJIT
-#ifdef FEATURE_REMOTING
-#include <remoting.h>
-#include "objectclone.h"
-#endif
#include <virtualcallstub.h>
#include "peimagelayout.inl"
+#include "gcinterface.h"
+#include "gcinterface.dac.h"
+
+
DacTableInfo g_dacTableInfo;
DacGlobals g_dacGlobals;
diff --git a/src/debug/daccess/enummem.cpp b/src/debug/daccess/enummem.cpp
index 0f38aa582a..027fe59543 100644
--- a/src/debug/daccess/enummem.cpp
+++ b/src/debug/daccess/enummem.cpp
@@ -21,7 +21,6 @@
#include "ipcmanagerinterface.h"
#include "binder.h"
#include "win32threadpool.h"
-#include "gcscan.h"
#ifdef FEATURE_APPX
#include "appxutil.h"
@@ -266,6 +265,12 @@ HRESULT ClrDataAccess::EnumMemCLRStatic(IN CLRDataEnumMemoryFlags flags)
ReportMem( m_globalBase + g_dacGlobals.dac__g_FCDynamicallyAssignedImplementations,
sizeof(TADDR)*ECall::NUM_DYNAMICALLY_ASSIGNED_FCALL_IMPLEMENTATIONS);
+
+ // We need all of the dac variables referenced by the GC DAC global struct.
+ // This struct contains pointers to pointers, so we first dereference the pointers
+ // to obtain the location of the variable that's reported.
+#define GC_DAC_VAR(type, name) ReportMem(g_gcDacGlobals->name.GetAddr(), sizeof(type));
+#include "../../gc/gcinterface.dacvars.def"
}
EX_CATCH_RETHROW_ONLY_COR_E_OPERATIONCANCELLED
@@ -292,9 +297,6 @@ HRESULT ClrDataAccess::EnumMemCLRStatic(IN CLRDataEnumMemoryFlags flags)
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pValueTypeClass.EnumMem(); )
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pEnumClass.EnumMem(); )
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pThreadClass.EnumMem(); )
-#ifdef FEATURE_CER
- CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pCriticalFinalizerObjectClass.EnumMem(); )
-#endif
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pFreeObjectMethodTable.EnumMem(); )
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pObjectCtorMD.EnumMem(); )
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_fHostConfig.EnumMem(); )
@@ -315,12 +317,10 @@ HRESULT ClrDataAccess::EnumMemCLRStatic(IN CLRDataEnumMemoryFlags flags)
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pFinalizerThread.EnumMem(); )
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pSuspensionThread.EnumMem(); )
-#ifdef FEATURE_SVR_GC
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED
(
- IGCHeap::gcHeapType.EnumMem();
+ g_heap_type.EnumMem();
);
-#endif // FEATURE_SVR_GC
m_dumpStats.m_cbClrStatics = m_cbMemoryReported - cbMemoryReported;
@@ -404,7 +404,7 @@ HRESULT ClrDataAccess::DumpManagedObject(CLRDataEnumMemoryFlags flags, OBJECTREF
return status;
}
- if (!GCScan::GetGcRuntimeStructuresValid ())
+ if (*g_gcDacGlobals->gc_structures_invalid_cnt != 0)
{
// GC is in progress, don't dump this object
return S_OK;
@@ -462,7 +462,7 @@ HRESULT ClrDataAccess::DumpManagedExcepObject(CLRDataEnumMemoryFlags flags, OBJE
return S_OK;
}
- if (!GCScan::GetGcRuntimeStructuresValid ())
+ if (*g_gcDacGlobals->gc_structures_invalid_cnt != 0)
{
// GC is in progress, don't dump this object
return S_OK;
@@ -1734,11 +1734,7 @@ HRESULT ClrDataAccess::EnumMemoryRegionsWorkerCustom()
ECustomDumpFlavor eFlavor;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- eFlavor = CCLRErrorReportingManager::g_ECustomDumpFlavor;
-#else
eFlavor = DUMP_FLAVOR_Default;
-#endif
m_enumMemFlags = CLRDATA_ENUM_MEM_MINI;
diff --git a/src/debug/daccess/gcinterface.dac.h b/src/debug/daccess/gcinterface.dac.h
new file mode 100644
index 0000000000..031ec36f30
--- /dev/null
+++ b/src/debug/daccess/gcinterface.dac.h
@@ -0,0 +1,5 @@
+// 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 "../../gc/gcinterface.dac.h"
diff --git a/src/debug/daccess/inspect.cpp b/src/debug/daccess/inspect.cpp
index 5276626dcb..a69cfa3835 100644
--- a/src/debug/daccess/inspect.cpp
+++ b/src/debug/daccess/inspect.cpp
@@ -166,9 +166,6 @@ GetTypeFieldValueFlags(TypeHandle typeHandle,
otherFlags |= CLRDATA_VALUE_FROM_TASK_LOCAL;
}
else
-#ifdef FEATURE_REMOTING
- if (!fieldDesc->IsContextStatic())
-#endif
{
otherFlags |= CLRDATA_VALUE_FROM_INSTANCE;
}
@@ -1436,13 +1433,6 @@ ClrDataValue::NewFromFieldDesc(ClrDataAccess* dac,
baseAddr =
TO_CDADDR(tlsThread->GetStaticFieldAddrNoCreate(fieldDesc, NULL));
}
-#ifdef FEATURE_REMOTING
- else if (fieldDesc->IsContextStatic())
- {
- // XXX Microsoft - Microsoft says Context is going away.
- return E_NOTIMPL;
- }
-#endif
else if (fieldDesc->IsStatic())
{
baseAddr = TO_CDADDR
diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp
index 23e76c4fe4..77c05b5801 100644
--- a/src/debug/daccess/nidump.cpp
+++ b/src/debug/daccess/nidump.cpp
@@ -19,15 +19,11 @@
#include <algorithm>
#endif
-#include <constrainedexecutionregion.h>
#include <formattype.h>
#include <pedecoder.h>
-#ifdef FEATURE_REMOTING
-#include <crossdomaincalls.h>
-#endif
#include <mdfileformat.h>
@@ -623,20 +619,6 @@ void NativeImageDumper::DumpAssemblySignature(CORCOMPILE_ASSEMBLY_SIGNATURE & as
CORCOMPILE_ASSEMBLY_SIGNATURE, COR_INFO );
}
-#ifndef FEATURE_CORECLR
-
-const NativeImageDumper::EnumMnemonics s_CorCompileDependencyInfoFlags[] =
-{
-#define CMDI_ENTRY(f) NativeImageDumper::EnumMnemonics(CORCOMPILE_DEPENDENCY_ ## f, W(#f))
-
-#ifdef FEATURE_APTCA
- CMDI_ENTRY(IS_APTCA),
- CMDI_ENTRY(IS_CAPTCA),
-#endif //FEATURE_APTCA
-#undef CMDI_ENTRY
-};
-
-#endif //!FEATURE_CORECLR
//error code return?
void
@@ -1102,12 +1084,6 @@ NativeImageDumper::DumpNativeImage()
WriteFieldMDTokenImport( dwAssemblyDef, deps[i].dwAssemblyDef,
CORCOMPILE_DEPENDENCY, COR_INFO,
m_manifestImport );
-#ifndef FEATURE_CORECLR
- DisplayWriteFieldEnumerated( dependencyInfo, deps[i].dependencyInfo,
- CORCOMPILE_DEPENDENCY,
- s_CorCompileDependencyInfoFlags, W(", "),
- COR_INFO );
-#endif // !FEATURE_CORECLR
DisplayStartStructureWithOffset( signAssemblyDef,
DPtrToPreferredAddr(deps + i) + offsetof(CORCOMPILE_DEPENDENCY, signAssemblyDef),
sizeof(deps[i]).signAssemblyDef,
@@ -3749,9 +3725,6 @@ const NativeImageDumper::EnumMnemonics s_MSDFlags[] =
{
#define MSD_ENTRY(f) NativeImageDumper::EnumMnemonics(ModuleSecurityDescriptorFlags_ ## f, W(#f))
MSD_ENTRY(IsComputed),
-#ifdef FEATURE_APTCA
- MSD_ENTRY(IsAPTCA),
-#endif // FEATURE_APTCA
MSD_ENTRY(IsAllCritical),
MSD_ENTRY(IsAllTransparent),
MSD_ENTRY(IsTreatAsSafe),
@@ -4044,12 +4017,6 @@ void NativeImageDumper::DumpModule( PTR_Module module )
DisplayWriteFieldPointer( m_pNgenStats,
DataPtrToDisplay((TADDR)module->m_pNgenStats),
Module, MODULE );
-#if defined(FEATURE_MIXEDMODE)
- DisplayWriteFieldPointer( m_pThunkHeap,
- DataPtrToDisplay(dac_cast<TADDR>(module->m_pThunkHeap)),
- Module, MODULE );
- _ASSERTE(module->m_pThunkHeap == NULL);
-#endif
DisplayWriteFieldAddress(m_propertyNameSet,
DPtrToPreferredAddr(module->m_propertyNameSet),
@@ -4088,25 +4055,6 @@ void NativeImageDumper::DumpModule( PTR_Module module )
(int)(module->m_maxDynamicEntries
* sizeof(*(module->m_pDynamicStaticsInfo))));
-#ifdef FEATURE_CER
- DisplayWriteFieldInt( m_dwReliabilityContract,
- module->m_dwReliabilityContract, Module, MODULE );
-
- DisplayWriteFieldPointer( m_pCerPrepInfo,
- DataPtrToDisplay((TADDR)module->m_pCerPrepInfo),
- Module, MODULE );
- DisplayWriteFieldPointer( m_pCerCrst, DataPtrToDisplay((TADDR)module->m_pCerCrst),
- Module, MODULE );
- _ASSERTE(module->m_pCerPrepInfo == NULL && module->m_pCerCrst == NULL);
-
- IF_OPT_OR(MODULE, SLIM_MODULE_TBLS)
- {
- PTR_CerNgenRootTable table( TO_TADDR(module->m_pCerNgenRootTable) );
- DumpNgenRootTable( table, "m_pCerNgenRootTable",
- offsetof(Module, m_pCerNgenRootTable),
- fieldsize(Module, m_pCerNgenRootTable) );
- }
-#endif
_ASSERTE(module->m_debuggerSpecificData.m_pDynamicILCrst == NULL);
@@ -4154,87 +4102,6 @@ bool NativeImageDumper::isPrecode(TADDR maybePrecode)
return !!module->IsZappedPrecode(maybePrecode);
}
-#ifdef FEATURE_CER
-void NativeImageDumper::DumpNgenRootTable( PTR_CerNgenRootTable table,
- const char * name, unsigned offset,
- unsigned fieldSize )
-{
- if( table == NULL )
- {
- IF_OPT(MODULE)
- {
- m_display->WriteFieldPointer( name, (unsigned)DPtrToPreferredAddr(table),
- offset, fieldSize );
- }
- return;
- }
- IF_OPT(MODULE)
- {
- m_display->StartStructureWithOffset( name, offset, fieldSize,
- DPtrToPreferredAddr(table),
- sizeof(*table) );
- }
-
- DisplayWriteFieldPointer( m_cRoots, table->GetRootCount(),
- CerNgenRootTable, MODULE );
- DisplayWriteFieldAddress( m_pRestoreBitmap,
- DataPtrToDisplay((TADDR)table->GetRestoreBitmap()),
- table->SizeOfRestoreBitmap(),
- CerNgenRootTable, MODULE );
- DisplayWriteFieldInt( m_cSlots, table->m_cSlots, CerNgenRootTable,
- MODULE );
- DisplayStartArray( "Roots", NULL, SLIM_MODULE_TBLS );
-
- PTR_CerRoot roots(TO_TADDR(table->GetRoots()));
- for( unsigned i = 0; i < table->GetRootCount(); ++i )
- {
- PTR_CerRoot root = roots + i;
- DisplayStartStructure( "CerRoot", DPtrToPreferredAddr(root),
- sizeof(*root), SLIM_MODULE_TBLS );
- WriteFieldMethodDesc( m_pRootMD,
- PTR_MethodDesc(TO_TADDR(root->m_pRootMD)),
- CerRoot, SLIM_MODULE_TBLS );
-
- DisplayStartArray( "MethodContexts", NULL, SLIM_MODULE_TBLS );
-
- PTR_MethodContextElement ctx(TO_TADDR(root->m_pList));
- bool dumpedSentinel = false;
- while( !dumpedSentinel )
- {
- DisplayStartStructure( "MethodContext",
- DPtrToPreferredAddr(ctx),
- sizeof(*ctx), SLIM_MODULE_TBLS );
- if( ctx->m_pMethodDesc.IsNull() )
- dumpedSentinel = true;
- WriteFieldMethodDesc( m_pMethodDesc,
- ctx->m_pMethodDesc.GetValue(),
- MethodContextElement, SLIM_MODULE_TBLS );
-
- if (!ctx->m_pExactMT.IsNull())
- {
- WriteFieldMethodTable( m_pExactMT,
- ctx->m_pExactMT.GetValue(),
- MethodContextElement, SLIM_MODULE_TBLS );
- }
-
- DisplayEndStructure( SLIM_MODULE_TBLS ); //MethodContext
- ++ctx;
- }
-
- DisplayEndArray( "Total Contexts", SLIM_MODULE_TBLS); //MethodContexts
- DisplayEndStructure(SLIM_MODULE_TBLS); //CerRoot
- }
-
- DisplayEndArray( "Total Roots", SLIM_MODULE_TBLS ); //Roots
-
- /* REVISIT_TODO Wed 10/05/2005
- * m_cSlots seems to be set to something, but the number seems
- * completely useless. What is up with that?
- */
-
- DisplayEndStructure( MODULE ); //CERNgenRootTable
-}
-#endif // FEATURE_CER
void NativeImageDumper::IterateTypeDefToMTCallback( TADDR mtTarget,
TADDR flags,
@@ -5675,9 +5542,6 @@ NativeImageDumper::EnumMnemonics s_MTFlagsLow[] =
MTFLAG_ENTRY(GenericsMask_GenericInst),
MTFLAG_ENTRY(GenericsMask_SharedInst),
MTFLAG_ENTRY(GenericsMask_TypicalInst),
-#if defined(FEATURE_REMOTING)
- MTFLAG_ENTRY(ContextStatic),
-#endif
MTFLAG_ENTRY(HasRemotingVtsInfo),
MTFLAG_ENTRY(HasVariance),
MTFLAG_ENTRY(HasDefaultCtor),
@@ -5685,9 +5549,9 @@ NativeImageDumper::EnumMnemonics s_MTFlagsLow[] =
#if defined(FEATURE_HFA)
MTFLAG_ENTRY(IsHFA),
#endif // FEATURE_HFA
-#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
MTFLAG_ENTRY(IsRegStructPassed),
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
MTFLAG_ENTRY(IsByRefLike),
MTFLAG_ENTRY(UNUSED_ComponentSize_5),
MTFLAG_ENTRY(UNUSED_ComponentSize_6),
@@ -5918,9 +5782,6 @@ static NativeImageDumper::EnumMnemonics s_VMFlags[] =
VMF_ENTRY(FIXED_ADDRESS_VT_STATICS),
VMF_ENTRY(HASLAYOUT),
VMF_ENTRY(ISNESTED),
-#ifdef FEATURE_REMOTING
- VMF_ENTRY(CANNOT_BE_BLITTED_BY_OBJECT_CLONER),
-#endif
VMF_ENTRY(IS_EQUIVALENT_TYPE),
VMF_ENTRY(HASOVERLAYEDFIELDS),
@@ -7027,12 +6888,6 @@ void NativeImageDumper::DumpFieldDesc( PTR_FieldDesc fd, const char * name )
offsetof(FieldDesc, m_dword1),
fieldsize(FieldDesc, m_dword1),
fd->m_isThreadLocal );
-#if defined(FEATURE_REMOTING)
- m_display->WriteFieldFlag( "m_isContextLocal",
- offsetof(FieldDesc, m_dword1),
- fieldsize(FieldDesc, m_dword1),
- fd->m_isContextLocal );
-#endif
m_display->WriteFieldFlag( "m_isRVA", offsetof(FieldDesc, m_dword1),
fieldsize(FieldDesc, m_dword1),
fd->m_isRVA );
@@ -7064,30 +6919,6 @@ void NativeImageDumper::DumpFieldDesc( PTR_FieldDesc fd, const char * name )
#endif
DisplayEndStructure( ALWAYS ); //name
}
-#if defined(FEATURE_REMOTING)
-NativeImageDumper::EnumMnemonics s_XADOptFlags[] =
-{
-#define XAD_ENTRY(x) NativeImageDumper::EnumMnemonics( RemotableMethodInfo:: x, W(#x) )
- XAD_ENTRY(XAD_FLAGS_INITIALIZED),
- XAD_ENTRY(XAD_NOT_OPTIMIZABLE),
- XAD_ENTRY(XAD_BLITTABLE_ARGS),
- XAD_ENTRY(XAD_BLITTABLE_RET),
-
- //this is actually the OR of the three below this. It is a "flag" so
- //it gets cleared out.
- XAD_ENTRY(XAD_RET_GC_REF),
- XAD_ENTRY(XAD_RET_FLOAT),
- XAD_ENTRY(XAD_RET_DOUBLE),
-#ifdef FEATURE_HFA
- XAD_ENTRY(XAD_RET_HFA_TYPE),
-#endif
-
- XAD_ENTRY(XAD_METHOD_IS_VIRTUAL),
- XAD_ENTRY(XAD_ARGS_HAVE_A_FLOAT),
-
-#undef XAD_ENTRY
-};
-#endif
#ifdef _PREFAST_
#pragma warning(push)
@@ -7570,135 +7401,6 @@ NativeImageDumper::DumpMethodTable( PTR_MethodTable mt, const char * name,
}
#endif // FEATURE_COMINTEROP
-#if defined(FEATURE_REMOTING)
- //RemotingVtsInfo comes after the generic dictionaries. So if I
- //don't have extents, I can't print them.
- if(haveCompleteExtents &&
- mt->HasRemotingVtsInfo()
- && CHECK_OPT(METHODTABLES)
- )
- {
- _ASSERTE(clazz == GetClassFromMT(mt));
- /* REVISIT_TODO Tue 12/13/2005
- * Is this right? is m_wNumStaticFields actually the number of static
- * fields?
- */
- unsigned numFields = (unsigned)(CountFields(mt)
- - clazz->GetNumStaticFields());
- PTR_RemotingVtsInfo vts = *mt->GetRemotingVtsInfoPtr();
- m_display->StartStructureWithOffset( "OptionalMember_RemotingVtsInfo",
- mt->GetOffsetOfOptionalMember(MethodTable::OptionalMember_RemotingVtsInfo),
- sizeof(void*),
- DPtrToPreferredAddr(vts),
- RemotingVtsInfo::GetSize(numFields)
- );
-
- DisplayStartArrayWithOffset( m_pCallbacks, W("%-30s: %s"),
- RemotingVtsInfo, ALWAYS );
- for( int i = 0; i < _countof(vts->m_pCallbacks); ++i )
- {
- PTR_MethodDesc md( vts->m_pCallbacks[i].GetValue() );
- DisplayStartElement( "Callback", ALWAYS );
- DisplayWriteElementString( "CallbackType", s_VTSCallbackNames[i],
- ALWAYS );
- if (CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(md)))
- {
- DoWriteFieldMethodDesc( "MethodDesc", UINT_MAX, UINT_MAX, md );
- }
- else
- {
- WriteElementMethodDesc( "MethodDesc", md );
- }
- DisplayEndElement( ALWAYS ); //Callback
- }
- DisplayEndArray( NULL, ALWAYS ); //m_pCallbacks
-#ifdef _DEBUG
- DisplayWriteFieldInt( m_dwNumFields, vts->m_dwNumFields,
- RemotingVtsInfo, ALWAYS );
-#endif
- /* REVISIT_TODO Tue 12/13/2005
- * Is there any reason to dump this map?
- */
- m_display->WriteFieldEmpty("m_rFieldTypes",
- offsetof(RemotingVtsInfo, m_rFieldTypes),
- RemotingVtsInfo::GetSize(numFields)
- - offsetof(RemotingVtsInfo, m_rFieldTypes) );
- DisplayEndStructure( ALWAYS ); //OptionalMember_RemotingVtsInfo
- }
-
- //RemotableMethodInfo comes after the generic dictionaries. So if I
- //don't have extents, I can't print them.
- if(haveCompleteExtents &&
- mt->HasRemotableMethodInfo() &&
- CHECK_OPT(METHODTABLES)
- )
- {
- PTR_CrossDomainOptimizationInfo cdOpt = *mt->GetRemotableMethodInfoPtr();
- if( cdOpt == NULL )
- {
- _ASSERTE(mt->GetNumVtableSlots() == 0 );
- m_display->WriteElementPointer("OptionalMember_RemotableMethodInfo",
- NULL);
- }
- else
- {
- _ASSERTE(mt->GetNumVtableSlots() > 0 );
- /* REVISIT_TODO Tue 12/13/2005
- * One liner copied from CrossDomainCalls.cpp
- */
- unsigned size = sizeof(RemotableMethodInfo) * mt->GetNumVtableSlots();
- //one remotable method info for each method.
- m_display->StartStructureWithOffset( "OptionalMember_RemotableMethodInfo",
- mt->GetOffsetOfOptionalMember(MethodTable::OptionalMember_RemotableMethodInfo),
- sizeof(void*),
- DPtrToPreferredAddr(cdOpt),
- size );
- m_display->StartArrayWithOffset( "m_rmi",
- offsetof(CrossDomainOptimizationInfo,
- m_rmi),
- mt->GetNumVtableSlots()
- * sizeof(RemotableMethodInfo), NULL );
- PTR_RemotableMethodInfo rmi( PTR_HOST_MEMBER_TADDR(CrossDomainOptimizationInfo, cdOpt, m_rmi) );
- for( unsigned i = 0; i < mt->GetNumVtableSlots(); ++i )
- {
- PTR_RemotableMethodInfo current = rmi + i;
- DisplayStartStructure( "RemotableMethodInfo",
- DPtrToPreferredAddr(current),
- sizeof(*current), ALWAYS );
- DisplayWriteFieldEnumerated( m_OptFlags, current->m_OptFlags,
- RemotableMethodInfo, s_XADOptFlags,
- W(", "), ALWAYS );
- DisplayEndStructure( ALWAYS ); //RemotableMethodInfo
- }
- DisplayEndArray( "Total RemotableMethodInfos", ALWAYS ); //m_rmi
- DisplayEndStructure( ALWAYS ); // OptionalMember_RemotableMethodInfo
- }
- }
-
- //ContextStatics comes after the generic dictionaries. So if I
- //don't have extents, I can't print them.
- if(haveCompleteExtents &&
- mt->HasContextStatics() &&
- CHECK_OPT(METHODTABLES)
- )
- {
- PTR_ContextStaticsBucket statics =
- *(mt->GetContextStaticsBucketPtr());
- m_display->StartStructureWithOffset( "OptionalMember_ContextStatics",
- mt->GetOffsetOfOptionalMember(MethodTable::OptionalMember_ContextStatics),
- sizeof(void*),
- DPtrToPreferredAddr(statics),
- sizeof(*statics) );
-
-#define HANDLE_FIELD(field) \
- DisplayWriteFieldInt( field, statics->field, \
- ContextStaticsBucket, ALWAYS )
- HANDLE_FIELD(m_dwContextStaticsOffset);
- HANDLE_FIELD(m_wContextStaticsSize);
-#undef HANDLE_FIELD
- DisplayEndStructure( ALWAYS ); //OptionalMember_ContextStatics
- }
-#endif
DisplayEndStructure( METHODTABLES ); //MethodTable
} // NativeImageDumper::DumpMethodTable
#ifdef _PREFAST_
@@ -9039,14 +8741,6 @@ NativeImageDumper::DumpEEClassForMethodTable( PTR_MethodTable mt )
DisplayWriteFieldInt( m_cbModuleDynamicID, pClassOptional->m_cbModuleDynamicID,
EEClassOptionalFields, EECLASSES );
-#ifdef FEATURE_CER
- /* REVISIT_TODO Fri 10/14/2005
- * Use the macros from ConstrainedExecutionRegion.cpp on this?
- */
- DisplayWriteFieldUInt( m_dwReliabilityContract,
- clazz->GetReliabilityContract(),
- EEClassOptionalFields, EECLASSES );
-#endif
DisplayWriteFieldEnumerated( m_SecProps, clazz->GetSecurityProperties()->dwFlags,
EEClassOptionalFields, s_SecurityProperties, W("|"),
diff --git a/src/debug/daccess/request.cpp b/src/debug/daccess/request.cpp
index 35ab5a0814..78ac831cd9 100644
--- a/src/debug/daccess/request.cpp
+++ b/src/debug/daccess/request.cpp
@@ -13,8 +13,8 @@
#include "stdafx.h"
#include <win32threadpool.h>
-#include <gceewks.cpp>
-#include <handletablepriv.h>
+// TODO(Local GC) - The DAC should not include GC headers
+#include <../../gc/handletablepriv.h>
#include "typestring.h"
#include <gccover.h>
#include <virtualcallstub.h>
@@ -31,7 +31,7 @@
#include <exstatecommon.h>
#include "rejit.h"
-
+#include "request_common.h"
// GC headers define these to EE-specific stuff that we don't want.
#undef EnterCriticalSection
@@ -264,7 +264,6 @@ VOID GetJITMethodInfo (EECodeInfo * pCodeInfo, JITTypes *pJITType, CLRDATA_ADDRE
*pGCInfo = (CLRDATA_ADDRESS)PTR_TO_TADDR(pCodeInfo->GetGCInfo());
}
-
HRESULT
ClrDataAccess::GetWorkRequestData(CLRDATA_ADDRESS addr, struct DacpWorkRequestData *workRequestData)
{
@@ -737,10 +736,12 @@ ClrDataAccess::GetHeapAllocData(unsigned int count, struct DacpGenerationAllocDa
if (data && count >= 1)
{
- for (int i=0;i<NUMBERGENERATIONS;i++)
+ DPTR(dac_generation) table = g_gcDacGlobals->generation_table;
+ for (unsigned int i=0; i < *g_gcDacGlobals->max_gen + 2; i++)
{
- data[0].allocData[i].allocBytes = (CLRDATA_ADDRESS)(ULONG_PTR) WKS::generation_table[i].allocation_context.alloc_bytes;
- data[0].allocData[i].allocBytesLoh = (CLRDATA_ADDRESS)(ULONG_PTR) WKS::generation_table[i].allocation_context.alloc_bytes_loh;
+ dac_generation entry = *GenerationTableIndex(table, i);
+ data[0].allocData[i].allocBytes = (CLRDATA_ADDRESS)(ULONG_PTR) entry.allocation_context.alloc_bytes;
+ data[0].allocData[i].allocBytesLoh = (CLRDATA_ADDRESS)(ULONG_PTR) entry.allocation_context.alloc_bytes_loh;
}
}
}
@@ -1580,9 +1581,6 @@ ClrDataAccess::GetModuleData(CLRDATA_ADDRESS addr, struct DacpModuleData *Module
ModuleData->FileReferencesMap = PTR_CDADDR(pModule->m_FileReferencesMap.pTable);
ModuleData->ManifestModuleReferencesMap = PTR_CDADDR(pModule->m_ManifestModuleReferencesMap.pTable);
-#ifdef FEATURE_MIXEDMODE // IJW
- ModuleData->pThunkHeap = HOST_CDADDR(pModule->m_pThunkHeap);
-#endif // FEATURE_MIXEDMODE // IJW
}
EX_CATCH
{
@@ -1804,11 +1802,7 @@ ClrDataAccess::GetFieldDescData(CLRDATA_ADDRESS addr, struct DacpFieldDescData *
FieldDescData->MTOfEnclosingClass = HOST_CDADDR(pFieldDesc->GetApproxEnclosingMethodTable());
FieldDescData->dwOffset = pFieldDesc->GetOffset();
FieldDescData->bIsThreadLocal = pFieldDesc->IsThreadStatic();
-#ifdef FEATURE_REMOTING
- FieldDescData->bIsContextLocal = pFieldDesc->IsContextStatic();;
-#else
FieldDescData->bIsContextLocal = FALSE;
-#endif
FieldDescData->bIsStatic = pFieldDesc->IsStatic();
FieldDescData->NextField = HOST_CDADDR(PTR_FieldDesc(PTR_HOST_TO_TADDR(pFieldDesc) + sizeof(FieldDesc)));
@@ -1838,16 +1832,8 @@ ClrDataAccess::GetMethodTableFieldData(CLRDATA_ADDRESS mt, struct DacpMethodTabl
data->FirstField = PTR_TO_TADDR(pMT->GetClass()->GetFieldDescList());
-#ifdef FEATURE_REMOTING
- BOOL hasContextStatics = pMT->HasContextStatics();
-
- data->wContextStaticsSize = (hasContextStatics) ? pMT->GetContextStaticsSize() : 0;
- _ASSERTE(!hasContextStatics || FitsIn<WORD>(pMT->GetContextStaticsOffset()));
- data->wContextStaticOffset = (hasContextStatics) ? static_cast<WORD>(pMT->GetContextStaticsOffset()) : 0;
-#else
data->wContextStaticsSize = 0;
data->wContextStaticOffset = 0;
-#endif
}
SOSDacLeave();
@@ -2295,10 +2281,6 @@ ClrDataAccess::GetFailedAssemblyData(CLRDATA_ADDRESS assembly, unsigned int *pCo
}
else
{
-#ifdef FEATURE_FUSION
- if (pContext)
- *pContext = pAssembly->context;
-#endif
if (pResult)
*pResult = pAssembly->error;
}
@@ -2679,10 +2661,6 @@ ClrDataAccess::GetAssemblyData(CLRDATA_ADDRESS cdBaseDomainPtr, CLRDATA_ADDRESS
if (pAssembly->GetManifestFile())
{
-#ifdef FEATURE_FUSION
- assemblyData->LoadContext = pAssembly->GetManifestFile()->GetLoadContext();
- assemblyData->dwLocationFlags = pAssembly->GetManifestFile()->GetLocationFlags();
-#endif
}
@@ -2833,43 +2811,34 @@ ClrDataAccess::GetGCHeapStaticData(struct DacpGcHeapDetails *detailsData)
detailsData->lowest_address = PTR_CDADDR(g_lowest_address);
detailsData->highest_address = PTR_CDADDR(g_highest_address);
detailsData->card_table = PTR_CDADDR(g_card_table);
-
detailsData->heapAddr = NULL;
+ detailsData->alloc_allocated = (CLRDATA_ADDRESS)*g_gcDacGlobals->alloc_allocated;
+ detailsData->ephemeral_heap_segment = (CLRDATA_ADDRESS)*g_gcDacGlobals->ephemeral_heap_segment;
+ detailsData->mark_array = (CLRDATA_ADDRESS)*g_gcDacGlobals->mark_array;
+ detailsData->current_c_gc_state = (CLRDATA_ADDRESS)*g_gcDacGlobals->current_c_gc_state;
+ detailsData->next_sweep_obj = (CLRDATA_ADDRESS)*g_gcDacGlobals->next_sweep_obj;
+ detailsData->saved_sweep_ephemeral_seg = (CLRDATA_ADDRESS)*g_gcDacGlobals->saved_sweep_ephemeral_seg;
+ detailsData->saved_sweep_ephemeral_start = (CLRDATA_ADDRESS)*g_gcDacGlobals->saved_sweep_ephemeral_start;
+ detailsData->background_saved_lowest_address = (CLRDATA_ADDRESS)*g_gcDacGlobals->background_saved_lowest_address;
+ detailsData->background_saved_highest_address = (CLRDATA_ADDRESS)*g_gcDacGlobals->background_saved_highest_address;
- detailsData->alloc_allocated = PTR_CDADDR(WKS::gc_heap::alloc_allocated);
- detailsData->ephemeral_heap_segment = PTR_CDADDR(WKS::gc_heap::ephemeral_heap_segment);
+ for (unsigned int i=0; i < *g_gcDacGlobals->max_gen + 2; i++)
+ {
+ DPTR(dac_generation) generation = GenerationTableIndex(g_gcDacGlobals->generation_table, i);
+ detailsData->generation_table[i].start_segment = (CLRDATA_ADDRESS) dac_cast<TADDR>(generation->start_segment);
-#ifdef BACKGROUND_GC
- detailsData->mark_array = PTR_CDADDR(WKS::gc_heap::mark_array);
- detailsData->current_c_gc_state = (CLRDATA_ADDRESS)(ULONG_PTR)WKS::gc_heap::current_c_gc_state;
- detailsData->next_sweep_obj = PTR_CDADDR(WKS::gc_heap::next_sweep_obj);
- detailsData->saved_sweep_ephemeral_seg = PTR_CDADDR(WKS::gc_heap::saved_sweep_ephemeral_seg);
- detailsData->saved_sweep_ephemeral_start = PTR_CDADDR(WKS::gc_heap::saved_sweep_ephemeral_start);
- detailsData->background_saved_lowest_address = PTR_CDADDR(WKS::gc_heap::background_saved_lowest_address);
- detailsData->background_saved_highest_address = PTR_CDADDR(WKS::gc_heap::background_saved_highest_address);
-#endif //BACKGROUND_GC
+ detailsData->generation_table[i].allocation_start = (CLRDATA_ADDRESS) generation->allocation_start;
- for (int i=0;i<NUMBERGENERATIONS;i++)
- {
- detailsData->generation_table[i].start_segment = (CLRDATA_ADDRESS)dac_cast<TADDR>(WKS::generation_table[i].start_segment);
- detailsData->generation_table[i].allocation_start = (CLRDATA_ADDRESS)(ULONG_PTR) WKS::generation_table[i].allocation_start;
- detailsData->generation_table[i].allocContextPtr = (CLRDATA_ADDRESS)(ULONG_PTR) WKS::generation_table[i].allocation_context.alloc_ptr;
- detailsData->generation_table[i].allocContextLimit = (CLRDATA_ADDRESS)(ULONG_PTR) WKS::generation_table[i].allocation_context.alloc_limit;
+ DPTR(gc_alloc_context) alloc_context = dac_cast<TADDR>(generation) + offsetof(dac_generation, allocation_context);
+ detailsData->generation_table[i].allocContextPtr = (CLRDATA_ADDRESS)alloc_context->alloc_ptr;
+ detailsData->generation_table[i].allocContextLimit = (CLRDATA_ADDRESS)alloc_context->alloc_limit;
}
- TADDR pFillPointerArray = TO_TADDR(WKS::gc_heap::finalize_queue.GetAddr()) + offsetof(WKS::CFinalize,m_FillPointers);
- for(int i=0;i<(NUMBERGENERATIONS+WKS::CFinalize::ExtraSegCount);i++)
+ DPTR(dac_finalize_queue) fq = Dereference(g_gcDacGlobals->finalize_queue);
+ DPTR(uint8_t*) fillPointersTable = dac_cast<TADDR>(fq) + offsetof(dac_finalize_queue, m_FillPointers);
+ for (unsigned int i = 0; i<(*g_gcDacGlobals->max_gen + 2 + dac_finalize_queue::ExtraSegCount); i++)
{
- ULONG32 returned = 0;
- size_t pValue;
- hr = m_pTarget->ReadVirtual(pFillPointerArray+(i*sizeof(size_t)), (PBYTE)&pValue, sizeof(size_t), &returned);
- if (SUCCEEDED(hr))
- {
- if (returned == sizeof(size_t))
- detailsData->finalization_fill_pointers[i] = (CLRDATA_ADDRESS) pValue;
- else
- hr = E_FAIL;
- }
+ detailsData->finalization_fill_pointers[i] = (CLRDATA_ADDRESS)*TableIndex(fillPointersTable, i, sizeof(uint8_t*));
}
SOSDacLeave();
@@ -2894,7 +2863,7 @@ ClrDataAccess::GetHeapSegmentData(CLRDATA_ADDRESS seg, struct DacpHeapSegmentDat
}
else
{
- WKS::heap_segment *pSegment = __DPtr<WKS::heap_segment>(TO_TADDR(seg));
+ dac_heap_segment *pSegment = __DPtr<dac_heap_segment>(TO_TADDR(seg));
if (!pSegment)
{
hr = E_INVALIDARG;
@@ -2960,31 +2929,33 @@ ClrDataAccess::GetGCHeapData(struct DacpGcHeapData *gcheapData)
SOSDacEnter();
- // for server GC-capable builds only, we need to check and see if IGCHeap::gcHeapType
+ // we need to check and see if g_heap_type
// is GC_HEAP_INVALID, in which case we fail.
- // IGCHeap::gcHeapType doesn't exist on non-server-GC capable builds.
-#ifdef FEATURE_SVR_GC
- ULONG32 gcHeapValue = IGCHeap::gcHeapType;
+ ULONG32 gcHeapValue = g_heap_type;
// GC_HEAP_TYPE has three possible values:
// GC_HEAP_INVALID = 0,
// GC_HEAP_WKS = 1,
// GC_HEAP_SVR = 2
// If we get something other than that, we probably read the wrong location.
- _ASSERTE(gcHeapValue >= IGCHeap::GC_HEAP_INVALID && gcHeapValue <= IGCHeap::GC_HEAP_SVR);
+ _ASSERTE(gcHeapValue >= GC_HEAP_INVALID && gcHeapValue <= GC_HEAP_SVR);
- // we have GC_HEAP_INVALID if gcHeapValue == 0, so we're done
- if (gcHeapValue == IGCHeap::GC_HEAP_INVALID)
+ // we have GC_HEAP_INVALID if gcHeapValue == 0, so we're done - we haven't
+ // initialized the heap yet.
+ if (gcHeapValue == GC_HEAP_INVALID)
{
hr = E_FAIL;
goto cleanup;
}
-#endif
// Now we can get other important information about the heap
- gcheapData->g_max_generation = GCHeapUtilities::GetMaxGeneration();
+ // We can use GCHeapUtilities::IsServerHeap here because we have already validated
+ // that the heap is in a valid state. We couldn't use it above, because IsServerHeap
+ // asserts if the heap type is GC_HEAP_INVALID.
+ gcheapData->g_max_generation = *g_gcDacGlobals->max_gen;
gcheapData->bServerMode = GCHeapUtilities::IsServerHeap();
- gcheapData->bGcStructuresValid = GCScan::GetGcRuntimeStructuresValid();
+ gcheapData->bGcStructuresValid = *g_gcDacGlobals->gc_structures_invalid_cnt == 0;
+
if (GCHeapUtilities::IsServerHeap())
{
#if !defined (FEATURE_SVR_GC)
@@ -2999,10 +2970,8 @@ ClrDataAccess::GetGCHeapData(struct DacpGcHeapData *gcheapData)
gcheapData->HeapCount = 1;
}
-#ifdef FEATURE_SVR_GC
cleanup:
;
-#endif
SOSDacLeave();
return hr;
@@ -3020,7 +2989,7 @@ ClrDataAccess::GetOOMStaticData(struct DacpOomData *oomData)
if (!GCHeapUtilities::IsServerHeap())
{
- oom_history* pOOMInfo = &(WKS::gc_heap::oom_info);
+ oom_history* pOOMInfo = g_gcDacGlobals->oom_info;
oomData->reason = pOOMInfo->reason;
oomData->alloc_size = pOOMInfo->alloc_size;
oomData->available_pagefile_mb = pOOMInfo->available_pagefile_mb;
@@ -3074,7 +3043,7 @@ ClrDataAccess::GetGCGlobalMechanisms(size_t* globalMechanisms)
for (int i = 0; i < MAX_GLOBAL_GC_MECHANISMS_COUNT; i++)
{
- globalMechanisms[i] = gc_global_mechanisms[i];
+ globalMechanisms[i] = g_gcDacGlobals->gc_global_mechanisms[i];
}
SOSDacLeave();
@@ -3091,19 +3060,25 @@ ClrDataAccess::GetGCInterestingInfoStaticData(struct DacpGCInterestingInfoData *
if (data == NULL)
return E_INVALIDARG;
+ static_assert_no_msg(DAC_NUMBERGENERATIONS == NUMBERGENERATIONS);
+ static_assert_no_msg(DAC_NUM_GC_DATA_POINTS == NUM_GC_DATA_POINTS);
+ static_assert_no_msg(DAC_MAX_COMPACT_REASONS_COUNT == MAX_COMPACT_REASONS_COUNT);
+ static_assert_no_msg(DAC_MAX_EXPAND_MECHANISMS_COUNT == MAX_EXPAND_MECHANISMS_COUNT);
+ static_assert_no_msg(DAC_MAX_GC_MECHANISM_BITS_COUNT == MAX_GC_MECHANISM_BITS_COUNT);
+
SOSDacEnter();
memset(data, 0, sizeof(DacpGCInterestingInfoData));
- if (!GCHeapUtilities::IsServerHeap())
+ if (g_heap_type != GC_HEAP_SVR)
{
for (int i = 0; i < NUM_GC_DATA_POINTS; i++)
- data->interestingDataPoints[i] = WKS::interesting_data_per_heap[i];
+ data->interestingDataPoints[i] = g_gcDacGlobals->interesting_data_per_heap[i];
for (int i = 0; i < MAX_COMPACT_REASONS_COUNT; i++)
- data->compactReasons[i] = WKS::compact_reasons_per_heap[i];
+ data->compactReasons[i] = g_gcDacGlobals->compact_reasons_per_heap[i];
for (int i = 0; i < MAX_EXPAND_MECHANISMS_COUNT; i++)
- data->expandMechanisms[i] = WKS::expand_mechanisms_per_heap[i];
+ data->expandMechanisms[i] = g_gcDacGlobals->expand_mechanisms_per_heap[i];
for (int i = 0; i < MAX_GC_MECHANISM_BITS_COUNT; i++)
- data->bitMechanisms[i] = WKS::interesting_mechanism_bits_per_heap[i];
+ data->bitMechanisms[i] = g_gcDacGlobals->interesting_mechanism_bits_per_heap[i];
}
else
{
@@ -3176,9 +3151,9 @@ ClrDataAccess::GetHeapAnalyzeStaticData(struct DacpGcHeapAnalyzeData *analyzeDat
SOSDacEnter();
- analyzeData->internal_root_array = PTR_CDADDR(WKS::gc_heap::internal_root_array);
- analyzeData->internal_root_array_index = (size_t) WKS::gc_heap::internal_root_array_index;
- analyzeData->heap_analyze_success = (BOOL) WKS::gc_heap::heap_analyze_success;
+ analyzeData->internal_root_array = dac_cast<TADDR>(g_gcDacGlobals->internal_root_array);
+ analyzeData->internal_root_array_index = *g_gcDacGlobals->internal_root_array_index;
+ analyzeData->heap_analyze_success = *g_gcDacGlobals->heap_analyze_success;
SOSDacLeave();
return hr;
@@ -3849,25 +3824,30 @@ void
ClrDataAccess::EnumWksGlobalMemoryRegions(CLRDataEnumMemoryFlags flags)
{
SUPPORTS_DAC;
- WKS::gc_heap::ephemeral_heap_segment.EnumMem();
- WKS::gc_heap::alloc_allocated.EnumMem();
- WKS::gc_heap::finalize_queue.EnumMem();
- WKS::generation_table.EnumMem();
- WKS::gc_heap::oom_info.EnumMem();
- if (WKS::generation_table.IsValid())
+ Dereference(g_gcDacGlobals->ephemeral_heap_segment).EnumMem();
+ g_gcDacGlobals->alloc_allocated.EnumMem();
+ g_gcDacGlobals->gc_structures_invalid_cnt.EnumMem();
+ Dereference(g_gcDacGlobals->finalize_queue).EnumMem();
+
+ // Enumerate the entire generation table, which has variable size
+ size_t gen_table_size = g_gcDacGlobals->generation_size * (*g_gcDacGlobals->max_gen + 1);
+ DacEnumMemoryRegion(dac_cast<TADDR>(g_gcDacGlobals->generation_table), gen_table_size);
+
+ if (g_gcDacGlobals->generation_table.IsValid())
{
// enumerating the generations from max (which is normally gen2) to max+1 gives you
// the segment list for all the normal segements plus the large heap segment (max+1)
// this is the convention in the GC so it is repeated here
- for (ULONG i = GCHeapUtilities::GetMaxGeneration(); i <= GCHeapUtilities::GetMaxGeneration()+1; i++)
+ for (ULONG i = *g_gcDacGlobals->max_gen; i <= *g_gcDacGlobals->max_gen +1; i++)
{
- __DPtr<WKS::heap_segment> seg = dac_cast<TADDR>(WKS::generation_table[i].start_segment);
+ dac_generation *gen = GenerationTableIndex(g_gcDacGlobals->generation_table, i);
+ __DPtr<dac_heap_segment> seg = dac_cast<TADDR>(gen->start_segment);
while (seg)
{
- DacEnumMemoryRegion(dac_cast<TADDR>(seg), sizeof(WKS::heap_segment));
+ DacEnumMemoryRegion(dac_cast<TADDR>(seg), sizeof(dac_heap_segment));
- seg = __DPtr<WKS::heap_segment>(dac_cast<TADDR>(seg->next));
+ seg = seg->next;
}
}
}
@@ -3910,7 +3890,7 @@ HRESULT ClrDataAccess::GetClrWatsonBucketsWorker(Thread * pThread, GenericModeBl
if (ohThrowable != NULL)
{
// Get the object from handle and check if the throwable is preallocated or not
- OBJECTREF oThrowable = ObjectFromHandle(ohThrowable);
+ OBJECTREF oThrowable = ::HndFetchHandle(ohThrowable);
if (oThrowable != NULL)
{
// Does the throwable have buckets?
@@ -4204,7 +4184,7 @@ HRESULT ClrDataAccess::GetCCWData(CLRDATA_ADDRESS ccw, struct DacpCCWData *ccwDa
ccwData->isAggregated = pCCW->GetSimpleWrapper()->IsAggregated();
if (pCCW->GetObjectHandle() != NULL)
- ccwData->managedObject = PTR_CDADDR(ObjectFromHandle(pCCW->GetObjectHandle()));
+ ccwData->managedObject = PTR_CDADDR(::HndFetchHandle(pCCW->GetObjectHandle()));
// count the number of COM vtables
ccwData->interfaceCount = 0;
@@ -4378,4 +4358,4 @@ HRESULT ClrDataAccess::GetClrNotification(CLRDATA_ADDRESS arguments[], int count
SOSDacLeave();
return hr;;
-} \ No newline at end of file
+}
diff --git a/src/debug/daccess/request_common.h b/src/debug/daccess/request_common.h
new file mode 100644
index 0000000000..aef46b14ff
--- /dev/null
+++ b/src/debug/daccess/request_common.h
@@ -0,0 +1,58 @@
+// 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.
+
+// This file contains functions used by both request.cpp and request_svr.cpp
+// to communicate with the debuggee's GC.
+
+#ifndef _REQUEST_COMMON_H_
+#define _REQUEST_COMMON_H_
+
+// Indexes into an array of elements of type T, where the size of type
+// T is not (or may not be) known at compile-time.
+// Returns a DPTR to the requested element (the element at the given index).
+template<typename T>
+DPTR(T) TableIndex(DPTR(T) base, size_t index, size_t t_size)
+{
+ TADDR base_addr = base.GetAddr();
+ TADDR element_addr = DacTAddrOffset(base_addr, index, t_size);
+ return __DPtr<T>(element_addr);
+}
+
+// Dereferences a DPTR(T*), yielding a DPTR(T).
+template<typename T>
+DPTR(T) Dereference(DPTR(T*) ptr)
+{
+ TADDR ptr_base = (TADDR)*ptr;
+ return __DPtr<T>(ptr_base);
+}
+
+// Indexes into a given generation table, returning a DPTR to the
+// requested element (the element at the given index) of the table.
+inline DPTR(dac_generation)
+GenerationTableIndex(DPTR(dac_generation) base, size_t index)
+{
+ return TableIndex(base, index, g_gcDacGlobals->generation_size);
+}
+
+// Indexes into a heap's generation table, given the heap instance
+// and the desired index. Returns a DPTR to the requested element.
+inline DPTR(dac_generation)
+ServerGenerationTableIndex(DPTR(dac_gc_heap) heap, size_t index)
+{
+ TADDR base_addr = dac_cast<TADDR>(heap) + offsetof(dac_gc_heap, generation_table);
+ DPTR(dac_generation) base = __DPtr<dac_generation>(base_addr);
+ return TableIndex(base, index, g_gcDacGlobals->generation_size);
+}
+
+// Indexes into the global heap table, returning a DPTR to the requested
+// heap instance.
+inline DPTR(dac_gc_heap)
+HeapTableIndex(DPTR(dac_gc_heap**) heaps, size_t index)
+{
+ DPTR(dac_gc_heap*) heap_table = Dereference(heaps);
+ DPTR(dac_gc_heap*) ptr = TableIndex(heap_table, index, sizeof(dac_gc_heap*));
+ return Dereference(ptr);
+}
+
+#endif // _REQUEST_COMMON_H_
diff --git a/src/debug/daccess/request_svr.cpp b/src/debug/daccess/request_svr.cpp
index 1fe20e2b60..6a1de35ff9 100644
--- a/src/debug/daccess/request_svr.cpp
+++ b/src/debug/daccess/request_svr.cpp
@@ -18,13 +18,11 @@
#include <sigformat.h>
#include <win32threadpool.h>
-
-#include <gceesvr.cpp>
-
+#include "request_common.h"
int GCHeapCount()
{
- return SVR::gc_heap::n_heaps;
+ return *g_gcDacGlobals->n_heaps;
}
HRESULT GetServerHeapData(CLRDATA_ADDRESS addr, DacpHeapSegmentData *pSegment)
@@ -37,8 +35,7 @@ HRESULT GetServerHeapData(CLRDATA_ADDRESS addr, DacpHeapSegmentData *pSegment)
}
// marshal the segment from target to host
- SVR::heap_segment *pHeapSegment =
- __DPtr<SVR::heap_segment>(TO_TADDR(addr));
+ dac_heap_segment *pHeapSegment = __DPtr<dac_heap_segment>(TO_TADDR(addr));
// initialize fields by copying from the marshaled segment (note that these are all target addresses)
pSegment->segmentAddr = addr;
@@ -48,7 +45,7 @@ HRESULT GetServerHeapData(CLRDATA_ADDRESS addr, DacpHeapSegmentData *pSegment)
pSegment->used = (CLRDATA_ADDRESS)(ULONG_PTR) pHeapSegment->used;
pSegment->mem = (CLRDATA_ADDRESS)(ULONG_PTR) (pHeapSegment->mem);
pSegment->next = (CLRDATA_ADDRESS)dac_cast<TADDR>(pHeapSegment->next);
- pSegment->gc_heap = (CLRDATA_ADDRESS)(ULONG_PTR) pHeapSegment->heap;
+ pSegment->gc_heap = (CLRDATA_ADDRESS)pHeapSegment->heap;
return S_OK;
}
@@ -64,42 +61,20 @@ HRESULT GetServerHeaps(CLRDATA_ADDRESS pGCHeaps[], ICorDebugDataTarget * pTarget
// a DAC global (__GlobalPtr). The __GlobalPtr<...>::GetAddr() function gets the starting address of that global, but
// be sure to note this is a target address. We'll use this as our source for getting our local list of
// heap addresses.
- TADDR ptr = SVR::gc_heap::g_heaps.GetAddr();
- ULONG32 bytesRead = 0;
-
- for (int i=0;i<GCHeapCount();i++)
+ for (int i = 0; i < GCHeapCount(); i++)
{
-
- LPVOID pGCHeapAddr;
-
- // read the i-th element of g_heaps into pGCHeapAddr
- // @todo Microsoft: Again, if we capture the HRESULT from ReadVirtual, we can print a more explanatory
- // failure message.
- if (pTarget->ReadVirtual(ptr + i*sizeof(TADDR),
- (PBYTE) &pGCHeapAddr, sizeof(TADDR),
- &bytesRead) != S_OK)
- {
- return E_FAIL;
- }
- if (bytesRead != sizeof(LPVOID))
- {
- return E_FAIL;
- }
-
- // store the heap's starting address in our array.
- pGCHeaps[i] = (CLRDATA_ADDRESS)(ULONG_PTR) pGCHeapAddr;
+ pGCHeaps[i] = (CLRDATA_ADDRESS)HeapTableIndex(g_gcDacGlobals->g_heaps, i).GetAddr();
}
+
return S_OK;
}
#define PTR_CDADDR(ptr) TO_CDADDR(PTR_TO_TADDR(ptr))
#define HOST_CDADDR(host) TO_CDADDR(PTR_HOST_TO_TADDR(host))
-typedef DPTR(class SVR::gc_heap) PTR_SVR_gc_heap;
-
HRESULT ClrDataAccess::GetServerAllocData(unsigned int count, struct DacpGenerationAllocData *data, unsigned int *pNeeded)
{
- unsigned int heaps = (unsigned int)SVR::gc_heap::n_heaps;
+ unsigned int heaps = (unsigned int)GCHeapCount();
if (pNeeded)
*pNeeded = heaps;
@@ -108,13 +83,14 @@ HRESULT ClrDataAccess::GetServerAllocData(unsigned int count, struct DacpGenerat
if (count > heaps)
count = heaps;
- for (int n=0;n<SVR::gc_heap::n_heaps;n++)
+ for (unsigned int n=0; n < heaps; n++)
{
- PTR_SVR_gc_heap pHeap = PTR_SVR_gc_heap(SVR::gc_heap::g_heaps[n]);
+ DPTR(dac_gc_heap) pHeap = HeapTableIndex(g_gcDacGlobals->g_heaps, n);
for (int i=0;i<NUMBERGENERATIONS;i++)
{
- data[n].allocData[i].allocBytes = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->generation_table[i].allocation_context.alloc_bytes;
- data[n].allocData[i].allocBytesLoh = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->generation_table[i].allocation_context.alloc_bytes_loh;
+ dac_generation generation = *ServerGenerationTableIndex(pHeap, i);
+ data[n].allocData[i].allocBytes = (CLRDATA_ADDRESS)(ULONG_PTR) generation.allocation_context.alloc_bytes;
+ data[n].allocData[i].allocBytesLoh = (CLRDATA_ADDRESS)(ULONG_PTR) generation.allocation_context.alloc_bytes_loh;
}
}
}
@@ -130,7 +106,7 @@ HRESULT ClrDataAccess::ServerGCHeapDetails(CLRDATA_ADDRESS heapAddr, DacpGcHeapD
return E_INVALIDARG;
}
- SVR::gc_heap *pHeap = PTR_SVR_gc_heap(TO_TADDR(heapAddr));
+ DPTR(dac_gc_heap) pHeap = __DPtr<dac_gc_heap>(TO_TADDR(heapAddr));
int i;
//get global information first
@@ -142,35 +118,25 @@ HRESULT ClrDataAccess::ServerGCHeapDetails(CLRDATA_ADDRESS heapAddr, DacpGcHeapD
// now get information specific to this heap (server mode gives us several heaps; we're getting
// information about only one of them.
- detailsData->alloc_allocated = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->alloc_allocated;
- detailsData->ephemeral_heap_segment = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->ephemeral_heap_segment;
+ detailsData->alloc_allocated = (CLRDATA_ADDRESS)pHeap->alloc_allocated;
+ detailsData->ephemeral_heap_segment = (CLRDATA_ADDRESS)dac_cast<TADDR>(pHeap->ephemeral_heap_segment);
// get bounds for the different generations
for (i=0; i<NUMBERGENERATIONS; i++)
{
- detailsData->generation_table[i].start_segment = (CLRDATA_ADDRESS)dac_cast<TADDR>(pHeap->generation_table[i].start_segment);
- detailsData->generation_table[i].allocation_start = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->generation_table[i].allocation_start;
- detailsData->generation_table[i].allocContextPtr = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->generation_table[i].allocation_context.alloc_ptr;
- detailsData->generation_table[i].allocContextLimit = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->generation_table[i].allocation_context.alloc_limit;
+ DPTR(dac_generation) generation = ServerGenerationTableIndex(pHeap, i);
+ detailsData->generation_table[i].start_segment = (CLRDATA_ADDRESS)dac_cast<TADDR>(generation->start_segment);
+ detailsData->generation_table[i].allocation_start = (CLRDATA_ADDRESS)(ULONG_PTR)generation->allocation_start;
+ DPTR(gc_alloc_context) alloc_context = dac_cast<TADDR>(generation) + offsetof(dac_generation, allocation_context);
+ detailsData->generation_table[i].allocContextPtr = (CLRDATA_ADDRESS)(ULONG_PTR) alloc_context->alloc_ptr;
+ detailsData->generation_table[i].allocContextLimit = (CLRDATA_ADDRESS)(ULONG_PTR) alloc_context->alloc_limit;
}
- // since these are all TADDRS, we have to compute the address of the m_FillPointers field explicitly
- TADDR pFillPointerArray = dac_cast<TADDR>(pHeap->finalize_queue) + offsetof(SVR::CFinalize,m_FillPointers);
-
- for(i=0; i<(NUMBERGENERATIONS+SVR::CFinalize::ExtraSegCount); i++)
+ DPTR(dac_finalize_queue) fq = pHeap->finalize_queue;
+ DPTR(uint8_t*) pFillPointerArray= dac_cast<TADDR>(fq) + offsetof(dac_finalize_queue, m_FillPointers);
+ for(i=0; i<(NUMBERGENERATIONS+dac_finalize_queue::ExtraSegCount); i++)
{
- ULONG32 returned = 0;
- size_t pValue;
- HRESULT hr = m_pTarget->ReadVirtual(pFillPointerArray+(i*sizeof(TADDR)),
- (PBYTE)&pValue,
- sizeof(TADDR),
- &returned);
- if (FAILED(hr) || (returned != sizeof(TADDR)))
- {
- return E_FAIL;
- }
-
- detailsData->finalization_fill_pointers[i] = (CLRDATA_ADDRESS) pValue;
+ detailsData->finalization_fill_pointers[i] = (CLRDATA_ADDRESS) pFillPointerArray[i];
}
return S_OK;
@@ -179,16 +145,16 @@ HRESULT ClrDataAccess::ServerGCHeapDetails(CLRDATA_ADDRESS heapAddr, DacpGcHeapD
HRESULT
ClrDataAccess::ServerOomData(CLRDATA_ADDRESS addr, DacpOomData *oomData)
{
- SVR::gc_heap *pHeap = PTR_SVR_gc_heap(TO_TADDR(addr));
+ DPTR(dac_gc_heap) pHeap = __DPtr<dac_gc_heap>(TO_TADDR(addr));
- oom_history* pOOMInfo = (oom_history*)((TADDR)pHeap + offsetof(SVR::gc_heap,oom_info));
- oomData->reason = pOOMInfo->reason;
- oomData->alloc_size = pOOMInfo->alloc_size;
- oomData->available_pagefile_mb = pOOMInfo->available_pagefile_mb;
- oomData->gc_index = pOOMInfo->gc_index;
- oomData->fgm = pOOMInfo->fgm;
- oomData->size = pOOMInfo->size;
- oomData->loh_p = pOOMInfo->loh_p;
+ oom_history pOOMInfo = pHeap->oom_info;
+ oomData->reason = pOOMInfo.reason;
+ oomData->alloc_size = pOOMInfo.alloc_size;
+ oomData->available_pagefile_mb = pOOMInfo.available_pagefile_mb;
+ oomData->gc_index = pOOMInfo.gc_index;
+ oomData->fgm = pOOMInfo.fgm;
+ oomData->size = pOOMInfo.size;
+ oomData->loh_p = pOOMInfo.loh_p;
return S_OK;
}
@@ -197,7 +163,7 @@ HRESULT
ClrDataAccess::ServerGCInterestingInfoData(CLRDATA_ADDRESS addr, DacpGCInterestingInfoData *interestingInfoData)
{
#ifdef GC_CONFIG_DRIVEN
- SVR::gc_heap *pHeap = PTR_SVR_gc_heap(TO_TADDR(addr));
+ dac_gc_heap *pHeap = __DPtr<dac_gc_heap>(TO_TADDR(addr));
size_t* dataPoints = (size_t*)&(pHeap->interesting_data_per_heap);
for (int i = 0; i < NUM_GC_DATA_POINTS; i++)
@@ -226,11 +192,11 @@ HRESULT ClrDataAccess::ServerGCHeapAnalyzeData(CLRDATA_ADDRESS heapAddr, DacpGcH
return E_INVALIDARG;
}
- SVR::gc_heap *pHeap = PTR_SVR_gc_heap(TO_TADDR(heapAddr));
+ DPTR(dac_gc_heap) pHeap = __DPtr<dac_gc_heap>(TO_TADDR(heapAddr));
analyzeData->heapAddr = heapAddr;
- analyzeData->internal_root_array = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->internal_root_array;
- analyzeData->internal_root_array_index = (size_t) pHeap->internal_root_array_index;
+ analyzeData->internal_root_array = (CLRDATA_ADDRESS)pHeap->internal_root_array;
+ analyzeData->internal_root_array_index = (size_t)pHeap->internal_root_array_index;
analyzeData->heap_analyze_success = (BOOL)pHeap->heap_analyze_success;
return S_OK;
@@ -240,30 +206,33 @@ void
ClrDataAccess::EnumSvrGlobalMemoryRegions(CLRDataEnumMemoryFlags flags)
{
SUPPORTS_DAC;
- SVR::gc_heap::n_heaps.EnumMem();
- DacEnumMemoryRegion(SVR::gc_heap::g_heaps.GetAddr(),
- sizeof(TADDR) * SVR::gc_heap::n_heaps);
+ g_gcDacGlobals->n_heaps.EnumMem();
+ DacEnumMemoryRegion(g_gcDacGlobals->g_heaps.GetAddr(),
+ sizeof(TADDR) * *g_gcDacGlobals->n_heaps);
- SVR::gc_heap::g_heaps.EnumMem();
+ g_gcDacGlobals->gc_structures_invalid_cnt.EnumMem();
+ g_gcDacGlobals->g_heaps.EnumMem();
- for (int i=0;i<SVR::gc_heap::n_heaps;i++)
+ for (int i=0; i < *g_gcDacGlobals->n_heaps; i++)
{
- PTR_SVR_gc_heap pHeap = PTR_SVR_gc_heap(SVR::gc_heap::g_heaps[i]);
+ DPTR(dac_gc_heap) pHeap = HeapTableIndex(g_gcDacGlobals->g_heaps, i);
- DacEnumMemoryRegion(dac_cast<TADDR>(pHeap), sizeof(SVR::gc_heap));
- DacEnumMemoryRegion(dac_cast<TADDR>(pHeap->finalize_queue), sizeof(SVR::CFinalize));
+ size_t gen_table_size = g_gcDacGlobals->generation_size * (*g_gcDacGlobals->max_gen + 1);
+ DacEnumMemoryRegion(dac_cast<TADDR>(pHeap), sizeof(dac_gc_heap));
+ DacEnumMemoryRegion(dac_cast<TADDR>(pHeap->finalize_queue), sizeof(dac_finalize_queue));
+ DacEnumMemoryRegion(dac_cast<TADDR>(pHeap->generation_table), gen_table_size);
// enumerating the generations from max (which is normally gen2) to max+1 gives you
// the segment list for all the normal segements plus the large heap segment (max+1)
// this is the convention in the GC so it is repeated here
- for (ULONG i = GCHeapUtilities::GetMaxGeneration(); i <= GCHeapUtilities::GetMaxGeneration()+1; i++)
+ for (ULONG i = *g_gcDacGlobals->max_gen; i <= *g_gcDacGlobals->max_gen +1; i++)
{
- __DPtr<SVR::heap_segment> seg = dac_cast<TADDR>(pHeap->generation_table[i].start_segment);
+ DPTR(dac_heap_segment) seg = ServerGenerationTableIndex(pHeap, i)->start_segment;
while (seg)
{
- DacEnumMemoryRegion(PTR_HOST_TO_TADDR(seg), sizeof(SVR::heap_segment));
+ DacEnumMemoryRegion(PTR_HOST_TO_TADDR(seg), sizeof(dac_heap_segment));
- seg = __DPtr<SVR::heap_segment>(dac_cast<TADDR>(seg->next));
+ seg = seg->next;
}
}
}
@@ -271,9 +240,9 @@ ClrDataAccess::EnumSvrGlobalMemoryRegions(CLRDataEnumMemoryFlags flags)
DWORD DacGetNumHeaps()
{
- if (GCHeapUtilities::IsServerHeap())
- return (DWORD)SVR::gc_heap::n_heaps;
-
+ if (g_heap_type == GC_HEAP_SVR)
+ return (DWORD)*g_gcDacGlobals->n_heaps;
+
// workstation gc
return 1;
}
@@ -281,7 +250,7 @@ DWORD DacGetNumHeaps()
HRESULT DacHeapWalker::InitHeapDataSvr(HeapData *&pHeaps, size_t &pCount)
{
// Scrape basic heap details
- int heaps = SVR::gc_heap::n_heaps;
+ int heaps = *g_gcDacGlobals->n_heaps;
pCount = heaps;
pHeaps = new (nothrow) HeapData[heaps];
if (pHeaps == NULL)
@@ -290,18 +259,22 @@ HRESULT DacHeapWalker::InitHeapDataSvr(HeapData *&pHeaps, size_t &pCount)
for (int i = 0; i < heaps; ++i)
{
// Basic heap info.
- PTR_SVR_gc_heap heap = PTR_SVR_gc_heap(SVR::gc_heap::g_heaps[i]);
+ DPTR(dac_gc_heap) heap = HeapTableIndex(g_gcDacGlobals->g_heaps, i);
+ dac_generation gen0 = *ServerGenerationTableIndex(heap, 0);
+ dac_generation gen1 = *ServerGenerationTableIndex(heap, 1);
+ dac_generation gen2 = *ServerGenerationTableIndex(heap, 2);
+ dac_generation loh = *ServerGenerationTableIndex(heap, 3);
- pHeaps[i].YoungestGenPtr = (CORDB_ADDRESS)heap->generation_table[0].allocation_context.alloc_ptr;
- pHeaps[i].YoungestGenLimit = (CORDB_ADDRESS)heap->generation_table[0].allocation_context.alloc_limit;
+ pHeaps[i].YoungestGenPtr = (CORDB_ADDRESS)gen0.allocation_context.alloc_ptr;
+ pHeaps[i].YoungestGenLimit = (CORDB_ADDRESS)gen0.allocation_context.alloc_limit;
- pHeaps[i].Gen0Start = (CORDB_ADDRESS)heap->generation_table[0].allocation_start;
+ pHeaps[i].Gen0Start = (CORDB_ADDRESS)gen0.allocation_start;
pHeaps[i].Gen0End = (CORDB_ADDRESS)heap->alloc_allocated;
- pHeaps[i].Gen1Start = (CORDB_ADDRESS)heap->generation_table[1].allocation_start;
+ pHeaps[i].Gen1Start = (CORDB_ADDRESS)gen1.allocation_start;
// Segments
- int count = GetSegmentCount(heap->generation_table[NUMBERGENERATIONS-1].start_segment);
- count += GetSegmentCount(heap->generation_table[NUMBERGENERATIONS-2].start_segment);
+ int count = GetSegmentCount(loh.start_segment);
+ count += GetSegmentCount(gen2.start_segment);
pHeaps[i].SegmentCount = count;
pHeaps[i].Segments = new (nothrow) SegmentData[count];
@@ -309,12 +282,12 @@ HRESULT DacHeapWalker::InitHeapDataSvr(HeapData *&pHeaps, size_t &pCount)
return E_OUTOFMEMORY;
// Small object heap segments
- SVR::PTR_heap_segment seg = heap->generation_table[NUMBERGENERATIONS-2].start_segment;
+ DPTR(dac_heap_segment) seg = gen2.start_segment;
int j = 0;
for (; seg && (j < count); ++j)
{
pHeaps[i].Segments[j].Start = (CORDB_ADDRESS)seg->mem;
- if (seg.GetAddr() == TO_TADDR(heap->ephemeral_heap_segment))
+ if (seg.GetAddr() == heap->ephemeral_heap_segment.GetAddr())
{
pHeaps[i].Segments[j].End = (CORDB_ADDRESS)heap->alloc_allocated;
pHeaps[i].EphemeralSegment = j;
@@ -331,7 +304,7 @@ HRESULT DacHeapWalker::InitHeapDataSvr(HeapData *&pHeaps, size_t &pCount)
// Large object heap segments
- seg = heap->generation_table[NUMBERGENERATIONS-1].start_segment;
+ seg = loh.start_segment;
for (; seg && (j < count); ++j)
{
pHeaps[i].Segments[j].Generation = 3;
diff --git a/src/debug/daccess/stdafx.h b/src/debug/daccess/stdafx.h
index 5c2d37688b..1c19ebff10 100644
--- a/src/debug/daccess/stdafx.h
+++ b/src/debug/daccess/stdafx.h
@@ -47,9 +47,6 @@
#include <xcordebug.h>
#include "dacimpl.h"
-#if defined(FEATURE_APPX_BINDER)
-#include <clrprivbinderappx.h>
-#endif // defined(FEATURE_APPX)
#define STRSAFE_NO_DEPRECATE
#include <strsafe.h>
diff --git a/src/debug/debug-pal/unix/twowaypipe.cpp b/src/debug/debug-pal/unix/twowaypipe.cpp
index db4599aeb9..9dfe1e3ecb 100644
--- a/src/debug/debug-pal/unix/twowaypipe.cpp
+++ b/src/debug/debug-pal/unix/twowaypipe.cpp
@@ -24,11 +24,16 @@ bool TwoWayPipe::CreateServer(DWORD id)
PAL_GetTransportPipeName(m_inPipeName, id, "in");
PAL_GetTransportPipeName(m_outPipeName, id, "out");
+ unlink(m_inPipeName);
+
if (mkfifo(m_inPipeName, S_IRWXU) == -1)
{
return false;
}
+
+ unlink(m_outPipeName);
+
if (mkfifo(m_outPipeName, S_IRWXU) == -1)
{
unlink(m_inPipeName);
diff --git a/src/debug/di/cordb.cpp b/src/debug/di/cordb.cpp
index 497225fd67..e6ed44ddb9 100644
--- a/src/debug/di/cordb.cpp
+++ b/src/debug/di/cordb.cpp
@@ -86,7 +86,7 @@ HINSTANCE g_hInst; // Instance handle to this piece of code
//*****************************************************************************
STDAPI CreateCordbObject(int iDebuggerVersion, IUnknown ** ppCordb)
{
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_DBGIPC_TRANSPORT_DI) && !defined(FEATURE_CORESYSTEM)
+#if !defined(FEATURE_DBGIPC_TRANSPORT_DI) && !defined(FEATURE_CORESYSTEM)
// This API should not be called for Windows CoreCLR unless we are doing interop-debugging
// (which is only supported internally). Use code:CoreCLRCreateCordbObject instead.
if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgEnableMixedModeDebugging) == 0)
@@ -94,7 +94,7 @@ STDAPI CreateCordbObject(int iDebuggerVersion, IUnknown ** ppCordb)
_ASSERTE(!"Deprecated entry point CreateCordbObject() is called on Windows CoreCLR\n");
return E_NOTIMPL;
}
-#endif // FEATURE_CORECLR && !FEATURE_DBGIPC_TRANSPORT_DI
+#endif // !defined(FEATURE_DBGIPC_TRANSPORT_DI) && !defined(FEATURE_CORESYSTEM)
if (ppCordb == NULL)
{
@@ -108,7 +108,6 @@ STDAPI CreateCordbObject(int iDebuggerVersion, IUnknown ** ppCordb)
return Cordb::CreateObject((CorDebugInterfaceVersion)iDebuggerVersion, IID_ICorDebug, (void **) ppCordb);
}
-#if defined(FEATURE_CORECLR)
//
// Public API.
// Telesto Creation path - only way to debug multi-instance.
@@ -161,7 +160,6 @@ STDAPI CoreCLRCreateCordbObject(int iDebuggerVersion, DWORD pid, HMODULE hmodTar
return hr;
}
-#endif // FEATURE_CORECLR
@@ -501,7 +499,7 @@ DbiGetThreadContext(HANDLE hThread,
DT_CONTEXT *lpContext)
{
// if we aren't local debugging this isn't going to work
-#if !defined(_ARM_) || defined(FEATURE_DBGIPC_TRANSPORT_DI)
+#if !defined(_ARM_) || defined(FEATURE_DBGIPC_TRANSPORT_DI) || defined(__ANDROID__)
_ASSERTE(!"Can't use local GetThreadContext remotely, this needed to go to datatarget");
return FALSE;
#else
@@ -540,7 +538,7 @@ BOOL
DbiSetThreadContext(HANDLE hThread,
const DT_CONTEXT *lpContext)
{
-#if !defined(_ARM_) || defined(FEATURE_DBGIPC_TRANSPORT_DI)
+#if !defined(_ARM_) || defined(FEATURE_DBGIPC_TRANSPORT_DI) || defined(__ANDROID__)
_ASSERTE(!"Can't use local GetThreadContext remotely, this needed to go to datatarget");
return FALSE;
#else
diff --git a/src/debug/di/platformspecific.cpp b/src/debug/di/platformspecific.cpp
index 9df22b1728..2565a5b256 100644
--- a/src/debug/di/platformspecific.cpp
+++ b/src/debug/di/platformspecific.cpp
@@ -16,7 +16,7 @@
#include "dbgtransportpipeline.cpp"
#include "shimremotedatatarget.cpp"
#include "remoteeventchannel.cpp"
-#else
+#elif WIN32
#include "WindowsPipeline.cpp"
#include "EventRedirectionPipeline.cpp"
#include "ShimLocalDataTarget.cpp"
diff --git a/src/debug/di/process.cpp b/src/debug/di/process.cpp
index a5496eee54..b6d49c218d 100644
--- a/src/debug/di/process.cpp
+++ b/src/debug/di/process.cpp
@@ -2363,18 +2363,7 @@ HRESULT CordbProcess::EnumerateHandles(CorGCReferenceType types, ICorDebugGCRefe
HRESULT CordbProcess::EnableNGENPolicy(CorDebugNGENPolicy ePolicy)
{
-#ifdef FEATURE_CORECLR
return E_NOTIMPL;
-#else
- HRESULT hr = S_OK;
- PUBLIC_API_BEGIN(this);
-
- IDacDbiInterface* pDAC = GetProcess()->GetDAC();
- hr = pDAC->EnableNGENPolicy(ePolicy);
-
- PUBLIC_API_END(hr);
- return hr;
-#endif
}
@@ -4502,12 +4491,6 @@ void CordbProcess::GetModulesInLoadOrder(
// static
void CordbProcess::CountConnectionsCallback(DWORD id, LPCWSTR pName, void * pUserData)
{
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES)
- EnumerateConnectionsData * pCallbackData = reinterpret_cast<EnumerateConnectionsData *>(pUserData);
- INTERNAL_DAC_CALLBACK(pCallbackData->m_pThis);
-
- pCallbackData->m_uIndex += 1;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
//---------------------------------------------------------------------------------------
@@ -4524,20 +4507,6 @@ void CordbProcess::CountConnectionsCallback(DWORD id, LPCWSTR pName, void * pUse
// static
void CordbProcess::EnumerateConnectionsCallback(DWORD id, LPCWSTR pName, void * pUserData)
{
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES)
- EnumerateConnectionsData * pCallbackData = reinterpret_cast<EnumerateConnectionsData *>(pUserData);
- INTERNAL_DAC_CALLBACK(pCallbackData->m_pThis);
-
- // get the next entry in the array to be filled in
- EnumerateConnectionsEntry * pEntry = &(pCallbackData->m_pEntryArray[pCallbackData->m_uIndex]);
-
- // initialize the StringCopyHolder in the entry and copy over the name of the connection
- new (&(pEntry->m_pName)) StringCopyHolder;
- pEntry->m_pName.AssignCopy(pName);
- pEntry->m_dwID = id;
-
- pCallbackData->m_uIndex += 1;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
//---------------------------------------------------------------------------------------
@@ -4549,51 +4518,6 @@ void CordbProcess::QueueFakeConnectionEvents()
{
PUBLIC_API_ENTRY_FOR_SHIM(this);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- EnumerateConnectionsData callbackData;
- callbackData.m_pThis = this;
- callbackData.m_uIndex = 0;
- callbackData.m_pEntryArray = NULL;
-
- UINT32 uSize = 0;
-
- // We must take the process lock before calling DAC primitives which will call back into DBI.
- // On the other hand, we must NOT be holding the lock when we call out to the shim.
- // So introduce a new scope here.
- {
- RSLockHolder lockHolder(GetProcessLock());
- GetDAC()->EnumerateConnections(CountConnectionsCallback, &callbackData);
-
- // save the size for later
- uSize = callbackData.m_uIndex;
-
- // Allocate the array to store the connections. This array will be released when the dtor runs.
- callbackData.m_uIndex = 0;
- callbackData.m_pEntryArray = new EnumerateConnectionsEntry[uSize];
- GetDAC()->EnumerateConnections(EnumerateConnectionsCallback, &callbackData);
- _ASSERTE(uSize == callbackData.m_uIndex);
- }
-
- {
- // V2 would send CreateConnection for all connections, and then ChangeConnection
- // for all connections.
- PUBLIC_CALLBACK_IN_THIS_SCOPE0_NO_LOCK(this);
- for (UINT32 i = 0; i < uSize; i++)
- {
- EnumerateConnectionsEntry * pEntry = &(callbackData.m_pEntryArray[i]);
- GetShim()->GetShimCallback()->CreateConnection(
- this,
- (CONNID)pEntry->m_dwID,
- const_cast<WCHAR *>((const WCHAR *)(pEntry->m_pName)));
- }
-
- for (UINT32 i = 0; i < uSize; i++)
- {
- EnumerateConnectionsEntry * pEntry = &(callbackData.m_pEntryArray[i]);
- GetShim()->GetShimCallback()->ChangeConnection(this, (CONNID)pEntry->m_dwID);
- }
- }
-#endif
}
//
@@ -4601,10 +4525,6 @@ void CordbProcess::QueueFakeConnectionEvents()
// from the runtime controller. This represents the last amount of processing
// the DI gets to do on an event before giving it to the user.
//
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
-#endif
void CordbProcess::DispatchRCEvent()
{
INTERNAL_API_ENTRY(this);
@@ -4805,6 +4725,10 @@ void CordbProcess::DbgAssertAppDomainDeleted(VMPTR_AppDomain vmAppDomainDeleted)
// A V2 shim can provide a proxy calllack that takes these events and queues them and
// does the real dispatch to the user to emulate V2 semantics.
//
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
+#endif
void CordbProcess::RawDispatchEvent(
DebuggerIPCEvent * pEvent,
RSLockHolder * pLockHolder,
@@ -7509,33 +7433,6 @@ void CordbProcess::VerifyControlBlock()
// For Telesto, Dbi and Wks have a more flexible versioning allowed, as described by the Debugger
// Version Protocol String in DEBUGGER_PROTOCOL_STRING in DbgIpcEvents.h. This allows different build
// numbers, but the other protocol numbers should still match.
-#if !defined(FEATURE_CORECLR)
- bool fSkipVerCheck = false;
-#if _DEBUG
- // In debug builds, allow us to disable the version check to help with applying hotfixes.
- // The hotfix may be built against a compatible IPC protocol, but have a slightly different build number.
- fSkipVerCheck = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgSkipVerCheck) != 0;
-#endif
-
- if (!fSkipVerCheck)
- {
- //
- // These asserts double check that the version of the Right Side matches the version of the left side.
- //
- // If you hit these asserts, it is probably because you rebuilt mscordbi without rebuilding mscorwks, or rebuilt
- // mscorwks without rebuilding mscordbi. You might be able to ignore these asserts, but proceed at your own risk.
- //
- CONSISTENCY_CHECK_MSGF(VER_PRODUCTBUILD == GetDCB()->m_verMajor,
- ("version of %s (%d) in the debuggee does not match version of mscordbi.dll (%d) in the debugger.\n"
- "This means your setup is wrong. You can ignore this but proceed at your own risk.\n",
- MAIN_CLR_DLL_NAME_A, GetDCB()->m_verMajor, VER_PRODUCTBUILD));
- CONSISTENCY_CHECK_MSGF(VER_PRODUCTBUILD_QFE == GetDCB()->m_verMinor,
- ("QFE version of %s (%d) in the debuggee does not match QFE version of mscordbi.dll (%d) in the debugger.\n"
- "Both dlls have build # (%d).\n"
- "This means your setup is wrong. You can ignore this but proceed at your own risk.\n",
- MAIN_CLR_DLL_NAME_A, GetDCB()->m_verMinor, VER_PRODUCTBUILD_QFE, VER_PRODUCTBUILD));
- }
-#endif // !FEATURE_CORECLR
// These assertions verify that the debug manager is behaving correctly.
// An assertion failure here means that the runtime version of the debuggee is different from the runtime version of
@@ -15210,11 +15107,7 @@ bool CordbProcess::IsCompatibleWith(DWORD clrMajorVersion)
// honored for SLv4.
if (requiredVersion <= 0)
{
-#if defined(FEATURE_CORECLR)
requiredVersion = 2;
-#else
- requiredVersion = 4;
-#endif
}
// Compare the version we were created for against the minimum required
diff --git a/src/debug/di/rsmain.cpp b/src/debug/di/rsmain.cpp
index 0f5778789f..cdad21bf58 100644
--- a/src/debug/di/rsmain.cpp
+++ b/src/debug/di/rsmain.cpp
@@ -60,7 +60,7 @@ const char * GetDebugCodeName(DWORD dwCode)
"(5) EXIT_PROCESS_DEBUG_EVENT",
"(6) LOAD_DLL_DEBUG_EVENT",
"(7) UNLOAD_DLL_DEBUG_EVENT",
- "(8) OUTPUT_DEBUG_STRING_EVENT"
+ "(8) OUTPUT_DEBUG_STRING_EVENT",
"(9) RIP_EVENT",// <-- only on Win9X
};
@@ -1308,7 +1308,6 @@ HRESULT Cordb::WaitForIPCEventFromProcess(CordbProcess* process,
event);
}
-#ifdef FEATURE_CORECLR
HRESULT Cordb::SetTargetCLR(HMODULE hmodTargetCLR)
{
if (m_initialized)
@@ -1332,7 +1331,6 @@ HRESULT Cordb::SetTargetCLR(HMODULE hmodTargetCLR)
return S_OK;
}
-#endif // FEATURE_CORECLR
//-----------------------------------------------------------
// ICorDebug
@@ -1411,7 +1409,7 @@ HRESULT Cordb::SetUnmanagedHandler(ICorDebugUnmanagedCallback *pCallback)
// It is currently supported on Mac CoreCLR, but that may change.
bool Cordb::IsCreateProcessSupported()
{
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_DBGIPC_TRANSPORT_DI)
+#if !defined(FEATURE_DBGIPC_TRANSPORT_DI)
return false;
#else
return true;
@@ -1425,14 +1423,14 @@ bool Cordb::IsInteropDebuggingSupported()
// ICorDebug::SetUnmanagedHandler for details.
#ifdef FEATURE_INTEROP_DEBUGGING
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_CORESYSTEM)
+#if !defined(FEATURE_CORESYSTEM)
// Interop debugging is only supported internally on CoreCLR.
// Check if the special reg key is set. If not, then we don't allow interop debugging.
if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DbgEnableMixedModeDebugging) == 0)
{
return false;
}
-#endif // FEATURE_CORECLR
+#endif // FEATURE_CORESYSTEM
return true;
#else
diff --git a/src/debug/di/rsmda.cpp b/src/debug/di/rsmda.cpp
index d69b448309..751fdc8938 100644
--- a/src/debug/di/rsmda.cpp
+++ b/src/debug/di/rsmda.cpp
@@ -150,11 +150,7 @@ HRESULT CordbMDA::GetName(ULONG32 cchName, ULONG32 * pcchName, __out_ecount_part
HRESULT hr = S_OK;
PUBLIC_API_BEGIN(this)
{
-#if defined(FEATURE_CORECLR)
hr = E_NOTIMPL;
-#else // !FEATURE_CORECLR
- hr = CopyOutString(m_szName, cchName, pcchName, szName);
-#endif // FEATURE_CORECLR
}
PUBLIC_API_END(hr);
return hr;
@@ -169,11 +165,7 @@ HRESULT CordbMDA::GetDescription(ULONG32 cchName, ULONG32 * pcchName, __out_ecou
HRESULT hr = S_OK;
PUBLIC_API_BEGIN(this)
{
-#if defined(FEATURE_CORECLR)
hr = E_NOTIMPL;
-#else // !FEATURE_CORECLR
- hr = CopyOutString(m_szDescription, cchName, pcchName, szName);
-#endif // FEATURE_CORECLR
}
PUBLIC_API_END(hr);
return hr;
@@ -190,11 +182,7 @@ HRESULT CordbMDA::GetXML(ULONG32 cchName, ULONG32 * pcchName, __out_ecount_part_
HRESULT hr = S_OK;
PUBLIC_API_BEGIN(this)
{
-#if defined(FEATURE_CORECLR)
hr = E_NOTIMPL;
-#else // !FEATURE_CORECLR
- hr = CopyOutString(m_szXml, cchName, pcchName, szName);
-#endif // FEATURE_CORECLR
}
PUBLIC_API_END(hr);
return hr;
@@ -208,12 +196,7 @@ HRESULT CordbMDA::GetFlags(CorDebugMDAFlags * pFlags)
HRESULT hr = S_OK;
PUBLIC_API_BEGIN(this)
{
-#if defined(FEATURE_CORECLR)
hr = E_NOTIMPL;
-#else // !FEATURE_CORECLR
- ValidateOrThrow(pFlags);
- *pFlags = this->m_flags;
-#endif // FEATURE_CORECLR
}
PUBLIC_API_END(hr);
return hr;
@@ -229,13 +212,7 @@ HRESULT CordbMDA::GetOSThreadId(DWORD * pOsTid)
HRESULT hr = S_OK;
PUBLIC_API_BEGIN(this)
{
-#if defined(FEATURE_CORECLR)
hr = E_NOTIMPL;
-#else // !FEATURE_CORECLR
- ValidateOrThrow(pOsTid);
-
- *pOsTid = this->m_dwOSTID;
-#endif // FEATURE_CORECLR
}
PUBLIC_API_END(hr);
return hr;
diff --git a/src/debug/di/rspriv.h b/src/debug/di/rspriv.h
index 8f369b7414..d714517985 100644
--- a/src/debug/di/rspriv.h
+++ b/src/debug/di/rspriv.h
@@ -2199,9 +2199,7 @@ public:
// ICorDebug
//-----------------------------------------------------------
-#ifdef FEATURE_CORECLR
HRESULT SetTargetCLR(HMODULE hmodTargetCLR);
-#endif // FEATURE_CORECLR
COM_METHOD Initialize();
COM_METHOD Terminate();
diff --git a/src/debug/di/shimprocess.cpp b/src/debug/di/shimprocess.cpp
index a6fc15407e..46c35fdc2b 100644
--- a/src/debug/di/shimprocess.cpp
+++ b/src/debug/di/shimprocess.cpp
@@ -1850,11 +1850,7 @@ HMODULE ShimProcess::GetDacModule()
// mscordaccore.dll <-- coreclr
// mscordacwks.dll <-- desktop
PCWSTR eeFlavor =
-#if defined(FEATURE_MAIN_CLR_MODULE_USES_CORE_NAME)
W("mscordaccore.dll");
-#else
- W("mscordacwks.dll");
-#endif
#endif // FEATURE_PAL
wszAccessDllPath.Append(eeFlavor);
diff --git a/src/debug/ee/arm64/dbghelpers.S b/src/debug/ee/arm64/dbghelpers.S
index 07ed04acd5..64932f322b 100644
--- a/src/debug/ee/arm64/dbghelpers.S
+++ b/src/debug/ee/arm64/dbghelpers.S
@@ -1,25 +1,50 @@
-//Licensed to the .NET Foundation under one or more agreements.
+// 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 "asmconstants.h"
#include "unixasmmacros.inc"
-NESTED_ENTRY FuncEvalHijack, _TEXT, FuncEvalHijackPersonalityRoutine
+//
+// hijacking stub used to perform a func-eval, see Debugger::FuncEvalSetup() for use.
+//
+// on entry:
+// x0 : pointer to DebuggerEval object
+//
-// NOTE: FuncEvalHijackPersonalityRoutine is dependent on the stack layout so if
-// you change the prolog you will also need to update the personality routine.
+// @dbgtodo- once we port Funceval, use the ExceptionHijack stub instead of this func-eval stub.
+NESTED_ENTRY FuncEvalHijack, _TEXT, UnhandledExceptionHandlerUnix
-// push arg to the stack so our personality routine can find it
-// push lr to get good stacktrace in debugger
+ // NOTE: FuncEvalHijackPersonalityRoutine is dependent on the stack layout so if
+ // you change the prolog you will also need to update the personality routine.
-PROLOG_SAVE_REG_PAIR fp, lr, #-32
+ // push arg to the stack so our personality routine can find it
+ // push lr to get good stacktrace in debugger
+ PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -32
+ str x0, [sp, #16]
+ // FuncEvalHijackWorker returns the address we should jump to.
+ bl FuncEvalHijackWorker
+
+ EPILOG_STACK_FREE 32
+ EPILOG_BRANCH_REG x0
+NESTED_END FuncEvalHijack
+
+// This is the general purpose hijacking stub. The DacDbi Hijack primitive will
+// set up the stack and then set the IP here, and so this just makes the call.
+NESTED_ENTRY ExceptionHijack, _TEXT, UnhandledExceptionHandlerUnix
+
+ // make the call
+ bl ExceptionHijackWorker
+
+ // effective NOP to terminate unwind
+ mov x3, x3
+
+ // *** should never get here ***
+ EMIT_BREAKPOINT
+
+// exported label so the debugger knows where the end of this function is
+PATCH_LABEL ExceptionHijackEnd
+
+NESTED_END ExceptionHijack, _TEXT
- str x0, [sp, #16]
- // FuncEvalHijackWorker returns the address we should jump to.
- bl FuncEvalHijackWorker
-
- EPILOG_STACK_FREE 32
- EPILOG_BRANCH_REG x0
-NESTED_END FuncEvalHijack, _TEXT
-//NESTED_ENTRY ExceptionHijack,,ExceptionHijackPersonalityRoutine \ No newline at end of file
diff --git a/src/debug/ee/controller.h b/src/debug/ee/controller.h
index a314874b8d..95569b55c7 100644
--- a/src/debug/ee/controller.h
+++ b/src/debug/ee/controller.h
@@ -954,8 +954,6 @@ class DebuggerController
//
public:
- // Once we support debugging + fibermode (which was cut in V2.0), we may need some Thread::BeginThreadAffinity() calls
- // associated with the controller lock because this lock wraps context operations.
class ControllerLockHolder : public CrstHolder
{
public:
diff --git a/src/debug/ee/dactable.cpp b/src/debug/ee/dactable.cpp
index c37bbed744..af7de1710d 100644
--- a/src/debug/ee/dactable.cpp
+++ b/src/debug/ee/dactable.cpp
@@ -21,14 +21,6 @@
#include "../../vm/gcenv.h"
#include "../../vm/ecall.h"
#include "../../vm/rcwwalker.h"
-#include "../../gc/gc.h"
-#include "../../gc/gcscan.h"
-
-#undef SERVER_GC
-namespace WKS {
-#include "../../gc/gcimpl.h"
-#include "../../gc/gcpriv.h"
-}
#ifdef DEBUGGING_SUPPORTED
@@ -40,11 +32,7 @@ extern DWORD gThreadTLSIndex;
extern DWORD gAppDomainTLSIndex;
#ifdef FEATURE_APPX
-#if defined(FEATURE_CORECLR)
extern BOOL g_fAppX;
-#else
-extern PTR_AppXRTInfo g_pAppXRTInfo;
-#endif
#endif // FEATURE_APPX
DacGlobals g_dacTable;
diff --git a/src/debug/ee/debugger.cpp b/src/debug/ee/debugger.cpp
index 1f2126b9f0..ae698e2234 100644
--- a/src/debug/ee/debugger.cpp
+++ b/src/debug/ee/debugger.cpp
@@ -18,9 +18,6 @@
#include "eeconfig.h" // This is here even for retail & free builds...
#include "../../dlls/mscorrc/resource.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "context.h"
#include "vars.hpp"
@@ -43,9 +40,7 @@
#include "datatest.h"
#endif // TEST_DATA_CONSISTENCY
-#if defined(FEATURE_CORECLR)
#include "dbgenginemetrics.h"
-#endif // FEATURE_CORECLR
#include "../../vm/rejit.h"
@@ -281,20 +276,6 @@ bool IsGuardPageGone()
return fGuardPageGone;
}
-
-// This is called from AppDomainEnumerationIPCBlock::Lock and Unlock
-void BeginThreadAffinityHelper()
-{
- WRAPPER_NO_CONTRACT;
-
- Thread::BeginThreadAffinity();
-}
-void EndThreadAffinityHelper()
-{
- WRAPPER_NO_CONTRACT;
- Thread::EndThreadAffinity();
-}
-
//-----------------------------------------------------------------------------
// LSPTR_XYZ is a type-safe wrapper around an opaque reference type XYZ in the left-side.
// But TypeHandles are value-types that can't be directly converted into a pointer.
@@ -1896,7 +1877,7 @@ void Debugger::SendCreateProcess(DebuggerLockHolder * pDbgLockHolder)
pDbgLockHolder->Acquire();
}
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if !defined(FEATURE_PAL)
HANDLE g_hContinueStartupEvent = INVALID_HANDLE_VALUE;
@@ -1966,7 +1947,7 @@ void NotifyDebuggerOfTelestoStartup()
g_hContinueStartupEvent = NULL;
}
-#endif // FEATURE_CORECLR && !FEATURE_PAL
+#endif // !FEATURE_PAL
//---------------------------------------------------------------------------------------
//
@@ -1999,7 +1980,7 @@ HRESULT Debugger::Startup(void)
_ASSERTE(g_pEEInterface != NULL);
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if !defined(FEATURE_PAL)
if (IsWatsonEnabled() || IsTelestoDebugPackInstalled())
{
// Iff the debug pack is installed, then go through the telesto debugging pipeline.
@@ -2018,7 +1999,7 @@ HRESULT Debugger::Startup(void)
// The transport requires the debug pack to be present. Otherwise it'll raise a fatal error.
return S_FALSE;
}
-#endif // FEATURE_CORECLR && !FEATURE_PAL
+#endif // !FEATURE_PAL
{
DebuggerLockHolder dbgLockHolder(this);
@@ -5200,39 +5181,6 @@ HRESULT Debugger::MapPatchToDJI( DebuggerControllerPatch *dcp,DebuggerJitInfo *d
return S_OK;
}
-//
-// Wrapper function for debugger to WaitForSingleObject. If CLR is hosted,
-// notify host before we leave runtime.
-//
-DWORD Debugger::WaitForSingleObjectHelper(HANDLE handle, DWORD dwMilliseconds)
-{
- CONTRACTL
- {
- SO_NOT_MAINLINE;
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- DWORD dw = 0;
- EX_TRY
- {
-
- // make sure that we let host know that we are leaving runtime.
- LeaveRuntimeHolder holder((size_t)(::WaitForSingleObject));
- dw = ::WaitForSingleObject(handle,dwMilliseconds);
- }
- EX_CATCH
- {
- // Only possibility to enter here is when Thread::LeaveRuntime
- // throws exception.
- dw = WAIT_ABANDONED;
- }
- EX_END_CATCH(SwallowAllExceptions);
- return dw;
-
-}
-
/* ------------------------------------------------------------------------ *
* EE Interface routines
@@ -8139,8 +8087,7 @@ LONG Debugger::NotifyOfCHFFilter(EXCEPTION_POINTERS* pExceptionPointers, PVOID p
pExState->GetFlags()->SetDebugCatchHandlerFound();
#ifdef DEBUGGING_SUPPORTED
-
-
+#ifdef DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED
if ( (pThread != NULL) &&
(pThread->IsExceptionInProgress()) &&
(pThread->GetExceptionState()->GetFlags()->DebuggerInterceptInfo()) )
@@ -8151,6 +8098,7 @@ LONG Debugger::NotifyOfCHFFilter(EXCEPTION_POINTERS* pExceptionPointers, PVOID p
//
ClrDebuggerDoUnwindAndIntercept(X86_FIRST_ARG(EXCEPTION_CHAIN_END) pExceptionPointers->ExceptionRecord);
}
+#endif // DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED
#endif // DEBUGGING_SUPPORTED
return EXCEPTION_CONTINUE_SEARCH;
@@ -9589,23 +9537,6 @@ void Debugger::LoadModule(Module* pRuntimeModule,
SENDIPCEVENT_BEGIN(this, pThread);
-#ifdef FEATURE_FUSION
- // Fix for issue Whidbey - 106398
- // Populate the pdb to fusion cache.
-
- //
- if (pRuntimeModule->IsIStream() == FALSE)
- {
- SUPPRESS_ALLOCATION_ASSERTS_IN_THIS_SCOPE;
-
- HRESULT hrCopy = S_OK;
- EX_TRY
- {
- pRuntimeModule->FusionCopyPDBs(pRuntimeModule->GetPath());
- }
- EX_CATCH_HRESULT(hrCopy); // ignore failures
- }
-#endif // FEATURE_FUSION
DebuggerIPCEvent* ipce = NULL;
@@ -9804,7 +9735,6 @@ void Debugger::LoadModuleFinished(Module * pRuntimeModule, AppDomain * pAppDomai
// Use code:Debugger.SendUpdateModuleSymsEventAndBlock for that.
void Debugger::SendRawUpdateModuleSymsEvent(Module *pRuntimeModule, AppDomain *pAppDomain)
{
-// @telest - do we need an #ifdef FEATURE_FUSION here?
CONTRACTL
{
NOTHROW;
@@ -12740,27 +12670,13 @@ CorDebugUserState Debugger::GetFullUserState(Thread *pThread)
/******************************************************************************
*
* Helper for debugger to get an unique thread id
- * If we are not in Fiber mode, we can safely use OSThreadId
- * Otherwise, we will use our own unique ID.
- *
- * We will return our unique ID when our host is hosting Thread.
- *
*
******************************************************************************/
DWORD Debugger::GetThreadIdHelper(Thread *pThread)
{
WRAPPER_NO_CONTRACT;
- if (!CLRTaskHosted())
- {
- // use the plain old OS Thread ID
- return pThread->GetOSThreadId();
- }
- else
- {
- // use our unique thread ID
- return pThread->GetThreadId();
- }
+ return pThread->GetOSThreadId();
}
//-----------------------------------------------------------------------------
@@ -14964,21 +14880,6 @@ HRESULT Debugger::CopyModulePdb(Module* pRuntimeModule)
}
HRESULT hr = S_OK;
-#ifdef FEATURE_FUSION
- //
- // Populate the pdb to fusion cache.
- //
- if (pRuntimeModule->IsIStream() == FALSE)
- {
- SUPPRESS_ALLOCATION_ASSERTS_IN_THIS_SCOPE;
-
- EX_TRY
- {
- pRuntimeModule->FusionCopyPDBs(pRuntimeModule->GetPath());
- }
- EX_CATCH_HRESULT(hr); // ignore failures
- }
-#endif // FEATURE_FUSION
return hr;
}
@@ -15101,15 +15002,6 @@ HRESULT Debugger::InitAppDomainIPC(void)
// uninited values.
ZeroMemory(m_pAppDomainCB, sizeof(*m_pAppDomainCB));
- // Fix for issue: whidbey 143061
- // We are creating the mutex as hold, when we unlock, the EndThreadAffinity in
- // hosting case will be unbalanced.
- // Ideally, I would like to fix this by creating mutex not-held and call Lock method.
- // This way, when we clean up the OOM, (as you can tell, we never release the mutex in
- // some error cases), we can change it to holder class.
- //
- Thread::BeginThreadAffinity();
-
// Create a mutex to allow the Left and Right Sides to properly
// synchronize. The Right Side will spin until m_hMutex is valid,
// then it will acquire it before accessing the data.
@@ -16095,7 +15987,7 @@ BOOL Debugger::SendCtrlCToDebugger(DWORD dwCtrlType)
// now wait for notification from the right side about whether or not
// the out-of-proc debugger is handling ControlC events.
- WaitForSingleObjectHelper(GetCtrlCMutex(), INFINITE);
+ ::WaitForSingleObject(GetCtrlCMutex(), INFINITE);
return GetDebuggerHandlingCtrlC();
}
diff --git a/src/debug/ee/debugger.h b/src/debug/ee/debugger.h
index 9cdf546290..f99931e9dd 100644
--- a/src/debug/ee/debugger.h
+++ b/src/debug/ee/debugger.h
@@ -397,9 +397,9 @@ inline LPVOID PushedRegAddr(REGDISPLAY* pRD, LPVOID pAddr)
{
LIMITED_METHOD_CONTRACT;
-#if defined(_TARGET_AMD64_)
+#ifdef WIN64EXCEPTIONS
if ( ((UINT_PTR)(pAddr) >= (UINT_PTR)pRD->pCurrentContextPointers) &&
- ((UINT_PTR)(pAddr) <= ((UINT_PTR)pRD->pCurrentContextPointers + sizeof(_KNONVOLATILE_CONTEXT_POINTERS))) )
+ ((UINT_PTR)(pAddr) <= ((UINT_PTR)pRD->pCurrentContextPointers + sizeof(T_KNONVOLATILE_CONTEXT_POINTERS))) )
#else
if ( ((UINT_PTR)(pAddr) >= (UINT_PTR)pRD->pContext) &&
((UINT_PTR)(pAddr) <= ((UINT_PTR)pRD->pContext + sizeof(T_CONTEXT))) )
@@ -2772,8 +2772,6 @@ public:
bool ResumeThreads(AppDomain* pAppDomain);
- static DWORD WaitForSingleObjectHelper(HANDLE handle, DWORD dwMilliseconds);
-
void ProcessAnyPendingEvals(Thread *pThread);
bool HasLazyData();
diff --git a/src/debug/ee/debugger.inl b/src/debug/ee/debugger.inl
index 57372868c0..612aacd609 100644
--- a/src/debug/ee/debugger.inl
+++ b/src/debug/ee/debugger.inl
@@ -225,7 +225,7 @@ inline void FuncEvalFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
return;
}
-#if !defined(_WIN64)
+#ifndef WIN64EXCEPTIONS
// Reset pContext; it's only valid for active (top-most) frame.
pRD->pContext = NULL;
#endif // !_WIN64
diff --git a/src/debug/ee/frameinfo.cpp b/src/debug/ee/frameinfo.cpp
index 35e5bb9a09..fb9ea886bf 100644
--- a/src/debug/ee/frameinfo.cpp
+++ b/src/debug/ee/frameinfo.cpp
@@ -1778,29 +1778,6 @@ StackWalkAction DebuggerWalkStackProc(CrawlFrame *pCF, void *data)
}
break;
-#ifdef FEATURE_REMOTING
- case Frame::TYPE_TP_METHOD_FRAME:
- LOG((LF_CORDB, LL_INFO100000, "DWSP: Frame type is TYPE_TP_METHOD_FRAME.\n"));
- if (d->ShouldIgnoreNonmethodFrames())
- {
- // Transparant Proxies push a frame onto the stack that they
- // use to figure out where they're really going; this frame
- // doesn't actually contain any code, although it does have
- // enough info into fooling our routines into thinking it does:
- // Just ignore these.
- LOG((LF_CORDB, LL_INFO100000, "DWSP: Skipping frame 0x%x b/c it's "
- "a transparant proxy frame!\n", frame));
- use = false;
- }
- else
- {
- // Otherwise do the same thing as for internal frames
- LOG((LF_CORDB, LL_INFO100000, "DWSP: NOT Skipping frame 0x%x even though it's "
- "a transparant proxy frame!\n", frame));
- INTERNAL_FRAME_ACTION(d, use);
- }
- break;
-#endif
default:
_ASSERTE(!"Invalid frame type!");
break;
diff --git a/src/debug/ee/funceval.cpp b/src/debug/ee/funceval.cpp
index eb8950deab..dcfe5a5dcf 100644
--- a/src/debug/ee/funceval.cpp
+++ b/src/debug/ee/funceval.cpp
@@ -21,9 +21,6 @@
#include "eeconfig.h" // This is here even for retail & free builds...
#include "../../dlls/mscorrc/resource.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "context.h"
#include "vars.hpp"
diff --git a/src/debug/ee/stdafx.h b/src/debug/ee/stdafx.h
index 7ccfa8d984..519ce510c4 100644
--- a/src/debug/ee/stdafx.h
+++ b/src/debug/ee/stdafx.h
@@ -12,10 +12,6 @@
#include <stdio.h>
#include <windows.h>
-#if !defined(FEATURE_CORECLR)
-#undef GetCurrentTime // works around a macro def conflict of GetCurrentTime
-#include <windows.ui.xaml.h>
-#endif // !FEATURE_CORECLR
#include <switches.h>
#include <winwrap.h>
diff --git a/src/debug/ee/wks/CMakeLists.txt b/src/debug/ee/wks/CMakeLists.txt
index 1088355f12..4c4c537607 100644
--- a/src/debug/ee/wks/CMakeLists.txt
+++ b/src/debug/ee/wks/CMakeLists.txt
@@ -58,7 +58,7 @@ add_compile_options(-fPIC)
if(CLR_CMAKE_PLATFORM_ARCH_AMD64 OR CLR_CMAKE_PLATFORM_ARCH_ARM OR CLR_CMAKE_PLATFORM_ARCH_ARM64 OR CLR_CMAKE_PLATFORM_ARCH_I386)
add_library_clr(cordbee_wks ${CORDBEE_SOURCES_WKS} ../${ARCH_SOURCES_DIR}/dbghelpers.S)
elseif(CLR_CMAKE_PLATFORM_ARCH_ARM64)
- add_library_clr(cordbee_wks ${CORDBEE_SOURCES_WKS})
+ add_library_clr(cordbee_wks ${CORDBEE_SOURCES_WKS} ../${ARCH_SOURCES_DIR}/dbghelpers.S)
else()
message(FATAL_ERROR "Only ARM and AMD64 is supported")
endif()
diff --git a/src/debug/inc/dacdbiinterface.h b/src/debug/inc/dacdbiinterface.h
index 569ccbaca7..4077ad426a 100644
--- a/src/debug/inc/dacdbiinterface.h
+++ b/src/debug/inc/dacdbiinterface.h
@@ -979,9 +979,6 @@ public:
// V2 Attach would provide faked up CreateConnection, ChangeConnection events on attach.
// This enumeration ability allows V3 to emulate that behavior.
//
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- virtual void EnumerateConnections(FP_CONNECTION_CALLBACK fpCallback, CALLBACK_DATA pUserData) = 0;
-#endif //FEATURE_INCLUDE_ALL_INTERFACES
//
// Enumerate all threads in the target.
diff --git a/src/debug/inc/dbgappdomain.h b/src/debug/inc/dbgappdomain.h
index 70504c09ec..91d024be70 100644
--- a/src/debug/inc/dbgappdomain.h
+++ b/src/debug/inc/dbgappdomain.h
@@ -9,10 +9,6 @@
class AppDomain;
-void BeginThreadAffinityHelper();
-void EndThreadAffinityHelper();
-
-
// AppDomainInfo contains information about an AppDomain
// All pointers are for the left side, and we do not own any of the memory
struct AppDomainInfo
@@ -180,8 +176,6 @@ struct AppDomainEnumerationIPCBlock
*************************************************************************/
BOOL Lock()
{
- BeginThreadAffinityHelper();
-
DWORD dwRes = WaitForSingleObject(m_hMutex, 3000);
if (dwRes == WAIT_TIMEOUT)
{
@@ -218,8 +212,6 @@ struct AppDomainEnumerationIPCBlock
// Lock may or may not be valid at this point. Thus Release may fail,
// but we'll just ignore that.
ReleaseMutex(m_hMutex);
- EndThreadAffinityHelper();
-
}
/*************************************************************************
diff --git a/src/dlls/dbgshim/dbgshim.cpp b/src/dlls/dbgshim/dbgshim.cpp
index 5f15cabe97..39c966a3ce 100644
--- a/src/dlls/dbgshim/dbgshim.cpp
+++ b/src/dlls/dbgshim/dbgshim.cpp
@@ -1818,10 +1818,8 @@ CLRCreateInstance(
#if defined(FEATURE_CORESYSTEM)
GUID skuId = CLR_ID_ONECORE_CLR;
-#elif defined(FEATURE_CORECLR)
- GUID skuId = CLR_ID_CORECLR;
#else
- GUID skuId = CLR_ID_V4_DESKTOP;
+ GUID skuId = CLR_ID_CORECLR;
#endif
CLRDebuggingImpl *pDebuggingImpl = new CLRDebuggingImpl(skuId);
diff --git a/src/dlls/mscordac/CMakeLists.txt b/src/dlls/mscordac/CMakeLists.txt
index 8780db904d..afe5bea7d0 100644
--- a/src/dlls/mscordac/CMakeLists.txt
+++ b/src/dlls/mscordac/CMakeLists.txt
@@ -1,5 +1,4 @@
include(${CLR_DIR}/dac.cmake)
-
add_definitions(-DFEATURE_NO_HOST)
if(CLR_CMAKE_PLATFORM_UNIX)
@@ -7,7 +6,6 @@ if(CLR_CMAKE_PLATFORM_UNIX)
endif(CLR_CMAKE_PLATFORM_UNIX)
set(CLR_DAC_SOURCES
- mscordac.cpp
)
add_definitions(-DFX_VER_INTERNALNAME_STR=mscordaccore.dll)
@@ -20,11 +18,13 @@ if(WIN32)
mscordac.src
)
+ set(CURRENT_BINARY_DIR_FOR_CONFIG ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR})
+
#Preprocess exports definition file
- preprocess_def_file(${CMAKE_CURRENT_SOURCE_DIR}/${DEF_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/mscordac.def)
+ preprocess_def_file(${CMAKE_CURRENT_SOURCE_DIR}/${DEF_SOURCES} ${CURRENT_BINARY_DIR_FOR_CONFIG}/mscordac.def)
#create target to add file dependency on mscordac.def
- add_custom_target(mscordaccore_def DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/mscordac.def)
+ add_custom_target(mscordaccore_def DEPENDS ${CURRENT_BINARY_DIR_FOR_CONFIG}/mscordac.def)
# No library groups for Win32
set(START_LIBRARY_GROUP)
@@ -58,7 +58,11 @@ if(CLR_CMAKE_PLATFORM_DARWIN)
set(EXPORTS_LINKER_OPTION -Wl,-exported_symbols_list,${EXPORTS_FILE})
endif(CLR_CMAKE_PLATFORM_DARWIN)
-add_library_clr(mscordaccore SHARED ${CLR_DAC_SOURCES})
+# Create object library to enable creation of proper dependency of mscordaccore.exp on mscordac.obj and
+# mscordaccore on both the mscordaccore.exp and mscordac.obj.
+add_library(mscordacobj OBJECT mscordac.cpp)
+
+add_library_clr(mscordaccore SHARED ${CLR_DAC_SOURCES} $<TARGET_OBJECTS:mscordacobj>)
if(CLR_CMAKE_PLATFORM_UNIX)
add_custom_target(mscordaccore_exports DEPENDS ${EXPORTS_FILE})
@@ -93,15 +97,26 @@ if(WIN32)
# mscordac.def should be generated before mscordaccore.dll is built
add_dependencies(mscordaccore mscordaccore_def)
+ set(MSCORDAC_OBJ_PATH "${CMAKE_CURRENT_BINARY_DIR}/mscordacobj.dir/${CMAKE_CFG_INTDIR}/mscordac.obj")
+
# Generate export file
- add_custom_command(TARGET mscordaccore
- PRE_LINK
- COMMAND lib.exe /OUT:"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/mscordaccore.lib" /DEF:"${CMAKE_CURRENT_BINARY_DIR}/mscordac.def" "$<TARGET_FILE:daccess>" $<$<OR:$<CONFIG:Release>,$<CONFIG:Relwithdebinfo>>:/LTCG> ${STATIC_LIBRARY_FLAGS} "${CMAKE_CURRENT_BINARY_DIR}/mscordaccore.dir/$<CONFIG>/mscordac.obj"
+ add_custom_command(
+ DEPENDS mscordaccore_def "${CURRENT_BINARY_DIR_FOR_CONFIG}/mscordac.def" mscordacobj daccess
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/mscordaccore.exp
+ COMMAND lib.exe /OUT:"${CMAKE_CURRENT_BINARY_DIR}/mscordaccore.lib" /DEF:"${CURRENT_BINARY_DIR_FOR_CONFIG}/mscordac.def" "$<TARGET_FILE:daccess>" $<$<OR:$<CONFIG:Release>,$<CONFIG:Relwithdebinfo>>:/LTCG> ${STATIC_LIBRARY_FLAGS} ${MSCORDAC_OBJ_PATH}
COMMENT "Generating mscordaccore.exp export file"
)
+ set_source_files_properties(
+ ${CMAKE_CURRENT_BINARY_DIR}/mscordaccore.exp
+ PROPERTIES GENERATED TRUE
+ )
+
+ add_custom_target(mscordaccore_exp DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/mscordaccore.exp)
+ add_dependencies(mscordaccore mscordaccore_exp)
+
set(COREDAC_LIBRARIES
- ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/mscordaccore.exp # export file
+ ${CMAKE_CURRENT_BINARY_DIR}/mscordaccore.exp # export file
${COREDAC_LIBRARIES}
mdwinmd_dac
kernel32.lib
diff --git a/src/dlls/mscordac/GetFileVersion.dll b/src/dlls/mscordac/GetFileVersion.dll
deleted file mode 100644
index 4479d7cad7..0000000000
--- a/src/dlls/mscordac/GetFileVersion.dll
+++ /dev/null
Binary files differ
diff --git a/src/dlls/mscordbi/mscordbi.src b/src/dlls/mscordbi/mscordbi.src
index 0baa49537e..3b1f37720d 100644
--- a/src/dlls/mscordbi/mscordbi.src
+++ b/src/dlls/mscordbi/mscordbi.src
@@ -18,9 +18,7 @@ EXPORTS
OpenVirtualProcess private
OpenVirtualProcess2
-#ifdef FEATURE_CORECLR
CoreCLRCreateCordbObject private
-#endif // FEATURE_CORECLR
#if defined(FEATURE_DBGIPC_TRANSPORT_DI)
DllGetClassObject private
diff --git a/src/dlls/mscoree/coreclr/CMakeLists.txt b/src/dlls/mscoree/coreclr/CMakeLists.txt
index afd18d6c27..3144b5139f 100644
--- a/src/dlls/mscoree/coreclr/CMakeLists.txt
+++ b/src/dlls/mscoree/coreclr/CMakeLists.txt
@@ -159,23 +159,22 @@ if(WIN32)
endif()
add_custom_command(
- TARGET coreclr
- POST_BUILD
+ DEPENDS coreclr mscordaccore mscordbi ${CLR_DIR}/src/debug/daccess/daccess.cpp
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/inject_debug_resources.timestamp
COMMAND ${CMAKE_CXX_COMPILER} /P /EP /TP ${PREPROCESS_DEFINITIONS} ${INC_DIR} /Fi${CMAKE_CURRENT_BINARY_DIR}/daccess.i ${CLR_DIR}/src/debug/daccess/daccess.cpp
COMMAND ${BuildToolsDir}/dactablegen.exe /dac:${CMAKE_CURRENT_BINARY_DIR}/daccess.i /pdb:${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/coreclr.pdb /dll:$<TARGET_FILE:coreclr> /bin:${CMAKE_CURRENT_BINARY_DIR}/wks.bin
COMMAND ${BuildToolsDir}/InjectResource.exe /bin:${CMAKE_CURRENT_BINARY_DIR}/wks.bin /dll:$<TARGET_FILE:coreclr>
COMMAND ${BuildToolsDir}/GenClrDebugResource.exe /dac:$<TARGET_FILE:mscordaccore> /dbi:$<TARGET_FILE:mscordbi> /sku:onecoreclr /out:${CMAKE_CURRENT_BINARY_DIR}/clrDebugResource.bin
COMMAND ${BuildToolsDir}/InjectResource.exe /bin:${CMAKE_CURRENT_BINARY_DIR}/clrDebugResource.bin /dll:$<TARGET_FILE:coreclr> /name:CLRDEBUGINFO
- COMMENT Add dactable & debug resources to coreclr
- )
-else()
- add_custom_command(
- TARGET coreclr
- POST_BUILD
- VERBATIM
- COMMAND sh ${CLR_DIR}/src/pal/tools/gen-dactable-rva.sh $<TARGET_FILE:coreclr> ${GENERATED_INCLUDE_DIR}/dactablerva.h
- COMMENT Generating ${GENERATED_INCLUDE_DIR}/dactablerva.h
+ COMMAND ${BuildToolsDir}/InjectResource.exe /bin:${CMAKE_CURRENT_SOURCE_DIR}/dump_helper_resource.bin /dll:$<TARGET_FILE:coreclr> /name:MINIDUMP_AUXILIARY_PROVIDER
+ COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/inject_debug_resources.timestamp
+ COMMENT Add dactable, debug resources, and dump helper resources to coreclr
)
+
+ if(NOT DEFINED CLR_CROSS_COMPONENTS_BUILD)
+ add_custom_target(inject_debug_resources ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/inject_debug_resources.timestamp)
+ endif()
+
endif(WIN32)
# add the install targets
diff --git a/src/dlls/mscoree/coreclr/README.md b/src/dlls/mscoree/coreclr/README.md
new file mode 100644
index 0000000000..b33473bca4
--- /dev/null
+++ b/src/dlls/mscoree/coreclr/README.md
@@ -0,0 +1,7 @@
+dump\_helper\_resource.bin in this folder is a text file with a single 0 byte appended on the end using a hex-editor. It is unlikely it will need to be modified frequently if at all,
+but if that changes we can always create a little nicer tooling for it.
+
+dump\_helper\_resource.bin is used to populate the DUMP\_HELPER resource inside coreclr.dll on Windows. When an application crashes, Windows MinidumpWriteDump is planning to scan
+modules looking for this resource. The content of the resource is expected to be the name of a dll in the same folder, encoded in UTF8, null terminated, that implements the
+CLRDataCreateInterface function. For OS security purposes MinidumpWriteDump will do an authenticode signing check before loading the indicated binary, however if your build isn't
+signed you can get around this limitation by registering it at HKLM\Software\Microsoft\WindowsNT\CurrentVersion\MiniDumpAuxilliaryDlls. \ No newline at end of file
diff --git a/src/dlls/mscoree/coreclr/dump_helper_resource.bin b/src/dlls/mscoree/coreclr/dump_helper_resource.bin
new file mode 100644
index 0000000000..aa2d9eae1f
--- /dev/null
+++ b/src/dlls/mscoree/coreclr/dump_helper_resource.bin
Binary files differ
diff --git a/src/dlls/mscoree/mscoree.cpp b/src/dlls/mscoree/mscoree.cpp
index 8ec460eedd..f33f0955e4 100644
--- a/src/dlls/mscoree/mscoree.cpp
+++ b/src/dlls/mscoree/mscoree.cpp
@@ -383,30 +383,6 @@ STDAPI ReOpenMetaDataWithMemoryEx(
return hr;
}
-#ifdef FEATURE_FUSION
-// ---------------------------------------------------------------------------
-// %%Function: GetAssemblyMDImport
-// This function gets the IMDAssemblyImport given the filename
-// ---------------------------------------------------------------------------
-STDAPI GetAssemblyMDImport( // Return code.
- LPCWSTR szFileName, // [in] The scope to open.
- REFIID riid, // [in] The interface desired.
- IUnknown **ppIUnk) // [out] Return interface on success.
-{
- CONTRACTL
- {
- NOTHROW;
- ENTRY_POINT;
- }
- CONTRACTL_END;
- HRESULT hr=S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- hr=GetAssemblyMDInternalImport(szFileName, riid, ppIUnk);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-#endif
#ifndef CROSSGEN_COMPILE
// ---------------------------------------------------------------------------
diff --git a/src/dlls/mscoree/mscorwks_ntdef.src b/src/dlls/mscoree/mscorwks_ntdef.src
index 13656d7aca..8115475418 100644
--- a/src/dlls/mscoree/mscorwks_ntdef.src
+++ b/src/dlls/mscoree/mscorwks_ntdef.src
@@ -7,7 +7,6 @@ EXPORTS
; Common exports
;
-#ifdef FEATURE_CORECLR
GetCLRRuntimeHost
@@ -29,170 +28,3 @@ EXPORTS
GetMetaDataInternalInterfaceFromPublic
GetMetaDataPublicInterfaceFromInternal
-#else //FEATURE_CORECLR
-
-; VM
- DllGetClassObjectInternal private
- DllGetActivationFactoryImpl private
- GetClassActivatorForApplicationImpl private
- MetaDataGetDispenser
- GetMetaDataInternalInterface
- GetMetaDataInternalInterfaceFromPublic
- GetMetaDataPublicInterfaceFromInternal
- _CorExeMain2
- _CorDllMain
- CoInitializeEE
- CoUninitializeEE
- CoInitializeCor
- CoUninitializeCor
- PostErrorVA
-
- LoadStringRC @22
- ReOpenMetaDataWithMemory @23
-
- LoadStringRCEx
- ReOpenMetaDataWithMemoryEx private
- TranslateSecurityAttributes private
- GetPermissionRequests
- CorExitProcess
-#ifdef FEATURE_CLICKONCE
- CorLaunchApplication
-#endif
-
- CorMarkThreadInThreadPool
-
- LogHelp_LogAssert private
- LogHelp_NoGuiOnAssert private
- LogHelp_TerminateOnAssert private
-
- GetPrivateContextsPerfCounters private
-
- GetAssemblyMDImport private
-
- IEE private
-
-#ifdef FEATURE_FUSION
-; Fusion
- GetCachePath
- CreateAssemblyNameObject
- CreateApplicationContext
- CreateAssemblyCache
- CreateAssemblyEnum
- CreateHistoryReader
- LookupHistoryAssembly
- GetHistoryFileDirectory
- PreBindAssembly
- PreBindAssemblyEx
- SetMSIHandleForLogging
- NukeDownloadedCache
- ClearDownloadCache
- GetCLRIdentityManager
- CreateAssemblyConfigCookie
- DestroyAssemblyConfigCookie
- CompareAssemblyIdentity
- CompareAssemblyIdentityWithConfig
- InitializeFusion private
- CopyPDBs private
- DeleteShadowCache private
-#endif
-; Strong Name
- StrongNameErrorInfo
- StrongNameFreeBuffer
- StrongNameKeyGen
- StrongNameKeyGenEx
- StrongNameKeyInstall
- StrongNameKeyDelete
- StrongNameGetPublicKey
- StrongNameSignatureGeneration
- StrongNameSignatureGenerationEx
- StrongNameTokenFromAssembly
- StrongNameTokenFromAssemblyEx
- StrongNameTokenFromPublicKey
- StrongNameSignatureVerification
- StrongNameCompareAssemblies
- StrongNameHashSize
- StrongNameSignatureSize
- StrongNameSignatureVerificationEx
- GetHashFromAssemblyFile
- GetHashFromAssemblyFileW
- GetHashFromBlob
- GetHashFromFile
- GetHashFromFileW
- GetHashFromHandle
- StrongNameSignatureVerificationFromImage
- StrongNameGetBlob
- StrongNameGetBlobFromImage
- StrongNameSignatureVerificationEx2
- StrongNameGetPublicKeyEx
- StrongNameDigestGenerate
- StrongNameDigestSign
- StrongNameDigestEmbed
-
-; VM
-#ifdef FEATURE_COMINTEROP
- DllCanUnloadNowInternal private
-#endif
-#ifdef FEATURE_COMINTEROP_REGISTRATION
- ClrCreateManagedInstance
- DllRegisterServerInternal private
- DllUnregisterServerInternal private
- EEDllRegisterServer private
- EEDllUnregisterServer private
-#endif
- SetRuntimeInfo
- _CorExeMain
-#ifdef FEATURE_MIXEDMODE
- CorDllMainForThunk private
-#endif
- CoEEShutDownCOM
-#ifdef FEATURE_PREJIT
- NGenCreateNGenWorker
- LegacyNGenCreateZapper
- LegacyNGenFreeZapper
- LegacyNGenTryEnumerateFusionCache
- LegacyNGenCompile
-#endif
- GetAddrOfContractShutoffFlag private
- GetCLRFunction private
-
-#ifdef PROFILING_SUPPORTED
- AttachProfiler private
-#endif // PROFILING_SUPPORTED
-
-#ifdef FEATURE_FUSION
-; Fusion
- CreateInstallReferenceEnum
- InstallCustomModule
- GetAssemblyIdentityFromFile
- GetIdentityAuthority private
- ParseManifest private
- CreateCMSFromXml private
- GetAppIdAuthority private
- GetUserStore private
- CreateActContext private
- GetUserStateManager private
-; CreateCMSFromXmlInternal private
-; GetUserStoreInternal private
-; ParseManifestInternal private
-; CreateActContextInternal private
-; GetUserStateManagerInternal private
- CertCreateAuthenticodeLicense private
- CertTimestampAuthenticodeLicense private
- CertVerifyAuthenticodeLicense private
- CertFreeAuthenticodeSignerInfo private
- CertFreeAuthenticodeTimestamperInfo private
- _AxlPublicKeyBlobToPublicKeyToken private
- _AxlRSAKeyValueToPublicKeyToken private
- _AxlGetIssuerPublicKeyHash private
-#endif // FEATURE_FUSION
-
-;
-; win64 common
-;
-#ifdef _WIN64
- GetRuntimeStackWalkInfo
-#endif
-
- Nirvana_Dummy @24 NONAME PRIVATE
-
-#endif //FEATURE_CORECLR
diff --git a/src/dlls/mscorrc/fuslog.rc b/src/dlls/mscorrc/fuslog.rc
index 8a106fa084..c02d1b692b 100644
--- a/src/dlls/mscorrc/fuslog.rc
+++ b/src/dlls/mscorrc/fuslog.rc
@@ -3,295 +3,6 @@
// See the LICENSE file in the project root for more information.
#include "fusres.h"
-#ifdef FEATURE_FUSION
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_ASSEMBLY_CREATION_FAILURE L"WRN: Found match in cache, but cannot create assembly from the cache information."
- ID_FUSLOG_ASSEMBLY_LOOKUP_FAILURE L"LOG: GAC Lookup was unsuccessful."
- ID_FUSLOG_ISEQUAL_DIFF_NAME L"WRN: Comparing the assembly name resulted in the mismatch: NAME"
- ID_FUSLOG_ISEQUAL_DIFF_VERSION_MAJOR L"WRN: Comparing the assembly name resulted in the mismatch: Major Version"
- ID_FUSLOG_ISEQUAL_DIFF_VERSION_MINOR L"WRN: Comparing the assembly name resulted in the mismatch: Minor Version"
- ID_FUSLOG_ISEQUAL_DIFF_VERSION_REVISION L"WRN: Comparing the assembly name resulted in the mismatch: Revision Number"
- ID_FUSLOG_ISEQUAL_DIFF_VERSION_BUILD L"WRN: Comparing the assembly name resulted in the mismatch: Build Number"
- ID_FUSLOG_ISEQUAL_DIFF_PUBLIC_KEY_TOKEN L"WRN: Comparing the assembly name resulted in the mismatch: PUBLIC KEY TOKEN"
- ID_FUSLOG_ISEQUAL_DIFF_CULTURE L"WRN: Comparing the assembly name resulted in the mismatch: CULTURE"
- ID_FUSLOG_ISEQUAL_DIFF_CUSTOM L"WRN: Comparing the assembly name resulted in the mismatch: CUSTOM"
- ID_FUSLOG_CANONICALIZATION_ERROR L"ERR: Fatal error occurred attempting to canonicalize the codebase for this bind."
-END
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_POLICY_CACHE_FAILURE L"LOG: Unable to prepare policy cache object."
- ID_FUSLOG_APP_CFG_PIGGYBACK L"LOG: Download of application configuration file is already in progress."
- ID_FUSLOG_PREBIND_INFO_START L"=== Pre-bind state information ==="
- ID_FUSLOG_PREBIND_INFO_DISPLAY_NAME L"LOG: DisplayName = %ws\n (%ws)"
- ID_FUSLOG_PREBIND_INFO_WHERE_REF L"LOG: Where-ref bind. Location = %ws"
- ID_FUSLOG_PREBIND_INFO_APPBASE L"LOG: Appbase = %ws"
- ID_FUSLOG_PREBIND_INFO_PRIVATE_PATH L"LOG: Initial PrivatePath = %ws"
- ID_FUSLOG_PREBIND_INFO_DYNAMIC_BASE L"LOG: Dynamic Base = %ws"
- ID_FUSLOG_PREBIND_INFO_CACHE_BASE L"LOG: Cache Base = %ws"
- ID_FUSLOG_PREBIND_INFO_APP_NAME L"LOG: AppName = %ws"
- ID_FUSLOG_PREBIND_INFO_END L"==="
- ID_FUSLOG_APP_CFG_DOWNLOAD L"LOG: Attempting application configuration file download."
- ID_FUSLOG_APP_CFG_DOWNLOAD_LOCATION L"LOG: Download of application configuration file was attempted from %ws."
- ID_FUSLOG_CFG_NOT_EXIST L"LOG: Configuration file %ws does not exist."
- ID_FUSLOG_APP_CFG_FOUND L"LOG: Found application configuration file (%ws)."
-END
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_DEVOVERRIDE_REF_DEF_MISMATCH L"LOG: Found assembly in DEVOVERRIDE location [%ws], but the assembly reference did not match the assembly definition found."
- ID_FUSLOG_DEVOVERRIDE_SIGNATURE_CHECK_FAILED L"LOG: Found assembly in DEVOVERRIDE location [%ws], but signature validation failed."
- ID_FUSLOG_XML_PRIVATE_ASM_REDIRECT L"WRN: Binding redirects specified for assemblies without strong names are ignored."
- ID_FUSLOG_XML_PARSE_ERROR_CODE L"ERR: There was an error parsing XML (hr = 0x%x)."
- ID_FUSLOG_XML_ASSEMBLYIDENTITY_MISSING_NAME L"WRN: The assemblyIdentity was not processed because the name attribute was missing."
- ID_FUSLOG_XML_BINDINGREDIRECT_INSUFFICIENT_DATA L"WRN: bindingRedirect tag not processed due to insufficient data."
- ID_FUSLOG_XML_CODEBASE_HREF_MISSING L"WRN: codeBase tag not processed because href not present."
- ID_FUSLOG_XML_MULTIPLE_IDENTITIES L"WRN: Invalid XML. Encountered more than 1 assemblyIdentity inside single dependentAssembly. Ignoring."
- ID_FUSLOG_PRIVATE_PATH_DUPLICATE L"WRN: Private path set. Ignoring duplicate entry."
- ID_FUSLOG_POLICY_NOT_APPLIED L"LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind)."
- ID_FUSLOG_NO_APP_CONFIG_FILE L"LOG: No application configuration file found."
- ID_FUSLOG_APP_CONFIG_FILE L"LOG: Using application configuration file: %ws"
- ID_FUSLOG_HOST_CONFIG_FILE L"LOG: Using host configuration file: %ws"
- ID_FUSLOG_HOST_CONFIG_FILE_MISSING L"LOG: Host configuration file not found."
- ID_FUSLOG_XML_INVALID_PROCESSORARCHITECTURE L"WRN: Invalid processor architecture is specified in assemblyIdentity. Valid processor architectures are neutral/x86/IA64/AMD64."
-END
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_HOST_CFG_REDIRECT L"LOG: Redirect found in host configuration file: %ws redirected to %ws."
- ID_FUSLOG_HOST_CFG_NO_REDIRECT L"LOG: No redirect found in host configuration file."
- ID_FUSLOG_APP_CFG_REDIRECT L"LOG: Redirect found in application configuration file: %ws redirected to %ws."
- ID_FUSLOG_APP_CFG_SAFE_MODE L"LOG: Safe mode is set (publisher policy disallowed)."
- ID_FUSLOG_PUB_CFG_MISSING L"LOG: Publisher policy file is not found."
- ID_FUSLOG_PUB_CFG_FOUND L"LOG: Publisher policy file is found at %ws."
- ID_FUSLOG_PUB_CFG_REDIRECT L"LOG: Publisher policy file redirect is found: %ws redirected to %ws."
- ID_FUSLOG_PUBLISHER_POLICY_CONFIG_MISSING L"ERR: Publisher policy assembly is found, but there is no config file."
- ID_FUSLOG_MACHINE_CFG_MISSING L"LOG: Machine configuration file does not exist at %ws."
- ID_FUSLOG_MACHINE_CFG_FOUND L"LOG: Using machine configuration file from %ws."
- ID_FUSLOG_MACHINE_CFG_REDIRECT L"LOG: Machine configuration policy file redirect found: %ws redirected to %ws."
- ID_FUSLOG_REDIRECT_NO_CODEBASE L"WRN: Binding redirect encountered, but could not retrieve codebase."
- ID_FUSLOG_POLICY_CODEBASE L"LOG: Using codebase from policy file: %ws."
- ID_FUSLOG_POST_POLICY_REFERENCE L"LOG: Post-policy reference: %ws"
- ID_FUSLOG_APPLY_POLICY_FAILED L"ERR: Failed to apply policy (hr = 0x%x)."
- ID_FUSLOG_CFG_PRIVATE_PATH L"LOG: Private path hint found in configuration file: %s."
- ID_FUSLOG_CAB_ASM_NOT_FOUND L"LOG: Unable to find target assembly in CAB file."
-END
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_XML_PARSE_ERROR_FILE L"WRN: Error parsing XML file %ws. Ignoring."
- ID_FUSLOG_CODEBASE_RETRIEVE_FAILURE L"ERR: A fatal error occurred when retrieving next codebase for download (hr = 0x%x)."
- ID_FUSLOG_ATTEMPT_NEW_DOWNLOAD L"LOG: Attempting download of new URL %ws."
- ID_FUSLOG_LOADER_PERMISSION_CHECK_FAILURE L"ERR: Loader location access permission check failed for URL %ws (hr = 0x%x)."
- ID_FUSLOG_PROBE_FAIL_BUT_ASM_FOUND L"LOG: Probing in application directory failed, but assembly bind was still able to complete."
- ID_FUSLOG_ASM_SETUP_FAILURE L"ERR: Failed to complete setup of assembly (hr = 0x%x). Probing terminated."
- ID_FUSLOG_PREDOWNLOAD_FAILURE L"ERR: Unrecoverable error occurred during pre-download check (hr = 0x%x)."
- ID_FUSLOG_URLMON_MISSING L"WRN: Unable to find URLMON.DLL. Assemblies cannot be downloaded."
- ID_FUSLOG_DOWNLOAD_PIGGYBACK L"LOG: Duplicate download found. Re-using the download in progress."
- ID_FUSLOG_DOWNLOAD_SUCCESS L"LOG: Assembly download was successful. Attempting setup of file: %ws"
- ID_FUSLOG_LAST_MOD_FAILURE L"ERR: Unable to extract last modified time from %ws."
- ID_FUSLOG_MSI_CODEBASE_UNSUPPORTED L"WRN: Current version does not support CODEBASEs to .MSI files. Setup is unable to complete."
- ID_FUSLOG_FAILED_PROBING L"LOG: All probing URLs attempted and failed."
- ID_FUSLOG_PARTIAL_GAC_UNSUPPORTED L"ERR: Partial binds to assemblies in the global assembly cache are not supported."
- ID_FUSLOG_GAC_LOOKUP_SUCCESS L"LOG: Lookup in global assembly cache succeeded."
- ID_FUSLOG_MSI_INSTALL_ATTEMPT L"LOG: Attempting to install assembly using Windows Installer."
- ID_FUSLOG_PREVIOUS_FAILED L"LOG: The same bind was seen before, and was failed with hr = 0x%x."
-END
-
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_MSI_ASM_INSTALL_SUCCESS L"LOG: Successfully installed assembly using Windows Installer."
- ID_FUSLOG_POLICY_CACHE_INSERT_FAILURE L"ERR: Error inserting entry into policy cache."
- ID_FUSLOG_MSI_SUCCESS_FUSION_SETUP_FAIL L"WRN: Windows Installer was able to provide the requested assembly, but setup of resulting file failed."
- ID_FUSLOG_SETUP_RUN_FROM_SOURCE L"LOG: Entering run-from-source setup phase."
- ID_FUSLOG_SETUP_RUN_FROM_SOURCE_FAILURE L"ERR: Run-from-source setup phase failed with hr = 0x%x."
- ID_FUSLOG_MODULE_INTEGRITY_CHECK_FAILURE L"ERR: Module integrity check failed."
- ID_FUSLOG_SETUP_DOWNLOAD_CACHE L"LOG: Entering download cache setup phase."
- ID_FUSLOG_REF_DEF_MISMATCH L"ERR: The assembly reference did not match the assembly definition found."
- ID_FUSLOG_SETUP_FAILURE L"ERR: Setup failed with hr = 0x%x."
- ID_FUSLOG_IGNORE_INVALID_PROBE L"WRN: Not probing location %ws, because the location falls outside of the appbase."
- ID_FUSLOG_CACHE_LOOKUP_SUCCESS L"LOG: Found assembly by looking in the GAC."
- ID_FUSLOG_PREJIT_NOT_FOUND L"ERR: Expected to find a pre-jit assembly in cache, but assembly was not found."
- ID_FUSLOG_CODEBASE_CONSTRUCTION_FAILURE L"ERR: Error occurred constructing the probing codebase list."
- ID_FUSLOG_CODEBASE_UNAVAILABLE L"ERR: No codebases found to download from."
- ID_FUSLOG_DOWNLOAD_CACHE_LOOKUP_SUCCESS L"LOG: Found assembly by looking in the download cache."
- ID_FUSLOG_SETUP_CAB L"LOG: Setting up CAB file."
-END
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_TEMP_DIR_CREATE_FAILURE L"ERR: Unable to create a temporary directory (hr = 0x%x)."
- ID_FUSLOG_CAB_EXTRACT_FAILURE L"ERR: Unable to extract the CAB file (hr = 0x%x)."
- ID_FUSLOG_CAB_ASM_FOUND L"LOG: Found matching assembly from CAB file: %ws."
- ID_FUSLOG_CAB_EXTRACT_SUCCESS L"LOG: Successfully extracted assembly from CAB file."
- ID_FUSLOG_DOWNLOAD_CACHE_CREATE_FAILURE L"ERR: Unable to create assembly in download cache (hr = 0x%x)."
- ID_FUSLOG_CAB_ASM_NOT_FOUND_EXTRACTED L"LOG: Unable to find assembly from extracted CAB location: %ws."
- ID_FUSLOG_TEMP_DIR_REMOVE_FAILURE L"ERR: Unable to remove temporary directory: %ws."
- ID_FUSLOG_MANIFEST_EXTRACT_FAILURE L"ERR: Error extracting manifest import from file (hr = 0x%x)."
- ID_FUSLOG_NAME_DEF_EXTRACT_FAILURE L"ERR: Error retrieving assembly name definition from manifest import (hr = 0x%x)."
- ID_FUSLOG_INVALID_ASM_PLATFORM L"ERR: Invalid assembly platform or ContentType in file (hr = 0x%x)."
- ID_FUSLOG_INVALID_PRIVATE_ASM_LOCATION L"LOG: Private assembly found in invalid location."
- ID_FUSLOG_PARTIAL_ASM_IN_APP_DIR L"LOG: A partially-specified assembly bind succeeded from the application directory. Need to re-apply policy."
- ID_FUSLOG_LOADFROM_DEFAULT_MISMATCH L"LOG: Assembly in default load context is loaded from a different location than the one in LoadFrom context."
- ID_FUSLOG_WHERE_REF_APPLY_POLICY L"LOG: Re-apply policy for where-ref bind."
- ID_FUSLOG_WHERE_REF_GAC_MATCH L"LOG: Codebase matches assembly in GAC."
- ID_FUSLOG_WHERE_REF_GAC_MISMATCH L"LOG: Codebase does not match assembly in GAC."
- ID_FUSLOG_WHERE_REF_LOAD_CONTEXT_MATCH L"LOG: Where-ref bind Codebase matches what is found in default context. Keep the result in default context."
- ID_FUSLOG_WHERE_REF_LOAD_CONTEXT_MISMATCH L"LOG: Where-ref bind Codebase does not match what is found in default context. Keep the result in LoadFrom context."
- ID_FUSLOG_REPROBE_REQUIRED L"LOG: The post-policy assembly reference requires probing again."
- ID_FUSLOG_SWITCH_TO_DEFAULT_CONTEXT L"LOG: Switch from LoadFrom context to default context."
- ID_FUSLOG_SWITCH_TO_LOADFROM_CONTEXT L"LOG: Switch from default context to LoadFrom context."
- ID_FUSLOG_DUPLICATE_ASM_COMMIT L"WRN: A duplicate assembly was found while copying the assembly item to the cache."
- ID_FUSLOG_COPY_FILE_FAILURE L"ERR: Unable to copy file to cache location."
- ID_FUSLOG_INVALID_LOCATION_INFO L"ERR: The private assembly was located outside of appbase. Source Url = %ws."
-END
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_ASYNC_CFG_DOWNLOAD_SUCCESS L"LOG: The asynchronous application configuration file download successful. Download location %ws"
- ID_FUSLOG_ASYNC_CFG_DOWNLOAD_FAILURE L"LOG: The asynchronous configuration file download unsuccessful."
- ID_FUSLOG_CACHE_ITEM_CREATE_FAILURE L"ERR: Unable to create assembly cache item (hr = 0x%x)."
- ID_FUSLOG_CACHE_ITEM_COMMIT_FAILURE L"ERR: Unable to commit cache item. Attempt to put assembly in cache unsuccessful (hr = 0x%x)."
- ID_FUSLOG_LOADCTX_HIT L"LOG: Reusing an assembly instance that was previously loaded (%ws)."
- ID_FUSLOG_BIND_SUCCESS L"LOG: Binding succeeds. Returns assembly from %ws."
- ID_FUSLOG_ASSEMBLY_NAME_DEF L"LOG: Assembly Name is: %ws"
-END
-
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_OPERATION_SUCCESSFUL L"The operation was successful."
- ID_FUSLOG_OPERATION_FAILED L"The operation failed."
- ID_FUSLOG_DETAILED_LOG L"--- A detailed error log follows. \n"
- ID_FUSLOG_HEADER_TEXT L"*** Assembly Binder Log Entry "
- ID_FUSLOG_BIND_RESULT_TEXT L"Bind result: hr = 0x%x. %ws"
- ID_FUSLOG_NO_DESCRIPTION L"No description available.\n"
- ID_FUSLOG_FUSION_DLL_PATH L"Assembly manager loaded from: "
- ID_FUSLOG_EXECUTABLE L"Running under executable "
- ID_FUSLOG_QUALIFIED_ASSEMBLY L"LOG: Partial reference qualified from config file. New reference: %ws."
- ID_FUSLOG_CALLING_ASSEMBLY L"Calling assembly : %ws."
- ID_FUSLOG_CFG_ASSEMBLY_STORE L"LOG: AssemblyStore path = %ws"
- END
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_PARTIAL_BIND_DEBUG L"ERR: Partial GAC binds disallowed. [Partial Name = %ws : Calling Assembly = %ws : EXE Name = %ws]."
- ID_FUSLOG_DISALLOW_APPLY_PUB_POLICY L"WRN: Application configuration file safe mode disallowed."
- ID_FUSLOG_DISALLOW_APP_BINDING_REDIRECTS L"WRN: Application configuration file binding redirects disallowed."
- ID_FUSLOG_PREBIND_INFO_DEVOVERRIDE_GLOBAL L"LOG: Global DEVOVERRIDE path = %ws"
- ID_FUSLOG_PREBIND_INFO_DEVOVERRIDE_LOCAL L"LOG: Local DEVOVERRIDE path = %ws"
- ID_FUSLOG_DEVOVERRIDE_FOUND L"LOG: Found assembly in DEVOVERRIDE path %ws"
- ID_FUSLOG_DEVOVERRIDE_MISS L"LOG: Did not find assembly in DEVOVERRIDE path %ws"
- ID_FUSLOG_PREBIND_INFO_DEVPATH L"LOG: DEVPATH = %ws"
- ID_FUSLOG_ASSEMBLYSTORE_DUPLICATE L"WRN: assemblyStore has already been set. Ignoring duplicate entry."
- ID_FUSLOG_DEVOVERRIDE_DUPLICATE L"WRN: devOverridePath has already been set. Ignoring duplicate entry."
- ID_FUSLOG_DISALLOW_APP_BASE_PROBING L"WRN: App base probing is disallowed."
- ID_FUSLOG_INSPECTION_ONLY L"LOG: This is an inspection only bind."
- ID_FUSLOG_SHOW_START_LOAD_CONTEXT L"LOG: This bind starts in %ws load context."
- ID_FUSLOG_SHOW_RESULT_LOAD_CONTEXT L"LOG: Assembly is loaded in %ws load context."
- ID_FUSLOG_LOAD_CONTEXT_PA_MISMATCH L"ERR: An assembly with different processor architecture is already loaded."
- ID_FUSLOG_INCOMPATIBLE_PROCESSOR_ARCHITECTURE L"ERR: Attempt to load an assembly with ProcessorArchitecture incompatible with the running process."
-END
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_ISEQUAL_DIFF_RETARGET L"WRN: Comparing the assembly name resulted in the mismatch: Retargetable flag"
- ID_FUSLOG_ISEQUAL_DIFF_PROCESSOR_ARCHITECTURE L"WRN: Comparing the assembly name resulted in mismatch of Processor Architecture: Ref %ws, Def %ws."
- ID_FUSLOG_ISEQUAL_DIFF_CONTENT_TYPE L"WRN: Comparing the assembly name resulted in the mismatch: Content Type"
- ID_FUSLOG_RETARGET_CFG_MISSING L"LOG: Retarget policy is not found."
- ID_FUSLOG_RETARGET_CFG_NAME_REDIRECT L"LOG: Name redirect found in retarget config: %ws redirected to %ws."
- ID_FUSLOG_RETARGET_CFG_VER_REDIRECT L"LOG: Version redirect found in retarget config: %ws redirected to %ws."
- ID_FUSLOG_RETARGET_CFG_PKT_REDIRECT L"LOG: PublicKeyToken redirect found in retarget config: %ws redirected to %ws."
- ID_FUSLOG_XML_PARSE_ERROR_MEMORY L"ERR: Parse XML memory stream failed."
- ID_FUSLOG_XML_BINDINGRETARGET_INSUFFICIENT_DATA L"ERR: bindingRetarget tag is not processed due to insufficient data."
- ID_FUSLOG_FX_CFG_MISSING L"Log: framework config is not found."
- ID_FUSLOG_FX_CFG_VER_REDIRECT L"LOG: Version redirect found in framework config: %ws redirected to %ws."
- ID_FUSLOG_APPLIESTO_DUPLICATE L"WRN: appliesTo has already been set. Ignoring duplicate appliesTo."
- ID_FUSLOG_PORTABILITY_CFG_NAME_REDIRECT L"LOG: Name redirect found in portability config: %ws redirected to %ws."
- ID_FUSLOG_PORTABILITY_CFG_VER_REDIRECT L"LOG: Version redirect found in portability config: %ws redirected to %ws."
- ID_FUSLOG_PORTABILITY_CFG_PKT_REDIRECT L"LOG: PublicKeyToken redirect found in portability config: %ws redirected to %ws."
- ID_FUSLOG_WARNING_SUPPORTPORTABILITY_MISSING_PKT L"WRN: supportPortability tag is not processed due to missing PKT attribute."
- ID_FUSLOG_WARNING_SUPPORTPORTABILITY_MISSING_ENABLE L"WRN: supportPortability tag is not processed due to missing enable attribute."
- ID_FUSLOG_WARNING_SUPPORTPORTABILITY_INVALID_ENABLE L"WRN: supportPortability tag is not processed due to enable attribute not being 'true' or 'false'."
-
-END
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_LOADCTX_HIT_HOST L"LOG: Reusing a host assembly instance that was previously loaded."
- ID_FUSLOG_HOST_RESOLVED L"LOG: Assembly binding is resolved by the host."
- ID_FUSLOG_ADMIN_CFG_POLICY_CODEBASE L"LOG: Codebase hint found in machine config file: %ws"
- ID_FUSLOG_PROCESSOR_ARCHITECTURE_LOCKED L"LOG: ProcessorArchitecture is locked to %ws."
- ID_FUSLOG_CHECK_HOST L"LOG: Fusion is hosted. Check host about this assembly."
- ID_FUSLOG_NOT_IN_CLR_LOADED_LIST L"LOG: Assembly is not in CLR Loaded list. Asking host assembly store."
- ID_FUSLOG_IN_CLR_LOADED_LIST L"LOG: Assembly is in CLR Loaded list. Proceed to normal probing."
- ID_FUSLOG_HOST_STORE_NOT_AVAILABLE L"WRN: Host did not provide an assembly store."
- ID_FUSLOG_HOST_STORE_RESOLVE_TRY L"LOG: Try host assembly store with assembly %ws."
- ID_FUSLOG_HOST_STORE_RESOLVE_FAILED L"WRN: Host assembly store does not contain this assembly."
- ID_FUSLOG_HOST_STORE_PARTIAL_NAME_SKIP L"LOG: Input is partial name. Skip host assembly store lookup."
- ID_FUSLOG_HOST_GAC_ASM_MISMATCH L"WRN: The assembly returned from host store has different signature from the one in GAC."
- ID_FUSLOG_HOST_RESULT L"LOG: Host store returns assembly stream with id = %I64u, context = %I64u."
- ID_FUSLOG_HOST_NO_DEBUG_STREAM L"LOG: Host store does not provide debug stream."
-END
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_EXPLICIT_BIND_IJW L"LOG: IJW explicit bind. File path:%ws."
- ID_FUSLOG_EXPLICIT_BIND_EXE L"LOG: EXE explicit bind. File path:%ws."
- ID_FUSLOG_EXPLICIT_BIND_IJW_BIND_FAIL L"ERR: IJW assembly bind failure. hr = 0x%x."
- ID_FUSLOG_EXPLICIT_BIND_IJW_PATH_DIFF L"LOG: IJW assembly bind returned a different path: %ws. Use the file provided."
- ID_FUSLOG_EXPLICIT_BIND_IJW_PATH_MATCH L"LOG: IJW assembly bind returned the same manifest path."
- ID_FUSLOG_EXPLICIT_BIND_IJW_NOT_FOUND L"LOG: IJW assembly bind returned file not found."
- ID_FUSLOG_EXPLICIT_BIND_EXE_LOADCONTEXT_COLLISION L"ERR: Assembly with the same identity has already been loaded."
-END
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_LOG_TURNED_OFF L"WRN: Assembly binding logging is turned OFF."
- ID_FUSLOG_LOG_TURN_ON_HKLM L"To enable assembly bind failure logging, set the registry value [HKLM\\Software\\Microsoft\\Fusion!EnableLog] (DWORD) to 1."
- ID_FUSLOG_LOG_PERF_WARNING L"Note: There is some performance penalty associated with assembly bind failure logging."
- ID_FUSLOG_LOG_TURN_OFF_HKLM L"To turn this feature off, remove the registry value [HKLM\\Software\\Microsoft\\Fusion!EnableLog]."
- ID_FUSLOG_UNSUPPORTED_LINKED_CONFIGURATION L"ERR: Unsupported linked configuration location: %ws"
- ID_FUSLOG_LINKED_CONFIGURATION_PARSE_ERROR L"ERR: Error processing linked configurations (hr = 0x%x)"
- ID_FUSLOG_LINKED_CONFIGURATION_DUPLICATE L"WRN: Ignoring duplicate linked configuration"
- ID_FUSLOG_PROCESSING_LINKED_CONFIGURATION L"LOG: Processing linked configuration: %ws"
- ID_FUSLOG_MISSING_CACHE_FILE L"ERR: Downloaded file was not cached. The web server may be configured to expire content immediately."
- ID_FUSLOG_NO_PARTIAL_NAME_FOR_HOST_APPBASE_COMMON_ASM L"ERR: Partial Name Binding is not allowed when the same assembly exists in both the host assembly store and application base."
-END
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_WARNING_PARTIAL_NAME_HEADER L"WRN: Partial binding information was supplied for an assembly:"
- ID_FUSLOG_WARNING_PARTIAL_NAME_DETAIL L"WRN: A partial bind occurs when only part of the assembly display name is provided.\r\nWRN: This might result in the binder loading an incorrect assembly.\r\nWRN: It is recommended to provide a fully specified textual identity for the assembly,\r\nWRN: that consists of the simple name, version, culture, and public key token.\r\nWRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue."
- ID_FUSLOG_WARNING_PARTIAL_NAME_INSTANCE L"WRN: Assembly Name: %s | Domain ID: %d"
- ID_FUSLOG_WARNING_MULTIPLE_VERSIONS_HEADER L"WRN: Multiple versions of the same assembly were loaded into one context of an application domain:"
- ID_FUSLOG_WARNING_MULTIPLE_VERSIONS_DETAIL L"WRN: This might lead to runtime failures.\r\nWRN: It is recommended that you remove the dependency on multiple versions, and change the app.config file to point to the required version of the assembly only.\r\nWRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information."
- ID_FUSLOG_WARNING_MULTIPLE_VERSIONS_INSTANCE L"WRN: Context: %s | Domain ID: %d | Assembly Name: %s"
- ID_FUSLOG_WARNING_MULTIPLE_CONTEXTS_HEADER L"WRN: The same assembly was loaded into multiple contexts of an application domain:"
- ID_FUSLOG_WARNING_MULTIPLE_CONTEXTS_DETAIL L"WRN: This might lead to runtime failures.\r\nWRN: It is recommended to inspect your application on whether this is intentional or not.\r\nWRN: See whitepaper http://go.microsoft.com/fwlink/?LinkId=109270 for more information and common solutions to this issue."
-END
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_BINDING_STATUS_BEGIN L"BEGIN : %s"
- ID_FUSLOG_BINDING_STATUS_END L"END"
- ID_FUSLOG_BINDING_STATUS_END_HR L"END : %s"
- ID_FUSLOG_BINDING_STATUS_NATIVE_DEPENDENCY L"Native image dependency bind."
- ID_FUSLOG_BINDING_STATUS_IMMERSIVE L"Immersive bind."
- ID_FUSLOG_BINDING_STATUS_FRAMEWORK L"Framework bind."
- ID_FUSLOG_BINDING_STATUS_FX_ASSEMBLY_BLOCKED L"Found .NET Framework assembly is not supported in AppX."
- ID_FUSLOG_BINDING_STATUS_LOAD_FILE L"Assembly.LoadFile bind."
- ID_FUSLOG_BINDING_STATUS_WINRT L"Windows Runtime Type bind."
- ID_FUSLOG_BINDING_DEPENDENCY_NAME L"Dependency name: %s"
- ID_FUSLOG_BINDING_STATUS_FOUND L"Found: %s"
- ID_FUSLOG_BINDING_STATUS_IL_IMAGE L"IL image bind."
- ID_FUSLOG_BINDING_STATUS_NATIVE_IMAGE L"Native image bind."
-END
-
-#else // FEATURE_FUSION
STRINGTABLE DISCARDABLE
BEGIN
@@ -346,4 +57,3 @@ BEGIN
ID_FUSLOG_BINDING_HEADER_END L"--- A detailed log follows."
END
-#endif // FEATURE_FUSION
diff --git a/src/dlls/mscorrc/fusres.h b/src/dlls/mscorrc/fusres.h
index 6d3e1b2216..6d6ddd1e9f 100644
--- a/src/dlls/mscorrc/fusres.h
+++ b/src/dlls/mscorrc/fusres.h
@@ -4,254 +4,6 @@
#ifndef __FUSION_RESOURCE_H_
#define __FUSION_RESOURCE_H_
-#ifdef FEATURE_FUSION
-
-#define ID_FUSLOG_ASSEMBLY_CREATION_FAILURE 10000
-#define ID_FUSLOG_ASSEMBLY_LOOKUP_FAILURE 10001
-#define ID_FUSLOG_ISEQUAL_DIFF_NAME 10005
-#define ID_FUSLOG_ISEQUAL_DIFF_VERSION_MAJOR 10006
-#define ID_FUSLOG_ISEQUAL_DIFF_VERSION_MINOR 10007
-#define ID_FUSLOG_ISEQUAL_DIFF_VERSION_REVISION 10008
-#define ID_FUSLOG_ISEQUAL_DIFF_VERSION_BUILD 10009
-#define ID_FUSLOG_ISEQUAL_DIFF_PUBLIC_KEY_TOKEN 10010
-#define ID_FUSLOG_ISEQUAL_DIFF_CULTURE 10011
-#define ID_FUSLOG_ISEQUAL_DIFF_CUSTOM 10012
-#define ID_FUSLOG_CANONICALIZATION_ERROR 10014
-#define ID_FUSLOG_POLICY_CACHE_FAILURE 10016
-#define ID_FUSLOG_APP_CFG_PIGGYBACK 10017
-#define ID_FUSLOG_PREBIND_INFO_START 10018
-#define ID_FUSLOG_PREBIND_INFO_DISPLAY_NAME 10019
-#define ID_FUSLOG_PREBIND_INFO_WHERE_REF 10020
-#define ID_FUSLOG_PREBIND_INFO_APPBASE 10021
-#define ID_FUSLOG_PREBIND_INFO_PRIVATE_PATH 10023
-#define ID_FUSLOG_PREBIND_INFO_DYNAMIC_BASE 10024
-#define ID_FUSLOG_PREBIND_INFO_CACHE_BASE 10025
-#define ID_FUSLOG_PREBIND_INFO_APP_NAME 10026
-#define ID_FUSLOG_PREBIND_INFO_END 10027
-#define ID_FUSLOG_APP_CFG_DOWNLOAD 10028
-#define ID_FUSLOG_APP_CFG_DOWNLOAD_LOCATION 10029
-#define ID_FUSLOG_LOADCTX_HIT 10030
-#define ID_FUSLOG_CFG_NOT_EXIST 10031
-#define ID_FUSLOG_APP_CFG_FOUND 10032
-#define ID_FUSLOG_DEVOVERRIDE_REF_DEF_MISMATCH 10036
-#define ID_FUSLOG_DEVOVERRIDE_SIGNATURE_CHECK_FAILED 10037
-#define ID_FUSLOG_XML_PRIVATE_ASM_REDIRECT 10039
-#define ID_FUSLOG_XML_PARSE_ERROR_CODE 10041
-#define ID_FUSLOG_XML_ASSEMBLYIDENTITY_MISSING_NAME 10042
-#define ID_FUSLOG_XML_BINDINGREDIRECT_INSUFFICIENT_DATA 10043
-#define ID_FUSLOG_XML_CODEBASE_HREF_MISSING 10044
-#define ID_FUSLOG_XML_MULTIPLE_IDENTITIES 10045
-#define ID_FUSLOG_PRIVATE_PATH_DUPLICATE 10046
-#define ID_FUSLOG_POLICY_NOT_APPLIED 10047
-#define ID_FUSLOG_HOST_CONFIG_FILE 10048
-#define ID_FUSLOG_HOST_CONFIG_FILE_MISSING 10049
-#define ID_FUSLOG_HOST_CFG_REDIRECT 10051
-#define ID_FUSLOG_HOST_CFG_NO_REDIRECT 10052
-#define ID_FUSLOG_APP_CFG_REDIRECT 10053
-#define ID_FUSLOG_APP_CFG_SAFE_MODE 10054
-#define ID_FUSLOG_PUB_CFG_MISSING 10055
-#define ID_FUSLOG_PUB_CFG_FOUND 10056
-#define ID_FUSLOG_PUB_CFG_REDIRECT 10057
-#define ID_FUSLOG_MACHINE_CFG_MISSING 10058
-#define ID_FUSLOG_MACHINE_CFG_FOUND 10059
-#define ID_FUSLOG_MACHINE_CFG_REDIRECT 10060
-#define ID_FUSLOG_REDIRECT_NO_CODEBASE 10061
-#define ID_FUSLOG_POLICY_CODEBASE 10062
-#define ID_FUSLOG_POST_POLICY_REFERENCE 10063
-#define ID_FUSLOG_APPLY_POLICY_FAILED 10064
-#define ID_FUSLOG_CFG_PRIVATE_PATH 10065
-#define ID_FUSLOG_XML_PARSE_ERROR_FILE 10066
-#define ID_FUSLOG_CODEBASE_RETRIEVE_FAILURE 10067
-#define ID_FUSLOG_ATTEMPT_NEW_DOWNLOAD 10068
-#define ID_FUSLOG_PROBE_FAIL_BUT_ASM_FOUND 10069
-#define ID_FUSLOG_ASM_SETUP_FAILURE 10070
-#define ID_FUSLOG_PREDOWNLOAD_FAILURE 10071
-#define ID_FUSLOG_URLMON_MISSING 10072
-#define ID_FUSLOG_DOWNLOAD_PIGGYBACK 10073
-#define ID_FUSLOG_DOWNLOAD_SUCCESS 10074
-#define ID_FUSLOG_LAST_MOD_FAILURE 10075
-#define ID_FUSLOG_MSI_CODEBASE_UNSUPPORTED 10076
-#define ID_FUSLOG_CAB_ASM_NOT_FOUND_EXTRACTED 10077
-#define ID_FUSLOG_FAILED_PROBING 10078
-#define ID_FUSLOG_PARTIAL_GAC_UNSUPPORTED 10079
-#define ID_FUSLOG_GAC_LOOKUP_SUCCESS 10080
-#define ID_FUSLOG_MSI_INSTALL_ATTEMPT 10081
-#define ID_FUSLOG_MSI_ASM_INSTALL_SUCCESS 10082
-#define ID_FUSLOG_POLICY_CACHE_INSERT_FAILURE 10084
-#define ID_FUSLOG_MSI_SUCCESS_FUSION_SETUP_FAIL 10085
-#define ID_FUSLOG_SETUP_RUN_FROM_SOURCE 10086
-#define ID_FUSLOG_MODULE_INTEGRITY_CHECK_FAILURE 10087
-#define ID_FUSLOG_SETUP_DOWNLOAD_CACHE 10088
-#define ID_FUSLOG_REF_DEF_MISMATCH 10089
-#define ID_FUSLOG_SETUP_FAILURE 10090
-#define ID_FUSLOG_IGNORE_INVALID_PROBE 10091
-#define ID_FUSLOG_CACHE_LOOKUP_SUCCESS 10092
-#define ID_FUSLOG_PREJIT_NOT_FOUND 10093
-#define ID_FUSLOG_CODEBASE_CONSTRUCTION_FAILURE 10094
-#define ID_FUSLOG_CODEBASE_UNAVAILABLE 10095
-#define ID_FUSLOG_DOWNLOAD_CACHE_LOOKUP_SUCCESS 10096
-#define ID_FUSLOG_SETUP_CAB 10097
-#define ID_FUSLOG_TEMP_DIR_CREATE_FAILURE 10098
-#define ID_FUSLOG_CAB_EXTRACT_FAILURE 10099
-#define ID_FUSLOG_CAB_ASM_FOUND 10100
-#define ID_FUSLOG_CAB_EXTRACT_SUCCESS 10101
-#define ID_FUSLOG_DOWNLOAD_CACHE_CREATE_FAILURE 10102
-#define ID_FUSLOG_CAB_ASM_NOT_FOUND 10103
-#define ID_FUSLOG_TEMP_DIR_REMOVE_FAILURE 10104
-#define ID_FUSLOG_MANIFEST_EXTRACT_FAILURE 10105
-#define ID_FUSLOG_NAME_DEF_EXTRACT_FAILURE 10106
-#define ID_FUSLOG_INVALID_PRIVATE_ASM_LOCATION 10107
-#define ID_FUSLOG_PARTIAL_ASM_IN_APP_DIR 10108
-#define ID_FUSLOG_REPROBE_REQUIRED 10109
-#define ID_FUSLOG_DUPLICATE_ASM_COMMIT 10110
-#define ID_FUSLOG_INVALID_ASM_PLATFORM 10111
-#define ID_FUSLOG_COPY_FILE_FAILURE 10112
-#define ID_FUSLOG_INVALID_LOCATION_INFO 10113
-#define ID_FUSLOG_ASYNC_CFG_DOWNLOAD_SUCCESS 10114
-#define ID_FUSLOG_ASYNC_CFG_DOWNLOAD_FAILURE 10115
-#define ID_FUSLOG_CACHE_ITEM_CREATE_FAILURE 10116
-#define ID_FUSLOG_CACHE_ITEM_COMMIT_FAILURE 10117
-
-
-#define ID_FUSLOG_OPERATION_SUCCESSFUL 10118
-#define ID_FUSLOG_OPERATION_FAILED 10119
-#define ID_FUSLOG_DETAILED_LOG 10120
-#define ID_FUSLOG_HEADER_TEXT 10121
-#define ID_FUSLOG_BIND_RESULT_TEXT 10122
-#define ID_FUSLOG_NO_DESCRIPTION 10123
-#define ID_FUSLOG_FUSION_DLL_PATH 10124
-#define ID_FUSLOG_EXECUTABLE 10125
-
-#define ID_FUSLOG_QUALIFIED_ASSEMBLY 10126
-#define ID_FUSLOG_CALLING_ASSEMBLY 10127
-
-#define ID_FUSLOG_CFG_ASSEMBLY_STORE 10128
-#define ID_FUSLOG_SETUP_RUN_FROM_SOURCE_FAILURE 10129
-
-#define ID_FUSLOG_ISEQUAL_DIFF_RETARGET 10130
-#define ID_FUSLOG_RETARGET_CFG_MISSING 10131
-#define ID_FUSLOG_RETARGET_CFG_NAME_REDIRECT 10132
-#define ID_FUSLOG_RETARGET_CFG_VER_REDIRECT 10133
-#define ID_FUSLOG_RETARGET_CFG_PKT_REDIRECT 10134
-#define ID_FUSLOG_XML_PARSE_ERROR_MEMORY 10135
-#define ID_FUSLOG_XML_BINDINGRETARGET_INSUFFICIENT_DATA 10136
-#define ID_FUSLOG_XML_INVALID_PROCESSORARCHITECTURE 10137
-
-#define ID_FUSLOG_BIND_SUCCESS 10139
-
-#define ID_FUSLOG_CROSS_SITE_REDIRECT 10140
-#define ID_FUSLOG_DISALLOW_APPLY_PUB_POLICY 10141
-#define ID_FUSLOG_DISALLOW_APP_BINDING_REDIRECTS 10142
-#define ID_FUSLOG_DISALLOW_APP_BASE_PROBING 10143
-#define ID_FUSLOG_INSPECTION_ONLY 10144
-#define ID_FUSLOG_SHOW_START_LOAD_CONTEXT 10145
-#define ID_FUSLOG_SHOW_RESULT_LOAD_CONTEXT 10146
-#define ID_FUSLOG_LOAD_CONTEXT_PA_MISMATCH 10147
-
-#define ID_FUSLOG_FX_CFG_MISSING 10150
-#define ID_FUSLOG_FX_CFG_VER_REDIRECT 10151
-#define ID_FUSLOG_APPLIESTO_DUPLICATE 10152
-
-#define ID_FUSLOG_PREBIND_INFO_DEVOVERRIDE_GLOBAL 10153
-#define ID_FUSLOG_PREBIND_INFO_DEVOVERRIDE_LOCAL 10154
-#define ID_FUSLOG_DEVOVERRIDE_FOUND 10155
-#define ID_FUSLOG_DEVOVERRIDE_MISS 10156
-#define ID_FUSLOG_PREBIND_INFO_DEVPATH 10157
-#define ID_FUSLOG_ASSEMBLYSTORE_DUPLICATE 10158
-#define ID_FUSLOG_DEVOVERRIDE_DUPLICATE 10159
-
-#define ID_FUSLOG_LOADCTX_HIT_HOST 10160
-#define ID_FUSLOG_HOST_RESOLVED 10161
-#define ID_FUSLOG_ADMIN_CFG_POLICY_CODEBASE 10162
-#define ID_FUSLOG_PROCESSOR_ARCHITECTURE_LOCKED 10163
-#define ID_FUSLOG_CHECK_HOST 10164
-#define ID_FUSLOG_NOT_IN_CLR_LOADED_LIST 10165
-#define ID_FUSLOG_IN_CLR_LOADED_LIST 10166
-#define ID_FUSLOG_HOST_STORE_RESOLVE_TRY 10167
-#define ID_FUSLOG_HOST_STORE_RESOLVE_FAILED 10168
-#define ID_FUSLOG_HOST_STORE_NOT_AVAILABLE 10169
-
-// 10170 - 10211 used by native binder
-
-#define ID_FUSLOG_EXPLICIT_BIND_IJW 10220
-#define ID_FUSLOG_EXPLICIT_BIND_EXE 10221
-#define ID_FUSLOG_EXPLICIT_BIND_IJW_BIND_FAIL 10222
-#define ID_FUSLOG_EXPLICIT_BIND_IJW_PATH_DIFF 10223
-#define ID_FUSLOG_EXPLICIT_BIND_IJW_PATH_MATCH 10224
-#define ID_FUSLOG_EXPLICIT_BIND_IJW_NOT_FOUND 10225
-#define ID_FUSLOG_EXPLICIT_BIND_EXE_LOADCONTEXT_COLLISION 10226
-
-#define ID_FUSLOG_PUBLISHER_POLICY_CONFIG_MISSING 10231
-
-#define ID_FUSLOG_UNSUPPORTED_LINKED_CONFIGURATION 10300
-#define ID_FUSLOG_LINKED_CONFIGURATION_PARSE_ERROR 10301
-#define ID_FUSLOG_LINKED_CONFIGURATION_DUPLICATE 10302
-#define ID_FUSLOG_PROCESSING_LINKED_CONFIGURATION 10303
-
-#define ID_FUSLOG_ISEQUAL_DIFF_PROCESSOR_ARCHITECTURE 10310
-#define ID_FUSLOG_ISEQUAL_DIFF_CONTENT_TYPE 10311
-
-#define ID_FUSLOG_WHERE_REF_APPLY_POLICY 10320
-#define ID_FUSLOG_SWITCH_TO_DEFAULT_CONTEXT 10321
-#define ID_FUSLOG_SWITCH_TO_LOADFROM_CONTEXT 10322
-#define ID_FUSLOG_WHERE_REF_GAC_MATCH 10323
-#define ID_FUSLOG_WHERE_REF_GAC_MISMATCH 10324
-#define ID_FUSLOG_WHERE_REF_LOAD_CONTEXT_MATCH 10325
-#define ID_FUSLOG_WHERE_REF_LOAD_CONTEXT_MISMATCH 10326
-#define ID_FUSLOG_HOST_STORE_PARTIAL_NAME_SKIP 10327
-#define ID_FUSLOG_MISSING_CACHE_FILE 10328
-#define ID_FUSLOG_HOST_GAC_ASM_MISMATCH 10329
-#define ID_FUSLOG_HOST_RESULT 10330
-#define ID_FUSLOG_HOST_NO_DEBUG_STREAM 10331
-#define ID_FUSLOG_APP_CONFIG_FILE 10332
-#define ID_FUSLOG_NO_APP_CONFIG_FILE 10333
-#define ID_FUSLOG_ASSEMBLY_NAME_DEF 10334
-#define ID_FUSLOG_PREVIOUS_FAILED 10335
-#define ID_FUSLOG_LOADFROM_DEFAULT_MISMATCH 10336
-#define ID_FUSLOG_LOADER_PERMISSION_CHECK_FAILURE 10337
-#define ID_FUSLOG_INCOMPATIBLE_PROCESSOR_ARCHITECTURE 10338
-#define ID_FUSLOG_NO_PARTIAL_NAME_FOR_HOST_APPBASE_COMMON_ASM 10339
-
-// 10400 - 10500 used by native binder
-
-#define ID_FUSLOG_LOG_TURNED_OFF 10990
-#define ID_FUSLOG_LOG_TURN_ON_HKLM 10991
-#define ID_FUSLOG_LOG_PERF_WARNING 10992
-#define ID_FUSLOG_LOG_TURN_OFF_HKLM 10993
-
-#define ID_FUSLOG_PARTIAL_BIND_DEBUG 11000
-
-#define ID_FUSLOG_WARNING_PARTIAL_NAME_HEADER 11001
-#define ID_FUSLOG_WARNING_PARTIAL_NAME_DETAIL 11002
-#define ID_FUSLOG_WARNING_PARTIAL_NAME_INSTANCE 11003
-#define ID_FUSLOG_WARNING_MULTIPLE_VERSIONS_HEADER 11004
-#define ID_FUSLOG_WARNING_MULTIPLE_VERSIONS_DETAIL 11005
-#define ID_FUSLOG_WARNING_MULTIPLE_VERSIONS_INSTANCE 11006
-#define ID_FUSLOG_WARNING_MULTIPLE_CONTEXTS_HEADER 11007
-#define ID_FUSLOG_WARNING_MULTIPLE_CONTEXTS_DETAIL 11008
-
-#define ID_FUSLOG_PORTABILITY_CFG_NAME_REDIRECT 11011
-#define ID_FUSLOG_PORTABILITY_CFG_VER_REDIRECT 11012
-#define ID_FUSLOG_PORTABILITY_CFG_PKT_REDIRECT 11013
-#define ID_FUSLOG_WARNING_SUPPORTPORTABILITY_MISSING_PKT 11014
-#define ID_FUSLOG_WARNING_SUPPORTPORTABILITY_MISSING_ENABLE 11015
-#define ID_FUSLOG_WARNING_SUPPORTPORTABILITY_INVALID_ENABLE 11016
-
-#define ID_FUSLOG_BINDING_STATUS_BEGIN 11020
-#define ID_FUSLOG_BINDING_STATUS_END 11021
-#define ID_FUSLOG_BINDING_STATUS_END_HR 11022
-#define ID_FUSLOG_BINDING_STATUS_NATIVE_DEPENDENCY 11023
-#define ID_FUSLOG_BINDING_STATUS_IMMERSIVE 11024
-#define ID_FUSLOG_BINDING_STATUS_FRAMEWORK 11025
-#define ID_FUSLOG_BINDING_STATUS_LOAD_FILE 11026
-#define ID_FUSLOG_BINDING_STATUS_WINRT 11027
-#define ID_FUSLOG_BINDING_DEPENDENCY_NAME 11028
-#define ID_FUSLOG_BINDING_STATUS_FOUND 11029
-#define ID_FUSLOG_BINDING_STATUS_IL_IMAGE 11030
-#define ID_FUSLOG_BINDING_STATUS_NATIVE_IMAGE 11031
-#define ID_FUSLOG_BINDING_STATUS_FX_ASSEMBLY_BLOCKED 11032
-
-#else //!FEATURE_FUSION
// we have 10000 to 10125 available (and more)
// Used are 10000 to 10042
@@ -305,6 +57,5 @@
#define ID_FUSLOG_BINDING_HEADER_BIND_RESULT_ERROR 10041
#define ID_FUSLOG_BINDING_HEADER_END 10042
-#endif //!FEATURE_FUSION
#endif // __FUSION_RESOURCE_H_
diff --git a/src/dlls/mscorrc/include.rc b/src/dlls/mscorrc/include.rc
index ee46940871..50c7c779ae 100644
--- a/src/dlls/mscorrc/include.rc
+++ b/src/dlls/mscorrc/include.rc
@@ -4,4 +4,3 @@
#include "mscorrc.rc"
#include "fuslog.rc"
-#include "nativelog.rc"
diff --git a/src/dlls/mscorrc/mscorrc.rc b/src/dlls/mscorrc/mscorrc.rc
index 138db55b66..bb2a9ee0fb 100644
--- a/src/dlls/mscorrc/mscorrc.rc
+++ b/src/dlls/mscorrc/mscorrc.rc
@@ -994,11 +994,7 @@ BEGIN
IDS_EE_LOAD_BAD_MAIN_SIG "Main method for type '%1' has invalid signature."
IDS_EE_LOAD_CIRCULAR_DEPENDENCY "A circular dependency was detected when loading file or assembly '%1'."
-#ifdef FEATURE_CORECLR
IDS_EE_FILE_NOT_FOUND "File or assembly name '%1' was not found."
-#else
- IDS_EE_FILE_NOT_FOUND "File or assembly name '%1', or one of its dependencies, was not found."
-#endif
IDS_EE_TOO_MANY_OPEN_FILES "The system cannot open file '%1'. There may be too many open files."
IDS_EE_SHARING_VIOLATION "Cannot access file '%1' because it is being used by another process."
@@ -1376,11 +1372,7 @@ BEGIN
IDS_EE_CANNOT_HAVE_ASSEMBLY_SPEC "Unexpected assembly-qualifier in a typename."
IDS_EE_NEEDS_ASSEMBLY_SPEC "Typename needs an assembly qualifier."
-#ifdef FEATURE_CORECLR
IDS_EE_FILELOAD_ERROR_GENERIC "Could not load file or assembly '%1'. %2"
-#else
- IDS_EE_FILELOAD_ERROR_GENERIC "Could not load file or assembly '%1' or one of its dependencies. %2"
-#endif
IDS_EE_CRYPTO_UNKNOWN_OPERATION "Unknown import key operation specified."
@@ -1509,11 +1501,7 @@ BEGIN
IDS_CLASSLOAD_OVERLAPPING_INTERFACES "The type '%1' in assembly '%2' has a contracting interface set for some instantiations"
-#ifdef FEATURE_CORECLR
IDS_CLASSLOAD_32BITCLRLOADING64BITASSEMBLY "Attempted to load a 64-bit assembly on a 32-bit platform."
-#else // !FEATURE_CORECLR
- IDS_CLASSLOAD_32BITCLRLOADING64BITASSEMBLY "Attempted to load a 64-bit assembly on a 32-bit platform. Use ReflectionOnlyLoad() instead if trying to load for reflection purposes."
-#endif // FEATURE_CORECLR
IDS_CLASSLOAD_CONSTRAINT_MISMATCH_ON_IMPLICIT_OVERRIDE "Method '%3' on type '%1' from assembly '%2' tried to implicitly override a method with weaker type parameter constraints."
IDS_CLASSLOAD_CONSTRAINT_MISMATCH_ON_IMPLICIT_IMPLEMENTATION "Method '%3' on type '%1' from assembly '%2' tried to implicitly implement an interface method with weaker type parameter constraints."
@@ -1545,17 +1533,9 @@ BEGIN
IDS_UNMARSHALABLE_DEMAND_OBJECT "The security object (Permission or PermissionSet) used for performing a Demand caused an error relating to serialization/deserialization."
IDS_EE_OBJECT_TO_VARIANT_NOT_SUPPORTED "Invalid managed/unmanaged type combination (Marshaling to and from COM VARIANTs isn't supported)."
IDS_EE_OBJECT_TO_ITF_NOT_SUPPORTED "Invalid managed/unmanaged type combination (Marshaling to and from COM interface pointers isn't supported)."
-#ifdef FEATURE_CORECLR
IDS_TYPE_INHERITANCE_RULES_VIOLATED "Inheritance security rules violated by type: '%1'. Derived types must either match the security accessibility of the base type or be less accessible. If the base class has a non-transparent default constructor, the derived class must also have a default constructor, and the method inheritance rules apply across those two methods."
-#else // !FEATURE_CORECLR
- IDS_TYPE_INHERITANCE_RULES_VIOLATED "Inheritance security rules violated by type: '%1'. Derived types must either match the security accessibility of the base type or be less accessible."
-#endif // FEATURE_CORECLR
IDS_METHOD_INHERITANCE_RULES_VIOLATED "Inheritance security rules violated while overriding member: '%1'. Security accessibility of the overriding method must match the security accessibility of the method being overriden."
IDS_CRITICAL_METHOD_ACCESS_DENIED "Attempt to access method %1 in violation of security transparency rules failed."
-#ifdef FEATURE_CAS_POLICY
- IDS_E_LOADFROM_REMOTE_SOURCE "An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information."
- IDS_E_LOADFROM_REMOTE_SOURCE_MOTW "An attempt was made to load an assembly that was downloaded from a network location, which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this assembly is trusted, either remove the Zone marker from it or enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information."
-#endif // FEATURE_CAS_POLICY
IDS_CRITICAL_TYPE_ACCESS_DENIED "Attempt to access type %1 in violation of security transparency rules failed."
IDS_APPLICATION_ASSEMBLY_EXEC_DENIED "Application assemblies cannot be directly executed: %1"
IDS_REFLECTION_METHOD_ACCESS_DENIED "Application code cannot access %1 using Reflection."
@@ -1574,11 +1554,9 @@ BEGIN
IDS_E_CRITICAL_FIELD_ACCESS_DENIED "Attempt by security transparent method '%1' to access security critical field '%2' failed.%3"
IDS_E_CRITICAL_METHOD_ACCESS_DENIED "Attempt by security transparent method '%1' to access security critical method '%2' failed.%3"
IDS_E_CRITICAL_TYPE_ACCESS_DENIED "Attempt by security transparent method '%1' to access security critical type '%2' failed.%3"
-#ifdef FEATURE_CORECLR
IDS_E_DELEGATE_BINDING_TRANSPARENCY "A delegate of type '%1' cannot be bound to the method '%2' due to security transparency rules. Ensure the delegate type and the method being bound have compatible security transparency."
IDS_E_DELEGATE_FULLTRUST_ARPIC_1 "Delegate '%1' must be bound to a method in a fully-trusted assembly and the method must have the AllowReversePinvokeCallsAttribute."
IDS_E_DELEGATE_FULLTRUST_ARPIC_2 "Cannot create a Delegate for marshalling out unless it is bound to a method in a fully-trusted assembly and the method has the AllowReversePinvokeCallsAttribute."
-#endif
IDS_E_ACCESSING_PRIVATE_FRAMEWORK_CODE "Reflection invocation to internal or private types or members in the framework is not allowed."
IDS_EE_TORNSTATE "Unexpected change made to file '%1'."
@@ -1591,10 +1569,6 @@ STRINGTABLE DISCARDABLE
BEGIN
IDS_ACCESS_EXCEPTION_CONTEXT_LEVEL2_APTCA "Assembly '%1' is marked with the AllowPartiallyTrustedCallersAttribute, and uses the level 2 security transparency model. Level 2 transparency causes all methods in AllowPartiallyTrustedCallers assemblies to become security transparent by default, which may be the cause of this exception."
IDS_ACCESS_EXCEPTION_CONTEXT_PT_TRANSPARENT "Assembly '%1' is partially trusted, which causes the CLR to make it entirely security transparent regardless of any transparency annotations in the assembly itself. In order to access security critical code, this assembly must be fully trusted."
-#ifdef FEATURE_APTCA
- IDS_ACCESS_EXCEPTION_CONTEXT_APTCA_KILLBIT "Assembly '%1' has had an APTCA killbit set for it, which prevents it from being used by partial trust or security transparent code."
- IDS_ACCESS_EXCEPTION_CONTEXT_CONDITIONAL_APTCA "Assembly '%1' is a conditionally APTCA assembly which is not enabled in the current AppDomain. To enable this assembly to be used by partial trust or security transparent code, please add assembly name '%2' to the the PartialTrustVisibleAssemblies list when creating the AppDomain."
-#endif // FEATURE_APTCA
END
// These strings are generated from within the EE for streams
@@ -1612,11 +1586,7 @@ STRINGTABLE DISCARDABLE
BEGIN
IDS_ER_APPLICATION "Application: "
IDS_ER_UNKNOWN "unknown"
-#ifndef FEATURE_CORECLR
- IDS_ER_FRAMEWORK_VERSION "Framework Version: "
-#else // FEATURE_CORECLR
IDS_ER_FRAMEWORK_VERSION "CoreCLR Version: "
-#endif // !FEATURE_CORECLR
IDS_ER_UNHANDLEDEXCEPTION "Description: The process was terminated due to an unhandled exception."
IDS_ER_UNHANDLEDEXCEPTIONMSG "Exception Info: "
IDS_ER_MANAGEDFAILFAST "Description: The application requested process termination through System.Environment.FailFast(string message)."
@@ -2121,15 +2091,7 @@ BEGIN
IDS_DIALOG_BOX_IGNORE_BUTTON "&Ignore"
END
-#ifndef FEATURE_CORECLR
-// OOB servicing
-STRINGTABLE DISCARDABLE
-BEGIN
- IDS_EE_ASSEMBLY_ON_DENY_LIST "The assembly %1 that the application tried to load has a known vulnerability. Please go to %2 to find a fix for this issue."
-END
-#endif
-#ifdef FEATURE_CORECLR
STRINGTABLE DISCARDABLE
BEGIN
IDS_EE_BADMARSHAL_TYPE_ANSIBSTR "Marshalling as AnsiBStr is not supported"
@@ -2140,9 +2102,7 @@ BEGIN
IDS_EE_BADMARSHAL_TYPE_IDISPATCH "Marshalling as IDispatch is not supported"
IDS_EE_ERROR_IDISPATCH "IDispatch and IDispatchEx are not supported"
END
-#endif // FEATURE_CORECLR
-#ifdef FEATURE_HOST_ASSEMBLY_RESOLVER
STRINGTABLE DISCARDABLE
BEGIN
IDS_HOST_ASSEMBLY_RESOLVER_ASSEMBLY_ALREADY_LOADED_IN_CONTEXT "Assembly with same name is already loaded"
@@ -2150,7 +2110,6 @@ BEGIN
IDS_HOST_ASSEMBLY_RESOLVER_INCOMPATIBLE_BINDING_CONTEXT "Assembly is already bound to an incompatible binding context."
IDS_HOST_ASSEMBLY_RESOLVER_INCOMPATIBLE_TPA_BINDING_CONTEXT "Default binding context is already attached to managed load context."
END
-#endif // FEATURE_HOST_ASSEMBLY_RESOLVER
STRINGTABLE DISCARDABLE
BEGIN
diff --git a/src/dlls/mscorrc/nativelog.rc b/src/dlls/mscorrc/nativelog.rc
deleted file mode 100644
index 33e94dc129..0000000000
--- a/src/dlls/mscorrc/nativelog.rc
+++ /dev/null
@@ -1,32 +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 "nativeres.h"
-
-#ifdef FEATURE_FUSION
-
-STRINGTABLE DISCARDABLE
-BEGIN
- ID_FUSLOG_NGEN_BIND_IL_PROVIDED L"LOG: IL assembly loaded from %ws."
- ID_FUSLOG_NGEN_BIND_LOADFROM_NOT_ALLOWED L"WRN: Native image will not be probed in LoadFrom context. Native image will only be probed in default load context, like with Assembly.Load()."
- ID_FUSLOG_NGEN_BIND_SUCCESS L"LOG: Bind to native image succeeded."
- ID_FUSLOG_NGEN_BIND_FAIL L"ERR: Error encountered when binding to native image assembly. (hr = 0x%x)."
- ID_FUSLOG_NGEN_BIND_NO_MATCH L"WRN: No matching native image found."
- ID_FUSLOG_NGEN_BIND_NGEN_REJECT_CONFIG_MASK L"WRN: Native image compile options do not match request. Looking for next native image."
- ID_FUSLOG_NGEN_BIND_NI_DEPEND_START L"LOG: [Level %d]Start validating native image dependency %ws."
- ID_FUSLOG_NGEN_BIND_IL_DEPEND_START L"LOG: [Level %d]Start validating IL dependency %ws."
- ID_FUSLOG_NGEN_BIND_VALIDATE_DEPENDENCIES L"LOG: Start validating all the dependencies."
- ID_FUSLOG_NGEN_BIND_VALIDATE_DEPENDENCIES_SUCCESS L"LOG: Validation of dependencies succeeded."
- ID_FUSLOG_NGEN_BIND_REJECT_IL_NOT_FOUND L"WRN: Cannot load IL assembly. (hr = 0x%x)."
- ID_FUSLOG_NGEN_BIND_MISSING_FOUND L"WRN: Dependency assembly was not found at ngen time, but is found at binding time. Disallow using this native image."
- ID_FUSLOG_NGEN_BIND_AUXCORRUPTION_GENERAL L"ERR: Rejecting native image due to corrupted or missing .aux file (%ws)."
- ID_FUSLOG_NGEN_BIND_AUX_REOPTIMIZED L"LOG: Successfully updated stale timestamp in .aux file (%ws)."
- ID_FUSLOG_NGEN_BIND_REJECT_SIG L"WRN: Signature of the IL assembly does not match record in .aux file. Validation stops."
- ID_FUSLOG_NGEN_BIND_REJECT_TP L"WRN: TPBand of the IL assembly does not match record in .aux file. Validation stops."
- ID_FUSLOG_NGEN_BIND_REJECT_TIMESTAMP_SIGFALLBACK L"WRN: Timestamp of the IL assembly does not match record in .aux file. Loading IL to compare signature."
- ID_FUSLOG_NGEN_BIND_REJECT_TIMESTAMP_TPFALLBACK L"WRN: Timestamp of the IL assembly does not match record in .aux file. Loading IL to compare TPBand."
- ID_FUSLOG_NGEN_BIND_CHANGED_BINDING_POLICY L"WRN: Assembly resolved to a different version or identity than expected. Check if binding policy changed since native image built."
- ID_FUSLOG_NGEN_BIND_REJECT_OPTOUT L"WRN: The application has opted out of using native images for this assembly."
-END
-
-#endif // FEATURE_FUSION
diff --git a/src/dlls/mscorrc/nativeres.h b/src/dlls/mscorrc/nativeres.h
deleted file mode 100644
index d1315176f8..0000000000
--- a/src/dlls/mscorrc/nativeres.h
+++ /dev/null
@@ -1,35 +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.
-#ifndef __NATIVE_BINDER_RESOURCE_H_
-#define __NATIVE_BINDER_RESOURCE_H_
-
-#ifdef FEATURE_FUSION
-
-#define ID_FUSLOG_NGEN_BIND_IL_PROVIDED 10204
-#define ID_FUSLOG_NGEN_BIND_LOADFROM_NOT_ALLOWED 10174
-#define ID_FUSLOG_NGEN_BIND_SUCCESS 10171
-#define ID_FUSLOG_NGEN_BIND_FAIL 10172
-#define ID_FUSLOG_NGEN_BIND_NO_MATCH 10179
-#define ID_FUSLOG_NGEN_BIND_NGEN_REJECT_CONFIG_MASK 10178
-#define ID_FUSLOG_NGEN_BIND_NI_DEPEND_START 10206
-#define ID_FUSLOG_NGEN_BIND_IL_DEPEND_START 10207
-#define ID_FUSLOG_NGEN_BIND_VALIDATE_DEPENDENCIES 10197
-#define ID_FUSLOG_NGEN_BIND_VALIDATE_DEPENDENCIES_SUCCESS 10200
-#define ID_FUSLOG_NGEN_BIND_REJECT_IL_NOT_FOUND 10183
-#define ID_FUSLOG_NGEN_BIND_MISSING_FOUND 10209
-
-// Ids 10400 - 10500 reserved for new native binder messages
-// If more ids are needed, reserve them in fusres.h
-#define ID_FUSLOG_NGEN_BIND_AUXCORRUPTION_GENERAL 10400
-#define ID_FUSLOG_NGEN_BIND_AUX_REOPTIMIZED 10401
-#define ID_FUSLOG_NGEN_BIND_REJECT_SIG 10402
-#define ID_FUSLOG_NGEN_BIND_REJECT_TP 10403
-#define ID_FUSLOG_NGEN_BIND_REJECT_TIMESTAMP_SIGFALLBACK 10404
-#define ID_FUSLOG_NGEN_BIND_REJECT_TIMESTAMP_TPFALLBACK 10405
-#define ID_FUSLOG_NGEN_BIND_CHANGED_BINDING_POLICY 10406
-#define ID_FUSLOG_NGEN_BIND_REJECT_OPTOUT 10407
-
-#endif // FEATURE_FUSION
-
-#endif // __NATIVE_BINDER_RESOURCE_H_
diff --git a/src/dlls/mscorrc/resource.h b/src/dlls/mscorrc/resource.h
index 77e937a81e..6153246bb4 100644
--- a/src/dlls/mscorrc/resource.h
+++ b/src/dlls/mscorrc/resource.h
@@ -812,16 +812,12 @@
#define IDS_E_TRANSPARENT_CALL_NATIVE 0x2120
#define IDS_E_TRANSPARENT_REFLECTION 0x2121
-#ifdef FEATURE_CORECLR
#define IDS_E_DELEGATE_BINDING_TRANSPARENCY 0x2122
-#endif
#define IDS_E_ACCESSING_PRIVATE_FRAMEWORK_CODE 0x2123
-#ifdef FEATURE_CORECLR
#define IDS_E_DELEGATE_FULLTRUST_ARPIC_1 0x2124
#define IDS_E_DELEGATE_FULLTRUST_ARPIC_2 0x2125
-#endif
#define IDS_ACCESS_EXCEPTION_CONTEXT_LEVEL2_APTCA 0x2200
#define IDS_ACCESS_EXCEPTION_CONTEXT_APTCA_KILLBIT 0x2201
@@ -870,10 +866,8 @@
#define IDS_E_PROF_TIMEOUT_WAITING_FOR_CONCURRENT_GC 0x251D
-#ifdef FEATURE_CORECLR
#define IDS_EE_LINK_FOR_ERROR_MESSAGES 0x2600
#define IDS_EE_LINK_FOR_DEBUGGING_MESSAGES 0x2601
-#endif
#define IDS_DIALOG_BOX_ABORT_BUTTON 0x2602
#define IDS_DIALOG_BOX_DEBUG_BUTTON 0x2603
@@ -920,15 +914,11 @@
#define IDS_EE_INTEROP_DLL_IMPORT_ON_USER_METHOD 0x262b
#endif
-#ifndef FEATURE_CORECLR
-#define IDS_EE_ASSEMBLY_ON_DENY_LIST 0x262c
-#endif
#ifdef FEATURE_COMINTEROP
#define IDS_EE_WINRT_WEAKREF_BAD_TYPE 0x262e
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_CORECLR
#define IDS_EE_BADMARSHAL_TYPE_ANSIBSTR 0x262f
#define IDS_EE_BADMARSHAL_TYPE_VBBYVALSTR 0x2630
#define IDS_EE_BADMARSHAL_TYPE_REFERENCECUSTOMMARSHALER 0x2631
@@ -936,14 +926,11 @@
#define IDS_EE_BADMARSHAL_TYPE_ASANYA 0x2633
#define IDS_EE_BADMARSHAL_TYPE_IDISPATCH 0x2634
#define IDS_EE_ERROR_IDISPATCH 0x2635
-#endif // FEATURE_CORECLR
-#ifdef FEATURE_HOST_ASSEMBLY_RESOLVER
#define IDS_HOST_ASSEMBLY_RESOLVER_ASSEMBLY_ALREADY_LOADED_IN_CONTEXT 0x2636
#define IDS_HOST_ASSEMBLY_RESOLVER_DYNAMICALLY_EMITTED_ASSEMBLIES_UNSUPPORTED 0x2637
#define IDS_HOST_ASSEMBLY_RESOLVER_INCOMPATIBLE_BINDING_CONTEXT 0x2638
#define IDS_HOST_ASSEMBLY_RESOLVER_INCOMPATIBLE_TPA_BINDING_CONTEXT 0x2639
-#endif // FEATURE_HOST_ASSEMBLY_RESOLVER
#define IDS_NATIVE_IMAGE_CANNOT_BE_LOADED_MULTIPLE_TIMES 0x263a
diff --git a/src/gc/CMakeLists.txt b/src/gc/CMakeLists.txt
index cba1aa9778..59c18ffd87 100644
--- a/src/gc/CMakeLists.txt
+++ b/src/gc/CMakeLists.txt
@@ -31,6 +31,7 @@ set( GC_SOURCES_DAC_AND_WKS_COMMON
set( GC_SOURCES_WKS
${GC_SOURCES_DAC_AND_WKS_COMMON}
+ gchandletable.cpp
gceesvr.cpp
gceewks.cpp
handletablecache.cpp)
diff --git a/src/gc/env/gcenv.base.h b/src/gc/env/gcenv.base.h
index 9fe583f9a6..a4befca09e 100644
--- a/src/gc/env/gcenv.base.h
+++ b/src/gc/env/gcenv.base.h
@@ -37,7 +37,7 @@
// Aliases for Win32 types
//
-typedef uint32_t BOOL;
+typedef int BOOL;
typedef uint32_t DWORD;
// -----------------------------------------------------------------------------------------------------------
@@ -65,6 +65,7 @@ inline HRESULT HRESULT_FROM_WIN32(unsigned long x)
#define E_UNEXPECTED 0x8000FFFF
#define E_NOTIMPL 0x80004001
#define E_INVALIDARG 0x80070057
+#define COR_E_EXECUTIONENGINE 0x80131506
#define NOERROR 0x0
#define ERROR_TIMEOUT 1460
@@ -328,16 +329,6 @@ typedef PTR_PTR_Object PTR_OBJECTREF;
typedef PTR_Object _UNCHECKED_OBJECTREF;
typedef PTR_PTR_Object PTR_UNCHECKED_OBJECTREF;
-#ifndef DACCESS_COMPILE
-struct OBJECTHANDLE__
-{
- void* unused;
-};
-typedef struct OBJECTHANDLE__* OBJECTHANDLE;
-#else
-typedef TADDR OBJECTHANDLE;
-#endif
-
// With no object reference wrapping the following macros are very simple.
#define ObjectToOBJECTREF(_obj) (OBJECTREF)(_obj)
#define OBJECTREFToObject(_obj) (Object*)(_obj)
diff --git a/src/gc/env/gcenv.ee.h b/src/gc/env/gcenv.ee.h
index 9f7f266a89..aa00d19780 100644
--- a/src/gc/env/gcenv.ee.h
+++ b/src/gc/env/gcenv.ee.h
@@ -68,6 +68,12 @@ public:
static void StompWriteBarrier(WriteBarrierParameters* args);
static void EnableFinalization(bool foundFinalizers);
+
+ static void HandleFatalError(unsigned int exitCode);
+ static bool ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj);
+ static bool ForceFullGCToBeBlocking();
+ static bool EagerFinalized(Object* obj);
+ static MethodTable* GetFreeObjectMethodTable();
};
#endif // __GCENV_EE_H__
diff --git a/src/gc/env/gcenv.structs.h b/src/gc/env/gcenv.structs.h
index 5887dd7852..bb503e36e8 100644
--- a/src/gc/env/gcenv.structs.h
+++ b/src/gc/env/gcenv.structs.h
@@ -65,7 +65,7 @@ extern "C" uint32_t __stdcall GetCurrentThreadId();
class EEThreadId
{
- uint32_t m_uiId;
+ uint64_t m_uiId;
public:
bool IsCurrentThread()
diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp
index 66c8b6afbc..ecc13e38fd 100644
--- a/src/gc/gc.cpp
+++ b/src/gc/gc.cpp
@@ -53,9 +53,13 @@ BOOL bgc_heap_walk_for_etw_p = FALSE;
#define LOH_PIN_QUEUE_LENGTH 100
#define LOH_PIN_DECAY 10
-// Right now we support maximum 256 procs - meaning that we will create at most
-// 256 GC threads and 256 GC heaps.
-#define MAX_SUPPORTED_CPUS 256
+#ifdef BIT64
+// Right now we support maximum 1024 procs - meaning that we will create at most
+// that many GC threads and GC heaps.
+#define MAX_SUPPORTED_CPUS 1024
+#else
+#define MAX_SUPPORTED_CPUS 64
+#endif // BIT64
#ifdef GC_CONFIG_DRIVEN
int compact_ratio = 0;
@@ -68,6 +72,24 @@ int compact_ratio = 0;
// See comments in reset_memory.
BOOL reset_mm_p = TRUE;
+bool g_fFinalizerRunOnShutDown = false;
+
+#ifdef FEATURE_SVR_GC
+bool g_built_with_svr_gc = true;
+#else
+bool g_built_with_svr_gc = false;
+#endif // FEATURE_SVR_GC
+
+#if defined(BUILDENV_DEBUG)
+uint8_t g_build_variant = 0;
+#elif defined(BUILDENV_CHECKED)
+uint8_t g_build_variant = 1;
+#else
+uint8_t g_build_variant = 2;
+#endif // defined(BUILDENV_DEBUG)
+
+VOLATILE(int32_t) g_no_gc_lock = -1;
+
#if defined (TRACE_GC) && !defined (DACCESS_COMPILE)
const char * const allocation_state_str[] = {
"start",
@@ -93,7 +115,6 @@ const char * const allocation_state_str[] = {
};
#endif //TRACE_GC && !DACCESS_COMPILE
-
// Keep this in sync with the definition of gc_reason
#if (defined(DT_LOG) || defined(TRACE_GC)) && !defined (DACCESS_COMPILE)
static const char* const str_gc_reasons[] =
@@ -150,6 +171,7 @@ size_t GetHighPrecisionTimeStamp()
}
#endif
+
#ifdef GC_STATS
// There is a current and a prior copy of the statistics. This allows us to display deltas per reporting
// interval, as well as running totals. The 'min' and 'max' values require special treatment. They are
@@ -190,8 +212,10 @@ void GCStatistics::AddGCStats(const gc_mechanisms& settings, size_t timeInMSec)
if (is_induced (settings.reason))
cntReasons[(int)reason_induced]++;
+#ifdef STRESS_HEAP
else if (settings.stress_induced)
cntReasons[(int)reason_gcstress]++;
+#endif // STRESS_HEAP
else
cntReasons[(int)settings.reason]++;
@@ -1458,7 +1482,11 @@ inline bool can_use_write_watch_for_gc_heap()
inline bool can_use_write_watch_for_card_table()
{
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ return true;
+#else
return can_use_hardware_write_watch();
+#endif
}
#else
@@ -2161,18 +2189,6 @@ size_t logcount (size_t word)
return count;
}
-//n!=0
-int log2(unsigned int n)
-{
- int pos = 0;
- if (n >= 1<<16) { n >>= 16; pos += 16; }
- if (n >= 1<< 8) { n >>= 8; pos += 8; }
- if (n >= 1<< 4) { n >>= 4; pos += 4; }
- if (n >= 1<< 2) { n >>= 2; pos += 2; }
- if (n >= 1<< 1) { pos += 1; }
- return pos;
-}
-
#ifndef DACCESS_COMPILE
void stomp_write_barrier_resize(bool is_runtime_suspended, bool requires_upper_bounds_check)
@@ -2181,15 +2197,22 @@ void stomp_write_barrier_resize(bool is_runtime_suspended, bool requires_upper_b
args.operation = WriteBarrierOp::StompResize;
args.is_runtime_suspended = is_runtime_suspended;
args.requires_upper_bounds_check = requires_upper_bounds_check;
+
args.card_table = g_gc_card_table;
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ args.card_bundle_table = g_gc_card_bundle_table;
+#endif
+
args.lowest_address = g_gc_lowest_address;
args.highest_address = g_gc_highest_address;
+
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
if (SoftwareWriteWatch::IsEnabledForGCHeap())
{
args.write_watch_table = g_gc_sw_ww_table;
}
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
+
GCToEEInterface::StompWriteBarrier(&args);
}
@@ -2210,6 +2233,11 @@ void stomp_write_barrier_initialize()
args.is_runtime_suspended = true;
args.requires_upper_bounds_check = false;
args.card_table = g_gc_card_table;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ args.card_bundle_table = g_gc_card_bundle_table;
+#endif
+
args.lowest_address = g_gc_lowest_address;
args.highest_address = g_gc_highest_address;
args.ephemeral_low = reinterpret_cast<uint8_t*>(1);
@@ -2257,8 +2285,8 @@ void virtual_free (void* add, size_t size);
/* per heap static initialization */
#ifdef MARK_ARRAY
#ifndef MULTIPLE_HEAPS
-SPTR_IMPL_NS(uint32_t, WKS, gc_heap, mark_array);
-#endif //!MULTIPLE_HEAPS
+uint32_t* gc_heap::mark_array;
+#endif //MULTIPLE_HEAPS
#endif //MARK_ARRAY
#ifdef MARK_LIST
@@ -2292,8 +2320,9 @@ CLREvent gc_heap::gc_start_event;
bool gc_heap::gc_thread_no_affinitize_p = false;
-SVAL_IMPL_NS(int, SVR, gc_heap, n_heaps);
-SPTR_IMPL_NS(PTR_gc_heap, SVR, gc_heap, g_heaps);
+int gc_heap::n_heaps;
+
+gc_heap** gc_heap::g_heaps;
size_t* gc_heap::g_promoted;
@@ -2384,11 +2413,7 @@ size_t gc_heap::ephemeral_fgc_counts[max_generation];
BOOL gc_heap::alloc_wait_event_p = FALSE;
-#if defined (DACCESS_COMPILE) && !defined (MULTIPLE_HEAPS)
-SVAL_IMPL_NS_INIT(gc_heap::c_gc_state, WKS, gc_heap, current_c_gc_state, c_gc_state_free);
-#else
-VOLATILE(gc_heap::c_gc_state) gc_heap::current_c_gc_state = c_gc_state_free;
-#endif //DACCESS_COMPILE && !MULTIPLE_HEAPS
+VOLATILE(c_gc_state) gc_heap::current_c_gc_state = c_gc_state_free;
#endif //BACKGROUND_GC
@@ -2409,14 +2434,14 @@ BOOL gc_heap::elevation_requested = FALSE;
BOOL gc_heap::last_gc_before_oom = FALSE;
#ifdef BACKGROUND_GC
-SPTR_IMPL_NS_INIT(uint8_t, WKS, gc_heap, background_saved_lowest_address, 0);
-SPTR_IMPL_NS_INIT(uint8_t, WKS, gc_heap, background_saved_highest_address, 0);
-SPTR_IMPL_NS_INIT(uint8_t, WKS, gc_heap, next_sweep_obj, 0);
+uint8_t* gc_heap::background_saved_lowest_address = 0;
+uint8_t* gc_heap::background_saved_highest_address = 0;
+uint8_t* gc_heap::next_sweep_obj = 0;
uint8_t* gc_heap::current_sweep_pos = 0;
exclusive_sync* gc_heap::bgc_alloc_lock;
#endif //BACKGROUND_GC
-SVAL_IMPL_NS(oom_history, WKS, gc_heap, oom_info);
+oom_history gc_heap::oom_info;
fgm_history gc_heap::fgm_result;
@@ -2467,7 +2492,7 @@ size_t gc_heap::allocation_running_time;
size_t gc_heap::allocation_running_amount;
-SPTR_IMPL_NS_INIT(heap_segment, WKS, gc_heap, ephemeral_heap_segment, 0);
+heap_segment* gc_heap::ephemeral_heap_segment = 0;
BOOL gc_heap::blocking_collection = FALSE;
@@ -2542,8 +2567,9 @@ uint8_t* gc_heap::background_min_soh_overflow_address =0;
uint8_t* gc_heap::background_max_soh_overflow_address =0;
-SPTR_IMPL_NS_INIT(heap_segment, WKS, gc_heap, saved_sweep_ephemeral_seg, 0);
-SPTR_IMPL_NS_INIT(uint8_t, WKS, gc_heap, saved_sweep_ephemeral_start, 0);
+heap_segment* gc_heap::saved_sweep_ephemeral_seg = 0;
+
+uint8_t* gc_heap::saved_sweep_ephemeral_start = 0;
heap_segment* gc_heap::saved_overflow_ephemeral_seg = 0;
@@ -2619,9 +2645,11 @@ size_t gc_heap::total_ephemeral_size = 0;
size_t gc_heap::internal_root_array_length = initial_internal_roots;
-SPTR_IMPL_NS_INIT(PTR_uint8_t, WKS, gc_heap, internal_root_array, 0);
-SVAL_IMPL_NS_INIT(size_t, WKS, gc_heap, internal_root_array_index, 0);
-SVAL_IMPL_NS_INIT(BOOL, WKS, gc_heap, heap_analyze_success, TRUE);
+uint8_t** gc_heap::internal_root_array = 0;
+
+size_t gc_heap::internal_root_array_index = 0;
+
+BOOL gc_heap::heap_analyze_success = TRUE;
uint8_t* gc_heap::current_obj = 0;
size_t gc_heap::current_obj_size = 0;
@@ -2681,24 +2709,6 @@ BOOL gc_heap::heap_analyze_enabled = FALSE;
#ifndef MULTIPLE_HEAPS
-#ifndef DACCESS_COMPILE
-extern "C" {
-#endif //!DACCESS_COMPILE
-GARY_IMPL(generation, generation_table,NUMBERGENERATIONS+1);
-#ifdef GC_CONFIG_DRIVEN
-GARY_IMPL(size_t, interesting_data_per_heap, max_idp_count);
-GARY_IMPL(size_t, compact_reasons_per_heap, max_compact_reasons_count);
-GARY_IMPL(size_t, expand_mechanisms_per_heap, max_expand_mechanisms_count);
-GARY_IMPL(size_t, interesting_mechanism_bits_per_heap, max_gc_mechanism_bits_count);
-#endif //GC_CONFIG_DRIVEN
-#ifndef DACCESS_COMPILE
-}
-#endif //!DACCESS_COMPILE
-
-#endif //MULTIPLE_HEAPS
-
-#ifndef MULTIPLE_HEAPS
-
alloc_list gc_heap::loh_alloc_list [NUM_LOH_ALIST-1];
alloc_list gc_heap::gen2_alloc_list[NUM_GEN2_ALIST-1];
@@ -2706,7 +2716,7 @@ dynamic_data gc_heap::dynamic_data_table [NUMBERGENERATIONS+1];
gc_history_per_heap gc_heap::gc_data_per_heap;
size_t gc_heap::maxgen_pinned_compact_before_advance = 0;
-SPTR_IMPL_NS_INIT(uint8_t, WKS, gc_heap, alloc_allocated, 0);
+uint8_t* gc_heap::alloc_allocated = 0;
size_t gc_heap::allocation_quantum = CLR_SIZE;
@@ -2724,6 +2734,7 @@ unsigned int gc_heap::num_low_msl_acquire = 0;
size_t gc_heap::alloc_contexts_used = 0;
size_t gc_heap::soh_allocation_no_gc = 0;
size_t gc_heap::loh_allocation_no_gc = 0;
+bool gc_heap::no_gc_oom_p = false;
heap_segment* gc_heap::saved_loh_segment_no_gc = 0;
#endif //MULTIPLE_HEAPS
@@ -2737,9 +2748,19 @@ int gc_heap::gen0_must_clear_bricks = 0;
#endif //FFIND_OBJECT
#ifdef FEATURE_PREMORTEM_FINALIZATION
-SPTR_IMPL_NS_INIT(CFinalize, WKS, gc_heap, finalize_queue, 0);
+CFinalize* gc_heap::finalize_queue = 0;
#endif // FEATURE_PREMORTEM_FINALIZATION
+generation gc_heap::generation_table [NUMBERGENERATIONS + 1];
+
+size_t gc_heap::interesting_data_per_heap[max_idp_count];
+
+size_t gc_heap::compact_reasons_per_heap[max_compact_reasons_count];
+
+size_t gc_heap::expand_mechanisms_per_heap[max_expand_mechanisms_count];
+
+size_t gc_heap::interesting_mechanism_bits_per_heap[max_gc_mechanism_bits_count];
+
#endif // MULTIPLE_HEAPS
/* end of per heap static initialization */
@@ -3697,8 +3718,6 @@ heap_segment* seg_mapping_table_segment_of (uint8_t* o)
if (seg)
{
- // Can't assert this when it's callled by everyone (it's true when it's called by mark cards).
- //assert (in_range_for_segment (o, seg));
if (in_range_for_segment (o, seg))
{
dprintf (2, ("obj %Ix belongs to segment %Ix(-%Ix)", o, (uint8_t*)heap_segment_mem(seg), (uint8_t*)heap_segment_reserved(seg)));
@@ -3735,7 +3754,6 @@ heap_segment* seg_mapping_table_segment_of (uint8_t* o)
#endif //SEG_MAPPING_TABLE
size_t gcard_of ( uint8_t*);
-void gset_card (size_t card);
#define memref(i) *(uint8_t**)(i)
@@ -3873,10 +3891,10 @@ public:
{
assert (size >= free_object_base_size);
- assert (g_pFreeObjectMethodTable->GetBaseSize() == free_object_base_size);
- assert (g_pFreeObjectMethodTable->RawGetComponentSize() == 1);
+ assert (g_gc_pFreeObjectMethodTable->GetBaseSize() == free_object_base_size);
+ assert (g_gc_pFreeObjectMethodTable->RawGetComponentSize() == 1);
- RawSetMethodTable( g_pFreeObjectMethodTable );
+ RawSetMethodTable( g_gc_pFreeObjectMethodTable );
size_t* numComponentsPtr = (size_t*) &((uint8_t*) this)[ArrayBase::GetOffsetOfNumComponents()];
*numComponentsPtr = size - free_object_base_size;
@@ -3901,7 +3919,7 @@ public:
BOOL IsFree () const
{
- return (GetMethodTable() == g_pFreeObjectMethodTable);
+ return (GetMethodTable() == g_gc_pFreeObjectMethodTable);
}
#ifdef FEATURE_STRUCTALIGN
@@ -4897,12 +4915,12 @@ class heap_select
static unsigned n_sniff_buffers;
static unsigned cur_sniff_index;
- static uint8_t proc_no_to_heap_no[MAX_SUPPORTED_CPUS];
- static uint8_t heap_no_to_proc_no[MAX_SUPPORTED_CPUS];
- static uint8_t heap_no_to_numa_node[MAX_SUPPORTED_CPUS];
- static uint8_t heap_no_to_cpu_group[MAX_SUPPORTED_CPUS];
- static uint8_t heap_no_to_group_proc[MAX_SUPPORTED_CPUS];
- static uint8_t numa_node_to_heap_map[MAX_SUPPORTED_CPUS+4];
+ static uint16_t proc_no_to_heap_no[MAX_SUPPORTED_CPUS];
+ static uint16_t heap_no_to_proc_no[MAX_SUPPORTED_CPUS];
+ static uint16_t heap_no_to_numa_node[MAX_SUPPORTED_CPUS];
+ static uint16_t heap_no_to_cpu_group[MAX_SUPPORTED_CPUS];
+ static uint16_t heap_no_to_group_proc[MAX_SUPPORTED_CPUS];
+ static uint16_t numa_node_to_heap_map[MAX_SUPPORTED_CPUS+4];
static int access_time(uint8_t *sniff_buffer, int heap_number, unsigned sniff_index, unsigned n_sniff_buffers)
{
@@ -4944,7 +4962,7 @@ public:
//can not enable gc numa aware, force all heaps to be in
//one numa node by filling the array with all 0s
if (!NumaNodeInfo::CanEnableGCNumaAware())
- memset(heap_no_to_numa_node, 0, MAX_SUPPORTED_CPUS);
+ memset(heap_no_to_numa_node, 0, sizeof (heap_no_to_numa_node));
return TRUE;
}
@@ -4954,10 +4972,10 @@ public:
if (GCToOSInterface::CanGetCurrentProcessorNumber())
{
uint32_t proc_no = GCToOSInterface::GetCurrentProcessorNumber() % gc_heap::n_heaps;
- // We can safely cast heap_number to a BYTE 'cause GetCurrentProcessCpuCount
+ // We can safely cast heap_number to a uint16_t 'cause GetCurrentProcessCpuCount
// only returns up to MAX_SUPPORTED_CPUS procs right now. We only ever create at most
// MAX_SUPPORTED_CPUS GC threads.
- proc_no_to_heap_no[proc_no] = (uint8_t)heap_number;
+ proc_no_to_heap_no[proc_no] = (uint16_t)heap_number;
}
}
@@ -5020,42 +5038,42 @@ public:
return GCToOSInterface::CanGetCurrentProcessorNumber();
}
- static uint8_t find_proc_no_from_heap_no(int heap_number)
+ static uint16_t find_proc_no_from_heap_no(int heap_number)
{
return heap_no_to_proc_no[heap_number];
}
- static void set_proc_no_for_heap(int heap_number, uint8_t proc_no)
+ static void set_proc_no_for_heap(int heap_number, uint16_t proc_no)
{
heap_no_to_proc_no[heap_number] = proc_no;
}
- static uint8_t find_numa_node_from_heap_no(int heap_number)
+ static uint16_t find_numa_node_from_heap_no(int heap_number)
{
return heap_no_to_numa_node[heap_number];
}
- static void set_numa_node_for_heap(int heap_number, uint8_t numa_node)
+ static void set_numa_node_for_heap(int heap_number, uint16_t numa_node)
{
heap_no_to_numa_node[heap_number] = numa_node;
}
- static uint8_t find_cpu_group_from_heap_no(int heap_number)
+ static uint16_t find_cpu_group_from_heap_no(int heap_number)
{
return heap_no_to_cpu_group[heap_number];
}
- static void set_cpu_group_for_heap(int heap_number, uint8_t group_number)
+ static void set_cpu_group_for_heap(int heap_number, uint16_t group_number)
{
heap_no_to_cpu_group[heap_number] = group_number;
}
- static uint8_t find_group_proc_from_heap_no(int heap_number)
+ static uint16_t find_group_proc_from_heap_no(int heap_number)
{
return heap_no_to_group_proc[heap_number];
}
- static void set_group_proc_for_heap(int heap_number, uint8_t group_proc)
+ static void set_group_proc_for_heap(int heap_number, uint16_t group_proc)
{
heap_no_to_group_proc[heap_number] = group_proc;
}
@@ -5070,15 +5088,15 @@ public:
for (int i=1; i < nheaps; i++)
{
if (heap_no_to_numa_node[i] != heap_no_to_numa_node[i-1])
- numa_node_to_heap_map[node_index++] = (uint8_t)i;
+ numa_node_to_heap_map[node_index++] = (uint16_t)i;
}
- numa_node_to_heap_map[node_index] = (uint8_t)nheaps; //mark the end with nheaps
+ numa_node_to_heap_map[node_index] = (uint16_t)nheaps; //mark the end with nheaps
}
static void get_heap_range_for_heap(int hn, int* start, int* end)
{ // 1-tier/no numa case: heap_no_to_numa_node[] all zeros,
// and treated as in one node. thus: start=0, end=n_heaps
- uint8_t numa_node = heap_no_to_numa_node[hn];
+ uint16_t numa_node = heap_no_to_numa_node[hn];
*start = (int)numa_node_to_heap_map[numa_node];
*end = (int)(numa_node_to_heap_map[numa_node+1]);
}
@@ -5086,12 +5104,12 @@ public:
uint8_t* heap_select::sniff_buffer;
unsigned heap_select::n_sniff_buffers;
unsigned heap_select::cur_sniff_index;
-uint8_t heap_select::proc_no_to_heap_no[MAX_SUPPORTED_CPUS];
-uint8_t heap_select::heap_no_to_proc_no[MAX_SUPPORTED_CPUS];
-uint8_t heap_select::heap_no_to_numa_node[MAX_SUPPORTED_CPUS];
-uint8_t heap_select::heap_no_to_cpu_group[MAX_SUPPORTED_CPUS];
-uint8_t heap_select::heap_no_to_group_proc[MAX_SUPPORTED_CPUS];
-uint8_t heap_select::numa_node_to_heap_map[MAX_SUPPORTED_CPUS+4];
+uint16_t heap_select::proc_no_to_heap_no[MAX_SUPPORTED_CPUS];
+uint16_t heap_select::heap_no_to_proc_no[MAX_SUPPORTED_CPUS];
+uint16_t heap_select::heap_no_to_numa_node[MAX_SUPPORTED_CPUS];
+uint16_t heap_select::heap_no_to_cpu_group[MAX_SUPPORTED_CPUS];
+uint16_t heap_select::heap_no_to_group_proc[MAX_SUPPORTED_CPUS];
+uint16_t heap_select::numa_node_to_heap_map[MAX_SUPPORTED_CPUS+4];
BOOL gc_heap::create_thread_support (unsigned number_of_heaps)
{
@@ -5150,8 +5168,8 @@ void set_thread_group_affinity_for_heap(int heap_number, GCThreadAffinity* affin
dprintf(3, ("using processor group %d, mask %Ix for heap %d\n", gn, mask, heap_number));
affinity->Processor = gpn;
affinity->Group = gn;
- heap_select::set_cpu_group_for_heap(heap_number, (uint8_t)gn);
- heap_select::set_group_proc_for_heap(heap_number, (uint8_t)gpn);
+ heap_select::set_cpu_group_for_heap(heap_number, gn);
+ heap_select::set_group_proc_for_heap(heap_number, gpn);
if (NumaNodeInfo::CanEnableGCNumaAware())
{
PROCESSOR_NUMBER proc_no;
@@ -5161,11 +5179,11 @@ void set_thread_group_affinity_for_heap(int heap_number, GCThreadAffinity* affin
uint16_t node_no = 0;
if (NumaNodeInfo::GetNumaProcessorNodeEx(&proc_no, &node_no))
- heap_select::set_numa_node_for_heap(heap_number, (uint8_t)node_no);
+ heap_select::set_numa_node_for_heap(heap_number, node_no);
}
else
{ // no numa setting, each cpu group is treated as a node
- heap_select::set_numa_node_for_heap(heap_number, (uint8_t)gn);
+ heap_select::set_numa_node_for_heap(heap_number, gn);
}
return;
}
@@ -5202,7 +5220,7 @@ void set_thread_affinity_mask_for_heap(int heap_number, GCThreadAffinity* affini
proc_no.Reserved = 0;
if (NumaNodeInfo::GetNumaProcessorNodeEx(&proc_no, &node_no))
{
- heap_select::set_numa_node_for_heap(heap_number, (uint8_t)node_no);
+ heap_select::set_numa_node_for_heap(heap_number, node_no);
}
}
return;
@@ -5226,9 +5244,9 @@ bool gc_heap::create_gc_thread ()
#if !defined(FEATURE_PAL)
if (!gc_thread_no_affinitize_p)
{
- //We are about to set affinity for GC threads, it is a good place to setup NUMA and
- //CPU groups, because the process mask, processor number, group number are all
- //readyly available.
+ // We are about to set affinity for GC threads. It is a good place to set up NUMA and
+ // CPU groups because the process mask, processor number, and group number are all
+ // readily available.
if (CPUGroupInfo::CanEnableGCCPUGroups())
set_thread_group_affinity_for_heap(heap_number, &affinity);
else
@@ -5342,7 +5360,9 @@ bool virtual_alloc_commit_for_heap(void* addr, size_t size, int h_number)
#if defined(MULTIPLE_HEAPS) && !defined(FEATURE_REDHAWK) && !defined(FEATURE_PAL)
// Currently there is no way for us to specific the numa node to allocate on via hosting interfaces to
// a host. This will need to be added later.
+#if !defined(FEATURE_CORECLR)
if (!CLRMemoryHosted())
+#endif
{
if (NumaNodeInfo::CanEnableGCNumaAware())
{
@@ -5569,7 +5589,7 @@ public:
// We should think about whether it's really necessary to have to copy back the pre plug
// info since it was already copied during compacting plugs. But if a plug doesn't move
- // by < 3 ptr size, it means we'd have to recover pre plug info.
+ // by >= 3 ptr size (the size of gap_reloc_pair), it means we'd have to recover pre plug info.
void recover_plug_info()
{
if (saved_pre_p)
@@ -5714,18 +5734,13 @@ void gc_mechanisms::record (gc_history_global* history)
//as opposed to concurrent heap verification
void gc_heap::fix_youngest_allocation_area (BOOL for_gc_p)
{
- assert (alloc_allocated);
- alloc_context* acontext = generation_alloc_context (youngest_generation);
- dprintf (3, ("generation 0 alloc context: ptr: %Ix, limit %Ix",
- (size_t)acontext->alloc_ptr, (size_t)acontext->alloc_limit));
- fix_allocation_context (acontext, for_gc_p, get_alignment_constant (TRUE));
- if (for_gc_p)
- {
- acontext->alloc_ptr = alloc_allocated;
- acontext->alloc_limit = acontext->alloc_ptr;
- }
- heap_segment_allocated (ephemeral_heap_segment) =
- alloc_allocated;
+ UNREFERENCED_PARAMETER(for_gc_p);
+
+ // The gen 0 alloc context is never used for allocation in the allocator path. It's
+ // still used in the allocation path during GCs.
+ assert (generation_allocation_pointer (youngest_generation) == nullptr);
+ assert (generation_allocation_limit (youngest_generation) == nullptr);
+ heap_segment_allocated (ephemeral_heap_segment) = alloc_allocated;
}
void gc_heap::fix_large_allocation_area (BOOL for_gc_p)
@@ -5791,9 +5806,10 @@ void gc_heap::fix_allocation_context (alloc_context* acontext, BOOL for_gc_p,
alloc_contexts_used ++;
}
-
if (for_gc_p)
{
+ // We need to update the alloc_bytes to reflect the portion that we have not used
+ acontext->alloc_bytes -= (acontext->alloc_limit - acontext->alloc_ptr);
acontext->alloc_ptr = 0;
acontext->alloc_limit = acontext->alloc_ptr;
}
@@ -5830,12 +5846,6 @@ void void_allocation (gc_alloc_context* acontext, void*)
void gc_heap::repair_allocation_contexts (BOOL repair_p)
{
GCToEEInterface::GcEnumAllocContexts (repair_p ? repair_allocation : void_allocation, NULL);
-
- alloc_context* acontext = generation_alloc_context (youngest_generation);
- if (repair_p)
- repair_allocation (acontext, NULL);
- else
- void_allocation (acontext, NULL);
}
struct fix_alloc_context_args
@@ -5847,7 +5857,7 @@ struct fix_alloc_context_args
void fix_alloc_context(gc_alloc_context* acontext, void* param)
{
fix_alloc_context_args* args = (fix_alloc_context_args*)param;
- g_theGCHeap->FixAllocContext(acontext, FALSE, (void*)(size_t)(args->for_gc_p), args->heap);
+ g_theGCHeap->FixAllocContext(acontext, false, (void*)(size_t)(args->for_gc_p), args->heap);
}
void gc_heap::fix_allocation_contexts(BOOL for_gc_p)
@@ -5855,8 +5865,8 @@ void gc_heap::fix_allocation_contexts(BOOL for_gc_p)
fix_alloc_context_args args;
args.for_gc_p = for_gc_p;
args.heap = __this;
- GCToEEInterface::GcEnumAllocContexts(fix_alloc_context, &args);
+ GCToEEInterface::GcEnumAllocContexts(fix_alloc_context, &args);
fix_youngest_allocation_area(for_gc_p);
fix_large_allocation_area(for_gc_p);
}
@@ -6289,6 +6299,150 @@ void gc_heap::make_c_mark_list (uint8_t** arr)
}
#endif //BACKGROUND_GC
+
+#ifdef CARD_BUNDLE
+
+// The card bundle keeps track of groups of card words.
+static const size_t card_bundle_word_width = 32;
+
+// How do we express the fact that 32 bits (card_word_width) is one uint32_t?
+static const size_t card_bundle_size = (size_t)(OS_PAGE_SIZE / (sizeof(uint32_t)*card_bundle_word_width));
+
+inline
+size_t card_bundle_word (size_t cardb)
+{
+ return cardb / card_bundle_word_width;
+}
+
+inline
+uint32_t card_bundle_bit (size_t cardb)
+{
+ return (uint32_t)(cardb % card_bundle_word_width);
+}
+
+size_t align_cardw_on_bundle (size_t cardw)
+{
+ return ((size_t)(cardw + card_bundle_size - 1) & ~(card_bundle_size - 1 ));
+}
+
+// Get the card bundle representing a card word
+size_t cardw_card_bundle (size_t cardw)
+{
+ return cardw / card_bundle_size;
+}
+
+// Get the first card word in a card bundle
+size_t card_bundle_cardw (size_t cardb)
+{
+ return cardb * card_bundle_size;
+}
+
+// Clear the specified card bundle
+void gc_heap::card_bundle_clear (size_t cardb)
+{
+ card_bundle_table [card_bundle_word (cardb)] &= ~(1 << card_bundle_bit (cardb));
+ dprintf (1,("Cleared card bundle %Ix [%Ix, %Ix[", cardb, (size_t)card_bundle_cardw (cardb),
+ (size_t)card_bundle_cardw (cardb+1)));
+}
+
+void gc_heap::card_bundle_set (size_t cardb)
+{
+ if (!card_bundle_set_p (cardb))
+ {
+ card_bundle_table [card_bundle_word (cardb)] |= (1 << card_bundle_bit (cardb));
+ }
+}
+
+// Set the card bundle bits between start_cardb and end_cardb
+void gc_heap::card_bundles_set (size_t start_cardb, size_t end_cardb)
+{
+ if (start_cardb == end_cardb)
+ {
+ card_bundle_set(start_cardb);
+ return;
+ }
+
+ size_t start_word = card_bundle_word (start_cardb);
+ size_t end_word = card_bundle_word (end_cardb);
+
+ if (start_word < end_word)
+ {
+ // Set the partial words
+ card_bundle_table [start_word] |= highbits (~0u, card_bundle_bit (start_cardb));
+
+ if (card_bundle_bit (end_cardb))
+ card_bundle_table [end_word] |= lowbits (~0u, card_bundle_bit (end_cardb));
+
+ // Set the full words
+ for (size_t i = start_word + 1; i < end_word; i++)
+ card_bundle_table [i] = ~0u;
+ }
+ else
+ {
+ card_bundle_table [start_word] |= (highbits (~0u, card_bundle_bit (start_cardb)) &
+ lowbits (~0u, card_bundle_bit (end_cardb)));
+ }
+}
+
+// Indicates whether the specified bundle is set.
+BOOL gc_heap::card_bundle_set_p (size_t cardb)
+{
+ return (card_bundle_table[card_bundle_word(cardb)] & (1 << card_bundle_bit (cardb)));
+}
+
+// Returns the size (in bytes) of a card bundle representing the region from 'from' to 'end'
+size_t size_card_bundle_of (uint8_t* from, uint8_t* end)
+{
+ // Number of heap bytes represented by a card bundle word
+ size_t cbw_span = card_size * card_word_width * card_bundle_size * card_bundle_word_width;
+
+ // Align the start of the region down
+ from = (uint8_t*)((size_t)from & ~(cbw_span - 1));
+
+ // Align the end of the region up
+ end = (uint8_t*)((size_t)(end + (cbw_span - 1)) & ~(cbw_span - 1));
+
+ // Make sure they're really aligned
+ assert (((size_t)from & (cbw_span - 1)) == 0);
+ assert (((size_t)end & (cbw_span - 1)) == 0);
+
+ return ((end - from) / cbw_span) * sizeof (uint32_t);
+}
+
+// Takes a pointer to a card bundle table and an address, and returns a pointer that represents
+// where a theoretical card bundle table that represents every address (starting from 0) would
+// start if the bundle word representing the address were to be located at the pointer passed in.
+// The returned 'translated' pointer makes it convenient/fast to calculate where the card bundle
+// for a given address is using a simple shift operation on the address.
+uint32_t* translate_card_bundle_table (uint32_t* cb, uint8_t* lowest_address)
+{
+ // The number of bytes of heap memory represented by a card bundle word
+ const size_t heap_bytes_for_bundle_word = card_size * card_word_width * card_bundle_size * card_bundle_word_width;
+
+ // Each card bundle word is 32 bits
+ return (uint32_t*)((uint8_t*)cb - (((size_t)lowest_address / heap_bytes_for_bundle_word) * sizeof (uint32_t)));
+}
+
+void gc_heap::enable_card_bundles ()
+{
+ if (can_use_write_watch_for_card_table() && (!card_bundles_enabled()))
+ {
+ dprintf (1, ("Enabling card bundles"));
+
+ // We initially set all of the card bundles
+ card_bundles_set (cardw_card_bundle (card_word (card_of (lowest_address))),
+ cardw_card_bundle (align_cardw_on_bundle (card_word (card_of (highest_address)))));
+ settings.card_bundles = TRUE;
+ }
+}
+
+BOOL gc_heap::card_bundles_enabled ()
+{
+ return settings.card_bundles;
+}
+
+#endif // CARD_BUNDLE
+
#if defined (_TARGET_AMD64_)
#define brick_size ((size_t)4096)
#else
@@ -6418,14 +6572,18 @@ void gc_heap::clear_card (size_t card)
inline
void gc_heap::set_card (size_t card)
{
- card_table [card_word (card)] =
- (card_table [card_word (card)] | (1 << card_bit (card)));
-}
+ size_t word = card_word (card);
+ card_table[word] = (card_table [word] | (1 << card_bit (card)));
-inline
-void gset_card (size_t card)
-{
- g_gc_card_table [card_word (card)] |= (1 << card_bit (card));
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ // Also set the card bundle that corresponds to the card
+ size_t bundle_to_set = cardw_card_bundle(word);
+
+ card_bundle_set(bundle_to_set);
+
+ dprintf (3,("Set card %Ix [%Ix, %Ix[ and bundle %Ix", card, (size_t)card_address (card), (size_t)card_address (card+1), bundle_to_set));
+ assert(card_bundle_set_p(bundle_to_set) != 0);
+#endif
}
inline
@@ -6448,116 +6606,6 @@ size_t size_card_of (uint8_t* from, uint8_t* end)
return count_card_of (from, end) * sizeof(uint32_t);
}
-#ifdef CARD_BUNDLE
-
-//The card bundle keeps track of groups of card words
-#define card_bundle_word_width ((size_t)32)
-//how do we express the fact that 32 bits (card_word_width) is one uint32_t?
-#define card_bundle_size ((size_t)(OS_PAGE_SIZE/(sizeof (uint32_t)*card_bundle_word_width)))
-
-inline
-size_t card_bundle_word (size_t cardb)
-{
- return cardb / card_bundle_word_width;
-}
-
-inline
-uint32_t card_bundle_bit (size_t cardb)
-{
- return (uint32_t)(cardb % card_bundle_word_width);
-}
-
-size_t align_cardw_on_bundle (size_t cardw)
-{
- return ((size_t)(cardw + card_bundle_size - 1) & ~(card_bundle_size - 1 ));
-}
-
-size_t cardw_card_bundle (size_t cardw)
-{
- return cardw/card_bundle_size;
-}
-
-size_t card_bundle_cardw (size_t cardb)
-{
- return cardb*card_bundle_size;
-}
-
-void gc_heap::card_bundle_clear(size_t cardb)
-{
- card_bundle_table [card_bundle_word (cardb)] &= ~(1 << card_bundle_bit (cardb));
- dprintf (3,("Cleared card bundle %Ix [%Ix, %Ix[", cardb, (size_t)card_bundle_cardw (cardb),
- (size_t)card_bundle_cardw (cardb+1)));
-// printf ("Cleared card bundle %Ix\n", cardb);
-}
-
-void gc_heap::card_bundles_set (size_t start_cardb, size_t end_cardb)
-{
- size_t start_word = card_bundle_word (start_cardb);
- size_t end_word = card_bundle_word (end_cardb);
- if (start_word < end_word)
- {
- //set the partial words
- card_bundle_table [start_word] |= highbits (~0u, card_bundle_bit (start_cardb));
-
- if (card_bundle_bit (end_cardb))
- card_bundle_table [end_word] |= lowbits (~0u, card_bundle_bit (end_cardb));
-
- for (size_t i = start_word+1; i < end_word; i++)
- card_bundle_table [i] = ~0u;
-
- }
- else
- {
- card_bundle_table [start_word] |= (highbits (~0u, card_bundle_bit (start_cardb)) &
- lowbits (~0u, card_bundle_bit (end_cardb)));
-
- }
-
-}
-
-BOOL gc_heap::card_bundle_set_p (size_t cardb)
-{
- return ( card_bundle_table [ card_bundle_word (cardb) ] & (1 << card_bundle_bit (cardb)));
-}
-
-size_t size_card_bundle_of (uint8_t* from, uint8_t* end)
-{
- //align from to lower
- from = (uint8_t*)((size_t)from & ~(card_size*card_word_width*card_bundle_size*card_bundle_word_width - 1));
- //align to to upper
- end = (uint8_t*)((size_t)(end + (card_size*card_word_width*card_bundle_size*card_bundle_word_width - 1)) &
- ~(card_size*card_word_width*card_bundle_size*card_bundle_word_width - 1));
-
- assert (((size_t)from & ((card_size*card_word_width*card_bundle_size*card_bundle_word_width)-1)) == 0);
- assert (((size_t)end & ((card_size*card_word_width*card_bundle_size*card_bundle_word_width)-1)) == 0);
-
- return ((end - from) / (card_size*card_word_width*card_bundle_size*card_bundle_word_width)) * sizeof (uint32_t);
-}
-
-uint32_t* translate_card_bundle_table (uint32_t* cb)
-{
- return (uint32_t*)((uint8_t*)cb - ((((size_t)g_gc_lowest_address) / (card_size*card_word_width*card_bundle_size*card_bundle_word_width)) * sizeof (uint32_t)));
-}
-
-void gc_heap::enable_card_bundles ()
-{
- if (can_use_write_watch_for_card_table() && (!card_bundles_enabled()))
- {
- dprintf (3, ("Enabling card bundles"));
- //set all of the card bundles
- card_bundles_set (cardw_card_bundle (card_word (card_of (lowest_address))),
- cardw_card_bundle (align_cardw_on_bundle (card_word (card_of (highest_address)))));
- settings.card_bundles = TRUE;
- }
-}
-
-BOOL gc_heap::card_bundles_enabled ()
-{
- return settings.card_bundles;
-}
-
-#endif //CARD_BUNDLE
-
// We don't store seg_mapping_table in card_table_info because there's only always one view.
class card_table_info
{
@@ -6612,6 +6660,7 @@ short*& card_table_brick_table (uint32_t* c_table)
}
#ifdef CARD_BUNDLE
+// Get the card bundle table for the specified card table.
inline
uint32_t*& card_table_card_bundle_table (uint32_t* c_table)
{
@@ -6879,6 +6928,10 @@ void release_card_table (uint32_t* c_table)
if (&g_gc_card_table[card_word (gcard_of(g_gc_lowest_address))] == c_table)
{
g_gc_card_table = 0;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ g_gc_card_bundle_table = 0;
+#endif
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
SoftwareWriteWatch::StaticClose();
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
@@ -6927,8 +6980,12 @@ uint32_t* gc_heap::make_card_table (uint8_t* start, uint8_t* end)
#ifdef CARD_BUNDLE
if (can_use_write_watch_for_card_table())
{
- virtual_reserve_flags |= VirtualReserveFlags::WriteWatch;
cb = size_card_bundle_of (g_gc_lowest_address, g_gc_highest_address);
+#ifndef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ // If we're not manually managing the card bundles, we will need to use OS write
+ // watch APIs over this region to track changes.
+ virtual_reserve_flags |= VirtualReserveFlags::WriteWatch;
+#endif
}
#endif //CARD_BUNDLE
@@ -6987,6 +7044,11 @@ uint32_t* gc_heap::make_card_table (uint8_t* start, uint8_t* end)
#ifdef CARD_BUNDLE
card_table_card_bundle_table (ct) = (uint32_t*)((uint8_t*)card_table_brick_table (ct) + bs);
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ g_gc_card_bundle_table = translate_card_bundle_table(card_table_card_bundle_table(ct), g_gc_lowest_address);
+#endif
+
#endif //CARD_BUNDLE
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
@@ -7097,6 +7159,11 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
bool write_barrier_updated = false;
uint32_t virtual_reserve_flags = VirtualReserveFlags::None;
uint32_t* saved_g_card_table = g_gc_card_table;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ uint32_t* saved_g_card_bundle_table = g_gc_card_bundle_table;
+#endif
+
uint32_t* ct = 0;
uint32_t* translated_ct = 0;
short* bt = 0;
@@ -7117,8 +7184,13 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
#ifdef CARD_BUNDLE
if (can_use_write_watch_for_card_table())
{
- virtual_reserve_flags = VirtualReserveFlags::WriteWatch;
cb = size_card_bundle_of (saved_g_lowest_address, saved_g_highest_address);
+
+#ifndef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ // If we're not manually managing the card bundles, we will need to use OS write
+ // watch APIs over this region to track changes.
+ virtual_reserve_flags |= VirtualReserveFlags::WriteWatch;
+#endif
}
#endif //CARD_BUNDLE
@@ -7280,6 +7352,11 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
}
g_gc_card_table = translated_ct;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ g_gc_card_bundle_table = translate_card_bundle_table(card_table_card_bundle_table(ct), saved_g_lowest_address);
+#endif
+
SoftwareWriteWatch::SetResizedUntranslatedTable(
mem + sw_ww_table_offset,
saved_g_lowest_address,
@@ -7304,6 +7381,10 @@ int gc_heap::grow_brick_card_tables (uint8_t* start,
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
{
g_gc_card_table = translated_ct;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ g_gc_card_bundle_table = translate_card_bundle_table(card_table_card_bundle_table(ct), saved_g_lowest_address);
+#endif
}
seg_mapping_table = new_seg_mapping_table;
@@ -7335,6 +7416,10 @@ fail:
{
assert(g_gc_card_table == saved_g_card_table);
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ assert(g_gc_card_bundle_table == saved_g_card_bundle_table);
+#endif
+
//delete (uint32_t*)((uint8_t*)ct - sizeof(card_table_info));
if (!GCToOSInterface::VirtualRelease (mem, alloc_size_aligned))
{
@@ -7438,12 +7523,23 @@ void gc_heap::copy_brick_card_range (uint8_t* la, uint32_t* old_card_table,
(card_table_lowest_address (ct) <= start))
{
// or the card_tables
- uint32_t* dest = &card_table [card_word (card_of (start))];
- uint32_t* src = &((translate_card_table (ct)) [card_word (card_of (start))]);
+
+ size_t start_word = card_word (card_of (start));
+
+ uint32_t* dest = &card_table[start_word];
+ uint32_t* src = &((translate_card_table (ct))[start_word]);
ptrdiff_t count = count_card_of (start, end);
for (int x = 0; x < count; x++)
{
*dest |= *src;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ if (*src != 0)
+ {
+ card_bundle_set(cardw_card_bundle(start_word+x));
+ }
+#endif
+
dest++;
src++;
}
@@ -7519,7 +7615,10 @@ void gc_heap::copy_brick_card_table()
size_t st = 0;
#endif //GROWABLE_SEG_MAPPING_TABLE
#endif //MARK_ARRAY && _DEBUG
- card_bundle_table = translate_card_bundle_table (card_table_card_bundle_table (ct));
+ card_bundle_table = translate_card_bundle_table (card_table_card_bundle_table (ct), g_gc_lowest_address);
+
+ // Ensure that the word that represents g_gc_lowest_address in the translated table is located at the
+ // start of the untranslated table.
assert (&card_bundle_table [card_bundle_word (cardw_card_bundle (card_word (card_of (g_gc_lowest_address))))] ==
card_table_card_bundle_table (ct));
@@ -9341,89 +9440,112 @@ static unsigned int tot_cycles = 0;
#ifdef CARD_BUNDLE
+inline void gc_heap::verify_card_bundle_bits_set(size_t first_card_word, size_t last_card_word)
+{
+#ifdef _DEBUG
+ for (size_t x = cardw_card_bundle (first_card_word); x < cardw_card_bundle (last_card_word); x++)
+ {
+ if (!card_bundle_set_p (x))
+ {
+ assert (!"Card bundle not set");
+ dprintf (3, ("Card bundle %Ix not set", x));
+ }
+ }
+#endif
+}
+
+// Verifies that any bundles that are not set represent only cards that are not set.
+inline void gc_heap::verify_card_bundles()
+{
+#ifdef _DEBUG
+ size_t lowest_card = card_word (card_of (lowest_address));
+ size_t highest_card = card_word (card_of (highest_address));
+ size_t cardb = cardw_card_bundle (lowest_card);
+ size_t end_cardb = cardw_card_bundle (align_cardw_on_bundle (highest_card));
+
+ while (cardb < end_cardb)
+ {
+ uint32_t* card_word = &card_table[max(card_bundle_cardw (cardb), lowest_card)];
+ uint32_t* card_word_end = &card_table[min(card_bundle_cardw (cardb+1), highest_card)];
+
+ if (card_bundle_set_p (cardb) == 0)
+ {
+ // Verify that no card is set
+ while (card_word < card_word_end)
+ {
+ if (*card_word != 0)
+ {
+ dprintf (3, ("gc: %d, Card word %Ix for address %Ix set, card_bundle %Ix clear",
+ dd_collection_count (dynamic_data_of (0)),
+ (size_t)(card_word-&card_table[0]),
+ (size_t)(card_address ((size_t)(card_word-&card_table[0]) * card_word_width)), cardb));
+ }
+
+ assert((*card_word)==0);
+ card_word++;
+ }
+ }
+
+ cardb++;
+ }
+#endif
+}
+
+// If card bundles are enabled, use write watch to find pages in the card table that have
+// been dirtied, and set the corresponding card bundle bits.
void gc_heap::update_card_table_bundle()
{
if (card_bundles_enabled())
{
+ // The address of the card word containing the card representing the lowest heap address
uint8_t* base_address = (uint8_t*)(&card_table[card_word (card_of (lowest_address))]);
+
+ // The address of the card word containing the card representing the highest heap address
+ uint8_t* high_address = (uint8_t*)(&card_table[card_word (card_of (highest_address))]);
+
uint8_t* saved_base_address = base_address;
uintptr_t bcount = array_size;
- uint8_t* high_address = (uint8_t*)(&card_table[card_word (card_of (highest_address))]);
size_t saved_region_size = align_on_page (high_address) - saved_base_address;
do
{
size_t region_size = align_on_page (high_address) - base_address;
+
dprintf (3,("Probing card table pages [%Ix, %Ix[", (size_t)base_address, (size_t)base_address+region_size));
- bool success = GCToOSInterface::GetWriteWatch (false /* resetState */ , base_address, region_size,
- (void**)g_addresses,
- &bcount);
+ bool success = GCToOSInterface::GetWriteWatch(false /* resetState */,
+ base_address,
+ region_size,
+ (void**)g_addresses,
+ &bcount);
assert (success && "GetWriteWatch failed!");
+
dprintf (3,("Found %d pages written", bcount));
- for (unsigned i = 0; i < bcount; i++)
+ for (unsigned i = 0; i < bcount; i++)
{
+ // Offset of the dirty page from the start of the card table (clamped to base_address)
size_t bcardw = (uint32_t*)(max(g_addresses[i],base_address)) - &card_table[0];
+
+ // Offset of the end of the page from the start of the card table (clamped to high addr)
size_t ecardw = (uint32_t*)(min(g_addresses[i]+OS_PAGE_SIZE, high_address)) - &card_table[0];
assert (bcardw >= card_word (card_of (g_gc_lowest_address)));
- card_bundles_set (cardw_card_bundle (bcardw),
- cardw_card_bundle (align_cardw_on_bundle (ecardw)));
-
- dprintf (3,("Set Card bundle [%Ix, %Ix[",
- cardw_card_bundle (bcardw), cardw_card_bundle (align_cardw_on_bundle (ecardw))));
-
-#ifdef _DEBUG
- for (size_t x = cardw_card_bundle (bcardw); x < cardw_card_bundle (ecardw); x++)
- {
- if (!card_bundle_set_p (x))
- {
- assert (!"Card bundle not set");
- dprintf (3, ("Card bundle %Ix not set", x));
- }
- }
-#endif //_DEBUG
+ // Set the card bundle bits representing the dirty card table page
+ card_bundles_set (cardw_card_bundle (bcardw), cardw_card_bundle (align_cardw_on_bundle (ecardw)));
+ dprintf (3,("Set Card bundle [%Ix, %Ix[", cardw_card_bundle (bcardw), cardw_card_bundle (align_cardw_on_bundle (ecardw))));
+ verify_card_bundle_bits_set(bcardw, ecardw);
}
- if (bcount >= array_size){
+
+ if (bcount >= array_size)
+ {
base_address = g_addresses [array_size-1] + OS_PAGE_SIZE;
bcount = array_size;
}
+
} while ((bcount >= array_size) && (base_address < high_address));
+ // Now that we've updated the card bundle bits, reset the write-tracking state.
GCToOSInterface::ResetWriteWatch (saved_base_address, saved_region_size);
-
-#ifdef _DEBUG
-
- size_t lowest_card = card_word (card_of (lowest_address));
- size_t highest_card = card_word (card_of (highest_address));
- size_t cardb = cardw_card_bundle (lowest_card);
- size_t end_cardb = cardw_card_bundle (align_cardw_on_bundle (highest_card));
-
- //find a non null bundle
- while (cardb < end_cardb)
- {
- if (card_bundle_set_p (cardb)==0)
- {
- //verify that the cards are indeed empty
- uint32_t* card_word = &card_table[max(card_bundle_cardw (cardb), lowest_card)];
- uint32_t* card_word_end = &card_table[min(card_bundle_cardw (cardb+1), highest_card)];
- while (card_word < card_word_end)
- {
- if ((*card_word) != 0)
- {
- dprintf (3, ("gc: %d, Card word %Ix for address %Ix set, card_bundle %Ix clear",
- dd_collection_count (dynamic_data_of (0)),
- (size_t)(card_word-&card_table[0]),
- (size_t)(card_address ((size_t)(card_word-&card_table[0]) * card_word_width)), cardb));
- }
- assert((*card_word)==0);
- card_word++;
- }
- }
- //end of verification
- cardb++;
- }
-#endif //_DEBUG
}
}
#endif //CARD_BUNDLE
@@ -10346,7 +10468,7 @@ gc_heap::init_gc_heap (int h_number)
lowest_address = card_table_lowest_address (ct);
#ifdef CARD_BUNDLE
- card_bundle_table = translate_card_bundle_table (card_table_card_bundle_table (ct));
+ card_bundle_table = translate_card_bundle_table (card_table_card_bundle_table (ct), g_gc_lowest_address);
assert (&card_bundle_table [card_bundle_word (cardw_card_bundle (card_word (card_of (g_gc_lowest_address))))] ==
card_table_card_bundle_table (ct));
#endif //CARD_BUNDLE
@@ -11260,6 +11382,13 @@ void gc_heap::adjust_limit_clr (uint8_t* start, size_t limit_size,
}
acontext->alloc_ptr = start;
}
+ else
+ {
+ // If the next alloc context is right up against the current one it means we are absorbing the min
+ // object, so need to account for that.
+ acontext->alloc_bytes += (start - acontext->alloc_limit);
+ }
+
acontext->alloc_limit = (start + limit_size - aligned_min_obj_size);
acontext->alloc_bytes += limit_size - ((gen_number < max_generation + 1) ? aligned_min_obj_size : 0);
@@ -13219,11 +13348,11 @@ try_again:
if (CPUGroupInfo::CanEnableGCCPUGroups())
{ //only set ideal processor when max_hp and org_hp are in the same cpu
//group. DO NOT MOVE THREADS ACROSS CPU GROUPS
- uint8_t org_gn = heap_select::find_cpu_group_from_heap_no(org_hp->heap_number);
- uint8_t max_gn = heap_select::find_cpu_group_from_heap_no(max_hp->heap_number);
+ uint16_t org_gn = heap_select::find_cpu_group_from_heap_no(org_hp->heap_number);
+ uint16_t max_gn = heap_select::find_cpu_group_from_heap_no(max_hp->heap_number);
if (org_gn == max_gn) //only set within CPU group, so SetThreadIdealProcessor is enough
{
- uint8_t group_proc_no = heap_select::find_group_proc_from_heap_no(max_hp->heap_number);
+ uint16_t group_proc_no = heap_select::find_group_proc_from_heap_no(max_hp->heap_number);
GCThreadAffinity affinity;
affinity.Processor = group_proc_no;
@@ -13237,7 +13366,7 @@ try_again:
}
else
{
- uint8_t proc_no = heap_select::find_proc_no_from_heap_no(max_hp->heap_number);
+ uint16_t proc_no = heap_select::find_proc_no_from_heap_no(max_hp->heap_number);
GCThreadAffinity affinity;
affinity.Processor = proc_no;
@@ -14068,7 +14197,8 @@ uint8_t* gc_heap::allocate_in_condemned_generations (generation* gen,
to_gen_number = from_gen_number + (settings.promotion ? 1 : 0);
}
- dprintf (3, ("aic gen%d: s: %Id", gen->gen_num, size));
+ dprintf (3, ("aic gen%d: s: %Id, %d->%d, %Ix->%Ix", gen->gen_num, size, from_gen_number,
+ to_gen_number, generation_allocation_pointer(gen), generation_allocation_limit(gen)));
int pad_in_front = (old_loc != 0) ? USE_PADDING_FRONT : 0;
@@ -15006,26 +15136,21 @@ exit:
}
}
-#ifndef FEATURE_REDHAWK
- if (n == max_generation)
+ if (n == max_generation && GCToEEInterface::ForceFullGCToBeBlocking())
{
- if (SystemDomain::System()->RequireAppDomainCleanup())
- {
#ifdef BACKGROUND_GC
- // do not turn stress-induced collections into blocking GCs, unless there
- // have already been more full BGCs than full NGCs
+ // do not turn stress-induced collections into blocking GCs, unless there
+ // have already been more full BGCs than full NGCs
#if 0
- // This exposes DevDiv 94129, so we'll leave this out for now
- if (!settings.stress_induced ||
- full_gc_counts[gc_type_blocking] <= full_gc_counts[gc_type_background])
+ // This exposes DevDiv 94129, so we'll leave this out for now
+ if (!settings.stress_induced ||
+ full_gc_counts[gc_type_blocking] <= full_gc_counts[gc_type_background])
#endif // 0
#endif // BACKGROUND_GC
- {
- *blocking_collection_p = TRUE;
- }
+ {
+ *blocking_collection_p = TRUE;
}
}
-#endif //!FEATURE_REDHAWK
return n;
}
@@ -15219,6 +15344,10 @@ void gc_heap::gc1()
assert (g_gc_card_table == card_table);
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ assert (g_gc_card_bundle_table == card_bundle_table);
+#endif
+
{
if (n == max_generation)
{
@@ -15753,8 +15882,10 @@ start_no_gc_region_status gc_heap::prepare_for_no_gc_region (uint64_t total_size
size_t allocation_no_gc_soh = 0;
size_t size_per_heap = 0;
+ total_size = (size_t)((float)total_size * 1.05);
if (loh_size_known)
{
+ loh_size = (size_t)((float)loh_size * 1.05);
allocation_no_gc_loh = (size_t)loh_size;
allocation_no_gc_soh = (size_t)(total_size - loh_size);
}
@@ -15765,12 +15896,14 @@ start_no_gc_region_status gc_heap::prepare_for_no_gc_region (uint64_t total_size
}
size_t soh_segment_size = get_valid_segment_size();
+ int soh_align_const = get_alignment_constant (TRUE);
+ size_t max_soh_allocated = (soh_segment_size - OS_PAGE_SIZE - eph_gen_starts_size);
int num_heaps = 1;
#ifdef MULTIPLE_HEAPS
num_heaps = n_heaps;
#endif //MULTIPLE_HEAPS
- size_t total_allowed_soh_allocation = (soh_segment_size - OS_PAGE_SIZE) * num_heaps;
+ size_t total_allowed_soh_allocation = max_soh_allocated * num_heaps;
if (allocation_no_gc_soh > total_allowed_soh_allocation)
{
@@ -15783,24 +15916,23 @@ start_no_gc_region_status gc_heap::prepare_for_no_gc_region (uint64_t total_size
if (allocation_no_gc_soh != 0)
{
- current_no_gc_region_info.soh_allocation_size = (size_t)((float)allocation_no_gc_soh * 1.05);
- //current_no_gc_region_info.soh_allocation_size = allocation_no_gc_soh;
+ current_no_gc_region_info.soh_allocation_size = allocation_no_gc_soh;
size_per_heap = current_no_gc_region_info.soh_allocation_size;
#ifdef MULTIPLE_HEAPS
size_per_heap /= n_heaps;
for (int i = 0; i < n_heaps; i++)
{
// due to heap balancing we need to allow some room before we even look to balance to another heap.
- g_heaps[i]->soh_allocation_no_gc = min (Align (size_per_heap + min_balance_threshold, get_alignment_constant (TRUE)), (soh_segment_size - OS_PAGE_SIZE));
+ g_heaps[i]->soh_allocation_no_gc = min (Align ((size_per_heap + min_balance_threshold), soh_align_const), max_soh_allocated);
}
#else //MULTIPLE_HEAPS
- soh_allocation_no_gc = min (Align (size_per_heap, get_alignment_constant (TRUE)), (soh_segment_size - OS_PAGE_SIZE));
+ soh_allocation_no_gc = min (Align (size_per_heap, soh_align_const), max_soh_allocated);
#endif //MULTIPLE_HEAPS
}
if (allocation_no_gc_loh != 0)
{
- current_no_gc_region_info.loh_allocation_size = (size_t)((float)allocation_no_gc_loh * 1.05);
+ current_no_gc_region_info.loh_allocation_size = allocation_no_gc_loh;
size_per_heap = current_no_gc_region_info.loh_allocation_size;
#ifdef MULTIPLE_HEAPS
size_per_heap /= n_heaps;
@@ -16188,19 +16320,44 @@ BOOL gc_heap::expand_soh_with_minimal_gc()
heap_segment* new_seg = soh_get_segment_to_expand();
if (new_seg)
{
+ if (g_gc_card_table != card_table)
+ copy_brick_card_table();
+
settings.promotion = TRUE;
settings.demotion = FALSE;
ephemeral_promotion = TRUE;
- save_ephemeral_generation_starts();
+ int condemned_gen_number = max_generation - 1;
+
+ generation* gen = 0;
+ int align_const = get_alignment_constant (TRUE);
+
+ for (int i = 0; i <= condemned_gen_number; i++)
+ {
+ gen = generation_of (i);
+ saved_ephemeral_plan_start[i] = generation_allocation_start (gen);
+ saved_ephemeral_plan_start_size[i] = Align (size (generation_allocation_start (gen)), align_const);
+ }
+
+ // We do need to clear the bricks here as we are converting a bunch of ephemeral objects to gen2
+ // and need to make sure that there are no left over bricks from the previous GCs for the space
+ // we just used for gen0 allocation. We will need to go through the bricks for these objects for
+ // ephemeral GCs later.
+ for (size_t b = brick_of (generation_allocation_start (generation_of (0)));
+ b < brick_of (align_on_brick (heap_segment_allocated (ephemeral_heap_segment)));
+ b++)
+ {
+ set_brick (b, -1);
+ }
+
size_t ephemeral_size = (heap_segment_allocated (ephemeral_heap_segment) -
generation_allocation_start (generation_of (max_generation - 1)));
heap_segment_next (ephemeral_heap_segment) = new_seg;
ephemeral_heap_segment = new_seg;
uint8_t* start = heap_segment_mem (ephemeral_heap_segment);
- for (int i = (max_generation - 1); i >= 0; i--)
+ for (int i = condemned_gen_number; i >= 0; i--)
{
- generation* gen = generation_of (i);
+ gen = generation_of (i);
size_t gen_start_size = Align (min_obj_size);
make_generation (generation_table[i], ephemeral_heap_segment, start, 0);
generation_plan_allocation_start (gen) = start;
@@ -16210,15 +16367,11 @@ BOOL gc_heap::expand_soh_with_minimal_gc()
heap_segment_used (ephemeral_heap_segment) = start - plug_skew;
heap_segment_plan_allocated (ephemeral_heap_segment) = start;
- fix_generation_bounds ((max_generation - 1), generation_of (0));
+ fix_generation_bounds (condemned_gen_number, generation_of (0));
dd_gc_new_allocation (dynamic_data_of (max_generation)) -= ephemeral_size;
dd_new_allocation (dynamic_data_of (max_generation)) = dd_gc_new_allocation (dynamic_data_of (max_generation));
-#ifndef FEATURE_REDHAWK
- // IsGCThread() always returns false on CoreRT, but this assert is useful in CoreCLR.
- assert(!!IsGCThread());
-#endif // FEATURE_REDHAWK
adjust_ephemeral_limits();
return TRUE;
}
@@ -16226,11 +16379,36 @@ BOOL gc_heap::expand_soh_with_minimal_gc()
return FALSE;
}
+// Only to be done on the thread that calls restart in a join for server GC
+// and reset the oom status per heap.
+void gc_heap::check_and_set_no_gc_oom()
+{
+#ifdef MULTIPLE_HEAPS
+ for (int i = 0; i < n_heaps; i++)
+ {
+ gc_heap* hp = g_heaps[i];
+ if (hp->no_gc_oom_p)
+ {
+ current_no_gc_region_info.start_status = start_no_gc_no_memory;
+ hp->no_gc_oom_p = false;
+ }
+ }
+#else
+ if (no_gc_oom_p)
+ {
+ current_no_gc_region_info.start_status = start_no_gc_no_memory;
+ no_gc_oom_p = false;
+ }
+#endif //MULTIPLE_HEAPS
+}
+
void gc_heap::allocate_for_no_gc_after_gc()
{
if (current_no_gc_region_info.minimal_gc_p)
repair_allocation_contexts (TRUE);
+ no_gc_oom_p = false;
+
if (current_no_gc_region_info.start_status != start_no_gc_no_memory)
{
if (current_no_gc_region_info.soh_allocation_size != 0)
@@ -16238,18 +16416,19 @@ void gc_heap::allocate_for_no_gc_after_gc()
if (((size_t)(heap_segment_reserved (ephemeral_heap_segment) - heap_segment_allocated (ephemeral_heap_segment)) < soh_allocation_no_gc) ||
(!grow_heap_segment (ephemeral_heap_segment, (heap_segment_allocated (ephemeral_heap_segment) + soh_allocation_no_gc))))
{
- current_no_gc_region_info.start_status = start_no_gc_no_memory;
+ no_gc_oom_p = true;
}
#ifdef MULTIPLE_HEAPS
- if (!current_no_gc_region_info.minimal_gc_p &&
- (current_no_gc_region_info.loh_allocation_size != 0))
+ gc_t_join.join(this, gc_join_after_commit_soh_no_gc);
+ if (gc_t_join.joined())
{
- gc_t_join.join(this, gc_join_after_commit_soh_no_gc);
- if (gc_t_join.joined())
- {
- gc_t_join.restart();
- }
+#endif //MULTIPLE_HEAPS
+
+ check_and_set_no_gc_oom();
+
+#ifdef MULTIPLE_HEAPS
+ gc_t_join.restart();
}
#endif //MULTIPLE_HEAPS
}
@@ -16272,7 +16451,7 @@ void gc_heap::allocate_for_no_gc_after_gc()
found_seg_p = TRUE;
if (!commit_loh_for_no_gc (seg))
{
- current_no_gc_region_info.start_status = start_no_gc_no_memory;
+ no_gc_oom_p = true;
break;
}
}
@@ -16287,20 +16466,31 @@ void gc_heap::allocate_for_no_gc_after_gc()
gc_t_join.join(this, gc_join_expand_loh_no_gc);
if (gc_t_join.joined())
{
- for (int i = 0; i < n_heaps; i++)
+ check_and_set_no_gc_oom();
+
+ if (current_no_gc_region_info.start_status == start_no_gc_success)
{
- gc_heap* hp = g_heaps[i];
- if (hp->gc_policy == policy_expand)
+ for (int i = 0; i < n_heaps; i++)
{
- hp->saved_loh_segment_no_gc = get_segment_for_loh (get_large_seg_size (loh_allocation_no_gc), hp);
- if (!(hp->saved_loh_segment_no_gc))
- current_no_gc_region_info.start_status = start_no_gc_no_memory;
+ gc_heap* hp = g_heaps[i];
+ if (hp->gc_policy == policy_expand)
+ {
+ hp->saved_loh_segment_no_gc = get_segment_for_loh (get_large_seg_size (loh_allocation_no_gc), hp);
+ if (!(hp->saved_loh_segment_no_gc))
+ {
+ current_no_gc_region_info.start_status = start_no_gc_no_memory;
+ break;
+ }
+ }
}
}
+
gc_t_join.restart();
}
#else //MULTIPLE_HEAPS
- if (gc_policy == policy_expand)
+ check_and_set_no_gc_oom();
+
+ if ((current_no_gc_region_info.start_status == start_no_gc_success) && (gc_policy == policy_expand))
{
saved_loh_segment_no_gc = get_segment_for_loh (get_large_seg_size (loh_allocation_no_gc));
if (!saved_loh_segment_no_gc)
@@ -16312,8 +16502,8 @@ void gc_heap::allocate_for_no_gc_after_gc()
{
if (!commit_loh_for_no_gc (saved_loh_segment_no_gc))
{
- current_no_gc_region_info.start_status = start_no_gc_no_memory;
- }
+ no_gc_oom_p = true;
+ }
}
}
}
@@ -16323,6 +16513,9 @@ void gc_heap::allocate_for_no_gc_after_gc()
if (gc_t_join.joined())
{
#endif //MULTIPLE_HEAPS
+
+ check_and_set_no_gc_oom();
+
if (current_no_gc_region_info.start_status == start_no_gc_success)
{
set_allocations_for_no_gc();
@@ -17298,7 +17491,7 @@ void gc_heap::enque_pinned_plug (uint8_t* plug,
// risks. This happens very rarely and fixing it in the
// way so that we can continue is a bit involved and will
// not be done in Dev10.
- EEPOLICY_HANDLE_FATAL_ERROR(CORINFO_EXCEPTION_GC);
+ GCToEEInterface::HandleFatalError(CORINFO_EXCEPTION_GC);
}
}
@@ -18530,9 +18723,9 @@ gc_heap::scan_background_roots (promote_func* fn, int hn, ScanContext *pSC)
#endif //BACKGROUND_GC
-
void gc_heap::fix_card_table ()
{
+#ifdef NO_WRITE_BARRIER
#ifdef WRITE_WATCH
heap_segment* seg = heap_segment_rw (generation_start_segment (generation_of (max_generation)));
@@ -18598,14 +18791,22 @@ void gc_heap::fix_card_table ()
dprintf (3,("Found %Id pages written", bcount));
for (unsigned i = 0; i < bcount; i++)
{
- for (unsigned j = 0; j< (card_size*card_word_width)/OS_PAGE_SIZE; j++)
+ // Set the card words corresponding to the entire page.
+ for (unsigned j = 0; j < (card_size*card_word_width)/OS_PAGE_SIZE; j++)
{
card_table [card_word (card_of (g_addresses [i]))+j] = ~0u;
}
dprintf (2,("Set Cards [%Ix:%Ix, %Ix:%Ix[",
card_of (g_addresses [i]), (size_t)g_addresses [i],
card_of (g_addresses [i]+OS_PAGE_SIZE), (size_t)g_addresses [i]+OS_PAGE_SIZE));
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ // We don't need to update card bundles here because this function is only used when
+ // we don't have write barriers.
+ #error Cannot have manually managed card bundles without write barriers.
+#endif
}
+
if (bcount >= array_size){
base_address = g_addresses [array_size-1] + OS_PAGE_SIZE;
bcount = array_size;
@@ -18626,6 +18827,7 @@ void gc_heap::fix_card_table ()
}
#endif //BACKGROUND_GC
#endif //WRITE_WATCH
+#endif //NO_WRITE_BARRIER
}
#ifdef BACKGROUND_GC
@@ -19541,7 +19743,15 @@ void gc_heap::mark_phase (int condemned_gen_number, BOOL mark_only_p)
{
#endif //MULTIPLE_HEAPS
- update_card_table_bundle ();
+#ifndef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ // If we are manually managing card bundles, every write to the card table should already be
+ // accounted for in the card bundle table so there's nothing to update here.
+ update_card_table_bundle();
+#endif
+ if (card_bundles_enabled())
+ {
+ verify_card_bundles();
+ }
#ifdef MULTIPLE_HEAPS
gc_t_join.r_restart();
@@ -20880,7 +21090,7 @@ BOOL gc_heap::plan_loh()
{
while (o < heap_segment_allocated (seg) && !marked (o))
{
- dprintf (1235, ("%Ix(%Id) F (%d)", o, AlignQword (size (o)), ((method_table (o) == g_pFreeObjectMethodTable) ? 1 : 0)));
+ dprintf (1235, ("%Ix(%Id) F (%d)", o, AlignQword (size (o)), ((method_table (o) == g_gc_pFreeObjectMethodTable) ? 1 : 0)));
o = o + AlignQword (size (o));
}
}
@@ -21117,7 +21327,7 @@ void gc_heap::relocate_in_loh_compact()
generation_free_obj_space (gen)));
}
-void gc_heap::walk_relocation_for_loh (size_t profiling_context, record_surv_fn fn)
+void gc_heap::walk_relocation_for_loh (void* profiling_context, record_surv_fn fn)
{
generation* gen = large_object_generation;
heap_segment* seg = heap_segment_rw (generation_start_segment (gen));
@@ -21147,7 +21357,7 @@ void gc_heap::walk_relocation_for_loh (size_t profiling_context, record_surv_fn
STRESS_LOG_PLUG_MOVE(o, (o + size), -reloc);
- fn (o, (o + size), reloc, profiling_context, settings.compaction, FALSE);
+ fn (o, (o + size), reloc, profiling_context, !!settings.compaction, false);
o = o + size;
if (o < heap_segment_allocated (seg))
@@ -21190,7 +21400,7 @@ void gc_heap::convert_to_pinned_plug (BOOL& last_npinned_plug_p,
artificial_pinned_size = ps;
}
-// Because we have the artifical pinning, we can't gaurantee that pinned and npinned
+// Because we have the artificial pinning, we can't guarantee that pinned and npinned
// plugs are always interleaved.
void gc_heap::store_plug_gap_info (uint8_t* plug_start,
uint8_t* plug_end,
@@ -23962,7 +24172,7 @@ void gc_heap::walk_plug (uint8_t* plug, size_t size, BOOL check_last_object_p, w
STRESS_LOG_PLUG_MOVE(plug, (plug + size), -last_plug_relocation);
ptrdiff_t reloc = settings.compaction ? last_plug_relocation : 0;
- (args->fn) (plug, (plug + size), reloc, args->profiling_context, settings.compaction, FALSE);
+ (args->fn) (plug, (plug + size), reloc, args->profiling_context, !!settings.compaction, false);
if (check_last_object_p)
{
@@ -24030,7 +24240,7 @@ void gc_heap::walk_relocation_in_brick (uint8_t* tree, walk_relocate_args* args)
}
}
-void gc_heap::walk_relocation (size_t profiling_context, record_surv_fn fn)
+void gc_heap::walk_relocation (void* profiling_context, record_surv_fn fn)
{
generation* condemned_gen = generation_of (settings.condemned_generation);
uint8_t* start_address = generation_allocation_start (condemned_gen);
@@ -24086,7 +24296,7 @@ void gc_heap::walk_relocation (size_t profiling_context, record_surv_fn fn)
}
}
-void gc_heap::walk_survivors (record_surv_fn fn, size_t context, walk_surv_type type)
+void gc_heap::walk_survivors (record_surv_fn fn, void* context, walk_surv_type type)
{
if (type == walk_for_gc)
walk_survivors_relocation (context, fn);
@@ -24101,7 +24311,7 @@ void gc_heap::walk_survivors (record_surv_fn fn, size_t context, walk_surv_type
}
#if defined(BACKGROUND_GC) && defined(FEATURE_EVENT_TRACE)
-void gc_heap::walk_survivors_for_bgc (size_t profiling_context, record_surv_fn fn)
+void gc_heap::walk_survivors_for_bgc (void* profiling_context, record_surv_fn fn)
{
// This should only be called for BGCs
assert(settings.concurrent);
@@ -24136,7 +24346,7 @@ void gc_heap::walk_survivors_for_bgc (size_t profiling_context, record_surv_fn f
while (o < end)
{
- if (method_table(o) == g_pFreeObjectMethodTable)
+ if (method_table(o) == g_gc_pFreeObjectMethodTable)
{
o += Align (size (o), align_const);
continue;
@@ -24147,7 +24357,7 @@ void gc_heap::walk_survivors_for_bgc (size_t profiling_context, record_surv_fn f
uint8_t* plug_start = o;
- while (method_table(o) != g_pFreeObjectMethodTable)
+ while (method_table(o) != g_gc_pFreeObjectMethodTable)
{
o += Align (size (o), align_const);
if (o >= end)
@@ -24162,8 +24372,8 @@ void gc_heap::walk_survivors_for_bgc (size_t profiling_context, record_surv_fn f
plug_end,
0, // Reloc distance == 0 as this is non-compacting
profiling_context,
- FALSE, // Non-compacting
- TRUE); // BGC
+ false, // Non-compacting
+ true); // BGC
}
seg = heap_segment_next (seg);
@@ -24787,7 +24997,7 @@ void gc_heap::gc_thread_stub (void* arg)
#else
STRESS_LOG0(LF_GC, LL_ALWAYS, "Thread::CommitThreadStack failed.");
_ASSERTE(!"Thread::CommitThreadStack failed.");
- EEPOLICY_HANDLE_FATAL_ERROR(COR_E_STACKOVERFLOW);
+ GCToEEInterface::HandleFatalError(COR_E_STACKOVERFLOW);
#endif //BACKGROUND_GC
}
#endif // FEATURE_REDHAWK
@@ -26941,6 +27151,7 @@ void gc_heap::clear_cards (size_t start_card, size_t end_card)
size_t end_word = card_word (end_card);
if (start_word < end_word)
{
+ // Figure out the bit positions of the cards within their words
unsigned bits = card_bit (start_card);
card_table [start_word] &= lowbits (~0, bits);
for (size_t i = start_word+1; i < end_word; i++)
@@ -26954,6 +27165,8 @@ void gc_heap::clear_cards (size_t start_card, size_t end_card)
}
else
{
+ // If the start and end cards are in the same word, just clear the appropriate card
+ // bits in that word.
card_table [start_word] &= (lowbits (~0, card_bit (start_card)) |
highbits (~0, card_bit (end_card)));
}
@@ -26981,8 +27194,10 @@ void gc_heap::clear_card_for_addresses (uint8_t* start_address, uint8_t* end_add
// copy [srccard, ...[ to [dst_card, end_card[
// This will set the same bit twice. Can be optimized.
inline
-void gc_heap::copy_cards (size_t dst_card, size_t src_card,
- size_t end_card, BOOL nextp)
+void gc_heap::copy_cards (size_t dst_card,
+ size_t src_card,
+ size_t end_card,
+ BOOL nextp)
{
// If the range is empty, this function is a no-op - with the subtlety that
// either of the accesses card_table[srcwrd] or card_table[dstwrd] could be
@@ -26996,31 +27211,51 @@ void gc_heap::copy_cards (size_t dst_card, size_t src_card,
size_t dstwrd = card_word (dst_card);
unsigned int srctmp = card_table[srcwrd];
unsigned int dsttmp = card_table[dstwrd];
+
for (size_t card = dst_card; card < end_card; card++)
{
if (srctmp & (1 << srcbit))
dsttmp |= 1 << dstbit;
else
dsttmp &= ~(1 << dstbit);
+
if (!(++srcbit % 32))
{
srctmp = card_table[++srcwrd];
srcbit = 0;
}
+
if (nextp)
{
if (srctmp & (1 << srcbit))
dsttmp |= 1 << dstbit;
}
+
if (!(++dstbit % 32))
{
card_table[dstwrd] = dsttmp;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ if (dsttmp != 0)
+ {
+ card_bundle_set(cardw_card_bundle(dstwrd));
+ }
+#endif
+
dstwrd++;
dsttmp = card_table[dstwrd];
dstbit = 0;
}
}
+
card_table[dstwrd] = dsttmp;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ if (dsttmp != 0)
+ {
+ card_bundle_set(cardw_card_bundle(dstwrd));
+ }
+#endif
}
void gc_heap::copy_cards_for_addresses (uint8_t* dest, uint8_t* src, size_t len)
@@ -27081,6 +27316,10 @@ void gc_heap::copy_cards_for_addresses (uint8_t* dest, uint8_t* src, size_t len)
if (card_set_p (card_of (src + len - 1)))
set_card (end_dest_card);
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ card_bundles_set(cardw_card_bundle(card_word(card_of(dest))), cardw_card_bundle(align_cardw_on_bundle(card_word(end_dest_card))));
+#endif
}
#ifdef BACKGROUND_GC
@@ -27229,6 +27468,9 @@ uint8_t* gc_heap::find_first_object (uint8_t* start, uint8_t* first_object)
}
#ifdef CARD_BUNDLE
+
+// Find the first non-zero card word between cardw and cardw_end.
+// The index of the word we find is returned in cardw.
BOOL gc_heap::find_card_dword (size_t& cardw, size_t cardw_end)
{
dprintf (3, ("gc: %d, find_card_dword cardw: %Ix, cardw_end: %Ix",
@@ -27240,26 +27482,26 @@ BOOL gc_heap::find_card_dword (size_t& cardw, size_t cardw_end)
size_t end_cardb = cardw_card_bundle (align_cardw_on_bundle (cardw_end));
while (1)
{
- //find a non null bundle
- while ((cardb < end_cardb) &&
- (card_bundle_set_p (cardb)==0))
+ // Find a non-zero bundle
+ while ((cardb < end_cardb) && (card_bundle_set_p (cardb) == 0))
{
cardb++;
}
+
if (cardb == end_cardb)
return FALSE;
- //find a non empty card word
+ // We found a bundle, so go through its words and find a non-zero card word
uint32_t* card_word = &card_table[max(card_bundle_cardw (cardb),cardw)];
uint32_t* card_word_end = &card_table[min(card_bundle_cardw (cardb+1),cardw_end)];
- while ((card_word < card_word_end) &&
- !(*card_word))
+ while ((card_word < card_word_end) && !(*card_word))
{
card_word++;
}
+
if (card_word != card_word_end)
{
- cardw = (card_word - &card_table [0]);
+ cardw = (card_word - &card_table[0]);
return TRUE;
}
else if ((cardw <= card_bundle_cardw (cardb)) &&
@@ -27272,6 +27514,7 @@ BOOL gc_heap::find_card_dword (size_t& cardw, size_t cardw_end)
card_bundle_cardw (cardb+1)));
card_bundle_clear (cardb);
}
+
cardb++;
}
}
@@ -27282,96 +27525,122 @@ BOOL gc_heap::find_card_dword (size_t& cardw, size_t cardw_end)
while (card_word < card_word_end)
{
- if ((*card_word) != 0)
+ if (*card_word != 0)
{
cardw = (card_word - &card_table [0]);
return TRUE;
}
+
card_word++;
}
- return FALSE;
+ return FALSE;
}
-
}
#endif //CARD_BUNDLE
-BOOL gc_heap::find_card (uint32_t* card_table, size_t& card,
- size_t card_word_end, size_t& end_card)
+// Find cards that are set between two points in a card table.
+// Parameters
+// card_table : The card table.
+// card : [in/out] As input, the card to start searching from.
+// As output, the first card that's set.
+// card_word_end : The card word at which to stop looking.
+// end_card : [out] The last card which is set.
+BOOL gc_heap::find_card(uint32_t* card_table,
+ size_t& card,
+ size_t card_word_end,
+ size_t& end_card)
{
uint32_t* last_card_word;
- uint32_t y;
- uint32_t z;
+ uint32_t card_word_value;
+ uint32_t bit_position;
+
// Find the first card which is set
-
last_card_word = &card_table [card_word (card)];
- z = card_bit (card);
- y = (*last_card_word) >> z;
- if (!y)
+ bit_position = card_bit (card);
+ card_word_value = (*last_card_word) >> bit_position;
+ if (!card_word_value)
{
- z = 0;
+ bit_position = 0;
#ifdef CARD_BUNDLE
- size_t lcw = card_word(card)+1;
+ // Using the card bundle, go through the remaining card words between here and
+ // card_word_end until we find one that is non-zero.
+ size_t lcw = card_word(card) + 1;
if (gc_heap::find_card_dword (lcw, card_word_end) == FALSE)
+ {
return FALSE;
+ }
else
{
last_card_word = &card_table [lcw];
- y = *last_card_word;
+ card_word_value = *last_card_word;
}
#else //CARD_BUNDLE
+ // Go through the remaining card words between here and card_word_end until we find
+ // one that is non-zero.
do
{
++last_card_word;
}
+ while ((last_card_word < &card_table [card_word_end]) && !(*last_card_word));
- while ((last_card_word < &card_table [card_word_end]) &&
- !(*last_card_word));
if (last_card_word < &card_table [card_word_end])
- y = *last_card_word;
+ {
+ card_word_value = *last_card_word;
+ }
else
+ {
+ // We failed to find any non-zero card words before we got to card_word_end
return FALSE;
+ }
#endif //CARD_BUNDLE
}
-
// Look for the lowest bit set
- if (y)
+ if (card_word_value)
{
- while (!(y & 1))
+ while (!(card_word_value & 1))
{
- z++;
- y = y / 2;
+ bit_position++;
+ card_word_value = card_word_value / 2;
}
}
- card = (last_card_word - &card_table [0])* card_word_width + z;
+
+ // card is the card word index * card size + the bit index within the card
+ card = (last_card_word - &card_table[0]) * card_word_width + bit_position;
+
do
{
- z++;
- y = y / 2;
- if ((z == card_word_width) &&
- (last_card_word < &card_table [card_word_end]))
- {
+ // Keep going until we get to an un-set card.
+ bit_position++;
+ card_word_value = card_word_value / 2;
+ // If we reach the end of the card word and haven't hit a 0 yet, start going
+ // card word by card word until we get to one that's not fully set (0xFFFF...)
+ // or we reach card_word_end.
+ if ((bit_position == card_word_width) && (last_card_word < &card_table [card_word_end]))
+ {
do
{
- y = *(++last_card_word);
- }while ((last_card_word < &card_table [card_word_end]) &&
+ card_word_value = *(++last_card_word);
+ } while ((last_card_word < &card_table [card_word_end]) &&
+
#ifdef _MSC_VER
- (y == (1 << card_word_width)-1)
+ (card_word_value == (1 << card_word_width)-1)
#else
// if left shift count >= width of type,
// gcc reports error.
- (y == ~0u)
+ (card_word_value == ~0u)
#endif // _MSC_VER
);
- z = 0;
+ bit_position = 0;
}
- } while (y & 1);
+ } while (card_word_value & 1);
- end_card = (last_card_word - &card_table [0])* card_word_width + z;
+ end_card = (last_card_word - &card_table [0])* card_word_width + bit_position;
+
//dprintf (3, ("find_card: [%Ix, %Ix[ set", card, end_card));
dprintf (3, ("fc: [%Ix, %Ix[", card, end_card));
return TRUE;
@@ -27533,49 +27802,49 @@ void gc_heap::mark_through_cards_for_segments (card_fn fn, BOOL relocating)
#ifdef BACKGROUND_GC
dprintf (3, ("current_sweep_pos is %Ix, saved_sweep_ephemeral_seg is %Ix(%Ix)",
current_sweep_pos, saved_sweep_ephemeral_seg, saved_sweep_ephemeral_start));
+
heap_segment* soh_seg = heap_segment_rw (generation_start_segment (generation_of (max_generation)));
- PREFIX_ASSUME(soh_seg != NULL);
- while (soh_seg )
+ PREFIX_ASSUME(soh_seg != NULL);
+
+ while (soh_seg)
{
dprintf (3, ("seg %Ix, bgc_alloc: %Ix, alloc: %Ix",
soh_seg,
heap_segment_background_allocated (soh_seg),
heap_segment_allocated (soh_seg)));
+
soh_seg = heap_segment_next_rw (soh_seg);
}
#endif //BACKGROUND_GC
uint8_t* low = gc_low;
uint8_t* high = gc_high;
- size_t end_card = 0;
+ size_t end_card = 0;
+
generation* oldest_gen = generation_of (max_generation);
int curr_gen_number = max_generation;
- uint8_t* gen_boundary = generation_allocation_start
- (generation_of (curr_gen_number - 1));
- uint8_t* next_boundary = (compute_next_boundary
- (gc_low, curr_gen_number, relocating));
+ uint8_t* gen_boundary = generation_allocation_start(generation_of(curr_gen_number - 1));
+ uint8_t* next_boundary = compute_next_boundary(gc_low, curr_gen_number, relocating);
+
heap_segment* seg = heap_segment_rw (generation_start_segment (oldest_gen));
-
PREFIX_ASSUME(seg != NULL);
- uint8_t* beg = generation_allocation_start (oldest_gen);
- uint8_t* end = compute_next_end (seg, low);
- uint8_t* last_object = beg;
+ uint8_t* beg = generation_allocation_start (oldest_gen);
+ uint8_t* end = compute_next_end (seg, low);
+ uint8_t* last_object = beg;
size_t cg_pointers_found = 0;
- size_t card_word_end = (card_of (align_on_card_word (end)) /
- card_word_width);
+ size_t card_word_end = (card_of (align_on_card_word (end)) / card_word_width);
size_t n_eph = 0;
size_t n_gen = 0;
size_t n_card_set = 0;
- uint8_t* nhigh = (relocating ?
- heap_segment_plan_allocated (ephemeral_heap_segment) : high);
+ uint8_t* nhigh = (relocating ? heap_segment_plan_allocated (ephemeral_heap_segment) : high);
BOOL foundp = FALSE;
- uint8_t* start_address = 0;
- uint8_t* limit = 0;
+ uint8_t* start_address = 0;
+ uint8_t* limit = 0;
size_t card = card_of (beg);
#ifdef BACKGROUND_GC
BOOL consider_bgc_mark_p = FALSE;
@@ -27591,6 +27860,7 @@ void gc_heap::mark_through_cards_for_segments (card_fn fn, BOOL relocating)
{
if (card_of(last_object) > card)
{
+ // cg means cross-generational
dprintf (3, ("Found %Id cg pointers", cg_pointers_found));
if (cg_pointers_found == 0)
{
@@ -27599,23 +27869,29 @@ void gc_heap::mark_through_cards_for_segments (card_fn fn, BOOL relocating)
n_card_set -= (card_of (last_object) - card);
total_cards_cleared += (card_of (last_object) - card);
}
- n_eph +=cg_pointers_found;
+
+ n_eph += cg_pointers_found;
cg_pointers_found = 0;
card = card_of (last_object);
}
+
if (card >= end_card)
{
- foundp = find_card (card_table, card, card_word_end, end_card);
+ // Find the first card that's set (between card and card_word_end)
+ foundp = find_card(card_table, card, card_word_end, end_card);
if (foundp)
{
- n_card_set+= end_card - card;
+ // We found card(s) set.
+ n_card_set += end_card - card;
start_address = max (beg, card_address (card));
}
+
limit = min (end, card_address (end_card));
}
- if ((!foundp) || (last_object >= end) || (card_address (card) >= end))
+
+ if (!foundp || (last_object >= end) || (card_address (card) >= end))
{
- if ((foundp) && (cg_pointers_found == 0))
+ if (foundp && (cg_pointers_found == 0))
{
dprintf(3,(" Clearing cards [%Ix, %Ix[ ", (size_t)card_address(card),
(size_t)end));
@@ -27623,8 +27899,10 @@ void gc_heap::mark_through_cards_for_segments (card_fn fn, BOOL relocating)
n_card_set -= (card_of (end) - card);
total_cards_cleared += (card_of (end) - card);
}
- n_eph +=cg_pointers_found;
+
+ n_eph += cg_pointers_found;
cg_pointers_found = 0;
+
if ((seg = heap_segment_next_in_range (seg)) != 0)
{
#ifdef BACKGROUND_GC
@@ -27644,17 +27922,17 @@ void gc_heap::mark_through_cards_for_segments (card_fn fn, BOOL relocating)
}
}
+ // We've found a card and will now go through the objects in it.
assert (card_set_p (card));
{
- uint8_t* o = last_object;
-
+ uint8_t* o = last_object;
o = find_first_object (start_address, last_object);
- //Never visit an object twice.
- assert (o >= last_object);
+ // Never visit an object twice.
+ assert (o >= last_object);
- //dprintf(3,("Considering card %Ix start object: %Ix, %Ix[ boundary: %Ix",
- dprintf(3, ("c: %Ix, o: %Ix, l: %Ix[ boundary: %Ix",
- card, (size_t)o, (size_t)limit, (size_t)gen_boundary));
+ //dprintf(3,("Considering card %Ix start object: %Ix, %Ix[ boundary: %Ix",
+ dprintf(3, ("c: %Ix, o: %Ix, l: %Ix[ boundary: %Ix",
+ card, (size_t)o, (size_t)limit, (size_t)gen_boundary));
while (o < limit)
{
@@ -30489,6 +30767,7 @@ CObjectHeader* gc_heap::allocate_large_object (size_t jsize, int64_t& alloc_byte
uint8_t* result = acontext.alloc_ptr;
assert ((size_t)(acontext.alloc_limit - acontext.alloc_ptr) == size);
+ alloc_bytes += size;
CObjectHeader* obj = (CObjectHeader*)result;
@@ -30525,7 +30804,6 @@ CObjectHeader* gc_heap::allocate_large_object (size_t jsize, int64_t& alloc_byte
assert (obj != 0);
assert ((size_t)obj == Align ((size_t)obj, align_const));
- alloc_bytes += acontext.alloc_bytes;
return obj;
}
@@ -30580,7 +30858,7 @@ BOOL gc_heap::large_object_marked (uint8_t* o, BOOL clearp)
return m;
}
-void gc_heap::walk_survivors_relocation (size_t profiling_context, record_surv_fn fn)
+void gc_heap::walk_survivors_relocation (void* profiling_context, record_surv_fn fn)
{
// Now walk the portion of memory that is actually being relocated.
walk_relocation (profiling_context, fn);
@@ -30593,7 +30871,7 @@ void gc_heap::walk_survivors_relocation (size_t profiling_context, record_surv_f
#endif //FEATURE_LOH_COMPACTION
}
-void gc_heap::walk_survivors_for_loh (size_t profiling_context, record_surv_fn fn)
+void gc_heap::walk_survivors_for_loh (void* profiling_context, record_surv_fn fn)
{
generation* gen = large_object_generation;
heap_segment* seg = heap_segment_rw (generation_start_segment (gen));;
@@ -30631,7 +30909,7 @@ void gc_heap::walk_survivors_for_loh (size_t profiling_context, record_surv_fn f
plug_end = o;
- fn (plug_start, plug_end, 0, profiling_context, FALSE, FALSE);
+ fn (plug_start, plug_end, 0, profiling_context, false, false);
}
else
{
@@ -31265,7 +31543,7 @@ void gc_heap::background_sweep()
seg = start_seg;
prev_seg = 0;
o = generation_allocation_start (gen);
- assert (method_table (o) == g_pFreeObjectMethodTable);
+ assert (method_table (o) == g_gc_pFreeObjectMethodTable);
align_const = get_alignment_constant (FALSE);
o = o + Align(size (o), align_const);
plug_end = o;
@@ -32164,45 +32442,18 @@ int GCHeap::m_CurStressObj = 0;
#endif // FEATURE_REDHAWK
#endif //FEATURE_PREMORTEM_FINALIZATION
-inline
-static void spin_lock ()
-{
- enter_spin_lock_noinstru (&m_GCLock);
-}
-inline
-void EnterAllocLock()
-{
-#if defined(_TARGET_X86_)
- __asm {
- inc dword ptr m_GCLock
- jz gotit
- call spin_lock
- gotit:
- }
-#else //_TARGET_X86_
- spin_lock();
-#endif //_TARGET_X86_
-}
-
-inline
-void LeaveAllocLock()
-{
- // Trick this out
- leave_spin_lock_noinstru (&m_GCLock);
-}
-
-class AllocLockHolder
+class NoGCRegionLockHolder
{
public:
- AllocLockHolder()
+ NoGCRegionLockHolder()
{
- EnterAllocLock();
+ enter_spin_lock_noinstru(&g_no_gc_lock);
}
- ~AllocLockHolder()
+ ~NoGCRegionLockHolder()
{
- LeaveAllocLock();
+ leave_spin_lock_noinstru(&g_no_gc_lock);
}
};
@@ -32634,7 +32885,7 @@ void gc_heap::verify_partial ()
//dprintf (3, ("VOM: verifying member %Ix in obj %Ix", (size_t)*oo, o));
MethodTable *pMT = method_table (*oo);
- if (pMT == g_pFreeObjectMethodTable)
+ if (pMT == g_gc_pFreeObjectMethodTable)
{
free_ref_p = TRUE;
FATAL_GC_ERROR();
@@ -33068,12 +33319,12 @@ gc_heap::verify_heap (BOOL begin_gc_p)
}
}
- if (*((uint8_t**)curr_object) != (uint8_t *) g_pFreeObjectMethodTable)
+ if (*((uint8_t**)curr_object) != (uint8_t *) g_gc_pFreeObjectMethodTable)
{
#ifdef FEATURE_LOH_COMPACTION
if ((curr_gen_num == (max_generation+1)) && (prev_object != 0))
{
- assert (method_table (prev_object) == g_pFreeObjectMethodTable);
+ assert (method_table (prev_object) == g_gc_pFreeObjectMethodTable);
}
#endif //FEATURE_LOH_COMPACTION
@@ -33245,6 +33496,7 @@ void GCHeap::ValidateObjectMember (Object* obj)
{
dprintf (3, ("VOM: m: %Ix obj %Ix", (size_t)child_o, o));
MethodTable *pMT = method_table (child_o);
+ assert(pMT);
if (!pMT->SanityCheck()) {
dprintf (3, ("Bad member of %Ix %Ix",
(size_t)oo, (size_t)child_o));
@@ -33291,7 +33543,11 @@ HRESULT GCHeap::Shutdown ()
if (card_table_refcount (ct) == 0)
{
destroy_card_table (ct);
- g_gc_card_table = 0;
+ g_gc_card_table = nullptr;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ g_gc_card_bundle_table = nullptr;
+#endif
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
SoftwareWriteWatch::StaticClose();
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
@@ -33350,14 +33606,6 @@ HRESULT GCHeap::Init(size_t hn)
{
HRESULT hres = S_OK;
- //Initialize all of the instance members.
-
-#ifdef MULTIPLE_HEAPS
- m_GCLock = -1;
-#endif //MULTIPLE_HEAPS
-
- // Rest of the initialization
-
#ifdef MULTIPLE_HEAPS
if ((pGenGCHeap = gc_heap::make_gc_heap(this, (int)hn)) == 0)
hres = E_OUTOFMEMORY;
@@ -33382,6 +33630,8 @@ HRESULT GCHeap::Initialize ()
return E_FAIL;
}
+ g_gc_pFreeObjectMethodTable = GCToEEInterface::GetFreeObjectMethodTable();
+
//Initialize the static members.
#ifdef TRACE_GC
GcDuration = 0;
@@ -33405,6 +33655,8 @@ HRESULT GCHeap::Initialize ()
uint32_t nhp = ((nhp_from_config == 0) ? nhp_from_process :
(min (nhp_from_config, nhp_from_process)));
+ nhp = min (nhp, MAX_SUPPORTED_CPUS);
+
hr = gc_heap::initialize_gc (seg_size, large_seg_size /*LHEAP_ALLOC*/, nhp);
#else
hr = gc_heap::initialize_gc (seg_size, large_seg_size /*LHEAP_ALLOC*/);
@@ -33496,7 +33748,7 @@ HRESULT GCHeap::Initialize ()
////
// GC callback functions
-BOOL GCHeap::IsPromoted(Object* object)
+bool GCHeap::IsPromoted(Object* object)
{
#ifdef _DEBUG
((CObjectHeader*)object)->Validate();
@@ -33515,7 +33767,7 @@ BOOL GCHeap::IsPromoted(Object* object)
#ifdef BACKGROUND_GC
if (gc_heap::settings.concurrent)
{
- BOOL is_marked = (!((o < hp->background_saved_highest_address) && (o >= hp->background_saved_lowest_address))||
+ bool is_marked = (!((o < hp->background_saved_highest_address) && (o >= hp->background_saved_lowest_address))||
hp->background_marked (o));
return is_marked;
}
@@ -33556,11 +33808,11 @@ unsigned int GCHeap::WhichGeneration (Object* object)
return g;
}
-BOOL GCHeap::IsEphemeral (Object* object)
+bool GCHeap::IsEphemeral (Object* object)
{
uint8_t* o = (uint8_t*)object;
gc_heap* hp = gc_heap::heap_of (o);
- return hp->ephemeral_pointer_p (o);
+ return !!hp->ephemeral_pointer_p (o);
}
// Return NULL if can't find next object. When EE is not suspended,
@@ -33634,7 +33886,7 @@ BOOL GCHeap::IsInFrozenSegment (Object * object)
#endif //VERIFY_HEAP
// returns TRUE if the pointer is in one of the GC heaps.
-BOOL GCHeap::IsHeapPointer (void* vpObject, BOOL small_heap_only)
+bool GCHeap::IsHeapPointer (void* vpObject, bool small_heap_only)
{
STATIC_CONTRACT_SO_TOLERANT;
@@ -33805,7 +34057,7 @@ void GCHeap::Relocate (Object** ppObject, ScanContext* sc,
STRESS_LOG_ROOT_RELOCATE(ppObject, object, pheader, ((!(flags & GC_CALL_INTERIOR)) ? ((Object*)object)->GetGCSafeMethodTable() : 0));
}
-/*static*/ BOOL GCHeap::IsObjectInFixedHeap(Object *pObj)
+/*static*/ bool GCHeap::IsObjectInFixedHeap(Object *pObj)
{
// For now we simply look at the size of the object to determine if it in the
// fixed heap or not. If the bit indicating this gets set at some point
@@ -33851,10 +34103,11 @@ int StressRNG(int iMaxValue)
// free up object so that things will move and then do a GC
//return TRUE if GC actually happens, otherwise FALSE
-BOOL GCHeap::StressHeap(gc_alloc_context * context)
+bool GCHeap::StressHeap(gc_alloc_context * context)
{
#if defined(STRESS_HEAP) && !defined(FEATURE_REDHAWK)
alloc_context* acontext = static_cast<alloc_context*>(context);
+ assert(context != nullptr);
// if GC stress was dynamically disabled during this run we return FALSE
if (!GCStressPolicy::IsEnabled())
@@ -33936,9 +34189,6 @@ BOOL GCHeap::StressHeap(gc_alloc_context * context)
#ifndef MULTIPLE_HEAPS
static int32_t OneAtATime = -1;
- if (acontext == 0)
- acontext = generation_alloc_context (pGenGCHeap->generation_of(0));
-
// Only bother with this if the stress level is big enough and if nobody else is
// doing it right now. Note that some callers are inside the AllocLock and are
// guaranteed synchronized. But others are using AllocationContexts and have no
@@ -33954,11 +34204,11 @@ BOOL GCHeap::StressHeap(gc_alloc_context * context)
StringObject* str;
// If the current string is used up
- if (ObjectFromHandle(m_StressObjs[m_CurStressObj]) == 0)
+ if (HndFetchHandle(m_StressObjs[m_CurStressObj]) == 0)
{
// Populate handles with strings
int i = m_CurStressObj;
- while(ObjectFromHandle(m_StressObjs[i]) == 0)
+ while(HndFetchHandle(m_StressObjs[i]) == 0)
{
_ASSERTE(m_StressObjs[i] != 0);
unsigned strLen = (LARGE_OBJECT_SIZE - 32) / sizeof(WCHAR);
@@ -33990,7 +34240,7 @@ BOOL GCHeap::StressHeap(gc_alloc_context * context)
}
// Get the current string
- str = (StringObject*) OBJECTREFToObject(ObjectFromHandle(m_StressObjs[m_CurStressObj]));
+ str = (StringObject*) OBJECTREFToObject(HndFetchHandle(m_StressObjs[m_CurStressObj]));
if (str)
{
// Chop off the end of the string and form a new object out of it.
@@ -34061,122 +34311,7 @@ BOOL GCHeap::StressHeap(gc_alloc_context * context)
// Small Object Allocator
//
//
-Object *
-GCHeap::Alloc( size_t size, uint32_t flags REQD_ALIGN_DCL)
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- } CONTRACTL_END;
-
- TRIGGERSGC();
-
- Object* newAlloc = NULL;
-
-#ifdef TRACE_GC
-#ifdef COUNT_CYCLES
- AllocStart = GetCycleCount32();
- unsigned finish;
-#elif defined(ENABLE_INSTRUMENTATION)
- unsigned AllocStart = GetInstLogTime();
- unsigned finish;
-#endif //COUNT_CYCLES
-#endif //TRACE_GC
-
-#ifdef MULTIPLE_HEAPS
- //take the first heap....
- gc_heap* hp = gc_heap::g_heaps[0];
-#else
- gc_heap* hp = pGenGCHeap;
-#ifdef _PREFAST_
- // prefix complains about us dereferencing hp in wks build even though we only access static members
- // this way. not sure how to shut it up except for this ugly workaround:
- PREFIX_ASSUME(hp != NULL);
-#endif //_PREFAST_
-#endif //MULTIPLE_HEAPS
-
- {
- AllocLockHolder lh;
-
-#ifndef FEATURE_REDHAWK
- GCStress<gc_on_alloc>::MaybeTrigger(generation_alloc_context(hp->generation_of(0)));
-#endif // FEATURE_REDHAWK
-
- alloc_context* acontext = 0;
-
- if (size < LARGE_OBJECT_SIZE)
- {
- acontext = generation_alloc_context (hp->generation_of (0));
-
-#ifdef TRACE_GC
- AllocSmallCount++;
-#endif //TRACE_GC
- newAlloc = (Object*) hp->allocate (size + ComputeMaxStructAlignPad(requiredAlignment), acontext);
-#ifdef FEATURE_STRUCTALIGN
- newAlloc = (Object*) hp->pad_for_alignment ((uint8_t*) newAlloc, requiredAlignment, size, acontext);
-#endif // FEATURE_STRUCTALIGN
- // ASSERT (newAlloc);
- }
- else
- {
- acontext = generation_alloc_context (hp->generation_of (max_generation+1));
-
- newAlloc = (Object*) hp->allocate_large_object (size + ComputeMaxStructAlignPadLarge(requiredAlignment), acontext->alloc_bytes_loh);
-#ifdef FEATURE_STRUCTALIGN
- newAlloc = (Object*) hp->pad_for_alignment_large ((uint8_t*) newAlloc, requiredAlignment, size);
-#endif // FEATURE_STRUCTALIGN
- }
- }
-
- CHECK_ALLOC_AND_POSSIBLY_REGISTER_FOR_FINALIZATION(newAlloc, size, flags & GC_ALLOC_FINALIZE);
-
-#ifdef TRACE_GC
-#ifdef COUNT_CYCLES
- finish = GetCycleCount32();
-#elif defined(ENABLE_INSTRUMENTATION)
- finish = GetInstLogTime();
-#endif //COUNT_CYCLES
- AllocDuration += finish - AllocStart;
- AllocCount++;
-#endif //TRACE_GC
- return newAlloc;
-}
-
-// Allocate small object with an alignment requirement of 8-bytes. Non allocation context version.
-Object *
-GCHeap::AllocAlign8( size_t size, uint32_t flags)
-{
-#ifdef FEATURE_64BIT_ALIGNMENT
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- } CONTRACTL_END;
-
- Object* newAlloc = NULL;
-
- {
- AllocLockHolder lh;
-
-#ifdef MULTIPLE_HEAPS
- //take the first heap....
- gc_heap* hp = gc_heap::g_heaps[0];
-#else
- gc_heap* hp = pGenGCHeap;
-#endif //MULTIPLE_HEAPS
-
- newAlloc = AllocAlign8Common(hp, generation_alloc_context (hp->generation_of (0)), size, flags);
- }
-
- return newAlloc;
-#else
- UNREFERENCED_PARAMETER(size);
- UNREFERENCED_PARAMETER(flags);
- assert(!"should not call GCHeap::AllocAlign8 without FEATURE_64BIT_ALIGNMENT defined!");
- return nullptr;
-#endif //FEATURE_64BIT_ALIGNMENT
-}
-
-// Allocate small object with an alignment requirement of 8-bytes. Allocation context version.
+// Allocate small object with an alignment requirement of 8-bytes.
Object*
GCHeap::AllocAlign8(gc_alloc_context* ctx, size_t size, uint32_t flags )
{
@@ -34365,10 +34500,6 @@ GCHeap::AllocLHeap( size_t size, uint32_t flags REQD_ALIGN_DCL)
#endif //_PREFAST_
#endif //MULTIPLE_HEAPS
-#ifndef FEATURE_REDHAWK
- GCStress<gc_on_alloc>::MaybeTrigger(generation_alloc_context(hp->generation_of(0)));
-#endif // FEATURE_REDHAWK
-
alloc_context* acontext = generation_alloc_context (hp->generation_of (max_generation+1));
newAlloc = (Object*) hp->allocate_large_object (size + ComputeMaxStructAlignPadLarge(requiredAlignment), acontext->alloc_bytes_loh);
@@ -34470,7 +34601,7 @@ GCHeap::Alloc(gc_alloc_context* context, size_t size, uint32_t flags REQD_ALIGN_
}
void
-GCHeap::FixAllocContext (gc_alloc_context* context, BOOL lockp, void* arg, void *heap)
+GCHeap::FixAllocContext (gc_alloc_context* context, bool lockp, void* arg, void *heap)
{
alloc_context* acontext = static_cast<alloc_context*>(context);
#ifdef MULTIPLE_HEAPS
@@ -34506,14 +34637,18 @@ GCHeap::FixAllocContext (gc_alloc_context* context, BOOL lockp, void* arg, void
}
Object*
-GCHeap::GetContainingObject (void *pInteriorPtr)
+GCHeap::GetContainingObject (void *pInteriorPtr, bool fCollectedGenOnly)
{
uint8_t *o = (uint8_t*)pInteriorPtr;
gc_heap* hp = gc_heap::heap_of (o);
- if (o >= hp->lowest_address && o < hp->highest_address)
+
+ uint8_t* lowest = (fCollectedGenOnly ? hp->gc_low : hp->lowest_address);
+ uint8_t* highest = (fCollectedGenOnly ? hp->gc_high : hp->highest_address);
+
+ if (o >= lowest && o < highest)
{
- o = hp->find_object (o, hp->gc_low);
+ o = hp->find_object (o, lowest);
}
else
{
@@ -34544,7 +34679,7 @@ BOOL should_collect_optimized (dynamic_data* dd, BOOL low_memory_p)
// API to ensure that a complete new garbage collection takes place
//
HRESULT
-GCHeap::GarbageCollect (int generation, BOOL low_memory_p, int mode)
+GCHeap::GarbageCollect (int generation, bool low_memory_p, int mode)
{
#if defined(BIT64)
if (low_memory_p)
@@ -35375,7 +35510,7 @@ void GCHeap::SetLOHCompactionMode (int newLOHCompactionyMode)
#endif //FEATURE_LOH_COMPACTION
}
-BOOL GCHeap::RegisterForFullGCNotification(uint32_t gen2Percentage,
+bool GCHeap::RegisterForFullGCNotification(uint32_t gen2Percentage,
uint32_t lohPercentage)
{
#ifdef MULTIPLE_HEAPS
@@ -35398,7 +35533,7 @@ BOOL GCHeap::RegisterForFullGCNotification(uint32_t gen2Percentage,
return TRUE;
}
-BOOL GCHeap::CancelFullGCNotification()
+bool GCHeap::CancelFullGCNotification()
{
pGenGCHeap->fgn_maxgen_percent = 0;
pGenGCHeap->fgn_loh_percent = 0;
@@ -35425,9 +35560,9 @@ int GCHeap::WaitForFullGCComplete(int millisecondsTimeout)
return result;
}
-int GCHeap::StartNoGCRegion(uint64_t totalSize, BOOL lohSizeKnown, uint64_t lohSize, BOOL disallowFullBlockingGC)
+int GCHeap::StartNoGCRegion(uint64_t totalSize, bool lohSizeKnown, uint64_t lohSize, bool disallowFullBlockingGC)
{
- AllocLockHolder lh;
+ NoGCRegionLockHolder lh;
dprintf (1, ("begin no gc called"));
start_no_gc_region_status status = gc_heap::prepare_for_no_gc_region (totalSize, lohSizeKnown, lohSize, disallowFullBlockingGC);
@@ -35445,7 +35580,7 @@ int GCHeap::StartNoGCRegion(uint64_t totalSize, BOOL lohSizeKnown, uint64_t lohS
int GCHeap::EndNoGCRegion()
{
- AllocLockHolder lh;
+ NoGCRegionLockHolder lh;
return (int)gc_heap::end_no_gc_region();
}
@@ -35503,7 +35638,7 @@ HRESULT GCHeap::GetGcCounters(int gen, gc_counters* counters)
}
// Get the segment size to use, making sure it conforms.
-size_t GCHeap::GetValidSegmentSize(BOOL large_seg)
+size_t GCHeap::GetValidSegmentSize(bool large_seg)
{
return get_valid_segment_size (large_seg);
}
@@ -35627,15 +35762,15 @@ size_t GCHeap::GetFinalizablePromotedCount()
#endif //MULTIPLE_HEAPS
}
-BOOL GCHeap::FinalizeAppDomain(AppDomain *pDomain, BOOL fRunFinalizers)
+bool GCHeap::FinalizeAppDomain(AppDomain *pDomain, bool fRunFinalizers)
{
#ifdef MULTIPLE_HEAPS
- BOOL foundp = FALSE;
+ bool foundp = false;
for (int hn = 0; hn < gc_heap::n_heaps; hn++)
{
gc_heap* hp = gc_heap::g_heaps [hn];
if (hp->finalize_queue->FinalizeAppDomain (pDomain, fRunFinalizers))
- foundp = TRUE;
+ foundp = true;
}
return foundp;
@@ -35644,13 +35779,13 @@ BOOL GCHeap::FinalizeAppDomain(AppDomain *pDomain, BOOL fRunFinalizers)
#endif //MULTIPLE_HEAPS
}
-BOOL GCHeap::ShouldRestartFinalizerWatchDog()
+bool GCHeap::ShouldRestartFinalizerWatchDog()
{
// This condition was historically used as part of the condition to detect finalizer thread timeouts
return gc_heap::gc_lock.lock != -1;
}
-void GCHeap::SetFinalizeQueueForShutdown(BOOL fHasLock)
+void GCHeap::SetFinalizeQueueForShutdown(bool fHasLock)
{
#ifdef MULTIPLE_HEAPS
for (int hn = 0; hn < gc_heap::n_heaps; hn++)
@@ -35690,9 +35825,6 @@ void GCHeap::SetFinalizationRun (Object* obj)
((CObjectHeader*)obj)->GetHeader()->SetBit(BIT_SBLK_FINALIZER_RUN);
}
-#endif // FEATURE_PREMORTEM_FINALIZATION
-
-#ifdef FEATURE_PREMORTEM_FINALIZATION
//--------------------------------------------------------------------
//
@@ -35967,43 +36099,15 @@ CFinalize::FinalizeSegForAppDomain (AppDomain *pDomain,
// if it has the index we are looking for. If the methodtable is null, it can't be from the
// unloading domain, so skip it.
if (method_table(obj) == NULL)
+ {
continue;
+ }
- // eagerly finalize all objects except those that may be agile.
- if (obj->GetAppDomainIndex() != pDomain->GetIndex())
+ // does the EE actually want us to finalize this object?
+ if (!GCToEEInterface::ShouldFinalizeObjectForUnload(pDomain, obj))
+ {
continue;
-
-#ifndef FEATURE_REDHAWK
- if (method_table(obj)->IsAgileAndFinalizable())
- {
- // If an object is both agile & finalizable, we leave it in the
- // finalization queue during unload. This is OK, since it's agile.
- // Right now only threads can be this way, so if that ever changes, change
- // the assert to just continue if not a thread.
- _ASSERTE(method_table(obj) == g_pThreadClass);
-
- if (method_table(obj) == g_pThreadClass)
- {
- // However, an unstarted thread should be finalized. It could be holding a delegate
- // in the domain we want to unload. Once the thread has been started, its
- // delegate is cleared so only unstarted threads are a problem.
- Thread *pThread = ((THREADBASEREF)ObjectToOBJECTREF(obj))->GetInternal();
- if (! pThread || ! pThread->IsUnstarted())
- {
- // This appdomain is going to be gone soon so let us assign
- // it the appdomain that's guaranteed to exist
- // The object is agile and the delegate should be null so we can do it
- obj->GetHeader()->ResetAppDomainIndexNoFailure(SystemDomain::System()->DefaultDomain()->GetIndex());
- continue;
- }
- }
- else
- {
- obj->GetHeader()->ResetAppDomainIndexNoFailure(SystemDomain::System()->DefaultDomain()->GetIndex());
- continue;
- }
}
-#endif //!FEATURE_REDHAWK
if (!fRunFinalizers || (obj->GetHeader()->GetBits()) & BIT_SBLK_FINALIZER_RUN)
{
@@ -36039,10 +36143,10 @@ CFinalize::FinalizeSegForAppDomain (AppDomain *pDomain,
return finalizedFound;
}
-BOOL
-CFinalize::FinalizeAppDomain (AppDomain *pDomain, BOOL fRunFinalizers)
+bool
+CFinalize::FinalizeAppDomain (AppDomain *pDomain, bool fRunFinalizers)
{
- BOOL finalizedFound = FALSE;
+ bool finalizedFound = false;
unsigned int startSeg = gen_segment (max_generation);
@@ -36052,7 +36156,7 @@ CFinalize::FinalizeAppDomain (AppDomain *pDomain, BOOL fRunFinalizers)
{
if (FinalizeSegForAppDomain (pDomain, fRunFinalizers, Seg))
{
- finalizedFound = TRUE;
+ finalizedFound = true;
}
}
@@ -36162,16 +36266,11 @@ CFinalize::ScanForFinalization (promote_func* pfn, int gen, BOOL mark_only_p,
assert (method_table(obj)->HasFinalizer());
-#ifndef FEATURE_REDHAWK
- if (method_table(obj) == pWeakReferenceMT || method_table(obj)->GetCanonicalMethodTable() == pWeakReferenceOfTCanonMT)
+ if (GCToEEInterface::EagerFinalized(obj))
{
- //destruct the handle right there.
- FinalizeWeakReference (obj);
MoveItem (i, Seg, FreeList);
}
- else
-#endif //!FEATURE_REDHAWK
- if ((obj->GetHeader()->GetBits()) & BIT_SBLK_FINALIZER_RUN)
+ else if ((obj->GetHeader()->GetBits()) & BIT_SBLK_FINALIZER_RUN)
{
//remove the object because we don't want to
//run the finalizer
@@ -36460,13 +36559,13 @@ void GCHeap::DiagWalkObject (Object* obj, walk_fn fn, void* context)
}
}
-void GCHeap::DiagWalkSurvivorsWithType (void* gc_context, record_surv_fn fn, size_t diag_context, walk_surv_type type)
+void GCHeap::DiagWalkSurvivorsWithType (void* gc_context, record_surv_fn fn, void* diag_context, walk_surv_type type)
{
gc_heap* hp = (gc_heap*)gc_context;
hp->walk_survivors (fn, diag_context, type);
}
-void GCHeap::DiagWalkHeap (walk_fn fn, void* context, int gen_number, BOOL walk_large_object_heap_p)
+void GCHeap::DiagWalkHeap (walk_fn fn, void* context, int gen_number, bool walk_large_object_heap_p)
{
gc_heap::walk_heap (fn, context, gen_number, walk_large_object_heap_p);
}
@@ -36610,7 +36709,7 @@ inline void testGCShadow(Object** ptr)
if (*ptr != 0 && (uint8_t*) shadow < g_GCShadowEnd && *ptr != *shadow)
{
- // If you get this assertion, someone updated a GC poitner in the heap without
+ // If you get this assertion, someone updated a GC pointer in the heap without
// using the write barrier. To find out who, check the value of
// dd_collection_count (dynamic_data_of (0)). Also
// note the value of 'ptr'. Rerun the App that the previous GC just occurred.
@@ -36786,7 +36885,7 @@ void GCHeap::TemporaryDisableConcurrentGC()
#endif //BACKGROUND_GC
}
-BOOL GCHeap::IsConcurrentGCEnabled()
+bool GCHeap::IsConcurrentGCEnabled()
{
#ifdef BACKGROUND_GC
return (gc_heap::gc_can_use_concurrent && !(gc_heap::temp_disable_concurrent_p));
@@ -36794,3 +36893,52 @@ BOOL GCHeap::IsConcurrentGCEnabled()
return FALSE;
#endif //BACKGROUND_GC
}
+
+void GCHeap::SetFinalizeRunOnShutdown(bool value)
+{
+ g_fFinalizerRunOnShutDown = value;
+}
+
+void PopulateDacVars(GcDacVars *gcDacVars)
+{
+#ifndef DACCESS_COMPILE
+ assert(gcDacVars != nullptr);
+ *gcDacVars = {};
+ gcDacVars->major_version_number = 1;
+ gcDacVars->minor_version_number = 0;
+ gcDacVars->built_with_svr = &g_built_with_svr_gc;
+ gcDacVars->build_variant = &g_build_variant;
+ gcDacVars->gc_structures_invalid_cnt = const_cast<int32_t*>(&GCScan::m_GcStructuresInvalidCnt);
+ gcDacVars->generation_size = sizeof(generation);
+ gcDacVars->max_gen = &g_max_generation;
+#ifndef MULTIPLE_HEAPS
+ gcDacVars->mark_array = &gc_heap::mark_array;
+ gcDacVars->ephemeral_heap_segment = reinterpret_cast<dac_heap_segment**>(&gc_heap::ephemeral_heap_segment);
+ gcDacVars->current_c_gc_state = const_cast<c_gc_state*>(&gc_heap::current_c_gc_state);
+ gcDacVars->saved_sweep_ephemeral_seg = reinterpret_cast<dac_heap_segment**>(&gc_heap::saved_sweep_ephemeral_seg);
+ gcDacVars->saved_sweep_ephemeral_start = &gc_heap::saved_sweep_ephemeral_start;
+ gcDacVars->background_saved_lowest_address = &gc_heap::background_saved_lowest_address;
+ gcDacVars->background_saved_highest_address = &gc_heap::background_saved_highest_address;
+ gcDacVars->alloc_allocated = &gc_heap::alloc_allocated;
+ gcDacVars->next_sweep_obj = &gc_heap::next_sweep_obj;
+ gcDacVars->oom_info = &gc_heap::oom_info;
+ gcDacVars->finalize_queue = reinterpret_cast<dac_finalize_queue**>(&gc_heap::finalize_queue);
+ gcDacVars->generation_table = reinterpret_cast<dac_generation**>(&gc_heap::generation_table);
+#ifdef GC_CONFIG_DRIVEN
+ gcDacVars->gc_global_mechanisms = reinterpret_cast<size_t**>(&gc_global_mechanisms);
+ gcDacVars->interesting_data_per_heap = reinterpret_cast<size_t**>(&gc_heap::interesting_data_per_heap);
+ gcDacVars->compact_reasons_per_heap = reinterpret_cast<size_t**>(&gc_heap::compact_reasons_per_heap);
+ gcDacVars->expand_mechanisms_per_heap = reinterpret_cast<size_t**>(&gc_heap::expand_mechanisms_per_heap);
+ gcDacVars->interesting_mechanism_bits_per_heap = reinterpret_cast<size_t**>(&gc_heap::interesting_mechanism_bits_per_heap);
+#endif // GC_CONFIG_DRIVEN
+#ifdef HEAP_ANALYZE
+ gcDacVars->internal_root_array = &gc_heap::internal_root_array;
+ gcDacVars->internal_root_array_index = &gc_heap::internal_root_array_index;
+ gcDacVars->heap_analyze_success = &gc_heap::heap_analyze_success;
+#endif // HEAP_ANALYZE
+#else
+ gcDacVars->n_heaps = &gc_heap::n_heaps;
+ gcDacVars->g_heaps = reinterpret_cast<dac_gc_heap***>(&gc_heap::g_heaps);
+#endif // MULTIPLE_HEAPS
+#endif // DACCESS_COMPILE
+}
diff --git a/src/gc/gc.h b/src/gc/gc.h
index 7332e42885..a661c311ab 100644
--- a/src/gc/gc.h
+++ b/src/gc/gc.h
@@ -31,6 +31,11 @@ Module Name:
#ifdef FEATURE_STANDALONE_GC
#include "gcenv.ee.standalone.inl"
+
+// GCStress does not currently work with Standalone GC
+#ifdef STRESS_HEAP
+ #undef STRESS_HEAP
+#endif // STRESS_HEAP
#endif // FEATURE_STANDALONE_GC
/*
@@ -41,21 +46,6 @@ typedef void enum_func (Object*);
// callback functions for heap walkers
typedef void object_callback_func(void * pvContext, void * pvDataLoc);
-/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
-/* If you modify failure_get_memory and */
-/* oom_reason be sure to make the corresponding */
-/* changes in toolbox\sos\strike\strike.cpp. */
-/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
-enum failure_get_memory
-{
- fgm_no_failure = 0,
- fgm_reserve_segment = 1,
- fgm_commit_segment_beg = 2,
- fgm_commit_eph_segment = 3,
- fgm_grow_table = 4,
- fgm_commit_table = 5
-};
-
struct fgm_history
{
failure_get_memory fgm;
@@ -71,17 +61,6 @@ struct fgm_history
}
};
-enum oom_reason
-{
- oom_no_failure = 0,
- oom_budget = 1,
- oom_cant_commit = 2,
- oom_cant_reserve = 3,
- oom_loh = 4,
- oom_low_mem = 5,
- oom_unproductive_full_gc = 6
-};
-
// TODO : it would be easier to make this an ORed value
enum gc_reason
{
@@ -100,19 +79,6 @@ enum gc_reason
reason_max
};
-struct oom_history
-{
- oom_reason reason;
- size_t alloc_size;
- uint8_t* reserved;
- uint8_t* allocated;
- size_t gc_index;
- failure_get_memory fgm;
- size_t size;
- size_t available_pagefile_mb;
- BOOL loh_p;
-};
-
/* forward declerations */
class CObjectHeader;
class Object;
@@ -121,10 +87,11 @@ class IGCHeapInternal;
/* misc defines */
#define LARGE_OBJECT_SIZE ((size_t)(85000))
+#define max_generation 2
#ifdef GC_CONFIG_DRIVEN
#define MAX_GLOBAL_GC_MECHANISMS_COUNT 6
-GARY_DECL(size_t, gc_global_mechanisms, MAX_GLOBAL_GC_MECHANISMS_COUNT);
+extern size_t gc_global_mechanisms[MAX_GLOBAL_GC_MECHANISMS_COUNT];
#endif //GC_CONFIG_DRIVEN
#ifdef DACCESS_COMPILE
@@ -137,10 +104,18 @@ class DacHeapWalker;
#define MP_LOCKS
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+extern "C" uint32_t* g_gc_card_bundle_table;
+#endif
+
extern "C" uint32_t* g_gc_card_table;
extern "C" uint8_t* g_gc_lowest_address;
extern "C" uint8_t* g_gc_highest_address;
-extern "C" bool g_fFinalizerRunOnShutDown;
+extern "C" GCHeapType g_gc_heap_type;
+extern "C" uint32_t g_max_generation;
+extern "C" MethodTable* g_gc_pFreeObjectMethodTable;
+
+::IGCHandleTable* CreateGCHandleTable();
namespace WKS {
::IGCHeapInternal* CreateGCHeap();
@@ -248,32 +223,25 @@ public:
unsigned GetMaxGeneration()
{
- return IGCHeap::maxGeneration;
+ return max_generation;
}
- BOOL IsValidSegmentSize(size_t cbSize)
+ bool IsValidSegmentSize(size_t cbSize)
{
//Must be aligned on a Mb and greater than 4Mb
return (((cbSize & (1024*1024-1)) ==0) && (cbSize >> 22));
}
- BOOL IsValidGen0MaxSize(size_t cbSize)
+ bool IsValidGen0MaxSize(size_t cbSize)
{
return (cbSize >= 64*1024);
}
BOOL IsLargeObject(MethodTable *mt)
{
- WRAPPER_NO_CONTRACT;
-
return mt->GetBaseSize() >= LARGE_OBJECT_SIZE;
}
- void SetFinalizeRunOnShutdown(bool value)
- {
- g_fFinalizerRunOnShutDown = value;
- }
-
protected:
public:
#if defined(FEATURE_BASICFREEZE) && defined(VERIFY_HEAP)
@@ -289,30 +257,24 @@ void TouchPages(void * pStart, size_t cb);
void updateGCShadow(Object** ptr, Object* val);
#endif
-// the method table for the WeakReference class
-extern MethodTable *pWeakReferenceMT;
-// The canonical method table for WeakReference<T>
-extern MethodTable *pWeakReferenceOfTCanonMT;
-extern void FinalizeWeakReference(Object * obj);
-
// The single GC heap instance, shared with the VM.
extern IGCHeapInternal* g_theGCHeap;
+// The single GC handle table instance, shared with the VM.
+extern IGCHandleTable* g_theGCHandleTable;
+
#ifndef DACCESS_COMPILE
-inline BOOL IsGCInProgress(bool bConsiderGCStart = FALSE)
+inline bool IsGCInProgress(bool bConsiderGCStart = false)
{
- WRAPPER_NO_CONTRACT;
-
return g_theGCHeap != nullptr ? g_theGCHeap->IsGCInProgressHelper(bConsiderGCStart) : false;
}
#endif // DACCESS_COMPILE
-inline BOOL IsServerHeap()
+inline bool IsServerHeap()
{
- LIMITED_METHOD_CONTRACT;
#ifdef FEATURE_SVR_GC
- _ASSERTE(IGCHeap::gcHeapType != IGCHeap::GC_HEAP_INVALID);
- return (IGCHeap::gcHeapType == IGCHeap::GC_HEAP_SVR);
+ assert(g_gc_heap_type != GC_HEAP_INVALID);
+ return g_gc_heap_type == GC_HEAP_SVR;
#else // FEATURE_SVR_GC
return false;
#endif // FEATURE_SVR_GC
diff --git a/src/gc/gccommon.cpp b/src/gc/gccommon.cpp
index 133f05e490..f931597667 100644
--- a/src/gc/gccommon.cpp
+++ b/src/gc/gccommon.cpp
@@ -14,20 +14,15 @@
#include "gcenv.h"
#include "gc.h"
-#ifdef FEATURE_SVR_GC
-SVAL_IMPL_INIT(uint32_t,IGCHeap,gcHeapType,IGCHeap::GC_HEAP_INVALID);
-#endif // FEATURE_SVR_GC
-
-SVAL_IMPL_INIT(uint32_t,IGCHeap,maxGeneration,2);
-
IGCHeapInternal* g_theGCHeap;
+IGCHandleTable* g_theGCHandleTable;
#ifdef FEATURE_STANDALONE_GC
IGCToCLR* g_theGCToCLR;
#endif // FEATURE_STANDALONE_GC
#ifdef GC_CONFIG_DRIVEN
-GARY_IMPL(size_t, gc_global_mechanisms, MAX_GLOBAL_GC_MECHANISMS_COUNT);
+size_t gc_global_mechanisms[MAX_GLOBAL_GC_MECHANISMS_COUNT];
#endif //GC_CONFIG_DRIVEN
#ifndef DACCESS_COMPILE
@@ -39,16 +34,21 @@ uint8_t* g_shadow_lowest_address = NULL;
#endif
uint32_t* g_gc_card_table;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+uint32_t* g_gc_card_bundle_table;
+#endif
+
uint8_t* g_gc_lowest_address = 0;
uint8_t* g_gc_highest_address = 0;
-bool g_fFinalizerRunOnShutDown = false;
-
-VOLATILE(int32_t) m_GCLock = -1;
+GCHeapType g_gc_heap_type = GC_HEAP_INVALID;
+uint32_t g_max_generation = max_generation;
+MethodTable* g_gc_pFreeObjectMethodTable = nullptr;
#ifdef GC_CONFIG_DRIVEN
void record_global_mechanism (int mech_index)
{
- (gc_global_mechanisms[mech_index])++;
+ (gc_global_mechanisms[mech_index])++;
}
#endif //GC_CONFIG_DRIVEN
@@ -119,9 +119,9 @@ void InitializeHeapType(bool bServerHeap)
{
LIMITED_METHOD_CONTRACT;
#ifdef FEATURE_SVR_GC
- IGCHeap::gcHeapType = bServerHeap ? IGCHeap::GC_HEAP_SVR : IGCHeap::GC_HEAP_WKS;
+ g_gc_heap_type = bServerHeap ? GC_HEAP_SVR : GC_HEAP_WKS;
#ifdef WRITE_BARRIER_CHECK
- if (IGCHeap::gcHeapType == IGCHeap::GC_HEAP_SVR)
+ if (g_gc_heap_type == GC_HEAP_SVR)
{
g_GCShadow = 0;
g_GCShadowEnd = 0;
@@ -133,18 +133,55 @@ void InitializeHeapType(bool bServerHeap)
#endif // FEATURE_SVR_GC
}
-IGCHeap* InitializeGarbageCollector(IGCToCLR* clrToGC)
+namespace WKS
+{
+ extern void PopulateDacVars(GcDacVars* dacVars);
+}
+
+namespace SVR
+{
+ extern void PopulateDacVars(GcDacVars* dacVars);
+}
+
+bool InitializeGarbageCollector(IGCToCLR* clrToGC, IGCHeap** gcHeap, IGCHandleTable** gcHandleTable, GcDacVars* gcDacVars)
{
LIMITED_METHOD_CONTRACT;
IGCHeapInternal* heap;
+
+ assert(gcDacVars != nullptr);
+ assert(gcHeap != nullptr);
+ assert(gcHandleTable != nullptr);
+
+ IGCHandleTable* handleTable = CreateGCHandleTable();
+ if (handleTable == nullptr)
+ {
+ return false;
+ }
+
#ifdef FEATURE_SVR_GC
- assert(IGCHeap::gcHeapType != IGCHeap::GC_HEAP_INVALID);
- heap = IGCHeap::gcHeapType == IGCHeap::GC_HEAP_SVR ? SVR::CreateGCHeap() : WKS::CreateGCHeap();
+ assert(g_gc_heap_type != GC_HEAP_INVALID);
+
+ if (g_gc_heap_type == GC_HEAP_SVR)
+ {
+ heap = SVR::CreateGCHeap();
+ SVR::PopulateDacVars(gcDacVars);
+ }
+ else
+ {
+ heap = WKS::CreateGCHeap();
+ WKS::PopulateDacVars(gcDacVars);
+ }
#else
heap = WKS::CreateGCHeap();
+ WKS::PopulateDacVars(gcDacVars);
#endif
+ if (heap == nullptr)
+ {
+ return false;
+ }
+
g_theGCHeap = heap;
#ifdef FEATURE_STANDALONE_GC
@@ -155,7 +192,9 @@ IGCHeap* InitializeGarbageCollector(IGCToCLR* clrToGC)
assert(clrToGC == nullptr);
#endif
- return heap;
+ *gcHandleTable = handleTable;
+ *gcHeap = heap;
+ return true;
}
#endif // !DACCESS_COMPILE
diff --git a/src/gc/gcee.cpp b/src/gc/gcee.cpp
index c93cc91b57..889f940973 100644
--- a/src/gc/gcee.cpp
+++ b/src/gc/gcee.cpp
@@ -381,12 +381,12 @@ size_t GCHeap::GetNow()
return GetHighPrecisionTimeStamp();
}
-BOOL GCHeap::IsGCInProgressHelper (BOOL bConsiderGCStart)
+bool GCHeap::IsGCInProgressHelper (bool bConsiderGCStart)
{
return GcInProgress || (bConsiderGCStart? VolatileLoad(&gc_heap::gc_started) : FALSE);
}
-uint32_t GCHeap::WaitUntilGCComplete(BOOL bConsiderGCStart)
+uint32_t GCHeap::WaitUntilGCComplete(bool bConsiderGCStart)
{
if (bConsiderGCStart)
{
@@ -408,12 +408,8 @@ BlockAgain:
dwWaitResult = WaitForGCEvent->Wait(DETECT_DEADLOCK_TIMEOUT, FALSE );
if (dwWaitResult == WAIT_TIMEOUT) {
- // Even in retail, stop in the debugger if available. Ideally, the
- // following would use DebugBreak, but debspew.h makes this a null
- // macro in retail. Note that in debug, we don't use the debspew.h
- // macros because these take a critical section that may have been
- // taken by a suspended thread.
- FreeBuildDebugBreak();
+ // Even in retail, stop in the debugger if available.
+ GCToOSInterface::DebugBreak();
goto BlockAgain;
}
@@ -427,7 +423,7 @@ BlockAgain:
return dwWaitResult;
}
-void GCHeap::SetGCInProgress(BOOL fInProgress)
+void GCHeap::SetGCInProgress(bool fInProgress)
{
GcInProgress = fInProgress;
}
@@ -445,12 +441,12 @@ void GCHeap::WaitUntilConcurrentGCComplete()
#endif //BACKGROUND_GC
}
-BOOL GCHeap::IsConcurrentGCInProgress()
+bool GCHeap::IsConcurrentGCInProgress()
{
#ifdef BACKGROUND_GC
- return pGenGCHeap->settings.concurrent;
+ return !!pGenGCHeap->settings.concurrent;
#else
- return FALSE;
+ return false;
#endif //BACKGROUND_GC
}
@@ -681,6 +677,11 @@ void GCHeap::UnregisterFrozenSegment(segment_handle seg)
#endif // FEATURE_BASICFREEZE
}
+bool GCHeap::RuntimeStructuresValid()
+{
+ return GCScan::GetGcRuntimeStructuresValid();
+}
+
#endif // !DACCESS_COMPILE
diff --git a/src/gc/gceesvr.cpp b/src/gc/gceesvr.cpp
index aacae486f5..2e6dbe2d08 100644
--- a/src/gc/gceesvr.cpp
+++ b/src/gc/gceesvr.cpp
@@ -12,9 +12,11 @@
#include "gc.h"
#include "gcscan.h"
+#include "gchandletableimpl.h"
#define SERVER_GC 1
+
namespace SVR {
#include "gcimpl.h"
#include "gcee.cpp"
diff --git a/src/gc/gceewks.cpp b/src/gc/gceewks.cpp
index 72a7d3bdb9..f23038f012 100644
--- a/src/gc/gceewks.cpp
+++ b/src/gc/gceewks.cpp
@@ -10,6 +10,7 @@
#include "gc.h"
#include "gcscan.h"
+#include "gchandletableimpl.h"
#ifdef SERVER_GC
#undef SERVER_GC
diff --git a/src/gc/gcenv.ee.standalone.inl b/src/gc/gcenv.ee.standalone.inl
index 31f3d1d8da..f6954fc476 100644
--- a/src/gc/gcenv.ee.standalone.inl
+++ b/src/gc/gcenv.ee.standalone.inl
@@ -207,6 +207,35 @@ ALWAYS_INLINE void GCToEEInterface::EnableFinalization(bool foundFinalizers)
g_theGCToCLR->EnableFinalization(foundFinalizers);
}
+ALWAYS_INLINE void GCToEEInterface::HandleFatalError(unsigned int exitCode)
+{
+ assert(g_theGCToCLR != nullptr);
+ g_theGCToCLR->HandleFatalError(exitCode);
+}
+
+ALWAYS_INLINE bool GCToEEInterface::ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj)
+{
+ assert(g_theGCToCLR != nullptr);
+ return g_theGCToCLR->ShouldFinalizeObjectForUnload(pDomain, obj);
+}
+
+ALWAYS_INLINE bool GCToEEInterface::ForceFullGCToBeBlocking()
+{
+ assert(g_theGCToCLR != nullptr);
+ return g_theGCToCLR->ForceFullGCToBeBlocking();
+}
+
+ALWAYS_INLINE bool GCToEEInterface::EagerFinalized(Object* obj)
+{
+ assert(g_theGCToCLR != nullptr);
+ return g_theGCToCLR->EagerFinalized(obj);
+}
+
+ALWAYS_INLINE MethodTable* GCToEEInterface::GetFreeObjectMethodTable()
+{
+ assert(g_theGCToCLR != nullptr);
+ return g_theGCToCLR->GetFreeObjectMethodTable();
+}
#undef ALWAYS_INLINE
#endif // __GCTOENV_EE_STANDALONE_INL__
diff --git a/src/gc/gchandletable.cpp b/src/gc/gchandletable.cpp
new file mode 100644
index 0000000000..82ab269861
--- /dev/null
+++ b/src/gc/gchandletable.cpp
@@ -0,0 +1,111 @@
+// 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 "common.h"
+#include "gcenv.h"
+#include "gchandletableimpl.h"
+#include "objecthandle.h"
+
+IGCHandleTable* CreateGCHandleTable()
+{
+ return new(nothrow) GCHandleTable();
+}
+
+bool GCHandleTable::Initialize()
+{
+ return Ref_Initialize();
+}
+
+void GCHandleTable::Shutdown()
+{
+ Ref_Shutdown();
+}
+
+void* GCHandleTable::GetGlobalHandleStore()
+{
+ return (void*)g_HandleTableMap.pBuckets[0];
+}
+
+void* GCHandleTable::CreateHandleStore(void* context)
+{
+#ifndef FEATURE_REDHAWK
+ return (void*)::Ref_CreateHandleTableBucket(ADIndex((DWORD)(uintptr_t)context));
+#else
+ assert("CreateHandleStore is not implemented when FEATURE_REDHAWK is defined!");
+ return nullptr;
+#endif
+}
+
+void* GCHandleTable::GetHandleContext(OBJECTHANDLE handle)
+{
+ return (void*)((uintptr_t)::HndGetHandleTableADIndex(::HndGetHandleTable(handle)).m_dwIndex);
+}
+
+void GCHandleTable::DestroyHandleStore(void* store)
+{
+ Ref_DestroyHandleTableBucket((HandleTableBucket*) store);
+}
+
+void GCHandleTable::UprootHandleStore(void* store)
+{
+ Ref_RemoveHandleTableBucket((HandleTableBucket*) store);
+}
+
+bool GCHandleTable::ContainsHandle(void* store, OBJECTHANDLE handle)
+{
+ return ((HandleTableBucket*)store)->Contains(handle);
+}
+
+OBJECTHANDLE GCHandleTable::CreateHandleOfType(void* store, Object* object, int type)
+{
+ HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[GetCurrentThreadHomeHeapNumber()];
+ return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
+}
+
+OBJECTHANDLE GCHandleTable::CreateHandleOfType(void* store, Object* object, int type, int heapToAffinitizeTo)
+{
+ HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[heapToAffinitizeTo];
+ return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
+}
+
+OBJECTHANDLE GCHandleTable::CreateGlobalHandleOfType(Object* object, int type)
+{
+ return ::HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], type, ObjectToOBJECTREF(object));
+}
+
+OBJECTHANDLE GCHandleTable::CreateHandleWithExtraInfo(void* store, Object* object, int type, void* pExtraInfo)
+{
+ HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[GetCurrentThreadHomeHeapNumber()];
+ return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object), reinterpret_cast<uintptr_t>(pExtraInfo));
+}
+
+OBJECTHANDLE GCHandleTable::CreateDependentHandle(void* store, Object* primary, Object* secondary)
+{
+ HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[GetCurrentThreadHomeHeapNumber()];
+ OBJECTHANDLE handle = ::HndCreateHandle(handletable, HNDTYPE_DEPENDENT, ObjectToOBJECTREF(primary));
+ ::SetDependentHandleSecondary(handle, ObjectToOBJECTREF(secondary));
+
+ return handle;
+}
+
+OBJECTHANDLE GCHandleTable::CreateDuplicateHandle(OBJECTHANDLE handle)
+{
+ return ::HndCreateHandle(HndGetHandleTable(handle), HNDTYPE_DEFAULT, ::HndFetchHandle(handle));
+}
+
+void GCHandleTable::DestroyHandleOfType(OBJECTHANDLE handle, int type)
+{
+ ::HndDestroyHandle(::HndGetHandleTable(handle), type, handle);
+}
+
+void GCHandleTable::DestroyHandleOfUnknownType(OBJECTHANDLE handle)
+{
+ ::HndDestroyHandleOfUnknownType(::HndGetHandleTable(handle), handle);
+}
+
+void* GCHandleTable::GetExtraInfoFromHandle(OBJECTHANDLE handle)
+{
+ return (void*)::HndGetHandleExtraInfo(handle);
+}
diff --git a/src/gc/gchandletableimpl.h b/src/gc/gchandletableimpl.h
new file mode 100644
index 0000000000..af20f52e54
--- /dev/null
+++ b/src/gc/gchandletableimpl.h
@@ -0,0 +1,48 @@
+// 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.
+
+#ifndef GCHANDLETABLE_H_
+#define GCHANDLETABLE_H_
+
+#include "gcinterface.h"
+
+class GCHandleTable : public IGCHandleTable
+{
+public:
+ virtual bool Initialize();
+
+ virtual void Shutdown();
+
+ virtual void* GetGlobalHandleStore();
+
+ virtual void* CreateHandleStore(void* context);
+
+ virtual void* GetHandleContext(OBJECTHANDLE handle);
+
+ virtual void DestroyHandleStore(void* store);
+
+ virtual void UprootHandleStore(void* store);
+
+ virtual bool ContainsHandle(void* store, OBJECTHANDLE handle);
+
+ virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type);
+
+ virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type, int heapToAffinitizeTo);
+
+ virtual OBJECTHANDLE CreateHandleWithExtraInfo(void* store, Object* object, int type, void* pExtraInfo);
+
+ virtual OBJECTHANDLE CreateDependentHandle(void* store, Object* primary, Object* secondary);
+
+ virtual OBJECTHANDLE CreateGlobalHandleOfType(Object* object, int type);
+
+ virtual OBJECTHANDLE CreateDuplicateHandle(OBJECTHANDLE handle);
+
+ virtual void DestroyHandleOfType(OBJECTHANDLE handle, int type);
+
+ virtual void DestroyHandleOfUnknownType(OBJECTHANDLE handle);
+
+ virtual void* GetExtraInfoFromHandle(OBJECTHANDLE handle);
+};
+
+#endif // GCHANDLETABLE_H_
diff --git a/src/gc/gcimpl.h b/src/gc/gcimpl.h
index cb91c4dc3e..2a51d477b0 100644
--- a/src/gc/gcimpl.h
+++ b/src/gc/gcimpl.h
@@ -39,6 +39,11 @@ void GCProfileWalkHeap();
class gc_heap;
class CFinalize;
+extern bool g_fFinalizerRunOnShutDown;
+extern bool g_built_with_svr_gc;
+extern uint8_t g_build_variant;
+extern VOLATILE(int32_t) g_no_gc_lock;
+
class GCHeap : public IGCHeapInternal
{
protected:
@@ -80,19 +85,19 @@ public:
void DiagTraceGCSegments ();
void PublishObject(uint8_t* obj);
- BOOL IsGCInProgressHelper (BOOL bConsiderGCStart = FALSE);
+ bool IsGCInProgressHelper (bool bConsiderGCStart = false);
+
+ uint32_t WaitUntilGCComplete (bool bConsiderGCStart = false);
- uint32_t WaitUntilGCComplete (BOOL bConsiderGCStart = FALSE);
+ void SetGCInProgress(bool fInProgress);
- void SetGCInProgress(BOOL fInProgress);
+ bool RuntimeStructuresValid();
CLREvent * GetWaitForGCEvent();
HRESULT Initialize ();
//flags can be GC_ALLOC_CONTAINS_REF GC_ALLOC_FINALIZE
- Object* Alloc (size_t size, uint32_t flags);
- Object* AllocAlign8 (size_t size, uint32_t flags);
Object* AllocAlign8 (gc_alloc_context* acontext, size_t size, uint32_t flags);
private:
Object* AllocAlign8Common (void* hp, alloc_context* acontext, size_t size, uint32_t flags);
@@ -101,9 +106,9 @@ public:
Object* Alloc (gc_alloc_context* acontext, size_t size, uint32_t flags);
void FixAllocContext (gc_alloc_context* acontext,
- BOOL lockp, void* arg, void *heap);
+ bool lockp, void* arg, void *heap);
- Object* GetContainingObject(void *pInteriorPtr);
+ Object* GetContainingObject(void *pInteriorPtr, bool fCollectedGenOnly);
#ifdef MULTIPLE_HEAPS
static void AssignHeap (alloc_context* acontext);
@@ -116,15 +121,15 @@ public:
void HideAllocContext(alloc_context*);
void RevealAllocContext(alloc_context*);
- BOOL IsObjectInFixedHeap(Object *pObj);
+ bool IsObjectInFixedHeap(Object *pObj);
- HRESULT GarbageCollect (int generation = -1, BOOL low_memory_p=FALSE, int mode=collection_blocking);
+ HRESULT GarbageCollect (int generation = -1, bool low_memory_p=false, int mode=collection_blocking);
////
// GC callback functions
// Check if an argument is promoted (ONLY CALL DURING
// THE PROMOTIONSGRANTED CALLBACK.)
- BOOL IsPromoted (Object *object);
+ bool IsPromoted (Object *object);
size_t GetPromotedBytes (int heap_index);
@@ -152,8 +157,8 @@ public:
//returns the generation number of an object (not valid during relocation)
unsigned WhichGeneration (Object* object);
// returns TRUE is the object is ephemeral
- BOOL IsEphemeral (Object* object);
- BOOL IsHeapPointer (void* object, BOOL small_heap_only = FALSE);
+ bool IsEphemeral (Object* object);
+ bool IsHeapPointer (void* object, bool small_heap_only = false);
void ValidateObjectMember (Object *obj);
@@ -168,13 +173,13 @@ public:
int GetLOHCompactionMode();
void SetLOHCompactionMode(int newLOHCompactionyMode);
- BOOL RegisterForFullGCNotification(uint32_t gen2Percentage,
+ bool RegisterForFullGCNotification(uint32_t gen2Percentage,
uint32_t lohPercentage);
- BOOL CancelFullGCNotification();
+ bool CancelFullGCNotification();
int WaitForFullGCApproach(int millisecondsTimeout);
int WaitForFullGCComplete(int millisecondsTimeout);
- int StartNoGCRegion(uint64_t totalSize, BOOL lohSizeKnown, uint64_t lohSize, BOOL disallowFullBlockingGC);
+ int StartNoGCRegion(uint64_t totalSize, bool lohSizeKnown, uint64_t lohSize, bool disallowFullBlockingGC);
int EndNoGCRegion();
unsigned GetGcCount();
@@ -184,7 +189,7 @@ public:
PER_HEAP_ISOLATED HRESULT GetGcCounters(int gen, gc_counters* counters);
- size_t GetValidSegmentSize(BOOL large_seg = FALSE);
+ size_t GetValidSegmentSize(bool large_seg = false);
static size_t GetValidGen0MaxSize(size_t seg_size);
@@ -194,11 +199,12 @@ public:
PER_HEAP_ISOLATED size_t GetNumberFinalizableObjects();
PER_HEAP_ISOLATED size_t GetFinalizablePromotedCount();
- void SetFinalizeQueueForShutdown(BOOL fHasLock);
- BOOL FinalizeAppDomain(AppDomain *pDomain, BOOL fRunFinalizers);
- BOOL ShouldRestartFinalizerWatchDog();
+ void SetFinalizeQueueForShutdown(bool fHasLock);
+ bool FinalizeAppDomain(AppDomain *pDomain, bool fRunFinalizers);
+ bool ShouldRestartFinalizerWatchDog();
void DiagWalkObject (Object* obj, walk_fn fn, void* context);
+ void SetFinalizeRunOnShutdown(bool value);
public: // FIX
@@ -229,12 +235,12 @@ public: // FIX
#ifndef DACCESS_COMPILE
HRESULT WaitUntilConcurrentGCCompleteAsync(int millisecondsTimeout); // Use in native threads. TRUE if succeed. FALSE if failed or timeout
#endif
- BOOL IsConcurrentGCInProgress();
+ bool IsConcurrentGCInProgress();
// Enable/disable concurrent GC
void TemporaryEnableConcurrentGC();
void TemporaryDisableConcurrentGC();
- BOOL IsConcurrentGCEnabled();
+ bool IsConcurrentGCEnabled();
PER_HEAP_ISOLATED CLREvent *WaitForGCEvent; // used for syncing w/GC
@@ -253,7 +259,7 @@ private:
}
public:
//return TRUE if GC actually happens, otherwise FALSE
- BOOL StressHeap(gc_alloc_context * acontext = 0);
+ bool StressHeap(gc_alloc_context * acontext);
#ifndef FEATURE_REDHAWK // Redhawk forces relocation a different way
#ifdef STRESS_HEAP
@@ -273,7 +279,7 @@ protected:
virtual void DiagDescrGenerations (gen_walk_fn fn, void *context);
- virtual void DiagWalkSurvivorsWithType (void* gc_context, record_surv_fn fn, size_t diag_context, walk_surv_type type);
+ virtual void DiagWalkSurvivorsWithType (void* gc_context, record_surv_fn fn, void* diag_context, walk_surv_type type);
virtual void DiagWalkFinalizeQueue (void* gc_context, fq_walk_fn fn);
@@ -283,7 +289,7 @@ protected:
virtual void DiagScanDependentHandles (handle_scan_fn fn, int gen_number, ScanContext* context);
- virtual void DiagWalkHeap(walk_fn fn, void* context, int gen_number, BOOL walk_large_object_heap_p);
+ virtual void DiagWalkHeap(walk_fn fn, void* context, int gen_number, bool walk_large_object_heap_p);
public:
Object * NextObj (Object * object);
diff --git a/src/gc/gcinterface.dac.h b/src/gc/gcinterface.dac.h
new file mode 100644
index 0000000000..647101fa1f
--- /dev/null
+++ b/src/gc/gcinterface.dac.h
@@ -0,0 +1,156 @@
+// 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.
+
+#ifndef _GC_INTERFACE_DAC_H_
+#define _GC_INTERFACE_DAC_H_
+
+// This file defines the interface between the GC and the DAC. The interface consists of two things:
+// 1. A number of variables ("DAC vars") whose addresses are exposed to the DAC (see "struct GcDacVars")
+// 2. A number of types that are analogues to GC-internal types. These types expose a subset of the
+// GC-internal type's fields, while still maintaining the same layout.
+// This interface is strictly versioned, see gcinterface.dacvars.def for more information.
+
+#define NUM_GC_DATA_POINTS 9
+#define MAX_COMPACT_REASONS_COUNT 11
+#define MAX_EXPAND_MECHANISMS_COUNT 6
+#define MAX_GC_MECHANISM_BITS_COUNT 2
+#define MAX_GLOBAL_GC_MECHANISMS_COUNT 6
+#define NUMBERGENERATIONS 4
+
+// Analogue for the GC heap_segment class, containing information regarding a single
+// heap segment.
+class dac_heap_segment {
+public:
+ uint8_t* allocated;
+ uint8_t* committed;
+ uint8_t* reserved;
+ uint8_t* used;
+ uint8_t* mem;
+ size_t flags;
+ DPTR(dac_heap_segment) next;
+ uint8_t* background_allocated;
+ class dac_gc_heap* heap;
+};
+
+// Analogue for the GC generation class, containing information about the start segment
+// of a generation and its allocation context.
+class dac_generation {
+public:
+ gc_alloc_context allocation_context;
+ DPTR(dac_heap_segment) start_segment;
+ uint8_t* allocation_start;
+};
+
+// Analogue for the GC CFinalize class, containing information about the finalize queue.
+class dac_finalize_queue {
+public:
+ static const int ExtraSegCount = 2;
+ uint8_t** m_FillPointers[NUMBERGENERATIONS + ExtraSegCount];
+};
+
+// Possible values of the current_c_gc_state dacvar, indicating the state of
+// a background GC.
+enum c_gc_state
+{
+ c_gc_state_marking,
+ c_gc_state_planning,
+ c_gc_state_free
+};
+
+// Reasons why an OOM might occur, recorded in the oom_history
+// struct below.
+enum oom_reason
+{
+ oom_no_failure = 0,
+ oom_budget = 1,
+ oom_cant_commit = 2,
+ oom_cant_reserve = 3,
+ oom_loh = 4,
+ oom_low_mem = 5,
+ oom_unproductive_full_gc = 6
+};
+
+/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+/* If you modify failure_get_memory and */
+/* oom_reason be sure to make the corresponding */
+/* changes in toolbox\sos\strike\strike.cpp. */
+/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+enum failure_get_memory
+{
+ fgm_no_failure = 0,
+ fgm_reserve_segment = 1,
+ fgm_commit_segment_beg = 2,
+ fgm_commit_eph_segment = 3,
+ fgm_grow_table = 4,
+ fgm_commit_table = 5
+};
+
+// A record of the last OOM that occured in the GC, with some
+// additional information as to what triggered the OOM.
+struct oom_history
+{
+ oom_reason reason;
+ size_t alloc_size;
+ uint8_t* reserved;
+ uint8_t* allocated;
+ size_t gc_index;
+ failure_get_memory fgm;
+ size_t size;
+ size_t available_pagefile_mb;
+ BOOL loh_p;
+};
+
+// Analogue for the GC gc_heap class, containing information regarding a single
+// GC heap (of which there are multiple, with server GC).
+class dac_gc_heap {
+public:
+ uint8_t* alloc_allocated;
+ DPTR(dac_heap_segment) ephemeral_heap_segment;
+ DPTR(dac_finalize_queue) finalize_queue;
+ oom_history oom_info;
+ size_t interesting_data_per_heap[NUM_GC_DATA_POINTS];
+ size_t compact_reasons_per_heap[MAX_COMPACT_REASONS_COUNT];
+ size_t expand_mechanisms_per_heap[MAX_EXPAND_MECHANISMS_COUNT];
+ size_t interesting_mechanism_bits_per_heap[MAX_GC_MECHANISM_BITS_COUNT];
+ uint8_t* internal_root_array;
+ size_t internal_root_array_index;
+ BOOL heap_analyze_success;
+
+ // The generation table must always be last, because the size of this array
+ // (stored inline in the gc_heap class) can vary.
+ //
+ // The size of the generation class is not part of the GC-DAC interface,
+ // despite being embedded by-value into the gc_heap class. The DAC variable
+ // "generation_size" stores the size of the generation class, so the DAC can
+ // use it and pointer arithmetic to calculate correct offsets into the generation
+ // table. (See "GenerationTableIndex" function in the DAC for details)
+ //
+ // Also note that this array has length 1 because the C++ standard doesn't allow
+ // for 0-length arrays, although every major compiler is willing to tolerate it.
+ dac_generation generation_table[1];
+};
+
+
+// The actual structure containing the DAC variables. When DACCESS_COMPILE is not
+// defined (i.e. the normal runtime build), this structure contains pointers to the
+// GC's global DAC variabels. When DACCESS_COMPILE is defined (i.e. the DAC build),
+// this structure contains __DPtrs for every DAC variable that will marshal values
+// from the debugee process to the debugger process when dereferenced.
+struct GcDacVars {
+ uint8_t major_version_number;
+ uint8_t minor_version_number;
+ size_t generation_size;
+#ifdef DACCESS_COMPILE
+ #define GC_DAC_VAR(type, name) DPTR(type) name;
+ // ArrayDPTR doesn't allow decaying arrays to pointers, which
+ // avoids some accidental errors.
+ #define GC_DAC_PTR_VAR(type, name) DPTR(type*) name;
+ #define GC_DAC_ARRAY_VAR(type, name) DPTR(type) name;
+#else
+ #define GC_DAC_VAR(type, name) type *name;
+#endif
+#include "gcinterface.dacvars.def"
+};
+
+#endif // _GC_INTERFACE_DAC_H_
diff --git a/src/gc/gcinterface.dacvars.def b/src/gc/gcinterface.dacvars.def
new file mode 100644
index 0000000000..b788079dcb
--- /dev/null
+++ b/src/gc/gcinterface.dacvars.def
@@ -0,0 +1,66 @@
+// 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.
+
+// This file contains the defintions of all DAC variables that the G
+// exports and that the DAC uses to interface with the GC.
+//
+// This interface has a strict semantic versioning. The following changes require
+// a bump to the major version number:
+// 1. Changing the type of any of these variables,
+// 2. Changing the type layouts of any of the types in gcinterface.dac.h,
+// (dac_generation, dac_heap_segment, dac_finalize_queue)
+// 3. Changing the semantic meaning of any of these variables, such that the DAC's
+// use of them is no longer correct,
+//
+// The following change requires a bump to the minor version number:
+// 1. Adding additional DAC variables.
+//
+// Minor version mismatches are tolerated by the DAC, at the risk of a possibly
+// degraded debugging experience.
+// Major version mismatches are not tolerated by the DAC and will be rejected upon load.
+
+#ifndef GC_DAC_VAR
+ #define GC_DAC_VAR(type, name)
+#endif // GC_DAC_VAR
+
+#ifndef GC_DAC_ARRAY_VAR
+ #define GC_DAC_ARRAY_VAR(type, name) GC_DAC_VAR(type*, name)
+#endif // GC_DAC_ARRAY_VAR
+
+#ifndef GC_DAC_PTR_VAR
+ #define GC_DAC_PTR_VAR(type, name) GC_DAC_VAR(type*, name)
+#endif // GC_DAC_PTR_VAR
+
+// This sequence of macros defines the specific variables that are exposed by the
+// GC to the DAC.
+GC_DAC_VAR (uint8_t, build_variant)
+GC_DAC_VAR (bool, built_with_svr)
+GC_DAC_ARRAY_VAR (size_t, gc_global_mechanisms)
+GC_DAC_ARRAY_VAR (dac_generation, generation_table)
+GC_DAC_VAR (uint32_t, max_gen)
+GC_DAC_PTR_VAR (uint32_t, mark_array)
+GC_DAC_VAR (c_gc_state, current_c_gc_state)
+GC_DAC_PTR_VAR (dac_heap_segment, ephemeral_heap_segment)
+GC_DAC_PTR_VAR (dac_heap_segment, saved_sweep_ephemeral_seg)
+GC_DAC_PTR_VAR (uint8_t, saved_sweep_ephemeral_start)
+GC_DAC_PTR_VAR (uint8_t, background_saved_lowest_address)
+GC_DAC_PTR_VAR (uint8_t, background_saved_highest_address)
+GC_DAC_PTR_VAR (uint8_t, alloc_allocated)
+GC_DAC_PTR_VAR (uint8_t, next_sweep_obj)
+GC_DAC_VAR (oom_history, oom_info)
+GC_DAC_PTR_VAR (dac_finalize_queue, finalize_queue)
+GC_DAC_PTR_VAR (uint8_t*, internal_root_array)
+GC_DAC_VAR (size_t, internal_root_array_index)
+GC_DAC_VAR (BOOL, heap_analyze_success)
+GC_DAC_VAR (int, n_heaps)
+GC_DAC_PTR_VAR (dac_gc_heap*, g_heaps)
+GC_DAC_VAR (int32_t, gc_structures_invalid_cnt)
+GC_DAC_ARRAY_VAR (size_t, interesting_data_per_heap)
+GC_DAC_ARRAY_VAR (size_t, compact_reasons_per_heap)
+GC_DAC_ARRAY_VAR (size_t, expand_mechanisms_per_heap)
+GC_DAC_ARRAY_VAR (size_t, interesting_mechanism_bits_per_heap)
+
+#undef GC_DAC_VAR
+#undef GC_DAC_ARRAY_VAR
+#undef GC_DAC_PTR_VAR
diff --git a/src/gc/gcinterface.ee.h b/src/gc/gcinterface.ee.h
index 7c0eea2d95..7b868e780e 100644
--- a/src/gc/gcinterface.ee.h
+++ b/src/gc/gcinterface.ee.h
@@ -133,6 +133,39 @@ public:
// be finalized.
virtual
void EnableFinalization(bool foundFinalizers) = 0;
+
+ // Signals to the EE that the GC encountered a fatal error and can't recover.
+ virtual
+ void HandleFatalError(unsigned int exitCode) = 0;
+
+ // Asks the EE if it wants a particular object to be finalized when unloading
+ // an app domain.
+ virtual
+ bool ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj) = 0;
+
+ // Offers the EE the option to finalize the given object eagerly, i.e.
+ // not on the finalizer thread but on the current thread. The
+ // EE returns true if it finalized the object eagerly and the GC does not
+ // need to do so, and false if it chose not to eagerly finalize the object
+ // and it's up to the GC to finalize it later.
+ virtual
+ bool EagerFinalized(Object* obj) = 0;
+
+ // Asks the EE if it wishes for the current GC to be a blocking GC. The GC will
+ // only invoke this callback when it intends to do a full GC, so at this point
+ // the EE can opt to elevate that collection to be a blocking GC and not a background one.
+ virtual
+ bool ForceFullGCToBeBlocking() = 0;
+
+ // Retrieves the method table for the free object, a special kind of object used by the GC
+ // to keep the heap traversable. Conceptually, the free object is similar to a managed array
+ // of bytes: it consists of an object header (like all objects) and a "numComponents" field,
+ // followed by some number of bytes of space that's free on the heap.
+ //
+ // The free object allows the GC to traverse the heap because it can inspect the numComponents
+ // field to see how many bytes to skip before the next object on a heap segment begins.
+ virtual
+ MethodTable* GetFreeObjectMethodTable() = 0;
};
#endif // _GCINTERFACE_EE_H_
diff --git a/src/gc/gcinterface.h b/src/gc/gcinterface.h
index 99d79df633..cac2ba7114 100644
--- a/src/gc/gcinterface.h
+++ b/src/gc/gcinterface.h
@@ -77,6 +77,10 @@ struct WriteBarrierParameters
// card table. Used for WriteBarrierOp::Initialize and WriteBarrierOp::StompResize.
uint32_t* card_table;
+ // The new card bundle table location. May or may not be the same as the previous
+ // card bundle table. Used for WriteBarrierOp::Initialize and WriteBarrierOp::StompResize.
+ uint32_t* card_bundle_table;
+
// The heap's new low boundary. May or may not be the same as the previous
// value. Used for WriteBarrierOp::Initialize and WriteBarrierOp::StompResize.
uint8_t* lowest_address;
@@ -98,6 +102,11 @@ struct WriteBarrierParameters
uint8_t* write_watch_table;
};
+ /*
+ * Scanning callback.
+ */
+typedef void (CALLBACK *HANDLESCANPROC)(PTR_UNCHECKED_OBJECTREF pref, uintptr_t *pExtraInfo, uintptr_t param1, uintptr_t param2);
+
#include "gcinterface.ee.h"
// The allocation context must be known to the VM for use in the allocation
@@ -129,6 +138,8 @@ public:
}
};
+#include "gcinterface.dac.h"
+
// stub type to abstract a heap segment
struct gc_heap_segment_stub;
typedef gc_heap_segment_stub *segment_handle;
@@ -138,7 +149,7 @@ struct segment_info
void * pvMem; // base of the allocation, not the first object (must add ibFirstObject)
size_t ibFirstObject; // offset to the base of the first object in the segment
size_t ibAllocated; // limit of allocated memory in the segment (>= firstobject)
- size_t ibCommit; // limit of committed memory in the segment (>= alllocated)
+ size_t ibCommit; // limit of committed memory in the segment (>= allocated)
size_t ibReserved; // limit of reserved memory in the segment (>= commit)
};
@@ -152,18 +163,18 @@ struct segment_info
// one for the object header, and one for the first field in the object.
#define min_obj_size ((sizeof(uint8_t*) + sizeof(uintptr_t) + sizeof(size_t)))
-#define max_generation 2
-
// The bit shift used to convert a memory address into an index into the
// Software Write Watch table.
#define SOFTWARE_WRITE_WATCH_AddressToTableByteIndexShift 0xc
class Object;
class IGCHeap;
+class IGCHandleTable;
// Initializes the garbage collector. Should only be called
-// once, during EE startup.
-IGCHeap* InitializeGarbageCollector(IGCToCLR* clrToGC);
+// once, during EE startup. Returns true if the initialization
+// was successful, false otherwise.
+bool InitializeGarbageCollector(IGCToCLR* clrToGC, IGCHeap** gcHeap, IGCHandleTable** gcHandleTable, GcDacVars* gcDacVars);
// The runtime needs to know whether we're using workstation or server GC
// long before the GCHeap is created. This function sets the type of
@@ -182,8 +193,6 @@ extern uint8_t* g_shadow_lowest_address;
// For low memory notification from host
extern int32_t g_bLowMemoryFromHost;
-extern VOLATILE(int32_t) m_GCLock;
-
// !!!!!!!!!!!!!!!!!!!!!!!
// make sure you change the def in bcl\system\gc.cs
// if you change this!
@@ -229,12 +238,207 @@ enum end_no_gc_region_status
end_no_gc_alloc_exceeded = 3
};
-typedef BOOL (* walk_fn)(Object*, void*);
+typedef enum
+{
+ /*
+ * WEAK HANDLES
+ *
+ * Weak handles are handles that track an object as long as it is alive,
+ * but do not keep the object alive if there are no strong references to it.
+ *
+ */
+
+ /*
+ * SHORT-LIVED WEAK HANDLES
+ *
+ * Short-lived weak handles are weak handles that track an object until the
+ * first time it is detected to be unreachable. At this point, the handle is
+ * severed, even if the object will be visible from a pending finalization
+ * graph. This further implies that short weak handles do not track
+ * across object resurrections.
+ *
+ */
+ HNDTYPE_WEAK_SHORT = 0,
+
+ /*
+ * LONG-LIVED WEAK HANDLES
+ *
+ * Long-lived weak handles are weak handles that track an object until the
+ * object is actually reclaimed. Unlike short weak handles, long weak handles
+ * continue to track their referents through finalization and across any
+ * resurrections that may occur.
+ *
+ */
+ HNDTYPE_WEAK_LONG = 1,
+ HNDTYPE_WEAK_DEFAULT = 1,
+
+ /*
+ * STRONG HANDLES
+ *
+ * Strong handles are handles which function like a normal object reference.
+ * The existence of a strong handle for an object will cause the object to
+ * be promoted (remain alive) through a garbage collection cycle.
+ *
+ */
+ HNDTYPE_STRONG = 2,
+ HNDTYPE_DEFAULT = 2,
+
+ /*
+ * PINNED HANDLES
+ *
+ * Pinned handles are strong handles which have the added property that they
+ * prevent an object from moving during a garbage collection cycle. This is
+ * useful when passing a pointer to object innards out of the runtime while GC
+ * may be enabled.
+ *
+ * NOTE: PINNING AN OBJECT IS EXPENSIVE AS IT PREVENTS THE GC FROM ACHIEVING
+ * OPTIMAL PACKING OF OBJECTS DURING EPHEMERAL COLLECTIONS. THIS TYPE
+ * OF HANDLE SHOULD BE USED SPARINGLY!
+ */
+ HNDTYPE_PINNED = 3,
+
+ /*
+ * VARIABLE HANDLES
+ *
+ * Variable handles are handles whose type can be changed dynamically. They
+ * are larger than other types of handles, and are scanned a little more often,
+ * but are useful when the handle owner needs an efficient way to change the
+ * strength of a handle on the fly.
+ *
+ */
+ HNDTYPE_VARIABLE = 4,
+
+ /*
+ * REFCOUNTED HANDLES
+ *
+ * Refcounted handles are handles that behave as strong handles while the
+ * refcount on them is greater than 0 and behave as weak handles otherwise.
+ *
+ * N.B. These are currently NOT general purpose.
+ * The implementation is tied to COM Interop.
+ *
+ */
+ HNDTYPE_REFCOUNTED = 5,
+
+ /*
+ * DEPENDENT HANDLES
+ *
+ * Dependent handles are two handles that need to have the same lifetime. One handle refers to a secondary object
+ * that needs to have the same lifetime as the primary object. The secondary object should not cause the primary
+ * object to be referenced, but as long as the primary object is alive, so must be the secondary
+ *
+ * They are currently used for EnC for adding new field members to existing instantiations under EnC modes where
+ * the primary object is the original instantiation and the secondary represents the added field.
+ *
+ * They are also used to implement the ConditionalWeakTable class in mscorlib.dll. If you want to use
+ * these from managed code, they are exposed to BCL through the managed DependentHandle class.
+ *
+ *
+ */
+ HNDTYPE_DEPENDENT = 6,
+
+ /*
+ * PINNED HANDLES for asynchronous operation
+ *
+ * Pinned handles are strong handles which have the added property that they
+ * prevent an object from moving during a garbage collection cycle. This is
+ * useful when passing a pointer to object innards out of the runtime while GC
+ * may be enabled.
+ *
+ * NOTE: PINNING AN OBJECT IS EXPENSIVE AS IT PREVENTS THE GC FROM ACHIEVING
+ * OPTIMAL PACKING OF OBJECTS DURING EPHEMERAL COLLECTIONS. THIS TYPE
+ * OF HANDLE SHOULD BE USED SPARINGLY!
+ */
+ HNDTYPE_ASYNCPINNED = 7,
+
+ /*
+ * SIZEDREF HANDLES
+ *
+ * SizedRef handles are strong handles. Each handle has a piece of user data associated
+ * with it that stores the size of the object this handle refers to. These handles
+ * are scanned as strong roots during each GC but only during full GCs would the size
+ * be calculated.
+ *
+ */
+ HNDTYPE_SIZEDREF = 8,
+
+ /*
+ * WINRT WEAK HANDLES
+ *
+ * WinRT weak reference handles hold two different types of weak handles to any
+ * RCW with an underlying COM object that implements IWeakReferenceSource. The
+ * object reference itself is a short weak handle to the RCW. In addition an
+ * IWeakReference* to the underlying COM object is stored, allowing the handle
+ * to create a new RCW if the existing RCW is collected. This ensures that any
+ * code holding onto a WinRT weak reference can always access an RCW to the
+ * underlying COM object as long as it has not been released by all of its strong
+ * references.
+ */
+ HNDTYPE_WEAK_WINRT = 9
+} HandleType;
+
+typedef enum
+{
+ GC_HEAP_INVALID = 0,
+ GC_HEAP_WKS = 1,
+ GC_HEAP_SVR = 2
+} GCHeapType;
+
+typedef bool (* walk_fn)(Object*, void*);
typedef void (* gen_walk_fn)(void* context, int generation, uint8_t* range_start, uint8_t* range_end, uint8_t* range_reserved);
-typedef void (* record_surv_fn)(uint8_t* begin, uint8_t* end, ptrdiff_t reloc, size_t context, BOOL compacting_p, BOOL bgc_p);
-typedef void (* fq_walk_fn)(BOOL, void*);
+typedef void (* record_surv_fn)(uint8_t* begin, uint8_t* end, ptrdiff_t reloc, void* context, bool compacting_p, bool bgc_p);
+typedef void (* fq_walk_fn)(bool, void*);
typedef void (* fq_scan_fn)(Object** ppObject, ScanContext *pSC, uint32_t dwFlags);
-typedef void (* handle_scan_fn)(Object** pRef, Object* pSec, uint32_t flags, ScanContext* context, BOOL isDependent);
+typedef void (* handle_scan_fn)(Object** pRef, Object* pSec, uint32_t flags, ScanContext* context, bool isDependent);
+
+// Opaque type for tracking object pointers
+#ifndef DACCESS_COMPILE
+struct OBJECTHANDLE__
+{
+ void* unused;
+};
+typedef struct OBJECTHANDLE__* OBJECTHANDLE;
+#else
+typedef uintptr_t OBJECTHANDLE;
+#endif
+
+class IGCHandleTable {
+public:
+
+ virtual bool Initialize() = 0;
+
+ virtual void Shutdown() = 0;
+
+ virtual void* GetHandleContext(OBJECTHANDLE handle) = 0;
+
+ virtual void* GetGlobalHandleStore() = 0;
+
+ virtual void* CreateHandleStore(void* context) = 0;
+
+ virtual void DestroyHandleStore(void* store) = 0;
+
+ virtual void UprootHandleStore(void* store) = 0;
+
+ virtual bool ContainsHandle(void* store, OBJECTHANDLE handle) = 0;
+
+ virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type) = 0;
+
+ virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type, int heapToAffinitizeTo) = 0;
+
+ virtual OBJECTHANDLE CreateHandleWithExtraInfo(void* store, Object* object, int type, void* pExtraInfo) = 0;
+
+ virtual OBJECTHANDLE CreateDependentHandle(void* store, Object* primary, Object* secondary) = 0;
+
+ virtual OBJECTHANDLE CreateGlobalHandleOfType(Object* object, int type) = 0;
+
+ virtual OBJECTHANDLE CreateDuplicateHandle(OBJECTHANDLE handle) = 0;
+
+ virtual void DestroyHandleOfType(OBJECTHANDLE handle, int type) = 0;
+
+ virtual void DestroyHandleOfUnknownType(OBJECTHANDLE handle) = 0;
+
+ virtual void* GetExtraInfoFromHandle(OBJECTHANDLE handle) = 0;
+};
// IGCHeap is the interface that the VM will use when interacting with the GC.
class IGCHeap {
@@ -249,13 +453,13 @@ public:
*/
// Returns whether or not the given size is a valid segment size.
- virtual BOOL IsValidSegmentSize(size_t size) = 0;
+ virtual bool IsValidSegmentSize(size_t size) = 0;
// Returns whether or not the given size is a valid gen 0 max size.
- virtual BOOL IsValidGen0MaxSize(size_t size) = 0;
+ virtual bool IsValidGen0MaxSize(size_t size) = 0;
// Gets a valid segment size.
- virtual size_t GetValidSegmentSize(BOOL large_seg = FALSE) = 0;
+ virtual size_t GetValidSegmentSize(bool large_seg = false) = 0;
// Sets the limit for reserved virtual memory.
virtual void SetReservedVMLimit(size_t vmlimit) = 0;
@@ -275,7 +479,7 @@ public:
virtual void WaitUntilConcurrentGCComplete() = 0;
// Returns true if a concurrent GC is in progress, false otherwise.
- virtual BOOL IsConcurrentGCInProgress() = 0;
+ virtual bool IsConcurrentGCInProgress() = 0;
// Temporarily enables concurrent GC, used during profiling.
virtual void TemporaryEnableConcurrentGC() = 0;
@@ -284,7 +488,7 @@ public:
virtual void TemporaryDisableConcurrentGC() = 0;
// Returns whether or not Concurrent GC is enabled.
- virtual BOOL IsConcurrentGCEnabled() = 0;
+ virtual bool IsConcurrentGCEnabled() = 0;
// Wait for a concurrent GC to complete if one is in progress, with the given timeout.
virtual HRESULT WaitUntilConcurrentGCCompleteAsync(int millisecondsTimeout) = 0; // Use in native threads. TRUE if succeed. FALSE if failed or timeout
@@ -298,17 +502,17 @@ public:
*/
// Finalizes an app domain by finalizing objects within that app domain.
- virtual BOOL FinalizeAppDomain(AppDomain* pDomain, BOOL fRunFinalizers) = 0;
+ virtual bool FinalizeAppDomain(AppDomain* pDomain, bool fRunFinalizers) = 0;
// Finalizes all registered objects for shutdown, even if they are still reachable.
- virtual void SetFinalizeQueueForShutdown(BOOL fHasLock) = 0;
+ virtual void SetFinalizeQueueForShutdown(bool fHasLock) = 0;
// Gets the number of finalizable objects.
virtual size_t GetNumberOfFinalizable() = 0;
// Traditionally used by the finalizer thread on shutdown to determine
// whether or not to time out. Returns true if the GC lock has not been taken.
- virtual BOOL ShouldRestartFinalizerWatchDog() = 0;
+ virtual bool ShouldRestartFinalizerWatchDog() = 0;
// Gets the next finalizable object.
virtual Object* GetNextFinalizable() = 0;
@@ -341,10 +545,10 @@ public:
// Registers for a full GC notification, raising a notification if the gen 2 or
// LOH object heap thresholds are exceeded.
- virtual BOOL RegisterForFullGCNotification(uint32_t gen2Percentage, uint32_t lohPercentage) = 0;
+ virtual bool RegisterForFullGCNotification(uint32_t gen2Percentage, uint32_t lohPercentage) = 0;
// Cancels a full GC notification that was requested by `RegisterForFullGCNotification`.
- virtual BOOL CancelFullGCNotification() = 0;
+ virtual bool CancelFullGCNotification() = 0;
// Returns the status of a registered notification for determining whether a blocking
// Gen 2 collection is about to be initiated, with the given timeout.
@@ -365,7 +569,7 @@ public:
// Begins a no-GC region, returning a code indicating whether entering the no-GC
// region was successful.
- virtual int StartNoGCRegion(uint64_t totalSize, BOOL lohSizeKnown, uint64_t lohSize, BOOL disallowFullBlockingGC) = 0;
+ virtual int StartNoGCRegion(uint64_t totalSize, bool lohSizeKnown, uint64_t lohSize, bool disallowFullBlockingGC) = 0;
// Exits a no-GC region.
virtual int EndNoGCRegion() = 0;
@@ -375,7 +579,7 @@ public:
// Forces a garbage collection of the given generation. Also used extensively
// throughout the VM.
- virtual HRESULT GarbageCollect(int generation = -1, BOOL low_memory_p = FALSE, int mode = collection_blocking) = 0;
+ virtual HRESULT GarbageCollect(int generation = -1, bool low_memory_p = false, int mode = collection_blocking) = 0;
// Gets the largest GC generation. Also used extensively throughout the VM.
virtual unsigned GetMaxGeneration() = 0;
@@ -397,16 +601,16 @@ public:
virtual HRESULT Initialize() = 0;
// Returns whether nor this GC was promoted by the last GC.
- virtual BOOL IsPromoted(Object* object) = 0;
+ virtual bool IsPromoted(Object* object) = 0;
// Returns true if this pointer points into a GC heap, false otherwise.
- virtual BOOL IsHeapPointer(void* object, BOOL small_heap_only = FALSE) = 0;
+ virtual bool IsHeapPointer(void* object, bool small_heap_only = false) = 0;
// Return the generation that has been condemned by the current GC.
virtual unsigned GetCondemnedGeneration() = 0;
// Returns whether or not a GC is in progress.
- virtual BOOL IsGCInProgressHelper(BOOL bConsiderGCStart = FALSE) = 0;
+ virtual bool IsGCInProgressHelper(bool bConsiderGCStart = false) = 0;
// Returns the number of GCs that have occured. Mainly used for
// sanity checks asserting that a GC has not occured.
@@ -417,20 +621,23 @@ public:
virtual bool IsThreadUsingAllocationContextHeap(gc_alloc_context* acontext, int thread_number) = 0;
// Returns whether or not this object resides in an ephemeral generation.
- virtual BOOL IsEphemeral(Object* object) = 0;
+ virtual bool IsEphemeral(Object* object) = 0;
// Blocks until a GC is complete, returning a code indicating the wait was successful.
- virtual uint32_t WaitUntilGCComplete(BOOL bConsiderGCStart = FALSE) = 0;
+ virtual uint32_t WaitUntilGCComplete(bool bConsiderGCStart = false) = 0;
// "Fixes" an allocation context by binding its allocation pointer to a
// location on the heap.
- virtual void FixAllocContext(gc_alloc_context* acontext, BOOL lockp, void* arg, void* heap) = 0;
+ virtual void FixAllocContext(gc_alloc_context* acontext, bool lockp, void* arg, void* heap) = 0;
// Gets the total survived size plus the total allocated bytes on the heap.
virtual size_t GetCurrentObjSize() = 0;
// Sets whether or not a GC is in progress.
- virtual void SetGCInProgress(BOOL fInProgress) = 0;
+ virtual void SetGCInProgress(bool fInProgress) = 0;
+
+ // Gets whether or not the GC runtime structures are in a valid state for heap traversal.
+ virtual bool RuntimeStructuresValid() = 0;
/*
============================================================================
@@ -459,21 +666,22 @@ public:
*/
// Allocates an object on the given allocation context with the given size and flags.
+ // It is the responsibility of the caller to ensure that the passed-in alloc context is
+ // owned by the thread that is calling this function. If using per-thread alloc contexts,
+ // no lock is needed; callers not using per-thread alloc contexts will need to acquire
+ // a lock to ensure that the calling thread has unique ownership over this alloc context;
virtual Object* Alloc(gc_alloc_context* acontext, size_t size, uint32_t flags) = 0;
- // Allocates an object on the default allocation context with the given size and flags.
- virtual Object* Alloc(size_t size, uint32_t flags) = 0;
-
// Allocates an object on the large object heap with the given size and flags.
virtual Object* AllocLHeap(size_t size, uint32_t flags) = 0;
- // Allocates an object on the default allocation context, aligned to 64 bits,
- // with the given size and flags.
- virtual Object* AllocAlign8 (size_t size, uint32_t flags) = 0;
-
// Allocates an object on the given allocation context, aligned to 64 bits,
// with the given size and flags.
- virtual Object* AllocAlign8 (gc_alloc_context* acontext, size_t size, uint32_t flags) = 0;
+ // It is the responsibility of the caller to ensure that the passed-in alloc context is
+ // owned by the thread that is calling this function. If using per-thread alloc contexts,
+ // no lock is needed; callers not using per-thread alloc contexts will need to acquire
+ // a lock to ensure that the calling thread has unique ownership over this alloc context.
+ virtual Object* AllocAlign8(gc_alloc_context* acontext, size_t size, uint32_t flags) = 0;
// This is for the allocator to indicate it's done allocating a large object during a
// background GC as the BGC threads also need to walk LOH.
@@ -489,7 +697,7 @@ public:
===========================================================================
*/
// Returns whether or not this object is in the fixed heap.
- virtual BOOL IsObjectInFixedHeap(Object* pObj) = 0;
+ virtual bool IsObjectInFixedHeap(Object* pObj) = 0;
// Walks an object and validates its members.
virtual void ValidateObjectMember(Object* obj) = 0;
@@ -501,7 +709,9 @@ public:
// Given an interior pointer, return a pointer to the object
// containing that pointer. This is safe to call only when the EE is suspended.
- virtual Object* GetContainingObject(void* pInteriorPtr) = 0;
+ // When fCollectedGenOnly is true, it only returns the object if it's found in
+ // the generation(s) that are being collected.
+ virtual Object* GetContainingObject(void* pInteriorPtr, bool fCollectedGenOnly) = 0;
/*
===========================================================================
@@ -514,10 +724,10 @@ public:
virtual void DiagWalkObject(Object* obj, walk_fn fn, void* context) = 0;
// Walk the heap object by object.
- virtual void DiagWalkHeap(walk_fn fn, void* context, int gen_number, BOOL walk_large_object_heap_p) = 0;
+ virtual void DiagWalkHeap(walk_fn fn, void* context, int gen_number, bool walk_large_object_heap_p) = 0;
// Walks the survivors and get the relocation information if objects have moved.
- virtual void DiagWalkSurvivorsWithType(void* gc_context, record_surv_fn fn, size_t diag_context, walk_surv_type type) = 0;
+ virtual void DiagWalkSurvivorsWithType(void* gc_context, record_surv_fn fn, void* diag_context, walk_surv_type type) = 0;
// Walks the finalization queue.
virtual void DiagWalkFinalizeQueue(void* gc_context, fq_walk_fn fn) = 0;
@@ -543,8 +753,9 @@ public:
===========================================================================
*/
- // Returns TRUE if GC actually happens, otherwise FALSE
- virtual BOOL StressHeap(gc_alloc_context* acontext = 0) = 0;
+ // Returns TRUE if GC actually happens, otherwise FALSE. The passed alloc context
+ // must not be null.
+ virtual bool StressHeap(gc_alloc_context* acontext) = 0;
/*
===========================================================================
@@ -561,19 +772,6 @@ public:
IGCHeap() {}
virtual ~IGCHeap() {}
-
- typedef enum
- {
- GC_HEAP_INVALID = 0,
- GC_HEAP_WKS = 1,
- GC_HEAP_SVR = 2
- } GC_HEAP_TYPE;
-
-#ifdef FEATURE_SVR_GC
- SVAL_DECL(uint32_t, gcHeapType);
-#endif
-
- SVAL_DECL(uint32_t, maxGeneration);
};
#ifdef WRITE_BARRIER_CHECK
@@ -597,8 +795,8 @@ struct ScanContext
Thread* thread_under_crawl;
int thread_number;
uintptr_t stack_limit; // Lowest point on the thread stack that the scanning logic is permitted to read
- BOOL promotion; //TRUE: Promotion, FALSE: Relocation.
- BOOL concurrent; //TRUE: concurrent scanning
+ bool promotion; //TRUE: Promotion, FALSE: Relocation.
+ bool concurrent; //TRUE: concurrent scanning
#if CHECK_APP_DOMAIN_LEAKS || defined (FEATURE_APPDOMAIN_RESOURCE_MONITORING) || defined (DACCESS_COMPILE)
AppDomain *pCurrentDomain;
#endif //CHECK_APP_DOMAIN_LEAKS || FEATURE_APPDOMAIN_RESOURCE_MONITORING || DACCESS_COMPILE
@@ -619,8 +817,8 @@ struct ScanContext
thread_under_crawl = 0;
thread_number = -1;
stack_limit = 0;
- promotion = FALSE;
- concurrent = FALSE;
+ promotion = false;
+ concurrent = false;
#ifdef GC_PROFILING
pMD = NULL;
#endif //GC_PROFILING
diff --git a/src/gc/gcpriv.h b/src/gc/gcpriv.h
index 1f97d7f2d5..108045cd37 100644
--- a/src/gc/gcpriv.h
+++ b/src/gc/gcpriv.h
@@ -28,7 +28,7 @@ inline void FATAL_GC_ERROR()
GCToOSInterface::DebugBreak();
#endif // DACCESS_COMPILE
_ASSERTE(!"Fatal Error in GC.");
- EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
+ GCToEEInterface::HandleFatalError(COR_E_EXECUTIONENGINE);
}
#ifdef _MSC_VER
@@ -167,8 +167,6 @@ void GCLogConfig (const char *fmt, ... );
#define TRACE_GC
#endif
-#define NUMBERGENERATIONS 4 //Max number of generations
-
// For the bestfit algorithm when we relocate ephemeral generations into an
// existing gen2 segment.
// We recorded sizes from 2^6, 2^7, 2^8...up to 2^30 (1GB). So that's 25 sizes total.
@@ -759,10 +757,10 @@ public:
// Don't move these first two fields without adjusting the references
// from the __asm in jitinterface.cpp.
alloc_context allocation_context;
- heap_segment* allocation_segment;
PTR_heap_segment start_segment;
- uint8_t* allocation_context_start_region;
uint8_t* allocation_start;
+ heap_segment* allocation_segment;
+ uint8_t* allocation_context_start_region;
allocator free_list_allocator;
size_t free_list_allocated;
size_t end_seg_allocated;
@@ -792,6 +790,11 @@ public:
#endif //FREE_USAGE_STATS
};
+static_assert(offsetof(dac_generation, allocation_context) == offsetof(generation, allocation_context), "DAC generation offset mismatch");
+static_assert(offsetof(dac_generation, start_segment) == offsetof(generation, start_segment), "DAC generation offset mismatch");
+static_assert(offsetof(dac_generation, allocation_start) == offsetof(generation, allocation_start), "DAC generation offset mismatch");
+
+
// The dynamic data fields are grouped into 3 categories:
//
// calculated logical data (like desired_allocation)
@@ -1104,6 +1107,8 @@ class gc_heap
friend void initGCShadow();
#endif //defined (WRITE_BARRIER_CHECK) && !defined (SERVER_GC)
+ friend void PopulateDacVars(GcDacVars *gcDacVars);
+
#ifdef MULTIPLE_HEAPS
typedef void (gc_heap::* card_fn) (uint8_t**, int);
#define call_fn(fn) (this->*fn)
@@ -1293,19 +1298,19 @@ protected:
uint8_t* last_plug;
BOOL is_shortened;
mark* pinned_plug_entry;
- size_t profiling_context;
+ void* profiling_context;
record_surv_fn fn;
};
PER_HEAP
- void walk_survivors (record_surv_fn fn, size_t context, walk_surv_type type);
+ void walk_survivors (record_surv_fn fn, void* context, walk_surv_type type);
PER_HEAP
void walk_plug (uint8_t* plug, size_t size, BOOL check_last_object_p,
walk_relocate_args* args);
PER_HEAP
- void walk_relocation (size_t profiling_context, record_surv_fn fn);
+ void walk_relocation (void* profiling_context, record_surv_fn fn);
PER_HEAP
void walk_relocation_in_brick (uint8_t* tree, walk_relocate_args* args);
@@ -1315,14 +1320,14 @@ protected:
#if defined(BACKGROUND_GC) && defined(FEATURE_EVENT_TRACE)
PER_HEAP
- void walk_survivors_for_bgc (size_t profiling_context, record_surv_fn fn);
+ void walk_survivors_for_bgc (void* profiling_context, record_surv_fn fn);
#endif // defined(BACKGROUND_GC) && defined(FEATURE_EVENT_TRACE)
// used in blocking GCs after plan phase so this walks the plugs.
PER_HEAP
- void walk_survivors_relocation (size_t profiling_context, record_surv_fn fn);
+ void walk_survivors_relocation (void* profiling_context, record_surv_fn fn);
PER_HEAP
- void walk_survivors_for_loh (size_t profiling_context, record_surv_fn fn);
+ void walk_survivors_for_loh (void* profiling_context, record_surv_fn fn);
PER_HEAP
int generation_to_condemn (int n,
@@ -1390,6 +1395,9 @@ protected:
void thread_no_gc_loh_segments();
PER_HEAP
+ void check_and_set_no_gc_oom();
+
+ PER_HEAP
void allocate_for_no_gc_after_gc();
PER_HEAP
@@ -1550,13 +1558,6 @@ protected:
alloc_context* acontext,
int align_const);
- enum c_gc_state
- {
- c_gc_state_marking,
- c_gc_state_planning,
- c_gc_state_free
- };
-
#ifdef RECORD_LOH_STATE
#define max_saved_loh_states 12
PER_HEAP
@@ -1718,8 +1719,14 @@ protected:
PER_HEAP
void card_bundle_clear(size_t cardb);
PER_HEAP
+ void card_bundle_set (size_t cardb);
+ PER_HEAP
void card_bundles_set (size_t start_cardb, size_t end_cardb);
PER_HEAP
+ void verify_card_bundle_bits_set(size_t first_card_word, size_t last_card_word);
+ PER_HEAP
+ void verify_card_bundles();
+ PER_HEAP
BOOL card_bundle_set_p (size_t cardb);
PER_HEAP
BOOL find_card_dword (size_t& cardw, size_t cardw_end);
@@ -2161,7 +2168,7 @@ protected:
void relocate_in_loh_compact();
PER_HEAP
- void walk_relocation_for_loh (size_t profiling_context, record_surv_fn fn);
+ void walk_relocation_for_loh (void* profiling_context, record_surv_fn fn);
PER_HEAP
BOOL loh_enque_pinned_plug (uint8_t* plug, size_t len);
@@ -2753,9 +2760,6 @@ public:
PER_HEAP_ISOLATED
uint32_t cm_in_progress;
- PER_HEAP
- BOOL expanded_in_fgc;
-
// normally this is FALSE; we set it to TRUE at the end of the gen1 GC
// we do right before the bgc starts.
PER_HEAP_ISOLATED
@@ -2765,6 +2769,56 @@ public:
CLREvent bgc_start_event;
#endif //BACKGROUND_GC
+ // The variables in this block are known to the DAC and must come first
+ // in the gc_heap class.
+
+ // Keeps track of the highest address allocated by Alloc
+ PER_HEAP
+ uint8_t* alloc_allocated;
+
+ // The ephemeral heap segment
+ PER_HEAP
+ heap_segment* ephemeral_heap_segment;
+
+ // The finalize queue.
+ PER_HEAP
+ CFinalize* finalize_queue;
+
+ // OOM info.
+ PER_HEAP
+ oom_history oom_info;
+
+ // Interesting data, recorded per-heap.
+ PER_HEAP
+ size_t interesting_data_per_heap[max_idp_count];
+
+ PER_HEAP
+ size_t compact_reasons_per_heap[max_compact_reasons_count];
+
+ PER_HEAP
+ size_t expand_mechanisms_per_heap[max_expand_mechanisms_count];
+
+ PER_HEAP
+ size_t interesting_mechanism_bits_per_heap[max_gc_mechanism_bits_count];
+
+ PER_HEAP
+ uint8_t** internal_root_array;
+
+ PER_HEAP
+ size_t internal_root_array_index;
+
+ PER_HEAP
+ BOOL heap_analyze_success;
+
+ // The generation table. Must always be last.
+ PER_HEAP
+ generation generation_table [NUMBERGENERATIONS + 1];
+
+ // End DAC zone
+
+ PER_HEAP
+ BOOL expanded_in_fgc;
+
PER_HEAP_ISOLATED
uint32_t wait_for_gc_done(int32_t timeOut = INFINITE);
@@ -2815,12 +2869,8 @@ public:
short* brick_table;
#ifdef MARK_ARRAY
-#ifdef MULTIPLE_HEAPS
PER_HEAP
uint32_t* mark_array;
-#else
- SPTR_DECL(uint32_t, mark_array);
-#endif //MULTIPLE_HEAPS
#endif //MARK_ARRAY
#ifdef CARD_BUNDLE
@@ -2984,13 +3034,6 @@ protected:
#define heap_number (0)
#endif //MULTIPLE_HEAPS
-#ifndef MULTIPLE_HEAPS
- SPTR_DECL(heap_segment,ephemeral_heap_segment);
-#else
- PER_HEAP
- heap_segment* ephemeral_heap_segment;
-#endif // !MULTIPLE_HEAPS
-
PER_HEAP
size_t time_bgc_last;
@@ -3065,14 +3108,9 @@ protected:
uint8_t* background_written_addresses [array_size+2];
#endif //WRITE_WATCH
-#if defined (DACCESS_COMPILE) && !defined (MULTIPLE_HEAPS)
- // doesn't need to be volatile for DAC.
- SVAL_DECL(c_gc_state, current_c_gc_state);
-#else
PER_HEAP_ISOLATED
VOLATILE(c_gc_state) current_c_gc_state; //tells the large object allocator to
//mark the object as new since the start of gc.
-#endif //DACCESS_COMPILE && !MULTIPLE_HEAPS
PER_HEAP_ISOLATED
gc_mechanisms saved_bgc_settings;
@@ -3229,16 +3267,6 @@ protected:
PER_HEAP
heap_segment* saved_overflow_ephemeral_seg;
-#ifndef MULTIPLE_HEAPS
- SPTR_DECL(heap_segment, saved_sweep_ephemeral_seg);
-
- SPTR_DECL(uint8_t, saved_sweep_ephemeral_start);
-
- SPTR_DECL(uint8_t, background_saved_lowest_address);
-
- SPTR_DECL(uint8_t, background_saved_highest_address);
-#else
-
PER_HEAP
heap_segment* saved_sweep_ephemeral_seg;
@@ -3250,7 +3278,6 @@ protected:
PER_HEAP
uint8_t* background_saved_highest_address;
-#endif //!MULTIPLE_HEAPS
// This is used for synchronization between the bgc thread
// for this heap and the user threads allocating on this
@@ -3326,6 +3353,9 @@ protected:
size_t loh_allocation_no_gc;
PER_HEAP
+ bool no_gc_oom_p;
+
+ PER_HEAP
heap_segment* saved_loh_segment_no_gc;
PER_HEAP_ISOLATED
@@ -3334,14 +3364,6 @@ protected:
#define youngest_generation (generation_of (0))
#define large_object_generation (generation_of (max_generation+1))
-#ifndef MULTIPLE_HEAPS
- SPTR_DECL(uint8_t,alloc_allocated);
-#else
- PER_HEAP
- uint8_t* alloc_allocated; //keeps track of the highest
- //address allocated by alloc
-#endif // !MULTIPLE_HEAPS
-
// The more_space_lock and gc_lock is used for 3 purposes:
//
// 1) to coordinate threads that exceed their quantum (UP & MP) (more_space_lock)
@@ -3411,12 +3433,6 @@ protected:
#endif //SYNCHRONIZATION_STATS
-#ifdef MULTIPLE_HEAPS
- PER_HEAP
- generation generation_table [NUMBERGENERATIONS+1];
-#endif
-
-
#define NUM_LOH_ALIST (7)
#define BASE_LOH_ALIST (64*1024)
PER_HEAP
@@ -3493,34 +3509,14 @@ protected:
PER_HEAP_ISOLATED
BOOL alloc_wait_event_p;
-#ifndef MULTIPLE_HEAPS
- SPTR_DECL(uint8_t, next_sweep_obj);
-#else
PER_HEAP
uint8_t* next_sweep_obj;
-#endif //MULTIPLE_HEAPS
PER_HEAP
uint8_t* current_sweep_pos;
#endif //BACKGROUND_GC
-#ifndef MULTIPLE_HEAPS
- SVAL_DECL(oom_history, oom_info);
-#ifdef FEATURE_PREMORTEM_FINALIZATION
- SPTR_DECL(CFinalize,finalize_queue);
-#endif //FEATURE_PREMORTEM_FINALIZATION
-#else
-
- PER_HEAP
- oom_history oom_info;
-
-#ifdef FEATURE_PREMORTEM_FINALIZATION
- PER_HEAP
- PTR_CFinalize finalize_queue;
-#endif //FEATURE_PREMORTEM_FINALIZATION
-#endif // !MULTIPLE_HEAPS
-
PER_HEAP
fgm_history fgm_result;
@@ -3542,19 +3538,6 @@ protected:
PER_HEAP
size_t interesting_data_per_gc[max_idp_count];
-#ifdef MULTIPLE_HEAPS
- PER_HEAP
- size_t interesting_data_per_heap[max_idp_count];
-
- PER_HEAP
- size_t compact_reasons_per_heap[max_compact_reasons_count];
-
- PER_HEAP
- size_t expand_mechanisms_per_heap[max_expand_mechanisms_count];
-
- PER_HEAP
- size_t interesting_mechanism_bits_per_heap[max_gc_mechanism_bits_count];
-#endif //MULTIPLE_HEAPS
#endif //GC_CONFIG_DRIVEN
PER_HEAP
@@ -3635,21 +3618,6 @@ public:
PER_HEAP
size_t internal_root_array_length;
-#ifndef MULTIPLE_HEAPS
- SPTR_DECL(PTR_uint8_t, internal_root_array);
- SVAL_DECL(size_t, internal_root_array_index);
- SVAL_DECL(BOOL, heap_analyze_success);
-#else
- PER_HEAP
- uint8_t** internal_root_array;
-
- PER_HEAP
- size_t internal_root_array_index;
-
- PER_HEAP
- BOOL heap_analyze_success;
-#endif // !MULTIPLE_HEAPS
-
// next two fields are used to optimize the search for the object
// enclosing the current reference handled by ha_mark_object_simple.
PER_HEAP
@@ -3670,8 +3638,11 @@ public:
BOOL blocking_collection;
#ifdef MULTIPLE_HEAPS
- SVAL_DECL(int, n_heaps);
- SPTR_DECL(PTR_gc_heap, g_heaps);
+ static
+ int n_heaps;
+
+ static
+ gc_heap** g_heaps;
static
size_t* g_promoted;
@@ -3705,6 +3676,23 @@ protected:
}; // class gc_heap
+#define ASSERT_OFFSETS_MATCH(field) \
+ static_assert_no_msg(offsetof(dac_gc_heap, field) == offsetof(gc_heap, field))
+
+#ifdef MULTIPLE_HEAPS
+ASSERT_OFFSETS_MATCH(alloc_allocated);
+ASSERT_OFFSETS_MATCH(ephemeral_heap_segment);
+ASSERT_OFFSETS_MATCH(finalize_queue);
+ASSERT_OFFSETS_MATCH(oom_info);
+ASSERT_OFFSETS_MATCH(interesting_data_per_heap);
+ASSERT_OFFSETS_MATCH(compact_reasons_per_heap);
+ASSERT_OFFSETS_MATCH(expand_mechanisms_per_heap);
+ASSERT_OFFSETS_MATCH(interesting_mechanism_bits_per_heap);
+ASSERT_OFFSETS_MATCH(internal_root_array);
+ASSERT_OFFSETS_MATCH(internal_root_array_index);
+ASSERT_OFFSETS_MATCH(heap_analyze_success);
+ASSERT_OFFSETS_MATCH(generation_table);
+#endif // MULTIPLE_HEAPS
#ifdef FEATURE_PREMORTEM_FINALIZATION
class CFinalize
@@ -3712,6 +3700,9 @@ class CFinalize
#ifdef DACCESS_COMPILE
friend class ::ClrDataAccess;
#endif // DACCESS_COMPILE
+
+ friend class CFinalizeStaticAsserts;
+
private:
//adjust the count and add a constant to add a segment
@@ -3721,8 +3712,8 @@ private:
//Does not correspond to a segment
static const int FreeList = NUMBERGENERATIONS+ExtraSegCount;
- PTR_PTR_Object m_Array;
PTR_PTR_Object m_FillPointers[NUMBERGENERATIONS+ExtraSegCount];
+ PTR_PTR_Object m_Array;
PTR_PTR_Object m_EndArray;
size_t m_PromotedCount;
@@ -3776,10 +3767,18 @@ public:
void DiscardNonCriticalObjects();
//Methods used by the app domain unloading call to finalize objects in an app domain
- BOOL FinalizeAppDomain (AppDomain *pDomain, BOOL fRunFinalizers);
+ bool FinalizeAppDomain (AppDomain *pDomain, bool fRunFinalizers);
void CheckFinalizerObjects();
+
};
+
+class CFinalizeStaticAsserts {
+ static_assert(dac_finalize_queue::ExtraSegCount == CFinalize::ExtraSegCount, "ExtraSegCount mismatch");
+ static_assert(offsetof(dac_finalize_queue, m_FillPointers) == offsetof(CFinalize, m_FillPointers), "CFinalize layout mismatch");
+};
+
+
#endif // FEATURE_PREMORTEM_FINALIZATION
inline
@@ -4171,15 +4170,12 @@ public:
uint8_t* mem;
size_t flags;
PTR_heap_segment next;
- uint8_t* plan_allocated;
-#ifdef BACKGROUND_GC
uint8_t* background_allocated;
- uint8_t* saved_bg_allocated;
-#endif //BACKGROUND_GC
-
#ifdef MULTIPLE_HEAPS
gc_heap* heap;
#endif //MULTIPLE_HEAPS
+ uint8_t* plan_allocated;
+ uint8_t* saved_bg_allocated;
#ifdef _MSC_VER
// Disable this warning - we intentionally want __declspec(align()) to insert padding for us
@@ -4191,6 +4187,18 @@ public:
#endif
};
+static_assert(offsetof(dac_heap_segment, allocated) == offsetof(heap_segment, allocated), "DAC heap segment layout mismatch");
+static_assert(offsetof(dac_heap_segment, committed) == offsetof(heap_segment, committed), "DAC heap segment layout mismatch");
+static_assert(offsetof(dac_heap_segment, reserved) == offsetof(heap_segment, reserved), "DAC heap segment layout mismatch");
+static_assert(offsetof(dac_heap_segment, used) == offsetof(heap_segment, used), "DAC heap segment layout mismatch");
+static_assert(offsetof(dac_heap_segment, mem) == offsetof(heap_segment, mem), "DAC heap segment layout mismatch");
+static_assert(offsetof(dac_heap_segment, flags) == offsetof(heap_segment, flags), "DAC heap segment layout mismatch");
+static_assert(offsetof(dac_heap_segment, next) == offsetof(heap_segment, next), "DAC heap segment layout mismatch");
+static_assert(offsetof(dac_heap_segment, background_allocated) == offsetof(heap_segment, background_allocated), "DAC heap segment layout mismatch");
+#ifdef MULTIPLE_HEAPS
+static_assert(offsetof(dac_heap_segment, heap) == offsetof(heap_segment, heap), "DAC heap segment layout mismatch");
+#endif // MULTIPLE_HEAPS
+
inline
uint8_t*& heap_segment_reserved (heap_segment* inst)
{
@@ -4283,27 +4291,6 @@ gc_heap*& heap_segment_heap (heap_segment* inst)
}
#endif //MULTIPLE_HEAPS
-#ifndef MULTIPLE_HEAPS
-
-#ifndef DACCESS_COMPILE
-extern "C" {
-#endif //!DACCESS_COMPILE
-
-GARY_DECL(generation,generation_table,NUMBERGENERATIONS+1);
-
-#ifdef GC_CONFIG_DRIVEN
-GARY_DECL(size_t, interesting_data_per_heap, max_idp_count);
-GARY_DECL(size_t, compact_reasons_per_heap, max_compact_reasons_count);
-GARY_DECL(size_t, expand_mechanisms_per_heap, max_expand_mechanisms_count);
-GARY_DECL(size_t, interesting_mechanism_bits_per_heap, max_gc_mechanism_bits_count);
-#endif //GC_CONFIG_DRIVEN
-
-#ifndef DACCESS_COMPILE
-}
-#endif //!DACCESS_COMPILE
-
-#endif //MULTIPLE_HEAPS
-
inline
generation* gc_heap::generation_of (int n)
{
@@ -4329,12 +4316,14 @@ dynamic_data* gc_heap::dynamic_data_of (int gen_number)
#define card_size ((size_t)(OS_PAGE_SIZE/card_word_width))
#endif // BIT64
+// Returns the index of the card word a card is in
inline
size_t card_word (size_t card)
{
return card / card_word_width;
}
+// Returns the index of a card within its card word
inline
unsigned card_bit (size_t card)
{
diff --git a/src/gc/gcscan.cpp b/src/gc/gcscan.cpp
index b4e6352dd6..edcb533cd4 100644
--- a/src/gc/gcscan.cpp
+++ b/src/gc/gcscan.cpp
@@ -19,11 +19,7 @@
#include "gc.h"
#include "objecthandle.h"
-#ifdef DACCESS_COMPILE
-SVAL_IMPL_INIT(int32_t, GCScan, m_GcStructuresInvalidCnt, 1);
-#else //DACCESS_COMPILE
VOLATILE(int32_t) GCScan::m_GcStructuresInvalidCnt = 1;
-#endif //DACCESS_COMPILE
bool GCScan::GetGcRuntimeStructuresValid ()
{
@@ -33,18 +29,7 @@ bool GCScan::GetGcRuntimeStructuresValid ()
return (int32_t)m_GcStructuresInvalidCnt == 0;
}
-#ifdef DACCESS_COMPILE
-
-#ifndef FEATURE_REDHAWK
-void
-GCScan::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
-{
- UNREFERENCED_PARAMETER(flags);
- m_GcStructuresInvalidCnt.EnumMem();
-}
-#endif
-
-#else
+#ifndef DACCESS_COMPILE
//
// Dependent handle promotion scan support
diff --git a/src/gc/gcscan.h b/src/gc/gcscan.h
index 362370fa4a..c7060f3f51 100644
--- a/src/gc/gcscan.h
+++ b/src/gc/gcscan.h
@@ -89,19 +89,7 @@ class GCScan
static void VerifyHandleTable(int condemned, int max_gen, ScanContext* sc);
-private:
-#ifdef DACCESS_COMPILE
- SVAL_DECL(int32_t, m_GcStructuresInvalidCnt);
-#else
static VOLATILE(int32_t) m_GcStructuresInvalidCnt;
-#endif //DACCESS_COMPILE
};
-// These two functions are utilized to scan the heap if requested by ETW
-// or a profiler. The implementations of these two functions are in profheapwalkhelper.cpp.
-#if defined(FEATURE_EVENT_TRACE) | defined(GC_PROFILING)
-void ScanRootsHelper(Object* pObj, Object** ppRoot, ScanContext * pSC, DWORD dwFlags);
-BOOL HeapWalkHelper(Object * pBO, void * pvContext);
-#endif
-
#endif // _GCSCAN_H_
diff --git a/src/gc/handletable.cpp b/src/gc/handletable.cpp
index 29ee435b51..eee181959f 100644
--- a/src/gc/handletable.cpp
+++ b/src/gc/handletable.cpp
@@ -313,6 +313,10 @@ OBJECTHANDLE HndCreateHandle(HHANDLETABLE hTable, uint32_t uType, OBJECTREF obje
}
#endif // _DEBUG && !FEATURE_REDHAWK
+ // If we are creating a variable-strength handle, verify that the
+ // requested variable handle type is valid.
+ _ASSERTE(uType != HNDTYPE_VARIABLE || IS_VALID_VHT_VALUE(lExtraInfo));
+
VALIDATEOBJECTREF(object);
// fetch the handle table pointer
@@ -1334,24 +1338,6 @@ void Ref_RelocateAsyncPinHandles(HandleTableBucket *pSource, HandleTableBucket
}
#endif // !FEATURE_REDHAWK
-BOOL Ref_ContainHandle(HandleTableBucket *pBucket, OBJECTHANDLE handle)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- int limit = getNumberOfSlots();
- for (int n = 0; n < limit; n ++ )
- {
- if (TableContainHandle(Table(pBucket->pTable[n]), handle))
- return TRUE;
- }
-
- return FALSE;
-}
/*--------------------------------------------------------------------------*/
diff --git a/src/gc/handletable.h b/src/gc/handletable.h
index bbb8b1db22..ebf8c62c33 100644
--- a/src/gc/handletable.h
+++ b/src/gc/handletable.h
@@ -14,6 +14,7 @@
#ifndef _HANDLETABLE_H
#define _HANDLETABLE_H
+#include "gcinterface.h"
/****************************************************************************
*
@@ -103,11 +104,6 @@ void HndWriteBarrier(OBJECTHANDLE handle, OBJECTREF value);
*/
void HndLogSetEvent(OBJECTHANDLE handle, _UNCHECKED_OBJECTREF value);
- /*
- * Scanning callback.
- */
-typedef void (CALLBACK *HANDLESCANPROC)(PTR_UNCHECKED_OBJECTREF pref, uintptr_t *pExtraInfo, uintptr_t param1, uintptr_t param2);
-
/*
* NON-GC handle enumeration
*/
@@ -181,8 +177,11 @@ BOOL HndFirstAssignHandle(OBJECTHANDLE handle, OBJECTREF objref);
/*
* inline handle dereferencing
+ *
+ * NOTE: Changes to this implementation should be kept in sync with ObjectFromHandle
+ * on the VM side.
+ *
*/
-
FORCEINLINE OBJECTREF HndFetchHandle(OBJECTHANDLE handle)
{
WRAPPER_NO_CONTRACT;
@@ -217,18 +216,6 @@ FORCEINLINE BOOL HndIsNull(OBJECTHANDLE handle)
}
-
-/*
- * inline handle checking
- */
-FORCEINLINE BOOL HndCheckForNullUnchecked(OBJECTHANDLE handle)
-{
- LIMITED_METHOD_CONTRACT;
-
- return (handle == NULL || (*(_UNCHECKED_OBJECTREF *)handle) == NULL);
-}
-
-
/*
*
* Checks handle value for null or special value used for free handles in cache.
diff --git a/src/gc/objecthandle.cpp b/src/gc/objecthandle.cpp
index e8eed93006..5df53baad5 100644
--- a/src/gc/objecthandle.cpp
+++ b/src/gc/objecthandle.cpp
@@ -441,13 +441,13 @@ void CALLBACK ScanPointerForProfilerAndETW(_UNCHECKED_OBJECTREF *pObjRef, uintpt
ScanContext *pSC = (ScanContext *)lp1;
uint32_t rootFlags = 0;
- BOOL isDependent = FALSE;
+ bool isDependent = false;
OBJECTHANDLE handle = (OBJECTHANDLE)(pRef);
switch (HandleFetchType(handle))
{
case HNDTYPE_DEPENDENT:
- isDependent = TRUE;
+ isDependent = true;
break;
case HNDTYPE_WEAK_SHORT:
case HNDTYPE_WEAK_LONG:
@@ -871,24 +871,6 @@ void Ref_EndSynchronousGC(uint32_t condemned, uint32_t maxgen)
*/
}
-
-OBJECTHANDLE CreateDependentHandle(HHANDLETABLE table, OBJECTREF primary, OBJECTREF secondary)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- OBJECTHANDLE handle = HndCreateHandle(table, HNDTYPE_DEPENDENT, primary);
-
- SetDependentHandleSecondary(handle, secondary);
-
- return handle;
-}
-
void SetDependentHandleSecondary(OBJECTHANDLE handle, OBJECTREF objref)
{
CONTRACTL
@@ -925,30 +907,6 @@ void SetDependentHandleSecondary(OBJECTHANDLE handle, OBJECTREF objref)
//----------------------------------------------------------------------------
/*
- * CreateVariableHandle.
- *
- * Creates a variable-strength handle.
- *
- * N.B. This routine is not a macro since we do validation in RETAIL.
- * We always validate the type here because it can come from external callers.
- */
-OBJECTHANDLE CreateVariableHandle(HHANDLETABLE hTable, OBJECTREF object, uint32_t type)
-{
- WRAPPER_NO_CONTRACT;
-
- // verify that we are being asked to create a valid type
- if (!IS_VALID_VHT_VALUE(type))
- {
- // bogus value passed in
- _ASSERTE(FALSE);
- return NULL;
- }
-
- // create the handle
- return HndCreateHandle(hTable, HNDTYPE_VARIABLE, object, (uintptr_t)type);
-}
-
-/*
* GetVariableHandleType.
*
* Retrieves the dynamic type of a variable-strength handle.
@@ -1898,51 +1856,6 @@ bool HandleTableBucket::Contains(OBJECTHANDLE handle)
return FALSE;
}
-void DestroySizedRefHandle(OBJECTHANDLE handle)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- HHANDLETABLE hTable = HndGetHandleTable(handle);
- HndDestroyHandle(hTable , HNDTYPE_SIZEDREF, handle);
- AppDomain* pDomain = SystemDomain::GetAppDomainAtIndex(HndGetHandleTableADIndex(hTable));
- pDomain->DecNumSizedRefHandles();
-}
-
-#ifdef FEATURE_COMINTEROP
-
-void DestroyWinRTWeakHandle(OBJECTHANDLE handle)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- CAN_TAKE_LOCK;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- // Release the WinRT weak reference if we have one. We're assuming that this will not reenter the
- // runtime, since if we are pointing at a managed object, we should not be using a HNDTYPE_WEAK_WINRT
- // but rather a HNDTYPE_WEAK_SHORT or HNDTYPE_WEAK_LONG.
- IWeakReference* pWinRTWeakReference = reinterpret_cast<IWeakReference*>(HndGetHandleExtraInfo(handle));
- if (pWinRTWeakReference != NULL)
- {
- pWinRTWeakReference->Release();
- }
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_WEAK_WINRT, handle);
-}
-
-#endif // FEATURE_COMINTEROP
-
#endif // !DACCESS_COMPILE
OBJECTREF GetDependentHandleSecondary(OBJECTHANDLE handle)
diff --git a/src/gc/objecthandle.h b/src/gc/objecthandle.h
index 34c2a0e321..d3e45f8659 100644
--- a/src/gc/objecthandle.h
+++ b/src/gc/objecthandle.h
@@ -27,172 +27,9 @@
* non-NULL. In other words, if this handle is being initialized for the first
* time.
*/
-#define ObjectFromHandle(handle) HndFetchHandle(handle)
#define StoreObjectInHandle(handle, object) HndAssignHandle(handle, object)
#define InterlockedCompareExchangeObjectInHandle(handle, object, oldObj) HndInterlockedCompareExchangeHandle(handle, object, oldObj)
#define StoreFirstObjectInHandle(handle, object) HndFirstAssignHandle(handle, object)
-#define ObjectHandleIsNull(handle) HndIsNull(handle)
-#define IsHandleNullUnchecked(handle) HndCheckForNullUnchecked(handle)
-
-
-/*
- * HANDLES
- *
- * The default type of handle is a strong handle.
- *
- */
-#define HNDTYPE_DEFAULT HNDTYPE_STRONG
-
-
-/*
- * WEAK HANDLES
- *
- * Weak handles are handles that track an object as long as it is alive,
- * but do not keep the object alive if there are no strong references to it.
- *
- * The default type of weak handle is 'long-lived' weak handle.
- *
- */
-#define HNDTYPE_WEAK_DEFAULT HNDTYPE_WEAK_LONG
-
-
-/*
- * SHORT-LIVED WEAK HANDLES
- *
- * Short-lived weak handles are weak handles that track an object until the
- * first time it is detected to be unreachable. At this point, the handle is
- * severed, even if the object will be visible from a pending finalization
- * graph. This further implies that short weak handles do not track
- * across object resurrections.
- *
- */
-#define HNDTYPE_WEAK_SHORT (0)
-
-
-/*
- * LONG-LIVED WEAK HANDLES
- *
- * Long-lived weak handles are weak handles that track an object until the
- * object is actually reclaimed. Unlike short weak handles, long weak handles
- * continue to track their referents through finalization and across any
- * resurrections that may occur.
- *
- */
-#define HNDTYPE_WEAK_LONG (1)
-
-
-/*
- * STRONG HANDLES
- *
- * Strong handles are handles which function like a normal object reference.
- * The existence of a strong handle for an object will cause the object to
- * be promoted (remain alive) through a garbage collection cycle.
- *
- */
-#define HNDTYPE_STRONG (2)
-
-
-/*
- * PINNED HANDLES
- *
- * Pinned handles are strong handles which have the added property that they
- * prevent an object from moving during a garbage collection cycle. This is
- * useful when passing a pointer to object innards out of the runtime while GC
- * may be enabled.
- *
- * NOTE: PINNING AN OBJECT IS EXPENSIVE AS IT PREVENTS THE GC FROM ACHIEVING
- * OPTIMAL PACKING OF OBJECTS DURING EPHEMERAL COLLECTIONS. THIS TYPE
- * OF HANDLE SHOULD BE USED SPARINGLY!
- */
-#define HNDTYPE_PINNED (3)
-
-
-/*
- * VARIABLE HANDLES
- *
- * Variable handles are handles whose type can be changed dynamically. They
- * are larger than other types of handles, and are scanned a little more often,
- * but are useful when the handle owner needs an efficient way to change the
- * strength of a handle on the fly.
- *
- */
-#define HNDTYPE_VARIABLE (4)
-
-#if defined(FEATURE_COMINTEROP) || defined(FEATURE_REDHAWK)
-/*
- * REFCOUNTED HANDLES
- *
- * Refcounted handles are handles that behave as strong handles while the
- * refcount on them is greater than 0 and behave as weak handles otherwise.
- *
- * N.B. These are currently NOT general purpose.
- * The implementation is tied to COM Interop.
- *
- */
-#define HNDTYPE_REFCOUNTED (5)
-#endif // FEATURE_COMINTEROP || FEATURE_REDHAWK
-
-
-/*
- * DEPENDENT HANDLES
- *
- * Dependent handles are two handles that need to have the same lifetime. One handle refers to a secondary object
- * that needs to have the same lifetime as the primary object. The secondary object should not cause the primary
- * object to be referenced, but as long as the primary object is alive, so must be the secondary
- *
- * They are currently used for EnC for adding new field members to existing instantiations under EnC modes where
- * the primary object is the original instantiation and the secondary represents the added field.
- *
- * They are also used to implement the ConditionalWeakTable class in mscorlib.dll. If you want to use
- * these from managed code, they are exposed to BCL through the managed DependentHandle class.
- *
- *
- */
-#define HNDTYPE_DEPENDENT (6)
-
-/*
- * PINNED HANDLES for asynchronous operation
- *
- * Pinned handles are strong handles which have the added property that they
- * prevent an object from moving during a garbage collection cycle. This is
- * useful when passing a pointer to object innards out of the runtime while GC
- * may be enabled.
- *
- * NOTE: PINNING AN OBJECT IS EXPENSIVE AS IT PREVENTS THE GC FROM ACHIEVING
- * OPTIMAL PACKING OF OBJECTS DURING EPHEMERAL COLLECTIONS. THIS TYPE
- * OF HANDLE SHOULD BE USED SPARINGLY!
- */
-#define HNDTYPE_ASYNCPINNED (7)
-
-
-/*
- * SIZEDREF HANDLES
- *
- * SizedRef handles are strong handles. Each handle has a piece of user data associated
- * with it that stores the size of the object this handle refers to. These handles
- * are scanned as strong roots during each GC but only during full GCs would the size
- * be calculated.
- *
- */
-#define HNDTYPE_SIZEDREF (8)
-
-#ifdef FEATURE_COMINTEROP
-
-/*
- * WINRT WEAK HANDLES
- *
- * WinRT weak reference handles hold two different types of weak handles to any
- * RCW with an underlying COM object that implements IWeakReferenceSource. The
- * object reference itself is a short weak handle to the RCW. In addition an
- * IWeakReference* to the underlying COM object is stored, allowing the handle
- * to create a new RCW if the existing RCW is collected. This ensures that any
- * code holding onto a WinRT weak reference can always access an RCW to the
- * underlying COM object as long as it has not been released by all of its strong
- * references.
- */
-#define HNDTYPE_WEAK_WINRT (9)
-
-#endif // FEATURE_COMINTEROP
typedef DPTR(struct HandleTableMap) PTR_HandleTableMap;
typedef DPTR(struct HandleTableBucket) PTR_HandleTableBucket;
@@ -234,396 +71,25 @@ struct HandleTableBucket
(flag == VHT_STRONG) || \
(flag == VHT_PINNED))
-#ifndef DACCESS_COMPILE
-/*
- * Convenience macros and prototypes for the various handle types we define
- */
-
-inline OBJECTHANDLE CreateTypedHandle(HHANDLETABLE table, OBJECTREF object, int type)
-{
- WRAPPER_NO_CONTRACT;
-
- return HndCreateHandle(table, type, object);
-}
-
-inline void DestroyTypedHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandleOfUnknownType(HndGetHandleTable(handle), handle);
-}
-
-inline OBJECTHANDLE CreateHandle(HHANDLETABLE table, OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
-
- return HndCreateHandle(table, HNDTYPE_DEFAULT, object);
-}
-
-inline void DestroyHandle(OBJECTHANDLE handle)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- CAN_TAKE_LOCK;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_DEFAULT, handle);
-}
-
-inline OBJECTHANDLE CreateDuplicateHandle(OBJECTHANDLE handle) {
- WRAPPER_NO_CONTRACT;
-
- // Create a new STRONG handle in the same table as an existing handle.
- return HndCreateHandle(HndGetHandleTable(handle), HNDTYPE_DEFAULT, ObjectFromHandle(handle));
-}
-
-
-inline OBJECTHANDLE CreateWeakHandle(HHANDLETABLE table, OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
-
- return HndCreateHandle(table, HNDTYPE_WEAK_DEFAULT, object);
-}
-
-inline void DestroyWeakHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_WEAK_DEFAULT, handle);
-}
-
-inline OBJECTHANDLE CreateShortWeakHandle(HHANDLETABLE table, OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
-
- return HndCreateHandle(table, HNDTYPE_WEAK_SHORT, object);
-}
-
-inline void DestroyShortWeakHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_WEAK_SHORT, handle);
-}
-
-
-inline OBJECTHANDLE CreateLongWeakHandle(HHANDLETABLE table, OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
-
- return HndCreateHandle(table, HNDTYPE_WEAK_LONG, object);
-}
-
-inline void DestroyLongWeakHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_WEAK_LONG, handle);
-}
-
-#ifndef FEATURE_REDHAWK
-typedef Holder<OBJECTHANDLE,DoNothing<OBJECTHANDLE>,DestroyLongWeakHandle> LongWeakHandleHolder;
-#endif
-
-inline OBJECTHANDLE CreateStrongHandle(HHANDLETABLE table, OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
-
- return HndCreateHandle(table, HNDTYPE_STRONG, object);
-}
-
-inline void DestroyStrongHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_STRONG, handle);
-}
-
-inline OBJECTHANDLE CreatePinningHandle(HHANDLETABLE table, OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
-
- return HndCreateHandle(table, HNDTYPE_PINNED, object);
-}
-
-inline void DestroyPinningHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_PINNED, handle);
-}
-
-#ifndef FEATURE_REDHAWK
-typedef Wrapper<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroyPinningHandle, NULL> PinningHandleHolder;
-#endif
-
-inline OBJECTHANDLE CreateAsyncPinningHandle(HHANDLETABLE table, OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
-
- return HndCreateHandle(table, HNDTYPE_ASYNCPINNED, object);
-}
-
-inline void DestroyAsyncPinningHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_ASYNCPINNED, handle);
-}
-
-#ifndef FEATURE_REDHAWK
-typedef Wrapper<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroyAsyncPinningHandle, NULL> AsyncPinningHandleHolder;
-#endif
-
-inline OBJECTHANDLE CreateSizedRefHandle(HHANDLETABLE table, OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
-
- return HndCreateHandle(table, HNDTYPE_SIZEDREF, object, (uintptr_t)0);
-}
-
-void DestroySizedRefHandle(OBJECTHANDLE handle);
-
-#ifndef FEATURE_REDHAWK
-typedef Wrapper<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroySizedRefHandle, NULL> SizeRefHandleHolder;
-#endif
-
-#ifdef FEATURE_COMINTEROP
-inline OBJECTHANDLE CreateRefcountedHandle(HHANDLETABLE table, OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
-
- return HndCreateHandle(table, HNDTYPE_REFCOUNTED, object);
-}
-
-inline void DestroyRefcountedHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_REFCOUNTED, handle);
-}
-
-inline OBJECTHANDLE CreateWinRTWeakHandle(HHANDLETABLE table, OBJECTREF object, IWeakReference* pWinRTWeakReference)
-{
- WRAPPER_NO_CONTRACT;
- _ASSERTE(pWinRTWeakReference != NULL);
- return HndCreateHandle(table, HNDTYPE_WEAK_WINRT, object, reinterpret_cast<uintptr_t>(pWinRTWeakReference));
-}
-
-void DestroyWinRTWeakHandle(OBJECTHANDLE handle);
-
-#endif // FEATURE_COMINTEROP
-
-#endif // !DACCESS_COMPILE
-
OBJECTREF GetDependentHandleSecondary(OBJECTHANDLE handle);
#ifndef DACCESS_COMPILE
-OBJECTHANDLE CreateDependentHandle(HHANDLETABLE table, OBJECTREF primary, OBJECTREF secondary);
void SetDependentHandleSecondary(OBJECTHANDLE handle, OBJECTREF secondary);
-
-inline void DestroyDependentHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_DEPENDENT, handle);
-}
#endif // !DACCESS_COMPILE
#ifndef DACCESS_COMPILE
-
-OBJECTHANDLE CreateVariableHandle(HHANDLETABLE hTable, OBJECTREF object, uint32_t type);
uint32_t GetVariableHandleType(OBJECTHANDLE handle);
void UpdateVariableHandleType(OBJECTHANDLE handle, uint32_t type);
uint32_t CompareExchangeVariableHandleType(OBJECTHANDLE handle, uint32_t oldType, uint32_t newType);
-inline void DestroyVariableHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_VARIABLE, handle);
-}
-
void GCHandleValidatePinnedObject(OBJECTREF obj);
/*
- * Holder for OBJECTHANDLE
- */
-
-#ifndef FEATURE_REDHAWK
-typedef Wrapper<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroyHandle > OHWrapper;
-
-class OBJECTHANDLEHolder : public OHWrapper
-{
-public:
- FORCEINLINE OBJECTHANDLEHolder(OBJECTHANDLE p = NULL) : OHWrapper(p)
- {
- LIMITED_METHOD_CONTRACT;
- }
- FORCEINLINE void operator=(OBJECTHANDLE p)
- {
- WRAPPER_NO_CONTRACT;
-
- OHWrapper::operator=(p);
- }
-};
-#endif
-
-#ifdef FEATURE_COMINTEROP
-
-typedef Wrapper<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroyRefcountedHandle> RefCountedOHWrapper;
-
-class RCOBJECTHANDLEHolder : public RefCountedOHWrapper
-{
-public:
- FORCEINLINE RCOBJECTHANDLEHolder(OBJECTHANDLE p = NULL) : RefCountedOHWrapper(p)
- {
- LIMITED_METHOD_CONTRACT;
- }
- FORCEINLINE void operator=(OBJECTHANDLE p)
- {
- WRAPPER_NO_CONTRACT;
-
- RefCountedOHWrapper::operator=(p);
- }
-};
-
-#endif // FEATURE_COMINTEROP
-/*
* Convenience prototypes for using the global handles
*/
int GetCurrentThreadHomeHeapNumber();
-inline OBJECTHANDLE CreateGlobalTypedHandle(OBJECTREF object, int type)
-{
- WRAPPER_NO_CONTRACT;
- return HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], type, object);
-}
-
-inline void DestroyGlobalTypedHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandleOfUnknownType(HndGetHandleTable(handle), handle);
-}
-
-inline OBJECTHANDLE CreateGlobalHandle(OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
- CONDITIONAL_CONTRACT_VIOLATION(ModeViolation, object == NULL);
-
- return HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], HNDTYPE_DEFAULT, object);
-}
-
-inline void DestroyGlobalHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_DEFAULT, handle);
-}
-
-inline OBJECTHANDLE CreateGlobalWeakHandle(OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
-
- return HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], HNDTYPE_WEAK_DEFAULT, object);
-}
-
-inline void DestroyGlobalWeakHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_WEAK_DEFAULT, handle);
-}
-
-inline OBJECTHANDLE CreateGlobalShortWeakHandle(OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
- CONDITIONAL_CONTRACT_VIOLATION(ModeViolation, object == NULL);
-
- return HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], HNDTYPE_WEAK_SHORT, object);
-}
-
-inline void DestroyGlobalShortWeakHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_WEAK_SHORT, handle);
-}
-
-#ifndef FEATURE_REDHAWK
-typedef Holder<OBJECTHANDLE,DoNothing<OBJECTHANDLE>,DestroyGlobalShortWeakHandle> GlobalShortWeakHandleHolder;
-#endif
-
-inline OBJECTHANDLE CreateGlobalLongWeakHandle(OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
-
- return HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], HNDTYPE_WEAK_LONG, object);
-}
-
-inline void DestroyGlobalLongWeakHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_WEAK_LONG, handle);
-}
-
-inline OBJECTHANDLE CreateGlobalStrongHandle(OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
- CONDITIONAL_CONTRACT_VIOLATION(ModeViolation, object == NULL);
-
- return HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], HNDTYPE_STRONG, object);
-}
-
-inline void DestroyGlobalStrongHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_STRONG, handle);
-}
-
-#ifndef FEATURE_REDHAWK
-typedef Holder<OBJECTHANDLE,DoNothing<OBJECTHANDLE>,DestroyGlobalStrongHandle> GlobalStrongHandleHolder;
-#endif
-
-inline OBJECTHANDLE CreateGlobalPinningHandle(OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
-
- return HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], HNDTYPE_PINNED, object);
-}
-
-inline void DestroyGlobalPinningHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_PINNED, handle);
-}
-
-#ifdef FEATURE_COMINTEROP
-inline OBJECTHANDLE CreateGlobalRefcountedHandle(OBJECTREF object)
-{
- WRAPPER_NO_CONTRACT;
-
- return HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], HNDTYPE_REFCOUNTED, object);
-}
-
-inline void DestroyGlobalRefcountedHandle(OBJECTHANDLE handle)
-{
- WRAPPER_NO_CONTRACT;
-
- HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_REFCOUNTED, handle);
-}
-#endif // FEATURE_COMINTEROP
-
inline void ResetOBJECTHANDLE(OBJECTHANDLE handle)
{
WRAPPER_NO_CONTRACT;
@@ -645,7 +111,6 @@ BOOL Ref_HandleAsyncPinHandles();
void Ref_RelocateAsyncPinHandles(HandleTableBucket *pSource, HandleTableBucket *pTarget);
void Ref_RemoveHandleTableBucket(HandleTableBucket *pBucket);
void Ref_DestroyHandleTableBucket(HandleTableBucket *pBucket);
-BOOL Ref_ContainHandle(HandleTableBucket *pBucket, OBJECTHANDLE handle);
/*
* GC-time scanning entrypoints
@@ -671,8 +136,6 @@ void Ref_ScanSizedRefHandles(uint32_t condemned, uint32_t maxgen, ScanContext* s
void Ref_ScanPointers(uint32_t condemned, uint32_t maxgen, ScanContext* sc, Ref_promote_func* fn);
#endif
-typedef void (* handle_scan_fn)(Object** pRef, Object* pSec, uint32_t flags, ScanContext* context, BOOL isDependent);
-
void Ref_CheckReachable (uint32_t uCondemnedGeneration, uint32_t uMaxGeneration, uintptr_t lp1);
void Ref_CheckAlive (uint32_t uCondemnedGeneration, uint32_t uMaxGeneration, uintptr_t lp1);
void Ref_ScanHandlesForProfilerAndETW(uint32_t uMaxGeneration, uintptr_t lp1, handle_scan_fn fn);
diff --git a/src/gc/sample/CMakeLists.txt b/src/gc/sample/CMakeLists.txt
index 29fd32f2ff..5fe7887963 100644
--- a/src/gc/sample/CMakeLists.txt
+++ b/src/gc/sample/CMakeLists.txt
@@ -10,6 +10,7 @@ set(SOURCES
gcenv.ee.cpp
../gccommon.cpp
../gceewks.cpp
+ ../gchandletable.cpp
../gcscan.cpp
../gcwks.cpp
../handletable.cpp
diff --git a/src/gc/sample/GCSample.cpp b/src/gc/sample/GCSample.cpp
index 112d291420..2914ee1665 100644
--- a/src/gc/sample/GCSample.cpp
+++ b/src/gc/sample/GCSample.cpp
@@ -126,22 +126,26 @@ int __cdecl main(int argc, char* argv[])
g_pFreeObjectMethodTable = &freeObjectMT;
//
- // Initialize handle table
- //
- if (!Ref_Initialize())
- return -1;
-
- //
// Initialize GC heap
//
- IGCHeap *pGCHeap = InitializeGarbageCollector(nullptr);
- if (!pGCHeap)
+ GcDacVars dacVars;
+ IGCHeap *pGCHeap;
+ IGCHandleTable *pGCHandleTable;
+ if (!InitializeGarbageCollector(nullptr, &pGCHeap, &pGCHandleTable, &dacVars))
+ {
return -1;
+ }
if (FAILED(pGCHeap->Initialize()))
return -1;
//
+ // Initialize handle table
+ //
+ if (!pGCHandleTable->Initialize())
+ return -1;
+
+ //
// Initialize current thread
//
ThreadStore::AttachCurrentThread();
@@ -197,41 +201,41 @@ int __cdecl main(int argc, char* argv[])
return -1;
// Create strong handle and store the object into it
- OBJECTHANDLE oh = CreateGlobalHandle(pObj);
+ OBJECTHANDLE oh = HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], HNDTYPE_DEFAULT, pObj);
if (oh == NULL)
return -1;
for (int i = 0; i < 1000000; i++)
{
- Object * pBefore = ((My *)ObjectFromHandle(oh))->m_pOther1;
+ Object * pBefore = ((My *)HndFetchHandle(oh))->m_pOther1;
// Allocate more instances of the same object
Object * p = AllocateObject(pMyMethodTable);
if (p == NULL)
return -1;
- Object * pAfter = ((My *)ObjectFromHandle(oh))->m_pOther1;
+ Object * pAfter = ((My *)HndFetchHandle(oh))->m_pOther1;
// Uncomment this assert to see how GC triggered inside AllocateObject moved objects around
// assert(pBefore == pAfter);
// Store the newly allocated object into a field using WriteBarrier
- WriteBarrier(&(((My *)ObjectFromHandle(oh))->m_pOther1), p);
+ WriteBarrier(&(((My *)HndFetchHandle(oh))->m_pOther1), p);
}
// Create weak handle that points to our object
- OBJECTHANDLE ohWeak = CreateGlobalWeakHandle(ObjectFromHandle(oh));
+ OBJECTHANDLE ohWeak = HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], HNDTYPE_WEAK_DEFAULT, HndFetchHandle(oh));
if (ohWeak == NULL)
return -1;
// Destroy the strong handle so that nothing will be keeping out object alive
- DestroyGlobalHandle(oh);
+ HndDestroyHandle(HndGetHandleTable(oh), HNDTYPE_DEFAULT, oh);
// Explicitly trigger full GC
pGCHeap->GarbageCollect();
// Verify that the weak handle got cleared by the GC
- assert(ObjectFromHandle(ohWeak) == NULL);
+ assert(HndFetchHandle(ohWeak) == NULL);
printf("Done\n");
diff --git a/src/gc/sample/gcenv.ee.cpp b/src/gc/sample/gcenv.ee.cpp
index e95a78dc48..fa6efbf2d6 100644
--- a/src/gc/sample/gcenv.ee.cpp
+++ b/src/gc/sample/gcenv.ee.cpp
@@ -15,6 +15,8 @@ int32_t g_TrapReturningThreads;
EEConfig * g_pConfig;
+gc_alloc_context g_global_alloc_context;
+
bool CLREventStatic::CreateManualEventNoThrow(bool bInitialState)
{
m_hEvent = CreateEventW(NULL, TRUE, bInitialState, NULL);
@@ -135,7 +137,7 @@ void ThreadStore::AttachCurrentThread()
void GCToEEInterface::SuspendEE(SUSPEND_REASON reason)
{
- g_theGCHeap->SetGCInProgress(TRUE);
+ g_theGCHeap->SetGCInProgress(true);
// TODO: Implement
}
@@ -144,7 +146,7 @@ void GCToEEInterface::RestartEE(bool bFinishedGC)
{
// TODO: Implement
- g_theGCHeap->SetGCInProgress(FALSE);
+ g_theGCHeap->SetGCInProgress(false);
}
void GCToEEInterface::GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc)
@@ -263,6 +265,32 @@ void GCToEEInterface::EnableFinalization(bool foundFinalizers)
// TODO: Implement for finalization
}
+void GCToEEInterface::HandleFatalError(unsigned int exitCode)
+{
+ abort();
+}
+
+bool GCToEEInterface::ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj)
+{
+ return true;
+}
+
+bool GCToEEInterface::ForceFullGCToBeBlocking()
+{
+ return false;
+}
+
+bool GCToEEInterface::EagerFinalized(Object* obj)
+{
+ // The sample does not finalize anything eagerly.
+ return false;
+}
+
+MethodTable* GCToEEInterface::GetFreeObjectMethodTable()
+{
+ return g_pFreeObjectMethodTable;
+}
+
bool IsGCSpecialThread()
{
// TODO: Implement for background GC
diff --git a/src/gc/unix/CMakeLists.txt b/src/gc/unix/CMakeLists.txt
index ef66abf32a..3e1aa5ad19 100644
--- a/src/gc/unix/CMakeLists.txt
+++ b/src/gc/unix/CMakeLists.txt
@@ -5,6 +5,7 @@ include_directories("../env")
include(configure.cmake)
set(GC_PAL_SOURCES
- gcenv.unix.cpp)
+ gcenv.unix.cpp
+ cgroup.cpp)
add_library(gc_unix STATIC ${GC_PAL_SOURCES} ${VERSION_FILE_PATH})
diff --git a/src/gc/unix/cgroup.cpp b/src/gc/unix/cgroup.cpp
new file mode 100644
index 0000000000..1775ef7ff0
--- /dev/null
+++ b/src/gc/unix/cgroup.cpp
@@ -0,0 +1,342 @@
+// 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.
+
+/*++
+
+Module Name:
+
+ cgroup.cpp
+
+Abstract:
+ Read memory limits for the current process
+--*/
+#include <cstdint>
+#include <cstddef>
+#include <cassert>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/resource.h>
+#include <errno.h>
+
+#define SIZE_T_MAX (~(size_t)0)
+#define PROC_MOUNTINFO_FILENAME "/proc/self/mountinfo"
+#define PROC_CGROUP_FILENAME "/proc/self/cgroup"
+#define PROC_STATM_FILENAME "/proc/self/statm"
+#define MEM_LIMIT_FILENAME "/memory.limit_in_bytes"
+
+class CGroup
+{
+ char* m_memory_cgroup_path;
+public:
+ CGroup()
+ {
+ m_memory_cgroup_path = nullptr;
+ char* memoryHierarchyMount = nullptr;
+ char *cgroup_path_relative_to_mount = nullptr;
+ size_t len;
+ memoryHierarchyMount = FindMemoryHierarchyMount();
+ if (memoryHierarchyMount == nullptr)
+ goto done;
+
+ cgroup_path_relative_to_mount = FindCGroupPathForMemorySubsystem();
+ if (cgroup_path_relative_to_mount == nullptr)
+ goto done;
+
+ len = strlen(memoryHierarchyMount);
+ len += strlen(cgroup_path_relative_to_mount);
+ m_memory_cgroup_path = (char*)malloc(len+1);
+ if (m_memory_cgroup_path == nullptr)
+ goto done;
+
+ strcpy(m_memory_cgroup_path, memoryHierarchyMount);
+ strcat(m_memory_cgroup_path, cgroup_path_relative_to_mount);
+
+ done:
+ free(memoryHierarchyMount);
+ free(cgroup_path_relative_to_mount);
+ }
+
+ ~CGroup()
+ {
+ free(m_memory_cgroup_path);
+ }
+
+ bool GetPhysicalMemoryLimit(size_t *val)
+ {
+ char *mem_limit_filename = nullptr;
+ bool result = false;
+
+ if (m_memory_cgroup_path == nullptr)
+ return result;
+
+ size_t len = strlen(m_memory_cgroup_path);
+ len += strlen(MEM_LIMIT_FILENAME);
+ mem_limit_filename = (char*)malloc(len+1);
+ if (mem_limit_filename == nullptr)
+ return result;
+
+ strcpy(mem_limit_filename, m_memory_cgroup_path);
+ strcat(mem_limit_filename, MEM_LIMIT_FILENAME);
+ result = ReadMemoryValueFromFile(mem_limit_filename, val);
+ free(mem_limit_filename);
+ return result;
+ }
+
+private:
+ char* FindMemoryHierarchyMount()
+ {
+ char *line = nullptr;
+ size_t lineLen = 0, maxLineLen = 0;
+ char *filesystemType = nullptr;
+ char *options = nullptr;
+ char* mountpath = nullptr;
+
+ FILE *mountinfofile = fopen(PROC_MOUNTINFO_FILENAME, "r");
+ if (mountinfofile == nullptr)
+ goto done;
+
+ while (getline(&line, &lineLen, mountinfofile) != -1)
+ {
+ if (filesystemType == nullptr || lineLen > maxLineLen)
+ {
+ free(filesystemType);
+ free(options);
+ filesystemType = (char*)malloc(lineLen+1);
+ if (filesystemType == nullptr)
+ goto done;
+ options = (char*)malloc(lineLen+1);
+ if (options == nullptr)
+ goto done;
+ maxLineLen = lineLen;
+ }
+
+ char* separatorChar = strchr(line, '-');
+
+ // See man page of proc to get format for /proc/self/mountinfo file
+ int sscanfRet = sscanf(separatorChar,
+ "- %s %*s %s",
+ filesystemType,
+ options);
+ if (sscanfRet != 2)
+ {
+ assert(!"Failed to parse mount info file contents with sscanf.");
+ goto done;
+ }
+
+ if (strncmp(filesystemType, "cgroup", 6) == 0)
+ {
+ char* context = nullptr;
+ char* strTok = strtok_r(options, ",", &context);
+ while (strTok != nullptr)
+ {
+ if (strncmp("memory", strTok, 6) == 0)
+ {
+ mountpath = (char*)malloc(lineLen+1);
+ if (mountpath == nullptr)
+ goto done;
+
+ sscanfRet = sscanf(line,
+ "%*s %*s %*s %*s %s ",
+ mountpath);
+ if (sscanfRet != 1)
+ {
+ free(mountpath);
+ mountpath = nullptr;
+ assert(!"Failed to parse mount info file contents with sscanf.");
+ }
+ goto done;
+ }
+ strTok = strtok_r(nullptr, ",", &context);
+ }
+ }
+ }
+ done:
+ free(filesystemType);
+ free(options);
+ free(line);
+ if (mountinfofile)
+ fclose(mountinfofile);
+ return mountpath;
+ }
+
+ char* FindCGroupPathForMemorySubsystem()
+ {
+ char *line = nullptr;
+ size_t lineLen = 0;
+ size_t maxLineLen = 0;
+ char *subsystem_list = nullptr;
+ char *cgroup_path = nullptr;
+ bool result = false;
+
+ FILE *cgroupfile = fopen(PROC_CGROUP_FILENAME, "r");
+ if (cgroupfile == nullptr)
+ goto done;
+
+ while (!result && getline(&line, &lineLen, cgroupfile) != -1)
+ {
+ if (subsystem_list == nullptr || lineLen > maxLineLen)
+ {
+ free(subsystem_list);
+ free(cgroup_path);
+ subsystem_list = (char*)malloc(lineLen+1);
+ if (subsystem_list == nullptr)
+ goto done;
+ cgroup_path = (char*)malloc(lineLen+1);
+ if (cgroup_path == nullptr)
+ goto done;
+ maxLineLen = lineLen;
+ }
+
+ // See man page of proc to get format for /proc/self/cgroup file
+ int sscanfRet = sscanf(line,
+ "%*[^:]:%[^:]:%s",
+ subsystem_list,
+ cgroup_path);
+ if (sscanfRet != 2)
+ {
+ assert(!"Failed to parse cgroup info file contents with sscanf.");
+ goto done;
+ }
+
+ char* context = nullptr;
+ char* strTok = strtok_r(subsystem_list, ",", &context);
+ while (strTok != nullptr)
+ {
+ if (strncmp("memory", strTok, 6) == 0)
+ {
+ result = true;
+ break;
+ }
+ strTok = strtok_r(nullptr, ",", &context);
+ }
+ }
+ done:
+ free(subsystem_list);
+ if (!result)
+ {
+ free(cgroup_path);
+ cgroup_path = nullptr;
+ }
+ free(line);
+ if (cgroupfile)
+ fclose(cgroupfile);
+ return cgroup_path;
+ }
+
+ bool ReadMemoryValueFromFile(const char* filename, size_t* val)
+ {
+ bool result = false;
+ char *line = nullptr;
+ size_t lineLen = 0;
+ char* endptr = nullptr;
+ size_t num = 0, l, multiplier;
+ FILE* file = nullptr;
+
+ if (val == nullptr)
+ goto done;
+
+ file = fopen(filename, "r");
+ if (file == nullptr)
+ goto done;
+
+ if (getline(&line, &lineLen, file) == -1)
+ goto done;
+
+ errno = 0;
+ num = strtoull(line, &endptr, 0);
+ if (errno != 0)
+ goto done;
+
+ multiplier = 1;
+ switch(*endptr)
+ {
+ case 'g':
+ case 'G': multiplier = 1024;
+ case 'm':
+ case 'M': multiplier = multiplier*1024;
+ case 'k':
+ case 'K': multiplier = multiplier*1024;
+ }
+
+ *val = num * multiplier;
+ result = true;
+ if (*val/multiplier != num)
+ result = false;
+ done:
+ if (file)
+ fclose(file);
+ free(line);
+ return result;
+ }
+};
+
+size_t GetRestrictedPhysicalMemoryLimit()
+{
+ CGroup cgroup;
+ size_t physical_memory_limit;
+
+ if (!cgroup.GetPhysicalMemoryLimit(&physical_memory_limit))
+ physical_memory_limit = SIZE_T_MAX;
+
+ struct rlimit curr_rlimit;
+ size_t rlimit_soft_limit = RLIM_INFINITY;
+ if (getrlimit(RLIMIT_AS, &curr_rlimit) == 0)
+ {
+ rlimit_soft_limit = curr_rlimit.rlim_cur;
+ }
+ physical_memory_limit = (physical_memory_limit < rlimit_soft_limit) ?
+ physical_memory_limit : rlimit_soft_limit;
+
+ // Ensure that limit is not greater than real memory size
+ long pages = sysconf(_SC_PHYS_PAGES);
+ if (pages != -1)
+ {
+ long pageSize = sysconf(_SC_PAGE_SIZE);
+ if (pageSize != -1)
+ {
+ physical_memory_limit = (physical_memory_limit < (size_t)pages * pageSize)?
+ physical_memory_limit : (size_t)pages * pageSize;
+ }
+ }
+
+ return physical_memory_limit;
+}
+
+bool GetWorkingSetSize(size_t* val)
+{
+ bool result = false;
+ size_t linelen;
+ char* line = nullptr;
+
+ if (val == nullptr)
+ return false;
+
+ FILE* file = fopen(PROC_STATM_FILENAME, "r");
+ if (file != nullptr && getline(&line, &linelen, file) != -1)
+ {
+
+ char* context = nullptr;
+ char* strTok = strtok_r(line, " ", &context);
+ strTok = strtok_r(nullptr, " ", &context);
+
+ errno = 0;
+ *val = strtoull(strTok, nullptr, 0);
+ if (errno == 0)
+ {
+ long pageSize = sysconf(_SC_PAGE_SIZE);
+ if (pageSize != -1)
+ {
+ *val = *val * pageSize;
+ result = true;
+ }
+ }
+ }
+
+ if (file)
+ fclose(file);
+ free(line);
+ return result;
+}
diff --git a/src/gc/unix/gcenv.unix.cpp b/src/gc/unix/gcenv.unix.cpp
index 34a45b3cc1..45489c69a7 100644
--- a/src/gc/unix/gcenv.unix.cpp
+++ b/src/gc/unix/gcenv.unix.cpp
@@ -78,6 +78,11 @@ static uint8_t g_helperPage[OS_PAGE_SIZE] __attribute__((aligned(OS_PAGE_SIZE)))
// Mutex to make the FlushProcessWriteBuffersMutex thread safe
static pthread_mutex_t g_flushProcessWriteBuffersMutex;
+size_t GetRestrictedPhysicalMemoryLimit();
+bool GetWorkingSetSize(size_t* val);
+
+static size_t g_RestrictedPhysicalMemoryLimit = 0;
+
// Initialize the interface implementation
// Return:
// true if it has succeeded, false if it has failed
@@ -442,6 +447,18 @@ size_t GCToOSInterface::GetVirtualMemoryLimit()
// specified, it returns amount of actual physical memory.
uint64_t GCToOSInterface::GetPhysicalMemoryLimit()
{
+ size_t restricted_limit;
+ // The limit was not cached
+ if (g_RestrictedPhysicalMemoryLimit == 0)
+ {
+ restricted_limit = GetRestrictedPhysicalMemoryLimit();
+ VolatileStore(&g_RestrictedPhysicalMemoryLimit, restricted_limit);
+ }
+ restricted_limit = g_RestrictedPhysicalMemoryLimit;
+
+ if (restricted_limit != 0 && restricted_limit != SIZE_T_MAX)
+ return restricted_limit;
+
long pages = sysconf(_SC_PHYS_PAGES);
if (pages == -1)
{
@@ -471,14 +488,14 @@ void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available
uint64_t available = 0;
uint32_t load = 0;
+ size_t used;
// Get the physical memory in use - from it, we can get the physical memory available.
// We do this only when we have the total physical memory available.
- if (total > 0)
+ if (total > 0 && GetWorkingSetSize(&used))
{
- available = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGE_SIZE);
- uint64_t used = total - available;
- load = (uint32_t)((used * 100) / total);
+ available = total > used ? total-used : 0;
+ load = (uint32_t)(((float)used * 100) / (float)total);
}
if (memory_load != nullptr)
diff --git a/src/gc/windows/gcenv.windows.cpp b/src/gc/windows/gcenv.windows.cpp
index a636478245..30232bfb09 100644
--- a/src/gc/windows/gcenv.windows.cpp
+++ b/src/gc/windows/gcenv.windows.cpp
@@ -597,6 +597,9 @@ bool GCToOSInterface::CreateThread(GCThreadFunction function, void* param, GCThr
::SetThreadAffinityMask(gc_thread, (DWORD_PTR)1 << affinity->Processor);
}
+ ResumeThread(gc_thread);
+ CloseHandle(gc_thread);
+
return true;
}
diff --git a/src/gcdump/i386/gcdumpx86.cpp b/src/gcdump/i386/gcdumpx86.cpp
index 23e6c6834b..9096085f18 100644
--- a/src/gcdump/i386/gcdumpx86.cpp
+++ b/src/gcdump/i386/gcdumpx86.cpp
@@ -452,7 +452,10 @@ size_t GCDump::DumpGCTable(PTR_CBYTE table,
/* non-ptr arg push */
curOffs += (val & 0x07);
+#ifndef UNIX_X86_ABI
+ // For x86/Linux, non-ptr arg pushes can be reported even for EBP frames
_ASSERTE(!header.ebpFrame);
+#endif // UNIX_X86_ABI
argCnt++;
DumpEncoding(bp, table-bp); bp = table;
diff --git a/src/ilasm/asmman.cpp b/src/ilasm/asmman.cpp
index dba481faf2..0f0d1cff71 100644
--- a/src/ilasm/asmman.cpp
+++ b/src/ilasm/asmman.cpp
@@ -10,9 +10,6 @@
#include "assembler.h"
#include "strongname.h"
-#ifndef FEATURE_CORECLR
-#include "LegacyActivationShim.h"
-#endif
#include <limits.h>
#include <fusion.h>
@@ -153,78 +150,6 @@ void AsmMan::SetModuleName(__inout_opt __nullterminated char* szName)
}
}
//==============================================================================================================
-// Borrowed from VM\assembly.cpp
-#ifndef FEATURE_CORECLR
-HRESULT GetHash(__in LPWSTR moduleName,
- ALG_ID iHashAlg,
- BYTE** pbCurrentValue, // should be NULL
- DWORD *cbCurrentValue)
-{
- HRESULT hr = E_FAIL;
- HCRYPTPROV hProv = 0;
- HCRYPTHASH hHash = 0;
- DWORD dwCount = sizeof(DWORD);
- PBYTE pbBuffer = NULL;
- DWORD dwBufferLen;
- HANDLE hFile = INVALID_HANDLE_VALUE;
- HANDLE hMapFile = NULL;
-
- hFile = WszCreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ,
- 0, OPEN_EXISTING, 0, 0);
- if (hFile == INVALID_HANDLE_VALUE) return E_FAIL;
-
- dwBufferLen = SafeGetFileSize(hFile,NULL);
- if (dwBufferLen == 0xffffffff)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto exit;
- }
- hMapFile = WszCreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
- if (hMapFile == NULL) goto exit;
-
- pbBuffer = (PBYTE) MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
- if (pbBuffer == NULL) goto exit;
-
- // No need to late bind this stuff, all these crypto API entry points happen
- // to live in ADVAPI32.
-
- if ((!WszCryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) ||
- (!CryptCreateHash(hProv, iHashAlg, 0, 0, &hHash)) ||
- (!CryptHashData(hHash, pbBuffer, dwBufferLen, 0)) ||
- (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *) cbCurrentValue,
- &dwCount, 0))) {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto exit;
- }
-
- *pbCurrentValue = new BYTE[*cbCurrentValue];
- if (!(*pbCurrentValue)) {
- hr = E_OUTOFMEMORY;
- goto exit;
- }
-
- if(!CryptGetHashParam(hHash, HP_HASHVAL, *pbCurrentValue, cbCurrentValue, 0)) {
- hr = HRESULT_FROM_WIN32(GetLastError());
- delete[] *pbCurrentValue;
- *pbCurrentValue = 0;
- goto exit;
- }
-
- hr = S_OK;
-
- exit:
- if (pbBuffer) UnmapViewOfFile(pbBuffer);
- if (hMapFile) CloseHandle(hMapFile);
- CloseHandle(hFile);
- if (hHash)
- CryptDestroyHash(hHash);
- if (hProv)
- CryptReleaseContext(hProv, 0);
-
- return hr;
-}
-#endif // !FEATURE_CORECLR
-//==============================================================================================================
void AsmMan::AddFile(__in __nullterminated char* szName, DWORD dwAttr, BinStr* pHashBlob)
{
@@ -277,13 +202,6 @@ void AsmMan::EmitFiles()
if(m_pAssembly // and assembly is defined
&& m_pAssembly->ulHashAlgorithm) // and hash algorithm is defined...
{ // then try to compute it
-#ifndef FEATURE_CORECLR
- if(SUCCEEDED(GetHash(wzUniBuf,(ALG_ID)(m_pAssembly->ulHashAlgorithm),&pHash,&cbHash)))
- {
- tmp->pHash = new BinStr(pHash,cbHash);
- }
- else
-#endif // !FEATURE_CORECLR
{
pHash = NULL;
cbHash = 0;
@@ -449,145 +367,6 @@ void AsmMan::EndAssembly()
m_pCurAsmRef = NULL;
return;
}
-#ifndef FEATURE_CORECLR
- if(m_pCurAsmRef->isAutodetect)
- {
- IAssemblyName* pIAsmName;
- HRESULT hr;
- // Convert name to Unicode
- WszMultiByteToWideChar(g_uCodePage,0,m_pCurAsmRef->szName,-1,wzUniBuf,dwUniBuf);
- hr = CreateAssemblyNameObject(&pIAsmName,wzUniBuf,CANOF_PARSE_DISPLAY_NAME,NULL);
- if(SUCCEEDED(hr))
- {
- // set enumeration criteria: what is known about AsmRef (besides name)
- if(m_pCurAsmRef->usVerMajor != (USHORT)0xFFFF)
- pIAsmName->SetProperty(ASM_NAME_MAJOR_VERSION,&(m_pCurAsmRef->usVerMajor),2);
- if(m_pCurAsmRef->usVerMinor != (USHORT)0xFFFF)
- pIAsmName->SetProperty(ASM_NAME_MINOR_VERSION,&(m_pCurAsmRef->usVerMinor),2);
- if(m_pCurAsmRef->usBuild != (USHORT)0xFFFF)
- pIAsmName->SetProperty(ASM_NAME_BUILD_NUMBER,&(m_pCurAsmRef->usBuild),2);
- if(m_pCurAsmRef->usRevision != (USHORT)0xFFFF)
- pIAsmName->SetProperty(ASM_NAME_REVISION_NUMBER,&(m_pCurAsmRef->usRevision),2);
- if(m_pCurAsmRef->pPublicKeyToken)
- pIAsmName->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN,
- m_pCurAsmRef->pPublicKeyToken->ptr(),
- m_pCurAsmRef->pPublicKeyToken->length());
- if(m_pCurAsmRef->pLocale)
- pIAsmName->SetProperty(ASM_NAME_CULTURE,
- m_pCurAsmRef->pLocale->ptr(),
- m_pCurAsmRef->pLocale->length());
-
- // enumerate assemblies
- IAssemblyEnum* pIAsmEnum = NULL;
- hr = CreateAssemblyEnum(&pIAsmEnum, NULL, pIAsmName, ASM_CACHE_GAC, NULL);
- if(SUCCEEDED(hr))
- {
- IAssemblyName* pIAsmNameFound;
- IAssemblyName* pIAsmNameLatestVer = NULL;
- ULONGLONG ullVer=0, ullVerLatest=0;
- DWORD dwVerHi, dwVerLo;
-
- // find the latest and greatest, if any
- for(;;)
- {
- pIAsmNameFound = NULL;
- hr = pIAsmEnum->GetNextAssembly(NULL,&pIAsmNameFound,0);
- if(SUCCEEDED(hr) && pIAsmNameFound)
- {
-
- pIAsmNameFound->GetVersion(&dwVerHi,&dwVerLo);
- ullVer = (ULONGLONG)dwVerHi;
- ullVer <<= sizeof(DWORD);
- ullVer |= dwVerLo;
- if(ullVer > ullVerLatest)
- {
- if(pIAsmNameLatestVer)
- pIAsmNameLatestVer->Release();
- ullVerLatest = ullVer;
- pIAsmNameLatestVer = pIAsmNameFound;
- }
- else
- pIAsmNameFound->Release();
- }
- else break;
- }
- // if found, fill the gaps
- if(pIAsmNameLatestVer)
- {
- DWORD cbSize=0;
- USHORT usDummy=0;
-
- if(m_pCurAsmRef->pPublicKeyToken == NULL)
- {
- cbSize = 1024;
- pIAsmNameLatestVer->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN,
- wzUniBuf, &cbSize);
- if(cbSize)
- {
- if((m_pCurAsmRef->pPublicKeyToken = new BinStr()))
- memcpy(m_pCurAsmRef->pPublicKeyToken->getBuff(cbSize),
- wzUniBuf, cbSize);
- }
- }
-
- if(m_pCurAsmRef->usVerMajor == (USHORT)0xFFFF)
- {
- cbSize = (DWORD)sizeof(WORD);
- pIAsmNameLatestVer->GetProperty(ASM_NAME_MAJOR_VERSION,
- &usDummy, &cbSize);
- m_pCurAsmRef->usVerMajor = usDummy;
- }
- if(m_pCurAsmRef->usVerMinor == (USHORT)0xFFFF)
- {
- cbSize = (DWORD)sizeof(WORD);
- pIAsmNameLatestVer->GetProperty(ASM_NAME_MINOR_VERSION,
- &usDummy, &cbSize);
- m_pCurAsmRef->usVerMinor = usDummy;
- }
- if(m_pCurAsmRef->usBuild == (USHORT)0xFFFF)
- {
- cbSize = (DWORD)sizeof(WORD);
- pIAsmNameLatestVer->GetProperty(ASM_NAME_BUILD_NUMBER,
- &usDummy, &cbSize);
- m_pCurAsmRef->usBuild = usDummy;
- }
- if(m_pCurAsmRef->usRevision == (USHORT)0xFFFF)
- {
- cbSize = (DWORD)sizeof(WORD);
- pIAsmNameLatestVer->GetProperty(ASM_NAME_REVISION_NUMBER,
- &usDummy, &cbSize);
- m_pCurAsmRef->usRevision = usDummy;
- }
-
- if(m_pCurAsmRef->pLocale == NULL)
- {
- cbSize = 1024;
- pIAsmNameLatestVer->GetProperty(ASM_NAME_CULTURE,
- wzUniBuf, &cbSize);
-
- if(cbSize > (DWORD)sizeof(WCHAR))
- {
- if((m_pCurAsmRef->pLocale = new BinStr()))
- memcpy(m_pCurAsmRef->pLocale->getBuff(cbSize),
- wzUniBuf, cbSize);
- }
- }
- pIAsmNameLatestVer->Release();
- }
- else
- report->warn("Failed to autodetect assembly '%s'\n",m_pCurAsmRef->szName);
- // if no assembly found, leave it as is, it might be not a GAC assembly
-
- pIAsmEnum->Release();
- }
- else
- report->error("Failed to enum assemblies %S, hr=0x%08X\n",wzUniBuf,hr);
- pIAsmName->Release();
- }
- else
- report->error("Failed to create assembly name object for %S, hr=0x%08X\n",wzUniBuf,hr);
- } // end if isAutodetect
-#endif // !FEATURE_CORECLR
m_AsmRefLst.PUSH(m_pCurAsmRef);
m_pCurAsmRef->tkTok = TokenFromRid(m_AsmRefLst.COUNT(),mdtAssemblyRef);
}
@@ -608,29 +387,9 @@ void AsmMan::EndAssembly()
// character of the source ('@' for container).
if (*(((Assembler*)m_pAssembler)->m_wzKeySourceName) == L'@')
{
-#ifdef FEATURE_CORECLR
report->error("Error: ilasm on CoreCLR does not support getting public key from container.\n");
m_pCurAsmRef = NULL;
return;
-#else
- // Extract public key from container (works whether
- // container has just a public key or an entire key
- // pair).
- m_sStrongName.m_wzKeyContainer = &((Assembler*)m_pAssembler)->m_wzKeySourceName[1];
- if (FAILED(hr = LegacyActivationShim::StrongNameGetPublicKey_HRESULT(
- m_sStrongName.m_wzKeyContainer,
- NULL,
- 0,
- &m_sStrongName.m_pbPublicKey,
- &m_sStrongName.m_cbPublicKey)))
- {
- report->error("Failed to extract public key from '%S': 0x%08X\n",m_sStrongName.m_wzKeyContainer,hr);
- m_pCurAsmRef = NULL;
- return;
- }
- m_sStrongName.m_fFullSign = TRUE;
- m_sStrongName.m_dwPublicKeyAllocated = AsmManStrongName::AllocatedBySNApi;
-#endif // FEATURE_CORECLR
}
else
{
@@ -696,33 +455,9 @@ void AsmMan::EndAssembly()
// from a consistent place.
if (m_sStrongName.m_fFullSign)
{
-#ifdef FEATURE_CORECLR
report->error("Error: ilasm on CoreCLR does not support full sign.\n");
m_pCurAsmRef = NULL;
return;
-#else
- m_sStrongName.m_pbPrivateKey = m_sStrongName.m_pbPublicKey;
- m_sStrongName.m_cbPrivateKey = m_sStrongName.m_cbPublicKey;
-
- m_sStrongName.m_pbPublicKey = NULL;
- m_sStrongName.m_cbPublicKey = NULL;
- m_sStrongName.m_dwPublicKeyAllocated = AsmManStrongName::NotAllocated;
-
- // Retrieve the public key portion as a byte blob.
- if (FAILED(hr = LegacyActivationShim::StrongNameGetPublicKey_HRESULT(
- NULL,
- m_sStrongName.m_pbPrivateKey,
- m_sStrongName.m_cbPrivateKey,
- &m_sStrongName.m_pbPublicKey,
- &m_sStrongName.m_cbPublicKey)))
- {
- report->error("Failed to extract public key: 0x%08X\n",hr);
- m_pCurAsmRef = NULL;
- return;
- }
-
- m_sStrongName.m_dwPublicKeyAllocated = AsmManStrongName::AllocatedBySNApi;
-#endif // FEATURE_CORECLR
}
}
}
diff --git a/src/ilasm/asmman.hpp b/src/ilasm/asmman.hpp
index 35d8fdc0bc..0ee875b805 100644
--- a/src/ilasm/asmman.hpp
+++ b/src/ilasm/asmman.hpp
@@ -9,9 +9,6 @@
#define ASMMAN_HPP
#include "strongname.h"
-#ifndef FEATURE_CORECLR
-#include "LegacyActivationShim.h"
-#endif
#include "specstrings.h"
struct AsmManFile
@@ -173,13 +170,6 @@ struct AsmManStrongName
AsmManStrongName() { ZeroMemory(this, sizeof(*this)); }
~AsmManStrongName()
{
-#ifndef FEATURE_CORECLR
- if (m_dwPublicKeyAllocated == AllocatedBySNApi)
- {
- LegacyActivationShim::StrongNameFreeBuffer(m_pbPublicKey);
- }
- else
-#endif
if (m_dwPublicKeyAllocated == AllocatedByNew)
delete [] m_pbPublicKey;
diff --git a/src/ilasm/asmtemplates.h b/src/ilasm/asmtemplates.h
index eb2b413abf..b7d3025f02 100644
--- a/src/ilasm/asmtemplates.h
+++ b/src/ilasm/asmtemplates.h
@@ -60,54 +60,6 @@ private:
};
-#if (0)
-template <class T>
-class FIFO
-{
-public:
- inline FIFO() { m_pHead = m_pTail = NULL; m_ulCount = 0;};
- inline ~FIFO() {T *val; while(val = POP()) delete val; };
- void PUSH(T *item)
- {
- m_pTemp = new LIST_EL <T>(item);
- if(m_pTail) m_pTail->m_Next = m_pTemp;
- m_pTail = m_pTemp;
- if(m_pHead == NULL) m_pHead = m_pTemp;
- m_ulCount++;
- };
- T* POP()
- {
- T* ret = NULL;
- if(m_pTemp = m_pHead)
- {
- m_pHead = m_pHead->m_Next;
- ret = m_pTemp->m_Ptr;
- delete m_pTemp;
- if(m_pHead == NULL) m_pTail = NULL;
- m_ulCount--;
- }
- return ret;
- };
- ULONG COUNT() { return m_ulCount; };
- T* PEEK(ULONG idx)
- {
- T* ret = NULL;
- ULONG i;
- if(idx < m_ulCount)
- {
- if(idx == m_ulCount-1) m_pTemp = m_pTail;
- else for(m_pTemp = m_pHead, i = 0; i < idx; m_pTemp = m_pTemp->m_Next, i++);
- ret = m_pTemp->m_Ptr;
- }
- return ret;
- };
-private:
- LIST_EL <T> *m_pHead;
- LIST_EL <T> *m_pTail;
- LIST_EL <T> *m_pTemp;
- ULONG m_ulCount;
-};
-#else
template <class T>
class FIFO
{
@@ -180,7 +132,6 @@ private:
ULONG m_ulOffset;
ULONG m_ulArrLen;
};
-#endif
template <class T> struct Indx256
diff --git a/src/ilasm/assem.cpp b/src/ilasm/assem.cpp
index 18247621f9..6416dfe5c7 100644
--- a/src/ilasm/assem.cpp
+++ b/src/ilasm/assem.cpp
@@ -231,24 +231,18 @@ Assembler::~Assembler()
m_pDisp = NULL;
}
-#ifdef FEATURE_CORECLR
#ifdef FEATURE_PAL
if (g_loader != NULL)
{
g_loader->Finish();
}
#endif
-#else
- if (m_fDidCoInitialise)
- CoUninitialize();
-#endif // FEATURE_CORECLR
}
BOOL Assembler::Init()
{
-#ifdef FEATURE_CORECLR
#ifdef FEATURE_PAL
g_loader = CoreCLRLoader::Create(g_pszExeFile);
if (g_loader == NULL)
@@ -259,14 +253,6 @@ BOOL Assembler::Init()
#else
metaDataGetDispenser = (MetaDataGetDispenserFunc)MetaDataGetDispenser;
#endif // FEATURE_PAL
-#else
- if(!m_fDidCoInitialise)
- {
- if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED)))
- return FALSE;
- m_fDidCoInitialise = TRUE;
- }
-#endif // FEATURE_CORECLR
if (m_pCeeFileGen != NULL) {
if (m_pCeeFile)
m_pCeeFileGen->DestroyCeeFile(&m_pCeeFile);
diff --git a/src/ilasm/assembler.cpp b/src/ilasm/assembler.cpp
index 49d4ee9712..957b0bd22b 100644
--- a/src/ilasm/assembler.cpp
+++ b/src/ilasm/assembler.cpp
@@ -99,17 +99,6 @@ mdToken Assembler::ResolveClassRef(mdToken tkResScope, __in __nullterminated con
mdToken *ptkSpecial = NULL;
if(pszFullClassName == NULL) return mdTokenNil;
-#if (0)
- if (m_fInitialisedMetaData == FALSE)
- {
- if (FAILED(InitMetaData())) // impl. see WRITER.CPP
- {
- _ASSERTE(0);
- if(ppClass) *ppClass = NULL;
- return mdTokenNil;
- }
- }
-#endif
switch(strlen(pszFullClassName))
{
@@ -287,11 +276,16 @@ mdToken Assembler::GetAsmRef(__in __nullterminated const char* szName)
mdToken Assembler::GetBaseAsmRef()
{
- if(RidFromToken(m_pManifest->GetAsmRefTokByName("System.Runtime")) != 0)
+ if (RidFromToken(m_pManifest->GetAsmRefTokByName("System.Runtime")) != 0)
{
return GetAsmRef("System.Runtime");
}
+ if (RidFromToken(m_pManifest->GetAsmRefTokByName("netstandard")) != 0)
+ {
+ return GetAsmRef("netstandard");
+ }
+
return GetAsmRef("mscorlib");
}
@@ -2213,26 +2207,6 @@ void Assembler::EmitBytes(BYTE *p, unsigned len)
BinStr* Assembler::EncodeSecAttr(__in __nullterminated char* szReflName, BinStr* pbsSecAttrBlob, unsigned nProps)
{
unsigned cnt;
-#if (0)
- // Emit MemberRef for .ctor
- mdToken tkMscorlib = m_fIsMscorlib ? 1 : GetAsmRef("mscorlib");
- char buffer[64];
- BinStr *pbsSig = new BinStr();
-
- strcpy(buffer,"System.Security.Permissions.SecurityAction");
- mdToken tkSecAction = ResolveClassRef(tkMscorlib,buffer, NULL);
-
- pbsSig->appendInt8(IMAGE_CEE_CS_CALLCONV_HASTHIS);
- pbsSig->appendInt8(1); //corEmitInt(pbsSig,1);
- pbsSig->appendInt8(ELEMENT_TYPE_VOID);
- pbsSig->appendInt8(ELEMENT_TYPE_VALUETYPE);
- cnt = CorSigCompressToken(tkSecAction, pbsSig->getBuff(5));
- pbsSig->remove(5 - cnt);
-
- char* szName = new char[16];
- strcpy(szName,".ctor");
- MakeMemberRef(tkSecAttr,szName,pbsSig);
-#endif
// build the blob As BinStr
unsigned L = (unsigned) strlen(szReflName);
diff --git a/src/ilasm/assembler.h b/src/ilasm/assembler.h
index 1c211bc3c5..39fadd55ca 100644
--- a/src/ilasm/assembler.h
+++ b/src/ilasm/assembler.h
@@ -1049,12 +1049,10 @@ public:
void EmitSecurityInfo(mdToken token,
PermissionDecl* pPermissions,
PermissionSetDecl*pPermissionSets);
-#ifndef FEATURE_CORECLR
- HRESULT AllocateStrongNameSignature();
- HRESULT StrongNameSign();
-#endif
BinStr* EncodeSecAttr(__in __nullterminated char* szReflName, BinStr* pbsSecAttrBlob, unsigned nProps);
+ HRESULT AllocateStrongNameSignature();
+
// Custom values paraphernalia:
public:
mdToken m_tkCurrentCVOwner;
@@ -1189,9 +1187,6 @@ public:
unsigned NumTypeDefs() {return m_TypeDefDList.COUNT();};
private:
HRESULT GetCAName(mdToken tkCA, __out LPWSTR *ppszName);
-#ifndef FEATURE_CORECLR
- HRESULT GetSignatureKey();
-#endif
};
#endif // Assember_h
diff --git a/src/ilasm/grammar_after.cpp b/src/ilasm/grammar_after.cpp
index c8634801c7..53d141db54 100644
--- a/src/ilasm/grammar_after.cpp
+++ b/src/ilasm/grammar_after.cpp
@@ -372,16 +372,6 @@ static void AppendStringWithLength(BinStr* pbs, __in __nullterminated char* sz)
/* fetch the next token, and return it Also set the yylval.union if the
lexical token also has a value */
-#if (0)
-
-#define IsAlpha(x) ((('A' <= (x))&&((x) <= 'Z'))||(('a' <= (x))&&((x) <= 'z')))
-#define IsDigit(x) (('0' <= (x))&&((x) <= '9'))
-#define IsAlNum(x) (IsAlpha(x) || IsDigit(x))
-#define IsValidStartingSymbol(x) (IsAlpha(x)||((x)=='#')||((x)=='_')||((x)=='@')||((x)=='$'))
-#define IsValidContinuingSymbol(x) (IsAlNum(x)||((x)=='_')||((x)=='@')||((x)=='$')||((x)=='?'))
-void SetSymbolTables() { ; }
-
-#else
BOOL _Alpha[128];
BOOL _Digit[128];
@@ -433,7 +423,6 @@ BOOL IsAlNum(unsigned x) { return (x < 128)&&_AlNum[x]; }
BOOL IsValidStartingSymbol(unsigned x) { return (x < 128)&&_ValidSS[x]; }
BOOL IsValidContinuingSymbol(unsigned x) { return (x < 128)&&_ValidCS[x]; }
-#endif
char* nextBlank(__in __nullterminated char* curPos)
{
@@ -865,7 +854,6 @@ Its_An_Id:
TRUE, wzFullName,&pwz);
if(dw != 0)
{
- wzFullName.CloseBuffer((COUNT_T)(dw));
delete [] wzFile;
wzFile = wzFullName.GetCopyOfUnicodeString();
diff --git a/src/ilasm/grammar_before.cpp b/src/ilasm/grammar_before.cpp
index 42d2927fa5..dd30416bae 100644
--- a/src/ilasm/grammar_before.cpp
+++ b/src/ilasm/grammar_before.cpp
@@ -29,17 +29,6 @@ static AsmParse* parser = 0;
#define PASMM (parser->assem->m_pManifest)
#define PENV (parser->penv)
-#if (0)
-
-#define nextchar parser->penv->pfn_nextchar
-#define Sym parser->penv->pfn_Sym
-#define NewStrFromToken parser->penv->pfn_NewStrFromToken
-#define NewStaticStrFromToken parser->penv->pfn_NewStaticStrFromToken
-#define GetDouble parser->penv->pfn_GetDouble
-
-void SetFunctionPtrs() {;}
-
-#else
PFN_NEXTCHAR nextchar;
@@ -57,7 +46,6 @@ void SetFunctionPtrs()
GetDouble = PENV->pfn_GetDouble;
}
-#endif
static char* newStringWDel(__in __nullterminated char* str1, char delimiter, __in __nullterminated char* str3 = 0);
static char* newString(__in __nullterminated const char* str1);
diff --git a/src/ilasm/main.cpp b/src/ilasm/main.cpp
index 2bef40dd47..29a24b0203 100644
--- a/src/ilasm/main.cpp
+++ b/src/ilasm/main.cpp
@@ -106,7 +106,6 @@ extern "C" int _cdecl wmain(int argc, __in WCHAR **argv)
{
int i, NumFiles = 0, NumDeltaFiles = 0;
bool IsDLL = false, IsOBJ = false;
- char szOpt[128];
Assembler *pAsm;
MappedFileStream *pIn;
AsmParse *pParser;
@@ -224,14 +223,13 @@ extern "C" int _cdecl wmain(int argc, __in WCHAR **argv)
if((argv[i][0] == L'/') || (argv[i][0] == L'-'))
#endif
{
- memset(szOpt,0,sizeof(szOpt));
- WszWideCharToMultiByte(uCodePage,0,&argv[i][1],-1,szOpt,sizeof(szOpt),NULL,NULL);
- szOpt[3] = 0;
- if (!_stricmp(szOpt,"NOA"))
+ char szOpt[3 + 1] = { 0 };
+ WszWideCharToMultiByte(uCodePage, 0, &argv[i][1], 3, szOpt, sizeof(szOpt), NULL, NULL);
+ if (!_stricmp(szOpt, "NOA"))
{
pAsm->m_fAutoInheritFromObject = FALSE;
}
- else if (!_stricmp(szOpt,"QUI"))
+ else if (!_stricmp(szOpt, "QUI"))
{
pAsm->m_fReportProgress = FALSE;
bReportProgress = FALSE;
@@ -248,12 +246,8 @@ extern "C" int _cdecl wmain(int argc, __in WCHAR **argv)
else if (!_stricmp(szOpt, "DEB"))
{
pAsm->m_dwIncludeDebugInfo = 0x101;
-#ifdef FEATURE_CORECLR
// PDB is ignored under 'DEB' option for ilasm on CoreCLR.
// https://github.com/dotnet/coreclr/issues/2982
-#else
- pAsm->m_fGeneratePDB = TRUE;
-#endif
bNoDebug = FALSE;
WCHAR *pStr = EqualOrColon(argv[i]);
@@ -281,12 +275,8 @@ extern "C" int _cdecl wmain(int argc, __in WCHAR **argv)
}
else if (!_stricmp(szOpt, "PDB"))
{
-#ifdef FEATURE_CORECLR
// 'PDB' option is ignored for ilasm on CoreCLR.
// https://github.com/dotnet/coreclr/issues/2982
-#else
- pAsm->m_fGeneratePDB = TRUE;
-#endif
bNoDebug = FALSE;
}
else if (!_stricmp(szOpt, "CLO"))
@@ -746,21 +736,8 @@ extern "C" int _cdecl wmain(int argc, __in WCHAR **argv)
exitval = 1;
pParser->msg("Failed to write output file, error code=0x%08X\n",hr);
}
-#ifndef FEATURE_CORECLR
- else if (pAsm->m_pManifest->m_sStrongName.m_fFullSign)
- {
- // Strong name sign the resultant assembly.
- if(pAsm->m_fReportProgress) pParser->msg("Signing file with strong name\n");
- if (FAILED(hr=pAsm->StrongNameSign()))
- {
- exitval = 1;
- pParser->msg("Failed to strong name sign output file, error code=0x%08X\n",hr);
- }
- }
-#endif
if(bClock) cw.cEnd = GetTickCount();
#define ENC_ENABLED
-#ifdef ENC_ENABLED
if(exitval==0)
{
pAsm->m_fENCMode = TRUE;
@@ -857,7 +834,6 @@ extern "C" int _cdecl wmain(int argc, __in WCHAR **argv)
}
} // end for(iFile)
} // end if(exitval==0)
-#endif
}
}
@@ -922,12 +898,6 @@ extern "C" int _cdecl wmain(int argc, __in WCHAR **argv)
#pragma warning(pop)
#endif
-#ifndef FEATURE_CORECLR
-HINSTANCE GetModuleInst()
-{
- return (NULL);
-}
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_PAL
int main(int argc, char* str[])
diff --git a/src/ilasm/method.cpp b/src/ilasm/method.cpp
index 18f6c47b00..8fc300c23a 100644
--- a/src/ilasm/method.cpp
+++ b/src/ilasm/method.cpp
@@ -93,16 +93,6 @@ void Method::OpenScope()
{
psc->dwStart = m_pAssembler->m_CurPC;
psc->pSuperScope = m_pCurrScope;
-#if(0)
- LinePC *pLPC = new LinePC;
- if(pLPC)
- {
- pLPC->Line = m_pAssembler->m_ulCurLine;
- pLPC->Column = m_pAssembler->m_ulCurColumn;
- pLPC->PC = m_pAssembler->m_CurPC;
- m_LinePCList.PUSH(pLPC);
- }
-#endif
m_pCurrScope->SubScope.PUSH(psc);
m_pCurrScope = psc;
}
@@ -116,16 +106,6 @@ void Method::CloseScope()
if((pVD = m_Locals.PEEK(pAN->dwAttr))) pVD->bInScope = FALSE;
}
m_pCurrScope->dwEnd = m_pAssembler->m_CurPC;
-#if(0)
- LinePC *pLPC = new LinePC;
- if(pLPC)
- {
- pLPC->Line = m_pAssembler->m_ulCurLine;
- pLPC->Column = m_pAssembler->m_ulCurColumn;
- pLPC->PC = m_pAssembler->m_CurPC;
- m_LinePCList.PUSH(pLPC);
- }
-#endif
m_pCurrScope = m_pCurrScope->pSuperScope;
}
diff --git a/src/ilasm/writer.cpp b/src/ilasm/writer.cpp
index b5b87ce1ad..624c474bde 100644
--- a/src/ilasm/writer.cpp
+++ b/src/ilasm/writer.cpp
@@ -10,10 +10,6 @@
#include "assembler.h"
#include "ceefilegenwriter.h"
-#ifndef FEATURE_CORECLR
-#include "strongname.h"
-#include "LegacyActivationShim.h"
-#endif
#ifndef _MSC_VER
//cloned definition from ntimage.h that is removed for non MSVC builds
@@ -34,17 +30,8 @@ HRESULT Assembler::InitMetaData()
if(bClock) bClock->cMDInitBegin = GetTickCount();
-#ifdef FEATURE_CORECLR
hr = metaDataGetDispenser(CLSID_CorMetaDataDispenser,
IID_IMetaDataDispenserEx, (void **)&m_pDisp);
-#else
- hr = LegacyActivationShim::ClrCoCreateInstance(
- CLSID_CorMetaDataDispenser,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_IMetaDataDispenserEx,
- (void **)&m_pDisp);
-#endif
if (FAILED(hr))
goto exit;
@@ -66,25 +53,6 @@ HRESULT Assembler::InitMetaData()
if(FAILED(hr = m_pEmitter->QueryInterface(IID_IMetaDataImport2, (void**)&m_pImporter)))
goto exit;
-#ifndef FEATURE_CORECLR
- hr = CoCreateInstance(CLSID_CorSymWriter_SxS,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_ISymUnmanagedWriter,
- (void **)&m_pSymWriter);
- if(SUCCEEDED(hr))
- {
- if(m_pSymWriter) m_pSymWriter->Initialize((IUnknown*)m_pEmitter,
- m_wzOutputFileName,
- NULL,
- TRUE);
- }
- else
- {
- fprintf(stderr, "Error: QueryInterface(IID_ISymUnmanagedWriter) returns %X\n",hr);
- m_pSymWriter = NULL;
- }
-#endif // !FEATURE_CORECLR
//m_Parser = new AsmParse(m_pEmitter);
m_fInitialisedMetaData = TRUE;
@@ -687,197 +655,6 @@ BYTE HexToByte (CHAR wc)
return (BYTE) (wc - L'a' + 10);
}
-#ifndef FEATURE_CORECLR
-bool GetBytesFromHex (LPCSTR szPublicKeyHexString, ULONG cchPublicKeyHexString, BYTE** buffer, ULONG *cbBufferSize)
-{
- ULONG cchHex = cchPublicKeyHexString;
- if (cchHex % 2 != 0)
- return false;
- *cbBufferSize = cchHex / 2;
-
- *buffer = new BYTE[*cbBufferSize];
- if (!*buffer)
- return false;
-
- for (ULONG i = 0; i < *cbBufferSize; i++)
- {
- BYTE msn = HexToByte(*szPublicKeyHexString);
- BYTE lsn = HexToByte(*(szPublicKeyHexString + 1));
- if (msn == 0xFF || lsn == 0xFF)
- {
- delete[] *buffer;
- return false;
- }
-
- (*buffer)[i] = (BYTE) ( (msn << 4) | lsn );
- szPublicKeyHexString += 2;
- }
-
- return true;
-}
-
-HRESULT Assembler::GetSignatureKey()
-{
- HRESULT hr = S_OK;
- ULONG cbSize = 0;
- void * pvData = NULL;
- LPWSTR pName = NULL;
-
- CustomDescrList* pCDList = &m_pManifest->m_pAssembly->m_CustomDescrList;
-
- for (ULONG i = 0;i < pCDList->COUNT(); i++)
- {
- CustomDescr* pCD = pCDList->PEEK(i);
-
- if(pCD->pBlob)
- {
- pvData = (void *)(pCD->pBlob->ptr());
- cbSize = pCD->pBlob->length();
- pCD->tkOwner = m_pManifest->m_pAssembly->tkTok;
- mdToken tkOwnerType, tkTypeType = TypeFromToken(pCD->tkType);
-
- if (GetCAName(pCD->tkType, &pName) != S_OK)
- continue;
-
- if (wcscmp(pName, L"System.Reflection.AssemblySignatureKeyAttribute") == 0)
- {
- if (cbSize < sizeof(WORD) || GET_UNALIGNED_VAL16(pvData) != 1)
- {
- hr = E_FAIL;
- break;;
- }
- pvData = (unsigned char *)pvData + sizeof(WORD);
- cbSize -= sizeof(WORD);
-
- // String is stored as compressed length, UTF8.
- if (*(const BYTE*)pvData != 0xFF)
- {
- PCCOR_SIGNATURE sig = (PCCOR_SIGNATURE)pvData;
- cbSize -= CorSigUncompressedDataSize(sig);
- DWORD len = CorSigUncompressData(sig);
- pvData = (void *)sig;
- if (cbSize < len)
- {
- hr = E_FAIL;
- break;
- }
-
- AsmManStrongName *pSN = &m_pManifest->m_sStrongName;
- GetBytesFromHex((LPCSTR)pvData, len, &pSN->m_pbSignatureKey, &pSN->m_cbSignatureKey);
- }
-
- break;
- }
-
- if (pName)
- {
- delete pName;
- pName = NULL;
- }
- }
- }
-
- if (pName)
- delete pName;
- return hr;
-}
-
-HRESULT Assembler::AllocateStrongNameSignature()
-{
- HRESULT hr = S_OK;
- HCEESECTION hSection;
- DWORD dwDataLength;
- DWORD dwDataOffset;
- DWORD dwDataRVA;
- VOID *pvBuffer;
- AsmManStrongName *pSN = &m_pManifest->m_sStrongName;
-
- // Pulls the AssemblySignatureKey attribute from m_CustomDescrList
- // If present, populate the pSN->m_pbSignatureKey from the AssemblySignatureKeyAttribute blob
- if (FAILED(hr = GetSignatureKey()))
- {
- return hr;
- }
-
- // Determine size of signature blob.
- if (pSN->m_pbSignatureKey != NULL)
- {
- // If m_pbSignatureKey present use it, else fall back to using identity key.
- if (FAILED(hr = LegacyActivationShim::StrongNameSignatureSize_HRESULT(
- pSN->m_pbSignatureKey,
- pSN->m_cbSignatureKey,
- &dwDataLength)))
- {
- return hr;
- }
- }
- else if (FAILED(hr = LegacyActivationShim::StrongNameSignatureSize_HRESULT(
- pSN->m_pbPublicKey,
- pSN->m_cbPublicKey,
- &dwDataLength)))
- {
- return hr;
- }
-
- // Grab memory in the section for our stuff.
- if (FAILED(hr = m_pCeeFileGen->GetIlSection(m_pCeeFile,
- &hSection)))
- return hr;
-
- if (FAILED(hr = m_pCeeFileGen->GetSectionBlock(hSection,
- dwDataLength,
- 4,
- &pvBuffer)))
- return hr;
-
- // Where did we get that memory?
- if (FAILED(hr = m_pCeeFileGen->GetSectionDataLen(hSection,
- &dwDataOffset)))
- return hr;
-
- dwDataOffset -= dwDataLength;
-
- // Convert to an RVA.
- if (FAILED(hr = m_pCeeFileGen->GetMethodRVA(m_pCeeFile,
- dwDataOffset,
- &dwDataRVA)))
- return hr;
-
- // Emit the directory entry.
- if (FAILED(hr = m_pCeeFileGen->SetStrongNameEntry(m_pCeeFile,
- dwDataLength,
- dwDataRVA)))
- return hr;
-
- return S_OK;
-}
-
-HRESULT Assembler::StrongNameSign()
-{
- LPWSTR wszOutputFile;
- HRESULT hr = S_OK;
- AsmManStrongName *pSN = &m_pManifest->m_sStrongName;
-
- // Determine what the ouput PE was called.
- if (FAILED(hr = m_pCeeFileGen->GetOutputFileName(m_pCeeFile,
- &wszOutputFile)))
- return hr;
-
- // Update the output PE image with a strong name signature.
- if (FAILED(hr = LegacyActivationShim::StrongNameSignatureGeneration_HRESULT(
- wszOutputFile,
- pSN->m_wzKeyContainer,
- pSN->m_pbPrivateKey,
- pSN->m_cbPrivateKey,
- NULL,
- NULL)))
- {
- return hr;
- }
-
- return S_OK;
-}
-#endif // !FEATURE_CORECLR
BOOL Assembler::EmitFieldsMethods(Class* pClass)
{
@@ -1205,6 +982,62 @@ BOOL Assembler::EmitEventsProps(Class* pClass)
return ret;
}
+HRESULT Assembler::AllocateStrongNameSignature()
+{
+ HRESULT hr = S_OK;
+ HCEESECTION hSection;
+ DWORD dwDataLength;
+ DWORD dwDataOffset;
+ DWORD dwDataRVA;
+ VOID *pvBuffer;
+ AsmManStrongName *pSN = &m_pManifest->m_sStrongName;
+
+ // pSN->m_cbPublicKey is the length of the m_pbPublicKey
+ dwDataLength = ((int)pSN->m_cbPublicKey < 128 + 32) ? 128 : (int)pSN->m_cbPublicKey - 32;
+
+ // Grab memory in the section for our stuff.
+ if (FAILED(hr = m_pCeeFileGen->GetIlSection(m_pCeeFile,
+ &hSection)))
+ {
+ return hr;
+ }
+
+ if (FAILED(hr = m_pCeeFileGen->GetSectionBlock(hSection,
+ dwDataLength,
+ 4,
+ &pvBuffer)))
+ {
+ return hr;
+ }
+
+ // Where did we get that memory?
+ if (FAILED(hr = m_pCeeFileGen->GetSectionDataLen(hSection,
+ &dwDataOffset)))
+ {
+ return hr;
+ }
+
+ dwDataOffset -= dwDataLength;
+
+ // Convert to an RVA.
+ if (FAILED(hr = m_pCeeFileGen->GetMethodRVA(m_pCeeFile,
+ dwDataOffset,
+ &dwDataRVA)))
+ {
+ return hr;
+ }
+
+ // Emit the directory entry.
+ if (FAILED(hr = m_pCeeFileGen->SetStrongNameEntry(m_pCeeFile,
+ dwDataLength,
+ dwDataRVA)))
+ {
+ return hr;
+ }
+
+ return S_OK;
+}
+
#ifdef _PREFAST_
#pragma warning(push)
#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
@@ -1231,13 +1064,15 @@ HRESULT Assembler::CreatePEFile(__in __nullterminated WCHAR *pwzOutputFilename)
if(bClock) bClock->cMDEmit1 = GetTickCount();
-#ifndef FEATURE_CORECLR
// Allocate space for a strong name signature if we're delay or full
// signing the assembly.
if (m_pManifest->m_sStrongName.m_pbPublicKey)
+ {
if (FAILED(hr = AllocateStrongNameSignature()))
+ {
goto exit;
-#endif
+ }
+ }
if(bClock) bClock->cMDEmit2 = GetTickCount();
diff --git a/src/ilasm/writer_enc.cpp b/src/ilasm/writer_enc.cpp
index 055b2edca9..eee9c00a0a 100644
--- a/src/ilasm/writer_enc.cpp
+++ b/src/ilasm/writer_enc.cpp
@@ -70,28 +70,6 @@ HRESULT Assembler::InitMetaDataForENC(__in __nullterminated WCHAR* wzOrigFileNam
if(!Init()) goto exit; // close and re-open CeeFileGen and CeeFile
hr = S_OK;
-#ifndef FEATURE_CORECLR
- hr = CoCreateInstance(CLSID_CorSymWriter_SxS,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_ISymUnmanagedWriter,
- (void **)&m_pSymWriter);
- if(SUCCEEDED(hr))
- {
- WCHAR* pwc = &wzOrigFileName[wcslen(wzOrigFileName)];
- wcscat_s(wzOrigFileName,MAX_SCOPE_LENGTH,W(".pdb"));
- if(m_pSymWriter) m_pSymWriter->Initialize((IUnknown*)m_pEmitter,
- wzOrigFileName,
- NULL,
- TRUE);
- *pwc = 0;
- }
- else
- {
- fprintf(stderr, "Error: CoCreateInstance(IID_ISymUnmanagedWriter) returns %X\n",hr);
- m_pSymWriter = NULL;
- }
-#endif
exit:
return hr;
@@ -453,43 +431,6 @@ REPT_STEP
pBaseMDEmit->Release();
}
-#if(0)
-//===================================================================================
- // release SymWriter interfaces
- if (m_pSymWriter != NULL)
- {
- m_pSymWriter->Close();
- m_pSymWriter->Release();
- m_pSymWriter = NULL;
- }
-
- hr = CoCreateInstance(CLSID_CorSymWriter_SxS,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_ISymUnmanagedWriter,
- (void **)&m_pSymWriter);
- if(SUCCEEDED(hr))
- {
- WCHAR* pwc = &pwzOutputFilename[wcslen(pwzOutputFilename)];
- wcscat(pwzOutputFilename,L".pdb");
- if(m_pSymWriter) m_pSymWriter->Initialize((IUnknown*)m_pEmitter,
- pwzOutputFilename,
- NULL,
- TRUE);
- *pwc = 0;
- }
- else
- {
- fprintf(stderr, "Error: CoCreateInstance(IID_ISymUnmanagedWriter) returns %X\n",hr);
- m_pSymWriter = NULL;
- }
-
- m_fENCMode = FALSE;
- if(FAILED(hr=CreatePEFile(pwzOutputFilename)))
- report->msg("Could not create output file, error code=0x%08X\n",hr);
- m_fENCMode = TRUE;
-//=====================================================================================
-#endif
// release all interfaces
if (m_pSymWriter != NULL)
diff --git a/src/ildasm/dasm.cpp b/src/ildasm/dasm.cpp
index 7b6bca926e..3d172f009e 100644
--- a/src/ildasm/dasm.cpp
+++ b/src/ildasm/dasm.cpp
@@ -483,7 +483,7 @@ void Uninit()
{
SDELETE(g_szBuf_UnquotedProperName);
}
- if (g_szBuf_UnquotedProperName != NULL)
+ if (g_szBuf_ProperName != NULL)
{
SDELETE(g_szBuf_ProperName);
}
@@ -4576,36 +4576,6 @@ BOOL DumpClass(mdTypeDef cl, DWORD dwEntryPointToken, void* GUICookie, ULONG Wha
pszClassName = (char*)(pc1 ? pc1 : "");
pszNamespace = (char*)(pc2 ? pc2 : "");
-#if (0)
-
- if((!IsTdNested(dwClassAttrs)))
- {
- // take care of namespace, if any
- if(strcmp(pszNamespace,g_szNamespace))
- {
- if(strlen(g_szNamespace))
- {
- if(g_szAsmCodeIndent[0]) g_szAsmCodeIndent[strlen(g_szAsmCodeIndent)-2] = 0;
- szptr = &szString[0];
- szptr+=sprintf_s(szptr,SZSTRING_SIZE,"%s%s ",g_szAsmCodeIndent,UNSCOPE());
- sprintf_s(szptr,SZSTRING_REMAINING_SIZE(szptr),COMMENT("// end of namespace %s"),ProperName(g_szNamespace));
- printLine(GUICookie,szString);
- printLine(GUICookie,"");
- }
- strcpy_s(g_szNamespace,MAX_MEMBER_LENGTH,pszNamespace);
- if(strlen(g_szNamespace))
- {
- sprintf_s(szString,SZSTRING_SIZE,"%s%s %s",
- g_szAsmCodeIndent,KEYWORD(".namespace"), ProperName(g_szNamespace));
- printLine(GUICookie,szString);
- sprintf_s(szString,SZSTRING_SIZE,"%s%s",g_szAsmCodeIndent,SCOPE());
- printLine(GUICookie,szString);
- strcat_s(g_szAsmCodeIndent,MAX_MEMBER_LENGTH," ");
- }
- }
- }
-
-#endif
szptr = &szString[0];
szptr+=sprintf_s(szptr,SZSTRING_SIZE,"%s%s ",g_szAsmCodeIndent,KEYWORD(".class"));
@@ -7400,6 +7370,13 @@ BOOL DumpFile()
}
CORCOMPILE_HEADER * pNativeHeader;
g_pPELoader->getVAforRVA(VAL32(g_CORHeader->ManagedNativeHeader.VirtualAddress), (void**)&pNativeHeader);
+
+ if (pNativeHeader->Signature != CORCOMPILE_SIGNATURE)
+ {
+ printError( g_pFile, "/native only works on NGen images." );
+ goto exit;
+ }
+
g_pPELoader->getVAforRVA(VAL32(pNativeHeader->ManifestMetaData.VirtualAddress), &g_pMetaData);
g_cbMetaData = VAL32(pNativeHeader->ManifestMetaData.Size);
}
@@ -7571,24 +7548,6 @@ DoneInitialization:
}
}
-#if (0)
- /* Third, dump GC/EH info about the native methods, using the IPMap */
- IMAGE_DATA_DIRECTORY *pIPMap;
- if (g_pPELoader->IsPE32())
- {
- pIPMap = &g_pPELoader->ntHeaders32()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
- }
- else
- {
- pIPMap = &g_pPELoader->ntHeaders64()->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
- }
- DWORD IPMapSize;
- const BYTE * ipmap;
- IPMapSize = VAL32(pIPMap->Size);
- g_pPELoader->getVAforRVA(VAL32(pIPMap->VirtualAddress), (void **) &ipmap);
-
- DumpNativeInfo(ipmap, IPMapSize);
-#endif
// If there were "ldptr", dump the .rdata section with labels
if(g_iPtrCount)
diff --git a/src/inc/CMakeLists.txt b/src/inc/CMakeLists.txt
index d38fa40773..40499b44ea 100644
--- a/src/inc/CMakeLists.txt
+++ b/src/inc/CMakeLists.txt
@@ -9,7 +9,6 @@ set( CORGUIDS_IDL_SOURCES
ivalidator.idl
ivehandler.idl
gchost.idl
- fusionpriv.idl
mscorsvc.idl
tlbimpexp.idl
clrprivappxhosting.idl
diff --git a/src/inc/CrstTypes.def b/src/inc/CrstTypes.def
index bb6e710647..227f986a85 100644
--- a/src/inc/CrstTypes.def
+++ b/src/inc/CrstTypes.def
@@ -778,4 +778,8 @@ End
Crst InlineTrackingMap
AcquiredBefore IbcProfile
-End \ No newline at end of file
+End
+
+Crst EventPipe
+ AcquiredBefore ThreadIdDispenser ThreadStore
+End
diff --git a/src/inc/MSCOREE.IDL b/src/inc/MSCOREE.IDL
index 67605e23d4..97e2f2aca6 100644
--- a/src/inc/MSCOREE.IDL
+++ b/src/inc/MSCOREE.IDL
@@ -10,38 +10,24 @@
** **
**************************************************************************************/
-#ifdef FEATURE_CORECLR
-// API deprecation does not apply to CoreCLR
cpp_quote("#define DECLARE_DEPRECATED ")
cpp_quote("#define DEPRECATED_CLR_STDAPI STDAPI")
-#else // !FEATURE_CORECLR
-// API deprecation is only applicable to Desktop runtime.
-cpp_quote("#ifndef USE_DEPRECATED_CLR_API_WITHOUT_WARNING")
-cpp_quote("#define DEPRECATED_CLR_API_MESG \"This API has been deprecated. Refer to http://go.microsoft.com/fwlink/?LinkId=143720 for more details.\"")
-cpp_quote("#define DECLARE_DEPRECATED __declspec(deprecated(DEPRECATED_CLR_API_MESG))")
-cpp_quote("#define DEPRECATED_CLR_STDAPI EXTERN_C DECLARE_DEPRECATED HRESULT STDAPICALLTYPE")
-cpp_quote("#else // USE_DEPRECATED_CLR_API_WITHOUT_WARNING")
-cpp_quote("#define DECLARE_DEPRECATED ")
-cpp_quote("#define DEPRECATED_CLR_STDAPI STDAPI")
-cpp_quote("#endif // !USE_DEPRECATED_CLR_API_WITHOUT_WARNING")
-#endif // FEATURE_CORECLR
+
cpp_quote("")
//
// Interface descriptions
//
import "unknwn.idl";
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
+#if defined(FEATURE_WINDOWSPHONE)
import "gchost.idl";
#endif
import "ivalidator.idl";
#include "product_version.h"
-#ifdef FEATURE_CORECLR
cpp_quote("struct IActivationFactory;")
interface IActivationFactory;
-#endif
const char* CLR_MAJOR_VERSION = VER_MAJORVERSION;
const char* CLR_MINOR_VERSION = VER_MINORVERSION;
@@ -51,21 +37,10 @@ const char* CLR_ASSEMBLY_MAJOR_VERSION = VER_ASSEMBLYMAJORVERSION;
const char* CLR_ASSEMBLY_MINOR_VERSION = VER_ASSEMBLYMINORVERSION;
const char* CLR_ASSEMBLY_BUILD_VERSION = VER_ASSEMBLYBUILD;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-// LIBID mscoree
-cpp_quote("EXTERN_GUID(LIBID_mscoree, 0x5477469e,0x83b1,0x11d2,0x8b,0x49,0x00,0xa0,0xc9,0xb7,0xc9,0xc4);")
-
-// CLSID CorRuntimeHost : uuid(CB2F6723-AB3A-11d2-9C40-00C04FA30A3E)
-cpp_quote("EXTERN_GUID(CLSID_CorRuntimeHost, 0xcb2f6723, 0xab3a, 0x11d2, 0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e);")
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
// CLSID TypeNameFactory : uuid{B81FF171-20F3-11d2-8DCC-00A0C9B00525}
cpp_quote("EXTERN_GUID(CLSID_TypeNameFactory, 0xB81FF171, 0x20F3, 0x11d2, 0x8d, 0xcc, 0x00, 0xa0, 0xc9, 0xb0, 0x05, 0x25);")
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-// CLSID CLRRuntimeHost : uuid(90F1A06E-7712-4762-86B5-7A5EBA6BDB02)
-cpp_quote("EXTERN_GUID(CLSID_CLRRuntimeHost, 0x90F1A06E, 0x7712, 0x4762, 0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02);")
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#ifdef FEATURE_COMINTEROP
// CLSID ComCallUnmarshal
@@ -75,83 +50,12 @@ cpp_quote("EXTERN_GUID(CLSID_ComCallUnmarshal, 0x3F281000,0xE95A,0x11d2,0x88,0x6
cpp_quote("EXTERN_GUID(CLSID_ComCallUnmarshalV4, 0x45fb4600,0xe6e8,0x4928,0xb2,0x5e,0x50,0x47,0x6f,0xf7,0x94,0x25);")
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-// IID IObjectHandle : uuid(C460E2B4-E199-412a-8456-84DC3E4838C3)
-cpp_quote("EXTERN_GUID(IID_IObjectHandle, 0xc460e2b4, 0xe199, 0x412a, 0x84, 0x56, 0x84, 0xdc, 0x3e, 0x48, 0x38, 0xc3);")
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#ifdef FEATURE_COMINTEROP
// IID IManagedObject : uuid(C3FCC19E-A970-11d2-8B5A-00A0C9B7C9C4)
cpp_quote("EXTERN_GUID(IID_IManagedObject, 0xc3fcc19e, 0xa970, 0x11d2, 0x8b, 0x5a, 0x00, 0xa0, 0xc9, 0xb7, 0xc9, 0xc4);")
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-// IID IApartmentCallback : uuid(178E5337-1528-4591-B1C9-1C6E484686D8)
-cpp_quote("EXTERN_GUID(IID_IApartmentCallback, 0x178e5337, 0x1528, 0x4591, 0xb1, 0xc9, 0x1c, 0x6e, 0x48, 0x46, 0x86, 0xd8);")
-
-// IID ICatalogServices : uuid(04C6BE1E-1DB1-4058-AB7A-700CCCFBF254)
-cpp_quote("EXTERN_GUID(IID_ICatalogServices, 0x04c6be1e, 0x1db1, 0x4058, 0xab, 0x7a, 0x70, 0x0c, 0xcc, 0xfb, 0xf2, 0x54);")
-
-// IID ICorRuntimeHost : uuid(CB2F6722-AB3A-11d2-9C40-00C04FA30A3E)
-cpp_quote("EXTERN_GUID(IID_ICorRuntimeHost, 0xcb2f6722, 0xab3a, 0x11d2, 0x9c, 0x40, 0x00, 0xc0, 0x4f, 0xa3, 0x0a, 0x3e);")
-
-// IID ICorThreadpool : uuid(84680D3A-B2C1-46e8-ACC2-DBC0A359159A)
-cpp_quote("EXTERN_GUID(IID_ICorThreadpool, 0x84680D3A, 0xB2C1, 0x46e8, 0xAC, 0xC2, 0xDB, 0xC0, 0xA3, 0x59, 0x15, 0x9A);")
-
-// IID_ICLRDebugManager : uuid(00DCAEC6-2AC0-43a9-ACF9-1E36C139B10D)
-cpp_quote("EXTERN_GUID(IID_ICLRDebugManager, 0xdcaec6, 0x2ac0, 0x43a9, 0xac, 0xf9, 0x1e, 0x36, 0xc1, 0x39, 0xb1, 0xd);")
-
-// IID IHostMemoryNeededCallback : uuid(47EB8E57-0846-4546-AF76-6F42FCFC2649)
-cpp_quote("EXTERN_GUID(IID_IHostMemoryNeededCallback, 0x47EB8E57, 0x0846, 0x4546, 0xAF, 0x76, 0x6F, 0x42, 0xFC, 0xFC, 0x26, 0x49);")
-
-// IID IHostMalloc : uuid(1831991C-CC53-4A31-B218-04E910446479)
-cpp_quote("EXTERN_GUID(IID_IHostMalloc, 0x1831991C, 0xCC53, 0x4A31, 0xB2, 0x18, 0x04, 0xE9, 0x10, 0x44, 0x64, 0x79);")
-
-// IID IHostMemoryManager : uuid(7BC698D1-F9E3-4460-9CDE-D04248E9FA25)
-cpp_quote("EXTERN_GUID(IID_IHostMemoryManager, 0x7BC698D1, 0xF9E3, 0x4460, 0x9C, 0xDE, 0xD0, 0x42, 0x48, 0xE9, 0xFA, 0x25);")
-
-// IID ICLRTask : uuid(28E66A4A-9906-4225-B231-9187C3EB8611)
-cpp_quote("EXTERN_GUID(IID_ICLRTask, 0x28E66A4A, 0x9906, 0x4225, 0xB2, 0x31, 0x91, 0x87, 0xc3, 0xeb, 0x86, 0x11);")
-
-// IID ICLRTask2 : uuid(28E66A4A-9906-4225-B231-9187C3EB8612)
-cpp_quote("EXTERN_GUID(IID_ICLRTask2, 0x28E66A4A, 0x9906, 0x4225, 0xB2, 0x31, 0x91, 0x87, 0xc3, 0xeb, 0x86, 0x12);")
-
-// IID IHostTask : uuid(C2275828-C4B1-4B55-82C9-92135F74DF1A)
-cpp_quote("EXTERN_GUID(IID_IHostTask, 0xC2275828, 0xC4B1, 0x4B55, 0x82, 0xC9, 0x92, 0x13, 0x5F, 0x74, 0xDF, 0x1A);")
-
-// IID ICLRTaskManager : uuid(4862efbe-3ae5-44f8-8feb-346190ee8a34)
-cpp_quote("EXTERN_GUID(IID_ICLRTaskManager, 0x4862efbe, 0x3ae5, 0x44f8, 0x8F, 0xEB, 0x34, 0x61, 0x90, 0xeE, 0x8A, 0x34);")
-
-// IID IHostTaskManager : uuid(997FF24C-43B7-4352-8667-0DC04FAFD354)
-cpp_quote("EXTERN_GUID(IID_IHostTaskManager, 0x997FF24C, 0x43B7, 0x4352, 0x86, 0x67, 0x0D, 0xC0, 0x4F, 0xAF, 0xD3, 0x54);")
-
-// IID IHostThreadpoolManager : uuid(983D50E2-CB15-466B-80FC-845DC6E8C5FD)
-cpp_quote("EXTERN_GUID(IID_IHostThreadpoolManager, 0x983D50E2, 0xCB15, 0x466B, 0x80, 0xFC, 0x84, 0x5D, 0xC6, 0xE8, 0xC5, 0xFD);")
-
-// IID_ICLRIOCompletionManager : uuid(2D74CE86-B8D6-4C84-B3A7-9768933B3C12)
-cpp_quote("EXTERN_GUID(IID_ICLRIoCompletionManager, 0x2D74CE86, 0xB8D6, 0x4C84, 0xB3, 0xA7, 0x97, 0x68, 0x93, 0x3B, 0x3C, 0x12);")
-
-// IID_IHostIOCompletionManager : uuid(8BDE9D80-EC06-41D6-83E6-22580EFFCC20)
-cpp_quote("EXTERN_GUID(IID_IHostIoCompletionManager, 0x8BDE9D80, 0xEC06, 0x41D6, 0x83, 0xE6, 0x22, 0x58, 0x0E, 0xFF, 0xCC, 0x20);")
-
-// IID IHostSyncManager : uuid(234330c7-5f10-4f20-9615-5122dab7a0ac)
-cpp_quote("EXTERN_GUID(IID_IHostSyncManager, 0x234330c7, 0x5f10, 0x4f20, 0x96, 0x15, 0x51, 0x22, 0xda, 0xb7, 0xa0, 0xac);")
-
-// IID IHostCrst : uuid(6DF710A6-26A4-4a65-8CD5-7237B8BDA8DC)
-cpp_quote("EXTERN_GUID(IID_IHostCrst, 0x6DF710A6, 0x26A4, 0x4a65, 0x8c, 0xd5, 0x72, 0x37, 0xb8, 0xbd, 0xa8, 0xdc);")
-
-// IID IHostAutoEvent : uuid(50B0CFCE-4063-4278-9673-E5CB4ED0BDB8)
-cpp_quote("EXTERN_GUID(IID_IHostAutoEvent, 0x50B0CFCE, 0x4063, 0x4278, 0x96, 0x73, 0xe5, 0xcb, 0x4e, 0xd0, 0xbd, 0xb8);")
-
-// IID IHostManualEvent : uuid(1BF4EC38-AFFE-4fb9-85A6-525268F15B54)
-cpp_quote("EXTERN_GUID(IID_IHostManualEvent, 0x1BF4EC38, 0xAFFE, 0x4fb9, 0x85, 0xa6, 0x52, 0x52, 0x68, 0xf1, 0x5b, 0x54);")
-
-// IID IHostSemaphore : uuid(855efd47-cc09-463a-a97d-16acab882661)
-cpp_quote("EXTERN_GUID(IID_IHostSemaphore, 0x855efd47, 0xcc09, 0x463a, 0xa9, 0x7d, 0x16, 0xac, 0xab, 0x88, 0x26, 0x61);")
-
-// IID ICLRSyncManager : uuid(55FF199D-AD21-48f9-A16C-F24EBBB8727D)
-cpp_quote("EXTERN_GUID(IID_ICLRSyncManager, 0x55FF199D, 0xAD21, 0x48f9, 0xa1, 0x6c, 0xf2, 0x4e, 0xbb, 0xb8, 0x72, 0x7d);")
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
// IID ICLRAppDomainResourceMonitor: uuid(C62DE18C-2E23-4AEA-8423-B40C1FC59EAE)
@@ -161,86 +65,34 @@ cpp_quote("EXTERN_GUID(IID_ICLRAppDomainResourceMonitor, 0XC62DE18C, 0X2E23, 0X4
// {7D290010-D781-45da-A6F8-AA5D711A730E}
cpp_quote("EXTERN_GUID(IID_ICLRPolicyManager, 0x7D290010, 0xD781, 0x45da, 0xA6, 0xF8, 0xAA, 0x5D, 0x71, 0x1A, 0x73, 0x0E);")
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined (FEATURE_WINDOWSPHONE)
+#if defined (FEATURE_WINDOWSPHONE)
// IID_ICLRGCManager : uuid(54D9007E-A8E2-4885-B7BF-F998DEEE4F2A)
cpp_quote("EXTERN_GUID(IID_ICLRGCManager, 0x54D9007E, 0xA8E2, 0x4885, 0xB7, 0xBF, 0xF9, 0x98, 0xDE, 0xEE, 0x4F, 0x2A);")
// IID_ICLRGCManager2 : uuid(0603B793-A97A-4712-9CB4-0CD1C74C0F7C)
cpp_quote("EXTERN_GUID(IID_ICLRGCManager2, 0x0603B793, 0xA97A, 0x4712, 0x9C, 0xB4, 0x0C, 0xD1, 0xC7, 0x4C, 0x0F, 0x7C);")
// IID_ICLRErrorReportingManager : uuid(980D2F1A-BF79-4c08-812A-BB9778928F78)
cpp_quote("EXTERN_GUID(IID_ICLRErrorReportingManager, 0x980d2f1a, 0xbf79, 0x4c08, 0x81, 0x2a, 0xbb, 0x97, 0x78, 0x92, 0x8f, 0x78);")
-#endif // FEATURE_INCLUDE_ALL_INTERFACES || FEATURE_WINDOWSPHONE
+#endif // FEATURE_WINDOWSPHONE
#ifdef FEATURE_WINDOWSPHONE
// IID_ICLRErrorReportingManager2 : uuid(C68F63B1-4D8B-4E0B-9564-9D2EFE2FA18C)
cpp_quote("EXTERN_GUID(IID_ICLRErrorReportingManager2, 0xc68f63b1, 0x4d8b, 0x4e0b, 0x95, 0x64, 0x9d, 0x2e, 0xfe, 0x2f, 0xa1, 0x8c);")
#endif // FEATURE_WINDOWSPHONE
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-// {7AE49844-B1E3-4683-BA7C-1E8212EA3B79}
-cpp_quote("EXTERN_GUID(IID_IHostPolicyManager, 0x7AE49844, 0xB1E3, 0x4683, 0xBA, 0x7C, 0x1E, 0x82, 0x12, 0xEA, 0x3B, 0x79);")
-
-// IID IHostGCManager : uuid(5D4EC34E-F248-457B-B603-255FAABA0D21)
-cpp_quote("EXTERN_GUID(IID_IHostGCManager, 0x5D4EC34E, 0xF248, 0x457B, 0xB6, 0x03, 0x25, 0x5F, 0xAA, 0xBA, 0x0D, 0x21);")
-
-// {607BE24B-D91B-4E28-A242-61871CE56E35}
-cpp_quote("EXTERN_GUID(IID_IActionOnCLREvent, 0x607BE24B, 0xD91B, 0x4E28, 0xA2, 0x42, 0x61, 0x87, 0x1C, 0xE5, 0x6E, 0x35);")
-
-// {1D0E0132-E64F-493D-9260-025C0E32C175}
-cpp_quote("EXTERN_GUID(IID_ICLROnEventManager, 0x1D0E0132, 0xE64F, 0x493D, 0x92, 0x60, 0x02, 0x5C, 0x0E, 0x32, 0xC1, 0x75);")
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
// IID ICLRRuntimeHost: uuid(90F1A06C-7712-4762-86B5-7A5EBA6BDB02)
cpp_quote("EXTERN_GUID(IID_ICLRRuntimeHost, 0x90F1A06C, 0x7712, 0x4762, 0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02);")
-#ifdef FEATURE_CORECLR
// IID ICLRRuntimeHost2: uuid(712AB73F-2C22-4807-AD7E-F501D7B72C2D)
cpp_quote("EXTERN_GUID(IID_ICLRRuntimeHost2, 0x712AB73F, 0x2C22, 0x4807, 0xAD, 0x7E, 0xF5, 0x01, 0xD7, 0xb7, 0x2C, 0x2D);")
// IID IID_ICLRExecutionManager: uuid(1000A3E7-B420-4620-AE30-FB19B587AD1D)
cpp_quote("EXTERN_GUID(IID_ICLRExecutionManager, 0x1000A3E7, 0xB420, 0x4620, 0xAE, 0x30, 0xFB, 0x19, 0xB5, 0x87, 0xAD, 0x1D);")
-#endif // FEATURE_CORECLR
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-// IID ICLRHostProtectionManager : uuid{89F25F5C-CEEF-43e1-9CFA-A68CE863AAAC}
-cpp_quote("EXTERN_GUID(IID_ICLRHostProtectionManager, 0x89f25f5c, 0xceef, 0x43e1, 0x9c, 0xfa, 0xa6, 0x8c, 0xe8, 0x63, 0xaa, 0xac);")
-
-// IID IHostAssemblyStore : uuid(7B102A88-3F7F-496D-8FA2-C35374E01AF3)
-cpp_quote("EXTERN_GUID(IID_IHostAssemblyStore, 0x7b102a88, 0x3f7f, 0x496d, 0x8f, 0xa2, 0xc3, 0x53, 0x74, 0xe0, 0x1a, 0xf3);")
-
-// IID IHostAssemblyManager : uuid(613dabd7-62b2-493e-9e65-c1e32a1e0c5e)
-cpp_quote("EXTERN_GUID(IID_IHostAssemblyManager, 0x613dabd7, 0x62b2, 0x493e, 0x9e, 0x65, 0xc1, 0xe3, 0x2a, 0x1e, 0x0c, 0x5e);")
-
-// IID IHostSecurityManager : uuid{75AD2468-A349-4D02-A764-76A68AEE0C4F}
-cpp_quote("EXTERN_GUID(IID_IHostSecurityManager, 0x75ad2468, 0xa349, 0x4d02, 0xa7, 0x64, 0x76, 0xa6, 0x8a, 0xee, 0x0c, 0x4f);")
-
-// IID IHostSecurityContext : uuid{7E573CE4-0343-4423-98D7-6318348A1D3C}
-cpp_quote("EXTERN_GUID(IID_IHostSecurityContext, 0x7e573ce4, 0x343, 0x4423, 0x98, 0xd7, 0x63, 0x18, 0x34, 0x8a, 0x1d, 0x3c);")
-
-// IID ICLRAssemblyIdentityManager: uuid(15f0a9da-3ff6-4393-9da9-fdfd284e6972)
-cpp_quote("EXTERN_GUID(IID_ICLRAssemblyIdentityManager, 0x15f0a9da, 0x3ff6, 0x4393, 0x9d, 0xa9, 0xfd, 0xfd, 0x28, 0x4e, 0x69, 0x72);")
-
-// IID ICLRDomainManager: uuid(270D00A2-8E15-4d0b-ADEB-37BC3E47DF77)
-cpp_quote("EXTERN_GUID(IID_ICLRDomainManager, 0x270d00a2, 0x8e15, 0x4d0b, 0xad, 0xeb, 0x37, 0xbc, 0x3e, 0x47, 0xdf, 0x77);")
-
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
// IID ITypeName : uuid{B81FF171-20F3-11d2-8DCC-00A0C9B00522}
cpp_quote("EXTERN_GUID(IID_ITypeName, 0xB81FF171, 0x20F3, 0x11d2, 0x8d, 0xcc, 0x00, 0xa0, 0xc9, 0xb0, 0x05, 0x22);")
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-// IID ICLRAssemblyReferenceList: uuid(1b2c9750-2e66-4bda-8b44-0a642c5cd733)
-cpp_quote("EXTERN_GUID(IID_ICLRAssemblyReferenceList, 0x1b2c9750, 0x2e66, 0x4bda, 0x8b, 0x44, 0x0a, 0x64, 0x2c, 0x5c, 0xd7, 0x33);")
-
-// IID ICLRReferenceAssemblyEnum: uuid(d509cb5d-cf32-4876-ae61-67770cf91973)
-cpp_quote("EXTERN_GUID(IID_ICLRReferenceAssemblyEnum, 0xd509cb5d, 0xcf32, 0x4876, 0xae, 0x61, 0x67, 0x77, 0x0c, 0xf9, 0x19, 0x73);")
-
-// IID ICLRProbingAssemblyEnum: uuid(d0c5fb1f-416b-4f97-81f4-7ac7dc24dd5d)
-cpp_quote("EXTERN_GUID(IID_ICLRProbingAssemblyEnum, 0xd0c5fb1f, 0x416b, 0x4f97, 0x81, 0xf4, 0x7a, 0xc7, 0xdc, 0x24, 0xdd, 0x5d);")
-
-// IID ICLRHostBindingPolicyManager: uuid(4b3545e7-1856-48c9-a8ba-24b21a753c09)
-cpp_quote("EXTERN_GUID(IID_ICLRHostBindingPolicyManager, 0x4b3545e7, 0x1856, 0x48c9, 0xa8, 0xba, 0x24, 0xb2, 0x1a, 0x75, 0x3c, 0x09);")
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
// IID ITypeNameBuilder : uuid{B81FF171-20F3-11d2-8DCC-00A0C9B00523}
cpp_quote("EXTERN_GUID(IID_ITypeNameBuilder, 0xB81FF171, 0x20F3, 0x11d2, 0x8d, 0xcc, 0x00, 0xa0, 0xc9, 0xb0, 0x05, 0x23);")
@@ -271,24 +123,7 @@ cpp_quote("EXTERN_GUID(IID_ITypeNameFactory, 0xB81FF171, 0x20F3, 0x11d2, 0x8d, 0
#pragma midl_echo("DEPRECATED_CLR_STDAPI LoadStringRCEx(LCID lcid, UINT iResouceID, _Out_writes_z_(iMax) LPWSTR szBuffer, int iMax, int bQuiet, int *pcwchUsed);")
#endif
-#ifndef FEATURE_CORECLR
-// Ideally we would like to make the function pointer definition below as DEPRECATED_CLR_STDAPI. However,
-// since it is referenced in the following definition of LockClrVersion, it will result in a build failure
-// in our own build (since we treat warnings as errors).
-//
-// However, there is no other usage of this pointer outside LockClrVersion. Thus, we will not mark
-// the pointer as legacy API. This will ensure we can build the runtime and if someone tries to use
-// it via LockClrVersion, they will have build warning since LockClrVersion is marked as legacy API.
-#pragma midl_echo("typedef HRESULT (__stdcall *FLockClrVersionCallback) ();")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI LockClrVersion(FLockClrVersionCallback hostCallback,FLockClrVersionCallback *pBeginHostSetup,FLockClrVersionCallback *pEndHostSetup);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI CreateDebuggingInterfaceFromVersion(int iDebuggerVersion, LPCWSTR szDebuggeeVersion, IUnknown ** ppCordb);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI GetVersionFromProcess(HANDLE hProcess, _Out_writes_to_(cchBuffer, *dwLength) LPWSTR pVersion, DWORD cchBuffer, _Out_ DWORD* dwLength);")
-#endif
-
-
-#ifdef FEATURE_CORECLR
#pragma midl_echo("typedef HRESULT (STDAPICALLTYPE *FnGetCLRRuntimeHost)(REFIID riid, IUnknown **pUnk);")
-#endif
typedef enum {
HOST_TYPE_DEFAULT = 0x0,
@@ -324,11 +159,9 @@ typedef enum {
STARTUP_TRIM_GC_COMMIT = 0x80000, // GC uses less committed space when system memory low
STARTUP_ETW = 0x100000,
STARTUP_ARM = 0x400000, // Enable the ARM feature.
-#ifdef FEATURE_CORECLR
STARTUP_SINGLE_APPDOMAIN = 0x800000, // application runs in default domain, no more domains are created
STARTUP_APPX_APP_MODEL = 0x1000000, // jupiter app
STARTUP_DISABLE_RANDOMIZED_STRING_HASHING = 0x2000000 // Disable the randomized string hashing
-#endif
} STARTUP_FLAGS;
typedef enum {
@@ -356,11 +189,8 @@ typedef enum
APPDOMAIN_SECURITY_DEFAULT =0x0,
APPDOMAIN_SECURITY_SANDBOXED = 0x1, // appdomain is sandboxed
APPDOMAIN_SECURITY_FORBID_CROSSAD_REVERSE_PINVOKE = 0x2, // no cross ad reverse pinvokes
-#ifdef FEATURE_CORECLR
APPDOMAIN_IGNORE_UNHANDLED_EXCEPTIONS = 0x4, //
-#endif //FEATURE_CORECLR
APPDOMAIN_FORCE_TRIVIAL_WAIT_OPERATIONS = 0x08, // do not pump messages during wait operations, do not call sync context
-#ifdef FEATURE_CORECLR
// When passed by the host, this flag will allow any assembly to perform PInvoke or COMInterop operations.
// Otherwise, by default, only platform assemblies can perform those operations.
APPDOMAIN_ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP = 0x10,
@@ -369,159 +199,10 @@ typedef enum
APPDOMAIN_ENABLE_ASSEMBLY_LOADFILE = 0x80,
APPDOMAIN_DISABLE_TRANSPARENCY_ENFORCEMENT = 0x100,
-#endif //FEATURE_CORECLR
} APPDOMAIN_SECURITY_FLAGS;
#pragma midl_echo("STDAPI GetRequestedRuntimeVersionForCLSID(REFCLSID rclsid, _Out_writes_opt_(cchBuffer) LPWSTR pVersion, DWORD cchBuffer, _Out_opt_ DWORD* dwLength, CLSID_RESOLUTION_FLAGS dwResolutionFlags);")
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-//*****************************************************************************
-// Interface for Object Handles
-//*****************************************************************************
-[
- object,
- oleautomation,
- uuid(C460E2B4-E199-412a-8456-84DC3E4838C3),
- helpstring("Object Handle Interface"),
- pointer_default(unique)
-]
-interface IObjectHandle : IUnknown
-{
- HRESULT Unwrap([out, retval] VARIANT *ppv);
-};
-
-//*****************************************************************************
-// Interface for Setting runtime configuration
-//*****************************************************************************
-[
- uuid(5C2B07A7-1E98-11d3-872F-00C04F79ED0D),
- version(1.0),
- helpstring("Application Domain call back"),
- pointer_default(unique),
- local
-]
-interface IAppDomainBinding : IUnknown
-{
- // <TODO>TODO: this should return an AppDomain interface
- // The event is invoked everytime a domain is created </TODO>
- HRESULT OnAppDomain([in] IUnknown* pAppdomain);
-}
-
-
-//*****************************************************************************
-// Interface for participating in the scheduling of threads that would
-// otherwise be blocked for a GC
-//*****************************************************************************
-[
- uuid(F31D1788-C397-4725-87A5-6AF3472C2791),
- version(1.0),
- helpstring("Control over threads blocked in GC"),
- pointer_default(unique),
- local
-]
-interface IGCThreadControl : IUnknown
-{
- // Notification that the thread making the call is about to block, perhaps for
- // a GC or other suspension. This gives the host an opportunity to re-schedule
- // the thread for unmanaged tasks.
- HRESULT ThreadIsBlockingForSuspension();
-
- // Notification that the runtime is beginning a thread suspension for a GC or
- // other suspension. Do not reschedule this thread!
- HRESULT SuspensionStarting();
-
- // Notification that the runtime is resuming threads after a GC or other
- // suspension. Do not reschedule this thread!
- HRESULT SuspensionEnding(DWORD Generation);
-}
-
-//*****************************************************************************
-// Interface for GC to request change in virtual memory limit
-//*****************************************************************************
-[
- uuid(5513D564-8374-4cb9-AED9-0083F4160A1D),
- version(1.1),
- helpstring("Request change in virtual memory for GC"),
- pointer_default(unique),
- local
-]
-interface IGCHostControl : IUnknown
-{
- // Request to increase the virtual memeory limit of the runtime (GC heap)
- HRESULT RequestVirtualMemLimit([in] SIZE_T sztMaxVirtualMemMB,
- [in, out] SIZE_T* psztNewMaxVirtualMemMB);
-}
-
-//*****************************************************************************
-// Interface for accessing threadpool
-//*****************************************************************************
-cpp_quote("#ifdef __midl")
-typedef VOID (__stdcall *WAITORTIMERCALLBACK)(PVOID, BOOL);
-cpp_quote("#endif // __midl")
-
-cpp_quote("#ifdef __midl")
-typedef DWORD (__stdcall *LPTHREAD_START_ROUTINE)(LPVOID lpThreadParameter);
-typedef VOID (*LPOVERLAPPED_COMPLETION_ROUTINE)(DWORD dwErrorCode,
- DWORD dwNumberOfBytesTransfered,
- LPVOID lpOverlapped);
-cpp_quote("#endif // __midl")
-
-// Callback function for cleaning up TLS
-typedef VOID (__stdcall *PTLS_CALLBACK_FUNCTION)(PVOID);
-
-[
- uuid(84680D3A-B2C1-46e8-ACC2-DBC0A359159A),
- version(1.0),
- helpstring("Threadpool interface"),
- pointer_default(unique),
- local
-]
-interface ICorThreadpool : IUnknown
-{
- HRESULT CorRegisterWaitForSingleObject([in] HANDLE* phNewWaitObject,
- [in] HANDLE hWaitObject,
- [in] WAITORTIMERCALLBACK Callback,
- [in] PVOID Context,
- [in] ULONG timeout,
- [in] BOOL executeOnlyOnce,
- [out] BOOL* result );
-
- HRESULT CorUnregisterWait([in] HANDLE hWaitObject,[in] HANDLE CompletionEvent,[out] BOOL* result);
-
- HRESULT CorQueueUserWorkItem([in] LPTHREAD_START_ROUTINE Function,
- [in] PVOID Context,
- [in] BOOL executeOnlyOnce,
- [out] BOOL* result );
-
-
- HRESULT CorCreateTimer([in] HANDLE* phNewTimer,
- [in] WAITORTIMERCALLBACK Callback,
- [in] PVOID Parameter,
- [in] DWORD DueTime,
- [in] DWORD Period,
- [out] BOOL* result);
-
- HRESULT CorChangeTimer([in] HANDLE Timer, [in] ULONG DueTime, [in] ULONG Period, [out] BOOL* result);
-
- HRESULT CorDeleteTimer([in] HANDLE Timer, [in] HANDLE CompletionEvent, [out] BOOL* result);
-
- HRESULT CorBindIoCompletionCallback([in] HANDLE fileHandle, [in] LPOVERLAPPED_COMPLETION_ROUTINE callback);
-
- HRESULT CorCallOrQueueUserWorkItem([in] LPTHREAD_START_ROUTINE Function,
- [in] PVOID Context,
- [out] BOOL* result );
- HRESULT CorSetMaxThreads([in] DWORD MaxWorkerThreads,
- [in] DWORD MaxIOCompletionThreads);
-
- HRESULT CorGetMaxThreads([out] DWORD *MaxWorkerThreads,
- [out] DWORD *MaxIOCompletionThreads);
-
- HRESULT CorGetAvailableThreads([out] DWORD *AvailableWorkerThreads,
- [out] DWORD *AvailableIOCompletionThreads);
-
-
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
cpp_quote("EXTERN_GUID(IID_IDebuggerThreadControl, 0x23d86786, 0x0bb5, 0x4774, 0x8f, 0xb5, 0xe3, 0x52, 0x2a, 0xdd, 0x62, 0x46);")
[
@@ -567,124 +248,12 @@ interface IDebuggerInfo : IUnknown
HRESULT IsDebuggerAttached([out] BOOL *pbAttached);
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-// {5C2B07A5-1E98-11d3-872F-00C04F79ED0D}
-cpp_quote("EXTERN_GUID(IID_ICorConfiguration, 0x5c2b07a5, 0x1e98, 0x11d3, 0x87, 0x2f, 0x00, 0xc0, 0x4f, 0x79, 0xed, 0x0d);")
-[
- uuid(5C2B07A5-1E98-11d3-872F-00C04F79ED0D),
- version(1.0),
- helpstring("Common Language Runtime Configuration Interface"),
- pointer_default(unique),
- local
-]
-interface ICorConfiguration : IUnknown
-{
- // Set the callback for scheduling threads for non-runtime tasks when they
- // would otherwise be blocked for a GC.
- HRESULT SetGCThreadControl([in] IGCThreadControl* pGCThreadControl);
-
- // Set the callback for gc to request a change in virtual memmory limit
- HRESULT SetGCHostControl([in] IGCHostControl* pGCHostControl);
-
- // Set the callback interface that the debugging services will
- // call as Runtime threads are blocked and un-blocked for
- // debugging.
- HRESULT SetDebuggerThreadControl([in] IDebuggerThreadControl* pDebuggerThreadControl);
-
- // The host may indicate to the debugging services that a
- // particular thread should be allowed to continue to execute
- // while the debugger has an application stopped during
- // managed/unmanaged debugging scenarios. The specified thread
- // will not be allowed to run managed code, or to enter the
- // Runtime in any way. An example of such a thread would be an
- // in-process thread to support legacy script debuggers.
- HRESULT AddDebuggerSpecialThread([in] DWORD dwSpecialThreadId);
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
//*****************************************************************************
// Interface for hosting mscoree
//*****************************************************************************
typedef void* HDOMAINENUM;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-[
- uuid(CB2F6722-AB3A-11d2-9C40-00C04FA30A3E),
- version(1.0),
- helpstring("Common Language Runtime Hosting Interface"),
- pointer_default(unique),
- local
-]
-interface ICorRuntimeHost : IUnknown
-{
- HRESULT CreateLogicalThreadState();
- HRESULT DeleteLogicalThreadState();
- HRESULT SwitchInLogicalThreadState(
- [in] DWORD *pFiberCookie); // [in] Cookie that indicates the fiber to use.
-
- HRESULT SwitchOutLogicalThreadState(
- [out] DWORD **pFiberCookie); // [out] Cookie that indicates the fiber being switched out.
-
- HRESULT LocksHeldByLogicalThread( // Return code.
- [out] DWORD *pCount // [out] Number of locks that the current thread holds.
- );
-
- HRESULT MapFile(
- [in] HANDLE hFile, // [in] HANDLE for file
- [out] HMODULE* hMapAddress); // [out] HINSTANCE for mapped file
-
- //=================================================================
- //
- // New hosting methods
- //
- // Returns an object for configuring the runtime prior to
- // it starting. If the runtime has been initialized this
- // routine returns an error. See ICorConfiguration.
- HRESULT GetConfiguration([out] ICorConfiguration** pConfiguration);
-
- // Starts the runtime. This is equivalent to CoInitializeCor();
- HRESULT Start();
-
- // Terminates the runtime, This is equivalent CoUninitializeCor();
- HRESULT Stop();
-
- // Creates a domain in the runtime. The identity array is
- // a pointer to an array TYPE containing IIdentity objects defining
- // the security identity.
- HRESULT CreateDomain([in] LPCWSTR pwzFriendlyName,
- [in] IUnknown* pIdentityArray, // Optional
- [out] IUnknown** pAppDomain);
-
- // Returns the default domain.
- HRESULT GetDefaultDomain([out] IUnknown** pAppDomain);
-
-
- // Enumerate currently existing domains.
- HRESULT EnumDomains([out] HDOMAINENUM *hEnum);
-
- // Returns S_FALSE when there are no more domains. A domain
- // is passed out only when S_OK is returned.
- HRESULT NextDomain([in] HDOMAINENUM hEnum,
- [out] IUnknown** pAppDomain);
-
- // Close the enumeration, releasing resources
- HRESULT CloseEnum([in] HDOMAINENUM hEnum);
-
- HRESULT CreateDomainEx([in] LPCWSTR pwzFriendlyName, // Optional
- [in] IUnknown* pSetup, // Optional
- [in] IUnknown* pEvidence, // Optional
- [out] IUnknown** pAppDomain);
-
- HRESULT CreateDomainSetup([out] IUnknown** pAppDomainSetup);
-
- HRESULT CreateEvidence([out] IUnknown** pEvidence);
-
- HRESULT UnloadDomain([in] IUnknown* pAppDomain);
-
- // Returns the thread's domain.
- HRESULT CurrentDomain([out] IUnknown** pAppDomain);
-};
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
typedef enum
{
@@ -706,162 +275,10 @@ typedef enum {
WAIT_NOTINDEADLOCK = 0x4
}WAIT_OPTION;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-cpp_quote("EXTERN_GUID(IID_ICLRMemoryNotificationCallback, 0x47EB8E57, 0x0846, 0x4546, 0xAF, 0x76, 0x6F, 0x42, 0xFC, 0xFC, 0x26, 0x49);")
-[
- uuid(47EB8E57-0846-4546-AF76-6F42FCFC2649),
- version(1.0),
- helpstring("Callback by Host to notify runtime short of memory"),
- pointer_default(unique),
- local
-]
-interface ICLRMemoryNotificationCallback : IUnknown
-{
- // Callback by Host on out of memory to request runtime to free memory.
- // Runtime will do a GC and Wait for PendingFinalizer.
- HRESULT OnMemoryNotification([in] EMemoryAvailable eMemoryAvailable);
-}
-
-[
- uuid(1831991C-CC53-4A31-B218-04E910446479),
- version(1.0),
- helpstring("Host Malloc"),
- pointer_default(unique),
- local
-]
-interface IHostMalloc : IUnknown
-{
- HRESULT Alloc([in] SIZE_T cbSize,
- [in] EMemoryCriticalLevel eCriticalLevel,
- [out] void** ppMem);
-
- HRESULT DebugAlloc([in] SIZE_T cbSize,
- [in] EMemoryCriticalLevel eCriticalLevel,
- [in, annotation("_In_ ")] char* pszFileName,
- [in] int iLineNo,
- [out, annotation("_Outptr_result_maybenull_")] void** ppMem);
-
- HRESULT Free([in] void* pMem);
-}
-
-typedef enum
-{
- MALLOC_THREADSAFE = 0x1,
- MALLOC_EXECUTABLE = 0x2,
-} MALLOC_TYPE;
-
-[
- uuid(7BC698D1-F9E3-4460-9CDE-D04248E9FA25),
- version(1.0),
- helpstring("Host memory manager"),
- pointer_default(unique),
- local
-]
-interface IHostMemoryManager : IUnknown
-{
- HRESULT CreateMalloc([in] DWORD dwMallocType,
- [out] IHostMalloc **ppMalloc);
-
- HRESULT VirtualAlloc([in] void* pAddress,
- [in] SIZE_T dwSize,
- [in] DWORD flAllocationType,
- [in] DWORD flProtect,
- [in] EMemoryCriticalLevel eCriticalLevel,
- [out] void** ppMem);
-
- HRESULT VirtualFree([in] LPVOID lpAddress,
- [in] SIZE_T dwSize,
- [in] DWORD dwFreeType);
-
- HRESULT VirtualQuery([in] void * lpAddress,
- [out] void* lpBuffer,
- [in] SIZE_T dwLength,
- [out] SIZE_T * pResult);
-
- HRESULT VirtualProtect([in] void * lpAddress,
- [in] SIZE_T dwSize,
- [in] DWORD flNewProtect,
- [out] DWORD * pflOldProtect);
-
- HRESULT GetMemoryLoad([out] DWORD* pMemoryLoad,
- [out] SIZE_T *pAvailableBytes);
-
- HRESULT RegisterMemoryNotificationCallback([in] ICLRMemoryNotificationCallback * pCallback);
-
- HRESULT NeedsVirtualAddressSpace(
- [in] LPVOID startAddress,
- [in] SIZE_T size
- );
-
- HRESULT AcquiredVirtualAddressSpace(
- [in] LPVOID startAddress,
- [in] SIZE_T size
- );
-
- HRESULT ReleasedVirtualAddressSpace(
- [in] LPVOID startAddress
- );
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
typedef UINT64 TASKID;
typedef DWORD CONNID;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-[
- uuid(28E66A4A-9906-4225-B231-9187C3EB8611),
- version(1.0),
- helpstring("Callback by Host to collaborate with CLR on HostTask"),
- pointer_default(unique),
- local
-]
-interface ICLRTask: IUnknown
-{
- HRESULT SwitchIn([in] HANDLE threadHandle);
- HRESULT SwitchOut();
- HRESULT GetMemStats([out] COR_GC_THREAD_STATS *memUsage);
- HRESULT Reset(BOOL fFull);
- HRESULT ExitTask();
- HRESULT Abort();
- HRESULT RudeAbort();
- HRESULT NeedsPriorityScheduling([out] BOOL * pbNeedsPriorityScheduling);
- HRESULT YieldTask();
- HRESULT LocksHeld([out] SIZE_T *pLockCount);
- HRESULT SetTaskIdentifier([in] TASKID asked);
-}
-
-[
- uuid(28E66A4A-9906-4225-B231-9187C3EB8612),
- version(1.0),
- helpstring("Callback by Host to collaborate with CLR on HostTask"),
- pointer_default(unique),
- local
-]
-interface ICLRTask2 : ICLRTask
-{
- HRESULT BeginPreventAsyncAbort();
- HRESULT EndPreventAsyncAbort();
-}
-
-
-[
- uuid(C2275828-C4B1-4B55-82C9-92135F74DF1A),
- version(1.0),
- helpstring("Called by CLR to operate on a HostTask"),
- pointer_default(unique),
- local
-]
-interface IHostTask : IUnknown
-{
- HRESULT Start();
- HRESULT Alert();
- HRESULT Join([in] DWORD dwMilliseconds,
- [in] DWORD option);
- HRESULT SetPriority([in] int newPriority);
- HRESULT GetPriority([out] int *pPriority);
- HRESULT SetCLRTask([in] ICLRTask *pCLRTask);
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
typedef enum ETaskType
{
@@ -879,141 +296,6 @@ typedef enum ETaskType
TT_UNKNOWN = 0x80000000,
} ETaskType;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-[
- uuid(4862efbe-3ae5-44f8-8feb-346190ee8a34),
- version(1.0),
- helpstring("Functions provided by CLR to handle a CLRTask"),
- pointer_default(unique),
- local
-]
-interface ICLRTaskManager : IUnknown
-{
- HRESULT CreateTask ([out] ICLRTask **pTask);
- HRESULT GetCurrentTask ([out] ICLRTask **pTask);
- HRESULT SetUILocale([in] LCID lcid);
- HRESULT SetLocale([in] LCID lcid);
-
- HRESULT GetCurrentTaskType([out] ETaskType *pTaskType);
-
-}
-
-[
- uuid(997FF24C-43B7-4352-8667-0DC04FAFD354),
- version(1.0),
- helpstring("Functions provided by host to handle a HostTask"),
- pointer_default(unique),
- local
-]
-interface IHostTaskManager : IUnknown
-{
- HRESULT GetCurrentTask ([out] IHostTask **pTask);
- HRESULT CreateTask ([in] DWORD dwStackSize,
- [in] LPTHREAD_START_ROUTINE pStartAddress,
- [in] PVOID pParameter,
- [out] IHostTask **ppTask);
- HRESULT Sleep([in] DWORD dwMilliseconds,
- [in] DWORD option);
- HRESULT SwitchToTask([in] DWORD option);
-
- HRESULT SetUILocale([in] LCID lcid);
- HRESULT SetLocale([in] LCID lcid);
-
- HRESULT CallNeedsHostHook([in] SIZE_T target,
- [out] BOOL *pbCallNeedsHostHook);
-
- HRESULT LeaveRuntime([in] SIZE_T target);
- HRESULT EnterRuntime();
-
- HRESULT ReverseLeaveRuntime();
- HRESULT ReverseEnterRuntime();
-
- HRESULT BeginDelayAbort();
- HRESULT EndDelayAbort();
- HRESULT BeginThreadAffinity();
- HRESULT EndThreadAffinity();
-
- HRESULT SetStackGuarantee([in] ULONG guarantee);
- HRESULT GetStackGuarantee([out] ULONG *pGuarantee);
-
- HRESULT SetCLRTaskManager([in] ICLRTaskManager *ppManager);
-
-}
-
-[
- uuid(983D50E2-CB15-466B-80FC-845DC6E8C5FD),
- version(1.0),
- helpstring("Threadpool Functions provided by host"),
- pointer_default(unique),
- local
-]
-interface IHostThreadpoolManager : IUnknown
-{
- HRESULT QueueUserWorkItem(
- [in] LPTHREAD_START_ROUTINE Function,
- [in] PVOID Context,
- [in] ULONG Flags);
- HRESULT SetMaxThreads(
- [in] DWORD dwMaxWorkerThreads);
- HRESULT GetMaxThreads(
- [out] DWORD *pdwMaxWorkerThreads);
- HRESULT GetAvailableThreads(
- [out] DWORD *pdwAvailableWorkerThreads);
- HRESULT SetMinThreads(
- [in] DWORD dwMinIOCompletionThreads);
- HRESULT GetMinThreads(
- [out] DWORD *pdwMinIOCompletionThreads);
-}
-
-[
- uuid(2d74ce86-b8d6-4c84-b3a7-9768933b3c12),
- version(1.0),
- helpstring("Asynchronous IO support callback"),
- pointer_default(unique),
- local
-]
-interface ICLRIoCompletionManager : IUnknown
-{
- HRESULT OnComplete(
- [in] DWORD dwErrorCode,
- [in] DWORD NumberOfBytesTransferred,
- [in] void* pvOverlapped);
-}
-
-[
- uuid(8bde9d80-ec06-41d6-83e6-22580effcc20),
- version(1.0),
- helpstring("Asynchronous IO support provided by host"),
- pointer_default(unique),
- local
-]
-interface IHostIoCompletionManager : IUnknown
-{
- HRESULT CreateIoCompletionPort(
- [out] HANDLE *phPort);
- HRESULT CloseIoCompletionPort(
- [in] HANDLE hPort);
- HRESULT SetMaxThreads(
- [in] DWORD dwMaxIOCompletionThreads);
- HRESULT GetMaxThreads(
- [out] DWORD *pdwMaxIOCompletionThreads);
- HRESULT GetAvailableThreads(
- [out] DWORD *pdwAvailableIOCompletionThreads);
- HRESULT GetHostOverlappedSize(
- [out] DWORD * pcbSize);
- HRESULT SetCLRIoCompletionManager(
- [in] ICLRIoCompletionManager * pManager);
- HRESULT InitializeHostOverlapped(
- [in] void * pvOverlapped);
- HRESULT Bind(
- [in] HANDLE hPort,
- [in] HANDLE hHandle);
- HRESULT SetMinThreads(
- [in] DWORD dwMinIOCompletionThreads);
- HRESULT GetMinThreads(
- [out] DWORD *pdwMinIOCompletionThreads);
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
typedef enum {
eSymbolReadingNever = 0, // Never read PDBs
@@ -1021,41 +303,6 @@ typedef enum {
eSymbolReadingFullTrustOnly = 2 // Only read PDBs that correspond to full-trust assemblies
} ESymbolReadingPolicy;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-[
- uuid(00DCAEC6-2AC0-43a9-ACF9-1E36C139B10D),
- version(1.0),
- helpstring("CLR debugger manager"),
- pointer_default(unique),
- local
-]
-interface ICLRDebugManager : IUnknown
-{
- HRESULT BeginConnection(
- [in] CONNID dwConnectionId,
- [in, string, annotation("_In_")] wchar_t *szConnectionName);
- HRESULT SetConnectionTasks(
- [in] CONNID id,
- [in] DWORD dwCount,
- [in, size_is(dwCount)] ICLRTask **ppCLRTask);
- HRESULT EndConnection(
- [in] CONNID dwConnectionId);
- // Set ACL on shared section, events, and process
- HRESULT SetDacl([in] PACL pacl);
-
- // Returning the current ACL that CLR is using
- // The memory is allocated by runtime using CoTaskmemAlloc. Caller must
- // free the memory pointed to by pacl using CoTaskMemFree.
- HRESULT GetDacl([out] PACL *pacl);
-
- // Indicates whether or not a managed debugger is attached to this process.
- HRESULT IsDebuggerAttached([out] BOOL *pbAttached);
-
- // Specify whether the symbol reader should be used. Affects whether file and line
- // info can be included when the CLR captures a call stack.
- HRESULT SetSymbolReadingPolicy([in] ESymbolReadingPolicy policy);
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
typedef enum {
// Default to minidump
@@ -1117,7 +364,7 @@ typedef struct _BucketParameters
WCHAR pszParams[BucketParamsCount][BucketParamLength]; // Parameter strings.
} BucketParameters;
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
+#if defined(FEATURE_WINDOWSPHONE)
[
uuid(980D2F1A-BF79-4c08-812A-BB9778928F78),
version(1.0),
@@ -1221,119 +468,8 @@ interface ICLRErrorReportingManager2 : ICLRErrorReportingManager
}
#endif // FEATURE_WINDOWSPHONE
-#endif // defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-[
- uuid(6DF710A6-26A4-4a65-8CD5-7237B8BDA8DC),
- version(1.0),
- helpstring("CriticalSection provided by host"),
- pointer_default(unique),
- local
-]
-interface IHostCrst : IUnknown
-{
- HRESULT Enter([in] DWORD option);
- HRESULT Leave();
- HRESULT TryEnter([in] DWORD option,
- [out] BOOL *pbSucceeded);
- HRESULT SetSpinCount([in] DWORD dwSpinCount);
-}
-
-[
- uuid(50B0CFCE-4063-4278-9673-E5CB4ED0BDB8),
- version(1.0),
- helpstring("AutoEvent provided by host"),
- pointer_default(unique),
- local
-]
-interface IHostAutoEvent : IUnknown
-{
- HRESULT Wait([in] DWORD dwMilliseconds,
- [in] DWORD option);
- HRESULT Set();
-}
-
-[
- uuid(1BF4EC38-AFFE-4fb9-85A6-525268F15B54),
- version(1.0),
- helpstring("ManualEvent provided by host"),
- pointer_default(unique),
- local
-]
-interface IHostManualEvent : IUnknown
-{
- HRESULT Wait([in] DWORD dwMilliseconds,
- [in] DWORD option);
- HRESULT Reset();
- HRESULT Set();
-}
-
-[
- uuid(855efd47-cc09-463a-a97d-16acab882661),
- version(1.0),
- helpstring("Semaphore provided by host"),
- pointer_default(unique),
- local
-]
-interface IHostSemaphore : IUnknown
-{
- HRESULT Wait([in] DWORD dwMilliseconds,
- [in] DWORD option);
- HRESULT ReleaseSemaphore([in] LONG lReleaseCount,
- [out] LONG *lpPreviousCount);
-}
-
-[
- uuid(55FF199D-AD21-48f9-A16C-F24EBBB8727D),
- version(1.0),
- helpstring("Functions provided by CLR to provide infomation on synchronization objects"),
- pointer_default(unique),
- local
-]
-interface ICLRSyncManager : IUnknown
-{
- HRESULT GetMonitorOwner ([in] SIZE_T Cookie,
- [out] IHostTask **ppOwnerHostTask);
-
- HRESULT CreateRWLockOwnerIterator([in] SIZE_T Cookie, [out] SIZE_T *pIterator);
- HRESULT GetRWLockOwnerNext([in] SIZE_T Iterator, [out] IHostTask **ppOwnerHostTask);
- HRESULT DeleteRWLockOwnerIterator([in] SIZE_T Iterator);
-}
-
-[
- uuid(234330c7-5f10-4f20-9615-5122dab7a0ac),
- version(1.0),
- helpstring("Functions provided by host to create synchronization objects"),
- pointer_default(unique),
- local
-]
-interface IHostSyncManager : IUnknown
-{
- HRESULT SetCLRSyncManager([in] ICLRSyncManager *pManager);
-
- HRESULT CreateCrst([out] IHostCrst** ppCrst);
- HRESULT CreateCrstWithSpinCount ([in] DWORD dwSpinCount,
- [out] IHostCrst** ppCrst);
-
- HRESULT CreateAutoEvent([out] IHostAutoEvent **ppEvent);
- HRESULT CreateManualEvent([in] BOOL bInitialState,
- [out] IHostManualEvent **ppEvent);
+#endif // defined(FEATURE_WINDOWSPHONE)
- HRESULT CreateMonitorEvent([in] SIZE_T Cookie,
- [out] IHostAutoEvent **ppEvent);
-
- HRESULT CreateRWLockWriterEvent([in] SIZE_T Cookie,
- [out] IHostAutoEvent **ppEvent);
- HRESULT CreateRWLockReaderEvent([in] BOOL bInitialState,
- [in] SIZE_T Cookie,
- [out] IHostManualEvent **ppEvent);
-
- HRESULT CreateSemaphore([in] DWORD dwInitial,
- [in] DWORD dwMax,
- [out] IHostSemaphore ** ppSemaphore);
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
typedef enum
{
@@ -1423,29 +559,6 @@ interface ICLRPolicyManager: IUnknown
[in] EClrUnhandledException policy);
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-[
- uuid(7AE49844-B1E3-4683-BA7C-1E8212EA3B79),
- version(1.0),
- helpstring("Notify host about how CLR handles abnormal condition"),
- pointer_default(unique),
- local
-]
-interface IHostPolicyManager: IUnknown
-{
- HRESULT OnDefaultAction(
- [in] EClrOperation operation,
- [in] EPolicyAction action);
-
- HRESULT OnTimeout(
- [in] EClrOperation operation,
- [in] EPolicyAction action);
-
- HRESULT OnFailure(
- [in] EClrFailure failure,
- [in] EPolicyAction action);
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
typedef enum
{
@@ -1479,250 +592,8 @@ cpp_quote(" StackOverflowType soType;")
cpp_quote(" EXCEPTION_POINTERS *pExceptionInfo;")
cpp_quote("} StackOverflowInfo;")
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-[
- uuid(607BE24B-D91B-4E28-A242-61871CE56E35),
- version(1.0),
- helpstring("Allow host to register action on domain unload"),
- pointer_default(unique),
- local
-]
-interface IActionOnCLREvent: IUnknown
-{
- HRESULT OnEvent(
- [in] EClrEvent event,
- [in] PVOID data
- );
-}
-
-[
- uuid(1D0E0132-E64F-493D-9260-025C0E32C175),
- version(1.0),
- helpstring("Allow host to register action on event"),
- pointer_default(unique),
- local
-]
-interface ICLROnEventManager: IUnknown
-{
- HRESULT RegisterActionOnEvent(
- [in] EClrEvent event,
- [in] IActionOnCLREvent *pAction
- );
- HRESULT UnregisterActionOnEvent(
- [in] EClrEvent event,
- [in] IActionOnCLREvent *pAction
- );
-}
-
-[
- uuid(5D4EC34E-F248-457B-B603-255FAABA0D21),
- version(1.0),
- helpstring("Control over threads blocked in GC"),
- pointer_default(unique),
- local
-]
-interface IHostGCManager : IUnknown
-{
- // Notification that the thread making the call is about to block, perhaps for
- // a GC or other suspension. This gives the host an opportunity to re-schedule
- // the thread for unmanaged tasks.
- HRESULT ThreadIsBlockingForSuspension();
-
- // Notification that the runtime is beginning a thread suspension for a GC or
- // other suspension. Do not reschedule this thread!
- HRESULT SuspensionStarting();
-
- // Notification that the runtime is resuming threads after a GC or other
- // suspension. Do not reschedule this thread!
- HRESULT SuspensionEnding(DWORD Generation);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// ICLRAssemblyReferenceList
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- object,
- version(1.0),
- uuid(1b2c9750-2e66-4bda-8b44-0a642c5cd733),
- helpstring("Generic Assembly Reference List, created by CLR."),
- pointer_default(unique),
- local
-]
-interface ICLRAssemblyReferenceList : IUnknown
-{
- HRESULT IsStringAssemblyReferenceInList(
- [in] LPCWSTR pwzAssemblyName
- );
-
- HRESULT IsAssemblyReferenceInList(
- [in] IUnknown *pName
- );
-};
-///////////////////////////////////////////////////////////////////////////////
-//
-// ICLRReferenceAssemblyEnum
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- object,
- version(1.0),
- uuid(d509cb5d-cf32-4876-ae61-67770cf91973),
- helpstring("Reference Enum of an Assembly."),
- pointer_default(unique),
- local
-]
-interface ICLRReferenceAssemblyEnum : IUnknown
-{
- HRESULT Get(
- [in] DWORD dwIndex,
- [out, size_is(*pcchBufferSize), annotation("_Out_writes_all_(*pcchBufferSize)")]
- LPWSTR pwzBuffer,
- [in, out] DWORD *pcchBufferSize
- );
-};
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// ICLRProbingAssemblyEnum
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- object,
- version(1.0),
- uuid(d0c5fb1f-416b-4f97-81f4-7ac7dc24dd5d),
- helpstring("The assemblies CLR will probe for given assembly"),
- pointer_default(unique),
- local
-]
-interface ICLRProbingAssemblyEnum:IUnknown
-{
- HRESULT Get(
- [in] DWORD dwIndex,
- [out, size_is(*pcchBufferSize), annotation("_Out_writes_all_(*pcchBufferSize)")]
- LPWSTR pwzBuffer,
- [in, out] DWORD *pcchBufferSize
- );
-};
-
-typedef enum _CLRAssemblyIdentityFlags
-{
- CLR_ASSEMBLY_IDENTITY_FLAGS_DEFAULT = 0
-}ECLRAssemblyIdentityFlags;
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// ICLRAssemblyIdentityManager
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- object,
- version(1.0),
- uuid(15f0a9da-3ff6-4393-9da9-fdfd284e6972),
- helpstring("CLR Assembly Identity Manager"),
- pointer_default(unique),
- local
-]
-interface ICLRAssemblyIdentityManager : IUnknown
-{
- HRESULT GetCLRAssemblyReferenceList(
- [in] LPCWSTR *ppwzAssemblyReferences,
- [in] DWORD dwNumOfReferences,
- [out] ICLRAssemblyReferenceList **ppReferenceList
- );
-
- HRESULT GetBindingIdentityFromFile(
- [in] LPCWSTR pwzFilePath,
- [in] DWORD dwFlags,
- [out, size_is(*pcchBufferSize), annotation("_Out_writes_all_(*pcchBufferSize)")]
- LPWSTR pwzBuffer,
- [in, out] DWORD *pcchBufferSize
- );
-
- HRESULT GetBindingIdentityFromStream(
- [in] IStream *pStream,
- [in] DWORD dwFlags,
- [out, size_is(*pcchBufferSize), annotation("_Out_writes_all_(*pcchBufferSize)")]
- LPWSTR pwzBuffer,
- [in, out] DWORD *pcchBufferSize
- );
-
- HRESULT GetReferencedAssembliesFromFile(
- [in] LPCWSTR pwzFilePath,
- [in] DWORD dwFlags,
- [in] ICLRAssemblyReferenceList *pExcludeAssembliesList,
- [out] ICLRReferenceAssemblyEnum **ppReferenceEnum
- );
-
- HRESULT GetReferencedAssembliesFromStream(
- [in] IStream *pStream,
- [in] DWORD dwFlags,
- [in] ICLRAssemblyReferenceList *pExcludeAssembliesList,
- [out] ICLRReferenceAssemblyEnum **ppReferenceEnum
- );
-
- HRESULT GetProbingAssembliesFromReference(
- [in] DWORD dwMachineType,
- [in] DWORD dwFlags,
- [in] LPCWSTR pwzReferenceIdentity,
- [out] ICLRProbingAssemblyEnum **ppProbingAssemblyEnum
- );
-
- HRESULT IsStronglyNamed(
- [in] LPCWSTR pwzAssemblyIdentity,
- [out] BOOL *pbIsStronglyNamed
- );
-};
-
-typedef enum _hostBiningPolicyModifyFlags
-{
- HOST_BINDING_POLICY_MODIFY_DEFAULT = 0,
- HOST_BINDING_POLICY_MODIFY_CHAIN = 1,
- HOST_BINDING_POLICY_MODIFY_REMOVE = 2,
- HOST_BINDING_POLICY_MODIFY_MAX = 3
-}EHostBindingPolicyModifyFlags;
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// ICLRHostBindingPolicyManager
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- object,
- version(1.0),
- uuid(4b3545e7-1856-48c9-a8ba-24b21a753c09),
- helpstring("CLR Host Binding Policy Manager, managing binding policy for host."),
- pointer_default(unique),
- local
-]
-interface ICLRHostBindingPolicyManager : IUnknown
-{
- HRESULT ModifyApplicationPolicy(
- [in] LPCWSTR pwzSourceAssemblyIdentity,
- [in] LPCWSTR pwzTargetAssemblyIdentity,
- [in] BYTE *pbApplicationPolicy,
- [in] DWORD cbAppPolicySize,
- [in] DWORD dwPolicyModifyFlags,
- [out, size_is(*pcbNewAppPolicySize), annotation("_Out_writes_all_(*pcbNewAppPolicySize)")]
- BYTE *pbNewApplicationPolicy,
- [in, out] DWORD *pcbNewAppPolicySize
- );
-
- HRESULT EvaluatePolicy(
- [in] LPCWSTR pwzReferenceIdentity,
- [in] BYTE *pbApplicationPolicy,
- [in] DWORD cbAppPolicySize,
- [out, size_is(*pcchPostPolicyReferenceIdentity), annotation("_Out_writes_all_(*pcchPostPolicyReferenceIdentity)")]
- LPWSTR pwzPostPolicyReferenceIdentity,
- [in, out] DWORD *pcchPostPolicyReferenceIdentity,
- [out] DWORD *pdwPoliciesApplied
- );
-};
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
+#if defined(FEATURE_WINDOWSPHONE)
/*
* This interface is used to get information about the GC system and
@@ -1778,7 +649,7 @@ interface ICLRGCManager2 : ICLRGCManager
};
-#endif //FEATURE_INCLUDE_ALL_INTERFACES || FEATURE_WINDOWSPHONE
+#endif // FEATURE_WINDOWSPHONE
///////////////////////////////////////////////////////////////////////////////
//
@@ -1827,64 +698,6 @@ typedef enum _HostApplicationPolicy
}EHostApplicationPolicy;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-///////////////////////////////////////////////////////////////////////////////
-//
-// IHostAssemblyStore
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- local,
- object,
- version(1.0),
- uuid(7b102a88-3f7f-496d-8fa2-c35374e01af3),
- helpstring("Assembly Store provided by host"),
- pointer_default(unique)
-]
-interface IHostAssemblyStore: IUnknown
-{
- HRESULT ProvideAssembly
- (
- [in] AssemblyBindInfo *pBindInfo,
- [out] UINT64 *pAssemblyId,
- [out] UINT64 *pContext,
- [out] IStream **ppStmAssemblyImage,
- [out] IStream **ppStmPDB);
-
- HRESULT ProvideModule
- (
- [in] ModuleBindInfo *pBindInfo,
- [out] DWORD *pdwModuleId,
- [out] IStream **ppStmModuleImage,
- [out] IStream **ppStmPDB);
-};
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IHostAssemblyManager
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- local,
- object,
- version(1.0),
- uuid(613dabd7-62b2-493e-9e65-c1e32a1e0c5e),
- helpstring("Assembly Manager provided by host"),
- pointer_default(unique)
-]
-interface IHostAssemblyManager: IUnknown
-{
- HRESULT GetNonHostStoreAssemblies
- (
- [out] ICLRAssemblyReferenceList **ppReferenceList
- );
-
- HRESULT GetAssemblyStore
- (
- [out] IHostAssemblyStore **ppAssemblyStore
- );
-};
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
// Implemented in mscorwks.dll, use mscoree!GetRealProcAddress to get
// a function pointer of this API.
@@ -1980,8 +793,6 @@ interface ICLRRuntimeHost : IUnknown
[out] DWORD *pReturnValue);
};
-#ifdef FEATURE_CORECLR
-
// Keys for ICLRRuntmeHost2::Authenticate. No longer required.
cpp_quote("#define CORECLR_HOST_AUTHENTICATION_KEY 0x1C6CA6F94025800LL")
cpp_quote("#define CORECLR_HOST_AUTHENTICATION_KEY_NONGEN 0x1C6CA6F94025801LL")
@@ -2054,8 +865,6 @@ interface ICLRExecutionManager : IUnknown
HRESULT Resume([in] DWORD dwAppDomainId);
}
-#endif // FEATURE_CORECLR
-
//*****************************************************************************
// Interface to utilize HostProtection
//*****************************************************************************
@@ -2076,26 +885,6 @@ typedef enum
eAll = 0x1ff
} EApiCategories;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-[
- object,
- uuid(89F25F5C-CEEF-43e1-9CFA-A68CE863AAAC),
- helpstring("Host Protection Interface"),
- pointer_default(unique)
-]
-interface ICLRHostProtectionManager : IUnknown
-{
- // These allow the host to specify resources that could cause
- // instability in order to guarantee protection from them.
- HRESULT SetProtectedCategories([in] EApiCategories categories);
-
- // Call once before starting the runtime to sacrifice a little
- // assembly-loading-performance for a guarantee that a certain
- // rare race condition that can result in a FatalEE error won't
- // happen.
- HRESULT SetEagerSerializeGrantSets();
-};
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
//
// Interface for configuring the default AppDomain
@@ -2110,24 +899,6 @@ typedef enum
}
EInitializeNewDomainFlags;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-[
- object,
- uuid(270D00A2-8E15-4d0b-ADEB-37BC3E47DF77),
- helpstring("Default AppDomain Configuration Interface"),
- pointer_default(unique)
-]
-interface ICLRDomainManager : IUnknown
-{
- HRESULT SetAppDomainManagerType([in] LPCWSTR wszAppDomainManagerAssembly,
- [in] LPCWSTR wszAppDomainManagerType,
- [in] EInitializeNewDomainFlags dwInitializeDomainFlags);
-
- HRESULT SetPropertiesForDefaultAppDomain([in] DWORD nProperties,
- [in] LPCWSTR *pwszPropertyNames,
- [in] LPCWSTR *pwszPropertyValues);
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
//*****************************************************************************
// mscoree typelib definition
@@ -2210,24 +981,6 @@ library mscoree
HRESULT GetTypeNameBuilder([out, retval] ITypeNameBuilder** ppTypeBuilder);
};
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- //*****************************************************************************
- // Interface for apartment callbacks.
- //*****************************************************************************
- [
- object,
- oleautomation,
- uuid(178E5337-1528-4591-B1C9-1C6E484686D8),
- helpstring("Apartment callback interface"),
- pointer_default(unique)
- ]
- interface IApartmentCallback : IUnknown
- {
- HRESULT _stdcall DoCallback(
- [in] SIZE_T pFunc,
- [in] SIZE_T pData);
- };
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#ifdef _WIN64
#define CCW_PTR __int64 *
@@ -2259,24 +1012,6 @@ library mscoree
};
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- //*****************************************************************************
- // Interface for controlling a managed object
- //*****************************************************************************
- [
- object,
- oleautomation,
- uuid(04C6BE1E-1DB1-4058-AB7A-700CCCFBF254),
- helpstring("ICatalogServices Interface"),
- pointer_default(unique)
- ]
- interface ICatalogServices : IUnknown
- {
- HRESULT Autodone();
-
- HRESULT NotAutodone();
- };
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#ifdef FEATURE_COMINTEROP
//*****************************************************************************
@@ -2304,20 +1039,6 @@ library mscoree
};
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- [
- uuid(CB2F6723-AB3A-11d2-9C40-00C04FA30A3E),
- helpstring("Cor Runtime Hosting Class")
- ]
- coclass CorRuntimeHost
- {
- [default] interface ICorRuntimeHost;
- interface IGCHost;
- interface ICorConfiguration;
- interface IValidator;
- interface IDebuggerInfo;
- };
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
[
uuid(90F1A06E-7712-4762-86B5-7A5EBA6BDB02),
@@ -2345,64 +1066,6 @@ typedef enum
eRestrictedContext=0x01
} EContextType;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-///////////////////////////////////////////////////////////////////////////////
-//
-// IHostSecurityContext
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- object,
- version(1.0),
- uuid(7E573CE4-0343-4423-98D7-6318348A1D3C),
- helpstring("Security Context provided by host"),
- pointer_default(unique),
- local
-]
-
-interface IHostSecurityContext : IUnknown
-{
- HRESULT Capture([out] IHostSecurityContext** ppClonedContext);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IHostSecurityManager
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- object,
- version(1.0),
- uuid(75ad2468-a349-4d02-a764-76a68aee0c4f),
- helpstring("Security Manager provided by host"),
- pointer_default(unique),
- local
-]
-interface IHostSecurityManager: IUnknown
-{
- // Impersonation APIs.
- HRESULT ImpersonateLoggedOnUser(
- [in] HANDLE hToken);
-
- HRESULT RevertToSelf();
-
- HRESULT OpenThreadToken(
- [in] DWORD dwDesiredAccess,
- [in] BOOL bOpenAsSelf,
- [out] HANDLE *phThreadToken
- );
-
- HRESULT SetThreadToken(
- [in] HANDLE hToken);
-
- HRESULT GetSecurityContext([in] EContextType eContextType,
- [out] IHostSecurityContext** ppSecurityContext);
- // May return S_OK, E_FAIL (in what circumstances?)
- HRESULT SetSecurityContext([in] EContextType eContextType,
- [in] IHostSecurityContext* pSecurityContext);
-
-};
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/inc/apithreadstress.h b/src/inc/apithreadstress.h
index fc18dcc6e1..a0c6cdeb0b 100644
--- a/src/inc/apithreadstress.h
+++ b/src/inc/apithreadstress.h
@@ -46,37 +46,6 @@
#include "utilcode.h"
-#ifdef STRESS_THREAD
-
-class APIThreadStress
-{
- public:
- APIThreadStress();
- ~APIThreadStress();
-
- BOOL DoThreadStress();
- static void SyncThreadStress();
-
- static void SetThreadStressCount(int count);
-
- protected:
- virtual void Invoke() {LIMITED_METHOD_CONTRACT;};
-
- private:
- static DWORD WINAPI StartThread(void *arg);
-
- static int s_threadStressCount;
-
- int m_threadCount;
- HANDLE *m_hThreadArray;
- BOOL m_setupOK;
- LONG m_runCount;
- HANDLE m_syncEvent;
-
-};
-
-#else // STRESS_THREAD
-
class APIThreadStress
{
public:
@@ -85,6 +54,4 @@ class APIThreadStress
static void SetThreadStressCount(int count) { }
};
-#endif // STRESS_THREAD
-
#endif // _APITHREADSTRESS_H_
diff --git a/src/inc/appxutil.h b/src/inc/appxutil.h
index 2892ab7dd8..312c486332 100644
--- a/src/inc/appxutil.h
+++ b/src/inc/appxutil.h
@@ -24,7 +24,6 @@ template <typename T>
class NewArrayHolder;
BOOL WinRTSupported();
-#ifdef FEATURE_CORECLR
namespace AppX
{
@@ -34,103 +33,11 @@ namespace AppX
// On CoreCLR, the host is in charge of determining whether the process is AppX or not.
void SetIsAppXProcess(bool);
- inline bool IsAppXNGen()
- {
- WRAPPER_NO_CONTRACT;
- return false;
- }
-
#ifdef DACCESS_COMPILE
bool DacIsAppXProcess();
#endif // DACCESS_COMPILE
};
-#else // FEATURE_CORECLR
-
-struct AppXRTInfo;
-typedef DPTR(AppXRTInfo) PTR_AppXRTInfo;
-
-//---------------------------------------------------------------------------------------------
-namespace AppX
-{
- // cleans up resources allocated in InitAppXRT()
- void ShutDown();
-
- // Returns true if process is immersive (or if running in mockup environment).
- // NOTE: a return value of true doesn't necessarily indicate that the process is a
- // real Metro app, e.g. it could be an ngen process compiling an AppX assembly.
- bool IsAppXProcess();
-
-#ifdef DACCESS_COMPILE
- bool DacIsAppXProcess();
-#endif // DACCESS_COMPILE
-
- // Returns true if process is immersive (or if running in mockup environment).
- // Use only in NOFAULT regions when you are 100% sure that code:IsAppXProcess has been already called.
- // This function does not initialize (no faults).
- bool IsAppXProcess_Initialized_NoFault();
-
- // Returns true if process is NGen worker compiling an AppX assembly.
- bool IsAppXNGen();
-
- // Returns true if the host OS supports immersive apps.
- inline bool IsAppXSupported()
- { return WinRTSupported() != FALSE; }
-
- LPCWSTR GetHeadPackageMoniker();
-
- HRESULT GetCurrentPackageId(
- __inout PUINT32 pBufferLength,
- __out PBYTE pBuffer);
-
- HRESULT GetCurrentPackageInfo(
- __in UINT32 dwFlags,
- __inout PUINT32 pcbBuffer,
- __out PBYTE pbBuffer,
- __out PUINT32 nCount);
-
- bool IsAdaptiveApp();
- HRESULT GetCurrentPackageRoot(_Inout_ UINT32* length, _Out_opt_ PWSTR packageRoot);
- HRESULT GetWinMetadataDirForAdaptiveApps(_Out_ LPWSTR* winMetadDataDir);
-#ifdef FEATURE_APPX_BINDER
- enum FindFindInPackageFlags
- {
- FindFindInPackageFlags_None = 0,
- FindFindInPackageFlags_AllowLongFormatPath = 1,
- FindFindInPackageFlags_SkipCurrentPackageGraph = 2, // Only search in alt path
- };
-
- // If the function succeeds, pcchPathName is set to the length of the string that is copied to the buffer,
- // in characters, including the terminating null character, and the function returns S_OK. If the buffer
- // is too small, pcchPathName is set to the length of the buffer required (in characters),
- // including the terminating null character, and the function returns ERROR_INSUFFICIENT_BUFFER.
- HRESULT FindFileInCurrentPackage(
- __in PCWSTR pszFileName,
- __inout PUINT32 pcchPathName,
- __out PWSTR pszPathName,
- __in UINT32 uiFlags = PACKAGE_FILTER_CLR_DEFAULT,
- __in PCWSTR *rgwzAltPaths = NULL,
- __in UINT32 cAltPaths = 0,
- FindFindInPackageFlags findInCurrentPackageFlags = FindFindInPackageFlags_None);
-#endif // FEATURE_APPX_BINDER
-
- // Attempts to retrieve the AppContainer SID for the specified process.
- // For non-AppContainer processes the function will return S_FALSE and pAppContainerTokenInfo will be NULL.
- // For AppContainer processes the function will return S_OK and pAppContainerTokenInfo will contain data.
- // Note that there might be legitimate cases where this function fails (caller doesn't have permissions to
- // OpenProcess() for example) so any callers must account for such failures.
- // Use of NewArrayHolder permits method to reuse info for current process (dwPid == self) or to allocate
- // memory (dwPid != self). Cast the result to PTOKEN_APPCONTAINER_INFORMATION;
- HRESULT GetAppContainerTokenInfoForProcess(
- DWORD dwPid,
- NewArrayHolder<BYTE>& pbAppContainerTokenInfo, // Cast to PTOKEN_APPCONTAINER_INFORMATION on return.
- DWORD* pcbAppContainerTokenInfo = nullptr);
-
- // Called during NGen to pretend that we are in a certain package.
- HRESULT SetCurrentPackageForNGen(__in PCWSTR pszPackageFullName);
-}
-
-#endif // FEATURE_CORECLR
#else // FEATURE_APPX
diff --git a/src/inc/binderngen.idl b/src/inc/binderngen.idl
index d20cf93701..f3d41cd6a6 100644
--- a/src/inc/binderngen.idl
+++ b/src/inc/binderngen.idl
@@ -36,7 +36,6 @@ cpp_quote("#endif")
// interface IAssemblyName defined in fusion.idl
// interface IAssemblyEnum defined in fusion.idl
-// interface IFusionBindLog defined in fusionpriv.idl
// interface ICorSvcLogger defined in mscorsvc.idl
interface IAssemblyLocation;
diff --git a/src/inc/clrconfig.h b/src/inc/clrconfig.h
index 6d8c98190d..c15e2eb2f5 100644
--- a/src/inc/clrconfig.h
+++ b/src/inc/clrconfig.h
@@ -164,9 +164,6 @@ public:
//
// Methods to do config value (DWORD and String) lookups.
//
-#ifdef FEATURE_WIN_DB_APPCOMPAT
- static HRESULT getQuirkEnabledAndValueFromWinDB(LPCWSTR wszQuirkName, BOOL* isEnabled, CPT_QUIRK_DATA* quirkData);
-#endif
static BOOL IsConfigEnabled(const ConfigDWORDInfo & info);
// Look up a DWORD config value.
@@ -201,9 +198,6 @@ public:
// Register PerformanceDefaults' LookupConfigValue so CLRConfig can support 'MayHavePerformanceDefault' values
static void RegisterGetPerformanceDefaultValueCallback(GetPerformanceDefaultValueFunction func);
-#ifdef FEATURE_WIN_DB_APPCOMPAT
- static void RegisterWinDbQuirkApis(PFN_CptQuirkIsEnabled3 func1, PFN_CptQuirkGetData2 func2);
-#endif // FEATURE_WIN_DB_APPCOMPAT
private:
@@ -213,10 +207,6 @@ private:
// Function pointer to PerformanceDefaults' LookupConfigValue function (can't static bind from utilcode to VM)
static GetPerformanceDefaultValueFunction s_GetPerformanceDefaultValueCallback;
-#ifdef FEATURE_WIN_DB_APPCOMPAT
- static PFN_CptQuirkIsEnabled3 s_IsQuirkEnabledCallback;
- static PFN_CptQuirkGetData2 s_GetQuirkValueCallback;
-#endif // FEATURE_WIN_DB_APPCOMPAT
// Helper method to translate LookupOptions to REGUTIL::CORConfigLevel
static REGUTIL::CORConfigLevel GetConfigLevel(LookupOptions options);
diff --git a/src/inc/clrconfigvalues.h b/src/inc/clrconfigvalues.h
index eb321f3b3b..a0c24567d7 100644
--- a/src/inc/clrconfigvalues.h
+++ b/src/inc/clrconfigvalues.h
@@ -123,13 +123,9 @@ CONFIG_DWORD_INFO(INTERNAL_AppDomainNoUnload, W("AppDomainNoUnload"), 0, "Not us
RETAIL_CONFIG_STRING_INFO_EX(INTERNAL_TargetFrameworkMoniker, W("TargetFrameworkMoniker"), "Allows the test team to specify what TargetFrameworkMoniker to use.", CLRConfig::IgnoreHKLM | CLRConfig::IgnoreHKCU | CLRConfig::IgnoreConfigFiles | CLRConfig::IgnoreWindowsQuirkDB)
RETAIL_CONFIG_STRING_INFO_EX(INTERNAL_AppContextSwitchOverrides, W("AppContextSwitchOverrides"), "Allows default switch values defined in AppContext to be overwritten by values in the Config", CLRConfig::IgnoreEnv | CLRConfig::IgnoreHKLM | CLRConfig::IgnoreHKCU | CLRConfig::IgnoreWindowsQuirkDB | CLRConfig::ConfigFile_ApplicationFirst)
-#ifdef FEATURE_CORECLR
// For the proposal and discussion on why finalizers are not run on shutdown by default anymore in CoreCLR, see the API review:
// https://github.com/dotnet/corefx/issues/5205
#define DEFAULT_FinalizeOnShutdown (0)
-#else
-#define DEFAULT_FinalizeOnShutdown (1)
-#endif
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_FinalizeOnShutdown, W("FinalizeOnShutdown"), DEFAULT_FinalizeOnShutdown, "When enabled, on shutdown, blocks all user threads and calls finalizers for all finalizable objects, including live objects")
//
@@ -160,9 +156,6 @@ RETAIL_CONFIG_DWORD_INFO(EXTERNAL_DateTime_NetFX40AmPmParseAdjustment, W("Enable
#ifdef FEATURE_RANDOMIZED_STRING_HASHING
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_UseRandomizedStringHashAlgorithm, W("UseRandomizedStringHashAlgorithm"), 0, "Flag to use a string hashing algorithm who's behavior differs between AppDomains")
#endif // FEATURE_RANDOMIZED_STRING_HASHING
-#ifdef FEATURE_APPX
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_Windows8ProfileAPICheckFlag, W("Windows8ProfileAPICheckFlag"), 0, "Windows 8 Profile API check behavior (non-W8P framework APIs cannot be accessed through Reflection and RefEmit). 0: normal (only check in non-dev-mode APPX). 1: always check. 2: never check.");
-#endif
//
// Conditional breakpoints
@@ -312,9 +305,7 @@ RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_gcConcurrent, W("gcConcurrent"), (DWORD)-1,
#ifdef FEATURE_CONSERVATIVE_GC
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_gcConservative, W("gcConservative"), 0, "Enables/Disables conservative GC")
#endif
-#ifdef FEATURE_CORECLR
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_gcServer, W("gcServer"), 0, "Enables server GC")
-#endif
CONFIG_STRING_INFO(INTERNAL_GcCoverage, W("GcCoverage"), "specify a method or regular expression of method names to run with GCStress")
CONFIG_STRING_INFO(INTERNAL_SkipGCCoverage, W("SkipGcCoverage"), "specify a list of assembly names to skip with GC Coverage")
RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(UNSUPPORTED_gcForceCompact, W("gcForceCompact"), "When set to true, always do compacting GC")
@@ -386,7 +377,7 @@ CONFIG_STRING_INFO_EX(INTERNAL_JitDebugBreak, W("JitDebugBreak"), "", CLRConfig:
CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_JitDebuggable, W("JitDebuggable"), "")
CONFIG_DWORD_INFO_EX(INTERNAL_JitDefaultFill, W("JitDefaultFill"), 0xDD, "In debug builds, initialize the memory allocated by the nra with this byte.", CLRConfig::REGUTIL_default)
CONFIG_DWORD_INFO_EX(INTERNAL_JitDirectAlloc, W("JitDirectAlloc"), 0, "", CLRConfig::REGUTIL_default)
-#if (!defined(DEBUG) && !defined(_DEBUG)) || (defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR))
+#if !defined(DEBUG) && !defined(_DEBUG)
#define INTERNAL_JitEnableNoWayAssert_Default 0
#else
#define INTERNAL_JitEnableNoWayAssert_Default 1
@@ -477,7 +468,7 @@ RETAIL_CONFIG_DWORD_INFO(EXTERNAL_UseLegacyJit, W("useLegacyJit"), 0, "Set to 1
RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_DisableNativeImageLoadList, W("DisableNativeImageLoadList"), "Refuse to load native images corresponding to one of the assemblies on this semicolon-delimited list of assembly names.", CLRConfig::REGUTIL_default)
#endif
-#if defined(FEATURE_CORECLR) && defined(_TARGET_X86_)
+#if defined(_TARGET_X86_)
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_UseWindowsX86CoreLegacyJit, W("UseWindowsX86CoreLegacyJit"), 0, "Set to 1 to do all JITing with compatjit.dll. Only applicable to Windows x86 .NET Core.")
#endif
@@ -670,9 +661,6 @@ CONFIG_DWORD_INFO_EX(INTERNAL_MD_RegMetaDump, W("MD_RegMetaDump"), 0, "? Dump MD
CONFIG_DWORD_INFO_EX(INTERNAL_MD_TlbImp_BreakOnErr, W("MD_TlbImp_BreakOnErr"), 0, "ASSERT when importing TLB into MD", CLRConfig::REGUTIL_default)
CONFIG_STRING_INFO_EX(INTERNAL_MD_TlbImp_BreakOnTypeImport, W("MD_TlbImp_BreakOnTypeImport"), "ASSERT when importing a type from TLB", (CLRConfig::LookupOptions) (CLRConfig::REGUTIL_default | CLRConfig::DontPrependCOMPlus_))
// MetaData - Desktop-only
-#ifndef FEATURE_CORECLR
-RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_MD_UseMinimalDeltas, W("MD_UseMinimalDeltas"), 1, "? Some MD modifications when applying EnC?", CLRConfig::REGUTIL_default)
-#endif //!FEATURE_CORECLR
CONFIG_DWORD_INFO_EX(INTERNAL_MD_WinMD_Disable, W("MD_WinMD_Disable"), 0, "Never activate the WinMD import adapter", CLRConfig::REGUTIL_default)
CONFIG_DWORD_INFO_EX(INTERNAL_MD_WinMD_AssertOnIllegalUsage, W("MD_WinMD_AssertOnIllegalUsage"), 0, "ASSERT if a WinMD import adapter detects a tool incompatibility", CLRConfig::REGUTIL_default)
@@ -777,12 +765,7 @@ RETAIL_CONFIG_STRING_INFO_EX(UNSUPPORTED_NicPath, W("NicPath"), "Redirects NIC a
RETAIL_CONFIG_DWORD_INFO(INTERNAL_NGenTaskDelayStart, W("NGenTaskDelayStart"), 0, "Use NGen Task delay start trigger, instead of critical idle task")
// Flag for cross-platform ngen: Removes all execution of managed or third-party code in the ngen compilation process.
-#ifdef FEATURE_CORECLR
RETAIL_CONFIG_DWORD_INFO(INTERNAL_Ningen, W("Ningen"), 1, "Enable no-impact ngen")
-#else
-// Ningen is off by default for desktop to reduce compat risk
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_Ningen, W("Ningen"), 0, "Enable no-impact ngen")
-#endif
CONFIG_DWORD_INFO(INTERNAL_NoASLRForNgen, W("NoASLRForNgen"), 0, "Turn off IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE bit in generated ngen images. Makes nidump output repeatable from run to run.")
RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_NgenAllowOutput, W("NgenAllowOutput"), 0, "If set to 1, the NGEN worker will bind to the parent console, thus allowing stdout output to work", CLRConfig::REGUTIL_default)
@@ -953,6 +936,12 @@ CONFIG_DWORD_INFO(INTERNAL_SuspendDeadlockTimeout, W("SuspendDeadlockTimeout"),
CONFIG_DWORD_INFO(INTERNAL_SuspendThreadDeadlockTimeoutMs, W("SuspendThreadDeadlockTimeoutMs"), 2000, "")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadSuspendInjection, W("INTERNAL_ThreadSuspendInjection"), 1, "Specifies whether to inject activations for thread suspension on Unix")
+//
+// Thread (miscellaneous)
+//
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_Thread_DeadThreadCountThresholdForGCTrigger, W("Thread_DeadThreadCountThresholdForGCTrigger"), 75, "In the heuristics to clean up dead threads, this threshold must be reached before triggering a GC will be considered. Set to 0 to disable triggering a GC based on dead threads.")
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_Thread_DeadThreadGCTriggerPeriodMilliseconds, W("Thread_DeadThreadGCTriggerPeriodMilliseconds"), 1000 * 60 * 30, "In the heuristics to clean up dead threads, this much time must have elapsed since the previous max-generation GC before triggering another GC will be considered")
+
//
// Threadpool
//
@@ -980,6 +969,15 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_SampleIntervalLow,
RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_SampleIntervalHigh, W("HillClimbing_SampleIntervalHigh"), 200, "");
RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_GainExponent, W("HillClimbing_GainExponent"), 200, "The exponent to apply to the gain, times 100. 100 means to use linear gain, higher values will enhance large moves and damp small ones.");
+
+//
+// Tiered Compilation
+//
+#ifdef FEATURE_TIERED_COMPILATION
+RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_TieredCompilation, W("EXPERIMENTAL_TieredCompilation"), 0, "Enables tiered compilation")
+#endif
+
+
//
// TypeLoader
//
@@ -1027,11 +1025,7 @@ CONFIG_DWORD_INFO(INTERNAL_DebugAssertOnMissedCOWPage, W("DebugAssertOnMissedCOW
#endif //FEATURE_LAZY_COW_PAGES
-#ifdef FEATURE_CORECLR
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_ReadyToRun, W("ReadyToRun"), 1, "Enable/disable use of ReadyToRun native code") // On by default for CoreCLR
-#else
-RETAIL_CONFIG_DWORD_INFO(EXTERNAL_ReadyToRun, W("ReadyToRun"), 0, "Enable/disable use of ReadyToRun native code") // Off by default for desktop
-#endif
RETAIL_CONFIG_STRING_INFO(EXTERNAL_ReadyToRunExcludeList, W("ReadyToRunExcludeList"), "List of assemblies that cannot use Ready to Run images")
RETAIL_CONFIG_STRING_INFO(EXTERNAL_ReadyToRunLogFile, W("ReadyToRunLogFile"), "Name of file to log success/failure of using Ready to Run images")
@@ -1060,6 +1054,11 @@ RETAIL_CONFIG_STRING_INFO(INTERNAL_LocalWinMDPath, W("LocalWinMDPath"), "Additio
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_AllowDComReflection, W("AllowDComReflection"), 0, "Allows out of process DCOM clients to marshal blocked reflection types.")
//
+// Performance Tracing
+//
+RETAIL_CONFIG_DWORD_INFO(INTERNAL_PerformanceTracing, W("PerformanceTracing"), 0, "Enable/disable performance tracing. Non-zero values enable tracing.")
+
+//
// Unknown
//
//---------------------------------------------------------------------------------------
@@ -1076,7 +1075,6 @@ CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_AlwaysUseMetadataInterfaceMapLayout, W(
CONFIG_DWORD_INFO(INTERNAL_AssertOnUnneededThis, W("AssertOnUnneededThis"), 0, "While the ConfigDWORD is unnecessary, the contained ASSERT should be kept. This may result in some work tracking down violating MethodDescCallSites.")
CONFIG_DWORD_INFO_EX(INTERNAL_AssertStacktrace, W("AssertStacktrace"), 1, "", CLRConfig::REGUTIL_default)
RETAIL_CONFIG_STRING_INFO_DIRECT_ACCESS(UNSUPPORTED_BuildFlavor, W("BuildFlavor"), "Choice of build flavor (wks or svr) of CLR")
-CONFIG_DWORD_INFO(INTERNAL_CerLogging, W("CerLogging"), 0, "In vm\\ConstrainedExecutionRegion.cpp. Debug-only logging when we prepare methods, find reliability contract problems, restore stuff from ngen images, etc.")
CONFIG_DWORD_INFO_EX(INTERNAL_clearNativeImageStress, W("clearNativeImageStress"), 0, "", CLRConfig::REGUTIL_default)
RETAIL_CONFIG_STRING_INFO_DIRECT_ACCESS(INTERNAL_CLRLoadLogDir, W("CLRLoadLogDir"), "Enable logging of CLR selection")
RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_CONFIG, W("CONFIG"), "Used to specify an XML config file for EEConfig", CLRConfig::REGUTIL_default)
@@ -1128,11 +1126,7 @@ CONFIG_DWORD_INFO_EX(INTERNAL_MscorsnLogging, W("MscorsnLogging"), 0, "Enables s
RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_NativeImageRequire, W("NativeImageRequire"), 0, "", CLRConfig::REGUTIL_default)
CONFIG_DWORD_INFO_EX(INTERNAL_NestedEhOom, W("NestedEhOom"), 0, "", CLRConfig::REGUTIL_default)
RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_NO_SO_NOT_MAINLINE, W("NO_SO_NOT_MAINLINE"), 0, "", CLRConfig::REGUTIL_default)
-#if defined(CROSSGEN_COMPILE) || defined(FEATURE_CORECLR)
#define INTERNAL_NoGuiOnAssert_Default 1
-#else
-#define INTERNAL_NoGuiOnAssert_Default 0
-#endif
RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_NoGuiOnAssert, W("NoGuiOnAssert"), INTERNAL_NoGuiOnAssert_Default, "", CLRConfig::REGUTIL_default)
RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_NoProcedureSplitting, W("NoProcedureSplitting"), 0, "", CLRConfig::REGUTIL_default)
CONFIG_DWORD_INFO_EX(INTERNAL_NoStringInterning, W("NoStringInterning"), 1, "Disallows string interning. I see no value in it anymore.", CLRConfig::REGUTIL_default)
diff --git a/src/inc/clrhost.h b/src/inc/clrhost.h
index 8cd9e3e9c2..9fe978f95a 100644
--- a/src/inc/clrhost.h
+++ b/src/inc/clrhost.h
@@ -364,9 +364,7 @@ private:
SEMAPHORE_COOKIE m_semaphore;
};
-#if defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
HMODULE GetCLRModule ();
-#endif // defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
#ifndef FEATURE_NO_HOST
/*
diff --git a/src/inc/clrinternal.idl b/src/inc/clrinternal.idl
index 4193d1bfe8..0c93f4ae6d 100644
--- a/src/inc/clrinternal.idl
+++ b/src/inc/clrinternal.idl
@@ -16,17 +16,7 @@ import "unknwn.idl";
// import mscoree.idl for BucketParameters definition
import "mscoree.idl";
-#ifndef FEATURE_CORECLR
-import "hstring.idl";
-#endif //!FEATURE_CORECLR
-#ifndef FEATURE_CORECLR
-interface IActivationFactory;
-cpp_quote("interface IActivationFactory;")
-
-interface IWinRTClassActivator;
-cpp_quote("interface IWinRTClassActivator;")
-#endif //!FEATURE_CORECLR
cpp_quote("#if 0")
@@ -97,30 +87,6 @@ cpp_quote("EXTERN_GUID(CLR_ID_ONECORE_CLR, 0xb1ee760d, 0x6c4a, 0x4533, 0xba, 0x4
// IID_IPrivateManagedExceptionReporting : uuid{AD76A023-332D-4298-8001-07AA9350DCA4}
cpp_quote("EXTERN_GUID(IID_IPrivateManagedExceptionReporting, 0xad76a023, 0x332d, 0x4298, 0x80, 0x01, 0x07, 0xaa, 0x93, 0x50, 0xdc, 0xa4);")
-#ifndef FEATURE_CORECLR
-// CLSID CLRRuntimeHostInternal : uuid(f7721072-bf57-476d-89f8-a7625d27683a)
-cpp_quote("EXTERN_GUID(CLSID_CLRRuntimeHostInternal, 0xf7721072, 0xbf57, 0x476d, 0x89, 0xf8, 0xa7, 0x62, 0x5d, 0x27, 0x68, 0x3a);")
-// IID ICLRRuntimeHostInternal : uuid{07C4E752-3CBA-4A07-9943-B5F206382178}
-cpp_quote("EXTERN_GUID(IID_ICLRRuntimeHostInternal, 0x07c4e752, 0x3cba, 0x4a07, 0x99, 0x43, 0xb5, 0xf2, 0x06, 0x38, 0x21, 0x78);")
-
-// CLSID_CLRShimControlInternal : uuid(62D02A5B-F527-44d8-80BC-650BBD3CB082)
-cpp_quote("EXTERN_GUID(CLSID_CLRShimControlInternal, 0x62d02a5b, 0xf527, 0x44d8, 0x80, 0xbc, 0x65, 0xb, 0xbd, 0x3c, 0xb0, 0x82);")
-
-// IID ICLRShimControlInternal : uuid{826AAAD7-717B-44f8-9BB0-7DAC368B85A5}
-cpp_quote("EXTERN_GUID(IID_ICLRShimControlInternal, 0x826AAAD7, 0x717b, 0x44f8, 0x9b, 0xb0, 0x7d, 0xac, 0x36, 0x8b, 0x85, 0xa5);")
-
-// CLSID_CLRActivationFactory : uuid{5B132A7D-DA8E-461b-A0F2-109141C768CB}
-cpp_quote("EXTERN_GUID(CLSID_CLRActivationFactory, 0x5b132a7d, 0xda8e, 0x461b, 0xa0, 0xf2, 0x10, 0x91, 0x41, 0xc7, 0x68, 0xcb );")
-
-// IID_ICLRActivationFactory : uuid{331F2F6C-385F-462c-9125-816712FB2BC6}
-cpp_quote("EXTERN_GUID(IID_ICLRActivationFactory, 0x331f2f6c, 0x385f, 0x462c, 0x91, 0x25, 0x81, 0x67, 0x12, 0xfb, 0x2b, 0xc6);")
-
-// IID_ICLRActivationFactory2 : uuid{035049E5-2658-40C0-9269-21C48D8F0748}
-cpp_quote("EXTERN_GUID(IID_ICLRActivationFactory2, 0x035049E5, 0x2658, 0x40C0, 0x92, 0x69, 0x21, 0xC4, 0x8D, 0x8F, 0x07, 0x48);")
-
-// IID IID_ICLRExecutionManager: uuid(1000A3E7-B420-4620-AE30-FB19B587AD1D)
-cpp_quote("EXTERN_GUID(IID_ICLRExecutionManager, 0x1000A3E7, 0xB420, 0x4620, 0xAE, 0x30, 0xFB, 0x19, 0xB5, 0x87, 0xAD, 0x1D);")
-#endif // !FEATURE_CORECLR
//*****************************************************************************
// Interface for exposing services from the EE to other DLLs of the CLR.
@@ -327,165 +293,4 @@ interface IPrivateManagedExceptionReporting : IUnknown
HRESULT GetBucketParametersForCurrentException([out]BucketParameters *pParams);
}
-#ifndef FEATURE_CORECLR
-/**************************************************************************************
- ** ICLRRuntimeHostInternal **
- ** This is the functionality used only by CLR internal tools that moved from being **
- ** flat APIs (loading the latest runtime) to something that is runtime-specific and **
- ** requires the runtime to be loaded. **
- **************************************************************************************/
-[
- uuid(07C4E752-3CBA-4A07-9943-B5F206382178),
- version(1.0),
- helpstring("CLR internal hosting interface for V4.0"),
- local
-]
-interface ICLRRuntimeHostInternal : IUnknown
-{
- HRESULT MetaDataGetDispenser(
- [in] REFCLSID rclsid,
- [in] REFIID riid,
- [out, iid_is(riid), retval] IUnknown **ppInterface);
-
- HRESULT GetAssemblyMDImport(
- [in] LPCWSTR wszFileName, // The scope (file name) to open.
- [in] REFIID riid, // Desired interface.
- [out, iid_is(riid), retval] IUnknown **ppIUnk); // Returned interface on success.
-
- HRESULT GetMetaDataInternalInterface(
- [in, size_is(cbData)] BYTE *pbData, // MetaData data.
- [in] ULONG cbData, // MetaData data size.
- [in] DWORD flags, // Flags.
- [in] REFIID riid, // Desired interface.
- [out, iid_is(riid), retval] LPVOID *ppInterface); // Returned interface.
-
- HRESULT GetMetaDataInternalInterfaceFromPublic(
- [in] IUnknown *pInterface, // Given interface.
- [in] REFIID riid, // Desired interface.
- [out, iid_is(riid), retval] LPVOID *ppInterface); // Returned interface.
-
- HRESULT GetMetaDataPublicInterfaceFromInternal(
- [in] IUnknown *pInterface, // Given interface.
- [in] REFIID riid, // Desired interface.
- [out, iid_is(riid), retval] LPVOID *ppInterface); // Returned interface.
-
- /**********************************************************************************
- ** Returns the version string that MD emitter should by default write to images.**
- ** Supersedes: GetCORRequiredVersion **
- **********************************************************************************/
- HRESULT GetImageVersionString(
- [out, size_is(*pcchBuffer), annotation("__out_ecount_opt(*pcchBuffer)")] LPWSTR pwzBuffer, // Returned version string.
- [in, out] DWORD *pcchBuffer); // Buffer size/version length.
-
- /**********************************************************************************
- ** Locks the given module for this runtime. The HRESULT is S_OK if it is the **
- ** runtime represented by this instance, S_FALSE if somebody beat us to it. **
- **********************************************************************************/
- HRESULT LockModuleForRuntime(
- [in] BYTE *pModuleBase, // Address where the module is mapped.
- [in] REFIID riid, // Desired interface.
- [out, iid_is(riid)] LPVOID *ppRuntime); // The owning runtime.
-
- /**********************************************************************************
- ** Asks the Shim to attempt a graceful shutdown of all other runtimes loaded **
- ** in this process, then to exit the process via ::ExitProcess(). V4+ runtimes **
- ** call this instead of ::ExitProcess(). **
- **********************************************************************************/
- HRESULT ShutdownAllRuntimesThenExit(
- [in] UINT exitCode); // Process exit code.
-
- /**********************************************************************************
- ** GetTrueOSVersion - Bypasses the OS compatibility shim **
- **********************************************************************************/
- HRESULT GetTrueOSVersion(
- [out, in] LPOSVERSIONINFO osvi); // OS Version.
-
- /**********************************************************************************
- ** Returns the runtime that a COM component with the given CLSID would be **
- ** activated in. Returns runtime represented by this instance for Fx types. **
- **********************************************************************************/
- HRESULT GetRuntimeForManagedCOMObject(
- [in] REFCLSID rclsid, // CLSID of the component.
- [in] REFIID riid, // Desired runtime interface.
- [out, iid_is(riid), retval] LPVOID *ppRuntime); // Returned runtime.
-}; // interface ICLRRuntimeHostInternal
-
-/**************************************************************************************
- ** ICLRShimControlInternal **
- ** This is the functionality used only by CLR internal tools that moved from being **
- ** flat APIs (loading the latest runtime) to controlshim behavior **
- **************************************************************************************/
-[
- uuid(826AAAD7-717B-44f8-9BB0-7DAC368B85A5),
- version(1.0),
- helpstring("CLR internal hosting interface for V4.0"),
- local
-]
-interface ICLRShimControlInternal : IUnknown
-{
- HRESULT SetShouldSkipSkuCheck(
- [in] BOOL bValue
- );
-}; // interface ICLRRuntimeHostInternal
-
-
-
-/**************************************************************************************
- ** ICLRActivationFactory **
- ** This is the functionality used only by CLR to provide in-proc **
- ** hosting **
- **************************************************************************************/
-[
- uuid(331F2F6C-385F-462c-9125-816712FB2BC6),
- version(1.0),
- helpstring("CLR internal activation factory for V4.5"),
- local
-]
-interface ICLRActivationFactory : IUnknown
-{
- HRESULT CreateFactory([in] LPCWSTR activatableClassId,
- [out, retval] IActivationFactory** factory);
-
-}; // interface ICLRActivationFactory
-
-/**************************************************************************************
- ** ICLRActivationFactory2 **
- ** This is functionality exposed by the CLR to enable hosting WinRT components in a **
- ** non-AppX process **
- **************************************************************************************/
-[
- uuid(035049E5-2658-40C0-9269-21C48D8F0748),
- version(1.0),
- helpstring("CLR internal activation factory for desktop WinRT activation"),
- local
-]
-interface ICLRActivationFactory2 : ICLRActivationFactory
-{
- HRESULT GetClassActivatorForApplication(HSTRING appPath, [out] IWinRTClassActivator** ppActivator);
-};
-
-typedef enum
-{
- PAUSE_APP_DOMAINS = 0x1
-
-} PauseFlags;
-
-[
- uuid(1000A3E7-B420-4620-AE30-FB19B587AD1D),
- version(1.0),
- helpstring("Pause and Resume Interface"),
- pointer_default(unique),
- local
-]
-interface ICLRExecutionManager : IUnknown
-{
- // Pause all managed threads
- // Parameters are ignored and reserved for future use.
- HRESULT Pause([in] DWORD dwAppDomainId, [in] DWORD dwFlags);
-
- // Resume managed threads
- // Parameters are ignored and reserved for future use.
- HRESULT Resume([in] DWORD dwAppDomainId);
-}
-#endif // !FEATURE_CORECLR
diff --git a/src/inc/clrnt.h b/src/inc/clrnt.h
index 08a93a4961..ebea066663 100644
--- a/src/inc/clrnt.h
+++ b/src/inc/clrnt.h
@@ -80,10 +80,8 @@
#define __field_ecount(EHCount)
#endif
-#ifdef FEATURE_CORECLR
#undef _Ret_bytecap_
#define _Ret_bytecap_(_Size)
-#endif
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
diff --git a/src/inc/clrprivbinderutil.h b/src/inc/clrprivbinderutil.h
index 129e90388e..d42f2b8d66 100644
--- a/src/inc/clrprivbinderutil.h
+++ b/src/inc/clrprivbinderutil.h
@@ -11,9 +11,6 @@
#include "holder.h"
#include "internalunknownimpl.h"
-#ifdef FEATURE_FUSION
-#include "fusion.h"
-#endif
#include "clrprivbinding.h"
#include "slist.h"
#ifdef FEATURE_COMINTEROP
@@ -89,125 +86,6 @@ namespace CLRPrivBinderUtil
}
//=====================================================================================================================
-#ifdef FEATURE_FUSION
- class CLRPrivAssemblyBindResultWrapper :
- public IUnknownCommon<
- IBindResult,
- IAssemblyLocation>
- {
- public:
- //-----------------------------------------------------------------------------------------------------------------
- CLRPrivAssemblyBindResultWrapper(
- IAssemblyName *pIAssemblyName,
- PCWSTR wzAssemblyPath,
- IILFingerprintFactory *pILFingerprintFactory
- );
-
- //-----------------------------------------------------------------------------------------------------------------
- ~CLRPrivAssemblyBindResultWrapper();
-
- protected:
- //=================================================================================================================
- // IBindResult methods
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(GetAssemblyNameDef)(
- /*out*/ IAssemblyName **ppIAssemblyNameDef);
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(GetNextAssemblyModuleName)(
- /*in*/ DWORD dwNIndex,
- __inout_ecount(*pdwCCModuleName) LPWSTR pwzModuleName,
- /*in, out, annotation("__inout")*/ LPDWORD pdwCCModuleName);
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(GetAssemblyLocation)(
- /*out*/ IAssemblyLocation **ppIAssemblyLocation);
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(GetNativeImage)(
- /*out*/ IBindResult **ppIBindResultNI,
- /*out*/ BOOL *pfIBindResultNIProbed);
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(SetNativeImage)(
- /*in*/ IBindResult *pIBindResultNI,
- /*out*/ IBindResult **ppIBindResultNIFinal);
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(IsEqual)(
- /*in*/ IUnknown *pIUnk);
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(GetNextAssemblyNameRef)(
- /*in*/ DWORD dwNIndex,
- /*out*/ IAssemblyName **ppIAssemblyNameRef);
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(GetNextDependentAssembly)(
- /*in*/ DWORD dwNIndex,
- /*out*/ IUnknown **ppIUnknownAssembly);
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(GetAssemblyLocationOfILImage)(
- /*out*/ IAssemblyLocation **ppAssemblyLocation);
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(GetILFingerprint)(
- /*out*/ IILFingerprint **ppFingerprint);
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(GetSourceILTimestamp)(
- /*out*/ FILETIME* pFileTime);
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(GetSourceILSize)(
- /*out*/ DWORD* pSize);
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(GetNIInfo)(
- /*out*/ INativeImageInstallInfo** pInfo);
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(GetFlags)(
- /*out*/ DWORD * pdwFlags);
-
- //=================================================================================================================
- // IAssemblyLocation methods
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(GetLocationType)(
- /*out*/DWORD *pdwLocationType);
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(GetPath)(
- __inout_ecount(*pdwccAssemblyPath) LPWSTR pwzAssemblyPath,
- /*in, annotation("__inout")*/ LPDWORD pdwccAssemblyPath);
-
- //-----------------------------------------------------------------------------------------------------------------
- STDMETHOD(GetHostID)(
- /*out*/ UINT64 *puiHostID);
-
- private:
- inline PCWSTR GetILAssemblyPath()
- { LIMITED_METHOD_CONTRACT; return m_wzAssemblyPath; }
-
- NewArrayHolder<WCHAR> m_wzAssemblyPath;
- IAssemblyName * m_pIAssemblyName;
-
- // Since m_bIBindResultNISet and m_pIBindResultNI are separate data, they both need
- // to be treated as volatile, making sure to always fetch m_bIBindResultNISet first
- // and only read m_pIBindResultNI if m_bIBindResultNISet is true.
- Volatile<bool> m_bIBindResultNISet;
- VolatilePtr<IBindResult> m_pIBindResultNI;
-
- IILFingerprint * m_pIILFingerprint;
- ReleaseHolder<IILFingerprintFactory> m_pILFingerprintFactory;
-
- // Used as a leaf lock for publishing, such as m_pIBindResultNI.
- Crst m_lock;
- }; // class CLRPrivAssemblyBindResultWrapper
-#endif // FEATURE_FUSION
//=================================================================================================================
// Used to create an identity-only ICLRPrivAssembly from an ICLRPrivBinder. This is currently used when
@@ -859,9 +737,6 @@ namespace CLRPrivBinderUtil
/** probably should be exposed on an instance (of something) method rather that magically calling GetAppDomain() **/
ICLRPrivAssembly* RaiseAssemblyResolveEvent(IAssemblyName *pAssemblyName, ICLRPrivAssembly* pRequestingAssembly);
- /** PLACEHOLDER - CLRPRivBinderFusion::BindAssemblyByName throws, despite being an HRESULT function,
- most presumably because returning HRESULT is too lossy **/
-
/** Ultimately, only the binder can do ref-def matching, and it should be opaque to CLR.
This is not trivial to do, however, since we cannot do data conversion as the function is nofault **/
BOOL CompareHostBinderSpecs(AssemblySpec* a1, AssemblySpec* a2);
diff --git a/src/inc/clrtypes.h b/src/inc/clrtypes.h
index 5f9de0cbf1..b0b1fc23f4 100644
--- a/src/inc/clrtypes.h
+++ b/src/inc/clrtypes.h
@@ -12,7 +12,7 @@
#ifndef CLRTYPES_H_
#define CLRTYPES_H_
-#if defined(_MSC_VER) && !defined(SOURCE_FORMATTING) && (!defined(FEATURE_CORECLR) || defined(FEATURE_CORESYSTEM))
+#if defined(_MSC_VER) && !defined(SOURCE_FORMATTING) && defined(FEATURE_CORESYSTEM)
// Prefer intsafe.h when available, which defines many of the MAX/MIN
// values below (which is why they are in #ifndef blocks).
#include <intsafe.h>
diff --git a/src/inc/cor.h b/src/inc/cor.h
index 9fd279e74b..a050eb42aa 100644
--- a/src/inc/cor.h
+++ b/src/inc/cor.h
@@ -171,7 +171,6 @@ DEPRECATED_CLR_STDAPI_(void) CoUninitializeEE(BOOL fFlags);
DEPRECATED_CLR_STDAPI_(void) CoEEShutDownCOM(void);
-#ifdef FEATURE_MAIN_CLR_MODULE_USES_CORE_NAME
#define MAIN_CLR_MODULE_NAME_W W("coreclr")
#define MAIN_CLR_MODULE_NAME_A "coreclr"
@@ -179,24 +178,10 @@ DEPRECATED_CLR_STDAPI_(void) CoEEShutDownCOM(void);
#define MAIN_CLR_DLL_NAME_W MAKEDLLNAME_W(MAIN_CLR_MODULE_NAME_W)
#define MAIN_CLR_DLL_NAME_A MAKEDLLNAME_A(MAIN_CLR_MODULE_NAME_A)
-#else //FEATURE_MAIN_CLR_MODULE_USES_CORE_NAME
-#define MAIN_CLR_MODULE_NAME_W L"clr"
-#define MAIN_CLR_MODULE_NAME_A "clr"
-#define MAIN_CLR_DLL_NAME_W MAKEDLLNAME_W(MAIN_CLR_MODULE_NAME_W)
-#define MAIN_CLR_DLL_NAME_A MAKEDLLNAME_A(MAIN_CLR_MODULE_NAME_A)
-
-#endif //FEATURE_MAIN_CLR_MODULE_USES_CORE_NAME
-
-
-#ifdef FEATURE_CORECLR
#define MSCOREE_SHIM_W MAIN_CLR_DLL_NAME_W
#define MSCOREE_SHIM_A MAIN_CLR_DLL_NAME_A
-#else
-#define MSCOREE_SHIM_W L"mscoree.dll"
-#define MSCOREE_SHIM_A "mscoree.dll"
-#endif // FEATURE_CORECLR
#define SWITCHOUT_HANDLE_VALUE ((HANDLE)(LONG_PTR)-2)
diff --git a/src/inc/corbbtprof.h b/src/inc/corbbtprof.h
index 2f69dcccc8..5aa7782544 100644
--- a/src/inc/corbbtprof.h
+++ b/src/inc/corbbtprof.h
@@ -140,7 +140,7 @@ enum TypeProfilingDataFlags
ReadMethodTable = 0, // 0x00001
ReadEEClass = 1, // 0x00002
WriteEEClass = 2, // 0x00004
-// ReadStoredEnumData = 3, // 0x00008
+// ReadStoredEnumData = 3, // 0x00008 // obsolete
ReadFieldDescs = 4, // 0x00010
ReadCCtorInfo = 5, // 0x00020
ReadClassHashTable = 6, // 0x00040
@@ -148,34 +148,37 @@ enum TypeProfilingDataFlags
ReadDispatchTable = 8, // 0x00100
ReadMethodTableWriteableData = 9, // 0x00200
ReadFieldMarshalers = 10, // 0x00400
-// Unused = 11, // 0x00800 ... Was WriteDispatchTable in the past
-// WriteMethodTable = 12, // 0x01000
+// WriteDispatchTable = 11, // 0x00800 // obsolete
+// WriteMethodTable = 12, // 0x01000 // obsolete
WriteMethodTableWriteableData = 13, // 0x02000
ReadTypeDesc = 14, // 0x04000
WriteTypeDesc = 15, // 0x08000
ReadTypeHashTable = 16, // 0x10000
-// WriteTypeHashTable = 17, // 0x20000
-// ReadDictionary = 18, // 0x40000
-// WriteDictionary = 19, // 0x80000
+// WriteTypeHashTable = 17, // 0x20000 // obsolete
+// ReadDictionary = 18, // 0x40000 // obsolete
+// WriteDictionary = 19, // 0x80000 // obsolete
ReadNonVirtualSlots = 20, // 0x100000
};
enum MethodProfilingDataFlags
{
// Important: update toolbox\ibcmerge\ibcmerge.cs if you change these
- ReadMethodCode = 0, // 0x00001
+ ReadMethodCode = 0, // 0x00001 // Also means the method was executed
ReadMethodDesc = 1, // 0x00002
- RunOnceMethod = 2, // 0x00004 // was CommonMethod
- RunNeverMethod = 3, // 0x00008 // was MethodMetadataAccess
-// MethodStoredDataAccess = 4, // 0x00010
+ RunOnceMethod = 2, // 0x00004
+ RunNeverMethod = 3, // 0x00008
+// MethodStoredDataAccess = 4, // 0x00010 // obsolete
WriteMethodDesc = 5, // 0x00020
-// ReadFCallHash = 6, // 0x00040
+// ReadFCallHash = 6, // 0x00040 // obsolete
ReadGCInfo = 7, // 0x00080
CommonReadGCInfo = 8, // 0x00100
-// ReadMethodDefRidMap = 9, // 0x00200
+// ReadMethodDefRidMap = 9, // 0x00200 // obsolete
ReadCerMethodList = 10, // 0x00400
ReadMethodPrecode = 11, // 0x00800
WriteMethodPrecode = 12, // 0x01000
+ ExcludeHotMethodCode = 13, // 0x02000 // Hot method should be excluded from the ReadyToRun image
+ ExcludeColdMethodCode = 14, // 0x04000 // Cold method should be excluded from the ReadyToRun image
+ DisableInlining = 15, // 0x08000 // Disable inlining of this method in optimized AOT native code
};
enum GeneralProfilingDataFlags
diff --git a/src/inc/corcompile.h b/src/inc/corcompile.h
index 9cd072008a..f99e27eec0 100644
--- a/src/inc/corcompile.h
+++ b/src/inc/corcompile.h
@@ -32,11 +32,6 @@
#include <corhdr.h>
#include <corinfo.h>
#include <corjit.h>
-#ifdef FEATURE_FUSION
-#include <fusion.h>
-#include <fusionpriv.h>
-#include <binderngen.h>
-#endif //FEATURE_FUSION
#include <sstring.h>
#include <shash.h>
#include <daccess.h>
@@ -190,14 +185,8 @@ enum CorCompileCodegen
CORCOMPILE_CODEGEN_PROFILING = 0x0004, // supports profiling
CORCOMPILE_CODEGEN_PROF_INSTRUMENTING = 0x0008, // code is instrumented to collect profile count info
-#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR)
- CORCOMPILE_CODEGEN_USE_RYUJIT = 0x0100, // code is generated by Ryu JIT
-#endif
};
-#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR)
-bool UseRyuJit();
-#endif
// Used for INativeImageInstallInfo::GetConfigMask()
// A bind will ask for the particular bits it needs set; if all bits are set, it is a match. Additional
@@ -833,13 +822,8 @@ struct CORCOMPILE_ASSEMBLY_SIGNATURE
typedef enum
{
-#ifdef FEATURE_CORECLR
CORECLR_INFO,
CROSSGEN_COMPILER_INFO,
-#else
- CLR_INFO,
- NGEN_COMPILER_INFO,
-#endif
NUM_RUNTIME_DLLS
} CorCompileRuntimeDlls;
@@ -894,18 +878,6 @@ struct CORCOMPILE_VERSION_INFO
};
-#ifndef FEATURE_CORECLR
-enum CorCompileDependencyInfo
-{
-#ifdef FEATURE_APTCA
- CORCOMPILE_DEPENDENCY_IS_APTCA = 0x1,
- CORCOMPILE_DEPENDENCY_IS_CAPTCA = 0x2,
-#endif //FEATURE_APTCA
-
- CORCOMPILE_DEPENDENCY_PEKIND_MASK = 0xff00,
- CORCOMPILE_DEPENDENCY_PEKIND_SHIFT = 8,
-};
-#endif //!FEATURE_CORECLR
struct CORCOMPILE_DEPENDENCY
@@ -919,14 +891,7 @@ struct CORCOMPILE_DEPENDENCY
CORCOMPILE_NGEN_SIGNATURE signNativeImage; // INVALID_NGEN_SIGNATURE if this a soft-bound dependency
-#ifdef FEATURE_APTCA
- // Win32 version info for tracking dependency references to strong-named assemblies with APTCA
- ULARGE_INTEGER uliFileVersion; // OS file version ~ NOT assembly version
-#endif //FEATURE_APTCA
-#ifndef FEATURE_CORECLR
- CorCompileDependencyInfo dependencyInfo; //Flags about the dependency
-#endif //!FEATURE_CORECLR
};
/*********************************************************************************/
@@ -1339,6 +1304,12 @@ class ICorCompilePreloader
CORINFO_METHOD_HANDLE method,
CORINFO_METHOD_HANDLE duplicateMethod) = 0;
+ // Returns a compressed encoding of the inline tracking map
+ // for this compilation
+ virtual void GetSerializedInlineTrackingMap(
+ IN OUT SBuffer * pSerializedInlineTrackingMap
+ ) = 0;
+
//
// Release frees the preloader
//
@@ -1438,13 +1409,6 @@ class ICorCompilationDomain
DWORD *cDependencies
) = 0;
-#ifdef FEATURE_FUSION
- // Use to retrieve the IBindContext to be used by the native binder.
- // This is typically passed into InstallNativeAssembly.
- virtual HRESULT GetIBindContext(
- IBindContext **ppBindCtx
- ) = 0;
-#endif
#ifdef CROSSGEN_COMPILE
virtual HRESULT SetPlatformWinmdPaths(
@@ -1523,34 +1487,6 @@ class ICorCompileInfo
CORINFO_ASSEMBLY_HANDLE *pHandle
) = 0;
-#ifdef FEATURE_FUSION
- // Loads an assembly via fusion into the EE
- // and returns a handle to it.
- virtual HRESULT LoadAssemblyByName(
- LPCWSTR wzName,
- CORINFO_ASSEMBLY_HANDLE *pHandle
- ) = 0;
-
- // Loads an assembly via ref into the EE
- // and returns a handle to it. The last parameter
- // optionally allows an IAssemblyName for the ref
- // (pre-policy) to be returned
- virtual HRESULT LoadAssemblyRef(
- IMDInternalImport *pAssemblyImport,
- mdAssemblyRef ref,
- CORINFO_ASSEMBLY_HANDLE *pHandle,
- IAssemblyName **refAssemblyName = NULL
- ) = 0;
-
- // Loads an assembly via its IAssemblyName. This is
- // used by NGEN createpdb when generating PDBs for AutoNGENd images (it reads the
- // IAssemblyName from the AUX file).
- virtual HRESULT LoadAssemblyByIAssemblyName(
- IAssemblyName *pAssemblyName,
- CORINFO_ASSEMBLY_HANDLE *pHandle
- ) = 0;
-
-#endif //FEATURE_FUSION
#ifdef FEATURE_COMINTEROP
// Loads a WinRT typeref into the EE and returns
@@ -1574,19 +1510,6 @@ class ICorCompileInfo
CORINFO_MODULE_HANDLE *pHandle
) = 0;
-#ifndef FEATURE_CORECLR
- // Check if the assembly supports automatic NGen
- virtual BOOL SupportsAutoNGen(
- CORINFO_ASSEMBLY_HANDLE assembly
- ) = 0;
-
- // Tell OS to set cached signing level of the native image based on input assemblies
- virtual HRESULT SetCachedSigningLevel(
- HANDLE hNI,
- HANDLE *pModules,
- COUNT_T nModules
- ) = 0;
-#endif
// Checks to see if an up to date zap exists for the
// assembly
@@ -1603,22 +1526,6 @@ class ICorCompileInfo
CORINFO_MODULE_HANDLE module
) = 0;
-#ifdef FEATURE_FUSION
- enum GetAssemblyNameFlags
- {
- GANF_Default = 0,
- GANF_Simple = 1,
- };
-
- // Returns the fusion name of an assembly
- virtual HRESULT GetAssemblyName(
- CORINFO_ASSEMBLY_HANDLE hAssembly,
- DWORD dwFlags,
- __out_ecount(*cchAssemblyName)
- __out_z LPWSTR wzAssemblyName,
- LPDWORD cchAssemblyName
- ) = 0;
-#endif //FEATURE_FUSION
// Returns the dependency load setting for an assembly ref
virtual HRESULT GetLoadHint(
@@ -1908,9 +1815,7 @@ extern "C" unsigned __stdcall PartialNGenStressPercentage();
// create a PDB dumping all functions in hAssembly into pdbPath
extern "C" HRESULT __stdcall CreatePdb(CORINFO_ASSEMBLY_HANDLE hAssembly, BSTR pNativeImagePath, BSTR pPdbPath, BOOL pdbLines, BSTR pManagedPdbSearchPath, LPCWSTR pDiasymreaderPath);
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
extern bool g_fNGenMissingDependenciesOk;
-#endif
extern bool g_fNGenWinMDResilient;
diff --git a/src/inc/coregen.h b/src/inc/coregen.h
index 5ca7334e92..5864bbbaef 100644
--- a/src/inc/coregen.h
+++ b/src/inc/coregen.h
@@ -18,5 +18,6 @@
#define NGENWORKER_FLAGS_WINMD_RESILIENT 0x1000
#define NGENWORKER_FLAGS_READYTORUN 0x2000
#define NGENWORKER_FLAGS_NO_METADATA 0x4000
+#define NGENWORKER_FLAGS_SILENT 0x8000
#endif // _NGENCOMMON_H_
diff --git a/src/inc/corhdr.h b/src/inc/corhdr.h
index c194def07f..4b757421cb 100644
--- a/src/inc/corhdr.h
+++ b/src/inc/corhdr.h
@@ -751,6 +751,7 @@ typedef enum CorAssemblyFlags
afEnableJITcompileTracking = 0x8000, // From "DebuggableAttribute".
afDisableJITcompileOptimizer = 0x4000, // From "DebuggableAttribute".
+ afDebuggableAttributeMask = 0xc000,
afRetargetable = 0x0100, // The assembly can be retargeted (at runtime) to an
// assembly from a different publisher.
diff --git a/src/inc/corhost.h b/src/inc/corhost.h
index 579088ca61..3aabe9ed5d 100644
--- a/src/inc/corhost.h
+++ b/src/inc/corhost.h
@@ -28,9 +28,6 @@
#include "ivehandler.h"
#include "ivalidator.h"
-#ifdef FEATURE_FUSION
-#include "fusion.h"
-#endif
#include "holder.h"
#include "clrprivhosting.h"
@@ -46,210 +43,6 @@ class DangerousNonHostedSpinLock;
class AppDomain;
class Assembly;
-#if !defined(FEATURE_CORECLR)
-class CorThreadpool : public ICorThreadpool
-{
-public:
- HRESULT STDMETHODCALLTYPE CorRegisterWaitForSingleObject(PHANDLE phNewWaitObject,
- HANDLE hWaitObject,
- WAITORTIMERCALLBACK Callback,
- PVOID Context,
- ULONG timeout,
- BOOL executeOnlyOnce,
- BOOL* pResult);
-
- HRESULT STDMETHODCALLTYPE CorBindIoCompletionCallback(HANDLE fileHandle, LPOVERLAPPED_COMPLETION_ROUTINE callback);
-
- HRESULT STDMETHODCALLTYPE CorUnregisterWait(HANDLE hWaitObject,HANDLE CompletionEvent, BOOL* pResult);
-
- HRESULT STDMETHODCALLTYPE CorQueueUserWorkItem(LPTHREAD_START_ROUTINE Function,PVOID Context,BOOL executeOnlyOnce, BOOL* pResult );
-
- HRESULT STDMETHODCALLTYPE CorCallOrQueueUserWorkItem(LPTHREAD_START_ROUTINE Function,PVOID Context,BOOL* pResult );
-
- HRESULT STDMETHODCALLTYPE CorCreateTimer(PHANDLE phNewTimer,
- WAITORTIMERCALLBACK Callback,
- PVOID Parameter,
- DWORD DueTime,
- DWORD Period,
- BOOL* pResult);
-
- HRESULT STDMETHODCALLTYPE CorDeleteTimer(HANDLE Timer, HANDLE CompletionEvent, BOOL* pResult);
-
- HRESULT STDMETHODCALLTYPE CorChangeTimer(HANDLE Timer,ULONG DueTime,ULONG Period, BOOL* pResult);
-
- HRESULT STDMETHODCALLTYPE CorSetMaxThreads(DWORD MaxWorkerThreads,
- DWORD MaxIOCompletionThreads);
-
- HRESULT STDMETHODCALLTYPE CorGetMaxThreads(DWORD *MaxWorkerThreads,
- DWORD *MaxIOCompletionThreads);
-
- HRESULT STDMETHODCALLTYPE CorGetAvailableThreads(DWORD *AvailableWorkerThreads,
- DWORD *AvailableIOCompletionThreads);
-};
-
-class CorGCHost : public IGCHost2
-{
-public:
- // IGCHost
- STDMETHODIMP STDMETHODCALLTYPE SetGCStartupLimits(
- DWORD SegmentSize,
- DWORD MaxGen0Size);
-
- STDMETHODIMP STDMETHODCALLTYPE Collect(
- LONG Generation);
-
- STDMETHODIMP STDMETHODCALLTYPE GetStats(
- COR_GC_STATS *pStats);
-
- STDMETHODIMP STDMETHODCALLTYPE GetThreadStats(
- DWORD *pFiberCookie,
- COR_GC_THREAD_STATS *pStats);
-
- STDMETHODIMP STDMETHODCALLTYPE SetVirtualMemLimit(
- SIZE_T sztMaxVirtualMemMB);
-
- // IGCHost2
- STDMETHODIMP STDMETHODCALLTYPE SetGCStartupLimitsEx(
- SIZE_T SegmentSize,
- SIZE_T MaxGen0Size);
-
-private:
-
- HRESULT _SetGCSegmentSize(SIZE_T SegmentSize);
- HRESULT _SetGCMaxGen0Size(SIZE_T MaxGen0Size);
-};
-
-class CorConfiguration : public ICorConfiguration
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE SetGCThreadControl(
- /* [in] */ IGCThreadControl __RPC_FAR *pGCThreadControl);
-
- virtual HRESULT STDMETHODCALLTYPE SetGCHostControl(
- /* [in] */ IGCHostControl __RPC_FAR *pGCHostControl);
-
- virtual HRESULT STDMETHODCALLTYPE SetDebuggerThreadControl(
- /* [in] */ IDebuggerThreadControl __RPC_FAR *pDebuggerThreadControl);
-
- virtual HRESULT STDMETHODCALLTYPE AddDebuggerSpecialThread(
- /* [in] */ DWORD dwSpecialThreadId);
-
- // This mechanism isn't thread-safe with respect to reference counting, because
- // the runtime will use the cached pointer without adding extra refcounts to protect
- // itself. So if one thread calls GetGCThreadControl & another thread calls
- // ICorHost::SetGCThreadControl, we have a race.
- static IGCThreadControl *GetGCThreadControl()
- {
- LIMITED_METHOD_CONTRACT;
-
- return m_CachedGCThreadControl;
- }
-
- static IGCHostControl *GetGCHostControl()
- {
- LIMITED_METHOD_CONTRACT;
-
- return m_CachedGCHostControl;
- }
-
- static IDebuggerThreadControl *GetDebuggerThreadControl()
- {
- LIMITED_METHOD_CONTRACT;
-
- return m_CachedDebuggerThreadControl;
- }
-
- static DWORD GetDebuggerSpecialThreadCount()
- {
- LIMITED_METHOD_CONTRACT;
-
- return m_DSTCount;
- }
-
- static DWORD *GetDebuggerSpecialThreadArray()
- {
- LIMITED_METHOD_CONTRACT;
-
- return m_DSTArray;
- }
-
- // Helper function that returns true if the thread is in the debugger special thread list
- static BOOL IsDebuggerSpecialThread(DWORD dwThreadId);
-
- // Helper function to update the thread list in the debugger control block
- static HRESULT RefreshDebuggerSpecialThreadList();
-
- // Clean up debugger thread control object, called at shutdown
- static void CleanupDebuggerThreadControl();
-
-private:
- // Cache the IGCThreadControl interface until the EE is started, at which point
- // we pass it through.
- static IGCThreadControl *m_CachedGCThreadControl;
- static IGCHostControl *m_CachedGCHostControl;
- static IDebuggerThreadControl *m_CachedDebuggerThreadControl;
-
- // Array of ID's of threads that should be considered "special" to
- // the debugging services.
- static DWORD *m_DSTArray;
- static DWORD m_DSTArraySize;
- static DWORD m_DSTCount;
-};
-
-class CorValidator : public IValidator
-{
-protected:
- CorValidator() {LIMITED_METHOD_CONTRACT;}
-
-public:
- STDMETHODIMP STDMETHODCALLTYPE Validate(
- IVEHandler *veh,
- IUnknown *pAppDomain,
- unsigned long ulFlags,
- unsigned long ulMaxError,
- unsigned long token,
- __in_z LPWSTR fileName,
- BYTE *pe,
- unsigned long ulSize);
-
- STDMETHODIMP STDMETHODCALLTYPE FormatEventInfo(
- HRESULT hVECode,
- VEContext Context,
- __out_ecount(ulMaxLength) LPWSTR msg,
- unsigned long ulMaxLength,
- SAFEARRAY *psa);
-};
-
-class CLRValidator : public ICLRValidator
-{
-protected:
- CLRValidator() {LIMITED_METHOD_CONTRACT;}
-
-public:
- STDMETHODIMP STDMETHODCALLTYPE Validate(
- IVEHandler *veh,
- unsigned long ulAppDomainId,
- unsigned long ulFlags,
- unsigned long ulMaxError,
- unsigned long token,
- __in_z LPWSTR fileName,
- BYTE *pe,
- unsigned long ulSize);
-
- STDMETHODIMP STDMETHODCALLTYPE FormatEventInfo(
- HRESULT hVECode,
- VEContext Context,
- __out_ecount(ulMaxLength) LPWSTR msg,
- unsigned long ulMaxLength,
- SAFEARRAY *psa);
-};
-
-class CorDebuggerInfo : public IDebuggerInfo
-{
-public:
- STDMETHODIMP IsDebuggerAttached(BOOL *pbAttached);
-};
-#endif // !defined(FEATURE_CORECLR)
class CorExecutionManager
: public ICLRExecutionManager
@@ -271,9 +64,7 @@ protected:
CorRuntimeHostBase()
:m_Started(FALSE),
m_cRef(0)
-#ifdef FEATURE_CORECLR
, m_fStarted(FALSE)
-#endif // FEATURE_CORECLR
{LIMITED_METHOD_CONTRACT;}
STDMETHODIMP_(ULONG) AddRef(void);
@@ -336,11 +127,9 @@ protected:
LONG m_cRef; // Ref count.
-#ifdef FEATURE_CORECLR
// This flag will be used to ensure that a CoreCLR host can invoke Start/Stop in pairs only.
BOOL m_fStarted;
BOOL m_fAppDomainCreated; // this flag is used when an appdomain can only create a single appdomain
-#endif // FEATURE_CORECLR
static ULONG m_Version; // Version of ICorRuntimeHost.
// Some functions are only available in ICLRRuntimeHost.
@@ -358,162 +147,6 @@ public:
};
-#if !defined(FEATURE_CORECLR) // simple hosting
-class CorHost :
- public CorRuntimeHostBase, public ICorRuntimeHost, public CorThreadpool
- , public CorGCHost, public CorConfiguration
- , public CorValidator, public CorDebuggerInfo
- , public CorExecutionManager
-{
-public:
- CorHost() {WRAPPER_NO_CONTRACT;}
-
- // *** IUnknown methods ***
- STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
- STDMETHODIMP_(ULONG) AddRef(void)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::AddRef();
- }
- STDMETHODIMP_(ULONG) Release(void);
-
-
- // *** ICorRuntimeHost methods ***
- // Returns an object for configuring the runtime prior to
- // it starting. If the runtime has been initialized this
- // routine returns an error. See ICorConfiguration.
- STDMETHODIMP GetConfiguration(ICorConfiguration** pConfiguration);
-
-
- // Starts the runtime. This is equivalent to CoInitializeCor();
- STDMETHODIMP Start(void);
-
- STDMETHODIMP Stop();
-
- // Creates a domain in the runtime. The identity array is
- // a pointer to an array TYPE containing IIdentity objects defining
- // the security identity.
- STDMETHODIMP CreateDomain(LPCWSTR pwzFriendlyName, // Optional
- IUnknown* pIdentityArray, // Optional
- IUnknown ** pAppDomain)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::CreateDomain(pwzFriendlyName,pIdentityArray,pAppDomain);
- }
-
- // Returns the default domain.
- STDMETHODIMP GetDefaultDomain(IUnknown ** pAppDomain)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::GetDefaultDomain(pAppDomain);
- }
-
- // Enumerate currently existing domains.
- STDMETHODIMP EnumDomains(HDOMAINENUM *hEnum)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::EnumDomains(hEnum);
- }
-
- // Returns S_FALSE when there are no more domains. A domain
- // is passed out only when S_OK is returned.
- STDMETHODIMP NextDomain(HDOMAINENUM hEnum,
- IUnknown** pAppDomain)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::NextDomain(hEnum,pAppDomain);
- }
-
- // Close the enumeration releasing resources
- STDMETHODIMP CloseEnum(HDOMAINENUM hEnum)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::CloseEnum(hEnum);
- }
-
- STDMETHODIMP CreateDomainEx(LPCWSTR pwzFriendlyName,
- IUnknown* pSetup, // Optional
- IUnknown* pEvidence, // Optional
- IUnknown ** pAppDomain)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::CreateDomainEx(pwzFriendlyName,pSetup,pEvidence,pAppDomain);
- }
-
- // Create appdomain setup object that can be passed into CreateDomainEx
- STDMETHODIMP CreateDomainSetup(IUnknown** pAppDomainSetup)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::CreateDomainSetup(pAppDomainSetup);
- }
-
- // Create Evidence object that can be passed into CreateDomainEx
- STDMETHODIMP CreateEvidence(IUnknown** pEvidence)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::CreateEvidence(pEvidence);
- }
-
- // Unload a domain, releasing the reference will only release the
- // the wrapper to the domain not unload the domain.
- STDMETHODIMP UnloadDomain(IUnknown* pAppDomain)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::UnloadDomain(pAppDomain);
- }
-
- // Returns the threads domain if there is one.
- STDMETHODIMP CurrentDomain(IUnknown ** pAppDomain)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::CurrentDomain(pAppDomain);
- }
-
- // TODO: Following 4 APIs should be move to CorHost for V1.
- STDMETHODIMP CreateLogicalThreadState(); // Return code.
- STDMETHODIMP DeleteLogicalThreadState(); // Return code.
- STDMETHODIMP SwitchInLogicalThreadState( // Return code.
- DWORD *pFiberCookie // [in] Cookie that indicates the fiber to use.
- );
-
- STDMETHODIMP SwitchOutLogicalThreadState( // Return code.
- DWORD **pFiberCookie // [out] Cookie that indicates the fiber being switched out.
- );
-
- STDMETHODIMP LocksHeldByLogicalThread( // Return code.
- DWORD *pCount // [out] Number of locks that the current thread holds.
- )
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::LocksHeldByLogicalThread(pCount);
- }
-
- // Class factory hook-up.
- static HRESULT CreateObject(REFIID riid, void **ppUnk);
-
- STDMETHODIMP MapFile( // Return code.
- HANDLE hFile, // [in] Handle for file
- HMODULE *hMapAddress // [out] HINSTANCE for mapped file
- )
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return CorRuntimeHostBase::MapFile(hFile,hMapAddress);
- }
-};
-#endif // !defined(FEATURE_CORECLR)
class ConnectionNameTable;
typedef DPTR(class ConnectionNameTable) PTR_ConnectionNameTable;
@@ -529,91 +162,8 @@ enum ESymbolReadingSetBy
eSymbolReadingSetBy_COUNT
};
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-// Hash table entry to keep track <connection, name> for SQL fiber support
-typedef DPTR(struct ConnectionNameHashEntry) PTR_ConnectionNameHashEntry;
-struct ConnectionNameHashEntry
-{
- FREEHASHENTRY entry;
- CONNID m_dwConnectionId;
- PTR_WSTR m_pwzName;
- ICLRTask **m_ppCLRTaskArray;
- UINT m_CLRTaskCount;
-};
-
-
-class CCLRDebugManager : public ICLRDebugManager
-{
-public:
- CCLRDebugManager() {LIMITED_METHOD_CONTRACT;};
-
- STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
- STDMETHODIMP_(ULONG) AddRef(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
- STDMETHODIMP_(ULONG) Release(void);
-
- // ICLRTDebugManager's interface
- STDMETHODIMP BeginConnection(
- CONNID dwConnectionId,
- __in_z wchar_t *szConnectionName);
- STDMETHODIMP SetConnectionTasks(
- DWORD id,
- DWORD dwCount,
- ICLRTask **ppCLRTask);
- STDMETHODIMP EndConnection(
- CONNID dwConnectionId);
-
- // Set ACL on shared section, events, and process
- STDMETHODIMP SetDacl(PACL pacl);
-
- // Returning the current ACL that CLR is using
- STDMETHODIMP GetDacl(PACL *pacl);
-
- STDMETHODIMP IsDebuggerAttached(BOOL *pbAttached);
-
- // symbol reading policy - include file line info when getting a call stack etc.
- STDMETHODIMP SetSymbolReadingPolicy(ESymbolReadingPolicy policy);
-
-#ifdef DACCESS_COMPILE
- // Expose iterators for DAC. Debugger can use this on attach to find existing Connections.
- //
- // Example usage:
- // HASHFIND h;
- // ConnectionNameHashEntry * pConnection = FindFirst(&h);
- // while(pConnection != NULL) {
- // DoSomething(pConnection);
- // pConnection = FindNext(&h);
- // }
- static ConnectionNameHashEntry * FindFirst(HASHFIND * pHashfind);
- static ConnectionNameHashEntry * FindNext(HASHFIND * pHashfind);
-#endif
-
- static void ProcessInit();
- static void ProcessCleanup();
- // Get the current symbol reading policy setting
- static ESymbolReadingPolicy GetSymbolReadingPolicy()
- {
- return m_symbolReadingPolicy;
- }
-
- // Set the symbol reading policy if the setter has higher precendence than the current setting
- static void SetSymbolReadingPolicy( ESymbolReadingPolicy policy, ESymbolReadingSetBy setBy );
-
-private:
- static CrstStatic m_lockConnectionNameTable;
- SPTR_DECL(ConnectionNameTable, m_pConnectionNameHash);
-
- static ESymbolReadingPolicy m_symbolReadingPolicy;
- static ESymbolReadingSetBy m_symbolReadingSetBy;
-};
-
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
+#if defined(FEATURE_WINDOWSPHONE)
class CCLRErrorReportingManager :
#ifdef FEATURE_WINDOWSPHONE
public ICLRErrorReportingManager2
@@ -683,7 +233,7 @@ public:
};
extern CCLRErrorReportingManager g_CLRErrorReportingManager;
-#endif // defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
+#endif // defined(FEATURE_WINDOWSPHONE)
#ifdef FEATURE_IPCMAN
// @TODO:: a-meicht
@@ -725,17 +275,7 @@ class CorHost2 :
#ifndef FEATURE_PAL
, public IPrivateManagedExceptionReporting /* This interface is for internal Watson testing only*/
#endif // FEATURE_PAL
-#ifdef FEATURE_CORECLR
, public ICLRRuntimeHost2
-#else
- , public CorThreadpool
- , public CorGCHost
- , public CorConfiguration
- , public CLRValidator
- , public CorDebuggerInfo
- , public ICLRRuntimeHost
- , public ICLRPrivRuntime
-#endif // FEATURE_CORECLR
, public CorExecutionManager
{
friend struct _DacGlobals;
@@ -755,12 +295,6 @@ public:
// *** ICorRuntimeHost methods ***
-#ifndef FEATURE_CORECLR
- // Returns an object for configuring the runtime prior to
- // it starting. If the runtime has been initialized this
- // routine returns an error. See ICorConfiguration.
- STDMETHODIMP GetConfiguration(ICorConfiguration** pConfiguration);
-#endif // FEATURE_CORECLR
#ifndef FEATURE_PAL
// defined in IPrivateManagedExceptionReporting interface for internal Watson testing only
@@ -818,7 +352,6 @@ public:
LPCWSTR pwzArgument,
DWORD *pReturnValue);
-#ifdef FEATURE_CORECLR
// *** ICLRRuntimeHost2 methods ***
STDMETHODIMP CreateAppDomainWithManager(
LPCWSTR wszFriendlyName,
@@ -853,202 +386,8 @@ public:
LPCWSTR* argv,
DWORD* pReturnValue);
-#endif // !FEATURE_CORECLR
-
-#if !defined(FEATURE_CORECLR)
- /**********************************************************************************
- ** ICLRPrivRuntime Methods
- **********************************************************************************/
- STDMETHODIMP GetInterface(
- REFCLSID rclsid,
- REFIID riid,
- LPVOID * ppUnk);
-
- STDMETHODIMP CreateAppDomain(
- LPCWSTR pwzFriendlyName,
- ICLRPrivBinder * pBinder,
- LPDWORD pdwAppDomainId);
-
- STDMETHODIMP CreateDelegate(
- DWORD appDomainID,
- LPCWSTR wszAssemblyName,
- LPCWSTR wszClassName,
- LPCWSTR wszMethodName,
- LPVOID * ppvDelegate);
-
- STDMETHODIMP ExecuteMain(
- ICLRPrivBinder * pBinder,
- int * pRetVal);
-
-#endif // !FEATURE_CORECLR
-
- static IHostControl *GetHostControl ()
- {
- LIMITED_METHOD_CONTRACT;
-
-#ifdef FEATURE_CORECLR
- return NULL;
-#else // FEATURE_CORECLR
- return m_HostControl;
-#endif // FEATURE_CORECLR
- }
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- static IHostMemoryManager *GetHostMemoryManager ()
- {
- LIMITED_METHOD_CONTRACT;
-
-#ifdef FEATURE_CORECLR
- return NULL;
-#else // FEATURE_CORECLR
- return m_HostMemoryManager;
-#endif // FEATURE_CORECLR
- }
-
- static IHostMalloc *GetHostMalloc ()
- {
- LIMITED_METHOD_CONTRACT;
-
-#ifdef FEATURE_CORECLR
- return NULL;
-#else // FEATURE_CORECLR
- return m_HostMalloc;
-#endif // FEATURE_CORECLR
- }
-
- static IHostTaskManager *GetHostTaskManager ()
- {
- LIMITED_METHOD_CONTRACT;
-
-#ifdef FEATURE_CORECLR
- return NULL;
-#else // FEATURE_CORECLR
- return m_HostTaskManager;
-#endif // FEATURE_CORECLR
- }
-
- static IHostThreadpoolManager *GetHostThreadpoolManager ()
- {
- LIMITED_METHOD_CONTRACT;
-
-#ifdef FEATURE_CORECLR
- return NULL;
-#else // FEATURE_CORECLR
- return m_HostThreadpoolManager;
-#endif // FEATURE_CORECLR
- }
-
- static IHostIoCompletionManager *GetHostIoCompletionManager ()
- {
- LIMITED_METHOD_CONTRACT;
-
-#ifdef FEATURE_CORECLR
- return NULL;
-#else // FEATURE_CORECLR
- return m_HostIoCompletionManager;
-#endif // FEATURE_CORECLR
- }
-
- static IHostSyncManager *GetHostSyncManager ()
- {
- LIMITED_METHOD_CONTRACT;
-
-#ifdef FEATURE_CORECLR
- return NULL;
-#else // FEATURE_CORECLR
- return m_HostSyncManager;
-#endif // FEATURE_CORECLR
- }
-
- static IHostAssemblyManager *GetHostAssemblyManager()
- {
- LIMITED_METHOD_CONTRACT;
-
-#ifdef FEATURE_CORECLR
- return NULL;
-#else // FEATURE_CORECLR
- return m_HostAssemblyManager;
-#endif // FEATURE_CORECLR
- }
-
- static IHostGCManager *GetHostGCManager()
- {
- LIMITED_METHOD_CONTRACT;
-
-#ifdef FEATURE_CORECLR
- return NULL;
-#else // FEATURE_CORECLR
- return m_HostGCManager;
-#endif // FEATURE_CORECLR
- }
-
- static IHostSecurityManager *GetHostSecurityManager()
- {
- LIMITED_METHOD_CONTRACT;
-
-#ifdef FEATURE_CORECLR
- return NULL;
-#else // FEATURE_CORECLR
- return m_HostSecurityManager;
-#endif // FEATURE_CORECLR
- }
-
- static IHostPolicyManager *GetHostPolicyManager ()
- {
- LIMITED_METHOD_CONTRACT;
-
-#ifdef FEATURE_CORECLR
- return NULL;
-#else // FEATURE_CORECLR
- return m_HostPolicyManager;
-#endif // FEATURE_CORECLR
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- static int GetHostOverlappedExtensionSize()
- {
- LIMITED_METHOD_CONTRACT;
-
-#ifdef FEATURE_CORECLR
- return 0;
-#else // FEATURE_CORECLR
- _ASSERTE (m_HostOverlappedExtensionSize != -1);
- return m_HostOverlappedExtensionSize;
-#endif // FEATURE_CORECLR
- }
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- static ICLRAssemblyReferenceList *GetHostDomainNeutralAsms()
- {
- LIMITED_METHOD_CONTRACT;
-
-#ifdef FEATURE_CORECLR
- return NULL;
-#else // FEATURE_CORECLR
- return m_pHostDomainNeutralAsms;
-#endif // FEATURE_CORECLR
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
-#ifndef FEATURE_CORECLR
- static HRESULT SetFlagsAndHostConfig(STARTUP_FLAGS dwStartupFlags, LPCWSTR pwzHostConfigFile, BOOL fFinalize);
- static LPCWSTR GetHostConfigFile();
-
- static void GetDefaultAppDomainProperties(StringArrayList **ppPropertyNames, StringArrayList **ppPropertyValues);
-#endif // !FEATURE_CORECLR
-
static STARTUP_FLAGS GetStartupFlags();
-#ifndef FEATURE_CORECLR
- static HRESULT SetPropertiesForDefaultAppDomain(DWORD nProperties,
- __in_ecount(nProperties) LPCWSTR *pwszPropertyNames,
- __in_ecount(nProperties) LPCWSTR *pwszPropertyValues);
-
- static HRESULT SetAppDomainManagerType(LPCWSTR wszAppDomainManagerAssembly,
- LPCWSTR wszAppDomainManagerType,
- EInitializeNewDomainFlags dwInitializeDomainFlags);
-#endif // FEATURE_CORECLR
-
static LPCWSTR GetAppDomainManagerAsm();
static LPCWSTR GetAppDomainManagerType();
@@ -1069,14 +408,12 @@ public:
static BOOL IsLoadFromBlocked(); // LoadFrom, LoadFile and Load(byte[]) are blocked in certain hosting scenarios
private:
-#ifdef FEATURE_CORECLR
// This flag indicates if this instance was the first to load and start CoreCLR
BOOL m_fFirstToLoadCLR;
// This flag indicates if the host has authenticated with us or not
BOOL m_fIsHostAuthenticated;
-#endif // FEATURE_CORECLR
// Helpers for both ICLRRuntimeHost2 and ICLRPrivRuntime
HRESULT _CreateAppDomain(
@@ -1087,9 +424,6 @@ private:
int nProperties,
LPCWSTR* pPropertyNames,
LPCWSTR* pPropertyValues,
-#if !defined(FEATURE_CORECLR)
- ICLRPrivBinder* pBinder,
-#endif
DWORD* pAppDomainID);
HRESULT _CreateDelegate(
@@ -1110,38 +444,11 @@ private:
static LPCWSTR s_wszAppDomainManagerType;
static EInitializeNewDomainFlags s_dwDomainManagerInitFlags;
-#if !defined(FEATURE_CORECLR)
- static StringArrayList s_defaultDomainPropertyNames;
- static StringArrayList s_defaultDomainPropertyValues;
-
-protected:
- static IHostMemoryManager *m_HostMemoryManager;
- static IHostMalloc *m_HostMalloc;
- static IHostTaskManager *m_HostTaskManager;
- static IHostThreadpoolManager *m_HostThreadpoolManager;
- static IHostIoCompletionManager *m_HostIoCompletionManager;
- static IHostSyncManager *m_HostSyncManager;
- static IHostAssemblyManager *m_HostAssemblyManager;
- static IHostGCManager *m_HostGCManager;
- static IHostSecurityManager *m_HostSecurityManager;
- static IHostPolicyManager *m_HostPolicyManager;
- static int m_HostOverlappedExtensionSize;
- static ICLRAssemblyReferenceList *m_pHostDomainNeutralAsms;
-
- static WCHAR m_wzHostConfigFile[_MAX_PATH];
-
- static BOOL m_dwFlagsFinalized;
- static DangerousNonHostedSpinLock m_FlagsLock; // protects the flags and host config
-#endif // !defined(FEATURE_CORECLR)
SVAL_DECL(STARTUP_FLAGS, m_dwStartupFlags);
};
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-class CorHostProtectionManager : public ICLRHostProtectionManager
-#else // !FEATURE_INCLUDE_ALL_INTERFACES
class CorHostProtectionManager
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
private:
EApiCategories m_eProtectedCategories;
diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h
index f515fcbd6d..cbc4464e1d 100644
--- a/src/inc/corinfo.h
+++ b/src/inc/corinfo.h
@@ -149,7 +149,7 @@ The first 4 options are mutially exclusive
This last field can modify any of the cases above except CORINFO_FLG_HELPER
CORINFO_FLG_STATIC_IN_HEAP This is currently only used for static fields of value classes. If the field has
-this set then after computing what would normally be the field, what you actually get is a object poitner
+this set then after computing what would normally be the field, what you actually get is a object pointer
(that must be reported to the GC) to a boxed version of the value. Thus the actual field address is computed
by addr = (*addr+sizeof(OBJECTREF))
@@ -213,52 +213,20 @@ TODO: Talk about initializing strutures before use
#define SELECTANY extern __declspec(selectany)
#endif
-// COR_JIT_EE_VERSION is a #define that specifies a JIT-EE version, but on a less granular basis than the GUID.
-// The #define is intended to be used on a per-product basis. That is, for each release that we support a JIT
-// CTP build, we'll update the COR_JIT_EE_VERSION. The GUID must change any time any part of the interface changes.
-//
-// COR_JIT_EE_VERSION is set, by convention, to a number related to the the product number. So, 460 is .NET 4.60.
-// 461 would indicate .NET 4.6.1. Etc.
-//
-// Note that the EE should always build with the most current (highest numbered) version. Only the JIT will
-// potentially build with a lower version number. In that case, the COR_JIT_EE_VERSION will be specified in the
-// CTP JIT build project, such as ctpjit.nativeproj.
-
-#if !defined(COR_JIT_EE_VERSION)
-#define COR_JIT_EE_VERSION 999999999 // This means we'll take everything in the interface
-#endif
-
-#if COR_JIT_EE_VERSION > 460
-
// Update this one
-SELECTANY const GUID JITEEVersionIdentifier = { /* 4bd06266-8ef7-4172-bec6-d3149fde7859 */
- 0x4bd06266,
- 0x8ef7,
- 0x4172,
- {0xbe, 0xc6, 0xd3, 0x14, 0x9f, 0xde, 0x78, 0x59}
-};
-
-#else
-
-// ************ Leave this one alone ***************
-// We need it to build a .NET 4.6 compatible JIT for the RyuJIT CTP releases
-SELECTANY const GUID JITEEVersionIdentifier = { /* 9110edd8-8fc3-4e3d-8ac9-12555ff9be9c */
- 0x9110edd8,
- 0x8fc3,
- 0x4e3d,
- { 0x8a, 0xc9, 0x12, 0x55, 0x5f, 0xf9, 0xbe, 0x9c }
+SELECTANY const GUID JITEEVersionIdentifier = { /* f00b3f49-ddd2-49be-ba43-6e49ffa66959 */
+ 0xf00b3f49,
+ 0xddd2,
+ 0x49be,
+ { 0xba, 0x43, 0x6e, 0x49, 0xff, 0xa6, 0x69, 0x59 }
};
-#endif
-
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// END JITEEVersionIdentifier
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////
-#if COR_JIT_EE_VERSION > 460
-
// For System V on the CLR type system number of registers to pass in and return a struct is the same.
// The CLR type system allows only up to 2 eightbytes to be passed in registers. There is no SSEUP classification types.
#define CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS 2
@@ -381,8 +349,6 @@ private:
}
};
-#endif // COR_JIT_EE_VERSION
-
// CorInfoHelpFunc defines the set of helpers (accessed via the ICorDynamicInfo::getHelperFtn())
// These helpers can be called by native code which executes in the runtime.
// Compilers can emit calls to these helpers.
@@ -433,9 +399,7 @@ enum CorInfoHelpFunc
CORINFO_HELP_NEWSFAST, // allocator for small, non-finalizer, non-array object
CORINFO_HELP_NEWSFAST_ALIGN8, // allocator for small, non-finalizer, non-array object, 8 byte aligned
CORINFO_HELP_NEW_MDARR, // multi-dim array helper (with or without lower bounds - dimensions passed in as vararg)
-#if COR_JIT_EE_VERSION > 460
CORINFO_HELP_NEW_MDARR_NONVARARG,// multi-dim array helper (with or without lower bounds - dimensions passed in as unmanaged array)
-#endif
CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creation
CORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arrays
CORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arrays
@@ -481,9 +445,7 @@ enum CorInfoHelpFunc
CORINFO_HELP_RNGCHKFAIL, // array bounds check failed
CORINFO_HELP_OVERFLOW, // throw an overflow exception
CORINFO_HELP_THROWDIVZERO, // throw a divide by zero exception
-#if COR_JIT_EE_VERSION > 460
CORINFO_HELP_THROWNULLREF, // throw a null reference exception
-#endif // COR_JIT_EE_VERSION
CORINFO_HELP_INTERNALTHROW, // Support for really fast jit
CORINFO_HELP_VERIFICATION, // Throw a VerificationException
@@ -639,13 +601,9 @@ enum CorInfoHelpFunc
CORINFO_HELP_READYTORUN_CHKCAST,
CORINFO_HELP_READYTORUN_STATIC_BASE,
CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR,
-#if COR_JIT_EE_VERSION > 460
CORINFO_HELP_READYTORUN_GENERIC_HANDLE,
CORINFO_HELP_READYTORUN_DELEGATE_CTOR,
CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE,
-#else
- #define CORINFO_HELP_READYTORUN_DELEGATE_CTOR CORINFO_HELP_EE_PRESTUB
-#endif // COR_JIT_EE_VERSION
CORINFO_HELP_EE_PRESTUB, // Not real JIT helper. Used in native images.
@@ -682,7 +640,6 @@ enum CorInfoHelpFunc
CORINFO_HELP_LOOP_CLONE_CHOICE_ADDR, // Return the reference to a counter to decide to take cloned path in debug stress.
CORINFO_HELP_DEBUG_LOG_LOOP_CLONING, // Print a message that a loop cloning optimization has occurred in debug mode.
-#if COR_JIT_EE_VERSION > 460
CORINFO_HELP_THROW_ARGUMENTEXCEPTION, // throw ArgumentException
CORINFO_HELP_THROW_ARGUMENTOUTOFRANGEEXCEPTION, // throw ArgumentOutOfRangeException
@@ -691,7 +648,8 @@ enum CorInfoHelpFunc
CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER, // Transition to cooperative mode in reverse P/Invoke prolog, frame is the first argument
CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT, // Transition to preemptive mode in reverse P/Invoke epilog, frame is the first argument
-#endif
+
+ CORINFO_HELP_GVMLOOKUP_FOR_SLOT, // Resolve a generic virtual method target from this pointer and runtime method handle
CORINFO_HELP_COUNT,
};
@@ -789,6 +747,17 @@ enum CorInfoCallConv
CORINFO_CALLCONV_PARAMTYPE = 0x80, // Passed last. Same as CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG
};
+#ifdef UNIX_X86_ABI
+inline bool IsCallerPop(CorInfoCallConv callConv)
+{
+ unsigned int umask = CORINFO_CALLCONV_STDCALL
+ | CORINFO_CALLCONV_THISCALL
+ | CORINFO_CALLCONV_FASTCALL;
+
+ return !(callConv & umask);
+}
+#endif // UNIX_X86_ABI
+
enum CorInfoUnmanagedCallConv
{
// These correspond to CorUnmanagedCallingConvention
@@ -1309,8 +1278,6 @@ enum CORINFO_RUNTIME_LOOKUP_KIND
CORINFO_LOOKUP_CLASSPARAM,
};
-#if COR_JIT_EE_VERSION > 460
-
struct CORINFO_LOOKUP_KIND
{
bool needsRuntimeLookup;
@@ -1322,16 +1289,6 @@ struct CORINFO_LOOKUP_KIND
void * runtimeLookupArgs;
} ;
-#else
-
-struct CORINFO_LOOKUP_KIND
-{
- bool needsRuntimeLookup;
- CORINFO_RUNTIME_LOOKUP_KIND runtimeLookupKind;
-} ;
-
-#endif
-
// CORINFO_RUNTIME_LOOKUP indicates the details of the runtime lookup
// operation to be performed.
@@ -1609,10 +1566,11 @@ enum CorInfoTokenKind
// token comes from CEE_CONSTRAINED
CORINFO_TOKENKIND_Constrained = 0x100 | CORINFO_TOKENKIND_Class,
-#if COR_JIT_EE_VERSION > 460
// token comes from CEE_NEWOBJ
CORINFO_TOKENKIND_NewObj = 0x200 | CORINFO_TOKENKIND_Method,
-#endif
+
+ // token comes from CEE_LDVIRTFTN
+ CORINFO_TOKENKIND_Ldvirtftn = 0x400 | CORINFO_TOKENKIND_Method,
};
struct CORINFO_RESOLVED_TOKEN
@@ -1711,12 +1669,11 @@ enum CORINFO_FIELD_ACCESSOR
CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER, // static field access using the "generic static" helper (argument is MethodTable *)
CORINFO_FIELD_STATIC_ADDR_HELPER, // static field accessed using address-of helper (argument is FieldDesc *)
CORINFO_FIELD_STATIC_TLS, // unmanaged TLS access
-#if COR_JIT_EE_VERSION > 460
CORINFO_FIELD_STATIC_READYTORUN_HELPER, // static field access using a runtime lookup helper
-#endif
CORINFO_FIELD_INTRINSIC_ZERO, // intrinsic zero (IntPtr.Zero, UIntPtr.Zero)
CORINFO_FIELD_INTRINSIC_EMPTY_STRING, // intrinsic emptry string (String.Empty)
+ CORINFO_FIELD_INTRINSIC_ISLITTLEENDIAN, // intrinsic BitConverter.IsLittleEndian
};
// Set of flags returned in CORINFO_FIELD_INFO::fieldFlags
@@ -1828,7 +1785,6 @@ struct CORINFO_EE_INFO
// Array offsets
unsigned offsetOfObjArrayData;
-#if COR_JIT_EE_VERSION > 460
// Reverse PInvoke offsets
unsigned sizeOfReversePInvokeFrame;
@@ -1841,7 +1797,6 @@ struct CORINFO_EE_INFO
// Target ABI. Combined with target architecture and OS to determine
// GC, EH, and unwind styles.
CORINFO_RUNTIME_ABI targetAbi;
-#endif
CORINFO_OS osType;
unsigned osMajor;
@@ -1858,18 +1813,6 @@ enum { LCL_FINALLY_MARK = 0xFC }; // FC = "Finally Call"
* when it generates code
**********************************************************************************/
-#if COR_JIT_EE_VERSION <= 460
-
-#define CORINFO_PAGE_SIZE 0x1000 // the page size on the machine
-
-#ifndef FEATURE_PAL
-#define MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT ((32*1024)-1) // when generating JIT code
-#else // !FEATURE_PAL
-#define MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT ((OS_PAGE_SIZE / 2) - 1)
-#endif // !FEATURE_PAL
-
-#endif // COR_JIT_EE_VERISION <= 460
-
#include <pshpack4.h>
typedef void* CORINFO_MethodPtr; // a generic method pointer
@@ -2111,19 +2054,25 @@ public:
unsigned* offsetAfterIndirection /* OUT */
) = 0;
+ // Find the virtual method in implementingClass that overrides virtualMethod,
+ // or the method in implementingClass that implements the interface method
+ // represented by virtualMethod.
+ //
+ // Return null if devirtualization is not possible. Owner type is optional
+ // and provides additional context for shared interface devirtualization.
+ virtual CORINFO_METHOD_HANDLE resolveVirtualMethod(
+ CORINFO_METHOD_HANDLE virtualMethod, /* IN */
+ CORINFO_CLASS_HANDLE implementingClass, /* IN */
+ CORINFO_CONTEXT_HANDLE ownerType = NULL /* IN */
+ ) = 0;
+
// If a method's attributes have (getMethodAttribs) CORINFO_FLG_INTRINSIC set,
// getIntrinsicID() returns the intrinsic ID.
// *pMustExpand tells whether or not JIT must expand the intrinsic.
-#if COR_JIT_EE_VERSION > 460
virtual CorInfoIntrinsics getIntrinsicID(
CORINFO_METHOD_HANDLE method,
bool* pMustExpand = NULL /* OUT */
) = 0;
-#else
- virtual CorInfoIntrinsics getIntrinsicID(
- CORINFO_METHOD_HANDLE method
- ) = 0;
-#endif
// Is the given module the System.Numerics.Vectors module?
// This defaults to false.
@@ -2215,13 +2164,11 @@ public:
// failures during token resolution.
virtual void resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken) = 0;
-#if COR_JIT_EE_VERSION > 460
// Attempt to resolve a metadata token into a runtime method handle. Returns true
// if resolution succeeded and false otherwise (e.g. if it encounters invalid metadata
// during token reoslution). This method should be used instead of `resolveToken` in
// situations that need to be resilient to invalid metadata.
virtual bool tryResolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken) = 0;
-#endif
// Signature information about the call sig
virtual void findSig (
@@ -2368,7 +2315,7 @@ public:
// in representing of 'cls' from a GC perspective. The class is
// assumed to be an array of machine words
// (of length // getClassSize(cls) / sizeof(void*)),
- // 'gcPtrs' is a poitner to an array of BYTEs of this length.
+ // 'gcPtrs' is a pointer to an array of BYTEs of this length.
// getClassGClayout fills in this array so that gcPtrs[i] is set
// to one of the CorInfoGCType values which is the GC type of
// the i-th machine word of an object of type 'cls'
@@ -2440,7 +2387,7 @@ public:
// value into a particular location and thus has the signature
// void unboxHelper(void* dest, CORINFO_CLASS_HANDLE cls, Object* obj)
// Otherwise (it is null or points at a FALSE value) it is requesting
- // a helper that returns a poitner to the unboxed data
+ // a helper that returns a pointer to the unboxed data
// void* unboxHelper(CORINFO_CLASS_HANDLE cls, Object* obj)
// The EE has the option of NOT returning the copy style helper
// (But must be able to always honor the non-copy style helper)
@@ -2451,7 +2398,6 @@ public:
CORINFO_CLASS_HANDLE cls
) = 0;
-#if COR_JIT_EE_VERSION > 460
virtual bool getReadyToRunHelper(
CORINFO_RESOLVED_TOKEN * pResolvedToken,
CORINFO_LOOKUP_KIND * pGenericLookupKind,
@@ -2462,16 +2408,8 @@ public:
virtual void getReadyToRunDelegateCtorHelper(
CORINFO_RESOLVED_TOKEN * pTargetMethod,
CORINFO_CLASS_HANDLE delegateType,
- CORINFO_CONST_LOOKUP * pLookup
- ) = 0;
-#else
- virtual void getReadyToRunHelper(
- CORINFO_RESOLVED_TOKEN * pResolvedToken,
- CorInfoHelpFunc id,
- CORINFO_CONST_LOOKUP * pLookup
+ CORINFO_LOOKUP * pLookup
) = 0;
-#endif
-
virtual const char* getHelperName(
CorInfoHelpFunc
@@ -2788,7 +2726,6 @@ public:
virtual void ThrowExceptionForHelper(
const CORINFO_HELPER_DESC * throwHelper) = 0;
-#if COR_JIT_EE_VERSION > 460
// Runs the given function under an error trap. This allows the JIT to make calls
// to interface functions that may throw exceptions without needing to be aware of
// the EH ABI, exception types, etc. Returns true if the given function completed
@@ -2797,7 +2734,6 @@ public:
void (*function)(void*), // The function to run
void* parameter // The context parameter that will be passed to the function and the handler
) = 0;
-#endif
/*****************************************************************************
* ICorStaticInfo contains EE interface methods which return values that are
@@ -2849,16 +2785,12 @@ public:
size_t FQNameCapacity /* IN */
) = 0;
-#if COR_JIT_EE_VERSION > 460
-
// returns whether the struct is enregisterable. Only valid on a System V VM. Returns true on success, false on failure.
virtual bool getSystemVAmd64PassStructInRegisterDescriptor(
/* IN */ CORINFO_CLASS_HANDLE structHnd,
/* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr
) = 0;
-#endif // COR_JIT_EE_VERSION
-
};
/*****************************************************************************
@@ -2984,8 +2916,7 @@ public:
) = 0;
// NOTE: the two methods below--getPInvokeUnmanagedTarget and getAddressOfPInvokeFixup--are
- // deprecated. New code (i.e. anything that can depend on COR_JIT_EE_VERSION being
- // greater than 460) should instead use getAddressOfPInvokeTarget, which subsumes the
+ // deprecated. New code should instead use getAddressOfPInvokeTarget, which subsumes the
// functionality of these methods.
// return the unmanaged target *if method has already been prelinked.*
@@ -3000,14 +2931,12 @@ public:
void **ppIndirection = NULL
) = 0;
-#if COR_JIT_EE_VERSION > 460
// return the address of the PInvoke target. May be a fixup area in the
// case of late-bound PInvoke calls.
virtual void getAddressOfPInvokeTarget(
CORINFO_METHOD_HANDLE method,
CORINFO_CONST_LOOKUP *pLookup
) = 0;
-#endif
// Generate a cookie based on the signature that would needs to be passed
// to CORINFO_HELP_PINVOKE_CALLI
diff --git a/src/inc/corjit.h b/src/inc/corjit.h
index 6d01b9f9d9..e6d067c0fe 100644
--- a/src/inc/corjit.h
+++ b/src/inc/corjit.h
@@ -72,86 +72,6 @@ enum CorJitResult
CORJIT_RECOVERABLEERROR = MAKE_HRESULT(SEVERITY_ERROR,FACILITY_NULL, 5),
};
-
-#if COR_JIT_EE_VERSION <= 460
-
-/* values for flags in compileMethod */
-
-enum CorJitFlag
-{
- CORJIT_FLG_SPEED_OPT = 0x00000001,
- CORJIT_FLG_SIZE_OPT = 0x00000002,
- CORJIT_FLG_DEBUG_CODE = 0x00000004, // generate "debuggable" code (no code-mangling optimizations)
- CORJIT_FLG_DEBUG_EnC = 0x00000008, // We are in Edit-n-Continue mode
- CORJIT_FLG_DEBUG_INFO = 0x00000010, // generate line and local-var info
- CORJIT_FLG_MIN_OPT = 0x00000020, // disable all jit optimizations (not necesarily debuggable code)
- CORJIT_FLG_GCPOLL_CALLS = 0x00000040, // Emit calls to JIT_POLLGC for thread suspension.
- CORJIT_FLG_MCJIT_BACKGROUND = 0x00000080, // Calling from multicore JIT background thread, do not call JitComplete
-
- CORJIT_FLG_UNUSED1 = 0x00000100,
-
-#if defined(_TARGET_X86_)
-
- CORJIT_FLG_PINVOKE_RESTORE_ESP = 0x00000200, // Restore ESP after returning from inlined PInvoke
- CORJIT_FLG_TARGET_P4 = 0x00000400,
- CORJIT_FLG_USE_FCOMI = 0x00000800, // Generated code may use fcomi(p) instruction
- CORJIT_FLG_USE_CMOV = 0x00001000, // Generated code may use cmov instruction
- CORJIT_FLG_USE_SSE2 = 0x00002000, // Generated code may use SSE-2 instructions
-
-#elif defined(_TARGET_AMD64_)
-
- CORJIT_FLG_USE_SSE3_4 = 0x00000200,
- CORJIT_FLG_USE_AVX = 0x00000400,
- CORJIT_FLG_USE_AVX2 = 0x00000800,
- CORJIT_FLG_USE_AVX_512 = 0x00001000,
- CORJIT_FLG_FEATURE_SIMD = 0x00002000,
-
-#else // !defined(_TARGET_X86_) && !defined(_TARGET_AMD64_)
-
- CORJIT_FLG_UNUSED2 = 0x00000200,
- CORJIT_FLG_UNUSED3 = 0x00000400,
- CORJIT_FLG_UNUSED4 = 0x00000800,
- CORJIT_FLG_UNUSED5 = 0x00001000,
- CORJIT_FLG_UNUSED6 = 0x00002000,
-
-#endif // !defined(_TARGET_X86_) && !defined(_TARGET_AMD64_)
-
- CORJIT_FLG_MAKEFINALCODE = 0x00008000, // Use the final code generator, i.e., not the interpreter.
- CORJIT_FLG_READYTORUN = 0x00010000, // Use version-resilient code generation
-
- CORJIT_FLG_PROF_ENTERLEAVE = 0x00020000, // Instrument prologues/epilogues
- CORJIT_FLG_PROF_REJIT_NOPS = 0x00040000, // Insert NOPs to ensure code is re-jitable
- CORJIT_FLG_PROF_NO_PINVOKE_INLINE
- = 0x00080000, // Disables PInvoke inlining
- CORJIT_FLG_SKIP_VERIFICATION = 0x00100000, // (lazy) skip verification - determined without doing a full resolve. See comment below
- CORJIT_FLG_PREJIT = 0x00200000, // jit or prejit is the execution engine.
- CORJIT_FLG_RELOC = 0x00400000, // Generate relocatable code
- CORJIT_FLG_IMPORT_ONLY = 0x00800000, // Only import the function
- CORJIT_FLG_IL_STUB = 0x01000000, // method is an IL stub
- CORJIT_FLG_PROCSPLIT = 0x02000000, // JIT should separate code into hot and cold sections
- CORJIT_FLG_BBINSTR = 0x04000000, // Collect basic block profile information
- CORJIT_FLG_BBOPT = 0x08000000, // Optimize method based on profile information
- CORJIT_FLG_FRAMED = 0x10000000, // All methods have an EBP frame
- CORJIT_FLG_ALIGN_LOOPS = 0x20000000, // add NOPs before loops to align them at 16 byte boundaries
- CORJIT_FLG_PUBLISH_SECRET_PARAM= 0x40000000, // JIT must place stub secret param into local 0. (used by IL stubs)
- CORJIT_FLG_GCPOLL_INLINE = 0x80000000, // JIT must inline calls to GCPoll when possible
-};
-
-enum CorJitFlag2
-{
- CORJIT_FLG2_SAMPLING_JIT_BACKGROUND = 0x00000001, // JIT is being invoked as a result of stack sampling for hot methods in the background
-};
-
-struct CORJIT_FLAGS
-{
- unsigned corJitFlags; // Values are from CorJitFlag
- unsigned corJitFlags2; // Values are from CorJitFlag2
-};
-
-#endif // COR_JIT_EE_VERSION <= 460
-
-#if COR_JIT_EE_VERSION > 460
-
class CORJIT_FLAGS
{
public:
@@ -226,6 +146,8 @@ public:
CORJIT_FLAG_USE_PINVOKE_HELPERS = 36, // The JIT should use the PINVOKE_{BEGIN,END} helpers instead of emitting inline transitions
CORJIT_FLAG_REVERSE_PINVOKE = 37, // The JIT should insert REVERSE_PINVOKE_{ENTER,EXIT} helpers into method prolog/epilog
CORJIT_FLAG_DESKTOP_QUIRKS = 38, // The JIT should generate desktop-quirk-compatible code
+ CORJIT_FLAG_TIER0 = 39, // This is the initial tier for tiered compilation which should generate code as quickly as possible
+ CORJIT_FLAG_TIER1 = 40, // This is the final tier (for now) for tiered compilation which should generate high quality code
};
CORJIT_FLAGS()
@@ -292,7 +214,6 @@ private:
unsigned __int64 corJitFlags;
};
-#endif // COR_JIT_EE_VERSION > 460
/*****************************************************************************
Here is how CORJIT_FLAG_SKIP_VERIFICATION should be interepreted.
@@ -450,14 +371,10 @@ enum CheckedWriteBarrierKinds {
CWBKind_AddrOfLocal, // Store through the address of a local (arguably a bug that this happens at all).
};
-#if COR_JIT_EE_VERSION > 460
-
#include "corjithost.h"
extern "C" void __stdcall jitStartup(ICorJitHost* host);
-#endif
-
class ICorJitCompiler;
class ICorJitInfo;
struct IEEMemoryManager;
@@ -515,11 +432,7 @@ public:
// When the EE loads the System.Numerics.Vectors assembly, it asks the JIT what length (in bytes) of
// SIMD vector it supports as an intrinsic type. Zero means that the JIT does not support SIMD
// intrinsics, so the EE should use the default size (i.e. the size of the IL implementation).
-#if COR_JIT_EE_VERSION > 460
virtual unsigned getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags) { return 0; }
-#else
- virtual unsigned getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags) { return 0; }
-#endif
// IL obfuscators sometimes interpose on the EE-JIT interface. This function allows the VM to
// tell the JIT to use a particular ICorJitCompiler to implement the methods of this interface,
@@ -702,7 +615,6 @@ public:
//
virtual DWORD getExpectedTargetArchitecture() = 0;
-#if COR_JIT_EE_VERSION > 460
// Fetches extended flags for a particular compilation instance. Returns
// the number of bytes written to the provided buffer.
virtual DWORD getJitFlags(
@@ -710,7 +622,6 @@ public:
DWORD sizeInBytes /* IN: The size of the buffer. Note that this is effectively a
version number for the CORJIT_FLAGS value. */
) = 0;
-#endif
};
/**********************************************************************************/
diff --git a/src/inc/corpolicy.h b/src/inc/corpolicy.h
index ce37db463e..21d615bc82 100644
--- a/src/inc/corpolicy.h
+++ b/src/inc/corpolicy.h
@@ -28,46 +28,6 @@ extern "C" {
{ 0xd41e4f1f, 0xa407, 0x11d1, {0x8b, 0xc9, 0x0, 0xc0, 0x4f, 0xa3, 0xa, 0x41 } }
-#ifndef FEATURE_CORECLR
-// See if we're set up to do a version check
-#if (VER_MAJORVERSION < 4)
-#error "Looks like major version isn't set correctly. Are you including product_version.h?"
-#endif
-
-// The following check has been added to ensure the right thing is done
-// for SxS compatibility of mscorsecimpl.dll when moving to a new framework
-// version.
-//
-// The library is registered using a full path and a GUID in the following location:
-// HKLM\SOFTWARE\Microsoft\Cryptography\Providers\Trust\*
-// With a new SxS version of the framework, we need to move to a new
-// GUID so older versions continue to work unimpacted.
-//
-// The check will fail when the runtime version changes; when it does,
-// please do the following:
-//
-// If the new version is NOT a SxS release with the version number in the #if,
-// update the version number in the #if below to the new version and you're done.
-//
-// If the new release is a SxS release, then there's a bit more work involved:
-// 1. Change COREE_POLICY_PROVIDER in CorPolicy.h to a new GUID.
-// 2. Update batchSetup to use the new GUID. To do so, update
-// all occurrences of the GUID in
-// ndp\clr\src\dlls\mscorsecimpl\mscorsecimpl.vrg
-// 3. Update "real" setup to use the new GUID. To do so, update
-// all occurrences of the GUID in
-// setupauthoring\netfx\clr\Components\mscorsec.dll.ddc
-// 4. Update the version number in the #if below.
-
-#if !(VER_MAJORVERSION == 4 && VER_MINORVERSION == 0)
-#error "The guid for mscorsecimpl needs to change when the runtime version changes"
-#endif
-
-// {A7F4C378-21BE-494e-BA0F-BB12C5D208C5}
-#define COREE_POLICY_PROVIDER \
-{ 0xa7f4c378, 0x21be, 0x494e, {0xba, 0x0f, 0xbb, 0x12, 0xc5, 0xd2, 0x08, 0xc5 } }
-
-#endif //#ifndef FEATURE_CORECLR
// This structure is returned from the winverify trust call, free up the structure
// using CoTaskMemAlloc except for COREE_POLICY_PROVIDER which uses LocalALLoc.
diff --git a/src/inc/corpriv.h b/src/inc/corpriv.h
index 8c737c7607..c422351402 100644
--- a/src/inc/corpriv.h
+++ b/src/inc/corpriv.h
@@ -23,10 +23,6 @@
#include "peinformation.h"
//
-#ifndef FEATURE_CORECLR
-interface IILFingerprint;
-interface IILFingerprintFactory;
-#endif
interface IAssemblyName;
// PE images loaded through the runtime.
@@ -44,9 +40,7 @@ STDAPI MetaDataGetDispenser( // Return HRESULT
STDAPI RuntimeCheckLocationAccess(LPCWSTR wszLocation);
STDAPI RuntimeIsNativeImageOptedOut(IAssemblyName* pAssemblyDef);
-#ifdef FEATURE_VERSIONING
LocaleID RuntimeGetFileSystemLocale();
-#endif // FEATURE_VERSIONING
BOOL RuntimeFileNotFound(HRESULT hr);
@@ -331,11 +325,6 @@ STDAPI RuntimeOpenImageInternal(LPCWSTR pszFileName, HCORMODULE* hHandle,
STDAPI RuntimeOpenImageByStream(IStream* pIStream, UINT64 AssemblyId, DWORD dwModuleId,
HCORMODULE* hHandle, DWORD *pdwLength, MDInternalImportFlags flags);
-#ifndef FEATURE_CORECLR
-// NOTE: Performance critical codepaths should cache the result of this function.
-STDAPI RuntimeGetILFingerprintForPath(LPCWSTR path, IILFingerprint **ppFingerprint);
-STDAPI RuntimeCreateCachingILFingerprintFactory(IILFingerprintFactory **ppILFingerprintFactory);
-#endif //!FEATURE_CORECLR
void RuntimeAddRefHandle(HCORMODULE hHandle);
STDAPI RuntimeReleaseHandle(HCORMODULE hHandle);
STDAPI RuntimeGetImageBase(HCORMODULE hHandle, LPVOID* base, BOOL bMapped, COUNT_T* dwSize);
@@ -480,153 +469,6 @@ struct CORCOMPILE_VERSION_INFO;
struct CORCOMPILE_DEPENDENCY;
typedef GUID CORCOMPILE_NGEN_SIGNATURE;
-#ifdef FEATURE_FUSION
-//**********************************************************************
-// Gets the dependancies of a native image. If these change, then
-// the native image cannot be used.
-//
-// IMetaDataImport::GetAssemblyRefProps() can be used to obtain information about
-// the mdAssemblyRefs.
-//*****************************************************************************
-
-// {814C9E35-3F3F-4975-977A-371F0A878AC7}
-EXTERN_GUID(IID_INativeImageDependency, 0x814c9e35, 0x3f3f, 0x4975, 0x97, 0x7a, 0x37, 0x1f, 0xa, 0x87, 0x8a, 0xc7);
-
-DECLARE_INTERFACE_(INativeImageDependency, IUnknown)
-{
- // Get the referenced assembly
- STDMETHOD (GetILAssemblyRef) (
- mdAssemblyRef * pAssemblyRef // [OUT]
- ) PURE;
-
- // Get the post-policy assembly actually used
- STDMETHOD (GetILAssemblyDef) (
- mdAssemblyRef * ppAssemblyDef, // [OUT]
- CORCOMPILE_ASSEMBLY_SIGNATURE * pSign // [OUT]
- ) PURE;
-
- // Get the native image corresponding to GetILAssemblyDef() IF
- // there is a hard-bound (directly-referenced) native dependancy
- //
- // We do not need the configStrig because configStrings have to
- // be an exact part. Any partial matches are factored out into GetConfigMask()
- STDMETHOD (GetNativeAssemblyDef) (
- CORCOMPILE_NGEN_SIGNATURE * pNativeSign // [OUT] INVALID_NGEN_SIGNATURE if there is no hard-bound dependancy
- ) PURE;
-
- // Get PEKIND of the referenced assembly
- STDMETHOD (GetPEKind) (
- PEKIND * CorPEKind // [OUT]
- ) PURE;
-
-}; // INativeImageDependency
-
-//*****************************************************************************
-//
-// Fusion uses IFusionNativeImageInfo to obtain (and cache) informaton
-// about a native image being installed into the native image cache.
-// This allows Fusion to bind directly to native images
-// without requiring (expensively) binding to the IL assembly first.
-//
-// IMetaDataAssemblyImport can be queried for this interface
-//
-//*****************************************************************************
-// {0EA273D0-B4DA-4008-A60D-8D6EFFDD6E91}
-EXTERN_GUID(IID_INativeImageInstallInfo, 0xea273d0, 0xb4da, 0x4008, 0xa6, 0xd, 0x8d, 0x6e, 0xff, 0xdd, 0x6e, 0x91);
-
-DECLARE_INTERFACE_(INativeImageInstallInfo, IUnknown)
-{
- // Signature of the ngen image
- // This matches the argument type of INativeImageDependency::GetNativeAssemblyDef
-
- STDMETHOD (GetSignature) (
- CORCOMPILE_NGEN_SIGNATURE * pNgenSign // [OUT]
- ) PURE;
-
-
- // CLR timestamp, CPU, compile options, OS type and other attributes of the
- // NI image. This can be used to verify that the NI image was built
- // with the running CLR.
-
- STDMETHOD (GetVersionInfo) (
- CORCOMPILE_VERSION_INFO * pVersionInfo // [OUT]
- ) PURE;
-
-
- // Signature of the source IL assembly. This can be used to
- // verify that the IL image matches a candidate ngen image.
- // This matches the argument type of IAssemblyRuntimeSignature::CheckSignature
- //
-
- STDMETHOD (GetILSignature) (
- CORCOMPILE_ASSEMBLY_SIGNATURE * pILSign // [OUT]
- ) PURE;
-
- // A partial match is allowed for the current NativeImage to be valid
-
- STDMETHOD (GetConfigMask) (
- DWORD * pConfigMask // [OUT]
- ) PURE;
-
- //
- // Dependancy assemblies. The native image is only valid
- // if the dependancies have not changed.
- //
-
- STDMETHOD (EnumDependencies) (
- HCORENUM * phEnum, // [IN/OUT] - Pointer to the enum
- INativeImageDependency *rDeps[], // [OUT]
- ULONG cMax, // [IN] Max dependancies to enumerate in this iteration
- DWORD * pdwCount // [OUT] - Number of dependancies actually enumerated
- ) PURE;
-
-
- // Retrieve a specific dependency by the ngen signature.
-
- STDMETHOD (GetDependency) (
- const CORCOMPILE_NGEN_SIGNATURE *pcngenSign, // [IN] ngenSig of dependency you want
- CORCOMPILE_DEPENDENCY *pDep // [OUT] matching dependency
- ) PURE;
-
-}; // INativeImageInstallInfo
-
-//*****************************************************************************
-//
-// Runtime callback made by Fusion into the CLR to determine if the NativeAssembly
-// can be used. The pUnkBindSink argument of CAssemblyName::BindToObject() can
-// be queried for this interface
-//
-//*****************************************************************************
-// {065AA013-9BDC-447c-922F-FEE929908447}
-EXTERN_GUID(IID_INativeImageEvaluate, 0x65aa013, 0x9bdc, 0x447c, 0x92, 0x2f, 0xfe, 0xe9, 0x29, 0x90, 0x84, 0x47);
-
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:28718)
-#endif //_PREFAST_
-
-interface IAssembly;
-
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif //_PREFAST_
-
-
-DECLARE_INTERFACE_(INativeImageEvaluate, IUnknown)
-{
- // This will be called before the assemblies are actually loaded.
- //
- // Returns S_FALSE if the native-image cannot be used.
-
- STDMETHOD (Evaluate) (
- IAssembly *pILAssembly, // [IN] IL assembly in question
- IAssembly *pNativeAssembly, // [IN] NGen image we are trying to use for pILAssembly
- BYTE * pbCachedData, // [IN] Data cached when the native-image was generated
- DWORD dwDataSize // [IN] Size of the pbCachedData buffer
- ) PURE;
-}; // INativeImageEvaluate
-
-#endif // FEATURE_FUSION
//**********************************************************************
// Internal versions of shim functions for use by the CLR.
@@ -676,10 +518,6 @@ STDAPI GetRequestedRuntimeInfoInternal(LPCWSTR pExe,
// and is shared by the desktop and coreclr's which have separate native binders.
// Hence, this interface inherits a lot of "baggage."
-#ifdef FEATURE_FUSION
-interface IFusionBindLog;
-interface IAssemblyName;
-#endif // FEATURE_FUSION
// A small shim around PEAssemblies/IBindResult that allow us to write Fusion/CLR-agnostic code
@@ -694,10 +532,6 @@ class LoggableAssembly
{
public:
virtual SString DisplayString() = 0; // Returns an unspecified representation suitable for injecting into log messages.
-#ifdef FEATURE_FUSION
- virtual IAssemblyName* FusionAssemblyName() = 0; // Can return NULL. Caller must NOT release result.
- virtual IFusionBindLog* FusionBindLog() = 0; // Can return NULL. Caller must NOT release result.
-#endif // FEATURE_FUSION
};
@@ -720,11 +554,6 @@ BOOL RuntimeVerifyNativeImageDependency(const CORCOMPILE_DEPENDENCY *pExpected
-#ifndef FEATURE_CORECLR
-
-#include "iilfingerprint.h"
-
-#endif //!FEATURE_CORECLR
#endif // _CORPRIV_H_
// EOF =======================================================================
diff --git a/src/inc/corprof.idl b/src/inc/corprof.idl
index 9af1cd97a8..3378431317 100644
--- a/src/inc/corprof.idl
+++ b/src/inc/corprof.idl
@@ -3740,15 +3740,20 @@ interface ICorProfilerInfo6 : ICorProfilerInfo5
{
/*
* Returns an enumerator for all methods that
- * - belong to a given NGen module (inlinersModuleId) and
+ * - belong to a given NGen or R2R module (inlinersModuleId) and
* - inlined a body of a given method (inlineeModuleId / inlineeMethodId).
*
* If incompleteData is set to TRUE after function is called, it means that the methods enumerator
* doesn't contain all methods inlining a given method.
* It can happen when one or more direct or indirect dependencies of inliners module haven't been loaded yet.
- * If profiler needs accurate data it should retry later when more modules are loaded (preferable on each module load).
+ * If profiler needs accurate data it should retry later when more modules are loaded (preferably on each module load).
*
* It can be used to lift limitation on inlining for ReJIT.
+ *
+ * NOTE: If the inlinee method is decorated with the System.Runtime.Versioning.NonVersionable attribute then
+ * then some inliners may not ever be reported. If you need to get a full accounting you can avoid the issue
+ * by disabling the use of all native images.
+ *
*/
HRESULT EnumNgenModuleMethodsInliningThisMethod(
[in] ModuleID inlinersModuleId,
diff --git a/src/inc/crosscomp.h b/src/inc/crosscomp.h
index 494ca7c007..200c343a45 100644
--- a/src/inc/crosscomp.h
+++ b/src/inc/crosscomp.h
@@ -195,7 +195,7 @@ typedef union _NEON128 {
struct {
ULONGLONG Low;
LONGLONG High;
- } DUMMYSTRUCTNAME;
+ };
double D[2];
float S[4];
WORD H[8];
@@ -288,7 +288,7 @@ typedef struct _T_RUNTIME_FUNCTION {
DWORD CR : 2;
DWORD FrameSize : 9;
} PackedUnwindData;
- } DUMMYUNIONNAME;
+ };
} T_RUNTIME_FUNCTION, *PT_RUNTIME_FUNCTION;
diff --git a/src/inc/crsttypes.h b/src/inc/crsttypes.h
index 8c702fa553..b4f6f49e64 100644
--- a/src/inc/crsttypes.h
+++ b/src/inc/crsttypes.h
@@ -56,134 +56,135 @@ enum CrstType
CrstDynamicMT = 39,
CrstDynLinkZapItems = 40,
CrstEtwTypeLogHash = 41,
- CrstEventStore = 42,
- CrstException = 43,
- CrstExecuteManLock = 44,
- CrstExecuteManRangeLock = 45,
- CrstFCall = 46,
- CrstFriendAccessCache = 47,
- CrstFuncPtrStubs = 48,
- CrstFusionAppCtx = 49,
- CrstFusionAssemblyDownload = 50,
- CrstFusionBindContext = 51,
- CrstFusionBindResult = 52,
- CrstFusionClb = 53,
- CrstFusionClosure = 54,
- CrstFusionClosureGraph = 55,
- CrstFusionConfigSettings = 56,
- CrstFusionDownload = 57,
- CrstFusionIsoLibInit = 58,
- CrstFusionLoadContext = 59,
- CrstFusionLog = 60,
- CrstFusionNgenIndex = 61,
- CrstFusionNgenIndexPool = 62,
- CrstFusionPcyCache = 63,
- CrstFusionPolicyConfigPool = 64,
- CrstFusionSingleUse = 65,
- CrstFusionWarningLog = 66,
- CrstGCMemoryPressure = 67,
- CrstGlobalStrLiteralMap = 68,
- CrstHandleTable = 69,
- CrstHostAssemblyMap = 70,
- CrstHostAssemblyMapAdd = 71,
- CrstIbcProfile = 72,
- CrstIJWFixupData = 73,
- CrstIJWHash = 74,
- CrstILFingerprintCache = 75,
- CrstILStubGen = 76,
- CrstInlineTrackingMap = 77,
- CrstInstMethodHashTable = 78,
- CrstInterfaceVTableMap = 79,
- CrstInterop = 80,
- CrstInteropData = 81,
- CrstIOThreadpoolWorker = 82,
- CrstIsJMCMethod = 83,
- CrstISymUnmanagedReader = 84,
- CrstJit = 85,
- CrstJitGenericHandleCache = 86,
- CrstJitPerf = 87,
- CrstJumpStubCache = 88,
- CrstLeafLock = 89,
- CrstListLock = 90,
- CrstLoaderAllocator = 91,
- CrstLoaderAllocatorReferences = 92,
- CrstLoaderHeap = 93,
- CrstMda = 94,
- CrstMetadataTracker = 95,
- CrstModIntPairList = 96,
- CrstModule = 97,
- CrstModuleFixup = 98,
- CrstModuleLookupTable = 99,
- CrstMulticoreJitHash = 100,
- CrstMulticoreJitManager = 101,
- CrstMUThunkHash = 102,
- CrstNativeBinderInit = 103,
- CrstNativeImageCache = 104,
- CrstNls = 105,
- CrstObjectList = 106,
- CrstOnEventManager = 107,
- CrstPatchEntryPoint = 108,
- CrstPEFileSecurityManager = 109,
- CrstPEImage = 110,
- CrstPEImagePDBStream = 111,
- CrstPendingTypeLoadEntry = 112,
- CrstPinHandle = 113,
- CrstPinnedByrefValidation = 114,
- CrstProfilerGCRefDataFreeList = 115,
- CrstProfilingAPIStatus = 116,
- CrstPublisherCertificate = 117,
- CrstRCWCache = 118,
- CrstRCWCleanupList = 119,
- CrstRCWRefCache = 120,
- CrstReDacl = 121,
- CrstReflection = 122,
- CrstReJITDomainTable = 123,
- CrstReJITGlobalRequest = 124,
- CrstReJITSharedDomainTable = 125,
- CrstRemoting = 126,
- CrstRetThunkCache = 127,
- CrstRWLock = 128,
- CrstSavedExceptionInfo = 129,
- CrstSaveModuleProfileData = 130,
- CrstSecurityPolicyCache = 131,
- CrstSecurityPolicyInit = 132,
- CrstSecurityStackwalkCache = 133,
- CrstSharedAssemblyCreate = 134,
- CrstSharedBaseDomain = 135,
- CrstSigConvert = 136,
- CrstSingleUseLock = 137,
- CrstSpecialStatics = 138,
- CrstSqmManager = 139,
- CrstStackSampler = 140,
- CrstStressLog = 141,
- CrstStrongName = 142,
- CrstStubCache = 143,
- CrstStubDispatchCache = 144,
- CrstStubUnwindInfoHeapSegments = 145,
- CrstSyncBlockCache = 146,
- CrstSyncHashLock = 147,
- CrstSystemBaseDomain = 148,
- CrstSystemDomain = 149,
- CrstSystemDomainDelayedUnloadList = 150,
- CrstThreadIdDispenser = 151,
- CrstThreadpoolEventCache = 152,
- CrstThreadpoolTimerQueue = 153,
- CrstThreadpoolWaitThreads = 154,
- CrstThreadpoolWorker = 155,
- CrstThreadStaticDataHashTable = 156,
- CrstThreadStore = 157,
- CrstTPMethodTable = 158,
- CrstTypeEquivalenceMap = 159,
- CrstTypeIDMap = 160,
- CrstUMEntryThunkCache = 161,
- CrstUMThunkHash = 162,
- CrstUniqueStack = 163,
- CrstUnresolvedClassLock = 164,
- CrstUnwindInfoTableLock = 165,
- CrstVSDIndirectionCellLock = 166,
- CrstWinRTFactoryCache = 167,
- CrstWrapperTemplate = 168,
- kNumberOfCrstTypes = 169
+ CrstEventPipe = 42,
+ CrstEventStore = 43,
+ CrstException = 44,
+ CrstExecuteManLock = 45,
+ CrstExecuteManRangeLock = 46,
+ CrstFCall = 47,
+ CrstFriendAccessCache = 48,
+ CrstFuncPtrStubs = 49,
+ CrstFusionAppCtx = 50,
+ CrstFusionAssemblyDownload = 51,
+ CrstFusionBindContext = 52,
+ CrstFusionBindResult = 53,
+ CrstFusionClb = 54,
+ CrstFusionClosure = 55,
+ CrstFusionClosureGraph = 56,
+ CrstFusionConfigSettings = 57,
+ CrstFusionDownload = 58,
+ CrstFusionIsoLibInit = 59,
+ CrstFusionLoadContext = 60,
+ CrstFusionLog = 61,
+ CrstFusionNgenIndex = 62,
+ CrstFusionNgenIndexPool = 63,
+ CrstFusionPcyCache = 64,
+ CrstFusionPolicyConfigPool = 65,
+ CrstFusionSingleUse = 66,
+ CrstFusionWarningLog = 67,
+ CrstGCMemoryPressure = 68,
+ CrstGlobalStrLiteralMap = 69,
+ CrstHandleTable = 70,
+ CrstHostAssemblyMap = 71,
+ CrstHostAssemblyMapAdd = 72,
+ CrstIbcProfile = 73,
+ CrstIJWFixupData = 74,
+ CrstIJWHash = 75,
+ CrstILFingerprintCache = 76,
+ CrstILStubGen = 77,
+ CrstInlineTrackingMap = 78,
+ CrstInstMethodHashTable = 79,
+ CrstInterfaceVTableMap = 80,
+ CrstInterop = 81,
+ CrstInteropData = 82,
+ CrstIOThreadpoolWorker = 83,
+ CrstIsJMCMethod = 84,
+ CrstISymUnmanagedReader = 85,
+ CrstJit = 86,
+ CrstJitGenericHandleCache = 87,
+ CrstJitPerf = 88,
+ CrstJumpStubCache = 89,
+ CrstLeafLock = 90,
+ CrstListLock = 91,
+ CrstLoaderAllocator = 92,
+ CrstLoaderAllocatorReferences = 93,
+ CrstLoaderHeap = 94,
+ CrstMda = 95,
+ CrstMetadataTracker = 96,
+ CrstModIntPairList = 97,
+ CrstModule = 98,
+ CrstModuleFixup = 99,
+ CrstModuleLookupTable = 100,
+ CrstMulticoreJitHash = 101,
+ CrstMulticoreJitManager = 102,
+ CrstMUThunkHash = 103,
+ CrstNativeBinderInit = 104,
+ CrstNativeImageCache = 105,
+ CrstNls = 106,
+ CrstObjectList = 107,
+ CrstOnEventManager = 108,
+ CrstPatchEntryPoint = 109,
+ CrstPEFileSecurityManager = 110,
+ CrstPEImage = 111,
+ CrstPEImagePDBStream = 112,
+ CrstPendingTypeLoadEntry = 113,
+ CrstPinHandle = 114,
+ CrstPinnedByrefValidation = 115,
+ CrstProfilerGCRefDataFreeList = 116,
+ CrstProfilingAPIStatus = 117,
+ CrstPublisherCertificate = 118,
+ CrstRCWCache = 119,
+ CrstRCWCleanupList = 120,
+ CrstRCWRefCache = 121,
+ CrstReDacl = 122,
+ CrstReflection = 123,
+ CrstReJITDomainTable = 124,
+ CrstReJITGlobalRequest = 125,
+ CrstReJITSharedDomainTable = 126,
+ CrstRemoting = 127,
+ CrstRetThunkCache = 128,
+ CrstRWLock = 129,
+ CrstSavedExceptionInfo = 130,
+ CrstSaveModuleProfileData = 131,
+ CrstSecurityPolicyCache = 132,
+ CrstSecurityPolicyInit = 133,
+ CrstSecurityStackwalkCache = 134,
+ CrstSharedAssemblyCreate = 135,
+ CrstSharedBaseDomain = 136,
+ CrstSigConvert = 137,
+ CrstSingleUseLock = 138,
+ CrstSpecialStatics = 139,
+ CrstSqmManager = 140,
+ CrstStackSampler = 141,
+ CrstStressLog = 142,
+ CrstStrongName = 143,
+ CrstStubCache = 144,
+ CrstStubDispatchCache = 145,
+ CrstStubUnwindInfoHeapSegments = 146,
+ CrstSyncBlockCache = 147,
+ CrstSyncHashLock = 148,
+ CrstSystemBaseDomain = 149,
+ CrstSystemDomain = 150,
+ CrstSystemDomainDelayedUnloadList = 151,
+ CrstThreadIdDispenser = 152,
+ CrstThreadpoolEventCache = 153,
+ CrstThreadpoolTimerQueue = 154,
+ CrstThreadpoolWaitThreads = 155,
+ CrstThreadpoolWorker = 156,
+ CrstThreadStaticDataHashTable = 157,
+ CrstThreadStore = 158,
+ CrstTPMethodTable = 159,
+ CrstTypeEquivalenceMap = 160,
+ CrstTypeIDMap = 161,
+ CrstUMEntryThunkCache = 162,
+ CrstUMThunkHash = 163,
+ CrstUniqueStack = 164,
+ CrstUnresolvedClassLock = 165,
+ CrstUnwindInfoTableLock = 166,
+ CrstVSDIndirectionCellLock = 167,
+ CrstWinRTFactoryCache = 168,
+ CrstWrapperTemplate = 169,
+ kNumberOfCrstTypes = 170
};
#endif // __CRST_TYPES_INCLUDED
@@ -236,6 +237,7 @@ int g_rgCrstLevelMap[] =
3, // CrstDynamicMT
3, // CrstDynLinkZapItems
7, // CrstEtwTypeLogHash
+ 11, // CrstEventPipe
0, // CrstEventStore
0, // CrstException
7, // CrstExecuteManLock
@@ -410,6 +412,7 @@ LPCSTR g_rgCrstNameMap[] =
"CrstDynamicMT",
"CrstDynLinkZapItems",
"CrstEtwTypeLogHash",
+ "CrstEventPipe",
"CrstEventStore",
"CrstException",
"CrstExecuteManLock",
@@ -557,3 +560,4 @@ inline static LPCSTR GetCrstName(CrstType crstType)
}
#endif // defined(__IN_CRST_CPP) && defined(_DEBUG)
+
diff --git a/src/inc/daccess.h b/src/inc/daccess.h
index 3e3a62c746..7d82e86cb9 100644
--- a/src/inc/daccess.h
+++ b/src/inc/daccess.h
@@ -2393,6 +2393,10 @@ typedef DPTR(IMAGE_TLS_DIRECTORY) PTR_IMAGE_TLS_DIRECTORY;
#include <xclrdata.h>
#endif
+#if defined(_TARGET_X86_) && defined(FEATURE_PAL)
+typedef DPTR(struct _UNWIND_INFO) PTR_UNWIND_INFO;
+#endif
+
#ifdef _WIN64
typedef DPTR(T_RUNTIME_FUNCTION) PTR_RUNTIME_FUNCTION;
typedef DPTR(struct _UNWIND_INFO) PTR_UNWIND_INFO;
@@ -2445,13 +2449,8 @@ typedef DPTR(PTR_PCODE) PTR_PTR_PCODE;
#endif
// Macros like MAIN_CLR_MODULE_NAME* for the DAC module
-#ifdef FEATURE_MAIN_CLR_MODULE_USES_CORE_NAME
#define MAIN_DAC_MODULE_NAME_W W("mscordaccore")
#define MAIN_DAC_MODULE_DLL_NAME_W W("mscordaccore.dll")
-#else
-#define MAIN_DAC_MODULE_NAME_W W("mscordacwks")
-#define MAIN_DAC_MODULE_DLL_NAME_W W("mscordacwks.dll")
-#endif
// TARGET_CONSISTENCY_CHECK represents a condition that should not fail unless the DAC target is corrupt.
// This is in contrast to ASSERTs in DAC infrastructure code which shouldn't fail regardless of the memory
diff --git a/src/inc/dacprivate.h b/src/inc/dacprivate.h
index 0db4affcfc..a419c47fef 100644
--- a/src/inc/dacprivate.h
+++ b/src/inc/dacprivate.h
@@ -776,21 +776,18 @@ struct MSLAYOUT DacpOomData : ZeroInit<DacpOomData>
}
};
-// This is the value of max_idp_count in ndp\clr\src\vm\gcpriv.h
-#define NUM_GC_DATA_POINTS 9
-// These are from ndp\clr\src\vm\gcrecord.h
-#define MAX_COMPACT_REASONS_COUNT 11
-#define MAX_EXPAND_MECHANISMS_COUNT 6
-#define MAX_GC_MECHANISM_BITS_COUNT 2
-// This is from ndp\clr\src\vm\common.h
-#define MAX_GLOBAL_GC_MECHANISMS_COUNT 6
+#define DAC_NUM_GC_DATA_POINTS 9
+#define DAC_MAX_COMPACT_REASONS_COUNT 11
+#define DAC_MAX_EXPAND_MECHANISMS_COUNT 6
+#define DAC_MAX_GC_MECHANISM_BITS_COUNT 2
+#define DAC_MAX_GLOBAL_GC_MECHANISMS_COUNT 6
struct MSLAYOUT DacpGCInterestingInfoData : ZeroInit<DacpGCInterestingInfoData>
{
- size_t interestingDataPoints[NUM_GC_DATA_POINTS];
- size_t compactReasons[MAX_COMPACT_REASONS_COUNT];
- size_t expandMechanisms[MAX_EXPAND_MECHANISMS_COUNT];
- size_t bitMechanisms[MAX_GC_MECHANISM_BITS_COUNT];
- size_t globalMechanisms[MAX_GLOBAL_GC_MECHANISMS_COUNT];
+ size_t interestingDataPoints[DAC_NUM_GC_DATA_POINTS];
+ size_t compactReasons[DAC_MAX_COMPACT_REASONS_COUNT];
+ size_t expandMechanisms[DAC_MAX_EXPAND_MECHANISMS_COUNT];
+ size_t bitMechanisms[DAC_MAX_GC_MECHANISM_BITS_COUNT];
+ size_t globalMechanisms[DAC_MAX_GLOBAL_GC_MECHANISMS_COUNT];
HRESULT RequestGlobal(ISOSDacInterface *sos)
{
diff --git a/src/inc/dacvars.h b/src/inc/dacvars.h
index 0a60684ad1..4b7b7b1783 100644
--- a/src/inc/dacvars.h
+++ b/src/inc/dacvars.h
@@ -92,9 +92,6 @@ DEFINE_DACVAR(ULONG, PTR_ReadyToRunJitManager, ExecutionManager__m_pReadyToRunJi
DEFINE_DACVAR_NO_DUMP(ULONG, VMHELPDEF *, dac__hlpFuncTable, ::hlpFuncTable)
DEFINE_DACVAR(ULONG, VMHELPDEF *, dac__hlpDynamicFuncTable, ::hlpDynamicFuncTable)
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-DEFINE_DACVAR(ULONG, PTR_ConnectionNameTable, CCLRDebugManager__m_pConnectionNameHash, CCLRDebugManager::m_pConnectionNameHash)
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
DEFINE_DACVAR(ULONG, PTR_StubManager, StubManager__g_pFirstManager, StubManager::g_pFirstManager)
DEFINE_DACVAR(ULONG, PTR_PrecodeStubManager, PrecodeStubManager__g_pManager, PrecodeStubManager::g_pManager)
DEFINE_DACVAR(ULONG, PTR_StubLinkStubManager, StubLinkStubManager__g_pManager, StubLinkStubManager::g_pManager)
@@ -124,22 +121,8 @@ DEFINE_DACVAR(ULONG, int, dac__HillClimbingLogSize, ::HillClimbingLogSize)
DEFINE_DACVAR(ULONG, PTR_Thread, dac__g_pFinalizerThread, ::g_pFinalizerThread)
DEFINE_DACVAR(ULONG, PTR_Thread, dac__g_pSuspensionThread, ::g_pSuspensionThread)
-#ifdef FEATURE_SVR_GC
-DEFINE_DACVAR(ULONG, DWORD, IGCHeap__gcHeapType, IGCHeap::gcHeapType)
-#endif // FEATURE_SVR_GC
-
-DEFINE_DACVAR(ULONG, DWORD, IGCHeap__maxGeneration, IGCHeap::maxGeneration)
-DEFINE_DACVAR(ULONG, PTR_BYTE, WKS__gc_heap__alloc_allocated, WKS::gc_heap::alloc_allocated)
-DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE /*PTR_heap_segment*/, WKS__gc_heap__ephemeral_heap_segment, WKS::gc_heap::ephemeral_heap_segment)
-DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE /*PTR_CFinalize*/, WKS__gc_heap__finalize_queue, WKS::gc_heap::finalize_queue)
-
-// Can not use MULTIPLE_HEAPS here because desktop build contains it is not defined for workstation GC
-// but we include workstation GC in mscorwks.dll.
-#ifdef FEATURE_SVR_GC
-DEFINE_DACVAR_SVR(ULONG, int, SVR__gc_heap__n_heaps, SVR::gc_heap::n_heaps)
-DEFINE_DACVAR_SVR(ULONG, UNKNOWN_POINTER_TYPE /*(PTR_gc_heap*)*/, SVR__gc_heap__g_heaps, SVR::gc_heap::g_heaps)
-#endif // FEATURE_SVR_GC
-DEFINE_DACVAR(ULONG, oom_history, WKS__gc_heap__oom_info, WKS::gc_heap::oom_info)
+DEFINE_DACVAR(ULONG, DWORD, dac__g_heap_type, g_heap_type)
+DEFINE_DACVAR(ULONG, PTR_GcDacVars, dac__g_gcDacGlobals, g_gcDacGlobals)
DEFINE_DACVAR(ULONG, PTR_SystemDomain, SystemDomain__m_pSystemDomain, SystemDomain::m_pSystemDomain)
DEFINE_DACVAR(ULONG, ArrayListStatic, SystemDomain__m_appDomainIndexList, SystemDomain::m_appDomainIndexList)
@@ -151,27 +134,18 @@ DEFINE_DACVAR(ULONG, PTR_SharedDomain, SharedDomain__m_pSharedDomain, SharedDoma
DEFINE_DACVAR(ULONG, DWORD, CExecutionEngine__TlsIndex, CExecutionEngine::TlsIndex)
-DEFINE_DACVAR(ULONG, LONG, GCScan__m_GcStructuresInvalidCnt, GCScan::m_GcStructuresInvalidCnt)
-
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
+#if defined(FEATURE_WINDOWSPHONE)
DEFINE_DACVAR(ULONG, int, CCLRErrorReportingManager__g_ECustomDumpFlavor, CCLRErrorReportingManager::g_ECustomDumpFlavor)
#endif
DEFINE_DACVAR(ULONG, PTR_SString, SString__s_Empty, SString::s_Empty)
#ifdef FEATURE_APPX
-#if defined(FEATURE_CORECLR)
DEFINE_DACVAR(ULONG, BOOL, dac__g_fAppX, ::g_fAppX)
-#else
-DEFINE_DACVAR(ULONG, PTR_AppXRTInfo, dac__g_pAppXRTInfo, ::g_pAppXRTInfo)
-#endif
#endif // FEATURE_APPX
DEFINE_DACVAR(ULONG, BOOL, SString__s_IsANSIMultibyte, SString::s_IsANSIMultibyte)
-#ifdef FEATURE_REMOTING
-DEFINE_DACVAR_NO_DUMP(ULONG, MethodTable, CTPMethodTable__s_pThunkTable, CTPMethodTable::s_pThunkTable)
-#endif // FEATURE_REMOTING
DEFINE_DACVAR(ULONG, INT32, ArrayBase__s_arrayBoundsZero, ArrayBase::s_arrayBoundsZero)
@@ -194,21 +168,12 @@ DEFINE_DACVAR(ULONG, MscorlibBinder, dac__g_Mscorlib, ::g_Mscorlib)
DEFINE_DACVAR(ULONG, ProfControlBlock, dac__g_profControlBlock, ::g_profControlBlock)
#endif // defined(PROFILING_SUPPORTED) || defined(PROFILING_SUPPORTED_DATA)
-DEFINE_DACVAR_NO_DUMP(ULONG, SIZE_T, dac__generation_table, WKS::generation_table)
DEFINE_DACVAR(ULONG, PTR_DWORD, dac__g_card_table, ::g_card_table)
DEFINE_DACVAR(ULONG, PTR_BYTE, dac__g_lowest_address, ::g_lowest_address)
DEFINE_DACVAR(ULONG, PTR_BYTE, dac__g_highest_address, ::g_highest_address)
DEFINE_DACVAR(ULONG, IGCHeap, dac__g_pGCHeap, ::g_pGCHeap)
-#ifdef GC_CONFIG_DRIVEN
-DEFINE_DACVAR_NO_DUMP(ULONG, SIZE_T, dac__interesting_data_per_heap, WKS::interesting_data_per_heap)
-DEFINE_DACVAR_NO_DUMP(ULONG, SIZE_T, dac__compact_reasons_per_heap, WKS::compact_reasons_per_heap)
-DEFINE_DACVAR_NO_DUMP(ULONG, SIZE_T, dac__expand_mechanisms_per_heap, WKS::expand_mechanisms_per_heap)
-DEFINE_DACVAR_NO_DUMP(ULONG, SIZE_T, dac__interesting_mechanism_bits_per_heap, WKS::interesting_mechanism_bits_per_heap)
-DEFINE_DACVAR_NO_DUMP(ULONG, SIZE_T, dac__gc_global_mechanisms, ::gc_global_mechanisms)
-#endif //GC_CONFIG_DRIVEN
-
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pThinLockThreadIdDispenser, ::g_pThinLockThreadIdDispenser)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pModuleIndexDispenser, ::g_pModuleIndexDispenser)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pObjectClass, ::g_pObjectClass)
@@ -218,9 +183,7 @@ DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pStringClass, ::g_pStringClass
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pArrayClass, ::g_pArrayClass)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pSZArrayHelperClass, ::g_pSZArrayHelperClass)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pNullableClass, ::g_pNullableClass)
-#ifdef FEATURE_SPAN_OF_T
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pByReferenceClass, ::g_pByReferenceClass)
-#endif
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pExceptionClass, ::g_pExceptionClass)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pThreadAbortExceptionClass, ::g_pThreadAbortExceptionClass)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pOutOfMemoryExceptionClass, ::g_pOutOfMemoryExceptionClass)
@@ -233,12 +196,6 @@ DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pOverlappedDataClass, ::g_pOve
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pValueTypeClass, ::g_pValueTypeClass)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pEnumClass, ::g_pEnumClass)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pThreadClass, ::g_pThreadClass)
-#ifdef FEATURE_CER
-DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pCriticalFinalizerObjectClass, ::g_pCriticalFinalizerObjectClass)
-#endif
-#ifndef FEATURE_CORECLR
-DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pAsyncFileStream_AsyncResultClass, ::g_pAsyncFileStream_AsyncResultClass)
-#endif // !FEATURE_CORECLR
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pPredefinedArrayTypes, ::g_pPredefinedArrayTypes)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_TypedReferenceMT, ::g_TypedReferenceMT)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pByteArrayMT, ::g_pByteArrayMT)
@@ -252,9 +209,6 @@ DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pBaseRuntimeClass, ::g_pBaseRu
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pICastableInterface, ::g_pICastableInterface)
#endif // FEATURE_ICASTABLE
-#ifdef FEATURE_CER
-DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pPrepareConstrainedRegionsMethod, ::g_pPrepareConstrainedRegionsMethod)
-#endif
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pExecuteBackoutCodeHelperMethod, ::g_pExecuteBackoutCodeHelperMethod)
DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pObjectCtorMD, ::g_pObjectCtorMD)
@@ -304,24 +258,10 @@ DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE, dac__g_pIPCManagerInterface, ::g_pIPC
DEFINE_DACVAR_NO_DUMP(ULONG, SIZE_T, dac__g_FCDynamicallyAssignedImplementations, ::g_FCDynamicallyAssignedImplementations)
-DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE /*BYTE**/, WKS__gc_heap__internal_root_array, WKS::gc_heap::internal_root_array)
-DEFINE_DACVAR(ULONG, size_t, WKS__gc_heap__internal_root_array_index, WKS::gc_heap::internal_root_array_index)
-DEFINE_DACVAR(ULONG, ULONG, WKS__gc_heap__heap_analyze_success, WKS::gc_heap::heap_analyze_success)
-
-DEFINE_DACVAR(ULONG, SIZE_T, WKS__gc_heap__mark_array, WKS::gc_heap::mark_array)
-DEFINE_DACVAR(ULONG, SIZE_T, WKS__gc_heap__current_c_gc_state, WKS::gc_heap::current_c_gc_state)
-DEFINE_DACVAR(ULONG, PTR_BYTE, WKS__gc_heap__next_sweep_obj, WKS::gc_heap::next_sweep_obj)
-DEFINE_DACVAR(ULONG, UNKNOWN_POINTER_TYPE /* PTR_heap_segment */, WKS__gc_heap__saved_sweep_ephemeral_seg, WKS::gc_heap::saved_sweep_ephemeral_seg)
-DEFINE_DACVAR(ULONG, PTR_BYTE, WKS__gc_heap__saved_sweep_ephemeral_start, WKS::gc_heap::saved_sweep_ephemeral_start)
-DEFINE_DACVAR(ULONG, PTR_BYTE, WKS__gc_heap__background_saved_lowest_address, WKS::gc_heap::background_saved_lowest_address)
-DEFINE_DACVAR(ULONG, PTR_BYTE, WKS__gc_heap__background_saved_highest_address, WKS::gc_heap::background_saved_highest_address)
-
-#ifdef FEATURE_CORECLR
#ifndef FEATURE_PAL
DEFINE_DACVAR(ULONG, HANDLE, dac__g_hContinueStartupEvent, ::g_hContinueStartupEvent)
#endif // !FEATURE_PAL
DEFINE_DACVAR(ULONG, DWORD, CorHost2__m_dwStartupFlags, CorHost2::m_dwStartupFlags)
-#endif // FEATURE_CORECLR
DEFINE_DACVAR(ULONG, HRESULT, dac__g_hrFatalError, ::g_hrFatalError)
@@ -329,13 +269,7 @@ DEFINE_DACVAR(ULONG, HRESULT, dac__g_hrFatalError, ::g_hrFatalError)
DEFINE_DACVAR(ULONG, DWORD, PEFile__s_NGENDebugFlags, PEFile::s_NGENDebugFlags)
#endif //defined(DEBUGGING_SUPPORTED) && defined (FEATURE_PREJIT)
-#ifndef FEATURE_CORECLR
-DEFINE_DACVAR(ULONG, DWORD, AssemblyUsageLogManager__s_UsageLogFlags, AssemblyUsageLogManager::s_UsageLogFlags)
-#endif // FEATURE_CORECLR
-#if defined(FEATURE_APPX_BINDER)
-DEFINE_DACVAR(ULONG, PTR_CLRPrivBinderAppX, CLRPrivBinderAppX__s_pSingleton, CLRPrivBinderAppX::s_pSingleton)
-#endif //defined(FEATURE_APPX)
#ifdef FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
DEFINE_DACVAR(ULONG, DWORD, dac__g_MiniMetaDataBuffMaxSize, ::g_MiniMetaDataBuffMaxSize)
diff --git a/src/inc/eetwain.h b/src/inc/eetwain.h
index 54e9a34464..497e0b0e6b 100644
--- a/src/inc/eetwain.h
+++ b/src/inc/eetwain.h
@@ -652,7 +652,10 @@ HRESULT FixContextForEnC(PCONTEXT pCtx,
#ifdef WIN64EXCEPTIONS
static void EnsureCallerContextIsValid( PREGDISPLAY pRD, StackwalkCacheEntry* pCacheEntry, EECodeInfo * pCodeInfo = NULL );
static size_t GetCallerSp( PREGDISPLAY pRD );
-#endif
+#ifdef _TARGET_X86_
+ static size_t GetResumeSp( PCONTEXT pContext );
+#endif // _TARGET_X86_
+#endif // WIN64EXCEPTIONS
#ifdef DACCESS_COMPILE
virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
diff --git a/src/inc/eventtracebase.h b/src/inc/eventtracebase.h
index f773a7c375..bd5ad1a2d0 100644
--- a/src/inc/eventtracebase.h
+++ b/src/inc/eventtracebase.h
@@ -154,11 +154,6 @@ public:
class Object;
#if !defined(FEATURE_PAL)
-/******************************/
-/* CLR ETW supported versions */
-/******************************/
-#define ETW_SUPPORTED_MAJORVER 5 // ETW is supported on win2k and above
-#define ETW_ENABLED_MAJORVER 6 // OS versions >= to this we enable ETW registration by default, since on XP and Windows 2003, registration is too slow.
/***************************************/
/* Tracing levels supported by CLR ETW */
@@ -201,11 +196,6 @@ struct ProfilingScanContext;
#include <wmistr.h>
#include <evntrace.h>
#include <evntprov.h>
-#if !defined(DONOT_DEFINE_ETW_CALLBACK) && !defined(DACCESS_COMPILE)
-#define GetVersionEx(Version) (GetOSVersion((LPOSVERSIONINFOW)Version))
-#else
-#define GetVersionEx(Version) (WszGetVersionEx((LPOSVERSIONINFOW)Version))
-#endif // !DONOT_DEFINE_ETW_CALLBACK && !DACCESS_COMPILE
#endif //!FEATURE_REDHAWK
#endif //!defined(FEATURE_PAL)
diff --git a/src/inc/formattype.cpp b/src/inc/formattype.cpp
index 76aa506bf1..8a7965cb4f 100644
--- a/src/inc/formattype.cpp
+++ b/src/inc/formattype.cpp
@@ -412,7 +412,7 @@ const PCCOR_SIGNATURE PrettyPrintSignature(
/******************************************************************************/
-// pretty prints 'type' or its 'typedef' to the buffer 'out' returns a poitner to the next type,
+// pretty prints 'type' or its 'typedef' to the buffer 'out' returns a pointer to the next type,
// or 0 on a format failure; outside ILDASM -- simple wrapper for PrettyPrintType
PCCOR_SIGNATURE PrettyPrintTypeOrDef(
diff --git a/src/inc/fusion.idl b/src/inc/fusion.idl
index e64909e845..4056d168ba 100644
--- a/src/inc/fusion.idl
+++ b/src/inc/fusion.idl
@@ -31,27 +31,12 @@ cpp_quote("#ifdef _MSC_VER")
cpp_quote("#pragma once")
cpp_quote("#endif")
-#if !defined(FEATURE_FUSION) && !defined(FEATURE_VERSIONING)
-cpp_quote("#if defined(_CLR_BLD) && !defined(FEATURE_FUSION)")
-cpp_quote("#error FEATURE_FUSION is not enabled, please do not include fusion.h")
-cpp_quote("#endif")
-#endif // !defined(FEATURE_FUSION) && !defined(FEATURE_VERSIONING)
interface IAssemblyCache;
interface IAssemblyCacheItem;
interface IAssemblyName;
interface IAssemblyEnum;
-#ifdef FEATURE_FUSION
-typedef enum
-{
- ASM_CACHE_ZAP = 0x1,
- ASM_CACHE_GAC = 0x2,
- ASM_CACHE_DOWNLOAD = 0x4,
- ASM_CACHE_ROOT = 0x8, //This is only meaningful on GetCachePath.
- ASM_CACHE_ROOT_EX = 0x80 // Only valid when used with GetCachePath.
-} ASM_CACHE_FLAGS;
-#endif
cpp_quote("#ifndef PEKIND_ENUM_DEFINED")
cpp_quote("#define PEKIND_ENUM_DEFINED")
@@ -76,160 +61,6 @@ typedef enum _tagAssemblyContentType
AssemblyContentType_Invalid = 0xffffffff
} AssemblyContentType;
-#ifdef FEATURE_FUSION
-///////////////////////////////////////////////////////////////////////////////
-//
-// IAssemblyCache
-//
-///////////////////////////////////////////////////////////////////////////////
-
-cpp_quote("// {E707DCDE-D1CD-11D2-BAB9-00C04F8ECEAE}")
-cpp_quote("EXTERN_GUID(IID_IAssemblyCache, 0xE707DCDE, 0xD1CD, 0x11D2, 0xBA, 0xB9, 0x00, 0xC0, 0x4F, 0x8E, 0xCE, 0xAE);")
-
-[
- local,
- object,
- uuid(e707dcde-d1cd-11d2-bab9-00c04f8eceae),
- pointer_default(unique)
-]
-interface IAssemblyCache : IUnknown
-{
- cpp_quote("// {8cedc215-ac4b-488b-93c0-a50a49cb2fb8}")
- cpp_quote("EXTERN_GUID(FUSION_REFCOUNT_UNINSTALL_SUBKEY_GUID, 0x8cedc215, 0xac4b, 0x488b, 0x93, 0xc0, 0xa5, 0x0a, 0x49, 0xcb, 0x2f, 0xb8);")
- cpp_quote("")
- cpp_quote("// {b02f9d65-fb77-4f7a-afa5-b391309f11c9}")
- cpp_quote("EXTERN_GUID(FUSION_REFCOUNT_FILEPATH_GUID, 0xb02f9d65, 0xfb77, 0x4f7a, 0xaf, 0xa5, 0xb3, 0x91, 0x30, 0x9f, 0x11, 0xc9);")
- cpp_quote("")
- cpp_quote("// {2ec93463-b0c3-45e1-8364-327e96aea856}")
- cpp_quote("EXTERN_GUID(FUSION_REFCOUNT_OPAQUE_STRING_GUID, 0x2ec93463, 0xb0c3, 0x45e1, 0x83, 0x64, 0x32, 0x7e, 0x96, 0xae, 0xa8, 0x56);")
-
- cpp_quote(" // {25df0fc1-7f97-4070-add7-4b13bbfd7cb8} // this GUID cannot be used for installing into GAC.")
- cpp_quote("EXTERN_GUID(FUSION_REFCOUNT_MSI_GUID, 0x25df0fc1, 0x7f97, 0x4070, 0xad, 0xd7, 0x4b, 0x13, 0xbb, 0xfd, 0x7c, 0xb8); ")
-
- cpp_quote(" // {d16d444c-56d8-11d5-882d-0080c847b195}")
- cpp_quote("EXTERN_GUID(FUSION_REFCOUNT_OSINSTALL_GUID, 0xd16d444c, 0x56d8, 0x11d5, 0x88, 0x2d, 0x00, 0x80, 0xc8, 0x47, 0xb1, 0x95); ")
-
- typedef struct _FUSION_INSTALL_REFERENCE_
- {
- DWORD cbSize;
- DWORD dwFlags;
- GUID guidScheme; // contains one of the pre-defined guids.
- LPCWSTR szIdentifier; // unique identifier for app installing this assembly.
- LPCWSTR szNonCannonicalData; // data is description; relevent to the guid above
- } FUSION_INSTALL_REFERENCE, *LPFUSION_INSTALL_REFERENCE;
-
- typedef const FUSION_INSTALL_REFERENCE *LPCFUSION_INSTALL_REFERENCE;
-
-
- typedef struct _ASSEMBLY_INFO
- {
- ULONG cbAssemblyInfo; // size of this structure for future expansion
- DWORD dwAssemblyFlags;
- ULARGE_INTEGER uliAssemblySizeInKB;
- LPWSTR pszCurrentAssemblyPathBuf;
- ULONG cchBuf; // size of path buf.
- } ASSEMBLY_INFO;
-
- cpp_quote("#define IASSEMBLYCACHE_INSTALL_FLAG_REFRESH (0x00000001)")
- cpp_quote("#define IASSEMBLYCACHE_INSTALL_FLAG_FORCE_REFRESH (0x00000002)")
-
- cpp_quote("#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_UNINSTALLED (1)")
- cpp_quote("#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_STILL_IN_USE (2)")
- cpp_quote("#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_ALREADY_UNINSTALLED (3)")
- cpp_quote("#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_DELETE_PENDING (4)")
- cpp_quote("#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_HAS_INSTALL_REFERENCES (5)")
- cpp_quote("#define IASSEMBLYCACHE_UNINSTALL_DISPOSITION_REFERENCE_NOT_FOUND (6)")
-
- cpp_quote("#define QUERYASMINFO_FLAG_VALIDATE (0x00000001)")
- cpp_quote("#define QUERYASMINFO_FLAG_GETSIZE (0x00000002)")
-
- // these flags are for dwAssemblyFlags field in struct _ASSEMBLY_INFO
- cpp_quote("#define ASSEMBLYINFO_FLAG_INSTALLED (0x00000001)")
- cpp_quote("#define ASSEMBLYINFO_FLAG_PAYLOADRESIDENT (0x00000002)")
-
- HRESULT UninstallAssembly(
- [in] DWORD dwFlags,
- [in] LPCWSTR pszAssemblyName,
- [in] LPCFUSION_INSTALL_REFERENCE pRefData,
- [out, optional] ULONG *pulDisposition
- );
-
- HRESULT QueryAssemblyInfo(
- [in] DWORD dwFlags,
- [in] LPCWSTR pszAssemblyName,
- [in, out] ASSEMBLY_INFO *pAsmInfo
- );
-
- HRESULT CreateAssemblyCacheItem(
- [in] DWORD dwFlags,
- [in] PVOID pvReserved,
- [out] IAssemblyCacheItem **ppAsmItem,
- [in, optional] LPCWSTR pszAssemblyName // uncanonicalized, comma separted name=value pairs.
- );
-
- HRESULT CreateAssemblyScavenger
- (
- [out] IUnknown **ppUnkReserved
- );
-
- HRESULT InstallAssembly( // if you use this, fusion will do the streaming & commit.
- [in] DWORD dwFlags,
- [in] LPCWSTR pszManifestFilePath,
- [in] LPCFUSION_INSTALL_REFERENCE pRefData
- );
-
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IAssemblyCacheItem
-//
-///////////////////////////////////////////////////////////////////////////////
-
-cpp_quote("// {9e3aaeb4-d1cd-11d2-bab9-00c04f8eceae}")
-cpp_quote("EXTERN_GUID(IID_IAssemblyCacheItem, 0x9e3aaeb4,0xd1cd,0x11d2,0xba,0xb9,0x00,0xc0,0x4f,0x8e,0xce,0xae);")
-
-[
- local,
- object,
- uuid(9e3aaeb4-d1cd-11d2-bab9-00c04f8eceae),
- pointer_default(unique)
-]
-interface IAssemblyCacheItem : IUnknown
-{
- cpp_quote("#define STREAM_FORMAT_COMPLIB_MODULE 0")
- cpp_quote("#define STREAM_FORMAT_COMPLIB_MANIFEST 1")
- cpp_quote("#define STREAM_FORMAT_WIN32_MODULE 2")
- cpp_quote("#define STREAM_FORMAT_WIN32_MANIFEST 4")
-
- cpp_quote("#define IASSEMBLYCACHEITEM_COMMIT_FLAG_REFRESH (0x00000001)")
- cpp_quote("#define IASSEMBLYCACHEITEM_COMMIT_FLAG_FORCE_REFRESH (0x00000002)")
-
- cpp_quote("#define IASSEMBLYCACHEITEM_COMMIT_DISPOSITION_INSTALLED (1)") // first time install
- cpp_quote("#define IASSEMBLYCACHEITEM_COMMIT_DISPOSITION_REFRESHED (2)") // overwrite, if existing
- cpp_quote("#define IASSEMBLYCACHEITEM_COMMIT_DISPOSITION_ALREADY_INSTALLED (3)") // existing,
-
-
- HRESULT CreateStream(
- [in] DWORD dwFlags, // For general API flags
- [in] LPCWSTR pszStreamName, // Name of the stream to be passed in
- [in] DWORD dwFormat, // format of the file to be streamed in.
- [in] DWORD dwFormatFlags, // format-specific flags
- [out] IStream **ppIStream,
- [in, optional] ULARGE_INTEGER *puliMaxSize // Max size of the Stream.
- );
-
- HRESULT Commit
- (
- [in] DWORD dwFlags, // For general API flags like IASSEMBLYCACHEITEM _COMMIT_FLAG_REFRESH
- [out, optional] ULONG *pulDisposition
- );
-
- HRESULT AbortItem(); // If you have created IAssemblyCacheItem and don't plan to use it, its good idea to call AbortItem before releasing it.
-
-}
-#endif // FEATURE_FUSION
///////////////////////////////////////////////////////////////////////////////
//
@@ -406,125 +237,6 @@ interface IAssemblyName: IUnknown
}
-#ifdef FEATURE_FUSION
-///////////////////////////////////////////////////////////////////////////////
-//
-// IAssemblyEnum
-//
-///////////////////////////////////////////////////////////////////////////////
-cpp_quote("// {21B8916C-F28E-11D2-A473-00C04F8EF448}")
-cpp_quote("EXTERN_GUID(IID_IAssemblyEnum, 0x21B8916C,0xF28E,0x11D2,0xA4,0x73,0x00,0xC0,0x4F,0x8E,0xF4,0x48);")
-
-[
- local,
- object,
- uuid(21b8916c-f28e-11d2-a473-00c04f8ef448),
- pointer_default(unique)
-]
-interface IAssemblyEnum : IUnknown
-{
-
- HRESULT GetNextAssembly
- (
- [in] LPVOID pvReserved,
- [out] IAssemblyName **ppName,
- [in] DWORD dwFlags
- );
-
- HRESULT Reset(void);
-
- HRESULT Clone
- (
- [out] IAssemblyEnum **ppEnum
- );
-
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IInstallReferenceItem
-//
-///////////////////////////////////////////////////////////////////////////////
-
-cpp_quote("// {582dac66-e678-449f-aba6-6faaec8a9394}")
-cpp_quote("EXTERN_GUID(IID_IInstallReferenceItem, 0x582dac66,0xe678,0x449f,0xab,0xa6,0x6f,0xaa,0xec,0x8a,0x93,0x94);")
-
-[
- local,
- object,
- uuid(582dac66-e678-449f-aba6-6faaec8a9394),
- pointer_default(unique)
-]
-interface IInstallReferenceItem : IUnknown
-{
- HRESULT GetReference
- (
- [out] LPFUSION_INSTALL_REFERENCE *ppRefData,
- [in] DWORD dwFlags,
- [in] LPVOID pvReserved
- );
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IInstallReferenceEnum
-//
-///////////////////////////////////////////////////////////////////////////////
-
-cpp_quote("// {56b1a988-7c0c-4aa2-8639-c3eb5a90226f}")
-cpp_quote("EXTERN_GUID(IID_IInstallReferenceEnum, 0x56b1a988,0x7c0c,0x4aa2,0x86,0x39,0xc3,0xeb,0x5a,0x90,0x22,0x6f);")
-
-[
- local,
- object,
- uuid(56b1a988-7c0c-4aa2-8639-c3eb5a90226f),
- pointer_default(unique)
-]
-interface IInstallReferenceEnum : IUnknown
-{
- HRESULT GetNextInstallReferenceItem
- (
- [out] IInstallReferenceItem **ppRefItem,
- [in] DWORD dwFlags,
- [in] LPVOID pvReserved
- );
-}
-
-typedef enum _tagAssemblyComparisonResult
-{
- ACR_Unknown, // Unknown
- ACR_EquivalentFullMatch, // all fields match
- ACR_EquivalentWeakNamed, // match based on weak-name, version numbers ignored
- ACR_EquivalentFXUnified, // match based on FX-unification of version numbers
- ACR_EquivalentUnified, // match based on legacy-unification of version numbers
- ACR_NonEquivalentVersion, // all fields match except version field
- ACR_NonEquivalent, // no match
-
- ACR_EquivalentPartialMatch,
- ACR_EquivalentPartialWeakNamed,
- ACR_EquivalentPartialUnified,
- ACR_EquivalentPartialFXUnified,
- ACR_NonEquivalentPartialVersion
-} AssemblyComparisonResult;
-
-
-#pragma midl_echo("STDAPI CreateAssemblyConfigCookie(LPCWSTR wzConfigFilePath, struct AssemblyConfig **ppAssemblyConfigOut);")
-#pragma midl_echo("STDAPI DestroyAssemblyConfigCookie(struct AssemblyConfig *pAssemblyConfig);")
-
-#pragma midl_echo("STDAPI CompareAssemblyIdentity(LPCWSTR pwzAssemblyIdentity1, BOOL fUnified1, LPCWSTR pwzAssemblyIdentity2, BOOL fUnified2, BOOL *pfEquivalent, AssemblyComparisonResult *pResult); ")
-#pragma midl_echo("STDAPI CompareAssemblyIdentityWithConfig(LPCWSTR pwzAssemblyIdentity1, BOOL fUnified1, LPCWSTR pwzAssemblyIdentity2, BOOL fUnified2, struct AssemblyConfig *pAssemblyConfig, BOOL *pfEquivalent, AssemblyComparisonResult *pResult); ")
-#pragma midl_echo("STDAPI CreateInstallReferenceEnum(IInstallReferenceEnum **ppRefEnum, IAssemblyName *pName, DWORD dwFlags, LPVOID pvReserved); ")
-#pragma midl_echo("STDAPI CreateAssemblyEnum(IAssemblyEnum **pEnum, IUnknown *pUnkReserved, IAssemblyName *pName, DWORD dwFlags, LPVOID pvReserved); ")
-#endif // FEATURE_FUSION
#pragma midl_echo("STDAPI CreateAssemblyNameObject(LPASSEMBLYNAME *ppAssemblyNameObj, LPCWSTR szAssemblyName, DWORD dwFlags, LPVOID pvReserved); ")
-#ifdef FEATURE_FUSION
-#pragma midl_echo("STDAPI CreateAssemblyCache(IAssemblyCache **ppAsmCache, DWORD dwReserved); ")
-#pragma midl_echo("STDAPI GetCachePath(ASM_CACHE_FLAGS dwCacheFlags, _Out_writes_to_(*pcchPath,*pcchPath) LPWSTR pwzCachePath, PDWORD pcchPath); ")
-#pragma midl_echo("STDAPI GetAssemblyIdentityFromFile(LPCWSTR pwzFilePAth, REFIID riid, IUnknown **ppIdentity); ")
-#pragma midl_echo("STDAPI ClearDownloadCache();")
-#pragma midl_echo("typedef unsigned long MSIHANDLE;")
-#pragma midl_echo("STDAPI SetMSIHandleForLogging(MSIHANDLE hMSIHandle);")
-#endif // FEATURE_FUSION
diff --git a/src/inc/fusionbind.h b/src/inc/fusionbind.h
deleted file mode 100644
index 8628d3f9ce..0000000000
--- a/src/inc/fusionbind.h
+++ /dev/null
@@ -1,316 +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.
-
-
-
-/*============================================================
-**
-** Header: FusionBind.hpp
-**
-** Purpose: Implements FusionBind (loader domain) architecture
-**
-**
-===========================================================*/
-#ifndef _FUSIONBIND_H
-#define _FUSIONBIND_H
-
-#ifndef FEATURE_FUSION
-#error FEATURE_FUSION is not enabled, please do not include fusionbind.h
-#endif
-
-#include <fusion.h>
-#include <fusionpriv.h>
-#include "metadata.h"
-#include "fusionsink.h"
-#include "utilcode.h"
-#include "loaderheap.h"
-#include "fusionsetup.h"
-#include "sstring.h"
-#include "ex.h"
-#ifdef PAL_STDCPP_COMPAT
-#include <type_traits>
-#else
-#include "clr_std/type_traits"
-#endif
-
-#include "binderngen.h"
-#include "clrprivbinding.h"
-
-class FusionBind
-{
-public:
-
- //****************************************************************************************
- //
-
- static HRESULT GetVersion(__out_ecount(*pdwVersion) LPWSTR pVersion, __inout DWORD* pdwVersion);
-
-
- //****************************************************************************************
- //
- // Creates a fusion context for the application domain. All ApplicationContext properties
- // must be set in the AppDomain store prior to this call. Any changes or additions to the
- // AppDomain store are ignored.
- static HRESULT CreateFusionContext(LPCWSTR pzName, IApplicationContext** ppFusionContext);
-
-
- //****************************************************************************************
- //
- // Loads an environmental value into the fusion context
- static HRESULT AddEnvironmentProperty(__in LPCWSTR variable,
- __in LPCWSTR pProperty,
- IApplicationContext* pFusionContext);
-
- //****************************************************************************************
- //
- static HRESULT SetupFusionContext(LPCWSTR szAppBase,
- LPCWSTR szPrivateBin,
- IApplicationContext** ppFusionContext);
-
- // Starts remote load of an assembly. The thread is parked on
- // an event waiting for fusion to report success or failure.
- static HRESULT RemoteLoad(IApplicationContext * pFusionContext,
- FusionSink* pSink,
- IAssemblyName *pName,
- IAssembly *pParentAssembly,
- LPCWSTR pCodeBase,
- IAssembly** ppIAssembly,
- IHostAssembly** ppIHostAssembly,
- IBindResult** ppNativeFusionAssembly,
- BOOL fForIntrospectionOnly,
- BOOL fSuppressSecurityChecks);
-
- static HRESULT RemoteLoadModule(IApplicationContext * pFusionContext,
- IAssemblyModuleImport* pModule,
- FusionSink *pSink,
- IAssemblyModuleImport** pResult);
-
- static BOOL VerifyBindingStringW(LPCWSTR pwStr) {
- WRAPPER_NO_CONTRACT;
- if (wcschr(pwStr, '\\') ||
- wcschr(pwStr, '/') ||
- wcschr(pwStr, ':'))
- return FALSE;
-
- return TRUE;
- }
-
- static HRESULT VerifyBindingString(LPCSTR pName) {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END;
-
- DWORD dwStrLen = WszMultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, pName, -1, NULL, NULL);
- CQuickBytes qb;
- LPWSTR pwStr = (LPWSTR) qb.AllocNoThrow(dwStrLen*sizeof(WCHAR));
- if (!pwStr)
- return E_OUTOFMEMORY;
-
- if(!WszMultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, pName, -1, pwStr, dwStrLen))
- return HRESULT_FROM_GetLastError();
-
- if (VerifyBindingStringW(pwStr))
- return S_OK;
- else
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
-
- static void GetAssemblyManifestModulePath(IAssembly *pFusionAssembly, SString &result)
- {
- CONTRACTL
- {
- THROWS;
- INJECT_FAULT(ThrowOutOfMemory());
- }
- CONTRACTL_END;
-
- DWORD dwSize = 0;
- LPWSTR buffer = NULL;
- COUNT_T allocation = result.GetUnicodeAllocation();
- if (allocation > 0) {
- // pass in the buffer if we got one
- dwSize = allocation + 1;
- buffer = result.OpenUnicodeBuffer(allocation);
- }
- HRESULT hr = pFusionAssembly->GetManifestModulePath(buffer, &dwSize);
- if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- if (buffer != NULL)
- result.CloseBuffer(0);
- buffer = result.OpenUnicodeBuffer(dwSize-1);
- hr = pFusionAssembly->GetManifestModulePath(buffer, &dwSize);
- }
- if (buffer != NULL)
- result.CloseBuffer((SUCCEEDED(hr) && dwSize >= 1) ? (dwSize-1) : 0);
- IfFailThrow(hr);
- }
-
- static SString& GetAssemblyNameDisplayName(
- IAssemblyName *pName,
- SString &result,
- DWORD flags = 0 /* default */)
- {
- CONTRACTL
- {
- GC_NOTRIGGER;
- THROWS;
- INJECT_FAULT(ThrowOutOfMemory());
- }
- CONTRACTL_END;
-
- DWORD dwSize = 0;
- LPWSTR buffer = NULL;
- COUNT_T allocation = result.GetUnicodeAllocation();
- if (allocation > 0)
- {
- // pass in the buffer if we got one
- dwSize = allocation + 1;
- buffer = result.OpenUnicodeBuffer(allocation);
- }
-
- HRESULT hr = pName->GetDisplayName(buffer, &dwSize, flags);
- if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- if (buffer != NULL)
- result.CloseBuffer(0);
- buffer = result.OpenUnicodeBuffer(dwSize-1);
- hr = pName->GetDisplayName(buffer, &dwSize, flags);
- }
-
- if (buffer != NULL)
- {
- result.CloseBuffer((SUCCEEDED(hr) && dwSize >= 1) ? (dwSize-1) : 0);
- }
-
- IfFailThrow(hr);
- return result;
- }
-
- static BOOL GetAssemblyNameStringProperty(IAssemblyName *pName, DWORD property, SString &result)
- {
- CONTRACTL
- {
- THROWS;
- INJECT_FAULT(ThrowOutOfMemory());
- }
- CONTRACTL_END;
-
- DWORD dwSize = 0;
- LPWSTR buffer = NULL;
- COUNT_T allocation = result.GetUnicodeAllocation();
- if (allocation > 0) {
- // pass in the buffer if we got one
- dwSize = (allocation + 1) * sizeof(WCHAR);
- buffer = result.OpenUnicodeBuffer(allocation);
- }
- HRESULT hr = pName->GetProperty(property, (LPVOID)buffer, &dwSize);
- if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- if (buffer != NULL)
- result.CloseBuffer(0);
- buffer = result.OpenUnicodeBuffer(dwSize/sizeof(WCHAR) - 1);
- hr = pName->GetProperty(property, (LPVOID)buffer, &dwSize);
- }
- if (buffer != NULL)
- result.CloseBuffer((SUCCEEDED(hr) && dwSize >= sizeof(WCHAR)) ? (dwSize/sizeof(WCHAR)-1) : 0);
- if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
- {
- return FALSE;
- }
- IfFailThrow(hr);
-
- return TRUE;
- }
-
- static BOOL GetApplicationContextStringProperty(IApplicationContext *pContext,
- LPCWSTR property, SString &result)
- {
- CONTRACTL
- {
- THROWS;
- INJECT_FAULT(ThrowOutOfMemory());
- }
- CONTRACTL_END;
-
- DWORD dwSize = 0;
- LPWSTR buffer = NULL;
- COUNT_T allocation = result.GetUnicodeAllocation();
- if (allocation > 0) {
- // pass in the buffer if we got one
- dwSize = (allocation + 1) * sizeof(WCHAR);
- buffer = result.OpenUnicodeBuffer(allocation);
- }
- HRESULT hr = pContext->Get(property, (LPVOID)buffer, &dwSize, 0);
- if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- if (buffer != NULL)
- result.CloseBuffer(0);
- buffer = result.OpenUnicodeBuffer(dwSize/sizeof(WCHAR) - 1);
- hr = pContext->Get(property, (LPVOID)buffer, &dwSize, 0);
- }
- if (buffer != NULL)
- result.CloseBuffer((SUCCEEDED(hr) && dwSize >= sizeof(WCHAR)) ? (dwSize/sizeof(WCHAR)-1) : 0);
- if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
- {
- return FALSE;
- }
- IfFailThrow(hr);
-
- return TRUE;
- }
-
- static BOOL GetApplicationContextDWORDProperty(IApplicationContext *pContext,
- LPCWSTR property, DWORD *result)
- {
- CONTRACTL
- {
- THROWS;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END;
-
- DWORD dwSize = sizeof(DWORD);
- HRESULT hr = pContext->Get(property, result, &dwSize, 0);
- if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
- return FALSE;
-
- IfFailThrow(hr);
-
- return TRUE;
- }
-
- static void SetApplicationContextStringProperty(IApplicationContext *pContext, LPCWSTR property,
- SString &value)
- {
- CONTRACTL
- {
- THROWS;
- INJECT_FAULT(ThrowOutOfMemory());
- }
- CONTRACTL_END;
-
- IfFailThrow(pContext->Set(property, (void *) value.GetUnicode(),
- (value.GetCount()+1)*sizeof(WCHAR), 0));
- }
-
- static void SetApplicationContextDWORDProperty(IApplicationContext *pContext, LPCWSTR property,
- DWORD value)
- {
- CONTRACTL
- {
- THROWS;
- INJECT_FAULT(ThrowOutOfMemory());
- }
- CONTRACTL_END;
-
- IfFailThrow(pContext->Set(property, &value, sizeof(value), 0));
- }
-};
-
-#endif
-
diff --git a/src/inc/fusionpriv.idl b/src/inc/fusionpriv.idl
deleted file mode 100644
index f9aaefcd9c..0000000000
--- a/src/inc/fusionpriv.idl
+++ /dev/null
@@ -1,970 +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.
-//+---------------------------------------------------------------------------
-//
-// Microsoft Windows
-// File: fusionpriv.idl
-//
-// Contents: Fusion Interfaces
-//
-// Classes:
-//
-// Functions:
-//
-//
-//----------------------------------------------------------------------------
-cpp_quote("//=--------------------------------------------------------------------------=")
-cpp_quote("// fusionpriv.h")
-cpp_quote("//=--------------------------------------------------------------------------=")
-cpp_quote("// Licensed to the .NET Foundation under one or more agreements.")
-cpp_quote("// The .NET Foundation licenses this file to you under the MIT license.")
-cpp_quote("// See the LICENSE file in the project root for more information.")
-cpp_quote("//=--------------------------------------------------------------------------=")
-cpp_quote("")
-cpp_quote("#ifdef _MSC_VER")
-cpp_quote("#pragma comment(lib,\"uuid.lib\")")
-cpp_quote("#endif")
-cpp_quote("")
-cpp_quote("//---------------------------------------------------------------------------=")
-cpp_quote("// Fusion Interfaces.")
-cpp_quote("")
-
-cpp_quote("#if defined(_CLR_BLD) && !defined(FEATURE_FUSION)")
-cpp_quote("#error FEATURE_FUSION is not enabled, please do not include fusionpriv.h")
-cpp_quote("#endif")
-
-
-import "objidl.idl";
-import "oleidl.idl";
-import "fusion.idl";
-
-#ifndef FEATURE_CORECLR
-import "binderngen.idl";
-#endif
-
-cpp_quote("#ifdef _MSC_VER")
-cpp_quote("#pragma once")
-cpp_quote("#endif")
-
-interface IAssembly;
-interface IAssemblyBindSink;
-interface IAssemblyBinding;
-interface IAssemblyManifestImport;
-interface IAssemblyModuleImport;
-interface IAssemblyBindingClosure;
-
-interface IAssemblyNameBinder;
-interface IHistoryAssembly;
-interface IHistoryReader;
-interface IFusionBindLog;
-
-interface IAssemblyScavenger;
-
-interface IHostAssembly;
-interface IHostAssemblyModuleImport;
-
-interface IMetaDataAssemblyImport;
-#pragma midl_echo("struct IMetaDataAssemblyImport;")
-
-struct AssemblyReferenceClosureWalkContextForProfAPI;
-
-cpp_quote("EXTERN_C const IID IID_IApplicationContext; ")
-cpp_quote("EXTERN_C const IID IID_IAssembly; ")
-cpp_quote("EXTERN_C const IID IID_IAssemblyBindSink; ")
-cpp_quote("EXTERN_C const IID IID_IAssemblyBinding; ")
-cpp_quote("EXTERN_C const IID IID_IAssemblyManifestImport;")
-cpp_quote("EXTERN_C const IID IID_IAssemblyModuleImport; ")
-
-cpp_quote("EXTERN_C const IID IID_IHistoryAssembly; ")
-cpp_quote("EXTERN_C const IID IID_IHistoryReader; ")
-cpp_quote("EXTERN_C const IID IID_IMetaDataAssemblyImportControl; ")
-
-cpp_quote("EXTERN_C const IID IID_IAssemblyScavenger; ")
-
-cpp_quote("EXTERN_C const IID IID_IHostAssembly; ")
-cpp_quote("EXTERN_C const IID IID_IHostAssemblyModuleImport; ")
-//
-// Bind flags for IAssemblyName::BindToObject
-//
-// External caller of IAssemblyName::BindToObject should only use ASM_BINDF_PARENT_ASM_HINT/ASM_BINDF_NONE/ASM_BINDF_INSPECTION_ONLY.
-// The rest is used internally by fusion. They can(and should) be set via IApplicationContext::Set.
-//
-typedef enum
-{
- ASM_BINDF_NONE = 0x0,
- ASM_BINDF_FORCE_CACHE_INSTALL = 0x1,
- ASM_BINDF_RFS_INTEGRITY_CHECK = 0x2,
- ASM_BINDF_RFS_MODULE_CHECK = 0x4,
- ASM_BINDF_BINPATH_PROBE_ONLY = 0x8,
- //ASM_BINDF_SHARED_BINPATH_HINT = 0x10,
- ASM_BINDF_PARENT_ASM_HINT = 0x20,
- ASM_BINDF_DISALLOW_APPLYPUBLISHERPOLICY = 0x40,
- ASM_BINDF_DISALLOW_APPBINDINGREDIRECTS = 0x80,
- ASM_BINDF_DISABLE_FX_UNIFICATION = 0x100,
- ASM_BINDF_DO_NOT_PROBE_NATIVE_IMAGE = 0x200,
- ASM_BINDF_DISABLE_DOWNLOAD = 0x400,
- ASM_BINDF_INSPECTION_ONLY = 0x800,
- ASM_BINDF_DISALLOW_APP_BASE_PROBING = 0x1000,
- ASM_BINDF_SUPPRESS_SECURITY_CHECKS = 0x2000
-} ASM_BIND_FLAGS;
-
-typedef enum tagDEVOVERRIDEMODE {
- DEVOVERRIDE_LOCAL = 0x1,
- DEVOVERRIDE_GLOBAL = 0x2
-} DEVOVERRIDEMODE;
-
-typedef enum tagWALK_LEVEL
-{
- LEVEL_STARTING, // only basic info
- LEVEL_WINRTCHECK, // WinRT specific checks
- LEVEL_GACCHECK, // until find something outside of the GAC
- LEVEL_COMPLETE, // no reason to request higher than this
- LEVEL_FXPREDICTED, // full walk, but FX assemblies were predicted
- LEVEL_FXPROBED // full walk, but FX assemblies could not be predicted
-} WALK_LEVEL;
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IHistoryAssembly
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- local,
- object,
- uuid(e6096a07-e188-4a49-8d50-2a0172a0d205),
- pointer_default(unique)
-]
-interface IHistoryAssembly : IUnknown
-{
- HRESULT GetAssemblyName
- (
- [out, annotation("__out")] LPWSTR wzAsmName,
- [in, out, annotation("__inout")] DWORD *pdwSize
- );
-
- HRESULT GetPublicKeyToken
- (
- [out, annotation("__out")] LPWSTR wzPublicKeyToken,
- [in, out, annotation("__inout")] DWORD *pdwSize
- );
-
- HRESULT GetCulture
- (
- [out, annotation("__out")] LPWSTR wzCulture,
- [in, out, annotation("__inout")] DWORD *pdwSize
- );
-
- HRESULT GetReferenceVersion
- (
- [out, annotation("__out")] LPWSTR wzVerRef,
- [in, out, annotation("__inout")] DWORD *pdwSize
- );
-
- HRESULT GetActivationDate
- (
- [out, annotation("__out")] LPWSTR wzActivationDate,
- [in, out, annotation("__inout")] DWORD *pdwSize
- );
-
- HRESULT GetAppCfgVersion
- (
- [out, annotation("__out")] LPWSTR pwzVerAppCfg,
- [in, out, annotation("__inout")] DWORD *pdwSize
- );
-
- HRESULT GetPublisherCfgVersion
- (
- [out, annotation("__out")] LPWSTR pwzVerPublisherCfg,
- [in, out, annotation("__inout")] DWORD *pdwSize
- );
-
- HRESULT GetAdminCfgVersion
- (
- [out, annotation("__out")] LPWSTR pwzAdminCfg,
- [in, out, annotation("__inout")] DWORD *pdwSize
- );
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IHistoryReader
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- local,
- object,
- uuid(1d23df4d-a1e2-4b8b-93d6-6ea3dc285a54),
- pointer_default(unique)
-]
-interface IHistoryReader : IUnknown
-{
- HRESULT GetFilePath
- (
- [out, annotation("__out")] LPWSTR wzFilePath,
- [in, out, annotation("__inout")] DWORD *pdwSize
- );
-
- HRESULT GetApplicationName
- (
- [out, annotation("__out")] LPWSTR wzAppName,
- [in, out, annotation("__inout")] DWORD *pdwSize
- );
-
- HRESULT GetEXEModulePath
- (
- [out, annotation("__out")] LPWSTR wzExePath,
- [in, out, annotation("__inout")] DWORD *pdwSize
- );
-
-
- HRESULT GetNumActivations
- (
- [out] DWORD *pdwNumActivations
- );
-
- HRESULT GetActivationDate
- (
- [in] DWORD dwIdx,
- [out] FILETIME *pftDate
- );
-
- HRESULT GetRunTimeVersion
- (
- [in] FILETIME *pftActivationDate,
- [out, annotation("__out")] LPWSTR wzRunTimeVersion,
- [in, out, annotation("__inout")] DWORD *pdwSize
- );
-
- HRESULT GetNumAssemblies
- (
- [in] FILETIME *pftActivationDate,
- [out] DWORD *pdwNumAsms
- );
-
- HRESULT GetHistoryAssembly
- (
- [in] FILETIME *pftActivationDate,
- [in] DWORD dwIdx,
- [out] IHistoryAssembly **ppHistAsm
- );
-}
-
-typedef enum {
- LOADCTX_TYPE_DEFAULT,
- LOADCTX_TYPE_LOADFROM,
- LOADCTX_TYPE_UNKNOWN,
- LOADCTX_TYPE_HOSTED, // Assembly bind was provided by hosted binder.
-} LOADCTX_TYPE;
-
-// Log for normal assembly binding
-cpp_quote("#define FUSION_BIND_LOG_CATEGORY_DEFAULT 0")
-// Log for native image binding
-cpp_quote("#define FUSION_BIND_LOG_CATEGORY_NGEN 1")
-// max entry for bind log kinds. Should always point to the biggest one
-cpp_quote("#define FUSION_BIND_LOG_CATEGORY_MAX 2")
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IFusionBindLog
-//
-///////////////////////////////////////////////////////////////////////////////
-
-[
- local,
- object,
- uuid(67E9F87D-8B8A-4a90-9D3E-85ED5B2DCC83),
- pointer_default(unique)
-]
-interface IFusionBindLog : IUnknown
-{
- HRESULT SetResultCode
- (
- [in] DWORD dwLogCategory,
- [in] HRESULT hr
- );
-
- HRESULT GetResultCode
- (
- [in] DWORD dwLogCategory,
- [out] HRESULT *pHr
- );
-
- HRESULT GetBindLog
- (
- [in] DWORD dwDetailLevel,
- [in] DWORD dwLogCategory,
- [out, annotation("__out_opt")] LPWSTR pwzDebugLog,
- [in, out, annotation("__inout")] DWORD *pcbDebugLog
- );
-
- HRESULT LogMessage
- (
- [in] DWORD dwDetailLevel,
- [in] DWORD dwLogCategory,
- [in] LPCWSTR pwzDebugLog
- );
-
- HRESULT Flush
- (
- [in] DWORD dwDetailLevel,
- [in] DWORD dwLogCategory
- );
-
- HRESULT GetBindingID
- (
- [out] ULONGLONG *pullBindingID
- );
-
- HRESULT ETWTraceLogMessage
- (
- [in] DWORD dwETWLogCategory,
- [in] IAssemblyName *pAsm
- );
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IAssemblyManifestImport
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- local,
- object,
- uuid( de9a68ba-0fa2-11d3-94aa-00c04fc308ff),
- pointer_default(unique)
-]
-interface IAssemblyManifestImport: IUnknown
-{
- typedef [unique] IAssemblyManifestImport *LPASSEMBLY_MANIFEST_IMPORT;
-
- HRESULT GetAssemblyNameDef(
- [out] IAssemblyName **ppAssemblyName);
-
- HRESULT GetNextAssemblyNameRef(
- [in] DWORD nIndex,
- [out] IAssemblyName ** ppAssemblyName);
-
- HRESULT GetNextAssemblyModule(
- [in] DWORD nIndex,
- [out] IAssemblyModuleImport **ppImport);
-
- HRESULT GetModuleByName(
- [in] LPCOLESTR szModuleName,
- [out] IAssemblyModuleImport **ppModImport);
-
- HRESULT GetManifestModulePath(
- [out, size_is(*pccModulePath), annotation("__out_ecount_full(*pccModulePath)")] LPOLESTR szModulePath,
- [in, out] LPDWORD pccModulePath);
-
- HRESULT GetInternalMDImport(
- [out] IMetaDataAssemblyImport **ppMDImport);
-
- HRESULT LoadDataFromMDImport(
- [in] IMetaDataAssemblyImport *ppMDImport);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IApplicationContext
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- local,
- object,
- uuid(7c23ff90-33af-11d3-95da-00a024a85b51),
- pointer_default(unique)
-]
-interface IApplicationContext: IUnknown
-{
- cpp_quote("// App context configuration variables")
- cpp_quote("#define ACTAG_APP_BASE_URL L\"APPBASE\"")
- cpp_quote("#define ACTAG_MACHINE_CONFIG L\"MACHINE_CONFIG\"")
- cpp_quote("#define ACTAG_APP_PRIVATE_BINPATH L\"PRIVATE_BINPATH\"")
- cpp_quote("#define ACTAG_APP_SHARED_BINPATH L\"SHARED_BINPATH\"")
- cpp_quote("#define ACTAG_APP_SNAPSHOT_ID L\"SNAPSHOT_ID\"")
- cpp_quote("#define ACTAG_APP_CONFIG_FILE L\"APP_CONFIG_FILE\"")
- cpp_quote("#define ACTAG_APP_ID L\"APPLICATION_ID\"")
- cpp_quote("#define ACTAG_APP_SHADOW_COPY_DIRS L\"SHADOW_COPY_DIRS\"")
- cpp_quote("#define ACTAG_APP_DYNAMIC_BASE L\"DYNAMIC_BASE\"")
- cpp_quote("#define ACTAG_APP_CACHE_BASE L\"CACHE_BASE\"")
- cpp_quote("#define ACTAG_APP_NAME L\"APP_NAME\"")
- cpp_quote("#define ACTAG_DEV_PATH L\"DEV_PATH\"")
- cpp_quote("#define ACTAG_HOST_CONFIG_FILE L\"HOST_CONFIG\"")
- cpp_quote("#define ACTAG_SXS_ACTIVATION_CONTEXT L\"SXS\"")
- cpp_quote("#define ACTAG_APP_CFG_LOCAL_FILEPATH L\"APP_CFG_LOCAL_FILEPATH\"")
- cpp_quote("#define ACTAG_ZAP_STRING L\"ZAP_STRING\"")
- cpp_quote("#define ACTAG_ZAP_CONFIG_FLAGS L\"ZAP_CONFIG_FLAGS\"")
- cpp_quote("#define ACTAG_APP_DOMAIN_ID L\"APPDOMAIN_ID\"")
- cpp_quote("#define ACTAG_APP_CONFIG_BLOB L\"APP_CONFIG_BLOB\"")
- cpp_quote("#define ACTAG_FX_ONLY L\"FX_ONLY\"")
-
- cpp_quote("// App context flag overrides")
- cpp_quote("#define ACTAG_FORCE_CACHE_INSTALL L\"FORCE_CACHE_INSTALL\"")
- cpp_quote("#define ACTAG_RFS_INTEGRITY_CHECK L\"RFS_INTEGRITY_CHECK\"")
- cpp_quote("#define ACTAG_RFS_MODULE_CHECK L\"RFS_MODULE_CHECK\"")
- cpp_quote("#define ACTAG_BINPATH_PROBE_ONLY L\"BINPATH_PROBE_ONLY\"")
- cpp_quote("#define ACTAG_DISALLOW_APPLYPUBLISHERPOLICY L\"DISALLOW_APP\"")
- cpp_quote("#define ACTAG_DISALLOW_APP_BINDING_REDIRECTS L\"DISALLOW_APP_REDIRECTS\"")
- cpp_quote("#define ACTAG_DISALLOW_APP_BASE_PROBING L\"DISALLOW_APP_BASE_PROBING\"")
- cpp_quote("#define ACTAG_CODE_DOWNLOAD_DISABLED L\"CODE_DOWNLOAD_DISABLED\"")
- cpp_quote("#define ACTAG_DISABLE_FX_ASM_UNIFICATION L\"DISABLE_FX_ASM_UNIFICATION\"")
-
- typedef [unique] IApplicationContext *LPAPPLICATIONCONTEXT;
-
- typedef enum
- {
- APP_CTX_FLAGS_INTERFACE = 0x1
- } APP_FLAGS;
-
- HRESULT SetContextNameObject(
- [in] LPASSEMBLYNAME pName);
-
- HRESULT GetContextNameObject(
- [out] LPASSEMBLYNAME * ppName);
-
-
- HRESULT Set(
- [in] LPCOLESTR szName,
- [in] LPVOID pvValue,
- [in] DWORD cbValue,
- [in] DWORD dwFlags);
-
- HRESULT Get(
- [in] LPCOLESTR szName,
- [out] LPVOID pvValue,
- [in, out] LPDWORD pcbValue,
- [in] DWORD dwFlags);
-
- HRESULT GetDynamicDirectory(
- [out, annotation("__out_ecount_opt(*pdwSize)")] LPWSTR wzDynamicDir,
- [in, out] LPDWORD pdwSize);
-
- HRESULT GetAppCacheDirectory(
- [out, annotation("__out_ecount_opt(*pdwSize)")] LPWSTR wzAppCacheDir,
- [in, out] LPDWORD pdwSize);
-
- HRESULT RegisterKnownAssembly(
- [in] IAssemblyName *pName,
- [in] LPCWSTR pwzAsmURL,
- [out] IAssembly **ppAsmOut);
-
- HRESULT PrefetchAppConfigFile();
-
- // This will give a IAssemblyBindingClosure object without really walking
- // the closure. Any of the APIs on IAssemblyBindingClosure may trigger a
- // real walking.
- //
- // This closure is not cached in fusion. Caller is responsible to cache the closure.
- //
- // pUnk is the result of a previous bind within the same application context.
- // It could be IHostAssembly or IAssembly. The assembly has to be strongly named.
- //
- // dwSharingFlags cannot be 0 now.
- HRESULT GetAssemblyBindingClosure(
- [in] IUnknown *pUnk,
- [in] LPCWSTR pwzNativeImagePath,
- [out] IAssemblyBindingClosure **ppAsmClosure
- );
-}
-
-[
- local,
- object,
- uuid(56972d9d-0f6c-47de-a038-e82d5de3a777),
- pointer_default(unique)
-]
-interface IAssemblyNameBinder : IUnknown
-{
- HRESULT BindToObject(
- [in] REFIID refIID,
- [in] IUnknown *pUnkSink,
- [in] IUnknown *pUnkContext,
- [in] LPCOLESTR szCodeBase,
- [in] LONGLONG llFlags,
- [in] LPVOID pParentAssembly,
- [in] DWORD cbReserved,
- [out] LPVOID *ppv,
- [out] LPVOID *ppvNI);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IAssembly
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- local,
- object,
- uuid(ff08d7d4-04c2-11d3-94aa-00c04fc308ff),
- pointer_default(unique)
-]
-interface IAssembly : IUnknown
-{
- typedef [unique] IAssembly *LPASSEMBLY;
-
- cpp_quote("#define ASMLOC_LOCATION_MASK 0x0000001B")
- cpp_quote("#define ASMLOC_UNKNOWN 0x00000000")
- cpp_quote("#define ASMLOC_GAC 0x00000001")
- cpp_quote("#define ASMLOC_DOWNLOAD_CACHE 0x00000002")
- cpp_quote("#define ASMLOC_RUN_FROM_SOURCE 0x00000003")
- cpp_quote("#define ASMLOC_CODEBASE_HINT 0x00000004")
- cpp_quote("#define ASMLOC_ZAP 0x00000008")
- cpp_quote("#define ASMLOC_DEV_OVERRIDE 0x00000010")
-
- HRESULT GetAssemblyNameDef(
- [out] IAssemblyName **ppAssemblyName);
-
- HRESULT GetNextAssemblyNameRef(
- [in] DWORD nIndex,
- [out] IAssemblyName **ppAssemblyName);
-
- HRESULT GetNextAssemblyModule(
- [in] DWORD nIndex,
- [out] IAssemblyModuleImport **ppModImport);
-
- HRESULT GetModuleByName(
- [in] LPCOLESTR szModuleName,
- [out] IAssemblyModuleImport **ppModImport);
-
- HRESULT GetManifestModulePath(
- [out, size_is(*pccModulePath), annotation("__out_ecount_full_opt(*pccModulePath)")] LPOLESTR szModulePath,
- [in, out] LPDWORD pccModulePath);
-
- HRESULT GetAssemblyPath(
- [out, size_is(*lpcwBuffer), annotation("__out_ecount_full_opt(*lpcwBuffer)")] LPOLESTR pStr,
- [in, out] LPDWORD lpcwBuffer);
-
- HRESULT GetAssemblyLocation(
- [out] DWORD *pdwAsmLocation);
-
- LOADCTX_TYPE GetFusionLoadContext();
-
- HRESULT GetNextHardBoundDependency(
- [in] DWORD dwIndex,
- [out] IAssembly **ppILAsm,
- [out] IAssembly **ppNIAsm);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IAssemblyBindingClosureEnumerator
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- local,
- object,
- uuid(b3f1e4ed-cb09-4b85-9a1b-6809582f1ebc),
- pointer_default(unique)
-]
-interface IAssemblyBindingClosureEnumerator : IUnknown
-{
- // Get the next assembly in the closure's path
- HRESULT GetNextAssemblyPath(
- [out] LPCOLESTR *ppPath,
- [out] LPCOLESTR *ppniPath);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IAssemblyBindingClosure
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- local,
- object,
- uuid(415c226a-e513-41ba-9651-9c48e97aa5de),
- pointer_default(unique)
-]
-interface IAssemblyBindingClosure : IUnknown
-{
- // Test if all the assemblies in the closure are in GAC.
- // return:
- // S_OK all assemblies are in GAC.
- // S_FALSE not all assemblies are in GAC.
- // otherwise failure.
- HRESULT IsAllAssembliesInGAC();
-
- // Test to see if two closures are semantically the same
- // under the specified sharing context.
- // return:
- // S_OK Equal.
- // S_FALSE Not Equal.
- // otherwise failure.
- HRESULT IsEqual(
- [in] IAssemblyBindingClosure *pAssemblyClosure
- );
-
- HRESULT GetNextFailureAssembly(
- [in] DWORD dwIndex,
- [out] IAssemblyName **ppName,
- [out] HRESULT *pHResult);
-
- // ensure enough data is available
- HRESULT EnsureWalked(
- [in] IUnknown *pStartingAssembly,
- [in] IApplicationContext *pAppCtx,
- [in] WALK_LEVEL level);
-
- // Iterate over assembly paths in the closure
- HRESULT EnumerateAssemblies(
- [out] IAssemblyBindingClosureEnumerator **ppEnumerator);
-
- HRESULT HasBeenWalked([in] WALK_LEVEL level);
-
- // Test if the assembly might have unknonwn dependecies because of WinRT
- // return:
- // S_OK May.
- // S_FALSE No, all dependecies are traceable or FX.
- // otherwise failure.
- HRESULT MayHaveUnknownDependencies();
-
-
- // The closure walker asks the profiler (when present) for any additional
- // assembly references the profiler wishes to add. This method is then called
- // back by the profiler for each such assembly reference.
- HRESULT AddProfilerAssemblyReference(
- [in] LPVOID pbPublicKeyOrToken,
- [in] ULONG cbPublicKeyOrToken,
- [in] LPCWSTR szName,
- [in] LPVOID pMetaData,
- [in] void *pbHashValue,
- [in] ULONG cbHashValue,
- [in] DWORD dwAssemblyRefFlags,
- [in] struct AssemblyReferenceClosureWalkContextForProfAPI * pContext);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IAssemblyBindSink
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- local,
- object,
- uuid(af0bc960-0b9a-11d3-95ca-00a024a85b51),
- pointer_default(unique)
-]
-interface IAssemblyBindSink : IUnknown
-{
- typedef [unique] IAssemblyBindSink *LPASSEMBLY_BIND_SINK;
-
- typedef struct _tagFusionBindInfo
- {
- IFusionBindLog *pdbglog;
- IAssemblyName *pNamePolicy;
- DWORD dwPoliciesApplied;
- } FusionBindInfo;
-
- typedef enum
- {
- ASM_NOTIFICATION_START,
- ASM_NOTIFICATION_PROGRESS,
- ASM_NOTIFICATION_SUSPEND,
- ASM_NOTIFICATION_ATTEMPT_NEXT_CODEBASE,
- ASM_NOTIFICATION_BIND_INFO,
- ASM_NOTIFICATION_DONE,
- ASM_NOTIFICATION_NATIVE_IMAGE_DONE
- } ASM_NOTIFICATION;
-
-
- HRESULT OnProgress(
- [in] DWORD dwNotification,
- [in] HRESULT hrNotification,
- [in] LPCWSTR szNotification,
- [in] DWORD dwProgress,
- [in] DWORD dwProgressMax,
- [in] LPVOID pvBindInfo,
- [in] IUnknown *pUnk);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IAssemblyBinding
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- local,
- object,
- uuid(cfe52a80-12bd-11d3-95ca-00a024a85b51),
- pointer_default(unique)
-]
-interface IAssemblyBinding : IUnknown
-{
- typedef [unique] IAssemblyBinding *LPASSEMBLY_BINDINDING;
-
- HRESULT Control(
- [in] HRESULT hrControl);
-
- HRESULT DoDefaultUI(
- [in] HWND hWnd,
- [in] DWORD dwFlags);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IAssemblyModuleImport
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- local,
- object,
- uuid(da0cd4b0-1117-11d3-95ca-00a024a85b51),
- pointer_default(unique)
-]
-interface IAssemblyModuleImport : IStream
-{
- typedef [unique] IAssemblyModuleImport *LPASSEMBLY_MODULE_IMPORT;
-
- HRESULT GetModuleName(
- [out, size_is(*pccModuleName), annotation("__out_ecount_full_opt(*pccModuleName)")] LPOLESTR szModuleName,
- [in, out] LPDWORD pccModuleName);
-
- HRESULT GetHashAlgId(
- [out] LPDWORD pdwHashAlgId);
-
- HRESULT GetHashValue(
- [out, size_is(*pcbHashValue)] BYTE *pbHashValue,
- [in, out] LPDWORD pcbHashValue);
-
- HRESULT GetFlags(
- [out] LPDWORD pdwFlags);
-
- HRESULT GetModulePath(
- [out, size_is(*pccModulePath), annotation("__out_ecount_full_opt(*pccModulePath)")] LPOLESTR szModulePath,
- [in, out] LPDWORD pccModulePath);
-
- BOOL IsAvailable();
-
- HRESULT BindToObject(
- [in] IAssemblyBindSink *pBindSink,
- [in] IApplicationContext *pAppCtx,
- [in] LONGLONG llFlags,
- [out] LPVOID *ppv);
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// IAssemblyScavenger
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- local,
- object,
- uuid(21b8916c-f28e-11d2-a473-00ccff8ef448),
- pointer_default(unique)
-]
-interface IAssemblyScavenger : IUnknown
-{
-
- HRESULT ScavengeAssemblyCache
- (
- );
-
- HRESULT GetCacheDiskQuotas
- (
- [out] DWORD *pdwZapQuotaInGAC,
- [out] DWORD *pdwDownloadQuotaAdmin,
- [out] DWORD *pdwDownloadQuotaUser
- );
-
- HRESULT SetCacheDiskQuotas
- (
- [in] DWORD dwZapQuotaInGAC,
- [in] DWORD dwDownloadQuotaAdmin,
- [in] DWORD dwDownloadQuotaUser
- );
-
- HRESULT GetCurrentCacheUsage
- (
- [out] DWORD *dwZapUsage,
- [out] DWORD *dwDownloadUsage
- );
-}
-
-
-///////////////////////////////////////////////////////////////////////////////
-
-[
- local,
- object,
- uuid(D8FB9BD6-3969-11d3-B4AF-00C04F8ECB26),
- pointer_default(unique)
-]
-interface ICodebaseList : IUnknown
-{
- HRESULT AddCodebase
- (
- [in] LPCWSTR wzCodebase,
- [in] DWORD dwFlags
- );
-
- HRESULT RemoveCodebase
- (
- [in] DWORD dwIndex
- );
-
- HRESULT RemoveAll();
-
- HRESULT GetCount
- (
- [out] DWORD *pdwCount
- );
-
- HRESULT GetCodebase
- (
- [in] DWORD dwIndex,
- [out] DWORD *pdwFlags,
- [out, annotation("__out_ecount_opt(*pcbCodebase)")]
- LPWSTR wzCodebase,
- [in, out] DWORD *pcbCodebase
- );
-}
-
-[
- local,
- object,
- uuid(0A6F16F8-ACD7-11d3-B4ED-00C04F8ECB26),
- pointer_default(unique)
-]
-interface IDownloadMgr : IUnknown
-{
- HRESULT PreDownloadCheck
- (
- [out] void **ppv,
- [out] void **ppvNI
- );
-
- HRESULT DoSetup
- (
- [in] LPCWSTR wzSourceUrl,
- [in] LPCWSTR wzFilePath,
- [in] const FILETIME *pftLastMod,
- [out] IUnknown **ppUnk,
- [out] IUnknown **ppAsmNI
- );
-
- HRESULT ProbeFailed
- (
- [out] IUnknown **ppUnk
- );
-
- HRESULT IsDuplicate
- (
- [out] IDownloadMgr *ppDLMgr
- );
-
- HRESULT LogResult();
-
- HRESULT DownloadEnabled
- (
- [out] BOOL *pbEnabled
- );
-
- HRESULT GetBindInfo
- (
- [out] FusionBindInfo *pBindInfo
- );
-
- HRESULT CacheBindingResult
- (
- [in] HRESULT hrResult
- );
-}
-
-
-[
- local,
- object,
- uuid(711f7c2d-8234-4505-b02f-7554f46cbf29),
- pointer_default(unique)
-]
-interface IHostAssembly : IUnknown
-{
- typedef [unique] IHostAssembly *LPHOSTASSEMBLY;
-
- HRESULT GetAssemblyNameDef(
- [out] IAssemblyName **ppAssemblyName);
-
- HRESULT GetNextAssemblyNameRef(
- [in] DWORD nIndex,
- [out] IAssemblyName **ppAssemblyName);
-
- HRESULT GetNextAssemblyModule(
- [in] DWORD nIndex,
- [out] IHostAssemblyModuleImport **ppModImport);
-
- HRESULT GetModuleByName(
- [in] LPCOLESTR szModuleName,
- [out] IHostAssemblyModuleImport **ppModImport);
-
- // Always release the copy in fusion
- HRESULT GetAssemblyStream(
- [out] IStream **ppStreamAsm);
-
- HRESULT GetAssemblyId(
- [out] UINT64 *pAssemblyId);
-
- // Always release the copy in fusion
- HRESULT GetAssemblyDebugStream(
- [out] IStream **ppDebugStream);
-
- LOADCTX_TYPE GetFusionLoadContext(
- );
-
- HRESULT GetAssemblyContext(
- [out] UINT64 *pdwAssemblyContext);
-}
-
-[
- local,
- object,
- uuid(b6f2729d-6c0f-4944-b692-e5a2ce2c6e7a),
- pointer_default(unique)
-]
-interface IHostAssemblyModuleImport : IUnknown
-{
- typedef [unique] IHostAssemblyModuleImport *LPHOSTASSEMBLY_MODULE_IMPORT;
-
- HRESULT GetModuleName(
- [out, size_is(*pccModuleName), annotation("__out_ecount_full(*pccModuleName)")] LPOLESTR szModuleName,
- [in, out] LPDWORD pccModuleName);
-
- HRESULT GetModuleStream(
- [out] IStream **ppStreamModule);
-
- HRESULT GetModuleId(
- [out] DWORD *pdwModuleId);
-
- HRESULT GetModuleDebugStream(
- [out] IStream **ppDebugStream);
-}
-
-
-#pragma midl_echo("STDAPI CreateHistoryReader(LPCWSTR wzFilePath, IHistoryReader **ppHistReader);")
-#pragma midl_echo("STDAPI LookupHistoryAssembly(LPCWSTR pwzFilePath, FILETIME *pftActivationDate, LPCWSTR pwzAsmName, LPCWSTR pwzPublicKeyToken, LPCWSTR wzCulture, LPCWSTR pwzVerRef, IHistoryAssembly **pHistAsm);")
-#pragma midl_echo("STDAPI GetHistoryFileDirectory(__out_ecount_opt(*pdwSize) LPWSTR wzDir, DWORD *pdwSize);")
-#pragma midl_echo("STDAPI PreBindAssembly(IApplicationContext *pAppCtx, IAssemblyName *pName, IAssembly *pAsmParent, IAssemblyName **ppNamePostPolicy, LPVOID pvReserved); ")
-
-#pragma midl_echo("STDAPI CreateApplicationContext(IAssemblyName *pName, LPAPPLICATIONCONTEXT *ppCtx); ")
-#pragma midl_echo("STDAPI IsRetargetableAssembly(IAssemblyName *pName, BOOL *pbIsRetargetable); ")
-#pragma midl_echo("STDAPI IsOptionallyRetargetableAssembly(IAssemblyName *pName, BOOL *pbIsRetargetable); ")
-
-
-cpp_quote("#define EXPLICITBIND_FLAGS_NON_BINDABLE 0x0")
-cpp_quote("#define EXPLICITBIND_FLAGS_EXE 0x1")
-
-#ifndef FEATURE_CORECLR
-#pragma midl_echo("HRESULT BindToSystem(IAssemblyName *pNameSystem, LPCWSTR pcwzSystemDirectory, IUnknown *pNIEva, IApplicationContext *pAppCtx, IAssembly **ppAsmOut, IBindResult **ppNIAsmOut, IFusionBindLog **ppdbglog);")
-
-#pragma midl_echo("HRESULT ExplicitBind(LPCWSTR wzPath, IApplicationContext *pAppCtx, DWORD dwFlags, IUnknown *pNIEva, IAssembly **ppAsmOut, IBindResult **ppNIAsmOut, IFusionBindLog **ppdbglog);")
-
-#pragma midl_echo("HRESULT GetBindContextFromApplicationContext(IApplicationContext *pAppCtx, IBindContext **ppBindCtx);")
-
-#pragma midl_echo("HRESULT SetApplicationContext_WinRTBinder(IApplicationContext * pAppCtx, IBindContext * pWinRTBinder);")
-
-// Used by InstallNativeImage() to extract dependency names from the NI's CORCOMPILE_DEPENDENCY_INFO records.
-#pragma midl_echo("STDAPI FusionGetAssemblyNameRefFromMDImport(IMetaDataAssemblyImport *pMDImport, /* This is really an mdAssemblyRef */ DWORD mdar, DWORD dwFlags, IAssemblyName **ppName);")
-
-#endif //!FEATURE_CORECLR
diff --git a/src/inc/fusionsink.h b/src/inc/fusionsink.h
deleted file mode 100644
index adf88d4cd4..0000000000
--- a/src/inc/fusionsink.h
+++ /dev/null
@@ -1,129 +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.
-
-
-
-/*============================================================
-**
-** Header: FusionSink.hpp
-**
-** Purpose: Implements FusionSink
-**
-**
-===========================================================*/
-#ifndef _FUSIONSINK_H
-#define _FUSIONSINK_H
-
-#include <fusion.h>
-#include <fusionpriv.h>
-#include "corhlpr.h"
-#include "corpriv.h"
-
-class FusionSink : public IAssemblyBindSink, public INativeImageEvaluate
-{
-public:
-
- FusionSink() :
- m_punk(NULL),
- m_pNIunk(NULL),
- m_pAbortUnk(NULL),
- m_pFusionLog(NULL),
- m_cRef(1),
- m_hEvent(NULL),
- m_LastResult(S_OK)
- {
- WRAPPER_NO_CONTRACT;
- }
-
- virtual void Reset()
- {
- CONTRACTL
- {
- INSTANCE_CHECK;
- NOTHROW;
- }
- CONTRACTL_END;
-
- if(m_pAbortUnk) {
- m_pAbortUnk->Release();
- m_pAbortUnk = NULL;
- }
-
- if(m_punk) {
- m_punk->Release();
- m_punk = NULL;
- }
-
- if(m_pNIunk) {
- m_pNIunk->Release();
- m_pNIunk = NULL;
- }
-
- if(m_pFusionLog) {
- m_pFusionLog->Release();
- m_pFusionLog = NULL;
- }
-
- m_LastResult = S_OK;
- }
-
- ~FusionSink()
- {
- CONTRACTL
- {
- DESTRUCTOR_CHECK;
- NOTHROW;
- }
- CONTRACTL_END;
-
- if(m_hEvent) {
- delete m_hEvent;
- m_hEvent = NULL;
- }
-
- Reset();
- }
-
- HRESULT AssemblyResetEvent();
- HRESULT LastResult()
- {
- LIMITED_METHOD_CONTRACT;
- return m_LastResult;
- }
-
- STDMETHODIMP QueryInterface(REFIID riid, void **ppInterface);
- ULONG STDMETHODCALLTYPE AddRef(void);
- ULONG STDMETHODCALLTYPE Release(void);
-
- STDMETHODIMP OnProgress(DWORD dwNotification,
- HRESULT hrNotification,
- LPCWSTR szNotification,
- DWORD dwProgress,
- DWORD dwProgressMax,
- LPVOID pvBindInfo,
- IUnknown* punk);
-
- // Wait on the event.
- virtual HRESULT Wait();
-
- STDMETHODIMP Evaluate(
- IAssembly *pILAssembly,
- IAssembly *pNativeAssembly,
- BYTE * pbCachedData,
- DWORD dwDataSize);
-
- IUnknown* m_punk; // Getting an assembly
- IUnknown* m_pNIunk; // Getting an assembly
- IUnknown* m_pAbortUnk; // pUnk for aborting a bind
- IFusionBindLog *m_pFusionLog;
-
-protected:
- HRESULT AssemblyCreateEvent();
-
- LONG m_cRef; // Ref count.
- Event *m_hEvent; // Event to block thread.
- HRESULT m_LastResult; // Last notification result
-};
-
-#endif // _FUSIONSINK_H
diff --git a/src/inc/gchost.idl b/src/inc/gchost.idl
index 3aa528f028..6d85f91513 100644
--- a/src/inc/gchost.idl
+++ b/src/inc/gchost.idl
@@ -10,22 +10,8 @@
* -------------------------------------------------------------------------- */
import "unknwn.idl";
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-typedef enum
-{
- COR_GC_COUNTS = 0x00000001, // Fill out count values.
- COR_GC_MEMORYUSAGE = 0x00000002, // Fill out memory usage values.
-} COR_GC_STAT_TYPES;
-
-typedef enum
-{
- COR_GC_THREAD_HAS_PROMOTED_BYTES = 0x00000001 // Thread has bytes promoted in the last GC
- // if flags set to this value.
-} COR_GC_THREAD_STATS_TYPES;
-
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
+#if defined(FEATURE_WINDOWSPHONE)
/*
* This structure is used to return statics for the GC system. Set the Flags
* value to a bitmask of values that should be returned. Only those values which
@@ -50,86 +36,12 @@ typedef struct _COR_GC_STATS
SIZE_T KBytesPromotedFromGen1;
} COR_GC_STATS;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES || FEATURE_WINDOWSPHONE
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-/*
- * This structure is used to return per-thread statistics related to GC.
- */
-typedef struct _COR_GC_THREAD_STATS
-{
- ULONGLONG PerThreadAllocation; // Amount of memory allocated on this
- // thread. Cleared to 0 on each Gen 0 collection.
- ULONG Flags; // Thread has bytes promoted in the last GC?
-} COR_GC_THREAD_STATS;
-
-
-/*
- * This interface is used to get information about the GC system and
- * control some aspects of the GC. This interface is for expert usage
- * only, and can severely impact the performance of an application if
- * used improperly!!
- */
-[
- object,
- uuid(FAC34F6E-0DCD-47b5-8021-531BC5ECCA63),
- pointer_default(unique),
- local
-]
-interface IGCHost : IUnknown
-{
-
- /*
- * Sets the segment size and gen 0 maximum size. This value may only be
- * specified once and will not change if called later.
- */
- HRESULT SetGCStartupLimits([in] DWORD SegmentSize, [in] DWORD MaxGen0Size);
-
- /*
- * Forces a collection to occur for the given generation, regardless of
- * current GC statistics. A value of -1 means collect all generations.
- */
- HRESULT Collect([in] LONG Generation);
-
- /*
- * Returns a set of current statistics about the state of the GC system.
- * These values can then be used by a smart allocation system to help the
- * GC run, by say adding more memory or forcing a collection.
- */
- HRESULT GetStats([in][out] COR_GC_STATS *pStats);
-
- /*
- * This method returns the per-thread statics gathered by the GC.
- */
- HRESULT GetThreadStats([in] DWORD *pFiberCookie, [in][out] COR_GC_THREAD_STATS *pStats);
-
- /*
- * This method allows the caller to set virtual memory limit (MB) of the runtime. This limit
- * can be changed dynamically.
- */
- HRESULT SetVirtualMemLimit ([in] SIZE_T sztMaxVirtualMemMB);
-}
-
-[
- object,
- uuid(A1D70CEC-2DBE-4E2F-9291-FDF81438A1DF),
- pointer_default(unique),
- local
-]
-interface IGCHost2 : IGCHost
-{
- /*
- * Sets the segment size and gen 0 maximum size. This value may only be
- * specified once and will not change if called later.
- */
- HRESULT SetGCStartupLimitsEx([in] SIZE_T SegmentSize, [in] SIZE_T MaxGen0Size);
-}
+#endif // FEATURE_WINDOWSPHONE
-#else // FEATURE_INCLUDE_ALL_INTERFACES
cpp_quote("/*")
cpp_quote(" * WARNING - This is a dummy interface that should never be used.")
cpp_quote(" * The code is written this way because Midl requires a CoClass, Interface, etc... that generates")
-cpp_quote(" * a guid. Removing the IGCHost interface for FEATURE_INCLUDE_ALL_INTERFACES removes the only guid")
+cpp_quote(" * a guid. Removing the IGCHost interface removes the only guid")
cpp_quote(" * This option was selected because ifdefs are not simple to implement for excluding files in SOURCES")
cpp_quote("*/")
[
@@ -141,4 +53,3 @@ cpp_quote("*/")
interface IDummyDoNotUse : IUnknown
{
}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
diff --git a/src/inc/holder.h b/src/inc/holder.h
index a4d19bbf92..a92eeabaab 100644
--- a/src/inc/holder.h
+++ b/src/inc/holder.h
@@ -65,12 +65,6 @@
#ifdef _DEBUG
-#ifdef FEATURE_FUSION
-namespace NATIVE_BINDER_SPACE
-{
- class NativeAssembly;
-}
-#endif //FEATURE_FUSION
//------------------------------------------------------------------------------------------------
// This is used to make Visual Studio autoexp.dat work sensibly with holders again.
@@ -95,26 +89,11 @@ struct AutoExpVisibleValue
union
{
// Only include a class name here if it is customarily referred to through an abstract interface.
-#ifdef FEATURE_FUSION
- const class CAssemblyName *_asCAssemblyName;
- const class CAssembly *_asCAssembly;
- const class CAssemblyManifestImport *_asCAssemblyManifestImport;
- const class CAssemblyModuleImport *_asCAssemblyModuleImport;
- const class CHostAssembly *_asCHostAssembly;
- const class CHostAssemblyModuleImport *_asCHostAssemblyModuleImport;
- const class BindResult *_asBindResult;
- const class BindContext *_asBindContext;
- const class NATIVE_BINDER_SPACE::NativeAssembly *_asNativeAssembly;
- const class AssemblyLocation *_asAssemblyLocation;
-#endif //FEATURE_FUSION
#if defined(FEATURE_APPX)
const class AppXBindResultImpl *_asAppXBindResultImpl;
#endif
-#ifndef FEATURE_CORECLR
- const class PEFingerprint *_asPEFingerprint;
-#endif //!FEATURE_CORECLR
const void *_pPreventEmptyUnion;
};
};
@@ -1214,16 +1193,6 @@ FORCEINLINE void VoidDeleteFile(LPCWSTR wszFilePath) { WszDeleteFile(wszFilePath
typedef Wrapper<LPCWSTR, DoNothing<LPCWSTR>, VoidDeleteFile, NULL> DeleteFileHolder;
#endif // WszDeleteFile
-#if !defined(FEATURE_CORECLR) || defined(FEATURE_CRYPTO)
-// Crypto holders
-FORCEINLINE void VoidCryptReleaseContext(HCRYPTPROV h) { CryptReleaseContext(h, 0); }
-FORCEINLINE void VoidCryptDestroyHash(HCRYPTHASH h) { CryptDestroyHash(h); }
-FORCEINLINE void VoidCryptDestroyKey(HCRYPTKEY h) { CryptDestroyKey(h); }
-
-typedef Wrapper<HCRYPTPROV, DoNothing, VoidCryptReleaseContext, 0> HandleCSPHolder;
-typedef Wrapper<HCRYPTHASH, DoNothing, VoidCryptDestroyHash, 0> HandleHashHolder;
-typedef Wrapper<HCRYPTKEY, DoNothing, VoidCryptDestroyKey, 0> HandleKeyHolder;
-#endif // !FEATURE_CORECLR || FEATURE_CRYPTO
//-----------------------------------------------------------------------------
// Misc holders
diff --git a/src/inc/jithelpers.h b/src/inc/jithelpers.h
index f84db9142d..4e56250b04 100644
--- a/src/inc/jithelpers.h
+++ b/src/inc/jithelpers.h
@@ -38,15 +38,15 @@
// CORINFO_HELP_DBL2INT, CORINFO_HELP_DBL2UINT, and CORINFO_HELP_DBL2LONG get
// patched for CPUs that support SSE2 (P4 and above).
-#if !defined(_WIN64)
+#ifndef BIT64
JITHELPER(CORINFO_HELP_LLSH, JIT_LLsh, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_LRSH, JIT_LRsh, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_LRSZ, JIT_LRsz, CORINFO_HELP_SIG_REG_ONLY)
-#else
+#else // !BIT64
JITHELPER(CORINFO_HELP_LLSH, NULL, CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB)
JITHELPER(CORINFO_HELP_LRSH, NULL, CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB)
JITHELPER(CORINFO_HELP_LRSZ, NULL, CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB)
-#endif
+#endif // BIT64
JITHELPER(CORINFO_HELP_LMUL, JIT_LMul, CORINFO_HELP_SIG_16_STACK)
JITHELPER(CORINFO_HELP_LMUL_OVF, JIT_LMulOvf, CORINFO_HELP_SIG_16_STACK)
JITHELPER(CORINFO_HELP_ULMUL_OVF, JIT_ULMulOvf, CORINFO_HELP_SIG_16_STACK)
@@ -70,18 +70,12 @@
JITHELPER(CORINFO_HELP_DBLROUND, JIT_DoubleRound, CORINFO_HELP_SIG_16_STACK)
// Allocating a new object
-#ifdef FEATURE_REMOTING
- JITHELPER(CORINFO_HELP_NEW_CROSSCONTEXT, JIT_NewCrossContext, CORINFO_HELP_SIG_REG_ONLY)
-#else
JITHELPER(CORINFO_HELP_NEW_CROSSCONTEXT, NULL, CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB)
-#endif
JITHELPER(CORINFO_HELP_NEWFAST, JIT_New, CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_NEWSFAST, JIT_New, CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_NEWSFAST_ALIGN8, JIT_New, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_NEW_MDARR, JIT_NewMDArr,CORINFO_HELP_SIG_8_VA)
-#if COR_JIT_EE_VERSION > 460
JITHELPER(CORINFO_HELP_NEW_MDARR_NONVARARG, JIT_NewMDArrNonVarArg,CORINFO_HELP_SIG_4_STACK)
-#endif
JITHELPER(CORINFO_HELP_NEWARR_1_DIRECT, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_OBJ, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY)
DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_VC, JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY)
@@ -124,9 +118,7 @@
JITHELPER(CORINFO_HELP_RNGCHKFAIL, JIT_RngChkFail, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_OVERFLOW, JIT_Overflow, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_THROWDIVZERO, JIT_ThrowDivZero, CORINFO_HELP_SIG_REG_ONLY)
-#if COR_JIT_EE_VERSION > 460
JITHELPER(CORINFO_HELP_THROWNULLREF, JIT_ThrowNullRef, CORINFO_HELP_SIG_REG_ONLY)
-#endif // COR_JIT_EE_VERSION
JITHELPER(CORINFO_HELP_INTERNALTHROW, JIT_InternalThrow, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_VERIFICATION, IL_VerificationError,CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_SEC_UNMGDCODE_EXCPT, JIT_SecurityUnmanagedCodeException, CORINFO_HELP_SIG_REG_ONLY)
@@ -209,22 +201,8 @@
JITHELPER(CORINFO_HELP_GETFIELDADDR, JIT_GetFieldAddr,CORINFO_HELP_SIG_REG_ONLY)
-#ifdef FEATURE_REMOTING
- JITHELPER(CORINFO_HELP_GETSTATICFIELDADDR_CONTEXT, JIT_GetStaticFieldAddr_Context,CORINFO_HELP_SIG_REG_ONLY)
-#else
JITHELPER(CORINFO_HELP_GETSTATICFIELDADDR_CONTEXT, NULL, CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB)
-#endif
-
-#if COR_JIT_EE_VERSION > 460
-#ifdef FEATURE_MIXEDMODE
- // TLS
- JITHELPER(CORINFO_HELP_GETSTATICFIELDADDR_TLS, JIT_GetStaticFieldAddr_Tls,CORINFO_HELP_SIG_REG_ONLY)
-#else // FEATURE_MIXEDMODE
JITHELPER(CORINFO_HELP_GETSTATICFIELDADDR_TLS, NULL, CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB)
-#endif // FEATURE_MIXEDMODE
-#else // COR_JIT_EE_VERSION
- JITHELPER(CORINFO_HELP_GETSTATICFIELDADDR_TLS, JIT_GetStaticFieldAddr_Tls,CORINFO_HELP_SIG_REG_ONLY)
-#endif // COR_JIT_EE_VERSION
JITHELPER(CORINFO_HELP_GETGENERICS_GCSTATIC_BASE, JIT_GetGenericsGCStaticBase,CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_GETGENERICS_NONGCSTATIC_BASE, JIT_GetGenericsNonGCStaticBase,CORINFO_HELP_SIG_REG_ONLY)
@@ -308,11 +286,9 @@
JITHELPER(CORINFO_HELP_READYTORUN_CHKCAST, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
JITHELPER(CORINFO_HELP_READYTORUN_STATIC_BASE, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
JITHELPER(CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
-#if COR_JIT_EE_VERSION > 460
JITHELPER(CORINFO_HELP_READYTORUN_GENERIC_HANDLE, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
JITHELPER(CORINFO_HELP_READYTORUN_DELEGATE_CTOR, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
JITHELPER(CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
-#endif // COR_JIT_EE_VERSION
JITHELPER(CORINFO_HELP_EE_PRESTUB, ThePreStub, CORINFO_HELP_SIG_NO_ALIGN_STUB)
@@ -328,22 +304,18 @@
JITHELPER(CORINFO_HELP_EE_EXTERNAL_FIXUP, ExternalMethodFixupStub, CORINFO_HELP_SIG_NO_ALIGN_STUB)
JITHELPER(CORINFO_HELP_EE_VTABLE_FIXUP, VirtualMethodFixupStub, CORINFO_HELP_SIG_NO_ALIGN_STUB)
-#if (defined(_TARGET_X86_) || defined(_TARGET_ARM_)) && defined(FEATURE_REMOTING)
- JITHELPER(CORINFO_HELP_EE_REMOTING_THUNK, PrecodeRemotingThunk, CORINFO_HELP_SIG_UNDEF)
-#else
JITHELPER(CORINFO_HELP_EE_REMOTING_THUNK, NULL, CORINFO_HELP_SIG_UNDEF)
-#endif
// We do not need this to be saved in ngen images on Mac64 since the exception dispatch
// is not done via the OS and thus, there wont be any need to know this information
// by anyone.
-#if !defined(_TARGET_X86_)
+#ifdef WIN64EXCEPTIONS
JITHELPER(CORINFO_HELP_EE_PERSONALITY_ROUTINE, ProcessCLRException, CORINFO_HELP_SIG_UNDEF)
JITHELPER(CORINFO_HELP_EE_PERSONALITY_ROUTINE_FILTER_FUNCLET, ProcessCLRException,CORINFO_HELP_SIG_UNDEF)
-#else
+#else // WIN64EXCEPTIONS
JITHELPER(CORINFO_HELP_EE_PERSONALITY_ROUTINE, NULL, CORINFO_HELP_SIG_UNDEF)
JITHELPER(CORINFO_HELP_EE_PERSONALITY_ROUTINE_FILTER_FUNCLET, NULL, CORINFO_HELP_SIG_UNDEF)
-#endif
+#endif // !WIN64EXCEPTIONS
#ifdef _TARGET_X86_
JITHELPER(CORINFO_HELP_ASSIGN_REF_EAX, JIT_WriteBarrierEAX, CORINFO_HELP_SIG_NO_ALIGN_STUB)
@@ -378,8 +350,6 @@
JITHELPER(CORINFO_HELP_LOOP_CLONE_CHOICE_ADDR, JIT_LoopCloneChoiceAddr, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_DEBUG_LOG_LOOP_CLONING, JIT_DebugLogLoopCloning, CORINFO_HELP_SIG_REG_ONLY)
-#if COR_JIT_EE_VERSION > 460
-
JITHELPER(CORINFO_HELP_THROW_ARGUMENTEXCEPTION, JIT_ThrowArgumentException, CORINFO_HELP_SIG_REG_ONLY)
JITHELPER(CORINFO_HELP_THROW_ARGUMENTOUTOFRANGEEXCEPTION, JIT_ThrowArgumentOutOfRangeException, CORINFO_HELP_SIG_REG_ONLY)
@@ -389,7 +359,7 @@
JITHELPER(CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER, NULL, CORINFO_HELP_SIG_UNDEF)
JITHELPER(CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT, NULL, CORINFO_HELP_SIG_UNDEF)
-#endif // COR_JIT_EE_VERSION
+ JITHELPER(CORINFO_HELP_GVMLOOKUP_FOR_SLOT, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
#undef JITHELPER
#undef DYNAMICJITHELPER
diff --git a/src/inc/legacyactivationshim.h b/src/inc/legacyactivationshim.h
deleted file mode 100644
index 4d8eaa5dd9..0000000000
--- a/src/inc/legacyactivationshim.h
+++ /dev/null
@@ -1,1382 +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.
-//
-// LegacyActivationShim.h
-//
-// This file allows simple migration from .NET Runtime v2 Host Activation APIs
-// to the .NET Runtime v4 Host Activation APIs through simple shim functions.
-
-#ifndef __LEGACYACTIVATIONSHIM_H__
-#define __LEGACYACTIVATIONSHIM_H__
-
-#pragma warning(push)
-#pragma warning(disable:4127) // warning C4127: conditional expression is constant
- // caused by IfHrFailRet's while(0) code.
-#pragma warning(disable:4917) // a GUID can only be associated with a class, interface or namespace
-#pragma warning(disable:4191) // 'reinterpret_cast' : unsafe conversion from 'FARPROC' to 'XXX'
-
-#ifdef _MANAGED
-// We are compiling Managed C++, switch to native code then (and store current managed/native status on the stack)
-#pragma managed(push, off)
-#endif //_MANAGED
-
-#include "mscoree.h"
-#include "metahost.h"
-
-#include "wchar.h"
-
-#include "corerror.h"
-
-// To minimize how much we perturb sources that we are included in, we make sure that
-// all macros we define/redefine are restored at the end of the header.
-#pragma push_macro("IfHrFailRet")
-#pragma push_macro("IfHrFailRetFALSE")
-#pragma push_macro("IfHrFailRetVOID")
-
-// ---IfHrFailRet------------------------------------------------------------------------------------
-#undef IfHrFailRet
-#undef IfHrFailRetFALSE
-#undef IfHrFailRetVOID
-#define IfHrFailRet(EXPR) do { hr = (EXPR); if(FAILED(hr)) { return (hr); } } while (0)
-#define IfHrFailRetFALSE(EXPR) do { HRESULT _hr_ = (EXPR); if(FAILED(_hr_)) { return false; } } while (0)
-#define IfHrFailRetVOID(EXPR) do { HRESULT _hr_ = (EXPR); if(FAILED(_hr_)) { return; } } while (0)
-
-#include "legacyactivationshimutil.h"
-
-// Use of deprecated APIs within LegacyActivationShim namespace will result in C4996 that we will
-// disable for our own use.
-#pragma warning(push)
-#pragma warning(disable:4996)
-// ---LEGACYACTIVATONSHIM NAMESPACE----------------------------------------------------------------
-namespace LegacyActivationShim
-{
- // ---HELPERS----------------------------------------------------------------------------------
-#define GET_CLRMETAHOST(x) \
- ICLRMetaHost *x = NULL; \
- IfHrFailRet(Util::GetCLRMetaHost(&x))
-
-#define GET_CLRMETAHOSTPOLICY(x) \
- ICLRMetaHostPolicy*x = NULL; \
- IfHrFailRet(Util::GetCLRMetaHostPolicy(&x))
-
-#define GET_CLRINFO(x) \
- ICLRRuntimeInfo *x = NULL; \
- IfHrFailRet(Util::GetCLRRuntimeInfo(&x))
-
-#define LEGACY_API_PASS_THROUGH_STATIC(_name, _ret_type, _ret_value, _sig, _args) \
- { \
- hr = S_OK; \
- _ret_value = ::_name _args; \
- }
-
-#define LEGACY_API_PASS_THROUGH_STATIC_VOIDRET(_name, _sig, _args) \
- { \
- ::_name _args; \
- }
-
-#define LEGACY_API_PASS_THROUGH_DELAYLOAD(_name, _ret_type, _ret_value, _sig, _args) \
- { \
- typedef _ret_type __stdcall t_FN _sig; \
- Util::MscoreeFunctor<t_FN> FN; \
- if (SUCCEEDED(hr = FN.Init(#_name))) { \
- _ret_value = FN()_args; \
- } \
- }
-
-#define LEGACY_API_PASS_THROUGH_DELAYLOAD_VOIDRET(_name, _sig, _args) \
- { \
- typedef void __stdcall t_FN _sig; \
- Util::MscoreeFunctor<t_FN> FN; \
- if (SUCCEEDED(FN.Init(#_name))) { \
- FN()_args; \
- } \
- }
-
-#ifndef LEGACY_ACTIVATION_SHIM_DELAY_LOAD
-#define CALL_LEGACY_API(_name, _sig, _args) \
- LEGACY_API_PASS_THROUGH_STATIC(_name, HRESULT, hr, _sig, _args)
-#define CALL_LEGACY_API_VOIDRET(_name, _sig, _args) \
- LEGACY_API_PASS_THROUGH_STATIC_VOIDRET(_name, _sig, _args)
-#else
-#define CALL_LEGACY_API(_name, _sig, _args) \
- LEGACY_API_PASS_THROUGH_DELAYLOAD(_name, HRESULT, hr, _sig, _args)
-#define CALL_LEGACY_API_VOIDRET(_name, _sig, _args) \
- LEGACY_API_PASS_THROUGH_DELAYLOAD_VOIDRET(_name, _sig, _args)
-#endif
-
- // ---LEGACY SHIM FUNCTIONS--------------------------------------------------------------------
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT GetCORSystemDirectory(
- __out_ecount(cchBuffer) LPWSTR pBuffer,
- __in DWORD cchBuffer,
- __out DWORD *pdwLength)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- DWORD dwLengthDummy = cchBuffer;
- if (pdwLength == NULL)
- pdwLength = &dwLengthDummy;
- else
- *pdwLength = cchBuffer;
-
- GET_CLRINFO(pInfo);
- IfHrFailRet(pInfo->GetRuntimeDirectory(pBuffer, pdwLength));
- }
- else
- {
- CALL_LEGACY_API(GetCORSystemDirectory,
- (LPWSTR pBuffer,
- DWORD cchBuffer,
- DWORD *pdwLength),
- (pBuffer,
- cchBuffer,
- pdwLength));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT GetCORVersion(
- __out_ecount(cchBuffer) LPWSTR pbBuffer,
- __in DWORD cchBuffer,
- __out DWORD *pdwLength)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- DWORD dwLengthDummy = cchBuffer;
- if (pdwLength == NULL)
- pdwLength = &dwLengthDummy;
- else
- *pdwLength = cchBuffer;
-
- GET_CLRINFO(pInfo);
- IfHrFailRet(pInfo->GetVersionString(pbBuffer, pdwLength));
- }
- else
- {
- CALL_LEGACY_API(GetCORVersion,
- (LPWSTR pbBuffer,
- DWORD cchBuffer,
- DWORD *pdwLength),
- (pbBuffer,
- cchBuffer,
- pdwLength));
-
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT GetFileVersion(
- __in LPCWSTR szFileName,
- __out_ecount(cchBuffer) LPWSTR szBuffer,
- __in DWORD cchBuffer,
- __out DWORD *pdwLength)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- DWORD dwLengthDummy = cchBuffer;
- if (pdwLength == NULL)
- pdwLength = &dwLengthDummy;
- else
- *pdwLength = cchBuffer;
-
- GET_CLRMETAHOST(pMH);
- IfHrFailRet(pMH->GetVersionFromFile(szFileName, szBuffer, pdwLength));
- }
- else
- {
- CALL_LEGACY_API(GetFileVersion,
- (LPCWSTR szFileName,
- LPWSTR szBuffer,
- DWORD cchBuffer,
- DWORD *pdwLength),
- (szFileName,
- szBuffer,
- cchBuffer,
- pdwLength));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT GetCORRequiredVersion(
- __out_ecount(cchBuffer) LPWSTR pBuffer,
- __in DWORD cchBuffer,
- __out DWORD *pdwLength)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- DWORD dwLengthDummy = cchBuffer;
- if (pdwLength == NULL)
- pdwLength = &dwLengthDummy;
- else
- *pdwLength = cchBuffer;
-
- IfHrFailRet(Util::GetConfigImageVersion(pBuffer, pdwLength));
- }
- else
- {
- CALL_LEGACY_API(GetCORRequiredVersion,
- (LPWSTR pBuffer,
- DWORD cchBuffer,
- DWORD *pdwLength),
- (pBuffer,
- cchBuffer,
- pdwLength));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- // This API is the one exception that we don't have fully equivalent functionality for
- // in the new APIs. Specifically, we do not have the runtimeInfoFlags equivalent that
- // allows platform differentiation. As such, we just send the call to the legacy API,
- // which does not bind (thankfully) and so we do not cap this specific API to Whidbey.
- inline
- HRESULT GetRequestedRuntimeInfo(
- __in_opt LPCWSTR pExe,
- __in_opt LPCWSTR pwszVersion,
- __in_opt LPCWSTR pConfigurationFile,
- __in DWORD startupFlags,
- __in DWORD runtimeInfoFlags,
- __out_ecount(dwDirectory) LPWSTR pDirectory,
- __in DWORD dwDirectory,
- __out DWORD *pdwDirectoryLength,
- __out_ecount(cchBuffer) LPWSTR pVersion,
- __in DWORD cchBuffer,
- __out DWORD *pdwLength)
- {
- HRESULT hr = S_OK;
-
- CALL_LEGACY_API(GetRequestedRuntimeInfo,
- (LPCWSTR pExe,
- LPCWSTR pwszVersion,
- LPCWSTR pConfigurationFile,
- DWORD startupFlags,
- DWORD runtimeInfoFlags,
- LPWSTR pDirectory,
- DWORD dwDirectory,
- DWORD *pdwDirectoryLength,
- LPWSTR pVersion,
- DWORD cchBuffer,
- DWORD *pdwLength),
- (pExe,
- pwszVersion,
- pConfigurationFile,
- startupFlags,
- runtimeInfoFlags,
- pDirectory,
- dwDirectory,
- pdwDirectoryLength,
- pVersion,
- cchBuffer,
- pdwLength));
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT GetRequestedRuntimeVersion(
- __in LPWSTR pExe,
- __out_ecount(cchBuffer) LPWSTR pVersion,
- __in DWORD cchBuffer,
- __out DWORD *pdwLength)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- DWORD dwLengthDummy = cchBuffer;
- if (pdwLength == NULL)
- pdwLength = &dwLengthDummy;
- else
- *pdwLength = cchBuffer;
-
- GET_CLRMETAHOSTPOLICY(pMHP);
- ICLRRuntimeInfo *pInfo = NULL;
- IfHrFailRet(pMHP->GetRequestedRuntime(
- METAHOST_POLICY_USE_PROCESS_IMAGE_PATH,
- pExe,
- NULL, // config stream
- pVersion,
- pdwLength,
- NULL, // image version str
- NULL, // image version len
- NULL,
- IID_ICLRRuntimeInfo,
- reinterpret_cast<LPVOID*>(&pInfo)));// ppRuntime
- Util::ReleaseHolder<ICLRRuntimeInfo*> hInfo(pInfo);
- }
- else
- {
- CALL_LEGACY_API(GetRequestedRuntimeVersion,
- (LPWSTR pExe,
- LPWSTR pVersion,
- DWORD cchBuffer,
- DWORD *pdwLength),
- (pExe,
- pVersion,
- cchBuffer,
- pdwLength));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT CorBindToRuntimeHost(
- LPCWSTR pwszVersion,
- LPCWSTR pwszBuildFlavor,
- LPCWSTR pwszHostConfigFile,
- VOID* pReserved,
- DWORD startupFlags,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID FAR *ppv)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- IStream *pConfigStream = NULL;
- Util::ReleaseHolder<IStream*> hConfigStream;
- if (pwszHostConfigFile != NULL)
- {
- IfHrFailRet(Util::CreateIStreamFromFile(pwszHostConfigFile, &pConfigStream));
- hConfigStream.Assign(pConfigStream);
- }
-
- WCHAR wszVersionLocal[512];
- DWORD cchVersionLocal = 512;
- if (pwszVersion != NULL)
- wcsncpy_s(&wszVersionLocal[0], cchVersionLocal, pwszVersion, _TRUNCATE);
-
- ICLRRuntimeInfo *pInfo = NULL;
- IfHrFailRet(Util::GetCLRRuntimeInfo(
- &pInfo,
- NULL,
- pConfigStream,
- pwszVersion == NULL ? NULL : &wszVersionLocal[0],
- pwszVersion == NULL ? NULL : &cchVersionLocal));
-
- // We're intentionally ignoring the HRESULT return value, since CorBindToRuntimeEx
- // always ignored these flags when a runtime had already been bound, and we need
- // to emulate that behavior for when multiple calls to CorBindToRuntimeEx are made
- // but with different startup flags (ICLRRuntimeInfo::SetDefaultStartupFlags will
- // return E_INVALIDARG in the case that the runtime has already been started with
- // different flags).
- Util::AddStartupFlags(pInfo, pwszBuildFlavor, startupFlags, pwszHostConfigFile);
-
- IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
- }
- else
- {
- CALL_LEGACY_API(CorBindToRuntimeHost,
- (LPCWSTR pwszVersion,
- LPCWSTR pwszBuildFlavor,
- LPCWSTR pwszHostConfigFile,
- VOID* pReserved,
- DWORD startupFlags,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID FAR *ppv),
- (pwszVersion,
- pwszBuildFlavor,
- pwszHostConfigFile,
- pReserved,
- startupFlags,
- rclsid,
- riid,
- ppv));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT CorBindToRuntimeEx(
- LPCWSTR pwszVersion,
- LPCWSTR pwszBuildFlavor,
- DWORD startupFlags,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID* ppv)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- WCHAR wszVersionLocal[512];
- DWORD cchVersionLocal = 512;
- if (pwszVersion != NULL)
- wcsncpy_s(&wszVersionLocal[0], cchVersionLocal, pwszVersion, _TRUNCATE);
-
- ICLRRuntimeInfo *pInfo = NULL;
- IfHrFailRet(Util::GetCLRRuntimeInfo(
- &pInfo,
- NULL, // exe path
- NULL, // config stream
- pwszVersion == NULL ? NULL : &wszVersionLocal[0],
- pwszVersion == NULL ? NULL : &cchVersionLocal));
-
- // We're intentionally ignoring the HRESULT return value, since CorBindToRuntimeEx
- // always ignored these flags when a runtime had already been bound, and we need
- // to emulate that behavior for when multiple calls to CorBindToRuntimeEx are made
- // but with different startup flags (ICLRRuntimeInfo::SetDefaultStartupFlags will
- // return E_INVALIDARG in the case that the runtime has already been started with
- // different flags).
- Util::AddStartupFlags(pInfo, pwszBuildFlavor, startupFlags, NULL);
-
- IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
- }
- else
- {
- CALL_LEGACY_API(CorBindToRuntimeEx,
- (LPCWSTR pwszVersion,
- LPCWSTR pwszBuildFlavor,
- DWORD startupFlags,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID* ppv),
- (pwszVersion,
- pwszBuildFlavor,
- startupFlags,
- rclsid,
- riid,
- ppv));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT CorBindToRuntimeByCfg(
- IStream* pCfgStream,
- DWORD reserved,
- DWORD startupFlags,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID* ppv)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- // The legacy CorBindToRuntimeByCfg picks up startup flags from both the config stream and
- // application config file if it is present. For simplicity, we ignore the app config here.
- ICLRRuntimeInfo *pInfo = NULL;
- IfHrFailRet(Util::GetCLRRuntimeInfo(
- &pInfo,
- NULL, // exe path
- pCfgStream));
-
- // We're intentionally ignoring the HRESULT return value, since CorBindToRuntimeEx
- // always ignored these flags when a runtime had already been bound, and we need
- // to emulate that behavior for when multiple calls to CorBindToRuntimeEx are made
- // but with different startup flags (ICLRRuntimeInfo::SetDefaultStartupFlags will
- // return E_INVALIDARG in the case that the runtime has already been started with
- // different flags).
- Util::AddStartupFlags(pInfo, NULL, startupFlags, NULL);
-
- IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
- }
- else
- {
- CALL_LEGACY_API(CorBindToRuntimeByCfg,
- (IStream* pCfgStream,
- DWORD reserved,
- DWORD startupFlags,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID* ppv),
- (pCfgStream,
- reserved,
- startupFlags,
- rclsid,
- riid,
- ppv));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT CorBindToRuntime(
- LPCWSTR pwszVersion,
- LPCWSTR pwszBuildFlavor,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID* ppv)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- WCHAR wszVersionLocal[512];
- DWORD cchVersionLocal = 512;
- if (pwszVersion != NULL)
- wcsncpy_s(&wszVersionLocal[0], cchVersionLocal, pwszVersion, _TRUNCATE);
-
- ICLRRuntimeInfo *pInfo = NULL;
- IfHrFailRet(Util::GetCLRRuntimeInfo(
- &pInfo,
- NULL, // exe path
- NULL, // config stream
- pwszVersion == NULL ? NULL : &wszVersionLocal[0],
- pwszVersion == NULL ? NULL : &cchVersionLocal));
-
- // CorBindToRuntime has its special default flags
- //
- // We're intentionally ignoring the HRESULT return value, since CorBindToRuntimeEx
- // always ignored these flags when a runtime had already been bound, and we need
- // to emulate that behavior for when multiple calls to CorBindToRuntimeEx are made
- // but with different startup flags (ICLRRuntimeInfo::SetDefaultStartupFlags will
- // return E_INVALIDARG in the case that the runtime has already been started with
- // different flags).
- Util::AddStartupFlags(pInfo, NULL, STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST, NULL);
-
- IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
- }
- else
- {
- CALL_LEGACY_API(CorBindToRuntime,
- (LPCWSTR pwszVersion,
- LPCWSTR pwszBuildFlavor,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID* ppv),
- (pwszVersion,
- pwszBuildFlavor,
- rclsid,
- riid,
- ppv));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT CorBindToCurrentRuntime(
- LPCWSTR pwszFileName,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID FAR *ppv)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- ICLRRuntimeInfo *pInfo = NULL;
- IfHrFailRet(Util::GetCLRRuntimeInfo(
- &pInfo,
- pwszFileName));
-
- IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
- }
- else
- {
- CALL_LEGACY_API(CorBindToCurrentRuntime,
- (LPCWSTR pwszFileName,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID FAR *ppv),
- (pwszFileName,
- rclsid,
- riid,
- ppv));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT ClrCreateManagedInstance(
- LPCWSTR pTypeName,
- REFIID riid,
- void **ppObject)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- GET_CLRINFO(pInfo);
- HRESULT (STDMETHODCALLTYPE *pfnClrCreateManagedInstance)(LPCWSTR typeName, REFIID riid, void ** ppv) = NULL;
- IfHrFailRet(pInfo->GetProcAddress("ClrCreateManagedInstance", (LPVOID *)&pfnClrCreateManagedInstance));
- IfHrFailRet(pfnClrCreateManagedInstance(pTypeName, riid, ppObject));
- }
- else
- {
- CALL_LEGACY_API(ClrCreateManagedInstance,
- (LPCWSTR pTypeName,
- REFIID riid,
- void **ppObject),
- (pTypeName,
- riid,
- ppObject));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT LoadLibraryShim(
- LPCWSTR szDllName,
- LPCWSTR szVersion,
- LPVOID pvReserved,
- HMODULE *phModDll)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- Util::ReleaseHolder<ICLRRuntimeInfo*> hInfo;
- ICLRRuntimeInfo *pInfo = NULL;
-
- // Semantics of LoadLibraryShim is that a non-null version must match exactly.
- if (szVersion != NULL)
- {
- GET_CLRMETAHOST(pMH);
- IfHrFailRet(pMH->GetRuntime(szVersion, IID_ICLRRuntimeInfo, reinterpret_cast<LPVOID*>(&pInfo)));
- hInfo.Assign(pInfo);
- }
- else
- {
- IfHrFailRet(Util::GetCLRRuntimeInfo(&pInfo));
- }
- IfHrFailRet(pInfo->LoadLibrary(szDllName, phModDll));
- }
- else
- {
- CALL_LEGACY_API(LoadLibraryShim,
- (LPCWSTR szDllName,
- LPCWSTR szVersion,
- LPVOID pvReserved,
- HMODULE *phModDll),
- (szDllName,
- szVersion,
- pvReserved,
- phModDll));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT CallFunctionShim(
- LPCWSTR szDllName,
- LPCSTR szFunctionName,
- LPVOID lpvArgument1,
- LPVOID lpvArgument2,
- LPCWSTR szVersion,
- LPVOID pvReserved)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- HMODULE hMod = NULL;
- HRESULT (__stdcall * pfn)(LPVOID,LPVOID) = NULL;
-
- // Load library
- IfHrFailRet(LegacyActivationShim::LoadLibraryShim(szDllName, szVersion, pvReserved, &hMod));
-
- // NOTE: Legacy CallFunctionShim does not release HMODULE, leak to maintain compat
- // Util::HMODULEHolder hModHolder(hMod);
-
- // Find function.
- pfn = (HRESULT (__stdcall *)(LPVOID,LPVOID))GetProcAddress(hMod, szFunctionName);
- if (pfn == NULL)
- return HRESULT_FROM_WIN32(GetLastError());
-
- // Call it.
- return pfn(lpvArgument1, lpvArgument2);
- }
- else
- {
- CALL_LEGACY_API(CallFunctionShim,
- (LPCWSTR szDllName,
- LPCSTR szFunctionName,
- LPVOID lpvArgument1,
- LPVOID lpvArgument2,
- LPCWSTR szVersion,
- LPVOID pvReserved),
- (szDllName,
- szFunctionName,
- lpvArgument1,
- lpvArgument2,
- szVersion,
- pvReserved));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT GetRealProcAddress(
- LPCSTR pwszProcName,
- VOID **ppv)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- GET_CLRINFO(pInfo);
- IfHrFailRet(pInfo->GetProcAddress(pwszProcName, ppv));
- }
- else
- {
- CALL_LEGACY_API(GetRealProcAddress,
- (LPCSTR pwszProcName,
- VOID **ppv),
- (pwszProcName,
- ppv));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- void CorExitProcess(
- int exitCode)
- {
-#ifndef LEGACY_ACTIVATION_SHIM_DELAY_LOAD
- ::CorExitProcess(exitCode);
-#else
- typedef void __stdcall t_CorExitProcess(
- int exitCode);
-
- Util::MscoreeFunctor<t_CorExitProcess> FN;
- if (FAILED(FN.Init("CorExitProcess")))
- return;
-
- FN()(exitCode);
-#endif
- }
-
-// Define this method only if it is not yet defined as macro (see ndp\clr\src\inc\UtilCode.h).
-#ifndef LoadStringRC
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT LoadStringRC(
- UINT nResourceID,
- __out_ecount(nMax) LPWSTR szBuffer,
- int nMax,
- int fQuiet)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- GET_CLRINFO(pInfo);
- DWORD cchMax = static_cast<DWORD>(nMax);
- IfHrFailRet(pInfo->LoadErrorString(nResourceID, szBuffer, &cchMax, -1));
- }
- else
- {
- CALL_LEGACY_API(LoadStringRC,
- (UINT nResourceID,
- LPWSTR szBuffer,
- int nMax,
- int fQuiet),
- (nResourceID,
- szBuffer,
- nMax,
- fQuiet));
- }
-
- return hr;
- }
-#endif //LoadStringRC
-
-// Define this method only if it is not yet defined as macro (see ndp\clr\src\inc\UtilCode.h).
-#if !defined(LoadStringRCEx) && !defined(FEATURE_CORESYSTEM)
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT LoadStringRCEx(
- LCID lcid,
- UINT nResourceID,
- __out_ecount(nMax) LPWSTR szBuffer,
- int nMax,
- int fQuiet,
- int *pcwchUsed)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- GET_CLRINFO(pInfo);
- DWORD cchUsed = static_cast<DWORD>(nMax);
- IfHrFailRet(pInfo->LoadErrorString(nResourceID, szBuffer, &cchUsed, lcid));
- *pcwchUsed = cchUsed;
- }
- else
- {
- CALL_LEGACY_API(LoadStringRCEx,
- (LCID lcid,
- UINT nResourceID,
- LPWSTR szBuffer,
- int nMax,
- int fQuiet,
- int *pcwchUsed),
- (lcid,
- nResourceID,
- szBuffer,
- nMax,
- fQuiet,
- pcwchUsed));
- }
-
- return hr;
- }
-#endif //LoadStringRCEx
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT LockClrVersion(
- FLockClrVersionCallback hostCallback,
- FLockClrVersionCallback *pBeginHostSetup,
- FLockClrVersionCallback *pEndHostSetup)
- {
- HRESULT hr = S_OK;
-
- CALL_LEGACY_API(LockClrVersion,
- (FLockClrVersionCallback hostCallback,
- FLockClrVersionCallback *pBeginHostSetup,
- FLockClrVersionCallback *pEndHostSetup),
- (hostCallback,
- pBeginHostSetup,
- pEndHostSetup));
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT CreateDebuggingInterfaceFromVersion(
- int nDebuggerVersion,
- LPCWSTR szDebuggeeVersion,
- IUnknown ** ppCordb)
- {
- HRESULT hr = S_OK;
-
- CALL_LEGACY_API(CreateDebuggingInterfaceFromVersion,
- (int nDebuggerVersion,
- LPCWSTR szDebuggeeVersion,
- IUnknown ** ppCordb),
- (nDebuggerVersion,
- szDebuggeeVersion,
- ppCordb));
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT GetVersionFromProcess(
- __in HANDLE hProcess,
- __out_ecount(cchBuffer) LPWSTR pVersion,
- __in DWORD cchBuffer,
- __out DWORD *pdwLength)
- {
- HRESULT hr = S_OK;
-
- CALL_LEGACY_API(GetVersionFromProcess,
- (HANDLE hProcess,
- LPWSTR pVersion,
- DWORD cchBuffer,
- DWORD *pdwLength),
- (hProcess,
- pVersion,
- cchBuffer,
- pdwLength));
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
-// CoInitializeEE is declared in cor.h, define it only if explicitly requested
-#ifdef LEGACY_ACTIVATION_SHIM_DEFINE_CoInitializeEE
- inline
- HRESULT CoInitializeEE(DWORD flags)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- GET_CLRINFO(pInfo);
- HRESULT (* pfnCoInitializeEE)(DWORD);
- IfHrFailRet(pInfo->GetProcAddress("CoInitializeEE", (LPVOID *)&pfnCoInitializeEE));
- return (*pfnCoInitializeEE)(flags);
- }
- else
- {
- CALL_LEGACY_API(CoInitializeEE,
- (DWORD flags),
- (flags));
- }
-
- return hr;
- }
-
- inline
- VOID CoUninitializeEE(BOOL flags)
- {
- if (Util::HasNewActivationAPIs())
- {
- ICLRRuntimeInfo *pInfo = NULL;
- if (FAILED(Util::GetCLRRuntimeInfo(&pInfo)))
- return;
-
- VOID (* pfnCoUninitializeEE)(BOOL);
- if (FAILED(pInfo->GetProcAddress("CoUninitializeEE", (LPVOID *)&pfnCoUninitializeEE)))
- return;
-
- (*pfnCoUninitializeEE)(flags);
- }
- else
- {
- CALL_LEGACY_API_VOIDRET(CoUninitializeEE,
- (BOOL flags),
- (flags));
- }
- }
-
- inline
- HRESULT CoInitializeCor(DWORD flags)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- GET_CLRINFO(pInfo);
- HRESULT (* pfnCoInitializeCor)(DWORD);
- IfHrFailRet(pInfo->GetProcAddress("CoInitializeCor", (LPVOID *)&pfnCoInitializeCor));
- return (*pfnCoInitializeCor)(flags);
- }
- else
- {
- CALL_LEGACY_API(CoInitializeCor,
- (DWORD flags),
- (flags));
- }
-
- return hr;
- }
-
- inline
- VOID CoUninitializeCor()
- {
- if (Util::HasNewActivationAPIs())
- {
- ICLRRuntimeInfo *pInfo = NULL;
- if (FAILED(Util::GetCLRRuntimeInfo(&pInfo)))
- return;
-
- VOID (* pfnCoUninitializeCor)();
- if (FAILED(pInfo->GetProcAddress("CoUninitializeCor", (LPVOID *)&pfnCoUninitializeCor)))
- return;
-
- (*pfnCoUninitializeCor)();
- }
- else
- {
- CALL_LEGACY_API_VOIDRET(CoUninitializeCor,
- (VOID),
- ());
- }
- }
-
-#endif //LEGACY_ACTIVATION_SHIM_DEFINE_CoInitializeEE
-
- // --------------------------------------------------------------------------------------------
-// CoEEShutDownCOM is declared in cor.h, define it only if explicitly requested
-#ifdef LEGACY_ACTIVATION_SHIM_DEFINE_CoEEShutDownCOM
- inline
- void CoEEShutDownCOM()
- {
- if (Util::HasNewActivationAPIs())
- {
- ICLRRuntimeInfo *pInfo = NULL;
- IfHrFailRetVOID(Util::GetCLRRuntimeInfo(&pInfo));
- void (* pfnCoEEShutDownCOM)();
- IfHrFailRetVOID(pInfo->GetProcAddress("CoEEShutDownCOM", (LPVOID *)&pfnCoEEShutDownCOM));
- (*pfnCoEEShutDownCOM)();
- }
- else
- {
- CALL_LEGACY_API_VOIDRET(CoEEShutDownCOM,
- (),
- ());
- }
-
- return;
- }
-#endif //LEGACY_ACTIVATION_SHIM_DEFINE_CoEEShutDownCOM
-
- // ---StrongName Function Helpers--------------------------------------------------------------
-#if !defined(LEGACY_ACTIVATION_SHIM_DELAY_LOAD) && defined(__STRONG_NAME_H)
-#define LEGACY_STRONGNAME_API_PASS_THROUGH(_name, _ret_type, _ret_value, _sig, _args) \
- LEGACY_API_PASS_THROUGH_STATIC(_name, _ret_type, _ret_value, _sig, _args)
-#define LEGACY_STRONGNAME_API_PASS_THROUGH_VOIDRET(_name, _sig, _args) \
- LEGACY_API_PASS_THROUGH_STATIC_VOIDRET(_name, _sig, _args)
-#else //defined(LEGACY_ACTIVATION_SHIM_DELAY_LOAD) || !defined(__STRONG_NAME_H)
-#define LEGACY_STRONGNAME_API_PASS_THROUGH(_name, _ret_type, _ret_value, _sig, _args) \
- LEGACY_API_PASS_THROUGH_DELAYLOAD(_name, _ret_type, _ret_value, _sig, _args)
-#define LEGACY_STRONGNAME_API_PASS_THROUGH_VOIDRET(_name, _sig, _args) \
- LEGACY_API_PASS_THROUGH_DELAYLOAD_VOIDRET(_name, _sig, _args)
-#endif //defined(LEGACY_ACTIVATION_SHIM_DELAY_LOAD) || !defined(__STRONG_NAME_H)
-
-// Defines a method that just delegates a call to the right runtime, this one is for SN APIs that
-// return HRESULT.
-#define PASS_THROUGH_IMPL_HRESULT(_name, _signature, _args) \
- inline \
- HRESULT _name##_signature \
- { \
- HRESULT hr = S_OK; \
- if (Util::HasNewActivationAPIs()) \
- { \
- ICLRStrongName *pSN = NULL; \
- IfHrFailRet(Util::GetCLRStrongName(&pSN)); \
- IfHrFailRet(pSN->_name _args); \
- } \
- else \
- { \
- LEGACY_STRONGNAME_API_PASS_THROUGH( \
- _name, HRESULT, hr, _signature, _args); \
- IfHrFailRet(hr); \
- } \
- return hr; \
- }
-
-// Defines a method that just delegates a call to the right runtime, this one is for SN APIs that
-// return BOOL.
-#define PASS_THROUGH_IMPL_BOOLEAN(_name, _signature, _args) \
- inline \
- BOOL _name##_signature \
- { \
- HRESULT hr = S_OK; \
- if (Util::HasNewActivationAPIs()) \
- { \
- ICLRStrongName *pSN = NULL; \
- IfHrFailRetFALSE(Util::GetCLRStrongName(&pSN)); \
- IfHrFailRetFALSE(pSN->_name _args); \
- return TRUE; \
- } \
- else \
- { \
- BOOL fResult = TRUE; \
- LEGACY_STRONGNAME_API_PASS_THROUGH( \
- _name, BOOL, fResult, _signature, _args); \
- IfHrFailRetFALSE(hr); \
- return fResult; \
- } \
- }
-
-// Defines a method that just delegates a call to the right runtime, this one is for SN APIs that
-// return VOID.
-#define PASS_THROUGH_IMPL_VOID(_name, _signature, _args) \
- inline \
- VOID _name##_signature \
- { \
- HRESULT hr = S_OK; \
- if (Util::HasNewActivationAPIs()) \
- { \
- ICLRStrongName *pSN = NULL; \
- IfHrFailRetVOID(Util::GetCLRStrongName(&pSN)); \
- IfHrFailRetVOID(pSN->_name _args); \
- return; \
- } \
- else \
- { \
- LEGACY_STRONGNAME_API_PASS_THROUGH_VOIDRET( \
- _name, _signature, _args); \
- IfHrFailRetVOID(hr); \
- return; \
- } \
- }
-
- // ---StrongName functions---------------------------------------------------------------------
-
-PASS_THROUGH_IMPL_HRESULT(GetHashFromAssemblyFile,
- (LPCSTR pszFilePath, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
- (pszFilePath, piHashAlg, pbHash, cchHash, pchHash));
-
-PASS_THROUGH_IMPL_HRESULT(GetHashFromAssemblyFileW,
- (LPCWSTR pwzFilePath, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
- (pwzFilePath, piHashAlg, pbHash, cchHash, pchHash));
-
-PASS_THROUGH_IMPL_HRESULT(GetHashFromBlob,
- (BYTE *pbBlob, DWORD cchBlob, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
- (pbBlob, cchBlob, piHashAlg, pbHash, cchHash, pchHash));
-
-PASS_THROUGH_IMPL_HRESULT(GetHashFromFile,
- (LPCSTR pszFilePath, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
- (pszFilePath, piHashAlg, pbHash, cchHash, pchHash));
-
-PASS_THROUGH_IMPL_HRESULT(GetHashFromFileW,
- (LPCWSTR pwzFilePath, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
- (pwzFilePath, piHashAlg, pbHash, cchHash, pchHash));
-
-PASS_THROUGH_IMPL_HRESULT(GetHashFromHandle,
- (HANDLE hFile, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
- (hFile, piHashAlg, pbHash, cchHash, pchHash));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameCompareAssemblies,
- (LPCWSTR pwzAssembly1, LPCWSTR pwzAssembly2, DWORD *pdwResult),
- (pwzAssembly1, pwzAssembly2, pdwResult));
-
-PASS_THROUGH_IMPL_VOID(StrongNameFreeBuffer,
- (BYTE *pbMemory),
- (pbMemory));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameGetBlob,
- (LPCWSTR pwzFilePath, BYTE *pbBlob, DWORD *pcbBlob),
- (pwzFilePath, pbBlob, pcbBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameGetBlobFromImage,
- (BYTE *pbBase, DWORD dwLength, BYTE *pbBlob, DWORD *pcbBlob),
- (pbBase, dwLength, pbBlob, pcbBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameGetPublicKey,
- (LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbPublicKeyBlob, ULONG *pcbPublicKeyBlob),
- (pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbPublicKeyBlob, pcbPublicKeyBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameHashSize,
- (ULONG ulHashAlg, DWORD *pcbSize),
- (ulHashAlg, pcbSize));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameKeyDelete,
- (LPCWSTR pwzKeyContainer),
- (pwzKeyContainer));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameKeyGen,
- (LPCWSTR pwzKeyContainer, DWORD dwFlags, BYTE **ppbKeyBlob, ULONG *pcbKeyBlob),
- (pwzKeyContainer, dwFlags, ppbKeyBlob, pcbKeyBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameKeyGenEx,
- (LPCWSTR pwzKeyContainer, DWORD dwFlags, DWORD dwKeySize, BYTE **ppbKeyBlob, ULONG *pcbKeyBlob),
- (pwzKeyContainer, dwFlags, dwKeySize, ppbKeyBlob, pcbKeyBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameKeyInstall,
- (LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob),
- (pwzKeyContainer, pbKeyBlob, cbKeyBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureGeneration,
- (LPCWSTR pwzFilePath, LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbSignatureBlob, ULONG *pcbSignatureBlob),
- (pwzFilePath, pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbSignatureBlob, pcbSignatureBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureGenerationEx,
- (LPCWSTR wszFilePath, LPCWSTR wszKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbSignatureBlob, ULONG *pcbSignatureBlob, DWORD dwFlags),
- (wszFilePath, wszKeyContainer, pbKeyBlob, cbKeyBlob, ppbSignatureBlob, pcbSignatureBlob, dwFlags));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureSize,
- (BYTE *pbPublicKeyBlob, ULONG cbPublicKeyBlob, DWORD *pcbSize),
- (pbPublicKeyBlob, cbPublicKeyBlob, pcbSize));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureVerification,
- (LPCWSTR pwzFilePath, DWORD dwInFlags, DWORD *pdwOutFlags),
- (pwzFilePath, dwInFlags, pdwOutFlags));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureVerificationEx,
- (LPCWSTR pwzFilePath, BOOLEAN fForceVerification, BOOLEAN *pfWasVerified),
- (pwzFilePath, fForceVerification, pfWasVerified));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureVerificationFromImage,
- (BYTE *pbBase, DWORD dwLength, DWORD dwInFlags, DWORD *pdwOutFlags),
- (pbBase, dwLength, dwInFlags, pdwOutFlags));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameTokenFromAssembly,
- (LPCWSTR pwzFilePath, BYTE **ppbStrongNameToken, ULONG *pcbStrongNameToken),
- (pwzFilePath, ppbStrongNameToken, pcbStrongNameToken));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameTokenFromAssemblyEx,
- (LPCWSTR pwzFilePath, BYTE **ppbStrongNameToken, ULONG *pcbStrongNameToken, BYTE **ppbPublicKeyBlob, ULONG *pcbPublicKeyBlob),
- (pwzFilePath, ppbStrongNameToken, pcbStrongNameToken, ppbPublicKeyBlob, pcbPublicKeyBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameTokenFromPublicKey,
- (BYTE *pbPublicKeyBlob, ULONG cbPublicKeyBlob, BYTE **ppbStrongNameToken, ULONG *pcbStrongNameToken),
- (pbPublicKeyBlob, cbPublicKeyBlob, ppbStrongNameToken, pcbStrongNameToken));
-
-#undef PASS_THROUGH_IMPL_HRESULT
-#undef PASS_THROUGH_IMPL_BOOLEAN
-#undef PASS_THROUGH_IMPL_VOID
-
-// Defines a method that just delegates a call to the right runtime, this one is for SN APIs that
-// return BOOLEAN.
-#define WRAP_HRESULT_IMPL_BOOLEAN(_WrapperName, _name, _signature, _args) \
- inline \
- HRESULT _WrapperName##_signature \
- { \
- HRESULT hr = S_OK; \
- if (Util::HasNewActivationAPIs()) \
- { \
- ICLRStrongName *pSN = NULL; \
- IfHrFailRet(Util::GetCLRStrongName(&pSN)); \
- return pSN->_name _args; \
- } \
- else \
- { \
- typedef BOOL __stdcall t_FN _signature; \
- Util::MscoreeFunctor<t_FN> FN; \
- IfHrFailRet(FN.Init(#_name)); \
- if ((FN() _args)) \
- { \
- return S_OK; \
- } \
- else \
- { /*@TODO: Static bind version, if necessary*/ \
- typedef DWORD __stdcall t_FNStrongNameErrorInfo(void); \
- Util::MscoreeFunctor<t_FNStrongNameErrorInfo> FNStrongNameErrorInfo; \
- IfHrFailRet(FNStrongNameErrorInfo.Init("StrongNameErrorInfo")); \
- HRESULT hrResult = (HRESULT)FNStrongNameErrorInfo() (); \
- if (SUCCEEDED(hrResult)) \
- { \
- hrResult = E_FAIL; \
- } \
- return hrResult; \
- } \
- } \
- }
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameHashSize_HRESULT,
- StrongNameHashSize,
- (ULONG ulHashAlg, DWORD *pcbSize),
- (ulHashAlg, pcbSize));
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameTokenFromPublicKey_HRESULT,
- StrongNameTokenFromPublicKey,
- (BYTE *pbPublicKeyBlob, ULONG cbPublicKeyBlob, BYTE **ppbStrongNameToken, ULONG *pcbStrongNameToken),
- (pbPublicKeyBlob, cbPublicKeyBlob, ppbStrongNameToken, pcbStrongNameToken));
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameSignatureSize_HRESULT,
- StrongNameSignatureSize,
- (BYTE *pbPublicKeyBlob, ULONG cbPublicKeyBlob, DWORD *pcbSize),
- (pbPublicKeyBlob, cbPublicKeyBlob, pcbSize));
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameGetPublicKey_HRESULT,
- StrongNameGetPublicKey,
- (LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbPublicKeyBlob, ULONG *pcbPublicKeyBlob),
- (pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbPublicKeyBlob, pcbPublicKeyBlob));
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameKeyInstall_HRESULT,
- StrongNameKeyInstall,
- (LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob),
- (pwzKeyContainer, pbKeyBlob, cbKeyBlob));
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameSignatureGeneration_HRESULT,
- StrongNameSignatureGeneration,
- (LPCWSTR pwzFilePath, LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbSignatureBlob, ULONG *pcbSignatureBlob),
- (pwzFilePath, pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbSignatureBlob, pcbSignatureBlob));
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameKeyGen_HRESULT,
- StrongNameKeyGen,
- (LPCWSTR pwzKeyContainer, DWORD dwFlags, BYTE **ppbKeyBlob, ULONG *pcbKeyBlob),
- (pwzKeyContainer, dwFlags, ppbKeyBlob, pcbKeyBlob));
-
-#undef WRAP_HRESULT_IMPL_BOOLEAN
-
-// Defines a method that just delegates a call to the right runtime, this one is for ICLRStrongName2
-// APIs that return BOOLEAN.
-#define WRAP_HRESULT_IMPL_BOOLEAN(_WrapperName, _name, _signature, _args) \
- inline \
- HRESULT _WrapperName##_signature \
- { \
- HRESULT hr = S_OK; \
- if (Util::HasNewActivationAPIs()) \
- { \
- ICLRStrongName2 *pSN = NULL; \
- IfHrFailRet(Util::GetCLRStrongName2(&pSN)); \
- return pSN->_name _args; \
- } \
- else \
- { \
- return E_FAIL; \
- } \
- }
-
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameGetPublicKeyEx_HRESULT,
- StrongNameGetPublicKeyEx,
- (LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbPublicKeyBlob, ULONG *pcbPublicKeyBlob, ULONG uHashAlgId, ULONG uReserved),
- (pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbPublicKeyBlob, pcbPublicKeyBlob, uHashAlgId, uReserved));
-
-#undef WRAP_HRESULT_IMPL_BOOLEAN
-
- inline
- HRESULT ClrCoCreateInstance(
- REFCLSID rclsid,
- LPUNKNOWN pUnkOuter,
- DWORD dwClsContext,
- REFIID riid,
- LPVOID * ppv)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs() /*&& Util::IsCLSIDHostedByClr(rclsid)*/)
- {
- GET_CLRINFO(pInfo);
- IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
- }
- else
- {
- IfHrFailRet(::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv));
- }
-
- return hr;
- }
-}; // namespace LegacyActivationShim
-#pragma warning(pop) // Revert C4996 status
-
-#undef LEGACY_API_PASS_THROUGH_STATIC
-#undef LEGACY_API_PASS_THROUGH_STATIC_VOIDRET
-#undef LEGACY_API_PASS_THROUGH_DELAYLOAD
-#undef LEGACY_API_PASS_THROUGH_DELAYLOAD_VOIDRET
-#undef CALL_LEGACY_API
-#undef LEGACY_STRONGNAME_API_PASS_THROUGH
-#undef LEGACY_STRONGNAME_API_PASS_THROUGH_VOIDRET
-
-#undef LEGACY_ACTIVATION_SHIM_DEFAULT_PRODUCT_VER_HELPER_L
-#undef LEGACY_ACTIVATION_SHIM_DEFAULT_PRODUCT_VER_STR_L
-
-#pragma pop_macro("IfHrFailRetVOID")
-#pragma pop_macro("IfHrFailRetFALSE")
-#pragma pop_macro("IfHrFailRet")
-
-#ifdef _MANAGED
-// We are compiling Managed C++, restore previous managed/native status from the stack
-#pragma managed(pop)
-#endif //_MANAGED
-
-#pragma warning(pop)
-
-#endif // __LEGACYACTIVATIONSHIM_H__
diff --git a/src/inc/legacyactivationshimdelayload.h b/src/inc/legacyactivationshimdelayload.h
deleted file mode 100644
index 8e77ff2ce3..0000000000
--- a/src/inc/legacyactivationshimdelayload.h
+++ /dev/null
@@ -1,13 +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.
-//
-
-#ifndef __LEGACYACTIVATIONSHIMDELAYLOAD_H__
-#define __LEGACYACTIVATIONSHIMDELAYLOAD_H__
-
-#define LEGACY_ACTIVATION_SHIM_DELAY_LOAD
-#include <legacyactivationshim.h>
-#undef LEGACY_ACTIVATION_SHIM_DELAY_LOAD
-
-#endif //__LEGACYACTIVATIONSHIMDELAYLOAD_H__
diff --git a/src/inc/loglf.h b/src/inc/loglf.h
index ea121cda7c..e7fbd519d9 100644
--- a/src/inc/loglf.h
+++ b/src/inc/loglf.h
@@ -4,39 +4,39 @@
// The code in sos.DumpLog depends on the first 32 facility codes
// being bit flags sorted in incresing order.
-DEFINE_LOG_FACILITY(LF_GC ,0x00000001)
-DEFINE_LOG_FACILITY(LF_GCINFO ,0x00000002)
-DEFINE_LOG_FACILITY(LF_STUBS ,0x00000004)
-DEFINE_LOG_FACILITY(LF_JIT ,0x00000008)
-DEFINE_LOG_FACILITY(LF_LOADER ,0x00000010)
-DEFINE_LOG_FACILITY(LF_METADATA ,0x00000020)
-DEFINE_LOG_FACILITY(LF_SYNC ,0x00000040)
-DEFINE_LOG_FACILITY(LF_EEMEM ,0x00000080)
-DEFINE_LOG_FACILITY(LF_GCALLOC ,0x00000100)
-DEFINE_LOG_FACILITY(LF_CORDB ,0x00000200)
-DEFINE_LOG_FACILITY(LF_CLASSLOADER ,0x00000400)
-DEFINE_LOG_FACILITY(LF_CORPROF ,0x00000800)
-DEFINE_LOG_FACILITY(LF_REMOTING ,0x00001000)
-DEFINE_LOG_FACILITY(LF_DBGALLOC ,0x00002000)
-DEFINE_LOG_FACILITY(LF_EH ,0x00004000)
-DEFINE_LOG_FACILITY(LF_ENC ,0x00008000)
-DEFINE_LOG_FACILITY(LF_ASSERT ,0x00010000)
-DEFINE_LOG_FACILITY(LF_VERIFIER ,0x00020000)
-DEFINE_LOG_FACILITY(LF_THREADPOOL ,0x00040000)
-DEFINE_LOG_FACILITY(LF_GCROOTS ,0x00080000)
-DEFINE_LOG_FACILITY(LF_INTEROP ,0x00100000)
-DEFINE_LOG_FACILITY(LF_MARSHALER ,0x00200000)
-DEFINE_LOG_FACILITY(LF_IJW ,0x00400000)
-DEFINE_LOG_FACILITY(LF_ZAP ,0x00800000)
-DEFINE_LOG_FACILITY(LF_STARTUP ,0x01000000) // Log startupa and shutdown failures
-DEFINE_LOG_FACILITY(LF_APPDOMAIN ,0x02000000)
-DEFINE_LOG_FACILITY(LF_CODESHARING ,0x04000000)
-DEFINE_LOG_FACILITY(LF_STORE ,0x08000000)
-DEFINE_LOG_FACILITY(LF_SECURITY ,0x10000000)
-DEFINE_LOG_FACILITY(LF_LOCKS ,0x20000000)
-DEFINE_LOG_FACILITY(LF_BCL ,0x40000000)
-// LF_ALWAYS 0x80000000 // make certain you don't try to use this bit for a real facility
-// LF_ALL 0xFFFFFFFF
+DEFINE_LOG_FACILITY(LF_GC ,0x00000001)
+DEFINE_LOG_FACILITY(LF_GCINFO ,0x00000002)
+DEFINE_LOG_FACILITY(LF_STUBS ,0x00000004)
+DEFINE_LOG_FACILITY(LF_JIT ,0x00000008)
+DEFINE_LOG_FACILITY(LF_LOADER ,0x00000010)
+DEFINE_LOG_FACILITY(LF_METADATA ,0x00000020)
+DEFINE_LOG_FACILITY(LF_SYNC ,0x00000040)
+DEFINE_LOG_FACILITY(LF_EEMEM ,0x00000080)
+DEFINE_LOG_FACILITY(LF_GCALLOC ,0x00000100)
+DEFINE_LOG_FACILITY(LF_CORDB ,0x00000200)
+DEFINE_LOG_FACILITY(LF_CLASSLOADER ,0x00000400)
+DEFINE_LOG_FACILITY(LF_CORPROF ,0x00000800)
+DEFINE_LOG_FACILITY(LF_REMOTING ,0x00001000)
+DEFINE_LOG_FACILITY(LF_DBGALLOC ,0x00002000)
+DEFINE_LOG_FACILITY(LF_EH ,0x00004000)
+DEFINE_LOG_FACILITY(LF_ENC ,0x00008000)
+DEFINE_LOG_FACILITY(LF_ASSERT ,0x00010000)
+DEFINE_LOG_FACILITY(LF_VERIFIER ,0x00020000)
+DEFINE_LOG_FACILITY(LF_THREADPOOL ,0x00040000)
+DEFINE_LOG_FACILITY(LF_GCROOTS ,0x00080000)
+DEFINE_LOG_FACILITY(LF_INTEROP ,0x00100000)
+DEFINE_LOG_FACILITY(LF_MARSHALER ,0x00200000)
+DEFINE_LOG_FACILITY(LF_TIEREDCOMPILATION ,0x00400000) // This used to be IJW, but now repurposed for tiered compilation
+DEFINE_LOG_FACILITY(LF_ZAP ,0x00800000)
+DEFINE_LOG_FACILITY(LF_STARTUP ,0x01000000) // Log startupa and shutdown failures
+DEFINE_LOG_FACILITY(LF_APPDOMAIN ,0x02000000)
+DEFINE_LOG_FACILITY(LF_CODESHARING ,0x04000000)
+DEFINE_LOG_FACILITY(LF_STORE ,0x08000000)
+DEFINE_LOG_FACILITY(LF_SECURITY ,0x10000000)
+DEFINE_LOG_FACILITY(LF_LOCKS ,0x20000000)
+DEFINE_LOG_FACILITY(LF_BCL ,0x40000000)
+// LF_ALWAYS 0x80000000 // make certain you don't try to use this bit for a real facility
+// LF_ALL 0xFFFFFFFF
//
#undef DEFINE_LOG_FACILITY
diff --git a/src/inc/longfilepathwrappers.h b/src/inc/longfilepathwrappers.h
index a0ffe38da5..3bb9166990 100644
--- a/src/inc/longfilepathwrappers.h
+++ b/src/inc/longfilepathwrappers.h
@@ -152,120 +152,5 @@ DWORD WINAPI GetEnvironmentVariableWrapper(
BOOL PAL_GetPALDirectoryWrapper(SString& pbuffer);
-#ifndef FEATURE_CORECLR
-//Temporarily providing direct OS Calls Till All of the Desktop CLR start using the above format
-inline DWORD
-SearchPathWrapper(
- _In_opt_ LPCWSTR lpPath,
- _In_ LPCWSTR lpFileName,
- _In_opt_ LPCWSTR lpExtension,
- _In_ BOOL getPath,
- _Out_ LPWSTR lpBuffer,
- _Out_opt_ LPWSTR * lpFilePart
- )
-{
- return SearchPathW(
- lpPath,
- lpFileName,
- lpExtension,
- getPath,
- lpBuffer,
- lpFilePart
- );
-}
-
-
-inline DWORD
-GetShortPathNameWrapper(
- _In_ LPCWSTR lpszLongPath,
- _Out_ LPWSTR lpszShortPath,
- _In_ DWORD cchBuffer
- )
-{
- return GetShortPathNameW(
- lpszLongPath,
- lpszShortPath,
- cchBuffer
- );
-}
-
-inline DWORD
-GetLongPathNameWrapper(
- _In_ LPCWSTR lpszShortPath,
- _Out_ LPWSTR lpszLongPath,
- _In_ DWORD cchBuffer
- )
-{
- return GetLongPathNameW(
- lpszShortPath,
- lpszLongPath,
- cchBuffer
- );
-}
-
-inline UINT GetTempFileNameWrapper(
- _In_ LPCWSTR lpPathName,
- _In_ LPCWSTR lpPrefixString,
- _In_ UINT uUnique,
- _Out_ LPWSTR lpTempFileName
- )
-{
- return GetTempFileNameW(
- lpPathName,
- lpPrefixString,
- uUnique,
- lpTempFileName
- );
-}
-
-inline DWORD GetTempPathWrapper(
- _In_ DWORD nBufferLength,
- _Out_ LPWSTR lpBuffer
- )
-{
- return GetTempPathW(
- nBufferLength,
- lpBuffer
- );
-}
-
-inline DWORD GetCurrentDirectoryWrapper(
- _In_ DWORD nBufferLength,
- _Out_ LPWSTR lpBuffer
- )
-{
- return GetCurrentDirectoryW(
- nBufferLength,
- lpBuffer
- );
-}
-
-inline DWORD
-GetModuleFileNameWrapper(
- _In_opt_ HMODULE hModule,
- _Out_ LPWSTR lpFilename,
- _In_ DWORD nSize
- )
-{
- return GetModuleFileNameW(
- hModule,
- lpFilename,
- nSize
- );
-}
-
-inline DWORD GetEnvironmentVariableWrapper(
- _In_opt_ LPCWSTR lpName,
- _Out_opt_ LPWSTR lpBuffer,
- _In_ DWORD nSize
- )
-{
- return GetEnvironmentVariableW(
- lpName,
- lpBuffer,
- nSize
- );
-}
-#endif //FEATURE_CORECLR
#endif //_WIN_PATH_APIS_WRAPPER_
diff --git a/src/inc/metadatatracker.h b/src/inc/metadatatracker.h
index 93ecaab983..00aa56afae 100644
--- a/src/inc/metadatatracker.h
+++ b/src/inc/metadatatracker.h
@@ -5,7 +5,7 @@
#ifndef _METADATATRACKER_H_
#define _METADATATRACKER_H_
-#if defined(FEATURE_PREJIT) && (!defined(FEATURE_CORECLR) || defined(FEATURE_WINDOWSPHONE))
+#if defined(FEATURE_PREJIT) && defined(FEATURE_WINDOWSPHONE)
#define METADATATRACKER_DATA 1
#if !defined(DACCESS_COMPILE)
diff --git a/src/inc/mscoruef.idl b/src/inc/mscoruef.idl
deleted file mode 100644
index 4ed554f544..0000000000
--- a/src/inc/mscoruef.idl
+++ /dev/null
@@ -1,117 +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.
-//
-
-//
-/**************************************************************************************
- ** **
- ** Mscoruef.idl - interface definitions for internal UEF chain management. **
- ** **
- **************************************************************************************/
-
-//
-// Interface descriptions
-//
-import "unknwn.idl";
-
-cpp_quote("#ifdef FEATURE_UEF_CHAINMANAGER")
-
-// IID IUEFManager : uuid(F4D25DF3-E9B3-439c-8B2B-C814E36F9404)
-cpp_quote("EXTERN_GUID(IID_IUEFManager, 0xf4d25df3, 0xe9b3, 0x439c, 0x8b, 0x2b, 0xc8, 0x14, 0xe3, 0x6f, 0x94, 0x4);")
-
-// IID IWatsonSxSManager :uuid(A269593A-51E2-46bf-B914-8DCC5C39B5A5)
-cpp_quote("EXTERN_GUID(IID_IWatsonSxSManager, 0xa269593a, 0x51e2, 0x46bf, 0xb9, 0x14, 0x8d, 0xcc, 0x5c, 0x39, 0xb5, 0xa5);")
-
-cpp_quote("#ifdef __midl")
-
-#define EXCEPTION_MAXIMUM_PARAMETERS 15
-
-typedef struct _EXCEPTION_RECORD {
- DWORD ExceptionCode;
- DWORD ExceptionFlags;
- struct _EXCEPTION_RECORD *ExceptionRecord;
- PVOID ExceptionAddress;
- DWORD NumberParameters;
- ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
-} EXCEPTION_RECORD, *PEXCEPTION_RECORD;
-
-typedef struct _EXCEPTION_POINTERS {
- PEXCEPTION_RECORD ExceptionRecord;
- PVOID ContextRecord; // not using PCONTEXT here to avoid pulling extra definitions into this file
-} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS, *LPEXCEPTION_POINTERS;
-
-typedef LONG (__stdcall *PTOP_LEVEL_EXCEPTION_FILTER)(
- struct _EXCEPTION_POINTERS * pExceptionPointers);
-
-typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER;
-
-cpp_quote("#endif // __midl")
-
-typedef BOOL (__stdcall * IsExceptionFromManagedCodeFnPtr)(EXCEPTION_RECORD * pExceptionRecord);
-
-//*****************************************************************************
-// Interface for Watson SxS management to the VM.
-//*****************************************************************************
-[
- uuid(A269593A-51E2-46bf-B914-8DCC5C39B5A5),
- helpstring("CLR Watson SxS Management Interface"),
- pointer_default(unique),
- local
-]
-interface IWatsonSxSManager : IUnknown
-{
- // Used to register an exception claiming callback
- BOOL RegisterExceptionClaimingCallback(
- [in] IsExceptionFromManagedCodeFnPtr pCallback);
-
- // Used to unregister an exception claiming callback
- BOOL UnregisterExceptionClaimingCallback(
- [in] IsExceptionFromManagedCodeFnPtr pCallback);
-
- // Used to determine if the exception pointed by pExceptionRecord was thrown by a registered runtime
- BOOL IsExceptionClaimed(
- [in] EXCEPTION_RECORD * pExceptionRecord);
-
- // Used to check if Watson has been triggered
- BOOL HasWatsonBeenTriggered(void);
-
- // Used to bestow the permission to report Watson to only one of its callers
- BOOL IsCurrentRuntimeAllowedToReportWatson(void);
-
- // Used to wait for the Watson SxS completion event
- BOOL WaitForWatsonSxSCompletionEvent(void);
-
- // Used to signal Watson SxS completion event
- BOOL SignalWatsonSxSCompletionEvent(void);
-};
-
-//*****************************************************************************
-// Interface for UEF chain management to the VM.
-//*****************************************************************************
-[
- uuid(F4D25DF3-E9B3-439c-8B2B-C814E36F9404),
- helpstring("CLR UEF Chain Management Interface"),
- pointer_default(unique),
- local
-]
-interface IUEFManager : IUnknown
-{
- // Used to register the function to be invoked upon unhandled exception
- // notification from the OS
- BOOL AddUnhandledExceptionFilter(
- [in] LPTOP_LEVEL_EXCEPTION_FILTER uefCallbackFunc,
- [in] BOOL firstHandler);
-
- // Used to unregister a previously registered UEF callback
- BOOL RemoveUnhandledExceptionFilter(
- [in] LPTOP_LEVEL_EXCEPTION_FILTER uefCallbackFunc);
-
- // Used to explicitly invoke the registered UEF callbacks
- LONG InvokeUEFCallbacks(LPEXCEPTION_POINTERS pExceptionInfo);
-
- // Used to return the WatsonSxSManager singleton instance
- IWatsonSxSManager * GetWastonSxSManagerInstance(void);
-};
-
-cpp_quote("#endif // FEATURE_UEF_CHAINMANAGER")
diff --git a/src/inc/newapis.h b/src/inc/newapis.h
index dfe77a5000..e0e6d999e1 100644
--- a/src/inc/newapis.h
+++ b/src/inc/newapis.h
@@ -288,15 +288,17 @@ namespace NewApis
__in_ecount(cchCount2) LPCWSTR pString2, // String we're looking for
__in int cchCount2, // length of pString2
__in DWORD dwFlags, // search flags
- __in BOOL startWith);
+ __in BOOL startWith,
+ __out_opt LPINT pcchFound);
int LastIndexOfString(__in LPCWSTR lpLocaleName,
- __in_ecount(cchCount1) LPCWSTR pString1, // String to search in
- __in int cchCount1, // length of pString1
- __in_ecount(cchCount2) LPCWSTR pString2, // String we're looking for
- __in int cchCount2, // length of pString2
- __in DWORD dwFlags,
- __in BOOL endWith);
+ __in_ecount(cchCount1) LPCWSTR pString1, // String to search in
+ __in int cchCount1, // length of pString1
+ __in_ecount(cchCount2) LPCWSTR pString2, // String we're looking for
+ __in int cchCount2, // length of pString2
+ __in DWORD dwFlags,
+ __in BOOL endWith,
+ __out_opt LPINT pcchFound);
int FindNLSStringEx(__in LPCWSTR lpLocaleName,
__in DWORD dwFindNLSStringFlags,
diff --git a/src/inc/palclr_win.h b/src/inc/palclr_win.h
index 18edc6c8f5..372f467cbd 100644
--- a/src/inc/palclr_win.h
+++ b/src/inc/palclr_win.h
@@ -83,67 +83,6 @@
// WIN_PAL_ENDTRY
//
-#if !defined(FEATURE_CORECLR)
-
-#include "staticcontract.h"
-
-#define WIN_PAL_TRY_NAKED \
- { \
- bool __exHandled; __exHandled = false; \
- DWORD __exCode; __exCode = 0; \
- __try \
- {
-
-#define WIN_PAL_TRY \
- { \
- WIN_PAL_TRY_NAKED \
- WIN_PAL_TRY_HANDLER_DBG_BEGIN
-
-#define WIN_PAL_TRY_FOR_DLLMAIN(_reason) \
- { \
- WIN_PAL_TRY_NAKED \
- WIN_PAL_TRY_HANDLER_DBG_BEGIN_DLLMAIN(_reason)
-
-// Note: PAL_SEH_RESTORE_GUARD_PAGE is only ever defined in clrex.h, so we only restore guard pages automatically
-// when these macros are used from within the VM.
-#define WIN_PAL_SEH_RESTORE_GUARD_PAGE PAL_SEH_RESTORE_GUARD_PAGE
-
-#define WIN_PAL_EXCEPT_NAKED(Disposition) \
- } __except(__exCode = GetExceptionCode(), Disposition) { \
- __exHandled = true; \
- WIN_PAL_SEH_RESTORE_GUARD_PAGE
-
-#define WIN_PAL_EXCEPT(Disposition) \
- WIN_PAL_TRY_HANDLER_DBG_END \
- WIN_PAL_EXCEPT_NAKED(Disposition)
-
-#define WIN_PAL_EXCEPT_FILTER_NAKED(pfnFilter, pvFilterParameter) \
- } __except(__exCode = GetExceptionCode(), pfnFilter(GetExceptionInformation(), pvFilterParameter)) { \
- __exHandled = true; \
- WIN_PAL_SEH_RESTORE_GUARD_PAGE
-
-#define WIN_PAL_EXCEPT_FILTER(pfnFilter, pvFilterParameter) \
- WIN_PAL_TRY_HANDLER_DBG_END \
- WIN_PAL_EXCEPT_FILTER_NAKED(pfnFilter, pvFilterParameter)
-
-#define WIN_PAL_FINALLY_NAKED \
- } __finally { \
-
-#define WIN_PAL_FINALLY \
- WIN_PAL_TRY_HANDLER_DBG_END \
- WIN_PAL_FINALLY_NAKED
-
-#define WIN_PAL_ENDTRY_NAKED \
- } \
- } \
-
-#define WIN_PAL_ENDTRY \
- } \
- WIN_PAL_ENDTRY_NAKED_DBG \
- } \
- }
-
-#endif // !PAL_WIN_SEH
#if defined(_DEBUG_IMPL) && !defined(JIT_BUILD) && !defined(JIT64_BUILD) && !defined(_ARM_) // @ARMTODO
diff --git a/src/inc/profilepriv.h b/src/inc/profilepriv.h
index f74818c731..ae7b225f8c 100644
--- a/src/inc/profilepriv.h
+++ b/src/inc/profilepriv.h
@@ -148,9 +148,9 @@ GVAL_DECL(ProfControlBlock, g_profControlBlock);
#endif // defined(PROFILING_SUPPORTED_DATA) || defined(PROFILING_SUPPORTED)
// This is the helper callback that the gc uses when walking the heap.
-BOOL HeapWalkHelper(Object* pBO, void* pv);
+bool HeapWalkHelper(Object* pBO, void* pv);
void ScanRootsHelper(Object* pObj, Object** ppRoot, ScanContext *pSC, uint32_t dwUnused);
-BOOL AllocByClassHelper(Object* pBO, void* pv);
+bool AllocByClassHelper(Object* pBO, void* pv);
#endif // _ProfilePriv_h_
diff --git a/src/inc/readytorun.h b/src/inc/readytorun.h
index ebc557b6f1..0f5183ff3a 100644
--- a/src/inc/readytorun.h
+++ b/src/inc/readytorun.h
@@ -16,7 +16,9 @@
#define READYTORUN_SIGNATURE 0x00525452 // 'RTR'
#define READYTORUN_MAJOR_VERSION 0x0002
-#define READYTORUN_MINOR_VERSION 0x0000
+#define READYTORUN_MINOR_VERSION 0x0002
+// R2R Version 2.1 adds the READYTORUN_SECTION_INLINING_INFO section
+// R2R Version 2.2 adds the READYTORUN_SECTION_PROFILEDATA_INFO section
struct READYTORUN_HEADER
{
@@ -57,6 +59,14 @@ enum ReadyToRunSectionType
// 107 used by an older format of READYTORUN_SECTION_AVAILABLE_TYPES
READYTORUN_SECTION_AVAILABLE_TYPES = 108,
READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS = 109,
+ READYTORUN_SECTION_INLINING_INFO = 110, // Added in V2.1
+ READYTORUN_SECTION_PROFILEDATA_INFO = 111 // Added in V2.2
+
+ // If you add a new section consider whether it is a breaking or non-breaking change.
+ // Usually it is non-breaking, but if it is preferable to have older runtimes fail
+ // to load the image vs. ignoring the new section it could be marked breaking.
+ // Increment the READYTORUN_MINOR_VERSION (non-breaking) or READYTORUN_MAJOR_VERSION
+ // (breaking) as appropriate.
};
//
@@ -220,6 +230,9 @@ enum ReadyToRunHelper
// Get string handle lazily
READYTORUN_HELPER_GetString = 0x50,
+ // Used by /Tuning for Profile optimizations
+ READYTORUN_HELPER_LogMethodEnter = 0x51,
+
// Reflection helpers
READYTORUN_HELPER_GetRuntimeTypeHandle = 0x54,
READYTORUN_HELPER_GetRuntimeMethodHandle = 0x55,
diff --git a/src/inc/readytorunhelpers.h b/src/inc/readytorunhelpers.h
index 4524e1ae84..9baf0e4459 100644
--- a/src/inc/readytorunhelpers.h
+++ b/src/inc/readytorunhelpers.h
@@ -32,6 +32,8 @@ HELPER(READYTORUN_HELPER_Ldelema_Ref, CORINFO_HELP_LDELEMA_REF,
HELPER(READYTORUN_HELPER_MemSet, CORINFO_HELP_MEMSET, )
HELPER(READYTORUN_HELPER_MemCpy, CORINFO_HELP_MEMCPY, )
+HELPER(READYTORUN_HELPER_LogMethodEnter, CORINFO_HELP_BBT_FCN_ENTER, )
+
HELPER(READYTORUN_HELPER_GetRuntimeTypeHandle, CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE, )
HELPER(READYTORUN_HELPER_GetRuntimeMethodHandle, CORINFO_HELP_METHODDESC_TO_STUBRUNTIMEMETHOD, )
HELPER(READYTORUN_HELPER_GetRuntimeFieldHandle, CORINFO_HELP_FIELDDESC_TO_STUBRUNTIMEFIELD, )
diff --git a/src/inc/regdisp.h b/src/inc/regdisp.h
index d08c44c904..a361dca719 100644
--- a/src/inc/regdisp.h
+++ b/src/inc/regdisp.h
@@ -275,28 +275,7 @@ inline TADDR GetRegdisplayStackMark(REGDISPLAY *display) {
}
#else // none of the above processors
-
-PORTABILITY_WARNING("RegDisplay functions are not implemented on this platform.")
-
-struct REGDISPLAY : public REGDISPLAY_BASE {
- size_t * FramePtr;
- SLOT * pPC;
-};
-
-inline TADDR GetRegdisplayFP(REGDISPLAY *display) {
- LIMITED_METHOD_CONTRACT;
- return (TADDR)*(display->FramePtr);
-}
-
-inline BOOL IsInCalleesFrames(REGDISPLAY *display, LPVOID stackPointer) {
- LIMITED_METHOD_CONTRACT;
- return FALSE;
-}
-inline LPVOID GetRegdisplayStackMark(REGDISPLAY *display) {
- LIMITED_METHOD_CONTRACT;
- return (LPVOID)display->SP;
-}
-
+#error "RegDisplay functions are not implemented on this platform."
#endif
#if defined(_WIN64) || defined(_TARGET_ARM_) || (defined(_TARGET_X86_) && defined(WIN64EXCEPTIONS))
@@ -417,7 +396,7 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC
#elif defined(_TARGET_X86_) // _TARGET_ARM_
for (int i = 0; i < 7; i++)
{
- *(&pRD->ctxPtrsOne.Esi + i) = (&pctx->Esi + i);
+ *(&pRD->ctxPtrsOne.Edi + i) = (&pctx->Edi + i);
}
#else // _TARGET_X86_
PORTABILITY_ASSERT("FillRegDisplay");
@@ -477,35 +456,21 @@ inline void CopyRegDisplay(const PREGDISPLAY pInRD, PREGDISPLAY pOutRD, T_CONTEX
inline size_t * getRegAddr (unsigned regNum, PTR_CONTEXT regs)
{
#ifdef _TARGET_X86_
- switch (regNum)
+ _ASSERTE(regNum < 8);
+
+ static const SIZE_T OFFSET_OF_REGISTERS[] =
{
- case 0:
- return (size_t *)&regs->Eax;
- break;
- case 1:
- return (size_t *)&regs->Ecx;
- break;
- case 2:
- return (size_t *)&regs->Edx;
- break;
- case 3:
- return (size_t *)&regs->Ebx;
- break;
- case 4:
- return (size_t *)&regs->Esp;
- break;
- case 5:
- return (size_t *)&regs->Ebp;
- break;
- case 6:
- return (size_t *)&regs->Esi;
- break;
- case 7:
- return (size_t *)&regs->Edi;
- break;
- default:
- _ASSERTE (!"unknown regNum");
- }
+ offsetof(CONTEXT, Eax),
+ offsetof(CONTEXT, Ecx),
+ offsetof(CONTEXT, Edx),
+ offsetof(CONTEXT, Ebx),
+ offsetof(CONTEXT, Esp),
+ offsetof(CONTEXT, Ebp),
+ offsetof(CONTEXT, Esi),
+ offsetof(CONTEXT, Edi),
+ };
+
+ return (PTR_size_t)(PTR_BYTE(regs) + OFFSET_OF_REGISTERS[regNum]);
#elif defined(_TARGET_AMD64_)
_ASSERTE(regNum < 16);
return &regs->Rax + regNum;
diff --git a/src/inc/registrywrapper.h b/src/inc/registrywrapper.h
index bd6afe190b..6b284506bb 100644
--- a/src/inc/registrywrapper.h
+++ b/src/inc/registrywrapper.h
@@ -11,38 +11,10 @@
#ifndef __REGISTRYWRAPPER_H
#define __REGISTRYWRAPPER_H
-#if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) && !defined(FEATURE_CORECLR)
-
-// Registry API wrappers
-
-LONG ClrRegCreateKeyEx(
- HKEY hKey,
- LPCWSTR lpSubKey,
- DWORD Reserved,
- __in_opt LPWSTR lpClass,
- DWORD dwOptions,
- REGSAM samDesired,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes,
- PHKEY phkResult,
- LPDWORD lpdwDisposition
- );
-
-LONG ClrRegOpenKeyEx(
- HKEY hKey,
- LPCWSTR lpSubKey,
- DWORD ulOptions,
- REGSAM samDesired,
- PHKEY phkResult
- );
-
-bool IsNgenOffline();
-
-#else
#define ClrRegCreateKeyEx RegCreateKeyExW
#define ClrRegOpenKeyEx RegOpenKeyExW
#define IsNgenOffline() false
-#endif
#endif // __REGISTRYWRAPPER_H
diff --git a/src/inc/shimload.h b/src/inc/shimload.h
index 9a6ab7de6f..a2651d1aff 100644
--- a/src/inc/shimload.h
+++ b/src/inc/shimload.h
@@ -14,17 +14,6 @@
#ifndef _SHIMLOAD_H
#define _SHIMLOAD_H
-#ifndef FEATURE_CORECLR
-#include <delayimp.h>
-
-extern FARPROC __stdcall ShimDelayLoadHook(unsigned dliNotify, // What event has occurred, dli* flag.
- DelayLoadInfo *pdli); // Description of the event.
-
-//and one for safe mode
-extern FARPROC __stdcall ShimSafeModeDelayLoadHook(unsigned dliNotify, // What event has occurred, dli* flag.
- DelayLoadInfo *pdli); // Description of the event.
-
-#endif
//*****************************************************************************
// Sets/Gets the directory based on the location of the module. This routine
diff --git a/src/inc/stacktrace.h b/src/inc/stacktrace.h
index 49e951780c..9152116d39 100644
--- a/src/inc/stacktrace.h
+++ b/src/inc/stacktrace.h
@@ -74,7 +74,7 @@ void GetStringFromStackLevels(UINT ifrStart, UINT cfrTotal, __out_ecount(cchMaxA
******************************************************************** robch */
void GetStringFromAddr(DWORD_PTR dwAddr, __out_ecount(cchMaxAssertStackLevelStringLen) LPSTR szString);
-#if defined(_TARGET_X86_) && defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if defined(_TARGET_X86_) && !defined(FEATURE_PAL)
/****************************************************************************
* ClrCaptureContext *
*-------------------*
@@ -83,9 +83,9 @@ void GetStringFromAddr(DWORD_PTR dwAddr, __out_ecount(cchMaxAssertStackLevelStri
* support this, so we need it for CoreCLR 4, if we require Win2K support
****************************************************************************/
extern "C" void __stdcall ClrCaptureContext(__out PCONTEXT ctx);
-#else // _TARGET_X86_ && FEATURE_CORECLR && !FEATURE_PAL
+#else // _TARGET_X86_ && !FEATURE_PAL
#define ClrCaptureContext RtlCaptureContext
-#endif // _TARGET_X86_ && FEATURE_CORECLR && !FEATURE_PAL
+#endif // _TARGET_X86_ && !FEATURE_PAL
#endif
diff --git a/src/inc/stdmacros.h b/src/inc/stdmacros.h
index ab77a2cd91..3ec8bec6f3 100644
--- a/src/inc/stdmacros.h
+++ b/src/inc/stdmacros.h
@@ -277,7 +277,7 @@ inline ULONG RoundUpToPower2(ULONG x)
#define DBG_GET_CLASS_NAME(pMT) \
- (pMT)->GetClass()->GetDebugClassName()
+ (((pMT) == NULL) ? NULL : (pMT)->GetClass()->GetDebugClassName())
#define DBG_CLASS_NAME_MT(pMT) \
(DBG_GET_CLASS_NAME(pMT) == NULL) ? "<null-class>" : DBG_GET_CLASS_NAME(pMT)
diff --git a/src/inc/stgpool.h b/src/inc/stgpool.h
index 9eef70742e..4486695507 100644
--- a/src/inc/stgpool.h
+++ b/src/inc/stgpool.h
@@ -310,12 +310,11 @@ public:
{
LIMITED_METHOD_CONTRACT;
-// @todo: Triton workaround: FEATURE_METADATA_STANDALNE_WINRT_RO is supposed to disable FEATURE_PREJIT - remove this #ifdef once we figure out how to get that working in the CoreClr build.
-#if !(defined(FEATURE_UTILCODE_NO_DEPENDENCIES) || defined(FEATURE_METADATA_STANDALNE_WINRT_RO))
+#if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES)
m_HotHeap = hotHeap;
#else
_ASSERTE(!"InitHotData(): Not supposed to exist in RoMetaData.dll");
-#endif //!(defined(FEATURE_UTILCODE_NO_DEPENDENCIES) || defined(FEATURE_METADATA_STANDALNE_WINRT_RO))
+#endif //!(defined(FEATURE_UTILCODE_NO_DEPENDENCIES))
}
#endif //FEATURE_PREJIT
@@ -345,8 +344,7 @@ protected:
return CLDB_E_INDEX_NOTFOUND;
}
-// @todo: Triton workaround: FEATURE_METADATA_STANDALNE_WINRT_RO is supposed to disable FEATURE_PREJIT - remove this #if once we figure out how to get that working in the CoreClr build.
-#if !(defined(FEATURE_UTILCODE_NO_DEPENDENCIES) || defined(FEATURE_METADATA_STANDALNE_WINRT_RO))
+#if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES)
#ifdef FEATURE_PREJIT
// try hot data first
if (!m_HotHeap.IsEmpty())
@@ -359,7 +357,7 @@ protected:
_ASSERTE(hr == S_FALSE);
}
#endif //FEATURE_PREJIT
-#endif //!(defined(FEATURE_UTILCODE_NO_DEPENDENCIES) || defined(FEATURE_METADATA_STANDALNE_WINRT_RO))
+#endif //!(defined(FEATURE_UTILCODE_NO_DEPENDENCIES))
pData->Init(m_pSegData + nOffset, m_cbSegSize - nOffset);
@@ -381,11 +379,10 @@ protected:
} // StgPoolReadOnly::GetData
private:
-// @todo: Triton workaround: FEATURE_METADATA_STANDALNE_WINRT_RO is supposed to disable FEATURE_PREJIT - remove this #if once we figure out how to get that working in the CoreClr build.
-#if !(defined(FEATURE_UTILCODE_NO_DEPENDENCIES) || defined(FEATURE_METADATA_STANDALNE_WINRT_RO))
+#if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES)
// hot pool data
MetaData::HotHeap m_HotHeap;
-#endif //!(defined(FEATURE_UTILCODE_NO_DEPENDENCIES) || defined(FEATURE_METADATA_STANDALNE_WINRT_RO))
+#endif //!(defined(FEATURE_UTILCODE_NO_DEPENDENCIES))
}; // class StgPoolReadOnly
diff --git a/src/inc/switches.h b/src/inc/switches.h
index bb3ca28e12..bb303876e8 100644
--- a/src/inc/switches.h
+++ b/src/inc/switches.h
@@ -10,9 +10,6 @@
#define STRESS_HEAP
#endif
-#if !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
-#define STRESS_THREAD
-#endif
#define VERIFY_HEAP
@@ -67,9 +64,6 @@
#define GC_STATS
#endif
-#if !defined(FEATURE_CORECLR)
-#define EMIT_FIXUPS
-#endif
#if defined(_DEBUG) && !defined(DACCESS_COMPILE) && (defined(_TARGET_X86_) || defined(_TARGET_AMD64_))
// On x86/x64 Windows debug builds, respect the COMPlus_EnforceEEThreadNotRequiredContracts
@@ -110,16 +104,12 @@
// ALLOW_SXS_JIT_NGEN enables AltJit support for NGEN, via COMPlus_AltJitNgen / COMPlus_AltJitName.
// Note that if ALLOW_SXS_JIT_NGEN is defined, then ALLOW_SXS_JIT must be defined.
#define ALLOW_SXS_JIT
-#if defined(ALLOW_SXS_JIT)
#define ALLOW_SXS_JIT_NGEN
-#endif // ALLOW_SXS_JIT
-#if defined(FEATURE_CORECLR)
//master switch for gc suspension not based on hijacking
#define FEATURE_ENABLE_GCPOLL
-#endif //FEATURE_CORECLR
-#if defined(FEATURE_ENABLE_GCPOLL) && defined(_TARGET_X86_)
+#if defined(_TARGET_X86_)
//this enables a fast version of the GC Poll helper instead of the default portable one.
#define ENABLE_FAST_GCPOLL_HELPER
#endif // defined(FEATURE_ENABLE_GCPOLL) && defined(_TARGET_X86_)
@@ -132,18 +122,13 @@
#define PLATFORM_SUPPORTS_SAFE_THREADSUSPEND
#endif // !FEATURE_PAL
-#if !defined(PLATFORM_SUPPORTS_SAFE_THREADSUSPEND) && !defined(FEATURE_ENABLE_GCPOLL)
-#error "Platform must support either safe thread suspension or GC polling"
-#endif
#if defined(STRESS_HEAP) && defined(_DEBUG) && defined(FEATURE_HIJACK)
#define HAVE_GCCOVER
#endif
-#ifdef FEATURE_CORECLR
//Turns on a startup delay to allow simulation of slower and faster startup times.
#define ENABLE_STARTUP_DELAY
-#endif
#ifndef ALLOW_LOCAL_WORKER
@@ -182,28 +167,14 @@
#define FEATURE_PROFAPI_EVENT_LOGGING
#endif // defined(PROFILING_SUPPORTED)
-// Windows desktop supports the profiling API attach / detach feature.
-// This will eventually be supported on coreclr as well.
-#if defined(PROFILING_SUPPORTED) && !defined(FEATURE_CORECLR)
-#define FEATURE_PROFAPI_ATTACH_DETACH
-#endif
-
-// Windows desktop DAC builds need to see some of the data used in the profiling API
-// attach / detach feature, particularly Thread::m_dwProfilerEvacuationCounter
-#if defined(PROFILING_SUPPORTED_DATA) && !defined(FEATURE_CORECLR)
-#define DATA_PROFAPI_ATTACH_DETACH
-#endif
-
// MUST NEVER CHECK IN WITH THIS ENABLED.
// This is just for convenience in doing performance investigations in a checked-out enlistment.
// #define FEATURE_ENABLE_NO_RANGE_CHECKS
-#ifndef FEATURE_CORECLR
// This controls whether a compilation-timing feature that relies on Windows APIs, if available, else direct
// hardware instructions (rdtsc), for accessing high-resolution hardware timers is enabled. This is disabled
// in Silverlight (just to avoid thinking about whether the extra code space is worthwhile).
#define FEATURE_JIT_TIMER
-#endif // FEATURE_CORECLR
// This feature in RyuJIT supersedes the FEATURE_JIT_TIMER. In addition to supporting the time log file, this
// feature also supports using COMPlus_JitTimeLogCsv=a.csv, which will dump method-level and phase-level timing
@@ -221,9 +192,7 @@
// are treated as potential pinned interior pointers. When enabled, the runtime flag COMPLUS_GCCONSERVATIVE
// determines dynamically whether GC is conservative. Note that appdomain unload, LCG and unloadable assemblies
// do not work reliably with conservative GC.
-#ifdef FEATURE_CORECLR
#define FEATURE_CONSERVATIVE_GC 1
-#endif
#if (defined(_TARGET_ARM_) && !defined(ARM_SOFTFP)) || defined(_TARGET_ARM64_)
#define FEATURE_HFA
@@ -246,7 +215,7 @@
#define FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
#endif // defined(FEATURE_CORESYSTEM)
-#if defined(FEATURE_PREJIT) && defined(FEATURE_CORECLR) && defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_PREJIT) && defined(FEATURE_CORESYSTEM)
// Desktop CLR allows profilers and debuggers to opt out of loading NGENd images, and to
// JIT everything instead. "FEATURE_TREAT_NI_AS_MSIL_DURING_DIAGNOSTICS" is roughly the
// equivalent for Apollo, where MSIL images may not be available at all.
@@ -260,7 +229,7 @@
// If defined, support interpretation.
#if !defined(CROSSGEN_COMPILE)
-#if defined(ALLOW_SXS_JIT) && !defined(FEATURE_PAL)
+#if !defined(FEATURE_PAL)
#define FEATURE_STACK_SAMPLING
#endif // defined (ALLOW_SXS_JIT)
diff --git a/src/inc/tlbutils.h b/src/inc/tlbutils.h
deleted file mode 100644
index 54a274587c..0000000000
--- a/src/inc/tlbutils.h
+++ /dev/null
@@ -1,52 +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.
-
-//
-// Utilities used to help manipulating typelibs
-//
-
-
-#ifndef _TLBUTILS_H
-#define _TLBUTILS_H
-
-#ifndef FEATURE_COMINTEROP_TLB_SUPPORT
-#error FEATURE_COMINTEROP_TLB_SUPPORT is required for this file
-#endif // FEATURE_COMINTEROP_TLB_SUPPORT
-
-#include "windows.h"
-#include "utilcode.h"
-
-struct StdConvertibleItfInfo
-{
- LPUTF8 m_strMngTypeName;
- GUID * m_pNativeTypeIID;
- LPUTF8 m_strCustomMarshalerTypeName;
- LPUTF8 m_strCookie;
-};
-
-// This method returns the custom marshaler info to convert the native interface
-// to its managed equivalent. Or null if the interface is not a standard convertible interface.
-const StdConvertibleItfInfo *GetConvertionInfoFromNativeIID(REFGUID rGuidNativeItf);
-
-// This function determines the namespace name for a TypeLib.
-HRESULT GetNamespaceNameForTypeLib( // S_OK or error.
- ITypeLib *pITLB, // [IN] The TypeLib.
- BSTR *pwzNamespace); // [OUT] Put the namespace name here.
-
-// This function determines the namespace.name for a TypeInfo. If no namespace
-// is provided, it is retrieved from the containing library.
-HRESULT GetManagedNameForTypeInfo( // S_OK or error.
- ITypeInfo *pITI, // [IN] The TypeInfo.
- LPCWSTR wzNamespace, // [IN, OPTIONAL] Default namespace name.
- LPCWSTR wzAsmName, // [IN, OPTIONAL] Assembly name.
- BSTR *pwzName); // [OUT] Put the name here.
-
-#endif // _TLBUTILS_H
-
-
-
-
-
-
-
diff --git a/src/inc/utilcode.h b/src/inc/utilcode.h
index a1a083638b..5394f1beb2 100644
--- a/src/inc/utilcode.h
+++ b/src/inc/utilcode.h
@@ -51,7 +51,6 @@ const WCHAR kWatsonName2[] = W("drwtsn32");
#define WINDOWS_KERNEL32_DLLNAME_A "kernel32"
#define WINDOWS_KERNEL32_DLLNAME_W W("kernel32")
-#if defined(FEATURE_CORECLR)
#define CoreLibName_W W("System.Private.CoreLib")
#define CoreLibName_IL_W W("System.Private.CoreLib.dll")
#define CoreLibName_NI_W W("System.Private.CoreLib.ni.dll")
@@ -64,20 +63,6 @@ const WCHAR kWatsonName2[] = W("drwtsn32");
#define CoreLibSatelliteName_A "System.Private.CoreLib.resources"
#define CoreLibSatelliteNameLen 32
#define LegacyCoreLibName_A "mscorlib"
-#else // !defined(FEATURE_CORECLR)
-#define CoreLibName_W W("mscorlib")
-#define CoreLibName_IL_W W("mscorlib.dll")
-#define CoreLibName_NI_W W("mscorlib.ni.dll")
-#define CoreLibName_TLB_W W("mscorlib.tlb")
-#define CoreLibName_A "mscorlib"
-#define CoreLibName_IL_A "mscorlib.dll"
-#define CoreLibName_NI_A "mscorlib.ni.dll"
-#define CoreLibName_TLB_A "mscorlib.tlb"
-#define CoreLibNameLen 8
-#define CoreLibSatelliteName_A "mscorlib.resources"
-#define CoreLibSatelliteNameLen 18
-#define LegacyCoreLibName_A "mscorlib"
-#endif // defined(FEATURE_CORECLR)
class StringArrayList;
@@ -814,10 +799,8 @@ public:
// Get the default resource location (mscorrc.dll for desktop, mscorrc.debug.dll for CoreCLR)
static CCompRC* GetDefaultResourceDll();
-#ifdef FEATURE_CORECLR
// Get the generic messages dll (Silverlight only, mscorrc.dll)
static CCompRC* GetFallbackResourceDll();
-#endif
static void ShutdownDefaultResourceDll();
static void GetDefaultCallbacks(
FPGETTHREADUICULTURENAMES* fpGetThreadUICultureNames,
@@ -842,12 +825,10 @@ public:
fpGetThreadUICultureNames,
fpGetThreadUICultureId);
-#ifdef FEATURE_CORECLR
m_FallbackResourceDll.SetResourceCultureCallbacks(
fpGetThreadUICultureNames,
fpGetThreadUICultureId);
-#endif
}
#ifdef USE_FORMATMESSAGE_WRAPPER
@@ -881,12 +862,10 @@ private:
static CCompRC m_DefaultResourceDll;
static LPCWSTR m_pDefaultResource;
-#ifdef FEATURE_CORECLR
// fallback resources if debug pack is not installed
static LONG m_dwFallbackInitialized;
static CCompRC m_FallbackResourceDll;
static LPCWSTR m_pFallbackResource;
-#endif
// We must map between a thread's int and a dll instance.
// Since we only expect 1 language almost all of the time, we'll special case
@@ -1143,13 +1122,6 @@ void SplitPathInterior(
__out_opt LPCWSTR *pwszFileName, __out_opt size_t *pcchFileName,
__out_opt LPCWSTR *pwszExt, __out_opt size_t *pcchExt);
-#ifndef FEATURE_CORECLR
-void MakePath(__out_ecount (MAX_LONGPATH) register WCHAR *path,
- __in LPCWSTR drive,
- __in LPCWSTR dir,
- __in LPCWSTR fname,
- __in LPCWSTR ext);
-#endif
void MakePath(__out CQuickWSTR &path,
__in LPCWSTR drive,
@@ -1243,13 +1215,9 @@ public:
static void FreeConfigString(__in __in_z LPWSTR name);
-#ifdef FEATURE_CORECLR
private:
-#endif //FEATURE_CORECLR
static LPWSTR EnvGetString(LPCWSTR name, BOOL fPrependCOMPLUS);
-#ifdef FEATURE_CORECLR
public:
-#endif //FEATURE_CORECLR
static BOOL UseRegistry();
@@ -1267,138 +1235,6 @@ private:
BOOL fPrependCOMPLUS = TRUE);
public:
-#ifndef FEATURE_CORECLR
- static void AllowRegistryUse(BOOL fAllowUse);
-
-
-//*****************************************************************************
-// Open's the given key and returns the value desired. If the key or value is
-// not found, then the default is returned.
-//*****************************************************************************
- static long GetLong( // Return value from registry or default.
- LPCTSTR szName, // Name of value to get.
- long iDefault, // Default value to return if not found.
- LPCTSTR szKey=NULL, // Name of key, NULL==default.
- HKEY hKey=HKEY_LOCAL_MACHINE);// What key to work on.
-
-//*****************************************************************************
-// Open's the given key and returns the value desired. If the key or value is
-// not found, then the default is returned.
-//*****************************************************************************
- static long SetLong( // Return value from registry or default.
- LPCTSTR szName, // Name of value to get.
- long iValue, // Value to set.
- LPCTSTR szKey=NULL, // Name of key, NULL==default.
- HKEY hKey=HKEY_LOCAL_MACHINE);// What key to work on.
-
-//*****************************************************************************
-// Open's the given key and returns the value desired. If the key or value is
-// not found, then it's created
-//*****************************************************************************
- static long SetOrCreateLong( // Return value from registry or default.
- LPCTSTR szName, // Name of value to get.
- long iValue, // Value to set.
- LPCTSTR szKey=NULL, // Name of key, NULL==default.
- HKEY hKey=HKEY_LOCAL_MACHINE);// What key to work on.
-
-
-
-//*****************************************************************************
-// Set an entry in the registry of the form:
-// HKEY_CLASSES_ROOT\szKey\szSubkey = szValue. If szSubkey or szValue are
-// NULL, omit them from the above expression.
-//*****************************************************************************
- static BOOL SetKeyAndValue( // TRUE or FALSE.
- LPCTSTR szKey, // Name of the reg key to set.
- LPCTSTR szSubkey, // Optional subkey of szKey.
- LPCTSTR szValue); // Optional value for szKey\szSubkey.
-
-//*****************************************************************************
-// Delete an entry in the registry of the form:
-// HKEY_CLASSES_ROOT\szKey\szSubkey.
-//*****************************************************************************
- static LONG DeleteKey( // TRUE or FALSE.
- LPCTSTR szKey, // Name of the reg key to set.
- LPCTSTR szSubkey); // Subkey of szKey.
-
-//*****************************************************************************
-// Open the key, create a new keyword and value pair under it.
-//*****************************************************************************
- static BOOL SetRegValue( // Return status.
- LPCTSTR szKeyName, // Name of full key.
- LPCTSTR szKeyword, // Name of keyword.
- LPCTSTR szValue); // Value of keyword.
-
-//*****************************************************************************
-// Does standard registration of a CoClass with a progid.
-//*****************************************************************************
- static HRESULT RegisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID.
- LPCTSTR szDesc, // Description of the class.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID, // Class progid.
- LPCTSTR szThreadingModel, // What threading model to use.
- LPCTSTR szModule, // Path to class.
- HINSTANCE hInst, // Handle to module being registered
- LPCTSTR szAssemblyName, // Optional assembly name
- LPCTSTR szVersion, // Optional Runtime Version (directry containing runtime)
- BOOL fExternal, // flag - External to mscoree.
- BOOL fRelativePath); // flag - Relative path in szModule
-
-//*****************************************************************************
-// Unregister the basic information in the system registry for a given object
-// class.
-//*****************************************************************************
- static HRESULT UnregisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID, // Class progid.
- BOOL fExternal); // flag - External to mscoree.
-
-//*****************************************************************************
-// Does standard registration of a CoClass with a progid.
-// NOTE: This is the non-side-by-side execution version.
-//*****************************************************************************
- static HRESULT RegisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID.
- LPCTSTR szDesc, // Description of the class.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID, // Class progid.
- LPCTSTR szThreadingModel, // What threading model to use.
- LPCTSTR szModule, // Path to class.
- BOOL bInprocServer = true); // Whether we register the server as inproc or local
-
-//*****************************************************************************
-// Unregister the basic information in the system registry for a given object
-// class.
-// NOTE: This is the non-side-by-side execution version.
-//*****************************************************************************
- static HRESULT UnregisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID); // Class progid.
-
-//*****************************************************************************
-// Register a type library.
-//*****************************************************************************
- static HRESULT RegisterTypeLib( // Return code.
- REFGUID rtlbid, // TypeLib ID we are registering.
- int iVersion, // Typelib version.
- LPCTSTR szDesc, // TypeLib description.
- LPCTSTR szModule); // Path to the typelib.
-
-//*****************************************************************************
-// Remove the registry keys for a type library.
-//*****************************************************************************
- static HRESULT UnregisterTypeLib( // Return code.
- REFGUID rtlbid, // TypeLib ID we are registering.
- int iVersion); // Typelib version.
-
-#endif //#ifndef FEATURE_CORECLR
//*****************************************************************************
// (Optional) Initialize the config registry cache
@@ -1408,31 +1244,6 @@ public:
private:
-#ifndef FEATURE_CORECLR
-
-//*****************************************************************************
-// Register the basics for a in proc server.
-//*****************************************************************************
- static HRESULT RegisterClassBase( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szDesc, // Class description.
- LPCTSTR szProgID, // Class prog ID.
- LPCTSTR szIndepProgID, // Class version independant prog ID.
- __out_ecount (cchOutCLSID) LPTSTR szOutCLSID, // CLSID formatted in character form.
- DWORD cchOutCLSID); // Out CLS ID buffer size in characters
-
-
-//*****************************************************************************
-// Delete the basic settings for an inproc server.
-//*****************************************************************************
- static HRESULT UnregisterClassBase( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szProgID, // Class prog ID.
- LPCTSTR szIndepProgID, // Class version independant prog ID.
- __out_ecount (cchOutCLSID) LPTSTR szOutCLSID, // Return formatted class ID here.
- DWORD cchOutCLSID); // Out CLS ID buffer size in characters
-
-#endif //#ifndef FEATURE_CORECLR
//*****************************************************************************
// Return TRUE if the registry value name might have been seen in the registry
@@ -4688,18 +4499,6 @@ public:
return NtCurrentTeb()->ProcessEnvironmentBlock;
}
-#ifndef FEATURE_CORECLR
- static void* GetFiberDataPtr()
- {
- LIMITED_METHOD_CONTRACT;
- return ClrTeb::IsCurrentThreadAFiber()? GetCurrentFiber() : NULL;
- }
-
- static BOOL IsCurrentThreadAFiber()
- {
- return IsThreadAFiber();
- }
-#endif
static void* InvalidFiberPtrId()
{
@@ -5205,22 +5004,6 @@ typedef Wrapper<BSTR, DoNothing, HolderSysFreeString> BSTRHolder;
BOOL FileExists(LPCWSTR filename);
-#ifndef FEATURE_CORECLR
-class FileLockHolder
-{
-public:
- FileLockHolder();
- ~FileLockHolder();
-
- virtual void Acquire(LPCWSTR lockName, HANDLE hInterrupt = 0, BOOL* pInterrupted = NULL);
- HRESULT AcquireNoThrow(LPCWSTR lockName, HANDLE hInterrupt = 0, BOOL* pInterrupted = NULL);
-
- static BOOL IsTaken(LPCWSTR lockName);
- void Release();
-private:
- HANDLE _hLock;
-};
-#endif // FEATURE_CORECLR
// a class for general x.x version info
class MajorMinorVersionInfo
@@ -5336,7 +5119,6 @@ struct CoreClrCallbacks
pfnGetCLRFunction_t m_pfnGetCLRFunction;
};
-#if defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
// For DAC, we include this functionality only when EH SxS is enabled.
@@ -5362,7 +5144,6 @@ void OnUninitializedCoreClrCallbacks();
#define VALIDATECORECLRCALLBACKS()
#endif //_DEBUG
-#endif // defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
#ifdef FEATURE_CORRUPTING_EXCEPTIONS
@@ -5572,33 +5353,6 @@ void* FindLocalizedFile(_In_z_ LPCWSTR wzResourceDllName, LocalizedFileHandler l
BOOL IsClrHostedLegacyComObject(REFCLSID rclsid);
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-
-// No utilcode code should use the global LoadLibraryShim anymore. UtilCode::LoadLibraryShim will do
-// the right thing based on whether the hosted or non-hosted utilcode is linked to. Using the global
-// LoadLibraryShim will result in a deprecated use warning.
-
-#ifdef SELF_NO_HOST
-#define LEGACY_ACTIVATION_SHIM_LOAD_LIBRARY WszLoadLibrary
-#include "legacyactivationshim.h"
-#include "mscoreepriv.h"
-
-namespace UtilCode
-{
- inline HRESULT LoadLibraryShim(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE *phModDll)
- {
- return LegacyActivationShim::LoadLibraryShim(szDllName, szVersion, pvReserved, phModDll);
- }
-};
-#else // SELF_NO_HOST
-namespace UtilCode
-{
- // Hosted environment
- HRESULT LoadLibraryShim(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE *phModDll);
-};
-#endif // SELF_NO_HOST
-
-#endif // !FEATURE_CORECLR && !CROSSGEN_COMPILE
// Helper to support termination due to heap corruption
@@ -5606,10 +5360,6 @@ namespace UtilCode
void EnableTerminationOnHeapCorruption();
-#if !defined(FEATURE_CORECLR)
-// On success, sets pwszProcessExePath (required) to full path to process EXE.
-HRESULT GetProcessExePath(LPCWSTR *pwszProcessExePath);
-#endif
namespace Clr { namespace Util
{
diff --git a/src/inc/volatile.h b/src/inc/volatile.h
index c295f98696..9531d98085 100644
--- a/src/inc/volatile.h
+++ b/src/inc/volatile.h
@@ -479,7 +479,7 @@ public:
#else
// Disable use of Volatile<T> for GC/HandleTable code except on platforms where it's absolutely necessary.
-#if defined(_MSC_VER) && !defined(_ARM_)
+#if defined(_MSC_VER) && !defined(_ARM_) && !defined(_ARM64_)
#define VOLATILE(T) T RAW_KEYWORD(volatile)
#else
#define VOLATILE(T) Volatile<T>
diff --git a/src/inc/vptr_list.h b/src/inc/vptr_list.h
index bac0c1165e..a0333c3239 100644
--- a/src/inc/vptr_list.h
+++ b/src/inc/vptr_list.h
@@ -27,22 +27,10 @@ VPTR_CLASS(Module)
VPTR_CLASS(ReflectionModule)
VPTR_CLASS(AppDomain)
-#ifndef FEATURE_CORECLR // FEATURE_NATIVE_IMAGE_GENERATION
-VPTR_MULTI_CLASS(CompilationDomain, AppDomain)
-#endif
VPTR_CLASS(SharedDomain)
VPTR_CLASS(SystemDomain)
VPTR_CLASS(DomainAssembly)
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-VPTR_CLASS(DomainModule)
-#endif
-#ifdef FEATURE_REMOTING
-#ifdef _TARGET_AMD64_ // HAS_REMOTING_PRECODE
-VPTR_CLASS(CNonVirtualThunkMgr)
-#endif
-VPTR_CLASS(CVirtualThunkMgr)
-#endif
VPTR_CLASS(PrecodeStubManager)
VPTR_CLASS(StubLinkStubManager)
VPTR_CLASS(ThePreStubManager)
@@ -57,9 +45,6 @@ VPTR_CLASS(DelegateInvokeStubManager)
VPTR_CLASS(TailCallStubManager)
VPTR_CLASS(PEFile)
VPTR_CLASS(PEAssembly)
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-VPTR_CLASS(PEModule)
-#endif
VPTR_CLASS(PEImageLayout)
VPTR_CLASS(RawImageLayout)
VPTR_CLASS(ConvertedImageLayout)
@@ -68,20 +53,12 @@ VPTR_CLASS(MappedImageLayout)
VPTR_CLASS(LoadedImageLayout)
#endif // !CROSSGEN_COMPILE && !FEATURE_PAL
VPTR_CLASS(FlatImageLayout)
-#ifdef FEATURE_FUSION
-VPTR_CLASS(StreamImageLayout)
-#endif
#ifdef FEATURE_COMINTEROP
VPTR_CLASS(ComMethodFrame)
VPTR_CLASS(ComPlusMethodFrame)
VPTR_CLASS(ComPrestubMethodFrame)
#endif // FEATURE_COMINTEROP
VPTR_CLASS(ContextTransitionFrame)
-#ifdef FEATURE_REMOTING
-VPTR_CLASS(GCSafeCollectionFrame)
-VPTR_CLASS(GCSafeObjectTable)
-VPTR_CLASS(GCSafeObjectHashTable)
-#endif
#ifdef FEATURE_INTERPRETER
VPTR_CLASS(InterpreterFrame)
#endif // FEATURE_INTERPRETER
@@ -100,10 +77,6 @@ VPTR_CLASS(HelperMethodFrame_PROTECTOBJ)
VPTR_CLASS(HijackFrame)
#endif
VPTR_CLASS(InlinedCallFrame)
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) && defined(_TARGET_X86_)
-VPTR_CLASS(LeaveRuntimeFrame)
-VPTR_CLASS(ReverseEnterRuntimeFrame)
-#endif
VPTR_CLASS(SecureDelegateFrame)
VPTR_CLASS(SecurityContextFrame)
VPTR_CLASS(MulticastFrame)
@@ -123,9 +96,6 @@ VPTR_CLASS(DynamicHelperFrame)
#if !defined(_TARGET_X86_)
VPTR_CLASS(StubHelperFrame)
#endif
-#ifdef FEATURE_REMOTING
-VPTR_CLASS(TPMethodFrame)
-#endif
#if defined(_TARGET_X86_)
VPTR_CLASS(UMThkCallFrame)
#endif
diff --git a/src/inc/winrt/windowsruntime.h b/src/inc/winrt/windowsruntime.h
index 766b94ab9c..2ac4391612 100644
--- a/src/inc/winrt/windowsruntime.h
+++ b/src/inc/winrt/windowsruntime.h
@@ -9,18 +9,6 @@
#include <windowsstring.h>
#include "holder.h"
-#ifdef FEATURE_LEAVE_RUNTIME_HOLDER
- #define HR_LEAVE_RUNTIME_HOLDER(X) \
- GCX_PREEMP(); \
- LeaveRuntimeHolderNoThrow lrh(X); \
- if (FAILED(lrh.GetHR())) \
- { \
- return lrh.GetHR(); \
- }
-#else
- #define HR_LEAVE_RUNTIME_HOLDER(X) (void *)0;
-#endif
-
#ifndef IID_INS_ARGS
#define IID_INS_ARGS(ppType) __uuidof(**(ppType)), IID_INS_ARGS_Helper(ppType)
#endif
@@ -42,7 +30,7 @@ namespace clr
__deref_out ItfT** ppItf)
{
LIMITED_METHOD_CONTRACT;
- HR_LEAVE_RUNTIME_HOLDER(::RoGetActivationFactory);
+ GCX_PREEMP();
return GetActivationFactory(wzActivatableClassId.Get(), ppItf);
}
@@ -52,13 +40,12 @@ namespace clr
__in typename ReleaseHolder<ItfT>& hItf)
{
LIMITED_METHOD_CONTRACT;
- HR_LEAVE_RUNTIME_HOLDER(::RoGetActivationFactory);
+ GCX_PREEMP();
return GetActivationFactory(wzActivatableClassId.Get(), (ItfT**)&hItf);
}
} // namespace winrt
} // namespace clr
#endif //CROSSGEN_COMPILE
-#undef HR_LEAVE_RUNTIME_HOLDER
#endif // WindowsRuntime_h
diff --git a/src/inc/winwrap.h b/src/inc/winwrap.h
index 4a012d3726..820d64bdff 100644
--- a/src/inc/winwrap.h
+++ b/src/inc/winwrap.h
@@ -484,7 +484,6 @@
#define WszLogonUser LogonUserW
#define WszCreateProcessAsUser CreateProcessAsUserW
#define WszGetCurrentHwProfile GetCurrentHwProfileW
-#define WszGetVersionEx GetVersionExW
#define WszCreateJobObject CreateJobObjectW
#define WszOpenJobObject OpenJobObjectW
@@ -633,16 +632,6 @@
#define WszRegQueryValueExTrue RegQueryValueExW
#define WszRegQueryStringValueEx RegQueryValueExW
-#ifndef FEATURE_CORECLR
-#define WszRegDeleteKey RegDeleteKeyW
-#define WszRegCreateKeyEx ClrRegCreateKeyEx
-#define WszRegSetValueEx RegSetValueExW
-#define WszRegDeleteValue RegDeleteValueW
-#define WszRegLoadKey RegLoadKeyW
-#define WszRegUnLoadKey RegUnLoadKeyW
-#define WszRegRestoreKey RegRestoreKeyW
-#define WszRegReplaceKey RegReplaceKeyW
-#endif //#ifndef FEATURE_CORECLR
#define WszRegQueryInfoKey RegQueryInfoKeyW
#define WszRegEnumValue RegEnumValueW
@@ -935,8 +924,6 @@ __forceinline LONGLONG __InterlockedExchangeAdd64(LONGLONG volatile * Addend, LO
#define CLR_VER_SUITENAME 0x0000040
#define CLR_VER_PRODUCT_TYPE 0x0000080
-BOOL GetOSVersion(LPOSVERSIONINFOW osVer);
-
// Output printf-style formatted text to the debugger if it's present or stdout otherwise.
inline void DbgWPrintf(const LPCWSTR wszFormat, ...)
{
diff --git a/src/inc/zapper.h b/src/inc/zapper.h
index 1018505faa..a55ddbe75f 100644
--- a/src/inc/zapper.h
+++ b/src/inc/zapper.h
@@ -18,9 +18,6 @@
#include "shash.h"
#include "utilcode.h"
#include "corjit.h"
-#ifdef FEATURE_FUSION
-#include "binderngen.h"
-#endif
#include "corcompile.h"
#include "corhlprpriv.h"
#include "ngen.h"
@@ -115,22 +112,20 @@ class Zapper
BOOL m_failed;
CorInfoRegionKind m_currentRegionKind;
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
SString m_platformAssembliesPaths;
SString m_trustedPlatformAssemblies;
SString m_platformResourceRoots;
SString m_appPaths;
SString m_appNiPaths;
SString m_platformWinmdPaths;
-#endif // FEATURE_CORECLR || CROSSGEN_COMPILE
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
SString m_CLRJITPath;
bool m_fDontLoadJit;
-#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
-#if defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(NO_NGENPDB)
SString m_DiasymreaderPath;
-#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#endif // !defined(NO_NGENPDB)
bool m_fForceFullTrust;
SString m_outputFilename;
@@ -270,65 +265,6 @@ class Zapper
}
} m_assemblyDependencies;
-#ifndef FEATURE_CORECLR // No load lists on CoreCLR
- struct loadLists
- {
- loadLists() :
- m_loadAlwaysList(NULL),
- m_loadSometimesList(NULL),
- m_loadNeverList(NULL)
- {
- }
-
- SAFEARRAY *m_loadAlwaysList;
- SAFEARRAY *m_loadSometimesList;
- SAFEARRAY *m_loadNeverList;
-
- void SetLoadLists(SAFEARRAY *loadAlwaysList, SAFEARRAY *loadSometimesList, SAFEARRAY *loadNeverList)
- {
- m_loadAlwaysList = loadAlwaysList;
- m_loadSometimesList = loadSometimesList;
- m_loadNeverList = loadNeverList;
- }
-
- } m_loadLists;
-
- void SetLoadLists(SAFEARRAY *loadAlwaysList, SAFEARRAY *loadSometimesList, SAFEARRAY *loadNeverList)
- {
- m_loadLists.SetLoadLists(loadAlwaysList, loadSometimesList, loadNeverList);
- }
-
- void SetAssemblyHardBindList()
- {
- SAFEARRAY *loadAlwaysList = m_loadLists.m_loadAlwaysList;
- if (loadAlwaysList == NULL)
- {
- return;
- }
-
- LONG ubound = 0;
- IfFailThrow(SafeArrayGetUBound(loadAlwaysList, 1, &ubound));
-
- BSTR *pArrBstr = NULL;
- IfFailThrow(SafeArrayAccessData(loadAlwaysList, reinterpret_cast<void **>(&pArrBstr)));
-
- EX_TRY
- {
- _ASSERTE((ubound + 1) >= 0);
- m_pEECompileInfo->SetAssemblyHardBindList(reinterpret_cast<LPWSTR *>(pArrBstr), ubound + 1);
- }
- EX_CATCH
- {
- // If something went wrong, try to unlock the OLE array
- // Do not verify the outcome, as we can do nothing about it
- SafeArrayUnaccessData(loadAlwaysList);
- EX_RETHROW;
- }
- EX_END_CATCH_UNREACHABLE;
-
- IfFailThrow(SafeArrayUnaccessData(loadAlwaysList));
- }
-#endif // !FEATURE_CORECLR
public:
@@ -355,30 +291,6 @@ class Zapper
void InitEE(BOOL fForceDebug, BOOL fForceProfile, BOOL fForceInstrument);
void LoadAndInitializeJITForNgen(LPCWSTR pwzJitName, OUT HINSTANCE* phJit, OUT ICorJitCompiler** ppICorJitCompiler);
-#ifdef FEATURE_FUSION
- HRESULT TryEnumerateFusionCache(LPCWSTR assemblyName, bool fPrint, bool fDelete);
- int EnumerateFusionCache(LPCWSTR assemblyName, bool fPrint, bool fDelete,
- CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig = NULL);
- void PrintFusionCacheEntry(CorSvcLogLevel logLevel, IAssemblyName *pZapAssemblyName);
- void DeleteFusionCacheEntry(IAssemblyName *pZapAssemblyName);
- void DeleteFusionCacheEntry(LPCWSTR assemblyName, CORCOMPILE_NGEN_SIGNATURE *pNativeImageSig);
-
- void PrintDependencies(
- IMetaDataAssemblyImport * pAssemblyImport,
- CORCOMPILE_DEPENDENCY * pDependencies,
- COUNT_T cDependencies,
- SString &s);
- BOOL VerifyDependencies(
- IMDInternalImport * pAssemblyImport,
- CORCOMPILE_DEPENDENCY * pDependencies,
- COUNT_T cDependencies);
-
- void PrintAssemblyVersionInfo(IAssemblyName *pZapAssemblyName, SString &s);
-
- IAssemblyName *GetAssemblyFusionName(IMetaDataAssemblyImport *pImport);
- IAssemblyName *GetAssemblyRefFusionName(IMetaDataAssemblyImport *pImport,
- mdAssemblyRef ar);
-#endif //FEATURE_FUSION
BOOL IsAssembly(LPCWSTR path);
@@ -398,14 +310,6 @@ class Zapper
void CompileAssembly(CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig);
ZapImage * CompileModule(CORINFO_MODULE_HANDLE hModule,
IMetaDataAssemblyEmit *pEmit);
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- void CompileNonManifestModules(ULONG hashAlgId, SArray<HANDLE> &hFiles);
- static void * GetMapViewOfFile(
- HANDLE hFile,
- DWORD * pdwFileLen);
- static void ComputeHashValue(HANDLE hFile, int hashAlg,
- BYTE **ppHashValue, DWORD *cbHashValue);
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
void InstallCompiledAssembly(LPCWSTR szAssemblyName, LPCWSTR szNativeImagePath, HANDLE hFile, SArray<HANDLE> &hFiles);
HRESULT GetExceptionHR();
@@ -442,7 +346,6 @@ class Zapper
void GetOutputFolder();
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
void SetPlatformAssembliesPaths(LPCWSTR pwzPlatformAssembliesPaths);
void SetTrustedPlatformAssemblies(LPCWSTR pwzTrustedPlatformAssemblies);
void SetPlatformResourceRoots(LPCWSTR pwzPlatformResourceRoots);
@@ -450,16 +353,15 @@ class Zapper
void SetAppNiPaths(LPCWSTR pwzAppNiPaths);
void SetPlatformWinmdPaths(LPCWSTR pwzPlatformWinmdPaths);
void SetForceFullTrust(bool val);
-#endif // FEATURE_CORECLR || CROSSGEN_COMPILE
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
void SetCLRJITPath(LPCWSTR pwszCLRJITPath);
void SetDontLoadJit();
-#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE)
-#if defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#if !defined(NO_NGENPDB)
void SetDiasymreaderPath(LPCWSTR pwzDiasymreaderPath);
-#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#endif // !defined(NO_NGENPDB)
void SetOutputFilename(LPCWSTR pwszOutputFilename);
SString GetOutputFileName();
@@ -544,9 +446,7 @@ class ZapperOptions
bool m_legacyMode; // true if the zapper was invoked using legacy mode
-#ifdef FEATURE_CORECLR
bool m_fNoMetaData; // Do not copy metadata and IL to native image
-#endif
ZapperOptions();
~ZapperOptions();
diff --git a/src/ipcman/ipcfunccallimpl.cpp b/src/ipcman/ipcfunccallimpl.cpp
index 7107e28905..ed3a2bcaed 100644
--- a/src/ipcman/ipcfunccallimpl.cpp
+++ b/src/ipcman/ipcfunccallimpl.cpp
@@ -18,623 +18,6 @@
#include "ipcfunccall.h"
#include "ipcshared.h"
-#if defined(FEATURE_PERFMON) && defined(FEATURE_IPCMAN)
-
-// #define ENABLE_TIMING
-
-#ifdef ENABLE_TIMING
-#include "timer.h"
-CTimer g_time;
-#endif // ENABLE_TIMING
-
-//-----------------------------------------------------------------------------
-// <TODO>@todo: This is very generic. However, If we want to support multiple
-// functions calls, we will have to decorate the event object names.</TODO>
-//-----------------------------------------------------------------------------
-
-#define NamePrexix L"Global\\CLR_"
-
-// Name of sync objects
-#define StartEnumEventName NamePrexix L"PerfMon_StartEnumEvent"
-#define DoneEnumEventName NamePrexix L"PerfMon_DoneEnumEvent"
-#define WrapMutexName NamePrexix L"PerfMon_WrapMutex"
-
-// Time the Source Caller is willing to wait for Handler to finish
-// Note, a nefarious handler can at worst case make caller
-// wait twice the delay below.
-const DWORD START_ENUM_TIMEOUT = 500; // time out in milliseconds
-
-//-----------------------------------------------------------------------------
-// Wrap an unsafe call in a mutex to assure safety
-// Biggest error issues are:
-// 1. Timeout (probably handler doesn't exist)
-// 2. Handler can be destroyed at any time.
-//-----------------------------------------------------------------------------
-IPCFuncCallSource::EError IPCFuncCallSource::DoThreadSafeCall()
-{
- WRAPPER_NO_CONTRACT;
-
- DWORD dwDesiredAccess;
- DWORD dwErr;
- EError err = Ok;
-
-#if defined(ENABLE_TIMING)
- g_time.Reset();
- g_time.Start();
-#endif
-
- dwDesiredAccess = EVENT_MODIFY_STATE;
-
- HANDLE hStartEnum = NULL;
- HANDLE hDoneEnum = NULL;
- HANDLE hWrapCall = NULL;
- DWORD dwWaitRet;
-
- // Check if we have a handler (handler creates the events) and
- // abort if not. Do this check asap to optimize the most common
- // case of no handler.
- hStartEnum = WszOpenEvent(dwDesiredAccess,
- FALSE,
- StartEnumEventName);
- if (hStartEnum == NULL)
- {
- dwErr = GetLastError();
- err = Fail_NoHandler;
- goto errExit;
- }
-
- hDoneEnum = WszOpenEvent(dwDesiredAccess,
- FALSE,
- DoneEnumEventName);
- if (hDoneEnum == NULL)
- {
- dwErr = GetLastError();
- err = Fail_NoHandler;
- goto errExit;
- }
-
- // Need to create the mutex
- hWrapCall = WszCreateMutex(NULL, FALSE, WrapMutexName);
- if (hWrapCall == NULL)
- {
- dwErr = GetLastError();
- err = Fail_CreateMutex;
- goto errExit;
- }
-
-
-// Wait for our turn
- dwWaitRet = WaitForSingleObject(hWrapCall, START_ENUM_TIMEOUT);
- dwErr = GetLastError();
- switch(dwWaitRet) {
- case WAIT_OBJECT_0:
- // Good case. All other cases are errors and goto errExit.
- break;
-
- case WAIT_TIMEOUT:
- err = Fail_Timeout_Lock;
- goto errExit;
- break;
- default:
- err = Failed;
- goto errExit;
- break;
- }
-
- // Our turn: Make the function call
- {
- BOOL fSetOK = 0;
-
- // Reset the 'Done event' to make sure that Handler sets it after they start.
- fSetOK = ResetEvent(hDoneEnum);
- _ASSERTE(fSetOK);
- dwErr = GetLastError();
-
- // Signal Handler to execute callback
- fSetOK = SetEvent(hStartEnum);
- _ASSERTE(fSetOK);
- dwErr = GetLastError();
-
- // Now wait for handler to finish.
-
- dwWaitRet = WaitForSingleObject(hDoneEnum, START_ENUM_TIMEOUT);
- dwErr = GetLastError();
- switch (dwWaitRet)
- {
- case WAIT_OBJECT_0:
- break;
- case WAIT_TIMEOUT:
- err = Fail_Timeout_Call;
- break;
- default:
- err = Failed;
- break;
- }
-
-
- BOOL fMutexOk;
- fMutexOk = ReleaseMutex(hWrapCall);
- _ASSERTE(fMutexOk);
- dwErr = GetLastError();
-
- } // End function call
-
-
-
-errExit:
-// Close all handles
- if (hStartEnum != NULL)
- {
- CloseHandle(hStartEnum);
- hStartEnum = NULL;
-
- }
- if (hDoneEnum != NULL)
- {
- CloseHandle(hDoneEnum);
- hDoneEnum = NULL;
- }
- if (hWrapCall != NULL)
- {
- CloseHandle(hWrapCall);
- hWrapCall = NULL;
- }
-
-#if defined(ENABLE_TIMING)
- g_time.End();
- DWORD dwTime = g_time.GetEllapsedMS();
-#endif
-
-
- return err;
-
-}
-
-
-// Reset vars so we can be sure that Init was called
-IPCFuncCallHandler::IPCFuncCallHandler()
-{
- m_hStartEnum = NULL; // event to notify start call
- m_hDoneEnum = NULL; // event to notify end call
- m_hAuxThread = NULL; // thread to listen for m_hStartEnum
- m_pfnCallback = NULL; // Callback handler
- m_pfnCleanupCallback = NULL; // Cleanup callback handler
- m_fShutdownAuxThread = FALSE;
- m_hShutdownThread = NULL;
- m_hCallbackModule = NULL; // module in which the aux thread's start function lives
-}
-
-IPCFuncCallHandler::~IPCFuncCallHandler()
-{
- // If Terminate was not called then do so now. This should have been
- // called from CloseCtrs perf counters API. But in Windows XP this order is
- // not guaranteed.
- TerminateFCHandler();
-}
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning (disable: 6320) //We handle ALL exceptions so that the host process doesnt die
-#endif
-
-//-----------------------------------------------------------------------------
-// Thread callback
-//-----------------------------------------------------------------------------
-DWORD WINAPI HandlerAuxThreadProc(
- LPVOID lpParameter // thread data
-)
-{
- IPCFuncCallHandler * pHandler = (IPCFuncCallHandler *) lpParameter;
-
- struct Param
- {
- IPCFuncCallHandler * pHandler;
- } param;
- param.pHandler = pHandler;
-
- PAL_TRY(Param *, pParam, &param)
- {
- HANDLER_CALLBACK pfnCallback = pParam->pHandler->m_pfnCallback;
-
- DWORD dwErr = 0;
- DWORD dwWaitRet;
-
- HANDLE lpHandles[] = {pParam->pHandler->m_hShutdownThread, pParam->pHandler->m_hStartEnum};
- DWORD dwHandleCount = 2;
-
- do {
- dwWaitRet = WaitForMultipleObjects(dwHandleCount, lpHandles, FALSE /*Wait Any*/, INFINITE);
- dwErr = GetLastError();
-
- // If we are in terminate mode then exit this helper thread.
- if (pParam->pHandler->m_fShutdownAuxThread)
- break;
-
- // Keep the 0th index for the terminate thread so that we never miss it
- // in case of multiple events. note that the ShutdownAuxThread flag above it purely
- // to protect us against some bug in waitForMultipleObjects.
- if ((dwWaitRet-WAIT_OBJECT_0) == 0)
- break;
-
- // execute callback if wait succeeded
- if ((dwWaitRet-WAIT_OBJECT_0) == 1)
- {
- (*pfnCallback)();
-
- // reset manual event
- BOOL fResetOK;
- fResetOK = ResetEvent(pParam->pHandler->m_hStartEnum);
- _ASSERTE(fResetOK);
- dwErr = GetLastError();
-
- BOOL fSetOK;
- fSetOK = SetEvent(pParam->pHandler->m_hDoneEnum);
- _ASSERTE(fSetOK);
- dwErr = GetLastError();
- }
- } while (dwWaitRet != WAIT_FAILED);
- }
- PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- WCHAR wszMsg[128];
- swprintf_s(wszMsg, COUNTOF(wszMsg), L"HandlerAuxThreadProc caught exception %x", GetExceptionCode());
- ClrReportEvent(L".NET Runtime",
- EVENTLOG_ERROR_TYPE,
- 0,
- 0,
- NULL,
- wszMsg);
- }
- PAL_ENDTRY
-
-
- pHandler->SafeCleanup();
-
- HMODULE hCallbackModule = pHandler->m_hCallbackModule;
- pHandler->m_hCallbackModule = NULL;
-
- pHandler->m_fShutdownAuxThread = FALSE;
-
- // Close the thread's handle and clear the shut down flag. Note the order here is very tricky
- // to avoid a race. We must set the shutdown flag first to ensure that once m_hAuxThread is set
- // to NULL no further modification happens to pHandler.
- HANDLE hThread = InterlockedExchangeT(&pHandler->m_hAuxThread, NULL);
-
- // If hThread was null then WaitForCompletion will close it.
- if (hThread != NULL)
- CloseHandle(hThread);
-
- FreeLibraryAndExitThread (hCallbackModule, 0);
- // Above call doesn't return
-
- return 0;
-}
-
-#ifdef _MSC_VER
-#pragma warning (pop) //6320
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Receieves the call. This should be in a different process than the source
-//-----------------------------------------------------------------------------
-HRESULT IPCFuncCallHandler::InitFCHandler(HANDLER_CALLBACK pfnCallback, HANDLER_CALLBACK pfnCleanupCallback)
-{
- // If the thread is still in the process of shutting down then
- // we have to fail.
- if (!IsShutdownComplete())
- {
- _ASSERTE(!"shutdown should have completed before calling this function");
- return E_FAIL;
- }
-
- m_pfnCallback = pfnCallback;
- m_pfnCleanupCallback = pfnCleanupCallback;
-
- HRESULT hr = NOERROR;
- DWORD dwThreadId;
- DWORD dwErr = 0;
- DWORD dwDesiredAccess;
- DWORD dwRet = 0;
- HANDLE hToken = NULL;
-
- SetLastError(0);
-
- // Grab the SA
- DWORD dwPid = 0;
- SECURITY_ATTRIBUTES *pSA = NULL;
-
- dwDesiredAccess = EVENT_MODIFY_STATE | SYNCHRONIZE;
-
- dwPid = GetCurrentProcessId();
- hr = IPCShared::CreateWinNTDescriptor(dwPid, FALSE, &pSA, Event, eDescriptor_Public);
-
- if (FAILED(hr))
- goto errExit;;
-
- // try to open event first (another process may already have created one)
- m_hStartEnum = WszOpenEvent(dwDesiredAccess,
- FALSE,
- L"Global\\" StartEnumEventName);
- if (m_hStartEnum == NULL)
- {
- // Create the StartEnum Event
- m_hStartEnum = WszCreateEvent(pSA,
- TRUE, // manual event for multiple instances of corperfmonext.dll
- FALSE,
- StartEnumEventName);
- }
-
- if (m_hStartEnum == NULL)
- {
- dwErr = GetLastError();
- hr = HRESULT_FROM_WIN32(dwErr);
- goto errExit;
- }
-
- // try to open event first (another process may already have created one)
- m_hDoneEnum = WszOpenEvent(dwDesiredAccess,
- FALSE,
- L"Global\\" DoneEnumEventName);
-
- if (m_hDoneEnum == NULL)
- {
- // Create the EndEnumEvent
- m_hDoneEnum = WszCreateEvent(pSA,
- TRUE, // manual event for multiple instances of corperfmonext.dll
- FALSE,
- DoneEnumEventName);
- }
- if (m_hDoneEnum == NULL)
- {
- dwErr = GetLastError();
- hr = HRESULT_FROM_WIN32(dwErr);
- goto errExit;
- }
-
- // Create the ShutdownThread Event
- m_hShutdownThread = WszCreateEvent(pSA,
- TRUE, /* Manual Reset */
- FALSE, /* Initial state not signalled */
- NULL);
-
- dwErr = GetLastError();
- if (m_hShutdownThread == NULL)
- {
- hr = HRESULT_FROM_WIN32(dwErr);
- goto errExit;
- }
-
- BOOL bSuccess = FALSE;
-
- // Get current thread token with duplicate and impersonation access
- // Will use this token for polling thread impersonation if current
- // thread is impersonating
- bSuccess = OpenThreadToken(
- GetCurrentThread(),
- TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE,
- TRUE,
- &hToken
- );
-
- dwErr = GetLastError();
- // token won't exist if running local becase we are not impersonating
- if (FALSE == bSuccess && ERROR_NO_TOKEN != dwErr)
- {
- hr = HRESULT_FROM_WIN32(dwErr);
- goto errExit;
- }
-
- // at this point, we should either have a valid token or we failed
- // to get the token because one does not exist on this thread
- _ASSERTE(NULL != hToken || ERROR_NO_TOKEN == dwErr);
-
- // The thread that we are about to create should always
- // find the code in memory. So we take a ref on the DLL.
- // and do a free library at the end of the thread's start function
- m_hCallbackModule = WszLoadLibrary (L"CorPerfmonExt.dll");
-
- dwErr = GetLastError();
- if (m_hCallbackModule == NULL)
- {
- hr = HRESULT_FROM_WIN32(dwErr);
- goto errExit;
- }
-
- // Create thread suspended so we can set impersonation token
- m_hAuxThread = CreateThread(
- NULL,
- 0,
- HandlerAuxThreadProc,
- this,
- CREATE_SUSPENDED,
- &dwThreadId);
-
- dwErr = GetLastError();
- if (m_hAuxThread.Load() == NULL)
- {
- hr = HRESULT_FROM_WIN32(dwErr);
-
- // In case of an error free this library here otherwise
- // the thread's exit would take care of it.
- if (m_hCallbackModule)
- FreeLibrary (m_hCallbackModule);
- goto errExit;
- }
-
- // If we got a token for the current thread,
- // set token on new thread
- if (NULL != hToken)
- {
- bSuccess = SetThreadToken((PHANDLE)m_hAuxThread.GetPointer(), hToken);
-
- dwErr = GetLastError();
- if (FALSE == bSuccess)
- {
- hr = HRESULT_FROM_WIN32(dwErr);
- goto errExit;
- }
- }
-
- // Resume the newly created thread
- dwRet = ResumeThread(m_hAuxThread);
-
- dwErr = GetLastError();
- if (dwRet == (DWORD)(-1))
- {
- hr = HRESULT_FROM_WIN32(dwErr);
- goto errExit;
- }
-
- _ASSERTE(1 == dwRet);
-
-errExit:
- if (NULL != hToken)
- {
- CloseHandle(hToken);
- }
-
- if (!SUCCEEDED(hr))
- {
- TerminateFCHandler();
- }
-
- if (pSA != NULL)
- {
- IPCShared::DestroySecurityAttributes( pSA );
- }
- return hr;
-
-}
-
-//-----------------------------------------------------------------------------
-// Close all our handles
-//-----------------------------------------------------------------------------
-void IPCFuncCallHandler::SafeCleanup()
-{
- // Call the cleanup callback
-
- if (m_pfnCleanupCallback != NULL)
- {
- struct Param
- {
- IPCFuncCallHandler * pHandler;
- } param;
- param.pHandler = this;
-
- PAL_TRY(Param *, pParam, &param)
- {
- HANDLER_CALLBACK pfnCleanupCallback = pParam->pHandler->m_pfnCleanupCallback;
-
- (*pfnCleanupCallback)();
- }
- PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- WCHAR wszMsg[128];
- swprintf_s(wszMsg, COUNTOF(wszMsg), L"HandlerAuxThreadProc caught exception %x", GetExceptionCode());
- ClrReportEvent(L".NET Runtime",
- EVENTLOG_ERROR_TYPE,
- 0,
- 0,
- NULL,
- wszMsg);
- }
- PAL_ENDTRY
- }
-
-
- // Release all the handles
-
- if (m_hStartEnum != NULL)
- {
- CloseHandle(m_hStartEnum);
- m_hStartEnum = NULL;
- }
-
- if (m_hDoneEnum != NULL)
- {
- CloseHandle(m_hDoneEnum);
- m_hDoneEnum = NULL;
- }
-
- if (m_hShutdownThread != NULL)
- {
- CloseHandle(m_hShutdownThread);
- m_hShutdownThread = NULL;
- }
-
- m_pfnCallback = NULL;
- m_pfnCleanupCallback = NULL;
-}
-
-void IPCFuncCallHandler::TerminateFCHandler()
-{
- // If the thread is in the process of shutting down then
- // there is nothing to do
- if (m_fShutdownAuxThread)
- {
- return;
- }
-
- // If this IPCFuncCallHandler has not been initialized yet
- // then there is nothing to do
- if ((m_hStartEnum == NULL) &&
- (m_hDoneEnum == NULL) &&
- (m_hAuxThread.Load() == NULL) &&
- (m_pfnCallback == NULL))
- {
- return;
- }
-
- if(m_hAuxThread.Load() != NULL)
- {
- // Always resume the thread to make sure it is not suspended
- if (ResumeThread(m_hAuxThread) == (DWORD)(-1))
- {
- _ASSERTE (!"TerminateFCHandler: ResumeThread(m_hAuxThread) failed");
- }
-
- // First make sure that we make the aux thread gracefully exit
- m_fShutdownAuxThread = TRUE;
-
- // Hope that this set event makes the thread quit.
- if (!SetEvent (m_hShutdownThread))
- {
- _ASSERTE (!"TerminateFCHandler: SetEvent(m_hShutdownThread) failed");
- }
- }
- else
- {
- // We failed during InitFCHandler before creating the auxilliary thread
- SafeCleanup();
-
- }
-
- // The aux thread is responsible for cleanup. When it is finished cleaning
- // up it will set m_fShutdownAuxThread to FALSE.
-}
-
-BOOL IPCFuncCallHandler::IsShutdownComplete()
-{
- return m_hAuxThread.Load() == NULL;
-}
-
-void IPCFuncCallHandler::WaitForShutdown()
-{
- // Check to see if the thread handle is null. If it is then the thread has shut down,
- // otherwise we will wait for the thread to exit.
- HANDLE hThread = InterlockedExchangeT(&m_hAuxThread, NULL);
-
- if (hThread != NULL)
- {
- // Otherwise wait for the thread to complete and we close its handle.
- DWORD result = WaitForSingleObject(hThread, INFINITE);
- _ASSERTE(result == WAIT_OBJECT_0);
-
- CloseHandle(hThread);
- }
-}
-#else // !FEATURE_PERFMON || !FEATURE_IPCMAN
// Telesto stubs
@@ -650,4 +33,3 @@ IPCFuncCallSource::EError IPCFuncCallSource::DoThreadSafeCall()
return Ok;
}
-#endif // FEATURE_PERFMON && FEATURE_IPCMAN
diff --git a/src/ipcman/ipcsharedsrc.cpp b/src/ipcman/ipcsharedsrc.cpp
index ed1e7dc1ba..bb0f46bf0d 100644
--- a/src/ipcman/ipcsharedsrc.cpp
+++ b/src/ipcman/ipcsharedsrc.cpp
@@ -18,9 +18,6 @@
#include "ipcshared.h"
#include "ipcmanagerinterface.h"
-#ifndef FEATURE_CORECLR
-#include "AppXUtil.h"
-#endif
#if defined(FEATURE_IPCMAN)
@@ -170,41 +167,6 @@ HRESULT IPCShared::GenerateBlockTableName(DWORD pid, SString & sName, HANDLE & p
return hr;
}
-#ifndef FEATURE_CORECLR
- // when pid != GetCurrentProcessId() it means we're the consumer opening other process perf counter data
- if (pid != GetCurrentProcessId())
- {
- // if the target process is inside an appcontainer we need to add the appcontainer SID to the boundary descriptor.
- NewArrayHolder<BYTE> pbTokenMem;
- hr = AppX::GetAppContainerTokenInfoForProcess(pid, pbTokenMem);
-
- if (FAILED(hr))
- {
- // failed to open the target's process, continue on
- // assuming that the process isn't in an AppContainer.
- _ASSERTE(pbTokenMem == NULL);
- }
- else
- {
- if (hr == S_FALSE)
- {
- // not an appcontainer
- _ASSERTE(pbTokenMem == NULL);
- }
- else
- {
- // process is an appcontainer so add the SID
- PTOKEN_APPCONTAINER_INFORMATION pAppContainerTokenInfo =
- reinterpret_cast<PTOKEN_APPCONTAINER_INFORMATION>(pbTokenMem.GetValue());
- _ASSERTE(pAppContainerTokenInfo);
- _ASSERTE(pAppContainerTokenInfo->TokenAppContainer);
-
- if (!(*pAddSIDToBoundaryDescriptor)(&pBoundaryDesc, pAppContainerTokenInfo->TokenAppContainer))
- return HRESULT_FROM_WIN32(GetLastError());
- }
- }
- }
-#endif // FEATURE_CORECLR
if(bCreate)
{
@@ -666,10 +628,6 @@ BOOL IPCShared::InitializeGenericIPCAcl(DWORD pid, BOOL bRestrictiveACL, PACL *p
int iSIDforAdmin = -1;
int iSIDforUsers = -1;
int iSIDforLoggingUsers = -1;
-#if !defined (DACCESS_COMPILE) && !defined(FEATURE_CORECLR)
- NewArrayHolder<BYTE> pbTokenMem;
- PTOKEN_APPCONTAINER_INFORMATION pAppContainerTokenInfo = NULL;
-#endif
PermStruct[0].rgPSID = NULL;
@@ -802,39 +760,6 @@ BOOL IPCShared::InitializeGenericIPCAcl(DWORD pid, BOOL bRestrictiveACL, PACL *p
// non-fatal error, so don't goto errorexit
}
-#if !defined(DACCESS_COMPILE) && !defined(FEATURE_CORECLR)
- // when running on win8 if the process is an appcontainer then add the appcontainer SID to the ACL
- // going down this code path means we're creating the descriptor for our current PID.
- _ASSERTE(pid == GetCurrentProcessId());
- hr = AppX::GetAppContainerTokenInfoForProcess(pid, pbTokenMem);
-
- if (FAILED(hr))
- {
- // failed to open the target's process, continue on
- // assuming that the process isn't in an AppContainer.
- _ASSERTE(pbTokenMem == NULL);
- }
- else
- {
- if (hr == S_FALSE)
- {
- // not an appcontainer
- _ASSERTE(pbTokenMem == NULL);
- }
- else
- {
- // process is an appcontainer so add the SID
- pAppContainerTokenInfo =
- reinterpret_cast<PTOKEN_APPCONTAINER_INFORMATION>(pbTokenMem.GetValue());
- _ASSERTE(pAppContainerTokenInfo);
- _ASSERTE(pAppContainerTokenInfo->TokenAppContainer);
-
- PermStruct[cActualACECount].rgPSID = pAppContainerTokenInfo->TokenAppContainer;
- PermStruct[cActualACECount].rgAccessFlags = GetAccessFlagsForObject(whatObject, FALSE);
- ++cActualACECount;
- }
- }
-#endif // !defined(DACCESS_COMPILE) && !defined(FEATURE_CORECLR)
}
_ASSERTE(cActualACECount <= MaxNumberACEs);
diff --git a/src/ipcman/ipcwriterimpl.cpp b/src/ipcman/ipcwriterimpl.cpp
index b618f4b542..b2d5ba2a63 100644
--- a/src/ipcman/ipcwriterimpl.cpp
+++ b/src/ipcman/ipcwriterimpl.cpp
@@ -370,63 +370,7 @@ HRESULT IPCWriterInterface::CreateSxSPublicBlockOnPid(DWORD pid)
BOOL openedExistingBlock = FALSE;
-#if defined(FEATURE_PERFMON)
- DWORD dwFileMapErr = 0;
-
- // Retry several times to mitigate a potential race with another
- // runtime shutting down
- for (int tries = 0; tries < 3; ++tries)
- {
- // Connect the handle
- m_handleBlockTable = WszCreateFileMapping(INVALID_HANDLE_VALUE,
- pSA,
- PAGE_READWRITE | SEC_COMMIT,
- 0,
- sizeof(IPCControlBlockTable),
- szMemFileName);
-
- dwFileMapErr = GetLastError();
-
- LOG((LF_CORDB, LL_INFO10, "IPCWI::CPBOP: CreateFileMapping of %S, handle = 0x%08x, pid = 0x%8.8x GetLastError=%d\n",
- szMemFileName.GetUnicode(), m_handleBlockTable, pid, GetLastError()));
-
- // If GetLastError() returns ERROR_ALREADY_EXISTS, then we need to do some extra checks
- if (m_handleBlockTable != NULL && dwFileMapErr == ERROR_ALREADY_EXISTS)
- {
- openedExistingBlock = TRUE;
- }
-
- // If CreateFileMapping() failed with ERROR_ACCESS_DENIED, try calling OpenFileMapping()
- else if (m_handleBlockTable == NULL && dwFileMapErr == ERROR_ACCESS_DENIED)
- {
- // If we could not create the IPCBlockTable due to ERROR_ACCESS_DENIED,
- // then the IPCBlockTable already exists. Next we will try opening the
- // IPCBlockTable using OpenFileMapping().
- m_handleBlockTable = WszOpenFileMapping(FILE_MAP_WRITE,
- FALSE,
- szMemFileName);
- dwFileMapErr = GetLastError();
-
- // There is a chance for a race where another runtime might close the
- // IPCBlockTable before we can open it. Thus, if we get ERROR_FILE_NOT_FOUND
- // we retry calling CreateFileMapping().
- if (m_handleBlockTable == NULL && dwFileMapErr == ERROR_FILE_NOT_FOUND)
- {
- Sleep(1);
- continue;
- }
-
- if (m_handleBlockTable != NULL)
- {
- openedExistingBlock = TRUE;
- }
- }
-
- break;
- }
-#else // !FEATURE_PERFMON
m_handleBlockTable = NULL;
-#endif // FEATURE_PERFMON
// If unsuccessful, don't ever bail out.
if (m_handleBlockTable != NULL)
diff --git a/src/jit/CMakeLists.txt b/src/jit/CMakeLists.txt
index db6e5973ba..e2a9ca66ab 100644
--- a/src/jit/CMakeLists.txt
+++ b/src/jit/CMakeLists.txt
@@ -4,14 +4,13 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include_directories("./jitstd")
include_directories("../inc")
-# Enable the following for UNIX altjit on Windows
-# add_definitions(-DALT_JIT)
-
if (CLR_CMAKE_TARGET_ARCH_AMD64 OR (CLR_CMAKE_TARGET_ARCH_I386 AND NOT CLR_CMAKE_PLATFORM_UNIX))
add_definitions(-DFEATURE_SIMD)
add_definitions(-DFEATURE_AVX_SUPPORT)
endif ()
+# JIT_BUILD disables certain PAL_TRY debugging features
+add_definitions(-DJIT_BUILD=1)
if(WIN32)
set(JIT_RESOURCES Native.rc)
@@ -76,86 +75,99 @@ set( JIT_SOURCES
valuenum.cpp
)
-if(CLR_CMAKE_TARGET_ARCH_AMD64)
- set( ARCH_SOURCES
- codegenxarch.cpp
- emitxarch.cpp
- lowerxarch.cpp
- lsraxarch.cpp
- simd.cpp
- simdcodegenxarch.cpp
- targetamd64.cpp
- unwindamd64.cpp
- )
-elseif(CLR_CMAKE_TARGET_ARCH_ARM)
- set( ARCH_SOURCES
- codegenarm.cpp
- decomposelongs.cpp
- emitarm.cpp
- lowerarm.cpp
- lsraarm.cpp
- targetarm.cpp
- unwindarm.cpp
- )
-elseif(CLR_CMAKE_TARGET_ARCH_I386)
- set( ARCH_SOURCES
- codegenxarch.cpp
- decomposelongs.cpp
- emitxarch.cpp
- lowerxarch.cpp
- lsraxarch.cpp
- simd.cpp
- simdcodegenxarch.cpp
- targetx86.cpp
- unwindx86.cpp
- )
-elseif(CLR_CMAKE_TARGET_ARCH_ARM64)
- set( ARCH_SOURCES
- codegenarm64.cpp
- emitarm64.cpp
- lowerarm64.cpp
- lsraarm64.cpp
- targetarm64.cpp
- unwindarm.cpp
- unwindarm64.cpp
- )
-else()
- clr_unknown_arch()
-endif()
-
# The following defines all the source files used by the "legacy" back-end (#ifdef LEGACY_BACKEND).
# It is always safe to include both legacy and non-legacy files in the build, as everything is properly
# #ifdef'ed, though it makes the build slightly slower to do so. Note there is only a legacy backend for
# x86 and ARM.
-if(CLR_CMAKE_TARGET_ARCH_AMD64)
- set( ARCH_LEGACY_SOURCES
- )
-elseif(CLR_CMAKE_TARGET_ARCH_ARM)
- set( ARCH_LEGACY_SOURCES
+set(JIT_ARM_LEGACY_SOURCES
codegenlegacy.cpp
registerfp.cpp
- )
-elseif(CLR_CMAKE_TARGET_ARCH_I386)
- set( ARCH_LEGACY_SOURCES
+)
+set(JIT_I386_LEGACY_SOURCES
codegenlegacy.cpp
stackfp.cpp
- )
+)
+
+# Define all the architecture-specific source files
+
+set( JIT_AMD64_SOURCES
+ codegenxarch.cpp
+ emitxarch.cpp
+ lowerxarch.cpp
+ lsraxarch.cpp
+ simd.cpp
+ simdcodegenxarch.cpp
+ targetamd64.cpp
+ unwindamd64.cpp
+)
+
+set( JIT_ARM_SOURCES
+ ${JIT_ARM_LEGACY_SOURCES}
+ codegenarmarch.cpp
+ codegenarm.cpp
+ decomposelongs.cpp
+ emitarm.cpp
+ lowerarmarch.cpp
+ lowerarm.cpp
+ lsraarmarch.cpp
+ lsraarm.cpp
+ targetarm.cpp
+ unwindarm.cpp
+)
+
+set( JIT_I386_SOURCES
+ ${JIT_I386_LEGACY_SOURCES}
+ codegenxarch.cpp
+ decomposelongs.cpp
+ emitxarch.cpp
+ lowerxarch.cpp
+ lsraxarch.cpp
+ simd.cpp
+ simdcodegenxarch.cpp
+ targetx86.cpp
+ unwindx86.cpp
+)
+
+set( JIT_ARM64_SOURCES
+ codegenarmarch.cpp
+ codegenarm64.cpp
+ emitarm64.cpp
+ lowerarmarch.cpp
+ lowerarm64.cpp
+ lsraarmarch.cpp
+ lsraarm64.cpp
+ targetarm64.cpp
+ unwindarm.cpp
+ unwindarm64.cpp
+)
+
+if(CLR_CMAKE_TARGET_ARCH_AMD64)
+ set(JIT_ARCH_SOURCES ${JIT_AMD64_SOURCES})
+elseif(CLR_CMAKE_TARGET_ARCH_ARM)
+ set(JIT_ARCH_SOURCES ${JIT_ARM_SOURCES})
+elseif(CLR_CMAKE_TARGET_ARCH_I386)
+ set(JIT_ARCH_SOURCES ${JIT_I386_SOURCES})
elseif(CLR_CMAKE_TARGET_ARCH_ARM64)
- set( ARCH_LEGACY_SOURCES
- )
+ set(JIT_ARCH_SOURCES ${JIT_ARM64_SOURCES})
else()
clr_unknown_arch()
endif()
set( SOURCES
${JIT_SOURCES}
- ${ARCH_SOURCES}
- ${ARCH_LEGACY_SOURCES}
${JIT_RESOURCES}
)
convert_to_absolute_path(SOURCES ${SOURCES})
+convert_to_absolute_path(JIT_ARCH_SOURCES ${JIT_ARCH_SOURCES})
+
+# Also convert the per-architecture sources to absolute paths, if the subdirs want to use them.
+
+convert_to_absolute_path(JIT_AMD64_SOURCES ${JIT_AMD64_SOURCES})
+convert_to_absolute_path(JIT_ARM_SOURCES ${JIT_ARM_SOURCES})
+convert_to_absolute_path(JIT_I386_SOURCES ${JIT_I386_SOURCES})
+convert_to_absolute_path(JIT_ARM64_SOURCES ${JIT_ARM64_SOURCES})
if(WIN32)
add_precompiled_header(jitpch.h ../jitpch.cpp SOURCES)
@@ -200,17 +212,33 @@ endif()
add_custom_target(jit_exports DEPENDS ${JIT_EXPORTS_FILE})
-add_subdirectory(dll)
-add_subdirectory(crossgen)
+if (FEATURE_MERGE_JIT_AND_ENGINE)
+ # Despite the directory being named "dll", it creates a static library "clrjit_static" to link into the VM.
+ add_subdirectory(dll)
+ add_subdirectory(crossgen)
+endif (FEATURE_MERGE_JIT_AND_ENGINE)
+
add_subdirectory(standalone)
if (CLR_CMAKE_PLATFORM_ARCH_ARM)
add_subdirectory(protojit)
endif (CLR_CMAKE_PLATFORM_ARCH_ARM)
+if (CLR_CMAKE_PLATFORM_ARCH_I386 OR CLR_CMAKE_PLATFORM_ARCH_AMD64)
+ # On x86, build RyuJIT/ARM32 cross-compiling altjit.
+ # On amd64, build RyuJIT/ARM64 cross-compiling altjit.
+ add_subdirectory(protononjit)
+endif ()
+
+if ((CLR_CMAKE_PLATFORM_ARCH_I386 OR CLR_CMAKE_PLATFORM_ARCH_AMD64) AND WIN32)
+ # On Windows, build altjit that targets the Linux ABI:
+ # On x86, build Linux/x86 altjit. This enables UNIX_X86_ABI.
+ # On amd64, build Linux/AMD64 altjit. This enables UNIX_AMD64_ABI and FEATURE_UNIX_AMD64_STRUCT_PASSING.
+ add_subdirectory(linuxnonjit)
+endif ()
+
if (CLR_CMAKE_PLATFORM_ARCH_I386 AND WIN32)
- add_subdirectory(legacyjit)
- if (NOT CLR_BUILD_JIT32)
- add_subdirectory(compatjit)
- endif ()
+ # On Windows x86, build altjit generating Windows/ARM32 code using LEGACY_BACKEND.
+ # (Note: we could also create linuxlegacynonjit for generating Linux/ARM32 code using LEGACY_BACKEND, if needed.)
+ add_subdirectory(legacynonjit)
endif (CLR_CMAKE_PLATFORM_ARCH_I386 AND WIN32)
diff --git a/src/jit/DIRS.proj b/src/jit/DIRS.proj
index eb00cc1d64..12ea52fb20 100644
--- a/src/jit/DIRS.proj
+++ b/src/jit/DIRS.proj
@@ -36,13 +36,9 @@
<ProjectFile Condition="'$(BuildArchitecture)' == 'arm'" Include="protojit\protojit.nativeproj" />
<ProjectFile Condition="'$(BuildArchitecture)' == 'amd64'" Include="protojit\protojit.nativeproj" />
- <ProjectFile Condition="'$(BuildArchitecture)' == 'amd64'" Include="ctp\ctpjit.nativeproj" />
<ProjectFile Condition="'$(BuildArchitecture)' == 'amd64'" Include="arm64altjit\arm64altjit.nativeproj" />
<ProjectFile Condition="'$(BuildArchitecture)' == 'i386'" Include="protojit\protojit.nativeproj" />
<ProjectFile Condition="'$(BuildArchitecture)' == 'i386'" Include="protononjit\protononjit.nativeproj" />
-
- <!-- We could build skipjit for all architectures, but we only need it for x86 currently -->
- <ProjectFile Condition="'$(BuildArchitecture)' == 'i386'" Include="skipjit\skipjit.nativeproj" />
</ItemGroup>
<!--Import the targets-->
diff --git a/src/jit/ICorJitInfo_API_wrapper.hpp b/src/jit/ICorJitInfo_API_wrapper.hpp
index 4272b2755c..a3ad21165b 100644
--- a/src/jit/ICorJitInfo_API_wrapper.hpp
+++ b/src/jit/ICorJitInfo_API_wrapper.hpp
@@ -129,8 +129,6 @@ void WrapICorJitInfo::getMethodVTableOffset(
API_LEAVE(getMethodVTableOffset);
}
-#if COR_JIT_EE_VERSION > 460
-
CorInfoIntrinsics WrapICorJitInfo::getIntrinsicID(
CORINFO_METHOD_HANDLE method,
bool* pMustExpand /* OUT */)
@@ -141,18 +139,6 @@ CorInfoIntrinsics WrapICorJitInfo::getIntrinsicID(
return temp;
}
-#else
-
-CorInfoIntrinsics WrapICorJitInfo::getIntrinsicID(CORINFO_METHOD_HANDLE method)
-{
- API_ENTER(getIntrinsicID);
- CorInfoIntrinsics temp = wrapHnd->getIntrinsicID(method);
- API_LEAVE(getIntrinsicID);
- return temp;
-}
-
-#endif
-
bool WrapICorJitInfo::isInSIMDModule(CORINFO_CLASS_HANDLE classHnd)
{
API_ENTER(isInSIMDModule);
@@ -281,8 +267,6 @@ void WrapICorJitInfo::resolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResol
API_LEAVE(resolveToken);
}
-#if COR_JIT_EE_VERSION > 460
-
bool WrapICorJitInfo::tryResolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pResolvedToken)
{
API_ENTER(tryResolveToken);
@@ -291,8 +275,6 @@ bool WrapICorJitInfo::tryResolveToken(/* IN, OUT */ CORINFO_RESOLVED_TOKEN * pRe
return success;
}
-#endif
-
void WrapICorJitInfo::findSig(
CORINFO_MODULE_HANDLE module,
unsigned sigTOK,
@@ -617,8 +599,6 @@ CorInfoHelpFunc WrapICorJitInfo::getUnBoxHelper(
return temp;
}
-#if COR_JIT_EE_VERSION > 460
-
bool WrapICorJitInfo::getReadyToRunHelper(
CORINFO_RESOLVED_TOKEN * pResolvedToken,
CORINFO_LOOKUP_KIND * pGenericLookupKind,
@@ -634,27 +614,13 @@ bool WrapICorJitInfo::getReadyToRunHelper(
void WrapICorJitInfo::getReadyToRunDelegateCtorHelper(
CORINFO_RESOLVED_TOKEN * pTargetMethod,
CORINFO_CLASS_HANDLE delegateType,
- CORINFO_CONST_LOOKUP * pLookup)
+ CORINFO_LOOKUP * pLookup)
{
API_ENTER(getReadyToRunDelegateCtorHelper);
wrapHnd->getReadyToRunDelegateCtorHelper(pTargetMethod, delegateType, pLookup);
API_LEAVE(getReadyToRunDelegateCtorHelper);
}
-#else
-
-void WrapICorJitInfo::getReadyToRunHelper(
- CORINFO_RESOLVED_TOKEN * pResolvedToken,
- CorInfoHelpFunc id,
- CORINFO_CONST_LOOKUP * pLookup)
-{
- API_ENTER(getReadyToRunHelper);
- wrapHnd->getReadyToRunHelper(pResolvedToken, id, pLookup);
- API_LEAVE(getReadyToRunHelper);
-}
-
-#endif
-
const char* WrapICorJitInfo::getHelperName(
CorInfoHelpFunc funcNum)
{
@@ -1094,8 +1060,6 @@ size_t WrapICorJitInfo::findNameOfToken(
return result;
}
-#if COR_JIT_EE_VERSION > 460
-
bool WrapICorJitInfo::getSystemVAmd64PassStructInRegisterDescriptor(
/* IN */ CORINFO_CLASS_HANDLE structHnd,
/* OUT */ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr)
@@ -1106,8 +1070,6 @@ bool WrapICorJitInfo::getSystemVAmd64PassStructInRegisterDescriptor(
return result;
}
-#endif
-
DWORD WrapICorJitInfo::getThreadTLSIndex(
void **ppIndirection)
{
@@ -1271,8 +1233,6 @@ void* WrapICorJitInfo::getAddressOfPInvokeFixup(
return temp;
}
-#if COR_JIT_EE_VERSION > 460
-
void WrapICorJitInfo::getAddressOfPInvokeTarget(
CORINFO_METHOD_HANDLE method,
CORINFO_CONST_LOOKUP *pLookup)
@@ -1282,8 +1242,6 @@ void WrapICorJitInfo::getAddressOfPInvokeTarget(
API_LEAVE(getAddressOfPInvokeTarget);
}
-#endif
-
LPVOID WrapICorJitInfo::GetCookieForPInvokeCalliSig(
CORINFO_SIG_INFO* szMetaSig,
void ** ppIndirection)
@@ -1474,8 +1432,6 @@ void* WrapICorJitInfo::getTailCallCopyArgsThunk(
//
/*********************************************************************************/
-#if COR_JIT_EE_VERSION > 460
-
DWORD WrapICorJitInfo::getJitFlags(CORJIT_FLAGS *jitFlags, DWORD sizeInBytes)
{
API_ENTER(getJitFlags);
@@ -1489,8 +1445,6 @@ bool WrapICorJitInfo::runWithErrorTrap(void(*function)(void*), void *param)
return wrapHnd->runWithErrorTrap(function, param);
}
-#endif
-
IEEMemoryManager* WrapICorJitInfo::getMemoryManager()
{
API_ENTER(getMemoryManager);
diff --git a/src/jit/_typeinfo.h b/src/jit/_typeinfo.h
index 08273adc8d..b024912dda 100755
--- a/src/jit/_typeinfo.h
+++ b/src/jit/_typeinfo.h
@@ -27,8 +27,7 @@ enum ti_types
#define DEF_TI(ti, nm) ti,
#include "titypes.h"
#undef DEF_TI
- TI_ONLY_ENUM = TI_METHOD, // Enum values above this are completely described by the enumeration
- TI_COUNT
+ TI_ONLY_ENUM = TI_METHOD, // Enum values with greater value are completely described by the enumeration.
};
#if defined(_TARGET_64BIT_)
@@ -190,8 +189,6 @@ inline ti_types JITtype2tiType(CorInfoType type)
*
*/
-// TI_COUNT is less than or equal to TI_FLAG_DATA_MASK
-
#define TI_FLAG_DATA_BITS 6
#define TI_FLAG_DATA_MASK ((1 << TI_FLAG_DATA_BITS) - 1)
@@ -225,6 +222,9 @@ inline ti_types JITtype2tiType(CorInfoType type)
// since conversions between them are not verifiable.
#define TI_FLAG_NATIVE_INT 0x00000200
+// This item contains resolved token. It is used for ctor delegate optimization.
+#define TI_FLAG_TOKEN 0x00000400
+
// This item contains the 'this' pointer (used for tracking)
#define TI_FLAG_THIS_PTR 0x00001000
@@ -287,12 +287,13 @@ private:
union {
struct
{
- ti_types type : 6;
+ ti_types type : TI_FLAG_DATA_BITS;
unsigned uninitobj : 1; // used
unsigned byref : 1; // used
unsigned byref_readonly : 1; // used
unsigned nativeInt : 1; // used
- unsigned : 2; // unused
+ unsigned token : 1; // used
+ unsigned : 1; // unused
unsigned thisPtr : 1; // used
unsigned thisPermHome : 1; // used
unsigned generic_type_var : 1; // used
@@ -303,8 +304,10 @@ private:
union {
CORINFO_CLASS_HANDLE m_cls;
- // Valid only for type TI_METHOD
+ // Valid only for type TI_METHOD without IsToken
CORINFO_METHOD_HANDLE m_method;
+ // Valid only for TI_TOKEN with IsToken
+ CORINFO_RESOLVED_TOKEN* m_token;
};
template <typename T>
@@ -368,6 +371,16 @@ public:
m_method = method;
}
+ typeInfo(CORINFO_RESOLVED_TOKEN* token)
+ {
+ assert(token != nullptr);
+ assert(token->hMethod != nullptr);
+ assert(!isInvalidHandle(token->hMethod));
+ m_flags = TI_METHOD;
+ SetIsToken();
+ m_token = token;
+ }
+
#ifdef DEBUG
#if VERBOSE_VERIFY
void Dump() const;
@@ -447,6 +460,12 @@ public:
// Operations
/////////////////////////////////////////////////////////////////////////
+ void SetIsToken()
+ {
+ m_flags |= TI_FLAG_TOKEN;
+ assert(m_bits.token);
+ }
+
void SetIsThisPtr()
{
m_flags |= TI_FLAG_THIS_PTR;
@@ -556,14 +575,17 @@ public:
CORINFO_METHOD_HANDLE GetMethod() const
{
assert(GetType() == TI_METHOD);
+ if (IsToken())
+ {
+ return m_token->hMethod;
+ }
return m_method;
}
- // If FEATURE_CORECLR is enabled, GetMethod can be called
- // before the pointer type is known to be a method pointer type.
- CORINFO_METHOD_HANDLE GetMethod2() const
+ CORINFO_RESOLVED_TOKEN* GetToken() const
{
- return m_method;
+ assert(IsToken());
+ return m_token;
}
// Get this item's type
@@ -626,7 +648,7 @@ public:
// Returns whether this is a method desc
BOOL IsMethod() const
{
- return (GetType() == TI_METHOD);
+ return GetType() == TI_METHOD;
}
BOOL IsStruct() const
@@ -730,6 +752,11 @@ public:
return (m_flags & TI_FLAG_UNINIT_OBJREF);
}
+ BOOL IsToken() const
+ {
+ return IsMethod() && ((m_flags & TI_FLAG_TOKEN) != 0);
+ }
+
private:
// used to make functions that return typeinfo efficient.
typeInfo(DWORD flags, CORINFO_CLASS_HANDLE cls)
diff --git a/src/jit/assertionprop.cpp b/src/jit/assertionprop.cpp
index cb0832fe47..767d63a0df 100644
--- a/src/jit/assertionprop.cpp
+++ b/src/jit/assertionprop.cpp
@@ -511,7 +511,7 @@ ASSERT_TP& Compiler::GetAssertionDep(unsigned lclNum)
ExpandArray<ASSERT_TP>& dep = *optAssertionDep;
if (dep[lclNum] == nullptr)
{
- dep[lclNum] = optNewEmptyAssertSet();
+ dep[lclNum] = BitVecOps::MakeEmpty(apTraits);
}
return dep[lclNum];
}
@@ -524,10 +524,7 @@ ASSERT_TP& Compiler::GetAssertionDep(unsigned lclNum)
void Compiler::optAssertionTraitsInit(AssertionIndex assertionCount)
{
apTraits = new (getAllocator()) BitVecTraits(assertionCount, this);
- apFull = BitVecOps::UninitVal();
- apEmpty = BitVecOps::UninitVal();
- BitVecOps::AssignNoCopy(apTraits, apFull, BitVecOps::MakeFull(apTraits));
- BitVecOps::AssignNoCopy(apTraits, apEmpty, BitVecOps::MakeEmpty(apTraits));
+ apFull = BitVecOps::MakeFull(apTraits);
}
/*****************************************************************************
@@ -792,12 +789,7 @@ void Compiler::optPrintAssertion(AssertionDsc* curAssertion, AssertionIndex asse
if (assertionIndex > 0)
{
printf(" index=#%02u, mask=", assertionIndex);
-
- // This is an hack to reuse a known empty set in order to display
- // a single bit mask.
- BitVecOps::AddElemD(apTraits, apEmpty, assertionIndex - 1);
- printf("%s", BitVecOps::ToString(apTraits, apEmpty));
- BitVecOps::RemoveElemD(apTraits, apEmpty, assertionIndex - 1);
+ printf("%s", BitVecOps::ToString(apTraits, BitVecOps::MakeSingleton(apTraits, assertionIndex - 1)));
}
printf("\n");
}
@@ -828,7 +820,7 @@ Compiler::AssertionDsc* Compiler::optGetAssertion(AssertionIndex assertIndex)
* if they don't care about it. Refer overloaded method optCreateAssertion.
*
*/
-Compiler::AssertionIndex Compiler::optCreateAssertion(GenTreePtr op1, GenTreePtr op2, optAssertionKind assertionKind)
+AssertionIndex Compiler::optCreateAssertion(GenTreePtr op1, GenTreePtr op2, optAssertionKind assertionKind)
{
AssertionDsc assertionDsc;
return optCreateAssertion(op1, op2, assertionKind, &assertionDsc);
@@ -850,10 +842,10 @@ Compiler::AssertionIndex Compiler::optCreateAssertion(GenTreePtr op1, GenTreePtr
* NO_ASSERTION_INDEX and we could not create the assertion.
*
*/
-Compiler::AssertionIndex Compiler::optCreateAssertion(GenTreePtr op1,
- GenTreePtr op2,
- optAssertionKind assertionKind,
- AssertionDsc* assertion)
+AssertionIndex Compiler::optCreateAssertion(GenTreePtr op1,
+ GenTreePtr op2,
+ optAssertionKind assertionKind,
+ AssertionDsc* assertion)
{
memset(assertion, 0, sizeof(AssertionDsc));
//
@@ -955,12 +947,14 @@ Compiler::AssertionIndex Compiler::optCreateAssertion(GenTreePtr op1,
while (vnStore->GetVNFunc(vn, &funcAttr) && (funcAttr.m_func == (VNFunc)GT_ADD) &&
(vnStore->TypeOfVN(vn) == TYP_BYREF))
{
- if (vnStore->IsVNConstant(funcAttr.m_args[1]))
+ if (vnStore->IsVNConstant(funcAttr.m_args[1]) &&
+ varTypeIsIntegral(vnStore->TypeOfVN(funcAttr.m_args[1])))
{
offset += vnStore->CoercedConstantValue<ssize_t>(funcAttr.m_args[1]);
vn = funcAttr.m_args[0];
}
- else if (vnStore->IsVNConstant(funcAttr.m_args[0]))
+ else if (vnStore->IsVNConstant(funcAttr.m_args[0]) &&
+ varTypeIsIntegral(vnStore->TypeOfVN(funcAttr.m_args[0])))
{
offset += vnStore->CoercedConstantValue<ssize_t>(funcAttr.m_args[0]);
vn = funcAttr.m_args[1];
@@ -1491,13 +1485,15 @@ void Compiler::optPrintVnAssertionMapping()
*/
void Compiler::optAddVnAssertionMapping(ValueNum vn, AssertionIndex index)
{
- ASSERT_TP cur;
- if (!optValueNumToAsserts->Lookup(vn, &cur))
+ ASSERT_TP* cur = optValueNumToAsserts->LookupPointer(vn);
+ if (cur == nullptr)
{
- cur = optNewEmptyAssertSet();
- optValueNumToAsserts->Set(vn, cur);
+ optValueNumToAsserts->Set(vn, BitVecOps::MakeSingleton(apTraits, index - 1));
+ }
+ else
+ {
+ BitVecOps::AddElemD(apTraits, *cur, index - 1);
}
- BitVecOps::AddElemD(apTraits, cur, index - 1);
}
/*****************************************************************************
@@ -1538,7 +1534,7 @@ bool Compiler::optAssertionVnInvolvesNan(AssertionDsc* assertion)
* we use to refer to this element.
* If we need to add to the table and the table is full return the value zero
*/
-Compiler::AssertionIndex Compiler::optAddAssertion(AssertionDsc* newAssertion)
+AssertionIndex Compiler::optAddAssertion(AssertionDsc* newAssertion)
{
noway_assert(newAssertion->assertionKind != OAK_INVALID);
@@ -1745,9 +1741,9 @@ void Compiler::optCreateComplementaryAssertion(AssertionIndex assertionIndex, Ge
* for the operands.
*/
-Compiler::AssertionIndex Compiler::optCreateJtrueAssertions(GenTreePtr op1,
- GenTreePtr op2,
- Compiler::optAssertionKind assertionKind)
+AssertionIndex Compiler::optCreateJtrueAssertions(GenTreePtr op1,
+ GenTreePtr op2,
+ Compiler::optAssertionKind assertionKind)
{
AssertionDsc candidateAssertion;
AssertionIndex assertionIndex = optCreateAssertion(op1, op2, assertionKind, &candidateAssertion);
@@ -1760,7 +1756,7 @@ Compiler::AssertionIndex Compiler::optCreateJtrueAssertions(GenTreePtr
return assertionIndex;
}
-Compiler::AssertionIndex Compiler::optCreateJTrueBoundsAssertion(GenTreePtr tree)
+AssertionInfo Compiler::optCreateJTrueBoundsAssertion(GenTreePtr tree)
{
GenTreePtr relop = tree->gtGetOp1();
if ((relop->OperKind() & GTK_RELOP) == 0)
@@ -1771,6 +1767,8 @@ Compiler::AssertionIndex Compiler::optCreateJTrueBoundsAssertion(GenTreePtr tree
GenTreePtr op2 = relop->gtGetOp2();
ValueNum vn = op1->gtVNPair.GetConservative();
+
+ ValueNumStore::ArrLenUnsignedBoundInfo arrLenUnsignedBnd;
// Cases where op1 holds the condition with array arithmetic and op2 is 0.
// Loop condition like: "i < a.len +/-k == 0"
// Assertion: "i < a.len +/- k == 0"
@@ -1826,6 +1824,32 @@ Compiler::AssertionIndex Compiler::optCreateJTrueBoundsAssertion(GenTreePtr tree
optCreateComplementaryAssertion(index, nullptr, nullptr);
return index;
}
+ // Loop condition like "(uint)i < (uint)a.len" or equivalent
+ // Assertion: "no throw" since this condition guarantees that i is both >= 0 and < a.len (on the appropiate edge)
+ else if (vnStore->IsVNArrLenUnsignedBound(relop->gtVNPair.GetConservative(), &arrLenUnsignedBnd))
+ {
+ assert(arrLenUnsignedBnd.vnIdx != ValueNumStore::NoVN);
+ assert((arrLenUnsignedBnd.cmpOper == VNF_LT_UN) || (arrLenUnsignedBnd.cmpOper == VNF_GE_UN));
+ assert(vnStore->IsVNArrLen(arrLenUnsignedBnd.vnLen));
+
+ AssertionDsc dsc;
+ dsc.assertionKind = OAK_NO_THROW;
+ dsc.op1.kind = O1K_ARR_BND;
+ dsc.op1.vn = relop->gtVNPair.GetConservative();
+ dsc.op1.bnd.vnIdx = arrLenUnsignedBnd.vnIdx;
+ dsc.op1.bnd.vnLen = arrLenUnsignedBnd.vnLen;
+ dsc.op2.kind = O2K_INVALID;
+ dsc.op2.vn = ValueNumStore::NoVN;
+
+ AssertionIndex index = optAddAssertion(&dsc);
+ if (arrLenUnsignedBnd.cmpOper == VNF_GE_UN)
+ {
+ // By default JTRUE generated assertions hold on the "jump" edge. We have i >= a.len but we're really
+ // after i < a.len so we need to change the assertion edge to "next".
+ return AssertionInfo::ForNextEdge(index);
+ }
+ return index;
+ }
// Cases where op1 holds the condition bound check and op2 is 0.
// Loop condition like: "i < 100 == 0"
// Assertion: "i < 100 == false"
@@ -1870,7 +1894,7 @@ Compiler::AssertionIndex Compiler::optCreateJTrueBoundsAssertion(GenTreePtr tree
*
* Compute assertions for the JTrue node.
*/
-Compiler::AssertionIndex Compiler::optAssertionGenJtrue(GenTreePtr tree)
+AssertionInfo Compiler::optAssertionGenJtrue(GenTreePtr tree)
{
// Only create assertions for JTRUE when we are in the global phase
if (optLocalAssertionProp)
@@ -1889,10 +1913,10 @@ Compiler::AssertionIndex Compiler::optAssertionGenJtrue(GenTreePtr tree)
GenTreePtr op1 = relop->gtOp.gtOp1;
GenTreePtr op2 = relop->gtOp.gtOp2;
- AssertionIndex index = optCreateJTrueBoundsAssertion(tree);
- if (index != NO_ASSERTION_INDEX)
+ AssertionInfo info = optCreateJTrueBoundsAssertion(tree);
+ if (info.HasAssertion())
{
- return index;
+ return info;
}
// Find assertion kind.
@@ -1974,7 +1998,7 @@ Compiler::AssertionIndex Compiler::optAssertionGenJtrue(GenTreePtr tree)
* from all of the constituent phi operands.
*
*/
-Compiler::AssertionIndex Compiler::optAssertionGenPhiDefn(GenTreePtr tree)
+AssertionIndex Compiler::optAssertionGenPhiDefn(GenTreePtr tree)
{
if (!tree->IsPhiDefn())
{
@@ -2023,19 +2047,19 @@ void Compiler::optAssertionGen(GenTreePtr tree)
// For most of the assertions that we create below
// the assertion is true after the tree is processed
- bool assertionProven = true;
- AssertionIndex assertionIndex = NO_ASSERTION_INDEX;
+ bool assertionProven = true;
+ AssertionInfo assertionInfo;
switch (tree->gtOper)
{
case GT_ASG:
// VN takes care of non local assertions for assignments and data flow.
if (optLocalAssertionProp)
{
- assertionIndex = optCreateAssertion(tree->gtOp.gtOp1, tree->gtOp.gtOp2, OAK_EQUAL);
+ assertionInfo = optCreateAssertion(tree->gtOp.gtOp1, tree->gtOp.gtOp2, OAK_EQUAL);
}
else
{
- assertionIndex = optAssertionGenPhiDefn(tree);
+ assertionInfo = optAssertionGenPhiDefn(tree);
}
break;
@@ -2045,24 +2069,24 @@ void Compiler::optAssertionGen(GenTreePtr tree)
case GT_IND:
case GT_NULLCHECK:
// All indirections create non-null assertions
- assertionIndex = optCreateAssertion(tree->AsIndir()->Addr(), nullptr, OAK_NOT_EQUAL);
+ assertionInfo = optCreateAssertion(tree->AsIndir()->Addr(), nullptr, OAK_NOT_EQUAL);
break;
case GT_ARR_LENGTH:
// An array length is an indirection (but doesn't derive from GenTreeIndir).
- assertionIndex = optCreateAssertion(tree->AsArrLen()->ArrRef(), nullptr, OAK_NOT_EQUAL);
+ assertionInfo = optCreateAssertion(tree->AsArrLen()->ArrRef(), nullptr, OAK_NOT_EQUAL);
break;
case GT_ARR_BOUNDS_CHECK:
if (!optLocalAssertionProp)
{
- assertionIndex = optCreateAssertion(tree, nullptr, OAK_NO_THROW);
+ assertionInfo = optCreateAssertion(tree, nullptr, OAK_NO_THROW);
}
break;
case GT_ARR_ELEM:
// An array element reference can create a non-null assertion
- assertionIndex = optCreateAssertion(tree->gtArrElem.gtArrObj, nullptr, OAK_NOT_EQUAL);
+ assertionInfo = optCreateAssertion(tree->gtArrElem.gtArrObj, nullptr, OAK_NOT_EQUAL);
break;
case GT_CALL:
@@ -2071,7 +2095,7 @@ void Compiler::optAssertionGen(GenTreePtr tree)
if ((tree->gtFlags & GTF_CALL_NULLCHECK) || ((tree->gtFlags & GTF_CALL_VIRT_KIND_MASK) != GTF_CALL_NONVIRT))
{
// Retrieve the 'this' arg
- GenTreePtr thisArg = gtGetThisArg(tree);
+ GenTreePtr thisArg = gtGetThisArg(tree->AsCall());
#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) || defined(_TARGET_ARM_)
if (thisArg == nullptr)
{
@@ -2082,7 +2106,7 @@ void Compiler::optAssertionGen(GenTreePtr tree)
}
#endif // _TARGET_X86_ || _TARGET_AMD64_ || _TARGET_ARM_
noway_assert(thisArg != nullptr);
- assertionIndex = optCreateAssertion(thisArg, nullptr, OAK_NOT_EQUAL);
+ assertionInfo = optCreateAssertion(thisArg, nullptr, OAK_NOT_EQUAL);
}
break;
@@ -2093,13 +2117,13 @@ void Compiler::optAssertionGen(GenTreePtr tree)
// This represets an assertion that we would like to prove to be true. It is not actually a true
// assertion.
// If we can prove this assertion true then we can eliminate this cast.
- assertionIndex = optCreateAssertion(tree->gtOp.gtOp1, tree, OAK_SUBRANGE);
+ assertionInfo = optCreateAssertion(tree->gtOp.gtOp1, tree, OAK_SUBRANGE);
assertionProven = false;
}
break;
case GT_JTRUE:
- assertionIndex = optAssertionGenJtrue(tree);
+ assertionInfo = optAssertionGenJtrue(tree);
break;
default:
@@ -2108,9 +2132,9 @@ void Compiler::optAssertionGen(GenTreePtr tree)
}
// For global assertion prop we must store the assertion number in the tree node
- if ((assertionIndex != NO_ASSERTION_INDEX) && assertionProven && !optLocalAssertionProp)
+ if (assertionInfo.HasAssertion() && assertionProven && !optLocalAssertionProp)
{
- tree->SetAssertion(assertionIndex);
+ tree->SetAssertionInfo(assertionInfo);
}
}
@@ -2134,7 +2158,7 @@ void Compiler::optMapComplementary(AssertionIndex assertionIndex, AssertionIndex
* Given an assertion index, return the assertion index of the complementary
* assertion or 0 if one does not exist.
*/
-Compiler::AssertionIndex Compiler::optFindComplementary(AssertionIndex assertIndex)
+AssertionIndex Compiler::optFindComplementary(AssertionIndex assertIndex)
{
if (assertIndex == NO_ASSERTION_INDEX)
{
@@ -2177,9 +2201,7 @@ Compiler::AssertionIndex Compiler::optFindComplementary(AssertionIndex assertInd
* if one such assertion could not be found in "assertions."
*/
-Compiler::AssertionIndex Compiler::optAssertionIsSubrange(GenTreePtr tree,
- var_types toType,
- ASSERT_VALARG_TP assertions)
+AssertionIndex Compiler::optAssertionIsSubrange(GenTreePtr tree, var_types toType, ASSERT_VALARG_TP assertions)
{
if (!optLocalAssertionProp && BitVecOps::IsEmpty(apTraits, assertions))
{
@@ -2245,9 +2267,7 @@ Compiler::AssertionIndex Compiler::optAssertionIsSubrange(GenTreePtr tree,
* could not be found, then it returns NO_ASSERTION_INDEX.
*
*/
-Compiler::AssertionIndex Compiler::optAssertionIsSubtype(GenTreePtr tree,
- GenTreePtr methodTableArg,
- ASSERT_VALARG_TP assertions)
+AssertionIndex Compiler::optAssertionIsSubtype(GenTreePtr tree, GenTreePtr methodTableArg, ASSERT_VALARG_TP assertions)
{
if (!optLocalAssertionProp && BitVecOps::IsEmpty(apTraits, assertions))
{
@@ -2418,11 +2438,9 @@ GenTreePtr Compiler::optVNConstantPropOnTree(BasicBlock* block, GenTreePtr stmt,
#ifdef _TARGET_64BIT_
if (vnStore->IsVNHandle(vnCns))
{
-#ifdef RELOC_SUPPORT
// Don't perform constant folding that involves a handle that needs
// to be recorded as a relocation with the VM.
if (!opts.compReloc)
-#endif
{
newTree = gtNewIconHandleNode(value, vnStore->GetHandleFlags(vnCns));
newTree->gtVNPair = ValueNumPair(vnLib, vnCns);
@@ -2491,11 +2509,9 @@ GenTreePtr Compiler::optVNConstantPropOnTree(BasicBlock* block, GenTreePtr stmt,
#ifndef _TARGET_64BIT_
if (vnStore->IsVNHandle(vnCns))
{
-#ifdef RELOC_SUPPORT
// Don't perform constant folding that involves a handle that needs
// to be recorded as a relocation with the VM.
if (!opts.compReloc)
-#endif
{
newTree = gtNewIconHandleNode(value, vnStore->GetHandleFlags(vnCns));
newTree->gtVNPair = ValueNumPair(vnLib, vnCns);
@@ -2905,7 +2921,7 @@ GenTreePtr Compiler::optAssertionProp_LclVar(ASSERT_VALARG_TP assertions, const
* op1Kind and lclNum, op2Kind and the constant value and is either equal or
* not equal assertion.
*/
-Compiler::AssertionIndex Compiler::optLocalAssertionIsEqualOrNotEqual(
+AssertionIndex Compiler::optLocalAssertionIsEqualOrNotEqual(
optOp1Kind op1Kind, unsigned lclNum, optOp2Kind op2Kind, ssize_t cnsVal, ASSERT_VALARG_TP assertions)
{
noway_assert((op1Kind == O1K_LCLVAR) || (op1Kind == O1K_EXACT_TYPE) || (op1Kind == O1K_SUBTYPE));
@@ -2947,9 +2963,9 @@ Compiler::AssertionIndex Compiler::optLocalAssertionIsEqualOrNotEqual(
* "op1" == "op2" or "op1" != "op2." Does a value number based comparison.
*
*/
-Compiler::AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqual(ASSERT_VALARG_TP assertions,
- GenTreePtr op1,
- GenTreePtr op2)
+AssertionIndex Compiler::optGlobalAssertionIsEqualOrNotEqual(ASSERT_VALARG_TP assertions,
+ GenTreePtr op1,
+ GenTreePtr op2)
{
if (BitVecOps::IsEmpty(apTraits, assertions))
{
@@ -3503,7 +3519,7 @@ bool Compiler::optAssertionIsNonNull(GenTreePtr op,
* from the set of "assertions."
*
*/
-Compiler::AssertionIndex Compiler::optAssertionIsNonNullInternal(GenTreePtr op, ASSERT_VALARG_TP assertions)
+AssertionIndex Compiler::optAssertionIsNonNullInternal(GenTreePtr op, ASSERT_VALARG_TP assertions)
{
// If local assertion prop use lcl comparison, else use VN comparison.
if (!optLocalAssertionProp)
@@ -3562,16 +3578,13 @@ Compiler::AssertionIndex Compiler::optAssertionIsNonNullInternal(GenTreePtr op,
* Returns the modified tree, or nullptr if no assertion prop took place.
*
*/
-GenTreePtr Compiler::optNonNullAssertionProp_Call(ASSERT_VALARG_TP assertions,
- const GenTreePtr tree,
- const GenTreePtr stmt)
+GenTreePtr Compiler::optNonNullAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call, const GenTreePtr stmt)
{
- assert(tree->gtOper == GT_CALL);
- if ((tree->gtFlags & GTF_CALL_NULLCHECK) == 0)
+ if ((call->gtFlags & GTF_CALL_NULLCHECK) == 0)
{
return nullptr;
}
- GenTreePtr op1 = gtGetThisArg(tree);
+ GenTreePtr op1 = gtGetThisArg(call);
noway_assert(op1 != nullptr);
if (op1->gtOper != GT_LCL_VAR)
{
@@ -3589,13 +3602,13 @@ GenTreePtr Compiler::optNonNullAssertionProp_Call(ASSERT_VALARG_TP assertions,
{
(vnBased) ? printf("\nVN based non-null prop in BB%02u:\n", compCurBB->bbNum)
: printf("\nNon-null prop for index #%02u in BB%02u:\n", index, compCurBB->bbNum);
- gtDispTree(tree, nullptr, nullptr, true);
+ gtDispTree(call, nullptr, nullptr, true);
}
#endif
- tree->gtFlags &= ~GTF_CALL_NULLCHECK;
- tree->gtFlags &= ~GTF_EXCEPT;
- noway_assert(tree->gtFlags & GTF_SIDE_EFFECT);
- return tree;
+ call->gtFlags &= ~GTF_CALL_NULLCHECK;
+ call->gtFlags &= ~GTF_EXCEPT;
+ noway_assert(call->gtFlags & GTF_SIDE_EFFECT);
+ return call;
}
return nullptr;
}
@@ -3612,33 +3625,31 @@ GenTreePtr Compiler::optNonNullAssertionProp_Call(ASSERT_VALARG_TP assertions,
*
*/
-GenTreePtr Compiler::optAssertionProp_Call(ASSERT_VALARG_TP assertions, const GenTreePtr tree, const GenTreePtr stmt)
+GenTreePtr Compiler::optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call, const GenTreePtr stmt)
{
- assert(tree->gtOper == GT_CALL);
-
- if (optNonNullAssertionProp_Call(assertions, tree, stmt))
+ if (optNonNullAssertionProp_Call(assertions, call, stmt))
{
- return optAssertionProp_Update(tree, tree, stmt);
+ return optAssertionProp_Update(call, call, stmt);
}
- else if (!optLocalAssertionProp && (tree->gtCall.gtCallType == CT_HELPER))
+ else if (!optLocalAssertionProp && (call->gtCallType == CT_HELPER))
{
- if (tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFINTERFACE) ||
- tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFARRAY) ||
- tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFCLASS) ||
- tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFANY) ||
- tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTINTERFACE) ||
- tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTARRAY) ||
- tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTCLASS) ||
- tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTANY) ||
- tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTCLASS_SPECIAL))
+ if (call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFINTERFACE) ||
+ call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFARRAY) ||
+ call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFCLASS) ||
+ call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_ISINSTANCEOFANY) ||
+ call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTINTERFACE) ||
+ call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTARRAY) ||
+ call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTCLASS) ||
+ call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTANY) ||
+ call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_CHKCASTCLASS_SPECIAL))
{
- GenTreePtr arg1 = gtArgEntryByArgNum(tree->AsCall(), 1)->node;
+ GenTreePtr arg1 = gtArgEntryByArgNum(call, 1)->node;
if (arg1->gtOper != GT_LCL_VAR)
{
return nullptr;
}
- GenTreePtr arg2 = gtArgEntryByArgNum(tree->AsCall(), 0)->node;
+ GenTreePtr arg2 = gtArgEntryByArgNum(call, 0)->node;
unsigned index = optAssertionIsSubtype(arg1, arg2, assertions);
if (index != NO_ASSERTION_INDEX)
@@ -3647,18 +3658,18 @@ GenTreePtr Compiler::optAssertionProp_Call(ASSERT_VALARG_TP assertions, const Ge
if (verbose)
{
printf("\nDid VN based subtype prop for index #%02u in BB%02u:\n", index, compCurBB->bbNum);
- gtDispTree(tree, nullptr, nullptr, true);
+ gtDispTree(call, nullptr, nullptr, true);
}
#endif
GenTreePtr list = nullptr;
- gtExtractSideEffList(tree, &list, GTF_SIDE_EFFECT, true);
+ gtExtractSideEffList(call, &list, GTF_SIDE_EFFECT, true);
if (list != nullptr)
{
- arg1 = gtNewOperNode(GT_COMMA, tree->TypeGet(), list, arg1);
+ arg1 = gtNewOperNode(GT_COMMA, call->TypeGet(), list, arg1);
fgSetTreeSeq(arg1);
}
- return optAssertionProp_Update(arg1, tree, stmt);
+ return optAssertionProp_Update(arg1, call, stmt);
}
}
}
@@ -3889,7 +3900,7 @@ GenTreePtr Compiler::optAssertionProp(ASSERT_VALARG_TP assertions, const GenTree
return optAssertionProp_Cast(assertions, tree, stmt);
case GT_CALL:
- return optAssertionProp_Call(assertions, tree, stmt);
+ return optAssertionProp_Call(assertions, tree->AsCall(), stmt);
case GT_EQ:
case GT_NE:
@@ -4378,15 +4389,8 @@ public:
JITDUMP("AssertionPropCallback::EndMerge : BB%02d in -> %s\n\n", block->bbNum,
BitVecOps::ToString(apTraits, block->bbAssertionIn));
- // PERF: eliminate this tmp by passing in a OperationTree (AST) to the bitset,
- // so the expr tree is operated on a single bit level. See "expression templates."
- ASSERT_TP tmp = BitVecOps::MakeCopy(apTraits, block->bbAssertionIn);
- BitVecOps::UnionD(apTraits, tmp, block->bbAssertionGen);
- BitVecOps::IntersectionD(apTraits, block->bbAssertionOut, tmp);
-
- BitVecOps::Assign(apTraits, tmp, block->bbAssertionIn);
- BitVecOps::UnionD(apTraits, tmp, mJumpDestGen[block->bbNum]);
- BitVecOps::IntersectionD(apTraits, mJumpDestOut[block->bbNum], tmp);
+ BitVecOps::DataFlowD(apTraits, block->bbAssertionOut, block->bbAssertionGen, block->bbAssertionIn);
+ BitVecOps::DataFlowD(apTraits, mJumpDestOut[block->bbNum], mJumpDestGen[block->bbNum], block->bbAssertionIn);
bool changed = (!BitVecOps::Equal(apTraits, preMergeOut, block->bbAssertionOut) ||
!BitVecOps::Equal(apTraits, preMergeJumpDestOut, mJumpDestOut[block->bbNum]));
@@ -4411,16 +4415,6 @@ public:
}
};
-ASSERT_VALRET_TP Compiler::optNewFullAssertSet()
-{
- return BitVecOps::MakeCopy(apTraits, apFull);
-}
-
-ASSERT_VALRET_TP Compiler::optNewEmptyAssertSet()
-{
- return BitVecOps::MakeCopy(apTraits, apEmpty);
-}
-
/*****************************************************************************
*
* Compute the assertions generated by each block.
@@ -4429,15 +4423,10 @@ ASSERT_TP* Compiler::optComputeAssertionGen()
{
ASSERT_TP* jumpDestGen = fgAllocateTypeForEachBlk<ASSERT_TP>();
- ASSERT_TP valueGen = BitVecOps::MakeEmpty(apTraits);
- ASSERT_TP jumpDestValueGen = BitVecOps::MakeEmpty(apTraits);
-
for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
{
- jumpDestGen[block->bbNum] = BitVecOps::MakeEmpty(apTraits);
-
- BitVecOps::ClearD(apTraits, valueGen);
- BitVecOps::ClearD(apTraits, jumpDestValueGen);
+ ASSERT_TP valueGen = BitVecOps::MakeEmpty(apTraits);
+ GenTree* jtrue = nullptr;
// Walk the statement trees in this basic block.
for (GenTreePtr stmt = block->bbTreeList; stmt; stmt = stmt->gtNext)
@@ -4446,47 +4435,77 @@ ASSERT_TP* Compiler::optComputeAssertionGen()
for (GenTreePtr tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
{
- // Store whatever we have accumulated into jumpDest edge's valueGen.
if (tree->gtOper == GT_JTRUE)
{
- BitVecOps::Assign(apTraits, jumpDestValueGen, valueGen);
+ // A GT_TRUE is always the last node in a tree, so we can break here
+ assert((tree->gtNext == nullptr) && (stmt->gtNext == nullptr));
+ jtrue = tree;
+ break;
}
- if (!tree->HasAssertion())
+
+ if (tree->GeneratesAssertion())
{
- continue;
+ AssertionInfo info = tree->GetAssertionInfo();
+ optImpliedAssertions(info.GetAssertionIndex(), valueGen);
+ BitVecOps::AddElemD(apTraits, valueGen, info.GetAssertionIndex() - 1);
}
+ }
+ }
+
+ if (jtrue != nullptr)
+ {
+ // Copy whatever we have accumulated into jumpDest edge's valueGen.
+ ASSERT_TP jumpDestValueGen = BitVecOps::MakeCopy(apTraits, valueGen);
+
+ if (jtrue->GeneratesAssertion())
+ {
+ AssertionInfo info = jtrue->GetAssertionInfo();
+ AssertionIndex valueAssertionIndex;
+ AssertionIndex jumpDestAssertionIndex;
- // For regular trees, just update valueGen. For GT_JTRUE, for false part,
- // update valueGen and true part update jumpDestValueGen.
- AssertionIndex assertionIndex[2] = {(AssertionIndex)tree->GetAssertion(),
- (tree->OperGet() == GT_JTRUE)
- ? optFindComplementary((AssertionIndex)tree->GetAssertion())
- : 0};
+ if (info.IsNextEdgeAssertion())
+ {
+ valueAssertionIndex = info.GetAssertionIndex();
+ jumpDestAssertionIndex = optFindComplementary(info.GetAssertionIndex());
+ }
+ else // is jump edge assertion
+ {
+ valueAssertionIndex = optFindComplementary(info.GetAssertionIndex());
+ jumpDestAssertionIndex = info.GetAssertionIndex();
+ }
- for (unsigned i = 0; i < 2; ++i)
+ if (valueAssertionIndex != NO_ASSERTION_INDEX)
{
- if (assertionIndex[i] > 0)
- {
- // If GT_JTRUE, and true part use jumpDestValueGen.
- ASSERT_TP& gen = (i == 0 && tree->OperGet() == GT_JTRUE) ? jumpDestValueGen : valueGen;
- optImpliedAssertions(assertionIndex[i], gen);
- BitVecOps::AddElemD(apTraits, gen, assertionIndex[i] - 1);
- }
+ // Update valueGen if we have an assertion for the bbNext edge
+ optImpliedAssertions(valueAssertionIndex, valueGen);
+ BitVecOps::AddElemD(apTraits, valueGen, valueAssertionIndex - 1);
+ }
+
+ if (jumpDestAssertionIndex != NO_ASSERTION_INDEX)
+ {
+ // Update jumpDestValueGen if we have an assertion for the bbJumpDest edge
+ optImpliedAssertions(jumpDestAssertionIndex, jumpDestValueGen);
+ BitVecOps::AddElemD(apTraits, jumpDestValueGen, jumpDestAssertionIndex - 1);
}
}
+
+ jumpDestGen[block->bbNum] = jumpDestValueGen;
+ }
+ else
+ {
+ jumpDestGen[block->bbNum] = BitVecOps::MakeEmpty(apTraits);
}
- BitVecOps::Assign(apTraits, block->bbAssertionGen, valueGen);
- BitVecOps::Assign(apTraits, jumpDestGen[block->bbNum], jumpDestValueGen);
+ block->bbAssertionGen = valueGen;
#ifdef DEBUG
if (verbose)
{
- printf("\nBB%02u valueGen = %s", block->bbNum, BitVecOps::ToString(apTraits, valueGen));
+ printf("\nBB%02u valueGen = %s", block->bbNum, BitVecOps::ToString(apTraits, block->bbAssertionGen));
if (block->bbJumpKind == BBJ_COND)
{
printf(" => BB%02u valueGen = %s,", block->bbJumpDest->bbNum,
- BitVecOps::ToString(apTraits, jumpDestValueGen));
+ BitVecOps::ToString(apTraits, jumpDestGen[block->bbNum]));
}
}
#endif
@@ -4509,7 +4528,7 @@ ASSERT_TP* Compiler::optInitAssertionDataflowFlags()
// apFull (i.e. all possible bits set), we need to set the bits only for valid
// assertions (note that at this point we are not creating any new assertions).
// Also note that assertion indices start from 1.
- ASSERT_TP apValidFull = optNewEmptyAssertSet();
+ ASSERT_TP apValidFull = BitVecOps::MakeEmpty(apTraits);
for (int i = 1; i <= optAssertionCount; i++)
{
BitVecOps::AddElemD(apTraits, apValidFull, i - 1);
@@ -4523,20 +4542,21 @@ ASSERT_TP* Compiler::optInitAssertionDataflowFlags()
// edges.
for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
{
- block->bbAssertionIn = optNewEmptyAssertSet();
- if (!bbIsHandlerBeg(block))
+ if (bbIsHandlerBeg(block))
+ {
+ block->bbAssertionIn = BitVecOps::MakeEmpty(apTraits);
+ }
+ else
{
- BitVecOps::Assign(apTraits, block->bbAssertionIn, apValidFull);
+ block->bbAssertionIn = BitVecOps::MakeCopy(apTraits, apValidFull);
}
- block->bbAssertionGen = optNewEmptyAssertSet();
- block->bbAssertionOut = optNewEmptyAssertSet();
- BitVecOps::Assign(apTraits, block->bbAssertionOut, apValidFull);
- jumpDestOut[block->bbNum] = optNewEmptyAssertSet();
- BitVecOps::Assign(apTraits, jumpDestOut[block->bbNum], apValidFull);
+ block->bbAssertionGen = BitVecOps::MakeEmpty(apTraits);
+ block->bbAssertionOut = BitVecOps::MakeCopy(apTraits, apValidFull);
+ jumpDestOut[block->bbNum] = BitVecOps::MakeCopy(apTraits, apValidFull);
}
// Compute the data flow values for all tracked expressions
// IN and OUT never change for the initial basic block B1
- BitVecOps::Assign(apTraits, fgFirstBB->bbAssertionIn, apEmpty);
+ BitVecOps::ClearD(apTraits, fgFirstBB->bbAssertionIn);
return jumpDestOut;
}
@@ -4839,7 +4859,7 @@ void Compiler::optVnNonNullPropCurStmt(BasicBlock* block, GenTreePtr stmt, GenTr
GenTreePtr newTree = nullptr;
if (tree->OperGet() == GT_CALL)
{
- newTree = optNonNullAssertionProp_Call(empty, tree, stmt);
+ newTree = optNonNullAssertionProp_Call(empty, tree->AsCall(), stmt);
}
else if (tree->OperIsIndir())
{
@@ -5032,10 +5052,12 @@ void Compiler::optAssertionPropMain()
}
#endif // DEBUG
+ ASSERT_TP assertions = BitVecOps::MakeEmpty(apTraits);
+
// Perform assertion propagation (and constant folding)
for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
{
- ASSERT_TP assertions = BitVecOps::MakeCopy(apTraits, block->bbAssertionIn);
+ BitVecOps::Assign(apTraits, assertions, block->bbAssertionIn);
// TODO-Review: EH successor/predecessor iteration seems broken.
// SELF_HOST_TESTS_ARM\jit\Directed\ExcepFilters\fault\fault.exe
@@ -5070,9 +5092,16 @@ void Compiler::optAssertionPropMain()
// and thus we must morph, set order, re-link
for (GenTreePtr tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
{
+ if (tree->OperIs(GT_JTRUE))
+ {
+ // A GT_TRUE is always the last node in a tree, so we can break here
+ assert((tree->gtNext == nullptr) && (stmt->gtNext == nullptr));
+ break;
+ }
+
JITDUMP("Propagating %s assertions for BB%02d, stmt [%06d], tree [%06d], tree -> %d\n",
BitVecOps::ToString(apTraits, assertions), block->bbNum, dspTreeID(stmt), dspTreeID(tree),
- tree->GetAssertion());
+ tree->GetAssertionInfo().GetAssertionIndex());
GenTreePtr newTree = optAssertionProp(assertions, tree, stmt);
if (newTree)
@@ -5081,16 +5110,12 @@ void Compiler::optAssertionPropMain()
tree = newTree;
}
- // Is this an assignment to a local variable
- GenTreeLclVarCommon* lclVarTree = nullptr;
-
// If this tree makes an assertion - make it available.
- if (tree->HasAssertion())
+ if (tree->GeneratesAssertion())
{
- BitVecOps::AddElemD(apTraits, assertions, tree->GetAssertion() - 1);
-
- // Also include any implied assertions for the tree node.
- optImpliedAssertions((AssertionIndex)tree->GetAssertion(), assertions);
+ AssertionInfo info = tree->GetAssertionInfo();
+ optImpliedAssertions(info.GetAssertionIndex(), assertions);
+ BitVecOps::AddElemD(apTraits, assertions, info.GetAssertionIndex() - 1);
}
}
diff --git a/src/jit/bitset.cpp b/src/jit/bitset.cpp
index 90ef253199..785061f44c 100644
--- a/src/jit/bitset.cpp
+++ b/src/jit/bitset.cpp
@@ -98,9 +98,9 @@ void BitSetSupport::RunTests(Env env)
class TestBitSetTraits
{
public:
- static IAllocator* GetAllocator(IAllocator* alloc)
+ static void* Alloc(IAllocator* alloc, size_t byteSize)
{
- return alloc;
+ return alloc->Alloc(byteSize);
}
static unsigned GetSize(IAllocator* alloc)
{
diff --git a/src/jit/bitsetasshortlong.h b/src/jit/bitsetasshortlong.h
index ec437e189c..163cb366cb 100644
--- a/src/jit/bitsetasshortlong.h
+++ b/src/jit/bitsetasshortlong.h
@@ -38,6 +38,7 @@ private:
static BitSetShortLongRep MakeCopyLong(Env env, BitSetShortLongRep bs);
static bool IsEmptyLong(Env env, BitSetShortLongRep bs);
static unsigned CountLong(Env env, BitSetShortLongRep bs);
+ static bool IsEmptyUnionLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2);
static void UnionDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2);
static void DiffDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2);
static void AddElemDLong(Env env, BitSetShortLongRep& bs, unsigned i);
@@ -51,6 +52,15 @@ private:
static bool IsSubsetLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2);
static bool IsEmptyIntersectionLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2);
static void IntersectionDLong(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2);
+ static void DataFlowDLong(Env env,
+ BitSetShortLongRep& out,
+ const BitSetShortLongRep gen,
+ const BitSetShortLongRep in);
+ static void LivenessDLong(Env env,
+ BitSetShortLongRep& in,
+ const BitSetShortLongRep def,
+ const BitSetShortLongRep use,
+ const BitSetShortLongRep out);
#ifdef DEBUG
static const char* ToStringLong(Env env, BitSetShortLongRep bs);
#endif
@@ -176,6 +186,18 @@ public:
}
}
+ static bool IsEmptyUnion(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
+ {
+ if (IsShort(env))
+ {
+ return (((size_t)bs1) | ((size_t)bs2)) == 0;
+ }
+ else
+ {
+ return IsEmptyUnionLong(env, bs1, bs2);
+ }
+ }
+
static void UnionD(Env env, BitSetShortLongRep& bs1, BitSetShortLongRep bs2)
{
if (IsShort(env))
@@ -299,6 +321,34 @@ public:
}
}
+ static void DataFlowD(Env env, BitSetShortLongRep& out, const BitSetShortLongRep gen, const BitSetShortLongRep in)
+ {
+ if (IsShort(env))
+ {
+ (size_t&)out = (size_t)out & ((size_t)gen | (size_t)in);
+ }
+ else
+ {
+ DataFlowDLong(env, out, gen, in);
+ }
+ }
+
+ static void LivenessD(Env env,
+ BitSetShortLongRep& in,
+ const BitSetShortLongRep def,
+ const BitSetShortLongRep use,
+ const BitSetShortLongRep out)
+ {
+ if (IsShort(env))
+ {
+ (size_t&)in = (size_t)use | ((size_t)out & ~(size_t)def);
+ }
+ else
+ {
+ LivenessDLong(env, in, def, use, out);
+ }
+ }
+
static bool IsSubset(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
{
if (IsShort(env))
@@ -332,14 +382,13 @@ public:
if (IsShort(env))
{
assert(sizeof(BitSetShortLongRep) == sizeof(size_t));
- IAllocator* alloc = BitSetTraits::GetDebugOnlyAllocator(env);
- const int CharsForSizeT = sizeof(size_t) * 2;
- char* res = nullptr;
- const int ShortAllocSize = CharsForSizeT + 4;
- res = (char*)alloc->Alloc(ShortAllocSize);
- size_t bits = (size_t)bs;
- unsigned remaining = ShortAllocSize;
- char* ptr = res;
+ const int CharsForSizeT = sizeof(size_t) * 2;
+ char* res = nullptr;
+ const int ShortAllocSize = CharsForSizeT + 4;
+ res = (char*)BitSetTraits::DebugAlloc(env, ShortAllocSize);
+ size_t bits = (size_t)bs;
+ unsigned remaining = ShortAllocSize;
+ char* ptr = res;
if (sizeof(size_t) == sizeof(int64_t))
{
sprintf_s(ptr, remaining, "%016llX", bits);
@@ -629,7 +678,7 @@ BitSetShortLongRep BitSetOps</*BitSetType*/ BitSetShortLongRep,
assert(!IsShort(env));
unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
assert(len > 1); // Or else would not require an array.
- return (BitSetShortLongRep)(BitSetTraits::GetAllocator(env)->Alloc(len * sizeof(size_t)));
+ return (BitSetShortLongRep)(BitSetTraits::Alloc(env, len * sizeof(size_t)));
}
template <typename Env, typename BitSetTraits>
@@ -641,7 +690,7 @@ BitSetShortLongRep BitSetOps</*BitSetType*/ BitSetShortLongRep,
assert(!IsShort(env));
unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
assert(len > 1); // Or else would not require an array.
- BitSetShortLongRep res = (BitSetShortLongRep)(BitSetTraits::GetAllocator(env)->Alloc(len * sizeof(size_t)));
+ BitSetShortLongRep res = (BitSetShortLongRep)(BitSetTraits::Alloc(env, len * sizeof(size_t)));
for (unsigned i = 0; i < len; i++)
{
res[i] = 0;
@@ -658,7 +707,7 @@ BitSetShortLongRep BitSetOps</*BitSetType*/ BitSetShortLongRep,
assert(!IsShort(env));
unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
assert(len > 1); // Or else would not require an array.
- BitSetShortLongRep res = (BitSetShortLongRep)(BitSetTraits::GetAllocator(env)->Alloc(len * sizeof(size_t)));
+ BitSetShortLongRep res = (BitSetShortLongRep)(BitSetTraits::Alloc(env, len * sizeof(size_t)));
for (unsigned i = 0; i < len - 1; i++)
{
res[i] = size_t(-1);
@@ -722,6 +771,59 @@ template <typename Env, typename BitSetTraits>
bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
/*Brand*/ BSShortLong,
/*Env*/ Env,
+ /*BitSetTraits*/ BitSetTraits>::IsEmptyUnionLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
+{
+ assert(!IsShort(env));
+ unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
+ for (unsigned i = 0; i < len; i++)
+ {
+ if ((bs1[i] | bs2[i]) != 0)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+template <typename Env, typename BitSetTraits>
+void BitSetOps</*BitSetType*/ BitSetShortLongRep,
+ /*Brand*/ BSShortLong,
+ /*Env*/ Env,
+ /*BitSetTraits*/ BitSetTraits>::DataFlowDLong(Env env,
+ BitSetShortLongRep& out,
+ const BitSetShortLongRep gen,
+ const BitSetShortLongRep in)
+{
+ assert(!IsShort(env));
+ unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
+ for (unsigned i = 0; i < len; i++)
+ {
+ out[i] = out[i] & (gen[i] | in[i]);
+ }
+}
+
+template <typename Env, typename BitSetTraits>
+void BitSetOps</*BitSetType*/ BitSetShortLongRep,
+ /*Brand*/ BSShortLong,
+ /*Env*/ Env,
+ /*BitSetTraits*/ BitSetTraits>::LivenessDLong(Env env,
+ BitSetShortLongRep& in,
+ const BitSetShortLongRep def,
+ const BitSetShortLongRep use,
+ const BitSetShortLongRep out)
+{
+ assert(!IsShort(env));
+ unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
+ for (unsigned i = 0; i < len; i++)
+ {
+ in[i] = use[i] | (out[i] & ~def[i]);
+ }
+}
+
+template <typename Env, typename BitSetTraits>
+bool BitSetOps</*BitSetType*/ BitSetShortLongRep,
+ /*Brand*/ BSShortLong,
+ /*Env*/ Env,
/*BitSetTraits*/ BitSetTraits>::EqualLong(Env env, BitSetShortLongRep bs1, BitSetShortLongRep bs2)
{
assert(!IsShort(env));
@@ -762,13 +864,12 @@ const char* BitSetOps</*BitSetType*/ BitSetShortLongRep,
/*BitSetTraits*/ BitSetTraits>::ToStringLong(Env env, BitSetShortLongRep bs)
{
assert(!IsShort(env));
- unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
- const int CharsForSizeT = sizeof(size_t) * 2;
- unsigned allocSz = len * CharsForSizeT + 4;
- unsigned remaining = allocSz;
- IAllocator* alloc = BitSetTraits::GetDebugOnlyAllocator(env);
- char* res = (char*)alloc->Alloc(allocSz);
- char* temp = res;
+ unsigned len = BitSetTraits::GetArrSize(env, sizeof(size_t));
+ const int CharsForSizeT = sizeof(size_t) * 2;
+ unsigned allocSz = len * CharsForSizeT + 4;
+ unsigned remaining = allocSz;
+ char* res = (char*)BitSetTraits::DebugAlloc(env, allocSz);
+ char* temp = res;
for (unsigned i = len; 0 < i; i--)
{
size_t bits = bs[i - 1];
diff --git a/src/jit/block.h b/src/jit/block.h
index 786b83178f..752219bdb7 100644
--- a/src/jit/block.h
+++ b/src/jit/block.h
@@ -47,27 +47,28 @@ typedef BitVec_ValRet_T ASSERT_VALRET_TP;
* of the following enumeration.
*/
+// clang-format off
+
DECLARE_TYPED_ENUM(BBjumpKinds, BYTE)
{
- BBJ_EHFINALLYRET, // block ends with 'endfinally' (for finally or fault)
- BBJ_EHFILTERRET, // block ends with 'endfilter'
- BBJ_EHCATCHRET, // block ends with a leave out of a catch (only #if FEATURE_EH_FUNCLETS)
- BBJ_THROW, // block ends with 'throw'
- BBJ_RETURN, // block ends with 'ret'
-
- BBJ_NONE, // block flows into the next one (no jump)
-
- BBJ_ALWAYS, // block always jumps to the target
- BBJ_LEAVE, // block always jumps to the target, maybe out of guarded
- // region. Used temporarily until importing
- BBJ_CALLFINALLY, // block always calls the target finally
- BBJ_COND, // block conditionally jumps to the target
- BBJ_SWITCH, // block ends with a switch statement
-
- BBJ_COUNT
+ BBJ_EHFINALLYRET,// block ends with 'endfinally' (for finally or fault)
+ BBJ_EHFILTERRET, // block ends with 'endfilter'
+ BBJ_EHCATCHRET, // block ends with a leave out of a catch (only #if FEATURE_EH_FUNCLETS)
+ BBJ_THROW, // block ends with 'throw'
+ BBJ_RETURN, // block ends with 'ret'
+ BBJ_NONE, // block flows into the next one (no jump)
+ BBJ_ALWAYS, // block always jumps to the target
+ BBJ_LEAVE, // block always jumps to the target, maybe out of guarded region. Only used until importing.
+ BBJ_CALLFINALLY, // block always calls the target finally
+ BBJ_COND, // block conditionally jumps to the target
+ BBJ_SWITCH, // block ends with a switch statement
+
+ BBJ_COUNT
}
END_DECLARE_TYPED_ENUM(BBjumpKinds, BYTE)
+// clang-format on
+
struct GenTree;
struct GenTreeStmt;
struct BasicBlock;
@@ -377,66 +378,81 @@ struct BasicBlock : private LIR::Range
unsigned bbRefs; // number of blocks that can reach here, either by fall-through or a branch. If this falls to zero,
// the block is unreachable.
-#define BBF_VISITED 0x00000001 // BB visited during optimizations
-#define BBF_MARKED 0x00000002 // BB marked during optimizations
-#define BBF_CHANGED 0x00000004 // input/output of this block has changed
-#define BBF_REMOVED 0x00000008 // BB has been removed from bb-list
+// clang-format off
-#define BBF_DONT_REMOVE 0x00000010 // BB should not be removed during flow graph optimizations
-#define BBF_IMPORTED 0x00000020 // BB byte-code has been imported
-#define BBF_INTERNAL 0x00000040 // BB has been added by the compiler
+#define BBF_VISITED 0x00000001 // BB visited during optimizations
+#define BBF_MARKED 0x00000002 // BB marked during optimizations
+#define BBF_CHANGED 0x00000004 // input/output of this block has changed
+#define BBF_REMOVED 0x00000008 // BB has been removed from bb-list
+
+#define BBF_DONT_REMOVE 0x00000010 // BB should not be removed during flow graph optimizations
+#define BBF_IMPORTED 0x00000020 // BB byte-code has been imported
+#define BBF_INTERNAL 0x00000040 // BB has been added by the compiler
#define BBF_FAILED_VERIFICATION 0x00000080 // BB has verification exception
-#define BBF_TRY_BEG 0x00000100 // BB starts a 'try' block
-#define BBF_FUNCLET_BEG 0x00000200 // BB is the beginning of a funclet
-#define BBF_HAS_NULLCHECK 0x00000400 // BB contains a null check
-#define BBF_NEEDS_GCPOLL 0x00000800 // This BB is the source of a back edge and needs a GC Poll
-
-#define BBF_RUN_RARELY 0x00001000 // BB is rarely run (catch clauses, blocks with throws etc)
-#define BBF_LOOP_HEAD 0x00002000 // BB is the head of a loop
-#define BBF_LOOP_CALL0 0x00004000 // BB starts a loop that sometimes won't call
-#define BBF_LOOP_CALL1 0x00008000 // BB starts a loop that will always call
-
-#define BBF_HAS_LABEL 0x00010000 // BB needs a label
-#define BBF_JMP_TARGET 0x00020000 // BB is a target of an implicit/explicit jump
-#define BBF_HAS_JMP 0x00040000 // BB executes a JMP instruction (instead of return)
-#define BBF_GC_SAFE_POINT 0x00080000 // BB has a GC safe point (a call). More abstractly, BB does not
- // require a (further) poll -- this may be because this BB has a
- // call, or, in some cases, because the BB occurs in a loop, and
- // we've determined that all paths in the loop body leading to BB
- // include a call.
-#define BBF_HAS_VTABREF 0x00100000 // BB contains reference of vtable
-#define BBF_HAS_IDX_LEN 0x00200000 // BB contains simple index or length expressions on an array local var.
-#define BBF_HAS_NEWARRAY 0x00400000 // BB contains 'new' of an array
-#define BBF_HAS_NEWOBJ 0x00800000 // BB contains 'new' of an object type.
+#define BBF_TRY_BEG 0x00000100 // BB starts a 'try' block
+#define BBF_FUNCLET_BEG 0x00000200 // BB is the beginning of a funclet
+#define BBF_HAS_NULLCHECK 0x00000400 // BB contains a null check
+#define BBF_NEEDS_GCPOLL 0x00000800 // This BB is the source of a back edge and needs a GC Poll
+
+#define BBF_RUN_RARELY 0x00001000 // BB is rarely run (catch clauses, blocks with throws etc)
+#define BBF_LOOP_HEAD 0x00002000 // BB is the head of a loop
+#define BBF_LOOP_CALL0 0x00004000 // BB starts a loop that sometimes won't call
+#define BBF_LOOP_CALL1 0x00008000 // BB starts a loop that will always call
+
+#define BBF_HAS_LABEL 0x00010000 // BB needs a label
+#define BBF_JMP_TARGET 0x00020000 // BB is a target of an implicit/explicit jump
+#define BBF_HAS_JMP 0x00040000 // BB executes a JMP instruction (instead of return)
+#define BBF_GC_SAFE_POINT 0x00080000 // BB has a GC safe point (a call). More abstractly, BB does not require a
+ // (further) poll -- this may be because this BB has a call, or, in some
+ // cases, because the BB occurs in a loop, and we've determined that all
+ // paths in the loop body leading to BB include a call.
+
+#define BBF_HAS_VTABREF 0x00100000 // BB contains reference of vtable
+#define BBF_HAS_IDX_LEN 0x00200000 // BB contains simple index or length expressions on an array local var.
+#define BBF_HAS_NEWARRAY 0x00400000 // BB contains 'new' of an array
+#define BBF_HAS_NEWOBJ 0x00800000 // BB contains 'new' of an object type.
#if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
-#define BBF_FINALLY_TARGET 0x01000000 // BB is the target of a finally return: where a finally will return during
- // non-exceptional flow. Because the ARM calling sequence for calling a
- // finally explicitly sets the return address to the finally target and jumps
- // to the finally, instead of using a call instruction, ARM needs this to
- // generate correct code at the finally target, to allow for proper stack
- // unwind from within a non-exceptional call to a finally.
-#endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
-#define BBF_BACKWARD_JUMP 0x02000000 // BB is surrounded by a backward jump/switch arc
-#define BBF_RETLESS_CALL 0x04000000 // BBJ_CALLFINALLY that will never return (and therefore, won't need a paired
- // BBJ_ALWAYS); see isBBCallAlwaysPair().
-#define BBF_LOOP_PREHEADER 0x08000000 // BB is a loop preheader block
-
-#define BBF_COLD 0x10000000 // BB is cold
-#define BBF_PROF_WEIGHT 0x20000000 // BB weight is computed from profile data
+
+#define BBF_FINALLY_TARGET 0x01000000 // BB is the target of a finally return: where a finally will return during
+ // non-exceptional flow. Because the ARM calling sequence for calling a
+ // finally explicitly sets the return address to the finally target and jumps
+ // to the finally, instead of using a call instruction, ARM needs this to
+ // generate correct code at the finally target, to allow for proper stack
+ // unwind from within a non-exceptional call to a finally.
+
+#endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
+
+#define BBF_BACKWARD_JUMP 0x02000000 // BB is surrounded by a backward jump/switch arc
+#define BBF_RETLESS_CALL 0x04000000 // BBJ_CALLFINALLY that will never return (and therefore, won't need a paired
+ // BBJ_ALWAYS); see isBBCallAlwaysPair().
+#define BBF_LOOP_PREHEADER 0x08000000 // BB is a loop preheader block
+
+#define BBF_COLD 0x10000000 // BB is cold
+#define BBF_PROF_WEIGHT 0x20000000 // BB weight is computed from profile data
+
#ifdef LEGACY_BACKEND
-#define BBF_FORWARD_SWITCH 0x40000000 // Aux flag used in FP codegen to know if a jmptable entry has been forwarded
-#else // !LEGACY_BACKEND
-#define BBF_IS_LIR 0x40000000 // Set if the basic block contains LIR (as opposed to HIR)
-#endif // LEGACY_BACKEND
-#define BBF_KEEP_BBJ_ALWAYS 0x80000000 // A special BBJ_ALWAYS block, used by EH code generation. Keep the jump kind
- // as BBJ_ALWAYS. Used for the paired BBJ_ALWAYS block following the
- // BBJ_CALLFINALLY block, as well as, on x86, the final step block out of a
- // finally.
-
-#define BBF_CLONED_FINALLY_BEGIN 0x100000000 // First block of a cloned finally region
-#define BBF_CLONED_FINALLY_END 0x200000000 // Last block of a cloned finally region
+
+#define BBF_FORWARD_SWITCH 0x40000000 // Aux flag used in FP codegen to know if a jmptable entry has been forwarded
+
+#else // !LEGACY_BACKEND
+
+#define BBF_IS_LIR 0x40000000 // Set if the basic block contains LIR (as opposed to HIR)
+
+#endif // LEGACY_BACKEND
+
+#define BBF_KEEP_BBJ_ALWAYS 0x80000000 // A special BBJ_ALWAYS block, used by EH code generation. Keep the jump kind
+ // as BBJ_ALWAYS. Used for the paired BBJ_ALWAYS block following the
+ // BBJ_CALLFINALLY block, as well as, on x86, the final step block out of a
+ // finally.
+
+#define BBF_CLONED_FINALLY_BEGIN 0x100000000 // First block of a cloned finally region
+#define BBF_CLONED_FINALLY_END 0x200000000 // Last block of a cloned finally region
+
+// clang-format on
+
+#define BBF_DOMINATED_BY_EXCEPTIONAL_ENTRY 0x400000000 // Block is dominated by exceptional entry.
// Flags that relate blocks to loop structure.
@@ -518,22 +534,39 @@ struct BasicBlock : private LIR::Range
weight_t bbWeight; // The dynamic execution weight of this block
+ // getCalledCount -- get the value used to normalize weights for this method
+ weight_t getCalledCount(Compiler* comp);
+
// getBBWeight -- get the normalized weight of this block
- unsigned getBBWeight(Compiler* comp);
+ weight_t getBBWeight(Compiler* comp);
+
+ // hasProfileWeight -- Returns true if this block's weight came from profile data
+ bool hasProfileWeight() const
+ {
+ return ((this->bbFlags & BBF_PROF_WEIGHT) != 0);
+ }
- // setBBWeight -- if the block weight is not derived from a profile, then set the weight to the input
- // weight, but make sure to not overflow BB_MAX_WEIGHT
- void setBBWeight(unsigned weight)
+ // setBBWeight -- if the block weight is not derived from a profile,
+ // then set the weight to the input weight, making sure to not overflow BB_MAX_WEIGHT
+ // Note to set the weight from profile data, instead use setBBProfileWeight
+ void setBBWeight(weight_t weight)
{
- if (!(this->bbFlags & BBF_PROF_WEIGHT))
+ if (!hasProfileWeight())
{
this->bbWeight = min(weight, BB_MAX_WEIGHT);
}
}
+ // setBBProfileWeight -- Set the profile-derived weight for a basic block
+ void setBBProfileWeight(unsigned weight)
+ {
+ this->bbFlags |= BBF_PROF_WEIGHT;
+ this->bbWeight = weight;
+ }
+
// modifyBBWeight -- same as setBBWeight, but also make sure that if the block is rarely run, it stays that
// way, and if it's not rarely run then its weight never drops below 1.
- void modifyBBWeight(unsigned weight)
+ void modifyBBWeight(weight_t weight)
{
if (this->bbWeight != BB_ZERO_WEIGHT)
{
@@ -541,20 +574,12 @@ struct BasicBlock : private LIR::Range
}
}
- // setBBProfileWeight -- Set the profile-derived weight for a basic block
- void setBBProfileWeight(unsigned weight)
- {
- this->bbFlags |= BBF_PROF_WEIGHT;
- // Check if the multiplication by BB_UNITY_WEIGHT will overflow.
- this->bbWeight = (weight <= BB_MAX_WEIGHT / BB_UNITY_WEIGHT) ? weight * BB_UNITY_WEIGHT : BB_MAX_WEIGHT;
- }
-
// this block will inherit the same weight and relevant bbFlags as bSrc
void inheritWeight(BasicBlock* bSrc)
{
this->bbWeight = bSrc->bbWeight;
- if (bSrc->bbFlags & BBF_PROF_WEIGHT)
+ if (bSrc->hasProfileWeight())
{
this->bbFlags |= BBF_PROF_WEIGHT;
}
@@ -868,12 +893,6 @@ struct BasicBlock : private LIR::Range
unsigned bbDfsNum; // The index of this block in DFS reverse post order
// relative to the flow graph.
-#if ASSERTION_PROP
- // A set of blocks which dominate this one *except* the normal entry block. This is lazily initialized
- // and used only by Assertion Prop, intersected with fgEnterBlks!
- BlockSet bbDoms;
-#endif
-
IL_OFFSET bbCodeOffs; // IL offset of the beginning of the block
IL_OFFSET bbCodeOffsEnd; // IL offset past the end of the block. Thus, the [bbCodeOffs..bbCodeOffsEnd)
// range is not inclusive of the end offset. The count of IL bytes in the block
@@ -945,12 +964,6 @@ struct BasicBlock : private LIR::Range
};
union {
-#if ASSERTION_PROP
- ASSERT_TP bbAssertionKill; // value assignments killed by block
-#endif
- };
-
- union {
EXPSET_TP bbCseIn; // CSEs available on entry
#if ASSERTION_PROP
ASSERT_TP bbAssertionIn; // value assignments available on entry
@@ -1050,7 +1063,6 @@ struct BasicBlock : private LIR::Range
GenTreeStmt* firstStmt() const;
GenTreeStmt* lastStmt() const;
- GenTreeStmt* lastTopLevelStmt();
GenTree* firstNode();
GenTree* lastNode();
@@ -1074,13 +1086,7 @@ struct BasicBlock : private LIR::Range
GenTree* FirstNonPhiDefOrCatchArgAsg();
BasicBlock()
- :
-#if ASSERTION_PROP
- BLOCKSET_INIT_NOCOPY(bbDoms, BlockSetOps::UninitVal())
- ,
-#endif // ASSERTION_PROP
- VARSET_INIT_NOCOPY(bbLiveIn, VarSetOps::UninitVal())
- , VARSET_INIT_NOCOPY(bbLiveOut, VarSetOps::UninitVal())
+ : VARSET_INIT_NOCOPY(bbLiveIn, VarSetOps::UninitVal()), VARSET_INIT_NOCOPY(bbLiveOut, VarSetOps::UninitVal())
{
}
@@ -1167,6 +1173,16 @@ public:
void MakeLIR(GenTree* firstNode, GenTree* lastNode);
bool IsLIR();
+
+ void SetDominatedByExceptionalEntryFlag()
+ {
+ bbFlags |= BBF_DOMINATED_BY_EXCEPTIONAL_ENTRY;
+ }
+
+ bool IsDominatedByExceptionalEntryFlag()
+ {
+ return (bbFlags & BBF_DOMINATED_BY_EXCEPTIONAL_ENTRY) != 0;
+ }
};
template <>
diff --git a/src/jit/codegen.h b/src/jit/codegen.h
index 090283ee50..e50e6405e0 100755
--- a/src/jit/codegen.h
+++ b/src/jit/codegen.h
@@ -162,6 +162,36 @@ private:
//
unsigned genStackLevel;
+ void SubtractStackLevel(unsigned adjustment)
+ {
+ assert(genStackLevel >= adjustment);
+ unsigned newStackLevel = genStackLevel - adjustment;
+ if (genStackLevel != newStackLevel)
+ {
+ JITDUMP("Adjusting stack level from %d to %d\n", genStackLevel, newStackLevel);
+ }
+ genStackLevel = newStackLevel;
+ }
+
+ void AddStackLevel(unsigned adjustment)
+ {
+ unsigned newStackLevel = genStackLevel + adjustment;
+ if (genStackLevel != newStackLevel)
+ {
+ JITDUMP("Adjusting stack level from %d to %d\n", genStackLevel, newStackLevel);
+ }
+ genStackLevel = newStackLevel;
+ }
+
+ void SetStackLevel(unsigned newStackLevel)
+ {
+ if (genStackLevel != newStackLevel)
+ {
+ JITDUMP("Setting stack level from %d to %d\n", genStackLevel, newStackLevel);
+ }
+ genStackLevel = newStackLevel;
+ }
+
#if STACK_PROBES
// Stack Probes
bool genNeedPrologStackProbe;
@@ -416,20 +446,30 @@ protected:
void genPrologPadForReJit();
+ // clang-format off
void genEmitCall(int callType,
CORINFO_METHOD_HANDLE methHnd,
- INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo) void* addr X86_ARG(ssize_t argSize),
- emitAttr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
- IL_OFFSETX ilOffset,
- regNumber base = REG_NA,
- bool isJump = false,
- bool isNoGC = false);
-
+ INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo)
+ void* addr
+ X86_ARG(ssize_t argSize),
+ emitAttr retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
+ IL_OFFSETX ilOffset,
+ regNumber base = REG_NA,
+ bool isJump = false,
+ bool isNoGC = false);
+ // clang-format on
+
+ // clang-format off
void genEmitCall(int callType,
CORINFO_METHOD_HANDLE methHnd,
- INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo) GenTreeIndir* indir X86_ARG(ssize_t argSize),
- emitAttr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
- IL_OFFSETX ilOffset);
+ INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo)
+ GenTreeIndir* indir
+ X86_ARG(ssize_t argSize),
+ emitAttr retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
+ IL_OFFSETX ilOffset);
+ // clang-format on
//
// Epilog functions
@@ -470,6 +510,9 @@ protected:
void genSetPSPSym(regNumber initReg, bool* pInitRegZeroed);
void genUpdateCurrentFunclet(BasicBlock* block);
+#if defined(_TARGET_ARM_)
+ void genInsertNopForUnwinder(BasicBlock* block);
+#endif
#else // FEATURE_EH_FUNCLETS
@@ -479,6 +522,13 @@ protected:
return;
}
+#if defined(_TARGET_ARM_)
+ void genInsertNopForUnwinder(BasicBlock* block)
+ {
+ return;
+ }
+#endif
+
#endif // FEATURE_EH_FUNCLETS
void genGeneratePrologsAndEpilogs();
@@ -810,8 +860,8 @@ public:
instruction ins, regNumber reg, TempDsc* tmp, unsigned ofs, var_types type, emitAttr size = EA_UNKNOWN);
void inst_FS_ST(instruction ins, emitAttr size, TempDsc* tmp, unsigned ofs);
- void instEmit_indCall(GenTreePtr call,
- size_t argSize,
+ void instEmit_indCall(GenTreeCall* call,
+ size_t argSize,
emitAttr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize));
void instEmit_RM(instruction ins, GenTreePtr tree, GenTreePtr addr, unsigned offs);
diff --git a/src/jit/codegenarm.cpp b/src/jit/codegenarm.cpp
index 81f5889e3f..41bd8040ac 100644
--- a/src/jit/codegenarm.cpp
+++ b/src/jit/codegenarm.cpp
@@ -24,85 +24,47 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "emit.h"
//------------------------------------------------------------------------
-// genSetRegToIcon: Generate code that will set the given register to the integer constant.
-//
-void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFlags flags)
-{
- // Reg cannot be a FP reg
- assert(!genIsValidFloatReg(reg));
-
- // The only TYP_REF constant that can come this path is a managed 'null' since it is not
- // relocatable. Other ref type constants (e.g. string objects) go through a different
- // code path.
- noway_assert(type != TYP_REF || val == 0);
-
- instGen_Set_Reg_To_Imm(emitActualTypeSize(type), reg, val, flags);
-}
-
-//------------------------------------------------------------------------
-// genEmitGSCookieCheck: Generate code to check that the GS cookie wasn't thrashed by a buffer overrun.
-//
-void CodeGen::genEmitGSCookieCheck(bool pushReg)
-{
- NYI("ARM genEmitGSCookieCheck");
-}
-
-//------------------------------------------------------------------------
// genCallFinally: Generate a call to the finally block.
//
BasicBlock* CodeGen::genCallFinally(BasicBlock* block)
{
- NYI("ARM genCallFinally");
- return block;
+ BasicBlock* bbFinallyRet = nullptr;
+
+ // We don't have retless calls, since we use the BBJ_ALWAYS to point at a NOP pad where
+ // we would have otherwise created retless calls.
+ assert(block->isBBCallAlwaysPair());
+
+ assert(block->bbNext != NULL);
+ assert(block->bbNext->bbJumpKind == BBJ_ALWAYS);
+ assert(block->bbNext->bbJumpDest != NULL);
+ assert(block->bbNext->bbJumpDest->bbFlags & BBF_FINALLY_TARGET);
+
+ bbFinallyRet = block->bbNext->bbJumpDest;
+ bbFinallyRet->bbFlags |= BBF_JMP_TARGET;
+
+ // Load the address where the finally funclet should return into LR.
+ // The funclet prolog/epilog will do "push {lr}" / "pop {pc}" to do the return.
+ getEmitter()->emitIns_R_L(INS_movw, EA_4BYTE_DSP_RELOC, bbFinallyRet, REG_LR);
+ getEmitter()->emitIns_R_L(INS_movt, EA_4BYTE_DSP_RELOC, bbFinallyRet, REG_LR);
+
+ // Jump to the finally BB
+ inst_JMP(EJ_jmp, block->bbJumpDest);
+
+ // The BBJ_ALWAYS is used because the BBJ_CALLFINALLY can't point to the
+ // jump target using bbJumpDest - that is already used to point
+ // to the finally block. So just skip past the BBJ_ALWAYS unless the
+ // block is RETLESS.
+ assert(!(block->bbFlags & BBF_RETLESS_CALL));
+ assert(block->isBBCallAlwaysPair());
+ return block->bbNext;
}
//------------------------------------------------------------------------
// genEHCatchRet:
void CodeGen::genEHCatchRet(BasicBlock* block)
{
- NYI("ARM genEHCatchRet");
-}
-
-//---------------------------------------------------------------------
-// genIntrinsic - generate code for a given intrinsic
-//
-// Arguments
-// treeNode - the GT_INTRINSIC node
-//
-// Return value:
-// None
-//
-void CodeGen::genIntrinsic(GenTreePtr treeNode)
-{
- // Both operand and its result must be of the same floating point type.
- GenTreePtr srcNode = treeNode->gtOp.gtOp1;
- assert(varTypeIsFloating(srcNode));
- assert(srcNode->TypeGet() == treeNode->TypeGet());
-
- // Right now only Abs/Round/Sqrt are treated as math intrinsics.
- //
- switch (treeNode->gtIntrinsic.gtIntrinsicId)
- {
- case CORINFO_INTRINSIC_Abs:
- genConsumeOperands(treeNode->AsOp());
- getEmitter()->emitInsBinary(INS_vabs, emitTypeSize(treeNode), treeNode, srcNode);
- break;
-
- case CORINFO_INTRINSIC_Round:
- NYI_ARM("genIntrinsic for round - not implemented yet");
- break;
-
- case CORINFO_INTRINSIC_Sqrt:
- genConsumeOperands(treeNode->AsOp());
- getEmitter()->emitInsBinary(INS_vsqrt, emitTypeSize(treeNode), treeNode, srcNode);
- break;
-
- default:
- assert(!"genIntrinsic: Unsupported intrinsic");
- unreached();
- }
-
- genProduceReg(treeNode);
+ getEmitter()->emitIns_R_L(INS_movw, EA_4BYTE_DSP_RELOC, block->bbJumpDest, REG_INTRET);
+ getEmitter()->emitIns_R_L(INS_movt, EA_4BYTE_DSP_RELOC, block->bbJumpDest, REG_INTRET);
}
//------------------------------------------------------------------------
@@ -243,6 +205,131 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre
}
//------------------------------------------------------------------------
+// genCodeForBinary: Generate code for many binary arithmetic operators
+// This method is expected to have called genConsumeOperands() before calling it.
+//
+// Arguments:
+// treeNode - The binary operation for which we are generating code.
+//
+// Return Value:
+// None.
+//
+// Notes:
+// Mul and div are not handled here.
+// See the assert below for the operators that are handled.
+
+void CodeGen::genCodeForBinary(GenTree* treeNode)
+{
+ const genTreeOps oper = treeNode->OperGet();
+ regNumber targetReg = treeNode->gtRegNum;
+ var_types targetType = treeNode->TypeGet();
+ emitter* emit = getEmitter();
+
+ assert(oper == GT_ADD || oper == GT_SUB || oper == GT_ADD_LO || oper == GT_ADD_HI || oper == GT_SUB_LO ||
+ oper == GT_SUB_HI || oper == GT_OR || oper == GT_XOR || oper == GT_AND);
+
+ if ((oper == GT_ADD || oper == GT_SUB || oper == GT_ADD_HI || oper == GT_SUB_HI) && treeNode->gtOverflow())
+ {
+ // This is also checked in the importer.
+ NYI("Overflow not yet implemented");
+ }
+
+ GenTreePtr op1 = treeNode->gtGetOp1();
+ GenTreePtr op2 = treeNode->gtGetOp2();
+
+ instruction ins = genGetInsForOper(oper, targetType);
+
+ // The arithmetic node must be sitting in a register (since it's not contained)
+ noway_assert(targetReg != REG_NA);
+
+ if ((oper == GT_ADD_LO || oper == GT_SUB_LO))
+ {
+ // During decomposition, all operands become reg
+ assert(!op1->isContained() && !op2->isContained());
+ emit->emitIns_R_R_R(ins, emitTypeSize(treeNode), treeNode->gtRegNum, op1->gtRegNum, op2->gtRegNum,
+ INS_FLAGS_SET);
+ }
+ else
+ {
+ regNumber r = emit->emitInsTernary(ins, emitTypeSize(treeNode), treeNode, op1, op2);
+ assert(r == targetReg);
+ }
+
+ genProduceReg(treeNode);
+}
+
+//------------------------------------------------------------------------
+// genReturn: Generates code for return statement.
+// In case of struct return, delegates to the genStructReturn method.
+//
+// Arguments:
+// treeNode - The GT_RETURN or GT_RETFILT tree node.
+//
+// Return Value:
+// None
+//
+void CodeGen::genReturn(GenTreePtr treeNode)
+{
+ assert(treeNode->OperGet() == GT_RETURN || treeNode->OperGet() == GT_RETFILT);
+ GenTreePtr op1 = treeNode->gtGetOp1();
+ var_types targetType = treeNode->TypeGet();
+
+#ifdef DEBUG
+ if (targetType == TYP_VOID)
+ {
+ assert(op1 == nullptr);
+ }
+#endif
+
+ if (treeNode->TypeGet() == TYP_LONG)
+ {
+ assert(op1 != nullptr);
+ noway_assert(op1->OperGet() == GT_LONG);
+ GenTree* loRetVal = op1->gtGetOp1();
+ GenTree* hiRetVal = op1->gtGetOp2();
+ noway_assert((loRetVal->gtRegNum != REG_NA) && (hiRetVal->gtRegNum != REG_NA));
+
+ genConsumeReg(loRetVal);
+ genConsumeReg(hiRetVal);
+ if (loRetVal->gtRegNum != REG_LNGRET_LO)
+ {
+ inst_RV_RV(ins_Copy(targetType), REG_LNGRET_LO, loRetVal->gtRegNum, TYP_INT);
+ }
+ if (hiRetVal->gtRegNum != REG_LNGRET_HI)
+ {
+ inst_RV_RV(ins_Copy(targetType), REG_LNGRET_HI, hiRetVal->gtRegNum, TYP_INT);
+ }
+ }
+ else
+ {
+ if (varTypeIsStruct(treeNode))
+ {
+ NYI_ARM("struct return");
+ }
+ else if (targetType != TYP_VOID)
+ {
+ assert(op1 != nullptr);
+ noway_assert(op1->gtRegNum != REG_NA);
+
+ // !! NOTE !! genConsumeReg will clear op1 as GC ref after it has
+ // consumed a reg for the operand. This is because the variable
+ // is dead after return. But we are issuing more instructions
+ // like "profiler leave callback" after this consumption. So
+ // if you are issuing more instructions after this point,
+ // remember to keep the variable live up until the new method
+ // exit point where it is actually dead.
+ genConsumeReg(op1);
+
+ regNumber retReg = varTypeIsFloating(treeNode) ? REG_FLOATRET : REG_INTRET;
+ if (op1->gtRegNum != retReg)
+ {
+ inst_RV_RV(ins_Move_Extend(targetType, true), retReg, op1->gtRegNum, targetType);
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
// genCodeForTreeNode Generate code for a single node in the tree.
//
// Preconditions:
@@ -256,11 +343,13 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
#ifdef DEBUG
lastConsumedNode = nullptr;
+ if (compiler->verbose)
+ {
+ unsigned seqNum = treeNode->gtSeqNum; // Useful for setting a conditional break in Visual Studio
+ compiler->gtDispLIRNode(treeNode, "Generating: ");
+ }
#endif
- JITDUMP("Generating: ");
- DISPNODE(treeNode);
-
// contained nodes are part of their parents for codegen purposes
// ex : immediates, most LEAs
if (treeNode->isContained())
@@ -270,6 +359,10 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
switch (treeNode->gtOper)
{
+ case GT_LCLHEAP:
+ genLclHeap(treeNode);
+ break;
+
case GT_CNS_INT:
case GT_CNS_DBL:
genSetRegToConst(targetReg, targetType, treeNode);
@@ -313,12 +406,22 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
assert(varTypeIsIntegralOrI(treeNode));
__fallthrough;
+ case GT_ADD_LO:
+ case GT_ADD_HI:
+ case GT_SUB_LO:
+ case GT_SUB_HI:
case GT_ADD:
case GT_SUB:
+ genConsumeOperands(treeNode->AsOp());
+ genCodeForBinary(treeNode);
+ break;
+
case GT_MUL:
{
+ genConsumeOperands(treeNode->AsOp());
+
const genTreeOps oper = treeNode->OperGet();
- if ((oper == GT_ADD || oper == GT_SUB || oper == GT_MUL) && treeNode->gtOverflow())
+ if (treeNode->gtOverflow())
{
// This is also checked in the importer.
NYI("Overflow not yet implemented");
@@ -331,56 +434,8 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
// The arithmetic node must be sitting in a register (since it's not contained)
noway_assert(targetReg != REG_NA);
- regNumber op1reg = op1->gtRegNum;
- regNumber op2reg = op2->gtRegNum;
-
- GenTreePtr dst;
- GenTreePtr src;
-
- genConsumeIfReg(op1);
- genConsumeIfReg(op2);
-
- if (!varTypeIsFloating(targetType))
- {
- // This is the case of reg1 = reg1 op reg2
- // We're ready to emit the instruction without any moves
- if (op1reg == targetReg)
- {
- dst = op1;
- src = op2;
- }
- // We have reg1 = reg2 op reg1
- // In order for this operation to be correct
- // we need that op is a commutative operation so
- // we can convert it into reg1 = reg1 op reg2 and emit
- // the same code as above
- else if (op2reg == targetReg)
- {
- assert(GenTree::OperIsCommutative(treeNode->OperGet()));
- dst = op2;
- src = op1;
- }
- // dest, op1 and op2 registers are different:
- // reg3 = reg1 op reg2
- // We can implement this by issuing a mov:
- // reg3 = reg1
- // reg3 = reg3 op reg2
- else
- {
- inst_RV_RV(ins_Move_Extend(targetType, true), targetReg, op1reg, op1->gtType);
- regTracker.rsTrackRegCopy(targetReg, op1reg);
- gcInfo.gcMarkRegPtrVal(targetReg, targetType);
- dst = treeNode;
- src = op2;
- }
-
- regNumber r = emit->emitInsBinary(ins, emitTypeSize(treeNode), dst, src);
- assert(r == targetReg);
- }
- else
- {
- emit->emitIns_R_R_R(ins, emitTypeSize(treeNode), targetReg, op1reg, op2reg);
- }
+ regNumber r = emit->emitInsTernary(ins, emitTypeSize(treeNode), treeNode, op1, op2);
+ assert(r == targetReg);
}
genProduceReg(treeNode);
break;
@@ -388,18 +443,19 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
case GT_LSH:
case GT_RSH:
case GT_RSZ:
+ case GT_ROR:
genCodeForShift(treeNode);
- // genCodeForShift() calls genProduceReg()
+ break;
+
+ case GT_LSH_HI:
+ case GT_RSH_LO:
+ genCodeForShiftLong(treeNode);
break;
case GT_CAST:
// Cast is never contained (?)
noway_assert(targetReg != REG_NA);
- // Overflow conversions from float/double --> int types go through helper calls.
- if (treeNode->gtOverflow() && !varTypeIsFloating(treeNode->gtOp.gtOp1))
- NYI("Unimplmented GT_CAST:int <--> int with overflow");
-
if (varTypeIsFloating(targetType) && varTypeIsFloating(treeNode->gtOp.gtOp1))
{
// Casts float/double <--> double/float
@@ -480,45 +536,110 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
case GT_STORE_LCL_FLD:
{
- NYI_IF(targetType == TYP_STRUCT, "GT_STORE_LCL_FLD: struct store local field not supported");
+ noway_assert(targetType != TYP_STRUCT);
+
+ // record the offset
+ unsigned offset = treeNode->gtLclFld.gtLclOffs;
+
+ // We must have a stack store with GT_STORE_LCL_FLD
noway_assert(!treeNode->InReg());
+ noway_assert(targetReg == REG_NA);
- GenTreePtr op1 = treeNode->gtOp.gtOp1->gtEffectiveVal();
- genConsumeIfReg(op1);
- emit->emitInsBinary(ins_Store(targetType), emitTypeSize(treeNode), treeNode, op1);
+ GenTreeLclVarCommon* varNode = treeNode->AsLclVarCommon();
+ unsigned varNum = varNode->gtLclNum;
+ assert(varNum < compiler->lvaCount);
+ LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
+
+ // Ensure that lclVar nodes are typed correctly.
+ assert(!varDsc->lvNormalizeOnStore() || targetType == genActualType(varDsc->TypeGet()));
+
+ GenTreePtr data = treeNode->gtOp.gtOp1->gtEffectiveVal();
+ instruction ins = ins_Store(targetType);
+ emitAttr attr = emitTypeSize(targetType);
+ if (data->isContainedIntOrIImmed())
+ {
+ assert(data->IsIntegralConst(0));
+ NYI_ARM("st.lclFld contained operand");
+ }
+ else
+ {
+ assert(!data->isContained());
+ genConsumeReg(data);
+ emit->emitIns_S_R(ins, attr, data->gtRegNum, varNum, offset);
+ }
+
+ genUpdateLife(varNode);
+ varDsc->lvRegNum = REG_STK;
}
break;
case GT_STORE_LCL_VAR:
{
- NYI_IF(targetType == TYP_STRUCT, "struct store local not supported");
+ GenTreeLclVarCommon* varNode = treeNode->AsLclVarCommon();
- GenTreePtr op1 = treeNode->gtOp.gtOp1->gtEffectiveVal();
- genConsumeIfReg(op1);
- if (treeNode->gtRegNum == REG_NA)
- {
- // stack store
- emit->emitInsMov(ins_Store(targetType), emitTypeSize(treeNode), treeNode);
- compiler->lvaTable[treeNode->AsLclVarCommon()->gtLclNum].lvRegNum = REG_STK;
- }
- else if (op1->isContained())
+ unsigned varNum = varNode->gtLclNum;
+ assert(varNum < compiler->lvaCount);
+ LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
+ unsigned offset = 0;
+
+ // Ensure that lclVar nodes are typed correctly.
+ assert(!varDsc->lvNormalizeOnStore() || targetType == genActualType(varDsc->TypeGet()));
+
+ GenTreePtr data = treeNode->gtOp.gtOp1->gtEffectiveVal();
+
+ // var = call, where call returns a multi-reg return value
+ // case is handled separately.
+ if (data->gtSkipReloadOrCopy()->IsMultiRegCall())
{
- // Currently, we assume that the contained source of a GT_STORE_LCL_VAR writing to a register
- // must be a constant. However, in the future we might want to support a contained memory op.
- // This is a bit tricky because we have to decide it's contained before register allocation,
- // and this would be a case where, once that's done, we need to mark that node as always
- // requiring a register - which we always assume now anyway, but once we "optimize" that
- // we'll have to take cases like this into account.
- assert((op1->gtRegNum == REG_NA) && op1->OperIsConst());
- genSetRegToConst(treeNode->gtRegNum, targetType, op1);
+ genMultiRegCallStoreToLocal(treeNode);
+ break;
}
- else if (op1->gtRegNum != treeNode->gtRegNum)
+ else
{
- assert(op1->gtRegNum != REG_NA);
- emit->emitInsBinary(ins_Move_Extend(targetType, true), emitTypeSize(treeNode), treeNode, op1);
+ if (treeNode->TypeGet() == TYP_LONG)
+ {
+ genStoreLongLclVar(treeNode);
+ break;
+ }
+
+ genConsumeRegs(data);
+
+ regNumber dataReg = REG_NA;
+ if (data->isContainedIntOrIImmed())
+ {
+ assert(data->IsIntegralConst(0));
+ NYI_ARM("st.lclVar contained operand");
+ }
+ else
+ {
+ assert(!data->isContained());
+ dataReg = data->gtRegNum;
+ }
+ assert(dataReg != REG_NA);
+
+ if (targetReg == REG_NA) // store into stack based LclVar
+ {
+ inst_set_SV_var(varNode);
+
+ instruction ins = ins_Store(targetType);
+ emitAttr attr = emitTypeSize(targetType);
+
+ emit->emitIns_S_R(ins, attr, dataReg, varNum, offset);
+
+ genUpdateLife(varNode);
+
+ varDsc->lvRegNum = REG_STK;
+ }
+ else // store into register (i.e move into register)
+ {
+ if (dataReg != targetReg)
+ {
+ // Assign into targetReg when dataReg (from op1) is not the same register
+ inst_RV_RV(ins_Copy(targetType), targetReg, dataReg, targetType);
+ }
+ genProduceReg(treeNode);
+ }
}
- if (treeNode->gtRegNum != REG_NA)
- genProduceReg(treeNode);
}
break;
@@ -535,26 +656,8 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
__fallthrough;
case GT_RETURN:
- {
- GenTreePtr op1 = treeNode->gtOp.gtOp1;
- if (targetType == TYP_VOID)
- {
- assert(op1 == nullptr);
- break;
- }
- assert(op1 != nullptr);
- op1 = op1->gtEffectiveVal();
-
- NYI_IF(op1->gtRegNum == REG_NA, "GT_RETURN: return of a value not in register");
- genConsumeReg(op1);
-
- regNumber retReg = varTypeIsFloating(op1) ? REG_FLOATRET : REG_INTRET;
- if (op1->gtRegNum != retReg)
- {
- inst_RV_RV(ins_Move_Extend(targetType, true), retReg, op1->gtRegNum, targetType);
- }
- }
- break;
+ genReturn(treeNode);
+ break;
case GT_LEA:
{
@@ -568,7 +671,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
case GT_IND:
genConsumeAddress(treeNode->AsIndir()->Addr());
- emit->emitInsMov(ins_Load(treeNode->TypeGet()), emitTypeSize(treeNode), treeNode);
+ emit->emitInsLoadStoreOp(ins_Load(targetType), emitTypeSize(treeNode), targetReg, treeNode->AsIndir());
genProduceReg(treeNode);
break;
@@ -652,6 +755,22 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
// vmrs with register 0xf has special meaning of transferring flags
emit->emitIns_R(INS_vmrs, EA_4BYTE, REG_R15);
}
+ else if (varTypeIsLong(op1))
+ {
+#ifdef DEBUG
+ // The result of an unlowered long compare on a 32-bit target must either be
+ // a) materialized into a register, or
+ // b) unused.
+ //
+ // A long compare that has a result that is used but not materialized into a register should
+ // have been handled by Lowering::LowerCompare.
+
+ LIR::Use use;
+ assert((treeNode->gtRegNum != REG_NA) || !LIR::AsRange(compiler->compCurBB).TryGetUse(treeNode, &use));
+#endif
+ genCompareLong(treeNode);
+ break;
+ }
else
{
var_types op1Type = op1->TypeGet();
@@ -702,6 +821,19 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
}
break;
+ case GT_JCC:
+ {
+ GenTreeJumpCC* jcc = treeNode->AsJumpCC();
+
+ assert(compiler->compCurBB->bbJumpKind == BBJ_COND);
+
+ CompareKind compareKind = ((jcc->gtFlags & GTF_UNSIGNED) != 0) ? CK_UNSIGNED : CK_SIGNED;
+ emitJumpKind jumpKind = genJumpKindForOper(jcc->gtCondition, compareKind);
+
+ inst_JMP(jumpKind, compiler->compCurBB->bbJumpDest);
+ }
+ break;
+
case GT_RETURNTRAP:
{
// this is nothing but a conditional call to CORINFO_HELP_STOP_FOR_GC
@@ -785,30 +917,14 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
genConsumeAddress(addr);
}
- emit->emitInsMov(ins_Store(data->TypeGet()), emitTypeSize(storeInd), storeInd);
+ emit->emitInsLoadStoreOp(ins_Store(targetType), emitTypeSize(storeInd), data->gtRegNum,
+ treeNode->AsIndir());
}
}
break;
case GT_COPY:
- {
- assert(treeNode->gtOp.gtOp1->IsLocal());
- GenTreeLclVarCommon* lcl = treeNode->gtOp.gtOp1->AsLclVarCommon();
- LclVarDsc* varDsc = &compiler->lvaTable[lcl->gtLclNum];
- inst_RV_RV(ins_Move_Extend(targetType, true), targetReg, genConsumeReg(treeNode->gtOp.gtOp1), targetType,
- emitTypeSize(targetType));
-
- // The old location is dying
- genUpdateRegLife(varDsc, /*isBorn*/ false, /*isDying*/ true DEBUGARG(treeNode->gtOp.gtOp1));
-
- gcInfo.gcMarkRegSetNpt(genRegMask(treeNode->gtOp.gtOp1->gtRegNum));
-
- genUpdateVarReg(varDsc, treeNode);
-
- // The new location is going live
- genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(treeNode));
- }
- genProduceReg(treeNode);
+ // This is handled at the time we call genConsumeReg() on the GT_COPY
break;
case GT_LIST:
@@ -818,33 +934,8 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
break;
case GT_PUTARG_STK:
- {
- NYI_IF(targetType == TYP_STRUCT, "GT_PUTARG_STK: struct support not implemented");
-
- // Get argument offset on stack.
- // Here we cross check that argument offset hasn't changed from lowering to codegen since
- // we are storing arg slot number in GT_PUTARG_STK node in lowering phase.
- int argOffset = treeNode->AsPutArgStk()->gtSlotNum * TARGET_POINTER_SIZE;
-#ifdef DEBUG
- fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(treeNode->AsPutArgStk()->gtCall, treeNode);
- assert(curArgTabEntry);
- assert(argOffset == (int)curArgTabEntry->slotNum * TARGET_POINTER_SIZE);
-#endif
-
- GenTreePtr data = treeNode->gtOp.gtOp1->gtEffectiveVal();
- if (data->isContained())
- {
- emit->emitIns_S_I(ins_Store(targetType), emitTypeSize(targetType), compiler->lvaOutgoingArgSpaceVar,
- argOffset, (int)data->AsIntConCommon()->IconValue());
- }
- else
- {
- genConsumeReg(data);
- emit->emitIns_S_R(ins_Store(targetType), emitTypeSize(targetType), data->gtRegNum,
- compiler->lvaOutgoingArgSpaceVar, argOffset);
- }
- }
- break;
+ genPutArgStk(treeNode->AsPutArgStk());
+ break;
case GT_PUTARG_REG:
{
@@ -863,7 +954,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
break;
case GT_CALL:
- genCallInstruction(treeNode);
+ genCallInstruction(treeNode->AsCall());
break;
case GT_LOCKADD:
@@ -872,6 +963,10 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
genLockedInstructions(treeNode->AsOp());
break;
+ case GT_MEMORYBARRIER:
+ instGen_MemoryBarrier();
+ break;
+
case GT_CMPXCHG:
{
NYI("GT_CMPXCHG");
@@ -944,7 +1039,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
case GT_LABEL:
genPendingCallLabel = genCreateTempLabel();
treeNode->gtLabel.gtLabBB = genPendingCallLabel;
- emit->emitIns_R_L(INS_lea, EA_PTRSIZE, genPendingCallLabel, treeNode->gtRegNum);
+ emit->emitIns_J_R(INS_adr, EA_PTRSIZE, genPendingCallLabel, treeNode->gtRegNum);
break;
case GT_CLS_VAR_ADDR:
@@ -952,6 +1047,27 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
genProduceReg(treeNode);
break;
+ case GT_STORE_DYN_BLK:
+ case GT_STORE_BLK:
+ genCodeForStoreBlk(treeNode->AsBlk());
+ break;
+
+ case GT_JMPTABLE:
+ genJumpTable(treeNode);
+ break;
+
+ case GT_SWITCH_TABLE:
+ genTableBasedSwitch(treeNode);
+ break;
+
+ case GT_ARR_INDEX:
+ genCodeForArrIndex(treeNode->AsArrIndex());
+ break;
+
+ case GT_ARR_OFFSET:
+ genCodeForArrOffset(treeNode->AsArrOffs());
+ break;
+
case GT_IL_OFFSET:
// Do nothing; these nodes are simply markers for debug info.
break;
@@ -960,7 +1076,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
{
#ifdef DEBUG
char message[256];
- _snprintf_s(message, _countof(message), _TRUNCATE, "NYI: Unimplemented node type %s\n",
+ _snprintf_s(message, _countof(message), _TRUNCATE, "NYI: Unimplemented node type %s",
GenTree::NodeName(treeNode->OperGet()));
NYIRAW(message);
#else
@@ -982,70 +1098,372 @@ void CodeGen::genLockedInstructions(GenTreeOp* treeNode)
NYI("genLockedInstructions");
}
-//------------------------------------------------------------------------
-// genRangeCheck: generate code for GT_ARR_BOUNDS_CHECK node.
+//--------------------------------------------------------------------------------------
+// genLclHeap: Generate code for localloc
+//
+// Description:
+// There are 2 ways depending from build version to generate code for localloc:
+// 1) For debug build where memory should be initialized we generate loop
+// which invoke push {tmpReg} N times.
+// 2) Fore /o build However, we tickle the pages to ensure that SP is always
+// valid and is in sync with the "stack guard page". Amount of iteration
+// is N/PAGE_SIZE.
//
-void CodeGen::genRangeCheck(GenTreePtr oper)
+// Comments:
+// There can be some optimization:
+// 1) It's not needed to generate loop for zero size allocation
+// 2) For small allocation (less than 4 store) we unroll loop
+// 3) For allocation less than PAGE_SIZE and when it's not needed to initialize
+// memory to zero, we can just increment SP.
+//
+// Notes: Size N should be aligned to STACK_ALIGN before any allocation
+//
+void CodeGen::genLclHeap(GenTreePtr tree)
{
- noway_assert(oper->OperGet() == GT_ARR_BOUNDS_CHECK);
- GenTreeBoundsChk* bndsChk = oper->AsBoundsChk();
+ assert(tree->OperGet() == GT_LCLHEAP);
+
+ GenTreePtr size = tree->gtOp.gtOp1;
+ noway_assert((genActualType(size->gtType) == TYP_INT) || (genActualType(size->gtType) == TYP_I_IMPL));
+
+ // Result of localloc will be returned in regCnt.
+ // Also it used as temporary register in code generation
+ // for storing allocation size
+ regNumber regCnt = tree->gtRegNum;
+ regMaskTP tmpRegsMask = tree->gtRsvdRegs;
+ regNumber pspSymReg = REG_NA;
+ var_types type = genActualType(size->gtType);
+ emitAttr easz = emitTypeSize(type);
+ BasicBlock* endLabel = nullptr;
+ BasicBlock* loop = nullptr;
+ unsigned stackAdjustment = 0;
+
+#ifdef DEBUG
+ // Verify ESP
+ if (compiler->opts.compStackCheckOnRet)
+ {
+ noway_assert(compiler->lvaReturnEspCheck != 0xCCCCCCCC &&
+ compiler->lvaTable[compiler->lvaReturnEspCheck].lvDoNotEnregister &&
+ compiler->lvaTable[compiler->lvaReturnEspCheck].lvOnFrame);
+ getEmitter()->emitIns_S_R(INS_cmp, EA_PTRSIZE, REG_SPBASE, compiler->lvaReturnEspCheck, 0);
+
+ BasicBlock* esp_check = genCreateTempLabel();
+ emitJumpKind jmpEqual = genJumpKindForOper(GT_EQ, CK_SIGNED);
+ inst_JMP(jmpEqual, esp_check);
+ getEmitter()->emitIns(INS_BREAKPOINT);
+ genDefineTempLabel(esp_check);
+ }
+#endif
+
+ noway_assert(isFramePointerUsed()); // localloc requires Frame Pointer to be established since SP changes
+ noway_assert(genStackLevel == 0); // Can't have anything on the stack
+
+ // Whether method has PSPSym.
+ bool hasPspSym;
+#if FEATURE_EH_FUNCLETS
+ hasPspSym = (compiler->lvaPSPSym != BAD_VAR_NUM);
+#else
+ hasPspSym = false;
+#endif
+
+ // Check to 0 size allocations
+ // size_t amount = 0;
+ if (size->IsCnsIntOrI())
+ {
+ // If size is a constant, then it must be contained.
+ assert(size->isContained());
- GenTreePtr arrIdx = bndsChk->gtIndex->gtEffectiveVal();
- GenTreePtr arrLen = bndsChk->gtArrLen->gtEffectiveVal();
- GenTreePtr arrRef = NULL;
- int lenOffset = 0;
+ // If amount is zero then return null in regCnt
+ size_t amount = size->gtIntCon.gtIconVal;
+ if (amount == 0)
+ {
+ instGen_Set_Reg_To_Zero(EA_PTRSIZE, regCnt);
+ goto BAILOUT;
+ }
+ }
+ else
+ {
+ // If 0 bail out by returning null in regCnt
+ genConsumeRegAndCopy(size, regCnt);
+ endLabel = genCreateTempLabel();
+ getEmitter()->emitIns_R_R(INS_TEST, easz, regCnt, regCnt);
+ emitJumpKind jmpEqual = genJumpKindForOper(GT_EQ, CK_SIGNED);
+ inst_JMP(jmpEqual, endLabel);
+ }
- genConsumeIfReg(arrIdx);
- genConsumeIfReg(arrLen);
+ stackAdjustment = 0;
+#if FEATURE_EH_FUNCLETS
+ // If we have PSPsym, then need to re-locate it after localloc.
+ if (hasPspSym)
+ {
+ stackAdjustment += STACK_ALIGN;
+
+ // Save a copy of PSPSym
+ assert(genCountBits(tmpRegsMask) >= 1);
+ regMaskTP pspSymRegMask = genFindLowestBit(tmpRegsMask);
+ tmpRegsMask &= ~pspSymRegMask;
+ pspSymReg = genRegNumFromMask(pspSymRegMask);
+ getEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, pspSymReg, compiler->lvaPSPSym, 0);
+ }
+#endif
- GenTree * src1, *src2;
- emitJumpKind jmpKind;
+#if FEATURE_FIXED_OUT_ARGS
+ // If we have an outgoing arg area then we must adjust the SP by popping off the
+ // outgoing arg area. We will restore it right before we return from this method.
+ if (compiler->lvaOutgoingArgSpaceSize > 0)
+ {
+ assert((compiler->lvaOutgoingArgSpaceSize % STACK_ALIGN) == 0); // This must be true for the stack to remain
+ // aligned
+ inst_RV_IV(INS_add, REG_SPBASE, compiler->lvaOutgoingArgSpaceSize, EA_PTRSIZE);
+ stackAdjustment += compiler->lvaOutgoingArgSpaceSize;
+ }
+#endif
- if (arrIdx->isContainedIntOrIImmed())
+ // Put aligned allocation size to regCnt
+ if (size->IsCnsIntOrI())
{
- // To encode using a cmp immediate, we place the
- // constant operand in the second position
- src1 = arrLen;
- src2 = arrIdx;
- jmpKind = genJumpKindForOper(GT_LE, CK_UNSIGNED);
+ // 'amount' is the total number of bytes to localloc to properly STACK_ALIGN
+ size_t amount = size->gtIntCon.gtIconVal;
+ amount = AlignUp(amount, STACK_ALIGN);
+
+ // For small allocations we will generate up to four stp instructions
+ size_t cntStackAlignedWidthItems = (amount >> STACK_ALIGN_SHIFT);
+ if (cntStackAlignedWidthItems <= 4)
+ {
+ instGen_Set_Reg_To_Zero(EA_PTRSIZE, regCnt);
+
+ while (cntStackAlignedWidthItems != 0)
+ {
+ inst_IV(INS_push, (unsigned)genRegMask(regCnt));
+ cntStackAlignedWidthItems -= 1;
+ }
+
+ goto ALLOC_DONE;
+ }
+ else if (!compiler->info.compInitMem && (amount < compiler->eeGetPageSize())) // must be < not <=
+ {
+ // Since the size is a page or less, simply adjust the SP value
+ // The SP might already be in the guard page, must touch it BEFORE
+ // the alloc, not after.
+ getEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, regCnt, REG_SP, 0);
+ inst_RV_IV(INS_sub, REG_SP, amount, EA_PTRSIZE);
+ goto ALLOC_DONE;
+ }
+
+ // regCnt will be the total number of bytes to locAlloc
+ genSetRegToIcon(regCnt, amount, ((int)amount == amount) ? TYP_INT : TYP_LONG);
}
else
{
- src1 = arrIdx;
- src2 = arrLen;
- jmpKind = genJumpKindForOper(GT_GE, CK_UNSIGNED);
+ // Round up the number of bytes to allocate to a STACK_ALIGN boundary.
+ inst_RV_IV(INS_add, regCnt, (STACK_ALIGN - 1), emitActualTypeSize(type));
+ inst_RV_IV(INS_AND, regCnt, ~(STACK_ALIGN - 1), emitActualTypeSize(type));
+ }
+
+ // Allocation
+ if (compiler->info.compInitMem)
+ {
+ // At this point 'regCnt' is set to the total number of bytes to locAlloc.
+ // Since we have to zero out the allocated memory AND ensure that RSP is always valid
+ // by tickling the pages, we will just push 0's on the stack.
+
+ assert(tmpRegsMask != RBM_NONE);
+ assert(genCountBits(tmpRegsMask) >= 1);
+
+ regMaskTP regCntMask = genFindLowestBit(tmpRegsMask);
+ tmpRegsMask &= ~regCntMask;
+ regNumber regTmp = genRegNumFromMask(regCntMask);
+ instGen_Set_Reg_To_Zero(EA_PTRSIZE, regTmp);
+
+ // Loop:
+ BasicBlock* loop = genCreateTempLabel();
+ genDefineTempLabel(loop);
+
+ noway_assert(STACK_ALIGN == 8);
+ inst_IV(INS_push, (unsigned)genRegMask(regTmp));
+ inst_IV(INS_push, (unsigned)genRegMask(regTmp));
+
+ // If not done, loop
+ // Note that regCnt is the number of bytes to stack allocate.
+ assert(genIsValidIntReg(regCnt));
+ getEmitter()->emitIns_R_R_I(INS_sub, EA_PTRSIZE, regCnt, regCnt, STACK_ALIGN);
+ emitJumpKind jmpNotEqual = genJumpKindForOper(GT_NE, CK_SIGNED);
+ inst_JMP(jmpNotEqual, loop);
+ }
+ else
+ {
+ // At this point 'regCnt' is set to the total number of bytes to locAlloc.
+ //
+ // We don't need to zero out the allocated memory. However, we do have
+ // to tickle the pages to ensure that SP is always valid and is
+ // in sync with the "stack guard page". Note that in the worst
+ // case SP is on the last byte of the guard page. Thus you must
+ // touch SP+0 first not SP+0x1000.
+ //
+ // Another subtlety is that you don't want SP to be exactly on the
+ // boundary of the guard page because PUSH is predecrement, thus
+ // call setup would not touch the guard page but just beyond it
+ //
+ // Note that we go through a few hoops so that SP never points to
+ // illegal pages at any time during the ticking process
+ //
+ // subs regCnt, SP, regCnt // regCnt now holds ultimate SP
+ // jb Loop // result is smaller than orignial SP (no wrap around)
+ // mov regCnt, #0 // Overflow, pick lowest possible value
+ //
+ // Loop:
+ // ldr regTmp, [SP + 0] // tickle the page - read from the page
+ // sub regTmp, SP, PAGE_SIZE // decrement SP by PAGE_SIZE
+ // cmp regTmp, regCnt
+ // jb Done
+ // mov SP, regTmp
+ // j Loop
+ //
+ // Done:
+ // mov SP, regCnt
+ //
+
+ // Setup the regTmp
+ assert(tmpRegsMask != RBM_NONE);
+ assert(genCountBits(tmpRegsMask) == 1);
+ regNumber regTmp = genRegNumFromMask(tmpRegsMask);
+
+ BasicBlock* loop = genCreateTempLabel();
+ BasicBlock* done = genCreateTempLabel();
+
+ // subs regCnt, SP, regCnt // regCnt now holds ultimate SP
+ getEmitter()->emitIns_R_R_R(INS_sub, EA_PTRSIZE, regCnt, REG_SPBASE, regCnt);
+
+ inst_JMP(EJ_vc, loop); // branch if the V flag is not set
+
+ // Ups... Overflow, set regCnt to lowest possible value
+ instGen_Set_Reg_To_Zero(EA_PTRSIZE, regCnt);
+
+ genDefineTempLabel(loop);
+
+ // tickle the page - Read from the updated SP - this triggers a page fault when on the guard page
+ getEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, regTmp, REG_SPBASE, 0);
+
+ // decrement SP by PAGE_SIZE
+ getEmitter()->emitIns_R_R_I(INS_sub, EA_PTRSIZE, regTmp, REG_SPBASE, compiler->eeGetPageSize());
+
+ getEmitter()->emitIns_R_R(INS_cmp, EA_PTRSIZE, regTmp, regCnt);
+ emitJumpKind jmpLTU = genJumpKindForOper(GT_LT, CK_UNSIGNED);
+ inst_JMP(jmpLTU, done);
+
+ // Update SP to be at the next page of stack that we will tickle
+ getEmitter()->emitIns_R_R(INS_mov, EA_PTRSIZE, REG_SPBASE, regCnt);
+
+ // Jump to loop and tickle new stack address
+ inst_JMP(EJ_jmp, loop);
+
+ // Done with stack tickle loop
+ genDefineTempLabel(done);
+
+ // Now just move the final value to SP
+ getEmitter()->emitIns_R_R(INS_mov, EA_PTRSIZE, REG_SPBASE, regCnt);
+ }
+
+ALLOC_DONE:
+ // Re-adjust SP to allocate PSPSym and out-going arg area
+ if (stackAdjustment != 0)
+ {
+ assert((stackAdjustment % STACK_ALIGN) == 0); // This must be true for the stack to remain aligned
+ assert(stackAdjustment > 0);
+ getEmitter()->emitIns_R_R_I(INS_sub, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, (int)stackAdjustment);
+
+#if FEATURE_EH_FUNCLETS
+ // Write PSPSym to its new location.
+ if (hasPspSym)
+ {
+ assert(genIsValidIntReg(pspSymReg));
+ getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, pspSymReg, compiler->lvaPSPSym, 0);
+ }
+#endif
+ // Return the stackalloc'ed address in result register.
+ // regCnt = RSP + stackAdjustment.
+ getEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, regCnt, REG_SPBASE, (int)stackAdjustment);
+ }
+ else // stackAdjustment == 0
+ {
+ // Move the final value of SP to regCnt
+ inst_RV_RV(INS_mov, regCnt, REG_SPBASE);
+ }
+
+BAILOUT:
+ if (endLabel != nullptr)
+ genDefineTempLabel(endLabel);
+
+ // Write the lvaLocAllocSPvar stack frame slot
+ if (compiler->lvaLocAllocSPvar != BAD_VAR_NUM)
+ {
+ getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, regCnt, compiler->lvaLocAllocSPvar, 0);
+ }
+
+#if STACK_PROBES
+ if (compiler->opts.compNeedStackProbes)
+ {
+ genGenerateStackProbe();
+ }
+#endif
+
+#ifdef DEBUG
+ // Update new ESP
+ if (compiler->opts.compStackCheckOnRet)
+ {
+ noway_assert(compiler->lvaReturnEspCheck != 0xCCCCCCCC &&
+ compiler->lvaTable[compiler->lvaReturnEspCheck].lvDoNotEnregister &&
+ compiler->lvaTable[compiler->lvaReturnEspCheck].lvOnFrame);
+ getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, regCnt, compiler->lvaReturnEspCheck, 0);
}
+#endif
- getEmitter()->emitInsBinary(INS_cmp, emitAttr(TYP_INT), src1, src2);
- genJumpToThrowHlpBlk(jmpKind, SCK_RNGCHK_FAIL, bndsChk->gtIndRngFailBB);
+ genProduceReg(tree);
}
//------------------------------------------------------------------------
-// indirForm: Make a temporary indir we can feed to pattern matching routines
-// in cases where we don't want to instantiate all the indirs that happen.
+// genTableBasedSwitch: generate code for a switch statement based on a table of ip-relative offsets
//
-GenTreeIndir CodeGen::indirForm(var_types type, GenTree* base)
+void CodeGen::genTableBasedSwitch(GenTree* treeNode)
{
- GenTreeIndir i(GT_IND, type, base, nullptr);
- i.gtRegNum = REG_NA;
- // has to be nonnull (because contained nodes can't be the last in block)
- // but don't want it to be a valid pointer
- i.gtNext = (GenTree*)(-1);
- return i;
+ genConsumeOperands(treeNode->AsOp());
+ regNumber idxReg = treeNode->gtOp.gtOp1->gtRegNum;
+ regNumber baseReg = treeNode->gtOp.gtOp2->gtRegNum;
+
+ getEmitter()->emitIns_R_ARX(INS_ldr, EA_4BYTE, REG_PC, baseReg, idxReg, TARGET_POINTER_SIZE, 0);
}
//------------------------------------------------------------------------
-// intForm: Make a temporary int we can feed to pattern matching routines
-// in cases where we don't want to instantiate.
+// genJumpTable: emits the table and an instruction to get the address of the first element
//
-GenTreeIntCon CodeGen::intForm(var_types type, ssize_t value)
+void CodeGen::genJumpTable(GenTree* treeNode)
{
- GenTreeIntCon i(type, value);
- i.gtRegNum = REG_NA;
- // has to be nonnull (because contained nodes can't be the last in block)
- // but don't want it to be a valid pointer
- i.gtNext = (GenTree*)(-1);
- return i;
+ noway_assert(compiler->compCurBB->bbJumpKind == BBJ_SWITCH);
+ assert(treeNode->OperGet() == GT_JMPTABLE);
+
+ unsigned jumpCount = compiler->compCurBB->bbJumpSwt->bbsCount;
+ BasicBlock** jumpTable = compiler->compCurBB->bbJumpSwt->bbsDstTab;
+ unsigned jmpTabBase;
+
+ jmpTabBase = getEmitter()->emitBBTableDataGenBeg(jumpCount, false);
+
+ JITDUMP("\n J_M%03u_DS%02u LABEL DWORD\n", Compiler::s_compMethodsCount, jmpTabBase);
+
+ for (unsigned i = 0; i < jumpCount; i++)
+ {
+ BasicBlock* target = *jumpTable++;
+ noway_assert(target->bbFlags & BBF_JMP_TARGET);
+
+ JITDUMP(" DD L_M%03u_BB%02u\n", Compiler::s_compMethodsCount, target->bbNum);
+
+ getEmitter()->emitDataGenData(i, target);
+ }
+
+ getEmitter()->emitDataGenEnd();
+
+ getEmitter()->emitIns_R_D(INS_movw, EA_HANDLE_CNS_RELOC, jmpTabBase, treeNode->gtRegNum);
+ getEmitter()->emitIns_R_D(INS_movt, EA_HANDLE_CNS_RELOC, jmpTabBase, treeNode->gtRegNum);
+
+ genProduceReg(treeNode);
}
//------------------------------------------------------------------------
@@ -1096,6 +1514,27 @@ instruction CodeGen::genGetInsForOper(genTreeOps oper, var_types type)
case GT_XOR:
ins = INS_XOR;
break;
+ case GT_ROR:
+ ins = INS_ror;
+ break;
+ case GT_ADD_LO:
+ ins = INS_add;
+ break;
+ case GT_ADD_HI:
+ ins = INS_adc;
+ break;
+ case GT_SUB_LO:
+ ins = INS_sub;
+ break;
+ case GT_SUB_HI:
+ ins = INS_sbc;
+ break;
+ case GT_LSH_HI:
+ ins = INS_SHIFT_LEFT_LOGICAL;
+ break;
+ case GT_RSH_LO:
+ ins = INS_SHIFT_RIGHT_LOGICAL;
+ break;
default:
unreached();
break;
@@ -1103,357 +1542,303 @@ instruction CodeGen::genGetInsForOper(genTreeOps oper, var_types type)
return ins;
}
-//------------------------------------------------------------------------
-// genCodeForShift: Generates the code sequence for a GenTree node that
-// represents a bit shift or rotate operation (<<, >>, >>>, rol, ror).
-//
-// Arguments:
-// tree - the bit shift node (that specifies the type of bit shift to perform).
-//
-// Assumptions:
-// a) All GenTrees are register allocated.
-//
-void CodeGen::genCodeForShift(GenTreePtr tree)
+// Generates CpBlk code by performing a loop unroll
+// Preconditions:
+// The size argument of the CpBlk node is a constant and <= 64 bytes.
+// This may seem small but covers >95% of the cases in several framework assemblies.
+void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode)
{
- var_types targetType = tree->TypeGet();
- genTreeOps oper = tree->OperGet();
- instruction ins = genGetInsForOper(oper, targetType);
- emitAttr size = emitTypeSize(tree);
+ NYI_ARM("genCodeForCpBlkUnroll");
+}
- assert(tree->gtRegNum != REG_NA);
+// Generate code for InitBlk by performing a loop unroll
+// Preconditions:
+// a) Both the size and fill byte value are integer constants.
+// b) The size of the struct to initialize is smaller than INITBLK_UNROLL_LIMIT bytes.
+void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* initBlkNode)
+{
+ NYI_ARM("genCodeForInitBlkUnroll");
+}
- GenTreePtr operand = tree->gtGetOp1();
- genConsumeReg(operand);
+void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp)
+{
+ if (blkOp->gtBlkOpGcUnsafe)
+ {
+ getEmitter()->emitDisableGC();
+ }
+ bool isCopyBlk = blkOp->OperIsCopyBlkOp();
- GenTreePtr shiftBy = tree->gtGetOp2();
- if (!shiftBy->IsCnsIntOrI())
+ switch (blkOp->gtBlkOpKind)
{
- genConsumeReg(shiftBy);
- getEmitter()->emitIns_R_R_R(ins, size, tree->gtRegNum, operand->gtRegNum, shiftBy->gtRegNum);
+ case GenTreeBlk::BlkOpKindHelper:
+ if (isCopyBlk)
+ {
+ genCodeForCpBlk(blkOp);
+ }
+ else
+ {
+ genCodeForInitBlk(blkOp);
+ }
+ break;
+ case GenTreeBlk::BlkOpKindUnroll:
+ if (isCopyBlk)
+ {
+ genCodeForCpBlkUnroll(blkOp);
+ }
+ else
+ {
+ genCodeForInitBlkUnroll(blkOp);
+ }
+ break;
+ default:
+ unreached();
}
- else
+ if (blkOp->gtBlkOpGcUnsafe)
{
- unsigned immWidth = size * BITS_PER_BYTE;
- ssize_t shiftByImm = shiftBy->gtIntCon.gtIconVal & (immWidth - 1);
-
- getEmitter()->emitIns_R_R_I(ins, size, tree->gtRegNum, operand->gtRegNum, shiftByImm);
+ getEmitter()->emitEnableGC();
}
-
- genProduceReg(tree);
}
//------------------------------------------------------------------------
-// genRegCopy: Generate a register copy.
+// genCodeForShiftLong: Generates the code sequence for a GenTree node that
+// represents a three operand bit shift or rotate operation (<<Hi, >>Lo).
//
-void CodeGen::genRegCopy(GenTree* treeNode)
-{
- NYI("genRegCopy");
-}
-
-//------------------------------------------------------------------------
-// genCallInstruction: Produce code for a GT_CALL node
+// Arguments:
+// tree - the bit shift node (that specifies the type of bit shift to perform).
+//
+// Assumptions:
+// a) All GenTrees are register allocated.
+// b) The shift-by-amount in tree->gtOp.gtOp2 is a contained constant
//
-void CodeGen::genCallInstruction(GenTreePtr node)
+void CodeGen::genCodeForShiftLong(GenTreePtr tree)
{
- GenTreeCall* call = node->AsCall();
-
- assert(call->gtOper == GT_CALL);
-
- gtCallTypes callType = (gtCallTypes)call->gtCallType;
+ // Only the non-RMW case here.
+ genTreeOps oper = tree->OperGet();
+ assert(oper == GT_LSH_HI || oper == GT_RSH_LO);
- IL_OFFSETX ilOffset = BAD_IL_OFFSET;
+ GenTree* operand = tree->gtOp.gtOp1;
+ assert(operand->OperGet() == GT_LONG);
+ assert(operand->gtOp.gtOp1->isUsedFromReg());
+ assert(operand->gtOp.gtOp2->isUsedFromReg());
- // all virtuals should have been expanded into a control expression
- assert(!call->IsVirtual() || call->gtControlExpr || call->gtCallAddr);
-
- // Consume all the arg regs
- for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext())
- {
- assert(list->OperIsList());
+ GenTree* operandLo = operand->gtGetOp1();
+ GenTree* operandHi = operand->gtGetOp2();
- GenTreePtr argNode = list->Current();
+ regNumber regLo = operandLo->gtRegNum;
+ regNumber regHi = operandHi->gtRegNum;
- fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, argNode->gtSkipReloadOrCopy());
- assert(curArgTabEntry);
+ genConsumeOperands(tree->AsOp());
- if (curArgTabEntry->regNum == REG_STK)
- continue;
-
- // Deal with multi register passed struct args.
- if (argNode->OperGet() == GT_FIELD_LIST)
- {
- GenTreeArgList* argListPtr = argNode->AsArgList();
- unsigned iterationNum = 0;
- regNumber argReg = curArgTabEntry->regNum;
- for (; argListPtr != nullptr; argListPtr = argListPtr->Rest(), iterationNum++)
- {
- GenTreePtr putArgRegNode = argListPtr->gtOp.gtOp1;
- assert(putArgRegNode->gtOper == GT_PUTARG_REG);
+ var_types targetType = tree->TypeGet();
+ instruction ins = genGetInsForOper(oper, targetType);
- genConsumeReg(putArgRegNode);
+ GenTreePtr shiftBy = tree->gtGetOp2();
- if (putArgRegNode->gtRegNum != argReg)
- {
- inst_RV_RV(ins_Move_Extend(putArgRegNode->TypeGet(), putArgRegNode->InReg()), argReg,
- putArgRegNode->gtRegNum);
- }
+ assert(shiftBy->isContainedIntOrIImmed());
- argReg = genRegArgNext(argReg);
- }
- }
- else
- {
- regNumber argReg = curArgTabEntry->regNum;
- genConsumeReg(argNode);
- if (argNode->gtRegNum != argReg)
- {
- inst_RV_RV(ins_Move_Extend(argNode->TypeGet(), argNode->InReg()), argReg, argNode->gtRegNum);
- }
- }
+ unsigned int count = shiftBy->AsIntConCommon()->IconValue();
- // In the case of a varargs call,
- // the ABI dictates that if we have floating point args,
- // we must pass the enregistered arguments in both the
- // integer and floating point registers so, let's do that.
- if (call->IsVarargs() && varTypeIsFloating(argNode))
- {
- NYI_ARM("CodeGen - IsVarargs");
- }
- }
+ regNumber regResult = (oper == GT_LSH_HI) ? regHi : regLo;
- // Insert a null check on "this" pointer if asked.
- if (call->NeedsNullCheck())
+ if (regResult != tree->gtRegNum)
{
- const regNumber regThis = genGetThisArgReg(call);
- const regNumber tmpReg = genRegNumFromMask(node->gtRsvdRegs);
- getEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, tmpReg, regThis, 0);
+ inst_RV_RV(INS_mov, tree->gtRegNum, regResult, targetType);
}
- // Either gtControlExpr != null or gtCallAddr != null or it is a direct non-virtual call to a user or helper method.
- CORINFO_METHOD_HANDLE methHnd;
- GenTree* target = call->gtControlExpr;
- if (callType == CT_INDIRECT)
+ if (oper == GT_LSH_HI)
{
- assert(target == nullptr);
- target = call->gtCall.gtCallAddr;
- methHnd = nullptr;
+ inst_RV_SH(ins, EA_4BYTE, tree->gtRegNum, count);
+ getEmitter()->emitIns_R_R_R_I(INS_OR, EA_4BYTE, tree->gtRegNum, tree->gtRegNum, regLo, 32 - count,
+ INS_FLAGS_DONT_CARE, INS_OPTS_LSR);
}
else
{
- methHnd = call->gtCallMethHnd;
+ assert(oper == GT_RSH_LO);
+ inst_RV_SH(INS_SHIFT_RIGHT_LOGICAL, EA_4BYTE, tree->gtRegNum, count);
+ getEmitter()->emitIns_R_R_R_I(INS_OR, EA_4BYTE, tree->gtRegNum, tree->gtRegNum, regHi, 32 - count,
+ INS_FLAGS_DONT_CARE, INS_OPTS_LSL);
}
- CORINFO_SIG_INFO* sigInfo = nullptr;
-#ifdef DEBUG
- // Pass the call signature information down into the emitter so the emitter can associate
- // native call sites with the signatures they were generated from.
- if (callType != CT_HELPER)
+ genProduceReg(tree);
+}
+
+//------------------------------------------------------------------------
+// genLeaInstruction: Produce code for a GT_LEA subnode.
+//
+void CodeGen::genLeaInstruction(GenTreeAddrMode* lea)
+{
+ emitAttr size = emitTypeSize(lea);
+ genConsumeOperands(lea);
+
+ if (lea->Base() && lea->Index())
{
- sigInfo = call->callSig;
+ regNumber baseReg = lea->Base()->gtRegNum;
+ regNumber indexReg = lea->Index()->gtRegNum;
+ getEmitter()->emitIns_R_ARX(INS_lea, size, lea->gtRegNum, baseReg, indexReg, lea->gtScale, lea->gtOffset);
}
-#endif // DEBUG
-
- // If fast tail call, then we are done.
- if (call->IsFastTailCall())
+ else if (lea->Base())
{
- NYI_ARM("fast tail call");
+ regNumber baseReg = lea->Base()->gtRegNum;
+ getEmitter()->emitIns_R_AR(INS_lea, size, lea->gtRegNum, baseReg, lea->gtOffset);
}
-
- // For a pinvoke to unmanaged code we emit a label to clear
- // the GC pointer state before the callsite.
- // We can't utilize the typical lazy killing of GC pointers
- // at (or inside) the callsite.
- if (call->IsUnmanaged())
+ else if (lea->Index())
{
- genDefineTempLabel(genCreateTempLabel());
+ assert(!"Should we see a baseless address computation during CodeGen for ARM32?");
}
- // Determine return value size(s).
- ReturnTypeDesc* pRetTypeDesc = call->GetReturnTypeDesc();
- emitAttr retSize = EA_PTRSIZE;
+ genProduceReg(lea);
+}
- if (call->HasMultiRegRetVal())
- {
- NYI_ARM("has multi reg ret val");
- }
- else
- {
- assert(!varTypeIsStruct(call));
+//------------------------------------------------------------------------
+// genCompareLong: Generate code for comparing two longs when the result of the compare
+// is manifested in a register.
+//
+// Arguments:
+// treeNode - the compare tree
+//
+// Return Value:
+// None.
+//
+// Comments:
+// For long compares, we need to compare the high parts of operands first, then the low parts.
+// If the high compare is false, we do not need to compare the low parts. For less than and
+// greater than, if the high compare is true, we can assume the entire compare is true.
+//
+void CodeGen::genCompareLong(GenTreePtr treeNode)
+{
+ assert(treeNode->OperIsCompare());
- if (call->gtType == TYP_REF || call->gtType == TYP_ARRAY)
- {
- retSize = EA_GCREF;
- }
- else if (call->gtType == TYP_BYREF)
- {
- retSize = EA_BYREF;
- }
- }
+ GenTreeOp* tree = treeNode->AsOp();
+ GenTreePtr op1 = tree->gtOp1;
+ GenTreePtr op2 = tree->gtOp2;
- // We need to propagate the IL offset information to the call instruction, so we can emit
- // an IL to native mapping record for the call, to support managed return value debugging.
- // We don't want tail call helper calls that were converted from normal calls to get a record,
- // so we skip this hash table lookup logic in that case.
- if (compiler->opts.compDbgInfo && compiler->genCallSite2ILOffsetMap != nullptr && !call->IsTailCall())
- {
- (void)compiler->genCallSite2ILOffsetMap->Lookup(call, &ilOffset);
- }
+ assert(varTypeIsLong(op1->TypeGet()));
+ assert(varTypeIsLong(op2->TypeGet()));
- if (target != nullptr)
- {
- // For ARM a call target can not be a contained indirection
- assert(!target->isContainedIndir());
+ regNumber targetReg = treeNode->gtRegNum;
- // We have already generated code for gtControlExpr evaluating it into a register.
- // We just need to emit "call reg" in this case.
- //
- assert(genIsValidIntReg(target->gtRegNum));
+ genConsumeOperands(tree);
- genEmitCall(emitter::EC_INDIR_R, methHnd,
- INDEBUG_LDISASM_COMMA(sigInfo) nullptr, // addr
- retSize, ilOffset, target->gtRegNum);
- }
- else
- {
- // Generate a direct call to a non-virtual user defined or helper method
- assert(callType == CT_HELPER || callType == CT_USER_FUNC);
+ GenTreePtr loOp1 = op1->gtGetOp1();
+ GenTreePtr hiOp1 = op1->gtGetOp2();
+ GenTreePtr loOp2 = op2->gtGetOp1();
+ GenTreePtr hiOp2 = op2->gtGetOp2();
- void* addr = nullptr;
- if (callType == CT_HELPER)
- {
- // Direct call to a helper method.
- CorInfoHelpFunc helperNum = compiler->eeGetHelperNum(methHnd);
- noway_assert(helperNum != CORINFO_HELP_UNDEF);
+ // Create compare for the high parts
+ instruction ins = INS_cmp;
+ var_types cmpType = TYP_INT;
+ emitAttr cmpAttr = emitTypeSize(cmpType);
- void* pAddr = nullptr;
- addr = compiler->compGetHelperFtn(helperNum, (void**)&pAddr);
+ // Emit the compare instruction
+ getEmitter()->emitInsBinary(ins, cmpAttr, hiOp1, hiOp2);
- if (addr == nullptr)
- {
- addr = pAddr;
- }
- }
- else
- {
- // Direct call to a non-virtual user function.
- CORINFO_ACCESS_FLAGS aflags = CORINFO_ACCESS_ANY;
- if (call->IsSameThis())
- {
- aflags = (CORINFO_ACCESS_FLAGS)(aflags | CORINFO_ACCESS_THIS);
- }
+ // If the result is not being materialized in a register, we're done.
+ if (targetReg == REG_NA)
+ {
+ return;
+ }
- if ((call->NeedsNullCheck()) == 0)
- {
- aflags = (CORINFO_ACCESS_FLAGS)(aflags | CORINFO_ACCESS_NONNULL);
- }
+ BasicBlock* labelTrue = genCreateTempLabel();
+ BasicBlock* labelFalse = genCreateTempLabel();
+ BasicBlock* labelNext = genCreateTempLabel();
- CORINFO_CONST_LOOKUP addrInfo;
- compiler->info.compCompHnd->getFunctionEntryPoint(methHnd, &addrInfo, aflags);
+ genJccLongHi(tree->gtOper, labelTrue, labelFalse, tree->IsUnsigned());
+ getEmitter()->emitInsBinary(ins, cmpAttr, loOp1, loOp2);
+ genJccLongLo(tree->gtOper, labelTrue, labelFalse);
- addr = addrInfo.addr;
- }
+ genDefineTempLabel(labelFalse);
+ getEmitter()->emitIns_R_I(INS_mov, emitActualTypeSize(tree->gtType), tree->gtRegNum, 0);
+ getEmitter()->emitIns_J(INS_b, labelNext);
- assert(addr);
- // Non-virtual direct call to known addresses
- if (!arm_Valid_Imm_For_BL((ssize_t)addr))
- {
- regNumber tmpReg = genRegNumFromMask(node->gtRsvdRegs);
- instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, tmpReg, (ssize_t)addr);
- genEmitCall(emitter::EC_INDIR_R, methHnd, INDEBUG_LDISASM_COMMA(sigInfo) NULL, retSize, ilOffset, tmpReg);
- }
- else
- {
- genEmitCall(emitter::EC_FUNC_TOKEN, methHnd, INDEBUG_LDISASM_COMMA(sigInfo) addr, retSize, ilOffset);
- }
- }
+ genDefineTempLabel(labelTrue);
+ getEmitter()->emitIns_R_I(INS_mov, emitActualTypeSize(tree->gtType), tree->gtRegNum, 1);
+
+ genDefineTempLabel(labelNext);
- // if it was a pinvoke we may have needed to get the address of a label
- if (genPendingCallLabel)
+ genProduceReg(tree);
+}
+
+void CodeGen::genJccLongHi(genTreeOps cmp, BasicBlock* jumpTrue, BasicBlock* jumpFalse, bool isUnsigned)
+{
+ if (cmp != GT_NE)
{
- assert(call->IsUnmanaged());
- genDefineTempLabel(genPendingCallLabel);
- genPendingCallLabel = nullptr;
+ jumpFalse->bbFlags |= BBF_JMP_TARGET | BBF_HAS_LABEL;
}
- // Update GC info:
- // All Callee arg registers are trashed and no longer contain any GC pointers.
- // TODO-ARM-Bug?: As a matter of fact shouldn't we be killing all of callee trashed regs here?
- // For now we will assert that other than arg regs gc ref/byref set doesn't contain any other
- // registers from RBM_CALLEE_TRASH
- assert((gcInfo.gcRegGCrefSetCur & (RBM_CALLEE_TRASH & ~RBM_ARG_REGS)) == 0);
- assert((gcInfo.gcRegByrefSetCur & (RBM_CALLEE_TRASH & ~RBM_ARG_REGS)) == 0);
- gcInfo.gcRegGCrefSetCur &= ~RBM_ARG_REGS;
- gcInfo.gcRegByrefSetCur &= ~RBM_ARG_REGS;
-
- var_types returnType = call->TypeGet();
- if (returnType != TYP_VOID)
+ switch (cmp)
{
- regNumber returnReg;
+ case GT_EQ:
+ inst_JMP(EJ_ne, jumpFalse);
+ break;
- if (call->HasMultiRegRetVal())
- {
- assert(pRetTypeDesc != nullptr);
- unsigned regCount = pRetTypeDesc->GetReturnRegCount();
+ case GT_NE:
+ inst_JMP(EJ_ne, jumpTrue);
+ break;
- // If regs allocated to call node are different from ABI return
- // regs in which the call has returned its result, move the result
- // to regs allocated to call node.
- for (unsigned i = 0; i < regCount; ++i)
- {
- var_types regType = pRetTypeDesc->GetReturnRegType(i);
- returnReg = pRetTypeDesc->GetABIReturnReg(i);
- regNumber allocatedReg = call->GetRegNumByIdx(i);
- if (returnReg != allocatedReg)
- {
- inst_RV_RV(ins_Copy(regType), allocatedReg, returnReg, regType);
- }
- }
- }
- else
- {
- if (varTypeIsFloating(returnType))
+ case GT_LT:
+ case GT_LE:
+ if (isUnsigned)
{
- returnReg = REG_FLOATRET;
+ inst_JMP(EJ_hi, jumpFalse);
+ inst_JMP(EJ_lo, jumpTrue);
}
else
{
- returnReg = REG_INTRET;
+ inst_JMP(EJ_gt, jumpFalse);
+ inst_JMP(EJ_lt, jumpTrue);
}
+ break;
- if (call->gtRegNum != returnReg)
+ case GT_GE:
+ case GT_GT:
+ if (isUnsigned)
{
- inst_RV_RV(ins_Copy(returnType), call->gtRegNum, returnReg, returnType);
+ inst_JMP(EJ_lo, jumpFalse);
+ inst_JMP(EJ_hi, jumpTrue);
}
- }
-
- genProduceReg(call);
- }
+ else
+ {
+ inst_JMP(EJ_lt, jumpFalse);
+ inst_JMP(EJ_gt, jumpTrue);
+ }
+ break;
- // If there is nothing next, that means the result is thrown away, so this value is not live.
- // However, for minopts or debuggable code, we keep it live to support managed return value debugging.
- if ((call->gtNext == nullptr) && !compiler->opts.MinOpts() && !compiler->opts.compDbgCode)
- {
- gcInfo.gcMarkRegSetNpt(RBM_INTRET);
+ default:
+ noway_assert(!"expected a comparison operator");
}
}
-//------------------------------------------------------------------------
-// genLeaInstruction: Produce code for a GT_LEA subnode.
-//
-void CodeGen::genLeaInstruction(GenTreeAddrMode* lea)
+void CodeGen::genJccLongLo(genTreeOps cmp, BasicBlock* jumpTrue, BasicBlock* jumpFalse)
{
- if (lea->Base() && lea->Index())
+ switch (cmp)
{
- regNumber baseReg = genConsumeReg(lea->Base());
- regNumber indexReg = genConsumeReg(lea->Index());
- getEmitter()->emitIns_R_ARX(INS_lea, EA_BYREF, lea->gtRegNum, baseReg, indexReg, lea->gtScale, lea->gtOffset);
- }
- else if (lea->Base())
- {
- getEmitter()->emitIns_R_AR(INS_lea, EA_BYREF, lea->gtRegNum, genConsumeReg(lea->Base()), lea->gtOffset);
- }
+ case GT_EQ:
+ inst_JMP(EJ_eq, jumpTrue);
+ break;
- genProduceReg(lea);
+ case GT_NE:
+ inst_JMP(EJ_ne, jumpTrue);
+ break;
+
+ case GT_LT:
+ inst_JMP(EJ_lo, jumpTrue);
+ break;
+
+ case GT_LE:
+ inst_JMP(EJ_ls, jumpTrue);
+ break;
+
+ case GT_GE:
+ inst_JMP(EJ_hs, jumpTrue);
+ break;
+
+ case GT_GT:
+ inst_JMP(EJ_hi, jumpTrue);
+ break;
+
+ default:
+ noway_assert(!"expected comparison");
+ }
}
//------------------------------------------------------------------------
@@ -1497,151 +1882,92 @@ void CodeGen::genSetRegToCond(regNumber dstReg, GenTreePtr tree)
}
//------------------------------------------------------------------------
-// genIntToIntCast: Generate code for an integer cast
+// genLongToIntCast: Generate code for long to int casts.
//
// Arguments:
-// treeNode - The GT_CAST node
+// cast - The GT_CAST node
//
// Return Value:
// None.
//
// Assumptions:
-// The treeNode must have an assigned register.
-// For a signed convert from byte, the source must be in a byte-addressable register.
-// Neither the source nor target type can be a floating point type.
+// The cast node and its sources (via GT_LONG) must have been assigned registers.
+// The destination cannot be a floating point type or a small integer type.
//
-void CodeGen::genIntToIntCast(GenTreePtr treeNode)
+void CodeGen::genLongToIntCast(GenTree* cast)
{
- assert(treeNode->OperGet() == GT_CAST);
-
- GenTreePtr castOp = treeNode->gtCast.CastOp();
- emitter* emit = getEmitter();
+ assert(cast->OperGet() == GT_CAST);
- var_types dstType = treeNode->CastToType();
- var_types srcType = genActualType(castOp->TypeGet());
- emitAttr movSize = emitActualTypeSize(dstType);
- bool movRequired = false;
-
- regNumber targetReg = treeNode->gtRegNum;
- regNumber sourceReg = castOp->gtRegNum;
+ GenTree* src = cast->gtGetOp1();
+ noway_assert(src->OperGet() == GT_LONG);
- // For Long to Int conversion we will have a reserved integer register to hold the immediate mask
- regNumber tmpReg = (treeNode->gtRsvdRegs == RBM_NONE) ? REG_NA : genRegNumFromMask(treeNode->gtRsvdRegs);
+ genConsumeRegs(src);
- assert(genIsValidIntReg(targetReg));
- assert(genIsValidIntReg(sourceReg));
+ var_types srcType = ((cast->gtFlags & GTF_UNSIGNED) != 0) ? TYP_ULONG : TYP_LONG;
+ var_types dstType = cast->CastToType();
+ regNumber loSrcReg = src->gtGetOp1()->gtRegNum;
+ regNumber hiSrcReg = src->gtGetOp2()->gtRegNum;
+ regNumber dstReg = cast->gtRegNum;
- instruction ins = INS_invalid;
+ assert((dstType == TYP_INT) || (dstType == TYP_UINT));
+ assert(genIsValidIntReg(loSrcReg));
+ assert(genIsValidIntReg(hiSrcReg));
+ assert(genIsValidIntReg(dstReg));
- genConsumeReg(castOp);
- Lowering::CastInfo castInfo;
-
- // Get information about the cast.
- Lowering::getCastDescription(treeNode, &castInfo);
-
- if (castInfo.requiresOverflowCheck)
+ if (cast->gtOverflow())
{
- NYI_ARM("CodeGen::genIntToIntCast for OverflowCheck");
- }
- else // Non-overflow checking cast.
- {
- if (genTypeSize(srcType) == genTypeSize(dstType))
+ //
+ // Generate an overflow check for [u]long to [u]int casts:
+ //
+ // long -> int - check if the upper 33 bits are all 0 or all 1
+ //
+ // ulong -> int - check if the upper 33 bits are all 0
+ //
+ // long -> uint - check if the upper 32 bits are all 0
+ // ulong -> uint - check if the upper 32 bits are all 0
+ //
+
+ if ((srcType == TYP_LONG) && (dstType == TYP_INT))
{
- ins = INS_mov;
+ BasicBlock* allOne = genCreateTempLabel();
+ BasicBlock* success = genCreateTempLabel();
+
+ inst_RV_RV(INS_tst, loSrcReg, loSrcReg, TYP_INT, EA_4BYTE);
+ emitJumpKind JmpNegative = genJumpKindForOper(GT_LT, CK_LOGICAL);
+ inst_JMP(JmpNegative, allOne);
+ inst_RV_RV(INS_tst, hiSrcReg, hiSrcReg, TYP_INT, EA_4BYTE);
+ emitJumpKind jmpNotEqualL = genJumpKindForOper(GT_NE, CK_LOGICAL);
+ genJumpToThrowHlpBlk(jmpNotEqualL, SCK_OVERFLOW);
+ inst_JMP(EJ_jmp, success);
+
+ genDefineTempLabel(allOne);
+ inst_RV_IV(INS_cmp, hiSrcReg, -1, EA_4BYTE);
+ emitJumpKind jmpNotEqualS = genJumpKindForOper(GT_NE, CK_SIGNED);
+ genJumpToThrowHlpBlk(jmpNotEqualS, SCK_OVERFLOW);
+
+ genDefineTempLabel(success);
}
else
{
- var_types extendType = TYP_UNKNOWN;
-
- // If we need to treat a signed type as unsigned
- if ((treeNode->gtFlags & GTF_UNSIGNED) != 0)
- {
- extendType = genUnsignedType(srcType);
- movSize = emitTypeSize(extendType);
- movRequired = true;
- }
- else
+ if ((srcType == TYP_ULONG) && (dstType == TYP_INT))
{
- if (genTypeSize(srcType) < genTypeSize(dstType))
- {
- extendType = srcType;
- movSize = emitTypeSize(srcType);
- if (srcType == TYP_UINT)
- {
- movRequired = true;
- }
- }
- else // (genTypeSize(srcType) > genTypeSize(dstType))
- {
- extendType = dstType;
- movSize = emitTypeSize(dstType);
- }
+ inst_RV_RV(INS_tst, loSrcReg, loSrcReg, TYP_INT, EA_4BYTE);
+ emitJumpKind JmpNegative = genJumpKindForOper(GT_LT, CK_LOGICAL);
+ genJumpToThrowHlpBlk(JmpNegative, SCK_OVERFLOW);
}
- ins = ins_Move_Extend(extendType, castOp->InReg());
+ inst_RV_RV(INS_tst, hiSrcReg, hiSrcReg, TYP_INT, EA_4BYTE);
+ emitJumpKind jmpNotEqual = genJumpKindForOper(GT_NE, CK_LOGICAL);
+ genJumpToThrowHlpBlk(jmpNotEqual, SCK_OVERFLOW);
}
}
- // We should never be generating a load from memory instruction here!
- assert(!emit->emitInsIsLoad(ins));
-
- if ((ins != INS_mov) || movRequired || (targetReg != sourceReg))
+ if (dstReg != loSrcReg)
{
- emit->emitIns_R_R(ins, movSize, targetReg, sourceReg);
+ inst_RV_RV(INS_mov, dstReg, loSrcReg, TYP_INT, EA_4BYTE);
}
- genProduceReg(treeNode);
-}
-
-//------------------------------------------------------------------------
-// genFloatToFloatCast: Generate code for a cast between float and double
-//
-// Arguments:
-// treeNode - The GT_CAST node
-//
-// Return Value:
-// None.
-//
-// Assumptions:
-// Cast is a non-overflow conversion.
-// The treeNode must have an assigned register.
-// The cast is between float and double.
-//
-void CodeGen::genFloatToFloatCast(GenTreePtr treeNode)
-{
- // float <--> double conversions are always non-overflow ones
- assert(treeNode->OperGet() == GT_CAST);
- assert(!treeNode->gtOverflow());
-
- regNumber targetReg = treeNode->gtRegNum;
- assert(genIsValidFloatReg(targetReg));
-
- GenTreePtr op1 = treeNode->gtOp.gtOp1;
- assert(!op1->isContained()); // Cannot be contained
- assert(genIsValidFloatReg(op1->gtRegNum)); // Must be a valid float reg.
-
- var_types dstType = treeNode->CastToType();
- var_types srcType = op1->TypeGet();
- assert(varTypeIsFloating(srcType) && varTypeIsFloating(dstType));
-
- genConsumeOperands(treeNode->AsOp());
-
- // treeNode must be a reg
- assert(!treeNode->isContained());
-
- if (srcType != dstType)
- {
- instruction insVcvt = (srcType == TYP_FLOAT) ? INS_vcvt_f2d // convert Float to Double
- : INS_vcvt_d2f; // convert Double to Float
-
- getEmitter()->emitIns_R_R(insVcvt, emitTypeSize(treeNode), treeNode->gtRegNum, op1->gtRegNum);
- }
- else if (treeNode->gtRegNum != op1->gtRegNum)
- {
- getEmitter()->emitIns_R_R(INS_vmov, emitTypeSize(treeNode), treeNode->gtRegNum, op1->gtRegNum);
- }
-
- genProduceReg(treeNode);
+ genProduceReg(cast);
}
//------------------------------------------------------------------------
@@ -1802,36 +2128,6 @@ void CodeGen::genFloatToIntCast(GenTreePtr treeNode)
}
//------------------------------------------------------------------------
-// genCreateAndStoreGCInfo: Create and record GC Info for the function.
-//
-void CodeGen::genCreateAndStoreGCInfo(unsigned codeSize,
- unsigned prologSize,
- unsigned epilogSize DEBUGARG(void* codePtr))
-{
- IAllocator* allowZeroAlloc = new (compiler, CMK_GC) AllowZeroAllocator(compiler->getAllocatorGC());
- GcInfoEncoder* gcInfoEncoder = new (compiler, CMK_GC)
- GcInfoEncoder(compiler->info.compCompHnd, compiler->info.compMethodInfo, allowZeroAlloc, NOMEM);
- assert(gcInfoEncoder);
-
- // Follow the code pattern of the x86 gc info encoder (genCreateAndStoreGCInfoJIT32).
- gcInfo.gcInfoBlockHdrSave(gcInfoEncoder, codeSize, prologSize);
-
- // First we figure out the encoder ID's for the stack slots and registers.
- gcInfo.gcMakeRegPtrTable(gcInfoEncoder, codeSize, prologSize, GCInfo::MAKE_REG_PTR_MODE_ASSIGN_SLOTS);
- // Now we've requested all the slots we'll need; "finalize" these (make more compact data structures for them).
- gcInfoEncoder->FinalizeSlotIds();
- // Now we can actually use those slot ID's to declare live ranges.
- gcInfo.gcMakeRegPtrTable(gcInfoEncoder, codeSize, prologSize, GCInfo::MAKE_REG_PTR_MODE_DO_WORK);
-
- gcInfoEncoder->Build();
-
- // GC Encoder automatically puts the GC info in the right spot using ICorJitInfo::allocGCInfo(size_t)
- // let's save the values anyway for debugging purposes
- compiler->compInfoBlkAddr = gcInfoEncoder->Emit();
- compiler->compInfoBlkSize = 0; // not exposed by the GCEncoder interface
-}
-
-//------------------------------------------------------------------------
// genEmitHelperCall: Emit a call to a helper function.
//
void CodeGen::genEmitHelperCall(unsigned helper, int argSize, emitAttr retSize, regNumber callTargetReg /*= REG_NA */)
@@ -1900,6 +2196,58 @@ void CodeGen::genEmitHelperCall(unsigned helper, int argSize, emitAttr retSize,
regTracker.rsTrashRegsForGCInterruptability();
}
+//------------------------------------------------------------------------
+// genStoreLongLclVar: Generate code to store a non-enregistered long lclVar
+//
+// Arguments:
+// treeNode - A TYP_LONG lclVar node.
+//
+// Return Value:
+// None.
+//
+// Assumptions:
+// 'treeNode' must be a TYP_LONG lclVar node for a lclVar that has NOT been promoted.
+// Its operand must be a GT_LONG node.
+//
+void CodeGen::genStoreLongLclVar(GenTree* treeNode)
+{
+ emitter* emit = getEmitter();
+
+ GenTreeLclVarCommon* lclNode = treeNode->AsLclVarCommon();
+ unsigned lclNum = lclNode->gtLclNum;
+ LclVarDsc* varDsc = &(compiler->lvaTable[lclNum]);
+ assert(varDsc->TypeGet() == TYP_LONG);
+ assert(!varDsc->lvPromoted);
+ GenTreePtr op1 = treeNode->gtOp.gtOp1;
+ noway_assert(op1->OperGet() == GT_LONG || op1->OperGet() == GT_MUL_LONG);
+ genConsumeRegs(op1);
+
+ if (op1->OperGet() == GT_LONG)
+ {
+ // Definitions of register candidates will have been lowered to 2 int lclVars.
+ assert(!treeNode->InReg());
+
+ GenTreePtr loVal = op1->gtGetOp1();
+ GenTreePtr hiVal = op1->gtGetOp2();
+
+ // NYI: Contained immediates.
+ NYI_IF((loVal->gtRegNum == REG_NA) || (hiVal->gtRegNum == REG_NA),
+ "Store of long lclVar with contained immediate");
+
+ emit->emitIns_S_R(ins_Store(TYP_INT), EA_4BYTE, loVal->gtRegNum, lclNum, 0);
+ emit->emitIns_S_R(ins_Store(TYP_INT), EA_4BYTE, hiVal->gtRegNum, lclNum, genTypeSize(TYP_INT));
+ }
+ else if (op1->OperGet() == GT_MUL_LONG)
+ {
+ assert((op1->gtFlags & GTF_MUL_64RSLT) != 0);
+
+ // Stack store
+ getEmitter()->emitIns_S_R(ins_Store(TYP_INT), emitTypeSize(TYP_INT), REG_LNGRET_LO, lclNum, 0);
+ getEmitter()->emitIns_S_R(ins_Store(TYP_INT), emitTypeSize(TYP_INT), REG_LNGRET_HI, lclNum,
+ genTypeSize(TYP_INT));
+ }
+}
+
#endif // _TARGET_ARM_
#endif // !LEGACY_BACKEND
diff --git a/src/jit/codegenarm64.cpp b/src/jit/codegenarm64.cpp
index 71c6dd1162..7f98221df8 100644
--- a/src/jit/codegenarm64.cpp
+++ b/src/jit/codegenarm64.cpp
@@ -1265,67 +1265,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*/
-/*****************************************************************************
- *
- * Generate code that will set the given register to the integer constant.
- */
-
-void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFlags flags)
-{
- // Reg cannot be a FP reg
- assert(!genIsValidFloatReg(reg));
-
- // The only TYP_REF constant that can come this path is a managed 'null' since it is not
- // relocatable. Other ref type constants (e.g. string objects) go through a different
- // code path.
- noway_assert(type != TYP_REF || val == 0);
-
- instGen_Set_Reg_To_Imm(emitActualTypeSize(type), reg, val, flags);
-}
-
-/*****************************************************************************
- *
- * Generate code to check that the GS cookie wasn't thrashed by a buffer
- * overrun. On ARM64 we always use REG_TMP_0 and REG_TMP_1 as temp registers
- * and this works fine in the case of tail calls
- * Implementation Note: pushReg = true, in case of tail calls.
- */
-void CodeGen::genEmitGSCookieCheck(bool pushReg)
-{
- noway_assert(compiler->gsGlobalSecurityCookieAddr || compiler->gsGlobalSecurityCookieVal);
-
- // Make sure that the return register is reported as live GC-ref so that any GC that kicks in while
- // executing GS cookie check will not collect the object pointed to by REG_INTRET (R0).
- if (!pushReg && (compiler->info.compRetType == TYP_REF))
- gcInfo.gcRegGCrefSetCur |= RBM_INTRET;
-
- regNumber regGSConst = REG_TMP_0;
- regNumber regGSValue = REG_TMP_1;
-
- if (compiler->gsGlobalSecurityCookieAddr == nullptr)
- {
- // load the GS cookie constant into a reg
- //
- genSetRegToIcon(regGSConst, compiler->gsGlobalSecurityCookieVal, TYP_I_IMPL);
- }
- else
- {
- // Ngen case - GS cookie constant needs to be accessed through an indirection.
- instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, regGSConst, (ssize_t)compiler->gsGlobalSecurityCookieAddr);
- getEmitter()->emitIns_R_R_I(ins_Load(TYP_I_IMPL), EA_PTRSIZE, regGSConst, regGSConst, 0);
- }
- // Load this method's GS value from the stack frame
- getEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, regGSValue, compiler->lvaGSSecurityCookie, 0);
- // Compare with the GC cookie constant
- getEmitter()->emitIns_R_R(INS_cmp, EA_PTRSIZE, regGSConst, regGSValue);
-
- BasicBlock* gsCheckBlk = genCreateTempLabel();
- emitJumpKind jmpEqual = genJumpKindForOper(GT_EQ, CK_SIGNED);
- inst_JMP(jmpEqual, gsCheckBlk);
- genEmitHelperCall(CORINFO_HELP_FAIL_FAST, 0, EA_UNKNOWN);
- genDefineTempLabel(gsCheckBlk);
-}
-
BasicBlock* CodeGen::genCallFinally(BasicBlock* block)
{
// Generate a call to the finally, like this:
@@ -1532,14 +1471,14 @@ void CodeGen::genCodeForMulHi(GenTreeOp* treeNode)
var_types targetType = treeNode->TypeGet();
emitter *emit = getEmitter();
emitAttr size = emitTypeSize(treeNode);
- GenTree *op1 = treeNode->gtOp.gtOp1;
- GenTree *op2 = treeNode->gtOp.gtOp2;
+ GenTree *op1 = treeNode->gtOp1;
+ GenTree *op2 = treeNode->gtOp2;
// to get the high bits of the multiply, we are constrained to using the
// 1-op form: RDX:RAX = RAX * rm
// The 3-op form (Rx=Ry*Rz) does not support it.
- genConsumeOperands(treeNode->AsOp());
+ genConsumeOperands(treeNode);
GenTree* regOp = op1;
GenTree* rmOp = op2;
@@ -1883,8 +1822,8 @@ void CodeGen::genReturn(GenTreePtr treeNode)
if (movRequired)
{
- emitAttr movSize = EA_ATTR(genTypeSize(targetType));
- getEmitter()->emitIns_R_R(INS_mov, movSize, retReg, op1->gtRegNum);
+ emitAttr attr = emitTypeSize(targetType);
+ getEmitter()->emitIns_R_R(INS_mov, attr, retReg, op1->gtRegNum);
}
}
@@ -1923,8 +1862,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
if (compiler->verbose)
{
unsigned seqNum = treeNode->gtSeqNum; // Useful for setting a conditional break in Visual Studio
- printf("Generating: ");
- compiler->gtDispTree(treeNode, nullptr, nullptr, true);
+ compiler->gtDispLIRNode(treeNode, "Generating: ");
}
#endif // DEBUG
@@ -2721,7 +2659,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
break;
case GT_CALL:
- genCallInstruction(treeNode);
+ genCallInstruction(treeNode->AsCall());
break;
case GT_JMP:
@@ -2905,77 +2843,6 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
}
}
-//----------------------------------------------------------------------------------
-// genMultiRegCallStoreToLocal: store multi-reg return value of a call node to a local
-//
-// Arguments:
-// treeNode - Gentree of GT_STORE_LCL_VAR
-//
-// Return Value:
-// None
-//
-// Assumption:
-// The child of store is a multi-reg call node.
-// genProduceReg() on treeNode is made by caller of this routine.
-//
-void CodeGen::genMultiRegCallStoreToLocal(GenTreePtr treeNode)
-{
- assert(treeNode->OperGet() == GT_STORE_LCL_VAR);
-
- // Structs of size >=9 and <=16 are returned in two return registers on ARM64 and HFAs.
- assert(varTypeIsStruct(treeNode));
-
- // Assumption: current ARM64 implementation requires that a multi-reg struct
- // var in 'var = call' is flagged as lvIsMultiRegRet to prevent it from
- // being struct promoted.
- unsigned lclNum = treeNode->AsLclVarCommon()->gtLclNum;
- LclVarDsc* varDsc = &(compiler->lvaTable[lclNum]);
- noway_assert(varDsc->lvIsMultiRegRet);
-
- GenTree* op1 = treeNode->gtGetOp1();
- GenTree* actualOp1 = op1->gtSkipReloadOrCopy();
- GenTreeCall* call = actualOp1->AsCall();
- assert(call->HasMultiRegRetVal());
-
- genConsumeRegs(op1);
-
- ReturnTypeDesc* pRetTypeDesc = call->GetReturnTypeDesc();
- unsigned regCount = pRetTypeDesc->GetReturnRegCount();
-
- if (treeNode->gtRegNum != REG_NA)
- {
- // Right now the only enregistrable structs supported are SIMD types.
- assert(varTypeIsSIMD(treeNode));
- NYI("GT_STORE_LCL_VAR of a SIMD enregisterable struct");
- }
- else
- {
- // Stack store
- int offset = 0;
- for (unsigned i = 0; i < regCount; ++i)
- {
- var_types type = pRetTypeDesc->GetReturnRegType(i);
- regNumber reg = call->GetRegNumByIdx(i);
- if (op1->IsCopyOrReload())
- {
- // GT_COPY/GT_RELOAD will have valid reg for those positions
- // that need to be copied or reloaded.
- regNumber reloadReg = op1->AsCopyOrReload()->GetRegNumByIdx(i);
- if (reloadReg != REG_NA)
- {
- reg = reloadReg;
- }
- }
-
- assert(reg != REG_NA);
- getEmitter()->emitIns_S_R(ins_Store(type), emitTypeSize(type), reg, lclNum, offset);
- offset += genTypeSize(type);
- }
-
- varDsc->lvRegNum = REG_STK;
- }
-}
-
/***********************************************************************************************
* Generate code for localloc
*/
@@ -3331,7 +3198,6 @@ BAILOUT:
// b) The size of the struct to initialize is smaller than INITBLK_UNROLL_LIMIT bytes.
void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* initBlkNode)
{
-#if 0
// Make sure we got the arguments of the initblk/initobj operation in the right registers
unsigned size = initBlkNode->Size();
GenTreePtr dstAddr = initBlkNode->Addr();
@@ -3341,57 +3207,57 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* initBlkNode)
initVal = initVal->gtGetOp1();
}
- assert(!dstAddr->isContained());
- assert(!initVal->isContained());
+ assert(dstAddr->isUsedFromReg());
+ assert(initVal->isUsedFromReg() && !initVal->IsIntegralConst(0) || initVal->IsIntegralConst(0));
assert(size != 0);
assert(size <= INITBLK_UNROLL_LIMIT);
- assert(initVal->gtSkipReloadOrCopy()->IsCnsIntOrI());
- emitter *emit = getEmitter();
+ emitter* emit = getEmitter();
genConsumeOperands(initBlkNode);
- // If the initVal was moved, or spilled and reloaded to a different register,
- // get the original initVal from below the GT_RELOAD, but only after capturing the valReg,
- // which needs to be the new register.
- regNumber valReg = initVal->gtRegNum;
- initVal = initVal->gtSkipReloadOrCopy();
-#else // !0
- NYI("genCodeForInitBlkUnroll");
-#endif // !0
-}
+ regNumber valReg = initVal->IsIntegralConst(0) ? REG_ZR : initVal->gtRegNum;
-// Generates code for InitBlk by calling the VM memset helper function.
-// Preconditions:
-// a) The size argument of the InitBlk is not an integer constant.
-// b) The size argument of the InitBlk is >= INITBLK_STOS_LIMIT bytes.
-void CodeGen::genCodeForInitBlk(GenTreeBlk* initBlkNode)
-{
- // Make sure we got the arguments of the initblk operation in the right registers
- unsigned size = initBlkNode->Size();
- GenTreePtr dstAddr = initBlkNode->Addr();
- GenTreePtr initVal = initBlkNode->Data();
- if (initVal->OperIsInitVal())
- {
- initVal = initVal->gtGetOp1();
- }
+ assert(!initVal->IsIntegralConst(0) || (valReg == REG_ZR));
- assert(!dstAddr->isContained());
- assert(!initVal->isContained());
- assert(initBlkNode->gtRsvdRegs == RBM_ARG_2);
+ unsigned offset = 0;
-// TODO-ARM64-CQ: When initblk loop unrolling is implemented
-// put this assert back on.
-#if 0
- if (size != 0)
+ // Perform an unroll using stp.
+ if (size >= 2 * REGSIZE_BYTES)
{
- assert(blockSize >= INITBLK_UNROLL_LIMIT);
- }
-#endif // 0
+ // Determine how many 16 byte slots
+ size_t slots = size / (2 * REGSIZE_BYTES);
- genConsumeBlockOp(initBlkNode, REG_ARG_0, REG_ARG_1, REG_ARG_2);
+ while (slots-- > 0)
+ {
+ emit->emitIns_R_R_R_I(INS_stp, EA_8BYTE, valReg, valReg, dstAddr->gtRegNum, offset);
+ offset += (2 * REGSIZE_BYTES);
+ }
+ }
- genEmitHelperCall(CORINFO_HELP_MEMSET, 0, EA_UNKNOWN);
+ // Fill the remainder (15 bytes or less) if there's any.
+ if ((size & 0xf) != 0)
+ {
+ if ((size & 8) != 0)
+ {
+ emit->emitIns_R_R_I(INS_str, EA_8BYTE, valReg, dstAddr->gtRegNum, offset);
+ offset += 8;
+ }
+ if ((size & 4) != 0)
+ {
+ emit->emitIns_R_R_I(INS_str, EA_4BYTE, valReg, dstAddr->gtRegNum, offset);
+ offset += 4;
+ }
+ if ((size & 2) != 0)
+ {
+ emit->emitIns_R_R_I(INS_strh, EA_2BYTE, valReg, dstAddr->gtRegNum, offset);
+ offset += 2;
+ }
+ if ((size & 1) != 0)
+ {
+ emit->emitIns_R_R_I(INS_strb, EA_1BYTE, valReg, dstAddr->gtRegNum, offset);
+ }
+ }
}
// Generate code for a load from some address + offset
@@ -3413,13 +3279,34 @@ void CodeGen::genCodeForLoadOffset(instruction ins, emitAttr size, regNumber dst
}
}
+// Generate code for a load pair from some address + offset
+// base: tree node which can be either a local address or arbitrary node
+// offset: distance from the base from which to load
+void CodeGen::genCodeForLoadPairOffset(regNumber dst, regNumber dst2, GenTree* base, unsigned offset)
+{
+ emitter* emit = getEmitter();
+
+ if (base->OperIsLocalAddr())
+ {
+ if (base->gtOper == GT_LCL_FLD_ADDR)
+ offset += base->gtLclFld.gtLclOffs;
+
+ // TODO-ARM64-CQ: Implement support for using a ldp instruction with a varNum (see emitIns_R_S)
+ emit->emitIns_R_S(INS_ldr, EA_8BYTE, dst, base->gtLclVarCommon.gtLclNum, offset);
+ emit->emitIns_R_S(INS_ldr, EA_8BYTE, dst2, base->gtLclVarCommon.gtLclNum, offset + REGSIZE_BYTES);
+ }
+ else
+ {
+ emit->emitIns_R_R_R_I(INS_ldp, EA_8BYTE, dst, dst2, base->gtRegNum, offset);
+ }
+}
+
// Generate code for a store to some address + offset
// base: tree node which can be either a local address or arbitrary node
// offset: distance from the base from which to load
void CodeGen::genCodeForStoreOffset(instruction ins, emitAttr size, regNumber src, GenTree* base, unsigned offset)
{
-#if 0
- emitter *emit = getEmitter();
+ emitter* emit = getEmitter();
if (base->OperIsLocalAddr())
{
@@ -3429,11 +3316,30 @@ void CodeGen::genCodeForStoreOffset(instruction ins, emitAttr size, regNumber sr
}
else
{
- emit->emitIns_AR_R(ins, size, src, base->gtRegNum, offset);
+ emit->emitIns_R_R_I(ins, size, src, base->gtRegNum, offset);
+ }
+}
+
+// Generate code for a store pair to some address + offset
+// base: tree node which can be either a local address or arbitrary node
+// offset: distance from the base from which to load
+void CodeGen::genCodeForStorePairOffset(regNumber src, regNumber src2, GenTree* base, unsigned offset)
+{
+ emitter* emit = getEmitter();
+
+ if (base->OperIsLocalAddr())
+ {
+ if (base->gtOper == GT_LCL_FLD_ADDR)
+ offset += base->gtLclFld.gtLclOffs;
+
+ // TODO-ARM64-CQ: Implement support for using a stp instruction with a varNum (see emitIns_S_R)
+ emit->emitIns_S_R(INS_str, EA_8BYTE, src, base->gtLclVarCommon.gtLclNum, offset);
+ emit->emitIns_S_R(INS_str, EA_8BYTE, src2, base->gtLclVarCommon.gtLclNum, offset + REGSIZE_BYTES);
+ }
+ else
+ {
+ emit->emitIns_R_R_R_I(INS_stp, EA_8BYTE, src, src2, base->gtRegNum, offset);
}
-#else // !0
- NYI("genCodeForStoreOffset");
-#endif // !0
}
// Generates CpBlk code by performing a loop unroll
@@ -3442,80 +3348,96 @@ void CodeGen::genCodeForStoreOffset(instruction ins, emitAttr size, regNumber sr
// This may seem small but covers >95% of the cases in several framework assemblies.
void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode)
{
-#if 0
// Make sure we got the arguments of the cpblk operation in the right registers
unsigned size = cpBlkNode->Size();
GenTreePtr dstAddr = cpBlkNode->Addr();
GenTreePtr source = cpBlkNode->Data();
- noway_assert(source->gtOper == GT_IND);
- GenTreePtr srcAddr = source->gtGetOp1();
+ GenTreePtr srcAddr = nullptr;
- assert((size != 0 ) && (size <= CPBLK_UNROLL_LIMIT));
+ assert((size != 0) && (size <= CPBLK_UNROLL_LIMIT));
- emitter *emit = getEmitter();
+ emitter* emit = getEmitter();
- if (!srcAddr->isContained())
- genConsumeReg(srcAddr);
+ if (source->gtOper == GT_IND)
+ {
+ srcAddr = source->gtGetOp1();
+ if (srcAddr->isUsedFromReg())
+ {
+ genConsumeReg(srcAddr);
+ }
+ }
+ else
+ {
+ noway_assert(source->IsLocal());
+ // TODO-Cleanup: Consider making the addrForm() method in Rationalize public, e.g. in GenTree.
+ // OR: transform source to GT_IND(GT_LCL_VAR_ADDR)
+ if (source->OperGet() == GT_LCL_VAR)
+ {
+ source->SetOper(GT_LCL_VAR_ADDR);
+ }
+ else
+ {
+ assert(source->OperGet() == GT_LCL_FLD);
+ source->SetOper(GT_LCL_FLD_ADDR);
+ }
+ srcAddr = source;
+ }
- if (!dstAddr->isContained())
+ if (dstAddr->isUsedFromReg())
+ {
genConsumeReg(dstAddr);
+ }
unsigned offset = 0;
- // If the size of this struct is larger than 16 bytes
- // let's use SSE2 to be able to do 16 byte at a time
- // loads and stores.
- if (size >= XMM_REGSIZE_BYTES)
+ // Grab the integer temp register to emit the loads and stores.
+ regMaskTP tmpMask = genFindLowestBit(cpBlkNode->gtRsvdRegs & RBM_ALLINT);
+ regNumber tmpReg = genRegNumFromMask(tmpMask);
+
+ if (size >= 2 * REGSIZE_BYTES)
{
- assert(cpBlkNode->gtRsvdRegs != RBM_NONE);
- assert(genCountBits(cpBlkNode->gtRsvdRegs) == 1);
- regNumber xmmReg = genRegNumFromMask(cpBlkNode->gtRsvdRegs);
- assert(genIsValidFloatReg(xmmReg));
- size_t slots = size / XMM_REGSIZE_BYTES;
+ regMaskTP tmp2Mask = cpBlkNode->gtRsvdRegs & RBM_ALLINT & ~tmpMask;
+ regNumber tmp2Reg = genRegNumFromMask(tmp2Mask);
+
+ size_t slots = size / (2 * REGSIZE_BYTES);
while (slots-- > 0)
{
// Load
- genCodeForLoadOffset(INS_movdqu, EA_8BYTE, xmmReg, srcAddr, offset);
+ genCodeForLoadPairOffset(tmpReg, tmp2Reg, srcAddr, offset);
// Store
- genCodeForStoreOffset(INS_movdqu, EA_8BYTE, xmmReg, dstAddr, offset);
- offset += XMM_REGSIZE_BYTES;
+ genCodeForStorePairOffset(tmpReg, tmp2Reg, dstAddr, offset);
+ offset += 2 * REGSIZE_BYTES;
}
}
// Fill the remainder (15 bytes or less) if there's one.
if ((size & 0xf) != 0)
{
- // Grab the integer temp register to emit the remaining loads and stores.
- regNumber tmpReg = genRegNumFromMask(cpBlkNode->gtRsvdRegs & RBM_ALLINT);
-
if ((size & 8) != 0)
{
- genCodeForLoadOffset(INS_mov, EA_8BYTE, tmpReg, srcAddr, offset);
- genCodeForStoreOffset(INS_mov, EA_8BYTE, tmpReg, dstAddr, offset);
+ genCodeForLoadOffset(INS_ldr, EA_8BYTE, tmpReg, srcAddr, offset);
+ genCodeForStoreOffset(INS_str, EA_8BYTE, tmpReg, dstAddr, offset);
offset += 8;
}
if ((size & 4) != 0)
{
- genCodeForLoadOffset(INS_mov, EA_4BYTE, tmpReg, srcAddr, offset);
- genCodeForStoreOffset(INS_mov, EA_4BYTE, tmpReg, dstAddr, offset);
+ genCodeForLoadOffset(INS_ldr, EA_4BYTE, tmpReg, srcAddr, offset);
+ genCodeForStoreOffset(INS_str, EA_4BYTE, tmpReg, dstAddr, offset);
offset += 4;
}
if ((size & 2) != 0)
{
- genCodeForLoadOffset(INS_mov, EA_2BYTE, tmpReg, srcAddr, offset);
- genCodeForStoreOffset(INS_mov, EA_2BYTE, tmpReg, dstAddr, offset);
+ genCodeForLoadOffset(INS_ldrh, EA_2BYTE, tmpReg, srcAddr, offset);
+ genCodeForStoreOffset(INS_strh, EA_2BYTE, tmpReg, dstAddr, offset);
offset += 2;
}
if ((size & 1) != 0)
{
- genCodeForLoadOffset(INS_mov, EA_1BYTE, tmpReg, srcAddr, offset);
- genCodeForStoreOffset(INS_mov, EA_1BYTE, tmpReg, dstAddr, offset);
+ genCodeForLoadOffset(INS_ldrb, EA_1BYTE, tmpReg, srcAddr, offset);
+ genCodeForStoreOffset(INS_strb, EA_1BYTE, tmpReg, dstAddr, offset);
}
}
-#else // !0
- NYI("genCodeForCpBlkUnroll");
-#endif // !0
}
// Generate code for CpObj nodes wich copy structs that have interleaved
@@ -3587,22 +3509,28 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
unsigned slots = cpObjNode->gtSlots;
emitter* emit = getEmitter();
+ BYTE* gcPtrs = cpObjNode->gtGcPtrs;
+
// If we can prove it's on the stack we don't need to use the write barrier.
if (dstOnStack)
{
// TODO-ARM64-CQ: Consider using LDP/STP to save codesize.
- while (slots > 0)
+ for (unsigned i = 0; i < slots; ++i)
{
- emit->emitIns_R_R_I(INS_ldr, EA_8BYTE, tmpReg, REG_WRITE_BARRIER_SRC_BYREF, TARGET_POINTER_SIZE,
+ emitAttr attr = EA_8BYTE;
+ if (gcPtrs[i] == GCT_GCREF)
+ attr = EA_GCREF;
+ else if (gcPtrs[i] == GCT_BYREF)
+ attr = EA_BYREF;
+
+ emit->emitIns_R_R_I(INS_ldr, attr, tmpReg, REG_WRITE_BARRIER_SRC_BYREF, TARGET_POINTER_SIZE,
INS_OPTS_POST_INDEX);
- emit->emitIns_R_R_I(INS_str, EA_8BYTE, tmpReg, REG_WRITE_BARRIER_DST_BYREF, TARGET_POINTER_SIZE,
+ emit->emitIns_R_R_I(INS_str, attr, tmpReg, REG_WRITE_BARRIER_DST_BYREF, TARGET_POINTER_SIZE,
INS_OPTS_POST_INDEX);
- slots--;
}
}
else
{
- BYTE* gcPtrs = cpObjNode->gtGcPtrs;
unsigned gcPtrCount = cpObjNode->gtGcPtrCount;
unsigned i = 0;
@@ -3619,8 +3547,9 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
break;
default:
- // We have a GC pointer, call the memory barrier.
+ // In the case of a GC-Pointer we'll call the ByRef write barrier helper
genEmitHelperCall(CORINFO_HELP_ASSIGN_BYREF, 0, EA_PTRSIZE);
+
gcPtrCount--;
break;
}
@@ -3635,30 +3564,6 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
gcInfo.gcMarkRegSetNpt(RBM_WRITE_BARRIER_SRC_BYREF | RBM_WRITE_BARRIER_DST_BYREF);
}
-// Generate code for a CpBlk node by the means of the VM memcpy helper call
-// Preconditions:
-// a) The size argument of the CpBlk is not an integer constant
-// b) The size argument is a constant but is larger than CPBLK_MOVS_LIMIT bytes.
-void CodeGen::genCodeForCpBlk(GenTreeBlk* cpBlkNode)
-{
- // Make sure we got the arguments of the cpblk operation in the right registers
- unsigned blockSize = cpBlkNode->Size();
- GenTreePtr dstAddr = cpBlkNode->Addr();
- assert(!dstAddr->isContained());
-
- genConsumeBlockOp(cpBlkNode, REG_ARG_0, REG_ARG_1, REG_ARG_2);
-
-#if 0
- // Enable this when we support cpblk loop unrolling.
- if (blockSize != 0)
- {
- assert(blockSize->gtIntCon.gtIconVal >= CPBLK_UNROLL_LIMIT);
- }
-#endif // 0
-
- genEmitHelperCall(CORINFO_HELP_MEMCPY, 0, EA_UNKNOWN);
-}
-
// generate code do a switch statement based on a table of ip-relative offsets
void CodeGen::genTableBasedSwitch(GenTree* treeNode)
{
@@ -3779,239 +3684,6 @@ void CodeGen::genLockedInstructions(GenTreeOp* treeNode)
#endif // !0
}
-// generate code for BoundsCheck nodes
-void CodeGen::genRangeCheck(GenTreePtr oper)
-{
-#ifdef FEATURE_SIMD
- noway_assert(oper->OperGet() == GT_ARR_BOUNDS_CHECK || oper->OperGet() == GT_SIMD_CHK);
-#else // !FEATURE_SIMD
- noway_assert(oper->OperGet() == GT_ARR_BOUNDS_CHECK);
-#endif // !FEATURE_SIMD
-
- GenTreeBoundsChk* bndsChk = oper->AsBoundsChk();
-
- GenTreePtr arrLen = bndsChk->gtArrLen;
- GenTreePtr arrIndex = bndsChk->gtIndex;
- GenTreePtr arrRef = NULL;
- int lenOffset = 0;
-
- GenTree * src1, *src2;
- emitJumpKind jmpKind;
-
- genConsumeRegs(arrIndex);
- genConsumeRegs(arrLen);
-
- if (arrIndex->isContainedIntOrIImmed())
- {
- // To encode using a cmp immediate, we place the
- // constant operand in the second position
- src1 = arrLen;
- src2 = arrIndex;
- jmpKind = genJumpKindForOper(GT_LE, CK_UNSIGNED);
- }
- else
- {
- src1 = arrIndex;
- src2 = arrLen;
- jmpKind = genJumpKindForOper(GT_GE, CK_UNSIGNED);
- }
-
- GenTreeIntConCommon* intConst = nullptr;
- if (src2->isContainedIntOrIImmed())
- {
- intConst = src2->AsIntConCommon();
- }
-
- if (intConst != nullptr)
- {
- getEmitter()->emitIns_R_I(INS_cmp, EA_4BYTE, src1->gtRegNum, intConst->IconValue());
- }
- else
- {
- getEmitter()->emitIns_R_R(INS_cmp, EA_4BYTE, src1->gtRegNum, src2->gtRegNum);
- }
-
- genJumpToThrowHlpBlk(jmpKind, SCK_RNGCHK_FAIL, bndsChk->gtIndRngFailBB);
-}
-
-//------------------------------------------------------------------------
-// genOffsetOfMDArrayLowerBound: Returns the offset from the Array object to the
-// lower bound for the given dimension.
-//
-// Arguments:
-// elemType - the element type of the array
-// rank - the rank of the array
-// dimension - the dimension for which the lower bound offset will be returned.
-//
-// Return Value:
-// The offset.
-// TODO-Cleanup: move to CodeGenCommon.cpp
-
-// static
-unsigned CodeGen::genOffsetOfMDArrayLowerBound(var_types elemType, unsigned rank, unsigned dimension)
-{
- // Note that the lower bound and length fields of the Array object are always TYP_INT, even on 64-bit targets.
- return compiler->eeGetArrayDataOffset(elemType) + genTypeSize(TYP_INT) * (dimension + rank);
-}
-
-//------------------------------------------------------------------------
-// genOffsetOfMDArrayLength: Returns the offset from the Array object to the
-// size for the given dimension.
-//
-// Arguments:
-// elemType - the element type of the array
-// rank - the rank of the array
-// dimension - the dimension for which the lower bound offset will be returned.
-//
-// Return Value:
-// The offset.
-// TODO-Cleanup: move to CodeGenCommon.cpp
-
-// static
-unsigned CodeGen::genOffsetOfMDArrayDimensionSize(var_types elemType, unsigned rank, unsigned dimension)
-{
- // Note that the lower bound and length fields of the Array object are always TYP_INT, even on 64-bit targets.
- return compiler->eeGetArrayDataOffset(elemType) + genTypeSize(TYP_INT) * dimension;
-}
-
-//------------------------------------------------------------------------
-// genCodeForArrIndex: Generates code to bounds check the index for one dimension of an array reference,
-// producing the effective index by subtracting the lower bound.
-//
-// Arguments:
-// arrIndex - the node for which we're generating code
-//
-// Return Value:
-// None.
-//
-
-void CodeGen::genCodeForArrIndex(GenTreeArrIndex* arrIndex)
-{
- emitter* emit = getEmitter();
- GenTreePtr arrObj = arrIndex->ArrObj();
- GenTreePtr indexNode = arrIndex->IndexExpr();
- regNumber arrReg = genConsumeReg(arrObj);
- regNumber indexReg = genConsumeReg(indexNode);
- regNumber tgtReg = arrIndex->gtRegNum;
- noway_assert(tgtReg != REG_NA);
-
- // We will use a temp register to load the lower bound and dimension size values
- //
- regMaskTP tmpRegsMask = arrIndex->gtRsvdRegs; // there will be two bits set
- tmpRegsMask &= ~genRegMask(tgtReg); // remove the bit for 'tgtReg' from 'tmpRegsMask'
-
- regMaskTP tmpRegMask = genFindLowestBit(tmpRegsMask); // set tmpRegMsk to a one-bit mask
- regNumber tmpReg = genRegNumFromMask(tmpRegMask); // set tmpReg from that mask
- noway_assert(tmpReg != REG_NA);
-
- assert(tgtReg != tmpReg);
-
- unsigned dim = arrIndex->gtCurrDim;
- unsigned rank = arrIndex->gtArrRank;
- var_types elemType = arrIndex->gtArrElemType;
- unsigned offset;
-
- offset = genOffsetOfMDArrayLowerBound(elemType, rank, dim);
- emit->emitIns_R_R_I(ins_Load(TYP_INT), EA_8BYTE, tmpReg, arrReg, offset); // a 4 BYTE sign extending load
- emit->emitIns_R_R_R(INS_sub, EA_4BYTE, tgtReg, indexReg, tmpReg);
-
- offset = genOffsetOfMDArrayDimensionSize(elemType, rank, dim);
- emit->emitIns_R_R_I(ins_Load(TYP_INT), EA_8BYTE, tmpReg, arrReg, offset); // a 4 BYTE sign extending load
- emit->emitIns_R_R(INS_cmp, EA_4BYTE, tgtReg, tmpReg);
-
- emitJumpKind jmpGEU = genJumpKindForOper(GT_GE, CK_UNSIGNED);
- genJumpToThrowHlpBlk(jmpGEU, SCK_RNGCHK_FAIL);
-
- genProduceReg(arrIndex);
-}
-
-//------------------------------------------------------------------------
-// genCodeForArrOffset: Generates code to compute the flattened array offset for
-// one dimension of an array reference:
-// result = (prevDimOffset * dimSize) + effectiveIndex
-// where dimSize is obtained from the arrObj operand
-//
-// Arguments:
-// arrOffset - the node for which we're generating code
-//
-// Return Value:
-// None.
-//
-// Notes:
-// dimSize and effectiveIndex are always non-negative, the former by design,
-// and the latter because it has been normalized to be zero-based.
-
-void CodeGen::genCodeForArrOffset(GenTreeArrOffs* arrOffset)
-{
- GenTreePtr offsetNode = arrOffset->gtOffset;
- GenTreePtr indexNode = arrOffset->gtIndex;
- regNumber tgtReg = arrOffset->gtRegNum;
-
- noway_assert(tgtReg != REG_NA);
-
- if (!offsetNode->IsIntegralConst(0))
- {
- emitter* emit = getEmitter();
- regNumber offsetReg = genConsumeReg(offsetNode);
- noway_assert(offsetReg != REG_NA);
- regNumber indexReg = genConsumeReg(indexNode);
- noway_assert(indexReg != REG_NA);
- GenTreePtr arrObj = arrOffset->gtArrObj;
- regNumber arrReg = genConsumeReg(arrObj);
- noway_assert(arrReg != REG_NA);
- regMaskTP tmpRegMask = arrOffset->gtRsvdRegs;
- regNumber tmpReg = genRegNumFromMask(tmpRegMask);
- noway_assert(tmpReg != REG_NA);
- unsigned dim = arrOffset->gtCurrDim;
- unsigned rank = arrOffset->gtArrRank;
- var_types elemType = arrOffset->gtArrElemType;
- unsigned offset = genOffsetOfMDArrayDimensionSize(elemType, rank, dim);
-
- // Load tmpReg with the dimension size
- emit->emitIns_R_R_I(ins_Load(TYP_INT), EA_8BYTE, tmpReg, arrReg, offset); // a 4 BYTE sign extending load
-
- // Evaluate tgtReg = offsetReg*dim_size + indexReg.
- emit->emitIns_R_R_R_R(INS_madd, EA_4BYTE, tgtReg, tmpReg, offsetReg, indexReg);
- }
- else
- {
- regNumber indexReg = genConsumeReg(indexNode);
- if (indexReg != tgtReg)
- {
- inst_RV_RV(INS_mov, tgtReg, indexReg, TYP_INT);
- }
- }
- genProduceReg(arrOffset);
-}
-
-// make a temporary indir we can feed to pattern matching routines
-// in cases where we don't want to instantiate all the indirs that happen
-//
-// TODO-Cleanup: move to CodeGenCommon.cpp
-GenTreeIndir CodeGen::indirForm(var_types type, GenTree* base)
-{
- GenTreeIndir i(GT_IND, type, base, nullptr);
- i.gtRegNum = REG_NA;
- // has to be nonnull (because contained nodes can't be the last in block)
- // but don't want it to be a valid pointer
- i.gtNext = (GenTree*)(-1);
- return i;
-}
-
-// make a temporary int we can feed to pattern matching routines
-// in cases where we don't want to instantiate
-//
-// TODO-Cleanup: move to CodeGenCommon.cpp
-GenTreeIntCon CodeGen::intForm(var_types type, ssize_t value)
-{
- GenTreeIntCon i(type, value);
- i.gtRegNum = REG_NA;
- // has to be nonnull (because contained nodes can't be the last in block)
- // but don't want it to be a valid pointer
- i.gtNext = (GenTree*)(-1);
- return i;
-}
-
instruction CodeGen::genGetInsForOper(genTreeOps oper, var_types type)
{
instruction ins = INS_brk;
@@ -4098,414 +3770,6 @@ instruction CodeGen::genGetInsForOper(genTreeOps oper, var_types type)
return ins;
}
-//------------------------------------------------------------------------
-// genCodeForShift: Generates the code sequence for a GenTree node that
-// represents a bit shift or rotate operation (<<, >>, >>>, rol, ror).
-//
-// Arguments:
-// tree - the bit shift node (that specifies the type of bit shift to perform).
-//
-// Assumptions:
-// a) All GenTrees are register allocated.
-//
-void CodeGen::genCodeForShift(GenTreePtr tree)
-{
- var_types targetType = tree->TypeGet();
- genTreeOps oper = tree->OperGet();
- instruction ins = genGetInsForOper(oper, targetType);
- emitAttr size = emitTypeSize(tree);
-
- assert(tree->gtRegNum != REG_NA);
-
- GenTreePtr operand = tree->gtGetOp1();
- genConsumeOperands(tree->AsOp());
-
- GenTreePtr shiftBy = tree->gtGetOp2();
- if (!shiftBy->IsCnsIntOrI())
- {
- getEmitter()->emitIns_R_R_R(ins, size, tree->gtRegNum, operand->gtRegNum, shiftBy->gtRegNum);
- }
- else
- {
- unsigned immWidth = emitter::getBitWidth(size); // immWidth will be set to 32 or 64
- ssize_t shiftByImm = shiftBy->gtIntCon.gtIconVal & (immWidth - 1);
-
- getEmitter()->emitIns_R_R_I(ins, size, tree->gtRegNum, operand->gtRegNum, shiftByImm);
- }
-
- genProduceReg(tree);
-}
-
-void CodeGen::genRegCopy(GenTree* treeNode)
-{
- assert(treeNode->OperGet() == GT_COPY);
-
- var_types targetType = treeNode->TypeGet();
- regNumber targetReg = treeNode->gtRegNum;
- assert(targetReg != REG_NA);
-
- GenTree* op1 = treeNode->gtOp.gtOp1;
-
- // Check whether this node and the node from which we're copying the value have the same
- // register type.
- // This can happen if (currently iff) we have a SIMD vector type that fits in an integer
- // register, in which case it is passed as an argument, or returned from a call,
- // in an integer register and must be copied if it's in an xmm register.
-
- if (varTypeIsFloating(treeNode) != varTypeIsFloating(op1))
- {
- inst_RV_RV(INS_fmov, targetReg, genConsumeReg(op1), targetType);
- }
- else
- {
- inst_RV_RV(ins_Copy(targetType), targetReg, genConsumeReg(op1), targetType);
- }
-
- if (op1->IsLocal())
- {
- // The lclVar will never be a def.
- // If it is a last use, the lclVar will be killed by genConsumeReg(), as usual, and genProduceReg will
- // appropriately set the gcInfo for the copied value.
- // If not, there are two cases we need to handle:
- // - If this is a TEMPORARY copy (indicated by the GTF_VAR_DEATH flag) the variable
- // will remain live in its original register.
- // genProduceReg() will appropriately set the gcInfo for the copied value,
- // and genConsumeReg will reset it.
- // - Otherwise, we need to update register info for the lclVar.
-
- GenTreeLclVarCommon* lcl = op1->AsLclVarCommon();
- assert((lcl->gtFlags & GTF_VAR_DEF) == 0);
-
- if ((lcl->gtFlags & GTF_VAR_DEATH) == 0 && (treeNode->gtFlags & GTF_VAR_DEATH) == 0)
- {
- LclVarDsc* varDsc = &compiler->lvaTable[lcl->gtLclNum];
-
- // If we didn't just spill it (in genConsumeReg, above), then update the register info
- if (varDsc->lvRegNum != REG_STK)
- {
- // The old location is dying
- genUpdateRegLife(varDsc, /*isBorn*/ false, /*isDying*/ true DEBUGARG(op1));
-
- gcInfo.gcMarkRegSetNpt(genRegMask(op1->gtRegNum));
-
- genUpdateVarReg(varDsc, treeNode);
-
- // The new location is going live
- genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(treeNode));
- }
- }
- }
- genProduceReg(treeNode);
-}
-
-// Produce code for a GT_CALL node
-void CodeGen::genCallInstruction(GenTreePtr node)
-{
- GenTreeCall* call = node->AsCall();
-
- assert(call->gtOper == GT_CALL);
-
- gtCallTypes callType = (gtCallTypes)call->gtCallType;
-
- IL_OFFSETX ilOffset = BAD_IL_OFFSET;
-
- // all virtuals should have been expanded into a control expression
- assert(!call->IsVirtual() || call->gtControlExpr || call->gtCallAddr);
-
- // Consume all the arg regs
- for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext())
- {
- assert(list->OperIsList());
-
- GenTreePtr argNode = list->Current();
-
- fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, argNode->gtSkipReloadOrCopy());
- assert(curArgTabEntry);
-
- if (curArgTabEntry->regNum == REG_STK)
- continue;
-
- // Deal with multi register passed struct args.
- if (argNode->OperGet() == GT_FIELD_LIST)
- {
- GenTreeArgList* argListPtr = argNode->AsArgList();
- unsigned iterationNum = 0;
- regNumber argReg = curArgTabEntry->regNum;
- for (; argListPtr != nullptr; argListPtr = argListPtr->Rest(), iterationNum++)
- {
- GenTreePtr putArgRegNode = argListPtr->gtOp.gtOp1;
- assert(putArgRegNode->gtOper == GT_PUTARG_REG);
-
- genConsumeReg(putArgRegNode);
-
- if (putArgRegNode->gtRegNum != argReg)
- {
- inst_RV_RV(ins_Move_Extend(putArgRegNode->TypeGet(), putArgRegNode->InReg()), argReg,
- putArgRegNode->gtRegNum);
- }
-
- argReg = genRegArgNext(argReg);
- }
- }
- else
- {
- regNumber argReg = curArgTabEntry->regNum;
- genConsumeReg(argNode);
- if (argNode->gtRegNum != argReg)
- {
- inst_RV_RV(ins_Move_Extend(argNode->TypeGet(), argNode->InReg()), argReg, argNode->gtRegNum);
- }
- }
-
- // In the case of a varargs call,
- // the ABI dictates that if we have floating point args,
- // we must pass the enregistered arguments in both the
- // integer and floating point registers so, let's do that.
- if (call->IsVarargs() && varTypeIsFloating(argNode))
- {
- NYI_ARM64("CodeGen - IsVarargs");
- }
- }
-
- // Insert a null check on "this" pointer if asked.
- if (call->NeedsNullCheck())
- {
- const regNumber regThis = genGetThisArgReg(call);
- getEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, REG_ZR, regThis, 0);
- }
-
- // Either gtControlExpr != null or gtCallAddr != null or it is a direct non-virtual call to a user or helper method.
- CORINFO_METHOD_HANDLE methHnd;
- GenTree* target = call->gtControlExpr;
- if (callType == CT_INDIRECT)
- {
- assert(target == nullptr);
- target = call->gtCall.gtCallAddr;
- methHnd = nullptr;
- }
- else
- {
- methHnd = call->gtCallMethHnd;
- }
-
- CORINFO_SIG_INFO* sigInfo = nullptr;
-#ifdef DEBUG
- // Pass the call signature information down into the emitter so the emitter can associate
- // native call sites with the signatures they were generated from.
- if (callType != CT_HELPER)
- {
- sigInfo = call->callSig;
- }
-#endif // DEBUG
-
- // If fast tail call, then we are done. In this case we setup the args (both reg args
- // and stack args in incoming arg area) and call target in IP0. Epilog sequence would
- // generate "br IP0".
- if (call->IsFastTailCall())
- {
- // Don't support fast tail calling JIT helpers
- assert(callType != CT_HELPER);
-
- // Fast tail calls materialize call target either in gtControlExpr or in gtCallAddr.
- assert(target != nullptr);
-
- genConsumeReg(target);
-
- if (target->gtRegNum != REG_IP0)
- {
- inst_RV_RV(INS_mov, REG_IP0, target->gtRegNum);
- }
- return;
- }
-
- // For a pinvoke to unmanged code we emit a label to clear
- // the GC pointer state before the callsite.
- // We can't utilize the typical lazy killing of GC pointers
- // at (or inside) the callsite.
- if (call->IsUnmanaged())
- {
- genDefineTempLabel(genCreateTempLabel());
- }
-
- // Determine return value size(s).
- ReturnTypeDesc* pRetTypeDesc = call->GetReturnTypeDesc();
- emitAttr retSize = EA_PTRSIZE;
- emitAttr secondRetSize = EA_UNKNOWN;
-
- if (call->HasMultiRegRetVal())
- {
- retSize = emitTypeSize(pRetTypeDesc->GetReturnRegType(0));
- secondRetSize = emitTypeSize(pRetTypeDesc->GetReturnRegType(1));
- }
- else
- {
- assert(!varTypeIsStruct(call));
-
- if (call->gtType == TYP_REF || call->gtType == TYP_ARRAY)
- {
- retSize = EA_GCREF;
- }
- else if (call->gtType == TYP_BYREF)
- {
- retSize = EA_BYREF;
- }
- }
-
- // We need to propagate the IL offset information to the call instruction, so we can emit
- // an IL to native mapping record for the call, to support managed return value debugging.
- // We don't want tail call helper calls that were converted from normal calls to get a record,
- // so we skip this hash table lookup logic in that case.
- if (compiler->opts.compDbgInfo && compiler->genCallSite2ILOffsetMap != nullptr && !call->IsTailCall())
- {
- (void)compiler->genCallSite2ILOffsetMap->Lookup(call, &ilOffset);
- }
-
- if (target != nullptr)
- {
- // For Arm64 a call target can not be a contained indirection
- assert(!target->isContainedIndir());
-
- // We have already generated code for gtControlExpr evaluating it into a register.
- // We just need to emit "call reg" in this case.
- //
- assert(genIsValidIntReg(target->gtRegNum));
-
- genEmitCall(emitter::EC_INDIR_R, methHnd,
- INDEBUG_LDISASM_COMMA(sigInfo) nullptr, // addr
- retSize, secondRetSize, ilOffset, genConsumeReg(target));
- }
- else
- {
- // Generate a direct call to a non-virtual user defined or helper method
- assert(callType == CT_HELPER || callType == CT_USER_FUNC);
-
- void* addr = nullptr;
- if (callType == CT_HELPER)
- {
- // Direct call to a helper method.
- CorInfoHelpFunc helperNum = compiler->eeGetHelperNum(methHnd);
- noway_assert(helperNum != CORINFO_HELP_UNDEF);
-
- void* pAddr = nullptr;
- addr = compiler->compGetHelperFtn(helperNum, (void**)&pAddr);
-
- if (addr == nullptr)
- {
- addr = pAddr;
- }
- }
- else
- {
- // Direct call to a non-virtual user function.
- CORINFO_ACCESS_FLAGS aflags = CORINFO_ACCESS_ANY;
- if (call->IsSameThis())
- {
- aflags = (CORINFO_ACCESS_FLAGS)(aflags | CORINFO_ACCESS_THIS);
- }
-
- if ((call->NeedsNullCheck()) == 0)
- {
- aflags = (CORINFO_ACCESS_FLAGS)(aflags | CORINFO_ACCESS_NONNULL);
- }
-
- CORINFO_CONST_LOOKUP addrInfo;
- compiler->info.compCompHnd->getFunctionEntryPoint(methHnd, &addrInfo, aflags);
-
- addr = addrInfo.addr;
- }
-#if 0
- // Use this path if you want to load an absolute call target using
- // a sequence of movs followed by an indirect call (blr instruction)
-
- // Load the call target address in x16
- instGen_Set_Reg_To_Imm(EA_8BYTE, REG_IP0, (ssize_t) addr);
-
- // indirect call to constant address in IP0
- genEmitCall(emitter::EC_INDIR_R,
- methHnd,
- INDEBUG_LDISASM_COMMA(sigInfo)
- nullptr, //addr
- retSize,
- secondRetSize,
- ilOffset,
- REG_IP0);
-#else
- // Non-virtual direct call to known addresses
- genEmitCall(emitter::EC_FUNC_TOKEN, methHnd, INDEBUG_LDISASM_COMMA(sigInfo) addr, retSize, secondRetSize,
- ilOffset);
-#endif
- }
-
- // if it was a pinvoke we may have needed to get the address of a label
- if (genPendingCallLabel)
- {
- assert(call->IsUnmanaged());
- genDefineTempLabel(genPendingCallLabel);
- genPendingCallLabel = nullptr;
- }
-
- // Update GC info:
- // All Callee arg registers are trashed and no longer contain any GC pointers.
- // TODO-ARM64-Bug?: As a matter of fact shouldn't we be killing all of callee trashed regs here?
- // For now we will assert that other than arg regs gc ref/byref set doesn't contain any other
- // registers from RBM_CALLEE_TRASH
- assert((gcInfo.gcRegGCrefSetCur & (RBM_CALLEE_TRASH & ~RBM_ARG_REGS)) == 0);
- assert((gcInfo.gcRegByrefSetCur & (RBM_CALLEE_TRASH & ~RBM_ARG_REGS)) == 0);
- gcInfo.gcRegGCrefSetCur &= ~RBM_ARG_REGS;
- gcInfo.gcRegByrefSetCur &= ~RBM_ARG_REGS;
-
- var_types returnType = call->TypeGet();
- if (returnType != TYP_VOID)
- {
- regNumber returnReg;
-
- if (call->HasMultiRegRetVal())
- {
- assert(pRetTypeDesc != nullptr);
- unsigned regCount = pRetTypeDesc->GetReturnRegCount();
-
- // If regs allocated to call node are different from ABI return
- // regs in which the call has returned its result, move the result
- // to regs allocated to call node.
- for (unsigned i = 0; i < regCount; ++i)
- {
- var_types regType = pRetTypeDesc->GetReturnRegType(i);
- returnReg = pRetTypeDesc->GetABIReturnReg(i);
- regNumber allocatedReg = call->GetRegNumByIdx(i);
- if (returnReg != allocatedReg)
- {
- inst_RV_RV(ins_Copy(regType), allocatedReg, returnReg, regType);
- }
- }
- }
- else
- {
- if (varTypeIsFloating(returnType))
- {
- returnReg = REG_FLOATRET;
- }
- else
- {
- returnReg = REG_INTRET;
- }
-
- if (call->gtRegNum != returnReg)
- {
- inst_RV_RV(ins_Copy(returnType), call->gtRegNum, returnReg, returnType);
- }
- }
-
- genProduceReg(call);
- }
-
- // If there is nothing next, that means the result is thrown away, so this value is not live.
- // However, for minopts or debuggable code, we keep it live to support managed return value debugging.
- if ((call->gtNext == nullptr) && !compiler->opts.MinOpts() && !compiler->opts.compDbgCode)
- {
- gcInfo.gcMarkRegSetNpt(RBM_INTRET);
- }
-}
-
// Produce code for a GT_JMP node.
// The arguments of the caller needs to be transferred to the callee before exiting caller.
// The actual jump to callee is generated as part of caller epilog sequence.
@@ -4767,13 +4031,12 @@ void CodeGen::genLeaInstruction(GenTreeAddrMode* lea)
if (lsl > 0)
{
// Generate code to set tmpReg = base + index*scale
- emit->emitIns_R_R_R_I(INS_add, EA_PTRSIZE, tmpReg, memBase->gtRegNum, index->gtRegNum, lsl,
- INS_OPTS_LSL);
+ emit->emitIns_R_R_R_I(INS_add, size, tmpReg, memBase->gtRegNum, index->gtRegNum, lsl, INS_OPTS_LSL);
}
else // no scale
{
// Generate code to set tmpReg = base + index
- emit->emitIns_R_R_R(INS_add, EA_PTRSIZE, tmpReg, memBase->gtRegNum, index->gtRegNum);
+ emit->emitIns_R_R_R(INS_add, size, tmpReg, memBase->gtRegNum, index->gtRegNum);
}
// Then compute target reg from [tmpReg + offset]
@@ -4786,7 +4049,7 @@ void CodeGen::genLeaInstruction(GenTreeAddrMode* lea)
instGen_Set_Reg_To_Imm(EA_PTRSIZE, tmpReg, offset);
// Then add the base register
// rd = rd + base
- emit->emitIns_R_R_R(INS_add, EA_PTRSIZE, tmpReg, tmpReg, memBase->gtRegNum);
+ emit->emitIns_R_R_R(INS_add, size, tmpReg, tmpReg, memBase->gtRegNum);
noway_assert(tmpReg != index->gtRegNum);
@@ -5035,237 +4298,6 @@ void CodeGen::genSetRegToCond(regNumber dstReg, GenTreePtr tree)
}
//------------------------------------------------------------------------
-// genIntToIntCast: Generate code for an integer cast
-// This method handles integer overflow checking casts
-// as well as ordinary integer casts.
-//
-// Arguments:
-// treeNode - The GT_CAST node
-//
-// Return Value:
-// None.
-//
-// Assumptions:
-// The treeNode is not a contained node and must have an assigned register.
-// For a signed convert from byte, the source must be in a byte-addressable register.
-// Neither the source nor target type can be a floating point type.
-//
-// TODO-ARM64-CQ: Allow castOp to be a contained node without an assigned register.
-//
-void CodeGen::genIntToIntCast(GenTreePtr treeNode)
-{
- assert(treeNode->OperGet() == GT_CAST);
-
- GenTreePtr castOp = treeNode->gtCast.CastOp();
- emitter* emit = getEmitter();
-
- var_types dstType = treeNode->CastToType();
- var_types srcType = genActualType(castOp->TypeGet());
- emitAttr movSize = emitActualTypeSize(dstType);
- bool movRequired = false;
-
- regNumber targetReg = treeNode->gtRegNum;
- regNumber sourceReg = castOp->gtRegNum;
-
- // For Long to Int conversion we will have a reserved integer register to hold the immediate mask
- regNumber tmpReg = (treeNode->gtRsvdRegs == RBM_NONE) ? REG_NA : genRegNumFromMask(treeNode->gtRsvdRegs);
-
- assert(genIsValidIntReg(targetReg));
- assert(genIsValidIntReg(sourceReg));
-
- instruction ins = INS_invalid;
-
- genConsumeReg(castOp);
- Lowering::CastInfo castInfo;
-
- // Get information about the cast.
- Lowering::getCastDescription(treeNode, &castInfo);
-
- if (castInfo.requiresOverflowCheck)
- {
-
- emitAttr cmpSize = EA_ATTR(genTypeSize(srcType));
-
- if (castInfo.signCheckOnly)
- {
- // We only need to check for a negative value in sourceReg
- emit->emitIns_R_I(INS_cmp, cmpSize, sourceReg, 0);
- emitJumpKind jmpLT = genJumpKindForOper(GT_LT, CK_SIGNED);
- genJumpToThrowHlpBlk(jmpLT, SCK_OVERFLOW);
- noway_assert(genTypeSize(srcType) == 4 || genTypeSize(srcType) == 8);
- // This is only interesting case to ensure zero-upper bits.
- if ((srcType == TYP_INT) && (dstType == TYP_ULONG))
- {
- // cast to TYP_ULONG:
- // We use a mov with size=EA_4BYTE
- // which will zero out the upper bits
- movSize = EA_4BYTE;
- movRequired = true;
- }
- }
- else if (castInfo.unsignedSource || castInfo.unsignedDest)
- {
- // When we are converting from/to unsigned,
- // we only have to check for any bits set in 'typeMask'
-
- noway_assert(castInfo.typeMask != 0);
- emit->emitIns_R_I(INS_tst, cmpSize, sourceReg, castInfo.typeMask);
- emitJumpKind jmpNotEqual = genJumpKindForOper(GT_NE, CK_SIGNED);
- genJumpToThrowHlpBlk(jmpNotEqual, SCK_OVERFLOW);
- }
- else
- {
- // For a narrowing signed cast
- //
- // We must check the value is in a signed range.
-
- // Compare with the MAX
-
- noway_assert((castInfo.typeMin != 0) && (castInfo.typeMax != 0));
-
- if (emitter::emitIns_valid_imm_for_cmp(castInfo.typeMax, cmpSize))
- {
- emit->emitIns_R_I(INS_cmp, cmpSize, sourceReg, castInfo.typeMax);
- }
- else
- {
- noway_assert(tmpReg != REG_NA);
- instGen_Set_Reg_To_Imm(cmpSize, tmpReg, castInfo.typeMax);
- emit->emitIns_R_R(INS_cmp, cmpSize, sourceReg, tmpReg);
- }
-
- emitJumpKind jmpGT = genJumpKindForOper(GT_GT, CK_SIGNED);
- genJumpToThrowHlpBlk(jmpGT, SCK_OVERFLOW);
-
- // Compare with the MIN
-
- if (emitter::emitIns_valid_imm_for_cmp(castInfo.typeMin, cmpSize))
- {
- emit->emitIns_R_I(INS_cmp, cmpSize, sourceReg, castInfo.typeMin);
- }
- else
- {
- noway_assert(tmpReg != REG_NA);
- instGen_Set_Reg_To_Imm(cmpSize, tmpReg, castInfo.typeMin);
- emit->emitIns_R_R(INS_cmp, cmpSize, sourceReg, tmpReg);
- }
-
- emitJumpKind jmpLT = genJumpKindForOper(GT_LT, CK_SIGNED);
- genJumpToThrowHlpBlk(jmpLT, SCK_OVERFLOW);
- }
- ins = INS_mov;
- }
- else // Non-overflow checking cast.
- {
- if (genTypeSize(srcType) == genTypeSize(dstType))
- {
- ins = INS_mov;
- }
- else
- {
- var_types extendType = TYP_UNKNOWN;
-
- // If we need to treat a signed type as unsigned
- if ((treeNode->gtFlags & GTF_UNSIGNED) != 0)
- {
- extendType = genUnsignedType(srcType);
- movSize = emitTypeSize(extendType);
- movRequired = true;
- }
- else
- {
- if (genTypeSize(srcType) < genTypeSize(dstType))
- {
- extendType = srcType;
- if (srcType == TYP_UINT)
- {
- // If we are casting from a smaller type to
- // a larger type, then we need to make sure the
- // higher 4 bytes are zero to gaurentee the correct value.
- // Therefore using a mov with EA_4BYTE in place of EA_8BYTE
- // will zero the upper bits
- movSize = EA_4BYTE;
- movRequired = true;
- }
- }
- else // (genTypeSize(srcType) > genTypeSize(dstType))
- {
- extendType = dstType;
- if (dstType == TYP_INT)
- {
- movSize = EA_8BYTE; // a sxtw instruction requires EA_8BYTE
- }
- }
- }
-
- ins = ins_Move_Extend(extendType, castOp->InReg());
- }
- }
-
- // We should never be generating a load from memory instruction here!
- assert(!emit->emitInsIsLoad(ins));
-
- if ((ins != INS_mov) || movRequired || (targetReg != sourceReg))
- {
- emit->emitIns_R_R(ins, movSize, targetReg, sourceReg);
- }
-
- genProduceReg(treeNode);
-}
-
-//------------------------------------------------------------------------
-// genFloatToFloatCast: Generate code for a cast between float and double
-//
-// Arguments:
-// treeNode - The GT_CAST node
-//
-// Return Value:
-// None.
-//
-// Assumptions:
-// Cast is a non-overflow conversion.
-// The treeNode must have an assigned register.
-// The cast is between float and double or vice versa.
-//
-void CodeGen::genFloatToFloatCast(GenTreePtr treeNode)
-{
- // float <--> double conversions are always non-overflow ones
- assert(treeNode->OperGet() == GT_CAST);
- assert(!treeNode->gtOverflow());
-
- regNumber targetReg = treeNode->gtRegNum;
- assert(genIsValidFloatReg(targetReg));
-
- GenTreePtr op1 = treeNode->gtOp.gtOp1;
- assert(!op1->isContained()); // Cannot be contained
- assert(genIsValidFloatReg(op1->gtRegNum)); // Must be a valid float reg.
-
- var_types dstType = treeNode->CastToType();
- var_types srcType = op1->TypeGet();
- assert(varTypeIsFloating(srcType) && varTypeIsFloating(dstType));
-
- genConsumeOperands(treeNode->AsOp());
-
- // treeNode must be a reg
- assert(!treeNode->isContained());
-
- if (srcType != dstType)
- {
- insOpts cvtOption = (srcType == TYP_FLOAT) ? INS_OPTS_S_TO_D // convert Single to Double
- : INS_OPTS_D_TO_S; // convert Double to Single
-
- getEmitter()->emitIns_R_R(INS_fcvt, emitTypeSize(treeNode), treeNode->gtRegNum, op1->gtRegNum, cvtOption);
- }
- else if (treeNode->gtRegNum != op1->gtRegNum)
- {
- // If double to double cast or float to float cast. Emit a move instruction.
- getEmitter()->emitIns_R_R(INS_mov, emitTypeSize(treeNode), treeNode->gtRegNum, op1->gtRegNum);
- }
-
- genProduceReg(treeNode);
-}
-
-//------------------------------------------------------------------------
// genIntToFloatCast: Generate code to cast an int/long to float/double
//
// Arguments:
@@ -5543,546 +4575,6 @@ int CodeGenInterface::genCallerSPtoInitialSPdelta()
return callerSPtoSPdelta;
}
-//---------------------------------------------------------------------
-// genIntrinsic - generate code for a given intrinsic
-//
-// Arguments
-// treeNode - the GT_INTRINSIC node
-//
-// Return value:
-// None
-//
-void CodeGen::genIntrinsic(GenTreePtr treeNode)
-{
- // Both operand and its result must be of the same floating point type.
- GenTreePtr srcNode = treeNode->gtOp.gtOp1;
- assert(varTypeIsFloating(srcNode));
- assert(srcNode->TypeGet() == treeNode->TypeGet());
-
- // Right now only Abs/Round/Sqrt are treated as math intrinsics.
- //
- switch (treeNode->gtIntrinsic.gtIntrinsicId)
- {
- case CORINFO_INTRINSIC_Abs:
- genConsumeOperands(treeNode->AsOp());
- getEmitter()->emitInsBinary(INS_fabs, emitTypeSize(treeNode), treeNode, srcNode);
- break;
-
- case CORINFO_INTRINSIC_Round:
- genConsumeOperands(treeNode->AsOp());
- getEmitter()->emitInsBinary(INS_frintn, emitTypeSize(treeNode), treeNode, srcNode);
- break;
-
- case CORINFO_INTRINSIC_Sqrt:
- genConsumeOperands(treeNode->AsOp());
- getEmitter()->emitInsBinary(INS_fsqrt, emitTypeSize(treeNode), treeNode, srcNode);
- break;
-
- default:
- assert(!"genIntrinsic: Unsupported intrinsic");
- unreached();
- }
-
- genProduceReg(treeNode);
-}
-
-//---------------------------------------------------------------------
-// genPutArgStk - generate code for a GT_PUTARG_STK node
-//
-// Arguments
-// treeNode - the GT_PUTARG_STK node
-//
-// Return value:
-// None
-//
-void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
-{
- assert(treeNode->OperGet() == GT_PUTARG_STK);
- var_types targetType = treeNode->TypeGet();
- GenTreePtr source = treeNode->gtOp.gtOp1;
- emitter* emit = getEmitter();
-
- // This is the varNum for our store operations,
- // typically this is the varNum for the Outgoing arg space
- // When we are generating a tail call it will be the varNum for arg0
- unsigned varNumOut;
- unsigned argOffsetMax; // Records the maximum size of this area for assert checks
-
- // This is the varNum for our load operations,
- // only used when we have a multireg struct with a LclVar source
- unsigned varNumInp = BAD_VAR_NUM;
-
- // Get argument offset to use with 'varNumOut'
- // Here we cross check that argument offset hasn't changed from lowering to codegen since
- // we are storing arg slot number in GT_PUTARG_STK node in lowering phase.
- unsigned argOffsetOut = treeNode->AsPutArgStk()->gtSlotNum * TARGET_POINTER_SIZE;
-
-#ifdef DEBUG
- fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(treeNode->AsPutArgStk()->gtCall, treeNode);
- assert(curArgTabEntry);
- assert(argOffsetOut == (curArgTabEntry->slotNum * TARGET_POINTER_SIZE));
-#endif // DEBUG
-
-#if FEATURE_FASTTAILCALL
- bool putInIncomingArgArea = treeNode->AsPutArgStk()->putInIncomingArgArea;
-#else
- const bool putInIncomingArgArea = false;
-#endif
- // Whether to setup stk arg in incoming or out-going arg area?
- // Fast tail calls implemented as epilog+jmp = stk arg is setup in incoming arg area.
- // All other calls - stk arg is setup in out-going arg area.
- if (putInIncomingArgArea)
- {
- varNumOut = getFirstArgWithStackSlot();
- argOffsetMax = compiler->compArgSize;
-#if FEATURE_FASTTAILCALL
- // This must be a fast tail call.
- assert(treeNode->AsPutArgStk()->gtCall->AsCall()->IsFastTailCall());
-
- // Since it is a fast tail call, the existence of first incoming arg is guaranteed
- // because fast tail call requires that in-coming arg area of caller is >= out-going
- // arg area required for tail call.
- LclVarDsc* varDsc = &(compiler->lvaTable[varNumOut]);
- assert(varDsc != nullptr);
-#endif // FEATURE_FASTTAILCALL
- }
- else
- {
- varNumOut = compiler->lvaOutgoingArgSpaceVar;
- argOffsetMax = compiler->lvaOutgoingArgSpaceSize;
- }
- bool isStruct = (targetType == TYP_STRUCT) || (source->OperGet() == GT_FIELD_LIST);
-
- if (!isStruct) // a normal non-Struct argument
- {
- instruction storeIns = ins_Store(targetType);
- emitAttr storeAttr = emitTypeSize(targetType);
-
- // If it is contained then source must be the integer constant zero
- if (source->isContained())
- {
- assert(source->OperGet() == GT_CNS_INT);
- assert(source->AsIntConCommon()->IconValue() == 0);
- emit->emitIns_S_R(storeIns, storeAttr, REG_ZR, varNumOut, argOffsetOut);
- }
- else
- {
- genConsumeReg(source);
- emit->emitIns_S_R(storeIns, storeAttr, source->gtRegNum, varNumOut, argOffsetOut);
- }
- argOffsetOut += EA_SIZE_IN_BYTES(storeAttr);
- assert(argOffsetOut <= argOffsetMax); // We can't write beyound the outgoing area area
- }
- else // We have some kind of a struct argument
- {
- assert(source->isContained()); // We expect that this node was marked as contained in LowerArm64
-
- if (source->OperGet() == GT_FIELD_LIST)
- {
- // Deal with the multi register passed struct args.
- GenTreeFieldList* fieldListPtr = source->AsFieldList();
-
- // Evaluate each of the GT_FIELD_LIST items into their register
- // and store their register into the outgoing argument area
- for (; fieldListPtr != nullptr; fieldListPtr = fieldListPtr->Rest())
- {
- GenTreePtr nextArgNode = fieldListPtr->gtOp.gtOp1;
- genConsumeReg(nextArgNode);
-
- regNumber reg = nextArgNode->gtRegNum;
- var_types type = nextArgNode->TypeGet();
- emitAttr attr = emitTypeSize(type);
-
- // Emit store instructions to store the registers produced by the GT_FIELD_LIST into the outgoing
- // argument area
- emit->emitIns_S_R(ins_Store(type), attr, reg, varNumOut, argOffsetOut);
- argOffsetOut += EA_SIZE_IN_BYTES(attr);
- assert(argOffsetOut <= argOffsetMax); // We can't write beyound the outgoing area area
- }
- }
- else // We must have a GT_OBJ or a GT_LCL_VAR
- {
- noway_assert((source->OperGet() == GT_LCL_VAR) || (source->OperGet() == GT_OBJ));
-
- var_types targetType = source->TypeGet();
- noway_assert(varTypeIsStruct(targetType));
-
- // We will copy this struct to the stack, possibly using a ldp instruction
- // Setup loReg and hiReg from the internal registers that we reserved in lower.
- //
- regNumber loReg = REG_NA;
- regNumber hiReg = REG_NA;
- regNumber addrReg = REG_NA;
-
- // In lowerArm64/TreeNodeInfoInitPutArgStk we have reserved two internal integer registers
- genGetRegPairFromMask(treeNode->gtRsvdRegs, &loReg, &hiReg);
-
- GenTreeLclVarCommon* varNode = nullptr;
- GenTreePtr addrNode = nullptr;
-
- if (source->OperGet() == GT_LCL_VAR)
- {
- varNode = source->AsLclVarCommon();
- }
- else // we must have a GT_OBJ
- {
- assert(source->OperGet() == GT_OBJ);
-
- addrNode = source->gtOp.gtOp1;
-
- // addrNode can either be a GT_LCL_VAR_ADDR or an address expression
- //
- if (addrNode->OperGet() == GT_LCL_VAR_ADDR)
- {
- // We have a GT_OBJ(GT_LCL_VAR_ADDR)
- //
- // We will treat this case the same as above
- // (i.e if we just had this GT_LCL_VAR directly as the source)
- // so update 'source' to point this GT_LCL_VAR_ADDR node
- // and continue to the codegen for the LCL_VAR node below
- //
- varNode = addrNode->AsLclVarCommon();
- addrNode = nullptr;
- }
- }
-
- // Either varNode or addrNOde must have been setup above,
- // the xor ensures that only one of the two is setup, not both
- assert((varNode != nullptr) ^ (addrNode != nullptr));
-
- BYTE gcPtrs[MAX_ARG_REG_COUNT] = {}; // TYPE_GC_NONE = 0
- BYTE* structGcLayout = &gcPtrs[0]; // The GC layout for the struct
- unsigned gcPtrCount; // The count of GC pointers in the struct
- int structSize;
- bool isHfa;
-
- // Setup the structSize, isHFa, and gcPtrCount
- if (varNode != nullptr)
- {
- varNumInp = varNode->gtLclNum;
- assert(varNumInp < compiler->lvaCount);
- LclVarDsc* varDsc = &compiler->lvaTable[varNumInp];
-
- assert(varDsc->lvType == TYP_STRUCT);
- assert(varDsc->lvOnFrame); // This struct also must live in the stack frame
- assert(!varDsc->lvRegister); // And it can't live in a register (SIMD)
-
- structSize = varDsc->lvSize(); // This yields the roundUp size, but that is fine
- // as that is how much stack is allocated for this LclVar
- isHfa = varDsc->lvIsHfa();
- gcPtrCount = varDsc->lvStructGcCount;
- structGcLayout = varDsc->lvGcLayout;
- }
- else // addrNode is used
- {
- assert(addrNode != nullptr);
-
- // Generate code to load the address that we need into a register
- genConsumeAddress(addrNode);
- addrReg = addrNode->gtRegNum;
-
- CORINFO_CLASS_HANDLE objClass = source->gtObj.gtClass;
-
- structSize = compiler->info.compCompHnd->getClassSize(objClass);
- isHfa = compiler->IsHfa(objClass);
- gcPtrCount = compiler->info.compCompHnd->getClassGClayout(objClass, &gcPtrs[0]);
- }
-
- bool hasGCpointers = (gcPtrCount > 0); // true if there are any GC pointers in the struct
-
- // If we have an HFA we can't have any GC pointers,
- // if not then the max size for the the struct is 16 bytes
- if (isHfa)
- {
- noway_assert(gcPtrCount == 0);
- }
- else
- {
- noway_assert(structSize <= 2 * TARGET_POINTER_SIZE);
- }
-
- noway_assert(structSize <= MAX_PASS_MULTIREG_BYTES);
-
- // For a 16-byte structSize with GC pointers we will use two ldr and two str instructions
- // ldr x2, [x0]
- // ldr x3, [x0, #8]
- // str x2, [sp, #16]
- // str x3, [sp, #24]
- //
- // For a 16-byte structSize with no GC pointers we will use a ldp and two str instructions
- // ldp x2, x3, [x0]
- // str x2, [sp, #16]
- // str x3, [sp, #24]
- //
- // For a 32-byte structSize with no GC pointers we will use two ldp and four str instructions
- // ldp x2, x3, [x0]
- // str x2, [sp, #16]
- // str x3, [sp, #24]
- // ldp x2, x3, [x0]
- // str x2, [sp, #32]
- // str x3, [sp, #40]
- //
- // Note that when loading from a varNode we currently can't use the ldp instruction
- // TODO-ARM64-CQ: Implement support for using a ldp instruction with a varNum (see emitIns_R_S)
- //
-
- int remainingSize = structSize;
- unsigned structOffset = 0;
- unsigned nextIndex = 0;
-
- while (remainingSize >= 2 * TARGET_POINTER_SIZE)
- {
- var_types type0 = compiler->getJitGCType(gcPtrs[nextIndex + 0]);
- var_types type1 = compiler->getJitGCType(gcPtrs[nextIndex + 1]);
-
- if (hasGCpointers)
- {
- // We have GC pointers, so use two ldr instructions
- //
- // We must do it this way because we can't currently pass or track
- // two different emitAttr values for a ldp instruction.
-
- // Make sure that the first load instruction does not overwrite the addrReg.
- //
- if (loReg != addrReg)
- {
- if (varNode != nullptr)
- {
- // Load from our varNumImp source
- emit->emitIns_R_S(ins_Load(type0), emitTypeSize(type0), loReg, varNumInp, 0);
- emit->emitIns_R_S(ins_Load(type1), emitTypeSize(type1), hiReg, varNumInp,
- TARGET_POINTER_SIZE);
- }
- else
- {
- // Load from our address expression source
- emit->emitIns_R_R_I(ins_Load(type0), emitTypeSize(type0), loReg, addrReg, structOffset);
- emit->emitIns_R_R_I(ins_Load(type1), emitTypeSize(type1), hiReg, addrReg,
- structOffset + TARGET_POINTER_SIZE);
- }
- }
- else // loReg == addrReg
- {
- assert(varNode == nullptr); // because addrReg is REG_NA when varNode is non-null
- assert(hiReg != addrReg);
- // Load from our address expression source
- emit->emitIns_R_R_I(ins_Load(type1), emitTypeSize(type1), hiReg, addrReg,
- structOffset + TARGET_POINTER_SIZE);
- emit->emitIns_R_R_I(ins_Load(type0), emitTypeSize(type0), loReg, addrReg, structOffset);
- }
- }
- else // our struct has no GC pointers
- {
- if (varNode != nullptr)
- {
- // Load from our varNumImp source, currently we can't use a ldp instruction to do this
- emit->emitIns_R_S(ins_Load(type0), emitTypeSize(type0), loReg, varNumInp, 0);
- emit->emitIns_R_S(ins_Load(type1), emitTypeSize(type1), hiReg, varNumInp, TARGET_POINTER_SIZE);
- }
- else
- {
- // Use a ldp instruction
-
- // Load from our address expression source
- emit->emitIns_R_R_R_I(INS_ldp, EA_PTRSIZE, loReg, hiReg, addrReg, structOffset);
- }
- }
-
- // Emit two store instructions to store the two registers into the outgoing argument area
- emit->emitIns_S_R(ins_Store(type0), emitTypeSize(type0), loReg, varNumOut, argOffsetOut);
- emit->emitIns_S_R(ins_Store(type1), emitTypeSize(type1), hiReg, varNumOut,
- argOffsetOut + TARGET_POINTER_SIZE);
- argOffsetOut += (2 * TARGET_POINTER_SIZE); // We stored 16-bytes of the struct
- assert(argOffsetOut <= argOffsetMax); // We can't write beyound the outgoing area area
-
- remainingSize -= (2 * TARGET_POINTER_SIZE); // We loaded 16-bytes of the struct
- structOffset += (2 * TARGET_POINTER_SIZE);
- nextIndex += 2;
- }
-
- // For a 12-byte structSize we will we will generate two load instructions
- // ldr x2, [x0]
- // ldr w3, [x0, #8]
- // str x2, [sp, #16]
- // str w3, [sp, #24]
- //
- // When the first instruction has a loReg that is the same register as the addrReg,
- // we set deferLoad to true and issue the intructions in the reverse order
- // ldr x3, [x2, #8]
- // ldr x2, [x2]
- // str x2, [sp, #16]
- // str x3, [sp, #24]
- //
-
- var_types nextType = compiler->getJitGCType(gcPtrs[nextIndex]);
- emitAttr nextAttr = emitTypeSize(nextType);
- regNumber curReg = loReg;
-
- bool deferLoad = false;
- var_types deferType = TYP_UNKNOWN;
- emitAttr deferAttr = EA_PTRSIZE;
- int deferOffset = 0;
-
- while (remainingSize > 0)
- {
- if (remainingSize >= TARGET_POINTER_SIZE)
- {
- remainingSize -= TARGET_POINTER_SIZE;
-
- if ((curReg == addrReg) && (remainingSize != 0))
- {
- deferLoad = true;
- deferType = nextType;
- deferAttr = emitTypeSize(nextType);
- deferOffset = structOffset;
- }
- else // the typical case
- {
- if (varNode != nullptr)
- {
- // Load from our varNumImp source
- emit->emitIns_R_S(ins_Load(nextType), nextAttr, curReg, varNumInp, structOffset);
- }
- else
- {
- // Load from our address expression source
- emit->emitIns_R_R_I(ins_Load(nextType), nextAttr, curReg, addrReg, structOffset);
- }
- // Emit a store instruction to store the register into the outgoing argument area
- emit->emitIns_S_R(ins_Store(nextType), nextAttr, curReg, varNumOut, argOffsetOut);
- argOffsetOut += EA_SIZE_IN_BYTES(nextAttr);
- assert(argOffsetOut <= argOffsetMax); // We can't write beyound the outgoing area area
- }
- curReg = hiReg;
- structOffset += TARGET_POINTER_SIZE;
- nextIndex++;
- nextType = compiler->getJitGCType(gcPtrs[nextIndex]);
- nextAttr = emitTypeSize(nextType);
- }
- else // (remainingSize < TARGET_POINTER_SIZE)
- {
- int loadSize = remainingSize;
- remainingSize = 0;
-
- // We should never have to do a non-pointer sized load when we have a LclVar source
- assert(varNode == nullptr);
-
- // the left over size is smaller than a pointer and thus can never be a GC type
- assert(varTypeIsGC(nextType) == false);
-
- var_types loadType = TYP_UINT;
- if (loadSize == 1)
- {
- loadType = TYP_UBYTE;
- }
- else if (loadSize == 2)
- {
- loadType = TYP_USHORT;
- }
- else
- {
- // Need to handle additional loadSize cases here
- noway_assert(loadSize == 4);
- }
-
- instruction loadIns = ins_Load(loadType);
- emitAttr loadAttr = emitAttr(loadSize);
-
- // When deferLoad is false, curReg can be the same as addrReg
- // because the last instruction is allowed to overwrite addrReg.
- //
- noway_assert(!deferLoad || (curReg != addrReg));
-
- emit->emitIns_R_R_I(loadIns, loadAttr, curReg, addrReg, structOffset);
-
- // Emit a store instruction to store the register into the outgoing argument area
- emit->emitIns_S_R(ins_Store(loadType), loadAttr, curReg, varNumOut, argOffsetOut);
- argOffsetOut += EA_SIZE_IN_BYTES(loadAttr);
- assert(argOffsetOut <= argOffsetMax); // We can't write beyound the outgoing area area
- }
- }
-
- if (deferLoad)
- {
- // We should never have to do a deferred load when we have a LclVar source
- assert(varNode == nullptr);
-
- curReg = addrReg;
-
- // Load from our address expression source
- emit->emitIns_R_R_I(ins_Load(deferType), deferAttr, curReg, addrReg, deferOffset);
-
- // Emit a store instruction to store the register into the outgoing argument area
- emit->emitIns_S_R(ins_Store(nextType), nextAttr, curReg, varNumOut, argOffsetOut);
- argOffsetOut += EA_SIZE_IN_BYTES(nextAttr);
- assert(argOffsetOut <= argOffsetMax); // We can't write beyound the outgoing area area
- }
- }
- }
-}
-
-/*****************************************************************************
- *
- * Create and record GC Info for the function.
- */
-void CodeGen::genCreateAndStoreGCInfo(unsigned codeSize,
- unsigned prologSize,
- unsigned epilogSize DEBUGARG(void* codePtr))
-{
- genCreateAndStoreGCInfoX64(codeSize, prologSize DEBUGARG(codePtr));
-}
-
-void CodeGen::genCreateAndStoreGCInfoX64(unsigned codeSize, unsigned prologSize DEBUGARG(void* codePtr))
-{
- IAllocator* allowZeroAlloc = new (compiler, CMK_GC) AllowZeroAllocator(compiler->getAllocatorGC());
- GcInfoEncoder* gcInfoEncoder = new (compiler, CMK_GC)
- GcInfoEncoder(compiler->info.compCompHnd, compiler->info.compMethodInfo, allowZeroAlloc, NOMEM);
- assert(gcInfoEncoder != nullptr);
-
- // Follow the code pattern of the x86 gc info encoder (genCreateAndStoreGCInfoJIT32).
- gcInfo.gcInfoBlockHdrSave(gcInfoEncoder, codeSize, prologSize);
-
- // First we figure out the encoder ID's for the stack slots and registers.
- gcInfo.gcMakeRegPtrTable(gcInfoEncoder, codeSize, prologSize, GCInfo::MAKE_REG_PTR_MODE_ASSIGN_SLOTS);
-
- // Now we've requested all the slots we'll need; "finalize" these (make more compact data structures for them).
- gcInfoEncoder->FinalizeSlotIds();
-
- // Now we can actually use those slot ID's to declare live ranges.
- gcInfo.gcMakeRegPtrTable(gcInfoEncoder, codeSize, prologSize, GCInfo::MAKE_REG_PTR_MODE_DO_WORK);
-
- if (compiler->opts.compDbgEnC)
- {
- // what we have to preserve is called the "frame header" (see comments in VM\eetwain.cpp)
- // which is:
- // -return address
- // -saved off RBP
- // -saved 'this' pointer and bool for synchronized methods
-
- // 4 slots for RBP + return address + RSI + RDI
- int preservedAreaSize = 4 * REGSIZE_BYTES;
-
- if (compiler->info.compFlags & CORINFO_FLG_SYNCH)
- {
- if (!(compiler->info.compFlags & CORINFO_FLG_STATIC))
- preservedAreaSize += REGSIZE_BYTES;
-
- preservedAreaSize += 1; // bool for synchronized methods
- }
-
- // Used to signal both that the method is compiled for EnC, and also the size of the block at the top of the
- // frame
- gcInfoEncoder->SetSizeOfEditAndContinuePreservedArea(preservedAreaSize);
- }
-
- gcInfoEncoder->Build();
-
- // GC Encoder automatically puts the GC info in the right spot using ICorJitInfo::allocGCInfo(size_t)
- // let's save the values anyway for debugging purposes
- compiler->compInfoBlkAddr = gcInfoEncoder->Emit();
- compiler->compInfoBlkSize = 0; // not exposed by the GCEncoder interface
-}
-
/*****************************************************************************
* Emit a call to a helper function.
*
diff --git a/src/jit/codegenarmarch.cpp b/src/jit/codegenarmarch.cpp
new file mode 100644
index 0000000000..af9fdfed9c
--- /dev/null
+++ b/src/jit/codegenarmarch.cpp
@@ -0,0 +1,1687 @@
+// 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.
+
+/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XX XX
+XX ARM/ARM64 Code Generator Common Code XX
+XX XX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+*/
+#include "jitpch.h"
+#ifdef _MSC_VER
+#pragma hdrstop
+#endif
+
+#ifndef LEGACY_BACKEND // This file is ONLY used for the RyuJIT backend that uses the linear scan register allocator
+
+#ifdef _TARGET_ARMARCH_ // This file is ONLY used for ARM and ARM64 architectures
+
+#include "codegen.h"
+#include "lower.h"
+#include "gcinfo.h"
+#include "emit.h"
+
+//------------------------------------------------------------------------
+// genSetRegToIcon: Generate code that will set the given register to the integer constant.
+//
+void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFlags flags)
+{
+ // Reg cannot be a FP reg
+ assert(!genIsValidFloatReg(reg));
+
+ // The only TYP_REF constant that can come this path is a managed 'null' since it is not
+ // relocatable. Other ref type constants (e.g. string objects) go through a different
+ // code path.
+ noway_assert(type != TYP_REF || val == 0);
+
+ instGen_Set_Reg_To_Imm(emitActualTypeSize(type), reg, val, flags);
+}
+
+//---------------------------------------------------------------------
+// genIntrinsic - generate code for a given intrinsic
+//
+// Arguments
+// treeNode - the GT_INTRINSIC node
+//
+// Return value:
+// None
+//
+void CodeGen::genIntrinsic(GenTreePtr treeNode)
+{
+ // Both operand and its result must be of the same floating point type.
+ GenTreePtr srcNode = treeNode->gtOp.gtOp1;
+ assert(varTypeIsFloating(srcNode));
+ assert(srcNode->TypeGet() == treeNode->TypeGet());
+
+ // Right now only Abs/Round/Sqrt are treated as math intrinsics.
+ //
+ switch (treeNode->gtIntrinsic.gtIntrinsicId)
+ {
+ case CORINFO_INTRINSIC_Abs:
+ genConsumeOperands(treeNode->AsOp());
+ getEmitter()->emitInsBinary(INS_ABS, emitTypeSize(treeNode), treeNode, srcNode);
+ break;
+
+ case CORINFO_INTRINSIC_Round:
+ NYI_ARM("genIntrinsic for round - not implemented yet");
+ genConsumeOperands(treeNode->AsOp());
+ getEmitter()->emitInsBinary(INS_ROUND, emitTypeSize(treeNode), treeNode, srcNode);
+ break;
+
+ case CORINFO_INTRINSIC_Sqrt:
+ genConsumeOperands(treeNode->AsOp());
+ getEmitter()->emitInsBinary(INS_SQRT, emitTypeSize(treeNode), treeNode, srcNode);
+ break;
+
+ default:
+ assert(!"genIntrinsic: Unsupported intrinsic");
+ unreached();
+ }
+
+ genProduceReg(treeNode);
+}
+
+//---------------------------------------------------------------------
+// genPutArgStk - generate code for a GT_PUTARG_STK node
+//
+// Arguments
+// treeNode - the GT_PUTARG_STK node
+//
+// Return value:
+// None
+//
+void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
+{
+ assert(treeNode->OperGet() == GT_PUTARG_STK);
+ var_types targetType = treeNode->TypeGet();
+ GenTreePtr source = treeNode->gtOp1;
+ emitter* emit = getEmitter();
+
+ // This is the varNum for our store operations,
+ // typically this is the varNum for the Outgoing arg space
+ // When we are generating a tail call it will be the varNum for arg0
+ unsigned varNumOut = (unsigned)-1;
+ unsigned argOffsetMax = (unsigned)-1; // Records the maximum size of this area for assert checks
+
+ // Get argument offset to use with 'varNumOut'
+ // Here we cross check that argument offset hasn't changed from lowering to codegen since
+ // we are storing arg slot number in GT_PUTARG_STK node in lowering phase.
+ unsigned argOffsetOut = treeNode->gtSlotNum * TARGET_POINTER_SIZE;
+
+#ifdef DEBUG
+ fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(treeNode->gtCall, treeNode);
+ assert(curArgTabEntry);
+ assert(argOffsetOut == (curArgTabEntry->slotNum * TARGET_POINTER_SIZE));
+#endif // DEBUG
+
+ // Whether to setup stk arg in incoming or out-going arg area?
+ // Fast tail calls implemented as epilog+jmp = stk arg is setup in incoming arg area.
+ // All other calls - stk arg is setup in out-going arg area.
+ if (treeNode->putInIncomingArgArea())
+ {
+ NYI_ARM("genPutArgStk: fast tail call");
+
+#ifdef _TARGET_ARM64_
+ varNumOut = getFirstArgWithStackSlot();
+ argOffsetMax = compiler->compArgSize;
+#if FEATURE_FASTTAILCALL
+ // This must be a fast tail call.
+ assert(treeNode->gtCall->IsFastTailCall());
+
+ // Since it is a fast tail call, the existence of first incoming arg is guaranteed
+ // because fast tail call requires that in-coming arg area of caller is >= out-going
+ // arg area required for tail call.
+ LclVarDsc* varDsc = &(compiler->lvaTable[varNumOut]);
+ assert(varDsc != nullptr);
+#endif // FEATURE_FASTTAILCALL
+#endif // _TARGET_ARM64_
+ }
+ else
+ {
+ varNumOut = compiler->lvaOutgoingArgSpaceVar;
+ argOffsetMax = compiler->lvaOutgoingArgSpaceSize;
+ }
+
+ bool isStruct = (targetType == TYP_STRUCT) || (source->OperGet() == GT_FIELD_LIST);
+
+ if (!isStruct) // a normal non-Struct argument
+ {
+ instruction storeIns = ins_Store(targetType);
+ emitAttr storeAttr = emitTypeSize(targetType);
+
+ // If it is contained then source must be the integer constant zero
+ if (source->isContained())
+ {
+ assert(source->OperGet() == GT_CNS_INT);
+ assert(source->AsIntConCommon()->IconValue() == 0);
+ NYI_ARM("genPutArgStk: contained zero source");
+
+#ifdef _TARGET_ARM64_
+ emit->emitIns_S_R(storeIns, storeAttr, REG_ZR, varNumOut, argOffsetOut);
+#endif // _TARGET_ARM64_
+ }
+ else
+ {
+ genConsumeReg(source);
+ emit->emitIns_S_R(storeIns, storeAttr, source->gtRegNum, varNumOut, argOffsetOut);
+ }
+ argOffsetOut += EA_SIZE_IN_BYTES(storeAttr);
+ assert(argOffsetOut <= argOffsetMax); // We can't write beyound the outgoing area area
+ }
+ else // We have some kind of a struct argument
+ {
+ assert(source->isContained()); // We expect that this node was marked as contained in Lower
+
+ if (source->OperGet() == GT_FIELD_LIST)
+ {
+ // Deal with the multi register passed struct args.
+ GenTreeFieldList* fieldListPtr = source->AsFieldList();
+
+ // Evaluate each of the GT_FIELD_LIST items into their register
+ // and store their register into the outgoing argument area
+ for (; fieldListPtr != nullptr; fieldListPtr = fieldListPtr->Rest())
+ {
+ GenTreePtr nextArgNode = fieldListPtr->gtOp.gtOp1;
+ genConsumeReg(nextArgNode);
+
+ regNumber reg = nextArgNode->gtRegNum;
+ var_types type = nextArgNode->TypeGet();
+ emitAttr attr = emitTypeSize(type);
+
+ // Emit store instructions to store the registers produced by the GT_FIELD_LIST into the outgoing
+ // argument area
+ emit->emitIns_S_R(ins_Store(type), attr, reg, varNumOut, argOffsetOut);
+ argOffsetOut += EA_SIZE_IN_BYTES(attr);
+ assert(argOffsetOut <= argOffsetMax); // We can't write beyound the outgoing area area
+ }
+ }
+ else // We must have a GT_OBJ or a GT_LCL_VAR
+ {
+ noway_assert((source->OperGet() == GT_LCL_VAR) || (source->OperGet() == GT_OBJ));
+
+ NYI_ARM("genPutArgStk: GT_OBJ or GT_LCL_VAR source of struct type");
+
+#ifdef _TARGET_ARM64_
+
+ var_types targetType = source->TypeGet();
+ noway_assert(varTypeIsStruct(targetType));
+
+ // We will copy this struct to the stack, possibly using a ldp instruction
+ // Setup loReg and hiReg from the internal registers that we reserved in lower.
+ //
+ regNumber loReg = REG_NA;
+ regNumber hiReg = REG_NA;
+ regNumber addrReg = REG_NA;
+
+ // In lowerArm64/TreeNodeInfoInitPutArgStk we have reserved two internal integer registers
+ genGetRegPairFromMask(treeNode->gtRsvdRegs, &loReg, &hiReg);
+
+ GenTreeLclVarCommon* varNode = nullptr;
+ GenTreePtr addrNode = nullptr;
+
+ if (source->OperGet() == GT_LCL_VAR)
+ {
+ varNode = source->AsLclVarCommon();
+ }
+ else // we must have a GT_OBJ
+ {
+ assert(source->OperGet() == GT_OBJ);
+
+ addrNode = source->gtOp.gtOp1;
+
+ // addrNode can either be a GT_LCL_VAR_ADDR or an address expression
+ //
+ if (addrNode->OperGet() == GT_LCL_VAR_ADDR)
+ {
+ // We have a GT_OBJ(GT_LCL_VAR_ADDR)
+ //
+ // We will treat this case the same as above
+ // (i.e if we just had this GT_LCL_VAR directly as the source)
+ // so update 'source' to point this GT_LCL_VAR_ADDR node
+ // and continue to the codegen for the LCL_VAR node below
+ //
+ varNode = addrNode->AsLclVarCommon();
+ addrNode = nullptr;
+ }
+ }
+
+ // Either varNode or addrNOde must have been setup above,
+ // the xor ensures that only one of the two is setup, not both
+ assert((varNode != nullptr) ^ (addrNode != nullptr));
+
+ BYTE gcPtrs[MAX_ARG_REG_COUNT] = {}; // TYPE_GC_NONE = 0
+ unsigned gcPtrCount; // The count of GC pointers in the struct
+ int structSize;
+ bool isHfa;
+
+ // This is the varNum for our load operations,
+ // only used when we have a multireg struct with a LclVar source
+ unsigned varNumInp = BAD_VAR_NUM;
+
+ // Setup the structSize, isHFa, and gcPtrCount
+ if (varNode != nullptr)
+ {
+ varNumInp = varNode->gtLclNum;
+ assert(varNumInp < compiler->lvaCount);
+ LclVarDsc* varDsc = &compiler->lvaTable[varNumInp];
+
+ assert(varDsc->lvType == TYP_STRUCT);
+ assert(varDsc->lvOnFrame); // This struct also must live in the stack frame
+ assert(!varDsc->lvRegister); // And it can't live in a register (SIMD)
+
+ structSize = varDsc->lvSize(); // This yields the roundUp size, but that is fine
+ // as that is how much stack is allocated for this LclVar
+ isHfa = varDsc->lvIsHfa();
+ gcPtrCount = varDsc->lvStructGcCount;
+ for (unsigned i = 0; i < gcPtrCount; ++i)
+ gcPtrs[i] = varDsc->lvGcLayout[i];
+ }
+ else // addrNode is used
+ {
+ assert(addrNode != nullptr);
+
+ // Generate code to load the address that we need into a register
+ genConsumeAddress(addrNode);
+ addrReg = addrNode->gtRegNum;
+
+ CORINFO_CLASS_HANDLE objClass = source->gtObj.gtClass;
+
+ structSize = compiler->info.compCompHnd->getClassSize(objClass);
+ isHfa = compiler->IsHfa(objClass);
+ gcPtrCount = compiler->info.compCompHnd->getClassGClayout(objClass, &gcPtrs[0]);
+ }
+
+ bool hasGCpointers = (gcPtrCount > 0); // true if there are any GC pointers in the struct
+
+ // If we have an HFA we can't have any GC pointers,
+ // if not then the max size for the the struct is 16 bytes
+ if (isHfa)
+ {
+ noway_assert(gcPtrCount == 0);
+ }
+ else
+ {
+ noway_assert(structSize <= 2 * TARGET_POINTER_SIZE);
+ }
+
+ noway_assert(structSize <= MAX_PASS_MULTIREG_BYTES);
+
+ // For a 16-byte structSize with GC pointers we will use two ldr and two str instructions
+ // ldr x2, [x0]
+ // ldr x3, [x0, #8]
+ // str x2, [sp, #16]
+ // str x3, [sp, #24]
+ //
+ // For a 16-byte structSize with no GC pointers we will use a ldp and two str instructions
+ // ldp x2, x3, [x0]
+ // str x2, [sp, #16]
+ // str x3, [sp, #24]
+ //
+ // For a 32-byte structSize with no GC pointers we will use two ldp and four str instructions
+ // ldp x2, x3, [x0]
+ // str x2, [sp, #16]
+ // str x3, [sp, #24]
+ // ldp x2, x3, [x0]
+ // str x2, [sp, #32]
+ // str x3, [sp, #40]
+ //
+ // Note that when loading from a varNode we currently can't use the ldp instruction
+ // TODO-ARM64-CQ: Implement support for using a ldp instruction with a varNum (see emitIns_R_S)
+ //
+
+ int remainingSize = structSize;
+ unsigned structOffset = 0;
+ unsigned nextIndex = 0;
+
+ while (remainingSize >= 2 * TARGET_POINTER_SIZE)
+ {
+ var_types type0 = compiler->getJitGCType(gcPtrs[nextIndex + 0]);
+ var_types type1 = compiler->getJitGCType(gcPtrs[nextIndex + 1]);
+
+ if (hasGCpointers)
+ {
+ // We have GC pointers, so use two ldr instructions
+ //
+ // We must do it this way because we can't currently pass or track
+ // two different emitAttr values for a ldp instruction.
+
+ // Make sure that the first load instruction does not overwrite the addrReg.
+ //
+ if (loReg != addrReg)
+ {
+ if (varNode != nullptr)
+ {
+ // Load from our varNumImp source
+ emit->emitIns_R_S(ins_Load(type0), emitTypeSize(type0), loReg, varNumInp, 0);
+ emit->emitIns_R_S(ins_Load(type1), emitTypeSize(type1), hiReg, varNumInp,
+ TARGET_POINTER_SIZE);
+ }
+ else
+ {
+ // Load from our address expression source
+ emit->emitIns_R_R_I(ins_Load(type0), emitTypeSize(type0), loReg, addrReg, structOffset);
+ emit->emitIns_R_R_I(ins_Load(type1), emitTypeSize(type1), hiReg, addrReg,
+ structOffset + TARGET_POINTER_SIZE);
+ }
+ }
+ else // loReg == addrReg
+ {
+ assert(varNode == nullptr); // because addrReg is REG_NA when varNode is non-null
+ assert(hiReg != addrReg);
+ // Load from our address expression source
+ emit->emitIns_R_R_I(ins_Load(type1), emitTypeSize(type1), hiReg, addrReg,
+ structOffset + TARGET_POINTER_SIZE);
+ emit->emitIns_R_R_I(ins_Load(type0), emitTypeSize(type0), loReg, addrReg, structOffset);
+ }
+ }
+ else // our struct has no GC pointers
+ {
+ if (varNode != nullptr)
+ {
+ // Load from our varNumImp source, currently we can't use a ldp instruction to do this
+ emit->emitIns_R_S(ins_Load(type0), emitTypeSize(type0), loReg, varNumInp, 0);
+ emit->emitIns_R_S(ins_Load(type1), emitTypeSize(type1), hiReg, varNumInp, TARGET_POINTER_SIZE);
+ }
+ else
+ {
+ // Use a ldp instruction
+
+ // Load from our address expression source
+ emit->emitIns_R_R_R_I(INS_ldp, EA_PTRSIZE, loReg, hiReg, addrReg, structOffset);
+ }
+ }
+
+ // Emit two store instructions to store the two registers into the outgoing argument area
+ emit->emitIns_S_R(ins_Store(type0), emitTypeSize(type0), loReg, varNumOut, argOffsetOut);
+ emit->emitIns_S_R(ins_Store(type1), emitTypeSize(type1), hiReg, varNumOut,
+ argOffsetOut + TARGET_POINTER_SIZE);
+ argOffsetOut += (2 * TARGET_POINTER_SIZE); // We stored 16-bytes of the struct
+ assert(argOffsetOut <= argOffsetMax); // We can't write beyound the outgoing area area
+
+ remainingSize -= (2 * TARGET_POINTER_SIZE); // We loaded 16-bytes of the struct
+ structOffset += (2 * TARGET_POINTER_SIZE);
+ nextIndex += 2;
+ }
+
+ // For a 12-byte structSize we will we will generate two load instructions
+ // ldr x2, [x0]
+ // ldr w3, [x0, #8]
+ // str x2, [sp, #16]
+ // str w3, [sp, #24]
+ //
+ // When the first instruction has a loReg that is the same register as the addrReg,
+ // we set deferLoad to true and issue the intructions in the reverse order
+ // ldr x3, [x2, #8]
+ // ldr x2, [x2]
+ // str x2, [sp, #16]
+ // str x3, [sp, #24]
+ //
+
+ var_types nextType = compiler->getJitGCType(gcPtrs[nextIndex]);
+ emitAttr nextAttr = emitTypeSize(nextType);
+ regNumber curReg = loReg;
+
+ bool deferLoad = false;
+ var_types deferType = TYP_UNKNOWN;
+ emitAttr deferAttr = EA_PTRSIZE;
+ int deferOffset = 0;
+
+ while (remainingSize > 0)
+ {
+ if (remainingSize >= TARGET_POINTER_SIZE)
+ {
+ remainingSize -= TARGET_POINTER_SIZE;
+
+ if ((curReg == addrReg) && (remainingSize != 0))
+ {
+ deferLoad = true;
+ deferType = nextType;
+ deferAttr = emitTypeSize(nextType);
+ deferOffset = structOffset;
+ }
+ else // the typical case
+ {
+ if (varNode != nullptr)
+ {
+ // Load from our varNumImp source
+ emit->emitIns_R_S(ins_Load(nextType), nextAttr, curReg, varNumInp, structOffset);
+ }
+ else
+ {
+ // Load from our address expression source
+ emit->emitIns_R_R_I(ins_Load(nextType), nextAttr, curReg, addrReg, structOffset);
+ }
+ // Emit a store instruction to store the register into the outgoing argument area
+ emit->emitIns_S_R(ins_Store(nextType), nextAttr, curReg, varNumOut, argOffsetOut);
+ argOffsetOut += EA_SIZE_IN_BYTES(nextAttr);
+ assert(argOffsetOut <= argOffsetMax); // We can't write beyound the outgoing area area
+ }
+ curReg = hiReg;
+ structOffset += TARGET_POINTER_SIZE;
+ nextIndex++;
+ nextType = compiler->getJitGCType(gcPtrs[nextIndex]);
+ nextAttr = emitTypeSize(nextType);
+ }
+ else // (remainingSize < TARGET_POINTER_SIZE)
+ {
+ int loadSize = remainingSize;
+ remainingSize = 0;
+
+ // We should never have to do a non-pointer sized load when we have a LclVar source
+ assert(varNode == nullptr);
+
+ // the left over size is smaller than a pointer and thus can never be a GC type
+ assert(varTypeIsGC(nextType) == false);
+
+ var_types loadType = TYP_UINT;
+ if (loadSize == 1)
+ {
+ loadType = TYP_UBYTE;
+ }
+ else if (loadSize == 2)
+ {
+ loadType = TYP_USHORT;
+ }
+ else
+ {
+ // Need to handle additional loadSize cases here
+ noway_assert(loadSize == 4);
+ }
+
+ instruction loadIns = ins_Load(loadType);
+ emitAttr loadAttr = emitAttr(loadSize);
+
+ // When deferLoad is false, curReg can be the same as addrReg
+ // because the last instruction is allowed to overwrite addrReg.
+ //
+ noway_assert(!deferLoad || (curReg != addrReg));
+
+ emit->emitIns_R_R_I(loadIns, loadAttr, curReg, addrReg, structOffset);
+
+ // Emit a store instruction to store the register into the outgoing argument area
+ emit->emitIns_S_R(ins_Store(loadType), loadAttr, curReg, varNumOut, argOffsetOut);
+ argOffsetOut += EA_SIZE_IN_BYTES(loadAttr);
+ assert(argOffsetOut <= argOffsetMax); // We can't write beyound the outgoing area area
+ }
+ }
+
+ if (deferLoad)
+ {
+ // We should never have to do a deferred load when we have a LclVar source
+ assert(varNode == nullptr);
+
+ curReg = addrReg;
+
+ // Load from our address expression source
+ emit->emitIns_R_R_I(ins_Load(deferType), deferAttr, curReg, addrReg, deferOffset);
+
+ // Emit a store instruction to store the register into the outgoing argument area
+ emit->emitIns_S_R(ins_Store(nextType), nextAttr, curReg, varNumOut, argOffsetOut);
+ argOffsetOut += EA_SIZE_IN_BYTES(nextAttr);
+ assert(argOffsetOut <= argOffsetMax); // We can't write beyound the outgoing area area
+ }
+
+#endif // _TARGET_ARM64_
+ }
+ }
+}
+
+//----------------------------------------------------------------------------------
+// genMultiRegCallStoreToLocal: store multi-reg return value of a call node to a local
+//
+// Arguments:
+// treeNode - Gentree of GT_STORE_LCL_VAR
+//
+// Return Value:
+// None
+//
+// Assumption:
+// The child of store is a multi-reg call node.
+// genProduceReg() on treeNode is made by caller of this routine.
+//
+void CodeGen::genMultiRegCallStoreToLocal(GenTreePtr treeNode)
+{
+ assert(treeNode->OperGet() == GT_STORE_LCL_VAR);
+
+#if defined(_TARGET_ARM_)
+ // Longs are returned in two return registers on Arm32.
+ assert(varTypeIsLong(treeNode));
+#elif defined(_TARGET_ARM64_)
+ // Structs of size >=9 and <=16 are returned in two return registers on ARM64 and HFAs.
+ assert(varTypeIsStruct(treeNode));
+#endif // _TARGET_*
+
+ // Assumption: current implementation requires that a multi-reg
+ // var in 'var = call' is flagged as lvIsMultiRegRet to prevent it from
+ // being promoted.
+ unsigned lclNum = treeNode->AsLclVarCommon()->gtLclNum;
+ LclVarDsc* varDsc = &(compiler->lvaTable[lclNum]);
+ noway_assert(varDsc->lvIsMultiRegRet);
+
+ GenTree* op1 = treeNode->gtGetOp1();
+ GenTree* actualOp1 = op1->gtSkipReloadOrCopy();
+ GenTreeCall* call = actualOp1->AsCall();
+ assert(call->HasMultiRegRetVal());
+
+ genConsumeRegs(op1);
+
+ ReturnTypeDesc* pRetTypeDesc = call->GetReturnTypeDesc();
+ unsigned regCount = pRetTypeDesc->GetReturnRegCount();
+
+ if (treeNode->gtRegNum != REG_NA)
+ {
+ // Right now the only enregistrable multi-reg return types supported are SIMD types.
+ assert(varTypeIsSIMD(treeNode));
+ NYI("GT_STORE_LCL_VAR of a SIMD enregisterable struct");
+ }
+ else
+ {
+ // Stack store
+ int offset = 0;
+ for (unsigned i = 0; i < regCount; ++i)
+ {
+ var_types type = pRetTypeDesc->GetReturnRegType(i);
+ regNumber reg = call->GetRegNumByIdx(i);
+ if (op1->IsCopyOrReload())
+ {
+ // GT_COPY/GT_RELOAD will have valid reg for those positions
+ // that need to be copied or reloaded.
+ regNumber reloadReg = op1->AsCopyOrReload()->GetRegNumByIdx(i);
+ if (reloadReg != REG_NA)
+ {
+ reg = reloadReg;
+ }
+ }
+
+ assert(reg != REG_NA);
+ getEmitter()->emitIns_S_R(ins_Store(type), emitTypeSize(type), reg, lclNum, offset);
+ offset += genTypeSize(type);
+ }
+
+ varDsc->lvRegNum = REG_STK;
+ }
+}
+
+//------------------------------------------------------------------------
+// genRangeCheck: generate code for GT_ARR_BOUNDS_CHECK node.
+//
+void CodeGen::genRangeCheck(GenTreePtr oper)
+{
+#ifdef FEATURE_SIMD
+ noway_assert(oper->OperGet() == GT_ARR_BOUNDS_CHECK || oper->OperGet() == GT_SIMD_CHK);
+#else // !FEATURE_SIMD
+ noway_assert(oper->OperGet() == GT_ARR_BOUNDS_CHECK);
+#endif // !FEATURE_SIMD
+
+ GenTreeBoundsChk* bndsChk = oper->AsBoundsChk();
+
+ GenTreePtr arrLen = bndsChk->gtArrLen;
+ GenTreePtr arrIndex = bndsChk->gtIndex;
+ GenTreePtr arrRef = NULL;
+ int lenOffset = 0;
+
+ GenTree* src1;
+ GenTree* src2;
+ emitJumpKind jmpKind;
+
+ genConsumeRegs(arrIndex);
+ genConsumeRegs(arrLen);
+
+ if (arrIndex->isContainedIntOrIImmed())
+ {
+ // To encode using a cmp immediate, we place the
+ // constant operand in the second position
+ src1 = arrLen;
+ src2 = arrIndex;
+ jmpKind = genJumpKindForOper(GT_LE, CK_UNSIGNED);
+ }
+ else
+ {
+ src1 = arrIndex;
+ src2 = arrLen;
+ jmpKind = genJumpKindForOper(GT_GE, CK_UNSIGNED);
+ }
+
+ getEmitter()->emitInsBinary(INS_cmp, EA_4BYTE, src1, src2);
+ genJumpToThrowHlpBlk(jmpKind, SCK_RNGCHK_FAIL, bndsChk->gtIndRngFailBB);
+}
+
+//------------------------------------------------------------------------
+// genOffsetOfMDArrayLowerBound: Returns the offset from the Array object to the
+// lower bound for the given dimension.
+//
+// Arguments:
+// elemType - the element type of the array
+// rank - the rank of the array
+// dimension - the dimension for which the lower bound offset will be returned.
+//
+// Return Value:
+// The offset.
+// TODO-Cleanup: move to CodeGenCommon.cpp
+
+// static
+unsigned CodeGen::genOffsetOfMDArrayLowerBound(var_types elemType, unsigned rank, unsigned dimension)
+{
+ // Note that the lower bound and length fields of the Array object are always TYP_INT
+ return compiler->eeGetArrayDataOffset(elemType) + genTypeSize(TYP_INT) * (dimension + rank);
+}
+
+//------------------------------------------------------------------------
+// genOffsetOfMDArrayLength: Returns the offset from the Array object to the
+// size for the given dimension.
+//
+// Arguments:
+// elemType - the element type of the array
+// rank - the rank of the array
+// dimension - the dimension for which the lower bound offset will be returned.
+//
+// Return Value:
+// The offset.
+// TODO-Cleanup: move to CodeGenCommon.cpp
+
+// static
+unsigned CodeGen::genOffsetOfMDArrayDimensionSize(var_types elemType, unsigned rank, unsigned dimension)
+{
+ // Note that the lower bound and length fields of the Array object are always TYP_INT
+ return compiler->eeGetArrayDataOffset(elemType) + genTypeSize(TYP_INT) * dimension;
+}
+
+//------------------------------------------------------------------------
+// genCodeForArrIndex: Generates code to bounds check the index for one dimension of an array reference,
+// producing the effective index by subtracting the lower bound.
+//
+// Arguments:
+// arrIndex - the node for which we're generating code
+//
+// Return Value:
+// None.
+//
+void CodeGen::genCodeForArrIndex(GenTreeArrIndex* arrIndex)
+{
+ emitter* emit = getEmitter();
+ GenTreePtr arrObj = arrIndex->ArrObj();
+ GenTreePtr indexNode = arrIndex->IndexExpr();
+ regNumber arrReg = genConsumeReg(arrObj);
+ regNumber indexReg = genConsumeReg(indexNode);
+ regNumber tgtReg = arrIndex->gtRegNum;
+ noway_assert(tgtReg != REG_NA);
+
+ // We will use a temp register to load the lower bound and dimension size values
+ //
+ regMaskTP tmpRegsMask = arrIndex->gtRsvdRegs; // there will be two bits set
+ tmpRegsMask &= ~genRegMask(tgtReg); // remove the bit for 'tgtReg' from 'tmpRegsMask'
+
+ regMaskTP tmpRegMask = genFindLowestBit(tmpRegsMask); // set tmpRegMsk to a one-bit mask
+ regNumber tmpReg = genRegNumFromMask(tmpRegMask); // set tmpReg from that mask
+ noway_assert(tmpReg != REG_NA);
+
+ assert(tgtReg != tmpReg);
+
+ unsigned dim = arrIndex->gtCurrDim;
+ unsigned rank = arrIndex->gtArrRank;
+ var_types elemType = arrIndex->gtArrElemType;
+ unsigned offset;
+
+ offset = genOffsetOfMDArrayLowerBound(elemType, rank, dim);
+ emit->emitIns_R_R_I(ins_Load(TYP_INT), EA_PTRSIZE, tmpReg, arrReg, offset); // a 4 BYTE sign extending load
+ emit->emitIns_R_R_R(INS_sub, EA_4BYTE, tgtReg, indexReg, tmpReg);
+
+ offset = genOffsetOfMDArrayDimensionSize(elemType, rank, dim);
+ emit->emitIns_R_R_I(ins_Load(TYP_INT), EA_PTRSIZE, tmpReg, arrReg, offset); // a 4 BYTE sign extending load
+ emit->emitIns_R_R(INS_cmp, EA_4BYTE, tgtReg, tmpReg);
+
+ emitJumpKind jmpGEU = genJumpKindForOper(GT_GE, CK_UNSIGNED);
+ genJumpToThrowHlpBlk(jmpGEU, SCK_RNGCHK_FAIL);
+
+ genProduceReg(arrIndex);
+}
+
+//------------------------------------------------------------------------
+// genCodeForArrOffset: Generates code to compute the flattened array offset for
+// one dimension of an array reference:
+// result = (prevDimOffset * dimSize) + effectiveIndex
+// where dimSize is obtained from the arrObj operand
+//
+// Arguments:
+// arrOffset - the node for which we're generating code
+//
+// Return Value:
+// None.
+//
+// Notes:
+// dimSize and effectiveIndex are always non-negative, the former by design,
+// and the latter because it has been normalized to be zero-based.
+
+void CodeGen::genCodeForArrOffset(GenTreeArrOffs* arrOffset)
+{
+ GenTreePtr offsetNode = arrOffset->gtOffset;
+ GenTreePtr indexNode = arrOffset->gtIndex;
+ regNumber tgtReg = arrOffset->gtRegNum;
+
+ noway_assert(tgtReg != REG_NA);
+
+ if (!offsetNode->IsIntegralConst(0))
+ {
+ emitter* emit = getEmitter();
+ regNumber offsetReg = genConsumeReg(offsetNode);
+ regNumber indexReg = genConsumeReg(indexNode);
+ regNumber arrReg = genConsumeReg(arrOffset->gtArrObj);
+ noway_assert(offsetReg != REG_NA);
+ noway_assert(indexReg != REG_NA);
+ noway_assert(arrReg != REG_NA);
+
+ regMaskTP tmpRegMask = arrOffset->gtRsvdRegs;
+ regNumber tmpReg = genRegNumFromMask(tmpRegMask);
+ noway_assert(tmpReg != REG_NA);
+
+ unsigned dim = arrOffset->gtCurrDim;
+ unsigned rank = arrOffset->gtArrRank;
+ var_types elemType = arrOffset->gtArrElemType;
+ unsigned offset = genOffsetOfMDArrayDimensionSize(elemType, rank, dim);
+
+// Load tmpReg with the dimension size and evaluate
+// tgtReg = offsetReg*dim_size + indexReg.
+#if defined(_TARGET_ARM_)
+ emit->emitIns_R_R_I(ins_Load(TYP_INT), EA_4BYTE, tmpReg, arrReg, offset); // a 4 BYTE sign extending load
+ emit->emitIns_R_R_R(INS_MUL, EA_4BYTE, tgtReg, tmpReg, offsetReg);
+ emit->emitIns_R_R_R(INS_add, EA_4BYTE, tgtReg, tgtReg, indexReg);
+#elif defined(_TARGET_ARM64_)
+ emit->emitIns_R_R_I(ins_Load(TYP_INT), EA_8BYTE, tmpReg, arrReg, offset); // a 4 BYTE sign extending load
+ emit->emitIns_R_R_R_R(INS_madd, EA_4BYTE, tgtReg, tmpReg, offsetReg, indexReg);
+#endif // _TARGET_*
+ }
+ else
+ {
+ regNumber indexReg = genConsumeReg(indexNode);
+ if (indexReg != tgtReg)
+ {
+ inst_RV_RV(INS_mov, tgtReg, indexReg, TYP_INT);
+ }
+ }
+ genProduceReg(arrOffset);
+}
+
+//------------------------------------------------------------------------
+// indirForm: Make a temporary indir we can feed to pattern matching routines
+// in cases where we don't want to instantiate all the indirs that happen.
+//
+GenTreeIndir CodeGen::indirForm(var_types type, GenTree* base)
+{
+ GenTreeIndir i(GT_IND, type, base, nullptr);
+ i.gtRegNum = REG_NA;
+ // has to be nonnull (because contained nodes can't be the last in block)
+ // but don't want it to be a valid pointer
+ i.gtNext = (GenTree*)(-1);
+ return i;
+}
+
+//------------------------------------------------------------------------
+// intForm: Make a temporary int we can feed to pattern matching routines
+// in cases where we don't want to instantiate.
+//
+GenTreeIntCon CodeGen::intForm(var_types type, ssize_t value)
+{
+ GenTreeIntCon i(type, value);
+ i.gtRegNum = REG_NA;
+ // has to be nonnull (because contained nodes can't be the last in block)
+ // but don't want it to be a valid pointer
+ i.gtNext = (GenTree*)(-1);
+ return i;
+}
+
+//------------------------------------------------------------------------
+// genCodeForShift: Generates the code sequence for a GenTree node that
+// represents a bit shift or rotate operation (<<, >>, >>>, rol, ror).
+//
+// Arguments:
+// tree - the bit shift node (that specifies the type of bit shift to perform).
+//
+// Assumptions:
+// a) All GenTrees are register allocated.
+//
+void CodeGen::genCodeForShift(GenTreePtr tree)
+{
+ var_types targetType = tree->TypeGet();
+ genTreeOps oper = tree->OperGet();
+ instruction ins = genGetInsForOper(oper, targetType);
+ emitAttr size = emitTypeSize(tree);
+
+ assert(tree->gtRegNum != REG_NA);
+
+ genConsumeOperands(tree->AsOp());
+
+ GenTreePtr operand = tree->gtGetOp1();
+ GenTreePtr shiftBy = tree->gtGetOp2();
+ if (!shiftBy->IsCnsIntOrI())
+ {
+ getEmitter()->emitIns_R_R_R(ins, size, tree->gtRegNum, operand->gtRegNum, shiftBy->gtRegNum);
+ }
+ else
+ {
+ unsigned immWidth = emitter::getBitWidth(size); // For ARM64, immWidth will be set to 32 or 64
+ ssize_t shiftByImm = shiftBy->gtIntCon.gtIconVal & (immWidth - 1);
+
+ getEmitter()->emitIns_R_R_I(ins, size, tree->gtRegNum, operand->gtRegNum, shiftByImm);
+ }
+
+ genProduceReg(tree);
+}
+
+// Generate code for a CpBlk node by the means of the VM memcpy helper call
+// Preconditions:
+// a) The size argument of the CpBlk is not an integer constant
+// b) The size argument is a constant but is larger than CPBLK_MOVS_LIMIT bytes.
+void CodeGen::genCodeForCpBlk(GenTreeBlk* cpBlkNode)
+{
+ // Make sure we got the arguments of the cpblk operation in the right registers
+ unsigned blockSize = cpBlkNode->Size();
+ GenTreePtr dstAddr = cpBlkNode->Addr();
+ assert(!dstAddr->isContained());
+
+ genConsumeBlockOp(cpBlkNode, REG_ARG_0, REG_ARG_1, REG_ARG_2);
+
+#ifdef _TARGET_ARM64_
+ if (blockSize != 0)
+ {
+ assert(blockSize > CPBLK_UNROLL_LIMIT);
+ }
+#endif // _TARGET_ARM64_
+
+ genEmitHelperCall(CORINFO_HELP_MEMCPY, 0, EA_UNKNOWN);
+}
+
+// Generates code for InitBlk by calling the VM memset helper function.
+// Preconditions:
+// a) The size argument of the InitBlk is not an integer constant.
+// b) The size argument of the InitBlk is >= INITBLK_STOS_LIMIT bytes.
+void CodeGen::genCodeForInitBlk(GenTreeBlk* initBlkNode)
+{
+ // Make sure we got the arguments of the initblk operation in the right registers
+ unsigned size = initBlkNode->Size();
+ GenTreePtr dstAddr = initBlkNode->Addr();
+ GenTreePtr initVal = initBlkNode->Data();
+ if (initVal->OperIsInitVal())
+ {
+ initVal = initVal->gtGetOp1();
+ }
+
+ assert(!dstAddr->isContained());
+ assert(!initVal->isContained());
+ if (initBlkNode->gtOper == GT_STORE_DYN_BLK)
+ {
+ assert(initBlkNode->AsDynBlk()->gtDynamicSize->gtRegNum == REG_ARG_2);
+ }
+ else
+ {
+ assert(initBlkNode->gtRsvdRegs == RBM_ARG_2);
+ }
+
+#ifdef _TARGET_ARM64_
+ if (size != 0)
+ {
+ assert(size > INITBLK_UNROLL_LIMIT);
+ }
+#endif // _TARGET_ARM64_
+
+ genConsumeBlockOp(initBlkNode, REG_ARG_0, REG_ARG_1, REG_ARG_2);
+ genEmitHelperCall(CORINFO_HELP_MEMSET, 0, EA_UNKNOWN);
+}
+
+//------------------------------------------------------------------------
+// genRegCopy: Generate a register copy.
+//
+void CodeGen::genRegCopy(GenTree* treeNode)
+{
+ assert(treeNode->OperGet() == GT_COPY);
+
+ var_types targetType = treeNode->TypeGet();
+ regNumber targetReg = treeNode->gtRegNum;
+ assert(targetReg != REG_NA);
+
+ GenTree* op1 = treeNode->gtOp.gtOp1;
+
+ // Check whether this node and the node from which we're copying the value have the same
+ // register type.
+ // This can happen if (currently iff) we have a SIMD vector type that fits in an integer
+ // register, in which case it is passed as an argument, or returned from a call,
+ // in an integer register and must be copied if it's in an xmm register.
+
+ if (varTypeIsFloating(treeNode) != varTypeIsFloating(op1))
+ {
+ NYI_ARM("genRegCopy floating point");
+#ifdef _TARGET_ARM64_
+ inst_RV_RV(INS_fmov, targetReg, genConsumeReg(op1), targetType);
+#endif // _TARGET_ARM64_
+ }
+ else
+ {
+ inst_RV_RV(ins_Copy(targetType), targetReg, genConsumeReg(op1), targetType);
+ }
+
+ if (op1->IsLocal())
+ {
+ // The lclVar will never be a def.
+ // If it is a last use, the lclVar will be killed by genConsumeReg(), as usual, and genProduceReg will
+ // appropriately set the gcInfo for the copied value.
+ // If not, there are two cases we need to handle:
+ // - If this is a TEMPORARY copy (indicated by the GTF_VAR_DEATH flag) the variable
+ // will remain live in its original register.
+ // genProduceReg() will appropriately set the gcInfo for the copied value,
+ // and genConsumeReg will reset it.
+ // - Otherwise, we need to update register info for the lclVar.
+
+ GenTreeLclVarCommon* lcl = op1->AsLclVarCommon();
+ assert((lcl->gtFlags & GTF_VAR_DEF) == 0);
+
+ if ((lcl->gtFlags & GTF_VAR_DEATH) == 0 && (treeNode->gtFlags & GTF_VAR_DEATH) == 0)
+ {
+ LclVarDsc* varDsc = &compiler->lvaTable[lcl->gtLclNum];
+
+ // If we didn't just spill it (in genConsumeReg, above), then update the register info
+ if (varDsc->lvRegNum != REG_STK)
+ {
+ // The old location is dying
+ genUpdateRegLife(varDsc, /*isBorn*/ false, /*isDying*/ true DEBUGARG(op1));
+
+ gcInfo.gcMarkRegSetNpt(genRegMask(op1->gtRegNum));
+
+ genUpdateVarReg(varDsc, treeNode);
+
+ // The new location is going live
+ genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(treeNode));
+ }
+ }
+ }
+
+ genProduceReg(treeNode);
+}
+
+//------------------------------------------------------------------------
+// genCallInstruction: Produce code for a GT_CALL node
+//
+void CodeGen::genCallInstruction(GenTreeCall* call)
+{
+ gtCallTypes callType = (gtCallTypes)call->gtCallType;
+
+ IL_OFFSETX ilOffset = BAD_IL_OFFSET;
+
+ // all virtuals should have been expanded into a control expression
+ assert(!call->IsVirtual() || call->gtControlExpr || call->gtCallAddr);
+
+ // Consume all the arg regs
+ for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext())
+ {
+ assert(list->OperIsList());
+
+ GenTreePtr argNode = list->Current();
+
+ fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, argNode->gtSkipReloadOrCopy());
+ assert(curArgTabEntry);
+
+ if (curArgTabEntry->regNum == REG_STK)
+ continue;
+
+ // Deal with multi register passed struct args.
+ if (argNode->OperGet() == GT_FIELD_LIST)
+ {
+ GenTreeArgList* argListPtr = argNode->AsArgList();
+ unsigned iterationNum = 0;
+ regNumber argReg = curArgTabEntry->regNum;
+ for (; argListPtr != nullptr; argListPtr = argListPtr->Rest(), iterationNum++)
+ {
+ GenTreePtr putArgRegNode = argListPtr->gtOp.gtOp1;
+ assert(putArgRegNode->gtOper == GT_PUTARG_REG);
+
+ genConsumeReg(putArgRegNode);
+
+ if (putArgRegNode->gtRegNum != argReg)
+ {
+ inst_RV_RV(ins_Move_Extend(putArgRegNode->TypeGet(), putArgRegNode->InReg()), argReg,
+ putArgRegNode->gtRegNum);
+ }
+
+ argReg = genRegArgNext(argReg);
+ }
+ }
+ else
+ {
+ regNumber argReg = curArgTabEntry->regNum;
+ genConsumeReg(argNode);
+ if (argNode->gtRegNum != argReg)
+ {
+ inst_RV_RV(ins_Move_Extend(argNode->TypeGet(), argNode->InReg()), argReg, argNode->gtRegNum);
+ }
+ }
+
+ // In the case of a varargs call,
+ // the ABI dictates that if we have floating point args,
+ // we must pass the enregistered arguments in both the
+ // integer and floating point registers so, let's do that.
+ if (call->IsVarargs() && varTypeIsFloating(argNode))
+ {
+ NYI_ARM("CodeGen - IsVarargs");
+ NYI_ARM64("CodeGen - IsVarargs");
+ }
+ }
+
+ // Insert a null check on "this" pointer if asked.
+ if (call->NeedsNullCheck())
+ {
+ const regNumber regThis = genGetThisArgReg(call);
+
+#if defined(_TARGET_ARM_)
+ regMaskTP tempMask = genFindLowestBit(call->gtRsvdRegs);
+ const regNumber tmpReg = genRegNumFromMask(tempMask);
+ if (genCountBits(call->gtRsvdRegs) > 1)
+ {
+ call->gtRsvdRegs &= ~tempMask;
+ }
+ getEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, tmpReg, regThis, 0);
+#elif defined(_TARGET_ARM64_)
+ getEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, REG_ZR, regThis, 0);
+#endif // _TARGET_*
+ }
+
+ // Either gtControlExpr != null or gtCallAddr != null or it is a direct non-virtual call to a user or helper method.
+ CORINFO_METHOD_HANDLE methHnd;
+ GenTree* target = call->gtControlExpr;
+ if (callType == CT_INDIRECT)
+ {
+ assert(target == nullptr);
+ target = call->gtCallAddr;
+ methHnd = nullptr;
+ }
+ else
+ {
+ methHnd = call->gtCallMethHnd;
+ }
+
+ CORINFO_SIG_INFO* sigInfo = nullptr;
+#ifdef DEBUG
+ // Pass the call signature information down into the emitter so the emitter can associate
+ // native call sites with the signatures they were generated from.
+ if (callType != CT_HELPER)
+ {
+ sigInfo = call->callSig;
+ }
+#endif // DEBUG
+
+ // If fast tail call, then we are done. In this case we setup the args (both reg args
+ // and stack args in incoming arg area) and call target. Epilog sequence would
+ // generate "br <reg>".
+ if (call->IsFastTailCall())
+ {
+ // Don't support fast tail calling JIT helpers
+ assert(callType != CT_HELPER);
+
+ // Fast tail calls materialize call target either in gtControlExpr or in gtCallAddr.
+ assert(target != nullptr);
+
+ genConsumeReg(target);
+
+ NYI_ARM("fast tail call");
+
+#ifdef _TARGET_ARM64_
+ // Use IP0 as the call target register.
+ if (target->gtRegNum != REG_IP0)
+ {
+ inst_RV_RV(INS_mov, REG_IP0, target->gtRegNum);
+ }
+#endif // _TARGET_ARM64_
+
+ return;
+ }
+
+ // For a pinvoke to unmanaged code we emit a label to clear
+ // the GC pointer state before the callsite.
+ // We can't utilize the typical lazy killing of GC pointers
+ // at (or inside) the callsite.
+ if (call->IsUnmanaged())
+ {
+ genDefineTempLabel(genCreateTempLabel());
+ }
+
+ // Determine return value size(s).
+ ReturnTypeDesc* pRetTypeDesc = call->GetReturnTypeDesc();
+ emitAttr retSize = EA_PTRSIZE;
+ emitAttr secondRetSize = EA_UNKNOWN;
+
+ if (call->HasMultiRegRetVal())
+ {
+ retSize = emitTypeSize(pRetTypeDesc->GetReturnRegType(0));
+ secondRetSize = emitTypeSize(pRetTypeDesc->GetReturnRegType(1));
+ }
+ else
+ {
+ assert(!varTypeIsStruct(call));
+
+ if (call->gtType == TYP_REF || call->gtType == TYP_ARRAY)
+ {
+ retSize = EA_GCREF;
+ }
+ else if (call->gtType == TYP_BYREF)
+ {
+ retSize = EA_BYREF;
+ }
+ }
+
+ // We need to propagate the IL offset information to the call instruction, so we can emit
+ // an IL to native mapping record for the call, to support managed return value debugging.
+ // We don't want tail call helper calls that were converted from normal calls to get a record,
+ // so we skip this hash table lookup logic in that case.
+ if (compiler->opts.compDbgInfo && compiler->genCallSite2ILOffsetMap != nullptr && !call->IsTailCall())
+ {
+ (void)compiler->genCallSite2ILOffsetMap->Lookup(call, &ilOffset);
+ }
+
+ if (target != nullptr)
+ {
+ // A call target can not be a contained indirection
+ assert(!target->isContainedIndir());
+
+ genConsumeReg(target);
+
+ // We have already generated code for gtControlExpr evaluating it into a register.
+ // We just need to emit "call reg" in this case.
+ //
+ assert(genIsValidIntReg(target->gtRegNum));
+
+ genEmitCall(emitter::EC_INDIR_R, methHnd,
+ INDEBUG_LDISASM_COMMA(sigInfo) nullptr, // addr
+ retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize), ilOffset, target->gtRegNum);
+ }
+ else
+ {
+ // Generate a direct call to a non-virtual user defined or helper method
+ assert(callType == CT_HELPER || callType == CT_USER_FUNC);
+
+ void* addr = nullptr;
+ if (callType == CT_HELPER)
+ {
+ // Direct call to a helper method.
+ CorInfoHelpFunc helperNum = compiler->eeGetHelperNum(methHnd);
+ noway_assert(helperNum != CORINFO_HELP_UNDEF);
+
+ void* pAddr = nullptr;
+ addr = compiler->compGetHelperFtn(helperNum, (void**)&pAddr);
+
+ if (addr == nullptr)
+ {
+ addr = pAddr;
+ }
+ }
+ else
+ {
+ // Direct call to a non-virtual user function.
+ CORINFO_ACCESS_FLAGS aflags = CORINFO_ACCESS_ANY;
+ if (call->IsSameThis())
+ {
+ aflags = (CORINFO_ACCESS_FLAGS)(aflags | CORINFO_ACCESS_THIS);
+ }
+
+ if ((call->NeedsNullCheck()) == 0)
+ {
+ aflags = (CORINFO_ACCESS_FLAGS)(aflags | CORINFO_ACCESS_NONNULL);
+ }
+
+ CORINFO_CONST_LOOKUP addrInfo;
+ compiler->info.compCompHnd->getFunctionEntryPoint(methHnd, &addrInfo, aflags);
+
+ addr = addrInfo.addr;
+ }
+
+ assert(addr != nullptr);
+
+// Non-virtual direct call to known addresses
+#ifdef _TARGET_ARM_
+ if (!arm_Valid_Imm_For_BL((ssize_t)addr))
+ {
+ regNumber tmpReg = genRegNumFromMask(call->gtRsvdRegs);
+ instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, tmpReg, (ssize_t)addr);
+ genEmitCall(emitter::EC_INDIR_R, methHnd, INDEBUG_LDISASM_COMMA(sigInfo) NULL, retSize, ilOffset, tmpReg);
+ }
+ else
+#endif // _TARGET_ARM_
+ {
+ genEmitCall(emitter::EC_FUNC_TOKEN, methHnd, INDEBUG_LDISASM_COMMA(sigInfo) addr,
+ retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize), ilOffset);
+ }
+
+#if 0 && defined(_TARGET_ARM64_)
+ // Use this path if you want to load an absolute call target using
+ // a sequence of movs followed by an indirect call (blr instruction)
+
+ // Load the call target address in x16
+ instGen_Set_Reg_To_Imm(EA_8BYTE, REG_IP0, (ssize_t) addr);
+
+ // indirect call to constant address in IP0
+ genEmitCall(emitter::EC_INDIR_R,
+ methHnd,
+ INDEBUG_LDISASM_COMMA(sigInfo)
+ nullptr, //addr
+ retSize,
+ secondRetSize,
+ ilOffset,
+ REG_IP0);
+#endif
+ }
+
+ // if it was a pinvoke we may have needed to get the address of a label
+ if (genPendingCallLabel)
+ {
+ assert(call->IsUnmanaged());
+ genDefineTempLabel(genPendingCallLabel);
+ genPendingCallLabel = nullptr;
+ }
+
+ // Update GC info:
+ // All Callee arg registers are trashed and no longer contain any GC pointers.
+ // TODO-Bug?: As a matter of fact shouldn't we be killing all of callee trashed regs here?
+ // For now we will assert that other than arg regs gc ref/byref set doesn't contain any other
+ // registers from RBM_CALLEE_TRASH
+ assert((gcInfo.gcRegGCrefSetCur & (RBM_CALLEE_TRASH & ~RBM_ARG_REGS)) == 0);
+ assert((gcInfo.gcRegByrefSetCur & (RBM_CALLEE_TRASH & ~RBM_ARG_REGS)) == 0);
+ gcInfo.gcRegGCrefSetCur &= ~RBM_ARG_REGS;
+ gcInfo.gcRegByrefSetCur &= ~RBM_ARG_REGS;
+
+ var_types returnType = call->TypeGet();
+ if (returnType != TYP_VOID)
+ {
+ regNumber returnReg;
+
+ if (call->HasMultiRegRetVal())
+ {
+ assert(pRetTypeDesc != nullptr);
+ unsigned regCount = pRetTypeDesc->GetReturnRegCount();
+
+ // If regs allocated to call node are different from ABI return
+ // regs in which the call has returned its result, move the result
+ // to regs allocated to call node.
+ for (unsigned i = 0; i < regCount; ++i)
+ {
+ var_types regType = pRetTypeDesc->GetReturnRegType(i);
+ returnReg = pRetTypeDesc->GetABIReturnReg(i);
+ regNumber allocatedReg = call->GetRegNumByIdx(i);
+ if (returnReg != allocatedReg)
+ {
+ inst_RV_RV(ins_Copy(regType), allocatedReg, returnReg, regType);
+ }
+ }
+ }
+ else
+ {
+#ifdef _TARGET_ARM_
+ if (call->IsHelperCall(compiler, CORINFO_HELP_INIT_PINVOKE_FRAME))
+ {
+ // The CORINFO_HELP_INIT_PINVOKE_FRAME helper uses a custom calling convention that returns with
+ // TCB in REG_PINVOKE_TCB. fgMorphCall() sets the correct argument registers.
+ returnReg = REG_PINVOKE_TCB;
+ }
+ else
+#endif // _TARGET_ARM_
+ if (varTypeIsFloating(returnType))
+ {
+ returnReg = REG_FLOATRET;
+ }
+ else
+ {
+ returnReg = REG_INTRET;
+ }
+
+ if (call->gtRegNum != returnReg)
+ {
+ inst_RV_RV(ins_Copy(returnType), call->gtRegNum, returnReg, returnType);
+ }
+ }
+
+ genProduceReg(call);
+ }
+
+ // If there is nothing next, that means the result is thrown away, so this value is not live.
+ // However, for minopts or debuggable code, we keep it live to support managed return value debugging.
+ if ((call->gtNext == nullptr) && !compiler->opts.MinOpts() && !compiler->opts.compDbgCode)
+ {
+ gcInfo.gcMarkRegSetNpt(RBM_INTRET);
+ }
+}
+
+//------------------------------------------------------------------------
+// genIntToIntCast: Generate code for an integer cast
+//
+// Arguments:
+// treeNode - The GT_CAST node
+//
+// Return Value:
+// None.
+//
+// Assumptions:
+// The treeNode must have an assigned register.
+// For a signed convert from byte, the source must be in a byte-addressable register.
+// Neither the source nor target type can be a floating point type.
+//
+// TODO-ARM64-CQ: Allow castOp to be a contained node without an assigned register.
+//
+void CodeGen::genIntToIntCast(GenTreePtr treeNode)
+{
+ assert(treeNode->OperGet() == GT_CAST);
+
+ GenTreePtr castOp = treeNode->gtCast.CastOp();
+ emitter* emit = getEmitter();
+
+ var_types dstType = treeNode->CastToType();
+ var_types srcType = genActualType(castOp->TypeGet());
+ emitAttr movSize = emitActualTypeSize(dstType);
+ bool movRequired = false;
+
+#ifdef _TARGET_ARM_
+ if (varTypeIsLong(srcType))
+ {
+ genLongToIntCast(treeNode);
+ return;
+ }
+#endif // _TARGET_ARM_
+
+ regNumber targetReg = treeNode->gtRegNum;
+ regNumber sourceReg = castOp->gtRegNum;
+
+ // For Long to Int conversion we will have a reserved integer register to hold the immediate mask
+ regNumber tmpReg = (treeNode->gtRsvdRegs == RBM_NONE) ? REG_NA : genRegNumFromMask(treeNode->gtRsvdRegs);
+
+ assert(genIsValidIntReg(targetReg));
+ assert(genIsValidIntReg(sourceReg));
+
+ instruction ins = INS_invalid;
+
+ genConsumeReg(castOp);
+ Lowering::CastInfo castInfo;
+
+ // Get information about the cast.
+ Lowering::getCastDescription(treeNode, &castInfo);
+
+ if (castInfo.requiresOverflowCheck)
+ {
+ emitAttr cmpSize = EA_ATTR(genTypeSize(srcType));
+
+ if (castInfo.signCheckOnly)
+ {
+ // We only need to check for a negative value in sourceReg
+ emit->emitIns_R_I(INS_cmp, cmpSize, sourceReg, 0);
+ emitJumpKind jmpLT = genJumpKindForOper(GT_LT, CK_SIGNED);
+ genJumpToThrowHlpBlk(jmpLT, SCK_OVERFLOW);
+ noway_assert(genTypeSize(srcType) == 4 || genTypeSize(srcType) == 8);
+ // This is only interesting case to ensure zero-upper bits.
+ if ((srcType == TYP_INT) && (dstType == TYP_ULONG))
+ {
+ // cast to TYP_ULONG:
+ // We use a mov with size=EA_4BYTE
+ // which will zero out the upper bits
+ movSize = EA_4BYTE;
+ movRequired = true;
+ }
+ }
+ else if (castInfo.unsignedSource || castInfo.unsignedDest)
+ {
+ // When we are converting from/to unsigned,
+ // we only have to check for any bits set in 'typeMask'
+
+ noway_assert(castInfo.typeMask != 0);
+ emit->emitIns_R_I(INS_tst, cmpSize, sourceReg, castInfo.typeMask);
+ emitJumpKind jmpNotEqual = genJumpKindForOper(GT_NE, CK_SIGNED);
+ genJumpToThrowHlpBlk(jmpNotEqual, SCK_OVERFLOW);
+ }
+ else
+ {
+ // For a narrowing signed cast
+ //
+ // We must check the value is in a signed range.
+
+ // Compare with the MAX
+
+ noway_assert((castInfo.typeMin != 0) && (castInfo.typeMax != 0));
+
+#if defined(_TARGET_ARM_)
+ if (emitter::emitIns_valid_imm_for_cmp(castInfo.typeMax, INS_FLAGS_DONT_CARE))
+#elif defined(_TARGET_ARM64_)
+ if (emitter::emitIns_valid_imm_for_cmp(castInfo.typeMax, cmpSize))
+#endif // _TARGET_*
+ {
+ emit->emitIns_R_I(INS_cmp, cmpSize, sourceReg, castInfo.typeMax);
+ }
+ else
+ {
+ noway_assert(tmpReg != REG_NA);
+ instGen_Set_Reg_To_Imm(cmpSize, tmpReg, castInfo.typeMax);
+ emit->emitIns_R_R(INS_cmp, cmpSize, sourceReg, tmpReg);
+ }
+
+ emitJumpKind jmpGT = genJumpKindForOper(GT_GT, CK_SIGNED);
+ genJumpToThrowHlpBlk(jmpGT, SCK_OVERFLOW);
+
+// Compare with the MIN
+
+#if defined(_TARGET_ARM_)
+ if (emitter::emitIns_valid_imm_for_cmp(castInfo.typeMin, INS_FLAGS_DONT_CARE))
+#elif defined(_TARGET_ARM64_)
+ if (emitter::emitIns_valid_imm_for_cmp(castInfo.typeMin, cmpSize))
+#endif // _TARGET_*
+ {
+ emit->emitIns_R_I(INS_cmp, cmpSize, sourceReg, castInfo.typeMin);
+ }
+ else
+ {
+ noway_assert(tmpReg != REG_NA);
+ instGen_Set_Reg_To_Imm(cmpSize, tmpReg, castInfo.typeMin);
+ emit->emitIns_R_R(INS_cmp, cmpSize, sourceReg, tmpReg);
+ }
+
+ emitJumpKind jmpLT = genJumpKindForOper(GT_LT, CK_SIGNED);
+ genJumpToThrowHlpBlk(jmpLT, SCK_OVERFLOW);
+ }
+ ins = INS_mov;
+ }
+ else // Non-overflow checking cast.
+ {
+ if (genTypeSize(srcType) == genTypeSize(dstType))
+ {
+ ins = INS_mov;
+ }
+ else
+ {
+ var_types extendType = TYP_UNKNOWN;
+
+ // If we need to treat a signed type as unsigned
+ if ((treeNode->gtFlags & GTF_UNSIGNED) != 0)
+ {
+ extendType = genUnsignedType(srcType);
+ movSize = emitTypeSize(extendType);
+ movRequired = true;
+ }
+ else
+ {
+ if (genTypeSize(srcType) < genTypeSize(dstType))
+ {
+ extendType = srcType;
+#ifdef _TARGET_ARM_
+ movSize = emitTypeSize(srcType);
+#endif // _TARGET_ARM_
+ if (srcType == TYP_UINT)
+ {
+#ifdef _TARGET_ARM64_
+ // If we are casting from a smaller type to
+ // a larger type, then we need to make sure the
+ // higher 4 bytes are zero to gaurentee the correct value.
+ // Therefore using a mov with EA_4BYTE in place of EA_8BYTE
+ // will zero the upper bits
+ movSize = EA_4BYTE;
+#endif // _TARGET_ARM64_
+ movRequired = true;
+ }
+ }
+ else // (genTypeSize(srcType) > genTypeSize(dstType))
+ {
+ extendType = dstType;
+#if defined(_TARGET_ARM_)
+ movSize = emitTypeSize(dstType);
+#elif defined(_TARGET_ARM64_)
+ if (dstType == TYP_INT)
+ {
+ movSize = EA_8BYTE; // a sxtw instruction requires EA_8BYTE
+ }
+#endif // _TARGET_*
+ }
+ }
+
+ ins = ins_Move_Extend(extendType, castOp->InReg());
+ }
+ }
+
+ // We should never be generating a load from memory instruction here!
+ assert(!emit->emitInsIsLoad(ins));
+
+ if ((ins != INS_mov) || movRequired || (targetReg != sourceReg))
+ {
+ emit->emitIns_R_R(ins, movSize, targetReg, sourceReg);
+ }
+
+ genProduceReg(treeNode);
+}
+
+//------------------------------------------------------------------------
+// genFloatToFloatCast: Generate code for a cast between float and double
+//
+// Arguments:
+// treeNode - The GT_CAST node
+//
+// Return Value:
+// None.
+//
+// Assumptions:
+// Cast is a non-overflow conversion.
+// The treeNode must have an assigned register.
+// The cast is between float and double.
+//
+void CodeGen::genFloatToFloatCast(GenTreePtr treeNode)
+{
+ // float <--> double conversions are always non-overflow ones
+ assert(treeNode->OperGet() == GT_CAST);
+ assert(!treeNode->gtOverflow());
+
+ regNumber targetReg = treeNode->gtRegNum;
+ assert(genIsValidFloatReg(targetReg));
+
+ GenTreePtr op1 = treeNode->gtOp.gtOp1;
+ assert(!op1->isContained()); // Cannot be contained
+ assert(genIsValidFloatReg(op1->gtRegNum)); // Must be a valid float reg.
+
+ var_types dstType = treeNode->CastToType();
+ var_types srcType = op1->TypeGet();
+ assert(varTypeIsFloating(srcType) && varTypeIsFloating(dstType));
+
+ genConsumeOperands(treeNode->AsOp());
+
+ // treeNode must be a reg
+ assert(!treeNode->isContained());
+
+#if defined(_TARGET_ARM_)
+
+ if (srcType != dstType)
+ {
+ instruction insVcvt = (srcType == TYP_FLOAT) ? INS_vcvt_f2d // convert Float to Double
+ : INS_vcvt_d2f; // convert Double to Float
+
+ getEmitter()->emitIns_R_R(insVcvt, emitTypeSize(treeNode), treeNode->gtRegNum, op1->gtRegNum);
+ }
+ else if (treeNode->gtRegNum != op1->gtRegNum)
+ {
+ getEmitter()->emitIns_R_R(INS_vmov, emitTypeSize(treeNode), treeNode->gtRegNum, op1->gtRegNum);
+ }
+
+#elif defined(_TARGET_ARM64_)
+
+ if (srcType != dstType)
+ {
+ insOpts cvtOption = (srcType == TYP_FLOAT) ? INS_OPTS_S_TO_D // convert Single to Double
+ : INS_OPTS_D_TO_S; // convert Double to Single
+
+ getEmitter()->emitIns_R_R(INS_fcvt, emitTypeSize(treeNode), treeNode->gtRegNum, op1->gtRegNum, cvtOption);
+ }
+ else if (treeNode->gtRegNum != op1->gtRegNum)
+ {
+ // If double to double cast or float to float cast. Emit a move instruction.
+ getEmitter()->emitIns_R_R(INS_mov, emitTypeSize(treeNode), treeNode->gtRegNum, op1->gtRegNum);
+ }
+
+#endif // _TARGET_*
+
+ genProduceReg(treeNode);
+}
+
+//------------------------------------------------------------------------
+// genCreateAndStoreGCInfo: Create and record GC Info for the function.
+//
+void CodeGen::genCreateAndStoreGCInfo(unsigned codeSize,
+ unsigned prologSize,
+ unsigned epilogSize DEBUGARG(void* codePtr))
+{
+ IAllocator* allowZeroAlloc = new (compiler, CMK_GC) AllowZeroAllocator(compiler->getAllocatorGC());
+ GcInfoEncoder* gcInfoEncoder = new (compiler, CMK_GC)
+ GcInfoEncoder(compiler->info.compCompHnd, compiler->info.compMethodInfo, allowZeroAlloc, NOMEM);
+ assert(gcInfoEncoder != nullptr);
+
+ // Follow the code pattern of the x86 gc info encoder (genCreateAndStoreGCInfoJIT32).
+ gcInfo.gcInfoBlockHdrSave(gcInfoEncoder, codeSize, prologSize);
+
+ // We keep the call count for the second call to gcMakeRegPtrTable() below.
+ unsigned callCnt = 0;
+
+ // First we figure out the encoder ID's for the stack slots and registers.
+ gcInfo.gcMakeRegPtrTable(gcInfoEncoder, codeSize, prologSize, GCInfo::MAKE_REG_PTR_MODE_ASSIGN_SLOTS, &callCnt);
+
+ // Now we've requested all the slots we'll need; "finalize" these (make more compact data structures for them).
+ gcInfoEncoder->FinalizeSlotIds();
+
+ // Now we can actually use those slot ID's to declare live ranges.
+ gcInfo.gcMakeRegPtrTable(gcInfoEncoder, codeSize, prologSize, GCInfo::MAKE_REG_PTR_MODE_DO_WORK, &callCnt);
+
+#ifdef _TARGET_ARM64_
+
+ if (compiler->opts.compDbgEnC)
+ {
+ // what we have to preserve is called the "frame header" (see comments in VM\eetwain.cpp)
+ // which is:
+ // -return address
+ // -saved off RBP
+ // -saved 'this' pointer and bool for synchronized methods
+
+ // 4 slots for RBP + return address + RSI + RDI
+ int preservedAreaSize = 4 * REGSIZE_BYTES;
+
+ if (compiler->info.compFlags & CORINFO_FLG_SYNCH)
+ {
+ if (!(compiler->info.compFlags & CORINFO_FLG_STATIC))
+ preservedAreaSize += REGSIZE_BYTES;
+
+ preservedAreaSize += 1; // bool for synchronized methods
+ }
+
+ // Used to signal both that the method is compiled for EnC, and also the size of the block at the top of the
+ // frame
+ gcInfoEncoder->SetSizeOfEditAndContinuePreservedArea(preservedAreaSize);
+ }
+
+#endif // _TARGET_ARM64_
+
+ gcInfoEncoder->Build();
+
+ // GC Encoder automatically puts the GC info in the right spot using ICorJitInfo::allocGCInfo(size_t)
+ // let's save the values anyway for debugging purposes
+ compiler->compInfoBlkAddr = gcInfoEncoder->Emit();
+ compiler->compInfoBlkSize = 0; // not exposed by the GCEncoder interface
+}
+
+#endif // _TARGET_ARMARCH_
+
+#endif // !LEGACY_BACKEND
diff --git a/src/jit/codegenclassic.h b/src/jit/codegenclassic.h
index 3a88c83915..eb4aeb7754 100644
--- a/src/jit/codegenclassic.h
+++ b/src/jit/codegenclassic.h
@@ -283,7 +283,7 @@ void genCodeForJumpTable(GenTreePtr tree);
void genCodeForSwitchTable(GenTreePtr tree);
void genCodeForSwitch(GenTreePtr tree);
-size_t genPushArgList(GenTreePtr call);
+size_t genPushArgList(GenTreeCall* call);
#ifdef _TARGET_ARM_
// We are generating code for a promoted struct local variable. Fill the next slot (register or
@@ -351,15 +351,15 @@ bool genFillSlotFromPromotedStruct(GenTreePtr arg,
// of cpBlk).
regMaskTP genFindDeadFieldRegs(GenTreePtr cpBlk);
-void SetupLateArgs(GenTreePtr call);
+void SetupLateArgs(GenTreeCall* call);
#ifdef _TARGET_ARM_
void PushMkRefAnyArg(GenTreePtr mkRefAnyTree, fgArgTabEntryPtr curArgTabEntry, regMaskTP regNeedMask);
#endif // _TARGET_ARM_
-regMaskTP genLoadIndirectCallTarget(GenTreePtr call);
+regMaskTP genLoadIndirectCallTarget(GenTreeCall* call);
-regMaskTP genCodeForCall(GenTreePtr call, bool valUsed);
+regMaskTP genCodeForCall(GenTreeCall* call, bool valUsed);
GenTreePtr genGetAddrModeBase(GenTreePtr tree);
diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
index b1e474b755..89d6a4ca34 100644
--- a/src/jit/codegencommon.cpp
+++ b/src/jit/codegencommon.cpp
@@ -107,6 +107,11 @@ CodeGen::CodeGen(Compiler* theCompiler) : CodeGenInterface(theCompiler)
m_stkArgVarNum = BAD_VAR_NUM;
#endif
+#if defined(UNIX_X86_ABI)
+ curNestedAlignment = 0;
+ maxNestedAlignment = 0;
+#endif
+
regTracker.rsTrackInit(compiler, &regSet);
gcInfo.regSet = &regSet;
m_cgEmitter = new (compiler->getAllocator()) emitter();
@@ -647,7 +652,7 @@ regMaskTP Compiler::compHelperCallKillSet(CorInfoHelpFunc helper)
#if defined(_TARGET_AMD64_)
return RBM_RSI | RBM_RDI | RBM_CALLEE_TRASH;
#elif defined(_TARGET_ARM64_)
- return RBM_CALLEE_TRASH_NOGC;
+ return RBM_WRITE_BARRIER_SRC_BYREF | RBM_WRITE_BARRIER_DST_BYREF | RBM_CALLEE_TRASH_NOGC;
#elif defined(_TARGET_X86_)
return RBM_ESI | RBM_EDI | RBM_ECX;
#else
@@ -717,6 +722,8 @@ regMaskTP Compiler::compNoGCHelperCallKillSet(CorInfoHelpFunc helper)
#elif defined(_TARGET_X86_)
// This helper only trashes ECX.
return RBM_ECX;
+#elif defined(_TARGET_ARM64_)
+ return RBM_CALLEE_TRASH_NOGC & ~(RBM_WRITE_BARRIER_SRC_BYREF | RBM_WRITE_BARRIER_DST_BYREF);
#else
return RBM_CALLEE_TRASH_NOGC;
#endif // defined(_TARGET_AMD64_)
@@ -1095,9 +1102,9 @@ void Compiler::compChangeLife(VARSET_VALARG_TP newLife DEBUGARG(GenTreePtr tree)
/* Can't simultaneously become live and dead at the same time */
// (deadSet UNION bornSet) != EMPTY
- noway_assert(!VarSetOps::IsEmpty(this, VarSetOps::Union(this, deadSet, bornSet)));
+ noway_assert(!VarSetOps::IsEmptyUnion(this, deadSet, bornSet));
// (deadSet INTERSECTION bornSet) == EMPTY
- noway_assert(VarSetOps::IsEmpty(this, VarSetOps::Intersection(this, deadSet, bornSet)));
+ noway_assert(VarSetOps::IsEmptyIntersection(this, deadSet, bornSet));
#ifdef LEGACY_BACKEND
// In the LEGACY_BACKEND case, we only consider variables that are fully enregisterd
@@ -1406,9 +1413,8 @@ void CodeGenInterface::reloadFloatReg(var_types type, TempDsc* tmp, regNumber re
#endif // LEGACY_BACKEND
// inline
-regNumber CodeGenInterface::genGetThisArgReg(GenTreePtr call)
+regNumber CodeGenInterface::genGetThisArgReg(GenTreeCall* call) const
{
- noway_assert(call->IsCall());
return REG_ARG_0;
}
@@ -1633,7 +1639,7 @@ void CodeGen::genDefineTempLabel(BasicBlock* label)
void CodeGen::genAdjustSP(ssize_t delta)
{
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(UNIX_X86_ABI)
if (delta == sizeof(int))
inst_RV(INS_pop, REG_ECX, TYP_INT);
else
@@ -1663,14 +1669,14 @@ void CodeGen::genAdjustStackLevel(BasicBlock* block)
{
noway_assert(block->bbFlags & BBF_JMP_TARGET);
- genStackLevel = compiler->fgThrowHlpBlkStkLevel(block) * sizeof(int);
+ SetStackLevel(compiler->fgThrowHlpBlkStkLevel(block) * sizeof(int));
if (genStackLevel != 0)
{
#ifdef _TARGET_X86_
getEmitter()->emitMarkStackLvl(genStackLevel);
inst_RV_IV(INS_add, REG_SPBASE, genStackLevel, EA_PTRSIZE);
- genStackLevel = 0;
+ SetStackLevel(0);
#else // _TARGET_X86_
NYI("Need emitMarkStackLvl()");
#endif // _TARGET_X86_
@@ -1863,26 +1869,26 @@ bool CodeGen::genCreateAddrMode(GenTreePtr addr,
The following indirections are valid address modes on x86/x64:
[ icon] * not handled here
- [reg ] * not handled here
+ [reg ]
[reg + icon]
- [reg2 + reg1 ]
- [reg2 + reg1 + icon]
- [reg2 + 2 * reg1 ]
- [reg2 + 4 * reg1 ]
- [reg2 + 8 * reg1 ]
- [ 2 * reg1 + icon]
- [ 4 * reg1 + icon]
- [ 8 * reg1 + icon]
- [reg2 + 2 * reg1 + icon]
- [reg2 + 4 * reg1 + icon]
- [reg2 + 8 * reg1 + icon]
+ [reg1 + reg2 ]
+ [reg1 + reg2 + icon]
+ [reg1 + 2 * reg2 ]
+ [reg1 + 4 * reg2 ]
+ [reg1 + 8 * reg2 ]
+ [ 2 * reg2 + icon]
+ [ 4 * reg2 + icon]
+ [ 8 * reg2 + icon]
+ [reg1 + 2 * reg2 + icon]
+ [reg1 + 4 * reg2 + icon]
+ [reg1 + 8 * reg2 + icon]
The following indirections are valid address modes on arm64:
[reg]
[reg + icon]
- [reg2 + reg1]
- [reg2 + reg1 * natural-scale]
+ [reg1 + reg2]
+ [reg1 + reg2 * natural-scale]
*/
@@ -2442,6 +2448,11 @@ FOUND_AM:
noway_assert(FitsIn<INT32>(cns));
+ if (rv1 == nullptr && rv2 == nullptr)
+ {
+ return false;
+ }
+
/* Success - return the various components to the caller */
*revPtr = rev;
@@ -2604,6 +2615,51 @@ emitJumpKind CodeGen::genJumpKindForOper(genTreeOps cmp, CompareKind compareKind
return result;
}
+#ifndef LEGACY_BACKEND
+#ifdef _TARGET_ARMARCH_
+//------------------------------------------------------------------------
+// genEmitGSCookieCheck: Generate code to check that the GS cookie
+// wasn't thrashed by a buffer overrun. Coomon code for ARM32 and ARM64
+//
+void CodeGen::genEmitGSCookieCheck(bool pushReg)
+{
+ noway_assert(compiler->gsGlobalSecurityCookieAddr || compiler->gsGlobalSecurityCookieVal);
+
+ // Make sure that the return register is reported as live GC-ref so that any GC that kicks in while
+ // executing GS cookie check will not collect the object pointed to by REG_INTRET (R0).
+ if (!pushReg && (compiler->info.compRetType == TYP_REF))
+ gcInfo.gcRegGCrefSetCur |= RBM_INTRET;
+
+ regNumber regGSConst = REG_TMP_0;
+ regNumber regGSValue = REG_TMP_1;
+
+ if (compiler->gsGlobalSecurityCookieAddr == nullptr)
+ {
+ // load the GS cookie constant into a reg
+ //
+ genSetRegToIcon(regGSConst, compiler->gsGlobalSecurityCookieVal, TYP_I_IMPL);
+ }
+ else
+ {
+ // Ngen case - GS cookie constant needs to be accessed through an indirection.
+ instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, regGSConst, (ssize_t)compiler->gsGlobalSecurityCookieAddr);
+ getEmitter()->emitIns_R_R_I(ins_Load(TYP_I_IMPL), EA_PTRSIZE, regGSConst, regGSConst, 0);
+ }
+ // Load this method's GS value from the stack frame
+ getEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, regGSValue, compiler->lvaGSSecurityCookie, 0);
+ // Compare with the GC cookie constant
+ getEmitter()->emitIns_R_R(INS_cmp, EA_PTRSIZE, regGSConst, regGSValue);
+
+ BasicBlock* gsCheckBlk = genCreateTempLabel();
+ emitJumpKind jmpEqual = genJumpKindForOper(GT_EQ, CK_SIGNED);
+ inst_JMP(jmpEqual, gsCheckBlk);
+ // regGSConst and regGSValue aren't needed anymore, we can use them for helper call
+ genEmitHelperCall(CORINFO_HELP_FAIL_FAST, 0, EA_UNKNOWN, regGSConst);
+ genDefineTempLabel(gsCheckBlk);
+}
+#endif // _TARGET_ARMARCH_
+#endif // !LEGACY_BACKEND
+
/*****************************************************************************
*
* Generate an exit sequence for a return from a method (note: when compiling
@@ -2814,6 +2870,37 @@ void CodeGen::genUpdateCurrentFunclet(BasicBlock* block)
}
}
}
+
+#if defined(_TARGET_ARM_)
+void CodeGen::genInsertNopForUnwinder(BasicBlock* block)
+{
+ // If this block is the target of a finally return, we need to add a preceding NOP, in the same EH region,
+ // so the unwinder doesn't get confused by our "movw lr, xxx; movt lr, xxx; b Lyyy" calling convention that
+ // calls the funclet during non-exceptional control flow.
+ if (block->bbFlags & BBF_FINALLY_TARGET)
+ {
+ assert(block->bbFlags & BBF_JMP_TARGET);
+
+#ifdef DEBUG
+ if (compiler->verbose)
+ {
+ printf("\nEmitting finally target NOP predecessor for BB%02u\n", block->bbNum);
+ }
+#endif
+ // Create a label that we'll use for computing the start of an EH region, if this block is
+ // at the beginning of such a region. If we used the existing bbEmitCookie as is for
+ // determining the EH regions, then this NOP would end up outside of the region, if this
+ // block starts an EH region. If we pointed the existing bbEmitCookie here, then the NOP
+ // would be executed, which we would prefer not to do.
+
+ block->bbUnwindNopEmitCookie =
+ getEmitter()->emitAddLabel(gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur);
+
+ instGen(INS_nop);
+ }
+}
+#endif
+
#endif // FEATURE_EH_FUNCLETS
/*****************************************************************************
@@ -2946,7 +3033,8 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode)
if (compiler->fgHaveProfileData())
{
- printf("; with IBC profile data\n");
+ printf("; with IBC profile data, edge weights are %s, and fgCalledCount is %u\n",
+ compiler->fgHaveValidEdgeWeights ? "valid" : "invalid", compiler->fgCalledCount);
}
if (compiler->fgProfileData_ILSizeMismatch)
@@ -3120,14 +3208,11 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode)
bool trackedStackPtrsContig; // are tracked stk-ptrs contiguous ?
-#ifdef _TARGET_AMD64_
+#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
trackedStackPtrsContig = false;
#elif defined(_TARGET_ARM_)
// On arm due to prespilling of arguments, tracked stk-ptrs may not be contiguous
trackedStackPtrsContig = !compiler->opts.compDbgEnC && !compiler->compIsProfilerHookNeeded();
-#elif defined(_TARGET_ARM64_)
- // Incoming vararg registers are homed on the top of the stack. Tracked var may not be contiguous.
- trackedStackPtrsContig = !compiler->opts.compDbgEnC && !compiler->info.compIsVarArgs;
#else
trackedStackPtrsContig = !compiler->opts.compDbgEnC;
#endif
@@ -3171,7 +3256,7 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode)
genTypeStSz(TYP_LONG) + // longs/doubles may be transferred via stack, etc
(compiler->compTailCallUsed ? 4 : 0); // CORINFO_HELP_TAILCALL args
#if defined(UNIX_X86_ABI)
- maxAllowedStackDepth += genTypeStSz(TYP_INT) * 3; // stack align for x86 - allow up to 3 INT's for padding
+ maxAllowedStackDepth += maxNestedAlignment;
#endif
noway_assert(getEmitter()->emitMaxStackDepth <= maxAllowedStackDepth);
}
@@ -3896,12 +3981,12 @@ void CodeGen::genGCWriteBarrier(GenTreePtr tgt, GCInfo::WriteBarrierForm wbf)
}
#endif // DEBUG
#endif // 0
- genStackLevel += 4;
+ AddStackLevel(4);
inst_IV(INS_push, wbKind);
genEmitHelperCall(helper,
4, // argSize
EA_PTRSIZE); // retSize
- genStackLevel -= 4;
+ SubtractStackLevel(4);
}
else
{
@@ -7520,6 +7605,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
//
if (compiler->fgPtrArgCntMax < 1)
{
+ JITDUMP("Upping fgPtrArgCntMax from %d to 1\n", compiler->fgPtrArgCntMax);
compiler->fgPtrArgCntMax = 1;
}
#elif defined(_TARGET_ARM_)
@@ -7536,7 +7622,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed)
/* Restore the stack level */
- genStackLevel = saveStackLvl2;
+ SetStackLevel(saveStackLvl2);
#else // target
NYI("Emit Profiler Enter callback");
@@ -7679,6 +7765,7 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
//
if (compiler->fgPtrArgCntMax < 1)
{
+ JITDUMP("Upping fgPtrArgCntMax from %d to 1\n", compiler->fgPtrArgCntMax);
compiler->fgPtrArgCntMax = 1;
}
@@ -7765,7 +7852,7 @@ void CodeGen::genProfilingLeaveCallback(unsigned helper /*= CORINFO_HELP_PROF_FC
#endif // target
/* Restore the stack level */
- genStackLevel = saveStackLvl2;
+ SetStackLevel(saveStackLvl2);
}
#endif // PROFILING_SUPPORTED
@@ -8054,6 +8141,14 @@ void CodeGen::genFinalizeFrame()
}
#endif // defined(_TARGET_ARMARCH_)
+#if defined(_TARGET_ARM_)
+ // If there are any reserved registers, add them to the
+ if (regSet.rsMaskResvd != RBM_NONE)
+ {
+ regSet.rsSetRegsModified(regSet.rsMaskResvd);
+ }
+#endif // _TARGET_ARM_
+
#ifdef DEBUG
if (verbose)
{
@@ -9239,16 +9334,23 @@ void CodeGen::genFnEpilog(BasicBlock* block)
* the same descriptor with some minor adjustments.
*/
- getEmitter()->emitIns_Call(callType, methHnd, INDEBUG_LDISASM_COMMA(nullptr) addr,
+ // clang-format off
+ getEmitter()->emitIns_Call(callType,
+ methHnd,
+ INDEBUG_LDISASM_COMMA(nullptr)
+ addr,
0, // argSize
EA_UNKNOWN, // retSize
- gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur,
+ gcInfo.gcVarPtrSetCur,
+ gcInfo.gcRegGCrefSetCur,
+ gcInfo.gcRegByrefSetCur,
BAD_IL_OFFSET, // IL offset
indCallReg, // ireg
REG_NA, // xreg
0, // xmul
0, // disp
true); // isJump
+ // clang-format on
}
else
{
@@ -9341,13 +9443,21 @@ void CodeGen::genFnEpilog(BasicBlock* block)
// Simply emit a jump to the methodHnd. This is similar to a call so we can use
// the same descriptor with some minor adjustments.
- getEmitter()->emitIns_Call(callType, methHnd, INDEBUG_LDISASM_COMMA(nullptr) addrInfo.addr,
+
+ // clang-format off
+ getEmitter()->emitIns_Call(callType,
+ methHnd,
+ INDEBUG_LDISASM_COMMA(nullptr)
+ addrInfo.addr,
0, // argSize
EA_UNKNOWN, // retSize
EA_UNKNOWN, // secondRetSize
- gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur,
+ gcInfo.gcVarPtrSetCur,
+ gcInfo.gcRegGCrefSetCur,
+ gcInfo.gcRegByrefSetCur,
BAD_IL_OFFSET, REG_NA, REG_NA, 0, 0, /* iloffset, ireg, xreg, xmul, disp */
true); /* isJump */
+ // clang-format on
}
#if FEATURE_FASTTAILCALL
else
@@ -9419,6 +9529,20 @@ void CodeGen::genFnEpilog(BasicBlock* block)
genRestoreCalleeSavedFltRegs(compiler->compLclFrameSize);
#endif // !FEATURE_STACK_FP_X87
+#ifdef JIT32_GCENCODER
+ // When using the JIT32 GC encoder, we do not start the OS-reported portion of the epilog until after
+ // the above call to `genRestoreCalleeSavedFltRegs` because that function
+ // a) does not actually restore any registers: there are none when targeting the Windows x86 ABI,
+ // which is the only target that uses the JIT32 GC encoder
+ // b) may issue a `vzeroupper` instruction to eliminate AVX -> SSE transition penalties.
+ // Because the `vzeroupper` instruction is not recognized by the VM's unwinder and there are no
+ // callee-save FP restores that the unwinder would need to see, we can avoid the need to change the
+ // unwinder (and break binary compat with older versions of the runtime) by starting the epilog
+ // after any `vzeroupper` instruction has been emitted. If either of the above conditions changes,
+ // we will need to rethink this.
+ getEmitter()->emitStartEpilog();
+#endif
+
/* Compute the size in bytes we've pushed/popped */
if (!doubleAlignOrFramePointerUsed())
@@ -9615,14 +9739,21 @@ void CodeGen::genFnEpilog(BasicBlock* block)
// Simply emit a jump to the methodHnd. This is similar to a call so we can use
// the same descriptor with some minor adjustments.
- getEmitter()->emitIns_Call(callType, methHnd, INDEBUG_LDISASM_COMMA(nullptr) addrInfo.addr,
+
+ // clang-format off
+ getEmitter()->emitIns_Call(callType,
+ methHnd,
+ INDEBUG_LDISASM_COMMA(nullptr)
+ addrInfo.addr,
0, // argSize
EA_UNKNOWN // retSize
- FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(EA_UNKNOWN), // secondRetSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(EA_UNKNOWN), // secondRetSize
gcInfo.gcVarPtrSetCur,
- gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur, BAD_IL_OFFSET, REG_NA, REG_NA,
- 0, 0, /* iloffset, ireg, xreg, xmul, disp */
+ gcInfo.gcRegGCrefSetCur,
+ gcInfo.gcRegByrefSetCur,
+ BAD_IL_OFFSET, REG_NA, REG_NA, 0, 0, /* iloffset, ireg, xreg, xmul, disp */
true); /* isJump */
+ // clang-format on
}
#if FEATURE_FASTTAILCALL
else
@@ -9644,17 +9775,25 @@ void CodeGen::genFnEpilog(BasicBlock* block)
unsigned stkArgSize = 0; // Zero on all platforms except x86
#if defined(_TARGET_X86_)
-
- noway_assert(compiler->compArgSize >= intRegState.rsCalleeRegArgCount * sizeof(void*));
- stkArgSize = compiler->compArgSize - intRegState.rsCalleeRegArgCount * sizeof(void*);
-
- noway_assert(compiler->compArgSize < 0x10000); // "ret" only has 2 byte operand
+ bool fCalleePop = true;
// varargs has caller pop
if (compiler->info.compIsVarArgs)
- stkArgSize = 0;
+ fCalleePop = false;
-#endif // defined(_TARGET_X86_)
+#ifdef UNIX_X86_ABI
+ if (IsCallerPop(compiler->info.compMethodInfo->args.callConv))
+ fCalleePop = false;
+#endif // UNIX_X86_ABI
+
+ if (fCalleePop)
+ {
+ noway_assert(compiler->compArgSize >= intRegState.rsCalleeRegArgCount * sizeof(void*));
+ stkArgSize = compiler->compArgSize - intRegState.rsCalleeRegArgCount * sizeof(void*);
+
+ noway_assert(compiler->compArgSize < 0x10000); // "ret" only has 2 byte operand
+ }
+#endif // _TARGET_X86_
/* Return, popping our arguments (if any) */
instGen_Return(stkArgSize);
@@ -10271,6 +10410,22 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
/*****************************************************************************
*
* Generates code for an EH funclet prolog.
+ *
+ *
+ * Funclets have the following incoming arguments:
+ *
+ * catch/filter-handler: eax = the exception object that was caught (see GT_CATCH_ARG)
+ * filter: eax = the exception object that was caught (see GT_CATCH_ARG)
+ * finally/fault: none
+ *
+ * Funclets set the following registers on exit:
+ *
+ * catch/filter-handler: eax = the address at which execution should resume (see BBJ_EHCATCHRET)
+ * filter: eax = non-zero if the handler should handle the exception, zero otherwise (see GT_RETFILT)
+ * finally/fault: none
+ *
+ * Funclet prolog/epilog sequence and funclet frame layout are TBD.
+ *
*/
void CodeGen::genFuncletProlog(BasicBlock* block)
@@ -10284,12 +10439,17 @@ void CodeGen::genFuncletProlog(BasicBlock* block)
ScopedSetVariable<bool> _setGeneratingProlog(&compiler->compGeneratingProlog, true);
- compiler->unwindBegProlog();
+ gcInfo.gcResetForBB();
- // TODO Save callee-saved registers
+ compiler->unwindBegProlog();
// This is the end of the OS-reported prolog for purposes of unwinding
compiler->unwindEndProlog();
+
+ // TODO We may need EBP restore sequence here if we introduce PSPSym
+
+ // Add a padding for 16-byte alignment
+ inst_RV_IV(INS_sub, REG_SPBASE, 12, EA_PTRSIZE);
}
/*****************************************************************************
@@ -10308,7 +10468,8 @@ void CodeGen::genFuncletEpilog()
ScopedSetVariable<bool> _setGeneratingEpilog(&compiler->compGeneratingEpilog, true);
- // TODO Restore callee-saved registers
+ // Revert a padding that was added for 16-byte alignment
+ inst_RV_IV(INS_add, REG_SPBASE, 12, EA_PTRSIZE);
instGen_Return(0);
}
@@ -11061,7 +11222,7 @@ unsigned CodeGen::getFirstArgWithStackSlot()
//
void CodeGen::genSinglePush()
{
- genStackLevel += sizeof(void*);
+ AddStackLevel(REGSIZE_BYTES);
}
//------------------------------------------------------------------------
@@ -11069,7 +11230,7 @@ void CodeGen::genSinglePush()
//
void CodeGen::genSinglePop()
{
- genStackLevel -= sizeof(void*);
+ SubtractStackLevel(REGSIZE_BYTES);
}
//------------------------------------------------------------------------
diff --git a/src/jit/codegeninterface.h b/src/jit/codegeninterface.h
index 3950673e3a..08d854eaaf 100644
--- a/src/jit/codegeninterface.h
+++ b/src/jit/codegeninterface.h
@@ -191,7 +191,7 @@ public:
int genSPtoFPdelta();
int genTotalFrameSize();
- regNumber genGetThisArgReg(GenTreePtr call);
+ regNumber genGetThisArgReg(GenTreeCall* call) const;
#ifdef _TARGET_XARCH_
#ifdef _TARGET_AMD64_
diff --git a/src/jit/codegenlegacy.cpp b/src/jit/codegenlegacy.cpp
index 0530863d81..d65351115f 100644
--- a/src/jit/codegenlegacy.cpp
+++ b/src/jit/codegenlegacy.cpp
@@ -1897,10 +1897,22 @@ void CodeGen::genRangeCheck(GenTreePtr oper)
{
// If we need "arrRef" or "arrLen", and evaluating "index" displaced whichever of them we're using
// from its register, get it back in a register.
+ regMaskTP indRegMask = RBM_ALLINT;
+ regMaskTP arrRegMask = RBM_ALLINT;
+ if (!(index->gtFlags & GTF_SPILLED))
+ arrRegMask = ~genRegMask(index->gtRegNum);
if (arrRef != NULL)
- genRecoverReg(arrRef, ~genRegMask(index->gtRegNum), RegSet::KEEP_REG);
+ {
+ genRecoverReg(arrRef, arrRegMask, RegSet::KEEP_REG);
+ indRegMask &= ~genRegMask(arrRef->gtRegNum);
+ }
else if (!arrLen->IsCnsIntOrI())
- genRecoverReg(arrLen, ~genRegMask(index->gtRegNum), RegSet::KEEP_REG);
+ {
+ genRecoverReg(arrLen, arrRegMask, RegSet::KEEP_REG);
+ indRegMask &= ~genRegMask(arrLen->gtRegNum);
+ }
+ if (index->gtFlags & GTF_SPILLED)
+ regSet.rsUnspillReg(index, indRegMask, RegSet::KEEP_REG);
/* Make sure we have the values we expect */
noway_assert(index->gtFlags & GTF_REG_VAL);
@@ -5183,6 +5195,7 @@ void CodeGen::genCodeForTreeLeaf_GT_JMP(GenTreePtr tree)
//
if (compiler->fgPtrArgCntMax < 1)
{
+ JITDUMP("Upping fgPtrArgCntMax from %d to 1\n", compiler->fgPtrArgCntMax);
compiler->fgPtrArgCntMax = 1;
}
@@ -5214,7 +5227,7 @@ void CodeGen::genCodeForTreeLeaf_GT_JMP(GenTreePtr tree)
#endif //_TARGET_X86_
/* Restore the stack level */
- genStackLevel = saveStackLvl2;
+ SetStackLevel(saveStackLvl2);
}
#endif // PROFILING_SUPPORTED
@@ -10002,7 +10015,7 @@ void CodeGen::genCodeForTreeSmpOp(GenTreePtr tree, regMaskTP destReg, regMaskTP
// We have a return call() because we failed to tail call.
// In any case, just generate the call and be done.
assert(compiler->IsHfa(op1));
- genCodeForCall(op1, true);
+ genCodeForCall(op1->AsCall(), true);
genMarkTreeInReg(op1, REG_FLOATRET);
}
else
@@ -11226,7 +11239,7 @@ void CodeGen::genStoreFromFltRetRegs(GenTreePtr tree)
assert(op2->gtOper == GT_CALL);
// Generate code for call and copy the return registers into the local.
- regMaskTP retMask = genCodeForCall(op2, true);
+ regMaskTP retMask = genCodeForCall(op2->AsCall(), true);
// Ret mask should be contiguously set from s0, up to s3 or starting from d0 upto d3.
CLANG_FORMAT_COMMENT_ANCHOR;
@@ -12076,7 +12089,7 @@ void CodeGen::genCodeForTreeSpecialOp(GenTreePtr tree, regMaskTP destReg, regMas
switch (oper)
{
case GT_CALL:
- regs = genCodeForCall(tree, true);
+ regs = genCodeForCall(tree->AsCall(), true);
/* If the result is in a register, make sure it ends up in the right place */
@@ -12680,30 +12693,7 @@ void CodeGen::genCodeForBBlist()
#if FEATURE_EH_FUNCLETS
#if defined(_TARGET_ARM_)
- // If this block is the target of a finally return, we need to add a preceding NOP, in the same EH region,
- // so the unwinder doesn't get confused by our "movw lr, xxx; movt lr, xxx; b Lyyy" calling convention that
- // calls the funclet during non-exceptional control flow.
- if (block->bbFlags & BBF_FINALLY_TARGET)
- {
- assert(block->bbFlags & BBF_JMP_TARGET);
-
-#ifdef DEBUG
- if (compiler->verbose)
- {
- printf("\nEmitting finally target NOP predecessor for BB%02u\n", block->bbNum);
- }
-#endif
- // Create a label that we'll use for computing the start of an EH region, if this block is
- // at the beginning of such a region. If we used the existing bbEmitCookie as is for
- // determining the EH regions, then this NOP would end up outside of the region, if this
- // block starts an EH region. If we pointed the existing bbEmitCookie here, then the NOP
- // would be executed, which we would prefer not to do.
-
- block->bbUnwindNopEmitCookie =
- getEmitter()->emitAddLabel(gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur);
-
- instGen(INS_nop);
- }
+ genInsertNopForUnwinder(block);
#endif // defined(_TARGET_ARM_)
genUpdateCurrentFunclet(block);
@@ -12755,7 +12745,7 @@ void CodeGen::genCodeForBBlist()
/* Both stacks are always empty on entry to a basic block */
- genStackLevel = 0;
+ SetStackLevel(0);
#if FEATURE_STACK_FP_X87
genResetFPstkLevel();
#endif // FEATURE_STACK_FP_X87
@@ -12854,7 +12844,7 @@ void CodeGen::genCodeForBBlist()
// Managed Retval under managed debugger - we need to make sure that the returned ref-type is
// reported as alive even though not used within the caller for managed debugger sake. So
// consider the return value of the method as used if generating debuggable code.
- genCodeForCall(tree, compiler->opts.MinOpts() || compiler->opts.compDbgCode);
+ genCodeForCall(tree->AsCall(), compiler->opts.MinOpts() || compiler->opts.compDbgCode);
genUpdateLife(tree);
gcInfo.gcMarkRegSetNpt(RBM_INTRET);
break;
@@ -12961,7 +12951,7 @@ void CodeGen::genCodeForBBlist()
}
}
- genStackLevel -= savedStkLvl;
+ SubtractStackLevel(savedStkLvl);
gcInfo.gcMarkRegSetNpt(gcrefRegs | byrefRegs);
@@ -15055,7 +15045,7 @@ void CodeGen::genCodeForTreeLng(GenTreePtr tree, regMaskTP needReg, regMaskTP av
{
regMaskTP retMask;
case GT_CALL:
- retMask = genCodeForCall(tree, true);
+ retMask = genCodeForCall(tree->AsCall(), true);
if (retMask == RBM_NONE)
regPair = REG_PAIR_NONE;
else
@@ -15676,9 +15666,9 @@ void CodeGen::genEmitHelperCall(unsigned helper, int argSize, emitAttr retSize)
#pragma warning(push)
#pragma warning(disable : 21000) // Suppress PREFast warning about overly large function
#endif
-size_t CodeGen::genPushArgList(GenTreePtr call)
+size_t CodeGen::genPushArgList(GenTreeCall* call)
{
- GenTreeArgList* regArgs = call->gtCall.gtCallLateArgs;
+ GenTreeArgList* regArgs = call->gtCallLateArgs;
size_t size = 0;
regMaskTP addrReg;
@@ -15686,14 +15676,14 @@ size_t CodeGen::genPushArgList(GenTreePtr call)
// Create a local, artificial GenTreeArgList that includes the gtCallObjp, if that exists, as first argument,
// so we can iterate over this argument list more uniformly.
// Need to provide a temporary non-null first argument here: if we use this, we'll replace it.
- GenTreeArgList firstForObjp(/*temp dummy arg*/ call, call->gtCall.gtCallArgs);
- if (call->gtCall.gtCallObjp == NULL)
+ GenTreeArgList firstForObjp(/*temp dummy arg*/ call, call->gtCallArgs);
+ if (call->gtCallObjp == NULL)
{
- args = call->gtCall.gtCallArgs;
+ args = call->gtCallArgs;
}
else
{
- firstForObjp.Current() = call->gtCall.gtCallObjp;
+ firstForObjp.Current() = call->gtCallObjp;
args = &firstForObjp;
}
@@ -16358,7 +16348,7 @@ size_t CodeGen::genPushArgList(GenTreePtr call)
}
inst_RV_IV(INS_sub, REG_SPBASE, stkDisp, EA_PTRSIZE);
- genStackLevel += stkDisp;
+ AddStackLevel(stkDisp);
while (curDisp < stkDisp)
{
@@ -16508,10 +16498,9 @@ size_t CodeGen::genPushArgList(GenTreePtr call)
// ARM and AMD64 uses this method to pass the stack based args
//
// returns size pushed (always zero)
-size_t CodeGen::genPushArgList(GenTreePtr call)
+size_t CodeGen::genPushArgList(GenTreeCall* call)
{
-
- GenTreeArgList* lateArgs = call->gtCall.gtCallLateArgs;
+ GenTreeArgList* lateArgs = call->gtCallLateArgs;
GenTreePtr curr;
var_types type;
int argSize;
@@ -16520,14 +16509,14 @@ size_t CodeGen::genPushArgList(GenTreePtr call)
// Create a local, artificial GenTreeArgList that includes the gtCallObjp, if that exists, as first argument,
// so we can iterate over this argument list more uniformly.
// Need to provide a temporary non-null first argument here: if we use this, we'll replace it.
- GenTreeArgList objpArgList(/*temp dummy arg*/ call, call->gtCall.gtCallArgs);
- if (call->gtCall.gtCallObjp == NULL)
+ GenTreeArgList objpArgList(/*temp dummy arg*/ call, call->gtCallArgs);
+ if (call->gtCallObjp == NULL)
{
- args = call->gtCall.gtCallArgs;
+ args = call->gtCallArgs;
}
else
{
- objpArgList.Current() = call->gtCall.gtCallObjp;
+ objpArgList.Current() = call->gtCallObjp;
args = &objpArgList;
}
@@ -17478,14 +17467,14 @@ regMaskTP CodeGen::genFindDeadFieldRegs(GenTreePtr cpBlk)
return res;
}
-void CodeGen::SetupLateArgs(GenTreePtr call)
+void CodeGen::SetupLateArgs(GenTreeCall* call)
{
GenTreeArgList* lateArgs;
GenTreePtr curr;
/* Generate the code to move the late arguments into registers */
- for (lateArgs = call->gtCall.gtCallLateArgs; lateArgs; lateArgs = lateArgs->Rest())
+ for (lateArgs = call->gtCallLateArgs; lateArgs; lateArgs = lateArgs->Rest())
{
curr = lateArgs->Current();
assert(curr);
@@ -18035,7 +18024,7 @@ void CodeGen::SetupLateArgs(GenTreePtr call)
/* If any of the previously loaded arguments were spilled - reload them */
- for (lateArgs = call->gtCall.gtCallLateArgs; lateArgs; lateArgs = lateArgs->Rest())
+ for (lateArgs = call->gtCallLateArgs; lateArgs; lateArgs = lateArgs->Rest())
{
curr = lateArgs->Current();
assert(curr);
@@ -18139,9 +18128,9 @@ void CodeGen::PushMkRefAnyArg(GenTreePtr mkRefAnyTree, fgArgTabEntryPtr curArgTa
#endif // FEATURE_FIXED_OUT_ARGS
-regMaskTP CodeGen::genLoadIndirectCallTarget(GenTreePtr call)
+regMaskTP CodeGen::genLoadIndirectCallTarget(GenTreeCall* call)
{
- assert((gtCallTypes)call->gtCall.gtCallType == CT_INDIRECT);
+ assert((gtCallTypes)call->gtCallType == CT_INDIRECT);
regMaskTP fptrRegs;
@@ -18192,7 +18181,7 @@ regMaskTP CodeGen::genLoadIndirectCallTarget(GenTreePtr call)
}
/* Record the register(s) used for the indirect call func ptr */
- fptrRegs = genMakeRvalueAddressable(call->gtCall.gtCallAddr, prefRegs, RegSet::KEEP_REG, false);
+ fptrRegs = genMakeRvalueAddressable(call->gtCallAddr, prefRegs, RegSet::KEEP_REG, false);
/* If any of the previously loaded arguments were spilled, reload them */
@@ -18215,7 +18204,7 @@ regMaskTP CodeGen::genLoadIndirectCallTarget(GenTreePtr call)
/* Make sure the target is still addressable while avoiding the argument registers */
- fptrRegs = genKeepAddressable(call->gtCall.gtCallAddr, fptrRegs, argRegs);
+ fptrRegs = genKeepAddressable(call->gtCallAddr, fptrRegs, argRegs);
return fptrRegs;
}
@@ -18231,7 +18220,7 @@ regMaskTP CodeGen::genLoadIndirectCallTarget(GenTreePtr call)
#pragma warning(push)
#pragma warning(disable : 21000) // Suppress PREFast warning about overly large function
#endif
-regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
+regMaskTP CodeGen::genCodeForCall(GenTreeCall* call, bool valUsed)
{
emitAttr retSize;
size_t argSize;
@@ -18263,7 +18252,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
}
#endif
- gtCallTypes callType = (gtCallTypes)call->gtCall.gtCallType;
+ gtCallTypes callType = (gtCallTypes)call->gtCallType;
IL_OFFSETX ilOffset = BAD_IL_OFFSET;
CORINFO_SIG_INFO* sigInfo = nullptr;
@@ -18275,13 +18264,11 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
/* Make some sanity checks on the call node */
- // This is a call
- noway_assert(call->IsCall());
// "this" only makes sense for user functions
- noway_assert(call->gtCall.gtCallObjp == 0 || callType == CT_USER_FUNC || callType == CT_INDIRECT);
+ noway_assert(call->gtCallObjp == 0 || callType == CT_USER_FUNC || callType == CT_INDIRECT);
// tailcalls won't be done for helpers, caller-pop args, and check that
// the global flag is set
- noway_assert(!call->gtCall.IsTailCall() ||
+ noway_assert(!call->IsTailCall() ||
(callType != CT_HELPER && !(call->gtFlags & GTF_CALL_POP_ARGS) && compiler->compTailCallUsed));
#ifdef DEBUG
@@ -18289,7 +18276,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
// native call sites with the signatures they were generated from.
if (callType != CT_HELPER)
{
- sigInfo = call->gtCall.callSig;
+ sigInfo = call->callSig;
}
#endif // DEBUG
@@ -18338,7 +18325,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
/* Pass the arguments */
- if ((call->gtCall.gtCallObjp != NULL) || (call->gtCall.gtCallArgs != NULL))
+ if ((call->gtCallObjp != NULL) || (call->gtCallArgs != NULL))
{
argSize += genPushArgList(call);
}
@@ -18422,8 +18409,8 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
/* Do not spill the argument registers.
Multi-use of RBM_ARG_REGS should be prevented by genPushArgList() */
- noway_assert((regSet.rsMaskMult & call->gtCall.gtCallRegUsedMask) == 0);
- spillRegs &= ~call->gtCall.gtCallRegUsedMask;
+ noway_assert((regSet.rsMaskMult & call->gtCallRegUsedMask) == 0);
+ spillRegs &= ~call->gtCallRegUsedMask;
if (spillRegs)
{
@@ -18449,7 +18436,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
compCurFPState.Push(regReturn);
}
#else
- SpillForCallRegisterFP(call->gtCall.gtCallRegUsedMask);
+ SpillForCallRegisterFP(call->gtCallRegUsedMask);
#endif
/* If the method returns a GC ref, set size to EA_GCREF or EA_BYREF */
@@ -18487,7 +18474,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
/* fire the event at the call site */
/* alas, right now I can only handle calls via a method handle */
- if (compiler->compIsProfilerHookNeeded() && (callType == CT_USER_FUNC) && call->gtCall.IsTailCall())
+ if (compiler->compIsProfilerHookNeeded() && (callType == CT_USER_FUNC) && call->IsTailCall())
{
unsigned saveStackLvl2 = genStackLevel;
@@ -18499,7 +18486,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
#ifdef _TARGET_X86_
regMaskTP byrefPushedRegs;
regMaskTP norefPushedRegs;
- regMaskTP pushedArgRegs = genPushRegs(call->gtCall.gtCallRegUsedMask, &byrefPushedRegs, &norefPushedRegs);
+ regMaskTP pushedArgRegs = genPushRegs(call->gtCallRegUsedMask, &byrefPushedRegs, &norefPushedRegs);
if (compiler->compProfilerMethHndIndirected)
{
@@ -18521,6 +18508,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
//
if (compiler->fgPtrArgCntMax < 1)
{
+ JITDUMP("Upping fgPtrArgCntMax from %d to 1\n", compiler->fgPtrArgCntMax);
compiler->fgPtrArgCntMax = 1;
}
@@ -18582,7 +18570,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
#endif //_TARGET_X86_
/* Restore the stack level */
- genStackLevel = saveStackLvl2;
+ SetStackLevel(saveStackLvl2);
}
#endif // PROFILING_SUPPORTED
@@ -18597,7 +18585,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
// check the stacks as frequently as possible
&& !call->IsHelperCall()
#else
- && call->gtCall.gtCallType == CT_USER_FUNC
+ && call->gtCallType == CT_USER_FUNC
#endif
)
{
@@ -18617,18 +18605,18 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
bool fTailCallTargetIsVSD = false;
- bool fTailCall = (call->gtCall.gtCallMoreFlags & GTF_CALL_M_TAILCALL) != 0;
+ bool fTailCall = (call->gtCallMoreFlags & GTF_CALL_M_TAILCALL) != 0;
/* Check for Delegate.Invoke. If so, we inline it. We get the
target-object and target-function from the delegate-object, and do
an indirect call.
*/
- if ((call->gtCall.gtCallMoreFlags & GTF_CALL_M_DELEGATE_INV) && !fTailCall)
+ if ((call->gtCallMoreFlags & GTF_CALL_M_DELEGATE_INV) && !fTailCall)
{
- noway_assert(call->gtCall.gtCallType == CT_USER_FUNC);
+ noway_assert(call->gtCallType == CT_USER_FUNC);
- assert((compiler->info.compCompHnd->getMethodAttribs(call->gtCall.gtCallMethHnd) &
+ assert((compiler->info.compCompHnd->getMethodAttribs(call->gtCallMethHnd) &
(CORINFO_FLG_DELEGATE_INVOKE | CORINFO_FLG_FINAL)) ==
(CORINFO_FLG_DELEGATE_INVOKE | CORINFO_FLG_FINAL));
@@ -18644,7 +18632,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
firstTgtOffs = pInfo->offsetOfDelegateFirstTarget;
#ifdef _TARGET_ARM_
- if ((call->gtCall.gtCallMoreFlags & GTF_CALL_M_SECURE_DELEGATE_INV))
+ if ((call->gtCallMoreFlags & GTF_CALL_M_SECURE_DELEGATE_INV))
{
getEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, REG_VIRTUAL_STUB_PARAM, regThis,
pInfo->offsetOfSecureDelegateIndirectCell);
@@ -18725,13 +18713,13 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
// No need to null check the this pointer - the dispatch code will deal with this.
- noway_assert(genStillAddressable(call->gtCall.gtCallAddr));
+ noway_assert(genStillAddressable(call->gtCallAddr));
// Now put the address in REG_VIRTUAL_STUB_PARAM.
// This is typically a nop when the register used for
// the gtCallAddr is REG_VIRTUAL_STUB_PARAM
//
- inst_RV_TT(INS_mov, REG_VIRTUAL_STUB_PARAM, call->gtCall.gtCallAddr);
+ inst_RV_TT(INS_mov, REG_VIRTUAL_STUB_PARAM, call->gtCallAddr);
regTracker.rsTrackRegTrash(REG_VIRTUAL_STUB_PARAM);
#if defined(_TARGET_X86_)
@@ -18749,11 +18737,11 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
emitCallType = emitter::EC_INDIR_ARD;
indReg = REG_VIRTUAL_STUB_PARAM;
- genDoneAddressable(call->gtCall.gtCallAddr, fptrRegs, RegSet::KEEP_REG);
+ genDoneAddressable(call->gtCallAddr, fptrRegs, RegSet::KEEP_REG);
#elif CPU_LOAD_STORE_ARCH // ARM doesn't allow us to use an indirection for the call
- genDoneAddressable(call->gtCall.gtCallAddr, fptrRegs, RegSet::KEEP_REG);
+ genDoneAddressable(call->gtCallAddr, fptrRegs, RegSet::KEEP_REG);
// Make the virtual stub call:
// ldr indReg, [REG_VIRTUAL_STUB_PARAM]
@@ -18764,7 +18752,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
// Now dereference [REG_VIRTUAL_STUB_PARAM] and put it in a new temp register 'indReg'
//
indReg = regSet.rsGrabReg(RBM_ALLINT & ~RBM_VIRTUAL_STUB_PARAM);
- assert(call->gtCall.gtCallAddr->gtFlags & GTF_REG_VAL);
+ assert(call->gtCallAddr->gtFlags & GTF_REG_VAL);
getEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, indReg, REG_VIRTUAL_STUB_PARAM, 0);
regTracker.rsTrackRegTrash(indReg);
@@ -18787,7 +18775,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
// Get stub addr. This will return NULL if virtual call stubs are not active
void* stubAddr = NULL;
- stubAddr = (void*)call->gtCall.gtStubCallStubAddr;
+ stubAddr = (void*)call->gtStubCallStubAddr;
noway_assert(stubAddr != NULL);
@@ -18803,7 +18791,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
int disp = 0;
regNumber callReg = REG_NA;
- if (call->gtCall.gtCallMoreFlags & GTF_CALL_M_VIRTSTUB_REL_INDIRECT)
+ if (call->gtCallMoreFlags & GTF_CALL_M_VIRTSTUB_REL_INDIRECT)
{
#if CPU_LOAD_STORE_ARCH
callReg = regSet.rsGrabReg(RBM_VIRTUAL_STUB_PARAM);
@@ -18833,7 +18821,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
if (callTypeStubAddr != emitter::EC_INDIR_R)
#endif
{
- getEmitter()->emitIns_Call(callTypeStubAddr, call->gtCall.gtCallMethHnd,
+ getEmitter()->emitIns_Call(callTypeStubAddr, call->gtCallMethHnd,
INDEBUG_LDISASM_COMMA(sigInfo) addr, args, retSize,
gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur,
gcInfo.gcRegByrefSetCur, ilOffset, callReg, REG_NA, 0, disp);
@@ -18855,21 +18843,21 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
if (callType == CT_INDIRECT)
{
- noway_assert(genStillAddressable(call->gtCall.gtCallAddr));
+ noway_assert(genStillAddressable(call->gtCallAddr));
// Now put the address in EAX.
- inst_RV_TT(INS_mov, REG_TAILCALL_ADDR, call->gtCall.gtCallAddr);
+ inst_RV_TT(INS_mov, REG_TAILCALL_ADDR, call->gtCallAddr);
regTracker.rsTrackRegTrash(REG_TAILCALL_ADDR);
- genDoneAddressable(call->gtCall.gtCallAddr, fptrRegs, RegSet::KEEP_REG);
+ genDoneAddressable(call->gtCallAddr, fptrRegs, RegSet::KEEP_REG);
}
else
{
// importer/EE should guarantee the indirection
- noway_assert(call->gtCall.gtCallMoreFlags & GTF_CALL_M_VIRTSTUB_REL_INDIRECT);
+ noway_assert(call->gtCallMoreFlags & GTF_CALL_M_VIRTSTUB_REL_INDIRECT);
instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, REG_TAILCALL_ADDR,
- ssize_t(call->gtCall.gtStubCallStubAddr));
+ ssize_t(call->gtStubCallStubAddr));
}
fTailCallTargetIsVSD = true;
@@ -18903,12 +18891,11 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
VPTR_OFFS);
regTracker.rsTrackRegTrash(vptrReg);
- noway_assert(vptrMask & ~call->gtCall.gtCallRegUsedMask);
+ noway_assert(vptrMask & ~call->gtCallRegUsedMask);
/* Get hold of the vtable offset (note: this might be expensive) */
- compiler->info.compCompHnd->getMethodVTableOffset(call->gtCall.gtCallMethHnd,
- &vtabOffsOfIndirection,
+ compiler->info.compCompHnd->getMethodVTableOffset(call->gtCallMethHnd, &vtabOffsOfIndirection,
&vtabOffsAfterIndirection);
/* Get the appropriate vtable chunk */
@@ -18935,13 +18922,13 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
getEmitter()->emitIns_R_AR(ins_Load(TYP_I_IMPL), EA_PTRSIZE, vptrReg, vptrReg,
vtabOffsAfterIndirection);
- getEmitter()->emitIns_Call(emitter::EC_INDIR_R, call->gtCall.gtCallMethHnd,
+ getEmitter()->emitIns_Call(emitter::EC_INDIR_R, call->gtCallMethHnd,
INDEBUG_LDISASM_COMMA(sigInfo) NULL, // addr
args, retSize, gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur,
gcInfo.gcRegByrefSetCur, ilOffset,
vptrReg); // ireg
#else
- getEmitter()->emitIns_Call(emitter::EC_FUNC_VIRTUAL, call->gtCall.gtCallMethHnd,
+ getEmitter()->emitIns_Call(emitter::EC_FUNC_VIRTUAL, call->gtCallMethHnd,
INDEBUG_LDISASM_COMMA(sigInfo) NULL, // addr
args, retSize, gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur,
gcInfo.gcRegByrefSetCur, ilOffset,
@@ -18967,7 +18954,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
// - Indirect calls to computed addresses
// - Tailcall versions of all of the above
- CORINFO_METHOD_HANDLE methHnd = call->gtCall.gtCallMethHnd;
+ CORINFO_METHOD_HANDLE methHnd = call->gtCallMethHnd;
//------------------------------------------------------
// Non-virtual/Indirect calls: Insert a null check on the "this" pointer if needed
@@ -19015,10 +19002,10 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
if (callType == CT_INDIRECT)
{
- noway_assert(genStillAddressable(call->gtCall.gtCallAddr));
+ noway_assert(genStillAddressable(call->gtCallAddr));
- if (call->gtCall.gtCallAddr->gtFlags & GTF_REG_VAL)
- indCallReg = call->gtCall.gtCallAddr->gtRegNum;
+ if (call->gtCallAddr->gtFlags & GTF_REG_VAL)
+ indCallReg = call->gtCallAddr->gtRegNum;
nArgSize = (call->gtFlags & GTF_CALL_POP_ARGS) ? 0 : (int)argSize;
methHnd = 0;
@@ -19053,7 +19040,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
anyways.
*/
- inst_RV_TT(INS_mov, indCallReg, call->gtCall.gtCallAddr);
+ inst_RV_TT(INS_mov, indCallReg, call->gtCallAddr);
regTracker.rsTrackRegTrash(indCallReg);
}
@@ -19121,7 +19108,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
ilOffset, indCallReg);
if (callType == CT_INDIRECT)
- genDoneAddressable(call->gtCall.gtCallAddr, fptrRegs, RegSet::KEEP_REG);
+ genDoneAddressable(call->gtCallAddr, fptrRegs, RegSet::KEEP_REG);
getEmitter()->emitEnableRandomNops();
@@ -19131,15 +19118,15 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
if (callType == CT_INDIRECT)
{
- noway_assert(genStillAddressable(call->gtCall.gtCallAddr));
+ noway_assert(genStillAddressable(call->gtCallAddr));
- if (call->gtCall.gtCallCookie)
+ if (call->gtCallCookie)
{
//------------------------------------------------------
// Non-virtual indirect calls via the P/Invoke stub
- GenTreePtr cookie = call->gtCall.gtCallCookie;
- GenTreePtr target = call->gtCall.gtCallAddr;
+ GenTreePtr cookie = call->gtCallCookie;
+ GenTreePtr target = call->gtCallAddr;
noway_assert((call->gtFlags & GTF_CALL_POP_ARGS) == 0);
@@ -19188,8 +19175,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
// Ensure that we don't trash any of these registers if we have to load
// the helper call target into a register to invoke it.
regMaskTP regsUsed;
- regSet.rsLockReg(call->gtCall.gtCallRegUsedMask | RBM_PINVOKE_TARGET_PARAM |
- RBM_PINVOKE_COOKIE_PARAM,
+ regSet.rsLockReg(call->gtCallRegUsedMask | RBM_PINVOKE_TARGET_PARAM | RBM_PINVOKE_COOKIE_PARAM,
&regsUsed);
#else
NYI("Non-virtual indirect calls via the P/Invoke stub");
@@ -19201,7 +19187,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
genEmitHelperCall(CORINFO_HELP_PINVOKE_CALLI, (int)args, retSize);
#if defined(_TARGET_ARM_)
- regSet.rsUnlockReg(call->gtCall.gtCallRegUsedMask | RBM_PINVOKE_TARGET_PARAM |
+ regSet.rsUnlockReg(call->gtCallRegUsedMask | RBM_PINVOKE_TARGET_PARAM |
RBM_PINVOKE_COOKIE_PARAM,
regsUsed);
#endif
@@ -19218,14 +19204,14 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
if (fTailCall)
{
- inst_RV_TT(INS_mov, REG_TAILCALL_ADDR, call->gtCall.gtCallAddr);
+ inst_RV_TT(INS_mov, REG_TAILCALL_ADDR, call->gtCallAddr);
regTracker.rsTrackRegTrash(REG_TAILCALL_ADDR);
}
else
instEmit_indCall(call, args, retSize);
}
- genDoneAddressable(call->gtCall.gtCallAddr, fptrRegs, RegSet::KEEP_REG);
+ genDoneAddressable(call->gtCallAddr, fptrRegs, RegSet::KEEP_REG);
// Done with indirect calls
break;
@@ -19264,7 +19250,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
CORINFO_ACCESS_FLAGS aflags = CORINFO_ACCESS_ANY;
- if (call->gtCall.gtCallMoreFlags & GTF_CALL_M_NONVIRT_SAME_THIS)
+ if (call->gtCallMoreFlags & GTF_CALL_M_NONVIRT_SAME_THIS)
aflags = (CORINFO_ACCESS_FLAGS)(aflags | CORINFO_ACCESS_THIS);
if ((call->gtFlags & GTF_CALL_NULLCHECK) == 0)
@@ -19362,7 +19348,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
getEmitter()->emitCurIGsize + // size of the current IG
4; // size of the jump instruction
// that we are now emitting
- if (compiler->gtIsRecursiveCall(call->AsCall()) && codeOffset <= -CALL_DIST_MAX_NEG)
+ if (compiler->gtIsRecursiveCall(call) && codeOffset <= -CALL_DIST_MAX_NEG)
{
getEmitter()->emitIns_Call(emitter::EC_FUNC_TOKEN, methHnd,
INDEBUG_LDISASM_COMMA(sigInfo) NULL, // addr
@@ -19576,7 +19562,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
regMaskTP curArgMask = genMapArgNumToRegMask(areg, TYP_INT);
// Is this one of the used argument registers?
- if ((curArgMask & call->gtCall.gtCallRegUsedMask) == 0)
+ if ((curArgMask & call->gtCallRegUsedMask) == 0)
continue;
#ifdef _TARGET_ARM_
@@ -19609,7 +19595,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
regMaskTP curArgMask = genMapArgNumToRegMask(areg, TYP_FLOAT);
// Is this one of the used argument registers?
- if ((curArgMask & call->gtCall.gtCallRegUsedMask) == 0)
+ if ((curArgMask & call->gtCallRegUsedMask) == 0)
continue;
regSet.rsMaskUsed &= ~curArgMask;
@@ -19660,7 +19646,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
if (call->gtType == TYP_FLOAT || call->gtType == TYP_DOUBLE)
{
#ifdef _TARGET_ARM_
- if (call->gtCall.IsVarargs() || compiler->opts.compUseSoftFP)
+ if (call->IsVarargs() || compiler->opts.compUseSoftFP)
{
// Result return for vararg methods is in r0, r1, but our callers would
// expect the return in s0, s1 because of floating type. Do the move now.
@@ -19680,7 +19666,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
/* The function will pop all arguments before returning */
- genStackLevel = saveStackLvl;
+ SetStackLevel(saveStackLvl);
/* No trashed registers may possibly hold a pointer at this point */
CLANG_FORMAT_COMMENT_ANCHOR;
@@ -19885,9 +19871,9 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
#ifdef _TARGET_ARM_
case TYP_STRUCT:
{
- assert(call->gtCall.gtRetClsHnd != NULL);
- assert(compiler->IsHfa(call->gtCall.gtRetClsHnd));
- int retSlots = compiler->GetHfaCount(call->gtCall.gtRetClsHnd);
+ assert(call->gtRetClsHnd != NULL);
+ assert(compiler->IsHfa(call->gtRetClsHnd));
+ int retSlots = compiler->GetHfaCount(call->gtRetClsHnd);
assert(retSlots > 0 && retSlots <= MAX_HFA_RET_SLOTS);
assert(MAX_HFA_RET_SLOTS < sizeof(int) * 8);
retVal = ((1 << retSlots) - 1) << REG_FLOATRET;
@@ -19924,7 +19910,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
if (frameListRoot)
genPInvokeCallEpilog(frameListRoot, retVal);
- if (frameListRoot && (call->gtCall.gtCallMoreFlags & GTF_CALL_M_FRAME_VAR_DEATH))
+ if (frameListRoot && (call->gtCallMoreFlags & GTF_CALL_M_FRAME_VAR_DEATH))
{
if (frameListRoot->lvRegister)
{
@@ -19940,7 +19926,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreePtr call, bool valUsed)
// check the stack as frequently as possible
&& !call->IsHelperCall()
#else
- && call->gtCall.gtCallType == CT_USER_FUNC
+ && call->gtCallType == CT_USER_FUNC
#endif
)
{
@@ -20175,12 +20161,14 @@ void CodeGen::genCreateAndStoreGCInfoX64(unsigned codeSize, unsigned prologSize
// Follow the code pattern of the x86 gc info encoder (genCreateAndStoreGCInfoJIT32).
gcInfo.gcInfoBlockHdrSave(gcInfoEncoder, codeSize, prologSize);
+ // We keep the call count for the second call to gcMakeRegPtrTable() below.
+ unsigned callCnt = 0;
// First we figure out the encoder ID's for the stack slots and registers.
- gcInfo.gcMakeRegPtrTable(gcInfoEncoder, codeSize, prologSize, GCInfo::MAKE_REG_PTR_MODE_ASSIGN_SLOTS);
+ gcInfo.gcMakeRegPtrTable(gcInfoEncoder, codeSize, prologSize, GCInfo::MAKE_REG_PTR_MODE_ASSIGN_SLOTS, &callCnt);
// Now we've requested all the slots we'll need; "finalize" these (make more compact data structures for them).
gcInfoEncoder->FinalizeSlotIds();
// Now we can actually use those slot ID's to declare live ranges.
- gcInfo.gcMakeRegPtrTable(gcInfoEncoder, codeSize, prologSize, GCInfo::MAKE_REG_PTR_MODE_DO_WORK);
+ gcInfo.gcMakeRegPtrTable(gcInfoEncoder, codeSize, prologSize, GCInfo::MAKE_REG_PTR_MODE_DO_WORK, &callCnt);
gcInfoEncoder->Build();
@@ -21041,8 +21029,6 @@ regMaskTP CodeGen::genPInvokeMethodProlog(regMaskTP initRegs)
}
else
{
- noway_assert(pInfo->osMajor >= 5);
-
DWORD basePtr = WIN_NT5_TLS_HIGHOFFSET;
threadTlsIndex -= 64;
diff --git a/src/jit/codegenlinear.cpp b/src/jit/codegenlinear.cpp
index 329c4a755f..c8fcd88c10 100644
--- a/src/jit/codegenlinear.cpp
+++ b/src/jit/codegenlinear.cpp
@@ -246,6 +246,10 @@ void CodeGen::genCodeForBBlist()
}
}
+#if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
+ genInsertNopForUnwinder(block);
+#endif
+
/* Start a new code output block */
genUpdateCurrentFunclet(block);
@@ -292,7 +296,7 @@ void CodeGen::genCodeForBBlist()
/* Both stacks are always empty on entry to a basic block */
- genStackLevel = 0;
+ SetStackLevel(0);
genAdjustStackLevel(block);
savedStkLvl = genStackLevel;
@@ -486,7 +490,7 @@ void CodeGen::genCodeForBBlist()
}
}
- genStackLevel -= savedStkLvl;
+ SubtractStackLevel(savedStkLvl);
#ifdef DEBUG
// compCurLife should be equal to the liveOut set, except that we don't keep
@@ -1731,43 +1735,73 @@ void CodeGen::genTransferRegGCState(regNumber dst, regNumber src)
// pass in 'addr' for a relative call or 'base' for a indirect register call
// methHnd - optional, only used for pretty printing
// retSize - emitter type of return for GC purposes, should be EA_BYREF, EA_GCREF, or EA_PTRSIZE(not GC)
+//
+// clang-format off
void CodeGen::genEmitCall(int callType,
CORINFO_METHOD_HANDLE methHnd,
- INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo) void* addr X86_ARG(ssize_t argSize),
- emitAttr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
- IL_OFFSETX ilOffset,
- regNumber base,
- bool isJump,
- bool isNoGC)
+ INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo)
+ void* addr
+ X86_ARG(ssize_t argSize),
+ emitAttr retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
+ IL_OFFSETX ilOffset,
+ regNumber base,
+ bool isJump,
+ bool isNoGC)
{
#if !defined(_TARGET_X86_)
ssize_t argSize = 0;
#endif // !defined(_TARGET_X86_)
- getEmitter()->emitIns_Call(emitter::EmitCallType(callType), methHnd, INDEBUG_LDISASM_COMMA(sigInfo) addr, argSize,
- retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize), gcInfo.gcVarPtrSetCur,
- gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur, ilOffset, base, REG_NA, 0, 0, isJump,
+ getEmitter()->emitIns_Call(emitter::EmitCallType(callType),
+ methHnd,
+ INDEBUG_LDISASM_COMMA(sigInfo)
+ addr,
+ argSize,
+ retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
+ gcInfo.gcVarPtrSetCur,
+ gcInfo.gcRegGCrefSetCur,
+ gcInfo.gcRegByrefSetCur,
+ ilOffset, base, REG_NA, 0, 0, isJump,
emitter::emitNoGChelper(compiler->eeGetHelperNum(methHnd)));
}
+// clang-format on
// generates an indirect call via addressing mode (call []) given an indir node
// methHnd - optional, only used for pretty printing
// retSize - emitter type of return for GC purposes, should be EA_BYREF, EA_GCREF, or EA_PTRSIZE(not GC)
+//
+// clang-format off
void CodeGen::genEmitCall(int callType,
CORINFO_METHOD_HANDLE methHnd,
- INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo) GenTreeIndir* indir X86_ARG(ssize_t argSize),
- emitAttr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
- IL_OFFSETX ilOffset)
+ INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo)
+ GenTreeIndir* indir
+ X86_ARG(ssize_t argSize),
+ emitAttr retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
+ IL_OFFSETX ilOffset)
{
#if !defined(_TARGET_X86_)
ssize_t argSize = 0;
#endif // !defined(_TARGET_X86_)
genConsumeAddress(indir->Addr());
- getEmitter()->emitIns_Call(emitter::EmitCallType(callType), methHnd, INDEBUG_LDISASM_COMMA(sigInfo) nullptr,
- argSize, retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
- gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur, ilOffset,
- indir->Base() ? indir->Base()->gtRegNum : REG_NA,
- indir->Index() ? indir->Index()->gtRegNum : REG_NA, indir->Scale(), indir->Offset());
+ getEmitter()->emitIns_Call(emitter::EmitCallType(callType),
+ methHnd,
+ INDEBUG_LDISASM_COMMA(sigInfo)
+ nullptr,
+ argSize,
+ retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
+ gcInfo.gcVarPtrSetCur,
+ gcInfo.gcRegGCrefSetCur,
+ gcInfo.gcRegByrefSetCur,
+ ilOffset,
+ (indir->Base() != nullptr) ? indir->Base()->gtRegNum : REG_NA,
+ (indir->Index() != nullptr) ? indir->Index()->gtRegNum : REG_NA,
+ indir->Scale(),
+ indir->Offset());
}
+// clang-format on
#endif // !LEGACY_BACKEND
diff --git a/src/jit/codegenlinear.h b/src/jit/codegenlinear.h
index c8a5af657a..fa0c85c749 100644
--- a/src/jit/codegenlinear.h
+++ b/src/jit/codegenlinear.h
@@ -57,6 +57,10 @@ void genCompareInt(GenTreePtr treeNode);
#if !defined(_TARGET_64BIT_)
void genCompareLong(GenTreePtr treeNode);
+#if defined(_TARGET_ARM_)
+void genJccLongHi(genTreeOps cmp, BasicBlock* jumpTrue, BasicBlock* jumpFalse, bool isUnsigned = false);
+void genJccLongLo(genTreeOps cmp, BasicBlock* jumpTrue, BasicBlock* jumpFalse);
+#endif // defined(_TARGET_ARM_)
#endif
#ifdef FEATURE_SIMD
@@ -154,7 +158,7 @@ void genSetRegToIcon(regNumber reg, ssize_t val, var_types type = TYP_INT, insFl
void genCodeForShift(GenTreePtr tree);
-#if defined(_TARGET_X86_)
+#if defined(_TARGET_X86_) || defined(_TARGET_ARM_)
void genCodeForShiftLong(GenTreePtr tree);
#endif
@@ -170,6 +174,44 @@ void genCodeForCpBlkRepMovs(GenTreeBlk* cpBlkNode);
void genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode);
+void genAlignStackBeforeCall(GenTreePutArgStk* putArgStk);
+void genAlignStackBeforeCall(GenTreeCall* call);
+void genRemoveAlignmentAfterCall(GenTreeCall* call, unsigned bias = 0);
+
+#if defined(UNIX_X86_ABI)
+
+unsigned curNestedAlignment; // Keep track of alignment adjustment required during codegen.
+unsigned maxNestedAlignment; // The maximum amount of alignment adjustment required.
+
+void SubtractNestedAlignment(unsigned adjustment)
+{
+ assert(curNestedAlignment >= adjustment);
+ unsigned newNestedAlignment = curNestedAlignment - adjustment;
+ if (curNestedAlignment != newNestedAlignment)
+ {
+ JITDUMP("Adjusting stack nested alignment from %d to %d\n", curNestedAlignment, newNestedAlignment);
+ }
+ curNestedAlignment = newNestedAlignment;
+}
+
+void AddNestedAlignment(unsigned adjustment)
+{
+ unsigned newNestedAlignment = curNestedAlignment + adjustment;
+ if (curNestedAlignment != newNestedAlignment)
+ {
+ JITDUMP("Adjusting stack nested alignment from %d to %d\n", curNestedAlignment, newNestedAlignment);
+ }
+ curNestedAlignment = newNestedAlignment;
+
+ if (curNestedAlignment > maxNestedAlignment)
+ {
+ JITDUMP("Max stack nested alignment changed from %d to %d\n", maxNestedAlignment, curNestedAlignment);
+ maxNestedAlignment = curNestedAlignment;
+ }
+}
+
+#endif
+
#ifdef FEATURE_PUT_STRUCT_ARG_STK
#ifdef _TARGET_X86_
bool genAdjustStackForPutArgStk(GenTreePutArgStk* putArgStk);
@@ -179,10 +221,10 @@ void genPutArgStkFieldList(GenTreePutArgStk* putArgStk);
void genPutStructArgStk(GenTreePutArgStk* treeNode);
-int genMove8IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
-int genMove4IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
-int genMove2IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
-int genMove1IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
+unsigned genMove8IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
+unsigned genMove4IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
+unsigned genMove2IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
+unsigned genMove1IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset);
void genStructPutArgRepMovs(GenTreePutArgStk* putArgStkNode);
void genStructPutArgUnroll(GenTreePutArgStk* putArgStkNode);
void genStoreRegToStackArg(var_types type, regNumber reg, int offset);
@@ -190,7 +232,13 @@ void genStoreRegToStackArg(var_types type, regNumber reg, int offset);
void genCodeForLoadOffset(instruction ins, emitAttr size, regNumber dst, GenTree* base, unsigned offset);
-void genCodeForStoreOffset(instruction ins, emitAttr size, regNumber dst, GenTree* base, unsigned offset);
+void genCodeForStoreOffset(instruction ins, emitAttr size, regNumber src, GenTree* base, unsigned offset);
+
+#ifdef _TARGET_ARM64_
+void genCodeForLoadPairOffset(regNumber dst, regNumber dst2, GenTree* base, unsigned offset);
+
+void genCodeForStorePairOffset(regNumber src, regNumber src2, GenTree* base, unsigned offset);
+#endif // _TARGET_ARM64_
void genCodeForStoreBlk(GenTreeBlk* storeBlkNode);
@@ -214,7 +262,7 @@ void genStoreInd(GenTreePtr node);
bool genEmitOptimizedGCWriteBarrier(GCInfo::WriteBarrierForm writeBarrierForm, GenTree* addr, GenTree* data);
-void genCallInstruction(GenTreePtr call);
+void genCallInstruction(GenTreeCall* call);
void genJmpMethod(GenTreePtr jmp);
diff --git a/src/jit/codegenxarch.cpp b/src/jit/codegenxarch.cpp
index e893da6035..23c2a186a4 100644
--- a/src/jit/codegenxarch.cpp
+++ b/src/jit/codegenxarch.cpp
@@ -241,7 +241,9 @@ BasicBlock* CodeGen::genCallFinally(BasicBlock* block)
if ((compiler->lvaPSPSym == BAD_VAR_NUM) ||
(!compiler->compLocallocUsed && (compiler->funCurrentFunc()->funKind == FUNC_ROOT)))
{
+#ifndef UNIX_X86_ABI
inst_RV_RV(INS_mov, REG_ARG_0, REG_SPBASE, TYP_I_IMPL);
+#endif // !UNIX_X86_ABI
}
else
{
@@ -1264,8 +1266,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
if (compiler->verbose)
{
unsigned seqNum = treeNode->gtSeqNum; // Useful for setting a conditional break in Visual Studio
- printf("Generating: ");
- compiler->gtDispTree(treeNode, nullptr, nullptr, true);
+ compiler->gtDispLIRNode(treeNode, "Generating: ");
}
#endif // DEBUG
@@ -1313,7 +1314,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
case GT_CNS_INT:
#ifdef _TARGET_X86_
- NYI_IF(treeNode->IsIconHandle(GTF_ICON_TLS_HDL), "TLS constants");
+ assert(!treeNode->IsIconHandle(GTF_ICON_TLS_HDL));
#endif // _TARGET_X86_
__fallthrough;
@@ -1624,6 +1625,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
break;
case GT_IND:
+ {
#ifdef FEATURE_SIMD
// Handling of Vector3 type values loaded through indirection.
if (treeNode->TypeGet() == TYP_SIMD12)
@@ -1633,10 +1635,21 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
}
#endif // FEATURE_SIMD
- genConsumeAddress(treeNode->AsIndir()->Addr());
- emit->emitInsMov(ins_Load(treeNode->TypeGet()), emitTypeSize(treeNode), treeNode);
+ GenTree* addr = treeNode->AsIndir()->Addr();
+ if (addr->IsCnsIntOrI() && addr->IsIconHandle(GTF_ICON_TLS_HDL))
+ {
+ noway_assert(EA_ATTR(genTypeSize(treeNode->gtType)) == EA_PTRSIZE);
+ emit->emitIns_R_C(ins_Load(TYP_I_IMPL), EA_PTRSIZE, treeNode->gtRegNum, FLD_GLOBAL_FS,
+ (int)addr->gtIntCon.gtIconVal);
+ }
+ else
+ {
+ genConsumeAddress(addr);
+ emit->emitInsMov(ins_Load(treeNode->TypeGet()), emitTypeSize(treeNode), treeNode);
+ }
genProduceReg(treeNode);
- break;
+ }
+ break;
case GT_MULHI:
#ifdef _TARGET_X86_
@@ -2008,7 +2021,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
break;
case GT_CALL:
- genCallInstruction(treeNode);
+ genCallInstruction(treeNode->AsCall());
break;
case GT_JMP:
@@ -3223,7 +3236,7 @@ void CodeGen::genCodeForCpBlkRepMovs(GenTreeBlk* cpBlkNode)
// On x86, longTmpReg must be an xmm reg; on x64 it must be an integer register.
// This is checked by genStoreRegToStackArg.
//
-int CodeGen::genMove8IfNeeded(unsigned size, regNumber longTmpReg, GenTree* srcAddr, unsigned offset)
+unsigned CodeGen::genMove8IfNeeded(unsigned size, regNumber longTmpReg, GenTree* srcAddr, unsigned offset)
{
#ifdef _TARGET_X86_
instruction longMovIns = INS_movq;
@@ -3257,7 +3270,7 @@ int CodeGen::genMove8IfNeeded(unsigned size, regNumber longTmpReg, GenTree* srcA
// intTmpReg must be an integer register.
// This is checked by genStoreRegToStackArg.
//
-int CodeGen::genMove4IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
+unsigned CodeGen::genMove4IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
{
if ((size & 4) != 0)
{
@@ -3286,7 +3299,7 @@ int CodeGen::genMove4IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAd
// intTmpReg must be an integer register.
// This is checked by genStoreRegToStackArg.
//
-int CodeGen::genMove2IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
+unsigned CodeGen::genMove2IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
{
if ((size & 2) != 0)
{
@@ -3315,7 +3328,7 @@ int CodeGen::genMove2IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAd
// intTmpReg must be an integer register.
// This is checked by genStoreRegToStackArg.
//
-int CodeGen::genMove1IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
+unsigned CodeGen::genMove1IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset)
{
if ((size & 1) != 0)
@@ -3352,7 +3365,7 @@ void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode)
GenTreePtr dstAddr = putArgNode;
GenTreePtr src = putArgNode->gtOp.gtOp1;
- size_t size = putArgNode->getArgSize();
+ unsigned size = putArgNode->getArgSize();
assert(size <= CPBLK_UNROLL_LIMIT);
emitter* emit = getEmitter();
@@ -3813,6 +3826,7 @@ void CodeGen::genLockedInstructions(GenTreeOp* treeNode)
regNumber targetReg = treeNode->gtRegNum;
regNumber dataReg = data->gtRegNum;
regNumber addrReg = addr->gtRegNum;
+ var_types type = genActualType(data->TypeGet());
instruction ins;
// The register allocator should have extended the lifetime of the address
@@ -3827,7 +3841,7 @@ void CodeGen::genLockedInstructions(GenTreeOp* treeNode)
genConsumeOperands(treeNode);
if (targetReg != REG_NA && dataReg != REG_NA && dataReg != targetReg)
{
- inst_RV_RV(ins_Copy(data->TypeGet()), targetReg, dataReg);
+ inst_RV_RV(ins_Copy(type), targetReg, dataReg);
data->gtRegNum = targetReg;
// TODO-XArch-Cleanup: Consider whether it is worth it, for debugging purposes, to restore the
@@ -3853,8 +3867,8 @@ void CodeGen::genLockedInstructions(GenTreeOp* treeNode)
// all of these nodes implicitly do an indirection on op1
// so create a temporary node to feed into the pattern matching
- GenTreeIndir i = indirForm(data->TypeGet(), addr);
- getEmitter()->emitInsBinary(ins, emitTypeSize(data), &i, data);
+ GenTreeIndir i = indirForm(type, addr);
+ getEmitter()->emitInsBinary(ins, emitTypeSize(type), &i, data);
if (treeNode->gtRegNum != REG_NA)
{
@@ -4749,10 +4763,9 @@ bool CodeGen::genEmitOptimizedGCWriteBarrier(GCInfo::WriteBarrierForm writeBarri
}
// Produce code for a GT_CALL node
-void CodeGen::genCallInstruction(GenTreePtr node)
+void CodeGen::genCallInstruction(GenTreeCall* call)
{
- GenTreeCall* call = node->AsCall();
- assert(call->gtOper == GT_CALL);
+ genAlignStackBeforeCall(call);
gtCallTypes callType = (gtCallTypes)call->gtCallType;
@@ -4913,7 +4926,7 @@ void CodeGen::genCallInstruction(GenTreePtr node)
if (callType == CT_INDIRECT)
{
assert(target == nullptr);
- target = call->gtCall.gtCallAddr;
+ target = call->gtCallAddr;
methHnd = nullptr;
}
else
@@ -4993,16 +5006,30 @@ void CodeGen::genCallInstruction(GenTreePtr node)
}
#if defined(_TARGET_X86_)
+ bool fCallerPop = (call->gtFlags & GTF_CALL_POP_ARGS) != 0;
+
+#ifdef UNIX_X86_ABI
+ {
+ CorInfoCallConv callConv = CORINFO_CALLCONV_DEFAULT;
+
+ if ((callType != CT_HELPER) && call->callSig)
+ {
+ callConv = call->callSig->callConv;
+ }
+
+ fCallerPop |= IsCallerPop(callConv);
+ }
+#endif // UNIX_X86_ABI
+
// If the callee pops the arguments, we pass a positive value as the argSize, and the emitter will
// adjust its stack level accordingly.
// If the caller needs to explicitly pop its arguments, we must pass a negative value, and then do the
// pop when we're done.
ssize_t argSizeForEmitter = stackArgBytes;
- if ((call->gtFlags & GTF_CALL_POP_ARGS) != 0)
+ if (fCallerPop)
{
argSizeForEmitter = -stackArgBytes;
}
-
#endif // defined(_TARGET_X86_)
#ifdef FEATURE_AVX_SUPPORT
@@ -5044,11 +5071,20 @@ void CodeGen::genCallInstruction(GenTreePtr node)
genCopyRegIfNeeded(addr, REG_VIRTUAL_STUB_TARGET);
getEmitter()->emitIns_Nop(3);
- getEmitter()->emitIns_Call(emitter::EmitCallType(emitter::EC_INDIR_ARD), methHnd,
- INDEBUG_LDISASM_COMMA(sigInfo) nullptr, argSizeForEmitter,
- retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
- gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur,
+
+ // clang-format off
+ getEmitter()->emitIns_Call(emitter::EmitCallType(emitter::EC_INDIR_ARD),
+ methHnd,
+ INDEBUG_LDISASM_COMMA(sigInfo)
+ nullptr,
+ argSizeForEmitter,
+ retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
+ gcInfo.gcVarPtrSetCur,
+ gcInfo.gcRegGCrefSetCur,
+ gcInfo.gcRegByrefSetCur,
ilOffset, REG_VIRTUAL_STUB_TARGET, REG_NA, 1, 0);
+ // clang-format on
}
else
#endif
@@ -5060,18 +5096,29 @@ void CodeGen::genCallInstruction(GenTreePtr node)
// contained only if it can be encoded as PC-relative offset.
assert(target->AsIndir()->Base()->AsIntConCommon()->FitsInAddrBase(compiler));
- genEmitCall(emitter::EC_FUNC_TOKEN_INDIR, methHnd,
- INDEBUG_LDISASM_COMMA(sigInfo)(void*) target->AsIndir()
- ->Base()
- ->AsIntConCommon()
- ->IconValue() X86_ARG(argSizeForEmitter),
- retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize), ilOffset);
+ // clang-format off
+ genEmitCall(emitter::EC_FUNC_TOKEN_INDIR,
+ methHnd,
+ INDEBUG_LDISASM_COMMA(sigInfo)
+ (void*) target->AsIndir()->Base()->AsIntConCommon()->IconValue()
+ X86_ARG(argSizeForEmitter),
+ retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
+ ilOffset);
+ // clang-format on
}
else
{
- genEmitCall(emitter::EC_INDIR_ARD, methHnd,
- INDEBUG_LDISASM_COMMA(sigInfo) target->AsIndir() X86_ARG(argSizeForEmitter),
- retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize), ilOffset);
+ // clang-format off
+ genEmitCall(emitter::EC_INDIR_ARD,
+ methHnd,
+ INDEBUG_LDISASM_COMMA(sigInfo)
+ target->AsIndir()
+ X86_ARG(argSizeForEmitter),
+ retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
+ ilOffset);
+ // clang-format on
}
}
else
@@ -5079,19 +5126,34 @@ void CodeGen::genCallInstruction(GenTreePtr node)
// We have already generated code for gtControlExpr evaluating it into a register.
// We just need to emit "call reg" in this case.
assert(genIsValidIntReg(target->gtRegNum));
- genEmitCall(emitter::EC_INDIR_R, methHnd,
- INDEBUG_LDISASM_COMMA(sigInfo) nullptr // addr
+
+ // clang-format off
+ genEmitCall(emitter::EC_INDIR_R,
+ methHnd,
+ INDEBUG_LDISASM_COMMA(sigInfo)
+ nullptr // addr
X86_ARG(argSizeForEmitter),
- retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize), ilOffset, genConsumeReg(target));
+ retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
+ ilOffset,
+ genConsumeReg(target));
+ // clang-format on
}
}
#ifdef FEATURE_READYTORUN_COMPILER
else if (call->gtEntryPoint.addr != nullptr)
{
+ // clang-format off
genEmitCall((call->gtEntryPoint.accessType == IAT_VALUE) ? emitter::EC_FUNC_TOKEN
: emitter::EC_FUNC_TOKEN_INDIR,
- methHnd, INDEBUG_LDISASM_COMMA(sigInfo)(void*) call->gtEntryPoint.addr X86_ARG(argSizeForEmitter),
- retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize), ilOffset);
+ methHnd,
+ INDEBUG_LDISASM_COMMA(sigInfo)
+ (void*) call->gtEntryPoint.addr
+ X86_ARG(argSizeForEmitter),
+ retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
+ ilOffset);
+ // clang-format on
}
#endif
else
@@ -5127,18 +5189,18 @@ void CodeGen::genCallInstruction(GenTreePtr node)
}
// Non-virtual direct calls to known addresses
- genEmitCall(emitter::EC_FUNC_TOKEN, methHnd, INDEBUG_LDISASM_COMMA(sigInfo) addr X86_ARG(argSizeForEmitter),
- retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize), ilOffset);
- }
-#if defined(UNIX_X86_ABI)
- // Put back the stack pointer if there was any padding for stack alignment
- unsigned padStackAlign = call->fgArgInfo->GetPadStackAlign();
- if (padStackAlign != 0)
- {
- inst_RV_IV(INS_add, REG_SPBASE, padStackAlign * TARGET_POINTER_SIZE, EA_PTRSIZE);
+ // clang-format off
+ genEmitCall(emitter::EC_FUNC_TOKEN,
+ methHnd,
+ INDEBUG_LDISASM_COMMA(sigInfo)
+ addr
+ X86_ARG(argSizeForEmitter),
+ retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
+ ilOffset);
+ // clang-format on
}
-#endif // UNIX_X86_ABI
// if it was a pinvoke we may have needed to get the address of a label
if (genPendingCallLabel)
@@ -5148,11 +5210,6 @@ void CodeGen::genCallInstruction(GenTreePtr node)
genPendingCallLabel = nullptr;
}
-#if defined(_TARGET_X86_)
- // The call will pop its arguments.
- genStackLevel -= stackArgBytes;
-#endif // defined(_TARGET_X86_)
-
// Update GC info:
// All Callee arg registers are trashed and no longer contain any GC pointers.
// TODO-XArch-Bug?: As a matter of fact shouldn't we be killing all of callee trashed regs here?
@@ -5253,7 +5310,7 @@ void CodeGen::genCallInstruction(GenTreePtr node)
gcInfo.gcMarkRegSetNpt(RBM_INTRET);
}
-#if defined(_TARGET_X86_)
+#if !FEATURE_EH_FUNCLETS
//-------------------------------------------------------------------------
// Create a label for tracking of region protected by the monitor in synchronized methods.
// This needs to be here, rather than above where fPossibleSyncHelperCall is set,
@@ -5281,13 +5338,21 @@ void CodeGen::genCallInstruction(GenTreePtr node)
break;
}
}
+#endif // !FEATURE_EH_FUNCLETS
+
+ unsigned stackAdjustBias = 0;
+#if defined(_TARGET_X86_)
// Is the caller supposed to pop the arguments?
- if (((call->gtFlags & GTF_CALL_POP_ARGS) != 0) && (stackArgBytes != 0))
+ if (fCallerPop && (stackArgBytes != 0))
{
- genAdjustSP(stackArgBytes);
+ stackAdjustBias = stackArgBytes;
}
+
+ SubtractStackLevel(stackArgBytes);
#endif // _TARGET_X86_
+
+ genRemoveAlignmentAfterCall(call, stackAdjustBias);
}
// Produce code for a GT_JMP node.
@@ -7137,7 +7202,7 @@ int CodeGenInterface::genSPtoFPdelta()
{
int delta;
-#ifdef PLATFORM_UNIX
+#ifdef UNIX_AMD64_ABI
// We require frame chaining on Unix to support native tool unwinding (such as
// unwinding by the native debugger). We have a CLR-only extension to the
@@ -7145,7 +7210,7 @@ int CodeGenInterface::genSPtoFPdelta()
// If Unix ever supports EnC, the RSP == RBP assumption will have to be reevaluated.
delta = genTotalFrameSize();
-#else // !PLATFORM_UNIX
+#else // !UNIX_AMD64_ABI
// As per Amd64 ABI, RBP offset from initial RSP can be between 0 and 240 if
// RBP needs to be reported in unwind codes. This case would arise for methods
@@ -7171,7 +7236,7 @@ int CodeGenInterface::genSPtoFPdelta()
delta = genTotalFrameSize();
}
-#endif // !PLATFORM_UNIX
+#endif // !UNIX_AMD64_ABI
return delta;
}
@@ -7372,11 +7437,16 @@ void CodeGen::genIntrinsic(GenTreePtr treeNode)
switch (treeNode->gtIntrinsic.gtIntrinsicId)
{
case CORINFO_INTRINSIC_Sqrt:
- noway_assert(treeNode->TypeGet() == TYP_DOUBLE);
+ {
+ // Both operand and its result must be of the same floating point type.
+ GenTreePtr srcNode = treeNode->gtOp.gtOp1;
+ assert(varTypeIsFloating(srcNode));
+ assert(srcNode->TypeGet() == treeNode->TypeGet());
+
genConsumeOperands(treeNode->AsOp());
- getEmitter()->emitInsBinary(ins_FloatSqrt(treeNode->TypeGet()), emitTypeSize(treeNode), treeNode,
- treeNode->gtOp.gtOp1);
+ getEmitter()->emitInsBinary(ins_FloatSqrt(treeNode->TypeGet()), emitTypeSize(treeNode), treeNode, srcNode);
break;
+ }
case CORINFO_INTRINSIC_Abs:
genSSE2BitwiseOp(treeNode);
@@ -7415,16 +7485,10 @@ unsigned CodeGen::getBaseVarForPutArgStk(GenTreePtr treeNode)
unsigned baseVarNum;
-#if FEATURE_FASTTAILCALL
- bool putInIncomingArgArea = treeNode->AsPutArgStk()->putInIncomingArgArea;
-#else
- const bool putInIncomingArgArea = false;
-#endif
-
// Whether to setup stk arg in incoming or out-going arg area?
// Fast tail calls implemented as epilog+jmp = stk arg is setup in incoming arg area.
// All other calls - stk arg is setup in out-going arg area.
- if (putInIncomingArgArea)
+ if (treeNode->AsPutArgStk()->putInIncomingArgArea())
{
// See the note in the function header re: finding the first stack passed argument.
baseVarNum = getFirstArgWithStackSlot();
@@ -7461,7 +7525,96 @@ unsigned CodeGen::getBaseVarForPutArgStk(GenTreePtr treeNode)
return baseVarNum;
}
+//---------------------------------------------------------------------
+// genAlignStackBeforeCall: Align the stack if necessary before a call.
+//
+// Arguments:
+// putArgStk - the putArgStk node.
+//
+void CodeGen::genAlignStackBeforeCall(GenTreePutArgStk* putArgStk)
+{
+#if defined(UNIX_X86_ABI)
+
+ genAlignStackBeforeCall(putArgStk->gtCall);
+
+#endif // UNIX_X86_ABI
+}
+
+//---------------------------------------------------------------------
+// genAlignStackBeforeCall: Align the stack if necessary before a call.
+//
+// Arguments:
+// call - the call node.
+//
+void CodeGen::genAlignStackBeforeCall(GenTreeCall* call)
+{
+#if defined(UNIX_X86_ABI)
+
+ // Have we aligned the stack yet?
+ if (!call->fgArgInfo->IsStkAlignmentDone())
+ {
+ // We haven't done any stack alignment yet for this call. We might need to create
+ // an alignment adjustment, even if this function itself doesn't have any stack args.
+ // This can happen if this function call is part of a nested call sequence, and the outer
+ // call has already pushed some arguments.
+
+ unsigned stkLevel = genStackLevel + call->fgArgInfo->GetStkSizeBytes();
+ call->fgArgInfo->ComputeStackAlignment(stkLevel);
+
+ unsigned padStkAlign = call->fgArgInfo->GetStkAlign();
+ if (padStkAlign != 0)
+ {
+ // Now generate the alignment
+ inst_RV_IV(INS_sub, REG_SPBASE, padStkAlign, EA_PTRSIZE);
+ AddStackLevel(padStkAlign);
+ AddNestedAlignment(padStkAlign);
+ }
+
+ call->fgArgInfo->SetStkAlignmentDone();
+ }
+
+#endif // UNIX_X86_ABI
+}
+
+//---------------------------------------------------------------------
+// genRemoveAlignmentAfterCall: After a call, remove the alignment
+// added before the call, if any.
+//
+// Arguments:
+// call - the call node.
+// bias - additional stack adjustment
+//
+// Note:
+// When bias > 0, caller should adjust stack level appropriately as
+// bias is not considered when adjusting stack level.
+//
+void CodeGen::genRemoveAlignmentAfterCall(GenTreeCall* call, unsigned bias)
+{
+#if defined(_TARGET_X86_)
+#if defined(UNIX_X86_ABI)
+ // Put back the stack pointer if there was any padding for stack alignment
+ unsigned padStkAlign = call->fgArgInfo->GetStkAlign();
+ unsigned padStkAdjust = padStkAlign + bias;
+
+ if (padStkAdjust != 0)
+ {
+ inst_RV_IV(INS_add, REG_SPBASE, padStkAdjust, EA_PTRSIZE);
+ SubtractStackLevel(padStkAlign);
+ SubtractNestedAlignment(padStkAlign);
+ }
+#else // UNIX_X86_ABI
+ if (bias != 0)
+ {
+ genAdjustSP(bias);
+ }
+#endif // !UNIX_X86_ABI_
+#else // _TARGET_X86_
+ assert(bias == 0);
+#endif // !_TARGET_X86
+}
+
#ifdef _TARGET_X86_
+
//---------------------------------------------------------------------
// genAdjustStackForPutArgStk:
// adjust the stack pointer for a putArgStk node if necessary.
@@ -7484,7 +7637,7 @@ bool CodeGen::genAdjustStackForPutArgStk(GenTreePutArgStk* putArgStk)
{
const unsigned argSize = genTypeSize(putArgStk);
inst_RV_IV(INS_sub, REG_SPBASE, argSize, EA_PTRSIZE);
- genStackLevel += argSize;
+ AddStackLevel(argSize);
m_pushStkArg = false;
return true;
}
@@ -7528,7 +7681,7 @@ bool CodeGen::genAdjustStackForPutArgStk(GenTreePutArgStk* putArgStk)
{
m_pushStkArg = false;
inst_RV_IV(INS_sub, REG_SPBASE, argSize, EA_PTRSIZE);
- genStackLevel += argSize;
+ AddStackLevel(argSize);
return true;
}
}
@@ -7616,7 +7769,7 @@ void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk)
{
inst_IV(INS_push, 0);
currentOffset -= pushSize;
- genStackLevel += pushSize;
+ AddStackLevel(pushSize);
adjustment -= pushSize;
}
m_pushStkArg = true;
@@ -7638,7 +7791,7 @@ void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk)
// Adjust the stack pointer to the next slot boundary.
inst_RV_IV(INS_sub, REG_SPBASE, adjustment, EA_PTRSIZE);
currentOffset -= adjustment;
- genStackLevel += adjustment;
+ AddStackLevel(adjustment);
}
// Does it need to be in a byte register?
@@ -7691,7 +7844,7 @@ void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk)
}
}
currentOffset -= TARGET_POINTER_SIZE;
- genStackLevel += TARGET_POINTER_SIZE;
+ AddStackLevel(TARGET_POINTER_SIZE);
}
else
{
@@ -7713,14 +7866,14 @@ void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk)
}
else
{
-#if defined(_TARGET_X86_) && defined(FEATURE_SIMD)
+#if defined(FEATURE_SIMD)
if (fieldType == TYP_SIMD12)
{
assert(genIsValidFloatReg(simdTmpReg));
genStoreSIMD12ToStack(argReg, simdTmpReg);
}
else
-#endif // defined(_TARGET_X86_) && defined(FEATURE_SIMD)
+#endif // defined(FEATURE_SIMD)
{
genStoreRegToStackArg(fieldType, argReg, fieldOffset - currentOffset);
}
@@ -7737,7 +7890,7 @@ void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk)
{
// We don't expect padding at the beginning of a struct, but it could happen with explicit layout.
inst_RV_IV(INS_sub, REG_SPBASE, currentOffset, EA_PTRSIZE);
- genStackLevel += currentOffset;
+ AddStackLevel(currentOffset);
}
}
#endif // _TARGET_X86_
@@ -7758,15 +7911,7 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* putArgStk)
#ifdef _TARGET_X86_
-#if defined(UNIX_X86_ABI)
- // For each call, first stack argument has the padding for alignment
- // if this value is not zero, use it to adjust the ESP
- unsigned argPadding = putArgStk->getArgPadding();
- if (argPadding != 0)
- {
- inst_RV_IV(INS_sub, REG_SPBASE, argPadding * TARGET_POINTER_SIZE, EA_PTRSIZE);
- }
-#endif
+ genAlignStackBeforeCall(putArgStk);
if (varTypeIsStruct(targetType))
{
@@ -7797,7 +7942,7 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* putArgStk)
{
inst_IV(INS_push, data->gtIntCon.gtIconVal);
}
- genStackLevel += argSize;
+ AddStackLevel(argSize);
}
else if (data->OperGet() == GT_FIELD_LIST)
{
@@ -7896,7 +8041,7 @@ void CodeGen::genPushReg(var_types type, regNumber srcReg)
inst_RV_IV(INS_sub, REG_SPBASE, size, EA_PTRSIZE);
getEmitter()->emitIns_AR_R(ins, attr, srcReg, REG_SPBASE, 0);
}
- genStackLevel += size;
+ AddStackLevel(size);
}
#endif // _TARGET_X86_
@@ -8094,7 +8239,7 @@ void CodeGen::genPutStructArgStk(GenTreePutArgStk* putArgStk)
{
getEmitter()->emitIns_S(INS_push, slotAttr, srcLclNum, srcLclOffset + offset);
}
- genStackLevel += TARGET_POINTER_SIZE;
+ AddStackLevel(TARGET_POINTER_SIZE);
}
#else // !defined(_TARGET_X86_)
@@ -8354,12 +8499,14 @@ void CodeGen::genCreateAndStoreGCInfoX64(unsigned codeSize, unsigned prologSize
// Follow the code pattern of the x86 gc info encoder (genCreateAndStoreGCInfoJIT32).
gcInfo.gcInfoBlockHdrSave(gcInfoEncoder, codeSize, prologSize);
+ // We keep the call count for the second call to gcMakeRegPtrTable() below.
+ unsigned callCnt = 0;
// First we figure out the encoder ID's for the stack slots and registers.
- gcInfo.gcMakeRegPtrTable(gcInfoEncoder, codeSize, prologSize, GCInfo::MAKE_REG_PTR_MODE_ASSIGN_SLOTS);
+ gcInfo.gcMakeRegPtrTable(gcInfoEncoder, codeSize, prologSize, GCInfo::MAKE_REG_PTR_MODE_ASSIGN_SLOTS, &callCnt);
// Now we've requested all the slots we'll need; "finalize" these (make more compact data structures for them).
gcInfoEncoder->FinalizeSlotIds();
// Now we can actually use those slot ID's to declare live ranges.
- gcInfo.gcMakeRegPtrTable(gcInfoEncoder, codeSize, prologSize, GCInfo::MAKE_REG_PTR_MODE_DO_WORK);
+ gcInfo.gcMakeRegPtrTable(gcInfoEncoder, codeSize, prologSize, GCInfo::MAKE_REG_PTR_MODE_DO_WORK, &callCnt);
if (compiler->opts.compDbgEnC)
{
@@ -8466,14 +8613,22 @@ void CodeGen::genEmitHelperCall(unsigned helper, int argSize, emitAttr retSize,
}
}
- getEmitter()->emitIns_Call(callType, compiler->eeFindHelper(helper), INDEBUG_LDISASM_COMMA(nullptr) addr, argSize,
- retSize FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(EA_UNKNOWN), gcInfo.gcVarPtrSetCur,
- gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur,
+ // clang-format off
+ getEmitter()->emitIns_Call(callType,
+ compiler->eeFindHelper(helper),
+ INDEBUG_LDISASM_COMMA(nullptr) addr,
+ argSize,
+ retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(EA_UNKNOWN),
+ gcInfo.gcVarPtrSetCur,
+ gcInfo.gcRegGCrefSetCur,
+ gcInfo.gcRegByrefSetCur,
BAD_IL_OFFSET, // IL offset
callTarget, // ireg
REG_NA, 0, 0, // xreg, xmul, disp
false, // isJump
emitter::emitNoGChelper(helper));
+ // clang-format on
regTracker.rsTrashRegSet(killMask);
regTracker.rsTrashRegsForGCInterruptability();
diff --git a/src/jit/compatjit/.gitmirror b/src/jit/compatjit/.gitmirror
deleted file mode 100644
index f507630f94..0000000000
--- a/src/jit/compatjit/.gitmirror
+++ /dev/null
@@ -1 +0,0 @@
-Only contents of this folder, excluding subfolders, will be mirrored by the Git-TFS Mirror. \ No newline at end of file
diff --git a/src/jit/compatjit/CMakeLists.txt b/src/jit/compatjit/CMakeLists.txt
deleted file mode 100644
index 1e0615e431..0000000000
--- a/src/jit/compatjit/CMakeLists.txt
+++ /dev/null
@@ -1,66 +0,0 @@
-project(compatjit)
-
-# This compatjit.dll is only built if we are not building JIT32 as compatjit.dll.
-# It is the same build as legacyjit.dll, just with a different name, and not
-# built as an altjit.
-
-add_definitions(-DLEGACY_BACKEND)
-
-add_definitions(-DFEATURE_NO_HOST)
-add_definitions(-DSELF_NO_HOST)
-add_definitions(-DFEATURE_READYTORUN_COMPILER)
-remove_definitions(-DFEATURE_MERGE_JIT_AND_ENGINE)
-
-# No SIMD in legacy back-end.
-remove_definitions(-DFEATURE_SIMD)
-remove_definitions(-DFEATURE_AVX_SUPPORT)
-
-if(WIN32)
- add_definitions(-DFX_VER_INTERNALNAME_STR=compatjit.dll)
-endif(WIN32)
-
-add_library_clr(compatjit
- SHARED
- ${SHARED_LIB_SOURCES}
-)
-
-add_dependencies(compatjit jit_exports)
-
-set_property(TARGET compatjit APPEND_STRING PROPERTY LINK_FLAGS ${JIT_EXPORTS_LINKER_OPTION})
-set_property(TARGET compatjit APPEND_STRING PROPERTY LINK_DEPENDS ${JIT_EXPORTS_FILE})
-
-set(RYUJIT_LINK_LIBRARIES
- utilcodestaticnohost
- gcinfo
-)
-
-if(CLR_CMAKE_PLATFORM_UNIX)
- list(APPEND RYUJIT_LINK_LIBRARIES
- mscorrc_debug
- coreclrpal
- palrt
- )
-else()
- list(APPEND RYUJIT_LINK_LIBRARIES
- ${STATIC_MT_CRT_LIB}
- ${STATIC_MT_VCRT_LIB}
- kernel32.lib
- advapi32.lib
- ole32.lib
- oleaut32.lib
- uuid.lib
- user32.lib
- version.lib
- shlwapi.lib
- bcrypt.lib
- crypt32.lib
- RuntimeObject.lib
- )
-endif(CLR_CMAKE_PLATFORM_UNIX)
-
-target_link_libraries(compatjit
- ${RYUJIT_LINK_LIBRARIES}
-)
-
-# add the install targets
-install_clr(compatjit)
diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp
index 01c7f8d6a7..14b2abafb6 100644
--- a/src/jit/compiler.cpp
+++ b/src/jit/compiler.cpp
@@ -73,9 +73,9 @@ inline bool _our_GetThreadCycles(unsigned __int64* cycleOut)
inline bool _our_GetThreadCycles(unsigned __int64* cycleOut)
{
- uint64_t cycles;
- asm volatile("rdtsc" : "=A"(cycles));
- *cycleOut = cycles;
+ uint32_t hi, lo;
+ __asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi));
+ *cycleOut = (static_cast<unsigned __int64>(hi) << 32) | static_cast<unsigned __int64>(lo);
return true;
}
@@ -2296,7 +2296,6 @@ void Compiler::compSetProcessor()
#ifdef FEATURE_AVX_SUPPORT
// COMPlus_EnableAVX can be used to disable using AVX if available on a target machine.
- // Note that FEATURE_AVX_SUPPORT is not enabled for ctpjit
opts.compCanUseAVX = false;
if (!jitFlags.IsSet(JitFlags::JIT_FLAG_PREJIT) && jitFlags.IsSet(JitFlags::JIT_FLAG_USE_AVX2))
{
@@ -2471,7 +2470,8 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
opts.jitFlags = jitFlags;
opts.compFlags = CLFLG_MAXOPT; // Default value is for full optimization
- if (jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_CODE) || jitFlags->IsSet(JitFlags::JIT_FLAG_MIN_OPT))
+ if (jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_CODE) || jitFlags->IsSet(JitFlags::JIT_FLAG_MIN_OPT) ||
+ jitFlags->IsSet(JitFlags::JIT_FLAG_TIER0))
{
opts.compFlags = CLFLG_MINOPT;
}
@@ -2496,7 +2496,8 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
//
// If the EE sets SPEED_OPT we will optimize for speed at the expense of code size
//
- else if (jitFlags->IsSet(JitFlags::JIT_FLAG_SPEED_OPT))
+ else if (jitFlags->IsSet(JitFlags::JIT_FLAG_SPEED_OPT) ||
+ (jitFlags->IsSet(JitFlags::JIT_FLAG_TIER1) && !jitFlags->IsSet(JitFlags::JIT_FLAG_MIN_OPT)))
{
opts.compCodeOpt = FAST_CODE;
assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_SIZE_OPT));
@@ -3031,13 +3032,31 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
setUsesSIMDTypes(false);
#endif // FEATURE_SIMD
- if (compIsForInlining() || compIsForImportOnly())
+ if (compIsForImportOnly())
{
return;
}
+
+#if FEATURE_TAILCALL_OPT
+ // By default opportunistic tail call optimization is enabled.
+ // Recognition is done in the importer so this must be set for
+ // inlinees as well.
+ opts.compTailCallOpt = true;
+#endif // FEATURE_TAILCALL_OPT
+
+ if (compIsForInlining())
+ {
+ return;
+ }
+
// The rest of the opts fields that we initialize here
// should only be used when we generate code for the method
// They should not be used when importing or inlining
+ CLANG_FORMAT_COMMENT_ANCHOR;
+
+#if FEATURE_TAILCALL_OPT
+ opts.compTailCallLoopOpt = true;
+#endif // FEATURE_TAILCALL_OPT
opts.genFPorder = true;
opts.genFPopt = true;
@@ -3045,12 +3064,6 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
opts.instrCount = 0;
opts.lvRefCount = 0;
-#if FEATURE_TAILCALL_OPT
- // By default opportunistic tail call optimization is enabled
- opts.compTailCallOpt = true;
- opts.compTailCallLoopOpt = true;
-#endif
-
#ifdef PROFILING_SUPPORTED
opts.compJitELTHookEnabled = false;
#endif // PROFILING_SUPPORTED
@@ -3308,11 +3321,9 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
info.compMethodInfo->args.pSig);
#endif
-//-------------------------------------------------------------------------
+ //-------------------------------------------------------------------------
-#if RELOC_SUPPORT
opts.compReloc = jitFlags->IsSet(JitFlags::JIT_FLAG_RELOC);
-#endif
#ifdef DEBUG
#if defined(_TARGET_XARCH_) && !defined(LEGACY_BACKEND)
@@ -4444,7 +4455,7 @@ void Compiler::compCompile(void** methodCodePtr, ULONG* methodCodeSize, JitFlags
bool doRangeAnalysis = true;
int iterations = 1;
-#ifdef DEBUG
+#if defined(OPT_CONFIG)
doSsa = (JitConfig.JitDoSsa() != 0);
doEarlyProp = doSsa && (JitConfig.JitDoEarlyProp() != 0);
doValueNum = doSsa && (JitConfig.JitDoValueNumber() != 0);
@@ -4457,7 +4468,7 @@ void Compiler::compCompile(void** methodCodePtr, ULONG* methodCodeSize, JitFlags
{
iterations = JitConfig.JitOptRepeatCount();
}
-#endif
+#endif // defined(OPT_CONFIG)
while (iterations > 0)
{
@@ -4978,17 +4989,13 @@ int Compiler::compCompile(CORINFO_METHOD_HANDLE methodHnd,
// with an ARM-targeting "altjit").
info.compMatchedVM = IMAGE_FILE_MACHINE_TARGET == info.compCompHnd->getExpectedTargetArchitecture();
-#if defined(ALT_JIT) && defined(UNIX_AMD64_ABI)
- // ToDo: This code is to allow us to run UNIX codegen on Windows for now. Remove when appropriate.
- // Make sure that the generated UNIX altjit code is skipped on Windows. The static jit codegen is used to run.
+#if (defined(_TARGET_UNIX_) && !defined(_HOST_UNIX_)) || (!defined(_TARGET_UNIX_) && defined(_HOST_UNIX_))
+ // The host and target platforms don't match. This info isn't handled by the existing
+ // getExpectedTargetArchitecture() JIT-EE interface method.
info.compMatchedVM = false;
-#endif // UNIX_AMD64_ABI
+#endif
-#if COR_JIT_EE_VERSION > 460
compMaxUncheckedOffsetForNullObject = eeGetEEInfo()->maxUncheckedOffsetForNullObject;
-#else // COR_JIT_EE_VERSION <= 460
- compMaxUncheckedOffsetForNullObject = MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT;
-#endif // COR_JIT_EE_VERSION > 460
// Set the context for token lookup.
if (compIsForInlining())
@@ -5406,7 +5413,7 @@ void Compiler::compCompileFinish()
{
if (compJitHaltMethod())
{
-#if !defined(_TARGET_ARM64_) && !defined(PLATFORM_UNIX)
+#if !defined(_TARGET_ARM64_) && !defined(_HOST_UNIX_)
// TODO-ARM64-NYI: re-enable this when we have an OS that supports a pop-up dialog
// Don't do an assert, but just put up the dialog box so we get just-in-time debugger
@@ -5651,12 +5658,6 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr,
info.compCallUnmanaged = 0;
info.compLvFrameListRoot = BAD_VAR_NUM;
-#if FEATURE_FIXED_OUT_ARGS
- lvaOutgoingArgSpaceSize = 0;
-#endif
-
- lvaGenericsContextUsed = false;
-
info.compInitMem = ((methodInfo->options & CORINFO_OPT_INIT_LOCALS) != 0);
/* Allocate the local variable table */
@@ -7206,29 +7207,34 @@ double JitTimer::s_cyclesPerSec = CycleTimer::CyclesPerSecond();
#if defined(FEATURE_JIT_METHOD_PERF) || DUMP_FLOWGRAPHS || defined(FEATURE_TRACELOGGING)
const char* PhaseNames[] = {
-#define CompPhaseNameMacro(enum_nm, string_nm, short_nm, hasChildren, parent) string_nm,
+#define CompPhaseNameMacro(enum_nm, string_nm, short_nm, hasChildren, parent, measureIR) string_nm,
#include "compphases.h"
};
const char* PhaseEnums[] = {
-#define CompPhaseNameMacro(enum_nm, string_nm, short_nm, hasChildren, parent) #enum_nm,
+#define CompPhaseNameMacro(enum_nm, string_nm, short_nm, hasChildren, parent, measureIR) #enum_nm,
#include "compphases.h"
};
const LPCWSTR PhaseShortNames[] = {
-#define CompPhaseNameMacro(enum_nm, string_nm, short_nm, hasChildren, parent) W(short_nm),
+#define CompPhaseNameMacro(enum_nm, string_nm, short_nm, hasChildren, parent, measureIR) W(short_nm),
#include "compphases.h"
};
#endif // defined(FEATURE_JIT_METHOD_PERF) || DUMP_FLOWGRAPHS
#ifdef FEATURE_JIT_METHOD_PERF
bool PhaseHasChildren[] = {
-#define CompPhaseNameMacro(enum_nm, string_nm, short_nm, hasChildren, parent) hasChildren,
+#define CompPhaseNameMacro(enum_nm, string_nm, short_nm, hasChildren, parent, measureIR) hasChildren,
#include "compphases.h"
};
int PhaseParent[] = {
-#define CompPhaseNameMacro(enum_nm, string_nm, short_nm, hasChildren, parent) parent,
+#define CompPhaseNameMacro(enum_nm, string_nm, short_nm, hasChildren, parent, measureIR) parent,
+#include "compphases.h"
+};
+
+bool PhaseReportsIRSize[] = {
+#define CompPhaseNameMacro(enum_nm, string_nm, short_nm, hasChildren, parent, measureIR) measureIR,
#include "compphases.h"
};
@@ -7636,7 +7642,7 @@ JitTimer::JitTimer(unsigned byteCodeSize) : m_info(byteCodeSize)
}
}
-void JitTimer::EndPhase(Phases phase)
+void JitTimer::EndPhase(Compiler* compiler, Phases phase)
{
// Otherwise...
// We re-run some phases currently, so this following assert doesn't work.
@@ -7687,6 +7693,15 @@ void JitTimer::EndPhase(Phases phase)
m_curPhaseStart = threadCurCycles;
}
}
+
+ if ((JitConfig.JitMeasureIR() != 0) && PhaseReportsIRSize[phase])
+ {
+ m_info.m_nodeCountAfterPhase[phase] = compiler->fgMeasureIR();
+ }
+ else
+ {
+ m_info.m_nodeCountAfterPhase[phase] = 0;
+ }
}
#ifdef DEBUG
@@ -7795,6 +7810,9 @@ void JitTimer::PrintCsvHeader()
FILE* fp = _wfopen(jitTimeLogCsv, W("a"));
if (fp != nullptr)
{
+ // Seek to the end of the file s.t. `ftell` doesn't lie to us on Windows
+ fseek(fp, 0, SEEK_END);
+
// Write the header if the file is empty
if (ftell(fp) == 0)
{
@@ -7808,10 +7826,17 @@ void JitTimer::PrintCsvHeader()
for (int i = 0; i < PHASE_NUMBER_OF; i++)
{
fprintf(fp, "\"%s\",", PhaseNames[i]);
+ if (PhaseReportsIRSize[i])
+ {
+ fprintf(fp, "\"Node Count After %s\",", PhaseNames[i]);
+ }
}
InlineStrategy::DumpCsvHeader(fp);
+ fprintf(fp, "\"Executable Code Bytes\",");
+ fprintf(fp, "\"GC Info Bytes\",");
+ fprintf(fp, "\"Total Bytes Allocated\",");
fprintf(fp, "\"Total Cycles\",");
fprintf(fp, "\"CPS\"\n");
}
@@ -7858,10 +7883,18 @@ void JitTimer::PrintCsvMethodStats(Compiler* comp)
totCycles += m_info.m_cyclesByPhase[i];
}
fprintf(fp, "%I64u,", m_info.m_cyclesByPhase[i]);
+
+ if (PhaseReportsIRSize[i])
+ {
+ fprintf(fp, "%u,", m_info.m_nodeCountAfterPhase[i]);
+ }
}
comp->m_inlineStrategy->DumpCsvData(fp);
+ fprintf(fp, "%Iu,", comp->info.compNativeCodeSize);
+ fprintf(fp, "%Iu,", comp->compInfoBlkSize);
+ fprintf(fp, "%Iu,", comp->compGetAllocator()->getTotalBytesAllocated());
fprintf(fp, "%I64u,", m_info.m_totalCycles);
fprintf(fp, "%f\n", CycleTimer::CyclesPerSecond());
fclose(fp);
@@ -8126,11 +8159,12 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
* The versions that start with 'd' use the tlsCompiler, so don't require a Compiler*.
*
* Summary:
- * cBlock, dBlock : Display a basic block (call fgDispBasicBlock()).
+ * cBlock, dBlock : Display a basic block (call fgTableDispBasicBlock()).
* cBlocks, dBlocks : Display all the basic blocks of a function (call fgDispBasicBlocks()).
* cBlocksV, dBlocksV : Display all the basic blocks of a function (call fgDispBasicBlocks(true)).
* "V" means "verbose", and will dump all the trees.
* cTree, dTree : Display a tree (call gtDispTree()).
+ * cTreeLIR, dTreeLIR : Display a tree in LIR form (call gtDispLIRNode()).
* cTrees, dTrees : Display all the trees in a function (call fgDumpTrees()).
* cEH, dEH : Display the EH handler table (call fgDispHandlerTab()).
* cVar, dVar : Display a local variable given its number (call lvaDumpEntry()).
@@ -8200,6 +8234,13 @@ void cTree(Compiler* comp, GenTree* tree)
comp->gtDispTree(tree, nullptr, ">>>");
}
+void cTreeLIR(Compiler* comp, GenTree* tree)
+{
+ static unsigned sequenceNumber = 0; // separate calls with a number to indicate this function has been called
+ printf("===================================================================== *TreeLIR %u\n", sequenceNumber++);
+ comp->gtDispLIRNode(tree);
+}
+
void cTrees(Compiler* comp)
{
static unsigned sequenceNumber = 0; // separate calls with a number to indicate this function has been called
@@ -8314,6 +8355,11 @@ void dTree(GenTree* tree)
cTree(JitTls::GetCompiler(), tree);
}
+void dTreeLIR(GenTree* tree)
+{
+ cTreeLIR(JitTls::GetCompiler(), tree);
+}
+
void dTrees()
{
cTrees(JitTls::GetCompiler());
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index 4239cf613b..9ca0e1a3e1 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -252,8 +252,10 @@ public:
unsigned char lvStackByref : 1; // This is a compiler temporary of TYP_BYREF that is known to point into our local
// stack frame.
- unsigned char lvArgWrite : 1; // variable is a parameter and STARG was used on it
- unsigned char lvIsTemp : 1; // Short-lifetime compiler temp
+ unsigned char lvHasILStoreOp : 1; // there is at least one STLOC or STARG on this local
+ unsigned char lvHasMultipleILStoreOp : 1; // there is more than one STLOC on this local
+
+ unsigned char lvIsTemp : 1; // Short-lifetime compiler temp
#if OPT_BOOL_OPS
unsigned char lvIsBoolean : 1; // set if variable is boolean
#endif
@@ -322,6 +324,12 @@ public:
#endif // FEATURE_SIMD
unsigned char lvRegStruct : 1; // This is a reg-sized non-field-addressed struct.
+ unsigned char lvClassIsExact : 1; // lvClassHandle is the exact type
+
+#ifdef DEBUG
+ unsigned char lvClassInfoUpdated : 1; // true if this var has updated class handle or exactness
+#endif
+
union {
unsigned lvFieldLclStart; // The index of the local var representing the first field in the promoted struct
// local.
@@ -704,6 +712,8 @@ public:
typeInfo lvVerTypeInfo; // type info needed for verification
+ CORINFO_CLASS_HANDLE lvClassHnd; // class handle for the local, or null if not known
+
BYTE* lvGcLayout; // GC layout info for structs
#if ASSERTION_PROP
@@ -917,7 +927,7 @@ struct ArrayInfo
// partition a compilation.
enum Phases
{
-#define CompPhaseNameMacro(enum_nm, string_nm, short_nm, hasChildren, parent) enum_nm,
+#define CompPhaseNameMacro(enum_nm, string_nm, short_nm, hasChildren, parent, measureIR) enum_nm,
#include "compphases.h"
PHASE_NUMBER_OF
};
@@ -952,6 +962,7 @@ struct CompTimeInfo
static bool PhaseHasChildren[];
static int PhaseParent[];
+ static bool PhaseReportsIRSize[];
unsigned m_byteCodeBytes;
unsigned __int64 m_totalCycles;
@@ -961,6 +972,9 @@ struct CompTimeInfo
unsigned __int64 m_CLRinvokesByPhase[PHASE_NUMBER_OF];
unsigned __int64 m_CLRcyclesByPhase[PHASE_NUMBER_OF];
#endif
+
+ unsigned m_nodeCountAfterPhase[PHASE_NUMBER_OF];
+
// For better documentation, we call EndPhase on
// non-leaf phases. We should also call EndPhase on the
// last leaf subphase; obviously, the elapsed cycles between the EndPhase
@@ -1077,7 +1091,7 @@ public:
static void PrintCsvHeader();
// Ends the current phase (argument is for a redundant check).
- void EndPhase(Phases phase);
+ void EndPhase(Compiler* compiler, Phases phase);
#if MEASURE_CLRAPI_CALLS
// Start and end a timed CLR API call.
@@ -1186,11 +1200,6 @@ struct fgArgTabEntry
unsigned alignment; // 1 or 2 (slots/registers)
unsigned lateArgInx; // index into gtCallLateArgs list
unsigned tmpNum; // the LclVar number if we had to force evaluation of this arg
-#if defined(UNIX_X86_ABI)
- unsigned padStkAlign; // Count of number of padding slots for stack alignment. For each Call, only the first
- // argument may have a value to emit "sub esp, n" to adjust the stack before pushing
- // the argument.
-#endif
bool isSplit : 1; // True when this argument is split between the registers and OutArg area
bool needTmp : 1; // True when we force this argument's evaluation into a temp LclVar
@@ -1263,14 +1272,23 @@ typedef struct fgArgTabEntry* fgArgTabEntryPtr;
class fgArgInfo
{
- Compiler* compiler; // Back pointer to the compiler instance so that we can allocate memory
- GenTreePtr callTree; // Back pointer to the GT_CALL node for this fgArgInfo
- unsigned argCount; // Updatable arg count value
- unsigned nextSlotNum; // Updatable slot count value
- unsigned stkLevel; // Stack depth when we make this call (for x86)
+ Compiler* compiler; // Back pointer to the compiler instance so that we can allocate memory
+ GenTreeCall* callTree; // Back pointer to the GT_CALL node for this fgArgInfo
+ unsigned argCount; // Updatable arg count value
+ unsigned nextSlotNum; // Updatable slot count value
+ unsigned stkLevel; // Stack depth when we make this call (for x86)
+
#if defined(UNIX_X86_ABI)
- unsigned padStkAlign; // Count of number of padding slots for stack alignment. This value is used to turn back
- // stack pointer before it was adjusted after each Call
+ bool alignmentDone; // Updateable flag, set to 'true' after we've done any required alignment.
+ unsigned stkSizeBytes; // Size of stack used by this call, in bytes. Calculated during fgMorphArgs().
+ unsigned padStkAlign; // Stack alignment in bytes required before arguments are pushed for this call.
+ // Computed dynamically during codegen, based on stkSizeBytes and the current
+ // stack level (genStackLevel) when the first stack adjustment is made for
+ // this call.
+#endif
+
+#if FEATURE_FIXED_OUT_ARGS
+ unsigned outArgSize; // Size of the out arg area for the call, will be at least MIN_ARG_AREA_FOR_CALL
#endif
unsigned argTableSize; // size of argTable array (equal to the argCount when done with fgMorphArgs)
@@ -1284,8 +1302,8 @@ private:
void AddArg(fgArgTabEntryPtr curArgTabEntry);
public:
- fgArgInfo(Compiler* comp, GenTreePtr call, unsigned argCount);
- fgArgInfo(GenTreePtr newCall, GenTreePtr oldCall);
+ fgArgInfo(Compiler* comp, GenTreeCall* call, unsigned argCount);
+ fgArgInfo(GenTreeCall* newCall, GenTreeCall* oldCall);
fgArgTabEntryPtr AddRegArg(
unsigned argNum, GenTreePtr node, GenTreePtr parent, regNumber regNum, unsigned numRegs, unsigned alignment);
@@ -1321,10 +1339,6 @@ public:
void ArgsComplete();
-#if defined(UNIX_X86_ABI)
- void ArgsAlignPadding();
-#endif
-
void SortArgs();
void EvalArgsToTemps();
@@ -1344,12 +1358,6 @@ public:
{
return nextSlotNum;
}
-#if defined(UNIX_X86_ABI)
- unsigned GetPadStackAlign()
- {
- return padStkAlign;
- }
-#endif
bool HasRegArgs()
{
return hasRegArgs;
@@ -1362,6 +1370,49 @@ public:
{
return argsComplete;
}
+#if FEATURE_FIXED_OUT_ARGS
+ unsigned GetOutArgSize() const
+ {
+ return outArgSize;
+ }
+ void SetOutArgSize(unsigned newVal)
+ {
+ outArgSize = newVal;
+ }
+#endif // FEATURE_FIXED_OUT_ARGS
+
+ void ComputeStackAlignment(unsigned curStackLevelInBytes)
+ {
+#if defined(UNIX_X86_ABI)
+ padStkAlign = AlignmentPad(curStackLevelInBytes, STACK_ALIGN);
+#endif // defined(UNIX_X86_ABI)
+ }
+
+ void SetStkSizeBytes(unsigned newStkSizeBytes)
+ {
+#if defined(UNIX_X86_ABI)
+ stkSizeBytes = newStkSizeBytes;
+#endif // defined(UNIX_X86_ABI)
+ }
+
+#if defined(UNIX_X86_ABI)
+ unsigned GetStkAlign()
+ {
+ return padStkAlign;
+ }
+ unsigned GetStkSizeBytes() const
+ {
+ return stkSizeBytes;
+ }
+ bool IsStkAlignmentDone() const
+ {
+ return alignmentDone;
+ }
+ void SetStkAlignmentDone()
+ {
+ alignmentDone = true;
+ }
+#endif // defined(UNIX_X86_ABI)
// Get the late arg for arg at position argIndex. Caller must ensure this position has a late arg.
GenTreePtr GetLateArg(unsigned argIndex);
@@ -2021,9 +2072,9 @@ public:
GenTreeArgList* gtNewArgList(GenTreePtr op1, GenTreePtr op2);
GenTreeArgList* gtNewArgList(GenTreePtr op1, GenTreePtr op2, GenTreePtr op3);
- static fgArgTabEntryPtr gtArgEntryByArgNum(GenTreePtr call, unsigned argNum);
- static fgArgTabEntryPtr gtArgEntryByNode(GenTreePtr call, GenTreePtr node);
- fgArgTabEntryPtr gtArgEntryByLateArgIndex(GenTreePtr call, unsigned lateArgInx);
+ static fgArgTabEntryPtr gtArgEntryByArgNum(GenTreeCall* call, unsigned argNum);
+ static fgArgTabEntryPtr gtArgEntryByNode(GenTreeCall* call, GenTreePtr node);
+ fgArgTabEntryPtr gtArgEntryByLateArgIndex(GenTreeCall* call, unsigned lateArgInx);
bool gtArgIsThisPtr(fgArgTabEntryPtr argEntry);
GenTreePtr gtNewAssignNode(GenTreePtr dst, GenTreePtr src);
@@ -2129,7 +2180,7 @@ public:
unsigned flags = GTF_SIDE_EFFECT,
bool ignoreRoot = false);
- GenTreePtr gtGetThisArg(GenTreePtr call);
+ GenTreePtr gtGetThisArg(GenTreeCall* call);
// Static fields of struct types (and sometimes the types that those are reduced to) are represented by having the
// static field contain an object pointer to the boxed struct. This simplifies the GC implementation...but
@@ -2138,9 +2189,10 @@ public:
bool gtIsStaticFieldPtrToBoxedStruct(var_types fieldNodeType, CORINFO_FIELD_HANDLE fldHnd);
// Return true if call is a recursive call; return false otherwise.
+ // Note when inlining, this looks for calls back to the root method.
bool gtIsRecursiveCall(GenTreeCall* call)
{
- return (call->gtCallMethHnd == info.compMethodHnd);
+ return (call->gtCallMethHnd == impInlineRoot()->info.compMethodHnd);
}
//-------------------------------------------------------------------------
@@ -2166,6 +2218,8 @@ public:
CORINFO_CLASS_HANDLE gtGetStructHandleIfPresent(GenTreePtr tree);
// Get the handle, and assert if not found.
CORINFO_CLASS_HANDLE gtGetStructHandle(GenTreePtr tree);
+ // Get the handle for a ref type.
+ CORINFO_CLASS_HANDLE gtGetClassHandle(GenTreePtr tree, bool* isExact, bool* isNonNull);
//-------------------------------------------------------------------------
// Functions to display the trees
@@ -2204,16 +2258,16 @@ public:
char* gtGetLclVarName(unsigned lclNum);
void gtDispLclVar(unsigned varNum, bool padForBiggestDisp = true);
void gtDispTreeList(GenTreePtr tree, IndentStack* indentStack = nullptr);
- void gtGetArgMsg(GenTreePtr call, GenTreePtr arg, unsigned argNum, int listCount, char* bufp, unsigned bufLength);
- void gtGetLateArgMsg(GenTreePtr call, GenTreePtr arg, int argNum, int listCount, char* bufp, unsigned bufLength);
- void gtDispArgList(GenTreePtr tree, IndentStack* indentStack);
+ void gtGetArgMsg(GenTreeCall* call, GenTreePtr arg, unsigned argNum, int listCount, char* bufp, unsigned bufLength);
+ void gtGetLateArgMsg(GenTreeCall* call, GenTreePtr arg, int argNum, int listCount, char* bufp, unsigned bufLength);
+ void gtDispArgList(GenTreeCall* call, IndentStack* indentStack);
void gtDispFieldSeq(FieldSeqNode* pfsn);
void gtDispRange(LIR::ReadOnlyRange const& range);
void gtDispTreeRange(LIR::Range& containingRange, GenTree* tree);
- void gtDispLIRNode(GenTree* node);
+ void gtDispLIRNode(GenTree* node, const char* prefixMsg = nullptr);
#endif
// For tree walks
@@ -2399,9 +2453,9 @@ public:
// in case there are multiple BBJ_RETURN blocks in the inlinee.
#if FEATURE_FIXED_OUT_ARGS
- unsigned lvaOutgoingArgSpaceVar; // dummy TYP_LCLBLK var for fixed outgoing argument space
- unsigned lvaOutgoingArgSpaceSize; // size of fixed outgoing argument space
-#endif // FEATURE_FIXED_OUT_ARGS
+ unsigned lvaOutgoingArgSpaceVar; // dummy TYP_LCLBLK var for fixed outgoing argument space
+ PhasedVar<unsigned> lvaOutgoingArgSpaceSize; // size of fixed outgoing argument space
+#endif // FEATURE_FIXED_OUT_ARGS
#ifdef _TARGET_ARM_
// On architectures whose ABIs allow structs to be passed in registers, struct promotion will sometimes
@@ -2417,7 +2471,7 @@ public:
unsigned lvaCallEspCheck; // confirms ESP not corrupted after a call
#endif
- bool lvaGenericsContextUsed;
+ unsigned lvaGenericsContextUseCount;
bool lvaKeepAliveAndReportThis(); // Synchronized instance method of a reference type, or
// CORINFO_GENERICS_CTXT_FROM_THIS?
@@ -2564,7 +2618,7 @@ public:
void lvaMarkLocalVars(); // Local variable ref-counting
- void lvaAllocOutgoingArgSpace(); // 'Commit' lvaOutgoingArgSpaceSize and lvaOutgoingArgSpaceVar
+ void lvaAllocOutgoingArgSpaceVar(); // Set up lvaOutgoingArgSpaceVar
VARSET_VALRET_TP lvaStmtLclMask(GenTreePtr stmt);
@@ -2624,11 +2678,16 @@ public:
// Returns true if this local var is a multireg struct
bool lvaIsMultiregStruct(LclVarDsc* varDsc);
- // If the class is a TYP_STRUCT, get/set a class handle describing it
-
+ // If the local is a TYP_STRUCT, get/set a class handle describing it
CORINFO_CLASS_HANDLE lvaGetStruct(unsigned varNum);
void lvaSetStruct(unsigned varNum, CORINFO_CLASS_HANDLE typeHnd, bool unsafeValueClsCheck, bool setTypeInfo = true);
+ // If the local is TYP_REF, set or update the associated class information.
+ void lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact = false);
+ void lvaSetClass(unsigned varNum, GenTreePtr tree, CORINFO_CLASS_HANDLE stackHandle = nullptr);
+ void lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact = false);
+ void lvaUpdateClass(unsigned varNum, GenTreePtr tree, CORINFO_CLASS_HANDLE stackHandle = nullptr);
+
#define MAX_NumOfFieldsInPromotableStruct 4 // Maximum number of fields in promotable struct
// Info about struct fields
@@ -2664,6 +2723,7 @@ public:
lvaStructPromotionInfo* StructPromotionInfo,
bool sortFields);
void lvaCanPromoteStructVar(unsigned lclNum, lvaStructPromotionInfo* StructPromotionInfo);
+ bool lvaShouldPromoteStructVar(unsigned lclNum, lvaStructPromotionInfo* structPromotionInfo);
void lvaPromoteStructVar(unsigned lclNum, lvaStructPromotionInfo* StructPromotionInfo);
#if !defined(_TARGET_64BIT_)
void lvaPromoteLongVars();
@@ -2749,6 +2809,9 @@ protected:
static fgWalkPreFn lvaMarkLclRefsCallback;
void lvaMarkLclRefs(GenTreePtr tree);
+ bool IsDominatedByExceptionalEntry(BasicBlock* block);
+ void SetVolatileHint(LclVarDsc* varDsc);
+
// Keeps the mapping from SSA #'s to VN's for the implicit memory variables.
PerSsaArray lvMemoryPerSsaData;
unsigned lvMemoryNumSsaNames;
@@ -2820,6 +2883,7 @@ protected:
StackEntry impPopStack(CORINFO_CLASS_HANDLE& structTypeRet);
GenTreePtr impPopStack(typeInfo& ti);
StackEntry& impStackTop(unsigned n = 0);
+ unsigned impStackHeight();
void impSaveStackState(SavedStack* savePtr, bool copy);
void impRestoreStackState(SavedStack* savePtr);
@@ -2835,18 +2899,14 @@ protected:
bool impCanPInvokeInline();
bool impCanPInvokeInlineCallSite(BasicBlock* block);
void impCheckForPInvokeCall(
- GenTreePtr call, CORINFO_METHOD_HANDLE methHnd, CORINFO_SIG_INFO* sig, unsigned mflags, BasicBlock* block);
- GenTreePtr impImportIndirectCall(CORINFO_SIG_INFO* sig, IL_OFFSETX ilOffset = BAD_IL_OFFSET);
+ GenTreeCall* call, CORINFO_METHOD_HANDLE methHnd, CORINFO_SIG_INFO* sig, unsigned mflags, BasicBlock* block);
+ GenTreeCall* impImportIndirectCall(CORINFO_SIG_INFO* sig, IL_OFFSETX ilOffset = BAD_IL_OFFSET);
void impPopArgsForUnmanagedCall(GenTreePtr call, CORINFO_SIG_INFO* sig);
void impInsertHelperCall(CORINFO_HELPER_DESC* helperCall);
void impHandleAccessAllowed(CorInfoIsAccessAllowedResult result, CORINFO_HELPER_DESC* helperCall);
void impHandleAccessAllowedInternal(CorInfoIsAccessAllowedResult result, CORINFO_HELPER_DESC* helperCall);
- void impInsertCalloutForDelegate(CORINFO_METHOD_HANDLE callerMethodHnd,
- CORINFO_METHOD_HANDLE calleeMethodHnd,
- CORINFO_CLASS_HANDLE delegateTypeHnd);
-
var_types impImportCall(OPCODE opcode,
CORINFO_RESOLVED_TOKEN* pResolvedToken,
CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, // Is this a "constrained." call on a
@@ -2856,9 +2916,14 @@ protected:
CORINFO_CALL_INFO* callInfo,
IL_OFFSET rawILOffset);
+ void impDevirtualizeCall(GenTreeCall* call,
+ GenTreePtr obj,
+ CORINFO_CALL_INFO* callInfo,
+ CORINFO_CONTEXT_HANDLE* exactContextHnd);
+
bool impMethodInfo_hasRetBuffArg(CORINFO_METHOD_INFO* methInfo);
- GenTreePtr impFixupCallStructReturn(GenTreePtr call, CORINFO_CLASS_HANDLE retClsHnd);
+ GenTreePtr impFixupCallStructReturn(GenTreeCall* call, CORINFO_CLASS_HANDLE retClsHnd);
GenTreePtr impFixupStructReturnType(GenTreePtr op, CORINFO_CLASS_HANDLE retClsHnd);
@@ -2995,11 +3060,11 @@ public:
GenTreePtr impReadyToRunLookupToTree(CORINFO_CONST_LOOKUP* pLookup, unsigned flags, void* compileTimeHandle);
- GenTreePtr impReadyToRunHelperToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
- CorInfoHelpFunc helper,
- var_types type,
- GenTreeArgList* arg = nullptr,
- CORINFO_LOOKUP_KIND* pGenericLookupKind = nullptr);
+ GenTreeCall* impReadyToRunHelperToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
+ CorInfoHelpFunc helper,
+ var_types type,
+ GenTreeArgList* arg = nullptr,
+ CORINFO_LOOKUP_KIND* pGenericLookupKind = nullptr);
GenTreePtr impCastClassOrIsInstToTree(GenTreePtr op1,
GenTreePtr op2,
@@ -3072,6 +3137,11 @@ private:
//---------------- Spilling the importer stack ----------------------------
+ // The maximum number of bytes of IL processed without clean stack state.
+ // It allows to limit the maximum tree size and depth.
+ static const unsigned MAX_TREE_SIZE = 200;
+ bool impCanSpillNow(OPCODE prevOpcode);
+
struct PendingDsc
{
PendingDsc* pdNext;
@@ -3303,7 +3373,10 @@ private:
GenTreePtr variableBeingDereferenced,
InlArgInfo* inlArgInfo);
- void impMarkInlineCandidate(GenTreePtr call, CORINFO_CONTEXT_HANDLE exactContextHnd, CORINFO_CALL_INFO* callInfo);
+ void impMarkInlineCandidate(GenTreePtr call,
+ CORINFO_CONTEXT_HANDLE exactContextHnd,
+ bool exactContextNeedsRuntimeLookup,
+ CORINFO_CALL_INFO* callInfo);
bool impTailCallRetTypeCompatible(var_types callerRetType,
CORINFO_CLASS_HANDLE callerRetTypeClass,
@@ -3320,6 +3393,8 @@ private:
bool impIsImplicitTailCallCandidate(
OPCODE curOpcode, const BYTE* codeAddrOfNextOpcode, const BYTE* codeEnd, int prefixFlags, bool isRecursive);
+ CORINFO_RESOLVED_TOKEN* impAllocateToken(CORINFO_RESOLVED_TOKEN token);
+
/*
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
@@ -3470,6 +3545,8 @@ public:
void fgInsertBBafter(BasicBlock* insertAfterBlk, BasicBlock* newBlk);
void fgUnlinkBlock(BasicBlock* block);
+ unsigned fgMeasureIR();
+
#if OPT_BOOL_OPS // Used to detect multiple logical "not" assignments.
bool fgMultipleNots;
#endif
@@ -3517,7 +3594,7 @@ public:
bool fgSlopUsedInEdgeWeights; // true if their was some slop used when computing the edge weights
bool fgRangeUsedInEdgeWeights; // true if some of the edgeWeight are expressed in Min..Max form
bool fgNeedsUpdateFlowGraph; // true if we need to run fgUpdateFlowGraph
- BasicBlock::weight_t fgCalledWeight; // count of the number of times this method was called
+ BasicBlock::weight_t fgCalledCount; // count of the number of times this method was called
// This is derived from the profile data
// or is BB_UNITY_WEIGHT when we don't have profile data
@@ -3555,15 +3632,21 @@ public:
void fgRemoveEmptyFinally();
+ void fgMergeFinallyChains();
+
void fgCloneFinally();
void fgCleanupContinuation(BasicBlock* continuation);
void fgUpdateFinallyTargetFlags();
+ bool fgRetargetBranchesToCanonicalCallFinally(BasicBlock* block,
+ BasicBlock* handler,
+ BlockToBlockMap& continuationMap);
+
GenTreePtr fgGetCritSectOfStaticMethod();
-#if !defined(_TARGET_X86_)
+#if FEATURE_EH_FUNCLETS
void fgAddSyncMethodEnterExit();
@@ -3571,7 +3654,7 @@ public:
void fgConvertSyncReturnToLeave(BasicBlock* block);
-#endif // !_TARGET_X86_
+#endif // FEATURE_EH_FUNCLETS
void fgAddReversePInvokeEnterExit();
@@ -3627,9 +3710,9 @@ public:
GenTreePtr fgInitThisClass();
- GenTreePtr fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc helper);
+ GenTreeCall* fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc helper);
- GenTreePtr fgGetSharedCCtor(CORINFO_CLASS_HANDLE cls);
+ GenTreeCall* fgGetSharedCCtor(CORINFO_CLASS_HANDLE cls);
void fgLocalVarLiveness();
@@ -4010,6 +4093,8 @@ protected:
// Based on: A Simple, Fast Dominance Algorithm
// by Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy
+ void fgCompDominatedByExceptionalEntryBlocks();
+
BlockSet_ValRet_T fgGetDominatorSet(BasicBlock* block); // Returns a set of blocks that dominate the given block.
// Note: this is relatively slow compared to calling fgDominate(),
// especially if dealing with a single block versus block check.
@@ -4487,12 +4572,22 @@ protected:
bool fgHaveProfileData();
bool fgGetProfileWeightForBasicBlock(IL_OFFSET offset, unsigned* weight);
+ void fgInstrumentMethod();
+public:
+ // fgIsUsingProfileWeights - returns true if we have real profile data for this method
+ // or if we have some fake profile data for the stress mode
bool fgIsUsingProfileWeights()
{
return (fgHaveProfileData() || fgStressBBProf());
}
- void fgInstrumentMethod();
+
+ // fgProfileRunsCount - returns total number of scenario runs for the profile data
+ // or BB_UNITY_WEIGHT when we aren't using profile data.
+ unsigned fgProfileRunsCount()
+ {
+ return fgIsUsingProfileWeights() ? fgNumProfileRuns : BB_UNITY_WEIGHT;
+ }
//-------- Insert a statement at the start or end of a basic block --------
@@ -4647,7 +4742,9 @@ private:
void fgNoteNonInlineCandidate(GenTreeStmt* stmt, GenTreeCall* call);
static fgWalkPreFn fgFindNonInlineCandidate;
#endif
- GenTreePtr fgOptimizeDelegateConstructor(GenTreePtr call, CORINFO_CONTEXT_HANDLE* ExactContextHnd);
+ GenTreePtr fgOptimizeDelegateConstructor(GenTreeCall* call,
+ CORINFO_CONTEXT_HANDLE* ExactContextHnd,
+ CORINFO_RESOLVED_TOKEN* ldftnToken);
GenTreePtr fgMorphLeaf(GenTreePtr tree);
void fgAssignSetVarDef(GenTreePtr tree);
GenTreePtr fgMorphOneAsgBlockOp(GenTreePtr tree);
@@ -4789,7 +4886,7 @@ private:
static fgWalkPreFn gtHasLocalsWithAddrOpCB;
bool gtCanOptimizeTypeEquality(GenTreePtr tree);
- bool gtIsTypeHandleToRuntimeTypeHelper(GenTreePtr tree);
+ bool gtIsTypeHandleToRuntimeTypeHelper(GenTreeCall* call);
bool gtIsActiveCSE_Candidate(GenTreePtr tree);
#ifdef DEBUG
@@ -5343,7 +5440,6 @@ protected:
// Keeps tracked cse indices
BitVecTraits* cseTraits;
EXPSET_TP cseFull;
- EXPSET_TP cseEmpty;
/* Generic list of nodes - used by the CSE logic */
@@ -5397,6 +5493,14 @@ protected:
CSEdsc** optCSEhash;
CSEdsc** optCSEtab;
+ typedef SimplerHashTable<GenTreePtr, PtrKeyFuncs<GenTree>, GenTreePtr, JitSimplerHashBehavior> NodeToNodeMap;
+
+ NodeToNodeMap* optCseArrLenMap; // Maps array length nodes to ancestor compares that should be
+ // re-numbered with the array length to improve range check elimination
+
+ // Given a compare, look for a cse candidate arrlen feeding it and add a map entry if found.
+ void optCseUpdateArrLenMap(GenTreePtr compare);
+
void optCSEstop();
CSEdsc* optCSEfindDsc(unsigned index);
@@ -5504,7 +5608,7 @@ protected:
callInterf ivaMaskCall; // What kind of calls are there?
};
- static callInterf optCallInterf(GenTreePtr call);
+ static callInterf optCallInterf(GenTreeCall* call);
public:
// VN based copy propagation.
@@ -5568,6 +5672,12 @@ public:
optMethodFlags &= ~OMF_HAS_FATPOINTER;
}
+ void addFatPointerCandidate(GenTreeCall* call)
+ {
+ setMethodHasFatPointer();
+ call->SetFatPointerCandidate();
+ }
+
unsigned optMethodFlags;
// Recursion bound controls how far we can go backwards tracking for a SSA value.
@@ -5602,7 +5712,6 @@ public:
// Data structures for assertion prop
BitVecTraits* apTraits;
ASSERT_TP apFull;
- ASSERT_TP apEmpty;
enum optAssertionKind
{
@@ -5773,8 +5882,20 @@ public:
bool HasSameOp1(AssertionDsc* that, bool vnBased)
{
- return (op1.kind == that->op1.kind) &&
- ((vnBased && (op1.vn == that->op1.vn)) || (!vnBased && (op1.lcl.lclNum == that->op1.lcl.lclNum)));
+ if (op1.kind != that->op1.kind)
+ {
+ return false;
+ }
+ else if (op1.kind == O1K_ARR_BND)
+ {
+ assert(vnBased);
+ return (op1.bnd.vnIdx == that->op1.bnd.vnIdx) && (op1.bnd.vnLen == that->op1.bnd.vnLen);
+ }
+ else
+ {
+ return ((vnBased && (op1.vn == that->op1.vn)) ||
+ (!vnBased && (op1.lcl.lclNum == that->op1.lcl.lclNum)));
+ }
}
bool HasSameOp2(AssertionDsc* that, bool vnBased)
@@ -5823,12 +5944,22 @@ public:
bool Equals(AssertionDsc* that, bool vnBased)
{
- return (assertionKind == that->assertionKind) && HasSameOp1(that, vnBased) && HasSameOp2(that, vnBased);
+ if (assertionKind != that->assertionKind)
+ {
+ return false;
+ }
+ else if (assertionKind == OAK_NO_THROW)
+ {
+ assert(op2.kind == O2K_INVALID);
+ return HasSameOp1(that, vnBased);
+ }
+ else
+ {
+ return HasSameOp1(that, vnBased) && HasSameOp2(that, vnBased);
+ }
}
};
- typedef unsigned short AssertionIndex;
-
protected:
static fgWalkPreFn optAddCopiesCallback;
static fgWalkPreFn optVNAssertionPropCurStmtVisitor;
@@ -5865,8 +5996,6 @@ public:
ValueNumToAssertsMap;
ValueNumToAssertsMap* optValueNumToAsserts;
- static const AssertionIndex NO_ASSERTION_INDEX = 0;
-
// Assertion prop helpers.
ASSERT_TP& GetAssertionDep(unsigned lclNum);
AssertionDsc* optGetAssertion(AssertionIndex assertIndex);
@@ -5887,8 +6016,8 @@ public:
// Assertion Gen functions.
void optAssertionGen(GenTreePtr tree);
AssertionIndex optAssertionGenPhiDefn(GenTreePtr tree);
- AssertionIndex optCreateJTrueBoundsAssertion(GenTreePtr tree);
- AssertionIndex optAssertionGenJtrue(GenTreePtr tree);
+ AssertionInfo optCreateJTrueBoundsAssertion(GenTreePtr tree);
+ AssertionInfo optAssertionGenJtrue(GenTreePtr tree);
AssertionIndex optCreateJtrueAssertions(GenTreePtr op1, GenTreePtr op2, Compiler::optAssertionKind assertionKind);
AssertionIndex optFindComplementary(AssertionIndex assertionIndex);
void optMapComplementary(AssertionIndex assertionIndex, AssertionIndex index);
@@ -5936,14 +6065,14 @@ public:
GenTreePtr optAssertionProp_LclVar(ASSERT_VALARG_TP assertions, const GenTreePtr tree, const GenTreePtr stmt);
GenTreePtr optAssertionProp_Ind(ASSERT_VALARG_TP assertions, const GenTreePtr tree, const GenTreePtr stmt);
GenTreePtr optAssertionProp_Cast(ASSERT_VALARG_TP assertions, const GenTreePtr tree, const GenTreePtr stmt);
- GenTreePtr optAssertionProp_Call(ASSERT_VALARG_TP assertions, const GenTreePtr tree, const GenTreePtr stmt);
+ GenTreePtr optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call, const GenTreePtr stmt);
GenTreePtr optAssertionProp_RelOp(ASSERT_VALARG_TP assertions, const GenTreePtr tree, const GenTreePtr stmt);
GenTreePtr optAssertionProp_Comma(ASSERT_VALARG_TP assertions, const GenTreePtr tree, const GenTreePtr stmt);
GenTreePtr optAssertionProp_BndsChk(ASSERT_VALARG_TP assertions, const GenTreePtr tree, const GenTreePtr stmt);
GenTreePtr optAssertionPropGlobal_RelOp(ASSERT_VALARG_TP assertions, const GenTreePtr tree, const GenTreePtr stmt);
GenTreePtr optAssertionPropLocal_RelOp(ASSERT_VALARG_TP assertions, const GenTreePtr tree, const GenTreePtr stmt);
GenTreePtr optAssertionProp_Update(const GenTreePtr newTree, const GenTreePtr tree, const GenTreePtr stmt);
- GenTreePtr optNonNullAssertionProp_Call(ASSERT_VALARG_TP assertions, const GenTreePtr tree, const GenTreePtr stmt);
+ GenTreePtr optNonNullAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call, const GenTreePtr stmt);
// Implied assertion functions.
void optImpliedAssertions(AssertionIndex assertionIndex, ASSERT_TP& activeAssertions);
@@ -5951,9 +6080,6 @@ public:
void optImpliedByCopyAssertion(AssertionDsc* copyAssertion, AssertionDsc* depAssertion, ASSERT_TP& result);
void optImpliedByConstAssertion(AssertionDsc* curAssertion, ASSERT_TP& result);
- ASSERT_VALRET_TP optNewFullAssertSet();
- ASSERT_VALRET_TP optNewEmptyAssertSet();
-
#ifdef DEBUG
void optPrintAssertion(AssertionDsc* newAssertion, AssertionIndex assertionIndex = 0);
void optDebugCheckAssertion(AssertionDsc* assertion);
@@ -6469,11 +6595,7 @@ public:
// Returns the page size for the target machine as reported by the EE.
inline size_t eeGetPageSize()
{
-#if COR_JIT_EE_VERSION > 460
return eeGetEEInfo()->osPageSize;
-#else // COR_JIT_EE_VERSION <= 460
- return CORINFO_PAGE_SIZE;
-#endif // COR_JIT_EE_VERSION > 460
}
// Returns the frame size at which we will generate a loop to probe the stack.
@@ -6491,11 +6613,7 @@ public:
inline bool IsTargetAbi(CORINFO_RUNTIME_ABI abi)
{
-#if COR_JIT_EE_VERSION > 460
return eeGetEEInfo()->targetAbi == abi;
-#else
- return CORINFO_DESKTOP_ABI == abi;
-#endif
}
inline bool generateCFIUnwindCodes()
@@ -7690,28 +7808,20 @@ public:
// PInvoke transitions inline (e.g. when targeting CoreRT).
inline bool ShouldUsePInvokeHelpers()
{
-#if COR_JIT_EE_VERSION > 460
return jitFlags->IsSet(JitFlags::JIT_FLAG_USE_PINVOKE_HELPERS);
-#else
- return false;
-#endif
}
// true if we should use insert the REVERSE_PINVOKE_{ENTER,EXIT} helpers in the method
// prolog/epilog
inline bool IsReversePInvoke()
{
-#if COR_JIT_EE_VERSION > 460
return jitFlags->IsSet(JitFlags::JIT_FLAG_REVERSE_PINVOKE);
-#else
- return false;
-#endif
}
// true if we must generate code compatible with JIT32 quirks
inline bool IsJit32Compat()
{
-#if defined(_TARGET_X86_) && COR_JIT_EE_VERSION > 460
+#if defined(_TARGET_X86_)
return jitFlags->IsSet(JitFlags::JIT_FLAG_DESKTOP_QUIRKS);
#else
return false;
@@ -7721,9 +7831,9 @@ public:
// true if we must generate code compatible with Jit64 quirks
inline bool IsJit64Compat()
{
-#if defined(_TARGET_AMD64_) && COR_JIT_EE_VERSION > 460
+#if defined(_TARGET_AMD64_)
return jitFlags->IsSet(JitFlags::JIT_FLAG_DESKTOP_QUIRKS);
-#elif defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR)
+#elif !defined(FEATURE_CORECLR)
return true;
#else
return false;
@@ -7760,13 +7870,11 @@ public:
// (or)
// 3. When opts.compDbgEnC is true. (See also Compiler::compCompile).
//
-// When this flag is set, jit will allocate a gc-reference local variable (lvaSecurityObject),
-// which gets reported as a GC root to stackwalker.
-// (See also ICodeManager::GetAddrOfSecurityObject.)
+ // When this flag is set, jit will allocate a gc-reference local variable (lvaSecurityObject),
+ // which gets reported as a GC root to stackwalker.
+ // (See also ICodeManager::GetAddrOfSecurityObject.)
-#if RELOC_SUPPORT
bool compReloc;
-#endif
#ifdef DEBUG
#if defined(_TARGET_XARCH_) && !defined(LEGACY_BACKEND)
@@ -7790,8 +7898,11 @@ public:
bool genFPopt; // Can we do frame-pointer-omission optimization?
bool altJit; // True if we are an altjit and are compiling this method
+#ifdef OPT_CONFIG
+ bool optRepeat; // Repeat optimizer phases k times
+#endif
+
#ifdef DEBUG
- bool optRepeat; // Repeat optimizer phases k times
bool compProcedureSplittingEH; // Separate cold code from hot code for functions with EH
bool dspCode; // Display native code generated
bool dspEHTable; // Display the EH table reported to the VM
@@ -9371,6 +9482,10 @@ const instruction INS_ADDC = INS_adc;
const instruction INS_SUBC = INS_sbc;
const instruction INS_NOT = INS_mvn;
+const instruction INS_ABS = INS_vabs;
+const instruction INS_ROUND = INS_invalid;
+const instruction INS_SQRT = INS_vsqrt;
+
#endif
#ifdef _TARGET_ARM64_
@@ -9392,6 +9507,10 @@ const instruction INS_ADDC = INS_adc;
const instruction INS_SUBC = INS_sbc;
const instruction INS_NOT = INS_mvn;
+const instruction INS_ABS = INS_fabs;
+const instruction INS_ROUND = INS_frintn;
+const instruction INS_SQRT = INS_fsqrt;
+
#endif
/*****************************************************************************/
diff --git a/src/jit/compiler.hpp b/src/jit/compiler.hpp
index 6baf601892..88c082d499 100644
--- a/src/jit/compiler.hpp
+++ b/src/jit/compiler.hpp
@@ -2199,11 +2199,14 @@ inline bool Compiler::lvaKeepAliveAndReportThis()
return false;
}
+ const bool genericsContextIsThis = (info.compMethodInfo->options & CORINFO_GENERICS_CTXT_FROM_THIS) != 0;
+
#ifdef JIT32_GCENCODER
+
if (info.compFlags & CORINFO_FLG_SYNCH)
return true;
- if (info.compMethodInfo->options & CORINFO_GENERICS_CTXT_FROM_THIS)
+ if (genericsContextIsThis)
{
// TODO: Check if any of the exception clauses are
// typed using a generic type. Else, we do not need to report this.
@@ -2213,18 +2216,29 @@ inline bool Compiler::lvaKeepAliveAndReportThis()
if (opts.compDbgCode)
return true;
- if (lvaGenericsContextUsed)
+ if (lvaGenericsContextUseCount > 0)
+ {
+ JITDUMP("Reporting this as generic context: %u refs\n", lvaGenericsContextUseCount);
return true;
+ }
}
#else // !JIT32_GCENCODER
// If the generics context is the this pointer we need to report it if either
// the VM requires us to keep the generics context alive or it is used in a look-up.
- // We keep it alive in the lookup scenario, even when the VM didn't ask us too
+ // We keep it alive in the lookup scenario, even when the VM didn't ask us to,
// because collectible types need the generics context when gc-ing.
- if ((info.compMethodInfo->options & CORINFO_GENERICS_CTXT_FROM_THIS) &&
- (lvaGenericsContextUsed || (info.compMethodInfo->options & CORINFO_GENERICS_CTXT_KEEP_ALIVE)))
+ if (genericsContextIsThis)
{
- return true;
+ const bool isUsed = lvaGenericsContextUseCount > 0;
+ const bool mustKeep = (info.compMethodInfo->options & CORINFO_GENERICS_CTXT_KEEP_ALIVE) != 0;
+
+ if (isUsed || mustKeep)
+ {
+ JITDUMP("Reporting this as generic context: %u refs%s\n", lvaGenericsContextUseCount,
+ mustKeep ? ", must keep" : "");
+
+ return true;
+ }
}
#endif
@@ -2250,7 +2264,7 @@ inline bool Compiler::lvaReportParamTypeArg()
// Otherwise, if an exact type parameter is needed in the body, report the generics context.
// We do this because collectible types needs the generics context when gc-ing.
- if (lvaGenericsContextUsed)
+ if (lvaGenericsContextUseCount > 0)
{
return true;
}
@@ -2321,15 +2335,16 @@ inline
// On amd64, every param has a stack location, except on Unix-like systems.
assert(varDsc->lvIsParam);
#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
-#elif defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
- // For !LEGACY_BACKEND on x86, a stack parameter that is enregistered will have a stack location.
- assert(varDsc->lvIsParam && !varDsc->lvIsRegArg);
-#else // !(_TARGET_AMD64 || !(defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)))
+#elif !defined(LEGACY_BACKEND)
+ // For !LEGACY_BACKEND on other targets, a stack parameter that is enregistered or prespilled
+ // for profiling on ARM will have a stack location.
+ assert((varDsc->lvIsParam && !varDsc->lvIsRegArg) || isPrespilledArg);
+#else // !(_TARGET_AMD64 || defined(LEGACY_BACKEND))
// Otherwise, we only have a valid stack location for:
// A parameter that was passed on the stack, being homed into its register home,
// or a prespilled argument on arm under profiler.
assert((varDsc->lvIsParam && !varDsc->lvIsRegArg && varDsc->lvRegister) || isPrespilledArg);
-#endif // !(_TARGET_AMD64 || !(defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)))
+#endif // !(_TARGET_AMD64 || defined(LEGACY_BACKEND))
}
FPbased = varDsc->lvFramePointerBased;
@@ -2516,10 +2531,10 @@ inline BOOL Compiler::lvaIsOriginalThisArg(unsigned varNum)
// copy to a new local, and mark the original as DoNotEnregister, to
// ensure that it is stack-allocated. It should not be the case that the original one can be modified -- it
// should not be written to, or address-exposed.
- assert(!varDsc->lvArgWrite &&
+ assert(!varDsc->lvHasILStoreOp &&
(!varDsc->lvAddrExposed || ((info.compMethodInfo->options & CORINFO_GENERICS_CTXT_FROM_THIS) != 0)));
#else
- assert(!varDsc->lvArgWrite && !varDsc->lvAddrExposed);
+ assert(!varDsc->lvHasILStoreOp && !varDsc->lvAddrExposed);
#endif
}
#endif
@@ -2877,9 +2892,7 @@ inline bool Compiler::fgIsThrowHlpBlk(BasicBlock* block)
if (!((call->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_RNGCHKFAIL)) ||
(call->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_THROWDIVZERO)) ||
-#if COR_JIT_EE_VERSION > 460
(call->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_THROWNULLREF)) ||
-#endif // COR_JIT_EE_VERSION
(call->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_OVERFLOW))))
{
return false;
@@ -2893,11 +2906,8 @@ inline bool Compiler::fgIsThrowHlpBlk(BasicBlock* block)
{
if (block == add->acdDstBlk)
{
- return add->acdKind == SCK_RNGCHK_FAIL || add->acdKind == SCK_DIV_BY_ZERO || add->acdKind == SCK_OVERFLOW
-#if COR_JIT_EE_VERSION > 460
- || add->acdKind == SCK_ARG_EXCPN || add->acdKind == SCK_ARG_RNG_EXCPN
-#endif // COR_JIT_EE_VERSION
- ;
+ return add->acdKind == SCK_RNGCHK_FAIL || add->acdKind == SCK_DIV_BY_ZERO || add->acdKind == SCK_OVERFLOW ||
+ add->acdKind == SCK_ARG_EXCPN || add->acdKind == SCK_ARG_RNG_EXCPN;
}
}
@@ -2919,11 +2929,8 @@ inline unsigned Compiler::fgThrowHlpBlkStkLevel(BasicBlock* block)
{
// Compute assert cond separately as assert macro cannot have conditional compilation directives.
bool cond =
- (add->acdKind == SCK_RNGCHK_FAIL || add->acdKind == SCK_DIV_BY_ZERO || add->acdKind == SCK_OVERFLOW
-#if COR_JIT_EE_VERSION > 460
- || add->acdKind == SCK_ARG_EXCPN || add->acdKind == SCK_ARG_RNG_EXCPN
-#endif // COR_JIT_EE_VERSION
- );
+ (add->acdKind == SCK_RNGCHK_FAIL || add->acdKind == SCK_DIV_BY_ZERO || add->acdKind == SCK_OVERFLOW ||
+ add->acdKind == SCK_ARG_EXCPN || add->acdKind == SCK_ARG_RNG_EXCPN);
assert(cond);
// TODO: bbTgtStkDepth is DEBUG-only.
@@ -4450,7 +4457,7 @@ inline void Compiler::EndPhase(Phases phase)
#if defined(FEATURE_JIT_METHOD_PERF)
if (pCompJitTimer != nullptr)
{
- pCompJitTimer->EndPhase(phase);
+ pCompJitTimer->EndPhase(this, phase);
}
#endif
#if DUMP_FLOWGRAPHS
diff --git a/src/jit/compilerbitsettraits.h b/src/jit/compilerbitsettraits.h
index 4365c518d7..d0436f4052 100644
--- a/src/jit/compilerbitsettraits.h
+++ b/src/jit/compilerbitsettraits.h
@@ -22,10 +22,10 @@
class CompAllocBitSetTraits
{
public:
- static inline IAllocator* GetAllocator(class Compiler* comp);
+ static inline void* Alloc(Compiler* comp, size_t byteSize);
#ifdef DEBUG
- static inline IAllocator* GetDebugOnlyAllocator(class Compiler* comp);
+ static inline void* DebugAlloc(Compiler* comp, size_t byteSize);
#endif // DEBUG
};
@@ -112,10 +112,10 @@ public:
{
}
- static inline IAllocator* GetAllocator(BitVecTraits* b);
+ static inline void* Alloc(BitVecTraits* b, size_t byteSize);
#ifdef DEBUG
- static inline IAllocator* GetDebugOnlyAllocator(BitVecTraits* b);
+ static inline void* DebugAlloc(BitVecTraits* b, size_t byteSize);
#endif // DEBUG
static inline unsigned GetSize(BitVecTraits* b);
diff --git a/src/jit/compilerbitsettraits.hpp b/src/jit/compilerbitsettraits.hpp
index e2ba2f8a7a..be30564701 100644
--- a/src/jit/compilerbitsettraits.hpp
+++ b/src/jit/compilerbitsettraits.hpp
@@ -15,16 +15,16 @@
///////////////////////////////////////////////////////////////////////////////
// static
-IAllocator* CompAllocBitSetTraits::GetAllocator(Compiler* comp)
+void* CompAllocBitSetTraits::Alloc(Compiler* comp, size_t byteSize)
{
- return comp->getAllocatorBitset();
+ return comp->compGetMem(byteSize, CMK_bitset);
}
#ifdef DEBUG
// static
-IAllocator* CompAllocBitSetTraits::GetDebugOnlyAllocator(Compiler* comp)
+void* CompAllocBitSetTraits::DebugAlloc(Compiler* comp, size_t byteSize)
{
- return comp->getAllocatorDebugOnly();
+ return comp->compGetMem(byteSize, CMK_DebugOnly);
}
#endif // DEBUG
@@ -139,16 +139,16 @@ BitSetSupport::BitSetOpCounter* BasicBlockBitSetTraits::GetOpCounter(Compiler* c
///////////////////////////////////////////////////////////////////////////////
// static
-IAllocator* BitVecTraits::GetAllocator(BitVecTraits* b)
+void* BitVecTraits::Alloc(BitVecTraits* b, size_t byteSize)
{
- return b->comp->getAllocatorBitset();
+ return b->comp->compGetMem(byteSize, CMK_bitset);
}
#ifdef DEBUG
// static
-IAllocator* BitVecTraits::GetDebugOnlyAllocator(BitVecTraits* b)
+void* BitVecTraits::DebugAlloc(BitVecTraits* b, size_t byteSize)
{
- return b->comp->getAllocatorDebugOnly();
+ return b->comp->compGetMem(byteSize, CMK_DebugOnly);
}
#endif // DEBUG
diff --git a/src/jit/compphases.h b/src/jit/compphases.h
index 5038d6e9c9..e4dfedd499 100644
--- a/src/jit/compphases.h
+++ b/src/jit/compphases.h
@@ -11,95 +11,98 @@
// corresponding array of string names of those phases. This include file undefines CompPhaseNameMacro
// after the last use.
// The arguments are:
-// CompPhaseNameMacro(enumName, stringName, shortName, hasChildren, parent)
+// CompPhaseNameMacro(enumName, stringName, shortName, hasChildren, parent, measureIR)
// "enumName" is an Enumeration-style all-caps name.
// "stringName" is a self-explanatory.
// "shortName" is an abbreviated form for stringName
// "hasChildren" is true if this phase is broken out into subphases.
// (We should never do EndPhase on a phase that has children, only on 'leaf phases.')
// "parent" is -1 for leaf phases, otherwise it is the "enumName" of the parent phase.
+// "measureIR" is true for phases that generate a count of IR nodes during EndPhase when JitConfig.MeasureIR is
+// true.
// clang-format off
-CompPhaseNameMacro(PHASE_PRE_IMPORT, "Pre-import", "PRE-IMP", false, -1)
-CompPhaseNameMacro(PHASE_IMPORTATION, "Importation", "IMPORT", false, -1)
-CompPhaseNameMacro(PHASE_POST_IMPORT, "Post-import", "POST-IMP", false, -1)
-CompPhaseNameMacro(PHASE_MORPH_INIT, "Morph - Init", "MOR-INIT" ,false, -1)
-CompPhaseNameMacro(PHASE_MORPH_INLINE, "Morph - Inlining", "MOR-INL", false, -1)
-CompPhaseNameMacro(PHASE_MORPH_IMPBYREF, "Morph - ByRefs", "MOR-BYREF",false, -1)
-CompPhaseNameMacro(PHASE_EMPTY_TRY, "Remove empty try", "EMPTYTRY", false, -1)
-CompPhaseNameMacro(PHASE_EMPTY_FINALLY, "Remove empty finally", "EMPTYFIN", false, -1)
-CompPhaseNameMacro(PHASE_CLONE_FINALLY, "Clone finally", "CLONEFIN", false, -1)
-CompPhaseNameMacro(PHASE_STR_ADRLCL, "Morph - Structs/AddrExp", "MOR-STRAL",false, -1)
-CompPhaseNameMacro(PHASE_MORPH_GLOBAL, "Morph - Global", "MOR-GLOB", false, -1)
-CompPhaseNameMacro(PHASE_MORPH_END, "Morph - Finish", "MOR-END", false, -1)
-CompPhaseNameMacro(PHASE_GS_COOKIE, "GS Cookie", "GS-COOK", false, -1)
-CompPhaseNameMacro(PHASE_COMPUTE_PREDS, "Compute preds", "PREDS", false, -1)
-CompPhaseNameMacro(PHASE_MARK_GC_POLL_BLOCKS, "Mark GC poll blocks", "GC-POLL", false, -1)
-CompPhaseNameMacro(PHASE_COMPUTE_EDGE_WEIGHTS, "Compute edge weights (1)", "EDG-WGT", false, -1)
+CompPhaseNameMacro(PHASE_PRE_IMPORT, "Pre-import", "PRE-IMP", false, -1, false)
+CompPhaseNameMacro(PHASE_IMPORTATION, "Importation", "IMPORT", false, -1, true)
+CompPhaseNameMacro(PHASE_POST_IMPORT, "Post-import", "POST-IMP", false, -1, false)
+CompPhaseNameMacro(PHASE_MORPH_INIT, "Morph - Init", "MOR-INIT" ,false, -1, false)
+CompPhaseNameMacro(PHASE_MORPH_INLINE, "Morph - Inlining", "MOR-INL", false, -1, true)
+CompPhaseNameMacro(PHASE_MORPH_IMPBYREF, "Morph - ByRefs", "MOR-BYREF",false, -1, false)
+CompPhaseNameMacro(PHASE_EMPTY_TRY, "Remove empty try", "EMPTYTRY", false, -1, false)
+CompPhaseNameMacro(PHASE_EMPTY_FINALLY, "Remove empty finally", "EMPTYFIN", false, -1, false)
+CompPhaseNameMacro(PHASE_MERGE_FINALLY_CHAINS, "Merge callfinally chains", "MRGCFCHN", false, -1, false)
+CompPhaseNameMacro(PHASE_CLONE_FINALLY, "Clone finally", "CLONEFIN", false, -1, false)
+CompPhaseNameMacro(PHASE_STR_ADRLCL, "Morph - Structs/AddrExp", "MOR-STRAL",false, -1, false)
+CompPhaseNameMacro(PHASE_MORPH_GLOBAL, "Morph - Global", "MOR-GLOB", false, -1, false)
+CompPhaseNameMacro(PHASE_MORPH_END, "Morph - Finish", "MOR-END", false, -1, true)
+CompPhaseNameMacro(PHASE_GS_COOKIE, "GS Cookie", "GS-COOK", false, -1, false)
+CompPhaseNameMacro(PHASE_COMPUTE_PREDS, "Compute preds", "PREDS", false, -1, false)
+CompPhaseNameMacro(PHASE_MARK_GC_POLL_BLOCKS, "Mark GC poll blocks", "GC-POLL", false, -1, false)
+CompPhaseNameMacro(PHASE_COMPUTE_EDGE_WEIGHTS, "Compute edge weights (1, false)", "EDG-WGT", false, -1, false)
#if FEATURE_EH_FUNCLETS
-CompPhaseNameMacro(PHASE_CREATE_FUNCLETS, "Create EH funclets", "EH-FUNC", false, -1)
+CompPhaseNameMacro(PHASE_CREATE_FUNCLETS, "Create EH funclets", "EH-FUNC", false, -1, false)
#endif // FEATURE_EH_FUNCLETS
-CompPhaseNameMacro(PHASE_OPTIMIZE_LAYOUT, "Optimize layout", "LAYOUT", false, -1)
-CompPhaseNameMacro(PHASE_ALLOCATE_OBJECTS, "Allocate Objects", "ALLOC-OBJ",false, -1)
-CompPhaseNameMacro(PHASE_OPTIMIZE_LOOPS, "Optimize loops", "LOOP-OPT", false, -1)
-CompPhaseNameMacro(PHASE_CLONE_LOOPS, "Clone loops", "LP-CLONE", false, -1)
-CompPhaseNameMacro(PHASE_UNROLL_LOOPS, "Unroll loops", "UNROLL", false, -1)
-CompPhaseNameMacro(PHASE_HOIST_LOOP_CODE, "Hoist loop code", "LP-HOIST", false, -1)
-CompPhaseNameMacro(PHASE_MARK_LOCAL_VARS, "Mark local vars", "MARK-LCL", false, -1)
-CompPhaseNameMacro(PHASE_OPTIMIZE_BOOLS, "Optimize bools", "OPT-BOOL", false, -1)
-CompPhaseNameMacro(PHASE_FIND_OPER_ORDER, "Find oper order", "OPER-ORD", false, -1)
-CompPhaseNameMacro(PHASE_SET_BLOCK_ORDER, "Set block order", "BLK-ORD", false, -1)
-CompPhaseNameMacro(PHASE_BUILD_SSA, "Build SSA representation", "SSA", true, -1)
-CompPhaseNameMacro(PHASE_BUILD_SSA_TOPOSORT, "SSA: topological sort", "SSA-SORT", false, PHASE_BUILD_SSA)
-CompPhaseNameMacro(PHASE_BUILD_SSA_DOMS, "SSA: Doms1", "SSA-DOMS", false, PHASE_BUILD_SSA)
-CompPhaseNameMacro(PHASE_BUILD_SSA_LIVENESS, "SSA: liveness", "SSA-LIVE", false, PHASE_BUILD_SSA)
-CompPhaseNameMacro(PHASE_BUILD_SSA_IDF, "SSA: IDF", "SSA-IDF", false, PHASE_BUILD_SSA)
-CompPhaseNameMacro(PHASE_BUILD_SSA_INSERT_PHIS, "SSA: insert phis", "SSA-PHI", false, PHASE_BUILD_SSA)
-CompPhaseNameMacro(PHASE_BUILD_SSA_RENAME, "SSA: rename", "SSA-REN", false, PHASE_BUILD_SSA)
+CompPhaseNameMacro(PHASE_OPTIMIZE_LAYOUT, "Optimize layout", "LAYOUT", false, -1, false)
+CompPhaseNameMacro(PHASE_ALLOCATE_OBJECTS, "Allocate Objects", "ALLOC-OBJ",false, -1, false)
+CompPhaseNameMacro(PHASE_OPTIMIZE_LOOPS, "Optimize loops", "LOOP-OPT", false, -1, false)
+CompPhaseNameMacro(PHASE_CLONE_LOOPS, "Clone loops", "LP-CLONE", false, -1, false)
+CompPhaseNameMacro(PHASE_UNROLL_LOOPS, "Unroll loops", "UNROLL", false, -1, false)
+CompPhaseNameMacro(PHASE_HOIST_LOOP_CODE, "Hoist loop code", "LP-HOIST", false, -1, false)
+CompPhaseNameMacro(PHASE_MARK_LOCAL_VARS, "Mark local vars", "MARK-LCL", false, -1, false)
+CompPhaseNameMacro(PHASE_OPTIMIZE_BOOLS, "Optimize bools", "OPT-BOOL", false, -1, false)
+CompPhaseNameMacro(PHASE_FIND_OPER_ORDER, "Find oper order", "OPER-ORD", false, -1, false)
+CompPhaseNameMacro(PHASE_SET_BLOCK_ORDER, "Set block order", "BLK-ORD", false, -1, true)
+CompPhaseNameMacro(PHASE_BUILD_SSA, "Build SSA representation", "SSA", true, -1, false)
+CompPhaseNameMacro(PHASE_BUILD_SSA_TOPOSORT, "SSA: topological sort", "SSA-SORT", false, PHASE_BUILD_SSA, false)
+CompPhaseNameMacro(PHASE_BUILD_SSA_DOMS, "SSA: Doms1", "SSA-DOMS", false, PHASE_BUILD_SSA, false)
+CompPhaseNameMacro(PHASE_BUILD_SSA_LIVENESS, "SSA: liveness", "SSA-LIVE", false, PHASE_BUILD_SSA, false)
+CompPhaseNameMacro(PHASE_BUILD_SSA_IDF, "SSA: IDF", "SSA-IDF", false, PHASE_BUILD_SSA, false)
+CompPhaseNameMacro(PHASE_BUILD_SSA_INSERT_PHIS, "SSA: insert phis", "SSA-PHI", false, PHASE_BUILD_SSA, false)
+CompPhaseNameMacro(PHASE_BUILD_SSA_RENAME, "SSA: rename", "SSA-REN", false, PHASE_BUILD_SSA, false)
-CompPhaseNameMacro(PHASE_EARLY_PROP, "Early Value Propagation", "ERL-PROP", false, -1)
-CompPhaseNameMacro(PHASE_VALUE_NUMBER, "Do value numbering", "VAL-NUM", false, -1)
+CompPhaseNameMacro(PHASE_EARLY_PROP, "Early Value Propagation", "ERL-PROP", false, -1, false)
+CompPhaseNameMacro(PHASE_VALUE_NUMBER, "Do value numbering", "VAL-NUM", false, -1, false)
-CompPhaseNameMacro(PHASE_OPTIMIZE_INDEX_CHECKS, "Optimize index checks", "OPT-CHK", false, -1)
+CompPhaseNameMacro(PHASE_OPTIMIZE_INDEX_CHECKS, "Optimize index checks", "OPT-CHK", false, -1, false)
#if FEATURE_VALNUM_CSE
-CompPhaseNameMacro(PHASE_OPTIMIZE_VALNUM_CSES, "Optimize Valnum CSEs", "OPT-CSE", false, -1)
+CompPhaseNameMacro(PHASE_OPTIMIZE_VALNUM_CSES, "Optimize Valnum CSEs", "OPT-CSE", false, -1, false)
#endif
-CompPhaseNameMacro(PHASE_VN_COPY_PROP, "VN based copy prop", "CP-PROP", false, -1)
+CompPhaseNameMacro(PHASE_VN_COPY_PROP, "VN based copy prop", "CP-PROP", false, -1, false)
#if ASSERTION_PROP
-CompPhaseNameMacro(PHASE_ASSERTION_PROP_MAIN, "Assertion prop", "AST-PROP", false, -1)
+CompPhaseNameMacro(PHASE_ASSERTION_PROP_MAIN, "Assertion prop", "AST-PROP", false, -1, false)
#endif
-CompPhaseNameMacro(PHASE_UPDATE_FLOW_GRAPH, "Update flow graph", "UPD-FG", false, -1)
-CompPhaseNameMacro(PHASE_COMPUTE_EDGE_WEIGHTS2, "Compute edge weights (2)", "EDG-WGT2", false, -1)
-CompPhaseNameMacro(PHASE_DETERMINE_FIRST_COLD_BLOCK, "Determine first cold block", "COLD-BLK", false, -1)
-CompPhaseNameMacro(PHASE_RATIONALIZE, "Rationalize IR", "RAT", false, -1)
-CompPhaseNameMacro(PHASE_SIMPLE_LOWERING, "Do 'simple' lowering", "SMP-LWR", false, -1)
+CompPhaseNameMacro(PHASE_UPDATE_FLOW_GRAPH, "Update flow graph", "UPD-FG", false, -1, false)
+CompPhaseNameMacro(PHASE_COMPUTE_EDGE_WEIGHTS2, "Compute edge weights (2, false)", "EDG-WGT2", false, -1, false)
+CompPhaseNameMacro(PHASE_DETERMINE_FIRST_COLD_BLOCK, "Determine first cold block", "COLD-BLK", false, -1, true)
+CompPhaseNameMacro(PHASE_RATIONALIZE, "Rationalize IR", "RAT", false, -1, false)
+CompPhaseNameMacro(PHASE_SIMPLE_LOWERING, "Do 'simple' lowering", "SMP-LWR", false, -1, false)
-CompPhaseNameMacro(PHASE_LCLVARLIVENESS, "Local var liveness", "LIVENESS", true, -1)
-CompPhaseNameMacro(PHASE_LCLVARLIVENESS_INIT, "Local var liveness init", "LIV-INIT", false, PHASE_LCLVARLIVENESS)
-CompPhaseNameMacro(PHASE_LCLVARLIVENESS_PERBLOCK,"Per block local var liveness", "LIV-BLK", false, PHASE_LCLVARLIVENESS)
-CompPhaseNameMacro(PHASE_LCLVARLIVENESS_INTERBLOCK, "Global local var liveness", "LIV-GLBL", false, PHASE_LCLVARLIVENESS)
+CompPhaseNameMacro(PHASE_LCLVARLIVENESS, "Local var liveness", "LIVENESS", true, -1, false)
+CompPhaseNameMacro(PHASE_LCLVARLIVENESS_INIT, "Local var liveness init", "LIV-INIT", false, PHASE_LCLVARLIVENESS, false)
+CompPhaseNameMacro(PHASE_LCLVARLIVENESS_PERBLOCK,"Per block local var liveness", "LIV-BLK", false, PHASE_LCLVARLIVENESS, false)
+CompPhaseNameMacro(PHASE_LCLVARLIVENESS_INTERBLOCK, "Global local var liveness", "LIV-GLBL", false, PHASE_LCLVARLIVENESS, false)
#ifdef LEGACY_BACKEND
-CompPhaseNameMacro(PHASE_RA_ASSIGN_VARS, "RA assign vars", "REGALLOC", false, -1)
+CompPhaseNameMacro(PHASE_RA_ASSIGN_VARS, "RA assign vars", "REGALLOC", false, -1, false)
#endif // LEGACY_BACKEND
-CompPhaseNameMacro(PHASE_LOWERING_DECOMP, "Lowering decomposition", "LWR-DEC", false, -1)
-CompPhaseNameMacro(PHASE_LOWERING, "Lowering nodeinfo", "LWR-INFO", false, -1)
+CompPhaseNameMacro(PHASE_LOWERING_DECOMP, "Lowering decomposition", "LWR-DEC", false, -1, false)
+CompPhaseNameMacro(PHASE_LOWERING, "Lowering nodeinfo", "LWR-INFO", false, -1, true)
#ifndef LEGACY_BACKEND
-CompPhaseNameMacro(PHASE_LINEAR_SCAN, "Linear scan register alloc", "LSRA", true, -1)
-CompPhaseNameMacro(PHASE_LINEAR_SCAN_BUILD, "LSRA build intervals", "LSRA-BLD", false, PHASE_LINEAR_SCAN)
-CompPhaseNameMacro(PHASE_LINEAR_SCAN_ALLOC, "LSRA allocate", "LSRA-ALL", false, PHASE_LINEAR_SCAN)
-CompPhaseNameMacro(PHASE_LINEAR_SCAN_RESOLVE, "LSRA resolve", "LSRA-RES", false, PHASE_LINEAR_SCAN)
+CompPhaseNameMacro(PHASE_LINEAR_SCAN, "Linear scan register alloc", "LSRA", true, -1, true)
+CompPhaseNameMacro(PHASE_LINEAR_SCAN_BUILD, "LSRA build intervals", "LSRA-BLD", false, PHASE_LINEAR_SCAN, false)
+CompPhaseNameMacro(PHASE_LINEAR_SCAN_ALLOC, "LSRA allocate", "LSRA-ALL", false, PHASE_LINEAR_SCAN, false)
+CompPhaseNameMacro(PHASE_LINEAR_SCAN_RESOLVE, "LSRA resolve", "LSRA-RES", false, PHASE_LINEAR_SCAN, false)
#endif // !LEGACY_BACKEND
-CompPhaseNameMacro(PHASE_GENERATE_CODE, "Generate code", "CODEGEN", false, -1)
-CompPhaseNameMacro(PHASE_EMIT_CODE, "Emit code", "EMIT", false, -1)
-CompPhaseNameMacro(PHASE_EMIT_GCEH, "Emit GC+EH tables", "EMT-GCEH", false, -1)
+CompPhaseNameMacro(PHASE_GENERATE_CODE, "Generate code", "CODEGEN", false, -1, false)
+CompPhaseNameMacro(PHASE_EMIT_CODE, "Emit code", "EMIT", false, -1, false)
+CompPhaseNameMacro(PHASE_EMIT_GCEH, "Emit GC+EH tables", "EMT-GCEH", false, -1, false)
#if MEASURE_CLRAPI_CALLS
// The following is a "pseudo-phase" - it aggregates timing info
// for calls through ICorJitInfo across all "real" phases.
-CompPhaseNameMacro(PHASE_CLR_API, "CLR API calls", "CLR-API", false, -1)
+CompPhaseNameMacro(PHASE_CLR_API, "CLR API calls", "CLR-API", false, -1, false)
#endif
// clang-format on
diff --git a/src/jit/crossgen/CMakeLists.txt b/src/jit/crossgen/CMakeLists.txt
index 6440e91a04..4d49a319b8 100644
--- a/src/jit/crossgen/CMakeLists.txt
+++ b/src/jit/crossgen/CMakeLists.txt
@@ -4,4 +4,4 @@ if(CLR_CMAKE_TARGET_ARCH_ARM)
add_definitions(-DLEGACY_BACKEND)
endif()
-add_library_clr(clrjit_crossgen ${SOURCES})
+add_library_clr(clrjit_crossgen ${SOURCES} ${JIT_ARCH_SOURCES})
diff --git a/src/jit/decomposelongs.cpp b/src/jit/decomposelongs.cpp
index 407ae1c35b..d284c1cb47 100644
--- a/src/jit/decomposelongs.cpp
+++ b/src/jit/decomposelongs.cpp
@@ -265,7 +265,7 @@ GenTree* DecomposeLongs::DecomposeNode(GenTree* tree)
default:
{
JITDUMP("Illegal TYP_LONG node %s in Decomposition.", GenTree::NodeName(tree->OperGet()));
- noway_assert(!"Illegal TYP_LONG node in Decomposition.");
+ assert(!"Illegal TYP_LONG node in Decomposition.");
break;
}
}
@@ -580,6 +580,8 @@ GenTree* DecomposeLongs::DecomposeCast(LIR::Use& use)
srcType = genUnsignedType(srcType);
}
+ bool skipDecomposition = false;
+
if (varTypeIsLong(srcType))
{
if (cast->gtOverflow() && (varTypeIsUnsigned(srcType) != varTypeIsUnsigned(dstType)))
@@ -605,9 +607,7 @@ GenTree* DecomposeLongs::DecomposeCast(LIR::Use& use)
hiResult->gtFlags &= ~GTF_UNSIGNED;
hiResult->gtOp.gtOp1 = hiSrcOp;
- Range().Remove(cast);
Range().Remove(srcOp);
- Range().InsertAfter(hiSrcOp, hiResult);
}
else
{
@@ -634,13 +634,26 @@ GenTree* DecomposeLongs::DecomposeCast(LIR::Use& use)
}
else
{
- if (varTypeIsUnsigned(srcType))
+ if (!use.IsDummyUse() && (use.User()->OperGet() == GT_MUL))
+ {
+ //
+ // This int->long cast is used by a GT_MUL that will be transformed by DecomposeMul into a
+ // GT_LONG_MUL and as a result the high operand produced by the cast will become dead.
+ // Skip cast decomposition so DecomposeMul doesn't need to bother with dead code removal,
+ // especially in the case of sign extending casts that also introduce new lclvars.
+ //
+
+ assert((use.User()->gtFlags & GTF_MUL_64RSLT) != 0);
+
+ skipDecomposition = true;
+ }
+ else if (varTypeIsUnsigned(srcType))
{
loResult = cast->gtGetOp1();
hiResult = m_compiler->gtNewZeroConNode(TYP_INT);
+ Range().InsertAfter(cast, hiResult);
Range().Remove(cast);
- Range().InsertAfter(loResult, hiResult);
}
else
{
@@ -653,9 +666,10 @@ GenTree* DecomposeLongs::DecomposeCast(LIR::Use& use)
GenTree* shiftBy = m_compiler->gtNewIconNode(31, TYP_INT);
hiResult = m_compiler->gtNewOperNode(GT_RSH, TYP_INT, loCopy, shiftBy);
- Range().Remove(cast);
- Range().InsertAfter(loResult, loCopy, shiftBy, hiResult);
+ Range().InsertAfter(cast, loCopy, shiftBy, hiResult);
m_compiler->lvaIncRefCnts(loCopy);
+
+ Range().Remove(cast);
}
}
}
@@ -664,6 +678,11 @@ GenTree* DecomposeLongs::DecomposeCast(LIR::Use& use)
NYI("Unimplemented cast decomposition");
}
+ if (skipDecomposition)
+ {
+ return cast->gtNext;
+ }
+
return FinalizeDecomposition(use, loResult, hiResult, hiResult);
}
@@ -994,15 +1013,25 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
{
assert(use.IsInitialized());
- GenTree* tree = use.Def();
- GenTree* gtLong = tree->gtGetOp1();
+ GenTree* shift = use.Def();
+ GenTree* gtLong = shift->gtGetOp1();
GenTree* loOp1 = gtLong->gtGetOp1();
GenTree* hiOp1 = gtLong->gtGetOp2();
- GenTree* shiftByOp = tree->gtGetOp2();
+ GenTree* shiftByOp = shift->gtGetOp2();
- genTreeOps oper = tree->OperGet();
+ genTreeOps oper = shift->OperGet();
genTreeOps shiftByOper = shiftByOp->OperGet();
+ // tLo = ...
+ // ...
+ // tHi = ...
+ // ...
+ // tLong = long tLo, tHi
+ // ...
+ // tShiftAmount = ...
+ // ...
+ // tShift = shift tLong, tShiftAmount
+
assert((oper == GT_LSH) || (oper == GT_RSH) || (oper == GT_RSZ));
// If we are shifting by a constant int, we do not want to use a helper, instead, we decompose.
@@ -1013,9 +1042,9 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
if (count == 0)
{
- GenTree* next = tree->gtNext;
- // Remove tree and don't do anything else.
- Range().Remove(tree);
+ GenTree* next = shift->gtNext;
+ // Remove shift and don't do anything else.
+ Range().Remove(shift);
use.ReplaceWith(m_compiler, gtLong);
return next;
}
@@ -1029,15 +1058,27 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
{
case GT_LSH:
{
- Range().Remove(hiOp1);
if (count < 32)
{
- // Hi is a GT_LSH_HI, lo is a GT_LSH. Will produce:
- // reg1 = lo
- // shl lo, shift
- // shld hi, reg1, shift
+ // For shifts of < 32 bits, we transform the code to:
+ //
+ // tLo = ...
+ // st.lclVar vLo, tLo
+ // ...
+ // tHi = ...
+ // ...
+ // tShiftLo = lsh vLo, tShiftAmountLo
+ // tShitHiLong = long vLo, tHi
+ // tShiftHi = lsh_hi tShiftHiLong, tShiftAmountHi
+ //
+ // This will produce:
+ //
+ // reg1 = lo
+ // shl lo, shift
+ // shld hi, reg1, shift
Range().Remove(gtLong);
+
loOp1 = RepresentOpAsLocalVar(loOp1, gtLong, &gtLong->gtOp.gtOp1);
unsigned loOp1LclNum = loOp1->AsLclVarCommon()->gtLclNum;
Range().Remove(loOp1);
@@ -1055,16 +1096,25 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
m_compiler->lvaIncRefCnts(loCopy);
- Range().InsertBefore(tree, loCopy, hiOp1, hiOp);
- Range().InsertBefore(tree, shiftByHi, hiResult);
- Range().InsertBefore(tree, loOp1, shiftByLo, loResult);
+ Range().InsertBefore(shift, loOp1, shiftByLo, loResult);
+ Range().InsertBefore(shift, loCopy, hiOp, shiftByHi, hiResult);
- insertAfter = loResult;
+ insertAfter = hiResult;
}
else
{
assert(count >= 32);
+ // Since we're left shifting at least 32 bits, we can remove the hi part of the shifted value iff
+ // it has no side effects.
+ //
+ // TODO-CQ: we could go perform this removal transitively (i.e. iteratively remove everything that
+ // feeds the hi operand while there are no side effects)
+ if ((hiOp1->gtFlags & GTF_ALL_EFFECT) == 0)
+ {
+ Range().Remove(hiOp1);
+ }
+
if (count < 64)
{
if (count == 32)
@@ -1083,7 +1133,6 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
else
{
Range().Remove(gtLong);
- Range().Remove(loOp1);
assert(count > 32 && count < 64);
// Move loOp1 into hiResult, do a GT_LSH with count - 32.
@@ -1091,23 +1140,33 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
// temp
GenTree* shiftBy = m_compiler->gtNewIconNode(count - 32, TYP_INT);
hiResult = m_compiler->gtNewOperNode(oper, TYP_INT, loOp1, shiftBy);
- Range().InsertBefore(tree, loOp1, shiftBy, hiResult);
+ Range().InsertBefore(shift, shiftBy, hiResult);
}
}
else
{
- Range().Remove(gtLong);
- Range().Remove(loOp1);
assert(count >= 64);
+ Range().Remove(gtLong);
+
+ // Since we're left shifting at least 64 bits, we can remove the lo part of the shifted value
+ // iff it has no side effects.
+ //
+ // TODO-CQ: we could go perform this removal transitively (i.e. iteratively remove everything
+ // that feeds the lo operand while there are no side effects)
+ if ((loOp1->gtFlags & GTF_ALL_EFFECT) == 0)
+ {
+ Range().Remove(loOp1);
+ }
+
// Zero out hi (shift of >= 64 bits moves all the bits out of the two registers)
hiResult = m_compiler->gtNewZeroConNode(TYP_INT);
- Range().InsertBefore(tree, hiResult);
+ Range().InsertBefore(shift, hiResult);
}
// Zero out loResult (shift of >= 32 bits shifts all lo bits to hiResult)
loResult = m_compiler->gtNewZeroConNode(TYP_INT);
- Range().InsertBefore(tree, loResult);
+ Range().InsertBefore(shift, loResult);
insertAfter = loResult;
}
@@ -1140,14 +1199,22 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
GenTree* loOp = new (m_compiler, GT_LONG) GenTreeOp(GT_LONG, TYP_LONG, loOp1, hiCopy);
loResult = m_compiler->gtNewOperNode(GT_RSH_LO, TYP_INT, loOp, shiftByLo);
- Range().InsertBefore(tree, hiCopy, loOp);
- Range().InsertBefore(tree, shiftByLo, loResult);
- Range().InsertBefore(tree, shiftByHi, hiResult);
+ Range().InsertBefore(shift, hiCopy, loOp);
+ Range().InsertBefore(shift, shiftByLo, loResult);
+ Range().InsertBefore(shift, shiftByHi, hiResult);
}
else
{
- Range().Remove(loOp1);
- Range().Remove(hiOp1);
+ // Since we're right shifting at least 32 bits, we can remove the lo part of the shifted value iff
+ // it has no side effects.
+ //
+ // TODO-CQ: we could go perform this removal transitively (i.e. iteratively remove everything that
+ // feeds the lo operand while there are no side effects)
+ if ((loOp1->gtFlags & GTF_ALL_EFFECT) == 0)
+ {
+ Range().Remove(loOp1);
+ }
+
assert(count >= 32);
if (count < 64)
{
@@ -1155,7 +1222,6 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
{
// Move hiOp1 into loResult.
loResult = hiOp1;
- Range().InsertBefore(tree, loResult);
}
else
{
@@ -1164,21 +1230,31 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
// Move hiOp1 into loResult, do a GT_RSZ with count - 32.
GenTree* shiftBy = m_compiler->gtNewIconNode(count - 32, TYP_INT);
loResult = m_compiler->gtNewOperNode(oper, TYP_INT, hiOp1, shiftBy);
- Range().InsertBefore(tree, hiOp1, shiftBy, loResult);
+ Range().InsertBefore(shift, shiftBy, loResult);
}
}
else
{
assert(count >= 64);
+ // Since we're right shifting at least 64 bits, we can remove the hi part of the shifted value
+ // iff it has no side effects.
+ //
+ // TODO-CQ: we could go perform this removal transitively (i.e. iteratively remove everything
+ // that feeds the hi operand while there are no side effects)
+ if ((hiOp1->gtFlags & GTF_ALL_EFFECT) == 0)
+ {
+ Range().Remove(hiOp1);
+ }
+
// Zero out lo
loResult = m_compiler->gtNewZeroConNode(TYP_INT);
- Range().InsertBefore(tree, loResult);
+ Range().InsertBefore(shift, loResult);
}
// Zero out hi
hiResult = m_compiler->gtNewZeroConNode(TYP_INT);
- Range().InsertBefore(tree, hiResult);
+ Range().InsertBefore(shift, hiResult);
}
insertAfter = hiResult;
@@ -1187,7 +1263,6 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
case GT_RSH:
{
Range().Remove(gtLong);
- Range().Remove(loOp1);
hiOp1 = RepresentOpAsLocalVar(hiOp1, gtLong, &gtLong->gtOp.gtOp2);
unsigned hiOp1LclNum = hiOp1->AsLclVarCommon()->gtLclNum;
@@ -1212,20 +1287,31 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
GenTree* loOp = new (m_compiler, GT_LONG) GenTreeOp(GT_LONG, TYP_LONG, loOp1, hiCopy);
loResult = m_compiler->gtNewOperNode(GT_RSH_LO, TYP_INT, loOp, shiftByLo);
- Range().InsertBefore(tree, loOp1, hiCopy, loOp);
- Range().InsertBefore(tree, shiftByLo, loResult);
- Range().InsertBefore(tree, shiftByHi, hiOp1, hiResult);
+ Range().InsertBefore(shift, hiCopy, loOp);
+ Range().InsertBefore(shift, shiftByLo, loResult);
+ Range().InsertBefore(shift, shiftByHi, hiOp1, hiResult);
}
else
{
assert(count >= 32);
+
+ // Since we're right shifting at least 32 bits, we can remove the lo part of the shifted value iff
+ // it has no side effects.
+ //
+ // TODO-CQ: we could go perform this removal transitively (i.e. iteratively remove everything that
+ // feeds the lo operand while there are no side effects)
+ if ((loOp1->gtFlags & GTF_ALL_EFFECT) == 0)
+ {
+ Range().Remove(loOp1);
+ }
+
if (count < 64)
{
if (count == 32)
{
// Move hiOp1 into loResult.
loResult = hiOp1;
- Range().InsertBefore(tree, loResult);
+ Range().InsertBefore(shift, loResult);
}
else
{
@@ -1234,13 +1320,13 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
// Move hiOp1 into loResult, do a GT_RSH with count - 32.
GenTree* shiftBy = m_compiler->gtNewIconNode(count - 32, TYP_INT);
loResult = m_compiler->gtNewOperNode(oper, TYP_INT, hiOp1, shiftBy);
- Range().InsertBefore(tree, hiOp1, shiftBy, loResult);
+ Range().InsertBefore(shift, hiOp1, shiftBy, loResult);
}
// Propagate sign bit in hiResult
GenTree* shiftBy = m_compiler->gtNewIconNode(31, TYP_INT);
hiResult = m_compiler->gtNewOperNode(GT_RSH, TYP_INT, hiCopy, shiftBy);
- Range().InsertBefore(tree, shiftBy, hiCopy, hiResult);
+ Range().InsertBefore(shift, shiftBy, hiCopy, hiResult);
m_compiler->lvaIncRefCnts(hiCopy);
}
@@ -1251,12 +1337,12 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
// Propagate sign bit in loResult
GenTree* loShiftBy = m_compiler->gtNewIconNode(31, TYP_INT);
loResult = m_compiler->gtNewOperNode(GT_RSH, TYP_INT, hiCopy, loShiftBy);
- Range().InsertBefore(tree, hiCopy, loShiftBy, loResult);
+ Range().InsertBefore(shift, hiCopy, loShiftBy, loResult);
// Propagate sign bit in hiResult
GenTree* shiftBy = m_compiler->gtNewIconNode(31, TYP_INT);
hiResult = m_compiler->gtNewOperNode(GT_RSH, TYP_INT, hiOp1, shiftBy);
- Range().InsertBefore(tree, shiftBy, hiOp1, hiResult);
+ Range().InsertBefore(shift, shiftBy, hiOp1, hiResult);
m_compiler->lvaIncRefCnts(hiCopy);
}
@@ -1269,15 +1355,16 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
unreached();
}
- // Remove tree from Range
- Range().Remove(tree);
+ // Remove shift from Range
+ Range().Remove(shift);
return FinalizeDecomposition(use, loResult, hiResult, insertAfter);
}
else
{
- // arguments are single used, but LIR call can work only with local vars.
- shiftByOp = RepresentOpAsLocalVar(shiftByOp, tree, &tree->gtOp.gtOp2);
+ // Because calls must be created as HIR and lowered to LIR, we need to dump
+ // any LIR temps into lclVars before using them as arguments.
+ shiftByOp = RepresentOpAsLocalVar(shiftByOp, shift, &shift->gtOp.gtOp2);
loOp1 = RepresentOpAsLocalVar(loOp1, gtLong, &gtLong->gtOp.gtOp1);
hiOp1 = RepresentOpAsLocalVar(hiOp1, gtLong, &gtLong->gtOp.gtOp2);
@@ -1306,16 +1393,16 @@ GenTree* DecomposeLongs::DecomposeShift(LIR::Use& use)
GenTreeArgList* argList = m_compiler->gtNewArgList(loOp1, hiOp1, shiftByOp);
GenTree* call = m_compiler->gtNewHelperCallNode(helper, TYP_LONG, 0, argList);
- call->gtFlags |= tree->gtFlags & GTF_ALL_EFFECT;
+ call->gtFlags |= shift->gtFlags & GTF_ALL_EFFECT;
GenTreeCall* callNode = call->AsCall();
ReturnTypeDesc* retTypeDesc = callNode->GetReturnTypeDesc();
retTypeDesc->InitializeLongReturnType(m_compiler);
call = m_compiler->fgMorphArgs(callNode);
- Range().InsertAfter(tree, LIR::SeqTree(m_compiler, call));
+ Range().InsertAfter(shift, LIR::SeqTree(m_compiler, call));
- Range().Remove(tree);
+ Range().Remove(shift);
use.ReplaceWith(m_compiler, call);
return call;
}
@@ -1486,19 +1573,16 @@ GenTree* DecomposeLongs::DecomposeMul(LIR::Use& use)
GenTree* op1 = tree->gtGetOp1();
GenTree* op2 = tree->gtGetOp2();
- GenTree* loOp1 = op1->gtGetOp1();
- GenTree* hiOp1 = op1->gtGetOp2();
- GenTree* loOp2 = op2->gtGetOp1();
- GenTree* hiOp2 = op2->gtGetOp2();
+ // We expect both operands to be int->long casts. DecomposeCast specifically
+ // ignores such casts when they are used by GT_MULs.
+ assert((op1->OperGet() == GT_CAST) && (op1->TypeGet() == TYP_LONG));
+ assert((op2->OperGet() == GT_CAST) && (op2->TypeGet() == TYP_LONG));
- Range().Remove(hiOp1);
- Range().Remove(hiOp2);
Range().Remove(op1);
Range().Remove(op2);
- // Get rid of the hi ops. We don't need them.
- tree->gtOp.gtOp1 = loOp1;
- tree->gtOp.gtOp2 = loOp2;
+ tree->gtOp.gtOp1 = op1->gtGetOp1();
+ tree->gtOp.gtOp2 = op2->gtGetOp1();
tree->SetOperRaw(GT_MUL_LONG);
return StoreNodeToVar(use);
diff --git a/src/jit/dll/CMakeLists.txt b/src/jit/dll/CMakeLists.txt
index 43ed07eae5..6d247fe0d0 100644
--- a/src/jit/dll/CMakeLists.txt
+++ b/src/jit/dll/CMakeLists.txt
@@ -4,32 +4,18 @@ if(CLR_CMAKE_TARGET_ARCH_ARM)
add_definitions(-DLEGACY_BACKEND)
endif(CLR_CMAKE_TARGET_ARCH_ARM)
-# Disable the following for UNIX altjit on Windows
if(CLR_CMAKE_PLATFORM_UNIX)
add_compile_options(-fPIC)
add_library_clr(clrjit_static
STATIC
${SHARED_LIB_SOURCES}
+ ${JIT_ARCH_SOURCES}
)
add_dependencies(clrjit_static coreclrpal gcinfo)
else()
add_library_clr(clrjit_static
- ${SOURCES}
+ ${SHARED_LIB_SOURCES}
+ ${JIT_ARCH_SOURCES}
)
-# Disable up to here (see above) the following for UNIX altjit on Windows
-# Enable the following for UNIX altjit on Windows
-# add_library_clr(ClrJit
-# SHARED
-# ${SHARED_LIB_SOURCES}
-# )
-
-# Enable the following for UNIX altjit on Windows
-#target_link_libraries(ClrJit
-# utilcode
-# gcinfo
-# runtime_library
-# )
-
-# Disable the following for UNIX altjit on Windows
endif(CLR_CMAKE_PLATFORM_UNIX)
diff --git a/src/jit/ee_il_dll.cpp b/src/jit/ee_il_dll.cpp
index d5705ab353..c0384f3858 100644
--- a/src/jit/ee_il_dll.cpp
+++ b/src/jit/ee_il_dll.cpp
@@ -20,7 +20,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "emit.h"
#include "corexcep.h"
-#if !defined(PLATFORM_UNIX)
+#if !defined(_HOST_UNIX_)
#include <io.h> // For _dup, _setmode
#include <fcntl.h> // For _O_TEXT
#include <errno.h> // For EINVAL
@@ -66,9 +66,9 @@ extern "C" void __stdcall jitStartup(ICorJitHost* jitHost)
assert(!JitConfig.isInitialized());
JitConfig.initialize(jitHost);
-#if defined(PLATFORM_UNIX)
+#if defined(_HOST_UNIX_)
jitstdout = procstdout();
-#else
+#else // !_HOST_UNIX_
if (jitstdout == nullptr)
{
int stdoutFd = _fileno(procstdout());
@@ -99,7 +99,7 @@ extern "C" void __stdcall jitStartup(ICorJitHost* jitHost)
{
jitstdout = procstdout();
}
-#endif // PLATFORM_UNIX
+#endif // !_HOST_UNIX_
#ifdef FEATURE_TRACELOGGING
JitTelemetry::NotifyDllProcessAttach();
@@ -136,9 +136,6 @@ extern "C" BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID pvReserv
{
g_hInst = (HINSTANCE)hInstance;
DisableThreadLibraryCalls((HINSTANCE)hInstance);
-#if defined(SELF_NO_HOST) && COR_JIT_EE_VERSION <= 460
- jitStartup(JitHost::getJitHost());
-#endif
}
else if (dwReason == DLL_PROCESS_DETACH)
{
@@ -158,10 +155,6 @@ extern "C" void __stdcall sxsJitStartup(CoreClrCallbacks const& cccallbacks)
#ifndef SELF_NO_HOST
InitUtilcode(cccallbacks);
#endif
-
-#if COR_JIT_EE_VERSION <= 460
- jitStartup(JitHost::getJitHost());
-#endif
}
#endif // !FEATURE_MERGE_JIT_AND_ENGINE
@@ -286,15 +279,11 @@ CorJitResult CILJit::compileMethod(
JitFlags jitFlags;
-#if COR_JIT_EE_VERSION > 460
assert(flags == CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS);
CORJIT_FLAGS corJitFlags;
DWORD jitFlagsSize = compHnd->getJitFlags(&corJitFlags, sizeof(corJitFlags));
assert(jitFlagsSize == sizeof(corJitFlags));
jitFlags.SetFromFlags(corJitFlags);
-#else // COR_JIT_EE_VERSION <= 460
- jitFlags.SetFromOldFlags(flags, 0);
-#endif // COR_JIT_EE_VERSION <= 460
int result;
void* methodCodePtr = nullptr;
@@ -382,11 +371,7 @@ void CILJit::getVersionIdentifier(GUID* versionIdentifier)
* Determine the maximum length of SIMD vector supported by this JIT.
*/
-#if COR_JIT_EE_VERSION > 460
unsigned CILJit::getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags)
-#else
-unsigned CILJit::getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags)
-#endif
{
if (g_realJitCompiler != nullptr)
{
@@ -394,12 +379,7 @@ unsigned CILJit::getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags)
}
JitFlags jitFlags;
-
-#if COR_JIT_EE_VERSION > 460
jitFlags.SetFromFlags(cpuCompileFlags);
-#else // COR_JIT_EE_VERSION <= 460
- jitFlags.SetFromOldFlags(cpuCompileFlags, 0);
-#endif // COR_JIT_EE_VERSION <= 460
#ifdef FEATURE_SIMD
#ifdef _TARGET_XARCH_
@@ -409,16 +389,25 @@ unsigned CILJit::getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags)
{
if (JitConfig.EnableAVX() != 0)
{
- JITDUMP("getMaxIntrinsicSIMDVectorLength: returning 32\n");
+ if (GetJitTls() != nullptr && JitTls::GetCompiler() != nullptr)
+ {
+ JITDUMP("getMaxIntrinsicSIMDVectorLength: returning 32\n");
+ }
return 32;
}
}
#endif // FEATURE_AVX_SUPPORT
- JITDUMP("getMaxIntrinsicSIMDVectorLength: returning 16\n");
+ if (GetJitTls() != nullptr && JitTls::GetCompiler() != nullptr)
+ {
+ JITDUMP("getMaxIntrinsicSIMDVectorLength: returning 16\n");
+ }
return 16;
#endif // _TARGET_XARCH_
#else // !FEATURE_SIMD
- JITDUMP("getMaxIntrinsicSIMDVectorLength: returning 0\n");
+ if (GetJitTls() != nullptr && JitTls::GetCompiler() != nullptr)
+ {
+ JITDUMP("getMaxIntrinsicSIMDVectorLength: returning 0\n");
+ }
return 0;
#endif // !FEATURE_SIMD
}
@@ -1235,146 +1224,6 @@ void Compiler::eeGetSystemVAmd64PassStructInRegisterDescriptor(
#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
-#if COR_JIT_EE_VERSION <= 460
-
-// Validate the token to determine whether to turn the bad image format exception into
-// verification failure (for backward compatibility)
-static bool isValidTokenForTryResolveToken(ICorJitInfo* corInfo, CORINFO_RESOLVED_TOKEN* resolvedToken)
-{
- if (!corInfo->isValidToken(resolvedToken->tokenScope, resolvedToken->token))
- return false;
-
- CorInfoTokenKind tokenType = resolvedToken->tokenType;
- switch (TypeFromToken(resolvedToken->token))
- {
- case mdtModuleRef:
- case mdtTypeDef:
- case mdtTypeRef:
- case mdtTypeSpec:
- if ((tokenType & CORINFO_TOKENKIND_Class) == 0)
- return false;
- break;
-
- case mdtMethodDef:
- case mdtMethodSpec:
- if ((tokenType & CORINFO_TOKENKIND_Method) == 0)
- return false;
- break;
-
- case mdtFieldDef:
- if ((tokenType & CORINFO_TOKENKIND_Field) == 0)
- return false;
- break;
-
- case mdtMemberRef:
- if ((tokenType & (CORINFO_TOKENKIND_Method | CORINFO_TOKENKIND_Field)) == 0)
- return false;
- break;
-
- default:
- return false;
- }
-
- return true;
-}
-
-// This type encapsulates the information necessary for `TryResolveTokenFilter` and
-// `eeTryResolveToken` below.
-struct TryResolveTokenFilterParam
-{
- ICorJitInfo* m_corInfo;
- CORINFO_RESOLVED_TOKEN* m_resolvedToken;
- EXCEPTION_POINTERS m_exceptionPointers;
- bool m_success;
-};
-
-LONG TryResolveTokenFilter(struct _EXCEPTION_POINTERS* exceptionPointers, void* theParam)
-{
- assert(exceptionPointers->ExceptionRecord->ExceptionCode != SEH_VERIFICATION_EXCEPTION);
-
- // Backward compatibility: Convert bad image format exceptions thrown by the EE while resolving token to
- // verification exceptions if we are verifying. Verification exceptions will cause the JIT of the basic block to
- // fail, but the JITing of the whole method is still going to succeed. This is done for backward compatibility only.
- // Ideally, we would always treat bad tokens in the IL stream as fatal errors.
- if (exceptionPointers->ExceptionRecord->ExceptionCode == EXCEPTION_COMPLUS)
- {
- auto* param = reinterpret_cast<TryResolveTokenFilterParam*>(theParam);
- if (!isValidTokenForTryResolveToken(param->m_corInfo, param->m_resolvedToken))
- {
- param->m_exceptionPointers = *exceptionPointers;
- return param->m_corInfo->FilterException(exceptionPointers);
- }
- }
-
- return EXCEPTION_CONTINUE_SEARCH;
-}
-
-bool Compiler::eeTryResolveToken(CORINFO_RESOLVED_TOKEN* resolvedToken)
-{
- TryResolveTokenFilterParam param;
- param.m_corInfo = info.compCompHnd;
- param.m_resolvedToken = resolvedToken;
- param.m_success = true;
-
- PAL_TRY(TryResolveTokenFilterParam*, pParam, &param)
- {
- pParam->m_corInfo->resolveToken(pParam->m_resolvedToken);
- }
- PAL_EXCEPT_FILTER(TryResolveTokenFilter)
- {
- if (param.m_exceptionPointers.ExceptionRecord->ExceptionCode == EXCEPTION_COMPLUS)
- {
- param.m_corInfo->HandleException(&param.m_exceptionPointers);
- }
-
- param.m_success = false;
- }
- PAL_ENDTRY
-
- return param.m_success;
-}
-
-struct TrapParam
-{
- ICorJitInfo* m_corInfo;
- EXCEPTION_POINTERS m_exceptionPointers;
-
- void (*m_function)(void*);
- void* m_param;
- bool m_success;
-};
-
-static LONG __EEFilter(PEXCEPTION_POINTERS exceptionPointers, void* param)
-{
- auto* trapParam = reinterpret_cast<TrapParam*>(param);
- trapParam->m_exceptionPointers = *exceptionPointers;
- return trapParam->m_corInfo->FilterException(exceptionPointers);
-}
-
-bool Compiler::eeRunWithErrorTrapImp(void (*function)(void*), void* param)
-{
- TrapParam trapParam;
- trapParam.m_corInfo = info.compCompHnd;
- trapParam.m_function = function;
- trapParam.m_param = param;
- trapParam.m_success = true;
-
- PAL_TRY(TrapParam*, __trapParam, &trapParam)
- {
- __trapParam->m_function(__trapParam->m_param);
- }
- PAL_EXCEPT_FILTER(__EEFilter)
- {
- trapParam.m_corInfo->HandleException(&trapParam.m_exceptionPointers);
- trapParam.m_success = false;
- }
- PAL_ENDTRY
-
- return trapParam.m_success;
-}
-
-#else // CORJIT_EE_VER <= 460
-
bool Compiler::eeTryResolveToken(CORINFO_RESOLVED_TOKEN* resolvedToken)
{
return info.compCompHnd->tryResolveToken(resolvedToken);
@@ -1385,8 +1234,6 @@ bool Compiler::eeRunWithErrorTrapImp(void (*function)(void*), void* param)
return info.compCompHnd->runWithErrorTrap(function, param);
}
-#endif // CORJIT_EE_VER > 460
-
/*****************************************************************************
*
* Utility functions
diff --git a/src/jit/ee_il_dll.hpp b/src/jit/ee_il_dll.hpp
index 3899d92192..0565d6f561 100644
--- a/src/jit/ee_il_dll.hpp
+++ b/src/jit/ee_il_dll.hpp
@@ -21,11 +21,7 @@ class CILJit : public ICorJitCompiler
void getVersionIdentifier(GUID* versionIdentifier /* OUT */
);
-#if COR_JIT_EE_VERSION > 460
unsigned getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags);
-#else
- unsigned getMaxIntrinsicSIMDVectorLength(DWORD cpuCompileFlags);
-#endif
void setRealJit(ICorJitCompiler* realJitCompiler);
};
diff --git a/src/jit/emit.cpp b/src/jit/emit.cpp
index 1e566b2e76..3b765b9db2 100644
--- a/src/jit/emit.cpp
+++ b/src/jit/emit.cpp
@@ -1027,7 +1027,7 @@ void emitter::emitBegFN(bool hasFramePtr
emitPlaceholderList = emitPlaceholderLast = nullptr;
#ifdef JIT32_GCENCODER
- emitEpilogList = emitEpilogLast = NULL;
+ emitEpilogList = emitEpilogLast = nullptr;
#endif // JIT32_GCENCODER
/* We don't have any jumps */
@@ -1215,14 +1215,12 @@ size_t emitter::emitGenEpilogLst(size_t (*fp)(void*, unsigned), void* cp)
EpilogList* el;
size_t sz;
- for (el = emitEpilogList, sz = 0; el; el = el->elNext)
+ for (el = emitEpilogList, sz = 0; el != nullptr; el = el->elNext)
{
- assert(el->elIG->igFlags & IGF_EPILOG);
+ assert(el->elLoc.GetIG()->igFlags & IGF_EPILOG);
- UNATIVE_OFFSET ofs =
- el->elIG->igOffs; // The epilog starts at the beginning of the IG, so the IG offset is correct
-
- sz += fp(cp, ofs);
+ // The epilog starts at the location recorded in the epilog list.
+ sz += fp(cp, el->elLoc.CodeOffset(this));
}
return sz;
@@ -1383,7 +1381,6 @@ void* emitter::emitAllocInstr(size_t sz, emitAttr opsz)
id->idOpSize(EA_SIZE(opsz));
}
-#if RELOC_SUPPORT
// Amd64: ip-relative addressing is supported even when not generating relocatable ngen code
if (EA_IS_DSP_RELOC(opsz)
#ifndef _TARGET_AMD64_
@@ -1402,7 +1399,6 @@ void* emitter::emitAllocInstr(size_t sz, emitAttr opsz)
/* instruction has an immediate constant that is relocatable */
id->idSetIsCnsReloc();
}
-#endif
#if EMITTER_STATS
emitTotalInsCnt++;
@@ -1957,22 +1953,20 @@ void emitter::emitBegFnEpilog(insGroup* igPh)
#ifdef JIT32_GCENCODER
- EpilogList* el = new (emitComp, CMK_GC) EpilogList;
- el->elNext = NULL;
- el->elIG = emitCurIG;
+ EpilogList* el = new (emitComp, CMK_GC) EpilogList();
- if (emitEpilogLast)
+ if (emitEpilogLast != nullptr)
+ {
emitEpilogLast->elNext = el;
+ }
else
+ {
emitEpilogList = el;
+ }
emitEpilogLast = el;
#endif // JIT32_GCENCODER
-
- /* Remember current position so that we can compute total epilog size */
-
- emitEpilogBegLoc.CaptureLocation(this);
}
/*****************************************************************************
@@ -1984,22 +1978,17 @@ void emitter::emitEndFnEpilog()
{
emitEndPrologEpilog();
- UNATIVE_OFFSET newSize;
- UNATIVE_OFFSET epilogBegCodeOffset = emitEpilogBegLoc.CodeOffset(this);
-#ifdef _TARGET_XARCH_
- UNATIVE_OFFSET epilogExitSeqStartCodeOffset = emitExitSeqBegLoc.CodeOffset(this);
-#else
- UNATIVE_OFFSET epilogExitSeqStartCodeOffset = emitCodeOffset(emitCurIG, emitCurOffset());
-#endif
-
- newSize = epilogExitSeqStartCodeOffset - epilogBegCodeOffset;
+#ifdef JIT32_GCENCODER
+ assert(emitEpilogLast != nullptr);
-#ifdef _TARGET_X86_
+ UNATIVE_OFFSET epilogBegCodeOffset = emitEpilogLast->elLoc.CodeOffset(this);
+ UNATIVE_OFFSET epilogExitSeqStartCodeOffset = emitExitSeqBegLoc.CodeOffset(this);
+ UNATIVE_OFFSET newSize = epilogExitSeqStartCodeOffset - epilogBegCodeOffset;
/* Compute total epilog size */
-
assert(emitEpilogSize == 0 || emitEpilogSize == newSize); // All epilogs must be identical
- emitEpilogSize = newSize;
+ emitEpilogSize = newSize;
+
UNATIVE_OFFSET epilogEndCodeOffset = emitCodeOffset(emitCurIG, emitCurOffset());
assert(epilogExitSeqStartCodeOffset != epilogEndCodeOffset);
@@ -2019,8 +2008,7 @@ void emitter::emitEndFnEpilog()
);
emitExitSeqSize = newSize;
}
-
-#endif // _TARGET_X86_
+#endif // JIT32_GCENCODER
}
#if FEATURE_EH_FUNCLETS
@@ -2069,6 +2057,16 @@ void emitter::emitEndFuncletEpilog()
#ifdef JIT32_GCENCODER
+//
+// emitter::emitStartEpilog:
+// Mark the current position so that we can later compute the total epilog size.
+//
+void emitter::emitStartEpilog()
+{
+ assert(emitEpilogLast != nullptr);
+ emitEpilogLast->elLoc.CaptureLocation(this);
+}
+
/*****************************************************************************
*
* Return non-zero if the current method only has one epilog, which is
@@ -4233,7 +4231,7 @@ void emitter::emitCheckFuncletBranch(instrDesc* jmp, insGroup* jmpIG)
// meets one of those criteria...
assert(jmp->idIsBound());
-#ifdef _TARGET_AMD64_
+#ifdef _TARGET_XARCH_
// An lea of a code address (for constant data stored with the code)
// is treated like a jump for emission purposes but is not really a jump so
// we don't have to check anything here.
@@ -4405,6 +4403,12 @@ unsigned emitter::emitEndCodeGen(Compiler* comp,
emitFullyInt = fullyInt;
emitFullGCinfo = fullPtrMap;
+#ifndef UNIX_X86_ABI
+ emitFullArgInfo = !emitHasFramePtr;
+#else
+ emitFullArgInfo = fullPtrMap;
+#endif
+
#if EMITTER_STATS
GCrefsTable.record(emitGCrFrameOffsCnt);
emitSizeTable.record(static_cast<unsigned>(emitSizeMethod));
@@ -4419,7 +4423,10 @@ unsigned emitter::emitEndCodeGen(Compiler* comp,
#if EMIT_TRACK_STACK_DEPTH
/* Convert max. stack depth from # of bytes to # of entries */
- emitMaxStackDepth /= sizeof(int);
+ unsigned maxStackDepthIn4ByteElements = emitMaxStackDepth / sizeof(int);
+ JITDUMP("Converting emitMaxStackDepth from bytes (%d) to elements (%d)\n", emitMaxStackDepth,
+ maxStackDepthIn4ByteElements);
+ emitMaxStackDepth = maxStackDepthIn4ByteElements;
/* Should we use the simple stack */
@@ -4499,7 +4506,7 @@ unsigned emitter::emitEndCodeGen(Compiler* comp,
//
if (emitComp->fgHaveProfileData())
{
- if (emitComp->fgCalledWeight > (BB_VERY_HOT_WEIGHT * emitComp->fgNumProfileRuns))
+ if (emitComp->fgCalledCount > (BB_VERY_HOT_WEIGHT * emitComp->fgProfileRunsCount()))
{
allocMemFlag = CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN;
}
@@ -6814,7 +6821,7 @@ void emitter::emitStackPushLargeStk(BYTE* addr, GCtype gcType, unsigned count)
*u2.emitArgTrackTop++ = (BYTE)gcType;
assert(u2.emitArgTrackTop <= u2.emitArgTrackTab + emitMaxStackDepth);
- if (!emitHasFramePtr || needsGC(gcType))
+ if (emitFullArgInfo || needsGC(gcType))
{
if (emitFullGCinfo)
{
@@ -6886,7 +6893,7 @@ void emitter::emitStackPopLargeStk(BYTE* addr, bool isCall, unsigned char callIn
// This is an "interesting" argument
- if (!emitHasFramePtr || needsGC(gcType))
+ if (emitFullArgInfo || needsGC(gcType))
{
argRecCnt += 1;
}
@@ -7034,7 +7041,7 @@ void emitter::emitStackKillArgs(BYTE* addr, unsigned count, unsigned char callIn
/* We're about to kill the corresponding (pointer) arg records */
- if (emitHasFramePtr)
+ if (!emitFullArgInfo)
{
u2.emitGcArgTrackCnt -= gcCnt.Value();
}
diff --git a/src/jit/emit.h b/src/jit/emit.h
index f57cc0a0f7..e1c924f467 100644
--- a/src/jit/emit.h
+++ b/src/jit/emit.h
@@ -738,21 +738,13 @@ protected:
// arm64: 48 bits
CLANG_FORMAT_COMMENT_ANCHOR;
-#ifdef RELOC_SUPPORT
-
unsigned _idCnsReloc : 1; // LargeCns is an RVA and needs reloc tag
unsigned _idDspReloc : 1; // LargeDsp is an RVA and needs reloc tag
#define ID_EXTRA_RELOC_BITS (2)
-#else // RELOC_SUPPORT
-
-#define ID_EXTRA_RELOC_BITS (0)
-
-#endif // RELOC_SUPPORT
-
////////////////////////////////////////////////////////////////////////
- // Space taken up to here (assuming RELOC_SUPPORT):
+ // Space taken up to here:
// x86: 40 bits
// amd64: 48 bits
// arm: 50 bits
@@ -768,7 +760,7 @@ protected:
#define ID_MAX_SMALL_CNS (int)((1 << ID_BIT_SMALL_CNS) - 1U)
////////////////////////////////////////////////////////////////////////
- // Small constant size (assuming RELOC_SUPPORT):
+ // Small constant size:
// x86: 24 bits
// amd64: 16 bits
// arm: 14 bits
@@ -777,7 +769,7 @@ protected:
unsigned _idSmallCns : ID_BIT_SMALL_CNS;
////////////////////////////////////////////////////////////////////////
- // Space taken up to here (with RELOC_SUPPORT): 64 bits, all architectures, by design.
+ // Space taken up to here: 64 bits, all architectures, by design.
////////////////////////////////////////////////////////////////////////
CLANG_FORMAT_COMMENT_ANCHOR;
@@ -829,23 +821,13 @@ protected:
#define ID_EXTRA_BITFIELD_BITS (7)
-//
-// For x86, we are using 7 bits from the second DWORD for bitfields.
-//
-
-#ifdef RELOC_SUPPORT
+ //
+ // For x86, we are using 7 bits from the second DWORD for bitfields.
+ //
unsigned _idCnsReloc : 1; // LargeCns is an RVA and needs reloc tag
unsigned _idDspReloc : 1; // LargeDsp is an RVA and needs reloc tag
-#define ID_EXTRA_RELOC_BITS (2)
-
-#else // RELOC_SUPPORT
-
-#define ID_EXTRA_RELOC_BITS (0)
-
-#endif // RELOC_SUPPORT
-
#define ID_EXTRA_REG_BITS (0)
#define ID_EXTRA_BITS (ID_EXTRA_BITFIELD_BITS + ID_EXTRA_RELOC_BITS + ID_EXTRA_REG_BITS)
@@ -856,7 +838,7 @@ protected:
#define ID_MIN_SMALL_CNS 0
#define ID_MAX_SMALL_CNS (int)((1 << ID_BIT_SMALL_CNS) - 1U)
- // For x86 (assuming RELOC_SUPPORT) we have 23 bits remaining for the
+ // For x86 we have 23 bits remaining for the
// small constant in this extra DWORD.
unsigned _idSmallCns : ID_BIT_SMALL_CNS;
@@ -1283,8 +1265,6 @@ protected:
}
#endif // defined(_TARGET_ARM_)
-#ifdef RELOC_SUPPORT
-
bool idIsCnsReloc() const
{
assert(!idIsTiny());
@@ -1311,8 +1291,6 @@ protected:
return idIsDspReloc() || idIsCnsReloc();
}
-#endif
-
unsigned idSmallCns() const
{
assert(!idIsTiny());
@@ -1518,14 +1496,20 @@ protected:
// IG of the epilog, and use it to find the epilog offset at the end of code generation.
struct EpilogList
{
- EpilogList* elNext;
- insGroup* elIG;
+ EpilogList* elNext;
+ emitLocation elLoc;
+
+ EpilogList() : elNext(nullptr), elLoc()
+ {
+ }
};
EpilogList* emitEpilogList; // per method epilog list - head
EpilogList* emitEpilogLast; // per method epilog list - tail
public:
+ void emitStartEpilog();
+
bool emitHasEpilogEnd();
size_t emitGenEpilogLst(size_t (*fp)(void*, unsigned), void* cp);
@@ -1535,8 +1519,6 @@ public:
void emitBegPrologEpilog(insGroup* igPh);
void emitEndPrologEpilog();
- emitLocation emitEpilogBegLoc;
-
void emitBegFnEpilog(insGroup* igPh);
void emitEndFnEpilog();
@@ -2036,8 +2018,9 @@ public:
/* The following logic keeps track of live GC ref values */
/************************************************************************/
- bool emitFullGCinfo; // full GC pointer maps?
- bool emitFullyInt; // fully interruptible code?
+ bool emitFullArgInfo; // full arg info (including non-ptr arg)?
+ bool emitFullGCinfo; // full GC pointer maps?
+ bool emitFullyInt; // fully interruptible code?
#if EMIT_TRACK_STACK_DEPTH
unsigned emitCntStackDepth; // 0 in prolog/epilog, One DWORD elsewhere
diff --git a/src/jit/emitarm.cpp b/src/jit/emitarm.cpp
index 1b3ef1bdc7..53ee88b3a2 100644
--- a/src/jit/emitarm.cpp
+++ b/src/jit/emitarm.cpp
@@ -1380,7 +1380,7 @@ DONE:
/*****************************************************************************
*
- * emitIns_valid_imm_for_add() returns true when the immediate 'imm'
+ * emitins_valid_imm_for_add() returns true when the immediate 'imm'
* can be encoded using a single add or sub instruction.
*/
/*static*/ bool emitter::emitIns_valid_imm_for_add(int imm, insFlags flags)
@@ -1396,6 +1396,20 @@ DONE:
/*****************************************************************************
*
+ * emitins_valid_imm_for_cmp() returns true if this 'imm'
+ * can be encoded as a input operand to an cmp instruction.
+ */
+/*static*/ bool emitter::emitIns_valid_imm_for_cmp(int imm, insFlags flags)
+{
+ if (isModImmConst(imm)) // funky arm immediate
+ return true;
+ if (isModImmConst(-imm)) // funky arm immediate via sub
+ return true;
+ return false;
+}
+
+/*****************************************************************************
+ *
* emitIns_valid_imm_for_add_sp() returns true when the immediate 'imm'
* can be encoded in "add Rd,SP,i10".
*/
@@ -1408,6 +1422,20 @@ DONE:
/*****************************************************************************
*
+ * emitIns_valid_imm_for_ldst_offset() returns true when the immediate 'imm'
+ * can be encoded as the offset in a ldr/str instruction.
+ */
+/*static*/ bool emitter::emitIns_valid_imm_for_ldst_offset(int imm, emitAttr size)
+{
+ if ((imm & 0x0fff) == imm)
+ return true; // encodable using IF_T2_K1
+ if (unsigned_abs(imm) <= 0x0ff)
+ return true; // encodable using IF_T2_H0
+ return false;
+}
+
+/*****************************************************************************
+ *
* Add an instruction with no operands.
*/
@@ -4289,14 +4317,12 @@ void emitter::emitIns_R_D(instruction ins, emitAttr attr, unsigned offs, regNumb
id->idInsFmt(fmt);
id->idInsSize(isz);
-#if RELOC_SUPPORT
if (emitComp->opts.compReloc)
{
// Set the relocation flags - these give hint to zap to perform
// relocation of the specified 32bit address.
id->idSetRelocFlags(attr);
}
-#endif // RELOC_SUPPORT
dispIns(id);
appendToCurIG(id);
@@ -4579,7 +4605,6 @@ void emitter::emitIns_Call(EmitCallType callType,
id->idSetIsCallAddr();
}
-#if RELOC_SUPPORT
if (emitComp->opts.compReloc)
{
// Since this is an indirect call through a pointer and we don't
@@ -4588,7 +4613,6 @@ void emitter::emitIns_Call(EmitCallType callType,
id->idSetIsDspReloc();
}
-#endif
}
#ifdef DEBUG
@@ -5254,7 +5278,6 @@ BYTE* emitter::emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i)
else if (fmt == IF_T2_J2)
{
assert((distVal & 1) == 0);
-#ifdef RELOC_SUPPORT
if (emitComp->opts.compReloc && emitJumpCrossHotColdBoundary(srcOffs, dstOffs))
{
// dst isn't an actual final target location, just some intermediate
@@ -5263,7 +5286,6 @@ BYTE* emitter::emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i)
// rely on the relocation to do all the work
}
else
-#endif
{
assert(distVal >= CALL_DIST_MAX_NEG);
assert(distVal <= CALL_DIST_MAX_POS);
@@ -5290,7 +5312,6 @@ BYTE* emitter::emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i)
unsigned instrSize = emitOutput_Thumb2Instr(dst, code);
-#ifdef RELOC_SUPPORT
if (emitComp->opts.compReloc)
{
if (emitJumpCrossHotColdBoundary(srcOffs, dstOffs))
@@ -5303,7 +5324,6 @@ BYTE* emitter::emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i)
}
}
}
-#endif // RELOC_SUPPORT
dst += instrSize;
}
@@ -5968,9 +5988,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
assert(!id->idIsLclVar());
assert((ins == INS_movw) || (ins == INS_movt));
imm += (size_t)emitConsBlock;
-#ifdef RELOC_SUPPORT
if (!id->idIsCnsReloc() && !id->idIsDspReloc())
-#endif
{
goto SPLIT_IMM;
}
@@ -5988,7 +6006,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
}
}
-#ifdef RELOC_SUPPORT
if (id->idIsCnsReloc() || id->idIsDspReloc())
{
assert((ins == INS_movt) || (ins == INS_movw));
@@ -5997,7 +6014,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
emitRecordRelocation((void*)(dst - 8), (void*)imm, IMAGE_REL_BASED_THUMB_MOV32);
}
else
-#endif // RELOC_SUPPORT
{
assert((imm & 0x0000ffff) == imm);
code |= (imm & 0x00ff);
@@ -6220,7 +6236,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
}
code = emitInsCode(ins, fmt);
-#ifdef RELOC_SUPPORT
if (id->idIsDspReloc())
{
callInstrSize = SafeCvtAssert<unsigned char>(emitOutput_Thumb2Instr(dst, code));
@@ -6229,7 +6244,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
emitRecordRelocation((void*)(dst - 4), addr, IMAGE_REL_BASED_THUMB_BRANCH24);
}
else
-#endif // RELOC_SUPPORT
{
addr = (BYTE*)((size_t)addr & ~1); // Clear the lowest bit from target address
@@ -6935,14 +6949,12 @@ void emitter::emitDispInsHelp(
{
if (emitComp->opts.disDiffable)
imm = 0xD1FF;
-#if RELOC_SUPPORT
if (id->idIsCnsReloc() || id->idIsDspReloc())
{
if (emitComp->opts.disDiffable)
imm = 0xD1FFAB1E;
printf("%s RELOC ", (id->idIns() == INS_movw) ? "LOW" : "HIGH");
}
-#endif // RELOC_SUPPORT
}
emitDispImm(imm, false, (fmt == IF_T2_N));
break;
@@ -6973,12 +6985,10 @@ void emitter::emitDispInsHelp(
assert(jdsc != NULL);
-#ifdef RELOC_SUPPORT
if (id->idIsDspReloc())
{
printf("reloc ");
}
-#endif
printf("%s ADDRESS J_M%03u_DS%02u", (id->idIns() == INS_movw) ? "LOW" : "HIGH",
Compiler::s_compMethodsCount, imm);
@@ -7528,89 +7538,115 @@ void emitter::emitDispFrameRef(int varx, int disp, int offs, bool asmfm)
#ifndef LEGACY_BACKEND
-// this is very similar to emitInsBinary and probably could be folded in to same
-// except the requirements on the incoming parameter are different,
-// ex: the memory op in storeind case must NOT be contained
-void emitter::emitInsMov(instruction ins, emitAttr attr, GenTree* node)
+void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataReg, GenTreeIndir* indir)
{
- switch (node->OperGet())
+ GenTree* addr = indir->Addr();
+ GenTree* data = indir->gtOp.gtOp2;
+
+ if (addr->isContained())
{
- case GT_IND:
- case GT_STOREIND:
- {
- GenTreeIndir* indir = node->AsIndir();
- GenTree* addr = indir->Addr();
- GenTree* data = indir->gtOp.gtOp2;
+ assert(addr->OperGet() == GT_LCL_VAR_ADDR || addr->OperGet() == GT_LEA);
- regNumber reg = (node->OperGet() == GT_IND) ? node->gtRegNum : data->gtRegNum;
+ int offset = 0;
+ DWORD lsl = 0;
- if (addr->isContained())
+ if (addr->OperGet() == GT_LEA)
+ {
+ offset = (int)addr->AsAddrMode()->gtOffset;
+ if (addr->AsAddrMode()->gtScale > 0)
{
- assert(addr->OperGet() == GT_LCL_VAR_ADDR || addr->OperGet() == GT_LEA);
+ assert(isPow2(addr->AsAddrMode()->gtScale));
+ BitScanForward(&lsl, addr->AsAddrMode()->gtScale);
+ }
+ }
+
+ GenTree* memBase = indir->Base();
+
+ if (indir->HasIndex())
+ {
+ GenTree* index = indir->Index();
- int offset = 0;
- DWORD lsl = 0;
+ if (offset != 0)
+ {
+ regMaskTP tmpRegMask = indir->gtRsvdRegs;
+ regNumber tmpReg = genRegNumFromMask(tmpRegMask);
+ noway_assert(tmpReg != REG_NA);
- if (addr->OperGet() == GT_LEA)
+ if (emitIns_valid_imm_for_add(offset, INS_FLAGS_DONT_CARE))
{
- offset = (int)addr->AsAddrMode()->gtOffset;
- if (addr->AsAddrMode()->gtScale > 0)
+ if (lsl > 0)
{
- assert(isPow2(addr->AsAddrMode()->gtScale));
- BitScanForward(&lsl, addr->AsAddrMode()->gtScale);
+ // Generate code to set tmpReg = base + index*scale
+ emitIns_R_R_R_I(INS_add, EA_PTRSIZE, tmpReg, memBase->gtRegNum, index->gtRegNum, lsl,
+ INS_FLAGS_DONT_CARE, INS_OPTS_LSL);
+ }
+ else // no scale
+ {
+ // Generate code to set tmpReg = base + index
+ emitIns_R_R_R(INS_add, EA_PTRSIZE, tmpReg, memBase->gtRegNum, index->gtRegNum);
}
- }
- GenTree* memBase = indir->Base();
+ noway_assert(emitInsIsLoad(ins) || (tmpReg != dataReg));
- if (indir->HasIndex())
- {
- NYI_ARM("emitInsMov HasIndex");
+ // Then load/store dataReg from/to [tmpReg + offset]
+ emitIns_R_R_I(ins, attr, dataReg, tmpReg, offset);
}
- else
+ else // large offset
{
- // TODO check offset is valid for encoding
- emitIns_R_R_I(ins, attr, reg, memBase->gtRegNum, offset);
+ // First load/store tmpReg with the large offset constant
+ codeGen->instGen_Set_Reg_To_Imm(EA_PTRSIZE, tmpReg, offset);
+ // Then add the base register
+ // rd = rd + base
+ emitIns_R_R_R(INS_add, EA_PTRSIZE, tmpReg, tmpReg, memBase->gtRegNum);
+
+ noway_assert(emitInsIsLoad(ins) || (tmpReg != dataReg));
+ noway_assert(tmpReg != index->gtRegNum);
+
+ // Then load/store dataReg from/to [tmpReg + index*scale]
+ emitIns_R_R_R_I(ins, attr, dataReg, tmpReg, index->gtRegNum, lsl, INS_FLAGS_DONT_CARE,
+ INS_OPTS_LSL);
}
}
- else
+ else // (offset == 0)
{
- if (addr->OperGet() == GT_CLS_VAR_ADDR)
+ if (lsl > 0)
{
- emitIns_C_R(ins, attr, addr->gtClsVar.gtClsVarHnd, data->gtRegNum, 0);
+ // Then load/store dataReg from/to [memBase + index*scale]
+ emitIns_R_R_R_I(ins, attr, dataReg, memBase->gtRegNum, index->gtRegNum, lsl, INS_FLAGS_DONT_CARE,
+ INS_OPTS_LSL);
}
- else
+ else // no scale
{
- emitIns_R_R(ins, attr, reg, addr->gtRegNum);
+ // Then load/store dataReg from/to [memBase + index]
+ emitIns_R_R_R(ins, attr, dataReg, memBase->gtRegNum, index->gtRegNum);
}
}
}
- break;
-
- case GT_STORE_LCL_VAR:
+ else // no Index
{
- GenTreeLclVarCommon* varNode = node->AsLclVarCommon();
-
- GenTree* data = node->gtOp.gtOp1->gtEffectiveVal();
- codeGen->inst_set_SV_var(varNode);
- assert(varNode->gtRegNum == REG_NA); // stack store
-
- if (data->isContainedIntOrIImmed())
+ if (emitIns_valid_imm_for_ldst_offset(offset, attr))
{
- emitIns_S_I(ins, attr, varNode->GetLclNum(), 0, (int)data->AsIntConCommon()->IconValue());
- codeGen->genUpdateLife(varNode);
+ // Then load/store dataReg from/to [memBase + offset]
+ emitIns_R_R_I(ins, attr, dataReg, memBase->gtRegNum, offset);
}
else
{
- assert(!data->isContained());
- emitIns_S_R(ins, attr, data->gtRegNum, varNode->GetLclNum(), 0);
- codeGen->genUpdateLife(varNode);
+ // We require a tmpReg to hold the offset
+ regMaskTP tmpRegMask = indir->gtRsvdRegs;
+ regNumber tmpReg = genRegNumFromMask(tmpRegMask);
+ noway_assert(tmpReg != REG_NA);
+
+ // First load/store tmpReg with the large offset constant
+ codeGen->instGen_Set_Reg_To_Imm(EA_PTRSIZE, tmpReg, offset);
+
+ // Then load/store dataReg from/to [memBase + tmpReg]
+ emitIns_R_R_R(ins, attr, dataReg, memBase->gtRegNum, tmpReg);
}
}
- return;
-
- default:
- unreached();
+ }
+ else
+ {
+ emitIns_R_R(ins, attr, dataReg, addr->gtRegNum);
}
}
@@ -7646,5 +7682,174 @@ regNumber emitter::emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, G
}
}
+regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, GenTree* src1, GenTree* src2)
+{
+ regNumber result = REG_NA;
+
+ // dst can only be a reg
+ assert(!dst->isContained());
+
+ // find immed (if any) - it cannot be a dst
+ // Only one src can be an int.
+ GenTreeIntConCommon* intConst = nullptr;
+ GenTree* nonIntReg = nullptr;
+
+ if (varTypeIsFloating(dst))
+ {
+ // src1 can only be a reg
+ assert(!src1->isContained());
+ // src2 can only be a reg
+ assert(!src2->isContained());
+ }
+ else // not floating point
+ {
+ // src2 can be immed or reg
+ assert(!src2->isContained() || src2->isContainedIntOrIImmed());
+
+ // Check src2 first as we can always allow it to be a contained immediate
+ if (src2->isContainedIntOrIImmed())
+ {
+ intConst = src2->AsIntConCommon();
+ nonIntReg = src1;
+ }
+ // Only for commutative operations do we check src1 and allow it to be a contained immediate
+ else if (dst->OperIsCommutative())
+ {
+ // src1 can be immed or reg
+ assert(!src1->isContained() || src1->isContainedIntOrIImmed());
+
+ // Check src1 and allow it to be a contained immediate
+ if (src1->isContainedIntOrIImmed())
+ {
+ assert(!src2->isContainedIntOrIImmed());
+ intConst = src1->AsIntConCommon();
+ nonIntReg = src2;
+ }
+ }
+ else
+ {
+ // src1 can only be a reg
+ assert(!src1->isContained());
+ }
+ }
+ bool isMulOverflow = false;
+ bool isUnsignedMul = false;
+ regNumber extraReg = REG_NA;
+ if (dst->gtOverflowEx())
+ {
+ NYI_ARM("emitInsTernary overflow");
+#if 0
+ if (ins == INS_add)
+ {
+ ins = INS_adds;
+ }
+ else if (ins == INS_sub)
+ {
+ ins = INS_subs;
+ }
+ else if (ins == INS_mul)
+ {
+ isMulOverflow = true;
+ isUnsignedMul = ((dst->gtFlags & GTF_UNSIGNED) != 0);
+ assert(intConst == nullptr); // overflow format doesn't support an int constant operand
+ }
+ else
+ {
+ assert(!"Invalid ins for overflow check");
+ }
+#endif
+ }
+ if (intConst != nullptr)
+ {
+ emitIns_R_R_I(ins, attr, dst->gtRegNum, nonIntReg->gtRegNum, intConst->IconValue());
+ }
+ else
+ {
+ if (isMulOverflow)
+ {
+ NYI_ARM("emitInsTernary overflow");
+#if 0
+ // Make sure that we have an internal register
+ assert(genCountBits(dst->gtRsvdRegs) == 2);
+
+ // There will be two bits set in tmpRegsMask.
+ // Remove the bit for 'dst->gtRegNum' from 'tmpRegsMask'
+ regMaskTP tmpRegsMask = dst->gtRsvdRegs & ~genRegMask(dst->gtRegNum);
+ assert(tmpRegsMask != RBM_NONE);
+ regMaskTP tmpRegMask = genFindLowestBit(tmpRegsMask); // set tmpRegMsk to a one-bit mask
+ extraReg = genRegNumFromMask(tmpRegMask); // set tmpReg from that mask
+
+ if (isUnsignedMul)
+ {
+ if (attr == EA_4BYTE)
+ {
+ // Compute 8 byte results from 4 byte by 4 byte multiplication.
+ emitIns_R_R_R(INS_umull, EA_8BYTE, dst->gtRegNum, src1->gtRegNum, src2->gtRegNum);
+
+ // Get the high result by shifting dst.
+ emitIns_R_R_I(INS_lsr, EA_8BYTE, extraReg, dst->gtRegNum, 32);
+ }
+ else
+ {
+ assert(attr == EA_8BYTE);
+ // Compute the high result.
+ emitIns_R_R_R(INS_umulh, attr, extraReg, src1->gtRegNum, src2->gtRegNum);
+
+ // Now multiply without skewing the high result.
+ emitIns_R_R_R(ins, attr, dst->gtRegNum, src1->gtRegNum, src2->gtRegNum);
+ }
+
+ // zero-sign bit comparision to detect overflow.
+ emitIns_R_I(INS_cmp, attr, extraReg, 0);
+ }
+ else
+ {
+ int bitShift = 0;
+ if (attr == EA_4BYTE)
+ {
+ // Compute 8 byte results from 4 byte by 4 byte multiplication.
+ emitIns_R_R_R(INS_smull, EA_8BYTE, dst->gtRegNum, src1->gtRegNum, src2->gtRegNum);
+
+ // Get the high result by shifting dst.
+ emitIns_R_R_I(INS_lsr, EA_8BYTE, extraReg, dst->gtRegNum, 32);
+
+ bitShift = 31;
+ }
+ else
+ {
+ assert(attr == EA_8BYTE);
+ // Save the high result in a temporary register.
+ emitIns_R_R_R(INS_smulh, attr, extraReg, src1->gtRegNum, src2->gtRegNum);
+
+ // Now multiply without skewing the high result.
+ emitIns_R_R_R(ins, attr, dst->gtRegNum, src1->gtRegNum, src2->gtRegNum);
+
+ bitShift = 63;
+ }
+
+ // Sign bit comparision to detect overflow.
+ emitIns_R_R_I(INS_cmp, attr, extraReg, dst->gtRegNum, bitShift, INS_OPTS_ASR);
+ }
+#endif
+ }
+ else
+ {
+ // We can just multiply.
+ emitIns_R_R_R(ins, attr, dst->gtRegNum, src1->gtRegNum, src2->gtRegNum);
+ }
+ }
+
+ if (dst->gtOverflowEx())
+ {
+ NYI_ARM("emitInsTernary overflow");
+#if 0
+ assert(!varTypeIsFloating(dst));
+ codeGen->genCheckOverflow(dst);
+#endif
+ }
+
+ return dst->gtRegNum;
+}
+
#endif // !LEGACY_BACKEND
#endif // defined(_TARGET_ARM_)
diff --git a/src/jit/emitarm.h b/src/jit/emitarm.h
index 1440148f42..1e286e8425 100644
--- a/src/jit/emitarm.h
+++ b/src/jit/emitarm.h
@@ -10,10 +10,8 @@
struct CnsVal
{
- int cnsVal;
-#ifdef RELOC_SUPPORT
+ int cnsVal;
bool cnsReloc;
-#endif
};
insSize emitInsSize(insFormat insFmt);
@@ -109,6 +107,10 @@ bool emitInsIsLoad(instruction ins);
bool emitInsIsStore(instruction ins);
bool emitInsIsLoadOrStore(instruction ins);
+// Generate code for a load or store operation and handle the case
+// of contained GT_LEA op1 with [base + index<<scale + offset]
+void emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataReg, GenTreeIndir* indir);
+
/*****************************************************************************
*
* Convert between an index scale in bytes to a smaller encoding used for
@@ -230,6 +232,13 @@ inline static bool insOptsROR(insOpts opt)
return (opt == INS_OPTS_ROR);
}
+// Returns the number of bits used by the given 'size'.
+inline static unsigned getBitWidth(emitAttr size)
+{
+ assert(size <= EA_8BYTE);
+ return (unsigned)size * BITS_PER_BYTE;
+}
+
/************************************************************************/
/* The public entry points to output instructions */
/************************************************************************/
@@ -239,7 +248,9 @@ static bool emitIns_valid_imm_for_alu(int imm);
static bool emitIns_valid_imm_for_mov(int imm);
static bool emitIns_valid_imm_for_small_mov(regNumber reg, int imm, insFlags flags);
static bool emitIns_valid_imm_for_add(int imm, insFlags flags);
+static bool emitIns_valid_imm_for_cmp(int imm, insFlags flags);
static bool emitIns_valid_imm_for_add_sp(int imm);
+static bool emitIns_valid_imm_for_ldst_offset(int imm, emitAttr size);
void emitIns(instruction ins);
diff --git a/src/jit/emitarm64.cpp b/src/jit/emitarm64.cpp
index dd4bac808a..93994e7918 100644
--- a/src/jit/emitarm64.cpp
+++ b/src/jit/emitarm64.cpp
@@ -6697,12 +6697,8 @@ void emitter::emitIns_Call(EmitCallType callType,
{
assert(emitNoGChelper(Compiler::eeGetHelperNum(methHnd)));
- // This call will preserve the liveness of most registers
- //
- // - On the ARM64 the NOGC helpers will preserve all registers,
- // except for those listed in the RBM_CALLEE_TRASH_NOGC mask
-
- savedSet = RBM_ALLINT & ~RBM_CALLEE_TRASH_NOGC;
+ // Get the set of registers that this call kills and remove it from the saved set.
+ savedSet = RBM_ALLINT & ~emitComp->compNoGCHelperCallKillSet(Compiler::eeGetHelperNum(methHnd));
// In case of Leave profiler callback, we need to preserve liveness of REG_PROFILER_RET_SCRATCH
if (isProfLeaveCB)
@@ -6842,12 +6838,10 @@ void emitter::emitIns_Call(EmitCallType callType,
id->idSetIsCallAddr();
}
-#if RELOC_SUPPORT
if (emitComp->opts.compReloc)
{
id->idSetIsDspReloc();
}
-#endif
}
#ifdef DEBUG
@@ -10819,18 +10813,20 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR
regNumber tmpReg = genRegNumFromMask(tmpRegMask);
noway_assert(tmpReg != REG_NA);
+ emitAttr addType = varTypeIsGC(memBase) ? EA_BYREF : EA_PTRSIZE;
+
if (emitIns_valid_imm_for_add(offset, EA_8BYTE))
{
if (lsl > 0)
{
// Generate code to set tmpReg = base + index*scale
- emitIns_R_R_R_I(INS_add, EA_PTRSIZE, tmpReg, memBase->gtRegNum, index->gtRegNum, lsl,
+ emitIns_R_R_R_I(INS_add, addType, tmpReg, memBase->gtRegNum, index->gtRegNum, lsl,
INS_OPTS_LSL);
}
else // no scale
{
// Generate code to set tmpReg = base + index
- emitIns_R_R_R(INS_add, EA_PTRSIZE, tmpReg, memBase->gtRegNum, index->gtRegNum);
+ emitIns_R_R_R(INS_add, addType, tmpReg, memBase->gtRegNum, index->gtRegNum);
}
noway_assert(emitInsIsLoad(ins) || (tmpReg != dataReg));
@@ -10845,7 +10841,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR
codeGen->instGen_Set_Reg_To_Imm(EA_PTRSIZE, tmpReg, offset);
// Then add the base register
// rd = rd + base
- emitIns_R_R_R(INS_add, EA_PTRSIZE, tmpReg, tmpReg, memBase->gtRegNum);
+ emitIns_R_R_R(INS_add, addType, tmpReg, tmpReg, memBase->gtRegNum);
noway_assert(emitInsIsLoad(ins) || (tmpReg != dataReg));
noway_assert(tmpReg != index->gtRegNum);
diff --git a/src/jit/emitarm64.h b/src/jit/emitarm64.h
index 5459a0d6c8..6a8e42b86f 100644
--- a/src/jit/emitarm64.h
+++ b/src/jit/emitarm64.h
@@ -19,9 +19,7 @@ static bool strictArmAsm;
struct CnsVal
{
ssize_t cnsVal;
-#ifdef RELOC_SUPPORT
- bool cnsReloc;
-#endif
+ bool cnsReloc;
};
#ifdef DEBUG
diff --git a/src/jit/emitinl.h b/src/jit/emitinl.h
index 302b8ea448..82ad53d341 100644
--- a/src/jit/emitinl.h
+++ b/src/jit/emitinl.h
@@ -144,9 +144,7 @@ inline int emitter::emitGetInsCDinfo(instrDesc* id)
inline void emitter::emitGetInsCns(instrDesc* id, CnsVal* cv)
{
-#ifdef RELOC_SUPPORT
cv->cnsReloc = id->idIsCnsReloc();
-#endif
if (id->idIsLargeCns())
{
cv->cnsVal = ((instrDescCns*)id)->idcCnsVal;
@@ -159,9 +157,7 @@ inline void emitter::emitGetInsCns(instrDesc* id, CnsVal* cv)
inline ssize_t emitter::emitGetInsAmdCns(instrDesc* id, CnsVal* cv)
{
-#ifdef RELOC_SUPPORT
cv->cnsReloc = id->idIsCnsReloc();
-#endif
if (id->idIsLargeDsp())
{
if (id->idIsLargeCns())
@@ -192,9 +188,7 @@ inline ssize_t emitter::emitGetInsAmdCns(instrDesc* id, CnsVal* cv)
inline void emitter::emitGetInsDcmCns(instrDesc* id, CnsVal* cv)
{
-#ifdef RELOC_SUPPORT
cv->cnsReloc = id->idIsCnsReloc();
-#endif
if (id->idIsLargeCns())
{
if (id->idIsLargeDsp())
diff --git a/src/jit/emitxarch.cpp b/src/jit/emitxarch.cpp
index be5cefbfea..b495d015d6 100644
--- a/src/jit/emitxarch.cpp
+++ b/src/jit/emitxarch.cpp
@@ -48,6 +48,15 @@ bool IsSSEOrAVXInstruction(instruction ins)
#endif // !FEATURE_AVX_SUPPORT
}
+bool IsAVXOnlyInstruction(instruction ins)
+{
+#ifdef FEATURE_AVX_SUPPORT
+ return (ins >= INS_FIRST_AVX_INSTRUCTION && ins <= INS_LAST_AVX_INSTRUCTION);
+#else
+ return false;
+#endif
+}
+
bool emitter::IsAVXInstruction(instruction ins)
{
#ifdef FEATURE_AVX_SUPPORT
@@ -81,9 +90,11 @@ bool emitter::IsThreeOperandBinaryAVXInstruction(instruction ins)
ins == INS_minsd || ins == INS_divps || ins == INS_divpd || ins == INS_maxps || ins == INS_maxpd ||
ins == INS_maxss || ins == INS_maxsd || ins == INS_andnps || ins == INS_andnpd || ins == INS_paddb ||
ins == INS_paddw || ins == INS_paddd || ins == INS_paddq || ins == INS_psubb || ins == INS_psubw ||
- ins == INS_psubd || ins == INS_psubq || ins == INS_pmuludq || ins == INS_pxor || ins == INS_pmaxub ||
- ins == INS_pminub || ins == INS_pmaxsw || ins == INS_pminsw || ins == INS_insertps ||
- ins == INS_vinsertf128 || ins == INS_punpckldq || ins == INS_phaddd);
+ ins == INS_psubd || ins == INS_psubq || ins == INS_pmuludq || ins == INS_pxor || ins == INS_insertps ||
+ ins == INS_vinsertf128 || ins == INS_punpckldq || ins == INS_phaddd || ins == INS_pminub ||
+ ins == INS_pminsw || ins == INS_pminsb || ins == INS_pminsd || ins == INS_pminuw || ins == INS_pminud ||
+ ins == INS_pmaxub || ins == INS_pmaxsw || ins == INS_pmaxsb || ins == INS_pmaxsd || ins == INS_pmaxuw ||
+ ins == INS_pmaxud);
}
// Returns true if the AVX instruction is a move operator that requires 3 operands.
@@ -106,16 +117,9 @@ bool emitter::IsThreeOperandMoveAVXInstruction(instruction ins)
//
// Note that this should be true for any of the instructions in instrsXArch.h
// that use the SSE38 or SSE3A macro.
-//
-// TODO-XArch-Cleanup: This is a temporary solution for now. Eventually this
-// needs to be addressed by expanding instruction encodings.
bool emitter::Is4ByteAVXInstruction(instruction ins)
{
- return UseAVX() &&
- (ins == INS_dpps || ins == INS_dppd || ins == INS_insertps || ins == INS_pcmpeqq || ins == INS_pcmpgtq ||
- ins == INS_vbroadcastss || ins == INS_vbroadcastsd || ins == INS_vpbroadcastb || ins == INS_vpbroadcastw ||
- ins == INS_vpbroadcastd || ins == INS_vpbroadcastq || ins == INS_vextractf128 || ins == INS_vinsertf128 ||
- ins == INS_pmulld || ins == INS_ptest || ins == INS_phaddd);
+ return UseAVX() && (IsSSE4Instruction(ins) || IsAVXOnlyInstruction(ins)) && EncodedBySSE38orSSE3A(ins);
}
#endif // FEATURE_AVX_SUPPORT
@@ -134,8 +138,7 @@ bool emitter::Is4ByteSSE4Instruction(instruction ins)
// On legacy backend SSE3_4 is not enabled.
return false;
#else
- return UseSSE3_4() && (ins == INS_dpps || ins == INS_dppd || ins == INS_insertps || ins == INS_pcmpeqq ||
- ins == INS_pcmpgtq || ins == INS_pmulld || ins == INS_ptest || ins == INS_phaddd);
+ return UseSSE3_4() && IsSSE4Instruction(ins) && EncodedBySSE38orSSE3A(ins);
#endif
}
@@ -739,7 +742,10 @@ void emitter::emitMarkStackLvl(unsigned stackLevel)
emitCurStackLvl = emitCurIG->igStkLvl = stackLevel;
if (emitMaxStackDepth < emitCurStackLvl)
+ {
+ JITDUMP("Upping emitMaxStackDepth from %d to %d\n", emitMaxStackDepth, emitCurStackLvl);
emitMaxStackDepth = emitCurStackLvl;
+ }
}
#endif
@@ -938,72 +944,6 @@ inline size_t insCode(instruction ins)
/*****************************************************************************
*
- * Returns the "[r/m], 32-bit icon" encoding of the given CPU instruction.
- */
-
-inline size_t insCodeMI(instruction ins)
-{
- // clang-format off
- const static
- size_t insCodesMI[] =
- {
- #define INST0(id, nm, fp, um, rf, wf, mr )
- #define INST1(id, nm, fp, um, rf, wf, mr )
- #define INST2(id, nm, fp, um, rf, wf, mr, mi ) mi,
- #define INST3(id, nm, fp, um, rf, wf, mr, mi, rm ) mi,
- #define INST4(id, nm, fp, um, rf, wf, mr, mi, rm, a4 ) mi,
- #define INST5(id, nm, fp, um, rf, wf, mr, mi, rm, a4, rr) mi,
- #include "instrs.h"
- #undef INST0
- #undef INST1
- #undef INST2
- #undef INST3
- #undef INST4
- #undef INST5
- };
- // clang-format on
-
- assert((unsigned)ins < sizeof(insCodesMI) / sizeof(insCodesMI[0]));
- assert((insCodesMI[ins] != BAD_CODE));
-
- return insCodesMI[ins];
-}
-
-/*****************************************************************************
- *
- * Returns the "reg, [r/m]" encoding of the given CPU instruction.
- */
-
-inline size_t insCodeRM(instruction ins)
-{
- // clang-format off
- const static
- size_t insCodesRM[] =
- {
- #define INST0(id, nm, fp, um, rf, wf, mr )
- #define INST1(id, nm, fp, um, rf, wf, mr )
- #define INST2(id, nm, fp, um, rf, wf, mr, mi )
- #define INST3(id, nm, fp, um, rf, wf, mr, mi, rm ) rm,
- #define INST4(id, nm, fp, um, rf, wf, mr, mi, rm, a4 ) rm,
- #define INST5(id, nm, fp, um, rf, wf, mr, mi, rm, a4, rr) rm,
- #include "instrs.h"
- #undef INST0
- #undef INST1
- #undef INST2
- #undef INST3
- #undef INST4
- #undef INST5
- };
- // clang-format on
-
- assert((unsigned)ins < sizeof(insCodesRM) / sizeof(insCodesRM[0]));
- assert((insCodesRM[ins] != BAD_CODE));
-
- return insCodesRM[ins];
-}
-
-/*****************************************************************************
- *
* Returns the "AL/AX/EAX, imm" accumulator encoding of the given instruction.
*/
@@ -1070,6 +1010,86 @@ inline size_t insCodeRR(instruction ins)
// clang-format off
const static
+size_t insCodesRM[] =
+{
+ #define INST0(id, nm, fp, um, rf, wf, mr )
+ #define INST1(id, nm, fp, um, rf, wf, mr )
+ #define INST2(id, nm, fp, um, rf, wf, mr, mi )
+ #define INST3(id, nm, fp, um, rf, wf, mr, mi, rm ) rm,
+ #define INST4(id, nm, fp, um, rf, wf, mr, mi, rm, a4 ) rm,
+ #define INST5(id, nm, fp, um, rf, wf, mr, mi, rm, a4, rr) rm,
+ #include "instrs.h"
+ #undef INST0
+ #undef INST1
+ #undef INST2
+ #undef INST3
+ #undef INST4
+ #undef INST5
+};
+// clang-format on
+
+// Returns true iff the give CPU instruction has an RM encoding.
+inline bool hasCodeRM(instruction ins)
+{
+ assert((unsigned)ins < sizeof(insCodesRM) / sizeof(insCodesRM[0]));
+ return ((insCodesRM[ins] != BAD_CODE));
+}
+
+/*****************************************************************************
+ *
+ * Returns the "reg, [r/m]" encoding of the given CPU instruction.
+ */
+
+inline size_t insCodeRM(instruction ins)
+{
+ assert((unsigned)ins < sizeof(insCodesRM) / sizeof(insCodesRM[0]));
+ assert((insCodesRM[ins] != BAD_CODE));
+
+ return insCodesRM[ins];
+}
+
+// clang-format off
+const static
+size_t insCodesMI[] =
+{
+ #define INST0(id, nm, fp, um, rf, wf, mr )
+ #define INST1(id, nm, fp, um, rf, wf, mr )
+ #define INST2(id, nm, fp, um, rf, wf, mr, mi ) mi,
+ #define INST3(id, nm, fp, um, rf, wf, mr, mi, rm ) mi,
+ #define INST4(id, nm, fp, um, rf, wf, mr, mi, rm, a4 ) mi,
+ #define INST5(id, nm, fp, um, rf, wf, mr, mi, rm, a4, rr) mi,
+ #include "instrs.h"
+ #undef INST0
+ #undef INST1
+ #undef INST2
+ #undef INST3
+ #undef INST4
+ #undef INST5
+};
+// clang-format on
+
+// Returns true iff the give CPU instruction has an MI encoding.
+inline bool hasCodeMI(instruction ins)
+{
+ assert((unsigned)ins < sizeof(insCodesMI) / sizeof(insCodesMI[0]));
+ return ((insCodesMI[ins] != BAD_CODE));
+}
+
+/*****************************************************************************
+ *
+ * Returns the "[r/m], 32-bit icon" encoding of the given CPU instruction.
+ */
+
+inline size_t insCodeMI(instruction ins)
+{
+ assert((unsigned)ins < sizeof(insCodesMI) / sizeof(insCodesMI[0]));
+ assert((insCodesMI[ins] != BAD_CODE));
+
+ return insCodesMI[ins];
+}
+
+// clang-format off
+const static
size_t insCodesMR[] =
{
#define INST0(id, nm, fp, um, rf, wf, mr )
@@ -1108,6 +1128,32 @@ inline size_t insCodeMR(instruction ins)
return insCodesMR[ins];
}
+// Return true if the instruction uses the SSE38 or SSE3A macro in instrsXArch.h.
+bool emitter::EncodedBySSE38orSSE3A(instruction ins)
+{
+ const size_t SSE38 = 0x0F660038;
+ const size_t SSE3A = 0x0F66003A;
+ const size_t MASK = 0xFFFF00FF;
+
+ size_t insCode = 0;
+
+ if (hasCodeRM(ins))
+ {
+ insCode = insCodeRM(ins);
+ }
+ else if (hasCodeMI(ins))
+ {
+ insCode = insCodeMI(ins);
+ }
+ else if (hasCodeMR(ins))
+ {
+ insCode = insCodeMR(ins);
+ }
+
+ insCode &= MASK;
+ return insCode == SSE38 || insCode == SSE3A;
+}
+
/*****************************************************************************
*
* Returns an encoding for the specified register to be used in the bit0-2
@@ -1622,7 +1668,7 @@ inline UNATIVE_OFFSET emitter::emitInsSizeSV(code_t code, int var, int dsp)
if (EBPbased)
{
-#if defined(_TARGET_AMD64_) && !defined(PLATFORM_UNIX)
+#if defined(_TARGET_AMD64_) && !defined(UNIX_AMD64_ABI)
// If localloc is not used, then ebp chaining is done and hence
// offset of locals will be at negative offsets, Otherwise offsets
// will be positive. In future, when RBP gets positioned in the
@@ -1756,13 +1802,11 @@ inline UNATIVE_OFFSET emitter::emitInsSizeSV(instrDesc* id, int var, int dsp, in
valSize = sizeof(int);
}
-#ifdef RELOC_SUPPORT
if (id->idIsCnsReloc())
{
valInByte = false; // relocs can't be placed in a byte
assert(valSize == sizeof(int));
}
-#endif
if (valInByte)
{
@@ -1838,13 +1882,11 @@ UNATIVE_OFFSET emitter::emitInsSizeAM(instrDesc* id, code_t code)
break;
}
-#ifdef RELOC_SUPPORT
if (id->idIsDspReloc())
{
dspInByte = false; // relocs can't be placed in a byte
dspIsZero = false; // relocs won't always be zero
}
-#endif
if (code & 0xFF000000)
{
@@ -2031,13 +2073,11 @@ inline UNATIVE_OFFSET emitter::emitInsSizeAM(instrDesc* id, code_t code, int val
valSize = sizeof(INT32);
}
-#ifdef RELOC_SUPPORT
if (id->idIsCnsReloc())
{
valInByte = false; // relocs can't be placed in a byte
assert(valSize == sizeof(INT32));
}
-#endif
if (valInByte)
{
@@ -2079,13 +2119,11 @@ inline UNATIVE_OFFSET emitter::emitInsSizeCV(instrDesc* id, code_t code, int val
valSize = sizeof(INT32);
#endif // !_TARGET_AMD64_
-#ifdef RELOC_SUPPORT
if (id->idIsCnsReloc())
{
valInByte = false; // relocs can't be placed in a byte
assert(valSize == sizeof(INT32));
}
-#endif
if (valInByte)
{
@@ -2315,11 +2353,8 @@ void emitter::emitIns(instruction ins)
}
#ifndef LEGACY_BACKEND
- // Account for 2-byte VEX prefix in case of vzeroupper
- if (ins == INS_vzeroupper)
- {
- sz += 2;
- }
+ // vzeroupper includes its 2-byte VEX prefix in its MR code.
+ assert((ins != INS_vzeroupper) || (sz == 3));
#endif
insFormat fmt = IF_NONE;
@@ -3623,13 +3658,11 @@ void emitter::emitIns_IJ(emitAttr attr, regNumber reg, unsigned base)
void emitter::emitIns_C(instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE fldHnd, int offs)
{
-#if RELOC_SUPPORT
// Static always need relocs
if (!jitStaticFldIsGlobAddr(fldHnd))
{
attr = EA_SET_FLG(attr, EA_DSP_RELOC_FLG);
}
-#endif
UNATIVE_OFFSET sz;
instrDesc* id;
@@ -3791,13 +3824,11 @@ void emitter::emitIns_R_R_R(instruction ins, emitAttr attr, regNumber targetReg,
*/
void emitter::emitIns_R_C(instruction ins, emitAttr attr, regNumber reg, CORINFO_FIELD_HANDLE fldHnd, int offs)
{
-#if RELOC_SUPPORT
// Static always need relocs
if (!jitStaticFldIsGlobAddr(fldHnd))
{
attr = EA_SET_FLG(attr, EA_DSP_RELOC_FLG);
}
-#endif
emitAttr size = EA_SIZE(attr);
@@ -3876,13 +3907,11 @@ void emitter::emitIns_R_C(instruction ins, emitAttr attr, regNumber reg, CORINFO
void emitter::emitIns_C_R(instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE fldHnd, regNumber reg, int offs)
{
-#if RELOC_SUPPORT
// Static always need relocs
if (!jitStaticFldIsGlobAddr(fldHnd))
{
attr = EA_SET_FLG(attr, EA_DSP_RELOC_FLG);
}
-#endif
emitAttr size = EA_SIZE(attr);
@@ -3951,13 +3980,11 @@ void emitter::emitIns_C_R(instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE f
void emitter::emitIns_C_I(instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE fldHnd, int offs, int val)
{
-#if RELOC_SUPPORT
// Static always need relocs
if (!jitStaticFldIsGlobAddr(fldHnd))
{
attr = EA_SET_FLG(attr, EA_DSP_RELOC_FLG);
}
-#endif
insFormat fmt;
@@ -4039,7 +4066,6 @@ void emitter::emitIns_J_S(instruction ins, emitAttr attr, BasicBlock* dst, int v
emitTotalIGjmps++;
#endif
-#if RELOC_SUPPORT
#ifndef _TARGET_AMD64_
// Storing the address of a basicBlock will need a reloc
// as the instruction uses the absolute address,
@@ -4052,7 +4078,6 @@ void emitter::emitIns_J_S(instruction ins, emitAttr attr, BasicBlock* dst, int v
{
id->idSetIsDspReloc();
}
-#endif // RELOC_SUPPORT
id->idCodeSize(sz);
@@ -4984,7 +5009,6 @@ void emitter::emitIns_J(instruction ins, BasicBlock* dst, int instrCount /* = 0
}
else if (ins == INS_push || ins == INS_push_hide)
{
-#if RELOC_SUPPORT
// Pushing the address of a basicBlock will need a reloc
// as the instruction uses the absolute address,
// not a relative address
@@ -4992,7 +5016,6 @@ void emitter::emitIns_J(instruction ins, BasicBlock* dst, int instrCount /* = 0
{
id->idSetIsDspReloc();
}
-#endif
sz = PUSH_INST_SIZE;
}
else
@@ -5097,7 +5120,10 @@ void emitter::emitAdjustStackDepthPushPop(instruction ins)
emitCurStackLvl += emitCntStackDepth;
if (emitMaxStackDepth < emitCurStackLvl)
+ {
+ JITDUMP("Upping emitMaxStackDepth from %d to %d\n", emitMaxStackDepth, emitCurStackLvl);
emitMaxStackDepth = emitCurStackLvl;
+ }
}
else if (ins == INS_pop)
{
@@ -5133,7 +5159,10 @@ void emitter::emitAdjustStackDepth(instruction ins, ssize_t val)
emitCurStackLvl = newStackLvl.Value();
if (emitMaxStackDepth < emitCurStackLvl)
+ {
+ JITDUMP("Upping emitMaxStackDepth from %d to %d\n", emitMaxStackDepth, emitCurStackLvl);
emitMaxStackDepth = emitCurStackLvl;
+ }
}
else if (ins == INS_add)
{
@@ -5167,22 +5196,25 @@ void emitter::emitAdjustStackDepth(instruction ins, ssize_t val)
*
*/
+// clang-format off
void emitter::emitIns_Call(EmitCallType callType,
CORINFO_METHOD_HANDLE methHnd,
INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo) // used to report call sites to the EE
- void* addr,
- ssize_t argSize,
- emitAttr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
- VARSET_VALARG_TP ptrVars,
- regMaskTP gcrefRegs,
- regMaskTP byrefRegs,
- IL_OFFSETX ilOffset, // = BAD_IL_OFFSET
- regNumber ireg, // = REG_NA
- regNumber xreg, // = REG_NA
- unsigned xmul, // = 0
- ssize_t disp, // = 0
- bool isJump, // = false
- bool isNoGC) // = false
+ void* addr,
+ ssize_t argSize,
+ emitAttr retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
+ VARSET_VALARG_TP ptrVars,
+ regMaskTP gcrefRegs,
+ regMaskTP byrefRegs,
+ IL_OFFSETX ilOffset, // = BAD_IL_OFFSET
+ regNumber ireg, // = REG_NA
+ regNumber xreg, // = REG_NA
+ unsigned xmul, // = 0
+ ssize_t disp, // = 0
+ bool isJump, // = false
+ bool isNoGC) // = false
+// clang-format on
{
/* Sanity check the arguments depending on callType */
@@ -5480,7 +5512,6 @@ void emitter::emitIns_Call(EmitCallType callType,
id->idAddr()->iiaAddr = (BYTE*)addr;
sz = 6;
-#if RELOC_SUPPORT
// Since this is an indirect call through a pointer and we don't
// currently pass in emitAttr into this function, we query codegen
// whether addr needs a reloc.
@@ -5498,7 +5529,6 @@ void emitter::emitIns_Call(EmitCallType callType,
sz++;
}
#endif //_TARGET_AMD64_
-#endif // RELOC_SUPPORT
}
else
{
@@ -5518,13 +5548,11 @@ void emitter::emitIns_Call(EmitCallType callType,
id->idSetIsCallAddr();
}
-#if RELOC_SUPPORT
// Direct call to a method and no addr indirection is needed.
if (codeGen->genCodeAddrNeedsReloc((size_t)addr))
{
id->idSetIsDspReloc();
}
-#endif
}
#ifdef DEBUG
@@ -5979,12 +6007,10 @@ void emitter::emitDispClsVar(CORINFO_FIELD_HANDLE fldHnd, ssize_t offs, bool rel
doffs = Compiler::eeGetJitDataOffs(fldHnd);
-#ifdef RELOC_SUPPORT
if (reloc)
{
printf("reloc ");
}
-#endif
if (doffs >= 0)
{
@@ -6200,12 +6226,10 @@ void emitter::emitDispAddrMode(instrDesc* id, bool noDetail)
if (jdsc)
{
-#ifdef RELOC_SUPPORT
if (id->idIsDspReloc())
{
printf("reloc ");
}
-#endif
printf("J_M%03u_DS%02u", Compiler::s_compMethodsCount, id->idDebugOnlyInfo()->idMemCookie);
}
@@ -6246,7 +6270,6 @@ void emitter::emitDispAddrMode(instrDesc* id, bool noDetail)
nsep = true;
}
-#ifdef RELOC_SUPPORT
if ((id->idIsDspReloc()) && (id->idIns() != INS_i_jmp))
{
if (nsep)
@@ -6256,7 +6279,6 @@ void emitter::emitDispAddrMode(instrDesc* id, bool noDetail)
emitDispReloc(disp);
}
else
-#endif
{
// Munge any pointers if we want diff-able disassembly
if (emitComp->opts.disDiffable)
@@ -6463,11 +6485,8 @@ void emitter::emitDispIns(
printf("IN%04x: ", idNum);
}
-#ifdef RELOC_SUPPORT
#define ID_INFO_DSP_RELOC ((bool)(id->idIsDspReloc()))
-#else
-#define ID_INFO_DSP_RELOC false
-#endif
+
/* Display a constant value if the instruction references one */
if (!isNew)
@@ -6684,13 +6703,11 @@ void emitter::emitDispIns(
// no 8-byte immediates allowed here!
assert((val >= 0xFFFFFFFF80000000LL) && (val <= 0x000000007FFFFFFFLL));
#endif
-#ifdef RELOC_SUPPORT
if (id->idIsCnsReloc())
{
emitDispReloc(val);
}
else
-#endif
{
PRINT_CONSTANT:
// Munge any pointers if we want diff-able disassembly
@@ -6812,13 +6829,11 @@ void emitter::emitDispIns(
else
{
printf(", ");
-#ifdef RELOC_SUPPORT
if (cnsVal.cnsReloc)
{
emitDispReloc(val);
}
else
-#endif
{
goto PRINT_CONSTANT;
}
@@ -6893,13 +6908,11 @@ void emitter::emitDispIns(
else
{
printf(", ");
-#ifdef RELOC_SUPPORT
if (cnsVal.cnsReloc)
{
emitDispReloc(val);
}
else
-#endif
{
goto PRINT_CONSTANT;
}
@@ -6999,13 +7012,11 @@ void emitter::emitDispIns(
assert((val >= 0xFFFFFFFF80000000LL) && (val <= 0x000000007FFFFFFFLL));
#endif
printf(", ");
-#ifdef RELOC_SUPPORT
if (id->idIsCnsReloc())
{
emitDispReloc(val);
}
else
-#endif
{
goto PRINT_CONSTANT;
}
@@ -7073,14 +7084,11 @@ void emitter::emitDispIns(
// no 8-byte immediates allowed here!
assert((val >= 0xFFFFFFFF80000000LL) && (val <= 0x000000007FFFFFFFLL));
#endif
-#ifdef RELOC_SUPPORT
if (cnsVal.cnsReloc)
{
emitDispReloc(val);
}
- else
-#endif
- if (id->idInsFmt() == IF_MRW_SHF)
+ else if (id->idInsFmt() == IF_MRW_SHF)
{
emitDispShift(ins, (BYTE)val);
}
@@ -7125,13 +7133,11 @@ void emitter::emitDispIns(
case IF_RRW_CNS:
printf("%s, ", emitRegName(id->idReg1(), attr));
val = emitGetInsSC(id);
-#ifdef RELOC_SUPPORT
if (id->idIsCnsReloc())
{
emitDispReloc(val);
}
else
-#endif
{
goto PRINT_CONSTANT;
}
@@ -7477,11 +7483,7 @@ BYTE* emitter::emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
ssize_t cval = addc->cnsVal;
// Does the constant fit in a byte?
- if ((signed char)cval == cval &&
-#ifdef RELOC_SUPPORT
- addc->cnsReloc == false &&
-#endif
- ins != INS_mov && ins != INS_test)
+ if ((signed char)cval == cval && addc->cnsReloc == false && ins != INS_mov && ins != INS_test)
{
if (id->idInsFmt() != IF_ARW_SHF)
{
@@ -7626,12 +7628,10 @@ GOT_DSP:
dspInByte = ((signed char)dsp == (ssize_t)dsp);
dspIsZero = (dsp == 0);
-#ifdef RELOC_SUPPORT
if (id->idIsDspReloc())
{
dspInByte = false; // relocs can't be placed in a byte
}
-#endif
// Is there a [scaled] index component?
if (rgx == REG_NA)
@@ -7725,12 +7725,10 @@ GOT_DSP:
dst += emitOutputWord(dst, code | 0x8500);
dst += emitOutputLong(dst, dsp);
-#ifdef RELOC_SUPPORT
if (id->idIsDspReloc())
{
emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW);
}
-#endif
}
break;
@@ -7765,12 +7763,10 @@ GOT_DSP:
dst += emitOutputWord(dst, code | 0x8400);
dst += emitOutputByte(dst, 0x24);
dst += emitOutputLong(dst, dsp);
-#ifdef RELOC_SUPPORT
if (id->idIsDspReloc())
{
emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW);
}
-#endif
}
break;
@@ -7796,12 +7792,10 @@ GOT_DSP:
{
dst += emitOutputWord(dst, code | 0x8000);
dst += emitOutputLong(dst, dsp);
-#ifdef RELOC_SUPPORT
if (id->idIsDspReloc())
{
emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW);
}
-#endif
}
}
@@ -7846,12 +7840,10 @@ GOT_DSP:
dst += emitOutputWord(dst, code | 0x8400);
dst += emitOutputByte(dst, regByte);
dst += emitOutputLong(dst, dsp);
-#ifdef RELOC_SUPPORT
if (id->idIsDspReloc())
{
emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW);
}
-#endif
}
}
}
@@ -7871,12 +7863,10 @@ GOT_DSP:
}
dst += emitOutputLong(dst, dsp);
-#ifdef RELOC_SUPPORT
if (id->idIsDspReloc())
{
emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW);
}
-#endif
}
}
else
@@ -7904,12 +7894,10 @@ GOT_DSP:
dst += emitOutputWord(dst, code | 0x8400);
dst += emitOutputByte(dst, regByte);
dst += emitOutputLong(dst, dsp);
-#ifdef RELOC_SUPPORT
if (id->idIsDspReloc())
{
emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)dsp, IMAGE_REL_BASED_HIGHLOW);
}
-#endif
}
}
}
@@ -7943,13 +7931,11 @@ GOT_DSP:
assert(!"unexpected operand size");
}
-#ifdef RELOC_SUPPORT
if (addc->cnsReloc)
{
emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)(size_t)cval, IMAGE_REL_BASED_HIGHLOW);
assert(opsz == 4);
}
-#endif
}
DONE:
@@ -8099,11 +8085,7 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
ssize_t cval = addc->cnsVal;
// Does the constant fit in a byte?
- if ((signed char)cval == cval &&
-#ifdef RELOC_SUPPORT
- addc->cnsReloc == false &&
-#endif
- ins != INS_mov && ins != INS_test)
+ if ((signed char)cval == cval && addc->cnsReloc == false && ins != INS_mov && ins != INS_test)
{
if (id->idInsFmt() != IF_SRW_SHF)
{
@@ -8238,10 +8220,8 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
dspInByte = ((signed char)dsp == (int)dsp);
dspIsZero = (dsp == 0);
-#ifdef RELOC_SUPPORT
// for stack varaibles the dsp should never be a reloc
assert(id->idIsDspReloc() == 0);
-#endif
if (EBPbased)
{
@@ -8361,13 +8341,11 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
assert(!"unexpected operand size");
}
-#ifdef RELOC_SUPPORT
if (addc->cnsReloc)
{
emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)(size_t)cval, IMAGE_REL_BASED_HIGHLOW);
assert(opsz == 4);
}
-#endif
}
// Does this instruction operate on a GC ref value?
@@ -8510,11 +8488,7 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
{
ssize_t cval = addc->cnsVal;
// Does the constant fit in a byte?
- if ((signed char)cval == cval &&
-#ifdef RELOC_SUPPORT
- addc->cnsReloc == false &&
-#endif
- ins != INS_mov && ins != INS_test)
+ if ((signed char)cval == cval && addc->cnsReloc == false && ins != INS_mov && ins != INS_test)
{
if (id->idInsFmt() != IF_MRW_SHF)
{
@@ -8756,12 +8730,10 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
dst += emitOutputLong(dst, (int)target);
#endif //_TARGET_X86_
-#ifdef RELOC_SUPPORT
if (id->idIsDspReloc())
{
emitRecordRelocation((void*)(dst - sizeof(int)), target, IMAGE_REL_BASED_DISP32, 0, addlDelta);
}
-#endif
}
else
{
@@ -8774,12 +8746,10 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
dst += emitOutputSizeT(dst, (ssize_t)target);
-#ifdef RELOC_SUPPORT
if (id->idIsDspReloc())
{
emitRecordRelocation((void*)(dst - sizeof(void*)), target, IMAGE_REL_BASED_MOFFSET);
}
-#endif
#endif //_TARGET_X86_
}
@@ -8811,13 +8781,11 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
default:
assert(!"unexpected operand size");
}
-#ifdef RELOC_SUPPORT
if (addc->cnsReloc)
{
emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)(size_t)cval, IMAGE_REL_BASED_HIGHLOW);
assert(opsz == 4);
}
-#endif
}
// Does this instruction operate on a GC ref value?
@@ -9539,12 +9507,10 @@ BYTE* emitter::emitOutputRI(BYTE* dst, instrDesc* id)
ssize_t val = emitGetInsSC(id);
bool valInByte = ((signed char)val == val) && (ins != INS_mov) && (ins != INS_test);
-#ifdef RELOC_SUPPORT
if (id->idIsCnsReloc())
{
valInByte = false; // relocs can't be placed in a byte
}
-#endif
noway_assert(emitVerifyEncodable(ins, size, reg));
@@ -9632,12 +9598,10 @@ BYTE* emitter::emitOutputRI(BYTE* dst, instrDesc* id)
}
#endif
-#ifdef RELOC_SUPPORT
if (id->idIsCnsReloc())
{
emitRecordRelocation((void*)(dst - (unsigned)EA_SIZE(size)), (void*)(size_t)val, IMAGE_REL_BASED_MOFFSET);
}
-#endif
goto DONE;
}
@@ -9794,13 +9758,11 @@ BYTE* emitter::emitOutputRI(BYTE* dst, instrDesc* id)
break;
}
-#ifdef RELOC_SUPPORT
if (id->idIsCnsReloc())
{
emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)(size_t)val, IMAGE_REL_BASED_HIGHLOW);
assert(size == EA_4BYTE);
}
-#endif
}
DONE:
@@ -9909,7 +9871,6 @@ BYTE* emitter::emitOutputIV(BYTE* dst, instrDesc* id)
noway_assert(size < EA_8BYTE || ((int)val == val && !id->idIsCnsReloc()));
#endif
-#ifdef RELOC_SUPPORT
if (id->idIsCnsReloc())
{
valInByte = false; // relocs can't be placed in a byte
@@ -9917,7 +9878,6 @@ BYTE* emitter::emitOutputIV(BYTE* dst, instrDesc* id)
// Of these instructions only the push instruction can have reloc
assert(ins == INS_push || ins == INS_push_hide);
}
-#endif
switch (ins)
{
@@ -9959,12 +9919,10 @@ BYTE* emitter::emitOutputIV(BYTE* dst, instrDesc* id)
dst += emitOutputByte(dst, code);
dst += emitOutputLong(dst, val);
-#ifdef RELOC_SUPPORT
if (id->idIsCnsReloc())
{
emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)(size_t)val, IMAGE_REL_BASED_HIGHLOW);
}
-#endif
}
// Did we push a GC ref value?
@@ -10551,12 +10509,10 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
dst += emitOutputLong(dst, offset);
-#ifdef RELOC_SUPPORT
if (id->idIsDspReloc())
{
emitRecordRelocation((void*)(dst - sizeof(INT32)), addr, IMAGE_REL_BASED_REL32);
}
-#endif
DONE_CALL:
diff --git a/src/jit/emitxarch.h b/src/jit/emitxarch.h
index 9c435e5d87..faeba7d942 100644
--- a/src/jit/emitxarch.h
+++ b/src/jit/emitxarch.h
@@ -40,9 +40,7 @@ typedef unsigned __int64 code_t;
struct CnsVal
{
ssize_t cnsVal;
-#ifdef RELOC_SUPPORT
- bool cnsReloc;
-#endif
+ bool cnsReloc;
};
UNATIVE_OFFSET emitInsSize(code_t code);
@@ -107,6 +105,7 @@ void SetUseSSE3_4(bool value)
{
useSSE3_4Encodings = value;
}
+bool EncodedBySSE38orSSE3A(instruction ins);
bool Is4ByteSSE4Instruction(instruction ins);
bool hasRexPrefix(code_t code)
@@ -451,35 +450,41 @@ enum EmitCallType
EC_COUNT
};
+// clang-format off
void emitIns_Call(EmitCallType callType,
CORINFO_METHOD_HANDLE methHnd,
CORINFO_SIG_INFO* sigInfo, // used to report call sites to the EE
void* addr,
ssize_t argSize,
- emitAttr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
- VARSET_VALARG_TP ptrVars,
- regMaskTP gcrefRegs,
- regMaskTP byrefRegs,
- GenTreeIndir* indir,
- bool isJump = false,
- bool isNoGC = false);
-
+ emitAttr retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
+ VARSET_VALARG_TP ptrVars,
+ regMaskTP gcrefRegs,
+ regMaskTP byrefRegs,
+ GenTreeIndir* indir,
+ bool isJump = false,
+ bool isNoGC = false);
+// clang-format on
+
+// clang-format off
void emitIns_Call(EmitCallType callType,
CORINFO_METHOD_HANDLE methHnd,
INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo) // used to report call sites to the EE
- void* addr,
- ssize_t argSize,
- emitAttr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
- VARSET_VALARG_TP ptrVars,
- regMaskTP gcrefRegs,
- regMaskTP byrefRegs,
- IL_OFFSETX ilOffset = BAD_IL_OFFSET,
- regNumber ireg = REG_NA,
- regNumber xreg = REG_NA,
- unsigned xmul = 0,
- ssize_t disp = 0,
- bool isJump = false,
- bool isNoGC = false);
+ void* addr,
+ ssize_t argSize,
+ emitAttr retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
+ VARSET_VALARG_TP ptrVars,
+ regMaskTP gcrefRegs,
+ regMaskTP byrefRegs,
+ IL_OFFSETX ilOffset = BAD_IL_OFFSET,
+ regNumber ireg = REG_NA,
+ regNumber xreg = REG_NA,
+ unsigned xmul = 0,
+ ssize_t disp = 0,
+ bool isJump = false,
+ bool isNoGC = false);
+// clang-format on
#ifdef _TARGET_AMD64_
// Is the last instruction emitted a call instruction?
diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp
index 50318b0940..3374b8c820 100644
--- a/src/jit/flowgraph.cpp
+++ b/src/jit/flowgraph.cpp
@@ -44,7 +44,7 @@ void Compiler::fgInit()
fgSlopUsedInEdgeWeights = false;
fgRangeUsedInEdgeWeights = true;
fgNeedsUpdateFlowGraph = false;
- fgCalledWeight = BB_ZERO_WEIGHT;
+ fgCalledCount = BB_ZERO_WEIGHT;
/* We haven't yet computed the dominator sets */
fgDomsComputed = false;
@@ -330,14 +330,37 @@ void Compiler::fgInstrumentMethod()
// Add the method entry callback node
- GenTreeArgList* args = gtNewArgList(gtNewIconEmbMethHndNode(info.compMethodHnd));
+ GenTreePtr arg;
+
+#ifdef FEATURE_READYTORUN_COMPILER
+ if (opts.IsReadyToRun())
+ {
+ mdMethodDef currentMethodToken = info.compCompHnd->getMethodDefFromMethod(info.compMethodHnd);
+
+ CORINFO_RESOLVED_TOKEN resolvedToken;
+ resolvedToken.tokenContext = MAKE_METHODCONTEXT(info.compMethodHnd);
+ resolvedToken.tokenScope = info.compScopeHnd;
+ resolvedToken.token = currentMethodToken;
+ resolvedToken.tokenType = CORINFO_TOKENKIND_Method;
+
+ info.compCompHnd->resolveToken(&resolvedToken);
+
+ arg = impTokenToHandle(&resolvedToken);
+ }
+ else
+#endif
+ {
+ arg = gtNewIconEmbMethHndNode(info.compMethodHnd);
+ }
+
+ GenTreeArgList* args = gtNewArgList(arg);
GenTreePtr call = gtNewHelperCallNode(CORINFO_HELP_BBT_FCN_ENTER, TYP_VOID, 0, args);
GenTreePtr handle =
gtNewIconEmbHndNode((void*)&bbProfileBufferStart->ExecutionCount, nullptr, GTF_ICON_BBC_PTR);
GenTreePtr value = gtNewOperNode(GT_IND, TYP_INT, handle);
GenTreePtr relop = gtNewOperNode(GT_NE, TYP_INT, value, gtNewIconNode(0, TYP_INT));
- relop->gtFlags |= GTF_RELOP_QMARK;
+ relop->gtFlags |= GTF_RELOP_QMARK; // TODO-Cleanup: [Simple] Move this to gtNewQmarkNode
GenTreePtr colon = new (this, GT_COLON) GenTreeColon(TYP_VOID, gtNewNothingNode(), call);
GenTreePtr cond = gtNewQmarkNode(TYP_VOID, relop, colon);
stmt = gtNewStmt(cond);
@@ -397,6 +420,9 @@ BasicBlock* Compiler::fgNewBasicBlock(BBjumpKinds jumpKind)
void Compiler::fgEnsureFirstBBisScratch()
{
+ // This method does not update predecessor lists and so must only be called before they are computed.
+ assert(!fgComputePredsDone);
+
// Have we already allocated a scratch block?
if (fgFirstBBisScratch())
@@ -411,10 +437,11 @@ void Compiler::fgEnsureFirstBBisScratch()
if (fgFirstBB != nullptr)
{
// If we have profile data the new block will inherit fgFirstBlock's weight
- if (fgFirstBB->bbFlags & BBF_PROF_WEIGHT)
+ if (fgFirstBB->hasProfileWeight())
{
block->inheritWeight(fgFirstBB);
}
+
fgInsertBBbefore(fgFirstBB, block);
}
else
@@ -2386,6 +2413,7 @@ void Compiler::fgComputeDoms()
bbRoot.bbNum = 0;
bbRoot.bbIDom = &bbRoot;
bbRoot.bbDfsNum = 0;
+ bbRoot.bbFlags = 0;
flRoot.flNext = nullptr;
flRoot.flBlock = &bbRoot;
@@ -2508,6 +2536,8 @@ void Compiler::fgComputeDoms()
}
}
+ fgCompDominatedByExceptionalEntryBlocks();
+
#ifdef DEBUG
if (verbose)
{
@@ -3826,19 +3856,19 @@ bool Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block)
if (GCPOLL_CALL == pollType)
{
createdPollBlocks = false;
- GenTreePtr tree = gtNewHelperCallNode(CORINFO_HELP_POLL_GC, TYP_VOID);
+ GenTreeCall* call = gtNewHelperCallNode(CORINFO_HELP_POLL_GC, TYP_VOID);
#if GTF_CALL_REG_SAVE
- tree->gtCall.gtCallMoreFlags |= GTF_CALL_REG_SAVE;
+ call->gtCallMoreFlags |= GTF_CALL_REG_SAVE;
#endif // GTF_CALL_REG_SAVE
// for BBJ_ALWAYS I don't need to insert it before the condition. Just append it.
if (block->bbJumpKind == BBJ_ALWAYS)
{
- fgInsertStmtAtEnd(block, tree);
+ fgInsertStmtAtEnd(block, call);
}
else
{
- GenTreeStmt* newStmt = fgInsertStmtNearEnd(block, tree);
+ GenTreeStmt* newStmt = fgInsertStmtNearEnd(block, call);
// For DDB156656, we need to associate the GC Poll with the IL offset (and therefore sequence
// point) of the tree before which we inserted the poll. One example of when this is a
// problem:
@@ -3907,11 +3937,11 @@ bool Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block)
bottom->bbJumpDest = top->bbJumpDest;
// 2) Add a GC_CALL node to Poll.
- GenTreePtr tree = gtNewHelperCallNode(CORINFO_HELP_POLL_GC, TYP_VOID);
+ GenTreeCall* call = gtNewHelperCallNode(CORINFO_HELP_POLL_GC, TYP_VOID);
#if GTF_CALL_REG_SAVE
- tree->gtCall.gtCallMoreFlags |= GTF_CALL_REG_SAVE;
+ call->gtCallMoreFlags |= GTF_CALL_REG_SAVE;
#endif // GTF_CALL_REG_SAVE
- fgInsertStmtAtEnd(poll, tree);
+ fgInsertStmtAtEnd(poll, call);
// 3) Remove the last statement from Top and add it to Bottom.
if (oldJumpKind != BBJ_ALWAYS)
@@ -4248,7 +4278,7 @@ private:
// jumpTarget[N] is set to a JT_* value if IL offset N is a
// jump target in the method.
//
-// Also sets lvAddrExposed and lvArgWrite in lvaTable[].
+// Also sets lvAddrExposed and lvHasILStoreOp, ilHasMultipleILStoreOp in lvaTable[].
#ifdef _PREFAST_
#pragma warning(push)
@@ -4512,20 +4542,80 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, BYTE*
}
varNum = (sz == sizeof(BYTE)) ? getU1LittleEndian(codeAddr) : getU2LittleEndian(codeAddr);
- varNum = compMapILargNum(varNum); // account for possible hidden param
- // This check is only intended to prevent an AV. Bad varNum values will later
- // be handled properly by the verifier.
- if (varNum < lvaTableCnt)
+ if (isInlining)
{
- if (isInlining)
+ if (varNum < impInlineInfo->argCnt)
{
impInlineInfo->inlArgInfo[varNum].argHasStargOp = true;
}
+ }
+ else
+ {
+ // account for possible hidden param
+ varNum = compMapILargNum(varNum);
+
+ // This check is only intended to prevent an AV. Bad varNum values will later
+ // be handled properly by the verifier.
+ if (varNum < lvaTableCnt)
+ {
+ // In non-inline cases, note written-to arguments.
+ lvaTable[varNum].lvHasILStoreOp = 1;
+ }
+ }
+ }
+ break;
+
+ case CEE_STLOC_0:
+ case CEE_STLOC_1:
+ case CEE_STLOC_2:
+ case CEE_STLOC_3:
+ varNum = (opcode - CEE_STLOC_0);
+ goto STLOC;
+
+ case CEE_STLOC:
+ case CEE_STLOC_S:
+ {
+ noway_assert(sz == sizeof(BYTE) || sz == sizeof(WORD));
+
+ if (codeAddr > codeEndp - sz)
+ {
+ goto TOO_FAR;
+ }
+
+ varNum = (sz == sizeof(BYTE)) ? getU1LittleEndian(codeAddr) : getU2LittleEndian(codeAddr);
+
+ STLOC:
+ if (isInlining)
+ {
+ InlLclVarInfo& lclInfo = impInlineInfo->lclVarInfo[varNum + impInlineInfo->argCnt];
+
+ if (lclInfo.lclHasStlocOp)
+ {
+ lclInfo.lclHasMultipleStlocOp = 1;
+ }
else
{
+ lclInfo.lclHasStlocOp = 1;
+ }
+ }
+ else
+ {
+ varNum += info.compArgsCount;
+
+ // This check is only intended to prevent an AV. Bad varNum values will later
+ // be handled properly by the verifier.
+ if (varNum < lvaTableCnt)
+ {
// In non-inline cases, note written-to locals.
- lvaTable[varNum].lvArgWrite = 1;
+ if (lvaTable[varNum].lvHasILStoreOp)
+ {
+ lvaTable[varNum].lvHasMultipleILStoreOp = 1;
+ }
+ else
+ {
+ lvaTable[varNum].lvHasILStoreOp = 1;
+ }
}
}
}
@@ -4847,11 +4937,11 @@ void Compiler::fgAdjustForAddressExposedOrWrittenThis()
// Optionally enable adjustment during stress.
if (!tiVerificationNeeded && compStressCompile(STRESS_GENERIC_VARN, 15))
{
- lvaTable[info.compThisArg].lvArgWrite = true;
+ lvaTable[info.compThisArg].lvHasILStoreOp = true;
}
// If this is exposed or written to, create a temp for the modifiable this
- if (lvaTable[info.compThisArg].lvAddrExposed || lvaTable[info.compThisArg].lvArgWrite)
+ if (lvaTable[info.compThisArg].lvAddrExposed || lvaTable[info.compThisArg].lvHasILStoreOp)
{
// If there is a "ldarga 0" or "starg 0", grab and use the temp.
lvaArg0Var = lvaGrabTemp(false DEBUGARG("Address-exposed, or written this pointer"));
@@ -4865,14 +4955,14 @@ void Compiler::fgAdjustForAddressExposedOrWrittenThis()
lvaTable[lvaArg0Var].lvLclFieldExpr = lvaTable[info.compThisArg].lvLclFieldExpr;
lvaTable[lvaArg0Var].lvLiveAcrossUCall = lvaTable[info.compThisArg].lvLiveAcrossUCall;
#endif
- lvaTable[lvaArg0Var].lvArgWrite = lvaTable[info.compThisArg].lvArgWrite;
- lvaTable[lvaArg0Var].lvVerTypeInfo = lvaTable[info.compThisArg].lvVerTypeInfo;
+ lvaTable[lvaArg0Var].lvHasILStoreOp = lvaTable[info.compThisArg].lvHasILStoreOp;
+ lvaTable[lvaArg0Var].lvVerTypeInfo = lvaTable[info.compThisArg].lvVerTypeInfo;
// Clear the TI_FLAG_THIS_PTR in the original 'this' pointer.
noway_assert(lvaTable[lvaArg0Var].lvVerTypeInfo.IsThisPtr());
lvaTable[info.compThisArg].lvVerTypeInfo.ClearThisPtr();
- lvaTable[info.compThisArg].lvAddrExposed = false;
- lvaTable[info.compThisArg].lvArgWrite = false;
+ lvaTable[info.compThisArg].lvAddrExposed = false;
+ lvaTable[info.compThisArg].lvHasILStoreOp = false;
}
}
@@ -5779,11 +5869,12 @@ void Compiler::fgFindBasicBlocks()
compHndBBtabCount = impInlineInfo->InlinerCompiler->compHndBBtabCount;
info.compXcptnsCount = impInlineInfo->InlinerCompiler->info.compXcptnsCount;
- // Use a spill temp for the return value if there are multiple return blocks.
- if ((info.compRetNativeType != TYP_VOID) && (retBlocks > 1))
+ // Use a spill temp for the return value if there are multiple return blocks,
+ // or if the inlinee has GC ref locals.
+ if ((info.compRetNativeType != TYP_VOID) && ((retBlocks > 1) || impInlineInfo->HasGcRefLocals()))
{
// The lifetime of this var might expand multiple BBs. So it is a long lifetime compiler temp.
- lvaInlineeReturnSpillTemp = lvaGrabTemp(false DEBUGARG("Inline candidate multiple BBJ_RETURN spill temp"));
+ lvaInlineeReturnSpillTemp = lvaGrabTemp(false DEBUGARG("Inline return value spill temp"));
lvaTable[lvaInlineeReturnSpillTemp].lvType = info.compRetNativeType;
}
@@ -6696,9 +6787,7 @@ bool Compiler::fgIsThrow(GenTreePtr tree)
(tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_VERIFICATION)) ||
(tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_RNGCHKFAIL)) ||
(tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_THROWDIVZERO)) ||
-#if COR_JIT_EE_VERSION > 460
(tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_THROWNULLREF)) ||
-#endif // COR_JIT_EE_VERSION
(tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_THROW)) ||
(tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_RETHROW)))
{
@@ -6824,7 +6913,7 @@ GenTreePtr Compiler::fgIsIndirOfAddrOfLocal(GenTreePtr tree)
return res;
}
-GenTreePtr Compiler::fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc helper)
+GenTreeCall* Compiler::fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc helper)
{
bool bNeedClassID = true;
unsigned callFlags = 0;
@@ -6934,7 +7023,7 @@ GenTreePtr Compiler::fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfoHe
return gtNewHelperCallNode(helper, type, callFlags, argList);
}
-GenTreePtr Compiler::fgGetSharedCCtor(CORINFO_CLASS_HANDLE cls)
+GenTreeCall* Compiler::fgGetSharedCCtor(CORINFO_CLASS_HANDLE cls)
{
#ifdef FEATURE_READYTORUN_COMPILER
if (opts.IsReadyToRun())
@@ -7032,137 +7121,156 @@ bool Compiler::fgAddrCouldBeNull(GenTreePtr addr)
* Optimize the call to the delegate constructor.
*/
-GenTreePtr Compiler::fgOptimizeDelegateConstructor(GenTreePtr call, CORINFO_CONTEXT_HANDLE* ExactContextHnd)
+GenTreePtr Compiler::fgOptimizeDelegateConstructor(GenTreeCall* call,
+ CORINFO_CONTEXT_HANDLE* ExactContextHnd,
+ CORINFO_RESOLVED_TOKEN* ldftnToken)
{
- noway_assert(call->gtOper == GT_CALL);
-
- noway_assert(call->gtCall.gtCallType == CT_USER_FUNC);
- CORINFO_METHOD_HANDLE methHnd = call->gtCall.gtCallMethHnd;
+ noway_assert(call->gtCallType == CT_USER_FUNC);
+ CORINFO_METHOD_HANDLE methHnd = call->gtCallMethHnd;
CORINFO_CLASS_HANDLE clsHnd = info.compCompHnd->getMethodClass(methHnd);
- GenTreePtr targetMethod = call->gtCall.gtCallArgs->gtOp.gtOp2->gtOp.gtOp1;
+ GenTreePtr targetMethod = call->gtCallArgs->Rest()->Current();
noway_assert(targetMethod->TypeGet() == TYP_I_IMPL);
- genTreeOps oper = targetMethod->OperGet();
- if (oper == GT_FTN_ADDR || oper == GT_CALL || oper == GT_QMARK)
+ genTreeOps oper = targetMethod->OperGet();
+ CORINFO_METHOD_HANDLE targetMethodHnd = nullptr;
+ GenTreePtr qmarkNode = nullptr;
+ if (oper == GT_FTN_ADDR)
{
- CORINFO_METHOD_HANDLE targetMethodHnd = nullptr;
- GenTreePtr qmarkNode = nullptr;
- if (oper == GT_FTN_ADDR)
- {
- targetMethodHnd = targetMethod->gtFptrVal.gtFptrMethod;
- }
- else if (oper == GT_CALL && targetMethod->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_VIRTUAL_FUNC_PTR))
- {
- GenTreePtr handleNode = targetMethod->gtCall.gtCallArgs->gtOp.gtOp2->gtOp.gtOp2->gtOp.gtOp1;
+ targetMethodHnd = targetMethod->gtFptrVal.gtFptrMethod;
+ }
+ else if (oper == GT_CALL && targetMethod->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_VIRTUAL_FUNC_PTR))
+ {
+ GenTreePtr handleNode = targetMethod->gtCall.gtCallArgs->Rest()->Rest()->Current();
- if (handleNode->OperGet() == GT_CNS_INT)
- {
- // it's a ldvirtftn case, fetch the methodhandle off the helper for ldvirtftn. It's the 3rd arg
- targetMethodHnd = CORINFO_METHOD_HANDLE(handleNode->gtIntCon.gtCompileTimeHandle);
- }
- // Sometimes the argument to this is the result of a generic dictionary lookup, which shows
- // up as a GT_QMARK.
- else if (handleNode->OperGet() == GT_QMARK)
- {
- qmarkNode = handleNode;
- }
- }
- // Sometimes we don't call CORINFO_HELP_VIRTUAL_FUNC_PTR but instead just call
- // CORINFO_HELP_RUNTIMEHANDLE_METHOD directly.
- else if (oper == GT_QMARK)
+ if (handleNode->OperGet() == GT_CNS_INT)
{
- qmarkNode = targetMethod;
+ // it's a ldvirtftn case, fetch the methodhandle off the helper for ldvirtftn. It's the 3rd arg
+ targetMethodHnd = CORINFO_METHOD_HANDLE(handleNode->gtIntCon.gtCompileTimeHandle);
}
- if (qmarkNode)
+ // Sometimes the argument to this is the result of a generic dictionary lookup, which shows
+ // up as a GT_QMARK.
+ else if (handleNode->OperGet() == GT_QMARK)
{
- noway_assert(qmarkNode->OperGet() == GT_QMARK);
- // The argument is actually a generic dictionary lookup. For delegate creation it looks
- // like:
- // GT_QMARK
- // GT_COLON
- // op1 -> call
- // Arg 1 -> token (has compile time handle)
- // op2 -> lclvar
- //
- //
- // In this case I can find the token (which is a method handle) and that is the compile time
- // handle.
- noway_assert(qmarkNode->gtOp.gtOp2->OperGet() == GT_COLON);
- noway_assert(qmarkNode->gtOp.gtOp2->gtOp.gtOp1->OperGet() == GT_CALL);
- GenTreePtr runtimeLookupCall = qmarkNode->gtOp.gtOp2->gtOp.gtOp1;
-
- // This could be any of CORINFO_HELP_RUNTIMEHANDLE_(METHOD|CLASS)(_LOG?)
- GenTreePtr tokenNode = runtimeLookupCall->gtCall.gtCallArgs->gtOp.gtOp2->gtOp.gtOp1;
- noway_assert(tokenNode->OperGet() == GT_CNS_INT);
- targetMethodHnd = CORINFO_METHOD_HANDLE(tokenNode->gtIntCon.gtCompileTimeHandle);
+ qmarkNode = handleNode;
}
+ }
+ // Sometimes we don't call CORINFO_HELP_VIRTUAL_FUNC_PTR but instead just call
+ // CORINFO_HELP_RUNTIMEHANDLE_METHOD directly.
+ else if (oper == GT_QMARK)
+ {
+ qmarkNode = targetMethod;
+ }
+ if (qmarkNode)
+ {
+ noway_assert(qmarkNode->OperGet() == GT_QMARK);
+ // The argument is actually a generic dictionary lookup. For delegate creation it looks
+ // like:
+ // GT_QMARK
+ // GT_COLON
+ // op1 -> call
+ // Arg 1 -> token (has compile time handle)
+ // op2 -> lclvar
+ //
+ //
+ // In this case I can find the token (which is a method handle) and that is the compile time
+ // handle.
+ noway_assert(qmarkNode->gtOp.gtOp2->OperGet() == GT_COLON);
+ noway_assert(qmarkNode->gtOp.gtOp2->gtOp.gtOp1->OperGet() == GT_CALL);
+ GenTreeCall* runtimeLookupCall = qmarkNode->gtOp.gtOp2->gtOp.gtOp1->AsCall();
+
+ // This could be any of CORINFO_HELP_RUNTIMEHANDLE_(METHOD|CLASS)(_LOG?)
+ GenTreePtr tokenNode = runtimeLookupCall->gtCallArgs->gtOp.gtOp2->gtOp.gtOp1;
+ noway_assert(tokenNode->OperGet() == GT_CNS_INT);
+ targetMethodHnd = CORINFO_METHOD_HANDLE(tokenNode->gtIntCon.gtCompileTimeHandle);
+ }
#ifdef FEATURE_READYTORUN_COMPILER
- if (opts.IsReadyToRun())
+ if (opts.IsReadyToRun())
+ {
+ if (IsTargetAbi(CORINFO_CORERT_ABI))
{
- // ReadyToRun has this optimization for a non-virtual function pointers only for now.
- if (oper == GT_FTN_ADDR)
+ if (ldftnToken != nullptr)
{
- // The first argument of the helper is delegate this pointer
- GenTreeArgList* helperArgs = gtNewArgList(call->gtCall.gtCallObjp);
+ GenTreePtr thisPointer = call->gtCallObjp;
+ GenTreePtr targetObjPointers = call->gtCallArgs->Current();
+ GenTreeArgList* helperArgs = nullptr;
+ CORINFO_LOOKUP pLookup;
CORINFO_CONST_LOOKUP entryPoint;
-
- // The second argument of the helper is the target object pointers
- helperArgs->gtOp.gtOp2 = gtNewArgList(call->gtCall.gtCallArgs->gtOp.gtOp1);
-
+ info.compCompHnd->getReadyToRunDelegateCtorHelper(ldftnToken, clsHnd, &pLookup);
+ if (!pLookup.lookupKind.needsRuntimeLookup)
+ {
+ helperArgs = gtNewArgList(thisPointer, targetObjPointers);
+ entryPoint = pLookup.constLookup;
+ }
+ else
+ {
+ assert(oper != GT_FTN_ADDR);
+ CORINFO_CONST_LOOKUP genericLookup;
+ info.compCompHnd->getReadyToRunHelper(ldftnToken, &pLookup.lookupKind,
+ CORINFO_HELP_READYTORUN_GENERIC_HANDLE, &genericLookup);
+ GenTreePtr ctxTree = getRuntimeContextTree(pLookup.lookupKind.runtimeLookupKind);
+ helperArgs = gtNewArgList(thisPointer, targetObjPointers, ctxTree);
+ entryPoint = genericLookup;
+ }
call = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_DELEGATE_CTOR, TYP_VOID, GTF_EXCEPT, helperArgs);
-#if COR_JIT_EE_VERSION > 460
- info.compCompHnd->getReadyToRunDelegateCtorHelper(targetMethod->gtFptrVal.gtLdftnResolvedToken, clsHnd,
- &entryPoint);
-#else
- info.compCompHnd->getReadyToRunHelper(targetMethod->gtFptrVal.gtLdftnResolvedToken,
- CORINFO_HELP_READYTORUN_DELEGATE_CTOR, &entryPoint);
-#endif
- call->gtCall.setEntryPoint(entryPoint);
+ call->setEntryPoint(entryPoint);
}
}
- else
-#endif
- if (targetMethodHnd != nullptr)
+ // ReadyToRun has this optimization for a non-virtual function pointers only for now.
+ else if (oper == GT_FTN_ADDR)
{
- CORINFO_METHOD_HANDLE alternateCtor = nullptr;
- DelegateCtorArgs ctorData;
- ctorData.pMethod = info.compMethodHnd;
- ctorData.pArg3 = nullptr;
- ctorData.pArg4 = nullptr;
- ctorData.pArg5 = nullptr;
+ GenTreePtr thisPointer = call->gtCallObjp;
+ GenTreePtr targetObjPointers = call->gtCallArgs->Current();
+ GenTreeArgList* helperArgs = gtNewArgList(thisPointer, targetObjPointers);
- alternateCtor = info.compCompHnd->GetDelegateCtor(methHnd, clsHnd, targetMethodHnd, &ctorData);
- if (alternateCtor != methHnd)
- {
- // we erase any inline info that may have been set for generics has it is not needed here,
- // and in fact it will pass the wrong info to the inliner code
- *ExactContextHnd = nullptr;
+ call = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_DELEGATE_CTOR, TYP_VOID, GTF_EXCEPT, helperArgs);
- call->gtCall.gtCallMethHnd = alternateCtor;
+ CORINFO_LOOKUP entryPoint;
+ info.compCompHnd->getReadyToRunDelegateCtorHelper(ldftnToken, clsHnd, &entryPoint);
+ assert(!entryPoint.lookupKind.needsRuntimeLookup);
+ call->setEntryPoint(entryPoint.constLookup);
+ }
+ }
+ else
+#endif
+ if (targetMethodHnd != nullptr)
+ {
+ CORINFO_METHOD_HANDLE alternateCtor = nullptr;
+ DelegateCtorArgs ctorData;
+ ctorData.pMethod = info.compMethodHnd;
+ ctorData.pArg3 = nullptr;
+ ctorData.pArg4 = nullptr;
+ ctorData.pArg5 = nullptr;
- noway_assert(call->gtCall.gtCallArgs->gtOp.gtOp2->gtOp.gtOp2 == nullptr);
- if (ctorData.pArg3)
- {
- call->gtCall.gtCallArgs->gtOp.gtOp2->gtOp.gtOp2 =
- gtNewArgList(gtNewIconHandleNode(size_t(ctorData.pArg3), GTF_ICON_FTN_ADDR));
+ alternateCtor = info.compCompHnd->GetDelegateCtor(methHnd, clsHnd, targetMethodHnd, &ctorData);
+ if (alternateCtor != methHnd)
+ {
+ // we erase any inline info that may have been set for generics has it is not needed here,
+ // and in fact it will pass the wrong info to the inliner code
+ *ExactContextHnd = nullptr;
- if (ctorData.pArg4)
- {
- call->gtCall.gtCallArgs->gtOp.gtOp2->gtOp.gtOp2->gtOp.gtOp2 =
- gtNewArgList(gtNewIconHandleNode(size_t(ctorData.pArg4), GTF_ICON_FTN_ADDR));
+ call->gtCallMethHnd = alternateCtor;
- if (ctorData.pArg5)
- {
- call->gtCall.gtCallArgs->gtOp.gtOp2->gtOp.gtOp2->gtOp.gtOp2->gtOp.gtOp2 =
- gtNewArgList(gtNewIconHandleNode(size_t(ctorData.pArg5), GTF_ICON_FTN_ADDR));
- }
- }
- }
+ noway_assert(call->gtCallArgs->Rest()->Rest() == nullptr);
+ GenTreeArgList* addArgs = nullptr;
+ if (ctorData.pArg5)
+ {
+ GenTreePtr arg5 = gtNewIconHandleNode(size_t(ctorData.pArg5), GTF_ICON_FTN_ADDR);
+ addArgs = gtNewListNode(arg5, addArgs);
+ }
+ if (ctorData.pArg4)
+ {
+ GenTreePtr arg4 = gtNewIconHandleNode(size_t(ctorData.pArg4), GTF_ICON_FTN_ADDR);
+ addArgs = gtNewListNode(arg4, addArgs);
+ }
+ if (ctorData.pArg3)
+ {
+ GenTreePtr arg3 = gtNewIconHandleNode(size_t(ctorData.pArg3), GTF_ICON_FTN_ADDR);
+ addArgs = gtNewListNode(arg3, addArgs);
}
+ call->gtCallArgs->Rest()->Rest() = addArgs;
}
}
-
return call;
}
@@ -7478,7 +7586,7 @@ GenTreePtr Compiler::fgGetCritSectOfStaticMethod()
// Collectible types requires that for shared generic code, if we use the generic context paramter
// that we report it. (This is a conservative approach, we could detect some cases particularly when the
// context parameter is this that we don't need the eager reporting logic.)
- lvaGenericsContextUsed = true;
+ lvaGenericsContextUseCount++;
switch (kind.runtimeLookupKind)
{
@@ -7522,7 +7630,7 @@ GenTreePtr Compiler::fgGetCritSectOfStaticMethod()
return tree;
}
-#if !defined(_TARGET_X86_)
+#if FEATURE_EH_FUNCLETS
/*****************************************************************************
*
@@ -7614,8 +7722,15 @@ void Compiler::fgAddSyncMethodEnterExit()
assert(fgFirstBB->bbFallsThrough());
BasicBlock* tryBegBB = fgNewBBafter(BBJ_NONE, fgFirstBB, false);
+ BasicBlock* tryNextBB = tryBegBB->bbNext;
BasicBlock* tryLastBB = fgLastBB;
+ // If we have profile data the new block will inherit the next block's weight
+ if (tryNextBB->hasProfileWeight())
+ {
+ tryBegBB->inheritWeight(tryNextBB);
+ }
+
// Create a block for the fault.
assert(!tryLastBB->bbFallsThrough());
@@ -7890,7 +8005,7 @@ void Compiler::fgConvertSyncReturnToLeave(BasicBlock* block)
#endif
}
-#endif // !_TARGET_X86_
+#endif // FEATURE_EH_FUNCLETS
//------------------------------------------------------------------------
// fgAddReversePInvokeEnterExit: Add enter/exit calls for reverse PInvoke methods
@@ -7905,7 +8020,6 @@ void Compiler::fgAddReversePInvokeEnterExit()
{
assert(opts.IsReversePInvoke());
-#if COR_JIT_EE_VERSION > 460
lvaReversePInvokeFrameVar = lvaGrabTempWithImplicitUse(false DEBUGARG("Reverse Pinvoke FrameVar"));
LclVarDsc* varDsc = &lvaTable[lvaReversePInvokeFrameVar];
@@ -7952,8 +8066,6 @@ void Compiler::fgAddReversePInvokeEnterExit()
printf("\n");
}
#endif
-
-#endif // COR_JIT_EE_VERSION > 460
}
/*****************************************************************************
@@ -7989,6 +8101,16 @@ void Compiler::fgAddInternal()
{
noway_assert(!compIsForInlining());
+#ifndef LEGACY_BACKEND
+ // The RyuJIT backend requires a scratch BB into which it can safely insert a P/Invoke method prolog if one is
+ // required. Create it here.
+ if (info.compCallUnmanaged != 0)
+ {
+ fgEnsureFirstBBisScratch();
+ fgFirstBB->bbFlags |= BBF_DONT_REMOVE;
+ }
+#endif // !LEGACY_BACKEND
+
/*
<BUGNUM> VSW441487 </BUGNUM>
@@ -8017,8 +8139,8 @@ void Compiler::fgAddInternal()
lva0CopiedForGenericsCtxt = false;
#endif // JIT32_GCENCODER
noway_assert(lva0CopiedForGenericsCtxt || !lvaTable[info.compThisArg].lvAddrExposed);
- noway_assert(!lvaTable[info.compThisArg].lvArgWrite);
- noway_assert(lvaTable[lvaArg0Var].lvAddrExposed || lvaTable[lvaArg0Var].lvArgWrite ||
+ noway_assert(!lvaTable[info.compThisArg].lvHasILStoreOp);
+ noway_assert(lvaTable[lvaArg0Var].lvAddrExposed || lvaTable[lvaArg0Var].lvHasILStoreOp ||
lva0CopiedForGenericsCtxt);
var_types thisType = lvaTable[info.compThisArg].TypeGet();
@@ -8107,7 +8229,7 @@ void Compiler::fgAddInternal()
// If all BBJ_RETURN blocks have a valid profiled weights
// then allProfWeight will be true, else it is false
//
- if ((block->bbFlags & BBF_PROF_WEIGHT) == 0)
+ if (!block->hasProfileWeight())
{
allProfWeight = false;
}
@@ -8144,7 +8266,7 @@ void Compiler::fgAddInternal()
}
}
-#if !defined(_TARGET_X86_)
+#if FEATURE_EH_FUNCLETS
// Add the synchronized method enter/exit calls and try/finally protection. Note
// that this must happen before the one BBJ_RETURN block is created below, so the
// BBJ_RETURN block gets placed at the top-level, not within an EH region. (Otherwise,
@@ -8154,7 +8276,7 @@ void Compiler::fgAddInternal()
{
fgAddSyncMethodEnterExit();
}
-#endif // !_TARGET_X86_
+#endif // FEATURE_EH_FUNCLETS
if (oneReturn)
{
@@ -8373,7 +8495,7 @@ void Compiler::fgAddInternal()
#endif
}
-#if defined(_TARGET_X86_)
+#if !FEATURE_EH_FUNCLETS
/* Is this a 'synchronized' method? */
@@ -8449,7 +8571,7 @@ void Compiler::fgAddInternal()
syncEndEmitCookie = NULL;
}
-#endif // _TARGET_X86_
+#endif // !FEATURE_EH_FUNCLETS
/* Do we need to do runtime call out to check the security? */
@@ -8937,12 +9059,29 @@ void Compiler::fgFindOperOrder()
}
}
-/*****************************************************************************/
+//------------------------------------------------------------------------
+// fgSimpleLowering: do full walk of all IR, lowering selected operations
+// and computing lvaOutgoingArgumentAreaSize.
+//
+// Notes:
+// Lowers GT_ARR_LENGTH, GT_ARR_BOUNDS_CHECK, and GT_SIMD_CHK.
+//
+// For target ABIs with fixed out args area, computes upper bound on
+// the size of this area from the calls in the IR.
+//
+// Outgoing arg area size is computed here because we want to run it
+// after optimization (in case calls are removed) and need to look at
+// all possible calls in the method.
+
void Compiler::fgSimpleLowering()
{
+#if FEATURE_FIXED_OUT_ARGS
+ unsigned outgoingArgSpaceSize = 0;
+#endif // FEATURE_FIXED_OUT_ARGS
+
for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
{
- // Walk the statement trees in this basic block, converting ArrLength nodes.
+ // Walk the statement trees in this basic block.
compCurBB = block; // Used in fgRngChkTarget.
#ifdef LEGACY_BACKEND
@@ -8956,74 +9095,155 @@ void Compiler::fgSimpleLowering()
{
{
#endif
- if (tree->gtOper == GT_ARR_LENGTH)
+
+ switch (tree->OperGet())
{
- GenTreeArrLen* arrLen = tree->AsArrLen();
- GenTreePtr arr = arrLen->gtArrLen.ArrRef();
- GenTreePtr add;
- GenTreePtr con;
+ case GT_ARR_LENGTH:
+ {
+ GenTreeArrLen* arrLen = tree->AsArrLen();
+ GenTreePtr arr = arrLen->gtArrLen.ArrRef();
+ GenTreePtr add;
+ GenTreePtr con;
- /* Create the expression "*(array_addr + ArrLenOffs)" */
+ /* Create the expression "*(array_addr + ArrLenOffs)" */
- noway_assert(arr->gtNext == tree);
+ noway_assert(arr->gtNext == tree);
- noway_assert(arrLen->ArrLenOffset() == offsetof(CORINFO_Array, length) ||
- arrLen->ArrLenOffset() == offsetof(CORINFO_String, stringLen));
+ noway_assert(arrLen->ArrLenOffset() == offsetof(CORINFO_Array, length) ||
+ arrLen->ArrLenOffset() == offsetof(CORINFO_String, stringLen));
- if ((arr->gtOper == GT_CNS_INT) && (arr->gtIntCon.gtIconVal == 0))
- {
- // If the array is NULL, then we should get a NULL reference
- // exception when computing its length. We need to maintain
- // an invariant where there is no sum of two constants node, so
- // let's simply return an indirection of NULL.
+ if ((arr->gtOper == GT_CNS_INT) && (arr->gtIntCon.gtIconVal == 0))
+ {
+ // If the array is NULL, then we should get a NULL reference
+ // exception when computing its length. We need to maintain
+ // an invariant where there is no sum of two constants node, so
+ // let's simply return an indirection of NULL.
- add = arr;
- }
- else
- {
- con = gtNewIconNode(arrLen->ArrLenOffset(), TYP_I_IMPL);
- con->gtRsvdRegs = 0;
+ add = arr;
+ }
+ else
+ {
+ con = gtNewIconNode(arrLen->ArrLenOffset(), TYP_I_IMPL);
+ con->gtRsvdRegs = 0;
- add = gtNewOperNode(GT_ADD, TYP_REF, arr, con);
- add->gtRsvdRegs = arr->gtRsvdRegs;
+ add = gtNewOperNode(GT_ADD, TYP_REF, arr, con);
+ add->gtRsvdRegs = arr->gtRsvdRegs;
#ifdef LEGACY_BACKEND
- con->gtCopyFPlvl(arr);
+ con->gtCopyFPlvl(arr);
- add->gtCopyFPlvl(arr);
- add->CopyCosts(arr);
+ add->gtCopyFPlvl(arr);
+ add->CopyCosts(arr);
- arr->gtNext = con;
- con->gtPrev = arr;
+ arr->gtNext = con;
+ con->gtPrev = arr;
- con->gtNext = add;
- add->gtPrev = con;
+ con->gtNext = add;
+ add->gtPrev = con;
- add->gtNext = tree;
- tree->gtPrev = add;
+ add->gtNext = tree;
+ tree->gtPrev = add;
#else
- range.InsertAfter(arr, con, add);
+ range.InsertAfter(arr, con, add);
#endif
- }
+ }
- // Change to a GT_IND.
- tree->ChangeOperUnchecked(GT_IND);
+ // Change to a GT_IND.
+ tree->ChangeOperUnchecked(GT_IND);
- tree->gtOp.gtOp1 = add;
- }
- else if (tree->OperGet() == GT_ARR_BOUNDS_CHECK
+ tree->gtOp.gtOp1 = add;
+ break;
+ }
+
+ case GT_ARR_BOUNDS_CHECK:
#ifdef FEATURE_SIMD
- || tree->OperGet() == GT_SIMD_CHK
+ case GT_SIMD_CHK:
#endif // FEATURE_SIMD
- )
- {
- // Add in a call to an error routine.
- fgSetRngChkTarget(tree, false);
+ {
+ // Add in a call to an error routine.
+ fgSetRngChkTarget(tree, false);
+ break;
+ }
+
+#if FEATURE_FIXED_OUT_ARGS
+ case GT_CALL:
+ {
+ GenTreeCall* call = tree->AsCall();
+ // Fast tail calls use the caller-supplied scratch
+ // space so have no impact on this method's outgoing arg size.
+ if (!call->IsFastTailCall())
+ {
+ // Update outgoing arg size to handle this call
+ const unsigned thisCallOutAreaSize = call->fgArgInfo->GetOutArgSize();
+ assert(thisCallOutAreaSize >= MIN_ARG_AREA_FOR_CALL);
+
+ if (thisCallOutAreaSize > outgoingArgSpaceSize)
+ {
+ outgoingArgSpaceSize = thisCallOutAreaSize;
+ JITDUMP("Bumping outgoingArgSpaceSize to %u for call [%06d]\n", outgoingArgSpaceSize,
+ dspTreeID(tree));
+ }
+ else
+ {
+ JITDUMP("outgoingArgSpaceSize %u sufficient for call [%06d], which needs %u\n",
+ outgoingArgSpaceSize, dspTreeID(tree), thisCallOutAreaSize);
+ }
+ }
+ else
+ {
+ JITDUMP("outgoingArgSpaceSize not impacted by fast tail call [%06d]\n", dspTreeID(tree));
+ }
+ break;
+ }
+#endif // FEATURE_FIXED_OUT_ARGS
+
+ default:
+ {
+ // No other operators need processing.
+ break;
+ }
}
- }
+ } // foreach gtNext
+ } // foreach Stmt
+ } // foreach BB
+
+#if FEATURE_FIXED_OUT_ARGS
+ // Finish computing the outgoing args area size
+ //
+ // Need to make sure the MIN_ARG_AREA_FOR_CALL space is added to the frame if:
+ // 1. there are calls to THROW_HEPLPER methods.
+ // 2. we are generating profiling Enter/Leave/TailCall hooks. This will ensure
+ // that even methods without any calls will have outgoing arg area space allocated.
+ //
+ // An example for these two cases is Windows Amd64, where the ABI requires to have 4 slots for
+ // the outgoing arg space if the method makes any calls.
+ if (outgoingArgSpaceSize < MIN_ARG_AREA_FOR_CALL)
+ {
+ if (compUsesThrowHelper || compIsProfilerHookNeeded())
+ {
+ outgoingArgSpaceSize = MIN_ARG_AREA_FOR_CALL;
+ JITDUMP("Bumping outgoingArgSpaceSize to %u for throw helper or profile hook", outgoingArgSpaceSize);
}
}
+ // If a function has localloc, we will need to move the outgoing arg space when the
+ // localloc happens. When we do this, we need to maintain stack alignment. To avoid
+ // leaving alignment-related holes when doing this move, make sure the outgoing
+ // argument space size is a multiple of the stack alignment by aligning up to the next
+ // stack alignment boundary.
+ if (compLocallocUsed)
+ {
+ outgoingArgSpaceSize = (unsigned)roundUp(outgoingArgSpaceSize, STACK_ALIGN);
+ JITDUMP("Bumping outgoingArgSpaceSize to %u for localloc", outgoingArgSpaceSize);
+ }
+
+ // Publish the final value and mark it as read only so any update
+ // attempt later will cause an assert.
+ lvaOutgoingArgSpaceSize = outgoingArgSpaceSize;
+ lvaOutgoingArgSpaceSize.MarkAsReadOnly();
+
+#endif // FEATURE_FIXED_OUT_ARGS
+
#ifdef DEBUG
if (verbose && fgRngChkThrowAdded)
{
@@ -9695,8 +9915,7 @@ void Compiler::fgCompactBlocks(BasicBlock* block, BasicBlock* bNext)
// or if both block and bNext have non-zero weights
// then we select the highest weight block.
- if ((block->bbFlags & BBF_PROF_WEIGHT) || (bNext->bbFlags & BBF_PROF_WEIGHT) ||
- (block->bbWeight && bNext->bbWeight))
+ if (block->hasProfileWeight() || bNext->hasProfileWeight() || (block->bbWeight && bNext->bbWeight))
{
// We are keeping block so update its fields
// when bNext has a greater weight
@@ -11001,7 +11220,7 @@ bool Compiler::fgExpandRarelyRunBlocks()
NEW_RARELY_RUN:
/* If the weight of the block was obtained from a profile run,
than it's more accurate than our static analysis */
- if (bPrev->bbFlags & BBF_PROF_WEIGHT)
+ if (bPrev->hasProfileWeight())
{
continue;
}
@@ -11187,10 +11406,10 @@ bool Compiler::fgExpandRarelyRunBlocks()
// if bPrev->bbWeight is not based upon profile data we can adjust
// the weights of bPrev and block
//
- else if (bPrev->isBBCallAlwaysPair() && // we must have a BBJ_CALLFINALLY and BBK_ALWAYS pair
- (bPrev->bbWeight != block->bbWeight) && // the weights are currently different
- ((bPrev->bbFlags & BBF_PROF_WEIGHT) == 0)) // and the BBJ_CALLFINALLY block is not using profiled
- // weights
+ else if (bPrev->isBBCallAlwaysPair() && // we must have a BBJ_CALLFINALLY and BBK_ALWAYS pair
+ (bPrev->bbWeight != block->bbWeight) && // the weights are currently different
+ !bPrev->hasProfileWeight()) // and the BBJ_CALLFINALLY block is not using profiled
+ // weights
{
if (block->isRunRarely())
{
@@ -12126,7 +12345,8 @@ bool Compiler::fgRelocateEHRegions()
}
// Currently it is not good to move the rarely run handler regions to the end of the method
- // because fgDetermineFirstColdBlock() must put the start of any handler region in the hot section.
+ // because fgDetermineFirstColdBlock() must put the start of any handler region in the hot
+ // section.
CLANG_FORMAT_COMMENT_ANCHOR;
#if 0
@@ -12356,7 +12576,7 @@ void Compiler::fgPrintEdgeWeights()
if (edge->flEdgeWeightMin < BB_MAX_WEIGHT)
{
- printf("(%s", refCntWtd2str(edge->flEdgeWeightMin));
+ printf("(%u", edge->flEdgeWeightMin);
}
else
{
@@ -12366,7 +12586,7 @@ void Compiler::fgPrintEdgeWeights()
{
if (edge->flEdgeWeightMax < BB_MAX_WEIGHT)
{
- printf("..%s", refCntWtd2str(edge->flEdgeWeightMax));
+ printf("..%u", edge->flEdgeWeightMax);
}
else
{
@@ -12429,7 +12649,7 @@ void Compiler::fgComputeEdgeWeights()
}
#endif // DEBUG
fgHaveValidEdgeWeights = false;
- fgCalledWeight = BB_UNITY_WEIGHT;
+ fgCalledCount = BB_UNITY_WEIGHT;
}
#if DEBUG
@@ -12468,7 +12688,7 @@ void Compiler::fgComputeEdgeWeights()
for (bDst = fgFirstBB; bDst != nullptr; bDst = bDst->bbNext)
{
- if (((bDst->bbFlags & BBF_PROF_WEIGHT) == 0) && (bDst->bbPreds != nullptr))
+ if (!bDst->hasProfileWeight() && (bDst->bbPreds != nullptr))
{
BasicBlock* bOnlyNext;
@@ -12495,7 +12715,7 @@ void Compiler::fgComputeEdgeWeights()
bOnlyNext = nullptr;
}
- if ((bOnlyNext == bDst) && ((bSrc->bbFlags & BBF_PROF_WEIGHT) != 0))
+ if ((bOnlyNext == bDst) && bSrc->hasProfileWeight())
{
// We know the exact weight of bDst
newWeight = bSrc->bbWeight;
@@ -12547,8 +12767,7 @@ void Compiler::fgComputeEdgeWeights()
// Sum up the weights of all of the return blocks and throw blocks
// This is used when we have a back-edge into block 1
//
- if (((bDst->bbFlags & BBF_PROF_WEIGHT) != 0) &&
- ((bDst->bbJumpKind == BBJ_RETURN) || (bDst->bbJumpKind == BBJ_THROW)))
+ if (bDst->hasProfileWeight() && ((bDst->bbJumpKind == BBJ_RETURN) || (bDst->bbJumpKind == BBJ_THROW)))
{
returnWeight += bDst->bbWeight;
}
@@ -12568,25 +12787,57 @@ void Compiler::fgComputeEdgeWeights()
}
#endif
- // When we are not using profile data we have already setup fgCalledWeight
+ // When we are not using profile data we have already setup fgCalledCount
// only set it here if we are using profile data
//
if (fgIsUsingProfileWeights())
{
- // If the first block has one ref then it's weight is the fgCalledWeight
- // otherwise we have backedge's into the first block so instead
- // we use the sum of the return block weights.
- // If the profile data has a 0 for the returnWeoght
- // then just use the first block weight rather than the 0
+ BasicBlock* firstILBlock = fgFirstBB; // The first block for IL code (i.e. for the IL code at offset 0)
+
+ // Do we have an internal block as our first Block?
+ if (firstILBlock->bbFlags & BBF_INTERNAL)
+ {
+ // Skip past any/all BBF_INTERNAL blocks that may have been added before the first real IL block.
+ //
+ while (firstILBlock->bbFlags & BBF_INTERNAL)
+ {
+ firstILBlock = firstILBlock->bbNext;
+ }
+ // The 'firstILBlock' is now expected to have a profile-derived weight
+ assert(firstILBlock->hasProfileWeight());
+ }
+
+ // If the first block only has one ref then we use it's weight for fgCalledCount.
+ // Otherwise we have backedge's into the first block, so instead we use the sum
+ // of the return block weights for fgCalledCount.
+ //
+ // If the profile data has a 0 for the returnWeight
+ // (i.e. the function never returns because it always throws)
+ // then just use the first block weight rather than 0.
//
- if ((fgFirstBB->countOfInEdges() == 1) || (returnWeight == 0))
+ if ((firstILBlock->countOfInEdges() == 1) || (returnWeight == 0))
{
- fgCalledWeight = fgFirstBB->bbWeight;
+ assert(firstILBlock->hasProfileWeight()); // This should always be a profile-derived weight
+ fgCalledCount = firstILBlock->bbWeight;
}
else
{
- fgCalledWeight = returnWeight;
+ fgCalledCount = returnWeight;
}
+
+ // If we allocated a scratch block as the first BB then we need
+ // to set its profile-derived weight to be fgCalledCount
+ if (fgFirstBBisScratch())
+ {
+ fgFirstBB->setBBProfileWeight(fgCalledCount);
+ }
+
+#if DEBUG
+ if (verbose)
+ {
+ printf("We are using the Profile Weights and fgCalledCount is %d.\n", fgCalledCount);
+ }
+#endif
}
// Now we will compute the initial flEdgeWeightMin and flEdgeWeightMax values
@@ -12599,7 +12850,7 @@ void Compiler::fgComputeEdgeWeights()
//
if (bDst == fgFirstBB)
{
- bDstWeight -= fgCalledWeight;
+ bDstWeight -= fgCalledCount;
}
for (edge = bDst->bbPreds; edge != nullptr; edge = edge->flNext)
@@ -12616,7 +12867,7 @@ void Compiler::fgComputeEdgeWeights()
// then we must reset any values that they currently have
//
- if (((bSrc->bbFlags & BBF_PROF_WEIGHT) == 0) || ((bDst->bbFlags & BBF_PROF_WEIGHT) == 0))
+ if (!bSrc->hasProfileWeight() || !bDst->hasProfileWeight())
{
edge->flEdgeWeightMin = BB_ZERO_WEIGHT;
edge->flEdgeWeightMax = BB_MAX_WEIGHT;
@@ -12764,7 +13015,7 @@ void Compiler::fgComputeEdgeWeights()
//
if (bDst == fgFirstBB)
{
- bDstWeight -= fgCalledWeight;
+ bDstWeight -= fgCalledCount;
}
UINT64 minEdgeWeightSum = 0;
@@ -13000,7 +13251,7 @@ bool Compiler::fgOptimizeBranchToEmptyUnconditional(BasicBlock* block, BasicBloc
// When we optimize a branch to branch we need to update the profile weight
// of bDest by subtracting out the block/edge weight of the path that is being optimized.
//
- if (fgHaveValidEdgeWeights && ((bDest->bbFlags & BBF_PROF_WEIGHT) != 0))
+ if (fgHaveValidEdgeWeights && bDest->hasProfileWeight())
{
flowList* edge1 = fgGetPredForBlock(bDest, block);
noway_assert(edge1 != nullptr);
@@ -13333,7 +13584,7 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block)
// When we optimize a branch to branch we need to update the profile weight
// of bDest by subtracting out the block/edge weight of the path that is being optimized.
//
- if (fgIsUsingProfileWeights() && ((bDest->bbFlags & BBF_PROF_WEIGHT) != 0))
+ if (fgIsUsingProfileWeights() && bDest->hasProfileWeight())
{
if (fgHaveValidEdgeWeights)
{
@@ -13718,10 +13969,9 @@ bool Compiler::fgOptimizeUncondBranchToSimpleCond(BasicBlock* block, BasicBlock*
// add an unconditional block after this block to jump to the target block's fallthrough block
BasicBlock* next = fgNewBBafter(BBJ_ALWAYS, block, true);
- next->bbFlags = block->bbFlags | BBF_INTERNAL;
- next->bbFlags &= ~(BBF_TRY_BEG | BBF_LOOP_HEAD | BBF_LOOP_CALL0 | BBF_LOOP_CALL1 | BBF_HAS_LABEL | BBF_JMP_TARGET |
- BBF_FUNCLET_BEG | BBF_LOOP_PREHEADER | BBF_KEEP_BBJ_ALWAYS);
+ // The new block 'next' will inherit its weight from 'block'
+ next->inheritWeight(block);
next->bbJumpDest = target->bbNext;
target->bbNext->bbFlags |= BBF_JMP_TARGET;
fgAddRefPred(next, block);
@@ -14410,8 +14660,7 @@ void Compiler::fgReorderBlocks()
BasicBlock::weight_t profHotWeight = -1;
- if ((bPrev->bbFlags & BBF_PROF_WEIGHT) && (block->bbFlags & BBF_PROF_WEIGHT) &&
- ((bDest == nullptr) || (bDest->bbFlags & BBF_PROF_WEIGHT)))
+ if (bPrev->hasProfileWeight() && block->hasProfileWeight() && ((bDest == nullptr) || bDest->hasProfileWeight()))
{
//
// All blocks have profile information
@@ -17407,12 +17656,10 @@ unsigned Compiler::acdHelper(SpecialCodeKind codeKind)
{
case SCK_RNGCHK_FAIL:
return CORINFO_HELP_RNGCHKFAIL;
-#if COR_JIT_EE_VERSION > 460
case SCK_ARG_EXCPN:
return CORINFO_HELP_THROW_ARGUMENTEXCEPTION;
case SCK_ARG_RNG_EXCPN:
return CORINFO_HELP_THROW_ARGUMENTOUTOFRANGEEXCEPTION;
-#endif // COR_JIT_EE_VERSION
case SCK_DIV_BY_ZERO:
return CORINFO_HELP_THROWDIVZERO;
case SCK_ARITH_EXCPN:
@@ -17472,10 +17719,28 @@ BasicBlock* Compiler::fgAddCodeRef(BasicBlock* srcBlk, unsigned refData, Special
// this restriction could be removed with more careful code
// generation for BBJ_THROW (i.e. range check failed).
//
+ // For Linux/x86, we possibly need to insert stack alignment adjustment
+ // before the first stack argument pushed for every call. But we
+ // don't know what the stack alignment adjustment will be when
+ // we morph a tree that calls fgAddCodeRef(), so the stack depth
+ // number will be incorrect. For now, simply force all functions with
+ // these helpers to have EBP frames. It might be possible to make
+ // this less conservative. E.g., for top-level (not nested) calls
+ // without stack args, the stack pointer hasn't changed and stack
+ // depth will be known to be zero. Or, figure out a way to update
+ // or generate all required helpers after all stack alignment
+ // has been added, and the stack level at each call to fgAddCodeRef()
+ // is known, or can be recalculated.
+ CLANG_FORMAT_COMMENT_ANCHOR;
+
+#if defined(UNIX_X86_ABI)
+ codeGen->setFrameRequired(true);
+#else // !defined(UNIX_X86_ABI)
if (add->acdStkLvl != stkDepth)
{
codeGen->setFrameRequired(true);
}
+#endif // !defined(UNIX_X86_ABI)
#endif // _TARGET_X86_
return add->acdDstBlk;
@@ -17539,14 +17804,12 @@ BasicBlock* Compiler::fgAddCodeRef(BasicBlock* srcBlk, unsigned refData, Special
case SCK_OVERFLOW:
msg = " for OVERFLOW";
break;
-#if COR_JIT_EE_VERSION > 460
case SCK_ARG_EXCPN:
msg = " for ARG_EXCPN";
break;
case SCK_ARG_RNG_EXCPN:
msg = " for ARG_RNG_EXCPN";
break;
-#endif // COR_JIT_EE_VERSION
default:
msg = " for ??";
break;
@@ -17593,7 +17856,6 @@ BasicBlock* Compiler::fgAddCodeRef(BasicBlock* srcBlk, unsigned refData, Special
noway_assert(SCK_OVERFLOW == SCK_ARITH_EXCPN);
break;
-#if COR_JIT_EE_VERSION > 460
case SCK_ARG_EXCPN:
helper = CORINFO_HELP_THROW_ARGUMENTEXCEPTION;
break;
@@ -17601,7 +17863,6 @@ BasicBlock* Compiler::fgAddCodeRef(BasicBlock* srcBlk, unsigned refData, Special
case SCK_ARG_RNG_EXCPN:
helper = CORINFO_HELP_THROW_ARGUMENTOUTOFRANGEEXCEPTION;
break;
-#endif // COR_JIT_EE_VERSION
// case SCK_PAUSE_EXEC:
// noway_assert(!"add code to pause exec");
@@ -18819,7 +19080,7 @@ FILE* Compiler::fgOpenFlowGraphFile(bool* wbDontClose, Phases phase, LPCWSTR typ
if (wcscmp(filename, W("profiled")) == 0)
{
- if ((fgFirstBB->bbFlags & BBF_PROF_WEIGHT) != 0)
+ if (fgFirstBB->hasProfileWeight())
{
createDuplicateFgxFiles = true;
goto ONE_FILE_PER_METHOD;
@@ -19009,7 +19270,7 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
return false;
}
bool validWeights = fgHaveValidEdgeWeights;
- unsigned calledCount = max(fgCalledWeight, BB_UNITY_WEIGHT) / BB_UNITY_WEIGHT;
+ unsigned calledCount = max(fgCalledCount, BB_UNITY_WEIGHT) / BB_UNITY_WEIGHT;
double weightDivisor = (double)(calledCount * BB_UNITY_WEIGHT);
const char* escapedString;
const char* regionString = "NONE";
@@ -19124,7 +19385,7 @@ bool Compiler::fgDumpFlowGraph(Phases phase)
{
fprintf(fgxFile, "\n inHandler=\"%s\"", "true");
}
- if (((fgFirstBB->bbFlags & BBF_PROF_WEIGHT) != 0) && ((block->bbFlags & BBF_COLD) == 0))
+ if ((fgFirstBB->hasProfileWeight()) && ((block->bbFlags & BBF_COLD) == 0))
{
fprintf(fgxFile, "\n hot=\"true\"");
}
@@ -19397,8 +19658,28 @@ void Compiler::fgTableDispBasicBlock(BasicBlock* block, int ibcColWidth /* = 0 *
}
else
{
- printf("%6s", refCntWtd2str(block->getBBWeight(this)));
+ BasicBlock::weight_t weight = block->getBBWeight(this);
+
+ if (weight > 99999) // Is it going to be more than 6 characters?
+ {
+ if (weight <= 99999 * BB_UNITY_WEIGHT)
+ {
+ // print weight in this format ddddd.
+ printf("%5u.", (weight + (BB_UNITY_WEIGHT / 2)) / BB_UNITY_WEIGHT);
+ }
+ else // print weight in terms of k (i.e. 156k )
+ {
+ // print weight in this format dddddk
+ BasicBlock::weight_t weightK = weight / 1000;
+ printf("%5uk", (weightK + (BB_UNITY_WEIGHT / 2)) / BB_UNITY_WEIGHT);
+ }
+ }
+ else // print weight in this format ddd.dd
+ {
+ printf("%6s", refCntWtd2str(weight));
+ }
}
+ printf(" ");
//
// Display optional IBC weight column.
@@ -19407,7 +19688,7 @@ void Compiler::fgTableDispBasicBlock(BasicBlock* block, int ibcColWidth /* = 0 *
if (ibcColWidth > 0)
{
- if (block->bbFlags & BBF_PROF_WEIGHT)
+ if (block->hasProfileWeight())
{
printf("%*u", ibcColWidth, block->bbWeight);
}
@@ -19661,7 +19942,7 @@ void Compiler::fgDispBasicBlocks(BasicBlock* firstBlock, BasicBlock* lastBlock,
int ibcColWidth = 0;
for (block = firstBlock; block != nullptr; block = block->bbNext)
{
- if (block->bbFlags & BBF_PROF_WEIGHT)
+ if (block->hasProfileWeight())
{
int thisIbcWidth = CountDigits(block->bbWeight);
ibcColWidth = max(ibcColWidth, thisIbcWidth);
@@ -19686,11 +19967,11 @@ void Compiler::fgDispBasicBlocks(BasicBlock* firstBlock, BasicBlock* lastBlock,
// clang-format off
printf("\n");
- printf("------%*s------------------------------------%*s-----------------------%*s----------------------------------------\n",
+ printf("------%*s-------------------------------------%*s-----------------------%*s----------------------------------------\n",
padWidth, "------------",
ibcColWidth, "------------",
maxBlockNumWidth, "----");
- printf("BBnum %*sdescAddr ref try hnd %s weight %*s%s [IL range] [jump]%*s [EH region] [flags]\n",
+ printf("BBnum %*sdescAddr ref try hnd %s weight %*s%s [IL range] [jump]%*s [EH region] [flags]\n",
padWidth, "",
fgCheapPredsValid ? "cheap preds" :
(fgComputePredsDone ? "preds "
@@ -19700,7 +19981,7 @@ void Compiler::fgDispBasicBlocks(BasicBlock* firstBlock, BasicBlock* lastBlock,
: ""),
maxBlockNumWidth, ""
);
- printf("------%*s------------------------------------%*s-----------------------%*s----------------------------------------\n",
+ printf("------%*s-------------------------------------%*s-----------------------%*s----------------------------------------\n",
padWidth, "------------",
ibcColWidth, "------------",
maxBlockNumWidth, "----");
@@ -19724,16 +20005,16 @@ void Compiler::fgDispBasicBlocks(BasicBlock* firstBlock, BasicBlock* lastBlock,
if (block == fgFirstColdBlock)
{
- printf("~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~~~"
- "~~~~~~~~~~~~~~~\n",
+ printf("~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~%*s~~~~~~~~~~~~~~~~~~~~~~~~"
+ "~~~~~~~~~~~~~~~~\n",
padWidth, "~~~~~~~~~~~~", ibcColWidth, "~~~~~~~~~~~~", maxBlockNumWidth, "~~~~");
}
#if FEATURE_EH_FUNCLETS
if (block == fgFirstFuncletBB)
{
- printf("++++++%*s++++++++++++++++++++++++++++++++++++%*s+++++++++++++++++++++++%*s+++++++++++++++++++++++++"
- "+++++++++++++++ funclets follow\n",
+ printf("++++++%*s+++++++++++++++++++++++++++++++++++++%*s+++++++++++++++++++++++%*s++++++++++++++++++++++++"
+ "++++++++++++++++ funclets follow\n",
padWidth, "++++++++++++", ibcColWidth, "++++++++++++", maxBlockNumWidth, "++++");
}
#endif // FEATURE_EH_FUNCLETS
@@ -19746,8 +20027,8 @@ void Compiler::fgDispBasicBlocks(BasicBlock* firstBlock, BasicBlock* lastBlock,
}
}
- printf("------%*s------------------------------------%*s-----------------------%*s---------------------------------"
- "-------\n",
+ printf("------%*s-------------------------------------%*s-----------------------%*s--------------------------------"
+ "--------\n",
padWidth, "------------", ibcColWidth, "------------", maxBlockNumWidth, "----");
if (dumpTrees)
@@ -20283,10 +20564,11 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */, bool checkBBRef
// Should never expose the address of arg 0 or write to arg 0.
// In addition, lvArg0Var should remain 0 if arg0 is not
// written to or address-exposed.
- noway_assert(compThisArgAddrExposedOK && !lvaTable[info.compThisArg].lvArgWrite &&
- (lvaArg0Var == info.compThisArg ||
- lvaArg0Var != info.compThisArg && (lvaTable[lvaArg0Var].lvAddrExposed ||
- lvaTable[lvaArg0Var].lvArgWrite || copiedForGenericsCtxt)));
+ noway_assert(
+ compThisArgAddrExposedOK && !lvaTable[info.compThisArg].lvHasILStoreOp &&
+ (lvaArg0Var == info.compThisArg ||
+ lvaArg0Var != info.compThisArg &&
+ (lvaTable[lvaArg0Var].lvAddrExposed || lvaTable[lvaArg0Var].lvHasILStoreOp || copiedForGenericsCtxt)));
}
}
@@ -20496,7 +20778,7 @@ void Compiler::fgDebugCheckFlags(GenTreePtr tree)
if ((treeFlags & GTF_EXCEPT) && !(chkFlags & GTF_EXCEPT))
{
- switch (eeGetHelperNum(tree->gtCall.gtCallMethHnd))
+ switch (eeGetHelperNum(call->gtCallMethHnd))
{
// Is this a helper call that can throw an exception ?
case CORINFO_HELP_LDIV:
@@ -21048,6 +21330,7 @@ void Compiler::fgInline()
}
// See if we need to replace the return value place holder.
+ // Also, see if this update enables further devirtualization.
fgWalkTreePre(&stmt->gtStmtExpr, fgUpdateInlineReturnExpressionPlaceHolder, (void*)this);
// See if stmt is of the form GT_COMMA(call, nop)
@@ -21319,11 +21602,46 @@ void Compiler::fgAttachStructInlineeToAsg(GenTreePtr tree, GenTreePtr child, COR
#endif // FEATURE_MULTIREG_RET
-/*****************************************************************************
- * Callback to replace the inline return expression place holder (GT_RET_EXPR)
- */
+//------------------------------------------------------------------------
+// fgUpdateInlineReturnExpressionPlaceHolder: callback to replace the
+// inline return expression placeholder.
+//
+// Arguments:
+// pTree -- pointer to tree to examine for updates
+// data -- context data for the tree walk
+//
+// Returns:
+// fgWalkResult indicating the walk should continue; that
+// is we wish to fully explore the tree.
+//
+// Notes:
+// Looks for GT_RET_EXPR nodes that arose from tree splitting done
+// during importation for inline candidates, and replaces them.
+//
+// For successful inlines, substitutes the return value expression
+// from the inline body for the GT_RET_EXPR.
+//
+// For failed inlines, rejoins the original call into the tree from
+// whence it was split during importation.
+//
+// The code doesn't actually know if the corresponding inline
+// succeeded or not; it relies on the fact that gtInlineCandidate
+// initially points back at the call and is modified in place to
+// the inlinee return expression if the inline is successful (see
+// tail end of fgInsertInlineeBlocks for the update of iciCall).
+//
+// If the parent of the GT_RET_EXPR is a virtual call,
+// devirtualization is attempted. This should only succeed in the
+// successful inline case, when the inlinee's return value
+// expression provides a better type than the return type of the
+// method. Note for failed inlines, the devirtualizer can only go
+// by the return type, and any devirtualization that type enabled
+// would have already happened during importation.
+//
+// If the return type is a struct type and we're on a platform
+// where structs can be returned in multiple registers, ensure the
+// call has a suitable parent.
-/* static */
Compiler::fgWalkResult Compiler::fgUpdateInlineReturnExpressionPlaceHolder(GenTreePtr* pTree, fgWalkData* data)
{
GenTreePtr tree = *pTree;
@@ -21369,6 +21687,41 @@ Compiler::fgWalkResult Compiler::fgUpdateInlineReturnExpressionPlaceHolder(GenTr
}
#endif // DEBUG
} while (tree->gtOper == GT_RET_EXPR);
+
+ // Now see if this return value expression feeds the 'this'
+ // object at a virtual call site.
+ //
+ // Note for void returns where the inline failed, the
+ // GT_RET_EXPR may be top-level.
+ //
+ // May miss cases where there are intermediaries between call
+ // and this, eg commas.
+ GenTreePtr parentTree = data->parent;
+
+ if ((parentTree != nullptr) && (parentTree->gtOper == GT_CALL))
+ {
+ GenTreeCall* call = parentTree->AsCall();
+ bool tryLateDevirt = call->IsVirtual() && (call->gtCallObjp == tree);
+
+#ifdef DEBUG
+ tryLateDevirt = tryLateDevirt && (JitConfig.JitEnableLateDevirtualization() == 1);
+#endif // DEBUG
+
+ if (tryLateDevirt)
+ {
+#ifdef DEBUG
+ if (comp->verbose)
+ {
+ printf("**** Late devirt opportunity\n");
+ comp->gtDispTree(call);
+ }
+#endif // DEBUG
+
+ CORINFO_CALL_INFO x = {};
+ x.hMethod = call->gtCallMethHnd;
+ comp->impDevirtualizeCall(call, tree, &x, nullptr);
+ }
+ }
}
#if FEATURE_MULTIREG_RET
@@ -21784,7 +22137,7 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
}
#endif // DEBUG
- // Append statements to unpin, if necessary.
+ // Append statements to null out gc ref locals, if necessary.
fgInlineAppendStatements(pInlineInfo, iciBlock, stmtAfter);
goto _Done;
@@ -21954,7 +22307,7 @@ void Compiler::fgInsertInlineeBlocks(InlineInfo* pInlineInfo)
//
fgBBcount += InlineeCompiler->fgBBcount;
- // Append statements to unpin if necessary.
+ // Append statements to null out gc ref locals, if necessary.
fgInlineAppendStatements(pInlineInfo, bottomBlock, nullptr);
#ifdef DEBUG
@@ -22009,7 +22362,7 @@ _Done:
// If there is non-NULL return, replace the GT_CALL with its return value expression,
// so later it will be picked up by the GT_RET_EXPR node.
- if ((pInlineInfo->inlineCandidateInfo->fncRetType != TYP_VOID) || (iciCall->gtCall.gtReturnType == TYP_STRUCT))
+ if ((pInlineInfo->inlineCandidateInfo->fncRetType != TYP_VOID) || (iciCall->gtReturnType == TYP_STRUCT))
{
noway_assert(pInlineInfo->retExpr);
#ifdef DEBUG
@@ -22062,7 +22415,7 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
GenTreeStmt* postStmt = callStmt->gtNextStmt;
GenTreePtr afterStmt = callStmt; // afterStmt is the place where the new statements should be inserted after.
GenTreePtr newStmt = nullptr;
- GenTreePtr call = inlineInfo->iciCall;
+ GenTreeCall* call = inlineInfo->iciCall->AsCall();
noway_assert(call->gtOper == GT_CALL);
@@ -22115,9 +22468,13 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
for (unsigned argNum = 0; argNum < inlineInfo->argCnt; argNum++)
{
- if (inlArgInfo[argNum].argHasTmp)
+ const InlArgInfo& argInfo = inlArgInfo[argNum];
+ const bool argIsSingleDef = !argInfo.argHasLdargaOp && !argInfo.argHasStargOp;
+ GenTree* const argNode = inlArgInfo[argNum].argNode;
+
+ if (argInfo.argHasTmp)
{
- noway_assert(inlArgInfo[argNum].argIsUsed);
+ noway_assert(argInfo.argIsUsed);
/* argBashTmpNode is non-NULL iff the argument's value was
referenced exactly once by the original IL. This offers an
@@ -22131,27 +22488,29 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
once) but the optimization cannot be applied.
*/
- GenTreePtr argSingleUseNode = inlArgInfo[argNum].argBashTmpNode;
+ GenTreePtr argSingleUseNode = argInfo.argBashTmpNode;
- if (argSingleUseNode && !(argSingleUseNode->gtFlags & GTF_VAR_CLONED) &&
- !inlArgInfo[argNum].argHasLdargaOp && !inlArgInfo[argNum].argHasStargOp)
+ if ((argSingleUseNode != nullptr) && !(argSingleUseNode->gtFlags & GTF_VAR_CLONED) && argIsSingleDef)
{
// Change the temp in-place to the actual argument.
// We currently do not support this for struct arguments, so it must not be a GT_OBJ.
- GenTree* argNode = inlArgInfo[argNum].argNode;
assert(argNode->gtOper != GT_OBJ);
argSingleUseNode->CopyFrom(argNode, this);
continue;
}
else
{
- /* Create the temp assignment for this argument */
+ // We're going to assign the argument value to the
+ // temp we use for it in the inline body.
+ const unsigned tmpNum = argInfo.argTmpNum;
+ const var_types argType = lclVarInfo[argNum].lclTypeInfo;
+ // Create the temp assignment for this argument
CORINFO_CLASS_HANDLE structHnd = DUMMY_INIT(0);
- if (varTypeIsStruct(lclVarInfo[argNum].lclTypeInfo))
+ if (varTypeIsStruct(argType))
{
- structHnd = gtGetStructHandleIfPresent(inlArgInfo[argNum].argNode);
+ structHnd = gtGetStructHandleIfPresent(argNode);
noway_assert(structHnd != NO_CLASS_HANDLE);
}
@@ -22159,8 +22518,16 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
// argTmpNum here since in-linee compiler instance
// would have iterated over these and marked them
// accordingly.
- impAssignTempGen(inlArgInfo[argNum].argTmpNum, inlArgInfo[argNum].argNode, structHnd,
- (unsigned)CHECK_SPILL_NONE, &afterStmt, callILOffset, block);
+ impAssignTempGen(tmpNum, argNode, structHnd, (unsigned)CHECK_SPILL_NONE, &afterStmt, callILOffset,
+ block);
+
+ // If we know the argument's value can't be
+ // changed within the method body, try and improve
+ // the type of the temp.
+ if (argIsSingleDef && (argType == TYP_REF))
+ {
+ lvaUpdateClass(tmpNum, argNode);
+ }
#ifdef DEBUG
if (verbose)
@@ -22170,44 +22537,42 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
#endif // DEBUG
}
}
- else if (inlArgInfo[argNum].argIsByRefToStructLocal)
+ else if (argInfo.argIsByRefToStructLocal)
{
- // Do nothing.
+ // Do nothing. Arg was directly substituted as we read
+ // the inlinee.
}
else
{
/* The argument is either not used or a const or lcl var */
- noway_assert(!inlArgInfo[argNum].argIsUsed || inlArgInfo[argNum].argIsInvariant ||
- inlArgInfo[argNum].argIsLclVar);
+ noway_assert(!argInfo.argIsUsed || argInfo.argIsInvariant || argInfo.argIsLclVar);
/* Make sure we didnt change argNode's along the way, or else
subsequent uses of the arg would have worked with the bashed value */
- if (inlArgInfo[argNum].argIsInvariant)
+ if (argInfo.argIsInvariant)
{
- assert(inlArgInfo[argNum].argNode->OperIsConst() || inlArgInfo[argNum].argNode->gtOper == GT_ADDR);
+ assert(argNode->OperIsConst() || argNode->gtOper == GT_ADDR);
}
- noway_assert((inlArgInfo[argNum].argIsLclVar == 0) ==
- (inlArgInfo[argNum].argNode->gtOper != GT_LCL_VAR ||
- (inlArgInfo[argNum].argNode->gtFlags & GTF_GLOB_REF)));
+ noway_assert((argInfo.argIsLclVar == 0) ==
+ (argNode->gtOper != GT_LCL_VAR || (argNode->gtFlags & GTF_GLOB_REF)));
/* If the argument has side effects, append it */
- if (inlArgInfo[argNum].argHasSideEff)
+ if (argInfo.argHasSideEff)
{
- noway_assert(inlArgInfo[argNum].argIsUsed == false);
+ noway_assert(argInfo.argIsUsed == false);
- if (inlArgInfo[argNum].argNode->gtOper == GT_OBJ ||
- inlArgInfo[argNum].argNode->gtOper == GT_MKREFANY)
+ if (argNode->gtOper == GT_OBJ || argNode->gtOper == GT_MKREFANY)
{
// Don't put GT_OBJ node under a GT_COMMA.
// Codegen can't deal with it.
// Just hang the address here in case there are side-effect.
- newStmt = gtNewStmt(gtUnusedValNode(inlArgInfo[argNum].argNode->gtOp.gtOp1), callILOffset);
+ newStmt = gtNewStmt(gtUnusedValNode(argNode->gtOp.gtOp1), callILOffset);
}
else
{
- newStmt = gtNewStmt(gtUnusedValNode(inlArgInfo[argNum].argNode), callILOffset);
+ newStmt = gtNewStmt(gtUnusedValNode(argNode), callILOffset);
}
afterStmt = fgInsertStmtAfter(block, afterStmt, newStmt);
@@ -22336,45 +22701,103 @@ GenTreePtr Compiler::fgInlinePrependStatements(InlineInfo* inlineInfo)
// inlineInfo - information about the inline
// block - basic block for the new statements
// stmtAfter - (optional) insertion point for mid-block cases
+//
+// Notes:
+// If the call we're inlining is in tail position then
+// we skip nulling the locals, since it can interfere
+// with tail calls introduced by the local.
void Compiler::fgInlineAppendStatements(InlineInfo* inlineInfo, BasicBlock* block, GenTreePtr stmtAfter)
{
- // Null out any inline pinned locals
- if (!inlineInfo->hasPinnedLocals)
+ // If this inlinee was passed a runtime lookup generic context and
+ // ignores it, we can decrement the "generic context was used" ref
+ // count, because we created a new lookup tree and incremented the
+ // count when we imported the type parameter argument to pass to
+ // the inlinee. See corresponding logic in impImportCall that
+ // checks the sig for CORINFO_CALLCONV_PARAMTYPE.
+ //
+ // Does this method require a context (type) parameter?
+ if ((inlineInfo->inlineCandidateInfo->methInfo.args.callConv & CORINFO_CALLCONV_PARAMTYPE) != 0)
{
- // No pins, nothing to do
+ // Did the computation of that parameter require the
+ // caller to perform a runtime lookup?
+ if (inlineInfo->inlineCandidateInfo->exactContextNeedsRuntimeLookup)
+ {
+ // Fetch the temp for the generic context as it would
+ // appear in the inlinee's body.
+ const unsigned typeCtxtArg = inlineInfo->typeContextArg;
+ const unsigned tmpNum = inlineInfo->lclTmpNum[typeCtxtArg];
+
+ // Was it used in the inline body?
+ if (tmpNum == BAD_VAR_NUM)
+ {
+ // No -- so the associated runtime lookup is not needed
+ // and also no longer provides evidence that the generic
+ // context should be kept alive.
+ JITDUMP("Inlinee ignores runtime lookup generics context\n");
+ assert(lvaGenericsContextUseCount > 0);
+ lvaGenericsContextUseCount--;
+ }
+ }
+ }
+
+ // Null out any gc ref locals
+ if (!inlineInfo->HasGcRefLocals())
+ {
+ // No ref locals, nothing to do.
+ JITDUMP("fgInlineAppendStatements: no gc ref inline locals.\n");
return;
}
- JITDUMP("Unpin inlinee locals:\n");
+ if (inlineInfo->iciCall->IsImplicitTailCall())
+ {
+ JITDUMP("fgInlineAppendStatements: implicit tail call; skipping nulling.\n");
+ return;
+ }
+
+ JITDUMP("fgInlineAppendStatements: nulling out gc ref inlinee locals.\n");
GenTreePtr callStmt = inlineInfo->iciStmt;
IL_OFFSETX callILOffset = callStmt->gtStmt.gtStmtILoffsx;
CORINFO_METHOD_INFO* InlineeMethodInfo = InlineeCompiler->info.compMethodInfo;
- unsigned lclCnt = InlineeMethodInfo->locals.numArgs;
+ const unsigned lclCnt = InlineeMethodInfo->locals.numArgs;
InlLclVarInfo* lclVarInfo = inlineInfo->lclVarInfo;
+ unsigned gcRefLclCnt = inlineInfo->numberOfGcRefLocals;
+ const unsigned argCnt = inlineInfo->argCnt;
noway_assert(callStmt->gtOper == GT_STMT);
for (unsigned lclNum = 0; lclNum < lclCnt; lclNum++)
{
- unsigned tmpNum = inlineInfo->lclTmpNum[lclNum];
+ // Is the local a gc ref type? Need to look at the
+ // inline info for this since we will not have local
+ // temps for unused inlinee locals.
+ const var_types lclTyp = lclVarInfo[argCnt + lclNum].lclTypeInfo;
- // Is the local used at all?
- if (tmpNum == BAD_VAR_NUM)
+ if (!varTypeIsGC(lclTyp))
{
- // Nope, nothing to unpin.
+ // Nope, nothing to null out.
continue;
}
- // Is the local pinned?
- if (!lvaTable[tmpNum].lvPinned)
+ // Ensure we're examining just the right number of locals.
+ assert(gcRefLclCnt > 0);
+ gcRefLclCnt--;
+
+ // Fetch the temp for this inline local
+ const unsigned tmpNum = inlineInfo->lclTmpNum[lclNum];
+
+ // Is the local used at all?
+ if (tmpNum == BAD_VAR_NUM)
{
- // Nope, nothing to unpin.
+ // Nope, nothing to null out.
continue;
}
- // Does the local we're about to unpin appear in the return
+ // Local was used, make sure the type is consistent.
+ assert(lvaTable[tmpNum].lvType == lclTyp);
+
+ // Does the local we're about to null out appear in the return
// expression? If so we somehow messed up and didn't properly
// spill the return value. See impInlineFetchLocal.
GenTreePtr retExpr = inlineInfo->retExpr;
@@ -22384,29 +22807,29 @@ void Compiler::fgInlineAppendStatements(InlineInfo* inlineInfo, BasicBlock* bloc
noway_assert(!interferesWithReturn);
}
- // Emit the unpin, by assigning null to the local.
- var_types lclTyp = (var_types)lvaTable[tmpNum].lvType;
- noway_assert(lclTyp == lclVarInfo[lclNum + inlineInfo->argCnt].lclTypeInfo);
- noway_assert(!varTypeIsStruct(lclTyp));
- GenTreePtr unpinExpr = gtNewTempAssign(tmpNum, gtNewZeroConNode(genActualType(lclTyp)));
- GenTreePtr unpinStmt = gtNewStmt(unpinExpr, callILOffset);
+ // Assign null to the local.
+ GenTreePtr nullExpr = gtNewTempAssign(tmpNum, gtNewZeroConNode(lclTyp));
+ GenTreePtr nullStmt = gtNewStmt(nullExpr, callILOffset);
if (stmtAfter == nullptr)
{
- stmtAfter = fgInsertStmtAtBeg(block, unpinStmt);
+ stmtAfter = fgInsertStmtAtBeg(block, nullStmt);
}
else
{
- stmtAfter = fgInsertStmtAfter(block, stmtAfter, unpinStmt);
+ stmtAfter = fgInsertStmtAfter(block, stmtAfter, nullStmt);
}
#ifdef DEBUG
if (verbose)
{
- gtDispTree(unpinStmt);
+ gtDispTree(nullStmt);
}
#endif // DEBUG
}
+
+ // There should not be any GC ref locals left to null out.
+ assert(gcRefLclCnt == 0);
}
/*****************************************************************************/
@@ -22512,6 +22935,14 @@ void Compiler::fgRemoveEmptyFinally()
{
JITDUMP("\n*************** In fgRemoveEmptyFinally()\n");
+#if FEATURE_EH_FUNCLETS
+ // We need to do this transformation before funclets are created.
+ assert(!fgFuncletsCreated);
+#endif // FEATURE_EH_FUNCLETS
+
+ // Assume we don't need to update the bbPreds lists.
+ assert(!fgComputePredsDone);
+
if (compHndBBtabCount == 0)
{
JITDUMP("No EH in this method, nothing to remove.\n");
@@ -22741,6 +23172,14 @@ void Compiler::fgRemoveEmptyTry()
{
JITDUMP("\n*************** In fgRemoveEmptyTry()\n");
+#if FEATURE_EH_FUNCLETS
+ // We need to do this transformation before funclets are created.
+ assert(!fgFuncletsCreated);
+#endif // FEATURE_EH_FUNCLETS
+
+ // Assume we don't need to update the bbPreds lists.
+ assert(!fgComputePredsDone);
+
#ifdef FEATURE_CORECLR
bool enableRemoveEmptyTry = true;
#else
@@ -22969,6 +23408,7 @@ void Compiler::fgRemoveEmptyTry()
// Handler index of any nested blocks will update when we
// remove the EH table entry. Change handler exits to jump to
// the continuation. Clear catch type on handler entry.
+ // Decrement nesting level of enclosed GT_END_LFINs.
for (BasicBlock* block = firstHandlerBlock; block != endHandlerBlock; block = block->bbNext)
{
if (block == firstHandlerBlock)
@@ -22995,8 +23435,25 @@ void Compiler::fgRemoveEmptyTry()
fgRemoveStmt(block, finallyRet);
block->bbJumpKind = BBJ_ALWAYS;
block->bbJumpDest = continuation;
+ fgAddRefPred(continuation, block);
+ }
+ }
+
+#if !FEATURE_EH_FUNCLETS
+ // If we're in a non-funclet model, decrement the nesting
+ // level of any GT_END_LFIN we find in the handler region,
+ // since we're removing the enclosing handler.
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->gtNextStmt)
+ {
+ GenTreePtr expr = stmt->gtStmtExpr;
+ if (expr->gtOper == GT_END_LFIN)
+ {
+ const unsigned nestLevel = expr->gtVal.gtVal1;
+ assert(nestLevel > 0);
+ expr->gtVal.gtVal1 = nestLevel - 1;
}
}
+#endif // !FEATURE_EH_FUNCLETS
}
// (6) Remove the try-finally EH region. This will compact the
@@ -23060,6 +23517,14 @@ void Compiler::fgCloneFinally()
{
JITDUMP("\n*************** In fgCloneFinally()\n");
+#if FEATURE_EH_FUNCLETS
+ // We need to do this transformation before funclets are created.
+ assert(!fgFuncletsCreated);
+#endif // FEATURE_EH_FUNCLETS
+
+ // Assume we don't need to update the bbPreds lists.
+ assert(!fgComputePredsDone);
+
#ifdef FEATURE_CORECLR
bool enableCloning = true;
#else
@@ -23234,7 +23699,7 @@ void Compiler::fgCloneFinally()
BasicBlock* const firstTryBlock = HBtab->ebdTryBeg;
BasicBlock* const lastTryBlock = HBtab->ebdTryLast;
assert(firstTryBlock->getTryIndex() == XTnum);
- assert(lastTryBlock->getTryIndex() == XTnum);
+ assert(bbInTryRegions(XTnum, lastTryBlock));
BasicBlock* const beforeTryBlock = firstTryBlock->bbPrev;
BasicBlock* normalCallFinallyBlock = nullptr;
@@ -23564,7 +24029,7 @@ void Compiler::fgCloneFinally()
BasicBlock* firstClonedBlock = blockMap[firstBlock];
firstClonedBlock->bbCatchTyp = BBCT_NONE;
- // Cleanup the contination
+ // Cleanup the continuation
fgCleanupContinuation(normalCallFinallyReturn);
// Todo -- mark cloned blocks as a cloned finally....
@@ -23873,6 +24338,291 @@ void Compiler::fgUpdateFinallyTargetFlags()
#endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
}
+//------------------------------------------------------------------------
+// fgMergeFinallyChains: tail merge finally invocations
+//
+// Notes:
+//
+// Looks for common suffixes in chains of finally invocations
+// (callfinallys) and merges them. These typically arise from
+// try-finallys where there are multiple exit points in the try
+// that have the same target.
+
+void Compiler::fgMergeFinallyChains()
+{
+ JITDUMP("\n*************** In fgMergeFinallyChains()\n");
+
+#if FEATURE_EH_FUNCLETS
+ // We need to do this transformation before funclets are created.
+ assert(!fgFuncletsCreated);
+#endif // FEATURE_EH_FUNCLETS
+
+ // Assume we don't need to update the bbPreds lists.
+ assert(!fgComputePredsDone);
+
+ if (compHndBBtabCount == 0)
+ {
+ JITDUMP("No EH in this method, nothing to merge.\n");
+ return;
+ }
+
+ if (opts.MinOpts())
+ {
+ JITDUMP("Method compiled with minOpts, no merging.\n");
+ return;
+ }
+
+ if (opts.compDbgCode)
+ {
+ JITDUMP("Method compiled with debug codegen, no merging.\n");
+ return;
+ }
+
+ bool enableMergeFinallyChains = true;
+
+#if !FEATURE_EH_FUNCLETS
+ // For non-funclet models (x86) the callfinallys may contain
+ // statements and the continuations contain GT_END_LFINs. So no
+ // merging is possible until the GT_END_LFIN blocks can be merged
+ // and merging is not safe unless the callfinally blocks are split.
+ JITDUMP("EH using non-funclet model; merging not yet implemented.\n");
+ enableMergeFinallyChains = false;
+#endif // !FEATURE_EH_FUNCLETS
+
+#if !FEATURE_EH_CALLFINALLY_THUNKS
+ // For non-thunk EH models (arm32) the callfinallys may contain
+ // statements, and merging is not safe unless the callfinally
+ // blocks are split.
+ JITDUMP("EH using non-callfinally thunk model; merging not yet implemented.\n");
+ enableMergeFinallyChains = false;
+#endif
+
+ if (!enableMergeFinallyChains)
+ {
+ JITDUMP("fgMergeFinallyChains disabled\n");
+ return;
+ }
+
+#ifdef DEBUG
+ if (verbose)
+ {
+ printf("\n*************** Before fgMergeFinallyChains()\n");
+ fgDispBasicBlocks();
+ fgDispHandlerTab();
+ printf("\n");
+ }
+#endif // DEBUG
+
+ // Look for finallys.
+ bool hasFinally = false;
+ for (unsigned XTnum = 0; XTnum < compHndBBtabCount; XTnum++)
+ {
+ EHblkDsc* const HBtab = &compHndBBtab[XTnum];
+
+ // Check if this is a try/finally.
+ if (HBtab->HasFinallyHandler())
+ {
+ hasFinally = true;
+ break;
+ }
+ }
+
+ if (!hasFinally)
+ {
+ JITDUMP("Method does not have any try-finallys; no merging.\n");
+ return;
+ }
+
+ // Process finallys from outside in, merging as we go. This gives
+ // us the desired bottom-up tail merge order for callfinally
+ // chains: outer merges may enable inner merges.
+ bool canMerge = false;
+ bool didMerge = false;
+ BlockToBlockMap continuationMap(getAllocator());
+
+ // Note XTnum is signed here so we can count down.
+ for (int XTnum = compHndBBtabCount - 1; XTnum >= 0; XTnum--)
+ {
+ EHblkDsc* const HBtab = &compHndBBtab[XTnum];
+
+ // Screen out non-finallys
+ if (!HBtab->HasFinallyHandler())
+ {
+ continue;
+ }
+
+ JITDUMP("Examining callfinallys for EH#%d.\n", XTnum);
+
+ // Find all the callfinallys that invoke this finally.
+ BasicBlock* firstCallFinallyRangeBlock = nullptr;
+ BasicBlock* endCallFinallyRangeBlock = nullptr;
+ ehGetCallFinallyBlockRange(XTnum, &firstCallFinallyRangeBlock, &endCallFinallyRangeBlock);
+
+ // Clear out any stale entries in the continuation map
+ continuationMap.RemoveAll();
+
+ // Build a map from each continuation to the "canonical"
+ // callfinally for that continuation.
+ unsigned callFinallyCount = 0;
+ BasicBlock* const beginHandlerBlock = HBtab->ebdHndBeg;
+
+ for (BasicBlock* currentBlock = firstCallFinallyRangeBlock; currentBlock != endCallFinallyRangeBlock;
+ currentBlock = currentBlock->bbNext)
+ {
+ // Ignore "retless" callfinallys (where the finally doesn't return).
+ if (currentBlock->isBBCallAlwaysPair() && (currentBlock->bbJumpDest == beginHandlerBlock))
+ {
+ // The callfinally must be empty, so that we can
+ // safely retarget anything that branches here to
+ // another callfinally with the same contiuation.
+ assert(currentBlock->isEmpty());
+
+ // This callfinally invokes the finally for this try.
+ callFinallyCount++;
+
+ // Locate the continuation
+ BasicBlock* const leaveBlock = currentBlock->bbNext;
+ BasicBlock* const continuationBlock = leaveBlock->bbJumpDest;
+
+ // If this is the first time we've seen this
+ // continuation, register this callfinally as the
+ // canonical one.
+ if (!continuationMap.Lookup(continuationBlock))
+ {
+ continuationMap.Set(continuationBlock, currentBlock);
+ }
+ }
+ }
+
+ // Now we've seen all the callfinallys and their continuations.
+ JITDUMP("EH#%i has %u callfinallys, %u continuations\n", XTnum, callFinallyCount, continuationMap.GetCount());
+
+ // If there are more callfinallys than continuations, some of the
+ // callfinallys must share a continuation, and we can merge them.
+ const bool tryMerge = callFinallyCount > continuationMap.GetCount();
+
+ if (!tryMerge)
+ {
+ JITDUMP("EH#%i does not have any mergeable callfinallys\n", XTnum);
+ continue;
+ }
+
+ canMerge = true;
+
+ // Walk the callfinally region, looking for blocks that jump
+ // to a callfinally that invokes this try's finally, and make
+ // sure they all jump to the appropriate canonical
+ // callfinally.
+ for (BasicBlock* currentBlock = firstCallFinallyRangeBlock; currentBlock != endCallFinallyRangeBlock;
+ currentBlock = currentBlock->bbNext)
+ {
+ bool merged = fgRetargetBranchesToCanonicalCallFinally(currentBlock, beginHandlerBlock, continuationMap);
+ didMerge = didMerge || merged;
+ }
+ }
+
+ if (!canMerge)
+ {
+ JITDUMP("Method had try-finallys, but did not have any mergeable finally chains.\n");
+ }
+ else
+ {
+ if (didMerge)
+ {
+ JITDUMP("Method had mergeable try-finallys and some callfinally merges were performed.\n");
+
+#if DEBUG
+ if (verbose)
+ {
+ printf("\n*************** After fgMergeFinallyChains()\n");
+ fgDispBasicBlocks();
+ fgDispHandlerTab();
+ printf("\n");
+ }
+
+#endif // DEBUG
+ }
+ else
+ {
+ // We may not end up doing any merges, because we are only
+ // merging continuations for callfinallys that can
+ // actually be invoked, and the importer may leave
+ // unreachable callfinallys around (for instance, if it
+ // is forced to re-import a leave).
+ JITDUMP("Method had mergeable try-finallys but no callfinally merges were performed,\n"
+ "likely the non-canonical callfinallys were unreachable\n");
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+// fgRetargetBranchesToCanonicalCallFinally: find non-canonical callfinally
+// invocations and make them canonical.
+//
+// Arguments:
+// block -- block to examine for call finally invocation
+// handler -- start of the finally region for the try
+// continuationMap -- map giving the canonical callfinally for
+// each continuation
+//
+// Returns:
+// true iff the block's branch was retargeted.
+
+bool Compiler::fgRetargetBranchesToCanonicalCallFinally(BasicBlock* block,
+ BasicBlock* handler,
+ BlockToBlockMap& continuationMap)
+{
+ // We expect callfinallys to be invoked by a BBJ_ALWAYS at this
+ // stage in compilation.
+ if (block->bbJumpKind != BBJ_ALWAYS)
+ {
+ // Possible paranoia assert here -- no flow successor of
+ // this block should be a callfinally for this try.
+ return false;
+ }
+
+ // Screen out cases that are not callfinallys to the right
+ // handler.
+ BasicBlock* const callFinally = block->bbJumpDest;
+
+ if (!callFinally->isBBCallAlwaysPair())
+ {
+ return false;
+ }
+
+ if (callFinally->bbJumpDest != handler)
+ {
+ return false;
+ }
+
+ // Ok, this is a callfinally that invokes the right handler.
+ // Get its continuation.
+ BasicBlock* const leaveBlock = callFinally->bbNext;
+ BasicBlock* const continuationBlock = leaveBlock->bbJumpDest;
+
+ // Find the canonical callfinally for that continuation.
+ BasicBlock* const canonicalCallFinally = continuationMap[continuationBlock];
+ assert(canonicalCallFinally != nullptr);
+
+ // If the block already jumps to the canoncial call finally, no work needed.
+ if (block->bbJumpDest == canonicalCallFinally)
+ {
+ JITDUMP("BB%02u already canonical\n", block->bbNum);
+ return false;
+ }
+
+ // Else, retarget it so that it does...
+ JITDUMP("Redirecting branch in BB%02u from BB%02u to BB%02u.\n", block->bbNum, callFinally->bbNum,
+ canonicalCallFinally->bbNum);
+
+ block->bbJumpDest = canonicalCallFinally;
+ fgAddRefPred(canonicalCallFinally, block);
+ assert(callFinally->bbRefs > 0);
+ fgRemoveRefPred(callFinally, block);
+
+ return true;
+}
+
// FatCalliTransformer transforms calli that can use fat function pointer.
// Fat function pointer is pointer with the second least significant bit set,
// if the bit is set, the pointer (after clearing the bit) actually points to
@@ -24132,7 +24882,7 @@ private:
// fixedFptrAddress - pointer to the tuple <methodPointer, instantiationArgumentPointer>
//
// Return Value:
- // loaded hidden argument.
+ // generic context hidden argument.
GenTreePtr GetHiddenArgument(GenTreePtr fixedFptrAddress)
{
GenTreePtr fixedFptrAddressCopy = compiler->gtCloneExpr(fixedFptrAddress);
@@ -24148,7 +24898,7 @@ private:
//
// Arguments:
// actualCallAddress - fixed call address
- // hiddenArgument - loaded hidden argument
+ // hiddenArgument - generic context hidden argument
//
// Return Value:
// created call node.
@@ -24158,13 +24908,58 @@ private:
GenTreePtr fatTree = fatStmt->gtStmtExpr;
GenTreeCall* fatCall = GetCall(fatStmt);
fatCall->gtCallAddr = actualCallAddress;
- GenTreeArgList* args = fatCall->gtCallArgs;
- args = compiler->gtNewListNode(hiddenArgument, args);
- fatCall->gtCallArgs = args;
+ AddHiddenArgument(fatCall, hiddenArgument);
return fatStmt;
}
//------------------------------------------------------------------------
+ // AddHiddenArgument: add hidden argument to the call argument list.
+ //
+ // Arguments:
+ // fatCall - fat call node
+ // hiddenArgument - generic context hidden argument
+ //
+ void AddHiddenArgument(GenTreeCall* fatCall, GenTreePtr hiddenArgument)
+ {
+ GenTreeArgList* oldArgs = fatCall->gtCallArgs;
+ GenTreeArgList* newArgs;
+#if USER_ARGS_COME_LAST
+ if (fatCall->HasRetBufArg())
+ {
+ GenTreePtr retBuffer = oldArgs->Current();
+ GenTreeArgList* rest = oldArgs->Rest();
+ newArgs = compiler->gtNewListNode(hiddenArgument, rest);
+ newArgs = compiler->gtNewListNode(retBuffer, newArgs);
+ }
+ else
+ {
+ newArgs = compiler->gtNewListNode(hiddenArgument, oldArgs);
+ }
+#else
+ newArgs = oldArgs;
+ AddArgumentToTail(newArgs, hiddenArgument);
+#endif
+ fatCall->gtCallArgs = newArgs;
+ }
+
+ //------------------------------------------------------------------------
+ // AddArgumentToTail: add hidden argument to the tail of the call argument list.
+ //
+ // Arguments:
+ // argList - fat call node
+ // hiddenArgument - generic context hidden argument
+ //
+ void AddArgumentToTail(GenTreeArgList* argList, GenTreePtr hiddenArgument)
+ {
+ GenTreeArgList* iterator = argList;
+ while (iterator->Rest() != nullptr)
+ {
+ iterator = iterator->Rest();
+ }
+ iterator->Rest() = compiler->gtNewArgList(hiddenArgument);
+ }
+
+ //------------------------------------------------------------------------
// RemoveOldStatement: remove original stmt from current block.
//
void RemoveOldStatement()
@@ -24256,3 +25051,63 @@ void Compiler::fgTransformFatCalli()
CheckNoFatPointerCandidatesLeft();
#endif
}
+
+//------------------------------------------------------------------------
+// fgMeasureIR: count and return the number of IR nodes in the function.
+//
+unsigned Compiler::fgMeasureIR()
+{
+ unsigned nodeCount = 0;
+
+ for (BasicBlock* block = fgFirstBB; block != nullptr; block = block->bbNext)
+ {
+ if (!block->IsLIR())
+ {
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->getNextStmt())
+ {
+ fgWalkTreePre(&stmt->gtStmtExpr,
+ [](GenTree** slot, fgWalkData* data) -> Compiler::fgWalkResult {
+ (*reinterpret_cast<unsigned*>(data->pCallbackData))++;
+ return Compiler::WALK_CONTINUE;
+ },
+ &nodeCount);
+ }
+ }
+ else
+ {
+ for (GenTree* node : LIR::AsRange(block))
+ {
+ nodeCount++;
+ }
+ }
+ }
+
+ return nodeCount;
+}
+
+//------------------------------------------------------------------------
+// fgCompDominatedByExceptionalEntryBlocks: compute blocks that are
+// dominated by not normal entry.
+//
+void Compiler::fgCompDominatedByExceptionalEntryBlocks()
+{
+ assert(fgEnterBlksSetValid);
+ if (BlockSetOps::Count(this, fgEnterBlks) != 1) // There are exception entries.
+ {
+ for (unsigned i = 1; i <= fgBBNumMax; ++i)
+ {
+ BasicBlock* block = fgBBInvPostOrder[i];
+ if (BlockSetOps::IsMember(this, fgEnterBlks, block->bbNum))
+ {
+ if (fgFirstBB != block) // skip the normal entry.
+ {
+ block->SetDominatedByExceptionalEntryFlag();
+ }
+ }
+ else if (block->bbIDom->IsDominatedByExceptionalEntryFlag())
+ {
+ block->SetDominatedByExceptionalEntryFlag();
+ }
+ }
+ }
+}
diff --git a/src/jit/gcencode.cpp b/src/jit/gcencode.cpp
index dcca19ebe8..4c300ac15f 100644
--- a/src/jit/gcencode.cpp
+++ b/src/jit/gcencode.cpp
@@ -1318,6 +1318,8 @@ size_t GCInfo::gcInfoBlockHdrSave(
header->syncStartOffset = INVALID_SYNC_OFFSET;
header->syncEndOffset = INVALID_SYNC_OFFSET;
+#ifndef UNIX_X86_ABI
+ // JIT is responsible for synchronization on funclet-based EH model that x86/Linux uses.
if (compiler->info.compFlags & CORINFO_FLG_SYNCH)
{
assert(compiler->syncStartEmitCookie != NULL);
@@ -1332,6 +1334,7 @@ size_t GCInfo::gcInfoBlockHdrSave(
// synchronized methods can't have more than 1 epilog
assert(header->epilogCount <= 1);
}
+#endif
header->revPInvokeOffset = INVALID_REV_PINVOKE_OFFSET;
@@ -2424,7 +2427,9 @@ DONE_VLT:
assert((codeDelta & 0x7) == codeDelta);
*dest++ = 0xB0 | (BYTE)codeDelta;
+#ifndef UNIX_X86_ABI
assert(!compiler->isFramePointerUsed());
+#endif
/* Remember the new 'last' offset */
@@ -3844,13 +3849,15 @@ struct InterruptibleRangeReporter
}
};
-void GCInfo::gcMakeRegPtrTable(GcInfoEncoder* gcInfoEncoder,
- unsigned codeSize,
- unsigned prologSize,
- MakeRegPtrMode mode)
+void GCInfo::gcMakeRegPtrTable(
+ GcInfoEncoder* gcInfoEncoder, unsigned codeSize, unsigned prologSize, MakeRegPtrMode mode, unsigned* callCntRef)
{
GCENCODER_WITH_LOGGING(gcInfoEncoderWithLog, gcInfoEncoder);
+ const bool noTrackedGCSlots =
+ (compiler->opts.MinOpts() && !compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT) &&
+ !JitConfig.JitMinOptsTrackGCrefs());
+
if (mode == MAKE_REG_PTR_MODE_ASSIGN_SLOTS)
{
m_regSlotMap = new (compiler->getAllocator()) RegSlotMap(compiler->getAllocator());
@@ -3961,14 +3968,25 @@ void GCInfo::gcMakeRegPtrTable(GcInfoEncoder* gcInfoEncoder,
{
stackSlotBase = GC_FRAMEREG_REL;
}
- StackSlotIdKey sskey(varDsc->lvStkOffs, (stackSlotBase == GC_FRAMEREG_REL), flags);
- GcSlotId varSlotId;
- if (mode == MAKE_REG_PTR_MODE_ASSIGN_SLOTS)
+ if (noTrackedGCSlots)
{
- if (!m_stackSlotMap->Lookup(sskey, &varSlotId))
+ // No need to hash/lookup untracked GC refs; just grab a new Slot Id.
+ if (mode == MAKE_REG_PTR_MODE_ASSIGN_SLOTS)
{
- varSlotId = gcInfoEncoderWithLog->GetStackSlotId(varDsc->lvStkOffs, flags, stackSlotBase);
- m_stackSlotMap->Set(sskey, varSlotId);
+ gcInfoEncoderWithLog->GetStackSlotId(varDsc->lvStkOffs, flags, stackSlotBase);
+ }
+ }
+ else
+ {
+ StackSlotIdKey sskey(varDsc->lvStkOffs, (stackSlotBase == GC_FRAMEREG_REL), flags);
+ GcSlotId varSlotId;
+ if (mode == MAKE_REG_PTR_MODE_ASSIGN_SLOTS)
+ {
+ if (!m_stackSlotMap->Lookup(sskey, &varSlotId))
+ {
+ varSlotId = gcInfoEncoderWithLog->GetStackSlotId(varDsc->lvStkOffs, flags, stackSlotBase);
+ m_stackSlotMap->Set(sskey, varSlotId);
+ }
}
}
}
@@ -4204,9 +4222,24 @@ void GCInfo::gcMakeRegPtrTable(GcInfoEncoder* gcInfoEncoder,
{
if (gcCallDescList != nullptr)
{
- for (CallDsc* call = gcCallDescList; call != nullptr; call = call->cdNext)
+ if (noTrackedGCSlots)
{
- numCallSites++;
+ // We have the call count from the previous run.
+ numCallSites = *callCntRef;
+
+ // If there are no calls, tell the world and bail.
+ if (numCallSites == 0)
+ {
+ gcInfoEncoderWithLog->DefineCallSites(nullptr, nullptr, 0);
+ return;
+ }
+ }
+ else
+ {
+ for (CallDsc* call = gcCallDescList; call != nullptr; call = call->cdNext)
+ {
+ numCallSites++;
+ }
}
pCallSites = new (compiler, CMK_GC) unsigned[numCallSites];
pCallSiteSizes = new (compiler, CMK_GC) BYTE[numCallSites];
@@ -4216,17 +4249,8 @@ void GCInfo::gcMakeRegPtrTable(GcInfoEncoder* gcInfoEncoder,
// Now consider every call.
for (CallDsc* call = gcCallDescList; call != nullptr; call = call->cdNext)
{
- if (mode == MAKE_REG_PTR_MODE_DO_WORK)
- {
- pCallSites[callSiteNum] = call->cdOffs - call->cdCallInstrSize;
- pCallSiteSizes[callSiteNum] = call->cdCallInstrSize;
- callSiteNum++;
- }
-
- unsigned nextOffset;
-
// Figure out the code offset of this entry.
- nextOffset = call->cdOffs;
+ unsigned nextOffset = call->cdOffs;
// As far as I (DLD, 2010) can determine by asking around, the "call->u1.cdArgMask"
// and "cdArgCnt" cases are to handle x86 situations in which a call expression is nested as an
@@ -4251,13 +4275,35 @@ void GCInfo::gcMakeRegPtrTable(GcInfoEncoder* gcInfoEncoder,
assert(call->cdOffs >= call->cdCallInstrSize);
// call->cdOffs is actually the offset of the instruction *following* the call, so subtract
// the call instruction size to get the offset of the actual call instruction...
- unsigned callOffset = call->cdOffs - call->cdCallInstrSize;
- // Record that these registers are live before the call...
- gcInfoRecordGCRegStateChange(gcInfoEncoder, mode, callOffset, regMask, GC_SLOT_LIVE, byrefRegMask, nullptr);
- // ...and dead after.
- gcInfoRecordGCRegStateChange(gcInfoEncoder, mode, call->cdOffs, regMask, GC_SLOT_DEAD, byrefRegMask,
- nullptr);
+ unsigned callOffset = nextOffset - call->cdCallInstrSize;
+
+ if (noTrackedGCSlots && regMask == 0)
+ {
+ // No live GC refs in regs at the call -> don't record the call.
+ }
+ else
+ {
+ // Append an entry for the call if doing the real thing.
+ if (mode == MAKE_REG_PTR_MODE_DO_WORK)
+ {
+ pCallSites[callSiteNum] = callOffset;
+ pCallSiteSizes[callSiteNum] = call->cdCallInstrSize;
+ }
+ callSiteNum++;
+
+ // Record that these registers are live before the call...
+ gcInfoRecordGCRegStateChange(gcInfoEncoder, mode, callOffset, regMask, GC_SLOT_LIVE, byrefRegMask,
+ nullptr);
+ // ...and dead after.
+ gcInfoRecordGCRegStateChange(gcInfoEncoder, mode, nextOffset, regMask, GC_SLOT_DEAD, byrefRegMask,
+ nullptr);
+ }
}
+ // Make sure we've recorded the expected number of calls
+ assert(mode != MAKE_REG_PTR_MODE_DO_WORK || numCallSites == callSiteNum);
+ // Return the actual recorded call count to the caller
+ *callCntRef = callSiteNum;
+
// OK, define the call sites.
if (mode == MAKE_REG_PTR_MODE_DO_WORK)
{
diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp
index 7af500f877..c5733b81e4 100644
--- a/src/jit/gentree.cpp
+++ b/src/jit/gentree.cpp
@@ -2531,7 +2531,7 @@ AGAIN:
}
}
- if (tree->gtCall.gtCallLateArgs)
+ if (tree->gtCall.gtControlExpr)
{
if (gtHasRef(tree->gtCall.gtControlExpr, lclNum, defOnly))
{
@@ -5524,7 +5524,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree)
}
#ifdef FEATURE_READYTORUN_COMPILER
-#ifdef _TARGET_ARM64_
+#if defined(_TARGET_ARMARCH_)
if (tree->gtCall.IsR2RRelativeIndir())
{
ftreg |= RBM_R2R_INDIRECT_PARAM;
@@ -6927,7 +6927,7 @@ GenTreeCall* Compiler::gtNewCallNode(
// Initialize spill flags of gtOtherRegs
node->ClearOtherRegFlags();
-#if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
+#if (defined(_TARGET_X86_) || defined(_TARGET_ARM_)) && !defined(LEGACY_BACKEND)
// Initialize the multi-reg long return info if necessary
if (varTypeIsLong(node))
{
@@ -6941,7 +6941,7 @@ GenTreeCall* Compiler::gtNewCallNode(
// must be a long returned in two registers
assert(retTypeDesc->GetReturnRegCount() == 2);
}
-#endif // defined(_TARGET_X86_) && !defined(_LEGACY_BACKEND_)
+#endif // (defined(_TARGET_X86_) || defined(_TARGET_ARM_)) && !defined(_LEGACY_BACKEND_)
return node;
}
@@ -7062,10 +7062,9 @@ GenTreeArgList* Compiler::gtNewArgList(GenTreePtr arg1, GenTreePtr arg2, GenTree
* that has the matching argNum and return the fgArgTableEntryPtr
*/
-fgArgTabEntryPtr Compiler::gtArgEntryByArgNum(GenTreePtr call, unsigned argNum)
+fgArgTabEntryPtr Compiler::gtArgEntryByArgNum(GenTreeCall* call, unsigned argNum)
{
- noway_assert(call->IsCall());
- fgArgInfoPtr argInfo = call->gtCall.fgArgInfo;
+ fgArgInfoPtr argInfo = call->fgArgInfo;
noway_assert(argInfo != nullptr);
unsigned argCount = argInfo->ArgCount();
@@ -7090,10 +7089,9 @@ fgArgTabEntryPtr Compiler::gtArgEntryByArgNum(GenTreePtr call, unsigned argNum)
* that has the matching node and return the fgArgTableEntryPtr
*/
-fgArgTabEntryPtr Compiler::gtArgEntryByNode(GenTreePtr call, GenTreePtr node)
+fgArgTabEntryPtr Compiler::gtArgEntryByNode(GenTreeCall* call, GenTreePtr node)
{
- noway_assert(call->IsCall());
- fgArgInfoPtr argInfo = call->gtCall.fgArgInfo;
+ fgArgInfoPtr argInfo = call->fgArgInfo;
noway_assert(argInfo != nullptr);
unsigned argCount = argInfo->ArgCount();
@@ -7108,12 +7106,6 @@ fgArgTabEntryPtr Compiler::gtArgEntryByNode(GenTreePtr call, GenTreePtr node)
{
return curArgTabEntry;
}
-#ifdef PROTO_JIT
- else if (node->OperGet() == GT_RELOAD && node->gtOp.gtOp1 == curArgTabEntry->node)
- {
- return curArgTabEntry;
- }
-#endif // PROTO_JIT
else if (curArgTabEntry->parent != nullptr)
{
assert(curArgTabEntry->parent->OperIsList());
@@ -7124,7 +7116,7 @@ fgArgTabEntryPtr Compiler::gtArgEntryByNode(GenTreePtr call, GenTreePtr node)
}
else // (curArgTabEntry->parent == NULL)
{
- if (call->gtCall.gtCallObjp == node)
+ if (call->gtCallObjp == node)
{
return curArgTabEntry;
}
@@ -7139,10 +7131,9 @@ fgArgTabEntryPtr Compiler::gtArgEntryByNode(GenTreePtr call, GenTreePtr node)
* Find and return the entry with the given "lateArgInx". Requires that one is found
* (asserts this).
*/
-fgArgTabEntryPtr Compiler::gtArgEntryByLateArgIndex(GenTreePtr call, unsigned lateArgInx)
+fgArgTabEntryPtr Compiler::gtArgEntryByLateArgIndex(GenTreeCall* call, unsigned lateArgInx)
{
- noway_assert(call->IsCall());
- fgArgInfoPtr argInfo = call->gtCall.fgArgInfo;
+ fgArgInfoPtr argInfo = call->fgArgInfo;
noway_assert(argInfo != nullptr);
unsigned argCount = argInfo->ArgCount();
@@ -7909,8 +7900,7 @@ GenTreePtr Compiler::gtCloneExpr(
copy = new (this, oper) GenTreeFptrVal(tree->gtType, tree->gtFptrVal.gtFptrMethod);
#ifdef FEATURE_READYTORUN_COMPILER
- copy->gtFptrVal.gtEntryPoint = tree->gtFptrVal.gtEntryPoint;
- copy->gtFptrVal.gtLdftnResolvedToken = tree->gtFptrVal.gtLdftnResolvedToken;
+ copy->gtFptrVal.gtEntryPoint = tree->gtFptrVal.gtEntryPoint;
#endif
goto DONE;
@@ -8265,7 +8255,7 @@ GenTreePtr Compiler::gtCloneExpr(
if (tree->gtCall.fgArgInfo)
{
// Create and initialize the fgArgInfo for our copy of the call tree
- copy->gtCall.fgArgInfo = new (this, CMK_Unknown) fgArgInfo(copy, tree);
+ copy->gtCall.fgArgInfo = new (this, CMK_Unknown) fgArgInfo(copy->AsCall(), tree->AsCall());
}
else
{
@@ -8636,21 +8626,19 @@ bool Compiler::gtCompareTree(GenTree* op1, GenTree* op2)
return false;
}
-GenTreePtr Compiler::gtGetThisArg(GenTreePtr call)
+GenTreePtr Compiler::gtGetThisArg(GenTreeCall* call)
{
- assert(call->gtOper == GT_CALL);
-
- if (call->gtCall.gtCallObjp != nullptr)
+ if (call->gtCallObjp != nullptr)
{
- if (call->gtCall.gtCallObjp->gtOper != GT_NOP && call->gtCall.gtCallObjp->gtOper != GT_ASG)
+ if (call->gtCallObjp->gtOper != GT_NOP && call->gtCallObjp->gtOper != GT_ASG)
{
- if (!(call->gtCall.gtCallObjp->gtFlags & GTF_LATE_ARG))
+ if (!(call->gtCallObjp->gtFlags & GTF_LATE_ARG))
{
- return call->gtCall.gtCallObjp;
+ return call->gtCallObjp;
}
}
- if (call->gtCall.gtCallLateArgs)
+ if (call->gtCallLateArgs)
{
regNumber thisReg = REG_ARG_0;
unsigned argNum = 0;
@@ -8658,13 +8646,13 @@ GenTreePtr Compiler::gtGetThisArg(GenTreePtr call)
GenTreePtr result = thisArgTabEntry->node;
#if !FEATURE_FIXED_OUT_ARGS
- GenTreePtr lateArgs = call->gtCall.gtCallLateArgs;
- regList list = call->gtCall.regArgList;
+ GenTreePtr lateArgs = call->gtCallLateArgs;
+ regList list = call->regArgList;
int index = 0;
while (lateArgs != NULL)
{
assert(lateArgs->gtOper == GT_LIST);
- assert(index < call->gtCall.regArgListCount);
+ assert(index < call->regArgListCount);
regNumber curArgReg = list[index];
if (curArgReg == thisReg)
{
@@ -8811,8 +8799,8 @@ void GenTree::CopyTo(class Compiler* comp, const GenTree& gt)
{
SetOperRaw(gt.OperGet());
- gtType = gt.gtType;
- gtAssertionNum = gt.gtAssertionNum;
+ gtType = gt.gtType;
+ gtAssertionInfo = gt.gtAssertionInfo;
gtRegNum = gt.gtRegNum; // one union member.
CopyCosts(&gt);
@@ -9183,529 +9171,553 @@ GenTreePtr GenTree::GetChild(unsigned childNum)
}
}
-GenTreeUseEdgeIterator::GenTreeUseEdgeIterator() : m_node(nullptr), m_edge(nullptr), m_argList(nullptr), m_state(-1)
+GenTreeUseEdgeIterator::GenTreeUseEdgeIterator()
+ : m_advance(nullptr), m_node(nullptr), m_edge(nullptr), m_argList(nullptr), m_state(-1)
{
}
GenTreeUseEdgeIterator::GenTreeUseEdgeIterator(GenTree* node)
- : m_node(node), m_edge(nullptr), m_argList(nullptr), m_state(0)
+ : m_advance(nullptr), m_node(node), m_edge(nullptr), m_argList(nullptr), m_state(0)
{
assert(m_node != nullptr);
- // Advance to the first operand.
- ++(*this);
-}
+ // NOTE: the switch statement below must be updated when introducing new nodes.
-//------------------------------------------------------------------------
-// GenTreeUseEdgeIterator::GetNextUseEdge:
-// Gets the next operand of a node with a fixed number of operands.
-// This covers all nodes besides GT_CALL, GT_PHI, and GT_SIMD. For the
-// node types handled by this method, the `m_state` field indicates the
-// index of the next operand to produce.
-//
-// Returns:
-// The node's next operand or nullptr if all operands have been
-// produced.
-//
-GenTree** GenTreeUseEdgeIterator::GetNextUseEdge() const
-{
switch (m_node->OperGet())
{
- case GT_CMPXCHG:
- switch (m_state)
- {
- case 0:
- return &m_node->AsCmpXchg()->gtOpLocation;
- case 1:
- return &m_node->AsCmpXchg()->gtOpValue;
- case 2:
- return &m_node->AsCmpXchg()->gtOpComparand;
- default:
- return nullptr;
+ // Leaf nodes
+ case GT_LCL_VAR:
+ case GT_LCL_FLD:
+ case GT_LCL_VAR_ADDR:
+ case GT_LCL_FLD_ADDR:
+ case GT_CATCH_ARG:
+ case GT_LABEL:
+ case GT_FTN_ADDR:
+ case GT_RET_EXPR:
+ case GT_CNS_INT:
+ case GT_CNS_LNG:
+ case GT_CNS_DBL:
+ case GT_CNS_STR:
+ case GT_MEMORYBARRIER:
+ case GT_JMP:
+ case GT_JCC:
+ case GT_NO_OP:
+ case GT_START_NONGC:
+ case GT_PROF_HOOK:
+#if !FEATURE_EH_FUNCLETS
+ case GT_END_LFIN:
+#endif // !FEATURE_EH_FUNCLETS
+ case GT_PHI_ARG:
+#ifndef LEGACY_BACKEND
+ case GT_JMPTABLE:
+#endif // LEGACY_BACKEND
+ case GT_REG_VAR:
+ case GT_CLS_VAR:
+ case GT_CLS_VAR_ADDR:
+ case GT_ARGPLACE:
+ case GT_PHYSREG:
+ case GT_EMITNOP:
+ case GT_PINVOKE_PROLOG:
+ case GT_PINVOKE_EPILOG:
+ case GT_IL_OFFSET:
+ m_state = -1;
+ return;
+
+ // Standard unary operators
+ case GT_STORE_LCL_VAR:
+ case GT_STORE_LCL_FLD:
+ case GT_NOT:
+ case GT_NEG:
+ case GT_COPY:
+ case GT_RELOAD:
+ case GT_ARR_LENGTH:
+ case GT_CAST:
+ case GT_CKFINITE:
+ case GT_LCLHEAP:
+ case GT_ADDR:
+ case GT_IND:
+ case GT_OBJ:
+ case GT_BLK:
+ case GT_BOX:
+ case GT_ALLOCOBJ:
+ case GT_INIT_VAL:
+ case GT_JTRUE:
+ case GT_SWITCH:
+ case GT_NULLCHECK:
+ case GT_PHYSREGDST:
+ case GT_PUTARG_REG:
+ case GT_PUTARG_STK:
+ case GT_RETURNTRAP:
+ m_edge = &m_node->AsUnOp()->gtOp1;
+ assert(*m_edge != nullptr);
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
+ return;
+
+ // Unary operators with an optional operand
+ case GT_NOP:
+ case GT_RETURN:
+ case GT_RETFILT:
+ if (m_node->AsUnOp()->gtOp1 == nullptr)
+ {
+ assert(m_node->NullOp1Legal());
+ m_state = -1;
}
- case GT_ARR_BOUNDS_CHECK:
-#ifdef FEATURE_SIMD
- case GT_SIMD_CHK:
-#endif // FEATURE_SIMD
- switch (m_state)
+ else
{
- case 0:
- return &m_node->AsBoundsChk()->gtIndex;
- case 1:
- return &m_node->AsBoundsChk()->gtArrLen;
- default:
- return nullptr;
+ m_edge = &m_node->AsUnOp()->gtOp1;
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
}
+ return;
- case GT_FIELD:
- if (m_state == 0)
+ // Variadic nodes
+ case GT_PHI:
+ SetEntryStateForList(m_node->AsUnOp()->gtOp1);
+ return;
+
+ case GT_FIELD_LIST:
+ SetEntryStateForList(m_node);
+ return;
+
+#ifdef FEATURE_SIMD
+ case GT_SIMD:
+ if (m_node->AsSIMD()->gtSIMDIntrinsicID == SIMDIntrinsicInitN)
{
- return &m_node->AsField()->gtFldObj;
+ SetEntryStateForList(m_node->AsSIMD()->gtOp1);
}
- return nullptr;
-
- case GT_STMT:
- if (m_state == 0)
+ else
{
- return &m_node->AsStmt()->gtStmtExpr;
+ SetEntryStateForBinOp();
}
- return nullptr;
+ return;
+#endif // FEATURE_SIMD
- case GT_ARR_ELEM:
- if (m_state == 0)
+ // LEA, which may have no first operand
+ case GT_LEA:
+ if (m_node->AsAddrMode()->gtOp1 == nullptr)
{
- return &m_node->AsArrElem()->gtArrObj;
+ m_edge = &m_node->AsAddrMode()->gtOp2;
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
}
- else if (m_state <= m_node->AsArrElem()->gtArrRank)
+ else
{
- return &m_node->AsArrElem()->gtArrInds[m_state - 1];
+ SetEntryStateForBinOp();
}
- return nullptr;
+ return;
- case GT_ARR_OFFSET:
- switch (m_state)
- {
- case 0:
- return &m_node->AsArrOffs()->gtOffset;
- case 1:
- return &m_node->AsArrOffs()->gtIndex;
- case 2:
- return &m_node->AsArrOffs()->gtArrObj;
- default:
- return nullptr;
- }
+ // Special nodes
+ case GT_CMPXCHG:
+ m_edge = &m_node->AsCmpXchg()->gtOpLocation;
+ assert(*m_edge != nullptr);
+ m_advance = &GenTreeUseEdgeIterator::AdvanceCmpXchg;
+ return;
- // Call, phi, and SIMD nodes are handled by MoveNext{Call,Phi,SIMD}UseEdge, repsectively.
- case GT_CALL:
- case GT_PHI:
+ case GT_ARR_BOUNDS_CHECK:
#ifdef FEATURE_SIMD
- case GT_SIMD:
-#endif
- break;
+ case GT_SIMD_CHK:
+#endif // FEATURE_SIMD
+ m_edge = &m_node->AsBoundsChk()->gtIndex;
+ assert(*m_edge != nullptr);
+ m_advance = &GenTreeUseEdgeIterator::AdvanceBoundsChk;
+ return;
- case GT_ASG:
- {
- bool operandsReversed = (m_node->gtFlags & GTF_REVERSE_OPS) != 0;
- switch (m_state)
+ case GT_FIELD:
+ if (m_node->AsField()->gtFldObj == nullptr)
{
- case 0:
- return !operandsReversed ? &(m_node->AsOp()->gtOp1) : &(m_node->AsOp()->gtOp2);
- case 1:
- return !operandsReversed ? &(m_node->AsOp()->gtOp2) : &(m_node->AsOp()->gtOp1);
- default:
- return nullptr;
+ m_state = -1;
}
- }
+ else
+ {
+ m_edge = &m_node->AsField()->gtFldObj;
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
+ }
+ return;
+
+ case GT_STMT:
+ if (m_node->AsStmt()->gtStmtExpr == nullptr)
+ {
+ m_state = -1;
+ }
+ else
+ {
+ m_edge = &m_node->AsStmt()->gtStmtExpr;
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
+ }
+ return;
+
+ case GT_ARR_ELEM:
+ m_edge = &m_node->AsArrElem()->gtArrObj;
+ assert(*m_edge != nullptr);
+ m_advance = &GenTreeUseEdgeIterator::AdvanceArrElem;
+ return;
+
+ case GT_ARR_OFFSET:
+ m_edge = &m_node->AsArrOffs()->gtOffset;
+ assert(*m_edge != nullptr);
+ m_advance = &GenTreeUseEdgeIterator::AdvanceArrOffset;
+ return;
case GT_DYN_BLK:
{
GenTreeDynBlk* const dynBlock = m_node->AsDynBlk();
- switch (m_state)
- {
- case 0:
- return dynBlock->gtEvalSizeFirst ? &dynBlock->gtDynamicSize : &dynBlock->gtOp1;
- case 1:
- return dynBlock->gtEvalSizeFirst ? &dynBlock->gtOp1 : &dynBlock->gtDynamicSize;
- default:
- return nullptr;
- }
+ m_edge = dynBlock->gtEvalSizeFirst ? &dynBlock->gtDynamicSize : &dynBlock->gtOp1;
+ assert(*m_edge != nullptr);
+ m_advance = &GenTreeUseEdgeIterator::AdvanceDynBlk;
}
- break;
+ return;
case GT_STORE_DYN_BLK:
{
GenTreeDynBlk* const dynBlock = m_node->AsDynBlk();
if (dynBlock->gtEvalSizeFirst)
{
- switch (m_state)
- {
- case 0:
- return &dynBlock->gtDynamicSize;
- case 1:
- return dynBlock->IsReverseOp() ? &dynBlock->gtOp2 : &dynBlock->gtOp1;
- case 2:
- return dynBlock->IsReverseOp() ? &dynBlock->gtOp1 : &dynBlock->gtOp2;
- default:
- return nullptr;
- }
+ m_edge = &dynBlock->gtDynamicSize;
}
else
{
- switch (m_state)
- {
- case 0:
- return dynBlock->IsReverseOp() ? &dynBlock->gtOp2 : &dynBlock->gtOp1;
- case 1:
- return dynBlock->IsReverseOp() ? &dynBlock->gtOp1 : &dynBlock->gtOp2;
- case 2:
- return &dynBlock->gtDynamicSize;
- default:
- return nullptr;
- }
- }
- }
- break;
-
- case GT_LEA:
- {
- GenTreeAddrMode* lea = m_node->AsAddrMode();
-
- bool hasOp1 = lea->gtOp1 != nullptr;
- if (!hasOp1)
- {
- return m_state == 0 ? &lea->gtOp2 : nullptr;
+ m_edge = dynBlock->IsReverseOp() ? &dynBlock->gtOp2 : &dynBlock->gtOp1;
}
+ assert(*m_edge != nullptr);
- bool operandsReversed = (lea->gtFlags & GTF_REVERSE_OPS) != 0;
- switch (m_state)
- {
- case 0:
- return !operandsReversed ? &lea->gtOp1 : &lea->gtOp2;
- case 1:
- return !operandsReversed ? &lea->gtOp2 : &lea->gtOp1;
- default:
- return nullptr;
- }
+ m_advance = &GenTreeUseEdgeIterator::AdvanceStoreDynBlk;
}
- break;
+ return;
- case GT_FIELD_LIST:
- // Field List nodes are handled by MoveToNextFieldUseEdge.
- break;
+ case GT_CALL:
+ AdvanceCall<CALL_INSTANCE>();
+ return;
+ // Binary nodes
default:
- if (m_node->OperIsConst() || m_node->OperIsLeaf())
- {
- return nullptr;
- }
- else if (m_node->OperIsUnary())
- {
- return m_state == 0 ? &m_node->AsUnOp()->gtOp1 : nullptr;
- }
- else if (m_node->OperIsBinary())
- {
- bool operandsReversed = (m_node->gtFlags & GTF_REVERSE_OPS) != 0;
- switch (m_state)
- {
- case 0:
- return !operandsReversed ? &m_node->AsOp()->gtOp1 : &m_node->AsOp()->gtOp2;
- case 1:
- return !operandsReversed ? &m_node->AsOp()->gtOp2 : &m_node->AsOp()->gtOp1;
- default:
- return nullptr;
- }
- }
+ assert(m_node->OperIsBinary());
+ SetEntryStateForBinOp();
+ return;
}
-
- unreached();
}
//------------------------------------------------------------------------
-// GenTreeUseEdgeIterator::MoveToNextCallUseEdge:
-// Moves to the next operand of a call node. Unlike the simple nodes
-// handled by `GetNextUseEdge`, call nodes have a variable number of
-// operands stored in cons lists. This method expands the cons lists
-// into the operands stored within.
+// GenTreeUseEdgeIterator::AdvanceCmpXchg: produces the next operand of a CmpXchg node and advances the state.
//
-void GenTreeUseEdgeIterator::MoveToNextCallUseEdge()
+void GenTreeUseEdgeIterator::AdvanceCmpXchg()
{
- enum
- {
- CALL_INSTANCE = 0,
- CALL_ARGS = 1,
- CALL_LATE_ARGS = 2,
- CALL_CONTROL_EXPR = 3,
- CALL_COOKIE = 4,
- CALL_ADDRESS = 5,
- CALL_TERMINAL = 6,
- };
-
- GenTreeCall* call = m_node->AsCall();
-
- for (;;)
+ switch (m_state)
{
- switch (m_state)
- {
- case CALL_INSTANCE:
- m_state = CALL_ARGS;
- m_argList = call->gtCallArgs;
-
- if (call->gtCallObjp != nullptr)
- {
- m_edge = &call->gtCallObjp;
- return;
- }
- break;
-
- case CALL_ARGS:
- case CALL_LATE_ARGS:
- if (m_argList == nullptr)
- {
- m_state++;
-
- if (m_state == CALL_LATE_ARGS)
- {
- m_argList = call->gtCallLateArgs;
- }
- }
- else
- {
- GenTreeArgList* argNode = m_argList->AsArgList();
- m_edge = &argNode->gtOp1;
- m_argList = argNode->Rest();
- return;
- }
- break;
-
- case CALL_CONTROL_EXPR:
- m_state = call->gtCallType == CT_INDIRECT ? CALL_COOKIE : CALL_TERMINAL;
+ case 0:
+ m_edge = &m_node->AsCmpXchg()->gtOpValue;
+ m_state = 1;
+ break;
+ case 1:
+ m_edge = &m_node->AsCmpXchg()->gtOpComparand;
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
+ break;
+ default:
+ unreached();
+ }
- if (call->gtControlExpr != nullptr)
- {
- m_edge = &call->gtControlExpr;
- return;
- }
- break;
+ assert(*m_edge != nullptr);
+}
- case 4:
- assert(call->gtCallType == CT_INDIRECT);
+//------------------------------------------------------------------------
+// GenTreeUseEdgeIterator::AdvanceBoundsChk: produces the next operand of a BoundsChk node and advances the state.
+//
+void GenTreeUseEdgeIterator::AdvanceBoundsChk()
+{
+ m_edge = &m_node->AsBoundsChk()->gtArrLen;
+ assert(*m_edge != nullptr);
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
+}
- m_state = CALL_ADDRESS;
+//------------------------------------------------------------------------
+// GenTreeUseEdgeIterator::AdvanceArrElem: produces the next operand of a ArrElem node and advances the state.
+//
+// Because these nodes are variadic, this function uses `m_state` to index into the list of array indices.
+//
+void GenTreeUseEdgeIterator::AdvanceArrElem()
+{
+ if (m_state < m_node->AsArrElem()->gtArrRank)
+ {
+ m_edge = &m_node->AsArrElem()->gtArrInds[m_state];
+ assert(*m_edge != nullptr);
+ m_state++;
+ }
+ else
+ {
+ m_state = -1;
+ }
+}
- if (call->gtCallCookie != nullptr)
- {
- m_edge = &call->gtCallCookie;
- return;
- }
- break;
+//------------------------------------------------------------------------
+// GenTreeUseEdgeIterator::AdvanceArrOffset: produces the next operand of a ArrOffset node and advances the state.
+//
+void GenTreeUseEdgeIterator::AdvanceArrOffset()
+{
+ switch (m_state)
+ {
+ case 0:
+ m_edge = &m_node->AsArrOffs()->gtIndex;
+ m_state = 1;
+ break;
+ case 1:
+ m_edge = &m_node->AsArrOffs()->gtArrObj;
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
+ break;
+ default:
+ unreached();
+ }
- case 5:
- assert(call->gtCallType == CT_INDIRECT);
+ assert(*m_edge != nullptr);
+}
- m_state = CALL_TERMINAL;
- if (call->gtCallAddr != nullptr)
- {
- m_edge = &call->gtCallAddr;
- return;
- }
- break;
+//------------------------------------------------------------------------
+// GenTreeUseEdgeIterator::AdvanceDynBlk: produces the next operand of a DynBlk node and advances the state.
+//
+void GenTreeUseEdgeIterator::AdvanceDynBlk()
+{
+ GenTreeDynBlk* const dynBlock = m_node->AsDynBlk();
- default:
- m_node = nullptr;
- m_edge = nullptr;
- m_argList = nullptr;
- m_state = -1;
- return;
- }
- }
+ m_edge = dynBlock->gtEvalSizeFirst ? &dynBlock->gtOp1 : &dynBlock->gtDynamicSize;
+ assert(*m_edge != nullptr);
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
}
//------------------------------------------------------------------------
-// GenTreeUseEdgeIterator::MoveToNextPhiUseEdge:
-// Moves to the next operand of a phi node. Unlike the simple nodes
-// handled by `GetNextUseEdge`, phi nodes have a variable number of
-// operands stored in a cons list. This method expands the cons list
-// into the operands stored within.
+// GenTreeUseEdgeIterator::AdvanceStoreDynBlk: produces the next operand of a StoreDynBlk node and advances the state.
//
-void GenTreeUseEdgeIterator::MoveToNextPhiUseEdge()
+// These nodes are moderately complicated but rare enough that templating this function is probably not
+// worth the extra complexity.
+//
+void GenTreeUseEdgeIterator::AdvanceStoreDynBlk()
{
- GenTreeUnOp* phi = m_node->AsUnOp();
-
- for (;;)
+ GenTreeDynBlk* const dynBlock = m_node->AsDynBlk();
+ if (dynBlock->gtEvalSizeFirst)
{
switch (m_state)
{
case 0:
- m_state = 1;
- m_argList = phi->gtOp1;
+ m_edge = dynBlock->IsReverseOp() ? &dynBlock->gtOp2 : &dynBlock->gtOp1;
+ m_state = 1;
break;
-
case 1:
- if (m_argList == nullptr)
- {
- m_state = 2;
- }
- else
- {
- GenTreeArgList* argNode = m_argList->AsArgList();
- m_edge = &argNode->gtOp1;
- m_argList = argNode->Rest();
- return;
- }
+ m_edge = dynBlock->IsReverseOp() ? &dynBlock->gtOp1 : &dynBlock->gtOp2;
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
break;
-
default:
- m_node = nullptr;
- m_edge = nullptr;
- m_argList = nullptr;
- m_state = -1;
- return;
+ unreached();
}
}
-}
-
-#ifdef FEATURE_SIMD
-//------------------------------------------------------------------------
-// GenTreeUseEdgeIterator::MoveToNextSIMDUseEdge:
-// Moves to the next operand of a SIMD node. Most SIMD nodes have a
-// fixed number of operands and are handled accordingly.
-// `SIMDIntrinsicInitN` nodes, however, have a variable number of
-// operands stored in a cons list. This method expands the cons list
-// into the operands stored within.
-//
-void GenTreeUseEdgeIterator::MoveToNextSIMDUseEdge()
-{
- GenTreeSIMD* simd = m_node->AsSIMD();
-
- if (simd->gtSIMDIntrinsicID != SIMDIntrinsicInitN)
+ else
{
- bool operandsReversed = (simd->gtFlags & GTF_REVERSE_OPS) != 0;
switch (m_state)
{
case 0:
- m_edge = !operandsReversed ? &simd->gtOp1 : &simd->gtOp2;
+ m_edge = dynBlock->IsReverseOp() ? &dynBlock->gtOp1 : &dynBlock->gtOp2;
+ m_state = 1;
break;
case 1:
- m_edge = !operandsReversed ? &simd->gtOp2 : &simd->gtOp1;
+ m_edge = &dynBlock->gtDynamicSize;
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
break;
default:
- m_edge = nullptr;
- break;
+ unreached();
}
+ }
- if (m_edge != nullptr && *m_edge != nullptr)
- {
- m_state++;
- }
- else
- {
- m_node = nullptr;
- m_state = -1;
- }
+ assert(*m_edge != nullptr);
+}
- return;
- }
+//------------------------------------------------------------------------
+// GenTreeUseEdgeIterator::AdvanceBinOp: produces the next operand of a binary node and advances the state.
+//
+// This function must be instantiated s.t. `ReverseOperands` is `true` iff the node is marked with the
+// `GTF_REVERSE_OPS` flag.
+//
+template <bool ReverseOperands>
+void GenTreeUseEdgeIterator::AdvanceBinOp()
+{
+ assert(ReverseOperands == ((m_node->gtFlags & GTF_REVERSE_OPS) != 0));
- for (;;)
+ m_edge = !ReverseOperands ? &m_node->AsOp()->gtOp2 : &m_node->AsOp()->gtOp1;
+ assert(*m_edge != nullptr);
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
+}
+
+//------------------------------------------------------------------------
+// GenTreeUseEdgeIterator::SetEntryStateForBinOp: produces the first operand of a binary node and chooses
+// the appropriate advance function.
+//
+void GenTreeUseEdgeIterator::SetEntryStateForBinOp()
+{
+ assert(m_node != nullptr);
+ assert(m_node->OperIsBinary());
+
+ GenTreeOp* const node = m_node->AsOp();
+
+ if (node->gtOp2 == nullptr)
{
- switch (m_state)
- {
- case 0:
- m_state = 1;
- m_argList = simd->gtOp1;
- break;
+ assert(node->gtOp1 != nullptr);
+ assert(node->NullOp2Legal());
+ m_edge = &node->gtOp1;
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
+ }
+ else if ((node->gtFlags & GTF_REVERSE_OPS) != 0)
+ {
+ m_edge = &m_node->AsOp()->gtOp2;
+ m_advance = &GenTreeUseEdgeIterator::AdvanceBinOp<true>;
+ }
+ else
+ {
+ m_edge = &m_node->AsOp()->gtOp1;
+ m_advance = &GenTreeUseEdgeIterator::AdvanceBinOp<false>;
+ }
+}
- case 1:
- if (m_argList == nullptr)
- {
- m_state = 2;
- }
- else
- {
- GenTreeArgList* argNode = m_argList->AsArgList();
- m_edge = &argNode->gtOp1;
- m_argList = argNode->Rest();
- return;
- }
- break;
+//------------------------------------------------------------------------
+// GenTreeUseEdgeIterator::AdvanceList: produces the next operand of a variadic node and advances the state.
+//
+// This function does not use `m_state` for anything meaningful; it simply walks the `m_argList` until
+// there are no further entries.
+//
+void GenTreeUseEdgeIterator::AdvanceList()
+{
+ assert(m_state == 0);
- default:
- m_node = nullptr;
- m_edge = nullptr;
- m_argList = nullptr;
- m_state = -1;
- return;
- }
+ if (m_argList == nullptr)
+ {
+ m_state = -1;
+ }
+ else
+ {
+ GenTreeArgList* listNode = m_argList->AsArgList();
+ m_edge = &listNode->gtOp1;
+ m_argList = listNode->Rest();
}
}
-#endif // FEATURE_SIMD
-void GenTreeUseEdgeIterator::MoveToNextFieldUseEdge()
+//------------------------------------------------------------------------
+// GenTreeUseEdgeIterator::SetEntryStateForList: produces the first operand of a list node.
+//
+void GenTreeUseEdgeIterator::SetEntryStateForList(GenTree* list)
{
- assert(m_node->OperGet() == GT_FIELD_LIST);
+ m_argList = list;
+ m_advance = &GenTreeUseEdgeIterator::AdvanceList;
+ AdvanceList();
+}
- for (;;)
+//------------------------------------------------------------------------
+// GenTreeUseEdgeIterator::AdvanceCall: produces the next operand of a call node and advances the state.
+//
+// This function is a bit tricky: in order to avoid doing unnecessary work, it is instantiated with the
+// state number the iterator will be in when it is called. For example, `AdvanceCall<CALL_INSTANCE>`
+// is the instantiation used when the iterator is at the `CALL_INSTANCE` state (i.e. the entry state).
+// This sort of templating allows each state to avoid processing earlier states without unnecessary
+// duplication of code.
+//
+// Note that this method expands the argument lists (`gtCallArgs` and `gtCallLateArgs`) into their
+// component operands.
+//
+template <int state>
+void GenTreeUseEdgeIterator::AdvanceCall()
+{
+ GenTreeCall* const call = m_node->AsCall();
+
+ switch (state)
{
- switch (m_state)
- {
- case 0:
- m_state = 1;
- m_argList = m_node;
- break;
+ case CALL_INSTANCE:
+ m_argList = call->gtCallArgs;
+ m_advance = &GenTreeUseEdgeIterator::AdvanceCall<CALL_ARGS>;
+ if (call->gtCallObjp != nullptr)
+ {
+ m_edge = &call->gtCallObjp;
+ return;
+ }
+ __fallthrough;
- case 1:
- if (m_argList == nullptr)
+ case CALL_ARGS:
+ if (m_argList != nullptr)
+ {
+ GenTreeArgList* argNode = m_argList->AsArgList();
+ m_edge = &argNode->gtOp1;
+ m_argList = argNode->Rest();
+ return;
+ }
+ m_argList = call->gtCallLateArgs;
+ m_advance = &GenTreeUseEdgeIterator::AdvanceCall<CALL_LATE_ARGS>;
+ __fallthrough;
+
+ case CALL_LATE_ARGS:
+ if (m_argList != nullptr)
+ {
+ GenTreeArgList* argNode = m_argList->AsArgList();
+ m_edge = &argNode->gtOp1;
+ m_argList = argNode->Rest();
+ return;
+ }
+ m_advance = &GenTreeUseEdgeIterator::AdvanceCall<CALL_CONTROL_EXPR>;
+ __fallthrough;
+
+ case CALL_CONTROL_EXPR:
+ if (call->gtControlExpr != nullptr)
+ {
+ if (call->gtCallType == CT_INDIRECT)
{
- m_state = 2;
+ m_advance = &GenTreeUseEdgeIterator::AdvanceCall<CALL_COOKIE>;
}
else
{
- GenTreeArgList* listNode = m_argList->AsArgList();
- m_edge = &listNode->gtOp1;
- m_argList = listNode->Rest();
- return;
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
}
- break;
+ m_edge = &call->gtControlExpr;
+ return;
+ }
+ else if (call->gtCallType != CT_INDIRECT)
+ {
+ m_state = -1;
+ return;
+ }
+ __fallthrough;
- default:
- m_node = nullptr;
- m_edge = nullptr;
- m_argList = nullptr;
- m_state = -1;
+ case CALL_COOKIE:
+ assert(call->gtCallType == CT_INDIRECT);
+
+ m_advance = &GenTreeUseEdgeIterator::AdvanceCall<CALL_ADDRESS>;
+ if (call->gtCallCookie != nullptr)
+ {
+ m_edge = &call->gtCallCookie;
return;
- }
+ }
+ __fallthrough;
+
+ case CALL_ADDRESS:
+ assert(call->gtCallType == CT_INDIRECT);
+
+ m_advance = &GenTreeUseEdgeIterator::Terminate;
+ if (call->gtCallAddr != nullptr)
+ {
+ m_edge = &call->gtCallAddr;
+ }
+ return;
+
+ default:
+ unreached();
}
}
//------------------------------------------------------------------------
-// GenTreeUseEdgeIterator::operator++:
-// Advances the iterator to the next operand.
+// GenTreeUseEdgeIterator::Terminate: advances the iterator to the terminal state.
+//
+void GenTreeUseEdgeIterator::Terminate()
+{
+ m_state = -1;
+}
+
+//------------------------------------------------------------------------
+// GenTreeUseEdgeIterator::operator++: advances the iterator to the next operand.
//
GenTreeUseEdgeIterator& GenTreeUseEdgeIterator::operator++()
{
- if (m_state == -1)
+ // If we've reached the terminal state, do nothing.
+ if (m_state != -1)
{
- // If we've reached the terminal state, do nothing.
- assert(m_node == nullptr);
- assert(m_edge == nullptr);
- assert(m_argList == nullptr);
- }
- else
- {
- // Otherwise, move to the next operand in the node.
- genTreeOps op = m_node->OperGet();
- if (op == GT_CALL)
- {
- MoveToNextCallUseEdge();
- }
- else if (op == GT_PHI)
- {
- MoveToNextPhiUseEdge();
- }
-#ifdef FEATURE_SIMD
- else if (op == GT_SIMD)
- {
- MoveToNextSIMDUseEdge();
- }
-#endif
- else if (op == GT_FIELD_LIST)
- {
- MoveToNextFieldUseEdge();
- }
- else
- {
- m_edge = GetNextUseEdge();
- if (m_edge != nullptr && *m_edge != nullptr)
- {
- m_state++;
- }
- else
- {
- m_edge = nullptr;
- m_node = nullptr;
- m_state = -1;
- }
- }
+ (this->*m_advance)();
}
return *this;
@@ -11580,39 +11592,40 @@ void Compiler::gtDispTree(GenTreePtr tree,
case GT_CALL:
{
- assert(tree->gtFlags & GTF_CALL);
- unsigned numChildren = tree->NumChildren();
+ GenTreeCall* call = tree->AsCall();
+ assert(call->gtFlags & GTF_CALL);
+ unsigned numChildren = call->NumChildren();
GenTree* lastChild = nullptr;
if (numChildren != 0)
{
- lastChild = tree->GetChild(numChildren - 1);
+ lastChild = call->GetChild(numChildren - 1);
}
- if (tree->gtCall.gtCallType != CT_INDIRECT)
+ if (call->gtCallType != CT_INDIRECT)
{
const char* methodName;
const char* className;
- methodName = eeGetMethodName(tree->gtCall.gtCallMethHnd, &className);
+ methodName = eeGetMethodName(call->gtCallMethHnd, &className);
printf(" %s.%s", className, methodName);
}
- if ((tree->gtFlags & GTF_CALL_UNMANAGED) && (tree->gtCall.gtCallMoreFlags & GTF_CALL_M_FRAME_VAR_DEATH))
+ if ((call->gtFlags & GTF_CALL_UNMANAGED) && (call->gtCallMoreFlags & GTF_CALL_M_FRAME_VAR_DEATH))
{
printf(" (FramesRoot last use)");
}
- if (((tree->gtFlags & GTF_CALL_INLINE_CANDIDATE) != 0) && (tree->gtCall.gtInlineCandidateInfo != nullptr) &&
- (tree->gtCall.gtInlineCandidateInfo->exactContextHnd != nullptr))
+ if (((call->gtFlags & GTF_CALL_INLINE_CANDIDATE) != 0) && (call->gtInlineCandidateInfo != nullptr) &&
+ (call->gtInlineCandidateInfo->exactContextHnd != nullptr))
{
- printf(" (exactContextHnd=0x%p)", dspPtr(tree->gtCall.gtInlineCandidateInfo->exactContextHnd));
+ printf(" (exactContextHnd=0x%p)", dspPtr(call->gtInlineCandidateInfo->exactContextHnd));
}
- gtDispVN(tree);
- if (tree->IsMultiRegCall())
+ gtDispVN(call);
+ if (call->IsMultiRegCall())
{
- gtDispRegVal(tree);
+ gtDispRegVal(call);
}
printf("\n");
@@ -11623,10 +11636,10 @@ void Compiler::gtDispTree(GenTreePtr tree,
bufp = &buf[0];
- if ((tree->gtCall.gtCallObjp != nullptr) && (tree->gtCall.gtCallObjp->gtOper != GT_NOP) &&
- (!tree->gtCall.gtCallObjp->IsArgPlaceHolderNode()))
+ if ((call->gtCallObjp != nullptr) && (call->gtCallObjp->gtOper != GT_NOP) &&
+ (!call->gtCallObjp->IsArgPlaceHolderNode()))
{
- if (tree->gtCall.gtCallObjp->gtOper == GT_ASG)
+ if (call->gtCallObjp->gtOper == GT_ASG)
{
sprintf_s(bufp, sizeof(buf), "this SETUP%c", 0);
}
@@ -11634,34 +11647,33 @@ void Compiler::gtDispTree(GenTreePtr tree,
{
sprintf_s(bufp, sizeof(buf), "this in %s%c", compRegVarName(REG_ARG_0), 0);
}
- gtDispChild(tree->gtCall.gtCallObjp, indentStack,
- (tree->gtCall.gtCallObjp == lastChild) ? IIArcBottom : IIArc, bufp, topOnly);
+ gtDispChild(call->gtCallObjp, indentStack, (call->gtCallObjp == lastChild) ? IIArcBottom : IIArc,
+ bufp, topOnly);
}
- if (tree->gtCall.gtCallArgs)
+ if (call->gtCallArgs)
{
- gtDispArgList(tree, indentStack);
+ gtDispArgList(call, indentStack);
}
- if (tree->gtCall.gtCallType == CT_INDIRECT)
+ if (call->gtCallType == CT_INDIRECT)
{
- gtDispChild(tree->gtCall.gtCallAddr, indentStack,
- (tree->gtCall.gtCallAddr == lastChild) ? IIArcBottom : IIArc, "calli tgt", topOnly);
+ gtDispChild(call->gtCallAddr, indentStack, (call->gtCallAddr == lastChild) ? IIArcBottom : IIArc,
+ "calli tgt", topOnly);
}
- if (tree->gtCall.gtControlExpr != nullptr)
+ if (call->gtControlExpr != nullptr)
{
- gtDispChild(tree->gtCall.gtControlExpr, indentStack,
- (tree->gtCall.gtControlExpr == lastChild) ? IIArcBottom : IIArc, "control expr",
- topOnly);
+ gtDispChild(call->gtControlExpr, indentStack,
+ (call->gtControlExpr == lastChild) ? IIArcBottom : IIArc, "control expr", topOnly);
}
#if !FEATURE_FIXED_OUT_ARGS
- regList list = tree->gtCall.regArgList;
+ regList list = call->regArgList;
#endif
/* process the late argument list */
int lateArgIndex = 0;
- for (GenTreeArgList* lateArgs = tree->gtCall.gtCallLateArgs; lateArgs;
+ for (GenTreeArgList* lateArgs = call->gtCallLateArgs; lateArgs;
(lateArgIndex++, lateArgs = lateArgs->Rest()))
{
GenTreePtr argx;
@@ -11669,7 +11681,7 @@ void Compiler::gtDispTree(GenTreePtr tree,
argx = lateArgs->Current();
IndentInfo arcType = (lateArgs->Rest() == nullptr) ? IIArcBottom : IIArc;
- gtGetLateArgMsg(tree, argx, lateArgIndex, -1, bufp, sizeof(buf));
+ gtGetLateArgMsg(call, argx, lateArgIndex, -1, bufp, sizeof(buf));
gtDispChild(argx, indentStack, arcType, bufp, topOnly);
}
}
@@ -11787,9 +11799,9 @@ void Compiler::gtDispTree(GenTreePtr tree,
// 'arg' must be an argument to 'call' (else gtArgEntryByNode will assert)
void Compiler::gtGetArgMsg(
- GenTreePtr call, GenTreePtr arg, unsigned argNum, int listCount, char* bufp, unsigned bufLength)
+ GenTreeCall* call, GenTreePtr arg, unsigned argNum, int listCount, char* bufp, unsigned bufLength)
{
- if (call->gtCall.gtCallLateArgs != nullptr)
+ if (call->gtCallLateArgs != nullptr)
{
fgArgTabEntryPtr curArgTabEntry = gtArgEntryByArgNum(call, argNum);
assert(curArgTabEntry);
@@ -11843,7 +11855,7 @@ void Compiler::gtGetArgMsg(
// 'arg' must be an argument to 'call' (else gtArgEntryByNode will assert)
void Compiler::gtGetLateArgMsg(
- GenTreePtr call, GenTreePtr argx, int lateArgIndex, int listCount, char* bufp, unsigned bufLength)
+ GenTreeCall* call, GenTreePtr argx, int lateArgIndex, int listCount, char* bufp, unsigned bufLength)
{
assert(!argx->IsArgPlaceHolderNode()); // No place holders nodes are in gtCallLateArgs;
@@ -11852,8 +11864,8 @@ void Compiler::gtGetLateArgMsg(
regNumber argReg = curArgTabEntry->regNum;
#if !FEATURE_FIXED_OUT_ARGS
- assert(lateArgIndex < call->gtCall.regArgListCount);
- assert(argReg == call->gtCall.regArgList[lateArgIndex]);
+ assert(lateArgIndex < call->regArgListCount);
+ assert(argReg == call->regArgList[lateArgIndex]);
#else
if (argReg == REG_STK)
{
@@ -11908,28 +11920,25 @@ void Compiler::gtGetLateArgMsg(
// gtDispArgList: Dump the tree for a call arg list
//
// Arguments:
-// tree - The call for which 'arg' is an argument
+// call - The call to dump arguments for
// indentStack - the specification for the current level of indentation & arcs
//
// Return Value:
// None.
//
-// Assumptions:
-// 'tree' must be a call node
-
-void Compiler::gtDispArgList(GenTreePtr tree, IndentStack* indentStack)
+void Compiler::gtDispArgList(GenTreeCall* call, IndentStack* indentStack)
{
- GenTree* args = tree->gtCall.gtCallArgs;
+ GenTree* args = call->gtCallArgs;
unsigned argnum = 0;
const int BufLength = 256;
char buf[BufLength];
char* bufp = &buf[0];
- unsigned numChildren = tree->NumChildren();
+ unsigned numChildren = call->NumChildren();
assert(numChildren != 0);
- bool argListIsLastChild = (args == tree->GetChild(numChildren - 1));
+ bool argListIsLastChild = (args == call->GetChild(numChildren - 1));
IndentInfo arcType = IIArc;
- if (tree->gtCall.gtCallObjp != nullptr)
+ if (call->gtCallObjp != nullptr)
{
argnum++;
}
@@ -11940,7 +11949,7 @@ void Compiler::gtDispArgList(GenTreePtr tree, IndentStack* indentStack)
GenTree* arg = args->gtOp.gtOp1;
if (!arg->IsNothingNode() && !arg->IsArgPlaceHolderNode())
{
- gtGetArgMsg(tree, arg, argnum, -1, bufp, BufLength);
+ gtGetArgMsg(call, arg, argnum, -1, bufp, BufLength);
if (argListIsLastChild && (args->gtOp.gtOp2 == nullptr))
{
arcType = IIArcBottom;
@@ -12008,16 +12017,23 @@ void Compiler::gtDispTreeRange(LIR::Range& containingRange, GenTree* tree)
//
// Arguments:
// node - the LIR node to dump.
+// prefixMsg - an optional prefix for each line of output.
//
-void Compiler::gtDispLIRNode(GenTree* node)
+void Compiler::gtDispLIRNode(GenTree* node, const char* prefixMsg /* = nullptr */)
{
- auto displayOperand = [](GenTree* operand, const char* message, IndentInfo operandArc, IndentStack& indentStack) {
+ auto displayOperand = [](GenTree* operand, const char* message, IndentInfo operandArc, IndentStack& indentStack,
+ size_t prefixIndent) {
assert(operand != nullptr);
assert(message != nullptr);
+ if (prefixIndent != 0)
+ {
+ printf("%*s", (int)prefixIndent, "");
+ }
+
// 49 spaces for alignment
printf("%-49s", "");
-#ifdef FEATURE_SET_FLAGS
+#if FEATURE_SET_FLAGS
// additional flag enlarges the flag field by one character
printf(" ");
#endif
@@ -12028,11 +12044,16 @@ void Compiler::gtDispLIRNode(GenTree* node)
operandArc = IIArc;
printf(" t%-5d %-6s %s\n", operand->gtTreeID, varTypeName(operand->TypeGet()), message);
-
};
IndentStack indentStack(this);
+ size_t prefixIndent = 0;
+ if (prefixMsg != nullptr)
+ {
+ prefixIndent = strlen(prefixMsg);
+ }
+
const int bufLength = 256;
char buf[bufLength];
@@ -12054,19 +12075,19 @@ void Compiler::gtDispLIRNode(GenTree* node)
if (operand == call->gtCallObjp)
{
sprintf_s(buf, sizeof(buf), "this in %s", compRegVarName(REG_ARG_0));
- displayOperand(operand, buf, operandArc, indentStack);
+ displayOperand(operand, buf, operandArc, indentStack, prefixIndent);
}
else if (operand == call->gtCallAddr)
{
- displayOperand(operand, "calli tgt", operandArc, indentStack);
+ displayOperand(operand, "calli tgt", operandArc, indentStack, prefixIndent);
}
else if (operand == call->gtControlExpr)
{
- displayOperand(operand, "control expr", operandArc, indentStack);
+ displayOperand(operand, "control expr", operandArc, indentStack, prefixIndent);
}
else if (operand == call->gtCallCookie)
{
- displayOperand(operand, "cookie", operandArc, indentStack);
+ displayOperand(operand, "cookie", operandArc, indentStack, prefixIndent);
}
else
{
@@ -12088,7 +12109,7 @@ void Compiler::gtDispLIRNode(GenTree* node)
gtGetLateArgMsg(call, operand, curArgTabEntry->lateArgInx, listIndex, buf, sizeof(buf));
}
- displayOperand(operand, buf, operandArc, indentStack);
+ displayOperand(operand, buf, operandArc, indentStack, prefixIndent);
operandArc = IIArc;
}
}
@@ -12103,7 +12124,7 @@ void Compiler::gtDispLIRNode(GenTree* node)
gtGetLateArgMsg(call, operand, curArgTabEntry->lateArgInx, -1, buf, sizeof(buf));
}
- displayOperand(operand, buf, operandArc, indentStack);
+ displayOperand(operand, buf, operandArc, indentStack, prefixIndent);
}
}
}
@@ -12111,55 +12132,59 @@ void Compiler::gtDispLIRNode(GenTree* node)
{
if (operand == node->AsBlk()->Addr())
{
- displayOperand(operand, "lhs", operandArc, indentStack);
+ displayOperand(operand, "lhs", operandArc, indentStack, prefixIndent);
}
else if (operand == node->AsBlk()->Data())
{
- displayOperand(operand, "rhs", operandArc, indentStack);
+ displayOperand(operand, "rhs", operandArc, indentStack, prefixIndent);
}
else
{
assert(operand == node->AsDynBlk()->gtDynamicSize);
- displayOperand(operand, "size", operandArc, indentStack);
+ displayOperand(operand, "size", operandArc, indentStack, prefixIndent);
}
}
else if (node->OperGet() == GT_DYN_BLK)
{
if (operand == node->AsBlk()->Addr())
{
- displayOperand(operand, "lhs", operandArc, indentStack);
+ displayOperand(operand, "lhs", operandArc, indentStack, prefixIndent);
}
else
{
assert(operand == node->AsDynBlk()->gtDynamicSize);
- displayOperand(operand, "size", operandArc, indentStack);
+ displayOperand(operand, "size", operandArc, indentStack, prefixIndent);
}
}
else if (node->OperIsAssignment())
{
if (operand == node->gtGetOp1())
{
- displayOperand(operand, "lhs", operandArc, indentStack);
+ displayOperand(operand, "lhs", operandArc, indentStack, prefixIndent);
}
else
{
- displayOperand(operand, "rhs", operandArc, indentStack);
+ displayOperand(operand, "rhs", operandArc, indentStack, prefixIndent);
}
}
else
{
- displayOperand(operand, "", operandArc, indentStack);
+ displayOperand(operand, "", operandArc, indentStack, prefixIndent);
}
operandArc = IIArc;
}
// Visit the operator
+
+ if (prefixMsg != nullptr)
+ {
+ printf("%s", prefixMsg);
+ }
+
const bool topOnly = true;
const bool isLIR = true;
gtDispTree(node, &indentStack, nullptr, topOnly, isLIR);
-
- printf("\n");
}
/*****************************************************************************/
@@ -13410,15 +13435,10 @@ GenTreePtr Compiler::gtFoldExprConst(GenTreePtr tree)
#endif
#ifdef _TARGET_64BIT_
- // we need to properly re-sign-extend or truncate as needed.
- if (tree->gtFlags & GTF_UNSIGNED)
- {
- i1 = UINT32(i1);
- }
- else
- {
- i1 = INT32(i1);
- }
+ // Some operations are performed as 64 bit instead of 32 bit so the upper 32 bits
+ // need to be discarded. Since constant values are stored as ssize_t and the node
+ // has TYP_INT the result needs to be sign extended rather than zero extended.
+ i1 = INT32(i1);
#endif // _TARGET_64BIT_
/* Also all conditional folding jumps here since the node hanging from
@@ -14927,7 +14947,7 @@ bool Compiler::gtCanOptimizeTypeEquality(GenTreePtr tree)
{
if (tree->gtCall.gtCallType == CT_HELPER)
{
- if (gtIsTypeHandleToRuntimeTypeHelper(tree))
+ if (gtIsTypeHandleToRuntimeTypeHelper(tree->AsCall()))
{
return true;
}
@@ -14958,10 +14978,10 @@ bool Compiler::gtCanOptimizeTypeEquality(GenTreePtr tree)
return false;
}
-bool Compiler::gtIsTypeHandleToRuntimeTypeHelper(GenTreePtr tree)
+bool Compiler::gtIsTypeHandleToRuntimeTypeHelper(GenTreeCall* call)
{
- return tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE) ||
- tree->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE_MAYBENULL);
+ return call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE) ||
+ call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE_MAYBENULL);
}
bool Compiler::gtIsActiveCSE_Candidate(GenTreePtr tree)
@@ -15787,6 +15807,20 @@ unsigned GenTree::IsLclVarUpdateTree(GenTree** pOtherTree, genTreeOps* pOper)
}
//------------------------------------------------------------------------
+// canBeContained: check whether this tree node may be a subcomponent of its parent for purposes
+// of code generation.
+//
+// Return value: returns true if it is possible to contain this node and false otherwise.
+bool GenTree::canBeContained() const
+{
+ assert(IsLIR());
+
+ // It is not possible for nodes that do not produce values or that are not containable values
+ // to be contained.
+ return (OperKind() & (GTK_NOVALUE | GTK_NOCONTAIN)) == 0;
+}
+
+//------------------------------------------------------------------------
// isContained: check whether this tree node is a subcomponent of its parent for codegen purposes
//
// Return Value:
@@ -15801,14 +15835,16 @@ unsigned GenTree::IsLclVarUpdateTree(GenTree** pOtherTree, genTreeOps* pOper)
//
bool GenTree::isContained() const
{
- if (gtHasReg())
+ assert(IsLIR());
+
+ if (!canBeContained() || gtHasReg())
{
return false;
}
// these actually produce a register (the flags reg, we just don't model it)
// and are a separate instruction from the branch that consumes the result
- if (OperKind() & GTK_RELOP)
+ if ((OperKind() & GTK_RELOP) != 0)
{
return false;
}
@@ -15819,75 +15855,25 @@ bool GenTree::isContained() const
return false;
}
- switch (OperGet())
- {
- case GT_STOREIND:
- case GT_JTRUE:
- case GT_JCC:
- case GT_RETURN:
- case GT_RETFILT:
- case GT_STORE_LCL_FLD:
- case GT_STORE_LCL_VAR:
- case GT_ARR_BOUNDS_CHECK:
- case GT_LOCKADD:
- case GT_NOP:
- case GT_NO_OP:
- case GT_START_NONGC:
- case GT_PROF_HOOK:
- case GT_RETURNTRAP:
- case GT_COMMA:
- case GT_PINVOKE_PROLOG:
- case GT_PHYSREGDST:
- case GT_PUTARG_STK:
- case GT_MEMORYBARRIER:
- case GT_STORE_BLK:
- case GT_STORE_OBJ:
- case GT_STORE_DYN_BLK:
- case GT_SWITCH:
-#ifndef LEGACY_BACKEND
- case GT_JMPTABLE:
-#endif
- case GT_SWITCH_TABLE:
- case GT_SWAP:
- case GT_LCLHEAP:
- case GT_CKFINITE:
- case GT_JMP:
- case GT_IL_OFFSET:
-#ifdef FEATURE_SIMD
- case GT_SIMD_CHK:
-#endif // FEATURE_SIMD
-
-#if !FEATURE_EH_FUNCLETS
- case GT_END_LFIN:
-#endif
- return false;
-
#if !defined(LEGACY_BACKEND) && !defined(_TARGET_64BIT_)
- case GT_LONG:
- // GT_LONG nodes are normally contained. The only exception is when the result
- // of a TYP_LONG operation is not used and this can only happen if the GT_LONG
- // is the last node in the statement (in linear order).
- return gtNext != nullptr;
+ if (OperGet() == GT_LONG)
+ {
+ // GT_LONG nodes are normally contained. The only exception is when the result
+ // of a TYP_LONG operation is not used and this can only happen if the GT_LONG
+ // is the last node in the statement (in linear order).
+ return gtNext != nullptr;
+ }
#endif
- case GT_CALL:
- // Note: if you hit this assert you are probably calling isContained()
- // before the LSRA phase has allocated physical register to the tree nodes
- //
- assert(gtType == TYP_VOID);
- return false;
-
- default:
- // if it's contained it better have a parent
- assert(gtNext || OperIsLocal());
- return true;
- }
+ // if it's contained it better have a user
+ assert((gtNext != nullptr) || OperIsLocal());
+ return true;
}
// return true if node is contained and an indir
bool GenTree::isContainedIndir() const
{
- return isContained() && isIndir();
+ return isIndir() && isContained();
}
bool GenTree::isIndirAddrMode()
@@ -15989,11 +15975,7 @@ size_t GenTreeIndir::Offset()
bool GenTreeIntConCommon::ImmedValNeedsReloc(Compiler* comp)
{
-#ifdef RELOC_SUPPORT
return comp->opts.compReloc && (gtOper == GT_CNS_INT) && IsIconHandle();
-#else
- return false;
-#endif
}
//------------------------------------------------------------------------
@@ -16089,9 +16071,7 @@ bool GenTreeIntConCommon::FitsInAddrBase(Compiler* comp)
#endif
#endif //! LEGACY_BACKEND
- // TODO-x86 - TLS field handles are excluded for now as they are accessed relative to FS segment.
- // Handling of TLS field handles is a NYI and this needs to be relooked after implementing it.
- return IsCnsIntOrI() && !IsIconHandle(GTF_ICON_TLS_HDL);
+ return IsCnsIntOrI();
}
// Returns true if this icon value is encoded as addr needs recording a relocation with VM
@@ -16371,6 +16351,215 @@ CORINFO_CLASS_HANDLE Compiler::gtGetStructHandle(GenTree* tree)
return structHnd;
}
+//------------------------------------------------------------------------
+// gtGetClassHandle: find class handle for a ref type
+//
+// Arguments:
+// tree -- tree to find handle for
+// isExact [out] -- whether handle is exact type
+// isNonNull [out] -- whether tree value is known not to be null
+//
+// Return Value:
+// nullptr if class handle is unknown,
+// otherwise the class handle.
+// isExact set true if tree type is known to be exactly the handle type,
+// otherwise actual type may be a subtype.
+// isNonNull set true if tree value is known not to be null,
+// otherwise a null value is possible.
+
+CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTreePtr tree, bool* isExact, bool* isNonNull)
+{
+ // Set default values for our out params.
+ *isNonNull = false;
+ *isExact = false;
+ CORINFO_CLASS_HANDLE objClass = nullptr;
+
+ // Bail out if we're just importing and not generating code, since
+ // the jit uses TYP_REF for CORINFO_TYPE_VAR locals and args, but
+ // these may not be ref types.
+ if (compIsForImportOnly())
+ {
+ return objClass;
+ }
+
+ // Bail out if the tree is not a ref type.
+ var_types treeType = tree->TypeGet();
+ if (treeType != TYP_REF)
+ {
+ return objClass;
+ }
+
+ // Tunnel through commas.
+ GenTreePtr obj = tree->gtEffectiveVal(false);
+ const genTreeOps objOp = obj->OperGet();
+
+ switch (objOp)
+ {
+ case GT_COMMA:
+ {
+ // gtEffectiveVal above means we shouldn't see commas here.
+ assert(!"unexpected GT_COMMA");
+ break;
+ }
+
+ case GT_LCL_VAR:
+ {
+ // For locals, pick up type info from the local table.
+ const unsigned objLcl = obj->AsLclVar()->GetLclNum();
+
+ objClass = lvaTable[objLcl].lvClassHnd;
+ *isExact = lvaTable[objLcl].lvClassIsExact;
+ break;
+ }
+
+ case GT_FIELD:
+ {
+ // For fields, get the type from the field handle.
+ CORINFO_FIELD_HANDLE fieldHnd = obj->gtField.gtFldHnd;
+
+ if (fieldHnd != nullptr)
+ {
+ CORINFO_CLASS_HANDLE fieldClass = nullptr;
+ CorInfoType fieldCorType = info.compCompHnd->getFieldType(fieldHnd, &fieldClass);
+ if (fieldCorType == CORINFO_TYPE_CLASS)
+ {
+ objClass = fieldClass;
+ }
+ }
+
+ break;
+ }
+
+ case GT_RET_EXPR:
+ {
+ // If we see a RET_EXPR, recurse through to examine the
+ // return value expression.
+ GenTreePtr retExpr = tree->gtRetExpr.gtInlineCandidate;
+ objClass = gtGetClassHandle(retExpr, isExact, isNonNull);
+ break;
+ }
+
+ case GT_CALL:
+ {
+ GenTreeCall* call = tree->AsCall();
+ if (call->IsInlineCandidate())
+ {
+ // For inline candidates, we've already cached the return
+ // type class handle in the inline info.
+ InlineCandidateInfo* inlInfo = call->gtInlineCandidateInfo;
+ assert(inlInfo != nullptr);
+
+ // Grab it as our first cut at a return type.
+ assert(inlInfo->methInfo.args.retType == CORINFO_TYPE_CLASS);
+ objClass = inlInfo->methInfo.args.retTypeClass;
+
+ // If the method is shared, the above may not capture
+ // the most precise return type information (that is,
+ // it may represent a shared return type and as such,
+ // have instances of __Canon). See if we can use the
+ // context to get at something more definite.
+ //
+ // For now, we do this here on demand rather than when
+ // processing the call, but we could/should apply
+ // similar sharpening to the argument and local types
+ // of the inlinee.
+ const unsigned retClassFlags = info.compCompHnd->getClassAttribs(objClass);
+ if (retClassFlags & CORINFO_FLG_SHAREDINST)
+ {
+ CORINFO_CONTEXT_HANDLE context = inlInfo->exactContextHnd;
+
+ if (context != nullptr)
+ {
+ CORINFO_CLASS_HANDLE exactClass = nullptr;
+
+ if (((size_t)context & CORINFO_CONTEXTFLAGS_MASK) == CORINFO_CONTEXTFLAGS_CLASS)
+ {
+ exactClass = (CORINFO_CLASS_HANDLE)((size_t)context & ~CORINFO_CONTEXTFLAGS_MASK);
+ }
+ else
+ {
+ CORINFO_METHOD_HANDLE exactMethod =
+ (CORINFO_METHOD_HANDLE)((size_t)context & ~CORINFO_CONTEXTFLAGS_MASK);
+ exactClass = info.compCompHnd->getMethodClass(exactMethod);
+ }
+
+ // Grab the signature in this context.
+ CORINFO_SIG_INFO sig;
+ eeGetMethodSig(call->gtCallMethHnd, &sig, exactClass);
+ assert(sig.retType == CORINFO_TYPE_CLASS);
+ objClass = sig.retTypeClass;
+ }
+ }
+ }
+ else if (call->gtCallType == CT_USER_FUNC)
+ {
+ // For user calls, we can fetch the approximate return
+ // type info from the method handle. Unfortunately
+ // we've lost the exact context, so this is the best
+ // we can do for now.
+ CORINFO_METHOD_HANDLE method = call->gtCallMethHnd;
+ CORINFO_CLASS_HANDLE exactClass = nullptr;
+ CORINFO_SIG_INFO sig;
+ eeGetMethodSig(method, &sig, exactClass);
+ if (sig.retType == CORINFO_TYPE_VOID)
+ {
+ // This is a constructor call.
+ const unsigned methodFlags = info.compCompHnd->getMethodAttribs(method);
+ assert((methodFlags & CORINFO_FLG_CONSTRUCTOR) != 0);
+ objClass = info.compCompHnd->getMethodClass(method);
+ *isExact = true;
+ *isNonNull = true;
+ }
+ else
+ {
+ assert(sig.retType == CORINFO_TYPE_CLASS);
+ objClass = sig.retTypeClass;
+ }
+ }
+
+ break;
+ }
+
+ case GT_CNS_STR:
+ {
+ // For literal strings, we know the class and that the
+ // value is not null.
+ objClass = impGetStringClass();
+ *isExact = true;
+ *isNonNull = true;
+ break;
+ }
+
+ case GT_IND:
+ {
+ // indir(addr(lcl)) --> lcl
+ //
+ // This comes up during constrained callvirt on ref types.
+ GenTreeIndir* indir = obj->AsIndir();
+ if (indir->HasBase() && !indir->HasIndex())
+ {
+ GenTreePtr base = indir->Base();
+ GenTreeLclVarCommon* lcl = base->IsLocalAddrExpr();
+
+ if ((lcl != nullptr) && (base->OperGet() != GT_ADD))
+ {
+ const unsigned objLcl = lcl->GetLclNum();
+ objClass = lvaTable[objLcl].lvClassHnd;
+ *isExact = lvaTable[objLcl].lvClassIsExact;
+ }
+ }
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ return objClass;
+}
+
void GenTree::ParseArrayAddress(
Compiler* comp, ArrayInfo* arrayInfo, GenTreePtr* pArr, ValueNum* pInxVN, FieldSeqNode** pFldSeq)
{
@@ -17062,7 +17251,7 @@ void ReturnTypeDesc::InitializeStructReturnType(Compiler* comp, CORINFO_CLASS_HA
//
void ReturnTypeDesc::InitializeLongReturnType(Compiler* comp)
{
-#if defined(_TARGET_X86_)
+#if defined(_TARGET_X86_) || defined(_TARGET_ARM_)
// Setups up a ReturnTypeDesc for returning a long using two registers
//
@@ -17070,11 +17259,11 @@ void ReturnTypeDesc::InitializeLongReturnType(Compiler* comp)
m_regType[0] = TYP_INT;
m_regType[1] = TYP_INT;
-#else // not _TARGET_X86_
+#else // not (_TARGET_X86_ or _TARGET_ARM_)
m_regType[0] = TYP_LONG;
-#endif // _TARGET_X86_
+#endif // _TARGET_X86_ or _TARGET_ARM_
#ifdef DEBUG
m_inited = true;
@@ -17150,7 +17339,7 @@ regNumber ReturnTypeDesc::GetABIReturnReg(unsigned idx)
}
}
-#elif defined(_TARGET_X86_)
+#elif defined(_TARGET_X86_) || defined(_TARGET_ARM_)
if (idx == 0)
{
diff --git a/src/jit/gentree.h b/src/jit/gentree.h
index 0ea8321e77..1d52248657 100644
--- a/src/jit/gentree.h
+++ b/src/jit/gentree.h
@@ -120,6 +120,8 @@ enum genTreeKinds
GTK_NOVALUE = 0x0400, // node does not produce a value
GTK_NOTLIR = 0x0800, // node is not allowed in LIR
+ GTK_NOCONTAIN = 0x1000, // this node is a value, but may not be contained
+
/* Define composite value(s) */
GTK_SMPOP = (GTK_UNOP | GTK_BINOP | GTK_RELOP | GTK_LOGOP)
@@ -147,6 +149,61 @@ struct BasicBlock;
struct InlineCandidateInfo;
+typedef unsigned short AssertionIndex;
+
+static const AssertionIndex NO_ASSERTION_INDEX = 0;
+
+class AssertionInfo
+{
+ // true if the assertion holds on the bbNext edge instead of the bbJumpDest edge (for GT_JTRUE nodes)
+ unsigned short m_isNextEdgeAssertion : 1;
+ // 1-based index of the assertion
+ unsigned short m_assertionIndex : 15;
+
+ AssertionInfo(bool isNextEdgeAssertion, AssertionIndex assertionIndex)
+ : m_isNextEdgeAssertion(isNextEdgeAssertion), m_assertionIndex(assertionIndex)
+ {
+ assert(m_assertionIndex == assertionIndex);
+ }
+
+public:
+ AssertionInfo() : AssertionInfo(false, 0)
+ {
+ }
+
+ AssertionInfo(AssertionIndex assertionIndex) : AssertionInfo(false, assertionIndex)
+ {
+ }
+
+ static AssertionInfo ForNextEdge(AssertionIndex assertionIndex)
+ {
+ // Ignore the edge information if there's no assertion
+ bool isNextEdge = (assertionIndex != NO_ASSERTION_INDEX);
+ return AssertionInfo(isNextEdge, assertionIndex);
+ }
+
+ void Clear()
+ {
+ m_isNextEdgeAssertion = 0;
+ m_assertionIndex = NO_ASSERTION_INDEX;
+ }
+
+ bool HasAssertion() const
+ {
+ return m_assertionIndex != NO_ASSERTION_INDEX;
+ }
+
+ AssertionIndex GetAssertionIndex() const
+ {
+ return m_assertionIndex;
+ }
+
+ bool IsNextEdgeAssertion() const
+ {
+ return m_isNextEdgeAssertion;
+ }
+};
+
/*****************************************************************************/
// GT_FIELD nodes will be lowered into more "code-gen-able" representations, like
@@ -394,28 +451,27 @@ struct GenTree
unsigned char gtLIRFlags; // Used for nodes that are in LIR. See LIR::Flags in lir.h for the various flags.
#if ASSERTION_PROP
- unsigned short gtAssertionNum; // 0 or Assertion table index
- // valid only for non-GT_STMT nodes
+ AssertionInfo gtAssertionInfo; // valid only for non-GT_STMT nodes
- bool HasAssertion() const
+ bool GeneratesAssertion() const
{
- return gtAssertionNum != 0;
+ return gtAssertionInfo.HasAssertion();
}
+
void ClearAssertion()
{
- gtAssertionNum = 0;
+ gtAssertionInfo.Clear();
}
- unsigned short GetAssertion() const
+ AssertionInfo GetAssertionInfo() const
{
- return gtAssertionNum;
+ return gtAssertionInfo;
}
- void SetAssertion(unsigned short value)
+
+ void SetAssertionInfo(AssertionInfo info)
{
- assert((unsigned short)value == value);
- gtAssertionNum = (unsigned short)value;
+ gtAssertionInfo = info;
}
-
#endif
#if FEATURE_STACK_FP_X87
@@ -555,6 +611,8 @@ public:
__declspec(property(get = GetRegNum, put = SetRegNum)) regNumber gtRegNum;
+ bool canBeContained() const;
+
// for codegen purposes, is this node a subnode of its parent
bool isContained() const;
@@ -1852,6 +1910,10 @@ public:
{
return (gtFlags & GTF_REVERSE_OPS) ? true : false;
}
+ bool IsUnsigned() const
+ {
+ return ((gtFlags & GTF_UNSIGNED) != 0);
+ }
inline bool IsCnsIntOrI() const;
@@ -2051,19 +2113,22 @@ public:
};
//------------------------------------------------------------------------
-// GenTreeUseEdgeIterator: an iterator that will produce each use edge of a
-// GenTree node in the order in which they are
-// used. Note that the use edges of a node may not
-// correspond exactly to the nodes on the other
-// ends of its use edges: in particular, GT_LIST
-// nodes are expanded into their component parts
-// (with the optional exception of multi-reg
-// arguments). This differs from the behavior of
-// GenTree::GetChildPointer(), which does not expand
-// lists.
+// GenTreeUseEdgeIterator: an iterator that will produce each use edge of a GenTree node in the order in which
+// they are used.
//
-// Note: valid values of this type may be obtained by calling
-// `GenTree::UseEdgesBegin` and `GenTree::UseEdgesEnd`.
+// The use edges of a node may not correspond exactly to the nodes on the other ends of its use edges: in
+// particular, GT_LIST nodes are expanded into their component parts. This differs from the behavior of
+// GenTree::GetChildPointer(), which does not expand lists.
+//
+// Operand iteration is common enough in the back end of the compiler that the implementation of this type has
+// traded some simplicity for speed:
+// - As much work as is reasonable is done in the constructor rather than during operand iteration
+// - Node-specific functionality is handled by a small class of "advance" functions called by operator++
+// rather than making operator++ itself handle all nodes
+// - Some specialization has been performed for specific node types/shapes (e.g. the advance function for
+// binary nodes is specialized based on whether or not the node has the GTF_REVERSE_OPS flag set)
+//
+// Valid values of this type may be obtained by calling `GenTree::UseEdgesBegin` and `GenTree::UseEdgesEnd`.
//
class GenTreeUseEdgeIterator final
{
@@ -2071,6 +2136,20 @@ class GenTreeUseEdgeIterator final
friend GenTreeUseEdgeIterator GenTree::UseEdgesBegin();
friend GenTreeUseEdgeIterator GenTree::UseEdgesEnd();
+ enum
+ {
+ CALL_INSTANCE = 0,
+ CALL_ARGS = 1,
+ CALL_LATE_ARGS = 2,
+ CALL_CONTROL_EXPR = 3,
+ CALL_COOKIE = 4,
+ CALL_ADDRESS = 5,
+ CALL_TERMINAL = 6,
+ };
+
+ typedef void (GenTreeUseEdgeIterator::*AdvanceFn)();
+
+ AdvanceFn m_advance;
GenTree* m_node;
GenTree** m_edge;
GenTree* m_argList;
@@ -2078,24 +2157,40 @@ class GenTreeUseEdgeIterator final
GenTreeUseEdgeIterator(GenTree* node);
- GenTree** GetNextUseEdge() const;
- void MoveToNextCallUseEdge();
- void MoveToNextPhiUseEdge();
-#ifdef FEATURE_SIMD
- void MoveToNextSIMDUseEdge();
-#endif
- void MoveToNextFieldUseEdge();
+ // Advance functions for special nodes
+ void AdvanceCmpXchg();
+ void AdvanceBoundsChk();
+ void AdvanceArrElem();
+ void AdvanceArrOffset();
+ void AdvanceDynBlk();
+ void AdvanceStoreDynBlk();
+
+ template <bool ReverseOperands>
+ void AdvanceBinOp();
+ void SetEntryStateForBinOp();
+
+ // An advance function for list-like nodes (Phi, SIMDIntrinsicInitN, FieldList)
+ void AdvanceList();
+ void SetEntryStateForList(GenTree* list);
+
+ // The advance function for call nodes
+ template <int state>
+ void AdvanceCall();
+
+ void Terminate();
public:
GenTreeUseEdgeIterator();
inline GenTree** operator*()
{
+ assert(m_state != -1);
return m_edge;
}
inline GenTree** operator->()
{
+ assert(m_state != -1);
return m_edge;
}
@@ -3390,7 +3485,7 @@ struct GenTreeCall final : public GenTree
//
bool HasMultiRegRetVal() const
{
-#if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
+#if (defined(_TARGET_X86_) || defined(_TARGET_ARM_)) && !defined(LEGACY_BACKEND)
// LEGACY_BACKEND does not use multi reg returns for calls with long return types
return varTypeIsLong(gtType);
#elif FEATURE_MULTIREG_RET
@@ -3620,8 +3715,7 @@ struct GenTreeFptrVal : public GenTree
CORINFO_METHOD_HANDLE gtFptrMethod;
#ifdef FEATURE_READYTORUN_COMPILER
- CORINFO_CONST_LOOKUP gtEntryPoint;
- CORINFO_RESOLVED_TOKEN* gtLdftnResolvedToken;
+ CORINFO_CONST_LOOKUP gtEntryPoint;
#endif
GenTreeFptrVal(var_types type, CORINFO_METHOD_HANDLE meth) : GenTree(GT_FTN_ADDR, type), gtFptrMethod(meth)
@@ -4071,6 +4165,7 @@ struct GenTreeAddrMode : public GenTreeOp
GenTreeAddrMode(var_types type, GenTreePtr base, GenTreePtr index, unsigned scale, unsigned offset)
: GenTreeOp(GT_LEA, type, base, index)
{
+ assert(base != nullptr || index != nullptr);
gtScale = scale;
gtOffset = offset;
}
@@ -4571,7 +4666,7 @@ struct GenTreePhiArg : public GenTreeLclVarCommon
#endif
};
-/* gtPutArgStk -- Argument passed on stack */
+/* gtPutArgStk -- Argument passed on stack (GT_PUTARG_STK) */
struct GenTreePutArgStk : public GenTreeUnOp
{
@@ -4580,105 +4675,58 @@ struct GenTreePutArgStk : public GenTreeUnOp
unsigned gtPadAlign; // Number of padding slots for stack alignment
#endif
-#if FEATURE_FASTTAILCALL
- bool putInIncomingArgArea; // Whether this arg needs to be placed in incoming arg area.
- // By default this is false and will be placed in out-going arg area.
- // Fast tail calls set this to true.
- // In future if we need to add more such bool fields consider bit fields.
-
- GenTreePutArgStk(genTreeOps oper,
- var_types type,
- unsigned slotNum PUT_STRUCT_ARG_STK_ONLY_ARG(unsigned numSlots)
- PUT_STRUCT_ARG_STK_ONLY_ARG(bool isStruct),
- bool _putInIncomingArgArea = false DEBUGARG(GenTreePtr callNode = nullptr)
- DEBUGARG(bool largeNode = false))
- : GenTreeUnOp(oper, type DEBUGARG(largeNode))
+ // Don't let clang-format mess with the GenTreePutArgStk constructor.
+ // clang-format off
+
+ GenTreePutArgStk(genTreeOps oper,
+ var_types type,
+ GenTreePtr op1,
+ unsigned slotNum
+ PUT_STRUCT_ARG_STK_ONLY_ARG(unsigned numSlots),
+ bool putInIncomingArgArea = false,
+ GenTreeCall* callNode = nullptr)
+ : GenTreeUnOp(oper, type, op1 DEBUGARG(/*largeNode*/ false))
, gtSlotNum(slotNum)
#if defined(UNIX_X86_ABI)
, gtPadAlign(0)
#endif
- , putInIncomingArgArea(_putInIncomingArgArea)
+#if FEATURE_FASTTAILCALL
+ , gtPutInIncomingArgArea(putInIncomingArgArea)
+#endif // FEATURE_FASTTAILCALL
#ifdef FEATURE_PUT_STRUCT_ARG_STK
, gtPutArgStkKind(Kind::Invalid)
, gtNumSlots(numSlots)
, gtNumberReferenceSlots(0)
, gtGcPtrs(nullptr)
#endif // FEATURE_PUT_STRUCT_ARG_STK
- {
-#ifdef DEBUG
- gtCall = callNode;
+#if defined(DEBUG) || defined(UNIX_X86_ABI)
+ , gtCall(callNode)
#endif
+ {
}
- GenTreePutArgStk(genTreeOps oper,
- var_types type,
- GenTreePtr op1,
- unsigned slotNum PUT_STRUCT_ARG_STK_ONLY_ARG(unsigned numSlots),
- bool _putInIncomingArgArea = false DEBUGARG(GenTreePtr callNode = nullptr)
- DEBUGARG(bool largeNode = false))
- : GenTreeUnOp(oper, type, op1 DEBUGARG(largeNode))
- , gtSlotNum(slotNum)
-#if defined(UNIX_X86_ABI)
- , gtPadAlign(0)
-#endif
- , putInIncomingArgArea(_putInIncomingArgArea)
-#ifdef FEATURE_PUT_STRUCT_ARG_STK
- , gtPutArgStkKind(Kind::Invalid)
- , gtNumSlots(numSlots)
- , gtNumberReferenceSlots(0)
- , gtGcPtrs(nullptr)
-#endif // FEATURE_PUT_STRUCT_ARG_STK
+// clang-format on
+
+#if FEATURE_FASTTAILCALL
+
+ bool gtPutInIncomingArgArea; // Whether this arg needs to be placed in incoming arg area.
+ // By default this is false and will be placed in out-going arg area.
+ // Fast tail calls set this to true.
+ // In future if we need to add more such bool fields consider bit fields.
+
+ bool putInIncomingArgArea() const
{
-#ifdef DEBUG
- gtCall = callNode;
-#endif
+ return gtPutInIncomingArgArea;
}
#else // !FEATURE_FASTTAILCALL
- GenTreePutArgStk(genTreeOps oper,
- var_types type,
- unsigned slotNum PUT_STRUCT_ARG_STK_ONLY_ARG(unsigned numSlots)
- DEBUGARG(GenTreePtr callNode = NULL) DEBUGARG(bool largeNode = false))
- : GenTreeUnOp(oper, type DEBUGARG(largeNode))
- , gtSlotNum(slotNum)
-#if defined(UNIX_X86_ABI)
- , gtPadAlign(0)
-#endif
-#ifdef FEATURE_PUT_STRUCT_ARG_STK
- , gtPutArgStkKind(Kind::Invalid)
- , gtNumSlots(numSlots)
- , gtNumberReferenceSlots(0)
- , gtGcPtrs(nullptr)
-#endif // FEATURE_PUT_STRUCT_ARG_STK
+ bool putInIncomingArgArea() const
{
-#ifdef DEBUG
- gtCall = callNode;
-#endif
+ return false;
}
- GenTreePutArgStk(genTreeOps oper,
- var_types type,
- GenTreePtr op1,
- unsigned slotNum PUT_STRUCT_ARG_STK_ONLY_ARG(unsigned numSlots)
- DEBUGARG(GenTreePtr callNode = NULL) DEBUGARG(bool largeNode = false))
- : GenTreeUnOp(oper, type, op1 DEBUGARG(largeNode))
- , gtSlotNum(slotNum)
-#if defined(UNIX_X86_ABI)
- , gtPadAlign(0)
-#endif
-#ifdef FEATURE_PUT_STRUCT_ARG_STK
- , gtPutArgStkKind(Kind::Invalid)
- , gtNumSlots(numSlots)
- , gtNumberReferenceSlots(0)
- , gtGcPtrs(nullptr)
-#endif // FEATURE_PUT_STRUCT_ARG_STK
- {
-#ifdef DEBUG
- gtCall = callNode;
-#endif
- }
-#endif // FEATURE_FASTTAILCALL
+#endif // !FEATURE_FASTTAILCALL
unsigned getArgOffset()
{
@@ -4698,13 +4746,12 @@ struct GenTreePutArgStk : public GenTreeUnOp
#endif
#ifdef FEATURE_PUT_STRUCT_ARG_STK
+
unsigned getArgSize()
{
return gtNumSlots * TARGET_POINTER_SIZE;
}
-#endif // FEATURE_PUT_STRUCT_ARG_STK
-#ifdef FEATURE_PUT_STRUCT_ARG_STK
//------------------------------------------------------------------------
// setGcPointers: Sets the number of references and the layout of the struct object returned by the VM.
//
@@ -4726,13 +4773,7 @@ struct GenTreePutArgStk : public GenTreeUnOp
gtNumberReferenceSlots = numPointers;
gtGcPtrs = pointers;
}
-#endif // FEATURE_PUT_STRUCT_ARG_STK
-#ifdef DEBUG
- GenTreePtr gtCall; // the call node to which this argument belongs
-#endif
-
-#ifdef FEATURE_PUT_STRUCT_ARG_STK
// Instruction selection: during codegen time, what code sequence we will be using
// to encode this operation.
// TODO-Throughput: The following information should be obtained from the child
@@ -4751,7 +4792,12 @@ struct GenTreePutArgStk : public GenTreeUnOp
unsigned gtNumSlots; // Number of slots for the argument to be passed on stack
unsigned gtNumberReferenceSlots; // Number of reference slots.
BYTE* gtGcPtrs; // gcPointers
-#endif // FEATURE_PUT_STRUCT_ARG_STK
+
+#endif // FEATURE_PUT_STRUCT_ARG_STK
+
+#if defined(DEBUG) || defined(UNIX_X86_ABI)
+ GenTreeCall* gtCall; // the call node to which this argument belongs
+#endif
#if DEBUGGABLE_GENTREE
GenTreePutArgStk() : GenTreeUnOp()
diff --git a/src/jit/gtlist.h b/src/jit/gtlist.h
index 2d9255b6ce..826eaf1207 100644
--- a/src/jit/gtlist.h
+++ b/src/jit/gtlist.h
@@ -46,7 +46,7 @@ GTNODE(CNS_STR , "sconst" ,GenTreeStrCon ,0,GTK_LEAF|GTK_CON
//-----------------------------------------------------------------------------
GTNODE(NOT , "~" ,GenTreeOp ,0,GTK_UNOP)
-GTNODE(NOP , "nop" ,GenTree ,0,GTK_UNOP)
+GTNODE(NOP , "nop" ,GenTree ,0,GTK_UNOP|GTK_NOCONTAIN)
GTNODE(NEG , "unary -" ,GenTreeOp ,0,GTK_UNOP)
GTNODE(COPY , "copy" ,GenTreeCopyOrReload,0,GTK_UNOP) // Copies a variable from its current location to a register that satisfies
// code generation constraints. The child is the actual lclVar node.
@@ -65,8 +65,8 @@ GTNODE(CMPXCHG , "cmpxchg" ,GenTreeCmpXchg ,0,GTK_SPECIAL)
GTNODE(MEMORYBARRIER , "memoryBarrier",GenTree ,0,GTK_LEAF|GTK_NOVALUE)
GTNODE(CAST , "cast" ,GenTreeCast ,0,GTK_UNOP|GTK_EXOP) // conversion to another type
-GTNODE(CKFINITE , "ckfinite" ,GenTreeOp ,0,GTK_UNOP) // Check for NaN
-GTNODE(LCLHEAP , "lclHeap" ,GenTreeOp ,0,GTK_UNOP) // alloca()
+GTNODE(CKFINITE , "ckfinite" ,GenTreeOp ,0,GTK_UNOP|GTK_NOCONTAIN) // Check for NaN
+GTNODE(LCLHEAP , "lclHeap" ,GenTreeOp ,0,GTK_UNOP|GTK_NOCONTAIN) // alloca()
GTNODE(JMP , "jump" ,GenTreeVal ,0,GTK_LEAF|GTK_NOVALUE) // Jump to another function
GTNODE(ADDR , "addr" ,GenTreeOp ,0,GTK_UNOP) // address of
@@ -226,7 +226,7 @@ GTNODE(FIELD , "field" ,GenTreeField ,0,GTK_SPECIAL)
GTNODE(ARR_ELEM , "arrMD&" ,GenTreeArrElem ,0,GTK_SPECIAL) // Multi-dimensional array-element address
GTNODE(ARR_INDEX , "arrMDIdx" ,GenTreeArrIndex ,0,GTK_BINOP|GTK_EXOP) // Effective, bounds-checked index for one dimension of a multi-dimensional array element
GTNODE(ARR_OFFSET , "arrMDOffs" ,GenTreeArrOffs ,0,GTK_SPECIAL) // Flattened offset of multi-dimensional array element
-GTNODE(CALL , "call()" ,GenTreeCall ,0,GTK_SPECIAL)
+GTNODE(CALL , "call()" ,GenTreeCall ,0,GTK_SPECIAL|GTK_NOCONTAIN)
//-----------------------------------------------------------------------------
// Statement operator nodes:
@@ -261,7 +261,7 @@ GTNODE(PHI_ARG , "phiArg" ,GenTreePhiArg ,0,GTK_LEAF|GTK_LOC
//-----------------------------------------------------------------------------
#ifndef LEGACY_BACKEND
-GTNODE(JMPTABLE , "jumpTable" ,GenTreeJumpTable ,0, GTK_LEAF) // Generates the jump table for switches
+GTNODE(JMPTABLE , "jumpTable" ,GenTreeJumpTable ,0, GTK_LEAF|GTK_NOCONTAIN) // Generates the jump table for switches
#endif
GTNODE(SWITCH_TABLE , "tableSwitch" ,GenTreeOp ,0, GTK_BINOP|GTK_NOVALUE) // Jump Table based switch construct
diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp
index b1e0f487ef..54427ba4dd 100644
--- a/src/jit/importer.cpp
+++ b/src/jit/importer.cpp
@@ -350,6 +350,12 @@ StackEntry& Compiler::impStackTop(unsigned n)
return verCurrentState.esStack[verCurrentState.esStackDepth - n - 1];
}
+
+unsigned Compiler::impStackHeight()
+{
+ return verCurrentState.esStackDepth;
+}
+
/*****************************************************************************
* Some of the trees are spilled specially. While unspilling them, or
* making a copy, these need to be handled specially. The function
@@ -1232,13 +1238,13 @@ GenTreePtr Compiler::impAssignStructPtr(GenTreePtr destAddr,
}
else if (src->gtOper == GT_RET_EXPR)
{
- GenTreePtr call = src->gtRetExpr.gtInlineCandidate;
+ GenTreeCall* call = src->gtRetExpr.gtInlineCandidate->AsCall();
noway_assert(call->gtOper == GT_CALL);
- if (call->AsCall()->HasRetBufArg())
+ if (call->HasRetBufArg())
{
// insert the return value buffer into the argument list as first byref parameter
- call->gtCall.gtCallArgs = gtNewListNode(destAddr, call->gtCall.gtCallArgs);
+ call->gtCallArgs = gtNewListNode(destAddr, call->gtCallArgs);
// now returns void, not a struct
src->gtType = TYP_VOID;
@@ -1252,7 +1258,7 @@ GenTreePtr Compiler::impAssignStructPtr(GenTreePtr destAddr,
{
// Case of inline method returning a struct in one or more registers.
//
- var_types returnType = (var_types)call->gtCall.gtReturnType;
+ var_types returnType = (var_types)call->gtReturnType;
// We won't need a return buffer
asgType = returnType;
@@ -1842,7 +1848,7 @@ GenTreePtr Compiler::impReadyToRunLookupToTree(CORINFO_CONST_LOOKUP* pLookup,
return gtNewIconEmbHndNode(handle, pIndirection, handleFlags, 0, nullptr, compileTimeHandle);
}
-GenTreePtr Compiler::impReadyToRunHelperToTree(
+GenTreeCall* Compiler::impReadyToRunHelperToTree(
CORINFO_RESOLVED_TOKEN* pResolvedToken,
CorInfoHelpFunc helper,
var_types type,
@@ -1850,18 +1856,14 @@ GenTreePtr Compiler::impReadyToRunHelperToTree(
CORINFO_LOOKUP_KIND* pGenericLookupKind /* =NULL. Only used with generics */)
{
CORINFO_CONST_LOOKUP lookup;
-#if COR_JIT_EE_VERSION > 460
if (!info.compCompHnd->getReadyToRunHelper(pResolvedToken, pGenericLookupKind, helper, &lookup))
{
return nullptr;
}
-#else
- info.compCompHnd->getReadyToRunHelper(pResolvedToken, helper, &lookup);
-#endif
- GenTreePtr op1 = gtNewHelperCallNode(helper, type, GTF_EXCEPT, args);
+ GenTreeCall* op1 = gtNewHelperCallNode(helper, type, GTF_EXCEPT, args);
- op1->gtCall.setEntryPoint(lookup);
+ op1->setEntryPoint(lookup);
return op1;
}
@@ -1879,9 +1881,7 @@ GenTreePtr Compiler::impMethodPointer(CORINFO_RESOLVED_TOKEN* pResolvedToken, CO
#ifdef FEATURE_READYTORUN_COMPILER
if (opts.IsReadyToRun())
{
- op1->gtFptrVal.gtEntryPoint = pCallInfo->codePointerLookup.constLookup;
- op1->gtFptrVal.gtLdftnResolvedToken = new (this, CMK_Unknown) CORINFO_RESOLVED_TOKEN;
- *op1->gtFptrVal.gtLdftnResolvedToken = *pResolvedToken;
+ op1->gtFptrVal.gtEntryPoint = pCallInfo->codePointerLookup.constLookup;
}
else
{
@@ -1929,7 +1929,7 @@ GenTreePtr Compiler::getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind)
// Collectible types requires that for shared generic code, if we use the generic context parameter
// that we report it. (This is a conservative approach, we could detect some cases particularly when the
// context parameter is this that we don't need the eager reporting logic.)
- lvaGenericsContextUsed = true;
+ lvaGenericsContextUseCount++;
if (kind == CORINFO_LOOKUP_THISOBJ)
{
@@ -2179,9 +2179,12 @@ bool Compiler::impSpillStackEntry(unsigned level,
}
}
+ bool isNewTemp = false;
+
if (tnum == BAD_VAR_NUM)
{
- tnum = lvaGrabTemp(true DEBUGARG(reason));
+ tnum = lvaGrabTemp(true DEBUGARG(reason));
+ isNewTemp = true;
}
else if (tiVerificationNeeded && lvaTable[tnum].TypeGet() != TYP_UNDEF)
{
@@ -2211,6 +2214,13 @@ bool Compiler::impSpillStackEntry(unsigned level,
/* Assign the spilled entry to the temp */
impAssignTempGen(tnum, tree, verCurrentState.esStack[level].seTypeInfo.GetClassHandle(), level);
+ // If temp is newly introduced and a ref type, grab what type info we can.
+ if (isNewTemp && (lvaTable[tnum].lvType == TYP_REF))
+ {
+ CORINFO_CLASS_HANDLE stkHnd = verCurrentState.esStack[level].seTypeInfo.GetClassHandle();
+ lvaSetClass(tnum, tree, stkHnd);
+ }
+
// The tree type may be modified by impAssignTempGen, so use the type of the lclVar.
var_types type = genActualType(lvaTable[tnum].TypeGet());
GenTreePtr temp = gtNewLclvNode(tnum, type);
@@ -2584,6 +2594,21 @@ inline IL_OFFSETX Compiler::impCurILOffset(IL_OFFSET offs, bool callInstruction)
}
}
+//------------------------------------------------------------------------
+// impCanSpillNow: check is it possible to spill all values from eeStack to local variables.
+//
+// Arguments:
+// prevOpcode - last importer opcode
+//
+// Return Value:
+// true if it is legal, false if it could be a sequence that we do not want to divide.
+bool Compiler::impCanSpillNow(OPCODE prevOpcode)
+{
+ // Don't spill after ldtoken, because it could be a part of the InitializeArray sequence.
+ // Avoid breaking up to guarantee that impInitializeArrayIntrinsic can succeed.
+ return prevOpcode != CEE_LDTOKEN;
+}
+
/*****************************************************************************
*
* Remember the instr offset for the statements
@@ -2997,14 +3022,12 @@ GenTreePtr Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig)
#endif
)
{
-#if COR_JIT_EE_VERSION > 460
if (newArrayCall->gtCall.gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEW_MDARR_NONVARARG))
{
return nullptr;
}
isMDArray = true;
-#endif
}
CORINFO_CLASS_HANDLE arrayClsHnd = (CORINFO_CLASS_HANDLE)newArrayCall->gtCall.compileTimeHelperArgumentHandle;
@@ -3278,13 +3301,9 @@ GenTreePtr Compiler::impIntrinsic(GenTreePtr newobjThis,
bool tailCall,
CorInfoIntrinsics* pIntrinsicID)
{
- bool mustExpand = false;
-#if COR_JIT_EE_VERSION > 460
+ bool mustExpand = false;
CorInfoIntrinsics intrinsicID = info.compCompHnd->getIntrinsicID(method, &mustExpand);
-#else
- CorInfoIntrinsics intrinsicID = info.compCompHnd->getIntrinsicID(method);
-#endif
- *pIntrinsicID = intrinsicID;
+ *pIntrinsicID = intrinsicID;
#ifndef _TARGET_ARM_
genTreeOps interlockedOperator;
@@ -3557,7 +3576,7 @@ GenTreePtr Compiler::impIntrinsic(GenTreePtr newobjThis,
case CORINFO_INTRINSIC_GetTypeFromHandle:
op1 = impStackTop(0).val;
if (op1->gtOper == GT_CALL && (op1->gtCall.gtCallType == CT_HELPER) &&
- gtIsTypeHandleToRuntimeTypeHelper(op1))
+ gtIsTypeHandleToRuntimeTypeHelper(op1->AsCall()))
{
op1 = impPopStack().val;
// Change call to return RuntimeType directly.
@@ -3570,7 +3589,7 @@ GenTreePtr Compiler::impIntrinsic(GenTreePtr newobjThis,
case CORINFO_INTRINSIC_RTH_GetValueInternal:
op1 = impStackTop(0).val;
if (op1->gtOper == GT_CALL && (op1->gtCall.gtCallType == CT_HELPER) &&
- gtIsTypeHandleToRuntimeTypeHelper(op1))
+ gtIsTypeHandleToRuntimeTypeHelper(op1->AsCall()))
{
// Old tree
// Helper-RuntimeTypeHandle -> TreeToGetNativeTypeHandle
@@ -4989,6 +5008,23 @@ GenTreePtr Compiler::impImportLdvirtftn(GenTreePtr thisPtr,
NO_WAY("Virtual call to a function added via EnC is not supported");
}
+ // CoreRT generic virtual method
+ if (((pCallInfo->sig.callConv & CORINFO_CALLCONV_GENERIC) != 0) && IsTargetAbi(CORINFO_CORERT_ABI))
+ {
+ GenTreePtr runtimeMethodHandle = nullptr;
+ if (pCallInfo->exactContextNeedsRuntimeLookup)
+ {
+ runtimeMethodHandle =
+ impRuntimeLookupToTree(pResolvedToken, &pCallInfo->codePointerLookup, pCallInfo->hMethod);
+ }
+ else
+ {
+ runtimeMethodHandle = gtNewIconEmbMethHndNode(pResolvedToken->hMethod);
+ }
+ return gtNewHelperCallNode(CORINFO_HELP_GVMLOOKUP_FOR_SLOT, TYP_I_IMPL, GTF_EXCEPT,
+ gtNewArgList(thisPtr, runtimeMethodHandle));
+ }
+
#ifdef FEATURE_READYTORUN_COMPILER
if (opts.IsReadyToRun())
{
@@ -5238,7 +5274,6 @@ void Compiler::impImportNewObjArray(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORI
//
CLANG_FORMAT_COMMENT_ANCHOR;
-#if COR_JIT_EE_VERSION > 460
if (!opts.IsReadyToRun() || IsTargetAbi(CORINFO_CORERT_ABI))
{
LclVarDsc* newObjArrayArgsVar;
@@ -5298,7 +5333,6 @@ void Compiler::impImportNewObjArray(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORI
node = gtNewHelperCallNode(CORINFO_HELP_NEW_MDARR_NONVARARG, TYP_REF, 0, args);
}
else
-#endif
{
//
// The varargs helper needs the type and method handles as last
@@ -5522,14 +5556,14 @@ bool Compiler::impCanPInvokeInlineCallSite(BasicBlock* block)
// If GTF_CALL_UNMANAGED is set, increments info.compCallUnmanaged
void Compiler::impCheckForPInvokeCall(
- GenTreePtr call, CORINFO_METHOD_HANDLE methHnd, CORINFO_SIG_INFO* sig, unsigned mflags, BasicBlock* block)
+ GenTreeCall* call, CORINFO_METHOD_HANDLE methHnd, CORINFO_SIG_INFO* sig, unsigned mflags, BasicBlock* block)
{
CorInfoUnmanagedCallConv unmanagedCallConv;
// If VM flagged it as Pinvoke, flag the call node accordingly
if ((mflags & CORINFO_FLG_PINVOKE) != 0)
{
- call->gtCall.gtCallMoreFlags |= GTF_CALL_M_PINVOKE;
+ call->gtCallMoreFlags |= GTF_CALL_M_PINVOKE;
}
if (methHnd)
@@ -5554,7 +5588,7 @@ void Compiler::impCheckForPInvokeCall(
static_assert_no_msg((unsigned)CORINFO_CALLCONV_THISCALL == (unsigned)CORINFO_UNMANAGED_CALLCONV_THISCALL);
unmanagedCallConv = CorInfoUnmanagedCallConv(callConv);
- assert(!call->gtCall.gtCallCookie);
+ assert(!call->gtCallCookie);
}
if (unmanagedCallConv != CORINFO_UNMANAGED_CALLCONV_C && unmanagedCallConv != CORINFO_UNMANAGED_CALLCONV_STDCALL &&
@@ -5614,11 +5648,11 @@ void Compiler::impCheckForPInvokeCall(
if (unmanagedCallConv == CORINFO_UNMANAGED_CALLCONV_THISCALL)
{
- call->gtCall.gtCallMoreFlags |= GTF_CALL_M_UNMGD_THISCALL;
+ call->gtCallMoreFlags |= GTF_CALL_M_UNMGD_THISCALL;
}
}
-GenTreePtr Compiler::impImportIndirectCall(CORINFO_SIG_INFO* sig, IL_OFFSETX ilOffset)
+GenTreeCall* Compiler::impImportIndirectCall(CORINFO_SIG_INFO* sig, IL_OFFSETX ilOffset)
{
var_types callRetTyp = JITtype2varType(sig->retType);
@@ -5637,7 +5671,11 @@ GenTreePtr Compiler::impImportIndirectCall(CORINFO_SIG_INFO* sig, IL_OFFSETX ilO
/* Get the function pointer */
GenTreePtr fptr = impPopStack().val;
- assert(genActualType(fptr->gtType) == TYP_I_IMPL);
+
+ // The function pointer is typically a sized to match the target pointer size
+ // However, stubgen IL optimization can change LDC.I8 to LDC.I4
+ // See ILCodeStream::LowerOpcode
+ assert(genActualType(fptr->gtType) == TYP_I_IMPL || genActualType(fptr->gtType) == TYP_INT);
#ifdef DEBUG
// This temporary must never be converted to a double in stress mode,
@@ -5652,7 +5690,7 @@ GenTreePtr Compiler::impImportIndirectCall(CORINFO_SIG_INFO* sig, IL_OFFSETX ilO
/* Create the call node */
- GenTreePtr call = gtNewIndCallNode(fptr, callRetTyp, nullptr, ilOffset);
+ GenTreeCall* call = gtNewIndCallNode(fptr, callRetTyp, nullptr, ilOffset);
call->gtFlags |= GTF_EXCEPT | (fptr->gtFlags & GTF_GLOB_EFFECT);
@@ -5922,7 +5960,7 @@ GenTreePtr Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolve
}
break;
}
-#if COR_JIT_EE_VERSION > 460
+
case CORINFO_FIELD_STATIC_READYTORUN_HELPER:
{
#ifdef FEATURE_READYTORUN_COMPILER
@@ -5951,7 +5989,7 @@ GenTreePtr Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolve
#endif // FEATURE_READYTORUN_COMPILER
}
break;
-#endif // COR_JIT_EE_VERSION > 460
+
default:
{
if (!(access & CORINFO_ACCESS_ADDRESS))
@@ -6111,25 +6149,6 @@ void Compiler::impInsertHelperCall(CORINFO_HELPER_DESC* helperInfo)
impAppendTree(callout, (unsigned)CHECK_SPILL_NONE, impCurStmtOffs);
}
-void Compiler::impInsertCalloutForDelegate(CORINFO_METHOD_HANDLE callerMethodHnd,
- CORINFO_METHOD_HANDLE calleeMethodHnd,
- CORINFO_CLASS_HANDLE delegateTypeHnd)
-{
-#ifdef FEATURE_CORECLR
- if (!info.compCompHnd->isDelegateCreationAllowed(delegateTypeHnd, calleeMethodHnd))
- {
- // Call the JIT_DelegateSecurityCheck helper before calling the actual function.
- // This helper throws an exception if the CLR host disallows the call.
-
- GenTreePtr helper = gtNewHelperCallNode(CORINFO_HELP_DELEGATE_SECURITY_CHECK, TYP_VOID, GTF_EXCEPT,
- gtNewArgList(gtNewIconEmbClsHndNode(delegateTypeHnd),
- gtNewIconEmbMethHndNode(calleeMethodHnd)));
- // Append the callout statement
- impAppendTree(helper, (unsigned)CHECK_SPILL_NONE, impCurStmtOffs);
- }
-#endif // FEATURE_CORECLR
-}
-
// Checks whether the return types of caller and callee are compatible
// so that callee can be tail called. Note that here we don't check
// compatibility in IL Verifier sense, but on the lines of return type
@@ -6376,12 +6395,14 @@ var_types Compiler::impImportCall(OPCODE opcode,
GenTreeArgList* args = nullptr;
CORINFO_THIS_TRANSFORM constraintCallThisTransform = CORINFO_NO_THIS_TRANSFORM;
CORINFO_CONTEXT_HANDLE exactContextHnd = nullptr;
- BOOL exactContextNeedsRuntimeLookup = FALSE;
+ bool exactContextNeedsRuntimeLookup = false;
bool canTailCall = true;
const char* szCanTailCallFailReason = nullptr;
int tailCall = prefixFlags & PREFIX_TAILCALL;
bool readonlyCall = (prefixFlags & PREFIX_READONLY) != 0;
+ CORINFO_RESOLVED_TOKEN* ldftnToken = nullptr;
+
// Synchronized methods need to call CORINFO_HELP_MON_EXIT at the end. We could
// do that before tailcalls, but that is probably not the intended
// semantic. So just disallow tailcalls from synchronized methods.
@@ -6432,7 +6453,6 @@ var_types Compiler::impImportCall(OPCODE opcode,
eeGetSig(pResolvedToken->token, info.compScopeHnd, impTokenLookupContextHandle, &calliSig);
callRetTyp = JITtype2varType(calliSig.retType);
- clsHnd = calliSig.retTypeClass;
call = impImportIndirectCall(&calliSig, ilOffset);
@@ -6464,11 +6484,13 @@ var_types Compiler::impImportCall(OPCODE opcode,
if (IsTargetAbi(CORINFO_CORERT_ABI))
{
- bool managedCall = (calliSig.callConv & GTF_CALL_UNMANAGED) == 0;
+ bool managedCall = (((calliSig.callConv & CORINFO_CALLCONV_MASK) != CORINFO_CALLCONV_STDCALL) &&
+ ((calliSig.callConv & CORINFO_CALLCONV_MASK) != CORINFO_CALLCONV_C) &&
+ ((calliSig.callConv & CORINFO_CALLCONV_MASK) != CORINFO_CALLCONV_THISCALL) &&
+ ((calliSig.callConv & CORINFO_CALLCONV_MASK) != CORINFO_CALLCONV_FASTCALL));
if (managedCall)
{
- call->AsCall()->SetFatPointerCandidate();
- setMethodHasFatPointer();
+ addFatPointerCandidate(call->AsCall());
}
}
}
@@ -6519,7 +6541,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
if (mflags & CORINFO_FLG_DONT_INLINE_CALLER)
{
- compInlineResult->NoteFatal(InlineObservation::CALLEE_HAS_NOINLINE_CALLEE);
+ compInlineResult->NoteFatal(InlineObservation::CALLEE_STACK_CRAWL_MARK);
return callRetTyp;
}
@@ -6632,10 +6654,9 @@ var_types Compiler::impImportCall(OPCODE opcode,
// Work out what sort of call we're making.
// Dispense with virtual calls implemented via LDVIRTFTN immediately.
- constraintCallThisTransform = callInfo->thisTransform;
-
+ constraintCallThisTransform = callInfo->thisTransform;
exactContextHnd = callInfo->contextHandle;
- exactContextNeedsRuntimeLookup = callInfo->exactContextNeedsRuntimeLookup;
+ exactContextNeedsRuntimeLookup = callInfo->exactContextNeedsRuntimeLookup == TRUE;
// Recursive call is treaded as a loop to the begining of the method.
if (methHnd == info.compMethodHnd)
@@ -6773,6 +6794,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
nullptr DEBUGARG("LDVIRTFTN this pointer"));
GenTreePtr fptr = impImportLdvirtftn(thisPtr, pResolvedToken, callInfo);
+
if (compDonotInline())
{
return callRetTyp;
@@ -6792,6 +6814,11 @@ var_types Compiler::impImportCall(OPCODE opcode,
call->gtCall.gtCallObjp = thisPtrCopy;
call->gtFlags |= GTF_EXCEPT | (fptr->gtFlags & GTF_GLOB_EFFECT);
+ if (((sig->callConv & CORINFO_CALLCONV_GENERIC) != 0) && IsTargetAbi(CORINFO_CORERT_ABI))
+ {
+ // CoreRT generic virtual method: need to handle potential fat function pointers
+ addFatPointerCandidate(call->AsCall());
+ }
#ifdef FEATURE_READYTORUN_COMPILER
if (opts.IsReadyToRun())
{
@@ -6946,6 +6973,14 @@ var_types Compiler::impImportCall(OPCODE opcode,
}
#endif // !FEATURE_VARARG
+#ifdef UNIX_X86_ABI
+ if (call->gtCall.callSig == nullptr)
+ {
+ call->gtCall.callSig = new (this, CMK_CorSig) CORINFO_SIG_INFO;
+ *call->gtCall.callSig = *sig;
+ }
+#endif // UNIX_X86_ABI
+
if ((sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_VARARG ||
(sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_NATIVEVARARG)
{
@@ -7054,7 +7089,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
{
// New lexical block here to avoid compilation errors because of GOTOs.
BasicBlock* block = compIsForInlining() ? impInlineInfo->iciBlock : compCurBB;
- impCheckForPInvokeCall(call, methHnd, sig, mflags, block);
+ impCheckForPInvokeCall(call->AsCall(), methHnd, sig, mflags, block);
}
if (call->gtFlags & GTF_CALL_UNMANAGED)
@@ -7279,6 +7314,21 @@ var_types Compiler::impImportCall(OPCODE opcode,
exactContextHnd = nullptr;
}
+ if ((opcode == CEE_NEWOBJ) && ((clsFlags & CORINFO_FLG_DELEGATE) != 0))
+ {
+ // Only verifiable cases are supported.
+ // dup; ldvirtftn; newobj; or ldftn; newobj.
+ // IL test could contain unverifiable sequence, in this case optimization should not be done.
+ if (impStackHeight() > 0)
+ {
+ typeInfo delegateTypeInfo = impStackTop().seTypeInfo;
+ if (delegateTypeInfo.IsToken())
+ {
+ ldftnToken = delegateTypeInfo.GetToken();
+ }
+ }
+ }
+
//-------------------------------------------------------------------------
// The main group of arguments
@@ -7315,8 +7365,10 @@ var_types Compiler::impImportCall(OPCODE opcode,
if ((call->gtFlags & GTF_CALL_VIRT_KIND_MASK) != GTF_CALL_NONVIRT)
{
/* only true object pointers can be virtual */
-
assert(obj->gtType == TYP_REF);
+
+ // See if we can devirtualize.
+ impDevirtualizeCall(call->AsCall(), obj, callInfo, &exactContextHnd);
}
else
{
@@ -7357,7 +7409,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
{
// New inliner morph it in impImportCall.
// This will allow us to inline the call to the delegate constructor.
- call = fgOptimizeDelegateConstructor(call, &exactContextHnd);
+ call = fgOptimizeDelegateConstructor(call->AsCall(), &exactContextHnd, ldftnToken);
}
if (!bIntrinsicImported)
@@ -7371,7 +7423,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
#endif // defined(DEBUG) || defined(INLINE_DATA)
// Is it an inline candidate?
- impMarkInlineCandidate(call, exactContextHnd, callInfo);
+ impMarkInlineCandidate(call, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo);
}
// append the call node.
@@ -7595,7 +7647,7 @@ DONE:
#endif // defined(DEBUG) || defined(INLINE_DATA)
// Is it an inline candidate?
- impMarkInlineCandidate(call, exactContextHnd, callInfo);
+ impMarkInlineCandidate(call, exactContextHnd, exactContextNeedsRuntimeLookup, callInfo);
}
DONE_CALL:
@@ -7658,7 +7710,7 @@ DONE_CALL:
bool fatPointerCandidate = call->AsCall()->IsFatPointerCandidate();
if (varTypeIsStruct(callRetTyp))
{
- call = impFixupCallStructReturn(call, sig->retTypeClass);
+ call = impFixupCallStructReturn(call->AsCall(), sig->retTypeClass);
}
if ((call->gtFlags & GTF_CALL_INLINE_CANDIDATE) != 0)
@@ -7686,16 +7738,39 @@ DONE_CALL:
unsigned calliSlot = lvaGrabTemp(true DEBUGARG("calli"));
LclVarDsc* varDsc = &lvaTable[calliSlot];
varDsc->lvVerTypeInfo = tiRetVal;
- impAssignTempGen(calliSlot, call, clsHnd, (unsigned)CHECK_SPILL_NONE);
+ impAssignTempGen(calliSlot, call, tiRetVal.GetClassHandle(), (unsigned)CHECK_SPILL_NONE);
// impAssignTempGen can change src arg list and return type for call that returns struct.
var_types type = genActualType(lvaTable[calliSlot].TypeGet());
call = gtNewLclvNode(calliSlot, type);
}
}
+
// For non-candidates we must also spill, since we
// might have locals live on the eval stack that this
// call can modify.
- impSpillSideEffects(true, CHECK_SPILL_ALL DEBUGARG("non-inline candidate call"));
+ //
+ // Suppress this for certain well-known call targets
+ // that we know won't modify locals, eg calls that are
+ // recognized in gtCanOptimizeTypeEquality. Otherwise
+ // we may break key fragile pattern matches later on.
+ bool spillStack = true;
+ if (call->IsCall())
+ {
+ GenTreeCall* callNode = call->AsCall();
+ if ((callNode->gtCallType == CT_HELPER) && gtIsTypeHandleToRuntimeTypeHelper(callNode))
+ {
+ spillStack = false;
+ }
+ else if ((callNode->gtCallMoreFlags & GTF_CALL_M_SPECIAL_INTRINSIC) != 0)
+ {
+ spillStack = false;
+ }
+ }
+
+ if (spillStack)
+ {
+ impSpillSideEffects(true, CHECK_SPILL_ALL DEBUGARG("non-inline candidate call"));
+ }
}
}
@@ -7820,33 +7895,29 @@ var_types Compiler::impImportJitTestLabelMark(int numArgs)
// Return Value:
// Returns new GenTree node after fixing struct return of call node
//
-GenTreePtr Compiler::impFixupCallStructReturn(GenTreePtr call, CORINFO_CLASS_HANDLE retClsHnd)
+GenTreePtr Compiler::impFixupCallStructReturn(GenTreeCall* call, CORINFO_CLASS_HANDLE retClsHnd)
{
- assert(call->gtOper == GT_CALL);
-
if (!varTypeIsStruct(call))
{
return call;
}
- call->gtCall.gtRetClsHnd = retClsHnd;
-
- GenTreeCall* callNode = call->AsCall();
+ call->gtRetClsHnd = retClsHnd;
#if FEATURE_MULTIREG_RET
// Initialize Return type descriptor of call node
- ReturnTypeDesc* retTypeDesc = callNode->GetReturnTypeDesc();
+ ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
retTypeDesc->InitializeStructReturnType(this, retClsHnd);
#endif // FEATURE_MULTIREG_RET
#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
// Not allowed for FEATURE_CORCLR which is the only SKU available for System V OSs.
- assert(!callNode->IsVarargs() && "varargs not allowed for System V OSs.");
+ assert(!call->IsVarargs() && "varargs not allowed for System V OSs.");
// The return type will remain as the incoming struct type unless normalized to a
// single eightbyte return type below.
- callNode->gtReturnType = call->gtType;
+ call->gtReturnType = call->gtType;
unsigned retRegCount = retTypeDesc->GetReturnRegCount();
if (retRegCount != 0)
@@ -7854,14 +7925,14 @@ GenTreePtr Compiler::impFixupCallStructReturn(GenTreePtr call, CORINFO_CLASS_HAN
if (retRegCount == 1)
{
// struct returned in a single register
- callNode->gtReturnType = retTypeDesc->GetReturnRegType(0);
+ call->gtReturnType = retTypeDesc->GetReturnRegType(0);
}
else
{
// must be a struct returned in two registers
assert(retRegCount == 2);
- if ((!callNode->CanTailCall()) && (!callNode->IsInlineCandidate()))
+ if ((!call->CanTailCall()) && (!call->IsInlineCandidate()))
{
// Force a call returning multi-reg struct to be always of the IR form
// tmp = call
@@ -7876,7 +7947,7 @@ GenTreePtr Compiler::impFixupCallStructReturn(GenTreePtr call, CORINFO_CLASS_HAN
else
{
// struct not returned in registers i.e returned via hiddden retbuf arg.
- callNode->gtCallMoreFlags |= GTF_CALL_M_RETBUFFARG;
+ call->gtCallMoreFlags |= GTF_CALL_M_RETBUFFARG;
}
#else // not FEATURE_UNIX_AMD64_STRUCT_PASSING
@@ -7885,15 +7956,15 @@ GenTreePtr Compiler::impFixupCallStructReturn(GenTreePtr call, CORINFO_CLASS_HAN
// There is no fixup necessary if the return type is a HFA struct.
// HFA structs are returned in registers for ARM32 and ARM64
//
- if (!call->gtCall.IsVarargs() && IsHfa(retClsHnd))
+ if (!call->IsVarargs() && IsHfa(retClsHnd))
{
- if (call->gtCall.CanTailCall())
+ if (call->CanTailCall())
{
if (info.compIsVarArgs)
{
// We cannot tail call because control needs to return to fixup the calling
// convention for result return.
- call->gtCall.gtCallMoreFlags &= ~GTF_CALL_M_EXPLICIT_TAILCALL;
+ call->gtCallMoreFlags &= ~GTF_CALL_M_EXPLICIT_TAILCALL;
}
else
{
@@ -7926,12 +7997,12 @@ GenTreePtr Compiler::impFixupCallStructReturn(GenTreePtr call, CORINFO_CLASS_HAN
if (howToReturnStruct == SPK_ByReference)
{
assert(returnType == TYP_UNKNOWN);
- call->gtCall.gtCallMoreFlags |= GTF_CALL_M_RETBUFFARG;
+ call->gtCallMoreFlags |= GTF_CALL_M_RETBUFFARG;
}
else
{
assert(returnType != TYP_UNKNOWN);
- call->gtCall.gtReturnType = returnType;
+ call->gtReturnType = returnType;
// ToDo: Refactor this common code sequence into its own method as it is used 4+ times
if ((returnType == TYP_LONG) && (compLongUsed == false))
@@ -7949,7 +8020,7 @@ GenTreePtr Compiler::impFixupCallStructReturn(GenTreePtr call, CORINFO_CLASS_HAN
if (retRegCount >= 2)
{
- if ((!callNode->CanTailCall()) && (!callNode->IsInlineCandidate()))
+ if ((!call->CanTailCall()) && (!call->IsInlineCandidate()))
{
// Force a call returning multi-reg struct to be always of the IR form
// tmp = call
@@ -9379,6 +9450,9 @@ GenTreePtr Compiler::impCastClassOrIsInstToTree(GenTreePtr op1,
// Make QMark node a top level node by spilling it.
unsigned tmp = lvaGrabTemp(true DEBUGARG("spilling QMark2"));
impAssignTempGen(tmp, qmarkNull, (unsigned)CHECK_SPILL_NONE);
+
+ // TODO: Is it possible op1 has a better type?
+ lvaSetClass(tmp, pResolvedToken->hClass);
return gtNewLclvNode(tmp, TYP_REF);
#endif
}
@@ -9458,7 +9532,6 @@ void Compiler::impImportBlockCode(BasicBlock* block)
int prefixFlags = 0;
bool explicitTailCall, constraintCall, readonlyCall;
- bool insertLdloc = false; // set by CEE_DUP and cleared by following store
typeInfo tiRetVal;
unsigned numArgs = info.compArgsCount;
@@ -9500,7 +9573,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
/* Has it been a while since we last saw a non-empty stack (which
guarantees that the tree depth isnt accumulating. */
- if ((opcodeOffs - lastSpillOffs) > 200)
+ if ((opcodeOffs - lastSpillOffs) > MAX_TREE_SIZE && impCanSpillNow(prevOpcode))
{
impSpillStackEnsure();
lastSpillOffs = opcodeOffs;
@@ -9637,6 +9710,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
GenTreeArgList* args = nullptr; // What good do these "DUMMY_INIT"s do?
GenTreePtr newObjThisPtr = DUMMY_INIT(NULL);
bool uns = DUMMY_INIT(false);
+ bool isLocal = false;
/* Get the next opcode and the size of its parameters */
@@ -9892,7 +9966,9 @@ void Compiler::impImportBlockCode(BasicBlock* block)
{
lclNum = lvaArg0Var;
}
- lvaTable[lclNum].lvArgWrite = 1;
+
+ // We should have seen this arg write in the prescan
+ assert(lvaTable[lclNum].lvHasILStoreOp);
if (tiVerificationNeeded)
{
@@ -9909,12 +9985,14 @@ void Compiler::impImportBlockCode(BasicBlock* block)
goto VAR_ST;
case CEE_STLOC:
- lclNum = getU2LittleEndian(codeAddr);
+ lclNum = getU2LittleEndian(codeAddr);
+ isLocal = true;
JITDUMP(" %u", lclNum);
goto LOC_ST;
case CEE_STLOC_S:
- lclNum = getU1LittleEndian(codeAddr);
+ lclNum = getU1LittleEndian(codeAddr);
+ isLocal = true;
JITDUMP(" %u", lclNum);
goto LOC_ST;
@@ -9922,7 +10000,8 @@ void Compiler::impImportBlockCode(BasicBlock* block)
case CEE_STLOC_1:
case CEE_STLOC_2:
case CEE_STLOC_3:
- lclNum = (opcode - CEE_STLOC_0);
+ isLocal = true;
+ lclNum = (opcode - CEE_STLOC_0);
assert(lclNum >= 0 && lclNum < 4);
LOC_ST:
@@ -10023,31 +10102,32 @@ void Compiler::impImportBlockCode(BasicBlock* block)
}
}
- /* Filter out simple assignments to itself */
-
- if (op1->gtOper == GT_LCL_VAR && lclNum == op1->gtLclVarCommon.gtLclNum)
+ // If this is a local and the local is a ref type, see
+ // if we can improve type information based on the
+ // value being assigned.
+ if (isLocal && (lclTyp == TYP_REF))
{
- if (insertLdloc)
- {
- // This is a sequence of (ldloc, dup, stloc). Can simplify
- // to (ldloc, stloc). Goto LDVAR to reconstruct the ldloc node.
- CLANG_FORMAT_COMMENT_ANCHOR;
+ // We should have seen a stloc in our IL prescan.
+ assert(lvaTable[lclNum].lvHasILStoreOp);
-#ifdef DEBUG
- if (tiVerificationNeeded)
- {
- assert(
- typeInfo::AreEquivalent(tiRetVal, NormaliseForStack(lvaTable[lclNum].lvVerTypeInfo)));
- }
-#endif
+ const bool isSingleILStoreLocal =
+ !lvaTable[lclNum].lvHasMultipleILStoreOp && !lvaTable[lclNum].lvHasLdAddrOp;
- op1 = nullptr;
- insertLdloc = false;
+ // Conservative check that there is just one
+ // definition that reaches this store.
+ const bool hasSingleReachingDef = (block->bbStackDepthOnEntry() == 0);
- impLoadVar(lclNum, opcodeOffs + sz + 1);
- break;
+ if (isSingleILStoreLocal && hasSingleReachingDef)
+ {
+ lvaUpdateClass(lclNum, op1, clsHnd);
}
- else if (opts.compDbgCode)
+ }
+
+ /* Filter out simple assignments to itself */
+
+ if (op1->gtOper == GT_LCL_VAR && lclNum == op1->gtLclVarCommon.gtLclNum)
+ {
+ if (opts.compDbgCode)
{
op1 = gtNewNothingNode();
goto SPILL_APPEND;
@@ -10104,26 +10184,6 @@ void Compiler::impImportBlockCode(BasicBlock* block)
op1 = gtNewAssignNode(op2, op1);
}
- /* If insertLdloc is true, then we need to insert a ldloc following the
- stloc. This is done when converting a (dup, stloc) sequence into
- a (stloc, ldloc) sequence. */
-
- if (insertLdloc)
- {
- // From SPILL_APPEND
- impAppendTree(op1, (unsigned)CHECK_SPILL_ALL, impCurStmtOffs);
-
-#ifdef DEBUG
- // From DONE_APPEND
- impNoteLastILoffs();
-#endif
- op1 = nullptr;
- insertLdloc = false;
-
- impLoadVar(lclNum, opcodeOffs + sz + 1, tiRetVal);
- break;
- }
-
goto SPILL_APPEND;
case CEE_LDLOCA:
@@ -11566,22 +11626,6 @@ void Compiler::impImportBlockCode(BasicBlock* block)
op1 = impPopStack().val;
assertImp(genActualTypeIsIntOrI(op1->TypeGet()));
-#ifdef _TARGET_64BIT_
- // Widen 'op1' on 64-bit targets
- if (op1->TypeGet() != TYP_I_IMPL)
- {
- if (op1->OperGet() == GT_CNS_INT)
- {
- op1->gtType = TYP_I_IMPL;
- }
- else
- {
- op1 = gtNewCastNode(TYP_I_IMPL, op1, TYP_I_IMPL);
- }
- }
-#endif // _TARGET_64BIT_
- assert(genActualType(op1->TypeGet()) == TYP_I_IMPL);
-
/* We can create a switch node */
op1 = gtNewOperNode(GT_SWITCH, TYP_VOID, op1);
@@ -11941,48 +11985,30 @@ void Compiler::impImportBlockCode(BasicBlock* block)
impStackTop(0);
}
- // Convert a (dup, stloc) sequence into a (stloc, ldloc) sequence in the following cases:
- // - If this is non-debug code - so that CSE will recognize the two as equal.
- // This helps eliminate a redundant bounds check in cases such as:
- // ariba[i+3] += some_value;
- // - If the top of the stack is a non-leaf that may be expensive to clone.
+ // If the expression to dup is simple, just clone it.
+ // Otherwise spill it to a temp, and reload the temp
+ // twice.
+ op1 = impPopStack(tiRetVal);
- if (codeAddr < codeEndp)
+ if (!opts.compDbgCode && !op1->IsIntegralConst(0) && !op1->IsFPZero() && !op1->IsLocal())
{
- OPCODE nextOpcode = (OPCODE)getU1LittleEndian(codeAddr);
- if (impIsAnySTLOC(nextOpcode))
+ const unsigned tmpNum = lvaGrabTemp(true DEBUGARG("dup spill"));
+ impAssignTempGen(tmpNum, op1, tiRetVal.GetClassHandle(), (unsigned)CHECK_SPILL_ALL);
+ var_types type = genActualType(lvaTable[tmpNum].TypeGet());
+ op1 = gtNewLclvNode(tmpNum, type);
+
+ // Propagate type info to the temp
+ if (type == TYP_REF)
{
- if (!opts.compDbgCode)
- {
- insertLdloc = true;
- break;
- }
- GenTree* stackTop = impStackTop().val;
- if (!stackTop->IsIntegralConst(0) && !stackTop->IsFPZero() && !stackTop->IsLocal())
- {
- insertLdloc = true;
- break;
- }
+ lvaSetClass(tmpNum, op1, tiRetVal.GetClassHandle());
}
}
- /* Pull the top value from the stack */
- op1 = impPopStack(tiRetVal);
-
- /* Clone the value */
op1 = impCloneExpr(op1, &op2, tiRetVal.GetClassHandle(), (unsigned)CHECK_SPILL_ALL,
nullptr DEBUGARG("DUP instruction"));
- /* Either the tree started with no global effects, or impCloneExpr
- evaluated the tree to a temp and returned two copies of that
- temp. Either way, neither op1 nor op2 should have side effects.
- */
assert(!(op1->gtFlags & GTF_GLOB_EFFECT) && !(op2->gtFlags & GTF_GLOB_EFFECT));
-
- /* Push the tree/temp back on the stack */
impPushOnStack(op1, tiRetVal);
-
- /* Push the copy on the stack */
impPushOnStack(op2, tiRetVal);
break;
@@ -12290,7 +12316,8 @@ void Compiler::impImportBlockCode(BasicBlock* block)
return;
}
- impPushOnStack(op1, typeInfo(resolvedToken.hMethod));
+ CORINFO_RESOLVED_TOKEN* heapToken = impAllocateToken(resolvedToken);
+ impPushOnStack(op1, typeInfo(heapToken));
break;
}
@@ -12395,7 +12422,10 @@ void Compiler::impImportBlockCode(BasicBlock* block)
return;
}
- impPushOnStack(fptr, typeInfo(resolvedToken.hMethod));
+ CORINFO_RESOLVED_TOKEN* heapToken = impAllocateToken(resolvedToken);
+ assert(heapToken->tokenType == CORINFO_TOKENKIND_Method);
+ heapToken->tokenType = CORINFO_TOKENKIND_Ldvirtftn;
+ impPushOnStack(fptr, typeInfo(heapToken));
break;
}
@@ -12465,11 +12495,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
/* NEWOBJ does not respond to CONSTRAINED */
prefixFlags &= ~PREFIX_CONSTRAINED;
-#if COR_JIT_EE_VERSION > 460
_impResolveToken(CORINFO_TOKENKIND_NewObj);
-#else
- _impResolveToken(CORINFO_TOKENKIND_Method);
-#endif
eeGetCallInfo(&resolvedToken, nullptr /* constraint typeRef*/,
addVerifyFlag(combine(CORINFO_CALLINFO_SECURITYCHECKS, CORINFO_CALLINFO_ALLOWINSTPARAM)),
@@ -12673,6 +12699,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
// without exhaustive walk over all expressions.
impAssignTempGen(lclNum, op1, (unsigned)CHECK_SPILL_NONE);
+ lvaSetClass(lclNum, resolvedToken.hClass, true /* is Exact */);
newObjThisPtr = gtNewLclvNode(lclNum, TYP_REF);
}
@@ -12770,11 +12797,31 @@ void Compiler::impImportBlockCode(BasicBlock* block)
prefixFlags |= PREFIX_TAILCALL_EXPLICIT;
}
}
+ }
- // Note that when running under tail call stress, a call will be marked as explicit tail prefixed
- // hence will not be considered for implicit tail calling.
- bool isRecursive = (callInfo.hMethod == info.compMethodHnd);
- if (impIsImplicitTailCallCandidate(opcode, codeAddr + sz, codeEndp, prefixFlags, isRecursive))
+ // This is split up to avoid goto flow warnings.
+ bool isRecursive;
+ isRecursive = !compIsForInlining() && (callInfo.hMethod == info.compMethodHnd);
+
+ // Note that when running under tail call stress, a call will be marked as explicit tail prefixed
+ // hence will not be considered for implicit tail calling.
+ if (impIsImplicitTailCallCandidate(opcode, codeAddr + sz, codeEndp, prefixFlags, isRecursive))
+ {
+ if (compIsForInlining())
+ {
+#if FEATURE_TAILCALL_OPT_SHARED_RETURN
+ // Are we inlining at an implicit tail call site? If so the we can flag
+ // implicit tail call sites in the inline body. These call sites
+ // often end up in non BBJ_RETURN blocks, so only flag them when
+ // we're able to handle shared returns.
+ if (impInlineInfo->iciCall->IsImplicitTailCall())
+ {
+ JITDUMP(" (Inline Implicit Tail call: prefixFlags |= PREFIX_TAILCALL_IMPLICIT)");
+ prefixFlags |= PREFIX_TAILCALL_IMPLICIT;
+ }
+#endif // FEATURE_TAILCALL_OPT_SHARED_RETURN
+ }
+ else
{
JITDUMP(" (Implicit Tail call: prefixFlags |= PREFIX_TAILCALL_IMPLICIT)");
prefixFlags |= PREFIX_TAILCALL_IMPLICIT;
@@ -12793,7 +12840,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
impHandleAccessAllowed(callInfo.accessAllowed, &callInfo.callsiteCalloutHelper);
#if 0 // DevDiv 410397 - This breaks too many obfuscated apps to do this in an in-place release
-
+
// DevDiv 291703 - we need to check for accessibility between the caller of InitializeArray
// and the field it is reading, thus it is now unverifiable to not immediately precede with
// ldtoken <filed token>, and we now check accessibility
@@ -12838,14 +12885,6 @@ void Compiler::impImportBlockCode(BasicBlock* block)
assert(verCheckDelegateCreation(delegateCreateStart, codeAddr - 1, delegateMethodRef));
}
#endif
-
-#ifdef FEATURE_CORECLR
- // In coreclr the delegate transparency rule needs to be enforced even if verification is disabled
- typeInfo tiActualFtn = impStackTop(0).seTypeInfo;
- CORINFO_METHOD_HANDLE delegateMethodHandle = tiActualFtn.GetMethod2();
-
- impInsertCalloutForDelegate(info.compMethodHnd, delegateMethodHandle, resolvedToken.hClass);
-#endif // FEATURE_CORECLR
}
callTyp = impImportCall(opcode, &resolvedToken, constraintCall ? &constrainedResolvedToken : nullptr,
@@ -12932,9 +12971,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
return;
case CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER:
-#if COR_JIT_EE_VERSION > 460
case CORINFO_FIELD_STATIC_READYTORUN_HELPER:
-#endif
/* We may be able to inline the field accessors in specific instantiations of generic
* methods */
compInlineResult->NoteFatal(InlineObservation::CALLSITE_LDFLD_NEEDS_HELPER);
@@ -13165,9 +13202,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
case CORINFO_FIELD_STATIC_RVA_ADDRESS:
case CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER:
case CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER:
-#if COR_JIT_EE_VERSION > 460
case CORINFO_FIELD_STATIC_READYTORUN_HELPER:
-#endif
op1 = impImportStaticFieldAccess(&resolvedToken, (CORINFO_ACCESS_FLAGS)aflags, &fieldInfo,
lclTyp);
break;
@@ -13191,6 +13226,18 @@ void Compiler::impImportBlockCode(BasicBlock* block)
}
break;
+ case CORINFO_FIELD_INTRINSIC_ISLITTLEENDIAN:
+ {
+ assert(aflags & CORINFO_ACCESS_GET);
+#if BIGENDIAN
+ op1 = gtNewIconNode(0, lclTyp);
+#else
+ op1 = gtNewIconNode(1, lclTyp);
+#endif
+ goto FIELD_DONE;
+ }
+ break;
+
default:
assert(!"Unexpected fieldAccessor");
}
@@ -13311,10 +13358,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
return;
case CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER:
-#if COR_JIT_EE_VERSION > 460
case CORINFO_FIELD_STATIC_READYTORUN_HELPER:
-#endif
-
/* We may be able to inline the field accessors in specific instantiations of generic
* methods */
compInlineResult->NoteFatal(InlineObservation::CALLSITE_STFLD_NEEDS_HELPER);
@@ -13433,9 +13477,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
case CORINFO_FIELD_STATIC_RVA_ADDRESS:
case CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER:
case CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER:
-#if COR_JIT_EE_VERSION > 460
case CORINFO_FIELD_STATIC_READYTORUN_HELPER:
-#endif
op1 = impImportStaticFieldAccess(&resolvedToken, (CORINFO_ACCESS_FLAGS)aflags, &fieldInfo,
lclTyp);
break;
@@ -13611,9 +13653,10 @@ void Compiler::impImportBlockCode(BasicBlock* block)
Verify(elemTypeHnd == nullptr ||
!(info.compCompHnd->getClassAttribs(elemTypeHnd) & CORINFO_FLG_CONTAINS_STACK_PTR),
"array of byref-like type");
- tiRetVal = verMakeTypeInfo(resolvedToken.hClass);
}
+ tiRetVal = verMakeTypeInfo(resolvedToken.hClass);
+
accessAllowedResult =
info.compCompHnd->canAccessClass(&resolvedToken, info.compMethodHnd, &calloutHelper);
impHandleAccessAllowed(accessAllowedResult, &calloutHelper);
@@ -13748,7 +13791,7 @@ void Compiler::impImportBlockCode(BasicBlock* block)
#ifdef FEATURE_READYTORUN_COMPILER
if (opts.IsReadyToRun())
{
- GenTreePtr opLookup =
+ GenTreeCall* opLookup =
impReadyToRunHelperToTree(&resolvedToken, CORINFO_HELP_READYTORUN_ISINSTANCEOF, TYP_REF,
gtNewArgList(op1));
usingReadyToRunHelper = (opLookup != nullptr);
@@ -14279,8 +14322,8 @@ void Compiler::impImportBlockCode(BasicBlock* block)
#ifdef FEATURE_READYTORUN_COMPILER
if (opts.IsReadyToRun())
{
- GenTreePtr opLookup = impReadyToRunHelperToTree(&resolvedToken, CORINFO_HELP_READYTORUN_CHKCAST,
- TYP_REF, gtNewArgList(op1));
+ GenTreeCall* opLookup = impReadyToRunHelperToTree(&resolvedToken, CORINFO_HELP_READYTORUN_CHKCAST,
+ TYP_REF, gtNewArgList(op1));
usingReadyToRunHelper = (opLookup != nullptr);
op1 = (usingReadyToRunHelper ? opLookup : op1);
@@ -14782,11 +14825,8 @@ void Compiler::impImportBlockCode(BasicBlock* block)
prevOpcode = opcode;
prefixFlags = 0;
- assert(!insertLdloc || opcode == CEE_DUP);
}
- assert(!insertLdloc);
-
return;
#undef _impResolveToken
}
@@ -14994,6 +15034,16 @@ bool Compiler::impReturnInstruction(BasicBlock* block, int prefixFlags, OPCODE&
Verify(verCurrentState.esStackDepth == expectedStack, "stack non-empty on return");
}
+#ifdef DEBUG
+ // If we are importing an inlinee and have GC ref locals we always
+ // need to have a spill temp for the return value. This temp
+ // should have been set up in advance, over in fgFindBasicBlocks.
+ if (compIsForInlining() && impInlineInfo->HasGcRefLocals() && (info.compRetType != TYP_VOID))
+ {
+ assert(lvaInlineeReturnSpillTemp != BAD_VAR_NUM);
+ }
+#endif // DEBUG
+
GenTree* op2 = nullptr;
GenTree* op1 = nullptr;
CORINFO_CLASS_HANDLE retClsHnd = nullptr;
@@ -15100,7 +15150,7 @@ bool Compiler::impReturnInstruction(BasicBlock* block, int prefixFlags, OPCODE&
if (lvaInlineeReturnSpillTemp != BAD_VAR_NUM)
{
assert(info.compRetNativeType != TYP_VOID &&
- (fgMoreThanOneReturnBlock() || impInlineInfo->hasPinnedLocals));
+ (fgMoreThanOneReturnBlock() || impInlineInfo->HasGcRefLocals()));
// This is a bit of a workaround...
// If we are inlining a call that returns a struct, where the actual "native" return type is
@@ -15181,8 +15231,7 @@ bool Compiler::impReturnInstruction(BasicBlock* block, int prefixFlags, OPCODE&
// compRetNativeType is TYP_STRUCT.
// This implies that struct return via RetBuf arg or multi-reg struct return
- GenTreePtr iciCall = impInlineInfo->iciCall;
- assert(iciCall->gtOper == GT_CALL);
+ GenTreeCall* iciCall = impInlineInfo->iciCall->AsCall();
// Assign the inlinee return into a spill temp.
// spill temp only exists if there are multiple return points
@@ -15191,7 +15240,7 @@ bool Compiler::impReturnInstruction(BasicBlock* block, int prefixFlags, OPCODE&
// in this case we have to insert multiple struct copies to the temp
// and the retexpr is just the temp.
assert(info.compRetNativeType != TYP_VOID);
- assert(fgMoreThanOneReturnBlock() || impInlineInfo->hasPinnedLocals);
+ assert(fgMoreThanOneReturnBlock() || impInlineInfo->HasGcRefLocals());
impAssignTempGen(lvaInlineeReturnSpillTemp, op2, se.seTypeInfo.GetClassHandle(),
(unsigned)CHECK_SPILL_ALL);
@@ -15246,7 +15295,7 @@ bool Compiler::impReturnInstruction(BasicBlock* block, int prefixFlags, OPCODE&
if (retRegCount != 0)
{
- assert(!iciCall->AsCall()->HasRetBufArg());
+ assert(!iciCall->HasRetBufArg());
assert(retRegCount >= 2);
if (lvaInlineeReturnSpillTemp != BAD_VAR_NUM)
{
@@ -15265,8 +15314,8 @@ bool Compiler::impReturnInstruction(BasicBlock* block, int prefixFlags, OPCODE&
else
#endif // defined(_TARGET_ARM64_)
{
- assert(iciCall->AsCall()->HasRetBufArg());
- GenTreePtr dest = gtCloneExpr(iciCall->gtCall.gtCallArgs->gtOp.gtOp1);
+ assert(iciCall->HasRetBufArg());
+ GenTreePtr dest = gtCloneExpr(iciCall->gtCallArgs->gtOp.gtOp1);
// spill temp only exists if there are multiple return points
if (lvaInlineeReturnSpillTemp != BAD_VAR_NUM)
{
@@ -15946,11 +15995,11 @@ SPILLSTACK:
}
else
{
- assert(addTree->gtOper == GT_SWITCH && genActualType(addTree->gtOp.gtOp1->gtType) == TYP_I_IMPL);
+ assert(addTree->gtOper == GT_SWITCH && genActualTypeIsIntOrI(addTree->gtOp.gtOp1->TypeGet()));
unsigned temp = lvaGrabTemp(true DEBUGARG("spill addStmt SWITCH"));
impAssignTempGen(temp, addTree->gtOp.gtOp1, level);
- addTree->gtOp.gtOp1 = gtNewLclvNode(temp, TYP_I_IMPL);
+ addTree->gtOp.gtOp1 = gtNewLclvNode(temp, genActualType(addTree->gtOp.gtOp1->TypeGet()));
}
}
@@ -16921,7 +16970,7 @@ void Compiler::impMakeDiscretionaryInlineObservations(InlineInfo* pInlineInfo, I
{
frequency = InlineCallsiteFrequency::LOOP;
}
- else if ((pInlineInfo->iciBlock->bbFlags & BBF_PROF_WEIGHT) && (pInlineInfo->iciBlock->bbWeight > BB_ZERO_WEIGHT))
+ else if (pInlineInfo->iciBlock->hasProfileWeight() && (pInlineInfo->iciBlock->bbWeight > BB_ZERO_WEIGHT))
{
frequency = InlineCallsiteFrequency::WARM;
}
@@ -17378,7 +17427,8 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo)
// Ignore the type context argument
if (hasTypeCtxtArg && (argCnt == typeCtxtArg))
{
- typeCtxtArg = 0xFFFFFFFF;
+ pInlineInfo->typeContextArg = typeCtxtArg;
+ typeCtxtArg = 0xFFFFFFFF;
continue;
}
@@ -17621,6 +17671,11 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo)
lclVarInfo[i + argCnt].lclIsPinned = isPinned;
lclVarInfo[i + argCnt].lclTypeInfo = type;
+ if (varTypeIsGC(type))
+ {
+ pInlineInfo->numberOfGcRefLocals++;
+ }
+
if (isPinned)
{
// Pinned locals may cause inlines to fail.
@@ -17685,6 +17740,23 @@ void Compiler::impInlineInitVars(InlineInfo* pInlineInfo)
#endif // FEATURE_SIMD
}
+//------------------------------------------------------------------------
+// impInlineFetchLocal: get a local var that represents an inlinee local
+//
+// Arguments:
+// lclNum -- number of the inlinee local
+// reason -- debug string describing purpose of the local var
+//
+// Returns:
+// Number of the local to use
+//
+// Notes:
+// This method is invoked only for locals actually used in the
+// inlinee body.
+//
+// Allocates a new temp if necessary, and copies key properties
+// over from the inlinee local var info.
+
unsigned Compiler::impInlineFetchLocal(unsigned lclNum DEBUGARG(const char* reason))
{
assert(compIsForInlining());
@@ -17693,107 +17765,144 @@ unsigned Compiler::impInlineFetchLocal(unsigned lclNum DEBUGARG(const char* reas
if (tmpNum == BAD_VAR_NUM)
{
- var_types lclTyp = impInlineInfo->lclVarInfo[lclNum + impInlineInfo->argCnt].lclTypeInfo;
+ const InlLclVarInfo& inlineeLocal = impInlineInfo->lclVarInfo[lclNum + impInlineInfo->argCnt];
+ const var_types lclTyp = inlineeLocal.lclTypeInfo;
// The lifetime of this local might span multiple BBs.
// So it is a long lifetime local.
impInlineInfo->lclTmpNum[lclNum] = tmpNum = lvaGrabTemp(false DEBUGARG(reason));
- lvaTable[tmpNum].lvType = lclTyp;
- if (impInlineInfo->lclVarInfo[lclNum + impInlineInfo->argCnt].lclHasLdlocaOp)
- {
- lvaTable[tmpNum].lvHasLdAddrOp = 1;
- }
+ // Copy over key info
+ lvaTable[tmpNum].lvType = lclTyp;
+ lvaTable[tmpNum].lvHasLdAddrOp = inlineeLocal.lclHasLdlocaOp;
+ lvaTable[tmpNum].lvPinned = inlineeLocal.lclIsPinned;
+ lvaTable[tmpNum].lvHasILStoreOp = inlineeLocal.lclHasStlocOp;
+ lvaTable[tmpNum].lvHasMultipleILStoreOp = inlineeLocal.lclHasMultipleStlocOp;
- if (impInlineInfo->lclVarInfo[lclNum + impInlineInfo->argCnt].lclIsPinned)
+ // Copy over class handle for ref types. Note this may be a
+ // shared type -- someday perhaps we can get the exact
+ // signature and pass in a more precise type.
+ if (lclTyp == TYP_REF)
{
- lvaTable[tmpNum].lvPinned = 1;
-
- if (!impInlineInfo->hasPinnedLocals)
- {
- // If the inlinee returns a value, use a spill temp
- // for the return value to ensure that even in case
- // where the return expression refers to one of the
- // pinned locals, we can unpin the local right after
- // the inlined method body.
- if ((info.compRetNativeType != TYP_VOID) && (lvaInlineeReturnSpillTemp == BAD_VAR_NUM))
- {
- lvaInlineeReturnSpillTemp =
- lvaGrabTemp(false DEBUGARG("Inline candidate pinned local return spill temp"));
- lvaTable[lvaInlineeReturnSpillTemp].lvType = info.compRetNativeType;
- }
- }
-
- impInlineInfo->hasPinnedLocals = true;
+ lvaSetClass(tmpNum, inlineeLocal.lclVerTypeInfo.GetClassHandleForObjRef());
}
- if (impInlineInfo->lclVarInfo[lclNum + impInlineInfo->argCnt].lclVerTypeInfo.IsStruct())
+ if (inlineeLocal.lclVerTypeInfo.IsStruct())
{
if (varTypeIsStruct(lclTyp))
{
- lvaSetStruct(tmpNum,
- impInlineInfo->lclVarInfo[lclNum + impInlineInfo->argCnt].lclVerTypeInfo.GetClassHandle(),
- true /* unsafe value cls check */);
+ lvaSetStruct(tmpNum, inlineeLocal.lclVerTypeInfo.GetClassHandle(), true /* unsafe value cls check */);
}
else
{
// This is a wrapped primitive. Make sure the verstate knows that
- lvaTable[tmpNum].lvVerTypeInfo =
- impInlineInfo->lclVarInfo[lclNum + impInlineInfo->argCnt].lclVerTypeInfo;
+ lvaTable[tmpNum].lvVerTypeInfo = inlineeLocal.lclVerTypeInfo;
}
}
+
+#ifdef DEBUG
+ // Sanity check that we're properly prepared for gc ref locals.
+ if (varTypeIsGC(lclTyp))
+ {
+ // Since there are gc locals we should have seen them earlier
+ // and if there was a return value, set up the spill temp.
+ assert(impInlineInfo->HasGcRefLocals());
+ assert((info.compRetNativeType == TYP_VOID) || (lvaInlineeReturnSpillTemp != BAD_VAR_NUM));
+ }
+ else
+ {
+ // Make sure all pinned locals count as gc refs.
+ assert(!inlineeLocal.lclIsPinned);
+ }
+#endif // DEBUG
}
return tmpNum;
}
-// A method used to return the GenTree (usually a GT_LCL_VAR) representing the arguments of the inlined method.
-// Only use this method for the arguments of the inlinee method.
-// !!! Do not use it for the locals of the inlinee method. !!!!
+//------------------------------------------------------------------------
+// impInlineFetchArg: return tree node for argument value in an inlinee
+//
+// Arguments:
+// lclNum -- argument number in inlinee IL
+// inlArgInfo -- argument info for inlinee
+// lclVarInfo -- var info for inlinee
+//
+// Returns:
+// Tree for the argument's value. Often an inlinee-scoped temp
+// GT_LCL_VAR but can be other tree kinds, if the argument
+// expression from the caller can be directly substituted into the
+// inlinee body.
+//
+// Notes:
+// Must be used only for arguments -- use impInlineFetchLocal for
+// inlinee locals.
+//
+// Direct substitution is performed when the formal argument cannot
+// change value in the inlinee body (no starg or ldarga), and the
+// actual argument expression's value cannot be changed if it is
+// substituted it into the inlinee body.
+//
+// Even if an inlinee-scoped temp is returned here, it may later be
+// "bashed" to a caller-supplied tree when arguments are actually
+// passed (see fgInlinePrependStatements). Bashing can happen if
+// the argument ends up being single use and other conditions are
+// met. So the contents of the tree returned here may not end up
+// being the ones ultimately used for the argument.
+//
+// This method will side effect inlArgInfo. It should only be called
+// for actual uses of the argument in the inlinee.
GenTreePtr Compiler::impInlineFetchArg(unsigned lclNum, InlArgInfo* inlArgInfo, InlLclVarInfo* lclVarInfo)
{
- /* Get the argument type */
- var_types lclTyp = lclVarInfo[lclNum].lclTypeInfo;
+ // Cache the relevant arg and lcl info for this argument.
+ // We will modify argInfo but not lclVarInfo.
+ InlArgInfo& argInfo = inlArgInfo[lclNum];
+ const InlLclVarInfo& lclInfo = lclVarInfo[lclNum];
+ const bool argCanBeModified = argInfo.argHasLdargaOp || argInfo.argHasStargOp;
+ const var_types lclTyp = lclInfo.lclTypeInfo;
+ GenTreePtr op1 = nullptr;
- GenTreePtr op1 = nullptr;
-
- // constant or address of local
- if (inlArgInfo[lclNum].argIsInvariant && !inlArgInfo[lclNum].argHasLdargaOp && !inlArgInfo[lclNum].argHasStargOp)
+ if (argInfo.argIsInvariant && !argCanBeModified)
{
- /* Clone the constant. Note that we cannot directly use argNode
- in the trees even if inlArgInfo[lclNum].argIsUsed==false as this
- would introduce aliasing between inlArgInfo[].argNode and
- impInlineExpr. Then gtFoldExpr() could change it, causing further
- references to the argument working off of the bashed copy. */
-
- op1 = gtCloneExpr(inlArgInfo[lclNum].argNode);
+ // Directly substitute constants or addresses of locals
+ //
+ // Clone the constant. Note that we cannot directly use
+ // argNode in the trees even if !argInfo.argIsUsed as this
+ // would introduce aliasing between inlArgInfo[].argNode and
+ // impInlineExpr. Then gtFoldExpr() could change it, causing
+ // further references to the argument working off of the
+ // bashed copy.
+ op1 = gtCloneExpr(argInfo.argNode);
PREFIX_ASSUME(op1 != nullptr);
- inlArgInfo[lclNum].argTmpNum = (unsigned)-1; // illegal temp
+ argInfo.argTmpNum = BAD_VAR_NUM;
}
- else if (inlArgInfo[lclNum].argIsLclVar && !inlArgInfo[lclNum].argHasLdargaOp && !inlArgInfo[lclNum].argHasStargOp)
+ else if (argInfo.argIsLclVar && !argCanBeModified)
{
- /* Argument is a local variable (of the caller)
- * Can we re-use the passed argument node? */
-
- op1 = inlArgInfo[lclNum].argNode;
- inlArgInfo[lclNum].argTmpNum = op1->gtLclVarCommon.gtLclNum;
+ // Directly substitute caller locals
+ //
+ // Use the caller-supplied node if this is the first use.
+ op1 = argInfo.argNode;
+ argInfo.argTmpNum = op1->gtLclVarCommon.gtLclNum;
- if (inlArgInfo[lclNum].argIsUsed)
+ // Use an equivalent copy if this is the second or subsequent use.
+ if (argInfo.argIsUsed)
{
assert(op1->gtOper == GT_LCL_VAR);
assert(lclNum == op1->gtLclVar.gtLclILoffs);
+ var_types newTyp = lclTyp;
+
if (!lvaTable[op1->gtLclVarCommon.gtLclNum].lvNormalizeOnLoad())
{
- lclTyp = genActualType(lclTyp);
+ newTyp = genActualType(lclTyp);
}
- /* Create a new lcl var node - remember the argument lclNum */
- op1 = gtNewLclvNode(op1->gtLclVarCommon.gtLclNum, lclTyp, op1->gtLclVar.gtLclILoffs);
+ // Create a new lcl var node - remember the argument lclNum
+ op1 = gtNewLclvNode(op1->gtLclVarCommon.gtLclNum, newTyp, op1->gtLclVar.gtLclILoffs);
}
}
- else if (inlArgInfo[lclNum].argIsByRefToStructLocal && !inlArgInfo[lclNum].argHasStargOp)
+ else if (argInfo.argIsByRefToStructLocal && !argInfo.argHasStargOp)
{
/* Argument is a by-ref address to a struct, a normed struct, or its field.
In these cases, don't spill the byref to a local, simply clone the tree and use it.
@@ -17812,59 +17921,65 @@ GenTreePtr Compiler::impInlineFetchArg(unsigned lclNum, InlArgInfo* inlArgInfo,
then we change the argument tree (of "ldloca.s V_1") to TYP_I_IMPL to match the callee signature. We'll
soon afterwards reject the inlining anyway, since the tree we return isn't a GT_LCL_VAR.
*/
- assert(inlArgInfo[lclNum].argNode->TypeGet() == TYP_BYREF ||
- inlArgInfo[lclNum].argNode->TypeGet() == TYP_I_IMPL);
- op1 = gtCloneExpr(inlArgInfo[lclNum].argNode);
+ assert(argInfo.argNode->TypeGet() == TYP_BYREF || argInfo.argNode->TypeGet() == TYP_I_IMPL);
+ op1 = gtCloneExpr(argInfo.argNode);
}
else
{
/* Argument is a complex expression - it must be evaluated into a temp */
- if (inlArgInfo[lclNum].argHasTmp)
+ if (argInfo.argHasTmp)
{
- assert(inlArgInfo[lclNum].argIsUsed);
- assert(inlArgInfo[lclNum].argTmpNum < lvaCount);
+ assert(argInfo.argIsUsed);
+ assert(argInfo.argTmpNum < lvaCount);
/* Create a new lcl var node - remember the argument lclNum */
- op1 = gtNewLclvNode(inlArgInfo[lclNum].argTmpNum, genActualType(lclTyp));
+ op1 = gtNewLclvNode(argInfo.argTmpNum, genActualType(lclTyp));
/* This is the second or later use of the this argument,
so we have to use the temp (instead of the actual arg) */
- inlArgInfo[lclNum].argBashTmpNode = nullptr;
+ argInfo.argBashTmpNode = nullptr;
}
else
{
/* First time use */
- assert(inlArgInfo[lclNum].argIsUsed == false);
+ assert(!argInfo.argIsUsed);
/* Reserve a temp for the expression.
* Use a large size node as we may change it later */
- unsigned tmpNum = lvaGrabTemp(true DEBUGARG("Inlining Arg"));
+ const unsigned tmpNum = lvaGrabTemp(true DEBUGARG("Inlining Arg"));
lvaTable[tmpNum].lvType = lclTyp;
+
+ // Copy over class handle for ref types. Note this may be
+ // further improved if it is a shared type and we know the exact context.
+ if (lclTyp == TYP_REF)
+ {
+ lvaSetClass(tmpNum, lclInfo.lclVerTypeInfo.GetClassHandleForObjRef());
+ }
+
assert(lvaTable[tmpNum].lvAddrExposed == 0);
- if (inlArgInfo[lclNum].argHasLdargaOp)
+ if (argInfo.argHasLdargaOp)
{
lvaTable[tmpNum].lvHasLdAddrOp = 1;
}
- if (lclVarInfo[lclNum].lclVerTypeInfo.IsStruct())
+ if (lclInfo.lclVerTypeInfo.IsStruct())
{
if (varTypeIsStruct(lclTyp))
{
- lvaSetStruct(tmpNum, impInlineInfo->lclVarInfo[lclNum].lclVerTypeInfo.GetClassHandle(),
- true /* unsafe value cls check */);
+ lvaSetStruct(tmpNum, lclInfo.lclVerTypeInfo.GetClassHandle(), true /* unsafe value cls check */);
}
else
{
// This is a wrapped primitive. Make sure the verstate knows that
- lvaTable[tmpNum].lvVerTypeInfo = impInlineInfo->lclVarInfo[lclNum].lclVerTypeInfo;
+ lvaTable[tmpNum].lvVerTypeInfo = lclInfo.lclVerTypeInfo;
}
}
- inlArgInfo[lclNum].argHasTmp = true;
- inlArgInfo[lclNum].argTmpNum = tmpNum;
+ argInfo.argHasTmp = true;
+ argInfo.argTmpNum = tmpNum;
// If we require strict exception order, then arguments must
// be evaluated in sequence before the body of the inlined method.
@@ -17875,7 +17990,7 @@ GenTreePtr Compiler::impInlineFetchArg(unsigned lclNum, InlArgInfo* inlArgInfo,
// TODO-1stClassStructs: We currently do not reuse an existing lclVar
// if it is a struct, because it requires some additional handling.
- if (!varTypeIsStruct(lclTyp) && (!inlArgInfo[lclNum].argHasSideEff) && (!inlArgInfo[lclNum].argHasGlobRef))
+ if (!varTypeIsStruct(lclTyp) && !argInfo.argHasSideEff && !argInfo.argHasGlobRef)
{
/* Get a *LARGE* LCL_VAR node */
op1 = gtNewLclLNode(tmpNum, genActualType(lclTyp), lclNum);
@@ -17884,21 +17999,20 @@ GenTreePtr Compiler::impInlineFetchArg(unsigned lclNum, InlArgInfo* inlArgInfo,
If there are no further uses of the arg, we may be
able to use the actual arg node instead of the temp.
If we do see any further uses, we will clear this. */
- inlArgInfo[lclNum].argBashTmpNode = op1;
+ argInfo.argBashTmpNode = op1;
}
else
{
/* Get a small LCL_VAR node */
op1 = gtNewLclvNode(tmpNum, genActualType(lclTyp));
/* No bashing of this argument */
- inlArgInfo[lclNum].argBashTmpNode = nullptr;
+ argInfo.argBashTmpNode = nullptr;
}
}
}
- /* Mark the argument as used */
-
- inlArgInfo[lclNum].argIsUsed = true;
+ // Mark this argument as used.
+ argInfo.argIsUsed = true;
return op1;
}
@@ -17977,16 +18091,28 @@ BOOL Compiler::impInlineIsGuaranteedThisDerefBeforeAnySideEffects(GenTreePtr ad
return TRUE;
}
-/******************************************************************************/
-// Check the inlining eligibility of this GT_CALL node.
-// Mark GTF_CALL_INLINE_CANDIDATE on the GT_CALL node
-
-// Todo: find a way to record the failure reasons in the IR (or
-// otherwise build tree context) so when we do the inlining pass we
-// can capture these reasons
+//------------------------------------------------------------------------
+// impMarkInlineCandidate: determine if this call can be subsequently inlined
+//
+// Arguments:
+// callNode -- call under scrutiny
+// exactContextHnd -- context handle for inlining
+// exactContextNeedsRuntimeLookup -- true if context required runtime lookup
+// callInfo -- call info from VM
+//
+// Notes:
+// If callNode is an inline candidate, this method sets the flag
+// GTF_CALL_INLINE_CANDIDATE, and ensures that helper methods have
+// filled in the associated InlineCandidateInfo.
+//
+// If callNode is not an inline candidate, and the reason is
+// something that is inherent to the method being called, the
+// method may be marked as "noinline" to short-circuit any
+// future assessments of calls to this method.
void Compiler::impMarkInlineCandidate(GenTreePtr callNode,
CORINFO_CONTEXT_HANDLE exactContextHnd,
+ bool exactContextNeedsRuntimeLookup,
CORINFO_CALL_INFO* callInfo)
{
// Let the strategy know there's another call
@@ -18172,6 +18298,10 @@ void Compiler::impMarkInlineCandidate(GenTreePtr callNode,
// The old value should be NULL
assert(call->gtInlineCandidateInfo == nullptr);
+ // The new value should not be NULL.
+ assert(inlineCandidateInfo != nullptr);
+ inlineCandidateInfo->exactContextNeedsRuntimeLookup = exactContextNeedsRuntimeLookup;
+
call->gtInlineCandidateInfo = inlineCandidateInfo;
// Mark the call node as inline candidate.
@@ -18297,4 +18427,335 @@ bool Compiler::IsMathIntrinsic(GenTreePtr tree)
{
return (tree->OperGet() == GT_INTRINSIC) && IsMathIntrinsic(tree->gtIntrinsic.gtIntrinsicId);
}
-/*****************************************************************************/
+
+//------------------------------------------------------------------------
+// impDevirtualizeCall: Attempt to change a virtual vtable call into a
+// normal call
+//
+// Arguments:
+// call -- the call node to examine/modify
+// thisObj -- the value of 'this' for the call
+// callInfo -- [IN/OUT] info about the call from the VM
+// exactContextHnd -- [OUT] updated context handle iff call devirtualized
+//
+// Notes:
+// Virtual calls in IL will always "invoke" the base class method.
+//
+// This transformation looks for evidence that the type of 'this'
+// in the call is exactly known, is a final class or would invoke
+// a final method, and if that and other safety checks pan out,
+// modifies the call and the call info to create a direct call.
+//
+// This transformation is initially done in the importer and not
+// in some subsequent optimization pass because we want it to be
+// upstream of inline candidate identification.
+//
+// However, later phases may supply improved type information that
+// can enable further devirtualization. We currently reinvoke this
+// code after inlining, if the return value of the inlined call is
+// the 'this obj' of a subsequent virtual call.
+//
+void Compiler::impDevirtualizeCall(GenTreeCall* call,
+ GenTreePtr thisObj,
+ CORINFO_CALL_INFO* callInfo,
+ CORINFO_CONTEXT_HANDLE* exactContextHandle)
+{
+ // This should be a virtual vtable or virtual stub call.
+ assert(call->IsVirtual());
+
+ // Bail if not optimizing
+ if (opts.MinOpts())
+ {
+ return;
+ }
+
+ // Bail if debuggable codegen
+ if (opts.compDbgCode)
+ {
+ return;
+ }
+
+#if defined(DEBUG)
+ // Bail if devirt is disabled.
+ if (JitConfig.JitEnableDevirtualization() == 0)
+ {
+ return;
+ }
+
+ const bool doPrint = JitConfig.JitPrintDevirtualizedMethods() == 1;
+#endif // DEBUG
+
+ // Fetch information about the virtual method we're calling.
+ CORINFO_METHOD_HANDLE baseMethod = callInfo->hMethod;
+ unsigned baseMethodAttribs = callInfo->methodFlags;
+
+ if (baseMethodAttribs == 0)
+ {
+ // For late devirt we may not have method attributes, so fetch them.
+ baseMethodAttribs = info.compCompHnd->getMethodAttribs(baseMethod);
+ }
+ else
+ {
+#if defined(DEBUG)
+ // Validate that callInfo has up to date method flags
+ const DWORD freshBaseMethodAttribs = info.compCompHnd->getMethodAttribs(baseMethod);
+ assert(freshBaseMethodAttribs == baseMethodAttribs);
+#endif // DEBUG
+ }
+
+ // In R2R mode, we might see virtual stub calls to
+ // non-virtuals. For instance cases where the non-virtual method
+ // is in a different assembly but is called via CALLVIRT. For
+ // verison resilience we must allow for the fact that the method
+ // might become virtual in some update.
+ //
+ // In non-R2R modes CALLVIRT <nonvirtual> will be turned into a
+ // regular call+nullcheck upstream, so we won't reach this
+ // point.
+ if ((baseMethodAttribs & CORINFO_FLG_VIRTUAL) == 0)
+ {
+ assert(call->IsVirtualStub());
+ assert(opts.IsReadyToRun());
+ JITDUMP("\nimpDevirtualizeCall: [R2R] base method not virtual, sorry\n");
+ return;
+ }
+
+ // See what we know about the type of 'this' in the call.
+ bool isExact = false;
+ bool objIsNonNull = false;
+ CORINFO_CLASS_HANDLE objClass = gtGetClassHandle(thisObj, &isExact, &objIsNonNull);
+
+ // Bail if we know nothing.
+ if (objClass == nullptr)
+ {
+ JITDUMP("\nimpDevirtualizeCall: no type available (op=%s)\n", GenTree::OpName(thisObj->OperGet()));
+ return;
+ }
+
+ // Fetch information about the class that introduced the virtual method.
+ CORINFO_CLASS_HANDLE baseClass = info.compCompHnd->getMethodClass(baseMethod);
+ const DWORD baseClassAttribs = info.compCompHnd->getClassAttribs(baseClass);
+
+#if !defined(FEATURE_CORECLR)
+ // If base class is not beforefieldinit then devirtualizing may
+ // cause us to miss a base class init trigger. Spec says we don't
+ // need a trigger for ref class callvirts but desktop seems to
+ // have one anyways. So defer.
+ if ((baseClassAttribs & CORINFO_FLG_BEFOREFIELDINIT) == 0)
+ {
+ JITDUMP("\nimpDevirtualizeCall: base class has precise initialization, sorry\n");
+ return;
+ }
+#endif // FEATURE_CORECLR
+
+ // Is the call an interface call?
+ const bool isInterface = (baseClassAttribs & CORINFO_FLG_INTERFACE) != 0;
+
+ // If the objClass is sealed (final), then we may be able to devirtualize.
+ const DWORD objClassAttribs = info.compCompHnd->getClassAttribs(objClass);
+ const bool objClassIsFinal = (objClassAttribs & CORINFO_FLG_FINAL) != 0;
+
+#if defined(DEBUG)
+ const char* callKind = isInterface ? "interface" : "virtual";
+ const char* objClassNote = "[?]";
+ const char* objClassName = "?objClass";
+ const char* baseClassName = "?baseClass";
+ const char* baseMethodName = "?baseMethod";
+
+ if (verbose || doPrint)
+ {
+ objClassNote = isExact ? " [exact]" : objClassIsFinal ? " [final]" : "";
+ objClassName = info.compCompHnd->getClassName(objClass);
+ baseClassName = info.compCompHnd->getClassName(baseClass);
+ baseMethodName = eeGetMethodName(baseMethod, nullptr);
+
+ if (verbose)
+ {
+ printf("\nimpDevirtualizeCall: Trying to devirtualize %s call:\n"
+ " class for 'this' is %s%s (attrib %08x)\n"
+ " base method is %s::%s\n",
+ callKind, objClassName, objClassNote, objClassAttribs, baseClassName, baseMethodName);
+ }
+ }
+#endif // defined(DEBUG)
+
+ // Bail if obj class is an interface.
+ // See for instance System.ValueTuple`8::GetHashCode, where lcl 0 is System.IValueTupleInternal
+ // IL_021d: ldloc.0
+ // IL_021e: callvirt instance int32 System.Object::GetHashCode()
+ if ((objClassAttribs & CORINFO_FLG_INTERFACE) != 0)
+ {
+ JITDUMP("--- obj class is interface, sorry\n");
+ return;
+ }
+
+ if (isInterface)
+ {
+ assert(call->IsVirtualStub());
+ JITDUMP("--- base class is interface\n");
+ }
+
+ // Fetch the method that would be called based on the declared type of 'this'
+ CORINFO_CONTEXT_HANDLE ownerType = callInfo->contextHandle;
+ CORINFO_METHOD_HANDLE derivedMethod = info.compCompHnd->resolveVirtualMethod(baseMethod, objClass, ownerType);
+
+ // If we failed to get a handle, we can't devirtualize. This can
+ // happen when prejitting, if the devirtualization crosses
+ // servicing bubble boundaries.
+ if (derivedMethod == nullptr)
+ {
+ JITDUMP("--- no derived method, sorry\n");
+ return;
+ }
+
+ // Fetch method attributes to see if method is marked final.
+ const DWORD derivedMethodAttribs = info.compCompHnd->getMethodAttribs(derivedMethod);
+ const bool derivedMethodIsFinal = ((derivedMethodAttribs & CORINFO_FLG_FINAL) != 0);
+
+#if defined(DEBUG)
+ const char* derivedClassName = "?derivedClass";
+ const char* derivedMethodName = "?derivedMethod";
+
+ const char* note = "speculative";
+ if (isExact)
+ {
+ note = "exact";
+ }
+ else if (objClassIsFinal)
+ {
+ note = "final class";
+ }
+ else if (derivedMethodIsFinal)
+ {
+ note = "final method";
+ }
+
+ if (verbose || doPrint)
+ {
+ derivedMethodName = eeGetMethodName(derivedMethod, &derivedClassName);
+ if (verbose)
+ {
+ printf(" devirt to %s::%s -- %s\n", derivedClassName, derivedMethodName, note);
+ gtDispTree(call);
+ }
+ }
+#endif // defined(DEBUG)
+
+ if (!isExact && !objClassIsFinal && !derivedMethodIsFinal)
+ {
+ // Type is not exact, and neither class or method is final.
+ //
+ // We could speculatively devirtualize, but there's no
+ // reason to believe the derived method is the one that
+ // is likely to be invoked.
+ //
+ // If there's currently no further overriding (that is, at
+ // the time of jitting, objClass has no subclasses that
+ // override this method), then perhaps we'd be willing to
+ // make a bet...?
+ JITDUMP(" Class not final or exact, method not final, no devirtualization\n");
+ return;
+ }
+
+ // For interface calls we must have an exact type or final class.
+ if (isInterface && !isExact && !objClassIsFinal)
+ {
+ JITDUMP(" Class not final or exact for interface, no devirtualization\n");
+ return;
+ }
+
+ JITDUMP(" %s; can devirtualize\n", note);
+
+ // Make the updates.
+ call->gtFlags &= ~GTF_CALL_VIRT_VTABLE;
+ call->gtFlags &= ~GTF_CALL_VIRT_STUB;
+ call->gtCallMethHnd = derivedMethod;
+ call->gtCallType = CT_USER_FUNC;
+
+ // Virtual calls include an implicit null check, which we may
+ // now need to make explicit.
+ if (!objIsNonNull)
+ {
+ call->gtFlags |= GTF_CALL_NULLCHECK;
+ }
+
+ // Clear the inline candidate info (may be non-null since
+ // it's a union field used for other things by virtual
+ // stubs)
+ call->gtInlineCandidateInfo = nullptr;
+
+ // Fetch the class that introduced the derived method.
+ //
+ // Note this may not equal objClass, if there is a
+ // final method that objClass inherits.
+ CORINFO_CLASS_HANDLE derivedClass = info.compCompHnd->getMethodClass(derivedMethod);
+
+#ifdef FEATURE_READYTORUN_COMPILER
+ if (opts.IsReadyToRun())
+ {
+ // For R2R, getCallInfo triggers bookkeeping on the zap
+ // side so we need to call it here.
+ //
+ // First, cons up a suitable resolved token.
+ CORINFO_RESOLVED_TOKEN derivedResolvedToken = {};
+
+ derivedResolvedToken.tokenScope = info.compScopeHnd;
+ derivedResolvedToken.tokenContext = callInfo->contextHandle;
+ derivedResolvedToken.token = info.compCompHnd->getMethodDefFromMethod(derivedMethod);
+ derivedResolvedToken.tokenType = CORINFO_TOKENKIND_Method;
+ derivedResolvedToken.hClass = derivedClass;
+ derivedResolvedToken.hMethod = derivedMethod;
+
+ // Look up the new call info.
+ CORINFO_CALL_INFO derivedCallInfo;
+ eeGetCallInfo(&derivedResolvedToken, nullptr, addVerifyFlag(CORINFO_CALLINFO_ALLOWINSTPARAM), &derivedCallInfo);
+
+ // Update the call.
+ call->gtCallMoreFlags &= ~GTF_CALL_M_VIRTSTUB_REL_INDIRECT;
+ call->gtCallMoreFlags &= ~GTF_CALL_M_R2R_REL_INDIRECT;
+ call->setEntryPoint(derivedCallInfo.codePointerLookup.constLookup);
+ }
+#endif // FEATURE_READYTORUN_COMPILER
+
+ // Need to update call info too. This is fragile
+ // but hopefully the derived method conforms to
+ // the base in most other ways.
+ callInfo->hMethod = derivedMethod;
+ callInfo->methodFlags = derivedMethodAttribs;
+ callInfo->contextHandle = MAKE_METHODCONTEXT(derivedMethod);
+
+ // Update context handle.
+ if ((exactContextHandle != nullptr) && (*exactContextHandle != nullptr))
+ {
+ *exactContextHandle = MAKE_METHODCONTEXT(derivedMethod);
+ }
+
+#if defined(DEBUG)
+ if (verbose)
+ {
+ printf("... after devirt...\n");
+ gtDispTree(call);
+ }
+
+ if (doPrint)
+ {
+ printf("Devirtualized %s call to %s:%s; now direct call to %s:%s [%s]\n", callKind, baseClassName,
+ baseMethodName, derivedClassName, derivedMethodName, note);
+ }
+#endif // defined(DEBUG)
+}
+
+//------------------------------------------------------------------------
+// impAllocateToken: create CORINFO_RESOLVED_TOKEN into jit-allocated memory and init it.
+//
+// Arguments:
+// token - init value for the allocated token.
+//
+// Return Value:
+// pointer to token into jit-allocated memory.
+CORINFO_RESOLVED_TOKEN* Compiler::impAllocateToken(CORINFO_RESOLVED_TOKEN token)
+{
+ CORINFO_RESOLVED_TOKEN* memory = (CORINFO_RESOLVED_TOKEN*)compGetMem(sizeof(token));
+ *memory = token;
+ return memory;
+}
diff --git a/src/jit/inline.def b/src/jit/inline.def
index 2a6f5a3f73..ff0b21100e 100644
--- a/src/jit/inline.def
+++ b/src/jit/inline.def
@@ -39,7 +39,6 @@ INLINE_OBSERVATION(HAS_LEAVE, bool, "has leave",
INLINE_OBSERVATION(HAS_MANAGED_VARARGS, bool, "managed varargs", FATAL, CALLEE)
INLINE_OBSERVATION(HAS_NATIVE_VARARGS, bool, "native varargs", FATAL, CALLEE)
INLINE_OBSERVATION(HAS_NO_BODY, bool, "has no body", FATAL, CALLEE)
-INLINE_OBSERVATION(HAS_NOINLINE_CALLEE, bool, "in corelib, noinline callee", FATAL, CALLEE)
INLINE_OBSERVATION(HAS_NULL_FOR_LDELEM, bool, "has null pointer for ldelem", FATAL, CALLEE)
INLINE_OBSERVATION(IS_ARRAY_METHOD, bool, "is array method", FATAL, CALLEE)
INLINE_OBSERVATION(IS_GENERIC_VIRTUAL, bool, "generic virtual", FATAL, CALLEE)
@@ -56,6 +55,7 @@ INLINE_OBSERVATION(NEEDS_SECURITY_CHECK, bool, "needs security check",
INLINE_OBSERVATION(NO_METHOD_INFO, bool, "cannot get method info", FATAL, CALLEE)
INLINE_OBSERVATION(NOT_PROFITABLE_INLINE, bool, "unprofitable inline", FATAL, CALLEE)
INLINE_OBSERVATION(RANDOM_REJECT, bool, "random reject", FATAL, CALLEE)
+INLINE_OBSERVATION(STACK_CRAWL_MARK, bool, "uses stack crawl mark", FATAL, CALLEE)
INLINE_OBSERVATION(STFLD_NEEDS_HELPER, bool, "stfld needs helper", FATAL, CALLEE)
INLINE_OBSERVATION(THROW_WITH_INVALID_STACK, bool, "throw with invalid stack", FATAL, CALLEE)
INLINE_OBSERVATION(TOO_MANY_ARGUMENTS, bool, "too many arguments", FATAL, CALLEE)
diff --git a/src/jit/inline.h b/src/jit/inline.h
index 2634ebe6fa..ee07130676 100644
--- a/src/jit/inline.h
+++ b/src/jit/inline.h
@@ -506,6 +506,7 @@ struct InlineCandidateInfo
var_types fncRetType;
CORINFO_METHOD_HANDLE ilCallerHandle; // the logical IL caller of this inlinee.
CORINFO_CONTEXT_HANDLE exactContextHnd;
+ bool exactContextNeedsRuntimeLookup;
CorInfoInitClassResult initClassResult;
};
@@ -513,31 +514,32 @@ struct InlineCandidateInfo
struct InlArgInfo
{
- unsigned argIsUsed : 1; // is this arg used at all?
- unsigned argIsInvariant : 1; // the argument is a constant or a local variable address
- unsigned argIsLclVar : 1; // the argument is a local variable
- unsigned argIsThis : 1; // the argument is the 'this' pointer
- unsigned argHasSideEff : 1; // the argument has side effects
- unsigned argHasGlobRef : 1; // the argument has a global ref
- unsigned argHasTmp : 1; // the argument will be evaluated to a temp
- unsigned argIsByRefToStructLocal : 1; // Is this arg an address of a struct local or a normed struct local or a
- // field in them?
- unsigned argHasLdargaOp : 1; // Is there LDARGA(s) operation on this argument?
- unsigned argHasStargOp : 1; // Is there STARG(s) operation on this argument?
-
- unsigned argTmpNum; // the argument tmp number
- GenTreePtr argNode;
- GenTreePtr argBashTmpNode; // tmp node created, if it may be replaced with actual arg
+ GenTreePtr argNode; // caller node for this argument
+ GenTreePtr argBashTmpNode; // tmp node created, if it may be replaced with actual arg
+ unsigned argTmpNum; // the argument tmp number
+ unsigned argIsUsed : 1; // is this arg used at all?
+ unsigned argIsInvariant : 1; // the argument is a constant or a local variable address
+ unsigned argIsLclVar : 1; // the argument is a local variable
+ unsigned argIsThis : 1; // the argument is the 'this' pointer
+ unsigned argHasSideEff : 1; // the argument has side effects
+ unsigned argHasGlobRef : 1; // the argument has a global ref
+ unsigned argHasTmp : 1; // the argument will be evaluated to a temp
+ unsigned argHasLdargaOp : 1; // Is there LDARGA(s) operation on this argument?
+ unsigned argHasStargOp : 1; // Is there STARG(s) operation on this argument?
+ unsigned argIsByRefToStructLocal : 1; // Is this arg an address of a struct local or a normed struct local or a
+ // field in them?
};
-// InlArgInfo describes inline candidate local variable properties.
+// InlLclVarInfo describes inline candidate argument and local variable properties.
struct InlLclVarInfo
{
- var_types lclTypeInfo;
typeInfo lclVerTypeInfo;
- bool lclHasLdlocaOp; // Is there LDLOCA(s) operation on this argument?
- bool lclIsPinned;
+ var_types lclTypeInfo;
+ unsigned lclHasLdlocaOp : 1; // Is there LDLOCA(s) operation on this local?
+ unsigned lclHasStlocOp : 1; // Is there a STLOC on this local?
+ unsigned lclHasMultipleStlocOp : 1; // Is there more than one STLOC on this local
+ unsigned lclIsPinned : 1;
};
// InlineInfo provides detailed information about a particular inline candidate.
@@ -563,8 +565,16 @@ struct InlineInfo
int lclTmpNum[MAX_INL_LCLS]; // map local# -> temp# (-1 if unused)
InlLclVarInfo lclVarInfo[MAX_INL_LCLS + MAX_INL_ARGS + 1]; // type information from local sig
- bool thisDereferencedFirst;
- bool hasPinnedLocals;
+ unsigned numberOfGcRefLocals; // Number of TYP_REF and TYP_BYREF locals
+
+ bool HasGcRefLocals() const
+ {
+ return numberOfGcRefLocals > 0;
+ }
+
+ bool thisDereferencedFirst;
+ unsigned typeContextArg;
+
#ifdef FEATURE_SIMD
bool hasSIMDTypeArgLocalOrReturn;
#endif // FEATURE_SIMD
diff --git a/src/jit/instr.cpp b/src/jit/instr.cpp
index 7332ba6c71..e2435cab28 100644
--- a/src/jit/instr.cpp
+++ b/src/jit/instr.cpp
@@ -797,7 +797,6 @@ void CodeGen::sched_AM(instruction ins,
}
else if (addr->IsCnsIntOrI())
{
-#ifdef RELOC_SUPPORT
// Do we need relocations?
if (compiler->opts.compReloc && addr->IsIconHandle())
{
@@ -806,7 +805,6 @@ void CodeGen::sched_AM(instruction ins,
// so that we can uniquely identify the handle
assert(offs <= 4);
}
-#endif
ssize_t disp = addr->gtIntCon.gtIconVal + offs;
if ((insType == eIT_Store) && (ireg != REG_NA))
{
@@ -1113,7 +1111,6 @@ void CodeGen::sched_AM(instruction ins,
assert(addr->IsCnsIntOrI());
-#ifdef RELOC_SUPPORT
// Do we need relocations?
if (compiler->opts.compReloc && addr->IsIconHandle())
{
@@ -1122,7 +1119,7 @@ void CodeGen::sched_AM(instruction ins,
// so that we can uniquely identify the handle
assert(offs <= 4);
}
-#endif
+
reg = REG_NA;
ssize_t disp = addr->gtIntCon.gtIconVal + offs;
@@ -1251,9 +1248,12 @@ void CodeGen::sched_AM(instruction ins,
* Emit a "call [r/m]" instruction (the r/m operand given by a tree).
*/
-void CodeGen::instEmit_indCall(GenTreePtr call,
+// clang-format off
+void CodeGen::instEmit_indCall(GenTreeCall* call,
size_t argSize,
- emitAttr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize))
+ emitAttr retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize))
+// clang-format on
{
GenTreePtr addr;
@@ -1266,18 +1266,16 @@ void CodeGen::instEmit_indCall(GenTreePtr call,
CORINFO_SIG_INFO* sigInfo = nullptr;
- assert(call->gtOper == GT_CALL);
-
/* Get hold of the function address */
- assert(call->gtCall.gtCallType == CT_INDIRECT);
- addr = call->gtCall.gtCallAddr;
+ assert(call->gtCallType == CT_INDIRECT);
+ addr = call->gtCallAddr;
assert(addr);
#ifdef DEBUG
// Pass the call signature information from the GenTree node so the emitter can associate
// native call sites with the signatures they were generated from.
- sigInfo = call->gtCall.callSig;
+ sigInfo = call->callSig;
#endif // DEBUG
#if CPU_LOAD_STORE_ARCH
@@ -1290,11 +1288,19 @@ void CodeGen::instEmit_indCall(GenTreePtr call,
{
ssize_t funcPtr = addr->gtIntCon.gtIconVal;
+ // clang-format off
getEmitter()->emitIns_Call(emitter::EC_FUNC_ADDR,
NULL, // methHnd
- INDEBUG_LDISASM_COMMA(sigInfo)(void*) funcPtr, argSize,
- retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
- gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur);
+ INDEBUG_LDISASM_COMMA(sigInfo)
+ (void*) funcPtr,
+ argSize,
+ retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
+ gcInfo.gcVarPtrSetCur,
+ gcInfo.gcRegGCrefSetCur,
+ gcInfo.gcRegByrefSetCur);
+ // clang-format on
+
return;
}
}
@@ -1347,11 +1353,19 @@ void CodeGen::instEmit_indCall(GenTreePtr call,
{
ssize_t funcPtr = addr->gtIntCon.gtIconVal;
+ // clang-format off
getEmitter()->emitIns_Call(emitter::EC_FUNC_ADDR,
nullptr, // methHnd
- INDEBUG_LDISASM_COMMA(sigInfo)(void*) funcPtr, argSize,
- retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
- gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur);
+ INDEBUG_LDISASM_COMMA(sigInfo)
+ (void*) funcPtr,
+ argSize,
+ retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
+ gcInfo.gcVarPtrSetCur,
+ gcInfo.gcRegGCrefSetCur,
+ gcInfo.gcRegByrefSetCur);
+ // clang-format on
+
return;
}
}
@@ -1386,7 +1400,7 @@ void CodeGen::instEmit_indCall(GenTreePtr call,
INDEBUG(bool yes =)
genCreateAddrMode(addr, -1, true, RBM_NONE, &rev, &rv1, &rv2, &mul, &cns);
- INDEBUG(PREFIX_ASSUME(yes)); // since we have called genMakeAddressable() on call->gtCall.gtCallAddr
+ INDEBUG(PREFIX_ASSUME(yes)); // since we have called genMakeAddressable() on call->gtCallAddr
/* Get the additional operands if any */
@@ -1409,14 +1423,23 @@ void CodeGen::instEmit_indCall(GenTreePtr call,
#endif // CPU_LOAD_STORE_ARCH
+ // clang-format off
getEmitter()->emitIns_Call(emitCallType,
nullptr, // methHnd
- INDEBUG_LDISASM_COMMA(sigInfo) nullptr, // addr
- argSize, retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
- gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur, gcInfo.gcRegByrefSetCur,
+ INDEBUG_LDISASM_COMMA(sigInfo)
+ nullptr, // addr
+ argSize,
+ retSize
+ MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
+ gcInfo.gcVarPtrSetCur,
+ gcInfo.gcRegGCrefSetCur,
+ gcInfo.gcRegByrefSetCur,
BAD_IL_OFFSET, // ilOffset
- brg, xrg, mul,
+ brg,
+ xrg,
+ mul,
cns); // addressing mode values
+ // clang-format on
}
#ifdef LEGACY_BACKEND
@@ -2326,7 +2349,7 @@ void CodeGen::inst_RV_TT(instruction ins,
#if CPU_LOAD_STORE_ARCH
if (ins == INS_mov)
{
-#if defined(_TARGET_ARM_)
+#if defined(_TARGET_ARM_) && CPU_LONG_USES_REGPAIR
if (tree->TypeGet() != TYP_LONG)
{
ins = ins_Move_Extend(tree->TypeGet(), (tree->gtFlags & GTF_REG_VAL) != 0);
@@ -2341,7 +2364,7 @@ void CodeGen::inst_RV_TT(instruction ins,
ins = ins_Move_Extend(TYP_INT,
(tree->gtFlags & GTF_REG_VAL) != 0 && genRegPairHi(tree->gtRegPair) != REG_STK);
}
-#elif defined(_TARGET_ARM64_)
+#elif defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
ins = ins_Move_Extend(tree->TypeGet(), (tree->gtFlags & GTF_REG_VAL) != 0);
#else
NYI("CodeGen::inst_RV_TT with INS_mov");
@@ -2485,9 +2508,11 @@ AGAIN:
default:
regNumber regTmp;
#ifndef LEGACY_BACKEND
+#if CPU_LONG_USES_REGPAIR
if (tree->TypeGet() == TYP_LONG)
regTmp = (offs == 0) ? genRegPairLo(tree->gtRegPair) : genRegPairHi(tree->gtRegPair);
else
+#endif // CPU_LONG_USES_REGPAIR
regTmp = tree->gtRegNum;
#else // LEGACY_BACKEND
if (varTypeIsFloating(tree))
@@ -2595,17 +2620,6 @@ AGAIN:
constVal = (ssize_t)(tree->gtLngCon.gtLconVal >> 32);
size = EA_4BYTE;
}
-#ifndef LEGACY_BACKEND
-#ifdef _TARGET_ARM_
- if ((ins != INS_mov) && !arm_Valid_Imm_For_Instr(ins, constVal, flags))
- {
- regNumber constReg = (offs == 0) ? genRegPairLo(tree->gtRegPair) : genRegPairHi(tree->gtRegPair);
- instGen_Set_Reg_To_Imm(size, constReg, constVal);
- getEmitter()->emitIns_R_R(ins, size, reg, constReg, flags);
- break;
- }
-#endif // _TARGET_ARM_
-#endif // !LEGACY_BACKEND
inst_RV_IV(ins, reg, constVal, size, flags);
break;
@@ -3573,9 +3587,13 @@ instruction CodeGen::ins_FloatSqrt(var_types type)
{
ins = INS_sqrtsd;
}
+ else if (type == TYP_FLOAT)
+ {
+ ins = INS_sqrtss;
+ }
else
{
- // Right now sqrt of scalar single is not needed.
+ assert(!"ins_FloatSqrt: Unsupported type");
unreached();
}
@@ -3873,9 +3891,7 @@ void CodeGen::instGen_Set_Reg_To_Zero(emitAttr size, regNumber reg, insFlags fla
*/
void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, regNumber reg, ssize_t imm, insFlags flags)
{
-#if RELOC_SUPPORT
if (!compiler->opts.compReloc)
-#endif // RELOC_SUPPORT
{
size = EA_SIZE(size); // Strip any Reloc flags from size if we aren't doing relocs
}
diff --git a/src/jit/instrsxarch.h b/src/jit/instrsxarch.h
index 8ab3a845ba..729bece554 100644
--- a/src/jit/instrsxarch.h
+++ b/src/jit/instrsxarch.h
@@ -232,9 +232,10 @@ INST3( maxsd, "maxsd", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSEDBL(0x5F)) /
INST3( xorpd, "xorpd", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, PCKDBL(0x57)) // XOR packed doubles
INST3( andps, "andps", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, PCKFLT(0x54)) // AND packed singles
INST3( andpd, "andpd", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, PCKDBL(0x54)) // AND packed doubles
-INST3( sqrtsd, "sqrtsd", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSEDBL(0x51)) // Sqrt of a scalar double
-INST3( sqrtps, "sqrtps", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, PCKFLT(0x51)) // Sqrt of a packed float
-INST3( sqrtpd, "sqrtpd", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, PCKDBL(0x51)) // Sqrt of a packed double
+INST3( sqrtps, "sqrtps", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, PCKFLT(0x51)) // Sqrt of packed singles
+INST3( sqrtss, "sqrtss", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSEFLT(0x51)) // Sqrt of scalar single
+INST3( sqrtpd, "sqrtpd", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, PCKDBL(0x51)) // Sqrt of packed doubles
+INST3( sqrtsd, "sqrtsd", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSEDBL(0x51)) // Sqrt of scalar double
INST3( andnps, "andnps", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, PCKFLT(0x55)) // And-Not packed singles
INST3( andnpd, "andnpd", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, PCKDBL(0x55)) // And-Not packed doubles
INST3( orps, "orps", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, PCKFLT(0x56)) // Or packed singles
@@ -310,7 +311,6 @@ INST3(LAST_SSE2_INSTRUCTION, "LAST_SSE2_INSTRUCTION", 0, IUM_WR, 0, 0, BAD_CODE
#ifndef LEGACY_BACKEND
INST3(FIRST_SSE4_INSTRUCTION, "FIRST_SSE4_INSTRUCTION", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, BAD_CODE)
-// Most of the following instructions should be included in the method Is4ByteAVXInstruction()
// enum name FP updmode rf wf MR MI RM
INST3( dpps, "dpps" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE3A(0x40)) // Packed bit-wise AND NOT of two xmm regs
INST3( dppd, "dppd" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE3A(0x41)) // Packed bit-wise AND NOT of two xmm regs
@@ -323,6 +323,14 @@ INST3( phaddd, "phaddd" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SS
INST3( pabsb, "pabsb" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x1C)) // Packed absolute value of bytes
INST3( pabsw, "pabsw" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x1D)) // Packed absolute value of 16-bit integers
INST3( pabsd, "pabsd" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x1E)) // Packed absolute value of 32-bit integers
+INST3( pminsb, "pminsb" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x38)) // packed minimum signed bytes
+INST3( pminsd, "pminsd" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x39)) // packed minimum 32-bit signed integers
+INST3( pminuw, "pminuw" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x3A)) // packed minimum 16-bit unsigned integers
+INST3( pminud, "pminud" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x3B)) // packed minimum 32-bit unsigned integers
+INST3( pmaxsb, "pmaxsb" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x3C)) // packed maximum signed bytes
+INST3( pmaxsd, "pmaxsd" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x3D)) // packed maximum 32-bit signed integers
+INST3( pmaxuw, "pmaxuw" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x3E)) // packed maximum 16-bit unsigned integers
+INST3( pmaxud, "pmaxud" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x3F)) // packed maximum 32-bit unsigned integers
INST3(LAST_SSE4_INSTRUCTION, "LAST_SSE4_INSTRUCTION", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, BAD_CODE)
INST3(FIRST_AVX_INSTRUCTION, "FIRST_AVX_INSTRUCTION", 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, BAD_CODE)
diff --git a/src/jit/jit.h b/src/jit/jit.h
index 05b154e15a..ee3f8c9117 100644
--- a/src/jit/jit.h
+++ b/src/jit/jit.h
@@ -172,6 +172,31 @@
#define _TARGET_ARMARCH_
#endif
+// If the UNIX_AMD64_ABI is defined make sure that _TARGET_AMD64_ is also defined.
+#if defined(UNIX_AMD64_ABI)
+#if !defined(_TARGET_AMD64_)
+#error When UNIX_AMD64_ABI is defined you must define _TARGET_AMD64_ defined as well.
+#endif
+#endif
+
+// If the UNIX_X86_ABI is defined make sure that _TARGET_X86_ is also defined.
+#if defined(UNIX_X86_ABI)
+#if !defined(_TARGET_X86_)
+#error When UNIX_X86_ABI is defined you must define _TARGET_X86_ defined as well.
+#endif
+#endif
+
+#if defined(PLATFORM_UNIX)
+#define _HOST_UNIX_
+#endif
+
+// Are we generating code to target Unix? This is true if we will run on Unix (_HOST_UNIX_ is defined).
+// It's also true if we are building an altjit targetting Unix, which we determine by checking if either
+// UNIX_AMD64_ABI or UNIX_X86_ABI is defined.
+#if defined(_HOST_UNIX_) || ((defined(UNIX_AMD64_ABI) || defined(UNIX_X86_ABI)) && defined(ALT_JIT))
+#define _TARGET_UNIX_
+#endif
+
// --------------------------------------------------------------------------------
// IMAGE_FILE_MACHINE_TARGET
// --------------------------------------------------------------------------------
@@ -190,7 +215,14 @@
// Include the AMD64 unwind codes when appropriate.
#if defined(_TARGET_AMD64_)
+// We need to temporarily set PLATFORM_UNIX, if necessary, to get the Unix-specific unwind codes.
+#if defined(_TARGET_UNIX_) && !defined(_HOST_UNIX_)
+#define PLATFORM_UNIX
+#endif
#include "win64unwind.h"
+#if defined(_TARGET_UNIX_) && !defined(_HOST_UNIX_)
+#undef PLATFORM_UNIX
+#endif
#endif
// Macros for defining strongly-typed enums. Use as follows:
@@ -216,23 +248,6 @@
#define __PLACEMENT_NEW_INLINE // don't bring in the global placement new, it is easy to make a mistake
// with our new(compiler*) pattern.
-#if COR_JIT_EE_VER > 460
-#define NO_CLRCONFIG // Don't bring in the usual CLRConfig infrastructure, since the JIT uses the JIT/EE
- // interface to retrieve config values.
-
-// This is needed for contract.inl when FEATURE_STACK_PROBE is enabled.
-struct CLRConfig
-{
- static struct ConfigKey
- {
- } EXTERNAL_NO_SO_NOT_MAINLINE;
- static DWORD GetConfigValue(const ConfigKey& key)
- {
- return 0;
- }
-};
-#endif
-
#include "utilcode.h" // this defines assert as _ASSERTE
#include "host.h" // this redefines assert for the JIT to use assertAbort
#include "utils.h"
@@ -727,17 +742,6 @@ private:
/*****************************************************************************/
-#define SECURITY_CHECK 1
-#define VERIFY_IMPORTER 1
-
-/*****************************************************************************/
-
-#if !defined(RELOC_SUPPORT)
-#define RELOC_SUPPORT 1
-#endif
-
-/*****************************************************************************/
-
#include "error.h"
/*****************************************************************************/
diff --git a/src/jit/jit.settings.targets b/src/jit/jit.settings.targets
index 8749b80242..bde639556b 100644
--- a/src/jit/jit.settings.targets
+++ b/src/jit/jit.settings.targets
@@ -120,6 +120,9 @@
<CppCompile Include="..\TargetArm.cpp" />
<CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='True'" Include="..\registerfp.cpp" />
<CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\DecomposeLongs.cpp" />
+ <CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\LowerArmArch.cpp" />
+ <CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\lsraarmarch.cpp" />
+ <CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\CodeGenArmArch.cpp" />
<CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\LowerArm.cpp" />
<CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\lsraarm.cpp" />
<CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\CodeGenArm.cpp" />
@@ -129,6 +132,9 @@
<!-- ARM64 target is always RyuJIT backend -->
<CppCompile Include="..\emitarm64.cpp" />
<CppCompile Include="..\TargetArm64.cpp" />
+ <CppCompile Include="..\LowerArmArch.cpp" />
+ <CppCompile Include="..\lsraarmarch.cpp" />
+ <CppCompile Include="..\CodeGenArmArch.cpp" />
<CppCompile Include="..\LowerArm64.cpp" />
<CppCompile Include="..\lsraarm64.cpp" />
<CppCompile Include="..\CodeGenArm64.cpp" />
diff --git a/src/jit/jitconfigvalues.h b/src/jit/jitconfigvalues.h
index 4623fe8268..624ad1a191 100644
--- a/src/jit/jitconfigvalues.h
+++ b/src/jit/jitconfigvalues.h
@@ -6,6 +6,10 @@
#error CONFIG_INTEGER, CONFIG_STRING, and CONFIG_METHODSET must be defined before including this file.
#endif // !defined(CONFIG_INTEGER) || !defined(CONFIG_STRING) || !defined(CONFIG_METHODSET)
+#ifdef DEBUG
+#define OPT_CONFIG // Enable optimization level configuration.
+#endif
+
#if defined(DEBUG)
CONFIG_INTEGER(AltJitLimit, W("AltJitLimit"), 0) // Max number of functions to use altjit for (decimal)
CONFIG_INTEGER(AltJitSkipOnAssert, W("AltJitSkipOnAssert"), 0) // If AltJit hits an assert, fall back to the fallback
@@ -36,13 +40,6 @@ CONFIG_INTEGER(JitDebugLogLoopCloning, W("JitDebugLogLoopCloning"), 0) // In deb
CONFIG_INTEGER(JitDefaultFill, W("JitDefaultFill"), 0xff) // In debug builds, initialize the memory allocated by the nra
// with this byte.
CONFIG_INTEGER(JitDirectAlloc, W("JitDirectAlloc"), 0)
-CONFIG_INTEGER(JitDoAssertionProp, W("JitDoAssertionProp"), 1) // Perform assertion propagation optimization
-CONFIG_INTEGER(JitDoCopyProp, W("JitDoCopyProp"), 1) // Perform copy propagation on variables that appear redundant
-CONFIG_INTEGER(JitDoEarlyProp, W("JitDoEarlyProp"), 1) // Perform Early Value Propagataion
-CONFIG_INTEGER(JitDoLoopHoisting, W("JitDoLoopHoisting"), 1) // Perform loop hoisting on loop invariant values
-CONFIG_INTEGER(JitDoRangeAnalysis, W("JitDoRangeAnalysis"), 1) // Perform range check analysis
-CONFIG_INTEGER(JitDoSsa, W("JitDoSsa"), 1) // Perform Static Single Assignment (SSA) numbering on the variables
-CONFIG_INTEGER(JitDoValueNumber, W("JitDoValueNumber"), 1) // Perform value numbering on method expressions
CONFIG_INTEGER(JitDoubleAlign, W("JitDoubleAlign"), 1)
CONFIG_INTEGER(JitDumpASCII, W("JitDumpASCII"), 1) // Uses only ASCII characters in tree dumps
CONFIG_INTEGER(JitDumpFgDot, W("JitDumpFgDot"), 0) // Set to non-zero to emit Dot instead of Xml Flowgraph dump
@@ -51,6 +48,9 @@ CONFIG_INTEGER(JitDumpToDebugger, W("JitDumpToDebugger"), 0) // Output JitDu
CONFIG_INTEGER(JitDumpVerboseSsa, W("JitDumpVerboseSsa"), 0) // Produce especially verbose dump output for SSA
CONFIG_INTEGER(JitDumpVerboseTrees, W("JitDumpVerboseTrees"), 0) // Enable more verbose tree dumps
CONFIG_INTEGER(JitEmitPrintRefRegs, W("JitEmitPrintRefRegs"), 0)
+CONFIG_INTEGER(JitEnableDevirtualization, W("JitEnableDevirtualization"), 1) // Enable devirtualization in importer
+CONFIG_INTEGER(JitEnableLateDevirtualization, W("JitEnableLateDevirtualization"), 1) // Enable devirtualization after
+ // inlining
CONFIG_INTEGER(JitExpensiveDebugCheckLevel, W("JitExpensiveDebugCheckLevel"), 0) // Level indicates how much checking
// beyond the default to do in debug
// builds (currently 1-2)
@@ -97,6 +97,7 @@ CONFIG_INTEGER(JitOrder, W("JitOrder"), 0)
CONFIG_INTEGER(JitPInvokeCheckEnabled, W("JITPInvokeCheckEnabled"), 0)
CONFIG_INTEGER(JitPInvokeEnabled, W("JITPInvokeEnabled"), 1)
CONFIG_INTEGER(JitPrintInlinedMethods, W("JitPrintInlinedMethods"), 0)
+CONFIG_INTEGER(JitPrintDevirtualizedMethods, W("JitPrintDevirtualizedMethods"), 0)
CONFIG_INTEGER(JitRequired, W("JITRequired"), -1)
CONFIG_INTEGER(JitRoundFloat, W("JITRoundFloat"), DEFAULT_ROUND_LEVEL)
CONFIG_INTEGER(JitSkipArrayBoundCheck, W("JitSkipArrayBoundCheck"), 0)
@@ -154,12 +155,10 @@ CONFIG_METHODSET(JitNoProcedureSplittingEH, W("JitNoProcedureSplittingEH")) // D
// exception handling
CONFIG_METHODSET(JitStressOnly, W("JitStressOnly")) // Internal Jit stress mode: stress only the specified method(s)
CONFIG_METHODSET(JitUnwindDump, W("JitUnwindDump")) // Dump the unwind codes for the method
-CONFIG_METHODSET(JitOptRepeat, W("JitOptRepeat")) // Runs optimizer multiple times on the method
-CONFIG_INTEGER(JitOptRepeatCount, W("JitOptRepeatCount"), 2) // Number of times to repeat opts when repeating
-CONFIG_METHODSET(NgenDisasm, W("NgenDisasm")) // Same as JitDisasm, but for ngen
-CONFIG_METHODSET(NgenDump, W("NgenDump")) // Same as JitDump, but for ngen
-CONFIG_METHODSET(NgenDumpIR, W("NgenDumpIR")) // Same as JitDumpIR, but for ngen
-CONFIG_METHODSET(NgenEHDump, W("NgenEHDump")) // Dump the EH table for the method, as reported to the VM
+CONFIG_METHODSET(NgenDisasm, W("NgenDisasm")) // Same as JitDisasm, but for ngen
+CONFIG_METHODSET(NgenDump, W("NgenDump")) // Same as JitDump, but for ngen
+CONFIG_METHODSET(NgenDumpIR, W("NgenDumpIR")) // Same as JitDumpIR, but for ngen
+CONFIG_METHODSET(NgenEHDump, W("NgenEHDump")) // Dump the EH table for the method, as reported to the VM
CONFIG_METHODSET(NgenGCDump, W("NgenGCDump"))
CONFIG_METHODSET(NgenUnwindDump, W("NgenUnwindDump")) // Dump the unwind codes for the method
CONFIG_STRING(JitDumpFg, W("JitDumpFg")) // Dumps Xml/Dot Flowgraph for specified method
@@ -219,6 +218,15 @@ CONFIG_INTEGER(JitEnableNoWayAssert, W("JitEnableNoWayAssert"), 0)
CONFIG_INTEGER(JitEnableNoWayAssert, W("JitEnableNoWayAssert"), 1)
#endif // !defined(DEBUG) && !defined(_DEBUG)
+#if !defined(JIT32_GCENCODER)
+#if defined(_TARGET_AMD64_) && defined(FEATURE_CORECLR)
+#define JitMinOptsTrackGCrefs_Default 0 // Not tracking GC refs in MinOpts is new behavior
+#else
+#define JitMinOptsTrackGCrefs_Default 1
+#endif
+CONFIG_INTEGER(JitMinOptsTrackGCrefs, W("JitMinOptsTrackGCrefs"), JitMinOptsTrackGCrefs_Default) // Track GC roots
+#endif // !defined(JIT32_GCENCODER)
+
// The following should be wrapped inside "#if MEASURE_MEM_ALLOC / #endif", but
// some files include this one without bringing in the definitions from "jit.h"
// so we don't always know what the "true" value of that flag should be. For now
@@ -236,6 +244,19 @@ CONFIG_INTEGER(JitInlineSIMDMultiplier, W("JitInlineSIMDMultiplier"), 3)
CONFIG_INTEGER(JitNoRngChks, W("JitNoRngChks"), 0) // If 1, don't generate range checks
#endif // defined(FEATURE_ENABLE_NO_RANGE_CHECKS)
+#if defined(OPT_CONFIG)
+CONFIG_INTEGER(JitDoAssertionProp, W("JitDoAssertionProp"), 1) // Perform assertion propagation optimization
+CONFIG_INTEGER(JitDoCopyProp, W("JitDoCopyProp"), 1) // Perform copy propagation on variables that appear redundant
+CONFIG_INTEGER(JitDoEarlyProp, W("JitDoEarlyProp"), 1) // Perform Early Value Propagataion
+CONFIG_INTEGER(JitDoLoopHoisting, W("JitDoLoopHoisting"), 1) // Perform loop hoisting on loop invariant values
+CONFIG_INTEGER(JitDoRangeAnalysis, W("JitDoRangeAnalysis"), 1) // Perform range check analysis
+CONFIG_INTEGER(JitDoSsa, W("JitDoSsa"), 1) // Perform Static Single Assignment (SSA) numbering on the variables
+CONFIG_INTEGER(JitDoValueNumber, W("JitDoValueNumber"), 1) // Perform value numbering on method expressions
+
+CONFIG_METHODSET(JitOptRepeat, W("JitOptRepeat")) // Runs optimizer multiple times on the method
+CONFIG_INTEGER(JitOptRepeatCount, W("JitOptRepeatCount"), 2) // Number of times to repeat opts when repeating
+#endif // defined(OPT_CONFIG)
+
CONFIG_INTEGER(JitRegisterFP, W("JitRegisterFP"), 3) // Control FP enregistration
CONFIG_INTEGER(JitTelemetry, W("JitTelemetry"), 1) // If non-zero, gather JIT telemetry data
CONFIG_INTEGER(JitVNMapSelBudget, W("JitVNMapSelBudget"), 100) // Max # of MapSelect's considered for a particular
@@ -250,6 +271,9 @@ CONFIG_STRING(AltJitExcludeAssemblies,
W("AltJitExcludeAssemblies")) // Do not use AltJit on this semicolon-delimited list of assemblies.
#endif // defined(ALT_JIT)
+CONFIG_INTEGER(JitMeasureIR, W("JitMeasureIR"), 0) // If set, measure the IR size after some phases and report it in
+ // the time log.
+
CONFIG_STRING(JitFuncInfoFile, W("JitFuncInfoLogFile")) // If set, gather JIT function info and write to this file.
CONFIG_STRING(JitTimeLogCsv, W("JitTimeLogCsv")) // If set, gather JIT throughput data and write to a CSV file. This
// mode must be used in internal retail builds.
diff --git a/src/jit/jitee.h b/src/jit/jitee.h
index f9bd83f5bb..7b0e4a02dc 100644
--- a/src/jit/jitee.h
+++ b/src/jit/jitee.h
@@ -78,6 +78,8 @@ public:
JIT_FLAG_USE_PINVOKE_HELPERS = 36, // The JIT should use the PINVOKE_{BEGIN,END} helpers instead of emitting inline transitions
JIT_FLAG_REVERSE_PINVOKE = 37, // The JIT should insert REVERSE_PINVOKE_{ENTER,EXIT} helpers into method prolog/epilog
JIT_FLAG_DESKTOP_QUIRKS = 38, // The JIT should generate desktop-quirk-compatible code
+ JIT_FLAG_TIER0 = 39, // This is the initial tier for tiered compilation which should generate code as quickly as possible
+ JIT_FLAG_TIER1 = 40, // This is the final tier (for now) for tiered compilation which should generate high quality code
};
// clang-format on
@@ -127,72 +129,6 @@ public:
return m_jitFlags == 0;
}
-#if COR_JIT_EE_VERSION <= 460
-
- void SetFromOldFlags(unsigned corJitFlags, unsigned corJitFlags2)
- {
- Reset();
-
-#define CONVERT_OLD_FLAG(oldf, newf) \
- if ((corJitFlags & (oldf)) != 0) \
- this->Set(JitFlags::newf);
-#define CONVERT_OLD_FLAG2(oldf, newf) \
- if ((corJitFlags2 & (oldf)) != 0) \
- this->Set(JitFlags::newf);
-
- CONVERT_OLD_FLAG(CORJIT_FLG_SPEED_OPT, JIT_FLAG_SPEED_OPT)
- CONVERT_OLD_FLAG(CORJIT_FLG_SIZE_OPT, JIT_FLAG_SIZE_OPT)
- CONVERT_OLD_FLAG(CORJIT_FLG_DEBUG_CODE, JIT_FLAG_DEBUG_CODE)
- CONVERT_OLD_FLAG(CORJIT_FLG_DEBUG_EnC, JIT_FLAG_DEBUG_EnC)
- CONVERT_OLD_FLAG(CORJIT_FLG_DEBUG_INFO, JIT_FLAG_DEBUG_INFO)
- CONVERT_OLD_FLAG(CORJIT_FLG_MIN_OPT, JIT_FLAG_MIN_OPT)
- CONVERT_OLD_FLAG(CORJIT_FLG_GCPOLL_CALLS, JIT_FLAG_GCPOLL_CALLS)
- CONVERT_OLD_FLAG(CORJIT_FLG_MCJIT_BACKGROUND, JIT_FLAG_MCJIT_BACKGROUND)
-
-#if defined(_TARGET_X86_)
-
- CONVERT_OLD_FLAG(CORJIT_FLG_PINVOKE_RESTORE_ESP, JIT_FLAG_PINVOKE_RESTORE_ESP)
- CONVERT_OLD_FLAG(CORJIT_FLG_TARGET_P4, JIT_FLAG_TARGET_P4)
- CONVERT_OLD_FLAG(CORJIT_FLG_USE_FCOMI, JIT_FLAG_USE_FCOMI)
- CONVERT_OLD_FLAG(CORJIT_FLG_USE_CMOV, JIT_FLAG_USE_CMOV)
- CONVERT_OLD_FLAG(CORJIT_FLG_USE_SSE2, JIT_FLAG_USE_SSE2)
-
-#elif defined(_TARGET_AMD64_)
-
- CONVERT_OLD_FLAG(CORJIT_FLG_USE_SSE3_4, JIT_FLAG_USE_SSE3_4)
- CONVERT_OLD_FLAG(CORJIT_FLG_USE_AVX, JIT_FLAG_USE_AVX)
- CONVERT_OLD_FLAG(CORJIT_FLG_USE_AVX2, JIT_FLAG_USE_AVX2)
- CONVERT_OLD_FLAG(CORJIT_FLG_USE_AVX_512, JIT_FLAG_USE_AVX_512)
- CONVERT_OLD_FLAG(CORJIT_FLG_FEATURE_SIMD, JIT_FLAG_FEATURE_SIMD)
-
-#endif // !defined(_TARGET_X86_) && !defined(_TARGET_AMD64_)
-
- CONVERT_OLD_FLAG(CORJIT_FLG_MAKEFINALCODE, JIT_FLAG_MAKEFINALCODE)
- CONVERT_OLD_FLAG(CORJIT_FLG_READYTORUN, JIT_FLAG_READYTORUN)
- CONVERT_OLD_FLAG(CORJIT_FLG_PROF_ENTERLEAVE, JIT_FLAG_PROF_ENTERLEAVE)
- CONVERT_OLD_FLAG(CORJIT_FLG_PROF_REJIT_NOPS, JIT_FLAG_PROF_REJIT_NOPS)
- CONVERT_OLD_FLAG(CORJIT_FLG_PROF_NO_PINVOKE_INLINE, JIT_FLAG_PROF_NO_PINVOKE_INLINE)
- CONVERT_OLD_FLAG(CORJIT_FLG_SKIP_VERIFICATION, JIT_FLAG_SKIP_VERIFICATION)
- CONVERT_OLD_FLAG(CORJIT_FLG_PREJIT, JIT_FLAG_PREJIT)
- CONVERT_OLD_FLAG(CORJIT_FLG_RELOC, JIT_FLAG_RELOC)
- CONVERT_OLD_FLAG(CORJIT_FLG_IMPORT_ONLY, JIT_FLAG_IMPORT_ONLY)
- CONVERT_OLD_FLAG(CORJIT_FLG_IL_STUB, JIT_FLAG_IL_STUB)
- CONVERT_OLD_FLAG(CORJIT_FLG_PROCSPLIT, JIT_FLAG_PROCSPLIT)
- CONVERT_OLD_FLAG(CORJIT_FLG_BBINSTR, JIT_FLAG_BBINSTR)
- CONVERT_OLD_FLAG(CORJIT_FLG_BBOPT, JIT_FLAG_BBOPT)
- CONVERT_OLD_FLAG(CORJIT_FLG_FRAMED, JIT_FLAG_FRAMED)
- CONVERT_OLD_FLAG(CORJIT_FLG_ALIGN_LOOPS, JIT_FLAG_ALIGN_LOOPS)
- CONVERT_OLD_FLAG(CORJIT_FLG_PUBLISH_SECRET_PARAM, JIT_FLAG_PUBLISH_SECRET_PARAM)
- CONVERT_OLD_FLAG(CORJIT_FLG_GCPOLL_INLINE, JIT_FLAG_GCPOLL_INLINE)
-
- CONVERT_OLD_FLAG2(CORJIT_FLG2_SAMPLING_JIT_BACKGROUND, JIT_FLAG_SAMPLING_JIT_BACKGROUND)
-
-#undef CONVERT_OLD_FLAG
-#undef CONVERT_OLD_FLAG2
- }
-
-#else // COR_JIT_EE_VERSION > 460
-
void SetFromFlags(CORJIT_FLAGS flags)
{
// We don't want to have to check every one, so we assume it is exactly the same values as the JitFlag
@@ -253,12 +189,12 @@ public:
FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_PINVOKE_HELPERS, JIT_FLAG_USE_PINVOKE_HELPERS);
FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_REVERSE_PINVOKE, JIT_FLAG_REVERSE_PINVOKE);
FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_DESKTOP_QUIRKS, JIT_FLAG_DESKTOP_QUIRKS);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_TIER0, JIT_FLAG_TIER0);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_TIER1, JIT_FLAG_TIER1);
#undef FLAGS_EQUAL
}
-#endif // COR_JIT_EE_VERSION > 460
-
private:
unsigned __int64 m_jitFlags;
};
diff --git a/src/jit/jitgcinfo.h b/src/jit/jitgcinfo.h
index 3f8d8afe88..7b17b84204 100644
--- a/src/jit/jitgcinfo.h
+++ b/src/jit/jitgcinfo.h
@@ -295,7 +295,11 @@ public:
// references, building up mappings from tuples of <reg/offset X byref/pinning> to the corresponding
// slot id (in the two member fields declared above). In the "do work" mode, we use these slot ids to
// actually declare live ranges to the encoder.
- void gcMakeRegPtrTable(GcInfoEncoder* gcInfoEncoder, unsigned codeSize, unsigned prologSize, MakeRegPtrMode mode);
+ void gcMakeRegPtrTable(GcInfoEncoder* gcInfoEncoder,
+ unsigned codeSize,
+ unsigned prologSize,
+ MakeRegPtrMode mode,
+ unsigned* callCntRef);
#endif
#ifdef JIT32_GCENCODER
diff --git a/src/jit/jitpch.h b/src/jit/jitpch.h
index 2e69e79208..1fe8f27302 100644
--- a/src/jit/jitpch.h
+++ b/src/jit/jitpch.h
@@ -15,10 +15,6 @@
#include <cstdlib>
#include <intrin.h>
-#if COR_JIT_EE_VERSION <= 460
-#include "corjithost.h"
-#include "jithost.h"
-#endif
#include "jitconfig.h"
#include "jit.h"
#include "iallocator.h"
diff --git a/src/jit/jitstd/type_traits.h b/src/jit/jitstd/type_traits.h
index 1e853e8cca..f0f8518c40 100644
--- a/src/jit/jitstd/type_traits.h
+++ b/src/jit/jitstd/type_traits.h
@@ -178,14 +178,15 @@ struct make_unsigned<int>
typedef unsigned int type;
};
-#ifndef PLATFORM_UNIX
+#ifndef _HOST_UNIX_
template<>
struct make_unsigned<long>
{
typedef unsigned long type;
};
-#endif // PLATFORM_UNIX
+
+#endif // !_HOST_UNIX_
template<>
struct make_unsigned<__int64>
diff --git a/src/jit/lclvars.cpp b/src/jit/lclvars.cpp
index b4e4cc6e55..5bcb1c8f77 100644
--- a/src/jit/lclvars.cpp
+++ b/src/jit/lclvars.cpp
@@ -38,6 +38,8 @@ void Compiler::lvaInit()
lvaRefCountingStarted = false;
lvaLocalVarRefCounted = false;
+ lvaGenericsContextUseCount = 0;
+
lvaSortAgain = false; // false: We don't need to call lvaSortOnly()
lvaTrackedFixed = false; // false: We can still add new tracked variables
@@ -50,6 +52,7 @@ void Compiler::lvaInit()
#if FEATURE_FIXED_OUT_ARGS
lvaPInvokeFrameRegSaveVar = BAD_VAR_NUM;
lvaOutgoingArgSpaceVar = BAD_VAR_NUM;
+ lvaOutgoingArgSpaceSize = PhasedVar<unsigned>();
#endif // FEATURE_FIXED_OUT_ARGS
#ifdef _TARGET_ARM_
lvaPromotedStructAssemblyScratchVar = BAD_VAR_NUM;
@@ -246,10 +249,17 @@ void Compiler::lvaInitTypeRef()
CORINFO_CLASS_HANDLE typeHnd;
CorInfoTypeWithMod corInfoType =
info.compCompHnd->getArgType(&info.compMethodInfo->locals, localsSig, &typeHnd);
+
lvaInitVarDsc(varDsc, varNum, strip(corInfoType), typeHnd, localsSig, &info.compMethodInfo->locals);
varDsc->lvPinned = ((corInfoType & CORINFO_TYPE_MOD_PINNED) != 0);
varDsc->lvOnFrame = true; // The final home for this local variable might be our local stack frame
+
+ if (strip(corInfoType) == CORINFO_TYPE_CLASS)
+ {
+ CORINFO_CLASS_HANDLE clsHnd = info.compCompHnd->getArgClass(&info.compMethodInfo->locals, localsSig);
+ lvaSetClass(varNum, clsHnd);
+ }
}
if ( // If there already exist unsafe buffers, don't mark more structs as unsafe
@@ -395,6 +405,7 @@ void Compiler::lvaInitThisPtr(InitVarDscInfo* varDscInfo)
else
{
varDsc->lvType = TYP_REF;
+ lvaSetClass(varDscInfo->varNum, info.compClassHnd);
}
if (tiVerificationNeeded)
@@ -549,6 +560,12 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo)
lvaInitVarDsc(varDsc, varDscInfo->varNum, strip(corInfoType), typeHnd, argLst, &info.compMethodInfo->args);
+ if (strip(corInfoType) == CORINFO_TYPE_CLASS)
+ {
+ CORINFO_CLASS_HANDLE clsHnd = info.compCompHnd->getArgClass(&info.compMethodInfo->args, argLst);
+ lvaSetClass(varDscInfo->varNum, clsHnd);
+ }
+
// For ARM, ARM64, and AMD64 varargs, all arguments go in integer registers
var_types argType = mangleVarArgsType(varDsc->TypeGet());
var_types origArgType = argType;
@@ -660,11 +677,6 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo)
codeGen->regSet.rsMaskPreSpillRegArg |= regMask;
}
}
- else
- {
- varDsc->lvOnFrame = true; // The final home for this incoming register might be our local stack frame
- }
-
#else // !_TARGET_ARM_
#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR structDesc;
@@ -706,13 +718,12 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo)
}
}
#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#endif // !_TARGET_ARM_
// The final home for this incoming register might be our local stack frame.
// For System V platforms the final home will always be on the local stack frame.
varDsc->lvOnFrame = true;
-#endif // !_TARGET_ARM_
-
bool canPassArgInRegisters = false;
#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
@@ -1522,15 +1533,8 @@ void Compiler::lvaCanPromoteStructType(CORINFO_CLASS_HANDLE typeHnd,
pFieldInfo->fldOffset = (BYTE)fldOffset;
pFieldInfo->fldOrdinal = ordinal;
CorInfoType corType = info.compCompHnd->getFieldType(pFieldInfo->fldHnd, &pFieldInfo->fldTypeHnd);
- var_types varType = JITtype2varType(corType);
- pFieldInfo->fldType = varType;
- unsigned size = genTypeSize(varType);
- pFieldInfo->fldSize = size;
-
- if (varTypeIsGC(varType))
- {
- containsGCpointers = true;
- }
+ pFieldInfo->fldType = JITtype2varType(corType);
+ pFieldInfo->fldSize = genTypeSize(pFieldInfo->fldType);
#ifdef FEATURE_SIMD
// Check to see if this is a SIMD type.
@@ -1542,8 +1546,7 @@ void Compiler::lvaCanPromoteStructType(CORINFO_CLASS_HANDLE typeHnd,
var_types simdBaseType = getBaseTypeAndSizeOfSIMDType(pFieldInfo->fldTypeHnd, &simdSize);
if (simdBaseType != TYP_UNKNOWN)
{
- varType = getSIMDTypeForSize(simdSize);
- pFieldInfo->fldType = varType;
+ pFieldInfo->fldType = getSIMDTypeForSize(simdSize);
pFieldInfo->fldSize = simdSize;
}
}
@@ -1551,8 +1554,60 @@ void Compiler::lvaCanPromoteStructType(CORINFO_CLASS_HANDLE typeHnd,
if (pFieldInfo->fldSize == 0)
{
- // Non-primitive struct field. Don't promote.
- return;
+ // Size of TYP_BLK, TYP_FUNC, TYP_VOID and TYP_STRUCT is zero.
+ // Early out if field type is other than TYP_STRUCT.
+ // This is a defensive check as we don't expect a struct to have
+ // fields of TYP_BLK, TYP_FUNC or TYP_VOID.
+ if (pFieldInfo->fldType != TYP_STRUCT)
+ {
+ return;
+ }
+
+ // Non-primitive struct field.
+ // Try to promote structs of single field of scalar types aligned at their
+ // natural boundary.
+
+ // Do Not promote if the struct field in turn has more than one field.
+ if (info.compCompHnd->getClassNumInstanceFields(pFieldInfo->fldTypeHnd) != 1)
+ {
+ return;
+ }
+
+ // Do not promote if the single field is not aligned at its natural boundary within
+ // the struct field.
+ CORINFO_FIELD_HANDLE fHnd = info.compCompHnd->getFieldInClass(pFieldInfo->fldTypeHnd, 0);
+ unsigned fOffset = info.compCompHnd->getFieldOffset(fHnd);
+ if (fOffset != 0)
+ {
+ return;
+ }
+
+ CORINFO_CLASS_HANDLE cHnd;
+ CorInfoType fieldCorType = info.compCompHnd->getFieldType(fHnd, &cHnd);
+ var_types fieldVarType = JITtype2varType(fieldCorType);
+ unsigned fieldSize = genTypeSize(fieldVarType);
+
+ // Do not promote if either not a primitive type or size equal to ptr size on
+ // target or a struct containing a single floating-point field.
+ //
+ // TODO-PERF: Structs containing a single floating-point field on Amd64
+ // needs to be passed in integer registers. Right now LSRA doesn't support
+ // passing of floating-point LCL_VARS in integer registers. Enabling promotion
+ // of such structs results in an assert in lsra right now.
+ //
+ // TODO-PERF: Right now promotion is confined to struct containing a ptr sized
+ // field (int/uint/ref/byref on 32-bits and long/ulong/ref/byref on 64-bits).
+ // Though this would serve the purpose of promoting Span<T> containing ByReference<T>,
+ // this can be extended to other primitive types as long as they are aligned at their
+ // natural boundary.
+ if (fieldSize == 0 || fieldSize != TARGET_POINTER_SIZE || varTypeIsFloating(fieldVarType))
+ {
+ return;
+ }
+
+ // Retype the field as the type of the single field of the struct
+ pFieldInfo->fldType = fieldVarType;
+ pFieldInfo->fldSize = fieldSize;
}
if ((pFieldInfo->fldOffset % pFieldInfo->fldSize) != 0)
@@ -1563,6 +1618,11 @@ void Compiler::lvaCanPromoteStructType(CORINFO_CLASS_HANDLE typeHnd,
return;
}
+ if (varTypeIsGC(pFieldInfo->fldType))
+ {
+ containsGCpointers = true;
+ }
+
// The end offset for this field should never be larger than our structSize.
noway_assert(fldOffset + pFieldInfo->fldSize <= structSize);
@@ -1657,7 +1717,6 @@ void Compiler::lvaCanPromoteStructVar(unsigned lclNum, lvaStructPromotionInfo* S
noway_assert(varTypeIsStruct(varDsc));
noway_assert(!varDsc->lvPromoted); // Don't ask again :)
-#ifdef FEATURE_SIMD
// If this lclVar is used in a SIMD intrinsic, then we don't want to struct promote it.
// Note, however, that SIMD lclVars that are NOT used in a SIMD intrinsic may be
// profitably promoted.
@@ -1667,24 +1726,134 @@ void Compiler::lvaCanPromoteStructVar(unsigned lclNum, lvaStructPromotionInfo* S
return;
}
-#endif
-
- // TODO-PERF - Allow struct promotion for HFA register arguments
-
// Explicitly check for HFA reg args and reject them for promotion here.
// Promoting HFA args will fire an assert in lvaAssignFrameOffsets
// when the HFA reg arg is struct promoted.
//
+ // TODO-PERF - Allow struct promotion for HFA register arguments
if (varDsc->lvIsHfaRegArg())
{
StructPromotionInfo->canPromote = false;
return;
}
+#if !FEATURE_MULTIREG_STRUCT_PROMOTE
+ if (varDsc->lvIsMultiRegArg)
+ {
+ JITDUMP("Skipping V%02u: marked lvIsMultiRegArg.\n", lclNum);
+ StructPromotionInfo->canPromote = false;
+ return;
+ }
+#endif
+
+ if (varDsc->lvIsMultiRegRet)
+ {
+ JITDUMP("Skipping V%02u: marked lvIsMultiRegRet.\n", lclNum);
+ StructPromotionInfo->canPromote = false;
+ return;
+ }
+
CORINFO_CLASS_HANDLE typeHnd = varDsc->lvVerTypeInfo.GetClassHandle();
lvaCanPromoteStructType(typeHnd, StructPromotionInfo, true);
}
+//--------------------------------------------------------------------------------------------
+// lvaShouldPromoteStructVar - Should a struct var be promoted if it can be promoted?
+// This routine mainly performs profitability checks. Right now it also has
+// some correctness checks due to limitations of down-stream phases.
+//
+// Arguments:
+// lclNum - Struct local number
+// structPromotionInfo - In Parameter; struct promotion information
+//
+// Returns
+// true if the struct should be promoted
+bool Compiler::lvaShouldPromoteStructVar(unsigned lclNum, lvaStructPromotionInfo* structPromotionInfo)
+{
+ assert(lclNum < lvaCount);
+ assert(structPromotionInfo->canPromote);
+
+ LclVarDsc* varDsc = &lvaTable[lclNum];
+ assert(varTypeIsStruct(varDsc));
+
+ bool shouldPromote = true;
+
+ // We *can* promote; *should* we promote?
+ // We should only do so if promotion has potential savings. One source of savings
+ // is if a field of the struct is accessed, since this access will be turned into
+ // an access of the corresponding promoted field variable. Even if there are no
+ // field accesses, but only block-level operations on the whole struct, if the struct
+ // has only one or two fields, then doing those block operations field-wise is probably faster
+ // than doing a whole-variable block operation (e.g., a hardware "copy loop" on x86).
+ // Struct promotion also provides the following benefits: reduce stack frame size,
+ // reduce the need for zero init of stack frame and fine grained constant/copy prop.
+ // Asm diffs indicate that promoting structs up to 3 fields is a net size win.
+ // So if no fields are accessed independently, and there are four or more fields,
+ // then do not promote.
+ //
+ // TODO: Ideally we would want to consider the impact of whether the struct is
+ // passed as a parameter or assigned the return value of a call. Because once promoted,
+ // struct copying is done by field by field assignment instead of a more efficient
+ // rep.stos or xmm reg based copy.
+ if (structPromotionInfo->fieldCnt > 3 && !varDsc->lvFieldAccessed)
+ {
+ JITDUMP("Not promoting promotable struct local V%02u: #fields = %d, fieldAccessed = %d.\n", lclNum,
+ structPromotionInfo->fieldCnt, varDsc->lvFieldAccessed);
+ shouldPromote = false;
+ }
+#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
+ // TODO-PERF - Only do this when the LclVar is used in an argument context
+ // TODO-ARM64 - HFA support should also eliminate the need for this.
+ // TODO-LSRA - Currently doesn't support the passing of floating point LCL_VARS in the integer registers
+ //
+ // For now we currently don't promote structs with a single float field
+ // Promoting it can cause us to shuffle it back and forth between the int and
+ // the float regs when it is used as a argument, which is very expensive for XARCH
+ //
+ else if ((structPromotionInfo->fieldCnt == 1) && varTypeIsFloating(structPromotionInfo->fields[0].fldType))
+ {
+ JITDUMP("Not promoting promotable struct local V%02u: #fields = %d because it is a struct with "
+ "single float field.\n",
+ lclNum, structPromotionInfo->fieldCnt);
+ shouldPromote = false;
+ }
+#endif // _TARGET_AMD64_ || _TARGET_ARM64_
+ else if (varDsc->lvIsParam)
+ {
+#if FEATURE_MULTIREG_STRUCT_PROMOTE
+ // Is this a variable holding a value with exactly two fields passed in
+ // multiple registers?
+ if ((structPromotionInfo->fieldCnt != 2) && lvaIsMultiregStruct(varDsc))
+ {
+ JITDUMP("Not promoting multireg struct local V%02u, because lvIsParam is true and #fields != 2\n", lclNum);
+ shouldPromote = false;
+ }
+ else
+#endif // !FEATURE_MULTIREG_STRUCT_PROMOTE
+
+ // TODO-PERF - Implement struct promotion for incoming multireg structs
+ // Currently it hits assert(lvFieldCnt==1) in lclvar.cpp line 4417
+
+ if (structPromotionInfo->fieldCnt != 1)
+ {
+ JITDUMP("Not promoting promotable struct local V%02u, because lvIsParam is true and #fields = "
+ "%d.\n",
+ lclNum, structPromotionInfo->fieldCnt);
+ shouldPromote = false;
+ }
+ }
+
+ //
+ // If the lvRefCnt is zero and we have a struct promoted parameter we can end up with an extra store of
+ // the the incoming register into the stack frame slot.
+ // In that case, we would like to avoid promortion.
+ // However we haven't yet computed the lvRefCnt values so we can't do that.
+ //
+ CLANG_FORMAT_COMMENT_ANCHOR;
+
+ return shouldPromote;
+}
+
/*****************************************************************************
* Promote a struct type local */
@@ -2123,6 +2292,199 @@ void Compiler::lvaSetStruct(unsigned varNum, CORINFO_CLASS_HANDLE typeHnd, bool
}
}
+//------------------------------------------------------------------------
+// lvaSetClass: set class information for a local var.
+//
+// Arguments:
+// varNum -- number of the variable
+// clsHnd -- class handle to use in set or update
+// isExact -- true if class is known exactly
+//
+// Notes:
+// varNum must not already have a ref class handle.
+
+void Compiler::lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact)
+{
+ noway_assert(varNum < lvaCount);
+
+ // If we are just importing, we cannot reliably track local ref types,
+ // since the jit maps CORINFO_TYPE_VAR to TYP_REF.
+ if (compIsForImportOnly())
+ {
+ return;
+ }
+
+ // Else we should have a type handle.
+ assert(clsHnd != nullptr);
+
+ LclVarDsc* varDsc = &lvaTable[varNum];
+ assert(varDsc->lvType == TYP_REF);
+
+ // We shoud not have any ref type information for this var.
+ assert(varDsc->lvClassHnd == nullptr);
+ assert(!varDsc->lvClassIsExact);
+
+ JITDUMP("\nlvaSetClass: setting class for V%02i to (%p) %s %s\n", varNum, clsHnd,
+ info.compCompHnd->getClassName(clsHnd), isExact ? " [exact]" : "");
+
+ varDsc->lvClassHnd = clsHnd;
+ varDsc->lvClassIsExact = isExact;
+}
+
+//------------------------------------------------------------------------
+// lvaSetClass: set class information for a local var from a tree or stack type
+//
+// Arguments:
+// varNum -- number of the variable. Must be a single def local
+// tree -- tree establishing the variable's value
+// stackHnd -- handle for the type from the evaluation stack
+//
+// Notes:
+// Preferentially uses the tree's type, when available. Since not all
+// tree kinds can track ref types, the stack type is used as a
+// fallback.
+
+void Compiler::lvaSetClass(unsigned varNum, GenTreePtr tree, CORINFO_CLASS_HANDLE stackHnd)
+{
+ bool isExact = false;
+ bool isNonNull = false;
+ CORINFO_CLASS_HANDLE clsHnd = gtGetClassHandle(tree, &isExact, &isNonNull);
+
+ if (clsHnd != nullptr)
+ {
+ lvaSetClass(varNum, clsHnd, isExact);
+ }
+ else if (stackHnd != nullptr)
+ {
+ lvaSetClass(varNum, stackHnd);
+ }
+}
+
+//------------------------------------------------------------------------
+// lvaUpdateClass: update class information for a local var.
+//
+// Arguments:
+// varNum -- number of the variable
+// clsHnd -- class handle to use in set or update
+// isExact -- true if class is known exactly
+//
+// Notes:
+//
+// This method models the type update rule for an assignment.
+//
+// Updates currently should only happen for single-def user args or
+// locals, when we are processing the expression actually being
+// used to initialize the local (or inlined arg). The update will
+// change the local from the declared type to the type of the
+// initial value.
+//
+// These updates should always *improve* what we know about the
+// type, that is making an inexact type exact, or changing a type
+// to some subtype. However the jit lacks precise type information
+// for shared code, so ensuring this is so is currently not
+// possible.
+
+void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact)
+{
+ noway_assert(varNum < lvaCount);
+
+ // If we are just importing, we cannot reliably track local ref types,
+ // since the jit maps CORINFO_TYPE_VAR to TYP_REF.
+ if (compIsForImportOnly())
+ {
+ return;
+ }
+
+ // Else we should have a class handle to consider
+ assert(clsHnd != nullptr);
+
+ LclVarDsc* varDsc = &lvaTable[varNum];
+ assert(varDsc->lvType == TYP_REF);
+
+ // We should already have a class
+ assert(varDsc->lvClassHnd != nullptr);
+
+#if defined(DEBUG)
+
+ // In general we only expect one update per local var. However if
+ // a block is re-imported and that block has the only STLOC for
+ // the var, we may see multiple updates. All subsequent updates
+ // should agree on the type, since reimportation is triggered by
+ // type mismatches for things other than ref types.
+ if (varDsc->lvClassInfoUpdated)
+ {
+ assert(varDsc->lvClassHnd == clsHnd);
+ assert(varDsc->lvClassIsExact == isExact);
+ }
+
+ // This counts as an update, even if nothing changes.
+ varDsc->lvClassInfoUpdated = true;
+
+#endif // defined(DEBUG)
+
+ // If previous type was exact, there is nothing to update. Would
+ // like to verify new type is compatible but can't do this yet.
+ if (varDsc->lvClassIsExact)
+ {
+ return;
+ }
+
+ // Are we updating the type?
+ if (varDsc->lvClassHnd != clsHnd)
+ {
+ JITDUMP("\nlvaUpdateClass: Updating class for V%02i from (%p) %s to (%p) %s %s\n", varNum, varDsc->lvClassHnd,
+ info.compCompHnd->getClassName(varDsc->lvClassHnd), clsHnd, info.compCompHnd->getClassName(clsHnd),
+ isExact ? " [exact]" : "");
+
+ varDsc->lvClassHnd = clsHnd;
+ varDsc->lvClassIsExact = isExact;
+ return;
+ }
+
+ // Class info matched. Are we updating exactness?
+ if (isExact)
+ {
+ JITDUMP("\nlvaUpdateClass: Updating class for V%02i (%p) %s to be exact\n", varNum, varDsc->lvClassHnd,
+ info.compCompHnd->getClassName(varDsc->lvClassHnd));
+
+ varDsc->lvClassIsExact = isExact;
+ return;
+ }
+
+ // Else we have the same handle and (in)exactness as before. Do nothing.
+ return;
+}
+
+//------------------------------------------------------------------------
+// lvaUpdateClass: Uupdate class information for a local var from a tree
+// or stack type
+//
+// Arguments:
+// varNum -- number of the variable. Must be a single def local
+// tree -- tree establishing the variable's value
+// stackHnd -- handle for the type from the evaluation stack
+//
+// Notes:
+// Preferentially uses the tree's type, when available. Since not all
+// tree kinds can track ref types, the stack type is used as a
+// fallback.
+
+void Compiler::lvaUpdateClass(unsigned varNum, GenTreePtr tree, CORINFO_CLASS_HANDLE stackHnd)
+{
+ bool isExact = false;
+ bool isNonNull = false;
+ CORINFO_CLASS_HANDLE clsHnd = gtGetClassHandle(tree, &isExact, &isNonNull);
+
+ if (clsHnd != nullptr)
+ {
+ lvaUpdateClass(varNum, clsHnd, isExact);
+ }
+ else if (stackHnd != nullptr)
+ {
+ lvaUpdateClass(varNum, stackHnd);
+ }
+}
+
/*****************************************************************************
* Returns the array of BYTEs containing the GC layout information
*/
@@ -2134,9 +2496,14 @@ BYTE* Compiler::lvaGetGcLayout(unsigned varNum)
return lvaTable[varNum].lvGcLayout;
}
-/*****************************************************************************
- * Return the number of bytes needed for a local variable
- */
+//------------------------------------------------------------------------
+// lvaLclSize: returns size of a local variable, in bytes
+//
+// Arguments:
+// varNum -- variable to query
+//
+// Returns:
+// Number of bytes needed on the frame for such a local.
unsigned Compiler::lvaLclSize(unsigned varNum)
{
@@ -2152,10 +2519,8 @@ unsigned Compiler::lvaLclSize(unsigned varNum)
case TYP_LCLBLK:
#if FEATURE_FIXED_OUT_ARGS
- noway_assert(lvaOutgoingArgSpaceSize >= 0);
noway_assert(varNum == lvaOutgoingArgSpaceVar);
return lvaOutgoingArgSpaceSize;
-
#else // FEATURE_FIXED_OUT_ARGS
assert(!"Unknown size");
NO_WAY("Target doesn't support TYP_LCLBLK");
@@ -2217,8 +2582,41 @@ unsigned Compiler::lvaLclExactSize(unsigned varNum)
return genTypeSize(varType);
}
+// getCalledCount -- get the value used to normalized weights for this method
+// if we don't have profile data then getCalledCount will return BB_UNITY_WEIGHT (100)
+// otherwise it returns the number of times that profile data says the method was called.
+//
+BasicBlock::weight_t BasicBlock::getCalledCount(Compiler* comp)
+{
+ // when we don't have profile data then fgCalledCount will be BB_UNITY_WEIGHT (100)
+ BasicBlock::weight_t calledCount = comp->fgCalledCount;
+
+ // If we haven't yet reach the place where we setup fgCalledCount it could still be zero
+ // so return a reasonable value to use until we set it.
+ //
+ if (calledCount == 0)
+ {
+ if (comp->fgIsUsingProfileWeights())
+ {
+ // When we use profile data block counts we have exact counts,
+ // not multiples of BB_UNITY_WEIGHT (100)
+ calledCount = 1;
+ }
+ else
+ {
+ calledCount = comp->fgFirstBB->bbWeight;
+
+ if (calledCount == 0)
+ {
+ calledCount = BB_UNITY_WEIGHT;
+ }
+ }
+ }
+ return calledCount;
+}
+
// getBBWeight -- get the normalized weight of this block
-unsigned BasicBlock::getBBWeight(Compiler* comp)
+BasicBlock::weight_t BasicBlock::getBBWeight(Compiler* comp)
{
if (this->bbWeight == 0)
{
@@ -2226,22 +2624,50 @@ unsigned BasicBlock::getBBWeight(Compiler* comp)
}
else
{
- unsigned calledWeight = comp->fgCalledWeight;
- if (calledWeight == 0)
- {
- calledWeight = comp->fgFirstBB->bbWeight;
- if (calledWeight == 0)
- {
- calledWeight = BB_UNITY_WEIGHT;
- }
- }
+ weight_t calledCount = getCalledCount(comp);
+
+ // Normalize the bbWeights by multiplying by BB_UNITY_WEIGHT and dividing by the calledCount.
+ //
+ // 1. For methods that do not have IBC data the called weight will always be 100 (BB_UNITY_WEIGHT)
+ // and the entry point bbWeight value is almost always 100 (BB_UNITY_WEIGHT)
+ // 2. For methods that do have IBC data the called weight is the actual number of calls
+ // from the IBC data and the entry point bbWeight value is almost always the actual
+ // number of calls from the IBC data.
+ //
+ // "almost always" - except for the rare case where a loop backedge jumps to BB01
+ //
+ // We also perform a rounding operation by adding half of the 'calledCount' before performing
+ // the division.
+ //
+ // Thus for both cases we will return 100 (BB_UNITY_WEIGHT) for the entry point BasicBlock
+ //
+ // Note that with a 100 (BB_UNITY_WEIGHT) values between 1 and 99 represent decimal fractions.
+ // (i.e. 33 represents 33% and 75 represents 75%, and values greater than 100 require
+ // some kind of loop backedge)
+ //
+
if (this->bbWeight < (BB_MAX_WEIGHT / BB_UNITY_WEIGHT))
{
- return max(1, (((this->bbWeight * BB_UNITY_WEIGHT) + (calledWeight / 2)) / calledWeight));
+ // Calculate the result using unsigned arithmetic
+ weight_t result = ((this->bbWeight * BB_UNITY_WEIGHT) + (calledCount / 2)) / calledCount;
+
+ // We don't allow a value of zero, as that would imply rarely run
+ return max(1, result);
}
else
{
- return (unsigned)((((double)this->bbWeight * (double)BB_UNITY_WEIGHT) / (double)calledWeight) + 0.5);
+ // Calculate the full result using floating point
+ double fullResult = ((double)this->bbWeight * (double)BB_UNITY_WEIGHT) / (double)calledCount;
+
+ if (fullResult < (double)BB_MAX_WEIGHT)
+ {
+ // Add 0.5 and truncate to unsigned
+ return (weight_t)(fullResult + 0.5);
+ }
+ else
+ {
+ return BB_MAX_WEIGHT;
+ }
}
}
}
@@ -2522,7 +2948,7 @@ int __cdecl Compiler::RefCntCmp(const void* op1, const void* op2)
}
if (varTypeIsGC(dsc2->TypeGet()))
{
- weight1 += BB_UNITY_WEIGHT / 2;
+ weight2 += BB_UNITY_WEIGHT / 2;
}
if (dsc2->lvRegister)
@@ -2859,6 +3285,10 @@ void Compiler::lvaSortByRefCount()
lvaSetVarDoNotEnregister(lclNum DEBUGARG(DNER_PinningRef));
#endif
}
+ else if (opts.MinOpts() && !JitConfig.JitMinOptsTrackGCrefs() && varTypeIsGC(varDsc->TypeGet()))
+ {
+ varDsc->lvTracked = 0;
+ }
// Are we not optimizing and we have exception handlers?
// if so mark all args and locals "do not enregister".
@@ -3192,23 +3622,9 @@ void Compiler::lvaMarkLclRefs(GenTreePtr tree)
}
#if ASSERTION_PROP
- /* Exclude the normal entry block */
- if (fgDomsComputed && (lvaMarkRefsCurBlock->bbNum != 1) && lvaMarkRefsCurBlock->bbIDom != nullptr)
+ if (fgDomsComputed && IsDominatedByExceptionalEntry(lvaMarkRefsCurBlock))
{
- // If any entry block except the normal entry block dominates the block, then mark the local with the
- // lvVolatileHint flag.
-
- if (BlockSetOps::MayBeUninit(lvaMarkRefsCurBlock->bbDoms))
- {
- // Lazy init (If a block is not dominated by any other block, we'll redo this every time, but it'll be fast)
- BlockSetOps::AssignNoCopy(this, lvaMarkRefsCurBlock->bbDoms, fgGetDominatorSet(lvaMarkRefsCurBlock));
- BlockSetOps::RemoveElemD(this, lvaMarkRefsCurBlock->bbDoms, fgFirstBB->bbNum);
- }
- assert(fgEnterBlksSetValid);
- if (!BlockSetOps::IsEmptyIntersection(this, lvaMarkRefsCurBlock->bbDoms, fgEnterBlks))
- {
- varDsc->lvVolatileHint = 1;
- }
+ SetVolatileHint(varDsc);
}
/* Record if the variable has a single def or not */
@@ -3293,6 +3709,29 @@ void Compiler::lvaMarkLclRefs(GenTreePtr tree)
#endif
}
+//------------------------------------------------------------------------
+// IsDominatedByExceptionalEntry: Check is the block dominated by an exception entry block.
+//
+// Arguments:
+// block - the checking block.
+//
+bool Compiler::IsDominatedByExceptionalEntry(BasicBlock* block)
+{
+ assert(fgDomsComputed);
+ return block->IsDominatedByExceptionalEntryFlag();
+}
+
+//------------------------------------------------------------------------
+// SetVolatileHint: Set a local var's volatile hint.
+//
+// Arguments:
+// varDsc - the local variable that needs the hint.
+//
+void Compiler::SetVolatileHint(LclVarDsc* varDsc)
+{
+ varDsc->lvVolatileHint = true;
+}
+
/*****************************************************************************
*
* Helper passed to Compiler::fgWalkTreePre() to do variable ref marking.
@@ -3381,7 +3820,7 @@ void Compiler::lvaMarkLocalVars()
}
}
- lvaAllocOutgoingArgSpace();
+ lvaAllocOutgoingArgSpaceVar();
#if !FEATURE_EH_FUNCLETS
@@ -3516,7 +3955,7 @@ void Compiler::lvaMarkLocalVars()
lvaSortByRefCount();
}
-void Compiler::lvaAllocOutgoingArgSpace()
+void Compiler::lvaAllocOutgoingArgSpaceVar()
{
#if FEATURE_FIXED_OUT_ARGS
@@ -3532,21 +3971,6 @@ void Compiler::lvaAllocOutgoingArgSpace()
lvaTable[lvaOutgoingArgSpaceVar].lvRefCnt = 1;
lvaTable[lvaOutgoingArgSpaceVar].lvRefCntWtd = BB_UNITY_WEIGHT;
-
- if (lvaOutgoingArgSpaceSize == 0)
- {
- if (compUsesThrowHelper || compIsProfilerHookNeeded())
- {
- // Need to make sure the MIN_ARG_AREA_FOR_CALL space is added to the frame if:
- // 1. there are calls to THROW_HEPLPER methods.
- // 2. we are generating profiling Enter/Leave/TailCall hooks. This will ensure
- // that even methods without any calls will have outgoing arg area space allocated.
- //
- // An example for these two cases is Windows Amd64, where the ABI requires to have 4 slots for
- // the outgoing arg space if the method makes any calls.
- lvaOutgoingArgSpaceSize = MIN_ARG_AREA_FOR_CALL;
- }
- }
}
noway_assert(lvaOutgoingArgSpaceVar >= info.compLocalsCount && lvaOutgoingArgSpaceVar < lvaCount);
@@ -5799,10 +6223,14 @@ void Compiler::lvaAlignFrame()
}
// Align the stack with STACK_ALIGN value.
- int adjustFrameSize = compLclFrameSize;
+ int adjustFrameSize = compLclFrameSize;
#if defined(UNIX_X86_ABI)
+ bool isEbpPushed = codeGen->isFramePointerUsed();
+#if DOUBLE_ALIGN
+ isEbpPushed |= genDoubleAlign();
+#endif
// we need to consider spilled register(s) plus return address and/or EBP
- int adjustCount = compCalleeRegsPushed + 1 + (codeGen->isFramePointerUsed() ? 1 : 0);
+ int adjustCount = compCalleeRegsPushed + 1 + (isEbpPushed ? 1 : 0);
adjustFrameSize += (adjustCount * REGSIZE_BYTES) % STACK_ALIGN;
#endif
if ((adjustFrameSize % STACK_ALIGN) != 0)
@@ -5832,11 +6260,15 @@ void Compiler::lvaAssignFrameOffsetsToPromotedStructs()
//
if (varDsc->lvIsStructField
#ifndef UNIX_AMD64_ABI
+#if !defined(_TARGET_ARM_) || defined(LEGACY_BACKEND)
+ // Non-legacy ARM: lo/hi parts of a promoted long arg need to be updated.
+
// For System V platforms there is no outgoing args space.
// A register passed struct arg is homed on the stack in a separate local var.
// The offset of these structs is already calculated in lvaAssignVirtualFrameOffsetToArg methos.
// Make sure the code below is not executed for these structs and the offset is not changed.
&& !varDsc->lvIsParam
+#endif // !defined(_TARGET_ARM_) || defined(LEGACY_BACKEND)
#endif // UNIX_AMD64_ABI
)
{
@@ -6256,6 +6688,14 @@ void Compiler::lvaDumpEntry(unsigned lclNum, FrameLayoutState curState, size_t r
{
printf(" stack-byref");
}
+ if (varDsc->lvClassHnd != nullptr)
+ {
+ printf(" class-hnd");
+ }
+ if (varDsc->lvClassIsExact)
+ {
+ printf(" exact");
+ }
#ifndef _TARGET_64BIT_
if (varDsc->lvStructDoubleAlign)
printf(" double-align");
diff --git a/src/jit/legacyjit/CMakeLists.txt b/src/jit/legacyjit/CMakeLists.txt
deleted file mode 100644
index 73a4600a66..0000000000
--- a/src/jit/legacyjit/CMakeLists.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-project(legacyjit)
-
-add_definitions(-DLEGACY_BACKEND)
-add_definitions(-DALT_JIT)
-add_definitions(-DFEATURE_NO_HOST)
-add_definitions(-DSELF_NO_HOST)
-add_definitions(-DFEATURE_READYTORUN_COMPILER)
-remove_definitions(-DFEATURE_MERGE_JIT_AND_ENGINE)
-
-# No SIMD in legacy back-end.
-remove_definitions(-DFEATURE_SIMD)
-remove_definitions(-DFEATURE_AVX_SUPPORT)
-
-if(WIN32)
- add_definitions(-DFX_VER_INTERNALNAME_STR=legacyjit.dll)
-endif(WIN32)
-
-add_library_clr(legacyjit
- SHARED
- ${SHARED_LIB_SOURCES}
-)
-
-add_dependencies(legacyjit jit_exports)
-
-set_property(TARGET legacyjit APPEND_STRING PROPERTY LINK_FLAGS ${JIT_EXPORTS_LINKER_OPTION})
-set_property(TARGET legacyjit APPEND_STRING PROPERTY LINK_DEPENDS ${JIT_EXPORTS_FILE})
-
-set(RYUJIT_LINK_LIBRARIES
- utilcodestaticnohost
- gcinfo
-)
-
-if(CLR_CMAKE_PLATFORM_UNIX)
- list(APPEND RYUJIT_LINK_LIBRARIES
- mscorrc_debug
- coreclrpal
- palrt
- )
-else()
- list(APPEND RYUJIT_LINK_LIBRARIES
- ${STATIC_MT_CRT_LIB}
- ${STATIC_MT_VCRT_LIB}
- kernel32.lib
- advapi32.lib
- ole32.lib
- oleaut32.lib
- uuid.lib
- user32.lib
- version.lib
- shlwapi.lib
- bcrypt.lib
- crypt32.lib
- RuntimeObject.lib
- )
-endif(CLR_CMAKE_PLATFORM_UNIX)
-
-target_link_libraries(legacyjit
- ${RYUJIT_LINK_LIBRARIES}
-)
-
-# add the install targets
-install_clr(legacyjit)
diff --git a/src/ToolBox/PdbTypeMatch/.gitmirror b/src/jit/legacynonjit/.gitmirror
index f507630f94..f507630f94 100644
--- a/src/ToolBox/PdbTypeMatch/.gitmirror
+++ b/src/jit/legacynonjit/.gitmirror
diff --git a/src/jit/legacynonjit/CMakeLists.txt b/src/jit/legacynonjit/CMakeLists.txt
new file mode 100644
index 0000000000..de66d81e8e
--- /dev/null
+++ b/src/jit/legacynonjit/CMakeLists.txt
@@ -0,0 +1,67 @@
+project(legacynonjit)
+
+add_definitions(-DALT_JIT)
+add_definitions(-DFEATURE_NO_HOST)
+add_definitions(-DSELF_NO_HOST)
+add_definitions(-DFEATURE_READYTORUN_COMPILER)
+remove_definitions(-DFEATURE_MERGE_JIT_AND_ENGINE)
+
+remove_definitions(-DFEATURE_SIMD)
+remove_definitions(-DFEATURE_AVX_SUPPORT)
+
+add_definitions(-DLEGACY_BACKEND)
+
+remove_definitions(-D_TARGET_X86_=1)
+add_definitions(-D_TARGET_ARM_)
+set(JIT_ARCH_ALTJIT_SOURCES ${JIT_ARM_SOURCES})
+
+if(WIN32)
+ add_definitions(-DFX_VER_INTERNALNAME_STR=legacynonjit.dll)
+endif(WIN32)
+
+add_library_clr(legacynonjit
+ SHARED
+ ${SHARED_LIB_SOURCES}
+ ${JIT_ARCH_ALTJIT_SOURCES}
+)
+
+add_dependencies(legacynonjit jit_exports)
+
+set_property(TARGET legacynonjit APPEND_STRING PROPERTY LINK_FLAGS ${JIT_EXPORTS_LINKER_OPTION})
+set_property(TARGET legacynonjit APPEND_STRING PROPERTY LINK_DEPENDS ${JIT_EXPORTS_FILE})
+
+set(RYUJIT_LINK_LIBRARIES
+ utilcodestaticnohost
+ gcinfo
+)
+
+if(CLR_CMAKE_PLATFORM_UNIX)
+ list(APPEND RYUJIT_LINK_LIBRARIES
+ mscorrc_debug
+ coreclrpal
+ palrt
+ )
+else()
+ list(APPEND RYUJIT_LINK_LIBRARIES
+ ${STATIC_MT_CRT_LIB}
+ ${STATIC_MT_VCRT_LIB}
+ kernel32.lib
+ advapi32.lib
+ ole32.lib
+ oleaut32.lib
+ uuid.lib
+ user32.lib
+ version.lib
+ shlwapi.lib
+ bcrypt.lib
+ crypt32.lib
+ RuntimeObject.lib
+ )
+endif(CLR_CMAKE_PLATFORM_UNIX)
+
+target_link_libraries(legacynonjit
+ ${RYUJIT_LINK_LIBRARIES}
+)
+
+# add the install targets
+install_clr(legacynonjit)
diff --git a/src/jit/legacynonjit/legacynonjit.def b/src/jit/legacynonjit/legacynonjit.def
new file mode 100644
index 0000000000..1603af74ca
--- /dev/null
+++ b/src/jit/legacynonjit/legacynonjit.def
@@ -0,0 +1,7 @@
+; 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.
+EXPORTS
+ getJit
+ jitStartup
+ sxsJitStartup
diff --git a/src/jit/linuxnonjit/CMakeLists.txt b/src/jit/linuxnonjit/CMakeLists.txt
new file mode 100644
index 0000000000..87ec1e45c9
--- /dev/null
+++ b/src/jit/linuxnonjit/CMakeLists.txt
@@ -0,0 +1,71 @@
+project(linuxnonjit)
+
+add_definitions(-DALT_JIT)
+add_definitions(-DFEATURE_NO_HOST)
+add_definitions(-DSELF_NO_HOST)
+add_definitions(-DFEATURE_READYTORUN_COMPILER)
+remove_definitions(-DFEATURE_MERGE_JIT_AND_ENGINE)
+
+if (CLR_CMAKE_PLATFORM_ARCH_I386)
+ remove_definitions(-DFEATURE_SIMD)
+ remove_definitions(-DFEATURE_AVX_SUPPORT)
+ add_definitions(-DUNIX_X86_ABI)
+ set(JIT_ARCH_ALTJIT_SOURCES ${JIT_I386_SOURCES})
+elseif(CLR_CMAKE_PLATFORM_ARCH_AMD64)
+ add_definitions(-DUNIX_AMD64_ABI)
+ add_definitions(-DFEATURE_UNIX_AMD64_STRUCT_PASSING)
+ set(JIT_ARCH_ALTJIT_SOURCES ${JIT_AMD64_SOURCES})
+else()
+ clr_unknown_arch()
+endif()
+
+if(WIN32)
+ add_definitions(-DFX_VER_INTERNALNAME_STR=linuxnonjit.dll)
+endif(WIN32)
+
+add_library_clr(linuxnonjit
+ SHARED
+ ${SHARED_LIB_SOURCES}
+ ${JIT_ARCH_ALTJIT_SOURCES}
+)
+
+add_dependencies(linuxnonjit jit_exports)
+
+set_property(TARGET linuxnonjit APPEND_STRING PROPERTY LINK_FLAGS ${JIT_EXPORTS_LINKER_OPTION})
+set_property(TARGET linuxnonjit APPEND_STRING PROPERTY LINK_DEPENDS ${JIT_EXPORTS_FILE})
+
+set(RYUJIT_LINK_LIBRARIES
+ utilcodestaticnohost
+ gcinfo
+)
+
+if(CLR_CMAKE_PLATFORM_UNIX)
+ list(APPEND RYUJIT_LINK_LIBRARIES
+ mscorrc_debug
+ coreclrpal
+ palrt
+ )
+else()
+ list(APPEND RYUJIT_LINK_LIBRARIES
+ ${STATIC_MT_CRT_LIB}
+ ${STATIC_MT_VCRT_LIB}
+ kernel32.lib
+ advapi32.lib
+ ole32.lib
+ oleaut32.lib
+ uuid.lib
+ user32.lib
+ version.lib
+ shlwapi.lib
+ bcrypt.lib
+ crypt32.lib
+ RuntimeObject.lib
+ )
+endif(CLR_CMAKE_PLATFORM_UNIX)
+
+target_link_libraries(linuxnonjit
+ ${RYUJIT_LINK_LIBRARIES}
+)
+
+# add the install targets
+install_clr(linuxnonjit)
diff --git a/src/jit/liveness.cpp b/src/jit/liveness.cpp
index c6663185e4..47950aee63 100644
--- a/src/jit/liveness.cpp
+++ b/src/jit/liveness.cpp
@@ -1189,9 +1189,7 @@ class LiveVarAnalysis
}
/* Compute the 'm_liveIn' set */
- VarSetOps::Assign(m_compiler, m_liveIn, m_liveOut);
- VarSetOps::DiffD(m_compiler, m_liveIn, block->bbVarDef);
- VarSetOps::UnionD(m_compiler, m_liveIn, block->bbVarUse);
+ VarSetOps::LivenessD(m_compiler, m_liveIn, block->bbVarDef, block->bbVarUse, m_liveOut);
// Even if block->bbMemoryDef is set, we must assume that it doesn't kill memory liveness from m_memoryLiveOut,
// since (without proof otherwise) the use and def may touch different memory at run-time.
@@ -1218,12 +1216,8 @@ class LiveVarAnalysis
noway_assert(block->bbFlags & BBF_INTERNAL);
- liveInChanged =
- !VarSetOps::Equal(m_compiler, VarSetOps::Intersection(m_compiler, block->bbLiveIn, m_liveIn),
- m_liveIn);
- if (liveInChanged ||
- !VarSetOps::Equal(m_compiler, VarSetOps::Intersection(m_compiler, block->bbLiveOut, m_liveOut),
- m_liveOut))
+ liveInChanged = !VarSetOps::IsSubset(m_compiler, m_liveIn, block->bbLiveIn);
+ if (liveInChanged || !VarSetOps::IsSubset(m_compiler, m_liveOut, block->bbLiveOut))
{
#ifdef DEBUG
if (m_compiler->verbose)
@@ -1834,7 +1828,7 @@ VARSET_VALRET_TP Compiler::fgComputeLife(VARSET_VALARG_TP lifeArg,
VARSET_TP VARSET_INIT(this, keepAliveVars, volatileVars);
VarSetOps::UnionD(this, keepAliveVars, compCurBB->bbScope); // Don't kill vars in scope
- noway_assert(VarSetOps::Equal(this, VarSetOps::Intersection(this, keepAliveVars, life), keepAliveVars));
+ noway_assert(VarSetOps::IsSubset(this, keepAliveVars, life));
noway_assert(compCurStmt->gtOper == GT_STMT);
noway_assert(endNode || (startNode == compCurStmt->gtStmt.gtStmtExpr));
@@ -1882,7 +1876,7 @@ VARSET_VALRET_TP Compiler::fgComputeLifeLIR(VARSET_VALARG_TP lifeArg, BasicBlock
VARSET_TP VARSET_INIT(this, keepAliveVars, volatileVars);
VarSetOps::UnionD(this, keepAliveVars, block->bbScope); // Don't kill vars in scope
- noway_assert(VarSetOps::Equal(this, VarSetOps::Intersection(this, keepAliveVars, life), keepAliveVars));
+ noway_assert(VarSetOps::IsSubset(this, keepAliveVars, life));
LIR::Range& blockRange = LIR::AsRange(block);
GenTree* firstNonPhiNode = blockRange.FirstNonPhiNode();
@@ -2997,7 +2991,7 @@ void Compiler::fgInterBlockLocalVarLiveness()
// which may expose more dead stores.
fgLocalVarLivenessChanged = true;
- noway_assert(VarSetOps::Equal(this, VarSetOps::Intersection(this, life, block->bbLiveIn), life));
+ noway_assert(VarSetOps::IsSubset(this, life, block->bbLiveIn));
/* set the new bbLiveIn */
diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp
index 0316a34a21..035f0947c2 100644
--- a/src/jit/lower.cpp
+++ b/src/jit/lower.cpp
@@ -42,9 +42,12 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
void Lowering::MakeSrcContained(GenTreePtr parentNode, GenTreePtr childNode)
{
assert(!parentNode->OperIsLeaf());
+ assert(childNode->canBeContained());
+
int srcCount = childNode->gtLsraInfo.srcCount;
assert(srcCount >= 0);
m_lsra->clearOperandCounts(childNode);
+
assert(parentNode->gtLsraInfo.srcCount > 0);
parentNode->gtLsraInfo.srcCount += srcCount - 1;
}
@@ -465,7 +468,7 @@ GenTree* Lowering::LowerSwitch(GenTree* node)
// both GT_SWITCH lowering code paths.
// This condition is of the form: if (temp > jumpTableLength - 2){ goto jumpTable[jumpTableLength - 1]; }
GenTreePtr gtDefaultCaseCond = comp->gtNewOperNode(GT_GT, TYP_INT, comp->gtNewLclvNode(tempLclNum, tempLclType),
- comp->gtNewIconNode(jumpCnt - 2, TYP_INT));
+ comp->gtNewIconNode(jumpCnt - 2, tempLclType));
// Make sure we perform an unsigned comparison, just in case the switch index in 'temp'
// is now less than zero 0 (that would also hit the default case).
@@ -678,9 +681,16 @@ GenTree* Lowering::LowerSwitch(GenTree* node)
JITDUMP("Lowering switch BB%02u: using jump table expansion\n", originalSwitchBB->bbNum);
+ GenTree* switchValue = comp->gtNewLclvNode(tempLclNum, tempLclType);
+#ifdef _TARGET_64BIT_
+ if (tempLclType != TYP_I_IMPL)
+ {
+ // Note that the switch value is unsigned so the cast should be unsigned as well.
+ switchValue = comp->gtNewCastNode(TYP_I_IMPL, switchValue, TYP_U_IMPL);
+ }
+#endif
GenTreePtr gtTableSwitch =
- comp->gtNewOperNode(GT_SWITCH_TABLE, TYP_VOID, comp->gtNewLclvNode(tempLclNum, tempLclType),
- comp->gtNewJmpTableNode());
+ comp->gtNewOperNode(GT_SWITCH_TABLE, TYP_VOID, switchValue, comp->gtNewJmpTableNode());
/* Increment the lvRefCnt and lvRefCntWtd for temp */
tempVarDsc->incRefCnts(blockWeight, comp);
@@ -930,23 +940,11 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
// This provides the info to put this argument in in-coming arg area slot
// instead of in out-going arg area slot.
- PUT_STRUCT_ARG_STK_ONLY(assert(info->isStruct == varTypeIsStruct(type))); // Make sure state is
- // correct
+ PUT_STRUCT_ARG_STK_ONLY(assert(info->isStruct == varTypeIsStruct(type))); // Make sure state is correct
-#if FEATURE_FASTTAILCALL
putArg = new (comp, GT_PUTARG_STK)
GenTreePutArgStk(GT_PUTARG_STK, type, arg, info->slotNum PUT_STRUCT_ARG_STK_ONLY_ARG(info->numSlots),
- call->IsFastTailCall() DEBUGARG(call));
-#else
- putArg = new (comp, GT_PUTARG_STK)
- GenTreePutArgStk(GT_PUTARG_STK, type, arg,
- info->slotNum PUT_STRUCT_ARG_STK_ONLY_ARG(info->numSlots) DEBUGARG(call));
-#endif
-
-#if defined(UNIX_X86_ABI)
- assert((info->padStkAlign > 0 && info->numSlots > 0) || (info->padStkAlign == 0));
- putArg->AsPutArgStk()->setArgPadding(info->padStkAlign);
-#endif
+ call->IsFastTailCall(), call);
#ifdef FEATURE_PUT_STRUCT_ARG_STK
// If the ArgTabEntry indicates that this arg is a struct
@@ -971,6 +969,43 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
assert(!varTypeIsSIMD(arg));
numRefs = comp->info.compCompHnd->getClassGClayout(arg->gtObj.gtClass, gcLayout);
putArg->AsPutArgStk()->setGcPointers(numRefs, gcLayout);
+
+#ifdef _TARGET_X86_
+ // On x86 VM lies about the type of a struct containing a pointer sized
+ // integer field by returning the type of its field as the type of struct.
+ // Such struct can be passed in a register depending its position in
+ // parameter list. VM does this unwrapping only one level and therefore
+ // a type like Struct Foo { Struct Bar { int f}} awlays needs to be
+ // passed on stack. Also, VM doesn't lie about type of such a struct
+ // when it is a field of another struct. That is VM doesn't lie about
+ // the type of Foo.Bar
+ //
+ // We now support the promotion of fields that are of type struct.
+ // However we only support a limited case where the struct field has a
+ // single field and that single field must be a scalar type. Say Foo.Bar
+ // field is getting passed as a parameter to a call, Since it is a TYP_STRUCT,
+ // as per x86 ABI it should always be passed on stack. Therefore GenTree
+ // node under a PUTARG_STK could be GT_OBJ(GT_LCL_VAR_ADDR(v1)), where
+ // local v1 could be a promoted field standing for Foo.Bar. Note that
+ // the type of v1 will be the type of field of Foo.Bar.f when Foo is
+ // promoted. That is v1 will be a scalar type. In this case we need to
+ // pass v1 on stack instead of in a register.
+ //
+ // TODO-PERF: replace GT_OBJ(GT_LCL_VAR_ADDR(v1)) with v1 if v1 is
+ // a scalar type and the width of GT_OBJ matches the type size of v1.
+ // Note that this cannot be done till call node arguments are morphed
+ // because we should not lose the fact that the type of argument is
+ // a struct so that the arg gets correctly marked to be passed on stack.
+ GenTree* objOp1 = arg->gtGetOp1();
+ if (objOp1->OperGet() == GT_LCL_VAR_ADDR)
+ {
+ unsigned lclNum = objOp1->AsLclVarCommon()->GetLclNum();
+ if (comp->lvaTable[lclNum].lvType != TYP_STRUCT)
+ {
+ comp->lvaSetVarDoNotEnregister(lclNum DEBUGARG(Compiler::DNER_VMNeedsStackAddr));
+ }
+ }
+#endif // _TARGET_X86_
}
}
#endif // FEATURE_PUT_STRUCT_ARG_STK
@@ -1062,6 +1097,15 @@ void Lowering::LowerArg(GenTreeCall* call, GenTreePtr* ppArg)
LclVarDsc* varDsc = &comp->lvaTable[varNum];
type = varDsc->lvType;
}
+ else if (arg->OperGet() == GT_SIMD)
+ {
+ assert((arg->AsSIMD()->gtSIMDSize == 16) || (arg->AsSIMD()->gtSIMDSize == 12));
+
+ if (arg->AsSIMD()->gtSIMDSize == 12)
+ {
+ type = TYP_SIMD12;
+ }
+ }
}
#endif // defined(FEATURE_SIMD) && defined(_TARGET_X86_)
@@ -1075,25 +1119,41 @@ void Lowering::LowerArg(GenTreeCall* call, GenTreePtr* ppArg)
{
if (isReg)
{
- NYI("Lowering of long register argument");
- }
+ noway_assert(arg->OperGet() == GT_LONG);
+ assert(info->numRegs == 2);
+
+ GenTreePtr argLo = arg->gtGetOp1();
+ GenTreePtr argHi = arg->gtGetOp2();
+
+ GenTreeFieldList* fieldList = new (comp, GT_FIELD_LIST) GenTreeFieldList(argLo, 0, TYP_INT, nullptr);
+ (void)new (comp, GT_FIELD_LIST) GenTreeFieldList(argHi, 4, TYP_INT, fieldList);
- // For longs, we will replace the GT_LONG with a GT_FIELD_LIST, and put that under a PUTARG_STK.
- // Although the hi argument needs to be pushed first, that will be handled by the general case,
- // in which the fields will be reversed.
- noway_assert(arg->OperGet() == GT_LONG);
- assert(info->numSlots == 2);
- GenTreePtr argLo = arg->gtGetOp1();
- GenTreePtr argHi = arg->gtGetOp2();
- GenTreeFieldList* fieldList = new (comp, GT_FIELD_LIST) GenTreeFieldList(argLo, 0, TYP_INT, nullptr);
- // Only the first fieldList node (GTF_FIELD_LIST_HEAD) is in the instruction sequence.
- (void)new (comp, GT_FIELD_LIST) GenTreeFieldList(argHi, 4, TYP_INT, fieldList);
- putArg = NewPutArg(call, fieldList, info, TYP_VOID);
-
- // We can't call ReplaceArgWithPutArgOrCopy here because it presumes that we are keeping the original arg.
- BlockRange().InsertBefore(arg, fieldList, putArg);
- BlockRange().Remove(arg);
- *ppArg = putArg;
+ putArg = NewPutArg(call, fieldList, info, TYP_VOID);
+
+ BlockRange().InsertBefore(arg, putArg);
+ BlockRange().Remove(arg);
+ *ppArg = fieldList;
+ info->node = fieldList;
+ }
+ else
+ {
+ // For longs, we will replace the GT_LONG with a GT_FIELD_LIST, and put that under a PUTARG_STK.
+ // Although the hi argument needs to be pushed first, that will be handled by the general case,
+ // in which the fields will be reversed.
+ noway_assert(arg->OperGet() == GT_LONG);
+ assert(info->numSlots == 2);
+ GenTreePtr argLo = arg->gtGetOp1();
+ GenTreePtr argHi = arg->gtGetOp2();
+ GenTreeFieldList* fieldList = new (comp, GT_FIELD_LIST) GenTreeFieldList(argLo, 0, TYP_INT, nullptr);
+ // Only the first fieldList node (GTF_FIELD_LIST_HEAD) is in the instruction sequence.
+ (void)new (comp, GT_FIELD_LIST) GenTreeFieldList(argHi, 4, TYP_INT, fieldList);
+ putArg = NewPutArg(call, fieldList, info, TYP_VOID);
+
+ // We can't call ReplaceArgWithPutArgOrCopy here because it presumes that we are keeping the original arg.
+ BlockRange().InsertBefore(arg, fieldList, putArg);
+ BlockRange().Remove(arg);
+ *ppArg = putArg;
+ }
}
else
#endif // !defined(_TARGET_64BIT_)
@@ -1187,9 +1247,6 @@ void Lowering::LowerCall(GenTree* node)
LowerArgsForCall(call);
-// RyuJIT arm is not set up for lowered call control
-#ifndef _TARGET_ARM_
-
// note that everything generated from this point on runs AFTER the outgoing args are placed
GenTree* result = nullptr;
@@ -1294,7 +1351,6 @@ void Lowering::LowerCall(GenTree* node)
call->gtControlExpr = result;
}
-#endif //!_TARGET_ARM_
if (comp->opts.IsJit64Compat())
{
@@ -2196,7 +2252,6 @@ void Lowering::LowerCompare(GenTree* cmp)
// automatically inserts a cast from int32 to long on 64 bit architectures. However, the JIT
// accidentally generates int/long comparisons internally:
// - loop cloning compares int (and even small int) index limits against long constants
- // - switch lowering compares a 64 bit switch value against a int32 constant
//
// TODO-Cleanup: The above mentioned issues should be fixed and then the code below may be
// replaced with an assert or at least simplified. The special casing of constants in code
@@ -2487,7 +2542,7 @@ GenTree* Lowering::LowerDirectCall(GenTreeCall* call)
GenTree* indir = Ind(cellAddr);
#ifdef FEATURE_READYTORUN_COMPILER
-#ifdef _TARGET_ARM64_
+#if defined(_TARGET_ARMARCH_)
// For arm64, we dispatch code same as VSD using X11 for indirection cell address,
// which ZapIndirectHelperThunk expects.
if (call->IsR2RRelativeIndir())
@@ -2780,6 +2835,9 @@ void Lowering::InsertPInvokeMethodProlog()
JITDUMP("======= Inserting PInvoke method prolog\n");
+ // The first BB must be a scratch BB in order for us to be able to safely insert the P/Invoke prolog.
+ assert(comp->fgFirstBBisScratch());
+
LIR::Range& firstBlockRange = LIR::AsRange(comp->fgFirstBB);
const CORINFO_EE_INFO* pInfo = comp->eeGetEEInfo();
@@ -2795,11 +2853,11 @@ void Lowering::InsertPInvokeMethodProlog()
// for x86, don't pass the secretArg.
CLANG_FORMAT_COMMENT_ANCHOR;
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) || defined(_TARGET_ARM_)
GenTreeArgList* argList = comp->gtNewArgList(frameAddr);
-#else // !_TARGET_X86_
+#else
GenTreeArgList* argList = comp->gtNewArgList(frameAddr, PhysReg(REG_SECRET_STUB_PARAM));
-#endif // !_TARGET_X86_
+#endif
GenTree* call = comp->gtNewHelperCallNode(CORINFO_HELP_INIT_PINVOKE_FRAME, TYP_I_IMPL, 0, argList);
@@ -2814,14 +2872,13 @@ void Lowering::InsertPInvokeMethodProlog()
store->gtOp.gtOp1 = call;
store->gtFlags |= GTF_VAR_DEF;
- GenTree* insertionPoint = firstBlockRange.FirstNonPhiOrCatchArgNode();
-
comp->fgMorphTree(store);
- firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, store));
+ firstBlockRange.InsertAtEnd(LIR::SeqTree(comp, store));
DISPTREERANGE(firstBlockRange, store);
-#ifndef _TARGET_X86_ // For x86, this step is done at the call site (due to stack pointer not being static in the
- // function).
+#if !defined(_TARGET_X86_) && !defined(_TARGET_ARM_)
+ // For x86, this step is done at the call site (due to stack pointer not being static in the function).
+ // For arm32, CallSiteSP is set up by the call to CORINFO_HELP_INIT_PINVOKE_FRAME.
// --------------------------------------------------------
// InlinedCallFrame.m_pCallSiteSP = @RSP;
@@ -2830,10 +2887,13 @@ void Lowering::InsertPInvokeMethodProlog()
GenTreeLclFld(GT_STORE_LCL_FLD, TYP_I_IMPL, comp->lvaInlinedPInvokeFrameVar, callFrameInfo.offsetOfCallSiteSP);
storeSP->gtOp1 = PhysReg(REG_SPBASE);
- firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, storeSP));
+ firstBlockRange.InsertAtEnd(LIR::SeqTree(comp, storeSP));
DISPTREERANGE(firstBlockRange, storeSP);
-#endif // !_TARGET_X86_
+#endif // !defined(_TARGET_X86_) && !defined(_TARGET_ARM_)
+
+#if !defined(_TARGET_ARM_)
+ // For arm32, CalleeSavedFP is set up by the call to CORINFO_HELP_INIT_PINVOKE_FRAME.
// --------------------------------------------------------
// InlinedCallFrame.m_pCalleeSavedEBP = @RBP;
@@ -2843,8 +2903,9 @@ void Lowering::InsertPInvokeMethodProlog()
callFrameInfo.offsetOfCalleeSavedFP);
storeFP->gtOp1 = PhysReg(REG_FPBASE);
- firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, storeFP));
+ firstBlockRange.InsertAtEnd(LIR::SeqTree(comp, storeFP));
DISPTREERANGE(firstBlockRange, storeFP);
+#endif // !defined(_TARGET_ARM_)
// --------------------------------------------------------
// On 32-bit targets, CORINFO_HELP_INIT_PINVOKE_FRAME initializes the PInvoke frame and then pushes it onto
@@ -2857,7 +2918,7 @@ void Lowering::InsertPInvokeMethodProlog()
// Push a frame - if we are NOT in an IL stub, this is done right before the call
// The init routine sets InlinedCallFrame's m_pNext, so we just set the thead's top-of-stack
GenTree* frameUpd = CreateFrameLinkUpdate(PushFrame);
- firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, frameUpd));
+ firstBlockRange.InsertAtEnd(LIR::SeqTree(comp, frameUpd));
DISPTREERANGE(firstBlockRange, frameUpd);
}
#endif // _TARGET_64BIT_
@@ -2964,7 +3025,6 @@ void Lowering::InsertPInvokeCallProlog(GenTreeCall* call)
noway_assert(comp->lvaInlinedPInvokeFrameVar != BAD_VAR_NUM);
-#if COR_JIT_EE_VERSION > 460
if (comp->opts.ShouldUsePInvokeHelpers())
{
// First argument is the address of the frame variable.
@@ -2980,7 +3040,6 @@ void Lowering::InsertPInvokeCallProlog(GenTreeCall* call)
LowerNode(helperCall); // helper call is inserted before current node and should be lowered here.
return;
}
-#endif
// Emit the following sequence:
//
@@ -3113,7 +3172,6 @@ void Lowering::InsertPInvokeCallEpilog(GenTreeCall* call)
{
JITDUMP("======= Inserting PInvoke call epilog\n");
-#if COR_JIT_EE_VERSION > 460
if (comp->opts.ShouldUsePInvokeHelpers())
{
noway_assert(comp->lvaInlinedPInvokeFrameVar != BAD_VAR_NUM);
@@ -3131,7 +3189,6 @@ void Lowering::InsertPInvokeCallEpilog(GenTreeCall* call)
BlockRange().InsertAfter(call, LIR::SeqTree(comp, helperCall));
return;
}
-#endif
// gcstate = 1
GenTree* insertionPoint = call->gtNext;
@@ -3252,18 +3309,7 @@ GenTree* Lowering::LowerNonvirtPinvokeCall(GenTreeCall* call)
CORINFO_METHOD_HANDLE methHnd = call->gtCallMethHnd;
CORINFO_CONST_LOOKUP lookup;
-#if COR_JIT_EE_VERSION > 460
comp->info.compCompHnd->getAddressOfPInvokeTarget(methHnd, &lookup);
-#else
- void* pIndirection;
- lookup.accessType = IAT_PVALUE;
- lookup.addr = comp->info.compCompHnd->getAddressOfPInvokeFixup(methHnd, &pIndirection);
- if (lookup.addr == nullptr)
- {
- lookup.accessType = IAT_PPVALUE;
- lookup.addr = pIndirection;
- }
-#endif
void* addr = lookup.addr;
switch (lookup.accessType)
@@ -4381,6 +4427,14 @@ void Lowering::DoPhase()
#endif
#endif
+ // If we have any PInvoke calls, insert the one-time prolog code. We'll inserted the epilog code in the
+ // appropriate spots later. NOTE: there is a minor optimization opportunity here, as we still create p/invoke
+ // data structures and setup/teardown even if we've eliminated all p/invoke calls due to dead code elimination.
+ if (comp->info.compCallUnmanaged)
+ {
+ InsertPInvokeMethodProlog();
+ }
+
#if !defined(_TARGET_64BIT_)
DecomposeLongs decomp(comp); // Initialize the long decomposition class.
decomp.PrepareForDecomposition();
@@ -4398,14 +4452,6 @@ void Lowering::DoPhase()
LowerBlock(block);
}
- // If we have any PInvoke calls, insert the one-time prolog code. We've already inserted the epilog code in the
- // appropriate spots. NOTE: there is a minor optimization opportunity here, as we still create p/invoke data
- // structures and setup/teardown even if we've eliminated all p/invoke calls due to dead code elimination.
- if (comp->info.compCallUnmanaged)
- {
- InsertPInvokeMethodProlog();
- }
-
#ifdef DEBUG
JITDUMP("Lower has completed modifying nodes, proceeding to initialize LSRA TreeNodeInfo structs...\n");
if (VERBOSE)
@@ -4558,13 +4604,6 @@ void Lowering::CheckCallArg(GenTree* arg)
switch (arg->OperGet())
{
-#if !defined(_TARGET_64BIT_)
- case GT_LONG:
- assert(arg->gtGetOp1()->OperIsPutArg());
- assert(arg->gtGetOp2()->OperIsPutArg());
- break;
-#endif
-
case GT_FIELD_LIST:
{
GenTreeFieldList* list = arg->AsFieldList();
diff --git a/src/jit/lower.h b/src/jit/lower.h
index 57b4127f26..bcc2bafdab 100644
--- a/src/jit/lower.h
+++ b/src/jit/lower.h
@@ -195,6 +195,8 @@ private:
void TreeNodeInfoInitStoreLoc(GenTree* tree);
void TreeNodeInfoInitReturn(GenTree* tree);
void TreeNodeInfoInitShiftRotate(GenTree* tree);
+ void TreeNodeInfoInitPutArgReg(
+ GenTreeUnOp* node, regNumber argReg, TreeNodeInfo& info, bool isVarArgs, bool* callHasFloatRegArgs);
void TreeNodeInfoInitCall(GenTreeCall* call);
void TreeNodeInfoInitCmp(GenTreePtr tree);
void TreeNodeInfoInitStructArg(GenTreePtr structArg);
diff --git a/src/jit/lowerarm.cpp b/src/jit/lowerarm.cpp
index 9792b8a9c6..0701520b0a 100644
--- a/src/jit/lowerarm.cpp
+++ b/src/jit/lowerarm.cpp
@@ -31,189 +31,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "lsra.h"
//------------------------------------------------------------------------
-// LowerStoreLoc: Lower a store of a lclVar
-//
-// Arguments:
-// storeLoc - the local store (GT_STORE_LCL_FLD or GT_STORE_LCL_VAR)
-//
-// Notes:
-// This involves:
-// - Widening operations of unsigneds.
-//
-void Lowering::LowerStoreLoc(GenTreeLclVarCommon* storeLoc)
-{
- // Try to widen the ops if they are going into a local var.
- GenTree* op1 = storeLoc->gtGetOp1();
- if ((storeLoc->gtOper == GT_STORE_LCL_VAR) && (op1->gtOper == GT_CNS_INT))
- {
- GenTreeIntCon* con = op1->AsIntCon();
- ssize_t ival = con->gtIconVal;
- unsigned varNum = storeLoc->gtLclNum;
- LclVarDsc* varDsc = comp->lvaTable + varNum;
-
- if (varDsc->lvIsSIMDType())
- {
- noway_assert(storeLoc->gtType != TYP_STRUCT);
- }
- unsigned size = genTypeSize(storeLoc);
- // If we are storing a constant into a local variable
- // we extend the size of the store here
- if ((size < 4) && !varTypeIsStruct(varDsc))
- {
- if (!varTypeIsUnsigned(varDsc))
- {
- if (genTypeSize(storeLoc) == 1)
- {
- if ((ival & 0x7f) != ival)
- {
- ival = ival | 0xffffff00;
- }
- }
- else
- {
- assert(genTypeSize(storeLoc) == 2);
- if ((ival & 0x7fff) != ival)
- {
- ival = ival | 0xffff0000;
- }
- }
- }
-
- // A local stack slot is at least 4 bytes in size, regardless of
- // what the local var is typed as, so auto-promote it here
- // unless it is a field of a promoted struct
- // TODO-ARM-CQ: if the field is promoted shouldn't we also be able to do this?
- if (!varDsc->lvIsStructField)
- {
- storeLoc->gtType = TYP_INT;
- con->SetIconValue(ival);
- }
- }
- }
-}
-
-//------------------------------------------------------------------------
-// LowerCast: Lower GT_CAST(srcType, DstType) nodes.
-//
-// Arguments:
-// tree - GT_CAST node to be lowered
-//
-// Return Value:
-// None.
-//
-// Notes:
-// Casts from small int type to float/double are transformed as follows:
-// GT_CAST(byte, float/double) = GT_CAST(GT_CAST(byte, int32), float/double)
-// GT_CAST(sbyte, float/double) = GT_CAST(GT_CAST(sbyte, int32), float/double)
-// GT_CAST(int16, float/double) = GT_CAST(GT_CAST(int16, int32), float/double)
-// GT_CAST(uint16, float/double) = GT_CAST(GT_CAST(uint16, int32), float/double)
-//
-// Similarly casts from float/double to a smaller int type are transformed as follows:
-// GT_CAST(float/double, byte) = GT_CAST(GT_CAST(float/double, int32), byte)
-// GT_CAST(float/double, sbyte) = GT_CAST(GT_CAST(float/double, int32), sbyte)
-// GT_CAST(float/double, int16) = GT_CAST(GT_CAST(double/double, int32), int16)
-// GT_CAST(float/double, uint16) = GT_CAST(GT_CAST(double/double, int32), uint16)
-//
-// Note that for the overflow conversions we still depend on helper calls and
-// don't expect to see them here.
-// i) GT_CAST(float/double, int type with overflow detection)
-//
-void Lowering::LowerCast(GenTree* tree)
-{
- assert(tree->OperGet() == GT_CAST);
-
- JITDUMP("LowerCast for: ");
- DISPNODE(tree);
- JITDUMP("\n");
-
- GenTreePtr op1 = tree->gtOp.gtOp1;
- var_types dstType = tree->CastToType();
- var_types srcType = op1->TypeGet();
- var_types tmpType = TYP_UNDEF;
-
- if (varTypeIsFloating(srcType))
- {
- noway_assert(!tree->gtOverflow());
- }
-
- // Case of src is a small type and dst is a floating point type.
- if (varTypeIsSmall(srcType) && varTypeIsFloating(dstType))
- {
- NYI_ARM("Lowering for cast from small type to float"); // Not tested yet.
- // These conversions can never be overflow detecting ones.
- noway_assert(!tree->gtOverflow());
- tmpType = TYP_INT;
- }
- // case of src is a floating point type and dst is a small type.
- else if (varTypeIsFloating(srcType) && varTypeIsSmall(dstType))
- {
- NYI_ARM("Lowering for cast from float to small type"); // Not tested yet.
- tmpType = TYP_INT;
- }
-
- if (tmpType != TYP_UNDEF)
- {
- GenTreePtr tmp = comp->gtNewCastNode(tmpType, op1, tmpType);
- tmp->gtFlags |= (tree->gtFlags & (GTF_UNSIGNED | GTF_OVERFLOW | GTF_EXCEPT));
-
- tree->gtFlags &= ~GTF_UNSIGNED;
- tree->gtOp.gtOp1 = tmp;
- BlockRange().InsertAfter(op1, tmp);
- }
-}
-
-//------------------------------------------------------------------------
-// LowerRotate: Lower GT_ROL and GT_ROL nodes.
-//
-// Arguments:
-// tree - the node to lower
-//
-// Return Value:
-// None.
-//
-void Lowering::LowerRotate(GenTreePtr tree)
-{
- if (tree->OperGet() == GT_ROL)
- {
- // There is no ROL instruction on ARM. Convert ROL into ROR.
- GenTreePtr rotatedValue = tree->gtOp.gtOp1;
- unsigned rotatedValueBitSize = genTypeSize(rotatedValue->gtType) * 8;
- GenTreePtr rotateLeftIndexNode = tree->gtOp.gtOp2;
-
- if (rotateLeftIndexNode->IsCnsIntOrI())
- {
- ssize_t rotateLeftIndex = rotateLeftIndexNode->gtIntCon.gtIconVal;
- ssize_t rotateRightIndex = rotatedValueBitSize - rotateLeftIndex;
- rotateLeftIndexNode->gtIntCon.gtIconVal = rotateRightIndex;
- }
- else
- {
- GenTreePtr tmp =
- comp->gtNewOperNode(GT_NEG, genActualType(rotateLeftIndexNode->gtType), rotateLeftIndexNode);
- BlockRange().InsertAfter(rotateLeftIndexNode, tmp);
- tree->gtOp.gtOp2 = tmp;
- }
- tree->ChangeOper(GT_ROR);
- }
-}
-
-//------------------------------------------------------------------------
-// LowerPutArgStk: Lower a GT_PUTARG_STK node
-//
-// Arguments:
-// argNode - a GT_PUTARG_STK node
-//
-// Return Value:
-// None.
-//
-// Notes:
-// There is currently no Lowering required for this on ARM.
-//
-void Lowering::LowerPutArgStk(GenTreePutArgStk* argNode, fgArgTabEntryPtr info)
-{
-}
-
-//------------------------------------------------------------------------
// IsCallTargetInRange: Can a call target address be encoded in-place?
//
// Return Value:
diff --git a/src/jit/lowerarm64.cpp b/src/jit/lowerarm64.cpp
index f5bc55e10c..b24ed8221c 100644
--- a/src/jit/lowerarm64.cpp
+++ b/src/jit/lowerarm64.cpp
@@ -29,304 +29,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "sideeffects.h"
#include "lower.h"
-//------------------------------------------------------------------------
-// LowerStoreLoc: Lower a store of a lclVar
-//
-// Arguments:
-// storeLoc - the local store (GT_STORE_LCL_FLD or GT_STORE_LCL_VAR)
-//
-// Notes:
-// This involves:
-// - Widening operations of unsigneds.
-
-void Lowering::LowerStoreLoc(GenTreeLclVarCommon* storeLoc)
-{
- // Try to widen the ops if they are going into a local var.
- GenTree* op1 = storeLoc->gtGetOp1();
- if ((storeLoc->gtOper == GT_STORE_LCL_VAR) && (op1->gtOper == GT_CNS_INT))
- {
- GenTreeIntCon* con = op1->AsIntCon();
- ssize_t ival = con->gtIconVal;
- unsigned varNum = storeLoc->gtLclNum;
- LclVarDsc* varDsc = comp->lvaTable + varNum;
-
- if (varDsc->lvIsSIMDType())
- {
- noway_assert(storeLoc->gtType != TYP_STRUCT);
- }
- unsigned size = genTypeSize(storeLoc);
- // If we are storing a constant into a local variable
- // we extend the size of the store here
- if ((size < 4) && !varTypeIsStruct(varDsc))
- {
- if (!varTypeIsUnsigned(varDsc))
- {
- if (genTypeSize(storeLoc) == 1)
- {
- if ((ival & 0x7f) != ival)
- {
- ival = ival | 0xffffff00;
- }
- }
- else
- {
- assert(genTypeSize(storeLoc) == 2);
- if ((ival & 0x7fff) != ival)
- {
- ival = ival | 0xffff0000;
- }
- }
- }
-
- // A local stack slot is at least 4 bytes in size, regardless of
- // what the local var is typed as, so auto-promote it here
- // unless it is a field of a promoted struct
- // TODO-ARM64-CQ: if the field is promoted shouldn't we also be able to do this?
- if (!varDsc->lvIsStructField)
- {
- storeLoc->gtType = TYP_INT;
- con->SetIconValue(ival);
- }
- }
- }
-}
-
-//------------------------------------------------------------------------
-// LowerBlockStore: Set block store type
-//
-// Arguments:
-// blkNode - The block store node of interest
-//
-// Return Value:
-// None.
-//
-
-void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
-{
- GenTree* dstAddr = blkNode->Addr();
- unsigned size = blkNode->gtBlkSize;
- GenTree* source = blkNode->Data();
- Compiler* compiler = comp;
-
- // Sources are dest address and initVal or source.
- GenTreePtr srcAddrOrFill = nullptr;
- bool isInitBlk = blkNode->OperIsInitBlkOp();
-
- if (!isInitBlk)
- {
- // CopyObj or CopyBlk
- if ((blkNode->OperGet() == GT_STORE_OBJ) && ((blkNode->AsObj()->gtGcPtrCount == 0) || blkNode->gtBlkOpGcUnsafe))
- {
- blkNode->SetOper(GT_STORE_BLK);
- }
- if (source->gtOper == GT_IND)
- {
- srcAddrOrFill = blkNode->Data()->gtGetOp1();
- }
- }
-
- if (isInitBlk)
- {
- GenTreePtr initVal = source;
- if (initVal->OperIsInitVal())
- {
- initVal = initVal->gtGetOp1();
- }
- srcAddrOrFill = initVal;
-
-#if 0
- // TODO-ARM64-CQ: Currently we generate a helper call for every
- // initblk we encounter. Later on we should implement loop unrolling
- // code sequences to improve CQ.
- // For reference see the code in LowerXArch.cpp.
- if ((size != 0) && (size <= INITBLK_UNROLL_LIMIT) && initVal->IsCnsIntOrI())
- {
- // The fill value of an initblk is interpreted to hold a
- // value of (unsigned int8) however a constant of any size
- // may practically reside on the evaluation stack. So extract
- // the lower byte out of the initVal constant and replicate
- // it to a larger constant whose size is sufficient to support
- // the largest width store of the desired inline expansion.
-
- ssize_t fill = initVal->gtIntCon.gtIconVal & 0xFF;
- if (size < REGSIZE_BYTES)
- {
- initVal->gtIntCon.gtIconVal = 0x01010101 * fill;
- }
- else
- {
- initVal->gtIntCon.gtIconVal = 0x0101010101010101LL * fill;
- initVal->gtType = TYP_LONG;
- }
- initBlkNode->gtBlkOpKind = GenTreeBlkOp::BlkOpKindUnroll;
- }
- else
-#endif // 0
- {
- blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindHelper;
- }
- }
- else
- {
- // CopyObj or CopyBlk
- // Sources are src and dest and size if not constant.
-
- if (blkNode->OperGet() == GT_STORE_OBJ)
- {
- // CopyObj
-
- GenTreeObj* objNode = blkNode->AsObj();
-
- unsigned slots = objNode->gtSlots;
-
-#ifdef DEBUG
- // CpObj must always have at least one GC-Pointer as a member.
- assert(objNode->gtGcPtrCount > 0);
-
- assert(dstAddr->gtType == TYP_BYREF || dstAddr->gtType == TYP_I_IMPL);
-
- CORINFO_CLASS_HANDLE clsHnd = objNode->gtClass;
- size_t classSize = compiler->info.compCompHnd->getClassSize(clsHnd);
- size_t blkSize = roundUp(classSize, TARGET_POINTER_SIZE);
-
- // Currently, the EE always round up a class data structure so
- // we are not handling the case where we have a non multiple of pointer sized
- // struct. This behavior may change in the future so in order to keeps things correct
- // let's assert it just to be safe. Going forward we should simply
- // handle this case.
- assert(classSize == blkSize);
- assert((blkSize / TARGET_POINTER_SIZE) == slots);
- assert(objNode->HasGCPtr());
-#endif
-
- blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindUnroll;
- }
- else
- {
- // CopyBlk
- short internalIntCount = 0;
- regMaskTP internalIntCandidates = RBM_NONE;
-
-#if 0
- // In case of a CpBlk with a constant size and less than CPBLK_UNROLL_LIMIT size
- // we should unroll the loop to improve CQ.
- // For reference see the code in lowerxarch.cpp.
-
- // TODO-ARM64-CQ: cpblk loop unrolling is currently not implemented.
-
- if ((size != 0) && (size <= INITBLK_UNROLL_LIMIT))
- {
- blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindUnroll;
- }
- else
-#endif // 0
- {
- // In case we have a constant integer this means we went beyond
- // CPBLK_UNROLL_LIMIT bytes of size, still we should never have the case of
- // any GC-Pointers in the src struct.
- blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindHelper;
- }
- }
- }
-}
-
-/* Lower GT_CAST(srcType, DstType) nodes.
- *
- * Casts from small int type to float/double are transformed as follows:
- * GT_CAST(byte, float/double) = GT_CAST(GT_CAST(byte, int32), float/double)
- * GT_CAST(sbyte, float/double) = GT_CAST(GT_CAST(sbyte, int32), float/double)
- * GT_CAST(int16, float/double) = GT_CAST(GT_CAST(int16, int32), float/double)
- * GT_CAST(uint16, float/double) = GT_CAST(GT_CAST(uint16, int32), float/double)
- *
- * SSE2 conversion instructions operate on signed integers. casts from Uint32/Uint64
- * are morphed as follows by front-end and hence should not be seen here.
- * GT_CAST(uint32, float/double) = GT_CAST(GT_CAST(uint32, long), float/double)
- * GT_CAST(uint64, float) = GT_CAST(GT_CAST(uint64, double), float)
- *
- *
- * Similarly casts from float/double to a smaller int type are transformed as follows:
- * GT_CAST(float/double, byte) = GT_CAST(GT_CAST(float/double, int32), byte)
- * GT_CAST(float/double, sbyte) = GT_CAST(GT_CAST(float/double, int32), sbyte)
- * GT_CAST(float/double, int16) = GT_CAST(GT_CAST(double/double, int32), int16)
- * GT_CAST(float/double, uint16) = GT_CAST(GT_CAST(double/double, int32), uint16)
- *
- * SSE2 has instructions to convert a float/double vlaue into a signed 32/64-bit
- * integer. The above transformations help us to leverage those instructions.
- *
- * Note that for the overflow conversions we still depend on helper calls and
- * don't expect to see them here.
- * i) GT_CAST(float/double, int type with overflow detection)
- *
- */
-void Lowering::LowerCast(GenTree* tree)
-{
- assert(tree->OperGet() == GT_CAST);
-
- GenTreePtr op1 = tree->gtOp.gtOp1;
- var_types dstType = tree->CastToType();
- var_types srcType = op1->TypeGet();
- var_types tmpType = TYP_UNDEF;
-
- // We should never see the following casts as they are expected to be lowered
- // apropriately or converted into helper calls by front-end.
- // srcType = float/double dstType = * and overflow detecting cast
- // Reason: must be converted to a helper call
- //
- if (varTypeIsFloating(srcType))
- {
- noway_assert(!tree->gtOverflow());
- }
-
- // Case of src is a small type and dst is a floating point type.
- if (varTypeIsSmall(srcType) && varTypeIsFloating(dstType))
- {
- // These conversions can never be overflow detecting ones.
- noway_assert(!tree->gtOverflow());
- tmpType = TYP_INT;
- }
- // case of src is a floating point type and dst is a small type.
- else if (varTypeIsFloating(srcType) && varTypeIsSmall(dstType))
- {
- tmpType = TYP_INT;
- }
-
- if (tmpType != TYP_UNDEF)
- {
- GenTreePtr tmp = comp->gtNewCastNode(tmpType, op1, tmpType);
- tmp->gtFlags |= (tree->gtFlags & (GTF_UNSIGNED | GTF_OVERFLOW | GTF_EXCEPT));
-
- tree->gtFlags &= ~GTF_UNSIGNED;
- tree->gtOp.gtOp1 = tmp;
- BlockRange().InsertAfter(op1, tmp);
- }
-}
-
-void Lowering::LowerRotate(GenTreePtr tree)
-{
- if (tree->OperGet() == GT_ROL)
- {
- // There is no ROL instruction on ARM. Convert ROL into ROR.
- GenTreePtr rotatedValue = tree->gtOp.gtOp1;
- unsigned rotatedValueBitSize = genTypeSize(rotatedValue->gtType) * 8;
- GenTreePtr rotateLeftIndexNode = tree->gtOp.gtOp2;
-
- if (rotateLeftIndexNode->IsCnsIntOrI())
- {
- ssize_t rotateLeftIndex = rotateLeftIndexNode->gtIntCon.gtIconVal;
- ssize_t rotateRightIndex = rotatedValueBitSize - rotateLeftIndex;
- rotateLeftIndexNode->gtIntCon.gtIconVal = rotateRightIndex;
- }
- else
- {
- GenTreePtr tmp =
- comp->gtNewOperNode(GT_NEG, genActualType(rotateLeftIndexNode->gtType), rotateLeftIndexNode);
- BlockRange().InsertAfter(rotateLeftIndexNode, tmp);
- tree->gtOp.gtOp2 = tmp;
- }
- tree->ChangeOper(GT_ROR);
- }
-}
-
// returns true if the tree can use the read-modify-write memory instruction form
bool Lowering::isRMWRegOper(GenTreePtr tree)
{
diff --git a/src/jit/lowerarmarch.cpp b/src/jit/lowerarmarch.cpp
new file mode 100644
index 0000000000..4ff3552eb0
--- /dev/null
+++ b/src/jit/lowerarmarch.cpp
@@ -0,0 +1,346 @@
+// 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.
+
+/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XX XX
+XX Lowering for ARM and ARM64 common code XX
+XX XX
+XX This encapsulates common logic for lowering trees for the ARM and ARM64 XX
+XX architectures. For a more detailed view of what is lowering, please XX
+XX take a look at Lower.cpp XX
+XX XX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+*/
+
+#include "jitpch.h"
+#ifdef _MSC_VER
+#pragma hdrstop
+#endif
+
+#ifndef LEGACY_BACKEND // This file is ONLY used for the RyuJIT backend that uses the linear scan register allocator
+
+#ifdef _TARGET_ARMARCH_ // This file is ONLY used for ARM and ARM64 architectures
+
+#include "jit.h"
+#include "sideeffects.h"
+#include "lower.h"
+#include "lsra.h"
+
+//------------------------------------------------------------------------
+// LowerStoreLoc: Lower a store of a lclVar
+//
+// Arguments:
+// storeLoc - the local store (GT_STORE_LCL_FLD or GT_STORE_LCL_VAR)
+//
+// Notes:
+// This involves:
+// - Widening operations of unsigneds.
+//
+void Lowering::LowerStoreLoc(GenTreeLclVarCommon* storeLoc)
+{
+ // Try to widen the ops if they are going into a local var.
+ GenTree* op1 = storeLoc->gtGetOp1();
+ if ((storeLoc->gtOper == GT_STORE_LCL_VAR) && (op1->gtOper == GT_CNS_INT))
+ {
+ GenTreeIntCon* con = op1->AsIntCon();
+ ssize_t ival = con->gtIconVal;
+ unsigned varNum = storeLoc->gtLclNum;
+ LclVarDsc* varDsc = comp->lvaTable + varNum;
+
+ if (varDsc->lvIsSIMDType())
+ {
+ noway_assert(storeLoc->gtType != TYP_STRUCT);
+ }
+ unsigned size = genTypeSize(storeLoc);
+ // If we are storing a constant into a local variable
+ // we extend the size of the store here
+ if ((size < 4) && !varTypeIsStruct(varDsc))
+ {
+ if (!varTypeIsUnsigned(varDsc))
+ {
+ if (genTypeSize(storeLoc) == 1)
+ {
+ if ((ival & 0x7f) != ival)
+ {
+ ival = ival | 0xffffff00;
+ }
+ }
+ else
+ {
+ assert(genTypeSize(storeLoc) == 2);
+ if ((ival & 0x7fff) != ival)
+ {
+ ival = ival | 0xffff0000;
+ }
+ }
+ }
+
+ // A local stack slot is at least 4 bytes in size, regardless of
+ // what the local var is typed as, so auto-promote it here
+ // unless it is a field of a promoted struct
+ // TODO-CQ: if the field is promoted shouldn't we also be able to do this?
+ if (!varDsc->lvIsStructField)
+ {
+ storeLoc->gtType = TYP_INT;
+ con->SetIconValue(ival);
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+// LowerBlockStore: Set block store type
+//
+// Arguments:
+// blkNode - The block store node of interest
+//
+// Return Value:
+// None.
+//
+void Lowering::LowerBlockStore(GenTreeBlk* blkNode)
+{
+ GenTree* dstAddr = blkNode->Addr();
+ unsigned size = blkNode->gtBlkSize;
+ GenTree* source = blkNode->Data();
+ Compiler* compiler = comp;
+
+ // Sources are dest address and initVal or source.
+ GenTreePtr srcAddrOrFill = nullptr;
+ bool isInitBlk = blkNode->OperIsInitBlkOp();
+
+ if (!isInitBlk)
+ {
+ // CopyObj or CopyBlk
+ if ((blkNode->OperGet() == GT_STORE_OBJ) && ((blkNode->AsObj()->gtGcPtrCount == 0) || blkNode->gtBlkOpGcUnsafe))
+ {
+ blkNode->SetOper(GT_STORE_BLK);
+ }
+ if (source->gtOper == GT_IND)
+ {
+ srcAddrOrFill = blkNode->Data()->gtGetOp1();
+ }
+ }
+
+ if (isInitBlk)
+ {
+ GenTreePtr initVal = source;
+ if (initVal->OperIsInitVal())
+ {
+ initVal = initVal->gtGetOp1();
+ }
+ srcAddrOrFill = initVal;
+
+#ifdef _TARGET_ARM64_
+ if ((size != 0) && (size <= INITBLK_UNROLL_LIMIT) && initVal->IsCnsIntOrI())
+ {
+ // TODO-ARM-CQ: Currently we generate a helper call for every
+ // initblk we encounter. Later on we should implement loop unrolling
+ // code sequences to improve CQ.
+ // For reference see the code in LowerXArch.cpp.
+ NYI_ARM("initblk loop unrolling is currently not implemented.");
+
+ // The fill value of an initblk is interpreted to hold a
+ // value of (unsigned int8) however a constant of any size
+ // may practically reside on the evaluation stack. So extract
+ // the lower byte out of the initVal constant and replicate
+ // it to a larger constant whose size is sufficient to support
+ // the largest width store of the desired inline expansion.
+
+ ssize_t fill = initVal->gtIntCon.gtIconVal & 0xFF;
+ if (size < REGSIZE_BYTES)
+ {
+ initVal->gtIntCon.gtIconVal = 0x01010101 * fill;
+ }
+ else
+ {
+ initVal->gtIntCon.gtIconVal = 0x0101010101010101LL * fill;
+ initVal->gtType = TYP_LONG;
+ }
+ blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindUnroll;
+ }
+ else
+#endif // _TARGET_ARM64_
+ {
+ blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindHelper;
+ }
+ }
+ else
+ {
+ // CopyObj or CopyBlk
+ // Sources are src and dest and size if not constant.
+
+ if (blkNode->OperGet() == GT_STORE_OBJ)
+ {
+ // CopyObj
+
+ NYI_ARM("Lowering for GT_STORE_OBJ isn't implemented");
+
+#ifdef _TARGET_ARM64_
+
+ GenTreeObj* objNode = blkNode->AsObj();
+
+ unsigned slots = objNode->gtSlots;
+
+#ifdef DEBUG
+ // CpObj must always have at least one GC-Pointer as a member.
+ assert(objNode->gtGcPtrCount > 0);
+
+ assert(dstAddr->gtType == TYP_BYREF || dstAddr->gtType == TYP_I_IMPL);
+
+ CORINFO_CLASS_HANDLE clsHnd = objNode->gtClass;
+ size_t classSize = compiler->info.compCompHnd->getClassSize(clsHnd);
+ size_t blkSize = roundUp(classSize, TARGET_POINTER_SIZE);
+
+ // Currently, the EE always round up a class data structure so
+ // we are not handling the case where we have a non multiple of pointer sized
+ // struct. This behavior may change in the future so in order to keeps things correct
+ // let's assert it just to be safe. Going forward we should simply
+ // handle this case.
+ assert(classSize == blkSize);
+ assert((blkSize / TARGET_POINTER_SIZE) == slots);
+ assert(objNode->HasGCPtr());
+#endif
+
+ blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindUnroll;
+
+#endif // _TARGET_ARM64_
+ }
+ else
+ {
+ // CopyBlk
+ short internalIntCount = 0;
+ regMaskTP internalIntCandidates = RBM_NONE;
+
+#ifdef _TARGET_ARM64_
+ // In case of a CpBlk with a constant size and less than CPBLK_UNROLL_LIMIT size
+ // we should unroll the loop to improve CQ.
+ // For reference see the code in lowerxarch.cpp.
+ // TODO-ARM-CQ: cpblk loop unrolling is currently not implemented.
+
+ if ((size != 0) && (size <= INITBLK_UNROLL_LIMIT))
+ {
+ blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindUnroll;
+ }
+ else
+#endif // _TARGET_ARM64_
+ {
+ // In case we have a constant integer this means we went beyond
+ // CPBLK_UNROLL_LIMIT bytes of size, still we should never have the case of
+ // any GC-Pointers in the src struct.
+ blkNode->gtBlkOpKind = GenTreeBlk::BlkOpKindHelper;
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------
+// LowerCast: Lower GT_CAST(srcType, DstType) nodes.
+//
+// Arguments:
+// tree - GT_CAST node to be lowered
+//
+// Return Value:
+// None.
+//
+// Notes:
+// Casts from small int type to float/double are transformed as follows:
+// GT_CAST(byte, float/double) = GT_CAST(GT_CAST(byte, int32), float/double)
+// GT_CAST(sbyte, float/double) = GT_CAST(GT_CAST(sbyte, int32), float/double)
+// GT_CAST(int16, float/double) = GT_CAST(GT_CAST(int16, int32), float/double)
+// GT_CAST(uint16, float/double) = GT_CAST(GT_CAST(uint16, int32), float/double)
+//
+// Similarly casts from float/double to a smaller int type are transformed as follows:
+// GT_CAST(float/double, byte) = GT_CAST(GT_CAST(float/double, int32), byte)
+// GT_CAST(float/double, sbyte) = GT_CAST(GT_CAST(float/double, int32), sbyte)
+// GT_CAST(float/double, int16) = GT_CAST(GT_CAST(double/double, int32), int16)
+// GT_CAST(float/double, uint16) = GT_CAST(GT_CAST(double/double, int32), uint16)
+//
+// Note that for the overflow conversions we still depend on helper calls and
+// don't expect to see them here.
+// i) GT_CAST(float/double, int type with overflow detection)
+//
+void Lowering::LowerCast(GenTree* tree)
+{
+ assert(tree->OperGet() == GT_CAST);
+
+ JITDUMP("LowerCast for: ");
+ DISPNODE(tree);
+ JITDUMP("\n");
+
+ GenTreePtr op1 = tree->gtOp.gtOp1;
+ var_types dstType = tree->CastToType();
+ var_types srcType = op1->TypeGet();
+ var_types tmpType = TYP_UNDEF;
+
+ if (varTypeIsFloating(srcType))
+ {
+ noway_assert(!tree->gtOverflow());
+ }
+
+ // Case of src is a small type and dst is a floating point type.
+ if (varTypeIsSmall(srcType) && varTypeIsFloating(dstType))
+ {
+ NYI_ARM("Lowering for cast from small type to float"); // Not tested yet.
+ // These conversions can never be overflow detecting ones.
+ noway_assert(!tree->gtOverflow());
+ tmpType = TYP_INT;
+ }
+ // case of src is a floating point type and dst is a small type.
+ else if (varTypeIsFloating(srcType) && varTypeIsSmall(dstType))
+ {
+ NYI_ARM("Lowering for cast from float to small type"); // Not tested yet.
+ tmpType = TYP_INT;
+ }
+
+ if (tmpType != TYP_UNDEF)
+ {
+ GenTreePtr tmp = comp->gtNewCastNode(tmpType, op1, tmpType);
+ tmp->gtFlags |= (tree->gtFlags & (GTF_UNSIGNED | GTF_OVERFLOW | GTF_EXCEPT));
+
+ tree->gtFlags &= ~GTF_UNSIGNED;
+ tree->gtOp.gtOp1 = tmp;
+ BlockRange().InsertAfter(op1, tmp);
+ }
+}
+
+//------------------------------------------------------------------------
+// LowerRotate: Lower GT_ROL and GT_ROL nodes.
+//
+// Arguments:
+// tree - the node to lower
+//
+// Return Value:
+// None.
+//
+void Lowering::LowerRotate(GenTreePtr tree)
+{
+ if (tree->OperGet() == GT_ROL)
+ {
+ // There is no ROL instruction on ARM. Convert ROL into ROR.
+ GenTreePtr rotatedValue = tree->gtOp.gtOp1;
+ unsigned rotatedValueBitSize = genTypeSize(rotatedValue->gtType) * 8;
+ GenTreePtr rotateLeftIndexNode = tree->gtOp.gtOp2;
+
+ if (rotateLeftIndexNode->IsCnsIntOrI())
+ {
+ ssize_t rotateLeftIndex = rotateLeftIndexNode->gtIntCon.gtIconVal;
+ ssize_t rotateRightIndex = rotatedValueBitSize - rotateLeftIndex;
+ rotateLeftIndexNode->gtIntCon.gtIconVal = rotateRightIndex;
+ }
+ else
+ {
+ GenTreePtr tmp =
+ comp->gtNewOperNode(GT_NEG, genActualType(rotateLeftIndexNode->gtType), rotateLeftIndexNode);
+ BlockRange().InsertAfter(rotateLeftIndexNode, tmp);
+ tree->gtOp.gtOp2 = tmp;
+ }
+ tree->ChangeOper(GT_ROR);
+ }
+}
+
+#endif // _TARGET_ARMARCH_
+
+#endif // !LEGACY_BACKEND
diff --git a/src/jit/lsra.cpp b/src/jit/lsra.cpp
index ac76e29364..e7c1c839d1 100644
--- a/src/jit/lsra.cpp
+++ b/src/jit/lsra.cpp
@@ -39,9 +39,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Overview (doLinearScan):
- Walk all blocks, building intervals and RefPositions (buildIntervals)
- - Traverse the RefPositions, marking last uses (setLastUses)
- - Note that this is necessary because the execution order doesn't accurately reflect use order.
- There is a "TODO-Throughput" to eliminate this.
- Allocate registers (allocateRegisters)
- Annotate nodes with register assignments (resolveRegisters)
- Add move nodes as needed to resolve conflicting register
@@ -723,12 +720,25 @@ void LinearScan::associateRefPosWithInterval(RefPosition* rp)
applyCalleeSaveHeuristics(rp);
- // Ensure that we have consistent def/use on SDSU temps.
- // However, in the case of a non-commutative rmw def, we must avoid over-constraining
- // the def, so don't propagate a single-register restriction from the consumer to the producer
+ if (theInterval->isLocalVar)
+ {
+ if (RefTypeIsUse(rp->refType))
+ {
+ RefPosition* const prevRP = theInterval->recentRefPosition;
+ if ((prevRP != nullptr) && (prevRP->bbNum == rp->bbNum))
+ {
+ prevRP->lastUse = false;
+ }
+ }
- if (RefTypeIsUse(rp->refType) && !theInterval->isLocalVar)
+ rp->lastUse = (rp->refType != RefTypeExpUse) && (rp->refType != RefTypeParamDef) &&
+ (rp->refType != RefTypeZeroInit) && !extendLifetimes();
+ }
+ else if (rp->refType == RefTypeUse)
{
+ // Ensure that we have consistent def/use on SDSU temps.
+ // However, in the case of a non-commutative rmw def, we must avoid over-constraining
+ // the def, so don't propagate a single-register restriction from the consumer to the producer
RefPosition* prevRefPosition = theInterval->recentRefPosition;
assert(prevRefPosition != nullptr && theInterval->firstRefPosition == prevRefPosition);
regMaskTP prevAssignment = prevRefPosition->registerAssignment;
@@ -744,6 +754,8 @@ void LinearScan::associateRefPosWithInterval(RefPosition* rp)
{
theInterval->hasConflictingDefUse = true;
}
+
+ rp->lastUse = true;
}
}
@@ -2486,16 +2498,15 @@ RefType refTypeForLocalRefNode(GenTree* node)
// being set by dataflow analysis. It is necessary to do it this way only because the execution
// order wasn't strictly correct.
-void LinearScan::setLastUses(BasicBlock* block)
-{
#ifdef DEBUG
+void LinearScan::checkLastUses(BasicBlock* block)
+{
if (VERBOSE)
{
- JITDUMP("\n\nCALCULATING LAST USES for block %u, liveout=", block->bbNum);
+ JITDUMP("\n\nCHECKING LAST USES for block %u, liveout=", block->bbNum);
dumpConvertedVarSet(compiler, block->bbLiveOut);
JITDUMP("\n==============================\n");
}
-#endif // DEBUG
unsigned keepAliveVarNum = BAD_VAR_NUM;
if (compiler->lvaKeepAliveAndReportThis())
@@ -2513,8 +2524,8 @@ void LinearScan::setLastUses(BasicBlock* block)
VARSET_TP VARSET_INIT(compiler, temp, block->bbLiveOut);
+ bool foundDiff = false;
auto currentRefPosition = refPositions.rbegin();
-
while (currentRefPosition->refType != RefTypeBB)
{
// We should never see ParamDefs or ZeroInits within a basic block.
@@ -2523,42 +2534,46 @@ void LinearScan::setLastUses(BasicBlock* block)
{
unsigned varNum = currentRefPosition->getInterval()->varNum;
unsigned varIndex = currentRefPosition->getInterval()->getVarIndex(compiler);
+
+ LsraLocation loc = currentRefPosition->nodeLocation;
+
// We should always have a tree node for a localVar, except for the "special" RefPositions.
GenTreePtr tree = currentRefPosition->treeNode;
assert(tree != nullptr || currentRefPosition->refType == RefTypeExpUse ||
currentRefPosition->refType == RefTypeDummyDef);
+
if (!VarSetOps::IsMember(compiler, temp, varIndex) && varNum != keepAliveVarNum)
{
- // There was no exposed use, so this is a
- // "last use" (and we mark it thus even if it's a def)
+ // There was no exposed use, so this is a "last use" (and we mark it thus even if it's a def)
- if (tree != nullptr)
+ if (extendLifetimes())
{
- tree->gtFlags |= GTF_VAR_DEATH;
- }
- LsraLocation loc = currentRefPosition->nodeLocation;
-#ifdef DEBUG
- if (getLsraExtendLifeTimes())
- {
- JITDUMP("last use of V%02u @%u (not marked as last use for LSRA due to extendLifetimes stress "
- "option)\n",
- compiler->lvaTrackedToVarNum[varIndex], loc);
+ // NOTE: this is a bit of a hack. When extending lifetimes, the "last use" bit will be clear.
+ // This bit, however, would normally be used during resolveLocalRef to set the value of
+ // GTF_VAR_DEATH on the node for a ref position. If this bit is not set correctly even when
+ // extending lifetimes, the code generator will assert as it expects to have accurate last
+ // use information. To avoid these asserts, set the GTF_VAR_DEATH bit here.
+ if (tree != nullptr)
+ {
+ tree->gtFlags |= GTF_VAR_DEATH;
+ }
}
- else
-#endif // DEBUG
+ else if (!currentRefPosition->lastUse)
{
- JITDUMP("last use of V%02u @%u\n", compiler->lvaTrackedToVarNum[varIndex], loc);
- currentRefPosition->lastUse = true;
+ JITDUMP("missing expected last use of V%02u @%u\n", compiler->lvaTrackedToVarNum[varIndex], loc);
+ foundDiff = true;
}
VarSetOps::AddElemD(compiler, temp, varIndex);
}
- else
+ else if (currentRefPosition->lastUse)
{
- currentRefPosition->lastUse = false;
- if (tree != nullptr)
- {
- tree->gtFlags &= ~GTF_VAR_DEATH;
- }
+ JITDUMP("unexpected last use of V%02u @%u\n", compiler->lvaTrackedToVarNum[varIndex], loc);
+ foundDiff = true;
+ }
+ else if (extendLifetimes() && tree != nullptr)
+ {
+ // NOTE: see the comment above re: the extendLifetimes hack.
+ tree->gtFlags &= ~GTF_VAR_DEATH;
}
if (currentRefPosition->refType == RefTypeDef || currentRefPosition->refType == RefTypeDummyDef)
@@ -2566,15 +2581,14 @@ void LinearScan::setLastUses(BasicBlock* block)
VarSetOps::RemoveElemD(compiler, temp, varIndex);
}
}
+
assert(currentRefPosition != refPositions.rend());
++currentRefPosition;
}
-#ifdef DEBUG
VARSET_TP VARSET_INIT(compiler, temp2, block->bbLiveIn);
VarSetOps::DiffD(compiler, temp2, temp);
VarSetOps::DiffD(compiler, temp, block->bbLiveIn);
- bool foundDiff = false;
{
VARSET_ITER_INIT(compiler, iter, temp, varIndex);
@@ -2603,8 +2617,8 @@ void LinearScan::setLastUses(BasicBlock* block)
}
assert(!foundDiff);
-#endif // DEBUG
}
+#endif // DEBUG
void LinearScan::addRefsForPhysRegMask(regMaskTP mask, LsraLocation currentLoc, RefType refType, bool isLastUse)
{
@@ -2758,6 +2772,8 @@ regMaskTP LinearScan::getKillSetForNode(GenTree* tree)
needFloatTmpForFPCall = true;
}
}
+#endif // _TARGET_X86_
+#if defined(_TARGET_X86_) || defined(_TARGET_ARM_)
if (tree->IsHelperCall())
{
GenTreeCall* call = tree->AsCall();
@@ -2765,7 +2781,7 @@ regMaskTP LinearScan::getKillSetForNode(GenTree* tree)
killMask = compiler->compHelperCallKillSet(helpFunc);
}
else
-#endif // _TARGET_X86_
+#endif // defined(_TARGET_X86_) || defined(_TARGET_ARM_)
{
// if there is no FP used, we can ignore the FP kills
if (compiler->compFloatingPointUsed)
@@ -2782,9 +2798,6 @@ regMaskTP LinearScan::getKillSetForNode(GenTree* tree)
if (compiler->codeGen->gcInfo.gcIsWriteBarrierAsgNode(tree))
{
killMask = RBM_CALLEE_TRASH_NOGC;
-#if !NOGC_WRITE_BARRIERS && (defined(_TARGET_ARM_) || defined(_TARGET_AMD64_))
- killMask |= (RBM_ARG_0 | RBM_ARG_1);
-#endif // !NOGC_WRITE_BARRIERS && (defined(_TARGET_ARM_) || defined(_TARGET_AMD64_))
}
break;
@@ -3030,7 +3043,6 @@ void LinearScan::buildInternalRegisterUsesForNode(GenTree* tree,
{
RefPosition* newest = newRefPosition(defs[i]->getInterval(), currentLoc, RefTypeUse, tree, mask,
0 DEBUG_ARG(minRegCandidateCount));
- newest->lastUse = true;
if (tree->gtLsraInfo.isInternalRegDelayFree)
{
@@ -3549,8 +3561,6 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
}
RefPosition* pos = newRefPosition(interval, currentLoc, RefTypeUse, tree, candidates);
pos->isLocalDefUse = true;
- bool isLastUse = ((tree->gtFlags & GTF_VAR_DEATH) != 0);
- pos->lastUse = isLastUse;
pos->setAllocateIfProfitable(tree->IsRegOptional());
DBEXEC(VERBOSE, pos->dump());
return;
@@ -3566,6 +3576,39 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
}
#endif // DEBUG
+ const bool isContainedNode = !info.isLocalDefUse && consume == 0 && produce == 0 && tree->canBeContained();
+ if (isContainedNode)
+ {
+ assert(info.internalIntCount == 0);
+ assert(info.internalFloatCount == 0);
+
+ // Contained nodes map to the concatenated lists of their operands.
+ LocationInfoList locationInfoList;
+ for (GenTree* op : tree->Operands())
+ {
+ if (!op->gtLsraInfo.definesAnyRegisters)
+ {
+ assert(ComputeOperandDstCount(op) == 0);
+ continue;
+ }
+
+ LocationInfoList operandList;
+ bool removed = operandToLocationInfoMap.TryRemove(op, &operandList);
+ assert(removed);
+
+ locationInfoList.Append(operandList);
+ }
+
+ if (!locationInfoList.IsEmpty())
+ {
+ bool added = operandToLocationInfoMap.AddOrUpdate(tree, locationInfoList);
+ assert(added);
+ tree->gtLsraInfo.definesAnyRegisters = true;
+ }
+
+ return;
+ }
+
// Handle the case of local variable assignment
Interval* varDefInterval = nullptr;
RefType defRefType = RefTypeDef;
@@ -3851,31 +3894,28 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
}
#endif // FEATURE_SIMD
- bool delayRegFree = (hasDelayFreeSrc && useNode->gtLsraInfo.isDelayFree);
if (useNode->gtLsraInfo.isTgtPref)
{
prefSrcInterval = i;
}
- bool regOptionalAtUse = useNode->IsRegOptional();
- bool isLastUse = true;
- if (isCandidateLocalRef(useNode))
+ regMaskTP fixedAssignment = fixedCandidateMask(type, candidates);
+ if (fixedAssignment != RBM_NONE)
{
- isLastUse = ((useNode->gtFlags & GTF_VAR_DEATH) != 0);
+ candidates = fixedAssignment;
}
- else
+
+ const bool regOptionalAtUse = useNode->IsRegOptional();
+ const bool delayRegFree = (hasDelayFreeSrc && useNode->gtLsraInfo.isDelayFree);
+
+ assert(isCandidateLocalRef(useNode) == i->isLocalVar);
+ if (!i->isLocalVar)
{
// For non-localVar uses we record nothing,
// as nothing needs to be written back to the tree.
useNode = nullptr;
}
- regMaskTP fixedAssignment = fixedCandidateMask(type, candidates);
- if (fixedAssignment != RBM_NONE)
- {
- candidates = fixedAssignment;
- }
-
#ifdef DEBUG
// If delayRegFree, then Use will interfere with the destination of
// the consuming node. Therefore, we also need add the kill set of
@@ -3936,11 +3976,6 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
pos->delayRegFree = true;
}
- if (isLastUse)
- {
- pos->lastUse = true;
- }
-
if (regOptionalAtUse)
{
pos->setAllocateIfProfitable(1);
@@ -3973,8 +4008,6 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
#if defined(_TARGET_AMD64_)
// Multi-reg call node is the only node that could produce multi-reg value
assert(produce <= 1 || (tree->IsMultiRegCall() && produce == MAX_RET_REG_COUNT));
-#elif defined(_TARGET_ARM_)
- assert(!varTypeIsMultiReg(tree->TypeGet()));
#endif // _TARGET_xxx_
// Add kill positions before adding def positions
@@ -4074,27 +4107,6 @@ void LinearScan::buildRefPositionsForNode(GenTree* tree,
buildUpperVectorRestoreRefPositions(tree, defLocation, liveLargeVectors);
#endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
- bool isContainedNode = !noAdd && consume == 0 && produce == 0 &&
- (tree->OperIsFieldListHead() || ((tree->TypeGet() != TYP_VOID) && !tree->OperIsStore()));
- if (isContainedNode)
- {
- // Contained nodes map to the concatenated lists of their operands.
- for (GenTree* op : tree->Operands())
- {
- if (!op->gtLsraInfo.definesAnyRegisters)
- {
- assert(ComputeOperandDstCount(op) == 0);
- continue;
- }
-
- LocationInfoList operandList;
- bool removed = operandToLocationInfoMap.TryRemove(op, &operandList);
- assert(removed);
-
- locationInfoList.Append(operandList);
- }
- }
-
if (!locationInfoList.IsEmpty())
{
bool added = operandToLocationInfoMap.AddOrUpdate(tree, locationInfoList);
@@ -4716,15 +4728,27 @@ void LinearScan::buildIntervals()
JITDUMP("\n");
}
- // Identify the last uses of each variable, except in the case of MinOpts, where all vars
- // are kept live everywhere.
-
- if (!compiler->opts.MinOpts())
+ // Clear the "last use" flag on any vars that are live-out from this block.
{
- setLastUses(block);
+ VARSET_ITER_INIT(compiler, iter, block->bbLiveOut, varIndex);
+ while (iter.NextElem(compiler, &varIndex))
+ {
+ unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
+ LclVarDsc* const varDsc = &compiler->lvaTable[varNum];
+ if (isCandidateVar(varDsc))
+ {
+ RefPosition* const lastRP = getIntervalForLocalVar(varNum)->lastRefPosition;
+ if ((lastRP != nullptr) && (lastRP->bbNum == block->bbNum))
+ {
+ lastRP->lastUse = false;
+ }
+ }
+ }
}
#ifdef DEBUG
+ checkLastUses(block);
+
if (VERBOSE)
{
printf("use: ");
@@ -7669,6 +7693,22 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTreePtr treeNode, RefPosi
interval->recentRefPosition = currentRefPosition;
LclVarDsc* varDsc = interval->getLocalVar(compiler);
+ // NOTE: we set the GTF_VAR_DEATH flag here unless we are extending lifetimes, in which case we write
+ // this bit in checkLastUses. This is a bit of a hack, but is necessary because codegen requires
+ // accurate last use info that is not reflected in the lastUse bit on ref positions when we are extending
+ // lifetimes. See also the comments in checkLastUses.
+ if ((treeNode != nullptr) && !extendLifetimes())
+ {
+ if (currentRefPosition->lastUse)
+ {
+ treeNode->gtFlags |= GTF_VAR_DEATH;
+ }
+ else
+ {
+ treeNode->gtFlags &= ~GTF_VAR_DEATH;
+ }
+ }
+
if (currentRefPosition->registerAssignment == RBM_NONE)
{
assert(!currentRefPosition->RequiresRegister());
diff --git a/src/jit/lsra.h b/src/jit/lsra.h
index c8a3fb4e24..b6f83792a7 100644
--- a/src/jit/lsra.h
+++ b/src/jit/lsra.h
@@ -681,7 +681,9 @@ private:
void buildPhysRegRecords();
- void setLastUses(BasicBlock* block);
+#ifdef DEBUG
+ void checkLastUses(BasicBlock* block);
+#endif // DEBUG
void setFrameType();
@@ -744,6 +746,9 @@ private:
TreeNodeInfo& info = tree->gtLsraInfo;
info.srcCount = 0;
info.dstCount = 0;
+
+ info.internalIntCount = 0;
+ info.internalFloatCount = 0;
}
inline bool isLocalDefUse(GenTree* tree)
diff --git a/src/jit/lsraarm.cpp b/src/jit/lsraarm.cpp
index 57f0096b35..e35e57908a 100644
--- a/src/jit/lsraarm.cpp
+++ b/src/jit/lsraarm.cpp
@@ -30,251 +30,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "lsra.h"
//------------------------------------------------------------------------
-// TreeNodeInfoInitStoreLoc: Lower a store of a lclVar
-//
-// Arguments:
-// storeLoc - the local store (GT_STORE_LCL_FLD or GT_STORE_LCL_VAR)
-//
-// Notes:
-// This involves:
-// - Setting the appropriate candidates for a store of a multi-reg call return value.
-// - Handling of contained immediates and widening operations of unsigneds.
-//
-void Lowering::TreeNodeInfoInitStoreLoc(GenTreeLclVarCommon* storeLoc)
-{
- TreeNodeInfo* info = &(storeLoc->gtLsraInfo);
-
- // Is this the case of var = call where call is returning
- // a value in multiple return registers?
- GenTree* op1 = storeLoc->gtGetOp1();
- if (op1->IsMultiRegCall())
- {
- // backend expects to see this case only for store lclvar.
- assert(storeLoc->OperGet() == GT_STORE_LCL_VAR);
-
- // srcCount = number of registers in which the value is returned by call
- GenTreeCall* call = op1->AsCall();
- ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
- info->srcCount = retTypeDesc->GetReturnRegCount();
-
- // Call node srcCandidates = Bitwise-OR(allregs(GetReturnRegType(i))) for all i=0..RetRegCount-1
- regMaskTP srcCandidates = m_lsra->allMultiRegCallNodeRegs(call);
- op1->gtLsraInfo.setSrcCandidates(m_lsra, srcCandidates);
- return;
- }
-
- CheckImmedAndMakeContained(storeLoc, op1);
-}
-
-//------------------------------------------------------------------------
-// TreeNodeInfoInitCmp: Lower a GT comparison node.
-//
-// Arguments:
-// tree - the node to lower
-//
-// Return Value:
-// None.
-//
-void Lowering::TreeNodeInfoInitCmp(GenTreePtr tree)
-{
- TreeNodeInfo* info = &(tree->gtLsraInfo);
-
- info->srcCount = 2;
- info->dstCount = 1;
- CheckImmedAndMakeContained(tree, tree->gtOp.gtOp2);
-}
-
-//------------------------------------------------------------------------
-// TreeNodeInfoInitGCWriteBarrier: GC lowering helper.
-//
-// Arguments:
-// tree - the node to lower
-//
-// Return Value:
-// None.
-//
-void Lowering::TreeNodeInfoInitGCWriteBarrier(GenTree* tree)
-{
- GenTreePtr dst = tree;
- GenTreePtr addr = tree->gtOp.gtOp1;
- GenTreePtr src = tree->gtOp.gtOp2;
-
- if (addr->OperGet() == GT_LEA)
- {
- // In the case where we are doing a helper assignment, if the dst
- // is an indir through an lea, we need to actually instantiate the
- // lea in a register
- GenTreeAddrMode* lea = addr->AsAddrMode();
-
- short leaSrcCount = 0;
- if (lea->Base() != nullptr)
- {
- leaSrcCount++;
- }
- if (lea->Index() != nullptr)
- {
- leaSrcCount++;
- }
- lea->gtLsraInfo.srcCount = leaSrcCount;
- lea->gtLsraInfo.dstCount = 1;
- }
-
-#if NOGC_WRITE_BARRIERS
- NYI_ARM("NOGC_WRITE_BARRIERS");
-#else
- // For the standard JIT Helper calls
- // op1 goes into REG_ARG_0 and
- // op2 goes into REG_ARG_1
- //
- addr->gtLsraInfo.setSrcCandidates(m_lsra, RBM_ARG_0);
- src->gtLsraInfo.setSrcCandidates(m_lsra, RBM_ARG_1);
-#endif // NOGC_WRITE_BARRIERS
-
- // Both src and dst must reside in a register, which they should since we haven't set
- // either of them as contained.
- assert(addr->gtLsraInfo.dstCount == 1);
- assert(src->gtLsraInfo.dstCount == 1);
-}
-
-//------------------------------------------------------------------------
-// TreeNodeInfoInitIndir: Specify register requirements for address expression
-// of an indirection operation.
-//
-// Arguments:
-// indirTree - GT_IND, GT_STOREIND, block node or GT_NULLCHECK gentree node
-//
-void Lowering::TreeNodeInfoInitIndir(GenTreePtr indirTree)
-{
- assert(indirTree->OperIsIndir());
- // If this is the rhs of a block copy (i.e. non-enregisterable struct),
- // it has no register requirements.
- if (indirTree->TypeGet() == TYP_STRUCT)
- {
- return;
- }
-
- GenTreePtr addr = indirTree->gtGetOp1();
- TreeNodeInfo* info = &(indirTree->gtLsraInfo);
-
- GenTreePtr base = nullptr;
- GenTreePtr index = nullptr;
- unsigned cns = 0;
- unsigned mul;
- bool rev;
- bool modifiedSources = false;
-
- if ((addr->OperGet() == GT_LEA) && IsSafeToContainMem(indirTree, addr))
- {
- GenTreeAddrMode* lea = addr->AsAddrMode();
- base = lea->Base();
- index = lea->Index();
- cns = lea->gtOffset;
-
- m_lsra->clearOperandCounts(addr);
- // The srcCount is decremented because addr is now "contained",
- // then we account for the base and index below, if they are non-null.
- info->srcCount--;
- }
- else if (comp->codeGen->genCreateAddrMode(addr, -1, true, 0, &rev, &base, &index, &mul, &cns, true /*nogen*/) &&
- !(modifiedSources = AreSourcesPossiblyModifiedLocals(indirTree, base, index)))
- {
- // An addressing mode will be constructed that may cause some
- // nodes to not need a register, and cause others' lifetimes to be extended
- // to the GT_IND or even its parent if it's an assignment
-
- assert(base != addr);
- m_lsra->clearOperandCounts(addr);
-
- GenTreePtr arrLength = nullptr;
-
- // Traverse the computation below GT_IND to find the operands
- // for the addressing mode, marking the various constants and
- // intermediate results as not consuming/producing.
- // If the traversal were more complex, we might consider using
- // a traversal function, but the addressing mode is only made
- // up of simple arithmetic operators, and the code generator
- // only traverses one leg of each node.
-
- bool foundBase = (base == nullptr);
- bool foundIndex = (index == nullptr);
- GenTreePtr nextChild = nullptr;
- for (GenTreePtr child = addr; child != nullptr && !child->OperIsLeaf(); child = nextChild)
- {
- nextChild = nullptr;
- GenTreePtr op1 = child->gtOp.gtOp1;
- GenTreePtr op2 = (child->OperIsBinary()) ? child->gtOp.gtOp2 : nullptr;
-
- if (op1 == base)
- {
- foundBase = true;
- }
- else if (op1 == index)
- {
- foundIndex = true;
- }
- else
- {
- m_lsra->clearOperandCounts(op1);
- if (!op1->OperIsLeaf())
- {
- nextChild = op1;
- }
- }
-
- if (op2 != nullptr)
- {
- if (op2 == base)
- {
- foundBase = true;
- }
- else if (op2 == index)
- {
- foundIndex = true;
- }
- else
- {
- m_lsra->clearOperandCounts(op2);
- if (!op2->OperIsLeaf())
- {
- assert(nextChild == nullptr);
- nextChild = op2;
- }
- }
- }
- }
- assert(foundBase && foundIndex);
- info->srcCount--; // it gets incremented below.
- }
- else if (addr->gtOper == GT_ARR_ELEM)
- {
- // The GT_ARR_ELEM consumes all the indices and produces the offset.
- // The array object lives until the mem access.
- // We also consume the target register to which the address is
- // computed
-
- info->srcCount++;
- assert(addr->gtLsraInfo.srcCount >= 2);
- addr->gtLsraInfo.srcCount -= 1;
- }
- else
- {
- // it is nothing but a plain indir
- info->srcCount--; // base gets added in below
- base = addr;
- }
-
- if (base != nullptr)
- {
- info->srcCount++;
- }
-
- if (index != nullptr && !modifiedSources)
- {
- info->srcCount++;
- }
-}
-
-//------------------------------------------------------------------------
// TreeNodeInfoInitReturn: Set the NodeInfo for a GT_RETURN.
//
// Arguments:
@@ -289,375 +44,158 @@ void Lowering::TreeNodeInfoInitReturn(GenTree* tree)
LinearScan* l = m_lsra;
Compiler* compiler = comp;
- GenTree* op1 = tree->gtGetOp1();
- regMaskTP useCandidates = RBM_NONE;
-
- info->srcCount = (tree->TypeGet() == TYP_VOID) ? 0 : 1;
- info->dstCount = 0;
-
- if (varTypeIsStruct(tree))
- {
- NYI_ARM("struct return");
- }
- else
- {
- // Non-struct type return - determine useCandidates
- switch (tree->TypeGet())
- {
- case TYP_VOID:
- useCandidates = RBM_NONE;
- break;
- case TYP_FLOAT:
- useCandidates = RBM_FLOATRET;
- break;
- case TYP_DOUBLE:
- useCandidates = RBM_DOUBLERET;
- break;
- case TYP_LONG:
- useCandidates = RBM_LNGRET;
- break;
- default:
- useCandidates = RBM_INTRET;
- break;
- }
- }
-
- if (useCandidates != RBM_NONE)
- {
- tree->gtOp.gtOp1->gtLsraInfo.setSrcCandidates(l, useCandidates);
- }
-}
-
-//------------------------------------------------------------------------
-// TreeNodeInfoInitCall: Set the NodeInfo for a call.
-//
-// Arguments:
-// call - The call node of interest
-//
-// Return Value:
-// None.
-//
-void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
-{
- TreeNodeInfo* info = &(call->gtLsraInfo);
- LinearScan* l = m_lsra;
- Compiler* compiler = comp;
- bool hasMultiRegRetVal = false;
- ReturnTypeDesc* retTypeDesc = nullptr;
-
- info->srcCount = 0;
- if (call->TypeGet() != TYP_VOID)
- {
- hasMultiRegRetVal = call->HasMultiRegRetVal();
- if (hasMultiRegRetVal)
- {
- // dst count = number of registers in which the value is returned by call
- retTypeDesc = call->GetReturnTypeDesc();
- info->dstCount = retTypeDesc->GetReturnRegCount();
- }
- else
- {
- info->dstCount = 1;
- }
- }
- else
+ if (tree->TypeGet() == TYP_LONG)
{
+ GenTree* op1 = tree->gtGetOp1();
+ noway_assert(op1->OperGet() == GT_LONG);
+ GenTree* loVal = op1->gtGetOp1();
+ GenTree* hiVal = op1->gtGetOp2();
+ info->srcCount = 2;
+ loVal->gtLsraInfo.setSrcCandidates(l, RBM_LNGRET_LO);
+ hiVal->gtLsraInfo.setSrcCandidates(l, RBM_LNGRET_HI);
info->dstCount = 0;
}
-
- GenTree* ctrlExpr = call->gtControlExpr;
- if (call->gtCallType == CT_INDIRECT)
- {
- // either gtControlExpr != null or gtCallAddr != null.
- // Both cannot be non-null at the same time.
- assert(ctrlExpr == nullptr);
- assert(call->gtCallAddr != nullptr);
- ctrlExpr = call->gtCallAddr;
- }
-
- // set reg requirements on call target represented as control sequence.
- if (ctrlExpr != nullptr)
- {
- // we should never see a gtControlExpr whose type is void.
- assert(ctrlExpr->TypeGet() != TYP_VOID);
-
- info->srcCount++;
- // In case of fast tail implemented as jmp, make sure that gtControlExpr is
- // computed into a register.
- if (call->IsFastTailCall())
- {
- NYI_ARM("tail call");
- }
- }
- else
- {
- info->internalIntCount = 1;
- }
-
- RegisterType registerType = call->TypeGet();
-
- // Set destination candidates for return value of the call.
- if (hasMultiRegRetVal)
- {
- assert(retTypeDesc != nullptr);
- info->setDstCandidates(l, retTypeDesc->GetABIReturnRegs());
- }
- else if (varTypeIsFloating(registerType))
- {
- info->setDstCandidates(l, RBM_FLOATRET);
- }
- else if (registerType == TYP_LONG)
- {
- info->setDstCandidates(l, RBM_LNGRET);
- }
else
{
- info->setDstCandidates(l, RBM_INTRET);
- }
-
- // If there is an explicit this pointer, we don't want that node to produce anything
- // as it is redundant
- if (call->gtCallObjp != nullptr)
- {
- GenTreePtr thisPtrNode = call->gtCallObjp;
-
- if (thisPtrNode->gtOper == GT_PUTARG_REG)
- {
- l->clearOperandCounts(thisPtrNode);
- l->clearDstCount(thisPtrNode->gtOp.gtOp1);
- }
- else
- {
- l->clearDstCount(thisPtrNode);
- }
- }
-
- // First, count reg args
- bool callHasFloatRegArgs = false;
-
- for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext())
- {
- assert(list->OperIsList());
-
- GenTreePtr argNode = list->Current();
-
- fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, argNode);
- assert(curArgTabEntry);
-
- if (curArgTabEntry->regNum == REG_STK)
- {
- // late arg that is not passed in a register
- assert(argNode->gtOper == GT_PUTARG_STK);
-
- TreeNodeInfoInitPutArgStk(argNode->AsPutArgStk(), curArgTabEntry);
- continue;
- }
-
- var_types argType = argNode->TypeGet();
- bool argIsFloat = varTypeIsFloating(argType);
- callHasFloatRegArgs |= argIsFloat;
-
- regNumber argReg = curArgTabEntry->regNum;
- // We will setup argMask to the set of all registers that compose this argument
- regMaskTP argMask = 0;
+ GenTree* op1 = tree->gtGetOp1();
+ regMaskTP useCandidates = RBM_NONE;
- argNode = argNode->gtEffectiveVal();
+ info->srcCount = (tree->TypeGet() == TYP_VOID) ? 0 : 1;
+ info->dstCount = 0;
- // A GT_FIELD_LIST has a TYP_VOID, but is used to represent a multireg struct
- if (varTypeIsStruct(argNode) || (argNode->gtOper == GT_FIELD_LIST))
+ if (varTypeIsStruct(tree))
{
- GenTreePtr actualArgNode = argNode;
- unsigned originalSize = 0;
-
- if (argNode->gtOper == GT_FIELD_LIST)
+ // op1 has to be either an lclvar or a multi-reg returning call
+ if (op1->OperGet() == GT_LCL_VAR)
{
- // There could be up to 2-4 PUTARG_REGs in the list (3 or 4 can only occur for HFAs)
- GenTreeFieldList* fieldListPtr = argNode->AsFieldList();
-
- // Initailize the first register and the first regmask in our list
- regNumber targetReg = argReg;
- regMaskTP targetMask = genRegMask(targetReg);
- unsigned iterationNum = 0;
- originalSize = 0;
+ GenTreeLclVarCommon* lclVarCommon = op1->AsLclVarCommon();
+ LclVarDsc* varDsc = &(compiler->lvaTable[lclVarCommon->gtLclNum]);
+ assert(varDsc->lvIsMultiRegRet);
- for (; fieldListPtr; fieldListPtr = fieldListPtr->Rest())
+ // Mark var as contained if not enregistrable.
+ if (!varTypeIsEnregisterableStruct(op1))
{
- GenTreePtr putArgRegNode = fieldListPtr->Current();
- assert(putArgRegNode->gtOper == GT_PUTARG_REG);
- GenTreePtr putArgChild = putArgRegNode->gtOp.gtOp1;
-
- originalSize += REGSIZE_BYTES; // 8 bytes
-
- // Record the register requirements for the GT_PUTARG_REG node
- putArgRegNode->gtLsraInfo.setDstCandidates(l, targetMask);
- putArgRegNode->gtLsraInfo.setSrcCandidates(l, targetMask);
-
- // To avoid redundant moves, request that the argument child tree be
- // computed in the register in which the argument is passed to the call.
- putArgChild->gtLsraInfo.setSrcCandidates(l, targetMask);
-
- // We consume one source for each item in this list
- info->srcCount++;
- iterationNum++;
-
- // Update targetReg and targetMask for the next putarg_reg (if any)
- targetReg = genRegArgNext(targetReg);
- targetMask = genRegMask(targetReg);
+ MakeSrcContained(tree, op1);
}
}
else
{
-#ifdef DEBUG
- compiler->gtDispTreeRange(BlockRange(), argNode);
-#endif
- noway_assert(!"Unsupported TYP_STRUCT arg kind");
- }
-
- unsigned slots = ((unsigned)(roundUp(originalSize, REGSIZE_BYTES))) / REGSIZE_BYTES;
- regNumber curReg = argReg;
- regNumber lastReg = argIsFloat ? REG_ARG_FP_LAST : REG_ARG_LAST;
- unsigned remainingSlots = slots;
-
- while (remainingSlots > 0)
- {
- argMask |= genRegMask(curReg);
- remainingSlots--;
-
- if (curReg == lastReg)
- break;
+ noway_assert(op1->IsMultiRegCall());
- curReg = genRegArgNext(curReg);
+ ReturnTypeDesc* retTypeDesc = op1->AsCall()->GetReturnTypeDesc();
+ info->srcCount = retTypeDesc->GetReturnRegCount();
+ useCandidates = retTypeDesc->GetABIReturnRegs();
}
-
- // Struct typed arguments must be fully passed in registers (Reg/Stk split not allowed)
- noway_assert(remainingSlots == 0);
- argNode->gtLsraInfo.internalIntCount = 0;
}
- else // A scalar argument (not a struct)
+ else
{
- // We consume one source
- info->srcCount++;
-
- argMask |= genRegMask(argReg);
- argNode->gtLsraInfo.setDstCandidates(l, argMask);
- argNode->gtLsraInfo.setSrcCandidates(l, argMask);
-
- if (argNode->gtOper == GT_PUTARG_REG)
+ // Non-struct type return - determine useCandidates
+ switch (tree->TypeGet())
{
- GenTreePtr putArgChild = argNode->gtOp.gtOp1;
-
- // To avoid redundant moves, request that the argument child tree be
- // computed in the register in which the argument is passed to the call.
- putArgChild->gtLsraInfo.setSrcCandidates(l, argMask);
+ case TYP_VOID:
+ useCandidates = RBM_NONE;
+ break;
+ case TYP_FLOAT:
+ useCandidates = RBM_FLOATRET;
+ break;
+ case TYP_DOUBLE:
+ useCandidates = RBM_DOUBLERET;
+ break;
+ case TYP_LONG:
+ useCandidates = RBM_LNGRET;
+ break;
+ default:
+ useCandidates = RBM_INTRET;
+ break;
}
}
- }
- // Now, count stack args
- // Note that these need to be computed into a register, but then
- // they're just stored to the stack - so the reg doesn't
- // need to remain live until the call. In fact, it must not
- // because the code generator doesn't actually consider it live,
- // so it can't be spilled.
-
- GenTreePtr args = call->gtCallArgs;
- while (args)
- {
- GenTreePtr arg = args->gtOp.gtOp1;
-
- // Skip arguments that have been moved to the Late Arg list
- if (!(args->gtFlags & GTF_LATE_ARG))
+ if (useCandidates != RBM_NONE)
{
- if (arg->gtOper == GT_PUTARG_STK)
- {
- fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, arg);
- assert(curArgTabEntry);
-
- assert(curArgTabEntry->regNum == REG_STK);
-
- TreeNodeInfoInitPutArgStk(arg->AsPutArgStk(), curArgTabEntry);
- }
- else
- {
- TreeNodeInfo* argInfo = &(arg->gtLsraInfo);
- if (argInfo->dstCount != 0)
- {
- argInfo->isLocalDefUse = true;
- }
-
- argInfo->dstCount = 0;
- }
+ tree->gtOp.gtOp1->gtLsraInfo.setSrcCandidates(l, useCandidates);
}
- args = args->gtOp.gtOp2;
- }
-
- if (call->IsVarargs() && callHasFloatRegArgs && !call->IsFastTailCall() && (ctrlExpr != nullptr))
- {
- NYI_ARM("float reg varargs");
}
}
-//------------------------------------------------------------------------
-// TreeNodeInfoInitPutArgStk: Set the NodeInfo for a GT_PUTARG_STK node
-//
-// Arguments:
-// argNode - a GT_PUTARG_STK node
-//
-// Return Value:
-// None.
-//
-// Notes:
-// Set the child node(s) to be contained when we have a multireg arg
-//
-void Lowering::TreeNodeInfoInitPutArgStk(GenTreePutArgStk* argNode, fgArgTabEntryPtr info)
+void Lowering::TreeNodeInfoInitLclHeap(GenTree* tree)
{
- assert(argNode->gtOper == GT_PUTARG_STK);
+ TreeNodeInfo* info = &(tree->gtLsraInfo);
+ LinearScan* l = m_lsra;
+ Compiler* compiler = comp;
- GenTreePtr putArgChild = argNode->gtOp.gtOp1;
+ info->srcCount = 1;
+ info->dstCount = 1;
- // Initialize 'argNode' as not contained, as this is both the default case
- // and how MakeSrcContained expects to find things setup.
+ // Need a variable number of temp regs (see genLclHeap() in codegenarm.cpp):
+ // Here '-' means don't care.
//
- argNode->gtLsraInfo.srcCount = 1;
- argNode->gtLsraInfo.dstCount = 0;
+ // Size? Init Memory? # temp regs
+ // 0 - 0
+ // const and <=4 ptr words - hasPspSym ? 1 : 0
+ // const and <PageSize No hasPspSym ? 1 : 0
+ // >4 ptr words Yes hasPspSym ? 2 : 1
+ // Non-const Yes hasPspSym ? 2 : 1
+ // Non-const No hasPspSym ? 2 : 1
+
+ bool hasPspSym;
+#if FEATURE_EH_FUNCLETS
+ hasPspSym = (compiler->lvaPSPSym != BAD_VAR_NUM);
+#else
+ hasPspSym = false;
+#endif
- // Do we have a TYP_STRUCT argument (or a GT_FIELD_LIST), if so it must be a multireg pass-by-value struct
- if ((putArgChild->TypeGet() == TYP_STRUCT) || (putArgChild->OperGet() == GT_FIELD_LIST))
+ GenTreePtr size = tree->gtOp.gtOp1;
+ if (size->IsCnsIntOrI())
{
- // We will use store instructions that each write a register sized value
+ MakeSrcContained(tree, size);
- if (putArgChild->OperGet() == GT_FIELD_LIST)
+ size_t sizeVal = size->gtIntCon.gtIconVal;
+ if (sizeVal == 0)
{
- // We consume all of the items in the GT_FIELD_LIST
- argNode->gtLsraInfo.srcCount = info->numSlots;
+ info->internalIntCount = 0;
}
else
{
- // We could use a ldp/stp sequence so we need two internal registers
- argNode->gtLsraInfo.internalIntCount = 2;
+ sizeVal = AlignUp(sizeVal, STACK_ALIGN);
+ size_t cntStackAlignedWidthItems = (sizeVal >> STACK_ALIGN_SHIFT);
- if (putArgChild->OperGet() == GT_OBJ)
+ // For small allocations up to 4 store instructions
+ if (cntStackAlignedWidthItems <= 4)
+ {
+ info->internalIntCount = 0;
+ }
+ else if (!compiler->info.compInitMem)
{
- GenTreePtr objChild = putArgChild->gtOp.gtOp1;
- if (objChild->OperGet() == GT_LCL_VAR_ADDR)
+ // No need to initialize allocated stack space.
+ if (sizeVal < compiler->eeGetPageSize())
{
- // We will generate all of the code for the GT_PUTARG_STK, the GT_OBJ and the GT_LCL_VAR_ADDR
- // as one contained operation
- //
- MakeSrcContained(putArgChild, objChild);
+ info->internalIntCount = 0;
}
+ else
+ {
+ // target (regCnt) + tmp + [psp]
+ info->internalIntCount = 1;
+ info->isInternalRegDelayFree = true;
+ }
+ }
+ else
+ {
+ // target (regCnt) + tmp + [psp]
+ info->internalIntCount = 1;
+ info->isInternalRegDelayFree = true;
}
- // We will generate all of the code for the GT_PUTARG_STK and it's child node
- // as one contained operation
- //
- MakeSrcContained(argNode, putArgChild);
+ if (hasPspSym)
+ {
+ info->internalIntCount++;
+ }
}
}
else
{
- // We must not have a multi-reg struct
- assert(info->numSlots == 1);
+ // target (regCnt) + tmp + [psp]
+ info->internalIntCount = hasPspSym ? 2 : 1;
+ info->isInternalRegDelayFree = true;
}
}
@@ -689,6 +227,8 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
JITDUMP("TreeNodeInfoInit for: ");
DISPNODE(tree);
+ NYI_IF(tree->TypeGet() == TYP_DOUBLE, "lowering double");
+
switch (tree->OperGet())
{
GenTree* op1;
@@ -696,7 +236,14 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
case GT_STORE_LCL_FLD:
case GT_STORE_LCL_VAR:
- info->srcCount = 1;
+ if (tree->gtGetOp1()->OperGet() == GT_LONG)
+ {
+ info->srcCount = 2;
+ }
+ else
+ {
+ info->srcCount = 1;
+ }
info->dstCount = 0;
LowerStoreLoc(tree->AsLclVarCommon());
TreeNodeInfoInitStoreLoc(tree->AsLclVarCommon());
@@ -767,9 +314,33 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
}
#endif // DEBUG
- if (tree->gtOverflow())
+ if (varTypeIsLong(castOpType))
{
- NYI_ARM("overflow checks");
+ noway_assert(castOp->OperGet() == GT_LONG);
+ info->srcCount = 2;
+ }
+
+ CastInfo castInfo;
+
+ // Get information about the cast.
+ getCastDescription(tree, &castInfo);
+
+ if (castInfo.requiresOverflowCheck)
+ {
+ var_types srcType = castOp->TypeGet();
+ emitAttr cmpSize = EA_ATTR(genTypeSize(srcType));
+
+ // If we cannot store the comparisons in an immediate for either
+ // comparing against the max or min value, then we will need to
+ // reserve a temporary register.
+
+ bool canStoreMaxValue = emitter::emitIns_valid_imm_for_cmp(castInfo.typeMax, INS_FLAGS_DONT_CARE);
+ bool canStoreMinValue = emitter::emitIns_valid_imm_for_cmp(castInfo.typeMin, INS_FLAGS_DONT_CARE);
+
+ if (!canStoreMaxValue || !canStoreMinValue)
+ {
+ info->internalIntCount = 1;
+ }
}
}
break;
@@ -799,9 +370,8 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
break;
case GT_SWITCH_TABLE:
- info->srcCount = 2;
- info->internalIntCount = 1;
- info->dstCount = 0;
+ info->srcCount = 2;
+ info->dstCount = 0;
break;
case GT_ASG:
@@ -812,6 +382,10 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
info->dstCount = 0;
break;
+ case GT_ADD_LO:
+ case GT_ADD_HI:
+ case GT_SUB_LO:
+ case GT_SUB_HI:
case GT_ADD:
case GT_SUB:
if (varTypeIsFloating(tree->TypeGet()))
@@ -840,6 +414,13 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
CheckImmedAndMakeContained(tree, tree->gtOp.gtOp2);
break;
+ case GT_RETURNTRAP:
+ // this just turns into a compare of its child with an int
+ // + a conditional call
+ info->srcCount = 1;
+ info->dstCount = 0;
+ break;
+
case GT_MUL:
if (tree->gtOverflow())
{
@@ -867,6 +448,21 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
info->dstCount = 0;
break;
+ case GT_LONG:
+ if ((tree->gtLIRFlags & LIR::Flags::IsUnusedValue) != 0)
+ {
+ // An unused GT_LONG node needs to consume its sources.
+ info->srcCount = 2;
+ }
+ else
+ {
+ // Passthrough
+ info->srcCount = 0;
+ }
+
+ info->dstCount = 0;
+ break;
+
case GT_CNS_DBL:
info->srcCount = 0;
info->dstCount = 1;
@@ -907,6 +503,54 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
}
break;
+ case GT_ARR_BOUNDS_CHECK:
+#ifdef FEATURE_SIMD
+ case GT_SIMD_CHK:
+#endif // FEATURE_SIMD
+ {
+ // Consumes arrLen & index - has no result
+ info->srcCount = 2;
+ info->dstCount = 0;
+ }
+ break;
+
+ case GT_ARR_ELEM:
+ // These must have been lowered to GT_ARR_INDEX
+ noway_assert(!"We should never see a GT_ARR_ELEM in lowering");
+ info->srcCount = 0;
+ info->dstCount = 0;
+ break;
+
+ case GT_ARR_INDEX:
+ info->srcCount = 2;
+ info->dstCount = 1;
+
+ // We need one internal register when generating code for GT_ARR_INDEX, however the
+ // register allocator always may just give us the same one as it gives us for the 'dst'
+ // as a workaround we will just ask for two internal registers.
+ //
+ info->internalIntCount = 2;
+
+ // For GT_ARR_INDEX, the lifetime of the arrObj must be extended because it is actually used multiple
+ // times while the result is being computed.
+ tree->AsArrIndex()->ArrObj()->gtLsraInfo.isDelayFree = true;
+ info->hasDelayFreeSrc = true;
+ break;
+
+ case GT_ARR_OFFSET:
+ // This consumes the offset, if any, the arrObj and the effective index,
+ // and produces the flattened offset for this dimension.
+ info->srcCount = 3;
+ info->dstCount = 1;
+ info->internalIntCount = 1;
+
+ // we don't want to generate code for this
+ if (tree->gtArrOffs.gtOffset->IsIntegralConst(0))
+ {
+ MakeSrcContained(tree, tree->gtArrOffs.gtOffset);
+ }
+ break;
+
case GT_LEA:
{
GenTreeAddrMode* lea = tree->AsAddrMode();
@@ -928,13 +572,17 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
}
info->dstCount = 1;
+ // On ARM we may need a single internal register
+ // (when both conditions are true then we still only need a single internal register)
if ((index != nullptr) && (cns != 0))
{
- NYI_ARM("GT_LEA: index and cns are not nil");
+ // ARM does not support both Index and offset so we need an internal register
+ info->internalIntCount = 1;
}
else if (!emitter::emitIns_valid_imm_for_add(cns, INS_FLAGS_DONT_CARE))
{
- NYI_ARM("GT_LEA: invalid imm");
+ // This offset can't be contained in the add instruction, so we need an internal register
+ info->internalIntCount = 1;
}
}
break;
@@ -953,19 +601,10 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
case GT_RSH:
case GT_RSZ:
case GT_ROR:
- {
- info->srcCount = 2;
- info->dstCount = 1;
-
- GenTreePtr shiftBy = tree->gtOp.gtOp2;
- GenTreePtr source = tree->gtOp.gtOp1;
- if (shiftBy->IsCnsIntOrI())
- {
- l->clearDstCount(shiftBy);
- info->srcCount--;
- }
- }
- break;
+ case GT_LSH_HI:
+ case GT_RSH_LO:
+ TreeNodeInfoInitShiftRotate(tree);
+ break;
case GT_EQ:
case GT_NE:
@@ -980,6 +619,17 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
TreeNodeInfoInitCall(tree->AsCall());
break;
+ case GT_STORE_BLK:
+ case GT_STORE_OBJ:
+ case GT_STORE_DYN_BLK:
+ LowerBlockStore(tree->AsBlk());
+ TreeNodeInfoInitBlockStore(tree->AsBlk());
+ break;
+
+ case GT_LCLHEAP:
+ TreeNodeInfoInitLclHeap(tree);
+ break;
+
case GT_STOREIND:
{
info->srcCount = 2;
@@ -1030,17 +680,27 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
default:
#ifdef DEBUG
- JitTls::GetCompiler()->gtDispTree(tree);
-#endif
+ char message[256];
+ _snprintf_s(message, _countof(message), _TRUNCATE, "NYI: Unimplemented node type %s",
+ GenTree::NodeName(tree->OperGet()));
+ NYIRAW(message);
+#else
NYI_ARM("TreeNodeInfoInit default case");
+#endif
case GT_LCL_FLD:
+ case GT_LCL_FLD_ADDR:
case GT_LCL_VAR:
case GT_LCL_VAR_ADDR:
+ case GT_PHYSREG:
case GT_CLS_VAR_ADDR:
case GT_IL_OFFSET:
case GT_CNS_INT:
case GT_PUTARG_REG:
case GT_PUTARG_STK:
+ case GT_LABEL:
+ case GT_PINVOKE_PROLOG:
+ case GT_JCC:
+ case GT_MEMORYBARRIER:
info->dstCount = tree->IsValue() ? 1 : 0;
if (kind & (GTK_CONST | GTK_LEAF))
{
diff --git a/src/jit/lsraarm64.cpp b/src/jit/lsraarm64.cpp
index 0db30e1811..3b2d465495 100644
--- a/src/jit/lsraarm64.cpp
+++ b/src/jit/lsraarm64.cpp
@@ -29,43 +29,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#include "lower.h"
//------------------------------------------------------------------------
-// TreeNodeInfoInitStoreLoc: Set register requirements for a store of a lclVar
-//
-// Arguments:
-// storeLoc - the local store (GT_STORE_LCL_FLD or GT_STORE_LCL_VAR)
-//
-// Notes:
-// This involves:
-// - Setting the appropriate candidates for a store of a multi-reg call return value.
-// - Handling of contained immediates.
-
-void Lowering::TreeNodeInfoInitStoreLoc(GenTreeLclVarCommon* storeLoc)
-{
- TreeNodeInfo* info = &(storeLoc->gtLsraInfo);
-
- // Is this the case of var = call where call is returning
- // a value in multiple return registers?
- GenTree* op1 = storeLoc->gtGetOp1();
- if (op1->IsMultiRegCall())
- {
- // backend expects to see this case only for store lclvar.
- assert(storeLoc->OperGet() == GT_STORE_LCL_VAR);
-
- // srcCount = number of registers in which the value is returned by call
- GenTreeCall* call = op1->AsCall();
- ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
- info->srcCount = retTypeDesc->GetReturnRegCount();
-
- // Call node srcCandidates = Bitwise-OR(allregs(GetReturnRegType(i))) for all i=0..RetRegCount-1
- regMaskTP srcCandidates = m_lsra->allMultiRegCallNodeRegs(call);
- op1->gtLsraInfo.setSrcCandidates(m_lsra, srcCandidates);
- return;
- }
-
- CheckImmedAndMakeContained(storeLoc, op1);
-}
-
-//------------------------------------------------------------------------
// TreeNodeInfoInit: Set the register requirements for RA.
//
// Notes:
@@ -435,19 +398,8 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
case GT_RSH:
case GT_RSZ:
case GT_ROR:
- {
- info->srcCount = 2;
- info->dstCount = 1;
-
- GenTreePtr shiftBy = tree->gtOp.gtOp2;
- GenTreePtr source = tree->gtOp.gtOp1;
- if (shiftBy->IsCnsIntOrI())
- {
- l->clearDstCount(shiftBy);
- info->srcCount--;
- }
- }
- break;
+ TreeNodeInfoInitShiftRotate(tree);
+ break;
case GT_EQ:
case GT_NE:
@@ -847,502 +799,6 @@ void Lowering::TreeNodeInfoInitReturn(GenTree* tree)
}
}
-//------------------------------------------------------------------------
-// TreeNodeInfoInitCall: Set the NodeInfo for a call.
-//
-// Arguments:
-// call - The call node of interest
-//
-// Return Value:
-// None.
-//
-void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
-{
- TreeNodeInfo* info = &(call->gtLsraInfo);
- LinearScan* l = m_lsra;
- Compiler* compiler = comp;
- bool hasMultiRegRetVal = false;
- ReturnTypeDesc* retTypeDesc = nullptr;
-
- info->srcCount = 0;
- if (call->TypeGet() != TYP_VOID)
- {
- hasMultiRegRetVal = call->HasMultiRegRetVal();
- if (hasMultiRegRetVal)
- {
- // dst count = number of registers in which the value is returned by call
- retTypeDesc = call->GetReturnTypeDesc();
- info->dstCount = retTypeDesc->GetReturnRegCount();
- }
- else
- {
- info->dstCount = 1;
- }
- }
- else
- {
- info->dstCount = 0;
- }
-
- GenTree* ctrlExpr = call->gtControlExpr;
- if (call->gtCallType == CT_INDIRECT)
- {
- // either gtControlExpr != null or gtCallAddr != null.
- // Both cannot be non-null at the same time.
- assert(ctrlExpr == nullptr);
- assert(call->gtCallAddr != nullptr);
- ctrlExpr = call->gtCallAddr;
- }
-
- // set reg requirements on call target represented as control sequence.
- if (ctrlExpr != nullptr)
- {
- // we should never see a gtControlExpr whose type is void.
- assert(ctrlExpr->TypeGet() != TYP_VOID);
-
- info->srcCount++;
-
- // In case of fast tail implemented as jmp, make sure that gtControlExpr is
- // computed into a register.
- if (call->IsFastTailCall())
- {
- // Fast tail call - make sure that call target is always computed in IP0
- // so that epilog sequence can generate "br xip0" to achieve fast tail call.
- ctrlExpr->gtLsraInfo.setSrcCandidates(l, genRegMask(REG_IP0));
- }
- }
-
- RegisterType registerType = call->TypeGet();
-
- // Set destination candidates for return value of the call.
- if (hasMultiRegRetVal)
- {
- assert(retTypeDesc != nullptr);
- info->setDstCandidates(l, retTypeDesc->GetABIReturnRegs());
- }
- else if (varTypeIsFloating(registerType))
- {
- info->setDstCandidates(l, RBM_FLOATRET);
- }
- else if (registerType == TYP_LONG)
- {
- info->setDstCandidates(l, RBM_LNGRET);
- }
- else
- {
- info->setDstCandidates(l, RBM_INTRET);
- }
-
- // If there is an explicit this pointer, we don't want that node to produce anything
- // as it is redundant
- if (call->gtCallObjp != nullptr)
- {
- GenTreePtr thisPtrNode = call->gtCallObjp;
-
- if (thisPtrNode->gtOper == GT_PUTARG_REG)
- {
- l->clearOperandCounts(thisPtrNode);
- l->clearDstCount(thisPtrNode->gtOp.gtOp1);
- }
- else
- {
- l->clearDstCount(thisPtrNode);
- }
- }
-
- // First, count reg args
- bool callHasFloatRegArgs = false;
-
- for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext())
- {
- assert(list->OperIsList());
-
- GenTreePtr argNode = list->Current();
-
- fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, argNode);
- assert(curArgTabEntry);
-
- if (curArgTabEntry->regNum == REG_STK)
- {
- // late arg that is not passed in a register
- assert(argNode->gtOper == GT_PUTARG_STK);
-
- TreeNodeInfoInitPutArgStk(argNode->AsPutArgStk(), curArgTabEntry);
- continue;
- }
-
- var_types argType = argNode->TypeGet();
- bool argIsFloat = varTypeIsFloating(argType);
- callHasFloatRegArgs |= argIsFloat;
-
- regNumber argReg = curArgTabEntry->regNum;
- // We will setup argMask to the set of all registers that compose this argument
- regMaskTP argMask = 0;
-
- argNode = argNode->gtEffectiveVal();
-
- // A GT_FIELD_LIST has a TYP_VOID, but is used to represent a multireg struct
- if (varTypeIsStruct(argNode) || (argNode->gtOper == GT_FIELD_LIST))
- {
- GenTreePtr actualArgNode = argNode;
- unsigned originalSize = 0;
-
- if (argNode->gtOper == GT_FIELD_LIST)
- {
- // There could be up to 2-4 PUTARG_REGs in the list (3 or 4 can only occur for HFAs)
- GenTreeFieldList* fieldListPtr = argNode->AsFieldList();
-
- // Initailize the first register and the first regmask in our list
- regNumber targetReg = argReg;
- regMaskTP targetMask = genRegMask(targetReg);
- unsigned iterationNum = 0;
- originalSize = 0;
-
- for (; fieldListPtr; fieldListPtr = fieldListPtr->Rest())
- {
- GenTreePtr putArgRegNode = fieldListPtr->Current();
- assert(putArgRegNode->gtOper == GT_PUTARG_REG);
- GenTreePtr putArgChild = putArgRegNode->gtOp.gtOp1;
-
- originalSize += REGSIZE_BYTES; // 8 bytes
-
- // Record the register requirements for the GT_PUTARG_REG node
- putArgRegNode->gtLsraInfo.setDstCandidates(l, targetMask);
- putArgRegNode->gtLsraInfo.setSrcCandidates(l, targetMask);
-
- // To avoid redundant moves, request that the argument child tree be
- // computed in the register in which the argument is passed to the call.
- putArgChild->gtLsraInfo.setSrcCandidates(l, targetMask);
-
- // We consume one source for each item in this list
- info->srcCount++;
- iterationNum++;
-
- // Update targetReg and targetMask for the next putarg_reg (if any)
- targetReg = genRegArgNext(targetReg);
- targetMask = genRegMask(targetReg);
- }
- }
- else
- {
-#ifdef DEBUG
- compiler->gtDispTreeRange(BlockRange(), argNode);
-#endif
- noway_assert(!"Unsupported TYP_STRUCT arg kind");
- }
-
- unsigned slots = ((unsigned)(roundUp(originalSize, REGSIZE_BYTES))) / REGSIZE_BYTES;
- regNumber curReg = argReg;
- regNumber lastReg = argIsFloat ? REG_ARG_FP_LAST : REG_ARG_LAST;
- unsigned remainingSlots = slots;
-
- while (remainingSlots > 0)
- {
- argMask |= genRegMask(curReg);
- remainingSlots--;
-
- if (curReg == lastReg)
- break;
-
- curReg = genRegArgNext(curReg);
- }
-
- // Struct typed arguments must be fully passed in registers (Reg/Stk split not allowed)
- noway_assert(remainingSlots == 0);
- argNode->gtLsraInfo.internalIntCount = 0;
- }
- else // A scalar argument (not a struct)
- {
- // We consume one source
- info->srcCount++;
-
- argMask |= genRegMask(argReg);
- argNode->gtLsraInfo.setDstCandidates(l, argMask);
- argNode->gtLsraInfo.setSrcCandidates(l, argMask);
-
- if (argNode->gtOper == GT_PUTARG_REG)
- {
- GenTreePtr putArgChild = argNode->gtOp.gtOp1;
-
- // To avoid redundant moves, request that the argument child tree be
- // computed in the register in which the argument is passed to the call.
- putArgChild->gtLsraInfo.setSrcCandidates(l, argMask);
- }
- }
- }
-
- // Now, count stack args
- // Note that these need to be computed into a register, but then
- // they're just stored to the stack - so the reg doesn't
- // need to remain live until the call. In fact, it must not
- // because the code generator doesn't actually consider it live,
- // so it can't be spilled.
-
- GenTreePtr args = call->gtCallArgs;
- while (args)
- {
- GenTreePtr arg = args->gtOp.gtOp1;
-
- // Skip arguments that have been moved to the Late Arg list
- if (!(args->gtFlags & GTF_LATE_ARG))
- {
- if (arg->gtOper == GT_PUTARG_STK)
- {
- fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, arg);
- assert(curArgTabEntry);
-
- assert(curArgTabEntry->regNum == REG_STK);
-
- TreeNodeInfoInitPutArgStk(arg->AsPutArgStk(), curArgTabEntry);
- }
- else
- {
- TreeNodeInfo* argInfo = &(arg->gtLsraInfo);
- if (argInfo->dstCount != 0)
- {
- argInfo->isLocalDefUse = true;
- }
-
- argInfo->dstCount = 0;
- }
- }
- args = args->gtOp.gtOp2;
- }
-
- // If it is a fast tail call, it is already preferenced to use IP0.
- // Therefore, no need set src candidates on call tgt again.
- if (call->IsVarargs() && callHasFloatRegArgs && !call->IsFastTailCall() && (ctrlExpr != nullptr))
- {
- // Don't assign the call target to any of the argument registers because
- // we will use them to also pass floating point arguments as required
- // by Arm64 ABI.
- ctrlExpr->gtLsraInfo.setSrcCandidates(l, l->allRegs(TYP_INT) & ~(RBM_ARG_REGS));
- }
-}
-
-//------------------------------------------------------------------------
-// TreeNodeInfoInitPutArgStk: Set the NodeInfo for a GT_PUTARG_STK node
-//
-// Arguments:
-// argNode - a GT_PUTARG_STK node
-//
-// Return Value:
-// None.
-//
-// Notes:
-// Set the child node(s) to be contained when we have a multireg arg
-//
-void Lowering::TreeNodeInfoInitPutArgStk(GenTreePutArgStk* argNode, fgArgTabEntryPtr info)
-{
- assert(argNode->gtOper == GT_PUTARG_STK);
-
- GenTreePtr putArgChild = argNode->gtOp.gtOp1;
-
- // Initialize 'argNode' as not contained, as this is both the default case
- // and how MakeSrcContained expects to find things setup.
- //
- argNode->gtLsraInfo.srcCount = 1;
- argNode->gtLsraInfo.dstCount = 0;
-
- // Do we have a TYP_STRUCT argument (or a GT_FIELD_LIST), if so it must be a multireg pass-by-value struct
- if ((putArgChild->TypeGet() == TYP_STRUCT) || (putArgChild->OperGet() == GT_FIELD_LIST))
- {
- // We will use store instructions that each write a register sized value
-
- if (putArgChild->OperGet() == GT_FIELD_LIST)
- {
- // We consume all of the items in the GT_FIELD_LIST
- argNode->gtLsraInfo.srcCount = info->numSlots;
- }
- else
- {
- // We could use a ldp/stp sequence so we need two internal registers
- argNode->gtLsraInfo.internalIntCount = 2;
-
- if (putArgChild->OperGet() == GT_OBJ)
- {
- GenTreePtr objChild = putArgChild->gtOp.gtOp1;
- if (objChild->OperGet() == GT_LCL_VAR_ADDR)
- {
- // We will generate all of the code for the GT_PUTARG_STK, the GT_OBJ and the GT_LCL_VAR_ADDR
- // as one contained operation
- //
- MakeSrcContained(putArgChild, objChild);
- }
- }
-
- // We will generate all of the code for the GT_PUTARG_STK and it's child node
- // as one contained operation
- //
- MakeSrcContained(argNode, putArgChild);
- }
- }
- else
- {
- // We must not have a multi-reg struct
- assert(info->numSlots == 1);
- }
-}
-
-//------------------------------------------------------------------------
-// TreeNodeInfoInitBlockStore: Set the NodeInfo for a block store.
-//
-// Arguments:
-// blkNode - The block store node of interest
-//
-// Return Value:
-// None.
-//
-// Notes:
-
-void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
-{
- GenTree* dstAddr = blkNode->Addr();
- unsigned size = blkNode->gtBlkSize;
- GenTree* source = blkNode->Data();
- LinearScan* l = m_lsra;
- Compiler* compiler = comp;
-
- // Sources are dest address and initVal or source.
- // We may require an additional source or temp register for the size.
- blkNode->gtLsraInfo.srcCount = 2;
- blkNode->gtLsraInfo.dstCount = 0;
- GenTreePtr srcAddrOrFill = nullptr;
- bool isInitBlk = blkNode->OperIsInitBlkOp();
-
- if (!isInitBlk)
- {
- // CopyObj or CopyBlk
- if (source->gtOper == GT_IND)
- {
- srcAddrOrFill = blkNode->Data()->gtGetOp1();
- // We're effectively setting source as contained, but can't call MakeSrcContained, because the
- // "inheritance" of the srcCount is to a child not a parent - it would "just work" but could be misleading.
- // If srcAddr is already non-contained, we don't need to change it.
- if (srcAddrOrFill->gtLsraInfo.getDstCount() == 0)
- {
- srcAddrOrFill->gtLsraInfo.setDstCount(1);
- srcAddrOrFill->gtLsraInfo.setSrcCount(source->gtLsraInfo.srcCount);
- }
- m_lsra->clearOperandCounts(source);
- }
- else if (!source->IsMultiRegCall() && !source->OperIsSIMD())
- {
- assert(source->IsLocal());
- MakeSrcContained(blkNode, source);
- }
- }
-
- if (isInitBlk)
- {
- GenTreePtr initVal = source;
- if (initVal->OperIsInitVal())
- {
- initVal = initVal->gtGetOp1();
- }
- srcAddrOrFill = initVal;
-
-#if 0
- if (blkNode->gtBlkOpKind == GenTreeBlk::BlkOpKindUnroll)
- {
- // TODO-ARM64-CQ: Currently we generate a helper call for every
- // initblk we encounter. Later on we should implement loop unrolling
- // code sequences to improve CQ.
- // For reference see the code in lsraxarch.cpp.
- }
- else
-#endif // 0
- {
- assert(blkNode->gtBlkOpKind == GenTreeBlk::BlkOpKindHelper);
- // The helper follows the regular ABI.
- dstAddr->gtLsraInfo.setSrcCandidates(l, RBM_ARG_0);
- initVal->gtLsraInfo.setSrcCandidates(l, RBM_ARG_1);
- if (size != 0)
- {
- // Reserve a temp register for the block size argument.
- blkNode->gtLsraInfo.setInternalCandidates(l, RBM_ARG_2);
- blkNode->gtLsraInfo.internalIntCount = 1;
- }
- else
- {
- // The block size argument is a third argument to GT_STORE_DYN_BLK
- noway_assert(blkNode->gtOper == GT_STORE_DYN_BLK);
- blkNode->gtLsraInfo.setSrcCount(3);
- GenTree* sizeNode = blkNode->AsDynBlk()->gtDynamicSize;
- sizeNode->gtLsraInfo.setSrcCandidates(l, RBM_ARG_2);
- }
- }
- }
- else
- {
- // CopyObj or CopyBlk
- // Sources are src and dest and size if not constant.
-
- if (blkNode->OperGet() == GT_STORE_OBJ)
- {
- // CopyObj
-
- // We don't need to materialize the struct size but we still need
- // a temporary register to perform the sequence of loads and stores.
- blkNode->gtLsraInfo.internalIntCount = 1;
-
- dstAddr->gtLsraInfo.setSrcCandidates(l, RBM_WRITE_BARRIER_DST_BYREF);
- // If we have a source address we want it in REG_WRITE_BARRIER_SRC_BYREF.
- // Otherwise, if it is a local, codegen will put its address in REG_WRITE_BARRIER_SRC_BYREF,
- // which is killed by a StoreObj (and thus needn't be reserved).
- if (srcAddrOrFill != nullptr)
- {
- srcAddrOrFill->gtLsraInfo.setSrcCandidates(l, RBM_WRITE_BARRIER_SRC_BYREF);
- }
- }
- else
- {
- // CopyBlk
- short internalIntCount = 0;
- regMaskTP internalIntCandidates = RBM_NONE;
-
-#if 0
- if (blkNode->gtBlkOpKind == GenTreeBlk::BlkOpKindUnroll)
- {
- // TODO-ARM64-CQ: cpblk loop unrolling is currently not implemented.
- // In case of a CpBlk with a constant size and less than CPBLK_UNROLL_LIMIT size
- // we should unroll the loop to improve CQ.
- // For reference see the code in lsraxarch.cpp.
- }
- else
-#endif // 0
- {
- assert(blkNode->gtBlkOpKind == GenTreeBlk::BlkOpKindHelper);
- dstAddr->gtLsraInfo.setSrcCandidates(l, RBM_ARG_0);
- // The srcAddr goes in arg1.
- if (srcAddrOrFill != nullptr)
- {
- srcAddrOrFill->gtLsraInfo.setSrcCandidates(l, RBM_ARG_1);
- }
- if (size != 0)
- {
- // Reserve a temp register for the block size argument.
- internalIntCandidates |= RBM_ARG_2;
- internalIntCount++;
- }
- else
- {
- // The block size argument is a third argument to GT_STORE_DYN_BLK
- noway_assert(blkNode->gtOper == GT_STORE_DYN_BLK);
- blkNode->gtLsraInfo.setSrcCount(3);
- GenTree* blockSize = blkNode->AsDynBlk()->gtDynamicSize;
- blockSize->gtLsraInfo.setSrcCandidates(l, RBM_ARG_2);
- }
- }
- if (internalIntCount != 0)
- {
- blkNode->gtLsraInfo.internalIntCount = internalIntCount;
- blkNode->gtLsraInfo.setInternalCandidates(l, internalIntCandidates);
- }
- }
- }
-}
-
#ifdef FEATURE_SIMD
//------------------------------------------------------------------------
// TreeNodeInfoInitSIMD: Set the NodeInfo for a GT_SIMD tree.
@@ -1544,223 +1000,6 @@ void Lowering::TreeNodeInfoInitSIMD(GenTree* tree)
}
#endif // FEATURE_SIMD
-void Lowering::TreeNodeInfoInitGCWriteBarrier(GenTree* tree)
-{
- GenTreePtr dst = tree;
- GenTreePtr addr = tree->gtOp.gtOp1;
- GenTreePtr src = tree->gtOp.gtOp2;
-
- if (addr->OperGet() == GT_LEA)
- {
- // In the case where we are doing a helper assignment, if the dst
- // is an indir through an lea, we need to actually instantiate the
- // lea in a register
- GenTreeAddrMode* lea = addr->AsAddrMode();
-
- short leaSrcCount = 0;
- if (lea->Base() != nullptr)
- {
- leaSrcCount++;
- }
- if (lea->Index() != nullptr)
- {
- leaSrcCount++;
- }
- lea->gtLsraInfo.srcCount = leaSrcCount;
- lea->gtLsraInfo.dstCount = 1;
- }
-
-#if NOGC_WRITE_BARRIERS
- // For the NOGC JIT Helper calls
- //
- // the 'addr' goes into x14 (REG_WRITE_BARRIER_DST_BYREF)
- // the 'src' goes into x15 (REG_WRITE_BARRIER)
- //
- addr->gtLsraInfo.setSrcCandidates(m_lsra, RBM_WRITE_BARRIER_DST_BYREF);
- src->gtLsraInfo.setSrcCandidates(m_lsra, RBM_WRITE_BARRIER);
-#else
- // For the standard JIT Helper calls
- // op1 goes into REG_ARG_0 and
- // op2 goes into REG_ARG_1
- //
- addr->gtLsraInfo.setSrcCandidates(m_lsra, RBM_ARG_0);
- src->gtLsraInfo.setSrcCandidates(m_lsra, RBM_ARG_1);
-#endif // NOGC_WRITE_BARRIERS
-
- // Both src and dst must reside in a register, which they should since we haven't set
- // either of them as contained.
- assert(addr->gtLsraInfo.dstCount == 1);
- assert(src->gtLsraInfo.dstCount == 1);
-}
-
-//-----------------------------------------------------------------------------------------
-// TreeNodeInfoInitIndir: Specify register requirements for address expression of an indirection operation.
-//
-// Arguments:
-// indirTree - GT_IND or GT_STOREIND gentree node
-//
-void Lowering::TreeNodeInfoInitIndir(GenTreePtr indirTree)
-{
- assert(indirTree->OperIsIndir());
- // If this is the rhs of a block copy (i.e. non-enregisterable struct),
- // it has no register requirements.
- if (indirTree->TypeGet() == TYP_STRUCT)
- {
- return;
- }
-
- GenTreePtr addr = indirTree->gtGetOp1();
- TreeNodeInfo* info = &(indirTree->gtLsraInfo);
-
- GenTreePtr base = nullptr;
- GenTreePtr index = nullptr;
- unsigned cns = 0;
- unsigned mul;
- bool rev;
- bool modifiedSources = false;
-
- if ((addr->OperGet() == GT_LEA) && IsSafeToContainMem(indirTree, addr))
- {
- GenTreeAddrMode* lea = addr->AsAddrMode();
- base = lea->Base();
- index = lea->Index();
- cns = lea->gtOffset;
-
- m_lsra->clearOperandCounts(addr);
- // The srcCount is decremented because addr is now "contained",
- // then we account for the base and index below, if they are non-null.
- info->srcCount--;
- }
- else if (comp->codeGen->genCreateAddrMode(addr, -1, true, 0, &rev, &base, &index, &mul, &cns, true /*nogen*/) &&
- !(modifiedSources = AreSourcesPossiblyModifiedLocals(indirTree, base, index)))
- {
- // An addressing mode will be constructed that may cause some
- // nodes to not need a register, and cause others' lifetimes to be extended
- // to the GT_IND or even its parent if it's an assignment
-
- assert(base != addr);
- m_lsra->clearOperandCounts(addr);
-
- GenTreePtr arrLength = nullptr;
-
- // Traverse the computation below GT_IND to find the operands
- // for the addressing mode, marking the various constants and
- // intermediate results as not consuming/producing.
- // If the traversal were more complex, we might consider using
- // a traversal function, but the addressing mode is only made
- // up of simple arithmetic operators, and the code generator
- // only traverses one leg of each node.
-
- bool foundBase = (base == nullptr);
- bool foundIndex = (index == nullptr);
- GenTreePtr nextChild = nullptr;
- for (GenTreePtr child = addr; child != nullptr && !child->OperIsLeaf(); child = nextChild)
- {
- nextChild = nullptr;
- GenTreePtr op1 = child->gtOp.gtOp1;
- GenTreePtr op2 = (child->OperIsBinary()) ? child->gtOp.gtOp2 : nullptr;
-
- if (op1 == base)
- {
- foundBase = true;
- }
- else if (op1 == index)
- {
- foundIndex = true;
- }
- else
- {
- m_lsra->clearOperandCounts(op1);
- if (!op1->OperIsLeaf())
- {
- nextChild = op1;
- }
- }
-
- if (op2 != nullptr)
- {
- if (op2 == base)
- {
- foundBase = true;
- }
- else if (op2 == index)
- {
- foundIndex = true;
- }
- else
- {
- m_lsra->clearOperandCounts(op2);
- if (!op2->OperIsLeaf())
- {
- assert(nextChild == nullptr);
- nextChild = op2;
- }
- }
- }
- }
- assert(foundBase && foundIndex);
- info->srcCount--; // it gets incremented below.
- }
- else if (addr->gtOper == GT_ARR_ELEM)
- {
- // The GT_ARR_ELEM consumes all the indices and produces the offset.
- // The array object lives until the mem access.
- // We also consume the target register to which the address is
- // computed
-
- info->srcCount++;
- assert(addr->gtLsraInfo.srcCount >= 2);
- addr->gtLsraInfo.srcCount -= 1;
- }
- else
- {
- // it is nothing but a plain indir
- info->srcCount--; // base gets added in below
- base = addr;
- }
-
- if (base != nullptr)
- {
- info->srcCount++;
- }
-
- if (index != nullptr && !modifiedSources)
- {
- info->srcCount++;
- }
-
- // On ARM64 we may need a single internal register
- // (when both conditions are true then we still only need a single internal register)
- if ((index != nullptr) && (cns != 0))
- {
- // ARM64 does not support both Index and offset so we need an internal register
- info->internalIntCount = 1;
- }
- else if (!emitter::emitIns_valid_imm_for_ldst_offset(cns, emitTypeSize(indirTree)))
- {
- // This offset can't be contained in the ldr/str instruction, so we need an internal register
- info->internalIntCount = 1;
- }
-}
-
-//------------------------------------------------------------------------
-// TreeNodeInfoInitCmp: Set the register requirements for a compare.
-//
-// Arguments:
-// tree - The node of interest
-//
-// Return Value:
-// None.
-//
-void Lowering::TreeNodeInfoInitCmp(GenTreePtr tree)
-{
- TreeNodeInfo* info = &(tree->gtLsraInfo);
-
- info->srcCount = 2;
- info->dstCount = 1;
- CheckImmedAndMakeContained(tree, tree->gtOp.gtOp2);
-}
-
#endif // _TARGET_ARM64_
#endif // !LEGACY_BACKEND
diff --git a/src/jit/lsraarmarch.cpp b/src/jit/lsraarmarch.cpp
new file mode 100644
index 0000000000..7d999d880f
--- /dev/null
+++ b/src/jit/lsraarmarch.cpp
@@ -0,0 +1,868 @@
+// 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.
+
+/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XX XX
+XX Register Requirements for ARM and ARM64 common code XX
+XX XX
+XX This encapsulates common logic for setting register requirements for XX
+XX the ARM and ARM64 architectures. XX
+XX XX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+*/
+
+#include "jitpch.h"
+#ifdef _MSC_VER
+#pragma hdrstop
+#endif
+
+#ifndef LEGACY_BACKEND // This file is ONLY used for the RyuJIT backend that uses the linear scan register allocator
+
+#ifdef _TARGET_ARMARCH_ // This file is ONLY used for ARM and ARM64 architectures
+
+#include "jit.h"
+#include "sideeffects.h"
+#include "lower.h"
+#include "lsra.h"
+
+//------------------------------------------------------------------------
+// TreeNodeInfoInitStoreLoc: Set register requirements for a store of a lclVar
+//
+// Arguments:
+// storeLoc - the local store (GT_STORE_LCL_FLD or GT_STORE_LCL_VAR)
+//
+// Notes:
+// This involves:
+// - Setting the appropriate candidates for a store of a multi-reg call return value.
+// - Handling of contained immediates.
+//
+void Lowering::TreeNodeInfoInitStoreLoc(GenTreeLclVarCommon* storeLoc)
+{
+ TreeNodeInfo* info = &(storeLoc->gtLsraInfo);
+
+ // Is this the case of var = call where call is returning
+ // a value in multiple return registers?
+ GenTree* op1 = storeLoc->gtGetOp1();
+ if (op1->IsMultiRegCall())
+ {
+ // backend expects to see this case only for store lclvar.
+ assert(storeLoc->OperGet() == GT_STORE_LCL_VAR);
+
+ // srcCount = number of registers in which the value is returned by call
+ GenTreeCall* call = op1->AsCall();
+ ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
+ info->srcCount = retTypeDesc->GetReturnRegCount();
+
+ // Call node srcCandidates = Bitwise-OR(allregs(GetReturnRegType(i))) for all i=0..RetRegCount-1
+ regMaskTP srcCandidates = m_lsra->allMultiRegCallNodeRegs(call);
+ op1->gtLsraInfo.setSrcCandidates(m_lsra, srcCandidates);
+ return;
+ }
+
+ CheckImmedAndMakeContained(storeLoc, op1);
+}
+
+//------------------------------------------------------------------------
+// TreeNodeInfoInitCmp: Lower a GT comparison node.
+//
+// Arguments:
+// tree - the node to lower
+//
+// Return Value:
+// None.
+//
+void Lowering::TreeNodeInfoInitCmp(GenTreePtr tree)
+{
+ TreeNodeInfo* info = &(tree->gtLsraInfo);
+
+ info->srcCount = 2;
+ info->dstCount = 1;
+
+#ifdef _TARGET_ARM_
+
+ GenTreePtr op1 = tree->gtOp.gtOp1;
+ GenTreePtr op2 = tree->gtOp.gtOp2;
+ var_types op1Type = op1->TypeGet();
+ var_types op2Type = op2->TypeGet();
+
+ // Long compares will consume GT_LONG nodes, each of which produces two results.
+ // Thus for each long operand there will be an additional source.
+ // TODO-ARM-CQ: Mark hiOp2 and loOp2 as contained if it is a constant.
+ if (varTypeIsLong(op1Type))
+ {
+ info->srcCount++;
+ }
+ if (varTypeIsLong(op2Type))
+ {
+ info->srcCount++;
+ }
+
+#endif // _TARGET_ARM_
+
+ CheckImmedAndMakeContained(tree, tree->gtOp.gtOp2);
+}
+
+void Lowering::TreeNodeInfoInitGCWriteBarrier(GenTree* tree)
+{
+ GenTreePtr dst = tree;
+ GenTreePtr addr = tree->gtOp.gtOp1;
+ GenTreePtr src = tree->gtOp.gtOp2;
+
+ if (addr->OperGet() == GT_LEA)
+ {
+ // In the case where we are doing a helper assignment, if the dst
+ // is an indir through an lea, we need to actually instantiate the
+ // lea in a register
+ GenTreeAddrMode* lea = addr->AsAddrMode();
+
+ short leaSrcCount = 0;
+ if (lea->Base() != nullptr)
+ {
+ leaSrcCount++;
+ }
+ if (lea->Index() != nullptr)
+ {
+ leaSrcCount++;
+ }
+ lea->gtLsraInfo.srcCount = leaSrcCount;
+ lea->gtLsraInfo.dstCount = 1;
+ }
+
+#if NOGC_WRITE_BARRIERS
+ NYI_ARM("NOGC_WRITE_BARRIERS");
+
+ // For the NOGC JIT Helper calls
+ //
+ // the 'addr' goes into x14 (REG_WRITE_BARRIER_DST_BYREF)
+ // the 'src' goes into x15 (REG_WRITE_BARRIER)
+ //
+ addr->gtLsraInfo.setSrcCandidates(m_lsra, RBM_WRITE_BARRIER_DST_BYREF);
+ src->gtLsraInfo.setSrcCandidates(m_lsra, RBM_WRITE_BARRIER);
+#else
+ // For the standard JIT Helper calls
+ // op1 goes into REG_ARG_0 and
+ // op2 goes into REG_ARG_1
+ //
+ addr->gtLsraInfo.setSrcCandidates(m_lsra, RBM_ARG_0);
+ src->gtLsraInfo.setSrcCandidates(m_lsra, RBM_ARG_1);
+#endif // NOGC_WRITE_BARRIERS
+
+ // Both src and dst must reside in a register, which they should since we haven't set
+ // either of them as contained.
+ assert(addr->gtLsraInfo.dstCount == 1);
+ assert(src->gtLsraInfo.dstCount == 1);
+}
+
+//------------------------------------------------------------------------
+// TreeNodeInfoInitIndir: Specify register requirements for address expression
+// of an indirection operation.
+//
+// Arguments:
+// indirTree - GT_IND, GT_STOREIND, block node or GT_NULLCHECK gentree node
+//
+void Lowering::TreeNodeInfoInitIndir(GenTreePtr indirTree)
+{
+ assert(indirTree->OperIsIndir());
+ // If this is the rhs of a block copy (i.e. non-enregisterable struct),
+ // it has no register requirements.
+ if (indirTree->TypeGet() == TYP_STRUCT)
+ {
+ return;
+ }
+
+ GenTreePtr addr = indirTree->gtGetOp1();
+ TreeNodeInfo* info = &(indirTree->gtLsraInfo);
+
+ GenTreePtr base = nullptr;
+ GenTreePtr index = nullptr;
+ unsigned cns = 0;
+ unsigned mul;
+ bool rev;
+ bool modifiedSources = false;
+
+ if ((addr->OperGet() == GT_LEA) && IsSafeToContainMem(indirTree, addr))
+ {
+ GenTreeAddrMode* lea = addr->AsAddrMode();
+ base = lea->Base();
+ index = lea->Index();
+ cns = lea->gtOffset;
+
+ m_lsra->clearOperandCounts(addr);
+ // The srcCount is decremented because addr is now "contained",
+ // then we account for the base and index below, if they are non-null.
+ info->srcCount--;
+ }
+ else if (comp->codeGen->genCreateAddrMode(addr, -1, true, 0, &rev, &base, &index, &mul, &cns, true /*nogen*/) &&
+ !(modifiedSources = AreSourcesPossiblyModifiedLocals(indirTree, base, index)))
+ {
+ // An addressing mode will be constructed that may cause some
+ // nodes to not need a register, and cause others' lifetimes to be extended
+ // to the GT_IND or even its parent if it's an assignment
+
+ assert(base != addr);
+ m_lsra->clearOperandCounts(addr);
+
+ GenTreePtr arrLength = nullptr;
+
+ // Traverse the computation below GT_IND to find the operands
+ // for the addressing mode, marking the various constants and
+ // intermediate results as not consuming/producing.
+ // If the traversal were more complex, we might consider using
+ // a traversal function, but the addressing mode is only made
+ // up of simple arithmetic operators, and the code generator
+ // only traverses one leg of each node.
+
+ bool foundBase = (base == nullptr);
+ bool foundIndex = (index == nullptr);
+ GenTreePtr nextChild = nullptr;
+ for (GenTreePtr child = addr; child != nullptr && !child->OperIsLeaf(); child = nextChild)
+ {
+ nextChild = nullptr;
+ GenTreePtr op1 = child->gtOp.gtOp1;
+ GenTreePtr op2 = (child->OperIsBinary()) ? child->gtOp.gtOp2 : nullptr;
+
+ if (op1 == base)
+ {
+ foundBase = true;
+ }
+ else if (op1 == index)
+ {
+ foundIndex = true;
+ }
+ else
+ {
+ m_lsra->clearOperandCounts(op1);
+ if (!op1->OperIsLeaf())
+ {
+ nextChild = op1;
+ }
+ }
+
+ if (op2 != nullptr)
+ {
+ if (op2 == base)
+ {
+ foundBase = true;
+ }
+ else if (op2 == index)
+ {
+ foundIndex = true;
+ }
+ else
+ {
+ m_lsra->clearOperandCounts(op2);
+ if (!op2->OperIsLeaf())
+ {
+ assert(nextChild == nullptr);
+ nextChild = op2;
+ }
+ }
+ }
+ }
+ assert(foundBase && foundIndex);
+ info->srcCount--; // it gets incremented below.
+ }
+ else if (addr->gtOper == GT_ARR_ELEM)
+ {
+ // The GT_ARR_ELEM consumes all the indices and produces the offset.
+ // The array object lives until the mem access.
+ // We also consume the target register to which the address is
+ // computed
+
+ info->srcCount++;
+ assert(addr->gtLsraInfo.srcCount >= 2);
+ addr->gtLsraInfo.srcCount -= 1;
+ }
+ else
+ {
+ // it is nothing but a plain indir
+ info->srcCount--; // base gets added in below
+ base = addr;
+ }
+
+ if (base != nullptr)
+ {
+ info->srcCount++;
+ }
+
+ if (index != nullptr && !modifiedSources)
+ {
+ info->srcCount++;
+ }
+
+ // On ARM we may need a single internal register
+ // (when both conditions are true then we still only need a single internal register)
+ if ((index != nullptr) && (cns != 0))
+ {
+ // ARM does not support both Index and offset so we need an internal register
+ info->internalIntCount = 1;
+ }
+ else if (!emitter::emitIns_valid_imm_for_ldst_offset(cns, emitTypeSize(indirTree)))
+ {
+ // This offset can't be contained in the ldr/str instruction, so we need an internal register
+ info->internalIntCount = 1;
+ }
+}
+
+//------------------------------------------------------------------------
+// TreeNodeInfoInitShiftRotate: Set the NodeInfo for a shift or rotate.
+//
+// Arguments:
+// tree - The node of interest
+//
+// Return Value:
+// None.
+//
+void Lowering::TreeNodeInfoInitShiftRotate(GenTree* tree)
+{
+ TreeNodeInfo* info = &(tree->gtLsraInfo);
+ LinearScan* l = m_lsra;
+
+ info->srcCount = 2;
+ info->dstCount = 1;
+
+ GenTreePtr shiftBy = tree->gtOp.gtOp2;
+ GenTreePtr source = tree->gtOp.gtOp1;
+ if (shiftBy->IsCnsIntOrI())
+ {
+ l->clearDstCount(shiftBy);
+ info->srcCount--;
+ }
+
+#ifdef _TARGET_ARM_
+
+ // The first operand of a GT_LSH_HI and GT_RSH_LO oper is a GT_LONG so that
+ // we can have a three operand form. Increment the srcCount.
+ if (tree->OperGet() == GT_LSH_HI || tree->OperGet() == GT_RSH_LO)
+ {
+ assert(source->OperGet() == GT_LONG);
+
+ info->srcCount++;
+
+ if (tree->OperGet() == GT_LSH_HI)
+ {
+ GenTreePtr sourceLo = source->gtOp.gtOp1;
+ sourceLo->gtLsraInfo.isDelayFree = true;
+ }
+ else
+ {
+ GenTreePtr sourceHi = source->gtOp.gtOp2;
+ sourceHi->gtLsraInfo.isDelayFree = true;
+ }
+
+ source->gtLsraInfo.hasDelayFreeSrc = true;
+ info->hasDelayFreeSrc = true;
+ }
+
+#endif // _TARGET_ARM_
+}
+
+//------------------------------------------------------------------------
+// TreeNodeInfoInitPutArgReg: Set the NodeInfo for a PUTARG_REG.
+//
+// Arguments:
+// node - The PUTARG_REG node.
+// argReg - The register in which to pass the argument.
+// info - The info for the node's using call.
+// isVarArgs - True if the call uses a varargs calling convention.
+// callHasFloatRegArgs - Set to true if this PUTARG_REG uses an FP register.
+//
+// Return Value:
+// None.
+//
+void Lowering::TreeNodeInfoInitPutArgReg(
+ GenTreeUnOp* node, regNumber argReg, TreeNodeInfo& info, bool isVarArgs, bool* callHasFloatRegArgs)
+{
+ assert(node != nullptr);
+ assert(node->OperIsPutArgReg());
+ assert(argReg != REG_NA);
+
+ // Each register argument corresponds to one source.
+ info.srcCount++;
+
+ // Set the register requirements for the node.
+ const regMaskTP argMask = genRegMask(argReg);
+ node->gtLsraInfo.setDstCandidates(m_lsra, argMask);
+ node->gtLsraInfo.setSrcCandidates(m_lsra, argMask);
+
+ // To avoid redundant moves, have the argument operand computed in the
+ // register in which the argument is passed to the call.
+ node->gtOp.gtOp1->gtLsraInfo.setSrcCandidates(m_lsra, m_lsra->getUseCandidates(node));
+
+ *callHasFloatRegArgs |= varTypeIsFloating(node->TypeGet());
+}
+
+//------------------------------------------------------------------------
+// TreeNodeInfoInitCall: Set the NodeInfo for a call.
+//
+// Arguments:
+// call - The call node of interest
+//
+// Return Value:
+// None.
+//
+void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
+{
+ TreeNodeInfo* info = &(call->gtLsraInfo);
+ LinearScan* l = m_lsra;
+ Compiler* compiler = comp;
+ bool hasMultiRegRetVal = false;
+ ReturnTypeDesc* retTypeDesc = nullptr;
+
+ info->srcCount = 0;
+ if (call->TypeGet() != TYP_VOID)
+ {
+ hasMultiRegRetVal = call->HasMultiRegRetVal();
+ if (hasMultiRegRetVal)
+ {
+ // dst count = number of registers in which the value is returned by call
+ retTypeDesc = call->GetReturnTypeDesc();
+ info->dstCount = retTypeDesc->GetReturnRegCount();
+ }
+ else
+ {
+ info->dstCount = 1;
+ }
+ }
+ else
+ {
+ info->dstCount = 0;
+ }
+
+ GenTree* ctrlExpr = call->gtControlExpr;
+ if (call->gtCallType == CT_INDIRECT)
+ {
+ // either gtControlExpr != null or gtCallAddr != null.
+ // Both cannot be non-null at the same time.
+ assert(ctrlExpr == nullptr);
+ assert(call->gtCallAddr != nullptr);
+ ctrlExpr = call->gtCallAddr;
+ }
+
+ // set reg requirements on call target represented as control sequence.
+ if (ctrlExpr != nullptr)
+ {
+ // we should never see a gtControlExpr whose type is void.
+ assert(ctrlExpr->TypeGet() != TYP_VOID);
+
+ info->srcCount++;
+
+ // In case of fast tail implemented as jmp, make sure that gtControlExpr is
+ // computed into a register.
+ if (call->IsFastTailCall())
+ {
+ NYI_ARM("tail call");
+
+#ifdef _TARGET_ARM64_
+ // Fast tail call - make sure that call target is always computed in IP0
+ // so that epilog sequence can generate "br xip0" to achieve fast tail call.
+ ctrlExpr->gtLsraInfo.setSrcCandidates(l, genRegMask(REG_IP0));
+#endif // _TARGET_ARM64_
+ }
+ }
+#ifdef _TARGET_ARM_
+ else
+ {
+ info->internalIntCount = 1;
+ }
+#endif // _TARGET_ARM_
+
+ RegisterType registerType = call->TypeGet();
+
+// Set destination candidates for return value of the call.
+
+#ifdef _TARGET_ARM_
+ if (call->IsHelperCall(compiler, CORINFO_HELP_INIT_PINVOKE_FRAME))
+ {
+ // The ARM CORINFO_HELP_INIT_PINVOKE_FRAME helper uses a custom calling convention that returns with
+ // TCB in REG_PINVOKE_TCB. fgMorphCall() sets the correct argument registers.
+ info->setDstCandidates(l, RBM_PINVOKE_TCB);
+ }
+ else
+#endif // _TARGET_ARM_
+ if (hasMultiRegRetVal)
+ {
+ assert(retTypeDesc != nullptr);
+ info->setDstCandidates(l, retTypeDesc->GetABIReturnRegs());
+ }
+ else if (varTypeIsFloating(registerType))
+ {
+ info->setDstCandidates(l, RBM_FLOATRET);
+ }
+ else if (registerType == TYP_LONG)
+ {
+ info->setDstCandidates(l, RBM_LNGRET);
+ }
+ else
+ {
+ info->setDstCandidates(l, RBM_INTRET);
+ }
+
+ // If there is an explicit this pointer, we don't want that node to produce anything
+ // as it is redundant
+ if (call->gtCallObjp != nullptr)
+ {
+ GenTreePtr thisPtrNode = call->gtCallObjp;
+
+ if (thisPtrNode->gtOper == GT_PUTARG_REG)
+ {
+ l->clearOperandCounts(thisPtrNode);
+ l->clearDstCount(thisPtrNode->gtOp.gtOp1);
+ }
+ else
+ {
+ l->clearDstCount(thisPtrNode);
+ }
+ }
+
+ // First, count reg args
+ bool callHasFloatRegArgs = false;
+
+ for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext())
+ {
+ assert(list->OperIsList());
+
+ GenTreePtr argNode = list->Current();
+
+ fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, argNode);
+ assert(curArgTabEntry);
+
+ if (curArgTabEntry->regNum == REG_STK)
+ {
+ // late arg that is not passed in a register
+ assert(argNode->gtOper == GT_PUTARG_STK);
+
+ TreeNodeInfoInitPutArgStk(argNode->AsPutArgStk(), curArgTabEntry);
+ continue;
+ }
+
+ // A GT_FIELD_LIST has a TYP_VOID, but is used to represent a multireg struct
+ if (argNode->OperGet() == GT_FIELD_LIST)
+ {
+ // There could be up to 2-4 PUTARG_REGs in the list (3 or 4 can only occur for HFAs)
+ regNumber argReg = curArgTabEntry->regNum;
+ for (GenTreeFieldList* entry = argNode->AsFieldList(); entry != nullptr; entry = entry->Rest())
+ {
+ TreeNodeInfoInitPutArgReg(entry->Current()->AsUnOp(), argReg, *info, false, &callHasFloatRegArgs);
+
+ // Update argReg for the next putarg_reg (if any)
+ argReg = genRegArgNext(argReg);
+ }
+ }
+ else
+ {
+ TreeNodeInfoInitPutArgReg(argNode->AsUnOp(), curArgTabEntry->regNum, *info, false, &callHasFloatRegArgs);
+ }
+ }
+
+ // Now, count stack args
+ // Note that these need to be computed into a register, but then
+ // they're just stored to the stack - so the reg doesn't
+ // need to remain live until the call. In fact, it must not
+ // because the code generator doesn't actually consider it live,
+ // so it can't be spilled.
+
+ GenTreePtr args = call->gtCallArgs;
+ while (args)
+ {
+ GenTreePtr arg = args->gtOp.gtOp1;
+
+ // Skip arguments that have been moved to the Late Arg list
+ if (!(args->gtFlags & GTF_LATE_ARG))
+ {
+ if (arg->gtOper == GT_PUTARG_STK)
+ {
+ fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, arg);
+ assert(curArgTabEntry);
+
+ assert(curArgTabEntry->regNum == REG_STK);
+
+ TreeNodeInfoInitPutArgStk(arg->AsPutArgStk(), curArgTabEntry);
+ }
+ else
+ {
+ TreeNodeInfo* argInfo = &(arg->gtLsraInfo);
+ if (argInfo->dstCount != 0)
+ {
+ argInfo->isLocalDefUse = true;
+ }
+
+ argInfo->dstCount = 0;
+ }
+ }
+ args = args->gtOp.gtOp2;
+ }
+
+ // If it is a fast tail call, it is already preferenced to use IP0.
+ // Therefore, no need set src candidates on call tgt again.
+ if (call->IsVarargs() && callHasFloatRegArgs && !call->IsFastTailCall() && (ctrlExpr != nullptr))
+ {
+ NYI_ARM("float reg varargs");
+
+ // Don't assign the call target to any of the argument registers because
+ // we will use them to also pass floating point arguments as required
+ // by Arm64 ABI.
+ ctrlExpr->gtLsraInfo.setSrcCandidates(l, l->allRegs(TYP_INT) & ~(RBM_ARG_REGS));
+ }
+
+#ifdef _TARGET_ARM_
+
+ if (call->NeedsNullCheck())
+ {
+ info->internalIntCount++;
+ }
+
+#endif // _TARGET_ARM_
+}
+
+//------------------------------------------------------------------------
+// TreeNodeInfoInitPutArgStk: Set the NodeInfo for a GT_PUTARG_STK node
+//
+// Arguments:
+// argNode - a GT_PUTARG_STK node
+//
+// Return Value:
+// None.
+//
+// Notes:
+// Set the child node(s) to be contained when we have a multireg arg
+//
+void Lowering::TreeNodeInfoInitPutArgStk(GenTreePutArgStk* argNode, fgArgTabEntryPtr info)
+{
+ assert(argNode->gtOper == GT_PUTARG_STK);
+
+ GenTreePtr putArgChild = argNode->gtOp.gtOp1;
+
+ // Initialize 'argNode' as not contained, as this is both the default case
+ // and how MakeSrcContained expects to find things setup.
+ //
+ argNode->gtLsraInfo.srcCount = 1;
+ argNode->gtLsraInfo.dstCount = 0;
+
+ // Do we have a TYP_STRUCT argument (or a GT_FIELD_LIST), if so it must be a multireg pass-by-value struct
+ if ((putArgChild->TypeGet() == TYP_STRUCT) || (putArgChild->OperGet() == GT_FIELD_LIST))
+ {
+ // We will use store instructions that each write a register sized value
+
+ if (putArgChild->OperGet() == GT_FIELD_LIST)
+ {
+ // We consume all of the items in the GT_FIELD_LIST
+ argNode->gtLsraInfo.srcCount = info->numSlots;
+ }
+ else
+ {
+ // We could use a ldp/stp sequence so we need two internal registers
+ argNode->gtLsraInfo.internalIntCount = 2;
+
+ if (putArgChild->OperGet() == GT_OBJ)
+ {
+ GenTreePtr objChild = putArgChild->gtOp.gtOp1;
+ if (objChild->OperGet() == GT_LCL_VAR_ADDR)
+ {
+ // We will generate all of the code for the GT_PUTARG_STK, the GT_OBJ and the GT_LCL_VAR_ADDR
+ // as one contained operation
+ //
+ MakeSrcContained(putArgChild, objChild);
+ }
+ }
+
+ // We will generate all of the code for the GT_PUTARG_STK and it's child node
+ // as one contained operation
+ //
+ MakeSrcContained(argNode, putArgChild);
+ }
+ }
+ else
+ {
+ // We must not have a multi-reg struct
+ assert(info->numSlots == 1);
+ }
+}
+
+//------------------------------------------------------------------------
+// TreeNodeInfoInitBlockStore: Set the NodeInfo for a block store.
+//
+// Arguments:
+// blkNode - The block store node of interest
+//
+// Return Value:
+// None.
+//
+void Lowering::TreeNodeInfoInitBlockStore(GenTreeBlk* blkNode)
+{
+ GenTree* dstAddr = blkNode->Addr();
+ unsigned size = blkNode->gtBlkSize;
+ GenTree* source = blkNode->Data();
+ LinearScan* l = m_lsra;
+ Compiler* compiler = comp;
+
+ // Sources are dest address and initVal or source.
+ // We may require an additional source or temp register for the size.
+ blkNode->gtLsraInfo.srcCount = 2;
+ blkNode->gtLsraInfo.dstCount = 0;
+ GenTreePtr srcAddrOrFill = nullptr;
+ bool isInitBlk = blkNode->OperIsInitBlkOp();
+
+ if (!isInitBlk)
+ {
+ // CopyObj or CopyBlk
+ if (source->gtOper == GT_IND)
+ {
+ srcAddrOrFill = blkNode->Data()->gtGetOp1();
+ // We're effectively setting source as contained, but can't call MakeSrcContained, because the
+ // "inheritance" of the srcCount is to a child not a parent - it would "just work" but could be misleading.
+ // If srcAddr is already non-contained, we don't need to change it.
+ if (srcAddrOrFill->gtLsraInfo.getDstCount() == 0)
+ {
+ srcAddrOrFill->gtLsraInfo.setDstCount(1);
+ srcAddrOrFill->gtLsraInfo.setSrcCount(source->gtLsraInfo.srcCount);
+ }
+ m_lsra->clearOperandCounts(source);
+ }
+ else if (!source->IsMultiRegCall() && !source->OperIsSIMD())
+ {
+ assert(source->IsLocal());
+ MakeSrcContained(blkNode, source);
+ }
+ }
+
+ if (isInitBlk)
+ {
+ GenTreePtr initVal = source;
+ if (initVal->OperIsInitVal())
+ {
+ initVal = initVal->gtGetOp1();
+ }
+ srcAddrOrFill = initVal;
+
+ if (blkNode->gtBlkOpKind == GenTreeBlk::BlkOpKindUnroll)
+ {
+ // TODO-ARM-CQ: Currently we generate a helper call for every
+ // initblk we encounter. Later on we should implement loop unrolling
+ // code sequences to improve CQ.
+ // For reference see the code in lsraxarch.cpp.
+ NYI_ARM("initblk loop unrolling is currently not implemented.");
+
+#ifdef _TARGET_ARM64_
+ // No additional temporaries required
+ ssize_t fill = initVal->gtIntCon.gtIconVal & 0xFF;
+ if (fill == 0)
+ {
+ MakeSrcContained(blkNode, source);
+ }
+#endif // _TARGET_ARM64_
+ }
+ else
+ {
+ assert(blkNode->gtBlkOpKind == GenTreeBlk::BlkOpKindHelper);
+ // The helper follows the regular ABI.
+ dstAddr->gtLsraInfo.setSrcCandidates(l, RBM_ARG_0);
+ initVal->gtLsraInfo.setSrcCandidates(l, RBM_ARG_1);
+ if (size != 0)
+ {
+ // Reserve a temp register for the block size argument.
+ blkNode->gtLsraInfo.setInternalCandidates(l, RBM_ARG_2);
+ blkNode->gtLsraInfo.internalIntCount = 1;
+ }
+ else
+ {
+ // The block size argument is a third argument to GT_STORE_DYN_BLK
+ noway_assert(blkNode->gtOper == GT_STORE_DYN_BLK);
+ blkNode->gtLsraInfo.setSrcCount(3);
+ GenTree* sizeNode = blkNode->AsDynBlk()->gtDynamicSize;
+ sizeNode->gtLsraInfo.setSrcCandidates(l, RBM_ARG_2);
+ }
+ }
+ }
+ else
+ {
+ // CopyObj or CopyBlk
+ // Sources are src and dest and size if not constant.
+ if (blkNode->OperGet() == GT_STORE_OBJ)
+ {
+ // CopyObj
+ NYI_ARM("GT_STORE_OBJ is needed of write barriers implementation");
+
+#ifdef _TARGET_ARM64_
+
+ // We don't need to materialize the struct size but we still need
+ // a temporary register to perform the sequence of loads and stores.
+ blkNode->gtLsraInfo.internalIntCount = 1;
+
+ dstAddr->gtLsraInfo.setSrcCandidates(l, RBM_WRITE_BARRIER_DST_BYREF);
+ // If we have a source address we want it in REG_WRITE_BARRIER_SRC_BYREF.
+ // Otherwise, if it is a local, codegen will put its address in REG_WRITE_BARRIER_SRC_BYREF,
+ // which is killed by a StoreObj (and thus needn't be reserved).
+ if (srcAddrOrFill != nullptr)
+ {
+ srcAddrOrFill->gtLsraInfo.setSrcCandidates(l, RBM_WRITE_BARRIER_SRC_BYREF);
+ }
+
+#endif // _TARGET_ARM64_
+ }
+ else
+ {
+ // CopyBlk
+ short internalIntCount = 0;
+ regMaskTP internalIntCandidates = RBM_NONE;
+
+ if (blkNode->gtBlkOpKind == GenTreeBlk::BlkOpKindUnroll)
+ {
+ // TODO-ARM-CQ: cpblk loop unrolling is currently not implemented.
+ // In case of a CpBlk with a constant size and less than CPBLK_UNROLL_LIMIT size
+ // we should unroll the loop to improve CQ.
+ // For reference see the code in lsraxarch.cpp.
+ NYI_ARM("cpblk loop unrolling is currently not implemented.");
+
+#ifdef _TARGET_ARM64_
+
+ internalIntCount = 1;
+ internalIntCandidates = RBM_ALLINT;
+
+ if (size >= 2 * REGSIZE_BYTES)
+ {
+ // Use ldp/stp to reduce code size and improve performance
+ internalIntCount++;
+ }
+
+#endif // _TARGET_ARM64_
+ }
+ else
+ {
+ assert(blkNode->gtBlkOpKind == GenTreeBlk::BlkOpKindHelper);
+ dstAddr->gtLsraInfo.setSrcCandidates(l, RBM_ARG_0);
+ // The srcAddr goes in arg1.
+ if (srcAddrOrFill != nullptr)
+ {
+ srcAddrOrFill->gtLsraInfo.setSrcCandidates(l, RBM_ARG_1);
+ }
+ if (size != 0)
+ {
+ // Reserve a temp register for the block size argument.
+ internalIntCandidates |= RBM_ARG_2;
+ internalIntCount++;
+ }
+ else
+ {
+ // The block size argument is a third argument to GT_STORE_DYN_BLK
+ noway_assert(blkNode->gtOper == GT_STORE_DYN_BLK);
+ blkNode->gtLsraInfo.setSrcCount(3);
+ GenTree* blockSize = blkNode->AsDynBlk()->gtDynamicSize;
+ blockSize->gtLsraInfo.setSrcCandidates(l, RBM_ARG_2);
+ }
+ }
+ if (internalIntCount != 0)
+ {
+ blkNode->gtLsraInfo.internalIntCount = internalIntCount;
+ blkNode->gtLsraInfo.setInternalCandidates(l, internalIntCandidates);
+ }
+ }
+ }
+}
+
+#endif // _TARGET_ARMARCH_
+
+#endif // !LEGACY_BACKEND
diff --git a/src/jit/lsraxarch.cpp b/src/jit/lsraxarch.cpp
index a4da2b7ce6..002e3d803f 100644
--- a/src/jit/lsraxarch.cpp
+++ b/src/jit/lsraxarch.cpp
@@ -1174,6 +1174,55 @@ void Lowering::TreeNodeInfoInitShiftRotate(GenTree* tree)
}
//------------------------------------------------------------------------
+// TreeNodeInfoInitPutArgReg: Set the NodeInfo for a PUTARG_REG.
+//
+// Arguments:
+// node - The PUTARG_REG node.
+// argReg - The register in which to pass the argument.
+// info - The info for the node's using call.
+// isVarArgs - True if the call uses a varargs calling convention.
+// callHasFloatRegArgs - Set to true if this PUTARG_REG uses an FP register.
+//
+// Return Value:
+// None.
+//
+void Lowering::TreeNodeInfoInitPutArgReg(
+ GenTreeUnOp* node, regNumber argReg, TreeNodeInfo& info, bool isVarArgs, bool* callHasFloatRegArgs)
+{
+ assert(node != nullptr);
+ assert(node->OperIsPutArgReg());
+ assert(argReg != REG_NA);
+
+ // Each register argument corresponds to one source.
+ info.srcCount++;
+
+ // Set the register requirements for the node.
+ const regMaskTP argMask = genRegMask(argReg);
+ node->gtLsraInfo.setDstCandidates(m_lsra, argMask);
+ node->gtLsraInfo.setSrcCandidates(m_lsra, argMask);
+
+ // To avoid redundant moves, have the argument operand computed in the
+ // register in which the argument is passed to the call.
+ node->gtOp.gtOp1->gtLsraInfo.setSrcCandidates(m_lsra, m_lsra->getUseCandidates(node));
+
+#if FEATURE_VARARG
+ *callHasFloatRegArgs |= varTypeIsFloating(node->TypeGet());
+
+ // In the case of a varargs call, the ABI dictates that if we have floating point args,
+ // we must pass the enregistered arguments in both the integer and floating point registers.
+ // Since the integer register is not associated with this arg node, we will reserve it as
+ // an internal register so that it is not used during the evaluation of the call node
+ // (e.g. for the target).
+ if (isVarArgs && varTypeIsFloating(node))
+ {
+ regNumber targetReg = comp->getCallArgIntRegister(argReg);
+ info.setInternalIntCount(info.internalIntCount + 1);
+ info.addInternalCandidates(m_lsra, genRegMask(targetReg));
+ }
+#endif // FEATURE_VARARG
+}
+
+//------------------------------------------------------------------------
// TreeNodeInfoInitCall: Set the NodeInfo for a call.
//
// Arguments:
@@ -1337,15 +1386,23 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
}
}
-#if FEATURE_VARARG
bool callHasFloatRegArgs = false;
-#endif // !FEATURE_VARARG
+ bool isVarArgs = call->IsVarargs();
// First, count reg args
for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext())
{
assert(list->OperIsList());
+ // By this point, lowering has ensured that all call arguments are one of the following:
+ // - an arg setup store
+ // - an arg placeholder
+ // - a nop
+ // - a copy blk
+ // - a field list
+ // - a put arg
+ //
+ // Note that this property is statically checked by Lowering::CheckBlock.
GenTreePtr argNode = list->Current();
fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, argNode);
@@ -1372,166 +1429,30 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
argNode->gtLsraInfo.srcCount = 0;
}
#endif // FEATURE_PUT_STRUCT_ARG_STK
- continue;
- }
-
- regNumber argReg = REG_NA;
- regMaskTP argMask = RBM_NONE;
- short regCount = 0;
- bool isOnStack = true;
- if (curArgTabEntry->regNum != REG_STK)
- {
- isOnStack = false;
- var_types argType = argNode->TypeGet();
-
-#if FEATURE_VARARG
- callHasFloatRegArgs |= varTypeIsFloating(argType);
-#endif // !FEATURE_VARARG
-
- argReg = curArgTabEntry->regNum;
- regCount = 1;
-
- // Default case is that we consume one source; modify this later (e.g. for
- // promoted structs)
- info->srcCount++;
- argMask = genRegMask(argReg);
- argNode = argNode->gtEffectiveVal();
+ continue;
}
- // If the struct arg is wrapped in CPYBLK the type of the param will be TYP_VOID.
- // Use the curArgTabEntry's isStruct to get whether the param is a struct.
- if (varTypeIsStruct(argNode) PUT_STRUCT_ARG_STK_ONLY(|| curArgTabEntry->isStruct))
- {
- unsigned originalSize = 0;
- LclVarDsc* varDsc = nullptr;
- if (argNode->gtOper == GT_LCL_VAR)
- {
- varDsc = compiler->lvaTable + argNode->gtLclVarCommon.gtLclNum;
- originalSize = varDsc->lvSize();
- }
- else if (argNode->gtOper == GT_MKREFANY)
- {
- originalSize = 2 * TARGET_POINTER_SIZE;
- }
- else if (argNode->gtOper == GT_OBJ)
- {
- noway_assert(!"GT_OBJ not supported for amd64");
- }
#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
- else if (argNode->gtOper == GT_PUTARG_REG)
- {
- originalSize = genTypeSize(argNode->gtType);
- }
- else if (argNode->gtOper == GT_FIELD_LIST)
- {
- originalSize = 0;
-
- // There could be up to 2 PUTARG_REGs in the list
- GenTreeFieldList* fieldListPtr = argNode->AsFieldList();
- unsigned iterationNum = 0;
- for (; fieldListPtr; fieldListPtr = fieldListPtr->Rest())
- {
- GenTreePtr putArgRegNode = fieldListPtr->Current();
- assert(putArgRegNode->gtOper == GT_PUTARG_REG);
-
- if (iterationNum == 0)
- {
- varDsc = compiler->lvaTable + putArgRegNode->gtOp.gtOp1->gtLclVarCommon.gtLclNum;
- originalSize = varDsc->lvSize();
- assert(originalSize != 0);
- }
- else
- {
- // Need an extra source for every node, but the first in the list.
- info->srcCount++;
-
- // Get the mask for the second putarg_reg
- argMask = genRegMask(curArgTabEntry->otherRegNum);
- }
-
- putArgRegNode->gtLsraInfo.setDstCandidates(l, argMask);
- putArgRegNode->gtLsraInfo.setSrcCandidates(l, argMask);
-
- // To avoid redundant moves, have the argument child tree computed in the
- // register in which the argument is passed to the call.
- putArgRegNode->gtOp.gtOp1->gtLsraInfo.setSrcCandidates(l, l->getUseCandidates(putArgRegNode));
- iterationNum++;
- }
-
- assert(iterationNum <= CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS);
- }
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
- else
- {
- noway_assert(!"Can't predict unsupported TYP_STRUCT arg kind");
- }
-
- unsigned slots = ((unsigned)(roundUp(originalSize, TARGET_POINTER_SIZE))) / REGSIZE_BYTES;
- unsigned remainingSlots = slots;
-
- if (!isOnStack)
- {
- remainingSlots = slots - 1;
-
- regNumber reg = (regNumber)(argReg + 1);
- while (remainingSlots > 0 && reg <= REG_ARG_LAST)
- {
- argMask |= genRegMask(reg);
- reg = (regNumber)(reg + 1);
- remainingSlots--;
- regCount++;
- }
- }
+ if (argNode->OperGet() == GT_FIELD_LIST)
+ {
+ assert(varTypeIsStruct(argNode) || curArgTabEntry->isStruct);
- short internalIntCount = 0;
- if (remainingSlots > 0)
+ unsigned eightbyte = 0;
+ for (GenTreeFieldList* entry = argNode->AsFieldList(); entry != nullptr; entry = entry->Rest())
{
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
- // This TYP_STRUCT argument is also passed in the outgoing argument area
- // We need a register to address the TYP_STRUCT
- internalIntCount = 1;
-#else // FEATURE_UNIX_AMD64_STRUCT_PASSING
- // And we may need 2
- internalIntCount = 2;
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
- }
- argNode->gtLsraInfo.internalIntCount = internalIntCount;
+ const regNumber argReg = eightbyte == 0 ? curArgTabEntry->regNum : curArgTabEntry->otherRegNum;
+ TreeNodeInfoInitPutArgReg(entry->Current()->AsUnOp(), argReg, *info, isVarArgs, &callHasFloatRegArgs);
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
- if (argNode->gtOper == GT_PUTARG_REG)
- {
- argNode->gtLsraInfo.setDstCandidates(l, argMask);
- argNode->gtLsraInfo.setSrcCandidates(l, argMask);
+ eightbyte++;
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
}
else
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
{
- argNode->gtLsraInfo.setDstCandidates(l, argMask);
- argNode->gtLsraInfo.setSrcCandidates(l, argMask);
- }
-
- // To avoid redundant moves, have the argument child tree computed in the
- // register in which the argument is passed to the call.
- if (argNode->gtOper == GT_PUTARG_REG)
- {
- argNode->gtOp.gtOp1->gtLsraInfo.setSrcCandidates(l, l->getUseCandidates(argNode));
- }
-
-#if FEATURE_VARARG
- // In the case of a varargs call, the ABI dictates that if we have floating point args,
- // we must pass the enregistered arguments in both the integer and floating point registers.
- // Since the integer register is not associated with this arg node, we will reserve it as
- // an internal register so that it is not used during the evaluation of the call node
- // (e.g. for the target).
- if (call->IsVarargs() && varTypeIsFloating(argNode))
- {
- regNumber targetReg = compiler->getCallArgIntRegister(argReg);
- info->setInternalIntCount(info->internalIntCount + 1);
- info->addInternalCandidates(l, genRegMask(targetReg));
+ TreeNodeInfoInitPutArgReg(argNode->AsUnOp(), curArgTabEntry->regNum, *info, isVarArgs,
+ &callHasFloatRegArgs);
}
-#endif // FEATURE_VARARG
}
// Now, count stack args
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp
index dabca57710..92d5e0967e 100644
--- a/src/jit/morph.cpp
+++ b/src/jit/morph.cpp
@@ -92,7 +92,7 @@ GenTreePtr Compiler::fgMorphIntoHelperCall(GenTreePtr tree, int helper, GenTreeA
tree->gtCall.gtEntryPoint.addr = nullptr;
#endif
-#if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
+#if (defined(_TARGET_X86_) || defined(_TARGET_ARM_)) && !defined(LEGACY_BACKEND)
if (varTypeIsLong(tree))
{
GenTreeCall* callNode = tree->AsCall();
@@ -101,7 +101,7 @@ GenTreePtr Compiler::fgMorphIntoHelperCall(GenTreePtr tree, int helper, GenTreeA
retTypeDesc->InitializeLongReturnType(this);
callNode->ClearOtherRegs();
}
-#endif
+#endif // _TARGET_XXX_
/* Perform the morphing */
@@ -850,17 +850,22 @@ void fgArgTabEntry::Dump()
}
#endif
-fgArgInfo::fgArgInfo(Compiler* comp, GenTreePtr call, unsigned numArgs)
+fgArgInfo::fgArgInfo(Compiler* comp, GenTreeCall* call, unsigned numArgs)
{
- compiler = comp;
- callTree = call;
- assert(call->IsCall());
+ compiler = comp;
+ callTree = call;
argCount = 0; // filled in arg count, starts at zero
nextSlotNum = INIT_ARG_STACK_SLOT;
stkLevel = 0;
#if defined(UNIX_X86_ABI)
- padStkAlign = 0;
+ alignmentDone = false;
+ stkSizeBytes = 0;
+ padStkAlign = 0;
#endif
+#if FEATURE_FIXED_OUT_ARGS
+ outArgSize = 0;
+#endif
+
argTableSize = numArgs; // the allocated table size
hasRegArgs = false;
@@ -889,22 +894,22 @@ fgArgInfo::fgArgInfo(Compiler* comp, GenTreePtr call, unsigned numArgs)
* in the argTable contains pointers that must point to the
* new arguments and not the old arguments.
*/
-fgArgInfo::fgArgInfo(GenTreePtr newCall, GenTreePtr oldCall)
+fgArgInfo::fgArgInfo(GenTreeCall* newCall, GenTreeCall* oldCall)
{
- assert(oldCall->IsCall());
- assert(newCall->IsCall());
-
fgArgInfoPtr oldArgInfo = oldCall->gtCall.fgArgInfo;
- compiler = oldArgInfo->compiler;
- ;
- callTree = newCall;
- assert(newCall->IsCall());
+ compiler = oldArgInfo->compiler;
+ callTree = newCall;
argCount = 0; // filled in arg count, starts at zero
nextSlotNum = INIT_ARG_STACK_SLOT;
stkLevel = oldArgInfo->stkLevel;
#if defined(UNIX_X86_ABI)
- padStkAlign = oldArgInfo->padStkAlign;
+ alignmentDone = oldArgInfo->alignmentDone;
+ stkSizeBytes = oldArgInfo->stkSizeBytes;
+ padStkAlign = oldArgInfo->padStkAlign;
+#endif
+#if FEATURE_FIXED_OUT_ARGS
+ outArgSize = oldArgInfo->outArgSize;
#endif
argTableSize = oldArgInfo->argTableSize;
argsComplete = false;
@@ -924,22 +929,22 @@ fgArgInfo::fgArgInfo(GenTreePtr newCall, GenTreePtr oldCall)
// so we can iterate over these argument lists more uniformly.
// Need to provide a temporary non-null first arguments to these constructors: if we use them, we'll replace them
GenTreeArgList* newArgs;
- GenTreeArgList newArgObjp(newCall, newCall->gtCall.gtCallArgs);
+ GenTreeArgList newArgObjp(newCall, newCall->gtCallArgs);
GenTreeArgList* oldArgs;
- GenTreeArgList oldArgObjp(oldCall, oldCall->gtCall.gtCallArgs);
+ GenTreeArgList oldArgObjp(oldCall, oldCall->gtCallArgs);
- if (newCall->gtCall.gtCallObjp == nullptr)
+ if (newCall->gtCallObjp == nullptr)
{
- assert(oldCall->gtCall.gtCallObjp == nullptr);
- newArgs = newCall->gtCall.gtCallArgs;
- oldArgs = oldCall->gtCall.gtCallArgs;
+ assert(oldCall->gtCallObjp == nullptr);
+ newArgs = newCall->gtCallArgs;
+ oldArgs = oldCall->gtCallArgs;
}
else
{
- assert(oldCall->gtCall.gtCallObjp != nullptr);
- newArgObjp.Current() = newCall->gtCall.gtCallArgs;
+ assert(oldCall->gtCallObjp != nullptr);
+ newArgObjp.Current() = newCall->gtCallArgs;
newArgs = &newArgObjp;
- oldArgObjp.Current() = oldCall->gtCall.gtCallObjp;
+ oldArgObjp.Current() = oldCall->gtCallObjp;
oldArgs = &oldArgObjp;
}
@@ -1023,8 +1028,8 @@ fgArgInfo::fgArgInfo(GenTreePtr newCall, GenTreePtr oldCall)
if (scanRegArgs)
{
- newArgs = newCall->gtCall.gtCallLateArgs;
- oldArgs = oldCall->gtCall.gtCallLateArgs;
+ newArgs = newCall->gtCallLateArgs;
+ oldArgs = oldCall->gtCallLateArgs;
while (newArgs)
{
@@ -1085,19 +1090,16 @@ fgArgTabEntryPtr fgArgInfo::AddRegArg(
{
fgArgTabEntryPtr curArgTabEntry = new (compiler, CMK_fgArgInfo) fgArgTabEntry;
- curArgTabEntry->argNum = argNum;
- curArgTabEntry->node = node;
- curArgTabEntry->parent = parent;
- curArgTabEntry->regNum = regNum;
- curArgTabEntry->slotNum = 0;
- curArgTabEntry->numRegs = numRegs;
- curArgTabEntry->numSlots = 0;
- curArgTabEntry->alignment = alignment;
- curArgTabEntry->lateArgInx = (unsigned)-1;
- curArgTabEntry->tmpNum = (unsigned)-1;
-#if defined(UNIX_X86_ABI)
- curArgTabEntry->padStkAlign = 0;
-#endif
+ curArgTabEntry->argNum = argNum;
+ curArgTabEntry->node = node;
+ curArgTabEntry->parent = parent;
+ curArgTabEntry->regNum = regNum;
+ curArgTabEntry->slotNum = 0;
+ curArgTabEntry->numRegs = numRegs;
+ curArgTabEntry->numSlots = 0;
+ curArgTabEntry->alignment = alignment;
+ curArgTabEntry->lateArgInx = (unsigned)-1;
+ curArgTabEntry->tmpNum = (unsigned)-1;
curArgTabEntry->isSplit = false;
curArgTabEntry->isTmp = false;
curArgTabEntry->needTmp = false;
@@ -1163,19 +1165,16 @@ fgArgTabEntryPtr fgArgInfo::AddStkArg(unsigned argNum,
curArgTabEntry->isStruct = isStruct; // is this a struct arg
#endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
- curArgTabEntry->argNum = argNum;
- curArgTabEntry->node = node;
- curArgTabEntry->parent = parent;
- curArgTabEntry->regNum = REG_STK;
- curArgTabEntry->slotNum = nextSlotNum;
- curArgTabEntry->numRegs = 0;
- curArgTabEntry->numSlots = numSlots;
- curArgTabEntry->alignment = alignment;
- curArgTabEntry->lateArgInx = (unsigned)-1;
- curArgTabEntry->tmpNum = (unsigned)-1;
-#if defined(UNIX_X86_ABI)
- curArgTabEntry->padStkAlign = 0;
-#endif
+ curArgTabEntry->argNum = argNum;
+ curArgTabEntry->node = node;
+ curArgTabEntry->parent = parent;
+ curArgTabEntry->regNum = REG_STK;
+ curArgTabEntry->slotNum = nextSlotNum;
+ curArgTabEntry->numRegs = 0;
+ curArgTabEntry->numSlots = numSlots;
+ curArgTabEntry->alignment = alignment;
+ curArgTabEntry->lateArgInx = (unsigned)-1;
+ curArgTabEntry->tmpNum = (unsigned)-1;
curArgTabEntry->isSplit = false;
curArgTabEntry->isTmp = false;
curArgTabEntry->needTmp = false;
@@ -1701,52 +1700,6 @@ void fgArgInfo::ArgsComplete()
argsComplete = true;
}
-#if defined(UNIX_X86_ABI)
-// Get the stack alignment value for a Call holding this object
-//
-// NOTE: This function will calculate number of padding slots, to align the
-// stack before pushing arguments to the stack. Padding value is stored in
-// the first argument in fgArgTabEntry structure padStkAlign member so that
-// code (sub esp, n) can be emitted before generating argument push in
-// fgArgTabEntry node. As of result stack will be aligned right before
-// making a "Call". After the Call, stack is re-adjusted to the value it
-// was with fgArgInfo->padStkAlign value as we cann't use the one in fgArgTabEntry.
-//
-void fgArgInfo::ArgsAlignPadding()
-{
- // To get the padding amount, sum up all the slots and get the remainder for padding
- unsigned curInx;
- unsigned numSlots = 0;
- fgArgTabEntryPtr firstArgTabEntry = nullptr;
-
- for (curInx = 0; curInx < argCount; curInx++)
- {
- fgArgTabEntryPtr curArgTabEntry = argTable[curInx];
- if (curArgTabEntry->numSlots > 0)
- {
- // The argument may be REG_STK or constant or register that goes to stack
- assert(nextSlotNum >= curArgTabEntry->slotNum);
-
- numSlots += curArgTabEntry->numSlots;
- if (firstArgTabEntry == nullptr)
- {
- // First argument will be used to hold the padding amount
- firstArgTabEntry = curArgTabEntry;
- }
- }
- }
-
- if (firstArgTabEntry != nullptr)
- {
- const int numSlotsAligned = STACK_ALIGN / TARGET_POINTER_SIZE;
- // Set stack align pad for the first argument
- firstArgTabEntry->padStkAlign = AlignmentPad(numSlots, numSlotsAligned);
- // Set also for fgArgInfo that will be used to reset stack pointer after the Call
- this->padStkAlign = firstArgTabEntry->padStkAlign;
- }
-}
-#endif // UNIX_X86_ABI
-
void fgArgInfo::SortArgs()
{
assert(argsComplete == true);
@@ -2665,10 +2618,8 @@ GenTree* Compiler::fgInsertCommaFormTemp(GenTree** ppTree, CORINFO_CLASS_HANDLE
#pragma warning(push)
#pragma warning(disable : 21000) // Suppress PREFast warning about overly large function
#endif
-GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
+GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call)
{
- GenTreeCall* call = callNode->AsCall();
-
GenTreePtr args;
GenTreePtr argx;
@@ -2838,9 +2789,9 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
// so we record the stack depth on the first morph call when reMorphing
// was false (via RecordStkLevel) and then retrieve that value here (via RetrieveStkLevel)
//
- unsigned callStkLevel = call->fgArgInfo->RetrieveStkLevel();
if (call->gtCallLateArgs != nullptr)
{
+ unsigned callStkLevel = call->fgArgInfo->RetrieveStkLevel();
fgPtrArgCntCur += callStkLevel;
call->gtCallLateArgs = fgMorphTree(call->gtCallLateArgs)->AsArgList();
flagsSummary |= call->gtCallLateArgs->gtFlags;
@@ -2874,9 +2825,9 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
CLANG_FORMAT_COMMENT_ANCHOR;
#if !defined(LEGACY_BACKEND)
-#if defined(_TARGET_X86_)
- // The x86 CORINFO_HELP_INIT_PINVOKE_FRAME helper has a custom calling convention. Set the argument registers
- // correctly here.
+#if defined(_TARGET_X86_) || defined(_TARGET_ARM_)
+ // The x86 and arm32 CORINFO_HELP_INIT_PINVOKE_FRAME helpers has a custom calling convention.
+ // Set the argument registers correctly here.
if (call->IsHelperCall(this, CORINFO_HELP_INIT_PINVOKE_FRAME))
{
GenTreeArgList* args = call->gtCallArgs;
@@ -2884,6 +2835,8 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
assert(arg1 != nullptr);
nonStandardArgs.Add(arg1, REG_PINVOKE_FRAME);
}
+#endif // defined(_TARGET_X86_) || defined(_TARGET_ARM_)
+#if defined(_TARGET_X86_)
// The x86 shift helpers have custom calling conventions and expect the lo part of the long to be in EAX and the
// hi part to be in EDX. This sets the argument registers up correctly.
else if (call->IsHelperCall(this, CORINFO_HELP_LLSH) || call->IsHelperCall(this, CORINFO_HELP_LRSH) ||
@@ -4286,10 +4239,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
{
call->fgArgInfo->ArgsComplete();
-#if defined(UNIX_X86_ABI)
- call->fgArgInfo->ArgsAlignPadding();
-#endif // UNIX_X86_ABI
-
#ifdef LEGACY_BACKEND
call->gtCallRegUsedMask = genIntAllRegArgMask(intArgRegNum);
#if defined(_TARGET_ARM_)
@@ -4327,19 +4276,23 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
if (fgPtrArgCntMax < fgPtrArgCntCur)
{
+ JITDUMP("Upping fgPtrArgCntMax from %d to %d\n", fgPtrArgCntMax, fgPtrArgCntCur);
fgPtrArgCntMax = fgPtrArgCntCur;
}
+ assert(fgPtrArgCntCur >= genPtrArgCntSav);
+ call->fgArgInfo->SetStkSizeBytes((fgPtrArgCntCur - genPtrArgCntSav) * TARGET_POINTER_SIZE);
+
/* The call will pop all the arguments we pushed */
fgPtrArgCntCur = genPtrArgCntSav;
#if FEATURE_FIXED_OUT_ARGS
- // Update the outgoing argument size.
- // If the call is a fast tail call, it will setup its arguments in incoming arg
- // area instead of the out-going arg area. Therefore, don't consider fast tail
- // calls to update lvaOutgoingArgSpaceSize.
+ // Record the outgoing argument size. If the call is a fast tail
+ // call, it will setup its arguments in incoming arg area instead
+ // of the out-going arg area, so we don't need to track the
+ // outgoing arg size.
if (!call->IsFastTailCall())
{
unsigned preallocatedArgCount = call->fgArgInfo->GetNextSlotNum();
@@ -4359,26 +4312,14 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
}
#endif // UNIX_AMD64_ABI
- // Check if we need to increase the size of our Outgoing Arg Space
- if (preallocatedArgCount * REGSIZE_BYTES > lvaOutgoingArgSpaceSize)
- {
- lvaOutgoingArgSpaceSize = preallocatedArgCount * REGSIZE_BYTES;
+ const unsigned outgoingArgSpaceSize = preallocatedArgCount * REGSIZE_BYTES;
+ call->fgArgInfo->SetOutArgSize(max(outgoingArgSpaceSize, MIN_ARG_AREA_FOR_CALL));
- // If a function has localloc, we will need to move the outgoing arg space when the
- // localloc happens. When we do this, we need to maintain stack alignment. To avoid
- // leaving alignment-related holes when doing this move, make sure the outgoing
- // argument space size is a multiple of the stack alignment by aligning up to the next
- // stack alignment boundary.
- if (compLocallocUsed)
- {
- lvaOutgoingArgSpaceSize = (unsigned)roundUp(lvaOutgoingArgSpaceSize, STACK_ALIGN);
- }
- }
#ifdef DEBUG
if (verbose)
{
- printf("argSlots=%d, preallocatedArgCount=%d, nextSlotNum=%d, lvaOutgoingArgSpaceSize=%d\n", argSlots,
- preallocatedArgCount, call->fgArgInfo->GetNextSlotNum(), lvaOutgoingArgSpaceSize);
+ printf("argSlots=%d, preallocatedArgCount=%d, nextSlotNum=%d, outgoingArgSpaceSize=%d\n", argSlots,
+ preallocatedArgCount, call->fgArgInfo->GetNextSlotNum(), outgoingArgSpaceSize);
}
#endif
}
@@ -5047,7 +4988,7 @@ GenTreePtr Compiler::fgMorphMultiregStructArg(GenTreePtr arg, fgArgTabEntryPtr f
// replace the existing LDOBJ(ADDR(LCLVAR))
// with a FIELD_LIST(LCLFLD-LO, FIELD_LIST(LCLFLD-HI, nullptr) ...)
//
- unsigned offset = 0;
+ unsigned offset = baseOffset;
GenTreeFieldList* listEntry = nullptr;
for (unsigned inx = 0; inx < elemCount; inx++)
{
@@ -6163,6 +6104,14 @@ GenTreePtr Compiler::fgMorphField(GenTreePtr tree, MorphAddrContext* mac)
return newTree;
}
}
+ else if ((objRef != nullptr) && (objRef->OperGet() == GT_ADDR) && varTypeIsSIMD(objRef->gtGetOp1()))
+ {
+ GenTreeLclVarCommon* lcl = objRef->IsLocalAddrExpr();
+ if (lcl != nullptr)
+ {
+ lvaSetVarDoNotEnregister(lcl->gtLclNum DEBUGARG(DNER_LocalField));
+ }
+ }
#endif
/* Is this an instance data member? */
@@ -6735,8 +6684,10 @@ void Compiler::fgMorphCallInlineHelper(GenTreeCall* call, InlineResult* result)
printTreeID(fgMorphStmt);
printf(" in BB%02u:\n", compCurBB->bbNum);
gtDispTree(fgMorphStmt);
-
- // printf("startVars=%d.\n", startVars);
+ if (call->IsImplicitTailCall())
+ {
+ printf("Note: candidate is implicit tail call\n");
+ }
}
#endif
@@ -7865,6 +7816,9 @@ GenTreePtr Compiler::fgMorphCall(GenTreeCall* call)
// Either a call stmt or
// GT_RETURN(GT_CALL(..)) or GT_RETURN(GT_CAST(GT_CALL(..)))
// var = GT_CALL(..) or var = (GT_CAST(GT_CALL(..)))
+ // GT_COMMA(GT_CALL(..), GT_NOP) or GT_COMMA(GT_CAST(GT_CALL(..)), GT_NOP)
+ // In the above,
+ // GT_CASTS may be nested.
genTreeOps stmtOper = stmtExpr->gtOper;
if (stmtOper == GT_CALL)
{
@@ -7872,24 +7826,31 @@ GenTreePtr Compiler::fgMorphCall(GenTreeCall* call)
}
else
{
- noway_assert(stmtOper == GT_RETURN || stmtOper == GT_ASG);
+ noway_assert(stmtOper == GT_RETURN || stmtOper == GT_ASG || stmtOper == GT_COMMA);
GenTreePtr treeWithCall;
if (stmtOper == GT_RETURN)
{
treeWithCall = stmtExpr->gtGetOp1();
}
- else
+ else if (stmtOper == GT_COMMA)
{
- treeWithCall = stmtExpr->gtGetOp2();
+ // Second operation must be nop.
+ noway_assert(stmtExpr->gtGetOp2()->IsNothingNode());
+ treeWithCall = stmtExpr->gtGetOp1();
}
- if (treeWithCall->gtOper == GT_CAST)
+ else
{
- noway_assert(treeWithCall->gtGetOp1() == call && !treeWithCall->gtOverflow());
+ treeWithCall = stmtExpr->gtGetOp2();
}
- else
+
+ // Peel off casts
+ while (treeWithCall->gtOper == GT_CAST)
{
- noway_assert(treeWithCall == call);
+ noway_assert(!treeWithCall->gtOverflow());
+ treeWithCall = treeWithCall->gtGetOp1();
}
+
+ noway_assert(treeWithCall == call);
}
#endif
@@ -7909,10 +7870,11 @@ GenTreePtr Compiler::fgMorphCall(GenTreeCall* call)
// 2) tail.call, nop*, pop, nop*, ret
// 3) var=tail.call, nop*, ret(var)
// 4) var=tail.call, nop*, pop, ret
+ // 5) comma(tail.call, nop), nop*, ret
//
// See impIsTailCallILPattern() for details on tail call IL patterns
// that are supported.
- if ((stmtExpr->gtOper == GT_CALL) || (stmtExpr->gtOper == GT_ASG))
+ if (stmtExpr->gtOper != GT_RETURN)
{
// First delete all GT_NOPs after the call
GenTreeStmt* morphStmtToRemove = nullptr;
@@ -7940,7 +7902,16 @@ GenTreePtr Compiler::fgMorphCall(GenTreeCall* call)
GenTreeStmt* popStmt = nextMorphStmt;
nextMorphStmt = nextMorphStmt->gtNextStmt;
- noway_assert((popStmt->gtStmtExpr->gtFlags & GTF_ALL_EFFECT) == 0);
+ // Side effect flags on a GT_COMMA may be overly pessimistic, so examine
+ // the constituent nodes.
+ GenTreePtr popExpr = popStmt->gtStmtExpr;
+ bool isSideEffectFree = (popExpr->gtFlags & GTF_ALL_EFFECT) == 0;
+ if (!isSideEffectFree && (popExpr->OperGet() == GT_COMMA))
+ {
+ isSideEffectFree = ((popExpr->gtGetOp1()->gtFlags & GTF_ALL_EFFECT) == 0) &&
+ ((popExpr->gtGetOp2()->gtFlags & GTF_ALL_EFFECT) == 0);
+ }
+ noway_assert(isSideEffectFree);
fgRemoveStmt(compCurBB, popStmt);
}
@@ -9658,6 +9629,7 @@ GenTreePtr Compiler::fgMorphCopyBlock(GenTreePtr tree)
assert(dest->gtOper == GT_LCL_FLD);
blockWidth = genTypeSize(dest->TypeGet());
destAddr = gtNewOperNode(GT_ADDR, TYP_BYREF, dest);
+ destFldSeq = dest->AsLclFld()->gtFieldSeq;
}
}
else
@@ -9779,12 +9751,13 @@ GenTreePtr Compiler::fgMorphCopyBlock(GenTreePtr tree)
// Check to see if we are required to do a copy block because the struct contains holes
// and either the src or dest is externally visible
//
- bool requiresCopyBlock = false;
- bool srcSingleLclVarAsg = false;
+ bool requiresCopyBlock = false;
+ bool srcSingleLclVarAsg = false;
+ bool destSingleLclVarAsg = false;
- if ((destLclVar != nullptr) && (srcLclVar == destLclVar))
+ if ((destLclVar != nullptr) && (srcLclVar == destLclVar) && (destFldSeq == srcFldSeq))
{
- // Beyond perf reasons, it is not prudent to have a copy of a struct to itself.
+ // Self-assign; no effect.
GenTree* nop = gtNewNothingNode();
INDEBUG(nop->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED);
return nop;
@@ -9896,6 +9869,30 @@ GenTreePtr Compiler::fgMorphCopyBlock(GenTreePtr tree)
}
}
}
+ else
+ {
+ assert(srcDoFldAsg);
+ // Check for the symmetric case (which happens for the _pointer field of promoted spans):
+ //
+ // [000240] -----+------ /--* lclVar struct(P) V18 tmp9
+ // /--* byref V18._value (offs=0x00) -> V30 tmp21
+ // [000245] -A------R--- * = struct (copy)
+ // [000244] -----+------ \--* obj(8) struct
+ // [000243] -----+------ \--* addr byref
+ // [000242] D----+-N---- \--* lclVar byref V28 tmp19
+ //
+ if (blockWidthIsConst && (srcLclVar->lvFieldCnt == 1) && (destLclVar != nullptr) &&
+ (blockWidth == genTypeSize(destLclVar->TypeGet())))
+ {
+ // Check for type agreement
+ unsigned fieldLclNum = lvaTable[srcLclNum].lvFieldLclStart;
+ var_types srcType = lvaTable[fieldLclNum].TypeGet();
+ if (destLclVar->TypeGet() == srcType)
+ {
+ destSingleLclVarAsg = true;
+ }
+ }
+ }
}
// If we require a copy block the set both of the field assign bools to false
@@ -9912,7 +9909,7 @@ GenTreePtr Compiler::fgMorphCopyBlock(GenTreePtr tree)
// when they are not reg-sized non-field-addressed structs and we are using a CopyBlock
// or the struct is not promoted
//
- if (!destDoFldAsg && (destLclVar != nullptr))
+ if (!destDoFldAsg && (destLclVar != nullptr) && !destSingleLclVarAsg)
{
if (!destLclVar->lvRegStruct)
{
@@ -10166,45 +10163,56 @@ GenTreePtr Compiler::fgMorphCopyBlock(GenTreePtr tree)
noway_assert(srcLclNum != BAD_VAR_NUM);
unsigned fieldLclNum = lvaTable[srcLclNum].lvFieldLclStart + i;
- if (addrSpill)
+ if (destSingleLclVarAsg)
{
- assert(addrSpillTemp != BAD_VAR_NUM);
- dest = gtNewLclvNode(addrSpillTemp, TYP_BYREF);
+ noway_assert(fieldCnt == 1);
+ noway_assert(destLclVar != nullptr);
+ noway_assert(addrSpill == nullptr);
+
+ dest = gtNewLclvNode(destLclNum, destLclVar->TypeGet());
}
else
{
- dest = gtCloneExpr(destAddr);
- noway_assert(dest != nullptr);
-
- // Is the address of a local?
- GenTreeLclVarCommon* lclVarTree = nullptr;
- bool isEntire = false;
- bool* pIsEntire = (blockWidthIsConst ? &isEntire : nullptr);
- if (dest->DefinesLocalAddr(this, blockWidth, &lclVarTree, pIsEntire))
+ if (addrSpill)
+ {
+ assert(addrSpillTemp != BAD_VAR_NUM);
+ dest = gtNewLclvNode(addrSpillTemp, TYP_BYREF);
+ }
+ else
{
- lclVarTree->gtFlags |= GTF_VAR_DEF;
- if (!isEntire)
+ dest = gtCloneExpr(destAddr);
+ noway_assert(dest != nullptr);
+
+ // Is the address of a local?
+ GenTreeLclVarCommon* lclVarTree = nullptr;
+ bool isEntire = false;
+ bool* pIsEntire = (blockWidthIsConst ? &isEntire : nullptr);
+ if (dest->DefinesLocalAddr(this, blockWidth, &lclVarTree, pIsEntire))
{
- lclVarTree->gtFlags |= GTF_VAR_USEASG;
+ lclVarTree->gtFlags |= GTF_VAR_DEF;
+ if (!isEntire)
+ {
+ lclVarTree->gtFlags |= GTF_VAR_USEASG;
+ }
}
}
- }
- GenTreePtr fieldOffsetNode = gtNewIconNode(lvaTable[fieldLclNum].lvFldOffset, TYP_I_IMPL);
- // Have to set the field sequence -- which means we need the field handle.
- CORINFO_CLASS_HANDLE classHnd = lvaTable[srcLclNum].lvVerTypeInfo.GetClassHandle();
- CORINFO_FIELD_HANDLE fieldHnd =
- info.compCompHnd->getFieldInClass(classHnd, lvaTable[fieldLclNum].lvFldOrdinal);
- curFieldSeq = GetFieldSeqStore()->CreateSingleton(fieldHnd);
- fieldOffsetNode->gtIntCon.gtFieldSeq = curFieldSeq;
+ GenTreePtr fieldOffsetNode = gtNewIconNode(lvaTable[fieldLclNum].lvFldOffset, TYP_I_IMPL);
+ // Have to set the field sequence -- which means we need the field handle.
+ CORINFO_CLASS_HANDLE classHnd = lvaTable[srcLclNum].lvVerTypeInfo.GetClassHandle();
+ CORINFO_FIELD_HANDLE fieldHnd =
+ info.compCompHnd->getFieldInClass(classHnd, lvaTable[fieldLclNum].lvFldOrdinal);
+ curFieldSeq = GetFieldSeqStore()->CreateSingleton(fieldHnd);
+ fieldOffsetNode->gtIntCon.gtFieldSeq = curFieldSeq;
- dest = gtNewOperNode(GT_ADD, TYP_BYREF, dest, fieldOffsetNode);
+ dest = gtNewOperNode(GT_ADD, TYP_BYREF, dest, fieldOffsetNode);
- dest = gtNewOperNode(GT_IND, lvaTable[fieldLclNum].TypeGet(), dest);
+ dest = gtNewOperNode(GT_IND, lvaTable[fieldLclNum].TypeGet(), dest);
- // !!! The destination could be on stack. !!!
- // This flag will let us choose the correct write barrier.
- dest->gtFlags |= GTF_IND_TGTANYWHERE;
+ // !!! The destination could be on stack. !!!
+ // This flag will let us choose the correct write barrier.
+ dest->gtFlags |= GTF_IND_TGTANYWHERE;
+ }
}
if (srcDoFldAsg)
@@ -10849,7 +10857,6 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
op1->gtOp.gtOp1 = gtNewOperNode(GT_NOP, TYP_INT, op1->gtCast.CastOp());
op1->gtFlags &= ~GTF_ALL_EFFECT;
op1->gtFlags |= (op1->gtCast.CastOp()->gtFlags & GTF_ALL_EFFECT);
- op1->gtFlags |= GTF_DONT_CSE;
}
if (op2->gtCast.CastOp()->OperGet() != GT_NOP)
@@ -10857,9 +10864,11 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
op2->gtOp.gtOp1 = gtNewOperNode(GT_NOP, TYP_INT, op2->gtCast.CastOp());
op2->gtFlags &= ~GTF_ALL_EFFECT;
op2->gtFlags |= (op2->gtCast.CastOp()->gtFlags & GTF_ALL_EFFECT);
- op2->gtFlags |= GTF_DONT_CSE;
}
+ op1->gtFlags |= GTF_DONT_CSE;
+ op2->gtFlags |= GTF_DONT_CSE;
+
tree->gtFlags &= ~GTF_ALL_EFFECT;
tree->gtFlags |= ((op1->gtFlags | op2->gtFlags) & GTF_ALL_EFFECT);
@@ -11178,11 +11187,13 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
GenTreePtr pGetType;
#ifdef LEGACY_BACKEND
- bool bOp1ClassFromHandle = gtIsTypeHandleToRuntimeTypeHelper(op1);
- bool bOp2ClassFromHandle = gtIsTypeHandleToRuntimeTypeHelper(op2);
+ bool bOp1ClassFromHandle = gtIsTypeHandleToRuntimeTypeHelper(op1->AsCall());
+ bool bOp2ClassFromHandle = gtIsTypeHandleToRuntimeTypeHelper(op2->AsCall());
#else
- bool bOp1ClassFromHandle = op1->gtOper == GT_CALL ? gtIsTypeHandleToRuntimeTypeHelper(op1) : false;
- bool bOp2ClassFromHandle = op2->gtOper == GT_CALL ? gtIsTypeHandleToRuntimeTypeHelper(op2) : false;
+ bool bOp1ClassFromHandle =
+ op1->gtOper == GT_CALL ? gtIsTypeHandleToRuntimeTypeHelper(op1->AsCall()) : false;
+ bool bOp2ClassFromHandle =
+ op2->gtOper == GT_CALL ? gtIsTypeHandleToRuntimeTypeHelper(op2->AsCall()) : false;
#endif
// Optimize typeof(...) == typeof(...)
@@ -12244,6 +12255,23 @@ GenTreePtr Compiler::fgMorphSmpOp(GenTreePtr tree, MorphAddrContext* mac)
}
}
}
+ else // we have an unsigned comparison
+ {
+ if (op2->IsIntegralConst(0))
+ {
+ if ((oper == GT_GT) || (oper == GT_LE))
+ {
+ // IL doesn't have a cne instruction so compilers use cgt.un instead. The JIT
+ // recognizes certain patterns that involve GT_NE (e.g (x & 4) != 0) and fails
+ // if GT_GT is used instead. Transform (x GT_GT.unsigned 0) into (x GT_NE 0)
+ // and (x GT_LE.unsigned 0) into (x GT_EQ 0). The later case is rare, it sometimes
+ // occurs as a result of branch inversion.
+ oper = (oper == GT_LE) ? GT_EQ : GT_NE;
+ tree->SetOper(oper, GenTree::PRESERVE_VN);
+ tree->gtFlags &= ~GTF_UNSIGNED;
+ }
+ }
+ }
COMPARE:
@@ -14157,13 +14185,13 @@ GenTreePtr Compiler::fgRecognizeAndMorphBitwiseRotation(GenTreePtr tree)
//
// OR ROL
// / \ / \
- // LSH RSZ -> x y
+ // LSH RSZ -> x y
// / \ / \
- // x AND x AND
+ // x AND x AND
// / \ / \
- // y 31 ADD 31
+ // y 31 ADD 31
// / \
- // NEG 32
+ // NEG 32
// |
// y
// The patterns recognized:
@@ -14534,7 +14562,10 @@ GenTreePtr Compiler::fgMorphToEmulatedFP(GenTreePtr tree)
tree = fgMorphIntoHelperCall(tree, helper, args);
if (fgPtrArgCntMax < fgPtrArgCntCur)
+ {
+ JITDUMP("Upping fgPtrArgCntMax from %d to %d\n", fgPtrArgCntMax, fgPtrArgCntCur);
fgPtrArgCntMax = fgPtrArgCntCur;
+ }
fgPtrArgCntCur -= argc;
return tree;
@@ -15090,13 +15121,13 @@ bool Compiler::fgFoldConditional(BasicBlock* block)
// else if bTaken has valid profile weight and block does not we try to adjust block's weight
// We can only adjust the block weights when (the edge block -> bTaken) is the only edge into bTaken
//
- if (block->bbFlags & BBF_PROF_WEIGHT)
+ if (block->hasProfileWeight())
{
// The edge weights for (block -> bTaken) are 100% of block's weight
edgeTaken->flEdgeWeightMin = block->bbWeight;
edgeTaken->flEdgeWeightMax = block->bbWeight;
- if ((bTaken->bbFlags & BBF_PROF_WEIGHT) == 0)
+ if (!bTaken->hasProfileWeight())
{
if ((bTaken->countOfInEdges() == 1) || (bTaken->bbWeight < block->bbWeight))
{
@@ -15106,7 +15137,7 @@ bool Compiler::fgFoldConditional(BasicBlock* block)
}
}
}
- else if (bTaken->bbFlags & BBF_PROF_WEIGHT)
+ else if (bTaken->hasProfileWeight())
{
if (bTaken->countOfInEdges() == 1)
{
@@ -16171,7 +16202,9 @@ void Compiler::fgSetOptions()
// to use a frame pointer because of EH. But until all the code uses
// the same test, leave info.compXcptnsCount here.
if (info.compXcptnsCount > 0)
+ {
codeGen->setFramePointerRequiredEH(true);
+ }
#else // !_TARGET_X86_
@@ -16182,6 +16215,15 @@ void Compiler::fgSetOptions()
#endif // _TARGET_X86_
+#ifdef UNIX_X86_ABI
+ if (info.compXcptnsCount > 0)
+ {
+ assert(!codeGen->isGCTypeFixed());
+ // Enforce fully interruptible codegen for funclet unwinding
+ genInterruptible = true;
+ }
+#endif // UNIX_X86_ABI
+
fgCheckArgCnt();
if (info.compCallUnmanaged)
@@ -16250,6 +16292,15 @@ GenTreePtr Compiler::fgInitThisClass()
CORINFO_RESOLVED_TOKEN resolvedToken;
memset(&resolvedToken, 0, sizeof(resolvedToken));
+ // We are in a shared method body, but maybe we don't need a runtime lookup after all.
+ // This covers the case of a generic method on a non-generic type.
+ if (!(info.compClassAttr & CORINFO_FLG_SHAREDINST))
+ {
+ resolvedToken.hClass = info.compClassHnd;
+ return impReadyToRunHelperToTree(&resolvedToken, CORINFO_HELP_READYTORUN_STATIC_BASE, TYP_BYREF);
+ }
+
+ // We need a runtime lookup.
GenTreePtr ctxTree = getRuntimeContextTree(kind.runtimeLookupKind);
// CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE with a zeroed out resolvedToken means "get the static
@@ -16263,7 +16314,7 @@ GenTreePtr Compiler::fgInitThisClass()
// Collectible types requires that for shared generic code, if we use the generic context paramter
// that we report it. (This is a conservative approach, we could detect some cases particularly when the
// context parameter is this that we don't need the eager reporting logic.)
- lvaGenericsContextUsed = true;
+ lvaGenericsContextUseCount++;
switch (kind.runtimeLookupKind)
{
@@ -16952,6 +17003,10 @@ void Compiler::fgMorph()
EndPhase(PHASE_EMPTY_FINALLY);
+ fgMergeFinallyChains();
+
+ EndPhase(PHASE_MERGE_FINALLY_CHAINS);
+
fgCloneFinally();
EndPhase(PHASE_CLONE_FINALLY);
@@ -17072,13 +17127,11 @@ void Compiler::fgPromoteStructs()
#endif // DEBUG
// The lvaTable might grow as we grab temps. Make a local copy here.
-
unsigned startLvaCount = lvaCount;
//
// Loop through the original lvaTable. Looking for struct locals to be promoted.
//
-
lvaStructPromotionInfo structPromotionInfo;
bool tooManyLocals = false;
@@ -17088,13 +17141,14 @@ void Compiler::fgPromoteStructs()
bool promotedVar = false;
LclVarDsc* varDsc = &lvaTable[lclNum];
+ // If we have marked this as lvUsedInSIMDIntrinsic, then we do not want to promote
+ // its fields. Instead, we will attempt to enregister the entire struct.
if (varDsc->lvIsSIMDType() && varDsc->lvIsUsedInSIMDIntrinsic())
{
- // If we have marked this as lvUsedInSIMDIntrinsic, then we do not want to promote
- // its fields. Instead, we will attempt to enregister the entire struct.
varDsc->lvRegStruct = true;
}
- else if (lvaHaveManyLocals()) // Don't promote if we have reached the tracking limit.
+ // Don't promote if we have reached the tracking limit.
+ else if (lvaHaveManyLocals())
{
// Print the message first time when we detected this condition
if (!tooManyLocals)
@@ -17103,159 +17157,56 @@ void Compiler::fgPromoteStructs()
}
tooManyLocals = true;
}
-#if !FEATURE_MULTIREG_STRUCT_PROMOTE
- else if (varDsc->lvIsMultiRegArg)
- {
- JITDUMP("Skipping V%02u: marked lvIsMultiRegArg.\n", lclNum);
- }
-#endif // !FEATURE_MULTIREG_STRUCT_PROMOTE
- else if (varDsc->lvIsMultiRegRet)
- {
- JITDUMP("Skipping V%02u: marked lvIsMultiRegRet.\n", lclNum);
- }
else if (varTypeIsStruct(varDsc))
{
- lvaCanPromoteStructVar(lclNum, &structPromotionInfo);
- bool canPromote = structPromotionInfo.canPromote;
-
- // We start off with shouldPromote same as canPromote.
- // Based on further profitablity checks done below, shouldPromote
- // could be set to false.
- bool shouldPromote = canPromote;
-
- if (canPromote)
- {
- // We *can* promote; *should* we promote?
- // We should only do so if promotion has potential savings. One source of savings
- // is if a field of the struct is accessed, since this access will be turned into
- // an access of the corresponding promoted field variable. Even if there are no
- // field accesses, but only block-level operations on the whole struct, if the struct
- // has only one or two fields, then doing those block operations field-wise is probably faster
- // than doing a whole-variable block operation (e.g., a hardware "copy loop" on x86).
- // Struct promotion also provides the following benefits: reduce stack frame size,
- // reduce the need for zero init of stack frame and fine grained constant/copy prop.
- // Asm diffs indicate that promoting structs up to 3 fields is a net size win.
- // So if no fields are accessed independently, and there are four or more fields,
- // then do not promote.
- //
- // TODO: Ideally we would want to consider the impact of whether the struct is
- // passed as a parameter or assigned the return value of a call. Because once promoted,
- // struct copying is done by field by field assignment instead of a more efficient
- // rep.stos or xmm reg based copy.
- if (structPromotionInfo.fieldCnt > 3 && !varDsc->lvFieldAccessed)
- {
- JITDUMP("Not promoting promotable struct local V%02u: #fields = %d, fieldAccessed = %d.\n", lclNum,
- structPromotionInfo.fieldCnt, varDsc->lvFieldAccessed);
- shouldPromote = false;
- }
-#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
- // TODO-PERF - Only do this when the LclVar is used in an argument context
- // TODO-ARM64 - HFA support should also eliminate the need for this.
- // TODO-LSRA - Currently doesn't support the passing of floating point LCL_VARS in the integer registers
- //
- // For now we currently don't promote structs with a single float field
- // Promoting it can cause us to shuffle it back and forth between the int and
- // the float regs when it is used as a argument, which is very expensive for XARCH
- //
- else if ((structPromotionInfo.fieldCnt == 1) &&
- varTypeIsFloating(structPromotionInfo.fields[0].fldType))
- {
- JITDUMP("Not promoting promotable struct local V%02u: #fields = %d because it is a struct with "
- "single float field.\n",
- lclNum, structPromotionInfo.fieldCnt);
- shouldPromote = false;
- }
-#endif // _TARGET_AMD64_ || _TARGET_ARM64_
+ bool shouldPromote;
-#if !FEATURE_MULTIREG_STRUCT_PROMOTE
-#if defined(_TARGET_ARM64_)
- //
- // For now we currently don't promote structs that are passed in registers
- //
- else if (lvaIsMultiregStruct(varDsc))
- {
- JITDUMP("Not promoting promotable multireg struct local V%02u (size==%d): ", lclNum,
- lvaLclExactSize(lclNum));
- shouldPromote = false;
- }
-#endif // _TARGET_ARM64_
-#endif // !FEATURE_MULTIREG_STRUCT_PROMOTE
- else if (varDsc->lvIsParam)
- {
-#if FEATURE_MULTIREG_STRUCT_PROMOTE
- if (lvaIsMultiregStruct(
- varDsc) && // Is this a variable holding a value that is passed in multiple registers?
- (structPromotionInfo.fieldCnt != 2)) // Does it have exactly two fields
- {
- JITDUMP(
- "Not promoting multireg struct local V%02u, because lvIsParam is true and #fields != 2\n",
- lclNum);
- shouldPromote = false;
- }
- else
-#endif // !FEATURE_MULTIREG_STRUCT_PROMOTE
-
- // TODO-PERF - Implement struct promotion for incoming multireg structs
- // Currently it hits assert(lvFieldCnt==1) in lclvar.cpp line 4417
-
- if (structPromotionInfo.fieldCnt != 1)
- {
- JITDUMP("Not promoting promotable struct local V%02u, because lvIsParam is true and #fields = "
- "%d.\n",
- lclNum, structPromotionInfo.fieldCnt);
- shouldPromote = false;
- }
- }
-
- //
- // If the lvRefCnt is zero and we have a struct promoted parameter we can end up with an extra store of
- // the the incoming register into the stack frame slot.
- // In that case, we would like to avoid promortion.
- // However we haven't yet computed the lvRefCnt values so we can't do that.
- //
- CLANG_FORMAT_COMMENT_ANCHOR;
+ lvaCanPromoteStructVar(lclNum, &structPromotionInfo);
+ if (structPromotionInfo.canPromote)
+ {
+ shouldPromote = lvaShouldPromoteStructVar(lclNum, &structPromotionInfo);
+ }
+ else
+ {
+ shouldPromote = false;
+ }
#if 0
- // Often-useful debugging code: if you've narrowed down a struct-promotion problem to a single
- // method, this allows you to select a subset of the vars to promote (by 1-based ordinal number).
- static int structPromoVarNum = 0;
- structPromoVarNum++;
- if (atoi(getenv("structpromovarnumlo")) <= structPromoVarNum && structPromoVarNum <= atoi(getenv("structpromovarnumhi")))
+ // Often-useful debugging code: if you've narrowed down a struct-promotion problem to a single
+ // method, this allows you to select a subset of the vars to promote (by 1-based ordinal number).
+ static int structPromoVarNum = 0;
+ structPromoVarNum++;
+ if (atoi(getenv("structpromovarnumlo")) <= structPromoVarNum && structPromoVarNum <= atoi(getenv("structpromovarnumhi")))
#endif // 0
- if (shouldPromote)
- {
- assert(canPromote);
-
- // Promote the this struct local var.
- lvaPromoteStructVar(lclNum, &structPromotionInfo);
- promotedVar = true;
+ if (shouldPromote)
+ {
+ // Promote the this struct local var.
+ lvaPromoteStructVar(lclNum, &structPromotionInfo);
+ promotedVar = true;
#ifdef _TARGET_ARM_
- if (structPromotionInfo.requiresScratchVar)
+ if (structPromotionInfo.requiresScratchVar)
+ {
+ // Ensure that the scratch variable is allocated, in case we
+ // pass a promoted struct as an argument.
+ if (lvaPromotedStructAssemblyScratchVar == BAD_VAR_NUM)
{
- // Ensure that the scratch variable is allocated, in case we
- // pass a promoted struct as an argument.
- if (lvaPromotedStructAssemblyScratchVar == BAD_VAR_NUM)
- {
- lvaPromotedStructAssemblyScratchVar =
- lvaGrabTempWithImplicitUse(false DEBUGARG("promoted struct assembly scratch var."));
- lvaTable[lvaPromotedStructAssemblyScratchVar].lvType = TYP_I_IMPL;
- }
+ lvaPromotedStructAssemblyScratchVar =
+ lvaGrabTempWithImplicitUse(false DEBUGARG("promoted struct assembly scratch var."));
+ lvaTable[lvaPromotedStructAssemblyScratchVar].lvType = TYP_I_IMPL;
}
-#endif // _TARGET_ARM_
}
+#endif // _TARGET_ARM_
}
}
-#ifdef FEATURE_SIMD
- if (!promotedVar && varDsc->lvSIMDType && !varDsc->lvFieldAccessed)
+ if (!promotedVar && varDsc->lvIsSIMDType() && !varDsc->lvFieldAccessed)
{
// Even if we have not used this in a SIMD intrinsic, if it is not being promoted,
// we will treat it as a reg struct.
varDsc->lvRegStruct = true;
}
-#endif // FEATURE_SIMD
}
#ifdef DEBUG
@@ -17298,10 +17249,30 @@ Compiler::fgWalkResult Compiler::fgMorphStructField(GenTreePtr tree, fgWalkData*
tree->gtFlags &= ~GTF_GLOB_REF;
GenTreePtr parent = fgWalkPre->parentStack->Index(1);
- if ((parent->gtOper == GT_ASG) && (parent->gtOp.gtOp1 == tree))
+ if (parent->gtOper == GT_ASG)
{
- tree->gtFlags |= GTF_VAR_DEF;
- tree->gtFlags |= GTF_DONT_CSE;
+ if (parent->gtOp.gtOp1 == tree)
+ {
+ tree->gtFlags |= GTF_VAR_DEF;
+ tree->gtFlags |= GTF_DONT_CSE;
+ }
+
+ // Promotion of struct containing struct fields where the field
+ // is a struct with a single pointer sized scalar type field: in
+ // this case struct promotion uses the type of the underlying
+ // scalar field as the type of struct field instead of recursively
+ // promoting. This can lead to a case where we have a block-asgn
+ // with its RHS replaced with a scalar type. Mark RHS value as
+ // DONT_CSE so that assertion prop will not do const propagation.
+ // The reason this is required is that if RHS of a block-asg is a
+ // constant, then it is interpreted as init-block incorrectly.
+ //
+ // TODO - This can also be avoided if we implement recursive struct
+ // promotion.
+ if (varTypeIsStruct(parent) && parent->gtOp.gtOp2 == tree && !varTypeIsStruct(tree))
+ {
+ tree->gtFlags |= GTF_DONT_CSE;
+ }
}
#ifdef DEBUG
if (verbose)
diff --git a/src/jit/optcse.cpp b/src/jit/optcse.cpp
index 5ee6d84920..41aad403d9 100644
--- a/src/jit/optcse.cpp
+++ b/src/jit/optcse.cpp
@@ -321,8 +321,8 @@ Compiler::fgWalkResult Compiler::optCSE_MaskHelper(GenTreePtr* pTree, fgWalkData
//
void Compiler::optCSE_GetMaskData(GenTreePtr tree, optCSE_MaskData* pMaskData)
{
- pMaskData->CSE_defMask = BitVecOps::MakeCopy(cseTraits, cseEmpty);
- pMaskData->CSE_useMask = BitVecOps::MakeCopy(cseTraits, cseEmpty);
+ pMaskData->CSE_defMask = BitVecOps::MakeEmpty(cseTraits);
+ pMaskData->CSE_useMask = BitVecOps::MakeEmpty(cseTraits);
fgWalkTreePre(&tree, optCSE_MaskHelper, (void*)pMaskData);
}
@@ -498,10 +498,7 @@ void Compiler::optValnumCSE_Init()
// Init traits and full/empty bitvectors. This will be used to track the
// individual cse indexes.
cseTraits = new (getAllocator()) BitVecTraits(EXPSET_SZ, this);
- cseFull = BitVecOps::UninitVal();
- cseEmpty = BitVecOps::UninitVal();
- BitVecOps::AssignNoCopy(cseTraits, cseFull, BitVecOps::MakeFull(cseTraits));
- BitVecOps::AssignNoCopy(cseTraits, cseEmpty, BitVecOps::MakeEmpty(cseTraits));
+ cseFull = BitVecOps::MakeFull(cseTraits);
/* Allocate and clear the hash bucket table */
@@ -509,6 +506,9 @@ void Compiler::optValnumCSE_Init()
optCSECandidateCount = 0;
optDoCSE = false; // Stays false until we find duplicate CSE tree
+
+ // optCseArrLenMap is unused in most functions, allocated only when used
+ optCseArrLenMap = nullptr;
}
/*****************************************************************************
@@ -700,8 +700,17 @@ unsigned Compiler::optValnumCSE_Locate()
noway_assert(stmt->gtOper == GT_STMT);
/* We walk the tree in the forwards direction (bottom up) */
+ bool stmtHasArrLenCandidate = false;
for (tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
{
+ if (tree->OperIsCompare() && stmtHasArrLenCandidate)
+ {
+ // Check if this compare is a function of (one of) the arrary
+ // length candidate(s); we may want to update its value number
+ // if the array length gets CSEd
+ optCseUpdateArrLenMap(tree);
+ }
+
if (!optIsCSEcandidate(tree))
{
continue;
@@ -730,6 +739,11 @@ unsigned Compiler::optValnumCSE_Locate()
{
noway_assert(((unsigned)tree->gtCSEnum) == CSEindex);
}
+
+ if (IS_CSE_INDEX(CSEindex) && (tree->OperGet() == GT_ARR_LENGTH))
+ {
+ stmtHasArrLenCandidate = true;
+ }
}
}
}
@@ -748,6 +762,102 @@ unsigned Compiler::optValnumCSE_Locate()
return 1;
}
+//------------------------------------------------------------------------
+// optCseUpdateArrLenMap: Check if this compare is a tractable function of
+// an array length that is a CSE candidate, and insert
+// an entry in the optCseArrLenMap if so. This facilitates
+// subsequently updating the compare's value number if
+// the array length gets CSEd.
+//
+// Arguments:
+// compare - The compare node to check
+
+void Compiler::optCseUpdateArrLenMap(GenTreePtr compare)
+{
+ assert(compare->OperIsCompare());
+
+ ValueNum compareVN = compare->gtVNPair.GetConservative();
+ VNFuncApp cmpVNFuncApp;
+
+ if (!vnStore->GetVNFunc(compareVN, &cmpVNFuncApp) ||
+ (cmpVNFuncApp.m_func != GetVNFuncForOper(compare->OperGet(), compare->IsUnsigned())))
+ {
+ // Value numbering inferred this compare as something other
+ // than its own operator; leave its value number alone.
+ return;
+ }
+
+ // Now look for an array length feeding the compare
+ ValueNumStore::ArrLenArithBoundInfo info;
+ GenTreePtr arrLenParent = nullptr;
+
+ if (vnStore->IsVNArrLenBound(compareVN))
+ {
+ // Simple compare of an array legnth against something else.
+
+ vnStore->GetArrLenBoundInfo(compareVN, &info);
+ arrLenParent = compare;
+ }
+ else if (vnStore->IsVNArrLenArithBound(compareVN))
+ {
+ // Compare of an array length +/- some offset to something else.
+
+ GenTreePtr op1 = compare->gtGetOp1();
+ GenTreePtr op2 = compare->gtGetOp2();
+
+ vnStore->GetArrLenArithBoundInfo(compareVN, &info);
+ if (GetVNFuncForOper(op1->OperGet(), op1->IsUnsigned()) == (VNFunc)info.arrOper)
+ {
+ // The arithmetic node is the array length's parent.
+ arrLenParent = op1;
+ }
+ else if (GetVNFuncForOper(op2->OperGet(), op2->IsUnsigned()) == (VNFunc)info.arrOper)
+ {
+ // The arithmetic node is the array length's parent.
+ arrLenParent = op2;
+ }
+ }
+
+ if (arrLenParent != nullptr)
+ {
+ GenTreePtr arrLen = nullptr;
+
+ // Find which child of arrLenParent is the array length. Abort if its
+ // conservative value number doesn't match the one from the compare VN.
+
+ GenTreePtr child1 = arrLenParent->gtGetOp1();
+ if ((child1->OperGet() == GT_ARR_LENGTH) && IS_CSE_INDEX(child1->gtCSEnum) &&
+ (info.vnArray == child1->AsArrLen()->ArrRef()->gtVNPair.GetConservative()))
+ {
+ arrLen = child1;
+ }
+ else
+ {
+ GenTreePtr child2 = arrLenParent->gtGetOp2();
+ if ((child2->OperGet() == GT_ARR_LENGTH) && IS_CSE_INDEX(child2->gtCSEnum) &&
+ (info.vnArray == child2->AsArrLen()->ArrRef()->gtVNPair.GetConservative()))
+ {
+ arrLen = child2;
+ }
+ }
+
+ if (arrLen != nullptr)
+ {
+ // Found an arrayLen feeding a compare that is a tracatable function of it;
+ // record this in the map so we can update the compare VN if the array length
+ // node gets CSEd.
+
+ if (optCseArrLenMap == nullptr)
+ {
+ // Allocate map on first use.
+ optCseArrLenMap = new (getAllocator()) NodeToNodeMap(getAllocator());
+ }
+
+ optCseArrLenMap->Set(arrLen, compare);
+ }
+ }
+}
+
/*****************************************************************************
*
* Compute each blocks bbCseGen
@@ -782,7 +892,7 @@ void Compiler::optValnumCSE_InitDataFlow()
if (init_to_zero)
{
/* Initialize to {ZERO} prior to dataflow */
- block->bbCseIn = BitVecOps::MakeCopy(cseTraits, cseEmpty);
+ block->bbCseIn = BitVecOps::MakeEmpty(cseTraits);
}
else
{
@@ -793,7 +903,7 @@ void Compiler::optValnumCSE_InitDataFlow()
block->bbCseOut = BitVecOps::MakeCopy(cseTraits, cseFull);
/* Initialize to {ZERO} prior to locating the CSE candidates */
- block->bbCseGen = BitVecOps::MakeCopy(cseTraits, cseEmpty);
+ block->bbCseGen = BitVecOps::MakeEmpty(cseTraits);
}
// We walk the set of CSE candidates and set the bit corresponsing to the CSEindex
@@ -847,42 +957,31 @@ void Compiler::optValnumCSE_InitDataFlow()
*/
class CSE_DataFlow
{
-private:
- EXPSET_TP m_preMergeOut;
-
- Compiler* m_pCompiler;
+ BitVecTraits* m_pBitVecTraits;
+ EXPSET_TP m_preMergeOut;
public:
- CSE_DataFlow(Compiler* pCompiler) : m_pCompiler(pCompiler)
+ CSE_DataFlow(Compiler* pCompiler) : m_pBitVecTraits(pCompiler->cseTraits), m_preMergeOut(BitVecOps::UninitVal())
{
}
- Compiler* getCompiler()
- {
- return m_pCompiler;
- }
-
// At the start of the merge function of the dataflow equations, initialize premerge state (to detect changes.)
void StartMerge(BasicBlock* block)
{
- m_preMergeOut = BitVecOps::MakeCopy(m_pCompiler->cseTraits, block->bbCseOut);
+ BitVecOps::Assign(m_pBitVecTraits, m_preMergeOut, block->bbCseOut);
}
// During merge, perform the actual merging of the predecessor's (since this is a forward analysis) dataflow flags.
void Merge(BasicBlock* block, BasicBlock* predBlock, flowList* preds)
{
- BitVecOps::IntersectionD(m_pCompiler->cseTraits, block->bbCseIn, predBlock->bbCseOut);
+ BitVecOps::IntersectionD(m_pBitVecTraits, block->bbCseIn, predBlock->bbCseOut);
}
// At the end of the merge store results of the dataflow equations, in a postmerge state.
bool EndMerge(BasicBlock* block)
{
- BitVecTraits* traits = m_pCompiler->cseTraits;
- EXPSET_TP mergeOut = BitVecOps::MakeCopy(traits, block->bbCseIn);
- BitVecOps::UnionD(traits, mergeOut, block->bbCseGen);
- BitVecOps::IntersectionD(traits, mergeOut, block->bbCseOut);
- BitVecOps::Assign(traits, block->bbCseOut, mergeOut);
- return (!BitVecOps::Equal(traits, mergeOut, m_preMergeOut));
+ BitVecOps::DataFlowD(m_pBitVecTraits, block->bbCseOut, block->bbCseGen, block->bbCseIn);
+ return !BitVecOps::Equal(m_pBitVecTraits, block->bbCseOut, m_preMergeOut);
}
};
@@ -948,6 +1047,8 @@ void Compiler::optValnumCSE_Availablity()
printf("Labeling the CSEs with Use/Def information\n");
}
#endif
+ EXPSET_TP available_cses = BitVecOps::MakeEmpty(cseTraits);
+
for (BasicBlock* block = fgFirstBB; block; block = block->bbNext)
{
GenTreePtr stmt;
@@ -957,7 +1058,7 @@ void Compiler::optValnumCSE_Availablity()
compCurBB = block;
- EXPSET_TP available_cses = BitVecOps::MakeCopy(cseTraits, block->bbCseIn);
+ BitVecOps::Assign(cseTraits, available_cses, block->bbCseIn);
optCSEweight = block->getBBWeight(this);
@@ -1103,6 +1204,18 @@ public:
continue;
}
+#if FEATURE_FIXED_OUT_ARGS
+ // Skip the OutgoingArgArea in computing frame size, since
+ // its size is not yet known and it doesn't affect local
+ // offsets from the frame pointer (though it may affect
+ // them from the stack pointer).
+ noway_assert(m_pCompiler->lvaOutgoingArgSpaceVar != BAD_VAR_NUM);
+ if (lclNum == m_pCompiler->lvaOutgoingArgSpaceVar)
+ {
+ continue;
+ }
+#endif // FEATURE_FIXED_OUT_ARGS
+
bool onStack = (regAvailEstimate == 0); // true when it is likely that this LclVar will have a stack home
// Some LclVars always have stack homes
@@ -1909,6 +2022,39 @@ public:
// use to fetch the same value with no reload, so we can safely propagate that
// conservative VN to this use. This can help range check elimination later on.
cse->gtVNPair.SetConservative(defConservativeVN);
+
+ GenTreePtr cmp;
+ if ((exp->OperGet() == GT_ARR_LENGTH) && (m_pCompiler->optCseArrLenMap != nullptr) &&
+ (m_pCompiler->optCseArrLenMap->Lookup(exp, &cmp)))
+ {
+ // Propagate the new value number to this compare node as well, since
+ // subsequent range check elimination will try to correlate it with
+ // the other appearances that are getting CSEd.
+
+ ValueNumStore* vnStore = m_pCompiler->vnStore;
+ ValueNum oldCmpVN = cmp->gtVNPair.GetConservative();
+ ValueNumStore::ArrLenArithBoundInfo info;
+ ValueNum newCmpArgVN;
+ if (vnStore->IsVNArrLenBound(oldCmpVN))
+ {
+ // Comparison is against the array length directly.
+
+ newCmpArgVN = defConservativeVN;
+ vnStore->GetArrLenBoundInfo(oldCmpVN, &info);
+ }
+ else
+ {
+ // Comparison is against the array length +/- some offset.
+
+ assert(vnStore->IsVNArrLenArithBound(oldCmpVN));
+ vnStore->GetArrLenArithBoundInfo(oldCmpVN, &info);
+ newCmpArgVN = vnStore->VNForFunc(vnStore->TypeOfVN(info.arrOp), (VNFunc)info.arrOper,
+ info.arrOp, defConservativeVN);
+ }
+ ValueNum newCmpVN = vnStore->VNForFunc(vnStore->TypeOfVN(oldCmpVN), (VNFunc)info.cmpOper,
+ info.cmpOp, newCmpArgVN);
+ cmp->gtVNPair.SetConservative(newCmpVN);
+ }
}
#ifdef DEBUG
cse->gtDebugFlags |= GTF_DEBUG_VAR_CSE_REF;
diff --git a/src/jit/optimizer.cpp b/src/jit/optimizer.cpp
index 92edf62890..c18ebc55d0 100644
--- a/src/jit/optimizer.cpp
+++ b/src/jit/optimizer.cpp
@@ -227,7 +227,7 @@ void Compiler::optMarkLoopBlocks(BasicBlock* begBlk, BasicBlock* endBlk, bool ex
unsigned weight;
- if ((curBlk->bbFlags & BBF_PROF_WEIGHT) != 0)
+ if (curBlk->hasProfileWeight())
{
// We have real profile weights, so we aren't going to change this blocks weight
weight = curBlk->bbWeight;
@@ -370,7 +370,7 @@ void Compiler::optUnmarkLoopBlocks(BasicBlock* begBlk, BasicBlock* endBlk)
// Don't unmark blocks that are set to BB_MAX_WEIGHT
// Don't unmark blocks when we are using profile weights
//
- if (!curBlk->isMaxBBWeight() && ((curBlk->bbFlags & BBF_PROF_WEIGHT) == 0))
+ if (!curBlk->isMaxBBWeight() && !curBlk->hasProfileWeight())
{
if (!fgDominate(curBlk, endBlk))
{
@@ -3527,8 +3527,7 @@ void Compiler::fgOptWhileLoop(BasicBlock* block)
{
// Only rely upon the profile weight when all three of these blocks
// have good profile weights
- if ((block->bbFlags & BBF_PROF_WEIGHT) && (bTest->bbFlags & BBF_PROF_WEIGHT) &&
- (block->bbNext->bbFlags & BBF_PROF_WEIGHT))
+ if (block->hasProfileWeight() && bTest->hasProfileWeight() && block->bbNext->hasProfileWeight())
{
allProfileWeightsAreValid = true;
@@ -4836,18 +4835,16 @@ void Compiler::optEnsureUniqueHead(unsigned loopInd, unsigned ambientWeight)
* Determine the kind of interference for the call.
*/
-/* static */ inline Compiler::callInterf Compiler::optCallInterf(GenTreePtr call)
+/* static */ inline Compiler::callInterf Compiler::optCallInterf(GenTreeCall* call)
{
- assert(call->gtOper == GT_CALL);
-
// if not a helper, kills everything
- if (call->gtCall.gtCallType != CT_HELPER)
+ if (call->gtCallType != CT_HELPER)
{
return CALLINT_ALL;
}
// setfield and array address store kill all indirections
- switch (eeGetHelperNum(call->gtCall.gtCallMethHnd))
+ switch (eeGetHelperNum(call->gtCallMethHnd))
{
case CORINFO_HELP_ASSIGN_REF: // Not strictly needed as we don't make a GT_CALL with this
case CORINFO_HELP_CHECKED_ASSIGN_REF: // Not strictly needed as we don't make a GT_CALL with this
@@ -5311,7 +5308,7 @@ Compiler::fgWalkResult Compiler::optIsVarAssgCB(GenTreePtr* pTree, fgWalkData* d
isVarAssgDsc* desc = (isVarAssgDsc*)data->pCallbackData;
assert(desc && desc->ivaSelf == desc);
- desc->ivaMaskCall = optCallInterf(tree);
+ desc->ivaMaskCall = optCallInterf(tree->AsCall());
}
return WALK_CONTINUE;
@@ -6555,9 +6552,8 @@ void Compiler::fgCreateLoopPreHeader(unsigned lnum)
}
else
{
- bool allValidProfileWeights = ((head->bbFlags & BBF_PROF_WEIGHT) != 0) &&
- ((head->bbJumpDest->bbFlags & BBF_PROF_WEIGHT) != 0) &&
- ((head->bbNext->bbFlags & BBF_PROF_WEIGHT) != 0);
+ bool allValidProfileWeights =
+ (head->hasProfileWeight() && head->bbJumpDest->hasProfileWeight() && head->bbNext->hasProfileWeight());
if (allValidProfileWeights)
{
diff --git a/src/jit/protojit/CMakeLists.txt b/src/jit/protojit/CMakeLists.txt
index 91c69e9a83..d27f30281a 100644
--- a/src/jit/protojit/CMakeLists.txt
+++ b/src/jit/protojit/CMakeLists.txt
@@ -13,6 +13,7 @@ endif(WIN32)
add_library_clr(protojit
SHARED
${SHARED_LIB_SOURCES}
+ ${JIT_ARCH_SOURCES}
)
add_dependencies(protojit jit_exports)
diff --git a/src/ToolBox/PdbTypeMatch/include/.gitmirror b/src/jit/protononjit/.gitmirror
index f507630f94..f507630f94 100644
--- a/src/ToolBox/PdbTypeMatch/include/.gitmirror
+++ b/src/jit/protononjit/.gitmirror
diff --git a/src/jit/protononjit/CMakeLists.txt b/src/jit/protononjit/CMakeLists.txt
new file mode 100644
index 0000000000..e209e4cd36
--- /dev/null
+++ b/src/jit/protononjit/CMakeLists.txt
@@ -0,0 +1,84 @@
+project(protononjit)
+
+add_definitions(-DALT_JIT)
+add_definitions(-DFEATURE_NO_HOST)
+add_definitions(-DSELF_NO_HOST)
+add_definitions(-DFEATURE_READYTORUN_COMPILER)
+remove_definitions(-DFEATURE_MERGE_JIT_AND_ENGINE)
+
+remove_definitions(-DFEATURE_SIMD)
+remove_definitions(-DFEATURE_AVX_SUPPORT)
+
+if (CLR_CMAKE_PLATFORM_ARCH_I386)
+ remove_definitions(-D_TARGET_X86_=1)
+ add_definitions(-D_TARGET_ARM_)
+ set(JIT_ARCH_ALTJIT_SOURCES ${JIT_ARM_SOURCES})
+elseif(CLR_CMAKE_PLATFORM_ARCH_AMD64)
+ remove_definitions(-D_TARGET_AMD64_=1)
+ add_definitions(-D_TARGET_ARM64_)
+ set(JIT_ARCH_ALTJIT_SOURCES ${JIT_ARM64_SOURCES})
+else()
+ clr_unknown_arch()
+endif()
+
+if (NOT WIN32)
+ if (CLR_CMAKE_PLATFORM_ARCH_I386)
+ remove_definitions(-DUNIX_X86_ABI)
+ elseif(CLR_CMAKE_PLATFORM_ARCH_AMD64)
+ remove_definitions(-DUNIX_AMD64_ABI)
+ remove_definitions(-DFEATURE_UNIX_AMD64_STRUCT_PASSING)
+ else()
+ clr_unknown_arch()
+ endif()
+endif(NOT WIN32)
+
+if(WIN32)
+ add_definitions(-DFX_VER_INTERNALNAME_STR=protononjit.dll)
+endif(WIN32)
+
+add_library_clr(protononjit
+ SHARED
+ ${SHARED_LIB_SOURCES}
+ ${JIT_ARCH_ALTJIT_SOURCES}
+)
+
+add_dependencies(protononjit jit_exports)
+
+set_property(TARGET protononjit APPEND_STRING PROPERTY LINK_FLAGS ${JIT_EXPORTS_LINKER_OPTION})
+set_property(TARGET protononjit APPEND_STRING PROPERTY LINK_DEPENDS ${JIT_EXPORTS_FILE})
+
+set(RYUJIT_LINK_LIBRARIES
+ utilcodestaticnohost
+ gcinfo
+)
+
+if(CLR_CMAKE_PLATFORM_UNIX)
+ list(APPEND RYUJIT_LINK_LIBRARIES
+ mscorrc_debug
+ coreclrpal
+ palrt
+ )
+else()
+ list(APPEND RYUJIT_LINK_LIBRARIES
+ ${STATIC_MT_CRT_LIB}
+ ${STATIC_MT_VCRT_LIB}
+ kernel32.lib
+ advapi32.lib
+ ole32.lib
+ oleaut32.lib
+ uuid.lib
+ user32.lib
+ version.lib
+ shlwapi.lib
+ bcrypt.lib
+ crypt32.lib
+ RuntimeObject.lib
+ )
+endif(CLR_CMAKE_PLATFORM_UNIX)
+
+target_link_libraries(protononjit
+ ${RYUJIT_LINK_LIBRARIES}
+)
+
+# add the install targets
+install_clr(protononjit)
diff --git a/src/jit/protononjit/SOURCES b/src/jit/protononjit/SOURCES
new file mode 100644
index 0000000000..353c501873
--- /dev/null
+++ b/src/jit/protononjit/SOURCES
@@ -0,0 +1,10 @@
+
+#
+# DO NOT EDIT THIS FILE!!! Modify the project file in this directory
+# This file merely allows the MSBuild project file in this directory to be integrated with Build.Exe
+#
+TARGETTYPE=NOTARGET
+CLR_TARGETTYPE=DLL
+MSBuildProjectFile=protononjit.nativeproj
+SOURCES=
+ \ No newline at end of file
diff --git a/src/jit/protononjit/makefile b/src/jit/protononjit/makefile
new file mode 100644
index 0000000000..bf27e8c84b
--- /dev/null
+++ b/src/jit/protononjit/makefile
@@ -0,0 +1,7 @@
+
+#
+# DO NOT EDIT THIS FILE!!! Modify the project file in this directory
+# This file merely allows the MSBuild project file in this directory to be integrated with Build.Exe
+#
+
+!INCLUDE $(NTMAKEENV)\devdiv.def
diff --git a/src/jit/protononjit/protononjit.def b/src/jit/protononjit/protononjit.def
new file mode 100644
index 0000000000..1603af74ca
--- /dev/null
+++ b/src/jit/protononjit/protononjit.def
@@ -0,0 +1,7 @@
+; 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.
+EXPORTS
+ getJit
+ jitStartup
+ sxsJitStartup
diff --git a/src/jit/protononjit/protononjit.nativeproj b/src/jit/protononjit/protononjit.nativeproj
new file mode 100644
index 0000000000..64df6c5739
--- /dev/null
+++ b/src/jit/protononjit/protononjit.nativeproj
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <!--
+ PROTO JIT: The purpose of this module is to provide an isolated environment to develop
+ the RyuJIT backend without interfering with the development of the frontend. The
+ idea is to fork codegen and registerfp, that way we leave the PUCLR backend intact so
+ it can be still consumed by the RyuJIT frontend separately maintaining the code stability
+ of the PUCLR codegen.cpp logic.
+
+ This module is meant to be used as a throwaway or fallback cross-JIT (x86 -> arm) that will just
+ attempt to generate arm code, throw it away and then re-jit using the default jit on x86.
+ -->
+
+ <!--
+ Note that we are defining TargetArch directly because of altjit is not a real fully functional cross
+ compiled binary. It is just a convenience workaround for JIT devs.
+ -->
+ <PropertyGroup>
+ <TargetArch>arm</TargetArch>
+ </PropertyGroup>
+
+ <!-- Import the CLR's settings -->
+
+ <Import Project="$(_NTDRIVE)$(_NTROOT)\ndp\clr\clr.props" />
+
+ <PropertyGroup>
+
+ <!-- Set the output -->
+
+ <OutputName>protononjit</OutputName>
+ <FeatureMergeJitAndEngine>false</FeatureMergeJitAndEngine>
+ <TargetType>DYNLINK</TargetType>
+ <BuildCoreBinaries>false</BuildCoreBinaries>
+ <BuildSysBinaries>false</BuildSysBinaries>
+
+ <!-- Motherhood & apple pie here -->
+
+ <DllEntryPoint>_DllMainCRTStartup</DllEntryPoint>
+ <LinkSubsystem>windows</LinkSubsystem>
+ <LibCLib Condition="'$(FeatureMergeJitAndEngine)'!='true'">$(ClrCrtLib)</LibCLib>
+
+ <!-- JIT specific baloney -->
+
+ <LinkModuleDefinitionFile>$(OutputName).def</LinkModuleDefinitionFile>
+
+ <ClDefines>$(ClDefines);_TARGET_ARM_=1</ClDefines>
+ <ClDefines>$(ClDefines);ALT_JIT</ClDefines>
+
+ <Win32DllLibs>$(SdkLibPath)\kernel32.lib;$(SdkLibPath)\user32.lib;$(SdkLibPath)\advapi32.lib;$(SdkLibPath)\oleaut32.lib;$(SdkLibPath)\uuid.lib</Win32DllLibs>
+ <Win32DllLibs>$(Win32DllLibs);$(ClrLibPath)\utilcode.lib</Win32DllLibs>
+
+ <!-- Profile-guided optimization -->
+
+ <PogoOptimize>false</PogoOptimize>
+ <PogoInstrument>false</PogoInstrument>
+ <PogoUpdate>false</PogoUpdate>
+
+ <!-- Do we want to build with msvcdis disassembly? This should be enabled for DEBUG, disabled otherwise.
+ However, it can be useful to enable it temporarily in non-DEBUG builds, by changing the EnableLateDisasm property.
+ -->
+ <EnableLateDisasm>false</EnableLateDisasm>
+ <ClDefines Condition="'$(EnableLateDisasm)' == 'true'">$(ClDefines);LATE_DISASM=1</ClDefines>
+ <LinkDelayLoad Condition="'$(EnableLateDisasm)' == 'true'">$(LinkDelayLoad);msvcdis$(VC_NONCRT_ProdVerX).dll</LinkDelayLoad>
+ <UseDelayimpLib Condition="'$(EnableLateDisasm)' == 'true' and '$(FeatureMergeJitAndEngine)'!='true'">true</UseDelayimpLib>
+
+ </PropertyGroup>
+
+ <!-- Leaf Project Items -->
+ <ItemGroup>
+ <ProjectReference Include="$(ClrSrcDirectory)utilcode\dyncrt\dyncrt.nativeproj" />
+ <TargetLib Include="$(SdkLibPath)\mscoree.lib" />
+ <TargetLib Include="$(ClrLibPath)\ArmGCInfo.lib">
+ <ProjectReference>$(ClrSrcDirectory)gcinfo\armlib\ArmGCInfo.nativeproj</ProjectReference>
+ </TargetLib>
+ <TargetLib Condition="'$(UseDelayimpLib)' == 'true'" Include="$(ClrLibPath)\delayimp.lib">
+ <ProjectReference>$(ClrSrcDirectory)delayimp\delayimp.nativeproj</ProjectReference>
+ </TargetLib>
+ <TargetLib Condition="'$(DebugBuild)' == 'true'" Include="$(SdkLibPath)\ole32.lib" />
+ <TargetLib Condition="'$(EnableLateDisasm)' == 'true'" Include="$(VCToolsLibPath)\msvcdis.lib" />
+ <RCResourceFile Include="..\native.rc" />
+ </ItemGroup>
+
+ <Import Project="..\jit.settings.targets" />
+
+</Project>
diff --git a/src/jit/rangecheck.cpp b/src/jit/rangecheck.cpp
index 8d16cce31a..91ae81e322 100644
--- a/src/jit/rangecheck.cpp
+++ b/src/jit/rangecheck.cpp
@@ -506,7 +506,7 @@ void RangeCheck::MergeEdgeAssertions(GenTreePtr tree, const ASSERT_VALARG_TP ass
{
index++;
- Compiler::AssertionDsc* curAssertion = m_pCompiler->optGetAssertion((Compiler::AssertionIndex)index);
+ Compiler::AssertionDsc* curAssertion = m_pCompiler->optGetAssertion((AssertionIndex)index);
// Current assertion is about array length.
if (!curAssertion->IsArrLenArithBound() && !curAssertion->IsArrLenBound() && !curAssertion->IsConstantBound())
@@ -517,7 +517,7 @@ void RangeCheck::MergeEdgeAssertions(GenTreePtr tree, const ASSERT_VALARG_TP ass
#ifdef DEBUG
if (m_pCompiler->verbose)
{
- m_pCompiler->optPrintAssertion(curAssertion, (Compiler::AssertionIndex)index);
+ m_pCompiler->optPrintAssertion(curAssertion, (AssertionIndex)index);
}
#endif
@@ -617,7 +617,7 @@ void RangeCheck::MergeEdgeAssertions(GenTreePtr tree, const ASSERT_VALARG_TP ass
#ifdef DEBUG
if (m_pCompiler->verbose)
{
- m_pCompiler->optPrintAssertion(curAssertion, (Compiler::AssertionIndex)index);
+ m_pCompiler->optPrintAssertion(curAssertion, (AssertionIndex)index);
}
#endif
@@ -869,10 +869,13 @@ Range RangeCheck::ComputeRangeForLocalDef(
case GT_ASG:
{
Range range = GetRange(loc->block, loc->stmt, asg->gtGetOp2(), path, monotonic DEBUGARG(indent));
- JITDUMP("Merge assertions from BB%02d:%s for assignment about %p\n", block->bbNum,
- BitVecOps::ToString(m_pCompiler->apTraits, block->bbAssertionIn), dspPtr(asg->gtGetOp1()));
- MergeEdgeAssertions(asg->gtGetOp1(), block->bbAssertionIn, &range);
- JITDUMP("done merging\n");
+ if (!BitVecOps::MayBeUninit(block->bbAssertionIn))
+ {
+ JITDUMP("Merge assertions from BB%02d:%s for assignment about %p\n", block->bbNum,
+ BitVecOps::ToString(m_pCompiler->apTraits, block->bbAssertionIn), dspPtr(asg->gtGetOp1()));
+ MergeEdgeAssertions(asg->gtGetOp1(), block->bbAssertionIn, &range);
+ JITDUMP("done merging\n");
+ }
return range;
}
diff --git a/src/jit/rationalize.cpp b/src/jit/rationalize.cpp
index 00e0bec6f7..1bc3a614a5 100644
--- a/src/jit/rationalize.cpp
+++ b/src/jit/rationalize.cpp
@@ -732,6 +732,35 @@ Compiler::fgWalkResult Rationalizer::RewriteNode(GenTree** useEdge, ArrayStack<G
{
RewriteSIMDOperand(use, false);
}
+ else
+ {
+ // Due to promotion of structs containing fields of type struct with a
+ // single scalar type field, we could potentially see IR nodes of the
+ // form GT_IND(GT_ADD(lclvarAddr, 0)) where 0 is an offset representing
+ // a field-seq. These get folded here.
+ //
+ // TODO: This code can be removed once JIT implements recursive struct
+ // promotion instead of lying about the type of struct field as the type
+ // of its single scalar field.
+ GenTree* addr = node->AsIndir()->Addr();
+ if (addr->OperGet() == GT_ADD && addr->gtGetOp1()->OperGet() == GT_LCL_VAR_ADDR &&
+ addr->gtGetOp2()->IsIntegralConst(0))
+ {
+ GenTreeLclVarCommon* lclVarNode = addr->gtGetOp1()->AsLclVarCommon();
+ unsigned lclNum = lclVarNode->GetLclNum();
+ LclVarDsc* varDsc = comp->lvaTable + lclNum;
+ if (node->TypeGet() == varDsc->TypeGet())
+ {
+ JITDUMP("Rewriting GT_IND(GT_ADD(LCL_VAR_ADDR,0)) to LCL_VAR\n");
+ lclVarNode->SetOper(GT_LCL_VAR);
+ lclVarNode->gtType = node->TypeGet();
+ use.ReplaceWith(comp, lclVarNode);
+ BlockRange().Remove(addr);
+ BlockRange().Remove(addr->gtGetOp2());
+ BlockRange().Remove(node);
+ }
+ }
+ }
break;
case GT_NOP:
diff --git a/src/jit/regalloc.cpp b/src/jit/regalloc.cpp
index 5c3895b4f2..938f8e8124 100644
--- a/src/jit/regalloc.cpp
+++ b/src/jit/regalloc.cpp
@@ -4613,7 +4613,7 @@ regMaskTP Compiler::rpPredictTreeRegUse(GenTreePtr tree,
assert(!args->IsArgPlaceHolderNode()); // No place holders nodes are in gtCallLateArgs;
- fgArgTabEntryPtr curArgTabEntry = gtArgEntryByNode(tree, args);
+ fgArgTabEntryPtr curArgTabEntry = gtArgEntryByNode(tree->AsCall(), args);
assert(curArgTabEntry);
regNumber regNum = curArgTabEntry->regNum; // first register use to pass this argument
diff --git a/src/jit/registerfp.cpp b/src/jit/registerfp.cpp
index ed71886cae..68f3bb6c4e 100644
--- a/src/jit/registerfp.cpp
+++ b/src/jit/registerfp.cpp
@@ -637,7 +637,7 @@ void CodeGen::genCodeForTreeFloat(GenTreePtr tree, RegSet::RegisterPreference* p
else
{
assert(oper == GT_CALL);
- genCodeForCall(tree, true);
+ genCodeForCall(tree->AsCall(), true);
}
}
diff --git a/src/jit/regset.cpp b/src/jit/regset.cpp
index 0d0ac3e0ce..dbdf9c8aeb 100644
--- a/src/jit/regset.cpp
+++ b/src/jit/regset.cpp
@@ -1735,13 +1735,12 @@ void RegSet::rsSpillTree(regNumber reg, GenTreePtr tree, unsigned regIdx /* =0 *
*
* Spill the top of the FP x87 stack.
*/
-void RegSet::rsSpillFPStack(GenTreePtr tree)
+void RegSet::rsSpillFPStack(GenTreeCall* call)
{
SpillDsc* spill;
TempDsc* temp;
- var_types treeType = tree->TypeGet();
+ var_types treeType = call->TypeGet();
- assert(tree->OperGet() == GT_CALL);
spill = SpillDsc::alloc(m_rsCompiler, this, treeType);
/* Grab a temp to store the spilled value */
@@ -1750,10 +1749,10 @@ void RegSet::rsSpillFPStack(GenTreePtr tree)
/* Remember what it is we have spilled */
- spill->spillTree = tree;
+ spill->spillTree = call;
SpillDsc* lastDsc = spill;
- regNumber reg = tree->gtRegNum;
+ regNumber reg = call->gtRegNum;
lastDsc->spillNext = rsSpillDesc[reg];
rsSpillDesc[reg] = spill;
@@ -1766,7 +1765,7 @@ void RegSet::rsSpillFPStack(GenTreePtr tree)
/* Mark the tree node as having been spilled */
- rsMarkSpill(tree, reg);
+ rsMarkSpill(call, reg);
}
#endif // defined(_TARGET_X86_) && !FEATURE_STACK_FP_X87
diff --git a/src/jit/regset.h b/src/jit/regset.h
index cdfbb1502a..9af5200290 100644
--- a/src/jit/regset.h
+++ b/src/jit/regset.h
@@ -337,7 +337,7 @@ private:
void rsSpillTree(regNumber reg, GenTreePtr tree, unsigned regIdx = 0);
#if defined(_TARGET_X86_) && !FEATURE_STACK_FP_X87
- void rsSpillFPStack(GenTreePtr tree);
+ void rsSpillFPStack(GenTreeCall* call);
#endif // defined(_TARGET_X86_) && !FEATURE_STACK_FP_X87
#ifdef LEGACY_BACKEND
diff --git a/src/jit/simd.cpp b/src/jit/simd.cpp
index fb190c4fa1..4ba7832cca 100644
--- a/src/jit/simd.cpp
+++ b/src/jit/simd.cpp
@@ -1374,20 +1374,22 @@ GenTreePtr Compiler::impSIMDMinMax(SIMDIntrinsicID intrinsicId,
#ifdef _TARGET_XARCH_
// SSE2 has direct support for float/double/signed word/unsigned byte.
+ // SSE4.1 has direct support for int32/uint32/signed byte/unsigned word.
// For other integer types we compute min/max as follows
//
- // int32/uint32/int64/uint64:
+ // int32/uint32 (SSE2)
+ // int64/uint64 (SSE2&SSE3_4):
// compResult = (op1 < op2) in case of Min
// (op1 > op2) in case of Max
// Min/Max(op1, op2) = Select(compResult, op1, op2)
//
- // unsigned word:
+ // unsigned word (SSE2):
// op1 = op1 - 2^15 ; to make it fit within a signed word
// op2 = op2 - 2^15 ; to make it fit within a signed word
// result = SSE2 signed word Min/Max(op1, op2)
// result = result + 2^15 ; readjust it back
//
- // signed byte:
+ // signed byte (SSE2):
// op1 = op1 + 2^7 ; to make it unsigned
// op1 = op1 + 2^7 ; to make it unsigned
// result = SSE2 unsigned byte Min/Max(op1, op2)
@@ -1395,13 +1397,16 @@ GenTreePtr Compiler::impSIMDMinMax(SIMDIntrinsicID intrinsicId,
GenTree* simdTree = nullptr;
- if (varTypeIsFloating(baseType) || baseType == TYP_SHORT || baseType == TYP_UBYTE)
+ if (varTypeIsFloating(baseType) || baseType == TYP_SHORT || baseType == TYP_UBYTE ||
+ (getSIMDInstructionSet() >= InstructionSet_SSE3_4 &&
+ (baseType == TYP_BYTE || baseType == TYP_INT || baseType == TYP_UINT || baseType == TYP_CHAR)))
{
- // SSE2 has direct support
+ // SSE2 or SSE4.1 has direct support
simdTree = gtNewSIMDNode(simdType, op1, op2, intrinsicId, baseType, size);
}
else if (baseType == TYP_CHAR || baseType == TYP_BYTE)
{
+ assert(getSIMDInstructionSet() == InstructionSet_SSE2);
int constVal;
SIMDIntrinsicID operIntrinsic;
SIMDIntrinsicID adjustIntrinsic;
diff --git a/src/jit/simdcodegenxarch.cpp b/src/jit/simdcodegenxarch.cpp
index ace36422fb..468d302d17 100644
--- a/src/jit/simdcodegenxarch.cpp
+++ b/src/jit/simdcodegenxarch.cpp
@@ -243,6 +243,25 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type
{
result = INS_pminsw;
}
+ else if (compiler->getSIMDInstructionSet() >= InstructionSet_SSE3_4)
+ {
+ if (baseType == TYP_BYTE)
+ {
+ result = INS_pminsb;
+ }
+ else if (baseType == TYP_CHAR)
+ {
+ result = INS_pminuw;
+ }
+ else if (baseType == TYP_INT)
+ {
+ result = INS_pminsd;
+ }
+ else if (baseType == TYP_UINT)
+ {
+ result = INS_pminud;
+ }
+ }
else
{
unreached();
@@ -266,6 +285,25 @@ instruction CodeGen::getOpForSIMDIntrinsic(SIMDIntrinsicID intrinsicId, var_type
{
result = INS_pmaxsw;
}
+ else if (compiler->getSIMDInstructionSet() >= InstructionSet_SSE3_4)
+ {
+ if (baseType == TYP_BYTE)
+ {
+ result = INS_pmaxsb;
+ }
+ else if (baseType == TYP_CHAR)
+ {
+ result = INS_pmaxuw;
+ }
+ else if (baseType == TYP_INT)
+ {
+ result = INS_pmaxsd;
+ }
+ else if (baseType == TYP_UINT)
+ {
+ result = INS_pmaxud;
+ }
+ }
else
{
unreached();
diff --git a/src/jit/stackfp.cpp b/src/jit/stackfp.cpp
index 3e0eceabb7..e6d4c9e9c9 100644
--- a/src/jit/stackfp.cpp
+++ b/src/jit/stackfp.cpp
@@ -2595,7 +2595,7 @@ void CodeGen::genCodeForTreeStackFP_Special(GenTreePtr tree)
{
case GT_CALL:
{
- genCodeForCall(tree, true);
+ genCodeForCall(tree->AsCall(), true);
break;
}
default:
diff --git a/src/jit/standalone/CMakeLists.txt b/src/jit/standalone/CMakeLists.txt
index f20d3790c7..988108efb1 100644
--- a/src/jit/standalone/CMakeLists.txt
+++ b/src/jit/standalone/CMakeLists.txt
@@ -16,6 +16,7 @@ endif(WIN32)
add_library_clr(clrjit
SHARED
${SHARED_LIB_SOURCES}
+ ${JIT_ARCH_SOURCES}
)
add_dependencies(clrjit jit_exports)
diff --git a/src/jit/target.h b/src/jit/target.h
index 5b608ddfac..f62d90519b 100644
--- a/src/jit/target.h
+++ b/src/jit/target.h
@@ -6,25 +6,11 @@
#ifndef _TARGET_H_
#define _TARGET_H_
-// If the UNIX_AMD64_ABI is defined make sure that _TARGET_AMD64_ is also defined.
-#if defined(UNIX_AMD64_ABI)
-#if !defined(_TARGET_AMD64_)
-#error When UNIX_AMD64_ABI is defined you must define _TARGET_AMD64_ defined as well.
-#endif
-#endif
-
-// If the UNIX_X86_ABI is defined make sure that _TARGET_X86_ is also defined.
-#if defined(UNIX_X86_ABI)
-#if !defined(_TARGET_X86_)
-#error When UNIX_X86_ABI is defined you must define _TARGET_X86_ defined as well.
-#endif
-#endif
-
-#if (defined(FEATURE_CORECLR) && defined(PLATFORM_UNIX))
+#if defined(FEATURE_CORECLR) && defined(_TARGET_UNIX_)
#define FEATURE_VARARG 0
-#else // !(defined(FEATURE_CORECLR) && defined(PLATFORM_UNIX))
+#else // !(defined(FEATURE_CORECLR) && defined(_TARGET_UNIX_))
#define FEATURE_VARARG 1
-#endif // !(defined(FEATURE_CORECLR) && defined(PLATFORM_UNIX))
+#endif // !(defined(FEATURE_CORECLR) && defined(_TARGET_UNIX_))
/*****************************************************************************/
// The following are human readable names for the target architectures
@@ -1080,10 +1066,10 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define REG_ARG_4 REG_R8
#define REG_ARG_5 REG_R9
- SELECTANY const regNumber intArgRegs[] = { REG_EDI, REG_ESI, REG_EDX, REG_ECX, REG_R8, REG_R9 };
- SELECTANY const regMaskTP intArgMasks[] = { REG_EDI, REG_ESI, REG_EDX, REG_ECX, REG_R8, REG_R9 };
- SELECTANY const regNumber fltArgRegs[] = { REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3, REG_XMM4, REG_XMM5, REG_XMM6, REG_XMM7 };
- SELECTANY const regMaskTP fltArgMasks[] = { REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3, REG_XMM4, REG_XMM5, REG_XMM6, REG_XMM7 };
+ SELECTANY const regNumber intArgRegs [] = { REG_EDI, REG_ESI, REG_EDX, REG_ECX, REG_R8, REG_R9 };
+ SELECTANY const regMaskTP intArgMasks[] = { RBM_EDI, RBM_ESI, RBM_EDX, RBM_ECX, RBM_R8, RBM_R9 };
+ SELECTANY const regNumber fltArgRegs [] = { REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3, REG_XMM4, REG_XMM5, REG_XMM6, REG_XMM7 };
+ SELECTANY const regMaskTP fltArgMasks[] = { RBM_XMM0, RBM_XMM1, RBM_XMM2, RBM_XMM3, RBM_XMM4, RBM_XMM5, RBM_XMM6, RBM_XMM7 };
#define RBM_ARG_0 RBM_RDI
#define RBM_ARG_1 RBM_RSI
@@ -1103,9 +1089,9 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define REG_ARG_2 REG_R8
#define REG_ARG_3 REG_R9
- SELECTANY const regNumber intArgRegs[] = { REG_ECX, REG_EDX, REG_R8, REG_R9 };
+ SELECTANY const regNumber intArgRegs [] = { REG_ECX, REG_EDX, REG_R8, REG_R9 };
SELECTANY const regMaskTP intArgMasks[] = { RBM_ECX, RBM_EDX, RBM_R8, RBM_R9 };
- SELECTANY const regNumber fltArgRegs[] = { REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3 };
+ SELECTANY const regNumber fltArgRegs [] = { REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3 };
SELECTANY const regMaskTP fltArgMasks[] = { RBM_XMM0, RBM_XMM1, RBM_XMM2, RBM_XMM3 };
#define RBM_ARG_0 RBM_ECX
@@ -1182,7 +1168,11 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
// TODO-ARM-CQ: Check for sdiv/udiv at runtime and generate it if available
#define USE_HELPERS_FOR_INT_DIV 1 // BeagleBoard (ARMv7A) doesn't support SDIV/UDIV
#define CPU_LOAD_STORE_ARCH 1
+#ifdef LEGACY_BACKEND
#define CPU_LONG_USES_REGPAIR 1
+#else
+ #define CPU_LONG_USES_REGPAIR 0
+#endif
#define CPU_HAS_FP_SUPPORT 1
#define ROUND_FLOAT 0 // Do not round intermed float expression results
#define CPU_HAS_BYTE_REGS 0
@@ -1242,7 +1232,11 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define RBM_CALLEE_SAVED (RBM_INT_CALLEE_SAVED | RBM_FLT_CALLEE_SAVED)
#define RBM_CALLEE_TRASH (RBM_INT_CALLEE_TRASH | RBM_FLT_CALLEE_TRASH)
+#ifdef LEGACY_BACKEND
#define RBM_CALLEE_TRASH_NOGC (RBM_R2|RBM_R3|RBM_LR)
+#else
+ #define RBM_CALLEE_TRASH_NOGC RBM_CALLEE_TRASH
+#endif
#define REG_DEFAULT_HELPER_CALL_TARGET REG_R12
#define RBM_ALLINT (RBM_INT_CALLEE_SAVED | RBM_INT_CALLEE_TRASH)
@@ -1382,6 +1376,10 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define RBM_VIRTUAL_STUB_PARAM RBM_R4
#define PREDICT_REG_VIRTUAL_STUB_PARAM PREDICT_REG_R4
+ // R2R indirect call. Use the same registers as VSD
+ #define REG_R2R_INDIRECT_PARAM REG_R4
+ #define RBM_R2R_INDIRECT_PARAM RBM_R4
+
// Registers used by PInvoke frame setup
#define REG_PINVOKE_FRAME REG_R4
#define RBM_PINVOKE_FRAME RBM_R4
@@ -1424,6 +1422,10 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define RBM_INTRET RBM_R0
#define REG_LNGRET REG_PAIR_R0R1
#define RBM_LNGRET (RBM_R1|RBM_R0)
+ #define REG_LNGRET_LO REG_R0
+ #define REG_LNGRET_HI REG_R1
+ #define RBM_LNGRET_LO RBM_R0
+ #define RBM_LNGRET_HI RBM_R1
#define REG_FLOATRET REG_F0
#define RBM_FLOATRET RBM_F0
@@ -1434,7 +1436,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define RBM_STOP_FOR_GC_TRASH (RBM_CALLEE_TRASH & ~(RBM_FLOATRET | RBM_INTRET))
// The registers trashed by the CORINFO_HELP_INIT_PINVOKE_FRAME helper.
- #define RBM_INIT_PINVOKE_FRAME_TRASH RBM_CALLEE_TRASH
+ #define RBM_INIT_PINVOKE_FRAME_TRASH (RBM_CALLEE_TRASH | RBM_PINVOKE_TCB | RBM_PINVOKE_SCRATCH)
#define REG_FPBASE REG_R11
#define RBM_FPBASE RBM_R11
@@ -1668,7 +1670,6 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
// R2R indirect call. Use the same registers as VSD
#define REG_R2R_INDIRECT_PARAM REG_R11
#define RBM_R2R_INDIRECT_PARAM RBM_R11
- #define PREDICT_REG_RER_INDIRECT_PARAM PREDICT_REG_R11
// Registers used by PInvoke frame setup
#define REG_PINVOKE_FRAME REG_R9
diff --git a/src/jit/unwind.h b/src/jit/unwind.h
index 27d23b1b54..c74ee2d1f3 100644
--- a/src/jit/unwind.h
+++ b/src/jit/unwind.h
@@ -321,7 +321,12 @@ class UnwindEpilogCodes : public UnwindBase, public UnwindCodesBase
public:
UnwindEpilogCodes(Compiler* comp)
- : UnwindBase(comp), uecMem(uecMemLocal), uecMemSize(UEC_LOCAL_COUNT), uecCodeSlot(-1), uecFinalized(false)
+ : UnwindBase(comp)
+ , uecMem(uecMemLocal)
+ , firstByteOfLastCode(0)
+ , uecMemSize(UEC_LOCAL_COUNT)
+ , uecCodeSlot(-1)
+ , uecFinalized(false)
{
}
@@ -332,12 +337,16 @@ public:
virtual void AddCode(BYTE b1)
{
AppendByte(b1);
+
+ firstByteOfLastCode = b1;
}
virtual void AddCode(BYTE b1, BYTE b2)
{
AppendByte(b1);
AppendByte(b2);
+
+ firstByteOfLastCode = b1;
}
virtual void AddCode(BYTE b1, BYTE b2, BYTE b3)
@@ -345,6 +354,8 @@ public:
AppendByte(b1);
AppendByte(b2);
AppendByte(b3);
+
+ firstByteOfLastCode = b1;
}
virtual void AddCode(BYTE b1, BYTE b2, BYTE b3, BYTE b4)
@@ -353,6 +364,8 @@ public:
AppendByte(b2);
AppendByte(b3);
AppendByte(b4);
+
+ firstByteOfLastCode = b1;
}
// Return a pointer to the first unwind code byte
@@ -406,11 +419,13 @@ public:
{
assert(!uecFinalized);
noway_assert(0 <= uecCodeSlot && uecCodeSlot < uecMemSize); // There better be at least one code!
- BYTE lastCode = uecMem[uecCodeSlot];
- if (!IsEndCode(lastCode)) // If the last code is an end code, we don't need to append one.
+
+ if (!IsEndCode(firstByteOfLastCode)) // If the last code is an end code, we don't need to append one.
{
- AppendByte(UWC_END); // Add a default "end" code to the end of the array of unwind codes
+ AppendByte(UWC_END); // Add a default "end" code to the end of the array of unwind codes
+ firstByteOfLastCode = UWC_END; // Update firstByteOfLastCode in case we use it later
}
+
uecFinalized = true; // With the "end" code in place, now we're done
#ifdef DEBUG
@@ -445,6 +460,7 @@ private:
// If there are more unwind codes, we dynamically allocate memory.
BYTE uecMemLocal[UEC_LOCAL_COUNT];
BYTE* uecMem;
+ BYTE firstByteOfLastCode;
// uecMemSize is the number of bytes/slots in uecMem. This is equal to UEC_LOCAL_COUNT unless
// we've dynamically allocated memory to store the codes.
diff --git a/src/jit/unwindamd64.cpp b/src/jit/unwindamd64.cpp
index 14eba8cb50..1b2baf6584 100644
--- a/src/jit/unwindamd64.cpp
+++ b/src/jit/unwindamd64.cpp
@@ -448,7 +448,7 @@ void Compiler::unwindSetFrameRegWindows(regNumber reg, unsigned offset)
func->unwindHeader.FrameRegister = (BYTE)reg;
-#ifdef PLATFORM_UNIX
+#ifdef UNIX_AMD64_ABI
if (offset > 240)
{
// On Unix only, we have a CLR-only extension to the AMD64 unwind codes: UWOP_SET_FPREG_LARGE.
@@ -467,7 +467,7 @@ void Compiler::unwindSetFrameRegWindows(regNumber reg, unsigned offset)
func->unwindHeader.FrameOffset = 15;
}
else
-#endif // PLATFORM_UNIX
+#endif // UNIX_AMD64_ABI
{
assert(func->unwindCodeSlot > sizeof(UNWIND_CODE));
UNWIND_CODE* code = (UNWIND_CODE*)&func->unwindCodes[func->unwindCodeSlot -= sizeof(UNWIND_CODE)];
@@ -697,7 +697,7 @@ void DumpUnwindInfo(bool isHotCode,
pCode->CodeOffset, pCode->UnwindOp, pCode->OpInfo); // This should be zero
break;
-#ifdef PLATFORM_UNIX
+#ifdef UNIX_AMD64_ABI
case UWOP_SET_FPREG_LARGE:
printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SET_FPREG_LARGE (%u) OpInfo: Unused (%u)\n",
@@ -712,7 +712,7 @@ void DumpUnwindInfo(bool isHotCode,
}
break;
-#endif // PLATFORM_UNIX
+#endif // UNIX_AMD64_ABI
case UWOP_SAVE_NONVOL:
printf(" CodeOffset: 0x%02X UnwindOp: UWOP_SAVE_NONVOL (%u) OpInfo: %s (%u)\n",
@@ -858,7 +858,7 @@ void Compiler::unwindReserveFuncHelper(FuncInfoDsc* func, bool isHotCode)
#ifdef UNIX_AMD64_ABI
if (generateCFIUnwindCodes())
{
- unwindCodeBytes = func->cfiCodes->size() * sizeof(CFI_CODE);
+ unwindCodeBytes = (DWORD)(func->cfiCodes->size() * sizeof(CFI_CODE));
}
else
#endif // UNIX_AMD64_ABI
@@ -956,7 +956,7 @@ void Compiler::unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pCo
#ifdef UNIX_AMD64_ABI
if (generateCFIUnwindCodes())
{
- int size = func->cfiCodes->size();
+ DWORD size = (DWORD)func->cfiCodes->size();
if (size > 0)
{
unwindCodeBytes = size * sizeof(CFI_CODE);
diff --git a/src/jit/utils.cpp b/src/jit/utils.cpp
index 3a45039aa7..9fbe394a21 100644
--- a/src/jit/utils.cpp
+++ b/src/jit/utils.cpp
@@ -25,13 +25,13 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// same code for all platforms, hence it is here instead of in the targetXXX.cpp
// files.
-#ifdef PLATFORM_UNIX
+#ifdef _TARGET_UNIX_
// Should we distinguish Mac? Can we?
// Should we distinguish flavors of Unix? Can we?
const char* Target::g_tgtPlatformName = "Unix";
-#else // !PLATFORM_UNIX
+#else // !_TARGET_UNIX_
const char* Target::g_tgtPlatformName = "Windows";
-#endif // !PLATFORM_UNIX
+#endif // !_TARGET_UNIX_
/*****************************************************************************/
@@ -698,18 +698,24 @@ const char* refCntWtd2str(unsigned refCntWtd)
nump = (nump == num1) ? num2 : num1;
- unsigned valueInt = refCntWtd / BB_UNITY_WEIGHT;
- unsigned valueFrac = refCntWtd % BB_UNITY_WEIGHT;
-
- if (valueFrac == 0)
+ if (refCntWtd == BB_MAX_WEIGHT)
{
- sprintf_s(temp, bufSize, "%2u ", valueInt);
+ sprintf_s(temp, bufSize, "MAX ");
}
else
{
- sprintf_s(temp, bufSize, "%2u.%1u", valueInt, (valueFrac * 10 / BB_UNITY_WEIGHT));
- }
+ unsigned valueInt = refCntWtd / BB_UNITY_WEIGHT;
+ unsigned valueFrac = refCntWtd % BB_UNITY_WEIGHT;
+ if (valueFrac == 0)
+ {
+ sprintf_s(temp, bufSize, "%u ", valueInt);
+ }
+ else
+ {
+ sprintf_s(temp, bufSize, "%u.%02u", valueInt, (valueFrac * 100 / BB_UNITY_WEIGHT));
+ }
+ }
return temp;
}
@@ -780,7 +786,7 @@ void ConfigMethodRange::InitRanges(const wchar_t* rangeStr, unsigned capacity)
}
// Allocate some persistent memory
- ICorJitHost* jitHost = JitHost::getJitHost();
+ ICorJitHost* jitHost = g_jitHost;
m_ranges = (Range*)jitHost->allocateMemory(capacity * sizeof(Range));
m_entries = capacity;
@@ -1358,6 +1364,7 @@ void HelperCallProperties::init()
case CORINFO_HELP_ISINSTANCEOFCLASS:
case CORINFO_HELP_ISINSTANCEOFANY:
case CORINFO_HELP_READYTORUN_ISINSTANCEOF:
+ case CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE:
isPure = true;
noThrow = true; // These return null for a failing cast
@@ -1411,9 +1418,7 @@ void HelperCallProperties::init()
case CORINFO_HELP_GETGENERICS_GCSTATIC_BASE:
case CORINFO_HELP_GETGENERICS_NONGCSTATIC_BASE:
case CORINFO_HELP_READYTORUN_STATIC_BASE:
-#if COR_JIT_EE_VERSION > 460
case CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE:
-#endif // COR_JIT_EE_VERSION > 460
// These may invoke static class constructors
// These can throw InvalidProgram exception if the class can not be constructed
@@ -1463,9 +1468,7 @@ void HelperCallProperties::init()
case CORINFO_HELP_VERIFICATION:
case CORINFO_HELP_RNGCHKFAIL:
case CORINFO_HELP_THROWDIVZERO:
-#if COR_JIT_EE_VERSION > 460
case CORINFO_HELP_THROWNULLREF:
-#endif // COR_JIT_EE_VERSION
case CORINFO_HELP_THROW:
case CORINFO_HELP_RETHROW:
@@ -1747,7 +1750,7 @@ double FloatingPointUtils::round(double x)
{
// If the number has no fractional part do nothing
// This shortcut is necessary to workaround precision loss in borderline cases on some platforms
- if (x == ((double)((__int64)x)))
+ if (x == (double)((INT64)x))
{
return x;
}
@@ -1765,3 +1768,43 @@ double FloatingPointUtils::round(double x)
return _copysign(flrTempVal, x);
}
+
+// Windows x86 and Windows ARM/ARM64 may not define _copysignf() but they do define _copysign().
+// We will redirect the macro to this other functions if the macro is not defined for the platform.
+// This has the side effect of a possible implicit upcasting for arguments passed in and an explicit
+// downcasting for the _copysign() call.
+#if (defined(_TARGET_X86_) || defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)) && !defined(FEATURE_PAL)
+
+#if !defined(_copysignf)
+#define _copysignf (float)_copysign
+#endif
+
+#endif
+
+// Rounds a single-precision floating-point value to the nearest integer,
+// and rounds midpoint values to the nearest even number.
+// Note this should align with classlib in floatsingle.cpp
+// Specializing for x86 using a x87 instruction is optional since
+// this outcome is identical across targets.
+float FloatingPointUtils::round(float x)
+{
+ // If the number has no fractional part do nothing
+ // This shortcut is necessary to workaround precision loss in borderline cases on some platforms
+ if (x == (float)((INT32)x))
+ {
+ return x;
+ }
+
+ // We had a number that was equally close to 2 integers.
+ // We need to return the even one.
+
+ float tempVal = (x + 0.5f);
+ float flrTempVal = floorf(tempVal);
+
+ if ((flrTempVal == tempVal) && (fmodf(tempVal, 2.0f) != 0))
+ {
+ flrTempVal -= 1.0f;
+ }
+
+ return _copysignf(flrTempVal, x);
+}
diff --git a/src/jit/utils.h b/src/jit/utils.h
index 1cd35903dd..b41cf84a1e 100644
--- a/src/jit/utils.h
+++ b/src/jit/utils.h
@@ -381,6 +381,15 @@ public:
return m_value;
}
+ // Mark the value as read only; explicitly change the variable to the "read" phase.
+ void MarkAsReadOnly() const
+ {
+#ifdef DEBUG
+ assert(m_initialized);
+ (const_cast<PhasedVar*>(this))->m_writePhase = false;
+#endif // DEBUG
+ }
+
// Functions/operators to write the value. Must be in the write phase.
PhasedVar& operator=(const T& value)
@@ -638,6 +647,8 @@ public:
static unsigned __int64 convertDoubleToUInt64(double d);
static double round(double x);
+
+ static float round(float x);
};
// The CLR requires that critical section locks be initialized via its ClrCreateCriticalSection API...but
diff --git a/src/jit/valuenum.cpp b/src/jit/valuenum.cpp
index aba29c4411..03bc204070 100644
--- a/src/jit/valuenum.cpp
+++ b/src/jit/valuenum.cpp
@@ -32,7 +32,7 @@ VNFunc GetVNFuncForOper(genTreeOps oper, bool isUnsigned)
case GT_LE:
return VNF_LE_UN;
case GT_GE:
- return VNF_GT_UN;
+ return VNF_GE_UN;
case GT_GT:
return VNF_GT_UN;
case GT_ADD:
@@ -206,6 +206,52 @@ T ValueNumStore::EvalOp(VNFunc vnf, T v0, T v1, ValueNum* pExcSet)
}
}
+struct FloatTraits
+{
+ static float NaN()
+ {
+ unsigned bits = 0xFFC00000u;
+ float result;
+ static_assert(sizeof(bits) == sizeof(result), "sizeof(unsigned) must equal sizeof(float)");
+ memcpy(&result, &bits, sizeof(result));
+ return result;
+ }
+};
+
+struct DoubleTraits
+{
+ static double NaN()
+ {
+ unsigned long long bits = 0xFFF8000000000000ull;
+ double result;
+ static_assert(sizeof(bits) == sizeof(result), "sizeof(unsigned long long) must equal sizeof(double)");
+ memcpy(&result, &bits, sizeof(result));
+ return result;
+ }
+};
+
+template <typename TFp, typename TFpTraits>
+TFp FpRem(TFp dividend, TFp divisor)
+{
+ // From the ECMA standard:
+ //
+ // If [divisor] is zero or [dividend] is infinity
+ // the result is NaN.
+ // If [divisor] is infinity,
+ // the result is [dividend]
+
+ if (divisor == 0 || !_finite(dividend))
+ {
+ return TFpTraits::NaN();
+ }
+ else if (!_finite(divisor) && !_isnan(divisor))
+ {
+ return dividend;
+ }
+
+ return (TFp)fmod((double)dividend, (double)divisor);
+}
+
// Specialize for double for floating operations, that doesn't involve unsigned.
template <>
double ValueNumStore::EvalOp<double>(VNFunc vnf, double v0, double v1, ValueNum* pExcSet)
@@ -223,7 +269,31 @@ double ValueNumStore::EvalOp<double>(VNFunc vnf, double v0, double v1, ValueNum*
case GT_DIV:
return v0 / v1;
case GT_MOD:
- return fmod(v0, v1);
+ return FpRem<double, DoubleTraits>(v0, v1);
+
+ default:
+ unreached();
+ }
+}
+
+// Specialize for float for floating operations, that doesn't involve unsigned.
+template <>
+float ValueNumStore::EvalOp<float>(VNFunc vnf, float v0, float v1, ValueNum* pExcSet)
+{
+ genTreeOps oper = genTreeOps(vnf);
+ // Here we handle those that are the same for floating-point types.
+ switch (oper)
+ {
+ case GT_ADD:
+ return v0 + v1;
+ case GT_SUB:
+ return v0 - v1;
+ case GT_MUL:
+ return v0 * v1;
+ case GT_DIV:
+ return v0 / v1;
+ case GT_MOD:
+ return FpRem<float, FloatTraits>(v0, v1);
default:
unreached();
@@ -833,7 +903,7 @@ ValueNum ValueNumStore::VNForHandle(ssize_t cnsVal, unsigned handleFlags)
}
// Returns the value number for zero of the given "typ".
-// It has an unreached() for a "typ" that has no zero value, such as TYP_BYREF.
+// It has an unreached() for a "typ" that has no zero value, such as TYP_VOID.
ValueNum ValueNumStore::VNZeroForType(var_types typ)
{
switch (typ)
@@ -861,6 +931,8 @@ ValueNum ValueNumStore::VNZeroForType(var_types typ)
case TYP_REF:
case TYP_ARRAY:
return VNForNull();
+ case TYP_BYREF:
+ return VNForByrefCon(0);
case TYP_STRUCT:
#ifdef FEATURE_SIMD
// TODO-CQ: Improve value numbering for SIMD types.
@@ -959,6 +1031,17 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN)
}
}
+// Windows x86 and Windows ARM/ARM64 may not define _isnanf() but they do define _isnan().
+// We will redirect the macros to these other functions if the macro is not defined for the
+// platform. This has the side effect of a possible implicit upcasting for arguments passed.
+#if (defined(_TARGET_X86_) || defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)) && !defined(FEATURE_PAL)
+
+#if !defined(_isnanf)
+#define _isnanf _isnan
+#endif
+
+#endif
+
ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, ValueNum arg1VN)
{
assert(arg0VN != NoVN && arg1VN != NoVN);
@@ -986,8 +1069,12 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
// We don't try to fold a binary operation when one of the constant operands
// is a floating-point constant and the other is not.
//
- bool arg0IsFloating = varTypeIsFloating(TypeOfVN(arg0VN));
- bool arg1IsFloating = varTypeIsFloating(TypeOfVN(arg1VN));
+ var_types arg0VNtyp = TypeOfVN(arg0VN);
+ bool arg0IsFloating = varTypeIsFloating(arg0VNtyp);
+
+ var_types arg1VNtyp = TypeOfVN(arg1VN);
+ bool arg1IsFloating = varTypeIsFloating(arg1VNtyp);
+
if (arg0IsFloating != arg1IsFloating)
{
canFold = false;
@@ -997,8 +1084,10 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
// comparison would return false, an unordered comparison
// will return true if any operands are a NaN. We only perform
// ordered NaN comparison in EvalComparison.
- if ((arg0IsFloating && _isnan(GetConstantDouble(arg0VN))) ||
- (arg1IsFloating && _isnan(GetConstantDouble(arg1VN))))
+ if ((arg0IsFloating && (((arg0VNtyp == TYP_FLOAT) && _isnanf(GetConstantSingle(arg0VN))) ||
+ ((arg0VNtyp == TYP_DOUBLE) && _isnan(GetConstantDouble(arg0VN))))) ||
+ (arg1IsFloating && (((arg1VNtyp == TYP_FLOAT) && _isnanf(GetConstantSingle(arg1VN))) ||
+ ((arg0VNtyp == TYP_DOUBLE) && _isnan(GetConstantDouble(arg1VN))))))
{
canFold = false;
}
@@ -1607,27 +1696,24 @@ INT64 ValueNumStore::GetConstantInt64(ValueNum argVN)
return result;
}
-// Given a float or a double constant value number return its value as a double.
+// Given a double constant value number return its value as a double.
//
double ValueNumStore::GetConstantDouble(ValueNum argVN)
{
assert(IsVNConstant(argVN));
- var_types argVNtyp = TypeOfVN(argVN);
+ assert(TypeOfVN(argVN) == TYP_DOUBLE);
- double result = 0;
+ return ConstantValue<double>(argVN);
+}
- switch (argVNtyp)
- {
- case TYP_FLOAT:
- result = (double)ConstantValue<float>(argVN);
- break;
- case TYP_DOUBLE:
- result = ConstantValue<double>(argVN);
- break;
- default:
- unreached();
- }
- return result;
+// Given a float constant value number return its value as a float.
+//
+float ValueNumStore::GetConstantSingle(ValueNum argVN)
+{
+ assert(IsVNConstant(argVN));
+ assert(TypeOfVN(argVN) == TYP_FLOAT);
+
+ return ConstantValue<float>(argVN);
}
// Compute the proper value number when the VNFunc has all constant arguments
@@ -1796,40 +1882,52 @@ ValueNum ValueNumStore::EvalFuncForConstantFPArgs(var_types typ, VNFunc func, Va
assert(CanEvalForConstantArgs(func));
assert(IsVNConstant(arg0VN) && IsVNConstant(arg1VN));
- // We expect both argument types to be floating point types
+ // We expect both argument types to be floating-point types
var_types arg0VNtyp = TypeOfVN(arg0VN);
var_types arg1VNtyp = TypeOfVN(arg1VN);
assert(varTypeIsFloating(arg0VNtyp));
assert(varTypeIsFloating(arg1VNtyp));
- double arg0Val = GetConstantDouble(arg0VN);
- double arg1Val = GetConstantDouble(arg1VN);
+ // We also expect both arguments to be of the same floating-point type
+ assert(arg0VNtyp == arg1VNtyp);
ValueNum result; // left uninitialized, we are required to initialize it on all paths below.
if (VNFuncIsComparison(func))
{
assert(genActualType(typ) == TYP_INT);
- result = VNForIntCon(EvalComparison(func, arg0Val, arg1Val));
+
+ if (arg0VNtyp == TYP_FLOAT)
+ {
+ result = VNForIntCon(EvalComparison(func, GetConstantSingle(arg0VN), GetConstantSingle(arg1VN)));
+ }
+ else
+ {
+ assert(arg0VNtyp == TYP_DOUBLE);
+ result = VNForIntCon(EvalComparison(func, GetConstantDouble(arg0VN), GetConstantDouble(arg1VN)));
+ }
}
else
{
- assert(varTypeIsFloating(typ)); // We must be computing a floating point result
+ // We expect the return type to be the same as the argument type
+ assert(varTypeIsFloating(typ));
+ assert(arg0VNtyp == typ);
- // We always compute the result using a double
- ValueNum exception = VNForEmptyExcSet();
- double doubleResultVal = EvalOp(func, arg0Val, arg1Val, &exception);
- assert(exception == VNForEmptyExcSet()); // Floating point ops don't throw.
+ ValueNum exception = VNForEmptyExcSet();
if (typ == TYP_FLOAT)
{
- float floatResultVal = float(doubleResultVal);
- result = VNForFloatCon(floatResultVal);
+ float floatResultVal = EvalOp(func, GetConstantSingle(arg0VN), GetConstantSingle(arg1VN), &exception);
+ assert(exception == VNForEmptyExcSet()); // Floating point ops don't throw.
+ result = VNForFloatCon(floatResultVal);
}
else
{
assert(typ == TYP_DOUBLE);
+
+ double doubleResultVal = EvalOp(func, GetConstantDouble(arg0VN), GetConstantDouble(arg1VN), &exception);
+ assert(exception == VNForEmptyExcSet()); // Floating point ops don't throw.
result = VNForDoubleCon(doubleResultVal);
}
}
@@ -1876,6 +1974,7 @@ ValueNum ValueNumStore::EvalCastForConstantArgs(var_types typ, VNFunc func, Valu
{
#ifndef _TARGET_64BIT_
case TYP_REF:
+ case TYP_BYREF:
#endif
case TYP_INT:
{
@@ -1934,6 +2033,9 @@ ValueNum ValueNumStore::EvalCastForConstantArgs(var_types typ, VNFunc func, Valu
else
return VNForLongCon(INT64(arg0Val));
#endif
+ case TYP_BYREF:
+ assert(typ == TYP_BYREF);
+ return VNForByrefCon((INT64)arg0Val);
case TYP_FLOAT:
assert(typ == TYP_FLOAT);
if (srcIsUnsigned)
@@ -1962,6 +2064,7 @@ ValueNum ValueNumStore::EvalCastForConstantArgs(var_types typ, VNFunc func, Valu
{
#ifdef _TARGET_64BIT_
case TYP_REF:
+ case TYP_BYREF:
#endif
case TYP_LONG:
INT64 arg0Val = GetConstantInt64(arg0VN);
@@ -1992,6 +2095,9 @@ ValueNum ValueNumStore::EvalCastForConstantArgs(var_types typ, VNFunc func, Valu
case TYP_ULONG:
assert(typ == TYP_LONG);
return arg0VN;
+ case TYP_BYREF:
+ assert(typ == TYP_BYREF);
+ return VNForByrefCon((INT64)arg0Val);
case TYP_FLOAT:
assert(typ == TYP_FLOAT);
if (srcIsUnsigned)
@@ -2017,6 +2123,47 @@ ValueNum ValueNumStore::EvalCastForConstantArgs(var_types typ, VNFunc func, Valu
}
}
case TYP_FLOAT:
+ {
+ float arg0Val = GetConstantSingle(arg0VN);
+
+ switch (castToType)
+ {
+ case TYP_BYTE:
+ assert(typ == TYP_INT);
+ return VNForIntCon(INT8(arg0Val));
+ case TYP_BOOL:
+ case TYP_UBYTE:
+ assert(typ == TYP_INT);
+ return VNForIntCon(UINT8(arg0Val));
+ case TYP_SHORT:
+ assert(typ == TYP_INT);
+ return VNForIntCon(INT16(arg0Val));
+ case TYP_CHAR:
+ case TYP_USHORT:
+ assert(typ == TYP_INT);
+ return VNForIntCon(UINT16(arg0Val));
+ case TYP_INT:
+ assert(typ == TYP_INT);
+ return VNForIntCon(INT32(arg0Val));
+ case TYP_UINT:
+ assert(typ == TYP_INT);
+ return VNForIntCon(UINT32(arg0Val));
+ case TYP_LONG:
+ assert(typ == TYP_LONG);
+ return VNForLongCon(INT64(arg0Val));
+ case TYP_ULONG:
+ assert(typ == TYP_LONG);
+ return VNForLongCon(UINT64(arg0Val));
+ case TYP_FLOAT:
+ assert(typ == TYP_FLOAT);
+ return VNForFloatCon(arg0Val);
+ case TYP_DOUBLE:
+ assert(typ == TYP_DOUBLE);
+ return VNForDoubleCon(double(arg0Val));
+ default:
+ unreached();
+ }
+ }
case TYP_DOUBLE:
{
double arg0Val = GetConstantDouble(arg0VN);
@@ -3062,6 +3209,53 @@ void ValueNumStore::GetConstantBoundInfo(ValueNum vn, ConstantBoundInfo* info)
}
}
+//------------------------------------------------------------------------
+// IsVNArrLenUnsignedBound: Checks if the specified vn represents an expression
+// such as "(uint)i < (uint)a.len" that implies that the array index is valid
+// (0 <= i && i < a.len).
+//
+// Arguments:
+// vn - Value number to query
+// info - Pointer to an ArrLenUnsignedBoundInfo object to return information about
+// the expression. Not populated if the vn expression isn't suitable (e.g. i <= a.len).
+// This enables optCreateJTrueBoundAssertion to immediatly create an OAK_NO_THROW
+// assertion instead of the OAK_EQUAL/NOT_EQUAL assertions created by signed compares
+// (IsVNArrLenBound, IsVNArrLenArithBound) that require further processing.
+
+bool ValueNumStore::IsVNArrLenUnsignedBound(ValueNum vn, ArrLenUnsignedBoundInfo* info)
+{
+ VNFuncApp funcApp;
+
+ if (GetVNFunc(vn, &funcApp))
+ {
+ if ((funcApp.m_func == VNF_LT_UN) || (funcApp.m_func == VNF_GE_UN))
+ {
+ // We only care about "(uint)i < (uint)a.len" and its negation "(uint)i >= (uint)a.len"
+ if (IsVNArrLen(funcApp.m_args[1]))
+ {
+ info->vnIdx = funcApp.m_args[0];
+ info->cmpOper = funcApp.m_func;
+ info->vnLen = funcApp.m_args[1];
+ return true;
+ }
+ }
+ else if ((funcApp.m_func == VNF_GT_UN) || (funcApp.m_func == VNF_LE_UN))
+ {
+ // We only care about "(uint)a.len > (uint)i" and its negation "(uint)a.len <= (uint)i"
+ if (IsVNArrLen(funcApp.m_args[0]))
+ {
+ info->vnIdx = funcApp.m_args[1];
+ // Let's keep a consistent operand order - it's always i < a.len, never a.len > i
+ info->cmpOper = (funcApp.m_func == VNF_GT_UN) ? VNF_LT_UN : VNF_GE_UN;
+ info->vnLen = funcApp.m_args[0];
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
bool ValueNumStore::IsVNArrLenBound(ValueNum vn)
{
// Do we have "var < a.len"?
@@ -3257,48 +3451,103 @@ bool ValueNumStore::IsVNArrLen(ValueNum vn)
ValueNum ValueNumStore::EvalMathFuncUnary(var_types typ, CorInfoIntrinsics gtMathFN, ValueNum arg0VN)
{
assert(arg0VN == VNNormVal(arg0VN));
+
+ // If the math intrinsic is not implemented by target-specific instructions, such as implemented
+ // by user calls, then don't do constant folding on it. This minimizes precision loss.
+
if (IsVNConstant(arg0VN) && Compiler::IsTargetIntrinsic(gtMathFN))
{
- // If the math intrinsic is not implemented by target-specific instructions, such as implemented
- // by user calls, then don't do constant folding on it. This minimizes precision loss.
- // I *may* need separate tracks for the double/float -- if the intrinsic funcs have overloads for these.
- double arg0Val = GetConstantDouble(arg0VN);
+ assert(varTypeIsFloating(TypeOfVN(arg0VN)));
- double res = 0.0;
- switch (gtMathFN)
- {
- case CORINFO_INTRINSIC_Sin:
- res = sin(arg0Val);
- break;
- case CORINFO_INTRINSIC_Cos:
- res = cos(arg0Val);
- break;
- case CORINFO_INTRINSIC_Sqrt:
- res = sqrt(arg0Val);
- break;
- case CORINFO_INTRINSIC_Abs:
- res = fabs(arg0Val); // The result and params are doubles.
- break;
- case CORINFO_INTRINSIC_Round:
- res = FloatingPointUtils::round(arg0Val);
- break;
- default:
- unreached(); // the above are the only math intrinsics at the time of this writing.
- }
if (typ == TYP_DOUBLE)
{
+ // Both operand and its result must be of the same floating point type.
+ assert(typ == TypeOfVN(arg0VN));
+ double arg0Val = GetConstantDouble(arg0VN);
+
+ double res = 0.0;
+ switch (gtMathFN)
+ {
+ case CORINFO_INTRINSIC_Sin:
+ res = sin(arg0Val);
+ break;
+ case CORINFO_INTRINSIC_Cos:
+ res = cos(arg0Val);
+ break;
+ case CORINFO_INTRINSIC_Sqrt:
+ res = sqrt(arg0Val);
+ break;
+ case CORINFO_INTRINSIC_Abs:
+ res = fabs(arg0Val);
+ break;
+ case CORINFO_INTRINSIC_Round:
+ res = FloatingPointUtils::round(arg0Val);
+ break;
+ default:
+ unreached(); // the above are the only math intrinsics at the time of this writing.
+ }
+
return VNForDoubleCon(res);
}
else if (typ == TYP_FLOAT)
{
- return VNForFloatCon(float(res));
+ // Both operand and its result must be of the same floating point type.
+ assert(typ == TypeOfVN(arg0VN));
+ float arg0Val = GetConstantSingle(arg0VN);
+
+ float res = 0.0f;
+ switch (gtMathFN)
+ {
+ case CORINFO_INTRINSIC_Sin:
+ res = sinf(arg0Val);
+ break;
+ case CORINFO_INTRINSIC_Cos:
+ res = cosf(arg0Val);
+ break;
+ case CORINFO_INTRINSIC_Sqrt:
+ res = sqrtf(arg0Val);
+ break;
+ case CORINFO_INTRINSIC_Abs:
+ res = fabsf(arg0Val);
+ break;
+ case CORINFO_INTRINSIC_Round:
+ res = FloatingPointUtils::round(arg0Val);
+ break;
+ default:
+ unreached(); // the above are the only math intrinsics at the time of this writing.
+ }
+
+ return VNForFloatCon(res);
}
else
{
+ // CORINFO_INTRINSIC_Round is currently the only intrinsic that takes floating-point arguments
+ // and that returns a non floating-point result.
+
assert(typ == TYP_INT);
assert(gtMathFN == CORINFO_INTRINSIC_Round);
- return VNForIntCon(int(res));
+ int res = 0;
+
+ switch (TypeOfVN(arg0VN))
+ {
+ case TYP_DOUBLE:
+ {
+ double arg0Val = GetConstantDouble(arg0VN);
+ res = int(FloatingPointUtils::round(arg0Val));
+ break;
+ }
+ case TYP_FLOAT:
+ {
+ float arg0Val = GetConstantSingle(arg0VN);
+ res = int(FloatingPointUtils::round(arg0Val));
+ break;
+ }
+ default:
+ unreached();
+ }
+
+ return VNForIntCon(res);
}
}
else
@@ -7388,11 +7637,9 @@ VNFunc Compiler::fgValueNumberHelperMethVNFunc(CorInfoHelpFunc helpFunc)
case CORINFO_HELP_READYTORUN_STATIC_BASE:
vnf = VNF_ReadyToRunStaticBase;
break;
-#if COR_JIT_EE_VERSION > 460
case CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE:
vnf = VNF_ReadyToRunGenericStaticBase;
break;
-#endif // COR_JIT_EE_VERSION > 460
case CORINFO_HELP_GETSHARED_GCSTATIC_BASE_DYNAMICCLASS:
vnf = VNF_GetsharedGcstaticBaseDynamicclass;
break;
@@ -7466,6 +7713,10 @@ VNFunc Compiler::fgValueNumberHelperMethVNFunc(CorInfoHelpFunc helpFunc)
vnf = VNF_IsInstanceOf;
break;
+ case CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE:
+ vnf = VNF_TypeHandleToRuntimeType;
+ break;
+
case CORINFO_HELP_READYTORUN_ISINSTANCEOF:
vnf = VNF_ReadyToRunIsInstanceOf;
break;
diff --git a/src/jit/valuenum.h b/src/jit/valuenum.h
index e6e0e43a33..2be48491df 100644
--- a/src/jit/valuenum.h
+++ b/src/jit/valuenum.h
@@ -205,6 +205,7 @@ private:
int GetConstantInt32(ValueNum argVN);
INT64 GetConstantInt64(ValueNum argVN);
double GetConstantDouble(ValueNum argVN);
+ float GetConstantSingle(ValueNum argVN);
// Assumes that all the ValueNum arguments of each of these functions have been shown to represent constants.
// Assumes that "vnf" is a operator of the appropriate arity (unary for the first, binary for the second).
@@ -536,6 +537,17 @@ public:
// Returns true iff the VN represents an integeral constant.
bool IsVNInt32Constant(ValueNum vn);
+ struct ArrLenUnsignedBoundInfo
+ {
+ unsigned cmpOper;
+ ValueNum vnIdx;
+ ValueNum vnLen;
+
+ ArrLenUnsignedBoundInfo() : cmpOper(GT_NONE), vnIdx(NoVN), vnLen(NoVN)
+ {
+ }
+ };
+
struct ArrLenArithBoundInfo
{
// (vnArr.len - 1) > vnOp
@@ -606,6 +618,9 @@ public:
// If "vn" is constant bound, then populate the "info" fields for constVal, cmpOp, cmpOper.
void GetConstantBoundInfo(ValueNum vn, ConstantBoundInfo* info);
+ // If "vn" is of the form "(uint)var < (uint)a.len" (or equivalent) return true.
+ bool IsVNArrLenUnsignedBound(ValueNum vn, ArrLenUnsignedBoundInfo* info);
+
// If "vn" is of the form "var < a.len" or "a.len <= var" return true.
bool IsVNArrLenBound(ValueNum vn);
@@ -663,9 +678,13 @@ private:
__fallthrough;
case TYP_BYREF:
-#ifndef PLATFORM_UNIX
+
+#ifdef _MSC_VER
+
assert(&typeid(T) == &typeid(size_t)); // We represent ref/byref constants as size_t's.
-#endif // PLATFORM_UNIX
+
+#endif // _MSC_VER
+
__fallthrough;
case TYP_INT:
diff --git a/src/jit/valuenumfuncs.h b/src/jit/valuenumfuncs.h
index cb99507921..2711b4f056 100644
--- a/src/jit/valuenumfuncs.h
+++ b/src/jit/valuenumfuncs.h
@@ -34,6 +34,7 @@ ValueNumFuncDef(CastClass, 2, false, false, false) // Args: 0: Handle o
ValueNumFuncDef(IsInstanceOf, 2, false, false, false) // Args: 0: Handle of class being queried, 1: object being queried.
ValueNumFuncDef(ReadyToRunCastClass, 2, false, false, false) // Args: 0: Helper stub address, 1: object being cast.
ValueNumFuncDef(ReadyToRunIsInstanceOf, 2, false, false, false) // Args: 0: Helper stub address, 1: object being queried.
+ValueNumFuncDef(TypeHandleToRuntimeType, 1, false, false, false) // Args: 0: TypeHandle to translate
ValueNumFuncDef(LdElemA, 3, false, false, false) // Args: 0: array value; 1: index value; 2: type handle of element.
diff --git a/src/md/compiler/classfactory.cpp b/src/md/compiler/classfactory.cpp
index 603f7975aa..338095add3 100644
--- a/src/md/compiler/classfactory.cpp
+++ b/src/md/compiler/classfactory.cpp
@@ -42,14 +42,6 @@ const COCLASS_REGISTER g_CoClasses[] =
{
// pClsid szProgID pfnCreateObject
{ &CLSID_CorMetaDataDispenser, W("CorMetaDataDispenser"), Disp::CreateObject },
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE) // coreclr doesn't export these
- { &CLSID_CorMetaDataDispenserRuntime, W("CorMetaDataDispenserRuntime"), Disp::CreateObject },
-
- { &CLSID_CorRuntimeHost, W("CorRuntimeHost"), CorHost::CreateObject },
- { &CLSID_CLRRuntimeHost, W("CLRRuntimeHost"), CorHost2::CreateObject },
- { &__uuidof(CLRPrivRuntime), W("CLRPrivRuntime"), CorHost2::CreateObject },
- { &CLSID_TypeNameFactory, NULL, (PFN_CREATE_OBJ)TypeNameFactoryCreateObject },
-#endif // FEATURE_CORECLR && !CROSSGEN_COMPILE
{ NULL, NULL, NULL }
};
diff --git a/src/md/compiler/disp.cpp b/src/md/compiler/disp.cpp
index b091729744..85b71286d2 100644
--- a/src/md/compiler/disp.cpp
+++ b/src/md/compiler/disp.cpp
@@ -16,9 +16,6 @@
#include <corerror.h>
#include <mdlog.h>
#include <mdcommon.h>
-#ifdef FEATURE_COMINTEROP_TLB_SUPPORT
-#include <imptlb.h>
-#endif
#ifdef EnC_SUPPORTED
#define ENC_DELTA_HACK
@@ -95,11 +92,7 @@ Disp::DefineScope(
// Figure out what version of the metadata to emit
if (rclsid == CLSID_CLR_v1_MetaData)
{
-#ifdef FEATURE_METADATA_STANDALONE_WINRT
- IfFailGo(E_NOTIMPL);
-#else
optionForNewScope.m_MetadataVersion = MDVersion1;
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
}
else if (rclsid == CLSID_CLR_v2_MetaData)
{
@@ -200,7 +193,7 @@ static HRESULT DeliverScope(IMDCommon *pMDCommon, REFIID riid, DWORD dwOpenFlags
HRESULT hr;
BEGIN_ENTRYPOINT_NOTHROW;
-#if !defined(FEATURE_METADATA_STANDALONE_WINRT) && defined(FEATURE_COMINTEROP)
+#if defined(FEATURE_COMINTEROP)
IfFailGo((dwOpenFlags & ofNoTransform) ? S_FALSE : CheckIfWinMDAdapterNeeded(pMDCommon));
if (hr == S_OK)
{
@@ -439,13 +432,6 @@ ErrExit:
return hr;
} // Disp::OpenScopeOnMemory
-#if defined(FEATURE_METADATA_IN_VM) && !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-
-#include <metahost.h>
-// Pointer to the activated CLR interface provided by the shim.
-extern ICLRRuntimeInfo * g_pCLRRuntime;
-
-#endif
//*****************************************************************************
// Get the directory where the CLR system resides.
@@ -458,27 +444,11 @@ Disp::GetCORSystemDirectory(
DWORD cchBuffer, // [in] Size of the buffer
DWORD *pcchBuffer) // [out] Number of characters returned
{
-#if defined(FEATURE_METADATA_IN_VM) && !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- // This implies a machine-wide CLR install root, which may not exist for some CLR
- // skus using standalone metadata.
- *pcchBuffer = cchBuffer;
- hr = g_pCLRRuntime->GetRuntimeDirectory(szBuffer, pcchBuffer);
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-#else //!FEATURE_METADATA_IN_VM || FEATURE_CORECLR
-#ifdef FEATURE_CORECLR
UNREACHABLE_MSG("Calling IMetaDataDispenser::GetCORSystemDirectory! This code should not be "
"reachable or needs to be reimplemented for CoreCLR!");
-#endif //FEATURE_CORECLR
return E_NOTIMPL;
-#endif //!FEATURE_METADATA_IN_VM || FEATURE_CORECLR
} // Disp::GetCORSystemDirectory
HRESULT Disp::FindAssembly( // S_OK or error
@@ -912,7 +882,7 @@ ErrExit:
return hr;
} // Disp::GetOption
-#if defined(FEATURE_METADATA_IN_VM) || defined(FEATURE_METADATA_STANDALONE_WINRT)
+#if defined(FEATURE_METADATA_IN_VM)
//---------------------------------------------------------------------------------------
//
@@ -924,7 +894,7 @@ void DeleteMetaData()
LOADEDMODULES::DeleteStatics();
}
-#endif //FEATURE_METADATA_IN_VM || FEATURE_METADATA_STANDALONE_WINRT
+#endif //FEATURE_METADATA_IN_VM
//
// This is the entrypoint for usages of MetaData that need to start with the dispenser (e.g.
diff --git a/src/md/compiler/mdperf.h b/src/md/compiler/mdperf.h
index 77def32d21..a83c8c9ba7 100644
--- a/src/md/compiler/mdperf.h
+++ b/src/md/compiler/mdperf.h
@@ -143,7 +143,6 @@
MD_FUNC(GetCustomAttributeProps)\
MD_FUNC(FindTypeRef)\
MD_FUNC(RefToDefOptimization)\
- MD_FUNC(ProcessFilter)\
MD_FUNC(DefineAssembly)\
MD_FUNC(DefineAssemblyRef)\
MD_FUNC(DefineFile)\
diff --git a/src/md/compiler/mdsighelper.h b/src/md/compiler/mdsighelper.h
index 0d089729bb..49c0752fe3 100644
--- a/src/md/compiler/mdsighelper.h
+++ b/src/md/compiler/mdsighelper.h
@@ -104,13 +104,7 @@ class UnifiedAssemblySigComparer : public MDSigComparer::MDSigComparerBaseType
protected:
RegMeta *m_pRegMeta;
-#ifdef FEATURE_FUSION
- HRESULT _CreateIAssemblyNameFromAssemblyRef(
- mdToken tkAsmRef,
- IAssemblyName **ppAsmName);
-#else
HRESULT _CompareAssemblies(mdToken tkAsmRef1,mdToken tkAsmRef2, BOOL* pfEquivalent);
-#endif
HRESULT _CreateTypeNameFromTypeRef(
mdToken tkTypeRef,
diff --git a/src/md/compiler/mdutil.cpp b/src/md/compiler/mdutil.cpp
index 2e01258bea..0de5ad45ea 100644
--- a/src/md/compiler/mdutil.cpp
+++ b/src/md/compiler/mdutil.cpp
@@ -20,7 +20,7 @@
#include <rwutil.h>
-#if defined(FEATURE_METADATA_IN_VM) || defined(FEATURE_METADATA_STANDALONE_WINRT)
+#if defined(FEATURE_METADATA_IN_VM)
LOADEDMODULES * LOADEDMODULES::s_pLoadedModules = NULL;
UTSemReadWrite * LOADEDMODULES::m_pSemReadWrite = NULL;
@@ -363,7 +363,7 @@ ErrExit:
#endif //_DEBUG
-#endif //FEATURE_METADATA_IN_VM || FEATURE_METADATA_STANDALONE_WINRT
+#endif //FEATURE_METADATA_IN_VM
#ifdef FEATURE_METADATA_IN_VM
diff --git a/src/md/compiler/mdutil.h b/src/md/compiler/mdutil.h
index 58cdbf108a..331817ec9a 100644
--- a/src/md/compiler/mdutil.h
+++ b/src/md/compiler/mdutil.h
@@ -61,7 +61,7 @@ public:
}; // class CORPATHService
-#if defined(FEATURE_METADATA_IN_VM) || defined(FEATURE_METADATA_STANDALONE_WINRT)
+#if defined(FEATURE_METADATA_IN_VM)
class RegMeta;
@@ -114,6 +114,6 @@ public:
#endif
}; // class LOADEDMODULES
-#endif //FEATURE_METADATA_IN_VM || FEATURE_METADATA_STANDALONE_WINRT
+#endif //FEATURE_METADATA_IN_VM
#endif // __MDUtil__h__
diff --git a/src/md/compiler/mdvalidator.cpp b/src/md/compiler/mdvalidator.cpp
index adcfd51eb3..ce6c14e468 100644
--- a/src/md/compiler/mdvalidator.cpp
+++ b/src/md/compiler/mdvalidator.cpp
@@ -19,9 +19,6 @@
#include "pedecoder.h"
#include "stgio.h"
#include "corhost.h"
-#ifdef FEATURE_FUSION
-#include "fusion.h"
-#endif
#include "sstring.h"
#include "nsutilpriv.h"
#include "holder.h"
@@ -5210,7 +5207,7 @@ HRESULT RegMeta::ValidateAssembly(RID rid)
dwFlags = (CorAssemblyFlags) pMiniMd->getFlagsOfAssembly(pRecord);
// Validate the flags
- invalidAssemblyFlags = dwFlags & (~(afPublicKey | afRetargetable | afPA_FullMask | afEnableJITcompileTracking | afDisableJITcompileOptimizer | afContentType_Mask));
+ invalidAssemblyFlags = dwFlags & (~(afPublicKey | afRetargetable | afPA_FullMask | afDebuggableAttributeMask | afContentType_Mask));
// Validate we only set a legal processor architecture flags
// The processor architecture flags were introduced in CLR v2.0.
@@ -7185,123 +7182,7 @@ MDSigComparer::_CompareMethodSignatureHeader(
//*****************************************************************************
//*****************************************************************************
-#ifdef FEATURE_FUSION
-HRESULT
-UnifiedAssemblySigComparer::_CreateIAssemblyNameFromAssemblyRef(
- mdToken tkAsmRef,
- IAssemblyName **ppAsmName)
-{
- HRESULT hr;
-
- void const * pvPublicKey;
- ULONG cbPublicKey;
- ULONG cchName;
- ASSEMBLYMETADATA amd;
- void const * pvHashValue;
- ULONG cbHashValue;
- DWORD dwFlags;
-
- ZeroMemory(&amd, sizeof(amd));
-
- IfFailRet(m_pRegMeta->GetAssemblyRefProps(tkAsmRef,
- NULL,
- NULL,
- NULL,
- 0,
- &cchName,
- &amd,
- NULL,
- NULL,
- NULL));
-
- StackSString ssName;
- StackSString ssLocale;
- amd.szLocale = ssLocale.OpenUnicodeBuffer(amd.cbLocale);
-
- IfFailRet(m_pRegMeta->GetAssemblyRefProps(tkAsmRef,
- &pvPublicKey,
- &cbPublicKey,
- ssName.OpenUnicodeBuffer(cchName),
- cchName,
- &cchName,
- &amd,
- &pvHashValue,
- &cbHashValue,
- &dwFlags));
-
- ssName.CloseBuffer();
- ssLocale.CloseBuffer();
-
- IAssemblyName *pAsmName = NULL;
-
- IfFailRet(CreateAssemblyNameObject(&pAsmName,
- ssName.GetUnicode(),
- CANOF_SET_DEFAULT_VALUES,
- NULL));
-
- // Set the public key token
- IfFailRet(pAsmName->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN,
- (LPVOID)pvPublicKey,
- cbPublicKey));
- // Set the culture
- if (amd.cbLocale == 0 || amd.szLocale == NULL)
- {
- IfFailRet(pAsmName->SetProperty(ASM_NAME_CULTURE,
- W("Neutral"),
- sizeof(W("Neutral"))));
- }
- else
- {
- IfFailRet(pAsmName->SetProperty(ASM_NAME_CULTURE,
- amd.szLocale,
- amd.cbLocale));
- }
-
- // Set the major version
- IfFailRet(pAsmName->SetProperty(ASM_NAME_MAJOR_VERSION,
- &amd.usMajorVersion,
- sizeof(amd.usMajorVersion)));
-
- // Set the minor version
- IfFailRet(pAsmName->SetProperty(ASM_NAME_MINOR_VERSION,
- &amd.usMinorVersion,
- sizeof(amd.usMinorVersion)));
-
- // Set the build number
- IfFailRet(pAsmName->SetProperty(ASM_NAME_BUILD_NUMBER,
- &amd.usBuildNumber,
- sizeof(amd.usBuildNumber)));
-
- // Set the revision number
- IfFailRet(pAsmName->SetProperty(ASM_NAME_REVISION_NUMBER,
- &amd.usRevisionNumber,
- sizeof(amd.usRevisionNumber)));
-
- *ppAsmName = pAsmName;
-
- return S_OK;
-}
-
-//*****************************************************************************
-// Define holder to release IAssemblyName on exception.
-//*****************************************************************************
-void UnifiedAssemblySigComparer_IAssemblyNameRelease(IAssemblyName *value)
-{
- if (value != NULL)
- {
- value->Release();
- }
-}
-
-typedef Holder<IAssemblyName*,
- DoNothing<IAssemblyName*>,
- &UnifiedAssemblySigComparer_IAssemblyNameRelease,
- NULL> UnifiedAssemblySigComparer_IAssemblyNameHolder;
-
-#endif // FEATURE_FUSION
-
-#ifndef FEATURE_FUSION
HRESULT UnifiedAssemblySigComparer::_CompareAssemblies(mdToken tkAsmRef1,mdToken tkAsmRef2, BOOL* pfEquivalent)
{
@@ -7417,7 +7298,6 @@ HRESULT UnifiedAssemblySigComparer::_CompareAssemblies(mdToken tkAsmRef1,mdToken
return S_OK;
};
-#endif // FEATURE_FUSION
//*****************************************************************************
//*****************************************************************************
@@ -7523,38 +7403,8 @@ UnifiedAssemblySigComparer::CompareToken(
}
BOOL fEquivalent;
-#ifdef FEATURE_FUSION //move into _CompareAssemblies
- IAssemblyName *pAsmName1 = NULL;
- IfFailRet(_CreateIAssemblyNameFromAssemblyRef(tkParent1, &pAsmName1));
- UnifiedAssemblySigComparer_IAssemblyNameHolder anh1(pAsmName1);
-
- IAssemblyName *pAsmName2 = NULL;
- IfFailRet(_CreateIAssemblyNameFromAssemblyRef(tkParent2, &pAsmName2));
- UnifiedAssemblySigComparer_IAssemblyNameHolder anh2(pAsmName2);
-
- DWORD cchDisplayName = 0;
-
- StackSString ssDisplayName1;
- pAsmName1->GetDisplayName(NULL, &cchDisplayName, NULL);
- IfFailRet(pAsmName1->GetDisplayName(ssDisplayName1.OpenUnicodeBuffer(cchDisplayName), &cchDisplayName, NULL));
- ssDisplayName1.CloseBuffer();
-
- StackSString ssDisplayName2;
- pAsmName2->GetDisplayName(NULL, &cchDisplayName, NULL);
- IfFailRet(pAsmName2->GetDisplayName(ssDisplayName2.OpenUnicodeBuffer(cchDisplayName), &cchDisplayName, NULL));
- ssDisplayName2.CloseBuffer();
-
- AssemblyComparisonResult res;
- IfFailRet(CompareAssemblyIdentity(ssDisplayName1.GetUnicode(),
- TRUE,
- ssDisplayName2.GetUnicode(),
- TRUE,
- &fEquivalent,
- &res));
-#else
// no redirects supported
IfFailRet(_CompareAssemblies(tkParent1,tkParent2,&fEquivalent));
-#endif
if (!fEquivalent)
{
diff --git a/src/md/compiler/newmerger.cpp b/src/md/compiler/newmerger.cpp
deleted file mode 100644
index d5199bb570..0000000000
--- a/src/md/compiler/newmerger.cpp
+++ /dev/null
@@ -1,6303 +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.
-//*****************************************************************************
-// NewMerger.cpp
-//
-
-//
-// contains utility code to MD directory
-//
-// This file provides Compiler Support functionality in metadata.
-//*****************************************************************************
-#include "stdafx.h"
-
-#include "newmerger.h"
-#include "regmeta.h"
-
-
-#include "importhelper.h"
-#include "rwutil.h"
-#include "mdlog.h"
-#include <posterror.h>
-#include <sstring.h>
-#include "ndpversion.h"
-
-#ifdef FEATURE_METADATA_EMIT_ALL
-
-#define MODULEDEFTOKEN TokenFromRid(1, mdtModule)
-
-#define COR_MSCORLIB_NAME "mscorlib"
-#define COR_MSCORLIB_TYPEREF {0xb7, 0x7a, 0x5c, 0x56,0x19,0x34,0xe0,0x89}
-
-#define COR_CONSTRUCTOR_METADATA_IDENTIFIER W(".ctor")
-
-#define COR_COMPILERSERVICE_NAMESPACE "System.Runtime.CompilerServices"
-#define COR_EXCEPTIONSERVICE_NAMESPACE "System.Runtime.ExceptionServices"
-#define COR_SUPPRESS_MERGE_CHECK_ATTRIBUTE "SuppressMergeCheckAttribute"
-#define COR_HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE "HandleProcessCorruptedStateExceptionsAttribute"
-#define COR_MISCBITS_NAMESPACE "Microsoft.VisualC"
-#define COR_MISCBITS_ATTRIBUTE "Microsoft.VisualC.MiscellaneousBitsAttribute"
-#define COR_NATIVECPPCLASS_ATTRIBUTE "System.Runtime.CompilerServices.NativeCppClassAttribute"
-
-// MODULE_CA_LOCATION W("System.Runtime.CompilerServices.AssemblyAttributesGoHere")
-#define MODULE_CA_TYPENAME "AssemblyAttributesGoHere" // fake assembly type-ref for hanging Assembly-level CAs off of
-
-//*****************************************************************************
-// BEGIN: Security Critical Attributes and Enumeration
-//*****************************************************************************
-#define COR_SECURITYCRITICALSCOPE_ENUM_W W("System.Security.SecurityCriticalScope")
-
-#define COR_SECURITYCRITICAL_ATTRIBUTE_FULL "System.Security.SecurityCriticalAttribute"
-#define COR_SECURITYTRANSPARENT_ATTRIBUTE_FULL "System.Security.SecurityTransparentAttribute"
-#define COR_SECURITYTREATASSAFE_ATTRIBUTE_FULL "System.Security.SecurityTreatAsSafeAttribute"
-
-#define COR_SECURITYCRITICAL_ATTRIBUTE_FULL_W W("System.Security.SecurityCriticalAttribute")
-#define COR_SECURITYTRANSPARENT_ATTRIBUTE_FULL_W W("System.Security.SecurityTransparentAttribute")
-#define COR_SECURITYTREATASSAFE_ATTRIBUTE_FULL_W W("System.Security.SecurityTreatAsSafeAttribute")
-#define COR_SECURITYSAFECRITICAL_ATTRIBUTE_FULL_W W("System.Security.SecuritySafeCriticalAttribute")
-
- // definitions of enumeration for System.Security.SecurityCriticalScope (Explicit or Everything)
-#define COR_SECURITYCRITICAL_CTOR_ARGCOUNT_NO_SCOPE 0
-#define COR_SECURITYCRITICAL_CTOR_ARGCOUNT_SCOPE_EVERYTHING 1
-#define COR_SECURITYCRITICAL_CTOR_NO_SCOPE_SIG_MAX_SIZE (3)
-#define COR_SECURITYCRITICAL_CTOR_SCOPE_SIG_MAX_SIZE (5 + sizeof(mdTypeRef) * 1)
-
-#define COR_SECURITYCRITICAL_ATTRIBUTE_NAMESPACE "System.Security"
-#define COR_SECURITYCRITICAL_ATTRIBUTE "SecurityCriticalAttribute"
-#define COR_SECURITYTRANSPARENT_ATTRIBUTE_NAMESPACE "System.Security"
-#define COR_SECURITYTRANSPARENT_ATTRIBUTE "SecurityTransparentAttribute"
-#define COR_SECURITYTREATASSAFE_ATTRIBUTE_NAMESPACE "System.Security"
-#define COR_SECURITYTREATASSAFE_ATTRIBUTE "SecurityTreatAsSafeAttribute"
-#define COR_SECURITYSAFECRITICAL_ATTRIBUTE "SecuritySafeCriticalAttribute"
-
-
-#define COR_SECURITYCRITICAL_ATTRIBUTE_VALUE_EVERYTHING { 0x01, 0x00 ,0x01, 0x00, 0x00, 0x00 ,0x00, 0x00 }
-#define COR_SECURITYCRITICAL_ATTRIBUTE_VALUE_EXPLICIT {0x01, 0x00, 0x00 ,0x00}
-#define COR_SECURITYTREATASSAFE_ATTRIBUTE_VALUE {0x01, 0x00, 0x00 ,0x00}
-
-
- // if true, then registry has been read for enabling or disabling SecurityCritical support
-static BOOL g_fRefShouldMergeCriticalChecked = FALSE;
-
-// by default, security critical attributes will be merged (e.g. unmarked CRT marked Critical/TAS)
-// - unless registry config explicitly disables merging
-static BOOL g_fRefShouldMergeCritical = TRUE;
-//*****************************************************************************
-// END: Security Critical Attributes and Enumeration
-//*****************************************************************************
-
-//*****************************************************************************
-// Checks to see if the given type is managed or native. We'll key off of the
-// Custom Attribute "Microsoft.VisualC.MiscellaneousBitsAttribute". If the third
-// byte has the 01000000 bit set then it is an unmanaged type.
-// If we can't find the attribute, we will also check for the presence of the
-// "System.Runtime.CompilerServices.NativeCppClassAttribute" Custom Attribute
-// since the CPP compiler stopped emitting MiscellaneousBitsAttribute in Dev11.
-//*****************************************************************************
-HRESULT IsManagedType(CMiniMdRW* pMiniMd,
- mdTypeDef td,
- BOOL *fIsManagedType)
-{
- // First look for the custom attribute
- HENUMInternal hEnum;
- HRESULT hr = S_OK;
-
- IfFailRet(pMiniMd->CommonEnumCustomAttributeByName(td, COR_MISCBITS_ATTRIBUTE, false, &hEnum));
-
- // If there aren't any custom attributes here, then this must be a managed type
- if (hEnum.m_ulCount > 0)
- {
- // Let's loop through these, and see if any of them have that magical bit set.
- mdCustomAttribute ca;
- CustomAttributeRec *pRec;
- ULONG cbData = 0;
-
- while(HENUMInternal::EnumNext(&hEnum, &ca))
- {
- const BYTE* pData = NULL;
-
- IfFailGo(pMiniMd->GetCustomAttributeRecord(RidFromToken(ca), &pRec));
- IfFailGo(pMiniMd->getValueOfCustomAttribute(pRec, &pData, &cbData));
-
- if (pData != NULL && cbData >=3)
- {
- // See if the magical bit is set to make this an unmanaged type
- if ((*(pData+2)&0x40) > 0)
- {
- // Yes, this is an unmanaged type
- HENUMInternal::ClearEnum(&hEnum);
- *fIsManagedType = FALSE;
- return S_OK;
- }
- }
- }
-
- }
-
- HENUMInternal::ClearEnum(&hEnum);
-
- // If this was emitted by a Dev11+ CPP compiler, we only have NativeCppClassAttribute
- // so let's check for that before calling this a managed class.
- IfFailRet(pMiniMd->CommonEnumCustomAttributeByName(td, COR_NATIVECPPCLASS_ATTRIBUTE, false, &hEnum));
- if (hEnum.m_ulCount > 0)
- {
- // Yes, this is an unmanaged type
- HENUMInternal::ClearEnum(&hEnum);
- *fIsManagedType = FALSE;
- return S_OK;
- }
-
- // Nope, this isn't an unmanaged type.... must be managed
- HENUMInternal::ClearEnum(&hEnum);
- *fIsManagedType = TRUE;
- hr = S_OK;
-ErrExit:
- return hr;
-}// IsManagedType
-
-
-//*****************************************************************************
-// "Is CustomAttribute from certain namespace and assembly" check helper
-// Returns S_OK and fills **ppTypeRefRec.
-// Returns error code or S_FALSE otherwise as not found and fills **ppTypeRefRec with NULL.
-//*****************************************************************************
-HRESULT IsAttributeFromNamespace(
- CMiniMdRW *pMiniMd,
- mdToken tk,
- LPCSTR szNamespace,
- LPCSTR szAssembly,
- TypeRefRec **ppTypeRefRec)
-{
- HRESULT hr = S_OK;
- if(TypeFromToken(tk) == mdtMemberRef)
- {
- MemberRefRec *pMemRefRec;
- IfFailGo(pMiniMd->GetMemberRefRecord(RidFromToken(tk), &pMemRefRec));
- tk = pMiniMd->getClassOfMemberRef(pMemRefRec);
- }
- if(TypeFromToken(tk) == mdtTypeRef)
- {
- TypeRefRec *pTypeRefRec;
- IfFailGo(pMiniMd->GetTypeRefRecord(RidFromToken(tk), &pTypeRefRec));
- LPCSTR szTypeRefNamespace;
- IfFailGo(pMiniMd->getNamespaceOfTypeRef(pTypeRefRec, &szTypeRefNamespace));
- if (strcmp(szTypeRefNamespace, szNamespace) == 0)
- {
- mdToken tkResTmp = pMiniMd->getResolutionScopeOfTypeRef(pTypeRefRec);
- if (TypeFromToken(tkResTmp) == mdtAssemblyRef)
- {
- AssemblyRefRec *pAsmRefRec;
- IfFailGo(pMiniMd->GetAssemblyRefRecord(RidFromToken(tkResTmp), &pAsmRefRec));
- LPCSTR szAssemblyRefName;
- IfFailGo(pMiniMd->getNameOfAssemblyRef(pAsmRefRec, &szAssemblyRefName));
- if(SString::_stricmp(szAssemblyRefName, szAssembly) == 0)
- {
- *ppTypeRefRec = pTypeRefRec;
- return S_OK;
- }
- }
- }
- }
- // Record not found
- hr = S_FALSE;
-ErrExit:
- *ppTypeRefRec = NULL;
- return hr;
-}
-
-//*****************************************************************************
-// constructor
-//*****************************************************************************
-NEWMERGER::NEWMERGER()
- : m_pRegMetaEmit(0),
- m_pImportDataList(NULL),
- m_optimizeRefToDef(MDRefToDefDefault),
- m_isscsSecurityCritical(ISSCS_Unknown),
- m_isscsSecurityCriticalAllScopes(~ISSCS_Unknown)
-{
- m_pImportDataTail = &(m_pImportDataList);
-#if _DEBUG
- m_iImport = 0;
-#endif // _DEBUG
-} // NEWMERGER::NEWMERGER()
-
-//*****************************************************************************
-// initializer
-//*****************************************************************************
-HRESULT NEWMERGER::Init(RegMeta *pRegMeta)
-{
- HRESULT hr = NOERROR;
- MergeTypeData * pMTD;
-
- m_pRegMetaEmit = pRegMeta;
-
- // burn an entry so that the RID matches the array index
- IfNullGo(pMTD = m_rMTDs.Append());
-
- pMTD->m_bSuppressMergeCheck = false;
- pMTD->m_cMethods = 0;
- pMTD->m_cFields = 0;
- pMTD->m_cEvents = 0;
- pMTD->m_cProperties = 0;
-
-ErrExit:
- return hr;
-} // NEWMERGER::Init
-
-//*****************************************************************************
-// destructor
-//*****************************************************************************
-NEWMERGER::~NEWMERGER()
-{
- if (m_pImportDataList)
- {
- // delete this list and release all AddRef'ed interfaces!
- MergeImportData *pNext;
- for (pNext = m_pImportDataList; pNext != NULL; )
- {
- pNext = m_pImportDataList->m_pNextImportData;
- if (m_pImportDataList->m_pHandler)
- m_pImportDataList->m_pHandler->Release();
- if (m_pImportDataList->m_pHostMapToken)
- m_pImportDataList->m_pHostMapToken->Release();
- if (m_pImportDataList->m_pMDTokenMap)
- delete m_pImportDataList->m_pMDTokenMap;
- m_pImportDataList->m_pRegMetaImport->Release();
- delete m_pImportDataList;
- m_pImportDataList = pNext;
- }
- }
-} // NEWMERGER::~NEWMERGER
-
-//*****************************************************************************
-CMiniMdRW *NEWMERGER::GetMiniMdEmit()
-{
- return &(m_pRegMetaEmit->m_pStgdb->m_MiniMd);
-} // CMiniMdRW *NEWMERGER::GetMiniMdEmit()
-
-//*****************************************************************************
-// Adding a new import
-//*****************************************************************************
-HRESULT NEWMERGER::AddImport(
- IMetaDataImport2 *pImport, // [IN] The scope to be merged.
- IMapToken *pHostMapToken, // [IN] Host IMapToken interface to receive token remap notification
- IUnknown *pHandler) // [IN] An object to receive error notification.
-{
- HRESULT hr = NOERROR;
- MergeImportData *pData;
-
- RegMeta *pRM = static_cast<RegMeta*>(pImport);
-
- // Add a MergeImportData to track the information for this import scope
- pData = new (nothrow) MergeImportData;
- IfNullGo( pData );
- pData->m_pRegMetaImport = pRM;
- pData->m_pRegMetaImport->AddRef();
- pData->m_pHostMapToken = pHostMapToken;
- if (pData->m_pHostMapToken)
- pData->m_pHostMapToken->AddRef();
- if (pHandler)
- {
- pData->m_pHandler = pHandler;
- pData->m_pHandler->AddRef();
- }
- else
- {
- pData->m_pHandler = NULL;
- }
-
- pData->m_pMDTokenMap = NULL;
- pData->m_pNextImportData = NULL;
-#if _DEBUG
- pData->m_iImport = ++m_iImport;
-#endif // _DEBUG
-
- pData->m_tkHandleProcessCorruptedStateCtor = mdTokenNil;
- // add the newly create node to the tail of the list
- *m_pImportDataTail = pData;
- m_pImportDataTail = &(pData->m_pNextImportData);
-
-ErrExit:
-
- return hr;
-} // HRESULT NEWMERGER::AddImport()
-
-HRESULT NEWMERGER::InitMergeTypeData()
-{
- CMiniMdRW *pMiniMdEmit;
- ULONG cTypeDefRecs;
- ULONG i, j;
- bool bSuppressMergeCheck;
-
- ULONG ridStart, ridEnd;
- RID ridMap;
-
- mdToken tkSuppressMergeCheckCtor = mdTokenNil;
- mdToken tkCA;
- mdMethodDef mdEmit;
- mdFieldDef fdEmit;
- mdEvent evEmit;
- mdProperty prEmit;
-
- TypeDefRec *pTypeDefRec;
- EventMapRec *pEventMapRec;
- PropertyMapRec *pPropertyMapRec;
-
- MergeTypeData *pMTD;
-
- HRESULT hr = NOERROR;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- // cache the SuppressMergeCheckAttribute.ctor token
- ImportHelper::FindCustomAttributeCtorByName(
- pMiniMdEmit, COR_MSCORLIB_NAME,
- COR_COMPILERSERVICE_NAMESPACE, COR_SUPPRESS_MERGE_CHECK_ATTRIBUTE,
- &tkSuppressMergeCheckCtor);
-
- cTypeDefRecs = pMiniMdEmit->getCountTypeDefs();
- _ASSERTE(m_rMTDs.Count() > 0);
-
- for (i = m_rMTDs.Count(); i <= cTypeDefRecs; i++)
- {
- IfNullGo(pMTD = m_rMTDs.Append());
-
- pMTD->m_cMethods = 0;
- pMTD->m_cFields = 0;
- pMTD->m_cEvents = 0;
- pMTD->m_cProperties = 0;
- pMTD->m_bSuppressMergeCheck = (tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdEmit,
- TokenFromRid(i, mdtTypeDef), tkSuppressMergeCheckCtor,
- NULL, 0, &tkCA));
-
- IfFailGo(pMiniMdEmit->GetTypeDefRecord(i, &pTypeDefRec));
-
- // Count the number methods
- ridStart = pMiniMdEmit->getMethodListOfTypeDef(pTypeDefRec);
- IfFailGo(pMiniMdEmit->getEndMethodListOfTypeDef(i, &ridEnd));
-
- for (j = ridStart; j < ridEnd; j++)
- {
- IfFailGo(pMiniMdEmit->GetMethodRid(j, (ULONG *)&mdEmit));
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdEmit,
- mdEmit, tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (!bSuppressMergeCheck)
- {
- pMTD->m_cMethods++;
- }
- }
-
- // Count the number fields
- ridStart = pMiniMdEmit->getFieldListOfTypeDef(pTypeDefRec);
- IfFailGo(pMiniMdEmit->getEndFieldListOfTypeDef(i, &ridEnd));
-
- for (j = ridStart; j < ridEnd; j++)
- {
- IfFailGo(pMiniMdEmit->GetFieldRid(j, (ULONG *)&fdEmit));
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdEmit,
- fdEmit, tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (!bSuppressMergeCheck)
- {
- pMTD->m_cFields++;
- }
- }
-
- // Count the number of events
- IfFailGo(pMiniMdEmit->FindEventMapFor(i, &ridMap));
- if (!InvalidRid(ridMap))
- {
- IfFailGo(pMiniMdEmit->GetEventMapRecord(ridMap, &pEventMapRec));
- ridStart = pMiniMdEmit->getEventListOfEventMap(pEventMapRec);
- IfFailGo(pMiniMdEmit->getEndEventListOfEventMap(ridMap, &ridEnd));
-
- for (j = ridStart; j < ridEnd; j++)
- {
- IfFailGo(pMiniMdEmit->GetEventRid(j, (ULONG *)&evEmit));
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdEmit,
- evEmit, tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (!bSuppressMergeCheck)
- {
- pMTD->m_cEvents++;
- }
- }
- }
-
- // Count the number of properties
- IfFailGo(pMiniMdEmit->FindPropertyMapFor(i, &ridMap));
- if (!InvalidRid(ridMap))
- {
- IfFailGo(pMiniMdEmit->GetPropertyMapRecord(ridMap, &pPropertyMapRec));
- ridStart = pMiniMdEmit->getPropertyListOfPropertyMap(pPropertyMapRec);
- IfFailGo(pMiniMdEmit->getEndPropertyListOfPropertyMap(ridMap, &ridEnd));
-
- for (j = ridStart; j < ridEnd; j++)
- {
- IfFailGo(pMiniMdEmit->GetPropertyRid(j, (ULONG *)&prEmit));
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdEmit,
- prEmit, tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (!bSuppressMergeCheck)
- {
- pMTD->m_cProperties++;
- }
- }
- }
- }
-
-ErrExit:
- return hr;
-}
-
-//*****************************************************************************
-// Merge now
-//*****************************************************************************
-HRESULT NEWMERGER::Merge(MergeFlags dwMergeFlags, CorRefToDefCheck optimizeRefToDef)
-{
- MergeImportData *pImportData = m_pImportDataList;
- MDTOKENMAP **pPrevMap = NULL;
- MDTOKENMAP *pMDTokenMap;
- HRESULT hr = NOERROR;
- MDTOKENMAP *pCurTKMap;
- int i;
-
-#if _DEBUG
- {
- LOG((LOGMD, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"));
- LOG((LOGMD, "Merge scope list\n"));
- i = 0;
- for (MergeImportData *pID = m_pImportDataList; pID != NULL; pID = pID->m_pNextImportData)
- {
- WCHAR szScope[1024], szGuid[40];
- GUID mvid;
- ULONG cchScope;
- pID->m_pRegMetaImport->GetScopeProps(szScope, 1024, &cchScope, &mvid);
- szScope[1023] = 0;
- GuidToLPWSTR(mvid, szGuid, 40);
- ++i; // Counter is 1-based.
- LOG((LOGMD, "%3d: %ls : %ls\n", i, szGuid, szScope));
- }
- LOG((LOGMD, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"));
- }
-#endif // _DEBUG
-
- m_dwMergeFlags = dwMergeFlags;
- m_optimizeRefToDef = optimizeRefToDef;
-
- // check to see if we need to do dup check
- m_fDupCheck = ((m_dwMergeFlags & NoDupCheck) != NoDupCheck);
-
- while (pImportData)
- {
- // Verify that we have a filter for each import scope.
- IfNullGo( pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd.GetFilterTable() );
-
- // cache the SuppressMergeCheckAttribute.ctor token for each import scope
- ImportHelper::FindCustomAttributeCtorByName(
- &pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd, COR_MSCORLIB_NAME,
- COR_COMPILERSERVICE_NAMESPACE, COR_SUPPRESS_MERGE_CHECK_ATTRIBUTE,
- &pImportData->m_tkSuppressMergeCheckCtor);
-
- // cache the HandleProcessCorruptedStateExceptionsAttribute.ctor token for each import scope
- ImportHelper::FindCustomAttributeCtorByName(
- &pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd, COR_MSCORLIB_NAME,
- COR_EXCEPTIONSERVICE_NAMESPACE, COR_HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE,
- &pImportData->m_tkHandleProcessCorruptedStateCtor);
-
- // check for security critical attribute in the assembly (i.e. explicit annotations)
- InputScopeSecurityCriticalStatus isscsTemp = CheckInputScopeIsCritical(pImportData, hr);
- IfFailGo(hr);
- // clear the unset flag bits (e.g. if critical, clear transparent bit)
- // whatever bits remain are bits that have been set in all scopes
- if (ISSCS_Unknown == (isscsTemp & ISSCS_SECURITYCRITICAL_FLAGS))
- m_isscsSecurityCriticalAllScopes &= ISSCS_SECURITYCRITICAL_LEGACY;
- else
- m_isscsSecurityCriticalAllScopes &= isscsTemp;
- // set the flag bits (essentially, this allows us to see if _any_ scopes requested a bit)
- m_isscsSecurityCritical |= isscsTemp;
-
- // create the tokenmap class to track metadata token remap for each import scope
- pMDTokenMap = new (nothrow) MDTOKENMAP;
- IfNullGo(pMDTokenMap);
- IfFailGo(pMDTokenMap->Init((IMetaDataImport2*)pImportData->m_pRegMetaImport));
- pImportData->m_pMDTokenMap = pMDTokenMap;
- pImportData->m_pMDTokenMap->m_pMap = pImportData->m_pHostMapToken;
- if (pImportData->m_pHostMapToken)
- pImportData->m_pHostMapToken->AddRef();
- pImportData->m_pMDTokenMap->m_pNextMap = NULL;
- if (pPrevMap)
- *pPrevMap = pImportData->m_pMDTokenMap;
- pPrevMap = &(pImportData->m_pMDTokenMap->m_pNextMap);
- pImportData = pImportData->m_pNextImportData;
- }
-
- // Populate the m_rMTDs with the type info already defined in the emit scope
- IfFailGo( InitMergeTypeData() );
-
- // 1. Merge Module
- IfFailGo( MergeModule( ) );
-
- // 2. Merge TypeDef partially (i.e. only name)
- IfFailGo( MergeTypeDefNamesOnly() );
-
- // 3. Merge ModuleRef property and do ModuleRef to ModuleDef optimization
- IfFailGo( MergeModuleRefs() );
-
- // 4. Merge AssemblyRef.
- IfFailGo( MergeAssemblyRefs() );
-
- // 5. Merge TypeRef with TypeRef to TypeDef optimization
- IfFailGo( MergeTypeRefs() );
-
- // 6. Merge TypeSpec & MethodSpec
- IfFailGo( MergeTypeSpecs() );
-
- // 7. Now Merge the remaining of TypeDef records
- IfFailGo( CompleteMergeTypeDefs() );
-
- // 8. Merge Methods and Fields. Such that Signature translation is respecting the TypeRef to TypeDef optimization.
- IfFailGo( MergeTypeDefChildren() );
-
- // 9. Merge MemberRef with MemberRef to MethodDef/FieldDef optimization
- IfFailGo( MergeMemberRefs( ) );
-
- // 10. Merge InterfaceImpl
- IfFailGo( MergeInterfaceImpls( ) );
-
- // merge all of the remaining in metadata ....
-
- // 11. constant has dependency on property, field, param
- IfFailGo( MergeConstants() );
-
- // 12. field marshal has dependency on param and field
- IfFailGo( MergeFieldMarshals() );
-
- // 13. in ClassLayout, move over the FieldLayout and deal with FieldLayout as well
- IfFailGo( MergeClassLayouts() );
-
- // 14. FieldLayout has dependency on FieldDef.
- IfFailGo( MergeFieldLayouts() );
-
- // 15. FieldRVA has dependency on FieldDef.
- IfFailGo( MergeFieldRVAs() );
-
- // 16. MethodImpl has dependency on MemberRef, MethodDef, TypeRef and TypeDef.
- IfFailGo( MergeMethodImpls() );
-
- // 17. pinvoke depends on MethodDef and ModuleRef
- IfFailGo( MergePinvoke() );
-
- IfFailGo( MergeStandAloneSigs() );
-
- IfFailGo( MergeMethodSpecs() );
-
- IfFailGo( MergeStrings() );
-
- if (m_dwMergeFlags & MergeManifest)
- {
- // keep the manifest!!
- IfFailGo( MergeAssembly() );
- IfFailGo( MergeFiles() );
- IfFailGo( MergeExportedTypes() );
- IfFailGo( MergeManifestResources() );
- }
- else if (m_dwMergeFlags & ::MergeExportedTypes)
- {
- IfFailGo( MergeFiles() );
- IfFailGo( MergeExportedTypes() );
- }
-
- IfFailGo( MergeCustomAttributes() );
- IfFailGo( MergeDeclSecuritys() );
-
-
- // Please don't add any MergeXxx() below here. CustomAttributess must be
- // very late, because custom values are various other types.
-
- // Fixup list cannot be merged. Linker will need to re-emit them.
-
- // Now call back to host for the result of token remap
- //
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // Send token remap information for each import scope
- pCurTKMap = pImportData->m_pMDTokenMap;
- TOKENREC *pRec;
- if (pImportData->m_pHostMapToken)
- {
- for (i = 0; i < pCurTKMap->Count(); i++)
- {
- pRec = pCurTKMap->Get(i);
- if (!pRec->IsEmpty())
- pImportData->m_pHostMapToken->Map(pRec->m_tkFrom, pRec->m_tkTo);
- }
- }
- }
-
- // And last, but not least, let's do Security critical module-level attribute consolidation
- // and metadata fixups.
- IfFailGo( MergeSecurityCriticalAttributes() );
-
-
-
-
-
-#if _DEBUG
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // dump the mapping
- LOG((LOGMD, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"));
- LOG((LOGMD, "Dumping token remap for one import scope!\n"));
- LOG((LOGMD, "This is the %d import scope for merge!\n", pImportData->m_iImport));
-
- pCurTKMap = pImportData->m_pMDTokenMap;
- TOKENREC *pRec;
- for (i = 0; i < pCurTKMap->Count(); i++)
- {
- pRec = pCurTKMap->Get(i);
- if (!pRec->IsEmpty())
- {
- LOG((LOGMD, " Token 0x%08x ====>>>> Token 0x%08x\n", pRec->m_tkFrom, pRec->m_tkTo));
- }
- }
- LOG((LOGMD, "End dumping token remap!\n"));
- LOG((LOGMD, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"));
- }
-#endif // _DEBUG
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::Merge()
-
-
-//*****************************************************************************
-// Merge ModuleDef
-//*****************************************************************************
-HRESULT NEWMERGER::MergeModule()
-{
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
- HRESULT hr = NOERROR;
- TOKENREC *pTokenRec;
-
- // we don't really merge Module information but we create a one to one mapping for each module token into the TokenMap
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- // set the current MDTokenMap
-
- pCurTkMap = pImportData->m_pMDTokenMap;
- IfFailGo( pCurTkMap->InsertNotFound(MODULEDEFTOKEN, true, MODULEDEFTOKEN, &pTokenRec) );
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeModule()
-
-
-//*****************************************************************************
-// Merge TypeDef but only Names. This is a partial merge to support TypeRef to TypeDef optimization
-//*****************************************************************************
-HRESULT NEWMERGER::MergeTypeDefNamesOnly()
-{
- HRESULT hr = NOERROR;
- TypeDefRec *pRecImport = NULL;
- TypeDefRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdTypeDef tdEmit;
- mdTypeDef tdImport;
- bool bDuplicate;
- DWORD dwFlags;
- DWORD dwExportFlags;
- NestedClassRec *pNestedRec;
- RID iNestedRec;
- mdTypeDef tdNester;
- TOKENREC *pTokenRec;
-
- LPCUTF8 szNameImp;
- LPCUTF8 szNamespaceImp;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- mdCustomAttribute tkCA;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- iCount = pMiniMdImport->getCountTypeDefs();
-
- // Merge the typedefs
- for (i = 1; i <= iCount; i++)
- {
- // only merge those TypeDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsTypeDefMarked(TokenFromRid(i, mdtTypeDef)) == false)
- continue;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetTypeDefRecord(i, &pRecImport));
- IfFailGo(pMiniMdImport->getNameOfTypeDef(pRecImport, &szNameImp));
- IfFailGo(pMiniMdImport->getNamespaceOfTypeDef(pRecImport, &szNamespaceImp));
-
- // If the class is a Nested class, get the parent token.
- dwFlags = pMiniMdImport->getFlagsOfTypeDef(pRecImport);
- if (IsTdNested(dwFlags))
- {
- IfFailGo(pMiniMdImport->FindNestedClassHelper(TokenFromRid(i, mdtTypeDef), &iNestedRec));
- if (InvalidRid(iNestedRec))
- {
- _ASSERTE(!"Bad state!");
- IfFailGo(META_E_BADMETADATA);
- }
- else
- {
- IfFailGo(pMiniMdImport->GetNestedClassRecord(iNestedRec, &pNestedRec));
- tdNester = pMiniMdImport->getEnclosingClassOfNestedClass(pNestedRec);
- _ASSERTE(!IsNilToken(tdNester));
- IfFailGo(pCurTkMap->Remap(tdNester, &tdNester));
- }
- }
- else
- tdNester = mdTokenNil;
-
- bSuppressMergeCheck = (pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- TokenFromRid(i, mdtTypeDef), pImportData->m_tkSuppressMergeCheckCtor,
- NULL, 0, &tkCA));
-
- // does this TypeDef already exist in the emit scope?
- if ( ImportHelper::FindTypeDefByName(
- pMiniMdEmit,
- szNamespaceImp,
- szNameImp,
- tdNester,
- &tdEmit) == S_OK )
- {
- // Yes, it does
- bDuplicate = true;
-
- // Let's look at their accessiblities.
- IfFailGo(pMiniMdEmit->GetTypeDefRecord(RidFromToken(tdEmit), &pRecEmit));
- dwExportFlags = pMiniMdEmit->getFlagsOfTypeDef(pRecEmit);
-
- // Managed types need to have the same accessiblity
- BOOL fManagedType = FALSE;
- IfFailGo(IsManagedType(pMiniMdImport, TokenFromRid(i, mdtTypeDef), &fManagedType));
- if (fManagedType)
- {
- if ((dwFlags&tdVisibilityMask) != (dwExportFlags&tdVisibilityMask))
- {
- CheckContinuableErrorEx(META_E_MISMATCHED_VISIBLITY, pImportData, TokenFromRid(i, mdtTypeDef));
- }
-
- }
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
- if (pMTD->m_bSuppressMergeCheck != bSuppressMergeCheck)
- {
- CheckContinuableErrorEx(META_E_MD_INCONSISTENCY, pImportData, TokenFromRid(i, mdtTypeDef));
- }
- }
- else
- {
- // No, it doesn't. Copy it over.
- bDuplicate = false;
- IfFailGo(pMiniMdEmit->AddTypeDefRecord(&pRecEmit, (RID *)&tdEmit));
-
- // make sure the index matches
- _ASSERTE(((mdTypeDef)m_rMTDs.Count()) == tdEmit);
-
- IfNullGo(pMTD = m_rMTDs.Append());
-
- pMTD->m_cMethods = 0;
- pMTD->m_cFields = 0;
- pMTD->m_cEvents = 0;
- pMTD->m_cProperties = 0;
- pMTD->m_bSuppressMergeCheck = bSuppressMergeCheck;
-
- tdEmit = TokenFromRid( tdEmit, mdtTypeDef );
-
- // Set Full Qualified Name.
- IfFailGo( CopyTypeDefPartially( pRecEmit, pMiniMdImport, pRecImport) );
-
- // Create a NestedClass record if the class is a Nested class.
- if (! IsNilToken(tdNester))
- {
- IfFailGo(pMiniMdEmit->AddNestedClassRecord(&pNestedRec, &iNestedRec));
-
- // copy over the information
- IfFailGo( pMiniMdEmit->PutToken(TBL_NestedClass, NestedClassRec::COL_NestedClass,
- pNestedRec, tdEmit));
-
- // tdNester has already been remapped above to the Emit scope.
- IfFailGo( pMiniMdEmit->PutToken(TBL_NestedClass, NestedClassRec::COL_EnclosingClass,
- pNestedRec, tdNester));
- IfFailGo( pMiniMdEmit->AddNestedClassToHash(iNestedRec) );
-
- }
- }
-
- // record the token movement
- tdImport = TokenFromRid(i, mdtTypeDef);
- IfFailGo( pCurTkMap->InsertNotFound(tdImport, bDuplicate, tdEmit, &pTokenRec) );
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeTypeDefNamesOnly()
-
-
-//*****************************************************************************
-// Merge EnclosingType tables
-//*****************************************************************************
-HRESULT NEWMERGER::CopyTypeDefPartially(
- TypeDefRec *pRecEmit, // [IN] the emit record to fill
- CMiniMdRW *pMiniMdImport, // [IN] the importing scope
- TypeDefRec *pRecImp) // [IN] the record to import
-
-{
- HRESULT hr;
- LPCUTF8 szNameImp;
- LPCUTF8 szNamespaceImp;
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
-
- IfFailGo(pMiniMdImport->getNameOfTypeDef(pRecImp, &szNameImp));
- IfFailGo(pMiniMdImport->getNamespaceOfTypeDef(pRecImp, &szNamespaceImp));
-
- IfFailGo( pMiniMdEmit->PutString( TBL_TypeDef, TypeDefRec::COL_Name, pRecEmit, szNameImp) );
- IfFailGo( pMiniMdEmit->PutString( TBL_TypeDef, TypeDefRec::COL_Namespace, pRecEmit, szNamespaceImp) );
-
- pRecEmit->SetFlags(pRecImp->GetFlags());
-
- // Don't copy over the extends until TypeRef's remap is calculated
-
-ErrExit:
- return hr;
-
-} // HRESULT NEWMERGER::CopyTypeDefPartially()
-
-
-//*****************************************************************************
-// Merge ModuleRef tables including ModuleRef to ModuleDef optimization
-//*****************************************************************************
-HRESULT NEWMERGER::MergeModuleRefs()
-{
- HRESULT hr = NOERROR;
- ModuleRefRec *pRecImport = NULL;
- ModuleRefRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdModuleRef mrEmit;
- bool bDuplicate = false;
- TOKENREC *pTokenRec;
- LPCUTF8 szNameImp;
- bool isModuleDef;
-
- MergeImportData *pImportData;
- MergeImportData *pData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountModuleRefs();
-
- // loop through all ModuleRef
- for (i = 1; i <= iCount; i++)
- {
- // only merge those ModuleRefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsModuleRefMarked(TokenFromRid(i, mdtModuleRef)) == false)
- continue;
-
- isModuleDef = false;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetModuleRefRecord(i, &pRecImport));
- IfFailGo(pMiniMdImport->getNameOfModuleRef(pRecImport, &szNameImp));
-
- // Only do the ModuleRef to ModuleDef optimization if ModuleRef's name is meaningful!
- if ( szNameImp && szNameImp[0] != '\0')
- {
-
- // Check to see if this ModuleRef has become the ModuleDef token
- for (pData = m_pImportDataList; pData != NULL; pData = pData->m_pNextImportData)
- {
- CMiniMdRW *pMiniMd = &(pData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- ModuleRec *pRec;
- LPCUTF8 szName;
-
- IfFailGo(pMiniMd->GetModuleRecord(MODULEDEFTOKEN, &pRec));
- IfFailGo(pMiniMd->getNameOfModule(pRec, &szName));
- if (szName && szName[0] != '\0' && strcmp(szNameImp, szName) == 0)
- {
- // We found an import Module for merging that has the same name as the ModuleRef
- isModuleDef = true;
- bDuplicate = true;
- mrEmit = MODULEDEFTOKEN; // set the resulting token to ModuleDef Token
- break;
- }
- }
- }
-
- if (isModuleDef == false)
- {
- // does this ModuleRef already exist in the emit scope?
- hr = ImportHelper::FindModuleRef(pMiniMdEmit,
- szNameImp,
- &mrEmit);
- if (hr == S_OK)
- {
- // Yes, it does
- bDuplicate = true;
- }
- else if (hr == CLDB_E_RECORD_NOTFOUND)
- {
- // No, it doesn't. Copy it over.
- bDuplicate = false;
- IfFailGo(pMiniMdEmit->AddModuleRefRecord(&pRecEmit, (RID*)&mrEmit));
- mrEmit = TokenFromRid(mrEmit, mdtModuleRef);
-
- // Set ModuleRef Name.
- IfFailGo( pMiniMdEmit->PutString(TBL_ModuleRef, ModuleRefRec::COL_Name, pRecEmit, szNameImp) );
- }
- else
- IfFailGo(hr);
- }
-
- // record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(
- TokenFromRid(i, mdtModuleRef),
- bDuplicate,
- mrEmit,
- &pTokenRec) );
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeModuleRefs()
-
-
-//*****************************************************************************
-// Merge AssemblyRef tables
-//*****************************************************************************
-HRESULT NEWMERGER::MergeAssemblyRefs()
-{
- HRESULT hr = NOERROR;
- AssemblyRefRec *pRecImport = NULL;
- AssemblyRefRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- mdAssemblyRef arEmit;
- bool bDuplicate = false;
- LPCUTF8 szTmp;
- const void *pbTmp;
- ULONG cbTmp;
- ULONG iCount;
- ULONG i;
- ULONG iRecord;
- TOKENREC *pTokenRec;
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountAssemblyRefs();
-
- // loope through all the AssemblyRefs.
- for (i = 1; i <= iCount; i++)
- {
- // Compare with the emit scope.
- IfFailGo(pMiniMdImport->GetAssemblyRefRecord(i, &pRecImport));
- IfFailGo(pMiniMdImport->getPublicKeyOrTokenOfAssemblyRef(pRecImport, (const BYTE **)&pbTmp, &cbTmp));
- hr = CLDB_E_RECORD_NOTFOUND;
- if (m_fDupCheck)
- {
- LPCSTR szAssemblyRefName;
- LPCSTR szAssemblyRefLocale;
- IfFailGo(pMiniMdImport->getNameOfAssemblyRef(pRecImport, &szAssemblyRefName));
- IfFailGo(pMiniMdImport->getLocaleOfAssemblyRef(pRecImport, &szAssemblyRefLocale));
- hr = ImportHelper::FindAssemblyRef(
- pMiniMdEmit,
- szAssemblyRefName,
- szAssemblyRefLocale,
- pbTmp,
- cbTmp,
- pRecImport->GetMajorVersion(),
- pRecImport->GetMinorVersion(),
- pRecImport->GetBuildNumber(),
- pRecImport->GetRevisionNumber(),
- pRecImport->GetFlags(),
- &arEmit);
- }
- if (hr == S_OK)
- {
- // Yes, it does
- bDuplicate = true;
-
- // <TODO>@FUTURE: more verification?</TODO>
- }
- else if (hr == CLDB_E_RECORD_NOTFOUND)
- {
- // No, it doesn't. Copy it over.
- bDuplicate = false;
- IfFailGo(pMiniMdEmit->AddAssemblyRefRecord(&pRecEmit, &iRecord));
- arEmit = TokenFromRid(iRecord, mdtAssemblyRef);
-
- pRecEmit->Copy(pRecImport);
-
- IfFailGo(pMiniMdImport->getPublicKeyOrTokenOfAssemblyRef(pRecImport, (const BYTE **)&pbTmp, &cbTmp));
- IfFailGo(pMiniMdEmit->PutBlob(TBL_AssemblyRef, AssemblyRefRec::COL_PublicKeyOrToken,
- pRecEmit, pbTmp, cbTmp));
-
- IfFailGo(pMiniMdImport->getNameOfAssemblyRef(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_AssemblyRef, AssemblyRefRec::COL_Name,
- pRecEmit, szTmp));
-
- IfFailGo(pMiniMdImport->getLocaleOfAssemblyRef(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_AssemblyRef, AssemblyRefRec::COL_Locale,
- pRecEmit, szTmp));
-
- IfFailGo(pMiniMdImport->getHashValueOfAssemblyRef(pRecImport, (const BYTE **)&pbTmp, &cbTmp));
- IfFailGo(pMiniMdEmit->PutBlob(TBL_AssemblyRef, AssemblyRefRec::COL_HashValue,
- pRecEmit, pbTmp, cbTmp));
-
- }
- else
- IfFailGo(hr);
-
- // record the token movement.
- IfFailGo(pCurTkMap->InsertNotFound(
- TokenFromRid(i, mdtAssemblyRef),
- bDuplicate,
- arEmit,
- &pTokenRec));
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeAssemblyRefs()
-
-
-//*****************************************************************************
-// Merge TypeRef tables also performing TypeRef to TypeDef opitimization. ie.
-// we will not introduce a TypeRef record if we can optimize it to a TypeDef.
-//*****************************************************************************
-HRESULT NEWMERGER::MergeTypeRefs()
-{
- HRESULT hr = NOERROR;
- TypeRefRec *pRecImport = NULL;
- TypeRefRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdTypeRef trEmit;
- bool bDuplicate = false;
- TOKENREC *pTokenRec;
- bool isTypeDef;
-
- mdToken tkResImp;
- mdToken tkResEmit;
- LPCUTF8 szNameImp;
- LPCUTF8 szNamespaceImp;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountTypeRefs();
-
- // loop through all TypeRef
- for (i = 1; i <= iCount; i++)
- {
- // only merge those TypeRefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsTypeRefMarked(TokenFromRid(i, mdtTypeRef)) == false)
- continue;
-
- isTypeDef = false;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetTypeRefRecord(i, &pRecImport));
- tkResImp = pMiniMdImport->getResolutionScopeOfTypeRef(pRecImport);
- IfFailGo(pMiniMdImport->getNamespaceOfTypeRef(pRecImport, &szNamespaceImp));
- IfFailGo(pMiniMdImport->getNameOfTypeRef(pRecImport, &szNameImp));
- if (!IsNilToken(tkResImp))
- {
- IfFailGo(pCurTkMap->Remap(tkResImp, &tkResEmit));
- }
- else
- {
- tkResEmit = tkResImp;
- }
-
- // There are some interesting cases to consider here.
- // 1) If the TypeRef's ResolutionScope is a nil token, or is the MODULEDEFTOKEN (current module),
- // then the TypeRef refers to a type in the current scope, so we should find a corresponding
- // TypeDef in the output scope. If we find the TypeDef, we'll remap this TypeRef token
- // to that TypeDef token.
- // If we don't find that TypeDef, or if "TypeRef to TypeDef" optimization is turned off, we'll
- // create the TypeRef in the output scope.
- // 2) If the TypeRef's ResolutionScope has been resolved to a TypeDef, then this TypeRef was part
- // of a nested type definition. In that case, we'd better find a corresponding TypeDef
- // or we have an error.
- if (IsNilToken(tkResEmit) || tkResEmit == MODULEDEFTOKEN || TypeFromToken(tkResEmit) == mdtTypeDef)
- {
- hr = ImportHelper::FindTypeDefByName(
- pMiniMdEmit,
- szNamespaceImp,
- szNameImp,
- (TypeFromToken(tkResEmit) == mdtTypeDef) ? tkResEmit : mdTokenNil,
- &trEmit);
- if (hr == S_OK)
- {
- isTypeDef = true;
-
- // it really does not matter if we set the duplicate to true or false.
- bDuplicate = true;
- }
- }
-
- // If the ResolutionScope was merged as a TypeDef, and this token wasn't found as TypeDef, send the error.
- if (TypeFromToken(tkResEmit) == mdtTypeDef && !isTypeDef)
- {
- // Send the error notification. Use the "continuable error" callback, but even if linker says it is
- // ok, don't continue.
- CheckContinuableErrorEx(META_E_TYPEDEF_MISSING, pImportData, TokenFromRid(i, mdtTypeRef));
- IfFailGo(META_E_TYPEDEF_MISSING);
- }
-
- // If this TypeRef cannot be optmized to a TypeDef or the Ref to Def optimization is turned off, do the following.
- if (!isTypeDef || !((m_optimizeRefToDef & MDTypeRefToDef) == MDTypeRefToDef))
- {
- // does this TypeRef already exist in the emit scope?
- if ( m_fDupCheck && ImportHelper::FindTypeRefByName(
- pMiniMdEmit,
- tkResEmit,
- szNamespaceImp,
- szNameImp,
- &trEmit) == S_OK )
- {
- // Yes, it does
- bDuplicate = true;
- }
- else
- {
- // No, it doesn't. Copy it over.
- bDuplicate = false;
- IfFailGo(pMiniMdEmit->AddTypeRefRecord(&pRecEmit, (RID*)&trEmit));
- trEmit = TokenFromRid(trEmit, mdtTypeRef);
-
- // Set ResolutionScope. tkResEmit has already been re-mapped.
- IfFailGo(pMiniMdEmit->PutToken(TBL_TypeRef, TypeRefRec::COL_ResolutionScope,
- pRecEmit, tkResEmit));
-
- // Set Name.
- IfFailGo(pMiniMdEmit->PutString(TBL_TypeRef, TypeRefRec::COL_Name,
- pRecEmit, szNameImp));
- IfFailGo(pMiniMdEmit->AddNamedItemToHash(TBL_TypeRef, trEmit, szNameImp, 0));
-
- // Set Namespace.
- IfFailGo(pMiniMdEmit->PutString(TBL_TypeRef, TypeRefRec::COL_Namespace,
- pRecEmit, szNamespaceImp));
- }
- }
-
- // record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(
- TokenFromRid(i, mdtTypeRef),
- bDuplicate,
- trEmit,
- &pTokenRec) );
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeTypeRefs()
-
-
-//*****************************************************************************
-// copy over the remaining information of partially merged TypeDef records. Right now only
-// extends field is delayed to here. The reason that we delay extends field is because we want
-// to optimize TypeRef to TypeDef if possible.
-//*****************************************************************************
-HRESULT NEWMERGER::CompleteMergeTypeDefs()
-{
- HRESULT hr = NOERROR;
- TypeDefRec *pRecImport = NULL;
- TypeDefRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- TOKENREC *pTokenRec;
- mdToken tkExtendsImp;
- mdToken tkExtendsEmit;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- iCount = pMiniMdImport->getCountTypeDefs();
-
- // Merge the typedefs
- for (i = 1; i <= iCount; i++)
- {
- // only merge those TypeDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsTypeDefMarked(TokenFromRid(i, mdtTypeDef)) == false)
- continue;
-
- if ( !pCurTkMap->Find(TokenFromRid(i, mdtTypeDef), &pTokenRec) )
- {
- _ASSERTE( !"bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
-
- if (pTokenRec->m_isDuplicate == false)
- {
- // get the extends token from the import
- IfFailGo(pMiniMdImport->GetTypeDefRecord(i, &pRecImport));
- tkExtendsImp = pMiniMdImport->getExtendsOfTypeDef(pRecImport);
-
- // map the extends token to an merged token
- IfFailGo( pCurTkMap->Remap(tkExtendsImp, &tkExtendsEmit) );
-
- // set the extends to the merged TypeDef records.
- IfFailGo(pMiniMdEmit->GetTypeDefRecord(RidFromToken(pTokenRec->m_tkTo), &pRecEmit));
- IfFailGo(pMiniMdEmit->PutToken(TBL_TypeDef, TypeDefRec::COL_Extends, pRecEmit, tkExtendsEmit));
- }
- else
- {
- // <TODO>@FUTURE: we can check to make sure the import extends maps to the one that is set to the emit scope.
- // Otherwise, it is a error to report to linker.</TODO>
- }
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CompleteMergeTypeDefs()
-
-
-//*****************************************************************************
-// merging TypeSpecs
-//*****************************************************************************
-HRESULT NEWMERGER::MergeTypeSpecs()
-{
- HRESULT hr = NOERROR;
- TypeSpecRec *pRecImport = NULL;
- TypeSpecRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- TOKENREC *pTokenRec;
- mdTypeSpec tsImp;
- mdTypeSpec tsEmit;
- bool fDuplicate;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- iCount = pMiniMdImport->getCountTypeSpecs();
-
- // loop through all TypeSpec
- for (i = 1; i <= iCount; i++)
- {
- // only merge those TypeSpecs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsTypeSpecMarked(TokenFromRid(i, mdtTypeSpec)) == false)
- continue;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetTypeSpecRecord(i, &pRecImport));
- IfFailGo(pMiniMdImport->getSignatureOfTypeSpec(pRecImport, &pbSig, &cbSig));
-
- // convert tokens contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInFieldSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly information.
- pMiniMdImport, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
-
- hr = CLDB_E_RECORD_NOTFOUND;
- if (m_fDupCheck)
- hr = ImportHelper::FindTypeSpec(
- pMiniMdEmit,
- (PCOR_SIGNATURE) qbSig.Ptr(),
- cbEmit,
- &tsEmit );
-
- if ( hr == S_OK )
- {
- // find a duplicate
- fDuplicate = true;
- }
- else
- {
- // copy over
- fDuplicate = false;
- IfFailGo(pMiniMdEmit->AddTypeSpecRecord(&pRecEmit, (ULONG *)&tsEmit));
- tsEmit = TokenFromRid(tsEmit, mdtTypeSpec);
- IfFailGo( pMiniMdEmit->PutBlob(
- TBL_TypeSpec,
- TypeSpecRec::COL_Signature,
- pRecEmit,
- (PCOR_SIGNATURE)qbSig.Ptr(),
- cbEmit));
- }
- tsImp = TokenFromRid(i, mdtTypeSpec);
-
- // Record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(tsImp, fDuplicate, tsEmit, &pTokenRec) );
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeTypeSpecs()
-
-
-//*****************************************************************************
-// merging Children of TypeDefs. This includes field, method, parameter, property, event
-//*****************************************************************************
-HRESULT NEWMERGER::MergeTypeDefChildren()
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdTypeDef tdEmit;
- mdTypeDef tdImport;
- TOKENREC *pTokenRec;
-
-#if _DEBUG
- TypeDefRec *pRecImport = NULL;
- LPCUTF8 szNameImp;
- LPCUTF8 szNamespaceImp;
-#endif // _DEBUG
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountTypeDefs();
-
- // loop through all TypeDef again to merge/copy Methods, fields, events, and properties
- //
- for (i = 1; i <= iCount; i++)
- {
- // only merge those TypeDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsTypeDefMarked(TokenFromRid(i, mdtTypeDef)) == false)
- continue;
-
-#if _DEBUG
- IfFailGo(pMiniMdImport->GetTypeDefRecord(i, &pRecImport));
- IfFailGo(pMiniMdImport->getNameOfTypeDef(pRecImport, &szNameImp));
- IfFailGo(pMiniMdImport->getNamespaceOfTypeDef(pRecImport, &szNamespaceImp));
-#endif // _DEBUG
-
- // check to see if the typedef is duplicate or not
- tdImport = TokenFromRid(i, mdtTypeDef);
- if ( pCurTkMap->Find( tdImport, &pTokenRec) == false)
- {
- _ASSERTE( !"bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
- tdEmit = pTokenRec->m_tkTo;
- if (pTokenRec->m_isDuplicate == false)
- {
- // now move all of the children records over
- IfFailGo( CopyMethods(pImportData, tdImport, tdEmit) );
- IfFailGo( CopyFields(pImportData, tdImport, tdEmit) );
-
- IfFailGo( CopyEvents(pImportData, tdImport, tdEmit) );
-
- // Property has dependency on events
- IfFailGo( CopyProperties(pImportData, tdImport, tdEmit) );
-
- // Generic Params.
- IfFailGo( CopyGenericParams(pImportData, tdImport, tdEmit) );
- }
- else
- {
- // verify the children records
- IfFailGo( VerifyMethods(pImportData, tdImport, tdEmit) );
- IfFailGo( VerifyFields(pImportData, tdImport, tdEmit) );
- IfFailGo( VerifyEvents(pImportData, tdImport, tdEmit) );
-
- // property has dependency on events
- IfFailGo( VerifyProperties(pImportData, tdImport, tdEmit) );
-
- IfFailGo( VerifyGenericParams(pImportData, tdImport, tdEmit) );
- }
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeTypeDefChildren()
-
-
-//*******************************************************************************
-// Helper to copy an Method record
-//*******************************************************************************
-HRESULT NEWMERGER::CopyMethod(
- MergeImportData *pImportData, // [IN] import scope
- MethodRec *pRecImp, // [IN] the record to import
- MethodRec *pRecEmit) // [IN] the emit record to fill
-{
- HRESULT hr;
- CMiniMdRW *pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- LPCUTF8 szName;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
- MDTOKENMAP *pCurTkMap;
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // copy over the fix part of the record
- pRecEmit->Copy(pRecImp);
-
- // copy over the name
- IfFailGo(pMiniMdImp->getNameOfMethod(pRecImp, &szName));
- IfFailGo(pMiniMdEmit->PutString(TBL_Method, MethodRec::COL_Name, pRecEmit, szName));
-
- // copy over the signature
- IfFailGo(pMiniMdImp->getSignatureOfMethod(pRecImp, &pbSig, &cbSig));
-
- // convert rid contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly scope information.
- pMiniMdImp, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
-
- IfFailGo(pMiniMdEmit->PutBlob(TBL_Method, MethodRec::COL_Signature, pRecEmit, qbSig.Ptr(), cbEmit));
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyMethod()
-
-
-//*******************************************************************************
-// Helper to copy an field record
-//*******************************************************************************
-HRESULT NEWMERGER::CopyField(
- MergeImportData *pImportData, // [IN] import scope
- FieldRec *pRecImp, // [IN] the record to import
- FieldRec *pRecEmit) // [IN] the emit record to fill
-{
- HRESULT hr;
- CMiniMdRW *pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- LPCUTF8 szName;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
- MDTOKENMAP *pCurTkMap;
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // copy over the fix part of the record
- pRecEmit->SetFlags(pRecImp->GetFlags());
-
- // copy over the name
- IfFailGo(pMiniMdImp->getNameOfField(pRecImp, &szName));
- IfFailGo(pMiniMdEmit->PutString(TBL_Field, FieldRec::COL_Name, pRecEmit, szName));
-
- // copy over the signature
- IfFailGo(pMiniMdImp->getSignatureOfField(pRecImp, &pbSig, &cbSig));
-
- // convert rid contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInSig(
- NULL, // Emit assembly scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly scope information.
- pMiniMdImp, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
-
- IfFailGo(pMiniMdEmit->PutBlob(TBL_Field, FieldRec::COL_Signature, pRecEmit, qbSig.Ptr(), cbEmit));
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyField()
-
-//*******************************************************************************
-// Helper to copy an field record
-//*******************************************************************************
-HRESULT NEWMERGER::CopyParam(
- MergeImportData *pImportData, // [IN] import scope
- ParamRec *pRecImp, // [IN] the record to import
- ParamRec *pRecEmit) // [IN] the emit record to fill
-{
- HRESULT hr;
- CMiniMdRW *pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- LPCUTF8 szName;
- MDTOKENMAP *pCurTkMap;
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // copy over the fix part of the record
- pRecEmit->Copy(pRecImp);
-
- // copy over the name
- IfFailGo(pMiniMdImp->getNameOfParam(pRecImp, &szName));
- IfFailGo(pMiniMdEmit->PutString(TBL_Param, ParamRec::COL_Name, pRecEmit, szName));
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyParam()
-
-//*******************************************************************************
-// Helper to copy an Event record
-//*******************************************************************************
-HRESULT NEWMERGER::CopyEvent(
- MergeImportData *pImportData, // [IN] import scope
- EventRec *pRecImp, // [IN] the record to import
- EventRec *pRecEmit) // [IN] the emit record to fill
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- mdToken tkEventTypeImp;
- mdToken tkEventTypeEmit; // could be TypeDef or TypeRef
- LPCUTF8 szName;
- MDTOKENMAP *pCurTkMap;
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- pRecEmit->SetEventFlags(pRecImp->GetEventFlags());
-
- //move over the event name
- IfFailGo(pMiniMdImp->getNameOfEvent(pRecImp, &szName));
- IfFailGo( pMiniMdEmit->PutString(TBL_Event, EventRec::COL_Name, pRecEmit, szName) );
-
- // move over the EventType
- tkEventTypeImp = pMiniMdImp->getEventTypeOfEvent(pRecImp);
- if ( !IsNilToken(tkEventTypeImp) )
- {
- IfFailGo( pCurTkMap->Remap(tkEventTypeImp, &tkEventTypeEmit) );
- IfFailGo(pMiniMdEmit->PutToken(TBL_Event, EventRec::COL_EventType, pRecEmit, tkEventTypeEmit));
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyEvent()
-
-
-//*******************************************************************************
-// Helper to copy a property record
-//*******************************************************************************
-HRESULT NEWMERGER::CopyProperty(
- MergeImportData *pImportData, // [IN] import scope
- PropertyRec *pRecImp, // [IN] the record to import
- PropertyRec *pRecEmit) // [IN] the emit record to fill
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- LPCUTF8 szName;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
- MDTOKENMAP *pCurTkMap;
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // move over the flag value
- pRecEmit->SetPropFlags(pRecImp->GetPropFlags());
-
- //move over the property name
- IfFailGo(pMiniMdImp->getNameOfProperty(pRecImp, &szName));
- IfFailGo( pMiniMdEmit->PutString(TBL_Property, PropertyRec::COL_Name, pRecEmit, szName) );
-
- // move over the type of the property
- IfFailGo(pMiniMdImp->getTypeOfProperty(pRecImp, &pbSig, &cbSig));
-
- // convert rid contained in signature to new scope
- IfFailGo( ImportHelper::MergeUpdateTokenInSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly scope information.
- pMiniMdImp, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit) ); // number of bytes write to cbEmit
-
- IfFailGo(pMiniMdEmit->PutBlob(TBL_Property, PropertyRec::COL_Type, pRecEmit, qbSig.Ptr(), cbEmit));
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyProperty()
-
-
-//*****************************************************************************
-// Copy MethodSemantics for an event or a property
-//*****************************************************************************
-HRESULT NEWMERGER::CopyMethodSemantics(
- MergeImportData *pImportData,
- mdToken tkImport, // Event or property in the import scope
- mdToken tkEmit) // corresponding event or property in the emitting scope
-{
- HRESULT hr = NOERROR;
- MethodSemanticsRec *pRecImport = NULL;
- MethodSemanticsRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- ULONG i;
- ULONG msEmit; // MethodSemantics are just index not tokens
- mdToken tkMethodImp;
- mdToken tkMethodEmit;
- MDTOKENMAP *pCurTkMap;
- HENUMInternal hEnum;
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // copy over the associates
- IfFailGo( pMiniMdImport->FindMethodSemanticsHelper(tkImport, &hEnum) );
- while (HENUMInternal::EnumNext(&hEnum, (mdToken *) &i))
- {
- IfFailGo(pMiniMdImport->GetMethodSemanticsRecord(i, &pRecImport));
- IfFailGo(pMiniMdEmit->AddMethodSemanticsRecord(&pRecEmit, &msEmit));
- pRecEmit->SetSemantic(pRecImport->GetSemantic());
-
- // set the MethodSemantics
- tkMethodImp = pMiniMdImport->getMethodOfMethodSemantics(pRecImport);
- IfFailGo( pCurTkMap->Remap(tkMethodImp, &tkMethodEmit) );
- IfFailGo( pMiniMdEmit->PutToken(TBL_MethodSemantics, MethodSemanticsRec::COL_Method, pRecEmit, tkMethodEmit));
-
- // set the associate
- _ASSERTE( pMiniMdImport->getAssociationOfMethodSemantics(pRecImport) == tkImport );
- IfFailGo( pMiniMdEmit->PutToken(TBL_MethodSemantics, MethodSemanticsRec::COL_Association, pRecEmit, tkEmit));
-
- // no need to record the movement since it is not a token
- IfFailGo( pMiniMdEmit->AddMethodSemanticsToHash(msEmit) );
- }
-ErrExit:
- HENUMInternal::ClearEnum(&hEnum);
- return hr;
-} // HRESULT NEWMERGER::CopyMethodSemantics()
-
-
-//*****************************************************************************
-// Copy Methods given a TypeDef
-//*****************************************************************************
-HRESULT NEWMERGER::CopyMethods(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- MethodRec *pRecImport = NULL;
- MethodRec *pRecEmit = NULL;
- TypeDefRec *pTypeDefRec;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG ridStart, ridEnd;
- ULONG i;
- mdMethodDef mdEmit;
- mdMethodDef mdImp;
- TOKENREC *pTokenRec;
- MDTOKENMAP *pCurTkMap;
-
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- mdCustomAttribute tkCA;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- IfFailGo(pMiniMdImport->GetTypeDefRecord(RidFromToken(tdImport), &pTypeDefRec));
- ridStart = pMiniMdImport->getMethodListOfTypeDef(pTypeDefRec);
- IfFailGo(pMiniMdImport->getEndMethodListOfTypeDef(RidFromToken(tdImport), &ridEnd));
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- // make sure we didn't count the methods yet
- _ASSERTE(pMTD->m_cMethods == 0);
-
- // loop through all Methods
- for (i = ridStart; i < ridEnd; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetMethodRid(i, (ULONG *)&mdImp));
-
- // only merge those MethodDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsMethodMarked(TokenFromRid(mdImp, mdtMethodDef)) == false)
- continue;
-
- IfFailGo(pMiniMdImport->GetMethodRecord(mdImp, &pRecImport));
- IfFailGo(pMiniMdEmit->AddMethodRecord(&pRecEmit, (RID *)&mdEmit));
-
- // copy the method content over
- IfFailGo( CopyMethod(pImportData, pRecImport, pRecEmit) );
-
- IfFailGo( pMiniMdEmit->AddMethodToTypeDef(RidFromToken(tdEmit), mdEmit));
-
- // record the token movement
- mdImp = TokenFromRid(mdImp, mdtMethodDef);
- mdEmit = TokenFromRid(mdEmit, mdtMethodDef);
- IfFailGo( pMiniMdEmit->AddMemberDefToHash(
- mdEmit,
- tdEmit) );
-
- IfFailGo( pCurTkMap->InsertNotFound(mdImp, false, mdEmit, &pTokenRec) );
-
- // copy over the children
- IfFailGo( CopyParams(pImportData, mdImp, mdEmit) );
- IfFailGo( CopyGenericParams(pImportData, mdImp, mdEmit) );
-
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- mdImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
-
- if (!bSuppressMergeCheck) {
- pMTD->m_cMethods++;
- }
- }
-
- // make sure we don't count any methods if merge check is suppressed on the type
- _ASSERTE(pMTD->m_cMethods == 0 || !pMTD->m_bSuppressMergeCheck);
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyMethods()
-
-
-//*****************************************************************************
-// Copy Fields given a TypeDef
-//*****************************************************************************
-HRESULT NEWMERGER::CopyFields(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- FieldRec *pRecImport = NULL;
- FieldRec *pRecEmit = NULL;
- TypeDefRec *pTypeDefRec;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG ridStart, ridEnd;
- ULONG i;
- mdFieldDef fdEmit;
- mdFieldDef fdImp;
- bool bDuplicate;
- TOKENREC *pTokenRec;
- PCCOR_SIGNATURE pvSigBlob;
- ULONG cbSigBlob;
- MDTOKENMAP *pCurTkMap;
-
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- mdCustomAttribute tkCA;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- IfFailGo(pMiniMdImport->GetTypeDefRecord(RidFromToken(tdImport), &pTypeDefRec));
- ridStart = pMiniMdImport->getFieldListOfTypeDef(pTypeDefRec);
- IfFailGo(pMiniMdImport->getEndFieldListOfTypeDef(RidFromToken(tdImport), &ridEnd));
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- // make sure we didn't count the methods yet
- _ASSERTE(pMTD->m_cFields == 0);
-
- // loop through all FieldDef of a TypeDef
- for (i = ridStart; i < ridEnd; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetFieldRid(i, (ULONG *)&fdImp));
-
- // only merge those FieldDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(TokenFromRid(fdImp, mdtFieldDef)) == false)
- continue;
-
-
- IfFailGo(pMiniMdImport->GetFieldRecord(fdImp, &pRecImport));
- bDuplicate = false;
- IfFailGo(pMiniMdEmit->AddFieldRecord(&pRecEmit, (RID *)&fdEmit));
-
- // copy the field content over
- IfFailGo( CopyField(pImportData, pRecImport, pRecEmit) );
-
- IfFailGo( pMiniMdEmit->AddFieldToTypeDef(RidFromToken(tdEmit), fdEmit));
-
- // record the token movement
- fdImp = TokenFromRid(fdImp, mdtFieldDef);
- fdEmit = TokenFromRid(fdEmit, mdtFieldDef);
- IfFailGo(pMiniMdEmit->getSignatureOfField(pRecEmit, &pvSigBlob, &cbSigBlob));
- IfFailGo( pMiniMdEmit->AddMemberDefToHash(
- fdEmit,
- tdEmit) );
-
- IfFailGo( pCurTkMap->InsertNotFound(fdImp, false, fdEmit, &pTokenRec) );
-
- // count the number of fields that didn't suppress merge check
- // non-static fields doesn't inherite the suppress merge check attribute from the type
- bSuppressMergeCheck =
- (IsFdStatic(pRecEmit->GetFlags()) && pMTD->m_bSuppressMergeCheck) ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- fdImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (!bSuppressMergeCheck) {
- pMTD->m_cFields++;
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyFields()
-
-
-//*****************************************************************************
-// Copy Events given a TypeDef
-//*****************************************************************************
-HRESULT NEWMERGER::CopyEvents(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- RID ridEventMap;
- EventMapRec *pEventMapRec;
- EventRec *pRecImport;
- EventRec *pRecEmit;
- ULONG ridStart;
- ULONG ridEnd;
- ULONG i;
- mdEvent evImp;
- mdEvent evEmit;
- TOKENREC *pTokenRec;
- ULONG iEventMap;
- EventMapRec *pEventMap;
- MDTOKENMAP *pCurTkMap;
-
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- mdCustomAttribute tkCA;
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- // make sure we didn't count the events yet
- _ASSERTE(pMTD->m_cEvents == 0);
-
- IfFailGo(pMiniMdImport->FindEventMapFor(RidFromToken(tdImport), &ridEventMap));
- if (!InvalidRid(ridEventMap))
- {
- IfFailGo(pMiniMdImport->GetEventMapRecord(ridEventMap, &pEventMapRec));
- ridStart = pMiniMdImport->getEventListOfEventMap(pEventMapRec);
- IfFailGo(pMiniMdImport->getEndEventListOfEventMap(ridEventMap, &ridEnd));
-
- if (ridEnd > ridStart)
- {
- // If there is any event, create the eventmap record in the emit scope
- // Create new record.
- IfFailGo(pMiniMdEmit->AddEventMapRecord(&pEventMap, &iEventMap));
-
- // Set parent.
- IfFailGo(pMiniMdEmit->PutToken(TBL_EventMap, EventMapRec::COL_Parent, pEventMap, tdEmit));
- }
-
- for (i = ridStart; i < ridEnd; i++)
- {
- // get the real event rid
- IfFailGo(pMiniMdImport->GetEventRid(i, (ULONG *)&evImp));
-
- // only merge those Events that are marked
- if ( pMiniMdImport->GetFilterTable()->IsEventMarked(TokenFromRid(evImp, mdtEvent)) == false)
- continue;
-
- IfFailGo(pMiniMdImport->GetEventRecord(evImp, &pRecImport));
- IfFailGo(pMiniMdEmit->AddEventRecord(&pRecEmit, (RID *)&evEmit));
-
- // copy the event record over
- IfFailGo( CopyEvent(pImportData, pRecImport, pRecEmit) );
-
- // Add Event to the EventMap.
- IfFailGo( pMiniMdEmit->AddEventToEventMap(iEventMap, evEmit) );
-
- // record the token movement
- evImp = TokenFromRid(evImp, mdtEvent);
- evEmit = TokenFromRid(evEmit, mdtEvent);
-
- IfFailGo( pCurTkMap->InsertNotFound(evImp, false, evEmit, &pTokenRec) );
-
- // copy over the method semantics
- IfFailGo( CopyMethodSemantics(pImportData, evImp, evEmit) );
-
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- evImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (!bSuppressMergeCheck) {
- pMTD->m_cEvents++;
- }
- }
- }
-
- // make sure we don't count any events if merge check is suppressed on the type
- _ASSERTE(pMTD->m_cEvents == 0 || !pMTD->m_bSuppressMergeCheck);
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyEvents()
-
-
-//*****************************************************************************
-// Copy Properties given a TypeDef
-//*****************************************************************************
-HRESULT NEWMERGER::CopyProperties(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- RID ridPropertyMap;
- PropertyMapRec *pPropertyMapRec;
- PropertyRec *pRecImport;
- PropertyRec *pRecEmit;
- ULONG ridStart;
- ULONG ridEnd;
- ULONG i;
- mdProperty prImp;
- mdProperty prEmit;
- TOKENREC *pTokenRec;
- ULONG iPropertyMap;
- PropertyMapRec *pPropertyMap;
- MDTOKENMAP *pCurTkMap;
-
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- mdCustomAttribute tkCA;
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- // make sure we didn't count the properties yet
- _ASSERTE(pMTD->m_cProperties == 0);
-
- IfFailGo(pMiniMdImport->FindPropertyMapFor(RidFromToken(tdImport), &ridPropertyMap));
- if (!InvalidRid(ridPropertyMap))
- {
- IfFailGo(pMiniMdImport->GetPropertyMapRecord(ridPropertyMap, &pPropertyMapRec));
- ridStart = pMiniMdImport->getPropertyListOfPropertyMap(pPropertyMapRec);
- IfFailGo(pMiniMdImport->getEndPropertyListOfPropertyMap(ridPropertyMap, &ridEnd));
-
- if (ridEnd > ridStart)
- {
- // If there is any event, create the PropertyMap record in the emit scope
- // Create new record.
- IfFailGo(pMiniMdEmit->AddPropertyMapRecord(&pPropertyMap, &iPropertyMap));
-
- // Set parent.
- IfFailGo(pMiniMdEmit->PutToken(TBL_PropertyMap, PropertyMapRec::COL_Parent, pPropertyMap, tdEmit));
- }
-
- for (i = ridStart; i < ridEnd; i++)
- {
- // get the property rid
- IfFailGo(pMiniMdImport->GetPropertyRid(i, (ULONG *)&prImp));
-
- // only merge those Properties that are marked
- if ( pMiniMdImport->GetFilterTable()->IsPropertyMarked(TokenFromRid(prImp, mdtProperty)) == false)
- continue;
-
-
- IfFailGo(pMiniMdImport->GetPropertyRecord(prImp, &pRecImport));
- IfFailGo(pMiniMdEmit->AddPropertyRecord(&pRecEmit, (RID *)&prEmit));
-
- // copy the property record over
- IfFailGo( CopyProperty(pImportData, pRecImport, pRecEmit) );
-
- // Add Property to the PropertyMap.
- IfFailGo( pMiniMdEmit->AddPropertyToPropertyMap(iPropertyMap, prEmit) );
-
- // record the token movement
- prImp = TokenFromRid(prImp, mdtProperty);
- prEmit = TokenFromRid(prEmit, mdtProperty);
-
- IfFailGo( pCurTkMap->InsertNotFound(prImp, false, prEmit, &pTokenRec) );
-
- // copy over the method semantics
- IfFailGo( CopyMethodSemantics(pImportData, prImp, prEmit) );
-
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- prImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (!bSuppressMergeCheck) {
- pMTD->m_cProperties++;
- }
- }
- }
-
- // make sure we don't count any properties if merge check is suppressed on the type
- _ASSERTE(pMTD->m_cProperties == 0 || !pMTD->m_bSuppressMergeCheck);
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyProperties()
-
-
-//*****************************************************************************
-// Copy Parameters given a TypeDef
-//*****************************************************************************
-HRESULT NEWMERGER::CopyParams(
- MergeImportData *pImportData,
- mdMethodDef mdImport,
- mdMethodDef mdEmit)
-{
- HRESULT hr = NOERROR;
- ParamRec *pRecImport = NULL;
- ParamRec *pRecEmit = NULL;
- MethodRec *pMethodRec;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG ridStart, ridEnd;
- ULONG i;
- mdParamDef pdEmit;
- mdParamDef pdImp;
- TOKENREC *pTokenRec;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
-
- IfFailGo(pMiniMdImport->GetMethodRecord(RidFromToken(mdImport), &pMethodRec));
- ridStart = pMiniMdImport->getParamListOfMethod(pMethodRec);
- IfFailGo(pMiniMdImport->getEndParamListOfMethod(RidFromToken(mdImport), &ridEnd));
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // loop through all InterfaceImpl
- for (i = ridStart; i < ridEnd; i++)
- {
- // Get the param rid
- IfFailGo(pMiniMdImport->GetParamRid(i, (ULONG *)&pdImp));
-
- // only merge those Params that are marked
- if ( pMiniMdImport->GetFilterTable()->IsParamMarked(TokenFromRid(pdImp, mdtParamDef)) == false)
- continue;
-
-
- IfFailGo(pMiniMdImport->GetParamRecord(pdImp, &pRecImport));
- IfFailGo(pMiniMdEmit->AddParamRecord(&pRecEmit, (RID *)&pdEmit));
-
- // copy the Parameter record over
- IfFailGo( CopyParam(pImportData, pRecImport, pRecEmit) );
-
- // warning!! warning!!
- // We cannot add paramRec to method list until it is fully set.
- // AddParamToMethod will use the ulSequence in the record
- IfFailGo( pMiniMdEmit->AddParamToMethod(RidFromToken(mdEmit), pdEmit));
-
- // record the token movement
- pdImp = TokenFromRid(pdImp, mdtParamDef);
- pdEmit = TokenFromRid(pdEmit, mdtParamDef);
-
- IfFailGo( pCurTkMap->InsertNotFound(pdImp, false, pdEmit, &pTokenRec) );
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyParams()
-
-
-//*****************************************************************************
-// Copy GenericParams given a TypeDef
-//*****************************************************************************
-HRESULT NEWMERGER::CopyGenericParams(
- MergeImportData *pImportData,
- mdToken tkImport,
- mdToken tkEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- TOKENREC *pTokenRec;
- GenericParamRec *pRecImport = NULL;
- GenericParamRec *pRecEmit = NULL;
- MDTOKENMAP *pCurTkMap;
- HENUMInternal hEnum;
- mdGenericParam gpImport;
- mdGenericParam gpEmit;
- LPCSTR szGenericParamName;
-
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pMiniMdEmit = GetMiniMdEmit();
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- IfFailGo( pMiniMdImport->FindGenericParamHelper(tkImport, &hEnum) );
-
- while (HENUMInternal::EnumNext(&hEnum, (mdToken *) &gpImport))
- {
- // Get the import GenericParam record
- _ASSERTE(TypeFromToken(gpImport) == mdtGenericParam);
- IfFailGo(pMiniMdImport->GetGenericParamRecord(RidFromToken(gpImport), &pRecImport));
-
- // Create new emit record.
- IfFailGo(pMiniMdEmit->AddGenericParamRecord(&pRecEmit, (RID *)&gpEmit));
-
- // copy the GenericParam content
- pRecEmit->SetNumber( pRecImport->GetNumber());
- pRecEmit->SetFlags( pRecImport->GetFlags());
-
- IfFailGo( pMiniMdEmit->PutToken(TBL_GenericParam, GenericParamRec::COL_Owner, pRecEmit, tkEmit));
-
- IfFailGo(pMiniMdImport->getNameOfGenericParam(pRecImport, &szGenericParamName));
- IfFailGo( pMiniMdEmit->PutString(TBL_GenericParam, GenericParamRec::COL_Name, pRecEmit, szGenericParamName));
-
- // record the token movement
- gpImport = TokenFromRid(gpImport, mdtGenericParam);
- gpEmit = TokenFromRid(gpEmit, mdtGenericParam);
-
- IfFailGo( pCurTkMap->InsertNotFound(gpImport, false, gpEmit, &pTokenRec) );
-
- // copy over any constraints
- IfFailGo( CopyGenericParamConstraints(pImportData, gpImport, gpEmit) );
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyGenericParams()
-
-
-//*****************************************************************************
-// Copy GenericParamConstraints given a GenericParam
-//*****************************************************************************
-HRESULT NEWMERGER::CopyGenericParamConstraints(
- MergeImportData *pImportData,
- mdGenericParamConstraint tkImport,
- mdGenericParamConstraint tkEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- TOKENREC *pTokenRec;
- GenericParamConstraintRec *pRecImport = NULL;
- GenericParamConstraintRec *pRecEmit = NULL;
- MDTOKENMAP *pCurTkMap;
- HENUMInternal hEnum;
- mdGenericParamConstraint gpImport;
- mdGenericParamConstraint gpEmit;
- mdToken tkConstraint;
-
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pMiniMdEmit = GetMiniMdEmit();
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- IfFailGo( pMiniMdImport->FindGenericParamConstraintHelper(tkImport, &hEnum) );
-
- while (HENUMInternal::EnumNext(&hEnum, (mdToken *) &gpImport))
- {
- // Get the import GenericParam record
- _ASSERTE(TypeFromToken(gpImport) == mdtGenericParamConstraint);
- IfFailGo(pMiniMdImport->GetGenericParamConstraintRecord(RidFromToken(gpImport), &pRecImport));
-
- // Translate the constraint before creating new record.
- tkConstraint = pMiniMdImport->getConstraintOfGenericParamConstraint(pRecImport);
- if (pCurTkMap->Find(tkConstraint, &pTokenRec) == false)
- {
- // This should never fire unless the TypeDefs/Refs weren't merged
- // before this code runs.
- _ASSERTE(!"GenericParamConstraint Constraint not found in MERGER::CopyGenericParamConstraints. Bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
- tkConstraint = pTokenRec->m_tkTo;
-
- // Create new emit record.
- IfFailGo(pMiniMdEmit->AddGenericParamConstraintRecord(&pRecEmit, (RID *)&gpEmit));
-
- // copy the GenericParamConstraint content
- IfFailGo( pMiniMdEmit->PutToken(TBL_GenericParamConstraint, GenericParamConstraintRec::COL_Owner, pRecEmit, tkEmit));
-
- IfFailGo( pMiniMdEmit->PutToken(TBL_GenericParamConstraint, GenericParamConstraintRec::COL_Constraint, pRecEmit, tkConstraint));
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyGenericParamConstraints()
-
-
-//*****************************************************************************
-// Verify GenericParams given a TypeDef
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyGenericParams(
- MergeImportData *pImportData,
- mdToken tkImport,
- mdToken tkEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- TOKENREC *pTokenRec;
- MDTOKENMAP *pCurTkMap;
- HENUMInternal hEnumImport; // Enumerator for import scope.
- HENUMInternal hEnumEmit; // Enumerator for emit scope.
- ULONG cImport, cEmit; // Count of import & emit records.
- ULONG i; // Enumerating records in import scope.
- ULONG iEmit; // Tracking records in emit scope.
- mdGenericParam gpImport; // Import scope GenericParam token.
- mdGenericParam gpEmit; // Emit scope GenericParam token.
- GenericParamRec *pRecImport = NULL;
- GenericParamRec *pRecEmit = NULL;
- LPCSTR szNameImport; // Name of param in import scope.
- LPCSTR szNameEmit; // Name of param in emit scope.
-
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pMiniMdEmit = GetMiniMdEmit();
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // Get enumerators for the input and output scopes.
- IfFailGo(pMiniMdImport->FindGenericParamHelper(tkImport, &hEnumImport));
- IfFailGo(pMiniMdEmit->FindGenericParamHelper(tkEmit, &hEnumEmit));
-
- // The counts should be the same.
- IfFailGo(HENUMInternal::GetCount(&hEnumImport, &cImport));
- IfFailGo(HENUMInternal::GetCount(&hEnumEmit, &cEmit));
-
- if (cImport != cEmit)
- {
- CheckContinuableErrorEx(META_E_GENERICPARAM_INCONSISTENT, pImportData, tkImport);
- // If we are here, the linker says this error is OK.
- }
-
- for (i=iEmit=0; i<cImport; ++i)
- {
- // Get the import GenericParam record
- IfFailGo(HENUMInternal::GetElement(&hEnumImport, i, &gpImport));
- _ASSERTE(TypeFromToken(gpImport) == mdtGenericParam);
- IfFailGo(pMiniMdImport->GetGenericParamRecord(RidFromToken(gpImport), &pRecImport));
-
- // Find the emit record. If the import and emit scopes are ordered the same
- // this is easy; otherwise go looking for it.
- // Get the "next" emit record.
- if (iEmit < cEmit)
- {
- IfFailGo(HENUMInternal::GetElement(&hEnumEmit, iEmit, &gpEmit));
- _ASSERTE(TypeFromToken(gpEmit) == mdtGenericParam);
- IfFailGo(pMiniMdEmit->GetGenericParamRecord(RidFromToken(gpEmit), &pRecEmit));
- }
-
- // If the import and emit sequence numbers don't match, go looking.
- // Also, if we would have walked off end of array, go looking.
- if (iEmit >= cEmit || pRecImport->GetNumber() != pRecEmit->GetNumber())
- {
- for (iEmit=0; iEmit<cEmit; ++iEmit)
- {
- IfFailGo( HENUMInternal::GetElement(&hEnumEmit, iEmit, &gpEmit));
- _ASSERTE(TypeFromToken(gpEmit) == mdtGenericParam);
- IfFailGo(pMiniMdEmit->GetGenericParamRecord(RidFromToken(gpEmit), &pRecEmit));
-
- // The one we want?
- if (pRecImport->GetNumber() == pRecEmit->GetNumber())
- break;
- }
- if (iEmit >= cEmit)
- goto Error; // Didn't find it
- }
-
- // Check that these "n'th" GenericParam records match.
-
- // Flags.
- if (pRecImport->GetFlags() != pRecEmit->GetFlags())
- goto Error;
-
- // Name.
- IfFailGo(pMiniMdImport->getNameOfGenericParam(pRecImport, &szNameImport));
- IfFailGo(pMiniMdEmit->getNameOfGenericParam(pRecEmit, &szNameEmit));
- if (strcmp(szNameImport, szNameEmit) != 0)
- goto Error;
-
- // Verify any constraints.
- gpImport = TokenFromRid(gpImport, mdtGenericParam);
- gpEmit = TokenFromRid(gpEmit, mdtGenericParam);
- hr = VerifyGenericParamConstraints(pImportData, gpImport, gpEmit);
-
- if (SUCCEEDED(hr))
- {
- // record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(gpImport, true, gpEmit, &pTokenRec) );
- }
- else
- {
-Error:
- // inconsistent in GenericParams
- hr = S_OK; // discard old error; new error will be returned from CheckContinuableError
- CheckContinuableErrorEx(META_E_GENERICPARAM_INCONSISTENT, pImportData, tkImport);
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyGenericParams()
-
-
-//*****************************************************************************
-// Verify GenericParamConstraints given a GenericParam
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyGenericParamConstraints(
- MergeImportData *pImportData, // The import scope.
- mdGenericParam gpImport, // Import GenericParam.
- mdGenericParam gpEmit) // Emit GenericParam.
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- TOKENREC *pTokenRec;
- HENUMInternal hEnumImport; // Enumerator for import scope.
- HENUMInternal hEnumEmit; // Enumerator for emit scope.
- ULONG cImport, cEmit; // Count of import & emit records.
- ULONG i; // Enumerating records in import scope.
- ULONG iEmit; // Tracking records in emit scope.
- GenericParamConstraintRec *pRecImport = NULL;
- GenericParamConstraintRec *pRecEmit = NULL;
- MDTOKENMAP *pCurTkMap;
- mdToken tkConstraintImport = mdTokenNil;
- mdToken tkConstraintEmit = mdTokenNil;
-
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pMiniMdEmit = GetMiniMdEmit();
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // Get enumerators for the input and output scopes.
- IfFailGo(pMiniMdImport->FindGenericParamConstraintHelper(gpImport, &hEnumImport));
- IfFailGo(pMiniMdEmit->FindGenericParamConstraintHelper(gpEmit, &hEnumEmit));
-
- // The counts should be the same.
- IfFailGo(HENUMInternal::GetCount(&hEnumImport, &cImport));
- IfFailGo(HENUMInternal::GetCount(&hEnumEmit, &cEmit));
-
- if (cImport != cEmit)
- IfFailGo(META_E_GENERICPARAM_INCONSISTENT); // Different numbers of constraints.
-
- for (i=iEmit=0; i<cImport; ++i)
- {
- // Get the import GenericParam record
- IfFailGo( HENUMInternal::GetElement(&hEnumImport, i, &gpImport));
- _ASSERTE(TypeFromToken(gpImport) == mdtGenericParamConstraint);
- IfFailGo(pMiniMdImport->GetGenericParamConstraintRecord(RidFromToken(gpImport), &pRecImport));
-
- // Get the constraint.
- tkConstraintImport = pMiniMdImport->getConstraintOfGenericParamConstraint(pRecImport);
- if (pCurTkMap->Find(tkConstraintImport, &pTokenRec) == false)
- {
- // This should never fire unless the TypeDefs/Refs weren't merged
- // before this code runs.
- _ASSERTE(!"GenericParamConstraint Constraint not found in MERGER::VerifyGenericParamConstraints. Bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
- tkConstraintImport = pTokenRec->m_tkTo;
-
- // Find the emit record. If the import and emit scopes are ordered the same
- // this is easy; otherwise go looking for it.
- // Get the "next" emit record.
- if (iEmit < cEmit)
- {
- IfFailGo( HENUMInternal::GetElement(&hEnumEmit, iEmit, &gpEmit));
- _ASSERTE(TypeFromToken(gpEmit) == mdtGenericParamConstraint);
- IfFailGo(pMiniMdEmit->GetGenericParamConstraintRecord(RidFromToken(gpEmit), &pRecEmit));
- tkConstraintEmit = pMiniMdEmit->getConstraintOfGenericParamConstraint(pRecEmit);
- }
-
- // If the import and emit constraints don't match, go looking.
- if (iEmit >= cEmit || tkConstraintEmit != tkConstraintImport)
- {
- for (iEmit=0; iEmit<cEmit; ++iEmit)
- {
- IfFailGo( HENUMInternal::GetElement(&hEnumEmit, iEmit, &gpEmit));
- _ASSERTE(TypeFromToken(gpEmit) == mdtGenericParamConstraint);
- IfFailGo(pMiniMdEmit->GetGenericParamConstraintRecord(RidFromToken(gpEmit), &pRecEmit));
- tkConstraintEmit = pMiniMdEmit->getConstraintOfGenericParamConstraint(pRecEmit);
-
- // The one we want?
- if (tkConstraintEmit == tkConstraintImport)
- break;
- }
- if (iEmit >= cEmit)
- {
- IfFailGo(META_E_GENERICPARAM_INCONSISTENT); // Didn't find the constraint
- }
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyGenericParamConstraints()
-
-
-//*****************************************************************************
-// Verify Methods
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyMethods(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- MethodRec *pRecImp;
- MethodRec *pRecEmit;
- ULONG ridStart;
- ULONG ridEnd;
- ULONG i;
-
- TypeDefRec *pTypeDefRec;
- LPCUTF8 szName;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
- TOKENREC *pTokenRec;
- mdMethodDef mdImp;
- mdMethodDef mdEmit;
- MDTOKENMAP *pCurTkMap;
-
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- ULONG cImport = 0; // count of non-merge check suppressed methods
- mdCustomAttribute tkCA;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // Get a count of records in the import scope; prepare to enumerate them.
- IfFailGo(pMiniMdImport->GetTypeDefRecord(RidFromToken(tdImport), &pTypeDefRec));
- ridStart = pMiniMdImport->getMethodListOfTypeDef(pTypeDefRec);
- IfFailGo(pMiniMdImport->getEndMethodListOfTypeDef(RidFromToken(tdImport), &ridEnd));
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- // loop through all Methods of the TypeDef
- for (i = ridStart; i < ridEnd; i++)
- {
- IfFailGo(pMiniMdImport->GetMethodRid(i, (ULONG *)&mdImp));
-
- // only verify those Methods that are marked
- if ( pMiniMdImport->GetFilterTable()->IsMethodMarked(TokenFromRid(mdImp, mdtMethodDef)) == false)
- continue;
-
- IfFailGo(pMiniMdImport->GetMethodRecord(mdImp, &pRecImp));
-
- if (m_fDupCheck == FALSE && tdImport == pImportData->m_pRegMetaImport->m_tdModule) // TokenFromRid(1, mdtTypeDef))
- {
- // No dup check. This is the scenario that we only have one import scope. Just copy over the
- // globals.
- goto CopyMethodLabel;
- }
-
- IfFailGo(pMiniMdImport->getNameOfMethod(pRecImp, &szName));
- IfFailGo(pMiniMdImport->getSignatureOfMethod(pRecImp, &pbSig, &cbSig));
-
- mdImp = TokenFromRid(mdImp, mdtMethodDef);
-
- if ( IsMdPrivateScope( pRecImp->GetFlags() ) )
- {
- // Trigger additive merge
- goto CopyMethodLabel;
- }
-
- // convert rid contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly scope information.
- pMiniMdImport, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
-
- hr = ImportHelper::FindMethod(
- pMiniMdEmit,
- tdEmit,
- szName,
- (const COR_SIGNATURE *)qbSig.Ptr(),
- cbEmit,
- &mdEmit);
-
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- mdImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (bSuppressMergeCheck || (tdImport == pImportData->m_pRegMetaImport->m_tdModule))
- {
- // global functions! Make sure that we move over the non-duplicate global function
- // declaration
- //
- if (hr == S_OK)
- {
- // found the duplicate
- IfFailGo( VerifyMethod(pImportData, mdImp, mdEmit) );
- }
- else
- {
-CopyMethodLabel:
- // not a duplicate! Copy over the
- IfFailGo(pMiniMdEmit->AddMethodRecord(&pRecEmit, (RID *)&mdEmit));
-
- // copy the method content over
- IfFailGo( CopyMethod(pImportData, pRecImp, pRecEmit) );
-
- IfFailGo( pMiniMdEmit->AddMethodToTypeDef(RidFromToken(tdEmit), mdEmit));
-
- // record the token movement
- mdEmit = TokenFromRid(mdEmit, mdtMethodDef);
- IfFailGo( pMiniMdEmit->AddMemberDefToHash(
- mdEmit,
- tdEmit) );
-
- mdImp = TokenFromRid(mdImp, mdtMethodDef);
- IfFailGo( pCurTkMap->InsertNotFound(mdImp, false, mdEmit, &pTokenRec) );
-
- // copy over the children
- IfFailGo( CopyParams(pImportData, mdImp, mdEmit) );
- IfFailGo( CopyGenericParams(pImportData, mdImp, mdEmit) );
-
- }
- }
- else
- {
- if (hr == S_OK)
- {
- // Good! We are supposed to find a duplicate
- IfFailGo( VerifyMethod(pImportData, mdImp, mdEmit) );
- }
- else
- {
- // Oops! The typedef is duplicated but the method is not!!
- hr = S_OK; // discard old error; new error will be returned from CheckContinuableError
- CheckContinuableErrorEx(META_E_METHD_NOT_FOUND, pImportData, mdImp);
- }
-
- cImport++;
- }
- }
-
- // The counts should be the same, unless this is <module>
- if (cImport != pMTD->m_cMethods && tdImport != pImportData->m_pRegMetaImport->m_tdModule)
- {
- CheckContinuableErrorEx(META_E_METHOD_COUNTS, pImportData, tdImport);
- // If we are here, the linker says this error is OK.
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyMethods()
-
-
-//*****************************************************************************
-// verify a duplicated method
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyMethod(
- MergeImportData *pImportData,
- mdMethodDef mdImp, // [IN] the emit record to fill
- mdMethodDef mdEmit) // [IN] the record to import
-{
- HRESULT hr;
- MethodRec *pRecImp;
- MethodRec *pRecEmit;
- TOKENREC *pTokenRec;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- IfFailGo( pCurTkMap->InsertNotFound(mdImp, true, mdEmit, &pTokenRec) );
-
- IfFailGo(pMiniMdImport->GetMethodRecord(RidFromToken(mdImp), &pRecImp));
-
- // We need to make sure that the impl flags are propagated .
- // Rules are: if the first method has miForwardRef flag set but the new method does not,
- // we want to disable the miForwardRef flag. If the one found in the emit scope does not have
- // miForwardRef set and the second one doesn't either, we want to make sure that the rest of
- // impl flags are the same.
- //
- if ( !IsMiForwardRef( pRecImp->GetImplFlags() ) )
- {
- IfFailGo(pMiniMdEmit->GetMethodRecord(RidFromToken(mdEmit), &pRecEmit));
- if (!IsMiForwardRef(pRecEmit->GetImplFlags()))
- {
- // make sure the rest of ImplFlags are the same
- if (pRecEmit->GetImplFlags() != pRecImp->GetImplFlags())
- {
- // inconsistent in implflags
- CheckContinuableErrorEx(META_E_METHDIMPL_INCONSISTENT, pImportData, mdImp);
- }
- }
- else
- {
- // propagate the importing ImplFlags
- pRecEmit->SetImplFlags(pRecImp->GetImplFlags());
- }
- }
-
- // verify the children
- IfFailGo( VerifyParams(pImportData, mdImp, mdEmit) );
- IfFailGo( VerifyGenericParams(pImportData, mdImp, mdEmit) );
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyMethod()
-
-
-//*****************************************************************************
-// Verify Fields
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyFields(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- FieldRec *pRecImp;
- FieldRec *pRecEmit;
- mdFieldDef fdImp;
- mdFieldDef fdEmit;
- ULONG ridStart;
- ULONG ridEnd;
- ULONG i;
-
- TypeDefRec *pTypeDefRec;
- LPCUTF8 szName;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
- TOKENREC *pTokenRec;
- MDTOKENMAP *pCurTkMap;
-
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- ULONG cImport = 0; // count of non-merge check suppressed fields
- mdCustomAttribute tkCA;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // Get a count of records in the import scope; prepare to enumerate them.
- IfFailGo(pMiniMdImport->GetTypeDefRecord(RidFromToken(tdImport), &pTypeDefRec));
- ridStart = pMiniMdImport->getFieldListOfTypeDef(pTypeDefRec);
- IfFailGo(pMiniMdImport->getEndFieldListOfTypeDef(RidFromToken(tdImport), &ridEnd));
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- // loop through all fields of the TypeDef
- for (i = ridStart; i < ridEnd; i++)
- {
- IfFailGo(pMiniMdImport->GetFieldRid(i, (ULONG *)&fdImp));
-
- // only verify those fields that are marked
- if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(TokenFromRid(fdImp, mdtFieldDef)) == false)
- continue;
-
- IfFailGo(pMiniMdImport->GetFieldRecord(fdImp, &pRecImp));
-
- if (m_fDupCheck == FALSE && tdImport == pImportData->m_pRegMetaImport->m_tdModule)
- {
- // No dup check. This is the scenario that we only have one import scope. Just copy over the
- // globals.
- goto CopyFieldLabel;
- }
-
- IfFailGo(pMiniMdImport->getNameOfField(pRecImp, &szName));
- IfFailGo(pMiniMdImport->getSignatureOfField(pRecImp, &pbSig, &cbSig));
-
- if ( IsFdPrivateScope(pRecImp->GetFlags()))
- {
- // Trigger additive merge
- fdImp = TokenFromRid(fdImp, mdtFieldDef);
- goto CopyFieldLabel;
- }
-
- // convert rid contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly scope information.
- pMiniMdImport, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
-
- hr = ImportHelper::FindField(
- pMiniMdEmit,
- tdEmit,
- szName,
- (const COR_SIGNATURE *)qbSig.Ptr(),
- cbEmit,
- &fdEmit);
-
- fdImp = TokenFromRid(fdImp, mdtFieldDef);
-
- bSuppressMergeCheck =
- (IsFdStatic(pRecImp->GetFlags()) && pMTD->m_bSuppressMergeCheck) ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- fdImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (bSuppressMergeCheck || (tdImport == pImportData->m_pRegMetaImport->m_tdModule))
- {
- // global data! Make sure that we move over the non-duplicate global function
- // declaration
- //
- if (hr == S_OK)
- {
- // found the duplicate
- IfFailGo( pCurTkMap->InsertNotFound(fdImp, true, fdEmit, &pTokenRec) );
- }
- else
- {
-CopyFieldLabel:
- // not a duplicate! Copy over the
- IfFailGo(pMiniMdEmit->AddFieldRecord(&pRecEmit, (RID *)&fdEmit));
-
- // copy the field record over
- IfFailGo( CopyField(pImportData, pRecImp, pRecEmit) );
-
- IfFailGo( pMiniMdEmit->AddFieldToTypeDef(RidFromToken(tdEmit), fdEmit));
-
- // record the token movement
- fdEmit = TokenFromRid(fdEmit, mdtFieldDef);
- IfFailGo( pMiniMdEmit->AddMemberDefToHash(
- fdEmit,
- tdEmit) );
-
- fdImp = TokenFromRid(fdImp, mdtFieldDef);
- IfFailGo( pCurTkMap->InsertNotFound(fdImp, false, fdEmit, &pTokenRec) );
- }
- }
- else
- {
- if (hr == S_OK)
- {
- // Good! We are supposed to find a duplicate
- IfFailGo( pCurTkMap->InsertNotFound(fdImp, true, fdEmit, &pTokenRec) );
- }
- else
- {
- // Oops! The typedef is duplicated but the field is not!!
- hr = S_OK; // discard old error; new error will be returned from CheckContinuableError
- CheckContinuableErrorEx(META_E_FIELD_NOT_FOUND, pImportData, fdImp);
- }
-
- cImport++;
- }
- }
-
- // The counts should be the same, unless this is <module>
- if (cImport != pMTD->m_cFields && tdImport != pImportData->m_pRegMetaImport->m_tdModule)
- {
- CheckContinuableErrorEx(META_E_FIELD_COUNTS, pImportData, tdImport);
- // If we are here, the linker says this error is OK.
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyFields()
-
-
-//*****************************************************************************
-// Verify Events
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyEvents(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- RID ridEventMap, ridEventMapEmit;
- EventMapRec *pEventMapRec;
- EventRec *pRecImport;
- ULONG ridStart;
- ULONG ridEnd;
- ULONG i;
- mdEvent evImport;
- mdEvent evEmit;
- TOKENREC *pTokenRec;
- LPCUTF8 szName;
- mdToken tkType;
- MDTOKENMAP *pCurTkMap;
-
- EventMapRec *pEventMapEmit;
- EventRec *pRecEmit;
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- ULONG cImport = 0; // count of non-merge check suppressed events
- mdCustomAttribute tkCA;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- IfFailGo(pMiniMdImport->FindEventMapFor(RidFromToken(tdImport), &ridEventMap));
- if (!InvalidRid(ridEventMap))
- {
- // Get a count of records already in emit scope.
- IfFailGo(pMiniMdEmit->FindEventMapFor(RidFromToken(tdEmit), &ridEventMapEmit));
-
- if (InvalidRid(ridEventMapEmit)) {
- // If there is any event, create the eventmap record in the emit scope
- // Create new record.
- IfFailGo(pMiniMdEmit->AddEventMapRecord(&pEventMapEmit, &ridEventMapEmit));
-
- // Set parent.
- IfFailGo(pMiniMdEmit->PutToken(TBL_EventMap, EventMapRec::COL_Parent, pEventMapEmit, tdEmit));
- }
-
- // Get a count of records in the import scope; prepare to enumerate them.
- IfFailGo(pMiniMdImport->GetEventMapRecord(ridEventMap, &pEventMapRec));
- ridStart = pMiniMdImport->getEventListOfEventMap(pEventMapRec);
- IfFailGo(pMiniMdImport->getEndEventListOfEventMap(ridEventMap, &ridEnd));
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- for (i = ridStart; i < ridEnd; i++)
- {
- // get the property rid
- IfFailGo(pMiniMdImport->GetEventRid(i, (ULONG *)&evImport));
-
- // only verify those Events that are marked
- if ( pMiniMdImport->GetFilterTable()->IsEventMarked(TokenFromRid(evImport, mdtEvent)) == false)
- continue;
-
- IfFailGo(pMiniMdImport->GetEventRecord(evImport, &pRecImport));
- IfFailGo(pMiniMdImport->getNameOfEvent(pRecImport, &szName));
- tkType = pMiniMdImport->getEventTypeOfEvent( pRecImport );
- IfFailGo( pCurTkMap->Remap(tkType, &tkType) );
- evImport = TokenFromRid( evImport, mdtEvent);
-
- hr = ImportHelper::FindEvent(
- pMiniMdEmit,
- tdEmit,
- szName,
- &evEmit);
-
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- evImport, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (bSuppressMergeCheck)
- {
-
- if (hr == S_OK )
- {
- // Good. We found the matching event when we have a duplicate typedef
- IfFailGo( pCurTkMap->InsertNotFound(evImport, true, evEmit, &pTokenRec) );
- }
- else
- {
- // not a duplicate! Copy over the
- IfFailGo(pMiniMdEmit->AddEventRecord(&pRecEmit, (RID *)&evEmit));
-
- // copy the event record over
- IfFailGo( CopyEvent(pImportData, pRecImport, pRecEmit) );
-
- // Add Event to the EventMap.
- IfFailGo( pMiniMdEmit->AddEventToEventMap(ridEventMapEmit, evEmit) );
-
- // record the token movement
- evEmit = TokenFromRid(evEmit, mdtEvent);
-
- IfFailGo( pCurTkMap->InsertNotFound(evImport, false, evEmit, &pTokenRec) );
-
- // copy over the method semantics
- IfFailGo( CopyMethodSemantics(pImportData, evImport, evEmit) );
- }
- }
- else
- {
- if (hr == S_OK )
- {
- // Good. We found the matching event when we have a duplicate typedef
- IfFailGo( pCurTkMap->InsertNotFound(evImport, true, evEmit, &pTokenRec) );
- }
- else
- {
- // Oops! The typedef is duplicated but the event is not!!
- hr = S_OK; // discard old error; new error will be returned from CheckContinuableError
- CheckContinuableErrorEx(META_E_EVENT_NOT_FOUND, pImportData, evImport);
-
- }
-
- cImport++;
- }
- }
-
- // The counts should be the same, unless this is <module>
- if (cImport != pMTD->m_cEvents && tdImport != pImportData->m_pRegMetaImport->m_tdModule)
- {
- CheckContinuableErrorEx(META_E_EVENT_COUNTS, pImportData, tdImport);
- // If we are here, the linker says this error is OK.
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyEvents()
-
-
-//*****************************************************************************
-// Verify Properties
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyProperties(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- RID ridPropertyMap, ridPropertyMapEmit;
- PropertyMapRec *pPropertyMapRec;
- PropertyRec *pRecImport;
- ULONG ridStart;
- ULONG ridEnd;
- ULONG i;
- mdProperty prImp;
- mdProperty prEmit;
- TOKENREC *pTokenRec;
- LPCUTF8 szName;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
- MDTOKENMAP *pCurTkMap;
-
- PropertyMapRec *pPropertyMapEmit;
- PropertyRec *pRecEmit;
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- ULONG cImport = 0; // count of non-merge check suppressed properties
- mdCustomAttribute tkCA;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- IfFailGo(pMiniMdImport->FindPropertyMapFor(RidFromToken(tdImport), &ridPropertyMap));
- if (!InvalidRid(ridPropertyMap))
- {
- // Get a count of records already in emit scope.
- IfFailGo(pMiniMdEmit->FindPropertyMapFor(RidFromToken(tdEmit), &ridPropertyMapEmit));
-
- if (InvalidRid(ridPropertyMapEmit))
- {
- // If there is any event, create the PropertyMap record in the emit scope
- // Create new record.
- IfFailGo(pMiniMdEmit->AddPropertyMapRecord(&pPropertyMapEmit, &ridPropertyMapEmit));
-
- // Set parent.
- IfFailGo(pMiniMdEmit->PutToken(TBL_PropertyMap, PropertyMapRec::COL_Parent, pPropertyMapEmit, tdEmit));
- }
-
- // Get a count of records in the import scope; prepare to enumerate them.
- IfFailGo(pMiniMdImport->GetPropertyMapRecord(ridPropertyMap, &pPropertyMapRec));
- ridStart = pMiniMdImport->getPropertyListOfPropertyMap(pPropertyMapRec);
- IfFailGo(pMiniMdImport->getEndPropertyListOfPropertyMap(ridPropertyMap, &ridEnd));
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- for (i = ridStart; i < ridEnd; i++)
- {
- // get the property rid
- IfFailGo(pMiniMdImport->GetPropertyRid(i, (ULONG *)&prImp));
-
- // only verify those Properties that are marked
- if ( pMiniMdImport->GetFilterTable()->IsPropertyMarked(TokenFromRid(prImp, mdtProperty)) == false)
- continue;
-
- IfFailGo(pMiniMdImport->GetPropertyRecord(prImp, &pRecImport));
- IfFailGo(pMiniMdImport->getNameOfProperty(pRecImport, &szName));
- IfFailGo(pMiniMdImport->getTypeOfProperty(pRecImport, &pbSig, &cbSig));
- prImp = TokenFromRid( prImp, mdtProperty);
-
- // convert rid contained in signature to new scope
- IfFailGo( ImportHelper::MergeUpdateTokenInSig(
- NULL, // Emit assembly.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly scope information.
- pMiniMdImport, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit) ); // number of bytes write to cbEmit
-
- hr = ImportHelper::FindProperty(
- pMiniMdEmit,
- tdEmit,
- szName,
- (PCCOR_SIGNATURE) qbSig.Ptr(),
- cbEmit,
- &prEmit);
-
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- prImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (bSuppressMergeCheck)
- {
- if (hr == S_OK)
- {
- // Good. We found the matching property when we have a duplicate typedef
- IfFailGo( pCurTkMap->InsertNotFound(prImp, true, prEmit, &pTokenRec) );
- }
- else
- {
- IfFailGo(pMiniMdEmit->AddPropertyRecord(&pRecEmit, (RID *)&prEmit));
-
- // copy the property record over
- IfFailGo( CopyProperty(pImportData, pRecImport, pRecEmit) );
-
- // Add Property to the PropertyMap.
- IfFailGo( pMiniMdEmit->AddPropertyToPropertyMap(ridPropertyMapEmit, prEmit) );
-
- // record the token movement
- prEmit = TokenFromRid(prEmit, mdtProperty);
-
- IfFailGo( pCurTkMap->InsertNotFound(prImp, false, prEmit, &pTokenRec) );
-
- // copy over the method semantics
- IfFailGo( CopyMethodSemantics(pImportData, prImp, prEmit) );
- }
- }
- else
- {
- if (hr == S_OK)
- {
- // Good. We found the matching property when we have a duplicate typedef
- IfFailGo( pCurTkMap->InsertNotFound(prImp, true, prEmit, &pTokenRec) );
- }
- else
- {
- hr = S_OK; // discard old error; new error will be returned from CheckContinuableError
- CheckContinuableErrorEx(META_E_PROP_NOT_FOUND, pImportData, prImp);
- }
-
- cImport++;
- }
- }
-
- // The counts should be the same, unless this is <module>
- if (cImport != pMTD->m_cProperties && tdImport != pImportData->m_pRegMetaImport->m_tdModule)
- {
- CheckContinuableErrorEx(META_E_PROPERTY_COUNTS, pImportData, tdImport);
- // If we are here, the linker says this error is OK.
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyProperties()
-
-
-//*****************************************************************************
-// Verify Parameters given a Method
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyParams(
- MergeImportData *pImportData,
- mdMethodDef mdImport,
- mdMethodDef mdEmit)
-{
- HRESULT hr = NOERROR;
- ParamRec *pRecImport = NULL;
- ParamRec *pRecEmit = NULL;
- MethodRec *pMethodRec;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG ridStart, ridEnd;
- ULONG ridStartEmit, ridEndEmit;
- ULONG cImport, cEmit;
- ULONG i, j;
- mdParamDef pdEmit = 0;
- mdParamDef pdImp;
- TOKENREC *pTokenRec;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // Get count of params in import scope; prepare to enumerate.
- IfFailGo(pMiniMdImport->GetMethodRecord(RidFromToken(mdImport), &pMethodRec));
- ridStart = pMiniMdImport->getParamListOfMethod(pMethodRec);
- IfFailGo(pMiniMdImport->getEndParamListOfMethod(RidFromToken(mdImport), &ridEnd));
- cImport = ridEnd - ridStart;
-
- // Get count of params in emit scope; prepare to enumerate.
- IfFailGo(pMiniMdEmit->GetMethodRecord(RidFromToken(mdEmit), &pMethodRec));
- ridStartEmit = pMiniMdEmit->getParamListOfMethod(pMethodRec);
- IfFailGo(pMiniMdEmit->getEndParamListOfMethod(RidFromToken(mdEmit), &ridEndEmit));
- cEmit = ridEndEmit - ridStartEmit;
-
- // The counts should be the same.
- if (cImport != cEmit)
- {
- // That is, unless this is <module>, so get the method's parent.
- mdTypeDef tdImport;
- IfFailGo(pMiniMdImport->FindParentOfMethodHelper(mdImport, &tdImport));
- if (tdImport != pImportData->m_pRegMetaImport->m_tdModule)
- CheckContinuableErrorEx(META_E_PARAM_COUNTS, pImportData, mdImport);
- // If we are here, the linker says this error is OK.
- }
-
- // loop through all Parameters
- for (i = ridStart; i < ridEnd; i++)
- {
- // Get the importing param row
- IfFailGo(pMiniMdImport->GetParamRid(i, (ULONG *)&pdImp));
-
- // only verify those Params that are marked
- if ( pMiniMdImport->GetFilterTable()->IsParamMarked(TokenFromRid(pdImp, mdtParamDef)) == false)
- continue;
-
-
- IfFailGo(pMiniMdImport->GetParamRecord(pdImp, &pRecImport));
- pdImp = TokenFromRid(pdImp, mdtParamDef);
-
- // It turns out when we merge a typelib with itself, the emit and import scope
- // has different sequence of parameter
- //
- // find the corresponding emit param row
- for (j = ridStartEmit; j < ridEndEmit; j++)
- {
- IfFailGo(pMiniMdEmit->GetParamRid(j, (ULONG *)&pdEmit));
- IfFailGo(pMiniMdEmit->GetParamRecord(pdEmit, &pRecEmit));
- if (pRecEmit->GetSequence() == pRecImport->GetSequence())
- break;
- }
-
- if (j == ridEndEmit)
- {
- // did not find the corresponding parameter in the emiting scope
- hr = S_OK; // discard old error; new error will be returned from CheckContinuableError
- CheckContinuableErrorEx(META_S_PARAM_MISMATCH, pImportData, pdImp);
- }
-
- else
- {
- _ASSERTE( pRecEmit->GetSequence() == pRecImport->GetSequence() );
-
- pdEmit = TokenFromRid(pdEmit, mdtParamDef);
-
- // record the token movement
-#ifdef WE_DONT_NEED_TO_CHECK_NAMES__THEY_DONT_AFFECT_ANYTHING
- LPCUTF8 szNameImp;
- LPCUTF8 szNameEmit;
- IfFailGo(pMiniMdImport->getNameOfParam(pRecImport, &szNameImp));
- IfFailGo(pMiniMdEmit->getNameOfParam(pRecEmit, &szNameEmit));
- if (szNameImp && szNameEmit && strcmp(szNameImp, szNameEmit) != 0)
- {
- // parameter name doesn't match
- CheckContinuableErrorEx(META_S_PARAM_MISMATCH, pImportData, pdImp);
- }
-#endif
- if (pRecEmit->GetFlags() != pRecImport->GetFlags())
- {
- // flags doesn't match
- CheckContinuableErrorEx(META_S_PARAM_MISMATCH, pImportData, pdImp);
- }
-
- // record token movement. This is a duplicate.
- IfFailGo( pCurTkMap->InsertNotFound(pdImp, true, pdEmit, &pTokenRec) );
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyParams()
-
-
-//*****************************************************************************
-// merging MemberRef
-//*****************************************************************************
-HRESULT NEWMERGER::MergeMemberRefs( )
-{
- HRESULT hr = NOERROR;
- MemberRefRec *pRecImport = NULL;
- MemberRefRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdMemberRef mrEmit;
- mdMemberRef mrImp;
- bool bDuplicate = false;
- TOKENREC *pTokenRec;
- mdToken tkParentImp;
- mdToken tkParentEmit;
-
- LPCUTF8 szNameImp;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
-
- bool isRefOptimizedToDef;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- iCount = pMiniMdImport->getCountMemberRefs();
-
- // loop through all MemberRef
- for (i = 1; i <= iCount; i++)
- {
-
- // only merge those MemberRefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsMemberRefMarked(TokenFromRid(i, mdtMemberRef)) == false)
- continue;
-
- isRefOptimizedToDef = false;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetMemberRefRecord(i, &pRecImport));
- IfFailGo(pMiniMdImport->getNameOfMemberRef(pRecImport, &szNameImp));
- IfFailGo(pMiniMdImport->getSignatureOfMemberRef(pRecImport, &pbSig, &cbSig));
- tkParentImp = pMiniMdImport->getClassOfMemberRef(pRecImport);
-
- IfFailGo( pCurTkMap->Remap(tkParentImp, &tkParentEmit) );
-
- // convert rid contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly information.
- pMiniMdImport, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
-
- // We want to know if we can optimize this MemberRef to a FieldDef or MethodDef
- if (TypeFromToken(tkParentEmit) == mdtTypeDef && RidFromToken(tkParentEmit) != 0)
- {
- // The parent of this MemberRef has been successfully optimized to a TypeDef. Then this MemberRef should be
- // be able to optimized to a MethodDef or FieldDef unless one of the parent in the inheritance hierachy
- // is through TypeRef. Then this MemberRef stay as MemberRef. If This is a VarArg calling convention, then
- // we will remap the MemberRef's parent to a MethodDef or stay as TypeRef.
- //
- mdToken tkParent = tkParentEmit;
- mdToken tkMethDefOrFieldDef;
- PCCOR_SIGNATURE pbSigTmp = (const COR_SIGNATURE *) qbSig.Ptr();
-
- while (TypeFromToken(tkParent) == mdtTypeDef && RidFromToken(tkParent) != 0)
- {
- TypeDefRec *pRec;
- hr = ImportHelper::FindMember(pMiniMdEmit, tkParent, szNameImp, pbSigTmp, cbEmit, &tkMethDefOrFieldDef);
- if (hr == S_OK)
- {
- // We have found a match!!
- if (isCallConv(CorSigUncompressCallingConv(pbSigTmp), IMAGE_CEE_CS_CALLCONV_VARARG))
- {
- // The found MethodDef token will replace this MemberRef's parent token
- _ASSERTE(TypeFromToken(tkMethDefOrFieldDef) == mdtMethodDef);
- tkParentEmit = tkMethDefOrFieldDef;
- break;
- }
- else
- {
- // The found MethodDef/FieldDef token will replace this MemberRef token and we won't introduce a MemberRef
- // record.
- //
- mrEmit = tkMethDefOrFieldDef;
- isRefOptimizedToDef = true;
- bDuplicate = true;
- break;
- }
- }
-
- // now walk up to the parent class of tkParent and try to resolve this MemberRef
- IfFailGo(pMiniMdEmit->GetTypeDefRecord(RidFromToken(tkParent), &pRec));
- tkParent = pMiniMdEmit->getExtendsOfTypeDef(pRec);
- }
-
- // When we exit the loop, there are several possibilities:
- // 1. We found a MethodDef/FieldDef to replace the MemberRef
- // 2. We found a MethodDef matches the MemberRef but the MemberRef is VarArg, thus we want to use the MethodDef in the
- // parent column but not replacing it.
- // 3. We exit because we run out the TypeDef on the parent chain. If it is because we encounter a TypeRef, this TypeRef will
- // replace the parent column of the MemberRef. Or we encounter nil token! (This can be unresolved global MemberRef or
- // compiler error to put an undefined MemberRef. In this case, we should just use the old tkParentEmit
- // on the parent column for the MemberRef.
-
- if (TypeFromToken(tkParent) == mdtTypeRef && RidFromToken(tkParent) != 0)
- {
- // we had walked up the parent's chain to resolve it but we have not been successful and got stopped by a TypeRef.
- // Then we will use this TypeRef as the parent of the emit MemberRef record
- //
- tkParentEmit = tkParent;
- }
- }
- else if ((TypeFromToken(tkParentEmit) == mdtMethodDef &&
- !isCallConv(CorSigUncompressCallingConv(pbSig), IMAGE_CEE_CS_CALLCONV_VARARG)) ||
- (TypeFromToken(tkParentEmit) == mdtFieldDef))
- {
- // If the MemberRef's parent is already a non-vararg MethodDef or FieldDef, we can also
- // safely drop the MemberRef
- mrEmit = tkParentEmit;
- isRefOptimizedToDef = true;
- bDuplicate = true;
- }
-
- // If the Ref cannot be optimized to a Def or MemberRef to Def optmization is turned off, do the following.
- if (isRefOptimizedToDef == false || !((m_optimizeRefToDef & MDMemberRefToDef) == MDMemberRefToDef))
- {
- // does this MemberRef already exist in the emit scope?
- if ( m_fDupCheck && ImportHelper::FindMemberRef(
- pMiniMdEmit,
- tkParentEmit,
- szNameImp,
- (const COR_SIGNATURE *) qbSig.Ptr(),
- cbEmit,
- &mrEmit) == S_OK )
- {
- // Yes, it does
- bDuplicate = true;
- }
- else
- {
- // No, it doesn't. Copy it over.
- bDuplicate = false;
- IfFailGo(pMiniMdEmit->AddMemberRefRecord(&pRecEmit, (RID *)&mrEmit));
- mrEmit = TokenFromRid( mrEmit, mdtMemberRef );
-
- // Copy over the MemberRef context
- IfFailGo(pMiniMdEmit->PutString(TBL_MemberRef, MemberRefRec::COL_Name, pRecEmit, szNameImp));
- IfFailGo(pMiniMdEmit->PutToken(TBL_MemberRef, MemberRefRec::COL_Class, pRecEmit, tkParentEmit));
- IfFailGo(pMiniMdEmit->PutBlob(TBL_MemberRef, MemberRefRec::COL_Signature, pRecEmit,
- qbSig.Ptr(), cbEmit));
- IfFailGo(pMiniMdEmit->AddMemberRefToHash(mrEmit) );
- }
- }
- // record the token movement
- mrImp = TokenFromRid(i, mdtMemberRef);
- IfFailGo( pCurTkMap->InsertNotFound(mrImp, bDuplicate, mrEmit, &pTokenRec) );
- }
- }
-
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeMemberRefs()
-
-
-//*****************************************************************************
-// merge interface impl
-//*****************************************************************************
-HRESULT NEWMERGER::MergeInterfaceImpls( )
-{
- HRESULT hr = NOERROR;
- InterfaceImplRec *pRecImport = NULL;
- InterfaceImplRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdTypeDef tkParent;
- mdInterfaceImpl iiEmit;
- bool bDuplicate;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountInterfaceImpls();
-
- // loop through all InterfaceImpl
- for (i = 1; i <= iCount; i++)
- {
- // only merge those InterfaceImpls that are marked
- if ( pMiniMdImport->GetFilterTable()->IsInterfaceImplMarked(TokenFromRid(i, mdtInterfaceImpl)) == false)
- continue;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetInterfaceImplRecord(i, &pRecImport));
- tkParent = pMiniMdImport->getClassOfInterfaceImpl(pRecImport);
-
- // does this TypeRef already exist in the emit scope?
- if ( pCurTkMap->Find(tkParent, &pTokenRec) )
- {
- if ( pTokenRec->m_isDuplicate )
- {
- // parent in the emit scope
- mdToken tkParentEmit;
- mdToken tkInterface;
-
- // remap the typedef token
- tkParentEmit = pTokenRec->m_tkTo;
-
- // remap the implemented interface token
- tkInterface = pMiniMdImport->getInterfaceOfInterfaceImpl(pRecImport);
- IfFailGo( pCurTkMap->Remap( tkInterface, &tkInterface) );
-
- // Set duplicate flag
- bDuplicate = true;
-
- // find the corresponding interfaceimpl in the emit scope
- if ( ImportHelper::FindInterfaceImpl(pMiniMdEmit, tkParentEmit, tkInterface, &iiEmit) != S_OK )
- {
- // bad state!! We have a duplicate typedef but the interface impl is not the same!!
-
- // continuable error
- CheckContinuableErrorEx(
- META_E_INTFCEIMPL_NOT_FOUND,
- pImportData,
- TokenFromRid(i, mdtInterfaceImpl));
-
- iiEmit = mdTokenNil;
- }
- }
- else
- {
- // No, it doesn't. Copy it over.
- bDuplicate = false;
- IfFailGo(pMiniMdEmit->AddInterfaceImplRecord(&pRecEmit, (RID *)&iiEmit));
-
- // copy the interfaceimp record over
- IfFailGo( CopyInterfaceImpl( pRecEmit, pImportData, pRecImport) );
- }
- }
- else
- {
- _ASSERTE( !"bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
-
- // record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(
- TokenFromRid(i, mdtInterfaceImpl),
- bDuplicate,
- TokenFromRid( iiEmit, mdtInterfaceImpl ),
- &pTokenRec) );
- }
- }
-
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeInterfaceImpls()
-
-
-//*****************************************************************************
-// merge all of the constant for field, property, and parameter
-//*****************************************************************************
-HRESULT NEWMERGER::MergeConstants()
-{
- HRESULT hr = NOERROR;
- ConstantRec *pRecImport = NULL;
- ConstantRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- ULONG csEmit; // constant value is not a token
- mdToken tkParentImp;
- TOKENREC *pTokenRec;
- void const *pValue;
- ULONG cbBlob;
-#if _DEBUG
- ULONG typeParent;
-#endif // _DEBUG
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountConstants();
-
- // loop through all Constants
- for (i = 1; i <= iCount; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetConstantRecord(i, &pRecImport));
- tkParentImp = pMiniMdImport->getParentOfConstant(pRecImport);
-
- // only move those constant over if their parents are marked
- // If MDTOKENMAP::Find returns false, we don't need to copy the constant value over
- if ( pCurTkMap->Find(tkParentImp, &pTokenRec) )
- {
- // If the parent is duplicated, no need to move over the constant value
- if ( !pTokenRec->m_isDuplicate )
- {
- IfFailGo(pMiniMdEmit->AddConstantRecord(&pRecEmit, &csEmit));
- pRecEmit->SetType(pRecImport->GetType());
-
- // set the parent
- IfFailGo( pMiniMdEmit->PutToken(TBL_Constant, ConstantRec::COL_Parent, pRecEmit, pTokenRec->m_tkTo) );
-
- // move over the constant blob value
- IfFailGo(pMiniMdImport->getValueOfConstant(pRecImport, (const BYTE **)&pValue, &cbBlob));
- IfFailGo( pMiniMdEmit->PutBlob(TBL_Constant, ConstantRec::COL_Value, pRecEmit, pValue, cbBlob) );
- IfFailGo( pMiniMdEmit->AddConstantToHash(csEmit) );
- }
- else
- {
- // <TODO>@FUTURE: more verification on the duplicate??</TODO>
- }
- }
-#if _DEBUG
- // Include this block only under Debug build. The reason is that
- // the linker chooses all the errors that we report (such as unmatched MethodDef or FieldDef)
- // as a continuable error. It is likely to hit this else while the tkparentImp is marked if there
- // is any error reported earlier!!
- else
- {
- typeParent = TypeFromToken(tkParentImp);
- if (typeParent == mdtFieldDef)
- {
- // FieldDef should not be marked.
- if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(tkParentImp) == false)
- continue;
- }
- else if (typeParent == mdtParamDef)
- {
- // ParamDef should not be marked.
- if ( pMiniMdImport->GetFilterTable()->IsParamMarked(tkParentImp) == false)
- continue;
- }
- else
- {
- _ASSERTE(typeParent == mdtProperty);
- // Property should not be marked.
- if ( pMiniMdImport->GetFilterTable()->IsPropertyMarked(tkParentImp) == false)
- continue;
- }
-
- // If we come to here, we have a constant whose parent is marked but we could not
- // find it in the map!! Bad state.
-
- _ASSERTE(!"Ignore this error if you have seen error reported earlier! Otherwise bad token map or bad metadata!");
- }
-#endif // _DEBUG
- // Note that we don't need to record the token movement since constant is not a valid token kind.
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeConstants()
-
-
-//*****************************************************************************
-// Merge field marshal information
-//*****************************************************************************
-HRESULT NEWMERGER::MergeFieldMarshals()
-{
- HRESULT hr = NOERROR;
- FieldMarshalRec *pRecImport = NULL;
- FieldMarshalRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- ULONG fmEmit; // FieldMarhsal is not a token
- mdToken tkParentImp;
- TOKENREC *pTokenRec;
- void const *pValue;
- ULONG cbBlob;
-#if _DEBUG
- ULONG typeParent;
-#endif // _DEBUG
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountFieldMarshals();
-
- // loop through all TypeRef
- for (i = 1; i <= iCount; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetFieldMarshalRecord(i, &pRecImport));
- tkParentImp = pMiniMdImport->getParentOfFieldMarshal(pRecImport);
-
- // We want to merge only those field marshals that parents are marked.
- // Find will return false if the parent is not marked
- //
- if ( pCurTkMap->Find(tkParentImp, &pTokenRec) )
- {
- // If the parent is duplicated, no need to move over the constant value
- if ( !pTokenRec->m_isDuplicate )
- {
- IfFailGo(pMiniMdEmit->AddFieldMarshalRecord(&pRecEmit, &fmEmit));
-
- // set the parent
- IfFailGo( pMiniMdEmit->PutToken(
- TBL_FieldMarshal,
- FieldMarshalRec::COL_Parent,
- pRecEmit,
- pTokenRec->m_tkTo) );
-
- // move over the constant blob value
- IfFailGo(pMiniMdImport->getNativeTypeOfFieldMarshal(pRecImport, (const BYTE **)&pValue, &cbBlob));
- IfFailGo( pMiniMdEmit->PutBlob(TBL_FieldMarshal, FieldMarshalRec::COL_NativeType, pRecEmit, pValue, cbBlob) );
- IfFailGo( pMiniMdEmit->AddFieldMarshalToHash(fmEmit) );
-
- }
- else
- {
- // <TODO>@FUTURE: more verification on the duplicate??</TODO>
- }
- }
-#if _DEBUG
- else
- {
- typeParent = TypeFromToken(tkParentImp);
-
- if (typeParent == mdtFieldDef)
- {
- // FieldDefs should not be marked
- if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(tkParentImp) == false)
- continue;
- }
- else
- {
- _ASSERTE(typeParent == mdtParamDef);
- // ParamDefs should not be marked
- if ( pMiniMdImport->GetFilterTable()->IsParamMarked(tkParentImp) == false)
- continue;
- }
-
- // If we come to here, that is we have a FieldMarshal whose parent is marked and we don't find it
- // in the map!!!
-
- // either bad lookup map or bad metadata
- _ASSERTE(!"Ignore this assert if you have seen error reported earlier. Otherwise, it is bad state!");
- }
-#endif // _DEBUG
- }
- // Note that we don't need to record the token movement since FieldMarshal is not a valid token kind.
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeFieldMarshals()
-
-
-//*****************************************************************************
-// Merge class layout information
-//*****************************************************************************
-HRESULT NEWMERGER::MergeClassLayouts()
-{
- HRESULT hr = NOERROR;
- ClassLayoutRec *pRecImport = NULL;
- ClassLayoutRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- ULONG iRecord; // class layout is not a token
- mdToken tkParentImp;
- TOKENREC *pTokenRec;
- RID ridClassLayout;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountClassLayouts();
-
- // loop through all TypeRef
- for (i = 1; i <= iCount; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetClassLayoutRecord(i, &pRecImport));
- tkParentImp = pMiniMdImport->getParentOfClassLayout(pRecImport);
-
- // only merge those TypeDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsTypeDefMarked(tkParentImp) == false)
- continue;
-
- if ( pCurTkMap->Find(tkParentImp, &pTokenRec) )
- {
- if ( !pTokenRec->m_isDuplicate )
- {
- // If the parent is not duplicated, just copy over the classlayout information
- IfFailGo(pMiniMdEmit->AddClassLayoutRecord(&pRecEmit, &iRecord));
-
- // copy over the fix part information
- pRecEmit->Copy(pRecImport);
- IfFailGo( pMiniMdEmit->PutToken(TBL_ClassLayout, ClassLayoutRec::COL_Parent, pRecEmit, pTokenRec->m_tkTo));
- IfFailGo( pMiniMdEmit->AddClassLayoutToHash(iRecord) );
- }
- else
- {
-
- IfFailGo(pMiniMdEmit->FindClassLayoutHelper(pTokenRec->m_tkTo, &ridClassLayout));
-
- if (InvalidRid(ridClassLayout))
- {
- // class is duplicated but not class layout info
- CheckContinuableErrorEx(META_E_CLASS_LAYOUT_INCONSISTENT, pImportData, tkParentImp);
- }
- else
- {
- IfFailGo(pMiniMdEmit->GetClassLayoutRecord(RidFromToken(ridClassLayout), &pRecEmit));
- if (pMiniMdImport->getPackingSizeOfClassLayout(pRecImport) != pMiniMdEmit->getPackingSizeOfClassLayout(pRecEmit) ||
- pMiniMdImport->getClassSizeOfClassLayout(pRecImport) != pMiniMdEmit->getClassSizeOfClassLayout(pRecEmit) )
- {
- CheckContinuableErrorEx(META_E_CLASS_LAYOUT_INCONSISTENT, pImportData, tkParentImp);
- }
- }
- }
- }
- else
- {
- // bad lookup map
- _ASSERTE( !"bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
- // no need to record the index movement. Classlayout is not a token.
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeClassLayouts()
-
-//*****************************************************************************
-// Merge field layout information
-//*****************************************************************************
-HRESULT NEWMERGER::MergeFieldLayouts()
-{
- HRESULT hr = NOERROR;
- FieldLayoutRec *pRecImport = NULL;
- FieldLayoutRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- ULONG iRecord; // field layout2 is not a token.
- mdToken tkFieldImp;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountFieldLayouts();
-
- // loop through all FieldLayout records.
- for (i = 1; i <= iCount; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetFieldLayoutRecord(i, &pRecImport));
- tkFieldImp = pMiniMdImport->getFieldOfFieldLayout(pRecImport);
-
- // only merge those FieldDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(tkFieldImp) == false)
- continue;
-
- if ( pCurTkMap->Find(tkFieldImp, &pTokenRec) )
- {
- if ( !pTokenRec->m_isDuplicate )
- {
- // If the Field is not duplicated, just copy over the FieldLayout information
- IfFailGo(pMiniMdEmit->AddFieldLayoutRecord(&pRecEmit, &iRecord));
-
- // copy over the fix part information
- pRecEmit->Copy(pRecImport);
- IfFailGo( pMiniMdEmit->PutToken(TBL_FieldLayout, FieldLayoutRec::COL_Field, pRecEmit, pTokenRec->m_tkTo));
- IfFailGo( pMiniMdEmit->AddFieldLayoutToHash(iRecord) );
- }
- else
- {
- // <TODO>@FUTURE: more verification??</TODO>
- }
- }
- else
- {
- // bad lookup map
- _ASSERTE( !"bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
- // no need to record the index movement. fieldlayout2 is not a token.
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeFieldLayouts()
-
-
-//*****************************************************************************
-// Merge field RVAs
-//*****************************************************************************
-HRESULT NEWMERGER::MergeFieldRVAs()
-{
- HRESULT hr = NOERROR;
- FieldRVARec *pRecImport = NULL;
- FieldRVARec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- ULONG iRecord; // FieldRVA is not a token.
- mdToken tkFieldImp;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountFieldRVAs();
-
- // loop through all FieldRVA records.
- for (i = 1; i <= iCount; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetFieldRVARecord(i, &pRecImport));
- tkFieldImp = pMiniMdImport->getFieldOfFieldRVA(pRecImport);
-
- // only merge those FieldDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(TokenFromRid(tkFieldImp, mdtFieldDef)) == false)
- continue;
-
- if ( pCurTkMap->Find(tkFieldImp, &pTokenRec) )
- {
- if ( !pTokenRec->m_isDuplicate )
- {
- // If the Field is not duplicated, just copy over the FieldRVA information
- IfFailGo(pMiniMdEmit->AddFieldRVARecord(&pRecEmit, &iRecord));
-
- // copy over the fix part information
- pRecEmit->Copy(pRecImport);
- IfFailGo( pMiniMdEmit->PutToken(TBL_FieldRVA, FieldRVARec::COL_Field, pRecEmit, pTokenRec->m_tkTo));
- IfFailGo( pMiniMdEmit->AddFieldRVAToHash(iRecord) );
- }
- else
- {
- // <TODO>@FUTURE: more verification??</TODO>
- }
- }
- else
- {
- // bad lookup map
- _ASSERTE( !"bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
- // no need to record the index movement. FieldRVA is not a token.
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeFieldRVAs()
-
-
-//*****************************************************************************
-// Merge MethodImpl information
-//*****************************************************************************
-HRESULT NEWMERGER::MergeMethodImpls()
-{
- HRESULT hr = NOERROR;
- MethodImplRec *pRecImport = NULL;
- MethodImplRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- RID iRecord;
- mdTypeDef tkClassImp;
- mdToken tkBodyImp;
- mdToken tkDeclImp;
- TOKENREC *pTokenRecClass;
- mdToken tkBodyEmit;
- mdToken tkDeclEmit;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountMethodImpls();
-
- // loop through all the MethodImpls.
- for (i = 1; i <= iCount; i++)
- {
- // only merge those MethodImpls that are marked.
- if ( pMiniMdImport->GetFilterTable()->IsMethodImplMarked(i) == false)
- continue;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetMethodImplRecord(i, &pRecImport));
- tkClassImp = pMiniMdImport->getClassOfMethodImpl(pRecImport);
- tkBodyImp = pMiniMdImport->getMethodBodyOfMethodImpl(pRecImport);
- tkDeclImp = pMiniMdImport->getMethodDeclarationOfMethodImpl(pRecImport);
-
- if ( pCurTkMap->Find(tkClassImp, &pTokenRecClass))
- {
- // If the TypeDef is duplicated, no need to move over the MethodImpl record.
- if ( !pTokenRecClass->m_isDuplicate )
- {
- // Create a new record and set the data.
-
- // <TODO>@FUTURE: We might want to consider changing the error for the remap into a continuable error.
- // Because we probably can continue merging for more data...</TODO>
-
- IfFailGo( pCurTkMap->Remap(tkBodyImp, &tkBodyEmit) );
- IfFailGo( pCurTkMap->Remap(tkDeclImp, &tkDeclEmit) );
- IfFailGo(pMiniMdEmit->AddMethodImplRecord(&pRecEmit, &iRecord));
- IfFailGo( pMiniMdEmit->PutToken(TBL_MethodImpl, MethodImplRec::COL_Class, pRecEmit, pTokenRecClass->m_tkTo) );
- IfFailGo( pMiniMdEmit->PutToken(TBL_MethodImpl, MethodImplRec::COL_MethodBody, pRecEmit, tkBodyEmit) );
- IfFailGo( pMiniMdEmit->PutToken(TBL_MethodImpl, MethodImplRec::COL_MethodDeclaration, pRecEmit, tkDeclEmit) );
- IfFailGo( pMiniMdEmit->AddMethodImplToHash(iRecord) );
- }
- else
- {
- // <TODO>@FUTURE: more verification on the duplicate??</TODO>
- }
- // No need to record the token movement, MethodImpl is not a token.
- }
- else
- {
- // either bad lookup map or bad metadata
- _ASSERTE(!"bad state");
- IfFailGo( META_E_BADMETADATA );
- }
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeMethodImpls()
-
-
-//*****************************************************************************
-// Merge PInvoke
-//*****************************************************************************
-HRESULT NEWMERGER::MergePinvoke()
-{
- HRESULT hr = NOERROR;
- ImplMapRec *pRecImport = NULL;
- ImplMapRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdModuleRef mrImp;
- mdModuleRef mrEmit;
- mdMethodDef mdImp;
- RID mdImplMap;
- TOKENREC *pTokenRecMR;
- TOKENREC *pTokenRecMD;
-
- USHORT usMappingFlags;
- LPCUTF8 szImportName;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountImplMaps();
-
- // loop through all ImplMaps
- for (i = 1; i <= iCount; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetImplMapRecord(i, &pRecImport));
-
- // Get the MethodDef token in the new space.
- mdImp = pMiniMdImport->getMemberForwardedOfImplMap(pRecImport);
-
- // only merge those MethodDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsMethodMarked(mdImp) == false)
- continue;
-
- // Get the ModuleRef token in the new space.
- mrImp = pMiniMdImport->getImportScopeOfImplMap(pRecImport);
-
- // map the token to the new scope
- if (pCurTkMap->Find(mrImp, &pTokenRecMR) == false)
- {
- // This should never fire unless the module refs weren't merged
- // before this code ran.
- _ASSERTE(!"Parent ModuleRef not found in MERGER::MergePinvoke. Bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
-
- // If the ModuleRef has been remapped to the "module token", we need to undo that
- // for the pinvokeimpl. A pinvoke can only have a ModuleRef for the ImportScope.
- mrEmit = pTokenRecMR->m_tkTo;
- if (mrEmit == MODULEDEFTOKEN)
- { // Yes, the ModuleRef has been remapped to the module token. So,
- // find the ModuleRef in the output scope; if it is not found, add
- // it.
- ModuleRefRec *pModRefImport;
- LPCUTF8 szNameImp;
- IfFailGo(pMiniMdImport->GetModuleRefRecord(RidFromToken(mrImp), &pModRefImport));
- IfFailGo(pMiniMdImport->getNameOfModuleRef(pModRefImport, &szNameImp));
-
- // does this ModuleRef already exist in the emit scope?
- hr = ImportHelper::FindModuleRef(pMiniMdEmit,
- szNameImp,
- &mrEmit);
-
- if (hr == CLDB_E_RECORD_NOTFOUND)
- { // No, it doesn't. Copy it over.
- ModuleRefRec *pModRefEmit;
- IfFailGo(pMiniMdEmit->AddModuleRefRecord(&pModRefEmit, (RID*)&mrEmit));
- mrEmit = TokenFromRid(mrEmit, mdtModuleRef);
-
- // Set ModuleRef Name.
- IfFailGo( pMiniMdEmit->PutString(TBL_ModuleRef, ModuleRefRec::COL_Name, pModRefEmit, szNameImp) );
- }
- else
- IfFailGo(hr);
- }
-
-
- if (pCurTkMap->Find(mdImp, &pTokenRecMD) == false)
- {
- // This should never fire unless the method defs weren't merged
- // before this code ran.
- _ASSERTE(!"Parent MethodDef not found in MERGER::MergePinvoke. Bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
-
-
- // Get copy of rest of data.
- usMappingFlags = pMiniMdImport->getMappingFlagsOfImplMap(pRecImport);
- IfFailGo(pMiniMdImport->getImportNameOfImplMap(pRecImport, &szImportName));
-
- // If the method associated with PInvokeMap is not duplicated, then don't bother to look up the
- // duplicated PInvokeMap information.
- if (pTokenRecMD->m_isDuplicate == true)
- {
- // Does the correct ImplMap entry exist in the emit scope?
- IfFailGo(pMiniMdEmit->FindImplMapHelper(pTokenRecMD->m_tkTo, &mdImplMap));
- }
- else
- {
- mdImplMap = mdTokenNil;
- }
- if (!InvalidRid(mdImplMap))
- {
- // Verify that the rest of the data is identical, else it's an error.
- IfFailGo(pMiniMdEmit->GetImplMapRecord(mdImplMap, &pRecEmit));
- _ASSERTE(pMiniMdEmit->getMemberForwardedOfImplMap(pRecEmit) == pTokenRecMD->m_tkTo);
- LPCSTR szImplMapImportName;
- IfFailGo(pMiniMdEmit->getImportNameOfImplMap(pRecEmit, &szImplMapImportName));
- if (pMiniMdEmit->getImportScopeOfImplMap(pRecEmit) != mrEmit ||
- pMiniMdEmit->getMappingFlagsOfImplMap(pRecEmit) != usMappingFlags ||
- strcmp(szImplMapImportName, szImportName))
- {
- // Mismatched p-invoke entries are found.
- _ASSERTE(!"Mismatched P-invoke entries during merge. Bad State!");
- IfFailGo(E_FAIL);
- }
- }
- else
- {
- IfFailGo(pMiniMdEmit->AddImplMapRecord(&pRecEmit, &mdImplMap));
-
- // Copy rest of data.
- IfFailGo( pMiniMdEmit->PutToken(TBL_ImplMap, ImplMapRec::COL_MemberForwarded, pRecEmit, pTokenRecMD->m_tkTo) );
- IfFailGo( pMiniMdEmit->PutToken(TBL_ImplMap, ImplMapRec::COL_ImportScope, pRecEmit, mrEmit) );
- IfFailGo( pMiniMdEmit->PutString(TBL_ImplMap, ImplMapRec::COL_ImportName, pRecEmit, szImportName) );
- pRecEmit->SetMappingFlags(usMappingFlags);
- IfFailGo( pMiniMdEmit->AddImplMapToHash(mdImplMap) );
- }
- }
- }
-
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergePinvoke()
-
-
-//*****************************************************************************
-// Merge StandAloneSigs
-//*****************************************************************************
-HRESULT NEWMERGER::MergeStandAloneSigs()
-{
- HRESULT hr = NOERROR;
- StandAloneSigRec *pRecImport = NULL;
- StandAloneSigRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- TOKENREC *pTokenRec;
- mdSignature saImp;
- mdSignature saEmit;
- bool fDuplicate;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
- PCOR_SIGNATURE rgSig;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountStandAloneSigs();
-
- // loop through all Signatures
- for (i = 1; i <= iCount; i++)
- {
- // only merge those Signatures that are marked
- if ( pMiniMdImport->GetFilterTable()->IsSignatureMarked(TokenFromRid(i, mdtSignature)) == false)
- continue;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetStandAloneSigRecord(i, &pRecImport));
- IfFailGo(pMiniMdImport->getSignatureOfStandAloneSig(pRecImport, &pbSig, &cbSig));
-
- // This is a signature containing the return type after count of args
- // convert rid contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Assembly import scope info.
- pMiniMdImport, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
- rgSig = ( PCOR_SIGNATURE ) qbSig.Ptr();
-
- hr = ImportHelper::FindStandAloneSig(
- pMiniMdEmit,
- rgSig,
- cbEmit,
- &saEmit );
- if ( hr == S_OK )
- {
- // find a duplicate
- fDuplicate = true;
- }
- else
- {
- // copy over
- fDuplicate = false;
- IfFailGo(pMiniMdEmit->AddStandAloneSigRecord(&pRecEmit, (ULONG *)&saEmit));
- saEmit = TokenFromRid(saEmit, mdtSignature);
- IfFailGo( pMiniMdEmit->PutBlob(TBL_StandAloneSig, StandAloneSigRec::COL_Signature, pRecEmit, rgSig, cbEmit));
- }
- saImp = TokenFromRid(i, mdtSignature);
-
- // Record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(saImp, fDuplicate, saEmit, &pTokenRec) );
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeStandAloneSigs()
-
-//*****************************************************************************
-// Merge MethodSpecs
-//*****************************************************************************
-HRESULT NEWMERGER::MergeMethodSpecs()
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdToken tk;
- ULONG iRecord;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // Loop through all MethodSpec
- iCount = pMiniMdImport->getCountMethodSpecs();
- for (i=1; i<=iCount; ++i)
- {
- MethodSpecRec *pRecImport;
- MethodSpecRec *pRecEmit;
- TOKENREC *pTokenRecMethod;
- TOKENREC *pTokenRecMethodNew;
- PCCOR_SIGNATURE pvSig;
- ULONG cbSig;
- CQuickBytes qbSig;
- ULONG cbEmit;
-
- // Only copy marked records.
- if (!pMiniMdImport->GetFilterTable()->IsMethodSpecMarked(i))
- continue;
-
- IfFailGo(pMiniMdImport->GetMethodSpecRecord(i, &pRecImport));
- tk = pMiniMdImport->getMethodOfMethodSpec(pRecImport);
-
- // Map the token to the new scope.
- if (pCurTkMap->Find(tk, &pTokenRecMethod) == false)
- {
- // This should never fire unless the TypeDefs/Refs weren't merged
- // before this code runs.
- _ASSERTE(!"MethodSpec method not found in MERGER::MergeGenericsInfo. Bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
- // Copy to output scope.
- IfFailGo(pMiniMdEmit->AddMethodSpecRecord(&pRecEmit, &iRecord));
- IfFailGo( pMiniMdEmit->PutToken(TBL_MethodSpec, MethodSpecRec::COL_Method, pRecEmit, pTokenRecMethod->m_tkTo));
-
- // Copy the signature, translating any embedded tokens.
- IfFailGo(pMiniMdImport->getInstantiationOfMethodSpec(pRecImport, &pvSig, &cbSig));
-
- // ...convert rid contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly scope information.
- pMiniMdImport, // The scope to merge into the emit scope.
- pvSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
-
- // ...persist the converted signature
- IfFailGo( pMiniMdEmit->PutBlob(TBL_MethodSpec, MethodSpecRec::COL_Instantiation, pRecEmit, qbSig.Ptr(), cbEmit) );
-
- IfFailGo( pCurTkMap->InsertNotFound(TokenFromRid(i, mdtMethodSpec), false,
- TokenFromRid(iRecord, mdtMethodSpec), &pTokenRecMethodNew) );
- }
- }
-
- ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeMethodSpecs()
-
-//*****************************************************************************
-// Merge DeclSecuritys
-//*****************************************************************************
-HRESULT NEWMERGER::MergeDeclSecuritys()
-{
- HRESULT hr = NOERROR;
- DeclSecurityRec *pRecImport = NULL;
- DeclSecurityRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdToken tkParentImp;
- TOKENREC *pTokenRec;
- void const *pValue;
- ULONG cbBlob;
- mdPermission pmImp;
- mdPermission pmEmit;
- bool fDuplicate;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountDeclSecuritys();
-
- // loop through all DeclSecurity
- for (i = 1; i <= iCount; i++)
- {
- // only merge those DeclSecurities that are marked
- if ( pMiniMdImport->GetFilterTable()->IsDeclSecurityMarked(TokenFromRid(i, mdtPermission)) == false)
- continue;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetDeclSecurityRecord(i, &pRecImport));
- tkParentImp = pMiniMdImport->getParentOfDeclSecurity(pRecImport);
- if ( pCurTkMap->Find(tkParentImp, &pTokenRec) )
- {
- if ( !pTokenRec->m_isDuplicate )
- {
- // If the parent is not duplicated, just copy over the custom value
- goto CopyPermission;
- }
- else
- {
- // Try to see if the Permission is there in the emit scope or not.
- // If not, move it over still
- if ( ImportHelper::FindPermission(
- pMiniMdEmit,
- pTokenRec->m_tkTo,
- pRecImport->GetAction(),
- &pmEmit) == S_OK )
- {
- // found a match
- // <TODO>@FUTURE: more verification??</TODO>
- fDuplicate = true;
- }
- else
- {
- // Parent is duplicated but the Permission is not. Still copy over the
- // Permission.
-CopyPermission:
- fDuplicate = false;
- IfFailGo(pMiniMdEmit->AddDeclSecurityRecord(&pRecEmit, (ULONG *)&pmEmit));
- pmEmit = TokenFromRid(pmEmit, mdtPermission);
-
- pRecEmit->Copy(pRecImport);
-
- // set the parent
- IfFailGo( pMiniMdEmit->PutToken(
- TBL_DeclSecurity,
- DeclSecurityRec::COL_Parent,
- pRecEmit,
- pTokenRec->m_tkTo) );
-
- // move over the CustomAttribute blob value
- IfFailGo(pMiniMdImport->getPermissionSetOfDeclSecurity(pRecImport, (const BYTE **)&pValue, &cbBlob));
- IfFailGo(pMiniMdEmit->PutBlob(
- TBL_DeclSecurity,
- DeclSecurityRec::COL_PermissionSet,
- pRecEmit,
- pValue,
- cbBlob));
- }
- }
- pmEmit = TokenFromRid(pmEmit, mdtPermission);
- pmImp = TokenFromRid(i, mdtPermission);
-
- // Record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(pmImp, fDuplicate, pmEmit, &pTokenRec) );
- }
- else
- {
- // bad lookup map
- _ASSERTE(!"bad state");
- IfFailGo( META_E_BADMETADATA );
- }
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeDeclSecuritys()
-
-
-//*****************************************************************************
-// Merge Strings
-//*****************************************************************************
-HRESULT NEWMERGER::MergeStrings()
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- for (UINT32 nIndex = 0; ;)
- {
- MetaData::DataBlob userString;
- UINT32 nNextIndex;
- UINT32 nEmitIndex;
-
- hr = pMiniMdImport->GetUserStringAndNextIndex(
- nIndex,
- &userString,
- &nNextIndex);
- IfFailGo(hr);
- if (hr == S_FALSE)
- { // We reached the last user string
- hr = S_OK;
- break;
- }
- _ASSERTE(hr == S_OK);
-
- // Skip empty strings
- if (userString.IsEmpty())
- {
- nIndex = nNextIndex;
- continue;
- }
-
- if (pMiniMdImport->GetFilterTable()->IsUserStringMarked(TokenFromRid(nIndex, mdtString)) == false)
- {
- // Process next user string in the heap
- nIndex = nNextIndex;
- continue;
- }
-
- IfFailGo(pMiniMdEmit->PutUserString(
- userString,
- &nEmitIndex));
-
- IfFailGo(pCurTkMap->InsertNotFound(
- TokenFromRid(nIndex, mdtString),
- false,
- TokenFromRid(nEmitIndex, mdtString),
- &pTokenRec));
-
- // Process next user string in the heap
- nIndex = nNextIndex;
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeStrings()
-
-// Helper method to merge the module-level security critical attributes
-// Strips all module-level security critical attribute [that won't be ultimately needed]
-// Returns:
-// FAILED(hr): Failure occurred retrieving metadata or parsing scopes
-// S_OK: Attribute should be merged into final output scope
-// S_FALSE: Attribute should be ignored/dropped from output scope
-HRESULT NEWMERGER::MergeSecurityCriticalModuleLevelAttributes(
- MergeImportData* pImportData, // import scope
- mdToken tkParentImp, // parent token with attribute
- TOKENREC* pTypeRec, // token record of attribute ctor
- mdToken mrSecurityTreatAsSafeAttributeCtor, // 'generic' TAS attribute token
- mdToken mrSecurityTransparentAttributeCtor, // 'generic' Transparent attribute token
- mdToken mrSecurityCriticalExplicitAttributeCtor, // 'generic' Critical attribute token
- mdToken mrSecurityCriticalEverythingAttributeCtor)
-{
- HRESULT hr = S_OK;
-
- // if ANY assembly-level critical attributes were specified, then we'll output
- // one assembly-level Critical(Explicit) attribute only
- // AND if this scope has tags
- if (ISSCS_Unknown != pImportData->m_isscsSecurityCriticalStatus)
- {
- _ASSERTE(ISSCS_Unknown != m_isscsSecurityCritical);
- // drop only assembly-level attributes
- TypeRefRec* pTypeRefRec;
- // metadata emitter
- CMiniMdRW* pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // if compiler is generating a module - then this will be a module token
- LPCSTR szTypeRefName;
- if (tkParentImp == MODULEDEFTOKEN ||
- // otherwise, if merging assemblies, we have a fake type ref called MODULE_CA_LOCATION
- (TypeFromToken(tkParentImp) == mdtTypeRef &&
- (IsAttributeFromNamespace(pMiniMdImport, tkParentImp,
- COR_COMPILERSERVICE_NAMESPACE, COR_MSCORLIB_NAME,
- &pTypeRefRec) == S_OK) &&
- (pMiniMdImport->getNameOfTypeRef(pTypeRefRec, &szTypeRefName) == S_OK) &&
- (strcmp(MODULE_CA_TYPENAME, szTypeRefName) == 0)))
- {
- // drop the TAS attribute (unless all scopes have TAS)
- if ( pTypeRec->m_tkTo == mrSecurityTreatAsSafeAttributeCtor )
- {
- if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityTreatAsSafe) ==
- ISSCS_SecurityTreatAsSafe)
- {
- _ASSERTE((pImportData->m_isscsSecurityCriticalStatus & ISSCS_SecurityTreatAsSafe) ==
- ISSCS_SecurityTreatAsSafe);
- return S_OK;
- }
- return S_FALSE;
- }
- // drop the Transparent attribute (unless all scopes have Transparent)
- else if (pTypeRec->m_tkTo == mrSecurityTransparentAttributeCtor)
- {
- if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityTransparent) ==
- ISSCS_SecurityTransparent)
- {
- _ASSERTE((pImportData->m_isscsSecurityCriticalStatus & ISSCS_SecurityTransparent) ==
- ISSCS_SecurityTransparent);
- return S_OK;
- }
- return S_FALSE;
- }
- else if (pTypeRec->m_tkTo == mrSecurityCriticalExplicitAttributeCtor)
- {
- // if NOT Critical Everything, then leave the Critical.Explicit attribute
- // the Critical.Explicit attribute will be used as the final global attribute
- if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityCriticalEverything) !=
- ISSCS_SecurityCriticalEverything)
- {
- _ASSERTE((pImportData->m_isscsSecurityCriticalStatus & ISSCS_SecurityCriticalExplicit) ==
- ISSCS_SecurityCriticalExplicit);
- return S_OK;
- }
- else
- {
- // drop this attribute
- return S_FALSE;
- }
- }
- else if (pTypeRec->m_tkTo == mrSecurityCriticalEverythingAttributeCtor)
- {
- // OPTIMIZATION: if all attributes are Critical.Everything,
- // then leave the global Critical attribute
- if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityCriticalEverything) ==
- ISSCS_SecurityCriticalEverything)
- {
- _ASSERTE((pImportData->m_isscsSecurityCriticalStatus & ISSCS_SecurityCriticalEverything) ==
- ISSCS_SecurityCriticalEverything);
- return S_OK;
- }
- else
- {
- // drop this attribute
- return S_FALSE;
- }
- }
- }
- }
-
- return hr;
-} // NEWMERGER::MergeSecurityCriticalModuleLevelAttributes
-
-// HELPER: Retrieve the meta-data info related to SecurityCritical
-HRESULT NEWMERGER::RetrieveStandardSecurityCriticalMetaData(
- mdAssemblyRef& tkMscorlib,
- mdTypeRef& securityEnum,
- BYTE*& rgSigBytesSecurityCriticalEverythingCtor,
- DWORD& dwSigEverythingSize,
- BYTE*& rgSigBytesSecurityCriticalExplicitCtor,
- DWORD& dwSigExplicitSize)
-{
- HRESULT hr = S_OK;
-
- CMiniMdRW* emit = GetMiniMdEmit();
-
- // get typeref for mscorlib
- BYTE pbMscorlibToken[] = COR_MSCORLIB_TYPEREF;
- BYTE* pCurr = rgSigBytesSecurityCriticalEverythingCtor;
-
- IfFailGo(ImportHelper::FindAssemblyRef(emit,
- COR_MSCORLIB_NAME,
- NULL,
- pbMscorlibToken,
- sizeof(pbMscorlibToken),
- asm_rmj,
- asm_rmm,
- asm_rup,
- asm_rpt,
- 0,
- &tkMscorlib));
-
- IfFailGo(m_pRegMetaEmit->DefineTypeRefByName(tkMscorlib,
- COR_SECURITYCRITICALSCOPE_ENUM_W,
- &securityEnum));
-
- // build the constructor sig that takes SecurityCriticalScope argument
- if (rgSigBytesSecurityCriticalEverythingCtor)
- {
- *pCurr++ = IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS;
- *pCurr++ = COR_SECURITYCRITICAL_CTOR_ARGCOUNT_SCOPE_EVERYTHING; // one argument to constructor
- *pCurr++ = ELEMENT_TYPE_VOID;
- *pCurr++ = ELEMENT_TYPE_VALUETYPE;
- pCurr += CorSigCompressToken(securityEnum, pCurr);
- dwSigEverythingSize = (DWORD)(pCurr - rgSigBytesSecurityCriticalEverythingCtor);
- _ASSERTE(dwSigEverythingSize <= COR_SECURITYCRITICAL_CTOR_SCOPE_SIG_MAX_SIZE);
- }
-
- // if Explicit ctor is requested
- if (rgSigBytesSecurityCriticalExplicitCtor)
- {
- // build the constructor sig that has NO arguments
- pCurr = rgSigBytesSecurityCriticalExplicitCtor;
- *pCurr++ = IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS;
- *pCurr++ = COR_SECURITYCRITICAL_CTOR_ARGCOUNT_NO_SCOPE; // no arguments to constructor
- *pCurr++ = ELEMENT_TYPE_VOID;
- dwSigExplicitSize = (DWORD)(pCurr - rgSigBytesSecurityCriticalExplicitCtor);
- _ASSERTE(dwSigExplicitSize <= COR_SECURITYCRITICAL_CTOR_NO_SCOPE_SIG_MAX_SIZE);
- }
-
-ErrExit:
- return hr;
-} // NEWMERGER::RetrieveStandardSecurityCriticalMetaData
-
-//*****************************************************************************
-// Merge CustomAttributes
-//*****************************************************************************
-HRESULT NEWMERGER::MergeCustomAttributes()
-{
-
- HRESULT hr = NOERROR;
- CustomAttributeRec *pRecImport = NULL;
- CustomAttributeRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdToken tkParentImp; // Token of attributed object (parent).
- TOKENREC *pTokenRec; // Parent's remap.
- mdToken tkType; // Token of attribute's type.
- TOKENREC *pTypeRec; // Type's remap.
- void const *pValue; // The actual value.
- ULONG cbBlob; // Size of the value.
- mdToken cvImp;
- mdToken cvEmit;
- bool fDuplicate;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- TypeRefRec *pTypeRefRec;
- ULONG cTypeRefRecs;
- mdToken mrSuppressMergeCheckAttributeCtor = mdTokenNil;
- mdToken mrSecurityCriticalExplicitAttributeCtor = mdTokenNil;
- mdToken mrSecurityCriticalEverythingAttributeCtor = mdTokenNil;
- mdToken mrSecurityTransparentAttributeCtor = mdTokenNil;
- mdToken mrSecurityTreatAsSafeAttributeCtor = mdTokenNil;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- // Find out the TypeRef referring to our library's System.CompilerServices.SuppressMergeCheckAttribute,
- // System.Security.SecurityCriticalAttribute, System.Security.SecurityTransparentAttribute, and
- // System.Security.SecurityTreatAsSafeAttibute
- cTypeRefRecs = pMiniMdEmit->getCountTypeRefs();
-
- { // retrieve global attribute TypeRefs
-
- mdAssemblyRef tkMscorlib = mdTokenNil;
- mdTypeRef securityEnum = mdTokenNil;
-
- NewArrayHolder<BYTE> rgSigBytesSecurityCriticalEverythingCtor(new (nothrow)BYTE[COR_SECURITYCRITICAL_CTOR_SCOPE_SIG_MAX_SIZE]);
- BYTE* pSigBytesSecurityCriticalEverythingCtor = rgSigBytesSecurityCriticalEverythingCtor.GetValue();
- IfFailGo((pSigBytesSecurityCriticalEverythingCtor == NULL)?E_OUTOFMEMORY:S_OK);
- DWORD dwSigEverythingSize = 0;
-
- NewArrayHolder<BYTE> rgSigBytesSecurityCriticalExplicitCtor(new (nothrow)BYTE[COR_SECURITYCRITICAL_CTOR_NO_SCOPE_SIG_MAX_SIZE]);
- BYTE* pSigBytesSecurityCriticalExplicitCtor = rgSigBytesSecurityCriticalExplicitCtor.GetValue();
- IfFailGo((pSigBytesSecurityCriticalExplicitCtor == NULL)?E_OUTOFMEMORY:S_OK);
- DWORD dwSigExplicitSize = 0;
-
- // retrieve security critical metadata info if necessary
- if(ISSCS_Unknown != m_isscsSecurityCritical)
- {
-
- hr = RetrieveStandardSecurityCriticalMetaData(
- tkMscorlib,
- securityEnum,
- pSigBytesSecurityCriticalEverythingCtor,
- dwSigEverythingSize,
- pSigBytesSecurityCriticalExplicitCtor,
- dwSigExplicitSize);
-
- }
-
- // Search for the TypeRef.
- for (i = 1; i <= cTypeRefRecs; i++)
- {
- mdToken tkTmp = TokenFromRid(i,mdtTypeRef);
-
- if (IsAttributeFromNamespace(pMiniMdEmit, tkTmp,
- COR_COMPILERSERVICE_NAMESPACE, COR_MSCORLIB_NAME,
- &pTypeRefRec) == S_OK)
- {
- LPCSTR szNameOfTypeRef;
- IfFailGo(pMiniMdEmit->getNameOfTypeRef(pTypeRefRec, &szNameOfTypeRef));
- if (strcmp(szNameOfTypeRef, COR_SUPPRESS_MERGE_CHECK_ATTRIBUTE) == 0)
- {
- hr = ImportHelper::FindMemberRef(
- pMiniMdEmit, tkTmp,
- COR_CTOR_METHOD_NAME,
- NULL, 0,
- &mrSuppressMergeCheckAttributeCtor);
- if (S_OK == hr) continue;
- }
- }
- else
- // if we are merging security critical attributes, then look for transparent-related attributes
- if ((ISSCS_Unknown != m_isscsSecurityCritical) &&
- (IsAttributeFromNamespace(pMiniMdEmit, tkTmp,
- COR_SECURITYCRITICAL_ATTRIBUTE_NAMESPACE, COR_MSCORLIB_NAME,
- &pTypeRefRec) == S_OK))
- {
- LPCSTR szNameOfTypeRef;
- IfFailGo(pMiniMdEmit->getNameOfTypeRef(pTypeRefRec, &szNameOfTypeRef));
-
- // look for the SecurityCritical attribute
- if (strcmp(szNameOfTypeRef, COR_SECURITYCRITICAL_ATTRIBUTE) == 0)
- {
- // since the SecurityCritical attribute can be either
- // parameterless constructor or SecurityCriticalScope constructor, we
- // look for both
- hr = ImportHelper::FindMemberRef(
- pMiniMdEmit, tkTmp,
- COR_CTOR_METHOD_NAME,
- rgSigBytesSecurityCriticalEverythingCtor.GetValue(), dwSigEverythingSize,
- &mrSecurityCriticalEverythingAttributeCtor);
- if (S_OK == hr) continue;
- hr = ImportHelper::FindMemberRef(
- pMiniMdEmit, tkTmp,
- COR_CTOR_METHOD_NAME,
- rgSigBytesSecurityCriticalExplicitCtor.GetValue(), dwSigExplicitSize,
- &mrSecurityCriticalExplicitAttributeCtor);
- if (S_OK == hr) continue;
- }
- else
- // look for the SecurityTransparent attribute
- if (strcmp(szNameOfTypeRef, COR_SECURITYTRANSPARENT_ATTRIBUTE) == 0)
- {
- hr = ImportHelper::FindMemberRef(
- pMiniMdEmit, tkTmp,
- COR_CTOR_METHOD_NAME,
- NULL, 0,
- &mrSecurityTransparentAttributeCtor);
- if (S_OK == hr) continue;
- }
- else
- // look for the SecurityTreatAsSafe attribute
- if (strcmp(szNameOfTypeRef, COR_SECURITYTREATASSAFE_ATTRIBUTE) == 0)
- {
- hr = ImportHelper::FindMemberRef(
- pMiniMdEmit, tkTmp,
- COR_CTOR_METHOD_NAME,
- NULL, 0,
- &mrSecurityTreatAsSafeAttributeCtor);
- if (S_OK == hr) continue;
- }
- }
- hr = S_OK; // ignore failures since the attribute may not be used
- }
- }
-
- // Loop over every module scope
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountCustomAttributes();
-
- // loop through all CustomAttribute
- for (i = 1; i <= iCount; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetCustomAttributeRecord(i, &pRecImport));
- tkParentImp = pMiniMdImport->getParentOfCustomAttribute(pRecImport);
- tkType = pMiniMdImport->getTypeOfCustomAttribute(pRecImport);
- IfFailGo(pMiniMdImport->getValueOfCustomAttribute(pRecImport, (const BYTE **)&pValue, &cbBlob));
-
- // only merge those CustomAttributes that are marked
- if ( pMiniMdImport->GetFilterTable()->IsCustomAttributeMarked(TokenFromRid(i, mdtCustomAttribute)) == false)
- continue;
-
- // Check the type of the CustomAttribute. If it is not marked, then we don't need to move over the CustomAttributes.
- // This will only occur for compiler defined discardable CAs during linking.
- //
- if ( pMiniMdImport->GetFilterTable()->IsTokenMarked(tkType) == false)
- continue;
-
- if ( pCurTkMap->Find(tkParentImp, &pTokenRec) )
- {
- // If the From token type is different from the To token's type, we have optimized the ref to def.
- // In this case, we are dropping the CA associated with the Ref tokens.
- //
- if (TypeFromToken(tkParentImp) == TypeFromToken(pTokenRec->m_tkTo))
- {
-
- // If tkParentImp is a MemberRef and it is also mapped to a MemberRef in the merged scope with a MethodDef
- // parent, then it is a MemberRef optimized to a MethodDef. We are keeping the MemberRef because it is a
- // vararg call. So we can drop CAs on this MemberRef.
- if (TypeFromToken(tkParentImp) == mdtMemberRef)
- {
- MemberRefRec *pTempRec;
- IfFailGo(pMiniMdEmit->GetMemberRefRecord(RidFromToken(pTokenRec->m_tkTo), &pTempRec));
- if (TypeFromToken(pMiniMdEmit->getClassOfMemberRef(pTempRec)) == mdtMethodDef)
- continue;
- }
-
-
- if (! pCurTkMap->Find(tkType, &pTypeRec) )
- {
- _ASSERTE(!"CustomAttribute Type not found in output scope");
- IfFailGo(META_E_BADMETADATA);
- }
-
- // Determine if we need to copy or ignore security-critical-related attributes
- hr = MergeSecurityCriticalModuleLevelAttributes(
- pImportData, tkParentImp, pTypeRec,
- mrSecurityTreatAsSafeAttributeCtor, mrSecurityTransparentAttributeCtor,
- mrSecurityCriticalExplicitAttributeCtor,
- mrSecurityCriticalEverythingAttributeCtor);
- IfFailGo(hr);
- // S_FALSE means skip attribute
- if (hr == S_FALSE) continue;
- // S_OK means consider copying attribute
-
- // if it's the SuppressMergeCheckAttribute, don't copy it
- if ( pTypeRec->m_tkTo == mrSuppressMergeCheckAttributeCtor )
- {
- continue;
- }
-
- if ( pTokenRec->m_isDuplicate)
- {
- // Try to see if the custom value is there in the emit scope or not.
- // If not, move it over still
- hr = ImportHelper::FindCustomAttributeByToken(
- pMiniMdEmit,
- pTokenRec->m_tkTo,
- pTypeRec->m_tkTo,
- pValue,
- cbBlob,
- &cvEmit);
-
- if ( hr == S_OK )
- {
- // found a match
- // <TODO>@FUTURE: more verification??</TODO>
- fDuplicate = true;
- }
- else
- {
- TypeRefRec *pAttributeTypeRefRec;
- // We need to allow additive merge on TypeRef for CustomAttributes because compiler
- // could build module but not assembly. They are hanging of Assembly level CAs on a bogus
- // TypeRef.
- // Also allow additive merge for CAs from CompilerServices and Microsoft.VisualC
- if (tkParentImp == MODULEDEFTOKEN
- || TypeFromToken(tkParentImp) == mdtTypeRef
- || (IsAttributeFromNamespace(pMiniMdImport, tkType,
- COR_COMPILERSERVICE_NAMESPACE, COR_MSCORLIB_NAME,
- &pAttributeTypeRefRec) == S_OK)
- || (IsAttributeFromNamespace(pMiniMdImport, tkType,
- COR_MISCBITS_NAMESPACE, COR_MISCBITS_NAMESPACE,
- &pAttributeTypeRefRec) == S_OK))
- {
- // clear the error
- hr = NOERROR;
-
- // custom value of module token! Copy over the custom value
- goto CopyCustomAttribute;
- }
-
- // another case to support additive merge if the CA on MehtodDef is
- // HandleProcessCorruptedStateExceptionsAttribute
- if ( TypeFromToken(tkParentImp) == mdtMethodDef && tkType == pImportData->m_tkHandleProcessCorruptedStateCtor)
- {
- // clear the error
- hr = NOERROR;
-
- // custom value of module token! Copy over the custom value
- goto CopyCustomAttribute;
- }
- CheckContinuableErrorEx(META_E_MD_INCONSISTENCY, pImportData, TokenFromRid(i, mdtCustomAttribute));
- }
- }
- else
- {
-CopyCustomAttribute:
- if ((m_dwMergeFlags & DropMemberRefCAs) && TypeFromToken(pTokenRec->m_tkTo) == mdtMemberRef)
- {
- // CustomAttributes associated with MemberRef. If the parent of MemberRef is a MethodDef or FieldDef, drop
- // the custom attribute.
- MemberRefRec *pMemberRefRec;
- IfFailGo(pMiniMdEmit->GetMemberRefRecord(RidFromToken(pTokenRec->m_tkTo), &pMemberRefRec));
- mdToken mrParent = pMiniMdEmit->getClassOfMemberRef(pMemberRefRec);
- if (TypeFromToken(mrParent) == mdtMethodDef || TypeFromToken(mrParent) == mdtFieldDef)
- {
- // Don't bother to copy over
- continue;
- }
- }
-
- // Parent is duplicated but the custom value is not. Still copy over the
- // custom value.
- fDuplicate = false;
- IfFailGo(pMiniMdEmit->AddCustomAttributeRecord(&pRecEmit, (ULONG *)&cvEmit));
- cvEmit = TokenFromRid(cvEmit, mdtCustomAttribute);
-
- // set the parent
- IfFailGo( pMiniMdEmit->PutToken(TBL_CustomAttribute, CustomAttributeRec::COL_Parent, pRecEmit, pTokenRec->m_tkTo) );
- // set the type
- IfFailGo( pMiniMdEmit->PutToken(TBL_CustomAttribute, CustomAttributeRec::COL_Type, pRecEmit, pTypeRec->m_tkTo));
-
- // move over the CustomAttribute blob value
- IfFailGo(pMiniMdImport->getValueOfCustomAttribute(pRecImport, (const BYTE **)&pValue, &cbBlob));
-
- IfFailGo( pMiniMdEmit->PutBlob(TBL_CustomAttribute, CustomAttributeRec::COL_Value, pRecEmit, pValue, cbBlob));
- IfFailGo( pMiniMdEmit->AddCustomAttributesToHash(cvEmit) );
- }
- cvEmit = TokenFromRid(cvEmit, mdtCustomAttribute);
- cvImp = TokenFromRid(i, mdtCustomAttribute);
-
- // Record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(cvImp, pTokenRec->m_isDuplicate, cvEmit, &pTokenRec) );
- }
- }
- else
- {
-
- // either bad lookup map or bad metadata
- _ASSERTE(!"Bad state");
- IfFailGo( META_E_BADMETADATA );
- }
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeCustomAttributes()
-
-//*******************************************************************************
-// Helper to check if input scope has assembly-level security transparent awareness (either SecurityTransparent or SecurityCritical)
-// SIDE EFFECT: pImportData->m_isscsSecurityCriticalStatus will be explicitly set [same value as return value]
-// SecurityCritical.Explicit attribute injection occurs for all scopes that have tags (e.g. NOT ISSCS_Unknown)
-// If the tagged scopes are all SecurityCritical.Everything, then the final attribute should be SecurityCritical.Everything
-// anyway. Otherwise, at least one SecurityCritical.Explicit tag will be used/injected
-//*******************************************************************************
-InputScopeSecurityCriticalStatus NEWMERGER::CheckInputScopeIsCritical(MergeImportData* pImportData, HRESULT& hr)
-{
- hr = S_OK;
-
- // the attribute should be in a known state no matter how we return from this function
- // default to no attribute explicitly specified
- pImportData->m_isscsSecurityCriticalStatus = ISSCS_Unknown;
-
- mdTypeRef fakeModuleTypeRef = mdTokenNil;
- mdAssemblyRef tkMscorlib = mdTokenNil;
-
- // TODO: Should we remove the ability to disable merging critical attributes?
- if (g_fRefShouldMergeCriticalChecked == FALSE)
- {
- // shouldn't require thread safety lock
- g_fRefShouldMergeCritical = (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_MergeCriticalAttributes) != 0);
- g_fRefShouldMergeCriticalChecked = TRUE;
- }
-
- // return no merge needed, if the merge critical attribute setting is not enabled.
- if (!g_fRefShouldMergeCritical) return ISSCS_Unknown;
-
- // get typeref for mscorlib
- BYTE pbMscorlibToken[] = COR_MSCORLIB_TYPEREF;
-
- CMiniMdRW* pImportedMiniMd = &pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd;
-
- if (S_OK != ImportHelper::FindAssemblyRef(pImportedMiniMd,
- COR_MSCORLIB_NAME,
- NULL,
- pbMscorlibToken,
- sizeof(pbMscorlibToken),
- asm_rmj,
- asm_rmm,
- asm_rup,
- asm_rpt,
- 0,
- &tkMscorlib))
- {
- // there isn't an mscorlib ref here... we can't have the security critical attribute
- return ISSCS_Unknown;
- }
-
- if (S_OK != ImportHelper::FindTypeRefByName(pImportedMiniMd,
- tkMscorlib,
- COR_COMPILERSERVICE_NAMESPACE,
- MODULE_CA_TYPENAME,
- &fakeModuleTypeRef))
- {
- // for now let use the fake module ref as the assembly def
- fakeModuleTypeRef = 0x000001;
- }
-
- // Check the input scope for TreatAsSafe
- if (S_OK == ImportHelper::GetCustomAttributeByName(pImportedMiniMd,
- fakeModuleTypeRef, // This is the assembly def token
- COR_SECURITYTREATASSAFE_ATTRIBUTE_FULL,
- NULL,
- NULL))
- {
- pImportData->m_isscsSecurityCriticalStatus |= ISSCS_SecurityTreatAsSafe;
- }
-
- // Check the input scope for security transparency awareness
- // For example, the assembly is marked SecurityTransparent, SecurityCritical(Explicit), or SecurityCritical(Everything)
-
-
- const void *pbData = NULL; // [OUT] Put pointer to data here.
- ULONG cbData = 0; // number of bytes in pbData
-
- // Check if the SecurityTransparent attribute is present
- if (S_OK == ImportHelper::GetCustomAttributeByName(pImportedMiniMd,
- fakeModuleTypeRef, // This is the assembly def token
- COR_SECURITYTRANSPARENT_ATTRIBUTE_FULL,
- NULL,
- NULL))
- {
- pImportData->m_isscsSecurityCriticalStatus |= ISSCS_SecurityTransparent;
- }
- else
- // Check if the SecurityCritical attribute is present
- if (S_OK == ImportHelper::GetCustomAttributeByName(pImportedMiniMd,
- fakeModuleTypeRef, // This is the assembly def token
- COR_SECURITYCRITICAL_ATTRIBUTE_FULL,
- &pbData,
- &cbData))
- {
- // find out if critical everything or explicit
-
- // default to critical
- pImportData->m_isscsSecurityCriticalStatus = ISSCS_SecurityCritical;
-
- BYTE rgSecurityCriticalEverythingCtorValue[] = COR_SECURITYCRITICAL_ATTRIBUTE_VALUE_EVERYTHING;
- // if value is non-0 (i.e. 1), then mark as SecurityCritical everything, otherwise, explicit
- if (NULL != pbData && cbData == 8 &&
- memcmp(rgSecurityCriticalEverythingCtorValue, pbData, cbData) == 0)
- {
- pImportData->m_isscsSecurityCriticalStatus |= ISSCS_SecurityCriticalEverything;
- }
- else
- {
- pImportData->m_isscsSecurityCriticalStatus |= ISSCS_SecurityCriticalExplicit;
- }
- }
-
- return pImportData->m_isscsSecurityCriticalStatus;
-} // HRESULT NEWMERGER::CheckInputScopeIsCritical()
-
-//*******************************************************************************
-// Helper to merge security critical annotations across assemblies and types
-//*******************************************************************************
-HRESULT NEWMERGER::MergeSecurityCriticalAttributes()
-{
- // if no assembly-level critical attributes were specified, then none are needed,
- // and no need to do special attribute merging
- if (ISSCS_Unknown == m_isscsSecurityCritical)
- {
- return S_OK;
- }
- // or if the global-scope already has TAS/Critical.Everything, then ignore individual type fixes
- else if ((ISSCS_SECURITYCRITICAL_LEGACY & m_isscsSecurityCriticalAllScopes) == ISSCS_SECURITYCRITICAL_LEGACY)
- {
- return S_OK;
- }
-
- HRESULT hr = S_OK;
-
- CMiniMdRW* emit = GetMiniMdEmit();
- // The attribute we want to decorate all of the types with has not been defined.
- mdMemberRef tkSecurityCriticalEverythingAttribute = mdTokenNil;
- mdMemberRef tkSecurityTreatAsSafeAttribute = mdTokenNil;
- mdMemberRef tkSecuritySafeCriticalAttribute = mdTokenNil;
-
- mdAssemblyRef tkMscorlib = mdTokenNil;
- mdTypeRef fakeModuleTypeRef = mdTokenNil;
- mdTypeRef securityEnum = mdTokenNil;
-
- DWORD dwSigSize;
- BYTE* rgSigBytesSecurityCriticalExplicitCtor = 0;
- DWORD dwSigSize_TEMP;
-
- BYTE rgSigBytesTreatAsSafeCtor[] = {IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS, 0x00, ELEMENT_TYPE_VOID};
-
- BYTE rgSecurityCriticalEverythingCtorValue[] = COR_SECURITYCRITICAL_ATTRIBUTE_VALUE_EVERYTHING;
-
-
- mdTypeRef tkSecurityCriticalEverythingAttributeType = mdTokenNil;
- mdTypeRef tkSecurityTreatAsSafeAttributeType = mdTokenNil;
-
- NewArrayHolder<BYTE> rgSigBytesSecurityCriticalEverythingCtor(new (nothrow)BYTE[COR_SECURITYCRITICAL_CTOR_SCOPE_SIG_MAX_SIZE]);
- BYTE* pSigBytesSecurityCriticalEverythingCtor = rgSigBytesSecurityCriticalEverythingCtor.GetValue();
- IfFailGo((pSigBytesSecurityCriticalEverythingCtor == NULL)?E_OUTOFMEMORY:S_OK);
-
- IfFailGo(RetrieveStandardSecurityCriticalMetaData(
- tkMscorlib,
- securityEnum,
- pSigBytesSecurityCriticalEverythingCtor,
- dwSigSize,
- rgSigBytesSecurityCriticalExplicitCtor,
- dwSigSize_TEMP));
-
- if (S_OK != ImportHelper::FindTypeRefByName(emit,
- tkMscorlib,
- COR_COMPILERSERVICE_NAMESPACE,
- MODULE_CA_TYPENAME,
- &fakeModuleTypeRef))
- {
- // for now let use the fake module ref as the assembly def
- fakeModuleTypeRef = 0x000001;
- }
-
- IfFailGo(m_pRegMetaEmit->DefineTypeRefByName(
- tkMscorlib, COR_SECURITYCRITICAL_ATTRIBUTE_FULL_W, &tkSecurityCriticalEverythingAttributeType));
-
- IfFailGo(m_pRegMetaEmit->DefineMemberRef(tkSecurityCriticalEverythingAttributeType,
- COR_CONSTRUCTOR_METADATA_IDENTIFIER,
- rgSigBytesSecurityCriticalEverythingCtor.GetValue(),
- dwSigSize,
- &tkSecurityCriticalEverythingAttribute));
-
- IfFailGo(m_pRegMetaEmit->DefineTypeRefByName(
- tkMscorlib, COR_SECURITYTREATASSAFE_ATTRIBUTE_FULL_W,
- &tkSecurityTreatAsSafeAttributeType));
-
- IfFailGo(m_pRegMetaEmit->DefineMemberRef(tkSecurityTreatAsSafeAttributeType,
- COR_CONSTRUCTOR_METADATA_IDENTIFIER,
- rgSigBytesTreatAsSafeCtor,
- sizeof(rgSigBytesTreatAsSafeCtor),
- &tkSecurityTreatAsSafeAttribute));
-
-
- // place this block in a new scope so that we can safely goto past it
- {
- mdTypeRef tkSecuritySafeCriticalAttributeType = mdTokenNil;
- if (FAILED (hr = m_pRegMetaEmit->DefineTypeRefByName(tkMscorlib, COR_SECURITYSAFECRITICAL_ATTRIBUTE_FULL_W,
- &tkSecuritySafeCriticalAttributeType)))
- {
- _ASSERTE(!"Couldn't Emit a Typeref for SafeCritical attribute");
- return hr;
- }
-
- BYTE rgSigBytesSafeCriticalCtor[] = {IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS, 0x00, ELEMENT_TYPE_VOID};
- if (FAILED(hr = m_pRegMetaEmit->DefineMemberRef(tkSecuritySafeCriticalAttributeType,
- W(".ctor"),
- rgSigBytesSafeCriticalCtor,
- sizeof(rgSigBytesSafeCriticalCtor),
- &tkSecuritySafeCriticalAttribute)))
- {
- _ASSERTE(!"Couldn't Emit a MemberRef for SafeCritical attribute .ctor");
- return hr;
- }
- }
-
-
- for (MergeImportData* pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // if the import is marked TAS, then we need to explicitly mark each type as TAS
- // if the import is marked Crit/Everything, then we need to explicitly mark each type as Crit
- // if the import is not marked at all, then we need to explicitly mark each type TAS/Crit
-
- // if the import is marked ONLY Crit/Explicit or ONLY Transparent then we can ignore it
- if (ISSCS_SecurityTransparent == pImportData->m_isscsSecurityCriticalStatus ||
- ISSCS_SecurityCriticalExplicit == pImportData->m_isscsSecurityCriticalStatus) continue;
-
- // Run through the scopes that need to have their types decorated with this attribute
- MDTOKENMAP*pCurTKMap = pImportData->m_pMDTokenMap;
- BYTE rgTreatAsSafeCtorValue[] = COR_SECURITYTREATASSAFE_ATTRIBUTE_VALUE;
-
- BOOL fMarkEachTokenAsCritical = FALSE;
- // if the import is unmarked or marked Crit/Everything,
- // then we need to explicitly mark each token as Crit
- // Unless the the global scope already has SecurityCritical.Everything
- if (((ISSCS_SecurityCriticalEverything & m_isscsSecurityCriticalAllScopes) != ISSCS_SecurityCriticalEverything) &&
- (((ISSCS_SecurityCriticalEverything & pImportData->m_isscsSecurityCriticalStatus) == ISSCS_SecurityCriticalEverything ) ||
-
- // OR this scope is NOT transparent or critical-explicit
- (ISSCS_SecurityTransparent & pImportData->m_isscsSecurityCriticalStatus) == 0 ||
- (ISSCS_SecurityCritical & pImportData->m_isscsSecurityCriticalStatus) == 0 ||
-
- // OR this scope is UNKNOWN
- (ISSCS_Unknown == (ISSCS_SECURITYCRITICAL_FLAGS & pImportData->m_isscsSecurityCriticalStatus))))
- {
- fMarkEachTokenAsCritical = TRUE;
- }
-
- BOOL fMarkEachTokenAsSafe = FALSE;
- // if the import is unmarked or marked TAS,
- // then we need to explicitly mark each token as TAS
- // Unless the the global scope already has SecurityTreatAsSafe
- if (((ISSCS_SecurityTreatAsSafe & m_isscsSecurityCriticalAllScopes) != ISSCS_SecurityTreatAsSafe) &&
- ((ISSCS_SecurityTreatAsSafe & pImportData->m_isscsSecurityCriticalStatus) ||
- ISSCS_Unknown == (pImportData->m_isscsSecurityCriticalStatus & ISSCS_SECURITYCRITICAL_FLAGS)))
- {
- fMarkEachTokenAsSafe = TRUE;
- }
-
- BYTE rgSafeCriticalCtorValue[] = {0x01, 0x00, 0x00 ,0x00};
-
- for (int i = 0; i < pCurTKMap->Count(); i++)
- {
- TOKENREC* pRec = pCurTKMap->Get(i);
- BOOL fInjectSecurityAttributes = FALSE;
-
- // skip empty records
- if (pRec->IsEmpty()) continue;
-
- // If this scope contained a typeref that was resolved to a typedef, let's not mark it. We'll let the owner
- // of the actual typedef decide if that type should be marked.
- if ((TypeFromToken(pRec->m_tkFrom) == mdtTypeRef) && (TypeFromToken(pRec->m_tkTo) == mdtTypeDef))
- continue;
-
- // Same for method refs/method defs
- if ((TypeFromToken(pRec->m_tkFrom) == mdtMemberRef) && (TypeFromToken(pRec->m_tkTo) == mdtMethodDef))
- continue;
-
- // check for typedefs, but don't put this on the global typedef
- if ((TypeFromToken(pRec->m_tkTo) == mdtTypeDef) && (pRec->m_tkTo != TokenFromRid(1, mdtTypeDef)))
- {
- // by default we will inject
- fInjectSecurityAttributes = TRUE;
- // except for Enums
- DWORD dwClassAttrs = 0;
- mdTypeRef crExtends = mdTokenNil;
-
- if (FAILED(hr = m_pRegMetaEmit->GetTypeDefProps(pRec->m_tkTo, NULL, NULL, 0 , &dwClassAttrs, &crExtends)))
- {
- // TODO: should we fail ??
- }
-
- // check for Enum types
- if (!IsNilToken(crExtends) && (TypeFromToken(crExtends)==mdtTypeRef))
- {
- // get the namespace and the name for this token
- CMiniMdRW *pMiniMd = GetMiniMdEmit();
- TypeRefRec *pTypeRefRec;
- IfFailGo(pMiniMd->GetTypeRefRecord(RidFromToken(crExtends), &pTypeRefRec));
- LPCSTR szNamespace;
- LPCSTR szName;
- IfFailGo(pMiniMd->getNamespaceOfTypeRef(pTypeRefRec, &szNamespace));;
- IfFailGo(pMiniMd->getNameOfTypeRef(pTypeRefRec, &szName));
- // check for System.Enum
- BOOL bIsEnum = (!strcmp(szNamespace,"System"))&&(!strcmp(szName,"Enum"));
- if (bIsEnum)
- {
- fInjectSecurityAttributes = FALSE;
- }
- }
- }
- else // check for global method defs
- if (TypeFromToken(pRec->m_tkTo) == mdtMethodDef)
- {
- int isGlobal = 0;
- if (!FAILED(m_pRegMetaEmit->IsGlobal(pRec->m_tkTo, &isGlobal)))
- {
- // check for global methods
- if (isGlobal != 0)
- {
- fInjectSecurityAttributes = TRUE;
- }
- }
- }
-
- if (fInjectSecurityAttributes)
- {
- // check to see if the token already has a custom attribute
- const void *pbData = NULL; // [OUT] Put pointer to data here.
- ULONG cbData = 0;
-
- if (fMarkEachTokenAsCritical)
- {
- // Check if the Type already has SecurityCritical
- BOOL fInjectSecurityCriticalEverything = TRUE;
- if (S_OK == m_pRegMetaEmit->GetCustomAttributeByName(pRec->m_tkTo, COR_SECURITYCRITICAL_ATTRIBUTE_FULL_W, &pbData, &cbData))
- {
- // if value is non-0 (i.e. 1), then it is SecurityCritical.Everything - so do not inject another
- fInjectSecurityCriticalEverything = !(NULL != pbData && cbData == 8 &&
- memcmp(rgSecurityCriticalEverythingCtorValue, pbData, cbData) == 0);
- }
-
- // either inject or overwrite SecurityCritical.Everything
- if (fInjectSecurityCriticalEverything)
- {
- IfFailGo(m_pRegMetaEmit->DefineCustomAttribute(
- pRec->m_tkTo, tkSecurityCriticalEverythingAttribute,
- rgSecurityCriticalEverythingCtorValue, // Use this if you need specific custom attribute data (presence of the attribute isn't enough)
- sizeof(rgSecurityCriticalEverythingCtorValue), // Length of your custom attribute data
- NULL));
- }
- }
-
- // If the Type does NOT already have TAS then add it
- if (fMarkEachTokenAsSafe &&
- S_OK != m_pRegMetaEmit->GetCustomAttributeByName(pRec->m_tkTo, COR_SECURITYTREATASSAFE_ATTRIBUTE_FULL_W, &pbData, &cbData))
- {
- IfFailGo(m_pRegMetaEmit->DefineCustomAttribute(
- pRec->m_tkTo, tkSecurityTreatAsSafeAttribute,
- rgTreatAsSafeCtorValue, // Use this if you need specific custom attribute data (presence of the attribute isn't enough)
- sizeof(rgTreatAsSafeCtorValue), // Length of your custom attribute data
- NULL));
- }
-
- hr = m_pRegMetaEmit->DefineCustomAttribute(pRec->m_tkTo, tkSecuritySafeCriticalAttribute,
- rgSafeCriticalCtorValue, // Use this if you need specific custom attribute data (presence of the attribute isn't enough)
- sizeof(rgSafeCriticalCtorValue), // Length of your custom attribute data
- NULL);
-
- }
- }
- }
-
- // If the global scope is not Transparent, we should emit SecurityCritical.Explicit || Everything
- if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityTransparent) != ISSCS_SecurityTransparent &&
- (m_isscsSecurityCritical & ISSCS_SecurityCriticalEverything) != ISSCS_SecurityCriticalExplicit)
- {
- BOOL fEmitSecurityEverything = FALSE;
- // in the case of Unmarked and TAS/Unmarked, we need to emit the SecurityCritical.Everything attribute
- // if it hasn't already been emitted
- if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityCriticalEverything) ==
- ISSCS_SecurityCriticalEverything)
- {
- fEmitSecurityEverything = TRUE;
- }
- // otherwise, emit the SecurityCritical.Explicit attribute
-
- BOOL fSecurityCriticalExists = FALSE;
- // check to see if the assembly already has the appropriate SecurityCritical attribute
- // [from one of the input scopes]
- const void *pbData = NULL;
- ULONG cbData = 0;
- if (S_OK == ImportHelper::GetCustomAttributeByName(emit,
- fakeModuleTypeRef, // This is the assembly def token
- COR_SECURITYCRITICAL_ATTRIBUTE_FULL,
- &pbData,
- &cbData))
- {
- // find out if critical everything or explicit
- // default to critical
- // if value is non-0 (i.e. 1), then mark as SecurityCritical everything, otherwise, explicit
- if (NULL != pbData && cbData == 8 &&
- memcmp(rgSecurityCriticalEverythingCtorValue, pbData, cbData) == 0)
- {
- if (!fEmitSecurityEverything)
- {
- _ASSERTE(!"Unexpected SecurityCritical.Everything attribute detected");
- IfFailGo(META_E_BADMETADATA);
- }
- }
- else
- {
- if (fEmitSecurityEverything)
- {
- _ASSERTE(!"Unexpected SecurityCritical.Explicit attribute detected");
- IfFailGo(META_E_BADMETADATA);
- }
- }
- fSecurityCriticalExists = TRUE;
- }
-
- if (!fSecurityCriticalExists)
- {
- // retrieve the type and CustomAttribute
- mdCustomAttribute tkSecurityCriticalAttributeExplicit;
-
- mdTypeRef tkSecurityCriticalExplicitAttributeType = mdTokenNil;
-
- IfFailGo(m_pRegMetaEmit->DefineTypeRefByName(
- tkMscorlib, COR_SECURITYCRITICAL_ATTRIBUTE_FULL_W,
- &tkSecurityCriticalExplicitAttributeType));
-
- BYTE rgSigBytesSecurityCriticalExplicitCtorLocal[] = {IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS, 0x00, ELEMENT_TYPE_VOID};
- BYTE rgSecurityCriticalExplicitCtorValue[] = COR_SECURITYCRITICAL_ATTRIBUTE_VALUE_EXPLICIT;
-
- IfFailGo(m_pRegMetaEmit->DefineMemberRef(tkSecurityCriticalExplicitAttributeType,
- COR_CONSTRUCTOR_METADATA_IDENTIFIER,
- rgSigBytesSecurityCriticalExplicitCtorLocal,
- sizeof(rgSigBytesSecurityCriticalExplicitCtorLocal),
- &tkSecurityCriticalAttributeExplicit));
-
- IfFailGo(m_pRegMetaEmit->DefineCustomAttribute(
- fakeModuleTypeRef,
- fEmitSecurityEverything?tkSecurityCriticalEverythingAttribute:tkSecurityCriticalAttributeExplicit,
- fEmitSecurityEverything?rgSecurityCriticalEverythingCtorValue:rgSecurityCriticalExplicitCtorValue,
- fEmitSecurityEverything?sizeof(rgSecurityCriticalEverythingCtorValue):sizeof(rgSecurityCriticalExplicitCtorValue),
- NULL));
-
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeSecurityCriticalAttributes()
-
-//*******************************************************************************
-// Helper to copy an InterfaceImpl record
-//*******************************************************************************
-HRESULT NEWMERGER::CopyInterfaceImpl(
- InterfaceImplRec *pRecEmit, // [IN] the emit record to fill
- MergeImportData *pImportData, // [IN] the importing context
- InterfaceImplRec *pRecImp) // [IN] the record to import
-{
- HRESULT hr;
- mdToken tkParent;
- mdToken tkInterface;
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- CMiniMdRW *pMiniMdImp;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- tkParent = pMiniMdImp->getClassOfInterfaceImpl(pRecImp);
- tkInterface = pMiniMdImp->getInterfaceOfInterfaceImpl(pRecImp);
-
- IfFailGo( pCurTkMap->Remap(tkParent, &tkParent) );
- IfFailGo( pCurTkMap->Remap(tkInterface, &tkInterface) );
-
- IfFailGo( pMiniMdEmit->PutToken( TBL_InterfaceImpl, InterfaceImplRec::COL_Class, pRecEmit, tkParent) );
- IfFailGo( pMiniMdEmit->PutToken( TBL_InterfaceImpl, InterfaceImplRec::COL_Interface, pRecEmit, tkInterface) );
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyInterfaceImpl()
-
-
-//*****************************************************************************
-// Merge Assembly table
-//*****************************************************************************
-HRESULT NEWMERGER::MergeAssembly()
-{
- HRESULT hr = NOERROR;
- AssemblyRec *pRecImport = NULL;
- AssemblyRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- LPCUTF8 szTmp;
- const BYTE *pbTmp;
- ULONG cbTmp;
- ULONG iRecord;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- if (!pMiniMdImport->getCountAssemblys())
- goto ErrExit; // There is no Assembly in the import scope to merge.
-
- // Copy the Assembly map record to the Emit scope and send a token remap notifcation
- // to the client. No duplicate checking needed since the Assembly can be present in
- // only one scope and there can be atmost one entry.
- IfFailGo(pMiniMdImport->GetAssemblyRecord(1, &pRecImport));
- IfFailGo(pMiniMdEmit->AddAssemblyRecord(&pRecEmit, &iRecord));
-
- pRecEmit->Copy(pRecImport);
-
- IfFailGo(pMiniMdImport->getPublicKeyOfAssembly(pRecImport, &pbTmp, &cbTmp));
- IfFailGo(pMiniMdEmit->PutBlob(TBL_Assembly, AssemblyRec::COL_PublicKey, pRecEmit,
- pbTmp, cbTmp));
-
- IfFailGo(pMiniMdImport->getNameOfAssembly(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_Assembly, AssemblyRec::COL_Name, pRecEmit, szTmp));
-
- IfFailGo(pMiniMdImport->getLocaleOfAssembly(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_Assembly, AssemblyRec::COL_Locale, pRecEmit, szTmp));
-
- // record the token movement.
- IfFailGo(pCurTkMap->InsertNotFound(
- TokenFromRid(1, mdtAssembly),
- false,
- TokenFromRid(iRecord, mdtAssembly),
- &pTokenRec));
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeAssembly()
-
-
-
-
-//*****************************************************************************
-// Merge File table
-//*****************************************************************************
-HRESULT NEWMERGER::MergeFiles()
-{
- HRESULT hr = NOERROR;
- FileRec *pRecImport = NULL;
- FileRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- LPCUTF8 szTmp;
- const void *pbTmp;
- ULONG cbTmp;
- ULONG iCount;
- ULONG i;
- ULONG iRecord;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountFiles();
-
- // Loop through all File records and copy them to the Emit scope.
- // Since there can only be one File table in all the scopes combined,
- // there isn't any duplicate checking that needs to be done.
- for (i = 1; i <= iCount; i++)
- {
- IfFailGo(pMiniMdImport->GetFileRecord(i, &pRecImport));
- IfFailGo(pMiniMdEmit->AddFileRecord(&pRecEmit, &iRecord));
-
- pRecEmit->Copy(pRecImport);
-
- IfFailGo(pMiniMdImport->getNameOfFile(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_File, FileRec::COL_Name, pRecEmit, szTmp));
-
- IfFailGo(pMiniMdImport->getHashValueOfFile(pRecImport, (const BYTE **)&pbTmp, &cbTmp));
- IfFailGo(pMiniMdEmit->PutBlob(TBL_File, FileRec::COL_HashValue, pRecEmit, pbTmp, cbTmp));
-
- // record the token movement.
- IfFailGo(pCurTkMap->InsertNotFound(
- TokenFromRid(i, mdtFile),
- false,
- TokenFromRid(iRecord, mdtFile),
- &pTokenRec));
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeFiles()
-
-
-//*****************************************************************************
-// Merge ExportedType table
-//*****************************************************************************
-HRESULT NEWMERGER::MergeExportedTypes()
-{
- HRESULT hr = NOERROR;
- ExportedTypeRec *pRecImport = NULL;
- ExportedTypeRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- LPCUTF8 szTmp;
- mdToken tkTmp;
- ULONG iCount;
- ULONG i;
- ULONG iRecord;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountExportedTypes();
-
- // Loop through all ExportedType records and copy them to the Emit scope.
- // Since there can only be one ExportedType table in all the scopes combined,
- // there isn't any duplicate checking that needs to be done.
- for (i = 1; i <= iCount; i++)
- {
- IfFailGo(pMiniMdImport->GetExportedTypeRecord(i, &pRecImport));
- IfFailGo(pMiniMdEmit->AddExportedTypeRecord(&pRecEmit, &iRecord));
-
- pRecEmit->Copy(pRecImport);
-
- IfFailGo(pMiniMdImport->getTypeNameOfExportedType(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_ExportedType, ExportedTypeRec::COL_TypeName, pRecEmit, szTmp));
-
- IfFailGo(pMiniMdImport->getTypeNamespaceOfExportedType(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_ExportedType, ExportedTypeRec::COL_TypeNamespace, pRecEmit, szTmp));
-
- tkTmp = pMiniMdImport->getImplementationOfExportedType(pRecImport);
- IfFailGo(pCurTkMap->Remap(tkTmp, &tkTmp));
- IfFailGo(pMiniMdEmit->PutToken(TBL_ExportedType, ExportedTypeRec::COL_Implementation,
- pRecEmit, tkTmp));
-
-
- // record the token movement.
- IfFailGo(pCurTkMap->InsertNotFound(
- TokenFromRid(i, mdtExportedType),
- false,
- TokenFromRid(iRecord, mdtExportedType),
- &pTokenRec));
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeExportedTypes()
-
-
-//*****************************************************************************
-// Merge ManifestResource table
-//*****************************************************************************
-HRESULT NEWMERGER::MergeManifestResources()
-{
- HRESULT hr = NOERROR;
- ManifestResourceRec *pRecImport = NULL;
- ManifestResourceRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- LPCUTF8 szTmp;
- mdToken tkTmp;
- ULONG iCount;
- ULONG i;
- ULONG iRecord;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountManifestResources();
-
- // Loop through all ManifestResource records and copy them to the Emit scope.
- // Since there can only be one ManifestResource table in all the scopes combined,
- // there isn't any duplicate checking that needs to be done.
- for (i = 1; i <= iCount; i++)
- {
- IfFailGo(pMiniMdImport->GetManifestResourceRecord(i, &pRecImport));
- IfFailGo(pMiniMdEmit->AddManifestResourceRecord(&pRecEmit, &iRecord));
-
- pRecEmit->Copy(pRecImport);
-
- IfFailGo(pMiniMdImport->getNameOfManifestResource(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_ManifestResource, ManifestResourceRec::COL_Name,
- pRecEmit, szTmp));
-
- tkTmp = pMiniMdImport->getImplementationOfManifestResource(pRecImport);
- IfFailGo(pCurTkMap->Remap(tkTmp, &tkTmp));
- IfFailGo(pMiniMdEmit->PutToken(TBL_ManifestResource, ManifestResourceRec::COL_Implementation,
- pRecEmit, tkTmp));
-
- // record the token movement.
- IfFailGo(pCurTkMap->InsertNotFound(
- TokenFromRid(i, mdtManifestResource),
- false,
- TokenFromRid(iRecord, mdtManifestResource),
- &pTokenRec));
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeManifestResources()
-
-
-
-
-
-//*****************************************************************************
-// Error handling. Call back to host to see what they want to do.
-//*****************************************************************************
-HRESULT NEWMERGER::OnError(
- HRESULT hrIn, // The error HR we're reporting.
- MergeImportData *pImportData, // The input scope with the error.
- mdToken token) // The token with the error.
-{
- // This function does a QI and a Release on every call. However, it should be
- // called very infrequently, and lets the scope just keep a generic handler.
- IMetaDataError *pIErr = NULL;
- IUnknown *pHandler = pImportData->m_pHandler;
- CMiniMdRW *pMiniMd = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CQuickArray<WCHAR> rName; // Name of the TypeDef in unicode.
- LPCUTF8 szTypeName;
- LPCUTF8 szNSName;
- TypeDefRec *pTypeRec;
- int iLen; // Length of a name.
- mdToken tkParent;
- HRESULT hr = NOERROR;
-
- if (pHandler && pHandler->QueryInterface(IID_IMetaDataError, (void**)&pIErr)==S_OK)
- {
- switch (hrIn)
- {
-
- case META_E_PARAM_COUNTS:
- case META_E_METHD_NOT_FOUND:
- case META_E_METHDIMPL_INCONSISTENT:
- {
- LPCUTF8 szMethodName;
- MethodRec *pMethodRec;
-
- // Method name.
- _ASSERTE(TypeFromToken(token) == mdtMethodDef);
- IfFailGo(pMiniMd->GetMethodRecord(RidFromToken(token), &pMethodRec));
- IfFailGo(pMiniMd->getNameOfMethod(pMethodRec, &szMethodName));
- MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzMethodName, szMethodName);
- IfNullGo(wzMethodName);
-
- // Type and its name.
- IfFailGo( pMiniMd->FindParentOfMethodHelper(token, &tkParent) );
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
- PostError(hrIn, (LPWSTR) rName.Ptr(), wzMethodName, token);
- break;
- }
- case META_E_FIELD_NOT_FOUND:
- {
- LPCUTF8 szFieldName;
- FieldRec *pFieldRec;
-
- // Field name.
- _ASSERTE(TypeFromToken(token) == mdtFieldDef);
- IfFailGo(pMiniMd->GetFieldRecord(RidFromToken(token), &pFieldRec));
- IfFailGo(pMiniMd->getNameOfField(pFieldRec, &szFieldName));
- MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzFieldName, szFieldName);
- IfNullGo(wzFieldName);
-
- // Type and its name.
- IfFailGo( pMiniMd->FindParentOfFieldHelper(token, &tkParent) );
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
- PostError(hrIn, (LPWSTR) rName.Ptr(), wzFieldName, token);
- break;
- }
- case META_E_EVENT_NOT_FOUND:
- {
- LPCUTF8 szEventName;
- EventRec *pEventRec;
-
- // Event name.
- _ASSERTE(TypeFromToken(token) == mdtEvent);
- IfFailGo(pMiniMd->GetEventRecord(RidFromToken(token), &pEventRec));
- IfFailGo(pMiniMd->getNameOfEvent(pEventRec, &szEventName));
- MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzEventName, szEventName);
- IfNullGo(wzEventName);
-
- // Type and its name.
- IfFailGo( pMiniMd->FindParentOfEventHelper(token, &tkParent) );
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
- PostError(hrIn, (LPWSTR) rName.Ptr(), wzEventName, token);
- break;
- }
- case META_E_PROP_NOT_FOUND:
- {
- LPCUTF8 szPropertyName;
- PropertyRec *pPropertyRec;
-
- // Property name.
- _ASSERTE(TypeFromToken(token) == mdtProperty);
- IfFailGo(pMiniMd->GetPropertyRecord(RidFromToken(token), &pPropertyRec));
- IfFailGo(pMiniMd->getNameOfProperty(pPropertyRec, &szPropertyName));
- MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzPropertyName, szPropertyName);
- IfNullGo(wzPropertyName);
-
- // Type and its name.
- IfFailGo( pMiniMd->FindParentOfPropertyHelper(token, &tkParent) );
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
- PostError(hrIn, (LPWSTR) rName.Ptr(), wzPropertyName, token);
- break;
- }
- case META_S_PARAM_MISMATCH:
- {
- LPCUTF8 szMethodName;
- MethodRec *pMethodRec;
- mdToken tkMethod;
-
- // Method name.
- _ASSERTE(TypeFromToken(token) == mdtParamDef);
- IfFailGo( pMiniMd->FindParentOfParamHelper(token, &tkMethod) );
- IfFailGo(pMiniMd->GetMethodRecord(RidFromToken(tkMethod), &pMethodRec));
- IfFailGo(pMiniMd->getNameOfMethod(pMethodRec, &szMethodName));
- MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzMethodName, szMethodName);
- IfNullGo(wzMethodName);
-
- // Type and its name.
- IfFailGo( pMiniMd->FindParentOfMethodHelper(token, &tkParent) );
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
- // use the error hresult so that we can post the correct error.
- PostError(META_E_PARAM_MISMATCH, wzMethodName, (LPWSTR) rName.Ptr(), token);
- break;
- }
- case META_E_INTFCEIMPL_NOT_FOUND:
- {
- InterfaceImplRec *pRec; // The InterfaceImpl
- mdToken tkIface; // Token of the implemented interface.
- CQuickArray<WCHAR> rIface; // Name of the Implemented Interface in unicode.
- TypeRefRec *pRef; // TypeRef record when II is a typeref.
- InterfaceImplRec *pInterfaceImplRec;
-
- // Get the record.
- _ASSERTE(TypeFromToken(token) == mdtInterfaceImpl);
- IfFailGo(pMiniMd->GetInterfaceImplRecord(RidFromToken(token), &pRec));
- // Get the name of the class.
- tkParent = pMiniMd->getClassOfInterfaceImpl(pRec);
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
- // Get the name of the implemented interface.
- IfFailGo(pMiniMd->GetInterfaceImplRecord(RidFromToken(token), &pInterfaceImplRec));
- tkIface = pMiniMd->getInterfaceOfInterfaceImpl(pInterfaceImplRec);
- if (TypeFromToken(tkIface) == mdtTypeDef)
- { // If it is a typedef...
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkIface), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- }
- else
- { // If it is a typeref...
- _ASSERTE(TypeFromToken(tkIface) == mdtTypeRef);
- IfFailGo(pMiniMd->GetTypeRefRecord(RidFromToken(tkIface), &pRef));
- IfFailGo(pMiniMd->getNameOfTypeRef(pRef, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeRef(pRef, &szNSName));
- }
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rIface.ReSizeNoThrow(iLen+1));
- ns::MakePath(rIface.Ptr(), iLen+1, szNSName, szTypeName);
-
-
- PostError(hrIn, (LPWSTR) rName.Ptr(), (LPWSTR)rIface.Ptr(), token);
- break;
- }
- case META_E_CLASS_LAYOUT_INCONSISTENT:
- case META_E_METHOD_COUNTS:
- case META_E_FIELD_COUNTS:
- case META_E_EVENT_COUNTS:
- case META_E_PROPERTY_COUNTS:
- {
- // get the type name.
- _ASSERTE(TypeFromToken(token) == mdtTypeDef);
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(token), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
- PostError(hrIn, (LPWSTR) rName.Ptr(), token);
- break;
- }
- case META_E_GENERICPARAM_INCONSISTENT:
- {
- // If token is type, get type name; if method, get method name.
- LPWSTR wzName;
- LPCUTF8 szMethodName;
- MethodRec *pMethodRec;
-
- if ((TypeFromToken(token) == mdtMethodDef))
- {
- // Get the method name.
- IfFailGo(pMiniMd->GetMethodRecord(RidFromToken(token), &pMethodRec));
- IfFailGo(pMiniMd->getNameOfMethod(pMethodRec, &szMethodName));
- MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzMethodName, szMethodName);
- IfNullGo(wzMethodName);
- wzName = wzMethodName;
- }
- else
- {
- // Get the type name.
- _ASSERTE(TypeFromToken(token) == mdtTypeDef);
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(token), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
- wzName = (LPWSTR)rName.Ptr();
- }
-
- PostError(hrIn, wzName, token);
- break;
- }
- case META_E_TYPEDEF_MISSING:
- {
- TypeRefRec *pRef; // TypeRef record when II is a typeref.
-
- // Get the record.
- _ASSERTE(TypeFromToken(token) == mdtTypeRef);
- IfFailGo(pMiniMd->GetTypeRefRecord(RidFromToken(token), &pRef));
- IfFailGo(pMiniMd->getNameOfTypeRef(pRef, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeRef(pRef, &szNSName));
-
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
-
- PostError(hrIn, (LPWSTR) rName.Ptr(), token);
- break;
- }
- default:
- {
- PostError(hrIn, token);
- break;
- }
- }
- hr = pIErr->OnError(hrIn, token);
- }
- else
- hr = S_FALSE;
-ErrExit:
- if (pIErr)
- pIErr->Release();
- return (hr);
-} // NEWMERGER::OnError
-
-#endif //FEATURE_METADATA_EMIT_ALL
diff --git a/src/md/compiler/newmerger.h b/src/md/compiler/newmerger.h
deleted file mode 100644
index fc89ab7f61..0000000000
--- a/src/md/compiler/newmerger.h
+++ /dev/null
@@ -1,256 +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.
-//*****************************************************************************
-// NewMerger.h
-//
-
-//
-// Contains utility code for MD directory
-//
-//*****************************************************************************
-#ifndef __NEWMERGER__h__
-#define __NEWMERGER__h__
-
-class RegMeta;
-
-class MDTOKENMAP;
-
-// module-level awareness of Security critical annotions
-typedef BYTE InputScopeSecurityCriticalStatus;
-#define ISSCS_Unknown 0x0
-#define ISSCS_SecurityCritical 0x1
-#define ISSCS_SecurityCriticalEverything (ISSCS_SecurityCritical | 0x2)
-#define ISSCS_SecurityCriticalExplicit (ISSCS_SecurityCritical)
-#define ISSCS_SecurityTransparent 0x4
-#define ISSCS_SecurityTreatAsSafe 0x8
-#define ISSCS_SECURITYCRITICAL_LEGACY (ISSCS_SecurityCriticalEverything | ISSCS_SecurityTreatAsSafe)
-#define ISSCS_SECURITYCRITICAL_FLAGS (ISSCS_SecurityCriticalEverything | ISSCS_SecurityTransparent)
-
-//*********************************************************************
-// MergeImportData
-//*********************************************************************
-class MergeImportData
-{
-public:
- RegMeta *m_pRegMetaImport;
- IUnknown *m_pHandler;
- IMapToken *m_pHostMapToken;
- MDTOKENMAP *m_pMDTokenMap;
- MergeImportData *m_pNextImportData;
-
- mdMemberRef m_tkSuppressMergeCheckCtor; // caches the SuppressMergeCheckAttribute's .ctor token
- mdMemberRef m_tkHandleProcessCorruptedStateCtor; // caches the memberRef token to HandleProcessCorruptedStateExceptionsAttribute's .ctor token
-
- // import contains assembly-level SecurityTransparent or SecurityCritical
- InputScopeSecurityCriticalStatus m_isscsSecurityCriticalStatus;
-#if _DEBUG
- int m_iImport; // debug only. This is the ith import for merge.
-#endif // _DEBUG
-};
-
-//*********************************************************************
-// MergeTypeData
-//*********************************************************************
-struct MergeTypeData
-{
- ULONG m_cMethods;
- ULONG m_cFields;
- ULONG m_cEvents;
- ULONG m_cProperties;
- BOOL m_bSuppressMergeCheck;
-};
-
-
-//*********************************************************************
-// Class to handle merge
-//*********************************************************************
-class NEWMERGER
-{
- friend class RegMeta;
-public:
- NEWMERGER();
- ~NEWMERGER();
-
- HRESULT Init(RegMeta *pRegMetaDest);
-
- HRESULT AddImport(
- IMetaDataImport2 *pImport, // [IN] The scope to be merged.
- IMapToken *pHostMapToken, // [IN] Host IMapToken interface to receive token remap notification
- IUnknown *pHandler); // [IN] An object to receive to receive error notification.
-
- HRESULT Merge(MergeFlags flags, CorRefToDefCheck optimizeRefToDef);
-
-protected:
-
- CMiniMdRW *GetMiniMdEmit();
-
- HRESULT InitMergeTypeData();
-
- HRESULT MergeTypeDefNamesOnly();
- HRESULT MergeModuleRefs();
- HRESULT MergeAssemblyRefs();
- HRESULT MergeTypeRefs();
- HRESULT CompleteMergeTypeDefs();
-
- HRESULT CopyTypeDefPartially(
- TypeDefRec *pRecEmit, // [IN] the emit record to fill
- CMiniMdRW *pMiniMdImport, // [IN] the importing scope
- TypeDefRec *pRecImp); // [IN] the record to import
-
- // helpers for merging tables
- HRESULT MergeModule( );
- HRESULT MergeTypeDefChildren();
- HRESULT MergeInterfaceImpls( );
- HRESULT MergeMemberRefs( );
- HRESULT MergePinvoke();
-
- HRESULT MergeConstants( );
- HRESULT MergeCustomAttributes( );
- HRESULT MergeFieldMarshals( );
- HRESULT MergeDeclSecuritys( );
- HRESULT MergeClassLayouts( );
- HRESULT MergeFieldLayouts( );
- HRESULT MergeFieldRVAs();
- HRESULT MergeMethodImpls( );
- HRESULT MergeStandAloneSigs();
- HRESULT MergeMethodSpecs();
- HRESULT MergeTypeSpecs();
- HRESULT MergeSourceFiles( );
- HRESULT MergeBlocks( );
- HRESULT MergeScopes( );
- HRESULT MergeLocalVariables( );
- HRESULT MergeStrings( );
-
- HRESULT MergeAssembly();
- HRESULT MergeFiles();
- HRESULT MergeExportedTypes();
- HRESULT MergeManifestResources();
-
- // helpers for SecurityCritical-related merging
- InputScopeSecurityCriticalStatus CheckInputScopeIsCritical(MergeImportData* pImportData, HRESULT& hr);
- HRESULT RetrieveStandardSecurityCriticalMetaData(
- mdAssemblyRef& tkMscorlib,
- mdTypeRef& securityEnum,
- BYTE*& rgSigBytesSecurityCriticalEverythingCtor,
- DWORD& dwSigEverythingSize,
- BYTE*& rgSigBytesSecurityCriticalExplicitCtor,
- DWORD& dwSigExplicitSize);
-
- HRESULT MergeSecurityCriticalModuleLevelAttributes(
- MergeImportData* pImportData,
- mdToken tkParentImp, TOKENREC* pTypeRec,
- mdToken mrSecurityTreatAsSafeAttributeCtor,
- mdToken mrSecurityTransparentAttributeCtor,
- mdToken mrSecurityCriticalExplicitAttributeCtor,
- mdToken mrSecurityCriticalEverythingAttributeCtor);
- HRESULT MergeSecurityCriticalAttributes();
-
- // copy over a interfaceimpl record
- HRESULT CopyInterfaceImpl(
- InterfaceImplRec *pRecEmit, // [IN] the emit record to fill
- MergeImportData *pImportData, // [IN] the importing context
- InterfaceImplRec *pRecImp); // [IN] the record to import
-
- // verification helpers
- HRESULT VerifyMethods(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT VerifyFields(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT VerifyEvents(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT VerifyProperties(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT VerifyParams(MergeImportData *pImportData, mdMethodDef mdImp, mdMethodDef mdEmit);
- HRESULT VerifyGenericParams(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT VerifyGenericParamConstraints(MergeImportData *pImportData, mdGenericParam gpImp, mdGenericParam gpEmit);
-
- // Copy helpers
- HRESULT CopyMethods(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT CopyFields(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT CopyEvents(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT CopyProperties(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT CopyParams(MergeImportData *pImportData, mdMethodDef mdImp, mdMethodDef mdEmit);
- HRESULT CopyGenericParams(MergeImportData *pImportData, mdToken tkImp, mdToken tkEmit);
- HRESULT CopyGenericParamConstraints(MergeImportData *pImportData, mdGenericParam gpImp, mdGenericParam gpEmit);
-
- HRESULT CopyMethod(
- MergeImportData *pImportData, // [IN] import scope
- MethodRec *pRecImp, // [IN] the record to import
- MethodRec *pRecEmit); // [IN] the emit record to fill
-
- HRESULT CopyField(
- MergeImportData *pImportData, // [IN] import scope
- FieldRec *pRecImp, // [IN] the record to import
- FieldRec *pRecEmit); // [IN] the emit record to fill
-
- HRESULT CopyEvent(
- MergeImportData *pImportData, // [IN] import scope
- EventRec *pRecImp, // [IN] the record to import
- EventRec *pRecEmit); // [IN] the emit record to fill
-
- HRESULT CopyProperty(
- MergeImportData *pImportData, // [IN] import scope
- PropertyRec *pRecImp, // [IN] the record to import
- PropertyRec *pRecEmit); // [IN] the emit record to fill
-
- HRESULT CopyParam(
- MergeImportData *pImportData, // [IN] import scope
- ParamRec *pRecImp, // [IN] the record to import
- ParamRec *pRecEmit); // [IN] the emit record to fill
-
- HRESULT CopyMethodSemantics(
- MergeImportData *pImportData,
- mdToken tkImport, // Event or property in the import scope
- mdToken tkEmit); // corresponding event or property in the emitting scope
-
- HRESULT VerifyMethod(
- MergeImportData *pImportData,
- mdMethodDef mdImp, // [IN] the emit record to fill
- mdMethodDef mdEmit); // [IN] the record to import
-
- HRESULT OnError(HRESULT hr, MergeImportData *pImportData, mdToken token);
-
-private:
- RegMeta *m_pRegMetaEmit;
- MergeImportData *m_pImportDataList;
- MergeImportData **m_pImportDataTail;
- MergeFlags m_dwMergeFlags;
- BOOL m_fDupCheck;
- CorRefToDefCheck m_optimizeRefToDef;
- // the combined value of the Security Critical input scopes (e.g. UNION of each scope's attributes)
- // if ANY of the scopes have a bit set, then we must do some merging
- InputScopeSecurityCriticalStatus m_isscsSecurityCritical;
- // the common values of the Security Critical input scopes (e.g. INTERSECTION of each scope's attributes)
- // if all scopes have the same bit set, then we can emit one bit at the final output scope
- InputScopeSecurityCriticalStatus m_isscsSecurityCriticalAllScopes;
-
- CDynArray<MergeTypeData> m_rMTDs;
-#if _DEBUG
- int m_iImport; // debug only. To count how many import scopes to be merged.
-#endif // _DEBUG
-};
-
-
-#define CheckContinuableErrorEx(EXPR, HANDLER, TOKEN) \
-{ \
- HRESULT hrOnErr, hrExpr; \
- hrExpr = EXPR; \
- \
- hrOnErr = OnError(hrExpr, HANDLER, TOKEN); \
- if (hrOnErr != S_OK) \
- { \
- if (hrOnErr == S_FALSE) \
- { \
- hr = hrExpr; \
- } \
- else if (SUCCEEDED(hrOnErr)) \
- { \
- hr = E_UNEXPECTED; \
- } \
- else if (FAILED(hrOnErr)) \
- { \
- hr = hrOnErr; \
- } \
- IfFailGo(hr); \
- } \
-}
-
-
-#endif // __NEWMERGER__h__
diff --git a/src/md/compiler/regmeta.cpp b/src/md/compiler/regmeta.cpp
index feb1cdd31b..f591a6e01b 100644
--- a/src/md/compiler/regmeta.cpp
+++ b/src/md/compiler/regmeta.cpp
@@ -59,9 +59,6 @@ RegMeta::RegMeta() :
m_fIsTypeDefDirty(false),
m_fIsMemberDefDirty(false),
m_fStartedEE(false),
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- m_pCorHost(NULL),
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
m_pAppDomain(NULL),
m_OpenFlags(0),
m_cRef(0),
@@ -167,10 +164,6 @@ RegMeta::~RegMeta()
if (m_fStartedEE)
{
m_pAppDomain->Release();
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- m_pCorHost->Stop();
- m_pCorHost->Release();
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
if (m_pFilterManager != NULL)
@@ -284,11 +277,6 @@ RegMeta::CreateNewMD()
INDEBUG(m_pStgdb->m_MiniMd.Debug_SetLock(m_pSemReadWrite);)
}
-#ifdef FEATURE_METADATA_EMIT_ALL
- // initialize the embedded merger
- m_newMerger.Init(this);
-#endif //FEATURE_METADATA_EMIT_ALL
-
ErrExit:
return hr;
} // RegMeta::CreateNewMD
@@ -347,11 +335,6 @@ HRESULT RegMeta::OpenExistingMD(
if (!IsOfReOpen(dwOpenFlags))
{
-#ifdef FEATURE_METADATA_EMIT_ALL
- // initialize the embedded merger
- m_newMerger.Init(this);
-#endif //FEATURE_METADATA_EMIT_ALL
-
// There must always be a Global Module class and its the first entry in
// the TypeDef table.
m_tdModule = TokenFromRid(1, mdtTypeDef);
@@ -405,11 +388,6 @@ HRESULT RegMeta::OpenExistingMD(
if (!IsOfReOpen(dwOpenFlags))
{
-#ifdef FEATURE_METADATA_EMIT_ALL
- // initialize the embedded merger
- m_newMerger.Init(this);
-#endif //FEATURE_METADATA_EMIT_ALL
-
// There must always be a Global Module class and its the first entry in
// the TypeDef table.
m_tdModule = TokenFromRid(1, mdtTypeDef);
@@ -556,12 +534,10 @@ RegMeta::QueryInterface(
*ppUnk = static_cast<IMetaDataTables2 *>(this);
}
-#ifndef FEATURE_METADATA_STANDALONE_WINRT
else if (riid == IID_IMetaDataInfo)
{
*ppUnk = static_cast<IMetaDataInfo *>(this);
}
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
#ifdef FEATURE_METADATA_EMIT
else if (riid == IID_IMetaDataEmit)
@@ -581,12 +557,6 @@ RegMeta::QueryInterface(
}
#endif //FEATURE_METADATA_EMIT
-#if defined(FEATURE_METADATA_IN_VM) && !defined(FEATURE_CORECLR)
- else if (riid == IID_IMetaDataValidate)
- {
- *ppUnk = (IMetaDataValidate *)this;
- }
-#endif //defined(FEATURE_METADATA_IN_VM) && !defined(FEATURE_CORECLR)
#ifdef FEATURE_METADATA_EMIT_ALL
else if (riid == IID_IMetaDataFilter)
@@ -698,7 +668,6 @@ ErrExit:
return hr;
} // RegMeta::QueryInterface
-#ifndef FEATURE_METADATA_STANDALONE_WINRT
//---------------------------------------------------------------------------------------
//
@@ -794,7 +763,6 @@ ErrExit:
return hr;
} // RegMeta::GetFileMapping
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
//------------------------------------------------------------------------------
// Metadata dump
diff --git a/src/md/compiler/regmeta.h b/src/md/compiler/regmeta.h
index cb7bae17b5..04456d8548 100644
--- a/src/md/compiler/regmeta.h
+++ b/src/md/compiler/regmeta.h
@@ -20,16 +20,11 @@
#include "../inc/mdlog.h"
#include "utsem.h"
-#include "newmerger.h"
-
#include "rwutil.h"
#include "mdperf.h"
#include <ivehandler.h>
#include "sigparser.h"
-#ifdef FEATURE_FUSION
-#include "fusion.h"
-#endif
#include "winmdinterfaces.h"
@@ -155,9 +150,7 @@ class RegMeta :
public IMetaDataAssemblyImport,
public IMetaDataTables2
-#ifndef FEATURE_METADATA_STANDALONE_WINRT
, public IMetaDataInfo
-#endif
#ifdef FEATURE_METADATA_EMIT
, public IMetaDataEmit2
@@ -188,7 +181,6 @@ class RegMeta :
#endif
, public IMDCommon
{
- friend class NEWMERGER;
friend class CImportTlb;
friend class MDInternalRW;
friend class MDInternalRO;
@@ -1492,7 +1484,6 @@ public:
const void **ppv, // [OUT] put pointer to MD stream here.
ULONG *pcb); // [OUT] put size of the stream here.
-#ifndef FEATURE_METADATA_STANDALONE_WINRT
//*****************************************************************************
// IMetaDataInfo
@@ -1511,7 +1502,6 @@ public:
ULONGLONG * pcbData, // [out] Size of the mapped memory region..
DWORD * pdwMappingType); // [out] Type of file mapping (code:CorFileMapping).
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
#if defined(FEATURE_METADATA_IN_VM) && defined(FEATURE_PREJIT)
@@ -1633,8 +1623,6 @@ protected:
}
HRESULT PreSave();
- HRESULT ProcessFilter();
- HRESULT ProcessFilterWorker();
// Initialize the EE
HRESULT StartupEE();
@@ -2026,18 +2014,12 @@ protected:
bool m_fIsTypeDefDirty; // This flag is set when the TypeRef to TypeDef map is not valid
bool m_fIsMemberDefDirty; // This flag is set when the MemberRef to MemberDef map is not valid
bool m_fStartedEE; // Set when EE runtime has been started up.
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- ICorRuntimeHost *m_pCorHost; // Hosting environment for EE runtime.
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
IUnknown *m_pAppDomain; // AppDomain in which managed security code will be run.
private:
ULONG m_OpenFlags; // Open time flags.
LONG m_cRef; // Ref count.
-#ifdef FEATURE_METADATA_EMIT_ALL
- NEWMERGER m_newMerger; // class for handling merge
-#endif //FEATURE_METADATA_EMIT_ALL
IUnknown *m_pFreeThreadedMarshaler; // FreeThreadedMarshaler
#ifdef FEATURE_METADATA_PERF_STATS
@@ -2059,9 +2041,6 @@ private:
CorValidatorModuleType m_ModuleType;
IVEHandler *m_pVEHandler;
-#ifndef FEATURE_CORECLR
- ValidateRecordFunction m_ValidateRecordFunctionTable[TBL_COUNT];
-#endif
CCustAttrHash m_caHash; // Hashed list of custom attribute types seen.
bool m_bKeepKnownCa; // Should all known CA's be kept?
diff --git a/src/md/compiler/regmeta_compilersupport.cpp b/src/md/compiler/regmeta_compilersupport.cpp
index 0bea06699b..571f9288b6 100644
--- a/src/md/compiler/regmeta_compilersupport.cpp
+++ b/src/md/compiler/regmeta_compilersupport.cpp
@@ -49,35 +49,7 @@ STDMETHODIMP RegMeta::Merge( // S_OK or error.
IMapToken *pHostMapToken, // [IN] Host IMapToken interface to receive token remap notification
IUnknown *pHandler) // [IN] An object to receive to receive error notification.
{
-#ifdef FEATURE_METADATA_EMIT_ALL
- HRESULT hr = NOERROR;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- IMetaDataImport2 *pI2=NULL;
-
- LOG((LOGMD, "RegMeta::Merge(0x%08x, 0x%08x)\n", pImport, pHandler));
- START_MD_PERF();
- LOCKWRITE();
-
- IfFailGo(VerifyNotWinMD(pImport, "IMetaDataEmit::Merge(): merging with a .winmd file not supported."));
-
- IfFailGo(pImport->QueryInterface(IID_IMetaDataImport2, (void**)&pI2));
- m_hasOptimizedRefToDef = false;
-
- // track this import
- IfFailGo( m_newMerger.AddImport(pI2, pHostMapToken, pHandler) );
-
-ErrExit:
- if (pI2)
- pI2->Release();
- STOP_MD_PERF(Merge);
- END_ENTRYPOINT_NOTHROW;
-
- return (hr);
-#else //!FEATURE_METADATA_EMIT_ALL
return E_NOTIMPL;
-#endif //!FEATURE_METADATA_EMIT_ALL
} // RegMeta::Merge
@@ -86,32 +58,7 @@ ErrExit:
//*****************************************************************************
STDMETHODIMP RegMeta::MergeEnd() // S_OK or error.
{
-#ifdef FEATURE_METADATA_EMIT_ALL
- HRESULT hr = NOERROR;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- LOG((LOGMD, "RegMeta::MergeEnd()\n"));
- START_MD_PERF();
- LOCKWRITE();
- // Merge happens here!!
-
- // <REVISIT_TODO>bug 16719. Merge itself is doing a lots of small changes in literally
- // dozens of places. It would be to hard to maintain and would cause code
- // bloat to auto-grow the tables. So instead, we've opted to just expand
- // the world right away and avoid the trouble.</REVISIT_TODO>
- IfFailGo(m_pStgdb->m_MiniMd.ExpandTables());
-
- IfFailGo(m_newMerger.Merge(m_OptionValue.m_MergeOptions, m_OptionValue.m_RefToDefCheck) );
-
-ErrExit:
- STOP_MD_PERF(MergeEnd);
- END_ENTRYPOINT_NOTHROW;
-
- return (hr);
-#else //!FEATURE_METADATA_EMIT_ALL
return E_NOTIMPL;
-#endif //!FEATURE_METADATA_EMIT_ALL
} // RegMeta::MergeEnd
@@ -282,225 +229,4 @@ ErrExit:
#endif //!FEATURE_METADATA_EMIT_ALL
} // RegMeta::ResetENCLog
-#ifdef FEATURE_METADATA_EMIT_ALL
-
-// Helper for code:RegMeta::ProcessFilter
-HRESULT RegMeta::ProcessFilterWorker()
-{
- HRESULT hr = S_OK;
-
- CMiniMdRW *pMiniMd; // The MiniMd with the data.
- RegMeta *pMetaNew = NULL;
- CMapToken *pMergeMap = NULL;
- IMapToken *pMapNew = NULL;
- MergeTokenManager *pCompositHandler = NULL;
- IMapToken *pHostMapToken = NULL;
-
- // For convenience.
- pMiniMd = &(m_pStgdb->m_MiniMd);
- IfNullGo( pMiniMd->GetFilterTable() );
- _ASSERTE(pMiniMd->GetFilterTable()->Count() != 0); // caller verified this
-
- // Yes, client has used filter to specify what are the metadata needed.
- // We will create another instance of RegMeta and make this module an imported module
- // to be merged into the new RegMeta. We will provide the handler to track all of the token
- // movements. We will replace the merged light weight stgdb to this RegMeta..
- // Then we will need to fix up the MergeTokenManager with this new movement.
- // The reason that we decide to choose this approach is because it will be more complicated
- // and very likely less efficient to fix up the signature blob pool and then compact all of the pools!
- //
-
- // Create a new RegMeta.
- pMetaNew = new (nothrow) RegMeta();
- IfNullGo( pMetaNew );
- pMetaNew->AddRef();
- IfFailGo(pMetaNew->SetOption(&m_OptionValue));
-
-
- // Remember the open type.
- IfFailGo(pMetaNew->CreateNewMD());
- IfFailGo(pMetaNew->AddToCache());
-
- // Ignore the error return by setting handler
- hr = pMetaNew->SetHandler(m_pHandler);
-
- // create the IMapToken to receive token remap information from merge
- pMergeMap = new (nothrow) CMapToken;
- IfNullGo( pMergeMap );
-
- // use merge to filter out the unneeded data. But we need to keep COMType and also need to drop off the
- // CustomAttributes that associated with MemberRef with parent MethodDef
- //
- pMetaNew->m_hasOptimizedRefToDef = false;
- IfFailGo( pMetaNew->m_newMerger.AddImport(this, pMergeMap, NULL) );
- IfFailGo( pMetaNew->m_pStgdb->m_MiniMd.ExpandTables());
- IfFailGo( pMetaNew->m_newMerger.Merge((MergeFlags)(MergeManifest | DropMemberRefCAs | NoDupCheck), MDRefToDefDefault) );
-
- // Now we need to recalculate the token movement
- //
- if (m_newMerger.m_pImportDataList)
- {
-
- // This is the case the filter is applied to merged emit scope. We need calculate how this implicit merge
- // affects the original merge remap. Basically we need to walk all the m_pTkMapList in the merger and replace
- // the to token to the most recent to token.
- //
- MDTOKENMAP *pMDTokenMapList;
-
- pMDTokenMapList = m_newMerger.m_pImportDataList->m_pMDTokenMap;
-
- MDTOKENMAP *pMap;
- TOKENREC *pTKRec;
- ULONG i;
- mdToken tkFinalTo;
- ModuleRec *pMod;
- ModuleRec *pModNew;
- LPCUTF8 szName;
-
- // update each import map from merge to have the m_tkTo points to the final mapped to token
- for (pMap = pMDTokenMapList; pMap; pMap = pMap->m_pNextMap)
- {
- // update each record
- for (i = 0; i < (ULONG) (pMap->Count()); i++)
- {
- TOKENREC *pRecTo;
- pTKRec = pMap->Get(i);
- if ( pMergeMap->Find( pTKRec->m_tkTo, &pRecTo ) )
- {
- // This record is kept by the filter and the tkTo is changed
- pRecTo->m_isFoundInImport = true;
- tkFinalTo = pRecTo->m_tkTo;
- pTKRec->m_tkTo = tkFinalTo;
- pTKRec->m_isDeleted = false;
-
- // send the notification now. Because after merge, we may have everything in order and
- // won't send another set of notification.
- //
- LOG((LOGMD, "TokenRemap in RegMeta::ProcessFilter (IMapToken 0x%08x): from 0x%08x to 0x%08x\n", pMap->m_pMap, pTKRec->m_tkFrom, pTKRec->m_tkTo));
-
- pMap->m_pMap->Map(pTKRec->m_tkFrom, pTKRec->m_tkTo);
- }
- else
- {
- // This record is pruned by the filter upon save
- pTKRec->m_isDeleted = true;
- }
- }
- }
-
- // now walk the pMergeMap and check to see if there is any entry that is not set to true for m_isFoundInImport.
- // These are the records that from calling DefineXXX methods directly on the Emitting scope!
- if (m_pHandler)
- m_pHandler->QueryInterface(IID_IMapToken, (void **)&pHostMapToken);
- if (pHostMapToken)
- {
- for (i = 0; i < (ULONG) (pMergeMap->m_pTKMap->Count()); i++)
- {
- pTKRec = pMergeMap->m_pTKMap->Get(i);
- if (pTKRec->m_isFoundInImport == false)
- {
- LOG((LOGMD, "TokenRemap in RegMeta::ProcessFilter (default IMapToken 0x%08x): from 0x%08x to 0x%08x\n", pHostMapToken, pTKRec->m_tkFrom, pTKRec->m_tkTo));
-
- // send the notification on the IMapToken from SetHandler of this RegMeta
- pHostMapToken->Map(pTKRec->m_tkFrom, pTKRec->m_tkTo);
- }
- }
- }
-
- // Preserve module name across merge.
- IfFailGo(m_pStgdb->m_MiniMd.GetModuleRecord(1, &pMod));
- IfFailGo(pMetaNew->m_pStgdb->m_MiniMd.GetModuleRecord(1, &pModNew));
- IfFailGo(m_pStgdb->m_MiniMd.getNameOfModule(pMod, &szName));
- IfFailGo(pMetaNew->m_pStgdb->m_MiniMd.PutString(TBL_Module, ModuleRec::COL_Name, pModNew, szName));
-
- // now swap the stgdb but keep the merger...
- _ASSERTE( !IsOfExternalStgDB(m_OpenFlags) );
-
- CLiteWeightStgdbRW * pStgdbTmp = m_pStgdb;
- m_pStgdb = pMetaNew->m_pStgdb;
- pMetaNew->m_pStgdb = pStgdbTmp;
- // Update RuntimeVersion string pointers to point to the owning RegMeta string (the strings are 2 copies of the same string content)
- m_pStgdb->m_MiniMd.m_OptionValue.m_RuntimeVersion = m_OptionValue.m_RuntimeVersion;
- pMetaNew->m_pStgdb->m_MiniMd.m_OptionValue.m_RuntimeVersion = pMetaNew->m_OptionValue.m_RuntimeVersion;
- }
- else
- {
- // swap the Stgdb
- CLiteWeightStgdbRW * pStgdbTmp = m_pStgdb;
- m_pStgdb = pMetaNew->m_pStgdb;
- pMetaNew->m_pStgdb = pStgdbTmp;
- // Update RuntimeVersion string pointers to point to the owning RegMeta string (the strings are 2 copies of the same string content)
- m_pStgdb->m_MiniMd.m_OptionValue.m_RuntimeVersion = m_OptionValue.m_RuntimeVersion;
- pMetaNew->m_pStgdb->m_MiniMd.m_OptionValue.m_RuntimeVersion = pMetaNew->m_OptionValue.m_RuntimeVersion;
-
- // Client either open an existing scope and apply the filter mechanism, or client define the scope and then
- // apply the filter mechanism.
-
- // In this case, host better has supplied the handler!!
- _ASSERTE( m_bRemap && m_pHandler);
- IfFailGo( m_pHandler->QueryInterface(IID_IMapToken, (void **) &pMapNew) );
-
-
- {
- // Send the notification of token movement now because after merge we may not move tokens again
- // and thus no token notification will be send.
- MDTOKENMAP *pMap = pMergeMap->m_pTKMap;
- TOKENREC *pTKRec;
- ULONG i;
-
- for (i=0; i < (ULONG) (pMap->Count()); i++)
- {
- pTKRec = pMap->Get(i);
- pMap->m_pMap->Map(pTKRec->m_tkFrom, pTKRec->m_tkTo);
- }
-
- }
-
-
- // What we need to do here is create a IMapToken that will replace the original handler. This new IMapToken
- // upon called will first map the from token to the most original from token.
- //
- pCompositHandler = new (nothrow) MergeTokenManager(pMergeMap->m_pTKMap, NULL);
- IfNullGo( pCompositHandler );
-
- // now update the following field to hold on to the real IMapToken supplied by our client by SetHandler
- if (pMergeMap->m_pTKMap->m_pMap)
- pMergeMap->m_pTKMap->m_pMap->Release();
- _ASSERTE(pMapNew);
- pMergeMap->m_pTKMap->m_pMap = pMapNew;
-
- // ownership transferred
- pMergeMap = NULL;
- pMapNew = NULL;
-
- // now you want to replace all of the IMapToken set by calling SetHandler to this new MergeTokenManager
- IfFailGo( m_pStgdb->m_MiniMd.SetHandler(pCompositHandler) );
-
- m_pHandler = pCompositHandler;
-
- // ownership transferred
- pCompositHandler = NULL;
- }
-
- // Force a ref to def optimization because the remap information was stored in the thrown away CMiniMdRW
- m_hasOptimizedRefToDef = false;
- IfFailGo( RefToDefOptimization() );
-
-ErrExit:
- if (pHostMapToken)
- pHostMapToken->Release();
- if (pMetaNew)
- pMetaNew->Release();
- if (pMergeMap)
- pMergeMap->Release();
- if (pCompositHandler)
- pCompositHandler->Release();
- if (pMapNew)
- pMapNew->Release();
-
- return hr;
-} // RegMeta::ProcessFilter
-
-#endif //FEATURE_METADATA_EMIT_ALL
-
#endif //FEATURE_METADATA_EMIT
diff --git a/src/md/compiler/regmeta_emit.cpp b/src/md/compiler/regmeta_emit.cpp
index 22d2979343..d3268fec8a 100644
--- a/src/md/compiler/regmeta_emit.cpp
+++ b/src/md/compiler/regmeta_emit.cpp
@@ -279,13 +279,6 @@ STDMETHODIMP RegMeta::GetSaveSize( // S_OK or error.
IfFailGo(m_pFilterManager->Mark(TokenFromRid(iCount, mdtAssembly)));
}
}
-#ifdef FEATURE_METADATA_EMIT_ALL
- else if (m_newMerger.m_pImportDataList)
- {
- // always pipe through another pass of merge to drop unnecessary ref for linker.
- MarkAll();
- }
-#endif //FEATURE_METADATA_EMIT_ALL
IfFailGo(PreSave());
@@ -734,7 +727,6 @@ HRESULT RegMeta::PreSave() // Return code.
HRESULT hr = S_OK; // A result.
CMiniMdRW *pMiniMd; // The MiniMd with the data.
unsigned bRemapOld = m_bRemap;
- MergeTokenManager *ptkMgr = NULL;
// For convenience.
pMiniMd = &(m_pStgdb->m_MiniMd);
@@ -745,21 +737,6 @@ HRESULT RegMeta::PreSave() // Return code.
if (m_bSaveOptimized)
goto ErrExit;
-#ifdef FEATURE_METADATA_EMIT_ALL
- if (m_newMerger.m_pImportDataList != NULL)
- {
- // This is the linker scenario. We we have IMap for each scope. We will create an instance of our own mapper
- // who knows how to send notification back to host!
-
- // cache the host provided handler to the end our MergeTokenManager
-
- ptkMgr = new (nothrow) MergeTokenManager(m_newMerger.m_pImportDataList->m_pMDTokenMap, m_pHandler);
- IfNullGo(ptkMgr);
- hr = m_pStgdb->m_MiniMd.SetHandler(ptkMgr);
- _ASSERTE(SUCCEEDED(hr));
- }
-#endif //FEATURE_METADATA_EMIT_ALL
-
IfFailGo(RefToDefOptimization());
// we need to update MethodImpl table here with ref to def result
@@ -808,19 +785,7 @@ HRESULT RegMeta::PreSave() // Return code.
}
}
}
-
-#ifdef FEATURE_METADATA_EMIT_ALL
- IfFailGo(ProcessFilter());
-
- if (m_newMerger.m_pImportDataList != NULL)
- {
- // Allocate a token mapper object that will be used for phase 1 if there is not Handler but
- // linker has provided the IMapToken
- //
- m_bRemap = true;
- }
-#endif //FEATURE_METADATA_EMIT_ALL
-
+
// reget the minimd because it can be swapped in the call of ProcessFilter
pMiniMd = &(m_pStgdb->m_MiniMd);
@@ -831,13 +796,6 @@ HRESULT RegMeta::PreSave() // Return code.
IfFailGo(m_pStgdb->m_MiniMd.PreSave(m_ReorderingOptions, m_pCorProfileData));
ErrExit:
- if (ptkMgr != NULL)
- {
- // recovery the initial state
- hr = m_pStgdb->m_MiniMd.SetHandler(NULL);
- ptkMgr->Release();
- }
-
m_bRemap = bRemapOld;
return hr;
@@ -1008,37 +966,6 @@ ErrExit:
return hr;
} // RegMeta::RefToDefOptimization
-#ifdef FEATURE_METADATA_EMIT_ALL
-
-//*****************************************************************************
-// Process filter
-//*****************************************************************************
-HRESULT RegMeta::ProcessFilter()
-{
- HRESULT hr = S_OK;
-
- CMiniMdRW *pMiniMd; // The MiniMd with the data.
-
- START_MD_PERF();
-
- // For convenience.
- pMiniMd = &(m_pStgdb->m_MiniMd);
- IfNullGo( pMiniMd->GetFilterTable() );
- if ( pMiniMd->GetFilterTable()->Count() == 0 )
- {
- // there is no filter
- goto ErrExit;
- }
- hr = ProcessFilterWorker();
-
-ErrExit:
- STOP_MD_PERF(ProcessFilter);
-
- return hr;
-} // RegMeta::ProcessFilter
-
-#endif //FEATURE_METADATA_EMIT_ALL
-
//*****************************************************************************
// Define a TypeRef given the fully qualified name.
//*****************************************************************************
diff --git a/src/md/compiler/regmeta_vm.cpp b/src/md/compiler/regmeta_vm.cpp
index beebb08b5c..a4d9397b0e 100644
--- a/src/md/compiler/regmeta_vm.cpp
+++ b/src/md/compiler/regmeta_vm.cpp
@@ -29,23 +29,6 @@
#include <metamodelrw.h>
-#ifndef FEATURE_CORECLR
-
-#include <metahost.h>
-
-// Pointer to the activated CLR interface provided by the shim.
-extern ICLRRuntimeInfo *g_pCLRRuntime;
-
-#ifdef FEATURE_METADATA_EMIT_ALL
-
-#include "iappdomainsetup.h"
-
-// {27FFF232-A7A8-40dd-8D4A-734AD59FCD41}
-EXTERN_GUID(IID_IAppDomainSetup, 0x27FFF232, 0xA7A8, 0x40dd, 0x8D, 0x4A, 0x73, 0x4A, 0xD5, 0x9F, 0xCD, 0x41);
-
-#endif //FEATURE_METADATA_EMIT_ALL
-
-#endif // !FEATURE_CORECLR
#define DEFINE_CUSTOM_NODUPCHECK 1
@@ -66,7 +49,7 @@ EXTERN_GUID(IID_IAppDomainSetup, 0x27FFF232, 0xA7A8, 0x40dd, 0x8D, 0x4A, 0x73, 0
//*****************************************************************************
HRESULT RegMeta::AddToCache()
{
-#if defined(FEATURE_METADATA_IN_VM) || defined(FEATURE_METADATA_STANDALONE_WINRT)
+#if defined(FEATURE_METADATA_IN_VM)
HRESULT hr = S_OK;
// The ref count must be > 0 before the module is published, else another
@@ -83,9 +66,9 @@ ErrExit:
m_bCached = false;
}
return hr;
-#else //!FEATURE_METADATA_IN_VM && !FEATURE_METADATA_STANDALONE_WINRT
+#else // FEATURE_METADATA_IN_VM
return S_OK;
-#endif //!FEATURE_METADATA_IN_VM && !FEATURE_METADATA_STANDALONE_WINRT
+#endif // FEATURE_METADATA_IN_VM
} // RegMeta::AddToCache
@@ -97,13 +80,13 @@ HRESULT RegMeta::FindCachedReadOnlyEntry(
DWORD dwOpenFlags, // Flags the new file is opened with.
RegMeta **ppMeta) // Put found RegMeta here.
{
-#if defined(FEATURE_METADATA_IN_VM) || defined(FEATURE_METADATA_STANDALONE_WINRT)
+#if defined(FEATURE_METADATA_IN_VM)
return LOADEDMODULES::FindCachedReadOnlyEntry(szName, dwOpenFlags, ppMeta);
-#else //!FEATURE_METADATA_IN_VM && !FEATURE_METADATA_STANDALONE_WINRT
+#else // FEATURE_METADATA_IN_VM
// No cache support in standalone version.
*ppMeta = NULL;
return S_FALSE;
-#endif //!FEATURE_METADATA_IN_VM && !FEATURE_METADATA_STANDALONE_WINRT
+#endif // FEATURE_METADATA_IN_VM
} // RegMeta::FindCachedReadOnlyEntry
@@ -117,90 +100,8 @@ HRESULT RegMeta::FindCachedReadOnlyEntry(
//*****************************************************************************
HRESULT RegMeta::StartupEE()
{
-#ifdef FEATURE_CORECLR
UNREACHABLE_MSG_RET("About to CoCreateInstance! This code should not be "
"reachable or needs to be reimplemented for CoreCLR!");
-#else // !FEATURE_CORECLR
-
- struct Param
- {
- RegMeta *pThis;
- IUnknown *pSetup;
- IAppDomainSetup *pDomainSetup;
- bool fDoneStart;
- HRESULT hr;
- } param;
- param.pThis = this;
- param.pSetup = NULL;
- param.pDomainSetup = NULL;
- param.fDoneStart = false;
- param.hr = S_OK;
-
- PAL_TRY(Param *, pParam, &param)
- {
- HRESULT hr = S_OK;
-
- DWORD dwBuffer[1 + (MAX_LONGPATH+1) * sizeof(WCHAR) / sizeof(DWORD) + 1];
- BSTR bstrDir = NULL;
-
- // Create a hosting environment.
- IfFailGo(g_pCLRRuntime->GetInterface(
- CLSID_CorRuntimeHost,
- IID_ICorRuntimeHost,
- (void **)&pParam->pThis->m_pCorHost));
-
- // Startup the runtime.
- IfFailGo(pParam->pThis->m_pCorHost->Start());
- pParam->fDoneStart = true;
-
- // Create an AppDomain Setup so we can set the AppBase.
- IfFailGo(pParam->pThis->m_pCorHost->CreateDomainSetup(&pParam->pSetup));
-
- // Get the current directory (place it in a BSTR).
- bstrDir = (BSTR)(dwBuffer + 1);
- if ((dwBuffer[0] = (WszGetCurrentDirectory(MAX_LONGPATH + 1, bstrDir) * sizeof(WCHAR))))
- {
- // QI for the IAppDomainSetup interface.
- IfFailGo(pParam->pSetup->QueryInterface(IID_IAppDomainSetup,
- (void**)&pParam->pDomainSetup));
-
- // Set the AppBase.
- pParam->pDomainSetup->put_ApplicationBase(bstrDir);
- }
-
- // Create a new AppDomain.
- IfFailGo(pParam->pThis->m_pCorHost->CreateDomainEx(W("Compilation Domain"),
- pParam->pSetup,
- NULL,
- &pParam->pThis->m_pAppDomain));
-
- // That's it, we're all set up.
- _ASSERTE(pParam->pThis->m_pAppDomain != NULL);
- pParam->pThis->m_fStartedEE = true;
-
- ErrExit:
- pParam->hr = hr;
- }
- PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- _ASSERTE(!"Unexpected exception setting up hosting environment for security attributes");
- param.hr = E_FAIL;
- }
- PAL_ENDTRY
-
- // Cleanup temporary resources.
- if (m_pAppDomain && FAILED(param.hr))
- m_pAppDomain->Release();
- if (param.pDomainSetup)
- param.pDomainSetup->Release();
- if (param.pSetup)
- param.pSetup->Release();
- if (param.fDoneStart && FAILED(param.hr))
- m_pCorHost->Stop();
- if (m_pCorHost && FAILED(param.hr))
- m_pCorHost->Release();
- return param.hr;
-#endif // FEATURE_CORECLR
}
#endif //FEATURE_METADATA_EMIT_ALL
@@ -471,72 +372,16 @@ RegMeta::ResolveTypeRef(
goto ErrExit;
}
-#ifndef FEATURE_CORECLR
- wcscpy_s(rcModule, _MAX_PATH, wzNameSpace);
-
- //******************
- // Try to find the module on CORPATH
- //******************
-
- if ((wcsncmp(rcModule, W("System."), 16) != 0) &&
- (wcsncmp(rcModule, W("System/"), 16) != 0))
- {
- // only go through regular CORPATH lookup by fully qualified class name when
- // it is not System.*
- hr = CORPATHService::GetClassFromCORPath(
- rcModule,
- tr,
- pMiniMd,
- riid,
- ppIScope,
- ptd);
- }
- else
- {
- // force it to look for System.* in mscorlib.dll
- hr = S_FALSE;
- }
-
- if (hr == S_FALSE)
- {
- LPWSTR szTmp;
- WszSearchPath(
- NULL,
- W("mscorlib.dll"),
- NULL,
- sizeof(rcModule) / sizeof(rcModule[0]),
- rcModule,
- &szTmp);
-
- //*******************
- // Last desperate try!!
- //*******************
-
- // Use the file name "mscorlib:
- IfFailGo(CORPATHService::FindTypeDef(
- rcModule,
- tr,
- pMiniMd,
- riid,
- ppIScope,
- ptd));
- if (hr == S_FALSE)
- {
- IfFailGo(META_E_CANNOTRESOLVETYPEREF);
- }
- }
-#else //FEATURE_CORECLR
IfFailGo(META_E_CANNOTRESOLVETYPEREF);
-#endif //FEATURE_CORECLR
ErrExit:
STOP_MD_PERF(ResolveTypeRef);
END_ENTRYPOINT_NOTHROW;
return hr;
-#else //!FEATURE_METADATA_IN_VM
+#else // FEATURE_METADATA_IN_VM
return E_NOTIMPL;
-#endif //!FEATURE_METADATA_IN_VM
+#endif // FEATURE_METADATA_IN_VM
} // RegMeta::ResolveTypeRef
@@ -551,11 +396,11 @@ ULONG RegMeta::Release()
CONTRACT_VIOLATION (SOToleranceViolation);
BEGIN_CLEANUP_ENTRYPOINT;
-#if defined(FEATURE_METADATA_IN_VM) || defined(FEATURE_METADATA_STANDALONE_WINRT)
+#if defined(FEATURE_METADATA_IN_VM)
_ASSERTE(!m_bCached || LOADEDMODULES::IsEntryInList(this));
#else
_ASSERTE(!m_bCached);
-#endif //!FEATURE_METADATA_IN_VM && !FEATURE_METADATA_STANDALONE_WINRT
+#endif // FEATURE_METADATA_IN_VM
BOOL bCached = m_bCached;
ULONG cRef = InterlockedDecrement(&m_cRef);
// NOTE: 'this' may be unsafe after this point, if the module is cached, and
@@ -570,7 +415,7 @@ ULONG RegMeta::Release()
// discovered the module, so this thread can now safely delete it.
delete this;
}
-#if defined(FEATURE_METADATA_IN_VM) || defined(FEATURE_METADATA_STANDALONE_WINRT)
+#if defined(FEATURE_METADATA_IN_VM)
else if (LOADEDMODULES::RemoveModuleFromLoadedList(this))
{ // If the module was cached, RemoveModuleFromLoadedList() will try to
// safely un-publish the module, and if it succeeds, no other thread
@@ -578,7 +423,7 @@ ULONG RegMeta::Release()
m_bCached = false;
delete this;
}
-#endif //!FEATURE_METADATA_IN_VM && !FEATURE_METADATA_STANDALONE_WINRT
+#endif // FEATURE_METADATA_IN_VM
}
END_CLEANUP_ENTRYPOINT
diff --git a/src/md/compiler/wks/CMakeLists.txt b/src/md/compiler/wks/CMakeLists.txt
index 6bf6c80868..eb39ca7972 100644
--- a/src/md/compiler/wks/CMakeLists.txt
+++ b/src/md/compiler/wks/CMakeLists.txt
@@ -1,4 +1,6 @@
include(../../md_wks.cmake)
+add_definitions(-DFEATURE_METADATA_EMIT_ALL)
+
add_precompiled_header(stdafx.h ../stdafx.cpp MDCOMPILER_SOURCES)
-add_library_clr(mdcompiler_wks ${MDCOMPILER_SOURCES}) \ No newline at end of file
+add_library_clr(mdcompiler_wks ${MDCOMPILER_SOURCES})
diff --git a/src/md/enc/imptlb.cpp b/src/md/enc/imptlb.cpp
deleted file mode 100644
index faeb0d9882..0000000000
--- a/src/md/enc/imptlb.cpp
+++ /dev/null
@@ -1,8057 +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.
-// ===========================================================================
-// File: ImpTlb.CPP
-//
-
-//
-
-// ---------------------------------------------------------------
-// Who When What
-// ---------------------------------------------------------------
-// WGE 970906 Created
-//
-// ===========================================================================
-#include "stdafx.h"
-
-#include "imptlb.h"
-#include <posterror.h>
-#include <strongname.h>
-#include <nsutilpriv.h>
-
-#include "..\compiler\regmeta.h"
-#include "..\compiler\importhelper.h"
-#include "tlbutils.h" // For GenerateMangledTypeName().
-#include <tlbimpexp.h>
-#include "sstring.h"
-#include "strsafe.h"
-
-#include <metahost.h>
-
-// Pointer to the activated CLR interface provided by the shim.
-extern ICLRRuntimeInfo *g_pCLRRuntime;
-
-#ifdef wcsncmp
- #undef wcsncmp
-#endif
-#ifdef wcsncpy
- #undef wcsncpy
-#endif
-
-// deprecated: use the secureCrt replacements
-// _CRTIMP int __cdecl wcsncmp(const wchar_t *, const wchar_t *, size_t);
-// _CRTIMP wchar_t * __cdecl wcsncpy(wchar_t *, const wchar_t *, size_t);
-
-#define S_CONVERSION_LOSS _HRESULT_TYPEDEF_(3) // Non-error code meaning a conversion lost information.
-
-#define ADD_ITF_MEMBERS_TO_CLASS // Define to add interface members to the CoClass.
-#define ITF_MEMBER_RESOLUTION_NAMEONLY // Define to ignore signatures when looking for collisions (ie, when defined
- // void Foo(int) and void Foo(String) collide).
-
-// defines controlling ctor of non-creatable objects.
-#define NONCREATABLE_CTOR_VISIBILITY mdAssem // Define to a visibility flag.
-
-#define MAX_CLASSNAME_SIZE 1024
-
-#ifndef lengthof
-#define lengthof(rg) (sizeof(rg)/sizeof(rg[0]))
-#endif
-
-#ifndef IfNullGo
-#define IfNullGo(x) do {if (!(x)) IfFailGo(E_OUTOFMEMORY);} while (0)
-#endif
-
-#define BUILD_CUSTOM_ATTRIBUTE(type,bytes) {*reinterpret_cast<UNALIGNED type*>(__pca) = bytes; __pca += sizeof(type); _ASSERTE(__pca-__ca <= sizeof(__ca));}
-#define INIT_CUSTOM_ATTRIBUTE(n) {_ASSERTE((n) <= (sizeof(__ca)-sizeof(SHORT)));__pca = __ca; BUILD_CUSTOM_ATTRIBUTE(USHORT,1);}
-#define SIZEOF_CUSTOM_ATTRIBUTE() ((ULONG) (__pca - __ca))
-#define PTROF_CUSTOM_ATTRIBUTE() (&__ca[0])
-#define DECLARE_CUSTOM_ATTRIBUTE(n) BYTE __ca[(n)+sizeof(SHORT)*2], *__pca;__pca=__ca; INIT_CUSTOM_ATTRIBUTE(n);
-#define APPEND_STRING_TO_CUSTOM_ATTRIBUTE(str) {int l = (int)strlen(str); __pca=(BYTE*)CPackedLen::PutLength(__pca,l);memcpy(__pca,str,l);__pca+=l;}
-#define FINISH_CUSTOM_ATTRIBUTE() {BUILD_CUSTOM_ATTRIBUTE(short,0);}
-
-#define DECLARE_DYNLEN_CUSTOM_ATTRIBUTE(n) CQuickArray<BYTE> __tmpCAArray; IfFailGo(__tmpCAArray.ReSizeNoThrow(n + sizeof(SHORT)*2)); BYTE *__ca, *__pca; __ca = __tmpCAArray.Ptr(); __pca=__ca; BUILD_CUSTOM_ATTRIBUTE(USHORT,1);
-#define BUILD_DYNLEN_CUSTOM_ATTRIBUTE(type,bytes) {*reinterpret_cast<UNALIGNED type*>(__pca) = bytes; __pca += sizeof(type); _ASSERTE(__pca-__ca <= (int)__tmpCAArray.Size());}
-#define FINISH_DYNLEN_CUSTOM_ATTRIBUTE() {BUILD_DYNLEN_CUSTOM_ATTRIBUTE(short,0);}
-
-#define APPEND_WIDE_STRING_TO_CUSTOM_ATTRIBUTE(str) \
-{ \
- CQuickArray<char> __tmpStr; \
- int __cStr = WszWideCharToMultiByte(CP_ACP, 0, str, -1, 0, 0, NULL, NULL); \
- IfFailGo(__tmpStr.ReSizeNoThrow(__cStr)); \
- __cStr = WszWideCharToMultiByte(CP_ACP, 0, str, -1, __tmpStr.Ptr(), __cStr, NULL, NULL); \
- __pca=(BYTE*)CPackedLen::PutLength(__pca,__cStr); \
- memcpy(__pca,__tmpStr.Ptr(),__cStr); \
- __pca+=__cStr; \
-}
-
-// The maximum number of bytes the encoding of a DWORD can take.
-#define DWORD_MAX_CB 4
-
-// The maximum number of bytes the encoding of a DWORD can take.
-#define STRING_OVERHEAD_MAX_CB 4
-
-// Use the unused variant types m_knowntypes for common types.
-#define VT_SLOT_FOR_GUID VT_EMPTY
-#define VT_SLOT_FOR_IENUMERABLE VT_NULL
-#define VT_SLOT_FOR_MULTICASTDEL VT_I2
-#define VT_SLOT_FOR_TYPE VT_I4
-#define VT_SLOT_FOR_STRINGBUF VT_I8
-
-static LPCWSTR szObject = W("System.Object");
-static LPCWSTR szValueType = W("System.ValueType");
-static LPCWSTR szEnum = W("System.Enum");
-
-static LPCWSTR TLB_CLASSLIB_ARRAY = {W("System.Array")};
-static LPCWSTR TLB_CLASSLIB_DATE = {W("System.DateTime")};
-static LPCWSTR TLB_CLASSLIB_DECIMAL = {W("System.Decimal")};
-static LPCWSTR TLB_CLASSLIB_VARIANT = {W("System.Variant")};
-static LPCWSTR TLB_CLASSLIB_GUID = {W("System.Guid")};
-static LPCWSTR TLB_CLASSLIB_IENUMERABLE = {W("System.Collections.IEnumerable")};
-static LPCWSTR TLB_CLASSLIB_MULTICASTDELEGATE = {W("System.MulticastDelegate")};
-static LPCWSTR TLB_CLASSLIB_TYPE = {W("System.Type")};
-static LPCWSTR TLB_CLASSLIB_STRINGBUFFER = {W("System.Text.StringBuilder")};
-
-static LPCWSTR COM_STDOLE2 = {W("StdOle")};
-static LPCWSTR COM_GUID = {W("GUID")};
-
-static const LPCWSTR PROP_DECORATION_GET = {W("get_")};
-static const LPCWSTR PROP_DECORATION_SET = {W("set_")};
-static const LPCWSTR PROP_DECORATION_LET = {W("let_")};
-static const int PROP_DECORATION_LEN = 4;
-
-static const LPCWSTR DLL_EXTENSION = {W(".dll")};
-static const int DLL_EXTENSION_LEN = 4;
-static const LPCWSTR EXE_EXTENSION = {W(".exe")};
-static const int EXE_EXTENSION_LEN = 4;
-
-static LPCWSTR const OBJECT_INITIALIZER_NAME = {W(".ctor")};
-static const int OBJECT_INITIALIZER_FLAGS = mdPublic | mdSpecialName;
-static const int OBJECT_INITIALIZER_IMPL_FLAGS = miNative | miRuntime | miInternalCall;
-static const int NONCREATABLE_OBJECT_INITIALIZER_FLAGS = NONCREATABLE_CTOR_VISIBILITY | mdSpecialName;
-
-static const COR_SIGNATURE OBJECT_INITIALIZER_SIG[3] = {
- (IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS), 0, ELEMENT_TYPE_VOID };
-
-static const int DEFAULT_INTERFACE_FUNC_FLAGS = mdPublic | mdVirtual | mdAbstract | mdHideBySig | mdNewSlot;
-static const int DEFAULT_PROPERTY_FUNC_FLAGS = mdPublic | mdVirtual | mdAbstract | mdHideBySig | mdSpecialName | mdNewSlot;
-static const int DEFAULT_CONST_FIELD_FLAGS = fdPublic | fdStatic | fdLiteral;
-static const int DEFAULT_RECORD_FIELD_FLAGS = fdPublic;
-static const int DELEGATE_INVOKE_FUNC_FLAGS = mdPublic | mdVirtual;
-
-static const int DEFAULT_ITF_FUNC_IMPL_FLAGS = miNative | miRuntime | miInternalCall;
-
-static const WCHAR VTBL_GAP_FUNCTION[] = {W("_VtblGap")};
-static const int VTBL_GAP_FUNCTION_FLAGS = mdPublic | mdSpecialName;
-static const int VTBL_GAP_FUNC_IMPL_FLAGS = miRuntime;
-static const COR_SIGNATURE VTBL_GAP_SIGNATURE[] = {IMAGE_CEE_CS_CALLCONV_DEFAULT, 0, ELEMENT_TYPE_VOID};
-static const LPCWSTR VTBL_GAP_FORMAT_1 = {W("%ls%d")};
-static const LPCWSTR VTBL_GAP_FORMAT_N = {W("%ls%d_%d")};
-
-static const LPCWSTR ENUM_TYPE_NAME = {COR_ENUM_FIELD_NAME_W};
-static const DWORD ENUM_TYPE_FLAGS = fdPublic;
-static const COR_SIGNATURE ENUM_TYPE_SIGNATURE[] = {IMAGE_CEE_CS_CALLCONV_FIELD, ELEMENT_TYPE_I4};
-static const DWORD ENUM_TYPE_SIGNATURE_SIZE = lengthof(ENUM_TYPE_SIGNATURE);
-
-static const LPCWSTR DYNAMIC_NAMESPACE_NAME = {W("DynamicModule")};
-
-static const LPCWSTR UNSAFE_ITF_PREFIX = {W("Unsafe.")};
-
-static const LPCWSTR GET_ENUMERATOR_MEMBER_NAME = {W("GetEnumerator")};
-
-static const WCHAR CLASS_SUFFIX[] = {W("Class")};
-static const DWORD CLASS_SUFFIX_LENGTH = lengthof(CLASS_SUFFIX);
-static const WCHAR EVENT_ITF_SUFFIX[] = {W("_Event")};
-static const DWORD EVENT_ITF_SUFFIX_LENGTH = lengthof(EVENT_ITF_SUFFIX);
-static const WCHAR EVENT_PROVIDER_SUFFIX[] = {W("_EventProvider")};
-static const DWORD EVENT_PROVIDER_SUFFIX_LENGTH = lengthof(EVENT_ITF_SUFFIX);
-static const WCHAR EVENT_HANDLER_SUFFIX[] = {W("EventHandler")};
-static const DWORD EVENT_HANDLER_SUFFIX_LENGTH = lengthof(EVENT_HANDLER_SUFFIX);
-
-static const WCHAR EVENT_ADD_METH_PREFIX[] = {W("add_")};
-static const DWORD EVENT_ADD_METH_PREFIX_LENGTH = lengthof(EVENT_ADD_METH_PREFIX);
-static const WCHAR EVENT_REM_METH_PREFIX[] = {W("remove_")};
-static const DWORD EVENT_REM_METH_PREFIX_LENGTH = lengthof(EVENT_REM_METH_PREFIX);
-
-static const WCHAR DELEGATE_INVOKE_METH_NAME[] = {W("Invoke")};
-static const DWORD DELEGATE_INVOKE_METH_NAME_LENGTH = lengthof(EVENT_ADD_METH_PREFIX);
-
-// {C013B386-CC3E-4b6d-9B67-A3AE97274BBE}
-static const GUID FREE_STATUS_GUID =
-{ 0xc013b386, 0xcc3e, 0x4b6d, { 0x9b, 0x67, 0xa3, 0xae, 0x97, 0x27, 0x4b, 0xbe } };
-
-// {C013B387-CC3E-4b6d-9B67-A3AE97274BBE}
-static const GUID DELETED_STATUS_GUID =
-{ 0xc013b387, 0xcc3e, 0x4b6d, { 0x9b, 0x67, 0xa3, 0xae, 0x97, 0x27, 0x4b, 0xbe } };
-
-// {C013B388-CC3E-4b6d-9B67-A3AE97274BBE}
-static const GUID USED_STATUS_GUID =
-{ 0xc013b388, 0xcc3e, 0x4b6d, { 0x9b, 0x67, 0xa3, 0xae, 0x97, 0x27, 0x4b, 0xbe } };
-
-static const GUID IID_IEnumerable =
-{ 0x496b0abe, 0xcdee, 0x11d3, { 0x88, 0xe8, 0x00, 0x90, 0x27, 0x54, 0xc4, 0x3a } };
-
-
- #define STRUCTLAYOUT tdSequentialLayout
-// ULONG_MAX is a flag meaning "don't convert".
-static const ULONG rdwTypeFlags[] = {
- tdPublic | tdSealed, // TKIND_ENUM = 0,
- tdPublic | tdSealed | tdBeforeFieldInit | STRUCTLAYOUT, // TKIND_RECORD = TKIND_ENUM + 1,
- tdPublic | tdAbstract, // TKIND_MODULE = TKIND_RECORD + 1,
- tdPublic | tdInterface | tdAbstract | tdImport, // TKIND_INTERFACE = TKIND_MODULE + 1,
- tdPublic | tdInterface | tdAbstract | tdImport, // TKIND_DISPATCH = TKIND_INTERFACE + 1,
- tdPublic | tdImport, // TKIND_COCLASS = TKIND_DISPATCH + 1,
- tdPublic | tdImport, // TKIND_ALIAS = TKIND_COCLASS + 1,
- tdPublic | tdSealed | tdExplicitLayout, // TKIND_UNION = TKIND_ALIAS + 1,
- ULONG_MAX, // TKIND_MAX = TKIND_UNION + 1
-};
-static const LPCWSTR g_szTypekind[] = {
- W("Enum "),
- W("Record "),
- W("Module "),
- W("Interface "),
- W("Dispinterface"),
- W("Coclass "),
- W("Alias "),
- W("Union "),
-};
-
-#define NATIVE_TYPE_NONE ((CorNativeType)(NATIVE_TYPE_MAX+1))
-
-#define NON_CONVERTED_PARAMS_FLAGS (PARAMFLAG_FRETVAL|PARAMFLAG_FLCID)
-
-
-//*****************************************************************************
-// External declarations.
-//*****************************************************************************
-extern mdAssemblyRef DefineAssemblyRefForImportedTypeLib(
- void *pAssembly, // Assembly importing the typelib.
- void *pvModule, // Module importing the typelib.
- IUnknown *pIMeta, // IMetaData* from import module.
- IUnknown *pIUnk, // IUnknown to referenced Assembly.
- BSTR *pwzNamespace, // The namespace of the resolved assembly.
- BSTR *pwzAsmName, // The name of the resolved assembly.
- Assembly **AssemblyRef); // The resolved assembly.
-
-extern mdAssemblyRef DefineAssemblyRefForExportedAssembly(
- LPCWSTR szFullName, // Assembly full name.
- IUnknown *pIMeta); // Metadata emit interface.
-
-static HRESULT _UnpackVariantToConstantBlob(VARIANT *pvar, BYTE *pcvType, void **pvValue, __int64 *pd);
-static INT64 _DoubleDateToTicks(const double d);
-static HRESULT TryGetFuncDesc(ITypeInfo *pITI, int i, FUNCDESC **ppFunc);
-
-//*****************************************************************************
-// Class factory.
-//*****************************************************************************
-CImportTlb* CImportTlb::CreateImporter(
- LPCWSTR szLibrary,
- ITypeLib *pitlb,
- BOOL bGenerateTCEAdapters,
- BOOL bUnsafeInterfaces,
- BOOL bSafeArrayAsSystemArray,
- BOOL bTransformDispRetVals,
- BOOL bPreventClassMembers,
- BOOL bSerializableValueClasses)
-{
- return new (nothrow) CImportTlb(szLibrary, pitlb, bGenerateTCEAdapters, bUnsafeInterfaces, bSafeArrayAsSystemArray, bTransformDispRetVals, bPreventClassMembers, bSerializableValueClasses);
-} // CImportTlb* CImportTlb::CreateImporter()
-
-//*****************************************************************************
-// Default constructor.
-//*****************************************************************************
-CImportTlb::CImportTlb()
- : m_szLibrary(NULL),
- m_pITLB(NULL),
- m_bGenerateTCEAdapters(false),
- m_bSafeArrayAsSystemArray(false),
- m_bTransformDispRetVals(false),
- m_bPreventClassMembers(false),
- m_bSerializableValueClasses(false),
- m_pEmit(NULL),
- m_pImport(NULL),
- m_pITI(NULL),
- m_pOrigITI(NULL),
- m_psAttr(NULL),
- m_arSystem(mdAssemblyRefNil),
- m_Notify(NULL),
- m_trValueType(0),
- m_trEnum(0),
- m_bUnsafeInterfaces(FALSE),
- m_tkSuppressCheckAttr(mdTokenNil),
- m_tdHasDefault(0),
- m_szName(NULL),
- m_szMember(NULL),
- m_wzNamespace(NULL),
- m_tkInterface(0),
- m_szInterface(NULL),
- m_pMemberNames(NULL),
- m_cMemberProps(0),
- m_ImplIface(eImplIfaceNone)
-{
- // Clear the known types array. The values will be lazily initialized.
- memset(m_tkKnownTypes, 0, sizeof(m_tkKnownTypes));
- memset(m_tkAttr, 0, sizeof(m_tkAttr));
-} // CImportTlb::CImportTlb()
-
-//*****************************************************************************
-// Complex constructor.
-//*****************************************************************************
-CImportTlb::CImportTlb(
- LPCWSTR szLibrary, // Name of library being imported.
- ITypeLib *pitlb, // The type library to import from.
- BOOL bGenerateTCEAdapters, // A flag indicating if the TCE adapters are being generated.
- BOOL bUnsafeInterfaces, // A flag indicating that runtime security checks should be disabled
- BOOL bSafeArrayAsSystemArray,// A flag indicating whether to import SAFEARRAY's as System.Array's.
- BOOL bTransformDispRetVals, // A flag indicating if we should do [out,retval] transformation on disp only itfs.
- BOOL bPreventClassMembers, // A flag indicating if we should add members to CoClasses.
- BOOL bSerializableValueClasses) // A flag indicating if we should mark value classes serializable.
- : m_szLibrary(szLibrary),
- m_pITLB(pitlb),
- m_bGenerateTCEAdapters(bGenerateTCEAdapters),
- m_bUnsafeInterfaces(bUnsafeInterfaces),
- m_bSafeArrayAsSystemArray(bSafeArrayAsSystemArray),
- m_bTransformDispRetVals(bTransformDispRetVals),
- m_bPreventClassMembers(bPreventClassMembers),
- m_bSerializableValueClasses(bSerializableValueClasses),
- m_pEmit(0),
- m_pImport(0),
- m_pITI(0),
- m_pOrigITI(0),
- m_psAttr(0),
- m_arSystem(mdAssemblyRefNil),
- m_Notify(0),
- m_trValueType(0),
- m_trEnum(0),
- m_tkSuppressCheckAttr(mdTokenNil),
- m_tdHasDefault(0),
- m_szName(0),
- m_szMember(0),
- m_wzNamespace(0),
- m_tkInterface(0),
- m_szInterface(0),
- m_pMemberNames(0),
- m_cMemberProps(0),
- m_ImplIface(eImplIfaceNone)
-{
- if (pitlb)
- pitlb->AddRef();
-
- // Clear the known types array. The values will be lazily initialized.
- memset(m_tkKnownTypes, 0, sizeof(m_tkKnownTypes));
- memset(m_tkAttr, 0, sizeof(m_tkAttr));
-
-#if defined(TLB_STATS)
- m_bStats = QueryPerformanceFrequency(&m_freqVal);
-#endif
-} // CImportTlb::CImportTlb()
-
-//*****************************************************************************
-// Destructor.
-//*****************************************************************************
-CImportTlb::~CImportTlb()
-{
- if (m_pEmit)
- m_pEmit->Release();
- if (m_pImport)
- m_pImport->Release();
- if (m_pITLB)
- m_pITLB->Release();
- if (m_Notify)
- m_Notify->Release();
-
- if (m_wzNamespace)
- ::SysFreeString(m_wzNamespace);
-} // CImportTlb::~CImportTlb()
-
-
-//*****************************************************************************
-// Allow the user to specify a namespace to be used in the conversion.
-//*****************************************************************************
-HRESULT CImportTlb::SetNamespace(
- WCHAR const *pNamespace)
-{
- HRESULT hr=S_OK; // A result.
-
- IfNullGo(m_wzNamespace=::SysAllocString(pNamespace));
-
-ErrExit:
-
- return hr;
-} // HRESULT CImportTlb::SetNamespace()
-
-//*****************************************************************************
-// Allow the user to specify a notification object to be used in the conversion.
-//*****************************************************************************
-HRESULT CImportTlb::SetNotification(
- ITypeLibImporterNotifySink *pNotify)
-{
- _ASSERTE(m_Notify == 0);
- m_Notify = pNotify;
- pNotify->AddRef();
-
- return S_OK;
-} // HRESULT CImportTlb::SetNotification()
-
-//*****************************************************************************
-// Allow the user to specify the MetaData scope to be used in the conversion.
-//*****************************************************************************
-HRESULT CImportTlb::SetMetaData(
- IUnknown *pIUnk)
-{
- HRESULT hr;
- _ASSERTE(m_pEmit == 0);
- IfFailGo(pIUnk->QueryInterface(IID_IMetaDataEmit2, (void**)&m_pEmit));
-ErrExit:
- return hr;
-} // HRESULT CImportTlb::SetMetaData()
-
-//*****************************************************************************
-// Import a TypeLibrary into a CompLib.
-//*****************************************************************************
-HRESULT CImportTlb::Import()
-{
-#ifndef DACCESS_COMPILE
- HRESULT hr; // A result.
- mdModule md; // Module token.
- VARIANT vt = {0}; // For setting options.
- ITypeLib2 *pITLB2 = 0; // To get custom attributes.
- IMetaDataDispenserEx *pDisp = 0; // To create export scope.
- TLIBATTR *psAttr=0; // The library's attributes.
- BSTR szLibraryName = 0; // The library's name.
- LPCWSTR wzFile; // The filename of the typelib (no path).
- LPCWSTR wzSource; // Source of the typelib, for CA.
-
- _ASSERTE(m_Notify);
-
- // Quick sanity check.
- if (!m_pITLB)
- return (E_INVALIDARG);
-
- // Check to see if the type library implements ITypeLib2.
- if (m_pITLB->QueryInterface(IID_ITypeLib2, (void **)&pITLB2) != S_OK)
- pITLB2 = 0;
-
- // If custom attribute for namespace exists, use it.
- if (pITLB2)
- {
- VARIANT vt;
- VariantInit(&vt);
- if (pITLB2->GetCustData(GUID_ManagedName, &vt) == S_OK)
- {
- if (V_VT(&vt) == VT_BSTR)
- {
- // If there already was a namespace set, release it.
- if (m_wzNamespace)
- SysFreeString(m_wzNamespace);
-
- // If the namespace ends with .dll then remove the extension.
- LPWSTR pDest = wcsstr(vt.bstrVal, DLL_EXTENSION);
- if (pDest && (pDest[DLL_EXTENSION_LEN] == 0 || pDest[DLL_EXTENSION_LEN] == ' '))
- *pDest = 0;
-
- if (!pDest)
- {
- // If the namespace ends with .exe then remove the extension.
- pDest = wcsstr(vt.bstrVal, EXE_EXTENSION);
- if (pDest && (pDest[EXE_EXTENSION_LEN] == 0 || pDest[EXE_EXTENSION_LEN] == ' '))
- *pDest = 0;
- }
-
- if (pDest)
- {
- // We removed the extension so re-allocate a string of the new length.
- m_wzNamespace = SysAllocString(vt.bstrVal);
- SysFreeString(vt.bstrVal);
- IfNullGo(m_wzNamespace);
- }
- else
- {
- // There was no extension to remove so we can use the string returned
- // by GetCustData().
- m_wzNamespace = vt.bstrVal;
- }
- }
- else
- {
- VariantClear(&vt);
- }
- }
- }
-
- // Use the namespace name if we don't know the filename.
- if (!m_szLibrary)
- m_szLibrary = m_wzNamespace;
-
- // If the typelib was exported from COM+ to begin with, don't import it.
- if (pITLB2)
- {
- ::VariantInit(&vt);
- hr = pITLB2->GetCustData(GUID_ExportedFromComPlus, &vt);
- if (vt.vt != VT_EMPTY)
- {
- if (0)
- {
- // com emulates option is ON
- }
- else
- {
- IfFailGo(PostError(TLBX_E_CIRCULAR_IMPORT, m_szLibrary));
- }
- }
- }
-
- _ASSERTE(m_pEmit);
- IfFailGo(m_pEmit->QueryInterface(IID_IMetaDataImport2, (void **)&m_pImport));
-
- // Initialize the reserved names map.
- IfFailGo(m_ReservedNames.Init());
-
- // Initialize the default interface to class interface map for the TLB being imported.
- IfFailGo(m_DefItfToClassItfMap.Init(m_pITLB, m_wzNamespace));
-
- // Create the Object classref record and AssemblyRef for mscorlib.dll.
- IfFailGo(_DefineSysRefs());
-
- // Create the library record.
- IfFailGo(_NewLibraryObject());
-
- // Note that this was imported.
- IfFailGo(m_pITLB->GetLibAttr(&psAttr));
- if (SUCCEEDED(::QueryPathOfRegTypeLib(psAttr->guid, psAttr->wMajorVerNum, psAttr->wMinorVerNum, psAttr->lcid, &szLibraryName)))
- wzSource = szLibraryName;
- else
- wzSource = m_szLibrary;
-
- // We can't base the decision on SYSKIND. For example, we can have a SYS_WIN64 tlb loaded as 32-bit with 4-byte aligned pointers.
- m_cbVtableSlot = 0;
-
- IfFailGo(m_pImport->GetModuleFromScope(&md));
- // Skip the path or drive info
- wzFile = wcsrchr(wzSource, W('\\'));
- if (wzFile == 0)
- { // That's odd, should have been a fully qualified path. Just use an empty string.
- wzFile = W("");
- }
- else
- { // skip leading backslash
- wzFile++;
- }
-
- // Convert the typelib.
- IfFailGo(ConvertTypeLib());
-
-ErrExit:
- if (psAttr)
- m_pITLB->ReleaseTLibAttr(psAttr);
- if (szLibraryName)
- ::SysFreeString(szLibraryName);
- if (pITLB2)
- pITLB2->Release();
- if (pDisp)
- pDisp->Release();
-
- return (hr);
-#else
- DacNotImpl();
- return E_NOTIMPL;
-#endif // #ifndef DACCESS_COMPILE
-} // HRESULT CImportTlb::Import()
-
-//*****************************************************************************
-// Create the Complib to represent the TypeLib.
-//*****************************************************************************
-HRESULT CImportTlb::_NewLibraryObject()
-{
- HRESULT hr; // A result.
- TLIBATTR * psAttr=0; // The library's attributes.
- BSTR szLibraryName=0; // The library's name.
- CQuickArray<WCHAR> rScopeName; // The name of the scope.
-
- // Information about the library.
- IfFailGo(m_pITLB->GetLibAttr(&psAttr));
- IfFailGo(m_pITLB->GetDocumentation(MEMBERID_NIL, &szLibraryName, 0, 0, 0));
-
- // Create the scope name by using the typelib name and adding .dll.
- IfFailGo(rScopeName.ReSizeNoThrow(SysStringLen(szLibraryName) + 5 * sizeof(WCHAR)));
- StringCchPrintf(rScopeName.Ptr(), rScopeName.Size(), W("%s.dll"), szLibraryName);
-
- IfFailGo(m_pEmit->SetModuleProps(rScopeName.Ptr()));
-
-ErrExit:
- if (psAttr)
- m_pITLB->ReleaseTLibAttr(psAttr);
-
- if (szLibraryName)
- ::SysFreeString(szLibraryName);
-
- return (hr);
-} // HRESULT CImportTlb::_NewLibraryObject()
-
-//*****************************************************************************
-// Define an assembly ref for mscorlib, typeref for Object.
-//*****************************************************************************
-HRESULT CImportTlb::_DefineSysRefs()
-{
- HRESULT hr; // A result.
- WCHAR szPath[_MAX_PATH];
- WCHAR szDrive[_MAX_DRIVE];
- WCHAR szDir[_MAX_PATH];
- DWORD dwLen; // Length of system directory name.
- IMetaDataDispenserEx *pDisp = 0; // To import mscorlib.
- IMetaDataAssemblyImport *pAImp = 0; // To read mscorlib assembly.
- IMetaDataAssemblyEmit *pAEmit = 0; // To create mscorlib assembly ref.
- ASSEMBLYMETADATA amd = {0}; // Assembly metadata.
- mdToken tk; // A token.
- const void *pvPublicKey; // Public key.
- ULONG cbPublicKey; // Length of public key.
- BYTE *pbToken=0; // Compressed token for public key.
- ULONG cbToken; // Length of token.
- ULONG ulHashAlg; // Hash algorithm.
- DWORD dwFlags; // Assembly flags.
-
- // Get the dispenser.
- IfFailGo(g_pCLRRuntime->GetInterface(
- CLSID_CorMetaDataDispenser,
- IID_IMetaDataDispenserEx,
- (void **)&pDisp));
-
- // Get the name of mscorlib.
- //@todo: define, function, etc., instead of hard coded "mscorlib"
- dwLen = lengthof(szPath) - 13; // allow space for "mscorlib" ".dll" "\0"
- IfFailGo(pDisp->GetCORSystemDirectory(szPath, dwLen, &dwLen));
- SplitPath(szPath, szDrive, _MAX_DRIVE, szDir, _MAX_PATH, 0, 0, 0, 0);
- MakePath(szPath, szDrive, szDir, W("mscorlib"), W(".dll"));
-
- // Open the scope, get the details.
- IfFailGo(pDisp->OpenScope(szPath, 0, IID_IMetaDataAssemblyImport, (IUnknown**)&pAImp));
- IfFailGo(pAImp->GetAssemblyFromScope(&tk));
- IfFailGo(pAImp->GetAssemblyProps(tk, &pvPublicKey,&cbPublicKey, &ulHashAlg,
- szPath,lengthof(szPath),&dwLen, &amd, &dwFlags));
-
- if (!StrongNameTokenFromPublicKey((BYTE*)(pvPublicKey),cbPublicKey, &pbToken,&cbToken))
- {
- hr = StrongNameErrorInfo();
- goto ErrExit;
- }
- dwFlags &= ~afPublicKey;
-
- // Define the assembly ref.
- IfFailGo(m_pEmit->QueryInterface(IID_IMetaDataAssemblyEmit, (void**)&pAEmit));
- IfFailGo(pAEmit->DefineAssemblyRef(pbToken,cbToken, szPath, &amd,0,0,dwFlags, &m_arSystem));
-
- IfFailGo(m_TRMap.DefineTypeRef(m_pEmit, m_arSystem, szObject, &m_trObject));
-
- m_tkKnownTypes[VT_DISPATCH] = m_trObject;
- m_tkKnownTypes[VT_UNKNOWN] = m_trObject;
- m_tkKnownTypes[VT_VARIANT] = m_trObject;
-
-ErrExit:
- if (pbToken)
- StrongNameFreeBuffer(pbToken);
- if (pDisp)
- pDisp->Release();
- if (pAEmit)
- pAEmit->Release();
- if (pAImp)
- pAImp->Release();
-
- return hr;
-} // HRESULT CImportTlb::_DefineSysRefs()
-
-//*****************************************************************************
-// Lazily get the token for a CustomAttribute.
-//*****************************************************************************
-HRESULT CImportTlb::GetAttrType(
- int attr, // The attribute for which the type is desired.
- mdToken *pTk) // Put the type here.
-{
- HRESULT hr = S_OK; // A result.
- mdTypeRef tr; // An intermediate typeref.
- DWORD dwSigSize; // The size of the sig for special sigs.
- DWORD dwMaxSigSize; // The max size of the special sig.
- COR_SIGNATURE *pSig; // Pointer to the start of the sig,
- COR_SIGNATURE *pCurr; // Current sig pointer.
- mdTypeRef trType; // The typeref for System.Type.
-
- _ASSERTE(attr >= 0);
- _ASSERTE(attr < ATTR_COUNT);
-
- //@todo: globally define these names.
-#define INTEROP_ATTRIBUTE(x) static COR_SIGNATURE x##_SIG[] = INTEROP_##x##_SIG;
-#define INTEROP_ATTRIBUTE_SPECIAL(x)
- INTEROP_ATTRIBUTES();
-#undef INTEROP_ATTRIBUTE
-#undef INTEROP_ATTRIBUTE_SPECIAL
-#define INTEROP_ATTRIBUTE(x) \
- case ATTR_##x: \
- IfFailGo(m_pEmit->DefineTypeRefByName(m_arSystem, INTEROP_##x##_TYPE_W, &tr)); \
- IfFailGo(m_pEmit->DefineMemberRef(tr, W(".ctor"), x##_SIG, lengthof(x##_SIG), &m_tkAttr[attr])); \
- break;
-#define INTEROP_ATTRIBUTE_SPECIAL(x)
-
- if (IsNilToken(m_tkAttr[attr]))
- {
- switch (attr)
- {
- INTEROP_ATTRIBUTES();
-
- case ATTR_COMEVENTINTERFACE:
- {
- // Retrieve token for System.Type.
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_TYPE, &trType));
-
- // Build the sig.
- dwMaxSigSize = 5 + sizeof(mdTypeRef) * 2;
- pSig = (COR_SIGNATURE*)_alloca(dwMaxSigSize);
- pCurr = pSig;
- *pCurr++ = IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS;
- *pCurr++ = 2;
- *pCurr++ = ELEMENT_TYPE_VOID;
- *pCurr++ = ELEMENT_TYPE_CLASS;
- pCurr += CorSigCompressToken(trType, pCurr);
- *pCurr++ = ELEMENT_TYPE_CLASS;
- pCurr += CorSigCompressToken(trType, pCurr);
- dwSigSize = (DWORD)(pCurr - pSig);
- _ASSERTE(dwSigSize <= dwMaxSigSize);
-
- // Declare the typeref and the member ref for the CA.
- IfFailGo(m_pEmit->DefineTypeRefByName(m_arSystem, INTEROP_COMEVENTINTERFACE_TYPE_W, &tr)); \
- IfFailGo(m_pEmit->DefineMemberRef(tr, W(".ctor"), pSig, dwSigSize, &m_tkAttr[attr])); \
- break;
- }
-
- case ATTR_COCLASS:
- {
- // Retrieve token for System.Type.
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_TYPE, &trType));
-
- // Build the sig.
- dwMaxSigSize = 4 + sizeof(mdTypeRef);
- pSig = (COR_SIGNATURE*)_alloca(dwMaxSigSize);
- pCurr = pSig;
- *pCurr++ = IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS;
- *pCurr++ = 1;
- *pCurr++ = ELEMENT_TYPE_VOID;
- *pCurr++ = ELEMENT_TYPE_CLASS;
- pCurr += CorSigCompressToken(trType, pCurr);
- dwSigSize = (DWORD)(pCurr - pSig);
- _ASSERTE(dwSigSize <= dwMaxSigSize);
-
- // Declare the typeref and the member ref for the CA.
- IfFailGo(m_pEmit->DefineTypeRefByName(m_arSystem, INTEROP_COCLASS_TYPE_W, &tr)); \
- IfFailGo(m_pEmit->DefineMemberRef(tr, W(".ctor"), pSig, dwSigSize, &m_tkAttr[attr])); \
- break;
- }
- }
- }
-#undef INTEROP_ATTRIBUTE
-#undef INTEROP_ATTRIBUTE_SPECIAL
-
- *pTk = m_tkAttr[attr];
-ErrExit:
- return hr;
-} // HRESULT CImportTlb::GetAttrType()
-
-//*****************************************************************************
-// Create the TypeDefs.
-//*****************************************************************************
-HRESULT
-CImportTlb::ConvertTypeLib()
-{
- HRESULT hr;
- int cTi; // Count of TypeInfos.
- int i; // Loop control.
-
- // How many TypeInfos?
- IfFailGo(cTi = m_pITLB->GetTypeInfoCount());
-
- // Iterate over them.
- for (i = 0; i < cTi; ++i)
- {
- // Get the TypeInfo.
- hr = m_pITLB->GetTypeInfo(i, &m_pITI);
- if (SUCCEEDED(hr))
- {
- // Save up the original TypeInfo (may be later alias-resolved).
- _ASSERTE(m_pOrigITI == NULL);
- m_pOrigITI = m_pITI;
- m_pOrigITI->AddRef();
-
- // Retrieve the attributes of the type info.
- IfFailGo(m_pITI->GetTypeAttr(&m_psAttr));
-
- // Convert the TypeInfo.
- hr = ConvertTypeInfo();
- if (FAILED(hr))
- {
- if (hr == CEE_E_CVTRES_NOT_FOUND || hr == TLBX_I_RESOLVEREFFAILED)
- { // Reflection emit is broken, no need to try to continue.
- goto ErrExit;
- }
-
- BSTR szTypeInfoName = NULL;
- hr = m_pITI->GetDocumentation(MEMBERID_NIL, &szTypeInfoName, 0, 0, 0);
- if (SUCCEEDED(hr))
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_INVALID_TYPEINFO, szTypeInfoName);
- }
- else
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_INVALID_TYPEINFO_UNNAMED, i);
- }
- if (szTypeInfoName != NULL)
- ::SysFreeString(szTypeInfoName);
-#if defined(_DEBUG)
- if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_TlbImp_BreakOnErr))
- _ASSERTE(!"Invalid type");
-#endif
- }
-
- // Release for next TypeInfo.
- m_pOrigITI->Release();
- m_pOrigITI = NULL;
-
- m_pITI->ReleaseTypeAttr(m_psAttr);
- m_psAttr = NULL;
- m_pITI->Release();
- m_pITI = NULL;
- }
- }
-
-ErrExit:
- if (m_pOrigITI != NULL)
- {
- m_pOrigITI->Release();
- m_pOrigITI = NULL;
- }
-
- if (m_psAttr != NULL)
- {
- m_pITI->ReleaseTypeAttr(m_psAttr);
- m_psAttr = NULL;
- }
- if (m_pITI != NULL)
- {
- m_pITI->Release();
- m_pITI = NULL;
- }
- return hr;
-} // CImportTlb::ConvertTypeLib
-
-//*****************************************************************************
-// Convert a single ITypeInfo into the scope.
-//*****************************************************************************
-HRESULT CImportTlb::ConvertTypeInfo() // S_OK or error.
-{
- HRESULT hr; // A result.
- BSTR bstrManagedName=0; // Managed name (or part thereof).
- CQuickArray<WCHAR> qbClassName; // The name of the class.
- ULONG ulFlags; // TypeDef flags.
- WORD wTypeInfoFlags; // TypeInfo flags. Alias flags, if an alias.
- mdToken tkAttr; // Attribute type for flags.
- TYPEKIND tkindAlias; // TYPEKIND of an aliased TypeInfo.
- GUID guid; // GUID of the typeinfo.
- BOOL bConversionLoss=false; // If true, info was lost converting sigs.
- mdToken tkParent; // Parent of the typedef.
- mdToken td; // For looking up a TypeDef.
- ITypeInfo2 *pITI2=0; // For getting custom value.
-
-#if defined(TLB_STATS)
- WCHAR rcStats[16]; // Buffer for stats.
- LARGE_INTEGER __startVal;
- QueryPerformanceCounter(&__startVal);
-#endif
-
- m_tdTypeDef = mdTypeDefNil;
-
- // Get some information about the TypeInfo.
- IfFailGo(m_pITI->GetDocumentation(MEMBERID_NIL, &m_szName, 0, 0, 0));
-
-#if defined(_DEBUG)
- LPWSTR strShouldBreakOnTypeName = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_TlbImp_BreakOnTypeImport);
- if ((NULL != strShouldBreakOnTypeName) && (wcsncmp(strShouldBreakOnTypeName, m_szName, MAX_CLASSNAME_LENGTH) == 0))
- _ASSERTE(!"MD_TlbImp_BreakOnTypeImport");
-#endif
-
- // Assume that we will be able to convert the typeinfo.
- guid = m_psAttr->guid;
- wTypeInfoFlags = m_psAttr->wTypeFlags;
-
- // If this typeinfo is an alias, see what it is an alias for. If for a built-in
- // type, we will just skip it. If for a user-defined type, we will duplicate
- // that definition under this alias' name and guid.
- if (m_psAttr->typekind == TKIND_ALIAS)
- {
- hr = _ResolveTypeDescAliasTypeKind(m_pITI, &m_psAttr->tdescAlias, &tkindAlias);
- IfFailGo(hr);
- if (hr == S_OK)
- {
- TYPEDESC tdesc = m_psAttr->tdescAlias;
- m_pITI->ReleaseTypeAttr(m_psAttr);
- m_pITI->Release();
-
- IfFailGo(_ResolveTypeDescAlias(m_pOrigITI, &tdesc, &m_pITI, &m_psAttr, &guid));
- // Now m_pOrigITI refers to the alias whereas m_pITI is the TypeInfo of the aliased type.
-
- // We should no longer have an alias.
- _ASSERTE(m_psAttr->typekind == tkindAlias);
- _ASSERTE(tkindAlias != TKIND_ALIAS);
-
- ulFlags = rdwTypeFlags[tkindAlias];
- }
- else
- ulFlags = ULONG_MAX;
- }
- else
- {
- ulFlags = rdwTypeFlags[m_psAttr->typekind];
- }
-
- // Figure out the name.
-
- // If the type info is for a CoClass, we need to decorate the name.
- if (m_psAttr->typekind == TKIND_COCLASS)
- {
- // Generate a mangled name for the component.
- IfFailGo(GetManagedNameForCoClass(m_pOrigITI, qbClassName));
- m_szMngName = qbClassName.Ptr();
- }
- else
- {
- IfFailGo(GetManagedNameForTypeInfo(m_pOrigITI, m_wzNamespace, NULL, &bstrManagedName));
- m_szMngName = bstrManagedName;
- }
-
- if (m_psAttr->typekind == TKIND_INTERFACE ||
- (m_psAttr->typekind == TKIND_DISPATCH && m_psAttr->wTypeFlags & TYPEFLAG_FDUAL))
- {
- // If the interface is not derived from IUnknown, or not an interface, we can't convert it.
- if (IsIUnknownDerived(m_pITI, m_psAttr) != S_OK)
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_NOTIUNKNOWN, m_szName);
- ulFlags = ULONG_MAX;
- }
- // If the interface is not derived from IDispatch, but claims to be [dual], give a warning but convert it.
- if ((m_psAttr->wTypeFlags & TYPEFLAG_FDUAL) && IsIDispatchDerived(m_pITI, m_psAttr) != S_OK)
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_W_DUAL_NOT_DISPATCH, m_szName);
- }
- }
- else
- if (m_psAttr->typekind == TKIND_MODULE)
- { // If module has no vars, skip it. We currently don't import module functions.
- if (m_psAttr->cVars == 0)
- ulFlags = ULONG_MAX;
- }
-
- // If something we can convert...
- if (ulFlags != ULONG_MAX)
- {
- // Interfaces derive from nil...
- if (IsTdInterface(ulFlags))
- tkParent = mdTypeDefNil;
- else // ... enums from Enum, ...
- if (m_psAttr->typekind == TKIND_ENUM)
- {
- if (IsNilToken(m_trEnum))
- IfFailGo(m_TRMap.DefineTypeRef(m_pEmit, m_arSystem, szEnum, &m_trEnum));
- tkParent = m_trEnum;
- }
- else // ... structs from ValueType, ...
- if (m_psAttr->typekind == TKIND_RECORD || m_psAttr->typekind == TKIND_UNION)
- {
- if (IsNilToken(m_trValueType))
- IfFailGo(m_TRMap.DefineTypeRef(m_pEmit, m_arSystem, szValueType, &m_trValueType));
- tkParent = m_trValueType;
- }
- else // ... and classes derive from Object.
- tkParent = m_trObject;
-
- // The typelib importer generates metadata into an empty ReflectionEmit scope. Because
- // RE manages type names itself, duplicate checking is turned off. Because of user-defined
- // names (via CUSTOM), it is possible for the user to declare a duplicate. So,
- // before adding the new type, check for duplicates.
- hr = m_pImport->FindTypeDefByName(m_szMngName, mdTypeDefNil, &td);
- if (hr != CLDB_E_RECORD_NOTFOUND)
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_DUPLICATE_TYPE_NAME, m_szMngName);
- IfFailGo(TLBX_E_DUPLICATE_TYPE_NAME);
- }
-
- // Create the typedef.
- IfFailGo(m_pEmit->DefineTypeDef(m_szMngName, ulFlags, tkParent, 0, &m_tdTypeDef));
- IfFailGo(_AddGuidCa(m_tdTypeDef, guid));
-
- // Save the typeinfo flags.
- if (wTypeInfoFlags)
- {
- IfFailGo(GetAttrType(ATTR_TYPELIBTYPE, &tkAttr));
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(WORD));
- BUILD_CUSTOM_ATTRIBUTE(WORD, wTypeInfoFlags);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
-
- // Mark unsafe interfaces (suppressed security runtime checks).
- if (m_bUnsafeInterfaces)
- {
- if (m_tkSuppressCheckAttr == mdTokenNil)
- {
- mdTypeRef tr;
- COR_SIGNATURE rSig[] = {IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS, 0, ELEMENT_TYPE_VOID};
- IfFailGo(m_pEmit->DefineTypeRefByName(m_arSystem, COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE, &tr));
- IfFailGo(m_pEmit->DefineMemberRef(tr, COR_CTOR_METHOD_NAME_W, rSig, lengthof(rSig), &m_tkSuppressCheckAttr));
- }
-
- DECLARE_CUSTOM_ATTRIBUTE(0);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, m_tkSuppressCheckAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
- // Fill in the details depending on the type of the TypeInfo.
- switch (m_psAttr->typekind)
- {
- case TKIND_ENUM:
- hr = ConvEnum(m_pITI, m_psAttr);
- break;
-
- case TKIND_RECORD:
- hr = ConvRecord(m_pITI, m_psAttr, FALSE);
- break;
-
- case TKIND_UNION:
- hr = ConvRecord(m_pITI, m_psAttr, TRUE);
- break;
-
- case TKIND_MODULE:
- hr = ConvModule(m_pITI, m_psAttr);
- break;
-
- case TKIND_INTERFACE:
- hr = ConvIface(m_pITI, m_psAttr);
- break;
-
- case TKIND_DISPATCH:
- hr = ConvDispatch(m_pITI, m_psAttr);
- break;
-
- case TKIND_COCLASS:
- hr = ConvCoclass(m_pITI, m_psAttr);
- break;
-
- case TKIND_ALIAS:
- _ASSERTE(!"Alias should have been resolved!");
- break;
-
- default:
- _ASSERTE(!"Unexpected TYPEKIND");
- break;
- }
- if (FAILED(hr))
- goto ErrExit;
-
- if (hr == S_CONVERSION_LOSS)
- {
- bConversionLoss = true;
- IfFailGo(GetAttrType(ATTR_COMCONVERSIONLOSS, &tkAttr));
- DECLARE_CUSTOM_ATTRIBUTE(0);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, PTROF_CUSTOM_ATTRIBUTE(),SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
-
- }
-
- if (bConversionLoss)
- hr = S_CONVERSION_LOSS;
- else
- hr = S_OK;
-
-#if defined(TLB_STATS)
- LARGE_INTEGER __stopVal;
- QueryPerformanceCounter(&__stopVal);
- DWORD __delta;
- __delta = (DWORD)(__stopVal.QuadPart - __startVal.QuadPart);
- StringCchPrintf(rcStats, COUNTOF(rcStats), W(" %.2f"),
- ((float)__delta*1000)/(float)m_freqVal.QuadPart);
-#endif
-
- // Report that this type has been converted.
- ReportEvent(NOTIF_TYPECONVERTED, TLBX_I_TYPEINFO_IMPORTED, m_szName);
-
-ErrExit:
- if (pITI2)
- pITI2->Release();
- if (m_szName)
- ::SysFreeString(m_szName), m_szName = 0;
- if (bstrManagedName)
- ::SysFreeString(bstrManagedName);
- return (hr);
-} // HRESULT CImportTlb::ConvertTypeInfo()
-
-
-//*****************************************************************************
-// Determine if the type explicitly implements IEnumerable.
-//*****************************************************************************
-HRESULT CImportTlb::ExplicitlyImplementsIEnumerable(
- ITypeInfo *pITI, // ITypeInfo* to check for IEnumerable.
- TYPEATTR *psAttr, // TYPEATTR of TypeInfo.
- BOOL fLookupPartner) // Flag indicating if we should look at the partner itf.
-{
- HREFTYPE href; // HREFTYPE of an implemented interface.
- ITypeInfo *pItiIface=0; // ITypeInfo for an interface.
- TYPEATTR *psAttrIface=0; // TYPEATTR for an interface.
- BOOL fFoundImpl = FALSE;
- int i = 0;
- HRESULT hr = S_OK;
- ITypeInfo* pITISelf2 = NULL;
- TYPEATTR psAttrSelf2;
- int ImplFlags = 0;
-
- // Look through each of the implemented/inherited interfaces
- for (i=0; i<psAttr->cImplTypes && !fFoundImpl; ++i)
- {
- // Get an interface
- IfFailGo(pITI->GetRefTypeOfImplType(i, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pItiIface));
- IfFailGo(pItiIface->GetTypeAttr(&psAttrIface));
- IfFailGo(pITI->GetImplTypeFlags(i, &ImplFlags));
-
- if (!(ImplFlags & IMPLTYPEFLAG_FSOURCE))
- {
- hr = ExplicitlyImplementsIEnumerable(pItiIface, psAttrIface, TRUE);
- if (hr == S_OK)
- fFoundImpl = TRUE;
-
- // Check this interface for the IEnumerable.
- if (psAttrIface->guid == IID_IEnumerable)
- fFoundImpl = TRUE;
- }
-
- pItiIface->ReleaseTypeAttr(psAttrIface);
- psAttrIface = 0;
- pItiIface->Release();
- pItiIface = 0;
- }
-
- if ( fLookupPartner && (pITI->GetRefTypeOfImplType(-1, &href) == S_OK) )
- {
- IfFailGo(pITI->GetRefTypeInfo(href, &pItiIface));
- IfFailGo(pItiIface->GetTypeAttr(&psAttrIface));
-
- hr = ExplicitlyImplementsIEnumerable(pItiIface, psAttrIface, FALSE);
- if (hr == S_OK)
- fFoundImpl = TRUE;
-
- // Check this interface for the IEnumerable.
- if (psAttrIface->guid == IID_IEnumerable)
- fFoundImpl = TRUE;
- }
-
-
-ErrExit:
- if (psAttrIface)
- pItiIface->ReleaseTypeAttr(psAttrIface);
- if (pItiIface)
- pItiIface->Release();
-
- return (fFoundImpl) ? S_OK : S_FALSE;
-}
-
-
-//*****************************************************************************
-// Convert the details for a coclass.
-//*****************************************************************************
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
-#endif
-HRESULT CImportTlb::ConvCoclass( // S_OK or error.
- ITypeInfo *pITI, // ITypeInfo* to convert.
- TYPEATTR *psAttr) // TYPEATTR of TypeInfo.
-{
- BOOL fHadDefaultItf = FALSE;
- HRESULT hr; // A result.
- int i; // Loop control.
- HREFTYPE href; // HREFTYPE of an implemented interface.
- ITypeInfo *pItiIface=0; // ITypeInfo for an interface.
- TYPEATTR *psAttrIface=0; // TYPEATTR for an interface.
- int ImplFlags; // ImplType flags.
- mdToken tkIface; // Token for an interface.
- CQuickArray<mdToken> rImpls; // Array of implemented interfaces.
- CQuickArray<mdToken> rEvents; // Array of implemented event interfaces.
- CQuickArray<mdToken> rTmpImpls; // Temporary array of impls.
- CQuickArray<ITypeInfo*> rImplTypes; // Array of implemented ITypeInfo*s.
- CQuickArray<ITypeInfo*> rSrcTypes; // Array of source ITypeInfo*s.
- int ixSrc; // Index into rSrcTypes for source interfaces.
- int ixImpl; // Index into rImpls for implemented interface.
- int ixTmpImpl; // Index into rTmpImpls.
- mdToken mdCtor; // Dummy token for the object initializer.
- mdToken tkAttr; // Token for custom attribute type.
- mdToken token; // Dummy token for typeref.
- BOOL fInheritsIEnum = FALSE;
-
-#ifdef _DEBUG
- int bImplIEnumerable=0; // If true, the class implements IEnumerable.
-#endif
-
- // Size the rImpls and rSrcs arrays large enough for impls, events, the IEnumerable itf and two ending nulls.
- IfFailGo(rImpls.ReSizeNoThrow(psAttr->cImplTypes+2));
- memset(rImpls.Ptr(), 0, (psAttr->cImplTypes+2)*sizeof(mdToken));
- IfFailGo(rEvents.ReSizeNoThrow(psAttr->cImplTypes+1));
- memset(rEvents.Ptr(), 0, (psAttr->cImplTypes+1)*sizeof(mdToken));
- IfFailGo(rTmpImpls.ReSizeNoThrow(psAttr->cImplTypes+3));
- memset(rTmpImpls.Ptr(), 0, (psAttr->cImplTypes+3)*sizeof(mdToken));
- IfFailGo(rImplTypes.ReSizeNoThrow(psAttr->cImplTypes+2));
- memset(rImplTypes.Ptr(), 0, (psAttr->cImplTypes+2)*sizeof(ITypeInfo*));
- IfFailGo(rSrcTypes.ReSizeNoThrow(psAttr->cImplTypes+1));
- memset(rSrcTypes.Ptr(), 0, (psAttr->cImplTypes+1)*sizeof(ITypeInfo*));
- ixImpl = -1;
- ixSrc = -1;
- ixTmpImpl = -1;
-
- if (ExplicitlyImplementsIEnumerable(pITI, psAttr) == S_OK)
- fInheritsIEnum = TRUE;
-
- // Build the list of implemented and event interfaces.
- // The EE cares about implemented interfaces, so we convert them to actual
- // tokens and add them to the typedef. VB cares about event interfaces,
- // but we are going to add a list of typeref names as a custom attribute.
- // We can't build the list as we go along, because the default may not
- // be the first event source. So, we store tokens for the implemented
- // interfaces, but ITypeInfo*s for the event sources.
- for (i=0; i<psAttr->cImplTypes; ++i)
- {
- IfFailGo(pITI->GetRefTypeOfImplType(i, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pItiIface));
- IfFailGo(pItiIface->GetTypeAttr(&psAttrIface));
- IfFailGo(pITI->GetImplTypeFlags(i, &ImplFlags));
-
- // If the interface is derived from IUnknown, or not an interface, we can't use it as an interface.
- // Don't add explicit IUnknown or IDispatch.
- if ((IsIUnknownDerived(pItiIface, psAttrIface) != S_OK && psAttrIface->typekind != TKIND_DISPATCH) ||
- psAttrIface->guid == IID_IDispatch ||
- psAttrIface->guid == IID_IUnknown)
- {
- pItiIface->ReleaseTypeAttr(psAttrIface);
- psAttrIface = 0;
- pItiIface->Release();
- pItiIface = 0;
- continue;
- }
-
- // Add the event to the impls list or the events list.
- if (ImplFlags & IMPLTYPEFLAG_FSOURCE)
- {
- // Get the token for the event interface.
- IfFailGo(_GetTokenForEventItf(pItiIface, &tkIface));
-
- // If we've already marked this CoClass as implementing this source interface, don't do so again.
- for (int iCheck=0; iCheck <= ixSrc; iCheck++)
- {
- if (rEvents[iCheck] == tkIface)
- goto LoopEnd;
- }
-
- // Add the source interface to the list of source interfaces.
- ++ixSrc;
-
- // If this is explicitly the default source interface...
- if (ImplFlags & IMPLTYPEFLAG_FDEFAULT)
- {
- // Put the def source ITypeInfo at the head of the list of source
- // ITypeInfo's.
- for (int ix = ixSrc; ix > 0; --ix)
- {
- rSrcTypes[ix] = rSrcTypes[ix-1];
- rEvents[ix] = rEvents[ix-1];
- }
- rEvents[0] = tkIface;
- rSrcTypes[0] = pItiIface;
- }
- else
- {
- rEvents[ixSrc] = tkIface;
- rSrcTypes[ixSrc] = pItiIface;
- }
- }
- else
- {
- // Get the token for the interface.
- IfFailGo(_GetTokenForTypeInfo(pItiIface, FALSE, &tkIface));
-
- // If we've already marked this CoClass as implementing this interface, don't do so again.
- for (int iCheck=0; iCheck <= ixImpl; iCheck++)
- {
- if (rImpls[iCheck] == tkIface)
- goto LoopEnd;
- }
-
- // Add the implemented interface to the list of implemented interfaces.
- ++ixImpl;
-
- // If this is explicitly the default interface...
- if (ImplFlags & IMPLTYPEFLAG_FDEFAULT)
- {
- fHadDefaultItf = TRUE;
- // Put the new interface at the start of the list.
- for (int ix=ixImpl; ix > 0; --ix)
- {
- rImpls[ix] = rImpls[ix-1];
- rImplTypes[ix] = rImplTypes[ix-1];
- }
- rImpls[0] = tkIface;
- rImplTypes[0] = pItiIface;
- }
- else
- {
- rImpls[ixImpl] = tkIface;
- rImplTypes[ixImpl] = pItiIface;
- }
- }
-
-LoopEnd:
- pItiIface->ReleaseTypeAttr(psAttrIface);
- psAttrIface = 0;
- pItiIface = 0; // Pointer now owned by array.
- }
-
- // Create an interface that will represent the class.
- IfFailGo(_CreateClassInterface(pITI, rImplTypes[0], rImpls[0], rEvents[0], &tkIface));
-
- // Create a temporary array of interface tokens.
- if (fHadDefaultItf)
- {
- // default interface should be the first interface
- rTmpImpls[++ixTmpImpl] = rImpls[0];
- rTmpImpls[++ixTmpImpl] = tkIface;
- }
- else
- {
- rTmpImpls[++ixTmpImpl] = tkIface;
- if (ixImpl >= 0)
- rTmpImpls[++ixTmpImpl] = rImpls[0];
- }
- if (ixSrc >= 0)
- rTmpImpls[++ixTmpImpl] = rEvents[0];
- if (ixImpl >= 0)
- {
- memcpy(&rTmpImpls[ixTmpImpl + 1], &rImpls[1], ixImpl * sizeof(mdTypeRef));
- ixTmpImpl += ixImpl;
- }
- if (ixSrc >= 0)
- {
- memcpy(&rTmpImpls[ixTmpImpl + 1], &rEvents[1], ixSrc * sizeof(mdTypeRef));
- ixTmpImpl += ixSrc;
- }
-
- // Check to see if the default interface has a member with a DISPID of DISPID_NEWENUM.
- BOOL fIEnumFound = FALSE;
- if (ixImpl >= 0)
- {
- // The ITypeInfo for the default interface had better be set.
- _ASSERTE(rImplTypes[0]);
-
- if ( (!fInheritsIEnum) && (HasNewEnumMember(rImplTypes[0]) == S_OK) )
- {
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_IENUMERABLE, &tkIface));
- rTmpImpls[++ixTmpImpl] = tkIface;
- fIEnumFound = TRUE;
- }
- }
-
- // Else Check to see if the IEnumerable Custom Value exists on the CoClass.
- if (!fIEnumFound)
- {
- BOOL CVExists = FALSE;
- _ForceIEnumerableCVExists(pITI, &CVExists);
- if (CVExists && !fInheritsIEnum)
- {
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_IENUMERABLE, &tkIface));
- rTmpImpls[++ixTmpImpl] = tkIface;
- fIEnumFound = TRUE;
- }
- }
-
- // Add the implemented interfaces and event interfaces to the TypeDef.
- IfFailGo(m_pEmit->SetTypeDefProps(m_tdTypeDef, ULONG_MAX/*Classflags*/,
- ULONG_MAX, (mdToken*)rTmpImpls.Ptr()));
-
- // Create an initializer for the class.
- ULONG ulFlags;
- if (psAttr->wTypeFlags & TYPEFLAG_FCANCREATE)
- ulFlags = OBJECT_INITIALIZER_FLAGS;
- else
- ulFlags = NONCREATABLE_OBJECT_INITIALIZER_FLAGS;
- {
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, OBJECT_INITIALIZER_NAME, ulFlags,
- OBJECT_INITIALIZER_SIG, sizeof(OBJECT_INITIALIZER_SIG), 0/*rva*/, OBJECT_INITIALIZER_IMPL_FLAGS/*flags*/, &mdCtor));
- }
-
- // Set ClassInterfaceType.None on the generated class.
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(short));
- BUILD_CUSTOM_ATTRIBUTE(short, clsIfNone);
- IfFailGo(GetAttrType(ATTR_CLASSINTERFACE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
-
-
- if (!m_bPreventClassMembers)
- {
- // Iterate over the implemented interfaces, and add the members to the coclass.
- m_ImplIface = eImplIfaceDefault;
- for (i=0; i<=ixImpl; ++i)
- {
- _ASSERTE(rImplTypes[i]);
-
- // Interface info.
- m_tkInterface = rImpls[i];
- pItiIface = rImplTypes[i];
- rImplTypes[i] = 0; // ownership transferred.
-
- // Get interface name for decoration.
- if (m_szInterface)
- ::SysFreeString(m_szInterface), m_szInterface = 0;
- IfFailGo(pItiIface->GetDocumentation(MEMBERID_NIL, &m_szInterface, 0,0,0));
-
- // Add the interface members to the coclass.
- IfFailGo(pItiIface->GetTypeAttr(&psAttrIface));
- switch (psAttrIface->typekind)
- {
- case TKIND_DISPATCH:
- hr = ConvDispatch(pItiIface, psAttrIface, false);
- break;
- case TKIND_INTERFACE:
- hr = ConvIface(pItiIface, psAttrIface, false);
- break;
- default:
- hr = S_OK;
- _ASSERTE(!"Unexpected typekind for implemented interface");
- }
- pItiIface->ReleaseTypeAttr(psAttrIface);
- psAttrIface = 0;
- IfFailGo(hr);
- m_ImplIface = eImplIface;
- rImplTypes[i] = pItiIface;
- pItiIface = 0; // ownership transferred back.
- }
-
- // Add the methods of the event interfaces to the class.
- for (i=0; i<=ixSrc; ++i)
- IfFailGo(_AddSrcItfMembersToClass(rEvents[i]));
- }
-
- // If there are source interfaces, add a custom value for that.
- if (ixSrc >= 0)
- {
- CQuickArray<char> rEvents; // Output buffer.
- int cbCur; // Current location in output buffer.
- int cbReq; // Size of an individual piece.
- CQuickArray<WCHAR> rEvent;
-
- // Save 6 bytes at the beginning of the buffer for the custom attribute prolog and
- // the string length. The string length may require 1, 2, or 4 bytes to express.
- cbCur = 6;
-
- // For each event interface...
- for (int ix=0; ix <= ixSrc; ++ix)
- {
- pItiIface = rSrcTypes[ix];
- rSrcTypes[ix] = 0;
-
- // Get the typeref name for the interface.
- for(;;)
- {
- int cchReq;
- IfFailGo(_GetTokenForTypeInfo(pItiIface, FALSE, &token, rEvent.Ptr(), (int)rEvent.MaxSize(), &cchReq, TRUE));
- if (cchReq <= (int)rEvent.MaxSize())
- break;
- IfFailGo(rEvent.ReSizeNoThrow(cchReq));
- }
-
- // Append to the buffer. See how much space is required, get it.
- cbReq = WszWideCharToMultiByte(CP_UTF8,0, rEvent.Ptr(),-1, 0,0, 0,0);
-
- // make sure we have enough space for the extra terminating 0 and for the 00 00 suffix
- size_t cbNewSize;
- if (!ClrSafeInt<size_t>::addition(cbCur, cbReq, cbNewSize) ||
- !ClrSafeInt<size_t>::addition(cbNewSize, 3, cbNewSize))
- {
- IfFailGo(COR_E_OVERFLOW);
- }
- if (cbNewSize > rEvents.MaxSize())
- {
- IfFailGo(rEvents.ReSizeNoThrow(cbNewSize));
- }
- // Do the conversion.
- WszWideCharToMultiByte(CP_UTF8,0, rEvent.Ptr(),-1, rEvents.Ptr()+cbCur,cbReq, 0,0);
- cbCur += cbReq;
- pItiIface->Release();
- }
- pItiIface = 0;
-
- // Add an extra terminating 0.
- *(rEvents.Ptr()+cbCur) = 0;
- ++cbCur;
-
- // Now build the custom attribute.
- int iLen = cbCur - 6;
- char *pBytes = rEvents.Ptr();
-
- // Length may be encoded with less the 4 bytes.
- int lenPad = 4 - CPackedLen::Size(iLen);
- _ASSERTE(lenPad >= 0);
-
- pBytes += lenPad;
- cbCur -= lenPad;
-
- // Prologue.
- pBytes[0] = 0x01;
- pBytes[1] = 0x00;
-
- CPackedLen::PutLength(pBytes + 2, iLen);
-
- // Zero named properties/fields.
- pBytes[cbCur + 0] = 0x00;
- pBytes[cbCur + 1] = 0x00;
- cbCur += 2;
-
- // Finally, store it.
- IfFailGo(GetAttrType(ATTR_COMSOURCEINTERFACES, &tkAttr));
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, pBytes, cbCur, 0));
- }
-
-ErrExit:
- if (psAttrIface)
- pItiIface->ReleaseTypeAttr(psAttrIface);
- if (pItiIface)
- pItiIface->Release();
- // Clean up any left-over ITypeInfo*.
- for (ULONG ix=0; ix < rImplTypes.Size(); ++ix)
- if (rImplTypes[ix])
- (rImplTypes[ix])->Release();
- for (ULONG ix=0; ix < rSrcTypes.Size(); ++ix)
- if (rSrcTypes[ix])
- (rSrcTypes[ix])->Release();
- m_tkInterface = 0;
- if (m_szInterface)
- ::SysFreeString(m_szInterface), m_szInterface = 0;
- m_ImplIface = eImplIfaceNone;
- return (hr);
-} // HRESULT CImportTlb::ConvCoclass()
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
-//*****************************************************************************
-// Convert an enum to a class with fields that have default values.
-//*****************************************************************************
-HRESULT CImportTlb::ConvEnum( // S_OK or error.
- ITypeInfo *pITI, // ITypeInfo* to convert.
- TYPEATTR *psAttr) // TYPEATTR of TypeInfo.
-{
- HRESULT hr; // A result.
- int i; // Loop control.
- VARDESC *psVar=0; // VARDESC for a member.
- mdFieldDef mdField; // The FieldDef for the enum's type.
-
- // Create the field definition for the enum type. Always import as an __int32.
- IfFailGo(m_pEmit->DefineField(m_tdTypeDef, ENUM_TYPE_NAME, ENUM_TYPE_FLAGS, ENUM_TYPE_SIGNATURE,ENUM_TYPE_SIGNATURE_SIZE,
- 0,0, -1, &mdField));
-
- // Iterate over the vars.
- for (i=0; i<psAttr->cVars; ++i)
- {
- // Get variable information.
- IfFailGo(pITI->GetVarDesc(i, &psVar));
- // Do the conversion.
- IfFailGo(_ConvConstant(pITI, psVar, true/*enum member*/));
- // Release for next var.
- pITI->ReleaseVarDesc(psVar);
- psVar = 0;
- }
-
- hr = S_OK;
-
-ErrExit:
- if (psVar)
- pITI->ReleaseVarDesc(psVar);
- return (hr);
-} // HRESULT CImportTlb::ConvEnum()
-
-//*****************************************************************************
-// Convert a record to a class with fields.
-//*****************************************************************************
-HRESULT CImportTlb::ConvRecord( // S_OK or error.
- ITypeInfo *pITI, // ITypeInfo* to convert.
- TYPEATTR *psAttr, // TYPEATTR of TypeInfo.
- BOOL bUnion) // Convert as a union?
-{
- HRESULT hr=S_OK; // A result.
- int i; // Loop control.
- VARDESC *psVar=0; // VARDESC for a member.
- mdFieldDef mdField; // Token for a given field.
- CQuickArray<COR_FIELD_OFFSET> rLayout; // Array for layout information.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
-
- // Unions with embedded Object Types can't really be converted. Just reserve correct size.
- if (bUnion && (HasObjectFields(pITI, psAttr) == S_OK))
- {
- IfFailGo(m_pEmit->SetClassLayout(m_tdTypeDef, psAttr->cbAlignment, 0, psAttr->cbSizeInstance));
- goto ErrExit;
- }
-
- // Prepare for layout info.
- IfFailGo(rLayout.ReSizeNoThrow(psAttr->cVars+1));
-
- // Iterate over the vars.
- for (i=0; i<psAttr->cVars; ++i)
- {
- // Get variable information.
- IfFailGo(pITI->GetVarDesc(i, &psVar));
- // Do the conversion.
- IfFailGo(_ConvField(pITI, psVar, &mdField, bUnion));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
- // Save the layout info.
- rLayout[i].ridOfField = mdField;
- rLayout[i].ulOffset = psVar->oInst;
- // Release for next var.
- pITI->ReleaseVarDesc(psVar);
- psVar = 0;
- }
-
- // If it is a union, Save the layout information.
- if (bUnion)
- {
- rLayout[psAttr->cVars].ridOfField = mdFieldDefNil;
- IfFailGo(m_pEmit->SetClassLayout(m_tdTypeDef, psAttr->cbAlignment, rLayout.Ptr(), -1));
- }
- else // Not a union. Preserve the alignment.
- IfFailGo(m_pEmit->SetClassLayout(m_tdTypeDef, psAttr->cbAlignment, 0, -1));
-
- // If we are marking these as serializable - do so now.
- if (m_bSerializableValueClasses)
- {
- mdToken tkAttr;
- IfFailGo(GetAttrType(ATTR_SERIALIZABLE, &tkAttr));
- DECLARE_CUSTOM_ATTRIBUTE(0);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, PTROF_CUSTOM_ATTRIBUTE(),SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
-
- if (bConversionLoss)
- hr = S_CONVERSION_LOSS;
-
-ErrExit:
- if (psVar)
- pITI->ReleaseVarDesc(psVar);
- return (hr);
-} // HRESULT CImportTlb::ConvRecord()
-
-//*****************************************************************************
-// Convert an module to a class with fields that have default values.
-// @FUTURE: convert methods as PInvoke methods.
-//*****************************************************************************
-HRESULT CImportTlb::ConvModule( // S_OK or error.
- ITypeInfo *pITI, // ITypeInfo* to convert.
- TYPEATTR *psAttr) // TYPEATTR of TypeInfo.
-{
- HRESULT hr; // A result.
- int i; // Loop control.
- VARDESC *psVar=0; // VARDESC for a member.
-
- // Iterate over the vars.
- for (i=0; i<psAttr->cVars; ++i)
- {
- // Get variable information.
- IfFailGo(pITI->GetVarDesc(i, &psVar));
- // Do the conversion.
- IfFailGo(_ConvConstant(pITI, psVar));
- // Release for next var.
- pITI->ReleaseVarDesc(psVar);
- psVar = 0;
- }
-
- hr = S_OK;
-
-ErrExit:
- if (psVar)
- pITI->ReleaseVarDesc(psVar);
- return (hr);
-} // HRESULT CImportTlb::ConvModule()
-
-//*****************************************************************************
-// Convert metadata for an interface.
-//*****************************************************************************
-HRESULT CImportTlb::ConvIface( // S_OK or error.
- ITypeInfo *pITI, // ITypeInfo* to convert.
- TYPEATTR *psAttr, // TYPEATTR of TypeInfo.
- BOOL bVtblGapFuncs) // Vtable gap functions?
-{
- HRESULT hr; // A result.
- ITypeInfo *pITIBase=0; // ITypeInfo* of base interface.
- TYPEATTR *psAttrBase=0; // TYPEATTR of base interface.
- ITypeInfo *pITISelf2=0; // ITypeInfo* of partner.
- TYPEATTR *psAttrSelf2=0; // TYPEATTR of partner.
- mdToken tkImpls[3]={0,0,0}; // Token of implemented interfaces.
- int ixImpls = 0; // Index of current implemented interface.
- HREFTYPE href; // href of base interface.
- mdToken tkIface; // Token for an interface.
- BOOL fInheritsIEnum = FALSE;
-
- // If there is a partner interface, prefer it.
- if (pITI->GetRefTypeOfImplType(-1, &href) == S_OK)
- {
- IfFailGo(pITI->GetRefTypeInfo(href, &pITISelf2));
- IfFailGo(pITISelf2->GetTypeAttr(&psAttrSelf2));
- }
-
- // Base interface?
- if (psAttr->cImplTypes == 1)
- {
- IfFailGo(pITI->GetRefTypeOfImplType(0, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
-
- // If this interface extends something other than IDispatch or IUnknown, record that
- // fact as an "implemented interface".
- if (psAttrBase->guid != IID_IDispatch && psAttrBase->guid != IID_IUnknown)
- {
- // Get Token of the base interface.
- IfFailGo(_GetTokenForTypeInfo(pITIBase, FALSE, &tkImpls[ixImpls++]));
- }
- else
- { // Maybe we're "funky"...
- if (pITISelf2)
- {
- pITIBase->ReleaseTypeAttr(psAttrBase);
- pITIBase->Release();
- pITIBase = 0;
- psAttrBase = 0;
-
- if (psAttrSelf2->cImplTypes == 1)
- {
- IfFailGo(pITISelf2->GetRefTypeOfImplType(0, &href));
- IfFailGo(pITISelf2->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
-
- if (psAttrBase->guid != IID_IDispatch && psAttrBase->guid != IID_IUnknown)
- {
- // Get Token of the base interface.
- IfFailGo(_GetTokenForTypeInfo(pITIBase, FALSE, &tkImpls[ixImpls++]));
- }
- }
- else
- {
- BSTR szTypeInfoName;
- pITISelf2->GetDocumentation(MEMBERID_NIL, &szTypeInfoName, 0, 0, 0);
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_INVALID_TYPEINFO, szTypeInfoName);
- SysFreeString(szTypeInfoName);
-
- IfFailGo(TLBX_E_INVALID_TYPEINFO);
- }
- }
- }
-
- pITIBase->ReleaseTypeAttr(psAttrBase);
- psAttrBase = 0;
- pITIBase->Release();
- pITIBase = 0;
- }
-
- if (ExplicitlyImplementsIEnumerable(pITI, psAttr) == S_OK)
- fInheritsIEnum = TRUE;
-
- // If this interface has a NewEnum member then have it implement IEnumerable.
- if ( (!fInheritsIEnum) && (HasNewEnumMember(pITI) == S_OK) )
- {
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_IENUMERABLE, &tkIface));
- tkImpls[ixImpls++] = tkIface;
- }
-
- // If not processing an implemented interface, add additional interface properties.
- if (m_ImplIface == eImplIfaceNone)
- {
- // Set base interface as an implemented interface.
- if (tkImpls[0])
- IfFailGo(m_pEmit->SetTypeDefProps(m_tdTypeDef, ULONG_MAX/*flags*/, ULONG_MAX/*extends*/, tkImpls));
-
- // If the interface is not derived from IDispatch mark it as IUnknown based.
- if (IsIDispatchDerived(pITI, psAttr) == S_FALSE)
- {
- mdMemberRef mr;
- // Note that this is a vtable, but not IDispatch derived.
- // Custom attribute buffer.
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(short));
- // Set up the attribute.
- BUILD_CUSTOM_ATTRIBUTE(short, ifVtable);
- // Store the attribute
- IfFailGo(GetAttrType(ATTR_INTERFACETYPE, &mr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, mr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
- }
-
- // Convert the members on the interface (and base interfaces).
- // If this interface had a "funky partner", base the conversion on that.
- if (pITISelf2)
- IfFailGo(_ConvIfaceMembers(pITISelf2, psAttrSelf2, bVtblGapFuncs, psAttr->wTypeFlags & TYPEFLAG_FDUAL, fInheritsIEnum));
- else
- IfFailGo(_ConvIfaceMembers(pITI, psAttr, bVtblGapFuncs, psAttr->wTypeFlags & TYPEFLAG_FDUAL, fInheritsIEnum));
-
-ErrExit:
- if (psAttrSelf2)
- pITISelf2->ReleaseTypeAttr(psAttrSelf2);
- if (pITISelf2)
- pITISelf2->Release();
- if (psAttrBase)
- pITIBase->ReleaseTypeAttr(psAttrBase);
- if (pITIBase)
- pITIBase->Release();
- return (hr);
-} // HRESULT CImportTlb::ConvIface()
-
-//*****************************************************************************
-// Convert the metadata for a dispinterface. Try to convert as a normal
-// interface.
-//*****************************************************************************
-HRESULT CImportTlb::ConvDispatch( // S_OK or error.
- ITypeInfo *pITI, // ITypeInfo* to convert.
- TYPEATTR *psAttr, // TYPEATTR of TypeInfo.
- BOOL bVtblGapFuncs) // Vtable gap functions for interface implementations?
-{
- HRESULT hr; // A result.
- HREFTYPE href; // Base interface href.
- ITypeInfo *pITIBase=0; // Base interface ITypeInfo.
- TYPEATTR *psAttrBase=0; // TYPEATTR of base interface.
- mdMemberRef mr; // MemberRef for custom value.
- DWORD attr[2] = {0x00010001, 0x00000002};
- BYTE bIface = ifDispatch; // Custom value means "dispinterface"
- BOOL fInheritsIEnum = FALSE;
-
- // If this is a dual interface, treat it like a normal interface.
- if ((psAttr->wTypeFlags & TYPEFLAG_FDUAL))
- {
- hr = ConvIface(pITI, psAttr, bVtblGapFuncs);
- goto ErrExit;
- }
-
- if (ExplicitlyImplementsIEnumerable(pITI, psAttr) == S_OK)
- fInheritsIEnum = TRUE;
-
- // If there is a vtable view of this interface (funky dispinterface).
- // @FUTURE: what would be really nice here would be an alias mechanism, so that we could
- // just point this dispinterface to that other interface, in those situations that it
- // is dual. OTOH, that is probably pretty rare, because if that other interface
- // were dual, why would the dispinterface even be needed?
- if (pITI->GetRefTypeOfImplType(-1, &href) == S_OK)
- {
- IfFailGo(pITI->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
- IfFailGo(_ConvIfaceMembers(pITIBase, psAttrBase, bVtblGapFuncs, TRUE, fInheritsIEnum));
- pITIBase->ReleaseTypeAttr(psAttrBase);
- psAttrBase = 0;
- pITIBase->Release();
- pITIBase = 0;
- goto ErrExit;
- }
-
- // If not processing an implemented interface, mark the interface type.
- if (m_ImplIface == eImplIfaceNone)
- {
- // If this interface has a NewEnum member then have it implement IEnumerable.
- if ((S_OK == HasNewEnumMember(pITI)) && !fInheritsIEnum)
- {
- mdToken tkImpl[2] = {0,0};
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_IENUMERABLE, &tkImpl[0]));
- IfFailGo(m_pEmit->SetTypeDefProps(m_tdTypeDef, ULONG_MAX, ULONG_MAX, tkImpl));
- }
-
- // Note that this is a dispinterface.
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(short));
- // Set up the attribute.
- BUILD_CUSTOM_ATTRIBUTE(short, ifDispatch);
- // Store the attribute
- IfFailGo(GetAttrType(ATTR_INTERFACETYPE, &mr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, mr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
- IfFailGo(_ConvDispatchMembers(pITI, psAttr, fInheritsIEnum));
-
-ErrExit:
- if (psAttrBase)
- pITIBase->ReleaseTypeAttr(psAttrBase);
- if (pITIBase)
- pITIBase->Release();
- return (hr);
-} // HRESULT CImportTlb::ConvDispatch()
-
-//*****************************************************************************
-// Determine if an interface is derived from IUnknown.
-//*****************************************************************************
-HRESULT CImportTlb::IsIUnknownDerived(
- ITypeInfo *pITI, // The containing ITypeInfo.
- TYPEATTR *psAttr) // The ITypeInfo's TYPEATTR
-{
- HRESULT hr=S_OK; // A result.
-
- HREFTYPE href; // Base interface href.
- ITypeInfo *pITIBase=0; // Base interface ITypeInfo.
- TYPEATTR *psAttrBase=0; // TYPEATTR of base interface.
-
- // This should never be called on CoClasses.
- _ASSERTE(psAttr->typekind != TKIND_COCLASS);
-
- // If IDispatch or IUnknown, we've recursed far enough.
- if (IsEqualGUID(psAttr->guid, IID_IUnknown) || IsEqualGUID(psAttr->guid, IID_IDispatch))
- {
- goto ErrExit;
- }
-
- // Handle base interface.
- if (psAttr->cImplTypes == 1)
- {
- IfFailGo(pITI->GetRefTypeOfImplType(0, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
-
- // IUnknow derived if base interface is.
- hr = IsIUnknownDerived(pITIBase, psAttrBase);
- pITIBase->ReleaseTypeAttr(psAttrBase);
- psAttrBase = 0;
- pITIBase->Release();
- pITIBase = 0;
- }
- else
- { // No base interface, not IUnknown, not IDispatch. Not very COM-ish, so don't try to handle.
- hr = S_FALSE;
- }
-
-ErrExit:
- if (psAttrBase)
- pITIBase->ReleaseTypeAttr(psAttrBase);
- if (pITIBase)
- pITIBase->Release();
- return (hr);
-} // HRESULT CImportTlb::IsIUnknownDerived()
-
-//*****************************************************************************
-// Determine if an interface is derived from IDispatch. Note that a pure
-// dispinterface doesn't derive from IDispatch.
-//*****************************************************************************
-HRESULT CImportTlb::IsIDispatchDerived(
- ITypeInfo *pITI, // The containing ITypeInfo.
- TYPEATTR *psAttr) // The ITypeInfo's TYPEATTR
-{
- HRESULT hr=S_OK; // A result.
-
- HREFTYPE href; // Base interface href.
- ITypeInfo *pITIBase=0; // Base interface ITypeInfo.
- TYPEATTR *psAttrBase=0; // TYPEATTR of base interface.
-
- // If IDispatch, we've recursed far enough.
- if (IsEqualGUID(psAttr->guid, IID_IDispatch))
- {
- goto ErrExit;
- }
-
- if (psAttr->typekind == TKIND_DISPATCH)
- {
- IfFailGo(pITI->GetRefTypeOfImplType(-1, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
-
- // IDispatch derived if base interface is.
- hr = IsIDispatchDerived(pITIBase, psAttrBase);
- pITIBase->ReleaseTypeAttr(psAttrBase);
- psAttrBase = 0;
- pITIBase->Release();
- pITIBase = 0;
-
- goto ErrExit;
- }
-
- // Handle base interface.
- if (psAttr->cImplTypes == 1)
- {
- IfFailGo(pITI->GetRefTypeOfImplType(0, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
-
- // IDispatch derived if base interface is.
- hr = IsIDispatchDerived(pITIBase, psAttrBase);
- pITIBase->ReleaseTypeAttr(psAttrBase);
- psAttrBase = 0;
- pITIBase->Release();
- pITIBase = 0;
- }
- else
- { // No base interface, not IDispatch. Done.
- hr = S_FALSE;
- }
-
-ErrExit:
- if (psAttrBase)
- pITIBase->ReleaseTypeAttr(psAttrBase);
- if (pITIBase)
- pITIBase->Release();
- return (hr);
-} // HRESULT CImportTlb::IsIDispatchDerived()
-
-//*****************************************************************************
-// Determine if an interface has a member with a DISPID of DISPID_NEWENUM.
-//*****************************************************************************
-HRESULT CImportTlb::HasNewEnumMember( // S_OK if has NewEnum, S_FALSE otherwise.
- ITypeInfo *pItfTI) // The interface in question.
-{
- HRESULT hr = S_OK; // A result.
- BOOL bHasNewEnumMember=FALSE;// If true, has a NewEnum
- TYPEATTR *pAttr = NULL; // A TypeInfo's typeattr
- FUNCDESC *pFuncDesc = NULL; // A Function's FuncDesc
- VARDESC *pVarDesc = NULL; // A properties VarDesc
- int i; // Loop control.
- ITypeInfo *pITISelf2=0; // Partner interface.
- HREFTYPE href; // HREF of partner.
- WCHAR IEnumCA[] = W("{CD2BC5C9-F452-4326-B714-F9C539D4DA58}");
-
-
- // If there is a partner interface, prefer it.
- if (pItfTI->GetRefTypeOfImplType(-1, &href) == S_OK)
- {
- IfFailGo(pItfTI->GetRefTypeInfo(href, &pITISelf2));
- pItfTI = pITISelf2;
- }
-
- // Retrieve the attributes of the interface.
- IfFailGo(pItfTI->GetTypeAttr(&pAttr));
-
- if ((pAttr->typekind == TKIND_DISPATCH) || ((pAttr->typekind == TKIND_INTERFACE) && (IsIDispatchDerived(pItfTI, pAttr) == S_OK)))
- {
- // Check to see if the ForceIEnumerable custom value exists on the type
- _ForceIEnumerableCVExists(pItfTI, &bHasNewEnumMember);
-
- // Check to see if the interface has a function with a DISPID of DISPID_NEWENUM.
- for (i = 0; i < pAttr->cFuncs; i++)
- {
- IfFailGo(TryGetFuncDesc(pItfTI, i, &pFuncDesc));
-
- if (FuncIsNewEnum(pItfTI, pFuncDesc, i) == S_OK)
- {
- // Throw a warning if we find more than one func with DISPID_NEWENUM.
- if (bHasNewEnumMember == TRUE)
- {
- BSTR ObjectName;
- pItfTI->GetDocumentation(-1, &ObjectName, NULL, NULL, NULL);
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_INVALID_TYPEINFO, ObjectName);
- SysFreeString(ObjectName);
- }
-
- // The interface has a function with a DISPID of DISPID_NEWENUM.
- bHasNewEnumMember = TRUE;
- break;
- }
-
- pItfTI->ReleaseFuncDesc(pFuncDesc);
- pFuncDesc = NULL;
- }
-
- // Check to see if the interface as a property with a DISPID of DISPID_NEWENUM.
- for (i = 0; i < pAttr->cVars; i++)
- {
- IfFailGo(pItfTI->GetVarDesc(i, &pVarDesc));
-
- if (PropertyIsNewEnum(pItfTI, pVarDesc, i) == S_OK)
- {
- // Throw a warning if we find more than one func with DISPID_NEWENUM.
- if (bHasNewEnumMember == TRUE)
- {
- BSTR ObjectName;
- pItfTI->GetDocumentation(-1, &ObjectName, NULL, NULL, NULL);
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_INVALID_TYPEINFO, ObjectName);
- SysFreeString(ObjectName);
- }
-
- // The interface has a property with a DISPID of DISPID_NEWENUM.
- bHasNewEnumMember = TRUE;
- break;
- }
-
- pItfTI->ReleaseVarDesc(pVarDesc);
- pVarDesc = NULL;
- }
- }
- else
- {
- // Check to see if the ForceIEnumerable custom value exists on the type
- // If it does, spit out a warning.
- _ForceIEnumerableCVExists(pItfTI, &bHasNewEnumMember);
-
- if (bHasNewEnumMember)
- {
- // Invalid custom attribute on the iface.
- BSTR CustomValue = SysAllocString((const WCHAR*)&IEnumCA[0]);
- BSTR ObjectName;
- pItfTI->GetDocumentation(-1, &ObjectName, NULL, NULL, NULL);
-
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_W_IENUM_CA_ON_IUNK, CustomValue, ObjectName);
-
- SysFreeString(CustomValue);
- SysFreeString(ObjectName);
-
- bHasNewEnumMember = FALSE;
- }
- }
-
- hr = bHasNewEnumMember ? S_OK : S_FALSE;
-
-ErrExit:
- if (pAttr)
- pItfTI->ReleaseTypeAttr(pAttr);
- if (pFuncDesc)
- pItfTI->ReleaseFuncDesc(pFuncDesc);
- if (pVarDesc)
- pItfTI->ReleaseVarDesc(pVarDesc);
- if (pITISelf2)
- pITISelf2->Release();
- return hr;
-} // HRESULT CImportTlb::HasNewEnumMember(ITypeInfo *pItfTI)
-
-//*****************************************************************************
-// Determine if a given function is a valid NewEnum member.
-//*****************************************************************************
-HRESULT CImportTlb::FuncIsNewEnum( // S_OK if the function is the NewEnum member S_FALSE otherwise.
- ITypeInfo *pITI, // The ITypeInfo that contains the function.
- FUNCDESC *pFuncDesc, // The function in question.
- DWORD index) // The function index
-{
-
- HRESULT hr = S_OK;
- BOOL bIsValidNewEnum = FALSE;
- TYPEDESC* pType = NULL;
- TYPEATTR* pAttr = NULL;
- ITypeInfo* pITIUD = NULL;
- long lDispSet = 0;
-
- _GetDispIDCA(pITI, index, &lDispSet, TRUE);
-
- if ((pFuncDesc->memid == DISPID_NEWENUM) || (lDispSet == DISPID_NEWENUM))
- {
- if (pFuncDesc->funckind == FUNC_DISPATCH)
- {
- if ((pFuncDesc->invkind == INVOKE_PROPERTYGET) || (pFuncDesc->invkind == INVOKE_FUNC))
- {
- if (pFuncDesc->cParams == 0)
- {
- pType = &pFuncDesc->elemdescFunc.tdesc;
- }
- else if ((m_bTransformDispRetVals) && (pFuncDesc->cParams == 1) && (pFuncDesc->lprgelemdescParam[0].paramdesc.wParamFlags & PARAMFLAG_FRETVAL))
- {
- pType = pFuncDesc->lprgelemdescParam[0].tdesc.lptdesc;
- }
- }
- }
- else if (pFuncDesc->funckind == FUNC_PUREVIRTUAL)
- {
- if ((pFuncDesc->cParams == 1) &&
- ((pFuncDesc->invkind == INVOKE_PROPERTYGET) || (pFuncDesc->invkind == INVOKE_FUNC)) &&
- (pFuncDesc->lprgelemdescParam[0].paramdesc.wParamFlags & PARAMFLAG_FRETVAL) &&
- (pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_PTR))
- {
- pType = pFuncDesc->lprgelemdescParam[0].tdesc.lptdesc;
- }
- }
-
- if (pType)
- {
- if (pType->vt == VT_UNKNOWN || pType->vt == VT_DISPATCH)
- {
- // The member returns an IUnknown * or an IDispatch * which is valid.
- bIsValidNewEnum = TRUE;
- }
- else if (pType->vt == VT_PTR)
- {
- pType = pType->lptdesc;
- if (pType->vt == VT_USERDEFINED)
- {
- IfFailGo(pITI->GetRefTypeInfo(pType->hreftype, &pITIUD));
- IfFailGo(pITIUD->GetTypeAttr(&pAttr));
- if (IsEqualGUID(pAttr->guid, IID_IEnumVARIANT) ||
- IsEqualGUID(pAttr->guid, IID_IUnknown) ||
- IsEqualGUID(pAttr->guid, IID_IDispatch))
- {
- // The member returns a valid interface type for a NewEnum member.
- bIsValidNewEnum = TRUE;
- }
- }
- }
- }
- }
-
-ErrExit:
- if (pAttr)
- pITIUD->ReleaseTypeAttr(pAttr);
- if (pITIUD)
- pITIUD->Release();
-
- if (FAILED(hr))
- return hr;
- else
- return bIsValidNewEnum ? S_OK : S_FALSE;
-} // HRESULT CImportTlb::FuncIsNewEnum(FUNCDESC *pFuncDesc)
-
-//*****************************************************************************
-// Determine if a given function is a valid NewEnum member.
-//*****************************************************************************
-HRESULT CImportTlb::PropertyIsNewEnum( // S_OK if the function is the NewEnum member S_FALSE otherwise.
- ITypeInfo *pITI, // The ITypeInfo that contains the property.
- VARDESC *pVarDesc, // The function in question.
- DWORD index) // The property index.
-{
- HRESULT hr = S_OK;
- BOOL bIsValidNewEnum = FALSE;
- TYPEDESC* pType = NULL;
- TYPEATTR* pAttr = NULL;
- ITypeInfo* pITIUD = NULL;
- long lDispSet = 0;
-
- _GetDispIDCA(pITI, index, &lDispSet, FALSE);
-
- if ( ((pVarDesc->memid == DISPID_NEWENUM) || (lDispSet == DISPID_NEWENUM)) &&
- (pVarDesc->elemdescVar.paramdesc.wParamFlags & PARAMFLAG_FRETVAL) &&
- (pVarDesc->wVarFlags & VARFLAG_FREADONLY))
- {
- pType = &pVarDesc->elemdescVar.tdesc;
- if (pType->vt == VT_UNKNOWN || pType->vt == VT_DISPATCH)
- {
- // The member returns an IUnknown * or an IDispatch * which is valid.
- bIsValidNewEnum = TRUE;
- }
- else if (pType->vt == VT_PTR)
- {
- pType = pType->lptdesc;
- if (pType->vt == VT_USERDEFINED)
- {
- IfFailGo(pITI->GetRefTypeInfo(pType->hreftype, &pITIUD));
- IfFailGo(pITIUD->GetTypeAttr(&pAttr));
- if (IsEqualGUID(pAttr->guid, IID_IEnumVARIANT) ||
- IsEqualGUID(pAttr->guid, IID_IUnknown) ||
- IsEqualGUID(pAttr->guid, IID_IDispatch))
- {
- // The member returns a valid interface type for a NewEnum member.
- bIsValidNewEnum = TRUE;
- }
- }
- }
- }
-
-ErrExit:
- if (pAttr)
- pITIUD->ReleaseTypeAttr(pAttr);
- if (pITIUD)
- pITIUD->Release();
-
- if (FAILED(hr))
- return hr;
- else
- return bIsValidNewEnum ? S_OK : S_FALSE;
-} // HRESULT CImportTlb::FuncIsNewEnum(FUNCDESC *pFuncDesc)
-
-//*****************************************************************************
-// Determine is a TypeInfo has any object fields.
-//*****************************************************************************
-HRESULT CImportTlb::HasObjectFields( // S_OK, S_FALSE, or error.
- ITypeInfo *pITI, // The TypeInfo in question.
- TYPEATTR *psAttr) // Attributes of the typeinfo.
-{
- HRESULT hr; // A result.
-
- int i; // Loop control.
- VARDESC *psVar=0; // VARDESC for a member.
-
- // Iterate over the vars.
- for (i=0; i<psAttr->cVars; ++i)
- {
- // Get variable information.
- IfFailGo(pITI->GetVarDesc(i, &psVar));
-
- // See if it is an object type.
- IfFailGo(IsObjectType(pITI, &psVar->elemdescVar.tdesc));
- // If result is S_FALSE, not an Object; keep looking.
- if (hr == S_OK)
- goto ErrExit;
-
- // Release for next var.
- pITI->ReleaseVarDesc(psVar);
- psVar = 0;
- }
-
- hr = S_FALSE;
-
-ErrExit:
- if (psVar)
- pITI->ReleaseVarDesc(psVar);
- return hr;
-} // HRESULT CImportTlb::HasObjectFields()
-
-//*****************************************************************************
-// Is a given type an Object type?
-//*****************************************************************************
-HRESULT CImportTlb::IsObjectType( // S_OK, S_FALSE, or error.
- ITypeInfo *pITI, // The TypeInfo in question.
- const TYPEDESC *pType) // The type.
-{
- HRESULT hr; // A result.
- TYPEDESC tdTemp; // Copy of TYPEDESC, for R/W.
- ITypeInfo *pITIAlias=0; // Typeinfo of the aliased type.
- TYPEATTR *psAttrAlias=0; // TYPEATTR of the aliased typeinfo.
- int bObjectField=false; // The question to be answered.
- int iByRef=0; // Indirection.
-
- // Strip off leading VT_PTR and VT_BYREF
- while (pType->vt == VT_PTR)
- pType = pType->lptdesc, ++iByRef;
- if (pType->vt & VT_BYREF)
- {
- tdTemp = *pType;
- tdTemp.vt &= ~VT_BYREF;
- pType = &tdTemp;
- ++iByRef;
- }
-
- // Determine if the field is/has object type.
- switch (pType->vt)
- {
- case VT_PTR:
- _ASSERTE(!"Should not have VT_PTR here");
- break;
-
- // These are object types.
- case VT_BSTR:
- case VT_DISPATCH:
- case VT_VARIANT:
- case VT_UNKNOWN:
- case VT_SAFEARRAY:
- case VT_LPSTR:
- case VT_LPWSTR:
- bObjectField = true;
- break;
-
- // A user-defined may or may not be/contain Object type.
- case VT_USERDEFINED:
- // User defined type. Get the TypeInfo.
- IfFailGo(pITI->GetRefTypeInfo(pType->hreftype, &pITIAlias));
- IfFailGo(pITIAlias->GetTypeAttr(&psAttrAlias));
-
- // Some user defined class. Is it a value class, or a VOS class?
- switch (psAttrAlias->typekind)
- {
- // Alias -- Is the aliased thing an Object type?
- case TKIND_ALIAS:
- hr = IsObjectType(pITIAlias, &psAttrAlias->tdescAlias);
- goto ErrExit;
- // Record/Enum/Union -- Does it contain an Object type?
- case TKIND_RECORD:
- case TKIND_ENUM:
- case TKIND_UNION:
- // Byref/Ptrto record is Object. Contained record might be.
- if (iByRef)
- bObjectField = true;
- else
- {
- hr = HasObjectFields(pITIAlias, psAttrAlias);
- goto ErrExit;
- }
- break;
- // Class/Interface -- An Object Type.
- case TKIND_INTERFACE:
- case TKIND_DISPATCH:
- case TKIND_COCLASS:
- bObjectField = true;
- break;
- default:
- //case TKIND_MODULE: -- can't pass one of these as a parameter.
- _ASSERTE(!"Unexpected typekind for user defined type");
- bObjectField = true;
- } // switch (psAttrAlias->typekind)
- break;
-
- case VT_CY:
- case VT_DATE:
- case VT_DECIMAL:
- // Pointer to the value type is an object. Contained one isn't.
- if (iByRef)
- bObjectField = true;
- else
- bObjectField = false;
- break;
-
- // A fixed array is an Object type.
- case VT_CARRAY:
- bObjectField = true;
- break;
-
- // Other types I4, etc., are not Object types.
- default:
- bObjectField = false;
- break;
- } // switch (vt=pType->vt)
-
-
- hr = bObjectField ? S_OK : S_FALSE;
-
-ErrExit:
- if (psAttrAlias)
- pITIAlias->ReleaseTypeAttr(psAttrAlias);
- if (pITIAlias)
- pITIAlias->Release();
-
- return hr;
-} // HRESULT CImportTlb::IsObjectType()
-
-//*****************************************************************************
-// Convert the functions on an interface. Convert the functions on the
-// base interface first, because in COM Classic, parent's functions are also
-// in the derived interface's vtable.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvIfaceMembers(
- ITypeInfo *pITI, // The containing ITypeInfo.
- TYPEATTR *psAttr, // The ITypeInfo's TYPEATTR
- BOOL bVtblGapFuncs, // Add functions for vtblGaps?
- BOOL bAddDispIds, // Add DispIds to the member?
- BOOL bInheritsIEnum) // Inherits from IEnumerable.
-{
- HRESULT hr=S_OK; // A result.
- int i; // Loop control.
- FUNCDESC *psFunc=0; // FUNCDESC for a member.
-
- HREFTYPE href; // Base interface href.
- ITypeInfo *pITIBase=0; // Base interface ITypeInfo.
- TYPEATTR *psAttrBase=0; // TYPEATTR of base interface.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
-
- _ASSERTE( (psAttr->typekind == TKIND_INTERFACE) || (psAttr->typekind == TKIND_DISPATCH) );
-
- // If IDispatch or IUnknown, we've recursed far enough.
- if (IsEqualGUID(psAttr->guid, IID_IUnknown) || IsEqualGUID(psAttr->guid, IID_IDispatch))
- {
- if (m_cbVtableSlot == 0)
- {
- m_cbVtableSlot = psAttr->cbSizeInstance;
- }
- m_Slot = (psAttr->cbSizeVft / m_cbVtableSlot);
- goto ErrExit;
- }
-
- // Handle base interface.
- if (psAttr->cImplTypes == 1)
- {
- IfFailGo(pITI->GetRefTypeOfImplType(0, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
-
- IfFailGo(_ConvIfaceMembers(pITIBase, psAttrBase, bVtblGapFuncs, bAddDispIds, bInheritsIEnum));
-
- pITIBase->ReleaseTypeAttr(psAttrBase);
- psAttrBase = 0;
- pITIBase->Release();
- pITIBase = 0;
- }
- else
- { // No base interface, not IUnknown, not IDispatch. We shouldn't be here.
- m_Slot = 0;
- if (m_cbVtableSlot == 0)
- {
- m_cbVtableSlot = psAttr->cbSizeInstance;
- }
- _ASSERTE(!"Interface does not derive from IUnknown.");
- }
-
- // Loop over functions.
- IfFailGo(_FindFirstUserMethod(pITI, psAttr, &i));
- IfFailGo(BuildMemberList(pITI, i, psAttr->cFuncs, bInheritsIEnum));
-
- BOOL bAllowIEnum = !bInheritsIEnum;
- for (i=0; i<(int)m_MemberList.Size(); ++i)
- {
- // Convert the function.
- IfFailGo(_ConvFunction(pITI, &m_MemberList[i], bVtblGapFuncs, bAddDispIds, FALSE, &bAllowIEnum));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
- }
-
- // Add the property info.
- IfFailGo(_ConvPropertiesForFunctions(pITI, psAttr));
-
- if (bConversionLoss)
- hr = S_CONVERSION_LOSS;
-
-ErrExit:
- // Release FuncDescs.
- FreeMemberList(pITI);
-
- if (psAttrBase)
- pITIBase->ReleaseTypeAttr(psAttrBase);
- if (pITIBase)
- pITIBase->Release();
- if (psFunc)
- pITI->ReleaseFuncDesc(psFunc);
- return (hr);
-} // HRESULT CImportTlb::_ConvIfaceMembers()
-
-//*****************************************************************************
-// Convert the functions on a source interface to add_ and remove_ method.
-// Convert the functions on the base interface first, because in COM Classic,
-// parent's functions are also in the derived interface's vtable.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvSrcIfaceMembers(
- ITypeInfo *pITI, // The containing ITypeInfo.
- TYPEATTR *psAttr, // The ITypeInfo's TYPEATTR
- BOOL fInheritsIEnum)
-{
- HRESULT hr=S_OK; // A result.
- int i; // Loop control.
- FUNCDESC *psFunc=0; // FUNCDESC for a member.
- HREFTYPE href; // Base interface href.
- ITypeInfo *pITIBase=0; // Base interface ITypeInfo.
- TYPEATTR *psAttrBase=0; // TYPEATTR of base interface.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
-
- _ASSERTE( (psAttr->typekind == TKIND_INTERFACE) || (psAttr->typekind == TKIND_DISPATCH) );
-
- // If IDispatch or IUnknown, we've recursed far enough.
- if (IsEqualGUID(psAttr->guid, IID_IUnknown) || IsEqualGUID(psAttr->guid, IID_IDispatch))
- {
- if (m_cbVtableSlot == 0)
- {
- m_cbVtableSlot = psAttr->cbSizeInstance;
- }
- m_Slot = (psAttr->cbSizeVft / m_cbVtableSlot);
- goto ErrExit;
- }
-
- // Handle base interface.
- if (psAttr->cImplTypes == 1)
- {
- IfFailGo(pITI->GetRefTypeOfImplType(0, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
-
- IfFailGo(_ConvSrcIfaceMembers(pITIBase, psAttrBase, fInheritsIEnum));
- pITIBase->ReleaseTypeAttr(psAttrBase);
- psAttrBase = 0;
- pITIBase->Release();
- pITIBase = 0;
- }
- else
- { // No base interface, not IUnknown, not IDispatch. We shouldn't be here.
- m_Slot = 0;
- if (m_cbVtableSlot == 0)
- {
- m_cbVtableSlot = psAttr->cbSizeInstance;
- }
- _ASSERTE(!"Interface does not derive from IUnknown.");
- }
-
- // Loop over functions.
- IfFailGo(_FindFirstUserMethod(pITI, psAttr, &i));
- IfFailGo(BuildMemberList(pITI, i, psAttr->cFuncs, fInheritsIEnum));
-
- // If we have any properties, we want to skip them. Should we add gaps?
- if (m_cMemberProps != 0)
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_W_NO_PROPS_IN_EVENTS, m_szName);
- bConversionLoss = true;
- }
-
- for (i = m_cMemberProps; i<(int)m_MemberList.Size(); ++i)
- {
- // Convert the function.
- IfFailGo(_GenerateEvent(pITI, &m_MemberList[i], fInheritsIEnum));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
- }
-
- if (bConversionLoss)
- hr = S_CONVERSION_LOSS;
-
-ErrExit:
- // Release FuncDescs.
- FreeMemberList(pITI);
-
- if (psAttrBase)
- pITIBase->ReleaseTypeAttr(psAttrBase);
- if (pITIBase)
- pITIBase->Release();
- if (psFunc)
- pITI->ReleaseFuncDesc(psFunc);
- return (hr);
-} // HRESULT CImportTlb::_ConvIfaceMembers()
-
-//*****************************************************************************
-// Add the property definitions for property functions.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvPropertiesForFunctions(
- ITypeInfo *pITI, // ITypeInfo* being converted.
- TYPEATTR *psAttr) // TypeAttr for the typeinfo.
-{
- HRESULT hr=S_OK; // A result.
- int ix; // Loop control.
- int ix2; // More loop control.
- mdProperty pd; // A property token.
- USHORT ms; // Some method's semantics.
- mdToken tk; // A method's token.
- mdMethodDef mdFuncs[6] ={0}; // Array of setter, getter, other.
- FUNCDESC *psF=0; // FUNCDESC of Get, Put, or PutRef.
- TYPEDESC *pProperty; // TYPEDESC of property type.
- BOOL bPropRetval; // Is the property type a [retval]?
- ULONG ixValue; // Index of the value parameter for putters.
- int ixVarArg; // Index of vararg param, if any.
- CQuickBytes qbComSig; // new signature
- BYTE *pbSig; // Pointer into the signature.
- ULONG sigFlags; // Signature handling flags.
- ULONG cbTotal; // Size of the signature.
- ULONG cb; // Size of a signature element.
- LPWSTR pszName; // Possibly decorated name of property.
- CQuickArray<WCHAR> qbName; // Buffer for name decoration.
- int iSrcParam; // Param count, as looping through params.
- int cDestParams; // Count of destination params.
- CQuickArray<BYTE> qbDummyNativeTypeBuf; // A dummy native type array.
- ULONG iNativeOfs=0; // Current offset in native type buffer.
- BOOL bNewEnumMember=FALSE; // Is this a NewEnum property?
- BOOL bConversionLoss=FALSE; // Was some type not fully converted?
- int cFound; // Functions found matching a given property.
-
- // Using semantics as an index, so be sure array is big enough.
- _ASSERTE(lengthof(mdFuncs) > msOther);
-
- for (ix=m_cMemberProps; ix<(int)m_MemberList.Size(); ++ix)
- { // See if this one needs to be processed.
- if (m_MemberList[ix].m_mdFunc == 0)
- continue;
-
- MemberInfo *pMember = &m_MemberList[ix];
- pMember->GetFuncInfo(tk, ms);
-
- // Get the name.
- if (m_szMember)
- ::SysFreeString(m_szMember), m_szMember = 0;
- IfFailGo(pITI->GetDocumentation(pMember->m_psFunc->memid, &m_szMember, 0,0,0));
-
- // Found one. Put in the right slot.
- _ASSERTE(ms == msGetter || ms == msSetter || ms==msOther);
- mdFuncs[msSetter] = mdFuncs[msGetter] = mdFuncs[msOther] = 0;
- mdFuncs[ms] = tk;
- pMember->m_mdFunc = 0;
-
- // Look for related functions.
- cFound = 1;
- for (ix2=ix+1; ix2<(int)m_MemberList.Size(); ++ix2)
- {
- MemberInfo *pMember2 = &m_MemberList[ix2];
- if (pMember2->m_mdFunc != 0 && pMember2->m_psFunc->memid == pMember->m_psFunc->memid)
- { // Found a related function.
- pMember2->GetFuncInfo(tk, ms);
- _ASSERTE(ms == msGetter || ms == msSetter || ms==msOther);
- _ASSERTE(mdFuncs[ms] == 0);
- mdFuncs[ms] = tk;
- pMember2->m_mdFunc = 0;
- // If have found all three, don't bother looking for more.
- if (++cFound == 3)
- break;
- }
- }
-
- // Build the signature for the property.
- hr = _GetFunctionPropertyInfo(pMember->m_psFunc, &ms, &psF, &pProperty, &bPropRetval, TRUE, m_szMember);
-
- // The function really should have a property associated with it, to get here. Check anyway.
- _ASSERTE(pProperty);
- if (!pProperty)
- continue;
-
- // Some sort of property accessor.
- IfFailGo(qbComSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE + 1));
- pbSig = (BYTE *)qbComSig.Ptr();
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_PROPERTY, pbSig);
- // Count of parameters.
-
- // If this is a getter, see if there is a retval.
- if (psF->invkind == INVOKE_PROPERTYGET)
- { // Examine each param, and count all except the [retval].
- for (cDestParams=iSrcParam=0; iSrcParam<psF->cParams; ++iSrcParam)
- {
- if ((psF->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & NON_CONVERTED_PARAMS_FLAGS) == 0)
- ++cDestParams;
- }
- // There is no new value param for getters.
- ixValue = -1;
- }
- else
- {
- // This is a putter, so 1 param is new value, others are indices (or lcid).
- for (cDestParams=iSrcParam=0; iSrcParam<psF->cParams-1; ++iSrcParam)
- {
- if ((psF->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & NON_CONVERTED_PARAMS_FLAGS) == 0)
- ++cDestParams;
- }
- // The last parameter is the new value.
- ixValue = psF->cParams - 1;
- }
-
- //-------------------------------------------------------------------------
- // See if there is a vararg param.
- ixVarArg = psF->cParams + 1;
- if (psF->cParamsOpt == -1)
- {
- // If this is a PROPERTYPUT or PROPERTYPUTREF, skip the last non-retval parameter (it
- // is the new value to be set).
- BOOL bPropVal = (psF->invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF)) ? TRUE : FALSE;
- // Find the vararg param.
- for (iSrcParam=psF->cParams-1; iSrcParam>=0; --iSrcParam)
- {
- // The count of optional params does not include any lcid params, nor does
- // it include the return value, so skip those.
- if ((psF->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & (PARAMFLAG_FRETVAL|PARAMFLAG_FLCID)) != 0)
- continue;
- // If haven't yet seen the property value, this param is it, so skip it, too.
- if (bPropVal)
- {
- bPropVal = FALSE;
- continue;
- }
- ixVarArg = iSrcParam;
- break;
- } // for (iSrcParam=cParams-1...
- }
-
- // Put in the count of index parameters.
- _ASSERTE(cDestParams >= 0);
- cb = CorSigCompressData(cDestParams, &pbSig[cbTotal]);
- cbTotal += cb;
-
- // Create the signature for the property type.
- sigFlags = SIG_ELEM | (bPropRetval ? SIG_RET : (SigFlags)0);
- IfFailGo(_ConvSignature(pITI, pProperty, sigFlags, qbComSig, cbTotal, &cbTotal, qbDummyNativeTypeBuf, 0, &iNativeOfs, bNewEnumMember));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
-
- // Fill in the "index" part of the property's signature.
- for (iSrcParam=0; iSrcParam<psF->cParams; ++iSrcParam)
- {
- if (psF->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & NON_CONVERTED_PARAMS_FLAGS)
- continue;
- if (iSrcParam == static_cast<int>(ixValue))
- continue;
- sigFlags = SIG_FUNC | SIG_USE_BYREF;
- if (iSrcParam == ixVarArg)
- sigFlags |= SIG_VARARG;
- IfFailGo(_ConvSignature(pITI, &psF->lprgelemdescParam[iSrcParam].tdesc, sigFlags, qbComSig, cbTotal, &cbTotal, qbDummyNativeTypeBuf, 0, &iNativeOfs, bNewEnumMember));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
- }
-
- // Get the property name. Add interface name and make unique, if needed.
- // m_szInterface should be non-null if processing an implemented interface; should be null otherwise.
- _ASSERTE(m_ImplIface == eImplIfaceNone || m_szInterface != 0);
- IfFailGo(qbName.ReSizeNoThrow(wcslen(m_szMember)+2));
- wcscpy_s(qbName.Ptr(), wcslen(m_szMember)+2, m_szMember);
- IfFailGo(GenerateUniqueMemberName(qbName, (PCCOR_SIGNATURE)qbComSig.Ptr(), cbTotal, m_szInterface, mdtProperty));
- pszName = qbName.Ptr();
-
- // Define the property.
- IfFailGo(m_pEmit->DefineProperty(m_tdTypeDef, pszName, 0/*dwFlags*/,
- (PCCOR_SIGNATURE) qbComSig.Ptr(), cbTotal, 0, 0, -1,
- mdFuncs[msSetter], mdFuncs[msGetter], &mdFuncs[msOther],
- &pd));
-
- // Handle dispids for non-implemented interfaces, and for default interface
- if (m_ImplIface != eImplIface)
- {
- // Set the dispid CA on the property.
- long lDispSet = 1;
- _SetDispIDCA(pITI, pMember->m_iMember, psF->memid, pd, TRUE, &lDispSet, TRUE);
-
- // If this property is default property, add a custom attribute to the class.
- if (lDispSet == DISPID_VALUE)
- IfFailGo(_AddDefaultMemberCa(m_tdTypeDef, m_szMember));
- }
-
- // Add the alias information if the type is an alias.
- IfFailGo(_HandleAliasInfo(pITI, pProperty, pd));
- }
-
- if (bConversionLoss)
- hr = S_CONVERSION_LOSS;
-
-ErrExit:
- if (m_szMember)
- ::SysFreeString(m_szMember), m_szMember=0;
-
- return hr;
-} // HRESULT CImportTlb::_ConvPropertiesForFunctions()
-
-//*****************************************************************************
-// Convert the vars and functions of a dispinterface. Vars actually turn
-// into a getter and possibly a setter.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvDispatchMembers(
- ITypeInfo *pITI, // ITypeInfo* to convert.
- TYPEATTR *psAttr, // TypeAttr of ITypeInfo.
- BOOL fInheritsIEnum)
-{
- HRESULT hr; // A result.
- int i; // Loop control.
- BOOL bConversionLoss=FALSE; // If true, some attributes were lost on conversion.
-
- IfFailGo(_FindFirstUserMethod(pITI, psAttr, &i));
- IfFailGo(BuildMemberList(pITI, i, psAttr->cFuncs, fInheritsIEnum));
-
- // Dispatch members really have no slot.
- m_Slot = 0;
-
- // Loop over properties.
- for (i=0; i<m_cMemberProps; ++i)
- {
- IfFailGo(_ConvProperty(pITI, &m_MemberList[i]));
- }
-
- // Loop over functions.
- BOOL bAllowIEnum = !fInheritsIEnum;
- for (; i<(int)m_MemberList.Size(); ++i)
- {
- // Get variable information.
- IfFailGo(_ConvFunction(pITI, &m_MemberList[i], FALSE, TRUE, FALSE, &bAllowIEnum));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = TRUE;
- }
-
- // Add the property info.
- IfFailGo(_ConvPropertiesForFunctions(pITI, psAttr));
-
- if (bConversionLoss)
- hr = S_CONVERSION_LOSS;
-
-ErrExit:
- // Free the func descs.
- FreeMemberList(pITI);
-
- return (hr);
-} // HRESULT CImportTlb::_ConvDispatchMembers()
-
-//*****************************************************************************
-// Examine the functions on an interface, and skip the first 3 or first 7
-// if the functions are IUnknown or IDispatch members.
-//*****************************************************************************
-HRESULT CImportTlb::_FindFirstUserMethod(
- ITypeInfo *pITI, // The Typedef to examine.
- TYPEATTR *psAttr, // TYPEATTR for the typedef.
- int *pIx) // Put index of first user function here.
-{
- HRESULT hr = S_OK; // A result.
- int i; // Loop control.
- FUNCDESC *psFunc=0; // FUNCDESC for a member.
- BSTR szName=0; // A function's name.
-
- // Note: this is a terrible workaround, but in some situations the methods from IUnknown / IDispatch will
- // show up as though native dispatch functions.
- i = 0;
- if (psAttr->cFuncs >= 3)
- {
- IfFailGo(TryGetFuncDesc(pITI, i, &psFunc));
- if (psFunc->memid == 0x60000000 &&
- psFunc->elemdescFunc.tdesc.vt == VT_VOID &&
- psFunc->cParams == 2 &&
- psFunc->lprgelemdescParam[0].tdesc.vt == VT_PTR && // -> VT_USERDEFINED
- psFunc->lprgelemdescParam[1].tdesc.vt == VT_PTR && // -> VT_PTR -> VT_VOID
- SUCCEEDED(pITI->GetDocumentation(psFunc->memid, &szName, 0,0,0)) &&
- (wcscmp(szName, W("QueryInterface")) == 0) )
- i = 3;
- pITI->ReleaseFuncDesc(psFunc);
- psFunc=0;
- if (szName)
- ::SysFreeString(szName);
- szName = 0;
- if (psAttr->cFuncs >= 7)
- {
- IfFailGo(TryGetFuncDesc(pITI, i, &psFunc));
- if (psFunc->memid == 0x60010000 &&
- psFunc->elemdescFunc.tdesc.vt == VT_VOID &&
- psFunc->cParams == 1 &&
- psFunc->lprgelemdescParam[0].tdesc.vt == VT_PTR && // -> VT_UINT
- SUCCEEDED(pITI->GetDocumentation(psFunc->memid, &szName, 0,0,0)) &&
- (wcscmp(szName, W("GetTypeInfoCount")) == 0) )
- i = 7;
- pITI->ReleaseFuncDesc(psFunc);
- psFunc=0;
- if (szName)
- ::SysFreeString(szName);
- szName = 0;
- }
- }
-
- *pIx = i;
-
-ErrExit:
- if (psFunc)
- pITI->ReleaseFuncDesc(psFunc);
- if (szName)
- ::SysFreeString(szName);
- return (hr);
-} // HRESULT CImportTlb::_FindFirstUserMethod()
-
-//*****************************************************************************
-// Given a FUNCDESC that is has INVOKE_PROPERTY* decoration, determine
-// the role of the function, and the property signature type.
-//*****************************************************************************
-HRESULT CImportTlb::_GetFunctionPropertyInfo(
- FUNCDESC *psFunc, // Function for which to get info.
- USHORT *pSemantics, // Put appropriate semantics here.
- FUNCDESC **ppSig, // Put FUNCDESC for signature here.
- TYPEDESC **ppProperty, // Put TYPEDESC for return here.
- BOOL *pbRetval, // If true, the type is [retval]
- BOOL fUseLastParam, // If true, default to the last parameter as the return value
- BSTR strName) // Name of the property
-{
- FUNCDESC *psTmp; // FUNCDESC for some method.
- FUNCDESC *psGet=0; // FUNCDESC for Get method defining a property.
- FUNCDESC *psPut=0; // FUNCDESC for Put method defining a property.
- FUNCDESC *psPutRef=0; // FUNCDESC for PutRef method defining a property.
- FUNCDESC *psF; // A FUNCDESC.
- TYPEDESC *pReturn=0; // The FUNCDESC's return type.
- int cFound=0; // Count of functions found.
- int i; // Loop control.
- HRESULT hr = S_OK;
-
- if (psFunc->invkind & INVOKE_PROPERTYGET)
- { // A "Get", so return type is property type.
- *ppSig = psFunc;
- *pSemantics = msGetter;
- }
- else
- {
- _ASSERTE(psFunc->invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF));
- // Search for the "best" method from which to grab the signature. We prefer the Get(),
- // Followed by the Put(), followed by the PutRef()
- // Also look for Put() and PutRef(), so we can
- for (int iFunc=0; iFunc<(int)m_MemberList.Size() && cFound<3; ++iFunc)
- {
- // Get a FUNCDESC from the list.
- psTmp = m_MemberList[iFunc].m_psFunc;
-
- // Is it for the same func?
- if (psTmp->memid != psFunc->memid)
- continue;
-
- // Is it the Get()? If so, it is the one we want.
- if (psTmp->invkind & INVOKE_PROPERTYGET)
- {
- psGet = psTmp;
- ++cFound;
- continue;
- }
-
- // Is it the Put()? Use it if we don't find a Get().
- if (psTmp->invkind & INVOKE_PROPERTYPUT)
- {
- psPut = psTmp;
- ++cFound;
- continue;
- }
-
- // Is it the PutRef()? Keep track of it.
- if (psTmp->invkind & INVOKE_PROPERTYPUTREF)
- {
- psPutRef = psTmp;
- ++cFound;
- }
- }
- // Get the best FUNCDESC for the signature.
- *ppSig = psGet ? psGet : (psPut ? psPut : psFunc);
-
- // Determine whether this is a the "Set" or "VB specific Let" function.
- if (psFunc->invkind & INVOKE_PROPERTYPUTREF)
- { // This function is the PROPERTYPUTREF. Make it the setter. If
- // there is also a PROPERTYPUT, it will be the "letter".
- *pSemantics = msSetter;
- }
- else
- { // We are looking at the PROPERTYPUT function (the "Let" function in native VB6.).
-
- // If there is also a PROPERTYPUTREF, make this the "VB Specific Let" function.
- if (psPutRef)
- { // A PPROPERTYPUTREF also exists, so make this the "Let" function.
- *pSemantics = msOther;
- }
- else
- { // There is no PROPERTYPUTREF, so make this the setter.
- *pSemantics = msSetter;
- }
- }
- }
-
- // Occasionally there is a property with no discernable type. In that case, lose the
- // property on conversion.
-
- // Determine the type of the property, based on the "best" accessor.
- psF = *ppSig;
- *pbRetval = FALSE;
- if (psF->invkind & INVOKE_PROPERTYGET)
- { // look for [retval].
- for (i=psF->cParams-1; i>=0; --i)
- {
- if (psF->lprgelemdescParam[i].paramdesc.wParamFlags & PARAMFLAG_FRETVAL)
- { // will consume a level of indirection (later).
- *pbRetval = TRUE;
- pReturn = &psF->lprgelemdescParam[i].tdesc;
- break;
- }
- }
- // If no [retval], check return type.
- if (!pReturn && psF->elemdescFunc.tdesc.vt != VT_VOID && psF->elemdescFunc.tdesc.vt != VT_HRESULT)
- pReturn = &psF->elemdescFunc.tdesc;
-
- if (fUseLastParam)
- {
- // We may have stripped the [retval] if this is a disp-only interface. Just use the last parameter.
- if (!pReturn && (psF->cParams > 0))
- pReturn = &psF->lprgelemdescParam[psF->cParams-1].tdesc;
- }
- else
- {
- // If there is no type, don't try to set the getter.
- if (pReturn && pReturn->vt == VT_VOID)
- pReturn = NULL;
- }
-
- if (!pReturn)
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_PROPGET_WITHOUT_RETURN, strName, m_szMngName);
- }
- }
- else
- { // Find lastmost param that isn't [retval]. (Should be the last param, but it is
- // possible to write an IDL with a PROPERTYPUT that has a [retval].
- for (i=psF->cParams-1; i>=0; --i)
- {
- if ((psF->lprgelemdescParam[psF->cParams-1].paramdesc.wParamFlags & PARAMFLAG_FRETVAL) == 0)
- {
- { // First, and possibly only, param.
- pReturn = &psF->lprgelemdescParam[i].tdesc;
- break;
- }
- }
- }
- }
-
-//ErrExit:
- if (pReturn == 0)
- *pSemantics = 0;
- *ppProperty = pReturn;
-
- return hr;
-} // HRESULT CImportTlb::_GetFunctionPropertyInfo()
-
-//*****************************************************************************
-// Convert a function description to metadata entries.
-//
-// This can be rather involved. If the function is a INVOKE_PROPERTY*,
-// determine if it will be converted as a COM+ property, and if so, which
-// of up to three functions will be selected to provide the property
-// signature.
-// The function return type is found by scaning the parameters looking for
-// [retval]s.
-//*****************************************************************************
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
-#endif
-HRESULT CImportTlb::_ConvFunction(
- ITypeInfo *pITI, // Containing TypeInfo.
- MemberInfo *pMember, // iNFO for the function.
- BOOL bVtblGapFuncs, // Add functions for vtblGaps?
- BOOL bAddDispIds, // Add DispIds to the member?
- BOOL bDelegateInvokeMeth, // Convert function for a delegate invoke
- BOOL* bAllowIEnum) // Allowed to change this function to GetEnumerator
-{
- HRESULT hr; // A result.
- int iSrcParam; // Param count, as looping through params.
- int iDestParam; // Param count, as looping through params.
- int cDestParams; // Count of destination params.
- int ixOpt; // Index of first param that is optional due to cParamsOpt.
- int ixVarArg; // Index of vararg param, if any.
- mdMethodDef mdFunc; // Token of new member.
- BSTR szTypeName=0; // Name of the type.
- DWORD dwFlags=0; // Member flags.
- DWORD dwImplFlags=0; // The impl flags.
- WCHAR *pszName=0; // Possibly decorated name of member.
- CQuickArray<WCHAR> qbName; // Buffer for decorated name.
- TYPEDESC *pReturn=0; // Return type.
- int bRetval=false; // Is the return result a [retval] parameter?
- int ixRetval; // Which param is the [retval]?
- TYPEDESC *pReturnRetval=0; // Return type from [retval] (incl. indirection).
- WORD wRetFlags=0; // Return type flags.
- ULONG offset=0; // Offset of function
- BSTR *rszParamNames=0; // Parameter names.
- UINT iNames; // Count of actual names.
- CQuickBytes qbComSig; // new signature
- BYTE *pbSig; // Pointer into the signature.
- ULONG sigFlags; // Signature handling flags.
- CQuickArray<BYTE> qbNativeBuf; // Native type buffer.
- CQuickArray<BYTE> qbDummyNativeTypeBuf; // A dummy native type array.
- CQuickArray<ULONG> qbNativeOfs; // Offset of native type for each param.
- CQuickArray<ULONG> qbNativeLen; // Length of native type for each param.
- ULONG iNativeOfs=0; // Current offset in native type buffer.
- ULONG iNewNativeOfs=0; // New offset in native type buffer.
- ULONG cb; // Size of an element.
- ULONG cbTotal = 0; // Size of the signature.
- int bOleCall=false; // Is the implementation OLE style?(HRESULT or IDispatch)
- USHORT msSemantics=0; // Property's methodsemantics.
- WCHAR szSpecial[40]; // To build name of special function.
- mdToken tkAttr; // Token for custom attribute type.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
- enum {ParamRetval=-1, ParamNone=-2};
- int iParamError=ParamNone; // Index of param with conversion error.
- BOOL bNewEnumMember = FALSE; // A flag indicating if the member is the NewEnum member.
- int iLCIDParam = -1; // Index of the LCID parameter.
- FUNCDESC *psFunc = pMember->m_psFunc;
-
- // If we might insert vtable gaps, then we'd better have initialized the vtable slot size.
- _ASSERTE(!bVtblGapFuncs || (m_cbVtableSlot != 0));
-
- // Retrieve the member name from the member info.
- IfNullGo(m_szMember = SysAllocString(bDelegateInvokeMeth ? DELEGATE_INVOKE_METH_NAME : pMember->m_pName));
-
-#ifdef _DEBUG
- LPWSTR funcName = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TlbImpShouldBreakOnConvFunction);
- if (funcName)
- {
- if (wcscmp(funcName, pMember->m_pName) == 0)
- _ASSERTE(!"TlbImpBreakOnConvFunction");
-
- delete [] funcName;
- }
-#endif //_DEBUG
-
- // Determine if the member is the new enum member.
- if ((*bAllowIEnum))
- {
- bNewEnumMember = FuncIsNewEnum(pITI, psFunc, pMember->m_iMember) == S_OK;
-
- // Once a method is converted in this interface, don't convert any more.
- if (bNewEnumMember)
- *bAllowIEnum = FALSE;
- }
-
-
- // We should NEVER have a new enum member when we are dealing with a delegate invoke meth.
- if (bNewEnumMember && bDelegateInvokeMeth)
- {
- // Get the real name of the method
- BSTR szTypeInfoName = NULL;
- BSTR szMemberName = NULL;
- hr = m_pITI->GetDocumentation(MEMBERID_NIL, &szTypeInfoName, 0, 0, 0);
- if (FAILED(hr))
- szTypeInfoName = SysAllocString(W("???"));
-
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_EVENT_WITH_NEWENUM, szTypeInfoName);
-
- SysFreeString(szMemberName);
- SysFreeString(szTypeInfoName);
-
- IfFailGo(TLBX_E_EVENT_WITH_NEWENUM);
- }
-
- // If there is a gap in the vtable, emit a special function.
- if (bVtblGapFuncs)
- {
- if ((psFunc->oVft / m_cbVtableSlot) != m_Slot)
- {
- ULONG n = psFunc->oVft / m_cbVtableSlot;
- // Make sure slot numbers are monotonically increasing.
- if (n < m_Slot)
- {
- IfFailGo(pITI->GetDocumentation(MEMBERID_NIL, &szTypeName, 0, 0, 0));
- IfFailGo(PostError(TLBX_E_BAD_VTABLE, m_szMember, szTypeName, m_szLibrary));
- }
-
- n -= m_Slot;
- if (n == 1)
- _snwprintf_s(szSpecial, lengthof(szSpecial), lengthof(szSpecial) - 1, VTBL_GAP_FORMAT_1, VTBL_GAP_FUNCTION, m_Slot);
- else
- _snwprintf_s(szSpecial, lengthof(szSpecial), lengthof(szSpecial) - 1, VTBL_GAP_FORMAT_N, VTBL_GAP_FUNCTION, m_Slot, n);
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, szSpecial, VTBL_GAP_FUNCTION_FLAGS, VTBL_GAP_SIGNATURE,sizeof(VTBL_GAP_SIGNATURE),
- 0/* rva*/, VTBL_GAP_FUNC_IMPL_FLAGS, &mdFunc));
- m_Slot += n;
- }
- // What we will expect next time.
- ++m_Slot;
- }
-
- //-------------------------------------------------------------------------
- // Determine the return type.
- // If this is an hresult function, prepare to munge return, params.
- if (psFunc->elemdescFunc.tdesc.vt == VT_HRESULT)
- {
- bOleCall = true;
- }
- else
- {
- if ((psFunc->elemdescFunc.tdesc.vt != VT_VOID) && (psFunc->elemdescFunc.tdesc.vt != VT_HRESULT))
- pReturn = &psFunc->elemdescFunc.tdesc;
- }
-
- // Look for [RETVAL].
- for (iSrcParam=0; iSrcParam<psFunc->cParams; ++iSrcParam)
- {
- if (psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & PARAMFLAG_FRETVAL)
- {
- // If already have a return, or a DISPATCH function, error.
- if (pReturn != 0)
- { // Unexpected return found.
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_AMBIGUOUS_RETURN, m_szName, m_szMember);
- IfFailGo(TLBX_E_AMBIGUOUS_RETURN);
- }
- else
- { // Found a return type.
- wRetFlags = psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags;
- pReturn = &psFunc->lprgelemdescParam[iSrcParam].tdesc;
- bRetval = true;
- ixRetval = iSrcParam;
- }
- break;
- }
- }
-
- // Check to see if there is an LCID parameter.
- for (iSrcParam=0;iSrcParam<psFunc->cParams;iSrcParam++)
- {
- if (psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & PARAMFLAG_FLCID)
- {
- if (iLCIDParam != -1)
- IfFailGo(PostError(TLBX_E_MULTIPLE_LCIDS, m_szName, m_szMember));
- iLCIDParam = iSrcParam;
- }
- }
-
- //-------------------------------------------------------------------------
- // Size buffers to accomodate parameters.
- // Resize the native type length array.
- IfFailGo(qbNativeBuf.ReSizeNoThrow(1));
- IfFailGo(qbNativeLen.ReSizeNoThrow(psFunc->cParams + 1));
- IfFailGo(qbNativeOfs.ReSizeNoThrow(psFunc->cParams + 1));
- memset(qbNativeLen.Ptr(), 0, (psFunc->cParams + 1)*sizeof(int));
- memset(qbNativeOfs.Ptr(), 0, (psFunc->cParams + 1)*sizeof(int));
-
- // resize to make room for calling convention and count of argument
- IfFailGo(qbComSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE + 1));
- pbSig = (BYTE *)qbComSig.Ptr();
-
- //-------------------------------------------------------------------------
- // Determine which params need to be marked optional, by virtue of cParamsOpt count.
- if (psFunc->cParamsOpt == 0)
- ixVarArg = ixOpt = psFunc->cParams + 1;
- else
- {
- if (psFunc->cParamsOpt == -1)
- { // Varargs.
- ixVarArg = ixOpt = psFunc->cParams + 1;
- // If this is a PROPERTYPUT or PROPERTYPUTREF, skip the last non-retval parameter (it
- // is the new value to be set).
- BOOL bPropVal = (psFunc->invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF)) ? TRUE : FALSE;
- // Find the vararg param.
- for (iSrcParam=psFunc->cParams-1; iSrcParam>=0; --iSrcParam)
- {
- // The count of optional params does not include any lcid params, nor does
- // it include the return value, so skip those.
- if ((psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & (PARAMFLAG_FRETVAL|PARAMFLAG_FLCID)) != 0)
- continue;
- // If haven't yet seen the property value, this param is it, so skip it, too.
- if (bPropVal)
- {
- bPropVal = FALSE;
- continue;
- }
- ixVarArg = iSrcParam;
- break;
- } // for (iSrcParam=cParams-1...
- }
- else
- { // ixOpt will be index of first optional parameter.
- short cOpt = psFunc->cParamsOpt;
- ixOpt = 0;
- ixVarArg = psFunc->cParams + 1;
- for (iSrcParam=psFunc->cParams-1; iSrcParam>=0; --iSrcParam)
- {
- // The count of optional params does not include any lcid params, nor does
- // it include the return value, so skip those.
- if ((psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & (PARAMFLAG_FRETVAL|PARAMFLAG_FLCID)) == 0)
- {
- if (--cOpt == 0)
- {
- ixOpt = iSrcParam;
- break;
- }
- }
- } // for (iSrcParam=cParams-1...
- }
- }
-
-
- //-------------------------------------------------------------------------
- // Get the parameter names.
- rszParamNames = reinterpret_cast<BSTR*>(_alloca((psFunc->cParams+1) * sizeof(BSTR*)));
-
- // Get list of names.
- IfFailGo(pITI->GetNames(psFunc->memid, rszParamNames, psFunc->cParams+1, &iNames));
-
- // zero name pointer for non-named params.
- for (iSrcParam=iNames; iSrcParam<=psFunc->cParams; ++iSrcParam)
- rszParamNames[iSrcParam] = 0;
-
- //-------------------------------------------------------------------------
- // Convert the calling convention, param count, and return type.
- cDestParams = psFunc->cParams;
- if (bRetval)
- --cDestParams;
- if (iLCIDParam != -1)
- --cDestParams;
-
- if (pReturn)
- {
- // Param count
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS, pbSig);
- cb = CorSigCompressData(cDestParams, &(pbSig[cbTotal]));
- cbTotal += cb;
- // Return type or [retval].
- if (bRetval)
- sigFlags = (SigFlags)(wRetFlags & SIG_FLAGS_MASK) | SIG_FUNC, iParamError=ixRetval;
- else
- sigFlags = SIG_FUNC, iParamError=ParamRetval;
- IfFailGo(_ConvSignature(pITI, pReturn, sigFlags, qbComSig, cbTotal, &cbTotal, qbNativeBuf, iNativeOfs, &iNewNativeOfs, bNewEnumMember));
- qbNativeLen[0] = iNewNativeOfs - iNativeOfs;
- qbNativeOfs[0] = iNativeOfs;
- iNativeOfs = iNewNativeOfs;
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
- }
- else
- { // No return value
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS, pbSig);
- cb = CorSigCompressData(cDestParams, &(pbSig[cbTotal]));
- cbTotal += cb;
- cb = CorSigCompressData(ELEMENT_TYPE_VOID, &pbSig[cbTotal]);
- cbTotal += cb;
- }
-
- //-------------------------------------------------------------------------
- // Translate each parameter.
- for (iSrcParam=0, iDestParam=0; iSrcParam<psFunc->cParams; ++iSrcParam)
- {
- if (!(psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & NON_CONVERTED_PARAMS_FLAGS))
- {
- sigFlags = (SigFlags)(psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & SIG_FLAGS_MASK) | SIG_FUNC | SIG_USE_BYREF;
- if (iSrcParam == ixVarArg)
- sigFlags |= SIG_VARARG;
- iParamError = iSrcParam;
- IfFailGo(_ConvSignature(pITI, &psFunc->lprgelemdescParam[iSrcParam].tdesc, sigFlags, qbComSig, cbTotal, &cbTotal, qbNativeBuf, iNativeOfs, &iNewNativeOfs, bNewEnumMember));
- qbNativeLen[iDestParam+1] = iNewNativeOfs - iNativeOfs;
- qbNativeOfs[iDestParam+1] = iNativeOfs;
- iNativeOfs = iNewNativeOfs;
- iDestParam++;
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
- }
- }
- iParamError = ParamNone;
-
- //-------------------------------------------------------------------------
- // Get the previously decorated name. Add interface name and make unique.
- if (bDelegateInvokeMeth)
- {
- pszName = (WCHAR*)DELEGATE_INVOKE_METH_NAME;
- }
- else
- {
- // m_szInterface should be non-null if processing an implemented interface; should be null otherwise.
- _ASSERTE(m_ImplIface == eImplIfaceNone || m_szInterface != 0);
- IfFailGo(qbName.ReSizeNoThrow(wcslen(pMember->m_pName)+2));
- wcscpy_s(qbName.Ptr(), wcslen(pMember->m_pName)+2, pMember->m_pName);
- IfFailGo(GenerateUniqueMemberName(qbName, (PCCOR_SIGNATURE)qbComSig.Ptr(), cbTotal, m_szInterface, mdtMethodDef));
- pszName = qbName.Ptr();
- }
-
- // Determine the function's semantics, flags and impl flags.
- if (!bDelegateInvokeMeth)
- {
- msSemantics = pMember->m_msSemantics;
- dwImplFlags = DEFAULT_ITF_FUNC_IMPL_FLAGS;
- dwFlags = msSemantics ? DEFAULT_PROPERTY_FUNC_FLAGS : DEFAULT_INTERFACE_FUNC_FLAGS;
- // If processing an implemented interface, remove the abstract bit. Methods on classes are not abstract.
- if (m_ImplIface != eImplIfaceNone)
- dwFlags &= ~mdAbstract;
- }
- else
- {
- msSemantics = 0;
- dwImplFlags = miRuntime;
- dwFlags = DELEGATE_INVOKE_FUNC_FLAGS;
- }
-
- //-------------------------------------------------------------------------
- // Create the function definition in the metadata.
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, pszName, dwFlags, (PCCOR_SIGNATURE) qbComSig.Ptr(),cbTotal,
- 0 /* rva*/, dwImplFlags | (bOleCall ? 0 : miPreserveSig), &mdFunc));
-
- // If the method is part of a property, save info to set up the property.
- if (msSemantics)
- pMember->SetFuncInfo(mdFunc, msSemantics);
-
- // Handle dispids for non-implemented interfaces, and for default interface
- if (m_ImplIface != eImplIface)
- {
- // Add the DispIds if the flag is set.
- long lDispSet = 1;
- _SetDispIDCA(pITI, pMember->m_iMember, psFunc->memid, mdFunc, bAddDispIds, &lDispSet, TRUE);
-
- // If this method is the default, and not a property accessor, add a custom attribute to the class.
- if (lDispSet == DISPID_VALUE && msSemantics == 0)
- IfFailGo(_AddDefaultMemberCa(m_tdTypeDef, m_szMember));
- }
-
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(int));
-
- // If this method has an LCID then set the LCIDConversion attribute.
- if (iLCIDParam != -1)
- {
- // Dispid for the function.
- BUILD_CUSTOM_ATTRIBUTE(int, iLCIDParam);
- IfFailGo(GetAttrType(ATTR_LCIDCONVERSION, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(mdFunc, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
- // Save the func flags for anyone that needs typelib's flags.
- if (psFunc->wFuncFlags)
- {
- IfFailGo(GetAttrType(ATTR_TYPELIBFUNC, &tkAttr));
- INIT_CUSTOM_ATTRIBUTE(sizeof(WORD));
- BUILD_CUSTOM_ATTRIBUTE(WORD, psFunc->wFuncFlags);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(mdFunc, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
-
- //-------------------------------------------------------------------------
- // Convert the param info for the return type.
- if (pReturn)
- { // store return value parameter as sequence 0
- if (bRetval)
- {
- hr = _IsAlias(pITI, &psFunc->lprgelemdescParam[ixRetval].tdesc);
- IfFailGo(hr);
- if (qbNativeLen[0] || hr == S_OK)
- {
- IfFailGo(_ConvParam(pITI, mdFunc, 0, &psFunc->lprgelemdescParam[ixRetval], ParamNormal, 0 /*rszParamNames[ixRetval+1]*/,
- &qbNativeBuf[qbNativeOfs[0]], qbNativeLen[0]));
- }
- }
- else
- {
- hr = _IsAlias(pITI, &psFunc->elemdescFunc.tdesc);
- IfFailGo(hr);
- if (qbNativeLen[0] || hr == S_OK)
- {
- IfFailGo(_ConvParam(pITI, mdFunc, 0, &psFunc->elemdescFunc, ParamNormal, 0,
- &qbNativeBuf[qbNativeOfs[0]], qbNativeLen[0]));
- }
- }
- }
-
- //-------------------------------------------------------------------------
- // Convert parameter info (flags, native type, default value).
- for (iSrcParam=iDestParam=0; iSrcParam<psFunc->cParams; ++iSrcParam)
- {
- if ((psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & NON_CONVERTED_PARAMS_FLAGS) == 0)
- {
- ParamOpts opt = ParamNormal;
- if (iSrcParam >= ixOpt)
- opt = ParamOptional;
- else
- if (iSrcParam == ixVarArg)
- opt = ParamVarArg;
- iDestParam++;
- IfFailGo(_ConvParam(pITI, mdFunc, iDestParam, &psFunc->lprgelemdescParam[iSrcParam], opt, rszParamNames[iSrcParam + 1],
- &qbNativeBuf[qbNativeOfs[iDestParam]], qbNativeLen[iDestParam]));
- }
- }
-
-
- //-------------------------------------------------------------------------
- // If processing an implemented interface, set up MethodImpls.
- if (m_ImplIface != eImplIfaceNone)
- {
- // Define a memberref on the implemented interface.
- mdToken mrItfMember;
- IfFailGo(m_pEmit->DefineMemberRef(m_tkInterface, pMember->m_pName, (PCCOR_SIGNATURE) qbComSig.Ptr(),cbTotal, &mrItfMember));
-
- // Define a method impl.
- IfFailGo(m_pEmit->DefineMethodImpl(m_tdTypeDef, mdFunc, mrItfMember));
- }
-
- if (bConversionLoss)
- {
- hr = S_CONVERSION_LOSS;
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_I_UNCONVERTABLE_ARGS, m_szName, m_szMember);
- }
-
-ErrExit:
- // Special case for typeload load failures -- they're very hard to diagnose.
- if (hr == TYPE_E_CANTLOADLIBRARY)
- {
- if (iParamError >= 0 && iParamError < psFunc->cParams && rszParamNames[iParamError+1])
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_PARAM_ERROR_NAMED, m_szName, rszParamNames[iParamError+1], m_szMember);
- else
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_PARAM_ERROR_UNNAMED, m_szName, iParamError, m_szMember);
- }
- if (rszParamNames)
- {
- for (iSrcParam=0; iSrcParam<=psFunc->cParams; ++iSrcParam)
- if (rszParamNames[iSrcParam])
- ::SysFreeString(rszParamNames[iSrcParam]);
- }
- if (m_szMember)
- ::SysFreeString(m_szMember), m_szMember=0;
- if (szTypeName)
- ::SysFreeString(szTypeName);
-
- return (hr);
-} // HRESULT CImportTlb::_ConvFunction()
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
-
-HRESULT CImportTlb::_SetHiddenCA(mdTypeDef token)
-{
- mdToken tkAttr;
- HRESULT hr = S_OK;
-
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(short));
- BUILD_CUSTOM_ATTRIBUTE(short, TYPEFLAG_FHIDDEN);
- IfFailGo(GetAttrType(ATTR_TYPELIBTYPE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- m_pEmit->DefineCustomAttribute(token, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0);
-
-ErrExit:
- return S_OK;
-}
-
-HRESULT CImportTlb::_ForceIEnumerableCVExists(ITypeInfo* pITI, BOOL* CVExists)
-{
- ITypeInfo2 *pITI2 = 0;
- *CVExists = FALSE;
- HRESULT hr = S_OK;
-
- pITI->QueryInterface(IID_ITypeInfo2, reinterpret_cast<void**>(&pITI2));
-
- if (pITI2)
- {
- VARIANT vCustomData;
- VariantInit(&vCustomData);
-
- IfFailGo(pITI2->GetCustData(GUID_ForceIEnumerable, &vCustomData));
-
- if (V_VT(&vCustomData) != VT_EMPTY)
- *CVExists = TRUE;
-
- VariantClear(&vCustomData);
- }
-
-ErrExit:
- if (pITI2)
- pITI2->Release();
-
- return S_OK;
-}
-
-
-HRESULT CImportTlb::_GetDispIDCA(
- ITypeInfo* pITI,
- int iMember,
- long* lDispSet,
- BOOL bFunc
- )
-{
- ITypeInfo2 *pITI2=0; // For getting custom value.
- HRESULT hr = S_OK;
- long lDispId = DISPID_UNKNOWN;
-
- // Get the ITypeInfo2 interface if possible
- pITI->QueryInterface(IID_ITypeInfo2, reinterpret_cast<void**>(&pITI2));
-
- if (pITI2)
- {
- VARIANT vCustomData;
- VariantInit(&vCustomData);
-
- if (bFunc)
- IfFailGo(pITI2->GetFuncCustData(iMember, GUID_DispIdOverride, &vCustomData));
- else
- IfFailGo(pITI2->GetVarCustData(iMember, GUID_DispIdOverride, &vCustomData));
-
- if ((V_VT(&vCustomData) == VT_I2) || (V_VT(&vCustomData) == VT_I4))
- {
- hr = VariantChangeType(&vCustomData, &vCustomData, 0, VT_I4);
- if (hr == S_OK)
- lDispId = vCustomData.lVal;
- }
-
- VariantClear(&vCustomData);
- }
-
-ErrExit:
- if (lDispSet != NULL)
- *lDispSet = lDispId;
-
- if (pITI2)
- pITI2->Release();
-
- return S_OK;
-}
-
-
-
-HRESULT CImportTlb::_SetDispIDCA(
- ITypeInfo* pITI,
- int iMember,
- long lDispId,
- mdToken func,
- BOOL fAlwaysAdd,
- long* lDispSet,
- BOOL bFunc
- )
-{
- WCHAR DispIDCA[] = W("{CD2BC5C9-F452-4326-B714-F9C539D4DA58}");
- ITypeInfo2 *pITI2=0; // For getting custom value.
- HRESULT hr = S_OK;
-
- // Get the ITypeInfo2 interface if possible
- pITI->QueryInterface(IID_ITypeInfo2, reinterpret_cast<void**>(&pITI2));
-
- if (pITI2)
- {
- VARIANT vCustomData;
- VariantInit(&vCustomData);
-
- if (bFunc)
- IfFailGo(pITI2->GetFuncCustData(iMember, GUID_DispIdOverride, &vCustomData));
- else
- IfFailGo(pITI2->GetVarCustData(iMember, GUID_DispIdOverride, &vCustomData));
-
- if ((V_VT(&vCustomData) == VT_I2) || (V_VT(&vCustomData) == VT_I4))
- {
- hr = VariantChangeType(&vCustomData, &vCustomData, 0, VT_I4);
- if (hr == S_OK)
- {
- lDispId = vCustomData.lVal;
- fAlwaysAdd = true;
- }
- }
- else if (V_VT(&vCustomData) != VT_EMPTY)
- {
- // Invalid Variant type on the data - spit out a warning.
- BSTR CustomValue = SysAllocString((const WCHAR*)&DispIDCA[0]);
- BSTR ObjectName;
- IfFailGo(pITI2->GetDocumentation(iMember+1, &ObjectName, NULL, NULL, NULL));
-
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_W_NON_INTEGRAL_CA_TYPE, CustomValue, ObjectName);
-
- SysFreeString(CustomValue);
- SysFreeString(ObjectName);
- }
-
- VariantClear(&vCustomData);
- }
-
- // Set the dispid CA on the property.
- if (fAlwaysAdd)
- {
- mdToken tkAttr;
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(DISPID));
- BUILD_CUSTOM_ATTRIBUTE(DISPID, lDispId);
- IfFailGo(GetAttrType(ATTR_DISPID, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(func, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
-ErrExit:
- if (lDispSet != NULL)
- {
- *lDispSet = lDispId;
- }
-
- if (pITI2)
- pITI2->Release();
-
- return S_OK;
-}
-
-
-HRESULT CImportTlb::_CheckForPropertyCustomAttributes(ITypeInfo* pITI, int index, INVOKEKIND* ikind)
-{
- HRESULT hr;
- VARIANT vCustomData;
- ITypeInfo2* pITI2 = 0;
- BOOL found = FALSE;
-
- VariantInit(&vCustomData);
-
- // Get the ITypeInfo2 interface if possible
- pITI->QueryInterface(IID_ITypeInfo2, reinterpret_cast<void**>(&pITI2));
- if (pITI2)
- {
- // First, check for PropGet
- hr = pITI2->GetFuncCustData(index, GUID_PropGetCA, &vCustomData);
- IfFailGo(hr);
- if (V_VT(&vCustomData) != VT_EMPTY)
- {
- *ikind = INVOKE_PROPERTYGET;
- found = TRUE;
- goto ErrExit;
- }
-
- // Second, check for PropPut
- VariantClear(&vCustomData);
- hr = pITI2->GetFuncCustData(index, GUID_PropPutCA, &vCustomData);
- IfFailGo(hr);
- if (V_VT(&vCustomData) != VT_EMPTY)
- {
- *ikind = INVOKE_PROPERTYPUT;
- found = TRUE;
- goto ErrExit;
- }
- }
-
-ErrExit:
- VariantClear(&vCustomData);
-
- if (pITI2)
- pITI2->Release();
-
- if (found)
- return S_OK;
-
- return S_FALSE;
-}
-
-//*****************************************************************************
-// Generate an event with an add and remove method
-//*****************************************************************************
-HRESULT CImportTlb::_GenerateEvent(
- ITypeInfo *pITI, // Containing TypeInfo.
- MemberInfo *pMember, // Info for the function
- BOOL fInheritsIEnum)
-{
- HRESULT hr = S_OK; // A result.
- mdMethodDef mdAdd; // Token of add_XXX method.
- mdMethodDef mdRemove; // Token of remove_XXX method.
- CQuickArray<WCHAR> qbName; // Buffer for decorated name.
- CQuickArray<BYTE> qbSig; // The signature.
- ULONG cb; // Size of an element.
- ULONG cbTotal = 0; // Size of the signature.
- mdTypeDef tdDelegate; // The delegate type def.
- mdEvent tkEvent; // The token for the event.
-
- // If this method is a property method, then skip the event.
- // Also look at the property semantic - it might be we couldn't import this as a property
- // and fell back to a method.
- if ((pMember->m_psFunc->invkind != INVOKE_FUNC) && (pMember->m_msSemantics != 0))
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_W_NO_PROPS_IN_EVENTS, m_szName);
- return S_CONVERSION_LOSS;
- }
-
- // Generate the delegate.
- IfFailGo(_GenerateEventDelegate(pITI, pMember, &tdDelegate, fInheritsIEnum));
-
- // Generate the sig for the add and remove methods.
- IfFailGo(qbSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE * 2 + 1));
- cbTotal = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS, qbSig.Ptr());
- cb = CorSigCompressData(1, &(qbSig[cbTotal]));
- cbTotal += cb;
- cb = CorSigCompressData(ELEMENT_TYPE_VOID, &qbSig[cbTotal]);
- cbTotal += cb;
- cb = CorSigCompressData(ELEMENT_TYPE_CLASS, &qbSig[cbTotal]);
- cbTotal += cb;
- cb = CorSigCompressToken(tdDelegate, &qbSig[cbTotal]);
- cbTotal += cb;
-
- // Generate the add method.
- IfFailGo(qbName.ReSizeNoThrow(EVENT_ADD_METH_PREFIX_LENGTH + wcslen(pMember->m_pName) + 1));
- StringCchPrintf(qbName.Ptr(), qbName.Size(), W("%s%s"), EVENT_ADD_METH_PREFIX, pMember->m_pName);
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, qbName.Ptr(), DEFAULT_INTERFACE_FUNC_FLAGS,
- qbSig.Ptr(), cbTotal, 0 /* rva*/, DEFAULT_ITF_FUNC_IMPL_FLAGS, &mdAdd));
-
- // Generate the remove method.
- IfFailGo(qbName.ReSizeNoThrow(EVENT_REM_METH_PREFIX_LENGTH + wcslen(pMember->m_pName) + 1));
- StringCchPrintf(qbName.Ptr(), qbName.Size(), W("%s%s"), EVENT_REM_METH_PREFIX, pMember->m_pName);
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, qbName.Ptr(), DEFAULT_INTERFACE_FUNC_FLAGS,
- qbSig.Ptr(), cbTotal, 0 /* rva*/, DEFAULT_ITF_FUNC_IMPL_FLAGS, &mdRemove));
-
- // Define the event itself.
- IfFailGo(m_pEmit->DefineEvent(m_tdTypeDef, pMember->m_pName, 0, tdDelegate,
- mdAdd, mdRemove, mdTokenNil, NULL, &tkEvent));
-
-ErrExit:
-
- return (hr);
-} // HRESULT CImportTlb::_GenerateEvent()
-
-//*****************************************************************************
-// Generate an add and remove method
-//*****************************************************************************
-HRESULT CImportTlb::_GenerateEventDelegate(
- ITypeInfo *pITI, // Containing TypeInfo.
- MemberInfo *pMember, // Info for the source interface func
- mdTypeDef *ptd, // The output typedef.
- BOOL fInheritsIEnum)
-{
- HRESULT hr = S_OK; // A result.
- BSTR bstrSrcItfName = NULL; // The name of the source interface.
- CQuickArray<WCHAR> qbEventHandlerName; // The name of the event handler.
- BSTR szOldName = NULL; // The old value m_tdTypeDef.
- mdTypeDef tdOldTypeDef = NULL; // The old value m_szName.
- CQuickArray<BYTE> qbSig; // The signature.
- ULONG cb; // Size of an element.
- ULONG cbTotal = 0; // Total size of signature.
- mdMethodDef mdFunc; // The defined function.
- mdTypeRef trMulticastDelegate; // The type ref for System.MulticastDelegate.
- mdToken tkAttr; // Custom attribute type.
-
- // Store the old values of the ITypeInfo name and of the current type def.
- szOldName = m_szName;
- tdOldTypeDef = m_tdTypeDef;
- m_szName = NULL;
-
- // Retrieve the full name of the source interface.
- IfFailGo(GetManagedNameForTypeInfo(pITI, m_wzNamespace, NULL, &bstrSrcItfName));
-
- // Generate a unique name for the event handler which will be of the form:
- // <SrcItfName>_<MethodName>_EventHandler<PotentialSuffix>
- IfFailGo(qbEventHandlerName.ReSizeNoThrow(wcslen(bstrSrcItfName) + wcslen(pMember->m_pName) + EVENT_HANDLER_SUFFIX_LENGTH + 6));
- StringCchPrintf(qbEventHandlerName.Ptr(), qbEventHandlerName.Size(), W("%s_%s%s"), bstrSrcItfName, pMember->m_pName, EVENT_HANDLER_SUFFIX);
- IfFailGo(GenerateUniqueTypeName(qbEventHandlerName));
-
- // Set the information on the current type.
- IfNullGo(m_szName = SysAllocString(qbEventHandlerName.Ptr()));
-
- // Retrieve the parent type ref.
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_MULTICASTDEL, &trMulticastDelegate));
-
- // Create the typedef for the event interface.
- IfFailGo(m_pEmit->DefineTypeDef(m_szName, tdPublic | tdSealed, trMulticastDelegate, NULL, &m_tdTypeDef));
-
- // Hide the interface from Object Browsers (EventHandler)
- _SetHiddenCA(m_tdTypeDef);
-
- // Make the interface ComVisible(false).
- {
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(BYTE));
- BUILD_CUSTOM_ATTRIBUTE(BYTE, FALSE);
- IfFailGo(GetAttrType(ATTR_COMVISIBLE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
- // Generate the sig for the constructor.
- IfFailGo(qbSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE * 2 + 1));
- cbTotal = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS, qbSig.Ptr());
- cb = CorSigCompressData(2, &(qbSig[cbTotal]));
- cbTotal += cb;
- cb = CorSigCompressData(ELEMENT_TYPE_VOID, &qbSig[cbTotal]);
- cbTotal += cb;
- cb = CorSigCompressData(ELEMENT_TYPE_OBJECT, &qbSig[cbTotal]);
- cbTotal += cb;
- cb = CorSigCompressData(ELEMENT_TYPE_U, &qbSig[cbTotal]);
- cbTotal += cb;
-
- // Generate the constructor.
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, OBJECT_INITIALIZER_NAME, OBJECT_INITIALIZER_FLAGS,
- qbSig.Ptr(), cbTotal, 0 /* rva*/, miRuntime, &mdFunc));
-
- // Generate the invoke method.
- BOOL bAllowIEnum = !fInheritsIEnum;
- IfFailGo(_ConvFunction(pITI, pMember, FALSE, FALSE, TRUE, &bAllowIEnum));
-
- // Set the output typedef.
- *ptd = m_tdTypeDef;
-
-ErrExit:
- if (m_szName)
- ::SysFreeString(m_szName);
- if (m_szMember)
- ::SysFreeString(m_szMember); m_szMember=0;
- if (bstrSrcItfName)
- ::SysFreeString(bstrSrcItfName);
-
- // Restore the initial values for the ITypeInfo name and the type def.
- m_szName = szOldName;
- m_tdTypeDef = tdOldTypeDef;
-
- return (hr);
-} // HRESULT CImportTlb::_GenerateEventDelegate()
-
-//*****************************************************************************
-//*****************************************************************************
-struct MDTOKENHASH : HASHLINK
-{
- mdToken tkKey;
- mdToken tkData;
-}; // struct MDTOKENHASH : HASHLINK
-
-class CTokenHash : public CChainedHash<MDTOKENHASH>
-{
-public:
- virtual bool InUse(MDTOKENHASH *pItem)
- { return (pItem->tkKey != NULL); }
-
- virtual void SetFree(MDTOKENHASH *pItem)
- {
- pItem->tkKey = NULL;
- pItem->tkKey = NULL;
- }
-
- virtual ULONG Hash(const void *pData)
- {
- // Do case-insensitive hash
- return (ULONG)(ULONG_PTR)pData;
- }
-
- virtual int Cmp(const void *pData, void *pItem){
- return (mdToken)(ULONG_PTR)pData != reinterpret_cast<MDTOKENHASH*>(pItem)->tkKey;
- }
-}; // CTokenHash : public CChainedHash<MDTOKENHASH>
-
-//*****************************************************************************
-// Copy methods and events from a source interface to a class that sources the
-// given interface.
-//*****************************************************************************
-HRESULT CImportTlb::_AddSrcItfMembersToClass( // S_OK or error.
- mdTypeRef trSrcItf) // Typeref of the source interface.
-{
- HRESULT hr=S_OK; // A result.
- ULONG i; // Generic counter.
- HCORENUM MemberEnum = NULL; // The enum of members.
- ULONG cMembers = 0; // Temp count of members.
- mdTypeDef tdSrcItf; // A type def to the interface.
- mdEvent tkItfEvent; // The token of the interface event.
- mdEvent tkClassEvent; // The token of the class event.
- mdToken tkEventType; // The event type.
- mdMethodDef mdItfMethod; // The method def of the interface method.
- mdMethodDef mdAddMethod; // The add method.
- mdMethodDef mdRemoveMethod; // The remove method.
- mdMethodDef mdFireMethod; // The fire method.
- mdMethodDef mdClassMethod; // The method def of the class method.
- CQuickArray<mdMethodDef> qbOtherMethods; // The other methods for the property.
- ULONG cchOtherMethods; // The cound of other methods.
- CQuickArray<WCHAR> qbMemberName; // Name of the member.
- CQuickArray<WCHAR> qbEventItfFullName; // Full name of the event interface.
- CQuickArray<WCHAR> qbEventItfName; // Name of the event interface.
- ULONG cchName; // Length of a name, in wide chars.
- ULONG ItfMemberAttr; // The attributes of the interface member.
- ULONG ItfMemberImplFlags; // The impl flags of the interface member.
- PCCOR_SIGNATURE ItfMemberSig; // The signature of the interface member.
- ULONG ItfMemberSigSize; // The size of the member signature.
- mdMemberRef mrItfMember; // A member ref to the interface member def.
- BSTR bstrSrcItfName = NULL; // The name of the CoClass.
- mdAssemblyRef ar; // The assembly ref.
- CTokenHash ItfMDToClassMDMap; // The interface MD to class MD map.
- MDTOKENHASH * pItem; // An item in the token hashtable.
-
- // Retrieve the name of the event interface.
- do {
- IfFailGo(m_pImport->GetTypeRefProps(
- trSrcItf,
- &ar,
- qbEventItfFullName.Ptr(),
- (ULONG)qbEventItfFullName.MaxSize(),
- &cchName));
- if (hr == CLDB_S_TRUNCATION)
- {
- IfFailGo(qbEventItfFullName.ReSizeNoThrow(cchName));
- continue;
- }
- break;
- } while (1);
- IfFailGo(qbEventItfName.ReSizeNoThrow(cchName));
- ns::SplitPath(qbEventItfFullName.Ptr(), NULL, 0, qbEventItfName.Ptr(), (int)qbEventItfName.Size());
-
- // Resolve the typeref to a typedef.
- IfFailGo(m_pImport->FindTypeDefByName(qbEventItfFullName.Ptr(), mdTokenNil, &tdSrcItf));
-
- // Define methods and method impl's for all the methods in the interface.
- while ((hr = m_pImport->EnumMethods(&MemberEnum, tdSrcItf, &mdItfMethod, 1, &cMembers)) == S_OK)
- {
- // Retrieve the method properties.
- do {
- IfFailGo(m_pImport->GetMethodProps(
- mdItfMethod,
- NULL,
- qbMemberName.Ptr(),
- (ULONG)qbMemberName.MaxSize(),
- &cchName,
- &ItfMemberAttr,
- &ItfMemberSig,
- &ItfMemberSigSize,
- NULL,
- &ItfMemberImplFlags));
- if (hr == CLDB_S_TRUNCATION)
- {
- IfFailGo(qbMemberName.ReSizeNoThrow(cchName));
- continue;
- }
- break;
- } while (1);
-
- // Define a member ref on the class to the interface member def.
- IfFailGo(m_pEmit->DefineMemberRef(trSrcItf, qbMemberName.Ptr(), ItfMemberSig, ItfMemberSigSize, &mrItfMember));
-
- // Generate a unique name for the class member.
- IfFailGo(GenerateUniqueMemberName(qbMemberName, NULL, 0, qbEventItfName.Ptr(), mdtMethodDef));
-
- // Define a member on the class.
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, qbMemberName.Ptr(), ItfMemberAttr & ~mdAbstract,
- ItfMemberSig, ItfMemberSigSize, 0/*rva*/, ItfMemberImplFlags, &mdClassMethod));
-
- // Define a method impl.
- IfFailGo(m_pEmit->DefineMethodImpl(m_tdTypeDef, mdClassMethod, mrItfMember));
-
- // Add the interface member to the map.
- if ((pItem = ItfMDToClassMDMap.Add((const void *)(ULONG_PTR)mdItfMethod)) == NULL)
- IfFailGo(E_FAIL);
- PREFIX_ASSUME(pItem != NULL);
- pItem->tkKey = mdItfMethod;
- pItem->tkData = mdClassMethod;
- }
- IfFailGo(hr);
-
- m_pImport->CloseEnum(MemberEnum);
- MemberEnum = NULL;
-
- // Define all the events in the interface on the class.
- while ((hr = m_pImport->EnumEvents(&MemberEnum, tdSrcItf, &tkItfEvent, 1, &cMembers)) == S_OK)
- {
- // Retrieve the properties of the property.
- do {
- IfFailGo(m_pImport->GetEventProps(
- tkItfEvent,
- NULL,
- qbMemberName.Ptr(),
- (ULONG)qbMemberName.MaxSize(),
- &cchName,
- &ItfMemberAttr,
- &tkEventType,
- &mdAddMethod,
- &mdRemoveMethod,
- &mdFireMethod,
- qbOtherMethods.Ptr(),
- (ULONG)qbOtherMethods.MaxSize(),
- &cchOtherMethods));
- if (hr == CLDB_S_TRUNCATION)
- {
- IfFailGo(qbMemberName.ReSizeNoThrow(cchName));
- IfFailGo(qbOtherMethods.ReSizeNoThrow(cchOtherMethods));
- continue;
- }
- break;
- } while (1);
-
- // NULL terminate the array of other methods.
- IfFailGo(qbOtherMethods.ReSizeNoThrow(cchOtherMethods + 1));
- qbOtherMethods[cchOtherMethods] = NULL;
-
- // Replace all the interface method def's with the equivalent class method def's.
- if (!IsNilToken(mdAddMethod))
- {
- pItem = ItfMDToClassMDMap.Find((const void *)(ULONG_PTR)mdAddMethod);
- _ASSERTE(pItem);
- mdAddMethod = pItem->tkData;
- }
- if (!IsNilToken(mdRemoveMethod))
- {
- pItem = ItfMDToClassMDMap.Find((const void *)(ULONG_PTR)mdRemoveMethod);
- _ASSERTE(pItem);
- mdRemoveMethod = pItem->tkData;
- }
- _ASSERTE(IsNilToken(mdFireMethod));
- _ASSERTE(cchOtherMethods == 0);
-
- // Generate a unique name for the event.
- IfFailGo(GenerateUniqueMemberName(qbMemberName, NULL, 0, qbEventItfName.Ptr(), mdtEvent));
-
- // Define property on the class.
- IfFailGo(m_pEmit->DefineEvent(m_tdTypeDef, qbMemberName.Ptr(), ItfMemberAttr,
- tkEventType, mdAddMethod, mdRemoveMethod, mdFireMethod, qbOtherMethods.Ptr(), &tkClassEvent));
- }
- IfFailGo(hr);
-
- m_pImport->CloseEnum(MemberEnum);
- MemberEnum = NULL;
-
-ErrExit:
- if (MemberEnum)
- m_pImport->CloseEnum(MemberEnum);
- if (bstrSrcItfName)
- ::SysFreeString(bstrSrcItfName);
-
- return hr;
-
-#undef ITF_MEMBER_SIG
-#undef ITF_MEMBER_SIG_SIZE
-} // HRESULT CImportTlb::_AddSrcItfMembersToClass()
-
-//*****************************************************************************
-// Compare the two signatures ignoring the return type. If the signatures
-// match then TRUE will be returned, FALSE will be returned otherwise.
-// This method assumes the two signatures are in the same scope.
-//*****************************************************************************
-HRESULT CImportTlb::CompareSigsIgnoringRetType(
- PCCOR_SIGNATURE pbSig1, // The 1st method signature.
- ULONG cbSig1, // Size of the 1st method signature.
- PCCOR_SIGNATURE pbSig2, // The 2nd method signature.
- ULONG cbSig2) // Size of the 2nd method signature.
-{
- HRESULT hr = S_OK;
- PCCOR_SIGNATURE pbSig1Start;
- PCCOR_SIGNATURE pbSig2Start;
- ULONG Sig1ParamCount;
- ULONG Sig2ParamCount;
- ULONG cbSig1RetType;
- ULONG cbSig2RetType;
-
- // Save the start of the signatures.
- pbSig1Start = pbSig1;
- pbSig2Start = pbSig2;
-
- // Skip the calling conventions.
- CorSigUncompressData(pbSig1);
- CorSigUncompressData(pbSig2);
-
- // Compare the param count.
- Sig1ParamCount = CorSigUncompressData(pbSig1);
- Sig2ParamCount = CorSigUncompressData(pbSig2);
- if (Sig1ParamCount != Sig2ParamCount)
- return S_FALSE;
-
- // Skip the return type.
- cbSig1RetType = cbSig1 - (ULONG)(pbSig1 - pbSig1Start);
- IfFailGo(_CountBytesOfOneArg(pbSig1, &cbSig1RetType));
- pbSig1 += cbSig1RetType;
- cbSig2RetType = cbSig2 - (ULONG)(pbSig2 - pbSig2Start);
- IfFailGo(_CountBytesOfOneArg(pbSig2, &cbSig2RetType));
- pbSig2 += cbSig2RetType;
-
- // Update the remaining sig sizes.
- cbSig1 -= (ULONG) (pbSig1 - pbSig1Start);
- cbSig2 -= (ULONG) (pbSig2 - pbSig2Start);
-
- // If the remaining sig sizes are different then the sigs don't match.
- if (cbSig1 != cbSig2)
- return S_FALSE;
-
- // Compare the rest of the sigs using memcmp.
- if (memcmp(pbSig1, pbSig2, cbSig1) != 0)
- return S_FALSE;
-
- // The parameters match.
- return S_OK;
-
-ErrExit:
- // An error occurred.
- return hr;
-} // HRESULT CImportTlb::CompareSigsIgnoringRetType()
-
-//*****************************************************************************
-// Look up a method in the emit scope. This lookup method does not take the
-// return type into account when comparing using a sig. So 2 methods with
-// the same name, same parameters and a different return type will be
-// considered the same.
-//*****************************************************************************
-HRESULT CImportTlb::FindMethod( // S_OK or CLDB_E_RECORD_NOTFOUND, or error.
- mdTypeDef td, // The method typedef.
- LPCWSTR szName, // The method name.
- PCCOR_SIGNATURE pbReqSig, // The method signature.
- ULONG cbReqSig, // Size of the method signature.
- mdMethodDef *pmb) // Put the method here.
-{
- HRESULT hr = S_OK; // A result.
- PCCOR_SIGNATURE pbFoundSig = NULL;
- ULONG cbFoundSig = 0;
- ULONG MethodAttr;
- ULONG MethodImplFlags;
- mdMethodDef md;
- CQuickArray<WCHAR> qbMethodName;
- HCORENUM MethodEnum = NULL;
- ULONG cMethods = 0;
- ULONG cchName;
- BOOL bMethodFound = FALSE;
-
- // Go through all the methods on the class looking for one with the
- // same name and same parameters.
- while ((hr = m_pImport->EnumMethods(&MethodEnum, td, &md, 1, &cMethods)) == S_OK)
- {
- // Retrieve the method properties.
- do {
- IfFailGo(m_pImport->GetMethodProps(
- md,
- NULL,
- qbMethodName.Ptr(),
- (ULONG)qbMethodName.MaxSize(),
- &cchName,
- &MethodAttr,
- &pbFoundSig,
- &cbFoundSig,
- NULL,
- &MethodImplFlags));
- if (hr == CLDB_S_TRUNCATION)
- {
- IfFailGo(qbMethodName.ReSizeNoThrow(cchName));
- continue;
- }
- break;
- } while (1);
-
- // Compare the name of the method.
- if (wcscmp(szName, qbMethodName.Ptr()) != 0)
- continue;
-
- // If the signature of the requested method is specified, then compare
- // the signature against the signature of the found method ignoring
- // the return type.
- if (pbReqSig)
- {
- IfFailGo(hr = CompareSigsIgnoringRetType(pbReqSig, cbReqSig, pbFoundSig, cbFoundSig));
- if (hr == S_FALSE)
- continue;
- }
-
- // We have found the member.
- bMethodFound = TRUE;
- break;
- }
- IfFailGo(hr);
-
-ErrExit:
- if (MethodEnum)
- m_pImport->CloseEnum(MethodEnum);
-
- return bMethodFound ? S_OK : CLDB_E_RECORD_NOTFOUND;
-}
-
-//*****************************************************************************
-// Look up a property in the emit scope.
-//*****************************************************************************
-HRESULT CImportTlb::FindProperty( // S_OK or CLDB_E_RECORD_NOTFOUND, or error.
- mdTypeDef td, // The property typedef.
- LPCWSTR szName, // The property name.
- PCCOR_SIGNATURE pbSig, // The property signature.
- ULONG cbSig, // Size of the property signature.
- mdProperty *ppr) // Put the property here.
-{
- HRESULT hr; // A result.
- RegMeta *pRegMeta = (RegMeta*)(m_pEmit);
- LPUTF8 szNameAnsi;
-
- if (szName == NULL)
- {
- return CLDB_E_RECORD_NOTFOUND;
- }
- UTF8STR(szName, szNameAnsi);
-
- hr = ImportHelper::FindProperty(
- &(pRegMeta->GetMiniStgdb()->m_MiniMd),
- m_tdTypeDef,
- szNameAnsi,
- pbSig,
- cbSig,
- ppr);
- return hr;
-} // HRESULT CImportTlb::FindProperty()
-
-//*****************************************************************************
-// Look up a event in the emit scope.
-//*****************************************************************************
-HRESULT CImportTlb::FindEvent( // S_OK or CLDB_E_RECORD_NOTFOUND, or error.
- mdTypeDef td, // The event typedef.
- LPCWSTR szName, // The event name.
- mdEvent *pev) // Put the event here.
-{
- HRESULT hr; // A result.
- RegMeta *pRegMeta = (RegMeta*)(m_pEmit);
- LPUTF8 szNameAnsi;
-
- if (szName == NULL)
- {
- return CLDB_E_RECORD_NOTFOUND;
- }
- UTF8STR(szName, szNameAnsi);
-
- hr = ImportHelper::FindEvent(
- &(pRegMeta->GetMiniStgdb()->m_MiniMd),
- m_tdTypeDef,
- szNameAnsi,
- pev);
- return hr;
-} // HRESULT CImportTlb::FindEvent()
-
-//*****************************************************************************
-// Checks to see if the specified TYPEDESC is an alias.
-//*****************************************************************************
-HRESULT CImportTlb::_IsAlias(
- ITypeInfo *pITI, // The ITypeInfo containing the TYPEDESC.
- TYPEDESC *pTypeDesc) // The token of the param, field, etc.
-{
- HRESULT hr = S_FALSE; // A result.
- ITypeInfo *pTypeITI=0; // The ITypeInfo of the type.
- ITypeLib *pTypeTLB=0; // The TLB that contains the type.
- TYPEATTR *psTypeAttr=0; // TYPEATTR of the type.
-
- // Drill down to the actual type that is pointed to.
- while (pTypeDesc->vt == VT_PTR)
- pTypeDesc = pTypeDesc->lptdesc;
-
- // If the parameter is an alias then we need to add a custom attribute to the
- // parameter that describes the alias.
- if (pTypeDesc->vt == VT_USERDEFINED)
- {
- IfFailGo(pITI->GetRefTypeInfo(pTypeDesc->hreftype, &pTypeITI));
- IfFailGo(pTypeITI->GetTypeAttr(&psTypeAttr));
- if (psTypeAttr->typekind == TKIND_ALIAS)
- {
- hr = S_OK;
- }
- }
-
-ErrExit:
- if (psTypeAttr)
- pTypeITI->ReleaseTypeAttr(psTypeAttr);
- if (pTypeITI)
- pTypeITI->Release();
- return hr;
-} // HRESULT CImportTlb::_IsAlias()
-
-//*****************************************************************************
-// Add alias information if the TYPEDESC represents an alias.
-//*****************************************************************************
-HRESULT CImportTlb::_HandleAliasInfo(
- ITypeInfo *pITI, // The ITypeInfo containing the TYPEDESC.
- TYPEDESC *pTypeDesc, // The TYPEDESC.
- mdToken tk) // The token of the param, field, etc.
-{
- HRESULT hr = S_OK; // A result.
- ITypeInfo *pTypeITI=0; // The ITypeInfo of the type.
- ITypeLib *pTypeTLB=0; // The TLB that contains the type.
- TYPEATTR *psTypeAttr=0; // TYPEATTR of the type.
- BSTR bstrAliasTypeName=0; // The name of the alias type.
- BSTR bstrAliasTypeLibName=0; // The name of the typelib that contains the alias type.
-
- // Drill down to the actual type that is pointed to.
- while (pTypeDesc->vt == VT_PTR)
- pTypeDesc = pTypeDesc->lptdesc;
-
- // If the parameter is an alias then we need to add a custom attribute to the
- // parameter that describes the alias.
- if (pTypeDesc->vt == VT_USERDEFINED)
- {
- IfFailGo(pITI->GetRefTypeInfo(pTypeDesc->hreftype, &pTypeITI));
- IfFailGo(pTypeITI->GetTypeAttr(&psTypeAttr));
- if (psTypeAttr->typekind == TKIND_ALIAS)
- {
- // Retrieve the name of the alias type.
- IfFailGo(pTypeITI->GetContainingTypeLib(&pTypeTLB, NULL));
- IfFailGo(GetNamespaceOfRefTlb(pTypeTLB, &bstrAliasTypeLibName, NULL));
- IfFailGo(GetManagedNameForTypeInfo(pTypeITI, bstrAliasTypeLibName, NULL, &bstrAliasTypeName));
-
- // Add the ComAliasName CA to the parameter.
- _AddStringCa(ATTR_COMALIASNAME, tk, bstrAliasTypeName);
- }
- }
-
-ErrExit:
- if (psTypeAttr)
- pTypeITI->ReleaseTypeAttr(psTypeAttr);
- if (pTypeITI)
- pTypeITI->Release();
- if (pTypeTLB)
- pTypeTLB->Release();
- if (bstrAliasTypeLibName)
- ::SysFreeString(bstrAliasTypeLibName);
- if (bstrAliasTypeName)
- ::SysFreeString(bstrAliasTypeName);
- return hr;
-} // HRESULT CImportTlb::_HandleAliasInfo()
-
-//*****************************************************************************
-// Convert one of a function's parameters.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvParam(
- ITypeInfo *pITI, // Containing TypeInfo.
- mdMethodDef mdFunc, // Owning member.
- int iSequence, // Parameter sequence.
- const ELEMDESC *pdesc, // Param flags, default value.
- ParamOpts paramOpts, // Is param normal, optional, or vararg?
- LPCWSTR szName, // Name of the parameter.
- BYTE *pbNative, // Native type info, if any.
- ULONG cbNative) // Size of native type info.
-{
- HRESULT hr; // A result.
- mdParamDef pdParam; // Token of the parameter.
- DWORD dwFlags; // Param flags.
- USHORT Sequence = static_cast<USHORT>(iSequence);
- BYTE cvType = ELEMENT_TYPE_VOID; // ELEMENT_TYPE_* flag for constant value
- void *pcvValue=0; // constant value blob
- __int64 d; // For cases where value is a date.
- int bDecimal=0; // If true, constant is a decimal.
- mdToken tkAttr; // For custom attribute token.
- DECIMAL decVal; // Decimal constant value.
-
- // Compute the flags. Only make sense on non-return params.
- dwFlags = 0;
- if (iSequence > 0)
- {
- if (pdesc->paramdesc.wParamFlags & PARAMFLAG_FIN)
- dwFlags |= pdIn;
- if (pdesc->paramdesc.wParamFlags & PARAMFLAG_FOUT)
- dwFlags |= pdOut;
- if (pdesc->paramdesc.wParamFlags & PARAMFLAG_FOPT)
- dwFlags |= pdOptional;
- if (paramOpts == ParamOptional)
- dwFlags |= pdOptional;
- }
-
- // Get any default values. Return type, param with iSequence==0, has no default.
- if (pdesc->paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT && iSequence != 0)
- {
- switch (pdesc->paramdesc.pparamdescex->varDefaultValue.vt)
- {
- case VT_CY:
- case VT_DECIMAL:
- case VT_DATE:
- case VT_UNKNOWN:
- case VT_DISPATCH:
- break;
- default:
- // This workaround is because a typelib can store anything that can convert to VT_I4 with a value of 0
- // for the default value of an interface pointer. But, a VT_I2(0) confuses the consumers
- // of the managed wrapper dll. So, if it is an interface on the unmanaged side, make
- // the constant value an ET_CLASS.
- if (cbNative > 0 && (*pbNative == NATIVE_TYPE_INTF ||
- *pbNative == NATIVE_TYPE_IUNKNOWN ||
- *pbNative == NATIVE_TYPE_IDISPATCH))
- {
- cvType = ELEMENT_TYPE_CLASS;
- pcvValue = 0;
- }
- else
- IfFailGo( _UnpackVariantToConstantBlob(&pdesc->paramdesc.pparamdescex->varDefaultValue, &cvType, &pcvValue, &d) );
- }
- }
-
- // Create the param definition.
- IfFailGo(m_pEmit->DefineParam(mdFunc, iSequence, szName, dwFlags, cvType, pcvValue, -1, &pdParam));
-
- // Add the native type if it there is any.
- if (cbNative > 0)
- IfFailGo(m_pEmit->SetFieldMarshal(pdParam, (PCCOR_SIGNATURE) pbNative, cbNative));
-
- if (pdesc->paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT && iSequence != 0)
- {
- switch (pdesc->paramdesc.pparamdescex->varDefaultValue.vt)
- {
- case VT_CY:
- IfFailGo(VarDecFromCy(pdesc->paramdesc.pparamdescex->varDefaultValue.cyVal, &decVal));
- IfFailGo(DecimalCanonicalize(&decVal));
- goto StoreDecimal;
- case VT_DECIMAL:
- // If there is a decimal constant value, set it as a custom attribute.
- {
- decVal = pdesc->paramdesc.pparamdescex->varDefaultValue.decVal;
- StoreDecimal:
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(BYTE)+sizeof(BYTE)+sizeof(UINT)+sizeof(UINT)+sizeof(UINT));
- BUILD_CUSTOM_ATTRIBUTE(BYTE, decVal.scale);
- BUILD_CUSTOM_ATTRIBUTE(BYTE, decVal.sign);
- BUILD_CUSTOM_ATTRIBUTE(UINT, decVal.Hi32);
- BUILD_CUSTOM_ATTRIBUTE(UINT, decVal.Mid32);
- BUILD_CUSTOM_ATTRIBUTE(UINT, decVal.Lo32);
- IfFailGo(GetAttrType(ATTR_DECIMALVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(pdParam, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- case VT_DATE:
- {
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(__int64));
- __int64 date = _DoubleDateToTicks(pdesc->paramdesc.pparamdescex->varDefaultValue.date);
- BUILD_CUSTOM_ATTRIBUTE(__int64, date);
- IfFailGo(GetAttrType(ATTR_DATETIMEVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(pdParam, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- case VT_UNKNOWN:
- {
- DECLARE_CUSTOM_ATTRIBUTE(0);
- IfFailGo(GetAttrType(ATTR_IUNKNOWNVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(pdParam, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- case VT_DISPATCH:
- {
- DECLARE_CUSTOM_ATTRIBUTE(0);
- IfFailGo(GetAttrType(ATTR_IDISPATCHVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(pdParam, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- default:
- break;
- }
- }
-
- // Add the alias information if the param is an alias.
- IfFailGo(_HandleAliasInfo(pITI, (TYPEDESC*)&pdesc->tdesc, pdParam));
-
- // If a vararg param, set the custom attribute.
- if (paramOpts == ParamVarArg)
- {
- mdToken tkAttribute;
- DECLARE_CUSTOM_ATTRIBUTE(0);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(GetAttrType(ATTR_PARAMARRAY, &tkAttribute));
- IfFailGo(m_pEmit->DefineCustomAttribute(pdParam, tkAttribute, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
-ErrExit:
- return hr;
-} // HRESULT CImportTlb::_ConvParam()
-
-//*****************************************************************************
-// Convert a constant into a field with a default value.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvConstant(
- ITypeInfo *pITI, // Containing TypeInfo.
- VARDESC *psVar, // VARDESC for the property.
- BOOL bEnumMember) // If true, type is containing class.
-{
- HRESULT hr; // A result.
- mdFieldDef mdField; // Token of the new field.
- DWORD dwFlags; // Member flags.
- CQuickBytes qbComSig; // The COM+ Signature of the field.
- ULONG cb, cbTotal;
- BYTE cvType = ELEMENT_TYPE_VOID; // E_T_Type for constant value
- void *pcvValue; // Pointer to constant value data.
- mdToken tkAttr; // Type for custom attribute.
- __int64 d; // For cases where value is a date.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
- BYTE *pbSig; // Pointer to signature bytes.
- CQuickArray<BYTE> qbNativeBuf; // Native type buffer.
- ULONG cbNative = 0; // Size of native type.
- int bDecimal = 0; // If the value is a decimal.
- DECIMAL decVal; // Decimal constant value.
-
- // Information about the member.
- IfFailGo(pITI->GetDocumentation(psVar->memid, &m_szMember, 0,0,0));
-
- // resize to make room for calling convention and count of argument
- IfFailGo(qbComSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE * 4));
- pbSig = (BYTE *)qbComSig.Ptr();
-
- // Compute properties.
- dwFlags = DEFAULT_CONST_FIELD_FLAGS;
-
- // Build the signature.
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_FIELD, pbSig);
- if (bEnumMember)
- {
- cb = CorSigCompressData(ELEMENT_TYPE_VALUETYPE, &pbSig[cbTotal]);
- cbTotal += cb;
- cb = CorSigCompressToken(m_tdTypeDef, reinterpret_cast<ULONG*>(&pbSig[cbTotal]));
- cbTotal += cb;
- }
- else
- {
- // Use the conversion function to get the signature.
- ULONG cbSave = cbTotal;
- IfFailGo(_ConvSignature(pITI, &psVar->elemdescVar.tdesc, SIG_FLAGS_NONE, qbComSig, cbTotal, &cbTotal, qbNativeBuf, 0, &cbNative, FALSE));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
-
- if (psVar->elemdescVar.tdesc.vt == VT_DATE)
- {
- // But for dates, convert it as float -- DateTime is reported as R4 in a typelib!
- cbTotal = cbSave;
- cb = CorSigCompressData(ELEMENT_TYPE_R4, &pbSig[cbTotal]);
- cbTotal += cb;
- }
- }
-
- // Get the default value.
- switch (psVar->lpvarValue->vt)
- {
- case VT_CY:
- case VT_DECIMAL:
- case VT_DATE:
- case VT_UNKNOWN:
- case VT_DISPATCH:
- break;
- default:
- // This workaround is because a typelib can store anything that can convert to VT_I4 with a value of 0
- // for the default value of an interface pointer. But, a VT_I2(0) confuses the consumers
- // of the managed wrapper dll. So, if it is an interface on the unmanaged side, make
- // the constant value an ET_CLASS.
- BYTE *pbNative = NULL;
- pbNative = qbNativeBuf.Ptr();
- if (cbNative > 0 && (*pbNative == NATIVE_TYPE_INTF ||
- *pbNative == NATIVE_TYPE_IUNKNOWN ||
- *pbNative == NATIVE_TYPE_IDISPATCH))
- {
- cvType = ELEMENT_TYPE_CLASS;
- pcvValue = 0;
- }
- else
- IfFailGo( _UnpackVariantToConstantBlob(psVar->lpvarValue, &cvType, &pcvValue, &d) );
- }
-
- // Create the field definition.
- IfFailGo(m_pEmit->DefineField(m_tdTypeDef, m_szMember, dwFlags, (PCCOR_SIGNATURE)pbSig, cbTotal,
- cvType, pcvValue, -1, &mdField));
-
- switch (psVar->lpvarValue->vt)
- {
- case VT_CY:
- IfFailGo(VarDecFromCy(psVar->lpvarValue->cyVal, &decVal));
- IfFailGo(DecimalCanonicalize(&decVal));
- goto StoreDecimal;
- case VT_DECIMAL:
- // If there is a decimal constant value, set it as a custom attribute.
- {
- decVal = psVar->lpvarValue->decVal;
- StoreDecimal:
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(BYTE)+sizeof(BYTE)+sizeof(UINT)+sizeof(UINT)+sizeof(UINT));
- BUILD_CUSTOM_ATTRIBUTE(BYTE, decVal.scale);
- BUILD_CUSTOM_ATTRIBUTE(BYTE, decVal.sign);
- BUILD_CUSTOM_ATTRIBUTE(UINT, decVal.Hi32);
- BUILD_CUSTOM_ATTRIBUTE(UINT, decVal.Mid32);
- BUILD_CUSTOM_ATTRIBUTE(UINT, decVal.Lo32);
- IfFailGo(GetAttrType(ATTR_DECIMALVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(mdField, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- case VT_DATE:
- {
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(__int64));
- __int64 date = _DoubleDateToTicks(psVar->lpvarValue->date);
- BUILD_CUSTOM_ATTRIBUTE(__int64, date);
- IfFailGo(GetAttrType(ATTR_DATETIMEVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(mdField, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- case VT_UNKNOWN:
- {
- DECLARE_CUSTOM_ATTRIBUTE(0);
- IfFailGo(GetAttrType(ATTR_IUNKNOWNVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(mdField, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- case VT_DISPATCH:
- {
- DECLARE_CUSTOM_ATTRIBUTE(0);
- IfFailGo(GetAttrType(ATTR_IDISPATCHVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(mdField, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- default:
- break;
- }
-
- // Save the field flags.
- if (psVar->wVarFlags)
- {
- IfFailGo(GetAttrType(ATTR_TYPELIBVAR, &tkAttr));
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(WORD));
- BUILD_CUSTOM_ATTRIBUTE(WORD, psVar->wVarFlags);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(mdField, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
-
- // Set up the native description, if any.
- if (cbNative > 0)
- IfFailGo(m_pEmit->SetFieldMarshal(mdField, (PCCOR_SIGNATURE) qbNativeBuf.Ptr(), cbNative));
-
- // Add the alias information if the type is an alias.
- IfFailGo(_HandleAliasInfo(pITI, &psVar->elemdescVar.tdesc, mdField));
-
- if (bConversionLoss)
- {
- hr = S_CONVERSION_LOSS;
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_I_UNCONVERTABLE_FIELD, m_szName, m_szMember);
- }
-
-ErrExit:
- if (m_szMember)
- ::SysFreeString(m_szMember), m_szMember=0;
- return (hr);
-} // HRESULT CImportTlb::_ConvConstant()
-
-//*****************************************************************************
-// Convert a (record) field into a member.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvField(
- ITypeInfo *pITI, // Containing TypeInfo.
- VARDESC *psVar, // VARDESC for the property.
- mdFieldDef *pmdField, // Put field token here.
- BOOL bUnion) // Convert as a union?
-{
- HRESULT hr; // A result.
- DWORD dwFlags; // Member flags.
- CQuickBytes qbComSig; // The COM+ Signature of the field.
- ULONG cb, cbTotal; // Size of a sig element, signature.
- BYTE *pbSig; // Pointer to signature bytes.
- CQuickArray<BYTE> qbNativeBuf; // Native type buffer.
- ULONG cbNative; // Size of native type.
- mdToken tkAttr; // CustomAttribute type.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
-
- // Information about the member.
- IfFailGo(pITI->GetDocumentation(psVar->memid, &m_szMember, 0,0,0));
-
- // Compute properties.
- dwFlags = DEFAULT_RECORD_FIELD_FLAGS;
-
- // resize to make room for calling convention and count of argument
- IfFailGo(qbComSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE * 2));
- pbSig = (BYTE *)qbComSig.Ptr();
-
- // Build the signature.
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_FIELD, pbSig);
- IfFailGo(_ConvSignature(pITI, &psVar->elemdescVar.tdesc, SIG_FIELD, qbComSig, cbTotal, &cbTotal, qbNativeBuf, 0, &cbNative, FALSE));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
-
- // Create the field definition.
- IfFailGo(m_pEmit->DefineField(m_tdTypeDef, m_szMember, dwFlags, (PCCOR_SIGNATURE) qbComSig.Ptr(),cbTotal,
- ELEMENT_TYPE_VOID, NULL, -1, pmdField));
-
- // Save the field flags.
- if (psVar->wVarFlags)
- {
- IfFailGo(GetAttrType(ATTR_TYPELIBVAR, &tkAttr));
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(WORD));
- BUILD_CUSTOM_ATTRIBUTE(WORD, psVar->wVarFlags);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(*pmdField, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
-
- if (bConversionLoss)
- {
- IfFailGo(GetAttrType(ATTR_COMCONVERSIONLOSS, &tkAttr));
- DECLARE_CUSTOM_ATTRIBUTE(0);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(*pmdField, tkAttr, PTROF_CUSTOM_ATTRIBUTE(),SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
-
- // Set up the native description, if any.
- if (cbNative > 0)
- IfFailGo(m_pEmit->SetFieldMarshal(*pmdField, (PCCOR_SIGNATURE) qbNativeBuf.Ptr(), cbNative));
-
- // Add the alias information if the type is an alias.
- IfFailGo(_HandleAliasInfo(pITI, &psVar->elemdescVar.tdesc, *pmdField));
-
- if (bConversionLoss)
- {
- hr = S_CONVERSION_LOSS;
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_I_UNCONVERTABLE_FIELD, m_szName, m_szMember);
- }
-
-ErrExit:
- if (m_szMember)
- ::SysFreeString(m_szMember), m_szMember=0;
- return (hr);
-} // HRESULT CImportTlb::_ConvField()
-
-//*****************************************************************************
-// Convert a dispatch property into a pair of get/set functions.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvProperty(
- ITypeInfo *pITI, // Containing TypeInfo.
- MemberInfo *pMember) // VARDESC for the property.
-{
- HRESULT hr; // A result.
- mdMethodDef mdFuncGet; // A get function.
- mdMethodDef mdFuncSet; // A set function.
- mdProperty pdProperty; // Property on the two functions.
- DWORD dwFlags; // Function flags.
- WCHAR *pszName=0; // Decorated name of member.
- CQuickArray<WCHAR> qbName; // Buffer for decorated name.
- CQuickBytes qbComSig; // com signature buffer
- ULONG cb; // Size of an element.
- ULONG cbTotal = 0; // Total size of signature.
- BYTE *pbSig; // Pointer to signature buffer.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
- CQuickArray<BYTE> qbNativeBuf; // Native type buffer.
- ULONG iNativeOfs=0; // Current offset in native type buffer.
- VARDESC *psVar = pMember->m_psVar;
-
- // Check to see if the property is the NewEnum member.
- if (PropertyIsNewEnum(pITI, psVar, pMember->m_iMember) == S_OK)
- return _ConvNewEnumProperty(pITI, psVar, pMember);
-
- // Get the name.
- IfFailGo(pITI->GetDocumentation(psVar->memid, &m_szMember, 0,0,0));
-
- // Create the get signature.
- IfFailGo(qbComSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE * 2));
- pbSig = reinterpret_cast<BYTE*>(qbComSig.Ptr());
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS, pbSig);
- // Getter takes zero parameters.
- cb = CorSigCompressData(0, &(pbSig[cb]));
- cbTotal += cb;
- // Getter returns the property type.
- IfFailGo(_ConvSignature(pITI, &psVar->elemdescVar.tdesc, SIG_ELEM, qbComSig, cbTotal, &cbTotal, qbNativeBuf, 0, &iNativeOfs, FALSE));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
-
- // Getter properties.
- dwFlags = DEFAULT_PROPERTY_FUNC_FLAGS;
- // If processing an implemented interface, remove the abstract bit. Methods on classes are not abstract.
- if (m_ImplIface != eImplIfaceNone)
- dwFlags &= ~mdAbstract;
-
- // Get the previously decorated name. Add interface name and make unique.
- // m_szInterface should be non-null if processing an implemented interface; should be null otherwise.
- _ASSERTE(m_ImplIface == eImplIfaceNone || m_szInterface != 0);
- IfFailGo(qbName.ReSizeNoThrow(wcslen(pMember->m_pName)+2));
- wcscpy_s(qbName.Ptr(), wcslen(pMember->m_pName)+2, pMember->m_pName);
- IfFailGo(GenerateUniqueMemberName(qbName, (PCCOR_SIGNATURE)qbComSig.Ptr(), cbTotal, m_szInterface, mdtMethodDef));
- pszName = qbName.Ptr();
-
- // Create the get Accessor.
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, pszName, dwFlags, (PCCOR_SIGNATURE) qbComSig.Ptr(), cbTotal,
- 0/*RVA*/, DEFAULT_ITF_FUNC_IMPL_FLAGS, &mdFuncGet));
-
- // Handle dispids for non-implemented interfaces, and for default interface
- if (m_ImplIface != eImplIface)
- {
- // Set the Dispid CA.
- _SetDispIDCA(pITI, pMember->m_iMember, psVar->memid, mdFuncGet, TRUE, NULL, FALSE);
- }
-
- // If processing an implemented interface, set up MethodImpls.
- if (m_ImplIface != eImplIfaceNone)
- {
- // Define a memberref on the implemented interface.
- mdToken mrItfMember;
- IfFailGo(m_pEmit->DefineMemberRef(m_tkInterface, pMember->m_pName, (PCCOR_SIGNATURE) qbComSig.Ptr(),cbTotal, &mrItfMember));
-
- // Define a method impl.
- IfFailGo(m_pEmit->DefineMethodImpl(m_tdTypeDef, mdFuncGet, mrItfMember));
- }
-
- // If not a read-only var, create the setter.
- if ((psVar->wVarFlags & VARFLAG_FREADONLY) == 0)
- {
- // Create the setter signature.
- IfFailGo(qbComSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE * 3));
- pbSig = reinterpret_cast<BYTE*>(qbComSig.Ptr());
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS, pbSig);
- // Setter takes one parameter.
- cb = CorSigCompressData(1, &(pbSig[cb]));
- cbTotal += cb;
- // Setter returns nothing.
- cb = CorSigCompressData(ELEMENT_TYPE_VOID, &pbSig[cbTotal]);
- cbTotal += cb;
- // Setter takes the property type.
- IfFailGo(_ConvSignature(pITI, &psVar->elemdescVar.tdesc, SIG_ELEM, qbComSig, cbTotal, &cbTotal, qbNativeBuf, 0, &iNativeOfs, FALSE));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
-
- // Setter properties.
- dwFlags = DEFAULT_PROPERTY_FUNC_FLAGS;
- // If processing an implemented interface, remove the abstract bit. Methods on classes are not abstract.
- if (m_ImplIface != eImplIfaceNone)
- dwFlags &= ~mdAbstract;
-
- // Get the previously decorated name. Add interface name and make unique.
- // m_szInterface should be non-null if processing an implemented interface; should be null otherwise.
- _ASSERTE(m_ImplIface == eImplIfaceNone || m_szInterface != 0);
- IfFailGo(qbName.ReSizeNoThrow(wcslen(pMember->m_pName2)+2));
- wcscpy_s(qbName.Ptr(), wcslen(pMember->m_pName2)+2, pMember->m_pName2);
- IfFailGo(GenerateUniqueMemberName(qbName, (PCCOR_SIGNATURE)qbComSig.Ptr(), cbTotal, m_szInterface, mdtMethodDef));
- pszName = qbName.Ptr();
-
- // Create the setter Accessor.
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, pszName, dwFlags, (PCCOR_SIGNATURE) qbComSig.Ptr(),cbTotal,
- 0/*RVA*/, DEFAULT_ITF_FUNC_IMPL_FLAGS, &mdFuncSet));
-
- // Handle dispids for non-implemented interfaces, and for default interface
- if (m_ImplIface != eImplIface)
- {
- // Set the Dispid CA.
- _SetDispIDCA(pITI, pMember->m_iMember, psVar->memid, mdFuncSet, TRUE, NULL, FALSE);
- }
-
- // If processing an implemented interface, set up MethodImpls.
- if (m_ImplIface != eImplIfaceNone)
- {
- // Define a memberref on the implemented interface.
- mdToken mrItfMember;
- IfFailGo(m_pEmit->DefineMemberRef(m_tkInterface, pMember->m_pName2, (PCCOR_SIGNATURE) qbComSig.Ptr(),cbTotal, &mrItfMember));
-
- // Define a method impl.
- IfFailGo(m_pEmit->DefineMethodImpl(m_tdTypeDef, mdFuncSet, mrItfMember));
- }
- }
- else
- { // read-only, setter method is nil.
- mdFuncSet = mdMethodDefNil;
- }
-
- // Create the property signature: 'type', or <fieldcallconv><type>
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_PROPERTY, pbSig);
- cb = CorSigCompressData(0, &(pbSig[cb]));
- cbTotal += cb;
- // Property is just the property type.
- IfFailGo(_ConvSignature(pITI, &psVar->elemdescVar.tdesc, SIG_ELEM, qbComSig, cbTotal, &cbTotal, qbNativeBuf, 0, &iNativeOfs, FALSE));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
-
- // Get the property name. Add interface name and make unique, if needed.
- // m_szInterface should be non-null if processing an implemented interface; should be null otherwise.
- _ASSERTE(m_ImplIface == eImplIfaceNone || m_szInterface != 0);
- IfFailGo(qbName.ReSizeNoThrow(wcslen(m_szMember)+2));
- wcscpy_s(qbName.Ptr(), wcslen(m_szMember)+2, m_szMember);
- IfFailGo(GenerateUniqueMemberName(qbName, (PCCOR_SIGNATURE)qbComSig.Ptr(), cbTotal, m_szInterface, mdtProperty));
- pszName = qbName.Ptr();
-
- // Set up the Property on the two methods.
- IfFailGo(m_pEmit->DefineProperty(m_tdTypeDef, pszName, 0/*dwFlags*/, (PCCOR_SIGNATURE) qbComSig.Ptr(),cbTotal, ELEMENT_TYPE_VOID, NULL/*default*/, -1,
- mdFuncSet, mdFuncGet, NULL, &pdProperty));
-
- // Handle dispids for non-implemented interfaces, and for default interface
- if (m_ImplIface != eImplIface)
- {
- // Set the Dispid CA on the property.
- long lDispSet = 1;
- _SetDispIDCA(pITI, pMember->m_iMember, psVar->memid, pdProperty, TRUE, &lDispSet, FALSE);
-
- // If this property is default property, add a custom attribute to the class.
- if (lDispSet == DISPID_VALUE)
- IfFailGo(_AddDefaultMemberCa(m_tdTypeDef, m_szMember));
- }
-
- // Add the alias information if the type is an alias.
- IfFailGo(_HandleAliasInfo(pITI, &psVar->elemdescVar.tdesc, pdProperty));
-
- if (bConversionLoss)
- {
- hr = S_CONVERSION_LOSS;
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_I_UNCONVERTABLE_ARGS, m_szName, m_szMember);
- }
-
-ErrExit:
- if (m_szMember)
- ::SysFreeString(m_szMember), m_szMember=0;
- return (hr);
-} // HRESULT CImportTlb::_ConvProperty()
-
-//*****************************************************************************
-// Convert the NewEnum dispatch property into the GetEnumerator method.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvNewEnumProperty(
- ITypeInfo *pITI, // Containing TypeInfo.
- VARDESC *psVar, // VARDESC for the property.
- MemberInfo *pMember)
-{
- HRESULT hr; // A result.
- mdMethodDef mdGetEnum; // The GetEnumerator method.
- CQuickBytes qbComSig; // com signature buffer
- ULONG cb; // Size of an element.
- ULONG cbTotal = 0; // Total size of signature.
- BYTE *pbSig; // Pointer to signature buffer.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
- CQuickArray<BYTE> qbNativeBuf; // Native type buffer.
- ULONG iNativeOfs=0; // Current offset in native type buffer.
-
- // Get the name.
- IfFailGo(pITI->GetDocumentation(psVar->memid, &m_szMember, 0,0,0));
-
- // Create the GetEnumerator signature.
- IfFailGo(qbComSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE * 2));
- pbSig = reinterpret_cast<BYTE*>(qbComSig.Ptr());
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS, pbSig);
-
- // GetEnumerator takes zero parameters.
- cb = CorSigCompressData(0, &(pbSig[cb]));
- cbTotal += cb;
-
- // Getter returns the property type.
- IfFailGo(_ConvSignature(pITI, &psVar->elemdescVar.tdesc, SIG_ELEM, qbComSig, cbTotal, &cbTotal, qbNativeBuf, 0, &iNativeOfs, TRUE));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
-
- // Create the GetEnumerator method.
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, GET_ENUMERATOR_MEMBER_NAME, DEFAULT_INTERFACE_FUNC_FLAGS, (PCCOR_SIGNATURE) qbComSig.Ptr(), cbTotal,
- 0/*RVA*/, DEFAULT_ITF_FUNC_IMPL_FLAGS, &mdGetEnum));
-
- // Set the Dispid CA.
- _SetDispIDCA(pITI, pMember->m_iMember, psVar->memid, mdGetEnum, TRUE, NULL, FALSE);
-
- // Add the alias information if the type is an alias.
- IfFailGo(_HandleAliasInfo(pITI, &psVar->elemdescVar.tdesc, mdGetEnum));
-
- if (bConversionLoss)
- {
- hr = S_CONVERSION_LOSS;
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_I_UNCONVERTABLE_ARGS, m_szName, m_szMember);
- }
-
-ErrExit:
- if (m_szMember)
- ::SysFreeString(m_szMember), m_szMember=0;
- return (hr);
-} // HRESULT CImportTlb::_ConvNewEnumProperty()
-
-//*****************************************************************************
-// Given an ITypeLib*, come up with a namespace name. Use the typelib name
-// unless there is one specified via custom attribute.
-//
-// NOTE: This returns the member variable m_wzNamespace if the typelib
-// is the importing typelib. That must not be freed!
-//*****************************************************************************
-HRESULT CImportTlb::GetNamespaceOfRefTlb(
- ITypeLib *pITLB, // TypeLib for which to get namespace name.
- BSTR *pwzNamespace, // Put the name here.
- CImpTlbDefItfToClassItfMap **ppDefItfToClassItfMap) // Put def itf to class itf map here.
-{
- mdAssemblyRef arDummy;
- BSTR wzAsmName = NULL;
- HRESULT hr = S_OK;
-
- // If already resolved, just return assembly ref.
- if (!m_LibRefs.Find(pITLB, &arDummy, pwzNamespace, &wzAsmName, NULL, ppDefItfToClassItfMap))
- {
- // Add a reference to the typelib.
- IfFailGo(_AddTlbRef(pITLB, &arDummy, pwzNamespace, &wzAsmName, ppDefItfToClassItfMap));
- }
-
-ErrExit:
- if (wzAsmName)
- ::SysFreeString(wzAsmName);
-
- return hr;
-} // HRESULT CImportTlb::GetNamespaceOfRefTlb()
-
-//*****************************************************************************
-// Given a TYPEDESC, resolve the USERDEFINED to the TYPEKIND.
-//*****************************************************************************
-HRESULT CImportTlb::_ResolveTypeDescAliasTypeKind(
- ITypeInfo *pITIAlias, // The typeinfo containing the typedesc.
- TYPEDESC *ptdesc, // The typedesc.
- TYPEKIND *ptkind) // Put the aliased typekind.
-{
- HRESULT hr; // A result.
- ITypeInfo *pTIResolved=0; // The resolved ITypeInfo.
- TYPEATTR *psResolved=0; // The resolved TypeInfo's TYPEATTR
-
- if (ptdesc->vt != VT_USERDEFINED)
- {
- *ptkind = TKIND_MAX;
- return S_FALSE;
- }
-
- hr = _ResolveTypeDescAlias(pITIAlias, ptdesc, &pTIResolved, &psResolved);
- if (hr == S_OK)
- *ptkind = psResolved->typekind;
- else
- *ptkind = TKIND_MAX;
-
- if (psResolved)
- pTIResolved->ReleaseTypeAttr(psResolved);
- if (pTIResolved)
- pTIResolved->Release();
-
- return hr;
-} // HRESULT CImportTlb::_ResolveTypeDescAliasTypeKind()
-
-//*****************************************************************************
-// Given a TYPEDESC in a TypeInfo, eliminate aliases (get to the aliased
-// type).
-//*****************************************************************************
-HRESULT CImportTlb::_ResolveTypeDescAlias(
- ITypeInfo *pITIAlias, // The typeinfo containing the typedesc.
- const TYPEDESC *ptdesc, // The typedesc.
- ITypeInfo **ppTIResolved, // Put the aliased ITypeInfo here.
- TYPEATTR **ppsAttrResolved, // Put the ITypeInfo's TYPEATTR here.
- GUID *pGuid) // Caller may want aliased object's guid.
-{
- HRESULT hr; // A result.
- ITypeInfo *pITI=0; // Referenced typeinfo.
- TYPEATTR *psAttr=0; // TYPEATTR of referenced typeinfo.
-
- // If the TDESC isn't a USERDEFINED, it is already resolved.
- if (ptdesc->vt != VT_USERDEFINED)
- {
- *ppTIResolved = pITIAlias;
- pITIAlias->AddRef();
- // Need to addref the [out] psAttr. Only way to do it:
- IfFailGo(pITIAlias->GetTypeAttr(ppsAttrResolved));
- hr = S_FALSE;
- goto ErrExit;
- }
-
- // The TYPEDESC is a USERDEFINED. Get the TypeInfo.
- IfFailGo(pITIAlias->GetRefTypeInfo(ptdesc->hreftype, &pITI));
- IfFailGo(pITI->GetTypeAttr(&psAttr));
-
- // If the caller needs the aliased object's guid, get it now.
- if (pGuid && *pGuid == GUID_NULL && psAttr->guid != GUID_NULL)
- *pGuid = psAttr->guid;
-
- // If the userdefined typeinfo is not itself an alias, then it is what the alias aliases.
- // Also, if the userdefined typeinfo is an alias to a builtin type, then the builtin
- // type is what the alias aliases.
- if (psAttr->typekind != TKIND_ALIAS || psAttr->tdescAlias.vt != VT_USERDEFINED)
- {
- *ppsAttrResolved = psAttr;
- *ppTIResolved = pITI;
- if (psAttr->typekind == TKIND_ALIAS)
- hr = S_FALSE;
- psAttr = 0;
- pITI = 0;
- goto ErrExit;
- }
-
- // The userdefined type was itself an alias to a userdefined type. Alias to what?
- hr = _ResolveTypeDescAlias(pITI, &psAttr->tdescAlias, ppTIResolved, ppsAttrResolved, pGuid);
-
-ErrExit:
- if (psAttr)
- pITI->ReleaseTypeAttr(psAttr);
- if (pITI)
- pITI->Release();
- return hr;
-} // HRESULT CImportTlb::_ResolveTypeDescAlias()
-
-//*****************************************************************************
-// Create the TypeInfo records (AKA classes, AKA critters).
-//*****************************************************************************
-HRESULT CImportTlb::GetKnownTypeToken(
- VARTYPE vt, // The type for which the token is desired.
- mdTypeRef *ptr) // Put the token here.
-{
- HRESULT hr = S_OK; // A result.
-
- _ASSERTE(
- (vt >= VT_CY && vt <= VT_DECIMAL) || (vt == VT_SAFEARRAY) || (vt == VT_SLOT_FOR_GUID) ||
- (vt == VT_SLOT_FOR_IENUMERABLE) || (vt == VT_SLOT_FOR_MULTICASTDEL) || (vt == VT_SLOT_FOR_TYPE) ||
- (vt == VT_SLOT_FOR_STRINGBUF));
-
- // If it has already been added, just return it.
- if (m_tkKnownTypes[vt])
- {
- *ptr = m_tkKnownTypes[vt];
- goto ErrExit;
- }
-
- // Not yet created, so create the typeref now.
- switch (vt)
- {
- //=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
- // WARNING: the VT_EMPTY slot is used for System.GUID!!
- case VT_SLOT_FOR_GUID:
- _ASSERTE(VT_SLOT_FOR_GUID == VT_EMPTY);
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_GUID, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_SLOT_FOR_GUID])); // Put mdTypeRef here
- break;
-
- // WARNING: the VT_NULL slot is used for System.Collections.IEnumerable!!
- case VT_SLOT_FOR_IENUMERABLE:
- _ASSERTE(VT_SLOT_FOR_IENUMERABLE == VT_NULL);
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_IENUMERABLE, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_SLOT_FOR_IENUMERABLE])); // Put mdTypeRef here
- break;
-
- // WARNING: the VT_I2 slot is used for System.MulticastDelegate!!
- case VT_SLOT_FOR_MULTICASTDEL:
- _ASSERTE(VT_SLOT_FOR_MULTICASTDEL == VT_I2);
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_MULTICASTDELEGATE, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_SLOT_FOR_MULTICASTDEL])); // Put mdTypeRef here
- break;
-
- // WARNING: the VT_I4 slot is used for System.Type!!
- case VT_SLOT_FOR_TYPE:
- _ASSERTE(VT_SLOT_FOR_TYPE == VT_I4);
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_TYPE, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_SLOT_FOR_TYPE])); // Put mdTypeRef here
- break;
-
- // WARNING: the VT_I8 slot is used for System.Text.StringBuilder!!
- case VT_SLOT_FOR_STRINGBUF:
- _ASSERTE(VT_SLOT_FOR_STRINGBUF == VT_I8);
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_STRINGBUFFER, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_SLOT_FOR_STRINGBUF])); // Put mdTypeRef here
- break;
-
- case VT_CY:
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_DECIMAL, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_CY])); // Put mdTypeRef here
- break;
-
- case VT_DATE:
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_DATE, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_DATE])); // Put mdTypeRef here
- break;
-
- case VT_DECIMAL:
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_DECIMAL, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_DECIMAL])); // Put mdTypeRef here
- break;
-
- case VT_SAFEARRAY:
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_ARRAY, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_SAFEARRAY])); // Put mdTypeRef here
- break;
-
- default:
- _ASSERTE(!"Unknown type in GetKnownTypes");
- IfFailGo(E_INVALIDARG);
- }
-
- _ASSERTE(!IsNilToken(m_tkKnownTypes[vt]));
- *ptr = m_tkKnownTypes[vt];
-
-ErrExit:
- return hr;
-} // HRESULT CImportTlb::GetKnownTypeToken()
-
-
-//*****************************************************************************
-// Given an ITypeInfo for a coclass, return an ITypeInfo for the default
-// interface. This is either the explicitly marked default, or the first
-// non-source interface.
-//*****************************************************************************
-HRESULT CImportTlb::GetDefaultInterface( // Error, S_OK or S_FALSE.
- ITypeInfo *pCoClassTI, // The TypeInfo of the coclass.
- ITypeInfo **pDefaultItfTI) // The returned default interface.
-{
- HRESULT hr; // A result
- HREFTYPE href; // HREFTYPE of an implemented interface.
- INT ImplFlags; // ImplType flags.
- ITypeInfo *pITI=NULL; // ITypeInfo for an interface.
- TYPEATTR *pCoClassTypeAttr; // The type attributes of the coclass.
- int NumInterfaces; // The number of interfaces on the coclass.
- int i; // A counter.
-
- // Initialize the default interface to NULL.
- *pDefaultItfTI = NULL;
-
- // Retrieve the number of interfaces the coclass has
- IfFailGo(pCoClassTI->GetTypeAttr(&pCoClassTypeAttr));
- NumInterfaces = pCoClassTypeAttr->cImplTypes;
- pCoClassTI->ReleaseTypeAttr(pCoClassTypeAttr);
-
- for (i=0; i < NumInterfaces; i++)
- {
- IfFailGo(pCoClassTI->GetImplTypeFlags(i, &ImplFlags));
-
- if ((ImplFlags & (IMPLTYPEFLAG_FSOURCE | IMPLTYPEFLAG_FDEFAULT)) == IMPLTYPEFLAG_FDEFAULT)
- {
- // We have found a default interface.
- if (*pDefaultItfTI)
- (*pDefaultItfTI)->Release();
-
- IfFailGo(pCoClassTI->GetRefTypeOfImplType(i, &href));
- IfFailGo(pCoClassTI->GetRefTypeInfo(href, pDefaultItfTI));
- break;
- }
- else if (!(ImplFlags & IMPLTYPEFLAG_FSOURCE) && !(*pDefaultItfTI))
- {
- // If this is the first normal interface we encounter then we need to
- // hang on to it in case we don't find any default interfaces. If that
- // happens then this is the one that will be returned.
- IfFailGo(pCoClassTI->GetRefTypeOfImplType(i, &href));
- IfFailGo(pCoClassTI->GetRefTypeInfo(href, pDefaultItfTI));
- }
- }
-
- // Return either S_OK or S_FALSE depending on if we have found a default interface.
- if (*pDefaultItfTI)
- return S_OK;
- else
- return S_FALSE;
-
-ErrExit:
- if (pITI)
- pITI->Release();
-
- return hr;
-} // HRESULT CImportTlb::GetDefaultInterface()
-
-//*****************************************************************************
-// Given a TypeInfo, return a TypeDef/TypeRef token.
-//*****************************************************************************
-HRESULT CImportTlb::_GetTokenForTypeInfo(
- ITypeInfo *pITI, // ITypeInfo for which to get token.
- BOOL bConvDefItfToClassItf, // If TRUE, convert the def itf to its class itf.
- mdToken *pToken, // Put the token here.
- __out_ecount (chTypeRef) __out_opt LPWSTR pszTypeRef, // Optional, put the name here.
- int chTypeRef, // Size of the name buffer in characters.
- int *pchTypeRef, // Optional, put size of name here.
- BOOL bAsmQualifiedName) // Assembly qualified name or not?
-{
- HRESULT hr; // A result.
- ITypeLib *pITLB=0; // Containing typelib.
- BSTR bstrNamespace=0; // Namespace of the type.
- BSTR bstrFullName=0; // Fully qualified name of type.
- BSTR bstrTempName=0; // Temp name.
- BSTR bstrAsmName=0; // Assembly name.
- LPCWSTR strTypeName=0; // The type name.
- mdAssemblyRef ar; // The typelib's assembly ref.
- TYPEATTR* psAttr = 0; // The TYPEATTR for the type info.
- CImpTlbDefItfToClassItfMap *pDefItfToClassItfMap; // The default interface to class interface map.
-
- // Get the library.
- IfFailGo(pITI->GetContainingTypeLib(&pITLB, 0));
-
- // Resolve the external reference.
- IfFailGo(_AddTlbRef(pITLB, &ar, &bstrNamespace, &bstrAsmName, &pDefItfToClassItfMap));
-
- // If are converting default interfaces to class interfaces, then check
- // to see if we need to do the convertion for the current ITypeInfo.
- if (bConvDefItfToClassItf)
- {
- // Retrieve the TYPEATTR.
- IfFailGo(pITI->GetTypeAttr(&psAttr));
-
- // If we are dealing with an interface, then check to see if there
- // is a class interface we should use.
- if (psAttr->typekind == TKIND_INTERFACE || psAttr->typekind == TKIND_DISPATCH)
- {
- strTypeName = pDefItfToClassItfMap->GetClassItfName(psAttr->guid);
- }
- }
-
- // If we haven't found a class interface, then use the current interface.
- if (!strTypeName)
- {
- // Get the name of the typeinfo.
- IfFailGo(GetManagedNameForTypeInfo(pITI, bstrNamespace, NULL, &bstrFullName));
- strTypeName = bstrFullName;
- }
-
- // Give name back to caller, if desired.
- if (pszTypeRef)
- wcsncpy_s(pszTypeRef, chTypeRef, strTypeName, chTypeRef-1);
- if (pchTypeRef)
- *pchTypeRef = (int)(wcslen(pszTypeRef) + 1);
-
- // Define the TypeRef (will return any existing typeref).
- IfFailGo(m_TRMap.DefineTypeRef(m_pEmit, ar, strTypeName, pToken));
-
- // If the caller desires an assembly qualified name, then provide it.
- if (bAsmQualifiedName)
- {
- int cchAsmQualifiedName = SysStringLen(bstrFullName) + SysStringLen(bstrAsmName) + 2;
- IfNullGo(bstrTempName = ::SysAllocStringLen(0, cchAsmQualifiedName));
- ns::MakeAssemblyQualifiedName(bstrTempName, cchAsmQualifiedName + 1, bstrFullName, SysStringLen(bstrFullName), bstrAsmName, SysStringLen(bstrAsmName));
- SysFreeString(bstrFullName);
- bstrFullName = bstrTempName;
- }
-
- // Give name back to caller, if desired.
- if (pszTypeRef)
- wcsncpy_s(pszTypeRef, chTypeRef, bstrFullName, chTypeRef-1);
- if (pchTypeRef)
- *pchTypeRef = (int)(wcslen(pszTypeRef) + 1);
-
-ErrExit:
- if (bstrNamespace)
- ::SysFreeString(bstrNamespace);
- if (bstrFullName)
- ::SysFreeString(bstrFullName);
- if (bstrAsmName)
- ::SysFreeString(bstrAsmName);
- if (pITLB)
- pITLB->Release();
- if (psAttr)
- pITI->ReleaseTypeAttr(psAttr);
-
- return (hr);
-} // HRESULT CImportTlb::_GetTokenForTypeInfo()
-
-//*****************************************************************************
-// Given a TypeInfo for a source interface, creates a new event interface
-// if none exists or returns an existing one.
-//*****************************************************************************
-HRESULT CImportTlb::_GetTokenForEventItf(ITypeInfo *pSrcItfITI, mdTypeRef *ptr)
-{
-#ifndef DACCESS_COMPILE
- HRESULT hr = S_OK; // A result.
- ImpTlbEventInfo* pEventInfo; // The event information.
- BSTR bstrSrcItfName = NULL; // The name of the CoClass.
- CQuickArray<WCHAR> qbEventItfName; // The name of the event interface.
- CQuickArray<WCHAR> qbEventProviderName; // The name of the event provider.
- mdToken tkAttr; // Custom attribute type.
- BSTR szOldName = NULL; // The old value m_tdTypeDef.
- mdTypeDef tdOldTypeDef = NULL; // The old value m_szName.
- TYPEATTR* psAttr = 0; // The TYPEATTR for the source interface.
- mdTypeRef trEventItf; // A type ref to the event interface.
- ITypeLib* pTypeTLB; // The typelib containing this interface.
- mdAssemblyRef ar; // Dummy AssmRef.
- BSTR wzNamespace=0; // Namespace of the event interface assembly.
- BSTR wzAsmName=0; // Assembly name of the event interface assembly.
- Assembly* SrcItfAssembly=0; // The Source Event Interface assembly.
- CQuickArray<WCHAR> qbSrcItfName; // The name of the source interface.
- CImpTlbDefItfToClassItfMap *pDefItfToClassItfMap; // The default interface to class interface map.
- BOOL fInheritsIEnum = FALSE;
-
- // Retrieve the namespace of the typelib containing this source interface.
- IfFailGo(pSrcItfITI->GetContainingTypeLib(&pTypeTLB, NULL));
-
- // Resolve the external reference.
- IfFailGo(_AddTlbRef(pTypeTLB, &ar, &wzNamespace, &wzAsmName, &pDefItfToClassItfMap));
-
- // Get the assembly + namespace the source interface resides in.
- // May return all NULL - indicating the importing assembly.
- m_LibRefs.Find(pTypeTLB, &ar, &wzNamespace, &wzAsmName, &SrcItfAssembly, NULL);
- if (SrcItfAssembly == NULL)
- SrcItfAssembly = m_pAssembly;
-
- // Retrieve the full name of the source interface.
- if (wzNamespace)
- IfFailGo(GetManagedNameForTypeInfo(pSrcItfITI, (WCHAR*)wzNamespace, NULL, &bstrSrcItfName));
- else
- IfFailGo(GetManagedNameForTypeInfo(pSrcItfITI, m_wzNamespace, NULL, &bstrSrcItfName));
-
- // Start by looking up the event information for the source itf type info.
- pEventInfo = m_EventInfoMap.FindEventInfo(bstrSrcItfName);
- if (pEventInfo)
- {
- SysFreeString(bstrSrcItfName);
- *ptr = pEventInfo->trEventItf;
- return S_OK;
- }
-
- // Store the old values of the ITypeInfo name and of the current type def.
- szOldName = m_szName;
- tdOldTypeDef = m_tdTypeDef;
- m_szName = NULL;
-
- // Get some information about the TypeInfo.
- IfFailGo(pSrcItfITI->GetDocumentation(MEMBERID_NIL, &m_szName, 0, 0, 0));
- IfFailGo(pSrcItfITI->GetTypeAttr(&psAttr));
-
- if (ExplicitlyImplementsIEnumerable(pSrcItfITI, psAttr) == S_OK)
- fInheritsIEnum = TRUE;
-
- // Generate a unique name for the event interface which will be of the form:
- // <ImportingAssemblyNamespace>.<SrcItfName>_Event<PotentialSuffix>
-
- // Strip the namespace
- IfFailGo(qbSrcItfName.ReSizeNoThrow(wcslen(bstrSrcItfName) + 2));
- ns::SplitPath((WCHAR*)bstrSrcItfName, NULL, 0, qbSrcItfName.Ptr(), (int)wcslen(bstrSrcItfName) + 1);
-
- // Add the namespace of the importing typelib and the event suffix
- IfFailGo(qbEventItfName.ReSizeNoThrow(qbSrcItfName.Size() + wcslen(m_wzNamespace) + EVENT_ITF_SUFFIX_LENGTH + 7));
- StringCchPrintf(qbEventItfName.Ptr(), qbEventItfName.Size(), W("%s.%s%s"), m_wzNamespace, qbSrcItfName.Ptr(), EVENT_ITF_SUFFIX);
- IfFailGo(GenerateUniqueTypeName(qbEventItfName));
-
- // Generate a unique name for the event provider which will be of the form:
- // <ImportingAssemblyNamespace>.<SrcItfName>_EventProvider<PotentialSuffix>
-
- // Add the namespace of the imporing typelib and the event suffix
- IfFailGo(qbEventProviderName.ReSizeNoThrow(qbSrcItfName.Size() + wcslen(m_wzNamespace) + EVENT_PROVIDER_SUFFIX_LENGTH + 7));
- StringCchPrintf(qbEventProviderName.Ptr(), qbEventProviderName.Size(), W("%s.%s%s"), m_wzNamespace, qbSrcItfName.Ptr(), EVENT_PROVIDER_SUFFIX);
- IfFailGo(GenerateUniqueTypeName(qbEventProviderName));
-
- // Add the event provider as a reserved name.
- m_ReservedNames.AddReservedName(qbEventProviderName.Ptr());
-
- // Create the typedef for the event interface.
- IfFailGo(m_pEmit->DefineTypeDef(qbEventItfName.Ptr(), tdPublic | tdInterface | tdAbstract, mdTypeDefNil, NULL, &m_tdTypeDef));
-
- // Hide the event interface from the VB object browser (_Event)
- _SetHiddenCA(m_tdTypeDef);
-
- // Make the interface ComVisible(false).
- {
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(BYTE));
- BUILD_CUSTOM_ATTRIBUTE(BYTE, FALSE);
- IfFailGo(GetAttrType(ATTR_COMVISIBLE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
- // Set the ComEventInterface CA on the interface.
- {
- CQuickBytes asmQualifiedSrcItfName;
- if (!ns::MakeAssemblyQualifiedName(asmQualifiedSrcItfName, bstrSrcItfName, wzAsmName))
- IfFailGo(E_OUTOFMEMORY);
- DECLARE_DYNLEN_CUSTOM_ATTRIBUTE(wcslen((WCHAR*)asmQualifiedSrcItfName.Ptr()) + 5 + wcslen(qbEventProviderName.Ptr()) + 5);
- APPEND_WIDE_STRING_TO_CUSTOM_ATTRIBUTE((WCHAR*)asmQualifiedSrcItfName.Ptr());
- APPEND_WIDE_STRING_TO_CUSTOM_ATTRIBUTE(qbEventProviderName.Ptr());
- IfFailGo(GetAttrType(ATTR_COMEVENTINTERFACE, &tkAttr));
- FINISH_DYNLEN_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
- // Add the add_XXX and remove_XXX methods to the event interface.
- IfFailGo(_ConvSrcIfaceMembers(pSrcItfITI, psAttr, fInheritsIEnum));
-
- // Define a typeref for the event interface.
- IfFailGo(m_pEmit->DefineTypeRefByName(TokenFromRid(1, mdtModule), qbEventItfName.Ptr(), &trEventItf));
-
- // Add the event info to the map.
- IfFailGo(m_EventInfoMap.AddEventInfo(bstrSrcItfName, trEventItf, qbEventItfName.Ptr(), qbEventProviderName.Ptr(), SrcItfAssembly));
-
- // Set the out type ref.
- *ptr = trEventItf;
-
-ErrExit:
- if (bstrSrcItfName)
- ::SysFreeString(bstrSrcItfName);
- if (m_szName)
- ::SysFreeString(m_szName);
- if (psAttr)
- pSrcItfITI->ReleaseTypeAttr(psAttr);
- if (pTypeTLB)
- pTypeTLB->Release();
-
- // Restore the initial values for the ITypeInfo name and the type def.
- m_szName = szOldName;
- m_tdTypeDef = tdOldTypeDef;
-
- return (hr);
-#else
- DacNotImpl();
- return E_NOTIMPL;
-#endif // #ifndef DACCESS_COMPILE
-} // HRESULT CImportTlb::_GetTokenForEventItf()
-
-//*****************************************************************************
-// Creates an interface with the same name as the class and which implements
-// the default interface and the default event interface.
-//*****************************************************************************
-HRESULT CImportTlb::_CreateClassInterface(ITypeInfo *pCoClassITI, ITypeInfo *pDefItfITI, mdTypeRef trDefItf, mdTypeRef rtDefEvItf, mdToken *ptr)
-{
- HRESULT hr = S_OK; // A result.
- CQuickArray<mdToken> rImpls; // Array of implemented interfaces.
- int ixImpl = -1; // Index into rImpls for implemented interface.
- mdTypeDef tdTypeDef; // The class interface typedef.
- BSTR bstrFullName = NULL; // The name of the CoClass.
- TYPEATTR *psAttrIface=0; // TYPEATTR for an interface.
- CQuickArray<WCHAR> qbClassName; // The name of the class.
-
- IfFailGo(rImpls.ReSizeNoThrow(3));
- memset(rImpls.Ptr(), 0, 3 * sizeof(mdToken));
- if (trDefItf)
- rImpls[++ixImpl] = trDefItf;
- if (rtDefEvItf)
- rImpls[++ixImpl] = rtDefEvItf;
-
- // Retrieve the TypeAttr for the interface.
- if (pDefItfITI)
- IfFailGo(pDefItfITI->GetTypeAttr(&psAttrIface));
-
- // Retrieve the name of the CoClass (use the original name if this is an alias).
- IfFailGo(GetManagedNameForTypeInfo(m_pOrigITI, m_wzNamespace, NULL, &bstrFullName));
-
- // Create the typedef.
- IfFailGo(m_pEmit->DefineTypeDef(bstrFullName, rdwTypeFlags[TKIND_INTERFACE], mdTypeDefNil, 0, &tdTypeDef));
-
- // Set the IID to the IID of the default interface.
- IfFailGo(_AddGuidCa(tdTypeDef, psAttrIface ? psAttrIface->guid : GUID_NULL));
-
- // Add the CoClass CA to the interface.
- _AddStringCa(ATTR_COCLASS, tdTypeDef, m_szMngName);
-
- // Add the implemented interfaces and event interfaces to the TypeDef.
- IfFailGo(m_pEmit->SetTypeDefProps(tdTypeDef, ULONG_MAX/*Classflags*/,
- ULONG_MAX, (mdToken*)rImpls.Ptr()));
-
- // Set the out type def.
- *ptr = tdTypeDef;
-
-ErrExit:
- if (bstrFullName)
- ::SysFreeString(bstrFullName);
- if (psAttrIface)
- pDefItfITI->ReleaseTypeAttr(psAttrIface);
-
- return (hr);
-} // HRESULT CImportTlb::_CreateClassInterface()
-
-//*****************************************************************************
-// Creates an interface with the same name as the class and which implements
-// the default interface and the default event interface.
-//*****************************************************************************
-HRESULT CImportTlb::GetManagedNameForCoClass(ITypeInfo *pITI, CQuickArray<WCHAR> &qbClassName)
-{
- HRESULT hr = S_OK; // A result.
- BSTR bstrFullName=0; // Fully qualified name of type.
-
- // Retrieve the name of the CoClass.
- IfFailGo(GetManagedNameForTypeInfo(pITI, m_wzNamespace, NULL, &bstrFullName));
-
- // Resize the class name to accomodate the Class and potential suffix.
- IfFailGo(qbClassName.ReSizeNoThrow(wcslen(bstrFullName) + CLASS_SUFFIX_LENGTH + 6));
-
- // Set the class name to the CoClass name suffixed with Class.
- StringCchPrintf(qbClassName.Ptr(), qbClassName.Size(), W("%s%s"), bstrFullName, CLASS_SUFFIX);
-
- // Generate a unique name for the class.
- IfFailGo(GenerateUniqueTypeName(qbClassName));
-
-ErrExit:
- if (bstrFullName)
- ::SysFreeString(bstrFullName);
-
- return (hr);
-} // HRESULT CImportTlb::GetManagedNameForCoClass()
-
-//*****************************************************************************
-// Creates an interface with the same name as the class and which implements
-// the default interface and the default event interface.
-//*****************************************************************************
-HRESULT CImportTlb::GenerateUniqueTypeName(CQuickArray<WCHAR> &qbTypeName)
-{
- HRESULT hr = S_OK; // A result.
- WCHAR *pSuffix=0; // Location for suffix.
- size_t cchSuffix;
- WCHAR *pName=0; // The name without the namespace.
- int iSuffix=2; // Starting value for suffix.
- mdToken td; // For looking up a TypeDef.
- BSTR szTypeInfoName=0; // Name of a typeinfo.
- ITypeInfo *pITI=0; // A typeinfo.
-
- // Resize the class name to accomodate the Class and potential suffix.
- IfFailGo(qbTypeName.ReSizeNoThrow(wcslen(qbTypeName.Ptr()) + 6));
-
- // Set the suffix pointer.
- pSuffix = qbTypeName.Ptr() + wcslen(qbTypeName.Ptr());
- cchSuffix = qbTypeName.Size() - wcslen(qbTypeName.Ptr());
-
- // Set the name pointer.
- WCHAR* pTemp = ns::FindSep(qbTypeName.Ptr());
- if (pTemp == NULL)
- pName = qbTypeName.Ptr();
- else
- pName = pTemp + 1;
-
- // Attempt to find a class name that is not in use.
- for (;;)
- {
- // First check to see if the type name is in use in the metadata we
- // have emitted so far.
- hr = m_pImport->FindTypeDefByName(qbTypeName.Ptr(), mdTypeDefNil, &td);
- if (hr == CLDB_E_RECORD_NOTFOUND)
- {
- // It is not in use in the metadata but we still need to check the
- // typelib because the type might not have been emitted yet.
- USHORT cReq = 4;
- USHORT cFound = cReq;
- BOOL bTypeInTlb = FALSE;
- CQuickArray<ITypeInfo *> qbTI;
- CQuickArray<MEMBERID> qbMemId;
-
- // Retrieve all the instances of the name in the typelib.
- do
- {
- // Double the number of requested names.
- cReq *= 2;
-
- // Resize the array's to accomodate the resquested names.
- IfFailGo(qbTI.ReSizeNoThrow(cReq));
- IfFailGo(qbMemId.ReSizeNoThrow(cReq));
-
- // Request the names.
- cFound = cReq;
- IfFailGo(m_pITLB->FindName(pName, 0, qbTI.Ptr(), qbMemId.Ptr(), &cFound));
-
- // Release all the ITypeInfo's.
- for (int i = 0; i < cFound; i++)
- qbTI[i]->Release();
- }
- while (cReq == cFound);
-
- // Check to see if one of the instances of the name is for a type.
- for (int i = 0; i < cFound; i++)
- {
- if (qbMemId[i] == MEMBERID_NIL)
- {
- bTypeInTlb = TRUE;
- break;
- }
- }
-
- // If the type name exists in the typelib, but we didn't find it as a type,
- // we still need to do a deeper check, due to how FindName() works.
- if (!bTypeInTlb && cFound > 0)
- {
- int cTi; // Count of TypeInfos.
- int i; // Loop control.
-
- //@todo: this iterates over every typeinfo every time! We could cache
- // the names, and skip the types already converted. However, this should
- // be pretty rare.
-
- // How many TypeInfos?
- IfFailGo(cTi = m_pITLB->GetTypeInfoCount());
-
- // Iterate over them.
- for (i=0; i<cTi; ++i)
- {
- // Get the TypeInfo, and its name.
- IfFailGo(m_pITLB->GetTypeInfo(i, &pITI));
- IfFailGo(pITI->GetDocumentation(MEMBERID_NIL, &szTypeInfoName, 0, 0, 0));
- if (wcscmp(pName, szTypeInfoName) == 0)
- {
- bTypeInTlb = TRUE;
- break;
- }
-
- // Release for next TypeInfo.
- ::SysFreeString(szTypeInfoName);
- szTypeInfoName = 0;
- pITI->Release();
- pITI = 0;
- }
- }
-
- // The type name is not in the typelib and not in the metadata then we still
- // need to check to see if is a reserved name.
- if (!bTypeInTlb)
- {
- if (!m_ReservedNames.IsReservedName(qbTypeName.Ptr()))
- {
- // The name is not a reserved name so we can use it.
- break;
- }
- }
- }
- IfFailGo(hr);
-
- // Append the new suffix to the class name.
- StringCchPrintf(pSuffix, cchSuffix, W("_%i"), iSuffix++);
- }
-
-ErrExit:
- if (szTypeInfoName)
- ::SysFreeString(szTypeInfoName);
- if (pITI)
- pITI->Release();
- return (hr);
-} // HRESULT CImportTlb::GenerateUniqueTypeName()
-
-//*****************************************************************************
-// Generate a unique member name based on the interface member name.
-//*****************************************************************************
-HRESULT CImportTlb::GenerateUniqueMemberName(// S_OK or error
- CQuickArray<WCHAR> &qbMemberName, // Original name of member.
- PCCOR_SIGNATURE pSig, // Signature of the member.
- ULONG cSig, // Length of the signature.
- LPCWSTR szPrefix, // Possible prefix for decoration.
- mdToken type) // Is it a property? (Not a method?)
-{
- HRESULT hr; // A result.
- mdToken tkMember; // Dummy location for token.
- WCHAR *pSuffix=0; // Location for suffix.
- size_t cchSuffix = 0;
- int iSuffix=2; // Starting value for suffix.
-
- // Try to find a member name that is not already in use.
- for (;;)
- { // See if this is (finally) a unique member or property.
- switch (type)
- {
- case mdtProperty:
- hr = FindProperty(m_tdTypeDef, qbMemberName.Ptr(), 0, 0, &tkMember);
- // If name is OK as property, check that there is no method or
- // property with the name.
- if (hr == CLDB_E_RECORD_NOTFOUND)
- hr = FindMethod(m_tdTypeDef, qbMemberName.Ptr(), 0,0, &tkMember);
- if (hr == CLDB_E_RECORD_NOTFOUND)
- hr = FindEvent(m_tdTypeDef, qbMemberName.Ptr(), &tkMember);
- break;
- case mdtMethodDef:
- hr = FindMethod(m_tdTypeDef, qbMemberName.Ptr(), pSig, cSig, &tkMember);
- // If name is OK as method, check that there is no property or
- // event with the name.
- if (hr == CLDB_E_RECORD_NOTFOUND)
- hr = FindProperty(m_tdTypeDef, qbMemberName.Ptr(), 0,0, &tkMember);
- if (hr == CLDB_E_RECORD_NOTFOUND)
- hr = FindEvent(m_tdTypeDef, qbMemberName.Ptr(), &tkMember);
- break;
- case mdtEvent:
- hr = FindEvent(m_tdTypeDef, qbMemberName.Ptr(), &tkMember);
- // If name is OK as event, check that there is no property or
- // method with the name.
- if (hr == CLDB_E_RECORD_NOTFOUND)
- hr = FindProperty(m_tdTypeDef, qbMemberName.Ptr(), 0,0, &tkMember);
- if (hr == CLDB_E_RECORD_NOTFOUND)
- hr = FindMethod(m_tdTypeDef, qbMemberName.Ptr(), 0,0, &tkMember);
- break;
- default:
- // Unexpected type. Make noise, but let it pass.
- _ASSERTE(!"Unexpected token type in GenerateUniqueMemberName");
- hr = CLDB_E_RECORD_NOTFOUND;
- }
-
- // If name was not found, it is unique.
- if (hr == CLDB_E_RECORD_NOTFOUND)
- {
- hr = S_OK;
- goto ErrExit;
- }
- // Test for failure.
- IfFailGo(hr);
-
- // Make a test decoration.
- if (szPrefix)
- {
- size_t iLenPrefix, iLenName;
- iLenPrefix = wcslen(szPrefix);
- iLenName = wcslen(qbMemberName.Ptr());
- IfFailGo(qbMemberName.ReSizeNoThrow(iLenName + iLenPrefix + 2));
- // Shift by prefix length, plus '_'. Note use of overlap-safe move.
- memmove(&qbMemberName[iLenPrefix+1], &qbMemberName[0], (iLenName+1)*sizeof(WCHAR));
- wcscpy_s(qbMemberName.Ptr(), iLenPrefix + 1, szPrefix);
- qbMemberName[iLenPrefix] = W('_');
- szPrefix = 0;
- // Try again with prefix before trying a suffix.
- continue;
- }
- if (!pSuffix)
- {
- IfFailGo(qbMemberName.ReSizeNoThrow(wcslen(qbMemberName.Ptr()) + 6));
- pSuffix = qbMemberName.Ptr() + wcslen(qbMemberName.Ptr());
- cchSuffix = qbMemberName.Size() - wcslen(qbMemberName.Ptr());
- }
- StringCchPrintf(pSuffix, cchSuffix, W("_%i"), iSuffix++);
- }
-
-ErrExit:
- return hr;
-} // HRESULT CImportTlb::GenerateUniqueMemberName()
-
-//*****************************************************************************
-// Convert a TYPEDESC to a COM+ signature.
-//
-// Conversion rules:
-// integral types are converted as-is.
-// strings to strings, with native type decoration.
-// VT_UNKNOWN, VT_DISPATCH as ref class (ie, Object)
-// VT_PTR -> VT_USERDEFINED interface as Object
-// VT_USERDEFINED record as value type.
-//
-// With SIG_FUNC:
-// PTR to valuetype depends on other flags:
-// [IN] or [RETVAL] valuetype + NATIVE_TYPE_LPSTRUCT
-// [OUT] or [IN, OUT] byref valuetype
-// PTR to integral type:
-// [IN] @todo: see atti
-// [OUT] [IN, OUT] byref type
-// [RETVAL] type
-// PTR to object
-// [IN] @todo: see atti
-// [OUT] [IN, OUT] byref object
-// [RETVAL] object
-//
-// With SIG_FIELD:
-// PTR to integral type adds ELEMENT_TYPE_PTR.
-//
-// Conversion proceeds in three steps.
-// 1) Parse the COM type info. Accumulate VT_PTR and VT_BYREF into a count
-// of indirections. Follow TKIND_ALIAS to determine the ultimate aliased
-// type, and for non-user-defined types, convert that ultimate type.
-// Collect array sizes and udt names. Determine element type and native
-// type.
-// 2) Normalize to COM+ types. Determine if there is conversion loss.
-// 3) Emit the COM+ signature. Recurse to handle array types. Add native
-// type info if there is any.
-//*****************************************************************************
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
-#endif
-HRESULT CImportTlb::_ConvSignature( // S_OK, S_CONVERSION_LOSS, or error.
- ITypeInfo *pITI, // [IN] The typeinfo containing the TYPEDESC.
- const TYPEDESC *pType, // [IN] The TYPEDESC to convert.
- ULONG Flags, // [IN] Flags describing the TYPEDESC.
- CQuickBytes &qbSigBuf, // [IN, OUT] A CQuickBytes containing the signature.
- ULONG cbSig, // [IN] Where to start building the signature.
- ULONG *pcbSig, // [OUT] Where the signature ends (ix of first byte past; where to start next).
- CQuickArray<BYTE> &qbNativeTypeBuf, // [IN, OUT] A CQuickBytes containing the native type.
- ULONG cbNativeType, // [IN] Where to start building the native type.
- ULONG *pcbNativeType, // [OUT] Where the native type ends (ix of first byte past; where to start next).
- BOOL bNewEnumMember, // [IN] A flag indicating if the member is the NewEnum member.
- int iByRef) // [IN] ByRef count of caller (for recursive calls).
-{
- HRESULT hr=S_OK; // A result.
- TYPEDESC tdTemp; // Copy of TYPEDESC, for R/W.
- VARTYPE vt; // The typelib signature element.
- int bByRef=false; // If true, convert first pointer as "ELEMENT_TYPE_BYREF".
- COR_SIGNATURE et=0; // The COM+ signature element.
- mdToken tk=0; // Token from some COM+ signature element.
- ULONG nt=NATIVE_TYPE_NONE; // Native type decoration.
- ITypeInfo *pITIAlias=0; // Typeinfo of the aliased type.
- TYPEATTR *psAttrAlias=0; // TYPEATTR of the aliased typeinfo.
- ITypeInfo *pITIUD=0; // TypeInfo of an aliased UserDefined type.
- ITypeLib *pITLBUD=0; // TypeLib of an aliased UserDefined type.
- BSTR bstrNamespace=0; // Namespace name.
- BSTR bstrName=0; // UserDefined name.
- int bConversionLoss=false; // If true, the conversion was lossy.
- BYTE *pbSig; // Byte pointer for easy pointer math.
- ULONG cb; // Size of a signature element.
- ULONG cElems=0; // Count of elements in an array.
- int i; // Loop control.
- TYPEATTR *psAttr = 0; // The TYPEATTR for the user defined type being converted.
- const StdConvertibleItfInfo *pConvertionInfo = 0; // The standard convertible interface information.
- CQuickArray<BYTE> qbNestedNativeType;// A native type buffer used for array sig convertion.
- ULONG iNestedNativeTypeOfs=0; // A native type offset.
- ULONG nested=NATIVE_TYPE_NONE; // A nested native type.
-
- // VT_ to ELEMENT_TYPE_ translation table.
- struct VtSig
- {
- CorElementType et;
- CorNativeType nt;
- short flags;
- };
-
- // The VARIANT_TYPE to sig mapping table.
- static const VtSig
- _VtInfo[MAX_TLB_VT] =
- {
- // Relies on {0} initializing the entire sub-structure to 0.
- {ELEMENT_TYPE_MAX, NATIVE_TYPE_NONE, 0}, // VT_EMPTY = 0
- {ELEMENT_TYPE_MAX, NATIVE_TYPE_NONE, 0}, // VT_NULL = 1
- {ELEMENT_TYPE_I2, NATIVE_TYPE_NONE, 0}, // VT_I2 = 2
- {ELEMENT_TYPE_I4, NATIVE_TYPE_NONE, 0}, // VT_I4 = 3
- {ELEMENT_TYPE_R4, NATIVE_TYPE_NONE, 0}, // VT_R4 = 4
- {ELEMENT_TYPE_R8, NATIVE_TYPE_NONE, 0}, // VT_R8 = 5
- {ELEMENT_TYPE_VALUETYPE,NATIVE_TYPE_CURRENCY, 0}, // VT_CY = 6
- {ELEMENT_TYPE_VALUETYPE,NATIVE_TYPE_NONE, 0}, // VT_DATE = 7
- {ELEMENT_TYPE_STRING, NATIVE_TYPE_BSTR, 0}, // VT_BSTR = 8
- {ELEMENT_TYPE_OBJECT, NATIVE_TYPE_IDISPATCH, 0}, // VT_DISPATCH = 9
- {ELEMENT_TYPE_I4, NATIVE_TYPE_ERROR, 0}, // VT_ERROR = 10 scode
- {ELEMENT_TYPE_BOOLEAN, NATIVE_TYPE_NONE, 0}, // VT_BOOL = 11
- {ELEMENT_TYPE_OBJECT, NATIVE_TYPE_STRUCT, 0}, // VT_VARIANT = 12
- {ELEMENT_TYPE_OBJECT, NATIVE_TYPE_IUNKNOWN, 0}, // VT_UNKNOWN = 13
- {ELEMENT_TYPE_VALUETYPE,NATIVE_TYPE_NONE, 0}, // VT_DECIMAL = 14
- {ELEMENT_TYPE_MAX, NATIVE_TYPE_NONE, 0}, // = 15
- {ELEMENT_TYPE_I1, NATIVE_TYPE_NONE, 0}, // VT_I1 = 16
- {ELEMENT_TYPE_U1, NATIVE_TYPE_NONE, 0}, // VT_UI1 = 17
- {ELEMENT_TYPE_U2, NATIVE_TYPE_NONE, 0}, // VT_UI2 = 18
- {ELEMENT_TYPE_U4, NATIVE_TYPE_NONE, 0}, // VT_UI4 = 19
- {ELEMENT_TYPE_I8, NATIVE_TYPE_NONE, 0}, // VT_I8 = 20
- {ELEMENT_TYPE_U8, NATIVE_TYPE_NONE, 0}, // VT_UI8 = 21
-
- // it would be nice to convert these as I and U, with NT_I4 and NT_U4, but that doesn't work.
- {ELEMENT_TYPE_I4, NATIVE_TYPE_NONE, 0}, // VT_INT = 22 INT is I4 on win32
- {ELEMENT_TYPE_U4, NATIVE_TYPE_NONE, 0}, // VT_UINT = 23 UINT is UI4 on win32
-
- {ELEMENT_TYPE_VOID, NATIVE_TYPE_NONE, 0}, // VT_VOID = 24
-
- {ELEMENT_TYPE_I4, NATIVE_TYPE_ERROR, 0}, // VT_HRESULT = 25
- {ELEMENT_TYPE_MAX, NATIVE_TYPE_NONE, 0}, // VT_PTR = 26
- {ELEMENT_TYPE_MAX, NATIVE_TYPE_NONE, 0}, // VT_SAFEARRAY = 27
- {ELEMENT_TYPE_SZARRAY, NATIVE_TYPE_FIXEDARRAY, 0}, // VT_CARRAY = 28
- {ELEMENT_TYPE_MAX, NATIVE_TYPE_NONE, 0}, // VT_USERDEFINED = 29
- {ELEMENT_TYPE_STRING, NATIVE_TYPE_LPSTR, 0}, // VT_LPSTR = 30
- {ELEMENT_TYPE_STRING, NATIVE_TYPE_LPWSTR, 0}, // VT_LPWSTR = 31
- };
-
- _ASSERTE(pType && pcbSig && pcbNativeType);
-
- //-------------------------------------------------------------------------
- // Parse COM signature
-
- // Strip off leading VT_PTR and VT_BYREF
- while (pType->vt == VT_PTR)
- pType = pType->lptdesc, ++iByRef;
- if (pType->vt & VT_BYREF)
- {
- tdTemp = *pType;
- tdTemp.vt &= ~VT_BYREF;
- ++iByRef;
- pType = &tdTemp;
- }
-
- // Determine the element type, and possibly the token and/or native type.
- switch (vt=pType->vt)
- {
- case VT_PTR:
- _ASSERTE(!"Should not have VT_PTR here");
- break;
-
- // These are all known types (plus GUID).
- case VT_CY:
- case VT_DATE:
- case VT_DECIMAL:
- IfFailGo(GetKnownTypeToken(vt, &tk));
- et = _VtInfo[vt].et;
- nt = _VtInfo[vt].nt;
- break;
-
- case VT_SAFEARRAY:
- if (m_bSafeArrayAsSystemArray && !IsSigVarArg(Flags))
- {
- IfFailGo(GetKnownTypeToken(vt, &tk));
- et = ELEMENT_TYPE_CLASS;
- nt = NATIVE_TYPE_SAFEARRAY;
- }
- else
- {
- IfFailGo(GetKnownTypeToken(vt, &tk));
- et = ELEMENT_TYPE_SZARRAY;
- nt = NATIVE_TYPE_SAFEARRAY;
- }
- break;
-
- case VT_USERDEFINED:
- // Resolve the alias to the ultimate aliased type.
- IfFailGo(_ResolveTypeDescAlias(pITI, pType, &pITIAlias, &psAttrAlias));
-
- // If the aliased type was built-in, convert that built-in type.
- if (psAttrAlias->typekind == TKIND_ALIAS)
- { // Recurse to follow the alias chain.
- _ASSERTE(psAttrAlias->tdescAlias.vt != VT_USERDEFINED);
- hr = _ConvSignature(pITIAlias, &psAttrAlias->tdescAlias, Flags, qbSigBuf, cbSig, pcbSig, qbNativeTypeBuf, cbNativeType, pcbNativeType, bNewEnumMember, iByRef);
- goto ErrExit;
- }
-
- // If the type is a coclass then we need to retrieve the default interface and
- // substitute it for the coclass. Look up on the resolved alias, because it is
- // that class that has a default interface.
- if (psAttrAlias->typekind == TKIND_COCLASS)
- {
- ITypeInfo *pDefaultItf = NULL;
- hr = GetDefaultInterface(pITIAlias, &pDefaultItf);
- if ((hr != S_OK) || !pDefaultItf)
- {
- hr = E_UNEXPECTED;
- goto ErrExit;
- }
-
- pITIUD = pDefaultItf;
- }
- else
- { // USERDEFINED class/interface/record/union/enum. Retrieve the type
- // info for the user defined type. Note: use the TKIND_ALIAS typeinfo
- // itself for this conversion (not the aliased type) to preserve
- // names, lib locations, etc.
- IfFailGo(pITI->GetRefTypeInfo(pType->hreftype, &pITIUD));
- }
-
- // pITIUD points to the typeinfo for which we'll create a signature.
- IfFailGo(pITIUD->GetDocumentation(MEMBERID_NIL, &bstrName, 0,0,0));
- IfFailGo(pITIUD->GetContainingTypeLib(&pITLBUD, 0));
- IfFailGo(pITIUD->GetTypeAttr(&psAttr));
- IfFailGo(GetNamespaceNameForTypeLib(pITLBUD, &bstrNamespace));
-
- // If the "User Defined Type" is GUID in StdOle2, convert to M.R.GUID
- if (SString::_wcsicmp(bstrNamespace, COM_STDOLE2) == 0 && wcscmp(bstrName, COM_GUID) == 0)
- { // Classlib valuetype GUID.
- et = ELEMENT_TYPE_VALUETYPE;
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_GUID, &tk));
- }
- else
- { // Some user defined class. Is it a value class, or a VOS class?
- tk = 0;
- switch (psAttrAlias->typekind)
- {
- case TKIND_RECORD:
- case TKIND_ENUM:
- case TKIND_UNION:
- et = ELEMENT_TYPE_VALUETYPE;
- break;
- case TKIND_INTERFACE:
- case TKIND_DISPATCH:
- case TKIND_COCLASS:
- // A pointer to a user defined type of interface/dispatch/coclass
- // is a straight COM+ object (the ref is implicit), so eliminate
- // one byref count for those.
- // Somehow, there are typelibs written with ([out, retval] IFoo *pOut);
- if (iByRef <= 0)
- {
- // convert to an int.
- bConversionLoss = true;
- tk = 0;
- et = ELEMENT_TYPE_I;
- nt = NATIVE_TYPE_NONE;
- iByRef = 0;
- break;
- }
- else
- {
- --iByRef;
-
- // Check for references to Stdole2.IUnknown or Stdole2.IDispatch.
- if (psAttr->guid == IID_IUnknown)
- {
- vt = VT_UNKNOWN;
- goto IsReallyUnknown;
- }
- else if (psAttr->guid == IID_IDispatch)
- {
- vt = VT_DISPATCH;
- goto IsReallyUnknown;
- }
-
- // Check to see if this user defined type is one of the standard ones
- // we generate custom marshalers for.
- pConvertionInfo = GetConvertionInfoFromNativeIID(psAttr->guid);
- if (pConvertionInfo)
- {
- // Convert the UTF8 string to unicode.
- int MngTypeNameStrLen = (int)(strlen(pConvertionInfo->m_strMngTypeName) + 1);
- WCHAR *strFullyQualifiedMngTypeName = (WCHAR *)_alloca(MngTypeNameStrLen * sizeof(WCHAR));
- int ret = WszMultiByteToWideChar(CP_UTF8, 0, pConvertionInfo->m_strMngTypeName, MngTypeNameStrLen, strFullyQualifiedMngTypeName, MngTypeNameStrLen);
- _ASSERTE(ret != 0);
- if (!ret)
- IfFailGo(HRESULT_FROM_GetLastError());
-
- // Create a TypeRef to the marshaller.
- IfFailGo(m_TRMap.DefineTypeRef(m_pEmit, m_arSystem, strFullyQualifiedMngTypeName, &tk));
-
- // The type is a standard interface that we need to convert.
- et = ELEMENT_TYPE_CLASS;
- nt = NATIVE_TYPE_CUSTOMMARSHALER;
- break;
- }
- }
- et = ELEMENT_TYPE_CLASS;
- nt = NATIVE_TYPE_INTF;
- break;
- default:
- //case TKIND_MODULE: -- can't pass one of these as a parameter.
- //case TKIND_ALIAS: -- should already be resolved.
- _ASSERTE(!"Unexpected typekind for user defined type");
- et = ELEMENT_TYPE_END;
- } // switch (psAttrAlias->typekind)
- }
- break;
-
- IsReallyUnknown:
- case VT_UNKNOWN:
- case VT_DISPATCH:
- // If the NewEnum member, retrieve the custom marshaler information for IEnumVARIANT.
- if (bNewEnumMember && (pConvertionInfo=GetConvertionInfoFromNativeIID(IID_IEnumVARIANT)))
- {
- // Convert the UTF8 string to unicode.
- int MngTypeNameStrLen = (int)(strlen(pConvertionInfo->m_strMngTypeName) + 1);
- WCHAR *strFullyQualifiedMngTypeName = (WCHAR *)_alloca(MngTypeNameStrLen * sizeof(WCHAR));
- int ret = WszMultiByteToWideChar(CP_UTF8, 0, pConvertionInfo->m_strMngTypeName, MngTypeNameStrLen, strFullyQualifiedMngTypeName, MngTypeNameStrLen);
- _ASSERTE(ret != 0);
- if (!ret)
- IfFailGo(HRESULT_FROM_GetLastError());
-
- // Create a TypeRef to the marshaller.
- IfFailGo(m_TRMap.DefineTypeRef(m_pEmit, m_arSystem, strFullyQualifiedMngTypeName, &tk));
-
- // The type is a standard interface that we need to convert.
- et = ELEMENT_TYPE_CLASS;
- nt = NATIVE_TYPE_CUSTOMMARSHALER;
- }
- else
- {
- et = _VtInfo[vt].et;
- nt = _VtInfo[vt].nt;
- }
- break;
-
- case VT_CARRAY:
- // Determine the count of elements.
- for (cElems=1, i=0; i<pType->lpadesc->cDims; ++i)
- cElems *= pType->lpadesc->rgbounds[i].cElements;
-
- // Set the native type based on weither we are dealing with a field or a method sig.
- if (IsSigField(Flags))
- {
- nt = NATIVE_TYPE_FIXEDARRAY;
- }
- else
- {
- nt = NATIVE_TYPE_ARRAY;
- }
-
- // Set the element type.
- et = _VtInfo[vt].et;
- break;
-
- case VT_BOOL:
- // Special case for VARIANT_BOOL: If a field of a struct or union, convert
- // as ET_I2.
- if (IsSigField(Flags))
- vt = VT_I2;
- // Fall through to default case.
-
- default:
- if (vt > VT_LPWSTR)
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_BAD_VT_TYPE, vt, m_szName, m_szMember);
- IfFailGo(PostError(TLBX_E_BAD_VT_TYPE, vt, m_szName, m_szMember));
- }
- _ASSERTE(vt <= VT_LPWSTR && _VtInfo[vt].et != ELEMENT_TYPE_MAX);
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:26000) // "Disable PREFast/espX warning about buffer overflow"
-#endif
- et = _VtInfo[vt].et;
- nt = _VtInfo[vt].nt;
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
- break;
- } // switch (vt=pType->vt)
-
- //-------------------------------------------------------------------------
- // Normalize to COM+ types.
-
- // At this point the type, flags, and pointer nesting are known. Is this a legal combination?
- // If not, what is the appropriate "simplifing assumption"?
-
- if (et == ELEMENT_TYPE_VOID)
- {
- if (IsSigField(Flags))
- { // A void as a field. No byref.
- iByRef = 0;
- }
- else
- {
- // Param or return type. "void *" -> ET_I, "void **", "void ***",... -> ET_BYREF ET_I
- if (iByRef > 1)
- iByRef = 1;
- else
- if (iByRef == 1)
- iByRef = 0;
- }
- tk = 0;
- et = ELEMENT_TYPE_I;
- nt = NATIVE_TYPE_NONE;
- }
-
- if (et == ELEMENT_TYPE_STRING && iByRef == 0 && !IsSigField(Flags) && IsSigOut(Flags))
- {
- // This is an [out] or [in, out] string parameter without indirections.
- if (vt == VT_BSTR)
- {
- // [in, out] System.String does not make much sense. Managed strings are
- // immutable and we do not have BSTR <-> StringBuilder marshaling support.
- // Convert them to IntPtr.
- bConversionLoss = true;
- tk = 0;
- et = ELEMENT_TYPE_I;
- nt = NATIVE_TYPE_NONE;
- }
- else
- {
- _ASSERTE(vt == VT_LPSTR || vt == VT_LPWSTR);
-
- // [in, out] C-strings and wide strings have a lossless conversion to StringBuilder.
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_STRINGBUF, &tk));
- et = ELEMENT_TYPE_CLASS;
-
- // nt already has the right value
- _ASSERTE(nt == (vt == VT_LPSTR ? NATIVE_TYPE_LPSTR : NATIVE_TYPE_LPWSTR));
- }
- }
-
- if (iByRef)
- {
- if (et == ELEMENT_TYPE_VALUETYPE && iByRef >= 2)
- {
- bConversionLoss = true;
- tk = 0;
- et = ELEMENT_TYPE_I;
- nt = NATIVE_TYPE_NONE;
- iByRef = 0;
- }
- else
- {
- switch (Flags & SIG_TYPE_MASK)
- {
- case SIG_FIELD:
- // If ptr to valuetype or class type, we can't handle it.
- if (et == ELEMENT_TYPE_END ||
- et == ELEMENT_TYPE_CLASS ||
- et == ELEMENT_TYPE_OBJECT ||
- et == ELEMENT_TYPE_VALUETYPE)
- {
- bConversionLoss = true;
- tk = 0;
- et = ELEMENT_TYPE_I;
- nt = NATIVE_TYPE_NONE;
- iByRef = 0;
- }
- break;
- case SIG_FUNC:
- // Pointer to value type?
- if (et == ELEMENT_TYPE_VALUETYPE)
- {
- // For [retval], eat one level of indirection; otherwise turn one into BYREF
- if (IsSigOutRet(Flags))
- { // [out, retval], so reduce one level of indirection.
- --iByRef;
- }
- else
- { // Favor BYREF over NATIVE_TYPE_LPSTRUCT
- if (IsSigUseByref(Flags))
- {
- bByRef = true;
- --iByRef;
- }
- if (iByRef > 0)
- {
- nt = NATIVE_TYPE_LPSTRUCT;
- --iByRef;
- }
- }
- }
- else // Pointer to Object or base type.
- {
- if (IsSigRet(Flags))
- { // [retval] so consume one indirection.
- _ASSERTE(iByRef > 0);
- --iByRef;
- }
- if (iByRef > 0 && IsSigUseByref(Flags))
- {
- bByRef = true;
- --iByRef;
- }
- }
- break;
- case SIG_ELEM:
- // This case comes up when a property type is from a [retval].
- if (IsSigRet(Flags))
- {
- if (iByRef > 0)
- --iByRef;
- }
- break;
- }
- }
- } // if (iByRef)
-
- //-------------------------------------------------------------------------
- // We don't want any ET_PTR, so if there are any byref counts left, bail.
- if (iByRef)
- {
- bConversionLoss = true;
- tk = 0;
- et = ELEMENT_TYPE_I;
- nt = NATIVE_TYPE_NONE;
- iByRef = 0;
- bByRef = false;
- }
-
- //-------------------------------------------------------------------------
- // Build COM+ signature.
-
- // Type has been analyzed, and possibly modified. Emit the COM+ signature.
- _ASSERTE(et != ELEMENT_TYPE_MAX);
- _ASSERTE(et != ELEMENT_TYPE_END);
-
- // If it is a pointer to something, emit that now.
- if (bByRef || iByRef)
- {
- // Size the array to hold the elements.
- IfFailGo(qbSigBuf.ReSizeNoThrow(cbSig + CB_MAX_ELEMENT_TYPE * (iByRef+(bByRef?1:0))));
- pbSig = reinterpret_cast<BYTE*>(qbSigBuf.Ptr());
-
- // Put in any leading "BYREF"
- if (bByRef)
- {
- pbSig = reinterpret_cast<BYTE*>(qbSigBuf.Ptr());
- cb = CorSigCompressData(ELEMENT_TYPE_BYREF, &pbSig[cbSig]);
- cbSig += cb;
- }
-
- // Put in the "PTR"s.
- while (iByRef-- > 0)
- {
- cb = CorSigCompressData(ELEMENT_TYPE_PTR, &pbSig[cbSig]);
- cbSig += cb;
- }
- }
-
- // Emit the type.
- IfFailGo(qbSigBuf.ReSizeNoThrow(cbSig + CB_MAX_ELEMENT_TYPE));
- pbSig = reinterpret_cast<BYTE*>(qbSigBuf.Ptr());
- cb = CorSigCompressData(et, &pbSig[cbSig]);
- cbSig += cb;
-
- // Add the class type, the array information, etc.
- switch (et)
- {
- case ELEMENT_TYPE_CLASS:
- case ELEMENT_TYPE_VALUETYPE:
- // Size the array to hold the token.
- IfFailGo(qbSigBuf.ReSizeNoThrow(cbSig + CB_MAX_ELEMENT_TYPE));
- pbSig = reinterpret_cast<BYTE*>(qbSigBuf.Ptr());
-
- // If the token hasn't been resolved yet, do that now.
- if (tk == 0)
- {
- _ASSERTE(pITIUD);
- IfFailGo(_GetTokenForTypeInfo(pITIUD, TRUE, &tk));
- }
- cb = CorSigCompressToken(tk, reinterpret_cast<ULONG*>(&pbSig[cbSig]));
- cbSig += cb;
- break;
-
- case ELEMENT_TYPE_SZARRAY:
- // map to SZARRAY <subtype>
- IfFailGo(qbSigBuf.ReSizeNoThrow(cbSig + CB_MAX_ELEMENT_TYPE));
- pbSig = reinterpret_cast<BYTE*>(qbSigBuf.Ptr());
- // Recurse on the type.
- IfFailGo(_ConvSignature(pITI, &pType->lpadesc->tdescElem, SIG_ELEM, qbSigBuf, cbSig, &cbSig, qbNestedNativeType, 0, &iNestedNativeTypeOfs, bNewEnumMember));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
- break;
-
- case VT_DISPATCH:
- case VT_UNKNOWN:
- default:
- _ASSERTE(tk == 0);
- // et, nt assigned above.
- break;
- } // switch (et)
-
- // Do any native type info.
- if (nt != NATIVE_TYPE_NONE)
- {
- if (iNestedNativeTypeOfs > 0)
- CorSigUncompressData(reinterpret_cast<PCCOR_SIGNATURE>(qbNestedNativeType.Ptr()), &nested);
-
- if (nt == NATIVE_TYPE_FIXEDARRAY)
- {
- IfFailGo(qbNativeTypeBuf.ReSizeNoThrow(cbNativeType + NATIVE_TYPE_MAX_CB * 2 + DWORD_MAX_CB));
- cbNativeType += CorSigCompressData(nt, &qbNativeTypeBuf[cbNativeType]);
- cbNativeType += CorSigCompressData(cElems, &qbNativeTypeBuf[cbNativeType]);
- if (nested == NATIVE_TYPE_BSTR || nested == NATIVE_TYPE_LPWSTR || nested == NATIVE_TYPE_LPSTR)
- { // Use the nested type.
- cbNativeType += CorSigCompressData(nested, &qbNativeTypeBuf[cbNativeType]);
- }
- else
- { // Use a default sub type.
- cbNativeType += CorSigCompressData(NATIVE_TYPE_MAX, &qbNativeTypeBuf[cbNativeType]);
- }
- }
- else if (nt == NATIVE_TYPE_ARRAY)
- {
- IfFailGo(qbNativeTypeBuf.ReSizeNoThrow(cbNativeType + NATIVE_TYPE_MAX_CB * 2 + DWORD_MAX_CB * 2));
- cbNativeType += CorSigCompressData(nt, &qbNativeTypeBuf[cbNativeType]);
- if (nested == NATIVE_TYPE_BSTR || nested == NATIVE_TYPE_LPWSTR || nested == NATIVE_TYPE_LPSTR)
- { // Use the nested type.
- cbNativeType += CorSigCompressData(nested, &qbNativeTypeBuf[cbNativeType]);
- }
- else
- { // Use a default sub type.
- cbNativeType += CorSigCompressData(NATIVE_TYPE_MAX, &qbNativeTypeBuf[cbNativeType]);
- }
- // Use zero for param index.
- cbNativeType += CorSigCompressData(0, &qbNativeTypeBuf[cbNativeType]);
- // Use count from typelib for elem count.
- cbNativeType += CorSigCompressData(cElems, &qbNativeTypeBuf[cbNativeType]);
- }
- else if (nt == NATIVE_TYPE_SAFEARRAY)
- {
- BOOL bPtrArray = FALSE;
- CQuickArray<WCHAR> rTemp;
- CQuickArray<char> rTypeName;
- LPUTF8 strTypeName = "";
- TYPEDESC *pTypeDesc = &pType->lpadesc->tdescElem;
- VARTYPE ArrayElemVT = pTypeDesc->vt;
-
- if (ArrayElemVT == VT_PTR)
- {
- bPtrArray = TRUE;
- pTypeDesc = pType->lpadesc->tdescElem.lptdesc;
- ArrayElemVT = pTypeDesc->vt;
- if ((ArrayElemVT != VT_USERDEFINED) && (ArrayElemVT != VT_VOID))
- {
- // We do not support deep marshalling pointers.
- ArrayElemVT = VT_INT;
- bConversionLoss = TRUE;
- }
- }
-
- // If we are dealing with a safe array of user defined types and if we
- // are importing safe array's as System.Array then add the SafeArrayUserDefSubType.
- if (ArrayElemVT == VT_USERDEFINED)
- {
- // Resolve the alias to the ultimate aliased type.
- IfFailGo(_ResolveTypeDescAlias(pITI, pTypeDesc, &pITIAlias, &psAttrAlias));
-
- // If the type is a coclass then we need to retrieve the default interface and
- // substitute it for the coclass. Look up on the resolved alias, because it is
- // that class that has a default interface.
- if (psAttrAlias->typekind == TKIND_COCLASS)
- {
- ITypeInfo *pDefaultItf = NULL;
- hr = GetDefaultInterface(pITIAlias, &pDefaultItf);
- if ((hr != S_OK) || !pDefaultItf)
- {
- hr = E_UNEXPECTED;
- goto ErrExit;
- }
-
- pITIUD = pDefaultItf;
- }
- else
- { // USERDEFINED interface/record/union/enum. Retrieve the type
- // info for the user defined type. Note: use the TKIND_ALIAS typeinfo
- // itself for this conversion (not the aliased type) to preserve
- // names, lib locations, etc.
- IfFailGo(pITI->GetRefTypeInfo(pTypeDesc->hreftype, &pITIUD));
- }
-
- // pITIUD points to the typeinfo for which we'll create a signature.
- IfFailGo(pITIUD->GetTypeAttr(&psAttr));
-
- // Get the typeref name for the type.
- for(;;)
- {
- int cchReq;
- mdToken tkDummy;
- IfFailGo(_GetTokenForTypeInfo(pITIUD, TRUE, &tkDummy, rTemp.Ptr(), (int)rTemp.MaxSize(), &cchReq, TRUE));
- if (cchReq <= (int)rTemp.MaxSize())
- break;
- IfFailGo(rTemp.ReSizeNoThrow(cchReq));
- }
-
- // Convert the type name to UTF8.
- ULONG cbReq = WszWideCharToMultiByte(CP_UTF8, 0, rTemp.Ptr(), -1, 0, 0, 0, 0);
- IfFailGo(rTypeName.ReSizeNoThrow(cbReq + 1));
- WszWideCharToMultiByte(CP_UTF8, 0, rTemp.Ptr(), -1, rTypeName.Ptr(), cbReq, 0, 0);
-
- // Determine the safe array element VT.
- switch (psAttrAlias->typekind)
- {
- case TKIND_RECORD:
- case TKIND_ENUM:
- case TKIND_UNION:
- if (bPtrArray)
- {
- ArrayElemVT = VT_INT;
- bConversionLoss = TRUE;
- }
- else
- {
- ArrayElemVT = psAttrAlias->typekind == TKIND_ENUM ? VT_I4 : VT_RECORD;
- strTypeName = rTypeName.Ptr();
- }
- break;
-
- case TKIND_INTERFACE:
- case TKIND_DISPATCH:
- case TKIND_COCLASS:
- if (!bPtrArray)
- {
- ArrayElemVT = VT_INT;
- bConversionLoss = TRUE;
- }
- else
- {
- if (IsIDispatchDerived(pITIUD, psAttr) == S_FALSE)
- ArrayElemVT = VT_UNKNOWN;
- else
- ArrayElemVT = VT_DISPATCH;
- strTypeName = rTypeName.Ptr();
- }
- break;
- }
-
- // If we are not converting the SAFEARRAY to a System.Array, then
- // we don't need to encode the name of the user defined type.
- if (!m_bSafeArrayAsSystemArray)
- strTypeName = "";
- }
-
- // Make sure the native type buffer is large enough.
- ULONG TypeNameStringLen = (ULONG)strlen(strTypeName);
- IfFailGo(qbNativeTypeBuf.ReSizeNoThrow(cbNativeType + NATIVE_TYPE_MAX_CB * 2 + DWORD_MAX_CB + TypeNameStringLen + STRING_OVERHEAD_MAX_CB));
-
- // Add the native type to the native type info.
- cbNativeType += CorSigCompressData(nt, &qbNativeTypeBuf[cbNativeType]);
-
- // Add the VARTYPE of the array.
- cbNativeType += CorSigCompressData(ArrayElemVT, &qbNativeTypeBuf[cbNativeType]);
-
- // Add the type name to the native type info.
- BYTE *pNativeType = (BYTE*)CPackedLen::PutLength(&qbNativeTypeBuf[cbNativeType], TypeNameStringLen);
- cbNativeType += (ULONG)(pNativeType - &qbNativeTypeBuf[cbNativeType]);
- memcpy(&qbNativeTypeBuf[cbNativeType], strTypeName, TypeNameStringLen);
- cbNativeType += TypeNameStringLen;
- }
- else if (nt == NATIVE_TYPE_CUSTOMMARSHALER)
- {
- // Calculate the length of each string and then the total length of the native type info.
- ULONG MarshalerTypeNameStringLen = (ULONG)strlen(pConvertionInfo->m_strCustomMarshalerTypeName);
- ULONG CookieStringLen = (ULONG)strlen(pConvertionInfo->m_strCookie);
- ULONG TotalNativeTypeLen = MarshalerTypeNameStringLen + CookieStringLen;
- BYTE *pNativeType = 0;
-
- // Make sure the native type buffer is large enough.
- IfFailGo(qbNativeTypeBuf.ReSizeNoThrow(cbNativeType + NATIVE_TYPE_MAX_CB + TotalNativeTypeLen + STRING_OVERHEAD_MAX_CB * 4));
-
- // Add the native type to the native type info.
- cbNativeType += CorSigCompressData(nt, &qbNativeTypeBuf[cbNativeType]);
-
- // Add an empty string for the typelib guid.
- pNativeType = (BYTE*)CPackedLen::PutLength(&qbNativeTypeBuf[cbNativeType], 0);
- cbNativeType += (ULONG)(pNativeType - &qbNativeTypeBuf[cbNativeType]);
-
- // Add an empty string for the unmanaged type name.
- pNativeType = (BYTE*)CPackedLen::PutLength(&qbNativeTypeBuf[cbNativeType], 0);
- cbNativeType += (ULONG)(pNativeType - &qbNativeTypeBuf[cbNativeType]);
-
- // Add the name of the custom marshaler to the native type info.
- pNativeType = (BYTE*)CPackedLen::PutLength(&qbNativeTypeBuf[cbNativeType], MarshalerTypeNameStringLen);
- cbNativeType += (ULONG)(pNativeType - &qbNativeTypeBuf[cbNativeType]);
- memcpy(&qbNativeTypeBuf[cbNativeType], pConvertionInfo->m_strCustomMarshalerTypeName, MarshalerTypeNameStringLen);
- cbNativeType += MarshalerTypeNameStringLen;
-
- // Add the cookie to the native type info.
- pNativeType = (BYTE*)CPackedLen::PutLength(&qbNativeTypeBuf[cbNativeType], CookieStringLen);
- cbNativeType += (ULONG)(pNativeType - &qbNativeTypeBuf[cbNativeType]);
- memcpy(&qbNativeTypeBuf[cbNativeType], pConvertionInfo->m_strCookie, CookieStringLen);
- cbNativeType += CookieStringLen;
- }
- else
- {
- IfFailGo(qbNativeTypeBuf.ReSizeNoThrow(cbNativeType + NATIVE_TYPE_MAX_CB + 1));
- cbNativeType += CorSigCompressData(nt, &qbNativeTypeBuf[cbNativeType]);
- }
- }
-
- // Return the size of the native type to the caller.
- *pcbNativeType = cbNativeType;
-
- // Return size to caller.
- *pcbSig = cbSig;
-
- // If there was a conversion loss, change the return code.
- if (bConversionLoss)
- hr = S_CONVERSION_LOSS;
-
-ErrExit:
- if (bstrNamespace)
- ::SysFreeString(bstrNamespace);
- if (bstrName)
- ::SysFreeString(bstrName);
- if(psAttrAlias)
- pITIAlias->ReleaseTypeAttr(psAttrAlias);
- if (pITIAlias)
- pITIAlias->Release();
- if (psAttr)
- pITIUD->ReleaseTypeAttr(psAttr);
- if (pITIUD)
- pITIUD->Release();
- if (pITLBUD)
- pITLBUD->Release();
-
- return hr;
-} // HRESULT CImportTlb::_ConvSignature()
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
-//*****************************************************************************
-// Build a sorted list of functions to convert. (Sort by vtable offset.)
-//*****************************************************************************
-HRESULT CImportTlb::BuildMemberList(
- ITypeInfo *pITI, // TypeInfo with functions.
- int iStart, // First function to take.
- int iEnd, // Last function to take.
- BOOL bInheritsIEnum) // Inherits from IEnumerable.
-{
- HRESULT hr; // A result.
- int bNeedSort = false; // If true, need to sort the array.
- int ix = 0; // Loop counter.
- int oVftPrev = -1; // To see if oVft is increasing.
- TYPEATTR *psAttr = 0; // TypeAttr for pITI.
- FUNCDESC *psFunc; // A FUNCDESC.
- LPWSTR pszName; // Working pointer for name.
- BSTR bstrName=0; // Name from typelib.
- ITypeInfo2 *pITI2=0; // To get custom attributes.
- VARIANT vt; // Variant type.
- BOOL bFunctionToGetter; // Did a given getter come from a managed function?
-
- ::VariantInit(&vt);
-
- IfFailGo(pITI->GetTypeAttr(&psAttr));
- pITI->QueryInterface(IID_ITypeInfo2, reinterpret_cast<void**>(&pITI2));
-
- // Get the vars.
- IfFailGo(m_MemberList.ReSizeNoThrow(psAttr->cVars + iEnd - iStart));
- memset(m_MemberList.Ptr(), 0, m_MemberList.Size()*sizeof(MemberInfo));
- for (ix=0; ix<psAttr->cVars; ++ix)
- {
- IfFailGo(pITI->GetVarDesc(ix, &(m_MemberList[ix].m_psVar)));
- m_MemberList[ix].m_iMember = ix;
- }
- m_cMemberProps = psAttr->cVars;
-
- // Get the funcs.
- for (; iStart<iEnd; ++iStart, ++ix)
- {
- IfFailGo(TryGetFuncDesc(pITI, iStart, &(m_MemberList[ix].m_psFunc)));
- psFunc = m_MemberList[ix].m_psFunc;
- if (psFunc->oVft < oVftPrev)
- bNeedSort = true;
- oVftPrev = psFunc->oVft;
- m_MemberList[ix].m_iMember = iStart;
- }
-
- if (bNeedSort)
- {
- class Sorter : public CQuickSort<MemberInfo>
- {
- typedef CImportTlb::MemberInfo MemberInfo;
- public:
- Sorter(MemberInfo *p, int n) : CQuickSort<MemberInfo>(p,n) {}
- virtual int Compare(MemberInfo *p1, MemberInfo *p2)
- {
- if (p1->m_psFunc->oVft < p2->m_psFunc->oVft)
- return -1;
- if (p1->m_psFunc->oVft == p2->m_psFunc->oVft)
- return 0;
- return 1;
- }
- };
- Sorter sorter(m_MemberList.Ptr()+m_cMemberProps, (int)m_MemberList.Size()-m_cMemberProps);
- sorter.Sort();
- // Check for duplicates.
- oVftPrev = -1;
- for (ix=m_cMemberProps; ix<(int)m_MemberList.Size(); ++ix)
- {
- if (m_MemberList[ix].m_psFunc->oVft == oVftPrev)
- {
- hr = TLBX_E_BAD_VTABLE;
- break;
- }
- oVftPrev = m_MemberList[ix].m_psFunc->oVft;
- }
- }
-
- // Build the list of unique names.
- m_pMemberNames = new (nothrow) CWCHARPool;
- IfNullGo(m_pMemberNames);
-
- // Property names. No possibility of collisions.
- for (ix=0; ix<m_cMemberProps; ++ix)
- {
- IfFailGo(pITI->GetDocumentation(m_MemberList[ix].m_psVar->memid, &bstrName, 0,0,0));
- IfNullGo(pszName = m_pMemberNames->Alloc((ULONG)wcslen(bstrName)+PROP_DECORATION_LEN+1));
- wcscpy_s(pszName, wcslen(bstrName)+PROP_DECORATION_LEN+1, PROP_DECORATION_GET);
- wcscat_s(pszName, wcslen(bstrName)+PROP_DECORATION_LEN+1, bstrName);
- m_MemberList[ix].m_pName = pszName;
- if ((m_MemberList[ix].m_psVar->wVarFlags & VARFLAG_FREADONLY) == 0)
- {
- IfNullGo(pszName = m_pMemberNames->Alloc((ULONG)wcslen(bstrName)+PROP_DECORATION_LEN+1));
- wcscpy_s(pszName, wcslen(bstrName)+PROP_DECORATION_LEN+1, PROP_DECORATION_SET);
- wcscat_s(pszName, wcslen(bstrName)+PROP_DECORATION_LEN+1, bstrName);
- m_MemberList[ix].m_pName2 = pszName;
- }
- ::SysFreeString(bstrName);
- bstrName = 0;
- }
-
- // Function names. Because of get_/set_ decoration, collisions are possible.
- for (ix=m_cMemberProps; ix<(int)m_MemberList.Size(); ++ix)
- {
- int bNewEnumMember = FALSE;
-
- // Build a name based on invkind.
- psFunc = m_MemberList[ix].m_psFunc;
-
- // Unless we are doing the [out, retval] transformation for disp only interfaces,
- // we need to clear the [retval] flag.
- if (!m_bTransformDispRetVals)
- {
- if (psFunc->funckind == FUNC_DISPATCH)
- { // If [RETVAL] is set, clear it.
- for (int i=0; i<psFunc->cParams; ++i)
- if ((psFunc->lprgelemdescParam[i].paramdesc.wParamFlags & PARAMFLAG_FRETVAL) != 0)
- psFunc->lprgelemdescParam[i].paramdesc.wParamFlags &= ~PARAMFLAG_FRETVAL;
- }
- }
-
- BOOL bExplicitManagedName = FALSE;
- if ( (!bNewEnumMember) && (!bInheritsIEnum) && (FuncIsNewEnum(pITI, psFunc, m_MemberList[ix].m_iMember) == S_OK) )
- {
- // The member is the new enum member so set its name to GetEnumerator.
- IfNullGo(bstrName = SysAllocString(GET_ENUMERATOR_MEMBER_NAME));
- bNewEnumMember = TRUE;
-
- // To prevent additional methods from implementing the NewEnum method, we mark the interface
- bInheritsIEnum = TRUE;
- }
- else
- {
- // If the managed name custom value is set for this member, then use it.
- if (pITI2)
- {
- hr = pITI2->GetFuncCustData(m_MemberList[ix].m_iMember, GUID_ManagedName, &vt);
- if (hr == S_OK && vt.vt == VT_BSTR)
- {
- IfNullGo(bstrName = SysAllocString(vt.bstrVal));
- bExplicitManagedName = TRUE;
- }
- ::VariantClear(&vt);
- }
-
- if (!bstrName)
- IfFailGo(pITI->GetDocumentation(psFunc->memid, &bstrName, 0,0,0));
- }
-
- // If this is a property getter, see if it was originally a function.
- bFunctionToGetter = FALSE;
- if (psFunc->invkind == INVOKE_PROPERTYGET && pITI2)
- {
- hr = pITI2->GetFuncCustData(m_MemberList[ix].m_iMember, GUID_Function2Getter, &vt);
- if (hr == S_OK && vt.vt == VT_I4 && vt.lVal == 1)
- bFunctionToGetter = TRUE;
- ::VariantClear(&vt);
- }
-
-
- // Check for the propget and propset custom attributes if this not already a property.
- if ( (psFunc->invkind & (INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF)) == 0 )
- {
- INVOKEKIND ikind;
- if (S_OK == _CheckForPropertyCustomAttributes(pITI, m_MemberList[ix].m_iMember, &ikind))
- psFunc->invkind = ikind;
- }
-
-
- // If this is a property accessor, but not the 'new enum member', and not
- // originally from a managed function (that was exported as a getter),
- // decorate the name appropriately. If the managed name was set explicitly by
- // the Guid_ManagedName attribute, then don't try an decorate it.
- ULONG nChars = 0;
- if (!bExplicitManagedName && (psFunc->invkind & (INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF) && !bNewEnumMember && !bFunctionToGetter))
- {
- nChars = (ULONG)wcslen(bstrName)+PROP_DECORATION_LEN+1;
- IfNullGo(pszName = m_pMemberNames->Alloc(nChars));
-
- USHORT msSemantics=0; // Property's methodsemantics.
- FUNCDESC *psF; // FUNCDESC of Get, Put, or PutRef.
- TYPEDESC *pProperty; // TYPEDESC of property type.
- BOOL bPropRetval; // Is the property type a [retval]?
- IfFailGo(_GetFunctionPropertyInfo(psFunc, &msSemantics, &psF, &pProperty, &bPropRetval, FALSE, bstrName));
-
- m_MemberList[ix].m_msSemantics = msSemantics;
- switch(msSemantics)
- {
- case msGetter:
- wcscpy_s(pszName, nChars, PROP_DECORATION_GET);
- break;
- case msSetter:
- wcscpy_s(pszName, nChars, PROP_DECORATION_SET);
- break;
- case msOther:
- wcscpy_s(pszName, nChars, PROP_DECORATION_LET);
- break;
- default:
- _ASSERTE(msSemantics == 0);
- *pszName = 0;
- break;
- }
- wcscat_s(pszName, nChars, bstrName);
- }
- else
- {
- nChars = (ULONG)wcslen(bstrName)+1;
- IfNullGo(pszName = m_pMemberNames->Alloc(nChars));
- wcscpy_s(pszName, nChars, bstrName);
- }
-
- // Check for name collision, restore original name if collision occurs.
- for (int index=0; index<ix; index++)
- {
- if ( (m_MemberList[index].m_pName) && (wcscmp(pszName, m_MemberList[index].m_pName) == 0) )
- {
- wcscpy_s(pszName, nChars, bstrName);
- m_MemberList[ix].m_msSemantics = 0;
- }
- }
-
- // Save the unique name.
- m_MemberList[ix].m_pName = pszName;
- ::SysFreeString(bstrName);
- bstrName = 0;
- }
-
-ErrExit:
- if (pITI2)
- pITI2->Release();
- if (psAttr)
- pITI->ReleaseTypeAttr(psAttr);
- if (bstrName)
- ::SysFreeString(bstrName);
- ::VariantClear(&vt);
- return hr;
-} // HRESULT CImportTlb::BuildMemberList()
-
-//*****************************************************************************
-// Free the list built in BuildMemberList().
-//*****************************************************************************
-HRESULT CImportTlb::FreeMemberList(
- ITypeInfo *pITI) // TypeInfo with functions.
-{
- int ix; // Loop control.
- for (ix=0; ix<m_cMemberProps; ++ix)
- pITI->ReleaseVarDesc(m_MemberList[ix].m_psVar);
- m_cMemberProps = 0;
- for (; ix<(int)m_MemberList.Size(); ++ix)
- pITI->ReleaseFuncDesc(m_MemberList[ix].m_psFunc);
- m_MemberList.Shrink(0);
- if (m_pMemberNames)
- {
- delete m_pMemberNames;
- m_pMemberNames = 0;
- }
- return S_OK;
-} // HRESULT CImportTlb::FreeMemberList()
-
-//*****************************************************************************
-// Set a GUID CustomAttribute on an object.
-//*****************************************************************************
-HRESULT CImportTlb::_AddGuidCa( // S_OK or error.
- mdToken tkObj, // Object to be attributed.
- REFGUID guid) // The GUID.
-{
- HRESULT hr; // A result.
- mdMemberRef mr; // MemberRef for GUID CA.
- WCHAR wzGuid[40]; // Buffer for Guid, Unicode.
- CHAR szGuid[40]; // Buffer for Guid, Ansi.
- DECLARE_CUSTOM_ATTRIBUTE(40);
-
- // If GUID_NULL, don't store it.
- if (guid == GUID_NULL)
- return S_OK;
-
- // Get the GUID as a string.
- // ----+----1----+----2----+----3----+----4
- // {12345678-1234-1234-1234-123456789012}
- GuidToLPWSTR(guid, wzGuid, lengthof(wzGuid));
- _ASSERTE(wzGuid[37] == W('}'));
- wzGuid[37] = W('\0');
- WszWideCharToMultiByte(CP_UTF8, 0, wzGuid+1,-1, szGuid,sizeof(szGuid), 0,0);
-
- // Put it in the Custom Attribute.
- APPEND_STRING_TO_CUSTOM_ATTRIBUTE(szGuid);
-
- // Store the attribute
- IfFailGo(GetAttrType(ATTR_GUID, &mr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(tkObj, mr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
-
-ErrExit:
- return hr;
-} // HRESULT CImportTlb::_AddGuidCa()
-
-//*****************************************************************************
-// Add a default member as a custom attribute.
-//*****************************************************************************
-HRESULT CImportTlb::_AddDefaultMemberCa(// S_OK or error.
- mdToken tkObj, // TypeDef with default member.
- LPCWSTR wzName) // Name of the default member.
-{
- // Only set once per typedef.
- if (tkObj == m_tdHasDefault)
- return S_OK;
- m_tdHasDefault = tkObj;
-
- return _AddStringCa(ATTR_DEFAULTMEMBER, tkObj, wzName);
-} // HRESULT CImportTlb::_AddDefaultMemberCa()
-
-//*****************************************************************************
-// Add a string custom attribute of the given type to the token.
-//*****************************************************************************
-HRESULT CImportTlb::_AddStringCa( // S_OK or error.
- int attr, // The type of the CA.
- mdToken tk, // Token to add the CA to.
- LPCWSTR wzString) // String to put in the CA.
-{
- HRESULT hr = S_OK; // A result.
- mdMemberRef mr; // MemberRef for DefaultMember CA.
- BYTE *pca; // Pointer to custom attribute.
- BYTE *ca; // Pointer to custom attribute.
- int wzLen; // Length of wide string.
- int len; // Length of the string.
- CQuickArray<BYTE> buf;
-
- if (wzString == NULL)
- {
- hr = E_INVALIDARG;
- goto ErrExit;
- }
-
- // Prolog, up to 4 bytes length, string, epilog
- wzLen = (int)wcslen(wzString);
- len = WszWideCharToMultiByte(CP_UTF8,0, wzString, wzLen, 0,0, 0,0);
- IfFailGo(buf.ReSizeNoThrow(2 + 4 + len + 2));
- ca = pca = buf.Ptr();
-
- // Add prolog.
- *reinterpret_cast<UNALIGNED USHORT*>(pca) = 1;
- pca += sizeof(USHORT);
-
- // Add length.
- pca = reinterpret_cast<BYTE*>(CPackedLen::PutLength(pca, len));
-
- // Add string.
- WszWideCharToMultiByte(CP_UTF8,0, wzString, wzLen, reinterpret_cast<char*>(pca), len, 0, 0);
- pca += len;
-
- // Add epilog.
- *reinterpret_cast<UNALIGNED USHORT*>(pca) = 0;
- pca += sizeof(USHORT);
-
- // Store the attribute
- IfFailGo(GetAttrType(attr, &mr));
- IfFailGo(m_pEmit->DefineCustomAttribute(tk, mr, ca, (ULONG)(pca-ca), 0));
-
-ErrExit:
- return hr;
-} // HRESULT CImportTlb::_AddStringCa()
-
-//*****************************************************************************
-// Add a referenced typelib to the list of referenced typelibs. Check if
-// it is "this" typelib first.
-//*****************************************************************************
-HRESULT CImportTlb::_AddTlbRef( // S_OK or error.
- ITypeLib *pITLB, // The referenced typelib.
- mdAssemblyRef *par, // The AssemblyRef in this module.
- BSTR *pwzNamespace, // The namespace contained in the resolved assembly.
- BSTR *pwzAsmName, // The name of the resolved assembly.
- CImpTlbDefItfToClassItfMap **ppDefItfToClassItfMap) // The default interface to class interface map.
-{
- HRESULT hr = S_OK; // A result.
- IUnknown *pIUnk=0; // IUnknown for external assembly.
- mdAssemblyRef ar=0; // Assembly ref in the module containing the typeref.
- ITypeLib2 *pITLB2=0; // To get custom attributes.
- VARIANT vt; // Variant type.
- Assembly* ResolvedAssembly=0; // The resolved assembly.
- CImpTlbDefItfToClassItfMap *pDefItfToClassItfMap; // Temp def itf to class itf map.
-
- // Validate the arguments.
- _ASSERTE(pITLB && par && pwzNamespace && pwzAsmName);
-
- // Initialize the out parameters to NULL.
- *par = mdTokenNil;
- *pwzNamespace = NULL;
- *pwzAsmName = NULL;
- if (ppDefItfToClassItfMap)
- *ppDefItfToClassItfMap = NULL;
-
- ::VariantInit(&vt);
-
- // If not the importing typelib, add it to the list.
- if (pITLB == m_pITLB)
- { // Not an external assembly.
- //*par = mdAssemblyRefNil;
- *par = TokenFromRid(1, mdtModule);
- IfNullGo(*pwzNamespace = SysAllocStringLen(m_wzNamespace, SysStringLen(m_wzNamespace)));
- *pwzAsmName = NULL;
- if (ppDefItfToClassItfMap)
- *ppDefItfToClassItfMap = &m_DefItfToClassItfMap;
- return S_OK;
- }
-
- // If already resolved, just return assembly ref.
- if (m_LibRefs.Find(pITLB, par, pwzNamespace, pwzAsmName, NULL, ppDefItfToClassItfMap))
- return S_OK;
-
- // See if the typelib was exported, in which case it already has assembly ref information.
- if (pITLB->QueryInterface(IID_ITypeLib2, reinterpret_cast<void**>(&pITLB2)) == S_OK)
- {
- hr = pITLB2->GetCustData(GUID_ExportedFromComPlus, &vt);
- if (vt.vt == VT_BSTR)
- {
- // Use the CA data to get a reference.
- //CQuickArray<BYTE> rBuf;
- //int iLen;
- // The buffer should have been converted with CP_ACP, and should convert back directly.
- //IfFailGo(rBuf.ReSizeNoThrow(iLen=::SysStringLen(vt.bstrVal)));
- //if (iLen=WszWideCharToMultiByte(CP_ACP,0, vt.bstrVal,iLen, (char*)rBuf.Ptr(),iLen, 0,0))
- {
- // Define the assembly ref for the exported assembly.
- //ar = DefineAssemblyRefForExportedAssembly(rBuf.Ptr(),(DWORD)rBuf.Size(), m_pEmit);
- ar = DefineAssemblyRefForExportedAssembly(vt.bstrVal, m_pEmit);
-
- // Retrieve the namespace from the typelib.
- IfFailGo(GetNamespaceNameForTypeLib(pITLB, pwzNamespace));
-
- // Set the assembly name.
- IfNullGo(*pwzAsmName = SysAllocStringLen(vt.bstrVal, SysStringLen(vt.bstrVal)));
- }
- }
- }
-
- // If it wasn't directly converted to a reference, callback to the resolver.
- if (IsNilToken(ar))
- {
- // Get the assembly for that typelib.
- if (FAILED(m_Notify->ResolveRef(pITLB, &pIUnk)))
- IfFailGo(TLBX_I_RESOLVEREFFAILED);
-
- // If a NULL assembly was returned, then stop converting the type but
- // continue the import.
- if (pIUnk == NULL)
- IfFailGo(TLBX_E_INVALID_TYPEINFO);
-
- // Create an assembly ref in local assembly for referenced assembly.
- ar = DefineAssemblyRefForImportedTypeLib(m_pAssembly, m_pModule, m_pEmit, pIUnk, pwzNamespace, pwzAsmName, &ResolvedAssembly);
- }
-
- // Make sure the ref was resolved before adding to cache.
- if (IsNilToken(ar))
- IfFailGo(TLBX_I_RESOLVEREFFAILED);
-
- // Add the TLB to the list of references.
- IfFailGo(m_LibRefs.Add(pITLB, this, ar, *pwzNamespace, *pwzAsmName, ResolvedAssembly, &pDefItfToClassItfMap));
-
- // Set the output parameters.
- *par = ar;
- if (ppDefItfToClassItfMap)
- *ppDefItfToClassItfMap = pDefItfToClassItfMap;
-
-ErrExit:
- if (FAILED(hr))
- {
- if (*pwzNamespace)
- {
- SysFreeString(*pwzNamespace);
- *pwzNamespace = NULL;
- }
- if (*pwzAsmName)
- {
- SysFreeString(*pwzAsmName);
- *pwzAsmName = NULL;
- }
- }
- if (pIUnk)
- pIUnk->Release();
- if (pITLB2)
- pITLB2->Release();
- VariantClear(&vt);
-
- return hr;
-} // HRESULT CImportTlb::_AddTlbRef()
-
-//*****************************************************************************
-// Error reporting helper.
-//*****************************************************************************
-HRESULT CImportTlb::ReportEvent( // Returns the original HR.
- int ev, // The event kind.
- int hrRpt, // HR.
- ...) // Variable args.
-{
- HRESULT hr; // A result.
- va_list marker; // User text.
- BSTR bstrBuf=0; // BSTR for bufferrr.
- BSTR bstrMsg=0; // BSTR for message.
- const int iSize = 1024; // Message size;
-
- // We need a BSTR anyway for the call to ReportEvent, so just allocate a
- // big one for the buffer.
- IfNullGo(bstrBuf = ::SysAllocStringLen(0, iSize));
-
- // Format the message.
- va_start(marker, hrRpt);
- hr = FormatRuntimeErrorVa(bstrBuf, iSize, hrRpt, marker);
- va_end(marker);
-
- // Display it.
- IfNullGo(bstrMsg = ::SysAllocString(bstrBuf));
- m_Notify->ReportEvent(static_cast<ImporterEventKind>(ev), hrRpt, bstrMsg);
-
-ErrExit:
- // Clean up.
- if (bstrBuf)
- ::SysFreeString(bstrBuf);
- if (bstrMsg)
- ::SysFreeString(bstrMsg);
- return hrRpt;
-} // HRESULT CImportTlb::ReportEvent()
-
-//*****************************************************************************
-// Helper function to perform the shared functions of creating a TypeRef.
-//*****************************************************************************
-HRESULT CImpTlbTypeRef::DefineTypeRef( // S_OK or error.
- IMetaDataEmit *pEmit, // Emit interface.
- mdAssemblyRef ar, // The system assemblyref.
- const LPCWSTR szURL, // URL of the TypeDef, wide chars.
- mdTypeRef *ptr) // Put mdTypeRef here
-{
- HRESULT hr = S_OK; // A result.
- LPCWSTR szLookup; // The name to look up.
- mdToken tkNester; // Token of enclosing class.
-
- // If the name contains a '+', this is a nested type. The first part becomes
- // the resolution scope for the part after the '+'.
- szLookup = wcsrchr(szURL, NESTED_SEPARATOR_WCHAR);
- if (szLookup)
- {
- CQuickArray<WCHAR> qbName;
- IfFailGo(qbName.ReSizeNoThrow(szLookup - szURL + 1));
- wcsncpy_s(qbName.Ptr(), (szLookup - szURL + 1), szURL, szLookup - szURL);
- IfFailGo(DefineTypeRef(pEmit, ar, qbName.Ptr(), &tkNester));
- ar = tkNester;
- ++szLookup;
- }
- else
- szLookup = szURL;
-
- // Look for the item in the map.
- CImpTlbTypeRef::TokenOfTypeRefHashKey sSearch, *pMapped;
-
- sSearch.tkResolutionScope = ar;
- sSearch.szName = szLookup;
- pMapped = m_Map.Find(&sSearch);
-
- if (pMapped)
- {
- *ptr = pMapped->tr;
- goto ErrExit;
- }
-
- // Wasn't found, create a new one and add to the map.
- hr = pEmit->DefineTypeRefByName(ar, szLookup, ptr);
- if (SUCCEEDED(hr))
- {
- sSearch.tr = *ptr;
- pMapped = m_Map.Add(&sSearch);
- IfNullGo(pMapped);
- }
-
-ErrExit:
- return (hr);
-} // HRESULT CImpTlbTypeRef::DefineTypeRef()
-
-//*****************************************************************************
-// Free the held typelibs in the list of imported typelibs.
-//*****************************************************************************
-CImpTlbLibRef::~CImpTlbLibRef()
-{
- for (ULONG i = 0; i < Size(); i++)
- {
- SysFreeString(operator[](i).szNameSpace);
- delete operator[](i).pDefItfToClassItfMap;
- }
-} // CImpTlbLibRef::~CImpTlbLibRef()
-
-//*****************************************************************************
-// Add a new typelib reference to the list.
-//*****************************************************************************
-HRESULT CImpTlbLibRef::Add(
- ITypeLib *pITLB,
- CImportTlb *pImporter,
- mdAssemblyRef ar,
- BSTR wzNamespace,
- BSTR wzAsmName,
- Assembly* assm,
- CImpTlbDefItfToClassItfMap **ppMap)
-{
- HRESULT hr = S_OK; // A result.
- TLIBATTR *pAttr=0; // A typelib attribute.
- ULONG i; // Index.
- CTlbRef *pTlbRef=0; // A pointer to the TlbRef struct.
- CImpTlbDefItfToClassItfMap *pDefItfToClassItfMap = NULL; // ptr to the default interface to class interface map.
-
- // Validate the arguments.
- _ASSERTE(wzNamespace);
- _ASSERTE(wzAsmName);
-
- IfFailGo(pITLB->GetLibAttr(&pAttr));
-
-#if defined(_DEBUG)
- for (i=0; i<Size(); ++i)
- {
- if (operator[](i).guid == pAttr->guid)
- {
- _ASSERTE(!"External TypeLib already referenced");
- goto ErrExit;
- }
- }
-#else
- i = (ULONG)Size();
-#endif
-
- // Allocate and initialize the default interface to class interface map.
- pDefItfToClassItfMap = new (nothrow) CImpTlbDefItfToClassItfMap();
- IfNullGo(pDefItfToClassItfMap);
- IfFailGo(pDefItfToClassItfMap->Init(pITLB, wzNamespace));
-
- // Attemp to resize the array.
- IfFailGo(ReSizeNoThrow(i+1));
- pTlbRef = &operator[](i);
- pTlbRef->guid = pAttr->guid;
- pTlbRef->ar = ar;
- IfNullGo(pTlbRef->szNameSpace = SysAllocString(wzNamespace));
- IfNullGo(pTlbRef->szAsmName = SysAllocString(wzAsmName));
- pTlbRef->pDefItfToClassItfMap = pDefItfToClassItfMap;
- pTlbRef->Asm = assm;
-
-ErrExit:
- if (pAttr)
- pITLB->ReleaseTLibAttr(pAttr);
- if (FAILED(hr))
- {
- if (pTlbRef && pTlbRef->szNameSpace)
- SysFreeString(pTlbRef->szNameSpace);
- if (pTlbRef && pTlbRef->szAsmName)
- SysFreeString(pTlbRef->szAsmName);
- delete pDefItfToClassItfMap;
- }
- else
- {
- *ppMap = pDefItfToClassItfMap;
- }
-
- return hr;
-} // void CImpTlbLibRef::Add()
-
-//*****************************************************************************
-// Find an existing typelib reference.
-//*****************************************************************************
-int CImpTlbLibRef::Find(
- ITypeLib *pITLB,
- mdAssemblyRef *par,
- BSTR *pwzNamespace,
- BSTR *pwzAsmName,
- Assembly** assm,
- CImpTlbDefItfToClassItfMap **ppDefItfToClassItfMap)
-{
- HRESULT hr; // A result.
- TLIBATTR *pAttr=0; // A typelib attribute.
- int rslt = FALSE; // Return result.
- ULONG i; // Loop control.
-
- _ASSERTE(pwzNamespace);
- _ASSERTE(pwzAsmName);
-
- // Initalize the out parameters to NULL.
- *pwzNamespace = NULL;
- *pwzAsmName = NULL;
-
- if (assm)
- *assm = NULL;
-
- IfFailGo(pITLB->GetLibAttr(&pAttr));
-
- for (i=0; i<Size(); ++i)
- {
- if (operator[](i).guid == pAttr->guid)
- {
- *par = operator[](i).ar;
- IfNullGo(*pwzNamespace = SysAllocString(operator[](i).szNameSpace));
- IfNullGo(*pwzAsmName = SysAllocString(operator[](i).szAsmName));
- if (ppDefItfToClassItfMap)
- *ppDefItfToClassItfMap = operator[](i).pDefItfToClassItfMap;
- if (assm)
- *assm = operator[](i).Asm;
- rslt = TRUE;
- goto ErrExit;
- }
- }
-
-ErrExit:
- if (FAILED(hr))
- {
- if (*pwzNamespace)
- SysFreeString(*pwzNamespace);
- if (*pwzAsmName)
- SysFreeString(*pwzAsmName);
- }
- if (pAttr)
- pITLB->ReleaseTLibAttr(pAttr);
- return rslt;
-} // void CImpTlbLibRef::Find()
-
-//*****************************************************************************
-// unpack variant to an ELEMENT_TYPE_* plus a blob value
-// If VT_BOOL, it is a two-byte value.
-//*****************************************************************************
-HRESULT _UnpackVariantToConstantBlob(VARIANT *pvar, BYTE *pcvType, void **pvValue, __int64 *pd)
-{
- HRESULT hr = NOERROR;
-
- switch (pvar->vt)
- {
- case VT_BOOL:
- *pcvType = ELEMENT_TYPE_BOOLEAN;
- *((VARIANT_BOOL **)pvValue) = &(pvar->boolVal);
- break;
- case VT_I1:
- *pcvType = ELEMENT_TYPE_I1;
- *((CHAR **)pvValue) = &(pvar->cVal);
- break;
- case VT_UI1:
- *pcvType = ELEMENT_TYPE_U1;
- *((BYTE **)pvValue) = &(pvar->bVal);
- break;
- case VT_I2:
- *pcvType = ELEMENT_TYPE_I2;
- *((SHORT **)pvValue) = &(pvar->iVal);
- break;
- case VT_UI2:
- *pcvType = ELEMENT_TYPE_U2;
- *((USHORT **)pvValue) = &(pvar->uiVal);
- break;
- case VT_I4:
- case VT_INT:
- *pcvType = ELEMENT_TYPE_I4;
- *((LONG **)pvValue) = &(pvar->lVal);
- break;
- case VT_UI4:
- case VT_UINT:
- *pcvType = ELEMENT_TYPE_U4;
- *((ULONG **)pvValue) = &(pvar->ulVal);
- break;
- case VT_R4:
- *pcvType = ELEMENT_TYPE_R4;
- *((float **)pvValue) = &(pvar->fltVal);
- break;
- case VT_I8:
- *pcvType = ELEMENT_TYPE_I8;
- *((LONGLONG **)pvValue) = &(pvar->cyVal.int64);
- break;
- case VT_R8:
- *pcvType = ELEMENT_TYPE_R8;
- *((double **)pvValue) = &(pvar->dblVal);
- break;
- case VT_BSTR:
- *pcvType = ELEMENT_TYPE_STRING;
- *((BSTR *)pvValue) = pvar->bstrVal;
- break;
-
- case VT_DATE:
- *pcvType = ELEMENT_TYPE_I8;
- *pd = _DoubleDateToTicks(pvar->date);
- *((LONGLONG **)pvValue) = pd;
- break;
- case VT_UNKNOWN:
- case VT_DISPATCH:
- *pcvType = ELEMENT_TYPE_CLASS;
- _ASSERTE(pvar->punkVal == NULL);
- *((IUnknown ***)pvValue) = &(pvar->punkVal);
- break;
- default:
- _ASSERTE(!"Not a valid type to specify default value!");
- IfFailGo( META_E_BAD_INPUT_PARAMETER );
- break;
- }
-ErrExit:
- return hr;
-} // HRESULT _UnpackVariantToConstantBlob()
-
-//*****************************************************************************
-// Stolen from classlib.
-//*****************************************************************************
-INT64 _DoubleDateToTicks(const double d)
-{
- const INT64 MillisPerSecond = 1000;
- const INT64 MillisPerDay = MillisPerSecond * 60 * 60 * 24;
- const INT64 TicksPerMillisecond = 10000;
- const INT64 TicksPerSecond = TicksPerMillisecond * 1000;
- const INT64 TicksPerMinute = TicksPerSecond * 60;
- const INT64 TicksPerHour = TicksPerMinute * 60;
- const INT64 TicksPerDay = TicksPerHour * 24;
- const int DaysPer4Years = 365 * 4 + 1;
- const int DaysPer100Years = DaysPer4Years * 25 - 1;
- const int DaysPer400Years = DaysPer100Years * 4 + 1;
- const int DaysTo1899 = DaysPer400Years * 4 + DaysPer100Years * 3 - 367;
- const INT64 DoubleDateOffset = DaysTo1899 * TicksPerDay;
- const int DaysTo10000 = DaysPer400Years * 25 - 366;
- const INT64 MaxMillis = DaysTo10000 * MillisPerDay;
-
- INT64 millis = (INT64)(d * MillisPerDay + (d >= 0? 0.5: -0.5));
- if (millis < 0) millis -= (millis % MillisPerDay) * 2;
- millis += DoubleDateOffset / TicksPerMillisecond;
- if (millis < 0 || millis >= MaxMillis) {
- return 0;
- }
- return millis * TicksPerMillisecond;
-} // INT64 _DoubleDateToTicks()
-
-
-//*****************************************************************************
-// Wrapper for GetFuncDesc to catch errors.
-//*****************************************************************************
-static HRESULT TryGetFuncDesc( // S_OK or error.
- ITypeInfo *pITI, // ITypeInfo with function.
- int i, // Function index.
- FUNCDESC **ppFunc) // Put FUNCDESC here.
-{
- HRESULT hr; // A return code.
- __try
- {
- hr = pITI->GetFuncDesc(i, ppFunc);
- }
- __except(1)
- {
- hr = PostError(TLBX_E_TLB_EXCEPTION, _exception_code());
- }
-
- return hr;
-} // static HRESULT TryGetFuncDesc()
-
-//*****************************************************************************
-// Implementation of a hashed ResolutionScope+Name to TypeRef map.
-//*****************************************************************************
-void CImpTlbTypeRef::CTokenOfTypeRefHash::Clear()
-{
-#if defined(_DEBUG)
- // printf("Name to TypeRef cache: %d buckets, %d used, %d collisions\n", Buckets(), Count(), Collisions());
-#endif
- CClosedHash<class TokenOfTypeRefHashKey>::Clear();
-} // void CImpTlbTypeRef::CTokenOfTypeRefHash::Clear()
-
-unsigned int CImpTlbTypeRef::CTokenOfTypeRefHash::Hash(const TokenOfTypeRefHashKey *pData)
-{
- // Starting value for hash.
- ULONG hash = 5381;
-
- // Hash in the resolution scope token.
- const BYTE *pbData = reinterpret_cast<const BYTE *>(&pData->tkResolutionScope);
- int iSize = 4;
- while (--iSize >= 0)
- {
- hash = ((hash << 5) + hash) ^ *pbData;
- ++pbData;
- }
-
- // Hash in the typeref name.
- LPCWSTR szStr = pData->szName;
- int c;
- while ((c = *szStr) != 0)
- {
- hash = ((hash << 5) + hash) ^ c;
- ++szStr;
- }
-
- return hash;
-} // unsigned int CImpTlbTypeRef::CTokenOfTypeRefHash::Hash()
-
-unsigned int CImpTlbTypeRef::CTokenOfTypeRefHash::Compare(const TokenOfTypeRefHashKey *p1, TokenOfTypeRefHashKey *p2)
-{
- // Resolution scopes are fast to compare.
- if (p1->tkResolutionScope < p2->tkResolutionScope)
- return -1;
- if (p1->tkResolutionScope > p2->tkResolutionScope)
- return 1;
- // But if they are the same, compare the names.
- return wcscmp(p1->szName, p2->szName);
-} // unsigned int CImpTlbTypeRef::CTokenOfTypeRefHash::Compare()
-
-CImpTlbTypeRef::CTokenOfTypeRefHash::ELEMENTSTATUS CImpTlbTypeRef::CTokenOfTypeRefHash::Status(TokenOfTypeRefHashKey *p)
-{
- if (p->tkResolutionScope == static_cast<mdToken>(FREE))
- return (FREE);
- if (p->tkResolutionScope == static_cast<mdToken>(DELETED))
- return (DELETED);
- return (USED);
-} // CImpTlbTypeRef::CTokenOfTypeRefHash::ELEMENTSTATUS CImpTlbTypeRef::CTokenOfTypeRefHash::Status()
-
-void CImpTlbTypeRef::CTokenOfTypeRefHash::SetStatus(TokenOfTypeRefHashKey *p, ELEMENTSTATUS s)
-{
- p->tkResolutionScope = static_cast<mdToken>(s);
-} // void CImpTlbTypeRef::CTokenOfTypeRefHash::SetStatus()
-
-void *CImpTlbTypeRef::CTokenOfTypeRefHash::GetKey(TokenOfTypeRefHashKey *p)
-{
- return p;
-} // void *CImpTlbTypeRef::CTokenOfTypeRefHash::GetKey()
-
-CImpTlbTypeRef::TokenOfTypeRefHashKey* CImpTlbTypeRef::CTokenOfTypeRefHash::Add(const TokenOfTypeRefHashKey *pData)
-{
- LPWSTR pName;
- const void *pvData = pData;
- TokenOfTypeRefHashKey *pNew = Super::Add(const_cast<void*>(pvData));
- if (pNew == 0)
- return 0;
- pNew->szName = pName = m_Names.Alloc((ULONG)wcslen(pData->szName)+1);
- if (pNew->szName == 0)
- return 0;
- wcscpy_s(pName, wcslen(pData->szName)+1, pData->szName);
- pNew->tkResolutionScope = pData->tkResolutionScope;
- pNew->tr = pData->tr;
-
- return pNew;
-} // TokenOfTypeRefHashKey* CImpTlbTypeRef::CTokenOfTypeRefHash::Add()
-
-//*****************************************************************************
-// Implementation of a hashed ITypeInfo * source interface to event information
-// map.
-//*****************************************************************************
-HRESULT CImpTlbEventInfoMap::AddEventInfo(LPCWSTR szSrcItfName, mdTypeRef trEventItf, LPCWSTR szEventItfName, LPCWSTR szEventProviderName, Assembly* SrcItfAssembly)
-{
- ImpTlbEventInfo sNew;
- sNew.szSrcItfName = szSrcItfName;
- sNew.trEventItf = trEventItf;
- sNew.szEventItfName = szEventItfName;
- sNew.szEventProviderName = szEventProviderName;
- sNew.SrcItfAssembly = SrcItfAssembly;
- return Add(&sNew) != NULL ? S_OK : E_OUTOFMEMORY;
-} // BOOL CImpTlbEventInfoMap::AddEventInfo()
-
-ImpTlbEventInfo *CImpTlbEventInfoMap::FindEventInfo(LPCWSTR szSrcItfName)
-{
- ImpTlbEventInfo sSearch, *pMapped;
- sSearch.szSrcItfName = szSrcItfName;
- pMapped = Find(&sSearch);
- return pMapped;
-} // ImpTlbEventInfo *CImpTlbEventInfoMap::FindEventInfo()
-
-HRESULT CImpTlbEventInfoMap::GetEventInfoList(CQuickArray<ImpTlbEventInfo*> &qbEvInfoList)
-{
- HRESULT hr = S_OK;
- int cCurrEvInfo = 0;
-
- // Resise the event info list.
- IfFailGo(qbEvInfoList.ReSizeNoThrow(Count()));
-
- // Retrieve the first event info.
- ImpTlbEventInfo *pEvInfo = GetFirst();
-
- // Add all the event info's to the list.
- while (pEvInfo)
- {
- qbEvInfoList[cCurrEvInfo++] = pEvInfo;
- pEvInfo = GetNext(pEvInfo);
- }
-
-ErrExit:
- return hr;
-} // HRESULT CImpTlbEventInfoMap::GetEventInfoList()
-
-unsigned int CImpTlbEventInfoMap::Hash(const ImpTlbEventInfo *pData)
-{
- // Starting value for hash.
- ULONG hash = 5381;
-
- // Hash in the source interface name.
- LPCWSTR szStr = pData->szSrcItfName;
- int c;
- while ((c = *szStr) != 0)
- {
- hash = ((hash << 5) + hash) ^ c;
- ++szStr;
- }
-
- return hash;
-} // unsigned int CImpTlbEventInfoMap::Hash()
-
-unsigned int CImpTlbEventInfoMap::Compare(const ImpTlbEventInfo *p1, ImpTlbEventInfo *p2)
-{
- // Compare the source interface names.
- return wcscmp(p1->szSrcItfName, p2->szSrcItfName);
-} // unsigned int CImpTlbEventInfoMap::Compare()
-
-CImpTlbEventInfoMap::ELEMENTSTATUS CImpTlbEventInfoMap::Status(ImpTlbEventInfo *p)
-{
- if (p->szSrcItfName == reinterpret_cast<LPCWSTR>(FREE))
- return (FREE);
- if (p->szSrcItfName == reinterpret_cast<LPCWSTR>(DELETED))
- return (DELETED);
- return (USED);
-} // CImpTlbEventInfoMap::ELEMENTSTATUS CImpTlbEventInfoMap::Status()
-
-void CImpTlbEventInfoMap::SetStatus(ImpTlbEventInfo *p, ELEMENTSTATUS s)
-{
- p->szSrcItfName = reinterpret_cast<LPCWSTR>(s);
-} // void CImpTlbEventInfoMap::SetStatus()
-
-void *CImpTlbEventInfoMap::GetKey(ImpTlbEventInfo *p)
-{
- return p;
-} // void *CImpTlbEventInfoMap::GetKey()
-
-ImpTlbEventInfo* CImpTlbEventInfoMap::Add(const ImpTlbEventInfo *pData)
-{
- // Add the new entry to the map.
- const void *pvData = pData;
- ImpTlbEventInfo *pNew = Super::Add(const_cast<void*>(pvData));
- if (pNew == 0)
- return 0;
-
- // Copy the source interface name.
- pNew->szSrcItfName = m_Names.Alloc((ULONG)wcslen(pData->szSrcItfName)+1);
- if (pNew->szSrcItfName == 0)
- return 0;
- wcscpy_s((LPWSTR)pNew->szSrcItfName, wcslen(pData->szSrcItfName)+1, pData->szSrcItfName);
-
- // Copy the event interface type def.
- pNew->trEventItf = pData->trEventItf;
-
- // Copy the event interface name.
- pNew->szEventItfName = m_Names.Alloc((ULONG)wcslen(pData->szEventItfName)+1);
- if (pNew->szEventItfName == 0)
- return 0;
- wcscpy_s((LPWSTR)pNew->szEventItfName, wcslen(pData->szEventItfName)+1, pData->szEventItfName);
-
- // Copy the event provider name.
- pNew->szEventProviderName = m_Names.Alloc((ULONG)wcslen(pData->szEventProviderName)+1);
- if (pNew->szEventProviderName == 0)
- return 0;
- wcscpy_s((LPWSTR)pNew->szEventProviderName, wcslen(pData->szEventProviderName)+1, pData->szEventProviderName);
-
- // Copy the Source Interface Assembly pointer
- pNew->SrcItfAssembly = pData->SrcItfAssembly;
-
- // Return the new entry.
- return pNew;
-} // ImpTlbEventInfo* CImpTlbEventInfoMap::Add()
-
-CImpTlbDefItfToClassItfMap::CImpTlbDefItfToClassItfMap()
-: CClosedHash<class ImpTlbClassItfInfo>(101)
-, m_bstrNameSpace(NULL)
-{
-}
-
-CImpTlbDefItfToClassItfMap::~CImpTlbDefItfToClassItfMap()
-{
- Clear();
- if (m_bstrNameSpace)
- {
- ::SysFreeString(m_bstrNameSpace);
- m_bstrNameSpace = NULL;
- }
-}
-
-HRESULT CImpTlbDefItfToClassItfMap::Init(ITypeLib *pTlb, BSTR bstrNameSpace)
-{
- HRESULT hr; // A result.
- int cTi; // Count of TypeInfos.
- int i; // Loop control.
- TYPEATTR *psAttr=0; // TYPEATTR for the ITypeInfo.
- TYPEATTR *psDefItfAttr=0; // TYPEATTR for the default interface.
- ITypeInfo *pITI=0; // The ITypeInfo.
- ITypeInfo *pDefItfITI=0; // The ITypeInfo for the default interface.
-
- // Save the namespace.
- IfNullGo(m_bstrNameSpace = SysAllocString(bstrNameSpace));
-
- // How many TypeInfos?
- IfFailGo(cTi = pTlb->GetTypeInfoCount());
-
- // Iterate over them.
- for (i = 0; i < cTi; ++i)
- {
- // Get the TypeInfo.
- hr = pTlb->GetTypeInfo(i, &pITI);
- if (SUCCEEDED(hr))
- {
- // Retrieve the attributes of the type info.
- IfFailGo(pITI->GetTypeAttr(&psAttr));
-
- // If we are dealing with a CoClass, then set up the default interface to
- // class interface mapping.
- if (psAttr->typekind == TKIND_COCLASS)
- IfFailGo(AddCoClassInterfaces(pITI, psAttr));
-
- // Release for next TypeInfo.
- if (psAttr)
- {
- pITI->ReleaseTypeAttr(psAttr);
- psAttr = 0;
- }
- if (pITI)
- {
- pITI->Release();
- pITI = 0;
- }
- }
- }
-
-ErrExit:
- if (psAttr)
- pITI->ReleaseTypeAttr(psAttr);
- if (pITI)
- pITI->Release();
-
- return (hr);
-}
-
-HRESULT CImpTlbDefItfToClassItfMap::AddCoClassInterfaces(ITypeInfo *pCoClassITI, TYPEATTR *pCoClassTypeAttr)
-{
- HRESULT hr; // A result
- HREFTYPE href; // HREFTYPE of an implemented interface.
- INT ImplFlags; // ImplType flags.
- int NumInterfaces; // The number of interfaces on the coclass.
- int i; // A counter.
- ITypeInfo *pItfITI=0; // The ITypeInfo for the current interface.
- ITypeInfo *pBaseItfITI=0; // The ITypeInfo for the base interface.
- TYPEATTR *psItfAttr=0; // TYPEATTR for the interface.
- BSTR bstrClassItfName=0; // The name of the class interface.
-
- // Retrieve the name of the CoClass.
- IfFailGo(GetManagedNameForTypeInfo(pCoClassITI, m_bstrNameSpace, NULL, &bstrClassItfName));
-
- // Retrieve the default interface for the CoClass.
- IfFailGo(CImportTlb::GetDefaultInterface(pCoClassITI, &pItfITI));
-
- // If there is a default interface, then add it to the map.
- if (hr == S_OK)
- {
- // Retrieve the attributes of the default interface type info.
- IfFailGo(pItfITI->GetTypeAttr(&psItfAttr));
-
- // If there already is a CoClass that implements this
- // interface then we do not want to do the mapping.
- ImpTlbClassItfInfo sSearch, *pMapped;
- sSearch.ItfIID = psItfAttr->guid;
- pMapped = Find(&sSearch);
- if (pMapped)
- {
- // There already is a CoClass that implements the interface so
- // we set the class itf name to NULL to indicate not to do the def
- // itf to class itf convertion for this interface.
- pMapped->szClassItfName = NULL;
- }
- else
- {
- // Unless the default interface is IUnknown or IDispatch, add the
- // def itf to class itf entry to the map.
- if (psItfAttr->guid != IID_IUnknown && psItfAttr->guid != IID_IDispatch)
- {
- ImpTlbClassItfInfo sNew;
- sNew.ItfIID = psItfAttr->guid;
- sNew.szClassItfName = bstrClassItfName;
- IfNullGo(Add(&sNew));
- }
- }
-
- // Release for next interface.
- pItfITI->ReleaseTypeAttr(psItfAttr);
- psItfAttr = 0;
- pItfITI->Release();
- pItfITI = 0;
- }
-
- // Retrieve the number of interfaces the coclass has
- NumInterfaces = pCoClassTypeAttr->cImplTypes;
-
- // Go through all the interfaces and add them to the map.
- for (i=0; i < NumInterfaces; i++)
- {
- // Get the impl flags.
- IfFailGo(pCoClassITI->GetImplTypeFlags(i, &ImplFlags));
-
- // If this is an implemented interface.
- if (!(ImplFlags & IMPLTYPEFLAG_FSOURCE))
- {
- IfFailGo(pCoClassITI->GetRefTypeOfImplType(i, &href));
- IfFailGo(pCoClassITI->GetRefTypeInfo(href, &pItfITI));
-
- do
- {
- // Retrieve the attributes of the interface type info.
- IfFailGo(pItfITI->GetTypeAttr(&psItfAttr));
-
- // If there already is a CoClass that implements this
- // interface then we do not want to do the mapping.
- ImpTlbClassItfInfo sSearch, *pMapped;
- sSearch.ItfIID = psItfAttr->guid;
- pMapped = Find(&sSearch);
- if (pMapped)
- {
- // There already is a CoClass that implements the interface. If that
- // CoClass is not the current one, then we we set the class itf name
- // to NULL to indicate not to do the def itf to class itf convertion
- // for this interface.
- if (pMapped->szClassItfName && wcscmp(pMapped->szClassItfName, bstrClassItfName) != 0)
- pMapped->szClassItfName = NULL;
- }
- else
- {
- // Add an entry with a NULL name to prevent future substitutions.
- ImpTlbClassItfInfo sNew;
- sNew.ItfIID = psItfAttr->guid;
- sNew.szClassItfName = NULL;
- IfNullGo(Add(&sNew));
- }
-
- // If there is a base interface, then handle it also.
- if (psItfAttr->cImplTypes == 1)
- {
- IfFailGo(pItfITI->GetRefTypeOfImplType(0, &href));
- IfFailGo(pItfITI->GetRefTypeInfo(href, &pBaseItfITI));
- }
-
- // Release for next interface.
- if (psItfAttr)
- {
- pItfITI->ReleaseTypeAttr(psItfAttr);
- psItfAttr = 0;
- }
- if (pItfITI)
- {
- pItfITI->Release();
- pItfITI = 0;
- }
-
- // Set the current interface to the base interface.
- pItfITI = pBaseItfITI;
- pBaseItfITI = 0;
- }
- while(pItfITI);
- }
- }
-
-ErrExit:
- if (psItfAttr)
- pItfITI->ReleaseTypeAttr(psItfAttr);
- if (pItfITI)
- pItfITI->Release();
- if (bstrClassItfName)
- ::SysFreeString(bstrClassItfName);
-
- return hr;
-}
-
-LPCWSTR CImpTlbDefItfToClassItfMap::GetClassItfName(IID &rItfIID)
-{
- ImpTlbClassItfInfo sSearch, *pMapped;
- sSearch.ItfIID = rItfIID;
- pMapped = Find(&sSearch);
- return pMapped ? pMapped->szClassItfName : NULL;
-}
-
-unsigned int CImpTlbDefItfToClassItfMap::Hash(const ImpTlbClassItfInfo *pData)
-{
- // Starting value for hash.
- ULONG hash = 5381;
-
- // Hash in the IID.
- const BYTE *pbData = reinterpret_cast<const BYTE *>(&pData->ItfIID);
- int iSize = sizeof(IID);
- while (--iSize >= 0)
- {
- hash = ((hash << 5) + hash) ^ *pbData;
- ++pbData;
- }
-
- return hash;
-} // unsigned int CImpTlbDefItfToClassItfMap::Hash()
-
-unsigned int CImpTlbDefItfToClassItfMap::Compare(const ImpTlbClassItfInfo *p1, ImpTlbClassItfInfo *p2)
-{
- // Compare the IID's.
- return memcmp(&p1->ItfIID, &p2->ItfIID, sizeof(IID));
-} // unsigned int CImpTlbEventInfoMap::Compare()
-
-CImpTlbDefItfToClassItfMap::ELEMENTSTATUS CImpTlbDefItfToClassItfMap::Status(ImpTlbClassItfInfo *p)
-{
- if (IsEqualGUID(p->ItfIID, FREE_STATUS_GUID))
- {
- return (FREE);
- }
- else if (IsEqualGUID(p->ItfIID, DELETED_STATUS_GUID))
- {
- return (DELETED);
- }
- return (USED);
-} // CImpTlbDefItfToClassItfMap::ELEMENTSTATUS CImpTlbEventInfoMap::Status()
-
-void CImpTlbDefItfToClassItfMap::SetStatus(ImpTlbClassItfInfo *p, ELEMENTSTATUS s)
-{
- if (s == FREE)
- {
- p->ItfIID = FREE_STATUS_GUID;
- }
- else if (s == DELETED)
- {
- p->ItfIID = DELETED_STATUS_GUID;
- }
- else
- {
- _ASSERTE(!"Invalid status!");
- }
-} // void CImpTlbDefItfToClassItfMap::SetStatus()
-
-void *CImpTlbDefItfToClassItfMap::GetKey(ImpTlbClassItfInfo *p)
-{
- return p;
-} // void *CImpTlbDefItfToClassItfMap::GetKey()
-
-ImpTlbClassItfInfo* CImpTlbDefItfToClassItfMap::Add(const ImpTlbClassItfInfo *pData)
-{
- // Add the new entry to the map.
- const void *pvData = pData;
- ImpTlbClassItfInfo *pNew = Super::Add(const_cast<void*>(pvData));
- if (pNew == 0)
- return 0;
-
- // Copy the IID.
- pNew->ItfIID = pData->ItfIID;
-
- // Copy the class interface name.
- if (pData->szClassItfName)
- {
- pNew->szClassItfName = m_Names.Alloc((ULONG)wcslen(pData->szClassItfName)+1);
- if (pNew->szClassItfName == 0)
- return 0;
- wcscpy_s((LPWSTR)pNew->szClassItfName, wcslen(pData->szClassItfName)+1, pData->szClassItfName);
- }
- else
- {
- pNew->szClassItfName = NULL;
- }
-
- // Return the new entry.
- return pNew;
-} // ImpTlbEventInfo* CImpTlbEventInfoMap::Add()
-
-// EOF =======================================================================
diff --git a/src/md/enc/liteweightstgdbrw.cpp b/src/md/enc/liteweightstgdbrw.cpp
index 12779f59c0..9bd923c931 100644
--- a/src/md/enc/liteweightstgdbrw.cpp
+++ b/src/md/enc/liteweightstgdbrw.cpp
@@ -339,12 +339,7 @@ HRESULT CLiteWeightStgdbRW::OpenForRead(
// If we're taking ownership of this memory.....
if (IsOfTakeOwnership(dwFlags))
{
-#ifdef FEATURE_METADATA_STANDALONE_WINRT_RO
- // Shared memory uses ole32.dll - we cannot depend on it in the standalone WinRT Read-Only DLL
- IfFailGo(E_INVALIDARG);
-#else
dmOpenFlags = (DBPROPMODE)(dmOpenFlags | DBPROP_TMODEF_SHAREDMEM);
-#endif //!FEATURE_METADATA_STANDALONE_WINRT_RO
}
#ifdef FEATURE_METADATA_LOAD_TRUSTED_IMAGES
if (IsOfTrustedImage(dwFlags))
@@ -1251,28 +1246,5 @@ BOOL
CLiteWeightStgdbRW::IsValidFileNameLength(
const WCHAR * wszFileName)
{
-#ifdef FEATURE_CORECLR
return TRUE;
-#else
- static const WCHAR const_wszLongPathPrefix[] = W("\\\\?\\");
-
- if (wszFileName == NULL)
- {
- return TRUE;
- }
- size_t cchFileName = wcslen(wszFileName);
- if (cchFileName < _MAX_PATH)
- {
- return TRUE;
- }
- if (SString::_wcsnicmp(wszFileName, const_wszLongPathPrefix, _countof(const_wszLongPathPrefix) - 1) != 0)
- { // Path does not have long path prefix \\?\ (as required by CreateFile API)
- return FALSE;
- }
- if (cchFileName < 32767)
- { // Limit for the long path length as defined in CreateFile API
- return TRUE;
- }
- return FALSE;
-#endif
} // CLiteWeightStgdbRW::IsValidFileNameLength
diff --git a/src/md/enc/metamodelenc.cpp b/src/md/enc/metamodelenc.cpp
index 4d972827ca..7460d580dc 100644
--- a/src/md/enc/metamodelenc.cpp
+++ b/src/md/enc/metamodelenc.cpp
@@ -263,18 +263,6 @@ CMiniMdRW::ApplyDelta(
return E_INVALIDARG;
}
-#ifndef FEATURE_CORECLR
- // Verify that the delta is based on the base.
- IfFailGo(mdDelta.getEncBaseIdOfModule(pModDelta, &GuidDelta));
- IfFailGo(getEncBaseIdOfModule(pModBase,&GuidBase));
- if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_DeltaCheck) &&
- CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_UseMinimalDeltas) &&
- (GuidDelta != GuidBase))
- {
- _ASSERTE(!"The Delta MetaData is based on a different generation than the current MetaData.");
- return E_INVALIDARG;
- }
-#endif //!FEATURE_CORECLR
// Let the other md prepare for sparse records.
IfFailGo(mdDelta.StartENCMap());
@@ -390,19 +378,6 @@ ErrExit:
HRESULT hrReturn = hr;
IfFailRet(mdDelta.EndENCMap());
-#ifndef FEATURE_CORECLR
- if (SUCCEEDED(hrReturn) &&
- CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_DeltaCheck) &&
- CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_UseMinimalDeltas))
- {
- GUID GuidNewBase;
-
- // We'll use the delta's 'delta guid' for our new base guid
- IfFailRet(mdDelta.getEncIdOfModule(pModDelta, &GuidNewBase));
-
- IfFailRet(PutGuid(TBL_Module, ModuleRec::COL_EncBaseId, pModBase, GuidNewBase));
- }
-#endif //!FEATURE_CORECLR
return hrReturn;
} // CMiniMdRW::ApplyDelta
diff --git a/src/md/enc/metamodelrw.cpp b/src/md/enc/metamodelrw.cpp
index f9002b6fa9..6a3bc327ef 100644
--- a/src/md/enc/metamodelrw.cpp
+++ b/src/md/enc/metamodelrw.cpp
@@ -4317,11 +4317,6 @@ CMiniMdRW::SaveHotPoolsToStream(
UINT32 *pnPoolDirSize,
UINT32 *pnHeapsSavedSize)
{
-// @todo: Triton workaround: FEATURE_METADATA_STANDALNE_WINRT_RO is supposed to disable FEATURE_PREJIT - remove this #if once we figure out how to get that working in the CoreClr build.
-#ifdef FEATURE_METADATA_STANDALONE_WINRT_RO
- _ASSERTE(!"SaveHotPoolsToStream: This method not supported in RoMetadata.dll");
- return E_NOTIMPL;
-#else // FEATURE_METADATA_STANDALONE_WINRT_RO
HRESULT hr = S_OK;
UINT32 rgHeapSavedSize[MDPoolCount] = { 0, 0, 0, 0 };
@@ -4393,7 +4388,6 @@ CMiniMdRW::SaveHotPoolsToStream(
}
return S_OK;
-#endif //FEATURE_METADATA_STANDALONE_WINRT_RO
} // CMiniMdRW::SaveHotPoolsToStream
// write hot data of specific blob
@@ -4406,11 +4400,6 @@ CMiniMdRW::SaveHotPoolToStream(
MetaData::HotHeapWriter *pHotHeapWriter,
UINT32 *pnSavedSize)
{
-// @todo: Triton workaround: FEATURE_METADATA_STANDALNE_WINRT_RO is supposed to disable FEATURE_PREJIT - remove this #if once we figure out how to get that working in the CoreClr build.
-#ifdef FEATURE_METADATA_STANDALONE_WINRT_RO
- _ASSERTE(!"SaveHotPoolToStream: This method not supported in RoMetadata.dll");
- return E_NOTIMPL;
-#else //FEATURE_METADATA_STANDALONE_WINRT_RO
_ASSERTE(pProfileData != NULL);
@@ -4435,7 +4424,6 @@ CMiniMdRW::SaveHotPoolToStream(
}
return S_OK;
-#endif // FEATURE_METADATA_STANDALONE_WINRT_RO
} // CMiniMdRW::SaveHotPoolToStream
#endif //FEATURE_PREJIT
@@ -8228,19 +8216,6 @@ CMiniMdRW::ResetENCLog()
// Get the module record.
IfFailGo(GetModuleRecord(1, &pMod));
-#ifndef FEATURE_CORECLR
- if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_UseMinimalDeltas))
- { // Update the ENC Guids
- GUID encid;
- // Copy EncId as BaseId.
- ULONG uVal = GetCol(TBL_Module, ModuleRec::COL_EncId, pMod);
- IfFailGo(PutCol(TBL_Module, ModuleRec::COL_EncBaseId, pMod, uVal));
-
- // Allocate a new GUID for EncId.
- IfFailGo(CoCreateGuid(&encid));
- IfFailGo(PutGuid(TBL_Module, ModuleRec::COL_EncId, pMod, encid));
- }
-#endif //!FEATURE_CORECLR
// Reset the pool deltas
m_StringHeap.StartNewEnCSession();
diff --git a/src/md/enc/rwutil.cpp b/src/md/enc/rwutil.cpp
index 874d972716..a00eddb3f1 100644
--- a/src/md/enc/rwutil.cpp
+++ b/src/md/enc/rwutil.cpp
@@ -952,149 +952,6 @@ ErrExit:
-
-//*********************************************************************************************************
-//
-// Merge Token manager's constructor
-//
-//*********************************************************************************************************
-MergeTokenManager::MergeTokenManager(MDTOKENMAP *pTkMapList, IUnknown *pHandler)
-{
- m_cRef = 1;
- m_pTkMapList = pTkMapList;
- m_pDefaultHostRemap = NULL;
- if (pHandler)
- pHandler->QueryInterface(IID_IMapToken, (void **) &m_pDefaultHostRemap);
-} // TokenManager::TokenManager()
-
-
-
-//*********************************************************************************************************
-//
-// Merge Token manager's destructor
-//
-//*********************************************************************************************************
-MergeTokenManager::~MergeTokenManager()
-{
- if (m_pDefaultHostRemap)
- m_pDefaultHostRemap->Release();
-} // TokenManager::~TokenManager()
-
-
-
-
-ULONG MergeTokenManager::AddRef()
-{
- return InterlockedIncrement(&m_cRef);
-} // TokenManager::AddRef()
-
-
-
-ULONG MergeTokenManager::Release()
-{
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (!cRef)
- delete this;
- return (cRef);
-} // TokenManager::Release()
-
-
-HRESULT MergeTokenManager::QueryInterface(REFIID riid, void **ppUnk)
-{
- if (ppUnk == NULL)
- return E_INVALIDARG;
-
- if (IsEqualIID(riid, IID_IMapToken))
- {
- //*ppUnk = (IUnknown *) (IMapToken *) this;
- // it should return the accurate type requested,
- // if IUnknown is returned, it will finally converted to IMapToken*
- *ppUnk = (IMapToken *) this;
- }
- else if (IsEqualIID(riid, IID_IUnknown))
- {
- // add query handling for IUnknown
- // this upcasting (converting a derived-class
- // reference or pointer to a base-class) is safe
- *ppUnk = (IUnknown *) this;
- }
- else
- {
- *ppUnk = NULL;
- return (E_NOINTERFACE);
- }
-
- AddRef();
- return (S_OK);
-} // TokenManager::QueryInterface
-
-
-
-//*********************************************************************************************************
-//
-// Token manager keep tracks a list of tokenmaps. Each tokenmap corresponding
-// to an imported scope. Note that with this, we do have problem in how to
-// tell linker regarding the token movement when the token is added by Define
-// rather than merge. This should be fixed with new merge implementation.
-// The tkImp is the old tokens in the emit scope, tkEmit is the new token in the
-// emit scope. We need to find the token from an import scope that is resolved
-// to the tkImp. We then need to tell linker about this token movement.
-// If we don't find any import scope which generates the tkImp token, that is
-// this tkImp is generated by calling DefinXXX directly on the final merged scope.
-// Then we use the default host remap to send the notification.
-//
-//*********************************************************************************************************
-HRESULT MergeTokenManager::Map(mdToken tkImp, mdToken tkEmit)
-{
- HRESULT hr = NOERROR;
- MDTOKENMAP *pTkMapList = m_pTkMapList;
- bool fFoundInImport = false;
- int iPosition;
- TOKENREC *pRec;
-
- _ASSERTE(m_pTkMapList);
- while ( pTkMapList )
- {
- // FindWithToToken will return the first match with the To token.
- // pTkMapList is sorted with To token. It might contain several From tokens
- // that map to the To token due to ref to def optimiation. Make sure that
- // all notification is sent to all of these From tokens.
- //
- if ( pTkMapList->FindWithToToken(tkImp, &iPosition) )
- {
- // make sure that we don't walk over the last entry
- while (iPosition < pTkMapList->Count())
- {
- pRec = pTkMapList->Get(iPosition);
- if (pRec->m_tkTo != tkImp)
- {
- // we are done!
- break;
- }
-
- // more matching record...
- fFoundInImport = true;
- if (pTkMapList->m_pMap)
- hr = pTkMapList->m_pMap->Map(pRec->m_tkFrom, tkEmit);
- _ASSERTE(SUCCEEDED(hr));
- IfFailGo( hr );
- iPosition++;
- }
- }
- pTkMapList = pTkMapList->m_pNextMap;
- }
-
- if (fFoundInImport == false && m_pDefaultHostRemap)
- {
- // use the default remap to send the notification
- IfFailGo( m_pDefaultHostRemap->Map(tkImp, tkEmit) );
- }
-ErrExit:
- return hr;
-}
-
-
-
//*********************************************************************************************************
//
// CMapToken's constructor
diff --git a/src/md/enc/stgio.cpp b/src/md/enc/stgio.cpp
index 27d5ff2c5d..9dea3cb689 100644
--- a/src/md/enc/stgio.cpp
+++ b/src/md/enc/stgio.cpp
@@ -42,17 +42,10 @@
#include "pedecoder.inl"
//********** Types. ***********************************************************
-#if !defined(FEATURE_METADATA_STANDALONE_WINRT_RO)
#define SMALL_ALLOC_MAP_SIZE (64 * 1024) // 64 kb is the minimum size of virtual
// memory you can allocate, so anything
// less is a waste of VM resources.
-#else //FEATURE_METADATA_STANDALONE_WINRT_RO
-// RoMetadata.dll is required to call CreateFileMapping on all WinMD files (even small ones) to use
-// Code Intergrity checks on Win8 - see code:#EnableCodeIntegrity
-#define SMALL_ALLOC_MAP_SIZE 0
-
-#endif //FEATURE_METADATA_STANDALONE_WINRT_RO
#define MIN_WRITE_CACHE_BYTES (16 * 1024) // 16 kb for a write back cache
@@ -154,7 +147,6 @@ HRESULT StgIO::Open( // Return code.
m_pData = (void *) pbBuff;
m_cbData = cbBuff;
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
// All access to data will be by memory provided.
if ((fFlags & DBPROP_TMODEF_SHAREDMEM) == DBPROP_TMODEF_SHAREDMEM)
{
@@ -163,7 +155,6 @@ HRESULT StgIO::Open( // Return code.
m_iType = STGIO_SHAREDMEM;
}
else
-#endif //!FEATURE_METADATA_STANDALONE_WINRT_RO
{
m_iType = STGIO_MEM;
}
@@ -359,7 +350,6 @@ void StgIO::Close()
{
switch (m_iType)
{
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
// Free any allocated memory.
case STGIO_SHAREDMEM:
if (m_pBaseData != NULL)
@@ -368,7 +358,6 @@ void StgIO::Close()
m_pBaseData = NULL;
break;
}
-#endif //!FEATURE_METADATA_STANDALONE_WINRT_RO
case STGIO_MEM:
case STGIO_HFILEMEM:
@@ -538,9 +527,7 @@ HRESULT StgIO::Read( // Return code.
// Simply copy the data from our data.
case STGIO_MEM:
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
case STGIO_SHAREDMEM:
-#endif
case STGIO_HFILEMEM:
{
_ASSERTE(m_pData && m_cbData);
@@ -686,9 +673,7 @@ HRESULT StgIO::Seek( // New offset.
break;
case STGIO_MEM:
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
case STGIO_SHAREDMEM:
-#endif
case STGIO_HFILEMEM:
case STGIO_HMODULE:
{
@@ -770,9 +755,7 @@ HRESULT StgIO::MapFileToMem( // Return code.
if (IsBackingStore() ||
IsMemoryMapped() ||
(m_iType == STGIO_MEM) ||
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
(m_iType == STGIO_SHAREDMEM) ||
-#endif
(m_iType == STGIO_HFILEMEM))
{
ptr = m_pData;
@@ -854,24 +837,13 @@ HRESULT StgIO::MapFileToMem( // Return code.
_ASSERTE(m_hMapping == 0);
DWORD dwProtectionFlags = PAGE_READONLY;
-#ifdef FEATURE_METADATA_STANDALONE_WINRT_RO
- //#EnableCodeIntegrity
- // RoMetadata.dll is required to always map (WinMD) files with SEC_IMAGE to enable Code Integrity checkes on Win8
- // Note: MidlRtMd.dll cannot do the same, because it runs on pre-Win8 OS versions where SEC_IMAGE-mapping will likely
- // refuse WinMD files (they are Win8+ only in PE headers)
- dwProtectionFlags |= SEC_IMAGE;
-#endif
if ((m_hMapping = WszCreateFileMapping(m_hFile, pAttributes, dwProtectionFlags,
0, 0, nullptr)) == 0)
{
return (MapFileError(GetLastError()));
}
-#ifdef FEATURE_METADATA_STANDALONE_WINRT_RO
- m_mtMappedType = MTYPE_IMAGE;
-#else // FEATURE_METADATA_STANDALONE_WINRT_RO
m_mtMappedType = MTYPE_FLAT;
-#endif // FEATURE_METADATA_STANDALONE_WINRT_RO
// Check to see if the memory already exists, in which case we have
// no guarantees it is the right piece of data.
if (GetLastError() == ERROR_ALREADY_EXISTS)
@@ -958,7 +930,6 @@ ErrExit:
HRESULT StgIO::ReleaseMappingObject() // Return code.
{
// Check type first.
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
if (m_iType != STGIO_SHAREDMEM)
{
_ASSERTE(FALSE);
@@ -982,7 +953,6 @@ HRESULT StgIO::ReleaseMappingObject() // Return code.
VERIFY(CloseHandle(m_hMapping));
m_hMapping = 0;
}
-#endif //!FEATURE_METADATA_STANDALONE_WINRT_RO
return S_OK;
}
@@ -998,7 +968,6 @@ HRESULT StgIO::SetBaseRange( // Return code.
void *pbStart, // Start of file data.
ULONG cbSize) // How big is the range.
{
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
if (m_iType == STGIO_SHAREDMEM)
{
// The base range must be inside of the current range.
@@ -1006,7 +975,6 @@ HRESULT StgIO::SetBaseRange( // Return code.
_ASSERTE(((LONG_PTR) pbStart >= (LONG_PTR) m_pBaseData));
_ASSERTE(((LONG_PTR) pbStart + cbSize <= (LONG_PTR) m_pBaseData + m_cbData));
}
-#endif //!FEATURE_METADATA_STANDALONE_WINRT_RO
// Save the base range per user request.
m_pData = pbStart;
@@ -1117,9 +1085,7 @@ HRESULT StgIO::GetPtrForMem( // Return code.
// Memory version or memory mapped file work the same way.
else if (IsMemoryMapped() ||
(m_iType == STGIO_MEM) ||
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
(m_iType == STGIO_SHAREDMEM) ||
-#endif
(m_iType == STGIO_HFILEMEM))
{
if (!(cbStart <= m_cbData))
@@ -1245,9 +1211,7 @@ HRESULT StgIO::WriteToDisk( // Return code.
// We cannot write to fixed read/only memory or LoadLibrary module.
case STGIO_HMODULE:
case STGIO_MEM:
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
case STGIO_SHAREDMEM:
-#endif
_ASSERTE(0);
hr = BadError(E_UNEXPECTED);
break;
@@ -1384,9 +1348,7 @@ int StgIO::IsAlignedPtr(ULONG_PTR Value, int iAlignment)
void *ptrStart = NULL;
if ((m_iType == STGIO_STREAM) ||
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
(m_iType == STGIO_SHAREDMEM) ||
-#endif
(m_iType == STGIO_MEM))
{
return ((Value - (ULONG_PTR) m_pData) % iAlignment == 0);
diff --git a/src/md/enc/stgtiggerstorage.cpp b/src/md/enc/stgtiggerstorage.cpp
index 436b3d72e3..2c8420d02d 100644
--- a/src/md/enc/stgtiggerstorage.cpp
+++ b/src/md/enc/stgtiggerstorage.cpp
@@ -138,9 +138,6 @@ TiggerStorage::GetDefaultVersion(
if (g_pDefaultVersion == NULL)
{
-#ifdef FEATURE_METADATA_STANDALONE_WINRT
- g_pDefaultVersion = "";
-#else //!FEATURE_METADATA_STANDALONE_WINRT
#ifndef DACCESS_COMPILE
HRESULT hr;
@@ -170,7 +167,6 @@ TiggerStorage::GetDefaultVersion(
#else
DacNotImpl();
#endif //DACCESS_COMPILE
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
}
*ppVersion = g_pDefaultVersion;
diff --git a/src/md/enc/wks/CMakeLists.txt b/src/md/enc/wks/CMakeLists.txt
index df7664187d..2c0a2b1af5 100644
--- a/src/md/enc/wks/CMakeLists.txt
+++ b/src/md/enc/wks/CMakeLists.txt
@@ -1,4 +1,6 @@
include(../../md_wks.cmake)
+add_definitions(-DFEATURE_METADATA_EMIT_ALL)
+
add_precompiled_header(stdafx.h ../stdafx.cpp MDRUNTIMERW_SOURCES)
add_library_clr(mdruntimerw_wks ${MDRUNTIMERW_SOURCES})
diff --git a/src/md/hotdata/hotdataformat.h b/src/md/hotdata/hotdataformat.h
index 0823010611..3431d18deb 100644
--- a/src/md/hotdata/hotdataformat.h
+++ b/src/md/hotdata/hotdataformat.h
@@ -35,7 +35,7 @@ namespace MetaData
// #HotMetaData
// To help with startup time, we create a section of metadata that is only that meta-data that was touched
// durring IBC profiling. Given an offset into a pool this checks if we have any hot data associated with
-// it. If we do we return a poitner to it, otherwse we return NULL.
+// it. If we do we return a pointer to it, otherwse we return NULL.
#include <pshpack1.h>
diff --git a/src/md/inc/assemblymdinternaldisp.h b/src/md/inc/assemblymdinternaldisp.h
index 91b7d2cc29..8e8017ee9b 100644
--- a/src/md/inc/assemblymdinternaldisp.h
+++ b/src/md/inc/assemblymdinternaldisp.h
@@ -14,710 +14,5 @@
#include "../runtime/mdinternalro.h"
-#ifdef FEATURE_FUSION
-
-#include "fusionpriv.h"
-
-struct CORCOMPILE_VERSION_INFO;
-struct CORCOMPILE_DEPENDENCY;
-
-//*****************************************************************************
-// This class can support the IMetaDataAssemblyImport and some funcationalities
-// of IMetaDataImport on the internal import interface (IMDInternalImport).
-//*****************************************************************************
-class AssemblyMDInternalImport :
- public IMetaDataAssemblyImport,
- public IMetaDataImport2,
-#ifdef FEATURE_PREJIT
- public IGetIMDInternalImport,
-#endif //FEATURE_PREJIT
- public ISNAssemblySignature
-#ifdef FEATURE_PREJIT
- , public INativeImageInstallInfo
-#endif // FEATURE_PREJIT
-{
-public:
- AssemblyMDInternalImport(IMDInternalImport *pMDInternalImport);
- ~AssemblyMDInternalImport();
-
- // *** IUnknown methods ***
- STDMETHODIMP QueryInterface(REFIID riid, void** ppUnk);
- STDMETHODIMP_(ULONG) AddRef(void);
- STDMETHODIMP_(ULONG) Release(void);
-
- // *** IMetaDataAssemblyImport methods ***
- STDMETHODIMP GetAssemblyProps ( // S_OK or error.
- mdAssembly mda, // [IN] The Assembly for which to get the properties.
- const void **ppbPublicKey, // [OUT] Pointer to the public key.
- ULONG *pcbPublicKey, // [OUT] Count of bytes in the public key.
- ULONG *pulHashAlgId, // [OUT] Hash Algorithm.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- ASSEMBLYMETADATA *pMetaData, // [OUT] Assembly MetaData.
- DWORD *pdwAssemblyFlags); // [OUT] Flags.
-
- STDMETHODIMP GetAssemblyRefProps ( // S_OK or error.
- mdAssemblyRef mdar, // [IN] The AssemblyRef for which to get the properties.
- const void **ppbPublicKeyOrToken, // [OUT] Pointer to the public key or token.
- ULONG *pcbPublicKeyOrToken, // [OUT] Count of bytes in the public key or token.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- ASSEMBLYMETADATA *pMetaData, // [OUT] Assembly MetaData.
- const void **ppbHashValue, // [OUT] Hash blob.
- ULONG *pcbHashValue, // [OUT] Count of bytes in the hash blob.
- DWORD *pdwAssemblyRefFlags); // [OUT] Flags.
-
- STDMETHODIMP GetFileProps ( // S_OK or error.
- mdFile mdf, // [IN] The File for which to get the properties.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- const void **ppbHashValue, // [OUT] Pointer to the Hash Value Blob.
- ULONG *pcbHashValue, // [OUT] Count of bytes in the Hash Value Blob.
- DWORD *pdwFileFlags); // [OUT] Flags.
-
- STDMETHODIMP GetExportedTypeProps ( // S_OK or error.
- mdExportedType mdct, // [IN] The ExportedType for which to get the properties.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- mdToken *ptkImplementation, // [OUT] mdFile or mdAssemblyRef or mdExportedType.
- mdTypeDef *ptkTypeDef, // [OUT] TypeDef token within the file.
- DWORD *pdwExportedTypeFlags); // [OUT] Flags.
-
- STDMETHODIMP GetManifestResourceProps ( // S_OK or error.
- mdManifestResource mdmr, // [IN] The ManifestResource for which to get the properties.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- mdToken *ptkImplementation, // [OUT] mdFile or mdAssemblyRef that provides the ManifestResource.
- DWORD *pdwOffset, // [OUT] Offset to the beginning of the resource within the file.
- DWORD *pdwResourceFlags); // [OUT] Flags.
-
- STDMETHODIMP EnumAssemblyRefs ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdAssemblyRef rAssemblyRefs[], // [OUT] Put AssemblyRefs here.
- ULONG cMax, // [IN] Max AssemblyRefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHODIMP EnumFiles ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdFile rFiles[], // [OUT] Put Files here.
- ULONG cMax, // [IN] Max Files to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHODIMP EnumExportedTypes ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdExportedType rExportedTypes[], // [OUT] Put ExportedTypes here.
- ULONG cMax, // [IN] Max ExportedTypes to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHODIMP EnumManifestResources ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdManifestResource rManifestResources[], // [OUT] Put ManifestResources here.
- ULONG cMax, // [IN] Max Resources to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHODIMP GetAssemblyFromScope ( // S_OK or error
- mdAssembly *ptkAssembly); // [OUT] Put token here.
-
- STDMETHODIMP FindExportedTypeByName ( // S_OK or error
- LPCWSTR szName, // [IN] Name of the ExportedType.
- mdToken mdtExportedType, // [IN] ExportedType for the enclosing class.
- mdExportedType *ptkExportedType); // [OUT] Put the ExportedType token here.
-
- STDMETHODIMP FindManifestResourceByName ( // S_OK or error
- LPCWSTR szName, // [IN] Name of the ManifestResource.
- mdManifestResource *ptkManifestResource); // [OUT] Put the ManifestResource token here.
-
- STDMETHOD_(void, CloseEnum)(
- HCORENUM hEnum); // Enum to be closed.
-
- STDMETHODIMP FindAssembliesByName ( // S_OK or error
- LPCWSTR szAppBase, // [IN] optional - can be NULL
- LPCWSTR szPrivateBin, // [IN] optional - can be NULL
- LPCWSTR szAssemblyName, // [IN] required - this is the assembly you are requesting
- IUnknown *ppIUnk[], // [OUT] put IMetaDataAssemblyImport pointers here
- ULONG cMax, // [IN] The max number to put
- ULONG *pcAssemblies); // [OUT] The number of assemblies returned.
-
- // *** IMetaDataImport methods ***
- STDMETHOD(CountEnum)(HCORENUM hEnum, ULONG *pulCount);
- STDMETHOD(ResetEnum)(HCORENUM hEnum, ULONG ulPos);
- STDMETHOD(EnumTypeDefs)(HCORENUM *phEnum, mdTypeDef rTypeDefs[],
- ULONG cMax, ULONG *pcTypeDefs);
- STDMETHOD(EnumInterfaceImpls)(HCORENUM *phEnum, mdTypeDef td,
- mdInterfaceImpl rImpls[], ULONG cMax,
- ULONG* pcImpls);
- STDMETHOD(EnumTypeRefs)(HCORENUM *phEnum, mdTypeRef rTypeRefs[],
- ULONG cMax, ULONG* pcTypeRefs);
-
- STDMETHOD(FindTypeDefByName)( // S_OK or error.
- LPCWSTR szTypeDef, // [IN] Name of the Type.
- mdToken tkEnclosingClass, // [IN] TypeDef/TypeRef for Enclosing class.
- mdTypeDef *ptd); // [OUT] Put the TypeDef token here.
-
- STDMETHOD(GetScopeProps)(
- __out_ecount_part_opt(cchName, *pchName)
- LPWSTR wszName, // [OUT] Put the name here.
- ULONG cchName, // [IN] Size of name buffer in wide chars.
- ULONG * pchName, // [OUT] Put size of name (wide chars) here.
- GUID * pMvid); // [OUT, OPTIONAL] Put MVID here.
-
- STDMETHOD(GetModuleFromScope)( // S_OK.
- mdModule *pmd); // [OUT] Put mdModule token here.
-
- STDMETHOD(GetTypeDefProps)(
- mdTypeDef td, // [IN] TypeDef token for inquiry.
- __out_ecount_part_opt(cchTypeDef, *pchTypeDef)
- LPWSTR wszTypeDef, // [OUT] Put name here.
- ULONG cchTypeDef, // [IN] size of name buffer in wide chars.
- ULONG * pchTypeDef, // [OUT] put size of name (wide chars) here.
- DWORD * pdwTypeDefFlags, // [OUT] Put flags here.
- mdToken * ptkExtends); // [OUT] Put base class TypeDef/TypeRef here.
-
- STDMETHOD(GetInterfaceImplProps)( // S_OK or error.
- mdInterfaceImpl iiImpl, // [IN] InterfaceImpl token.
- mdTypeDef *pClass, // [OUT] Put implementing class token here.
- mdToken *ptkIface); // [OUT] Put implemented interface token here.
-
- STDMETHOD(GetTypeRefProps)(
- mdTypeRef tr, // [IN] TypeRef token.
- mdToken * ptkResolutionScope, // [OUT] Resolution scope, ModuleRef or AssemblyRef.
- __out_ecount_part_opt(cchName, *pchName)
- LPWSTR wszName, // [OUT] Name of the TypeRef.
- ULONG cchName, // [IN] Size of buffer.
- ULONG * pchName); // [OUT] Size of Name.
-
- STDMETHOD(ResolveTypeRef)(mdTypeRef tr, REFIID riid, IUnknown **ppIScope, mdTypeDef *ptd);
-
- STDMETHOD(EnumMembers)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- mdToken rMembers[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumMembersWithName)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- LPCWSTR szName, // [IN] Limit results to those with this name.
- mdToken rMembers[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumMethods)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- mdMethodDef rMethods[], // [OUT] Put MethodDefs here.
- ULONG cMax, // [IN] Max MethodDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumMethodsWithName)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- LPCWSTR szName, // [IN] Limit results to those with this name.
- mdMethodDef rMethods[], // [OU] Put MethodDefs here.
- ULONG cMax, // [IN] Max MethodDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumFields)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- mdFieldDef rFields[], // [OUT] Put FieldDefs here.
- ULONG cMax, // [IN] Max FieldDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumFieldsWithName)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- LPCWSTR szName, // [IN] Limit results to those with this name.
- mdFieldDef rFields[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
-
- STDMETHOD(EnumParams)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdMethodDef mb, // [IN] MethodDef to scope the enumeration.
- mdParamDef rParams[], // [OUT] Put ParamDefs here.
- ULONG cMax, // [IN] Max ParamDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumMemberRefs)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tkParent, // [IN] Parent token to scope the enumeration.
- mdMemberRef rMemberRefs[], // [OUT] Put MemberRefs here.
- ULONG cMax, // [IN] Max MemberRefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumMethodImpls)( // S_OK, S_FALSE, or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef td, // [IN] TypeDef to scope the enumeration.
- mdToken rMethodBody[], // [OUT] Put Method Body tokens here.
- mdToken rMethodDecl[], // [OUT] Put Method Declaration tokens here.
- ULONG cMax, // [IN] Max tokens to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumPermissionSets)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tk, // [IN] if !NIL, token to scope the enumeration.
- DWORD dwActions, // [IN] if !0, return only these actions.
- mdPermission rPermission[], // [OUT] Put Permissions here.
- ULONG cMax, // [IN] Max Permissions to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(FindMember)(
- mdTypeDef td, // [IN] given typedef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdToken *pmb); // [OUT] matching memberdef
-
- STDMETHOD(FindMethod)(
- mdTypeDef td, // [IN] given typedef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdMethodDef *pmb); // [OUT] matching memberdef
-
- STDMETHOD(FindField)(
- mdTypeDef td, // [IN] given typedef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdFieldDef *pmb); // [OUT] matching memberdef
-
- STDMETHOD(FindMemberRef)(
- mdTypeRef td, // [IN] given typeRef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdMemberRef *pmr); // [OUT] matching memberref
-
- STDMETHOD (GetMethodProps)(
- mdMethodDef mb, // The method for which to get props.
- mdTypeDef * pClass, // Put method's class here.
- __out_ecount_part_opt(cchMethod, *pchMethod)
- LPWSTR wszMethod, // Put method's name here.
- ULONG cchMethod, // Size of szMethod buffer in wide chars.
- ULONG * pchMethod, // Put actual size here.
- DWORD * pdwAttr, // Put flags here.
- PCCOR_SIGNATURE * ppvSigBlob, // [OUT] point to the blob value of meta data
- ULONG * pcbSigBlob, // [OUT] actual size of signature blob
- ULONG * pulCodeRVA, // [OUT] codeRVA
- DWORD * pdwImplFlags); // [OUT] Impl. Flags
-
- STDMETHOD(GetMemberRefProps)(
- mdMemberRef mr, // [IN] given memberref
- mdToken * ptk, // [OUT] Put classref or classdef here.
- __out_ecount_part_opt(cchMember, *pchMember)
- LPWSTR wszMember, // [OUT] buffer to fill for member's name
- ULONG cchMember, // [IN] the count of char of szMember
- ULONG * pchMember, // [OUT] actual count of char in member name
- PCCOR_SIGNATURE * ppvSigBlob, // [OUT] point to meta data blob value
- ULONG * pbSig); // [OUT] actual size of signature blob
-
- STDMETHOD(EnumProperties)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef td, // [IN] TypeDef to scope the enumeration.
- mdProperty rProperties[], // [OUT] Put Properties here.
- ULONG cMax, // [IN] Max properties to put.
- ULONG *pcProperties); // [OUT] Put # put here.
-
- STDMETHOD(EnumEvents)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef td, // [IN] TypeDef to scope the enumeration.
- mdEvent rEvents[], // [OUT] Put events here.
- ULONG cMax, // [IN] Max events to put.
- ULONG *pcEvents); // [OUT] Put # put here.
-
- STDMETHOD(GetEventProps)( // S_OK, S_FALSE, or error.
- mdEvent ev, // [IN] event token
- mdTypeDef *pClass, // [OUT] typedef containing the event declarion.
- LPCWSTR szEvent, // [OUT] Event name
- ULONG cchEvent, // [IN] the count of wchar of szEvent
- ULONG *pchEvent, // [OUT] actual count of wchar for event's name
- DWORD *pdwEventFlags, // [OUT] Event flags.
- mdToken *ptkEventType, // [OUT] EventType class
- mdMethodDef *pmdAddOn, // [OUT] AddOn method of the event
- mdMethodDef *pmdRemoveOn, // [OUT] RemoveOn method of the event
- mdMethodDef *pmdFire, // [OUT] Fire method of the event
- mdMethodDef rmdOtherMethod[], // [OUT] other method of the event
- ULONG cMax, // [IN] size of rmdOtherMethod
- ULONG *pcOtherMethod); // [OUT] total number of other method of this event
-
- STDMETHOD(EnumMethodSemantics)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdMethodDef mb, // [IN] MethodDef to scope the enumeration.
- mdToken rEventProp[], // [OUT] Put Event/Property here.
- ULONG cMax, // [IN] Max properties to put.
- ULONG *pcEventProp); // [OUT] Put # put here.
-
- STDMETHOD(GetMethodSemantics)( // S_OK, S_FALSE, or error.
- mdMethodDef mb, // [IN] method token
- mdToken tkEventProp, // [IN] event/property token.
- DWORD *pdwSemanticsFlags); // [OUT] the role flags for the method/propevent pair
-
- STDMETHOD(GetClassLayout) (
- mdTypeDef td, // [IN] give typedef
- DWORD *pdwPackSize, // [OUT] 1, 2, 4, 8, or 16
- COR_FIELD_OFFSET rFieldOffset[], // [OUT] field offset array
- ULONG cMax, // [IN] size of the array
- ULONG *pcFieldOffset, // [OUT] needed array size
- ULONG *pulClassSize); // [OUT] the size of the class
-
- STDMETHOD(GetFieldMarshal) (
- mdToken tk, // [IN] given a field's memberdef
- PCCOR_SIGNATURE *ppvNativeType, // [OUT] native type of this field
- ULONG *pcbNativeType); // [OUT] the count of bytes of *ppvNativeType
-
- STDMETHOD(GetRVA)( // S_OK or error.
- mdToken tk, // Member for which to set offset
- ULONG *pulCodeRVA, // The offset
- DWORD *pdwImplFlags); // the implementation flags
-
- STDMETHOD(GetPermissionSetProps) (
- mdPermission pm, // [IN] the permission token.
- DWORD *pdwAction, // [OUT] CorDeclSecurity.
- void const **ppvPermission, // [OUT] permission blob.
- ULONG *pcbPermission); // [OUT] count of bytes of pvPermission.
-
- STDMETHOD(GetSigFromToken)( // S_OK or error.
- mdSignature mdSig, // [IN] Signature token.
- PCCOR_SIGNATURE *ppvSig, // [OUT] return pointer to token.
- ULONG *pcbSig); // [OUT] return size of signature.
-
- STDMETHOD(GetModuleRefProps)(
- mdModuleRef mur, // [IN] moduleref token.
- __out_ecount_part_opt(cchName, *pchName)
- LPWSTR wszName, // [OUT] buffer to fill with the moduleref name.
- ULONG cchName, // [IN] size of szName in wide characters.
- ULONG * pchName); // [OUT] actual count of characters in the name.
-
- STDMETHOD(EnumModuleRefs)( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] pointer to the enum.
- mdModuleRef rModuleRefs[], // [OUT] put modulerefs here.
- ULONG cmax, // [IN] max memberrefs to put.
- ULONG *pcModuleRefs); // [OUT] put # put here.
-
- STDMETHOD(GetTypeSpecFromToken)( // S_OK or error.
- mdTypeSpec typespec, // [IN] TypeSpec token.
- PCCOR_SIGNATURE *ppvSig, // [OUT] return pointer to TypeSpec signature
- ULONG *pcbSig); // [OUT] return size of signature.
-
- STDMETHOD(GetNameFromToken)( // <TODO>Not Recommended! May be removed!</TODO>
- mdToken tk, // [IN] Token to get name from. Must have a name.
- MDUTF8CSTR *pszUtf8NamePtr); // [OUT] Return pointer to UTF8 name in heap.
-
- STDMETHOD(EnumUnresolvedMethods)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken rMethods[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(GetUserString)(
- mdString stk, // [IN] String token.
- __out_ecount_part_opt(cchString, *pchString)
- LPWSTR wszString, // [OUT] Copy of string.
- ULONG cchString, // [IN] Max chars of room in szString.
- ULONG * pchString); // [OUT] How many chars in actual string.
-
- STDMETHOD(GetPinvokeMap)(
- mdToken tk, // [IN] FieldDef or MethodDef.
- DWORD * pdwMappingFlags, // [OUT] Flags used for mapping.
- __out_ecount_part_opt(cchImportName, *pchImportName)
- LPWSTR wszImportName, // [OUT] Import name.
- ULONG cchImportName, // [IN] Size of the name buffer.
- ULONG * pchImportName, // [OUT] Actual number of characters stored.
- mdModuleRef * pmrImportDLL); // [OUT] ModuleRef token for the target DLL.
-
- STDMETHOD(EnumSignatures)( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] pointer to the enum.
- mdSignature rSignatures[], // [OUT] put signatures here.
- ULONG cmax, // [IN] max signatures to put.
- ULONG *pcSignatures); // [OUT] put # put here.
-
- STDMETHOD(EnumTypeSpecs)( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] pointer to the enum.
- mdTypeSpec rTypeSpecs[], // [OUT] put TypeSpecs here.
- ULONG cmax, // [IN] max TypeSpecs to put.
- ULONG *pcTypeSpecs); // [OUT] put # put here.
-
- STDMETHOD(EnumUserStrings)( // S_OK or error.
- HCORENUM *phEnum, // [IN/OUT] pointer to the enum.
- mdString rStrings[], // [OUT] put Strings here.
- ULONG cmax, // [IN] max Strings to put.
- ULONG *pcStrings); // [OUT] put # put here.
-
- STDMETHOD(GetParamForMethodIndex)( // S_OK or error.
- mdMethodDef md, // [IN] Method token.
- ULONG ulParamSeq, // [IN] Parameter sequence.
- mdParamDef *ppd); // [IN] Put Param token here.
-
- STDMETHOD(EnumCustomAttributes)( // S_OK or error.
- HCORENUM *phEnum, // [IN, OUT] COR enumerator.
- mdToken tk, // [IN] Token to scope the enumeration, 0 for all.
- mdToken tkType, // [IN] Type of interest, 0 for all.
- mdCustomAttribute rCustomAttributes[], // [OUT] Put custom attribute tokens here.
- ULONG cMax, // [IN] Size of rCustomAttributes.
- ULONG *pcCustomAttributes); // [OUT, OPTIONAL] Put count of token values here.
-
- STDMETHOD(GetCustomAttributeProps)( // S_OK or error.
- mdCustomAttribute cv, // [IN] CustomAttribute token.
- mdToken *ptkObj, // [OUT, OPTIONAL] Put object token here.
- mdToken *ptkType, // [OUT, OPTIONAL] Put AttrType token here.
- void const **ppBlob, // [OUT, OPTIONAL] Put pointer to data here.
- ULONG *pcbSize); // [OUT, OPTIONAL] Put size of date here.
-
- STDMETHOD(FindTypeRef)(
- mdToken tkResolutionScope, // [IN] ModuleRef, AssemblyRef or TypeRef.
- LPCWSTR szName, // [IN] TypeRef Name.
- mdTypeRef *ptr); // [OUT] matching TypeRef.
-
- STDMETHOD(GetMemberProps)(
- mdToken mb, // The member for which to get props.
- mdTypeDef * pClass, // Put member's class here.
- __out_ecount_part_opt(cchMember, *pchMember)
- LPWSTR wszMember, // Put member's name here.
- ULONG cchMember, // Size of szMember buffer in wide chars.
- ULONG * pchMember, // Put actual size here
- DWORD * pdwAttr, // Put flags here.
- PCCOR_SIGNATURE * ppvSigBlob, // [OUT] point to the blob value of meta data
- ULONG * pcbSigBlob, // [OUT] actual size of signature blob
- ULONG * pulCodeRVA, // [OUT] codeRVA
- DWORD * pdwImplFlags, // [OUT] Impl. Flags
- DWORD * pdwCPlusTypeFlag, // [OUT] flag for value type. selected ELEMENT_TYPE_*
- UVCP_CONSTANT * ppValue, // [OUT] constant value
- ULONG * pcchValue); // [OUT] size of constant string in chars, 0 for non-strings.
-
- STDMETHOD(GetFieldProps)(
- mdFieldDef mb, // The field for which to get props.
- mdTypeDef * pClass, // Put field's class here.
- __out_ecount_part_opt(cchField, *pchField)
- LPWSTR szField, // Put field's name here.
- ULONG cchField, // Size of szField buffer in wide chars.
- ULONG * pchField, // Put actual size here.
- DWORD * pdwAttr, // Put flags here.
- PCCOR_SIGNATURE * ppvSigBlob, // [OUT] point to the blob value of meta data.
- ULONG * pcbSigBlob, // [OUT] actual size of signature blob.
- DWORD * pdwCPlusTypeFlag, // [OUT] flag for value type. selected ELEMENT_TYPE_*.
- UVCP_CONSTANT * ppValue, // [OUT] constant value.
- ULONG * pcchValue); // [OUT] size of constant string in chars, 0 for non-strings.
-
- STDMETHOD(GetPropertyProps)( // S_OK, S_FALSE, or error.
- mdProperty prop, // [IN] property token
- mdTypeDef *pClass, // [OUT] typedef containing the property declarion.
- LPCWSTR szProperty, // [OUT] Property name
- ULONG cchProperty, // [IN] the count of wchar of szProperty
- ULONG *pchProperty, // [OUT] actual count of wchar for property name
- DWORD *pdwPropFlags, // [OUT] property flags.
- PCCOR_SIGNATURE *ppvSig, // [OUT] property type. pointing to meta data internal blob
- ULONG *pbSig, // [OUT] count of bytes in *ppvSig
- DWORD *pdwCPlusTypeFlag, // [OUT] flag for value type. selected ELEMENT_TYPE_*
- UVCP_CONSTANT *ppDefaultValue, // [OUT] constant value
- ULONG *pcchDefaultValue, // [OUT] size of constant string in chars, 0 for non-strings.
- mdMethodDef *pmdSetter, // [OUT] setter method of the property
- mdMethodDef *pmdGetter, // [OUT] getter method of the property
- mdMethodDef rmdOtherMethod[], // [OUT] other method of the property
- ULONG cMax, // [IN] size of rmdOtherMethod
- ULONG *pcOtherMethod); // [OUT] total number of other method of this property
-
- STDMETHOD(GetParamProps)(
- mdParamDef tk, // [IN]The Parameter.
- mdMethodDef * pmd, // [OUT] Parent Method token.
- ULONG * pulSequence, // [OUT] Parameter sequence.
- __out_ecount_part_opt(cchName, *pchName)
- LPWSTR wszName, // [OUT] Put name here.
- ULONG cchName, // [OUT] Size of name buffer.
- ULONG * pchName, // [OUT] Put actual size of name here.
- DWORD * pdwAttr, // [OUT] Put flags here.
- DWORD * pdwCPlusTypeFlag, // [OUT] Flag for value type. selected ELEMENT_TYPE_*.
- UVCP_CONSTANT * ppValue, // [OUT] Constant value.
- ULONG * pcchValue); // [OUT] size of constant string in chars, 0 for non-strings.
-
- STDMETHOD(GetCustomAttributeByName)( // S_OK or error.
- mdToken tkObj, // [IN] Object with Custom Attribute.
- LPCWSTR szName, // [IN] Name of desired Custom Attribute.
- const void **ppData, // [OUT] Put pointer to data here.
- ULONG *pcbData); // [OUT] Put size of data here.
-
- STDMETHOD_(BOOL, IsValidToken)( // True or False.
- mdToken tk); // [IN] Given token.
-
- STDMETHOD(GetNestedClassProps)( // S_OK or error.
- mdTypeDef tdNestedClass, // [IN] NestedClass token.
- mdTypeDef *ptdEnclosingClass); // [OUT] EnclosingClass token.
-
- STDMETHOD(GetNativeCallConvFromSig)( // S_OK or error.
- void const *pvSig, // [IN] Pointer to signature.
- ULONG cbSig, // [IN] Count of signature bytes.
- ULONG *pCallConv); // [OUT] Put calling conv here (see CorPinvokemap).
-
- STDMETHOD(IsGlobal)( // S_OK or error.
- mdToken pd, // [IN] Type, Field, or Method token.
- int *pbGlobal); // [OUT] Put 1 if global, 0 otherwise.
-
-//*****************************************************************************
-// IMetaDataImport2 methods
-//*****************************************************************************
- STDMETHOD(GetMethodSpecProps)(
- mdMethodSpec mi, // [IN] The method instantiation
- mdToken *tkParent, // [OUT] MethodDef or MemberRef
- PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data
- ULONG *pcbSigBlob); // [OUT] actual size of signature blob
-
- STDMETHOD(GetGenericParamProps)(
- mdGenericParam gp, // [IN] GenericParam
- ULONG * pulParamSeq, // [OUT] Index of the type parameter
- DWORD * pdwParamFlags, // [OUT] Flags, for future use (e.g. variance)
- mdToken * ptOwner, // [OUT] Owner (TypeDef or MethodDef)
- DWORD * pdwReserved, // [OUT] For future use (e.g. non-type parameters)
- __out_ecount_part_opt(cchName, *pchName)
- LPWSTR wszName, // [OUT] Put name here
- ULONG cchName, // [IN] Size of buffer
- ULONG * pchName); // [OUT] Put size of name (wide chars) here.
-
- STDMETHOD(GetGenericParamConstraintProps)( // S_OK or error.
- mdGenericParamConstraint gpc, // [IN] GenericParamConstraint
- mdGenericParam *ptGenericParam, // [OUT] GenericParam that is constrained
- mdToken *ptkConstraintType); // [OUT] TypeDef/Ref/Spec constraint
-
- STDMETHOD(EnumGenericParams)( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tk, // [IN] TypeDef or MethodDef whose generic parameters are requested
- mdGenericParam rGenericParams[], // [OUT] Put GenericParams here.
- ULONG cMax, // [IN] Max GenericParams to put.
- ULONG *pcGenericParams); // [OUT] Put # put here.
-
- STDMETHOD(EnumGenericParamConstraints)( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdGenericParam tk, // [IN] GenericParam whose constraints are requested
- mdGenericParamConstraint rGenericParamConstraints[], // [OUT] Put GenericParamConstraints here.
- ULONG cMax, // [IN] Max GenericParamConstraints to put.
- ULONG *pcGenericParamConstraints); // [OUT] Put # put here.
-
- STDMETHOD(EnumMethodSpecs)(
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tk, // [IN] MethodDef or MemberRef whose MethodSpecs are requested
- mdMethodSpec rMethodSpecs[], // [OUT] Put MethodSpecs here.
- ULONG cMax, // [IN] Max tokens to put.
- ULONG *pcMethodSpecs); // [OUT] Put actual count here.
-
- STDMETHOD(GetPEKind)( // S_OK or error.
- DWORD* pdwPEKind, // [OUT] The kind of PE (0 - not a PE)
- DWORD* pdwMachine); // [OUT] Machine as defined in NT header
-
- STDMETHOD(GetVersionString)(
- __out_ecount_part_opt(ccBufSize, *pccBufSize)
- LPWSTR pwzBuf, // Put version string here.
- DWORD ccBufSize, // [in] Size of the buffer, in wide chars.
- DWORD * pccBufSize); // [out] Size of the version string, wide chars, including terminating nul.
-
-
- // *** ISNAssemblySignature methods ***
-
- STDMETHOD(GetSNAssemblySignature)( // S_OK or error.
- BYTE *pbSig, // [IN, OUT] Buffer to write signature
- DWORD *pcbSig); // [IN, OUT] Size of buffer, bytes written
-
-
-#ifdef FEATURE_PREJIT
- // *** IGetIMDInternalImport methods ***
-
- STDMETHOD(GetIMDInternalImport) (
- IMDInternalImport ** ppIMDInternalImport);
-
- // *** INativeImageInstallInfo ***
-
- STDMETHOD (GetSignature) (
- CORCOMPILE_NGEN_SIGNATURE * pNgenSign
- );
-
- STDMETHOD (GetVersionInfo) (
- CORCOMPILE_VERSION_INFO * pVersionInfo
- );
-
-
- STDMETHOD (GetILSignature) (
- CORCOMPILE_ASSEMBLY_SIGNATURE * pILSign
- );
-
- STDMETHOD (GetConfigMask) (
- DWORD * pConfigMask
- );
-
- STDMETHOD (EnumDependencies) (
- HCORENUM * phEnum,
- INativeImageDependency *rDeps[],
- ULONG cMax,
- DWORD * pdwCount
- );
-
- STDMETHOD (GetDependency) (
- const CORCOMPILE_NGEN_SIGNATURE *pcngenSign,
- CORCOMPILE_DEPENDENCY *pDep
- );
-
-
-#endif // FEATURE_PREJIT
-
- //------------ setters for privates -----------
- void SetHandle(HCORMODULE hHandle)
- {
- RuntimeAddRefHandle(hHandle);
- m_pHandle = hHandle;
- }
-
- void SetPEKind(DWORD dwPEKind)
- {
- m_dwPEKind = dwPEKind;
- }
-
- void SetMachine(DWORD dwMachine)
- {
- m_dwMachine = dwMachine;
- }
-
- void SetVersionString(const char* szVersionString)
- {
- m_szVersionString = szVersionString;
- }
-
- void SetBase(LPVOID base)
- {
- m_pBase = base;
- }
-
-#ifdef FEATURE_PREJIT
- void SetZapVersionInfo(CORCOMPILE_VERSION_INFO * info, CORCOMPILE_DEPENDENCY * pDeps, COUNT_T cDeps)
- {
- m_pZapVersionInfo = info;
- m_pZapDependencies = pDeps;
- m_cZapDependencies = cDeps;
- }
-#endif // FEATURE_PREJIT
-
-private:
- LONG m_cRef;
- HCORMODULE m_pHandle; // Handle to a cached PE image
- LPVOID m_pBase; // File mapping (if runtime is not inited)
-#ifdef FEATURE_PREJIT
- struct CORCOMPILE_VERSION_INFO * m_pZapVersionInfo; // Zap image information
- struct CORCOMPILE_DEPENDENCY * m_pZapDependencies; // Zap Dependancies directory
- COUNT_T m_cZapDependencies;
-#endif // FEATURE_PREJIT
- IMDInternalImport * m_pMDInternalImport;
- DWORD m_dwPEKind;
- DWORD m_dwMachine;
- const char * m_szVersionString;
-#ifdef _DEBUG
- IMetaDataAssemblyImport * m_pDebugMDImport;
-#endif //_DEBUG
-};
-
-#endif // FEATURE_FUSION
#endif // __AssemblyMDInternalDispenser__h__
diff --git a/src/md/inc/imptlb.h b/src/md/inc/imptlb.h
deleted file mode 100644
index ba2981a415..0000000000
--- a/src/md/inc/imptlb.h
+++ /dev/null
@@ -1,777 +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.
-//*****************************************************************************
-// File: imptlb.h
-//
-
-//
-// TypeLib importer.
-//*****************************************************************************
-#ifndef __imptlb_h__
-#define __imptlb_h__
-
-#ifndef FEATURE_COMINTEROP
-#error FEATURE_COMINTEROP is required for this file
-#endif // FEATURE_COMINTEROP
-#ifndef FEATURE_COMINTEROP_TLB_SUPPORT
-#error FEATURE_COMINTEROP_TLB_SUPPORT is required for this file
-#endif // FEATURE_COMINTEROP_TLB_SUPPORT
-
-//#define TLB_STATS
-
-#define MAX_TLB_VT VT_LPWSTR + 1
-#define MAX_INIT_SIG 3
-#define MAX_COM_GUID_SIG 6
-#define MAX_COM_ADDLISTENER_SIG 8
-#define MAX_COM_REMOVELISTENER_SIG 8
-#define CB_MAX_ELEMENT_TYPE 4
-
-// Forward declarations.
-struct ITypeLibImporterNotifySink;
-class Assembly;
-class Module;
-class CImportTlb;
-
-//*****************************************************************************
-// Class to perform memory management. Memory is not moved as the heap is
-// expanded, and all of the allocations are cleaned up in the destructor.
-//*****************************************************************************
-class CWCHARPool : public StgPool
-{
-public:
- CWCHARPool() : StgPool()
- {
- HRESULT hr = InitNew();
- _ASSERTE(hr == S_OK);
- }
-
- // Allocate some bytes from the pool.
- WCHAR * Alloc(ULONG nChars)
- {
- BYTE *pRslt;
- // Convert from characters to bytes.
- nChars *= sizeof(WCHAR);
- if (nChars > GetCbSegAvailable())
- if (!Grow(nChars))
- return 0;
- pRslt = GetNextLocation();
- SegAllocate(nChars);
- return (WCHAR*)pRslt;
- }
-}; // class CDescPool : public StgPool
-
-
-//*****************************************************************************
-// This helper method is used to track an url to typeref token. This makes
-// defining new typerefs faster.
-//*****************************************************************************
-class CImpTlbTypeRef
-{
-public:
- CImpTlbTypeRef() { }
- ~CImpTlbTypeRef() { m_Map.Clear(); }
-
- //*****************************************************************************
- // Look for an existing typeref in the map and return if found. If not found,
- // then create a new one and add it to the map for later.
- //*****************************************************************************
- HRESULT DefineTypeRef( // S_OK or error.
- IMetaDataEmit *pEmit, // Emit interface.
- mdAssemblyRef ar, // Containing assembly.
- const LPCWSTR szURL, // URL of the TypeDef, wide chars.
- mdTypeRef *ptr); // Put mdTypeRef here
-
- class TokenOfTypeRefHashKey
- {
- public:
- mdToken tkResolutionScope; // TypeRef's resolution scope.
- LPCWSTR szName; // TypeRef's name.
- mdTypeRef tr; // The TypeRef's token.
- };
-
-private:
-
- class CTokenOfTypeRefHash : public CClosedHash<class TokenOfTypeRefHashKey>
- {
- public:
- typedef CClosedHash<class TokenOfTypeRefHashKey> Super;
- typedef TokenOfTypeRefHashKey T;
-
- CTokenOfTypeRefHash() : CClosedHash<class TokenOfTypeRefHashKey>(101) {}
- ~CTokenOfTypeRefHash() { Clear(); }
-
- virtual void Clear();
-
- unsigned int Hash(const void *pData) {return Hash((const T*)pData);}
- unsigned int Hash(const T *pData);
-
- unsigned int Compare(const void *p1, BYTE *p2) {return Compare((const T*)p1, (T*)p2);}
- unsigned int Compare(const T *p1, T *p2);
-
- ELEMENTSTATUS Status(BYTE *p) {return Status((T*)p);}
- ELEMENTSTATUS Status(T *p);
-
- void SetStatus(BYTE *p, ELEMENTSTATUS s) {SetStatus((T*)p, s);}
- void SetStatus(T *p, ELEMENTSTATUS s);
-
- void* GetKey(BYTE *p) {return GetKey((T*)p);}
- void *GetKey(T *p);
-
- T* Add(const T *pData);
-
- CWCHARPool m_Names; // Heap of names.
- };
-
- CTokenOfTypeRefHash m_Map; // Map of namespace to token.
-};
-
-
-//*****************************************************************************
-// This helper class is used to track source interface ITypeInfo*'s to event
-// information.
-//*****************************************************************************
-class ImpTlbEventInfo
-{
-public:
- LPCWSTR szSrcItfName; // The source interface name (the key).
- mdTypeRef trEventItf; // The event interface typedef.
- LPCWSTR szEventItfName; // The event interface name.
- LPCWSTR szEventProviderName; // The event provider name.
- Assembly* SrcItfAssembly; // The assembly where source interface resides.
-};
-
-class CImpTlbEventInfoMap : protected CClosedHash<class ImpTlbEventInfo>
-{
-public:
- typedef CClosedHash<class ImpTlbEventInfo> Super;
- typedef ImpTlbEventInfo T;
-
- CImpTlbEventInfoMap() : CClosedHash<class ImpTlbEventInfo>(101) {}
- ~CImpTlbEventInfoMap() { Clear(); }
-
- HRESULT AddEventInfo(LPCWSTR szSrcItfName, mdTypeRef trEventItf, LPCWSTR szEventItfName, LPCWSTR szEventProviderName, Assembly* SrcItfAssembly);
- ImpTlbEventInfo *FindEventInfo(LPCWSTR szSrcItfName);
-
- HRESULT GetEventInfoList(CQuickArray<ImpTlbEventInfo*> &qbEvInfoList);
-
-private:
- unsigned int Hash(const void *pData) {return Hash((const T*)pData);}
- unsigned int Hash(const T *pData);
-
- unsigned int Compare(const void *p1, BYTE *p2) {return Compare((const T*)p1, (T*)p2);}
- unsigned int Compare(const T *p1, T *p2);
-
- ELEMENTSTATUS Status(BYTE *p) {return Status((T*)p);}
- ELEMENTSTATUS Status(T *p);
-
- void SetStatus(BYTE *p, ELEMENTSTATUS s) {SetStatus((T*)p, s);}
- void SetStatus(T *p, ELEMENTSTATUS s);
-
- void* GetKey(BYTE *p) {return GetKey((T*)p);}
- void *GetKey(T *p);
-
- T* Add(const T *pData);
-
- CWCHARPool m_Names; // Heap of names.
-};
-
-
-#if defined(_UNICODE) || defined(UNICODE)
-#define _tHashString(szStr) HashString(szStr)
-#else
-#define _tHashString(szStr) HashStringA(szStr)
-#endif
-
-
-
-//*****************************************************************************
-// This helper template is used by the TStringMap to track an item by its
-// character name.
-//*****************************************************************************
-template <class T> class TStringMapItem : HASHENTRY
-{
-public:
- TStringMapItem() :
- m_szString(0)
- {
- LIMITED_METHOD_CONTRACT;
- }
- ~TStringMapItem()
- {
- LIMITED_METHOD_CONTRACT;
- delete [] m_szString;
- }
-
- HRESULT SetString(LPCTSTR szValue)
- {
- WRAPPER_NO_CONTRACT;
- int iLen = (int)(::_tcslen(szValue) + 1);
- if ((m_szString = new TCHAR[iLen]) == 0)
- return (OutOfMemory());
- ::_tcscpy_s((TCHAR*)m_szString, iLen, szValue);
- return (S_OK);
- }
-
-public:
- LPTSTR m_szString; // Key data.
- T m_value; // Value for this key.
-};
-
-
-//*****************************************************************************
-// IMPORTANT: This data structure is deprecated, please do not add any new uses.
-// The hashtable implementation that should be used instead is code:SHash.
-// If code:SHash does not work for you, talk to mailto:clrdeag.
-//*****************************************************************************
-// This template provides a map from string to item, determined by the template
-// type passed in.
-//*****************************************************************************
-template <class T, int iBuckets=17, class TAllocator=CNewData, int iMaxSize=4096>
-class TStringMap :
- protected CHashTableAndData<TAllocator>
-{
- typedef CHashTableAndData<TAllocator> Super;
-
-public:
- typedef TStringMapItem<T> TItemType;
- typedef TStringMapItem<long> TOffsetType;
-
-#ifndef DACCESS_COMPILE
-
- TStringMap() :
- CHashTableAndData<TAllocator>(iBuckets)
- {
- LIMITED_METHOD_CONTRACT;
- }
-
-//*****************************************************************************
-// This is the second part of construction where we do all of the work that
-// can fail. We also take the array of structs here because the calling class
-// presumably needs to allocate it in its NewInit.
-//*****************************************************************************
- HRESULT NewInit() // Return status.
- {
- WRAPPER_NO_CONTRACT;
- return (CHashTableAndData<TAllocator>::NewInit(
- CNewData::GrowSize(0)/sizeof(TItemType),
- sizeof(TItemType),
- iMaxSize));
- }
-
-//*****************************************************************************
-// For each item still allocated, invoke its dtor so it frees up anything it
-// holds onto.
-//*****************************************************************************
- void Clear()
- {
- WRAPPER_NO_CONTRACT;
- HASHFIND sSrch;
- TItemType *p = (TItemType *) FindFirstEntry(&sSrch);
-
- while (p != 0)
- {
- // Call dtor on the item, since m_value is contained the scalar
- // dtor will get called.
- p->~TStringMapItem<T>();
- p = (TItemType *) FindNextEntry(&sSrch);
- }
- CHashTableAndData<TAllocator>::Clear();
- }
-
-#endif // #ifndef DACCESS_COMPILE
-
-//*****************************************************************************
-// Retrieve an item by name.
-//*****************************************************************************
- T *GetItem( // Null or object.
- LPCTSTR szKey) // What to do the lookup on.
- {
- WRAPPER_NO_CONTRACT;
- TItemType sInfo;
- TItemType *ptr; // Working pointer.
-
- // Create a key.
- sInfo.m_szString = (LPTSTR) szKey;
-
- // Look it up in the hash table.
- ptr = (TItemType *) Super::Find( _tHashString(szKey), (SIZE_T) &sInfo);
-
- // Don't let dtor free our string.
- sInfo.m_szString = 0;
-
- // If pointer found, return to caller. To handle T's that have
- // an operator &(), find raw address without going through &m_value.
- if (ptr)
- return ((T *) ((BYTE *) ptr + offsetof(TOffsetType, m_value)));
- else
- return (0);
- }
-
-//*****************************************************************************
-// Initialize an iterator and return the first item.
-//*****************************************************************************
- TItemType *FindFirstEntry(
- HASHFIND *psSrch)
- {
- WRAPPER_NO_CONTRACT;
- TItemType *ptr = (TItemType *) Super::FindFirstEntry(psSrch);
-
- return (ptr);
- }
-
-//*****************************************************************************
-// Return the next item, via an iterator.
-//*****************************************************************************
- TItemType *FindNextEntry(
- HASHFIND *psSrch)
- {
- WRAPPER_NO_CONTRACT;
- TItemType *ptr = (TItemType *) Super::FindNextEntry(psSrch);
-
- return (ptr);
- }
-
-#ifndef DACCESS_COMPILE
-
-//*****************************************************************************
-// Add an item to the list.
-//*****************************************************************************
- HRESULT AddItem( // S_OK, or S_FALSE.
- LPCTSTR szKey, // The key value for the item.
- T &item) // Thing to add.
- {
- WRAPPER_NO_CONTRACT;
- TItemType *ptr; // Working pointer.
-
- // Allocate an entry in the hash table.
- if ((ptr = (TItemType *) this->Add( _tHashString(szKey))) == 0)
- return (OutOfMemory());
-
- // Fill the record.
- if (ptr->SetString(szKey) < 0)
- {
- DelItem(ptr);
- return (OutOfMemory());
- }
-
- // Call the placement new operator on the item so it can init itself.
- // To handle T's that have an operator &(), find raw address without
- // going through &m_value.
- T *p = new ((void *) ((BYTE *) ptr + offsetof(TOffsetType, m_value))) T;
- *p = item;
- return (S_OK);
- }
-
-//*****************************************************************************
-// Delete an item.
-//*****************************************************************************
- void DelItem(
- LPCTSTR szKey) // What to delete.
- {
- WRAPPER_NO_CONTRACT;
- TItemType sInfo;
- TItemType *ptr; // Working pointer.
-
- // Create a key.
- sInfo.m_szString = (LPTSTR) szKey;
-
- // Look it up in the hash table.
- ptr = (TItemType *) this->Find( _tHashString(szKey), (BYTE *) &sInfo);
-
- // Don't let dtor free our string.
- sInfo.m_szString = 0;
-
- // If found, delete.
- if (ptr)
- DelItem(ptr);
- }
-
-#endif // #ifndef DACCESS_COMPILE
-
-//*****************************************************************************
-// Compare the keys for two collections.
-//*****************************************************************************
- BOOL Cmp( // 0 or != 0.
- SIZE_T data, // Raw key data on lookup.
- const HASHENTRY *pElement) // The element to compare data against.
- {
- LIMITED_METHOD_DAC_CONTRACT;
- TItemType *p = (TItemType *) (size_t) pElement;
- return (::_tcscmp(((TItemType *) data)->m_szString, p->m_szString));
- }
-
-private:
- void DelItem(
- TItemType *pItem) // Entry to delete.
- {
- WRAPPER_NO_CONTRACT;
- // Need to destruct this item.
- pItem->~TStringMapItem<T>();
- CHashTableAndData<TAllocator>::Delete( HashString(pItem->m_szString), (HASHENTRY *)(void *)pItem);
- }
-};
-
-class CImpTlbReservedNames
-{
-public:
- CImpTlbReservedNames() {}
- ~CImpTlbReservedNames() {/*m_StringMap.Clear();*/}
-
-#ifndef DACCESS_COMPILE
- HRESULT Init() {return m_StringMap.NewInit();}
-
- void AddReservedName(LPCWSTR szName) {BOOL flag = TRUE; m_StringMap.AddItem(szName, flag);}
-#endif
- BOOL IsReservedName(LPCWSTR szName) {return m_StringMap.GetItem(szName) != 0;}
-
-private:
- TStringMap<BOOL> m_StringMap;
-};
-
-
-//*****************************************************************************
-// Helper class to keep track of the mappings from default interfaces to
-// class interfaces.
-//*****************************************************************************
-class ImpTlbClassItfInfo
-{
-public:
- IID ItfIID; // The IID of the interface.
- LPCWSTR szClassItfName; // The class interface name.
-};
-
-class CImpTlbDefItfToClassItfMap : protected CClosedHash<class ImpTlbClassItfInfo>
-{
-public:
- typedef CClosedHash<class ImpTlbClassItfInfo> Super;
- typedef ImpTlbClassItfInfo T;
-
- CImpTlbDefItfToClassItfMap();
- ~CImpTlbDefItfToClassItfMap();
-
- HRESULT Init(ITypeLib *pTlb, BSTR bstrNameSpace);
-
- LPCWSTR GetClassItfName(IID &rItfIID);
-
-private:
- HRESULT AddCoClassInterfaces(ITypeInfo *pCoClassITI, TYPEATTR *pCoClassTypeAttr);
-
- unsigned int Hash(const void *pData) {return Hash((const T*)pData);}
- unsigned int Hash(const T *pData);
-
- unsigned int Compare(const void *p1, BYTE *p2) {return Compare((const T*)p1, (T*)p2);}
- unsigned int Compare(const T *p1, T *p2);
-
- ELEMENTSTATUS Status(BYTE *p) {return Status((T*)p);}
- ELEMENTSTATUS Status(T *p);
-
- void SetStatus(BYTE *p, ELEMENTSTATUS s) {SetStatus((T*)p, s);}
- void SetStatus(T *p, ELEMENTSTATUS s);
-
- void* GetKey(BYTE *p) {return GetKey((T*)p);}
- void *GetKey(T *p);
-
- T* Add(const T *pData);
-
- CWCHARPool m_Names; // Heap of names.
- BSTR m_bstrNameSpace; // Namespace of the typelib.
-};
-
-
-//*****************************************************************************
-// Helper class to keep track of imported typelibs. Typically, a typelib
-// imports only 2 or 3 other typelibs, so a simple array is used.
-//*****************************************************************************
-struct CTlbRef
-{
- GUID guid; // GUID of referenced typelib.
- mdAssemblyRef ar; // AssemblyRef for the module containing reference.
- BSTR szNameSpace; // The namespace of the types contained in the assembly.
- BSTR szAsmName; // The assembly name.
- Assembly* Asm; // The assembly.
- CImpTlbDefItfToClassItfMap *pDefItfToClassItfMap; // The default interface to class interface map.
-
- ~CTlbRef()
- {
- SysFreeString(szNameSpace);
- SysFreeString(szAsmName);
- delete pDefItfToClassItfMap;
- }
-};
-
-class CImpTlbLibRef : public CQuickArray<CTlbRef>
-{
- typedef CQuickArray<CTlbRef> base;
-public:
- CImpTlbLibRef() {base::Shrink(0);}
- ~CImpTlbLibRef();
-
- HRESULT Add(ITypeLib *pITLB, CImportTlb *pImporter, mdAssemblyRef ar, BSTR wzNamespace, BSTR wzAsmName, Assembly* assm, CImpTlbDefItfToClassItfMap **ppMap);
- int Find(ITypeLib *pITLB, mdAssemblyRef *par, BSTR *pwzNamespace, BSTR *pwzAsmName, Assembly** assm, CImpTlbDefItfToClassItfMap **ppDefItfToClassItfMap);
-};
-
-
-class CImportTlb
-{
-public:
- static CImportTlb* CreateImporter(LPCWSTR szLibrary, ITypeLib *pitlb, BOOL bGenerateTCEAdapters, BOOL bUnsafeInterfaces, BOOL bSafeArrayAsSystemArray, BOOL bTransformDispRetVals, BOOL bPreventClassMembers, BOOL bSerializableValueClasses);
-
- CImportTlb();
- CImportTlb(LPCWSTR szLibrary, ITypeLib *pitlb, BOOL bGenerateTCEAdapters, BOOL bUnsafeInterfaces, BOOL bSafeArrayAsSystemArray, BOOL bTransformDispRetVals, BOOL bPreventClassMembers, BOOL bSerializableValueClasses);
- ~CImportTlb();
-
- HRESULT Import();
- HRESULT SetNamespace(WCHAR const *pNamespace);
- WCHAR *GetNamespace() {return m_wzNamespace;}
- HRESULT SetNotification(ITypeLibImporterNotifySink *pINotify);
- HRESULT SetMetaData(IUnknown *pIUnk);
- void SetAssembly(Assembly *pAssembly) {m_pAssembly = pAssembly;}
- void SetModule(Module *pModule) {m_pModule = pModule;}
- HRESULT GetNamespaceOfRefTlb(ITypeLib *pITLB, BSTR *pwzNamespace, CImpTlbDefItfToClassItfMap **ppDefItfToClassItfMap);
- HRESULT GetEventInfoList(CQuickArray<ImpTlbEventInfo*> &qbEvInfoList) {return m_EventInfoMap.GetEventInfoList(qbEvInfoList);}
-
- static HRESULT GetDefaultInterface(ITypeInfo *pCoClassTI, ITypeInfo **pDefaultItfTI);
-
-protected:
-
- struct MemberInfo
- {
- union
- {
- FUNCDESC *m_psFunc; // Pointer to FuncDesc.
- VARDESC *m_psVar; // Pointer to VarDesc.
- };
- LPWSTR m_pName; // Function/Prop's name, possibly decorated.
- int m_iMember; // The index of the member in the ITypeInfo.
- union
- {
- LPWSTR m_pName2; // Prop's second name, if any.
- mdToken m_mdFunc; // Function's token & semantics, if not property.
- USHORT m_msSemantics; // Semantics only.
- };
- void SetFuncInfo(mdMethodDef mdFunc, USHORT msSemantics) {m_mdFunc = RidFromToken(mdFunc) | (msSemantics<<24);}
- void GetFuncInfo(mdMethodDef &mdFunc, USHORT &msSemantics) {mdFunc = m_mdFunc&0xffffff | mdtMethodDef; msSemantics = m_mdFunc>>24;}
- };
-
-
- HRESULT ConvertTypeLib();
- HRESULT ConvertTypeInfo();
-
- HRESULT ExplicitlyImplementsIEnumerable(ITypeInfo *pITI, TYPEATTR *psAttr, BOOL fLookupPartner = TRUE);
-
- HRESULT _NewLibraryObject();
- HRESULT ConvCoclass(ITypeInfo *pITI, TYPEATTR *psAttr);
- HRESULT ConvEnum(ITypeInfo *pITI, TYPEATTR *psAttr);
- HRESULT ConvRecord(ITypeInfo *pITI, TYPEATTR *psAttr, BOOL bUnion);
- HRESULT ConvIface(ITypeInfo *pITI, TYPEATTR *psAttr, BOOL bVtblGaps=true);
- HRESULT ConvDispatch(ITypeInfo *pITI, TYPEATTR *psAttr, BOOL bVtblGaps=true);
- HRESULT ConvModule(ITypeInfo *pITI, TYPEATTR *psAttr);
-
- HRESULT IsIUnknownDerived(ITypeInfo *pITI, TYPEATTR *psAttr);
- HRESULT IsIDispatchDerived(ITypeInfo *pITI, TYPEATTR *psAttr);
- HRESULT HasNewEnumMember(ITypeInfo *pItfTI);
- HRESULT FuncIsNewEnum(ITypeInfo *pITI, FUNCDESC *pFuncDesc, DWORD index);
- HRESULT PropertyIsNewEnum(ITypeInfo *pITI, VARDESC *pVarDesc, DWORD index);
-
- HRESULT HasObjectFields(ITypeInfo *pITI, TYPEATTR *psAttr);
- HRESULT IsObjectType(ITypeInfo *pITI, const TYPEDESC *pType);
- HRESULT CompareSigsIgnoringRetType(PCCOR_SIGNATURE pbSig1, ULONG cbSig1, PCCOR_SIGNATURE pbSig2, ULONG cbSig2);
-
- HRESULT FindMethod(mdTypeDef td, LPCWSTR szName, PCCOR_SIGNATURE pbSig, ULONG cbSig, mdMethodDef *pmb);
- HRESULT FindProperty(mdTypeDef td, LPCWSTR szName, PCCOR_SIGNATURE pSig, ULONG cbSig, mdProperty *pPr);
- HRESULT FindEvent(mdTypeDef td, LPCWSTR szName, mdProperty *pEv);
-
- HRESULT ReportEvent(int ev, int hr, ...);
-
- HRESULT _DefineSysRefs();
- HRESULT _GetNamespaceName(ITypeLib *pITLB, BSTR *pwzNamespace);
- HRESULT _GetTokenForTypeInfo(ITypeInfo *pITI, BOOL bConvDefItfToClassItf, mdToken *pToken, __out_ecount (chTypeRef) __out_opt LPWSTR pszTypeRef=0, int chTypeRef=0, int *pchTypeRef=0, BOOL bAsmQualifiedName = FALSE);
-
- HRESULT _FindFirstUserMethod(ITypeInfo *pITI, TYPEATTR *psAttr, int *pIx);
- HRESULT _ResolveTypeDescAliasTypeKind(ITypeInfo *pITIAlias, TYPEDESC *ptdesc, TYPEKIND *ptkind);
- HRESULT _ResolveTypeDescAlias(ITypeInfo *pITIAlias, const TYPEDESC *ptdesc, ITypeInfo **ppTIResolved, TYPEATTR **ppsAttrResolved, GUID *pGuid=0);
-
- HRESULT _SetHiddenCA(mdTypeDef token);
- HRESULT _ForceIEnumerableCVExists(ITypeInfo* pITI, BOOL* CVExists);
- HRESULT _SetDispIDCA(ITypeInfo* pITI, int iMember, long lDispId, mdToken func, BOOL fAlwaysAdd, long* lDispSet, BOOL bFunc);
- HRESULT _GetDispIDCA(ITypeInfo* pITI, int iMember, long* lDispSet, BOOL bFunc);
- HRESULT _CheckForPropertyCustomAttributes(ITypeInfo* pITI, int index, INVOKEKIND* ikind);
-
- HRESULT _ConvIfaceMembers(ITypeInfo *pITI, TYPEATTR *psAttr, BOOL bVtblGaps, BOOL bAddDispIds, BOOL bInheritsIEnum);
- HRESULT _ConvSrcIfaceMembers(ITypeInfo *pITI, TYPEATTR* psAttr, BOOL fInheritsIEnum);
- HRESULT _ConvDispatchMembers(ITypeInfo *pITI, TYPEATTR *psAttr, BOOL fInheritsIEnum);
- HRESULT _GetFunctionPropertyInfo(FUNCDESC *psFunc, USHORT *pSemantics, FUNCDESC **ppSig, TYPEDESC **ppProperty, BOOL *pbRetval, BOOL fUseLastParam, BSTR strName);
- HRESULT _ConvFunction(ITypeInfo *pITI, MemberInfo *pMember, int bVtblGapFuncs, BOOL bAddDispIds, BOOL bDelegateInvokeMeth, BOOL* bAllowIEnum);
- HRESULT _GenerateEvent(ITypeInfo *pITI, MemberInfo *pMember, BOOL fInheritsIEnum);
- HRESULT _GenerateEventDelegate(ITypeInfo *pITI, MemberInfo *pMember, mdTypeDef *ptd, BOOL fInheritsIEnum);
- HRESULT _AddSrcItfMembersToClass(mdTypeRef trSrcItf);
-
- HRESULT _ConvPropertiesForFunctions(ITypeInfo *pITI, TYPEATTR *psAttr);
- enum ParamOpts{ParamNormal=0, ParamOptional, ParamVarArg};
- HRESULT _ConvParam(ITypeInfo *pITI, mdMethodDef mbFunc, int iSequence, const ELEMDESC *pdesc, ParamOpts paramOpts, const WCHAR *pszName, BYTE *pbNative, ULONG cbNative);
- HRESULT _ConvConstant(ITypeInfo *pITI, VARDESC *psVar, BOOL bEnumMember=false);
- HRESULT _ConvField(ITypeInfo *pITI, VARDESC *psVar, mdFieldDef *pmdField, BOOL bUnion);
- HRESULT _ConvProperty(ITypeInfo *pITI, MemberInfo *pMember);
- HRESULT _ConvNewEnumProperty(ITypeInfo *pITI, VARDESC *psVar, MemberInfo *pMember);
-
- HRESULT _HandleAliasInfo(ITypeInfo *pITI, TYPEDESC *pTypeDesc, mdToken tk);
-
- HRESULT _AddTlbRef(ITypeLib *pITLB, mdAssemblyRef *par, BSTR *pwzNamespace, BSTR *pwzAsmName, CImpTlbDefItfToClassItfMap **ppDefItfToClassItfMap);
-
- HRESULT _AddGuidCa(mdToken tkObj, REFGUID guid);
- HRESULT _AddDefaultMemberCa(mdToken tkObj, LPCWSTR szName);
-
- HRESULT _AddStringCa(int attr, mdToken tk, LPCWSTR wzString);
-
- HRESULT GetKnownTypeToken(VARTYPE vt, mdTypeRef *ptr);
-
- HRESULT _GetTokenForEventItf(ITypeInfo *pSrcItfITI, mdTypeRef *ptr);
- HRESULT _CreateClassInterface(ITypeInfo *pCoClassITI, ITypeInfo *pDefItfITI, mdTypeRef trDefItf, mdTypeRef rtDefEvItf, mdToken *ptr);
-
- HRESULT GetManagedNameForCoClass(ITypeInfo *pITI, CQuickArray<WCHAR> &qbClassName);
- HRESULT GenerateUniqueTypeName(CQuickArray<WCHAR> &qbTypeName);
- HRESULT GenerateUniqueMemberName(CQuickArray<WCHAR> &qbMemberName, PCCOR_SIGNATURE pSig, ULONG SigSize, LPCWSTR szPrefix, mdToken type);
- HRESULT _IsAlias(ITypeInfo *pITI, TYPEDESC *pTypeDesc);
-
- HRESULT GetDefMemberName(ITypeInfo *pITI, BOOL bItfQualified, CQuickArray<WCHAR> &qbDefMemberName);
-
- enum SigFlags {
- // These match the typelib values
- SIG_IN = 0x0001, // Input param.
- SIG_OUT = 0x0002, // Output param.
- SIG_RET = 0x0008, // Retval. Currently unused.
- SIG_OPT = 0x0010, // Optional param. Currently unused.
- SIG_FLAGS_MASK = 0x001b, // Mask of flags from TypeLib PARAMFLAGs
-
- SIG_FUNC = 0x0100, // Convert signature for function.
- SIG_FIELD = 0x0200, // Convert signature for field.
- SIG_ELEM = 0x0300, // Convert signature for sub element (eg, array of X).
- SIG_TYPE_MASK = 0x0300,
-
- SIG_USE_BYREF = 0x1000, // If set convert one ptr as E_T_BYREF.
- SIG_VARARG = 0x4000, // If set, this is a paramarray type. Use szArray, not System.Array.
-
- SIG_FLAGS_NONE = 0 // '0' of this enum type.
- };
-
- #define IsSigIn(flags) ((flags & SIG_IN) == SIG_IN)
- #define IsSigOut(flags) ((flags & SIG_OUT) == SIG_OUT)
- #define IsSigRet(flags) ((flags & SIG_RET) == SIG_RET)
- #define IsSigOpt(flags) ((flags & SIG_OPT) == SIG_OPT)
- #define IsSigOutRet(flags) ((flags & (SIG_OUT|SIG_RET)) == (SIG_OUT|SIG_RET))
-
- #define IsSigFunc(flags) ((flags & SIG_TYPE_MASK) == SIG_FUNC)
- #define IsSigField(flags) ((flags & SIG_TYPE_MASK) == SIG_FIELD)
- #define IsSigElem(flags) ((flags & SIG_TYPE_MASK) == SIG_ELEM)
-
- #define IsSigUseByref(flags) ((flags & SIG_USE_BYREF) == SIG_USE_BYREF)
- #define IsSigVarArg(flags) ((flags & SIG_VARARG) == SIG_VARARG)
-
- HRESULT _ConvSignature(ITypeInfo *pITI, const TYPEDESC *pType, ULONG Flags, CQuickBytes &qbSigBuf, ULONG cbSig, ULONG *pcbSig, CQuickArray<BYTE> &qbNativeTypeBuf, ULONG cbNativeType, ULONG *pcbNativeType, BOOL bNewEnumMember, int iByRef=0);
-
- // For handling out-of-order vtables.
- CQuickArray<MemberInfo> m_MemberList;
- CWCHARPool *m_pMemberNames;
- int m_cMemberProps; // Count of props in memberlist.
- HRESULT BuildMemberList(ITypeInfo *pITI, int iStart, int iEnd, BOOL bInheritsIEnum);
- HRESULT FreeMemberList(ITypeInfo *pITI);
-
- // List of predefined token types for custom attributes.
-#define INTEROP_ATTRIBUTES() \
- INTEROP_ATTRIBUTE(DISPID) \
- INTEROP_ATTRIBUTE(CLASSINTERFACE) \
- INTEROP_ATTRIBUTE(INTERFACETYPE) \
- INTEROP_ATTRIBUTE(TYPELIBTYPE) \
- INTEROP_ATTRIBUTE(TYPELIBVAR) \
- INTEROP_ATTRIBUTE(TYPELIBFUNC) \
- INTEROP_ATTRIBUTE(COMSOURCEINTERFACES) \
- INTEROP_ATTRIBUTE(COMCONVERSIONLOSS) \
- INTEROP_ATTRIBUTE(GUID) \
- INTEROP_ATTRIBUTE(DEFAULTMEMBER) \
- INTEROP_ATTRIBUTE(COMALIASNAME) \
- INTEROP_ATTRIBUTE(PARAMARRAY) \
- INTEROP_ATTRIBUTE(LCIDCONVERSION) \
- INTEROP_ATTRIBUTE(DECIMALVALUE) \
- INTEROP_ATTRIBUTE(DATETIMEVALUE) \
- INTEROP_ATTRIBUTE(IUNKNOWNVALUE) \
- INTEROP_ATTRIBUTE(IDISPATCHVALUE) \
- INTEROP_ATTRIBUTE(COMVISIBLE) \
- INTEROP_ATTRIBUTE(SERIALIZABLE) \
- INTEROP_ATTRIBUTE_SPECIAL(COMEVENTINTERFACE) \
- INTEROP_ATTRIBUTE_SPECIAL(COCLASS) \
-
-#define INTEROP_ATTRIBUTE(x) ATTR_##x,
-#define INTEROP_ATTRIBUTE_SPECIAL(x) ATTR_##x,
- enum {INTEROP_ATTRIBUTES()
- // Last value gives array size.
- ATTR_COUNT};
-#undef INTEROP_ATTRIBUTE
-#undef INTEROP_ATTRIBUTE_SPECIAL
-
- mdToken m_tkAttr[ATTR_COUNT];
- HRESULT GetAttrType(int attr, mdToken *ptk);
-
- // look up table for known type
- mdTypeRef m_tkKnownTypes[MAX_TLB_VT];
-
- LPCWSTR m_szLibrary; // Name of typelib being imported.
- BOOL m_bGenerateTCEAdapters; // A flag indicating if the TCE adapters are being generated or not.
- BOOL m_bUnsafeInterfaces; // A flag indicating whether runtime security checks should be disabled on an interface
- BOOL m_bSafeArrayAsSystemArray; // A flag indicating whether to import SAFEARRAY's as System.Array's.
- BOOL m_bTransformDispRetVals; // A flag indicating if we should do [out,retval] transformation on disp only itfs.
- BOOL m_bPreventClassMembers; // A flag indicating if we should add members to CoClasses.
- BOOL m_bSerializableValueClasses; // A flag indicating if we should mark value classes as serializable.
- mdMemberRef m_tkSuppressCheckAttr; // Cached ctor for security check custom attribute
- ITypeLib *m_pITLB; // Typelib being imported.
- IMetaDataEmit2 *m_pEmit; // Emit API Interface pointer.
- IMetaDataImport2 *m_pImport; // Import API Interface pointer.
-
- BSTR m_wzNamespace; // Namespace of the created TypeDefs.
- mdTypeRef m_trObject; // Token of System.Object.
- mdTypeRef m_trValueType; // Token of System.ValueType.
- mdTypeRef m_trEnum; // Token of System.Enum.
- mdAssemblyRef m_arSystem; // AssemblyRef for classlib.
-
- ITypeInfo *m_pITI; // "Current" ITypeInfo being converted.
- ITypeInfo *m_pOrigITI; // Original "Current" ITypeInfo being converted,
- // represents TKIND_ALIAS or is equal to m_pITI.
-
- TYPEATTR *m_psAttr; // "TYPEATTR" of current ITypeInfo.
-
- BSTR m_szName; // Name of original current ITypeInfo.
- BSTR m_szMember; // Name of current Member (method or field).
- LPWSTR m_szMngName; // Full name of the managed type.
-
- ULONG m_cbVtableSlot; // Size of a vtable slot.
- ULONG m_Slot; // "Current" vtbl index within an interface.
-
- void *m_psClass; // "Current" class record.
- mdTypeDef m_tdTypeDef; // Current TypeDef.
- mdTypeDef m_tdHasDefault; // Most recent TypeDef with a default.
- enum {eImplIfaceNone, eImplIfaceDefault, eImplIface} m_ImplIface;
- mdToken m_tkInterface; // Interface being added to a coclass.
- BSTR m_szInterface; // Interface name for decoration.
-
- CImpTlbTypeRef m_TRMap; // Typeref map.
- CImpTlbLibRef m_LibRefs; // Referenced typelibs.
- CImpTlbDefItfToClassItfMap m_DefItfToClassItfMap; // The default interface to class interface map.
-
- CImpTlbReservedNames m_ReservedNames; // Reserved names.
- CImpTlbEventInfoMap m_EventInfoMap; // Map of event info's.
-
- ITypeLibImporterNotifySink *m_Notify; // Notification object.
- Assembly *m_pAssembly; // Containing assembly.
- Module *m_pModule; // Module we are emiting into.
-
-#if defined(TLB_STATS)
- LARGE_INTEGER m_freqVal; // Frequency of perf counter.
- BOOL m_bStats; // If true, collect timings.
-#endif // TLB_STATS
-};
-
-
-
-#endif
-
-//-eof-************************************************************************
diff --git a/src/md/inc/liteweightstgdb.h b/src/md/inc/liteweightstgdb.h
index 1234524731..057e29d1ca 100644
--- a/src/md/inc/liteweightstgdb.h
+++ b/src/md/inc/liteweightstgdb.h
@@ -66,8 +66,6 @@ protected:
friend class CorMetaDataScope;
friend class COR;
friend class RegMeta;
- friend class MERGER;
- friend class NEWMERGER;
friend class MDInternalRO;
friend class MDInternalRW;
};
diff --git a/src/md/inc/metamodelrw.h b/src/md/inc/metamodelrw.h
index 6e00d3cf3e..c2d24db8a5 100644
--- a/src/md/inc/metamodelrw.h
+++ b/src/md/inc/metamodelrw.h
@@ -1420,10 +1420,6 @@ public:
void EnableDeltaMetadataGeneration()
{
_ASSERTE(m_OptionValue.m_UpdateMode == MDUpdateENC);
-#ifndef FEATURE_CORECLR
- if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_UseMinimalDeltas))
- m_OptionValue.m_UpdateMode = MDUpdateDelta;
-#endif //!FEATURE_CORECLR
}
void DisableDeltaMetadataGeneration() {m_OptionValue.m_UpdateMode = MDUpdateENC;}
diff --git a/src/md/inc/rwutil.h b/src/md/inc/rwutil.h
index 5d7f98919c..81966b7fb9 100644
--- a/src/md/inc/rwutil.h
+++ b/src/md/inc/rwutil.h
@@ -181,30 +181,6 @@ private:
//*********************************************************************
//
-// Merge Token manager. This class is created in GetSaveSize as an agent to
-// notify linker regarding token movements. It does not have the ability to
-// keep track token movement.
-//
-//*********************************************************************
-class MergeTokenManager : public IMapToken
-{
-public:
- STDMETHODIMP QueryInterface(REFIID riid, PVOID *pp);
- STDMETHODIMP_(ULONG) AddRef();
- STDMETHODIMP_(ULONG) Release();
- STDMETHODIMP Map(mdToken tkImp, mdToken tkEmit);
- MergeTokenManager(MDTOKENMAP *pTkMapList, IUnknown *pHandler);
- virtual ~MergeTokenManager();
-private:
- LONG m_cRef;
- MDTOKENMAP *m_pTkMapList;
- IMapToken *m_pDefaultHostRemap;
-};
-
-
-
-//*********************************************************************
-//
// This CMapToken class implemented the IMapToken. It is used in RegMeta for
// filter process. This class can track all of the tokens are mapped. It also
// supplies a Find function.
diff --git a/src/md/inc/stgio.h b/src/md/inc/stgio.h
index 96a2f1dddb..2ec873d4c8 100644
--- a/src/md/inc/stgio.h
+++ b/src/md/inc/stgio.h
@@ -46,10 +46,8 @@ enum DBPROPMODE
{ DBPROP_TMODEF_READ = 0x1,
DBPROP_TMODEF_WRITE = 0x2,
DBPROP_TMODEF_EXCLUSIVE = 0x4,
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
// Shared memory uses ole32.dll - we cannot depend on it in the standalone WinRT Read-Only DLL
DBPROP_TMODEF_SHAREDMEM = 0x8,
-#endif
DBPROP_TMODEF_CREATE = 0x10,
DBPROP_TMODEF_FAILIFTHERE = 0x20,
DBPROP_TMODEF_SLOWSAVE = 0x100,
@@ -77,10 +75,8 @@ enum STGIOTYPE
STGIO_HMODULE = 2, // The file was loaded via LoadLibrary as module.
STGIO_STREAM = 3, // Stream pointer has data.
STGIO_MEM = 4, // In memory pointer has data.
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
// Shared memory uses ole32.dll - we cannot depend on it in the standalone WinRT Read-Only DLL
STGIO_SHAREDMEM = 5, // Shared memory handle.
-#endif
STGIO_HFILEMEM = 6 // Handle open, but memory allocated.
};
diff --git a/src/md/inc/winmdinterfaces.h b/src/md/inc/winmdinterfaces.h
index 4233e615d3..47f43df083 100644
--- a/src/md/inc/winmdinterfaces.h
+++ b/src/md/inc/winmdinterfaces.h
@@ -103,15 +103,7 @@ HRESULT VerifyNotWinMDHelper(IUnknown *pUnknown
,int line
#endif //_DEBUG
);
-#if defined(FEATURE_METADATA_IN_VM) && !defined(FEATURE_CORECLR)
-#ifdef _DEBUG
-#define VerifyNotWinMD(pUnknown, assertMsg) VerifyNotWinMDHelper(pUnknown, assertMsg, __FILE__, __LINE__)
-#else
-#define VerifyNotWinMD(pUnknown, assertMsg) VerifyNotWinMDHelper(pUnknown)
-#endif
-#else
#define VerifyNotWinMD(pUnknown, assertMsg) S_OK
-#endif // FEATURE_METADATA_IN_VM
#endif //__WINMDINTERFACES_H__
diff --git a/src/md/md_wks.cmake b/src/md/md_wks.cmake
index ab9df6c667..4d72c55a14 100644
--- a/src/md/md_wks.cmake
+++ b/src/md/md_wks.cmake
@@ -3,4 +3,4 @@ add_definitions(-DFEATURE_METADATA_INTERNAL_APIS)
add_definitions(-DFEATURE_METADATA_IN_VM)
if(WIN32)
add_definitions(-DFEATURE_METADATA_VERIFY_LAYOUTS)
-endif(WIN32) \ No newline at end of file
+endif(WIN32)
diff --git a/src/md/runtime/mdfileformat.cpp b/src/md/runtime/mdfileformat.cpp
index 2edd2e0292..844dc3cfae 100644
--- a/src/md/runtime/mdfileformat.cpp
+++ b/src/md/runtime/mdfileformat.cpp
@@ -77,7 +77,6 @@ MDFormat::VerifySignature(
}
}
-#if !defined(FEATURE_METADATA_STANDALONE_WINRT)
// Only a specific version of the 0.x format is supported by this code
// in order to support the NT 5 beta clients which used this format.
if (pSig->GetMajorVer() == FILE_VER_MAJOR_v0)
@@ -89,7 +88,6 @@ MDFormat::VerifySignature(
}
}
else
-#endif // !defined(FEATURE_METADATA_STANDALONE_WINRT)
// There is currently no code to migrate an old format of the 1.x. This
// would be added only under special circumstances.
if ((pSig->GetMajorVer() != FILE_VER_MAJOR) || (pSig->GetMinorVer() != FILE_VER_MINOR))
diff --git a/src/md/runtime/mdinternaldisp.cpp b/src/md/runtime/mdinternaldisp.cpp
index 1f5725ff01..e6e25a2110 100644
--- a/src/md/runtime/mdinternaldisp.cpp
+++ b/src/md/runtime/mdinternaldisp.cpp
@@ -112,11 +112,6 @@ CheckFileFormat(
}
else if (strcmp(pStream->GetName(), ENC_MODEL_STREAM_A) == 0)
{
-#ifdef FEATURE_METADATA_STANDALONE_WINRT
- Debug_ReportError("ENC model stream #- is not supported.");
- hr = CLDB_E_FILE_CORRUPT;
- goto ErrExit;
-#else //!FEATURE_METADATA_STANDALONE_WINRT
// Validate that only one of compressed/uncompressed is present.
if (*pFormat != MDFormat_Invalid)
{ // Already found a good stream.
@@ -126,21 +121,14 @@ CheckFileFormat(
}
// Found the ENC meta data stream.
*pFormat = MDFormat_ReadWrite;
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
}
else if (strcmp(pStream->GetName(), SCHEMA_STREAM_A) == 0)
{
-#ifdef FEATURE_METADATA_STANDALONE_WINRT
- Debug_ReportError("Schema stream #Schema is not supported.");
- hr = CLDB_E_FILE_CORRUPT;
- goto ErrExit;
-#else //!FEATURE_METADATA_STANDALONE_WINRT
// Found the uncompressed format
*pFormat = MDFormat_ICR;
// keep going. We may find the compressed format later.
// If so, we want to use the compressed format.
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
}
// Pick off the next stream if there is one.
@@ -228,1607 +216,5 @@ ErrExit:
} // GetMDInternalInterface
-#ifdef FEATURE_FUSION
-
-#ifndef DACCESS_COMPILE
-
-//*****************************************************************************
-// GetAssemblyMDInternalImport.
-// Instantiating an instance of AssemblyMDInternalImport.
-// This class can support the IMetaDataAssemblyImport and some functionalities
-// of IMetaDataImport on the internal import interface (IMDInternalImport).
-//*****************************************************************************
-STDAPI GetAssemblyMDInternalImport( // Return code.
- LPCWSTR szFileName, // [in] The scope to open.
- REFIID riid, // [in] The interface desired.
- IUnknown **ppIUnk) // [out] Return interface on success.
-{
- return GetAssemblyMDInternalImportEx(szFileName, riid, MDInternalImport_Default, ppIUnk);
-}
-
-STDAPI GetAssemblyMDInternalImportEx( // Return code.
- LPCWSTR szFileName, // [in] The scope to open.
- REFIID riid, // [in] The interface desired.
- MDInternalImportFlags flags, // [in] Flags to control opening the assembly
- IUnknown **ppIUnk, // [out] Return interface on success.
- HANDLE hFile)
-{
- HRESULT hr;
-
- if (!szFileName || !szFileName[0] || !ppIUnk)
- return E_INVALIDARG;
-
- // Sanity check the name.
- if (wcslen(szFileName) >= _MAX_PATH)
- return E_INVALIDARG;
-
- if (memcmp(szFileName, W("file:"), 10) == 0)
- szFileName = &szFileName[5];
-
- HCORMODULEHolder hModule;
- DWORD dwFileLength;
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
-
- IfFailGoto(RuntimeOpenImageInternal(szFileName, &hModule, &dwFileLength, flags, hFile), ErrAsmExpected);
-
- IfFailGo(GetAssemblyMDInternalImportHelper(hModule, riid, flags, ppIUnk));
-
-
-ErrAsmExpected:
- if(hr == COR_E_BADIMAGEFORMAT)
- hr = COR_E_ASSEMBLYEXPECTED;
-
-ErrExit:
-;
- END_SO_INTOLERANT_CODE;
-
- return hr;
-}
-
-HRESULT GetAssemblyMDInternalImportFromImage(
- HCORMODULE hImage,
- REFIID riid,
- IUnknown **ppIUnk)
-{
-
- HRESULT hr;
-
- IfFailGo(GetAssemblyMDInternalImportHelper(hImage, riid, MDInternalImport_Default, ppIUnk));
-
-ErrExit:
- return hr;
-}
-
-STDAPI GetAssemblyMDInternalImportByStream( // Return code.
- IStream *pIStream, // [in] The IStream for the file
- UINT64 AssemblyId, // [in] Unique Id for the assembly
- REFIID riid, // [in] The interface desired.
- IUnknown **ppIUnk) // [out] Return interface on success.
-{
- return GetAssemblyMDInternalImportByStreamEx(pIStream, AssemblyId, riid, MDInternalImport_Default, ppIUnk);
-}
-
-STDAPI GetAssemblyMDInternalImportByStreamEx( // Return code.
- IStream *pIStream, // [in] The IStream for the file
- UINT64 AssemblyId, // [in] Unique Id for the assembly
- REFIID riid, // [in] The interface desired.
- MDInternalImportFlags flags, // [in[ Flags to control opening the assembly
- IUnknown **ppIUnk) // [out] Return interface on success.
-{
- if (!pIStream || !ppIUnk)
- return E_INVALIDARG;
-
- HRESULT hr;
- DWORD dwFileLength;
- HCORMODULEHolder hModule;
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
-
- IfFailGoto(RuntimeOpenImageByStream(pIStream, AssemblyId, 0, &hModule, &dwFileLength, flags), ErrAsmExpected);
-
- IfFailGo(GetAssemblyMDInternalImportHelper(hModule, riid, flags, ppIUnk));
-
-
-ErrAsmExpected:
- if(hr == COR_E_BADIMAGEFORMAT)
- hr = COR_E_ASSEMBLYEXPECTED;
-
-ErrExit:
- ;
- END_SO_INTOLERANT_CODE;
-
- return hr;
-}
-
-
-HRESULT GetAssemblyMDInternalImportHelper(HCORMODULE hModule,
- REFIID riid,
- MDInternalImportFlags flags,
- IUnknown **ppIUnk)
-{
- AssemblyMDInternalImport *pAssemblyMDInternalImport = NULL;
- HRESULT hr;
- LPVOID base;
- PEDecoder pe;
- IfFailGoto(RuntimeGetImageBase(hModule,&base,TRUE,NULL), ErrAsmExpected);
-
- if (base!=NULL)
- IfFailGoto(pe.Init(base), ErrAsmExpected);
- else
- {
- COUNT_T lgth;
- IfFailGoto(RuntimeGetImageBase(hModule,&base,FALSE,&lgth), ErrAsmExpected);
- pe.Init(base, lgth);
- }
-
- // Both of these need to pass.
- if (!pe.HasCorHeader() || !pe.CheckCorHeader())
- IfFailGo(COR_E_ASSEMBLYEXPECTED);
- // Only one of these needs to.
- if (!pe.CheckILFormat() && !pe.CheckNativeFormat())
- IfFailGo(COR_E_BADIMAGEFORMAT);
-
- COUNT_T cbMetaData;
- LPCVOID pMetaData;
- pMetaData = pe.GetMetadata(&cbMetaData);
-
- // Get the IL metadata.
- IMDInternalImport *pMDInternalImport;
- IfFailGo(RuntimeGetMDInternalImport(hModule, flags, &pMDInternalImport));
- if (pMDInternalImport == NULL)
- IfFailGo(E_OUTOFMEMORY);
-
- _ASSERTE(pMDInternalImport);
- pAssemblyMDInternalImport = new (nothrow) AssemblyMDInternalImport (pMDInternalImport);
- if (!pAssemblyMDInternalImport) {
- pMDInternalImport->Release();
- IfFailGo(E_OUTOFMEMORY);
- }
-
- { // identify PE kind and machine type, plus the version string location
- DWORD dwKind=0;
- DWORD dwMachine=0;
- RuntimeGetImageKind(hModule,&dwKind,&dwMachine);
- pAssemblyMDInternalImport->SetPEKind(dwKind);
- pAssemblyMDInternalImport->SetMachine(dwMachine);
-
- {
- LPCSTR pString = NULL;
- IfFailGo(GetImageRuntimeVersionString((PVOID)pMetaData, &pString));
-
- pAssemblyMDInternalImport->SetVersionString(pString);
- }
-
- }
-
- pAssemblyMDInternalImport->SetHandle(hModule);
-
-#ifdef FEATURE_PREJIT
- // Check for zap header for INativeImageInstallInfo
- // Dont do this if we are returning the IL metadata as CORCOMPILE_DEPENDENCY
- // references the native image metadata, not the IL metadata.
-
- if (pe.HasNativeHeader() && !(flags & MDInternalImport_ILMetaData))
- {
- CORCOMPILE_VERSION_INFO *pNativeVersionInfo = pe.GetNativeVersionInfo();
-
- COUNT_T cDeps;
- CORCOMPILE_DEPENDENCY *pDeps = pe.GetNativeDependencies(&cDeps);
-
- pAssemblyMDInternalImport->SetZapVersionInfo(pNativeVersionInfo, pDeps, cDeps);
- }
-#endif // FEATURE_PREJIT
-
- IfFailGo(pAssemblyMDInternalImport->QueryInterface(riid, (void**)ppIUnk));
-
- return hr;
-
-ErrAsmExpected:
- if(hr == COR_E_BADIMAGEFORMAT)
- hr = COR_E_ASSEMBLYEXPECTED;
-
-ErrExit:
-
- if (pAssemblyMDInternalImport)
- delete pAssemblyMDInternalImport;
-
- return hr;
-}
-
-AssemblyMDInternalImport::AssemblyMDInternalImport (IMDInternalImport *pMDInternalImport)
-: m_cRef(0),
- m_pHandle(0),
- m_pBase(NULL),
-#ifdef FEATURE_PREJIT
- m_pZapVersionInfo(NULL),
-#endif // FEATURE_PREJIT
- m_pMDInternalImport(pMDInternalImport),
- m_dwPEKind(0),
- m_dwMachine(0),
- m_szVersionString("")
-{
- _ASSERTE(m_pMDInternalImport);
-} // AssemblyMDInternalImport
-
-AssemblyMDInternalImport::~AssemblyMDInternalImport ()
-{
- m_pMDInternalImport->Release();
-
- if (m_pBase)
- {
- UnmapViewOfFile(m_pBase);
- m_pBase = NULL;
- CloseHandle(m_pHandle);
- }
- else if(m_pHandle)
- {
- HRESULT hr;
- hr = RuntimeReleaseHandle(m_pHandle);
- _ASSERTE(SUCCEEDED(hr));
- }
-
- m_pHandle = NULL;
-}
-
-ULONG AssemblyMDInternalImport::AddRef()
-{
- return InterlockedIncrement(&m_cRef);
-} // ULONG AssemblyMDInternalImport::AddRef()
-
-ULONG AssemblyMDInternalImport::Release()
-{
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (!cRef)
- {
- VALIDATE_BACKOUT_STACK_CONSUMPTION;
- delete this;
- }
- return (cRef);
-} // ULONG AssemblyMDInternalImport::Release()
-
-HRESULT AssemblyMDInternalImport::QueryInterface(REFIID riid, void **ppUnk)
-{
- *ppUnk = 0;
-
- if (riid == IID_IUnknown)
- *ppUnk = (IUnknown *) (IMetaDataAssemblyImport *) this;
- else if (riid == IID_IMetaDataAssemblyImport)
- *ppUnk = (IMetaDataAssemblyImport *) this;
- else if (riid == IID_IMetaDataImport)
- *ppUnk = (IMetaDataImport *) this;
- else if (riid == IID_IMetaDataImport2)
- *ppUnk = (IMetaDataImport2 *) this;
- else if (riid == IID_ISNAssemblySignature)
- *ppUnk = (ISNAssemblySignature *) this;
-#ifdef FEATURE_PREJIT
- else if (riid == IID_IGetIMDInternalImport)
- *ppUnk = (IGetIMDInternalImport *) this;
- else if (riid == IID_INativeImageInstallInfo && m_pZapVersionInfo)
- *ppUnk = (INativeImageInstallInfo *) this;
-#endif // FEATURE_PREJIT
- else
- return (E_NOINTERFACE);
- AddRef();
- return (S_OK);
-}
-
-
-STDMETHODIMP AssemblyMDInternalImport::GetAssemblyProps ( // S_OK or error.
- mdAssembly mda, // [IN] The Assembly for which to get the properties.
- const void **ppbPublicKey, // [OUT] Pointer to the public key.
- ULONG *pcbPublicKey, // [OUT] Count of bytes in the public key.
- ULONG *pulHashAlgId, // [OUT] Hash Algorithm.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- ASSEMBLYMETADATA *pMetaData, // [OUT] Assembly MetaData.
- DWORD *pdwAssemblyFlags) // [OUT] Flags.
-{
- HRESULT hr;
- LPCSTR _szName;
- AssemblyMetaDataInternal _AssemblyMetaData;
-
- _AssemblyMetaData.ulProcessor = 0;
- _AssemblyMetaData.ulOS = 0;
-
- IfFailRet(m_pMDInternalImport->GetAssemblyProps(
- mda, // [IN] The Assembly for which to get the properties.
- ppbPublicKey, // [OUT] Pointer to the public key.
- pcbPublicKey, // [OUT] Count of bytes in the public key.
- pulHashAlgId, // [OUT] Hash Algorithm.
- &_szName, // [OUT] Buffer to fill with name.
- &_AssemblyMetaData, // [OUT] Assembly MetaData.
- pdwAssemblyFlags)); // [OUT] Flags.
-
- if (pchName != NULL)
- {
- *pchName = WszMultiByteToWideChar(CP_UTF8, 0, _szName, -1, szName, cchName);
- if (*pchName == 0)
- {
- return HRESULT_FROM_GetLastError();
- }
- }
-
- if (pMetaData)
- {
- pMetaData->usMajorVersion = _AssemblyMetaData.usMajorVersion;
- pMetaData->usMinorVersion = _AssemblyMetaData.usMinorVersion;
- pMetaData->usBuildNumber = _AssemblyMetaData.usBuildNumber;
- pMetaData->usRevisionNumber = _AssemblyMetaData.usRevisionNumber;
- pMetaData->ulProcessor = 0;
- pMetaData->ulOS = 0;
-
- pMetaData->cbLocale = WszMultiByteToWideChar(CP_UTF8, 0, _AssemblyMetaData.szLocale, -1, pMetaData->szLocale, pMetaData->cbLocale);
- if (pMetaData->cbLocale == 0)
- {
- return HRESULT_FROM_GetLastError();
- }
- }
-
- return S_OK;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetAssemblyRefProps ( // S_OK or error.
- mdAssemblyRef mdar, // [IN] The AssemblyRef for which to get the properties.
- const void **ppbPublicKeyOrToken, // [OUT] Pointer to the public key or token.
- ULONG *pcbPublicKeyOrToken, // [OUT] Count of bytes in the public key or token.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- ASSEMBLYMETADATA *pMetaData, // [OUT] Assembly MetaData.
- const void **ppbHashValue, // [OUT] Hash blob.
- ULONG *pcbHashValue, // [OUT] Count of bytes in the hash blob.
- DWORD *pdwAssemblyRefFlags) // [OUT] Flags.
-{
- HRESULT hr;
- LPCSTR _szName;
- AssemblyMetaDataInternal _AssemblyMetaData;
-
- _AssemblyMetaData.ulProcessor = 0;
- _AssemblyMetaData.ulOS = 0;
-
- IfFailRet(m_pMDInternalImport->GetAssemblyRefProps(
- mdar, // [IN] The Assembly for which to get the properties.
- ppbPublicKeyOrToken, // [OUT] Pointer to the public key or token.
- pcbPublicKeyOrToken, // [OUT] Count of bytes in the public key or token.
- &_szName, // [OUT] Buffer to fill with name.
- &_AssemblyMetaData, // [OUT] Assembly MetaData.
- ppbHashValue, // [OUT] Hash blob.
- pcbHashValue, // [OUT] Count of bytes in the hash blob.
- pdwAssemblyRefFlags)); // [OUT] Flags.
-
- if (pchName != NULL)
- {
- *pchName = WszMultiByteToWideChar(CP_UTF8, 0, _szName, -1, szName, cchName);
- if (*pchName == 0)
- {
- return HRESULT_FROM_GetLastError();
- }
- }
-
- pMetaData->usMajorVersion = _AssemblyMetaData.usMajorVersion;
- pMetaData->usMinorVersion = _AssemblyMetaData.usMinorVersion;
- pMetaData->usBuildNumber = _AssemblyMetaData.usBuildNumber;
- pMetaData->usRevisionNumber = _AssemblyMetaData.usRevisionNumber;
- pMetaData->ulProcessor = 0;
- pMetaData->ulOS = 0;
-
- pMetaData->cbLocale = WszMultiByteToWideChar(CP_UTF8, 0, _AssemblyMetaData.szLocale, -1, pMetaData->szLocale, pMetaData->cbLocale);
- if (pMetaData->cbLocale == 0)
- {
- return HRESULT_FROM_GetLastError();
- }
-
- return S_OK;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetFileProps ( // S_OK or error.
- mdFile mdf, // [IN] The File for which to get the properties.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- const void **ppbHashValue, // [OUT] Pointer to the Hash Value Blob.
- ULONG *pcbHashValue, // [OUT] Count of bytes in the Hash Value Blob.
- DWORD *pdwFileFlags) // [OUT] Flags.
-{
- HRESULT hr;
- LPCSTR _szName;
- IfFailRet(m_pMDInternalImport->GetFileProps(
- mdf,
- &_szName,
- ppbHashValue,
- pcbHashValue,
- pdwFileFlags));
-
- if (pchName != NULL)
- {
- *pchName = WszMultiByteToWideChar(CP_UTF8, 0, _szName, -1, szName, cchName);
- if (*pchName == 0)
- {
- return HRESULT_FROM_GetLastError();
- }
- }
-
- return S_OK;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetExportedTypeProps ( // S_OK or error.
- mdExportedType mdct, // [IN] The ExportedType for which to get the properties.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- mdToken *ptkImplementation, // [OUT] mdFile or mdAssemblyRef or mdExportedType.
- mdTypeDef *ptkTypeDef, // [OUT] TypeDef token within the file.
- DWORD *pdwExportedTypeFlags) // [OUT] Flags.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetManifestResourceProps ( // S_OK or error.
- mdManifestResource mdmr, // [IN] The ManifestResource for which to get the properties.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- mdToken *ptkImplementation, // [OUT] mdFile or mdAssemblyRef that provides the ManifestResource.
- DWORD *pdwOffset, // [OUT] Offset to the beginning of the resource within the file.
- DWORD *pdwResourceFlags) // [OUT] Flags.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumAssemblyRefs ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdAssemblyRef rAssemblyRefs[], // [OUT] Put AssemblyRefs here.
- ULONG cMax, // [IN] Max AssemblyRefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- HENUMInternal **ppmdEnum = reinterpret_cast<HENUMInternal **> (phEnum);
- HRESULT hr = NOERROR;
- HENUMInternal *pEnum;
-
- if (*ppmdEnum == NULL)
- {
- // create the enumerator.
- IfFailGo(HENUMInternal::CreateSimpleEnum(
- mdtAssemblyRef,
- 0,
- 1,
- &pEnum));
-
- IfFailGo(m_pMDInternalImport->EnumInit(mdtAssemblyRef, 0, pEnum));
-
- // set the output parameter.
- *ppmdEnum = pEnum;
- }
- else
- {
- pEnum = *ppmdEnum;
- }
-
- // we can only fill the minimum of what the caller asked for or what we have left.
- IfFailGo(HENUMInternal::EnumWithCount(pEnum, cMax, rAssemblyRefs, pcTokens));
-ErrExit:
- HENUMInternal::DestroyEnumIfEmpty(ppmdEnum);
-
- return hr;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumFiles ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdFile rFiles[], // [OUT] Put Files here.
- ULONG cMax, // [IN] Max Files to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- HENUMInternal **ppmdEnum = reinterpret_cast<HENUMInternal **> (phEnum);
- HRESULT hr = NOERROR;
- HENUMInternal *pEnum;
-
- if (*ppmdEnum == NULL)
- {
- // create the enumerator.
- IfFailGo(HENUMInternal::CreateSimpleEnum(
- mdtFile,
- 0,
- 1,
- &pEnum));
-
- IfFailGo(m_pMDInternalImport->EnumInit(mdtFile, 0, pEnum));
-
- // set the output parameter.
- *ppmdEnum = pEnum;
- }
- else
- {
- pEnum = *ppmdEnum;
- }
-
- // we can only fill the minimum of what the caller asked for or what we have left.
- IfFailGo(HENUMInternal::EnumWithCount(pEnum, cMax, rFiles, pcTokens));
-
-ErrExit:
- HENUMInternal::DestroyEnumIfEmpty(ppmdEnum);
- return hr;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumExportedTypes ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdExportedType rExportedTypes[], // [OUT] Put ExportedTypes here.
- ULONG cMax, // [IN] Max ExportedTypes to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumManifestResources ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdManifestResource rManifestResources[], // [OUT] Put ManifestResources here.
- ULONG cMax, // [IN] Max Resources to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetAssemblyFromScope ( // S_OK or error
- mdAssembly *ptkAssembly) // [OUT] Put token here.
-{
- return m_pMDInternalImport->GetAssemblyFromScope (ptkAssembly);
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindExportedTypeByName (// S_OK or error
- LPCWSTR szName, // [IN] Name of the ExportedType.
- mdToken mdtExportedType, // [IN] ExportedType for the enclosing class.
- mdExportedType *ptkExportedType) // [OUT] Put the ExportedType token here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindManifestResourceByName ( // S_OK or error
- LPCWSTR szName, // [IN] Name of the ManifestResource.
- mdManifestResource *ptkManifestResource) // [OUT] Put the ManifestResource token here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-void AssemblyMDInternalImport::CloseEnum (
- HCORENUM hEnum) // Enum to be closed.
-{
- HENUMInternal *pmdEnum = reinterpret_cast<HENUMInternal *> (hEnum);
-
- if (pmdEnum == NULL)
- return;
-
- HENUMInternal::DestroyEnum(pmdEnum);
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindAssembliesByName ( // S_OK or error
- LPCWSTR szAppBase, // [IN] optional - can be NULL
- LPCWSTR szPrivateBin, // [IN] optional - can be NULL
- LPCWSTR szAssemblyName, // [IN] required - this is the assembly you are requesting
- IUnknown *ppIUnk[], // [OUT] put IMetaDataAssemblyImport pointers here
- ULONG cMax, // [IN] The max number to put
- ULONG *pcAssemblies) // [OUT] The number of assemblies returned.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::CountEnum (HCORENUM hEnum, ULONG *pulCount)
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::ResetEnum (HCORENUM hEnum, ULONG ulPos)
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumTypeDefs (HCORENUM *phEnum, mdTypeDef rTypeDefs[],
- ULONG cMax, ULONG *pcTypeDefs)
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumInterfaceImpls (HCORENUM *phEnum, mdTypeDef td,
- mdInterfaceImpl rImpls[], ULONG cMax,
- ULONG* pcImpls)
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumTypeRefs (HCORENUM *phEnum, mdTypeRef rTypeRefs[],
- ULONG cMax, ULONG* pcTypeRefs)
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindTypeDefByName ( // S_OK or error.
- LPCWSTR szTypeDef, // [IN] Name of the Type.
- mdToken tkEnclosingClass, // [IN] TypeDef/TypeRef for Enclosing class.
- mdTypeDef *ptd) // [OUT] Put the TypeDef token here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetScopeProps ( // S_OK or error.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Put the name here.
- ULONG cchName, // [IN] Size of name buffer in wide chars.
- ULONG *pchName, // [OUT] Put size of name (wide chars) here.
- GUID *pmvid) // [OUT, OPTIONAL] Put MVID here.
-{
- HRESULT hr;
- LPCSTR _szName;
-
- if (!m_pMDInternalImport->IsValidToken(m_pMDInternalImport->GetModuleFromScope()))
- return COR_E_BADIMAGEFORMAT;
-
- IfFailRet(m_pMDInternalImport->GetScopeProps(&_szName, pmvid));
-
- if (pchName != NULL)
- {
- *pchName = WszMultiByteToWideChar(CP_UTF8, 0, _szName, -1, szName, cchName);
- if (*pchName == 0)
- {
- return HRESULT_FROM_GetLastError();
- }
- }
-
- return S_OK;
-
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetModuleFromScope ( // S_OK.
- mdModule *pmd) // [OUT] Put mdModule token here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetTypeDefProps ( // S_OK or error.
- mdTypeDef td, // [IN] TypeDef token for inquiry.
- __out_ecount (cchTypeDef) LPWSTR szTypeDef, // [OUT] Put name here.
- ULONG cchTypeDef, // [IN] size of name buffer in wide chars.
- ULONG *pchTypeDef, // [OUT] put size of name (wide chars) here.
- DWORD *pdwTypeDefFlags, // [OUT] Put flags here.
- mdToken *ptkExtends) // [OUT] Put base class TypeDef/TypeRef here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetInterfaceImplProps ( // S_OK or error.
- mdInterfaceImpl iiImpl, // [IN] InterfaceImpl token.
- mdTypeDef *pClass, // [OUT] Put implementing class token here.
- mdToken *ptkIface) // [OUT] Put implemented interface token here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetTypeRefProps ( // S_OK or error.
- mdTypeRef tr, // [IN] TypeRef token.
- mdToken *ptkResolutionScope, // [OUT] Resolution scope, ModuleRef or AssemblyRef.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Name of the TypeRef.
- ULONG cchName, // [IN] Size of buffer.
- ULONG *pchName) // [OUT] Size of Name.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::ResolveTypeRef (mdTypeRef tr, REFIID riid, IUnknown **ppIScope, mdTypeDef *ptd)
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMembers ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- mdToken rMembers[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMembersWithName ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- LPCWSTR szName, // [IN] Limit results to those with this name.
- mdToken rMembers[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMethods ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- mdMethodDef rMethods[], // [OUT] Put MethodDefs here.
- ULONG cMax, // [IN] Max MethodDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMethodsWithName ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- LPCWSTR szName, // [IN] Limit results to those with this name.
- mdMethodDef rMethods[], // [OU] Put MethodDefs here.
- ULONG cMax, // [IN] Max MethodDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumFields ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- mdFieldDef rFields[], // [OUT] Put FieldDefs here.
- ULONG cMax, // [IN] Max FieldDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumFieldsWithName ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- LPCWSTR szName, // [IN] Limit results to those with this name.
- mdFieldDef rFields[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-
-STDMETHODIMP AssemblyMDInternalImport::EnumParams ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdMethodDef mb, // [IN] MethodDef to scope the enumeration.
- mdParamDef rParams[], // [OUT] Put ParamDefs here.
- ULONG cMax, // [IN] Max ParamDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMemberRefs ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tkParent, // [IN] Parent token to scope the enumeration.
- mdMemberRef rMemberRefs[], // [OUT] Put MemberRefs here.
- ULONG cMax, // [IN] Max MemberRefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMethodImpls ( // S_OK, S_FALSE, or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef td, // [IN] TypeDef to scope the enumeration.
- mdToken rMethodBody[], // [OUT] Put Method Body tokens here.
- mdToken rMethodDecl[], // [OUT] Put Method Declaration tokens here.
- ULONG cMax, // [IN] Max tokens to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumPermissionSets ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tk, // [IN] if !NIL, token to scope the enumeration.
- DWORD dwActions, // [IN] if !0, return only these actions.
- mdPermission rPermission[], // [OUT] Put Permissions here.
- ULONG cMax, // [IN] Max Permissions to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindMember (
- mdTypeDef td, // [IN] given typedef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdToken *pmb) // [OUT] matching memberdef
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindMethod (
- mdTypeDef td, // [IN] given typedef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdMethodDef *pmb) // [OUT] matching memberdef
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindField (
- mdTypeDef td, // [IN] given typedef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdFieldDef *pmb) // [OUT] matching memberdef
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindMemberRef (
- mdTypeRef td, // [IN] given typeRef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdMemberRef *pmr) // [OUT] matching memberref
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetMethodProps (
- mdMethodDef mb, // The method for which to get props.
- mdTypeDef *pClass, // Put method's class here.
- __out_ecount (cchMethod) LPWSTR szMethod, // Put method's name here.
- ULONG cchMethod, // Size of szMethod buffer in wide chars.
- ULONG *pchMethod, // Put actual size here
- DWORD *pdwAttr, // Put flags here.
- PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data
- ULONG *pcbSigBlob, // [OUT] actual size of signature blob
- ULONG *pulCodeRVA, // [OUT] codeRVA
- DWORD *pdwImplFlags) // [OUT] Impl. Flags
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetMemberRefProps ( // S_OK or error.
- mdMemberRef mr, // [IN] given memberref
- mdToken *ptk, // [OUT] Put classref or classdef here.
- __out_ecount (cchMember) LPWSTR szMember, // [OUT] buffer to fill for member's name
- ULONG cchMember, // [IN] the count of char of szMember
- ULONG *pchMember, // [OUT] actual count of char in member name
- PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to meta data blob value
- ULONG *pbSig) // [OUT] actual size of signature blob
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumProperties ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef td, // [IN] TypeDef to scope the enumeration.
- mdProperty rProperties[], // [OUT] Put Properties here.
- ULONG cMax, // [IN] Max properties to put.
- ULONG *pcProperties) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumEvents ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef td, // [IN] TypeDef to scope the enumeration.
- mdEvent rEvents[], // [OUT] Put events here.
- ULONG cMax, // [IN] Max events to put.
- ULONG *pcEvents) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetEventProps ( // S_OK, S_FALSE, or error.
- mdEvent ev, // [IN] event token
- mdTypeDef *pClass, // [OUT] typedef containing the event declarion.
- LPCWSTR szEvent, // [OUT] Event name
- ULONG cchEvent, // [IN] the count of wchar of szEvent
- ULONG *pchEvent, // [OUT] actual count of wchar for event's name
- DWORD *pdwEventFlags, // [OUT] Event flags.
- mdToken *ptkEventType, // [OUT] EventType class
- mdMethodDef *pmdAddOn, // [OUT] AddOn method of the event
- mdMethodDef *pmdRemoveOn, // [OUT] RemoveOn method of the event
- mdMethodDef *pmdFire, // [OUT] Fire method of the event
- mdMethodDef rmdOtherMethod[], // [OUT] other method of the event
- ULONG cMax, // [IN] size of rmdOtherMethod
- ULONG *pcOtherMethod) // [OUT] total number of other method of this event
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMethodSemantics ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdMethodDef mb, // [IN] MethodDef to scope the enumeration.
- mdToken rEventProp[], // [OUT] Put Event/Property here.
- ULONG cMax, // [IN] Max properties to put.
- ULONG *pcEventProp) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetMethodSemantics ( // S_OK, S_FALSE, or error.
- mdMethodDef mb, // [IN] method token
- mdToken tkEventProp, // [IN] event/property token.
- DWORD *pdwSemanticsFlags) // [OUT] the role flags for the method/propevent pair
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetClassLayout (
- mdTypeDef td, // [IN] give typedef
- DWORD *pdwPackSize, // [OUT] 1, 2, 4, 8, or 16
- COR_FIELD_OFFSET rFieldOffset[], // [OUT] field offset array
- ULONG cMax, // [IN] size of the array
- ULONG *pcFieldOffset, // [OUT] needed array size
- ULONG *pulClassSize) // [OUT] the size of the class
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetFieldMarshal (
- mdToken tk, // [IN] given a field's memberdef
- PCCOR_SIGNATURE *ppvNativeType, // [OUT] native type of this field
- ULONG *pcbNativeType) // [OUT] the count of bytes of *ppvNativeType
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetRVA ( // S_OK or error.
- mdToken tk, // Member for which to set offset
- ULONG *pulCodeRVA, // The offset
- DWORD *pdwImplFlags) // the implementation flags
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetPermissionSetProps (
- mdPermission pm, // [IN] the permission token.
- DWORD *pdwAction, // [OUT] CorDeclSecurity.
- void const **ppvPermission, // [OUT] permission blob.
- ULONG *pcbPermission) // [OUT] count of bytes of pvPermission.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetSigFromToken ( // S_OK or error.
- mdSignature mdSig, // [IN] Signature token.
- PCCOR_SIGNATURE *ppvSig, // [OUT] return pointer to token.
- ULONG *pcbSig) // [OUT] return size of signature.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetModuleRefProps ( // S_OK or error.
- mdModuleRef mur, // [IN] moduleref token.
- __out_ecount (cchName) LPWSTR szName, // [OUT] buffer to fill with the moduleref name.
- ULONG cchName, // [IN] size of szName in wide characters.
- ULONG *pchName) // [OUT] actual count of characters in the name.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumModuleRefs ( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] pointer to the enum.
- mdModuleRef rModuleRefs[], // [OUT] put modulerefs here.
- ULONG cmax, // [IN] max memberrefs to put.
- ULONG *pcModuleRefs) // [OUT] put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetTypeSpecFromToken ( // S_OK or error.
- mdTypeSpec typespec, // [IN] TypeSpec token.
- PCCOR_SIGNATURE *ppvSig, // [OUT] return pointer to TypeSpec signature
- ULONG *pcbSig) // [OUT] return size of signature.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetNameFromToken ( // Not Recommended! May be removed!
- mdToken tk, // [IN] Token to get name from. Must have a name.
- MDUTF8CSTR *pszUtf8NamePtr) // [OUT] Return pointer to UTF8 name in heap.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumUnresolvedMethods ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken rMethods[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetUserString ( // S_OK or error.
- mdString stk, // [IN] String token.
- __out_ecount (cchString) LPWSTR szString, // [OUT] Copy of string.
- ULONG cchString, // [IN] Max chars of room in szString.
- ULONG *pchString) // [OUT] How many chars in actual string.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetPinvokeMap ( // S_OK or error.
- mdToken tk, // [IN] FieldDef or MethodDef.
- DWORD *pdwMappingFlags, // [OUT] Flags used for mapping.
- __out_ecount (cchImportName) LPWSTR szImportName, // [OUT] Import name.
- ULONG cchImportName, // [IN] Size of the name buffer.
- ULONG *pchImportName, // [OUT] Actual number of characters stored.
- mdModuleRef *pmrImportDLL) // [OUT] ModuleRef token for the target DLL.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumSignatures ( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] pointer to the enum.
- mdSignature rSignatures[], // [OUT] put signatures here.
- ULONG cmax, // [IN] max signatures to put.
- ULONG *pcSignatures) // [OUT] put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumTypeSpecs ( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] pointer to the enum.
- mdTypeSpec rTypeSpecs[], // [OUT] put TypeSpecs here.
- ULONG cmax, // [IN] max TypeSpecs to put.
- ULONG *pcTypeSpecs) // [OUT] put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumUserStrings ( // S_OK or error.
- HCORENUM *phEnum, // [IN/OUT] pointer to the enum.
- mdString rStrings[], // [OUT] put Strings here.
- ULONG cmax, // [IN] max Strings to put.
- ULONG *pcStrings) // [OUT] put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetParamForMethodIndex ( // S_OK or error.
- mdMethodDef md, // [IN] Method token.
- ULONG ulParamSeq, // [IN] Parameter sequence.
- mdParamDef *ppd) // [IN] Put Param token here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumCustomAttributes ( // S_OK or error.
- HCORENUM *phEnum, // [IN, OUT] COR enumerator.
- mdToken tk, // [IN] Token to scope the enumeration, 0 for all.
- mdToken tkType, // [IN] Type of interest, 0 for all.
- mdCustomAttribute rCustomAttributes[], // [OUT] Put custom attribute tokens here.
- ULONG cMax, // [IN] Size of rCustomAttributes.
- ULONG *pcCustomAttributes) // [OUT, OPTIONAL] Put count of token values here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetCustomAttributeProps ( // S_OK or error.
- mdCustomAttribute cv, // [IN] CustomAttribute token.
- mdToken *ptkObj, // [OUT, OPTIONAL] Put object token here.
- mdToken *ptkType, // [OUT, OPTIONAL] Put AttrType token here.
- void const **ppBlob, // [OUT, OPTIONAL] Put pointer to data here.
- ULONG *pcbSize) // [OUT, OPTIONAL] Put size of date here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindTypeRef (
- mdToken tkResolutionScope, // [IN] ModuleRef, AssemblyRef or TypeRef.
- LPCWSTR szName, // [IN] TypeRef Name.
- mdTypeRef *ptr) // [OUT] matching TypeRef.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetMemberProps (
- mdToken mb, // The member for which to get props.
- mdTypeDef *pClass, // Put member's class here.
- __out_ecount (cchMember) LPWSTR szMember, // Put member's name here.
- ULONG cchMember, // Size of szMember buffer in wide chars.
- ULONG *pchMember, // Put actual size here
- DWORD *pdwAttr, // Put flags here.
- PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data
- ULONG *pcbSigBlob, // [OUT] actual size of signature blob
- ULONG *pulCodeRVA, // [OUT] codeRVA
- DWORD *pdwImplFlags, // [OUT] Impl. Flags
- DWORD *pdwCPlusTypeFlag, // [OUT] flag for value type. selected ELEMENT_TYPE_*
- UVCP_CONSTANT *ppValue, // [OUT] constant value
- ULONG *pcchValue) // [OUT] size of constant string in chars, 0 for non-strings.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetFieldProps (
- mdFieldDef mb, // The field for which to get props.
- mdTypeDef *pClass, // Put field's class here.
- __out_ecount (cchField) LPWSTR szField, // Put field's name here.
- ULONG cchField, // Size of szField buffer in wide chars.
- ULONG *pchField, // Put actual size here
- DWORD *pdwAttr, // Put flags here.
- PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data
- ULONG *pcbSigBlob, // [OUT] actual size of signature blob
- DWORD *pdwCPlusTypeFlag, // [OUT] flag for value type. selected ELEMENT_TYPE_*
- UVCP_CONSTANT *ppValue, // [OUT] constant value
- ULONG *pcchValue) // [OUT] size of constant string in chars, 0 for non-strings.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetPropertyProps ( // S_OK, S_FALSE, or error.
- mdProperty prop, // [IN] property token
- mdTypeDef *pClass, // [OUT] typedef containing the property declarion.
- LPCWSTR szProperty, // [OUT] Property name
- ULONG cchProperty, // [IN] the count of wchar of szProperty
- ULONG *pchProperty, // [OUT] actual count of wchar for property name
- DWORD *pdwPropFlags, // [OUT] property flags.
- PCCOR_SIGNATURE *ppvSig, // [OUT] property type. pointing to meta data internal blob
- ULONG *pbSig, // [OUT] count of bytes in *ppvSig
- DWORD *pdwCPlusTypeFlag, // [OUT] flag for value type. selected ELEMENT_TYPE_*
- UVCP_CONSTANT *ppDefaultValue, // [OUT] constant value
- ULONG *pcchDefaultValue, // [OUT] size of constant string in chars, 0 for non-strings.
- mdMethodDef *pmdSetter, // [OUT] setter method of the property
- mdMethodDef *pmdGetter, // [OUT] getter method of the property
- mdMethodDef rmdOtherMethod[], // [OUT] other method of the property
- ULONG cMax, // [IN] size of rmdOtherMethod
- ULONG *pcOtherMethod) // [OUT] total number of other method of this property
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetParamProps ( // S_OK or error.
- mdParamDef tk, // [IN]The Parameter.
- mdMethodDef *pmd, // [OUT] Parent Method token.
- ULONG *pulSequence, // [OUT] Parameter sequence.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Put name here.
- ULONG cchName, // [OUT] Size of name buffer.
- ULONG *pchName, // [OUT] Put actual size of name here.
- DWORD *pdwAttr, // [OUT] Put flags here.
- DWORD *pdwCPlusTypeFlag, // [OUT] Flag for value type. selected ELEMENT_TYPE_*.
- UVCP_CONSTANT *ppValue, // [OUT] Constant value.
- ULONG *pcchValue) // [OUT] size of constant string in chars, 0 for non-strings.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetCustomAttributeByName ( // S_OK or error.
- mdToken tkObj, // [IN] Object with Custom Attribute.
- LPCWSTR szName, // [IN] Name of desired Custom Attribute.
- const void **ppData, // [OUT] Put pointer to data here.
- ULONG *pcbData) // [OUT] Put size of data here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-BOOL AssemblyMDInternalImport::IsValidToken ( // True or False.
- mdToken tk) // [IN] Given token.
-{
- _ASSERTE(!"NYI");
- return FALSE;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetNestedClassProps ( // S_OK or error.
- mdTypeDef tdNestedClass, // [IN] NestedClass token.
- mdTypeDef *ptdEnclosingClass) // [OUT] EnclosingClass token.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetNativeCallConvFromSig ( // S_OK or error.
- void const *pvSig, // [IN] Pointer to signature.
- ULONG cbSig, // [IN] Count of signature bytes.
- ULONG *pCallConv) // [OUT] Put calling conv here (see CorPinvokemap).
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::IsGlobal ( // S_OK or error.
- mdToken pd, // [IN] Type, Field, or Method token.
- int *pbGlobal) // [OUT] Put 1 if global, 0 otherwise.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetMethodSpecProps(
- mdMethodSpec mi, // [IN] The method instantiation
- mdToken *tkParent, // [OUT] MethodDef or MemberRef
- PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data
- ULONG *pcbSigBlob) // [OUT] actual size of signature blob
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-// *** ISNAssemblySignature methods ***
-
-STDMETHODIMP AssemblyMDInternalImport::GetSNAssemblySignature(
- BYTE *pbSig, // [IN, OUT] Buffer to write signature
- DWORD *pcbSig) // [IN, OUT] Size of buffer, bytes written
-{
- return RuntimeGetAssemblyStrongNameHashForModule(m_pHandle, this, pbSig, pcbSig);
-}
-
-
-#include "strongname.h"
-
-#ifdef FEATURE_PREJIT
-// *** IGetIMDInternalImport ***
-STDMETHODIMP AssemblyMDInternalImport::GetIMDInternalImport(
- IMDInternalImport ** pIMDInternalImport)
-{
- m_pMDInternalImport->AddRef();
- *pIMDInternalImport = m_pMDInternalImport;
- return S_OK;
-}
-
-
-
-// ===========================================================================
-
-class CNativeImageDependency : public INativeImageDependency
-{
-public:
- CNativeImageDependency(CORCOMPILE_DEPENDENCY * pDependency)
- : m_cRef(1), m_pDependency(pDependency)
- {
- }
-
- ~CNativeImageDependency()
- {
- }
-
- //
- // IUnknown
- //
-
- STDMETHODIMP_(ULONG) AddRef()
- {
- return InterlockedIncrement(&m_cRef);
- }
-
- STDMETHODIMP_(ULONG) Release()
- {
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (!cRef)
- delete this;
- return (cRef);
- }
-
- STDMETHODIMP QueryInterface(REFIID riid, void **ppUnk)
- {
- *ppUnk = 0;
-
- if (riid == IID_IUnknown)
- *ppUnk = (IUnknown *) (IMetaDataAssemblyImport *) this;
- else if (riid == IID_INativeImageDependency)
- *ppUnk = (INativeImageDependency *) this;
- else
- return (E_NOINTERFACE);
- AddRef();
- return (S_OK);
- }
-
- //
- // INativeImageDependency
- //
-
- STDMETHODIMP GetILAssemblyRef(mdAssemblyRef * pAssemblyRef)
- {
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pAssemblyRef = m_pDependency->dwAssemblyRef;
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
- }
-
- STDMETHODIMP GetILAssemblyDef(
- mdAssemblyRef * ppAssemblyDef,
- CORCOMPILE_ASSEMBLY_SIGNATURE * pSign)
- {
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *ppAssemblyDef = m_pDependency->dwAssemblyDef;
- *pSign = m_pDependency->signAssemblyDef;
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
- }
-
- STDMETHODIMP GetNativeAssemblyDef(CORCOMPILE_NGEN_SIGNATURE * pNativeSign)
- {
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pNativeSign = m_pDependency->signNativeImage;
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
- }
-
- STDMETHODIMP GetPEKind(PEKIND *pPEKind)
- {
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pPEKind = PEKIND((m_pDependency->dependencyInfo & CORCOMPILE_DEPENDENCY_PEKIND_MASK) >> CORCOMPILE_DEPENDENCY_PEKIND_SHIFT);
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
- }
-
-protected:
-
- LONG m_cRef;
- CORCOMPILE_DEPENDENCY * m_pDependency;
-};
-
-// ===========================================================================
-// *** INativeImageInstallInfo ***
-// ===========================================================================
-
-STDMETHODIMP AssemblyMDInternalImport::GetSignature(CORCOMPILE_NGEN_SIGNATURE * pNgenSign)
-{
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pNgenSign = m_pZapVersionInfo->signature;
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetVersionInfo(CORCOMPILE_VERSION_INFO * pVersionInfo)
-{
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pVersionInfo = *m_pZapVersionInfo;
- END_ENTRYPOINT_NOTHROW;
- return S_OK;
-}
-
-
-
-STDMETHODIMP AssemblyMDInternalImport::GetILSignature(CORCOMPILE_ASSEMBLY_SIGNATURE * pILSign)
-{
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pILSign = m_pZapVersionInfo->sourceAssembly;
- END_ENTRYPOINT_NOTHROW;
- return S_OK;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetConfigMask(DWORD * pConfigMask)
-{
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pConfigMask = m_pZapVersionInfo->wConfigFlags;
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumDependencies (
- HCORENUM * phEnum, // [IN/OUT] - Pointer to the enum
- INativeImageDependency *rDeps[], // [OUT]
- ULONG cMax, // Max dependancies to enumerate in this iteration
- DWORD * pdwCount // [OUT] - Number of dependancies actually enumerated
- )
-{
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- CORCOMPILE_DEPENDENCY * pDependenciesEnd = m_pZapDependencies + m_cZapDependencies;
-
- CORCOMPILE_DEPENDENCY * pNextDependency;
-
- // Is the enum just being initialized, or are we walking an existing one?
- if ((*phEnum) == NULL)
- pNextDependency = m_pZapDependencies;
- else
- pNextDependency = (CORCOMPILE_DEPENDENCY *)(*phEnum);
-
- DWORD count;
- for (count = 0;
- pNextDependency < pDependenciesEnd && count < cMax;
- count++, pNextDependency++)
- {
- CNativeImageDependency * pDep = new (nothrow) CNativeImageDependency(pNextDependency);
- IfNullGo( pDep );
-
- rDeps[count] = pDep;
- }
-
- *phEnum = (HCORENUM)(pNextDependency < pDependenciesEnd) ? pNextDependency : NULL;
- *pdwCount = count;
-
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-
-STDMETHODIMP AssemblyMDInternalImport::GetDependency (
- const CORCOMPILE_NGEN_SIGNATURE *pcngenSign, // [IN] ngenSig of dependency you want
- CORCOMPILE_DEPENDENCY *pDep // [OUT] matching dependency
- )
-{
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- _ASSERTE(pcngenSign != NULL);
- _ASSERTE(*pcngenSign != INVALID_NGEN_SIGNATURE);
- _ASSERTE(pDep != NULL);
-
- CORCOMPILE_DEPENDENCY * pDependenciesEnd = m_pZapDependencies + m_cZapDependencies;
- CORCOMPILE_DEPENDENCY * pNextDependency = m_pZapDependencies;
- while (pNextDependency != pDependenciesEnd)
- {
- if (pNextDependency->signNativeImage == *pcngenSign)
- {
- *pDep = *pNextDependency;
- hr = S_OK;
- goto ErrExit;
- }
- pNextDependency++;
- }
- hr = S_FALSE;
-
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-
-#endif // FEATURE_PREJIT
-
-
-//*****************************************************************************
-// IMetaDataImport2 methods
-//*****************************************************************************
-STDMETHODIMP AssemblyMDInternalImport::GetGenericParamProps( // S_OK or error.
- mdGenericParam gp, // [IN] GenericParam
- ULONG *pulParamSeq, // [OUT] Index of the type parameter
- DWORD *pdwParamFlags, // [OUT] Flags, for future use (e.g. variance)
- mdToken *ptOwner, // [OUT] Owner (TypeDef or MethodDef)
- DWORD *reserved, // [OUT] For future use (e.g. non-type parameters)
- __out_ecount (cchName) LPWSTR wzname, // [OUT] Put name here
- ULONG cchName, // [IN] Size of buffer
- ULONG *pchName) // [OUT] Put size of name (wide chars) here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetGenericParamConstraintProps( // S_OK or error.
- mdGenericParamConstraint gpc, // [IN] GenericParamConstraint
- mdGenericParam *ptGenericParam, // [OUT] GenericParam that is constrained
- mdToken *ptkConstraintType) // [OUT] TypeDef/Ref/Spec constraint
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumGenericParams( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tk, // [IN] TypeDef or MethodDef whose generic parameters are requested
- mdGenericParam rGenericParams[], // [OUT] Put GenericParams here.
- ULONG cMax, // [IN] Max GenericParams to put.
- ULONG *pcGenericParams) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumGenericParamConstraints( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdGenericParam tk, // [IN] GenericParam whose constraints are requested
- mdGenericParamConstraint rGenericParamConstraints[], // [OUT] Put GenericParamConstraints here.
- ULONG cMax, // [IN] Max GenericParamConstraints to put.
- ULONG *pcGenericParamConstraints) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMethodSpecs( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tk, // [IN] MethodDef or MemberRef whose MethodSpecs are requested
- mdMethodSpec rMethodSpecs[], // [OUT] Put MethodSpecs here.
- ULONG cMax, // [IN] Max tokens to put.
- ULONG *pcMethodSpecs) // [OUT] Put actual count here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetPEKind( // S_OK or error.
- DWORD* pdwPEKind, // [OUT] The kind of PE (0 - not a PE)
- DWORD* pdwMachine) // [OUT] Machine as defined in NT header
-{
- HRESULT hr = S_OK;
- if(pdwPEKind) *pdwPEKind = m_dwPEKind;
- if(pdwMachine) *pdwMachine = m_dwMachine;
- return hr;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetVersionString( // S_OK or error.
- __out_ecount (ccBufSize) LPWSTR pwzBuf, // Put version string here.
- DWORD ccBufSize, // [in] size of the buffer, in wide chars
- DWORD *pccBufSize) // [out] Size of the version string, wide chars, including terminating nul.
-{
- HRESULT hr=S_OK;
- DWORD L = WszMultiByteToWideChar(CP_UTF8,0,m_szVersionString,-1,pwzBuf,ccBufSize);
- if(ccBufSize < L)
- hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
-
- if(pccBufSize) *pccBufSize = L;
- return hr;
-}
-
-#endif //!DACCESS_COMPILE
-
-#endif // FEATURE_FUSION
#endif //FEATURE_METADATA_INTERNAL_APIS
diff --git a/src/md/runtime/metamodel.cpp b/src/md/runtime/metamodel.cpp
index 293e5b6b5e..83addc6d6c 100644
--- a/src/md/runtime/metamodel.cpp
+++ b/src/md/runtime/metamodel.cpp
@@ -519,7 +519,6 @@ CMiniMdBase::SchemaPopulate(
{
// No it's not. Is this an older version that we support?
-#ifndef FEATURE_METADATA_STANDALONE_WINRT
// Is this v1.0?
if ((m_Schema.m_major == METAMODEL_MAJOR_VER_V1_0) &&
(m_Schema.m_minor == METAMODEL_MINOR_VER_V1_0))
@@ -535,7 +534,6 @@ CMiniMdBase::SchemaPopulate(
m_TableDefs[TBL_GenericParam].m_pColDefs = BYTEARRAY_TO_COLDES(s_GenericParamCol);
}
else
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
{ // We don't support this version of the metadata
Debug_ReportError("Unsupported version of MetaData.");
return PostError(CLDB_E_FILE_OLDVER, m_Schema.m_major, m_Schema.m_minor);
diff --git a/src/md/runtime/wks/CMakeLists.txt b/src/md/runtime/wks/CMakeLists.txt
index 9a1f72ed25..3e2a8cc6be 100644
--- a/src/md/runtime/wks/CMakeLists.txt
+++ b/src/md/runtime/wks/CMakeLists.txt
@@ -1,5 +1,7 @@
include(../../md_wks.cmake)
+add_definitions(-DFEATURE_METADATA_EMIT_ALL)
+
add_precompiled_header(stdafx.h ../stdafx.cpp MDRUNTIME_SOURCES)
add_library_clr(mdruntime_wks ${MDRUNTIME_SOURCES})
diff --git a/src/md/winmd/adapter.cpp b/src/md/winmd/adapter.cpp
index 2c9dd1b9fd..d4e95b7f8b 100644
--- a/src/md/winmd/adapter.cpp
+++ b/src/md/winmd/adapter.cpp
@@ -1185,14 +1185,12 @@ void WinMDAdapter::GetExtraAssemblyRefProps(FrameworkAssemblyIndex index,
if (ppPublicKeytoken)
{
-#ifdef FEATURE_CORECLR
if (index == FrameworkAssembly_Mscorlib)
{
*ppPublicKeytoken = g_rbTheSilverlightPlatformKeyToken;
*pTokenLength = sizeof(g_rbTheSilverlightPlatformKeyToken);
}
else
-#endif
{
if (index == FrameworkAssembly_SystemNumericsVectors || index == FrameworkAssembly_SystemRuntime || index == FrameworkAssembly_SystemObjectModel)
{
diff --git a/src/md/winmd/inc/adapter.h b/src/md/winmd/inc/adapter.h
index e42992f81f..cc422017b6 100644
--- a/src/md/winmd/inc/adapter.h
+++ b/src/md/winmd/inc/adapter.h
@@ -236,14 +236,12 @@ public:
if (pusRevisionNumber != nullptr)
*pusRevisionNumber = VER_ASSEMBLYBUILD_QFE;
-#ifdef FEATURE_CORECLR
// Under CoreCLR, we replace the ECMA key in the mscorlib assembly ref with the CoreCLR platform public key token
if (ppbPublicKeyOrToken != nullptr)
{
*ppbPublicKeyOrToken = g_rbTheSilverlightPlatformKeyToken;
*pcbPublicKeyOrToken = _countof(g_rbTheSilverlightPlatformKeyToken);
}
-#endif
}
else if (RidFromToken(mdar) > m_rawAssemblyRefCount)
{
@@ -632,11 +630,7 @@ public:
case FrameworkAssembly_SystemRuntimeWindowsRuntimeUIXaml:
return "System.Runtime.WindowsRuntime.UI.Xaml";
case FrameworkAssembly_SystemNumericsVectors:
-#ifdef FEATURE_CORECLR
return "System.Numerics.Vectors";
-#else
- return "System.Numerics";
-#endif
default:
_ASSERTE(!"Invalid AssemblyRef token!");
return NULL;
diff --git a/src/md/winmd/wks/CMakeLists.txt b/src/md/winmd/wks/CMakeLists.txt
index 139b68b28c..defcc1d51d 100644
--- a/src/md/winmd/wks/CMakeLists.txt
+++ b/src/md/winmd/wks/CMakeLists.txt
@@ -1,4 +1,6 @@
include(../../md_wks.cmake)
+add_definitions(-DFEATURE_METADATA_EMIT_ALL)
+
add_precompiled_header(stdafx.h ../stdafx.cpp MDWINMD_SOURCES)
-add_library_clr(mdwinmd_wks ${MDWINMD_SOURCES}) \ No newline at end of file
+add_library_clr(mdwinmd_wks ${MDWINMD_SOURCES})
diff --git a/src/mscorlib/Common/NotImplemented.cs b/src/mscorlib/Common/NotImplemented.cs
new file mode 100644
index 0000000000..82f4e18ddc
--- /dev/null
+++ b/src/mscorlib/Common/NotImplemented.cs
@@ -0,0 +1,34 @@
+// 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.
+
+namespace System
+{
+ //
+ // This simple class enables one to throw a NotImplementedException using the following
+ // idiom:
+ //
+ // throw NotImplemented.ByDesign;
+ //
+ // Used by methods whose intended implementation is to throw a NotImplementedException (typically
+ // virtual methods in public abstract classes that intended to be subclassed by third parties.)
+ //
+ // This makes it distinguishable both from human eyes and CCI from NYI's that truly represent undone work.
+ //
+ internal static class NotImplemented
+ {
+ internal static Exception ByDesign
+ {
+ get
+ {
+ return new NotImplementedException();
+ }
+ }
+
+ internal static Exception ByDesignWithMessage(string message)
+ {
+ return new NotImplementedException(message);
+ }
+ }
+}
+
diff --git a/src/mscorlib/Common/PinnableBufferCache.cs b/src/mscorlib/Common/PinnableBufferCache.cs
index 6c85a5a2f6..3f7853ce59 100644
--- a/src/mscorlib/Common/PinnableBufferCache.cs
+++ b/src/mscorlib/Common/PinnableBufferCache.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
#define ENABLE
#define MINBUFFERS
+
using System;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
@@ -20,7 +21,6 @@ namespace System
{
internal sealed class PinnableBufferCache
{
-
/// <summary>
/// Create a PinnableBufferCache that works on any object (it is intended for OverlappedData)
/// This is only used in mscorlib.
@@ -519,22 +519,22 @@ namespace System
public static readonly PinnableBufferCacheEventSource Log = new PinnableBufferCacheEventSource();
public bool IsEnabled() { return false; }
- public void DebugMessage(string message) {}
- public void Create(string cacheName) {}
- public void AllocateBuffer(string cacheName, ulong objectId, int objectHash, int objectGen, int freeCountAfter) {}
- public void AllocateBufferFromNotGen2(string cacheName, int notGen2CountAfter) {}
- public void AllocateBufferCreatingNewBuffers(string cacheName, int totalBuffsBefore, int objectCount) {}
- public void AllocateBufferAged(string cacheName, int agedCount) {}
- public void AllocateBufferFreeListEmpty(string cacheName, int notGen2CountBefore) {}
- public void FreeBuffer(string cacheName, ulong objectId, int objectHash, int freeCountBefore) {}
- public void FreeBufferStillTooYoung(string cacheName, int notGen2CountBefore) {}
- public void TrimCheck(string cacheName, int totalBuffs, bool neededMoreThanFreeList, int deltaMSec) {}
- public void TrimFree(string cacheName, int totalBuffs, int freeListCount, int toBeFreed) {}
- public void TrimExperiment(string cacheName, int totalBuffs, int freeListCount, int numTrimTrial) {}
- public void TrimFreeSizeOK(string cacheName, int totalBuffs, int freeListCount) {}
- public void TrimFlush(string cacheName, int totalBuffs, int freeListCount, int notGen2CountBefore) {}
- public void AgePendingBuffersResults(string cacheName, int promotedToFreeListCount, int heldBackCount) {}
- public void WalkFreeListResult(string cacheName, int freeListCount, int gen0BuffersInFreeList) {}
+ public void DebugMessage(string message) { }
+ public void Create(string cacheName) { }
+ public void AllocateBuffer(string cacheName, ulong objectId, int objectHash, int objectGen, int freeCountAfter) { }
+ public void AllocateBufferFromNotGen2(string cacheName, int notGen2CountAfter) { }
+ public void AllocateBufferCreatingNewBuffers(string cacheName, int totalBuffsBefore, int objectCount) { }
+ public void AllocateBufferAged(string cacheName, int agedCount) { }
+ public void AllocateBufferFreeListEmpty(string cacheName, int notGen2CountBefore) { }
+ public void FreeBuffer(string cacheName, ulong objectId, int objectHash, int freeCountBefore) { }
+ public void FreeBufferStillTooYoung(string cacheName, int notGen2CountBefore) { }
+ public void TrimCheck(string cacheName, int totalBuffs, bool neededMoreThanFreeList, int deltaMSec) { }
+ public void TrimFree(string cacheName, int totalBuffs, int freeListCount, int toBeFreed) { }
+ public void TrimExperiment(string cacheName, int totalBuffs, int freeListCount, int numTrimTrial) { }
+ public void TrimFreeSizeOK(string cacheName, int totalBuffs, int freeListCount) { }
+ public void TrimFlush(string cacheName, int totalBuffs, int freeListCount, int notGen2CountBefore) { }
+ public void AgePendingBuffersResults(string cacheName, int promotedToFreeListCount, int heldBackCount) { }
+ public void WalkFreeListResult(string cacheName, int freeListCount, int gen0BuffersInFreeList) { }
static internal ulong AddressOf(object obj)
{
diff --git a/src/mscorlib/Common/Preprocessed/AssemblyRefs.g.cs b/src/mscorlib/Common/Preprocessed/AssemblyRefs.g.cs
index d5866a4bcd..fba0953e20 100644
--- a/src/mscorlib/Common/Preprocessed/AssemblyRefs.g.cs
+++ b/src/mscorlib/Common/Preprocessed/AssemblyRefs.g.cs
@@ -15,19 +15,21 @@ using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
-internal static class FXAssembly {
+internal static class FXAssembly
+{
internal const string Version = "4.0.0.0";
}
-internal static class ThisAssembly {
+internal static class ThisAssembly
+{
internal const string Version = "4.0.0.0";
internal const int DailyBuildNumber = 22306;
}
-internal static class AssemblyRef {
- internal const string EcmaPublicKey = "b77a5c561934e089";
- internal const string EcmaPublicKeyToken = "b77a5c561934e089";
- internal const string MicrosoftPublicKeyToken = "b03f5f7f11d50a3a";
- internal const string SystemRuntimeWindowsRuntime = "System.Runtime.WindowsRuntime, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + EcmaPublicKey;
-
+internal static class AssemblyRef
+{
+ internal const string EcmaPublicKey = "b77a5c561934e089";
+ internal const string EcmaPublicKeyToken = "b77a5c561934e089";
+ internal const string MicrosoftPublicKeyToken = "b03f5f7f11d50a3a";
+ internal const string SystemRuntimeWindowsRuntime = "System.Runtime.WindowsRuntime, Version=" + FXAssembly.Version + ", Culture=neutral, PublicKeyToken=" + EcmaPublicKey;
}
diff --git a/src/mscorlib/Common/System/SR.cs b/src/mscorlib/Common/System/SR.cs
new file mode 100644
index 0000000000..29f3970633
--- /dev/null
+++ b/src/mscorlib/Common/System/SR.cs
@@ -0,0 +1,197 @@
+// 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.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Threading;
+
+namespace System
+{
+ internal static partial class SR
+ {
+ private static ResourceManager ResourceManager
+ {
+ get;
+ set;
+ }
+
+ // This method is used to decide if we need to append the exception message parameters to the message when calling SR.Format.
+ // by default it returns false.
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static bool UsingResourceKeys()
+ {
+ return false;
+ }
+
+ // Needed for debugger integration
+ internal static string GetResourceString(string resourceKey)
+ {
+ return GetResourceString(resourceKey, String.Empty);
+ }
+
+ internal static string GetResourceString(string resourceKey, string defaultString)
+ {
+ string resourceString = null;
+ try { resourceString = InternalGetResourceString(resourceKey); }
+ catch (MissingManifestResourceException) { }
+
+ if (defaultString != null && resourceKey.Equals(resourceString, StringComparison.Ordinal))
+ {
+ return defaultString;
+ }
+
+ return resourceString;
+ }
+
+ private static object _lock = new object();
+ private static List<string> _currentlyLoading;
+ private static int _infinitelyRecursingCount;
+ private static bool _resourceManagerInited = false;
+
+ private static string InternalGetResourceString(string key)
+ {
+ if (key == null || key.Length == 0)
+ {
+ Debug.Assert(false, "SR::GetResourceString with null or empty key. Bug in caller, or weird recursive loading problem?");
+ return key;
+ }
+
+ // We have a somewhat common potential for infinite
+ // loops with mscorlib's ResourceManager. If "potentially dangerous"
+ // code throws an exception, we will get into an infinite loop
+ // inside the ResourceManager and this "potentially dangerous" code.
+ // Potentially dangerous code includes the IO package, CultureInfo,
+ // parts of the loader, some parts of Reflection, Security (including
+ // custom user-written permissions that may parse an XML file at
+ // class load time), assembly load event handlers, etc. Essentially,
+ // this is not a bounded set of code, and we need to fix the problem.
+ // Fortunately, this is limited to mscorlib's error lookups and is NOT
+ // a general problem for all user code using the ResourceManager.
+
+ // The solution is to make sure only one thread at a time can call
+ // GetResourceString. Also, since resource lookups can be
+ // reentrant, if the same thread comes into GetResourceString
+ // twice looking for the exact same resource name before
+ // returning, we're going into an infinite loop and we should
+ // return a bogus string.
+
+ bool lockTaken = false;
+ try
+ {
+ Monitor.Enter(_lock, ref lockTaken);
+
+ // Are we recursively looking up the same resource? Note - our backout code will set
+ // the ResourceHelper's currentlyLoading stack to null if an exception occurs.
+ if (_currentlyLoading != null && _currentlyLoading.Count > 0 && _currentlyLoading.LastIndexOf(key) != -1)
+ {
+ // We can start infinitely recursing for one resource lookup,
+ // then during our failure reporting, start infinitely recursing again.
+ // avoid that.
+ if (_infinitelyRecursingCount > 0)
+ {
+ return key;
+ }
+ _infinitelyRecursingCount++;
+
+ // Note: our infrastructure for reporting this exception will again cause resource lookup.
+ // This is the most direct way of dealing with that problem.
+ string message = $"Infinite recursion during resource lookup within {System.CoreLib.Name}. This may be a bug in {System.CoreLib.Name}, or potentially in certain extensibility points such as assembly resolve events or CultureInfo names. Resource name: {key}";
+ Assert.Fail("[Recursive resource lookup bug]", message, Assert.COR_E_FAILFAST, System.Diagnostics.StackTrace.TraceFormat.NoResourceLookup);
+ Environment.FailFast(message);
+ }
+ if (_currentlyLoading == null)
+ _currentlyLoading = new List<string>();
+
+ // Call class constructors preemptively, so that we cannot get into an infinite
+ // loop constructing a TypeInitializationException. If this were omitted,
+ // we could get the Infinite recursion assert above by failing type initialization
+ // between the Push and Pop calls below.
+ if (!_resourceManagerInited)
+ {
+ RuntimeHelpers.RunClassConstructor(typeof(ResourceManager).TypeHandle);
+ RuntimeHelpers.RunClassConstructor(typeof(ResourceReader).TypeHandle);
+ RuntimeHelpers.RunClassConstructor(typeof(RuntimeResourceSet).TypeHandle);
+ RuntimeHelpers.RunClassConstructor(typeof(BinaryReader).TypeHandle);
+ _resourceManagerInited = true;
+ }
+
+ _currentlyLoading.Add(key); // Push
+
+ if (ResourceManager == null)
+ {
+ ResourceManager = new ResourceManager(SR.ResourceType);
+ }
+ string s = ResourceManager.GetString(key, null);
+ _currentlyLoading.RemoveAt(_currentlyLoading.Count - 1); // Pop
+
+ Debug.Assert(s != null, "Managed resource string lookup failed. Was your resource name misspelled? Did you rebuild mscorlib after adding a resource to resources.txt? Debug this w/ cordbg and bug whoever owns the code that called SR.GetResourceString. Resource name was: \"" + key + "\"");
+ return s ?? key;
+ }
+ catch
+ {
+ if (lockTaken)
+ {
+ // Backout code - throw away potentially corrupt state
+ ResourceManager = null;
+ _currentlyLoading = null;
+ }
+ throw;
+ }
+ finally
+ {
+ if (lockTaken)
+ {
+ Monitor.Exit(_lock);
+ }
+ }
+ }
+
+ internal static string Format(string resourceFormat, params object[] args)
+ {
+ if (args != null)
+ {
+ if (UsingResourceKeys())
+ {
+ return resourceFormat + String.Join(", ", args);
+ }
+
+ return String.Format(resourceFormat, args);
+ }
+
+ return resourceFormat;
+ }
+
+ internal static string Format(string resourceFormat, object p1)
+ {
+ if (UsingResourceKeys())
+ {
+ return String.Join(", ", resourceFormat, p1);
+ }
+
+ return String.Format(resourceFormat, p1);
+ }
+
+ internal static string Format(string resourceFormat, object p1, object p2)
+ {
+ if (UsingResourceKeys())
+ {
+ return String.Join(", ", resourceFormat, p1, p2);
+ }
+
+ return String.Format(resourceFormat, p1, p2);
+ }
+
+ internal static string Format(string resourceFormat, object p1, object p2, object p3)
+ {
+ if (UsingResourceKeys())
+ {
+ return String.Join(", ", resourceFormat, p1, p2, p3);
+ }
+ return String.Format(resourceFormat, p1, p2, p3);
+ }
+ }
+}
diff --git a/src/mscorlib/GenerateSplitStringResources.targets b/src/mscorlib/GenerateSplitStringResources.targets
index 88e01cb612..6041cbe0e3 100644
--- a/src/mscorlib/GenerateSplitStringResources.targets
+++ b/src/mscorlib/GenerateSplitStringResources.targets
@@ -14,7 +14,7 @@
Outputs="@(SplitTextStringResource->'$(IntermediateOutputPath)%(Filename).txt')">
<ItemGroup>
- <Internal_ResGenDefines Remove="" />
+ <Internal_ResGenDefines Remove="@(Internal_ResGenDefines)" />
<Internal_ResGenDefines Include="INCLUDE_DEBUG" />
<Internal_ResGenDefines Include="INCLUDE_RUNTIME" />
<Internal_ResGenDefines Include="%(SplitTextStringResource.ResGenDefines)" />
@@ -36,7 +36,7 @@
</ItemGroup>
<ItemGroup>
- <Internal_ResGenDefines Remove="" />
- </ItemGroup>
+ <Internal_ResGenDefines Remove="@(Internal_ResGenDefines)" />
+ </ItemGroup>
</Target>
-</Project> \ No newline at end of file
+</Project>
diff --git a/src/mscorlib/PinvokeAnalyzerExceptionList.analyzerdata b/src/mscorlib/PinvokeAnalyzerExceptionList.analyzerdata
new file mode 100644
index 0000000000..4bbdccae19
--- /dev/null
+++ b/src/mscorlib/PinvokeAnalyzerExceptionList.analyzerdata
@@ -0,0 +1,3 @@
+<!-- Not a bug, these APIs are in the allowed list but under kernel32 and we need it under normaliz.dll -->
+normaliz.dll!IsNormalizedString
+normaliz.dll!NormalizeString
diff --git a/src/mscorlib/Resources/Strings.resx b/src/mscorlib/Resources/Strings.resx
new file mode 100644
index 0000000000..cb9474fe00
--- /dev/null
+++ b/src/mscorlib/Resources/Strings.resx
@@ -0,0 +1,3611 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="Acc_CreateAbst" xml:space="preserve">
+ <value>Cannot create an abstract class.</value>
+ </data>
+ <data name="Acc_CreateAbstEx" xml:space="preserve">
+ <value>Cannot create an instance of {0} because it is an abstract class.</value>
+ </data>
+ <data name="Acc_CreateArgIterator" xml:space="preserve">
+ <value>Cannot dynamically create an instance of ArgIterator.</value>
+ </data>
+ <data name="Acc_CreateGeneric" xml:space="preserve">
+ <value>Cannot create a type for which Type.ContainsGenericParameters is true.</value>
+ </data>
+ <data name="Acc_CreateGenericEx" xml:space="preserve">
+ <value>Cannot create an instance of {0} because Type.ContainsGenericParameters is true.</value>
+ </data>
+ <data name="Acc_CreateInterface" xml:space="preserve">
+ <value>Cannot create an instance of an interface.</value>
+ </data>
+ <data name="Acc_CreateInterfaceEx" xml:space="preserve">
+ <value>Cannot create an instance of {0} because it is an interface.</value>
+ </data>
+ <data name="Acc_CreateVoid" xml:space="preserve">
+ <value>Cannot dynamically create an instance of System.Void.</value>
+ </data>
+ <data name="Acc_NotClassInit" xml:space="preserve">
+ <value>Type initializer was not callable.</value>
+ </data>
+ <data name="Acc_ReadOnly" xml:space="preserve">
+ <value>Cannot set a constant field.</value>
+ </data>
+ <data name="Acc_RvaStatic" xml:space="preserve">
+ <value>SkipVerification permission is needed to modify an image-based (RVA) static field.</value>
+ </data>
+ <data name="Access_Void" xml:space="preserve">
+ <value>Cannot create an instance of void.</value>
+ </data>
+ <data name="AggregateException_ctor_DefaultMessage" xml:space="preserve">
+ <value>One or more errors occurred.</value>
+ </data>
+ <data name="AggregateException_ctor_InnerExceptionNull" xml:space="preserve">
+ <value>An element of innerExceptions was null.</value>
+ </data>
+ <data name="AggregateException_DeserializationFailure" xml:space="preserve">
+ <value>The serialization stream contains no inner exceptions.</value>
+ </data>
+ <data name="AggregateException_ToString" xml:space="preserve">
+ <value>{0}{1}---&gt; (Inner Exception #{2}) {3}{4}{5}</value>
+ </data>
+ <data name="AppDomain_AppBaseNotSet" xml:space="preserve">
+ <value>The ApplicationBase must be set before retrieving this property.</value>
+ </data>
+ <data name="Arg_AccessException" xml:space="preserve">
+ <value>Cannot access member.</value>
+ </data>
+ <data name="Arg_AccessViolationException" xml:space="preserve">
+ <value>Attempted to read or write protected memory. This is often an indication that other memory is corrupt.</value>
+ </data>
+ <data name="Arg_AmbiguousMatchException" xml:space="preserve">
+ <value>Ambiguous match found.</value>
+ </data>
+ <data name="Arg_AppDomainUnloadedException" xml:space="preserve">
+ <value>Attempted to access an unloaded AppDomain.</value>
+ </data>
+ <data name="Arg_ApplicationException" xml:space="preserve">
+ <value>Error in the application.</value>
+ </data>
+ <data name="Arg_ArgumentException" xml:space="preserve">
+ <value>Value does not fall within the expected range.</value>
+ </data>
+ <data name="Arg_ArgumentOutOfRangeException" xml:space="preserve">
+ <value>Specified argument was out of the range of valid values.</value>
+ </data>
+ <data name="Arg_ArithmeticException" xml:space="preserve">
+ <value>Overflow or underflow in the arithmetic operation.</value>
+ </data>
+ <data name="Arg_ArrayLengthsDiffer" xml:space="preserve">
+ <value>Array lengths must be the same.</value>
+ </data>
+ <data name="Arg_ArrayPlusOffTooSmall" xml:space="preserve">
+ <value>Destination array is not long enough to copy all the items in the collection. Check array index and length.</value>
+ </data>
+ <data name="Arg_ArrayTypeMismatchException" xml:space="preserve">
+ <value>Attempted to access an element as a type incompatible with the array.</value>
+ </data>
+ <data name="Arg_ArrayZeroError" xml:space="preserve">
+ <value>Array must not be of length zero.</value>
+ </data>
+ <data name="Arg_BadDecimal" xml:space="preserve">
+ <value>Read an invalid decimal value from the buffer.</value>
+ </data>
+ <data name="Arg_BadImageFormatException" xml:space="preserve">
+ <value>Format of the executable (.exe) or library (.dll) is invalid.</value>
+ </data>
+ <data name="Arg_BadLiteralFormat" xml:space="preserve">
+ <value>Encountered an invalid type for a default value.</value>
+ </data>
+ <data name="Arg_BogusIComparer" xml:space="preserve">
+ <value>Unable to sort because the IComparer.Compare() method returns inconsistent results. Either a value does not compare equal to itself, or one value repeatedly compared to another value yields different results. IComparer: '{0}'.</value>
+ </data>
+ <data name="Arg_BufferTooSmall" xml:space="preserve">
+ <value>Not enough space available in the buffer.</value>
+ </data>
+ <data name="Arg_CannotBeNaN" xml:space="preserve">
+ <value>TimeSpan does not accept floating point Not-a-Number values.</value>
+ </data>
+ <data name="Arg_CannotHaveNegativeValue" xml:space="preserve">
+ <value>String cannot contain a minus sign if the base is not 10.</value>
+ </data>
+ <data name="Arg_CATypeResolutionFailed" xml:space="preserve">
+ <value>Failed to resolve type from string "{0}" which was embedded in custom attribute blob.</value>
+ </data>
+ <data name="Arg_COMAccess" xml:space="preserve">
+ <value>Must specify property Set or Get or method call for a COM Object.</value>
+ </data>
+ <data name="Arg_COMException" xml:space="preserve">
+ <value>Error HRESULT E_FAIL has been returned from a call to a COM component.</value>
+ </data>
+ <data name="Arg_COMPropSetPut" xml:space="preserve">
+ <value>Only one of the following binding flags can be set: BindingFlags.SetProperty, BindingFlags.PutDispProperty, BindingFlags.PutRefDispProperty.</value>
+ </data>
+ <data name="Arg_CreatInstAccess" xml:space="preserve">
+ <value>Cannot specify both CreateInstance and another access type.</value>
+ </data>
+ <data name="Arg_CryptographyException" xml:space="preserve">
+ <value>Error occurred during a cryptographic operation.</value>
+ </data>
+ <data name="Arg_CustomAttributeFormatException" xml:space="preserve">
+ <value>Binary format of the specified custom attribute was invalid.</value>
+ </data>
+ <data name="Arg_DataMisalignedException" xml:space="preserve">
+ <value>A datatype misalignment was detected in a load or store instruction.</value>
+ </data>
+ <data name="Arg_DateTimeRange" xml:space="preserve">
+ <value>Combination of arguments to the DateTime constructor is out of the legal range.</value>
+ </data>
+ <data name="Arg_DecBitCtor" xml:space="preserve">
+ <value>Decimal byte array constructor requires an array of length four containing valid decimal bytes.</value>
+ </data>
+ <data name="Arg_DirectoryNotFoundException" xml:space="preserve">
+ <value>Attempted to access a path that is not on the disk.</value>
+ </data>
+ <data name="Arg_DivideByZero" xml:space="preserve">
+ <value>Attempted to divide by zero.</value>
+ </data>
+ <data name="Arg_DlgtNullInst" xml:space="preserve">
+ <value>Delegate to an instance method cannot have null 'this'.</value>
+ </data>
+ <data name="Arg_DlgtTargMeth" xml:space="preserve">
+ <value>Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.</value>
+ </data>
+ <data name="Arg_DlgtTypeMis" xml:space="preserve">
+ <value>Delegates must be of the same type.</value>
+ </data>
+ <data name="Arg_DllNotFoundException" xml:space="preserve">
+ <value>Dll was not found.</value>
+ </data>
+ <data name="Arg_DriveNotFoundException" xml:space="preserve">
+ <value>Attempted to access a drive that is not available.</value>
+ </data>
+ <data name="Arg_DuplicateWaitObjectException" xml:space="preserve">
+ <value>Duplicate objects in argument.</value>
+ </data>
+ <data name="Arg_EHClauseNotClause" xml:space="preserve">
+ <value>This ExceptionHandlingClause is not a clause.</value>
+ </data>
+ <data name="Arg_EHClauseNotFilter" xml:space="preserve">
+ <value>This ExceptionHandlingClause is not a filter.</value>
+ </data>
+ <data name="Arg_EmptyArray" xml:space="preserve">
+ <value>Array may not be empty.</value>
+ </data>
+ <data name="Arg_EmptyOrNullString" xml:space="preserve">
+ <value>String may not be empty or null.</value>
+ </data>
+ <data name="Arg_EndOfStreamException" xml:space="preserve">
+ <value>Attempted to read past the end of the stream.</value>
+ </data>
+ <data name="Arg_EntryPointNotFoundException" xml:space="preserve">
+ <value>Entry point was not found.</value>
+ </data>
+ <data name="Arg_EnumAndObjectMustBeSameType" xml:space="preserve">
+ <value>Object must be the same type as the enum. The type passed in was '{0}'; the enum type was '{1}'.</value>
+ </data>
+ <data name="Arg_EnumFormatUnderlyingTypeAndObjectMustBeSameType" xml:space="preserve">
+ <value>Enum underlying type and the object must be same type or object. Type passed in was '{0}'; the enum underlying type was '{1}'.</value>
+ </data>
+ <data name="Arg_EnumIllegalVal" xml:space="preserve">
+ <value>Illegal enum value: {0}.</value>
+ </data>
+ <data name="Arg_EnumLitValueNotFound" xml:space="preserve">
+ <value>Literal value was not found.</value>
+ </data>
+ <data name="Arg_EnumUnderlyingTypeAndObjectMustBeSameType" xml:space="preserve">
+ <value>Enum underlying type and the object must be same type or object must be a String. Type passed in was '{0}'; the enum underlying type was '{1}'.</value>
+ </data>
+ <data name="Arg_EnumValueNotFound" xml:space="preserve">
+ <value>Requested value '{0}' was not found.</value>
+ </data>
+ <data name="Arg_ExecutionEngineException" xml:space="preserve">
+ <value>Internal error in the runtime.</value>
+ </data>
+ <data name="Arg_ExternalException" xml:space="preserve">
+ <value>External component has thrown an exception.</value>
+ </data>
+ <data name="Arg_FieldAccessException" xml:space="preserve">
+ <value>Attempted to access a field that is not accessible by the caller.</value>
+ </data>
+ <data name="Arg_FieldDeclTarget" xml:space="preserve">
+ <value>Field '{0}' defined on type '{1}' is not a field on the target object which is of type '{2}'.</value>
+ </data>
+ <data name="Arg_FldGetArgErr" xml:space="preserve">
+ <value>No arguments can be provided to Get a field value.</value>
+ </data>
+ <data name="Arg_FldGetPropSet" xml:space="preserve">
+ <value>Cannot specify both GetField and SetProperty.</value>
+ </data>
+ <data name="Arg_FldSetArgErr" xml:space="preserve">
+ <value>Only the field value can be specified to set a field value.</value>
+ </data>
+ <data name="Arg_FldSetGet" xml:space="preserve">
+ <value>Cannot specify both Get and Set on a field.</value>
+ </data>
+ <data name="Arg_FldSetInvoke" xml:space="preserve">
+ <value>Cannot specify Set on a Field and Invoke on a method.</value>
+ </data>
+ <data name="Arg_FldSetPropGet" xml:space="preserve">
+ <value>Cannot specify both SetField and GetProperty.</value>
+ </data>
+ <data name="Arg_FormatException" xml:space="preserve">
+ <value>One of the identified items was in an invalid format.</value>
+ </data>
+ <data name="Arg_GenericParameter" xml:space="preserve">
+ <value>Method must be called on a Type for which Type.IsGenericParameter is false.</value>
+ </data>
+ <data name="Arg_GetMethNotFnd" xml:space="preserve">
+ <value>Property Get method was not found.</value>
+ </data>
+ <data name="Arg_GuidArrayCtor" xml:space="preserve">
+ <value>Byte array for GUID must be exactly {0} bytes long.</value>
+ </data>
+ <data name="Arg_HandleNotAsync" xml:space="preserve">
+ <value>Handle does not support asynchronous operations. The parameters to the FileStream constructor may need to be changed to indicate that the handle was opened synchronously (that is, it was not opened for overlapped I/O).</value>
+ </data>
+ <data name="Arg_HandleNotSync" xml:space="preserve">
+ <value>Handle does not support synchronous operations. The parameters to the FileStream constructor may need to be changed to indicate that the handle was opened asynchronously (that is, it was opened explicitly for overlapped I/O).</value>
+ </data>
+ <data name="Arg_HexStyleNotSupported" xml:space="preserve">
+ <value>The number style AllowHexSpecifier is not supported on floating point data types.</value>
+ </data>
+ <data name="Arg_HTCapacityOverflow" xml:space="preserve">
+ <value>Hashtable's capacity overflowed and went negative. Check load factor, capacity and the current size of the table.</value>
+ </data>
+ <data name="Arg_IndexMustBeInt" xml:space="preserve">
+ <value>All indexes must be of type Int32.</value>
+ </data>
+ <data name="Arg_IndexOutOfRangeException" xml:space="preserve">
+ <value>Index was outside the bounds of the array.</value>
+ </data>
+ <data name="Arg_InsufficientExecutionStackException" xml:space="preserve">
+ <value>Insufficient stack to continue executing the program safely. This can happen from having too many functions on the call stack or function on the stack using too much stack space.</value>
+ </data>
+ <data name="Arg_InvalidANSIString" xml:space="preserve">
+ <value>The ANSI string passed in could not be converted from the default ANSI code page to Unicode.</value>
+ </data>
+ <data name="Arg_InvalidBase" xml:space="preserve">
+ <value>Invalid Base.</value>
+ </data>
+ <data name="Arg_InvalidCastException" xml:space="preserve">
+ <value>Specified cast is not valid.</value>
+ </data>
+ <data name="Arg_InvalidComObjectException" xml:space="preserve">
+ <value>Attempt has been made to use a COM object that does not have a backing class factory.</value>
+ </data>
+ <data name="Arg_InvalidFilterCriteriaException" xml:space="preserve">
+ <value>Specified filter criteria was invalid.</value>
+ </data>
+ <data name="Arg_InvalidHandle" xml:space="preserve">
+ <value>Invalid handle.</value>
+ </data>
+ <data name="Arg_InvalidHexStyle" xml:space="preserve">
+ <value>With the AllowHexSpecifier bit set in the enum bit field, the only other valid bits that can be combined into the enum value must be a subset of those in HexNumber.</value>
+ </data>
+ <data name="Arg_InvalidNeutralResourcesLanguage_Asm_Culture" xml:space="preserve">
+ <value>The NeutralResourcesLanguageAttribute on the assembly "{0}" specifies an invalid culture name: "{1}".</value>
+ </data>
+ <data name="Arg_InvalidNeutralResourcesLanguage_FallbackLoc" xml:space="preserve">
+ <value>The NeutralResourcesLanguageAttribute specifies an invalid or unrecognized ultimate resource fallback location: "{0}".</value>
+ </data>
+ <data name="Arg_InvalidOleVariantTypeException" xml:space="preserve">
+ <value>Specified OLE variant was invalid.</value>
+ </data>
+ <data name="Arg_InvalidOperationException" xml:space="preserve">
+ <value>Operation is not valid due to the current state of the object.</value>
+ </data>
+ <data name="Arg_InvalidSearchPattern" xml:space="preserve">
+ <value>Search pattern cannot contain ".." to move up directories and can be contained only internally in file/directory names, as in "a..b".</value>
+ </data>
+ <data name="Arg_InvalidTypeInRetType" xml:space="preserve">
+ <value>The return Type contains some invalid type (i.e. null, ByRef)</value>
+ </data>
+ <data name="Arg_InvalidTypeInSignature" xml:space="preserve">
+ <value>The signature Type array contains some invalid type (i.e. null, void)</value>
+ </data>
+ <data name="Arg_InvalidUTF8String" xml:space="preserve">
+ <value>The UTF8 string passed in could not be converted to Unicode.</value>
+ </data>
+ <data name="Arg_IOException" xml:space="preserve">
+ <value>I/O error occurred.</value>
+ </data>
+ <data name="Arg_KeyNotFound" xml:space="preserve">
+ <value>The given key was not present in the dictionary.</value>
+ </data>
+ <data name="Arg_LongerThanDestArray" xml:space="preserve">
+ <value>Destination array was not long enough. Check the destination index, length, and the array's lower bounds.</value>
+ </data>
+ <data name="Arg_LongerThanSrcArray" xml:space="preserve">
+ <value>Source array was not long enough. Check the source index, length, and the array's lower bounds.</value>
+ </data>
+ <data name="Arg_LongerThanSrcString" xml:space="preserve">
+ <value>Source string was not long enough. Check sourceIndex and count.</value>
+ </data>
+ <data name="Arg_LowerBoundsMustMatch" xml:space="preserve">
+ <value>The arrays' lower bounds must be identical.</value>
+ </data>
+ <data name="Arg_MarshalAsAnyRestriction" xml:space="preserve">
+ <value>AsAny cannot be used on return types, ByRef parameters, ArrayWithOffset, or parameters passed from unmanaged to managed.</value>
+ </data>
+ <data name="Arg_MarshalDirectiveException" xml:space="preserve">
+ <value>Marshaling directives are invalid.</value>
+ </data>
+ <data name="Arg_MethodAccessException" xml:space="preserve">
+ <value>Attempt to access the method failed.</value>
+ </data>
+ <data name="Arg_MethodAccessException_WithMethodName" xml:space="preserve">
+ <value>Attempt to access the method "{0}" on type "{1}" failed.</value>
+ </data>
+ <data name="Arg_MissingFieldException" xml:space="preserve">
+ <value>Attempted to access a non-existing field.</value>
+ </data>
+ <data name="Arg_MissingManifestResourceException" xml:space="preserve">
+ <value>Unable to find manifest resource.</value>
+ </data>
+ <data name="Arg_MissingMemberException" xml:space="preserve">
+ <value>Attempted to access a missing member.</value>
+ </data>
+ <data name="Arg_MissingMethodException" xml:space="preserve">
+ <value>Attempted to access a missing method.</value>
+ </data>
+ <data name="Arg_MulticastNotSupportedException" xml:space="preserve">
+ <value>Attempted to add multiple callbacks to a delegate that does not support multicast.</value>
+ </data>
+ <data name="Arg_MustBeBoolean" xml:space="preserve">
+ <value>Object must be of type Boolean.</value>
+ </data>
+ <data name="Arg_MustBeByte" xml:space="preserve">
+ <value>Object must be of type Byte.</value>
+ </data>
+ <data name="Arg_MustBeChar" xml:space="preserve">
+ <value>Object must be of type Char.</value>
+ </data>
+ <data name="Arg_MustBeDateTime" xml:space="preserve">
+ <value>Object must be of type DateTime.</value>
+ </data>
+ <data name="Arg_MustBeDateTimeOffset" xml:space="preserve">
+ <value>Object must be of type DateTimeOffset.</value>
+ </data>
+ <data name="Arg_MustBeDecimal" xml:space="preserve">
+ <value>Object must be of type Decimal.</value>
+ </data>
+ <data name="Arg_MustBeDelegate" xml:space="preserve">
+ <value>Type must derive from Delegate.</value>
+ </data>
+ <data name="Arg_MustBeDouble" xml:space="preserve">
+ <value>Object must be of type Double.</value>
+ </data>
+ <data name="Arg_MustBeEnum" xml:space="preserve">
+ <value>Type provided must be an Enum.</value>
+ </data>
+ <data name="Arg_MustBeEnumBaseTypeOrEnum" xml:space="preserve">
+ <value>The value passed in must be an enum base or an underlying type for an enum, such as an Int32.</value>
+ </data>
+ <data name="Arg_MustBeGuid" xml:space="preserve">
+ <value>Object must be of type GUID.</value>
+ </data>
+ <data name="Arg_MustBeInt16" xml:space="preserve">
+ <value>Object must be of type Int16.</value>
+ </data>
+ <data name="Arg_MustBeInt32" xml:space="preserve">
+ <value>Object must be of type Int32.</value>
+ </data>
+ <data name="Arg_MustBeInt64" xml:space="preserve">
+ <value>Object must be of type Int64.</value>
+ </data>
+ <data name="Arg_MustBeInterface" xml:space="preserve">
+ <value>Type passed must be an interface.</value>
+ </data>
+ <data name="Arg_MustBePointer" xml:space="preserve">
+ <value>Type must be a Pointer.</value>
+ </data>
+ <data name="Arg_MustBePrimArray" xml:space="preserve">
+ <value>Object must be an array of primitives.</value>
+ </data>
+ <data name="Arg_MustBeSByte" xml:space="preserve">
+ <value>Object must be of type SByte.</value>
+ </data>
+ <data name="Arg_MustBeSingle" xml:space="preserve">
+ <value>Object must be of type Single.</value>
+ </data>
+ <data name="Arg_MustBeStatic" xml:space="preserve">
+ <value>Method must be a static method.</value>
+ </data>
+ <data name="Arg_MustBeString" xml:space="preserve">
+ <value>Object must be of type String.</value>
+ </data>
+ <data name="Arg_MustBeStringPtrNotAtom" xml:space="preserve">
+ <value>The pointer passed in as a String must not be in the bottom 64K of the process's address space.</value>
+ </data>
+ <data name="Arg_MustBeTimeSpan" xml:space="preserve">
+ <value>Object must be of type TimeSpan.</value>
+ </data>
+ <data name="Arg_MustBeType" xml:space="preserve">
+ <value>Type must be a type provided by the runtime.</value>
+ </data>
+ <data name="Arg_MustBeUInt16" xml:space="preserve">
+ <value>Object must be of type UInt16.</value>
+ </data>
+ <data name="Arg_MustBeUInt32" xml:space="preserve">
+ <value>Object must be of type UInt32.</value>
+ </data>
+ <data name="Arg_MustBeUInt64" xml:space="preserve">
+ <value>Object must be of type UInt64.</value>
+ </data>
+ <data name="Arg_MustBeVersion" xml:space="preserve">
+ <value>Object must be of type Version.</value>
+ </data>
+ <data name="Arg_MustContainEnumInfo" xml:space="preserve">
+ <value>Must specify valid information for parsing in the string.</value>
+ </data>
+ <data name="Arg_NamedParamNull" xml:space="preserve">
+ <value>Named parameter value must not be null.</value>
+ </data>
+ <data name="Arg_NamedParamTooBig" xml:space="preserve">
+ <value>Named parameter array cannot be bigger than argument array.</value>
+ </data>
+ <data name="Arg_NDirectBadObject" xml:space="preserve">
+ <value>No PInvoke conversion exists for value passed to Object-typed parameter.</value>
+ </data>
+ <data name="Arg_Need1DArray" xml:space="preserve">
+ <value>Array was not a one-dimensional array.</value>
+ </data>
+ <data name="Arg_Need2DArray" xml:space="preserve">
+ <value>Array was not a two-dimensional array.</value>
+ </data>
+ <data name="Arg_Need3DArray" xml:space="preserve">
+ <value>Array was not a three-dimensional array.</value>
+ </data>
+ <data name="Arg_NeedAtLeast1Rank" xml:space="preserve">
+ <value>Must provide at least one rank.</value>
+ </data>
+ <data name="Arg_NegativeArgCount" xml:space="preserve">
+ <value>Argument count must not be negative.</value>
+ </data>
+ <data name="Arg_NoAccessSpec" xml:space="preserve">
+ <value>Must specify binding flags describing the invoke operation required (BindingFlags.InvokeMethod CreateInstance GetField SetField GetProperty SetProperty).</value>
+ </data>
+ <data name="Arg_NoDefCTor" xml:space="preserve">
+ <value>No parameterless constructor defined for this object.</value>
+ </data>
+ <data name="Arg_NoITypeInfo" xml:space="preserve">
+ <value>Specified TypeInfo was invalid because it did not support the ITypeInfo interface.</value>
+ </data>
+ <data name="Arg_NoITypeLib" xml:space="preserve">
+ <value>Specified TypeLib was invalid because it did not support the ITypeLib interface.</value>
+ </data>
+ <data name="Arg_NonZeroLowerBound" xml:space="preserve">
+ <value>The lower bound of target array must be zero.</value>
+ </data>
+ <data name="Arg_NoStaticVirtual" xml:space="preserve">
+ <value>Method cannot be both static and virtual.</value>
+ </data>
+ <data name="Arg_NotFiniteNumberException" xml:space="preserve">
+ <value>Number encountered was not a finite quantity.</value>
+ </data>
+ <data name="Arg_NotFoundIFace" xml:space="preserve">
+ <value>Interface not found.</value>
+ </data>
+ <data name="Arg_NotGenericMethodDefinition" xml:space="preserve">
+ <value>{0} is not a GenericMethodDefinition. MakeGenericMethod may only be called on a method for which MethodBase.IsGenericMethodDefinition is true.</value>
+ </data>
+ <data name="Arg_NotGenericParameter" xml:space="preserve">
+ <value>Method may only be called on a Type for which Type.IsGenericParameter is true.</value>
+ </data>
+ <data name="Arg_NotGenericTypeDefinition" xml:space="preserve">
+ <value>{0} is not a GenericTypeDefinition. MakeGenericType may only be called on a type for which Type.IsGenericTypeDefinition is true.</value>
+ </data>
+ <data name="Arg_NotImplementedException" xml:space="preserve">
+ <value>The method or operation is not implemented.</value>
+ </data>
+ <data name="Arg_NotSupportedException" xml:space="preserve">
+ <value>Specified method is not supported.</value>
+ </data>
+ <data name="Arg_NullIndex" xml:space="preserve">
+ <value>Arrays indexes must be set to an object instance.</value>
+ </data>
+ <data name="Arg_NullReferenceException" xml:space="preserve">
+ <value>Object reference not set to an instance of an object.</value>
+ </data>
+ <data name="Arg_ObjObj" xml:space="preserve">
+ <value>Object type cannot be converted to target type.</value>
+ </data>
+ <data name="Arg_ObjObjEx" xml:space="preserve">
+ <value>Object of type '{0}' cannot be converted to type '{1}'.</value>
+ </data>
+ <data name="Arg_OleAutDateInvalid" xml:space="preserve">
+ <value>Not a legal OleAut date.</value>
+ </data>
+ <data name="Arg_OleAutDateScale" xml:space="preserve">
+ <value>OleAut date did not convert to a DateTime correctly.</value>
+ </data>
+ <data name="Arg_OverflowException" xml:space="preserve">
+ <value>Arithmetic operation resulted in an overflow.</value>
+ </data>
+ <data name="Arg_ParamName_Name" xml:space="preserve">
+ <value>Parameter name: {0}</value>
+ </data>
+ <data name="Arg_ParmArraySize" xml:space="preserve">
+ <value>Must specify one or more parameters.</value>
+ </data>
+ <data name="Arg_ParmCnt" xml:space="preserve">
+ <value>Parameter count mismatch.</value>
+ </data>
+ <data name="Arg_PathIllegal" xml:space="preserve">
+ <value>The path is not of a legal form.</value>
+ </data>
+ <data name="Arg_PathIllegalUNC" xml:space="preserve">
+ <value>The UNC path should be of the form \\\\server\\share.</value>
+ </data>
+ <data name="Arg_PlatformNotSupported" xml:space="preserve">
+ <value>Operation is not supported on this platform.</value>
+ </data>
+ <data name="Arg_PrimWiden" xml:space="preserve">
+ <value>Cannot widen from source type to target type either because the source type is a not a primitive type or the conversion cannot be accomplished.</value>
+ </data>
+ <data name="Arg_PropSetGet" xml:space="preserve">
+ <value>Cannot specify both Get and Set on a property.</value>
+ </data>
+ <data name="Arg_PropSetInvoke" xml:space="preserve">
+ <value>Cannot specify Set on a property and Invoke on a method.</value>
+ </data>
+ <data name="Arg_RankException" xml:space="preserve">
+ <value>Attempted to operate on an array with the incorrect number of dimensions.</value>
+ </data>
+ <data name="Arg_RankIndices" xml:space="preserve">
+ <value>Indices length does not match the array rank.</value>
+ </data>
+ <data name="Arg_RankMultiDimNotSupported" xml:space="preserve">
+ <value>Only single dimensional arrays are supported for the requested action.</value>
+ </data>
+ <data name="Arg_RanksAndBounds" xml:space="preserve">
+ <value>Number of lengths and lowerBounds must match.</value>
+ </data>
+ <data name="Arg_ReflectionOnlyCA" xml:space="preserve">
+ <value>It is illegal to reflect on the custom attributes of a Type loaded via ReflectionOnlyGetType (see Assembly.ReflectionOnly) -- use CustomAttributeData instead.</value>
+ </data>
+ <data name="Arg_ReflectionOnlyField" xml:space="preserve">
+ <value>It is illegal to get or set the value on a field on a Type loaded via ReflectionOnlyGetType.</value>
+ </data>
+ <data name="Arg_ReflectionOnlyInvoke" xml:space="preserve">
+ <value>It is illegal to invoke a method on a Type loaded via ReflectionOnlyGetType.</value>
+ </data>
+ <data name="Arg_RegBadKeyKind" xml:space="preserve">
+ <value>The specified RegistryValueKind is an invalid value.</value>
+ </data>
+ <data name="Arg_RegGetOverflowBug" xml:space="preserve">
+ <value>RegistryKey.GetValue does not allow a String that has a length greater than Int32.MaxValue.</value>
+ </data>
+ <data name="Arg_RegInvalidKeyName" xml:space="preserve">
+ <value>Registry key name must start with a valid base key name.</value>
+ </data>
+ <data name="Arg_RegKeyNotFound" xml:space="preserve">
+ <value>The specified registry key does not exist.</value>
+ </data>
+ <data name="Arg_RegKeyStrLenBug" xml:space="preserve">
+ <value>Registry key names should not be greater than 255 characters.</value>
+ </data>
+ <data name="Arg_RegSetBadArrType" xml:space="preserve">
+ <value>RegistryKey.SetValue does not support arrays of type '{0}'. Only Byte[] and String[] are supported.</value>
+ </data>
+ <data name="Arg_RegSetMismatchedKind" xml:space="preserve">
+ <value>The type of the value object did not match the specified RegistryValueKind or the object could not be properly converted.</value>
+ </data>
+ <data name="Arg_RegSetStrArrNull" xml:space="preserve">
+ <value>RegistryKey.SetValue does not allow a String[] that contains a null String reference.</value>
+ </data>
+ <data name="Arg_RegSubKeyValueAbsent" xml:space="preserve">
+ <value>No value exists with that name.</value>
+ </data>
+ <data name="Arg_RegValStrLenBug" xml:space="preserve">
+ <value>Registry value names should not be greater than 16,383 characters.</value>
+ </data>
+ <data name="Arg_RemoveArgNotFound" xml:space="preserve">
+ <value>Cannot remove the specified item because it was not found in the specified Collection.</value>
+ </data>
+ <data name="Arg_ResMgrNotResSet" xml:space="preserve">
+ <value>Type parameter must refer to a subclass of ResourceSet.</value>
+ </data>
+ <data name="Arg_ResourceFileUnsupportedVersion" xml:space="preserve">
+ <value>The ResourceReader class does not know how to read this version of .resources files. Expected version: {0} This file: {1}</value>
+ </data>
+ <data name="Arg_ResourceNameNotExist" xml:space="preserve">
+ <value>The specified resource name "{0}" does not exist in the resource file.</value>
+ </data>
+ <data name="Arg_SafeArrayRankMismatchException" xml:space="preserve">
+ <value>Specified array was not of the expected rank.</value>
+ </data>
+ <data name="Arg_SafeArrayTypeMismatchException" xml:space="preserve">
+ <value>Specified array was not of the expected type.</value>
+ </data>
+ <data name="Arg_SecurityException" xml:space="preserve">
+ <value>Security error.</value>
+ </data>
+ <data name="SerializationException" xml:space="preserve">
+ <value>Serialization error.</value>
+ </data>
+ <data name="Arg_SetMethNotFnd" xml:space="preserve">
+ <value>Property set method not found.</value>
+ </data>
+ <data name="Arg_StackOverflowException" xml:space="preserve">
+ <value>Operation caused a stack overflow.</value>
+ </data>
+ <data name="Arg_SurrogatesNotAllowedAsSingleChar" xml:space="preserve">
+ <value>Unicode surrogate characters must be written out as pairs together in the same call, not individually. Consider passing in a character array instead.</value>
+ </data>
+ <data name="Arg_SynchronizationLockException" xml:space="preserve">
+ <value>Object synchronization method was called from an unsynchronized block of code.</value>
+ </data>
+ <data name="Arg_SystemException" xml:space="preserve">
+ <value>System error.</value>
+ </data>
+ <data name="Arg_TargetInvocationException" xml:space="preserve">
+ <value>Exception has been thrown by the target of an invocation.</value>
+ </data>
+ <data name="Arg_TargetParameterCountException" xml:space="preserve">
+ <value>Number of parameters specified does not match the expected number.</value>
+ </data>
+ <data name="Arg_ThreadStartException" xml:space="preserve">
+ <value>Thread failed to start.</value>
+ </data>
+ <data name="Arg_ThreadStateException" xml:space="preserve">
+ <value>Thread was in an invalid state for the operation being executed.</value>
+ </data>
+ <data name="Arg_TimeoutException" xml:space="preserve">
+ <value>The operation has timed out.</value>
+ </data>
+ <data name="Arg_TypeAccessException" xml:space="preserve">
+ <value>Attempt to access the type failed.</value>
+ </data>
+ <data name="Arg_TypedReference_Null" xml:space="preserve">
+ <value>The TypedReference must be initialized.</value>
+ </data>
+ <data name="Arg_TypeLoadException" xml:space="preserve">
+ <value>Failure has occurred while loading a type.</value>
+ </data>
+ <data name="Arg_TypeLoadNullStr" xml:space="preserve">
+ <value>A null or zero length string does not represent a valid Type.</value>
+ </data>
+ <data name="Arg_TypeRefPrimitve" xml:space="preserve">
+ <value>TypedReferences cannot be redefined as primitives.</value>
+ </data>
+ <data name="Arg_TypeUnloadedException" xml:space="preserve">
+ <value>Type had been unloaded.</value>
+ </data>
+ <data name="Arg_UnauthorizedAccessException" xml:space="preserve">
+ <value>Attempted to perform an unauthorized operation.</value>
+ </data>
+ <data name="Arg_UnboundGenField" xml:space="preserve">
+ <value>Late bound operations cannot be performed on fields with types for which Type.ContainsGenericParameters is true.</value>
+ </data>
+ <data name="Arg_UnboundGenParam" xml:space="preserve">
+ <value>Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.</value>
+ </data>
+ <data name="Arg_UnknownTypeCode" xml:space="preserve">
+ <value>Unknown TypeCode value.</value>
+ </data>
+ <data name="Arg_VarMissNull" xml:space="preserve">
+ <value>Missing parameter does not have a default value.</value>
+ </data>
+ <data name="Arg_VersionString" xml:space="preserve">
+ <value>Version string portion was too short or too long.</value>
+ </data>
+ <data name="Arg_WrongAsyncResult" xml:space="preserve">
+ <value>IAsyncResult object did not come from the corresponding async method on this type.</value>
+ </data>
+ <data name="Arg_WrongType" xml:space="preserve">
+ <value>The value "{0}" is not of type "{1}" and cannot be used in this generic collection.</value>
+ </data>
+ <data name="Argument_AbsolutePathRequired" xml:space="preserve">
+ <value>Absolute path information is required.</value>
+ </data>
+ <data name="Argument_AddingDuplicate" xml:space="preserve">
+ <value>An item with the same key has already been added.</value>
+ </data>
+ <data name="Argument_AddingDuplicate__" xml:space="preserve">
+ <value>Item has already been added. Key in dictionary: '{0}' Key being added: '{1}'</value>
+ </data>
+ <data name="Argument_AddingDuplicateWithKey" xml:space="preserve">
+ <value>An item with the same key has already been added. Key: {0}</value>
+ </data>
+ <data name="Argument_AdjustmentRulesNoNulls" xml:space="preserve">
+ <value>The AdjustmentRule array cannot contain null elements.</value>
+ </data>
+ <data name="Argument_AdjustmentRulesOutOfOrder" xml:space="preserve">
+ <value>The elements of the AdjustmentRule array must be in chronological order and must not overlap.</value>
+ </data>
+ <data name="Argument_AlreadyACCW" xml:space="preserve">
+ <value>The object already has a CCW associated with it.</value>
+ </data>
+ <data name="Argument_AlreadyBoundOrSyncHandle" xml:space="preserve">
+ <value>'handle' has already been bound to the thread pool, or was not opened for asynchronous I/O.</value>
+ </data>
+ <data name="Argument_ArgumentZero" xml:space="preserve">
+ <value>Argument cannot be zero.</value>
+ </data>
+ <data name="Argument_ArrayGetInterfaceMap" xml:space="preserve">
+ <value>Interface maps for generic interfaces on arrays cannot be retrieved.</value>
+ </data>
+ <data name="Argument_ArraysInvalid" xml:space="preserve">
+ <value>Array or pointer types are not valid.</value>
+ </data>
+ <data name="Argument_BadAttributeOnInterfaceMethod" xml:space="preserve">
+ <value>Interface method must be abstract and virtual.</value>
+ </data>
+ <data name="Argument_BadConstantValue" xml:space="preserve">
+ <value>Bad default value.</value>
+ </data>
+ <data name="Argument_BadConstructor" xml:space="preserve">
+ <value>Cannot have private or static constructor.</value>
+ </data>
+ <data name="Argument_BadConstructorCallConv" xml:space="preserve">
+ <value>Constructor must have standard calling convention.</value>
+ </data>
+ <data name="Argument_BadExceptionCodeGen" xml:space="preserve">
+ <value>Incorrect code generation for exception block.</value>
+ </data>
+ <data name="Argument_BadFieldForConstructorBuilder" xml:space="preserve">
+ <value>Field must be on the same type of the given ConstructorInfo.</value>
+ </data>
+ <data name="Argument_BadFieldSig" xml:space="preserve">
+ <value>Field signatures do not have return types.</value>
+ </data>
+ <data name="Argument_BadFieldType" xml:space="preserve">
+ <value>Bad field type in defining field.</value>
+ </data>
+ <data name="Argument_BadFormatSpecifier" xml:space="preserve">
+ <value>Format specifier was invalid.</value>
+ </data>
+ <data name="Argument_BadImageFormatExceptionResolve" xml:space="preserve">
+ <value>A BadImageFormatException has been thrown while parsing the signature. This is likely due to lack of a generic context. Ensure genericTypeArguments and genericMethodArguments are provided and contain enough context.</value>
+ </data>
+ <data name="Argument_BadLabel" xml:space="preserve">
+ <value>Bad label in ILGenerator.</value>
+ </data>
+ <data name="Argument_BadLabelContent" xml:space="preserve">
+ <value>Bad label content in ILGenerator.</value>
+ </data>
+ <data name="Argument_BadNestedTypeFlags" xml:space="preserve">
+ <value>Visibility of interfaces must be one of the following: NestedAssembly, NestedFamANDAssem, NestedFamily, NestedFamORAssem, NestedPrivate or NestedPublic.</value>
+ </data>
+ <data name="Argument_BadObjRef" xml:space="preserve">
+ <value>Invalid ObjRef provided to '{0}'.</value>
+ </data>
+ <data name="Argument_BadParameterCountsForConstructor" xml:space="preserve">
+ <value>Parameter count does not match passed in argument value count.</value>
+ </data>
+ <data name="Argument_BadParameterTypeForCAB" xml:space="preserve">
+ <value>Cannot emit a CustomAttribute with argument of type {0}.</value>
+ </data>
+ <data name="Argument_BadPropertyForConstructorBuilder" xml:space="preserve">
+ <value>Property must be on the same type of the given ConstructorInfo.</value>
+ </data>
+ <data name="Argument_BadSigFormat" xml:space="preserve">
+ <value>Incorrect signature format.</value>
+ </data>
+ <data name="Argument_BadSizeForData" xml:space="preserve">
+ <value>Data size must be &gt; 1 and &lt; 0x3f0000</value>
+ </data>
+ <data name="Argument_BadTypeAttrInvalidLayout" xml:space="preserve">
+ <value>Bad type attributes. Invalid layout attribute specified.</value>
+ </data>
+ <data name="Argument_BadTypeAttrNestedVisibilityOnNonNestedType" xml:space="preserve">
+ <value>Bad type attributes. Nested visibility flag set on a non-nested type.</value>
+ </data>
+ <data name="Argument_BadTypeAttrNonNestedVisibilityNestedType" xml:space="preserve">
+ <value>Bad type attributes. Non-nested visibility flag set on a nested type.</value>
+ </data>
+ <data name="Argument_BadTypeAttrReservedBitsSet" xml:space="preserve">
+ <value>Bad type attributes. Reserved bits set on the type.</value>
+ </data>
+ <data name="Argument_BadTypeInCustomAttribute" xml:space="preserve">
+ <value>An invalid type was used as a custom attribute constructor argument, field or property.</value>
+ </data>
+ <data name="Argument_CannotCreateTypedReference" xml:space="preserve">
+ <value>Cannot use function evaluation to create a TypedReference object.</value>
+ </data>
+ <data name="Argument_CannotGetTypeTokenForByRef" xml:space="preserve">
+ <value>Cannot get TypeToken for a ByRef type.</value>
+ </data>
+ <data name="Argument_CannotSetParentToInterface" xml:space="preserve">
+ <value>Cannot set parent to an interface.</value>
+ </data>
+ <data name="Argument_CantCallSecObjFunc" xml:space="preserve">
+ <value>Cannot evaluate a security function.</value>
+ </data>
+ <data name="Argument_CodepageNotSupported" xml:space="preserve">
+ <value>{0} is not a supported code page.</value>
+ </data>
+ <data name="Argument_CompareOptionOrdinal" xml:space="preserve">
+ <value>CompareOption.Ordinal cannot be used with other options.</value>
+ </data>
+ <data name="Argument_ConflictingDateTimeRoundtripStyles" xml:space="preserve">
+ <value>The DateTimeStyles value RoundtripKind cannot be used with the values AssumeLocal, AssumeUniversal or AdjustToUniversal.</value>
+ </data>
+ <data name="Argument_ConflictingDateTimeStyles" xml:space="preserve">
+ <value>The DateTimeStyles values AssumeLocal and AssumeUniversal cannot be used together.</value>
+ </data>
+ <data name="Argument_ConstantDoesntMatch" xml:space="preserve">
+ <value>Constant does not match the defined type.</value>
+ </data>
+ <data name="Argument_ConstantNotSupported" xml:space="preserve">
+ <value>{0} is not a supported constant type.</value>
+ </data>
+ <data name="Argument_ConstantNull" xml:space="preserve">
+ <value>Null is not a valid constant value for this type.</value>
+ </data>
+ <data name="Argument_ConstructorNeedGenericDeclaringType" xml:space="preserve">
+ <value>The specified constructor must be declared on a generic type definition.</value>
+ </data>
+ <data name="Argument_ConversionOverflow" xml:space="preserve">
+ <value>Conversion buffer overflow.</value>
+ </data>
+ <data name="Argument_ConvertMismatch" xml:space="preserve">
+ <value>The conversion could not be completed because the supplied DateTime did not have the Kind property set correctly. For example, when the Kind property is DateTimeKind.Local, the source time zone must be TimeZoneInfo.Local.</value>
+ </data>
+ <data name="Argument_CORDBBadMethod" xml:space="preserve">
+ <value>Cannot find the method on the object instance.</value>
+ </data>
+ <data name="Argument_CORDBBadVarArgCallConv" xml:space="preserve">
+ <value>Cannot evaluate a VarArgs function.</value>
+ </data>
+ <data name="Argument_CultureIetfNotSupported" xml:space="preserve">
+ <value>Culture IETF Name {0} is not a recognized IETF name.</value>
+ </data>
+ <data name="Argument_CultureInvalidIdentifier" xml:space="preserve">
+ <value>{0} is an invalid culture identifier.</value>
+ </data>
+ <data name="Argument_CultureIsNeutral" xml:space="preserve">
+ <value>Culture ID {0} (0x{0:X4}) is a neutral culture; a region cannot be created from it.</value>
+ </data>
+ <data name="Argument_CultureNotSupported" xml:space="preserve">
+ <value>Culture is not supported.</value>
+ </data>
+ <data name="Argument_CustomAssemblyLoadContextRequestedNameMismatch" xml:space="preserve">
+ <value>Resolved assembly's simple name should be the same as of the requested assembly.</value>
+ </data>
+ <data name="Argument_CustomCultureCannotBePassedByNumber" xml:space="preserve">
+ <value>Customized cultures cannot be passed by LCID, only by name.</value>
+ </data>
+ <data name="Argument_DateTimeBadBinaryData" xml:space="preserve">
+ <value>The binary data must result in a DateTime with ticks between DateTime.MinValue.Ticks and DateTime.MaxValue.Ticks.</value>
+ </data>
+ <data name="Argument_DateTimeHasTicks" xml:space="preserve">
+ <value>The supplied DateTime must have the Year, Month, and Day properties set to 1. The time cannot be specified more precisely than whole milliseconds.</value>
+ </data>
+ <data name="Argument_DateTimeHasTimeOfDay" xml:space="preserve">
+ <value>The supplied DateTime includes a TimeOfDay setting. This is not supported.</value>
+ </data>
+ <data name="Argument_DateTimeIsInvalid" xml:space="preserve">
+ <value>The supplied DateTime represents an invalid time. For example, when the clock is adjusted forward, any time in the period that is skipped is invalid.</value>
+ </data>
+ <data name="Argument_DateTimeIsNotAmbiguous" xml:space="preserve">
+ <value>The supplied DateTime is not in an ambiguous time range.</value>
+ </data>
+ <data name="Argument_DateTimeKindMustBeUnspecified" xml:space="preserve">
+ <value>The supplied DateTime must have the Kind property set to DateTimeKind.Unspecified.</value>
+ </data>
+ <data name="Argument_DateTimeKindMustBeUnspecifiedOrUtc" xml:space="preserve">
+ <value>The supplied DateTime must have the Kind property set to DateTimeKind.Unspecified or DateTimeKind.Utc.</value>
+ </data>
+ <data name="Argument_DateTimeOffsetInvalidDateTimeStyles" xml:space="preserve">
+ <value>The DateTimeStyles value 'NoCurrentDateDefault' is not allowed when parsing DateTimeOffset.</value>
+ </data>
+ <data name="Argument_DateTimeOffsetIsNotAmbiguous" xml:space="preserve">
+ <value>The supplied DateTimeOffset is not in an ambiguous time range.</value>
+ </data>
+ <data name="Argument_DestinationTooShort" xml:space="preserve">
+ <value>Destination is too short.</value>
+ </data>
+ <data name="Argument_DuplicateTypeName" xml:space="preserve">
+ <value>Duplicate type name within an assembly.</value>
+ </data>
+ <data name="Argument_EmitWriteLineType" xml:space="preserve">
+ <value>EmitWriteLine does not support this field or local type.</value>
+ </data>
+ <data name="Argument_EmptyDecString" xml:space="preserve">
+ <value>Decimal separator cannot be the empty string.</value>
+ </data>
+ <data name="Argument_EmptyFileName" xml:space="preserve">
+ <value>Empty file name is not legal.</value>
+ </data>
+ <data name="Argument_EmptyName" xml:space="preserve">
+ <value>Empty name is not legal.</value>
+ </data>
+ <data name="Argument_EmptyPath" xml:space="preserve">
+ <value>Empty path name is not legal.</value>
+ </data>
+ <data name="Argument_EmptyWaithandleArray" xml:space="preserve">
+ <value>Waithandle array may not be empty.</value>
+ </data>
+ <data name="Argument_EncoderFallbackNotEmpty" xml:space="preserve">
+ <value>Must complete Convert() operation or call Encoder.Reset() before calling GetBytes() or GetByteCount(). Encoder '{0}' fallback '{1}'.</value>
+ </data>
+ <data name="Argument_EncodingConversionOverflowBytes" xml:space="preserve">
+ <value>The output byte buffer is too small to contain the encoded data, encoding '{0}' fallback '{1}'.</value>
+ </data>
+ <data name="Argument_EncodingConversionOverflowChars" xml:space="preserve">
+ <value>The output char buffer is too small to contain the decoded characters, encoding '{0}' fallback '{1}'.</value>
+ </data>
+ <data name="Argument_EncodingNotSupported" xml:space="preserve">
+ <value>'{0}' is not a supported encoding name. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.</value>
+ </data>
+ <data name="Argument_EnumTypeDoesNotMatch" xml:space="preserve">
+ <value>The argument type, '{0}', is not the same as the enum type '{1}'.</value>
+ </data>
+ <data name="Argument_FallbackBufferNotEmpty" xml:space="preserve">
+ <value>Cannot change fallback when buffer is not empty. Previous Convert() call left data in the fallback buffer.</value>
+ </data>
+ <data name="Argument_FieldDeclaringTypeGeneric" xml:space="preserve">
+ <value>Cannot resolve field {0} because the declaring type of the field handle {1} is generic. Explicitly provide the declaring type to GetFieldFromHandle.</value>
+ </data>
+ <data name="Argument_FieldNeedGenericDeclaringType" xml:space="preserve">
+ <value>The specified field must be declared on a generic type definition.</value>
+ </data>
+ <data name="Argument_GenConstraintViolation" xml:space="preserve">
+ <value>GenericArguments[{0}], '{1}', on '{2}' violates the constraint of type '{3}'.</value>
+ </data>
+ <data name="Argument_GenericArgsCount" xml:space="preserve">
+ <value>The number of generic arguments provided doesn't equal the arity of the generic type definition.</value>
+ </data>
+ <data name="Argument_GenericsInvalid" xml:space="preserve">
+ <value>Generic types are not valid.</value>
+ </data>
+ <data name="Argument_GlobalFunctionHasToBeStatic" xml:space="preserve">
+ <value>Global members must be static.</value>
+ </data>
+ <data name="Argument_HandleLeak" xml:space="preserve">
+ <value>Cannot pass a GCHandle across AppDomains.</value>
+ </data>
+ <data name="Argument_HasToBeArrayClass" xml:space="preserve">
+ <value>Must be an array type.</value>
+ </data>
+ <data name="Argument_IdnBadBidi" xml:space="preserve">
+ <value>Left to right characters may not be mixed with right to left characters in IDN labels.</value>
+ </data>
+ <data name="Argument_IdnBadLabelSize" xml:space="preserve">
+ <value>IDN labels must be between 1 and 63 characters long.</value>
+ </data>
+ <data name="Argument_IdnBadNameSize" xml:space="preserve">
+ <value>IDN names must be between 1 and {0} characters long.</value>
+ </data>
+ <data name="Argument_IdnBadPunycode" xml:space="preserve">
+ <value>Invalid IDN encoded string.</value>
+ </data>
+ <data name="Argument_IdnBadStd3" xml:space="preserve">
+ <value>Label contains character '{0}' not allowed with UseStd3AsciiRules</value>
+ </data>
+ <data name="Argument_IdnIllegalName" xml:space="preserve">
+ <value>Decoded string is not a valid IDN name.</value>
+ </data>
+ <data name="Argument_IllegalEnvVarName" xml:space="preserve">
+ <value>Environment variable name cannot contain equal character.</value>
+ </data>
+ <data name="Argument_IllegalName" xml:space="preserve">
+ <value>Illegal name.</value>
+ </data>
+ <data name="Argument_ImplementIComparable" xml:space="preserve">
+ <value>At least one object must implement IComparable.</value>
+ </data>
+ <data name="Argument_IndexOutOfArrayBounds" xml:space="preserve">
+ <value>The specified index is out of bounds of the specified array.</value>
+ </data>
+ <data name="Argument_InsufficientSpaceToCopyCollection" xml:space="preserve">
+ <value>The specified space is not sufficient to copy the elements from this Collection.</value>
+ </data>
+ <data name="Argument_InterfaceMap" xml:space="preserve">
+ <value>'this' type cannot be an interface itself.</value>
+ </data>
+ <data name="Argument_InvalidAppendMode" xml:space="preserve">
+ <value>Append access can be requested only in write-only mode.</value>
+ </data>
+ <data name="Argument_InvalidArgumentForComparison" xml:space="preserve">
+ <value>Type of argument is not compatible with the generic comparer.</value>
+ </data>
+ <data name="Argument_InvalidArrayLength" xml:space="preserve">
+ <value>Length of the array must be {0}.</value>
+ </data>
+ <data name="Argument_InvalidArrayType" xml:space="preserve">
+ <value>Target array type is not compatible with the type of items in the collection.</value>
+ </data>
+ <data name="Argument_InvalidAssemblyName" xml:space="preserve">
+ <value>Assembly names may not begin with whitespace or contain the characters '/', or '\\' or ':'.</value>
+ </data>
+ <data name="Argument_InvalidCalendar" xml:space="preserve">
+ <value>Not a valid calendar for the given culture.</value>
+ </data>
+ <data name="Argument_InvalidCharSequence" xml:space="preserve">
+ <value>Invalid Unicode code point found at index {0}.</value>
+ </data>
+ <data name="Argument_InvalidCharSequenceNoIndex" xml:space="preserve">
+ <value>String contains invalid Unicode code points.</value>
+ </data>
+ <data name="Argument_InvalidCodePageBytesIndex" xml:space="preserve">
+ <value>Unable to translate bytes {0} at index {1} from specified code page to Unicode.</value>
+ </data>
+ <data name="Argument_InvalidCodePageConversionIndex" xml:space="preserve">
+ <value>Unable to translate Unicode character \\u{0:X4} at index {1} to specified code page.</value>
+ </data>
+ <data name="Argument_InvalidConstructorDeclaringType" xml:space="preserve">
+ <value>The specified constructor must be declared on the generic type definition of the specified type.</value>
+ </data>
+ <data name="Argument_InvalidConstructorInfo" xml:space="preserve">
+ <value>The ConstructorInfo object is not valid.</value>
+ </data>
+ <data name="Argument_InvalidCultureName" xml:space="preserve">
+ <value>Culture name '{0}' is not supported.</value>
+ </data>
+ <data name="Argument_InvalidDateTimeKind" xml:space="preserve">
+ <value>Invalid DateTimeKind value.</value>
+ </data>
+ <data name="Argument_InvalidDateTimeStyles" xml:space="preserve">
+ <value>An undefined DateTimeStyles value is being used.</value>
+ </data>
+ <data name="Argument_InvalidDigitSubstitution" xml:space="preserve">
+ <value>The DigitSubstitution property must be of a valid member of the DigitShapes enumeration. Valid entries include Context, NativeNational or None.</value>
+ </data>
+ <data name="Argument_InvalidEnum" xml:space="preserve">
+ <value>The Enum type should contain one and only one instance field.</value>
+ </data>
+ <data name="Argument_InvalidEnumValue" xml:space="preserve">
+ <value>The value '{0}' is not valid for this usage of the type {1}.</value>
+ </data>
+ <data name="Argument_InvalidFieldDeclaringType" xml:space="preserve">
+ <value>The specified field must be declared on the generic type definition of the specified type.</value>
+ </data>
+ <data name="Argument_InvalidFileModeAndAccessCombo" xml:space="preserve">
+ <value>Combining FileMode: {0} with FileAccess: {1} is invalid.</value>
+ </data>
+ <data name="Argument_InvalidFlag" xml:space="preserve">
+ <value>Value of flags is invalid.</value>
+ </data>
+ <data name="Argument_InvalidGenericArg" xml:space="preserve">
+ <value>The generic type parameter was not valid</value>
+ </data>
+ <data name="Argument_InvalidGenericInstArray" xml:space="preserve">
+ <value>Generic arguments must be provided for each generic parameter and each generic argument must be a RuntimeType.</value>
+ </data>
+ <data name="Argument_InvalidGroupSize" xml:space="preserve">
+ <value>Every element in the value array should be between one and nine, except for the last element, which can be zero.</value>
+ </data>
+ <data name="Argument_InvalidHandle" xml:space="preserve">
+ <value>The handle is invalid.</value>
+ </data>
+ <data name="Argument_InvalidHighSurrogate" xml:space="preserve">
+ <value>Found a high surrogate char without a following low surrogate at index: {0}. The input may not be in this encoding, or may not contain valid Unicode (UTF-16) characters.</value>
+ </data>
+ <data name="Argument_InvalidId" xml:space="preserve">
+ <value>The specified ID parameter '{0}' is not supported.</value>
+ </data>
+ <data name="Argument_InvalidKindOfTypeForCA" xml:space="preserve">
+ <value>This type cannot be represented as a custom attribute.</value>
+ </data>
+ <data name="Argument_InvalidLabel" xml:space="preserve">
+ <value>Invalid Label.</value>
+ </data>
+ <data name="Argument_InvalidLowSurrogate" xml:space="preserve">
+ <value>Found a low surrogate char without a preceding high surrogate at index: {0}. The input may not be in this encoding, or may not contain valid Unicode (UTF-16) characters.</value>
+ </data>
+ <data name="Argument_InvalidMemberForNamedArgument" xml:space="preserve">
+ <value>The member must be either a field or a property.</value>
+ </data>
+ <data name="Argument_InvalidMethodDeclaringType" xml:space="preserve">
+ <value>The specified method must be declared on the generic type definition of the specified type.</value>
+ </data>
+ <data name="Argument_InvalidName" xml:space="preserve">
+ <value>Invalid name.</value>
+ </data>
+ <data name="Argument_InvalidNativeDigitCount" xml:space="preserve">
+ <value>The NativeDigits array must contain exactly ten members.</value>
+ </data>
+ <data name="Argument_InvalidNativeDigitValue" xml:space="preserve">
+ <value>Each member of the NativeDigits array must be a single text element (one or more UTF16 code points) with a Unicode Nd (Number, Decimal Digit) property indicating it is a digit.</value>
+ </data>
+ <data name="Argument_InvalidNeutralRegionName" xml:space="preserve">
+ <value>The region name {0} should not correspond to neutral culture; a specific culture name is required.</value>
+ </data>
+ <data name="Argument_InvalidNormalizationForm" xml:space="preserve">
+ <value>Invalid or unsupported normalization form.</value>
+ </data>
+ <data name="Argument_InvalidNumberStyles" xml:space="preserve">
+ <value>An undefined NumberStyles value is being used.</value>
+ </data>
+ <data name="Argument_InvalidOffLen" xml:space="preserve">
+ <value>Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.</value>
+ </data>
+ <data name="Argument_InvalidOpCodeOnDynamicMethod" xml:space="preserve">
+ <value>Ldtoken, Ldftn and Ldvirtftn OpCodes cannot target DynamicMethods.</value>
+ </data>
+ <data name="Argument_InvalidParameterInfo" xml:space="preserve">
+ <value>The ParameterInfo object is not valid.</value>
+ </data>
+ <data name="Argument_InvalidParamInfo" xml:space="preserve">
+ <value>Invalid type for ParameterInfo member in Attribute class.</value>
+ </data>
+ <data name="Argument_InvalidPathChars" xml:space="preserve">
+ <value>Illegal characters in path.</value>
+ </data>
+ <data name="Argument_InvalidREG_TZI_FORMAT" xml:space="preserve">
+ <value>The REG_TZI_FORMAT structure is corrupt.</value>
+ </data>
+ <data name="Argument_InvalidRegistryViewCheck" xml:space="preserve">
+ <value>The specified RegistryView value is invalid.</value>
+ </data>
+ <data name="Argument_InvalidResourceCultureName" xml:space="preserve">
+ <value>The given culture name '{0}' cannot be used to locate a resource file. Resource filenames must consist of only letters, numbers, hyphens or underscores.</value>
+ </data>
+ <data name="Argument_InvalidSafeBufferOffLen" xml:space="preserve">
+ <value>Offset and length were greater than the size of the SafeBuffer.</value>
+ </data>
+ <data name="Argument_InvalidSeekOrigin" xml:space="preserve">
+ <value>Invalid seek origin.</value>
+ </data>
+ <data name="Argument_InvalidSerializedString" xml:space="preserve">
+ <value>The specified serialized string '{0}' is not supported.</value>
+ </data>
+ <data name="Argument_InvalidTimeSpanStyles" xml:space="preserve">
+ <value>An undefined TimeSpanStyles value is being used.</value>
+ </data>
+ <data name="Argument_InvalidToken" xml:space="preserve">
+ <value>Token {0:x} is not valid in the scope of module {1}.</value>
+ </data>
+ <data name="Argument_InvalidTypeForCA" xml:space="preserve">
+ <value>Cannot build type parameter for custom attribute with a type that does not support the AssemblyQualifiedName property. The type instance supplied was of type '{0}'.</value>
+ </data>
+ <data name="Argument_InvalidTypeForDynamicMethod" xml:space="preserve">
+ <value>Invalid type owner for DynamicMethod.</value>
+ </data>
+ <data name="Argument_InvalidTypeName" xml:space="preserve">
+ <value>The name of the type is invalid.</value>
+ </data>
+ <data name="Argument_InvalidTypeWithPointersNotSupported" xml:space="preserve">
+ <value>Cannot use type '{0}'. Only value types without pointers or references are supported.</value>
+ </data>
+ <data name="Argument_InvalidUnity" xml:space="preserve">
+ <value>Invalid Unity type.</value>
+ </data>
+ <data name="Argument_InvalidValue" xml:space="preserve">
+ <value>Value was invalid.</value>
+ </data>
+ <data name="Argument_LargeInteger" xml:space="preserve">
+ <value>Integer or token was too large to be encoded.</value>
+ </data>
+ <data name="Argument_LongEnvVarValue" xml:space="preserve">
+ <value>Environment variable name or value is too long.</value>
+ </data>
+ <data name="Argument_MethodDeclaringTypeGeneric" xml:space="preserve">
+ <value>Cannot resolve method {0} because the declaring type of the method handle {1} is generic. Explicitly provide the declaring type to GetMethodFromHandle.</value>
+ </data>
+ <data name="Argument_MethodDeclaringTypeGenericLcg" xml:space="preserve">
+ <value>Method '{0}' has a generic declaring type '{1}'. Explicitly provide the declaring type to GetTokenFor.</value>
+ </data>
+ <data name="Argument_MethodNeedGenericDeclaringType" xml:space="preserve">
+ <value>The specified method cannot be dynamic or global and must be declared on a generic type definition.</value>
+ </data>
+ <data name="Argument_MinMaxValue" xml:space="preserve">
+ <value>'{0}' cannot be greater than {1}.</value>
+ </data>
+ <data name="Argument_MismatchedArrays" xml:space="preserve">
+ <value>Two arrays, {0} and {1}, must be of the same size.</value>
+ </data>
+ <data name="Argument_MissingDefaultConstructor" xml:space="preserve">
+ <value>was missing default constructor.</value>
+ </data>
+ <data name="Argument_MustBeFalse" xml:space="preserve">
+ <value>Argument must be initialized to false</value>
+ </data>
+ <data name="Argument_MustBeRuntimeAssembly" xml:space="preserve">
+ <value>Assembly must be a runtime Assembly object.</value>
+ </data>
+ <data name="Argument_MustBeRuntimeFieldInfo" xml:space="preserve">
+ <value>FieldInfo must be a runtime FieldInfo object.</value>
+ </data>
+ <data name="Argument_MustBeRuntimeMethodInfo" xml:space="preserve">
+ <value>MethodInfo must be a runtime MethodInfo object.</value>
+ </data>
+ <data name="Argument_MustBeRuntimeModule" xml:space="preserve">
+ <value>Module must be a runtime Module object.</value>
+ </data>
+ <data name="Argument_MustBeRuntimeReflectionObject" xml:space="preserve">
+ <value>The object must be a runtime Reflection object.</value>
+ </data>
+ <data name="Argument_MustBeRuntimeType" xml:space="preserve">
+ <value>Type must be a runtime Type object.</value>
+ </data>
+ <data name="Argument_MustBeTypeBuilder" xml:space="preserve">
+ <value>'type' must contain a TypeBuilder as a generic argument.</value>
+ </data>
+ <data name="Argument_MustHaveAttributeBaseClass" xml:space="preserve">
+ <value>Type passed in must be derived from System.Attribute or System.Attribute itself.</value>
+ </data>
+ <data name="Argument_MustHaveLayoutOrBeBlittable" xml:space="preserve">
+ <value>The specified structure must be blittable or have layout information.</value>
+ </data>
+ <data name="Argument_NativeOverlappedAlreadyFree" xml:space="preserve">
+ <value>'overlapped' has already been freed.</value>
+ </data>
+ <data name="Argument_NativeOverlappedWrongBoundHandle" xml:space="preserve">
+ <value>'overlapped' was not allocated by this ThreadPoolBoundHandle instance.</value>
+ </data>
+ <data name="Argument_NeedGenericMethodDefinition" xml:space="preserve">
+ <value>Method must represent a generic method definition on a generic type definition.</value>
+ </data>
+ <data name="Argument_NeedNonGenericObject" xml:space="preserve">
+ <value>The specified object must not be an instance of a generic type.</value>
+ </data>
+ <data name="Argument_NeedNonGenericType" xml:space="preserve">
+ <value>The specified Type must not be a generic type definition.</value>
+ </data>
+ <data name="Argument_NeedStructWithNoRefs" xml:space="preserve">
+ <value>The specified Type must be a struct containing no references.</value>
+ </data>
+ <data name="Argument_NeverValidGenericArgument" xml:space="preserve">
+ <value>The type '{0}' may not be used as a type argument.</value>
+ </data>
+ <data name="Argument_NoDomainManager" xml:space="preserve">
+ <value>The domain manager specified by the host could not be instantiated.</value>
+ </data>
+ <data name="Argument_NoEra" xml:space="preserve">
+ <value>No Era was supplied.</value>
+ </data>
+ <data name="Argument_NoModuleFileExtension" xml:space="preserve">
+ <value>Module file name '{0}' must have file extension.</value>
+ </data>
+ <data name="Argument_NoRegionInvariantCulture" xml:space="preserve">
+ <value>There is no region associated with the Invariant Culture (Culture ID: 0x7F).</value>
+ </data>
+ <data name="Argument_NotATP" xml:space="preserve">
+ <value>Type must be a TransparentProxy</value>
+ </data>
+ <data name="Argument_NotAWritableProperty" xml:space="preserve">
+ <value>Not a writable property.</value>
+ </data>
+ <data name="Argument_NotEnoughBytesToRead" xml:space="preserve">
+ <value>There are not enough bytes remaining in the accessor to read at this position.</value>
+ </data>
+ <data name="Argument_NotEnoughBytesToWrite" xml:space="preserve">
+ <value>There are not enough bytes remaining in the accessor to write at this position.</value>
+ </data>
+ <data name="Argument_NotEnoughGenArguments" xml:space="preserve">
+ <value>The type or method has {1} generic parameter(s), but {0} generic argument(s) were provided. A generic argument must be provided for each generic parameter.</value>
+ </data>
+ <data name="Argument_NotExceptionType" xml:space="preserve">
+ <value>Does not extend Exception.</value>
+ </data>
+ <data name="Argument_NotInExceptionBlock" xml:space="preserve">
+ <value>Not currently in an exception block.</value>
+ </data>
+ <data name="Argument_NotMethodCallOpcode" xml:space="preserve">
+ <value>The specified opcode cannot be passed to EmitCall.</value>
+ </data>
+ <data name="Argument_NotSerializable" xml:space="preserve">
+ <value>Argument passed in is not serializable.</value>
+ </data>
+ <data name="Argument_NoUnderlyingCCW" xml:space="preserve">
+ <value>The object has no underlying COM data associated with it.</value>
+ </data>
+ <data name="Argument_NoUninitializedStrings" xml:space="preserve">
+ <value>Uninitialized Strings cannot be created.</value>
+ </data>
+ <data name="Argument_ObjIsWinRTObject" xml:space="preserve">
+ <value>The object's type must not be a Windows Runtime type.</value>
+ </data>
+ <data name="Argument_ObjNotComObject" xml:space="preserve">
+ <value>The object's type must be __ComObject or derived from __ComObject.</value>
+ </data>
+ <data name="Argument_OffsetAndCapacityOutOfBounds" xml:space="preserve">
+ <value>Offset and capacity were greater than the size of the view.</value>
+ </data>
+ <data name="Argument_OffsetAndLengthOutOfBounds" xml:space="preserve">
+ <value>Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.</value>
+ </data>
+ <data name="Argument_OffsetLocalMismatch" xml:space="preserve">
+ <value>The UTC Offset of the local dateTime parameter does not match the offset argument.</value>
+ </data>
+ <data name="Argument_OffsetOfFieldNotFound" xml:space="preserve">
+ <value>Field passed in is not a marshaled member of the type '{0}'.</value>
+ </data>
+ <data name="Argument_OffsetOutOfRange" xml:space="preserve">
+ <value>Offset must be within plus or minus 14 hours.</value>
+ </data>
+ <data name="Argument_OffsetPrecision" xml:space="preserve">
+ <value>Offset must be specified in whole minutes.</value>
+ </data>
+ <data name="Argument_OffsetUtcMismatch" xml:space="preserve">
+ <value>The UTC Offset for Utc DateTime instances must be 0.</value>
+ </data>
+ <data name="Argument_OneOfCulturesNotSupported" xml:space="preserve">
+ <value>Culture name {0} or {1} is not supported.</value>
+ </data>
+ <data name="Argument_OnlyMscorlib" xml:space="preserve">
+ <value>Only mscorlib's assembly is valid.</value>
+ </data>
+ <data name="Argument_OutOfOrderDateTimes" xml:space="preserve">
+ <value>The DateStart property must come before the DateEnd property.</value>
+ </data>
+ <data name="Argument_PathEmpty" xml:space="preserve">
+ <value>Path cannot be the empty string or all whitespace.</value>
+ </data>
+ <data name="Argument_PathFormatNotSupported" xml:space="preserve">
+ <value>The given path's format is not supported.</value>
+ </data>
+ <data name="Argument_PreAllocatedAlreadyAllocated" xml:space="preserve">
+ <value>'preAllocated' is already in use.</value>
+ </data>
+ <data name="Argument_RecursiveFallback" xml:space="preserve">
+ <value>Recursive fallback not allowed for character \\u{0:X4}.</value>
+ </data>
+ <data name="Argument_RecursiveFallbackBytes" xml:space="preserve">
+ <value>Recursive fallback not allowed for bytes {0}.</value>
+ </data>
+ <data name="Argument_RedefinedLabel" xml:space="preserve">
+ <value>Label multiply defined.</value>
+ </data>
+ <data name="Argument_ResolveField" xml:space="preserve">
+ <value>Token {0:x} is not a valid FieldInfo token in the scope of module {1}.</value>
+ </data>
+ <data name="Argument_ResolveFieldHandle" xml:space="preserve">
+ <value>Type handle '{0}' and field handle with declaring type '{1}' are incompatible. Get RuntimeFieldHandle and declaring RuntimeTypeHandle off the same FieldInfo.</value>
+ </data>
+ <data name="Argument_ResolveMember" xml:space="preserve">
+ <value>Token {0:x} is not a valid MemberInfo token in the scope of module {1}.</value>
+ </data>
+ <data name="Argument_ResolveMethod" xml:space="preserve">
+ <value>Token {0:x} is not a valid MethodBase token in the scope of module {1}.</value>
+ </data>
+ <data name="Argument_ResolveMethodHandle" xml:space="preserve">
+ <value>Type handle '{0}' and method handle with declaring type '{1}' are incompatible. Get RuntimeMethodHandle and declaring RuntimeTypeHandle off the same MethodBase.</value>
+ </data>
+ <data name="Argument_ResolveModuleType" xml:space="preserve">
+ <value>Token {0} resolves to the special module type representing this module.</value>
+ </data>
+ <data name="Argument_ResolveString" xml:space="preserve">
+ <value>Token {0:x} is not a valid string token in the scope of module {1}.</value>
+ </data>
+ <data name="Argument_ResolveType" xml:space="preserve">
+ <value>Token {0:x} is not a valid Type token in the scope of module {1}.</value>
+ </data>
+ <data name="Argument_ResultCalendarRange" xml:space="preserve">
+ <value>The result is out of the supported range for this calendar. The result should be between {0} (Gregorian date) and {1} (Gregorian date), inclusive.</value>
+ </data>
+ <data name="Argument_SemaphoreInitialMaximum" xml:space="preserve">
+ <value>The initial count for the semaphore must be greater than or equal to zero and less than the maximum count.</value>
+ </data>
+ <data name="Argument_ShouldNotSpecifyExceptionType" xml:space="preserve">
+ <value>Should not specify exception type for catch clause for filter block.</value>
+ </data>
+ <data name="Argument_ShouldOnlySetVisibilityFlags" xml:space="preserve">
+ <value>Should only set visibility flags when creating EnumBuilder.</value>
+ </data>
+ <data name="Argument_SigIsFinalized" xml:space="preserve">
+ <value>Completed signature cannot be modified.</value>
+ </data>
+ <data name="Argument_StreamNotReadable" xml:space="preserve">
+ <value>Stream was not readable.</value>
+ </data>
+ <data name="Argument_StreamNotWritable" xml:space="preserve">
+ <value>Stream was not writable.</value>
+ </data>
+ <data name="Argument_StringFirstCharIsZero" xml:space="preserve">
+ <value>The first char in the string is the null character.</value>
+ </data>
+ <data name="Argument_StringZeroLength" xml:space="preserve">
+ <value>String cannot be of zero length.</value>
+ </data>
+ <data name="Argument_StructMustNotBeValueClass" xml:space="preserve">
+ <value>The structure must not be a value class.</value>
+ </data>
+ <data name="Argument_TimeSpanHasSeconds" xml:space="preserve">
+ <value>The TimeSpan parameter cannot be specified more precisely than whole minutes.</value>
+ </data>
+ <data name="Argument_TimeZoneInfoBadTZif" xml:space="preserve">
+ <value>The tzfile does not begin with the magic characters 'TZif'. Please verify that the file is not corrupt.</value>
+ </data>
+ <data name="Argument_TimeZoneInfoInvalidTZif" xml:space="preserve">
+ <value>The TZif data structure is corrupt.</value>
+ </data>
+ <data name="Argument_ToExclusiveLessThanFromExclusive" xml:space="preserve">
+ <value>fromInclusive must be less than or equal to toExclusive.</value>
+ </data>
+ <data name="Argument_TooManyFinallyClause" xml:space="preserve">
+ <value>Exception blocks may have at most one finally clause.</value>
+ </data>
+ <data name="Argument_TransitionTimesAreIdentical" xml:space="preserve">
+ <value>The DaylightTransitionStart property must not equal the DaylightTransitionEnd property.</value>
+ </data>
+ <data name="Argument_TypedReferenceInvalidField" xml:space="preserve">
+ <value>Field in TypedReferences cannot be static or init only.</value>
+ </data>
+ <data name="Argument_TypeIsWinRTType" xml:space="preserve">
+ <value>The type must not be a Windows Runtime type.</value>
+ </data>
+ <data name="Argument_TypeMustBeVisibleFromCom" xml:space="preserve">
+ <value>The specified type must be visible from COM.</value>
+ </data>
+ <data name="Argument_TypeMustNotBeComImport" xml:space="preserve">
+ <value>The type must not be imported from COM.</value>
+ </data>
+ <data name="Argument_TypeNameTooLong" xml:space="preserve">
+ <value>Type name was too long. The fully qualified type name must be less than 1,024 characters.</value>
+ </data>
+ <data name="Argument_TypeNotActivatableViaWindowsRuntime" xml:space="preserve">
+ <value>Type '{0}' does not have an activation factory because it is not activatable by Windows Runtime.</value>
+ </data>
+ <data name="Argument_TypeNotComObject" xml:space="preserve">
+ <value>The type must be __ComObject or be derived from __ComObject.</value>
+ </data>
+ <data name="Argument_TypeNotValid" xml:space="preserve">
+ <value>The Type object is not valid.</value>
+ </data>
+ <data name="Argument_UnclosedExceptionBlock" xml:space="preserve">
+ <value>The IL Generator cannot be used while there are unclosed exceptions.</value>
+
+ </data>
+ <data name="Argument_Unexpected_TypeSource" xml:space="preserve">
+ <value>Unexpected TypeKind when marshaling Windows.Foundation.TypeName.</value>
+ </data>
+ <data name="Argument_UnknownUnmanagedCallConv" xml:space="preserve">
+ <value>Unknown unmanaged calling convention for function signature.</value>
+ </data>
+ <data name="Argument_UnmanagedMemAccessorWrapAround" xml:space="preserve">
+ <value>The UnmanagedMemoryAccessor capacity and offset would wrap around the high end of the address space.</value>
+ </data>
+ <data name="Argument_UnmatchedMethodForLocal" xml:space="preserve">
+ <value>Local passed in does not belong to this ILGenerator.</value>
+ </data>
+ <data name="Argument_UnmatchingSymScope" xml:space="preserve">
+ <value>Non-matching symbol scope.</value>
+ </data>
+ <data name="Argument_UnrecognizedLoaderOptimization" xml:space="preserve">
+ <value>Unrecognized LOADER_OPTIMIZATION property value. Supported values may include "SingleDomain", "MultiDomain", "MultiDomainHost", and "NotSpecified".</value>
+ </data>
+ <data name="Argument_UTCOutOfRange" xml:space="preserve">
+ <value>The UTC time represented when the offset is applied must be between year 0 and 10,000.</value>
+ </data>
+ <data name="Argument_VerStringTooLong" xml:space="preserve">
+ <value>The unmanaged Version information is too large to persist.</value>
+ </data>
+ <data name="Argument_WaitHandleNameTooLong" xml:space="preserve">
+ <value>The name can be no more than {0} characters in length.</value>
+ </data>
+ <data name="Argument_WinRTSystemRuntimeType" xml:space="preserve">
+ <value>Cannot marshal type '{0}' to Windows Runtime. Only 'System.RuntimeType' is supported.</value>
+ </data>
+ <data name="ArgumentException_BadMethodImplBody" xml:space="preserve">
+ <value>MethodOverride's body must be from this type.</value>
+ </data>
+ <data name="ArgumentException_BufferNotFromPool" xml:space="preserve">
+ <value>The buffer is not associated with this pool and may not be returned to it.</value>
+ </data>
+ <data name="ArgumentException_OtherNotArrayOfCorrectLength" xml:space="preserve">
+ <value>Object is not a array with the same number of elements as the array to compare it to.</value>
+ </data>
+ <data name="ArgumentException_TupleIncorrectType" xml:space="preserve">
+ <value>Argument must be of type {0}.</value>
+ </data>
+ <data name="ArgumentException_TupleLastArgumentNotATuple" xml:space="preserve">
+ <value>The last element of an eight element tuple must be a Tuple.</value>
+ </data>
+ <data name="ArgumentException_ValueTupleIncorrectType" xml:space="preserve">
+ <value>Argument must be of type {0}.</value>
+ </data>
+ <data name="ArgumentException_ValueTupleLastArgumentNotAValueTuple" xml:space="preserve">
+ <value>The last element of an eight element ValueTuple must be a ValueTuple.</value>
+ </data>
+ <data name="ArgumentNull_Array" xml:space="preserve">
+ <value>Array cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_ArrayElement" xml:space="preserve">
+ <value>At least one element in the specified array was null.</value>
+ </data>
+ <data name="ArgumentNull_ArrayValue" xml:space="preserve">
+ <value>Found a null value within an array.</value>
+ </data>
+ <data name="ArgumentNull_Assembly" xml:space="preserve">
+ <value>Assembly cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_AssemblyName" xml:space="preserve">
+ <value>AssemblyName cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_AssemblyNameName" xml:space="preserve">
+ <value>AssemblyName.Name cannot be null or an empty string.</value>
+ </data>
+ <data name="ArgumentNull_Buffer" xml:space="preserve">
+ <value>Buffer cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_Collection" xml:space="preserve">
+ <value>Collection cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_FileName" xml:space="preserve">
+ <value>File name cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_Generic" xml:space="preserve">
+ <value>Value cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_GUID" xml:space="preserve">
+ <value>GUID cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_Key" xml:space="preserve">
+ <value>Key cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_Obj" xml:space="preserve">
+ <value>Object cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_Path" xml:space="preserve">
+ <value>Path cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_SafeHandle" xml:space="preserve">
+ <value>SafeHandle cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_Stream" xml:space="preserve">
+ <value>Stream cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_String" xml:space="preserve">
+ <value>String reference not set to an instance of a String.</value>
+ </data>
+ <data name="ArgumentNull_Type" xml:space="preserve">
+ <value>Type cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_TypedRefType" xml:space="preserve">
+ <value>Type in TypedReference cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_Waithandles" xml:space="preserve">
+ <value>The waitHandles parameter cannot be null.</value>
+ </data>
+ <data name="ArgumentNull_WithParamName" xml:space="preserve">
+ <value>Parameter '{0}' cannot be null.</value>
+ </data>
+ <data name="ArgumentOutOfRange_ActualValue" xml:space="preserve">
+ <value>Actual value was {0}.</value>
+ </data>
+ <data name="ArgumentOutOfRange_AddressSpace" xml:space="preserve">
+ <value>The number of bytes cannot exceed the virtual address space on a 32 bit machine.</value>
+ </data>
+ <data name="ArgumentOutOfRange_AddValue" xml:space="preserve">
+ <value>Value to add was out of range.</value>
+ </data>
+ <data name="ArgumentOutOfRange_ArrayLB" xml:space="preserve">
+ <value>Number was less than the array's lower bound in the first dimension.</value>
+ </data>
+ <data name="ArgumentOutOfRange_ArrayLBAndLength" xml:space="preserve">
+ <value>Higher indices will exceed Int32.MaxValue because of large lower bound and/or length.</value>
+ </data>
+ <data name="ArgumentOutOfRange_ArrayListInsert" xml:space="preserve">
+ <value>Insertion index was out of range. Must be non-negative and less than or equal to size.</value>
+ </data>
+ <data name="ArgumentOutOfRange_BadHourMinuteSecond" xml:space="preserve">
+ <value>Hour, Minute, and Second parameters describe an un-representable DateTime.</value>
+ </data>
+ <data name="ArgumentOutOfRange_BadYearMonthDay" xml:space="preserve">
+ <value>Year, Month, and Day parameters describe an un-representable DateTime.</value>
+ </data>
+ <data name="ArgumentOutOfRange_BiggerThanCollection" xml:space="preserve">
+ <value>Larger than collection size.</value>
+ </data>
+ <data name="ArgumentOutOfRange_BinaryReaderFillBuffer" xml:space="preserve">
+ <value>The number of bytes requested does not fit into BinaryReader's internal buffer.</value>
+ </data>
+ <data name="ArgumentOutOfRange_Bounds_Lower_Upper" xml:space="preserve">
+ <value>Argument must be between {0} and {1}.</value>
+ </data>
+ <data name="ArgumentOutOfRange_CalendarRange" xml:space="preserve">
+ <value>Specified time is not supported in this calendar. It should be between {0} (Gregorian date) and {1} (Gregorian date), inclusive.</value>
+ </data>
+ <data name="ArgumentOutOfRange_Capacity" xml:space="preserve">
+ <value>Capacity exceeds maximum capacity.</value>
+ </data>
+ <data name="ArgumentOutOfRange_Count" xml:space="preserve">
+ <value>Count must be positive and count must refer to a location within the string/array/collection.</value>
+ </data>
+ <data name="ArgumentOutOfRange_DateArithmetic" xml:space="preserve">
+ <value>The added or subtracted value results in an un-representable DateTime.</value>
+ </data>
+ <data name="ArgumentOutOfRange_DateTimeBadMonths" xml:space="preserve">
+ <value>Months value must be between +/-120000.</value>
+ </data>
+ <data name="ArgumentOutOfRange_DateTimeBadTicks" xml:space="preserve">
+ <value>Ticks must be between DateTime.MinValue.Ticks and DateTime.MaxValue.Ticks.</value>
+ </data>
+ <data name="ArgumentOutOfRange_DateTimeBadYears" xml:space="preserve">
+ <value>Years value must be between +/-10000.</value>
+ </data>
+ <data name="ArgumentOutOfRange_Day" xml:space="preserve">
+ <value>Day must be between 1 and {0} for month {1}.</value>
+ </data>
+ <data name="ArgumentOutOfRange_DayOfWeek" xml:space="preserve">
+ <value>The DayOfWeek enumeration must be in the range 0 through 6.</value>
+ </data>
+ <data name="ArgumentOutOfRange_DayParam" xml:space="preserve">
+ <value>The Day parameter must be in the range 1 through 31.</value>
+ </data>
+ <data name="ArgumentOutOfRange_DecimalRound" xml:space="preserve">
+ <value>Decimal can only round to between 0 and 28 digits of precision.</value>
+ </data>
+ <data name="ArgumentOutOfRange_DecimalScale" xml:space="preserve">
+ <value>Decimal's scale value must be between 0 and 28, inclusive.</value>
+ </data>
+ <data name="ArgumentOutOfRange_EndIndexStartIndex" xml:space="preserve">
+ <value>endIndex cannot be greater than startIndex.</value>
+ </data>
+ <data name="ArgumentOutOfRange_Enum" xml:space="preserve">
+ <value>Enum value was out of legal range.</value>
+ </data>
+ <data name="ArgumentOutOfRange_Era" xml:space="preserve">
+ <value>Time value was out of era range.</value>
+ </data>
+ <data name="ArgumentOutOfRange_FileLengthTooBig" xml:space="preserve">
+ <value>Specified file length was too large for the file system.</value>
+ </data>
+ <data name="ArgumentOutOfRange_FileTimeInvalid" xml:space="preserve">
+ <value>Not a valid Win32 FileTime.</value>
+ </data>
+ <data name="ArgumentOutOfRange_GenericPositive" xml:space="preserve">
+ <value>Value must be positive.</value>
+ </data>
+ <data name="ArgumentOutOfRange_GetByteCountOverflow" xml:space="preserve">
+ <value>Too many characters. The resulting number of bytes is larger than what can be returned as an int.</value>
+ </data>
+ <data name="ArgumentOutOfRange_GetCharCountOverflow" xml:space="preserve">
+ <value>Too many bytes. The resulting number of chars is larger than what can be returned as an int.</value>
+ </data>
+ <data name="ArgumentOutOfRange_HashtableLoadFactor" xml:space="preserve">
+ <value>Load factor needs to be between 0.1 and 1.0.</value>
+ </data>
+ <data name="ArgumentOutOfRange_HugeArrayNotSupported" xml:space="preserve">
+ <value>Arrays larger than 2GB are not supported.</value>
+ </data>
+ <data name="ArgumentOutOfRange_Index" xml:space="preserve">
+ <value>Index was out of range. Must be non-negative and less than the size of the collection.</value>
+ </data>
+ <data name="ArgumentOutOfRange_IndexCount" xml:space="preserve">
+ <value>Index and count must refer to a location within the string.</value>
+ </data>
+ <data name="ArgumentOutOfRange_IndexCountBuffer" xml:space="preserve">
+ <value>Index and count must refer to a location within the buffer.</value>
+ </data>
+ <data name="ArgumentOutOfRange_IndexLargerThanMaxValue" xml:space="preserve">
+ <value>This collection cannot work with indices larger than Int32.MaxValue - 1 (0x7FFFFFFF - 1).</value>
+ </data>
+ <data name="ArgumentOutOfRange_IndexLength" xml:space="preserve">
+ <value>Index and length must refer to a location within the string.</value>
+ </data>
+ <data name="ArgumentOutOfRange_IndexString" xml:space="preserve">
+ <value>Index was out of range. Must be non-negative and less than the length of the string.</value>
+ </data>
+ <data name="ArgumentOutOfRange_InvalidEraValue" xml:space="preserve">
+ <value>Era value was not valid.</value>
+ </data>
+ <data name="ArgumentOutOfRange_InvalidHighSurrogate" xml:space="preserve">
+ <value>A valid high surrogate character is between 0xd800 and 0xdbff, inclusive.</value>
+ </data>
+ <data name="ArgumentOutOfRange_InvalidLowSurrogate" xml:space="preserve">
+ <value>A valid low surrogate character is between 0xdc00 and 0xdfff, inclusive.</value>
+ </data>
+ <data name="ArgumentOutOfRange_InvalidUTF32" xml:space="preserve">
+ <value>A valid UTF32 value is between 0x000000 and 0x10ffff, inclusive, and should not include surrogate codepoint values (0x00d800 ~ 0x00dfff).</value>
+ </data>
+ <data name="ArgumentOutOfRange_Length" xml:space="preserve">
+ <value>The specified length exceeds maximum capacity of SecureString.</value>
+ </data>
+ <data name="ArgumentOutOfRange_LengthGreaterThanCapacity" xml:space="preserve">
+ <value>The length cannot be greater than the capacity.</value>
+ </data>
+ <data name="ArgumentOutOfRange_LengthTooLarge" xml:space="preserve">
+ <value>The specified length exceeds the maximum value of {0}.</value>
+ </data>
+ <data name="ArgumentOutOfRange_LessEqualToIntegerMaxVal" xml:space="preserve">
+ <value>Argument must be less than or equal to 2^31 - 1 milliseconds.</value>
+ </data>
+ <data name="ArgumentOutOfRange_ListInsert" xml:space="preserve">
+ <value>Index must be within the bounds of the List.</value>
+ </data>
+ <data name="ArgumentOutOfRange_Month" xml:space="preserve">
+ <value>Month must be between one and twelve.</value>
+ </data>
+ <data name="ArgumentOutOfRange_MonthParam" xml:space="preserve">
+ <value>The Month parameter must be in the range 1 through 12.</value>
+ </data>
+ <data name="ArgumentOutOfRange_MustBeNonNegInt32" xml:space="preserve">
+ <value>Value must be non-negative and less than or equal to Int32.MaxValue.</value>
+ </data>
+ <data name="ArgumentOutOfRange_MustBeNonNegNum" xml:space="preserve">
+ <value>'{0}' must be non-negative.</value>
+ </data>
+ <data name="ArgumentOutOfRange_MustBePositive" xml:space="preserve">
+ <value>'{0}' must be greater than zero.</value>
+ </data>
+ <data name="ArgumentOutOfRange_NeedNonNegNum" xml:space="preserve">
+ <value>Non-negative number required.</value>
+ </data>
+ <data name="ArgumentOutOfRange_NeedNonNegOrNegative1" xml:space="preserve">
+ <value>Number must be either non-negative and less than or equal to Int32.MaxValue or -1.</value>
+ </data>
+ <data name="ArgumentOutOfRange_NeedPosNum" xml:space="preserve">
+ <value>Positive number required.</value>
+ </data>
+ <data name="ArgumentOutOfRange_NeedValidId" xml:space="preserve">
+ <value>The ID parameter must be in the range {0} through {1}.</value>
+ </data>
+ <data name="ArgumentOutOfRange_NegativeCapacity" xml:space="preserve">
+ <value>Capacity must be positive.</value>
+ </data>
+ <data name="ArgumentOutOfRange_NegativeCount" xml:space="preserve">
+ <value>Count cannot be less than zero.</value>
+ </data>
+ <data name="ArgumentOutOfRange_NegativeLength" xml:space="preserve">
+ <value>Length cannot be less than zero.</value>
+ </data>
+ <data name="ArgumentOutOfRange_OffsetLength" xml:space="preserve">
+ <value>Offset and length must refer to a position in the string.</value>
+ </data>
+ <data name="ArgumentOutOfRange_OffsetOut" xml:space="preserve">
+ <value>Either offset did not refer to a position in the string, or there is an insufficient length of destination character array.</value>
+ </data>
+ <data name="ArgumentOutOfRange_ParamSequence" xml:space="preserve">
+ <value>The specified parameter index is not in range.</value>
+ </data>
+ <data name="ArgumentOutOfRange_PartialWCHAR" xml:space="preserve">
+ <value>Pointer startIndex and length do not refer to a valid string.</value>
+ </data>
+ <data name="ArgumentOutOfRange_PeriodTooLarge" xml:space="preserve">
+ <value>Period must be less than 2^32-2.</value>
+ </data>
+ <data name="ArgumentOutOfRange_PositionLessThanCapacityRequired" xml:space="preserve">
+ <value>The position may not be greater or equal to the capacity of the accessor.</value>
+ </data>
+ <data name="ArgumentOutOfRange_Range" xml:space="preserve">
+ <value>Valid values are between {0} and {1}, inclusive.</value>
+ </data>
+ <data name="ArgumentOutOfRange_RoundingDigits" xml:space="preserve">
+ <value>Rounding digits must be between 0 and 15, inclusive.</value>
+ </data>
+ <data name="ArgumentOutOfRange_SmallCapacity" xml:space="preserve">
+ <value>capacity was less than the current size.</value>
+ </data>
+ <data name="ArgumentOutOfRange_SmallMaxCapacity" xml:space="preserve">
+ <value>MaxCapacity must be one or greater.</value>
+ </data>
+ <data name="ArgumentOutOfRange_StartIndex" xml:space="preserve">
+ <value>StartIndex cannot be less than zero.</value>
+ </data>
+ <data name="ArgumentOutOfRange_StartIndexLargerThanLength" xml:space="preserve">
+ <value>startIndex cannot be larger than length of string.</value>
+ </data>
+ <data name="ArgumentOutOfRange_StartIndexLessThanLength" xml:space="preserve">
+ <value>startIndex must be less than length of string.</value>
+ </data>
+ <data name="ArgumentOutOfRange_StreamLength" xml:space="preserve">
+ <value>Stream length must be non-negative and less than 2^31 - 1 - origin.</value>
+ </data>
+ <data name="ArgumentOutOfRange_TimeoutTooLarge" xml:space="preserve">
+ <value>Time-out interval must be less than 2^32-2.</value>
+ </data>
+ <data name="ArgumentOutOfRange_UIntPtrMax" xml:space="preserve">
+ <value>The length of the buffer must be less than the maximum UIntPtr value for your platform.</value>
+ </data>
+ <data name="ArgumentOutOfRange_UnmanagedMemStreamLength" xml:space="preserve">
+ <value>UnmanagedMemoryStream length must be non-negative and less than 2^63 - 1 - baseAddress.</value>
+ </data>
+ <data name="ArgumentOutOfRange_UnmanagedMemStreamWrapAround" xml:space="preserve">
+ <value>The UnmanagedMemoryStream capacity would wrap around the high end of the address space.</value>
+ </data>
+ <data name="ArgumentOutOfRange_UtcOffset" xml:space="preserve">
+ <value>The TimeSpan parameter must be within plus or minus 14.0 hours.</value>
+ </data>
+ <data name="ArgumentOutOfRange_UtcOffsetAndDaylightDelta" xml:space="preserve">
+ <value>The sum of the BaseUtcOffset and DaylightDelta properties must within plus or minus 14.0 hours.</value>
+ </data>
+ <data name="ArgumentOutOfRange_Version" xml:space="preserve">
+ <value>Version's parameters must be greater than or equal to zero.</value>
+ </data>
+ <data name="ArgumentOutOfRange_Week" xml:space="preserve">
+ <value>The Week parameter must be in the range 1 through 5.</value>
+ </data>
+ <data name="ArgumentOutOfRange_Year" xml:space="preserve">
+ <value>Year must be between 1 and 9999.</value>
+ </data>
+ <data name="Arithmetic_NaN" xml:space="preserve">
+ <value>Function does not accept floating point Not-a-Number values.</value>
+ </data>
+ <data name="ArrayTypeMismatch_CantAssignType" xml:space="preserve">
+ <value>Source array type cannot be assigned to destination array type.</value>
+ </data>
+ <data name="ArrayTypeMismatch_ConstrainedCopy" xml:space="preserve">
+ <value>Array.ConstrainedCopy will only work on array types that are provably compatible, without any form of boxing, unboxing, widening, or casting of each array element. Change the array types (i.e., copy a Derived[] to a Base[]), or use a mitigation strategy in the CER for Array.Copy's less powerful reliability contract, such as cloning the array or throwing away the potentially corrupt destination array.</value>
+ </data>
+ <data name="Arugment_EmitMixedContext1" xml:space="preserve">
+ <value>Type '{0}' was loaded in the ReflectionOnly context but the AssemblyBuilder was not created as AssemblyBuilderAccess.ReflectionOnly.</value>
+ </data>
+ <data name="Arugment_EmitMixedContext2" xml:space="preserve">
+ <value>Type '{0}' was not loaded in the ReflectionOnly context but the AssemblyBuilder was created as AssemblyBuilderAccess.ReflectionOnly.</value>
+ </data>
+ <data name="AssertionFailed" xml:space="preserve">
+ <value>Assertion failed.</value>
+ </data>
+ <data name="AssertionFailed_Cnd" xml:space="preserve">
+ <value>Assertion failed: {0}</value>
+ </data>
+ <data name="AssumptionFailed" xml:space="preserve">
+ <value>Assumption failed.</value>
+ </data>
+ <data name="AssumptionFailed_Cnd" xml:space="preserve">
+ <value>Assumption failed: {0}</value>
+ </data>
+ <data name="AsyncMethodBuilder_InstanceNotInitialized" xml:space="preserve">
+ <value>The builder was not properly initialized.</value>
+ </data>
+ <data name="BadImageFormat_BadILFormat" xml:space="preserve">
+ <value>Bad IL format.</value>
+ </data>
+ <data name="BadImageFormat_InvalidType" xml:space="preserve">
+ <value>Corrupt .resources file. The specified type doesn't exist.</value>
+ </data>
+ <data name="BadImageFormat_NegativeStringLength" xml:space="preserve">
+ <value>Corrupt .resources file. String length must be non-negative.</value>
+ </data>
+ <data name="BadImageFormat_ParameterSignatureMismatch" xml:space="preserve">
+ <value>The parameters and the signature of the method don't match.</value>
+ </data>
+ <data name="BadImageFormat_ResourceDataLengthInvalid" xml:space="preserve">
+ <value>Corrupt .resources file. The specified data length '{0}' is not a valid position in the stream.</value>
+ </data>
+ <data name="BadImageFormat_ResourceNameCorrupted" xml:space="preserve">
+ <value>Corrupt .resources file. A resource name extends past the end of the stream.</value>
+ </data>
+ <data name="BadImageFormat_ResourceNameCorrupted_NameIndex" xml:space="preserve">
+ <value>Corrupt .resources file. The resource name for name index {0} extends past the end of the stream.</value>
+ </data>
+ <data name="BadImageFormat_ResourcesDataInvalidOffset" xml:space="preserve">
+ <value>Corrupt .resources file. Invalid offset '{0}' into data section.</value>
+ </data>
+ <data name="BadImageFormat_ResourcesHeaderCorrupted" xml:space="preserve">
+ <value>Corrupt .resources file. Unable to read resources from this file because of invalid header information. Try regenerating the .resources file.</value>
+ </data>
+ <data name="BadImageFormat_ResourcesIndexTooLong" xml:space="preserve">
+ <value>Corrupt .resources file. String for name index '{0}' extends past the end of the file.</value>
+ </data>
+ <data name="BadImageFormat_ResourcesNameInvalidOffset" xml:space="preserve">
+ <value>Corrupt .resources file. Invalid offset '{0}' into name section.</value>
+ </data>
+ <data name="BadImageFormat_ResourcesNameTooLong" xml:space="preserve">
+ <value>Corrupt .resources file. Resource name extends past the end of the file.</value>
+ </data>
+ <data name="BadImageFormat_TypeMismatch" xml:space="preserve">
+ <value>Corrupt .resources file. The specified type doesn't match the available data in the stream.</value>
+ </data>
+ <data name="CancellationToken_CreateLinkedToken_TokensIsEmpty" xml:space="preserve">
+ <value>No tokens were supplied.</value>
+ </data>
+ <data name="CancellationToken_SourceDisposed" xml:space="preserve">
+ <value>The CancellationTokenSource associated with this CancellationToken has been disposed.</value>
+ </data>
+ <data name="CancellationTokenSource_Disposed" xml:space="preserve">
+ <value>The CancellationTokenSource has been disposed.</value>
+ </data>
+ <data name="ConcurrentCollection_SyncRoot_NotSupported" xml:space="preserve">
+ <value>The SyncRoot property may not be used for the synchronization of concurrent collections.</value>
+ </data>
+ <data name="ConcurrentDictionary_ArrayIncorrectType" xml:space="preserve">
+ <value>The array is multidimensional, or the type parameter for the set cannot be cast automatically to the type of the destination array.</value>
+ </data>
+ <data name="ConcurrentDictionary_ArrayNotLargeEnough" xml:space="preserve">
+ <value>The index is equal to or greater than the length of the array, or the number of elements in the dictionary is greater than the available space from index to the end of the destination array.</value>
+ </data>
+ <data name="ConcurrentDictionary_CapacityMustNotBeNegative" xml:space="preserve">
+ <value>The capacity argument must be greater than or equal to zero.</value>
+ </data>
+ <data name="ConcurrentDictionary_ConcurrencyLevelMustBePositive" xml:space="preserve">
+ <value>The concurrencyLevel argument must be positive.</value>
+ </data>
+ <data name="ConcurrentDictionary_IndexIsNegative" xml:space="preserve">
+ <value>The index argument is less than zero.</value>
+ </data>
+ <data name="ConcurrentDictionary_ItemKeyIsNull" xml:space="preserve">
+ <value>TKey is a reference type and item.Key is null.</value>
+ </data>
+ <data name="ConcurrentDictionary_KeyAlreadyExisted" xml:space="preserve">
+ <value>The key already existed in the dictionary.</value>
+ </data>
+ <data name="ConcurrentDictionary_TypeOfKeyIncorrect" xml:space="preserve">
+ <value>The key was of an incorrect type for this dictionary.</value>
+ </data>
+ <data name="ConcurrentDictionary_TypeOfValueIncorrect" xml:space="preserve">
+ <value>The value was of an incorrect type for this dictionary.</value>
+ </data>
+ <data name="event_Barrier_PhaseFinished" xml:space="preserve">
+ <value>Barrier finishing phase {1}.</value>
+ </data>
+ <data name="event_ConcurrentBag_TryPeekSteals" xml:space="preserve">
+ <value>ConcurrentBag stealing in TryPeek.</value>
+ </data>
+ <data name="event_ConcurrentBag_TryTakeSteals" xml:space="preserve">
+ <value>ConcurrentBag stealing in TryTake.</value>
+ </data>
+ <data name="event_ConcurrentDictionary_AcquiringAllLocks" xml:space="preserve">
+ <value>ConcurrentDictionary acquiring all locks on {0} bucket(s).</value>
+ </data>
+ <data name="event_ConcurrentStack_FastPopFailed" xml:space="preserve">
+ <value>Pop from ConcurrentStack spun {0} time(s).</value>
+ </data>
+ <data name="event_ConcurrentStack_FastPushFailed" xml:space="preserve">
+ <value>Push to ConcurrentStack spun {0} time(s).</value>
+ </data>
+ <data name="event_ParallelFork" xml:space="preserve">
+ <value>Task {1} entering fork/join {2}.</value>
+ </data>
+ <data name="event_ParallelInvokeBegin" xml:space="preserve">
+ <value>Beginning ParallelInvoke {2} from Task {1} for {4} actions.</value>
+ </data>
+ <data name="event_ParallelInvokeEnd" xml:space="preserve">
+ <value>Ending ParallelInvoke {2}.</value>
+ </data>
+ <data name="event_ParallelJoin" xml:space="preserve">
+ <value>Task {1} leaving fork/join {2}.</value>
+ </data>
+ <data name="event_ParallelLoopBegin" xml:space="preserve">
+ <value>Beginning {3} loop {2} from Task {1}.</value>
+ </data>
+ <data name="event_ParallelLoopEnd" xml:space="preserve">
+ <value>Ending loop {2} after {3} iterations.</value>
+ </data>
+ <data name="event_SpinLock_FastPathFailed" xml:space="preserve">
+ <value>SpinLock beginning to spin.</value>
+ </data>
+ <data name="event_SpinWait_NextSpinWillYield" xml:space="preserve">
+ <value>Next spin will yield.</value>
+ </data>
+ <data name="event_TaskCompleted" xml:space="preserve">
+ <value>Task {2} completed.</value>
+ </data>
+ <data name="event_TaskScheduled" xml:space="preserve">
+ <value>Task {2} scheduled to TaskScheduler {0}.</value>
+ </data>
+ <data name="event_TaskStarted" xml:space="preserve">
+ <value>Task {2} executing.</value>
+ </data>
+ <data name="event_TaskWaitBegin" xml:space="preserve">
+ <value>Beginning wait ({3}) on Task {2}.</value>
+ </data>
+ <data name="event_TaskWaitEnd" xml:space="preserve">
+ <value>Ending wait on Task {2}.</value>
+ </data>
+ <data name="EventSource_AbstractMustNotDeclareEventMethods" xml:space="preserve">
+ <value>Abstract event source must not declare event methods ({0} with ID {1}).</value>
+ </data>
+ <data name="EventSource_AbstractMustNotDeclareKTOC" xml:space="preserve">
+ <value>Abstract event source must not declare {0} nested type.</value>
+ </data>
+ <data name="EventSource_AddScalarOutOfRange" xml:space="preserve">
+ <value>Getting out of bounds during scalar addition.</value>
+ </data>
+ <data name="EventSource_ChannelTypeDoesNotMatchEventChannelValue" xml:space="preserve">
+ <value>Channel {0} does not match event channel value {1}.</value>
+ </data>
+ <data name="EventSource_DataDescriptorsOutOfRange" xml:space="preserve">
+ <value>Data descriptors are out of range.</value>
+ </data>
+ <data name="EventSource_DuplicateStringKey" xml:space="preserve">
+ <value>Multiple definitions for string "{0}".</value>
+ </data>
+ <data name="EventSource_EnumKindMismatch" xml:space="preserve">
+ <value>The type of {0} is not expected in {1}.</value>
+ </data>
+ <data name="EventSource_EventChannelOutOfRange" xml:space="preserve">
+ <value>Channel {0} has a value of {1} which is outside the legal range (16-254).</value>
+ </data>
+ <data name="EventSource_EventIdReused" xml:space="preserve">
+ <value>Event {0} has ID {1} which is already in use.</value>
+ </data>
+ <data name="EventSource_EventMustHaveTaskIfNonDefaultOpcode" xml:space="preserve">
+ <value>Event {0} (with ID {1}) has a non-default opcode but not a task.</value>
+ </data>
+ <data name="EventSource_EventMustNotBeExplicitImplementation" xml:space="preserve">
+ <value>Event method {0} (with ID {1}) is an explicit interface method implementation. Re-write method as implicit implementation.</value>
+ </data>
+ <data name="EventSource_EventNameDoesNotEqualTaskPlusOpcode" xml:space="preserve">
+ <value>Event {0} (with ID {1}) has a name that is not the concatenation of its task name and opcode.</value>
+ </data>
+ <data name="EventSource_EventNameReused" xml:space="preserve">
+ <value>Event name {0} used more than once. If you wish to overload a method, the overloaded method should have a NonEvent attribute.</value>
+ </data>
+ <data name="EventSource_EventParametersMismatch" xml:space="preserve">
+ <value>Event {0} was called with {1} argument(s), but it is defined with {2} parameter(s).</value>
+ </data>
+ <data name="EventSource_EventSourceGuidInUse" xml:space="preserve">
+ <value>An instance of EventSource with Guid {0} already exists.</value>
+ </data>
+ <data name="EventSource_EventWithAdminChannelMustHaveMessage" xml:space="preserve">
+ <value>Event {0} specifies an Admin channel {1}. It must specify a Message property.</value>
+ </data>
+ <data name="EventSource_IllegalKeywordsValue" xml:space="preserve">
+ <value>Keyword {0} has a value of {1} which is outside the legal range (0-0x0000080000000000).</value>
+ </data>
+ <data name="EventSource_IllegalOpcodeValue" xml:space="preserve">
+ <value>Opcode {0} has a value of {1} which is outside the legal range (11-238).</value>
+ </data>
+ <data name="EventSource_IllegalTaskValue" xml:space="preserve">
+ <value>Task {0} has a value of {1} which is outside the legal range (1-65535).</value>
+ </data>
+ <data name="EventSource_IncorrentlyAuthoredTypeInfo" xml:space="preserve">
+ <value>Incorrectly-authored TypeInfo - a type should be serialized as one field or as one group</value>
+ </data>
+ <data name="EventSource_InvalidCommand" xml:space="preserve">
+ <value>Invalid command value.</value>
+ </data>
+ <data name="EventSource_InvalidEventFormat" xml:space="preserve">
+ <value>Can't specify both etw event format flags.</value>
+ </data>
+ <data name="EventSource_KeywordCollision" xml:space="preserve">
+ <value>Keywords {0} and {1} are defined with the same value ({2}).</value>
+ </data>
+ <data name="EventSource_KeywordNeedPowerOfTwo" xml:space="preserve">
+ <value>Value {0} for keyword {1} needs to be a power of 2.</value>
+ </data>
+ <data name="EventSource_ListenerCreatedInsideCallback" xml:space="preserve">
+ <value>Creating an EventListener inside a EventListener callback.</value>
+ </data>
+ <data name="EventSource_ListenerNotFound" xml:space="preserve">
+ <value>Listener not found.</value>
+ </data>
+ <data name="EventSource_ListenerWriteFailure" xml:space="preserve">
+ <value>An error occurred when writing to a listener.</value>
+ </data>
+ <data name="EventSource_MaxChannelExceeded" xml:space="preserve">
+ <value>Attempt to define more than the maximum limit of 8 channels for a provider.</value>
+ </data>
+ <data name="EventSource_MismatchIdToWriteEvent" xml:space="preserve">
+ <value>Event {0} is givien event ID {1} but {2} was passed to WriteEvent.</value>
+ </data>
+ <data name="EventSource_NeedGuid" xml:space="preserve">
+ <value>The Guid of an EventSource must be non zero.</value>
+ </data>
+ <data name="EventSource_NeedName" xml:space="preserve">
+ <value>The name of an EventSource must not be null.</value>
+ </data>
+ <data name="EventSource_NeedPositiveId" xml:space="preserve">
+ <value>Event IDs must be positive integers.</value>
+ </data>
+ <data name="EventSource_NoFreeBuffers" xml:space="preserve">
+ <value>No Free Buffers available from the operating system (e.g. event rate too fast).</value>
+ </data>
+ <data name="EventSource_NonCompliantTypeError" xml:space="preserve">
+ <value>The API supports only anonymous types or types decorated with the EventDataAttribute. Non-compliant type: {0} dataType.</value>
+ </data>
+ <data name="EventSource_NoRelatedActivityId" xml:space="preserve">
+ <value>EventSource expects the first parameter of the Event method to be of type Guid and to be named "relatedActivityId" when calling WriteEventWithRelatedActivityId.</value>
+ </data>
+ <data name="EventSource_NotSupportedArrayOfBinary" xml:space="preserve">
+ <value>Arrays of Binary are not supported.</value>
+ </data>
+ <data name="EventSource_NotSupportedArrayOfNil" xml:space="preserve">
+ <value>Arrays of Nil are not supported.</value>
+ </data>
+ <data name="EventSource_NotSupportedArrayOfNullTerminatedString" xml:space="preserve">
+ <value>Arrays of null-terminated string are not supported.</value>
+ </data>
+ <data name="EventSource_NotSupportedCustomSerializedData" xml:space="preserve">
+ <value>Enumerables of custom-serialized data are not supported</value>
+ </data>
+ <data name="EventSource_NotSupportedNestedArraysEnums" xml:space="preserve">
+ <value>Nested arrays/enumerables are not supported.</value>
+ </data>
+ <data name="EventSource_NullInput" xml:space="preserve">
+ <value>Null passed as a event argument.</value>
+ </data>
+ <data name="EventSource_OpcodeCollision" xml:space="preserve">
+ <value>Opcodes {0} and {1} are defined with the same value ({2}).</value>
+ </data>
+ <data name="EventSource_PinArrayOutOfRange" xml:space="preserve">
+ <value>Pins are out of range.</value>
+ </data>
+ <data name="EventSource_RecursiveTypeDefinition" xml:space="preserve">
+ <value>Recursive type definition is not supported.</value>
+ </data>
+ <data name="EventSource_SessionIdError" xml:space="preserve">
+ <value>Bit position in AllKeywords ({0}) must equal the command argument named "EtwSessionKeyword" ({1}).</value>
+ </data>
+ <data name="EventSource_StopsFollowStarts" xml:space="preserve">
+ <value>An event with stop suffix must follow a corresponding event with a start suffix.</value>
+ </data>
+ <data name="EventSource_TaskCollision" xml:space="preserve">
+ <value>Tasks {0} and {1} are defined with the same value ({2}).</value>
+ </data>
+ <data name="EventSource_TaskOpcodePairReused" xml:space="preserve">
+ <value>Event {0} (with ID {1}) has the same task/opcode pair as event {2} (with ID {3}).</value>
+ </data>
+ <data name="EventSource_TooManyArgs" xml:space="preserve">
+ <value>Too many arguments.</value>
+ </data>
+ <data name="EventSource_TooManyFields" xml:space="preserve">
+ <value>Too many fields in structure.</value>
+ </data>
+ <data name="EventSource_ToString" xml:space="preserve">
+ <value>EventSource({0}, {1})</value>
+ </data>
+ <data name="EventSource_TypeMustBeSealedOrAbstract" xml:space="preserve">
+ <value>Event source types must be sealed or abstract.</value>
+ </data>
+ <data name="EventSource_TypeMustDeriveFromEventSource" xml:space="preserve">
+ <value>Event source types must derive from EventSource.</value>
+ </data>
+ <data name="EventSource_UndefinedChannel" xml:space="preserve">
+ <value>Use of undefined channel value {0} for event {1}.</value>
+ </data>
+ <data name="EventSource_UndefinedKeyword" xml:space="preserve">
+ <value>Use of undefined keyword value {0} for event {1}.</value>
+ </data>
+ <data name="EventSource_UndefinedOpcode" xml:space="preserve">
+ <value>Use of undefined opcode value {0} for event {1}.</value>
+ </data>
+ <data name="EventSource_UnsupportedEventTypeInManifest" xml:space="preserve">
+ <value>Unsupported type {0} in event source.</value>
+ </data>
+ <data name="EventSource_UnsupportedMessageProperty" xml:space="preserve">
+ <value>Event {0} specifies an illegal or unsupported formatting message ("{1}").</value>
+ </data>
+ <data name="EventSource_VarArgsParameterMismatch" xml:space="preserve">
+ <value>The parameters to the Event method do not match the parameters to the WriteEvent method. This may cause the event to be displayed incorrectly.</value>
+ </data>
+ <data name="Exception_EndOfInnerExceptionStack" xml:space="preserve">
+ <value>--- End of inner exception stack trace ---</value>
+ </data>
+ <data name="Exception_EndStackTraceFromPreviousThrow" xml:space="preserve">
+ <value>--- End of stack trace from previous location where exception was thrown ---</value>
+ </data>
+ <data name="Exception_WasThrown" xml:space="preserve">
+ <value>Exception of type '{0}' was thrown.</value>
+ </data>
+ <data name="ExecutionContext_ExceptionInAsyncLocalNotification" xml:space="preserve">
+ <value>An exception was not handled in an AsyncLocal&lt;T&gt; notification callback.</value>
+ </data>
+ <data name="FieldAccess_InitOnly" xml:space="preserve">
+ <value>InitOnly (aka ReadOnly) fields can only be initialized in the type/instance constructor.</value>
+ </data>
+ <data name="FileNotFound_ResolveAssembly" xml:space="preserve">
+ <value>Could not resolve assembly '{0}'.</value>
+ </data>
+ <data name="Format_AttributeUsage" xml:space="preserve">
+ <value>Duplicate AttributeUsageAttribute found on attribute type {0}.</value>
+ </data>
+ <data name="Format_Bad7BitInt32" xml:space="preserve">
+ <value>Too many bytes in what should have been a 7 bit encoded Int32.</value>
+ </data>
+ <data name="Format_BadBase" xml:space="preserve">
+ <value>Invalid digits for the specified base.</value>
+ </data>
+ <data name="Format_BadBase64Char" xml:space="preserve">
+ <value>The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.</value>
+ </data>
+ <data name="Format_BadBase64CharArrayLength" xml:space="preserve">
+ <value>Invalid length for a Base-64 char array or string.</value>
+ </data>
+ <data name="Format_BadBoolean" xml:space="preserve">
+ <value>String was not recognized as a valid Boolean.</value>
+ </data>
+ <data name="Format_BadDatePattern" xml:space="preserve">
+ <value>Could not determine the order of year, month, and date from '{0}'.</value>
+ </data>
+ <data name="Format_BadDateTime" xml:space="preserve">
+ <value>String was not recognized as a valid DateTime.</value>
+ </data>
+ <data name="Format_BadDateTimeCalendar" xml:space="preserve">
+ <value>The DateTime represented by the string is not supported in calendar {0}.</value>
+ </data>
+ <data name="Format_BadDayOfWeek" xml:space="preserve">
+ <value>String was not recognized as a valid DateTime because the day of week was incorrect.</value>
+ </data>
+ <data name="Format_BadFormatSpecifier" xml:space="preserve">
+ <value>Format specifier was invalid.</value>
+ </data>
+ <data name="Format_BadQuote" xml:space="preserve">
+ <value>Cannot find a matching quote character for the character '{0}'.</value>
+ </data>
+ <data name="Format_BadTimeSpan" xml:space="preserve">
+ <value>String was not recognized as a valid TimeSpan.</value>
+ </data>
+ <data name="Format_DateOutOfRange" xml:space="preserve">
+ <value>The DateTime represented by the string is out of range.</value>
+ </data>
+ <data name="Format_EmptyInputString" xml:space="preserve">
+ <value>Input string was either empty or contained only whitespace.</value>
+ </data>
+ <data name="Format_ExtraJunkAtEnd" xml:space="preserve">
+ <value>Additional non-parsable characters are at the end of the string.</value>
+ </data>
+ <data name="Format_GuidBrace" xml:space="preserve">
+ <value>Expected {0xdddddddd, etc}.</value>
+ </data>
+ <data name="Format_GuidBraceAfterLastNumber" xml:space="preserve">
+ <value>Could not find a brace, or the length between the previous token and the brace was zero (i.e., '0x,'etc.).</value>
+ </data>
+ <data name="Format_GuidComma" xml:space="preserve">
+ <value>Could not find a comma, or the length between the previous token and the comma was zero (i.e., '0x,'etc.).</value>
+ </data>
+ <data name="Format_GuidDashes" xml:space="preserve">
+ <value>Dashes are in the wrong position for GUID parsing.</value>
+ </data>
+ <data name="Format_GuidEndBrace" xml:space="preserve">
+ <value>Could not find the ending brace.</value>
+ </data>
+ <data name="Format_GuidHexPrefix" xml:space="preserve">
+ <value>Expected hex 0x in '{0}'.</value>
+ </data>
+ <data name="Format_GuidInvalidChar" xml:space="preserve">
+ <value>Guid string should only contain hexadecimal characters.</value>
+ </data>
+ <data name="Format_GuidInvLen" xml:space="preserve">
+ <value>Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).</value>
+ </data>
+ <data name="Format_GuidUnrecognized" xml:space="preserve">
+ <value>Unrecognized Guid format.</value>
+ </data>
+ <data name="Format_IndexOutOfRange" xml:space="preserve">
+ <value>Index (zero based) must be greater than or equal to zero and less than the size of the argument list.</value>
+ </data>
+ <data name="Format_InvalidEnumFormatSpecification" xml:space="preserve">
+ <value>Format String can be only "G", "g", "X", "x", "F", "f", "D" or "d".</value>
+ </data>
+ <data name="Format_InvalidGuidFormatSpecification" xml:space="preserve">
+ <value>Format String can be only "D", "d", "N", "n", "P", "p", "B", "b", "X" or "x".</value>
+ </data>
+ <data name="Format_InvalidString" xml:space="preserve">
+ <value>Input string was not in a correct format.</value>
+ </data>
+ <data name="Format_MissingIncompleteDate" xml:space="preserve">
+ <value>There must be at least a partial date with a year present in the input.</value>
+ </data>
+ <data name="Format_NeedSingleChar" xml:space="preserve">
+ <value>String must be exactly one character long.</value>
+ </data>
+ <data name="Format_NoParsibleDigits" xml:space="preserve">
+ <value>Could not find any recognizable digits.</value>
+ </data>
+ <data name="Format_OffsetOutOfRange" xml:space="preserve">
+ <value>The time zone offset must be within plus or minus 14 hours.</value>
+ </data>
+ <data name="Format_RepeatDateTimePattern" xml:space="preserve">
+ <value>DateTime pattern '{0}' appears more than once with different values.</value>
+ </data>
+ <data name="Format_StringZeroLength" xml:space="preserve">
+ <value>String cannot have zero length.</value>
+ </data>
+ <data name="Format_UnknowDateTimeWord" xml:space="preserve">
+ <value>The string was not recognized as a valid DateTime. There is an unknown word starting at index {0}.</value>
+ </data>
+ <data name="Format_UTCOutOfRange" xml:space="preserve">
+ <value>The UTC representation of the date falls outside the year range 1-9999.</value>
+ </data>
+ <data name="Globalization_cp_1200" xml:space="preserve">
+ <value>Unicode</value>
+ </data>
+ <data name="Globalization_cp_12000" xml:space="preserve">
+ <value>Unicode (UTF-32)</value>
+ </data>
+ <data name="Globalization_cp_12001" xml:space="preserve">
+ <value>Unicode (UTF-32 Big-Endian)</value>
+ </data>
+ <data name="Globalization_cp_1201" xml:space="preserve">
+ <value>Unicode (Big-Endian)</value>
+ </data>
+ <data name="Globalization_cp_20127" xml:space="preserve">
+ <value>US-ASCII</value>
+ </data>
+ <data name="Globalization_cp_28591" xml:space="preserve">
+ <value>Western European (ISO)</value>
+ </data>
+ <data name="Globalization_cp_65000" xml:space="preserve">
+ <value>Unicode (UTF-7)</value>
+ </data>
+ <data name="Globalization_cp_65001" xml:space="preserve">
+ <value>Unicode (UTF-8)</value>
+ </data>
+ <data name="IndexOutOfRange_ArrayRankIndex" xml:space="preserve">
+ <value>Array does not have that many dimensions.</value>
+ </data>
+ <data name="IndexOutOfRange_IORaceCondition" xml:space="preserve">
+ <value>Probable I/O race condition detected while copying memory. The I/O package is not thread safe by default. In multithreaded applications, a stream must be accessed in a thread-safe way, such as a thread-safe wrapper returned by TextReader's or TextWriter's Synchronized methods. This also applies to classes like StreamWriter and StreamReader.</value>
+ </data>
+ <data name="IndexOutOfRange_UMSPosition" xml:space="preserve">
+ <value>Unmanaged memory stream position was beyond the capacity of the stream.</value>
+ </data>
+ <data name="InsufficientMemory_MemFailPoint" xml:space="preserve">
+ <value>Insufficient available memory to meet the expected demands of an operation at this time. Please try again later.</value>
+ </data>
+ <data name="InsufficientMemory_MemFailPoint_TooBig" xml:space="preserve">
+ <value>Insufficient memory to meet the expected demands of an operation, and this system is likely to never satisfy this request. If this is a 32 bit system, consider booting in 3 GB mode.</value>
+ </data>
+ <data name="InsufficientMemory_MemFailPoint_VAFrag" xml:space="preserve">
+ <value>Insufficient available memory to meet the expected demands of an operation at this time, possibly due to virtual address space fragmentation. Please try again later.</value>
+ </data>
+ <data name="Interop_COM_TypeMismatch" xml:space="preserve">
+ <value>Type mismatch between source and destination types.</value>
+ </data>
+ <data name="Interop_Marshal_Unmappable_Char" xml:space="preserve">
+ <value>Cannot marshal: Encountered unmappable character.</value>
+ </data>
+ <data name="InvalidCast_CannotCastNullToValueType" xml:space="preserve">
+ <value>Null object cannot be converted to a value type.</value>
+ </data>
+ <data name="InvalidCast_CannotCoerceByRefVariant" xml:space="preserve">
+ <value>Object cannot be coerced to the original type of the ByRef VARIANT it was obtained from.</value>
+ </data>
+ <data name="InvalidCast_DBNull" xml:space="preserve">
+ <value>Object cannot be cast to DBNull.</value>
+ </data>
+ <data name="InvalidCast_DownCastArrayElement" xml:space="preserve">
+ <value>At least one element in the source array could not be cast down to the destination array type.</value>
+ </data>
+ <data name="InvalidCast_Empty" xml:space="preserve">
+ <value>Object cannot be cast to Empty.</value>
+ </data>
+ <data name="InvalidCast_FromDBNull" xml:space="preserve">
+ <value>Object cannot be cast from DBNull to other types.</value>
+ </data>
+ <data name="InvalidCast_FromTo" xml:space="preserve">
+ <value>Invalid cast from '{0}' to '{1}'.</value>
+ </data>
+ <data name="InvalidCast_IConvertible" xml:space="preserve">
+ <value>Object must implement IConvertible.</value>
+ </data>
+ <data name="InvalidCast_OATypeMismatch" xml:space="preserve">
+ <value>OleAut reported a type mismatch.</value>
+ </data>
+ <data name="InvalidCast_StoreArrayElement" xml:space="preserve">
+ <value>Object cannot be stored in an array of this type.</value>
+ </data>
+ <data name="InvalidCast_WinRTIPropertyValueArrayCoersion" xml:space="preserve">
+ <value>Object in an IPropertyValue is of type '{0}' which cannot be convereted to a '{1}' due to array element '{2}': {3}.</value>
+ </data>
+ <data name="InvalidCast_WinRTIPropertyValueCoersion" xml:space="preserve">
+ <value>Object in an IPropertyValue is of type '{0}' with value '{1}', which cannot be converted to a '{2}'.</value>
+ </data>
+ <data name="InvalidCast_WinRTIPropertyValueElement" xml:space="preserve">
+ <value>Object in an IPropertyValue is of type '{0}', which cannot be converted to a '{1}'.</value>
+ </data>
+ <data name="InvalidOperation_AsyncFlowCtrlCtxMismatch" xml:space="preserve">
+ <value>AsyncFlowControl objects can be used to restore flow only on a Context that had its flow suppressed.</value>
+ </data>
+ <data name="InvalidOperation_AsyncIOInProgress" xml:space="preserve">
+ <value>The stream is currently in use by a previous operation on the stream.</value>
+ </data>
+ <data name="InvalidOperation_BadEmptyMethodBody" xml:space="preserve">
+ <value>Method '{0}' does not have a method body.</value>
+ </data>
+ <data name="InvalidOperation_BadILGeneratorUsage" xml:space="preserve">
+ <value>ILGenerator usage is invalid.</value>
+ </data>
+ <data name="InvalidOperation_BadInstructionOrIndexOutOfBound" xml:space="preserve">
+ <value>MSIL instruction is invalid or index is out of bounds.</value>
+ </data>
+ <data name="InvalidOperation_BadInterfaceNotAbstract" xml:space="preserve">
+ <value>Interface must be declared abstract.</value>
+ </data>
+ <data name="InvalidOperation_BadMethodBody" xml:space="preserve">
+ <value>Method '{0}' cannot have a method body.</value>
+ </data>
+ <data name="InvalidOperation_BadTypeAttributesNotAbstract" xml:space="preserve">
+ <value>Type must be declared abstract if any of its methods are abstract.</value>
+ </data>
+ <data name="InvalidOperation_CalledTwice" xml:space="preserve">
+ <value>The method cannot be called twice on the same instance.</value>
+ </data>
+ <data name="InvalidOperation_CannotImportGlobalFromDifferentModule" xml:space="preserve">
+ <value>Unable to import a global method or field from a different module.</value>
+ </data>
+ <data name="InvalidOperation_CannotRemoveLastFromEmptyCollection" xml:space="preserve">
+ <value>Cannot remove the last element from an empty collection.</value>
+ </data>
+ <data name="InvalidOperation_CannotRestoreUnsupressedFlow" xml:space="preserve">
+ <value>Cannot restore context flow when it is not suppressed.</value>
+ </data>
+ <data name="InvalidOperation_CannotSupressFlowMultipleTimes" xml:space="preserve">
+ <value>Context flow is already suppressed.</value>
+ </data>
+ <data name="InvalidOperation_CannotUseAFCMultiple" xml:space="preserve">
+ <value>AsyncFlowControl object can be used only once to call Undo().</value>
+ </data>
+ <data name="InvalidOperation_CannotUseAFCOtherThread" xml:space="preserve">
+ <value>AsyncFlowControl object must be used on the thread where it was created.</value>
+ </data>
+ <data name="InvalidOperation_CantInstantiateAbstractClass" xml:space="preserve">
+ <value>Instances of abstract classes cannot be created.</value>
+ </data>
+ <data name="InvalidOperation_CantInstantiateFunctionPointer" xml:space="preserve">
+ <value>Instances of function pointers cannot be created.</value>
+ </data>
+ <data name="InvalidOperation_CollectionBackingDictionaryTooLarge" xml:space="preserve">
+ <value>The collection backing this Dictionary contains too many elements.</value>
+ </data>
+ <data name="InvalidOperation_CollectionBackingListTooLarge" xml:space="preserve">
+ <value>The collection backing this List contains too many elements.</value>
+ </data>
+ <data name="InvalidOperation_CollectionCorrupted" xml:space="preserve">
+ <value>A prior operation on this collection was interrupted by an exception. Collection's state is no longer trusted.</value>
+ </data>
+ <data name="InvalidOperation_ConstructorNotAllowedOnInterface" xml:space="preserve">
+ <value>Interface cannot have constructors.</value>
+ </data>
+ <data name="InvalidOperation_CriticalTransparentAreMutuallyExclusive" xml:space="preserve">
+ <value>SecurityTransparent and SecurityCritical attributes cannot be applied to the assembly scope at the same time.</value>
+ </data>
+ <data name="InvalidOperation_DateTimeParsing" xml:space="preserve">
+ <value>Internal Error in DateTime and Calendar operations.</value>
+ </data>
+ <data name="InvalidOperation_DebuggerLaunchFailed" xml:space="preserve">
+ <value>Debugger unable to launch.</value>
+ </data>
+ <data name="InvalidOperation_DefaultConstructorILGen" xml:space="preserve">
+ <value>Unable to access ILGenerator on a constructor created with DefineDefaultConstructor.</value>
+ </data>
+ <data name="InvalidOperation_EndReadCalledMultiple" xml:space="preserve">
+ <value>EndRead can only be called once for each asynchronous operation.</value>
+ </data>
+ <data name="InvalidOperation_EndWriteCalledMultiple" xml:space="preserve">
+ <value>EndWrite can only be called once for each asynchronous operation.</value>
+ </data>
+ <data name="InvalidOperation_EnumEnded" xml:space="preserve">
+ <value>Enumeration already finished.</value>
+ </data>
+ <data name="InvalidOperation_EnumFailedVersion" xml:space="preserve">
+ <value>Collection was modified; enumeration operation may not execute.</value>
+ </data>
+ <data name="InvalidOperation_EnumNotStarted" xml:space="preserve">
+ <value>Enumeration has not started. Call MoveNext.</value>
+ </data>
+ <data name="InvalidOperation_EnumOpCantHappen" xml:space="preserve">
+ <value>Enumeration has either not started or has already finished.</value>
+ </data>
+ <data name="InvalidOperation_EventInfoNotAvailable" xml:space="preserve">
+ <value>This API does not support EventInfo tokens.</value>
+ </data>
+ <data name="InvalidOperation_EventTokenTableRequiresDelegate" xml:space="preserve">
+ <value>Type '{0}' is not a delegate type. EventTokenTable may only be used with delegate types.</value>
+ </data>
+ <data name="InvalidOperation_GenericParametersAlreadySet" xml:space="preserve">
+ <value>The generic parameters are already defined on this MethodBuilder.</value>
+ </data>
+ <data name="InvalidOperation_GetVersion" xml:space="preserve">
+ <value>OSVersion's call to GetVersionEx failed.</value>
+ </data>
+ <data name="InvalidOperation_GlobalsHaveBeenCreated" xml:space="preserve">
+ <value>Type definition of the global function has been completed.</value>
+ </data>
+ <data name="InvalidOperation_HandleIsNotInitialized" xml:space="preserve">
+ <value>Handle is not initialized.</value>
+ </data>
+ <data name="InvalidOperation_HandleIsNotPinned" xml:space="preserve">
+ <value>Handle is not pinned.</value>
+ </data>
+ <data name="InvalidOperation_HashInsertFailed" xml:space="preserve">
+ <value>Hashtable insert failed. Load factor too high. The most common cause is multiple threads writing to the Hashtable simultaneously.</value>
+ </data>
+ <data name="InvalidOperation_IComparerFailed" xml:space="preserve">
+ <value>Failed to compare two elements in the array.</value>
+ </data>
+ <data name="InvalidOperation_MethodBaked" xml:space="preserve">
+ <value>Type definition of the method is complete.</value>
+ </data>
+ <data name="InvalidOperation_MethodBuilderBaked" xml:space="preserve">
+ <value>The signature of the MethodBuilder can no longer be modified because an operation on the MethodBuilder caused the methodDef token to be created. For example, a call to SetCustomAttribute requires the methodDef token to emit the CustomAttribute token.</value>
+ </data>
+ <data name="InvalidOperation_MethodHasBody" xml:space="preserve">
+ <value>Method already has a body.</value>
+ </data>
+ <data name="InvalidOperation_MustCallInitialize" xml:space="preserve">
+ <value>You must call Initialize on this object instance before using it.</value>
+ </data>
+ <data name="InvalidOperation_NativeOverlappedReused" xml:space="preserve">
+ <value>NativeOverlapped cannot be reused for multiple operations.</value>
+ </data>
+ <data name="InvalidOperation_NoMultiModuleAssembly" xml:space="preserve">
+ <value>You cannot have more than one dynamic module in each dynamic assembly in this version of the runtime.</value>
+ </data>
+ <data name="InvalidOperation_NoPublicAddMethod" xml:space="preserve">
+ <value>Cannot add the event handler since no public add method exists for the event.</value>
+ </data>
+ <data name="InvalidOperation_NoPublicRemoveMethod" xml:space="preserve">
+ <value>Cannot remove the event handler since no public remove method exists for the event.</value>
+ </data>
+ <data name="InvalidOperation_NotADebugModule" xml:space="preserve">
+ <value>Not a debug ModuleBuilder.</value>
+ </data>
+ <data name="InvalidOperation_NotAllowedInDynamicMethod" xml:space="preserve">
+ <value>The requested operation is invalid for DynamicMethod.</value>
+ </data>
+ <data name="InvalidOperation_NotAllowedInReflectionOnly" xml:space="preserve">
+ <value>The requested operation is invalid in the ReflectionOnly context.</value>
+ </data>
+ <data name="InvalidOperation_NotAVarArgCallingConvention" xml:space="preserve">
+ <value>Calling convention must be VarArgs.</value>
+ </data>
+ <data name="InvalidOperation_NotGenericType" xml:space="preserve">
+ <value>This operation is only valid on generic types.</value>
+ </data>
+ <data name="InvalidOperation_NotSupportedOnWinRTEvent" xml:space="preserve">
+ <value>Adding or removing event handlers dynamically is not supported on WinRT events.</value>
+ </data>
+ <data name="InvalidOperation_NotWithConcurrentGC" xml:space="preserve">
+ <value>This API is not available when the concurrent GC is enabled.</value>
+ </data>
+ <data name="InvalidOperation_NoUnderlyingTypeOnEnum" xml:space="preserve">
+ <value>Underlying type information on enumeration is not specified.</value>
+ </data>
+ <data name="InvalidOperation_NoValue" xml:space="preserve">
+ <value>Nullable object must have a value.</value>
+ </data>
+ <data name="InvalidOperation_NullArray" xml:space="preserve">
+ <value>The underlying array is null.</value>
+ </data>
+ <data name="InvalidOperation_NullContext" xml:space="preserve">
+ <value>Cannot call Set on a null context</value>
+ </data>
+ <data name="InvalidOperation_NullModuleHandle" xml:space="preserve">
+ <value>The requested operation is invalid when called on a null ModuleHandle.</value>
+ </data>
+ <data name="InvalidOperation_OpenLocalVariableScope" xml:space="preserve">
+ <value>Local variable scope was not properly closed.</value>
+ </data>
+ <data name="InvalidOperation_Overlapped_Pack" xml:space="preserve">
+ <value>Cannot pack a packed Overlapped again.</value>
+ </data>
+ <data name="InvalidOperation_PropertyInfoNotAvailable" xml:space="preserve">
+ <value>This API does not support PropertyInfo tokens.</value>
+ </data>
+ <data name="InvalidOperation_ReadOnly" xml:space="preserve">
+ <value>Instance is read-only.</value>
+ </data>
+ <data name="InvalidOperation_ResMgrBadResSet_Type" xml:space="preserve">
+ <value>'{0}': ResourceSet derived classes must provide a constructor that takes a String file name and a constructor that takes a Stream.</value>
+ </data>
+ <data name="InvalidOperation_ResourceNotStream_Name" xml:space="preserve">
+ <value>Resource '{0}' was not a Stream - call GetObject instead.</value>
+ </data>
+ <data name="InvalidOperation_ResourceNotString_Name" xml:space="preserve">
+ <value>Resource '{0}' was not a String - call GetObject instead.</value>
+ </data>
+ <data name="InvalidOperation_ResourceNotString_Type" xml:space="preserve">
+ <value>Resource was of type '{0}' instead of String - call GetObject instead.</value>
+ </data>
+ <data name="InvalidOperation_SetData_OnlyOnce" xml:space="preserve">
+ <value>SetData can only be used to set the value of a given name once.</value>
+ </data>
+ <data name="InvalidOperation_ShouldNotHaveMethodBody" xml:space="preserve">
+ <value>Method body should not exist.</value>
+ </data>
+ <data name="InvalidOperation_StrongNameKeyPairRequired" xml:space="preserve">
+ <value>A strong name key pair is required to emit a strong-named dynamic assembly.</value>
+ </data>
+ <data name="InvalidOperation_ThreadWrongThreadStart" xml:space="preserve">
+ <value>The thread was created with a ThreadStart delegate that does not accept a parameter.</value>
+ </data>
+ <data name="InvalidOperation_TimeoutsNotSupported" xml:space="preserve">
+ <value>Timeouts are not supported on this stream.</value>
+ </data>
+ <data name="InvalidOperation_TypeCannotBeBoxed" xml:space="preserve">
+ <value>The given type cannot be boxed.</value>
+ </data>
+ <data name="InvalidOperation_TypeHasBeenCreated" xml:space="preserve">
+ <value>Unable to change after type has been created.</value>
+ </data>
+ <data name="InvalidOperation_TypeNotCreated" xml:space="preserve">
+ <value>Type has not been created.</value>
+ </data>
+ <data name="InvalidOperation_UnknownEnumType" xml:space="preserve">
+ <value>Unknown enum type.</value>
+ </data>
+ <data name="InvalidOperation_WriteOnce" xml:space="preserve">
+ <value>This property has already been set and cannot be modified.</value>
+ </data>
+ <data name="InvalidOperation_WrongAsyncResultOrEndCalledMultiple" xml:space="preserve">
+ <value>Either the IAsyncResult object did not come from the corresponding async method on this type, or the End method was called multiple times with the same IAsyncResult.</value>
+ </data>
+ <data name="InvalidOperation_WrongAsyncResultOrEndReadCalledMultiple" xml:space="preserve">
+ <value>Either the IAsyncResult object did not come from the corresponding async method on this type, or EndRead was called multiple times with the same IAsyncResult.</value>
+ </data>
+ <data name="InvalidOperation_WrongAsyncResultOrEndWriteCalledMultiple" xml:space="preserve">
+ <value>Either the IAsyncResult object did not come from the corresponding async method on this type, or EndWrite was called multiple times with the same IAsyncResult.</value>
+ </data>
+ <data name="InvalidProgram_Default" xml:space="preserve">
+ <value>Common Language Runtime detected an invalid program.</value>
+ </data>
+ <data name="InvalidTimeZone_InvalidFileData" xml:space="preserve">
+ <value>The time zone ID '{0}' was found on the local computer, but the file at '{1}' was corrupt.</value>
+ </data>
+ <data name="InvalidTimeZone_InvalidRegistryData" xml:space="preserve">
+ <value>The time zone ID '{0}' was found on the local computer, but the registry information was corrupt.</value>
+ </data>
+ <data name="InvalidTimeZone_JulianDayNotSupported" xml:space="preserve">
+ <value>Julian dates in POSIX strings are unsupported.</value>
+ </data>
+ <data name="InvalidTimeZone_NoTTInfoStructures" xml:space="preserve">
+ <value>There are no ttinfo structures in the tzfile. At least one ttinfo structure is required in order to construct a TimeZoneInfo object.</value>
+ </data>
+ <data name="InvalidTimeZone_UnparseablePosixMDateString" xml:space="preserve">
+ <value>'{0}' is not a valid POSIX-TZ-environment-variable MDate rule. A valid rule has the format 'Mm.w.d'.</value>
+ </data>
+ <data name="InvariantFailed" xml:space="preserve">
+ <value>Invariant failed.</value>
+ </data>
+ <data name="InvariantFailed_Cnd" xml:space="preserve">
+ <value>Invariant failed: {0}</value>
+ </data>
+ <data name="IO_DriveNotFound_Drive" xml:space="preserve">
+ <value>Could not find the drive '{0}'. The drive might not be ready or might not be mapped.</value>
+ </data>
+ <data name="IO_EOF_ReadBeyondEOF" xml:space="preserve">
+ <value>Unable to read beyond the end of the stream.</value>
+ </data>
+ <data name="IO_FileLoad" xml:space="preserve">
+ <value>Could not load the specified file.</value>
+ </data>
+ <data name="IO_FileName_Name" xml:space="preserve">
+ <value>File name: '{0}'</value>
+ </data>
+ <data name="IO_FileNotFound" xml:space="preserve">
+ <value>Unable to find the specified file.</value>
+ </data>
+ <data name="IO_FileNotFound_FileName" xml:space="preserve">
+ <value>Could not find file '{0}'.</value>
+ </data>
+ <data name="IO_AlreadyExists_Name" xml:space="preserve">
+ <value>Cannot create "{0}" because a file or directory with the same name already exists.</value>
+ </data>
+ <data name="IO_BindHandleFailed" xml:space="preserve">
+ <value>BindHandle for ThreadPool failed on this handle.</value>
+ </data>
+ <data name="IO_FileExists_Name" xml:space="preserve">
+ <value>The file '{0}' already exists.</value>
+ </data>
+ <data name="IO_FileStreamHandlePosition" xml:space="preserve">
+ <value>The OS handle's position is not what FileStream expected. Do not use a handle simultaneously in one FileStream and in Win32 code or another FileStream. This may cause data loss.</value>
+ </data>
+ <data name="IO_FileTooLong2GB" xml:space="preserve">
+ <value>The file is too long. This operation is currently limited to supporting files less than 2 gigabytes in size.</value>
+ </data>
+ <data name="IO_FileTooLongOrHandleNotSync" xml:space="preserve">
+ <value>IO operation will not work. Most likely the file will become too long or the handle was not opened to support synchronous IO operations.</value>
+ </data>
+ <data name="IO_FixedCapacity" xml:space="preserve">
+ <value>Unable to expand length of this stream beyond its capacity.</value>
+ </data>
+ <data name="IO_InvalidStringLen_Len" xml:space="preserve">
+ <value>BinaryReader encountered an invalid string length of {0} characters.</value>
+ </data>
+ <data name="IO_NoPermissionToDirectoryName" xml:space="preserve">
+ <value>&lt;Path discovery permission to the specified directory was denied.&gt;</value>
+ </data>
+ <data name="IO_SeekAppendOverwrite" xml:space="preserve">
+ <value>Unable seek backward to overwrite data that previously existed in a file opened in Append mode.</value>
+ </data>
+ <data name="IO_SeekBeforeBegin" xml:space="preserve">
+ <value>An attempt was made to move the position before the beginning of the stream.</value>
+ </data>
+ <data name="IO_SetLengthAppendTruncate" xml:space="preserve">
+ <value>Unable to truncate data that previously existed in a file opened in Append mode.</value>
+ </data>
+ <data name="IO_SharingViolation_File" xml:space="preserve">
+ <value>The process cannot access the file '{0}' because it is being used by another process.</value>
+ </data>
+ <data name="IO_SharingViolation_NoFileName" xml:space="preserve">
+ <value>The process cannot access the file because it is being used by another process.</value>
+ </data>
+ <data name="IO_StreamTooLong" xml:space="preserve">
+ <value>Stream was too long.</value>
+ </data>
+ <data name="IO_PathNotFound_NoPathName" xml:space="preserve">
+ <value>Could not find a part of the path.</value>
+ </data>
+ <data name="IO_PathNotFound_Path" xml:space="preserve">
+ <value>Could not find a part of the path '{0}'.</value>
+ </data>
+ <data name="IO_PathTooLong" xml:space="preserve">
+ <value>The specified file name or path is too long, or a component of the specified path is too long.</value>
+ </data>
+ <data name="IO_UnknownFileName" xml:space="preserve">
+ <value>[Unknown]</value>
+ </data>
+ <data name="Lazy_CreateValue_NoParameterlessCtorForT" xml:space="preserve">
+ <value>The lazily-initialized type does not have a public, parameterless constructor.</value>
+ </data>
+ <data name="Lazy_ctor_ModeInvalid" xml:space="preserve">
+ <value>The mode argument specifies an invalid value.</value>
+ </data>
+ <data name="Lazy_StaticInit_InvalidOperation" xml:space="preserve">
+ <value>ValueFactory returned null.</value>
+ </data>
+ <data name="Lazy_ToString_ValueNotCreated" xml:space="preserve">
+ <value>Value is not created.</value>
+ </data>
+ <data name="Lazy_Value_RecursiveCallsToValue" xml:space="preserve">
+ <value>ValueFactory attempted to access the Value property of this instance.</value>
+ </data>
+ <data name="Loader_ContextPolicies" xml:space="preserve">
+ <value>Context Policies:</value>
+ </data>
+ <data name="Loader_Name" xml:space="preserve">
+ <value>Name:</value>
+ </data>
+ <data name="Loader_NoContextPolicies" xml:space="preserve">
+ <value>There are no context policies.</value>
+ </data>
+ <data name="ManualResetEventSlim_ctor_SpinCountOutOfRange" xml:space="preserve">
+ <value>The spinCount argument must be in the range 0 to {0}, inclusive.</value>
+ </data>
+ <data name="ManualResetEventSlim_ctor_TooManyWaiters" xml:space="preserve">
+ <value>There are too many threads currently waiting on the event. A maximum of {0} waiting threads are supported.</value>
+ </data>
+ <data name="ManualResetEventSlim_Disposed" xml:space="preserve">
+ <value>The event has been disposed.</value>
+ </data>
+ <data name="Marshaler_StringTooLong" xml:space="preserve">
+ <value>Marshaler restriction: Excessively long string.</value>
+ </data>
+ <data name="MissingConstructor_Name" xml:space="preserve">
+ <value>Constructor on type '{0}' not found.</value>
+ </data>
+ <data name="MissingField" xml:space="preserve">
+ <value>Field not found.</value>
+ </data>
+ <data name="MissingField_Name" xml:space="preserve">
+ <value>Field '{0}' not found.</value>
+ </data>
+ <data name="MissingManifestResource_LooselyLinked" xml:space="preserve">
+ <value>Could not find a manifest resource entry called "{0}" in assembly "{1}". Please check spelling, capitalization, and build rules to ensure "{0}" is being linked into the assembly.</value>
+ </data>
+ <data name="MissingManifestResource_MultipleBlobs" xml:space="preserve">
+ <value>A case-insensitive lookup for resource file "{0}" in assembly "{1}" found multiple entries. Remove the duplicates or specify the exact case.</value>
+ </data>
+ <data name="MissingManifestResource_NoNeutralAsm" xml:space="preserve">
+ <value>Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "{0}" was correctly embedded or linked into assembly "{1}" at compile time, or that all the satellite assemblies required are loadable and fully signed.</value>
+ </data>
+ <data name="MissingManifestResource_NoNeutralDisk" xml:space="preserve">
+ <value>Could not find any resources appropriate for the specified culture (or the neutral culture) on disk.</value>
+ </data>
+ <data name="MissingManifestResource_NoPRIresources" xml:space="preserve">
+ <value>Unable to open Package Resource Index.</value>
+ </data>
+ <data name="MissingManifestResource_ResWFileNotLoaded" xml:space="preserve">
+ <value>Unable to load resources for resource file "{0}" in package "{1}".</value>
+ </data>
+ <data name="MissingMember" xml:space="preserve">
+ <value>Member not found.</value>
+ </data>
+ <data name="MissingMember_Name" xml:space="preserve">
+ <value>Member '{0}' not found.</value>
+ </data>
+ <data name="MissingMemberNestErr" xml:space="preserve">
+ <value>TypedReference can only be made on nested value Types.</value>
+ </data>
+ <data name="MissingMemberTypeRef" xml:space="preserve">
+ <value>FieldInfo does not match the target Type.</value>
+ </data>
+ <data name="MissingMethod_Name" xml:space="preserve">
+ <value>Method '{0}' not found.</value>
+ </data>
+ <data name="MissingSatelliteAssembly_Culture_Name" xml:space="preserve">
+ <value>The satellite assembly named "{1}" for fallback culture "{0}" either could not be found or could not be loaded. This is generally a setup problem. Please consider reinstalling or repairing the application.</value>
+ </data>
+ <data name="MissingSatelliteAssembly_Default" xml:space="preserve">
+ <value>Resource lookup fell back to the ultimate fallback resources in a satellite assembly, but that satellite either was not found or could not be loaded. Please consider reinstalling or repairing the application.</value>
+ </data>
+ <data name="Multicast_Combine" xml:space="preserve">
+ <value>Delegates that are not of type MulticastDelegate may not be combined.</value>
+ </data>
+ <data name="MustUseCCRewrite" xml:space="preserve">
+ <value>An assembly (probably "{1}") must be rewritten using the code contracts binary rewriter (CCRewrite) because it is calling Contract.{0} and the CONTRACTS_FULL symbol is defined. Remove any explicit definitions of the CONTRACTS_FULL symbol from your project and rebuild. CCRewrite can be downloaded from http://go.microsoft.com/fwlink/?LinkID=169180. \r\nAfter the rewriter is installed, it can be enabled in Visual Studio from the project's Properties page on the Code Contracts pane. Ensure that "Perform Runtime Contract Checking" is enabled, which will define CONTRACTS_FULL.</value>
+ </data>
+ <data name="NotImplemented_ResourcesLongerThanInt64Max" xml:space="preserve">
+ <value>Resource files longer than 2^63 bytes are not currently implemented.</value>
+ </data>
+ <data name="NotSupported_AbstractNonCLS" xml:space="preserve">
+ <value>This non-CLS method is not implemented.</value>
+ </data>
+ <data name="NotSupported_ActivAttr" xml:space="preserve">
+ <value>Activation Attributes are not supported.</value>
+ </data>
+ <data name="NotSupported_AppX" xml:space="preserve">
+ <value>{0} is not supported in AppX.</value>
+ </data>
+ <data name="NotSupported_AssemblyLoadCodeBase" xml:space="preserve">
+ <value>Assembly.Load with a Codebase is not supported.</value>
+ </data>
+ <data name="NotSupported_AssemblyLoadFromHash" xml:space="preserve">
+ <value>Assembly.LoadFrom with hashValue is not supported.</value>
+ </data>
+ <data name="NotSupported_ByRefLike" xml:space="preserve">
+ <value>Cannot create boxed ByRef-like values.</value>
+ </data>
+ <data name="NotSupported_ByRefLikeArray" xml:space="preserve">
+ <value>Cannot create arrays of ByRef-like values.</value>
+ </data>
+ <data name="NotSupported_ByRefReturn" xml:space="preserve">
+ <value>ByRef return value not supported in reflection invocation.</value>
+ </data>
+ <data name="NotSupported_CallToVarArg" xml:space="preserve">
+ <value>Vararg calling convention not supported.</value>
+ </data>
+ <data name="NotSupported_CannotCallEqualsOnSpan" xml:space="preserve">
+ <value>Equals() on Span and ReadOnlySpan is not supported. Use operator== instead.</value>
+ </data>
+ <data name="NotSupported_CannotCallGetHashCodeOnSpan" xml:space="preserve">
+ <value>GetHashCode() on Span and ReadOnlySpan is not supported.</value>
+ </data>
+ <data name="NotSupported_ChangeType" xml:space="preserve">
+ <value>ChangeType operation is not supported.</value>
+ </data>
+ <data name="NotSupported_CollectibleAssemblyResolve" xml:space="preserve">
+ <value>Resolving to a collectible assembly is not supported.</value>
+ </data>
+ <data name="NotSupported_CollectibleBoundNonCollectible" xml:space="preserve">
+ <value>A non-collectible assembly may not reference a collectible assembly.</value>
+ </data>
+ <data name="NotSupported_CollectibleCOM" xml:space="preserve">
+ <value>COM Interop is not supported for collectible types.</value>
+ </data>
+ <data name="NotSupported_CollectibleDelegateMarshal" xml:space="preserve">
+ <value>Delegate marshaling for types within collectible assemblies is not supported.</value>
+ </data>
+ <data name="NotSupported_Constructor" xml:space="preserve">
+ <value>Object cannot be created through this constructor.</value>
+ </data>
+ <data name="NotSupported_CreateInstanceWithTypeBuilder" xml:space="preserve">
+ <value>CreateInstance cannot be used with an object of type TypeBuilder.</value>
+ </data>
+ <data name="NotSupported_DBNullSerial" xml:space="preserve">
+ <value>Only one DBNull instance may exist, and calls to DBNull deserialization methods are not allowed.</value>
+ </data>
+ <data name="NotSupported_DelegateMarshalToWrongDomain" xml:space="preserve">
+ <value>Delegates cannot be marshaled from native code into a domain other than their home domain.</value>
+ </data>
+ <data name="NotSupported_DelegateSerHolderSerial" xml:space="preserve">
+ <value>DelegateSerializationHolder objects are designed to represent a delegate during serialization and are not serializable themselves.</value>
+ </data>
+ <data name="NotSupported_DynamicAssembly" xml:space="preserve">
+ <value>The invoked member is not supported in a dynamic assembly.</value>
+ </data>
+ <data name="NotSupported_DynamicAssemblyNoRunAccess" xml:space="preserve">
+ <value>Cannot execute code on a dynamic assembly without run access.</value>
+ </data>
+ <data name="NotSupported_DynamicMethodFlags" xml:space="preserve">
+ <value>Wrong MethodAttributes or CallingConventions for DynamicMethod. Only public, static, standard supported</value>
+ </data>
+ <data name="NotSupported_DynamicModule" xml:space="preserve">
+ <value>The invoked member is not supported in a dynamic module.</value>
+ </data>
+ <data name="NotSupported_FileStreamOnNonFiles" xml:space="preserve">
+ <value>FileStream was asked to open a device that was not a file. For support for devices like 'com1:' or 'lpt1:', call CreateFile, then use the FileStream constructors that take an OS handle as an IntPtr.</value>
+ </data>
+ <data name="NotSupported_FixedSizeCollection" xml:space="preserve">
+ <value>Collection was of a fixed size.</value>
+ </data>
+ <data name="NotSupported_GenericMethod" xml:space="preserve">
+ <value>Generic methods with NativeCallableAttribute are not supported.</value>
+ </data>
+ <data name="NotSupported_GlobalMethodSerialization" xml:space="preserve">
+ <value>Serialization of global methods (including implicit serialization via the use of asynchronous delegates) is not supported.</value>
+ </data>
+ <data name="NotSupported_IDispInvokeDefaultMemberWithNamedArgs" xml:space="preserve">
+ <value>Invoking default method with named arguments is not supported.</value>
+ </data>
+ <data name="NotSupported_IllegalOneByteBranch" xml:space="preserve">
+ <value>Illegal one-byte branch at position: {0}. Requested branch was: {1}.</value>
+ </data>
+ <data name="NotSupported_KeyCollectionSet" xml:space="preserve">
+ <value>Mutating a key collection derived from a dictionary is not allowed.</value>
+ </data>
+ <data name="NotSupported_ManagedActivation" xml:space="preserve">
+ <value>Cannot create uninitialized instances of types requiring managed activation.</value>
+ </data>
+ <data name="NotSupported_MaxWaitHandles" xml:space="preserve">
+ <value>The number of WaitHandles must be less than or equal to 64.</value>
+ </data>
+ <data name="NotSupported_MemStreamNotExpandable" xml:space="preserve">
+ <value>Memory stream is not expandable.</value>
+ </data>
+ <data name="NotSupported_MustBeModuleBuilder" xml:space="preserve">
+ <value>Module argument must be a ModuleBuilder.</value>
+ </data>
+ <data name="NotSupported_NativeCallableTarget" xml:space="preserve">
+ <value>Methods with NativeCallableAttribute cannot be used as delegate target.</value>
+ </data>
+ <data name="NotSupported_NoCodepageData" xml:space="preserve">
+ <value>No data is available for encoding {0}. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.</value>
+ </data>
+ <data name="NotSupported_NonBlittableTypes" xml:space="preserve">
+ <value>Non-blittable parameter types are not supported for NativeCallable methods.</value>
+ </data>
+ <data name="NotSupported_NonReflectedType" xml:space="preserve">
+ <value>Not supported in a non-reflected type.</value>
+ </data>
+ <data name="NotSupported_NonStaticMethod" xml:space="preserve">
+ <value>Non-static methods with NativeCallableAttribute are not supported.</value>
+ </data>
+ <data name="NotSupported_NoParentDefaultConstructor" xml:space="preserve">
+ <value>Parent does not have a default constructor. The default constructor must be explicitly defined.</value>
+ </data>
+ <data name="NotSupported_NoTypeInfo" xml:space="preserve">
+ <value>Cannot resolve {0} to a TypeInfo object.</value>
+ </data>
+ <data name="NotSupported_NYI" xml:space="preserve">
+ <value>This feature is not currently implemented.</value>
+ </data>
+ <data name="NotSupported_ObsoleteResourcesFile" xml:space="preserve">
+ <value>Found an obsolete .resources file in assembly '{0}'. Rebuild that .resources file then rebuild that assembly.</value>
+ </data>
+ <data name="NotSupported_OleAutBadVarType" xml:space="preserve">
+ <value>The given Variant type is not supported by this OleAut function.</value>
+ </data>
+ <data name="NotSupported_OpenType" xml:space="preserve">
+ <value>Cannot create arrays of open type.</value>
+ </data>
+ <data name="NotSupported_OutputStreamUsingTypeBuilder" xml:space="preserve">
+ <value>Output streams do not support TypeBuilders.</value>
+ </data>
+ <data name="NotSupported_PIAInAppxProcess" xml:space="preserve">
+ <value>A Primary Interop Assembly is not supported in AppX.</value>
+ </data>
+ <data name="NotSupported_Reading" xml:space="preserve">
+ <value>Accessor does not support reading.</value>
+ </data>
+ <data name="NotSupported_ReadOnlyCollection" xml:space="preserve">
+ <value>Collection is read-only.</value>
+ </data>
+ <data name="NotSupported_ResourceObjectSerialization" xml:space="preserve">
+ <value>Cannot read resources that depend on serialization.</value>
+ </data>
+ <data name="NotSupported_SignalAndWaitSTAThread" xml:space="preserve">
+ <value>SignalAndWait on a STA thread is not supported.</value>
+ </data>
+ <data name="NotSupported_StringComparison" xml:space="preserve">
+ <value>The string comparison type passed in is currently not supported.</value>
+ </data>
+ <data name="NotSupported_SubclassOverride" xml:space="preserve">
+ <value>Derived classes must provide an implementation.</value>
+ </data>
+ <data name="NotSupported_SymbolMethod" xml:space="preserve">
+ <value>Not supported in an array method of a type definition that is not complete.</value>
+ </data>
+ <data name="NotSupported_TooManyArgs" xml:space="preserve">
+ <value>Stack size too deep. Possibly too many arguments.</value>
+ </data>
+ <data name="NotSupported_Type" xml:space="preserve">
+ <value>Type is not supported.</value>
+ </data>
+ <data name="NotSupported_TypeCannotDeserialized" xml:space="preserve">
+ <value>Direct deserialization of type '{0}' is not supported.</value>
+ </data>
+ <data name="NotSupported_TypeNotYetCreated" xml:space="preserve">
+ <value>The invoked member is not supported before the type is created.</value>
+ </data>
+ <data name="NotSupported_UmsSafeBuffer" xml:space="preserve">
+ <value>This operation is not supported for an UnmanagedMemoryStream created from a SafeBuffer.</value>
+ </data>
+ <data name="NotSupported_UnitySerHolder" xml:space="preserve">
+ <value>The UnitySerializationHolder object is designed to transmit information about other types and is not serializable itself.</value>
+ </data>
+ <data name="NotSupported_UnknownTypeCode" xml:space="preserve">
+ <value>TypeCode '{0}' was not valid.</value>
+ </data>
+ <data name="NotSupported_UnreadableStream" xml:space="preserve">
+ <value>Stream does not support reading.</value>
+ </data>
+ <data name="NotSupported_UnseekableStream" xml:space="preserve">
+ <value>Stream does not support seeking.</value>
+ </data>
+ <data name="NotSupported_UnwritableStream" xml:space="preserve">
+ <value>Stream does not support writing.</value>
+ </data>
+ <data name="NotSupported_ValueClassCM" xml:space="preserve">
+ <value>Custom marshalers for value types are not currently supported.</value>
+ </data>
+ <data name="NotSupported_ValueCollectionSet" xml:space="preserve">
+ <value>Mutating a value collection derived from a dictionary is not allowed.</value>
+ </data>
+ <data name="NotSupported_VoidArray" xml:space="preserve">
+ <value>Arrays of System.Void are not supported.</value>
+ </data>
+ <data name="NotSupported_WinRT_PartialTrust" xml:space="preserve">
+ <value>Windows Runtime is not supported in partial trust.</value>
+ </data>
+ <data name="NotSupported_Writing" xml:space="preserve">
+ <value>Accessor does not support writing.</value>
+ </data>
+ <data name="NotSupported_WrongResourceReader_Type" xml:space="preserve">
+ <value>This .resources file should not be read with this reader. The resource reader type is "{0}".</value>
+ </data>
+ <data name="NullReference_This" xml:space="preserve">
+ <value>The pointer for this method was null.</value>
+ </data>
+ <data name="ObjectDisposed_FileClosed" xml:space="preserve">
+ <value>Cannot access a closed file.</value>
+ </data>
+ <data name="ObjectDisposed_Generic" xml:space="preserve">
+ <value>Cannot access a disposed object.</value>
+ </data>
+ <data name="ObjectDisposed_ObjectName_Name" xml:space="preserve">
+ <value>Object name: '{0}'.</value>
+ </data>
+ <data name="ObjectDisposed_ReaderClosed" xml:space="preserve">
+ <value>Cannot read from a closed TextReader.</value>
+ </data>
+ <data name="ObjectDisposed_RegKeyClosed" xml:space="preserve">
+ <value>Cannot access a closed registry key.</value>
+ </data>
+ <data name="ObjectDisposed_ResourceSet" xml:space="preserve">
+ <value>Cannot access a closed resource set.</value>
+ </data>
+ <data name="ObjectDisposed_StreamClosed" xml:space="preserve">
+ <value>Cannot access a closed Stream.</value>
+ </data>
+ <data name="ObjectDisposed_ViewAccessorClosed" xml:space="preserve">
+ <value>Cannot access a closed accessor.</value>
+ </data>
+ <data name="OperationCanceled" xml:space="preserve">
+ <value>The operation was canceled.</value>
+ </data>
+ <data name="OutOfMemory_GCHandleMDA" xml:space="preserve">
+ <value>The GCHandle MDA has run out of available cookies.</value>
+ </data>
+ <data name="Overflow_Byte" xml:space="preserve">
+ <value>Value was either too large or too small for an unsigned byte.</value>
+ </data>
+ <data name="Overflow_Char" xml:space="preserve">
+ <value>Value was either too large or too small for a character.</value>
+ </data>
+ <data name="Overflow_Currency" xml:space="preserve">
+ <value>Value was either too large or too small for a Currency.</value>
+ </data>
+ <data name="Overflow_Decimal" xml:space="preserve">
+ <value>Value was either too large or too small for a Decimal.</value>
+ </data>
+ <data name="Overflow_Double" xml:space="preserve">
+ <value>Value was either too large or too small for a Double.</value>
+ </data>
+ <data name="Overflow_Duration" xml:space="preserve">
+ <value>The duration cannot be returned for TimeSpan.MinValue because the absolute value of TimeSpan.MinValue exceeds the value of TimeSpan.MaxValue.</value>
+ </data>
+ <data name="Overflow_Int16" xml:space="preserve">
+ <value>Value was either too large or too small for an Int16.</value>
+ </data>
+ <data name="Overflow_Int32" xml:space="preserve">
+ <value>Value was either too large or too small for an Int32.</value>
+ </data>
+ <data name="Overflow_Int64" xml:space="preserve">
+ <value>Value was either too large or too small for an Int64.</value>
+ </data>
+ <data name="Overflow_NegateTwosCompNum" xml:space="preserve">
+ <value>Negating the minimum value of a twos complement number is invalid.</value>
+ </data>
+ <data name="Overflow_NegativeUnsigned" xml:space="preserve">
+ <value>The string was being parsed as an unsigned number and could not have a negative sign.</value>
+ </data>
+ <data name="Overflow_SByte" xml:space="preserve">
+ <value>Value was either too large or too small for a signed byte.</value>
+ </data>
+ <data name="Overflow_Single" xml:space="preserve">
+ <value>Value was either too large or too small for a Single.</value>
+ </data>
+ <data name="Overflow_TimeSpanElementTooLarge" xml:space="preserve">
+ <value>The TimeSpan could not be parsed because at least one of the numeric components is out of range or contains too many digits.</value>
+ </data>
+ <data name="Overflow_TimeSpanTooLong" xml:space="preserve">
+ <value>TimeSpan overflowed because the duration is too long.</value>
+ </data>
+ <data name="Overflow_UInt16" xml:space="preserve">
+ <value>Value was either too large or too small for a UInt16.</value>
+ </data>
+ <data name="Overflow_UInt32" xml:space="preserve">
+ <value>Value was either too large or too small for a UInt32.</value>
+ </data>
+ <data name="Overflow_UInt64" xml:space="preserve">
+ <value>Value was either too large or too small for a UInt64.</value>
+ </data>
+ <data name="PlatformNotSupported_ArgIterator" xml:space="preserve">
+ <value>ArgIterator is not supported on this platform.</value>
+ </data>
+ <data name="PlatformNotSupported_ComInterop" xml:space="preserve">
+ <value>COM Interop is not supported on this platform.</value>
+ </data>
+ <data name="PlatformNotSupported_NamedSynchronizationPrimitives" xml:space="preserve">
+ <value>The named version of this synchronization primitive is not supported on this platform.</value>
+ </data>
+ <data name="PlatformNotSupported_NamedSyncObjectWaitAnyWaitAll" xml:space="preserve">
+ <value>Wait operations on multiple wait handles including a named synchronization primitive are not supported on this platform.</value>
+ </data>
+ <data name="PlatformNotSupported_OSXFileLocking" xml:space="preserve">
+ <value>Locking/unlocking file regions is not supported on this platform. Use FileShare on the entire file instead.</value>
+ </data>
+ <data name="PlatformNotSupported_ReflectionOnly" xml:space="preserve">
+ <value>ReflectionOnly loading is not supported on this platform.</value>
+ </data>
+ <data name="PlatformNotSupported_Remoting" xml:space="preserve">
+ <value>Remoting is not supported on this platform.</value>
+ </data>
+ <data name="PlatformNotSupported_SecureBinarySerialization" xml:space="preserve">
+ <value>Secure binary serialization is not supported on this platform.</value>
+ </data>
+ <data name="PlatformNotSupported_StrongNameSigning" xml:space="preserve">
+ <value>Strong-name signing is not supported on this platform.</value>
+ </data>
+ <data name="PlatformNotSupported_WinRT" xml:space="preserve">
+ <value>Windows Runtime is not supported on this operating system.</value>
+ </data>
+ <data name="Policy_CannotLoadSemiTrustAssembliesDuringInit" xml:space="preserve">
+ <value>All assemblies loaded as part of AppDomain initialization must be fully trusted.</value>
+ </data>
+ <data name="PostconditionFailed" xml:space="preserve">
+ <value>Postcondition failed.</value>
+ </data>
+ <data name="PostconditionFailed_Cnd" xml:space="preserve">
+ <value>Postcondition failed: {0}</value>
+ </data>
+ <data name="PostconditionOnExceptionFailed" xml:space="preserve">
+ <value>Postcondition failed after throwing an exception.</value>
+ </data>
+ <data name="PostconditionOnExceptionFailed_Cnd" xml:space="preserve">
+ <value>Postcondition failed after throwing an exception: {0}</value>
+ </data>
+ <data name="PreconditionFailed" xml:space="preserve">
+ <value>Precondition failed.</value>
+ </data>
+ <data name="PreconditionFailed_Cnd" xml:space="preserve">
+ <value>Precondition failed: {0}</value>
+ </data>
+ <data name="Rank_MultiDimNotSupported" xml:space="preserve">
+ <value>Only single dimension arrays are supported here.</value>
+ </data>
+ <data name="Rank_MustMatch" xml:space="preserve">
+ <value>The specified arrays must have the same number of dimensions.</value>
+ </data>
+ <data name="ReflectionTypeLoad_LoadFailed" xml:space="preserve">
+ <value>Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.</value>
+ </data>
+ <data name="Remoting_AppDomainUnloaded_ThreadUnwound" xml:space="preserve">
+ <value>The application domain in which the thread was running has been unloaded.</value>
+ </data>
+ <data name="ResourceReaderIsClosed" xml:space="preserve">
+ <value>ResourceReader is closed.</value>
+ </data>
+ <data name="Resources_StreamNotValid" xml:space="preserve">
+ <value>Stream is not a valid resource file.</value>
+ </data>
+ <data name="RFLCT_AmbigCust" xml:space="preserve">
+ <value>Multiple custom attributes of the same type found.</value>
+ </data>
+ <data name="RFLCT_Ambiguous" xml:space="preserve">
+ <value>Ambiguous match found.</value>
+ </data>
+ <data name="InvalidFilterCriteriaException_CritInt" xml:space="preserve">
+ <value>An Int32 must be provided for the filter criteria.</value>
+ </data>
+ <data name="InvalidFilterCriteriaException_CritString" xml:space="preserve">
+ <value>A String must be provided for the filter criteria.</value>
+ </data>
+ <data name="RFLCT_InvalidFieldFail" xml:space="preserve">
+ <value>'{0}' field specified was not found.</value>
+ </data>
+ <data name="RFLCT_InvalidPropFail" xml:space="preserve">
+ <value>'{0}' property specified was not found.</value>
+ </data>
+ <data name="RFLCT_Targ_ITargMismatch" xml:space="preserve">
+ <value>Object does not match target type.</value>
+ </data>
+ <data name="RFLCT_Targ_StatFldReqTarg" xml:space="preserve">
+ <value>Non-static field requires a target.</value>
+ </data>
+ <data name="RFLCT_Targ_StatMethReqTarg" xml:space="preserve">
+ <value>Non-static method requires a target.</value>
+ </data>
+ <data name="RuntimeWrappedException" xml:space="preserve">
+ <value>An object that does not derive from System.Exception has been wrapped in a RuntimeWrappedException.</value>
+ </data>
+ <data name="Security_CannotReadFileData" xml:space="preserve">
+ <value>The time zone ID '{0}' was found on the local computer, but the application does not have permission to read the file.</value>
+ </data>
+ <data name="Security_CannotReadRegistryData" xml:space="preserve">
+ <value>The time zone ID '{0}' was found on the local computer, but the application does not have permission to read the registry information.</value>
+ </data>
+ <data name="Security_RegistryPermission" xml:space="preserve">
+ <value>Requested registry access is not allowed.</value>
+ </data>
+ <data name="SemaphoreSlim_ctor_InitialCountWrong" xml:space="preserve">
+ <value>The initialCount argument must be non-negative and less than or equal to the maximumCount.</value>
+ </data>
+ <data name="SemaphoreSlim_ctor_MaxCountWrong" xml:space="preserve">
+ <value>The maximumCount argument must be a positive number. If a maximum is not required, use the constructor without a maxCount parameter.</value>
+ </data>
+ <data name="SemaphoreSlim_Disposed" xml:space="preserve">
+ <value>The semaphore has been disposed.</value>
+ </data>
+ <data name="SemaphoreSlim_Release_CountWrong" xml:space="preserve">
+ <value>The releaseCount argument must be greater than zero.</value>
+ </data>
+ <data name="SemaphoreSlim_Wait_TimeoutWrong" xml:space="preserve">
+ <value>The timeout must represent a value between -1 and Int32.MaxValue, inclusive.</value>
+ </data>
+ <data name="Serialization_BadParameterInfo" xml:space="preserve">
+ <value>Non existent ParameterInfo. Position bigger than member's parameters length.</value>
+ </data>
+ <data name="Serialization_CorruptField" xml:space="preserve">
+ <value>The value of the field '{0}' is invalid. The serialized data is corrupt.</value>
+ </data>
+ <data name="Serialization_DateTimeTicksOutOfRange" xml:space="preserve">
+ <value>Invalid serialized DateTime data. Ticks must be between DateTime.MinValue.Ticks and DateTime.MaxValue.Ticks.</value>
+ </data>
+ <data name="Serialization_InsufficientDeserializationState" xml:space="preserve">
+ <value>Insufficient state to deserialize the object. Missing field '{0}'. More information is needed.</value>
+ </data>
+ <data name="Serialization_InsufficientState" xml:space="preserve">
+ <value>Insufficient state to return the real object.</value>
+ </data>
+ <data name="Serialization_InvalidData" xml:space="preserve">
+ <value>An error occurred while deserializing the object. The serialized data is corrupt.</value>
+ </data>
+ <data name="Serialization_InvalidDelegateType" xml:space="preserve">
+ <value>Cannot serialize delegates over unmanaged function pointers, dynamic methods or methods outside the delegate creator's assembly.</value>
+ </data>
+ <data name="Serialization_InvalidEscapeSequence" xml:space="preserve">
+ <value>The serialized data contained an invalid escape sequence '\\{0}'.</value>
+ </data>
+ <data name="Serialization_InvalidFieldState" xml:space="preserve">
+ <value>Object fields may not be properly initialized.</value>
+ </data>
+ <data name="Serialization_InvalidOnDeser" xml:space="preserve">
+ <value>OnDeserialization method was called while the object was not being deserialized.</value>
+ </data>
+ <data name="Serialization_InvalidPtrValue" xml:space="preserve">
+ <value>An IntPtr or UIntPtr with an eight byte value cannot be deserialized on a machine with a four byte word size.</value>
+ </data>
+ <data name="Serialization_InvalidType" xml:space="preserve">
+ <value>Only system-provided types can be passed to the GetUninitializedObject method. '{0}' is not a valid instance of a type.</value>
+ </data>
+ <data name="Serialization_KeyValueDifferentSizes" xml:space="preserve">
+ <value>The keys and values arrays have different sizes.</value>
+ </data>
+ <data name="Serialization_MemberOutOfRange" xml:space="preserve">
+ <value>The deserialized value of the member "{0}" in the class "{1}" is out of range.</value>
+ </data>
+ <data name="Serialization_MemberTypeNotRecognized" xml:space="preserve">
+ <value>Unknown member type.</value>
+ </data>
+ <data name="Serialization_MissField" xml:space="preserve">
+ <value>Field {0} is missing.</value>
+ </data>
+ <data name="Serialization_MissingDateTimeData" xml:space="preserve">
+ <value>Invalid serialized DateTime data. Unable to find 'ticks' or 'dateData'.</value>
+ </data>
+ <data name="Serialization_MissingKeys" xml:space="preserve">
+ <value>The Keys for this Hashtable are missing.</value>
+ </data>
+ <data name="Serialization_MissingValues" xml:space="preserve">
+ <value>The values for this dictionary are missing.</value>
+ </data>
+ <data name="Serialization_NonSerType" xml:space="preserve">
+ <value>Type '{0}' in Assembly '{1}' is not marked as serializable.</value>
+ </data>
+ <data name="Serialization_NoParameterInfo" xml:space="preserve">
+ <value>Serialized member does not have a ParameterInfo.</value>
+ </data>
+ <data name="Serialization_NotFound" xml:space="preserve">
+ <value>Member '{0}' was not found.</value>
+ </data>
+ <data name="Serialization_NullKey" xml:space="preserve">
+ <value>One of the serialized keys is null.</value>
+ </data>
+ <data name="Serialization_NullSignature" xml:space="preserve">
+ <value>The method signature cannot be null.</value>
+ </data>
+ <data name="Serialization_OptionalFieldVersionValue" xml:space="preserve">
+ <value>Version value must be positive.</value>
+ </data>
+ <data name="Serialization_SameNameTwice" xml:space="preserve">
+ <value>Cannot add the same member twice to a SerializationInfo object.</value>
+ </data>
+ <data name="Serialization_StringBuilderCapacity" xml:space="preserve">
+ <value>The serialized Capacity property of StringBuilder must be positive, less than or equal to MaxCapacity and greater than or equal to the String length.</value>
+ </data>
+ <data name="Serialization_StringBuilderMaxCapacity" xml:space="preserve">
+ <value>The serialized MaxCapacity property of StringBuilder must be positive and greater than or equal to the String length.</value>
+ </data>
+ <data name="Serialization_UnableToFindModule" xml:space="preserve">
+ <value>The given module {0} cannot be found within the assembly {1}.</value>
+ </data>
+ <data name="Serialization_UnknownMember" xml:space="preserve">
+ <value>Cannot get the member '{0}'.</value>
+ </data>
+ <data name="SpinLock_Exit_SynchronizationLockException" xml:space="preserve">
+ <value>The calling thread does not hold the lock.</value>
+ </data>
+ <data name="SpinLock_IsHeldByCurrentThread" xml:space="preserve">
+ <value>Thread tracking is disabled.</value>
+ </data>
+ <data name="SpinLock_TryEnter_ArgumentOutOfRange" xml:space="preserve">
+ <value>The timeout must be a value between -1 and Int32.MaxValue, inclusive.</value>
+ </data>
+ <data name="SpinLock_TryEnter_LockRecursionException" xml:space="preserve">
+ <value>The calling thread already holds the lock.</value>
+ </data>
+ <data name="SpinLock_TryReliableEnter_ArgumentException" xml:space="preserve">
+ <value>The tookLock argument must be set to false before calling this method.</value>
+ </data>
+ <data name="SpinWait_SpinUntil_ArgumentNull" xml:space="preserve">
+ <value>The condition argument is null.</value>
+ </data>
+ <data name="SpinWait_SpinUntil_TimeoutWrong" xml:space="preserve">
+ <value>The timeout must represent a value between -1 and Int32.MaxValue, inclusive.</value>
+ </data>
+ <data name="StackTrace_InFileLineNumber" xml:space="preserve">
+ <value>in {0}:line {1}</value>
+ </data>
+ <data name="Task_ContinueWith_ESandLR" xml:space="preserve">
+ <value>The specified TaskContinuationOptions combined LongRunning and ExecuteSynchronously. Synchronous continuations should not be long running.</value>
+ </data>
+ <data name="Task_ContinueWith_NotOnAnything" xml:space="preserve">
+ <value>The specified TaskContinuationOptions excluded all continuation kinds.</value>
+ </data>
+ <data name="Task_Delay_InvalidDelay" xml:space="preserve">
+ <value>The value needs to translate in milliseconds to -1 (signifying an infinite timeout), 0 or a positive integer less than or equal to Int32.MaxValue.</value>
+ </data>
+ <data name="Task_Delay_InvalidMillisecondsDelay" xml:space="preserve">
+ <value>The value needs to be either -1 (signifying an infinite timeout), 0 or a positive integer.</value>
+ </data>
+ <data name="Task_Dispose_NotCompleted" xml:space="preserve">
+ <value>A task may only be disposed if it is in a completion state (RanToCompletion, Faulted or Canceled).</value>
+ </data>
+ <data name="Task_FromAsync_LongRunning" xml:space="preserve">
+ <value>It is invalid to specify TaskCreationOptions.LongRunning in calls to FromAsync.</value>
+ </data>
+ <data name="Task_FromAsync_PreferFairness" xml:space="preserve">
+ <value>It is invalid to specify TaskCreationOptions.PreferFairness in calls to FromAsync.</value>
+ </data>
+ <data name="Task_MultiTaskContinuation_EmptyTaskList" xml:space="preserve">
+ <value>The tasks argument contains no tasks.</value>
+ </data>
+ <data name="Task_MultiTaskContinuation_FireOptions" xml:space="preserve">
+ <value>It is invalid to exclude specific continuation kinds for continuations off of multiple tasks.</value>
+ </data>
+ <data name="Task_MultiTaskContinuation_NullTask" xml:space="preserve">
+ <value>The tasks argument included a null value.</value>
+ </data>
+ <data name="Task_RunSynchronously_AlreadyStarted" xml:space="preserve">
+ <value>RunSynchronously may not be called on a task that was already started.</value>
+ </data>
+ <data name="Task_RunSynchronously_Continuation" xml:space="preserve">
+ <value>RunSynchronously may not be called on a continuation task.</value>
+ </data>
+ <data name="Task_RunSynchronously_Promise" xml:space="preserve">
+ <value>RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.</value>
+ </data>
+ <data name="Task_RunSynchronously_TaskCompleted" xml:space="preserve">
+ <value>RunSynchronously may not be called on a task that has already completed.</value>
+ </data>
+ <data name="Task_Start_AlreadyStarted" xml:space="preserve">
+ <value>Start may not be called on a task that was already started.</value>
+ </data>
+ <data name="Task_Start_ContinuationTask" xml:space="preserve">
+ <value>Start may not be called on a continuation task.</value>
+ </data>
+ <data name="Task_Start_Promise" xml:space="preserve">
+ <value>Start may not be called on a promise-style task.</value>
+ </data>
+ <data name="Task_Start_TaskCompleted" xml:space="preserve">
+ <value>Start may not be called on a task that has completed.</value>
+ </data>
+ <data name="Task_ThrowIfDisposed" xml:space="preserve">
+ <value>The task has been disposed.</value>
+ </data>
+ <data name="Task_WaitMulti_NullTask" xml:space="preserve">
+ <value>The tasks array included at least one null element.</value>
+ </data>
+ <data name="TaskCanceledException_ctor_DefaultMessage" xml:space="preserve">
+ <value>A task was canceled.</value>
+ </data>
+ <data name="TaskCompletionSourceT_TrySetException_NoExceptions" xml:space="preserve">
+ <value>The exceptions collection was empty.</value>
+ </data>
+ <data name="TaskCompletionSourceT_TrySetException_NullException" xml:space="preserve">
+ <value>The exceptions collection included at least one null element.</value>
+ </data>
+ <data name="TaskExceptionHolder_UnhandledException" xml:space="preserve">
+ <value>A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread.</value>
+ </data>
+ <data name="TaskExceptionHolder_UnknownExceptionType" xml:space="preserve">
+ <value>(Internal)Expected an Exception or an IEnumerable&lt;Exception&gt;</value>
+ </data>
+ <data name="TaskScheduler_ExecuteTask_WrongTaskScheduler" xml:space="preserve">
+ <value>ExecuteTask may not be called for a task which was previously queued to a different TaskScheduler.</value>
+ </data>
+ <data name="TaskScheduler_FromCurrentSynchronizationContext_NoCurrent" xml:space="preserve">
+ <value>The current SynchronizationContext may not be used as a TaskScheduler.</value>
+ </data>
+ <data name="TaskScheduler_InconsistentStateAfterTryExecuteTaskInline" xml:space="preserve">
+ <value>The TryExecuteTaskInline call to the underlying scheduler succeeded, but the task body was not invoked.</value>
+ </data>
+ <data name="TaskSchedulerException_ctor_DefaultMessage" xml:space="preserve">
+ <value>An exception was thrown by a TaskScheduler.</value>
+ </data>
+ <data name="TaskT_DebuggerNoResult" xml:space="preserve">
+ <value>{Not yet computed}</value>
+ </data>
+ <data name="TaskT_TransitionToFinal_AlreadyCompleted" xml:space="preserve">
+ <value>An attempt was made to transition a task to a final state when it had already completed.</value>
+ </data>
+ <data name="Threading_AbandonedMutexException" xml:space="preserve">
+ <value>The wait completed due to an abandoned mutex.</value>
+ </data>
+ <data name="Threading_WaitHandleCannotBeOpenedException" xml:space="preserve">
+ <value>No handle of the given name exists.</value>
+ </data>
+ <data name="Threading_WaitHandleCannotBeOpenedException_InvalidHandle" xml:space="preserve">
+ <value>A WaitHandle with system-wide name '{0}' cannot be created. A WaitHandle of a different type might have the same name.</value>
+ </data>
+ <data name="Threading_WaitHandleTooManyPosts" xml:space="preserve">
+ <value>The WaitHandle cannot be signaled because it would exceed its maximum count.</value>
+ </data>
+ <data name="Threading_SemaphoreFullException" xml:space="preserve">
+ <value>Adding the specified count to the semaphore would cause it to exceed its maximum count.</value>
+ </data>
+ <data name="ThreadLocal_Disposed" xml:space="preserve">
+ <value>The ThreadLocal object has been disposed.</value>
+ </data>
+ <data name="ThreadLocal_Value_RecursiveCallsToValue" xml:space="preserve">
+ <value>ValueFactory attempted to access the Value property of this instance.</value>
+ </data>
+ <data name="ThreadLocal_ValuesNotAvailable" xml:space="preserve">
+ <value>The ThreadLocal object is not tracking values. To use the Values property, use a ThreadLocal constructor that accepts the trackAllValues parameter and set the parameter to true.</value>
+ </data>
+ <data name="TimeZoneNotFound_MissingData" xml:space="preserve">
+ <value>The time zone ID '{0}' was not found on the local computer.</value>
+ </data>
+ <data name="TypeInitialization_Default" xml:space="preserve">
+ <value>Type constructor threw an exception.</value>
+ </data>
+ <data name="TypeInitialization_Type" xml:space="preserve">
+ <value>The type initializer for '{0}' threw an exception.</value>
+ </data>
+ <data name="TypeLoad_ResolveNestedType" xml:space="preserve">
+ <value>Could not resolve nested type '{0}' in type "{1}'.</value>
+ </data>
+ <data name="TypeLoad_ResolveType" xml:space="preserve">
+ <value>Could not resolve type '{0}'.</value>
+ </data>
+ <data name="TypeLoad_ResolveTypeFromAssembly" xml:space="preserve">
+ <value>Could not resolve type '{0}' in assembly '{1}'.</value>
+ </data>
+ <data name="UnauthorizedAccess_IODenied_NoPathName" xml:space="preserve">
+ <value>Access to the path is denied.</value>
+ </data>
+ <data name="UnauthorizedAccess_IODenied_Path" xml:space="preserve">
+ <value>Access to the path '{0}' is denied.</value>
+ </data>
+ <data name="UnauthorizedAccess_MemStreamBuffer" xml:space="preserve">
+ <value>MemoryStream's internal buffer cannot be accessed.</value>
+ </data>
+ <data name="UnauthorizedAccess_RegistryKeyGeneric_Key" xml:space="preserve">
+ <value>Access to the registry key '{0}' is denied.</value>
+ </data>
+ <data name="UnauthorizedAccess_RegistryNoWrite" xml:space="preserve">
+ <value>Cannot write to the registry key.</value>
+ </data>
+ <data name="UnauthorizedAccess_SystemDomain" xml:space="preserve">
+ <value>Cannot execute an assembly in the system domain.</value>
+ </data>
+ <data name="UnknownError_Num" xml:space="preserve">
+ <value>Unknown error "{0}".</value>
+ </data>
+ <data name="Verification_Exception" xml:space="preserve">
+ <value>Operation could destabilize the runtime.</value>
+ </data>
+ <data name="Word_At" xml:space="preserve">
+ <value>at</value>
+ </data>
+ <data name="DebugAssertBanner" xml:space="preserve">
+ <value>---- DEBUG ASSERTION FAILED ----</value>
+ </data>
+ <data name="DebugAssertLongMessage" xml:space="preserve">
+ <value>---- Assert Long Message ----</value>
+ </data>
+ <data name="DebugAssertShortMessage" xml:space="preserve">
+ <value>---- Assert Short Message ----</value>
+ </data>
+ <data name="LockRecursionException_ReadAfterWriteNotAllowed" xml:space="preserve">
+ <value>A read lock may not be acquired with the write lock held in this mode.</value>
+ </data>
+ <data name="LockRecursionException_RecursiveReadNotAllowed" xml:space="preserve">
+ <value>Recursive read lock acquisitions not allowed in this mode.</value>
+ </data>
+ <data name="LockRecursionException_RecursiveWriteNotAllowed" xml:space="preserve">
+ <value>Recursive write lock acquisitions not allowed in this mode.</value>
+ </data>
+ <data name="LockRecursionException_ReadAfterWriteNotAllowed" xml:space="preserve">
+ <value>A read lock may not be acquired with the write lock held in this mode.</value>
+ </data>
+ <data name="LockRecursionException_RecursiveUpgradeNotAllowed" xml:space="preserve">
+ <value>Recursive upgradeable lock acquisitions not allowed in this mode.</value>
+ </data>
+ <data name="LockRecursionException_RecursiveReadNotAllowed" xml:space="preserve">
+ <value>Recursive read lock acquisitions not allowed in this mode.</value>
+ </data>
+ <data name="LockRecursionException_WriteAfterReadNotAllowed" xml:space="preserve">
+ <value>Write lock may not be acquired with read lock held. This pattern is prone to deadlocks. Please ensure that read locks are released before taking a write lock. If an upgrade is necessary, use an upgrade lock in place of the read lock.</value>
+ </data>
+ <data name="LockRecursionException_WriteAfterReadNotAllowed" xml:space="preserve">
+ <value>Write lock may not be acquired with read lock held. This pattern is prone to deadlocks. Please ensure that read locks are released before taking a write lock. If an upgrade is necessary, use an upgrade lock in place of the read lock.</value>
+ </data>
+ <data name="SynchronizationLockException_MisMatchedUpgrade" xml:space="preserve">
+ <value>The upgradeable lock is being released without being held.</value>
+ </data>
+ <data name="SynchronizationLockException_MisMatchedRead" xml:space="preserve">
+ <value>The read lock is being released without being held.</value>
+ </data>
+ <data name="SynchronizationLockException_IncorrectDispose" xml:space="preserve">
+ <value>The lock is being disposed while still being used. It either is being held by a thread and/or has active waiters waiting to acquire the lock.</value>
+ </data>
+ <data name="LockRecursionException_UpgradeAfterReadNotAllowed" xml:space="preserve">
+ <value>Upgradeable lock may not be acquired with read lock held.</value>
+ </data>
+ <data name="LockRecursionException_UpgradeAfterWriteNotAllowed" xml:space="preserve">
+ <value>Upgradeable lock may not be acquired with write lock held in this mode. Acquiring Upgradeable lock gives the ability to read along with an option to upgrade to a writer.</value>
+ </data>
+ <data name="SynchronizationLockException_MisMatchedWrite" xml:space="preserve">
+ <value>The write lock is being released without being held.</value>
+ </data>
+</root>
diff --git a/src/mscorlib/System.Private.CoreLib.csproj b/src/mscorlib/System.Private.CoreLib.csproj
index 3ac5dbd287..3a0917f75e 100644
--- a/src/mscorlib/System.Private.CoreLib.csproj
+++ b/src/mscorlib/System.Private.CoreLib.csproj
@@ -1,14 +1,10 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-
<!-- Always use latest Roslyn compiler -->
- <Import Project="..\..\Tools\net45\roslyn\build\Microsoft.Net.Compilers.props" Condition="'$(OS)'=='Windows_NT'" />
-
+ <Import Project="..\..\Tools\net46\roslyn\build\Microsoft.Net.Compilers.props" Condition="'$(OS)'=='Windows_NT'" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-
<!-- Include common build properties -->
<Import Project="..\..\dir.props" />
-
<!-- Compilation options -->
<PropertyGroup>
<AvailablePlatforms>amd64,x86,arm,armel,arm64</AvailablePlatforms>
@@ -19,16 +15,13 @@
<Platform Condition=" '$(Platform)' == 'x64' ">amd64</Platform>
<Platform Condition=" '$(Platform)' == 'armel' ">arm</Platform>
<ProjectGuid>{3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}</ProjectGuid>
-
<OutputType>Library</OutputType>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-
<!-- This prevents the default MsBuild targets from referencing System.Core.dll -->
<AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
<!-- These prevent the default MsBuild targets from referencing System.dll and mscorlib.dll -->
<NoStdLib>true</NoStdLib>
<NoCompilerStandardLib>true</NoCompilerStandardLib>
-
<SubsystemVersion>6.00</SubsystemVersion>
<UTF8OutPut>true</UTF8OutPut>
<HighEntropyVA>true</HighEntropyVA>
@@ -39,20 +32,21 @@
<WarningsNotAsErrors>$(WarningsNotAsErrors);618</WarningsNotAsErrors>
<NoWarn>649,3019,414,169,3015</NoWarn>
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
-
<SignAssembly>true</SignAssembly>
<DelaySign>true</DelaySign>
-
- <DefineConstants>$(DefineConstants);CORECLR;_USE_NLS_PLUS_TABLE;RESOURCE_SATELLITE_CONFIG;INSIDE_CLR;CODE_ANALYSIS_BASELINE</DefineConstants>
+ <DefineConstants>$(DefineConstants);CORECLR;_USE_NLS_PLUS_TABLE;RESOURCE_SATELLITE_CONFIG;CODE_ANALYSIS_BASELINE</DefineConstants>
+ <!-- We don't use any of MSBuild's resolution logic for resolving the framework, so just set these two properties to any folder that exists to skip
+ the GenerateReferenceAssemblyPaths task (not target) and to prevent it from outputting a warning (MSB3644). -->
+ <_TargetFrameworkDirectories>$(MSBuildThisFileDirectory)/Documentation</_TargetFrameworkDirectories>
+ <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory)/Documentation</_FullFrameworkReferenceAssemblyPaths>
+ <SkipCommonResourcesIncludes>true</SkipCommonResourcesIncludes>
</PropertyGroup>
-
<!-- Add Serviceable attribute to the project's metadata -->
<ItemGroup>
<AssemblyMetadata Include="Serviceable">
- <Value>True</Value>
+ <Value>True</Value>
</AssemblyMetadata>
</ItemGroup>
-
<!-- Platform specific properties -->
<PropertyGroup Condition="'$(Platform)' == 'amd64'">
<PlatformTarget>x64</PlatformTarget>
@@ -73,7 +67,6 @@
<PlatformTarget>AnyCPU</PlatformTarget>
<DefineConstants>BIT64;ARM64;$(DefineConstants)</DefineConstants>
</PropertyGroup>
-
<!-- Configuration specific properties -->
<PropertyGroup Condition="'$(Configuration)' == 'Debug' or '$(Configuration)' == 'Checked'">
<DebugSymbols>true</DebugSymbols>
@@ -89,19 +82,20 @@
<DebugType>pdbOnly</DebugType>
<DefineConstants>TRACE;$(DefineConstants)</DefineConstants>
</PropertyGroup>
-
- <!-- Roslyn does not support writing PDBs on Unix -->
+ <!-- Make portable PDBs on Unix -->
<PropertyGroup Condition="'$(OsEnvironment)' == 'Unix'">
- <DebugSymbols>false</DebugSymbols>
- <DebugType>none</DebugType>
+ <DebugType>portable</DebugType>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(TargetsOSX)' == 'true'">
+ <DefineConstants>PLATFORM_OSX;$(DefineConstants)</DefineConstants>
</PropertyGroup>
-
<!-- Assembly attributes -->
<PropertyGroup>
<AssemblyName>System.Private.CoreLib</AssemblyName>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
<MajorVersion>4</MajorVersion>
<MinorVersion>6</MinorVersion>
+ <ExcludeAssemblyInfoPartialFile>true</ExcludeAssemblyInfoPartialFile>
</PropertyGroup>
<ItemGroup>
<AssemblyInfoLines Include="[assembly: System.Resources.SatelliteContractVersion(&quot;$(AssemblyVersion)&quot;)]" />
@@ -109,1148 +103,629 @@
<AssemblyInfoLines Include="[assembly: System.Runtime.InteropServices.ComVisible(false)]" />
<AssemblyInfoLines Include="[assembly: System.Resources.NeutralResourcesLanguage(&quot;en-US&quot;)]" />
</ItemGroup>
-
<!--
Helper Paths
-->
<PropertyGroup>
<CommonPath>$(MSBuildThisFileDirectory)Common</CommonPath>
<BclSourcesRoot>$(MSBuildThisFileDirectory)src</BclSourcesRoot>
- <CoreFxSourcesRoot>$(MSBuildThisFileDirectory)corefx</CoreFxSourcesRoot>
<MscorlibDir>$(MSBuildThisFileDirectory)</MscorlibDir>
<NlpObjDir>$(BclSourcesRoot)\System\Globalization\Tables</NlpObjDir>
</PropertyGroup>
-
- <!-- Output paths -->
- <PropertyGroup>
- <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)' == ''">$(RootBinDir)obj</BaseIntermediateOutputPath>
- <IntermediateOutputPath Condition="'$(IntermediateOutputPath)' == ''">$(BaseIntermediateOutputPath)\$(BuildOS).$(BuildArch).$(Configuration)</IntermediateOutputPath>
- <OutputPath Condition="'$(OutputPath)' == ''">$(BinDir)</OutputPath>
- </PropertyGroup>
-
<!-- Msbuild variables needed to get CoreCLR features to be set properly. -->
<PropertyGroup>
<ClrProduct>core_clr</ClrProduct>
<BuildForCoreSystem>true</BuildForCoreSystem>
-
<!-- These are needed to make sure we have the right set of defines -->
<TargetArch Condition="'$(Platform)'=='x86'">i386</TargetArch>
<TargetArch Condition="'$(Platform)'!='x86'">$(Platform)</TargetArch>
</PropertyGroup>
-
<!-- CLR Features -->
<Import Project="$(MSBuildThisFileDirectory)..\..\clr.coreclr.props" />
<Import Project="$(MSBuildThisFileDirectory)..\..\clr.defines.targets" />
-
<!-- Sources -->
<ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\AccessedThroughPropertyAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\RuntimeHelpers.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CompilerGeneratedAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CustomConstantAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\DateTimeConstantAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\DiscardableAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\DecimalConstantAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\DisablePrivateReflectionAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CompilationRelaxations.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CompilerGlobalScopeAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\ExtensionAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\FormattableStringFactory.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\FixedBufferAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IndexerNameAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\InternalsVisibleToAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IsVolatile.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\MethodImplAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\FixedAddressValueTypeAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\UnsafeValueTypeAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\AssemblySettingAttributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\TypeDependencyAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CompilerMarshalOverride.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\jithelpers.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\Unsafe.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\SpecialNameAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\SuppressMergeCheckAttribute.cs" />
- <MscorlibSources Condition="'$(FeatureICastable)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\ICastable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\SuppressIldasmAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\TypeForwardedToAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\TypeForwardedFromAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\ReferenceAssemblyAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\RuntimeCompatibilityAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\RuntimeWrappedException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\ConditionalWeakTable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CallerFilePathAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CallerLineNumberAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CallerMemberNameAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\StateMachineAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IteratorStateMachineAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\AsyncStateMachineAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\AsyncMethodBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\IAsyncStateMachine.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\INotifyCompletion.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\TaskAwaiter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\YieldAwaitable.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Reliability\CriticalFinalizerObject.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Reliability\ReliabilityContractAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Reliability\PrePrepareMethodAttribute.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\MemoryFailPoint.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\GcSettings.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\CollectionBase.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\ArrayList.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Comparer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\CompatibleComparer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\ListDictionaryInternal.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\EmptyReadOnlyDictionaryInternal.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Hashtable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\DictionaryEntry.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\ICollection.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\IComparer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\IDictionary.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\IDictionaryEnumerator.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\IEnumerable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\IEnumerator.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\IEqualityComparer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\IHashCodeProvider.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\IList.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\IStructuralEquatable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\IStructuralComparable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\StructuralComparisons.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\ComponentModel\EditorBrowsableAttribute.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ArrayWithOffset.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\Attributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\CallingConvention.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\CharSet.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\COMException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\CriticalHandle.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ExternalException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\GcHandle.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\GCHandleCookieTable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\HandleRef.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ICustomMarshaler.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\InvalidOleVariantTypeException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\LayoutKind.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\Marshal.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\MarshalDirectiveException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\PInvokeMap.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\RuntimeEnvironment.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SEHException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SafeBuffer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SafeHandle.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\BStrWrapper.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\CurrencyWrapper.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ErrorWrapper.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\UnknownWrapper.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\VariantWrapper.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComMemberType.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ICustomAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ICustomQueryInterface.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\InvalidComObjectException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SafeArrayRankMismatchException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SafeArrayTypeMismatchException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\NativeCallableAttribute.cs" />
- <MscorlibSources Condition="'$(FeatureCominterop)' != 'true'" Include="$(BclSourcesRoot)\System\Runtime\InteropServices\NonPortable.cs" />
- <MscorlibSources Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\InteropServices\DispatchWrapper.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ICustomFactory.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Runtime\InteropServices\StringBuffer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\RuntimeHelpers.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\CustomConstantAttribute.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\DateTimeConstantAttribute.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\DecimalConstantAttribute.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\FriendAccessAllowedAttribute.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\MethodImplAttribute.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\TypeDependencyAttribute.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\jithelpers.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\Unsafe.cs" />
+ <Compile Condition="'$(FeatureICastable)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\ICastable.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\RuntimeWrappedException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\ConditionalWeakTable.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\AsyncMethodBuilder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\TaskAwaiter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\CompilerServices\YieldAwaitable.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\Reliability\CriticalFinalizerObject.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\Reliability\PrePrepareMethodAttribute.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\MemoryFailPoint.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\GcSettings.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Collections\ArrayList.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\Comparer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\CompatibleComparer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\ListDictionaryInternal.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\EmptyReadOnlyDictionaryInternal.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\Hashtable.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\IHashCodeProvider.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ArrayWithOffset.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\Attributes.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\COMException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\CriticalHandle.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\GcHandle.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\GCHandleCookieTable.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\HandleRef.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ICustomMarshaler.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\InvalidOleVariantTypeException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\Marshal.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\MarshalDirectiveException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\PInvokeMap.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\RuntimeEnvironment.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SEHException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SafeBuffer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SafeHandle.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\BStrWrapper.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\CurrencyWrapper.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ErrorWrapper.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\UnknownWrapper.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\VariantWrapper.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComMemberType.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ICustomAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ICustomQueryInterface.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\InvalidComObjectException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SafeArrayRankMismatchException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\SafeArrayTypeMismatchException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\NativeCallableAttribute.cs" />
+ <Compile Condition="'$(FeatureCominterop)' != 'true'" Include="$(BclSourcesRoot)\System\Runtime\InteropServices\NonPortable.cs" />
+ <Compile Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\Runtime\InteropServices\DispatchWrapper.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ICustomFactory.cs" />
</ItemGroup>
<ItemGroup Condition="'$(FeatureClassicCominterop)' == 'true'">
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ITypeLibConverter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ITypeLibConverter.cs" />
</ItemGroup>
<ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\Expando\IExpando.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\Expando\IExpando.cs" />
</ItemGroup>
<ItemGroup Condition="'$(FeatureClassicCominterop)' == 'true'">
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComEventsHelper.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComEventsInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComEventsMethod.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComEventsSink.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\NativeMethods.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IBindCtx.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IConnectionPointContainer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IConnectionPoint.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IEnumMoniker.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IEnumConnections.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IEnumConnectionPoints.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IEnumString.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IEnumVARIANT.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IMoniker.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IPersistFile.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IRunningObjectTable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IStream.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\ITypeComp.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\ITypeInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\ITypeLib.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\ITypeLib2.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\ITypeInfo2.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComEventsHelper.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComEventsInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComEventsMethod.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComEventsSink.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\NativeMethods.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IBindCtx.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IConnectionPointContainer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IConnectionPoint.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IEnumMoniker.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IEnumConnections.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IEnumConnectionPoints.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IEnumString.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IEnumVARIANT.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IMoniker.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IPersistFile.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IRunningObjectTable.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\IStream.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\ITypeComp.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\ITypeInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\ITypeLib.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\ITypeLib2.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\ComTypes\ITypeInfo2.cs" />
</ItemGroup>
<ItemGroup Condition="'$(FeatureCominterop)' == 'true'">
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\Attributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\ConstantSplittableMap.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\DictionaryKeyCollection.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\DictionaryValueCollection.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\EnumeratorToIteratorAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\VectorToListAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\VectorToCollectionAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\VectorViewToReadOnlyCollectionAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\MapToDictionaryAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\MapToCollectionAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\MapViewToReadOnlyCollectionAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\ListToVectorAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\DictionaryToMapAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\BindableVectorToListAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\BindableVectorToCollectionAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\ListToBindableVectorAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\ListToBindableVectorViewAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\EventRegistrationToken.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\EventRegistrationTokenTable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IActivationFactory.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IRestrictedErrorInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IMapViewToIReadOnlyDictionaryAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IVectorViewToIReadOnlyListAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IReadOnlyDictionaryToIMapViewAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IReadOnlyListToIVectorViewAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IteratorToEnumeratorAdapter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\ManagedActivationFactory.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\NativeMethods.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\PropertyValue.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\WindowsRuntimeMarshal.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\WindowsRuntimeMetadata.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IClosable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\RuntimeClass.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\Attributes.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\ConstantSplittableMap.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\DictionaryKeyCollection.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\DictionaryValueCollection.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\EnumeratorToIteratorAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\VectorToListAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\VectorToCollectionAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\VectorViewToReadOnlyCollectionAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\MapToDictionaryAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\MapToCollectionAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\MapViewToReadOnlyCollectionAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\ListToVectorAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\DictionaryToMapAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\BindableVectorToListAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\BindableVectorToCollectionAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\ListToBindableVectorAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\ListToBindableVectorViewAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\EventRegistrationToken.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\EventRegistrationTokenTable.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IActivationFactory.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IRestrictedErrorInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IMapViewToIReadOnlyDictionaryAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IVectorViewToIReadOnlyListAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IReadOnlyDictionaryToIMapViewAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IReadOnlyListToIVectorViewAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IteratorToEnumeratorAdapter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\ManagedActivationFactory.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\NativeMethods.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\PropertyValue.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\WindowsRuntimeMarshal.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\WindowsRuntimeMetadata.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IClosable.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\RuntimeClass.cs" />
</ItemGroup>
<ItemGroup Condition="'$(FeatureCominterop)' == 'true'">
- <MscorlibSources Include='$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\CLRIPropertyValueImpl.cs' />
- <MscorlibSources Include='$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\CLRIReferenceImpl.cs' />
- <MscorlibSources Include='$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IPropertyValue.cs' />
- <MscorlibSources Include='$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IReference.cs' />
- <MscorlibSources Include='$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\WindowsFoundationEventHandler.cs' />
- <MscorlibSources Include='$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\ICustomPropertyProvider.cs' />
- <MscorlibSources Include='$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\ICustomProperty.cs' />
- <MscorlibSources Include='$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\CustomPropertyImpl.cs' />
- <MscorlibSources Include='$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\WindowsRuntimeBufferHelper.cs' />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\CLRIPropertyValueImpl.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\CLRIReferenceImpl.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IPropertyValue.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IReference.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\WindowsFoundationEventHandler.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\ICustomPropertyProvider.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\ICustomProperty.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\CustomPropertyImpl.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\WindowsRuntimeBufferHelper.cs" />
</ItemGroup>
<ItemGroup Condition="'$(FeatureCominterop)' == 'true'">
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IIterable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IIterator.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IVector.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IMap.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\CLRIKeyValuePairImpl.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\AggregateException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\AppContext\AppContext.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\AppContext\AppContextSwitches.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\AppContext\AppContextDefaultValues.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\AppContext\AppContextDefaultValues.CoreClrOverrides.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\AppContext\AppContextDefaultValues.Defaults.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\AppContext\AppContextDefaultValues.Defaults.Central.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\CurrentTimeZone.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\TimeZone.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Object.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ICloneable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Action.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Array.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ArraySegment.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IComparable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IEquatable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ThrowHelper.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Tuple.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\String.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\String.Comparison.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\String.Manipulation.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\String.Searching.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\StringComparer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\StringComparison.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\StringSplitOptions.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\StringBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\StringBuilderCache.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Exception.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\FormattableString.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\DateTime.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\DateTimeKind.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\DateTimeOffset.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\SystemException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\OutOfMemoryException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\StackOverflowException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\DataMisalignedException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ExecutionEngineException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Delegate.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\MulticastDelegate.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\__Filters.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\__HResults.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\BCLDebug.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\MemberAccessException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Activator.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\AccessViolationException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ApplicationException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\AppDomain.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\AppDomainSetup.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\AppDomainManager.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IAppDomainPauseManager.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\AppDomainAttributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\AppDomainUnloadedException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ArgumentException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ArgumentNullException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ArgumentOutOfRangeException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ArgIterator.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ArithmeticException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ArrayTypeMismatchException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\AsyncCallback.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Attribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\AttributeTargets.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\AttributeUsageAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\BadImageFormatException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\BitConverter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Boolean.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Buffer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Byte.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Char.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\CharEnumerator.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\CLSCompliantAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\TypeUnloadedException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\CompatibilitySwitches.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\LowLevelConsole.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Convert.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\StringFreezingAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Currency.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\DayOfWeek.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\DBNull.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Decimal.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\DefaultBinder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\DelegateSerializationHolder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\DivideByZeroException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Double.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\DuplicateWaitObjectException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Empty.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Enum.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\EntryPointNotFoundException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\DllNotFoundException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Environment.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\EventArgs.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\EventHandler.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\FieldAccessException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\FlagsAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\FormatException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\GC.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Guid.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IAsyncResult.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ICustomFormatter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IDisposable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IFormatProvider.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IFormattable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IndexOutOfRangeException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IObservable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IObserver.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IProgress.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\InsufficientMemoryException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\InsufficientExecutionStackException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Lazy.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Int16.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Int32.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Int64.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IntPtr.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Internal.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\InvalidCastException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\InvalidOperationException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\InvalidProgramException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\InvalidTimeZoneException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IConvertible.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IServiceObjectProvider.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\MarshalByRefObject.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Math.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\MathF.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\mda.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\MethodAccessException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\MidpointRounding.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\MissingFieldException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\MissingMemberException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\MissingMethodException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\MulticastNotSupportedException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\NonSerializedAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\NotFiniteNumberException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\NotImplementedException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\NotSupportedException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\NullReferenceException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Number.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ObjectDisposedException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ObsoleteAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\OperatingSystem.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\OperationCanceledException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\OverflowException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ParamArrayAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ParamsArray.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ParseNumbers.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\PlatformID.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\PlatformNotSupportedException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Progress.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Random.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\RankException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ResId.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\RtType.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\RuntimeArgumentHandle.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\RuntimeHandles.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\SByte.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\SerializableAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\SharedStatics.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Single.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\StubHelpers.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ThreadAttributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\TimeoutException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\TimeSpan.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\TimeZoneInfo.AdjustmentRule.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\TimeZoneInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\TimeZoneInfo.StringSerializer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\TimeZoneInfo.TransitionTime.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\TimeZoneNotFoundException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Type.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\TypeAccessException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\TypeNameParser.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\TypeCode.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\TypedReference.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\TypeInitializationException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\TypeLoadException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\UInt16.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\UInt32.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\UInt64.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\UIntPtr.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\UnauthorizedAccessException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\UnitySerializationHolder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\UnhandledExceptionEventArgs.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\UnhandledExceptionEventHandler.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ValueType.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Version.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Void.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\WeakReference.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\WeakReferenceOfT.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\XmlIgnoreMemberAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\CLRConfig.cs" />
- <MscorlibSources Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\__ComObject.cs" />
- <MscorlibSources Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\Variant.cs" />
- <MscorlibSources Condition="'$(FeatureClassicCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\OleAutBinder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ByReference.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Span.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ReadOnlySpan.cs" />
- </ItemGroup>
- <ItemGroup Condition="'$(TargetsUnix)' == 'true'">
- <MscorlibSources Include="$(BclSourcesRoot)\System\TimeZoneInfo.Unix.cs" />
- </ItemGroup>
- <ItemGroup Condition="'$(TargetsUnix)' != 'true'">
- <MscorlibSources Include="$(BclSourcesRoot)\System\TimeZoneInfo.Win32.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\Internal\Runtime\Augments\EnvironmentAugments.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\Internal\Runtime\Augments\RuntimeThread.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\__Filters.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\AmbiguousMatchException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Assembly.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\AssemblyAttributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\AssemblyName.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\AssemblyNameFlags.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Associates.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\CustomAttributeExtensions.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\CustomAttributeFormatException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Binder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\BindingFlags.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\CallingConventions.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\ConstructorInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\CustomAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\DefaultMemberAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\EventAttributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\EventInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\FieldAttributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\FieldInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\GenericParameterAttributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\ICustomAttributeProvider.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\IReflectableType.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\IntrospectionExtensions.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\RuntimeReflectionExtensions.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\InterfaceMapping.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\InvalidFilterCriteriaException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\IReflect.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\LoaderAllocator.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\ManifestResourceInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\MdConstant.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\MdImport.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\MemberFilter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\MemberInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\MemberInfoSerializationHolder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\MemberTypes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\MethodAttributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\MethodBase.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\MethodImplAttributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\MethodInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Missing.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Module.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\ObfuscateAssemblyAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\ObfuscationAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\MethodBody.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\ParameterAttributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\ParameterInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\ParameterModifier.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Pointer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\PropertyAttributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\PropertyInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\ReflectionContext.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\ReflectionTypeLoadException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\ResourceAttributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\StrongNameKeyPair.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\TargetException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\TargetInvocationException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\TargetParameterCountException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\TypeAttributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\TypeDelegator.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\TypeFilter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\TypeInfo.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\AssemblyBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\AssemblyBuilderData.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\AssemblyBuilderAccess.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\AQNBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\ConstructorBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\DynamicILGenerator.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\DynamicMethod.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\EventBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\EventToken.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\FieldBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\FieldToken.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\ILGenerator.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\ISymWrapperCore.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\Label.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\LocalBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\MethodBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\MethodBuilderInstantiation.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\SymbolType.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\SymbolMethod.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\CustomAttributeBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\MethodToken.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\ModuleBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\ModuleBuilderData.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\PEFileKinds.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\OpCodes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\Opcode.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\OpcodeType.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\StackBehaviour.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\OperandType.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\FlowControl.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\ParameterBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\ParameterToken.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\PropertyBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\PropertyToken.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\SignatureHelper.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\SignatureToken.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\StringToken.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\TypeBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\TypeBuilderInstantiation.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\GenericTypeParameterBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\EnumBuilder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\TypeToken.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Emit\XXXOnTypeBuilderInstantiation.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Reflection\Metadata\AssemblyExtensions.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\DateTimeFormat.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\DateTimeParse.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\DateTimeStyles.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\NumberStyles.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\TimeSpanFormat.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\TimeSpanParse.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\DaylightTime.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IIterable.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IIterator.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IVector.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\IMap.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\WindowsRuntime\CLRIKeyValuePairImpl.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\AggregateException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\AppContext\AppContext.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\AppContext\AppContextSwitches.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\AppContext\AppContextDefaultValues.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\AppContext\AppContextDefaultValues.CoreClrOverrides.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\AppContext\AppContextDefaultValues.Defaults.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\AppContext\AppContextDefaultValues.Defaults.Central.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\CurrentSystemTimeZone.Cache.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Object.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Array.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\ArraySegment.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\ThrowHelper.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Tuple.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\String.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\String.Comparison.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\String.Manipulation.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\String.Searching.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\StringBuilder.CoreCLR.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\StringBuilderCache.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Exception.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\DateTime.CoreCLR.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\OutOfMemoryException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Delegate.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\MulticastDelegate.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\__HResults.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\HResults.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\BCLDebug.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Activator.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\AccessViolationException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\AppDomain.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\AppDomainSetup.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\AppDomainManager.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IAppDomainPauseManager.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\AppDomainAttributes.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\AppDomainUnloadedException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\ArgumentOutOfRangeException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\ArgIterator.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Attribute.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\BadImageFormatException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\BitConverter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Boolean.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Buffer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Byte.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\CompatibilitySwitches.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Currency.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Decimal.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\DefaultBinder.CanConvert.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\DelegateSerializationHolder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Double.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Empty.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Enum.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\DllNotFoundException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Environment.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\GC.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Guid.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\InsufficientMemoryException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Int16.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Int32.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Int64.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IntPtr.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Internal.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Math.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\MathF.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\mda.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\MissingFieldException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\MissingMemberException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\NonSerializedAttribute.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Number.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\OperatingSystem.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\OperationCanceledException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\ParseNumbers.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\PlatformID.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\ResId.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\RtType.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\RuntimeArgumentHandle.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\RuntimeHandles.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\SByte.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\SerializableAttribute.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\SharedStatics.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Single.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\StubHelpers.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\TimeSpan.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\TimeZoneInfo.AdjustmentRule.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\TimeZoneInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\TimeZoneInfo.StringSerializer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\TimeZoneInfo.TransitionTime.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Type.CoreCLR.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\TypeNameParser.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\TypedReference.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\TypeLoadException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\UInt16.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\UInt32.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\UInt64.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\UIntPtr.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\ValueType.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\WeakReference.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\WeakReferenceOfT.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\CLRConfig.cs" />
+ <Compile Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\__ComObject.cs" />
+ <Compile Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\Variant.cs" />
+ <Compile Condition="'$(FeatureClassicCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\OleAutBinder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\ByReference.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Span.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\ReadOnlySpan.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\Internal\Runtime\Augments\EnvironmentAugments.cs" />
+ <Compile Include="$(BclSourcesRoot)\Internal\Runtime\Augments\RuntimeThread.cs" />
+ <Compile Include="$(BclSourcesRoot)\Internal\Console.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Assembly.CoreCLR.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\AssemblyName.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Associates.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\CustomAttributeExtensions.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\ConstructorInfo.CoreCLR.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\CustomAttribute.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\ExceptionHandlingClause.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\FieldInfo.CoreCLR.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\INVOCATION_FLAGS.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\LoaderAllocator.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\LocalVariableInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\MdConstant.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\MdFieldInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\MdImport.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\MemberInfo.Internal.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\MemberSerializationStringGenerator.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\MethodBase.CoreCLR.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\MethodBody.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\RtFieldInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\RuntimeAssembly.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\RuntimeConstructorInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\RuntimeEventInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\RuntimeFieldInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\RuntimeMethodInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\RuntimeModule.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\RuntimeParameterInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\RuntimePropertyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\AssemblyBuilder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\AssemblyBuilderData.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\AssemblyBuilderAccess.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\AQNBuilder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\ConstructorBuilder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\DynamicILGenerator.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\DynamicMethod.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\EventBuilder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\EventToken.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\FieldBuilder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\FieldToken.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\ILGenerator.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\ISymWrapperCore.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\Label.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\LocalBuilder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\MethodBuilder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\MethodBuilderInstantiation.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\SymbolType.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\SymbolMethod.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\CustomAttributeBuilder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\MethodToken.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\ModuleBuilder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\ModuleBuilderData.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\PEFileKinds.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\OpCodes.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\Opcode.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\OpcodeType.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\StackBehaviour.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\OperandType.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\FlowControl.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\ParameterBuilder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\ParameterToken.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\PropertyBuilder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\PropertyToken.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\SignatureHelper.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\SignatureToken.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\StringToken.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\TypeBuilder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\TypeBuilderInstantiation.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\GenericTypeParameterBuilder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\EnumBuilder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\TypeToken.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Emit\XXXOnTypeBuilderInstantiation.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Reflection\Metadata\AssemblyExtensions.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\BidiCategory.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\Calendar.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\CalendarData.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\CharUnicodeInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\CharUnicodeInfoData.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\CompareInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\CompareInfo.Invariant.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\CultureData.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\CultureInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\GlobalizationMode.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\GregorianCalendar.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\GregorianCalendarHelper.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\IdnMapping.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\NumberFormatInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\RegionInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\SortKey.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\StringInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\TextElementEnumerator.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\TextInfo.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\TimeSpanFormat.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\TimeSpanParse.cs" />
</ItemGroup>
<ItemGroup Condition="'$(FeatureCoreFxGlobalization)' != 'true'">
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\BidiCategory.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\Calendar.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\CalendarData.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\CalendarAlgorithmType.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\CalendarWeekRule.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\CalendricalCalculationsHelper.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\CharUnicodeInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\CompareInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\CultureInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\CultureNotFoundException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\CultureTypes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\DateTimeFormatInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\DateTimeFormatInfoScanner.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\DigitShapes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\EncodingDataItem.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\EncodingTable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\GlobalizationAssembly.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\GregorianCalendar.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\GregorianCalendarTypes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\GregorianCalendarHelper.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\HebrewCalendar.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\HijriCalendar.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\UmAlQuraCalendar.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\PersianCalendar.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\IdnMapping.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\JapaneseCalendar.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\KoreanCalendar.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\RegionInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\SortKey.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\SortVersion.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\StringInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\TaiwanCalendar.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\TextElementEnumerator.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\TextInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\ThaiBuddhistCalendar.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\TimeSpanStyles.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\NumberFormatInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\UnicodeCategory.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\CultureData.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\HebrewNumber.cs" />
- <MscorlibSources Condition="'$(FeatureOnlyCoreCalendars)'==''" Include="$(BclSourcesRoot)\System\Globalization\ChineseLunisolarCalendar.cs" />
- <MscorlibSources Condition="'$(FeatureOnlyCoreCalendars)'==''" Include="$(BclSourcesRoot)\System\Globalization\EastAsianLunisolarCalendar.cs" />
- <MscorlibSources Condition="'$(FeatureOnlyCoreCalendars)'==''" Include="$(BclSourcesRoot)\System\Globalization\JapaneseLunisolarCalendar.cs" />
- <MscorlibSources Condition="'$(FeatureOnlyCoreCalendars)'==''" Include="$(BclSourcesRoot)\System\Globalization\JulianCalendar.cs" />
- <MscorlibSources Condition="'$(FeatureOnlyCoreCalendars)'==''" Include="$(BclSourcesRoot)\System\Globalization\KoreanLunisolarCalendar.cs" />
- <MscorlibSources Condition="'$(FeatureOnlyCoreCalendars)'==''" Include="$(BclSourcesRoot)\System\Globalization\TaiwanLunisolarCalendar.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\EncodingDataItem.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\EncodingTable.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\GlobalizationAssembly.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Threading\SynchronizationContext.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\EventWaitHandle.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Interlocked.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Monitor.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Mutex.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Overlapped.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Semaphore.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Thread.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\ThreadInterruptedException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\ThreadPool.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Timer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Volatile.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\WaitHandle.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\SpinLock.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\SpinWait.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\LazyInitializer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\ThreadLocal.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\ReaderWriterLockSlim.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\SemaphoreSlim.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\ManualResetEventSlim.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\CancellationTokenRegistration.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\CancellationTokenSource.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\CancellationToken.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\future.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\FutureFactory.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\Task.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskContinuation.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskExceptionHolder.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskFactory.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskScheduler.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\ThreadPoolTaskScheduler.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskCompletionSource.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\AsyncCausalityTracer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\ConcurrentExclusiveSchedulerPair.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\ProducerConsumerQueues.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TPLETWProvider.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskToApm.cs" />
+ <Compile Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\Threading\Tasks\IAsyncCausalityTracerStatics.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Buffers\ArrayPoolEventSource.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\ClrThreadPoolBoundHandle.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\ClrThreadPoolBoundHandleOverlapped.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Threading\ClrThreadPoolPreAllocatedOverlapped.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\IO\__Error.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\__HResults.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\BinaryReader.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\BinaryWriter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\Directory.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\SearchOption.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\DriveNotFoundException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\EncodingCache.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\File.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\FileLoadException.CoreCLR.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\FileNotFoundException.CoreCLR.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\IOException.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\MemoryStream.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\PinnedBufferMemoryStream.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\Stream.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\UnmanagedMemoryAccessor.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\UnmanagedMemoryStream.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\UnmanagedMemoryStreamWrapper.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Security\DynamicSecurityMethodAttribute.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Assert.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\AssertFilter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\AssertFilters.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Debugger.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\DebuggerAttributes.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\ICustomDebuggerNotification.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\log.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\LoggingLevels.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\LogSwitch.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Stacktrace.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Stackframe.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\EditAndContinueHelper.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventSource_CoreCLR.cs" />
+ <Compile Condition="'$(FeatureXplatEventSource)' == 'true'" Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\XplatEventLogger.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\FrameworkEventSource.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Contracts\Contracts.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Contracts\ContractsBCL.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\SymbolStore\ISymDocumentWriter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\SymbolStore\ISymWriter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\SymbolStore\SymAddressKind.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\SymbolStore\Token.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\ExceptionServices\CorruptingExceptionCommon.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\ExceptionServices\ExceptionServicesCommon.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\ExceptionServices\ExceptionNotification.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\Loader\AssemblyLoadContext.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\Serialization\FormatterConverter.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\Serialization\FormatterServices.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\Serialization\SerializationInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\Remoting\ObjectHandle.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Text\DecoderNLS.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\DecoderBestFitFallback.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\DecoderExceptionFallback.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\DecoderFallback.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\DecoderReplacementFallback.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\EncoderNLS.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\EncoderBestFitFallback.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\EncoderExceptionFallback.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\EncoderFallback.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\EncoderReplacementFallback.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\Encoding.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\Latin1Encoding.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\UTF7Encoding.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\Microsoft\Win32\UnsafeNativeMethods.cs" />
+ <Compile Include="$(BclSourcesRoot)\Microsoft\Win32\Win32Native.cs" />
+ <Compile Condition="'$(FeatureWin32Registry)' == 'true'" Include="$(BclSourcesRoot)\Microsoft\Win32\Registry.cs" />
+ <Compile Condition="'$(FeatureWin32Registry)' == 'true'" Include="$(BclSourcesRoot)\Microsoft\Win32\RegistryKey.cs" />
+ <Compile Condition="'$(FeatureWin32Registry)' == 'true'" Include="$(BclSourcesRoot)\Microsoft\Win32\RegistryValueKind.cs" />
+ <Compile Condition="'$(FeatureClassicCominterop)' == 'true'" Include="$(BclSourcesRoot)\Microsoft\Win32\OAVariantLib.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Resources\__FastResourceComparer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Resources\__HResults.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Resources\FileBasedResourceGroveler.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Resources\IResourceGroveler.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Resources\LooselyLinkedResourceReference.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Resources\ManifestBasedResourceGroveler.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Resources\ResourceFallbackManager.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Resources\ResourceManager.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Resources\ResourceReader.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Resources\ResourceSet.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Resources\RuntimeResourceSet.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\System\Nullable.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\Generic\Comparer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\Generic\ComparerHelpers.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\Generic\Dictionary.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\Generic\EqualityComparer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\Generic\DebugView.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\Generic\List.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\Generic\ArraySortHelper.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\ObjectModel\Collection.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\ObjectModel\ReadOnlyCollection.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\ObjectModel\ReadOnlyDictionary.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\Concurrent\ConcurrentStack.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\Concurrent\IProducerConsumerCollection.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\Concurrent\ConcurrentDictionary.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Collections\Concurrent\ConcurrentQueue.cs" />
</ItemGroup>
<ItemGroup>
- <MscorlibSources Include="$(CoreFxSourcesRoot)\SR.cs" />
- </ItemGroup>
- <ItemGroup Condition="'$(FeatureCoreFxGlobalization)' == 'true'">
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\Calendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\CalendarAlgorithmType.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\CalendarData.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\CalendarWeekRule.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\CalendricalCalculationsHelper.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\CharUnicodeInfo.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\CharUnicodeInfoData.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\ChineseLunisolarCalendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\CompareInfo.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\CultureData.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\CultureInfo.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\CultureTypes.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\CultureNotFoundException.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\DateTimeFormatInfo.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\DateTimeFormatInfoScanner.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\EastAsianLunisolarCalendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\GregorianCalendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\GregorianCalendarHelper.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\GregorianCalendarTypes.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\HebrewCalendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\HebrewNumber.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\HijriCalendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\IdnMapping.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\InternalGlobalizationHelper.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\JapaneseCalendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\JapaneseLunisolarCalendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\JulianCalendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\KoreanCalendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\KoreanLunisolarCalendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\NumberFormatInfo.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\PersianCalendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\RegionInfo.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\SortKey.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\SortVersion.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\StringInfo.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\TaiwanCalendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\TaiwanLunisolarCalendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\TextElementEnumerator.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\TextInfo.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\ThaiBuddhistCalendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\TimeSpanStyles.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\UmAlQuraCalendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\UnicodeCategory.cs " />
- </ItemGroup>
- <ItemGroup Condition="'$(FeatureCoreFxGlobalization)' == 'true' and '$(TargetsUnix)' == 'true'">
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\EncodingTable.Unix.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Globalization\EncodingDataItem.Unix.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\Normalization.Unix.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Calendar.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Casing.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Collation.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Idna.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Locale.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Normalization.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.ResultCode.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.TimeZoneInfo.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Utils.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\CalendarData.Unix.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\CompareInfo.Unix.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\CultureData.Unix.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\CultureInfo.Unix.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\DigitShapes.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\HijriCalendar.Unix.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\IdnMapping.Unix.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\JapaneseCalendar.Unix.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\LocaleData.Unix.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Globalization\TextInfo.Unix.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\AbandonedMutexException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\AsyncLocal.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\AutoResetEvent.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\SendOrPostCallback.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\SynchronizationContext.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\EventResetMode.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\EventWaitHandle.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\ExecutionContext.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Interlocked.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\LockRecursionException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\ManualResetEvent.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Monitor.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Mutex.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Overlapped.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\ParameterizedThreadStart.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Semaphore.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\SemaphoreFullException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\SynchronizationLockException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Thread.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\ThreadAbortException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\ThreadInterruptedException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\ThreadPool.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\ThreadPriority.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\ThreadStart.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\ThreadState.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\ThreadStateException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\ThreadStaticAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\ThreadStartException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Timeout.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Timer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Volatile.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\WaitHandle.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\WaitHandleCannotBeOpenedException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\ApartmentState.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\SpinLock.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\SpinWait.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\CountdownEvent.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\LazyInitializer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\ThreadLocal.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\SemaphoreSlim.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\ManualResetEventSlim.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\CancellationTokenRegistration.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\CancellationTokenSource.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\CancellationToken.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\future.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\FutureFactory.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\Task.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskContinuation.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskCanceledException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskSchedulerException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskExceptionHolder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskFactory.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskScheduler.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\ThreadPoolTaskScheduler.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskCompletionSource.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\AsyncCausalityTracer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\ConcurrentExclusiveSchedulerPair.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\ProducerConsumerQueues.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\TPLETWProvider.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskToApm.cs" />
- <MscorlibSources Condition="'$(FeatureCominterop)' == 'true'" Include="$(BclSourcesRoot)\System\Threading\Tasks\IAsyncCausalityTracerStatics.cs" />
- </ItemGroup>
+ <Compile Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeFindHandle.cs" />
+ <Compile Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeLibraryHandle.cs" />
+ <Compile Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeWaitHandle.cs" />
+ <Compile Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\Win32SafeHandles.cs" />
+ <Compile Condition="'$(FeatureWin32Registry)' == 'true'" Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeRegistryHandle.cs" />
+ </ItemGroup>
<ItemGroup>
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\IO\FileStream.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\IO\Error.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Numerics\Hashing\HashHelpers.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsUnix)' == 'true'">
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Microsoft\Win32\SafeHandles\SafeFileHandle.Unix.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\IO\FileStream.Unix.cs" />
- </ItemGroup>
- <ItemGroup Condition="'$(TargetsUnix)' != 'true'">
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Microsoft\Win32\SafeHandles\SafeFileHandle.Windows.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\IO\FileStream.Win32.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\IO\FileStreamCompletionSource.Win32.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\IO\Win32Marshal.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\IO\Path.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\IO\PathInternal.cs" />
- </ItemGroup>
- <ItemGroup Condition="'$(TargetsUnix)' == 'true'">
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\IO\Path.Unix.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\IO\PathInternal.Unix.cs" />
- </ItemGroup>
- <ItemGroup Condition="'$(TargetsUnix)' != 'true'">
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\IO\Path.Win32.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\IO\Path.Windows.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\IO\PathHelper.Windows.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\IO\PathInternal.Windows.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\IO\PathInternal.Windows.StringBuffer.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Threading\DeferredDisposableLifetime.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Threading\ClrThreadPoolBoundHandle.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Threading\ClrThreadPoolBoundHandleOverlapped.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Threading\ClrThreadPoolPreAllocatedOverlapped.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\__Error.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\__HResults.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\BinaryReader.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\BinaryWriter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\Directory.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\SearchOption.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\DirectoryNotFoundException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\DriveNotFoundException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\EncodingCache.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\EndOfStreamException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\File.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\FileAccess.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\FileLoadException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\FileMode.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\FileNotFoundException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\FileOptions.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\FileShare.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\FileSystemEnumerable.cs" Condition="'$(TargetsUnix)' == 'true'" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\IOException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\MemoryStream.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\PathTooLongException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\PinnedBufferMemoryStream.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\SeekOrigin.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\Stream.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\StreamHelpers.CopyValidation.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\TextReader.cs" Condition="'$(TargetsUnix)' == 'true'" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\StreamReader.cs" Condition="'$(TargetsUnix)' == 'true'" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\UnmanagedMemoryAccessor.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\UnmanagedMemoryStream.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\IO\UnmanagedMemoryStreamWrapper.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Security\Attributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Security\SecurityException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Security\SecurityState.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Security\VerificationException.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Security\Util\URLString.cs" />
+ <Compile Include="$(BclSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Collation.cs" />
+ <Compile Include="$(BclSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.ICU.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Debug.Unix.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\CalendarData.Unix.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\CompareInfo.Unix.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\CultureData.Unix.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\CultureInfo.Unix.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\EncodingTable.Unix.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\EncodingDataItem.Unix.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\GlobalizationMode.Unix.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\HijriCalendar.Unix.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\IdnMapping.Unix.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\JapaneseCalendar.Unix.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\TextInfo.Unix.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\FileSystemEnumerable.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\TextReader.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\IO\StreamReader.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Runtime\Versioning\CompatibilitySwitch.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\Normalization.Unix.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\TimeZoneInfo.Unix.cs" />
+ </ItemGroup>
+ <ItemGroup Condition="'$(TargetsWindows)' == 'true'">
+ <Compile Include="$(BclSourcesRoot)\Interop\Windows\kernel32\Interop.Globalization.cs" />
+ <Compile Include="$(BclSourcesRoot)\Interop\Windows\Normaliz\Interop.Idna.cs" />
+ <Compile Include="$(BclSourcesRoot)\Interop\Windows\Normaliz\Interop.Normalization.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Debug.Windows.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\CalendarData.Windows.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\CompareInfo.Windows.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\CultureData.Windows.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\CultureInfo.Windows.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\GlobalizationMode.Windows.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\HijriCalendar.Win32.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\IdnMapping.Windows.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\JapaneseCalendar.Win32.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Globalization\TextInfo.Windows.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Text\Normalization.Windows.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\TimeZoneInfo.Win32.cs" />
</ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Assert.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\AssertFilter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\AssertFilters.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\ConditionalAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Debugger.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\DebuggerAttributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\ICustomDebuggerNotification.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\log.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\LoggingLevels.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\LogSwitch.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Stacktrace.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Stackframe.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\EditAndContinueHelper.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\ActivityTracker.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventActivityOptions.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventDescriptor.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventProvider.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventSource.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventSource_CoreCLR.cs" />
- <MscorlibSources Condition="'$(FeatureXplatEventSource)' == 'true'" Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\XplatEventLogger.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\EventSourceException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\FrameworkEventSource.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\StubEnvironment.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\Winmeta.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\ArrayTypeInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\ConcurrentSet.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\ConcurrentSetItem.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\DataCollector.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\EmptyStruct.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\EnumerableTypeInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\EnumHelper.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\EventDataAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\EventFieldAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\EventFieldFormat.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\EventIgnoreAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\EventPayload.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\EventSourceOptions.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\FieldMetadata.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\InvokeTypeInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\NameInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\PropertyValue.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\PropertyAnalysis.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\SimpleEventTypes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\SimpleTypeInfos.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\Statics.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TraceLoggingDataCollector.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TraceLoggingDataType.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TraceLoggingEventSource.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TraceLoggingEventTraits.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TraceLoggingEventTypes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TraceLoggingMetadataCollector.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TraceLoggingTypeInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Eventing\TraceLogging\TypeAnalysis.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\CodeAnalysis\SuppressMessageAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Contracts\Contracts.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\Contracts\ContractsBCL.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\SymbolStore\ISymDocumentWriter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\SymbolStore\ISymWriter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\SymbolStore\SymAddressKind.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Diagnostics\SymbolStore\Token.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\ExceptionServices\CorruptingExceptionCommon.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\ExceptionServices\ExceptionServicesCommon.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\ExceptionServices\ExceptionNotification.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Loader\AssemblyLoadContext.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\FormatterConverter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\FormatterServices.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\IDeserializationCallback.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\IFormatterConverter.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\IObjectReference.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\ISerializable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\SerializationAttributes.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\SerializationException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\SerializationInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\SerializationInfoEnumerator.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\StreamingContext.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Serialization\SafeSerializationManager.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Versioning\TargetFrameworkAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Versioning\CompatibilitySwitch.cs" Condition="'$(TargetsUnix)' == 'true'" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Versioning\NonVersionableAttribute.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Configuration\Assemblies\AssemblyHashAlgorithm.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Configuration\Assemblies\AssemblyVersionCompatibility.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Runtime\Remoting\ObjectHandle.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\ASCIIEncoding.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\Decoder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\DecoderNLS.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\DecoderBestFitFallback.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\DecoderExceptionFallback.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\DecoderFallback.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\DecoderReplacementFallback.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\Encoder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\EncoderNLS.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\EncoderBestFitFallback.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\EncoderExceptionFallback.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\EncoderFallback.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\EncoderReplacementFallback.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\Encoding.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\EncodingForwarder.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\EncodingInfo.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\EncodingNLS.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\EncodingProvider.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\Latin1Encoding.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\Normalization.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\Normalization.Windows.cs" Condition="'$(TargetsUnix)' != 'true'"/>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\UnicodeEncoding.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\UTF7Encoding.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\UTF8Encoding.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Text\UTF32Encoding.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\Microsoft\Win32\UnsafeNativeMethods.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\Microsoft\Win32\Win32Native.cs" />
- <MscorlibSources Condition="'$(FeatureWin32Registry)' == 'true'" Include="$(BclSourcesRoot)\Microsoft\Win32\Registry.cs" />
- <MscorlibSources Condition="'$(FeatureWin32Registry)' == 'true'" Include="$(BclSourcesRoot)\Microsoft\Win32\RegistryKey.cs" />
- <MscorlibSources Condition="'$(FeatureWin32Registry)' == 'true'" Include="$(BclSourcesRoot)\Microsoft\Win32\RegistryValueKind.cs" />
- <MscorlibSources Condition="'$(FeatureWin32Registry)' == 'true'" Include="$(BclSourcesRoot)\Microsoft\Win32\RegistryView.cs" />
- <MscorlibSources Condition="'$(FeatureClassicCominterop)' == 'true'" Include="$(BclSourcesRoot)\Microsoft\Win32\OAVariantLib.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\__FastResourceComparer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\__HResults.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\FileBasedResourceGroveler.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\IResourceGroveler.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\IResourceReader.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\LooselyLinkedResourceReference.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\ManifestBasedResourceGroveler.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\MissingManifestResourceException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\MissingSatelliteAssemblyException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\NeutralResourcesLanguageAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\ResourceFallbackManager.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\ResourceManager.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\ResourceReader.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\ResourceSet.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\ResourceTypeCode.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\RuntimeResourceSet.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\SatelliteContractVersionAttribute.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Resources\UltimateResourceFallbackLocation.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Nullable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\Comparer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\Dictionary.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\EqualityComparer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\DebugView.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\ICollection.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\IComparer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\IDictionary.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\IEnumerable.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\IEnumerator.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\IEqualityComparer.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\IList.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\IReadOnlyCollection.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\IReadOnlyList.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\IReadOnlyDictionary.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\KeyNotFoundException.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\KeyValuePair.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\List.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Generic\ArraySortHelper.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\ObjectModel\Collection.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\ObjectModel\ReadOnlyCollection.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\ObjectModel\ReadOnlyDictionary.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\ObjectModel\KeyedCollection.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Concurrent\ConcurrentStack.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Concurrent\IProducerConsumerCollection.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Concurrent\ConcurrentDictionary.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\System\Collections\Concurrent\ConcurrentQueue.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeFindHandle.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeLibraryHandle.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeWaitHandle.cs" />
- <MscorlibSources Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\Win32SafeHandles.cs" />
- <MscorlibSources Condition="'$(FeatureWin32Registry)' == 'true'" Include="$(BclSourcesRoot)\Microsoft\Win32\SafeHandles\SafeRegistryHandle.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(BclSourcesRoot)\System\Numerics\Hashing\HashHelpers.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Buffers\ArrayPool.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Buffers\ArrayPoolEventSource.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Buffers\ConfigurableArrayPool.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Buffers\TlsOverPerCoreLockedStacksArrayPool.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Buffers\Utilities.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Security\CryptographicException.cs" />
- </ItemGroup>
- <ItemGroup Condition="'$(TargetsUnix)' != 'true'">
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\HResults.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\Interop.BOOL.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\Interop.Errors.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\Interop.Libraries.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\BCrypt\Interop.BCryptGenRandom.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\BCrypt\Interop.NTSTATUS.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.CancelIoEx.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.CloseHandle.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.CreateFile.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.FileTypes.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.FileOperations.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.FlushFileBuffers.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.FormatMessage.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.GetFileInformationByHandleEx.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.GetFileType_SafeHandle.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.GetFullPathNameW.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.GetLongPathNameW.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.GetTempFileNameW.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.GetTempPathW.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.LockFile.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.ReadFile_SafeHandle_IntPtr.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.ReadFile_SafeHandle_NativeOverlapped.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.SafeCreateFile.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.SECURITY_ATTRIBUTES.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.SecurityOptions.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.SetEndOfFile.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.SetErrorMode.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.SetFileInformationByHandle.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.SetFilePointerEx.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.UnsafeCreateFile.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.WriteFile_SafeHandle_IntPtr.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.WriteFile_SafeHandle_NativeOverlapped.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Security\SecureString.cs" />
- </ItemGroup>
- <ItemGroup Condition="'$(TargetsUnix)' != 'true'">
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Security\SafeBSTRHandle.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Security\SecureString.Windows.cs" />
- <!-- Interop sources -->
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\Crypt32\Interop.CryptProtectMemory.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\NtDll\Interop.ZeroMemory.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.WideCharToMultiByte.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\oleaut32\Interop.SysAllocStringLen.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Windows\oleaut32\Interop.SysStringLen.cs" />
- </ItemGroup>
- <ItemGroup Condition="'$(TargetsUnix)' == 'true'">
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\Security\SecureString.Unix.cs" />
- </ItemGroup>
- <ItemGroup Condition="'$(TargetsUnix)' == 'true'">
- <MscorlibSources Include="$(CoreFxSourcesRoot)\System\HResults.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\Interop.Errors.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\Interop.IOErrors.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\Interop.Libraries.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Close.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.GetCwd.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.GetUnixName.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Fcntl.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.FLock.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.FSync.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.FTruncate.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.LSeek.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.MksTemps.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Open.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.OpenFlags.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.PathConf.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Permissions.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.PosixFAdvise.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Read.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Stat.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Unlink.cs" />
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Interop\Unix\System.Native\Interop.Write.cs" />
- </ItemGroup>
- <ItemGroup>
- <MscorlibSources Include="$(CoreFxSourcesRoot)\Debug.cs" />
- </ItemGroup>
-
<!-- Include additional sources shared files in the compilation -->
<ItemGroup>
<!-- These are files are preprocessed -->
- <MscorlibSources Include="$(CommonPath)\Preprocessed\AssemblyRefs.g.cs" />
-
+ <Compile Include="$(CommonPath)\Preprocessed\AssemblyRefs.g.cs" />
<!-- These files are shared with other framework components and don't live the same folder as the rest of them-->
- <MscorlibSources Include="$(CommonPath)\PinnableBufferCache.cs" />
-
+ <Compile Include="$(CommonPath)\NotImplemented.cs" />
+ <Compile Include="$(CommonPath)\PinnableBufferCache.cs" />
+ <Compile Include="$(CommonPath)\System\SR.cs" />
<!-- Include Internals visible to file in the compilation -->
- <MscorlibSources Include="$(BclSourcesRoot)\mscorlib.Friends.cs" />
-
+ <Compile Include="$(BclSourcesRoot)\mscorlib.Friends.cs" />
<!-- TODO list of types to be cleaned up from CoreLib -->
- <MscorlibSources Include="$(BclSourcesRoot)\CleanupToDoList.cs" />
- </ItemGroup>
-
- <ItemGroup>
- <!-- We want the sources to show up nicely in VS-->
- <Compile Include="@(MscorlibSources)">
- </Compile>
- <Compile Include="src\System\Runtime\CompilerServices\ITuple.cs" />
- <Compile Include="src\System\Runtime\CompilerServices\TupleElementNamesAttribute.cs" />
- <Compile Include="src\System\TupleExtensions.cs" />
- <Compile Include="src\System\ValueTuple.cs" />
+ <Compile Include="$(BclSourcesRoot)\CleanupToDoList.cs" />
</ItemGroup>
-
- <!-- Resources -->
<ItemGroup>
- <SplitTextStringResource Include="$(BclSourcesRoot)\System.Private.CoreLib.txt">
- <ResFile>System.Private.CoreLib</ResFile>
- <ResGenDefines>$(DefineConstants)</ResGenDefines>
- </SplitTextStringResource>
+ <Compile Include="src\System\Runtime\RuntimeImports.cs" />
</ItemGroup>
-
+ <Import Project="shared\System.Private.CoreLib.Shared.projitems" Label="Shared" />
<PropertyGroup>
<CheckCDefines Condition="'$(CheckCDefines)'==''">true</CheckCDefines>
</PropertyGroup>
-
<Target Name="CDefineChecker" BeforeTargets="Build" Condition="'$(CheckCDefines)'=='true'">
<!-- Compiler Definition Verification -->
<Message Importance="High" Text="============" />
@@ -1258,46 +733,28 @@
<IgnoreDefineConstants>FEATURE_IMPLICIT_TLS;FEATURE_HIJACK</IgnoreDefineConstants>
<CMakeDefinitionSaveFile>$(IntermediateOutputPath)\cmake.definitions</CMakeDefinitionSaveFile>
</PropertyGroup>
- <Exec Command='python $(MSBuildThisFileDirectory)..\scripts\check-definitions.py "$(CMakeDefinitionSaveFile)" "$(DefineConstants)" "$(IgnoreDefineConstants)" ' />
+ <Exec Command="python $(MSBuildThisFileDirectory)..\scripts\check-definitions.py &quot;$(CMakeDefinitionSaveFile)&quot; &quot;$(DefineConstants)&quot; &quot;$(IgnoreDefineConstants)&quot; " />
<Message Importance="High" Text="============" />
</Target>
-
- <ItemGroup>
- <EmbeddedResource Include="$(NlpObjDir)\charinfo.nlp">
- <LogicalName>charinfo.nlp</LogicalName>
- </EmbeddedResource>
- </ItemGroup>
-
<PropertyGroup Condition="'$(BuildOS)' == 'Windows_NT'">
<EnableDotnetAnalyzers Condition="'$(EnableDotnetAnalyzers)'==''">true</EnableDotnetAnalyzers>
<UseWin32Apis>true</UseWin32Apis>
<OSGroup>Windows_NT</OSGroup>
</PropertyGroup>
- <Import Project="$(ToolsDir)\codeAnalysis.targets" />
-
- <Import Project="$(ToolsDir)\Microsoft.CSharp.Targets" />
-
<PropertyGroup>
<StrongNameSig>Silverlight</StrongNameSig>
</PropertyGroup>
-
- <!-- Import signing tools -->
- <Import Condition="Exists('$(ToolsDir)\sign.targets')" Project="$(ToolsDir)\sign.targets" />
-
- <!-- Overwrite the key that we are going to use for signing -->
+ <Import Project="$(MSBuildThisFileDirectory)Tools\Versioning\GenerateVersionInfo.targets" />
+ <!--
+ Import common targets: codeAnalysis, Microsoft.CSharp, sign, versioning, codeOptimizations, etc.
+ In doing so, override versioning targets.
+ -->
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup>
+ <!-- Overwrite the key that we are going to use for signing -->
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)Tools\Signing\mscorlib.snk</AssemblyOriginatorKeyFile>
- </PropertyGroup>
-
- <Import Project="$(MSBuildThisFileDirectory)Tools\Versioning\GenerateVersionInfo.targets"/>
- <!-- Override versioning targets -->
- <Import Condition="Exists('$(ToolsDir)versioning.targets')" Project="$(ToolsDir)versioning.targets" />
-
- <PropertyGroup>
<!-- Use a different nativeresource file to avoid conflicts with mscorlib-->
<Win32Resource Condition="'$(GenerateNativeVersionInfo)'=='true'">$(IntermediateOutputPath)\System.Private.CoreLib.res</Win32Resource>
</PropertyGroup>
-
- <Import Project="GenerateSplitStringResources.targets"/>
- <Import Project="GenerateCompilerResponseFile.targets"/>
-</Project>
+ <Import Project="GenerateCompilerResponseFile.targets" />
+</Project> \ No newline at end of file
diff --git a/src/mscorlib/System.Private.CoreLib.sln b/src/mscorlib/System.Private.CoreLib.sln
index 4ab28af2d9..d5cdd02cf3 100644
--- a/src/mscorlib/System.Private.CoreLib.sln
+++ b/src/mscorlib/System.Private.CoreLib.sln
@@ -1,11 +1,17 @@

Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25420.1
+# Visual Studio 15
+VisualStudioVersion = 15.0.26208.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Private.CoreLib", "System.Private.CoreLib.csproj", "{3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}"
EndProject
+Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "System.Private.CoreLib.Shared", "shared\System.Private.CoreLib.Shared.shproj", "{C5ED3C1D-B572-46F1-8F96-522A85CE1179}"
+EndProject
Global
+ GlobalSection(SharedMSBuildProjectFiles) = preSolution
+ shared\System.Private.CoreLib.Shared.projitems*{3da06c3a-2e7b-4cb7-80ed-9b12916013f9}*SharedItemsImports = 4
+ shared\System.Private.CoreLib.Shared.projitems*{c5ed3c1d-b572-46f1-8f96-522a85ce1179}*SharedItemsImports = 13
+ EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Checked|amd64 = Checked|amd64
Checked|arm = Checked|arm
@@ -21,14 +27,14 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|amd64.ActiveCfg = Checked|amd64
- {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|amd64.Build.0 = Checked|amd64
- {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|arm.ActiveCfg = Checked|arm
- {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|arm.Build.0 = Checked|arm
- {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|arm64.ActiveCfg = Checked|arm64
- {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|arm64.Build.0 = Checked|arm64
- {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|x86.ActiveCfg = Checked|x86
- {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|x86.Build.0 = Checked|x86
+ {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|amd64.ActiveCfg = Release|amd64
+ {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|amd64.Build.0 = Release|amd64
+ {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|arm.ActiveCfg = Release|arm
+ {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|arm.Build.0 = Release|arm
+ {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|arm64.ActiveCfg = Release|arm64
+ {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|arm64.Build.0 = Release|arm64
+ {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|x86.ActiveCfg = Release|x86
+ {3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Checked|x86.Build.0 = Release|x86
{3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Debug|amd64.ActiveCfg = Debug|amd64
{3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Debug|amd64.Build.0 = Debug|amd64
{3DA06C3A-2E7B-4CB7-80ED-9B12916013F9}.Debug|arm.ActiveCfg = Debug|arm
diff --git a/src/mscorlib/corefx/Debug.cs b/src/mscorlib/corefx/Debug.cs
deleted file mode 100644
index 3398c0e31e..0000000000
--- a/src/mscorlib/corefx/Debug.cs
+++ /dev/null
@@ -1,29 +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.Diagnostics;
-
-namespace System
-{
- internal static class Debug
- {
- [Conditional("_DEBUG")]
- static public void Assert(bool condition)
- {
- BCLDebug.Assert(condition);
- }
-
- [Conditional("_DEBUG")]
- static public void Assert(bool condition, string message)
- {
- BCLDebug.Assert(condition, message);
- }
-
- [Conditional("_DEBUG")]
- static public void Fail(string message)
- {
- BCLDebug.Assert(false, message);
- }
- }
-} \ No newline at end of file
diff --git a/src/mscorlib/corefx/Interop/Unix/Interop.Libraries.cs b/src/mscorlib/corefx/Interop/Unix/Interop.Libraries.cs
deleted file mode 100644
index 1b6d26e40f..0000000000
--- a/src/mscorlib/corefx/Interop/Unix/Interop.Libraries.cs
+++ /dev/null
@@ -1,12 +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 static partial class Interop
-{
- private static partial class Libraries
- {
- internal const string GlobalizationInterop = "System.Globalization.Native"; // CoreFX wrappers for ICU
- internal const string SystemNative = "System.Native";
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs b/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs
deleted file mode 100644
index 25585c6dfb..0000000000
--- a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Collation.cs
+++ /dev/null
@@ -1,69 +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.Globalization;
-using System.Runtime.InteropServices;
-using System.Security;
-
-internal static partial class Interop
-{
- internal static partial class GlobalizationInterop
- {
- [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetSortHandle")]
- internal unsafe static extern ResultCode GetSortHandle(byte[] localeName, out SafeSortHandle sortHandle);
-
- [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_CloseSortHandle")]
- internal unsafe static extern void CloseSortHandle(IntPtr handle);
-
- [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_CompareString")]
- internal unsafe static extern int CompareString(SafeSortHandle sortHandle, char* lpStr1, int cwStr1Len, char* lpStr2, int cwStr2Len, CompareOptions options);
-
- [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_IndexOf")]
- internal unsafe static extern int IndexOf(SafeSortHandle sortHandle, string target, int cwTargetLength, char* pSource, int cwSourceLength, CompareOptions options);
-
- [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_LastIndexOf")]
- internal unsafe static extern int LastIndexOf(SafeSortHandle sortHandle, string target, int cwTargetLength, char* pSource, int cwSourceLength, CompareOptions options);
-
- [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_IndexOfOrdinalIgnoreCase")]
- internal unsafe static extern int IndexOfOrdinalIgnoreCase(string target, int cwTargetLength, char* pSource, int cwSourceLength, bool findLast);
-
- [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_StartsWith")]
- [return: MarshalAs(UnmanagedType.Bool)]
- internal unsafe static extern bool StartsWith(SafeSortHandle sortHandle, string target, int cwTargetLength, string source, int cwSourceLength, CompareOptions options);
-
- [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_EndsWith")]
- [return: MarshalAs(UnmanagedType.Bool)]
- internal unsafe static extern bool EndsWith(SafeSortHandle sortHandle, string target, int cwTargetLength, string source, int cwSourceLength, CompareOptions options);
-
- [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetSortKey")]
- internal unsafe static extern int GetSortKey(SafeSortHandle sortHandle, string str, int strLength, byte* sortKey, int sortKeyLength, CompareOptions options);
-
- [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_CompareStringOrdinalIgnoreCase")]
- internal unsafe static extern int CompareStringOrdinalIgnoreCase(char* lpStr1, int cwStr1Len, char* lpStr2, int cwStr2Len);
-
- [DllImport(Libraries.GlobalizationInterop, EntryPoint = "GlobalizationNative_GetSortVersion")]
- internal static extern int GetSortVersion();
-
- internal class SafeSortHandle : SafeHandle
- {
- private SafeSortHandle() :
- base(IntPtr.Zero, true)
- {
- }
-
- public override bool IsInvalid
- {
- get { return handle == IntPtr.Zero; }
- }
-
- protected override bool ReleaseHandle()
- {
- CloseSortHandle(handle);
- SetHandle(IntPtr.Zero);
- return true;
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.GetCwd.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.GetCwd.cs
deleted file mode 100644
index 724e342342..0000000000
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.GetCwd.cs
+++ /dev/null
@@ -1,74 +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.InteropServices;
-
-internal static partial class Interop
-{
- internal static partial class Sys
- {
- [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetCwd", SetLastError = true)]
- private static unsafe extern byte* GetCwd(byte* buffer, int bufferLength);
-
- internal static unsafe string GetCwd()
- {
- const int StackLimit = 256;
-
- // First try to get the path into a buffer on the stack
- byte* stackBuf = stackalloc byte[StackLimit];
- string result = GetCwdHelper(stackBuf, StackLimit);
- if (result != null)
- {
- return result;
- }
-
- // If that was too small, try increasing large buffer sizes
- // until we get one that works or until we hit MaxPath.
- int maxPath = Interop.Sys.MaxPath;
- if (StackLimit < maxPath)
- {
- int bufferSize = StackLimit;
- do
- {
- checked { bufferSize *= 2; }
- var buf = new byte[Math.Min(bufferSize, maxPath)];
- fixed (byte* ptr = buf)
- {
- result = GetCwdHelper(ptr, buf.Length);
- if (result != null)
- {
- return result;
- }
- }
- }
- while (bufferSize < maxPath);
- }
-
- // If we couldn't get the cwd with a MaxPath-sized buffer, something's wrong.
- throw Interop.GetExceptionForIoErrno(new ErrorInfo(Interop.Error.ENAMETOOLONG));
- }
-
- private static unsafe string GetCwdHelper(byte* ptr, int bufferSize)
- {
- // Call the real getcwd
- byte* result = GetCwd(ptr, bufferSize);
-
- // If it returned non-null, the null-terminated path is in the buffer
- if (result != null)
- {
- return Marshal.PtrToStringAnsi((IntPtr)ptr);
- }
-
- // Otherwise, if it failed due to the buffer being too small, return null;
- // for anything else, throw.
- ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo();
- if (errorInfo.Error == Interop.Error.ERANGE)
- {
- return null;
- }
- throw Interop.GetExceptionForIoErrno(errorInfo);
- }
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.GetUnixName.cs b/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.GetUnixName.cs
deleted file mode 100644
index 33664c4d39..0000000000
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.GetUnixName.cs
+++ /dev/null
@@ -1,21 +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.InteropServices;
-
-internal static partial class Interop
-{
- internal static partial class Sys
- {
- [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetUnixName")]
- private static extern IntPtr GetUnixNamePrivate();
-
- internal static string GetUnixName()
- {
- IntPtr ptr = GetUnixNamePrivate();
- return Marshal.PtrToStringAnsi(ptr);
- }
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/BCrypt/Interop.BCryptGenRandom.cs b/src/mscorlib/corefx/Interop/Windows/BCrypt/Interop.BCryptGenRandom.cs
deleted file mode 100644
index d2ce4131b0..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/BCrypt/Interop.BCryptGenRandom.cs
+++ /dev/null
@@ -1,26 +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.Diagnostics;
-using System.Runtime.InteropServices;
-
-internal partial class Interop
-{
- internal partial class BCrypt
- {
- internal static unsafe NTSTATUS BCryptGenRandom(byte* pbBuffer, int count)
- {
- Debug.Assert(pbBuffer != null);
- Debug.Assert(count >= 0);
-
- return BCryptGenRandom(IntPtr.Zero, pbBuffer, count, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
- }
-
- private const int BCRYPT_USE_SYSTEM_PREFERRED_RNG = 0x00000002;
-
- [DllImport(Libraries.BCrypt, CharSet = CharSet.Unicode)]
- private static unsafe extern NTSTATUS BCryptGenRandom(IntPtr hAlgorithm, byte* pbBuffer, int cbBuffer, int dwFlags);
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/BCrypt/Interop.NTSTATUS.cs b/src/mscorlib/corefx/Interop/Windows/BCrypt/Interop.NTSTATUS.cs
deleted file mode 100644
index 49d674f399..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/BCrypt/Interop.NTSTATUS.cs
+++ /dev/null
@@ -1,19 +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;
-
-internal partial class Interop
-{
- internal partial class BCrypt
- {
- internal enum NTSTATUS : uint
- {
- STATUS_SUCCESS = 0x0,
- STATUS_NOT_FOUND = 0xc0000225,
- STATUS_INVALID_PARAMETER = 0xc000000d,
- STATUS_NO_MEMORY = 0xc0000017,
- }
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/Interop.Errors.cs b/src/mscorlib/corefx/Interop/Windows/Interop.Errors.cs
deleted file mode 100644
index 7eeb18de01..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/Interop.Errors.cs
+++ /dev/null
@@ -1,71 +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 Errors
- {
- internal const int ERROR_SUCCESS = 0x0;
- internal const int ERROR_INVALID_FUNCTION = 0x1;
- internal const int ERROR_FILE_NOT_FOUND = 0x2;
- internal const int ERROR_PATH_NOT_FOUND = 0x3;
- internal const int ERROR_ACCESS_DENIED = 0x5;
- internal const int ERROR_INVALID_HANDLE = 0x6;
- internal const int ERROR_NOT_ENOUGH_MEMORY = 0x8;
- internal const int ERROR_INVALID_DATA = 0xD;
- internal const int ERROR_INVALID_DRIVE = 0xF;
- internal const int ERROR_NO_MORE_FILES = 0x12;
- internal const int ERROR_NOT_READY = 0x15;
- internal const int ERROR_BAD_LENGTH = 0x18;
- internal const int ERROR_SHARING_VIOLATION = 0x20;
- internal const int ERROR_LOCK_VIOLATION = 0x21;
- internal const int ERROR_HANDLE_EOF = 0x26;
- internal const int ERROR_FILE_EXISTS = 0x50;
- internal const int ERROR_INVALID_PARAMETER = 0x57;
- internal const int ERROR_BROKEN_PIPE = 0x6D;
- internal const int ERROR_INSUFFICIENT_BUFFER = 0x7A;
- internal const int ERROR_INVALID_NAME = 0x7B;
- internal const int ERROR_NEGATIVE_SEEK = 0x83;
- internal const int ERROR_DIR_NOT_EMPTY = 0x91;
- internal const int ERROR_BAD_PATHNAME = 0xA1;
- internal const int ERROR_LOCK_FAILED = 0xA7;
- internal const int ERROR_BUSY = 0xAA;
- internal const int ERROR_ALREADY_EXISTS = 0xB7;
- internal const int ERROR_BAD_EXE_FORMAT = 0xC1;
- internal const int ERROR_ENVVAR_NOT_FOUND = 0xCB;
- internal const int ERROR_FILENAME_EXCED_RANGE = 0xCE;
- internal const int ERROR_EXE_MACHINE_TYPE_MISMATCH = 0xD8;
- internal const int ERROR_PIPE_BUSY = 0xE7;
- internal const int ERROR_NO_DATA = 0xE8;
- internal const int ERROR_PIPE_NOT_CONNECTED = 0xE9;
- internal const int ERROR_MORE_DATA = 0xEA;
- internal const int ERROR_NO_MORE_ITEMS = 0x103;
- internal const int ERROR_PARTIAL_COPY = 0x12B;
- internal const int ERROR_ARITHMETIC_OVERFLOW = 0x216;
- internal const int ERROR_PIPE_CONNECTED = 0x217;
- internal const int ERROR_PIPE_LISTENING = 0x218;
- internal const int ERROR_OPERATION_ABORTED = 0x3E3;
- internal const int ERROR_IO_PENDING = 0x3E5;
- internal const int ERROR_NO_TOKEN = 0x3f0;
- internal const int ERROR_DLL_INIT_FAILED = 0x45A;
- internal const int ERROR_NOT_FOUND = 0x490;
- internal const int ERROR_NON_ACCOUNT_SID = 0x4E9;
- internal const int ERROR_NOT_ALL_ASSIGNED = 0x514;
- internal const int ERROR_UNKNOWN_REVISION = 0x519;
- internal const int ERROR_INVALID_OWNER = 0x51B;
- internal const int ERROR_INVALID_PRIMARY_GROUP = 0x51C;
- internal const int ERROR_NO_SUCH_PRIVILEGE = 0x521;
- internal const int ERROR_PRIVILEGE_NOT_HELD = 0x522;
- internal const int ERROR_INVALID_ACL = 0x538;
- internal const int ERROR_INVALID_SECURITY_DESCR = 0x53A;
- internal const int ERROR_INVALID_SID = 0x539;
- internal const int ERROR_BAD_IMPERSONATION_LEVEL = 0x542;
- internal const int ERROR_CANT_OPEN_ANONYMOUS = 0x543;
- internal const int ERROR_NO_SECURITY_ON_OBJECT = 0x546;
- internal const int ERROR_TRUSTED_RELATIONSHIP_FAILURE = 0x6FD;
- internal const int ERROR_RESOURCE_LANG_NOT_FOUND = 0x717;
- internal const int EFail = unchecked((int)0x80004005);
- internal const int E_FILENOTFOUND = unchecked((int)0x80070002);
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/Interop.Libraries.cs b/src/mscorlib/corefx/Interop/Windows/Interop.Libraries.cs
deleted file mode 100644
index f19f9dcf52..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/Interop.Libraries.cs
+++ /dev/null
@@ -1,15 +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 static partial class Interop
-{
- internal static class Libraries
- {
- internal const string BCrypt = "BCrypt.dll";
- internal const string Crypt32 = "crypt32.dll";
- internal const string Kernel32 = "kernel32.dll";
- internal const string NtDll = "ntdll.dll";
- internal const string OleAut32 = "oleaut32.dll";
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/NtDll/Interop.ZeroMemory.cs b/src/mscorlib/corefx/Interop/Windows/NtDll/Interop.ZeroMemory.cs
deleted file mode 100644
index bd2a64cf14..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/NtDll/Interop.ZeroMemory.cs
+++ /dev/null
@@ -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.
-
-using System;
-using System.Runtime.InteropServices;
-using System.Security;
-
-internal partial class Interop
-{
- internal partial class NtDll
- {
-
- [DllImport(Libraries.NtDll, CharSet = CharSet.Unicode, EntryPoint = "RtlZeroMemory")]
- internal static extern void ZeroMemory(IntPtr address, UIntPtr length);
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.CreateFile.cs b/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.CreateFile.cs
deleted file mode 100644
index 5f6f6115ab..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.CreateFile.cs
+++ /dev/null
@@ -1,40 +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 Microsoft.Win32.SafeHandles;
-using System;
-using System.IO;
-using System.Runtime.InteropServices;
-
-internal partial class Interop
-{
- internal partial class Kernel32
- {
- /// <summary>
- /// WARNING: This method does not implicitly handle long paths. Use CreateFile.
- /// </summary>
- [DllImport(Libraries.Kernel32, EntryPoint = "CreateFileW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
- private static extern SafeFileHandle CreateFilePrivate(
- string lpFileName,
- int dwDesiredAccess,
- System.IO.FileShare dwShareMode,
- [In] ref SECURITY_ATTRIBUTES securityAttrs,
- System.IO.FileMode dwCreationDisposition,
- int dwFlagsAndAttributes,
- IntPtr hTemplateFile);
-
- internal static SafeFileHandle CreateFile(
- string lpFileName,
- int dwDesiredAccess,
- System.IO.FileShare dwShareMode,
- [In] ref SECURITY_ATTRIBUTES securityAttrs,
- System.IO.FileMode dwCreationDisposition,
- int dwFlagsAndAttributes,
- IntPtr hTemplateFile)
- {
- lpFileName = PathInternal.EnsureExtendedPrefixOverMaxPath(lpFileName);
- return CreateFilePrivate(lpFileName, dwDesiredAccess, dwShareMode, ref securityAttrs, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
- }
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FileOperations.cs b/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FileOperations.cs
deleted file mode 100644
index 6e3ebb9ae9..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FileOperations.cs
+++ /dev/null
@@ -1,12 +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 Kernel32
- {
-
- internal const uint SEM_FAILCRITICALERRORS = 1;
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetFileInformationByHandleEx.cs b/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetFileInformationByHandleEx.cs
deleted file mode 100644
index 146c4638ee..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetFileInformationByHandleEx.cs
+++ /dev/null
@@ -1,26 +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 Microsoft.Win32.SafeHandles;
-using System;
-using System.Runtime.InteropServices;
-
-internal partial class Interop
-{
- internal partial class Kernel32
- {
- [DllImport(Libraries.Kernel32, SetLastError = true)]
- internal static extern bool GetFileInformationByHandleEx(SafeFileHandle hFile, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, out FILE_STANDARD_INFO lpFileInformation, uint dwBufferSize);
-
- internal partial struct FILE_STANDARD_INFO
- {
- internal long AllocationSize;
- internal long EndOfFile;
- internal uint NumberOfLinks;
- internal BOOL DeletePending;
- internal BOOL Directory;
- }
-
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetLongPathNameW.cs b/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetLongPathNameW.cs
deleted file mode 100644
index a58d1013ca..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetLongPathNameW.cs
+++ /dev/null
@@ -1,18 +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.InteropServices;
-
-partial class Interop
-{
- partial class Kernel32
- {
- /// <summary>
- /// WARNING: This method does not implicitly handle long paths. Use GetFullPath/PathHelper.
- /// </summary>
- [DllImport(Libraries.Kernel32, SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)]
- internal static extern uint GetLongPathNameW(char[] lpszShortPath, char[] lpszLongPath, uint cchBuffer);
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetTempFileNameW.cs b/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetTempFileNameW.cs
deleted file mode 100644
index d157a29c92..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetTempFileNameW.cs
+++ /dev/null
@@ -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.Text;
-using System.Runtime.InteropServices;
-
-partial class Interop
-{
- partial class Kernel32
- {
- [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false)]
- internal static extern uint GetTempFileNameW(string tmpPath, string prefix, uint uniqueIdOrZero, [Out]StringBuilder tmpFileName);
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetTempPathW.cs b/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetTempPathW.cs
deleted file mode 100644
index 25ffcd55b0..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetTempPathW.cs
+++ /dev/null
@@ -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.IO;
-using System.Text;
-using System.Runtime.InteropServices;
-
-partial class Interop
-{
- partial class Kernel32
- {
- [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, BestFitMapping = false)]
- internal static extern uint GetTempPathW(int bufferLen, [Out]StringBuilder buffer);
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SafeCreateFile.cs b/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SafeCreateFile.cs
deleted file mode 100644
index 4192f569e0..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SafeCreateFile.cs
+++ /dev/null
@@ -1,45 +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.IO;
-using System.Runtime.InteropServices;
-using Microsoft.Win32.SafeHandles;
-
-internal partial class Interop
-{
- internal partial class Kernel32
- {
- internal static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); // WinBase.h
-
- /// <summary>
- /// Does not allow access to non-file devices. This disallows DOS devices like "con:", "com1:",
- /// "lpt1:", etc. Use this to avoid security problems, like allowing a web client asking a server
- /// for "http://server/com1.aspx" and then causing a worker process to hang.
- /// </summary>
- internal static SafeFileHandle SafeCreateFile(
- String lpFileName,
- int dwDesiredAccess,
- System.IO.FileShare dwShareMode,
- ref Interop.Kernel32.SECURITY_ATTRIBUTES securityAttrs,
- FileMode dwCreationDisposition,
- int dwFlagsAndAttributes,
- IntPtr hTemplateFile)
- {
- SafeFileHandle handle = UnsafeCreateFile(lpFileName, dwDesiredAccess, dwShareMode, ref securityAttrs, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
-
- if (!handle.IsInvalid)
- {
- int fileType = Interop.Kernel32.GetFileType(handle);
- if (fileType != Interop.Kernel32.FileTypes.FILE_TYPE_DISK)
- {
- handle.Dispose();
- throw new NotSupportedException(SR.NotSupported_FileStreamOnNonFiles);
- }
- }
-
- return handle;
- }
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetErrorMode.cs b/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetErrorMode.cs
deleted file mode 100644
index caa2ce5bfa..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetErrorMode.cs
+++ /dev/null
@@ -1,14 +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.Runtime.InteropServices;
-
-internal partial class Interop
-{
- internal partial class Kernel32
- {
- [DllImport(Libraries.Kernel32, SetLastError = false, EntryPoint = "SetErrorMode", ExactSpelling = true)]
- internal static extern uint SetErrorMode(uint newMode);
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.UnsafeCreateFile.cs b/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.UnsafeCreateFile.cs
deleted file mode 100644
index 9a5cd2834d..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.UnsafeCreateFile.cs
+++ /dev/null
@@ -1,25 +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.IO;
-using Microsoft.Win32.SafeHandles;
-
-internal partial class Interop
-{
- internal partial class Kernel32
- {
- internal static SafeFileHandle UnsafeCreateFile(
- string lpFileName,
- int dwDesiredAccess,
- FileShare dwShareMode,
- ref Interop.Kernel32.SECURITY_ATTRIBUTES securityAttrs,
- FileMode dwCreationDisposition,
- int dwFlagsAndAttributes,
- IntPtr hTemplateFile)
- {
- return CreateFile(lpFileName, dwDesiredAccess, dwShareMode, ref securityAttrs, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
- }
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.WideCharToMultiByte.cs b/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.WideCharToMultiByte.cs
deleted file mode 100644
index 07271cae33..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.WideCharToMultiByte.cs
+++ /dev/null
@@ -1,22 +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.InteropServices;
-
-internal partial class Interop
-{
- internal partial class Kernel32
- {
- [DllImport(Libraries.Kernel32)]
- internal static extern unsafe int WideCharToMultiByte(
- uint CodePage, uint dwFlags,
- char* lpWideCharStr, int cchWideChar,
- byte* lpMultiByteStr, int cbMultiByte,
- IntPtr lpDefaultChar, IntPtr lpUsedDefaultChar);
-
- internal const uint CP_ACP = 0;
- internal const uint WC_NO_BEST_FIT_CHARS = 0x00000400;
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.WriteFile_SafeHandle_IntPtr.cs b/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.WriteFile_SafeHandle_IntPtr.cs
deleted file mode 100644
index e7e868e142..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.WriteFile_SafeHandle_IntPtr.cs
+++ /dev/null
@@ -1,24 +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 Microsoft.Win32.SafeHandles;
-using System;
-using System.Runtime.InteropServices;
-
-internal partial class Interop
-{
- internal partial class Kernel32
- {
- // Note there are two different WriteFile prototypes - this is to use
- // the type system to force you to not trip across a "feature" in
- // Win32's async IO support. You can't do the following three things
- // simultaneously: overlapped IO, free the memory for the overlapped
- // struct in a callback (or an EndWrite method called by that callback),
- // and pass in an address for the numBytesRead parameter.
-
- [DllImport(Libraries.Kernel32, SetLastError = true)]
- internal static extern unsafe int WriteFile(SafeHandle handle, byte* bytes, int numBytesToWrite, out int numBytesWritten, IntPtr mustBeZero);
-
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/oleaut32/Interop.SysAllocStringLen.cs b/src/mscorlib/corefx/Interop/Windows/oleaut32/Interop.SysAllocStringLen.cs
deleted file mode 100644
index 65da4eaaea..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/oleaut32/Interop.SysAllocStringLen.cs
+++ /dev/null
@@ -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.InteropServices;
-using System.Security;
-
-internal partial class Interop
-{
- internal partial class OleAut32
- {
- [DllImport(Libraries.OleAut32, CharSet = CharSet.Unicode)]
- internal static extern SafeBSTRHandle SysAllocStringLen(IntPtr src, uint len); // BSTR
- }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/oleaut32/Interop.SysStringLen.cs b/src/mscorlib/corefx/Interop/Windows/oleaut32/Interop.SysStringLen.cs
deleted file mode 100644
index 027d8eece9..0000000000
--- a/src/mscorlib/corefx/Interop/Windows/oleaut32/Interop.SysStringLen.cs
+++ /dev/null
@@ -1,22 +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.InteropServices;
-using System.Security;
-
-internal partial class Interop
-{
- internal partial class OleAut32
- {
- [DllImport(Libraries.OleAut32)]
- internal static extern uint SysStringLen(SafeBSTRHandle bstr);
-
- [DllImport(Libraries.OleAut32)]
- internal static extern uint SysStringLen(IntPtr bstr);
-
- [DllImport(Libraries.OleAut32)]
- internal static extern void SysFreeString(IntPtr bstr);
- }
-}
diff --git a/src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeThreadPoolIOHandle.cs b/src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeThreadPoolIOHandle.cs
deleted file mode 100644
index 3dbc2bb620..0000000000
--- a/src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeThreadPoolIOHandle.cs
+++ /dev/null
@@ -1,28 +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.InteropServices;
-
-namespace Microsoft.Win32.SafeHandles
-{
- internal class SafeThreadPoolIOHandle : SafeHandle
- {
- private SafeThreadPoolIOHandle()
- : base(IntPtr.Zero, true)
- {
- }
-
- public override bool IsInvalid
- {
- get { return handle == IntPtr.Zero; }
- }
-
- protected override bool ReleaseHandle()
- {
- Interop.mincore.CloseThreadpoolIo(handle);
- return true;
- }
- }
-}
diff --git a/src/mscorlib/corefx/SR.cs b/src/mscorlib/corefx/SR.cs
deleted file mode 100644
index 012bb86a66..0000000000
--- a/src/mscorlib/corefx/SR.cs
+++ /dev/null
@@ -1,818 +0,0 @@
-using System;
-using System.Globalization;
-
-// CoreFX creates SR in the System namespace. While putting the CoreCLR SR adapter in the root
-// may be unconventional, it allows us to keep the shared code identical.
-
-internal static class SR
-{
- public static string Arg_ArrayZeroError
- {
- get { return Environment.GetResourceString("Arg_ArrayZeroError"); }
- }
-
- public static string Arg_ExternalException
- {
- get { return Environment.GetResourceString("Arg_ExternalException"); }
- }
-
- public static string Arg_HexStyleNotSupported
- {
- get { return Environment.GetResourceString("Arg_HexStyleNotSupported"); }
- }
-
- public static string Arg_InvalidHexStyle
- {
- get { return Environment.GetResourceString("Arg_InvalidHexStyle"); }
- }
-
- public static string ArgumentNull_Array
- {
- get { return Environment.GetResourceString("ArgumentNull_Array"); }
- }
-
- public static string ArgumentNull_ArrayValue
- {
- get { return Environment.GetResourceString("ArgumentNull_ArrayValue"); }
- }
-
- public static string ArgumentNull_Obj
- {
- get { return Environment.GetResourceString("ArgumentNull_Obj"); }
- }
-
- public static string ArgumentNull_String
- {
- get { return Environment.GetResourceString("ArgumentNull_String"); }
- }
-
- public static string ArgumentOutOfRange_AddValue
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_AddValue"); }
- }
-
- public static string ArgumentOutOfRange_BadHourMinuteSecond
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_BadHourMinuteSecond"); }
- }
-
- public static string ArgumentOutOfRange_BadYearMonthDay
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"); }
- }
-
- public static string ArgumentOutOfRange_Bounds_Lower_Upper
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper"); }
- }
-
- public static string ArgumentOutOfRange_CalendarRange
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_CalendarRange"); }
- }
-
- public static string ArgumentOutOfRange_Count
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_Count"); }
- }
-
- public static string ArgumentOutOfRange_Day
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_Day"); }
- }
-
- public static string ArgumentOutOfRange_Enum
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_Enum"); }
- }
-
- public static string ArgumentOutOfRange_Era
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_Era"); }
- }
-
- public static string ArgumentOutOfRange_Index
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_Index"); }
- }
-
- public static string ArgumentOutOfRange_IndexCountBuffer
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"); }
- }
-
- public static string ArgumentOutOfRange_InvalidEraValue
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"); }
- }
-
- public static string ArgumentOutOfRange_Month
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_Month"); }
- }
-
- public static string ArgumentOutOfRange_NeedNonNegNum
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"); }
- }
-
- public static string ArgumentOutOfRange_NeedPosNum
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"); }
- }
-
- public static string Arg_ArgumentOutOfRangeException
- {
- get { return Environment.GetResourceString("Arg_ArgumentOutOfRangeException"); }
- }
-
- public static string ArgumentOutOfRange_OffsetLength
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"); }
- }
-
- public static string ArgumentOutOfRange_Range
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_Range"); }
- }
-
- public static string Argument_CompareOptionOrdinal
- {
- get { return Environment.GetResourceString("Argument_CompareOptionOrdinal"); }
- }
-
- public static string Argument_ConflictingDateTimeRoundtripStyles
- {
- get { return Environment.GetResourceString("Argument_ConflictingDateTimeRoundtripStyles"); }
- }
-
- public static string Argument_ConflictingDateTimeStyles
- {
- get { return Environment.GetResourceString("Argument_ConflictingDateTimeStyles"); }
- }
-
- public static string Argument_CultureIetfNotSupported
- {
- get { return Environment.GetResourceString("Argument_CultureIetfNotSupported"); }
- }
-
- public static string Argument_CultureInvalidIdentifier
- {
- get { return Environment.GetResourceString("Argument_CultureInvalidIdentifier"); }
- }
-
- public static string Argument_CultureNotSupported
- {
- get { return Environment.GetResourceString("Argument_CultureNotSupported"); }
- }
-
- public static string Argument_CultureIsNeutral
- {
- get { return Environment.GetResourceString("Argument_CultureIsNeutral"); }
- }
-
- public static string Argument_CustomCultureCannotBePassedByNumber
- {
- get { return Environment.GetResourceString("Argument_CustomCultureCannotBePassedByNumber"); }
- }
-
- public static string Argument_EmptyDecString
- {
- get { return Environment.GetResourceString("Argument_EmptyDecString"); }
- }
-
- public static string Argument_IdnBadLabelSize
- {
- get { return Environment.GetResourceString("Argument_IdnBadLabelSize"); }
- }
-
- public static string Argument_IdnBadPunycode
- {
- get { return Environment.GetResourceString("Argument_IdnBadPunycode"); }
- }
-
- public static string Argument_IdnIllegalName
- {
- get { return Environment.GetResourceString("Argument_IdnIllegalName"); }
- }
-
- public static string Argument_InvalidArrayLength
- {
- get { return Environment.GetResourceString("Argument_InvalidArrayLength"); }
- }
-
- public static string Argument_InvalidCalendar
- {
- get { return Environment.GetResourceString("Argument_InvalidCalendar"); }
- }
-
- public static string Argument_InvalidCharSequence
- {
- get { return Environment.GetResourceString("Argument_InvalidCharSequence"); }
- }
-
- public static string Argument_InvalidCultureName
- {
- get { return Environment.GetResourceString("Argument_InvalidCultureName"); }
- }
-
- public static string Argument_InvalidDateTimeStyles
- {
- get { return Environment.GetResourceString("Argument_InvalidDateTimeStyles"); }
- }
-
- public static string Argument_InvalidDigitSubstitution
- {
- get { return Environment.GetResourceString("Argument_InvalidDigitSubstitution"); }
- }
-
- public static string Argument_InvalidFlag
- {
- get { return Environment.GetResourceString("Argument_InvalidFlag"); }
- }
-
- public static string Argument_InvalidGroupSize
- {
- get { return Environment.GetResourceString("Argument_InvalidGroupSize"); }
- }
-
- public static string Argument_InvalidNativeDigitCount
- {
- get { return Environment.GetResourceString("Argument_InvalidNativeDigitCount"); }
- }
-
- public static string Argument_InvalidNativeDigitValue
- {
- get { return Environment.GetResourceString("Argument_InvalidNativeDigitValue"); }
- }
-
- public static string Argument_InvalidNeutralRegionName
- {
- get { return Environment.GetResourceString("Argument_InvalidNeutralRegionName"); }
- }
-
- public static string Argument_InvalidNumberStyles
- {
- get { return Environment.GetResourceString("Argument_InvalidNumberStyles"); }
- }
-
- public static string Argument_InvalidResourceCultureName
- {
- get { return Environment.GetResourceString("Argument_InvalidResourceCultureName"); }
- }
-
- public static string Argument_NoEra
- {
- get { return Environment.GetResourceString("Argument_NoEra"); }
- }
-
- public static string Argument_NoRegionInvariantCulture
- {
- get { return Environment.GetResourceString("Argument_NoRegionInvariantCulture"); }
- }
-
- public static string Argument_OneOfCulturesNotSupported
- {
- get { return Environment.GetResourceString("Argument_OneOfCulturesNotSupported"); }
- }
-
- public static string Argument_OnlyMscorlib
- {
- get { return Environment.GetResourceString("Argument_OnlyMscorlib"); }
- }
-
- public static string Argument_ResultCalendarRange
- {
- get { return Environment.GetResourceString("Argument_ResultCalendarRange"); }
- }
-
- public static string Format_BadFormatSpecifier
- {
- get { return Environment.GetResourceString("Format_BadFormatSpecifier"); }
- }
-
- public static string InvalidOperation_DateTimeParsing
- {
- get { return Environment.GetResourceString("InvalidOperation_DateTimeParsing"); }
- }
-
- public static string InvalidOperation_EnumEnded
- {
- get { return Environment.GetResourceString("InvalidOperation_EnumEnded"); }
- }
-
- public static string InvalidOperation_EnumNotStarted
- {
- get { return Environment.GetResourceString("InvalidOperation_EnumNotStarted"); }
- }
-
- public static string InvalidOperation_ReadOnly
- {
- get { return Environment.GetResourceString("InvalidOperation_ReadOnly"); }
- }
-
- public static string Overflow_TimeSpanTooLong
- {
- get { return Environment.GetResourceString("Overflow_TimeSpanTooLong"); }
- }
-
- public static string Serialization_MemberOutOfRange
- {
- get { return Environment.GetResourceString("Serialization_MemberOutOfRange"); }
- }
-
- public static string Arg_InvalidHandle
- {
- get { return Environment.GetResourceString("Arg_InvalidHandle"); }
- }
-
- public static string ObjectDisposed_FileClosed
- {
- get { return Environment.GetResourceString("ObjectDisposed_FileClosed"); }
- }
-
- public static string Arg_HandleNotAsync
- {
- get { return Environment.GetResourceString("Arg_HandleNotAsync"); }
- }
-
- public static string ArgumentNull_Path
- {
- get { return Environment.GetResourceString("ArgumentNull_Path"); }
- }
-
- public static string Argument_EmptyPath
- {
- get { return Environment.GetResourceString("Argument_EmptyPath"); }
- }
-
- public static string Argument_InvalidFileModeAndAccessCombo
- {
- get { return Environment.GetResourceString("Argument_InvalidFileMode&AccessCombo"); }
- }
-
- public static string Argument_InvalidAppendMode
- {
- get { return Environment.GetResourceString("Argument_InvalidAppendMode"); }
- }
-
- public static string ArgumentNull_Buffer
- {
- get { return Environment.GetResourceString("ArgumentNull_Buffer"); }
- }
-
- public static string Argument_InvalidOffLen
- {
- get { return Environment.GetResourceString("Argument_InvalidOffLen"); }
- }
-
- public static string IO_UnknownFileName
- {
- get { return Environment.GetResourceString("IO_UnknownFileName"); }
- }
-
- public static string IO_FileStreamHandlePosition
- {
- get { return Environment.GetResourceString("IO.IO_FileStreamHandlePosition"); }
- }
-
- public static string NotSupported_FileStreamOnNonFiles
- {
- get { return Environment.GetResourceString("NotSupported_FileStreamOnNonFiles"); }
- }
-
- public static string IO_BindHandleFailed
- {
- get { return Environment.GetResourceString("IO.IO_BindHandleFailed"); }
- }
-
- public static string Arg_HandleNotSync
- {
- get { return Environment.GetResourceString("Arg_HandleNotSync"); }
- }
-
- public static string IO_SetLengthAppendTruncate
- {
- get { return Environment.GetResourceString("IO.IO_SetLengthAppendTruncate"); }
- }
-
- public static string ArgumentOutOfRange_FileLengthTooBig
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_FileLengthTooBig"); }
- }
-
- public static string Argument_InvalidSeekOrigin
- {
- get { return Environment.GetResourceString("Argument_InvalidSeekOrigin"); }
- }
-
- public static string IO_SeekAppendOverwrite
- {
- get { return Environment.GetResourceString("IO.IO_SeekAppendOverwrite"); }
- }
-
- public static string IO_FileTooLongOrHandleNotSync
- {
- get { return Environment.GetResourceString("IO_FileTooLongOrHandleNotSync"); }
- }
-
- public static string IndexOutOfRange_IORaceCondition
- {
- get { return Environment.GetResourceString("IndexOutOfRange_IORaceCondition"); }
- }
-
- public static string IO_FileNotFound
- {
- get { return Environment.GetResourceString("IO.FileNotFound"); }
- }
-
- public static string IO_FileNotFound_FileName
- {
- get { return Environment.GetResourceString("IO.FileNotFound_FileName"); }
- }
-
- public static string IO_PathNotFound_NoPathName
- {
- get { return Environment.GetResourceString("IO.PathNotFound_NoPathName"); }
- }
-
- public static string IO_PathNotFound_Path
- {
- get { return Environment.GetResourceString("IO.PathNotFound_Path"); }
- }
-
- public static string UnauthorizedAccess_IODenied_NoPathName
- {
- get { return Environment.GetResourceString("UnauthorizedAccess_IODenied_NoPathName"); }
- }
-
- public static string UnauthorizedAccess_IODenied_Path
- {
- get { return Environment.GetResourceString("UnauthorizedAccess_IODenied_Path"); }
- }
-
- public static string IO_AlreadyExists_Name
- {
- get { return Environment.GetResourceString("IO.IO_AlreadyExists_Name"); }
- }
-
- public static string IO_PathTooLong
- {
- get { return Environment.GetResourceString("IO.PathTooLong"); }
- }
-
- public static string IO_SharingViolation_NoFileName
- {
- get { return Environment.GetResourceString("IO.IO_SharingViolation_NoFileName"); }
- }
-
- public static string IO_SharingViolation_File
- {
- get { return Environment.GetResourceString("IO.IO_SharingViolation_File"); }
- }
-
- public static string IO_FileExists_Name
- {
- get { return Environment.GetResourceString("IO.IO_FileExists_Name"); }
- }
-
- public static string NotSupported_UnwritableStream
- {
- get { return Environment.GetResourceString("NotSupported_UnwritableStream"); }
- }
-
- public static string NotSupported_UnreadableStream
- {
- get { return Environment.GetResourceString("NotSupported_UnreadableStream"); }
- }
-
- public static string NotSupported_UnseekableStream
- {
- get { return Environment.GetResourceString("NotSupported_UnseekableStream"); }
- }
-
- public static string IO_EOF_ReadBeyondEOF
- {
- get { return Environment.GetResourceString("IO.EOF_ReadBeyondEOF"); }
- }
-
- public static string Argument_InvalidHandle
- {
- get { return Environment.GetResourceString("Argument_InvalidHandle"); }
- }
-
- public static string Argument_AlreadyBoundOrSyncHandle
- {
- get { return Environment.GetResourceString("Argument_AlreadyBoundOrSyncHandle"); }
- }
-
- public static string Argument_PreAllocatedAlreadyAllocated
- {
- get { return Environment.GetResourceString("Argument_PreAllocatedAlreadyAllocated"); }
- }
-
- public static string Argument_NativeOverlappedAlreadyFree
- {
- get { return Environment.GetResourceString("Argument_NativeOverlappedAlreadyFree"); }
- }
-
- public static string Argument_NativeOverlappedWrongBoundHandle
- {
- get { return Environment.GetResourceString("Argument_NativeOverlappedWrongBoundHandle"); }
- }
-
- public static string InvalidOperation_NativeOverlappedReused
- {
- get { return Environment.GetResourceString("InvalidOperation_NativeOverlappedReused"); }
- }
-
- public static string ArgumentOutOfRange_Length
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_Length"); }
- }
-
- public static string ArgumentOutOfRange_IndexString
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_IndexString"); }
- }
-
- public static string ArgumentOutOfRange_Capacity
- {
- get { return Environment.GetResourceString("ArgumentOutOfRange_Capacity"); }
- }
-
- public static string Arg_CryptographyException
- {
- get { return Environment.GetResourceString("Arg_CryptographyException"); }
- }
-
- public static string ArgumentException_BufferNotFromPool
- {
- get { return Environment.GetResourceString("ArgumentException_BufferNotFromPool"); }
- }
-
- public static string Argument_InvalidPathChars
- {
- get { return Environment.GetResourceString("Argument_InvalidPathChars"); }
- }
-
- public static string Argument_PathFormatNotSupported
- {
- get { return Environment.GetResourceString("Argument_PathFormatNotSupported"); }
- }
-
- public static string Arg_PathIllegal
- {
- get { return Environment.GetResourceString("Arg_PathIllegal"); }
- }
-
- public static string Arg_PathIllegalUNC
- {
- get { return Environment.GetResourceString("Arg_PathIllegalUNC"); }
- }
-
- public static string Arg_InvalidSearchPattern
- {
- get { return Environment.GetResourceString("Arg_InvalidSearchPattern"); }
- }
-
- public static string InvalidOperation_Cryptography
- {
- get { return Environment.GetResourceString("InvalidOperation_Cryptography"); }
- }
-
- public static string Format(string formatString, params object[] args)
- {
- return string.Format(CultureInfo.CurrentCulture, formatString, args);
- }
-
- internal static string ArgumentException_ValueTupleIncorrectType
- {
- get { return Environment.GetResourceString("ArgumentException_ValueTupleIncorrectType"); }
- }
-
- internal static string ArgumentException_ValueTupleLastArgumentNotATuple
- {
- get { return Environment.GetResourceString("ArgumentException_ValueTupleLastArgumentNotATuple"); }
- }
-
- internal static string SpinLock_TryEnter_ArgumentOutOfRange
- {
- get { return Environment.GetResourceString("SpinLock_TryEnter_ArgumentOutOfRange"); }
- }
-
- internal static string SpinLock_TryReliableEnter_ArgumentException
- {
- get { return Environment.GetResourceString("SpinLock_TryReliableEnter_ArgumentException"); }
- }
-
- internal static string SpinLock_TryEnter_LockRecursionException
- {
- get { return Environment.GetResourceString("SpinLock_TryEnter_LockRecursionException"); }
- }
-
- internal static string SpinLock_Exit_SynchronizationLockException
- {
- get { return Environment.GetResourceString("SpinLock_Exit_SynchronizationLockException"); }
- }
-
- internal static string SpinLock_IsHeldByCurrentThread
- {
- get { return Environment.GetResourceString("SpinLock_IsHeldByCurrentThread"); }
- }
-
- internal static string ObjectDisposed_StreamIsClosed
- {
- get { return Environment.GetResourceString("ObjectDisposed_StreamIsClosed"); }
- }
-
- internal static string Arg_SystemException
- {
- get { return Environment.GetResourceString("Arg_SystemException"); }
- }
-
- internal static string Arg_StackOverflowException
- {
- get { return Environment.GetResourceString("Arg_StackOverflowException"); }
- }
-
- internal static string Arg_DataMisalignedException
- {
- get { return Environment.GetResourceString("Arg_DataMisalignedException"); }
- }
-
- internal static string Arg_ExecutionEngineException
- {
- get { return Environment.GetResourceString("Arg_ExecutionEngineException"); }
- }
-
- internal static string Arg_AccessException
- {
- get { return Environment.GetResourceString("Arg_AccessException"); }
- }
-
- internal static string Arg_AccessViolationException
- {
- get { return Environment.GetResourceString("Arg_AccessViolationException"); }
- }
-
- internal static string Arg_ApplicationException
- {
- get { return Environment.GetResourceString("Arg_ApplicationException"); }
- }
-
- internal static string Arg_ArgumentException
- {
- get { return Environment.GetResourceString("Arg_ArgumentException"); }
- }
-
- internal static string Arg_ParamName_Name
- {
- get { return Environment.GetResourceString("Arg_ParamName_Name"); }
- }
-
- internal static string ArgumentNull_Generic
- {
- get { return Environment.GetResourceString("ArgumentNull_Generic"); }
- }
-
- internal static string Arg_ArithmeticException
- {
- get { return Environment.GetResourceString("Arg_ArithmeticException"); }
- }
-
- internal static string Arg_ArrayTypeMismatchException
- {
- get { return Environment.GetResourceString("Arg_ArrayTypeMismatchException"); }
- }
-
- internal static string Arg_DivideByZero
- {
- get { return Environment.GetResourceString("Arg_DivideByZero"); }
- }
-
- internal static string Arg_DuplicateWaitObjectException
- {
- get { return Environment.GetResourceString("Arg_DuplicateWaitObjectException"); }
- }
-
- internal static string Arg_EntryPointNotFoundException
- {
- get { return Environment.GetResourceString("Arg_EntryPointNotFoundException"); }
- }
-
- internal static string Arg_FieldAccessException
- {
- get { return Environment.GetResourceString("Arg_FieldAccessException"); }
- }
-
- internal static string Arg_FormatException
- {
- get { return Environment.GetResourceString("Arg_FormatException"); }
- }
-
- internal static string Arg_IndexOutOfRangeException
- {
- get { return Environment.GetResourceString("Arg_IndexOutOfRangeException"); }
- }
-
- internal static string Arg_InsufficientExecutionStackException
- {
- get { return Environment.GetResourceString("Arg_InsufficientExecutionStackException"); }
- }
-
- internal static string Arg_InvalidCastException
- {
- get { return Environment.GetResourceString("Arg_InvalidCastException"); }
- }
-
- internal static string Arg_InvalidOperationException
- {
- get { return Environment.GetResourceString("Arg_InvalidOperationException"); }
- }
-
- internal static string InvalidProgram_Default
- {
- get { return Environment.GetResourceString("InvalidProgram_Default"); }
- }
-
- internal static string Arg_MethodAccessException
- {
- get { return Environment.GetResourceString("Arg_MethodAccessException"); }
- }
-
- internal static string Arg_MulticastNotSupportedException
- {
- get { return Environment.GetResourceString("Arg_MulticastNotSupportedException"); }
- }
-
- internal static string Arg_NotFiniteNumberException
- {
- get { return Environment.GetResourceString("Arg_NotFiniteNumberException"); }
- }
-
- internal static string Arg_NotImplementedException
- {
- get { return Environment.GetResourceString("Arg_NotImplementedException"); }
- }
-
- internal static string Arg_NotSupportedException
- {
- get { return Environment.GetResourceString("Arg_NotSupportedException"); }
- }
-
- internal static string Arg_NullReferenceException
- {
- get { return Environment.GetResourceString("Arg_NullReferenceException"); }
- }
-
- internal static string ObjectDisposed_Generic
- {
- get { return Environment.GetResourceString("ObjectDisposed_Generic"); }
- }
-
- internal static string ObjectDisposed_ObjectName_Name
- {
- get { return Environment.GetResourceString("ObjectDisposed_ObjectName_Name"); }
- }
-
- internal static string Arg_OverflowException
- {
- get { return Environment.GetResourceString("Arg_OverflowException"); }
- }
-
- internal static string Arg_PlatformNotSupported
- {
- get { return Environment.GetResourceString("Arg_PlatformNotSupported"); }
- }
-
- internal static string Arg_RankException
- {
- get { return Environment.GetResourceString("Arg_RankException"); }
- }
-
- internal static string Arg_TimeoutException
- {
- get { return Environment.GetResourceString("Arg_TimeoutException"); }
- }
-
- internal static string Arg_TypeAccessException
- {
- get { return Environment.GetResourceString("Arg_TypeAccessException"); }
- }
-
- internal static string TypeInitialization_Default
- {
- get { return Environment.GetResourceString("TypeInitialization_Default"); }
- }
-
- internal static string TypeInitialization_Type
- {
- get { return Environment.GetResourceString("TypeInitialization_Type"); }
- }
-
- internal static string Arg_UnauthorizedAccessException
- {
- get { return Environment.GetResourceString("Arg_UnauthorizedAccessException"); }
- }
-}
diff --git a/src/mscorlib/corefx/System/Buffers/Utilities.cs b/src/mscorlib/corefx/System/Buffers/Utilities.cs
deleted file mode 100644
index 823299f5fc..0000000000
--- a/src/mscorlib/corefx/System/Buffers/Utilities.cs
+++ /dev/null
@@ -1,35 +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.Diagnostics;
-using System.Runtime.CompilerServices;
-
-namespace System.Buffers
-{
- internal static class Utilities
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static int SelectBucketIndex(int bufferSize)
- {
- uint bitsRemaining = ((uint)bufferSize - 1) >> 4;
-
- int poolIndex = 0;
- if (bitsRemaining > 0xFFFF) { bitsRemaining >>= 16; poolIndex = 16; }
- if (bitsRemaining > 0xFF) { bitsRemaining >>= 8; poolIndex += 8; }
- if (bitsRemaining > 0xF) { bitsRemaining >>= 4; poolIndex += 4; }
- if (bitsRemaining > 0x3) { bitsRemaining >>= 2; poolIndex += 2; }
- if (bitsRemaining > 0x1) { bitsRemaining >>= 1; poolIndex += 1; }
-
- return poolIndex + (int)bitsRemaining;
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static int GetMaxSizeForBucket(int binIndex)
- {
- int maxSize = 16 << binIndex;
- Debug.Assert(maxSize >= 0);
- return maxSize;
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/Calendar.cs b/src/mscorlib/corefx/System/Globalization/Calendar.cs
deleted file mode 100644
index 0ff5040c74..0000000000
--- a/src/mscorlib/corefx/System/Globalization/Calendar.cs
+++ /dev/null
@@ -1,859 +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.Diagnostics;
-using System.Diagnostics.Contracts;
-using System.Runtime.Serialization;
-
-namespace System.Globalization
-{
- // This abstract class represents a calendar. A calendar reckons time in
- // divisions such as weeks, months and years. The number, length and start of
- // the divisions vary in each calendar.
- //
- // Any instant in time can be represented as an n-tuple of numeric values using
- // a particular calendar. For example, the next vernal equinox occurs at (0.0, 0
- // , 46, 8, 20, 3, 1999) in the Gregorian calendar. An implementation of
- // Calendar can map any DateTime value to such an n-tuple and vice versa. The
- // DateTimeFormat class can map between such n-tuples and a textual
- // representation such as "8:46 AM March 20th 1999 AD".
- //
- // Most calendars identify a year which begins the current era. There may be any
- // number of previous eras. The Calendar class identifies the eras as enumerated
- // integers where the current era (CurrentEra) has the value zero.
- //
- // For consistency, the first unit in each interval, e.g. the first month, is
- // assigned the value one.
- // The calculation of hour/minute/second is moved to Calendar from GregorianCalendar,
- // since most of the calendars (or all?) have the same way of calcuating hour/minute/second.
-
- [Serializable]
- public abstract partial class Calendar : ICloneable
- {
- // Number of 100ns (10E-7 second) ticks per time unit
- internal const long TicksPerMillisecond = 10000;
- internal const long TicksPerSecond = TicksPerMillisecond * 1000;
- internal const long TicksPerMinute = TicksPerSecond * 60;
- internal const long TicksPerHour = TicksPerMinute * 60;
- internal const long TicksPerDay = TicksPerHour * 24;
-
- // Number of milliseconds per time unit
- internal const int MillisPerSecond = 1000;
- internal const int MillisPerMinute = MillisPerSecond * 60;
- internal const int MillisPerHour = MillisPerMinute * 60;
- internal const int MillisPerDay = MillisPerHour * 24;
-
- // Number of days in a non-leap year
- internal const int DaysPerYear = 365;
- // Number of days in 4 years
- internal const int DaysPer4Years = DaysPerYear * 4 + 1;
- // Number of days in 100 years
- internal const int DaysPer100Years = DaysPer4Years * 25 - 1;
- // Number of days in 400 years
- internal const int DaysPer400Years = DaysPer100Years * 4 + 1;
-
- // Number of days from 1/1/0001 to 1/1/10000
- internal const int DaysTo10000 = DaysPer400Years * 25 - 366;
-
- internal const long MaxMillis = (long)DaysTo10000 * MillisPerDay;
-
-
- private int _currentEraValue = -1;
-
- [OptionalField(VersionAdded = 2)]
- private bool _isReadOnly = false;
-
-#if INSIDE_CLR
- internal const CalendarId CAL_HEBREW = CalendarId.HEBREW;
- internal const CalendarId CAL_HIJRI = CalendarId.HIJRI;
- internal const CalendarId CAL_JAPAN = CalendarId.JAPAN;
- internal const CalendarId CAL_JULIAN = CalendarId.JULIAN;
- internal const CalendarId CAL_TAIWAN = CalendarId.TAIWAN;
- internal const CalendarId CAL_UMALQURA = CalendarId.UMALQURA;
- internal const CalendarId CAL_PERSIAN = CalendarId.PERSIAN;
-#endif
-
- // The minimum supported DateTime range for the calendar.
-
- public virtual DateTime MinSupportedDateTime
- {
- get
- {
- return (DateTime.MinValue);
- }
- }
-
- // The maximum supported DateTime range for the calendar.
-
- public virtual DateTime MaxSupportedDateTime
- {
- get
- {
- return (DateTime.MaxValue);
- }
- }
-
- public virtual CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.Unknown;
- }
- }
-
- protected Calendar()
- {
- //Do-nothing constructor.
- }
-
- ///
- // This can not be abstract, otherwise no one can create a subclass of Calendar.
- //
- internal virtual CalendarId ID
- {
- get
- {
- return CalendarId.UNINITIALIZED_VALUE;
- }
- }
-
- ///
- // Return the Base calendar ID for calendars that didn't have defined data in calendarData
- //
-
- internal virtual CalendarId BaseCalendarID
- {
- get { return ID; }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // IsReadOnly
- //
- // Detect if the object is readonly.
- //
- ////////////////////////////////////////////////////////////////////////
- public bool IsReadOnly
- {
- get { return (_isReadOnly); }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Clone
- //
- // Is the implementation of ICloneable.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual object Clone()
- {
- object o = MemberwiseClone();
- ((Calendar)o).SetReadOnlyState(false);
- return (o);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ReadOnly
- //
- // Create a cloned readonly instance or return the input one if it is
- // readonly.
- //
- ////////////////////////////////////////////////////////////////////////
- public static Calendar ReadOnly(Calendar calendar)
- {
- if (calendar == null) { throw new ArgumentNullException(nameof(calendar)); }
- Contract.EndContractBlock();
- if (calendar.IsReadOnly) { return (calendar); }
-
- Calendar clonedCalendar = (Calendar)(calendar.MemberwiseClone());
- clonedCalendar.SetReadOnlyState(true);
-
- return (clonedCalendar);
- }
-
- internal void VerifyWritable()
- {
- if (_isReadOnly)
- {
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- }
- }
-
- internal void SetReadOnlyState(bool readOnly)
- {
- _isReadOnly = readOnly;
- }
-
-
- /*=================================CurrentEraValue==========================
- **Action: This is used to convert CurretEra(0) to an appropriate era value.
- **Returns:
- **Arguments:
- **Exceptions:
- **Notes:
- ** The value is from calendar.nlp.
- ============================================================================*/
-
- internal virtual int CurrentEraValue
- {
- get
- {
- // The following code assumes that the current era value can not be -1.
- if (_currentEraValue == -1)
- {
- Debug.Assert(BaseCalendarID != CalendarId.UNINITIALIZED_VALUE, "[Calendar.CurrentEraValue] Expected a real calendar ID");
- _currentEraValue = CalendarData.GetCalendarData(BaseCalendarID).iCurrentEra;
- }
- return (_currentEraValue);
- }
- }
-
- // The current era for a calendar.
-
- public const int CurrentEra = 0;
-
- internal int twoDigitYearMax = -1;
-
- internal static void CheckAddResult(long ticks, DateTime minValue, DateTime maxValue)
- {
- if (ticks < minValue.Ticks || ticks > maxValue.Ticks)
- {
- throw new ArgumentException(
- String.Format(CultureInfo.InvariantCulture, SR.Format(SR.Argument_ResultCalendarRange,
- minValue, maxValue)));
- }
- Contract.EndContractBlock();
- }
-
- internal DateTime Add(DateTime time, double value, int scale)
- {
- // From ECMA CLI spec, Partition III, section 3.27:
- //
- // If overflow occurs converting a floating-point type to an integer, or if the floating-point value
- // being converted to an integer is a NaN, the value returned is unspecified.
- //
- // Based upon this, this method should be performing the comparison against the double
- // before attempting a cast. Otherwise, the result is undefined.
- double tempMillis = (value * scale + (value >= 0 ? 0.5 : -0.5));
- if (!((tempMillis > -(double)MaxMillis) && (tempMillis < (double)MaxMillis)))
- {
- throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_AddValue);
- }
-
- long millis = (long)tempMillis;
- long ticks = time.Ticks + millis * TicksPerMillisecond;
- CheckAddResult(ticks, MinSupportedDateTime, MaxSupportedDateTime);
- return (new DateTime(ticks));
- }
-
- // Returns the DateTime resulting from adding the given number of
- // milliseconds to the specified DateTime. The result is computed by rounding
- // the number of milliseconds given by value to the nearest integer,
- // and adding that interval to the specified DateTime. The value
- // argument is permitted to be negative.
- //
-
- public virtual DateTime AddMilliseconds(DateTime time, double milliseconds)
- {
- return (Add(time, milliseconds, 1));
- }
-
-
- // Returns the DateTime resulting from adding a fractional number of
- // days to the specified DateTime. The result is computed by rounding the
- // fractional number of days given by value to the nearest
- // millisecond, and adding that interval to the specified DateTime. The
- // value argument is permitted to be negative.
- //
-
- public virtual DateTime AddDays(DateTime time, int days)
- {
- return (Add(time, days, MillisPerDay));
- }
-
- // Returns the DateTime resulting from adding a fractional number of
- // hours to the specified DateTime. The result is computed by rounding the
- // fractional number of hours given by value to the nearest
- // millisecond, and adding that interval to the specified DateTime. The
- // value argument is permitted to be negative.
- //
-
- public virtual DateTime AddHours(DateTime time, int hours)
- {
- return (Add(time, hours, MillisPerHour));
- }
-
-
- // Returns the DateTime resulting from adding a fractional number of
- // minutes to the specified DateTime. The result is computed by rounding the
- // fractional number of minutes given by value to the nearest
- // millisecond, and adding that interval to the specified DateTime. The
- // value argument is permitted to be negative.
- //
-
- public virtual DateTime AddMinutes(DateTime time, int minutes)
- {
- return (Add(time, minutes, MillisPerMinute));
- }
-
-
- // Returns the DateTime resulting from adding the given number of
- // months to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year and month parts of the specified DateTime by
- // value months, and, if required, adjusting the day part of the
- // resulting date downwards to the last day of the resulting month in the
- // resulting year. The time-of-day part of the result is the same as the
- // time-of-day part of the specified DateTime.
- //
- // In more precise terms, considering the specified DateTime to be of the
- // form y / m / d + t, where y is the
- // year, m is the month, d is the day, and t is the
- // time-of-day, the result is y1 / m1 / d1 + t,
- // where y1 and m1 are computed by adding value months
- // to y and m, and d1 is the largest value less than
- // or equal to d that denotes a valid day in month m1 of year
- // y1.
- //
-
- public abstract DateTime AddMonths(DateTime time, int months);
-
- // Returns the DateTime resulting from adding a number of
- // seconds to the specified DateTime. The result is computed by rounding the
- // fractional number of seconds given by value to the nearest
- // millisecond, and adding that interval to the specified DateTime. The
- // value argument is permitted to be negative.
- //
-
- public virtual DateTime AddSeconds(DateTime time, int seconds)
- {
- return Add(time, seconds, MillisPerSecond);
- }
-
- // Returns the DateTime resulting from adding a number of
- // weeks to the specified DateTime. The
- // value argument is permitted to be negative.
- //
-
- public virtual DateTime AddWeeks(DateTime time, int weeks)
- {
- return (AddDays(time, weeks * 7));
- }
-
-
- // Returns the DateTime resulting from adding the given number of
- // years to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year part of the specified DateTime by value
- // years. If the month and day of the specified DateTime is 2/29, and if the
- // resulting year is not a leap year, the month and day of the resulting
- // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
- // parts of the result are the same as those of the specified DateTime.
- //
-
- public abstract DateTime AddYears(DateTime time, int years);
-
- // Returns the day-of-month part of the specified DateTime. The returned
- // value is an integer between 1 and 31.
- //
-
- public abstract int GetDayOfMonth(DateTime time);
-
- // Returns the day-of-week part of the specified DateTime. The returned value
- // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
- // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
- // Thursday, 5 indicates Friday, and 6 indicates Saturday.
- //
-
- public abstract DayOfWeek GetDayOfWeek(DateTime time);
-
- // Returns the day-of-year part of the specified DateTime. The returned value
- // is an integer between 1 and 366.
- //
-
- public abstract int GetDayOfYear(DateTime time);
-
- // Returns the number of days in the month given by the year and
- // month arguments.
- //
-
- public virtual int GetDaysInMonth(int year, int month)
- {
- return (GetDaysInMonth(year, month, CurrentEra));
- }
-
- // Returns the number of days in the month given by the year and
- // month arguments for the specified era.
- //
-
- public abstract int GetDaysInMonth(int year, int month, int era);
-
- // Returns the number of days in the year given by the year argument for the current era.
- //
-
- public virtual int GetDaysInYear(int year)
- {
- return (GetDaysInYear(year, CurrentEra));
- }
-
- // Returns the number of days in the year given by the year argument for the current era.
- //
-
- public abstract int GetDaysInYear(int year, int era);
-
- // Returns the era for the specified DateTime value.
-
- public abstract int GetEra(DateTime time);
-
- /*=================================Eras==========================
- **Action: Get the list of era values.
- **Returns: The int array of the era names supported in this calendar.
- ** null if era is not used.
- **Arguments: None.
- **Exceptions: None.
- ============================================================================*/
-
-
- public abstract int[] Eras
- {
- get;
- }
-
-
- // Returns the hour part of the specified DateTime. The returned value is an
- // integer between 0 and 23.
- //
-
- public virtual int GetHour(DateTime time)
- {
- return ((int)((time.Ticks / TicksPerHour) % 24));
- }
-
- // Returns the millisecond part of the specified DateTime. The returned value
- // is an integer between 0 and 999.
- //
-
- public virtual double GetMilliseconds(DateTime time)
- {
- return (double)((time.Ticks / TicksPerMillisecond) % 1000);
- }
-
- // Returns the minute part of the specified DateTime. The returned value is
- // an integer between 0 and 59.
- //
-
- public virtual int GetMinute(DateTime time)
- {
- return ((int)((time.Ticks / TicksPerMinute) % 60));
- }
-
- // Returns the month part of the specified DateTime. The returned value is an
- // integer between 1 and 12.
- //
-
- public abstract int GetMonth(DateTime time);
-
- // Returns the number of months in the specified year in the current era.
-
- public virtual int GetMonthsInYear(int year)
- {
- return (GetMonthsInYear(year, CurrentEra));
- }
-
- // Returns the number of months in the specified year and era.
-
- public abstract int GetMonthsInYear(int year, int era);
-
- // Returns the second part of the specified DateTime. The returned value is
- // an integer between 0 and 59.
- //
-
- public virtual int GetSecond(DateTime time)
- {
- return ((int)((time.Ticks / TicksPerSecond) % 60));
- }
-
- /*=================================GetFirstDayWeekOfYear==========================
- **Action: Get the week of year using the FirstDay rule.
- **Returns: the week of year.
- **Arguments:
- ** time
- ** firstDayOfWeek the first day of week (0=Sunday, 1=Monday, ... 6=Saturday)
- **Notes:
- ** The CalendarWeekRule.FirstDay rule: Week 1 begins on the first day of the year.
- ** Assume f is the specifed firstDayOfWeek,
- ** and n is the day of week for January 1 of the specified year.
- ** Assign offset = n - f;
- ** Case 1: offset = 0
- ** E.g.
- ** f=1
- ** weekday 0 1 2 3 4 5 6 0 1
- ** date 1/1
- ** week# 1 2
- ** then week of year = (GetDayOfYear(time) - 1) / 7 + 1
- **
- ** Case 2: offset < 0
- ** e.g.
- ** n=1 f=3
- ** weekday 0 1 2 3 4 5 6 0
- ** date 1/1
- ** week# 1 2
- ** This means that the first week actually starts 5 days before 1/1.
- ** So week of year = (GetDayOfYear(time) + (7 + offset) - 1) / 7 + 1
- ** Case 3: offset > 0
- ** e.g.
- ** f=0 n=2
- ** weekday 0 1 2 3 4 5 6 0 1 2
- ** date 1/1
- ** week# 1 2
- ** This means that the first week actually starts 2 days before 1/1.
- ** So Week of year = (GetDayOfYear(time) + offset - 1) / 7 + 1
- ============================================================================*/
-
- internal int GetFirstDayWeekOfYear(DateTime time, int firstDayOfWeek)
- {
- int dayOfYear = GetDayOfYear(time) - 1; // Make the day of year to be 0-based, so that 1/1 is day 0.
- // Calculate the day of week for the first day of the year.
- // dayOfWeek - (dayOfYear % 7) is the day of week for the first day of this year. Note that
- // this value can be less than 0. It's fine since we are making it positive again in calculating offset.
- int dayForJan1 = (int)GetDayOfWeek(time) - (dayOfYear % 7);
- int offset = (dayForJan1 - firstDayOfWeek + 14) % 7;
- Debug.Assert(offset >= 0, "Calendar.GetFirstDayWeekOfYear(): offset >= 0");
- return ((dayOfYear + offset) / 7 + 1);
- }
-
- private int GetWeekOfYearFullDays(DateTime time, int firstDayOfWeek, int fullDays)
- {
- int dayForJan1;
- int offset;
- int day;
-
- int dayOfYear = GetDayOfYear(time) - 1; // Make the day of year to be 0-based, so that 1/1 is day 0.
- //
- // Calculate the number of days between the first day of year (1/1) and the first day of the week.
- // This value will be a positive value from 0 ~ 6. We call this value as "offset".
- //
- // If offset is 0, it means that the 1/1 is the start of the first week.
- // Assume the first day of the week is Monday, it will look like this:
- // Sun Mon Tue Wed Thu Fri Sat
- // 12/31 1/1 1/2 1/3 1/4 1/5 1/6
- // +--> First week starts here.
- //
- // If offset is 1, it means that the first day of the week is 1 day ahead of 1/1.
- // Assume the first day of the week is Monday, it will look like this:
- // Sun Mon Tue Wed Thu Fri Sat
- // 1/1 1/2 1/3 1/4 1/5 1/6 1/7
- // +--> First week starts here.
- //
- // If offset is 2, it means that the first day of the week is 2 days ahead of 1/1.
- // Assume the first day of the week is Monday, it will look like this:
- // Sat Sun Mon Tue Wed Thu Fri Sat
- // 1/1 1/2 1/3 1/4 1/5 1/6 1/7 1/8
- // +--> First week starts here.
-
-
-
- // Day of week is 0-based.
- // Get the day of week for 1/1. This can be derived from the day of week of the target day.
- // Note that we can get a negative value. It's ok since we are going to make it a positive value when calculating the offset.
- dayForJan1 = (int)GetDayOfWeek(time) - (dayOfYear % 7);
-
- // Now, calculate the offset. Subtract the first day of week from the dayForJan1. And make it a positive value.
- offset = (firstDayOfWeek - dayForJan1 + 14) % 7;
- if (offset != 0 && offset >= fullDays)
- {
- //
- // If the offset is greater than the value of fullDays, it means that
- // the first week of the year starts on the week where Jan/1 falls on.
- //
- offset -= 7;
- }
- //
- // Calculate the day of year for specified time by taking offset into account.
- //
- day = dayOfYear - offset;
- if (day >= 0)
- {
- //
- // If the day of year value is greater than zero, get the week of year.
- //
- return (day / 7 + 1);
- }
- //
- // Otherwise, the specified time falls on the week of previous year.
- // Call this method again by passing the last day of previous year.
- //
- // the last day of the previous year may "underflow" to no longer be a valid date time for
- // this calendar if we just subtract so we need the subclass to provide us with
- // that information
- if (time <= MinSupportedDateTime.AddDays(dayOfYear))
- {
- return GetWeekOfYearOfMinSupportedDateTime(firstDayOfWeek, fullDays);
- }
- return (GetWeekOfYearFullDays(time.AddDays(-(dayOfYear + 1)), firstDayOfWeek, fullDays));
- }
-
- private int GetWeekOfYearOfMinSupportedDateTime(int firstDayOfWeek, int minimumDaysInFirstWeek)
- {
- int dayOfYear = GetDayOfYear(MinSupportedDateTime) - 1; // Make the day of year to be 0-based, so that 1/1 is day 0.
- int dayOfWeekOfFirstOfYear = (int)GetDayOfWeek(MinSupportedDateTime) - dayOfYear % 7;
-
- // Calculate the offset (how many days from the start of the year to the start of the week)
- int offset = (firstDayOfWeek + 7 - dayOfWeekOfFirstOfYear) % 7;
- if (offset == 0 || offset >= minimumDaysInFirstWeek)
- {
- // First of year falls in the first week of the year
- return 1;
- }
-
- int daysInYearBeforeMinSupportedYear = DaysInYearBeforeMinSupportedYear - 1; // Make the day of year to be 0-based, so that 1/1 is day 0.
- int dayOfWeekOfFirstOfPreviousYear = dayOfWeekOfFirstOfYear - 1 - (daysInYearBeforeMinSupportedYear % 7);
-
- // starting from first day of the year, how many days do you have to go forward
- // before getting to the first day of the week?
- int daysInInitialPartialWeek = (firstDayOfWeek - dayOfWeekOfFirstOfPreviousYear + 14) % 7;
- int day = daysInYearBeforeMinSupportedYear - daysInInitialPartialWeek;
- if (daysInInitialPartialWeek >= minimumDaysInFirstWeek)
- {
- // If the offset is greater than the minimum Days in the first week, it means that
- // First of year is part of the first week of the year even though it is only a partial week
- // add another week
- day += 7;
- }
-
- return (day / 7 + 1);
- }
-
- // it would be nice to make this abstract but we can't since that would break previous implementations
- protected virtual int DaysInYearBeforeMinSupportedYear
- {
- get
- {
- return 365;
- }
- }
-
-
- // Returns the week of year for the specified DateTime. The returned value is an
- // integer between 1 and 53.
- //
-
- public virtual int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
- {
- if ((int)firstDayOfWeek < 0 || (int)firstDayOfWeek > 6)
- {
- throw new ArgumentOutOfRangeException(
- nameof(firstDayOfWeek), SR.Format(SR.ArgumentOutOfRange_Range,
- DayOfWeek.Sunday, DayOfWeek.Saturday));
- }
- Contract.EndContractBlock();
- switch (rule)
- {
- case CalendarWeekRule.FirstDay:
- return (GetFirstDayWeekOfYear(time, (int)firstDayOfWeek));
- case CalendarWeekRule.FirstFullWeek:
- return (GetWeekOfYearFullDays(time, (int)firstDayOfWeek, 7));
- case CalendarWeekRule.FirstFourDayWeek:
- return (GetWeekOfYearFullDays(time, (int)firstDayOfWeek, 4));
- }
- throw new ArgumentOutOfRangeException(
- nameof(rule), SR.Format(SR.ArgumentOutOfRange_Range,
- CalendarWeekRule.FirstDay, CalendarWeekRule.FirstFourDayWeek));
- }
-
- // Returns the year part of the specified DateTime. The returned value is an
- // integer between 1 and 9999.
- //
-
- public abstract int GetYear(DateTime time);
-
- // Checks whether a given day in the current era is a leap day. This method returns true if
- // the date is a leap day, or false if not.
- //
-
- public virtual bool IsLeapDay(int year, int month, int day)
- {
- return (IsLeapDay(year, month, day, CurrentEra));
- }
-
- // Checks whether a given day in the specified era is a leap day. This method returns true if
- // the date is a leap day, or false if not.
- //
-
- public abstract bool IsLeapDay(int year, int month, int day, int era);
-
- // Checks whether a given month in the current era is a leap month. This method returns true if
- // month is a leap month, or false if not.
- //
-
- public virtual bool IsLeapMonth(int year, int month)
- {
- return (IsLeapMonth(year, month, CurrentEra));
- }
-
- // Checks whether a given month in the specified era is a leap month. This method returns true if
- // month is a leap month, or false if not.
- //
-
- public abstract bool IsLeapMonth(int year, int month, int era);
-
- // Returns the leap month in a calendar year of the current era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
- public virtual int GetLeapMonth(int year)
- {
- return (GetLeapMonth(year, CurrentEra));
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
- public virtual int GetLeapMonth(int year, int era)
- {
- if (!IsLeapYear(year, era))
- return 0;
-
- int monthsCount = GetMonthsInYear(year, era);
- for (int month = 1; month <= monthsCount; month++)
- {
- if (IsLeapMonth(year, month, era))
- return month;
- }
-
- return 0;
- }
-
- // Checks whether a given year in the current era is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
-
- public virtual bool IsLeapYear(int year)
- {
- return (IsLeapYear(year, CurrentEra));
- }
-
- // Checks whether a given year in the specified era is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
-
- public abstract bool IsLeapYear(int year, int era);
-
- // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
- //
-
- public virtual DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond)
- {
- return (ToDateTime(year, month, day, hour, minute, second, millisecond, CurrentEra));
- }
-
- // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
- //
-
- public abstract DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era);
-
- internal virtual Boolean TryToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era, out DateTime result)
- {
- result = DateTime.MinValue;
- try
- {
- result = ToDateTime(year, month, day, hour, minute, second, millisecond, era);
- return true;
- }
- catch (ArgumentException)
- {
- return false;
- }
- }
-
- internal virtual bool IsValidYear(int year, int era)
- {
- return (year >= GetYear(MinSupportedDateTime) && year <= GetYear(MaxSupportedDateTime));
- }
-
- internal virtual bool IsValidMonth(int year, int month, int era)
- {
- return (IsValidYear(year, era) && month >= 1 && month <= GetMonthsInYear(year, era));
- }
-
- internal virtual bool IsValidDay(int year, int month, int day, int era)
- {
- return (IsValidMonth(year, month, era) && day >= 1 && day <= GetDaysInMonth(year, month, era));
- }
-
-
- // Returns and assigns the maximum value to represent a two digit year. This
- // value is the upper boundary of a 100 year range that allows a two digit year
- // to be properly translated to a four digit year. For example, if 2029 is the
- // upper boundary, then a two digit value of 30 should be interpreted as 1930
- // while a two digit value of 29 should be interpreted as 2029. In this example
- // , the 100 year range would be from 1930-2029. See ToFourDigitYear().
-
- public virtual int TwoDigitYearMax
- {
- get
- {
- return (twoDigitYearMax);
- }
-
- set
- {
- VerifyWritable();
- twoDigitYearMax = value;
- }
- }
-
- // Converts the year value to the appropriate century by using the
- // TwoDigitYearMax property. For example, if the TwoDigitYearMax value is 2029,
- // then a two digit value of 30 will get converted to 1930 while a two digit
- // value of 29 will get converted to 2029.
-
- public virtual int ToFourDigitYear(int year)
- {
- if (year < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(year),
- SR.ArgumentOutOfRange_NeedNonNegNum);
- }
- Contract.EndContractBlock();
- if (year < 100)
- {
- return ((TwoDigitYearMax / 100 - (year > TwoDigitYearMax % 100 ? 1 : 0)) * 100 + year);
- }
- // If the year value is above 100, just return the year value. Don't have to do
- // the TwoDigitYearMax comparison.
- return (year);
- }
-
- // Return the tick count corresponding to the given hour, minute, second.
- // Will check the if the parameters are valid.
- internal static long TimeToTicks(int hour, int minute, int second, int millisecond)
- {
- if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >= 0 && second < 60)
- {
- if (millisecond < 0 || millisecond >= MillisPerSecond)
- {
- throw new ArgumentOutOfRangeException(
- nameof(millisecond),
- String.Format(
- CultureInfo.InvariantCulture,
- SR.Format(SR.ArgumentOutOfRange_Range, 0, MillisPerSecond - 1)));
- }
- return InternalGloablizationHelper.TimeToTicks(hour, minute, second) + millisecond * TicksPerMillisecond;
- }
- throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
- }
-
- internal static int GetSystemTwoDigitYearSetting(CalendarId CalID, int defaultYearValue)
- {
- // Call nativeGetTwoDigitYearMax
- int twoDigitYearMax = CalendarData.GetTwoDigitYearMax(CalID);
- if (twoDigitYearMax < 0)
- {
- twoDigitYearMax = defaultYearValue;
- }
- return (twoDigitYearMax);
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/CalendarAlgorithmType.cs b/src/mscorlib/corefx/System/Globalization/CalendarAlgorithmType.cs
deleted file mode 100644
index 159b0e6f77..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CalendarAlgorithmType.cs
+++ /dev/null
@@ -1,20 +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;
-
-namespace System.Globalization
-{
- public enum CalendarAlgorithmType
- {
- Unknown = 0, // This is the default value to return in the Calendar base class.
- SolarCalendar = 1, // Solar-base calendar, such as GregorianCalendar, jaoaneseCalendar, JulianCalendar, etc.
- // Solar calendars are based on the solar year and seasons.
- LunarCalendar = 2, // Lunar-based calendar, such as Hijri and UmAlQuraCalendar.
- // Lunar calendars are based on the path of the moon. The seasons are not accurately represented.
- LunisolarCalendar = 3 // Lunisolar-based calendar which use leap month rule, such as HebrewCalendar and Asian Lunisolar calendars.
- // Lunisolar calendars are based on the cycle of the moon, but consider the seasons as a secondary consideration,
- // so they align with the seasons as well as lunar events.
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/CalendarData.Unix.cs b/src/mscorlib/corefx/System/Globalization/CalendarData.Unix.cs
deleted file mode 100644
index 19c81f17b0..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CalendarData.Unix.cs
+++ /dev/null
@@ -1,335 +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.Collections.Generic;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-using System.Runtime.InteropServices;
-using System.Security;
-using System.Text;
-
-namespace System.Globalization
-{
- // needs to be kept in sync with CalendarDataType in System.Globalization.Native
- internal enum CalendarDataType
- {
- Uninitialized = 0,
- NativeName = 1,
- MonthDay = 2,
- ShortDates = 3,
- LongDates = 4,
- YearMonths = 5,
- DayNames = 6,
- AbbrevDayNames = 7,
- MonthNames = 8,
- AbbrevMonthNames = 9,
- SuperShortDayNames = 10,
- MonthGenitiveNames = 11,
- AbbrevMonthGenitiveNames = 12,
- EraNames = 13,
- AbbrevEraNames = 14,
- }
-
- internal partial class CalendarData
- {
- private bool LoadCalendarDataFromSystem(String localeName, CalendarId calendarId)
- {
- bool result = true;
- result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.NativeName, out this.sNativeName);
- result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.MonthDay, out this.sMonthDay);
- this.sMonthDay = NormalizeDatePattern(this.sMonthDay);
-
- result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.ShortDates, out this.saShortDates);
- result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.LongDates, out this.saLongDates);
- result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.YearMonths, out this.saYearMonths);
- result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.DayNames, out this.saDayNames);
- result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.AbbrevDayNames, out this.saAbbrevDayNames);
- result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.SuperShortDayNames, out this.saSuperShortDayNames);
- result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthNames, out this.saMonthNames);
- result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthNames, out this.saAbbrevMonthNames);
- result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthGenitiveNames, out this.saMonthGenitiveNames);
- result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthGenitiveNames, out this.saAbbrevMonthGenitiveNames);
- result &= EnumEraNames(localeName, calendarId, CalendarDataType.EraNames, out this.saEraNames);
- result &= EnumEraNames(localeName, calendarId, CalendarDataType.AbbrevEraNames, out this.saAbbrevEraNames);
-
- return result;
- }
-
- internal static int GetTwoDigitYearMax(CalendarId calendarId)
- {
- // There is no user override for this value on Linux or in ICU.
- // So just return -1 to use the hard-coded defaults.
- return -1;
- }
-
- // Call native side to figure out which calendars are allowed
- internal static int GetCalendars(string localeName, bool useUserOverride, CalendarId[] calendars)
- {
- // NOTE: there are no 'user overrides' on Linux
- int count = Interop.GlobalizationInterop.GetCalendars(localeName, calendars, calendars.Length);
-
- // ensure there is at least 1 calendar returned
- if (count == 0 && calendars.Length > 0)
- {
- calendars[0] = CalendarId.GREGORIAN;
- count = 1;
- }
-
- return count;
- }
-
- private static bool SystemSupportsTaiwaneseCalendar()
- {
- return true;
- }
-
- // PAL Layer ends here
-
- private static bool GetCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string calendarString)
- {
- return Interop.CallStringMethod(
- (locale, calId, type, stringBuilder) =>
- Interop.GlobalizationInterop.GetCalendarInfo(
- locale,
- calId,
- type,
- stringBuilder,
- stringBuilder.Capacity),
- localeName,
- calendarId,
- dataType,
- out calendarString);
- }
-
- private static bool EnumDatePatterns(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] datePatterns)
- {
- datePatterns = null;
-
- CallbackContext callbackContext = new CallbackContext();
- callbackContext.DisallowDuplicates = true;
- bool result = EnumCalendarInfo(localeName, calendarId, dataType, callbackContext);
- if (result)
- {
- List<string> datePatternsList = callbackContext.Results;
-
- datePatterns = new string[datePatternsList.Count];
- for (int i = 0; i < datePatternsList.Count; i++)
- {
- datePatterns[i] = NormalizeDatePattern(datePatternsList[i]);
- }
- }
-
- return result;
- }
-
- /// <summary>
- /// The ICU date format characters are not exactly the same as the .NET date format characters.
- /// NormalizeDatePattern will take in an ICU date pattern and return the equivalent .NET date pattern.
- /// </summary>
- /// <remarks>
- /// see Date Field Symbol Table in http://userguide.icu-project.org/formatparse/datetime
- /// and https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx
- /// </remarks>
- private static string NormalizeDatePattern(string input)
- {
- StringBuilder destination = StringBuilderCache.Acquire(input.Length);
-
- int index = 0;
- while (index < input.Length)
- {
- switch (input[index])
- {
- case '\'':
- // single quotes escape characters, like 'de' in es-SP
- // so read verbatim until the next single quote
- destination.Append(input[index++]);
- while (index < input.Length)
- {
- char current = input[index++];
- destination.Append(current);
- if (current == '\'')
- {
- break;
- }
- }
- break;
- case 'E':
- case 'e':
- case 'c':
- // 'E' in ICU is the day of the week, which maps to 3 or 4 'd's in .NET
- // 'e' in ICU is the local day of the week, which has no representation in .NET, but
- // maps closest to 3 or 4 'd's in .NET
- // 'c' in ICU is the stand-alone day of the week, which has no representation in .NET, but
- // maps closest to 3 or 4 'd's in .NET
- NormalizeDayOfWeek(input, destination, ref index);
- break;
- case 'L':
- case 'M':
- // 'L' in ICU is the stand-alone name of the month,
- // which maps closest to 'M' in .NET since it doesn't support stand-alone month names in patterns
- // 'M' in both ICU and .NET is the month,
- // but ICU supports 5 'M's, which is the super short month name
- int occurrences = CountOccurrences(input, input[index], ref index);
- if (occurrences > 4)
- {
- // 5 'L's or 'M's in ICU is the super short name, which maps closest to MMM in .NET
- occurrences = 3;
- }
- destination.Append('M', occurrences);
- break;
- case 'G':
- // 'G' in ICU is the era, which maps to 'g' in .NET
- occurrences = CountOccurrences(input, 'G', ref index);
-
- // it doesn't matter how many 'G's, since .NET only supports 'g' or 'gg', and they
- // have the same meaning
- destination.Append('g');
- break;
- case 'y':
- // a single 'y' in ICU is the year with no padding or trimming.
- // a single 'y' in .NET is the year with 1 or 2 digits
- // so convert any single 'y' to 'yyyy'
- occurrences = CountOccurrences(input, 'y', ref index);
- if (occurrences == 1)
- {
- occurrences = 4;
- }
- destination.Append('y', occurrences);
- break;
- default:
- const string unsupportedDateFieldSymbols = "YuUrQqwWDFg";
- Debug.Assert(unsupportedDateFieldSymbols.IndexOf(input[index]) == -1,
- string.Format(CultureInfo.InvariantCulture,
- "Encountered an unexpected date field symbol '{0}' from ICU which has no known corresponding .NET equivalent.",
- input[index]));
-
- destination.Append(input[index++]);
- break;
- }
- }
-
- return StringBuilderCache.GetStringAndRelease(destination);
- }
-
- private static void NormalizeDayOfWeek(string input, StringBuilder destination, ref int index)
- {
- char dayChar = input[index];
- int occurrences = CountOccurrences(input, dayChar, ref index);
- occurrences = Math.Max(occurrences, 3);
- if (occurrences > 4)
- {
- // 5 and 6 E/e/c characters in ICU is the super short names, which maps closest to ddd in .NET
- occurrences = 3;
- }
-
- destination.Append('d', occurrences);
- }
-
- private static int CountOccurrences(string input, char value, ref int index)
- {
- int startIndex = index;
- while (index < input.Length && input[index] == value)
- {
- index++;
- }
-
- return index - startIndex;
- }
-
- private static bool EnumMonthNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] monthNames)
- {
- monthNames = null;
-
- CallbackContext callbackContext = new CallbackContext();
- bool result = EnumCalendarInfo(localeName, calendarId, dataType, callbackContext);
- if (result)
- {
- // the month-name arrays are expected to have 13 elements. If ICU only returns 12, add an
- // extra empty string to fill the array.
- if (callbackContext.Results.Count == 12)
- {
- callbackContext.Results.Add(string.Empty);
- }
-
- monthNames = callbackContext.Results.ToArray();
- }
-
- return result;
- }
-
- private static bool EnumEraNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] eraNames)
- {
- bool result = EnumCalendarInfo(localeName, calendarId, dataType, out eraNames);
-
- // .NET expects that only the Japanese calendars have more than 1 era.
- // So for other calendars, only return the latest era.
- if (calendarId != CalendarId.JAPAN && calendarId != CalendarId.JAPANESELUNISOLAR && eraNames.Length > 0)
- {
- string[] latestEraName = new string[] { eraNames[eraNames.Length - 1] };
- eraNames = latestEraName;
- }
-
- return result;
- }
-
- internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] calendarData)
- {
- calendarData = null;
-
- CallbackContext callbackContext = new CallbackContext();
- bool result = EnumCalendarInfo(localeName, calendarId, dataType, callbackContext);
- if (result)
- {
- calendarData = callbackContext.Results.ToArray();
- }
-
- return result;
- }
-
- private static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, CallbackContext callbackContext)
- {
- GCHandle context = GCHandle.Alloc(callbackContext);
- try
- {
- return Interop.GlobalizationInterop.EnumCalendarInfo(EnumCalendarInfoCallback, localeName, calendarId, dataType, (IntPtr)context);
- }
- finally
- {
- context.Free();
- }
- }
-
- private static void EnumCalendarInfoCallback(string calendarString, IntPtr context)
- {
- CallbackContext callbackContext = (CallbackContext)((GCHandle)context).Target;
-
- if (callbackContext.DisallowDuplicates)
- {
- foreach (string existingResult in callbackContext.Results)
- {
- if (string.Equals(calendarString, existingResult, StringComparison.Ordinal))
- {
- // the value is already in the results, so don't add it again
- return;
- }
- }
- }
-
- callbackContext.Results.Add(calendarString);
- }
-
- private class CallbackContext
- {
- private List<string> _results = new List<string>();
-
- public CallbackContext()
- {
- }
-
- public List<string> Results { get { return _results; } }
-
- public bool DisallowDuplicates { get; set; }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/CalendarData.Windows.cs b/src/mscorlib/corefx/System/Globalization/CalendarData.Windows.cs
deleted file mode 100644
index bdf3ff1881..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CalendarData.Windows.cs
+++ /dev/null
@@ -1,469 +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.InteropServices;
-using System.Runtime.CompilerServices;
-using System.Diagnostics.Contracts;
-using System.Collections.Generic;
-
-namespace System.Globalization
-{
- internal partial class CalendarData
- {
- private bool LoadCalendarDataFromSystem(String localeName, CalendarId calendarId)
- {
- bool ret = true;
-
- uint useOverrides = this.bUseUserOverrides ? 0 : CAL_NOUSEROVERRIDE;
-
- //
- // Windows doesn't support some calendars right now, so remap those.
- //
- switch (calendarId)
- {
- case CalendarId.JAPANESELUNISOLAR: // Data looks like Japanese
- calendarId = CalendarId.JAPAN;
- break;
- case CalendarId.JULIAN: // Data looks like gregorian US
- case CalendarId.CHINESELUNISOLAR: // Algorithmic, so actual data is irrelevent
- case CalendarId.SAKA: // reserved to match Office but not implemented in our code, so data is irrelevent
- case CalendarId.LUNAR_ETO_CHN: // reserved to match Office but not implemented in our code, so data is irrelevent
- case CalendarId.LUNAR_ETO_KOR: // reserved to match Office but not implemented in our code, so data is irrelevent
- case CalendarId.LUNAR_ETO_ROKUYOU: // reserved to match Office but not implemented in our code, so data is irrelevent
- case CalendarId.KOREANLUNISOLAR: // Algorithmic, so actual data is irrelevent
- case CalendarId.TAIWANLUNISOLAR: // Algorithmic, so actual data is irrelevent
- calendarId = CalendarId.GREGORIAN_US;
- break;
- }
-
- //
- // Special handling for some special calendar due to OS limitation.
- // This includes calendar like Taiwan calendar, UmAlQura calendar, etc.
- //
- CheckSpecialCalendar(ref calendarId, ref localeName);
-
- // Numbers
- ret &= CallGetCalendarInfoEx(localeName, calendarId, CAL_ITWODIGITYEARMAX | useOverrides, out this.iTwoDigitYearMax);
-
- // Strings
- ret &= CallGetCalendarInfoEx(localeName, calendarId, CAL_SCALNAME, out this.sNativeName);
- ret &= CallGetCalendarInfoEx(localeName, calendarId, CAL_SMONTHDAY | useOverrides, out this.sMonthDay);
-
- // String Arrays
- // Formats
- ret &= CallEnumCalendarInfo(localeName, calendarId, CAL_SSHORTDATE, LOCALE_SSHORTDATE | useOverrides, out this.saShortDates);
- ret &= CallEnumCalendarInfo(localeName, calendarId, CAL_SLONGDATE, LOCALE_SLONGDATE | useOverrides, out this.saLongDates);
-
- // Get the YearMonth pattern.
- ret &= CallEnumCalendarInfo(localeName, calendarId, CAL_SYEARMONTH, LOCALE_SYEARMONTH, out this.saYearMonths);
-
- // Day & Month Names
- // These are all single calType entries, 1 per day, so we have to make 7 or 13 calls to collect all the names
-
- // Day
- // Note that we're off-by-one since managed starts on sunday and windows starts on monday
- ret &= GetCalendarDayInfo(localeName, calendarId, CAL_SDAYNAME7, out this.saDayNames);
- ret &= GetCalendarDayInfo(localeName, calendarId, CAL_SABBREVDAYNAME7, out this.saAbbrevDayNames);
-
- // Month names
- ret &= GetCalendarMonthInfo(localeName, calendarId, CAL_SMONTHNAME1, out this.saMonthNames);
- ret &= GetCalendarMonthInfo(localeName, calendarId, CAL_SABBREVMONTHNAME1, out this.saAbbrevMonthNames);
-
- //
- // The following LCTYPE are not supported in some platforms. If the call fails,
- // don't return a failure.
- //
- GetCalendarDayInfo(localeName, calendarId, CAL_SSHORTESTDAYNAME7, out this.saSuperShortDayNames);
-
- // Gregorian may have genitive month names
- if (calendarId == CalendarId.GREGORIAN)
- {
- GetCalendarMonthInfo(localeName, calendarId, CAL_SMONTHNAME1 | CAL_RETURN_GENITIVE_NAMES, out this.saMonthGenitiveNames);
- GetCalendarMonthInfo(localeName, calendarId, CAL_SABBREVMONTHNAME1 | CAL_RETURN_GENITIVE_NAMES, out this.saAbbrevMonthGenitiveNames);
- }
-
- // Calendar Parts Names
- // This doesn't get always get localized names for gregorian (not available in windows < 7)
- // so: eg: coreclr on win < 7 won't get these
- CallEnumCalendarInfo(localeName, calendarId, CAL_SERASTRING, 0, out this.saEraNames);
- CallEnumCalendarInfo(localeName, calendarId, CAL_SABBREVERASTRING, 0, out this.saAbbrevEraNames);
-
- //
- // Calendar Era Info
- // Note that calendar era data (offsets, etc) is hard coded for each calendar since this
- // data is implementation specific and not dynamic (except perhaps Japanese)
- //
-
- // Clean up the escaping of the formats
- this.saShortDates = CultureData.ReescapeWin32Strings(this.saShortDates);
- this.saLongDates = CultureData.ReescapeWin32Strings(this.saLongDates);
- this.saYearMonths = CultureData.ReescapeWin32Strings(this.saYearMonths);
- this.sMonthDay = CultureData.ReescapeWin32String(this.sMonthDay);
-
- return ret;
- }
-
- // Get native two digit year max
- internal static int GetTwoDigitYearMax(CalendarId calendarId)
- {
- int twoDigitYearMax = -1;
-
- if (!CallGetCalendarInfoEx(null, calendarId, (uint)CAL_ITWODIGITYEARMAX, out twoDigitYearMax))
- {
- twoDigitYearMax = -1;
- }
-
- return twoDigitYearMax;
- }
-
- // Call native side to figure out which calendars are allowed
- internal static int GetCalendars(String localeName, bool useUserOverride, CalendarId[] calendars)
- {
- EnumCalendarsData data = new EnumCalendarsData();
- data.userOverride = 0;
- data.calendars = new LowLevelList<int>();
-
- // First call GetLocaleInfo if necessary
- if (useUserOverride)
- {
- // They want user overrides, see if the user calendar matches the input calendar
- int userCalendar = Interop.mincore.GetLocaleInfoExInt(localeName, LOCALE_ICALENDARTYPE);
-
- // If we got a default, then use it as the first calendar
- if (userCalendar != 0)
- {
- data.userOverride = userCalendar;
- data.calendars.Add(userCalendar);
- }
- }
-
- GCHandle contextHandle = GCHandle.Alloc(data);
- try
- {
- // Now call the enumeration API. Work is done by our callback function
- IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, uint, IntPtr, IntPtr, Interop.BOOL>>(EnumCalendarsCallback);
- Interop.mincore.EnumCalendarInfoExEx(callback, localeName, ENUM_ALL_CALENDARS, null, CAL_ICALINTVALUE, (IntPtr)contextHandle);
- }
- finally
- {
- contextHandle.Free();
- }
-
- // Copy to the output array
- for (int i = 0; i < Math.Min(calendars.Length, data.calendars.Count); i++)
- calendars[i] = (CalendarId)data.calendars[i];
-
- // Now we have a list of data, return the count
- return data.calendars.Count;
- }
-
- private static bool SystemSupportsTaiwaneseCalendar()
- {
- string data;
- // Taiwanese calendar get listed as one of the optional zh-TW calendars only when having zh-TW UI
- return CallGetCalendarInfoEx("zh-TW", CalendarId.TAIWAN, CAL_SCALNAME, out data);
- }
-
- // PAL Layer ends here
-
- private const uint CAL_RETURN_NUMBER = 0x20000000;
- private const uint CAL_RETURN_GENITIVE_NAMES = 0x10000000;
- private const uint CAL_NOUSEROVERRIDE = 0x80000000;
- private const uint CAL_SCALNAME = 0x00000002;
- private const uint CAL_SMONTHDAY = 0x00000038;
- private const uint CAL_SSHORTDATE = 0x00000005;
- private const uint CAL_SLONGDATE = 0x00000006;
- private const uint CAL_SYEARMONTH = 0x0000002f;
- private const uint CAL_SDAYNAME7 = 0x0000000d;
- private const uint CAL_SABBREVDAYNAME7 = 0x00000014;
- private const uint CAL_SMONTHNAME1 = 0x00000015;
- private const uint CAL_SABBREVMONTHNAME1 = 0x00000022;
- private const uint CAL_SSHORTESTDAYNAME7 = 0x00000037;
- private const uint CAL_SERASTRING = 0x00000004;
- private const uint CAL_SABBREVERASTRING = 0x00000039;
- private const uint CAL_ICALINTVALUE = 0x00000001;
- private const uint CAL_ITWODIGITYEARMAX = 0x00000030;
-
- private const uint ENUM_ALL_CALENDARS = 0xffffffff;
-
- private const uint LOCALE_SSHORTDATE = 0x0000001F;
- private const uint LOCALE_SLONGDATE = 0x00000020;
- private const uint LOCALE_SYEARMONTH = 0x00001006;
- private const uint LOCALE_ICALENDARTYPE = 0x00001009;
-
- ////////////////////////////////////////////////////////////////////////
- //
- // For calendars like Gregorain US/Taiwan/UmAlQura, they are not available
- // in all OS or all localized versions of OS.
- // If OS does not support these calendars, we will fallback by using the
- // appropriate fallback calendar and locale combination to retrieve data from OS.
- //
- // Parameters:
- // __deref_inout pCalendarInt:
- // Pointer to the calendar ID. This will be updated to new fallback calendar ID if needed.
- // __in_out pLocaleNameStackBuffer
- // Pointer to the StackSString object which holds the locale name to be checked.
- // This will be updated to new fallback locale name if needed.
- //
- ////////////////////////////////////////////////////////////////////////
- private static void CheckSpecialCalendar(ref CalendarId calendar, ref string localeName)
- {
- string data;
-
- // Gregorian-US isn't always available in the OS, however it is the same for all locales
- switch (calendar)
- {
- case CalendarId.GREGORIAN_US:
- // See if this works
- if (!CallGetCalendarInfoEx(localeName, calendar, CAL_SCALNAME, out data))
- {
- // Failed, set it to a locale (fa-IR) that's alway has Gregorian US available in the OS
- localeName = "fa-IR";
- }
- // See if that works
- if (!CallGetCalendarInfoEx(localeName, calendar, CAL_SCALNAME, out data))
- {
- // Failed again, just use en-US with the gregorian calendar
- localeName = "en-US";
- calendar = CalendarId.GREGORIAN;
- }
- break;
- case CalendarId.TAIWAN:
- // Taiwan calendar data is not always in all language version of OS due to Geopolical reasons.
- // It is only available in zh-TW localized versions of Windows.
- // Let's check if OS supports it. If not, fallback to Greogrian localized for Taiwan calendar.
- if (!SystemSupportsTaiwaneseCalendar())
- {
- calendar = CalendarId.GREGORIAN;
- }
- break;
- }
- }
-
- private static bool CallGetCalendarInfoEx(string localeName, CalendarId calendar, uint calType, out int data)
- {
- return (Interop.mincore.GetCalendarInfoEx(localeName, (uint)calendar, IntPtr.Zero, calType | CAL_RETURN_NUMBER, IntPtr.Zero, 0, out data) != 0);
- }
-
- private static unsafe bool CallGetCalendarInfoEx(string localeName, CalendarId calendar, uint calType, out string data)
- {
- const int BUFFER_LENGTH = 80;
-
- // The maximum size for values returned from GetCalendarInfoEx is 80 characters.
- char* buffer = stackalloc char[BUFFER_LENGTH];
-
- int ret = Interop.mincore.GetCalendarInfoEx(localeName, (uint)calendar, IntPtr.Zero, calType, (IntPtr)buffer, BUFFER_LENGTH, IntPtr.Zero);
- if (ret > 0)
- {
- if (buffer[ret - 1] == '\0')
- {
- ret--; // don't include the null termination in the string
- }
- data = new string(buffer, 0, ret);
- return true;
- }
- data = "";
- return false;
- }
-
- // Context for EnumCalendarInfoExEx callback.
- private class EnumData
- {
- public string userOverride;
- public LowLevelList<string> strings;
- }
-
- // EnumCalendarInfoExEx callback itself.
- [NativeCallable(CallingConvention = CallingConvention.StdCall)]
- private static unsafe Interop.BOOL EnumCalendarInfoCallback(IntPtr lpCalendarInfoString, uint calendar, IntPtr pReserved, IntPtr lParam)
- {
- EnumData context = (EnumData)((GCHandle)lParam).Target;
- try
- {
- string calendarInfo = new string((char*)lpCalendarInfoString);
-
- // If we had a user override, check to make sure this differs
- if (context.userOverride != calendarInfo)
- context.strings.Add(calendarInfo);
-
- return Interop.BOOL.TRUE;
- }
- catch (Exception)
- {
- return Interop.BOOL.FALSE;
- }
- }
-
- private static unsafe bool CallEnumCalendarInfo(string localeName, CalendarId calendar, uint calType, uint lcType, out string[] data)
- {
- EnumData context = new EnumData();
- context.userOverride = null;
- context.strings = new LowLevelList<string>();
-
- // First call GetLocaleInfo if necessary
- if (((lcType != 0) && ((lcType & CAL_NOUSEROVERRIDE) == 0)) &&
- // Get user locale, see if it matches localeName.
- // Note that they should match exactly, including letter case
- GetUserDefaultLocaleName() == localeName)
- {
- // They want user overrides, see if the user calendar matches the input calendar
- CalendarId userCalendar = (CalendarId)Interop.mincore.GetLocaleInfoExInt(localeName, LOCALE_ICALENDARTYPE);
-
- // If the calendars were the same, see if the locales were the same
- if (userCalendar == calendar)
- {
- // They matched, get the user override since locale & calendar match
- string res = Interop.mincore.GetLocaleInfoEx(localeName, lcType);
-
- // if it succeeded remember the override for the later callers
- if (res != "")
- {
- // Remember this was the override (so we can look for duplicates later in the enum function)
- context.userOverride = res;
-
- // Add to the result strings.
- context.strings.Add(res);
- }
- }
- }
-
- GCHandle contextHandle = GCHandle.Alloc(context);
- try
- {
- // Now call the enumeration API. Work is done by our callback function
- IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, uint, IntPtr, IntPtr, Interop.BOOL>>(EnumCalendarInfoCallback);
- Interop.mincore.EnumCalendarInfoExEx(callback, localeName, (uint)calendar, null, calType, (IntPtr)contextHandle);
- }
- finally
- {
- contextHandle.Free();
- }
-
- // Now we have a list of data, fail if we didn't find anything.
- if (context.strings.Count == 0)
- {
- data = null;
- return false;
- }
-
- string[] output = context.strings.ToArray();
-
- if (calType == CAL_SABBREVERASTRING || calType == CAL_SERASTRING)
- {
- // Eras are enumerated backwards. (oldest era name first, but
- // Japanese calendar has newest era first in array, and is only
- // calendar with multiple eras)
- Array.Reverse(output, 0, output.Length);
- }
-
- data = output;
-
- return true;
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Get the native day names
- //
- // NOTE: There's a disparity between .Net & windows day orders, the input day should
- // start with Sunday
- //
- // Parameters:
- // OUT pOutputStrings The output string[] value.
- //
- ////////////////////////////////////////////////////////////////////////
- private static bool GetCalendarDayInfo(string localeName, CalendarId calendar, uint calType, out string[] outputStrings)
- {
- bool result = true;
-
- //
- // We'll need a new array of 7 items
- //
- string[] results = new string[7];
-
- // Get each one of them
- for (int i = 0; i < 7; i++, calType++)
- {
- result &= CallGetCalendarInfoEx(localeName, calendar, calType, out results[i]);
-
- // On the first iteration we need to go from CAL_SDAYNAME7 to CAL_SDAYNAME1, so subtract 7 before the ++ happens
- // This is because the framework starts on sunday and windows starts on monday when counting days
- if (i == 0)
- calType -= 7;
- }
-
- outputStrings = results;
-
- return result;
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Get the native month names
- //
- // Parameters:
- // OUT pOutputStrings The output string[] value.
- //
- ////////////////////////////////////////////////////////////////////////
- private static bool GetCalendarMonthInfo(string localeName, CalendarId calendar, uint calType, out string[] outputStrings)
- {
- //
- // We'll need a new array of 13 items
- //
- string[] results = new string[13];
-
- // Get each one of them
- for (int i = 0; i < 13; i++, calType++)
- {
- if (!CallGetCalendarInfoEx(localeName, calendar, calType, out results[i]))
- results[i] = "";
- }
-
- outputStrings = results;
-
- return true;
- }
-
- //
- // struct to help our calendar data enumaration callback
- //
- private class EnumCalendarsData
- {
- public int userOverride; // user override value (if found)
- public LowLevelList<int> calendars; // list of calendars found so far
- }
-
- [NativeCallable(CallingConvention = CallingConvention.StdCall)]
- private static Interop.BOOL EnumCalendarsCallback(IntPtr lpCalendarInfoString, uint calendar, IntPtr reserved, IntPtr lParam)
- {
- EnumCalendarsData context = (EnumCalendarsData)((GCHandle)lParam).Target;
- try
- {
- // If we had a user override, check to make sure this differs
- if (context.userOverride != calendar)
- context.calendars.Add((int)calendar);
-
- return Interop.BOOL.TRUE;
- }
- catch (Exception)
- {
- return Interop.BOOL.FALSE;
- }
- }
-
- private static unsafe String GetUserDefaultLocaleName()
- {
- const int LOCALE_NAME_MAX_LENGTH = 85;
- const uint LOCALE_SNAME = 0x0000005c;
- const string LOCALE_NAME_USER_DEFAULT = null;
-
- int result;
- char* localeName = stackalloc char[LOCALE_NAME_MAX_LENGTH];
- result = Interop.mincore.GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME, localeName, LOCALE_NAME_MAX_LENGTH);
-
- return result <= 0 ? "" : new String(localeName, 0, result - 1); // exclude the null termination
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/CalendarData.cs b/src/mscorlib/corefx/System/Globalization/CalendarData.cs
deleted file mode 100644
index d22bd67ac1..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CalendarData.cs
+++ /dev/null
@@ -1,377 +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.Diagnostics;
-
-namespace System.Globalization
-{
- // List of calendar data
- // Note the we cache overrides.
- // Note that localized names (resource names) aren't available from here.
- //
- // NOTE: Calendars depend on the locale name that creates it. Only a few
- // properties are available without locales using CalendarData.GetCalendar(CalendarData)
-
- internal partial class CalendarData
- {
- // Max calendars
- internal const int MAX_CALENDARS = 23;
-
- // Identity
- internal String sNativeName; // Calendar Name for the locale
-
- // Formats
- internal String[] saShortDates; // Short Data format, default first
- internal String[] saYearMonths; // Year/Month Data format, default first
- internal String[] saLongDates; // Long Data format, default first
- internal String sMonthDay; // Month/Day format
-
- // Calendar Parts Names
- internal String[] saEraNames; // Names of Eras
- internal String[] saAbbrevEraNames; // Abbreviated Era Names
- internal String[] saAbbrevEnglishEraNames; // Abbreviated Era Names in English
- internal String[] saDayNames; // Day Names, null to use locale data, starts on Sunday
- internal String[] saAbbrevDayNames; // Abbrev Day Names, null to use locale data, starts on Sunday
- internal String[] saSuperShortDayNames; // Super short Day of week names
- internal String[] saMonthNames; // Month Names (13)
- internal String[] saAbbrevMonthNames; // Abbrev Month Names (13)
- internal String[] saMonthGenitiveNames; // Genitive Month Names (13)
- internal String[] saAbbrevMonthGenitiveNames; // Genitive Abbrev Month Names (13)
- internal String[] saLeapYearMonthNames; // Multiple strings for the month names in a leap year.
-
- // Integers at end to make marshaller happier
- internal int iTwoDigitYearMax = 2029; // Max 2 digit year (for Y2K bug data entry)
- internal int iCurrentEra = 0; // current era # (usually 1)
-
- // Use overrides?
- internal bool bUseUserOverrides; // True if we want user overrides.
-
- // Static invariant for the invariant locale
- internal static CalendarData Invariant;
-
- // Private constructor
- private CalendarData() { }
-
- // Invariant constructor
- static CalendarData()
- {
- // Set our default/gregorian US calendar data
- // Calendar IDs are 1-based, arrays are 0 based.
- CalendarData invariant = new CalendarData();
-
- // Set default data for calendar
- // Note that we don't load resources since this IS NOT supposed to change (by definition)
- invariant.sNativeName = "Gregorian Calendar"; // Calendar Name
-
- // Year
- invariant.iTwoDigitYearMax = 2029; // Max 2 digit year (for Y2K bug data entry)
- invariant.iCurrentEra = 1; // Current era #
-
- // Formats
- invariant.saShortDates = new String[] { "MM/dd/yyyy", "yyyy-MM-dd" }; // short date format
- invariant.saLongDates = new String[] { "dddd, dd MMMM yyyy" }; // long date format
- invariant.saYearMonths = new String[] { "yyyy MMMM" }; // year month format
- invariant.sMonthDay = "MMMM dd"; // Month day pattern
-
- // Calendar Parts Names
- invariant.saEraNames = new String[] { "A.D." }; // Era names
- invariant.saAbbrevEraNames = new String[] { "AD" }; // Abbreviated Era names
- invariant.saAbbrevEnglishEraNames = new String[] { "AD" }; // Abbreviated era names in English
- invariant.saDayNames = new String[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };// day names
- invariant.saAbbrevDayNames = new String[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; // abbreviated day names
- invariant.saSuperShortDayNames = new String[] { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" }; // The super short day names
- invariant.saMonthNames = new String[] { "January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December", String.Empty}; // month names
- invariant.saAbbrevMonthNames = new String[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", String.Empty}; // abbreviated month names
- invariant.saMonthGenitiveNames = invariant.saMonthNames; // Genitive month names (same as month names for invariant)
- invariant.saAbbrevMonthGenitiveNames = invariant.saAbbrevMonthNames; // Abbreviated genitive month names (same as abbrev month names for invariant)
- invariant.saLeapYearMonthNames = invariant.saMonthNames; // leap year month names are unused in Gregorian English (invariant)
-
- invariant.bUseUserOverrides = false;
-
- // Calendar was built, go ahead and assign it...
- Invariant = invariant;
- }
-
- //
- // Get a bunch of data for a calendar
- //
- internal CalendarData(String localeName, CalendarId calendarId, bool bUseUserOverrides)
- {
- this.bUseUserOverrides = bUseUserOverrides;
-
- if (!LoadCalendarDataFromSystem(localeName, calendarId))
- {
- Debug.Assert(false, "[CalendarData] LoadCalendarDataFromSystem call isn't expected to fail for calendar " + calendarId + " locale " + localeName);
-
- // Something failed, try invariant for missing parts
- // This is really not good, but we don't want the callers to crash.
- if (this.sNativeName == null) this.sNativeName = String.Empty; // Calendar Name for the locale.
-
- // Formats
- if (this.saShortDates == null) this.saShortDates = Invariant.saShortDates; // Short Data format, default first
- if (this.saYearMonths == null) this.saYearMonths = Invariant.saYearMonths; // Year/Month Data format, default first
- if (this.saLongDates == null) this.saLongDates = Invariant.saLongDates; // Long Data format, default first
- if (this.sMonthDay == null) this.sMonthDay = Invariant.sMonthDay; // Month/Day format
-
- // Calendar Parts Names
- if (this.saEraNames == null) this.saEraNames = Invariant.saEraNames; // Names of Eras
- if (this.saAbbrevEraNames == null) this.saAbbrevEraNames = Invariant.saAbbrevEraNames; // Abbreviated Era Names
- if (this.saAbbrevEnglishEraNames == null) this.saAbbrevEnglishEraNames = Invariant.saAbbrevEnglishEraNames; // Abbreviated Era Names in English
- if (this.saDayNames == null) this.saDayNames = Invariant.saDayNames; // Day Names, null to use locale data, starts on Sunday
- if (this.saAbbrevDayNames == null) this.saAbbrevDayNames = Invariant.saAbbrevDayNames; // Abbrev Day Names, null to use locale data, starts on Sunday
- if (this.saSuperShortDayNames == null) this.saSuperShortDayNames = Invariant.saSuperShortDayNames; // Super short Day of week names
- if (this.saMonthNames == null) this.saMonthNames = Invariant.saMonthNames; // Month Names (13)
- if (this.saAbbrevMonthNames == null) this.saAbbrevMonthNames = Invariant.saAbbrevMonthNames; // Abbrev Month Names (13)
- // Genitive and Leap names can follow the fallback below
- }
-
- if (calendarId == CalendarId.TAIWAN)
- {
- if (SystemSupportsTaiwaneseCalendar())
- {
- // We got the month/day names from the OS (same as gregorian), but the native name is wrong
- this.sNativeName = "\x4e2d\x83ef\x6c11\x570b\x66c6";
- }
- else
- {
- this.sNativeName = String.Empty;
- }
- }
-
- // Check for null genitive names (in case unmanaged side skips it for non-gregorian calendars, etc)
- if (this.saMonthGenitiveNames == null || this.saMonthGenitiveNames.Length == 0 || String.IsNullOrEmpty(this.saMonthGenitiveNames[0]))
- this.saMonthGenitiveNames = this.saMonthNames; // Genitive month names (same as month names for invariant)
- if (this.saAbbrevMonthGenitiveNames == null || this.saAbbrevMonthGenitiveNames.Length == 0 || String.IsNullOrEmpty(this.saAbbrevMonthGenitiveNames[0]))
- this.saAbbrevMonthGenitiveNames = this.saAbbrevMonthNames; // Abbreviated genitive month names (same as abbrev month names for invariant)
- if (this.saLeapYearMonthNames == null || this.saLeapYearMonthNames.Length == 0 || String.IsNullOrEmpty(this.saLeapYearMonthNames[0]))
- this.saLeapYearMonthNames = this.saMonthNames;
-
- InitializeEraNames(localeName, calendarId);
-
- InitializeAbbreviatedEraNames(localeName, calendarId);
-
- // Abbreviated English Era Names are only used for the Japanese calendar.
- if (calendarId == CalendarId.JAPAN)
- {
- this.saAbbrevEnglishEraNames = JapaneseCalendar.EnglishEraNames();
- }
- else
- {
- // For all others just use the an empty string (doesn't matter we'll never ask for it for other calendars)
- this.saAbbrevEnglishEraNames = new String[] { "" };
- }
-
- // Japanese is the only thing with > 1 era. Its current era # is how many ever
- // eras are in the array. (And the others all have 1 string in the array)
- this.iCurrentEra = this.saEraNames.Length;
- }
-
- private void InitializeEraNames(string localeName, CalendarId calendarId)
- {
- // Note that the saEraNames only include "A.D." We don't have localized names for other calendars available from windows
- switch (calendarId)
- {
- // For Localized Gregorian we really expect the data from the OS.
- case CalendarId.GREGORIAN:
- // Fallback for CoreCLR < Win7 or culture.dll missing
- if (this.saEraNames == null || this.saEraNames.Length == 0 || String.IsNullOrEmpty(this.saEraNames[0]))
- {
- this.saEraNames = new String[] { "A.D." };
- }
- break;
-
- // The rest of the calendars have constant data, so we'll just use that
- case CalendarId.GREGORIAN_US:
- case CalendarId.JULIAN:
- this.saEraNames = new String[] { "A.D." };
- break;
- case CalendarId.HEBREW:
- this.saEraNames = new String[] { "C.E." };
- break;
- case CalendarId.HIJRI:
- case CalendarId.UMALQURA:
- if (localeName == "dv-MV")
- {
- // Special case for Divehi
- this.saEraNames = new String[] { "\x0780\x07a8\x0796\x07b0\x0783\x07a9" };
- }
- else
- {
- this.saEraNames = new String[] { "\x0628\x0639\x062F \x0627\x0644\x0647\x062C\x0631\x0629" };
- }
- break;
- case CalendarId.GREGORIAN_ARABIC:
- case CalendarId.GREGORIAN_XLIT_ENGLISH:
- case CalendarId.GREGORIAN_XLIT_FRENCH:
- // These are all the same:
- this.saEraNames = new String[] { "\x0645" };
- break;
-
- case CalendarId.GREGORIAN_ME_FRENCH:
- this.saEraNames = new String[] { "ap. J.-C." };
- break;
-
- case CalendarId.TAIWAN:
- if (SystemSupportsTaiwaneseCalendar())
- {
- this.saEraNames = new String[] { "\x4e2d\x83ef\x6c11\x570b" };
- }
- else
- {
- this.saEraNames = new String[] { String.Empty };
- }
- break;
-
- case CalendarId.KOREA:
- this.saEraNames = new String[] { "\xb2e8\xae30" };
- break;
-
- case CalendarId.THAI:
- this.saEraNames = new String[] { "\x0e1e\x002e\x0e28\x002e" };
- break;
-
- case CalendarId.JAPAN:
- case CalendarId.JAPANESELUNISOLAR:
- this.saEraNames = JapaneseCalendar.EraNames();
- break;
-
- case CalendarId.PERSIAN:
- if (this.saEraNames == null || this.saEraNames.Length == 0 || String.IsNullOrEmpty(this.saEraNames[0]))
- {
- this.saEraNames = new String[] { "\x0647\x002e\x0634" };
- }
- break;
-
- default:
- // Most calendars are just "A.D."
- this.saEraNames = Invariant.saEraNames;
- break;
- }
- }
-
- private void InitializeAbbreviatedEraNames(string localeName, CalendarId calendarId)
- {
- // Note that the saAbbrevEraNames only include "AD" We don't have localized names for other calendars available from windows
- switch (calendarId)
- {
- // For Localized Gregorian we really expect the data from the OS.
- case CalendarId.GREGORIAN:
- // Fallback for CoreCLR < Win7 or culture.dll missing
- if (this.saAbbrevEraNames == null || this.saAbbrevEraNames.Length == 0 || String.IsNullOrEmpty(this.saAbbrevEraNames[0]))
- {
- this.saAbbrevEraNames = new String[] { "AD" };
- }
- break;
-
- // The rest of the calendars have constant data, so we'll just use that
- case CalendarId.GREGORIAN_US:
- case CalendarId.JULIAN:
- this.saAbbrevEraNames = new String[] { "AD" };
- break;
- case CalendarId.JAPAN:
- case CalendarId.JAPANESELUNISOLAR:
- this.saAbbrevEraNames = JapaneseCalendar.AbbrevEraNames();
- break;
- case CalendarId.HIJRI:
- case CalendarId.UMALQURA:
- if (localeName == "dv-MV")
- {
- // Special case for Divehi
- this.saAbbrevEraNames = new String[] { "\x0780\x002e" };
- }
- else
- {
- this.saAbbrevEraNames = new String[] { "\x0647\x0640" };
- }
- break;
- case CalendarId.TAIWAN:
- // Get era name and abbreviate it
- this.saAbbrevEraNames = new String[1];
- if (this.saEraNames[0].Length == 4)
- {
- this.saAbbrevEraNames[0] = this.saEraNames[0].Substring(2, 2);
- }
- else
- {
- this.saAbbrevEraNames[0] = this.saEraNames[0];
- }
- break;
-
- case CalendarId.PERSIAN:
- if (this.saAbbrevEraNames == null || this.saAbbrevEraNames.Length == 0 || String.IsNullOrEmpty(this.saAbbrevEraNames[0]))
- {
- this.saAbbrevEraNames = this.saEraNames;
- }
- break;
-
- default:
- // Most calendars just use the full name
- this.saAbbrevEraNames = this.saEraNames;
- break;
- }
- }
-
- internal static CalendarData GetCalendarData(CalendarId calendarId)
- {
- //
- // Get a calendar.
- // Unfortunately we depend on the locale in the OS, so we need a locale
- // no matter what. So just get the appropriate calendar from the
- // appropriate locale here
- //
-
- // Get a culture name
- // TODO: Note that this doesn't handle the new calendars (lunisolar, etc)
- String culture = CalendarIdToCultureName(calendarId);
-
- // Return our calendar
- return CultureInfo.GetCultureInfo(culture).m_cultureData.GetCalendar(calendarId);
- }
-
- private static String CalendarIdToCultureName(CalendarId calendarId)
- {
- switch (calendarId)
- {
- case CalendarId.GREGORIAN_US:
- return "fa-IR"; // "fa-IR" Iran
-
- case CalendarId.JAPAN:
- return "ja-JP"; // "ja-JP" Japan
-
- case CalendarId.TAIWAN:
- return "zh-TW"; // zh-TW Taiwan
-
- case CalendarId.KOREA:
- return "ko-KR"; // "ko-KR" Korea
-
- case CalendarId.HIJRI:
- case CalendarId.GREGORIAN_ARABIC:
- case CalendarId.UMALQURA:
- return "ar-SA"; // "ar-SA" Saudi Arabia
-
- case CalendarId.THAI:
- return "th-TH"; // "th-TH" Thailand
-
- case CalendarId.HEBREW:
- return "he-IL"; // "he-IL" Israel
-
- case CalendarId.GREGORIAN_ME_FRENCH:
- return "ar-DZ"; // "ar-DZ" Algeria
-
- case CalendarId.GREGORIAN_XLIT_ENGLISH:
- case CalendarId.GREGORIAN_XLIT_FRENCH:
- return "ar-IQ"; // "ar-IQ"; Iraq
-
- default:
- // Default to gregorian en-US
- break;
- }
-
- return "en-US";
- }
- }
-}
-
diff --git a/src/mscorlib/corefx/System/Globalization/CalendarWeekRule.cs b/src/mscorlib/corefx/System/Globalization/CalendarWeekRule.cs
deleted file mode 100644
index 4013ce7237..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CalendarWeekRule.cs
+++ /dev/null
@@ -1,18 +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;
-
-namespace System.Globalization
-{
- [Serializable]
- public enum CalendarWeekRule
- {
- FirstDay = 0, // Week 1 begins on the first day of the year
-
- FirstFullWeek = 1, // Week 1 begins on first FirstDayOfWeek not before the first day of the year
-
- FirstFourDayWeek = 2 // Week 1 begins on first FirstDayOfWeek such that FirstDayOfWeek+3 is not before the first day of the year
- };
-}
diff --git a/src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs b/src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs
deleted file mode 100644
index 38ce441a78..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CharUnicodeInfo.cs
+++ /dev/null
@@ -1,391 +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.
-
-////////////////////////////////////////////////////////////////////////////
-//
-//
-// Purpose: This class implements a set of methods for retrieving
-// character type information. Character type information is
-// independent of culture and region.
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-
-namespace System.Globalization
-{
- public static partial class CharUnicodeInfo
- {
- //--------------------------------------------------------------------//
- // Internal Information //
- //--------------------------------------------------------------------//
-
- //
- // Native methods to access the Unicode category data tables in charinfo.nlp.
- //
- internal const char HIGH_SURROGATE_START = '\ud800';
- internal const char HIGH_SURROGATE_END = '\udbff';
- internal const char LOW_SURROGATE_START = '\udc00';
- internal const char LOW_SURROGATE_END = '\udfff';
-
- internal const int UNICODE_CATEGORY_OFFSET = 0;
- internal const int BIDI_CATEGORY_OFFSET = 1;
-
-
-
- // The starting codepoint for Unicode plane 1. Plane 1 contains 0x010000 ~ 0x01ffff.
- internal const int UNICODE_PLANE01_START = 0x10000;
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Actions:
- // Convert the BMP character or surrogate pointed by index to a UTF32 value.
- // This is similar to Char.ConvertToUTF32, but the difference is that
- // it does not throw exceptions when invalid surrogate characters are passed in.
- //
- // WARNING: since it doesn't throw an exception it CAN return a value
- // in the surrogate range D800-DFFF, which are not legal unicode values.
- //
- ////////////////////////////////////////////////////////////////////////
-
- internal static int InternalConvertToUtf32(String s, int index)
- {
- Debug.Assert(s != null, "s != null");
- Debug.Assert(index >= 0 && index < s.Length, "index < s.Length");
- if (index < s.Length - 1)
- {
- int temp1 = (int)s[index] - HIGH_SURROGATE_START;
- if (temp1 >= 0 && temp1 <= 0x3ff)
- {
- int temp2 = (int)s[index + 1] - LOW_SURROGATE_START;
- if (temp2 >= 0 && temp2 <= 0x3ff)
- {
- // Convert the surrogate to UTF32 and get the result.
- return ((temp1 * 0x400) + temp2 + UNICODE_PLANE01_START);
- }
- }
- }
- return ((int)s[index]);
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Convert a character or a surrogate pair starting at index of string s
- // to UTF32 value.
- //
- // Parameters:
- // s The string
- // index The starting index. It can point to a BMP character or
- // a surrogate pair.
- // len The length of the string.
- // charLength [out] If the index points to a BMP char, charLength
- // will be 1. If the index points to a surrogate pair,
- // charLength will be 2.
- //
- // WARNING: since it doesn't throw an exception it CAN return a value
- // in the surrogate range D800-DFFF, which are not legal unicode values.
- //
- // Returns:
- // The UTF32 value
- //
- ////////////////////////////////////////////////////////////////////////
-
- internal static int InternalConvertToUtf32(String s, int index, out int charLength)
- {
- Debug.Assert(s != null, "s != null");
- Debug.Assert(s.Length > 0, "s.Length > 0");
- Debug.Assert(index >= 0 && index < s.Length, "index >= 0 && index < s.Length");
- charLength = 1;
- if (index < s.Length - 1)
- {
- int temp1 = (int)s[index] - HIGH_SURROGATE_START;
- if (temp1 >= 0 && temp1 <= 0x3ff)
- {
- int temp2 = (int)s[index + 1] - LOW_SURROGATE_START;
- if (temp2 >= 0 && temp2 <= 0x3ff)
- {
- // Convert the surrogate to UTF32 and get the result.
- charLength++;
- return ((temp1 * 0x400) + temp2 + UNICODE_PLANE01_START);
- }
- }
- }
- return ((int)s[index]);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // IsWhiteSpace
- //
- // Determines if the given character is a white space character.
- //
- ////////////////////////////////////////////////////////////////////////
-
- internal static bool IsWhiteSpace(String s, int index)
- {
- Debug.Assert(s != null, "s!=null");
- Debug.Assert(index >= 0 && index < s.Length, "index >= 0 && index < s.Length");
-
- UnicodeCategory uc = GetUnicodeCategory(s, index);
- // In Unicode 3.0, U+2028 is the only character which is under the category "LineSeparator".
- // And U+2029 is th eonly character which is under the category "ParagraphSeparator".
- switch (uc)
- {
- case (UnicodeCategory.SpaceSeparator):
- case (UnicodeCategory.LineSeparator):
- case (UnicodeCategory.ParagraphSeparator):
- return (true);
- }
- return (false);
- }
-
-
- internal static bool IsWhiteSpace(char c)
- {
- UnicodeCategory uc = GetUnicodeCategory(c);
- // In Unicode 3.0, U+2028 is the only character which is under the category "LineSeparator".
- // And U+2029 is th eonly character which is under the category "ParagraphSeparator".
- switch (uc)
- {
- case (UnicodeCategory.SpaceSeparator):
- case (UnicodeCategory.LineSeparator):
- case (UnicodeCategory.ParagraphSeparator):
- return (true);
- }
-
- return (false);
- }
-
-
- //
- // This is called by the public char and string, index versions
- //
- // Note that for ch in the range D800-DFFF we just treat it as any other non-numeric character
- //
- internal static unsafe double InternalGetNumericValue(int ch)
- {
- Debug.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range.");
- // Get the level 2 item from the highest 12 bit (8 - 19) of ch.
- ushort index = s_pNumericLevel1Index[ch >> 8];
- // Get the level 2 WORD offset from the 4 - 7 bit of ch. This provides the base offset of the level 3 table.
- // The offset is referred to an float item in m_pNumericFloatData.
- // Note that & has the lower precedence than addition, so don't forget the parathesis.
- index = s_pNumericLevel1Index[index + ((ch >> 4) & 0x000f)];
-
- fixed (ushort* pUshortPtr = &(s_pNumericLevel1Index[index]))
- {
- byte* pBytePtr = (byte*)pUshortPtr;
- fixed (byte* pByteNum = s_pNumericValues)
- {
- double* pDouble = (double*)pByteNum;
- return pDouble[pBytePtr[(ch & 0x000f)]];
- }
- }
- }
-
- internal static unsafe ushort InternalGetDigitValues(int ch)
- {
- Debug.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range.");
- // Get the level 2 item from the highest 12 bit (8 - 19) of ch.
- ushort index = s_pNumericLevel1Index[ch >> 8];
- // Get the level 2 WORD offset from the 4 - 7 bit of ch. This provides the base offset of the level 3 table.
- // Note that & has the lower precedence than addition, so don't forget the parathesis.
- index = s_pNumericLevel1Index[index + ((ch >> 4) & 0x000f)];
-
- fixed (ushort* pUshortPtr = &(s_pNumericLevel1Index[index]))
- {
- byte* pBytePtr = (byte*)pUshortPtr;
- return s_pDigitValues[pBytePtr[(ch & 0x000f)]];
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- //Returns the numeric value associated with the character c. If the character is a fraction,
- // the return value will not be an integer. If the character does not have a numeric value, the return value is -1.
- //
- //Returns:
- // the numeric value for the specified Unicode character. If the character does not have a numeric value, the return value is -1.
- //Arguments:
- // ch a Unicode character
- //Exceptions:
- // ArgumentNullException
- // ArgumentOutOfRangeException
- //
- ////////////////////////////////////////////////////////////////////////
-
-
- public static double GetNumericValue(char ch)
- {
- return (InternalGetNumericValue(ch));
- }
-
-
- public static double GetNumericValue(String s, int index)
- {
- if (s == null)
- {
- throw new ArgumentNullException(nameof(s));
- }
- if (index < 0 || index >= s.Length)
- {
- throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
- }
- Contract.EndContractBlock();
- return (InternalGetNumericValue(InternalConvertToUtf32(s, index)));
- }
-
- public static int GetDecimalDigitValue(char ch)
- {
- return (sbyte)(InternalGetDigitValues(ch) >> 8);
- }
-
- public static int GetDecimalDigitValue(String s, int index)
- {
- if (s == null)
- {
- throw new ArgumentNullException(nameof(s));
- }
-
- if (index < 0 || index >= s.Length)
- {
- throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
- }
- Contract.EndContractBlock();
-
- return (sbyte)(InternalGetDigitValues(InternalConvertToUtf32(s, index)) >> 8);
- }
-
- public static int GetDigitValue(char ch)
- {
- return (sbyte)(InternalGetDigitValues(ch) & 0x00FF);
- }
-
- public static int GetDigitValue(String s, int index)
- {
- if (s == null)
- {
- throw new ArgumentNullException(nameof(s));
- }
-
- if (index < 0 || index >= s.Length)
- {
- throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
- }
-
- Contract.EndContractBlock();
- return (sbyte)(InternalGetDigitValues(InternalConvertToUtf32(s, index)) & 0x00FF);
- }
-
- public static UnicodeCategory GetUnicodeCategory(char ch)
- {
- return (InternalGetUnicodeCategory(ch));
- }
-
- public static UnicodeCategory GetUnicodeCategory(String s, int index)
- {
- if (s == null)
- throw new ArgumentNullException(nameof(s));
- if (((uint)index) >= ((uint)s.Length))
- {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- return InternalGetUnicodeCategory(s, index);
- }
-
- internal static unsafe UnicodeCategory InternalGetUnicodeCategory(int ch)
- {
- return ((UnicodeCategory)InternalGetCategoryValue(ch, UNICODE_CATEGORY_OFFSET));
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- //Action: Returns the Unicode Category property for the character c.
- //Returns:
- // an value in UnicodeCategory enum
- //Arguments:
- // ch a Unicode character
- //Exceptions:
- // None
- //
- //Note that this API will return values for D800-DF00 surrogate halves.
- //
- ////////////////////////////////////////////////////////////////////////
-
- internal static unsafe byte InternalGetCategoryValue(int ch, int offset)
- {
- Debug.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range.");
- // Get the level 2 item from the highest 12 bit (8 - 19) of ch.
- ushort index = s_pCategoryLevel1Index[ch >> 8];
- // Get the level 2 WORD offset from the 4 - 7 bit of ch. This provides the base offset of the level 3 table.
- // Note that & has the lower precedence than addition, so don't forget the parathesis.
- index = s_pCategoryLevel1Index[index + ((ch >> 4) & 0x000f)];
-
- fixed (ushort* pUshortPtr = &(s_pCategoryLevel1Index[index]))
- {
- byte* pBytePtr = (byte*)pUshortPtr;
- // Get the result from the 0 -3 bit of ch.
- byte valueIndex = pBytePtr[(ch & 0x000f)];
- byte uc = s_pCategoriesValue[valueIndex * 2 + offset];
- //
- // Make sure that OtherNotAssigned is the last category in UnicodeCategory.
- // If that changes, change the following assertion as well.
- //
- //Debug.Assert(uc >= 0 && uc <= UnicodeCategory.OtherNotAssigned, "Table returns incorrect Unicode category");
- return (uc);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- //Action: Returns the Unicode Category property for the character c.
- //Returns:
- // an value in UnicodeCategory enum
- //Arguments:
- // value a Unicode String
- // index Index for the specified string.
- //Exceptions:
- // None
- //
- ////////////////////////////////////////////////////////////////////////
-
- internal static UnicodeCategory InternalGetUnicodeCategory(String value, int index)
- {
- Debug.Assert(value != null, "value can not be null");
- Debug.Assert(index < value.Length, "index < value.Length");
-
- return (InternalGetUnicodeCategory(InternalConvertToUtf32(value, index)));
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Get the Unicode category of the character starting at index. If the character is in BMP, charLength will return 1.
- // If the character is a valid surrogate pair, charLength will return 2.
- //
- ////////////////////////////////////////////////////////////////////////
-
- internal static UnicodeCategory InternalGetUnicodeCategory(String str, int index, out int charLength)
- {
- Debug.Assert(str != null, "str can not be null");
- Debug.Assert(str.Length > 0, "str.Length > 0"); ;
- Debug.Assert(index >= 0 && index < str.Length, "index >= 0 && index < str.Length");
-
- return (InternalGetUnicodeCategory(InternalConvertToUtf32(str, index, out charLength)));
- }
-
- internal static bool IsCombiningCategory(UnicodeCategory uc)
- {
- Debug.Assert(uc >= 0, "uc >= 0");
- return (
- uc == UnicodeCategory.NonSpacingMark ||
- uc == UnicodeCategory.SpacingCombiningMark ||
- uc == UnicodeCategory.EnclosingMark
- );
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/ChineseLunisolarCalendar.cs b/src/mscorlib/corefx/System/Globalization/ChineseLunisolarCalendar.cs
deleted file mode 100644
index 5002555384..0000000000
--- a/src/mscorlib/corefx/System/Globalization/ChineseLunisolarCalendar.cs
+++ /dev/null
@@ -1,395 +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.Diagnostics.Contracts;
-
-namespace System.Globalization
-{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about ChineseLunisolarCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
- /*
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 1901/02/19 2101/01/28
- ** ChineseLunisolar 1901/01/01 2100/12/29
- */
- [Serializable]
- public class ChineseLunisolarCalendar : EastAsianLunisolarCalendar
- {
- //
- // The era value for the current era.
- //
-
- public const int ChineseEra = 1;
-
- internal const int MIN_LUNISOLAR_YEAR = 1901;
- internal const int MAX_LUNISOLAR_YEAR = 2100;
-
- internal const int MIN_GREGORIAN_YEAR = 1901;
- internal const int MIN_GREGORIAN_MONTH = 2;
- internal const int MIN_GREGORIAN_DAY = 19;
-
- internal const int MAX_GREGORIAN_YEAR = 2101;
- internal const int MAX_GREGORIAN_MONTH = 1;
- internal const int MAX_GREGORIAN_DAY = 28;
-
- internal static DateTime minDate = new DateTime(MIN_GREGORIAN_YEAR, MIN_GREGORIAN_MONTH, MIN_GREGORIAN_DAY);
- internal static DateTime maxDate = new DateTime((new DateTime(MAX_GREGORIAN_YEAR, MAX_GREGORIAN_MONTH, MAX_GREGORIAN_DAY, 23, 59, 59, 999)).Ticks + 9999);
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (minDate);
- }
- }
-
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (maxDate);
- }
- }
-
- protected override int DaysInYearBeforeMinSupportedYear
- {
- get
- {
- // 1900: 1-29 2-30 3-29 4-29 5-30 6-29 7-30 8-30 Leap8-29 9-30 10-30 11-29 12-30 from Calendrical Tabulations
- return 384;
- }
- }
-
-
- private static readonly int[,] s_yinfo =
- {
- /*Y LM Lmon Lday DaysPerMonth D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 #Days
- 1901 */
- { 0 , 2 , 19 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1902 */{ 0 , 2 , 8 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1903 */{ 5 , 1 , 29 , 21096 },/* 29 30 29 30 29 29 30 29 29 30 30 29 30 383
-1904 */{ 0 , 2 , 16 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1905 */{ 0 , 2 , 4 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1906 */{ 4 , 1 , 25 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
-1907 */{ 0 , 2 , 13 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1908 */{ 0 , 2 , 2 , 39632 },/* 30 29 29 30 30 29 30 29 30 30 29 30 0 355
-1909 */{ 2 , 1 , 22 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1910 */{ 0 , 2 , 10 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1911 */{ 6 , 1 , 30 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1912 */{ 0 , 2 , 18 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1913 */{ 0 , 2 , 6 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1914 */{ 5 , 1 , 26 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
-1915 */{ 0 , 2 , 14 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1916 */{ 0 , 2 , 3 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 0 355
-1917 */{ 2 , 1 , 23 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1918 */{ 0 , 2 , 11 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1919 */{ 7 , 2 , 1 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1920 */{ 0 , 2 , 20 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1921 */{ 0 , 2 , 8 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1922 */{ 5 , 1 , 28 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1923 */{ 0 , 2 , 16 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1924 */{ 0 , 2 , 5 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1925 */{ 4 , 1 , 24 , 44456 },/* 30 29 30 29 30 30 29 30 30 29 30 29 30 385
-1926 */{ 0 , 2 , 13 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1927 */{ 0 , 2 , 2 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 0 355
-1928 */{ 2 , 1 , 23 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
-1929 */{ 0 , 2 , 10 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1930 */{ 6 , 1 , 30 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
-1931 */{ 0 , 2 , 17 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1932 */{ 0 , 2 , 6 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-1933 */{ 5 , 1 , 26 , 27976 },/* 29 30 30 29 30 30 29 30 29 30 29 29 30 384
-1934 */{ 0 , 2 , 14 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
-1935 */{ 0 , 2 , 4 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1936 */{ 3 , 1 , 24 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
-1937 */{ 0 , 2 , 11 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1938 */{ 7 , 1 , 31 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-1939 */{ 0 , 2 , 19 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
-1940 */{ 0 , 2 , 8 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1941 */{ 6 , 1 , 27 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1942 */{ 0 , 2 , 15 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1943 */{ 0 , 2 , 5 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1944 */{ 4 , 1 , 25 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
-1945 */{ 0 , 2 , 13 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1946 */{ 0 , 2 , 2 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-1947 */{ 2 , 1 , 22 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-1948 */{ 0 , 2 , 10 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1949 */{ 7 , 1 , 29 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-1950 */{ 0 , 2 , 17 , 27808 },/* 29 30 30 29 30 30 29 29 30 29 30 29 0 354
-1951 */{ 0 , 2 , 6 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1952 */{ 5 , 1 , 27 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-1953 */{ 0 , 2 , 14 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
-1954 */{ 0 , 2 , 3 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-1955 */{ 3 , 1 , 24 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1956 */{ 0 , 2 , 12 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1957 */{ 8 , 1 , 31 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 29 383
-1958 */{ 0 , 2 , 18 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
-1959 */{ 0 , 2 , 8 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1960 */{ 6 , 1 , 28 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1961 */{ 0 , 2 , 15 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1962 */{ 0 , 2 , 5 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1963 */{ 4 , 1 , 25 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1964 */{ 0 , 2 , 13 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1965 */{ 0 , 2 , 2 , 21088 },/* 29 30 29 30 29 29 30 29 29 30 30 29 0 353
-1966 */{ 3 , 1 , 21 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-1967 */{ 0 , 2 , 9 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1968 */{ 7 , 1 , 30 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1969 */{ 0 , 2 , 17 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1970 */{ 0 , 2 , 6 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-1971 */{ 5 , 1 , 27 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1972 */{ 0 , 2 , 15 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
-1973 */{ 0 , 2 , 3 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1974 */{ 4 , 1 , 23 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1975 */{ 0 , 2 , 11 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1976 */{ 8 , 1 , 31 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
-1977 */{ 0 , 2 , 18 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1978 */{ 0 , 2 , 7 , 46752 },/* 30 29 30 30 29 30 30 29 30 29 30 29 0 355
-1979 */{ 6 , 1 , 28 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1980 */{ 0 , 2 , 16 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1981 */{ 0 , 2 , 5 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1982 */{ 4 , 1 , 25 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-1983 */{ 0 , 2 , 13 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1984 */{ 10 , 2 , 2 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1985 */{ 0 , 2 , 20 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1986 */{ 0 , 2 , 9 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1987 */{ 6 , 1 , 29 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 29 384
-1988 */{ 0 , 2 , 17 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1989 */{ 0 , 2 , 6 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 0 355
-1990 */{ 5 , 1 , 27 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
-1991 */{ 0 , 2 , 15 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1992 */{ 0 , 2 , 4 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1993 */{ 3 , 1 , 23 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1994 */{ 0 , 2 , 10 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-1995 */{ 8 , 1 , 31 , 27432 },/* 29 30 30 29 30 29 30 30 29 29 30 29 30 384
-1996 */{ 0 , 2 , 19 , 23232 },/* 29 30 29 30 30 29 30 29 30 30 29 29 0 354
-1997 */{ 0 , 2 , 7 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1998 */{ 5 , 1 , 28 , 37736 },/* 30 29 29 30 29 29 30 30 29 30 30 29 30 384
-1999 */{ 0 , 2 , 16 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-2000 */{ 0 , 2 , 5 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-2001 */{ 4 , 1 , 24 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-2002 */{ 0 , 2 , 12 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-2003 */{ 0 , 2 , 1 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-2004 */{ 2 , 1 , 22 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-2005 */{ 0 , 2 , 9 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-2006 */{ 7 , 1 , 29 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
-2007 */{ 0 , 2 , 18 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-2008 */{ 0 , 2 , 7 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-2009 */{ 5 , 1 , 26 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-2010 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-2011 */{ 0 , 2 , 3 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-2012 */{ 4 , 1 , 23 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-2013 */{ 0 , 2 , 10 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2014 */{ 9 , 1 , 31 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-2015 */{ 0 , 2 , 19 , 19360 },/* 29 30 29 29 30 29 30 30 30 29 30 29 0 354
-2016 */{ 0 , 2 , 8 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-2017 */{ 6 , 1 , 28 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-2018 */{ 0 , 2 , 16 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-2019 */{ 0 , 2 , 5 , 43312 },/* 30 29 30 29 30 29 29 30 29 29 30 30 0 354
-2020 */{ 4 , 1 , 25 , 29864 },/* 29 30 30 30 29 30 29 29 30 29 30 29 30 384
-2021 */{ 0 , 2 , 12 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-2022 */{ 0 , 2 , 1 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2023 */{ 2 , 1 , 22 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
-2024 */{ 0 , 2 , 10 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-2025 */{ 6 , 1 , 29 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-2026 */{ 0 , 2 , 17 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
-2027 */{ 0 , 2 , 6 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-2028 */{ 5 , 1 , 26 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-2029 */{ 0 , 2 , 13 , 54576 },/* 30 30 29 30 29 30 29 30 29 29 30 30 0 355
-2030 */{ 0 , 2 , 3 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-2031 */{ 3 , 1 , 23 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
-2032 */{ 0 , 2 , 11 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-2033 */{ 11 , 1 , 31 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-2034 */{ 0 , 2 , 19 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
-2035 */{ 0 , 2 , 8 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-2036 */{ 6 , 1 , 28 , 53848 },/* 30 30 29 30 29 29 30 29 29 30 29 30 30 384
-2037 */{ 0 , 2 , 15 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-2038 */{ 0 , 2 , 4 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
-2039 */{ 5 , 1 , 24 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 29 384
-2040 */{ 0 , 2 , 12 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
-2041 */{ 0 , 2 , 1 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-2042 */{ 2 , 1 , 22 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
-2043 */{ 0 , 2 , 10 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-2044 */{ 7 , 1 , 30 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-2045 */{ 0 , 2 , 17 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-2046 */{ 0 , 2 , 6 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-2047 */{ 5 , 1 , 26 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-2048 */{ 0 , 2 , 14 , 27936 },/* 29 30 30 29 30 30 29 30 29 29 30 29 0 354
-2049 */{ 0 , 2 , 2 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
-2050 */{ 3 , 1 , 23 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-2051 */{ 0 , 2 , 11 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-2052 */{ 8 , 2 , 1 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
-2053 */{ 0 , 2 , 19 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-2054 */{ 0 , 2 , 8 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-2055 */{ 6 , 1 , 28 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-2056 */{ 0 , 2 , 15 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-2057 */{ 0 , 2 , 4 , 27424 },/* 29 30 30 29 30 29 30 30 29 29 30 29 0 354
-2058 */{ 4 , 1 , 24 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 29 384
-2059 */{ 0 , 2 , 12 , 43744 },/* 30 29 30 29 30 29 30 29 30 30 30 29 0 355
-2060 */{ 0 , 2 , 2 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-2061 */{ 3 , 1 , 21 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 29 384
-2062 */{ 0 , 2 , 9 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-2063 */{ 7 , 1 , 29 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-2064 */{ 0 , 2 , 17 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-2065 */{ 0 , 2 , 5 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-2066 */{ 5 , 1 , 26 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-2067 */{ 0 , 2 , 14 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-2068 */{ 0 , 2 , 3 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
-2069 */{ 4 , 1 , 23 , 21224 },/* 29 30 29 30 29 29 30 29 30 30 30 29 30 384
-2070 */{ 0 , 2 , 11 , 21200 },/* 29 30 29 30 29 29 30 29 30 30 29 30 0 354
-2071 */{ 8 , 1 , 31 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-2072 */{ 0 , 2 , 19 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-2073 */{ 0 , 2 , 7 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-2074 */{ 6 , 1 , 27 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-2075 */{ 0 , 2 , 15 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2076 */{ 0 , 2 , 5 , 21920 },/* 29 30 29 30 29 30 29 30 30 29 30 29 0 354
-2077 */{ 4 , 1 , 24 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 29 384
-2078 */{ 0 , 2 , 12 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-2079 */{ 0 , 2 , 2 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-2080 */{ 3 , 1 , 22 , 43320 },/* 30 29 30 29 30 29 29 30 29 29 30 30 30 384
-2081 */{ 0 , 2 , 9 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 0 354
-2082 */{ 7 , 1 , 29 , 29336 },/* 29 30 30 30 29 29 30 29 30 29 29 30 30 384
-2083 */{ 0 , 2 , 17 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-2084 */{ 0 , 2 , 6 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2085 */{ 5 , 1 , 26 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
-2086 */{ 0 , 2 , 14 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-2087 */{ 0 , 2 , 3 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-2088 */{ 4 , 1 , 24 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 29 383
-2089 */{ 0 , 2 , 10 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-2090 */{ 8 , 1 , 30 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-2091 */{ 0 , 2 , 18 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
-2092 */{ 0 , 2 , 7 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
-2093 */{ 6 , 1 , 27 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
-2094 */{ 0 , 2 , 15 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-2095 */{ 0 , 2 , 5 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-2096 */{ 4 , 1 , 25 , 42216 },/* 30 29 30 29 29 30 29 29 30 30 30 29 30 384
-2097 */{ 0 , 2 , 12 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-2098 */{ 0 , 2 , 1 , 53584 },/* 30 30 29 30 29 29 29 30 29 30 29 30 0 354
-2099 */{ 2 , 1 , 21 , 55592 },/* 30 30 29 30 30 29 29 30 29 29 30 29 30 384
-2100 */{ 0 , 2 , 9 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
- */};
-
-
- internal override int MinCalendarYear
- {
- get
- {
- return (MIN_LUNISOLAR_YEAR);
- }
- }
-
- internal override int MaxCalendarYear
- {
- get
- {
- return (MAX_LUNISOLAR_YEAR);
- }
- }
-
- internal override DateTime MinDate
- {
- get
- {
- return (minDate);
- }
- }
-
- internal override DateTime MaxDate
- {
- get
- {
- return (maxDate);
- }
- }
-
- internal override EraInfo[] CalEraInfo
- {
- get
- {
- return (null);
- }
- }
-
- internal override int GetYearInfo(int lunarYear, int index)
- {
- if ((lunarYear < MIN_LUNISOLAR_YEAR) || (lunarYear > MAX_LUNISOLAR_YEAR))
- {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range, MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR));
- }
- Contract.EndContractBlock();
-
- return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index];
- }
-
- internal override int GetYear(int year, DateTime time)
- {
- return year;
- }
-
- internal override int GetGregorianYear(int year, int era)
- {
- if (era != CurrentEra && era != ChineseEra)
- {
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
-
- if (year < MIN_LUNISOLAR_YEAR || year > MAX_LUNISOLAR_YEAR)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range, MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR));
- }
- Contract.EndContractBlock();
-
- return year;
- }
-
- public ChineseLunisolarCalendar()
- {
- }
-
- public override int GetEra(DateTime time)
- {
- CheckTicksRange(time.Ticks);
- return (ChineseEra);
- }
-
- internal override CalendarId ID
- {
- get
- {
- return (CalendarId.CHINESELUNISOLAR);
- }
- }
-
- internal override CalendarId BaseCalendarID
- {
- get
- {
- //Use CAL_GREGORIAN just to get CurrentEraValue as 1 since we do not have data under the ID CAL_ChineseLunisolar yet
- return (CalendarId.GREGORIAN);
- }
- }
-
-
- public override int[] Eras
- {
- get
- {
- return (new int[] { ChineseEra });
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs b/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs
deleted file mode 100644
index 21c3c9f7e4..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs
+++ /dev/null
@@ -1,397 +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.Diagnostics;
-using System.Diagnostics.Contracts;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Security;
-
-namespace System.Globalization
-{
- public partial class CompareInfo
- {
- [NonSerialized]
- private Interop.GlobalizationInterop.SafeSortHandle _sortHandle;
-
- [NonSerialized]
- private bool _isAsciiEqualityOrdinal;
-
- internal CompareInfo(CultureInfo culture)
- {
- _name = culture.m_name;
- InitSort(culture);
- }
-
- private void InitSort(CultureInfo culture)
- {
- _sortName = culture.SortName;
- Interop.GlobalizationInterop.ResultCode resultCode = Interop.GlobalizationInterop.GetSortHandle(GetNullTerminatedUtf8String(_sortName), out _sortHandle);
- if (resultCode != Interop.GlobalizationInterop.ResultCode.Success)
- {
- _sortHandle.Dispose();
-
- if (resultCode == Interop.GlobalizationInterop.ResultCode.OutOfMemory)
- throw new OutOfMemoryException();
-
- throw new ExternalException(SR.Arg_ExternalException);
- }
- _isAsciiEqualityOrdinal = (_sortName == "en-US" || _sortName == "");
- }
-
- internal static unsafe int IndexOfOrdinal(string source, string value, int startIndex, int count, bool ignoreCase)
- {
- Debug.Assert(source != null);
- Debug.Assert(value != null);
-
- if (value.Length == 0)
- {
- return startIndex;
- }
-
- if (count < value.Length)
- {
- return -1;
- }
-
- if (ignoreCase)
- {
- fixed (char* pSource = source)
- {
- int index = Interop.GlobalizationInterop.IndexOfOrdinalIgnoreCase(value, value.Length, pSource + startIndex, count, findLast: false);
- return index != -1 ?
- startIndex + index :
- -1;
- }
- }
-
- int endIndex = startIndex + (count - value.Length);
- for (int i = startIndex; i <= endIndex; i++)
- {
- int valueIndex, sourceIndex;
-
- for (valueIndex = 0, sourceIndex = i;
- valueIndex < value.Length && source[sourceIndex] == value[valueIndex];
- valueIndex++, sourceIndex++) ;
-
- if (valueIndex == value.Length)
- {
- return i;
- }
- }
-
- return -1;
- }
-
- internal static unsafe int LastIndexOfOrdinal(string source, string value, int startIndex, int count, bool ignoreCase)
- {
- Debug.Assert(source != null);
- Debug.Assert(value != null);
-
- if (value.Length == 0)
- {
- return startIndex;
- }
-
- if (count < value.Length)
- {
- return -1;
- }
-
- // startIndex is the index into source where we start search backwards from.
- // leftStartIndex is the index into source of the start of the string that is
- // count characters away from startIndex.
- int leftStartIndex = startIndex - count + 1;
-
- if (ignoreCase)
- {
- fixed (char* pSource = source)
- {
- int lastIndex = Interop.GlobalizationInterop.IndexOfOrdinalIgnoreCase(value, value.Length, pSource + leftStartIndex, count, findLast: true);
- return lastIndex != -1 ?
- leftStartIndex + lastIndex :
- -1;
- }
- }
-
- for (int i = startIndex - value.Length + 1; i >= leftStartIndex; i--)
- {
- int valueIndex, sourceIndex;
-
- for (valueIndex = 0, sourceIndex = i;
- valueIndex < value.Length && source[sourceIndex] == value[valueIndex];
- valueIndex++, sourceIndex++) ;
-
- if (valueIndex == value.Length) {
- return i;
- }
- }
-
- return -1;
- }
-
- private int GetHashCodeOfStringCore(string source, CompareOptions options)
- {
- Debug.Assert(source != null);
- Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
-
- return GetHashCodeOfStringCore(source, options, forceRandomizedHashing: false, additionalEntropy: 0);
- }
-
- private static unsafe int CompareStringOrdinalIgnoreCase(char* string1, int count1, char* string2, int count2)
- {
- return Interop.GlobalizationInterop.CompareStringOrdinalIgnoreCase(string1, count1, string2, count2);
- }
-
- private unsafe int CompareString(string string1, int offset1, int length1, string string2, int offset2, int length2, CompareOptions options)
- {
- Debug.Assert(string1 != null);
- Debug.Assert(string2 != null);
- Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
-
- fixed (char* pString1 = string1)
- {
- fixed (char* pString2 = string2)
- {
- return Interop.GlobalizationInterop.CompareString(_sortHandle, pString1 + offset1, length1, pString2 + offset2, length2, options);
- }
- }
- }
-
- private unsafe int IndexOfCore(string source, string target, int startIndex, int count, CompareOptions options)
- {
- Debug.Assert(!string.IsNullOrEmpty(source));
- Debug.Assert(target != null);
- Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
-
- if (target.Length == 0)
- {
- return startIndex;
- }
-
- if (options == CompareOptions.Ordinal)
- {
- return IndexOfOrdinal(source, target, startIndex, count, ignoreCase: false);
- }
-
- if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsFastSort() && target.IsFastSort())
- {
- return IndexOf(source, target, startIndex, count, GetOrdinalCompareOptions(options));
- }
-
- fixed (char* pSource = source)
- {
- int index = Interop.GlobalizationInterop.IndexOf(_sortHandle, target, target.Length, pSource + startIndex, count, options);
-
- return index != -1 ? index + startIndex : -1;
- }
- }
-
- private unsafe int LastIndexOfCore(string source, string target, int startIndex, int count, CompareOptions options)
- {
- Debug.Assert(!string.IsNullOrEmpty(source));
- Debug.Assert(target != null);
- Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
-
- if (target.Length == 0)
- {
- return startIndex;
- }
-
- if (options == CompareOptions.Ordinal)
- {
- return LastIndexOfOrdinal(source, target, startIndex, count, ignoreCase: false);
- }
-
- if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsFastSort() && target.IsFastSort())
- {
- return LastIndexOf(source, target, startIndex, count, GetOrdinalCompareOptions(options));
- }
-
- // startIndex is the index into source where we start search backwards from. leftStartIndex is the index into source
- // of the start of the string that is count characters away from startIndex.
- int leftStartIndex = (startIndex - count + 1);
-
- fixed (char* pSource = source)
- {
- int lastIndex = Interop.GlobalizationInterop.LastIndexOf(_sortHandle, target, target.Length, pSource + (startIndex - count + 1), count, options);
-
- return lastIndex != -1 ? lastIndex + leftStartIndex : -1;
- }
- }
-
- private bool StartsWith(string source, string prefix, CompareOptions options)
- {
- Debug.Assert(!string.IsNullOrEmpty(source));
- Debug.Assert(!string.IsNullOrEmpty(prefix));
- Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
-
- if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsFastSort() && prefix.IsFastSort())
- {
- return IsPrefix(source, prefix, GetOrdinalCompareOptions(options));
- }
-
- return Interop.GlobalizationInterop.StartsWith(_sortHandle, prefix, prefix.Length, source, source.Length, options);
- }
-
- private bool EndsWith(string source, string suffix, CompareOptions options)
- {
- Debug.Assert(!string.IsNullOrEmpty(source));
- Debug.Assert(!string.IsNullOrEmpty(suffix));
- Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
-
- if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsFastSort() && suffix.IsFastSort())
- {
- return IsSuffix(source, suffix, GetOrdinalCompareOptions(options));
- }
-
- return Interop.GlobalizationInterop.EndsWith(_sortHandle, suffix, suffix.Length, source, source.Length, options);
- }
-
- private unsafe SortKey CreateSortKey(String source, CompareOptions options)
- {
- if (source==null) { throw new ArgumentNullException(nameof(source)); }
- Contract.EndContractBlock();
-
- if ((options & ValidSortkeyCtorMaskOffFlags) != 0)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
- }
-
- byte [] keyData;
- if (source.Length == 0)
- {
- keyData = EmptyArray<Byte>.Value;
- }
- else
- {
- int sortKeyLength = Interop.GlobalizationInterop.GetSortKey(_sortHandle, source, source.Length, null, 0, options);
- keyData = new byte[sortKeyLength];
-
- fixed (byte* pSortKey = keyData)
- {
- Interop.GlobalizationInterop.GetSortKey(_sortHandle, source, source.Length, pSortKey, sortKeyLength, options);
- }
- }
-
- return new SortKey(Name, source, options, keyData);
- }
-
- private unsafe static bool IsSortable(char *text, int length)
- {
- int index = 0;
- UnicodeCategory uc;
-
- while (index < length)
- {
- if (Char.IsHighSurrogate(text[index]))
- {
- if (index == length - 1 || !Char.IsLowSurrogate(text[index+1]))
- return false; // unpaired surrogate
-
- uc = CharUnicodeInfo.InternalGetUnicodeCategory(Char.ConvertToUtf32(text[index], text[index+1]));
- if (uc == UnicodeCategory.PrivateUse || uc == UnicodeCategory.OtherNotAssigned)
- return false;
-
- index += 2;
- continue;
- }
-
- if (Char.IsLowSurrogate(text[index]))
- {
- return false; // unpaired surrogate
- }
-
- uc = CharUnicodeInfo.GetUnicodeCategory(text[index]);
- if (uc == UnicodeCategory.PrivateUse || uc == UnicodeCategory.OtherNotAssigned)
- {
- return false;
- }
-
- index++;
- }
-
- return true;
- }
-
- // -----------------------------
- // ---- PAL layer ends here ----
- // -----------------------------
-
- internal unsafe int GetHashCodeOfStringCore(string source, CompareOptions options, bool forceRandomizedHashing, long additionalEntropy)
- {
- Debug.Assert(source != null);
- Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
-
- if (source.Length == 0)
- {
- return 0;
- }
-
- int sortKeyLength = Interop.GlobalizationInterop.GetSortKey(_sortHandle, source, source.Length, null, 0, options);
-
- // As an optimization, for small sort keys we allocate the buffer on the stack.
- if (sortKeyLength <= 256)
- {
- byte* pSortKey = stackalloc byte[sortKeyLength];
- Interop.GlobalizationInterop.GetSortKey(_sortHandle, source, source.Length, pSortKey, sortKeyLength, options);
- return InternalHashSortKey(pSortKey, sortKeyLength, false, additionalEntropy);
- }
-
- byte[] sortKey = new byte[sortKeyLength];
-
- fixed(byte* pSortKey = sortKey)
- {
- Interop.GlobalizationInterop.GetSortKey(_sortHandle, source, source.Length, pSortKey, sortKeyLength, options);
- return InternalHashSortKey(pSortKey, sortKeyLength, false, additionalEntropy);
- }
- }
-
- [DllImport(JitHelpers.QCall)]
- [SuppressUnmanagedCodeSecurity]
- private static unsafe extern int InternalHashSortKey(byte* sortKey, int sortKeyLength, [MarshalAs(UnmanagedType.Bool)] bool forceRandomizedHashing, long additionalEntropy);
-
- private static CompareOptions GetOrdinalCompareOptions(CompareOptions options)
- {
- if ((options & CompareOptions.IgnoreCase) == CompareOptions.IgnoreCase)
- {
- return CompareOptions.OrdinalIgnoreCase;
- }
- else
- {
- return CompareOptions.Ordinal;
- }
- }
-
- private static bool CanUseAsciiOrdinalForOptions(CompareOptions options)
- {
- // Unlike the other Ignore options, IgnoreSymbols impacts ASCII characters (e.g. ').
- return (options & CompareOptions.IgnoreSymbols) == 0;
- }
-
- private static byte[] GetNullTerminatedUtf8String(string s)
- {
- int byteLen = System.Text.Encoding.UTF8.GetByteCount(s);
-
- // Allocate an extra byte (which defaults to 0) as the null terminator.
- byte[] buffer = new byte[byteLen + 1];
-
- int bytesWritten = System.Text.Encoding.UTF8.GetBytes(s, 0, s.Length, buffer, 0);
-
- Debug.Assert(bytesWritten == byteLen);
-
- return buffer;
- }
-
- private SortVersion GetSortVersion()
- {
- int sortVersion = Interop.GlobalizationInterop.GetSortVersion();
- return new SortVersion(sortVersion, LCID, new Guid(sortVersion, 0, 0, 0, 0, 0, 0,
- (byte) (LCID >> 24),
- (byte) ((LCID & 0x00FF0000) >> 16),
- (byte) ((LCID & 0x0000FF00) >> 8),
- (byte) (LCID & 0xFF)));
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/CompareInfo.Windows.cs b/src/mscorlib/corefx/System/Globalization/CompareInfo.Windows.cs
deleted file mode 100644
index d4936522dd..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CompareInfo.Windows.cs
+++ /dev/null
@@ -1,415 +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.Diagnostics;
-using System.Diagnostics.Contracts;
-
-namespace System.Globalization
-{
- public partial class CompareInfo
- {
- internal unsafe CompareInfo(CultureInfo culture)
- {
- _name = culture._name;
- InitSort(culture);
- }
-
- private void InitSort(CultureInfo culture)
- {
- _sortName = culture.SortName;
-
- const uint LCMAP_SORTHANDLE = 0x20000000;
-
- _name = culture._name;
- _sortName = culture.SortName;
-
- IntPtr handle;
- int ret = Interop.mincore.LCMapStringEx(_sortName, LCMAP_SORTHANDLE, null, 0, &handle, IntPtr.Size, null, null, IntPtr.Zero);
- _sortHandle = ret > 0 ? handle : IntPtr.Zero;
- }
-
- private static unsafe int FindStringOrdinal(
- uint dwFindStringOrdinalFlags,
- string stringSource,
- int offset,
- int cchSource,
- string value,
- int cchValue,
- bool bIgnoreCase)
- {
- fixed (char* pSource = stringSource)
- fixed (char* pValue = value)
- {
- int ret = Interop.mincore.FindStringOrdinal(
- dwFindStringOrdinalFlags,
- pSource + offset,
- cchSource,
- pValue,
- cchValue,
- bIgnoreCase ? 1 : 0);
- return ret < 0 ? ret : ret + offset;
- }
- }
-
- internal static int IndexOfOrdinal(string source, string value, int startIndex, int count, bool ignoreCase)
- {
- Debug.Assert(source != null);
- Debug.Assert(value != null);
-
- return FindStringOrdinal(FIND_FROMSTART, source, startIndex, count, value, value.Length, ignoreCase);
- }
-
- internal static int LastIndexOfOrdinal(string source, string value, int startIndex, int count, bool ignoreCase)
- {
- Debug.Assert(source != null);
- Debug.Assert(value != null);
-
- return FindStringOrdinal(FIND_FROMEND, source, startIndex - count + 1, count, value, value.Length, ignoreCase);
- }
-
- private unsafe int GetHashCodeOfStringCore(string source, CompareOptions options)
- {
- Debug.Assert(source != null);
- Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
-
- if (source.Length == 0)
- {
- return 0;
- }
-
- int tmpHash = 0;
-
- fixed (char* pSource = source)
- {
- if (Interop.mincore.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _sortName,
- LCMAP_HASH | (uint)GetNativeCompareFlags(options),
- pSource, source.Length,
- &tmpHash, sizeof(int),
- null, null, _sortHandle) == 0)
- {
- Environment.FailFast("LCMapStringEx failed!");
- }
- }
-
- return tmpHash;
- }
-
- private static unsafe int CompareStringOrdinalIgnoreCase(char* string1, int count1, char* string2, int count2)
- {
- // Use the OS to compare and then convert the result to expected value by subtracting 2
- return Interop.mincore.CompareStringOrdinal(string1, count1, string2, count2, true) - 2;
- }
-
- private unsafe int CompareString(string string1, int offset1, int length1, string string2, int offset2, int length2, CompareOptions options)
- {
- Debug.Assert(string1 != null);
- Debug.Assert(string2 != null);
- Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
-
- string localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
-
- fixed (char* pLocaleName = localeName)
- fixed (char* pString1 = string1)
- fixed (char* pString2 = string2)
- {
- int result = Interop.mincore.CompareStringEx(
- pLocaleName,
- (uint)GetNativeCompareFlags(options),
- pString1 + offset1,
- length1,
- pString2 + offset2,
- length2,
- null,
- null,
- _sortHandle);
-
- if (result == 0)
- {
- Environment.FailFast("CompareStringEx failed");
- }
-
- // Map CompareStringEx return value to -1, 0, 1.
- return result - 2;
- }
- }
-
- private unsafe int FindString(
- uint dwFindNLSStringFlags,
- string lpStringSource,
- int startSource,
- int cchSource,
- string lpStringValue,
- int startValue,
- int cchValue)
- {
- string localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
-
- fixed (char* pLocaleName = localeName)
- fixed (char* pSource = lpStringSource)
- fixed (char* pValue = lpStringValue)
- {
- char* pS = pSource + startSource;
- char* pV = pValue + startValue;
-
- return Interop.mincore.FindNLSStringEx(
- pLocaleName,
- dwFindNLSStringFlags,
- pS,
- cchSource,
- pV,
- cchValue,
- null,
- null,
- null,
- _sortHandle);
- }
- }
-
- private int IndexOfCore(string source, string target, int startIndex, int count, CompareOptions options)
- {
- Debug.Assert(!string.IsNullOrEmpty(source));
- Debug.Assert(target != null);
- Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
-
- // TODO: Consider moving this up to the relevent APIs we need to ensure this behavior for
- // and add a precondition that target is not empty.
- if (target.Length == 0)
- return startIndex; // keep Whidbey compatibility
-
- if ((options & CompareOptions.Ordinal) != 0)
- {
- return FastIndexOfString(source, target, startIndex, count, target.Length, findLastIndex: false);
- }
- else
- {
- int retValue = FindString(FIND_FROMSTART | (uint)GetNativeCompareFlags(options),
- source,
- startIndex,
- count,
- target,
- 0,
- target.Length);
- if (retValue >= 0)
- {
- return retValue + startIndex;
- }
- }
-
- return -1;
- }
-
- private int LastIndexOfCore(string source, string target, int startIndex, int count, CompareOptions options)
- {
- Debug.Assert(!string.IsNullOrEmpty(source));
- Debug.Assert(target != null);
- Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
-
- // TODO: Consider moving this up to the relevent APIs we need to ensure this behavior for
- // and add a precondition that target is not empty.
- if (target.Length == 0)
- return startIndex; // keep Whidbey compatibility
-
- if ((options & CompareOptions.Ordinal) != 0)
- {
- return FastIndexOfString(source, target, startIndex, count, target.Length, findLastIndex: true);
- }
- else
- {
- int retValue = FindString(FIND_FROMEND | (uint)GetNativeCompareFlags(options),
- source,
- startIndex - count + 1,
- count,
- target,
- 0,
- target.Length);
-
- if (retValue >= 0)
- {
- return retValue + startIndex - (count - 1);
- }
- }
-
- return -1;
- }
-
- private bool StartsWith(string source, string prefix, CompareOptions options)
- {
- Debug.Assert(!string.IsNullOrEmpty(source));
- Debug.Assert(!string.IsNullOrEmpty(prefix));
- Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
-
- return FindString(FIND_STARTSWITH | (uint)GetNativeCompareFlags(options),
- source,
- 0,
- source.Length,
- prefix,
- 0,
- prefix.Length) >= 0;
- }
-
- private bool EndsWith(string source, string suffix, CompareOptions options)
- {
- Debug.Assert(!string.IsNullOrEmpty(source));
- Debug.Assert(!string.IsNullOrEmpty(suffix));
- Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
-
- return FindString(FIND_ENDSWITH | (uint)GetNativeCompareFlags(options),
- source,
- 0,
- source.Length,
- suffix,
- 0,
- suffix.Length) >= 0;
- }
-
- // PAL ends here
- [NonSerialized]
- private readonly IntPtr _sortHandle;
-
- private const uint LCMAP_HASH = 0x00040000;
-
- private const int FIND_STARTSWITH = 0x00100000;
- private const int FIND_ENDSWITH = 0x00200000;
- private const int FIND_FROMSTART = 0x00400000;
- private const int FIND_FROMEND = 0x00800000;
-
- // TODO: Instead of this method could we just have upstack code call IndexOfOrdinal with ignoreCase = false?
- private static unsafe int FastIndexOfString(string source, string target, int startIndex, int sourceCount, int targetCount, bool findLastIndex)
- {
- int retValue = -1;
-
- int sourceStartIndex = findLastIndex ? startIndex - sourceCount + 1 : startIndex;
-
- fixed (char* pSource = source, spTarget = target)
- {
- char* spSubSource = pSource + sourceStartIndex;
-
- if (findLastIndex)
- {
- int startPattern = (sourceCount - 1) - targetCount + 1;
- if (startPattern < 0)
- return -1;
-
- char patternChar0 = spTarget[0];
- for (int ctrSrc = startPattern; ctrSrc >= 0; ctrSrc--)
- {
- if (spSubSource[ctrSrc] != patternChar0)
- continue;
-
- int ctrPat;
- for (ctrPat = 1; ctrPat < targetCount; ctrPat++)
- {
- if (spSubSource[ctrSrc + ctrPat] != spTarget[ctrPat])
- break;
- }
- if (ctrPat == targetCount)
- {
- retValue = ctrSrc;
- break;
- }
- }
-
- if (retValue >= 0)
- {
- retValue += startIndex - sourceCount + 1;
- }
- }
- else
- {
- int endPattern = (sourceCount - 1) - targetCount + 1;
- if (endPattern < 0)
- return -1;
-
- char patternChar0 = spTarget[0];
- for (int ctrSrc = 0; ctrSrc <= endPattern; ctrSrc++)
- {
- if (spSubSource[ctrSrc] != patternChar0)
- continue;
- int ctrPat;
- for (ctrPat = 1; ctrPat < targetCount; ctrPat++)
- {
- if (spSubSource[ctrSrc + ctrPat] != spTarget[ctrPat])
- break;
- }
- if (ctrPat == targetCount)
- {
- retValue = ctrSrc;
- break;
- }
- }
-
- if (retValue >= 0)
- {
- retValue += startIndex;
- }
- }
- }
-
- return retValue;
- }
-
- private unsafe SortKey CreateSortKey(String source, CompareOptions options)
- {
- if (source == null) { throw new ArgumentNullException(nameof(source)); }
- Contract.EndContractBlock();
-
- if ((options & ValidSortkeyCtorMaskOffFlags) != 0)
- {
- throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
- }
-
- throw new NotImplementedException();
- }
-
- private static unsafe bool IsSortable(char* text, int length)
- {
- // CompareInfo c = CultureInfo.InvariantCulture.CompareInfo;
- // return (InternalIsSortable(c.m_dataHandle, c.m_handleOrigin, c.m_sortName, text, text.Length));
- throw new NotImplementedException();
- }
-
- private const int COMPARE_OPTIONS_ORDINAL = 0x40000000; // Ordinal
- private const int NORM_IGNORECASE = 0x00000001; // Ignores case. (use LINGUISTIC_IGNORECASE instead)
- private const int NORM_IGNOREKANATYPE = 0x00010000; // Does not differentiate between Hiragana and Katakana characters. Corresponding Hiragana and Katakana will compare as equal.
- private const int NORM_IGNORENONSPACE = 0x00000002; // Ignores nonspacing. This flag also removes Japanese accent characters. (use LINGUISTIC_IGNOREDIACRITIC instead)
- private const int NORM_IGNORESYMBOLS = 0x00000004; // Ignores symbols.
- private const int NORM_IGNOREWIDTH = 0x00020000; // Does not differentiate between a single-byte character and the same character as a double-byte character.
- private const int NORM_LINGUISTIC_CASING = 0x08000000; // use linguistic rules for casing
- private const int SORT_STRINGSORT = 0x00001000; // Treats punctuation the same as symbols.
-
- private static int GetNativeCompareFlags(CompareOptions options)
- {
- // Use "linguistic casing" by default (load the culture's casing exception tables)
- int nativeCompareFlags = NORM_LINGUISTIC_CASING;
-
- if ((options & CompareOptions.IgnoreCase) != 0) { nativeCompareFlags |= NORM_IGNORECASE; }
- if ((options & CompareOptions.IgnoreKanaType) != 0) { nativeCompareFlags |= NORM_IGNOREKANATYPE; }
- if ((options & CompareOptions.IgnoreNonSpace) != 0) { nativeCompareFlags |= NORM_IGNORENONSPACE; }
- if ((options & CompareOptions.IgnoreSymbols) != 0) { nativeCompareFlags |= NORM_IGNORESYMBOLS; }
- if ((options & CompareOptions.IgnoreWidth) != 0) { nativeCompareFlags |= NORM_IGNOREWIDTH; }
- if ((options & CompareOptions.StringSort) != 0) { nativeCompareFlags |= SORT_STRINGSORT; }
-
- // TODO: Can we try for GetNativeCompareFlags to never
- // take Ordinal or OrdinalIgnoreCase. This value is not part of Win32, we just handle it special
- // in some places.
- // Suffix & Prefix shouldn't use this, make sure to turn off the NORM_LINGUISTIC_CASING flag
- if (options == CompareOptions.Ordinal) { nativeCompareFlags = COMPARE_OPTIONS_ORDINAL; }
-
- Debug.Assert(((options & ~(CompareOptions.IgnoreCase |
- CompareOptions.IgnoreKanaType |
- CompareOptions.IgnoreNonSpace |
- CompareOptions.IgnoreSymbols |
- CompareOptions.IgnoreWidth |
- CompareOptions.StringSort)) == 0) ||
- (options == CompareOptions.Ordinal), "[CompareInfo.GetNativeCompareFlags]Expected all flags to be handled");
-
- return nativeCompareFlags;
- }
-
- private SortVersion GetSortVersion()
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/CompareInfo.cs b/src/mscorlib/corefx/System/Globalization/CompareInfo.cs
deleted file mode 100644
index 64dbfe84f7..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CompareInfo.cs
+++ /dev/null
@@ -1,1094 +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.
-
-////////////////////////////////////////////////////////////////////////////
-//
-//
-//
-// Purpose: This class implements a set of methods for comparing
-// strings.
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
-using System.Reflection;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-using System.Runtime.Serialization;
-
-namespace System.Globalization
-{
- [Flags]
- [Serializable]
- public enum CompareOptions
- {
- None = 0x00000000,
- IgnoreCase = 0x00000001,
- IgnoreNonSpace = 0x00000002,
- IgnoreSymbols = 0x00000004,
- IgnoreKanaType = 0x00000008, // ignore kanatype
- IgnoreWidth = 0x00000010, // ignore width
- OrdinalIgnoreCase = 0x10000000, // This flag can not be used with other flags.
- StringSort = 0x20000000, // use string sort method
- Ordinal = 0x40000000, // This flag can not be used with other flags.
- }
-
- [Serializable]
- public partial class CompareInfo : IDeserializationCallback
- {
- // Mask used to check if IndexOf()/LastIndexOf()/IsPrefix()/IsPostfix() has the right flags.
- private const CompareOptions ValidIndexMaskOffFlags =
- ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace |
- CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType);
-
- // Mask used to check if Compare() has the right flags.
- private const CompareOptions ValidCompareMaskOffFlags =
- ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace |
- CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType | CompareOptions.StringSort);
-
- // Mask used to check if GetHashCodeOfString() has the right flags.
- private const CompareOptions ValidHashCodeOfStringMaskOffFlags =
- ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace |
- CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType);
-
- // Mask used to check if we have the right flags.
- private const CompareOptions ValidSortkeyCtorMaskOffFlags =
- ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace |
- CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType | CompareOptions.StringSort);
-
- //
- // CompareInfos have an interesting identity. They are attached to the locale that created them,
- // ie: en-US would have an en-US sort. For haw-US (custom), then we serialize it as haw-US.
- // The interesting part is that since haw-US doesn't have its own sort, it has to point at another
- // locale, which is what SCOMPAREINFO does.
-
- [OptionalField(VersionAdded = 2)]
- private String _name; // The name used to construct this CompareInfo
- [NonSerialized]
- private String _sortName; // The name that defines our behavior
-
- [OptionalField(VersionAdded = 3)]
- private SortVersion _sortVersion;
-
- /*=================================GetCompareInfo==========================
- **Action: Get the CompareInfo constructed from the data table in the specified assembly for the specified culture.
- ** Warning: The assembly versioning mechanism is dead!
- **Returns: The CompareInfo for the specified culture.
- **Arguments:
- ** culture the ID of the culture
- ** assembly the assembly which contains the sorting table.
- **Exceptions:
- ** ArugmentNullException when the assembly is null
- ** ArgumentException if culture is invalid.
- ============================================================================*/
- // Assembly constructor should be deprecated, we don't act on the assembly information any more
- public static CompareInfo GetCompareInfo(int culture, Assembly assembly)
- {
- // Parameter checking.
- if (assembly == null)
- {
- throw new ArgumentNullException(nameof(assembly));
- }
- if (assembly != typeof(Object).Module.Assembly)
- {
- throw new ArgumentException(SR.Argument_OnlyMscorlib);
- }
- Contract.EndContractBlock();
-
- return GetCompareInfo(culture);
- }
-
- /*=================================GetCompareInfo==========================
- **Action: Get the CompareInfo constructed from the data table in the specified assembly for the specified culture.
- ** The purpose of this method is to provide version for CompareInfo tables.
- **Returns: The CompareInfo for the specified culture.
- **Arguments:
- ** name the name of the culture
- ** assembly the assembly which contains the sorting table.
- **Exceptions:
- ** ArugmentNullException when the assembly is null
- ** ArgumentException if name is invalid.
- ============================================================================*/
- // Assembly constructor should be deprecated, we don't act on the assembly information any more
- public static CompareInfo GetCompareInfo(String name, Assembly assembly)
- {
- if (name == null || assembly == null)
- {
- throw new ArgumentNullException(name == null ? nameof(name) : nameof(assembly));
- }
- Contract.EndContractBlock();
-
- if (assembly != typeof(Object).Module.Assembly)
- {
- throw new ArgumentException(SR.Argument_OnlyMscorlib);
- }
-
- return GetCompareInfo(name);
- }
-
- /*=================================GetCompareInfo==========================
- **Action: Get the CompareInfo for the specified culture.
- ** This method is provided for ease of integration with NLS-based software.
- **Returns: The CompareInfo for the specified culture.
- **Arguments:
- ** culture the ID of the culture.
- **Exceptions:
- ** ArgumentException if culture is invalid.
- ============================================================================*/
- // People really shouldn't be calling LCID versions, no custom support
- public static CompareInfo GetCompareInfo(int culture)
- {
- if (CultureData.IsCustomCultureId(culture))
- {
- // Customized culture cannot be created by the LCID.
- throw new ArgumentException(SR.Argument_CustomCultureCannotBePassedByNumber, nameof(culture));
- }
-
- return CultureInfo.GetCultureInfo(culture).CompareInfo;
- }
-
- /*=================================GetCompareInfo==========================
- **Action: Get the CompareInfo for the specified culture.
- **Returns: The CompareInfo for the specified culture.
- **Arguments:
- ** name the name of the culture.
- **Exceptions:
- ** ArgumentException if name is invalid.
- ============================================================================*/
-
- public static CompareInfo GetCompareInfo(String name)
- {
- if (name == null)
- {
- throw new ArgumentNullException(nameof(name));
- }
- Contract.EndContractBlock();
-
- return CultureInfo.GetCultureInfo(name).CompareInfo;
- }
-
- public static unsafe bool IsSortable(char ch)
- {
- char *pChar = &ch;
- return IsSortable(pChar, 1);
- }
-
- public static unsafe bool IsSortable(string text)
- {
- if (text == null)
- {
- // A null param is invalid here.
- throw new ArgumentNullException(nameof(text));
- }
-
- if (0 == text.Length)
- {
- // A zero length string is not invalid, but it is also not sortable.
- return (false);
- }
-
- fixed (char *pChar = text)
- {
- return IsSortable(pChar, text.Length);
- }
- }
-
-
- [OnDeserializing]
- private void OnDeserializing(StreamingContext ctx)
- {
- _name = null;
- }
-
- void IDeserializationCallback.OnDeserialization(Object sender)
- {
- OnDeserialized();
- }
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext ctx)
- {
- OnDeserialized();
- }
-
- private void OnDeserialized()
- {
- if (_name != null)
- {
- InitSort(CultureInfo.GetCultureInfo(_name));
- }
- }
-
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx) { }
-
- ///////////////////////////----- Name -----/////////////////////////////////
- //
- // Returns the name of the culture (well actually, of the sort).
- // Very important for providing a non-LCID way of identifying
- // what the sort is.
- //
- // Note that this name isn't dereferenced in case the CompareInfo is a different locale
- // which is consistent with the behaviors of earlier versions. (so if you ask for a sort
- // and the locale's changed behavior, then you'll get changed behavior, which is like
- // what happens for a version update)
- //
- ////////////////////////////////////////////////////////////////////////
-
- public virtual String Name
- {
- get
- {
- Debug.Assert(_name != null, "CompareInfo.Name Expected _name to be set");
- if (_name == "zh-CHT" || _name == "zh-CHS")
- {
- return _name;
- }
-
- return _sortName;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Compare
- //
- // Compares the two strings with the given options. Returns 0 if the
- // two strings are equal, a number less than 0 if string1 is less
- // than string2, and a number greater than 0 if string1 is greater
- // than string2.
- //
- ////////////////////////////////////////////////////////////////////////
-
- public virtual int Compare(String string1, String string2)
- {
- return (Compare(string1, string2, CompareOptions.None));
- }
-
- public unsafe virtual int Compare(String string1, String string2, CompareOptions options)
- {
- if (options == CompareOptions.OrdinalIgnoreCase)
- {
- return String.Compare(string1, string2, StringComparison.OrdinalIgnoreCase);
- }
-
- // Verify the options before we do any real comparison.
- if ((options & CompareOptions.Ordinal) != 0)
- {
- if (options != CompareOptions.Ordinal)
- {
- throw new ArgumentException(SR.Argument_CompareOptionOrdinal, nameof(options));
- }
- return String.CompareOrdinal(string1, string2);
- }
-
- if ((options & ValidCompareMaskOffFlags) != 0)
- {
- throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
- }
-
- //Our paradigm is that null sorts less than any other string and
- //that two nulls sort as equal.
- if (string1 == null)
- {
- if (string2 == null)
- {
- return (0); // Equal
- }
- return (-1); // null < non-null
- }
- if (string2 == null)
- {
- return (1); // non-null > null
- }
-
- return CompareString(string1, 0, string1.Length, string2, 0, string2.Length, options);
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Compare
- //
- // Compares the specified regions of the two strings with the given
- // options.
- // Returns 0 if the two strings are equal, a number less than 0 if
- // string1 is less than string2, and a number greater than 0 if
- // string1 is greater than string2.
- //
- ////////////////////////////////////////////////////////////////////////
-
-
- public unsafe virtual int Compare(String string1, int offset1, int length1, String string2, int offset2, int length2)
- {
- return Compare(string1, offset1, length1, string2, offset2, length2, 0);
- }
-
-
- public unsafe virtual int Compare(String string1, int offset1, String string2, int offset2, CompareOptions options)
- {
- return Compare(string1, offset1, string1 == null ? 0 : string1.Length - offset1,
- string2, offset2, string2 == null ? 0 : string2.Length - offset2, options);
- }
-
-
- public unsafe virtual int Compare(String string1, int offset1, String string2, int offset2)
- {
- return Compare(string1, offset1, string2, offset2, 0);
- }
-
-
- public unsafe virtual int Compare(String string1, int offset1, int length1, String string2, int offset2, int length2, CompareOptions options)
- {
- if (options == CompareOptions.OrdinalIgnoreCase)
- {
- int result = String.Compare(string1, offset1, string2, offset2, length1 < length2 ? length1 : length2, StringComparison.OrdinalIgnoreCase);
- if ((length1 != length2) && result == 0)
- return (length1 > length2 ? 1 : -1);
- return (result);
- }
-
- // Verify inputs
- if (length1 < 0 || length2 < 0)
- {
- throw new ArgumentOutOfRangeException((length1 < 0) ? nameof(length1) : nameof(length2), SR.ArgumentOutOfRange_NeedPosNum);
- }
- if (offset1 < 0 || offset2 < 0)
- {
- throw new ArgumentOutOfRangeException((offset1 < 0) ? nameof(offset1) : nameof(offset2), SR.ArgumentOutOfRange_NeedPosNum);
- }
- if (offset1 > (string1 == null ? 0 : string1.Length) - length1)
- {
- throw new ArgumentOutOfRangeException(nameof(string1), SR.ArgumentOutOfRange_OffsetLength);
- }
- if (offset2 > (string2 == null ? 0 : string2.Length) - length2)
- {
- throw new ArgumentOutOfRangeException(nameof(string2), SR.ArgumentOutOfRange_OffsetLength);
- }
- if ((options & CompareOptions.Ordinal) != 0)
- {
- if (options != CompareOptions.Ordinal)
- {
- throw new ArgumentException(SR.Argument_CompareOptionOrdinal,
- nameof(options));
- }
- }
- else if ((options & ValidCompareMaskOffFlags) != 0)
- {
- throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
- }
-
- //
- // Check for the null case.
- //
- if (string1 == null)
- {
- if (string2 == null)
- {
- return (0);
- }
- return (-1);
- }
- if (string2 == null)
- {
- return (1);
- }
-
- if (options == CompareOptions.Ordinal)
- {
- return CompareOrdinal(string1, offset1, length1,
- string2, offset2, length2);
- }
- return CompareString(string1, offset1, length1,
- string2, offset2, length2,
- options);
- }
-
- private static int CompareOrdinal(string string1, int offset1, int length1, string string2, int offset2, int length2)
- {
- int result = String.CompareOrdinal(string1, offset1, string2, offset2,
- (length1 < length2 ? length1 : length2));
- if ((length1 != length2) && result == 0)
- {
- return (length1 > length2 ? 1 : -1);
- }
- return (result);
- }
-
- //
- // CompareOrdinalIgnoreCase compare two string oridnally with ignoring the case.
- // it assumes the strings are Ascii string till we hit non Ascii character in strA or strB and then we continue the comparison by
- // calling the OS.
- //
- internal static unsafe int CompareOrdinalIgnoreCase(string strA, int indexA, int lengthA, string strB, int indexB, int lengthB)
- {
- Debug.Assert(indexA + lengthA <= strA.Length);
- Debug.Assert(indexB + lengthB <= strB.Length);
-
- int length = Math.Min(lengthA, lengthB);
- int range = length;
-
- fixed (char* ap = strA) fixed (char* bp = strB)
- {
- char* a = ap + indexA;
- char* b = bp + indexB;
-
- while (length != 0 && (*a <= 0x80) && (*b <= 0x80))
- {
- int charA = *a;
- int charB = *b;
-
- if (charA == charB)
- {
- a++; b++;
- length--;
- continue;
- }
-
- // uppercase both chars - notice that we need just one compare per char
- if ((uint)(charA - 'a') <= (uint)('z' - 'a')) charA -= 0x20;
- if ((uint)(charB - 'a') <= (uint)('z' - 'a')) charB -= 0x20;
-
- //Return the (case-insensitive) difference between them.
- if (charA != charB)
- return charA - charB;
-
- // Next char
- a++; b++;
- length--;
- }
-
- if (length == 0)
- return lengthA - lengthB;
-
- range -= length;
-
- return CompareStringOrdinalIgnoreCase(a, lengthA - range, b, lengthB - range);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // IsPrefix
- //
- // Determines whether prefix is a prefix of string. If prefix equals
- // String.Empty, true is returned.
- //
- ////////////////////////////////////////////////////////////////////////
- public unsafe virtual bool IsPrefix(String source, String prefix, CompareOptions options)
- {
- if (source == null || prefix == null)
- {
- throw new ArgumentNullException((source == null ? nameof(source) : nameof(prefix)),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
-
- if (prefix.Length == 0)
- {
- return (true);
- }
-
- if (source.Length == 0)
- {
- return false;
- }
-
- if (options == CompareOptions.OrdinalIgnoreCase)
- {
- return source.StartsWith(prefix, StringComparison.OrdinalIgnoreCase);
- }
-
- if (options == CompareOptions.Ordinal)
- {
- return source.StartsWith(prefix, StringComparison.Ordinal);
- }
-
- if ((options & ValidIndexMaskOffFlags) != 0)
- {
- throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
- }
-
- return StartsWith(source, prefix, options);
- }
-
- public virtual bool IsPrefix(String source, String prefix)
- {
- return (IsPrefix(source, prefix, 0));
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // IsSuffix
- //
- // Determines whether suffix is a suffix of string. If suffix equals
- // String.Empty, true is returned.
- //
- ////////////////////////////////////////////////////////////////////////
- public unsafe virtual bool IsSuffix(String source, String suffix, CompareOptions options)
- {
- if (source == null || suffix == null)
- {
- throw new ArgumentNullException((source == null ? nameof(source) : nameof(suffix)),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
-
- if (suffix.Length == 0)
- {
- return (true);
- }
-
- if (source.Length == 0)
- {
- return false;
- }
-
- if (options == CompareOptions.OrdinalIgnoreCase)
- {
- return source.EndsWith(suffix, StringComparison.OrdinalIgnoreCase);
- }
-
- if (options == CompareOptions.Ordinal)
- {
- return source.EndsWith(suffix, StringComparison.Ordinal);
- }
-
- if ((options & ValidIndexMaskOffFlags) != 0)
- {
- throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
- }
-
- return EndsWith(source, suffix, options);
- }
-
-
- public virtual bool IsSuffix(String source, String suffix)
- {
- return (IsSuffix(source, suffix, 0));
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // IndexOf
- //
- // Returns the first index where value is found in string. The
- // search starts from startIndex and ends at endIndex. Returns -1 if
- // the specified value is not found. If value equals String.Empty,
- // startIndex is returned. Throws IndexOutOfRange if startIndex or
- // endIndex is less than zero or greater than the length of string.
- // Throws ArgumentException if value is null.
- //
- ////////////////////////////////////////////////////////////////////////
-
-
- public unsafe virtual int IndexOf(String source, char value)
- {
- if (source == null)
- throw new ArgumentNullException(nameof(source));
- Contract.EndContractBlock();
-
- return IndexOf(source, value, 0, source.Length, CompareOptions.None);
- }
-
-
- public unsafe virtual int IndexOf(String source, String value)
- {
- if (source == null)
- throw new ArgumentNullException(nameof(source));
- Contract.EndContractBlock();
-
- return IndexOf(source, value, 0, source.Length, CompareOptions.None);
- }
-
-
- public unsafe virtual int IndexOf(String source, char value, CompareOptions options)
- {
- if (source == null)
- throw new ArgumentNullException(nameof(source));
- Contract.EndContractBlock();
-
- return IndexOf(source, value, 0, source.Length, options);
- }
-
-
- public unsafe virtual int IndexOf(String source, String value, CompareOptions options)
- {
- if (source == null)
- throw new ArgumentNullException(nameof(source));
- Contract.EndContractBlock();
-
- return IndexOf(source, value, 0, source.Length, options);
- }
-
- public unsafe virtual int IndexOf(String source, char value, int startIndex)
- {
- if (source == null)
- throw new ArgumentNullException(nameof(source));
- Contract.EndContractBlock();
-
- return IndexOf(source, value, startIndex, source.Length - startIndex, CompareOptions.None);
- }
-
- public unsafe virtual int IndexOf(String source, String value, int startIndex)
- {
- if (source == null)
- throw new ArgumentNullException(nameof(source));
- Contract.EndContractBlock();
-
- return IndexOf(source, value, startIndex, source.Length - startIndex, CompareOptions.None);
- }
-
- public unsafe virtual int IndexOf(String source, char value, int startIndex, CompareOptions options)
- {
- if (source == null)
- throw new ArgumentNullException(nameof(source));
- Contract.EndContractBlock();
-
- return IndexOf(source, value, startIndex, source.Length - startIndex, options);
- }
-
-
- public unsafe virtual int IndexOf(String source, String value, int startIndex, CompareOptions options)
- {
- if (source == null)
- throw new ArgumentNullException(nameof(source));
- Contract.EndContractBlock();
-
- return IndexOf(source, value, startIndex, source.Length - startIndex, options);
- }
-
-
- public unsafe virtual int IndexOf(String source, char value, int startIndex, int count)
- {
- return IndexOf(source, value, startIndex, count, CompareOptions.None);
- }
-
-
- public unsafe virtual int IndexOf(String source, String value, int startIndex, int count)
- {
- return IndexOf(source, value, startIndex, count, CompareOptions.None);
- }
-
- public unsafe virtual int IndexOf(String source, char value, int startIndex, int count, CompareOptions options)
- {
- // Validate inputs
- if (source == null)
- throw new ArgumentNullException(nameof(source));
-
- if (startIndex < 0 || startIndex > source.Length)
- throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
-
- if (count < 0 || startIndex > source.Length - count)
- throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
- Contract.EndContractBlock();
-
- if (options == CompareOptions.OrdinalIgnoreCase)
- {
- return source.IndexOf(value.ToString(), startIndex, count, StringComparison.OrdinalIgnoreCase);
- }
-
- // Validate CompareOptions
- // Ordinal can't be selected with other flags
- if ((options & ValidIndexMaskOffFlags) != 0 && (options != CompareOptions.Ordinal))
- throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
-
- return IndexOfCore(source, new string(value, 1), startIndex, count, options);
- }
-
-
- public unsafe virtual int IndexOf(String source, String value, int startIndex, int count, CompareOptions options)
- {
- // Validate inputs
- if (source == null)
- throw new ArgumentNullException(nameof(source));
- if (value == null)
- throw new ArgumentNullException(nameof(value));
-
- if (startIndex > source.Length)
- {
- throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
- }
- Contract.EndContractBlock();
-
- // In Everett we used to return -1 for empty string even if startIndex is negative number so we keeping same behavior here.
- // We return 0 if both source and value are empty strings for Everett compatibility too.
- if (source.Length == 0)
- {
- if (value.Length == 0)
- {
- return 0;
- }
- return -1;
- }
-
- if (startIndex < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
- }
-
- if (count < 0 || startIndex > source.Length - count)
- throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
-
- if (options == CompareOptions.OrdinalIgnoreCase)
- {
- return IndexOfOrdinal(source, value, startIndex, count, ignoreCase: true);
- }
-
- // Validate CompareOptions
- // Ordinal can't be selected with other flags
- if ((options & ValidIndexMaskOffFlags) != 0 && (options != CompareOptions.Ordinal))
- throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
-
- return IndexOfCore(source, value, startIndex, count, options);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // LastIndexOf
- //
- // Returns the last index where value is found in string. The
- // search starts from startIndex and ends at endIndex. Returns -1 if
- // the specified value is not found. If value equals String.Empty,
- // endIndex is returned. Throws IndexOutOfRange if startIndex or
- // endIndex is less than zero or greater than the length of string.
- // Throws ArgumentException if value is null.
- //
- ////////////////////////////////////////////////////////////////////////
-
-
- public unsafe virtual int LastIndexOf(String source, char value)
- {
- if (source == null)
- throw new ArgumentNullException(nameof(source));
- Contract.EndContractBlock();
-
- // Can't start at negative index, so make sure we check for the length == 0 case.
- return LastIndexOf(source, value, source.Length - 1,
- source.Length, CompareOptions.None);
- }
-
-
- public virtual int LastIndexOf(String source, String value)
- {
- if (source == null)
- throw new ArgumentNullException(nameof(source));
- Contract.EndContractBlock();
-
- // Can't start at negative index, so make sure we check for the length == 0 case.
- return LastIndexOf(source, value, source.Length - 1,
- source.Length, CompareOptions.None);
- }
-
-
- public virtual int LastIndexOf(String source, char value, CompareOptions options)
- {
- if (source == null)
- throw new ArgumentNullException(nameof(source));
- Contract.EndContractBlock();
-
- // Can't start at negative index, so make sure we check for the length == 0 case.
- return LastIndexOf(source, value, source.Length - 1,
- source.Length, options);
- }
-
- public unsafe virtual int LastIndexOf(String source, String value, CompareOptions options)
- {
- if (source == null)
- throw new ArgumentNullException(nameof(source));
- Contract.EndContractBlock();
-
- // Can't start at negative index, so make sure we check for the length == 0 case.
- return LastIndexOf(source, value, source.Length - 1,
- source.Length, options);
- }
-
- public unsafe virtual int LastIndexOf(String source, char value, int startIndex)
- {
- return LastIndexOf(source, value, startIndex, startIndex + 1, CompareOptions.None);
- }
-
-
- public unsafe virtual int LastIndexOf(String source, String value, int startIndex)
- {
- return LastIndexOf(source, value, startIndex, startIndex + 1, CompareOptions.None);
- }
-
- public unsafe virtual int LastIndexOf(String source, char value, int startIndex, CompareOptions options)
- {
- return LastIndexOf(source, value, startIndex, startIndex + 1, options);
- }
-
-
- public unsafe virtual int LastIndexOf(String source, String value, int startIndex, CompareOptions options)
- {
- return LastIndexOf(source, value, startIndex, startIndex + 1, options);
- }
-
-
- public unsafe virtual int LastIndexOf(String source, char value, int startIndex, int count)
- {
- return LastIndexOf(source, value, startIndex, count, CompareOptions.None);
- }
-
-
- public unsafe virtual int LastIndexOf(String source, String value, int startIndex, int count)
- {
- return LastIndexOf(source, value, startIndex, count, CompareOptions.None);
- }
-
-
- public unsafe virtual int LastIndexOf(String source, char value, int startIndex, int count, CompareOptions options)
- {
- // Verify Arguments
- if (source == null)
- throw new ArgumentNullException(nameof(source));
- Contract.EndContractBlock();
-
- // Validate CompareOptions
- // Ordinal can't be selected with other flags
- if ((options & ValidIndexMaskOffFlags) != 0 &&
- (options != CompareOptions.Ordinal) &&
- (options != CompareOptions.OrdinalIgnoreCase))
- throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
-
- // Special case for 0 length input strings
- if (source.Length == 0 && (startIndex == -1 || startIndex == 0))
- return -1;
-
- // Make sure we're not out of range
- if (startIndex < 0 || startIndex > source.Length)
- throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
-
- // Make sure that we allow startIndex == source.Length
- if (startIndex == source.Length)
- {
- startIndex--;
- if (count > 0)
- count--;
- }
-
- // 2nd have of this also catches when startIndex == MAXINT, so MAXINT - 0 + 1 == -1, which is < 0.
- if (count < 0 || startIndex - count + 1 < 0)
- throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
-
- if (options == CompareOptions.OrdinalIgnoreCase)
- {
- return source.LastIndexOf(value.ToString(), startIndex, count, StringComparison.OrdinalIgnoreCase);
- }
-
- return LastIndexOfCore(source, value.ToString(), startIndex, count, options);
- }
-
-
- public unsafe virtual int LastIndexOf(String source, String value, int startIndex, int count, CompareOptions options)
- {
- // Verify Arguments
- if (source == null)
- throw new ArgumentNullException(nameof(source));
- if (value == null)
- throw new ArgumentNullException(nameof(value));
- Contract.EndContractBlock();
-
- // Validate CompareOptions
- // Ordinal can't be selected with other flags
- if ((options & ValidIndexMaskOffFlags) != 0 &&
- (options != CompareOptions.Ordinal) &&
- (options != CompareOptions.OrdinalIgnoreCase))
- throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
-
- // Special case for 0 length input strings
- if (source.Length == 0 && (startIndex == -1 || startIndex == 0))
- return (value.Length == 0) ? 0 : -1;
-
- // Make sure we're not out of range
- if (startIndex < 0 || startIndex > source.Length)
- throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
-
- // Make sure that we allow startIndex == source.Length
- if (startIndex == source.Length)
- {
- startIndex--;
- if (count > 0)
- count--;
-
- // If we are looking for nothing, just return 0
- if (value.Length == 0 && count >= 0 && startIndex - count + 1 >= 0)
- return startIndex;
- }
-
- // 2nd half of this also catches when startIndex == MAXINT, so MAXINT - 0 + 1 == -1, which is < 0.
- if (count < 0 || startIndex - count + 1 < 0)
- throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
-
- if (options == CompareOptions.OrdinalIgnoreCase)
- {
- return LastIndexOfOrdinal(source, value, startIndex, count, ignoreCase: true);
- }
-
- return LastIndexOfCore(source, value, startIndex, count, options);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetSortKey
- //
- // Gets the SortKey for the given string with the given options.
- //
- ////////////////////////////////////////////////////////////////////////
- public unsafe virtual SortKey GetSortKey(String source, CompareOptions options)
- {
- return CreateSortKey(source, options);
- }
-
-
- public unsafe virtual SortKey GetSortKey(String source)
- {
- return CreateSortKey(source, CompareOptions.None);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Equals
- //
- // Implements Object.Equals(). Returns a boolean indicating whether
- // or not object refers to the same CompareInfo as the current
- // instance.
- //
- ////////////////////////////////////////////////////////////////////////
-
-
- public override bool Equals(Object value)
- {
- CompareInfo that = value as CompareInfo;
-
- if (that != null)
- {
- return this.Name == that.Name;
- }
-
- return (false);
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetHashCode
- //
- // Implements Object.GetHashCode(). Returns the hash code for the
- // CompareInfo. The hash code is guaranteed to be the same for
- // CompareInfo A and B where A.Equals(B) is true.
- //
- ////////////////////////////////////////////////////////////////////////
-
-
- public override int GetHashCode()
- {
- return (this.Name.GetHashCode());
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetHashCodeOfString
- //
- // This internal method allows a method that allows the equivalent of creating a Sortkey for a
- // string from CompareInfo, and generate a hashcode value from it. It is not very convenient
- // to use this method as is and it creates an unnecessary Sortkey object that will be GC'ed.
- //
- // The hash code is guaranteed to be the same for string A and B where A.Equals(B) is true and both
- // the CompareInfo and the CompareOptions are the same. If two different CompareInfo objects
- // treat the string the same way, this implementation will treat them differently (the same way that
- // Sortkey does at the moment).
- //
- // This method will never be made public itself, but public consumers of it could be created, e.g.:
- //
- // string.GetHashCode(CultureInfo)
- // string.GetHashCode(CompareInfo)
- // string.GetHashCode(CultureInfo, CompareOptions)
- // string.GetHashCode(CompareInfo, CompareOptions)
- // etc.
- //
- // (the methods above that take a CultureInfo would use CultureInfo.CompareInfo)
- //
- ////////////////////////////////////////////////////////////////////////
- internal int GetHashCodeOfString(string source, CompareOptions options)
- {
- //
- // Parameter validation
- //
- if (null == source)
- {
- throw new ArgumentNullException(nameof(source));
- }
-
- if ((options & ValidHashCodeOfStringMaskOffFlags) != 0)
- {
- throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
- }
- Contract.EndContractBlock();
-
- return GetHashCodeOfStringCore(source, options);
- }
-
- public virtual int GetHashCode(string source, CompareOptions options)
- {
- if (source == null)
- {
- throw new ArgumentNullException(nameof(source));
- }
-
- if (options == CompareOptions.Ordinal)
- {
- return source.GetHashCode();
- }
-
- if (options == CompareOptions.OrdinalIgnoreCase)
- {
- return TextInfo.GetHashCodeOrdinalIgnoreCase(source);
- }
-
- //
- // GetHashCodeOfString does more parameters validation. basically will throw when
- // having Ordinal, OrdinalIgnoreCase and StringSort
- //
-
- return GetHashCodeOfString(source, options);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ToString
- //
- // Implements Object.ToString(). Returns a string describing the
- // CompareInfo.
- //
- ////////////////////////////////////////////////////////////////////////
- public override String ToString()
- {
- return ("CompareInfo - " + this.Name);
- }
-
- public SortVersion Version
- {
- get
- {
- if (_sortVersion == null)
- {
- _sortVersion = GetSortVersion();
- }
-
- return _sortVersion;
- }
- }
-
- public int LCID
- {
- get
- {
- return CultureInfo.GetCultureInfo(Name).LCID;
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/CultureData.Unix.cs b/src/mscorlib/corefx/System/Globalization/CultureData.Unix.cs
deleted file mode 100644
index ba96189458..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CultureData.Unix.cs
+++ /dev/null
@@ -1,419 +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.Collections.Generic;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-using System.Runtime.InteropServices;
-using System.Security;
-using System.Text;
-
-namespace System.Globalization
-{
- internal partial class CultureData
- {
- // ICU constants
- const int ICU_ULOC_KEYWORD_AND_VALUES_CAPACITY = 100; // max size of keyword or value
- const int ICU_ULOC_FULLNAME_CAPACITY = 157; // max size of locale name
- const string ICU_COLLATION_KEYWORD = "@collation=";
-
-
- /// <summary>
- /// This method uses the sRealName field (which is initialized by the constructor before this is called) to
- /// initialize the rest of the state of CultureData based on the underlying OS globalization library.
- /// </summary>
- private unsafe bool InitCultureData()
- {
- Debug.Assert(_sRealName != null);
-
- string alternateSortName = string.Empty;
- string realNameBuffer = _sRealName;
-
- // Basic validation
- if (realNameBuffer.Contains("@"))
- {
- return false; // don't allow ICU variants to come in directly
- }
-
- // Replace _ (alternate sort) with @collation= for ICU
- int index = realNameBuffer.IndexOf('_');
- if (index > 0)
- {
- if (index >= (realNameBuffer.Length - 1) // must have characters after _
- || realNameBuffer.Substring(index + 1).Contains("_")) // only one _ allowed
- {
- return false; // fail
- }
- alternateSortName = realNameBuffer.Substring(index + 1);
- realNameBuffer = realNameBuffer.Substring(0, index) + ICU_COLLATION_KEYWORD + alternateSortName;
- }
-
- // Get the locale name from ICU
- if (!GetLocaleName(realNameBuffer, out _sWindowsName))
- {
- return false; // fail
- }
-
- // Replace the ICU collation keyword with an _
- index = _sWindowsName.IndexOf(ICU_COLLATION_KEYWORD, StringComparison.Ordinal);
- if (index >= 0)
- {
- _sName = _sWindowsName.Substring(0, index) + "_" + alternateSortName;
- }
- else
- {
- _sName = _sWindowsName;
- }
- _sRealName = _sName;
-
- _iLanguage = this.ILANGUAGE;
- if (_iLanguage == 0)
- {
- _iLanguage = CultureInfo.LOCALE_CUSTOM_UNSPECIFIED;
- }
-
- _bNeutral = (this.SISO3166CTRYNAME.Length == 0);
-
- _sSpecificCulture = _bNeutral ? LocaleData.GetSpecificCultureName(_sRealName) : _sRealName;
-
- // Remove the sort from sName unless custom culture
- if (index>0 && !_bNeutral && !IsCustomCultureId(_iLanguage))
- {
- _sName = _sWindowsName.Substring(0, index);
- }
- return true;
- }
-
- internal static bool GetLocaleName(string localeName, out string windowsName)
- {
- // Get the locale name from ICU
- StringBuilder sb = StringBuilderCache.Acquire(ICU_ULOC_FULLNAME_CAPACITY);
- if (!Interop.GlobalizationInterop.GetLocaleName(localeName, sb, sb.Capacity))
- {
- StringBuilderCache.Release(sb);
- windowsName = null;
- return false; // fail
- }
-
- // Success - use the locale name returned which may be different than realNameBuffer (casing)
- windowsName = StringBuilderCache.GetStringAndRelease(sb); // the name passed to subsequent ICU calls
- return true;
- }
-
- internal static bool GetDefaultLocaleName(out string windowsName)
- {
- // Get the default (system) locale name from ICU
- StringBuilder sb = StringBuilderCache.Acquire(ICU_ULOC_FULLNAME_CAPACITY);
- if (!Interop.GlobalizationInterop.GetDefaultLocaleName(sb, sb.Capacity))
- {
- StringBuilderCache.Release(sb);
- windowsName = null;
- return false; // fail
- }
-
- // Success - use the locale name returned which may be different than realNameBuffer (casing)
- windowsName = StringBuilderCache.GetStringAndRelease(sb); // the name passed to subsequent ICU calls
- return true;
- }
-
- private string GetLocaleInfo(LocaleStringData type)
- {
- Debug.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo] Expected _sWindowsName to be populated already");
- return GetLocaleInfo(_sWindowsName, type);
- }
-
- // For LOCALE_SPARENT we need the option of using the "real" name (forcing neutral names) instead of the
- // "windows" name, which can be specific for downlevel (< windows 7) os's.
- private string GetLocaleInfo(string localeName, LocaleStringData type)
- {
- Debug.Assert(localeName != null, "[CultureData.GetLocaleInfo] Expected localeName to be not be null");
-
- switch (type)
- {
- case LocaleStringData.NegativeInfinitySymbol:
- // not an equivalent in ICU; prefix the PositiveInfinitySymbol with NegativeSign
- return GetLocaleInfo(localeName, LocaleStringData.NegativeSign) +
- GetLocaleInfo(localeName, LocaleStringData.PositiveInfinitySymbol);
- }
-
- StringBuilder sb = StringBuilderCache.Acquire(ICU_ULOC_KEYWORD_AND_VALUES_CAPACITY);
-
- bool result = Interop.GlobalizationInterop.GetLocaleInfoString(localeName, (uint)type, sb, sb.Capacity);
- if (!result)
- {
- // Failed, just use empty string
- StringBuilderCache.Release(sb);
- Debug.Assert(false, "[CultureData.GetLocaleInfo(LocaleStringData)] Failed");
- return String.Empty;
- }
- return StringBuilderCache.GetStringAndRelease(sb);
- }
-
- private int GetLocaleInfo(LocaleNumberData type)
- {
- Debug.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo(LocaleNumberData)] Expected _sWindowsName to be populated already");
-
- switch (type)
- {
- case LocaleNumberData.CalendarType:
- // returning 0 will cause the first supported calendar to be returned, which is the preferred calendar
- return 0;
- }
-
-
- int value = 0;
- bool result = Interop.GlobalizationInterop.GetLocaleInfoInt(_sWindowsName, (uint)type, ref value);
- if (!result)
- {
- // Failed, just use 0
- Debug.Assert(false, "[CultureData.GetLocaleInfo(LocaleNumberData)] failed");
- }
-
- return value;
- }
-
- private int[] GetLocaleInfo(LocaleGroupingData type)
- {
- Debug.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo(LocaleGroupingData)] Expected _sWindowsName to be populated already");
-
- int primaryGroupingSize = 0;
- int secondaryGroupingSize = 0;
- bool result = Interop.GlobalizationInterop.GetLocaleInfoGroupingSizes(_sWindowsName, (uint)type, ref primaryGroupingSize, ref secondaryGroupingSize);
- if (!result)
- {
- Debug.Assert(false, "[CultureData.GetLocaleInfo(LocaleGroupingData type)] failed");
- }
-
- if (secondaryGroupingSize == 0)
- {
- return new int[] { primaryGroupingSize };
- }
-
- return new int[] { primaryGroupingSize, secondaryGroupingSize };
- }
-
- private string GetTimeFormatString()
- {
- return GetTimeFormatString(false);
- }
-
- private string GetTimeFormatString(bool shortFormat)
- {
- Debug.Assert(_sWindowsName != null, "[CultureData.GetTimeFormatString(bool shortFormat)] Expected _sWindowsName to be populated already");
-
- StringBuilder sb = StringBuilderCache.Acquire(ICU_ULOC_KEYWORD_AND_VALUES_CAPACITY);
-
- bool result = Interop.GlobalizationInterop.GetLocaleTimeFormat(_sWindowsName, shortFormat, sb, sb.Capacity);
- if (!result)
- {
- // Failed, just use empty string
- StringBuilderCache.Release(sb);
- Debug.Assert(false, "[CultureData.GetTimeFormatString(bool shortFormat)] Failed");
- return String.Empty;
- }
-
- return ConvertIcuTimeFormatString(StringBuilderCache.GetStringAndRelease(sb));
- }
-
- private int GetFirstDayOfWeek()
- {
- return this.GetLocaleInfo(LocaleNumberData.FirstDayOfWeek);
- }
-
- private String[] GetTimeFormats()
- {
- string format = GetTimeFormatString(false);
- return new string[] { format };
- }
-
- private String[] GetShortTimeFormats()
- {
- string format = GetTimeFormatString(true);
- return new string[] { format };
- }
-
- private static CultureData GetCultureDataFromRegionName(String regionName)
- {
- // no support to lookup by region name, other than the hard-coded list in CultureData
- return null;
- }
-
- private static string GetLanguageDisplayName(string cultureName)
- {
- return new CultureInfo(cultureName).m_cultureData.GetLocaleInfo(cultureName, LocaleStringData.LocalizedDisplayName);
- }
-
- private static string GetRegionDisplayName(string isoCountryCode)
- {
- // use the fallback which is to return NativeName
- return null;
- }
-
- private static CultureInfo GetUserDefaultCulture()
- {
- return CultureInfo.GetUserDefaultCulture();
- }
-
- private static string ConvertIcuTimeFormatString(string icuFormatString)
- {
- StringBuilder sb = StringBuilderCache.Acquire(ICU_ULOC_FULLNAME_CAPACITY);
- bool amPmAdded = false;
-
- for (int i = 0; i < icuFormatString.Length; i++)
- {
- switch(icuFormatString[i])
- {
- case ':':
- case '.':
- case 'H':
- case 'h':
- case 'm':
- case 's':
- sb.Append(icuFormatString[i]);
- break;
-
- case ' ':
- case '\u00A0':
- // Convert nonbreaking spaces into regular spaces
- sb.Append(' ');
- break;
-
- case 'a': // AM/PM
- if (!amPmAdded)
- {
- amPmAdded = true;
- sb.Append("tt");
- }
- break;
-
- }
- }
-
- return StringBuilderCache.GetStringAndRelease(sb);
- }
-
- private static string LCIDToLocaleName(int culture)
- {
- return LocaleData.LCIDToLocaleName(culture);
- }
-
- private static int LocaleNameToLCID(string cultureName)
- {
- int lcid = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.Lcid);
- return lcid == -1 ? CultureInfo.LOCALE_CUSTOM_UNSPECIFIED : lcid;
- }
-
- private static int GetAnsiCodePage(string cultureName)
- {
- int ansiCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.AnsiCodePage);
- return ansiCodePage == -1 ? CultureData.Invariant.IDEFAULTANSICODEPAGE : ansiCodePage;
- }
-
- private static int GetOemCodePage(string cultureName)
- {
- int oemCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.OemCodePage);
- return oemCodePage == -1 ? CultureData.Invariant.IDEFAULTOEMCODEPAGE : oemCodePage;
- }
-
- private static int GetMacCodePage(string cultureName)
- {
- int macCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.MacCodePage);
- return macCodePage == -1 ? CultureData.Invariant.IDEFAULTMACCODEPAGE : macCodePage;
- }
-
- private static int GetEbcdicCodePage(string cultureName)
- {
- int ebcdicCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.EbcdicCodePage);
- return ebcdicCodePage == -1 ? CultureData.Invariant.IDEFAULTEBCDICCODEPAGE : ebcdicCodePage;
- }
-
- private static int GetGeoId(string cultureName)
- {
- int geoId = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.GeoId);
- return geoId == -1 ? CultureData.Invariant.IGEOID : geoId;
- }
-
- private static int GetDigitSubstitution(string cultureName)
- {
- int digitSubstitution = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.DigitSubstitution);
- return digitSubstitution == -1 ? (int) DigitShapes.None : digitSubstitution;
- }
-
- private static string GetThreeLetterWindowsLanguageName(string cultureName)
- {
- string langName = LocaleData.GetThreeLetterWindowsLangageName(cultureName);
- return langName == null ? "ZZZ" /* default lang name */ : langName;
- }
-
- private static CultureInfo[] EnumCultures(CultureTypes types)
- {
- if ((types & (CultureTypes.NeutralCultures | CultureTypes.SpecificCultures)) == 0)
- {
- return Array.Empty<CultureInfo>();
- }
-
- int bufferLength = Interop.GlobalizationInterop.GetLocales(null, 0);
- if (bufferLength <= 0)
- {
- return Array.Empty<CultureInfo>();
- }
-
- Char [] chars = new Char[bufferLength];
-
- bufferLength = Interop.GlobalizationInterop.GetLocales(chars, bufferLength);
- if (bufferLength <= 0)
- {
- return Array.Empty<CultureInfo>();
- }
-
- bool enumNeutrals = (types & CultureTypes.NeutralCultures) != 0;
- bool enumSpecificss = (types & CultureTypes.SpecificCultures) != 0;
-
- List<CultureInfo> list = new List<CultureInfo>();
- if (enumNeutrals)
- {
- list.Add(CultureInfo.InvariantCulture);
- }
-
- int index = 0;
- while (index < bufferLength)
- {
- int length = (int) chars[index++];
- if (index + length <= bufferLength)
- {
- CultureInfo ci = CultureInfo.GetCultureInfo(new String(chars, index, length));
- if ((enumNeutrals && ci.IsNeutralCulture) || (enumSpecificss && !ci.IsNeutralCulture))
- {
- list.Add(ci);
- }
- }
-
- index += length;
- }
-
- return list.ToArray();
- }
-
- private static string GetConsoleFallbackName(string cultureName)
- {
- return LocaleData.GetConsoleUICulture(cultureName);
- }
-
- internal bool IsFramework // not applicable on Linux based systems
- {
- get { return false; }
- }
-
- internal bool IsWin32Installed // not applicable on Linux based systems
- {
- get { return false; }
- }
-
- internal bool IsReplacementCulture // not applicable on Linux based systems
- {
- get { return false; }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/CultureData.Windows.cs b/src/mscorlib/corefx/System/Globalization/CultureData.Windows.cs
deleted file mode 100644
index 0c264e5f8b..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CultureData.Windows.cs
+++ /dev/null
@@ -1,672 +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.Collections.Generic;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Text;
-
-#if ENABLE_WINRT
-using Internal.Runtime.Augments;
-#endif
-
-namespace System.Globalization
-{
- internal partial class CultureData
- {
- private const uint LOCALE_NOUSEROVERRIDE = 0x80000000;
- private const uint LOCALE_RETURN_NUMBER = 0x20000000;
- private const uint LOCALE_SISO3166CTRYNAME = 0x0000005A;
-
- private const uint TIME_NOSECONDS = 0x00000002;
-
- /// <summary>
- /// Check with the OS to see if this is a valid culture.
- /// If so we populate a limited number of fields. If its not valid we return false.
- ///
- /// The fields we populate:
- ///
- /// sWindowsName -- The name that windows thinks this culture is, ie:
- /// en-US if you pass in en-US
- /// de-DE_phoneb if you pass in de-DE_phoneb
- /// fj-FJ if you pass in fj (neutral, on a pre-Windows 7 machine)
- /// fj if you pass in fj (neutral, post-Windows 7 machine)
- ///
- /// sRealName -- The name you used to construct the culture, in pretty form
- /// en-US if you pass in EN-us
- /// en if you pass in en
- /// de-DE_phoneb if you pass in de-DE_phoneb
- ///
- /// sSpecificCulture -- The specific culture for this culture
- /// en-US for en-US
- /// en-US for en
- /// de-DE_phoneb for alt sort
- /// fj-FJ for fj (neutral)
- ///
- /// sName -- The IETF name of this culture (ie: no sort info, could be neutral)
- /// en-US if you pass in en-US
- /// en if you pass in en
- /// de-DE if you pass in de-DE_phoneb
- ///
- /// bNeutral -- TRUE if it is a neutral locale
- ///
- /// For a neutral we just populate the neutral name, but we leave the windows name pointing to the
- /// windows locale that's going to provide data for us.
- /// </summary>
- private unsafe bool InitCultureData()
- {
- const int LOCALE_NAME_MAX_LENGTH = 85;
-
- const uint LOCALE_ILANGUAGE = 0x00000001;
- const uint LOCALE_INEUTRAL = 0x00000071;
- const uint LOCALE_SNAME = 0x0000005c;
-
- int result;
- string realNameBuffer = _sRealName;
- char* pBuffer = stackalloc char[LOCALE_NAME_MAX_LENGTH];
-
- result = Interop.mincore.GetLocaleInfoEx(realNameBuffer, LOCALE_SNAME, pBuffer, LOCALE_NAME_MAX_LENGTH);
-
- // Did it fail?
- if (result == 0)
- {
- return false;
- }
-
- // It worked, note that the name is the locale name, so use that (even for neutrals)
- // We need to clean up our "real" name, which should look like the windows name right now
- // so overwrite the input with the cleaned up name
- _sRealName = new String(pBuffer, 0, result - 1);
- realNameBuffer = _sRealName;
-
- // Check for neutrality, don't expect to fail
- // (buffer has our name in it, so we don't have to do the gc. stuff)
-
- result = Interop.mincore.GetLocaleInfoEx(realNameBuffer, LOCALE_INEUTRAL | LOCALE_RETURN_NUMBER, pBuffer, sizeof(int) / sizeof(char));
- if (result == 0)
- {
- return false;
- }
-
- // Remember our neutrality
- _bNeutral = *((uint*)pBuffer) != 0;
-
- // Note: Parents will be set dynamically
-
- // Start by assuming the windows name'll be the same as the specific name since windows knows
- // about specifics on all versions. Only for downlevel Neutral locales does this have to change.
- _sWindowsName = realNameBuffer;
-
- // Neutrals and non-neutrals are slightly different
- if (_bNeutral)
- {
- // Neutral Locale
-
- // IETF name looks like neutral name
- _sName = realNameBuffer;
-
- // Specific locale name is whatever ResolveLocaleName (win7+) returns.
- // (Buffer has our name in it, and we can recycle that because windows resolves it before writing to the buffer)
- result = Interop.mincore.ResolveLocaleName(realNameBuffer, pBuffer, LOCALE_NAME_MAX_LENGTH);
-
- // 0 is failure, 1 is invariant (""), which we expect
- if (result < 1)
- {
- return false;
- }
- // We found a locale name, so use it.
- // In vista this should look like a sort name (de-DE_phoneb) or a specific culture (en-US) and be in the "pretty" form
- _sSpecificCulture = new String(pBuffer, 0, result - 1);
- }
- else
- {
- // Specific Locale
-
- // Specific culture's the same as the locale name since we know its not neutral
- // On mac we'll use this as well, even for neutrals. There's no obvious specific
- // culture to use and this isn't exposed, but behaviorally this is correct on mac.
- // Note that specifics include the sort name (de-DE_phoneb)
- _sSpecificCulture = realNameBuffer;
-
- _sName = realNameBuffer;
-
- // We need the IETF name (sname)
- // If we aren't an alt sort locale then this is the same as the windows name.
- // If we are an alt sort locale then this is the same as the part before the _ in the windows name
- // This is for like de-DE_phoneb and es-ES_tradnl that hsouldn't have the _ part
-
- result = Interop.mincore.GetLocaleInfoEx(realNameBuffer, LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER, pBuffer, sizeof(int) / sizeof(char));
- if (result == 0)
- {
- return false;
- }
-
- _iLanguage = *((int*)pBuffer);
-
- if (!IsCustomCultureId(_iLanguage))
- {
- // not custom locale
- int index = realNameBuffer.IndexOf('_');
- if (index > 0 && index < realNameBuffer.Length)
- {
- _sName = realNameBuffer.Substring(0, index);
- }
- }
- }
-
- // It succeeded.
- return true;
- }
-
- private string GetLocaleInfo(LocaleStringData type)
- {
- Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfo] Expected _sWindowsName to be populated by already");
- return GetLocaleInfo(_sWindowsName, type);
- }
-
- // For LOCALE_SPARENT we need the option of using the "real" name (forcing neutral names) instead of the
- // "windows" name, which can be specific for downlevel (< windows 7) os's.
- private string GetLocaleInfo(string localeName, LocaleStringData type)
- {
- uint lctype = (uint)type;
-
- return GetLocaleInfoFromLCType(localeName, lctype, UseUserOverride);
- }
-
- private int GetLocaleInfo(LocaleNumberData type)
- {
- uint lctype = (uint)type;
-
- // Fix lctype if we don't want overrides
- if (!UseUserOverride)
- {
- lctype |= LOCALE_NOUSEROVERRIDE;
- }
-
- // Ask OS for data, note that we presume it returns success, so we have to know that
- // sWindowsName is valid before calling.
- Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already");
- int result = Interop.mincore.GetLocaleInfoExInt(_sWindowsName, lctype);
-
- return result;
- }
-
- private int[] GetLocaleInfo(LocaleGroupingData type)
- {
- return ConvertWin32GroupString(GetLocaleInfoFromLCType(_sWindowsName, (uint)type, UseUserOverride));
- }
-
- private string GetTimeFormatString()
- {
- const uint LOCALE_STIMEFORMAT = 0x00001003;
-
- return ReescapeWin32String(GetLocaleInfoFromLCType(_sWindowsName, LOCALE_STIMEFORMAT, UseUserOverride));
- }
-
- private int GetFirstDayOfWeek()
- {
- Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already");
-
- const uint LOCALE_IFIRSTDAYOFWEEK = 0x0000100C;
-
- int result = Interop.mincore.GetLocaleInfoExInt(_sWindowsName, LOCALE_IFIRSTDAYOFWEEK | (!UseUserOverride ? LOCALE_NOUSEROVERRIDE : 0));
-
- // Win32 and .NET disagree on the numbering for days of the week, so we have to convert.
- return ConvertFirstDayOfWeekMonToSun(result);
- }
-
- private String[] GetTimeFormats()
- {
- // Note that this gets overrides for us all the time
- Debug.Assert(_sWindowsName != null, "[CultureData.DoEnumTimeFormats] Expected _sWindowsName to be populated by already");
- String[] result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, 0, UseUserOverride));
-
- return result;
- }
-
- private String[] GetShortTimeFormats()
- {
- // Note that this gets overrides for us all the time
- Debug.Assert(_sWindowsName != null, "[CultureData.DoEnumShortTimeFormats] Expected _sWindowsName to be populated by already");
- String[] result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, TIME_NOSECONDS, UseUserOverride));
-
- return result;
- }
-
- // Enumerate all system cultures and then try to find out which culture has
- // region name match the requested region name
- private static CultureData GetCultureDataFromRegionName(String regionName)
- {
- Debug.Assert(regionName != null);
-
- const uint LOCALE_SUPPLEMENTAL = 0x00000002;
- const uint LOCALE_SPECIFICDATA = 0x00000020;
-
- EnumLocaleData context = new EnumLocaleData();
- context.cultureName = null;
- context.regionName = regionName;
-
- GCHandle contextHandle = GCHandle.Alloc(context);
- try
- {
- IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, uint, IntPtr, Interop.BOOL>>(EnumSystemLocalesProc);
- Interop.mincore.EnumSystemLocalesEx(callback, LOCALE_SPECIFICDATA | LOCALE_SUPPLEMENTAL, (IntPtr)contextHandle, IntPtr.Zero);
- }
- finally
- {
- contextHandle.Free();
- }
-
- if (context.cultureName != null)
- {
- // we got a matched culture
- return GetCultureData(context.cultureName, true);
- }
-
- return null;
- }
-
- private string GetLanguageDisplayName(string cultureName)
- {
-#if ENABLE_WINRT
- return WinRTInterop.Callbacks.GetLanguageDisplayName(cultureName);
-#else
- // Usually the UI culture shouldn't be different than what we got from WinRT except
- // if DefaultThreadCurrentUICulture was set
- CultureInfo ci;
-
- if (CultureInfo.DefaultThreadCurrentUICulture != null &&
- ((ci = GetUserDefaultCulture()) != null) &&
- !CultureInfo.DefaultThreadCurrentUICulture.Name.Equals(ci.Name))
- {
- return SNATIVEDISPLAYNAME;
- }
- else
- {
- return GetLocaleInfo(cultureName, LocaleStringData.LocalizedDisplayName);
- }
-#endif // ENABLE_WINRT
- }
-
- private string GetRegionDisplayName(string isoCountryCode)
- {
-#if ENABLE_WINRT
- return WinRTInterop.Callbacks.GetRegionDisplayName(isoCountryCode);
-#else
- // Usually the UI culture shouldn't be different than what we got from WinRT except
- // if DefaultThreadCurrentUICulture was set
- CultureInfo ci;
-
- if (CultureInfo.DefaultThreadCurrentUICulture != null &&
- ((ci = GetUserDefaultCulture()) != null) &&
- !CultureInfo.DefaultThreadCurrentUICulture.Name.Equals(ci.Name))
- {
- return SNATIVECOUNTRY;
- }
- else
- {
- return GetLocaleInfo(LocaleStringData.LocalizedCountryName);
- }
-#endif // ENABLE_WINRT
- }
-
- private static CultureInfo GetUserDefaultCulture()
- {
-#if ENABLE_WINRT
- return (CultureInfo)WinRTInterop.Callbacks.GetUserDefaultCulture();
-#else
- return CultureInfo.GetUserDefaultCulture();
-#endif // ENABLE_WINRT
- }
-
- // PAL methods end here.
-
- private static string GetLocaleInfoFromLCType(string localeName, uint lctype, bool useUserOveride)
- {
- Debug.Assert(localeName != null, "[CultureData.GetLocaleInfoFromLCType] Expected localeName to be not be null");
-
- // Fix lctype if we don't want overrides
- if (!useUserOveride)
- {
- lctype |= LOCALE_NOUSEROVERRIDE;
- }
-
- // Ask OS for data
- string result = Interop.mincore.GetLocaleInfoEx(localeName, lctype);
- if (result == null)
- {
- // Failed, just use empty string
- result = String.Empty;
- }
-
- return result;
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Reescape a Win32 style quote string as a NLS+ style quoted string
- //
- // This is also the escaping style used by custom culture data files
- //
- // NLS+ uses \ to escape the next character, whether in a quoted string or
- // not, so we always have to change \ to \\.
- //
- // NLS+ uses \' to escape a quote inside a quoted string so we have to change
- // '' to \' (if inside a quoted string)
- //
- // We don't build the stringbuilder unless we find something to change
- ////////////////////////////////////////////////////////////////////////////
- internal static String ReescapeWin32String(String str)
- {
- // If we don't have data, then don't try anything
- if (str == null)
- return null;
-
- StringBuilder result = null;
-
- bool inQuote = false;
- for (int i = 0; i < str.Length; i++)
- {
- // Look for quote
- if (str[i] == '\'')
- {
- // Already in quote?
- if (inQuote)
- {
- // See another single quote. Is this '' of 'fred''s' or '''', or is it an ending quote?
- if (i + 1 < str.Length && str[i + 1] == '\'')
- {
- // Found another ', so we have ''. Need to add \' instead.
- // 1st make sure we have our stringbuilder
- if (result == null)
- result = new StringBuilder(str, 0, i, str.Length * 2);
-
- // Append a \' and keep going (so we don't turn off quote mode)
- result.Append("\\'");
- i++;
- continue;
- }
-
- // Turning off quote mode, fall through to add it
- inQuote = false;
- }
- else
- {
- // Found beginning quote, fall through to add it
- inQuote = true;
- }
- }
- // Is there a single \ character?
- else if (str[i] == '\\')
- {
- // Found a \, need to change it to \\
- // 1st make sure we have our stringbuilder
- if (result == null)
- result = new StringBuilder(str, 0, i, str.Length * 2);
-
- // Append our \\ to the string & continue
- result.Append("\\\\");
- continue;
- }
-
- // If we have a builder we need to add our character
- if (result != null)
- result.Append(str[i]);
- }
-
- // Unchanged string? , just return input string
- if (result == null)
- return str;
-
- // String changed, need to use the builder
- return result.ToString();
- }
-
- internal static String[] ReescapeWin32Strings(String[] array)
- {
- if (array != null)
- {
- for (int i = 0; i < array.Length; i++)
- {
- array[i] = ReescapeWin32String(array[i]);
- }
- }
-
- return array;
- }
-
- // If we get a group from windows, then its in 3;0 format with the 0 backwards
- // of how NLS+ uses it (ie: if the string has a 0, then the int[] shouldn't and vice versa)
- // EXCEPT in the case where the list only contains 0 in which NLS and NLS+ have the same meaning.
- private static int[] ConvertWin32GroupString(String win32Str)
- {
- // None of these cases make any sense
- if (win32Str == null || win32Str.Length == 0)
- {
- return (new int[] { 3 });
- }
-
- if (win32Str[0] == '0')
- {
- return (new int[] { 0 });
- }
-
- // Since its in n;n;n;n;n format, we can always get the length quickly
- int[] values;
- if (win32Str[win32Str.Length - 1] == '0')
- {
- // Trailing 0 gets dropped. 1;0 -> 1
- values = new int[(win32Str.Length / 2)];
- }
- else
- {
- // Need extra space for trailing zero 1 -> 1;0
- values = new int[(win32Str.Length / 2) + 2];
- values[values.Length - 1] = 0;
- }
-
- int i;
- int j;
- for (i = 0, j = 0; i < win32Str.Length && j < values.Length; i += 2, j++)
- {
- // Note that this # shouldn't ever be zero, 'cause 0 is only at end
- // But we'll test because its registry that could be anything
- if (win32Str[i] < '1' || win32Str[i] > '9')
- return new int[] { 3 };
-
- values[j] = (int)(win32Str[i] - '0');
- }
-
- return (values);
- }
-
- private static int ConvertFirstDayOfWeekMonToSun(int iTemp)
- {
- // Convert Mon-Sun to Sun-Sat format
- iTemp++;
- if (iTemp > 6)
- {
- // Wrap Sunday and convert invalid data to Sunday
- iTemp = 0;
- }
- return iTemp;
- }
-
-
- // Context for EnumCalendarInfoExEx callback.
- private class EnumLocaleData
- {
- public string regionName;
- public string cultureName;
- }
-
- // EnumSystemLocaleEx callback.
- [NativeCallable(CallingConvention = CallingConvention.StdCall)]
- private static unsafe Interop.BOOL EnumSystemLocalesProc(IntPtr lpLocaleString, uint flags, IntPtr contextHandle)
- {
- EnumLocaleData context = (EnumLocaleData)((GCHandle)contextHandle).Target;
- try
- {
- string cultureName = new string((char*)lpLocaleString);
- string regionName = Interop.mincore.GetLocaleInfoEx(cultureName, LOCALE_SISO3166CTRYNAME);
- if (regionName != null && regionName.Equals(context.regionName, StringComparison.OrdinalIgnoreCase))
- {
- context.cultureName = cultureName;
- return Interop.BOOL.FALSE; // we found a match, then stop the enumeration
- }
-
- return Interop.BOOL.TRUE;
- }
- catch (Exception)
- {
- return Interop.BOOL.FALSE;
- }
- }
-
- // Context for EnumTimeFormatsEx callback.
- private class EnumData
- {
- public LowLevelList<string> strings;
- }
-
- // EnumTimeFormatsEx callback itself.
- [NativeCallable(CallingConvention = CallingConvention.StdCall)]
- private static unsafe Interop.BOOL EnumTimeCallback(IntPtr lpTimeFormatString, IntPtr lParam)
- {
- EnumData context = (EnumData)((GCHandle)lParam).Target;
-
- try
- {
- context.strings.Add(new string((char*)lpTimeFormatString));
- return Interop.BOOL.TRUE;
- }
- catch (Exception)
- {
- return Interop.BOOL.FALSE;
- }
- }
-
- private static unsafe String[] nativeEnumTimeFormats(String localeName, uint dwFlags, bool useUserOverride)
- {
- const uint LOCALE_SSHORTTIME = 0x00000079;
- const uint LOCALE_STIMEFORMAT = 0x00001003;
-
- EnumData data = new EnumData();
- data.strings = new LowLevelList<string>();
-
- GCHandle dataHandle = GCHandle.Alloc(data);
- try
- {
- // Now call the enumeration API. Work is done by our callback function
- IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, IntPtr, Interop.BOOL>>(EnumTimeCallback);
- Interop.mincore.EnumTimeFormatsEx(callback, localeName, (uint)dwFlags, (IntPtr)dataHandle);
- }
- finally
- {
- dataHandle.Free();
- }
-
- if (data.strings.Count > 0)
- {
- // Now we need to allocate our stringarray and populate it
- string[] results = data.strings.ToArray();
-
- if (!useUserOverride && data.strings.Count > 1)
- {
- // Since there is no "NoUserOverride" aware EnumTimeFormatsEx, we always get an override
- // The override is the first entry if it is overriden.
- // We can check if we have overrides by checking the GetLocaleInfo with no override
- // If we do have an override, we don't know if it is a user defined override or if the
- // user has just selected one of the predefined formats so we can't just remove it
- // but we can move it down.
- uint lcType = (dwFlags == TIME_NOSECONDS) ? LOCALE_SSHORTTIME : LOCALE_STIMEFORMAT;
- string timeFormatNoUserOverride = GetLocaleInfoFromLCType(localeName, lcType, useUserOverride);
- if (timeFormatNoUserOverride != "")
- {
- string firstTimeFormat = results[0];
- if (timeFormatNoUserOverride != firstTimeFormat)
- {
- results[0] = results[1];
- results[1] = firstTimeFormat;
- }
- }
- }
-
- return results;
- }
-
- return null;
- }
-
- private int LocaleNameToLCID(string cultureName)
- {
- return GetLocaleInfo(LocaleNumberData.LanguageId);
- }
-
- private static string LCIDToLocaleName(int culture)
- {
- throw new NotImplementedException();
- }
-
- private int GetAnsiCodePage(string cultureName)
- {
- return GetLocaleInfo(LocaleNumberData.AnsiCodePage);
- }
-
- private int GetOemCodePage(string cultureName)
- {
- return GetLocaleInfo(LocaleNumberData.OemCodePage);
- }
-
- private int GetMacCodePage(string cultureName)
- {
- return GetLocaleInfo(LocaleNumberData.MacCodePage);
- }
-
- private int GetEbcdicCodePage(string cultureName)
- {
- return GetLocaleInfo(LocaleNumberData.EbcdicCodePage);
- }
-
- private int GetGeoId(string cultureName)
- {
- return GetLocaleInfo(LocaleNumberData.GeoId);
- }
-
- private int GetDigitSubstitution(string cultureName)
- {
- return GetLocaleInfo(LocaleNumberData.DigitSubstitution);
- }
-
- private string GetThreeLetterWindowsLanguageName(string cultureName)
- {
- return GetLocaleInfo(cultureName, LocaleStringData.AbbreviatedWindowsLanguageName);
- }
-
- private static CultureInfo[] EnumCultures(CultureTypes types)
- {
- throw new NotImplementedException();
- }
-
- private string GetConsoleFallbackName(string cultureName)
- {
- return GetLocaleInfo(cultureName, LocaleStringData.ConsoleFallbackName);
- }
-
- internal bool IsFramework
- {
- get { throw new NotImplementedException(); }
- }
-
- internal bool IsWin32Installed
- {
- get { throw new NotImplementedException(); }
- }
-
- internal bool IsReplacementCulture
- {
- get { throw new NotImplementedException(); }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/CultureData.cs b/src/mscorlib/corefx/System/Globalization/CultureData.cs
deleted file mode 100644
index c15a77cf45..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CultureData.cs
+++ /dev/null
@@ -1,2470 +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.Collections.Generic;
-using System.Diagnostics;
-using System.Text;
-using System.Threading;
-
-namespace System.Globalization
-{
-
-#if INSIDE_CLR
- using StringStringDictionary = Dictionary<string, string>;
- using StringCultureDataDictionary = Dictionary<string, CultureData>;
- using LcidToCultureNameDictionary = Dictionary<int, string>;
- using Lock = Object;
-#else
- using StringStringDictionary = LowLevelDictionary<string, string>;
- using StringCultureDataDictionary = LowLevelDictionary<string, CultureData>;
- using LcidToCultureNameDictionary = LowLevelDictionary<int, string>;
-#endif
-
- //
- // List of culture data
- // Note the we cache overrides.
- // Note that localized names (resource names) aren't available from here.
- //
-
- //
- // Our names are a tad confusing.
- //
- // sWindowsName -- The name that windows thinks this culture is, ie:
- // en-US if you pass in en-US
- // de-DE_phoneb if you pass in de-DE_phoneb
- // fj-FJ if you pass in fj (neutral, on a pre-Windows 7 machine)
- // fj if you pass in fj (neutral, post-Windows 7 machine)
- //
- // sRealName -- The name you used to construct the culture, in pretty form
- // en-US if you pass in EN-us
- // en if you pass in en
- // de-DE_phoneb if you pass in de-DE_phoneb
- //
- // sSpecificCulture -- The specific culture for this culture
- // en-US for en-US
- // en-US for en
- // de-DE_phoneb for alt sort
- // fj-FJ for fj (neutral)
- //
- // sName -- The IETF name of this culture (ie: no sort info, could be neutral)
- // en-US if you pass in en-US
- // en if you pass in en
- // de-DE if you pass in de-DE_phoneb
- //
- internal partial class CultureData
- {
- private const int undef = -1;
-
- // Override flag
- private String _sRealName; // Name you passed in (ie: en-US, en, or de-DE_phoneb)
- private String _sWindowsName; // Name OS thinks the object is (ie: de-DE_phoneb, or en-US (even if en was passed in))
-
- // Identity
- private String _sName; // locale name (ie: en-us, NO sort info, but could be neutral)
- private String _sParent; // Parent name (which may be a custom locale/culture)
- private String _sLocalizedDisplayName; // Localized pretty name for this locale
- private String _sEnglishDisplayName; // English pretty name for this locale
- private String _sNativeDisplayName; // Native pretty name for this locale
- private String _sSpecificCulture; // The culture name to be used in CultureInfo.CreateSpecificCulture(), en-US form if neutral, sort name if sort
-
- // Language
- private String _sISO639Language; // ISO 639 Language Name
- private String _sISO639Language2; // ISO 639 Language Name
- private String _sLocalizedLanguage; // Localized name for this language
- private String _sEnglishLanguage; // English name for this language
- private String _sNativeLanguage; // Native name of this language
- private String _sAbbrevLang; // abbreviated language name (Windows Language Name) ex: ENU
- private string _sConsoleFallbackName; // The culture name for the console fallback UI culture
- private int _iInputLanguageHandle=undef;// input language handle
-
- // Region
- private String _sRegionName; // (RegionInfo)
- private String _sLocalizedCountry; // localized country name
- private String _sEnglishCountry; // english country name (RegionInfo)
- private String _sNativeCountry; // native country name
- private String _sISO3166CountryName; // ISO 3166 (RegionInfo), ie: US
- private String _sISO3166CountryName2; // 3 char ISO 3166 country name 2 2(RegionInfo) ex: USA (ISO)
- private int _iGeoId = undef; // GeoId
-
- // Numbers
- private String _sPositiveSign; // (user can override) positive sign
- private String _sNegativeSign; // (user can override) negative sign
- // (nfi populates these 5, don't have to be = undef)
- private int _iDigits; // (user can override) number of fractional digits
- private int _iNegativeNumber; // (user can override) negative number format
- private int[] _waGrouping; // (user can override) grouping of digits
- private String _sDecimalSeparator; // (user can override) decimal separator
- private String _sThousandSeparator; // (user can override) thousands separator
- private String _sNaN; // Not a Number
- private String _sPositiveInfinity; // + Infinity
- private String _sNegativeInfinity; // - Infinity
-
- // Percent
- private int _iNegativePercent = undef; // Negative Percent (0-3)
- private int _iPositivePercent = undef; // Positive Percent (0-11)
- private String _sPercent; // Percent (%) symbol
- private String _sPerMille; // PerMille symbol
-
- // Currency
- private String _sCurrency; // (user can override) local monetary symbol
- private String _sIntlMonetarySymbol; // international monetary symbol (RegionInfo)
- private String _sEnglishCurrency; // English name for this currency
- private String _sNativeCurrency; // Native name for this currency
- // (nfi populates these 4, don't have to be = undef)
- private int _iCurrencyDigits; // (user can override) # local monetary fractional digits
- private int _iCurrency; // (user can override) positive currency format
- private int _iNegativeCurrency; // (user can override) negative currency format
- private int[] _waMonetaryGrouping; // (user can override) monetary grouping of digits
- private String _sMonetaryDecimal; // (user can override) monetary decimal separator
- private String _sMonetaryThousand; // (user can override) monetary thousands separator
-
- // Misc
- private int _iMeasure = undef; // (user can override) system of measurement 0=metric, 1=US (RegionInfo)
- private String _sListSeparator; // (user can override) list separator
-
- // Time
- private String _sAM1159; // (user can override) AM designator
- private String _sPM2359; // (user can override) PM designator
- private String _sTimeSeparator;
- private volatile String[] _saLongTimes; // (user can override) time format
- private volatile String[] _saShortTimes; // short time format
- private volatile String[] _saDurationFormats; // time duration format
-
- // Calendar specific data
- private int _iFirstDayOfWeek = undef; // (user can override) first day of week (gregorian really)
- private int _iFirstWeekOfYear = undef; // (user can override) first week of year (gregorian really)
- private volatile CalendarId[] _waCalendars; // all available calendar type(s). The first one is the default calendar
-
- // Store for specific data about each calendar
- private CalendarData[] _calendars; // Store for specific calendar data
-
- // Text information
- private int _iReadingLayout = undef; // Reading layout data
- // 0 - Left to right (eg en-US)
- // 1 - Right to left (eg arabic locales)
- // 2 - Vertical top to bottom with columns to the left and also left to right (ja-JP locales)
- // 3 - Vertical top to bottom with columns proceeding to the right
-
- // CoreCLR depends on this even though its not exposed publicly.
-
- private int _iDefaultAnsiCodePage = undef; // default ansi code page ID (ACP)
- private int _iDefaultOemCodePage = undef; // default oem code page ID (OCP or OEM)
- private int _iDefaultMacCodePage = undef; // default macintosh code page
- private int _iDefaultEbcdicCodePage = undef; // default EBCDIC code page
-
- private int _iLanguage; // locale ID (0409) - NO sort information
- private bool _bUseOverrides; // use user overrides?
- private bool _bNeutral; // Flags for the culture (ie: neutral or not right now)
-
-
- // Region Name to Culture Name mapping table
- // (In future would be nice to be in registry or something)
-
- //Using a property so we avoid creating the dictionary untill we need it
- private static StringStringDictionary RegionNames
- {
- get
- {
- if (s_RegionNames == null)
- {
- StringStringDictionary regionNames = new StringStringDictionary(211 /* prime */);
-
- regionNames.Add("029", "en-029");
- regionNames.Add("AE", "ar-AE");
- regionNames.Add("AF", "prs-AF");
- regionNames.Add("AL", "sq-AL");
- regionNames.Add("AM", "hy-AM");
- regionNames.Add("AR", "es-AR");
- regionNames.Add("AT", "de-AT");
- regionNames.Add("AU", "en-AU");
- regionNames.Add("AZ", "az-Cyrl-AZ");
- regionNames.Add("BA", "bs-Latn-BA");
- regionNames.Add("BD", "bn-BD");
- regionNames.Add("BE", "nl-BE");
- regionNames.Add("BG", "bg-BG");
- regionNames.Add("BH", "ar-BH");
- regionNames.Add("BN", "ms-BN");
- regionNames.Add("BO", "es-BO");
- regionNames.Add("BR", "pt-BR");
- regionNames.Add("BY", "be-BY");
- regionNames.Add("BZ", "en-BZ");
- regionNames.Add("CA", "en-CA");
- regionNames.Add("CH", "it-CH");
- regionNames.Add("CL", "es-CL");
- regionNames.Add("CN", "zh-CN");
- regionNames.Add("CO", "es-CO");
- regionNames.Add("CR", "es-CR");
- regionNames.Add("CS", "sr-Cyrl-CS");
- regionNames.Add("CZ", "cs-CZ");
- regionNames.Add("DE", "de-DE");
- regionNames.Add("DK", "da-DK");
- regionNames.Add("DO", "es-DO");
- regionNames.Add("DZ", "ar-DZ");
- regionNames.Add("EC", "es-EC");
- regionNames.Add("EE", "et-EE");
- regionNames.Add("EG", "ar-EG");
- regionNames.Add("ES", "es-ES");
- regionNames.Add("ET", "am-ET");
- regionNames.Add("FI", "fi-FI");
- regionNames.Add("FO", "fo-FO");
- regionNames.Add("FR", "fr-FR");
- regionNames.Add("GB", "en-GB");
- regionNames.Add("GE", "ka-GE");
- regionNames.Add("GL", "kl-GL");
- regionNames.Add("GR", "el-GR");
- regionNames.Add("GT", "es-GT");
- regionNames.Add("HK", "zh-HK");
- regionNames.Add("HN", "es-HN");
- regionNames.Add("HR", "hr-HR");
- regionNames.Add("HU", "hu-HU");
- regionNames.Add("ID", "id-ID");
- regionNames.Add("IE", "en-IE");
- regionNames.Add("IL", "he-IL");
- regionNames.Add("IN", "hi-IN");
- regionNames.Add("IQ", "ar-IQ");
- regionNames.Add("IR", "fa-IR");
- regionNames.Add("IS", "is-IS");
- regionNames.Add("IT", "it-IT");
- regionNames.Add("IV", "");
- regionNames.Add("JM", "en-JM");
- regionNames.Add("JO", "ar-JO");
- regionNames.Add("JP", "ja-JP");
- regionNames.Add("KE", "sw-KE");
- regionNames.Add("KG", "ky-KG");
- regionNames.Add("KH", "km-KH");
- regionNames.Add("KR", "ko-KR");
- regionNames.Add("KW", "ar-KW");
- regionNames.Add("KZ", "kk-KZ");
- regionNames.Add("LA", "lo-LA");
- regionNames.Add("LB", "ar-LB");
- regionNames.Add("LI", "de-LI");
- regionNames.Add("LK", "si-LK");
- regionNames.Add("LT", "lt-LT");
- regionNames.Add("LU", "lb-LU");
- regionNames.Add("LV", "lv-LV");
- regionNames.Add("LY", "ar-LY");
- regionNames.Add("MA", "ar-MA");
- regionNames.Add("MC", "fr-MC");
- regionNames.Add("ME", "sr-Latn-ME");
- regionNames.Add("MK", "mk-MK");
- regionNames.Add("MN", "mn-MN");
- regionNames.Add("MO", "zh-MO");
- regionNames.Add("MT", "mt-MT");
- regionNames.Add("MV", "dv-MV");
- regionNames.Add("MX", "es-MX");
- regionNames.Add("MY", "ms-MY");
- regionNames.Add("NG", "ig-NG");
- regionNames.Add("NI", "es-NI");
- regionNames.Add("NL", "nl-NL");
- regionNames.Add("NO", "nn-NO");
- regionNames.Add("NP", "ne-NP");
- regionNames.Add("NZ", "en-NZ");
- regionNames.Add("OM", "ar-OM");
- regionNames.Add("PA", "es-PA");
- regionNames.Add("PE", "es-PE");
- regionNames.Add("PH", "en-PH");
- regionNames.Add("PK", "ur-PK");
- regionNames.Add("PL", "pl-PL");
- regionNames.Add("PR", "es-PR");
- regionNames.Add("PT", "pt-PT");
- regionNames.Add("PY", "es-PY");
- regionNames.Add("QA", "ar-QA");
- regionNames.Add("RO", "ro-RO");
- regionNames.Add("RS", "sr-Latn-RS");
- regionNames.Add("RU", "ru-RU");
- regionNames.Add("RW", "rw-RW");
- regionNames.Add("SA", "ar-SA");
- regionNames.Add("SE", "sv-SE");
- regionNames.Add("SG", "zh-SG");
- regionNames.Add("SI", "sl-SI");
- regionNames.Add("SK", "sk-SK");
- regionNames.Add("SN", "wo-SN");
- regionNames.Add("SV", "es-SV");
- regionNames.Add("SY", "ar-SY");
- regionNames.Add("TH", "th-TH");
- regionNames.Add("TJ", "tg-Cyrl-TJ");
- regionNames.Add("TM", "tk-TM");
- regionNames.Add("TN", "ar-TN");
- regionNames.Add("TR", "tr-TR");
- regionNames.Add("TT", "en-TT");
- regionNames.Add("TW", "zh-TW");
- regionNames.Add("UA", "uk-UA");
- regionNames.Add("US", "en-US");
- regionNames.Add("UY", "es-UY");
- regionNames.Add("UZ", "uz-Cyrl-UZ");
- regionNames.Add("VE", "es-VE");
- regionNames.Add("VN", "vi-VN");
- regionNames.Add("YE", "ar-YE");
- regionNames.Add("ZA", "af-ZA");
- regionNames.Add("ZW", "en-ZW");
-
- s_RegionNames = regionNames;
- }
-
- return s_RegionNames;
- }
- }
-
- // Cache of regions we've already looked up
- private static volatile StringCultureDataDictionary s_cachedRegions;
- private static volatile StringStringDictionary s_RegionNames;
-
- internal static CultureData GetCultureDataForRegion(String cultureName, bool useUserOverride)
- {
- // First do a shortcut for Invariant
- if (String.IsNullOrEmpty(cultureName))
- {
- return CultureData.Invariant;
- }
-
- //
- // First check if GetCultureData() can find it (ie: its a real culture)
- //
- CultureData retVal = GetCultureData(cultureName, useUserOverride);
- if (retVal != null && (retVal.IsNeutralCulture == false)) return retVal;
-
- //
- // Not a specific culture, perhaps it's region-only name
- // (Remember this isn't a core clr path where that's not supported)
- //
-
- // If it was neutral remember that so that RegionInfo() can throw the right exception
- CultureData neutral = retVal;
-
- // Try the hash table next
- String hashName = AnsiToLower(useUserOverride ? cultureName : cultureName + '*');
- StringCultureDataDictionary tempHashTable = s_cachedRegions;
- if (tempHashTable == null)
- {
- // No table yet, make a new one
- tempHashTable = new StringCultureDataDictionary();
- }
- else
- {
- // Check the hash table
- lock (s_lock)
- {
- tempHashTable.TryGetValue(hashName, out retVal);
- }
- if (retVal != null)
- {
- return retVal;
- }
- }
-
- //
- // Not found in the hash table, look it up the hard way
- //
-
- // If not a valid mapping from the registry we'll have to try the hard coded table
- if (retVal == null || (retVal.IsNeutralCulture == true))
- {
- // Not a valid mapping, try the hard coded table
- string name;
- if (RegionNames.TryGetValue(cultureName, out name))
- {
- // Make sure we can get culture data for it
- retVal = GetCultureData(name, useUserOverride);
- }
- }
-
- // If not found in the hard coded table we'll have to find a culture that works for us
- if (retVal == null || (retVal.IsNeutralCulture == true))
- {
- retVal = GetCultureDataFromRegionName(cultureName);
- }
-
- // If we found one we can use, then cache it for next time
- if (retVal != null && (retVal.IsNeutralCulture == false))
- {
- // first add it to the cache
- lock (s_lock)
- {
- tempHashTable[hashName] = retVal;
- }
-
- // Copy the hashtable to the corresponding member variables. This will potentially overwrite
- // new tables simultaneously created by a new thread, but maximizes thread safety.
- s_cachedRegions = tempHashTable;
- }
- else
- {
- // Unable to find a matching culture/region, return null or neutral
- // (regionInfo throws a more specific exception on neutrals)
- retVal = neutral;
- }
-
- // Return the found culture to use, null, or the neutral culture.
- return retVal;
- }
-
- // Clear our internal caches
- internal static void ClearCachedData()
- {
- s_cachedCultures = null;
- s_cachedRegions = null;
- }
-
- internal static CultureInfo[] GetCultures(CultureTypes types)
- {
- // Disable warning 618: System.Globalization.CultureTypes.FrameworkCultures' is obsolete
-#pragma warning disable 618
- // Validate flags
- if ((int)types <= 0 || ((int)types & (int)~(CultureTypes.NeutralCultures | CultureTypes.SpecificCultures |
- CultureTypes.InstalledWin32Cultures | CultureTypes.UserCustomCulture |
- CultureTypes.ReplacementCultures | CultureTypes.WindowsOnlyCultures |
- CultureTypes.FrameworkCultures)) != 0)
- {
- throw new ArgumentOutOfRangeException(nameof(types),
- SR.Format(SR.ArgumentOutOfRange_Range, CultureTypes.NeutralCultures, CultureTypes.FrameworkCultures));
- }
-
- // We have deprecated CultureTypes.FrameworkCultures.
- // When this enum is used, we will enumerate Whidbey framework cultures (for compatibility).
- //
-
- // We have deprecated CultureTypes.WindowsOnlyCultures.
- // When this enum is used, we will return an empty array for this enum.
- if ((types & CultureTypes.WindowsOnlyCultures) != 0)
- {
- // Remove the enum as it is an no-op.
- types &= (~CultureTypes.WindowsOnlyCultures);
- }
-
-#pragma warning restore 618
- return EnumCultures(types);
- }
-
- /////////////////////////////////////////////////////////////////////////
- // Build our invariant information
- //
- // We need an invariant instance, which we build hard-coded
- /////////////////////////////////////////////////////////////////////////
- internal static CultureData Invariant
- {
- get
- {
- if (s_Invariant == null)
- {
- // Make a new culturedata
- CultureData invariant = new CultureData();
-
- // Basics
- // Note that we override the resources since this IS NOT supposed to change (by definition)
- invariant._bUseOverrides = false;
- invariant._sRealName = ""; // Name you passed in (ie: en-US, en, or de-DE_phoneb)
- invariant._sWindowsName = ""; // Name OS thinks the object is (ie: de-DE_phoneb, or en-US (even if en was passed in))
-
- // Identity
- invariant._sName = ""; // locale name (ie: en-us)
- invariant._sParent = ""; // Parent name (which may be a custom locale/culture)
- invariant._bNeutral = false; // Flags for the culture (ie: neutral or not right now)
- invariant._sEnglishDisplayName = "Invariant Language (Invariant Country)"; // English pretty name for this locale
- invariant._sNativeDisplayName = "Invariant Language (Invariant Country)"; // Native pretty name for this locale
- invariant._sSpecificCulture = ""; // The culture name to be used in CultureInfo.CreateSpecificCulture()
-
- // Language
- invariant._sISO639Language = "iv"; // ISO 639 Language Name
- invariant._sISO639Language2 = "ivl"; // 3 char ISO 639 lang name 2
- invariant._sLocalizedLanguage = "Invariant Language"; // Display name for this Language
- invariant._sEnglishLanguage = "Invariant Language"; // English name for this language
- invariant._sNativeLanguage = "Invariant Language"; // Native name of this language
- invariant._sAbbrevLang = "IVL"; // abbreviated language name (Windows Language Name)
- invariant._sConsoleFallbackName = ""; // The culture name for the console fallback UI culture
- invariant._iInputLanguageHandle = 0x07F; // input language handle
-
- // Region
- invariant._sRegionName = "IV"; // (RegionInfo)
- invariant._sEnglishCountry = "Invariant Country"; // english country name (RegionInfo)
- invariant._sNativeCountry = "Invariant Country"; // native country name (Windows Only)
- invariant._sISO3166CountryName = "IV"; // (RegionInfo), ie: US
- invariant._sISO3166CountryName2 = "ivc"; // 3 char ISO 3166 country name 2 2(RegionInfo)
- invariant._iGeoId = 244; // GeoId (Windows Only)
-
- // Numbers
- invariant._sPositiveSign = "+"; // positive sign
- invariant._sNegativeSign = "-"; // negative sign
- invariant._iDigits = 2; // number of fractional digits
- invariant._iNegativeNumber = 1; // negative number format
- invariant._waGrouping = new int[] { 3 }; // grouping of digits
- invariant._sDecimalSeparator = "."; // decimal separator
- invariant._sThousandSeparator = ","; // thousands separator
- invariant._sNaN = "NaN"; // Not a Number
- invariant._sPositiveInfinity = "Infinity"; // + Infinity
- invariant._sNegativeInfinity = "-Infinity"; // - Infinity
-
- // Percent
- invariant._iNegativePercent = 0; // Negative Percent (0-3)
- invariant._iPositivePercent = 0; // Positive Percent (0-11)
- invariant._sPercent = "%"; // Percent (%) symbol
- invariant._sPerMille = "\x2030"; // PerMille symbol
-
- // Currency
- invariant._sCurrency = "\x00a4"; // local monetary symbol: for international monetary symbol
- invariant._sIntlMonetarySymbol = "XDR"; // international monetary symbol (RegionInfo)
- invariant._sEnglishCurrency = "International Monetary Fund"; // English name for this currency (Windows Only)
- invariant._sNativeCurrency = "International Monetary Fund"; // Native name for this currency (Windows Only)
- invariant._iCurrencyDigits = 2; // # local monetary fractional digits
- invariant._iCurrency = 0; // positive currency format
- invariant._iNegativeCurrency = 0; // negative currency format
- invariant._waMonetaryGrouping = new int[] { 3 }; // monetary grouping of digits
- invariant._sMonetaryDecimal = "."; // monetary decimal separator
- invariant._sMonetaryThousand = ","; // monetary thousands separator
-
- // Misc
- invariant._iMeasure = 0; // system of measurement 0=metric, 1=US (RegionInfo)
- invariant._sListSeparator = ","; // list separator
-
- // Time
- invariant._sAM1159 = "AM"; // AM designator
- invariant._sPM2359 = "PM"; // PM designator
- invariant._saLongTimes = new String[] { "HH:mm:ss" }; // time format
- invariant._saShortTimes = new String[] { "HH:mm", "hh:mm tt", "H:mm", "h:mm tt" }; // short time format
- invariant._saDurationFormats = new String[] { "HH:mm:ss" }; // time duration format
-
-
- // Calendar specific data
- invariant._iFirstDayOfWeek = 0; // first day of week
- invariant._iFirstWeekOfYear = 0; // first week of year
- invariant._waCalendars = new CalendarId[] { CalendarId.GREGORIAN }; // all available calendar type(s). The first one is the default calendar
-
- // Store for specific data about each calendar
- invariant._calendars = new CalendarData[CalendarData.MAX_CALENDARS];
- invariant._calendars[0] = CalendarData.Invariant;
-
- // Text information
- invariant._iReadingLayout = 0;
-
- // These are desktop only, not coreclr
-
- invariant._iLanguage = CultureInfo.LOCALE_INVARIANT; // locale ID (0409) - NO sort information
- invariant._iDefaultAnsiCodePage = 1252; // default ansi code page ID (ACP)
- invariant._iDefaultOemCodePage = 437; // default oem code page ID (OCP or OEM)
- invariant._iDefaultMacCodePage = 10000; // default macintosh code page
- invariant._iDefaultEbcdicCodePage = 037; // default EBCDIC code page
- // Remember it
- s_Invariant = invariant;
- }
- return s_Invariant;
- }
- }
- private volatile static CultureData s_Invariant;
-
- ///////////////
- // Constructors //
- ///////////////
- // Cache of cultures we've already looked up
- private static volatile StringCultureDataDictionary s_cachedCultures;
- private static readonly Lock s_lock = new Lock();
-
- internal static CultureData GetCultureData(String cultureName, bool useUserOverride)
- {
- // First do a shortcut for Invariant
- if (String.IsNullOrEmpty(cultureName))
- {
- return CultureData.Invariant;
- }
-
- // Try the hash table first
- String hashName = AnsiToLower(useUserOverride ? cultureName : cultureName + '*');
- StringCultureDataDictionary tempHashTable = s_cachedCultures;
- if (tempHashTable == null)
- {
- // No table yet, make a new one
- tempHashTable = new StringCultureDataDictionary();
- }
- else
- {
- // Check the hash table
- bool ret;
- CultureData retVal;
- lock (s_lock)
- {
- ret = tempHashTable.TryGetValue(hashName, out retVal);
- }
- if (ret && retVal != null)
- {
- return retVal;
- }
- }
-
- // Not found in the hash table, need to see if we can build one that works for us
- CultureData culture = CreateCultureData(cultureName, useUserOverride);
- if (culture == null)
- {
- return null;
- }
-
- // Found one, add it to the cache
- lock (s_lock)
- {
- tempHashTable[hashName] = culture;
- }
-
- // Copy the hashtable to the corresponding member variables. This will potentially overwrite
- // new tables simultaneously created by a new thread, but maximizes thread safety.
- s_cachedCultures = tempHashTable;
-
- return culture;
- }
-
- private static CultureData CreateCultureData(string cultureName, bool useUserOverride)
- {
- CultureData culture = new CultureData();
- culture._bUseOverrides = useUserOverride;
- culture._sRealName = cultureName;
-
- // Ask native code if that one's real
- if (culture.InitCultureData() == false)
- {
- if (culture.InitCompatibilityCultureData() == false)
- {
- return null;
- }
- }
-
- return culture;
- }
-
- private bool InitCompatibilityCultureData()
- {
- // for compatibility handle the deprecated ids: zh-chs, zh-cht
- string cultureName = _sRealName;
-
- string fallbackCultureName;
- string realCultureName;
- switch (AnsiToLower(cultureName))
- {
- case "zh-chs":
- fallbackCultureName = "zh-Hans";
- realCultureName = "zh-CHS";
- break;
- case "zh-cht":
- fallbackCultureName = "zh-Hant";
- realCultureName = "zh-CHT";
- break;
- default:
- return false;
- }
-
- _sRealName = fallbackCultureName;
- if (InitCultureData() == false)
- {
- return false;
- }
- // fixup our data
- _sName = realCultureName; // the name that goes back to the user
- _sParent = fallbackCultureName;
-
- return true;
- }
-
- // We'd rather people use the named version since this doesn't allow custom locales
- internal static CultureData GetCultureData(int culture, bool bUseUserOverride)
- {
- string localeName = null;
- CultureData retVal = null;
-
- if (culture == CultureInfo.LOCALE_INVARIANT)
- return Invariant;
-
- // Convert the lcid to a name, then use that
- // Note that this'll return neutral names (unlike Vista native API)
- localeName = LCIDToLocaleName(culture);
-
- if (!String.IsNullOrEmpty(localeName))
- {
- // Valid name, use it
- retVal = GetCultureData(localeName, bUseUserOverride);
- }
-
- // If not successful, throw
- if (retVal == null)
- throw new CultureNotFoundException(nameof(culture), culture, SR.Argument_CultureNotSupported);
-
- // Return the one we found
- return retVal;
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // All the accessors
- //
- // Accessors for our data object items
- //
- ////////////////////////////////////////////////////////////////////////
-
- ///////////
- // Identity //
- ///////////
-
- // The real name used to construct the locale (ie: de-DE_phoneb)
- internal String CultureName
- {
- get
- {
- Debug.Assert(_sRealName != null, "[CultureData.CultureName] Expected _sRealName to be populated by already");
- // since windows doesn't know about zh-CHS and zh-CHT,
- // we leave sRealName == zh-Hanx but we still need to
- // pretend that it was zh-CHX.
- switch (_sName)
- {
- case "zh-CHS":
- case "zh-CHT":
- return _sName;
- }
- return _sRealName;
- }
- }
-
- // Are overrides enabled?
- internal bool UseUserOverride
- {
- get
- {
- return _bUseOverrides;
- }
- }
-
- // locale name (ie: de-DE, NO sort information)
- internal String SNAME
- {
- get
- {
- if (_sName == null)
- {
- _sName = String.Empty;
- }
- return _sName;
- }
- }
-
- // Parent name (which may be a custom locale/culture)
- internal String SPARENT
- {
- get
- {
- if (_sParent == null)
- {
- // Ask using the real name, so that we get parents of neutrals
- _sParent = GetLocaleInfo(_sRealName, LocaleStringData.ParentName);
- }
- return _sParent;
- }
- }
-
- // Localized pretty name for this locale (ie: Inglis (estados Unitos))
- internal String SLOCALIZEDDISPLAYNAME
- {
- get
- {
- if (_sLocalizedDisplayName == null)
- {
- if (this.IsSupplementalCustomCulture)
- {
- if (this.IsNeutralCulture)
- {
- _sLocalizedDisplayName = this.SNATIVELANGUAGE;
- }
- else
- {
- _sLocalizedDisplayName = this.SNATIVEDISPLAYNAME;
- }
- }
- else
- {
- try
- {
- const string ZH_CHT = "zh-CHT";
- const string ZH_CHS = "zh-CHS";
-
- if (SNAME.Equals(ZH_CHT, StringComparison.OrdinalIgnoreCase))
- {
- _sLocalizedDisplayName = GetLanguageDisplayName("zh-Hant");
- }
- else if (SNAME.Equals(ZH_CHS, StringComparison.OrdinalIgnoreCase))
- {
- _sLocalizedDisplayName = GetLanguageDisplayName("zh-Hans");
- }
- else
- {
- _sLocalizedDisplayName = GetLanguageDisplayName(SNAME);
- }
- }
- catch (Exception)
- {
- // do nothing
- }
- }
- // If it hasn't been found (Windows 8 and up), fallback to the system
- if (String.IsNullOrEmpty(_sLocalizedDisplayName))
- {
- // If its neutral use the language name
- if (this.IsNeutralCulture)
- {
- _sLocalizedDisplayName = this.SLOCALIZEDLANGUAGE;
- }
- else
- {
- // Usually the UI culture shouldn't be different than what we got from WinRT except
- // if DefaultThreadCurrentUICulture was set
- CultureInfo ci;
-
- if (CultureInfo.DefaultThreadCurrentUICulture != null &&
- ((ci = GetUserDefaultCulture()) != null) &&
- !CultureInfo.DefaultThreadCurrentUICulture.Name.Equals(ci.Name))
- {
- _sLocalizedDisplayName = this.SNATIVEDISPLAYNAME;
- }
- else
- {
- _sLocalizedDisplayName = GetLocaleInfo(LocaleStringData.LocalizedDisplayName);
- }
- }
- }
- }
-
- return _sLocalizedDisplayName;
- }
- }
-
- // English pretty name for this locale (ie: English (United States))
- internal String SENGDISPLAYNAME
- {
- get
- {
- if (_sEnglishDisplayName == null)
- {
- // If its neutral use the language name
- if (this.IsNeutralCulture)
- {
- _sEnglishDisplayName = this.SENGLISHLANGUAGE;
- // differentiate the legacy display names
- switch (_sName)
- {
- case "zh-CHS":
- case "zh-CHT":
- _sEnglishDisplayName += " Legacy";
- break;
- }
- }
- else
- {
- _sEnglishDisplayName = GetLocaleInfo(LocaleStringData.EnglishDisplayName);
-
- // if it isn't found build one:
- if (String.IsNullOrEmpty(_sEnglishDisplayName))
- {
- // Our existing names mostly look like:
- // "English" + "United States" -> "English (United States)"
- // "Azeri (Latin)" + "Azerbaijan" -> "Azeri (Latin, Azerbaijan)"
- if (this.SENGLISHLANGUAGE[this.SENGLISHLANGUAGE.Length - 1] == ')')
- {
- // "Azeri (Latin)" + "Azerbaijan" -> "Azeri (Latin, Azerbaijan)"
- _sEnglishDisplayName =
- this.SENGLISHLANGUAGE.Substring(0, _sEnglishLanguage.Length - 1) +
- ", " + this.SENGCOUNTRY + ")";
- }
- else
- {
- // "English" + "United States" -> "English (United States)"
- _sEnglishDisplayName = this.SENGLISHLANGUAGE + " (" + this.SENGCOUNTRY + ")";
- }
- }
- }
- }
- return _sEnglishDisplayName;
- }
- }
-
- // Native pretty name for this locale (ie: Deutsch (Deutschland))
- internal String SNATIVEDISPLAYNAME
- {
- get
- {
- if (_sNativeDisplayName == null)
- {
- // If its neutral use the language name
- if (this.IsNeutralCulture)
- {
- _sNativeDisplayName = this.SNATIVELANGUAGE;
- // differentiate the legacy display names
- switch (_sName)
- {
- case "zh-CHS":
- _sNativeDisplayName += " \u65E7\u7248";
- break;
- case "zh-CHT":
- _sNativeDisplayName += " \u820A\u7248";
- break;
- }
- }
- else
- {
- _sNativeDisplayName = GetLocaleInfo(LocaleStringData.NativeDisplayName);
-
- // if it isn't found build one:
- if (String.IsNullOrEmpty(_sNativeDisplayName))
- {
- // These should primarily be "Deutsch (Deutschland)" type names
- _sNativeDisplayName = this.SNATIVELANGUAGE + " (" + this.SNATIVECOUNTRY + ")";
- }
- }
- }
- return _sNativeDisplayName;
- }
- }
-
- // The culture name to be used in CultureInfo.CreateSpecificCulture()
- internal string SSPECIFICCULTURE
- {
- get
- {
- // This got populated during the culture initialization
- Debug.Assert(_sSpecificCulture != null, "[CultureData.SSPECIFICCULTURE] Expected this.sSpecificCulture to be populated by culture data initialization already");
- return _sSpecificCulture;
- }
- }
-
- /////////////
- // Language //
- /////////////
-
- // iso 639 language name, ie: en
- internal String SISO639LANGNAME
- {
- get
- {
- if (_sISO639Language == null)
- {
- _sISO639Language = GetLocaleInfo(LocaleStringData.Iso639LanguageTwoLetterName);
- }
- return _sISO639Language;
- }
- }
-
- // iso 639 language name, ie: eng
- internal string SISO639LANGNAME2
- {
- get
- {
- if (_sISO639Language2 == null)
- {
- _sISO639Language2 = GetLocaleInfo(LocaleStringData.Iso639LanguageThreeLetterName);
- }
- return _sISO639Language2;
- }
- }
-
- // abbreviated windows language name (ie: enu) (non-standard, avoid this)
- internal string SABBREVLANGNAME
- {
- get
- {
- if (_sAbbrevLang == null)
- {
- _sAbbrevLang = GetThreeLetterWindowsLanguageName(_sRealName);
- }
- return _sAbbrevLang;
- }
- }
-
- // Localized name for this language (Windows Only) ie: Inglis
- // This is only valid for Windows 8 and higher neutrals:
- internal String SLOCALIZEDLANGUAGE
- {
- get
- {
- if (_sLocalizedLanguage == null)
- {
- // Usually the UI culture shouldn't be different than what we got from WinRT except
- // if DefaultThreadCurrentUICulture was set
- CultureInfo ci;
-
- if (CultureInfo.DefaultThreadCurrentUICulture != null &&
- ((ci = GetUserDefaultCulture()) != null) &&
- !CultureInfo.DefaultThreadCurrentUICulture.Name.Equals(ci.Name))
- {
- _sLocalizedLanguage = SNATIVELANGUAGE;
- }
- else
- {
- _sLocalizedLanguage = GetLocaleInfo(LocaleStringData.LocalizedLanguageName);
- }
- }
-
- return _sLocalizedLanguage;
- }
- }
-
- // English name for this language (Windows Only) ie: German
- internal String SENGLISHLANGUAGE
- {
- get
- {
- if (_sEnglishLanguage == null)
- {
- _sEnglishLanguage = GetLocaleInfo(LocaleStringData.EnglishLanguageName);
- }
- return _sEnglishLanguage;
- }
- }
-
- // Native name of this language (Windows Only) ie: Deutsch
- internal String SNATIVELANGUAGE
- {
- get
- {
- if (_sNativeLanguage == null)
- {
- _sNativeLanguage = GetLocaleInfo(LocaleStringData.NativeLanguageName);
- }
- return _sNativeLanguage;
- }
- }
-
- ///////////
- // Region //
- ///////////
-
- // region name (eg US)
- internal String SREGIONNAME
- {
- get
- {
- if (_sRegionName == null)
- {
- _sRegionName = GetLocaleInfo(LocaleStringData.Iso3166CountryName);
- }
- return _sRegionName;
- }
- }
-
- internal int IGEOID
- {
- get
- {
- if (_iGeoId == undef)
- {
- _iGeoId = GetGeoId(_sRealName);
- }
- return _iGeoId;
- }
- }
-
- // localized name for the country
- internal string SLOCALIZEDCOUNTRY
- {
- get
- {
- if (_sLocalizedCountry == null)
- {
- try
- {
- _sLocalizedCountry = GetRegionDisplayName(SISO3166CTRYNAME);
- }
- catch (Exception)
- {
- // do nothing. we'll fallback
- }
-
- if (_sLocalizedCountry == null)
- {
- _sLocalizedCountry = SNATIVECOUNTRY;
- }
- }
- return _sLocalizedCountry;
- }
- }
-
- // english country name (RegionInfo) ie: Germany
- internal String SENGCOUNTRY
- {
- get
- {
- if (_sEnglishCountry == null)
- {
- _sEnglishCountry = GetLocaleInfo(LocaleStringData.EnglishCountryName);
- }
- return _sEnglishCountry;
- }
- }
-
- // native country name (RegionInfo) ie: Deutschland
- internal String SNATIVECOUNTRY
- {
- get
- {
- if (_sNativeCountry == null)
- {
- _sNativeCountry = GetLocaleInfo(LocaleStringData.NativeCountryName);
- }
- return _sNativeCountry;
- }
- }
-
- // ISO 3166 Country Name
- internal String SISO3166CTRYNAME
- {
- get
- {
- if (_sISO3166CountryName == null)
- {
- _sISO3166CountryName = GetLocaleInfo(LocaleStringData.Iso3166CountryName);
- }
- return _sISO3166CountryName;
- }
- }
-
- // 3 letter ISO 3166 country code
- internal String SISO3166CTRYNAME2
- {
- get
- {
- if (_sISO3166CountryName2 == null)
- {
- _sISO3166CountryName2 = GetLocaleInfo(LocaleStringData.Iso3166CountryName2);
- }
- return _sISO3166CountryName2;
- }
- }
-
- internal int IINPUTLANGUAGEHANDLE
- {
- get
- {
- if (_iInputLanguageHandle == undef)
- {
- if (IsSupplementalCustomCulture)
- {
- _iInputLanguageHandle = 0x0409;
- }
- else
- {
- // Input Language is same as LCID for built-in cultures
- _iInputLanguageHandle = this.ILANGUAGE;
- }
- }
- return _iInputLanguageHandle;
- }
- }
-
- // Console fallback name (ie: locale to use for console apps for unicode-only locales)
- internal string SCONSOLEFALLBACKNAME
- {
- get
- {
- if (_sConsoleFallbackName == null)
- {
- _sConsoleFallbackName = GetConsoleFallbackName(_sRealName);
- }
- return _sConsoleFallbackName;
- }
- }
-
- // (user can override) grouping of digits
- internal int[] WAGROUPING
- {
- get
- {
- if (_waGrouping == null)
- {
- _waGrouping = GetLocaleInfo(LocaleGroupingData.Digit);
- }
- return _waGrouping;
- }
- }
-
-
- // internal String sDecimalSeparator ; // (user can override) decimal separator
- // internal String sThousandSeparator ; // (user can override) thousands separator
-
- // Not a Number
- internal String SNAN
- {
- get
- {
- if (_sNaN == null)
- {
- _sNaN = GetLocaleInfo(LocaleStringData.NaNSymbol);
- }
- return _sNaN;
- }
- }
-
- // + Infinity
- internal String SPOSINFINITY
- {
- get
- {
- if (_sPositiveInfinity == null)
- {
- _sPositiveInfinity = GetLocaleInfo(LocaleStringData.PositiveInfinitySymbol);
- }
- return _sPositiveInfinity;
- }
- }
-
- // - Infinity
- internal String SNEGINFINITY
- {
- get
- {
- if (_sNegativeInfinity == null)
- {
- _sNegativeInfinity = GetLocaleInfo(LocaleStringData.NegativeInfinitySymbol);
- }
- return _sNegativeInfinity;
- }
- }
-
-
- ////////////
- // Percent //
- ///////////
-
- // Negative Percent (0-3)
- internal int INEGATIVEPERCENT
- {
- get
- {
- if (_iNegativePercent == undef)
- {
- // Note that <= Windows Vista this is synthesized by native code
- _iNegativePercent = GetLocaleInfo(LocaleNumberData.NegativePercentFormat);
- }
- return _iNegativePercent;
- }
- }
-
- // Positive Percent (0-11)
- internal int IPOSITIVEPERCENT
- {
- get
- {
- if (_iPositivePercent == undef)
- {
- // Note that <= Windows Vista this is synthesized by native code
- _iPositivePercent = GetLocaleInfo(LocaleNumberData.PositivePercentFormat);
- }
- return _iPositivePercent;
- }
- }
-
- // Percent (%) symbol
- internal String SPERCENT
- {
- get
- {
- if (_sPercent == null)
- {
- _sPercent = GetLocaleInfo(LocaleStringData.PercentSymbol);
- }
- return _sPercent;
- }
- }
-
- // PerMille symbol
- internal String SPERMILLE
- {
- get
- {
- if (_sPerMille == null)
- {
- _sPerMille = GetLocaleInfo(LocaleStringData.PerMilleSymbol);
- }
- return _sPerMille;
- }
- }
-
- /////////////
- // Currency //
- /////////////
-
- // (user can override) local monetary symbol, eg: $
- internal String SCURRENCY
- {
- get
- {
- if (_sCurrency == null)
- {
- _sCurrency = GetLocaleInfo(LocaleStringData.MonetarySymbol);
- }
- return _sCurrency;
- }
- }
-
- // international monetary symbol (RegionInfo), eg: USD
- internal String SINTLSYMBOL
- {
- get
- {
- if (_sIntlMonetarySymbol == null)
- {
- _sIntlMonetarySymbol = GetLocaleInfo(LocaleStringData.Iso4217MonetarySymbol);
- }
- return _sIntlMonetarySymbol;
- }
- }
-
- // English name for this currency (RegionInfo), eg: US Dollar
- internal String SENGLISHCURRENCY
- {
- get
- {
- if (_sEnglishCurrency == null)
- {
- _sEnglishCurrency = GetLocaleInfo(LocaleStringData.CurrencyEnglishName);
- }
- return _sEnglishCurrency;
- }
- }
-
- // Native name for this currency (RegionInfo), eg: Schweiz Frank
- internal String SNATIVECURRENCY
- {
- get
- {
- if (_sNativeCurrency == null)
- {
- _sNativeCurrency = GetLocaleInfo(LocaleStringData.CurrencyNativeName);
- }
- return _sNativeCurrency;
- }
- }
-
- // internal int iCurrencyDigits ; // (user can override) # local monetary fractional digits
- // internal int iCurrency ; // (user can override) positive currency format
- // internal int iNegativeCurrency ; // (user can override) negative currency format
-
- // (user can override) monetary grouping of digits
- internal int[] WAMONGROUPING
- {
- get
- {
- if (_waMonetaryGrouping == null)
- {
- _waMonetaryGrouping = GetLocaleInfo(LocaleGroupingData.Monetary);
- }
- return _waMonetaryGrouping;
- }
- }
-
- // (user can override) system of measurement 0=metric, 1=US (RegionInfo)
- internal int IMEASURE
- {
- get
- {
- if (_iMeasure == undef)
- {
- _iMeasure = GetLocaleInfo(LocaleNumberData.MeasurementSystem);
- }
- return _iMeasure;
- }
- }
-
- // (user can override) list Separator
- internal String SLIST
- {
- get
- {
- if (_sListSeparator == null)
- {
- _sListSeparator = GetLocaleInfo(LocaleStringData.ListSeparator);
- }
- return _sListSeparator;
- }
- }
-
-
- ////////////////////////////
- // Calendar/Time (Gregorian) //
- ////////////////////////////
-
- // (user can override) AM designator
- internal String SAM1159
- {
- get
- {
- if (_sAM1159 == null)
- {
- _sAM1159 = GetLocaleInfo(LocaleStringData.AMDesignator);
- }
- return _sAM1159;
- }
- }
-
- // (user can override) PM designator
- internal String SPM2359
- {
- get
- {
- if (_sPM2359 == null)
- {
- _sPM2359 = GetLocaleInfo(LocaleStringData.PMDesignator);
- }
- return _sPM2359;
- }
- }
-
- // (user can override) time format
- internal String[] LongTimes
- {
- get
- {
- if (_saLongTimes == null)
- {
- String[] longTimes = GetTimeFormats();
- if (longTimes == null || longTimes.Length == 0)
- {
- _saLongTimes = Invariant._saLongTimes;
- }
- else
- {
- _saLongTimes = longTimes;
- }
- }
- return _saLongTimes;
- }
- }
-
- // short time format
- // Short times (derived from long times format)
- // TODO: NLS Arrowhead - On Windows 7 we should have short times so this isn't necessary
- internal String[] ShortTimes
- {
- get
- {
- if (_saShortTimes == null)
- {
- // Try to get the short times from the OS/culture.dll
- String[] shortTimes = null;
- shortTimes = GetShortTimeFormats();
-
- if (shortTimes == null || shortTimes.Length == 0)
- {
- //
- // If we couldn't find short times, then compute them from long times
- // (eg: CORECLR on < Win7 OS & fallback for missing culture.dll)
- //
- shortTimes = DeriveShortTimesFromLong();
- }
-
- /* The above logic doesn't make sense on Mac, since the OS can provide us a "short time pattern".
- * currently this is the 4th element in the array returned by LongTimes. We'll add this to our array
- * if it doesn't exist.
- */
- shortTimes = AdjustShortTimesForMac(shortTimes);
-
- // Found short times, use them
- _saShortTimes = shortTimes;
- }
- return _saShortTimes;
- }
- }
-
- private string[] AdjustShortTimesForMac(string[] shortTimes)
- {
- return shortTimes;
- }
-
- private string[] DeriveShortTimesFromLong()
- {
- // Our logic is to look for h,H,m,s,t. If we find an s, then we check the string
- // between it and the previous marker, if any. If its a short, unescaped separator,
- // then we don't retain that part.
- // We then check after the ss and remove anything before the next h,H,m,t...
- string[] shortTimes = new string[LongTimes.Length];
-
- for (int i = 0; i < LongTimes.Length; i++)
- {
- shortTimes[i] = StripSecondsFromPattern(LongTimes[i]);
- }
- return shortTimes;
- }
-
- private static string StripSecondsFromPattern(string time)
- {
- bool bEscape = false;
- int iLastToken = -1;
-
- // Find the seconds
- for (int j = 0; j < time.Length; j++)
- {
- // Change escape mode?
- if (time[j] == '\'')
- {
- // Continue
- bEscape = !bEscape;
- continue;
- }
-
- // See if there was a single \
- if (time[j] == '\\')
- {
- // Skip next char
- j++;
- continue;
- }
-
- if (bEscape)
- {
- continue;
- }
-
- switch (time[j])
- {
- // Check for seconds
- case 's':
- // Found seconds, see if there was something unescaped and short between
- // the last marker and the seconds. Windows says separator can be a
- // maximum of three characters (without null)
- // If 1st or last characters were ', then ignore it
- if ((j - iLastToken) <= 4 && (j - iLastToken) > 1 &&
- (time[iLastToken + 1] != '\'') &&
- (time[j - 1] != '\''))
- {
- // There was something there we want to remember
- if (iLastToken >= 0)
- {
- j = iLastToken + 1;
- }
- }
-
- bool containsSpace;
- int endIndex = GetIndexOfNextTokenAfterSeconds(time, j, out containsSpace);
-
- string sep;
-
- if (containsSpace)
- {
- sep = " ";
- }
- else
- {
- sep = "";
- }
-
- time = time.Substring(0, j) + sep + time.Substring(endIndex);
- break;
- case 'm':
- case 'H':
- case 'h':
- iLastToken = j;
- break;
- }
- }
- return time;
- }
-
- private static int GetIndexOfNextTokenAfterSeconds(string time, int index, out bool containsSpace)
- {
- bool bEscape = false;
- containsSpace = false;
- for (; index < time.Length; index++)
- {
- switch (time[index])
- {
- case '\'':
- bEscape = !bEscape;
- continue;
- case '\\':
- index++;
- if (time[index] == ' ')
- {
- containsSpace = true;
- }
- continue;
- case ' ':
- containsSpace = true;
- break;
- case 't':
- case 'm':
- case 'H':
- case 'h':
- if (bEscape)
- {
- continue;
- }
- return index;
- }
- }
- containsSpace = false;
- return index;
- }
-
- // (user can override) first day of week
- internal int IFIRSTDAYOFWEEK
- {
- get
- {
- if (_iFirstDayOfWeek == undef)
- {
- _iFirstDayOfWeek = GetFirstDayOfWeek();
- }
- return _iFirstDayOfWeek;
- }
- }
-
- // (user can override) first week of year
- internal int IFIRSTWEEKOFYEAR
- {
- get
- {
- if (_iFirstWeekOfYear == undef)
- {
- _iFirstWeekOfYear = GetLocaleInfo(LocaleNumberData.FirstWeekOfYear);
- }
- return _iFirstWeekOfYear;
- }
- }
-
- // (user can override default only) short date format
- internal String[] ShortDates(CalendarId calendarId)
- {
- return GetCalendar(calendarId).saShortDates;
- }
-
- // (user can override default only) long date format
- internal String[] LongDates(CalendarId calendarId)
- {
- return GetCalendar(calendarId).saLongDates;
- }
-
- // (user can override) date year/month format.
- internal String[] YearMonths(CalendarId calendarId)
- {
- return GetCalendar(calendarId).saYearMonths;
- }
-
- // day names
- internal string[] DayNames(CalendarId calendarId)
- {
- return GetCalendar(calendarId).saDayNames;
- }
-
- // abbreviated day names
- internal string[] AbbreviatedDayNames(CalendarId calendarId)
- {
- // Get abbreviated day names for this calendar from the OS if necessary
- return GetCalendar(calendarId).saAbbrevDayNames;
- }
-
- // The super short day names
- internal string[] SuperShortDayNames(CalendarId calendarId)
- {
- return GetCalendar(calendarId).saSuperShortDayNames;
- }
-
- // month names
- internal string[] MonthNames(CalendarId calendarId)
- {
- return GetCalendar(calendarId).saMonthNames;
- }
-
- // Genitive month names
- internal string[] GenitiveMonthNames(CalendarId calendarId)
- {
- return GetCalendar(calendarId).saMonthGenitiveNames;
- }
-
- // month names
- internal string[] AbbreviatedMonthNames(CalendarId calendarId)
- {
- return GetCalendar(calendarId).saAbbrevMonthNames;
- }
-
- // Genitive month names
- internal string[] AbbreviatedGenitiveMonthNames(CalendarId calendarId)
- {
- return GetCalendar(calendarId).saAbbrevMonthGenitiveNames;
- }
-
- // Leap year month names
- // Note: This only applies to Hebrew, and it basically adds a "1" to the 6th month name
- // the non-leap names skip the 7th name in the normal month name array
- internal string[] LeapYearMonthNames(CalendarId calendarId)
- {
- return GetCalendar(calendarId).saLeapYearMonthNames;
- }
-
- // month/day format (single string, no override)
- internal String MonthDay(CalendarId calendarId)
- {
- return GetCalendar(calendarId).sMonthDay;
- }
-
-
-
- /////////////
- // Calendars //
- /////////////
-
- // all available calendar type(s), The first one is the default calendar.
- internal CalendarId[] CalendarIds
- {
- get
- {
- if (_waCalendars == null)
- {
- // We pass in an array of ints, and native side fills it up with count calendars.
- // We then have to copy that list to a new array of the right size.
- // Default calendar should be first
- CalendarId[] calendars = new CalendarId[23];
- Debug.Assert(_sWindowsName != null, "[CultureData.CalendarIds] Expected _sWindowsName to be populated by already");
- int count = CalendarData.GetCalendars(_sWindowsName, _bUseOverrides, calendars);
-
- // See if we had a calendar to add.
- if (count == 0)
- {
- // Failed for some reason, just grab Gregorian from Invariant
- _waCalendars = Invariant._waCalendars;
- }
- else
- {
- // The OS may not return calendar 4 for zh-TW, but we've always allowed it.
- // TODO: Is this hack necessary long-term?
- if (_sWindowsName == "zh-TW")
- {
- bool found = false;
-
- // Do we need to insert calendar 4?
- for (int i = 0; i < count; i++)
- {
- // Stop if we found calendar four
- if (calendars[i] == CalendarId.TAIWAN)
- {
- found = true;
- break;
- }
- }
-
- // If not found then insert it
- if (!found)
- {
- // Insert it as the 2nd calendar
- count++;
- // Copy them from the 2nd position to the end, -1 for skipping 1st, -1 for one being added.
- Array.Copy(calendars, 1, calendars, 2, 23 - 1 - 1);
- calendars[1] = CalendarId.TAIWAN;
- }
- }
-
- // It worked, remember the list
- CalendarId[] temp = new CalendarId[count];
- Array.Copy(calendars, temp, count);
-
- // Want 1st calendar to be default
- // Prior to Vista the enumeration didn't have default calendar first
- if (temp.Length > 1)
- {
- CalendarId i = (CalendarId)GetLocaleInfo(LocaleNumberData.CalendarType);
- if (temp[1] == i)
- {
- temp[1] = temp[0];
- temp[0] = i;
- }
- }
-
- _waCalendars = temp;
- }
- }
-
- return _waCalendars;
- }
- }
-
- // Native calendar names. index of optional calendar - 1, empty if no optional calendar at that number
- internal string CalendarName(CalendarId calendarId)
- {
- // Get the calendar
- return GetCalendar(calendarId).sNativeName;
- }
-
- internal CalendarData GetCalendar(CalendarId calendarId)
- {
- Debug.Assert(calendarId > 0 && calendarId <= CalendarId.LAST_CALENDAR,
- "[CultureData.GetCalendar] Expect calendarId to be in a valid range");
-
- // arrays are 0 based, calendarIds are 1 based
- int calendarIndex = (int)calendarId - 1;
-
- // Have to have calendars
- if (_calendars == null)
- {
- _calendars = new CalendarData[CalendarData.MAX_CALENDARS];
- }
-
- // we need the following local variable to avoid returning null
- // when another thread creates a new array of CalendarData (above)
- // right after we insert the newly created CalendarData (below)
- CalendarData calendarData = _calendars[calendarIndex];
- // Make sure that calendar has data
- if (calendarData == null)
- {
- Debug.Assert(_sWindowsName != null, "[CultureData.GetCalendar] Expected _sWindowsName to be populated by already");
- calendarData = new CalendarData(_sWindowsName, calendarId, this.UseUserOverride);
- _calendars[calendarIndex] = calendarData;
- }
-
- return calendarData;
- }
-
- ///////////////////
- // Text Information //
- ///////////////////
-
- // IsRightToLeft
- internal bool IsRightToLeft
- {
- get
- {
- // Returns one of the following 4 reading layout values:
- // 0 - Left to right (eg en-US)
- // 1 - Right to left (eg arabic locales)
- // 2 - Vertical top to bottom with columns to the left and also left to right (ja-JP locales)
- // 3 - Vertical top to bottom with columns proceeding to the right
- return (this.IREADINGLAYOUT == 1);
- }
- }
-
- // IREADINGLAYOUT
- // Returns one of the following 4 reading layout values:
- // 0 - Left to right (eg en-US)
- // 1 - Right to left (eg arabic locales)
- // 2 - Vertical top to bottom with columns to the left and also left to right (ja-JP locales)
- // 3 - Vertical top to bottom with columns proceeding to the right
- //
- // If exposed as a public API, we'd have an enum with those 4 values
- private int IREADINGLAYOUT
- {
- get
- {
- if (_iReadingLayout == undef)
- {
- Debug.Assert(_sRealName != null, "[CultureData.IsRightToLeft] Expected _sRealName to be populated by already");
- _iReadingLayout = GetLocaleInfo(LocaleNumberData.ReadingLayout);
- }
-
- return (_iReadingLayout);
- }
- }
-
- // The TextInfo name never includes that alternate sort and is always specific
- // For customs, it uses the SortLocale (since the textinfo is not exposed in Win7)
- // en -> en-US
- // en-US -> en-US
- // fj (custom neutral) -> en-US (assuming that en-US is the sort locale for fj)
- // fj_FJ (custom specific) -> en-US (assuming that en-US is the sort locale for fj-FJ)
- // es-ES_tradnl -> es-ES
- internal String STEXTINFO // Text info name to use for text information
- {
- get
- {
- // Note: Custom cultures might point at another culture's textinfo, however windows knows how
- // to redirect it to the desired textinfo culture, so this is OK.
- Debug.Assert(_sRealName != null, "[CultureData.STEXTINFO] Expected _sRealName to be populated by already");
- return (_sRealName);
- }
- }
-
- // Compare info name (including sorting key) to use if custom
- internal String SCOMPAREINFO
- {
- get
- {
- Debug.Assert(_sRealName != null, "[CultureData.SCOMPAREINFO] Expected _sRealName to be populated by already");
- return (_sRealName);
- }
- }
-
- internal bool IsSupplementalCustomCulture
- {
- get
- {
- return IsCustomCultureId(this.ILANGUAGE);
- }
- }
-
- internal int IDEFAULTANSICODEPAGE // default ansi code page ID (ACP)
- {
- get
- {
- if (_iDefaultAnsiCodePage == undef)
- {
- _iDefaultAnsiCodePage = GetAnsiCodePage(_sRealName);
- }
- return _iDefaultAnsiCodePage;
- }
- }
-
- internal int IDEFAULTOEMCODEPAGE // default oem code page ID (OCP or OEM)
- {
- get
- {
- if (_iDefaultOemCodePage == undef)
- {
- _iDefaultOemCodePage = GetOemCodePage(_sRealName);
- }
- return _iDefaultOemCodePage;
- }
- }
-
- internal int IDEFAULTMACCODEPAGE // default macintosh code page
- {
- get
- {
- if (_iDefaultMacCodePage == undef)
- {
- _iDefaultMacCodePage = GetMacCodePage(_sRealName);
- }
- return _iDefaultMacCodePage;
- }
- }
-
- internal int IDEFAULTEBCDICCODEPAGE // default EBCDIC code page
- {
- get
- {
- if (_iDefaultEbcdicCodePage == undef)
- {
- _iDefaultEbcdicCodePage = GetEbcdicCodePage(_sRealName);
- }
- return _iDefaultEbcdicCodePage;
- }
- }
-
- internal int ILANGUAGE
- {
- get
- {
- if (_iLanguage == 0)
- {
- Debug.Assert(_sRealName != null, "[CultureData.ILANGUAGE] Expected this.sRealName to be populated by COMNlsInfo::nativeInitCultureData already");
- _iLanguage = LocaleNameToLCID(_sRealName);
- }
- return _iLanguage;
- }
- }
-
- internal bool IsNeutralCulture
- {
- get
- {
- // InitCultureData told us if we're neutral or not
- return _bNeutral;
- }
- }
-
- internal bool IsInvariantCulture
- {
- get
- {
- return String.IsNullOrEmpty(this.SNAME);
- }
- }
-
- // Get an instance of our default calendar
- internal Calendar DefaultCalendar
- {
- get
- {
- CalendarId defaultCalId = (CalendarId)GetLocaleInfo(LocaleNumberData.CalendarType);
-
- if (defaultCalId == 0)
- {
- defaultCalId = this.CalendarIds[0];
- }
-
- return CultureInfo.GetCalendarInstance(defaultCalId);
- }
- }
-
- // All of our era names
- internal String[] EraNames(CalendarId calendarId)
- {
- Debug.Assert(calendarId > 0, "[CultureData.saEraNames] Expected Calendar.ID > 0");
-
- return this.GetCalendar(calendarId).saEraNames;
- }
-
- internal String[] AbbrevEraNames(CalendarId calendarId)
- {
- Debug.Assert(calendarId > 0, "[CultureData.saAbbrevEraNames] Expected Calendar.ID > 0");
-
- return this.GetCalendar(calendarId).saAbbrevEraNames;
- }
-
- internal String[] AbbreviatedEnglishEraNames(CalendarId calendarId)
- {
- Debug.Assert(calendarId > 0, "[CultureData.saAbbrevEraNames] Expected Calendar.ID > 0");
-
- return this.GetCalendar(calendarId).saAbbrevEnglishEraNames;
- }
-
- //// String array DEFAULTS
- //// Note: GetDTFIOverrideValues does the user overrides for these, so we don't have to.
-
-
- // Time separator (derived from time format)
- internal String TimeSeparator
- {
- get
- {
- if (_sTimeSeparator == null)
- {
- string longTimeFormat = GetTimeFormatString();
- if (String.IsNullOrEmpty(longTimeFormat))
- {
- longTimeFormat = LongTimes[0];
- }
-
- // Compute STIME from time format
- _sTimeSeparator = GetTimeSeparator(longTimeFormat);
- }
- return _sTimeSeparator;
- }
- }
-
- // Date separator (derived from short date format)
- internal String DateSeparator(CalendarId calendarId)
- {
- return GetDateSeparator(ShortDates(calendarId)[0]);
- }
-
- //////////////////////////////////////
- // Helper Functions to get derived properties //
- //////////////////////////////////////
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Unescape a NLS style quote string
- //
- // This removes single quotes:
- // 'fred' -> fred
- // 'fred -> fred
- // fred' -> fred
- // fred's -> freds
- //
- // This removes the first \ of escaped characters:
- // fred\'s -> fred's
- // a\\b -> a\b
- // a\b -> ab
- //
- // We don't build the stringbuilder unless we find a ' or a \. If we find a ' or a \, we
- // always build a stringbuilder because we need to remove the ' or \.
- //
- ////////////////////////////////////////////////////////////////////////////
- private static String UnescapeNlsString(String str, int start, int end)
- {
- Debug.Assert(str != null);
- Debug.Assert(start >= 0);
- Debug.Assert(end >= 0);
- StringBuilder result = null;
-
- for (int i = start; i < str.Length && i <= end; i++)
- {
- switch (str[i])
- {
- case '\'':
- if (result == null)
- {
- result = new StringBuilder(str, start, i - start, str.Length);
- }
- break;
- case '\\':
- if (result == null)
- {
- result = new StringBuilder(str, start, i - start, str.Length);
- }
- ++i;
- if (i < str.Length)
- {
- result.Append(str[i]);
- }
- break;
- default:
- if (result != null)
- {
- result.Append(str[i]);
- }
- break;
- }
- }
-
- if (result == null)
- return (str.Substring(start, end - start + 1));
-
- return (result.ToString());
- }
-
- private static String GetTimeSeparator(String format)
- {
- // Time format separator (ie: : in 12:39:00)
- //
- // We calculate this from the provided time format
- //
-
- //
- // Find the time separator so that we can pretend we know STIME.
- //
- return GetSeparator(format, "Hhms");
- }
-
- private static String GetDateSeparator(String format)
- {
- // Date format separator (ie: / in 9/1/03)
- //
- // We calculate this from the provided short date
- //
-
- //
- // Find the date separator so that we can pretend we know SDATE.
- //
- return GetSeparator(format, "dyM");
- }
-
- private static string GetSeparator(string format, string timeParts)
- {
- int index = IndexOfTimePart(format, 0, timeParts);
-
- if (index != -1)
- {
- // Found a time part, find out when it changes
- char cTimePart = format[index];
-
- do
- {
- index++;
- } while (index < format.Length && format[index] == cTimePart);
-
- int separatorStart = index;
-
- // Now we need to find the end of the separator
- if (separatorStart < format.Length)
- {
- int separatorEnd = IndexOfTimePart(format, separatorStart, timeParts);
- if (separatorEnd != -1)
- {
- // From [separatorStart, count) is our string, except we need to unescape
- return UnescapeNlsString(format, separatorStart, separatorEnd - 1);
- }
- }
- }
-
- return String.Empty;
- }
-
- private static int IndexOfTimePart(string format, int startIndex, string timeParts)
- {
- Debug.Assert(startIndex >= 0, "startIndex cannot be negative");
- Debug.Assert(timeParts.IndexOfAny(new char[] { '\'', '\\' }) == -1, "timeParts cannot include quote characters");
- bool inQuote = false;
- for (int i = startIndex; i < format.Length; ++i)
- {
- // See if we have a time Part
- if (!inQuote && timeParts.IndexOf(format[i]) != -1)
- {
- return i;
- }
- switch (format[i])
- {
- case '\\':
- if (i + 1 < format.Length)
- {
- ++i;
- switch (format[i])
- {
- case '\'':
- case '\\':
- break;
- default:
- --i; //backup since we will move over this next
- break;
- }
- }
- break;
- case '\'':
- inQuote = !inQuote;
- break;
- }
- }
-
- return -1;
- }
-
- internal static bool IsCustomCultureId(int cultureId)
- {
- return (cultureId == CultureInfo.LOCALE_CUSTOM_DEFAULT || cultureId == CultureInfo.LOCALE_CUSTOM_UNSPECIFIED);
- }
-
- internal void GetNFIValues(NumberFormatInfo nfi)
- {
- if (this.IsInvariantCulture)
- {
- // FUTURE: NumberFormatInfo already has default values for many of these fields. Can we not do this?
- nfi.positiveSign = _sPositiveSign;
- nfi.negativeSign = _sNegativeSign;
-
- nfi.numberGroupSeparator = _sThousandSeparator;
- nfi.numberDecimalSeparator = _sDecimalSeparator;
- nfi.numberDecimalDigits = _iDigits;
- nfi.numberNegativePattern = _iNegativeNumber;
-
- nfi.currencySymbol = _sCurrency;
- nfi.currencyGroupSeparator = _sMonetaryThousand;
- nfi.currencyDecimalSeparator = _sMonetaryDecimal;
- nfi.currencyDecimalDigits = _iCurrencyDigits;
- nfi.currencyNegativePattern = _iNegativeCurrency;
- nfi.currencyPositivePattern = _iCurrency;
- }
- else
- {
- Debug.Assert(_sWindowsName != null, "[CultureData.GetNFIValues] Expected _sWindowsName to be populated by already");
- // String values
- nfi.positiveSign = GetLocaleInfo(LocaleStringData.PositiveSign);
- nfi.negativeSign = GetLocaleInfo(LocaleStringData.NegativeSign);
-
- nfi.numberDecimalSeparator = GetLocaleInfo(LocaleStringData.DecimalSeparator);
- nfi.numberGroupSeparator = GetLocaleInfo(LocaleStringData.ThousandSeparator);
- nfi.currencyGroupSeparator = GetLocaleInfo(LocaleStringData.MonetaryThousandSeparator);
- nfi.currencyDecimalSeparator = GetLocaleInfo(LocaleStringData.MonetaryDecimalSeparator);
- nfi.currencySymbol = GetLocaleInfo(LocaleStringData.MonetarySymbol);
-
- // Numeric values
- nfi.numberDecimalDigits = GetLocaleInfo(LocaleNumberData.FractionalDigitsCount);
- nfi.currencyDecimalDigits = GetLocaleInfo(LocaleNumberData.MonetaryFractionalDigitsCount);
- nfi.currencyPositivePattern = GetLocaleInfo(LocaleNumberData.PositiveMonetaryNumberFormat);
- nfi.currencyNegativePattern = GetLocaleInfo(LocaleNumberData.NegativeMonetaryNumberFormat);
- nfi.numberNegativePattern = GetLocaleInfo(LocaleNumberData.NegativeNumberFormat);
-
- // LOCALE_SNATIVEDIGITS (array of 10 single character strings).
- string digits = GetLocaleInfo(LocaleStringData.Digits);
- nfi.nativeDigits = new string[10];
- for (int i = 0; i < nfi.nativeDigits.Length; i++)
- {
- nfi.nativeDigits[i] = new string(digits[i], 1);
- }
-
- nfi.digitSubstitution = GetDigitSubstitution(_sRealName);
- }
-
- //
- // Gather additional data
- //
- nfi.numberGroupSizes = this.WAGROUPING;
- nfi.currencyGroupSizes = this.WAMONGROUPING;
-
- // prefer the cached value since these do not have user overrides
- nfi.percentNegativePattern = this.INEGATIVEPERCENT;
- nfi.percentPositivePattern = this.IPOSITIVEPERCENT;
- nfi.percentSymbol = this.SPERCENT;
- nfi.perMilleSymbol = this.SPERMILLE;
-
- nfi.negativeInfinitySymbol = this.SNEGINFINITY;
- nfi.positiveInfinitySymbol = this.SPOSINFINITY;
- nfi.nanSymbol = this.SNAN;
-
- //
- // We don't have percent values, so use the number values
- //
- nfi.percentDecimalDigits = nfi.numberDecimalDigits;
- nfi.percentDecimalSeparator = nfi.numberDecimalSeparator;
- nfi.percentGroupSizes = nfi.numberGroupSizes;
- nfi.percentGroupSeparator = nfi.numberGroupSeparator;
-
- //
- // Clean up a few odd values
- //
-
- // Windows usually returns an empty positive sign, but we like it to be "+"
- if (nfi.positiveSign == null || nfi.positiveSign.Length == 0) nfi.positiveSign = "+";
-
- //Special case for Italian. The currency decimal separator in the control panel is the empty string. When the user
- //specifies C4 as the currency format, this results in the number apparently getting multiplied by 10000 because the
- //decimal point doesn't show up. We'll just hack this here because our default currency format will never use nfi.
- if (nfi.currencyDecimalSeparator == null || nfi.currencyDecimalSeparator.Length == 0)
- {
- nfi.currencyDecimalSeparator = nfi.numberDecimalSeparator;
- }
- }
-
- // Helper
- // This is ONLY used for caching names and shouldn't be used for anything else
- internal static string AnsiToLower(string testString)
- {
- int index = 0;
-
- while (index<testString.Length && (testString[index]<'A' || testString[index]>'Z' ))
- {
- index++;
- }
- if (index >= testString.Length)
- {
- return testString; // we didn't really change the string
- }
-
- StringBuilder sb = new StringBuilder(testString.Length);
- for (int i=0; i<index; i++)
- {
- sb.Append(testString[i]);
- }
-
- sb.Append((char) (testString[index] -'A' + 'a'));
-
- for (int ich = index+1; ich < testString.Length; ich++)
- {
- char ch = testString[ich];
- sb.Append(ch <= 'Z' && ch >= 'A' ? (char)(ch - 'A' + 'a') : ch);
- }
-
- return (sb.ToString());
- }
-
- /// <remarks>
- /// The numeric values of the enum members match their Win32 counterparts. The CultureData Win32 PAL implementation
- /// takes a dependency on this fact, in order to prevent having to construct a mapping from internal values to LCTypes.
- /// </remarks>
- private enum LocaleStringData : uint
- {
- /// <summary>localized name of locale, eg "German (Germany)" in UI language (coresponds to LOCALE_SLOCALIZEDDISPLAYNAME)</summary>
- LocalizedDisplayName = 0x00000002,
- /// <summary>Display name (language + country usually) in English, eg "German (Germany)" (coresponds to LOCALE_SENGLISHDISPLAYNAME)</summary>
- EnglishDisplayName = 0x00000072,
- /// <summary>Display name in native locale language, eg "Deutsch (Deutschland) (coresponds to LOCALE_SNATIVEDISPLAYNAME)</summary>
- NativeDisplayName = 0x00000073,
- /// <summary>Language Display Name for a language, eg "German" in UI language (coresponds to LOCALE_SLOCALIZEDLANGUAGENAME)</summary>
- LocalizedLanguageName = 0x0000006f,
- /// <summary>English name of language, eg "German" (coresponds to LOCALE_SENGLISHLANGUAGENAME)</summary>
- EnglishLanguageName = 0x00001001,
- /// <summary>native name of language, eg "Deutsch" (coresponds to LOCALE_SNATIVELANGUAGENAME)</summary>
- NativeLanguageName = 0x00000004,
- /// <summary>localized name of country, eg "Germany" in UI language (coresponds to LOCALE_SLOCALIZEDCOUNTRYNAME)</summary>
- LocalizedCountryName = 0x00000006,
- /// <summary>English name of country, eg "Germany" (coresponds to LOCALE_SENGLISHCOUNTRYNAME)</summary>
- EnglishCountryName = 0x00001002,
- /// <summary>native name of country, eg "Deutschland" (coresponds to LOCALE_SNATIVECOUNTRYNAME)</summary>
- NativeCountryName = 0x00000008,
- /// <summary>abbreviated language name (coresponds to LOCALE_SABBREVLANGNAME)</summary>
- AbbreviatedWindowsLanguageName = 0x00000003,
- /// <summary>list item separator (coresponds to LOCALE_SLIST)</summary>
- ListSeparator = 0x0000000C,
- /// <summary>decimal separator (coresponds to LOCALE_SDECIMAL)</summary>
- DecimalSeparator = 0x0000000E,
- /// <summary>thousand separator (coresponds to LOCALE_STHOUSAND)</summary>
- ThousandSeparator = 0x0000000F,
- /// <summary>digit grouping (coresponds to LOCALE_SGROUPING)</summary>
- Digits = 0x00000013,
- /// <summary>local monetary symbol (coresponds to LOCALE_SCURRENCY)</summary>
- MonetarySymbol = 0x00000014,
- /// <summary>English currency name (coresponds to LOCALE_SENGCURRNAME)</summary>
- CurrencyEnglishName = 0x00001007,
- /// <summary>Native currency name (coresponds to LOCALE_SNATIVECURRNAME)</summary>
- CurrencyNativeName = 0x00001008,
- /// <summary>uintl monetary symbol (coresponds to LOCALE_SINTLSYMBOL)</summary>
- Iso4217MonetarySymbol = 0x00000015,
- /// <summary>monetary decimal separator (coresponds to LOCALE_SMONDECIMALSEP)</summary>
- MonetaryDecimalSeparator = 0x00000016,
- /// <summary>monetary thousand separator (coresponds to LOCALE_SMONTHOUSANDSEP)</summary>
- MonetaryThousandSeparator = 0x00000017,
- /// <summary>AM designator (coresponds to LOCALE_S1159)</summary>
- AMDesignator = 0x00000028,
- /// <summary>PM designator (coresponds to LOCALE_S2359)</summary>
- PMDesignator = 0x00000029,
- /// <summary>positive sign (coresponds to LOCALE_SPOSITIVESIGN)</summary>
- PositiveSign = 0x00000050,
- /// <summary>negative sign (coresponds to LOCALE_SNEGATIVESIGN)</summary>
- NegativeSign = 0x00000051,
- /// <summary>ISO abbreviated language name (coresponds to LOCALE_SISO639LANGNAME)</summary>
- Iso639LanguageTwoLetterName = 0x00000059,
- /// <summary>ISO abbreviated country name (coresponds to LOCALE_SISO639LANGNAME2)</summary>
- Iso639LanguageThreeLetterName = 0x00000067,
- /// <summary>ISO abbreviated language name (coresponds to LOCALE_SISO639LANGNAME)</summary>
- Iso639LanguageName = 0x00000059,
- /// <summary>ISO abbreviated country name (coresponds to LOCALE_SISO3166CTRYNAME)</summary>
- Iso3166CountryName = 0x0000005A,
- /// <summary>3 letter ISO country code (coresponds to LOCALE_SISO3166CTRYNAME2)</summary>
- Iso3166CountryName2 = 0x00000068, // 3 character ISO country name
- /// <summary>Not a Number (coresponds to LOCALE_SNAN)</summary>
- NaNSymbol = 0x00000069,
- /// <summary>+ Infinity (coresponds to LOCALE_SPOSINFINITY)</summary>
- PositiveInfinitySymbol = 0x0000006a,
- /// <summary>- Infinity (coresponds to LOCALE_SNEGINFINITY)</summary>
- NegativeInfinitySymbol = 0x0000006b,
- /// <summary>Fallback name for resources (coresponds to LOCALE_SPARENT)</summary>
- ParentName = 0x0000006d,
- /// <summary>Fallback name for within the console (coresponds to LOCALE_SCONSOLEFALLBACKNAME)</summary>
- ConsoleFallbackName = 0x0000006e,
- /// <summary>Returns the percent symbol (coresponds to LOCALE_SPERCENT)</summary>
- PercentSymbol = 0x00000076,
- /// <summary>Returns the permille (U+2030) symbol (coresponds to LOCALE_SPERMILLE)</summary>
- PerMilleSymbol = 0x00000077
- }
-
- /// <remarks>
- /// The numeric values of the enum members match their Win32 counterparts. The CultureData Win32 PAL implementation
- /// takes a dependency on this fact, in order to prevent having to construct a mapping from internal values to LCTypes.
- /// </remarks>
- private enum LocaleGroupingData : uint
- {
- /// <summary>digit grouping (coresponds to LOCALE_SGROUPING)</summary>
- Digit = 0x00000010,
- /// <summary>monetary grouping (coresponds to LOCALE_SMONGROUPING)</summary>
- Monetary = 0x00000018,
- }
-
- /// <remarks>
- /// The numeric values of the enum members match their Win32 counterparts. The CultureData Win32 PAL implementation
- /// takes a dependency on this fact, in order to prevent having to construct a mapping from internal values to LCTypes.
- /// </remarks>
- private enum LocaleNumberData : uint
- {
- /// <summary>language id (coresponds to LOCALE_ILANGUAGE)</summary>
- LanguageId = 0x00000001,
- /// <summary>geographical location id, (coresponds to LOCALE_IGEOID)</summary>
- GeoId = 0x00000008,
- /// <summary>0 = context, 1 = none, 2 = national (coresponds to LOCALE_IDIGITSUBSTITUTION)</summary>
- DigitSubstitution = 0x00001014,
- /// <summary>0 = metric, 1 = US (coresponds to LOCALE_IMEASURE)</summary>
- MeasurementSystem = 0x0000000D,
- /// <summary>number of fractional digits (coresponds to LOCALE_IDIGITS)</summary>
- FractionalDigitsCount = 0x00000011,
- /// <summary>negative number mode (coresponds to LOCALE_INEGNUMBER)</summary>
- NegativeNumberFormat = 0x00001010,
- /// <summary># local monetary digits (coresponds to LOCALE_ICURRDIGITS)</summary>
- MonetaryFractionalDigitsCount = 0x00000019,
- /// <summary>positive currency mode (coresponds to LOCALE_ICURRENCY)</summary>
- PositiveMonetaryNumberFormat = 0x0000001B,
- /// <summary>negative currency mode (coresponds to LOCALE_INEGCURR)</summary>
- NegativeMonetaryNumberFormat = 0x0000001C,
- /// <summary>type of calendar specifier (coresponds to LOCALE_ICALENDARTYPE)</summary>
- CalendarType = 0x00001009,
- /// <summary>first day of week specifier (coresponds to LOCALE_IFIRSTDAYOFWEEK)</summary>
- FirstDayOfWeek = 0x0000100C,
- /// <summary>first week of year specifier (coresponds to LOCALE_IFIRSTWEEKOFYEAR)</summary>
- FirstWeekOfYear = 0x0000100D,
- /// <summary>
- /// Returns one of the following 4 reading layout values:
- /// 0 - Left to right (eg en-US)
- /// 1 - Right to left (eg arabic locales)
- /// 2 - Vertical top to bottom with columns to the left and also left to right (ja-JP locales)
- /// 3 - Vertical top to bottom with columns proceeding to the right
- /// (coresponds to LOCALE_IREADINGLAYOUT)
- /// </summary>
- ReadingLayout = 0x00000070,
- /// <summary>Returns 0-11 for the negative percent format (coresponds to LOCALE_INEGATIVEPERCENT)</summary>
- NegativePercentFormat = 0x00000074,
- /// <summary>Returns 0-3 for the positive percent format (coresponds to LOCALE_IPOSITIVEPERCENT)</summary>
- PositivePercentFormat = 0x00000075,
- /// <summary>default ansi code page (coresponds to LOCALE_IDEFAULTCODEPAGE)</summary>
- OemCodePage = 0x0000000B,
- /// <summary>default ansi code page (coresponds to LOCALE_IDEFAULTANSICODEPAGE)</summary>
- AnsiCodePage = 0x00001004,
- /// <summary>default mac code page (coresponds to LOCALE_IDEFAULTMACCODEPAGE)</summary>
- MacCodePage = 0x00001011,
- /// <summary>default ebcdic code page (coresponds to LOCALE_IDEFAULTEBCDICCODEPAGE)</summary>
- EbcdicCodePage = 0x00001012,
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/CultureInfo.Unix.cs b/src/mscorlib/corefx/System/Globalization/CultureInfo.Unix.cs
deleted file mode 100644
index 6911688b08..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CultureInfo.Unix.cs
+++ /dev/null
@@ -1,31 +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.
-
-namespace System.Globalization
-{
- public partial class CultureInfo : IFormatProvider
- {
- private static CultureInfo GetUserDefaultCultureCacheOverride()
- {
- return null; // ICU doesn't provide a user override
- }
-
- internal static CultureInfo GetUserDefaultCulture()
- {
- CultureInfo cultureInfo = null;
- string localeName;
- if (CultureData.GetDefaultLocaleName(out localeName))
- {
- cultureInfo = GetCultureByName(localeName, true);
- cultureInfo.m_isReadOnly = true;
- }
- else
- {
- cultureInfo = CultureInfo.InvariantCulture;
- }
-
- return cultureInfo;
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/CultureInfo.Windows.cs b/src/mscorlib/corefx/System/Globalization/CultureInfo.Windows.cs
deleted file mode 100644
index c019eb2ceb..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CultureInfo.Windows.cs
+++ /dev/null
@@ -1,57 +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.
-
-#if ENABLE_WINRT
-using Internal.Runtime.Augments;
-#endif
-
-namespace System.Globalization
-{
- public partial class CultureInfo : IFormatProvider
- {
- /// <summary>
- /// Gets the default user culture from WinRT, if available.
- /// </summary>
- /// <remarks>
- /// This method may return null, if there is no default user culture or if WinRT isn't available.
- /// </remarks>
- private static CultureInfo GetUserDefaultCultureCacheOverride()
- {
-#if ENABLE_WINRT
- WinRTInteropCallbacks callbacks = WinRTInterop.UnsafeCallbacks;
- if (callbacks != null && callbacks.IsAppxModel())
- {
- return (CultureInfo)callbacks.GetUserDefaultCulture();
- }
-#endif
-
- return null;
- }
-
- internal static CultureInfo GetUserDefaultCulture()
- {
- const uint LOCALE_SNAME = 0x0000005c;
- const string LOCALE_NAME_USER_DEFAULT = null;
- const string LOCALE_NAME_SYSTEM_DEFAULT = "!x-sys-default-locale";
-
- string strDefault = Interop.mincore.GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME);
- if (strDefault == null)
- {
- strDefault = Interop.mincore.GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_SNAME);
-
- if (strDefault == null)
- {
- // If system default doesn't work, use invariant
- return CultureInfo.InvariantCulture;
- }
- }
-
- CultureInfo temp = GetCultureByName(strDefault, true);
-
- temp._isReadOnly = true;
-
- return temp;
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/CultureInfo.cs b/src/mscorlib/corefx/System/Globalization/CultureInfo.cs
deleted file mode 100644
index da084d17f9..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CultureInfo.cs
+++ /dev/null
@@ -1,1558 +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.
-
-////////////////////////////////////////////////////////////////////////////
-//
-//
-//
-// Purpose: This class represents the software preferences of a particular
-// culture or community. It includes information such as the
-// language, writing system, and a calendar used by the culture
-// as well as methods for common operations such as printing
-// dates and sorting strings.
-//
-//
-//
-// !!!! NOTE WHEN CHANGING THIS CLASS !!!!
-//
-// If adding or removing members to this class, please update CultureInfoBaseObject
-// in ndp/clr/src/vm/object.h. Note, the "actual" layout of the class may be
-// different than the order in which members are declared. For instance, all
-// reference types will come first in the class before value types (like ints, bools, etc)
-// regardless of the order in which they are declared. The best way to see the
-// actual order of the class is to do a !dumpobj on an instance of the managed
-// object inside of the debugger.
-//
-////////////////////////////////////////////////////////////////////////////
-
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-using System.Runtime.Serialization;
-using System.Threading;
-
-namespace System.Globalization
-{
-
-#if INSIDE_CLR
- using StringCultureInfoDictionary = Dictionary<string, CultureInfo>;
- using StringLcidDictionary = Dictionary<int, CultureInfo>;
-
- using Lock = Object;
-#else
- using StringCultureInfoDictionary = LowLevelDictionary<string, CultureInfo>;
- using StringLcidDictionary = LowLevelDictionary<int, CultureInfo>;
-#endif
-
- [Serializable]
- public partial class CultureInfo : IFormatProvider, ICloneable
- {
- //--------------------------------------------------------------------//
- // Internal Information //
- //--------------------------------------------------------------------//
-
- //--------------------------------------------------------------------//
- // Data members to be serialized:
- //--------------------------------------------------------------------//
-
- // We use an RFC4646 type string to construct CultureInfo.
- // This string is stored in m_name and is authoritative.
- // We use the m_cultureData to get the data for our object
-
- private bool m_isReadOnly;
- private CompareInfo compareInfo;
- private TextInfo textInfo;
- internal NumberFormatInfo numInfo;
- internal DateTimeFormatInfo dateTimeInfo;
- private Calendar calendar;
- //
- // The CultureData instance that we are going to read data from.
- // For supported culture, this will be the CultureData instance that read data from mscorlib assembly.
- // For customized culture, this will be the CultureData instance that read data from user customized culture binary file.
- //
- [NonSerialized]
- internal CultureData m_cultureData;
-
- [NonSerialized]
- internal bool m_isInherited;
-
- [NonSerialized]
- private CultureInfo m_consoleFallbackCulture;
-
- // Names are confusing. Here are 3 names we have:
- //
- // new CultureInfo() m_name m_nonSortName m_sortName
- // en-US en-US en-US en-US
- // de-de_phoneb de-DE_phoneb de-DE de-DE_phoneb
- // fj-fj (custom) fj-FJ fj-FJ en-US (if specified sort is en-US)
- // en en
- //
- // Note that in Silverlight we ask the OS for the text and sort behavior, so the
- // textinfo and compareinfo names are the same as the name
-
- // Note that the name used to be serialized for Everett; it is now serialized
- // because alernate sorts can have alternate names.
- // This has a de-DE, de-DE_phoneb or fj-FJ style name
- internal string m_name;
-
- // This will hold the non sorting name to be returned from CultureInfo.Name property.
- // This has a de-DE style name even for de-DE_phoneb type cultures
- [NonSerialized]
- private string m_nonSortName;
-
- // This will hold the sorting name to be returned from CultureInfo.SortName property.
- // This might be completely unrelated to the culture name if a custom culture. Ie en-US for fj-FJ.
- // Otherwise its the sort name, ie: de-DE or de-DE_phoneb
- [NonSerialized]
- private string m_sortName;
-
- //--------------------------------------------------------------------//
- //
- // Static data members
- //
- //--------------------------------------------------------------------//
-
- //Get the current user default culture. This one is almost always used, so we create it by default.
- private static volatile CultureInfo s_userDefaultCulture;
-
- //
- // All of the following will be created on demand.
- //
-
- // WARNING: We allow diagnostic tools to directly inspect these three members (s_InvariantCultureInfo, s_DefaultThreadCurrentUICulture and s_DefaultThreadCurrentCulture)
- // See https://github.com/dotnet/corert/blob/master/Documentation/design-docs/diagnostics/diagnostics-tools-contract.md for more details.
- // Please do not change the type, the name, or the semantic usage of this member without understanding the implication for tools.
- // Get in touch with the diagnostics team if you have questions.
-
- //The Invariant culture;
- private static volatile CultureInfo s_InvariantCultureInfo;
-
- //These are defaults that we use if a thread has not opted into having an explicit culture
- private static volatile CultureInfo s_DefaultThreadCurrentUICulture;
- private static volatile CultureInfo s_DefaultThreadCurrentCulture;
-
- [ThreadStatic]
- private static volatile CultureInfo s_currentThreadCulture;
- [ThreadStatic]
- private static volatile CultureInfo s_currentThreadUICulture;
-
- private static readonly Lock m_lock = new Lock();
- private static volatile StringCultureInfoDictionary s_NameCachedCultures;
- private static volatile StringLcidDictionary s_LcidCachedCultures;
-
- //The parent culture.
- [NonSerialized]
- private CultureInfo m_parent;
-
- // LOCALE constants of interest to us internally and privately for LCID functions
- // (ie: avoid using these and use names if possible)
- internal const int LOCALE_NEUTRAL = 0x0000;
- private const int LOCALE_USER_DEFAULT = 0x0400;
- private const int LOCALE_SYSTEM_DEFAULT = 0x0800;
- internal const int LOCALE_CUSTOM_UNSPECIFIED = 0x1000;
- internal const int LOCALE_CUSTOM_DEFAULT = 0x0c00;
- internal const int LOCALE_INVARIANT = 0x007F;
-
- static AsyncLocal<CultureInfo> s_asyncLocalCurrentCulture;
- static AsyncLocal<CultureInfo> s_asyncLocalCurrentUICulture;
-
- static void AsyncLocalSetCurrentCulture(AsyncLocalValueChangedArgs<CultureInfo> args)
- {
- s_currentThreadCulture = args.CurrentValue;
- }
-
- static void AsyncLocalSetCurrentUICulture(AsyncLocalValueChangedArgs<CultureInfo> args)
- {
- s_currentThreadUICulture = args.CurrentValue;
- }
-
- //
- // The CultureData instance that reads the data provided by our CultureData class.
- //
- // Using a field initializer rather than a static constructor so that the whole class can be lazy
- // init.
- private static readonly bool init = Init();
- private static bool Init()
- {
- if (s_InvariantCultureInfo == null)
- {
- CultureInfo temp = new CultureInfo("", false);
- temp.m_isReadOnly = true;
- s_InvariantCultureInfo = temp;
- }
-
- s_userDefaultCulture = GetUserDefaultCulture();
- return true;
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // CultureInfo Constructors
- //
- ////////////////////////////////////////////////////////////////////////
-
-
- public CultureInfo(String name)
- : this(name, true)
- {
- }
-
-
- public CultureInfo(String name, bool useUserOverride)
- {
- if (name == null)
- {
- throw new ArgumentNullException(nameof(name),
- SR.ArgumentNull_String);
- }
-
- InitializeFromName(name, useUserOverride);
- }
-
- public CultureInfo(int culture) : this(culture, true)
- {
- }
-
- public CultureInfo(int culture, bool useUserOverride)
- {
- // We don't check for other invalid LCIDS here...
- if (culture < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(culture), SR.ArgumentOutOfRange_NeedPosNum);
- }
- Contract.EndContractBlock();
-
- InitializeFromCultureId(culture, useUserOverride);
- }
-
- private void InitializeFromCultureId(int culture, bool useUserOverride)
- {
- switch (culture)
- {
- case LOCALE_CUSTOM_DEFAULT:
- case LOCALE_SYSTEM_DEFAULT:
- case LOCALE_NEUTRAL:
- case LOCALE_USER_DEFAULT:
- case LOCALE_CUSTOM_UNSPECIFIED:
- // Can't support unknown custom cultures and we do not support neutral or
- // non-custom user locales.
- throw new CultureNotFoundException(nameof(culture), culture, SR.Argument_CultureNotSupported);
-
- default:
- // Now see if this LCID is supported in the system default CultureData table.
- m_cultureData = CultureData.GetCultureData(culture, useUserOverride);
- break;
- }
- m_isInherited = (this.GetType() != typeof(System.Globalization.CultureInfo));
- m_name = m_cultureData.CultureName;
- }
-
- private void InitializeFromName(string name, bool useUserOverride)
- {
- // Get our data providing record
- this.m_cultureData = CultureData.GetCultureData(name, useUserOverride);
-
- if (this.m_cultureData == null)
- {
- throw new CultureNotFoundException(nameof(name), name, SR.Argument_CultureNotSupported);
- }
-
- this.m_name = this.m_cultureData.CultureName;
- this.m_isInherited = (this.GetType() != typeof(System.Globalization.CultureInfo));
- }
-
- // Constructor called by SQL Server's special munged culture - creates a culture with
- // a TextInfo and CompareInfo that come from a supplied alternate source. This object
- // is ALWAYS read-only.
- // Note that we really cannot use an LCID version of this override as the cached
- // name we create for it has to include both names, and the logic for this is in
- // the GetCultureInfo override *only*.
- internal CultureInfo(String cultureName, String textAndCompareCultureName)
- {
- if (cultureName == null)
- {
- throw new ArgumentNullException(nameof(cultureName),SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
-
- m_cultureData = CultureData.GetCultureData(cultureName, false);
- if (m_cultureData == null)
- throw new CultureNotFoundException(nameof(cultureName), cultureName, SR.Argument_CultureNotSupported);
-
- m_name = m_cultureData.CultureName;
-
- CultureInfo altCulture = GetCultureInfo(textAndCompareCultureName);
- compareInfo = altCulture.CompareInfo;
- textInfo = altCulture.TextInfo;
- }
-
- // We do this to try to return the system UI language and the default user languages
- // This method will fallback if this fails (like Invariant)
- //
- // TODO: It would appear that this is only ever called with userOveride = true
- // and this method only has one caller. Can we fold it into the caller?
- private static CultureInfo GetCultureByName(String name, bool userOverride)
- {
- CultureInfo ci = null;
- // Try to get our culture
- try
- {
- ci = userOverride ? new CultureInfo(name) : CultureInfo.GetCultureInfo(name);
- }
- catch (ArgumentException)
- {
- }
-
- if (ci == null)
- {
- ci = InvariantCulture;
- }
-
- return ci;
- }
-
- //
- // Return a specific culture. A tad irrelevent now since we always return valid data
- // for neutral locales.
- //
- // Note that there's interesting behavior that tries to find a smaller name, ala RFC4647,
- // if we can't find a bigger name. That doesn't help with things like "zh" though, so
- // the approach is of questionable value
- //
- public static CultureInfo CreateSpecificCulture(String name)
- {
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
-
- CultureInfo culture;
-
- try
- {
- culture = new CultureInfo(name);
- }
- catch (ArgumentException)
- {
- // When CultureInfo throws this exception, it may be because someone passed the form
- // like "az-az" because it came out of an http accept lang. We should try a little
- // parsing to perhaps fall back to "az" here and use *it* to create the neutral.
-
- int idx;
-
- culture = null;
- for (idx = 0; idx < name.Length; idx++)
- {
- if ('-' == name[idx])
- {
- try
- {
- culture = new CultureInfo(name.Substring(0, idx));
- break;
- }
- catch (ArgumentException)
- {
- // throw the original exception so the name in the string will be right
- throw;
- }
- }
- }
-
- if (culture == null)
- {
- // nothing to save here; throw the original exception
- throw;
- }
- }
-
- // In the most common case, they've given us a specific culture, so we'll just return that.
- if (!(culture.IsNeutralCulture))
- {
- return culture;
- }
-
- return (new CultureInfo(culture.m_cultureData.SSPECIFICCULTURE));
- }
-
- // //
- // // Return a specific culture. A tad irrelevent now since we always return valid data
- // // for neutral locales.
- // //
- // // Note that there's interesting behavior that tries to find a smaller name, ala RFC4647,
- // // if we can't find a bigger name. That doesn't help with things like "zh" though, so
- // // the approach is of questionable value
- // //
-
- internal static bool VerifyCultureName(String cultureName, bool throwException)
- {
- // This function is used by ResourceManager.GetResourceFileName().
- // ResourceManager searches for resource using CultureInfo.Name,
- // so we should check against CultureInfo.Name.
-
- for (int i = 0; i < cultureName.Length; i++)
- {
- char c = cultureName[i];
- // TODO: Names can only be RFC4646 names (ie: a-zA-Z0-9) while this allows any unicode letter/digit
- if (Char.IsLetterOrDigit(c) || c == '-' || c == '_')
- {
- continue;
- }
- if (throwException)
- {
- throw new ArgumentException(SR.Format(SR.Argument_InvalidResourceCultureName, cultureName));
- }
- return false;
- }
- return true;
- }
-
- internal static bool VerifyCultureName(CultureInfo culture, bool throwException)
- {
- //If we have an instance of one of our CultureInfos, the user can't have changed the
- //name and we know that all names are valid in files.
- if (!culture.m_isInherited)
- {
- return true;
- }
-
- return VerifyCultureName(culture.Name, throwException);
- }
-
- // We need to store the override from the culture data record.
- private bool m_useUserOverride;
-
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx)
- {
- m_name = m_cultureData.CultureName;
- m_useUserOverride = m_cultureData.UseUserOverride;
- }
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext ctx)
- {
- Debug.Assert(m_name != null, "[CultureInfo.OnDeserialized] m_name != null");
- InitializeFromName(m_name, m_useUserOverride);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // CurrentCulture
- //
- // This instance provides methods based on the current user settings.
- // These settings are volatile and may change over the lifetime of the
- // thread.
- //
- ////////////////////////////////////////////////////////////////////////
-
- //
- // We use the following order to return CurrentCulture and CurrentUICulture
- // o Use WinRT to return the current user profile language
- // o use current thread culture if the user already set one using CurrentCulture/CurrentUICulture
- // o use thread culture if the user already set one using DefaultThreadCurrentCulture
- // or DefaultThreadCurrentUICulture
- // o Use NLS default user culture
- // o Use NLS default system culture
- // o Use Invariant culture
- //
- public static CultureInfo CurrentCulture
- {
- get
- {
- CultureInfo ci = GetUserDefaultCultureCacheOverride();
- if (ci != null)
- {
- return ci;
- }
-
- if (s_currentThreadCulture != null)
- {
- return s_currentThreadCulture;
- }
-
- ci = s_DefaultThreadCurrentCulture;
- if (ci != null)
- {
- return ci;
- }
-
- // if s_userDefaultCulture == null means CultureInfo statics didn't get initialized yet. this can happen if there early static
- // method get executed which eventually hit the cultureInfo code while CultureInfo statics didn’t get chance to initialize
- if (s_userDefaultCulture == null)
- {
- Init();
- }
-
- Debug.Assert(s_userDefaultCulture != null);
- return s_userDefaultCulture;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value));
- }
-
- if (s_asyncLocalCurrentCulture == null)
- {
- Interlocked.CompareExchange(ref s_asyncLocalCurrentCulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentCulture), null);
- }
- // this one will set s_currentThreadCulture too
- s_asyncLocalCurrentCulture.Value = value;
- }
- }
-
- public static CultureInfo CurrentUICulture
- {
- get
- {
- CultureInfo ci = GetUserDefaultCultureCacheOverride();
- if (ci != null)
- {
- return ci;
- }
-
- if (s_currentThreadUICulture != null)
- {
- return s_currentThreadUICulture;
- }
-
- ci = s_DefaultThreadCurrentUICulture;
- if (ci != null)
- {
- return ci;
- }
-
- // if s_userDefaultCulture == null means CultureInfo statics didn't get initialized yet. this can happen if there early static
- // method get executed which eventually hit the cultureInfo code while CultureInfo statics didn’t get chance to initialize
- if (s_userDefaultCulture == null)
- {
- Init();
- }
-
- Debug.Assert(s_userDefaultCulture != null);
- return s_userDefaultCulture;
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value));
- }
-
- CultureInfo.VerifyCultureName(value, true);
-
- if (s_asyncLocalCurrentUICulture == null)
- {
- Interlocked.CompareExchange(ref s_asyncLocalCurrentUICulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentUICulture), null);
- }
-
- // this one will set s_currentThreadUICulture too
- s_asyncLocalCurrentUICulture.Value = value;
- }
- }
-
- public static CultureInfo InstalledUICulture
- {
- get
- {
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
- if (s_userDefaultCulture == null)
- {
- Init();
- }
- Debug.Assert(s_userDefaultCulture != null, "[CultureInfo.InstalledUICulture] s_userDefaultCulture != null");
- return s_userDefaultCulture;
- }
- }
-
- public static CultureInfo DefaultThreadCurrentCulture
- {
- get { return s_DefaultThreadCurrentCulture; }
- set
- {
- // If you add pre-conditions to this method, check to see if you also need to
- // add them to Thread.CurrentCulture.set.
-
- s_DefaultThreadCurrentCulture = value;
- }
- }
-
- public static CultureInfo DefaultThreadCurrentUICulture
- {
- get { return s_DefaultThreadCurrentUICulture; }
- set
- {
- //If they're trying to use a Culture with a name that we can't use in resource lookup,
- //don't even let them set it on the thread.
-
- // If you add more pre-conditions to this method, check to see if you also need to
- // add them to Thread.CurrentUICulture.set.
-
- if (value != null)
- {
- CultureInfo.VerifyCultureName(value, true);
- }
-
- s_DefaultThreadCurrentUICulture = value;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // InvariantCulture
- //
- // This instance provides methods, for example for casing and sorting,
- // that are independent of the system and current user settings. It
- // should be used only by processes such as some system services that
- // require such invariant results (eg. file systems). In general,
- // the results are not linguistically correct and do not match any
- // culture info.
- //
- ////////////////////////////////////////////////////////////////////////
-
-
- public static CultureInfo InvariantCulture
- {
- get
- {
- return (s_InvariantCultureInfo);
- }
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Parent
- //
- // Return the parent CultureInfo for the current instance.
- //
- ////////////////////////////////////////////////////////////////////////
-
- public virtual CultureInfo Parent
- {
- get
- {
- if (null == m_parent)
- {
- try
- {
- string parentName = this.m_cultureData.SPARENT;
-
- if (String.IsNullOrEmpty(parentName))
- {
- m_parent = InvariantCulture;
- }
- else
- {
- m_parent = new CultureInfo(parentName, this.m_cultureData.UseUserOverride);
- }
- }
- catch (ArgumentException)
- {
- // For whatever reason our IPARENT or SPARENT wasn't correct, so use invariant
- // We can't allow ourselves to fail. In case of custom cultures the parent of the
- // current custom culture isn't installed.
- m_parent = InvariantCulture;
- }
- }
- return m_parent;
- }
- }
-
- public virtual int LCID
- {
- get
- {
- return (this.m_cultureData.ILANGUAGE);
- }
- }
-
- public virtual int KeyboardLayoutId
- {
- get
- {
- return m_cultureData.IINPUTLANGUAGEHANDLE;
- }
- }
-
- public static CultureInfo[] GetCultures(CultureTypes types)
- {
- Contract.Ensures(Contract.Result<CultureInfo[]>() != null);
- // internally we treat UserCustomCultures as Supplementals but v2
- // treats as Supplementals and Replacements
- if((types & CultureTypes.UserCustomCulture) == CultureTypes.UserCustomCulture)
- {
- types |= CultureTypes.ReplacementCultures;
- }
- return (CultureData.GetCultures(types));
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Name
- //
- // Returns the full name of the CultureInfo. The name is in format like
- // "en-US" This version does NOT include sort information in the name.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String Name
- {
- get
- {
- // We return non sorting name here.
- if (this.m_nonSortName == null)
- {
- this.m_nonSortName = this.m_cultureData.SNAME;
- if (this.m_nonSortName == null)
- {
- this.m_nonSortName = String.Empty;
- }
- }
- return this.m_nonSortName;
- }
- }
-
- // This one has the sort information (ie: de-DE_phoneb)
- internal String SortName
- {
- get
- {
- if (this.m_sortName == null)
- {
- this.m_sortName = this.m_cultureData.SCOMPAREINFO;
- }
-
- return this.m_sortName;
- }
- }
-
- public string IetfLanguageTag
- {
- get
- {
- Contract.Ensures(Contract.Result<string>() != null);
-
- // special case the compatibility cultures
- switch (this.Name)
- {
- case "zh-CHT":
- return "zh-Hant";
- case "zh-CHS":
- return "zh-Hans";
- default:
- return this.Name;
- }
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // DisplayName
- //
- // Returns the full name of the CultureInfo in the localized language.
- // For example, if the localized language of the runtime is Spanish and the CultureInfo is
- // US English, "Ingles (Estados Unidos)" will be returned.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String DisplayName
- {
- get
- {
- Contract.Ensures(Contract.Result<String>() != null);
- Debug.Assert(m_name != null, "[CultureInfo.DisplayName] Always expect m_name to be set");
-
- return m_cultureData.SLOCALIZEDDISPLAYNAME;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetNativeName
- //
- // Returns the full name of the CultureInfo in the native language.
- // For example, if the CultureInfo is US English, "English
- // (United States)" will be returned.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String NativeName
- {
- get
- {
- Contract.Ensures(Contract.Result<String>() != null);
- return (this.m_cultureData.SNATIVEDISPLAYNAME);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetEnglishName
- //
- // Returns the full name of the CultureInfo in English.
- // For example, if the CultureInfo is US English, "English
- // (United States)" will be returned.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String EnglishName
- {
- get
- {
- Contract.Ensures(Contract.Result<String>() != null);
- return (this.m_cultureData.SENGDISPLAYNAME);
- }
- }
-
- // ie: en
- public virtual String TwoLetterISOLanguageName
- {
- get
- {
- Contract.Ensures(Contract.Result<String>() != null);
- return (this.m_cultureData.SISO639LANGNAME);
- }
- }
-
- // ie: eng
- public virtual String ThreeLetterISOLanguageName
- {
- get
- {
- Contract.Ensures(Contract.Result<String>() != null);
- return m_cultureData.SISO639LANGNAME2;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ThreeLetterWindowsLanguageName
- //
- // Returns the 3 letter windows language name for the current instance. eg: "ENU"
- // The ISO names are much preferred
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String ThreeLetterWindowsLanguageName
- {
- get
- {
- Contract.Ensures(Contract.Result<String>() != null);
- return m_cultureData.SABBREVLANGNAME;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // CompareInfo Read-Only Property
- //
- // Gets the CompareInfo for this culture.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual CompareInfo CompareInfo
- {
- get
- {
- if (this.compareInfo == null)
- {
- // Since CompareInfo's don't have any overrideable properties, get the CompareInfo from
- // the Non-Overridden CultureInfo so that we only create one CompareInfo per culture
- CompareInfo temp = UseUserOverride
- ? GetCultureInfo(this.m_name).CompareInfo
- : new CompareInfo(this);
- if (OkayToCacheClassWithCompatibilityBehavior)
- {
- this.compareInfo = temp;
- }
- else
- {
- return temp;
- }
- }
- return (compareInfo);
- }
- }
-
- private static bool OkayToCacheClassWithCompatibilityBehavior
- {
- get
- {
- return true;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // TextInfo
- //
- // Gets the TextInfo for this culture.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual TextInfo TextInfo
- {
- get
- {
- if (textInfo == null)
- {
- // Make a new textInfo
- TextInfo tempTextInfo = new TextInfo(this.m_cultureData);
- tempTextInfo.SetReadOnlyState(m_isReadOnly);
-
- if (OkayToCacheClassWithCompatibilityBehavior)
- {
- textInfo = tempTextInfo;
- }
- else
- {
- return tempTextInfo;
- }
- }
- return (textInfo);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Equals
- //
- // Implements Object.Equals(). Returns a boolean indicating whether
- // or not object refers to the same CultureInfo as the current instance.
- //
- ////////////////////////////////////////////////////////////////////////
-
-
- public override bool Equals(Object value)
- {
- if (Object.ReferenceEquals(this, value))
- return true;
-
- CultureInfo that = value as CultureInfo;
-
- if (that != null)
- {
- // using CompareInfo to verify the data passed through the constructor
- // CultureInfo(String cultureName, String textAndCompareCultureName)
-
- return (this.Name.Equals(that.Name) && this.CompareInfo.Equals(that.CompareInfo));
- }
-
- return (false);
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetHashCode
- //
- // Implements Object.GetHashCode(). Returns the hash code for the
- // CultureInfo. The hash code is guaranteed to be the same for CultureInfo A
- // and B where A.Equals(B) is true.
- //
- ////////////////////////////////////////////////////////////////////////
-
- public override int GetHashCode()
- {
- return (this.Name.GetHashCode() + this.CompareInfo.GetHashCode());
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ToString
- //
- // Implements Object.ToString(). Returns the name of the CultureInfo,
- // eg. "de-DE_phoneb", "en-US", or "fj-FJ".
- //
- ////////////////////////////////////////////////////////////////////////
-
-
- public override String ToString()
- {
- return m_name;
- }
-
-
- public virtual Object GetFormat(Type formatType)
- {
- if (formatType == typeof(NumberFormatInfo))
- return (NumberFormat);
- if (formatType == typeof(DateTimeFormatInfo))
- return (DateTimeFormat);
- return (null);
- }
-
- public virtual bool IsNeutralCulture
- {
- get
- {
- return this.m_cultureData.IsNeutralCulture;
- }
- }
-
- public CultureTypes CultureTypes
- {
- get
- {
- CultureTypes types = 0;
-
- if (m_cultureData.IsNeutralCulture)
- types |= CultureTypes.NeutralCultures;
- else
- types |= CultureTypes.SpecificCultures;
-
- types |= m_cultureData.IsWin32Installed ? CultureTypes.InstalledWin32Cultures : 0;
-
-// Disable warning 618: System.Globalization.CultureTypes.FrameworkCultures' is obsolete
-#pragma warning disable 618
- types |= m_cultureData.IsFramework ? CultureTypes.FrameworkCultures : 0;
-
-#pragma warning restore 618
- types |= m_cultureData.IsSupplementalCustomCulture ? CultureTypes.UserCustomCulture : 0;
- types |= m_cultureData.IsReplacementCulture ? CultureTypes.ReplacementCultures | CultureTypes.UserCustomCulture : 0;
-
- return types;
- }
- }
-
- public virtual NumberFormatInfo NumberFormat
- {
- get
- {
- if (numInfo == null)
- {
- NumberFormatInfo temp = new NumberFormatInfo(this.m_cultureData);
- temp.isReadOnly = m_isReadOnly;
- Interlocked.CompareExchange(ref numInfo, temp, null);
- }
- return (numInfo);
- }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value), SR.ArgumentNull_Obj);
- }
- VerifyWritable();
- numInfo = value;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetDateTimeFormatInfo
- //
- // Create a DateTimeFormatInfo, and fill in the properties according to
- // the CultureID.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual DateTimeFormatInfo DateTimeFormat
- {
- get
- {
- if (dateTimeInfo == null)
- {
- // Change the calendar of DTFI to the specified calendar of this CultureInfo.
- DateTimeFormatInfo temp = new DateTimeFormatInfo(this.m_cultureData, this.Calendar);
- temp._isReadOnly = m_isReadOnly;
- Interlocked.CompareExchange(ref dateTimeInfo, temp, null);
- }
- return (dateTimeInfo);
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value), SR.ArgumentNull_Obj);
- }
- VerifyWritable();
- dateTimeInfo = value;
- }
- }
-
- public void ClearCachedData()
- {
- s_userDefaultCulture = null;
-
- RegionInfo.s_currentRegionInfo = null;
- #pragma warning disable 0618 // disable the obsolete warning
- TimeZone.ResetTimeZone();
- #pragma warning restore 0618
- TimeZoneInfo.ClearCachedData();
- s_LcidCachedCultures = null;
- s_NameCachedCultures = null;
-
- CultureData.ClearCachedData();
- }
-
- /*=================================GetCalendarInstance==========================
- **Action: Map a Win32 CALID to an instance of supported calendar.
- **Returns: An instance of calendar.
- **Arguments: calType The Win32 CALID
- **Exceptions:
- ** Shouldn't throw exception since the calType value is from our data table or from Win32 registry.
- ** If we are in trouble (like getting a weird value from Win32 registry), just return the GregorianCalendar.
- ============================================================================*/
- internal static Calendar GetCalendarInstance(CalendarId calType)
- {
- if (calType == CalendarId.GREGORIAN)
- {
- return (new GregorianCalendar());
- }
- return GetCalendarInstanceRare(calType);
- }
-
- //This function exists as a shortcut to prevent us from loading all of the non-gregorian
- //calendars unless they're required.
- internal static Calendar GetCalendarInstanceRare(CalendarId calType)
- {
- Debug.Assert(calType != CalendarId.GREGORIAN, "calType!=CalendarId.GREGORIAN");
-
- switch (calType)
- {
- case CalendarId.GREGORIAN_US: // Gregorian (U.S.) calendar
- case CalendarId.GREGORIAN_ME_FRENCH: // Gregorian Middle East French calendar
- case CalendarId.GREGORIAN_ARABIC: // Gregorian Arabic calendar
- case CalendarId.GREGORIAN_XLIT_ENGLISH: // Gregorian Transliterated English calendar
- case CalendarId.GREGORIAN_XLIT_FRENCH: // Gregorian Transliterated French calendar
- return (new GregorianCalendar((GregorianCalendarTypes)calType));
- case CalendarId.TAIWAN: // Taiwan Era calendar
- return (new TaiwanCalendar());
- case CalendarId.JAPAN: // Japanese Emperor Era calendar
- return (new JapaneseCalendar());
- case CalendarId.KOREA: // Korean Tangun Era calendar
- return (new KoreanCalendar());
- case CalendarId.THAI: // Thai calendar
- return (new ThaiBuddhistCalendar());
- case CalendarId.HIJRI: // Hijri (Arabic Lunar) calendar
- return (new HijriCalendar());
- case CalendarId.HEBREW: // Hebrew (Lunar) calendar
- return (new HebrewCalendar());
- case CalendarId.UMALQURA:
- return (new UmAlQuraCalendar());
- case CalendarId.PERSIAN:
- return (new PersianCalendar());
- }
- return (new GregorianCalendar());
- }
-
- /*=================================Calendar==========================
- **Action: Return/set the default calendar used by this culture.
- ** This value can be overridden by regional option if this is a current culture.
- **Returns:
- **Arguments:
- **Exceptions:
- ** ArgumentNull_Obj if the set value is null.
- ============================================================================*/
- public virtual Calendar Calendar
- {
- get
- {
- if (calendar == null)
- {
- Debug.Assert(this.m_cultureData.CalendarIds.Length > 0, "this.m_cultureData.CalendarIds.Length > 0");
- // Get the default calendar for this culture. Note that the value can be
- // from registry if this is a user default culture.
- Calendar newObj = this.m_cultureData.DefaultCalendar;
-
- System.Threading.Interlocked.MemoryBarrier();
- newObj.SetReadOnlyState(m_isReadOnly);
- calendar = newObj;
- }
- return (calendar);
- }
- }
-
- /*=================================OptionCalendars==========================
- **Action: Return an array of the optional calendar for this culture.
- **Returns: an array of Calendar.
- **Arguments:
- **Exceptions:
- ============================================================================*/
-
-
- public virtual Calendar[] OptionalCalendars
- {
- get
- {
- Contract.Ensures(Contract.Result<Calendar[]>() != null);
-
- //
- // This property always returns a new copy of the calendar array.
- //
- CalendarId[] calID = this.m_cultureData.CalendarIds;
- Calendar[] cals = new Calendar[calID.Length];
- for (int i = 0; i < cals.Length; i++)
- {
- cals[i] = GetCalendarInstance(calID[i]);
- }
- return (cals);
- }
- }
-
- public bool UseUserOverride
- {
- get
- {
- return m_cultureData.UseUserOverride;
- }
- }
-
- public CultureInfo GetConsoleFallbackUICulture()
- {
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
-
- CultureInfo temp = m_consoleFallbackCulture;
- if (temp == null)
- {
- temp = CreateSpecificCulture(m_cultureData.SCONSOLEFALLBACKNAME);
- temp.m_isReadOnly = true;
- m_consoleFallbackCulture = temp;
- }
- return (temp);
- }
-
- public virtual Object Clone()
- {
- CultureInfo ci = (CultureInfo)MemberwiseClone();
- ci.m_isReadOnly = false;
-
- //If this is exactly our type, we can make certain optimizations so that we don't allocate NumberFormatInfo or DTFI unless
- //they've already been allocated. If this is a derived type, we'll take a more generic codepath.
- if (!m_isInherited)
- {
- if (this.dateTimeInfo != null)
- {
- ci.dateTimeInfo = (DateTimeFormatInfo)this.dateTimeInfo.Clone();
- }
- if (this.numInfo != null)
- {
- ci.numInfo = (NumberFormatInfo)this.numInfo.Clone();
- }
- }
- else
- {
- ci.DateTimeFormat = (DateTimeFormatInfo)this.DateTimeFormat.Clone();
- ci.NumberFormat = (NumberFormatInfo)this.NumberFormat.Clone();
- }
-
- if (textInfo != null)
- {
- ci.textInfo = (TextInfo)textInfo.Clone();
- }
-
- if (calendar != null)
- {
- ci.calendar = (Calendar)calendar.Clone();
- }
-
- return (ci);
- }
-
- public static CultureInfo ReadOnly(CultureInfo ci)
- {
- if (ci == null)
- {
- throw new ArgumentNullException(nameof(ci));
- }
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
- Contract.EndContractBlock();
-
- if (ci.IsReadOnly)
- {
- return (ci);
- }
- CultureInfo newInfo = (CultureInfo)(ci.MemberwiseClone());
-
- if (!ci.IsNeutralCulture)
- {
- //If this is exactly our type, we can make certain optimizations so that we don't allocate NumberFormatInfo or DTFI unless
- //they've already been allocated. If this is a derived type, we'll take a more generic codepath.
- if (!ci.m_isInherited)
- {
- if (ci.dateTimeInfo != null)
- {
- newInfo.dateTimeInfo = DateTimeFormatInfo.ReadOnly(ci.dateTimeInfo);
- }
- if (ci.numInfo != null)
- {
- newInfo.numInfo = NumberFormatInfo.ReadOnly(ci.numInfo);
- }
- }
- else
- {
- newInfo.DateTimeFormat = DateTimeFormatInfo.ReadOnly(ci.DateTimeFormat);
- newInfo.NumberFormat = NumberFormatInfo.ReadOnly(ci.NumberFormat);
- }
- }
-
- if (ci.textInfo != null)
- {
- newInfo.textInfo = TextInfo.ReadOnly(ci.textInfo);
- }
-
- if (ci.calendar != null)
- {
- newInfo.calendar = Calendar.ReadOnly(ci.calendar);
- }
-
- // Don't set the read-only flag too early.
- // We should set the read-only flag here. Otherwise, info.DateTimeFormat will not be able to set.
- newInfo.m_isReadOnly = true;
-
- return (newInfo);
- }
-
-
- public bool IsReadOnly
- {
- get
- {
- return (m_isReadOnly);
- }
- }
-
- private void VerifyWritable()
- {
- if (m_isReadOnly)
- {
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- }
- }
-
- // For resource lookup, we consider a culture the invariant culture by name equality.
- // We perform this check frequently during resource lookup, so adding a property for
- // improved readability.
- internal bool HasInvariantCultureName
- {
- get { return Name == CultureInfo.InvariantCulture.Name; }
- }
-
- // Helper function both both overloads of GetCachedReadOnlyCulture. If lcid is 0, we use the name.
- // If lcid is -1, use the altName and create one of those special SQL cultures.
- internal static CultureInfo GetCultureInfoHelper(int lcid, string name, string altName)
- {
- // retval is our return value.
- CultureInfo retval;
-
- // Temporary hashtable for the names.
- StringCultureInfoDictionary tempNameHT = s_NameCachedCultures;
-
- if (name != null)
- {
- name = CultureData.AnsiToLower(name);
- }
-
- if (altName != null)
- {
- altName = CultureData.AnsiToLower(altName);
- }
-
- // We expect the same result for both hashtables, but will test individually for added safety.
- if (tempNameHT == null)
- {
- tempNameHT = new StringCultureInfoDictionary();
- }
- else
- {
- // If we are called by name, check if the object exists in the hashtable. If so, return it.
- if (lcid == -1 || lcid == 0)
- {
- bool ret;
- lock (m_lock)
- {
- ret = tempNameHT.TryGetValue(lcid == 0 ? name : name + '\xfffd' + altName, out retval);
- }
-
- if (ret && retval != null)
- {
- return retval;
- }
- }
- }
-
- // Next, the Lcid table.
- StringLcidDictionary tempLcidHT = s_LcidCachedCultures;
-
- if (tempLcidHT == null)
- {
- // Case insensitive is not an issue here, save the constructor call.
- tempLcidHT = new StringLcidDictionary();
- }
- else
- {
- // If we were called by Lcid, check if the object exists in the table. If so, return it.
- if (lcid > 0)
- {
- bool ret;
- lock (m_lock)
- {
- ret = tempLcidHT.TryGetValue(lcid, out retval);
- }
- if (ret && retval != null)
- {
- return retval;
- }
- }
- }
-
- // We now have two temporary hashtables and the desired object was not found.
- // We'll construct it. We catch any exceptions from the constructor call and return null.
- try
- {
- switch (lcid)
- {
- case -1:
- // call the private constructor
- retval = new CultureInfo(name, altName);
- break;
-
- case 0:
- retval = new CultureInfo(name, false);
- break;
-
- default:
- retval = new CultureInfo(lcid, false);
- break;
- }
- }
- catch (ArgumentException)
- {
- return null;
- }
-
- // Set it to read-only
- retval.m_isReadOnly = true;
-
- if (lcid == -1)
- {
- lock (m_lock)
- {
- // This new culture will be added only to the name hash table.
- tempNameHT[name + '\xfffd' + altName] = retval;
- }
- // when lcid == -1 then TextInfo object is already get created and we need to set it as read only.
- retval.TextInfo.SetReadOnlyState(true);
- }
- else if (lcid == 0)
- {
- // Remember our name (as constructed). Do NOT use alternate sort name versions because
- // we have internal state representing the sort. (So someone would get the wrong cached version)
- string newName = CultureData.AnsiToLower(retval.m_name);
-
- // We add this new culture info object to both tables.
- lock (m_lock)
- {
- tempNameHT[newName] = retval;
- }
- }
- else
- {
- lock (m_lock)
- {
- tempLcidHT[lcid] = retval;
- }
- }
-
- // Copy the two hashtables to the corresponding member variables. This will potentially overwrite
- // new tables simultaneously created by a new thread, but maximizes thread safety.
- if (-1 != lcid)
- {
- // Only when we modify the lcid hash table, is there a need to overwrite.
- s_LcidCachedCultures = tempLcidHT;
- }
-
- s_NameCachedCultures = tempNameHT;
-
- // Finally, return our new CultureInfo object.
- return retval;
- }
-
- // Gets a cached copy of the specified culture from an internal hashtable (or creates it
- // if not found). (LCID version)... use named version
- public static CultureInfo GetCultureInfo(int culture)
- {
- // Must check for -1 now since the helper function uses the value to signal
- // the altCulture code path for SQL Server.
- // Also check for zero as this would fail trying to add as a key to the hash.
- if (culture <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(culture), SR.ArgumentOutOfRange_NeedPosNum);
- }
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
- Contract.EndContractBlock();
- CultureInfo retval = GetCultureInfoHelper(culture, null, null);
- if (null == retval)
- {
- throw new CultureNotFoundException(nameof(culture), culture, SR.Argument_CultureNotSupported);
- }
- return retval;
- }
-
- // Gets a cached copy of the specified culture from an internal hashtable (or creates it
- // if not found). (Named version)
- public static CultureInfo GetCultureInfo(string name)
- {
- // Make sure we have a valid, non-zero length string as name
- if (name == null)
- {
- throw new ArgumentNullException(nameof(name));
- }
-
- CultureInfo retval = GetCultureInfoHelper(0, name, null);
- if (retval == null)
- {
- throw new CultureNotFoundException(
- nameof(name), name, SR.Argument_CultureNotSupported);
- }
- return retval;
- }
-
- // Gets a cached copy of the specified culture from an internal hashtable (or creates it
- // if not found).
- public static CultureInfo GetCultureInfo(string name, string altName)
- {
- // Make sure we have a valid, non-zero length string as name
- if (name == null)
- {
- throw new ArgumentNullException(nameof(name));
- }
-
- if (altName == null)
- {
- throw new ArgumentNullException(nameof(altName));
- }
-
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
- Contract.EndContractBlock();
-
- CultureInfo retval = GetCultureInfoHelper(-1, name, altName);
- if (retval == null)
- {
- throw new CultureNotFoundException("name or altName",
- SR.Format(SR.Argument_OneOfCulturesNotSupported, name, altName));
- }
- return retval;
- }
-
- // This function is deprecated, we don't like it
- public static CultureInfo GetCultureInfoByIetfLanguageTag(string name)
- {
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
-
- // Disallow old zh-CHT/zh-CHS names
- if (name == "zh-CHT" || name == "zh-CHS")
- {
- throw new CultureNotFoundException(nameof(name), SR.Format(SR.Argument_CultureIetfNotSupported, name));
- }
-
- CultureInfo ci = GetCultureInfo(name);
-
- // Disallow alt sorts and es-es_TS
- if (ci.LCID > 0xffff || ci.LCID == 0x040a)
- {
- throw new CultureNotFoundException(nameof(name), SR.Format(SR.Argument_CultureIetfNotSupported, name));
- }
-
- return ci;
- }
- }
-}
-
diff --git a/src/mscorlib/corefx/System/Globalization/CultureNotFoundException.cs b/src/mscorlib/corefx/System/Globalization/CultureNotFoundException.cs
deleted file mode 100644
index d296ad88e5..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CultureNotFoundException.cs
+++ /dev/null
@@ -1,122 +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.Serialization;
-using System.Threading;
-
-namespace System.Globalization
-{
- [Serializable]
- public class CultureNotFoundException : ArgumentException, ISerializable
- {
- private string _invalidCultureName; // unrecognized culture name
- private int? _invalidCultureId; // unrecognized culture Lcid
-
- public CultureNotFoundException()
- : base(DefaultMessage)
- {
- }
-
- public CultureNotFoundException(String message)
- : base(message)
- {
- }
-
- public CultureNotFoundException(String paramName, String message)
- : base(message, paramName)
- {
- }
-
- public CultureNotFoundException(String message, Exception innerException)
- : base(message, innerException)
- {
- }
-
- public CultureNotFoundException(String paramName, string invalidCultureName, String message)
- : base(message, paramName)
- {
- _invalidCultureName = invalidCultureName;
- }
-
- public CultureNotFoundException(String message, string invalidCultureName, Exception innerException)
- : base(message, innerException)
- {
- _invalidCultureName = invalidCultureName;
- }
-
- public CultureNotFoundException(string message, int invalidCultureId, Exception innerException)
- : base(message, innerException)
- {
- _invalidCultureId = invalidCultureId;
- }
-
- public CultureNotFoundException(string paramName, int invalidCultureId, string message)
- : base(message, paramName)
- {
- _invalidCultureId = invalidCultureId;
- }
-
- protected CultureNotFoundException(SerializationInfo info, StreamingContext context)
- : base(info, context)
- {
- _invalidCultureId = (int?)info.GetValue("InvalidCultureId", typeof(int?));
- _invalidCultureName = (string)info.GetValue("InvalidCultureName", typeof(string));
- }
-
- public override void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- base.GetObjectData(info, context);
- info.AddValue("InvalidCultureId", _invalidCultureId, typeof(int?));
- info.AddValue("InvalidCultureName", _invalidCultureName, typeof(string));
- }
-
- public virtual Nullable<int> InvalidCultureId
- {
- get { return _invalidCultureId; }
- }
-
- public virtual string InvalidCultureName
- {
- get { return _invalidCultureName; }
- }
-
- private static String DefaultMessage
- {
- get
- {
- return SR.Argument_CultureNotSupported;
- }
- }
-
- private String FormatedInvalidCultureId
- {
- get
- {
- return InvalidCultureId != null ?
- String.Format(CultureInfo.InvariantCulture, "{0} (0x{0:x4})", (int)InvalidCultureId) :
- InvalidCultureName;
- }
- }
-
- public override String Message
- {
- get
- {
- String s = base.Message;
- if (_invalidCultureId != null || _invalidCultureName != null)
- {
- String valueMessage = SR.Format(SR.Argument_CultureInvalidIdentifier, FormatedInvalidCultureId);
- if (s == null)
- {
- return valueMessage;
- }
-
- return s + Environment.NewLine + valueMessage;
- }
- return s;
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/CultureTypes.cs b/src/mscorlib/corefx/System/Globalization/CultureTypes.cs
deleted file mode 100644
index 35ddff6086..0000000000
--- a/src/mscorlib/corefx/System/Globalization/CultureTypes.cs
+++ /dev/null
@@ -1,28 +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.
-
-// The enumeration constants used in CultureInfo.GetCultures().
-// On Linux platforms, the only enum values used there is NeutralCultures and SpecificCultures
-// the rest are obsolete or not valid on Linux
-
-namespace System.Globalization
-{
- [Serializable]
- [Flags]
- public enum CultureTypes
- {
- NeutralCultures = 0x0001, // Neutral cultures are cultures like "en", "de", "zh", etc, for enumeration this includes ALL neutrals regardless of other flags
- SpecificCultures = 0x0002, // Non-netural cultuers. Examples are "en-us", "zh-tw", etc., for enumeration this includes ALL specifics regardless of other flags
- InstalledWin32Cultures = 0x0004, // Win32 installed cultures in the system and exists in the framework too., this is effectively all cultures
-
- AllCultures = NeutralCultures | SpecificCultures | InstalledWin32Cultures,
-
- UserCustomCulture = 0x0008, // User defined custom culture
- ReplacementCultures = 0x0010, // User defined replacement custom culture.
- [Obsolete("This value has been deprecated. Please use other values in CultureTypes.")]
- WindowsOnlyCultures = 0x0020, // this will always return empty list.
- [Obsolete("This value has been deprecated. Please use other values in CultureTypes.")]
- FrameworkCultures = 0x0040, // will return only the v2 cultures marked as Framework culture.
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/DateTimeFormatInfo.cs b/src/mscorlib/corefx/System/Globalization/DateTimeFormatInfo.cs
deleted file mode 100644
index b79ce90424..0000000000
--- a/src/mscorlib/corefx/System/Globalization/DateTimeFormatInfo.cs
+++ /dev/null
@@ -1,3087 +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.Collections.Generic;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-using System.Runtime.Serialization;
-
-namespace System.Globalization
-{
- //
- // Flags used to indicate different styles of month names.
- // This is an internal flag used by internalGetMonthName().
- // Use flag here in case that we need to provide a combination of these styles
- // (such as month name of a leap year in genitive form. Not likely for now,
- // but would like to keep the option open).
- //
-
- [Flags]
- internal enum MonthNameStyles
- {
- Regular = 0x00000000,
- Genitive = 0x00000001,
- LeapYear = 0x00000002,
- }
-
- //
- // Flags used to indicate special rule used in parsing/formatting
- // for a specific DateTimeFormatInfo instance.
- // This is an internal flag.
- //
- // This flag is different from MonthNameStyles because this flag
- // can be expanded to accomodate parsing behaviors like CJK month names
- // or alternative month names, etc.
-
- [Flags]
- internal enum DateTimeFormatFlags
- {
- None = 0x00000000,
- UseGenitiveMonth = 0x00000001,
- UseLeapYearMonth = 0x00000002,
- UseSpacesInMonthNames = 0x00000004, // Has spaces or non-breaking space in the month names.
- UseHebrewRule = 0x00000008, // Format/Parse using the Hebrew calendar rule.
- UseSpacesInDayNames = 0x00000010, // Has spaces or non-breaking space in the day names.
- UseDigitPrefixInTokens = 0x00000020, // Has token starting with numbers.
-
- NotInitialized = -1,
- }
-
-
- [Serializable]
- public sealed class DateTimeFormatInfo : IFormatProvider, ICloneable
- {
- // cache for the invariant culture.
- // invariantInfo is constant irrespective of your current culture.
- private static volatile DateTimeFormatInfo s_invariantInfo;
-
- // an index which points to a record in Culture Data Table.
- [NonSerialized]
- private CultureData _cultureData;
-
- // The culture name used to create this DTFI.
-
- [OptionalField(VersionAdded = 2)]
- private String _name = null;
-
- // The language name of the culture used to create this DTFI.
- [NonSerialized]
- private String _langName = null;
-
- // CompareInfo usually used by the parser.
- [NonSerialized]
- private CompareInfo _compareInfo = null;
-
- // Culture matches current DTFI. mainly used for string comparisons during parsing.
- [NonSerialized]
- private CultureInfo _cultureInfo = null;
-
- //
- // Caches for various properties.
- //
-
- private String amDesignator = null;
- private String pmDesignator = null;
-
- private String dateSeparator = null; // derived from short date (whidbey expects, arrowhead doesn't)
-
- private String generalShortTimePattern = null; // short date + short time (whidbey expects, arrowhead doesn't)
-
- private String generalLongTimePattern = null; // short date + long time (whidbey expects, arrowhead doesn't)
-
- private String timeSeparator = null; // derived from long time (whidbey expects, arrowhead doesn't)
- private String monthDayPattern = null;
- // added in .NET Framework Release {2.0SP1/3.0SP1/3.5RTM}
- private String dateTimeOffsetPattern = null;
-
- //
- // The following are constant values.
- //
- private const String rfc1123Pattern = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'";
-
- // The sortable pattern is based on ISO 8601.
- private const String sortableDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss";
- private const String universalSortableDateTimePattern = "yyyy'-'MM'-'dd HH':'mm':'ss'Z'";
-
- //
- // The following are affected by calendar settings.
- //
- private Calendar calendar = null;
-
- private int firstDayOfWeek = -1;
- private int calendarWeekRule = -1;
-
-
- private String fullDateTimePattern = null; // long date + long time (whidbey expects, arrowhead doesn't)
-
- private String[] abbreviatedDayNames = null;
-
-
- private String[] m_superShortDayNames = null;
-
- private String[] dayNames = null;
- private String[] abbreviatedMonthNames = null;
- private String[] monthNames = null;
- // Cache the genitive month names that we retrieve from the data table.
-
- private String[] genitiveMonthNames = null;
-
- // Cache the abbreviated genitive month names that we retrieve from the data table.
-
- private String[] m_genitiveAbbreviatedMonthNames = null;
-
- // Cache the month names of a leap year that we retrieve from the data table.
-
- private String[] leapYearMonthNames = null;
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
-
- // The "default" Date/time patterns
- private String longDatePattern = null;
- private String shortDatePattern = null;
- private String yearMonthPattern = null;
- private String longTimePattern = null;
- private String shortTimePattern = null;
-
- [OptionalField(VersionAdded = 3)]
- private String[] allYearMonthPatterns = null;
-
- private String[] allShortDatePatterns = null;
- private String[] allLongDatePatterns = null;
- private String[] allShortTimePatterns = null;
- private String[] allLongTimePatterns = null;
-
- // Cache the era names for this DateTimeFormatInfo instance.
- private String[] m_eraNames = null;
- private String[] m_abbrevEraNames = null;
- private String[] m_abbrevEnglishEraNames = null;
-
- private CalendarId[] optionalCalendars = null;
-
- private const int DEFAULT_ALL_DATETIMES_SIZE = 132;
-
- // CultureInfo updates this
- internal bool _isReadOnly = false;
-
- // This flag gives hints about if formatting/parsing should perform special code path for things like
- // genitive form or leap year month names.
-
- private DateTimeFormatFlags formatFlags = DateTimeFormatFlags.NotInitialized;
-
- private String CultureName
- {
- get
- {
- if (_name == null)
- {
- _name = _cultureData.CultureName;
- }
- return (_name);
- }
- }
-
- private CultureInfo Culture
- {
- get
- {
- if (_cultureInfo == null)
- {
- _cultureInfo = CultureInfo.GetCultureInfo(this.CultureName);
- }
- return _cultureInfo;
- }
- }
-
- // TODO: This ignores other cultures that might want to do something similar
- private String LanguageName
- {
- get
- {
- if (_langName == null)
- {
- _langName = _cultureData.SISO639LANGNAME;
- }
- return (_langName);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Create an array of string which contains the abbreviated day names.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- private String[] internalGetAbbreviatedDayOfWeekNames()
- {
- if (this.abbreviatedDayNames == null)
- {
- // Get the abbreviated day names for our current calendar
- this.abbreviatedDayNames = _cultureData.AbbreviatedDayNames(Calendar.ID);
- Debug.Assert(this.abbreviatedDayNames.Length == 7, "[DateTimeFormatInfo.GetAbbreviatedDayOfWeekNames] Expected 7 day names in a week");
- }
- return (this.abbreviatedDayNames);
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Action: Returns the string array of the one-letter day of week names.
- // Returns:
- // an array of one-letter day of week names
- // Arguments:
- // None
- // Exceptions:
- // None
- //
- ////////////////////////////////////////////////////////////////////////
-
- private String[] internalGetSuperShortDayNames()
- {
- if (this.m_superShortDayNames == null)
- {
- // Get the super short day names for our current calendar
- this.m_superShortDayNames = _cultureData.SuperShortDayNames(Calendar.ID);
- Debug.Assert(this.m_superShortDayNames.Length == 7, "[DateTimeFormatInfo.internalGetSuperShortDayNames] Expected 7 day names in a week");
- }
- return (this.m_superShortDayNames);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Create an array of string which contains the day names.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- private String[] internalGetDayOfWeekNames()
- {
- if (this.dayNames == null)
- {
- // Get the day names for our current calendar
- this.dayNames = _cultureData.DayNames(Calendar.ID);
- Debug.Assert(this.dayNames.Length == 7, "[DateTimeFormatInfo.GetDayOfWeekNames] Expected 7 day names in a week");
- }
- return (this.dayNames);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Create an array of string which contains the abbreviated month names.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- private String[] internalGetAbbreviatedMonthNames()
- {
- if (this.abbreviatedMonthNames == null)
- {
- // Get the month names for our current calendar
- this.abbreviatedMonthNames = _cultureData.AbbreviatedMonthNames(Calendar.ID);
- Debug.Assert(this.abbreviatedMonthNames.Length == 12 || this.abbreviatedMonthNames.Length == 13,
- "[DateTimeFormatInfo.GetAbbreviatedMonthNames] Expected 12 or 13 month names in a year");
- }
- return (this.abbreviatedMonthNames);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Create an array of string which contains the month names.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- private String[] internalGetMonthNames()
- {
- if (this.monthNames == null)
- {
- // Get the month names for our current calendar
- this.monthNames = _cultureData.MonthNames(Calendar.ID);
- Debug.Assert(this.monthNames.Length == 12 || this.monthNames.Length == 13,
- "[DateTimeFormatInfo.GetMonthNames] Expected 12 or 13 month names in a year");
- }
-
- return (this.monthNames);
- }
-
-
- //
- // Invariant DateTimeFormatInfo doesn't have user-overriden values
- // Default calendar is gregorian
- public DateTimeFormatInfo()
- : this(CultureInfo.InvariantCulture.m_cultureData,
- GregorianCalendar.GetDefaultInstance())
- {
- }
-
- internal DateTimeFormatInfo(CultureData cultureData, Calendar cal)
- {
- Debug.Assert(cultureData != null);
- Debug.Assert(cal != null);
-
- // Remember our culture
- _cultureData = cultureData;
-
- this.Calendar = cal;
- }
-
- private void InitializeOverridableProperties(CultureData cultureData, CalendarId calendarId)
- {
- Debug.Assert(cultureData != null);
- Debug.Assert(calendarId != CalendarId.UNINITIALIZED_VALUE, "[DateTimeFormatInfo.Populate] Expected initalized calendarId");
-
- if (this.firstDayOfWeek == -1) { this.firstDayOfWeek = cultureData.IFIRSTDAYOFWEEK; }
- if (this.calendarWeekRule == -1) { this.calendarWeekRule = cultureData.IFIRSTWEEKOFYEAR; }
-
- if (this.amDesignator == null) { this.amDesignator = cultureData.SAM1159; }
- if (this.pmDesignator == null) { this.pmDesignator = cultureData.SPM2359; }
- if (this.timeSeparator == null) { this.timeSeparator = cultureData.TimeSeparator; }
- if (this.dateSeparator == null) { this.dateSeparator = cultureData.DateSeparator(calendarId); }
-
- this.allLongTimePatterns = _cultureData.LongTimes;
- Debug.Assert(this.allLongTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long time patterns");
-
- this.allShortTimePatterns = _cultureData.ShortTimes;
- Debug.Assert(this.allShortTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short time patterns");
-
- this.allLongDatePatterns = cultureData.LongDates(calendarId);
- Debug.Assert(this.allLongDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long date patterns");
-
- this.allShortDatePatterns = cultureData.ShortDates(calendarId);
- Debug.Assert(this.allShortDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short date patterns");
-
- this.allYearMonthPatterns = cultureData.YearMonths(calendarId);
- Debug.Assert(this.allYearMonthPatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some year month patterns");
- }
-
- [OptionalField(VersionAdded = 1)]
- private bool _useUserOverride;
-
- // This was synthesized by Whidbey so we knew what words might appear in the middle of a date string
- // Now we always synthesize so its not helpful
-
- internal String[] m_dateWords = null;
-
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx)
- {
- _name = this.CultureName; // make sure the _name is initialized.
- _useUserOverride = _cultureData.UseUserOverride;
-
- // Important to initialize these fields otherwise we may run into exception when deserializing on Whidbey
- // because Whidbey try to initialize some of these fields using calendar data which could be null values
- // and then we get exceptions. So we call the accessors to force the caches to get loaded.
- Object o;
- o = this.LongTimePattern;
- o = this.LongDatePattern;
- o = this.ShortTimePattern;
- o = this.ShortDatePattern;
- o = this.YearMonthPattern;
- o = this.AllLongTimePatterns;
- o = this.AllLongDatePatterns;
- o = this.AllShortTimePatterns;
- o = this.AllShortDatePatterns;
- o = this.AllYearMonthPatterns;
- }
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext ctx)
- {
- if (_name != null)
- {
- _cultureData = CultureData.GetCultureData(_name, _useUserOverride);
- if (_cultureData == null)
- {
- throw new CultureNotFoundException("_name", _name, SR.Argument_CultureNotSupported);
- }
- }
-
- if (calendar == null)
- {
- calendar = (Calendar)GregorianCalendar.GetDefaultInstance().Clone();
- calendar.SetReadOnlyState(_isReadOnly);
- }
-
- InitializeOverridableProperties(_cultureData, calendar.ID);
-
- //
- // turn off read only state till we finish initializing all fields and then store read only state after we are done.
- //
- bool isReadOnly = _isReadOnly;
- _isReadOnly = false;
-
- // If we deserialized defaults ala Whidbey, make sure they're still defaults
- // Whidbey's arrays could get a bit mixed up.
- if (longDatePattern != null) this.LongDatePattern = longDatePattern;
- if (shortDatePattern != null) this.ShortDatePattern = shortDatePattern;
- if (yearMonthPattern != null) this.YearMonthPattern = yearMonthPattern;
- if (longTimePattern != null) this.LongTimePattern = longTimePattern;
- if (shortTimePattern != null) this.ShortTimePattern = shortTimePattern;
-
- _isReadOnly = isReadOnly;
- }
-
- // Returns a default DateTimeFormatInfo that will be universally
- // supported and constant irrespective of the current culture.
- // Used by FromString methods.
- //
-
- public static DateTimeFormatInfo InvariantInfo
- {
- get
- {
- Contract.Ensures(Contract.Result<DateTimeFormatInfo>() != null);
- if (s_invariantInfo == null)
- {
- DateTimeFormatInfo info = new DateTimeFormatInfo();
- info.Calendar.SetReadOnlyState(true);
- info._isReadOnly = true;
- s_invariantInfo = info;
- }
- return (s_invariantInfo);
- }
- }
-
- // Returns the current culture's DateTimeFormatInfo. Used by Parse methods.
- //
-
- public static DateTimeFormatInfo CurrentInfo
- {
- get
- {
- Contract.Ensures(Contract.Result<DateTimeFormatInfo>() != null);
- System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CurrentCulture;
- if (!culture.m_isInherited)
- {
- DateTimeFormatInfo info = culture.dateTimeInfo;
- if (info != null)
- {
- return info;
- }
- }
- return (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo));
- }
- }
-
-
- public static DateTimeFormatInfo GetInstance(IFormatProvider provider)
- {
- // Fast case for a regular CultureInfo
- DateTimeFormatInfo info;
- CultureInfo cultureProvider = provider as CultureInfo;
- if (cultureProvider != null && !cultureProvider.m_isInherited)
- {
- return cultureProvider.DateTimeFormat;
- }
- // Fast case for a DTFI;
- info = provider as DateTimeFormatInfo;
- if (info != null)
- {
- return info;
- }
- // Wasn't cultureInfo or DTFI, do it the slower way
- if (provider != null)
- {
- info = provider.GetFormat(typeof(DateTimeFormatInfo)) as DateTimeFormatInfo;
- if (info != null)
- {
- return info;
- }
- }
- // Couldn't get anything, just use currentInfo as fallback
- return CurrentInfo;
- }
-
-
- public Object GetFormat(Type formatType)
- {
- return (formatType == typeof(DateTimeFormatInfo) ? this : null);
- }
-
-
- public Object Clone()
- {
- DateTimeFormatInfo n = (DateTimeFormatInfo)MemberwiseClone();
- // We can use the data member calendar in the setter, instead of the property Calendar,
- // since the cloned copy should have the same state as the original copy.
- n.calendar = (Calendar)this.Calendar.Clone();
- n._isReadOnly = false;
- return n;
- }
-
-
- public String AMDesignator
- {
- get
- {
- if (this.amDesignator == null)
- {
- this.amDesignator = _cultureData.SAM1159;
- }
- Debug.Assert(this.amDesignator != null, "DateTimeFormatInfo.AMDesignator, amDesignator != null");
- return (this.amDesignator);
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
- ClearTokenHashTable();
- amDesignator = value;
- }
- }
-
-
- public Calendar Calendar
- {
- get
- {
- Contract.Ensures(Contract.Result<Calendar>() != null);
-
- Debug.Assert(this.calendar != null, "DateTimeFormatInfo.Calendar: calendar != null");
- return (this.calendar);
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value), SR.ArgumentNull_Obj);
- }
- Contract.EndContractBlock();
- if (value == calendar)
- {
- return;
- }
-
- for (int i = 0; i < this.OptionalCalendars.Length; i++)
- {
- if (this.OptionalCalendars[i] == value.ID)
- {
- // We can use this one, so do so.
-
- // Clean related properties if we already had a calendar set
- if (calendar != null)
- {
- // clean related properties which are affected by the calendar setting,
- // so that they will be refreshed when they are accessed next time.
- //
-
- // These properites are in the order as appearing in calendar.xml.
- m_eraNames = null;
- m_abbrevEraNames = null;
- m_abbrevEnglishEraNames = null;
-
- monthDayPattern = null;
-
- dayNames = null;
- abbreviatedDayNames = null;
- m_superShortDayNames = null;
- monthNames = null;
- abbreviatedMonthNames = null;
- genitiveMonthNames = null;
- m_genitiveAbbreviatedMonthNames = null;
- leapYearMonthNames = null;
- formatFlags = DateTimeFormatFlags.NotInitialized;
-
- allShortDatePatterns = null;
- allLongDatePatterns = null;
- allYearMonthPatterns = null;
- dateTimeOffsetPattern = null;
-
- // The defaults need reset as well:
- longDatePattern = null;
- shortDatePattern = null;
- yearMonthPattern = null;
-
- // These properies are not in the OS data, but they are dependent on the values like shortDatePattern.
- fullDateTimePattern = null; // Long date + long time
- generalShortTimePattern = null; // short date + short time
- generalLongTimePattern = null; // short date + long time
-
- // Derived item that changes
- dateSeparator = null;
-
- // We don't need to do these because they are not changed by changing calendar
- // amDesignator
- // pmDesignator
- // timeSeparator
- // longTimePattern
- // firstDayOfWeek
- // calendarWeekRule
-
- // remember to reload tokens
- ClearTokenHashTable();
- }
-
- // Remember the new calendar
- calendar = value;
- InitializeOverridableProperties(_cultureData, calendar.ID);
-
- // We succeeded, return
- return;
- }
- }
-
- // The assigned calendar is not a valid calendar for this culture, throw
- throw new ArgumentOutOfRangeException(nameof(value), SR.Argument_InvalidCalendar);
- }
- }
-
- private CalendarId[] OptionalCalendars
- {
- get
- {
- if (this.optionalCalendars == null)
- {
- this.optionalCalendars = _cultureData.CalendarIds;
- }
- return (this.optionalCalendars);
- }
- }
-
- /*=================================GetEra==========================
- **Action: Get the era value by parsing the name of the era.
- **Returns: The era value for the specified era name.
- ** -1 if the name of the era is not valid or not supported.
- **Arguments: eraName the name of the era.
- **Exceptions: None.
- ============================================================================*/
-
-
- public int GetEra(String eraName)
- {
- if (eraName == null)
- {
- throw new ArgumentNullException(nameof(eraName),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
-
- // The Era Name and Abbreviated Era Name
- // for Taiwan Calendar on non-Taiwan SKU returns empty string (which
- // would be matched below) but we don't want the empty string to give
- // us an Era number
- // confer 85900 DTFI.GetEra("") should fail on all cultures
- if (eraName.Length == 0)
- {
- return (-1);
- }
-
- // The following is based on the assumption that the era value is starting from 1, and has a
- // serial values.
- // If that ever changes, the code has to be changed.
-
- // The calls to String.Compare should use the current culture for the string comparisons, but the
- // invariant culture when comparing against the english names.
- for (int i = 0; i < EraNames.Length; i++)
- {
- // Compare the era name in a case-insensitive way for the appropriate culture.
- if (m_eraNames[i].Length > 0)
- {
- if (this.Culture.CompareInfo.Compare(eraName, m_eraNames[i], CompareOptions.IgnoreCase) == 0)
- {
- return (i + 1);
- }
- }
- }
- for (int i = 0; i < AbbreviatedEraNames.Length; i++)
- {
- // Compare the abbreviated era name in a case-insensitive way for the appropriate culture.
- if (this.Culture.CompareInfo.Compare(eraName, m_abbrevEraNames[i], CompareOptions.IgnoreCase) == 0)
- {
- return (i + 1);
- }
- }
- for (int i = 0; i < AbbreviatedEnglishEraNames.Length; i++)
- {
- // this comparison should use the InvariantCulture. The English name could have linguistically
- // interesting characters.
- if (CultureInfo.InvariantCulture.CompareInfo.Compare(eraName, m_abbrevEnglishEraNames[i], CompareOptions.IgnoreCase) == 0)
- {
- return (i + 1);
- }
- }
- return (-1);
- }
-
-
- internal String[] EraNames
- {
- get
- {
- if (this.m_eraNames == null)
- {
- this.m_eraNames = _cultureData.EraNames(Calendar.ID); ;
- }
- return (this.m_eraNames);
- }
- }
-
- /*=================================GetEraName==========================
- **Action: Get the name of the era for the specified era value.
- **Returns: The name of the specified era.
- **Arguments:
- ** era the era value.
- **Exceptions:
- ** ArguementException if the era valie is invalid.
- ============================================================================*/
-
- // Era names are 1 indexed
- public String GetEraName(int era)
- {
- if (era == Calendar.CurrentEra)
- {
- era = Calendar.CurrentEraValue;
- }
-
- // The following is based on the assumption that the era value is starting from 1, and has a
- // serial values.
- // If that ever changes, the code has to be changed.
- if ((--era) < EraNames.Length && (era >= 0))
- {
- return (m_eraNames[era]);
- }
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
-
- internal String[] AbbreviatedEraNames
- {
- get
- {
- if (this.m_abbrevEraNames == null)
- {
- this.m_abbrevEraNames = _cultureData.AbbrevEraNames(Calendar.ID);
- }
- return (this.m_abbrevEraNames);
- }
- }
-
- // Era names are 1 indexed
- public String GetAbbreviatedEraName(int era)
- {
- if (AbbreviatedEraNames.Length == 0)
- {
- // If abbreviation era name is not used in this culture,
- // return the full era name.
- return (GetEraName(era));
- }
- if (era == Calendar.CurrentEra)
- {
- era = Calendar.CurrentEraValue;
- }
- if ((--era) < m_abbrevEraNames.Length && (era >= 0))
- {
- return (m_abbrevEraNames[era]);
- }
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
-
- internal String[] AbbreviatedEnglishEraNames
- {
- get
- {
- if (this.m_abbrevEnglishEraNames == null)
- {
- Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.AbbreviatedEnglishEraNames] Expected Calendar.ID > 0");
- this.m_abbrevEnglishEraNames = _cultureData.AbbreviatedEnglishEraNames(Calendar.ID);
- }
- return (this.m_abbrevEnglishEraNames);
- }
- }
-
- // Note that cultureData derives this from the short date format (unless someone's set this previously)
- // Note that this property is quite undesirable.
- public string DateSeparator
- {
- get
- {
- if (dateSeparator == null)
- {
- dateSeparator = _cultureData.DateSeparator(Calendar.ID);
- }
- Debug.Assert(this.dateSeparator != null, "DateTimeFormatInfo.DateSeparator, dateSeparator != null");
- return dateSeparator;
- }
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
-
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
- ClearTokenHashTable();
- dateSeparator = value;
- }
- }
-
- public DayOfWeek FirstDayOfWeek
- {
- get
- {
- if (this.firstDayOfWeek == -1)
- {
- this.firstDayOfWeek = _cultureData.IFIRSTDAYOFWEEK;
- }
- Debug.Assert(this.firstDayOfWeek != -1, "DateTimeFormatInfo.FirstDayOfWeek, firstDayOfWeek != -1");
-
- return ((DayOfWeek)this.firstDayOfWeek);
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value >= DayOfWeek.Sunday && value <= DayOfWeek.Saturday)
- {
- firstDayOfWeek = (int)value;
- }
- else
- {
- throw new ArgumentOutOfRangeException(
- nameof(value), SR.Format(SR.ArgumentOutOfRange_Range,
- DayOfWeek.Sunday, DayOfWeek.Saturday));
- }
- }
- }
-
- public CalendarWeekRule CalendarWeekRule
- {
- get
- {
- if (this.calendarWeekRule == -1)
- {
- this.calendarWeekRule = _cultureData.IFIRSTWEEKOFYEAR;
- }
- Debug.Assert(this.calendarWeekRule != -1, "DateTimeFormatInfo.CalendarWeekRule, calendarWeekRule != -1");
- return ((CalendarWeekRule)this.calendarWeekRule);
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value >= CalendarWeekRule.FirstDay && value <= CalendarWeekRule.FirstFourDayWeek)
- {
- calendarWeekRule = (int)value;
- }
- else
- {
- throw new ArgumentOutOfRangeException(
- nameof(value), SR.Format(SR.ArgumentOutOfRange_Range,
- CalendarWeekRule.FirstDay, CalendarWeekRule.FirstFourDayWeek));
- }
- }
- }
-
- public String FullDateTimePattern
- {
- get
- {
- if (fullDateTimePattern == null)
- {
- fullDateTimePattern = LongDatePattern + " " + LongTimePattern;
- }
- return (fullDateTimePattern);
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
- fullDateTimePattern = value;
- }
- }
-
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
- public String LongDatePattern
- {
- get
- {
- // Initialize our long date pattern from the 1st array value if not set
- if (this.longDatePattern == null)
- {
- // Initialize our data
- this.longDatePattern = this.UnclonedLongDatePatterns[0];
- }
-
- return this.longDatePattern;
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
-
- // Remember the new string
- this.longDatePattern = value;
-
- // Clear the token hash table
- ClearTokenHashTable();
-
- // Clean up cached values that will be affected by this property.
- this.fullDateTimePattern = null;
- }
- }
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
- public String LongTimePattern
- {
- get
- {
- // Initialize our long time pattern from the 1st array value if not set
- if (this.longTimePattern == null)
- {
- // Initialize our data
- this.longTimePattern = this.UnclonedLongTimePatterns[0];
- }
-
- return this.longTimePattern;
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
-
- // Remember the new string
- this.longTimePattern = value;
-
- // Clear the token hash table
- ClearTokenHashTable();
-
- // Clean up cached values that will be affected by this property.
- this.fullDateTimePattern = null; // Full date = long date + long Time
- this.generalLongTimePattern = null; // General long date = short date + long Time
- this.dateTimeOffsetPattern = null;
- }
- }
-
-
- // Note: just to be confusing there's only 1 month day pattern, not a whole list
- public String MonthDayPattern
- {
- get
- {
- if (this.monthDayPattern == null)
- {
- Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.MonthDayPattern] Expected calID > 0");
- this.monthDayPattern = _cultureData.MonthDay(Calendar.ID);
- }
- Debug.Assert(this.monthDayPattern != null, "DateTimeFormatInfo.MonthDayPattern, monthDayPattern != null");
- return (this.monthDayPattern);
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
-
- this.monthDayPattern = value;
- }
- }
-
-
- public String PMDesignator
- {
- get
- {
- if (this.pmDesignator == null)
- {
- this.pmDesignator = _cultureData.SPM2359;
- }
- Debug.Assert(this.pmDesignator != null, "DateTimeFormatInfo.PMDesignator, pmDesignator != null");
- return (this.pmDesignator);
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
- ClearTokenHashTable();
-
- pmDesignator = value;
- }
- }
-
-
- public String RFC1123Pattern
- {
- get
- {
- return (rfc1123Pattern);
- }
- }
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
- public String ShortDatePattern
- {
- get
- {
- // Initialize our short date pattern from the 1st array value if not set
- if (this.shortDatePattern == null)
- {
- // Initialize our data
- this.shortDatePattern = this.UnclonedShortDatePatterns[0];
- }
-
- return this.shortDatePattern;
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
- Contract.EndContractBlock();
-
- // Remember the new string
- this.shortDatePattern = value;
-
- // Clear the token hash table, note that even short dates could require this
- ClearTokenHashTable();
-
- // Clean up cached values that will be affected by this property.
- generalLongTimePattern = null; // General long time = short date + long time
- generalShortTimePattern = null; // General short time = short date + short Time
- dateTimeOffsetPattern = null;
- }
- }
-
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
- public String ShortTimePattern
- {
- get
- {
- // Initialize our short time pattern from the 1st array value if not set
- if (this.shortTimePattern == null)
- {
- // Initialize our data
- this.shortTimePattern = this.UnclonedShortTimePatterns[0];
- }
- return this.shortTimePattern;
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
-
- // Remember the new string
- this.shortTimePattern = value;
-
- // Clear the token hash table, note that even short times could require this
- ClearTokenHashTable();
-
- // Clean up cached values that will be affected by this property.
- generalShortTimePattern = null; // General short date = short date + short time.
- }
- }
-
-
- public String SortableDateTimePattern
- {
- get
- {
- return (sortableDateTimePattern);
- }
- }
-
- /*=================================GeneralShortTimePattern=====================
- **Property: Return the pattern for 'g' general format: shortDate + short time
- **Note: This is used by DateTimeFormat.cs to get the pattern for 'g'
- ** We put this internal property here so that we can avoid doing the
- ** concatation every time somebody asks for the general format.
- ==============================================================================*/
-
- internal String GeneralShortTimePattern
- {
- get
- {
- if (generalShortTimePattern == null)
- {
- generalShortTimePattern = ShortDatePattern + " " + ShortTimePattern;
- }
- return (generalShortTimePattern);
- }
- }
-
- /*=================================GeneralLongTimePattern=====================
- **Property: Return the pattern for 'g' general format: shortDate + Long time
- **Note: This is used by DateTimeFormat.cs to get the pattern for 'g'
- ** We put this internal property here so that we can avoid doing the
- ** concatation every time somebody asks for the general format.
- ==============================================================================*/
-
- internal String GeneralLongTimePattern
- {
- get
- {
- if (generalLongTimePattern == null)
- {
- generalLongTimePattern = ShortDatePattern + " " + LongTimePattern;
- }
- return (generalLongTimePattern);
- }
- }
-
- /*=================================DateTimeOffsetPattern==========================
- **Property: Return the default pattern DateTimeOffset : shortDate + long time + time zone offset
- **Note: This is used by DateTimeFormat.cs to get the pattern for short Date + long time + time zone offset
- ** We put this internal property here so that we can avoid doing the
- ** concatation every time somebody uses this form
- ==============================================================================*/
-
- /*=================================DateTimeOffsetPattern==========================
- **Property: Return the default pattern DateTimeOffset : shortDate + long time + time zone offset
- **Note: This is used by DateTimeFormat.cs to get the pattern for short Date + long time + time zone offset
- ** We put this internal property here so that we can avoid doing the
- ** concatation every time somebody uses this form
- ==============================================================================*/
-
- internal String DateTimeOffsetPattern
- {
- get
- {
- if (dateTimeOffsetPattern == null)
- {
- string dateTimePattern = ShortDatePattern + " " + LongTimePattern;
-
- /* LongTimePattern might contain a "z" as part of the format string in which case we don't want to append a time zone offset */
-
- bool foundZ = false;
- bool inQuote = false;
- char quote = '\'';
- for (int i = 0; !foundZ && i < LongTimePattern.Length; i++)
- {
- switch (LongTimePattern[i])
- {
- case 'z':
- /* if we aren't in a quote, we've found a z */
- foundZ = !inQuote;
- /* we'll fall out of the loop now because the test includes !foundZ */
- break;
- case '\'':
- case '\"':
- if (inQuote && (quote == LongTimePattern[i]))
- {
- /* we were in a quote and found a matching exit quote, so we are outside a quote now */
- inQuote = false;
- }
- else if (!inQuote)
- {
- quote = LongTimePattern[i];
- inQuote = true;
- }
- else
- {
- /* we were in a quote and saw the other type of quote character, so we are still in a quote */
- }
- break;
- case '%':
- case '\\':
- i++; /* skip next character that is escaped by this backslash */
- break;
- default:
- break;
- }
- }
-
- if (!foundZ)
- {
- dateTimePattern = dateTimePattern + " zzz";
- }
-
- dateTimeOffsetPattern = dateTimePattern;
- }
- return (dateTimeOffsetPattern);
- }
- }
-
- // Note that cultureData derives this from the long time format (unless someone's set this previously)
- // Note that this property is quite undesirable.
- public string TimeSeparator
- {
- get
- {
- if (timeSeparator == null)
- {
- timeSeparator = _cultureData.TimeSeparator;
- }
- Debug.Assert(this.timeSeparator != null, "DateTimeFormatInfo.TimeSeparator, timeSeparator != null");
- return (timeSeparator);
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
-
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String);
- }
-
- Contract.EndContractBlock();
- ClearTokenHashTable();
-
- timeSeparator = value;
- }
- }
-
- public String UniversalSortableDateTimePattern
- {
- get
- {
- return (universalSortableDateTimePattern);
- }
- }
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
- public String YearMonthPattern
- {
- get
- {
- // Initialize our year/month pattern from the 1st array value if not set
- if (this.yearMonthPattern == null)
- {
- // Initialize our data
- this.yearMonthPattern = this.UnclonedYearMonthPatterns[0];
- }
- return this.yearMonthPattern;
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
-
- // Remember the new string
- this.yearMonthPattern = value;
-
- // Clear the token hash table, note that even short times could require this
- ClearTokenHashTable();
- }
- }
-
- //
- // Check if a string array contains a null value, and throw ArgumentNullException with parameter name "value"
- //
- private static void CheckNullValue(String[] values, int length)
- {
- Debug.Assert(values != null, "value != null");
- Debug.Assert(values.Length >= length);
- for (int i = 0; i < length; i++)
- {
- if (values[i] == null)
- {
- throw new ArgumentNullException("value",
- SR.ArgumentNull_ArrayValue);
- }
- }
- }
-
-
- public String[] AbbreviatedDayNames
- {
- get
- {
- return ((String[])internalGetAbbreviatedDayOfWeekNames().Clone());
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_Array);
- }
- if (value.Length != 7)
- {
- throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value));
- }
- Contract.EndContractBlock();
- CheckNullValue(value, value.Length);
- ClearTokenHashTable();
-
- abbreviatedDayNames = value;
- }
- }
-
- // Returns the string array of the one-letter day of week names.
- public String[] ShortestDayNames
- {
- get
- {
- return ((String[])internalGetSuperShortDayNames().Clone());
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_Array);
- }
- if (value.Length != 7)
- {
- throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value));
- }
- Contract.EndContractBlock();
- CheckNullValue(value, value.Length);
- this.m_superShortDayNames = value;
- }
- }
-
-
- public String[] DayNames
- {
- get
- {
- return ((String[])internalGetDayOfWeekNames().Clone());
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_Array);
- }
- if (value.Length != 7)
- {
- throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value));
- }
- Contract.EndContractBlock();
- CheckNullValue(value, value.Length);
- ClearTokenHashTable();
-
- dayNames = value;
- }
- }
-
-
- public String[] AbbreviatedMonthNames
- {
- get
- {
- return ((String[])internalGetAbbreviatedMonthNames().Clone());
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_Array);
- }
- if (value.Length != 13)
- {
- throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
- }
- Contract.EndContractBlock();
- CheckNullValue(value, value.Length - 1);
- ClearTokenHashTable();
- abbreviatedMonthNames = value;
- }
- }
-
-
- public String[] MonthNames
- {
- get
- {
- return ((String[])internalGetMonthNames().Clone());
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_Array);
- }
- if (value.Length != 13)
- {
- throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
- }
- Contract.EndContractBlock();
- CheckNullValue(value, value.Length - 1);
- monthNames = value;
- ClearTokenHashTable();
- }
- }
-
- // Whitespaces that we allow in the month names.
- // U+00a0 is non-breaking space.
- private static readonly char[] s_monthSpaces = { ' ', '\u00a0' };
-
- internal bool HasSpacesInMonthNames
- {
- get
- {
- return (FormatFlags & DateTimeFormatFlags.UseSpacesInMonthNames) != 0;
- }
- }
-
- internal bool HasSpacesInDayNames
- {
- get
- {
- return (FormatFlags & DateTimeFormatFlags.UseSpacesInDayNames) != 0;
- }
- }
-
-
- //
- // internalGetMonthName
- //
- // Actions: Return the month name using the specified MonthNameStyles in either abbreviated form
- // or full form.
- // Arguments:
- // month
- // style To indicate a form like regular/genitive/month name in a leap year.
- // abbreviated When true, return abbreviated form. Otherwise, return a full form.
- // Exceptions:
- // ArgumentOutOfRangeException When month name is invalid.
- //
- internal String internalGetMonthName(int month, MonthNameStyles style, bool abbreviated)
- {
- //
- // Right now, style is mutual exclusive, but I make the style to be flag so that
- // maybe we can combine flag if there is such a need.
- //
- String[] monthNamesArray = null;
- switch (style)
- {
- case MonthNameStyles.Genitive:
- monthNamesArray = internalGetGenitiveMonthNames(abbreviated);
- break;
- case MonthNameStyles.LeapYear:
- monthNamesArray = internalGetLeapYearMonthNames(/*abbreviated*/);
- break;
- default:
- monthNamesArray = (abbreviated ? internalGetAbbreviatedMonthNames() : internalGetMonthNames());
- break;
- }
- // The month range is from 1 ~ this.m_monthNames.Length
- // (actually is 13 right now for all cases)
- if ((month < 1) || (month > monthNamesArray.Length))
- {
- throw new ArgumentOutOfRangeException(
- nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
- 1, monthNamesArray.Length));
- }
- return (monthNamesArray[month - 1]);
- }
-
- //
- // internalGetGenitiveMonthNames
- //
- // Action: Retrieve the array which contains the month names in genitive form.
- // If this culture does not use the gentive form, the normal month name is returned.
- // Arguments:
- // abbreviated When true, return abbreviated form. Otherwise, return a full form.
- //
- private String[] internalGetGenitiveMonthNames(bool abbreviated)
- {
- if (abbreviated)
- {
- if (this.m_genitiveAbbreviatedMonthNames == null)
- {
- this.m_genitiveAbbreviatedMonthNames = _cultureData.AbbreviatedGenitiveMonthNames(this.Calendar.ID);
- Debug.Assert(this.m_genitiveAbbreviatedMonthNames.Length == 13,
- "[DateTimeFormatInfo.GetGenitiveMonthNames] Expected 13 abbreviated genitive month names in a year");
- }
- return (this.m_genitiveAbbreviatedMonthNames);
- }
-
- if (this.genitiveMonthNames == null)
- {
- this.genitiveMonthNames = _cultureData.GenitiveMonthNames(this.Calendar.ID);
- Debug.Assert(this.genitiveMonthNames.Length == 13,
- "[DateTimeFormatInfo.GetGenitiveMonthNames] Expected 13 genitive month names in a year");
- }
- return (this.genitiveMonthNames);
- }
-
- //
- // internalGetLeapYearMonthNames
- //
- // Actions: Retrieve the month names used in a leap year.
- // If this culture does not have different month names in a leap year, the normal month name is returned.
- // Agruments: None. (can use abbreviated later if needed)
- //
- internal String[] internalGetLeapYearMonthNames(/*bool abbreviated*/)
- {
- if (this.leapYearMonthNames == null)
- {
- Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.internalGetLeapYearMonthNames] Expected Calendar.ID > 0");
- this.leapYearMonthNames = _cultureData.LeapYearMonthNames(Calendar.ID);
- Debug.Assert(this.leapYearMonthNames.Length == 13,
- "[DateTimeFormatInfo.internalGetLeapYearMonthNames] Expepcted 13 leap year month names");
- }
- return (leapYearMonthNames);
- }
-
-
- public String GetAbbreviatedDayName(DayOfWeek dayofweek)
- {
- if ((int)dayofweek < 0 || (int)dayofweek > 6)
- {
- throw new ArgumentOutOfRangeException(
- nameof(dayofweek), SR.Format(SR.ArgumentOutOfRange_Range,
- DayOfWeek.Sunday, DayOfWeek.Saturday));
- }
- Contract.EndContractBlock();
- //
- // Don't call the public property AbbreviatedDayNames here since a clone is needed in that
- // property, so it will be slower. Instead, use GetAbbreviatedDayOfWeekNames() directly.
- //
- return (internalGetAbbreviatedDayOfWeekNames()[(int)dayofweek]);
- }
-
- // Returns the super short day of week names for the specified day of week.
- public string GetShortestDayName(DayOfWeek dayOfWeek)
- {
- if ((int)dayOfWeek < 0 || (int)dayOfWeek > 6)
- {
- throw new ArgumentOutOfRangeException(
- nameof(dayOfWeek), SR.Format(SR.ArgumentOutOfRange_Range,
- DayOfWeek.Sunday, DayOfWeek.Saturday));
- }
- Contract.EndContractBlock();
- //
- // Don't call the public property SuperShortDayNames here since a clone is needed in that
- // property, so it will be slower. Instead, use internalGetSuperShortDayNames() directly.
- //
- return (internalGetSuperShortDayNames()[(int)dayOfWeek]);
- }
-
- // Get all possible combination of inputs
- private static String[] GetCombinedPatterns(String[] patterns1, String[] patterns2, String connectString)
- {
- Debug.Assert(patterns1 != null);
- Debug.Assert(patterns2 != null);
-
- // Get array size
- String[] result = new String[patterns1.Length * patterns2.Length];
-
- // Counter of actual results
- int k = 0;
- for (int i = 0; i < patterns1.Length; i++)
- {
- for (int j = 0; j < patterns2.Length; j++)
- {
- // Can't combine if null or empty
- result[k++] = patterns1[i] + connectString + patterns2[j];
- }
- }
-
- // Return the combinations
- return (result);
- }
-
- public string[] GetAllDateTimePatterns()
- {
- List<String> results = new List<String>(DEFAULT_ALL_DATETIMES_SIZE);
-
- for (int i = 0; i < DateTimeFormat.allStandardFormats.Length; i++)
- {
- String[] strings = GetAllDateTimePatterns(DateTimeFormat.allStandardFormats[i]);
- for (int j = 0; j < strings.Length; j++)
- {
- results.Add(strings[j]);
- }
- }
- return results.ToArray();
- }
-
- public string[] GetAllDateTimePatterns(char format)
- {
- Contract.Ensures(Contract.Result<String[]>() != null);
- String[] result = null;
-
- switch (format)
- {
- case 'd':
- result = this.AllShortDatePatterns;
- break;
- case 'D':
- result = this.AllLongDatePatterns;
- break;
- case 'f':
- result = GetCombinedPatterns(AllLongDatePatterns, AllShortTimePatterns, " ");
- break;
- case 'F':
- case 'U':
- result = GetCombinedPatterns(AllLongDatePatterns, AllLongTimePatterns, " ");
- break;
- case 'g':
- result = GetCombinedPatterns(AllShortDatePatterns, AllShortTimePatterns, " ");
- break;
- case 'G':
- result = GetCombinedPatterns(AllShortDatePatterns, AllLongTimePatterns, " ");
- break;
- case 'm':
- case 'M':
- result = new String[] { MonthDayPattern };
- break;
- case 'o':
- case 'O':
- result = new String[] { RoundtripFormat };
- break;
- case 'r':
- case 'R':
- result = new String[] { rfc1123Pattern };
- break;
- case 's':
- result = new String[] { sortableDateTimePattern };
- break;
- case 't':
- result = this.AllShortTimePatterns;
- break;
- case 'T':
- result = this.AllLongTimePatterns;
- break;
- case 'u':
- result = new String[] { UniversalSortableDateTimePattern };
- break;
- case 'y':
- case 'Y':
- result = this.AllYearMonthPatterns;
- break;
- default:
- throw new ArgumentException(SR.Format_BadFormatSpecifier, nameof(format));
- }
- return (result);
- }
-
-
- public String GetDayName(DayOfWeek dayofweek)
- {
- if ((int)dayofweek < 0 || (int)dayofweek > 6)
- {
- throw new ArgumentOutOfRangeException(
- nameof(dayofweek), SR.Format(SR.ArgumentOutOfRange_Range,
- DayOfWeek.Sunday, DayOfWeek.Saturday));
- }
- Contract.EndContractBlock();
-
- // Use the internal one so that we don't clone the array unnecessarily
- return (internalGetDayOfWeekNames()[(int)dayofweek]);
- }
-
-
-
- public String GetAbbreviatedMonthName(int month)
- {
- if (month < 1 || month > 13)
- {
- throw new ArgumentOutOfRangeException(
- nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
- 1, 13));
- }
- Contract.EndContractBlock();
- // Use the internal one so we don't clone the array unnecessarily
- return (internalGetAbbreviatedMonthNames()[month - 1]);
- }
-
-
- public String GetMonthName(int month)
- {
- if (month < 1 || month > 13)
- {
- throw new ArgumentOutOfRangeException(
- nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
- 1, 13));
- }
- Contract.EndContractBlock();
- // Use the internal one so we don't clone the array unnecessarily
- return (internalGetMonthNames()[month - 1]);
- }
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
- //
- // The resulting [] can get returned to the calling app, so clone it.
- private static string[] GetMergedPatterns(string[] patterns, string defaultPattern)
- {
- Debug.Assert(patterns != null && patterns.Length > 0,
- "[DateTimeFormatInfo.GetMergedPatterns]Expected array of at least one pattern");
- Debug.Assert(defaultPattern != null,
- "[DateTimeFormatInfo.GetMergedPatterns]Expected non null default string");
-
- // If the default happens to be the first in the list just return (a cloned) copy
- if (defaultPattern == patterns[0])
- {
- return (string[])patterns.Clone();
- }
-
- // We either need a bigger list, or the pattern from the list.
- int i;
- for (i = 0; i < patterns.Length; i++)
- {
- // Stop if we found it
- if (defaultPattern == patterns[i])
- break;
- }
-
- // Either way we're going to need a new array
- string[] newPatterns;
-
- // Did we find it
- if (i < patterns.Length)
- {
- // Found it, output will be same size
- newPatterns = (string[])patterns.Clone();
-
- // Have to move [0] item to [i] so we can re-write default at [0]
- // (remember defaultPattern == [i] so this is OK)
- newPatterns[i] = newPatterns[0];
- }
- else
- {
- // Not found, make room for it
- newPatterns = new String[patterns.Length + 1];
-
- // Copy existing array
- Array.Copy(patterns, 0, newPatterns, 1, patterns.Length);
- }
-
- // Remember the default
- newPatterns[0] = defaultPattern;
-
- // Return the reconstructed list
- return newPatterns;
- }
-
- // Needed by DateTimeFormatInfo and DateTimeFormat
- internal const String RoundtripFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK";
- internal const String RoundtripDateTimeUnfixed = "yyyy'-'MM'-'ddTHH':'mm':'ss zzz";
-
- // Default string isn't necessarily in our string array, so get the
- // merged patterns of both
- private String[] AllYearMonthPatterns
- {
- get
- {
- return GetMergedPatterns(this.UnclonedYearMonthPatterns, this.YearMonthPattern);
- }
- }
-
- private String[] AllShortDatePatterns
- {
- get
- {
- return GetMergedPatterns(this.UnclonedShortDatePatterns, this.ShortDatePattern);
- }
- }
-
- private String[] AllShortTimePatterns
- {
- get
- {
- return GetMergedPatterns(this.UnclonedShortTimePatterns, this.ShortTimePattern);
- }
- }
-
- private String[] AllLongDatePatterns
- {
- get
- {
- return GetMergedPatterns(this.UnclonedLongDatePatterns, this.LongDatePattern);
- }
- }
-
- private String[] AllLongTimePatterns
- {
- get
- {
- return GetMergedPatterns(this.UnclonedLongTimePatterns, this.LongTimePattern);
- }
- }
-
- // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
- // This won't include default, call AllYearMonthPatterns
- private String[] UnclonedYearMonthPatterns
- {
- get
- {
- if (this.allYearMonthPatterns == null)
- {
- Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedYearMonthPatterns] Expected Calendar.ID > 0");
- this.allYearMonthPatterns = _cultureData.YearMonths(this.Calendar.ID);
- Debug.Assert(this.allYearMonthPatterns.Length > 0,
- "[DateTimeFormatInfo.UnclonedYearMonthPatterns] Expected some year month patterns");
- }
-
- return this.allYearMonthPatterns;
- }
- }
-
-
- // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
- // This won't include default, call AllShortDatePatterns
- private String[] UnclonedShortDatePatterns
- {
- get
- {
- if (allShortDatePatterns == null)
- {
- Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedShortDatePatterns] Expected Calendar.ID > 0");
- this.allShortDatePatterns = _cultureData.ShortDates(this.Calendar.ID);
- Debug.Assert(this.allShortDatePatterns.Length > 0,
- "[DateTimeFormatInfo.UnclonedShortDatePatterns] Expected some short date patterns");
- }
-
- return this.allShortDatePatterns;
- }
- }
-
- // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
- // This won't include default, call AllLongDatePatterns
- private String[] UnclonedLongDatePatterns
- {
- get
- {
- if (allLongDatePatterns == null)
- {
- Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedLongDatePatterns] Expected Calendar.ID > 0");
- this.allLongDatePatterns = _cultureData.LongDates(this.Calendar.ID);
- Debug.Assert(this.allLongDatePatterns.Length > 0,
- "[DateTimeFormatInfo.UnclonedLongDatePatterns] Expected some long date patterns");
- }
-
- return this.allLongDatePatterns;
- }
- }
-
- // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
- // This won't include default, call AllShortTimePatterns
- private String[] UnclonedShortTimePatterns
- {
- get
- {
- if (this.allShortTimePatterns == null)
- {
- this.allShortTimePatterns = _cultureData.ShortTimes;
- Debug.Assert(this.allShortTimePatterns.Length > 0,
- "[DateTimeFormatInfo.UnclonedShortTimePatterns] Expected some short time patterns");
- }
-
- return this.allShortTimePatterns;
- }
- }
-
- // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
- // This won't include default, call AllLongTimePatterns
- private String[] UnclonedLongTimePatterns
- {
- get
- {
- if (this.allLongTimePatterns == null)
- {
- this.allLongTimePatterns = _cultureData.LongTimes;
- Debug.Assert(this.allLongTimePatterns.Length > 0,
- "[DateTimeFormatInfo.UnclonedLongTimePatterns] Expected some long time patterns");
- }
-
- return this.allLongTimePatterns;
- }
- }
-
- public static DateTimeFormatInfo ReadOnly(DateTimeFormatInfo dtfi)
- {
- if (dtfi == null)
- {
- throw new ArgumentNullException(nameof(dtfi),
- SR.ArgumentNull_Obj);
- }
- Contract.EndContractBlock();
- if (dtfi.IsReadOnly)
- {
- return (dtfi);
- }
- DateTimeFormatInfo newInfo = (DateTimeFormatInfo)(dtfi.MemberwiseClone());
- // We can use the data member calendar in the setter, instead of the property Calendar,
- // since the cloned copy should have the same state as the original copy.
- newInfo.calendar = Calendar.ReadOnly(dtfi.Calendar);
- newInfo._isReadOnly = true;
- return (newInfo);
- }
-
- public bool IsReadOnly
- {
- get
- {
- return (_isReadOnly);
- }
- }
-
- // Return the native name for the calendar in DTFI.Calendar. The native name is referred to
- // the culture used to create the DTFI. E.g. in the following example, the native language is Japanese.
- // DateTimeFormatInfo dtfi = new CultureInfo("ja-JP", false).DateTimeFormat.Calendar = new JapaneseCalendar();
- // String nativeName = dtfi.NativeCalendarName; // Get the Japanese name for the Japanese calendar.
- // DateTimeFormatInfo dtfi = new CultureInfo("ja-JP", false).DateTimeFormat.Calendar = new GregorianCalendar(GregorianCalendarTypes.Localized);
- // String nativeName = dtfi.NativeCalendarName; // Get the Japanese name for the Gregorian calendar.
- public string NativeCalendarName
- {
- get
- {
- return _cultureData.CalendarName(Calendar.ID);
- }
- }
-
- //
- // Used by custom cultures and others to set the list of available formats. Note that none of them are
- // explicitly used unless someone calls GetAllDateTimePatterns and subsequently uses one of the items
- // from the list.
- //
- // Most of the format characters that can be used in GetAllDateTimePatterns are
- // not really needed since they are one of the following:
- //
- // r/R/s/u locale-independent constants -- cannot be changed!
- // m/M/y/Y fields with a single string in them -- that can be set through props directly
- // f/F/g/G/U derived fields based on combinations of various of the below formats
- //
- // NOTE: No special validation is done here beyond what is done when the actual respective fields
- // are used (what would be the point of disallowing here what we allow in the appropriate property?)
- //
- // WARNING: If more validation is ever done in one place, it should be done in the other.
- //
- public void SetAllDateTimePatterns(String[] patterns, char format)
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
-
- if (patterns == null)
- {
- throw new ArgumentNullException(nameof(patterns), SR.ArgumentNull_Array);
- }
-
- if (patterns.Length == 0)
- {
- throw new ArgumentException(SR.Arg_ArrayZeroError, nameof(patterns));
- }
-
- Contract.EndContractBlock();
-
- for (int i=0; i<patterns.Length; i++)
- {
- if (patterns[i] == null)
- {
- throw new ArgumentNullException("patterns[" + i + "]", SR.ArgumentNull_ArrayValue);
- }
- }
-
- // Remember the patterns, and use the 1st as default
- switch (format)
- {
- case 'd':
- allShortDatePatterns = patterns;
- shortDatePattern = allShortDatePatterns[0];
- break;
-
- case 'D':
- allLongDatePatterns = patterns;
- longDatePattern = allLongDatePatterns[0];
- break;
-
- case 't':
- allShortTimePatterns = patterns;
- shortTimePattern = allShortTimePatterns[0];
- break;
-
- case 'T':
- allLongTimePatterns = patterns;
- longTimePattern = allLongTimePatterns[0];
- break;
-
- case 'y':
- case 'Y':
- allYearMonthPatterns = patterns;
- yearMonthPattern = allYearMonthPatterns[0];
- break;
-
- default:
- throw new ArgumentException(SR.Format_BadFormatSpecifier, nameof(format));
- }
-
- // Clear the token hash table, note that even short dates could require this
- ClearTokenHashTable();
- }
-
- public String[] AbbreviatedMonthGenitiveNames
- {
- get
- {
- return ((String[])internalGetGenitiveMonthNames(true).Clone());
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_Array);
- }
- if (value.Length != 13)
- {
- throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
- }
- Contract.EndContractBlock();
- CheckNullValue(value, value.Length - 1);
- ClearTokenHashTable();
- this.m_genitiveAbbreviatedMonthNames = value;
- }
- }
-
- public String[] MonthGenitiveNames
- {
- get
- {
- return ((String[])internalGetGenitiveMonthNames(false).Clone());
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_Array);
- }
- if (value.Length != 13)
- {
- throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
- }
- Contract.EndContractBlock();
- CheckNullValue(value, value.Length - 1);
- genitiveMonthNames = value;
- ClearTokenHashTable();
- }
- }
-
- //
- // Positive TimeSpan Pattern
- //
- [NonSerialized]
- private string _fullTimeSpanPositivePattern;
- internal String FullTimeSpanPositivePattern
- {
- get
- {
- if (_fullTimeSpanPositivePattern == null)
- {
- CultureData cultureDataWithoutUserOverrides;
- if (_cultureData.UseUserOverride)
- cultureDataWithoutUserOverrides = CultureData.GetCultureData(_cultureData.CultureName, false);
- else
- cultureDataWithoutUserOverrides = _cultureData;
- String decimalSeparator = new NumberFormatInfo(cultureDataWithoutUserOverrides).NumberDecimalSeparator;
-
- _fullTimeSpanPositivePattern = "d':'h':'mm':'ss'" + decimalSeparator + "'FFFFFFF";
- }
- return _fullTimeSpanPositivePattern;
- }
- }
-
- //
- // Negative TimeSpan Pattern
- //
- [NonSerialized]
- private string _fullTimeSpanNegativePattern;
- internal String FullTimeSpanNegativePattern
- {
- get
- {
- if (_fullTimeSpanNegativePattern == null)
- _fullTimeSpanNegativePattern = "'-'" + FullTimeSpanPositivePattern;
- return _fullTimeSpanNegativePattern;
- }
- }
-
- //
- // Get suitable CompareInfo from current DTFI object.
- //
- internal CompareInfo CompareInfo
- {
- get
- {
- if (_compareInfo == null)
- {
- // We use the regular GetCompareInfo here to make sure the created CompareInfo object is stored in the
- // CompareInfo cache. otherwise we would just create CompareInfo using _cultureData.
- _compareInfo = CompareInfo.GetCompareInfo(_cultureData.SCOMPAREINFO);
- }
-
- return _compareInfo;
- }
- }
-
-
- internal const DateTimeStyles InvalidDateTimeStyles = ~(DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite
- | DateTimeStyles.AllowInnerWhite | DateTimeStyles.NoCurrentDateDefault
- | DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeLocal
- | DateTimeStyles.AssumeUniversal | DateTimeStyles.RoundtripKind);
-
- internal static void ValidateStyles(DateTimeStyles style, String parameterName)
- {
- if ((style & InvalidDateTimeStyles) != 0)
- {
- throw new ArgumentException(SR.Argument_InvalidDateTimeStyles, parameterName);
- }
- if (((style & (DateTimeStyles.AssumeLocal)) != 0) && ((style & (DateTimeStyles.AssumeUniversal)) != 0))
- {
- throw new ArgumentException(SR.Argument_ConflictingDateTimeStyles, parameterName);
- }
- Contract.EndContractBlock();
- if (((style & DateTimeStyles.RoundtripKind) != 0)
- && ((style & (DateTimeStyles.AssumeLocal | DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)) != 0))
- {
- throw new ArgumentException(SR.Argument_ConflictingDateTimeRoundtripStyles, parameterName);
- }
- }
-
- //
- // Actions: Return the internal flag used in formatting and parsing.
- // The flag can be used to indicate things like if genitive forms is used in this DTFi, or if leap year gets different month names.
- //
- internal DateTimeFormatFlags FormatFlags
- {
- get
- {
- if (formatFlags == DateTimeFormatFlags.NotInitialized)
- {
- // Build the format flags from the data in this DTFI
- formatFlags = DateTimeFormatFlags.None;
- formatFlags |= (DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagGenitiveMonth(
- MonthNames, internalGetGenitiveMonthNames(false), AbbreviatedMonthNames, internalGetGenitiveMonthNames(true));
- formatFlags |= (DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagUseSpaceInMonthNames(
- MonthNames, internalGetGenitiveMonthNames(false), AbbreviatedMonthNames, internalGetGenitiveMonthNames(true));
- formatFlags |= (DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagUseSpaceInDayNames(DayNames, AbbreviatedDayNames);
- formatFlags |= (DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagUseHebrewCalendar((int)Calendar.ID);
- }
- return (formatFlags);
- }
- }
-
- internal Boolean HasForceTwoDigitYears
- {
- get
- {
- switch (calendar.ID)
- {
- // Handle Japanese and Taiwan cases.
- // If is y/yy, do not get (year % 100). "y" will print
- // year without leading zero. "yy" will print year with two-digit in leading zero.
- // If pattern is yyy/yyyy/..., print year value with two-digit in leading zero.
- // So year 5 is "05", and year 125 is "125".
- // The reason for not doing (year % 100) is for Taiwan calendar.
- // If year 125, then output 125 and not 25.
- // Note: OS uses "yyyy" for Taiwan calendar by default.
- case (CalendarId.JAPAN):
- case (CalendarId.TAIWAN):
- return true;
- }
- return false;
- }
- }
-
- // Returns whether the YearMonthAdjustment function has any fix-up work to do for this culture/calendar.
- internal Boolean HasYearMonthAdjustment
- {
- get
- {
- return ((FormatFlags & DateTimeFormatFlags.UseHebrewRule) != 0);
- }
- }
-
- // This is a callback that the parser can make back into the DTFI to let it fiddle with special
- // cases associated with that culture or calendar. Currently this only has special cases for
- // the Hebrew calendar, but this could be extended to other cultures.
- //
- // The return value is whether the year and month are actually valid for this calendar.
- internal Boolean YearMonthAdjustment(ref int year, ref int month, Boolean parsedMonthName)
- {
- if ((FormatFlags & DateTimeFormatFlags.UseHebrewRule) != 0)
- {
- // Special rules to fix up the Hebrew year/month
-
- // When formatting, we only format up to the hundred digit of the Hebrew year, although Hebrew year is now over 5000.
- // E.g. if the year is 5763, we only format as 763.
- if (year < 1000)
- {
- year += 5000;
- }
-
- // Because we need to calculate leap year, we should fall out now for an invalid year.
- if (year < Calendar.GetYear(Calendar.MinSupportedDateTime) || year > Calendar.GetYear(Calendar.MaxSupportedDateTime))
- {
- return false;
- }
-
- // To handle leap months, the set of month names in the symbol table does not always correspond to the numbers.
- // For non-leap years, month 7 (Adar Bet) is not present, so we need to make using this month invalid and
- // shuffle the other months down.
- if (parsedMonthName)
- {
- if (!Calendar.IsLeapYear(year))
- {
- if (month >= 8)
- {
- month--;
- }
- else if (month == 7)
- {
- return false;
- }
- }
- }
- }
- return true;
- }
-
- //
- // DateTimeFormatInfo tokenizer. This is used by DateTime.Parse() to break input string into tokens.
- //
- [NonSerialized]
- private TokenHashValue[] _dtfiTokenHash;
-
- private const int TOKEN_HASH_SIZE = 199;
- private const int SECOND_PRIME = 197;
- private const String dateSeparatorOrTimeZoneOffset = "-";
- private const String invariantDateSeparator = "/";
- private const String invariantTimeSeparator = ":";
-
- //
- // Common Ignorable Symbols
- //
- internal const String IgnorablePeriod = ".";
- internal const String IgnorableComma = ",";
-
- //
- // Year/Month/Day suffixes
- //
- internal const String CJKYearSuff = "\u5e74";
- internal const String CJKMonthSuff = "\u6708";
- internal const String CJKDaySuff = "\u65e5";
-
- internal const String KoreanYearSuff = "\ub144";
- internal const String KoreanMonthSuff = "\uc6d4";
- internal const String KoreanDaySuff = "\uc77c";
-
- internal const String KoreanHourSuff = "\uc2dc";
- internal const String KoreanMinuteSuff = "\ubd84";
- internal const String KoreanSecondSuff = "\ucd08";
-
- internal const String CJKHourSuff = "\u6642";
- internal const String ChineseHourSuff = "\u65f6";
-
- internal const String CJKMinuteSuff = "\u5206";
- internal const String CJKSecondSuff = "\u79d2";
-
- internal const String LocalTimeMark = "T";
-
- internal const String GMTName = "GMT";
- internal const String ZuluName = "Z";
-
- internal const String KoreanLangName = "ko";
- internal const String JapaneseLangName = "ja";
- internal const String EnglishLangName = "en";
-
- private static volatile DateTimeFormatInfo s_jajpDTFI;
- private static volatile DateTimeFormatInfo s_zhtwDTFI;
-
- //
- // Create a Japanese DTFI which uses JapaneseCalendar. This is used to parse
- // date string with Japanese era name correctly even when the supplied DTFI
- // does not use Japanese calendar.
- // The created instance is stored in global s_jajpDTFI.
- //
- internal static DateTimeFormatInfo GetJapaneseCalendarDTFI()
- {
- DateTimeFormatInfo temp = s_jajpDTFI;
- if (temp == null)
- {
- temp = new CultureInfo("ja-JP", false).DateTimeFormat;
- temp.Calendar = JapaneseCalendar.GetDefaultInstance();
- s_jajpDTFI = temp;
- }
- return (temp);
- }
-
- // Create a Taiwan DTFI which uses TaiwanCalendar. This is used to parse
- // date string with era name correctly even when the supplied DTFI
- // does not use Taiwan calendar.
- // The created instance is stored in global s_zhtwDTFI.
- internal static DateTimeFormatInfo GetTaiwanCalendarDTFI()
- {
- DateTimeFormatInfo temp = s_zhtwDTFI;
- if (temp == null)
- {
- temp = new CultureInfo("zh-TW", false).DateTimeFormat;
- temp.Calendar = TaiwanCalendar.GetDefaultInstance();
- s_zhtwDTFI = temp;
- }
- return (temp);
- }
-
-
- // DTFI properties should call this when the setter are called.
- private void ClearTokenHashTable()
- {
- _dtfiTokenHash = null;
- formatFlags = DateTimeFormatFlags.NotInitialized;
- }
-
- internal TokenHashValue[] CreateTokenHashTable()
- {
- TokenHashValue[] temp = _dtfiTokenHash;
- if (temp == null)
- {
- temp = new TokenHashValue[TOKEN_HASH_SIZE];
-
- bool koreanLanguage = LanguageName.Equals(KoreanLangName);
-
- string sep = this.TimeSeparator.Trim();
- if (IgnorableComma != sep) InsertHash(temp, IgnorableComma, TokenType.IgnorableSymbol, 0);
- if (IgnorablePeriod != sep) InsertHash(temp, IgnorablePeriod, TokenType.IgnorableSymbol, 0);
-
- if (KoreanHourSuff != sep && CJKHourSuff != sep && ChineseHourSuff != sep)
- {
- //
- // On the Macintosh, the default TimeSeparator is identical to the KoreanHourSuff, CJKHourSuff, or ChineseHourSuff for some cultures like
- // ja-JP and ko-KR. In these cases having the same symbol inserted into the hash table with multiple TokenTypes causes undesirable
- // DateTime.Parse behavior. For instance, the DateTimeFormatInfo.Tokenize() method might return SEP_DateOrOffset for KoreanHourSuff
- // instead of SEP_HourSuff.
- //
- InsertHash(temp, this.TimeSeparator, TokenType.SEP_Time, 0);
- }
-
- InsertHash(temp, this.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
- InsertHash(temp, this.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
-
- // TODO: This ignores similar custom cultures
- if (LanguageName.Equals("sq"))
- {
- // Albanian allows time formats like "12:00.PD"
- InsertHash(temp, IgnorablePeriod + this.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
- InsertHash(temp, IgnorablePeriod + this.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
- }
-
- // CJK suffix
- InsertHash(temp, CJKYearSuff, TokenType.SEP_YearSuff, 0);
- InsertHash(temp, KoreanYearSuff, TokenType.SEP_YearSuff, 0);
- InsertHash(temp, CJKMonthSuff, TokenType.SEP_MonthSuff, 0);
- InsertHash(temp, KoreanMonthSuff, TokenType.SEP_MonthSuff, 0);
- InsertHash(temp, CJKDaySuff, TokenType.SEP_DaySuff, 0);
- InsertHash(temp, KoreanDaySuff, TokenType.SEP_DaySuff, 0);
-
- InsertHash(temp, CJKHourSuff, TokenType.SEP_HourSuff, 0);
- InsertHash(temp, ChineseHourSuff, TokenType.SEP_HourSuff, 0);
- InsertHash(temp, CJKMinuteSuff, TokenType.SEP_MinuteSuff, 0);
- InsertHash(temp, CJKSecondSuff, TokenType.SEP_SecondSuff, 0);
-
- // TODO: This ignores other custom cultures that might want to do something similar
- if (koreanLanguage)
- {
- // Korean suffix
- InsertHash(temp, KoreanHourSuff, TokenType.SEP_HourSuff, 0);
- InsertHash(temp, KoreanMinuteSuff, TokenType.SEP_MinuteSuff, 0);
- InsertHash(temp, KoreanSecondSuff, TokenType.SEP_SecondSuff, 0);
- }
-
- if (LanguageName.Equals("ky"))
- {
- // For some cultures, the date separator works more like a comma, being allowed before or after any date part
- InsertHash(temp, dateSeparatorOrTimeZoneOffset, TokenType.IgnorableSymbol, 0);
- }
- else
- {
- InsertHash(temp, dateSeparatorOrTimeZoneOffset, TokenType.SEP_DateOrOffset, 0);
- }
-
- String[] dateWords = null;
- DateTimeFormatInfoScanner scanner = null;
-
- // We need to rescan the date words since we're always synthetic
- scanner = new DateTimeFormatInfoScanner();
- m_dateWords = dateWords = scanner.GetDateWordsOfDTFI(this);
- // Ensure the formatflags is initialized.
- DateTimeFormatFlags flag = FormatFlags;
-
- // For some cultures, the date separator works more like a comma, being allowed before or after any date part.
- // In these cultures, we do not use normal date separator since we disallow date separator after a date terminal state.
- // This is determined in DateTimeFormatInfoScanner. Use this flag to determine if we should treat date separator as ignorable symbol.
- bool useDateSepAsIgnorableSymbol = false;
-
- String monthPostfix = null;
- if (dateWords != null)
- {
- // There are DateWords. It could be a real date word (such as "de"), or a monthPostfix.
- // The monthPostfix starts with '\xfffe' (MonthPostfixChar), followed by the real monthPostfix.
- for (int i = 0; i < dateWords.Length; i++)
- {
- switch (dateWords[i][0])
- {
- // This is a month postfix
- case DateTimeFormatInfoScanner.MonthPostfixChar:
- // Get the real month postfix.
- monthPostfix = dateWords[i].Substring(1);
- // Add the month name + postfix into the token.
- AddMonthNames(temp, monthPostfix);
- break;
- case DateTimeFormatInfoScanner.IgnorableSymbolChar:
- String symbol = dateWords[i].Substring(1);
- InsertHash(temp, symbol, TokenType.IgnorableSymbol, 0);
- if (this.DateSeparator.Trim(null).Equals(symbol))
- {
- // The date separator is the same as the ignorable symbol.
- useDateSepAsIgnorableSymbol = true;
- }
- break;
- default:
- InsertHash(temp, dateWords[i], TokenType.DateWordToken, 0);
- // TODO: This ignores similar custom cultures
- if (LanguageName.Equals("eu"))
- {
- // Basque has date words with leading dots
- InsertHash(temp, IgnorablePeriod + dateWords[i], TokenType.DateWordToken, 0);
- }
- break;
- }
- }
- }
-
- if (!useDateSepAsIgnorableSymbol)
- {
- // Use the normal date separator.
- InsertHash(temp, this.DateSeparator, TokenType.SEP_Date, 0);
- }
- // Add the regular month names.
- AddMonthNames(temp, null);
-
- // Add the abbreviated month names.
- for (int i = 1; i <= 13; i++)
- {
- InsertHash(temp, GetAbbreviatedMonthName(i), TokenType.MonthToken, i);
- }
-
-
- if ((FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != 0)
- {
- for (int i = 1; i <= 13; i++)
- {
- String str;
- str = internalGetMonthName(i, MonthNameStyles.Genitive, false);
- InsertHash(temp, str, TokenType.MonthToken, i);
- }
- }
-
- if ((FormatFlags & DateTimeFormatFlags.UseLeapYearMonth) != 0)
- {
- for (int i = 1; i <= 13; i++)
- {
- String str;
- str = internalGetMonthName(i, MonthNameStyles.LeapYear, false);
- InsertHash(temp, str, TokenType.MonthToken, i);
- }
- }
-
- for (int i = 0; i < 7; i++)
- {
- //String str = GetDayOfWeekNames()[i];
- // We have to call public methods here to work with inherited DTFI.
- String str = GetDayName((DayOfWeek)i);
- InsertHash(temp, str, TokenType.DayOfWeekToken, i);
-
- str = GetAbbreviatedDayName((DayOfWeek)i);
- InsertHash(temp, str, TokenType.DayOfWeekToken, i);
- }
-
- int[] eras = calendar.Eras;
- for (int i = 1; i <= eras.Length; i++)
- {
- InsertHash(temp, GetEraName(i), TokenType.EraToken, i);
- InsertHash(temp, GetAbbreviatedEraName(i), TokenType.EraToken, i);
- }
-
- // TODO: This ignores other cultures that might want to do something similar
- if (LanguageName.Equals(JapaneseLangName))
- {
- // Japanese allows day of week forms like: "(Tue)"
- for (int i = 0; i < 7; i++)
- {
- String specialDayOfWeek = "(" + GetAbbreviatedDayName((DayOfWeek)i) + ")";
- InsertHash(temp, specialDayOfWeek, TokenType.DayOfWeekToken, i);
- }
- if (this.Calendar.GetType() != typeof(JapaneseCalendar))
- {
- // Special case for Japanese. If this is a Japanese DTFI, and the calendar is not Japanese calendar,
- // we will check Japanese Era name as well when the calendar is Gregorian.
- DateTimeFormatInfo jaDtfi = GetJapaneseCalendarDTFI();
- for (int i = 1; i <= jaDtfi.Calendar.Eras.Length; i++)
- {
- InsertHash(temp, jaDtfi.GetEraName(i), TokenType.JapaneseEraToken, i);
- InsertHash(temp, jaDtfi.GetAbbreviatedEraName(i), TokenType.JapaneseEraToken, i);
- // m_abbrevEnglishEraNames[0] contains the name for era 1, so the token value is i+1.
- InsertHash(temp, jaDtfi.AbbreviatedEnglishEraNames[i - 1], TokenType.JapaneseEraToken, i);
- }
- }
- }
- // TODO: This prohibits similar custom cultures, but we hard coded the name
- else if (CultureName.Equals("zh-TW"))
- {
- DateTimeFormatInfo twDtfi = GetTaiwanCalendarDTFI();
- for (int i = 1; i <= twDtfi.Calendar.Eras.Length; i++)
- {
- if (twDtfi.GetEraName(i).Length > 0)
- {
- InsertHash(temp, twDtfi.GetEraName(i), TokenType.TEraToken, i);
- }
- }
- }
-
- InsertHash(temp, InvariantInfo.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
- InsertHash(temp, InvariantInfo.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
-
- // Add invariant month names and day names.
- for (int i = 1; i <= 12; i++)
- {
- String str;
- // We have to call public methods here to work with inherited DTFI.
- // Insert the month name first, so that they are at the front of abbrevaited
- // month names.
- str = InvariantInfo.GetMonthName(i);
- InsertHash(temp, str, TokenType.MonthToken, i);
- str = InvariantInfo.GetAbbreviatedMonthName(i);
- InsertHash(temp, str, TokenType.MonthToken, i);
- }
-
- for (int i = 0; i < 7; i++)
- {
- // We have to call public methods here to work with inherited DTFI.
- String str = InvariantInfo.GetDayName((DayOfWeek)i);
- InsertHash(temp, str, TokenType.DayOfWeekToken, i);
-
- str = InvariantInfo.GetAbbreviatedDayName((DayOfWeek)i);
- InsertHash(temp, str, TokenType.DayOfWeekToken, i);
- }
-
- for (int i = 0; i < AbbreviatedEnglishEraNames.Length; i++)
- {
- // m_abbrevEnglishEraNames[0] contains the name for era 1, so the token value is i+1.
- InsertHash(temp, AbbreviatedEnglishEraNames[i], TokenType.EraToken, i + 1);
- }
-
- InsertHash(temp, LocalTimeMark, TokenType.SEP_LocalTimeMark, 0);
- InsertHash(temp, GMTName, TokenType.TimeZoneToken, 0);
- InsertHash(temp, ZuluName, TokenType.TimeZoneToken, 0);
-
- InsertHash(temp, invariantDateSeparator, TokenType.SEP_Date, 0);
- InsertHash(temp, invariantTimeSeparator, TokenType.SEP_Time, 0);
-
- _dtfiTokenHash = temp;
- }
- return (temp);
- }
-
- private void AddMonthNames(TokenHashValue[] temp, String monthPostfix)
- {
- for (int i = 1; i <= 13; i++)
- {
- String str;
- //str = internalGetMonthName(i, MonthNameStyles.Regular, false);
- // We have to call public methods here to work with inherited DTFI.
- // Insert the month name first, so that they are at the front of abbrevaited
- // month names.
- str = GetMonthName(i);
- if (str.Length > 0)
- {
- if (monthPostfix != null)
- {
- // Insert the month name with the postfix first, so it can be matched first.
- InsertHash(temp, str + monthPostfix, TokenType.MonthToken, i);
- }
- else
- {
- InsertHash(temp, str, TokenType.MonthToken, i);
- }
- }
- str = GetAbbreviatedMonthName(i);
- InsertHash(temp, str, TokenType.MonthToken, i);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Actions:
- // Try to parse the current word to see if it is a Hebrew number.
- // Tokens will be updated accordingly.
- // This is called by the Lexer of DateTime.Parse().
- //
- // Unlike most of the functions in this class, the return value indicates
- // whether or not it started to parse. The badFormat parameter indicates
- // if parsing began, but the format was bad.
- //
- ////////////////////////////////////////////////////////////////////////
-
- private static bool TryParseHebrewNumber(
-#if INSIDE_CLR
- ref __DTString str,
-#else
- ref FormatProvider.__DTString str,
-#endif
- out Boolean badFormat,
- out int number)
- {
- number = -1;
- badFormat = false;
-
- int i = str.Index;
- if (!HebrewNumber.IsDigit(str.Value[i]))
- {
- // If the current character is not a Hebrew digit, just return false.
- // There is no chance that we can parse a valid Hebrew number from here.
- return (false);
- }
- // The current character is a Hebrew digit. Try to parse this word as a Hebrew number.
- HebrewNumberParsingContext context = new HebrewNumberParsingContext(0);
- HebrewNumberParsingState state;
-
- do
- {
- state = HebrewNumber.ParseByChar(str.Value[i++], ref context);
- switch (state)
- {
- case HebrewNumberParsingState.InvalidHebrewNumber: // Not a valid Hebrew number.
- case HebrewNumberParsingState.NotHebrewDigit: // The current character is not a Hebrew digit character.
- // Break out so that we don't continue to try parse this as a Hebrew number.
- return (false);
- }
- } while (i < str.Value.Length && (state != HebrewNumberParsingState.FoundEndOfHebrewNumber));
-
- // When we are here, we are either at the end of the string, or we find a valid Hebrew number.
- Debug.Assert(state == HebrewNumberParsingState.ContinueParsing || state == HebrewNumberParsingState.FoundEndOfHebrewNumber,
- "Invalid returned state from HebrewNumber.ParseByChar()");
-
- if (state != HebrewNumberParsingState.FoundEndOfHebrewNumber)
- {
- // We reach end of the string but we can't find a terminal state in parsing Hebrew number.
- return (false);
- }
-
- // We have found a valid Hebrew number. Update the index.
- str.Advance(i - str.Index);
-
- // Get the final Hebrew number value from the HebrewNumberParsingContext.
- number = context.result;
-
- return (true);
- }
-
- private static bool IsHebrewChar(char ch)
- {
- return (ch >= '\x0590' && ch <= '\x05ff');
- }
-
- internal bool Tokenize(TokenType TokenMask, out TokenType tokenType, out int tokenValue,
-#if INSIDE_CLR
- ref __DTString str)
-#else
- ref FormatProvider.__DTString str)
-#endif
-
- {
- tokenType = TokenType.UnknownToken;
- tokenValue = 0;
-
- TokenHashValue value;
- Debug.Assert(str.Index < str.Value.Length, "DateTimeFormatInfo.Tokenize(): start < value.Length");
-
- char ch = str.m_current;
- bool isLetter = Char.IsLetter(ch);
- if (isLetter)
- {
- ch = this.Culture.TextInfo.ToLower(ch);
- if (IsHebrewChar(ch) && TokenMask == TokenType.RegularTokenMask)
- {
- bool badFormat;
- if (TryParseHebrewNumber(ref str, out badFormat, out tokenValue))
- {
- if (badFormat)
- {
- tokenType = TokenType.UnknownToken;
- return (false);
- }
- // This is a Hebrew number.
- // Do nothing here. TryParseHebrewNumber() will update token accordingly.
- tokenType = TokenType.HebrewNumber;
- return (true);
- }
- }
- }
-
-
- int hashcode = ch % TOKEN_HASH_SIZE;
- int hashProbe = 1 + ch % SECOND_PRIME;
- int remaining = str.len - str.Index;
- int i = 0;
-
- TokenHashValue[] hashTable = _dtfiTokenHash;
- if (hashTable == null)
- {
- hashTable = CreateTokenHashTable();
- }
- do
- {
- value = hashTable[hashcode];
- if (value == null)
- {
- // Not found.
- break;
- }
- // Check this value has the right category (regular token or separator token) that we are looking for.
- if (((int)value.tokenType & (int)TokenMask) > 0 && value.tokenString.Length <= remaining)
- {
- bool compareStrings = true;
- if (isLetter)
- {
- // If this token starts with a letter, make sure that we won't allow partial match. So you can't tokenize "MarchWed" separately.
- // Also an optimization to avoid string comparison
- int nextCharIndex = str.Index + value.tokenString.Length;
- if (nextCharIndex > str.len)
- {
- compareStrings = false;
- }
- else if (nextCharIndex < str.len)
- {
- // Check word boundary. The next character should NOT be a letter.
- char nextCh = str.Value[nextCharIndex];
- compareStrings = !(Char.IsLetter(nextCh));
- }
- }
- if (compareStrings && CompareStringIgnoreCaseOptimized(str.Value, str.Index, value.tokenString.Length, value.tokenString, 0, value.tokenString.Length))
- {
- tokenType = value.tokenType & TokenMask;
- tokenValue = value.tokenValue;
- str.Advance(value.tokenString.Length);
- return (true);
- }
- else if ((value.tokenType == TokenType.MonthToken && HasSpacesInMonthNames) ||
- (value.tokenType == TokenType.DayOfWeekToken && HasSpacesInDayNames))
- {
- // For month or day token, we will match the names which have spaces.
- int matchStrLen = 0;
- if (str.MatchSpecifiedWords(value.tokenString, true, ref matchStrLen))
- {
- tokenType = value.tokenType & TokenMask;
- tokenValue = value.tokenValue;
- str.Advance(matchStrLen);
- return (true);
- }
- }
- }
- i++;
- hashcode += hashProbe;
- if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
- } while (i < TOKEN_HASH_SIZE);
-
- return (false);
- }
-
- private void InsertAtCurrentHashNode(TokenHashValue[] hashTable, String str, char ch, TokenType tokenType, int tokenValue, int pos, int hashcode, int hashProbe)
- {
- // Remember the current slot.
- TokenHashValue previousNode = hashTable[hashcode];
-
- //// Console.WriteLine(" Insert Key: {0} in {1}", str, slotToInsert);
- // Insert the new node into the current slot.
- hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue); ;
-
- while (++pos < TOKEN_HASH_SIZE)
- {
- hashcode += hashProbe;
- if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
- // Remember this slot
- TokenHashValue temp = hashTable[hashcode];
-
- if (temp != null && this.Culture.TextInfo.ToLower(temp.tokenString[0]) != ch)
- {
- continue;
- }
- // Put the previous slot into this slot.
- hashTable[hashcode] = previousNode;
- //// Console.WriteLine(" Move {0} to slot {1}", previousNode.tokenString, hashcode);
- if (temp == null)
- {
- // Done
- return;
- }
- previousNode = temp;
- };
- Debug.Assert(false, "The hashtable is full. This should not happen.");
- }
-
- private void InsertHash(TokenHashValue[] hashTable, String str, TokenType tokenType, int tokenValue)
- {
- // The month of the 13th month is allowed to be null, so make sure that we ignore null value here.
- if (str == null || str.Length == 0)
- {
- return;
- }
- TokenHashValue value;
- int i = 0;
- // If there is whitespace characters in the beginning and end of the string, trim them since whitespaces are skipped by
- // DateTime.Parse().
- if (Char.IsWhiteSpace(str[0]) || Char.IsWhiteSpace(str[str.Length - 1]))
- {
- str = str.Trim(null); // Trim white space characters.
- // Could have space for separators
- if (str.Length == 0)
- return;
- }
- char ch = this.Culture.TextInfo.ToLower(str[0]);
- int hashcode = ch % TOKEN_HASH_SIZE;
- int hashProbe = 1 + ch % SECOND_PRIME;
- do
- {
- value = hashTable[hashcode];
- if (value == null)
- {
- //// Console.WriteLine(" Put Key: {0} in {1}", str, hashcode);
- hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue);
- return;
- }
- else
- {
- // Collision happens. Find another slot.
- if (str.Length >= value.tokenString.Length)
- {
- // If there are two tokens with the same prefix, we have to make sure that the longer token should be at the front of
- // the shorter ones.
- if (this.CompareStringIgnoreCaseOptimized(str, 0, value.tokenString.Length, value.tokenString, 0, value.tokenString.Length))
- {
- if (str.Length > value.tokenString.Length)
- {
- // The str to be inserted has the same prefix as the current token, and str is longer.
- // Insert str into this node, and shift every node behind it.
- InsertAtCurrentHashNode(hashTable, str, ch, tokenType, tokenValue, i, hashcode, hashProbe);
- return;
- }
- else
- {
- // Same token. If they have different types (regular token vs separator token). Add them.
- // If we have the same regular token or separator token in the hash already, do NOT update the hash.
- // Therefore, the order of inserting token is significant here regarding what tokenType will be kept in the hash.
-
-
- //
- // Check the current value of RegularToken (stored in the lower 8-bit of tokenType) , and insert the tokenType into the hash ONLY when we don't have a RegularToken yet.
- // Also check the current value of SeparatorToken (stored in the upper 8-bit of token), and insert the tokenType into the hash ONLY when we don't have the SeparatorToken yet.
- //
-
- int nTokenType = (int)tokenType;
- int nCurrentTokenTypeInHash = (int)value.tokenType;
-
- //
- // The folowing is the fix for the issue of throwing FormatException when "mar" is passed in string of the short date format dd/MMM/yyyy for es-MX
- //
-
- if (((nCurrentTokenTypeInHash & (int)TokenType.RegularTokenMask) == 0) && ((nTokenType & (int)TokenType.RegularTokenMask) != 0) ||
- ((nCurrentTokenTypeInHash & (int)TokenType.SeparatorTokenMask) == 0) && ((nTokenType & (int)TokenType.SeparatorTokenMask) != 0))
- {
- value.tokenType |= tokenType;
- if (tokenValue != 0)
- {
- value.tokenValue = tokenValue;
- }
- }
- // The token to be inserted is already in the table. Skip it.
- return;
- }
- }
- }
- }
- //// Console.WriteLine(" COLLISION. Old Key: {0}, New Key: {1}", hashTable[hashcode].tokenString, str);
- i++;
- hashcode += hashProbe;
- if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
- } while (i < TOKEN_HASH_SIZE);
- Debug.Assert(false, "The hashtable is full. This should not happen.");
- }
-
- private bool CompareStringIgnoreCaseOptimized(string string1, int offset1, int length1, string string2, int offset2, int length2)
- {
- // Optimize for one character cases which are common due to date and time separators (/ and :)
- if (length1 == 1 && length2 == 1 && string1[offset1] == string2[offset2])
- {
- return true;
- }
-
- return (this.Culture.CompareInfo.Compare(string1, offset1, length1, string2, offset2, length2, CompareOptions.IgnoreCase) == 0);
- }
-
- // class DateTimeFormatInfo
-
- internal class TokenHashValue
- {
- internal String tokenString;
- internal TokenType tokenType;
- internal int tokenValue;
-
- internal TokenHashValue(String tokenString, TokenType tokenType, int tokenValue)
- {
- this.tokenString = tokenString;
- this.tokenType = tokenType;
- this.tokenValue = tokenValue;
- }
- }
- }
-
-#if !INSIDE_CLR
- //
- // The type of token that will be returned by DateTimeFormatInfo.Tokenize().
- //
- internal enum TokenType
- {
- // The valid token should start from 1.
-
- // Regular tokens. The range is from 0x00 ~ 0xff.
- NumberToken = 1, // The number. E.g. "12"
- YearNumberToken = 2, // The number which is considered as year number, which has 3 or more digits. E.g. "2003"
- Am = 3, // AM timemark. E.g. "AM"
- Pm = 4, // PM timemark. E.g. "PM"
- MonthToken = 5, // A word (or words) that represents a month name. E.g. "March"
- EndOfString = 6, // End of string
- DayOfWeekToken = 7, // A word (or words) that represents a day of week name. E.g. "Monday" or "Mon"
- TimeZoneToken = 8, // A word that represents a timezone name. E.g. "GMT"
- EraToken = 9, // A word that represents a era name. E.g. "A.D."
- DateWordToken = 10, // A word that can appear in a DateTime string, but serves no parsing semantics. E.g. "de" in Spanish culture.
- UnknownToken = 11, // An unknown word, which signals an error in parsing.
- HebrewNumber = 12, // A number that is composed of Hebrew text. Hebrew calendar uses Hebrew digits for year values, month values, and day values.
- JapaneseEraToken = 13, // Era name for JapaneseCalendar
- TEraToken = 14, // Era name for TaiwanCalendar
- IgnorableSymbol = 15, // A separator like "," that is equivalent to whitespace
-
-
- // Separator tokens.
- SEP_Unk = 0x100, // Unknown separator.
- SEP_End = 0x200, // The end of the parsing string.
- SEP_Space = 0x300, // Whitespace (including comma).
- SEP_Am = 0x400, // AM timemark. E.g. "AM"
- SEP_Pm = 0x500, // PM timemark. E.g. "PM"
- SEP_Date = 0x600, // date separator. E.g. "/"
- SEP_Time = 0x700, // time separator. E.g. ":"
- SEP_YearSuff = 0x800, // Chinese/Japanese/Korean year suffix.
- SEP_MonthSuff = 0x900, // Chinese/Japanese/Korean month suffix.
- SEP_DaySuff = 0xa00, // Chinese/Japanese/Korean day suffix.
- SEP_HourSuff = 0xb00, // Chinese/Japanese/Korean hour suffix.
- SEP_MinuteSuff = 0xc00, // Chinese/Japanese/Korean minute suffix.
- SEP_SecondSuff = 0xd00, // Chinese/Japanese/Korean second suffix.
- SEP_LocalTimeMark = 0xe00, // 'T', used in ISO 8601 format.
- SEP_DateOrOffset = 0xf00, // '-' which could be a date separator or start of a time zone offset
-
- RegularTokenMask = 0x00ff,
- SeparatorTokenMask = 0xff00,
- }
-#endif
-
-}
diff --git a/src/mscorlib/corefx/System/Globalization/DateTimeFormatInfoScanner.cs b/src/mscorlib/corefx/System/Globalization/DateTimeFormatInfoScanner.cs
deleted file mode 100644
index 9cbc19f385..0000000000
--- a/src/mscorlib/corefx/System/Globalization/DateTimeFormatInfoScanner.cs
+++ /dev/null
@@ -1,742 +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.
-
-////////////////////////////////////////////////////////////////////////////
-//
-// DateTimeFormatInfoScanner
-//
-// Scan a specified DateTimeFormatInfo to search for data used in DateTime.Parse()
-//
-// The data includes:
-//
-// DateWords: such as "de" used in es-ES (Spanish) LongDatePattern.
-// Postfix: such as "ta" used in fi-FI after the month name.
-//
-// This class is shared among mscorlib.dll and sysglobl.dll.
-// Use conditional CULTURE_AND_REGIONINFO_BUILDER_ONLY to differentiate between
-// methods for mscorlib.dll and sysglobl.dll.
-//
-////////////////////////////////////////////////////////////////////////////
-
-using System;
-using System.Globalization;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text;
-
-namespace System.Globalization
-{
-
-#if INSIDE_CLR
- using StringStringDictionary = Dictionary<string, string>;
- using StringList = List<string>;
-#else
- using StringStringDictionary = LowLevelDictionary<string, string>;
- using StringList = LowLevelList<string>;
-#endif
-
- //
- // from LocaleEx.txt header
- //
- //; IFORMATFLAGS
- //; Parsing/formatting flags.
- internal enum FORMATFLAGS
- {
- None = 0x00000000,
- UseGenitiveMonth = 0x00000001,
- UseLeapYearMonth = 0x00000002,
- UseSpacesInMonthNames = 0x00000004,
- UseHebrewParsing = 0x00000008,
- UseSpacesInDayNames = 0x00000010, // Has spaces or non-breaking space in the day names.
- UseDigitPrefixInTokens = 0x00000020, // Has token starting with numbers.
- }
-
- internal enum CalendarId : ushort
- {
- UNINITIALIZED_VALUE = 0,
- GREGORIAN = 1, // Gregorian (localized) calendar
- GREGORIAN_US = 2, // Gregorian (U.S.) calendar
- JAPAN = 3, // Japanese Emperor Era calendar
- /* SSS_WARNINGS_OFF */
- TAIWAN = 4, // Taiwan Era calendar /* SSS_WARNINGS_ON */
- KOREA = 5, // Korean Tangun Era calendar
- HIJRI = 6, // Hijri (Arabic Lunar) calendar
- THAI = 7, // Thai calendar
- HEBREW = 8, // Hebrew (Lunar) calendar
- GREGORIAN_ME_FRENCH = 9, // Gregorian Middle East French calendar
- GREGORIAN_ARABIC = 10, // Gregorian Arabic calendar
- GREGORIAN_XLIT_ENGLISH = 11, // Gregorian Transliterated English calendar
- GREGORIAN_XLIT_FRENCH = 12,
- // Note that all calendars after this point are MANAGED ONLY for now.
- JULIAN = 13,
- JAPANESELUNISOLAR = 14,
- CHINESELUNISOLAR = 15,
- SAKA = 16, // reserved to match Office but not implemented in our code
- LUNAR_ETO_CHN = 17, // reserved to match Office but not implemented in our code
- LUNAR_ETO_KOR = 18, // reserved to match Office but not implemented in our code
- LUNAR_ETO_ROKUYOU = 19, // reserved to match Office but not implemented in our code
- KOREANLUNISOLAR = 20,
- TAIWANLUNISOLAR = 21,
- PERSIAN = 22,
- UMALQURA = 23,
- LAST_CALENDAR = 23 // Last calendar ID
- }
-
- internal class DateTimeFormatInfoScanner
- {
- // Special prefix-like flag char in DateWord array.
-
- // Use char in PUA area since we won't be using them in real data.
- // The char used to tell a read date word or a month postfix. A month postfix
- // is "ta" in the long date pattern like "d. MMMM'ta 'yyyy" for fi-FI.
- // In this case, it will be stored as "\xfffeta" in the date word array.
- internal const char MonthPostfixChar = '\xe000';
-
- // Add ignorable symbol in a DateWord array.
-
- // hu-HU has:
- // shrot date pattern: yyyy. MM. dd.;yyyy-MM-dd;yy-MM-dd
- // long date pattern: yyyy. MMMM d.
- // Here, "." is the date separator (derived from short date pattern). However,
- // "." also appear at the end of long date pattern. In this case, we just
- // "." as ignorable symbol so that the DateTime.Parse() state machine will not
- // treat the additional date separator at the end of y,m,d pattern as an error
- // condition.
- internal const char IgnorableSymbolChar = '\xe001';
-
- // Known CJK suffix
- internal const String CJKYearSuff = "\u5e74";
- internal const String CJKMonthSuff = "\u6708";
- internal const String CJKDaySuff = "\u65e5";
-
- internal const String KoreanYearSuff = "\ub144";
- internal const String KoreanMonthSuff = "\uc6d4";
- internal const String KoreanDaySuff = "\uc77c";
-
- internal const String KoreanHourSuff = "\uc2dc";
- internal const String KoreanMinuteSuff = "\ubd84";
- internal const String KoreanSecondSuff = "\ucd08";
-
- internal const String CJKHourSuff = "\u6642";
- internal const String ChineseHourSuff = "\u65f6";
-
- internal const String CJKMinuteSuff = "\u5206";
- internal const String CJKSecondSuff = "\u79d2";
-
- // The collection fo date words & postfix.
- internal StringList m_dateWords = new StringList();
- // Hashtable for the known words.
- private static volatile StringStringDictionary s_knownWords;
-
- static StringStringDictionary KnownWords
- {
- get
- {
- if (s_knownWords == null)
- {
- StringStringDictionary temp = new StringStringDictionary();
- // Add known words into the hash table.
-
- // Skip these special symbols.
- temp.Add("/", String.Empty);
- temp.Add("-", String.Empty);
- temp.Add(".", String.Empty);
- // Skip known CJK suffixes.
- temp.Add(CJKYearSuff, String.Empty);
- temp.Add(CJKMonthSuff, String.Empty);
- temp.Add(CJKDaySuff, String.Empty);
- temp.Add(KoreanYearSuff, String.Empty);
- temp.Add(KoreanMonthSuff, String.Empty);
- temp.Add(KoreanDaySuff, String.Empty);
- temp.Add(KoreanHourSuff, String.Empty);
- temp.Add(KoreanMinuteSuff, String.Empty);
- temp.Add(KoreanSecondSuff, String.Empty);
- temp.Add(CJKHourSuff, String.Empty);
- temp.Add(ChineseHourSuff, String.Empty);
- temp.Add(CJKMinuteSuff, String.Empty);
- temp.Add(CJKSecondSuff, String.Empty);
-
- s_knownWords = temp;
- }
- return (s_knownWords);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Parameters:
- // pattern: The pattern to be scanned.
- // currentIndex: the current index to start the scan.
- //
- // Returns:
- // Return the index with the first character that is a letter, which will
- // be the start of a date word.
- // Note that the index can be pattern.Length if we reach the end of the string.
- //
- ////////////////////////////////////////////////////////////////////////////
- internal static int SkipWhiteSpacesAndNonLetter(String pattern, int currentIndex)
- {
- while (currentIndex < pattern.Length)
- {
- char ch = pattern[currentIndex];
- if (ch == '\\')
- {
- // Escaped character. Look ahead one character.
- currentIndex++;
- if (currentIndex < pattern.Length)
- {
- ch = pattern[currentIndex];
- if (ch == '\'')
- {
- // Skip the leading single quote. We will
- // stop at the first letter.
- continue;
- }
- // Fall thru to check if this is a letter.
- }
- else
- {
- // End of string
- break;
- }
- }
- if (Char.IsLetter(ch) || ch == '\'' || ch == '.')
- {
- break;
- }
- // Skip the current char since it is not a letter.
- currentIndex++;
- }
- return (currentIndex);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // A helper to add the found date word or month postfix into ArrayList for date words.
- //
- // Parameters:
- // formatPostfix: What kind of postfix this is.
- // Possible values:
- // null: This is a regular date word
- // "MMMM": month postfix
- // word: The date word or postfix to be added.
- //
- ////////////////////////////////////////////////////////////////////////////
- internal void AddDateWordOrPostfix(String formatPostfix, String str)
- {
- if (str.Length > 0)
- {
- // Some cultures use . like an abbreviation
- if (str.Equals("."))
- {
- AddIgnorableSymbols(".");
- return;
- }
- String words;
- if (KnownWords.TryGetValue(str, out words) == false)
- {
- if (m_dateWords == null)
- {
- m_dateWords = new StringList();
- }
- if (formatPostfix == "MMMM")
- {
- // Add the word into the ArrayList as "\xfffe" + real month postfix.
- String temp = MonthPostfixChar + str;
- if (!m_dateWords.Contains(temp))
- {
- m_dateWords.Add(temp);
- }
- }
- else
- {
- if (!m_dateWords.Contains(str))
- {
- m_dateWords.Add(str);
- }
- if (str[str.Length - 1] == '.')
- {
- // Old version ignore the trialing dot in the date words. Support this as well.
- String strWithoutDot = str.Substring(0, str.Length - 1);
- if (!m_dateWords.Contains(strWithoutDot))
- {
- m_dateWords.Add(strWithoutDot);
- }
- }
- }
- }
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Scan the pattern from the specified index and add the date word/postfix
- // when appropriate.
- //
- // Parameters:
- // pattern: The pattern to be scanned.
- // index: The starting index to be scanned.
- // formatPostfix: The kind of postfix to be scanned.
- // Possible values:
- // null: This is a regular date word
- // "MMMM": month postfix
- //
- //
- ////////////////////////////////////////////////////////////////////////////
- internal int AddDateWords(String pattern, int index, String formatPostfix)
- {
- // Skip any whitespaces so we will start from a letter.
- int newIndex = SkipWhiteSpacesAndNonLetter(pattern, index);
- if (newIndex != index && formatPostfix != null)
- {
- // There are whitespaces. This will not be a postfix.
- formatPostfix = null;
- }
- index = newIndex;
-
- // This is the first char added into dateWord.
- // Skip all non-letter character. We will add the first letter into DateWord.
- StringBuilder dateWord = new StringBuilder();
- // We assume that date words should start with a letter.
- // Skip anything until we see a letter.
-
- while (index < pattern.Length)
- {
- char ch = pattern[index];
- if (ch == '\'')
- {
- // We have seen the end of quote. Add the word if we do not see it before,
- // and break the while loop.
- AddDateWordOrPostfix(formatPostfix, dateWord.ToString());
- index++;
- break;
- }
- else if (ch == '\\')
- {
- //
- // Escaped character. Look ahead one character
- //
-
- // Skip escaped backslash.
- index++;
- if (index < pattern.Length)
- {
- dateWord.Append(pattern[index]);
- index++;
- }
- }
- else if (Char.IsWhiteSpace(ch))
- {
- // Found a whitespace. We have to add the current date word/postfix.
- AddDateWordOrPostfix(formatPostfix, dateWord.ToString());
- if (formatPostfix != null)
- {
- // Done with postfix. The rest will be regular date word.
- formatPostfix = null;
- }
- // Reset the dateWord.
- dateWord.Length = 0;
- index++;
- }
- else
- {
- dateWord.Append(ch);
- index++;
- }
- }
- return (index);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // A simple helper to find the repeat count for a specified char.
- //
- ////////////////////////////////////////////////////////////////////////////
- internal static int ScanRepeatChar(String pattern, char ch, int index, out int count)
- {
- count = 1;
- while (++index < pattern.Length && pattern[index] == ch)
- {
- count++;
- }
- // Return the updated position.
- return (index);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Add the text that is a date separator but is treated like ignroable symbol.
- // E.g.
- // hu-HU has:
- // shrot date pattern: yyyy. MM. dd.;yyyy-MM-dd;yy-MM-dd
- // long date pattern: yyyy. MMMM d.
- // Here, "." is the date separator (derived from short date pattern). However,
- // "." also appear at the end of long date pattern. In this case, we just
- // "." as ignorable symbol so that the DateTime.Parse() state machine will not
- // treat the additional date separator at the end of y,m,d pattern as an error
- // condition.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal void AddIgnorableSymbols(String text)
- {
- if (m_dateWords == null)
- {
- // Create the date word array.
- m_dateWords = new StringList();
- }
- // Add the ignorable symbol into the ArrayList.
- String temp = IgnorableSymbolChar + text;
- if (!m_dateWords.Contains(temp))
- {
- m_dateWords.Add(temp);
- }
- }
-
-
- //
- // Flag used to trace the date patterns (yy/yyyyy/M/MM/MMM/MMM/d/dd) that we have seen.
- //
- private enum FoundDatePattern
- {
- None = 0x0000,
- FoundYearPatternFlag = 0x0001,
- FoundMonthPatternFlag = 0x0002,
- FoundDayPatternFlag = 0x0004,
- FoundYMDPatternFlag = 0x0007, // FoundYearPatternFlag | FoundMonthPatternFlag | FoundDayPatternFlag;
- }
-
- // Check if we have found all of the year/month/day pattern.
- private FoundDatePattern _ymdFlags = FoundDatePattern.None;
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Given a date format pattern, scan for date word or postfix.
- //
- // A date word should be always put in a single quoted string. And it will
- // start from a letter, so whitespace and symbols will be ignored before
- // the first letter.
- //
- // Examples of date word:
- // 'de' in es-SP: dddd, dd' de 'MMMM' de 'yyyy
- // "\x0443." in bg-BG: dd.M.yyyy '\x0433.'
- //
- // Example of postfix:
- // month postfix:
- // "ta" in fi-FI: d. MMMM'ta 'yyyy
- // Currently, only month postfix is supported.
- //
- // Usage:
- // Always call this with Framework-style pattern, instead of Windows style pattern.
- // Windows style pattern uses '' for single quote, while .NET uses \'
- //
- ////////////////////////////////////////////////////////////////////////////
- internal void ScanDateWord(String pattern)
- {
- // Check if we have found all of the year/month/day pattern.
- _ymdFlags = FoundDatePattern.None;
-
- int i = 0;
- while (i < pattern.Length)
- {
- char ch = pattern[i];
- int chCount;
-
- switch (ch)
- {
- case '\'':
- // Find a beginning quote. Search until the end quote.
- i = AddDateWords(pattern, i + 1, null);
- break;
- case 'M':
- i = ScanRepeatChar(pattern, 'M', i, out chCount);
- if (chCount >= 4)
- {
- if (i < pattern.Length && pattern[i] == '\'')
- {
- i = AddDateWords(pattern, i + 1, "MMMM");
- }
- }
- _ymdFlags |= FoundDatePattern.FoundMonthPatternFlag;
- break;
- case 'y':
- i = ScanRepeatChar(pattern, 'y', i, out chCount);
- _ymdFlags |= FoundDatePattern.FoundYearPatternFlag;
- break;
- case 'd':
- i = ScanRepeatChar(pattern, 'd', i, out chCount);
- if (chCount <= 2)
- {
- // Only count "d" & "dd".
- // ddd, dddd are day names. Do not count them.
- _ymdFlags |= FoundDatePattern.FoundDayPatternFlag;
- }
- break;
- case '\\':
- // Found a escaped char not in a quoted string. Skip the current backslash
- // and its next character.
- i += 2;
- break;
- case '.':
- if (_ymdFlags == FoundDatePattern.FoundYMDPatternFlag)
- {
- // If we find a dot immediately after the we have seen all of the y, m, d pattern.
- // treat it as a ignroable symbol. Check for comments in AddIgnorableSymbols for
- // more details.
- AddIgnorableSymbols(".");
- _ymdFlags = FoundDatePattern.None;
- }
- i++;
- break;
- default:
- if (_ymdFlags == FoundDatePattern.FoundYMDPatternFlag && !Char.IsWhiteSpace(ch))
- {
- // We are not seeing "." after YMD. Clear the flag.
- _ymdFlags = FoundDatePattern.None;
- }
- // We are not in quote. Skip the current character.
- i++;
- break;
- }
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Given a DTFI, get all of the date words from date patterns and time patterns.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal String[] GetDateWordsOfDTFI(DateTimeFormatInfo dtfi)
- {
- // Enumarate all LongDatePatterns, and get the DateWords and scan for month postfix.
- String[] datePatterns = dtfi.GetAllDateTimePatterns('D');
- int i;
-
- // Scan the long date patterns
- for (i = 0; i < datePatterns.Length; i++)
- {
- ScanDateWord(datePatterns[i]);
- }
-
- // Scan the short date patterns
- datePatterns = dtfi.GetAllDateTimePatterns('d');
- for (i = 0; i < datePatterns.Length; i++)
- {
- ScanDateWord(datePatterns[i]);
- }
- // Scan the YearMonth patterns.
- datePatterns = dtfi.GetAllDateTimePatterns('y');
- for (i = 0; i < datePatterns.Length; i++)
- {
- ScanDateWord(datePatterns[i]);
- }
-
- // Scan the month/day pattern
- ScanDateWord(dtfi.MonthDayPattern);
-
- // Scan the long time patterns.
- datePatterns = dtfi.GetAllDateTimePatterns('T');
- for (i = 0; i < datePatterns.Length; i++)
- {
- ScanDateWord(datePatterns[i]);
- }
-
- // Scan the short time patterns.
- datePatterns = dtfi.GetAllDateTimePatterns('t');
- for (i = 0; i < datePatterns.Length; i++)
- {
- ScanDateWord(datePatterns[i]);
- }
-
- String[] result = null;
- if (m_dateWords != null && m_dateWords.Count > 0)
- {
- result = new String[m_dateWords.Count];
- for (i = 0; i < m_dateWords.Count; i++)
- {
- result[i] = m_dateWords[i];
- }
- }
- return (result);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Scan the month names to see if genitive month names are used, and return
- // the format flag.
- //
- ////////////////////////////////////////////////////////////////////////////
- internal static FORMATFLAGS GetFormatFlagGenitiveMonth(String[] monthNames, String[] genitveMonthNames, String[] abbrevMonthNames, String[] genetiveAbbrevMonthNames)
- {
- // If we have different names in regular and genitive month names, use genitive month flag.
- return ((!EqualStringArrays(monthNames, genitveMonthNames) || !EqualStringArrays(abbrevMonthNames, genetiveAbbrevMonthNames))
- ? FORMATFLAGS.UseGenitiveMonth : 0);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Scan the month names to see if spaces are used or start with a digit, and return the format flag
- //
- ////////////////////////////////////////////////////////////////////////////
- internal static FORMATFLAGS GetFormatFlagUseSpaceInMonthNames(String[] monthNames, String[] genitveMonthNames, String[] abbrevMonthNames, String[] genetiveAbbrevMonthNames)
- {
- FORMATFLAGS formatFlags = 0;
- formatFlags |= (ArrayElementsBeginWithDigit(monthNames) ||
- ArrayElementsBeginWithDigit(genitveMonthNames) ||
- ArrayElementsBeginWithDigit(abbrevMonthNames) ||
- ArrayElementsBeginWithDigit(genetiveAbbrevMonthNames)
- ? FORMATFLAGS.UseDigitPrefixInTokens : 0);
-
- formatFlags |= (ArrayElementsHaveSpace(monthNames) ||
- ArrayElementsHaveSpace(genitveMonthNames) ||
- ArrayElementsHaveSpace(abbrevMonthNames) ||
- ArrayElementsHaveSpace(genetiveAbbrevMonthNames)
- ? FORMATFLAGS.UseSpacesInMonthNames : 0);
- return (formatFlags);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Scan the day names and set the correct format flag.
- //
- ////////////////////////////////////////////////////////////////////////////
- internal static FORMATFLAGS GetFormatFlagUseSpaceInDayNames(String[] dayNames, String[] abbrevDayNames)
- {
- return ((ArrayElementsHaveSpace(dayNames) ||
- ArrayElementsHaveSpace(abbrevDayNames))
- ? FORMATFLAGS.UseSpacesInDayNames : 0);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Check the calendar to see if it is HebrewCalendar and set the Hebrew format flag if necessary.
- //
- ////////////////////////////////////////////////////////////////////////////
- internal static FORMATFLAGS GetFormatFlagUseHebrewCalendar(int calID)
- {
- return (calID == (int)CalendarId.HEBREW ?
- FORMATFLAGS.UseHebrewParsing | FORMATFLAGS.UseLeapYearMonth : 0);
- }
-
-
- //-----------------------------------------------------------------------------
- // EqualStringArrays
- // compares two string arrays and return true if all elements of the first
- // array equals to all elmentsof the second array.
- // otherwise it returns false.
- //-----------------------------------------------------------------------------
-
- private static bool EqualStringArrays(string[] array1, string[] array2)
- {
- // Shortcut if they're the same array
- if (array1 == array2)
- {
- return true;
- }
-
- // This is effectively impossible
- if (array1.Length != array2.Length)
- {
- return false;
- }
-
- // Check each string
- for (int i = 0; i < array1.Length; i++)
- {
- if (!array1[i].Equals(array2[i]))
- {
- return false;
- }
- }
-
- return true;
- }
-
- //-----------------------------------------------------------------------------
- // ArrayElementsHaveSpace
- // It checks all input array elements if any of them has space character
- // returns true if found space character in one of the array elements.
- // otherwise returns false.
- //-----------------------------------------------------------------------------
-
- private static bool ArrayElementsHaveSpace(string[] array)
- {
- for (int i = 0; i < array.Length; i++)
- {
- // it is faster to check for space character manually instead of calling IndexOf
- // so we don't have to go to native code side.
- for (int j = 0; j < array[i].Length; j++)
- {
- if (Char.IsWhiteSpace(array[i][j]))
- {
- return true;
- }
- }
- }
-
- return false;
- }
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Check if any element of the array start with a digit.
- //
- ////////////////////////////////////////////////////////////////////////////
- private static bool ArrayElementsBeginWithDigit(string[] array)
- {
- for (int i = 0; i < array.Length; i++)
- {
- // it is faster to check for space character manually instead of calling IndexOf
- // so we don't have to go to native code side.
- if (array[i].Length > 0 &&
- array[i][0] >= '0' && array[i][0] <= '9')
- {
- int index = 1;
- while (index < array[i].Length && array[i][index] >= '0' && array[i][index] <= '9')
- {
- // Skip other digits.
- index++;
- }
- if (index == array[i].Length)
- {
- return (false);
- }
-
- if (index == array[i].Length - 1)
- {
- // Skip known CJK month suffix.
- // CJK uses month name like "1\x6708", since \x6708 is a known month suffix,
- // we don't need the UseDigitPrefixInTokens since it is slower.
- switch (array[i][index])
- {
- case '\x6708': // CJKMonthSuff
- case '\xc6d4': // KoreanMonthSuff
- return (false);
- }
- }
-
- if (index == array[i].Length - 4)
- {
- // Skip known CJK month suffix.
- // Starting with Windows 8, the CJK months for some cultures looks like: "1' \x6708'"
- // instead of just "1\x6708"
- if (array[i][index] == '\'' && array[i][index + 1] == ' ' &&
- array[i][index + 2] == '\x6708' && array[i][index + 3] == '\'')
- {
- return (false);
- }
- }
- return (true);
- }
- }
-
- return false;
- }
- }
-}
-
diff --git a/src/mscorlib/corefx/System/Globalization/DayLightTime.cs b/src/mscorlib/corefx/System/Globalization/DayLightTime.cs
deleted file mode 100644
index 6ec9d6a43e..0000000000
--- a/src/mscorlib/corefx/System/Globalization/DayLightTime.cs
+++ /dev/null
@@ -1,53 +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;
-
-namespace System.Globalization
-{
- // This class represents a starting/ending time for a period of daylight saving time.
-
- [Serializable]
- public class DaylightTime
- {
- private readonly DateTime _start;
- private readonly DateTime _end;
- private readonly TimeSpan _delta;
-
- private DaylightTime()
- {
- }
-
- public DaylightTime(DateTime start, DateTime end, TimeSpan delta)
- {
- _start = start;
- _end = end;
- _delta = delta;
- }
-
- // The start date of a daylight saving period.
- public DateTime Start => _start;
-
- // The end date of a daylight saving period.
- public DateTime End => _end;
-
- // Delta to stardard offset in ticks.
- public TimeSpan Delta => _delta;
- }
-
- // Value type version of DaylightTime
- internal struct DaylightTimeStruct
- {
- public DaylightTimeStruct(DateTime start, DateTime end, TimeSpan delta)
- {
- Start = start;
- End = end;
- Delta = delta;
- }
-
- public readonly DateTime Start;
- public readonly DateTime End;
- public readonly TimeSpan Delta;
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/DigitShapes.cs b/src/mscorlib/corefx/System/Globalization/DigitShapes.cs
deleted file mode 100644
index 0e4dcc87c3..0000000000
--- a/src/mscorlib/corefx/System/Globalization/DigitShapes.cs
+++ /dev/null
@@ -1,18 +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.
-
-//
-// The enumeration constants used in NumberFormatInfo.DigitSubstitution.
-//
-
-namespace System.Globalization
-{
- [Serializable]
- public enum DigitShapes : int
- {
- Context = 0x0000, // The shape depends on the previous text in the same output.
- None = 0x0001, // Gives full Unicode compatibility.
- NativeNational = 0x0002 // National shapes
- }
-} \ No newline at end of file
diff --git a/src/mscorlib/corefx/System/Globalization/EastAsianLunisolarCalendar.cs b/src/mscorlib/corefx/System/Globalization/EastAsianLunisolarCalendar.cs
deleted file mode 100644
index f82fad8e5b..0000000000
--- a/src/mscorlib/corefx/System/Globalization/EastAsianLunisolarCalendar.cs
+++ /dev/null
@@ -1,717 +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.Diagnostics.Contracts;
-
-namespace System.Globalization
-{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about EastAsianLunisolarCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
-
- [Serializable]
- public abstract class EastAsianLunisolarCalendar : Calendar
- {
- internal const int LeapMonth = 0;
- internal const int Jan1Month = 1;
- internal const int Jan1Date = 2;
- internal const int nDaysPerMonth = 3;
-
- // # of days so far in the solar year
- internal static readonly int[] DaysToMonth365 =
- {
- 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
- };
-
- internal static readonly int[] DaysToMonth366 =
- {
- 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335
- };
-
- internal const int DatePartYear = 0;
- internal const int DatePartDayOfYear = 1;
- internal const int DatePartMonth = 2;
- internal const int DatePartDay = 3;
-
- public override CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.LunisolarCalendar;
- }
- }
-
- // Return the year number in the 60-year cycle.
- //
-
- public virtual int GetSexagenaryYear(DateTime time)
- {
- CheckTicksRange(time.Ticks);
-
- int year = 0, month = 0, day = 0;
- TimeToLunar(time, ref year, ref month, ref day);
-
- return ((year - 4) % 60) + 1;
- }
-
- // Return the celestial year from the 60-year cycle.
- // The returned value is from 1 ~ 10.
- //
-
- public int GetCelestialStem(int sexagenaryYear)
- {
- if ((sexagenaryYear < 1) || (sexagenaryYear > 60))
- {
- throw new ArgumentOutOfRangeException(
- nameof(sexagenaryYear),
- SR.Format(SR.ArgumentOutOfRange_Range, 1, 60));
- }
- Contract.EndContractBlock();
-
- return ((sexagenaryYear - 1) % 10) + 1;
- }
-
- // Return the Terrestial Branch from the the 60-year cycle.
- // The returned value is from 1 ~ 12.
- //
-
- public int GetTerrestrialBranch(int sexagenaryYear)
- {
- if ((sexagenaryYear < 1) || (sexagenaryYear > 60))
- {
- throw new ArgumentOutOfRangeException(
- nameof(sexagenaryYear),
- SR.Format(SR.ArgumentOutOfRange_Range, 1, 60));
- }
- Contract.EndContractBlock();
-
- return ((sexagenaryYear - 1) % 12) + 1;
- }
-
- internal abstract int GetYearInfo(int LunarYear, int Index);
- internal abstract int GetYear(int year, DateTime time);
- internal abstract int GetGregorianYear(int year, int era);
-
- internal abstract int MinCalendarYear { get; }
- internal abstract int MaxCalendarYear { get; }
- internal abstract EraInfo[] CalEraInfo { get; }
- internal abstract DateTime MinDate { get; }
- internal abstract DateTime MaxDate { get; }
-
- internal const int MaxCalendarMonth = 13;
- internal const int MaxCalendarDay = 30;
-
- internal int MinEraCalendarYear(int era)
- {
- EraInfo[] mEraInfo = CalEraInfo;
- //ChineseLunisolarCalendar does not has m_EraInfo it is going to retuen null
- if (mEraInfo == null)
- {
- return MinCalendarYear;
- }
-
- if (era == Calendar.CurrentEra)
- {
- era = CurrentEraValue;
- }
- //era has to be in the supported range otherwise we will throw exception in CheckEraRange()
- if (era == GetEra(MinDate))
- {
- return (GetYear(MinCalendarYear, MinDate));
- }
-
- for (int i = 0; i < mEraInfo.Length; i++)
- {
- if (era == mEraInfo[i].era)
- {
- return (mEraInfo[i].minEraYear);
- }
- }
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
-
- internal int MaxEraCalendarYear(int era)
- {
- EraInfo[] mEraInfo = CalEraInfo;
- //ChineseLunisolarCalendar does not has m_EraInfo it is going to retuen null
- if (mEraInfo == null)
- {
- return MaxCalendarYear;
- }
-
- if (era == Calendar.CurrentEra)
- {
- era = CurrentEraValue;
- }
- //era has to be in the supported range otherwise we will throw exception in CheckEraRange()
- if (era == GetEra(MaxDate))
- {
- return (GetYear(MaxCalendarYear, MaxDate));
- }
-
- for (int i = 0; i < mEraInfo.Length; i++)
- {
- if (era == mEraInfo[i].era)
- {
- return (mEraInfo[i].maxEraYear);
- }
- }
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
-
- internal EastAsianLunisolarCalendar()
- {
- }
-
- internal void CheckTicksRange(long ticks)
- {
- if (ticks < MinSupportedDateTime.Ticks || ticks > MaxSupportedDateTime.Ticks)
- {
- throw new ArgumentOutOfRangeException(
- "time",
- String.Format(CultureInfo.InvariantCulture, SR.ArgumentOutOfRange_CalendarRange,
- MinSupportedDateTime, MaxSupportedDateTime));
- }
- Contract.EndContractBlock();
- }
-
- internal void CheckEraRange(int era)
- {
- if (era == Calendar.CurrentEra)
- {
- era = CurrentEraValue;
- }
-
- if ((era < GetEra(MinDate)) || (era > GetEra(MaxDate)))
- {
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
- }
-
- internal int CheckYearRange(int year, int era)
- {
- CheckEraRange(era);
- year = GetGregorianYear(year, era);
-
- if ((year < MinCalendarYear) || (year > MaxCalendarYear))
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- SR.Format(SR.ArgumentOutOfRange_Range, MinEraCalendarYear(era), MaxEraCalendarYear(era)));
- }
- return year;
- }
-
- internal int CheckYearMonthRange(int year, int month, int era)
- {
- year = CheckYearRange(year, era);
-
- if (month == 13)
- {
- //Reject if there is no leap month this year
- if (GetYearInfo(year, LeapMonth) == 0)
- throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
- }
-
- if (month < 1 || month > 13)
- {
- throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
- }
- return year;
- }
-
- internal int InternalGetDaysInMonth(int year, int month)
- {
- int nDays;
- int mask; // mask for extracting bits
-
- mask = 0x8000;
- // convert the lunar day into a lunar month/date
- mask >>= (month - 1);
- if ((GetYearInfo(year, nDaysPerMonth) & mask) == 0)
- nDays = 29;
- else
- nDays = 30;
- return nDays;
- }
-
- // Returns the number of days in the month given by the year and
- // month arguments.
- //
-
- public override int GetDaysInMonth(int year, int month, int era)
- {
- year = CheckYearMonthRange(year, month, era);
- return InternalGetDaysInMonth(year, month);
- }
-
- private static int GregorianIsLeapYear(int y)
- {
- return ((((y) % 4) != 0) ? 0 : ((((y) % 100) != 0) ? 1 : ((((y) % 400) != 0) ? 0 : 1)));
- }
-
- // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
- //
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
- {
- year = CheckYearMonthRange(year, month, era);
- int daysInMonth = InternalGetDaysInMonth(year, month);
- if (day < 1 || day > daysInMonth)
- {
- throw new ArgumentOutOfRangeException(
- nameof(day),
- SR.Format(SR.ArgumentOutOfRange_Day, daysInMonth, month));
- }
-
- int gy = 0; int gm = 0; int gd = 0;
-
- if (LunarToGregorian(year, month, day, ref gy, ref gm, ref gd))
- {
- return new DateTime(gy, gm, gd, hour, minute, second, millisecond);
- }
- else
- {
- throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
- }
- }
-
-
- //
- // GregorianToLunar calculates lunar calendar info for the given gregorian year, month, date.
- // The input date should be validated before calling this method.
- //
- internal void GregorianToLunar(int nSYear, int nSMonth, int nSDate, ref int nLYear, ref int nLMonth, ref int nLDate)
- {
- // unsigned int nLYear, nLMonth, nLDate; // lunar ymd
- int nSolarDay; // day # in solar year
- int nLunarDay; // day # in lunar year
- int fLeap; // is it a solar leap year?
- int LDpM; // lunar days/month bitfield
- int mask; // mask for extracting bits
- int nDays; // # days this lunar month
- int nJan1Month, nJan1Date;
-
- // calc the solar day of year
- fLeap = GregorianIsLeapYear(nSYear);
- nSolarDay = (fLeap == 1) ? DaysToMonth366[nSMonth - 1] : DaysToMonth365[nSMonth - 1];
- nSolarDay += nSDate;
-
- // init lunar year info
- nLunarDay = nSolarDay;
- nLYear = nSYear;
- if (nLYear == (MaxCalendarYear + 1))
- {
- nLYear--;
- nLunarDay += ((GregorianIsLeapYear(nLYear) == 1) ? 366 : 365);
- nJan1Month = GetYearInfo(nLYear, Jan1Month);
- nJan1Date = GetYearInfo(nLYear, Jan1Date);
- }
- else
- {
- nJan1Month = GetYearInfo(nLYear, Jan1Month);
- nJan1Date = GetYearInfo(nLYear, Jan1Date);
-
- // check if this solar date is actually part of the previous
- // lunar year
- if ((nSMonth < nJan1Month) ||
- (nSMonth == nJan1Month && nSDate < nJan1Date))
- {
- // the corresponding lunar day is actually part of the previous
- // lunar year
- nLYear--;
-
- // add a solar year to the lunar day #
- nLunarDay += ((GregorianIsLeapYear(nLYear) == 1) ? 366 : 365);
-
- // update the new start of year
- nJan1Month = GetYearInfo(nLYear, Jan1Month);
- nJan1Date = GetYearInfo(nLYear, Jan1Date);
- }
- }
-
- // convert solar day into lunar day.
- // subtract off the beginning part of the solar year which is not
- // part of the lunar year. since this part is always in Jan or Feb,
- // we don't need to handle Leap Year (LY only affects March
- // and later).
- nLunarDay -= DaysToMonth365[nJan1Month - 1];
- nLunarDay -= (nJan1Date - 1);
-
- // convert the lunar day into a lunar month/date
- mask = 0x8000;
- LDpM = GetYearInfo(nLYear, nDaysPerMonth);
- nDays = ((LDpM & mask) != 0) ? 30 : 29;
- nLMonth = 1;
- while (nLunarDay > nDays)
- {
- nLunarDay -= nDays;
- nLMonth++;
- mask >>= 1;
- nDays = ((LDpM & mask) != 0) ? 30 : 29;
- }
- nLDate = nLunarDay;
- }
-
- /*
- //Convert from Lunar to Gregorian
- //Highly inefficient, but it works based on the forward conversion
- */
- internal bool LunarToGregorian(int nLYear, int nLMonth, int nLDate, ref int nSolarYear, ref int nSolarMonth, ref int nSolarDay)
- {
- int numLunarDays;
-
- if (nLDate < 1 || nLDate > 30)
- return false;
-
- numLunarDays = nLDate - 1;
-
- //Add previous months days to form the total num of days from the first of the month.
- for (int i = 1; i < nLMonth; i++)
- {
- numLunarDays += InternalGetDaysInMonth(nLYear, i);
- }
-
- //Get Gregorian First of year
- int nJan1Month = GetYearInfo(nLYear, Jan1Month);
- int nJan1Date = GetYearInfo(nLYear, Jan1Date);
-
- // calc the solar day of year of 1 Lunar day
- int fLeap = GregorianIsLeapYear(nLYear);
- int[] days = (fLeap == 1) ? DaysToMonth366 : DaysToMonth365;
-
- nSolarDay = nJan1Date;
-
- if (nJan1Month > 1)
- nSolarDay += days[nJan1Month - 1];
-
- // Add the actual lunar day to get the solar day we want
- nSolarDay = nSolarDay + numLunarDays;// - 1;
-
- if (nSolarDay > (fLeap + 365))
- {
- nSolarYear = nLYear + 1;
- nSolarDay -= (fLeap + 365);
- }
- else
- {
- nSolarYear = nLYear;
- }
-
- for (nSolarMonth = 1; nSolarMonth < 12; nSolarMonth++)
- {
- if (days[nSolarMonth] >= nSolarDay)
- break;
- }
-
- nSolarDay -= days[nSolarMonth - 1];
- return true;
- }
-
- internal DateTime LunarToTime(DateTime time, int year, int month, int day)
- {
- int gy = 0; int gm = 0; int gd = 0;
- LunarToGregorian(year, month, day, ref gy, ref gm, ref gd);
- return (GregorianCalendar.GetDefaultInstance().ToDateTime(gy, gm, gd, time.Hour, time.Minute, time.Second, time.Millisecond));
- }
-
- internal void TimeToLunar(DateTime time, ref int year, ref int month, ref int day)
- {
- int gy = 0; int gm = 0; int gd = 0;
-
- Calendar Greg = GregorianCalendar.GetDefaultInstance();
- gy = Greg.GetYear(time);
- gm = Greg.GetMonth(time);
- gd = Greg.GetDayOfMonth(time);
-
- GregorianToLunar(gy, gm, gd, ref year, ref month, ref day);
- }
-
- // Returns the DateTime resulting from adding the given number of
- // months to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year and month parts of the specified DateTime by
- // value months, and, if required, adjusting the day part of the
- // resulting date downwards to the last day of the resulting month in the
- // resulting year. The time-of-day part of the result is the same as the
- // time-of-day part of the specified DateTime.
- //
-
- public override DateTime AddMonths(DateTime time, int months)
- {
- if (months < -120000 || months > 120000)
- {
- throw new ArgumentOutOfRangeException(
- nameof(months),
- SR.Format(SR.ArgumentOutOfRange_Range, -120000, 120000));
- }
- Contract.EndContractBlock();
-
- CheckTicksRange(time.Ticks);
-
- int y = 0; int m = 0; int d = 0;
- TimeToLunar(time, ref y, ref m, ref d);
-
- int i = m + months;
- if (i > 0)
- {
- int monthsInYear = InternalIsLeapYear(y) ? 13 : 12;
-
- while (i - monthsInYear > 0)
- {
- i -= monthsInYear;
- y++;
- monthsInYear = InternalIsLeapYear(y) ? 13 : 12;
- }
- m = i;
- }
- else
- {
- int monthsInYear;
- while (i <= 0)
- {
- monthsInYear = InternalIsLeapYear(y - 1) ? 13 : 12;
- i += monthsInYear;
- y--;
- }
- m = i;
- }
-
- int days = InternalGetDaysInMonth(y, m);
- if (d > days)
- {
- d = days;
- }
- DateTime dt = LunarToTime(time, y, m, d);
-
- CheckAddResult(dt.Ticks, MinSupportedDateTime, MaxSupportedDateTime);
- return (dt);
- }
-
-
- public override DateTime AddYears(DateTime time, int years)
- {
- CheckTicksRange(time.Ticks);
-
- int y = 0; int m = 0; int d = 0;
- TimeToLunar(time, ref y, ref m, ref d);
-
- y += years;
-
- if (m == 13 && !InternalIsLeapYear(y))
- {
- m = 12;
- d = InternalGetDaysInMonth(y, m);
- }
- int DaysInMonths = InternalGetDaysInMonth(y, m);
- if (d > DaysInMonths)
- {
- d = DaysInMonths;
- }
-
- DateTime dt = LunarToTime(time, y, m, d);
- CheckAddResult(dt.Ticks, MinSupportedDateTime, MaxSupportedDateTime);
- return (dt);
- }
-
- // Returns the day-of-year part of the specified DateTime. The returned value
- // is an integer between 1 and [354|355 |383|384].
- //
-
- public override int GetDayOfYear(DateTime time)
- {
- CheckTicksRange(time.Ticks);
-
- int y = 0; int m = 0; int d = 0;
- TimeToLunar(time, ref y, ref m, ref d);
-
- for (int i = 1; i < m; i++)
- {
- d = d + InternalGetDaysInMonth(y, i);
- }
- return d;
- }
-
- // Returns the day-of-month part of the specified DateTime. The returned
- // value is an integer between 1 and 29 or 30.
- //
-
- public override int GetDayOfMonth(DateTime time)
- {
- CheckTicksRange(time.Ticks);
-
- int y = 0; int m = 0; int d = 0;
- TimeToLunar(time, ref y, ref m, ref d);
-
- return d;
- }
-
- // Returns the number of days in the year given by the year argument for the current era.
- //
-
- public override int GetDaysInYear(int year, int era)
- {
- year = CheckYearRange(year, era);
-
- int Days = 0;
- int monthsInYear = InternalIsLeapYear(year) ? 13 : 12;
-
- while (monthsInYear != 0)
- Days += InternalGetDaysInMonth(year, monthsInYear--);
-
- return Days;
- }
-
- // Returns the month part of the specified DateTime. The returned value is an
- // integer between 1 and 13.
- //
-
- public override int GetMonth(DateTime time)
- {
- CheckTicksRange(time.Ticks);
-
- int y = 0; int m = 0; int d = 0;
- TimeToLunar(time, ref y, ref m, ref d);
-
- return m;
- }
-
- // Returns the year part of the specified DateTime. The returned value is an
- // integer between 1 and MaxCalendarYear.
- //
-
- public override int GetYear(DateTime time)
- {
- CheckTicksRange(time.Ticks);
-
- int y = 0; int m = 0; int d = 0;
- TimeToLunar(time, ref y, ref m, ref d);
-
- return GetYear(y, time);
- }
-
- // Returns the day-of-week part of the specified DateTime. The returned value
- // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
- // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
- // Thursday, 5 indicates Friday, and 6 indicates Saturday.
- //
-
- public override DayOfWeek GetDayOfWeek(DateTime time)
- {
- CheckTicksRange(time.Ticks);
- return ((DayOfWeek)((int)(time.Ticks / Calendar.TicksPerDay + 1) % 7));
- }
-
- // Returns the number of months in the specified year and era.
-
- public override int GetMonthsInYear(int year, int era)
- {
- year = CheckYearRange(year, era);
- return (InternalIsLeapYear(year) ? 13 : 12);
- }
-
- // Checks whether a given day in the specified era is a leap day. This method returns true if
- // the date is a leap day, or false if not.
- //
-
- public override bool IsLeapDay(int year, int month, int day, int era)
- {
- year = CheckYearMonthRange(year, month, era);
- int daysInMonth = InternalGetDaysInMonth(year, month);
-
- if (day < 1 || day > daysInMonth)
- {
- throw new ArgumentOutOfRangeException(
- nameof(day),
- SR.Format(SR.ArgumentOutOfRange_Day, daysInMonth, month));
- }
- int m = GetYearInfo(year, LeapMonth);
- return ((m != 0) && (month == (m + 1)));
- }
-
- // Checks whether a given month in the specified era is a leap month. This method returns true if
- // month is a leap month, or false if not.
- //
-
- public override bool IsLeapMonth(int year, int month, int era)
- {
- year = CheckYearMonthRange(year, month, era);
- int m = GetYearInfo(year, LeapMonth);
- return ((m != 0) && (month == (m + 1)));
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this this year is not a leap year.
- //
-
- public override int GetLeapMonth(int year, int era)
- {
- year = CheckYearRange(year, era);
- int month = GetYearInfo(year, LeapMonth);
- if (month > 0)
- {
- return (month + 1);
- }
- return 0;
- }
-
- internal bool InternalIsLeapYear(int year)
- {
- return (GetYearInfo(year, LeapMonth) != 0);
- }
- // Checks whether a given year in the specified era is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
-
- public override bool IsLeapYear(int year, int era)
- {
- year = CheckYearRange(year, era);
- return InternalIsLeapYear(year);
- }
-
- private const int DEFAULT_GREGORIAN_TWO_DIGIT_YEAR_MAX = 2029;
-
-
- public override int TwoDigitYearMax
- {
- get
- {
- if (twoDigitYearMax == -1)
- {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(BaseCalendarID, GetYear(new DateTime(DEFAULT_GREGORIAN_TWO_DIGIT_YEAR_MAX, 1, 1)));
- }
- return (twoDigitYearMax);
- }
-
- set
- {
- VerifyWritable();
- if (value < 99 || value > MaxCalendarYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(value),
- SR.Format(SR.ArgumentOutOfRange_Range, 99, MaxCalendarYear));
- }
- twoDigitYearMax = value;
- }
- }
-
-
- public override int ToFourDigitYear(int year)
- {
- if (year < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(year),
- SR.ArgumentOutOfRange_NeedNonNegNum);
- }
- Contract.EndContractBlock();
-
- year = base.ToFourDigitYear(year);
- CheckYearRange(year, CurrentEra);
- return (year);
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/GregorianCalendar.cs b/src/mscorlib/corefx/System/Globalization/GregorianCalendar.cs
deleted file mode 100644
index be5b65b385..0000000000
--- a/src/mscorlib/corefx/System/Globalization/GregorianCalendar.cs
+++ /dev/null
@@ -1,666 +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.Globalization;
-using System.Diagnostics.Contracts;
-using System.Runtime.Serialization;
-using System.Threading;
-
-namespace System.Globalization
-{
- // This calendar recognizes two era values:
- // 0 CurrentEra (AD)
- // 1 BeforeCurrentEra (BC)
-
- [Serializable]
-
- public class GregorianCalendar : Calendar
- {
- /*
- A.D. = anno Domini
- */
-
- public const int ADEra = 1;
-
-
- internal const int DatePartYear = 0;
- internal const int DatePartDayOfYear = 1;
- internal const int DatePartMonth = 2;
- internal const int DatePartDay = 3;
-
- //
- // This is the max Gregorian year can be represented by DateTime class. The limitation
- // is derived from DateTime class.
- //
- internal const int MaxYear = 9999;
-
- internal GregorianCalendarTypes m_type;
-
- internal static readonly int[] DaysToMonth365 =
- {
- 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
- };
-
- internal static readonly int[] DaysToMonth366 =
- {
- 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366
- };
-
- private static volatile Calendar s_defaultInstance;
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext ctx)
- {
- if (m_type < GregorianCalendarTypes.Localized ||
- m_type > GregorianCalendarTypes.TransliteratedFrench)
- {
- throw new SerializationException(
- String.Format(CultureInfo.CurrentCulture, SR.Serialization_MemberOutOfRange, "type", "GregorianCalendar"));
- }
- }
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (DateTime.MinValue);
- }
- }
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (DateTime.MaxValue);
- }
- }
-
- public override CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.SolarCalendar;
- }
- }
-
- /*=================================GetDefaultInstance==========================
- **Action: Internal method to provide a default intance of GregorianCalendar. Used by NLS+ implementation
- ** and other calendars.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
-
- internal static Calendar GetDefaultInstance()
- {
- if (s_defaultInstance == null)
- {
- s_defaultInstance = new GregorianCalendar();
- }
- return (s_defaultInstance);
- }
-
- // Construct an instance of gregorian calendar.
-
- public GregorianCalendar() :
- this(GregorianCalendarTypes.Localized)
- {
- }
-
-
- public GregorianCalendar(GregorianCalendarTypes type)
- {
- if ((int)type < (int)GregorianCalendarTypes.Localized || (int)type > (int)GregorianCalendarTypes.TransliteratedFrench)
- {
- throw new ArgumentOutOfRangeException(
- nameof(type),
- SR.Format(SR.ArgumentOutOfRange_Range,
- GregorianCalendarTypes.Localized, GregorianCalendarTypes.TransliteratedFrench));
- }
- Contract.EndContractBlock();
- this.m_type = type;
- }
-
- public virtual GregorianCalendarTypes CalendarType
- {
- get
- {
- return (m_type);
- }
-
- set
- {
- VerifyWritable();
-
- switch (value)
- {
- case GregorianCalendarTypes.Localized:
- case GregorianCalendarTypes.USEnglish:
- case GregorianCalendarTypes.MiddleEastFrench:
- case GregorianCalendarTypes.Arabic:
- case GregorianCalendarTypes.TransliteratedEnglish:
- case GregorianCalendarTypes.TransliteratedFrench:
- m_type = value;
- break;
-
- default:
- throw new ArgumentOutOfRangeException("m_type", SR.ArgumentOutOfRange_Enum);
- }
- }
- }
-
- internal override CalendarId ID
- {
- get
- {
- // By returning different ID for different variations of GregorianCalendar,
- // we can support the Transliterated Gregorian calendar.
- // DateTimeFormatInfo will use this ID to get formatting information about
- // the calendar.
- return ((CalendarId)m_type);
- }
- }
-
-
- // Returns a given date part of this DateTime. This method is used
- // to compute the year, day-of-year, month, or day part.
- internal virtual int GetDatePart(long ticks, int part)
- {
- // n = number of days since 1/1/0001
- int n = (int)(ticks / TicksPerDay);
- // y400 = number of whole 400-year periods since 1/1/0001
- int y400 = n / DaysPer400Years;
- // n = day number within 400-year period
- n -= y400 * DaysPer400Years;
- // y100 = number of whole 100-year periods within 400-year period
- int y100 = n / DaysPer100Years;
- // Last 100-year period has an extra day, so decrement result if 4
- if (y100 == 4) y100 = 3;
- // n = day number within 100-year period
- n -= y100 * DaysPer100Years;
- // y4 = number of whole 4-year periods within 100-year period
- int y4 = n / DaysPer4Years;
- // n = day number within 4-year period
- n -= y4 * DaysPer4Years;
- // y1 = number of whole years within 4-year period
- int y1 = n / DaysPerYear;
- // Last year has an extra day, so decrement result if 4
- if (y1 == 4) y1 = 3;
- // If year was requested, compute and return it
- if (part == DatePartYear)
- {
- return (y400 * 400 + y100 * 100 + y4 * 4 + y1 + 1);
- }
- // n = day number within year
- n -= y1 * DaysPerYear;
- // If day-of-year was requested, return it
- if (part == DatePartDayOfYear)
- {
- return (n + 1);
- }
- // Leap year calculation looks different from IsLeapYear since y1, y4,
- // and y100 are relative to year 1, not year 0
- bool leapYear = (y1 == 3 && (y4 != 24 || y100 == 3));
- int[] days = leapYear ? DaysToMonth366 : DaysToMonth365;
- // All months have less than 32 days, so n >> 5 is a good conservative
- // estimate for the month
- int m = (n >> 5) + 1;
- // m = 1-based month number
- while (n >= days[m]) m++;
- // If month was requested, return it
- if (part == DatePartMonth) return (m);
- // Return 1-based day-of-month
- return (n - days[m - 1] + 1);
- }
-
- /*=================================GetAbsoluteDate==========================
- **Action: Gets the absolute date for the given Gregorian date. The absolute date means
- ** the number of days from January 1st, 1 A.D.
- **Returns: the absolute date
- **Arguments:
- ** year the Gregorian year
- ** month the Gregorian month
- ** day the day
- **Exceptions:
- ** ArgumentOutOfRangException if year, month, day value is valid.
- **Note:
- ** This is an internal method used by DateToTicks() and the calculations of Hijri and Hebrew calendars.
- ** Number of Days in Prior Years (both common and leap years) +
- ** Number of Days in Prior Months of Current Year +
- ** Number of Days in Current Month
- **
- ============================================================================*/
-
- internal static long GetAbsoluteDate(int year, int month, int day)
- {
- if (year >= 1 && year <= MaxYear && month >= 1 && month <= 12)
- {
- int[] days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))) ? DaysToMonth366 : DaysToMonth365;
- if (day >= 1 && (day <= days[month] - days[month - 1]))
- {
- int y = year - 1;
- int absoluteDate = y * 365 + y / 4 - y / 100 + y / 400 + days[month - 1] + day - 1;
- return (absoluteDate);
- }
- }
- throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
- }
-
- // Returns the tick count corresponding to the given year, month, and day.
- // Will check the if the parameters are valid.
- internal virtual long DateToTicks(int year, int month, int day)
- {
- return (GetAbsoluteDate(year, month, day) * TicksPerDay);
- }
-
- // Returns the DateTime resulting from adding the given number of
- // months to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year and month parts of the specified DateTime by
- // value months, and, if required, adjusting the day part of the
- // resulting date downwards to the last day of the resulting month in the
- // resulting year. The time-of-day part of the result is the same as the
- // time-of-day part of the specified DateTime.
- //
- // In more precise terms, considering the specified DateTime to be of the
- // form y / m / d + t, where y is the
- // year, m is the month, d is the day, and t is the
- // time-of-day, the result is y1 / m1 / d1 + t,
- // where y1 and m1 are computed by adding value months
- // to y and m, and d1 is the largest value less than
- // or equal to d that denotes a valid day in month m1 of year
- // y1.
- //
-
- public override DateTime AddMonths(DateTime time, int months)
- {
- if (months < -120000 || months > 120000)
- {
- throw new ArgumentOutOfRangeException(
- nameof(months),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- -120000,
- 120000));
- }
- Contract.EndContractBlock();
- int y = GetDatePart(time.Ticks, DatePartYear);
- int m = GetDatePart(time.Ticks, DatePartMonth);
- int d = GetDatePart(time.Ticks, DatePartDay);
- int i = m - 1 + months;
- if (i >= 0)
- {
- m = i % 12 + 1;
- y = y + i / 12;
- }
- else
- {
- m = 12 + (i + 1) % 12;
- y = y + (i - 11) / 12;
- }
- int[] daysArray = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? DaysToMonth366 : DaysToMonth365;
- int days = (daysArray[m] - daysArray[m - 1]);
-
- if (d > days)
- {
- d = days;
- }
- long ticks = DateToTicks(y, m, d) + time.Ticks % TicksPerDay;
- Calendar.CheckAddResult(ticks, MinSupportedDateTime, MaxSupportedDateTime);
-
- return (new DateTime(ticks));
- }
-
-
- // Returns the DateTime resulting from adding the given number of
- // years to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year part of the specified DateTime by value
- // years. If the month and day of the specified DateTime is 2/29, and if the
- // resulting year is not a leap year, the month and day of the resulting
- // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
- // parts of the result are the same as those of the specified DateTime.
- //
-
- public override DateTime AddYears(DateTime time, int years)
- {
- return (AddMonths(time, years * 12));
- }
-
- // Returns the day-of-month part of the specified DateTime. The returned
- // value is an integer between 1 and 31.
- //
-
- public override int GetDayOfMonth(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartDay));
- }
-
- // Returns the day-of-week part of the specified DateTime. The returned value
- // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
- // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
- // Thursday, 5 indicates Friday, and 6 indicates Saturday.
- //
-
- public override DayOfWeek GetDayOfWeek(DateTime time)
- {
- return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
- }
-
- // Returns the day-of-year part of the specified DateTime. The returned value
- // is an integer between 1 and 366.
- //
-
- public override int GetDayOfYear(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartDayOfYear));
- }
-
- // Returns the number of days in the month given by the year and
- // month arguments.
- //
-
- public override int GetDaysInMonth(int year, int month, int era)
- {
- if (era == CurrentEra || era == ADEra)
- {
- if (year < 1 || year > MaxYear)
- {
- throw new ArgumentOutOfRangeException(nameof(year), SR.Format(SR.ArgumentOutOfRange_Range,
- 1, MaxYear));
- }
- if (month < 1 || month > 12)
- {
- throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
- }
- int[] days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? DaysToMonth366 : DaysToMonth365);
- return (days[month] - days[month - 1]);
- }
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
-
- // Returns the number of days in the year given by the year argument for the current era.
- //
-
- public override int GetDaysInYear(int year, int era)
- {
- if (era == CurrentEra || era == ADEra)
- {
- if (year >= 1 && year <= MaxYear)
- {
- return ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? 366 : 365);
- }
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 1,
- MaxYear));
- }
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
-
- // Returns the era for the specified DateTime value.
-
- public override int GetEra(DateTime time)
- {
- return (ADEra);
- }
-
-
- public override int[] Eras
- {
- get
- {
- return (new int[] { ADEra });
- }
- }
-
-
- // Returns the month part of the specified DateTime. The returned value is an
- // integer between 1 and 12.
- //
-
- public override int GetMonth(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartMonth));
- }
-
- // Returns the number of months in the specified year and era.
-
- public override int GetMonthsInYear(int year, int era)
- {
- if (era == CurrentEra || era == ADEra)
- {
- if (year >= 1 && year <= MaxYear)
- {
- return (12);
- }
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 1,
- MaxYear));
- }
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
-
- // Returns the year part of the specified DateTime. The returned value is an
- // integer between 1 and 9999.
- //
-
- public override int GetYear(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartYear));
- }
-
- // Checks whether a given day in the specified era is a leap day. This method returns true if
- // the date is a leap day, or false if not.
- //
-
- public override bool IsLeapDay(int year, int month, int day, int era)
- {
- if (month < 1 || month > 12)
- {
- throw new ArgumentOutOfRangeException(nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
- 1, 12));
- }
- Contract.EndContractBlock();
-
- if (era != CurrentEra && era != ADEra)
- {
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
- if (year < 1 || year > MaxYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- SR.Format(SR.ArgumentOutOfRange_Range, 1, MaxYear));
- }
-
- if (day < 1 || day > GetDaysInMonth(year, month))
- {
- throw new ArgumentOutOfRangeException(nameof(day), SR.Format(SR.ArgumentOutOfRange_Range,
- 1, GetDaysInMonth(year, month)));
- }
- if (!IsLeapYear(year))
- {
- return (false);
- }
- if (month == 2 && day == 29)
- {
- return (true);
- }
- return (false);
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
- public override int GetLeapMonth(int year, int era)
- {
- if (era != CurrentEra && era != ADEra)
- {
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
- if (year < 1 || year > MaxYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range, 1, MaxYear));
- }
- Contract.EndContractBlock();
- return (0);
- }
-
- // Checks whether a given month in the specified era is a leap month. This method returns true if
- // month is a leap month, or false if not.
- //
-
- public override bool IsLeapMonth(int year, int month, int era)
- {
- if (era != CurrentEra && era != ADEra)
- {
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
-
- if (year < 1 || year > MaxYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range, 1, MaxYear));
- }
-
- if (month < 1 || month > 12)
- {
- throw new ArgumentOutOfRangeException(nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
- 1, 12));
- }
- Contract.EndContractBlock();
- return (false);
- }
-
- // Checks whether a given year in the specified era is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
-
- public override bool IsLeapYear(int year, int era)
- {
- if (era == CurrentEra || era == ADEra)
- {
- if (year >= 1 && year <= MaxYear)
- {
- return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
- }
-
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range, 1, MaxYear));
- }
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
-
- // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
- //
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
- {
- if (era == CurrentEra || era == ADEra)
- {
- return new DateTime(year, month, day, hour, minute, second, millisecond);
- }
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
-
- internal override Boolean TryToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era, out DateTime result)
- {
- if (era == CurrentEra || era == ADEra)
- {
- try
- {
- result = new DateTime(year, month, day, hour, minute, second, millisecond);
- return true;
- }
- catch (ArgumentOutOfRangeException)
- {
- result = DateTime.Now;
- return false;
- }
- catch (ArgumentException)
- {
- result = DateTime.Now;
- return false;
- }
- }
- result = DateTime.MinValue;
- return false;
- }
-
- private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 2029;
-
-
- public override int TwoDigitYearMax
- {
- get
- {
- if (twoDigitYearMax == -1)
- {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
- }
- return (twoDigitYearMax);
- }
-
- set
- {
- VerifyWritable();
- if (value < 99 || value > MaxYear)
- {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 99,
- MaxYear));
- }
- twoDigitYearMax = value;
- }
- }
-
-
- public override int ToFourDigitYear(int year)
- {
- if (year < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(year),
- SR.ArgumentOutOfRange_NeedNonNegNum);
- }
- Contract.EndContractBlock();
-
- if (year > MaxYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range, 1, MaxYear));
- }
- return (base.ToFourDigitYear(year));
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/GregorianCalendarHelper.cs b/src/mscorlib/corefx/System/Globalization/GregorianCalendarHelper.cs
deleted file mode 100644
index ee8ba13894..0000000000
--- a/src/mscorlib/corefx/System/Globalization/GregorianCalendarHelper.cs
+++ /dev/null
@@ -1,668 +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.Diagnostics.Contracts;
-using System.Runtime.Serialization;
-using System.Threading;
-
-namespace System.Globalization
-{
- // Gregorian Calendars use Era Info
- [Serializable]
- internal class EraInfo
- {
- internal int era; // The value of the era.
- internal long ticks; // The time in ticks when the era starts
- internal int yearOffset; // The offset to Gregorian year when the era starts.
- // Gregorian Year = Era Year + yearOffset
- // Era Year = Gregorian Year - yearOffset
- internal int minEraYear; // Min year value in this era. Generally, this value is 1, but this may
- // be affected by the DateTime.MinValue;
- internal int maxEraYear; // Max year value in this era. (== the year length of the era + 1)
-
- [OptionalField(VersionAdded = 4)]
- internal String eraName; // The era name
- [OptionalField(VersionAdded = 4)]
- internal String abbrevEraName; // Abbreviated Era Name
- [OptionalField(VersionAdded = 4)]
- internal String englishEraName; // English era name
-
- internal EraInfo(int era, int startYear, int startMonth, int startDay, int yearOffset, int minEraYear, int maxEraYear)
- {
- this.era = era;
- this.yearOffset = yearOffset;
- this.minEraYear = minEraYear;
- this.maxEraYear = maxEraYear;
- this.ticks = new DateTime(startYear, startMonth, startDay).Ticks;
- }
-
- internal EraInfo(int era, int startYear, int startMonth, int startDay, int yearOffset, int minEraYear, int maxEraYear,
- String eraName, String abbrevEraName, String englishEraName)
- {
- this.era = era;
- this.yearOffset = yearOffset;
- this.minEraYear = minEraYear;
- this.maxEraYear = maxEraYear;
- this.ticks = new DateTime(startYear, startMonth, startDay).Ticks;
- this.eraName = eraName;
- this.abbrevEraName = abbrevEraName;
- this.englishEraName = englishEraName;
- }
- }
-
- // This calendar recognizes two era values:
- // 0 CurrentEra (AD)
- // 1 BeforeCurrentEra (BC)
- [Serializable]
- internal class GregorianCalendarHelper
- {
- // 1 tick = 100ns = 10E-7 second
- // Number of ticks per time unit
- internal const long TicksPerMillisecond = 10000;
- internal const long TicksPerSecond = TicksPerMillisecond * 1000;
- internal const long TicksPerMinute = TicksPerSecond * 60;
- internal const long TicksPerHour = TicksPerMinute * 60;
- internal const long TicksPerDay = TicksPerHour * 24;
-
- // Number of milliseconds per time unit
- internal const int MillisPerSecond = 1000;
- internal const int MillisPerMinute = MillisPerSecond * 60;
- internal const int MillisPerHour = MillisPerMinute * 60;
- internal const int MillisPerDay = MillisPerHour * 24;
-
- // Number of days in a non-leap year
- internal const int DaysPerYear = 365;
- // Number of days in 4 years
- internal const int DaysPer4Years = DaysPerYear * 4 + 1;
- // Number of days in 100 years
- internal const int DaysPer100Years = DaysPer4Years * 25 - 1;
- // Number of days in 400 years
- internal const int DaysPer400Years = DaysPer100Years * 4 + 1;
-
- // Number of days from 1/1/0001 to 1/1/10000
- internal const int DaysTo10000 = DaysPer400Years * 25 - 366;
-
- internal const long MaxMillis = (long)DaysTo10000 * MillisPerDay;
-
- internal const int DatePartYear = 0;
- internal const int DatePartDayOfYear = 1;
- internal const int DatePartMonth = 2;
- internal const int DatePartDay = 3;
-
- //
- // This is the max Gregorian year can be represented by DateTime class. The limitation
- // is derived from DateTime class.
- //
- internal int MaxYear
- {
- get
- {
- return (m_maxYear);
- }
- }
-
- internal static readonly int[] DaysToMonth365 =
- {
- 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
- };
-
- internal static readonly int[] DaysToMonth366 =
- {
- 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366
- };
-
- [OptionalField(VersionAdded = 1)]
- internal int m_maxYear = 9999;
- [OptionalField(VersionAdded = 1)]
- internal int m_minYear;
- internal Calendar m_Cal;
-
- [OptionalField(VersionAdded = 1)]
- internal EraInfo[] m_EraInfo;
- [OptionalField(VersionAdded = 1)]
- internal int[] m_eras = null;
-
-
- // Construct an instance of gregorian calendar.
- internal GregorianCalendarHelper(Calendar cal, EraInfo[] eraInfo)
- {
- m_Cal = cal;
- m_EraInfo = eraInfo;
- m_maxYear = m_EraInfo[0].maxEraYear;
- m_minYear = m_EraInfo[0].minEraYear; ;
- }
-
- /*=================================GetGregorianYear==========================
- **Action: Get the Gregorian year value for the specified year in an era.
- **Returns: The Gregorian year value.
- **Arguments:
- ** year the year value in Japanese calendar
- ** era the Japanese emperor era value.
- **Exceptions:
- ** ArgumentOutOfRangeException if year value is invalid or era value is invalid.
- ============================================================================*/
-
- internal int GetGregorianYear(int year, int era)
- {
- if (year < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(year),
- SR.ArgumentOutOfRange_NeedNonNegNum);
- }
- Contract.EndContractBlock();
-
- if (era == Calendar.CurrentEra)
- {
- era = m_Cal.CurrentEraValue;
- }
-
- for (int i = 0; i < m_EraInfo.Length; i++)
- {
- if (era == m_EraInfo[i].era)
- {
- if (year < m_EraInfo[i].minEraYear || year > m_EraInfo[i].maxEraYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- m_EraInfo[i].minEraYear,
- m_EraInfo[i].maxEraYear));
- }
- return (m_EraInfo[i].yearOffset + year);
- }
- }
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
-
- internal bool IsValidYear(int year, int era)
- {
- if (year < 0)
- {
- return false;
- }
-
- if (era == Calendar.CurrentEra)
- {
- era = m_Cal.CurrentEraValue;
- }
-
- for (int i = 0; i < m_EraInfo.Length; i++)
- {
- if (era == m_EraInfo[i].era)
- {
- if (year < m_EraInfo[i].minEraYear || year > m_EraInfo[i].maxEraYear)
- {
- return false;
- }
- return true;
- }
- }
- return false;
- }
-
-
- // Returns a given date part of this DateTime. This method is used
- // to compute the year, day-of-year, month, or day part.
- internal virtual int GetDatePart(long ticks, int part)
- {
- CheckTicksRange(ticks);
- // n = number of days since 1/1/0001
- int n = (int)(ticks / TicksPerDay);
- // y400 = number of whole 400-year periods since 1/1/0001
- int y400 = n / DaysPer400Years;
- // n = day number within 400-year period
- n -= y400 * DaysPer400Years;
- // y100 = number of whole 100-year periods within 400-year period
- int y100 = n / DaysPer100Years;
- // Last 100-year period has an extra day, so decrement result if 4
- if (y100 == 4) y100 = 3;
- // n = day number within 100-year period
- n -= y100 * DaysPer100Years;
- // y4 = number of whole 4-year periods within 100-year period
- int y4 = n / DaysPer4Years;
- // n = day number within 4-year period
- n -= y4 * DaysPer4Years;
- // y1 = number of whole years within 4-year period
- int y1 = n / DaysPerYear;
- // Last year has an extra day, so decrement result if 4
- if (y1 == 4) y1 = 3;
- // If year was requested, compute and return it
- if (part == DatePartYear)
- {
- return (y400 * 400 + y100 * 100 + y4 * 4 + y1 + 1);
- }
- // n = day number within year
- n -= y1 * DaysPerYear;
- // If day-of-year was requested, return it
- if (part == DatePartDayOfYear)
- {
- return (n + 1);
- }
- // Leap year calculation looks different from IsLeapYear since y1, y4,
- // and y100 are relative to year 1, not year 0
- bool leapYear = (y1 == 3 && (y4 != 24 || y100 == 3));
- int[] days = leapYear ? DaysToMonth366 : DaysToMonth365;
- // All months have less than 32 days, so n >> 5 is a good conservative
- // estimate for the month
- int m = (n >> 5) + 1;
- // m = 1-based month number
- while (n >= days[m]) m++;
- // If month was requested, return it
- if (part == DatePartMonth) return (m);
- // Return 1-based day-of-month
- return (n - days[m - 1] + 1);
- }
-
- /*=================================GetAbsoluteDate==========================
- **Action: Gets the absolute date for the given Gregorian date. The absolute date means
- ** the number of days from January 1st, 1 A.D.
- **Returns: the absolute date
- **Arguments:
- ** year the Gregorian year
- ** month the Gregorian month
- ** day the day
- **Exceptions:
- ** ArgumentOutOfRangException if year, month, day value is valid.
- **Note:
- ** This is an internal method used by DateToTicks() and the calculations of Hijri and Hebrew calendars.
- ** Number of Days in Prior Years (both common and leap years) +
- ** Number of Days in Prior Months of Current Year +
- ** Number of Days in Current Month
- **
- ============================================================================*/
-
- internal static long GetAbsoluteDate(int year, int month, int day)
- {
- if (year >= 1 && year <= 9999 && month >= 1 && month <= 12)
- {
- int[] days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))) ? DaysToMonth366 : DaysToMonth365;
- if (day >= 1 && (day <= days[month] - days[month - 1]))
- {
- int y = year - 1;
- int absoluteDate = y * 365 + y / 4 - y / 100 + y / 400 + days[month - 1] + day - 1;
- return (absoluteDate);
- }
- }
- throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
- }
-
- // Returns the tick count corresponding to the given year, month, and day.
- // Will check the if the parameters are valid.
- internal static long DateToTicks(int year, int month, int day)
- {
- return (GetAbsoluteDate(year, month, day) * TicksPerDay);
- }
-
- // Return the tick count corresponding to the given hour, minute, second.
- // Will check the if the parameters are valid.
- internal static long TimeToTicks(int hour, int minute, int second, int millisecond)
- {
- //TimeSpan.TimeToTicks is a family access function which does no error checking, so
- //we need to put some error checking out here.
- if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >= 0 && second < 60)
- {
- if (millisecond < 0 || millisecond >= MillisPerSecond)
- {
- throw new ArgumentOutOfRangeException(
- nameof(millisecond),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- MillisPerSecond - 1));
- }
- return (InternalGloablizationHelper.TimeToTicks(hour, minute, second) + millisecond * TicksPerMillisecond); ;
- }
- throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
- }
-
-
- internal void CheckTicksRange(long ticks)
- {
- if (ticks < m_Cal.MinSupportedDateTime.Ticks || ticks > m_Cal.MaxSupportedDateTime.Ticks)
- {
- throw new ArgumentOutOfRangeException(
- "time",
- String.Format(
- CultureInfo.InvariantCulture,
- SR.ArgumentOutOfRange_CalendarRange,
- m_Cal.MinSupportedDateTime,
- m_Cal.MaxSupportedDateTime));
- }
- Contract.EndContractBlock();
- }
-
- // Returns the DateTime resulting from adding the given number of
- // months to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year and month parts of the specified DateTime by
- // value months, and, if required, adjusting the day part of the
- // resulting date downwards to the last day of the resulting month in the
- // resulting year. The time-of-day part of the result is the same as the
- // time-of-day part of the specified DateTime.
- //
- // In more precise terms, considering the specified DateTime to be of the
- // form y / m / d + t, where y is the
- // year, m is the month, d is the day, and t is the
- // time-of-day, the result is y1 / m1 / d1 + t,
- // where y1 and m1 are computed by adding value months
- // to y and m, and d1 is the largest value less than
- // or equal to d that denotes a valid day in month m1 of year
- // y1.
- //
- public DateTime AddMonths(DateTime time, int months)
- {
- if (months < -120000 || months > 120000)
- {
- throw new ArgumentOutOfRangeException(
- nameof(months),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- -120000,
- 120000));
- }
- Contract.EndContractBlock();
- CheckTicksRange(time.Ticks);
-
- int y = GetDatePart(time.Ticks, DatePartYear);
- int m = GetDatePart(time.Ticks, DatePartMonth);
- int d = GetDatePart(time.Ticks, DatePartDay);
- int i = m - 1 + months;
- if (i >= 0)
- {
- m = i % 12 + 1;
- y = y + i / 12;
- }
- else
- {
- m = 12 + (i + 1) % 12;
- y = y + (i - 11) / 12;
- }
- int[] daysArray = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? DaysToMonth366 : DaysToMonth365;
- int days = (daysArray[m] - daysArray[m - 1]);
-
- if (d > days)
- {
- d = days;
- }
- long ticks = DateToTicks(y, m, d) + (time.Ticks % TicksPerDay);
- Calendar.CheckAddResult(ticks, m_Cal.MinSupportedDateTime, m_Cal.MaxSupportedDateTime);
- return (new DateTime(ticks));
- }
-
- // Returns the DateTime resulting from adding the given number of
- // years to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year part of the specified DateTime by value
- // years. If the month and day of the specified DateTime is 2/29, and if the
- // resulting year is not a leap year, the month and day of the resulting
- // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
- // parts of the result are the same as those of the specified DateTime.
- //
- public DateTime AddYears(DateTime time, int years)
- {
- return (AddMonths(time, years * 12));
- }
-
- // Returns the day-of-month part of the specified DateTime. The returned
- // value is an integer between 1 and 31.
- //
- public int GetDayOfMonth(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartDay));
- }
-
- // Returns the day-of-week part of the specified DateTime. The returned value
- // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
- // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
- // Thursday, 5 indicates Friday, and 6 indicates Saturday.
- //
- public DayOfWeek GetDayOfWeek(DateTime time)
- {
- CheckTicksRange(time.Ticks);
- return ((DayOfWeek)((time.Ticks / TicksPerDay + 1) % 7));
- }
-
- // Returns the day-of-year part of the specified DateTime. The returned value
- // is an integer between 1 and 366.
- //
- public int GetDayOfYear(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartDayOfYear));
- }
-
- // Returns the number of days in the month given by the year and
- // month arguments.
- //
- [Pure]
- public int GetDaysInMonth(int year, int month, int era)
- {
- //
- // Convert year/era value to Gregorain year value.
- //
- year = GetGregorianYear(year, era);
- if (month < 1 || month > 12)
- {
- throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
- }
- int[] days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? DaysToMonth366 : DaysToMonth365);
- return (days[month] - days[month - 1]);
- }
-
- // Returns the number of days in the year given by the year argument for the current era.
- //
-
- public int GetDaysInYear(int year, int era)
- {
- //
- // Convert year/era value to Gregorain year value.
- //
- year = GetGregorianYear(year, era);
- return ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? 366 : 365);
- }
-
- // Returns the era for the specified DateTime value.
- public int GetEra(DateTime time)
- {
- long ticks = time.Ticks;
- // The assumption here is that m_EraInfo is listed in reverse order.
- for (int i = 0; i < m_EraInfo.Length; i++)
- {
- if (ticks >= m_EraInfo[i].ticks)
- {
- return (m_EraInfo[i].era);
- }
- }
- throw new ArgumentOutOfRangeException(nameof(time), SR.ArgumentOutOfRange_Era);
- }
-
-
- public int[] Eras
- {
- get
- {
- if (m_eras == null)
- {
- m_eras = new int[m_EraInfo.Length];
- for (int i = 0; i < m_EraInfo.Length; i++)
- {
- m_eras[i] = m_EraInfo[i].era;
- }
- }
- return ((int[])m_eras.Clone());
- }
- }
-
- // Returns the month part of the specified DateTime. The returned value is an
- // integer between 1 and 12.
- //
- public int GetMonth(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartMonth));
- }
-
- // Returns the number of months in the specified year and era.
- public int GetMonthsInYear(int year, int era)
- {
- year = GetGregorianYear(year, era);
- return (12);
- }
-
- // Returns the year part of the specified DateTime. The returned value is an
- // integer between 1 and 9999.
- //
- public int GetYear(DateTime time)
- {
- long ticks = time.Ticks;
- int year = GetDatePart(ticks, DatePartYear);
- for (int i = 0; i < m_EraInfo.Length; i++)
- {
- if (ticks >= m_EraInfo[i].ticks)
- {
- return (year - m_EraInfo[i].yearOffset);
- }
- }
- throw new ArgumentException(SR.Argument_NoEra);
- }
-
- // Returns the year that match the specified Gregorian year. The returned value is an
- // integer between 1 and 9999.
- //
- public int GetYear(int year, DateTime time)
- {
- long ticks = time.Ticks;
- for (int i = 0; i < m_EraInfo.Length; i++)
- {
- // while calculating dates with JapaneseLuniSolarCalendar, we can run into cases right after the start of the era
- // and still belong to the month which is started in previous era. Calculating equivalent calendar date will cause
- // using the new era info which will have the year offset equal to the year we are calculating year = m_EraInfo[i].yearOffset
- // which will end up with zero as calendar year.
- // We should use the previous era info instead to get the right year number. Example of such date is Feb 2nd 1989
- if (ticks >= m_EraInfo[i].ticks && year > m_EraInfo[i].yearOffset)
- {
- return (year - m_EraInfo[i].yearOffset);
- }
- }
- throw new ArgumentException(SR.Argument_NoEra);
- }
-
- // Checks whether a given day in the specified era is a leap day. This method returns true if
- // the date is a leap day, or false if not.
- //
- public bool IsLeapDay(int year, int month, int day, int era)
- {
- // year/month/era checking is done in GetDaysInMonth()
- if (day < 1 || day > GetDaysInMonth(year, month, era))
- {
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 1,
- GetDaysInMonth(year, month, era)));
- }
- Contract.EndContractBlock();
-
- if (!IsLeapYear(year, era))
- {
- return (false);
- }
-
- if (month == 2 && day == 29)
- {
- return (true);
- }
-
- return (false);
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
- public int GetLeapMonth(int year, int era)
- {
- year = GetGregorianYear(year, era);
- return (0);
- }
-
- // Checks whether a given month in the specified era is a leap month. This method returns true if
- // month is a leap month, or false if not.
- //
- public bool IsLeapMonth(int year, int month, int era)
- {
- year = GetGregorianYear(year, era);
- if (month < 1 || month > 12)
- {
- throw new ArgumentOutOfRangeException(
- nameof(month),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 1,
- 12));
- }
- return (false);
- }
-
- // Checks whether a given year in the specified era is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
- public bool IsLeapYear(int year, int era)
- {
- year = GetGregorianYear(year, era);
- return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
- }
-
- // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
- //
- public DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
- {
- year = GetGregorianYear(year, era);
- long ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second, millisecond);
- CheckTicksRange(ticks);
- return (new DateTime(ticks));
- }
-
- public virtual int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
- {
- CheckTicksRange(time.Ticks);
- // Use GregorianCalendar to get around the problem that the implmentation in Calendar.GetWeekOfYear()
- // can call GetYear() that exceeds the supported range of the Gregorian-based calendars.
- return (GregorianCalendar.GetDefaultInstance().GetWeekOfYear(time, rule, firstDayOfWeek));
- }
-
-
- public int ToFourDigitYear(int year, int twoDigitYearMax)
- {
- if (year < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(year),
- SR.ArgumentOutOfRange_NeedPosNum);
- }
- Contract.EndContractBlock();
-
- if (year < 100)
- {
- int y = year % 100;
- return ((twoDigitYearMax / 100 - (y > twoDigitYearMax % 100 ? 1 : 0)) * 100 + y);
- }
-
- if (year < m_minYear || year > m_maxYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range, m_minYear, m_maxYear));
- }
- // If the year value is above 100, just return the year value. Don't have to do
- // the TwoDigitYearMax comparison.
- return (year);
- }
- }
-}
-
diff --git a/src/mscorlib/corefx/System/Globalization/GregorianCalendarTypes.cs b/src/mscorlib/corefx/System/Globalization/GregorianCalendarTypes.cs
deleted file mode 100644
index a14010fe60..0000000000
--- a/src/mscorlib/corefx/System/Globalization/GregorianCalendarTypes.cs
+++ /dev/null
@@ -1,21 +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;
-
-namespace System.Globalization
-{
- // Note: The values of the members of this enum must match the coresponding values
- // in the CalendarId enum (since we cast between GregorianCalendarTypes and CalendarId).
- [Serializable]
- public enum GregorianCalendarTypes
- {
- Localized = CalendarId.GREGORIAN,
- USEnglish = CalendarId.GREGORIAN_US,
- MiddleEastFrench = CalendarId.GREGORIAN_ME_FRENCH,
- Arabic = CalendarId.GREGORIAN_ARABIC,
- TransliteratedEnglish = CalendarId.GREGORIAN_XLIT_ENGLISH,
- TransliteratedFrench = CalendarId.GREGORIAN_XLIT_FRENCH,
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/HebrewNumber.cs b/src/mscorlib/corefx/System/Globalization/HebrewNumber.cs
deleted file mode 100644
index 01e251d9e8..0000000000
--- a/src/mscorlib/corefx/System/Globalization/HebrewNumber.cs
+++ /dev/null
@@ -1,458 +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.Text;
-using System.Diagnostics;
-
-namespace System.Globalization
-{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Used in HebrewNumber.ParseByChar to maintain the context information (
- // the state in the state machine and current Hebrew number values, etc.)
- // when parsing Hebrew number character by character.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal struct HebrewNumberParsingContext
- {
- // The current state of the state machine for parsing Hebrew numbers.
- internal HebrewNumber.HS state;
- // The current value of the Hebrew number.
- // The final value is determined when state is FoundEndOfHebrewNumber.
- internal int result;
-
- public HebrewNumberParsingContext(int result)
- {
- // Set the start state of the state machine for parsing Hebrew numbers.
- state = HebrewNumber.HS.Start;
- this.result = result;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Please see ParseByChar() for comments about different states defined here.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal enum HebrewNumberParsingState
- {
- InvalidHebrewNumber,
- NotHebrewDigit,
- FoundEndOfHebrewNumber,
- ContinueParsing,
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // class HebrewNumber
- //
- // Provides static methods for formatting integer values into
- // Hebrew text and parsing Hebrew number text.
- //
- // Limitations:
- // Parse can only handles value 1 ~ 999.
- // ToString() can only handles 1 ~ 999. If value is greater than 5000,
- // 5000 will be subtracted from the value.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal class HebrewNumber
- {
- // This class contains only static methods. Add a private ctor so that
- // compiler won't generate a default one for us.
- private HebrewNumber()
- {
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // ToString
- //
- // Converts the given number to Hebrew letters according to the numeric
- // value of each Hebrew letter. Basically, this converts the lunar year
- // and the lunar month to letters.
- //
- // The character of a year is described by three letters of the Hebrew
- // alphabet, the first and third giving, respectively, the days of the
- // weeks on which the New Year occurs and Passover begins, while the
- // second is the initial of the Hebrew word for defective, normal, or
- // complete.
- //
- // Defective Year : Both Heshvan and Kislev are defective (353 or 383 days)
- // Normal Year : Heshvan is defective, Kislev is full (354 or 384 days)
- // Complete Year : Both Heshvan and Kislev are full (355 or 385 days)
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal static String ToString(int Number)
- {
- char cTens = '\x0';
- char cUnits; // tens and units chars
- int Hundreds, Tens; // hundreds and tens values
- StringBuilder szHebrew = new StringBuilder();
-
-
- //
- // Adjust the number if greater than 5000.
- //
- if (Number > 5000)
- {
- Number -= 5000;
- }
-
- Debug.Assert(Number > 0 && Number <= 999, "Number is out of range."); ;
-
- //
- // Get the Hundreds.
- //
- Hundreds = Number / 100;
-
- if (Hundreds > 0)
- {
- Number -= Hundreds * 100;
- // \x05e7 = 100
- // \x05e8 = 200
- // \x05e9 = 300
- // \x05ea = 400
- // If the number is greater than 400, use the multiples of 400.
- for (int i = 0; i < (Hundreds / 4); i++)
- {
- szHebrew.Append('\x05ea');
- }
-
- int remains = Hundreds % 4;
- if (remains > 0)
- {
- szHebrew.Append((char)((int)'\x05e6' + remains));
- }
- }
-
- //
- // Get the Tens.
- //
- Tens = Number / 10;
- Number %= 10;
-
- switch (Tens)
- {
- case (0):
- cTens = '\x0';
- break;
- case (1):
- cTens = '\x05d9'; // Hebrew Letter Yod
- break;
- case (2):
- cTens = '\x05db'; // Hebrew Letter Kaf
- break;
- case (3):
- cTens = '\x05dc'; // Hebrew Letter Lamed
- break;
- case (4):
- cTens = '\x05de'; // Hebrew Letter Mem
- break;
- case (5):
- cTens = '\x05e0'; // Hebrew Letter Nun
- break;
- case (6):
- cTens = '\x05e1'; // Hebrew Letter Samekh
- break;
- case (7):
- cTens = '\x05e2'; // Hebrew Letter Ayin
- break;
- case (8):
- cTens = '\x05e4'; // Hebrew Letter Pe
- break;
- case (9):
- cTens = '\x05e6'; // Hebrew Letter Tsadi
- break;
- }
-
- //
- // Get the Units.
- //
- cUnits = (char)(Number > 0 ? ((int)'\x05d0' + Number - 1) : 0);
-
- if ((cUnits == '\x05d4') && // Hebrew Letter He (5)
- (cTens == '\x05d9'))
- { // Hebrew Letter Yod (10)
- cUnits = '\x05d5'; // Hebrew Letter Vav (6)
- cTens = '\x05d8'; // Hebrew Letter Tet (9)
- }
-
- if ((cUnits == '\x05d5') && // Hebrew Letter Vav (6)
- (cTens == '\x05d9'))
- { // Hebrew Letter Yod (10)
- cUnits = '\x05d6'; // Hebrew Letter Zayin (7)
- cTens = '\x05d8'; // Hebrew Letter Tet (9)
- }
-
- //
- // Copy the appropriate info to the given buffer.
- //
-
- if (cTens != '\x0')
- {
- szHebrew.Append(cTens);
- }
-
- if (cUnits != '\x0')
- {
- szHebrew.Append(cUnits);
- }
-
- if (szHebrew.Length > 1)
- {
- szHebrew.Insert(szHebrew.Length - 1, '"');
- }
- else
- {
- szHebrew.Append('\'');
- }
-
- //
- // Return success.
- //
- return (szHebrew.ToString());
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Token used to tokenize a Hebrew word into tokens so that we can use in the
- // state machine.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- private enum HebrewToken : short
- {
- Invalid = -1,
- Digit400 = 0,
- Digit200_300 = 1,
- Digit100 = 2,
- Digit10 = 3, // 10 ~ 90
- Digit1 = 4, // 1, 2, 3, 4, 5, 8,
- Digit6_7 = 5,
- Digit7 = 6,
- Digit9 = 7,
- SingleQuote = 8,
- DoubleQuote = 9,
- };
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // This class is used to map a token into its Hebrew digit value.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- private struct HebrewValue
- {
- internal HebrewToken token;
- internal short value;
- internal HebrewValue(HebrewToken token, short value)
- {
- this.token = token;
- this.value = value;
- }
- }
-
- //
- // Map a Hebrew character from U+05D0 ~ U+05EA to its digit value.
- // The value is -1 if the Hebrew character does not have a associated value.
- //
- private static readonly HebrewValue[] s_hebrewValues = {
- new HebrewValue(HebrewToken.Digit1, 1) , // '\x05d0
- new HebrewValue(HebrewToken.Digit1, 2) , // '\x05d1
- new HebrewValue(HebrewToken.Digit1, 3) , // '\x05d2
- new HebrewValue(HebrewToken.Digit1, 4) , // '\x05d3
- new HebrewValue(HebrewToken.Digit1, 5) , // '\x05d4
- new HebrewValue(HebrewToken.Digit6_7,6) , // '\x05d5
- new HebrewValue(HebrewToken.Digit6_7,7) , // '\x05d6
- new HebrewValue(HebrewToken.Digit1, 8) , // '\x05d7
- new HebrewValue(HebrewToken.Digit9, 9) , // '\x05d8
- new HebrewValue(HebrewToken.Digit10, 10) , // '\x05d9; // Hebrew Letter Yod
- new HebrewValue(HebrewToken.Invalid, -1) , // '\x05da;
- new HebrewValue(HebrewToken.Digit10, 20) , // '\x05db; // Hebrew Letter Kaf
- new HebrewValue(HebrewToken.Digit10, 30) , // '\x05dc; // Hebrew Letter Lamed
- new HebrewValue(HebrewToken.Invalid, -1) , // '\x05dd;
- new HebrewValue(HebrewToken.Digit10, 40) , // '\x05de; // Hebrew Letter Mem
- new HebrewValue(HebrewToken.Invalid, -1) , // '\x05df;
- new HebrewValue(HebrewToken.Digit10, 50) , // '\x05e0; // Hebrew Letter Nun
- new HebrewValue(HebrewToken.Digit10, 60) , // '\x05e1; // Hebrew Letter Samekh
- new HebrewValue(HebrewToken.Digit10, 70) , // '\x05e2; // Hebrew Letter Ayin
- new HebrewValue(HebrewToken.Invalid, -1) , // '\x05e3;
- new HebrewValue(HebrewToken.Digit10, 80) , // '\x05e4; // Hebrew Letter Pe
- new HebrewValue(HebrewToken.Invalid, -1) , // '\x05e5;
- new HebrewValue(HebrewToken.Digit10, 90) , // '\x05e6; // Hebrew Letter Tsadi
- new HebrewValue(HebrewToken.Digit100, 100) , // '\x05e7;
- new HebrewValue(HebrewToken.Digit200_300, 200) , // '\x05e8;
- new HebrewValue(HebrewToken.Digit200_300, 300) , // '\x05e9;
- new HebrewValue(HebrewToken.Digit400, 400) , // '\x05ea;
- };
-
- private const int minHebrewNumberCh = 0x05d0;
- private static char s_maxHebrewNumberCh = (char)(minHebrewNumberCh + s_hebrewValues.Length - 1);
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Hebrew number parsing State
- // The current state and the next token will lead to the next state in the state machine.
- // DQ = Double Quote
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal enum HS : sbyte
- {
- _err = -1, // an error state
- Start = 0,
- S400 = 1, // a Hebrew digit 400
- S400_400 = 2, // Two Hebrew digit 400
- S400_X00 = 3, // Two Hebrew digit 400 and followed by 100
- S400_X0 = 4, // Hebrew digit 400 and followed by 10 ~ 90
- X00_DQ = 5, // A hundred number and followed by a double quote.
- S400_X00_X0 = 6,
- X0_DQ = 7, // A two-digit number and followed by a double quote.
- X = 8, // A single digit Hebrew number.
- X0 = 9, // A two-digit Hebrew number
- X00 = 10, // A three-digit Hebrew number
- S400_DQ = 11, // A Hebrew digit 400 and followed by a double quote.
- S400_400_DQ = 12,
- S400_400_100 = 13,
- S9 = 14, // Hebrew digit 9
- X00_S9 = 15, // A hundered number and followed by a digit 9
- S9_DQ = 16, // Hebrew digit 9 and followed by a double quote
- END = 100, // A terminial state is reached.
- }
-
- //
- // The state machine for Hebrew number pasing.
- //
- private static readonly HS[] s_numberPasingState =
- {
- // 400 300/200 100 90~10 8~1 6, 7, 9, ' "
- /* 0 */
- HS.S400, HS.X00, HS.X00, HS.X0, HS.X, HS.X, HS.X, HS.S9, HS._err, HS._err,
- /* 1: S400 */
- HS.S400_400, HS.S400_X00, HS.S400_X00, HS.S400_X0, HS._err, HS._err, HS._err, HS.X00_S9 ,HS.END, HS.S400_DQ,
- /* 2: S400_400 */
- HS._err, HS._err, HS.S400_400_100,HS.S400_X0, HS._err, HS._err, HS._err, HS.X00_S9 ,HS._err, HS.S400_400_DQ,
- /* 3: S400_X00 */
- HS._err, HS._err, HS._err, HS.S400_X00_X0, HS._err, HS._err, HS._err, HS.X00_S9 ,HS._err, HS.X00_DQ,
- /* 4: S400_X0 */
- HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.X0_DQ,
- /* 5: X00_DQ */
- HS._err, HS._err, HS._err, HS.END, HS.END, HS.END, HS.END, HS.END, HS._err, HS._err,
- /* 6: S400_X00_X0 */
- HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.X0_DQ,
- /* 7: X0_DQ */
- HS._err, HS._err, HS._err, HS._err, HS.END, HS.END, HS.END, HS.END, HS._err, HS._err,
- /* 8: X */
- HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.END, HS._err,
- /* 9: X0 */
- HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.END, HS.X0_DQ,
- /* 10: X00 */
- HS._err, HS._err, HS._err, HS.S400_X0, HS._err, HS._err, HS._err, HS.X00_S9, HS.END, HS.X00_DQ,
- /* 11: S400_DQ */
- HS.END, HS.END, HS.END, HS.END, HS.END, HS.END, HS.END, HS.END, HS._err, HS._err,
- /* 12: S400_400_DQ*/
- HS._err, HS._err, HS.END, HS.END, HS.END, HS.END, HS.END, HS.END, HS._err, HS._err,
- /* 13: S400_400_100*/
- HS._err, HS._err, HS._err, HS.S400_X00_X0, HS._err, HS._err, HS._err, HS.X00_S9, HS._err, HS.X00_DQ,
- /* 14: S9 */
- HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.END, HS.S9_DQ,
- /* 15: X00_S9 */
- HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.S9_DQ,
- /* 16: S9_DQ */
- HS._err, HS._err, HS._err, HS._err, HS._err, HS.END, HS.END, HS._err, HS._err, HS._err
- };
-
- // Count of valid HebrewToken, column count in the NumberPasingState array
- private const int HebrewTokenCount = 10;
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Actions:
- // Parse the Hebrew number by passing one character at a time.
- // The state between characters are maintained at HebrewNumberPasingContext.
- // Returns:
- // Return a enum of HebrewNumberParsingState.
- // NotHebrewDigit: The specified ch is not a valid Hebrew digit.
- // InvalidHebrewNumber: After parsing the specified ch, it will lead into
- // an invalid Hebrew number text.
- // FoundEndOfHebrewNumber: A terminal state is reached. This means that
- // we find a valid Hebrew number text after the specified ch is parsed.
- // ContinueParsing: The specified ch is a valid Hebrew digit, and
- // it will lead into a valid state in the state machine, we should
- // continue to parse incoming characters.
- //
- ////////////////////////////////////////////////////////////////////////
-
- internal static HebrewNumberParsingState ParseByChar(char ch, ref HebrewNumberParsingContext context)
- {
- Debug.Assert(s_numberPasingState.Length == HebrewTokenCount * ((int)HS.S9_DQ + 1));
-
- HebrewToken token;
- if (ch == '\'')
- {
- token = HebrewToken.SingleQuote;
- }
- else if (ch == '\"')
- {
- token = HebrewToken.DoubleQuote;
- }
- else
- {
- int index = (int)ch - minHebrewNumberCh;
- if (index >= 0 && index < s_hebrewValues.Length)
- {
- token = s_hebrewValues[index].token;
- if (token == HebrewToken.Invalid)
- {
- return (HebrewNumberParsingState.NotHebrewDigit);
- }
- context.result += s_hebrewValues[index].value;
- }
- else
- {
- // Not in valid Hebrew digit range.
- return (HebrewNumberParsingState.NotHebrewDigit);
- }
- }
- context.state = s_numberPasingState[(int)context.state * (int)HebrewTokenCount + (int)token];
- if (context.state == HS._err)
- {
- // Invalid Hebrew state. This indicates an incorrect Hebrew number.
- return (HebrewNumberParsingState.InvalidHebrewNumber);
- }
- if (context.state == HS.END)
- {
- // Reach a terminal state.
- return (HebrewNumberParsingState.FoundEndOfHebrewNumber);
- }
- // We should continue to parse.
- return (HebrewNumberParsingState.ContinueParsing);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Actions:
- // Check if the ch is a valid Hebrew number digit.
- // This function will return true if the specified char is a legal Hebrew
- // digit character, single quote, or double quote.
- // Returns:
- // true if the specified character is a valid Hebrew number character.
- //
- ////////////////////////////////////////////////////////////////////////
-
- internal static bool IsDigit(char ch)
- {
- if (ch >= minHebrewNumberCh && ch <= s_maxHebrewNumberCh)
- {
- return (s_hebrewValues[ch - minHebrewNumberCh].value >= 0);
- }
- return (ch == '\'' || ch == '\"');
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/HijriCalendar.Win32.cs b/src/mscorlib/corefx/System/Globalization/HijriCalendar.Win32.cs
deleted file mode 100644
index 869b809bff..0000000000
--- a/src/mscorlib/corefx/System/Globalization/HijriCalendar.Win32.cs
+++ /dev/null
@@ -1,96 +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 Microsoft.Win32;
-
-namespace System.Globalization
-{
- public partial class HijriCalendar : Calendar
- {
- private int GetHijriDateAdjustment()
- {
- if (_hijriAdvance == Int32.MinValue)
- {
- // Never been set before. Use the system value from registry.
- _hijriAdvance = GetAdvanceHijriDate();
- }
- return (_hijriAdvance);
- }
-
- private const String InternationalRegKey = "Control Panel\\International";
- private const String HijriAdvanceRegKeyEntry = "AddHijriDate";
-
- /*=================================GetAdvanceHijriDate==========================
- **Action: Gets the AddHijriDate value from the registry.
- **Returns:
- **Arguments: None.
- **Exceptions:
- **Note:
- ** The HijriCalendar has a user-overidable calculation. That is, use can set a value from the control
- ** panel, so that the calculation of the Hijri Calendar can move ahead or backwards from -2 to +2 days.
- **
- ** The valid string values in the registry are:
- ** "AddHijriDate-2" => Add -2 days to the current calculated Hijri date.
- ** "AddHijriDate" => Add -1 day to the current calculated Hijri date.
- ** "" => Add 0 day to the current calculated Hijri date.
- ** "AddHijriDate+1" => Add +1 days to the current calculated Hijri date.
- ** "AddHijriDate+2" => Add +2 days to the current calculated Hijri date.
- ============================================================================*/
- private static int GetAdvanceHijriDate()
- {
- int hijriAdvance = 0;
- Microsoft.Win32.RegistryKey key = null;
-
- try
- {
- // Open in read-only mode.
- // Use InternalOpenSubKey so that we avoid the security check.
- key = RegistryKey.GetBaseKey(RegistryKey.HKEY_CURRENT_USER).OpenSubKey(InternationalRegKey, false);
- }
- //If this fails for any reason, we'll just return 0.
- catch (ObjectDisposedException) { return 0; }
- catch (ArgumentException) { return 0; }
-
- if (key != null)
- {
- try
- {
- Object value = key.InternalGetValue(HijriAdvanceRegKeyEntry, null, false, false);
- if (value == null)
- {
- return (0);
- }
- String str = value.ToString();
- if (String.Compare(str, 0, HijriAdvanceRegKeyEntry, 0, HijriAdvanceRegKeyEntry.Length, StringComparison.OrdinalIgnoreCase) == 0)
- {
- if (str.Length == HijriAdvanceRegKeyEntry.Length)
- hijriAdvance = -1;
- else
- {
- str = str.Substring(HijriAdvanceRegKeyEntry.Length);
- try
- {
- int advance = Int32.Parse(str.ToString(), CultureInfo.InvariantCulture);
- if ((advance >= MinAdvancedHijri) && (advance <= MaxAdvancedHijri))
- {
- hijriAdvance = advance;
- }
- }
- // If we got garbage from registry just ignore it.
- // hijriAdvance = 0 because of declaraction assignment up above.
- catch (ArgumentException) { }
- catch (FormatException) { }
- catch (OverflowException) { }
- }
- }
- }
- finally
- {
- key.Close();
- }
- }
- return (hijriAdvance);
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/HijriCalendar.cs b/src/mscorlib/corefx/System/Globalization/HijriCalendar.cs
deleted file mode 100644
index 0c72d9eaf5..0000000000
--- a/src/mscorlib/corefx/System/Globalization/HijriCalendar.cs
+++ /dev/null
@@ -1,679 +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.Versioning;
-using System.Diagnostics.Contracts;
-
-namespace System.Globalization
-{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Rules for the Hijri calendar:
- // - The Hijri calendar is a strictly Lunar calendar.
- // - Days begin at sunset.
- // - Islamic Year 1 (Muharram 1, 1 A.H.) is equivalent to absolute date
- // 227015 (Friday, July 16, 622 C.E. - Julian).
- // - Leap Years occur in the 2, 5, 7, 10, 13, 16, 18, 21, 24, 26, & 29th
- // years of a 30-year cycle. Year = leap iff ((11y+14) mod 30 < 11).
- // - There are 12 months which contain alternately 30 and 29 days.
- // - The 12th month, Dhu al-Hijjah, contains 30 days instead of 29 days
- // in a leap year.
- // - Common years have 354 days. Leap years have 355 days.
- // - There are 10,631 days in a 30-year cycle.
- // - The Islamic months are:
- // 1. Muharram (30 days) 7. Rajab (30 days)
- // 2. Safar (29 days) 8. Sha'ban (29 days)
- // 3. Rabi I (30 days) 9. Ramadan (30 days)
- // 4. Rabi II (29 days) 10. Shawwal (29 days)
- // 5. Jumada I (30 days) 11. Dhu al-Qada (30 days)
- // 6. Jumada II (29 days) 12. Dhu al-Hijjah (29 days) {30}
- //
- // NOTENOTE
- // The calculation of the HijriCalendar is based on the absolute date. And the
- // absolute date means the number of days from January 1st, 1 A.D.
- // Therefore, we do not support the days before the January 1st, 1 A.D.
- //
- ////////////////////////////////////////////////////////////////////////////
- /*
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 0622/07/18 9999/12/31
- ** Hijri 0001/01/01 9666/04/03
- */
-
- [Serializable]
- public partial class HijriCalendar : Calendar
- {
- public static readonly int HijriEra = 1;
-
- internal const int DatePartYear = 0;
- internal const int DatePartDayOfYear = 1;
- internal const int DatePartMonth = 2;
- internal const int DatePartDay = 3;
-
- internal const int MinAdvancedHijri = -2;
- internal const int MaxAdvancedHijri = 2;
-
- internal static readonly int[] HijriMonthDays = { 0, 30, 59, 89, 118, 148, 177, 207, 236, 266, 295, 325, 355 };
-
- private int _hijriAdvance = Int32.MinValue;
-
- // DateTime.MaxValue = Hijri calendar (year:9666, month: 4, day: 3).
- internal const int MaxCalendarYear = 9666;
- internal const int MaxCalendarMonth = 4;
- internal const int MaxCalendarDay = 3;
- // Hijri calendar (year: 1, month: 1, day:1 ) = Gregorian (year: 622, month: 7, day: 18)
- // This is the minimal Gregorian date that we support in the HijriCalendar.
- internal static readonly DateTime calendarMinValue = new DateTime(622, 7, 18);
- internal static readonly DateTime calendarMaxValue = DateTime.MaxValue;
-
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (calendarMinValue);
- }
- }
-
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (calendarMaxValue);
- }
- }
-
- public override CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.LunarCalendar;
- }
- }
-
- public HijriCalendar()
- {
- }
-
- internal override CalendarId ID
- {
- get
- {
- return CalendarId.HIJRI;
- }
- }
-
- protected override int DaysInYearBeforeMinSupportedYear
- {
- get
- {
- // the year before the 1st year of the cycle would have been the 30th year
- // of the previous cycle which is not a leap year. Common years have 354 days.
- return 354;
- }
- }
-
-
-
- /*=================================GetAbsoluteDateHijri==========================
- **Action: Gets the Absolute date for the given Hijri date. The absolute date means
- ** the number of days from January 1st, 1 A.D.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
-
- private long GetAbsoluteDateHijri(int y, int m, int d)
- {
- return (long)(DaysUpToHijriYear(y) + HijriMonthDays[m - 1] + d - 1 - HijriAdjustment);
- }
-
- /*=================================DaysUpToHijriYear==========================
- **Action: Gets the total number of days (absolute date) up to the given Hijri Year.
- ** The absolute date means the number of days from January 1st, 1 A.D.
- **Returns: Gets the total number of days (absolute date) up to the given Hijri Year.
- **Arguments: HijriYear year value in Hijri calendar.
- **Exceptions: None
- **Notes:
- ============================================================================*/
-
- private long DaysUpToHijriYear(int HijriYear)
- {
- long NumDays; // number of absolute days
- int NumYear30; // number of years up to current 30 year cycle
- int NumYearsLeft; // number of years into 30 year cycle
-
- //
- // Compute the number of years up to the current 30 year cycle.
- //
- NumYear30 = ((HijriYear - 1) / 30) * 30;
-
- //
- // Compute the number of years left. This is the number of years
- // into the 30 year cycle for the given year.
- //
- NumYearsLeft = HijriYear - NumYear30 - 1;
-
- //
- // Compute the number of absolute days up to the given year.
- //
- NumDays = ((NumYear30 * 10631L) / 30L) + 227013L;
- while (NumYearsLeft > 0)
- {
- // Common year is 354 days, and leap year is 355 days.
- NumDays += 354 + (IsLeapYear(NumYearsLeft, CurrentEra) ? 1 : 0);
- NumYearsLeft--;
- }
-
- //
- // Return the number of absolute days.
- //
- return (NumDays);
- }
-
- public int HijriAdjustment
- {
- get
- {
- if (_hijriAdvance == Int32.MinValue)
- {
- // Never been set before. Use the system value from registry.
- _hijriAdvance = GetHijriDateAdjustment();
- }
- return (_hijriAdvance);
- }
-
- set
- {
- // NOTE: Check the value of Min/MaxAdavncedHijri with Arabic speakers to see if the assumption is good.
- if (value < MinAdvancedHijri || value > MaxAdvancedHijri)
- {
- throw new ArgumentOutOfRangeException(
- "HijriAdjustment",
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Bounds_Lower_Upper,
- MinAdvancedHijri,
- MaxAdvancedHijri));
- }
- Contract.EndContractBlock();
- VerifyWritable();
-
- _hijriAdvance = value;
- }
- }
-
- internal static void CheckTicksRange(long ticks)
- {
- if (ticks < calendarMinValue.Ticks || ticks > calendarMaxValue.Ticks)
- {
- throw new ArgumentOutOfRangeException(
- "time",
- String.Format(
- CultureInfo.InvariantCulture,
- SR.ArgumentOutOfRange_CalendarRange,
- calendarMinValue,
- calendarMaxValue));
- }
- }
-
- internal static void CheckEraRange(int era)
- {
- if (era != CurrentEra && era != HijriEra)
- {
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
- }
-
- internal static void CheckYearRange(int year, int era)
- {
- CheckEraRange(era);
- if (year < 1 || year > MaxCalendarYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 1,
- MaxCalendarYear));
- }
- }
-
- internal static void CheckYearMonthRange(int year, int month, int era)
- {
- CheckYearRange(year, era);
- if (year == MaxCalendarYear)
- {
- if (month > MaxCalendarMonth)
- {
- throw new ArgumentOutOfRangeException(
- nameof(month),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 1,
- MaxCalendarMonth));
- }
- }
-
- if (month < 1 || month > 12)
- {
- throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
- }
- }
-
- /*=================================GetDatePart==========================
- **Action: Returns a given date part of this <i>DateTime</i>. This method is used
- ** to compute the year, day-of-year, month, or day part.
- **Returns:
- **Arguments:
- **Exceptions: ArgumentException if part is incorrect.
- **Notes:
- ** First, we get the absolute date (the number of days from January 1st, 1 A.C) for the given ticks.
- ** Use the formula (((AbsoluteDate - 227013) * 30) / 10631) + 1, we can a rough value for the Hijri year.
- ** In order to get the exact Hijri year, we compare the exact absolute date for HijriYear and (HijriYear + 1).
- ** From here, we can get the correct Hijri year.
- ============================================================================*/
-
- internal virtual int GetDatePart(long ticks, int part)
- {
- int HijriYear; // Hijri year
- int HijriMonth; // Hijri month
- int HijriDay; // Hijri day
- long NumDays; // The calculation buffer in number of days.
-
- CheckTicksRange(ticks);
-
- //
- // Get the absolute date. The absolute date is the number of days from January 1st, 1 A.D.
- // 1/1/0001 is absolute date 1.
- //
- NumDays = ticks / GregorianCalendar.TicksPerDay + 1;
-
- //
- // See how much we need to backup or advance
- //
- NumDays += HijriAdjustment;
-
- //
- // Calculate the appromixate Hijri Year from this magic formula.
- //
- HijriYear = (int)(((NumDays - 227013) * 30) / 10631) + 1;
-
- long daysToHijriYear = DaysUpToHijriYear(HijriYear); // The absoulte date for HijriYear
- long daysOfHijriYear = GetDaysInYear(HijriYear, CurrentEra); // The number of days for (HijriYear+1) year.
-
- if (NumDays < daysToHijriYear)
- {
- daysToHijriYear -= daysOfHijriYear;
- HijriYear--;
- }
- else if (NumDays == daysToHijriYear)
- {
- HijriYear--;
- daysToHijriYear -= GetDaysInYear(HijriYear, CurrentEra);
- }
- else
- {
- if (NumDays > daysToHijriYear + daysOfHijriYear)
- {
- daysToHijriYear += daysOfHijriYear;
- HijriYear++;
- }
- }
- if (part == DatePartYear)
- {
- return (HijriYear);
- }
-
- //
- // Calculate the Hijri Month.
- //
-
- HijriMonth = 1;
- NumDays -= daysToHijriYear;
-
- if (part == DatePartDayOfYear)
- {
- return ((int)NumDays);
- }
-
- while ((HijriMonth <= 12) && (NumDays > HijriMonthDays[HijriMonth - 1]))
- {
- HijriMonth++;
- }
- HijriMonth--;
-
- if (part == DatePartMonth)
- {
- return (HijriMonth);
- }
-
- //
- // Calculate the Hijri Day.
- //
- HijriDay = (int)(NumDays - HijriMonthDays[HijriMonth - 1]);
-
- if (part == DatePartDay)
- {
- return (HijriDay);
- }
- // Incorrect part value.
- throw new InvalidOperationException(SR.InvalidOperation_DateTimeParsing);
- }
-
- // Returns the DateTime resulting from adding the given number of
- // months to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year and month parts of the specified DateTime by
- // value months, and, if required, adjusting the day part of the
- // resulting date downwards to the last day of the resulting month in the
- // resulting year. The time-of-day part of the result is the same as the
- // time-of-day part of the specified DateTime.
- //
- // In more precise terms, considering the specified DateTime to be of the
- // form y / m / d + t, where y is the
- // year, m is the month, d is the day, and t is the
- // time-of-day, the result is y1 / m1 / d1 + t,
- // where y1 and m1 are computed by adding value months
- // to y and m, and d1 is the largest value less than
- // or equal to d that denotes a valid day in month m1 of year
- // y1.
- //
-
- public override DateTime AddMonths(DateTime time, int months)
- {
- if (months < -120000 || months > 120000)
- {
- throw new ArgumentOutOfRangeException(
- nameof(months),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- -120000,
- 120000));
- }
- Contract.EndContractBlock();
- // Get the date in Hijri calendar.
- int y = GetDatePart(time.Ticks, DatePartYear);
- int m = GetDatePart(time.Ticks, DatePartMonth);
- int d = GetDatePart(time.Ticks, DatePartDay);
- int i = m - 1 + months;
- if (i >= 0)
- {
- m = i % 12 + 1;
- y = y + i / 12;
- }
- else
- {
- m = 12 + (i + 1) % 12;
- y = y + (i - 11) / 12;
- }
- int days = GetDaysInMonth(y, m);
- if (d > days)
- {
- d = days;
- }
- long ticks = GetAbsoluteDateHijri(y, m, d) * TicksPerDay + (time.Ticks % TicksPerDay);
- Calendar.CheckAddResult(ticks, MinSupportedDateTime, MaxSupportedDateTime);
- return (new DateTime(ticks));
- }
-
- // Returns the DateTime resulting from adding the given number of
- // years to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year part of the specified DateTime by value
- // years. If the month and day of the specified DateTime is 2/29, and if the
- // resulting year is not a leap year, the month and day of the resulting
- // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
- // parts of the result are the same as those of the specified DateTime.
- //
-
- public override DateTime AddYears(DateTime time, int years)
- {
- return (AddMonths(time, years * 12));
- }
-
- // Returns the day-of-month part of the specified DateTime. The returned
- // value is an integer between 1 and 31.
- //
-
- public override int GetDayOfMonth(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartDay));
- }
-
- // Returns the day-of-week part of the specified DateTime. The returned value
- // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
- // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
- // Thursday, 5 indicates Friday, and 6 indicates Saturday.
- //
-
- public override DayOfWeek GetDayOfWeek(DateTime time)
- {
- return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
- }
-
- // Returns the day-of-year part of the specified DateTime. The returned value
- // is an integer between 1 and 366.
- //
-
- public override int GetDayOfYear(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartDayOfYear));
- }
-
- // Returns the number of days in the month given by the year and
- // month arguments.
- //
- [Pure]
- public override int GetDaysInMonth(int year, int month, int era)
- {
- CheckYearMonthRange(year, month, era);
- if (month == 12)
- {
- // For the 12th month, leap year has 30 days, and common year has 29 days.
- return (IsLeapYear(year, CurrentEra) ? 30 : 29);
- }
- // Other months contain 30 and 29 days alternatively. The 1st month has 30 days.
- return (((month % 2) == 1) ? 30 : 29);
- }
-
- // Returns the number of days in the year given by the year argument for the current era.
- //
-
- public override int GetDaysInYear(int year, int era)
- {
- CheckYearRange(year, era);
- // Common years have 354 days. Leap years have 355 days.
- return (IsLeapYear(year, CurrentEra) ? 355 : 354);
- }
-
- // Returns the era for the specified DateTime value.
-
- public override int GetEra(DateTime time)
- {
- CheckTicksRange(time.Ticks);
- return (HijriEra);
- }
-
-
- public override int[] Eras
- {
- get
- {
- return (new int[] { HijriEra });
- }
- }
-
- // Returns the month part of the specified DateTime. The returned value is an
- // integer between 1 and 12.
- //
-
- public override int GetMonth(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartMonth));
- }
-
- // Returns the number of months in the specified year and era.
-
- public override int GetMonthsInYear(int year, int era)
- {
- CheckYearRange(year, era);
- return (12);
- }
-
- // Returns the year part of the specified DateTime. The returned value is an
- // integer between 1 and MaxCalendarYear.
- //
-
- public override int GetYear(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartYear));
- }
-
- // Checks whether a given day in the specified era is a leap day. This method returns true if
- // the date is a leap day, or false if not.
- //
-
- public override bool IsLeapDay(int year, int month, int day, int era)
- {
- // The year/month/era value checking is done in GetDaysInMonth().
- int daysInMonth = GetDaysInMonth(year, month, era);
- if (day < 1 || day > daysInMonth)
- {
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Day,
- daysInMonth,
- month));
- }
- return (IsLeapYear(year, era) && month == 12 && day == 30);
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
- public override int GetLeapMonth(int year, int era)
- {
- CheckYearRange(year, era);
- return (0);
- }
-
- // Checks whether a given month in the specified era is a leap month. This method returns true if
- // month is a leap month, or false if not.
- //
-
- public override bool IsLeapMonth(int year, int month, int era)
- {
- CheckYearMonthRange(year, month, era);
- return (false);
- }
-
- // Checks whether a given year in the specified era is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
-
- public override bool IsLeapYear(int year, int era)
- {
- CheckYearRange(year, era);
- return ((((year * 11) + 14) % 30) < 11);
- }
-
- // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
- //
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
- {
- // The year/month/era checking is done in GetDaysInMonth().
- int daysInMonth = GetDaysInMonth(year, month, era);
- if (day < 1 || day > daysInMonth)
- {
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Day,
- daysInMonth,
- month));
- }
-
- long lDate = GetAbsoluteDateHijri(year, month, day);
-
- if (lDate >= 0)
- {
- return (new DateTime(lDate * GregorianCalendar.TicksPerDay + TimeToTicks(hour, minute, second, millisecond)));
- }
- else
- {
- throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
- }
- }
-
- private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 1451;
-
-
- public override int TwoDigitYearMax
- {
- get
- {
- if (twoDigitYearMax == -1)
- {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
- }
- return (twoDigitYearMax);
- }
-
- set
- {
- VerifyWritable();
- if (value < 99 || value > MaxCalendarYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(value),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 99,
- MaxCalendarYear));
- }
- twoDigitYearMax = value;
- }
- }
-
-
- public override int ToFourDigitYear(int year)
- {
- if (year < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(year),
- SR.ArgumentOutOfRange_NeedNonNegNum);
- }
- Contract.EndContractBlock();
-
- if (year < 100)
- {
- return (base.ToFourDigitYear(year));
- }
-
- if (year > MaxCalendarYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 1,
- MaxCalendarYear));
- }
- return (year);
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/IdnMapping.Unix.cs b/src/mscorlib/corefx/System/Globalization/IdnMapping.Unix.cs
deleted file mode 100644
index 58f4ccadde..0000000000
--- a/src/mscorlib/corefx/System/Globalization/IdnMapping.Unix.cs
+++ /dev/null
@@ -1,134 +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.
-
-namespace System.Globalization
-{
- sealed partial class IdnMapping
- {
- private unsafe string GetAsciiCore(char* unicode, int count)
- {
- uint flags = Flags;
- CheckInvalidIdnCharacters(unicode, count, flags, nameof(unicode));
-
- const int StackallocThreshold = 512;
- // Each unicode character is represented by up to 3 ASCII chars
- // and the whole string is prefixed by "xn--" (length 4)
- int estimatedLength = (int)Math.Min(count * 3L + 4, StackallocThreshold);
- int actualLength;
- if (estimatedLength < StackallocThreshold)
- {
- char* outputStack = stackalloc char[estimatedLength];
- actualLength = Interop.GlobalizationInterop.ToAscii(flags, unicode, count, outputStack, estimatedLength);
- if (actualLength > 0 && actualLength <= estimatedLength)
- {
- return new string(outputStack, 0, actualLength);
- }
- }
- else
- {
- actualLength = Interop.GlobalizationInterop.ToAscii(flags, unicode, count, null, 0);
- }
- if (actualLength == 0)
- {
- throw new ArgumentException(SR.Argument_IdnIllegalName, nameof(unicode));
- }
-
- char[] outputHeap = new char[actualLength];
- fixed (char* pOutputHeap = outputHeap)
- {
- actualLength = Interop.GlobalizationInterop.ToAscii(flags, unicode, count, pOutputHeap, actualLength);
- if (actualLength == 0 || actualLength > outputHeap.Length)
- {
- throw new ArgumentException(SR.Argument_IdnIllegalName, nameof(unicode));
- }
- return new string(pOutputHeap, 0, actualLength);
- }
- }
-
- private unsafe string GetUnicodeCore(char* ascii, int count)
- {
- uint flags = Flags;
- CheckInvalidIdnCharacters(ascii, count, flags, nameof(ascii));
-
- const int StackAllocThreshold = 512;
- if (count < StackAllocThreshold)
- {
- char* output = stackalloc char[count];
- return GetUnicodeCore(ascii, count, flags, output, count, reattempt: true);
- }
- else
- {
- char[] output = new char[count];
- fixed (char* pOutput = output)
- {
- return GetUnicodeCore(ascii, count, flags, pOutput, count, reattempt: true);
- }
- }
- }
-
- private unsafe string GetUnicodeCore(char* ascii, int count, uint flags, char* output, int outputLength, bool reattempt)
- {
- int realLen = Interop.GlobalizationInterop.ToUnicode(flags, ascii, count, output, outputLength);
-
- if (realLen == 0)
- {
- throw new ArgumentException(SR.Argument_IdnIllegalName, nameof(ascii));
- }
- else if (realLen <= outputLength)
- {
- return new string(output, 0, realLen);
- }
- else if (reattempt)
- {
- char[] newOutput = new char[realLen];
- fixed (char* pNewOutput = newOutput)
- {
- return GetUnicodeCore(ascii, count, flags, pNewOutput, realLen, reattempt: false);
- }
- }
-
- throw new ArgumentException(SR.Argument_IdnIllegalName, nameof(ascii));
- }
-
- // -----------------------------
- // ---- PAL layer ends here ----
- // -----------------------------
-
- private uint Flags
- {
- get
- {
- int flags =
- (AllowUnassigned ? Interop.GlobalizationInterop.AllowUnassigned : 0) |
- (UseStd3AsciiRules ? Interop.GlobalizationInterop.UseStd3AsciiRules : 0);
- return (uint)flags;
- }
- }
-
- /// <summary>
- /// ICU doesn't check for invalid characters unless the STD3 rules option
- /// is enabled.
- ///
- /// To match Windows behavior, we walk the string ourselves looking for these
- /// bad characters so we can continue to throw ArgumentException in these cases.
- /// </summary>
- private static unsafe void CheckInvalidIdnCharacters(char* s, int count, uint flags, string paramName)
- {
- if ((flags & Interop.GlobalizationInterop.UseStd3AsciiRules) == 0)
- {
- for (int i = 0; i < count; i++)
- {
- char c = s[i];
-
- // These characters are prohibited regardless of the UseStd3AsciiRules property.
- // See https://msdn.microsoft.com/en-us/library/system.globalization.idnmapping.usestd3asciirules(v=vs.110).aspx
- if (c <= 0x1F || c == 0x7F)
- {
- throw new ArgumentException(SR.Argument_IdnIllegalName, paramName);
- }
- }
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/IdnMapping.Windows.cs b/src/mscorlib/corefx/System/Globalization/IdnMapping.Windows.cs
deleted file mode 100644
index 3d3292e3db..0000000000
--- a/src/mscorlib/corefx/System/Globalization/IdnMapping.Windows.cs
+++ /dev/null
@@ -1,113 +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.Diagnostics;
-using System.Runtime.InteropServices;
-
-namespace System.Globalization
-{
- public sealed partial class IdnMapping
- {
- private unsafe string GetAsciiCore(char* unicode, int count)
- {
- uint flags = Flags;
-
- // Determine the required length
- int length = Interop.mincore.IdnToAscii(flags, new IntPtr(unicode), count, IntPtr.Zero, 0);
- if (length == 0)
- {
- ThrowForZeroLength(nameof(unicode), SR.Argument_IdnIllegalName, SR.Argument_InvalidCharSequenceNoIndex);
- }
-
- // Do the conversion
- const int StackAllocThreshold = 512; // arbitrary limit to switch from stack to heap allocation
- if (length < StackAllocThreshold)
- {
- char* output = stackalloc char[length];
- return GetAsciiCore(unicode, count, flags, output, length);
- }
- else
- {
- char[] output = new char[length];
- fixed (char* pOutput = output)
- {
- return GetAsciiCore(unicode, count, flags, pOutput, length);
- }
- }
- }
-
- private unsafe string GetAsciiCore(char* unicode, int count, uint flags, char* output, int outputLength)
- {
- int length = Interop.mincore.IdnToAscii(flags, new IntPtr(unicode), count, new IntPtr(output), outputLength);
- if (length == 0)
- {
- ThrowForZeroLength(nameof(unicode), SR.Argument_IdnIllegalName, SR.Argument_InvalidCharSequenceNoIndex);
- }
- Debug.Assert(length == outputLength);
- return new string(output, 0, length);
- }
-
- private unsafe string GetUnicodeCore(char* ascii, int count)
- {
- uint flags = Flags;
-
- // Determine the required length
- int length = Interop.mincore.IdnToUnicode(flags, new IntPtr(ascii), count, IntPtr.Zero, 0);
- if (length == 0)
- {
- ThrowForZeroLength(nameof(ascii), SR.Argument_IdnIllegalName, SR.Argument_IdnBadPunycode);
- }
-
- // Do the conversion
- const int StackAllocThreshold = 512; // arbitrary limit to switch from stack to heap allocation
- if (length < StackAllocThreshold)
- {
- char* output = stackalloc char[length];
- return GetUnicodeCore(ascii, count, flags, output, length);
- }
- else
- {
- char[] output = new char[length];
- fixed (char* pOutput = output)
- {
- return GetUnicodeCore(ascii, count, flags, pOutput, length);
- }
- }
- }
-
- private unsafe string GetUnicodeCore(char* ascii, int count, uint flags, char* output, int outputLength)
- {
- int length = Interop.mincore.IdnToUnicode(flags, new IntPtr(ascii), count, new IntPtr(output), outputLength);
- if (length == 0)
- {
- ThrowForZeroLength(nameof(ascii), SR.Argument_IdnIllegalName, SR.Argument_IdnBadPunycode);
- }
- Debug.Assert(length == outputLength);
- return new string(output, 0, length);
- }
-
- // -----------------------------
- // ---- PAL layer ends here ----
- // -----------------------------
-
- private uint Flags
- {
- get
- {
- int flags =
- (AllowUnassigned ? Interop.mincore.IDN_ALLOW_UNASSIGNED : 0) |
- (UseStd3AsciiRules ? Interop.mincore.IDN_USE_STD3_ASCII_RULES : 0);
- return (uint)flags;
- }
- }
-
- private static void ThrowForZeroLength(string paramName, string invalidNameString, string otherString)
- {
- throw new ArgumentException(
- Marshal.GetLastWin32Error() == Interop.ERROR_INVALID_NAME ? invalidNameString : otherString,
- paramName);
- }
- }
-}
-
diff --git a/src/mscorlib/corefx/System/Globalization/IdnMapping.cs b/src/mscorlib/corefx/System/Globalization/IdnMapping.cs
deleted file mode 100644
index 8424472751..0000000000
--- a/src/mscorlib/corefx/System/Globalization/IdnMapping.cs
+++ /dev/null
@@ -1,152 +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.
-
-// This file contains the IDN functions and implementation.
-//
-// This allows encoding of non-ASCII domain names in a "punycode" form,
-// for example:
-//
-// \u5B89\u5BA4\u5948\u7F8E\u6075-with-SUPER-MONKEYS
-//
-// is encoded as:
-//
-// xn---with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n
-//
-// Additional options are provided to allow unassigned IDN characters and
-// to validate according to the Std3ASCII Rules (like DNS names).
-//
-// There are also rules regarding bidirectionality of text and the length
-// of segments.
-//
-// For additional rules see also:
-// RFC 3490 - Internationalizing Domain Names in Applications (IDNA)
-// RFC 3491 - Nameprep: A Stringprep Profile for Internationalized Domain Names (IDN)
-// RFC 3492 - Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)
-
-using System.Diagnostics.Contracts;
-
-namespace System.Globalization
-{
- // IdnMapping class used to map names to Punycode
- public sealed partial class IdnMapping
- {
- private bool _allowUnassigned;
- private bool _useStd3AsciiRules;
-
- public IdnMapping()
- {
- }
-
- public bool AllowUnassigned
- {
- get { return _allowUnassigned; }
- set { _allowUnassigned = value; }
- }
-
- public bool UseStd3AsciiRules
- {
- get { return _useStd3AsciiRules; }
- set { _useStd3AsciiRules = value; }
- }
-
- // Gets ASCII (Punycode) version of the string
- public string GetAscii(string unicode)
- {
- return GetAscii(unicode, 0);
- }
-
- public string GetAscii(string unicode, int index)
- {
- if (unicode == null)
- throw new ArgumentNullException(nameof(unicode));
- Contract.EndContractBlock();
- return GetAscii(unicode, index, unicode.Length - index);
- }
-
- public string GetAscii(string unicode, int index, int count)
- {
- if (unicode == null)
- throw new ArgumentNullException(nameof(unicode));
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0) ? nameof(index) : nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
- if (index > unicode.Length)
- throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
- if (index > unicode.Length - count)
- throw new ArgumentOutOfRangeException(nameof(unicode), SR.ArgumentOutOfRange_IndexCountBuffer);
- Contract.EndContractBlock();
-
- if (count == 0)
- {
- throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(unicode));
- }
- if (unicode[index + count - 1] == 0)
- {
- throw new ArgumentException(SR.Format(SR.Argument_InvalidCharSequence, index + count - 1), nameof(unicode));
- }
-
- unsafe
- {
- fixed (char* pUnicode = unicode)
- {
- return GetAsciiCore(pUnicode + index, count);
- }
- }
- }
-
- // Gets Unicode version of the string. Normalized and limited to IDNA characters.
- public string GetUnicode(string ascii)
- {
- return GetUnicode(ascii, 0);
- }
-
- public string GetUnicode(string ascii, int index)
- {
- if (ascii == null)
- throw new ArgumentNullException(nameof(ascii));
- Contract.EndContractBlock();
- return GetUnicode(ascii, index, ascii.Length - index);
- }
-
- public string GetUnicode(string ascii, int index, int count)
- {
- if (ascii == null)
- throw new ArgumentNullException(nameof(ascii));
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0) ? nameof(index) : nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
- if (index > ascii.Length)
- throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
- if (index > ascii.Length - count)
- throw new ArgumentOutOfRangeException(nameof(ascii), SR.ArgumentOutOfRange_IndexCountBuffer);
-
- // This is a case (i.e. explicitly null-terminated input) where behavior in .NET and Win32 intentionally differ.
- // The .NET APIs should (and did in v4.0 and earlier) throw an ArgumentException on input that includes a terminating null.
- // The Win32 APIs fail on an embedded null, but not on a terminating null.
- if (count > 0 && ascii[index + count - 1] == (char)0)
- throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
- Contract.EndContractBlock();
-
- unsafe
- {
- fixed (char* pAscii = ascii)
- {
- return GetUnicodeCore(pAscii + index, count);
- }
- }
- }
-
- public override bool Equals(object obj)
- {
- IdnMapping that = obj as IdnMapping;
- return
- that != null &&
- _allowUnassigned == that._allowUnassigned &&
- _useStd3AsciiRules == that._useStd3AsciiRules;
- }
-
- public override int GetHashCode()
- {
- return (_allowUnassigned ? 100 : 200) + (_useStd3AsciiRules ? 1000 : 2000);
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/InternalGlobalizationHelper.cs b/src/mscorlib/corefx/System/Globalization/InternalGlobalizationHelper.cs
deleted file mode 100644
index 0a4e6f0600..0000000000
--- a/src/mscorlib/corefx/System/Globalization/InternalGlobalizationHelper.cs
+++ /dev/null
@@ -1,50 +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;
-
-namespace System.Globalization
-{
- internal class InternalGloablizationHelper
- {
- // Copied from the TimeSpan to be used inside the globalization code and avoid internal dependancy on TimeSpan class
- internal static long TimeToTicks(int hour, int minute, int second)
- {
- // totalSeconds is bounded by 2^31 * 2^12 + 2^31 * 2^8 + 2^31,
- // which is less than 2^44, meaning we won't overflow totalSeconds.
- long totalSeconds = (long)hour * 3600 + (long)minute * 60 + (long)second;
- if (totalSeconds > MaxSeconds || totalSeconds < MinSeconds)
- throw new ArgumentOutOfRangeException(null, SR.Overflow_TimeSpanTooLong);
- return totalSeconds * TicksPerSecond;
- }
-
-
- //
- // Define needed constants so globalization code can be independant from any other types
- //
-
- internal const long TicksPerMillisecond = 10000;
- internal const long TicksPerTenthSecond = TicksPerMillisecond * 100;
- internal const long TicksPerSecond = TicksPerMillisecond * 1000; // 10,000,000
- internal const long MaxSeconds = Int64.MaxValue / TicksPerSecond;
- internal const long MinSeconds = Int64.MinValue / TicksPerSecond;
- private const int DaysPerYear = 365;
- private const int DaysPer4Years = DaysPerYear * 4 + 1; // 1461
- private const int DaysPer100Years = DaysPer4Years * 25 - 1; // 36524
- private const int DaysPer400Years = DaysPer100Years * 4 + 1; // 146097
- private const int DaysTo10000 = DaysPer400Years * 25 - 366; // 3652059
- private const long TicksPerMinute = TicksPerSecond * 60;
- private const long TicksPerHour = TicksPerMinute * 60;
- private const long TicksPerDay = TicksPerHour * 24;
- internal const long MaxTicks = DaysTo10000 * TicksPerDay - 1;
- internal const long MinTicks = 0;
- internal const long MaxMilliSeconds = Int64.MaxValue / TicksPerMillisecond;
- internal const long MinMilliSeconds = Int64.MinValue / TicksPerMillisecond;
-
- internal const int StringBuilderDefaultCapacity = 16;
-
- internal const Int64 MaxOffset = TimeSpan.TicksPerHour * 14;
- internal const Int64 MinOffset = -MaxOffset;
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Unix.cs b/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Unix.cs
deleted file mode 100644
index b9bd94af6e..0000000000
--- a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Unix.cs
+++ /dev/null
@@ -1,88 +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.Collections.Generic;
-
-namespace System.Globalization
-{
- public partial class JapaneseCalendar : Calendar
- {
- private static EraInfo[] GetJapaneseEras()
- {
- string[] eraNames;
- if (!CalendarData.EnumCalendarInfo("ja-JP", CalendarId.JAPAN, CalendarDataType.EraNames, out eraNames))
- {
- return null;
- }
-
- string[] abbrevEnglishEraNames;
- if (!CalendarData.EnumCalendarInfo("en", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames, out abbrevEnglishEraNames))
- {
- return null;
- }
-
- List<EraInfo> eras = new List<EraInfo>();
- int lastMaxYear = GregorianCalendar.MaxYear;
-
- int latestEra = Interop.GlobalizationInterop.GetLatestJapaneseEra();
- for (int i = latestEra; i >= 0; i--)
- {
- DateTime dt;
- if (!GetJapaneseEraStartDate(i, out dt))
- {
- return null;
- }
-
- if (dt < JapaneseCalendar.calendarMinValue)
- {
- // only populate the Eras that are valid JapaneseCalendar date times
- break;
- }
-
- eras.Add(new EraInfo(i, dt.Year, dt.Month, dt.Day, dt.Year - 1, 1, lastMaxYear - dt.Year + 1,
- eraNames[i], GetAbbreviatedEraName(eraNames, i), abbrevEnglishEraNames[i]));
-
- lastMaxYear = dt.Year;
- }
-
- // remap the Era numbers, now that we know how many there will be
- for (int i = 0; i < eras.Count; i++)
- {
- eras[i].era = eras.Count - i;
- }
-
- return eras.ToArray();
- }
-
- // PAL Layer ends here
-
- private static string GetAbbreviatedEraName(string[] eraNames, int eraIndex)
- {
- // This matches the behavior on Win32 - only returning the first character of the era name.
- // See Calendar.EraAsString(Int32) - https://msdn.microsoft.com/en-us/library/windows/apps/br206751.aspx
- return eraNames[eraIndex].Substring(0, 1);
- }
-
- private static bool GetJapaneseEraStartDate(int era, out DateTime dateTime)
- {
- dateTime = default(DateTime);
-
- int startYear;
- int startMonth;
- int startDay;
- bool result = Interop.GlobalizationInterop.GetJapaneseEraStartDate(
- era,
- out startYear,
- out startMonth,
- out startDay);
-
- if (result)
- {
- dateTime = new DateTime(startYear, startMonth, startDay);
- }
-
- return result;
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Win32.cs b/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Win32.cs
deleted file mode 100644
index a83c4fad9e..0000000000
--- a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.Win32.cs
+++ /dev/null
@@ -1,209 +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.Diagnostics;
-
-using Microsoft.Win32;
-
-namespace System.Globalization
-{
- public partial class JapaneseCalendar : Calendar
- {
- private const string c_japaneseErasHive = @"System\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras";
- private const string c_japaneseErasHivePermissionList = @"HKEY_LOCAL_MACHINE\" + c_japaneseErasHive;
-
- // We know about 4 built-in eras, however users may add additional era(s) from the
- // registry, by adding values to HKLM\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras
- //
- // Registry values look like:
- // yyyy.mm.dd=era_abbrev_english_englishabbrev
- //
- // Where yyyy.mm.dd is the registry value name, and also the date of the era start.
- // yyyy, mm, and dd are the year, month & day the era begins (4, 2 & 2 digits long)
- // era is the Japanese Era name
- // abbrev is the Abbreviated Japanese Era Name
- // english is the English name for the Era (unused)
- // englishabbrev is the Abbreviated English name for the era.
- // . is a delimiter, but the value of . doesn't matter.
- // '_' marks the space between the japanese era name, japanese abbreviated era name
- // english name, and abbreviated english names.
- private static EraInfo[] GetJapaneseEras()
- {
- // Look in the registry key and see if we can find any ranges
- int iFoundEras = 0;
- EraInfo[] registryEraRanges = null;
-
- try
- {
- // Need to access registry
- RegistryKey key = RegistryKey.GetBaseKey(RegistryKey.HKEY_LOCAL_MACHINE).OpenSubKey(c_japaneseErasHive, false);
-
- // Abort if we didn't find anything
- if (key == null) return null;
-
- // Look up the values in our reg key
- String[] valueNames = key.GetValueNames();
- if (valueNames != null && valueNames.Length > 0)
- {
- registryEraRanges = new EraInfo[valueNames.Length];
-
- // Loop through the registry and read in all the values
- for (int i = 0; i < valueNames.Length; i++)
- {
- // See if the era is a valid date
- EraInfo era = GetEraFromValue(valueNames[i], key.GetValue(valueNames[i]).ToString());
-
- // continue if not valid
- if (era == null) continue;
-
- // Remember we found one.
- registryEraRanges[iFoundEras] = era;
- iFoundEras++;
- }
- }
- }
- catch (System.Security.SecurityException)
- {
- // If we weren't allowed to read, then just ignore the error
- return null;
- }
- catch (System.IO.IOException)
- {
- // If key is being deleted just ignore the error
- return null;
- }
- catch (System.UnauthorizedAccessException)
- {
- // Registry access rights permissions, just ignore the error
- return null;
- }
-
- //
- // If we didn't have valid eras, then fail
- // should have at least 4 eras
- //
- if (iFoundEras < 4) return null;
-
- //
- // Now we have eras, clean them up.
- //
- // Clean up array length
- Array.Resize(ref registryEraRanges, iFoundEras);
-
- // Sort them
- Array.Sort(registryEraRanges, CompareEraRanges);
-
- // Clean up era information
- for (int i = 0; i < registryEraRanges.Length; i++)
- {
- // eras count backwards from length to 1 (and are 1 based indexes into string arrays)
- registryEraRanges[i].era = registryEraRanges.Length - i;
-
- // update max era year
- if (i == 0)
- {
- // First range is 'til the end of the calendar
- registryEraRanges[0].maxEraYear = GregorianCalendar.MaxYear - registryEraRanges[0].yearOffset;
- }
- else
- {
- // Rest are until the next era (remember most recent era is first in array)
- registryEraRanges[i].maxEraYear = registryEraRanges[i - 1].yearOffset + 1 - registryEraRanges[i].yearOffset;
- }
- }
-
- // Return our ranges
- return registryEraRanges;
- }
-
- //
- // Compare two era ranges, eg just the ticks
- // Remember the era array is supposed to be in reverse chronological order
- //
- private static int CompareEraRanges(EraInfo a, EraInfo b)
- {
- return b.ticks.CompareTo(a.ticks);
- }
-
- //
- // GetEraFromValue
- //
- // Parse the registry value name/data pair into an era
- //
- // Registry values look like:
- // yyyy.mm.dd=era_abbrev_english_englishabbrev
- //
- // Where yyyy.mm.dd is the registry value name, and also the date of the era start.
- // yyyy, mm, and dd are the year, month & day the era begins (4, 2 & 2 digits long)
- // era is the Japanese Era name
- // abbrev is the Abbreviated Japanese Era Name
- // english is the English name for the Era (unused)
- // englishabbrev is the Abbreviated English name for the era.
- // . is a delimiter, but the value of . doesn't matter.
- // '_' marks the space between the japanese era name, japanese abbreviated era name
- // english name, and abbreviated english names.
- private static EraInfo GetEraFromValue(String value, String data)
- {
- // Need inputs
- if (value == null || data == null) return null;
-
- //
- // Get Date
- //
- // Need exactly 10 characters in name for date
- // yyyy.mm.dd although the . can be any character
- if (value.Length != 10) return null;
-
- int year;
- int month;
- int day;
-
- if (!Int32.TryParse(value.Substring(0, 4), NumberStyles.None, NumberFormatInfo.InvariantInfo, out year) ||
- !Int32.TryParse(value.Substring(5, 2), NumberStyles.None, NumberFormatInfo.InvariantInfo, out month) ||
- !Int32.TryParse(value.Substring(8, 2), NumberStyles.None, NumberFormatInfo.InvariantInfo, out day))
- {
- // Couldn't convert integer, fail
- return null;
- }
-
- //
- // Get Strings
- //
- // Needs to be a certain length e_a_E_A at least (7 chars, exactly 4 groups)
- String[] names = data.Split('_');
-
- // Should have exactly 4 parts
- // 0 - Era Name
- // 1 - Abbreviated Era Name
- // 2 - English Era Name
- // 3 - Abbreviated English Era Name
- if (names.Length != 4) return null;
-
- // Each part should have data in it
- if (names[0].Length == 0 ||
- names[1].Length == 0 ||
- names[2].Length == 0 ||
- names[3].Length == 0)
- return null;
-
- //
- // Now we have an era we can build
- // Note that the era # and max era year need cleaned up after sorting
- // Don't use the full English Era Name (names[2])
- //
- return new EraInfo(0, year, month, day, year - 1, 1, 0,
- names[0], names[1], names[3]);
- }
-
- // PAL Layer ends here
-
- private static string[] s_japaneseErasEnglishNames = new String[] { "M", "T", "S", "H" };
-
- private static string GetJapaneseEnglishEraName(int era)
- {
- Debug.Assert(era > 0);
- return era <= s_japaneseErasEnglishNames.Length ? s_japaneseErasEnglishNames[era - 1] : " ";
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.cs b/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.cs
deleted file mode 100644
index f0216c8f51..0000000000
--- a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.cs
+++ /dev/null
@@ -1,411 +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.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Diagnostics.Contracts;
-
-namespace System.Globalization
-{
- /*=================================JapaneseCalendar==========================
- **
- ** JapaneseCalendar is based on Gregorian calendar. The month and day values are the same as
- ** Gregorian calendar. However, the year value is an offset to the Gregorian
- ** year based on the era.
- **
- ** This system is adopted by Emperor Meiji in 1868. The year value is counted based on the reign of an emperor,
- ** and the era begins on the day an emperor ascends the throne and continues until his death.
- ** The era changes at 12:00AM.
- **
- ** For example, the current era is Heisei. It started on 1989/1/8 A.D. Therefore, Gregorian year 1989 is also Heisei 1st.
- ** 1989/1/8 A.D. is also Heisei 1st 1/8.
- **
- ** Any date in the year during which era is changed can be reckoned in either era. For example,
- ** 1989/1/1 can be 1/1 Heisei 1st year or 1/1 Showa 64th year.
- **
- ** Note:
- ** The DateTime can be represented by the JapaneseCalendar are limited to two factors:
- ** 1. The min value and max value of DateTime class.
- ** 2. The available era information.
- **
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 1868/09/08 9999/12/31
- ** Japanese Meiji 01/01 Heisei 8011/12/31
- ============================================================================*/
-
-
- [Serializable]
- public partial class JapaneseCalendar : Calendar
- {
- internal static readonly DateTime calendarMinValue = new DateTime(1868, 9, 8);
-
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (calendarMinValue);
- }
- }
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (DateTime.MaxValue);
- }
- }
-
- public override CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.SolarCalendar;
- }
- }
-
- //
- // Using a field initializer rather than a static constructor so that the whole class can be lazy
- // init.
- internal static volatile EraInfo[] japaneseEraInfo;
-
- //
- // Read our era info
- //
- // m_EraInfo must be listed in reverse chronological order. The most recent era
- // should be the first element.
- // That is, m_EraInfo[0] contains the most recent era.
- //
- // We know about 4 built-in eras, however users may add additional era(s) from the
- // registry, by adding values to HKLM\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras
- // we don't read the registry and instead we call WinRT to get the needed informatio
- //
- // Registry values look like:
- // yyyy.mm.dd=era_abbrev_english_englishabbrev
- //
- // Where yyyy.mm.dd is the registry value name, and also the date of the era start.
- // yyyy, mm, and dd are the year, month & day the era begins (4, 2 & 2 digits long)
- // era is the Japanese Era name
- // abbrev is the Abbreviated Japanese Era Name
- // english is the English name for the Era (unused)
- // englishabbrev is the Abbreviated English name for the era.
- // . is a delimiter, but the value of . doesn't matter.
- // '_' marks the space between the japanese era name, japanese abbreviated era name
- // english name, and abbreviated english names.
- //
- internal static EraInfo[] GetEraInfo()
- {
- // See if we need to build it
- if (japaneseEraInfo == null)
- {
- japaneseEraInfo = GetJapaneseEras();
- // See if we have to use the built-in eras
- if (japaneseEraInfo == null)
- {
- // We know about some built-in ranges
- EraInfo[] defaultEraRanges = new EraInfo[4];
- defaultEraRanges[0] = new EraInfo(4, 1989, 1, 8, 1988, 1, GregorianCalendar.MaxYear - 1988,
- "\x5e73\x6210", "\x5e73", "H"); // era #4 start year/month/day, yearOffset, minEraYear
- defaultEraRanges[1] = new EraInfo(3, 1926, 12, 25, 1925, 1, 1989 - 1925,
- "\x662d\x548c", "\x662d", "S"); // era #3,start year/month/day, yearOffset, minEraYear
- defaultEraRanges[2] = new EraInfo(2, 1912, 7, 30, 1911, 1, 1926 - 1911,
- "\x5927\x6b63", "\x5927", "T"); // era #2,start year/month/day, yearOffset, minEraYear
- defaultEraRanges[3] = new EraInfo(1, 1868, 1, 1, 1867, 1, 1912 - 1867,
- "\x660e\x6cbb", "\x660e", "M"); // era #1,start year/month/day, yearOffset, minEraYear
-
- // Remember the ranges we built
- japaneseEraInfo = defaultEraRanges;
- }
- }
-
- // return the era we found/made
- return japaneseEraInfo;
- }
-
- internal static volatile Calendar s_defaultInstance;
- internal GregorianCalendarHelper helper;
-
- /*=================================GetDefaultInstance==========================
- **Action: Internal method to provide a default intance of JapaneseCalendar. Used by NLS+ implementation
- ** and other calendars.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
-
- internal static Calendar GetDefaultInstance()
- {
- if (s_defaultInstance == null)
- {
- s_defaultInstance = new JapaneseCalendar();
- }
- return (s_defaultInstance);
- }
-
-
- public JapaneseCalendar()
- {
- try
- {
- new CultureInfo("ja-JP");
- }
- catch (ArgumentException e)
- {
- throw new TypeInitializationException(this.GetType().ToString(), e);
- }
- helper = new GregorianCalendarHelper(this, GetEraInfo());
- }
-
- internal override CalendarId ID
- {
- get
- {
- return CalendarId.JAPAN;
- }
- }
-
-
- public override DateTime AddMonths(DateTime time, int months)
- {
- return (helper.AddMonths(time, months));
- }
-
-
- public override DateTime AddYears(DateTime time, int years)
- {
- return (helper.AddYears(time, years));
- }
-
- /*=================================GetDaysInMonth==========================
- **Action: Returns the number of days in the month given by the year and month arguments.
- **Returns: The number of days in the given month.
- **Arguments:
- ** year The year in Japanese calendar.
- ** month The month
- ** era The Japanese era value.
- **Exceptions
- ** ArgumentException If month is less than 1 or greater * than 12.
- ============================================================================*/
-
-
- public override int GetDaysInMonth(int year, int month, int era)
- {
- return (helper.GetDaysInMonth(year, month, era));
- }
-
-
- public override int GetDaysInYear(int year, int era)
- {
- return (helper.GetDaysInYear(year, era));
- }
-
-
- public override int GetDayOfMonth(DateTime time)
- {
- return (helper.GetDayOfMonth(time));
- }
-
-
- public override DayOfWeek GetDayOfWeek(DateTime time)
- {
- return (helper.GetDayOfWeek(time));
- }
-
-
- public override int GetDayOfYear(DateTime time)
- {
- return (helper.GetDayOfYear(time));
- }
-
-
- public override int GetMonthsInYear(int year, int era)
- {
- return (helper.GetMonthsInYear(year, era));
- }
-
-
- [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
- public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
- {
- return (helper.GetWeekOfYear(time, rule, firstDayOfWeek));
- }
-
- /*=================================GetEra==========================
- **Action: Get the era value of the specified time.
- **Returns: The era value for the specified time.
- **Arguments:
- ** time the specified date time.
- **Exceptions: ArgumentOutOfRangeException if time is out of the valid era ranges.
- ============================================================================*/
-
-
- public override int GetEra(DateTime time)
- {
- return (helper.GetEra(time));
- }
-
-
- public override int GetMonth(DateTime time)
- {
- return (helper.GetMonth(time));
- }
-
-
- public override int GetYear(DateTime time)
- {
- return (helper.GetYear(time));
- }
-
-
- public override bool IsLeapDay(int year, int month, int day, int era)
- {
- return (helper.IsLeapDay(year, month, day, era));
- }
-
-
- public override bool IsLeapYear(int year, int era)
- {
- return (helper.IsLeapYear(year, era));
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
- public override int GetLeapMonth(int year, int era)
- {
- return (helper.GetLeapMonth(year, era));
- }
-
-
- public override bool IsLeapMonth(int year, int month, int era)
- {
- return (helper.IsLeapMonth(year, month, era));
- }
-
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
- {
- return (helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era));
- }
-
- // For Japanese calendar, four digit year is not used. Few emperors will live for more than one hundred years.
- // Therefore, for any two digit number, we just return the original number.
-
- public override int ToFourDigitYear(int year)
- {
- if (year <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(year),
- SR.ArgumentOutOfRange_NeedPosNum);
- }
- Contract.EndContractBlock();
-
- if (year > helper.MaxYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 1,
- helper.MaxYear));
- }
- return (year);
- }
-
-
- public override int[] Eras
- {
- get
- {
- return (helper.Eras);
- }
- }
-
- //
- // Return the various era strings
- // Note: The arrays are backwards of the eras
- //
- internal static String[] EraNames()
- {
- EraInfo[] eras = GetEraInfo();
- String[] eraNames = new String[eras.Length];
-
- for (int i = 0; i < eras.Length; i++)
- {
- // Strings are in chronological order, eras are backwards order.
- eraNames[i] = eras[eras.Length - i - 1].eraName;
- }
-
- return eraNames;
- }
-
- internal static String[] AbbrevEraNames()
- {
- EraInfo[] eras = GetEraInfo();
- String[] erasAbbrev = new String[eras.Length];
-
- for (int i = 0; i < eras.Length; i++)
- {
- // Strings are in chronological order, eras are backwards order.
- erasAbbrev[i] = eras[eras.Length - i - 1].abbrevEraName;
- }
-
- return erasAbbrev;
- }
-
- internal static String[] EnglishEraNames()
- {
- EraInfo[] eras = GetEraInfo();
- String[] erasEnglish = new String[eras.Length];
-
- for (int i = 0; i < eras.Length; i++)
- {
- // Strings are in chronological order, eras are backwards order.
- erasEnglish[i] = eras[eras.Length - i - 1].englishEraName;
- }
-
- return erasEnglish;
- }
-
- private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 99;
-
- internal override bool IsValidYear(int year, int era)
- {
- return helper.IsValidYear(year, era);
- }
-
- public override int TwoDigitYearMax
- {
- get
- {
- if (twoDigitYearMax == -1)
- {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
- }
- return (twoDigitYearMax);
- }
-
- set
- {
- VerifyWritable();
- if (value < 99 || value > helper.MaxYear)
- {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 99,
- helper.MaxYear));
- }
- twoDigitYearMax = value;
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/JapaneseLunisolarCalendar.cs b/src/mscorlib/corefx/System/Globalization/JapaneseLunisolarCalendar.cs
deleted file mode 100644
index cc3d34954d..0000000000
--- a/src/mscorlib/corefx/System/Globalization/JapaneseLunisolarCalendar.cs
+++ /dev/null
@@ -1,311 +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.Diagnostics.Contracts;
-
-namespace System.Globalization
-{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about JapaneseLunisolarCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
- /*
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 1960/01/28 2050/01/22
- ** JapaneseLunisolar 1960/01/01 2049/12/29
- */
-
- [Serializable]
- public class JapaneseLunisolarCalendar : EastAsianLunisolarCalendar
- {
- //
- // The era value for the current era.
- //
-
- public const int JapaneseEra = 1;
-
- internal GregorianCalendarHelper helper;
-
- internal const int MIN_LUNISOLAR_YEAR = 1960;
- internal const int MAX_LUNISOLAR_YEAR = 2049;
-
- internal const int MIN_GREGORIAN_YEAR = 1960;
- internal const int MIN_GREGORIAN_MONTH = 1;
- internal const int MIN_GREGORIAN_DAY = 28;
-
- internal const int MAX_GREGORIAN_YEAR = 2050;
- internal const int MAX_GREGORIAN_MONTH = 1;
- internal const int MAX_GREGORIAN_DAY = 22;
-
- internal static DateTime minDate = new DateTime(MIN_GREGORIAN_YEAR, MIN_GREGORIAN_MONTH, MIN_GREGORIAN_DAY);
- internal static DateTime maxDate = new DateTime((new DateTime(MAX_GREGORIAN_YEAR, MAX_GREGORIAN_MONTH, MAX_GREGORIAN_DAY, 23, 59, 59, 999)).Ticks + 9999);
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (minDate);
- }
- }
-
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (maxDate);
- }
- }
- protected override int DaysInYearBeforeMinSupportedYear
- {
- get
- {
- // 1959 from ChineseLunisolarCalendar
- return 354;
- }
- }
-
- private static readonly int[,] s_yinfo =
- {
- /*Y LM Lmon Lday DaysPerMonth D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 #Days
- 1960 */
- { 6 , 1 , 28 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1961 */{ 0 , 2 , 15 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1962 */{ 0 , 2 , 5 , 19808 },/* 29 30 29 29 30 30 29 30 29 30 30 29 0 354
-1963 */{ 4 , 1 , 25 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1964 */{ 0 , 2 , 13 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1965 */{ 0 , 2 , 2 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
-1966 */{ 3 , 1 , 22 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 29 383
-1967 */{ 0 , 2 , 9 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1968 */{ 7 , 1 , 30 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
-1969 */{ 0 , 2 , 17 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1970 */{ 0 , 2 , 6 , 39632 },/* 30 29 29 30 30 29 30 29 30 30 29 30 0 355
-1971 */{ 5 , 1 , 27 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1972 */{ 0 , 2 , 15 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1973 */{ 0 , 2 , 3 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
-1974 */{ 4 , 1 , 23 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1975 */{ 0 , 2 , 11 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1976 */{ 8 , 1 , 31 , 54600 },/* 30 30 29 30 29 30 29 30 29 30 29 29 30 384
-1977 */{ 0 , 2 , 18 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1978 */{ 0 , 2 , 7 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 0 355
-1979 */{ 6 , 1 , 28 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1980 */{ 0 , 2 , 16 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1981 */{ 0 , 2 , 5 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1982 */{ 4 , 1 , 25 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1983 */{ 0 , 2 , 13 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1984 */{ 10 , 2 , 2 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1985 */{ 0 , 2 , 20 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1986 */{ 0 , 2 , 9 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1987 */{ 6 , 1 , 29 , 46504 },/* 30 29 30 30 29 30 29 30 30 29 30 29 30 385
-1988 */{ 0 , 2 , 18 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1989 */{ 0 , 2 , 6 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1990 */{ 5 , 1 , 27 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1991 */{ 0 , 2 , 15 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1992 */{ 0 , 2 , 4 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1993 */{ 3 , 1 , 23 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1994 */{ 0 , 2 , 10 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-1995 */{ 8 , 1 , 31 , 27976 },/* 29 30 30 29 30 30 29 30 29 30 29 29 30 384
-1996 */{ 0 , 2 , 19 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
-1997 */{ 0 , 2 , 8 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1998 */{ 5 , 1 , 28 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
-1999 */{ 0 , 2 , 16 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-2000 */{ 0 , 2 , 5 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-2001 */{ 4 , 1 , 24 , 58536 },/* 30 30 30 29 29 30 29 29 30 29 30 29 30 384
-2002 */{ 0 , 2 , 12 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-2003 */{ 0 , 2 , 1 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-2004 */{ 2 , 1 , 22 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-2005 */{ 0 , 2 , 9 , 22208 },/* 29 30 29 30 29 30 30 29 30 30 29 29 0 354
-2006 */{ 7 , 1 , 29 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
-2007 */{ 0 , 2 , 18 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-2008 */{ 0 , 2 , 7 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-2009 */{ 5 , 1 , 26 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-2010 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-2011 */{ 0 , 2 , 3 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-2012 */{ 3 , 1 , 23 , 47696 },/* 30 29 30 30 30 29 30 29 29 30 29 30 29 384
-2013 */{ 0 , 2 , 10 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-2014 */{ 9 , 1 , 31 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-2015 */{ 0 , 2 , 19 , 19360 },/* 29 30 29 29 30 29 30 30 30 29 30 29 0 354
-2016 */{ 0 , 2 , 8 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-2017 */{ 5 , 1 , 28 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-2018 */{ 0 , 2 , 16 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-2019 */{ 0 , 2 , 5 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-2020 */{ 4 , 1 , 25 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-2021 */{ 0 , 2 , 12 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-2022 */{ 0 , 2 , 1 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2023 */{ 2 , 1 , 22 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-2024 */{ 0 , 2 , 10 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-2025 */{ 6 , 1 , 29 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-2026 */{ 0 , 2 , 17 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-2027 */{ 0 , 2 , 7 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
-2028 */{ 5 , 1 , 27 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 29 383
-2029 */{ 0 , 2 , 13 , 55600 },/* 30 30 29 30 30 29 29 30 29 29 30 30 0 355
-2030 */{ 0 , 2 , 3 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-2031 */{ 3 , 1 , 23 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
-2032 */{ 0 , 2 , 11 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-2033 */{ 11 , 1 , 31 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-2034 */{ 0 , 2 , 19 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-2035 */{ 0 , 2 , 8 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-2036 */{ 6 , 1 , 28 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-2037 */{ 0 , 2 , 15 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-2038 */{ 0 , 2 , 4 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
-2039 */{ 5 , 1 , 24 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 29 384
-2040 */{ 0 , 2 , 12 , 46752 },/* 30 29 30 30 29 30 30 29 30 29 30 29 0 355
-2041 */{ 0 , 2 , 1 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-2042 */{ 2 , 1 , 22 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
-2043 */{ 0 , 2 , 10 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-2044 */{ 7 , 1 , 30 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-2045 */{ 0 , 2 , 17 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-2046 */{ 0 , 2 , 6 , 45648 },/* 30 29 30 30 29 29 30 29 29 30 29 30 0 354
-2047 */{ 5 , 1 , 26 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-2048 */{ 0 , 2 , 14 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-2049 */{ 0 , 2 , 2 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
- */ };
-
- internal override int MinCalendarYear
- {
- get
- {
- return (MIN_LUNISOLAR_YEAR);
- }
- }
-
- internal override int MaxCalendarYear
- {
- get
- {
- return (MAX_LUNISOLAR_YEAR);
- }
- }
-
- internal override DateTime MinDate
- {
- get
- {
- return (minDate);
- }
- }
-
- internal override DateTime MaxDate
- {
- get
- {
- return (maxDate);
- }
- }
-
- internal override EraInfo[] CalEraInfo
- {
- get
- {
- return (JapaneseCalendar.GetEraInfo());
- }
- }
-
- internal override int GetYearInfo(int lunarYear, int index)
- {
- if ((lunarYear < MIN_LUNISOLAR_YEAR) || (lunarYear > MAX_LUNISOLAR_YEAR))
- {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- MIN_LUNISOLAR_YEAR,
- MAX_LUNISOLAR_YEAR));
- }
- Contract.EndContractBlock();
-
- return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index];
- }
-
- internal override int GetYear(int year, DateTime time)
- {
- return helper.GetYear(year, time);
- }
-
- internal override int GetGregorianYear(int year, int era)
- {
- return helper.GetGregorianYear(year, era);
- }
-
- // Trim off the eras that are before our date range
- private static EraInfo[] TrimEras(EraInfo[] baseEras)
- {
- EraInfo[] newEras = new EraInfo[baseEras.Length];
- int newIndex = 0;
-
- // Eras have most recent first, so start with that
- for (int i = 0; i < baseEras.Length; i++)
- {
- // If this one's minimum year is bigger than our maximum year
- // then we can't use it.
- if (baseEras[i].yearOffset + baseEras[i].minEraYear >= MAX_LUNISOLAR_YEAR)
- {
- // skip this one.
- continue;
- }
-
- // If this one's maximum era is less than our minimum era
- // then we've gotten too low in the era #s, so we're done
- if (baseEras[i].yearOffset + baseEras[i].maxEraYear < MIN_LUNISOLAR_YEAR)
- {
- break;
- }
-
- // Wasn't too large or too small, can use this one
- newEras[newIndex] = baseEras[i];
- newIndex++;
- }
-
- // If we didn't copy any then something was wrong, just return base
- if (newIndex == 0) return baseEras;
-
- // Resize the output array
- Array.Resize(ref newEras, newIndex);
- return newEras;
- }
-
-
- // Construct an instance of JapaneseLunisolar calendar.
- public JapaneseLunisolarCalendar()
- {
- helper = new GregorianCalendarHelper(this, TrimEras(JapaneseCalendar.GetEraInfo()));
- }
-
-
- public override int GetEra(DateTime time)
- {
- return (helper.GetEra(time));
- }
-
- internal override CalendarId BaseCalendarID
- {
- get
- {
- return (CalendarId.JAPAN);
- }
- }
-
- internal override CalendarId ID
- {
- get
- {
- return (CalendarId.JAPANESELUNISOLAR);
- }
- }
-
-
- public override int[] Eras
- {
- get
- {
- return (helper.Eras);
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/JulianCalendar.cs b/src/mscorlib/corefx/System/Globalization/JulianCalendar.cs
deleted file mode 100644
index 43e6ad07a2..0000000000
--- a/src/mscorlib/corefx/System/Globalization/JulianCalendar.cs
+++ /dev/null
@@ -1,444 +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.Diagnostics.Contracts;
-
-namespace System.Globalization
-{
- //
- // This class implements the Julian calendar. In 48 B.C. Julius Caesar ordered a calendar reform, and this calendar
- // is called Julian calendar. It consisted of a solar year of twelve months and of 365 days with an extra day
- // every fourth year.
- //*
- //* Calendar support range:
- //* Calendar Minimum Maximum
- //* ========== ========== ==========
- //* Gregorian 0001/01/01 9999/12/31
- //* Julia 0001/01/03 9999/10/19
-
- [Serializable]
- public class JulianCalendar : Calendar
- {
- public static readonly int JulianEra = 1;
-
- private const int DatePartYear = 0;
- private const int DatePartDayOfYear = 1;
- private const int DatePartMonth = 2;
- private const int DatePartDay = 3;
-
- // Number of days in a non-leap year
- private const int JulianDaysPerYear = 365;
- // Number of days in 4 years
- private const int JulianDaysPer4Years = JulianDaysPerYear * 4 + 1;
-
- private static readonly int[] s_daysToMonth365 =
- {
- 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
- };
-
- private static readonly int[] s_daysToMonth366 =
- {
- 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366
- };
-
- // Gregorian Calendar 9999/12/31 = Julian Calendar 9999/10/19
- // keep it as variable field for serialization compat.
- internal int MaxYear = 9999;
-
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (DateTime.MinValue);
- }
- }
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (DateTime.MaxValue);
- }
- }
-
- public override CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.SolarCalendar;
- }
- }
-
- public JulianCalendar()
- {
- // There is no system setting of TwoDigitYear max, so set the value here.
- twoDigitYearMax = 2029;
- }
-
- internal override CalendarId ID
- {
- get
- {
- return CalendarId.JULIAN;
- }
- }
-
- internal static void CheckEraRange(int era)
- {
- if (era != CurrentEra && era != JulianEra)
- {
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
- }
-
- internal void CheckYearEraRange(int year, int era)
- {
- CheckEraRange(era);
- if (year <= 0 || year > MaxYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 1,
- MaxYear));
- }
- }
-
- internal static void CheckMonthRange(int month)
- {
- if (month < 1 || month > 12)
- {
- throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
- }
- }
-
- /*===================================CheckDayRange============================
- **Action: Check for if the day value is valid.
- **Returns:
- **Arguments:
- **Exceptions:
- **Notes:
- ** Before calling this method, call CheckYearEraRange()/CheckMonthRange() to make
- ** sure year/month values are correct.
- ============================================================================*/
-
- internal static void CheckDayRange(int year, int month, int day)
- {
- if (year == 1 && month == 1)
- {
- // The mimimum supported Julia date is Julian 0001/01/03.
- if (day < 3)
- {
- throw new ArgumentOutOfRangeException(null,
- SR.ArgumentOutOfRange_BadYearMonthDay);
- }
- }
- bool isLeapYear = (year % 4) == 0;
- int[] days = isLeapYear ? s_daysToMonth366 : s_daysToMonth365;
- int monthDays = days[month] - days[month - 1];
- if (day < 1 || day > monthDays)
- {
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 1,
- monthDays));
- }
- }
-
-
- // Returns a given date part of this DateTime. This method is used
- // to compute the year, day-of-year, month, or day part.
- internal static int GetDatePart(long ticks, int part)
- {
- // Gregorian 1/1/0001 is Julian 1/3/0001. Remember DateTime(0) is refered to Gregorian 1/1/0001.
- // The following line convert Gregorian ticks to Julian ticks.
- long julianTicks = ticks + TicksPerDay * 2;
- // n = number of days since 1/1/0001
- int n = (int)(julianTicks / TicksPerDay);
- // y4 = number of whole 4-year periods within 100-year period
- int y4 = n / JulianDaysPer4Years;
- // n = day number within 4-year period
- n -= y4 * JulianDaysPer4Years;
- // y1 = number of whole years within 4-year period
- int y1 = n / JulianDaysPerYear;
- // Last year has an extra day, so decrement result if 4
- if (y1 == 4) y1 = 3;
- // If year was requested, compute and return it
- if (part == DatePartYear)
- {
- return (y4 * 4 + y1 + 1);
- }
- // n = day number within year
- n -= y1 * JulianDaysPerYear;
- // If day-of-year was requested, return it
- if (part == DatePartDayOfYear)
- {
- return (n + 1);
- }
- // Leap year calculation looks different from IsLeapYear since y1, y4,
- // and y100 are relative to year 1, not year 0
- bool leapYear = (y1 == 3);
- int[] days = leapYear ? s_daysToMonth366 : s_daysToMonth365;
- // All months have less than 32 days, so n >> 5 is a good conservative
- // estimate for the month
- int m = (n >> 5) + 1;
- // m = 1-based month number
- while (n >= days[m]) m++;
- // If month was requested, return it
- if (part == DatePartMonth) return (m);
- // Return 1-based day-of-month
- return (n - days[m - 1] + 1);
- }
-
- // Returns the tick count corresponding to the given year, month, and day.
- internal static long DateToTicks(int year, int month, int day)
- {
- int[] days = (year % 4 == 0) ? s_daysToMonth366 : s_daysToMonth365;
- int y = year - 1;
- int n = y * 365 + y / 4 + days[month - 1] + day - 1;
- // Gregorian 1/1/0001 is Julian 1/3/0001. n * TicksPerDay is the ticks in JulianCalendar.
- // Therefore, we subtract two days in the following to convert the ticks in JulianCalendar
- // to ticks in Gregorian calendar.
- return ((n - 2) * TicksPerDay);
- }
-
-
- public override DateTime AddMonths(DateTime time, int months)
- {
- if (months < -120000 || months > 120000)
- {
- throw new ArgumentOutOfRangeException(
- nameof(months),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- -120000,
- 120000));
- }
- Contract.EndContractBlock();
- int y = GetDatePart(time.Ticks, DatePartYear);
- int m = GetDatePart(time.Ticks, DatePartMonth);
- int d = GetDatePart(time.Ticks, DatePartDay);
- int i = m - 1 + months;
- if (i >= 0)
- {
- m = i % 12 + 1;
- y = y + i / 12;
- }
- else
- {
- m = 12 + (i + 1) % 12;
- y = y + (i - 11) / 12;
- }
- int[] daysArray = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? s_daysToMonth366 : s_daysToMonth365;
- int days = (daysArray[m] - daysArray[m - 1]);
-
- if (d > days)
- {
- d = days;
- }
- long ticks = DateToTicks(y, m, d) + time.Ticks % TicksPerDay;
- Calendar.CheckAddResult(ticks, MinSupportedDateTime, MaxSupportedDateTime);
- return (new DateTime(ticks));
- }
-
-
- public override DateTime AddYears(DateTime time, int years)
- {
- return (AddMonths(time, years * 12));
- }
-
-
- public override int GetDayOfMonth(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartDay));
- }
-
-
- public override DayOfWeek GetDayOfWeek(DateTime time)
- {
- return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
- }
-
-
- public override int GetDayOfYear(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartDayOfYear));
- }
-
-
- public override int GetDaysInMonth(int year, int month, int era)
- {
- CheckYearEraRange(year, era);
- CheckMonthRange(month);
- int[] days = (year % 4 == 0) ? s_daysToMonth366 : s_daysToMonth365;
- return (days[month] - days[month - 1]);
- }
-
-
- public override int GetDaysInYear(int year, int era)
- {
- // Year/Era range is done in IsLeapYear().
- return (IsLeapYear(year, era) ? 366 : 365);
- }
-
-
- public override int GetEra(DateTime time)
- {
- return (JulianEra);
- }
-
-
- public override int GetMonth(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartMonth));
- }
-
-
- public override int[] Eras
- {
- get
- {
- return (new int[] { JulianEra });
- }
- }
-
-
- public override int GetMonthsInYear(int year, int era)
- {
- CheckYearEraRange(year, era);
- return (12);
- }
-
-
- public override int GetYear(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartYear));
- }
-
-
- public override bool IsLeapDay(int year, int month, int day, int era)
- {
- CheckMonthRange(month);
- // Year/Era range check is done in IsLeapYear().
- if (IsLeapYear(year, era))
- {
- CheckDayRange(year, month, day);
- return (month == 2 && day == 29);
- }
- CheckDayRange(year, month, day);
- return (false);
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
- public override int GetLeapMonth(int year, int era)
- {
- CheckYearEraRange(year, era);
- return (0);
- }
-
-
- public override bool IsLeapMonth(int year, int month, int era)
- {
- CheckYearEraRange(year, era);
- CheckMonthRange(month);
- return (false);
- }
-
- // Checks whether a given year in the specified era is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
-
- public override bool IsLeapYear(int year, int era)
- {
- CheckYearEraRange(year, era);
- return (year % 4 == 0);
- }
-
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
- {
- CheckYearEraRange(year, era);
- CheckMonthRange(month);
- CheckDayRange(year, month, day);
- if (millisecond < 0 || millisecond >= MillisPerSecond)
- {
- throw new ArgumentOutOfRangeException(
- nameof(millisecond),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- MillisPerSecond - 1));
- }
-
- if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >= 0 && second < 60)
- {
- return new DateTime(DateToTicks(year, month, day) + (new TimeSpan(0, hour, minute, second, millisecond)).Ticks);
- }
- else
- {
- throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
- }
- }
-
-
- public override int TwoDigitYearMax
- {
- get
- {
- return (twoDigitYearMax);
- }
-
- set
- {
- VerifyWritable();
- if (value < 99 || value > MaxYear)
- {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 99,
- MaxYear));
- }
- twoDigitYearMax = value;
- }
- }
-
-
- public override int ToFourDigitYear(int year)
- {
- if (year < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(year),
- SR.ArgumentOutOfRange_NeedNonNegNum);
- }
- Contract.EndContractBlock();
-
- if (year > MaxYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Bounds_Lower_Upper,
- 1,
- MaxYear));
- }
- return (base.ToFourDigitYear(year));
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/KoreanCalendar.cs b/src/mscorlib/corefx/System/Globalization/KoreanCalendar.cs
deleted file mode 100644
index b015aa0716..0000000000
--- a/src/mscorlib/corefx/System/Globalization/KoreanCalendar.cs
+++ /dev/null
@@ -1,267 +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.Diagnostics.CodeAnalysis;
-using System.Diagnostics.Contracts;
-
-namespace System.Globalization
-{
- /*=================================KoreanCalendar==========================
- **
- ** Korean calendar is based on the Gregorian calendar. And the year is an offset to Gregorian calendar.
- ** That is,
- ** Korean year = Gregorian year + 2333. So 2000/01/01 A.D. is Korean 4333/01/01
- **
- ** 0001/1/1 A.D. is Korean year 2334.
- **
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 0001/01/01 9999/12/31
- ** Korean 2334/01/01 12332/12/31
- ============================================================================*/
-
-
- [Serializable]
- public class KoreanCalendar : Calendar
- {
- //
- // The era value for the current era.
- //
-
- public const int KoreanEra = 1;
-
- // Since
- // Gregorian Year = Era Year + yearOffset
- // Gregorian Year 1 is Korean year 2334, so that
- // 1 = 2334 + yearOffset
- // So yearOffset = -2333
- // Gregorian year 2001 is Korean year 4334.
-
- //m_EraInfo[0] = new EraInfo(1, new DateTime(1, 1, 1).Ticks, -2333, 2334, GregorianCalendar.MaxYear + 2333);
-
- // Initialize our era info.
- internal static EraInfo[] koreanEraInfo = new EraInfo[] {
- new EraInfo( 1, 1, 1, 1, -2333, 2334, GregorianCalendar.MaxYear + 2333) // era #, start year/month/day, yearOffset, minEraYear
- };
-
- internal GregorianCalendarHelper helper;
-
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (DateTime.MinValue);
- }
- }
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (DateTime.MaxValue);
- }
- }
-
- public override CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.SolarCalendar;
- }
- }
-
- public KoreanCalendar()
- {
- try
- {
- new CultureInfo("ko-KR");
- }
- catch (ArgumentException e)
- {
- throw new TypeInitializationException(this.GetType().ToString(), e);
- }
- helper = new GregorianCalendarHelper(this, koreanEraInfo);
- }
-
- internal override CalendarId ID
- {
- get
- {
- return CalendarId.KOREA;
- }
- }
-
-
- public override DateTime AddMonths(DateTime time, int months)
- {
- return (helper.AddMonths(time, months));
- }
-
-
- public override DateTime AddYears(DateTime time, int years)
- {
- return (helper.AddYears(time, years));
- }
-
- /*=================================GetDaysInMonth==========================
- **Action: Returns the number of days in the month given by the year and month arguments.
- **Returns: The number of days in the given month.
- **Arguments:
- ** year The year in Korean calendar.
- ** month The month
- ** era The Japanese era value.
- **Exceptions
- ** ArgumentException If month is less than 1 or greater * than 12.
- ============================================================================*/
-
-
- public override int GetDaysInMonth(int year, int month, int era)
- {
- return (helper.GetDaysInMonth(year, month, era));
- }
-
-
- public override int GetDaysInYear(int year, int era)
- {
- return (helper.GetDaysInYear(year, era));
- }
-
-
- public override int GetDayOfMonth(DateTime time)
- {
- return (helper.GetDayOfMonth(time));
- }
-
-
- public override DayOfWeek GetDayOfWeek(DateTime time)
- {
- return (helper.GetDayOfWeek(time));
- }
-
-
- public override int GetDayOfYear(DateTime time)
- {
- return (helper.GetDayOfYear(time));
- }
-
-
- public override int GetMonthsInYear(int year, int era)
- {
- return (helper.GetMonthsInYear(year, era));
- }
-
-
- [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
- public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
- {
- return (helper.GetWeekOfYear(time, rule, firstDayOfWeek));
- }
-
-
- public override int GetEra(DateTime time)
- {
- return (helper.GetEra(time));
- }
-
- public override int GetMonth(DateTime time)
- {
- return (helper.GetMonth(time));
- }
-
-
- public override int GetYear(DateTime time)
- {
- return (helper.GetYear(time));
- }
-
-
- public override bool IsLeapDay(int year, int month, int day, int era)
- {
- return (helper.IsLeapDay(year, month, day, era));
- }
-
-
- public override bool IsLeapYear(int year, int era)
- {
- return (helper.IsLeapYear(year, era));
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
- public override int GetLeapMonth(int year, int era)
- {
- return (helper.GetLeapMonth(year, era));
- }
-
-
- public override bool IsLeapMonth(int year, int month, int era)
- {
- return (helper.IsLeapMonth(year, month, era));
- }
-
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
- {
- return (helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era));
- }
-
-
- public override int[] Eras
- {
- get
- {
- return (helper.Eras);
- }
- }
-
- private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 4362;
-
-
- public override int TwoDigitYearMax
- {
- get
- {
- if (twoDigitYearMax == -1)
- {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
- }
- return (twoDigitYearMax);
- }
-
- set
- {
- VerifyWritable();
- if (value < 99 || value > helper.MaxYear)
- {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 99,
- helper.MaxYear));
- }
- twoDigitYearMax = value;
- }
- }
-
-
- public override int ToFourDigitYear(int year)
- {
- if (year < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(year),
- SR.ArgumentOutOfRange_NeedNonNegNum);
- }
- Contract.EndContractBlock();
-
- return (helper.ToFourDigitYear(year, this.TwoDigitYearMax));
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/KoreanLunisolarCalendar.cs b/src/mscorlib/corefx/System/Globalization/KoreanLunisolarCalendar.cs
deleted file mode 100644
index 6d091285b2..0000000000
--- a/src/mscorlib/corefx/System/Globalization/KoreanLunisolarCalendar.cs
+++ /dev/null
@@ -1,1329 +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.Diagnostics.Contracts;
-
-namespace System.Globalization
-{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about KoreanLunisolarCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
- /*
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 918/02/14 2051/02/10
- ** KoreanLunisolar 918/01/01 2050/13/29
- */
-
- [Serializable]
- public class KoreanLunisolarCalendar : EastAsianLunisolarCalendar
- {
- //
- // The era value for the current era.
- //
-
- public const int GregorianEra = 1;
-
- internal const int MIN_LUNISOLAR_YEAR = 918;
- internal const int MAX_LUNISOLAR_YEAR = 2050;
-
- internal const int MIN_GREGORIAN_YEAR = 918;
- internal const int MIN_GREGORIAN_MONTH = 2;
- internal const int MIN_GREGORIAN_DAY = 14;
-
- internal const int MAX_GREGORIAN_YEAR = 2051;
- internal const int MAX_GREGORIAN_MONTH = 2;
- internal const int MAX_GREGORIAN_DAY = 10;
-
- internal static DateTime minDate = new DateTime(MIN_GREGORIAN_YEAR, MIN_GREGORIAN_MONTH, MIN_GREGORIAN_DAY);
- internal static DateTime maxDate = new DateTime((new DateTime(MAX_GREGORIAN_YEAR, MAX_GREGORIAN_MONTH, MAX_GREGORIAN_DAY, 23, 59, 59, 999)).Ticks + 9999);
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (minDate);
- }
- }
-
-
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (maxDate);
- }
- }
-
- protected override int DaysInYearBeforeMinSupportedYear
- {
- get
- {
- // 917 -- From http://emr.cs.iit.edu/home/reingold/calendar-book/Calendrica.html
- // using ChineseLunisolar
- return 384;
- }
- }
-
- private static readonly int[,] s_yinfo =
- {
- /*Y LM Lmon Lday DaysPerMonth D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 #Days
- 918 */
- { 0 , 2 , 14 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-919 */{ 0 , 2 , 4 , 17872 },/* 29 30 29 29 29 30 29 30 30 30 29 30 0 354
-920 */{ 6 , 1 , 24 , 41688 },/* 30 29 30 29 29 29 30 29 30 30 29 30 30 384
-921 */{ 0 , 2 , 11 , 41648 },/* 30 29 30 29 29 29 30 29 30 29 30 30 0 354
-922 */{ 0 , 1 , 31 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-923 */{ 4 , 1 , 20 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-924 */{ 0 , 2 , 8 , 27936 },/* 29 30 30 29 30 30 29 30 29 29 30 29 0 354
-925 */{ 12 , 1 , 27 , 44384 },/* 30 29 30 29 30 30 29 30 29 30 30 29 29 384
-926 */{ 0 , 2 , 15 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-927 */{ 0 , 2 , 5 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-928 */{ 8 , 1 , 26 , 17848 },/* 29 30 29 29 29 30 29 30 30 29 30 30 30 384
-929 */{ 0 , 2 , 13 , 17776 },/* 29 30 29 29 29 30 29 30 29 30 30 30 0 354
-930 */{ 0 , 2 , 2 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-931 */{ 5 , 1 , 22 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 29 383
-932 */{ 0 , 2 , 9 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
-933 */{ 0 , 1 , 29 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-934 */{ 1 , 1 , 18 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-935 */{ 0 , 2 , 6 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-936 */{ 11 , 1 , 27 , 21344 },/* 29 30 29 30 29 29 30 30 29 30 30 29 29 383
-937 */{ 0 , 2 , 13 , 51904 },/* 30 30 29 29 30 29 30 29 30 30 29 29 0 354
-938 */{ 0 , 2 , 2 , 58720 },/* 30 30 30 29 29 30 29 30 29 30 30 29 0 355
-939 */{ 7 , 1 , 23 , 53928 },/* 30 30 29 30 29 29 30 29 30 29 30 29 30 384
-940 */{ 0 , 2 , 11 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
-941 */{ 0 , 1 , 30 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-942 */{ 3 , 1 , 20 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-943 */{ 0 , 2 , 8 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-944 */{ 12 , 1 , 28 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 29 384
-945 */{ 0 , 2 , 15 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-946 */{ 0 , 2 , 5 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
-947 */{ 7 , 1 , 25 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-948 */{ 0 , 2 , 13 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-949 */{ 0 , 2 , 1 , 45664 },/* 30 29 30 30 29 29 30 29 29 30 30 29 0 354
-950 */{ 5 , 1 , 21 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-951 */{ 0 , 2 , 9 , 45936 },/* 30 29 30 30 29 30 29 30 29 30 29 0 0 325
-952 */{ 0 , 12 , 31 , 43728 },/* 30 29 30 29 30 29 30 29 30 30 29 30 29 384
-953 */{ 1 , 1 , 18 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 29 384
-954 */{ 0 , 2 , 6 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-955 */{ 9 , 1 , 27 , 19128 },/* 29 30 29 29 30 29 30 29 30 29 30 30 30 384
-956 */{ 0 , 2 , 15 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-957 */{ 0 , 2 , 3 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-958 */{ 7 , 1 , 23 , 43672 },/* 30 29 30 29 30 29 30 29 30 29 29 30 30 384
-959 */{ 0 , 2 , 11 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-960 */{ 0 , 1 , 31 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-961 */{ 3 , 1 , 20 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
-962 */{ 0 , 2 , 8 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-963 */{ 12 , 1 , 28 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 29 384
-964 */{ 0 , 2 , 16 , 41840 },/* 30 29 30 29 29 29 30 30 29 30 30 30 0 355
-965 */{ 0 , 2 , 5 , 20848 },/* 29 30 29 30 29 29 29 30 29 30 30 30 0 354
-966 */{ 8 , 1 , 25 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
-967 */{ 0 , 2 , 12 , 54448 },/* 30 30 29 30 29 30 29 29 30 29 30 30 0 355
-968 */{ 0 , 2 , 2 , 23184 },/* 29 30 29 30 30 29 30 29 30 29 29 30 0 354
-969 */{ 5 , 1 , 21 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
-970 */{ 0 , 2 , 9 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-971 */{ 0 , 1 , 30 , 10976 },/* 29 29 30 29 30 29 30 29 30 30 30 29 0 354
-972 */{ 2 , 1 , 19 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
-973 */{ 0 , 2 , 6 , 41696 },/* 30 29 30 29 29 29 30 29 30 30 30 29 0 354
-974 */{ 10 , 1 , 26 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-975 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-976 */{ 0 , 2 , 3 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-977 */{ 7 , 1 , 22 , 55952 },/* 30 30 29 30 30 29 30 29 30 29 29 30 29 384
-978 */{ 0 , 2 , 10 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
-979 */{ 0 , 1 , 31 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-980 */{ 3 , 1 , 21 , 10968 },/* 29 29 30 29 30 29 30 29 30 30 29 30 30 384
-981 */{ 0 , 2 , 8 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-982 */{ 12 , 1 , 28 , 37592 },/* 30 29 29 30 29 29 30 29 30 30 29 30 30 384
-983 */{ 0 , 2 , 16 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
-984 */{ 0 , 2 , 5 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-985 */{ 9 , 1 , 24 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-986 */{ 0 , 2 , 12 , 44192 },/* 30 29 30 29 30 30 29 29 30 29 30 29 0 354
-987 */{ 0 , 2 , 1 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-988 */{ 5 , 1 , 22 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-989 */{ 0 , 2 , 9 , 19376 },/* 29 30 29 29 30 29 30 30 30 29 30 30 0 355
-990 */{ 0 , 1 , 30 , 9648 },/* 29 29 30 29 29 30 29 30 30 29 30 30 0 354
-991 */{ 2 , 1 , 19 , 37560 },/* 30 29 29 30 29 29 30 29 30 29 30 30 30 384
-992 */{ 0 , 2 , 7 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-993 */{ 10 , 1 , 26 , 26968 },/* 29 30 30 29 30 29 29 30 29 30 29 30 30 384
-994 */{ 0 , 2 , 14 , 22864 },/* 29 30 29 30 30 29 29 30 29 30 29 30 0 354
-995 */{ 0 , 2 , 3 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-996 */{ 7 , 1 , 23 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
-997 */{ 0 , 2 , 10 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-998 */{ 0 , 1 , 31 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-999 */{ 3 , 1 , 20 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1000 */{ 0 , 2 , 8 , 9584 },/* 29 29 30 29 29 30 29 30 29 30 30 30 0 354
-1001 */{ 12 , 1 , 28 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 29 383
-1002 */{ 0 , 2 , 15 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
-1003 */{ 0 , 2 , 4 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1004 */{ 9 , 1 , 25 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1005 */{ 0 , 2 , 12 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1006 */{ 0 , 2 , 1 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-1007 */{ 5 , 1 , 22 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1008 */{ 0 , 2 , 10 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
-1009 */{ 0 , 1 , 29 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1010 */{ 2 , 1 , 18 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1011 */{ 0 , 2 , 6 , 45664 },/* 30 29 30 30 29 29 30 29 29 30 30 29 0 354
-1012 */{ 10 , 1 , 26 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1013 */{ 0 , 2 , 13 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1014 */{ 0 , 2 , 3 , 13728 },/* 29 29 30 30 29 30 29 30 30 29 30 29 0 354
-1015 */{ 6 , 1 , 23 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 29 384
-1016 */{ 0 , 2 , 11 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1017 */{ 0 , 1 , 31 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1018 */{ 4 , 1 , 20 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1019 */{ 0 , 2 , 8 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1020 */{ 12 , 1 , 28 , 43608 },/* 30 29 30 29 30 29 30 29 29 30 29 30 30 384
-1021 */{ 0 , 2 , 15 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1022 */{ 0 , 2 , 4 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1023 */{ 9 , 1 , 25 , 11688 },/* 29 29 30 29 30 30 29 30 30 29 30 29 30 384
-1024 */{ 0 , 2 , 13 , 11088 },/* 29 29 30 29 30 29 30 30 29 30 29 30 0 354
-1025 */{ 0 , 2 , 1 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 0 355
-1026 */{ 5 , 1 , 22 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 29 383
-1027 */{ 0 , 2 , 9 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 0 355
-1028 */{ 0 , 1 , 30 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1029 */{ 2 , 1 , 18 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1030 */{ 0 , 2 , 5 , 55952 },/* 30 30 29 30 30 29 30 29 30 29 29 30 0 355
-1031 */{ 10 , 1 , 26 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
-1032 */{ 0 , 2 , 14 , 26320 },/* 29 30 30 29 29 30 30 29 30 30 29 30 0 355
-1033 */{ 0 , 2 , 3 , 9952 },/* 29 29 30 29 29 30 30 29 30 30 30 29 0 354
-1034 */{ 6 , 1 , 23 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
-1035 */{ 0 , 2 , 11 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1036 */{ 0 , 1 , 31 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1037 */{ 4 , 1 , 19 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1038 */{ 0 , 2 , 7 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1039 */{ 12 , 1 , 27 , 54928 },/* 30 30 29 30 29 30 30 29 30 29 29 30 29 384
-1040 */{ 0 , 2 , 15 , 46464 },/* 30 29 30 30 29 30 29 30 30 29 29 29 0 354
-1041 */{ 0 , 2 , 3 , 54960 },/* 30 30 29 30 29 30 30 29 30 29 30 30 0 356
-1042 */{ 9 , 1 , 25 , 9944 },/* 29 29 30 29 29 30 30 29 30 30 29 30 30 384
-1043 */{ 0 , 2 , 13 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1044 */{ 0 , 2 , 2 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
-1045 */{ 5 , 1 , 21 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1046 */{ 0 , 2 , 9 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1047 */{ 0 , 1 , 29 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1048 */{ 1 , 1 , 18 , 46424 },/* 30 29 30 30 29 30 29 30 29 30 29 30 30 385
-1049 */{ 0 , 2 , 6 , 11600 },/* 29 29 30 29 30 30 29 30 29 30 29 30 0 354
-1050 */{ 11 , 1 , 26 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-1051 */{ 0 , 2 , 14 , 19376 },/* 29 30 29 29 30 29 30 30 30 29 30 30 0 355
-1052 */{ 0 , 2 , 4 , 9648 },/* 29 29 30 29 29 30 29 30 30 29 30 30 0 354
-1053 */{ 7 , 1 , 23 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1054 */{ 0 , 2 , 11 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1055 */{ 0 , 1 , 31 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1056 */{ 3 , 1 , 20 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
-1057 */{ 0 , 2 , 7 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1058 */{ 12 , 1 , 27 , 43864 },/* 30 29 30 29 30 29 30 30 29 30 29 30 30 385
-1059 */{ 0 , 2 , 16 , 10064 },/* 29 29 30 29 29 30 30 30 29 30 29 30 0 354
-1060 */{ 0 , 2 , 5 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1061 */{ 8 , 1 , 24 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1062 */{ 0 , 2 , 12 , 42336 },/* 30 29 30 29 29 30 29 30 29 30 30 29 0 354
-1063 */{ 0 , 2 , 1 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1064 */{ 5 , 1 , 21 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-1065 */{ 0 , 2 , 8 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1066 */{ 0 , 1 , 29 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1067 */{ 1 , 1 , 18 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
-1068 */{ 0 , 2 , 6 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-1069 */{ 11 , 1 , 26 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1070 */{ 0 , 2 , 14 , 18896 },/* 29 30 29 29 30 29 29 30 30 30 29 30 0 354
-1071 */{ 0 , 2 , 3 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1072 */{ 7 , 1 , 23 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1073 */{ 0 , 2 , 10 , 43616 },/* 30 29 30 29 30 29 30 29 29 30 30 29 0 354
-1074 */{ 0 , 1 , 30 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1075 */{ 4 , 1 , 20 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1076 */{ 0 , 2 , 8 , 13728 },/* 29 29 30 30 29 30 29 30 30 29 30 29 0 354
-1077 */{ 0 , 1 , 27 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1078 */{ 1 , 1 , 17 , 19352 },/* 29 30 29 29 30 29 30 30 30 29 29 30 30 384
-1079 */{ 0 , 2 , 5 , 17840 },/* 29 30 29 29 29 30 29 30 30 29 30 30 0 354
-1080 */{ 9 , 1 , 25 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-1081 */{ 0 , 2 , 12 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1082 */{ 0 , 2 , 1 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1083 */{ 6 , 1 , 21 , 46408 },/* 30 29 30 30 29 30 29 30 29 30 29 29 30 384
-1084 */{ 0 , 2 , 9 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 0 355
-1085 */{ 0 , 1 , 29 , 11680 },/* 29 29 30 29 30 30 29 30 30 29 30 29 0 354
-1086 */{ 2 , 1 , 18 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 29 384
-1087 */{ 0 , 2 , 6 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1088 */{ 12 , 1 , 27 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 29 383
-1089 */{ 0 , 2 , 13 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 0 355
-1090 */{ 0 , 2 , 3 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1091 */{ 8 , 1 , 23 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1092 */{ 0 , 2 , 10 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-1093 */{ 0 , 1 , 30 , 23360 },/* 29 30 29 30 30 29 30 30 29 30 29 29 0 354
-1094 */{ 4 , 1 , 19 , 43880 },/* 30 29 30 29 30 29 30 30 29 30 30 29 30 385
-1095 */{ 0 , 2 , 8 , 10976 },/* 29 29 30 29 30 29 30 29 30 30 30 29 0 354
-1096 */{ 0 , 1 , 28 , 58896 },/* 30 30 30 29 29 30 30 29 29 29 29 30 0 354
-1097 */{ 2 , 1 , 16 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 29 384
-1098 */{ 0 , 2 , 4 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1099 */{ 9 , 1 , 24 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1100 */{ 0 , 2 , 12 , 21664 },/* 29 30 29 30 29 30 29 29 30 29 30 29 0 353
-1101 */{ 0 , 1 , 31 , 54864 },/* 30 30 29 30 29 30 30 29 29 30 29 30 0 355
-1102 */{ 6 , 1 , 21 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1103 */{ 0 , 2 , 9 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
-1104 */{ 0 , 1 , 30 , 9936 },/* 29 29 30 29 29 30 30 29 30 30 29 30 0 354
-1105 */{ 2 , 1 , 18 , 37608 },/* 30 29 29 30 29 29 30 29 30 30 30 29 30 384
-1106 */{ 0 , 2 , 6 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
-1107 */{ 10 , 1 , 26 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1108 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1109 */{ 0 , 2 , 2 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1110 */{ 8 , 1 , 22 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1111 */{ 0 , 2 , 10 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1112 */{ 0 , 1 , 31 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-1113 */{ 4 , 1 , 20 , 9656 },/* 29 29 30 29 29 30 29 30 30 29 30 30 30 384
-1114 */{ 0 , 2 , 8 , 17776 },/* 29 30 29 29 29 30 29 30 29 30 30 30 0 354
-1115 */{ 0 , 1 , 28 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1116 */{ 1 , 1 , 17 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1117 */{ 0 , 2 , 4 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1118 */{ 9 , 1 , 24 , 29352 },/* 29 30 30 30 29 29 30 29 30 29 30 29 30 384
-1119 */{ 0 , 2 , 12 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1120 */{ 0 , 2 , 1 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1121 */{ 5 , 1 , 21 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
-1122 */{ 0 , 2 , 9 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1123 */{ 0 , 1 , 29 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1124 */{ 3 , 1 , 19 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 29 383
-1125 */{ 0 , 2 , 5 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1126 */{ 11 , 1 , 25 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-1127 */{ 0 , 2 , 13 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1128 */{ 0 , 2 , 3 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1129 */{ 8 , 1 , 22 , 39824 },/* 30 29 29 30 30 29 30 30 30 29 29 30 29 384
-1130 */{ 0 , 2 , 10 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-1131 */{ 0 , 1 , 31 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1132 */{ 4 , 1 , 20 , 42216 },/* 30 29 30 29 29 30 29 29 30 30 30 29 30 384
-1133 */{ 0 , 2 , 7 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1134 */{ 0 , 1 , 27 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1135 */{ 2 , 1 , 16 , 55592 },/* 30 30 29 30 30 29 29 30 29 29 30 29 30 384
-1136 */{ 0 , 2 , 4 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1137 */{ 10 , 1 , 23 , 54952 },/* 30 30 29 30 29 30 30 29 30 29 30 29 30 385
-1138 */{ 0 , 2 , 12 , 11680 },/* 29 29 30 29 30 30 29 30 30 29 30 29 0 354
-1139 */{ 0 , 2 , 1 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1140 */{ 6 , 1 , 22 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
-1141 */{ 0 , 2 , 9 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1142 */{ 0 , 1 , 29 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1143 */{ 4 , 1 , 18 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1144 */{ 0 , 2 , 6 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1145 */{ 11 , 1 , 25 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-1146 */{ 0 , 2 , 13 , 27456 },/* 29 30 30 29 30 29 30 30 29 30 29 29 0 354
-1147 */{ 0 , 2 , 2 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1148 */{ 8 , 1 , 23 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 29 384
-1149 */{ 0 , 2 , 10 , 39280 },/* 30 29 29 30 30 29 29 30 29 30 30 30 0 355
-1150 */{ 0 , 1 , 31 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1151 */{ 4 , 1 , 20 , 25784 },/* 29 30 30 29 29 30 29 29 30 29 30 30 30 384
-1152 */{ 0 , 2 , 8 , 21680 },/* 29 30 29 30 29 30 29 29 30 29 30 30 0 354
-1153 */{ 12 , 1 , 27 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1154 */{ 0 , 2 , 14 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-1155 */{ 0 , 2 , 4 , 23232 },/* 29 30 29 30 30 29 30 29 30 30 29 29 0 354
-1156 */{ 10 , 1 , 24 , 43880 },/* 30 29 30 29 30 29 30 30 29 30 30 29 30 385
-1157 */{ 0 , 2 , 12 , 9952 },/* 29 29 30 29 29 30 30 29 30 30 30 29 0 354
-1158 */{ 0 , 2 , 1 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1159 */{ 6 , 1 , 21 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 29 384
-1160 */{ 0 , 2 , 9 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1161 */{ 0 , 1 , 28 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1162 */{ 2 , 1 , 17 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1163 */{ 0 , 2 , 5 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1164 */{ 11 , 1 , 26 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1165 */{ 0 , 2 , 13 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-1166 */{ 0 , 2 , 3 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1167 */{ 7 , 1 , 23 , 37608 },/* 30 29 29 30 29 29 30 29 30 30 30 29 30 384
-1168 */{ 0 , 2 , 11 , 37488 },/* 30 29 29 30 29 29 30 29 29 30 30 30 0 354
-1169 */{ 0 , 1 , 30 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1170 */{ 5 , 1 , 19 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1171 */{ 0 , 2 , 7 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1172 */{ 0 , 1 , 27 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1173 */{ 1 , 1 , 16 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1174 */{ 0 , 2 , 4 , 19888 },/* 29 30 29 29 30 30 29 30 30 29 30 30 0 355
-1175 */{ 9 , 1 , 25 , 9648 },/* 29 29 30 29 29 30 29 30 30 29 30 30 29 383
-1176 */{ 0 , 2 , 12 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1177 */{ 0 , 2 , 1 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1178 */{ 6 , 1 , 21 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1179 */{ 0 , 2 , 9 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1180 */{ 0 , 1 , 29 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1181 */{ 3 , 1 , 17 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1182 */{ 0 , 2 , 5 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1183 */{ 11 , 1 , 26 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
-1184 */{ 0 , 2 , 14 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1185 */{ 0 , 2 , 2 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1186 */{ 7 , 1 , 23 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 29 383
-1187 */{ 0 , 2 , 10 , 53392 },/* 30 30 29 30 29 29 30 29 29 30 30 0 0 325
-1188 */{ 0 , 1 , 1 , 29848 },/* 29 30 30 30 29 30 29 29 30 29 29 30 30 384
-1189 */{ 5 , 1 , 19 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
-1190 */{ 0 , 2 , 7 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1191 */{ 0 , 1 , 27 , 39760 },/* 30 29 29 30 30 29 30 30 29 30 29 30 0 355
-1192 */{ 2 , 1 , 17 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
-1193 */{ 0 , 2 , 4 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1194 */{ 10 , 1 , 24 , 42216 },/* 30 29 30 29 29 30 29 29 30 30 30 29 30 384
-1195 */{ 0 , 2 , 12 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1196 */{ 0 , 2 , 1 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1197 */{ 6 , 1 , 20 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
-1198 */{ 0 , 2 , 8 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1199 */{ 0 , 1 , 28 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 0 355
-1200 */{ 2 , 1 , 18 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
-1201 */{ 0 , 2 , 5 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1202 */{ 12 , 1 , 26 , 18904 },/* 29 30 29 29 30 29 29 30 30 30 29 30 30 384
-1203 */{ 0 , 2 , 14 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1204 */{ 0 , 2 , 3 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1205 */{ 8 , 1 , 22 , 43608 },/* 30 29 30 29 30 29 30 29 29 30 29 30 30 384
-1206 */{ 0 , 2 , 10 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1207 */{ 0 , 1 , 30 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1208 */{ 4 , 1 , 19 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 29 384
-1209 */{ 0 , 2 , 6 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1210 */{ 0 , 1 , 27 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1211 */{ 2 , 1 , 17 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1212 */{ 0 , 2 , 5 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1213 */{ 9 , 1 , 24 , 25784 },/* 29 30 30 29 29 30 29 29 30 29 30 30 30 384
-1214 */{ 0 , 2 , 12 , 21680 },/* 29 30 29 30 29 30 29 29 30 29 30 30 0 354
-1215 */{ 0 , 2 , 1 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1216 */{ 7 , 1 , 21 , 27944 },/* 29 30 30 29 30 30 29 30 29 29 30 29 30 384
-1217 */{ 0 , 2 , 8 , 23232 },/* 29 30 29 30 30 29 30 29 30 30 29 29 0 354
-1218 */{ 0 , 1 , 28 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1219 */{ 3 , 1 , 18 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
-1220 */{ 0 , 2 , 6 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1221 */{ 12 , 1 , 25 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 29 384
-1222 */{ 0 , 2 , 13 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1223 */{ 0 , 2 , 2 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1224 */{ 8 , 1 , 22 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1225 */{ 0 , 2 , 9 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1226 */{ 0 , 1 , 30 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1227 */{ 5 , 1 , 19 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
-1228 */{ 0 , 2 , 8 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1229 */{ 0 , 1 , 27 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1230 */{ 2 , 1 , 16 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-1231 */{ 0 , 2 , 4 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1232 */{ 9 , 1 , 24 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1233 */{ 0 , 2 , 11 , 45728 },/* 30 29 30 30 29 29 30 29 30 29 30 29 0 354
-1234 */{ 0 , 1 , 31 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1235 */{ 7 , 1 , 21 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1236 */{ 0 , 2 , 9 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
-1237 */{ 0 , 1 , 28 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-1238 */{ 4 , 1 , 18 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1239 */{ 0 , 2 , 6 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1240 */{ 12 , 1 , 26 , 43320 },/* 30 29 30 29 30 29 29 30 29 29 30 30 30 384
-1241 */{ 0 , 2 , 13 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 0 354
-1242 */{ 0 , 2 , 2 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1243 */{ 8 , 1 , 22 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1244 */{ 0 , 2 , 10 , 44624 },/* 30 29 30 29 30 30 30 29 29 30 29 30 0 355
-1245 */{ 0 , 1 , 30 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1246 */{ 4 , 1 , 19 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1247 */{ 0 , 2 , 7 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1248 */{ 0 , 1 , 28 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
-1249 */{ 2 , 1 , 16 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 29 383
-1250 */{ 0 , 2 , 3 , 58672 },/* 30 30 30 29 29 30 29 30 29 29 30 30 0 355
-1251 */{ 10 , 1 , 24 , 27800 },/* 29 30 30 29 30 30 29 29 30 29 29 30 30 384
-1252 */{ 0 , 2 , 12 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1253 */{ 0 , 1 , 31 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
-1254 */{ 6 , 1 , 21 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
-1255 */{ 0 , 2 , 9 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1256 */{ 0 , 1 , 29 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
-1257 */{ 4 , 1 , 17 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1258 */{ 0 , 2 , 5 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1259 */{ 11 , 1 , 25 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
-1260 */{ 0 , 2 , 13 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1261 */{ 0 , 2 , 1 , 46752 },/* 30 29 30 30 29 30 30 29 30 29 30 29 0 355
-1262 */{ 9 , 1 , 22 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
-1263 */{ 0 , 2 , 10 , 21872 },/* 29 30 29 30 29 30 29 30 29 30 30 30 0 355
-1264 */{ 0 , 1 , 31 , 18896 },/* 29 30 29 29 30 29 29 30 30 30 29 30 0 354
-1265 */{ 5 , 1 , 19 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1266 */{ 0 , 2 , 7 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1267 */{ 0 , 1 , 27 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1268 */{ 1 , 1 , 16 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-1269 */{ 0 , 2 , 3 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1270 */{ 11 , 1 , 23 , 46528 },/* 30 29 30 30 29 30 29 30 30 30 29 29 29 384
-1271 */{ 0 , 2 , 11 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1272 */{ 0 , 2 , 1 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1273 */{ 6 , 1 , 21 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1274 */{ 0 , 2 , 9 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1275 */{ 0 , 1 , 29 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1276 */{ 3 , 1 , 18 , 27224 },/* 29 30 30 29 30 29 30 29 29 30 29 30 30 384
-1277 */{ 0 , 2 , 5 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1278 */{ 11 , 1 , 25 , 27432 },/* 29 30 30 29 30 29 30 30 29 29 30 29 30 384
-1279 */{ 0 , 2 , 13 , 23232 },/* 29 30 29 30 30 29 30 29 30 30 29 29 0 354
-1280 */{ 0 , 2 , 2 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1281 */{ 8 , 1 , 22 , 10984 },/* 29 29 30 29 30 29 30 29 30 30 30 29 30 384
-1282 */{ 0 , 2 , 10 , 18912 },/* 29 30 29 29 30 29 29 30 30 30 30 29 0 354
-1283 */{ 0 , 1 , 30 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1284 */{ 5 , 1 , 19 , 53848 },/* 30 30 29 30 29 29 30 29 29 30 29 30 30 384
-1285 */{ 0 , 2 , 6 , 45648 },/* 30 29 30 30 29 29 30 29 29 30 29 30 0 354
-1286 */{ 0 , 1 , 26 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1287 */{ 2 , 1 , 15 , 62096 },/* 30 30 30 30 29 29 30 29 30 29 29 30 29 384
-1288 */{ 0 , 2 , 3 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
-1289 */{ 10 , 1 , 23 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 29 384
-1290 */{ 0 , 2 , 11 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1291 */{ 0 , 2 , 1 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1292 */{ 6 , 1 , 21 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-1293 */{ 0 , 2 , 8 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1294 */{ 0 , 1 , 28 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1295 */{ 4 , 1 , 17 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-1296 */{ 0 , 2 , 5 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1297 */{ 12 , 1 , 24 , 44384 },/* 30 29 30 29 30 30 29 30 29 30 30 29 29 384
-1298 */{ 0 , 2 , 12 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1299 */{ 0 , 2 , 2 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1300 */{ 8 , 1 , 23 , 2424 },/* 29 29 29 29 30 29 29 30 29 30 30 30 30 383
-1301 */{ 0 , 2 , 10 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1302 */{ 0 , 1 , 30 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1303 */{ 5 , 1 , 19 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1304 */{ 0 , 2 , 6 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-1305 */{ 0 , 1 , 26 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1306 */{ 1 , 1 , 15 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 29 384
-1307 */{ 0 , 2 , 3 , 42720 },/* 30 29 30 29 29 30 30 29 30 30 30 29 0 355
-1308 */{ 11 , 1 , 24 , 37608 },/* 30 29 29 30 29 29 30 29 30 30 30 29 30 384
-1309 */{ 0 , 2 , 11 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1310 */{ 0 , 1 , 31 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1311 */{ 7 , 1 , 20 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1312 */{ 0 , 2 , 8 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1313 */{ 0 , 1 , 27 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1314 */{ 3 , 1 , 17 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1315 */{ 0 , 2 , 5 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1316 */{ 0 , 1 , 25 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
-1317 */{ 1 , 1 , 14 , 37608 },/* 30 29 29 30 29 29 30 29 30 30 30 29 30 384
-1318 */{ 0 , 2 , 2 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
-1319 */{ 8 , 1 , 22 , 42328 },/* 30 29 30 29 29 30 29 30 29 30 29 30 30 384
-1320 */{ 0 , 2 , 10 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1321 */{ 0 , 1 , 29 , 45728 },/* 30 29 30 30 29 29 30 29 30 29 30 29 0 354
-1322 */{ 5 , 1 , 18 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1323 */{ 0 , 2 , 6 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1324 */{ 0 , 1 , 27 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
-1325 */{ 1 , 1 , 15 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 29 384
-1326 */{ 0 , 2 , 3 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1327 */{ 9 , 1 , 24 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1328 */{ 0 , 2 , 12 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
-1329 */{ 0 , 1 , 31 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 0 354
-1330 */{ 7 , 1 , 20 , 27288 },/* 29 30 30 29 30 29 30 29 30 29 29 30 30 384
-1331 */{ 0 , 2 , 8 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1332 */{ 0 , 1 , 28 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1333 */{ 3 , 1 , 17 , 19368 },/* 29 30 29 29 30 29 30 30 30 29 30 29 30 384
-1334 */{ 0 , 2 , 5 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1335 */{ 12 , 1 , 25 , 42608 },/* 30 29 30 29 29 30 30 29 29 30 30 30 29 384
-1336 */{ 0 , 2 , 13 , 41696 },/* 30 29 30 29 29 29 30 29 30 30 30 29 0 354
-1337 */{ 0 , 2 , 1 , 53600 },/* 30 30 29 30 29 29 29 30 29 30 30 29 0 354
-1338 */{ 8 , 1 , 21 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-1339 */{ 0 , 2 , 9 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1340 */{ 0 , 1 , 29 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
-1341 */{ 5 , 1 , 18 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 29 384
-1342 */{ 0 , 2 , 6 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1343 */{ 0 , 1 , 27 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1344 */{ 2 , 1 , 16 , 41704 },/* 30 29 30 29 29 29 30 29 30 30 30 29 30 384
-1345 */{ 0 , 2 , 3 , 41680 },/* 30 29 30 29 29 29 30 29 30 30 29 30 0 354
-1346 */{ 10 , 1 , 23 , 53592 },/* 30 30 29 30 29 29 29 30 29 30 29 30 30 384
-1347 */{ 0 , 2 , 11 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1348 */{ 0 , 1 , 31 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1349 */{ 7 , 1 , 19 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 29 384
-1350 */{ 0 , 2 , 7 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
-1351 */{ 0 , 1 , 28 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
-1352 */{ 3 , 1 , 18 , 18904 },/* 29 30 29 29 30 29 29 30 30 30 29 30 30 384
-1353 */{ 0 , 2 , 5 , 17840 },/* 29 30 29 29 29 30 29 30 30 29 30 30 0 354
-1354 */{ 0 , 1 , 25 , 41648 },/* 30 29 30 29 29 29 30 29 30 29 30 30 0 354
-1355 */{ 1 , 1 , 14 , 53592 },/* 30 30 29 30 29 29 29 30 29 30 29 30 30 384
-1356 */{ 0 , 2 , 2 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1357 */{ 9 , 1 , 21 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-1358 */{ 0 , 2 , 9 , 27424 },/* 29 30 30 29 30 29 30 30 29 29 30 29 0 354
-1359 */{ 0 , 1 , 29 , 44384 },/* 30 29 30 29 30 30 29 30 29 30 30 29 0 355
-1360 */{ 5 , 1 , 19 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-1361 */{ 0 , 2 , 6 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1362 */{ 0 , 1 , 27 , 17776 },/* 29 30 29 29 29 30 29 30 29 30 30 30 0 354
-1363 */{ 3 , 1 , 16 , 41656 },/* 30 29 30 29 29 29 30 29 30 29 30 30 30 384
-1364 */{ 0 , 2 , 4 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1365 */{ 10 , 1 , 23 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 29 383
-1366 */{ 0 , 2 , 10 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1367 */{ 0 , 1 , 31 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1368 */{ 7 , 1 , 20 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 29 384
-1369 */{ 0 , 2 , 7 , 42720 },/* 30 29 30 29 29 30 30 29 30 30 30 29 0 355
-1370 */{ 0 , 1 , 28 , 21216 },/* 29 30 29 30 29 29 30 29 30 30 30 29 0 354
-1371 */{ 3 , 1 , 17 , 50544 },/* 30 30 29 29 29 30 29 30 29 30 30 30 29 384
-1372 */{ 0 , 2 , 5 , 42336 },/* 30 29 30 29 29 30 29 30 29 30 30 29 0 354
-1373 */{ 11 , 1 , 24 , 53928 },/* 30 30 29 30 29 29 30 29 30 29 30 29 30 384
-1374 */{ 0 , 2 , 12 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
-1375 */{ 0 , 2 , 1 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1376 */{ 9 , 1 , 22 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1377 */{ 0 , 2 , 9 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1378 */{ 0 , 1 , 29 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
-1379 */{ 5 , 1 , 19 , 21224 },/* 29 30 29 30 29 29 30 29 30 30 30 29 30 384
-1380 */{ 0 , 2 , 7 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1381 */{ 0 , 1 , 26 , 43216 },/* 30 29 30 29 30 29 29 29 30 30 29 30 0 354
-1382 */{ 2 , 1 , 15 , 53928 },/* 30 30 29 30 29 29 30 29 30 29 30 29 30 384
-1383 */{ 0 , 2 , 3 , 45728 },/* 30 29 30 30 29 29 30 29 30 29 30 29 0 354
-1384 */{ 10 , 1 , 23 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1385 */{ 0 , 2 , 10 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1386 */{ 0 , 1 , 31 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
-1387 */{ 6 , 1 , 20 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 29 384
-1388 */{ 0 , 2 , 8 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1389 */{ 0 , 1 , 28 , 20912 },/* 29 30 29 30 29 29 29 30 30 29 30 30 0 354
-1390 */{ 4 , 1 , 17 , 43192 },/* 30 29 30 29 30 29 29 29 30 29 30 30 30 384
-1391 */{ 0 , 2 , 5 , 25904 },/* 29 30 30 29 29 30 29 30 29 29 30 30 0 354
-1392 */{ 12 , 1 , 25 , 27288 },/* 29 30 30 29 30 29 30 29 30 29 29 30 30 384
-1393 */{ 0 , 2 , 12 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1394 */{ 0 , 2 , 1 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1395 */{ 9 , 1 , 22 , 11176 },/* 29 29 30 29 30 29 30 30 30 29 30 29 30 384
-1396 */{ 0 , 2 , 10 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1397 */{ 0 , 1 , 29 , 50032 },/* 30 30 29 29 29 29 30 30 29 30 30 30 0 355
-1398 */{ 5 , 1 , 19 , 20848 },/* 29 30 29 30 29 29 29 30 29 30 30 30 29 383
-1399 */{ 0 , 2 , 6 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1400 */{ 0 , 1 , 26 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1401 */{ 3 , 1 , 15 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 29 383
-1402 */{ 0 , 2 , 2 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
-1403 */{ 11 , 1 , 23 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 29 384
-1404 */{ 0 , 2 , 11 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1405 */{ 0 , 1 , 31 , 10976 },/* 29 29 30 29 30 29 30 29 30 30 30 29 0 354
-1406 */{ 7 , 1 , 20 , 41704 },/* 30 29 30 29 29 29 30 29 30 30 30 29 30 384
-1407 */{ 0 , 2 , 8 , 41680 },/* 30 29 30 29 29 29 30 29 30 30 29 30 0 354
-1408 */{ 0 , 1 , 28 , 53584 },/* 30 30 29 30 29 29 29 30 29 30 29 30 0 354
-1409 */{ 4 , 1 , 16 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1410 */{ 0 , 2 , 4 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1411 */{ 12 , 1 , 24 , 46736 },/* 30 29 30 30 29 30 30 29 30 29 29 30 29 384
-1412 */{ 0 , 2 , 12 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
-1413 */{ 0 , 2 , 1 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
-1414 */{ 9 , 1 , 22 , 9688 },/* 29 29 30 29 29 30 29 30 30 30 29 30 30 384
-1415 */{ 0 , 2 , 10 , 17840 },/* 29 30 29 29 29 30 29 30 30 29 30 30 0 354
-1416 */{ 0 , 1 , 30 , 41648 },/* 30 29 30 29 29 29 30 29 30 29 30 30 0 354
-1417 */{ 5 , 1 , 18 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1418 */{ 0 , 2 , 6 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1419 */{ 0 , 1 , 26 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1420 */{ 1 , 1 , 15 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1421 */{ 0 , 2 , 2 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1422 */{ 12 , 1 , 23 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-1423 */{ 0 , 2 , 11 , 19312 },/* 29 30 29 29 30 29 30 30 29 30 30 30 0 355
-1424 */{ 0 , 2 , 1 , 17776 },/* 29 30 29 29 29 30 29 30 29 30 30 30 0 354
-1425 */{ 7 , 1 , 20 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1426 */{ 0 , 2 , 8 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1427 */{ 0 , 1 , 28 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1428 */{ 4 , 1 , 17 , 27816 },/* 29 30 30 29 30 30 29 29 30 29 30 29 30 384
-1429 */{ 0 , 2 , 4 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1430 */{ 12 , 1 , 24 , 39760 },/* 30 29 29 30 30 29 30 30 29 30 29 30 29 384
-1431 */{ 0 , 2 , 12 , 42720 },/* 30 29 30 29 29 30 30 29 30 30 30 29 0 355
-1432 */{ 0 , 2 , 2 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1433 */{ 8 , 1 , 21 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1434 */{ 0 , 2 , 9 , 42336 },/* 30 29 30 29 29 30 29 30 29 30 30 29 0 354
-1435 */{ 0 , 1 , 29 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
-1436 */{ 6 , 1 , 18 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 29 384
-1437 */{ 0 , 2 , 5 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1438 */{ 0 , 1 , 26 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1439 */{ 2 , 1 , 15 , 43728 },/* 30 29 30 29 30 29 30 29 30 30 29 30 29 384
-1440 */{ 0 , 2 , 3 , 38368 },/* 30 29 29 30 29 30 29 30 30 30 30 29 0 355
-1441 */{ 11 , 1 , 23 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1442 */{ 0 , 2 , 11 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1443 */{ 0 , 1 , 31 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1444 */{ 7 , 1 , 20 , 53872 },/* 30 30 29 30 29 29 30 29 29 30 30 30 29 384
-1445 */{ 0 , 2 , 7 , 45728 },/* 30 29 30 30 29 29 30 29 30 29 30 29 0 354
-1446 */{ 0 , 1 , 27 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1447 */{ 4 , 1 , 17 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1448 */{ 0 , 2 , 5 , 11680 },/* 29 29 30 29 30 30 29 30 30 29 30 29 0 354
-1449 */{ 0 , 1 , 24 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1450 */{ 1 , 1 , 14 , 19128 },/* 29 30 29 29 30 29 30 29 30 29 30 30 30 384
-1451 */{ 0 , 2 , 2 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1452 */{ 9 , 1 , 22 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-1453 */{ 0 , 2 , 9 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1454 */{ 0 , 1 , 29 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 0 354
-1455 */{ 6 , 1 , 18 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1456 */{ 0 , 2 , 6 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 0 355
-1457 */{ 0 , 1 , 26 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1458 */{ 2 , 1 , 15 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 29 384
-1459 */{ 0 , 2 , 3 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1460 */{ 11 , 1 , 24 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 29 383
-1461 */{ 0 , 2 , 10 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1462 */{ 0 , 1 , 30 , 58544 },/* 30 30 30 29 29 30 29 29 30 29 30 30 0 355
-1463 */{ 7 , 1 , 20 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 29 383
-1464 */{ 0 , 2 , 7 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
-1465 */{ 0 , 1 , 27 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
-1466 */{ 3 , 1 , 17 , 11112 },/* 29 29 30 29 30 29 30 30 29 30 30 29 30 384
-1467 */{ 0 , 2 , 5 , 9952 },/* 29 29 30 29 29 30 30 29 30 30 30 29 0 354
-1468 */{ 0 , 1 , 25 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1469 */{ 2 , 1 , 13 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-1470 */{ 0 , 2 , 1 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
-1471 */{ 9 , 1 , 21 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1472 */{ 0 , 2 , 9 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1473 */{ 0 , 1 , 28 , 46736 },/* 30 29 30 30 29 30 30 29 30 29 29 30 0 355
-1474 */{ 6 , 1 , 18 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
-1475 */{ 0 , 2 , 6 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-1476 */{ 0 , 1 , 27 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1477 */{ 2 , 1 , 15 , 37592 },/* 30 29 29 30 29 29 30 29 30 30 29 30 30 384
-1478 */{ 0 , 2 , 3 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
-1479 */{ 10 , 1 , 23 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1480 */{ 0 , 2 , 11 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1481 */{ 0 , 1 , 30 , 29856 },/* 29 30 30 30 29 30 29 29 30 29 30 29 0 354
-1482 */{ 8 , 1 , 19 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1483 */{ 0 , 2 , 7 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1484 */{ 0 , 1 , 28 , 21424 },/* 29 30 29 30 29 29 30 30 30 29 30 30 0 355
-1485 */{ 4 , 1 , 17 , 9656 },/* 29 29 30 29 29 30 29 30 30 29 30 30 30 384
-1486 */{ 0 , 2 , 5 , 9584 },/* 29 29 30 29 29 30 29 30 29 30 30 30 0 354
-1487 */{ 0 , 1 , 25 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1488 */{ 1 , 1 , 14 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1489 */{ 0 , 2 , 1 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1490 */{ 9 , 1 , 21 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
-1491 */{ 0 , 2 , 9 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1492 */{ 0 , 1 , 29 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1493 */{ 5 , 1 , 18 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
-1494 */{ 0 , 2 , 6 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1495 */{ 0 , 1 , 26 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1496 */{ 3 , 1 , 16 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 29 383
-1497 */{ 0 , 2 , 2 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
-1498 */{ 11 , 1 , 22 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 29 384
-1499 */{ 0 , 2 , 10 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1500 */{ 0 , 1 , 31 , 5792 },/* 29 29 29 30 29 30 30 29 30 29 30 29 0 353
-1501 */{ 7 , 1 , 19 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1502 */{ 0 , 2 , 7 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1503 */{ 0 , 1 , 28 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1504 */{ 4 , 1 , 17 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1505 */{ 0 , 2 , 4 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1506 */{ 0 , 1 , 24 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1507 */{ 1 , 1 , 13 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 29 384
-1508 */{ 0 , 2 , 1 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1509 */{ 9 , 1 , 21 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1510 */{ 0 , 2 , 9 , 11680 },/* 29 29 30 29 30 30 29 30 30 29 30 29 0 354
-1511 */{ 0 , 1 , 29 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1512 */{ 5 , 1 , 19 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1513 */{ 0 , 2 , 6 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1514 */{ 0 , 1 , 26 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1515 */{ 4 , 1 , 15 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1516 */{ 0 , 2 , 3 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 0 354
-1517 */{ 12 , 1 , 22 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1518 */{ 0 , 2 , 10 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 0 355
-1519 */{ 0 , 1 , 31 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1520 */{ 8 , 1 , 20 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 29 384
-1521 */{ 0 , 2 , 7 , 37616 },/* 30 29 29 30 29 29 30 29 30 30 30 30 0 355
-1522 */{ 0 , 1 , 28 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1523 */{ 4 , 1 , 17 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
-1524 */{ 0 , 2 , 4 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1525 */{ 12 , 1 , 23 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 29 384
-1526 */{ 0 , 2 , 11 , 54928 },/* 30 30 29 30 29 30 30 29 30 29 29 30 0 355
-1527 */{ 0 , 2 , 1 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1528 */{ 10 , 1 , 22 , 11112 },/* 29 29 30 29 30 29 30 30 29 30 30 29 30 384
-1529 */{ 0 , 2 , 9 , 9952 },/* 29 29 30 29 29 30 30 29 30 30 30 29 0 354
-1530 */{ 0 , 1 , 29 , 21216 },/* 29 30 29 30 29 29 30 29 30 30 30 29 0 354
-1531 */{ 6 , 1 , 18 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-1532 */{ 0 , 2 , 6 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
-1533 */{ 0 , 1 , 25 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1534 */{ 2 , 1 , 14 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1535 */{ 0 , 2 , 2 , 46480 },/* 30 29 30 30 29 30 29 30 30 29 29 30 0 355
-1536 */{ 12 , 1 , 23 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
-1537 */{ 0 , 2 , 10 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-1538 */{ 0 , 1 , 31 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1539 */{ 7 , 1 , 20 , 37592 },/* 30 29 29 30 29 29 30 29 30 30 29 30 30 384
-1540 */{ 0 , 2 , 8 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
-1541 */{ 0 , 1 , 27 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1542 */{ 5 , 1 , 16 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-1543 */{ 0 , 2 , 4 , 27808 },/* 29 30 30 29 30 30 29 29 30 29 30 29 0 354
-1544 */{ 0 , 1 , 24 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1545 */{ 1 , 1 , 13 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-1546 */{ 0 , 2 , 1 , 19376 },/* 29 30 29 29 30 29 30 30 30 29 30 30 0 355
-1547 */{ 9 , 1 , 22 , 9656 },/* 29 29 30 29 29 30 29 30 30 29 30 30 30 384
-1548 */{ 0 , 2 , 10 , 9584 },/* 29 29 30 29 29 30 29 30 29 30 30 30 0 354
-1549 */{ 0 , 1 , 29 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1550 */{ 6 , 1 , 18 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 29 383
-1551 */{ 0 , 2 , 5 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
-1552 */{ 0 , 1 , 26 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1553 */{ 3 , 1 , 14 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1554 */{ 0 , 2 , 2 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1555 */{ 11 , 1 , 23 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
-1556 */{ 0 , 2 , 11 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1557 */{ 0 , 1 , 30 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1558 */{ 7 , 1 , 20 , 21096 },/* 29 30 29 30 29 29 30 29 29 30 30 29 30 383
-1559 */{ 0 , 2 , 7 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1560 */{ 0 , 1 , 27 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1561 */{ 5 , 1 , 16 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1562 */{ 0 , 2 , 4 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1563 */{ 0 , 1 , 24 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-1564 */{ 2 , 1 , 14 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1565 */{ 0 , 2 , 1 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1566 */{ 10 , 1 , 21 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1567 */{ 0 , 2 , 9 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1568 */{ 0 , 1 , 29 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1569 */{ 6 , 1 , 17 , 54600 },/* 30 30 29 30 29 30 29 30 29 30 29 29 30 384
-1570 */{ 0 , 2 , 5 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1571 */{ 0 , 1 , 26 , 13728 },/* 29 29 30 30 29 30 29 30 30 29 30 29 0 354
-1572 */{ 2 , 1 , 15 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 29 384
-1573 */{ 0 , 2 , 2 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1574 */{ 12 , 1 , 23 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1575 */{ 0 , 2 , 11 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1576 */{ 0 , 1 , 31 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1577 */{ 8 , 1 , 19 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1578 */{ 0 , 2 , 7 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1579 */{ 0 , 1 , 27 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1580 */{ 4 , 1 , 16 , 44456 },/* 30 29 30 29 30 30 29 30 30 29 30 29 30 385
-1581 */{ 0 , 2 , 4 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1582 */{ 0 , 1 , 24 , 39024 },/* 30 29 29 30 29 29 30 30 39 30 30 30 0 365
-1583 */{ 2 , 1 , 24 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
-1584 */{ 0 , 2 , 12 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1585 */{ 9 , 1 , 31 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
-1586 */{ 0 , 2 , 18 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1587 */{ 0 , 3 , 9 , 53968 },/* 30 30 29 30 29 30 29 29 30 29 30 0 0 325
-1588 */{ 6 , 1 , 28 , 27464 },/* 29 30 30 29 30 29 30 30 29 30 29 29 30 384
-1589 */{ 0 , 2 , 15 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1590 */{ 0 , 2 , 5 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1591 */{ 3 , 1 , 25 , 37616 },/* 30 29 29 30 29 29 30 29 30 30 30 30 29 384
-1592 */{ 0 , 2 , 13 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1593 */{ 11 , 2 , 1 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-1594 */{ 0 , 2 , 20 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1595 */{ 0 , 2 , 9 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1596 */{ 8 , 1 , 29 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1597 */{ 0 , 2 , 16 , 46288 },/* 30 29 30 30 29 30 29 29 30 30 29 30 0 355
-1598 */{ 0 , 2 , 6 , 22192 },/* 29 30 29 30 29 30 30 29 30 29 30 30 0 355
-1599 */{ 4 , 1 , 27 , 9944 },/* 29 29 30 29 29 30 30 29 30 30 29 30 30 384
-1600 */{ 0 , 2 , 15 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1601 */{ 0 , 2 , 3 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-1602 */{ 2 , 1 , 23 , 51608 },/* 30 30 29 29 30 29 29 30 30 29 29 30 30 384
-1603 */{ 0 , 2 , 11 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1604 */{ 9 , 1 , 31 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-1605 */{ 0 , 2 , 18 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1606 */{ 0 , 2 , 7 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1607 */{ 6 , 1 , 28 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-1608 */{ 0 , 2 , 16 , 19376 },/* 29 30 29 29 30 29 30 30 30 29 30 30 0 355
-1609 */{ 0 , 2 , 5 , 9648 },/* 29 29 30 29 29 30 29 30 30 29 30 30 0 354
-1610 */{ 3 , 1 , 25 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1611 */{ 0 , 2 , 13 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1612 */{ 11 , 2 , 2 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 29 383
-1613 */{ 0 , 2 , 19 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
-1614 */{ 0 , 2 , 9 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1615 */{ 8 , 1 , 29 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1616 */{ 0 , 2 , 17 , 39760 },/* 30 29 29 30 30 29 30 30 29 30 29 30 0 355
-1617 */{ 0 , 2 , 6 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1618 */{ 4 , 1 , 26 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1619 */{ 0 , 2 , 14 , 42224 },/* 30 29 30 29 29 30 29 29 30 30 30 30 0 355
-1620 */{ 0 , 2 , 4 , 21088 },/* 29 30 29 30 29 29 30 29 29 30 30 29 0 353
-1621 */{ 2 , 1 , 22 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-1622 */{ 0 , 2 , 10 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1623 */{ 10 , 1 , 31 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1624 */{ 0 , 2 , 19 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1625 */{ 0 , 2 , 7 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-1626 */{ 6 , 1 , 28 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1627 */{ 0 , 2 , 16 , 18912 },/* 29 30 29 29 30 29 29 30 30 30 30 29 0 354
-1628 */{ 0 , 2 , 5 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1629 */{ 4 , 1 , 24 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1630 */{ 0 , 2 , 12 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1631 */{ 11 , 2 , 1 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
-1632 */{ 0 , 2 , 20 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1633 */{ 0 , 2 , 8 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
-1634 */{ 8 , 1 , 29 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 29 384
-1635 */{ 0 , 2 , 17 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1636 */{ 0 , 2 , 7 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1637 */{ 4 , 1 , 26 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-1638 */{ 0 , 2 , 14 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1639 */{ 0 , 2 , 3 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1640 */{ 1 , 1 , 23 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-1641 */{ 0 , 2 , 10 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1642 */{ 11 , 1 , 30 , 44456 },/* 30 29 30 29 30 30 29 30 30 29 30 29 30 385
-1643 */{ 0 , 2 , 19 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1644 */{ 0 , 2 , 8 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1645 */{ 6 , 1 , 28 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
-1646 */{ 0 , 2 , 16 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1647 */{ 0 , 2 , 5 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1648 */{ 3 , 1 , 24 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1649 */{ 0 , 2 , 11 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-1650 */{ 11 , 2 , 1 , 27464 },/* 29 30 30 29 30 29 30 30 29 30 29 29 30 384
-1651 */{ 0 , 2 , 20 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1652 */{ 0 , 2 , 10 , 11168 },/* 29 29 30 29 30 29 30 30 30 29 30 29 0 354
-1653 */{ 7 , 1 , 29 , 37616 },/* 30 29 29 30 29 29 30 29 30 30 30 30 29 384
-1654 */{ 0 , 2 , 17 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1655 */{ 0 , 2 , 6 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1656 */{ 5 , 1 , 26 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1657 */{ 0 , 2 , 13 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1658 */{ 0 , 2 , 2 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-1659 */{ 3 , 1 , 23 , 39592 },/* 30 29 29 30 30 29 30 29 30 29 30 29 30 384
-1660 */{ 0 , 2 , 11 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1661 */{ 7 , 1 , 30 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 29 384
-1662 */{ 0 , 2 , 18 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 0 355
-1663 */{ 0 , 2 , 8 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-1664 */{ 6 , 1 , 28 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1665 */{ 0 , 2 , 15 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1666 */{ 0 , 2 , 4 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1667 */{ 4 , 1 , 24 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1668 */{ 0 , 2 , 12 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1669 */{ 0 , 2 , 1 , 21920 },/* 29 30 29 30 29 30 29 30 30 29 30 29 0 354
-1670 */{ 2 , 1 , 21 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 29 384
-1671 */{ 0 , 2 , 9 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-1672 */{ 7 , 1 , 30 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1673 */{ 0 , 2 , 17 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1674 */{ 0 , 2 , 6 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 0 354
-1675 */{ 5 , 1 , 26 , 29864 },/* 29 30 30 30 29 30 29 29 30 29 30 29 30 384
-1676 */{ 0 , 2 , 14 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1677 */{ 0 , 2 , 2 , 44432 },/* 30 29 30 29 30 30 29 30 30 29 29 30 0 355
-1678 */{ 3 , 1 , 23 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
-1679 */{ 0 , 2 , 11 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1680 */{ 8 , 1 , 31 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1681 */{ 0 , 2 , 18 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
-1682 */{ 0 , 2 , 7 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1683 */{ 6 , 1 , 27 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-1684 */{ 0 , 2 , 15 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
-1685 */{ 0 , 2 , 3 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
-1686 */{ 4 , 1 , 24 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
-1687 */{ 0 , 2 , 12 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1688 */{ 0 , 2 , 2 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1689 */{ 3 , 1 , 21 , 42216 },/* 30 29 30 29 29 30 29 29 30 30 30 29 30 384
-1690 */{ 0 , 2 , 9 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1691 */{ 7 , 1 , 29 , 53848 },/* 30 30 29 30 29 29 30 29 29 30 29 30 30 384
-1692 */{ 0 , 2 , 17 , 45136 },/* 30 29 29 32 29 29 29 29 29 30 29 30 0 354
-1693 */{ 0 , 2 , 5 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
-1694 */{ 5 , 1 , 25 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 29 384
-1695 */{ 0 , 2 , 13 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
-1696 */{ 0 , 2 , 3 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
-1697 */{ 3 , 1 , 23 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
-1698 */{ 0 , 2 , 11 , 18896 },/* 29 30 29 29 30 29 29 30 30 30 29 30 0 354
-1699 */{ 7 , 1 , 31 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-1700 */{ 0 , 2 , 19 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1701 */{ 0 , 2 , 8 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1702 */{ 6 , 1 , 28 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-1703 */{ 0 , 2 , 16 , 27936 },/* 29 30 30 29 30 30 29 30 29 29 30 29 0 354
-1704 */{ 0 , 2 , 5 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
-1705 */{ 4 , 1 , 25 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-1706 */{ 0 , 2 , 13 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1707 */{ 0 , 2 , 3 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1708 */{ 3 , 1 , 23 , 25784 },/* 29 30 30 29 29 30 29 29 30 29 30 30 30 384
-1709 */{ 0 , 2 , 10 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1710 */{ 7 , 1 , 30 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1711 */{ 0 , 2 , 17 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-1712 */{ 0 , 2 , 7 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1713 */{ 5 , 1 , 26 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 29 384
-1714 */{ 0 , 2 , 14 , 43744 },/* 30 29 30 29 30 29 30 29 30 30 30 29 0 355
-1715 */{ 0 , 2 , 4 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1716 */{ 3 , 1 , 24 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 29 384
-1717 */{ 0 , 2 , 11 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1718 */{ 8 , 1 , 31 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1719 */{ 0 , 2 , 19 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1720 */{ 0 , 2 , 8 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1721 */{ 6 , 1 , 28 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1722 */{ 0 , 2 , 16 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1723 */{ 0 , 2 , 5 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
-1724 */{ 4 , 1 , 26 , 21224 },/* 29 30 29 30 29 29 30 29 30 30 30 29 30 384
-1725 */{ 0 , 2 , 13 , 21200 },/* 29 30 29 30 29 29 30 29 30 30 29 30 0 354
-1726 */{ 0 , 2 , 2 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1727 */{ 3 , 1 , 22 , 58536 },/* 30 30 30 29 29 30 29 29 30 29 30 29 30 384
-1728 */{ 0 , 2 , 10 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1729 */{ 7 , 1 , 29 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1730 */{ 0 , 2 , 17 , 40272 },/* 30 29 29 30 30 30 29 30 29 30 29 30 0 355
-1731 */{ 0 , 2 , 7 , 21920 },/* 29 30 29 30 29 30 29 30 30 29 30 29 0 354
-1732 */{ 5 , 1 , 27 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 29 384
-1733 */{ 0 , 2 , 14 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-1734 */{ 0 , 2 , 4 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1735 */{ 4 , 1 , 24 , 43192 },/* 30 29 30 29 30 29 29 29 30 29 30 30 30 384
-1736 */{ 0 , 2 , 12 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 0 354
-1737 */{ 9 , 1 , 31 , 27288 },/* 29 30 30 29 30 29 30 29 30 29 29 30 30 384
-1738 */{ 0 , 2 , 19 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1739 */{ 0 , 2 , 8 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1740 */{ 6 , 1 , 29 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
-1741 */{ 0 , 2 , 16 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1742 */{ 0 , 2 , 5 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1743 */{ 4 , 1 , 26 , 20848 },/* 29 30 29 30 29 29 29 30 29 30 30 30 29 383
-1744 */{ 0 , 2 , 13 , 53600 },/* 30 30 29 30 29 29 29 30 29 30 30 29 0 354
-1745 */{ 0 , 2 , 1 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 0 355
-1746 */{ 3 , 1 , 22 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 29 383
-1747 */{ 0 , 2 , 9 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
-1748 */{ 7 , 1 , 30 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 29 384
-1749 */{ 0 , 2 , 17 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1750 */{ 0 , 2 , 7 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1751 */{ 5 , 1 , 27 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1752 */{ 0 , 2 , 15 , 41680 },/* 30 29 30 29 29 29 30 29 30 30 29 30 0 354
-1753 */{ 0 , 2 , 3 , 53592 },/* 30 30 29 30 29 29 29 30 29 30 29 30 30 384
-1754 */{ 4 , 2 , 22 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1755 */{ 0 , 2 , 11 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1756 */{ 9 , 1 , 31 , 54928 },/* 30 30 29 30 29 30 30 29 30 29 29 30 29 384
-1757 */{ 0 , 2 , 18 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
-1758 */{ 0 , 2 , 8 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
-1759 */{ 6 , 1 , 29 , 10968 },/* 29 29 30 29 30 29 30 29 30 30 29 30 30 384
-1760 */{ 0 , 2 , 17 , 17840 },/* 29 30 29 29 29 30 29 30 30 29 30 30 0 354
-1761 */{ 0 , 2 , 5 , 41648 },/* 30 29 30 29 29 29 30 29 30 29 30 30 0 354
-1762 */{ 5 , 1 , 25 , 45400 },/* 30 29 30 30 29 29 29 30 29 30 29 30 30 384
-1763 */{ 0 , 2 , 13 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1764 */{ 0 , 2 , 2 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1765 */{ 2 , 1 , 21 , 46480 },/* 30 29 30 30 29 30 29 30 30 29 29 30 29 384
-1766 */{ 0 , 2 , 9 , 44384 },/* 30 29 30 29 30 30 29 30 29 30 30 29 0 355
-1767 */{ 7 , 1 , 30 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-1768 */{ 0 , 2 , 18 , 21360 },/* 29 30 29 30 29 29 30 30 29 30 30 30 0 355
-1769 */{ 0 , 2 , 7 , 17776 },/* 29 30 29 29 29 30 29 30 29 30 30 30 0 354
-1770 */{ 5 , 1 , 27 , 25272 },/* 29 30 30 29 29 29 30 29 30 29 30 30 30 384
-1771 */{ 0 , 2 , 15 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1772 */{ 0 , 2 , 4 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1773 */{ 3 , 1 , 23 , 27816 },/* 29 30 30 29 30 30 29 29 30 29 30 29 30 384
-1774 */{ 0 , 2 , 11 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1775 */{ 10 , 1 , 31 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
-1776 */{ 0 , 2 , 19 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
-1777 */{ 0 , 2 , 8 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1778 */{ 6 , 1 , 28 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 29 384
-1779 */{ 0 , 2 , 16 , 42336 },/* 30 29 30 29 29 30 29 30 29 30 30 29 0 354
-1780 */{ 0 , 2 , 5 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
-1781 */{ 5 , 1 , 24 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 29 384
-1782 */{ 0 , 2 , 12 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1783 */{ 0 , 2 , 2 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1784 */{ 3 , 1 , 22 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
-1785 */{ 0 , 2 , 9 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
-1786 */{ 7 , 1 , 30 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1787 */{ 0 , 2 , 18 , 19120 },/* 29 30 29 29 30 29 30 29 30 29 30 30 0 354
-1788 */{ 0 , 2 , 7 , 43216 },/* 30 29 30 29 30 29 29 29 30 30 29 30 0 354
-1789 */{ 5 , 1 , 26 , 53928 },/* 30 30 29 30 29 29 30 29 30 29 30 29 30 384
-1790 */{ 0 , 2 , 14 , 45728 },/* 30 29 30 30 29 29 30 29 30 29 30 29 0 354
-1791 */{ 0 , 2 , 3 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1792 */{ 4 , 1 , 24 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1793 */{ 0 , 2 , 11 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
-1794 */{ 0 , 1 , 31 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1795 */{ 2 , 1 , 21 , 19128 },/* 29 30 29 29 30 29 30 29 30 29 30 30 30 384
-1796 */{ 0 , 2 , 9 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1797 */{ 6 , 1 , 28 , 43192 },/* 30 29 30 29 30 29 29 29 30 29 30 30 30 384
-1798 */{ 0 , 2 , 16 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1799 */{ 0 , 2 , 5 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 0 354
-1800 */{ 4 , 1 , 25 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1801 */{ 0 , 2 , 13 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 0 355
-1802 */{ 0 , 2 , 3 , 11168 },/* 29 29 30 29 30 29 30 30 30 29 30 29 0 354
-1803 */{ 2 , 1 , 23 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 29 384
-1804 */{ 0 , 2 , 11 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1805 */{ 6 , 1 , 31 , 20848 },/* 29 30 29 30 29 29 29 30 29 30 30 30 29 383
-1806 */{ 0 , 2 , 18 , 53600 },/* 30 30 29 30 29 29 29 30 29 30 30 29 0 354
-1807 */{ 0 , 2 , 7 , 58544 },/* 30 30 30 29 29 30 29 29 30 29 30 30 0 355
-1808 */{ 5 , 1 , 28 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 29 383
-1809 */{ 0 , 2 , 14 , 55952 },/* 30 30 29 30 30 29 30 29 30 29 29 30 0 355
-1810 */{ 0 , 2 , 4 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 0 355
-1811 */{ 3 , 1 , 25 , 11112 },/* 29 29 30 29 30 29 30 30 29 30 30 29 30 384
-1812 */{ 0 , 2 , 13 , 10976 },/* 29 29 30 29 30 29 30 29 30 30 30 29 0 354
-1813 */{ 0 , 2 , 1 , 41696 },/* 30 29 30 29 29 29 30 29 30 30 30 29 0 354
-1814 */{ 2 , 1 , 21 , 53608 },/* 30 30 29 30 29 29 29 30 29 30 30 29 30 384
-1815 */{ 0 , 2 , 9 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
-1816 */{ 6 , 1 , 29 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1817 */{ 0 , 2 , 16 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1818 */{ 0 , 2 , 5 , 46736 },/* 30 29 30 30 29 30 30 29 30 29 29 30 0 355
-1819 */{ 4 , 1 , 26 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
-1820 */{ 0 , 2 , 14 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
-1821 */{ 0 , 2 , 3 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1822 */{ 3 , 1 , 23 , 41688 },/* 30 29 30 29 29 29 30 29 30 30 29 30 30 384
-1823 */{ 0 , 2 , 11 , 41648 },/* 30 29 30 29 29 29 30 29 30 29 30 30 0 354
-1824 */{ 7 , 1 , 31 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1825 */{ 0 , 2 , 18 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1826 */{ 0 , 2 , 7 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1827 */{ 5 , 1 , 27 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1828 */{ 0 , 2 , 15 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1829 */{ 0 , 2 , 4 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-1830 */{ 4 , 1 , 25 , 9656 },/* 29 29 30 29 29 30 29 30 30 29 30 30 30 384
-1831 */{ 0 , 2 , 13 , 9584 },/* 29 29 30 29 29 30 29 30 29 30 30 30 0 354
-1832 */{ 9 , 2 , 2 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1833 */{ 0 , 2 , 20 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1834 */{ 0 , 2 , 9 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1835 */{ 6 , 1 , 29 , 27816 },/* 29 30 30 29 30 30 29 29 30 29 30 29 30 384
-1836 */{ 0 , 2 , 17 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1837 */{ 0 , 2 , 5 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1838 */{ 4 , 1 , 26 , 21352 },/* 29 30 29 30 29 29 30 30 29 30 30 29 30 384
-1839 */{ 0 , 2 , 14 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1840 */{ 0 , 2 , 3 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1841 */{ 3 , 1 , 23 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 29 383
-1842 */{ 0 , 2 , 10 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
-1843 */{ 7 , 1 , 30 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 29 384
-1844 */{ 0 , 2 , 18 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1845 */{ 0 , 2 , 7 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1846 */{ 5 , 1 , 27 , 43728 },/* 30 29 30 29 30 29 30 29 30 30 29 30 29 384
-1847 */{ 0 , 2 , 15 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1848 */{ 0 , 2 , 5 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1849 */{ 4 , 1 , 24 , 42328 },/* 30 29 30 29 29 30 29 30 29 30 29 30 30 384
-1850 */{ 0 , 2 , 12 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1851 */{ 8 , 2 , 1 , 53848 },/* 30 30 29 30 29 29 30 29 29 30 29 30 30 384
-1852 */{ 0 , 2 , 20 , 45712 },/* 30 29 30 30 29 29 30 29 30 29 29 30 0 354
-1853 */{ 0 , 2 , 8 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1854 */{ 7 , 1 , 29 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1855 */{ 0 , 2 , 17 , 11680 },/* 29 29 30 29 30 30 29 30 30 29 30 29 0 354
-1856 */{ 0 , 2 , 6 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1857 */{ 5 , 1 , 26 , 19128 },/* 29 30 29 29 30 29 30 29 30 29 30 30 30 384
-1858 */{ 0 , 2 , 14 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1859 */{ 0 , 2 , 3 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1860 */{ 3 , 1 , 23 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1861 */{ 0 , 2 , 10 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 0 354
-1862 */{ 8 , 1 , 30 , 44360 },/* 30 29 30 29 30 30 29 30 29 30 29 29 30 384
-1863 */{ 0 , 2 , 18 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 0 355
-1864 */{ 0 , 2 , 8 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1865 */{ 5 , 1 , 27 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 29 384
-1866 */{ 0 , 2 , 15 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1867 */{ 0 , 2 , 5 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1868 */{ 4 , 1 , 25 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
-1869 */{ 0 , 2 , 11 , 58528 },/* 30 30 30 29 29 30 29 29 30 29 30 29 0 354
-1870 */{ 10 , 1 , 31 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 29 384
-1871 */{ 0 , 2 , 19 , 55952 },/* 30 30 29 30 30 29 30 29 30 29 29 30 0 355
-1872 */{ 0 , 2 , 9 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
-1873 */{ 6 , 1 , 29 , 11112 },/* 29 29 30 29 30 29 30 30 29 30 30 29 30 384
-1874 */{ 0 , 2 , 17 , 10976 },/* 29 29 30 29 30 29 30 29 30 30 30 29 0 354
-1875 */{ 0 , 2 , 6 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1876 */{ 5 , 1 , 26 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-1877 */{ 0 , 2 , 13 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
-1878 */{ 0 , 2 , 2 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1879 */{ 3 , 1 , 22 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1880 */{ 0 , 2 , 10 , 46736 },/* 30 29 30 30 29 30 30 29 30 29 29 30 0 355
-1881 */{ 7 , 1 , 30 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
-1882 */{ 0 , 2 , 18 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-1883 */{ 0 , 2 , 8 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1884 */{ 5 , 1 , 28 , 37592 },/* 30 29 29 30 29 29 30 29 30 30 29 30 30 384
-1885 */{ 0 , 2 , 15 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
-1886 */{ 0 , 2 , 4 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1887 */{ 4 , 1 , 24 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1888 */{ 0 , 2 , 12 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1889 */{ 0 , 1 , 31 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1890 */{ 2 , 1 , 21 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1891 */{ 0 , 2 , 9 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-1892 */{ 6 , 1 , 30 , 9656 },/* 29 29 30 29 29 30 29 30 30 29 30 30 30 384
-1893 */{ 0 , 2 , 17 , 9584 },/* 29 29 30 29 29 30 29 30 29 30 30 30 0 354
-1894 */{ 0 , 2 , 6 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1895 */{ 5 , 1 , 26 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 29 383
-1896 */{ 0 , 2 , 13 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
-1897 */{ 0 , 2 , 2 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1898 */{ 3 , 1 , 22 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1899 */{ 0 , 2 , 10 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1900 */{ 8 , 1 , 31 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
-1901 */{ 0 , 2 , 19 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1902 */{ 0 , 2 , 8 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1903 */{ 5 , 1 , 29 , 21096 },/* 29 30 29 30 29 29 30 29 29 30 30 29 30 383
-1904 */{ 0 , 2 , 16 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1905 */{ 0 , 2 , 4 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1906 */{ 4 , 1 , 25 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
-1907 */{ 0 , 2 , 13 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1908 */{ 0 , 2 , 2 , 39632 },/* 30 29 29 30 30 29 30 29 30 30 29 30 0 355
-1909 */{ 2 , 1 , 22 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1910 */{ 0 , 2 , 10 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1911 */{ 6 , 1 , 30 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1912 */{ 0 , 2 , 18 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1913 */{ 0 , 2 , 6 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1914 */{ 5 , 1 , 26 , 55624 },/* 30 30 29 30 30 29 29 30 29 30 29 29 30 384
-1915 */{ 0 , 2 , 14 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1916 */{ 0 , 2 , 4 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1917 */{ 2 , 1 , 23 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1918 */{ 0 , 2 , 11 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1919 */{ 7 , 2 , 1 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
-1920 */{ 0 , 2 , 20 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1921 */{ 0 , 2 , 8 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1922 */{ 5 , 1 , 28 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1923 */{ 0 , 2 , 16 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 0 354
-1924 */{ 0 , 2 , 5 , 44352 },/* 30 29 30 29 30 30 29 30 29 30 29 29 0 354
-1925 */{ 4 , 1 , 24 , 46504 },/* 30 29 30 30 29 30 29 30 30 29 30 29 30 385
-1926 */{ 0 , 2 , 13 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1927 */{ 0 , 2 , 2 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1928 */{ 2 , 1 , 23 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1929 */{ 0 , 2 , 10 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1930 */{ 6 , 1 , 30 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
-1931 */{ 0 , 2 , 17 , 58528 },/* 30 30 30 29 29 30 29 29 30 29 30 29 0 354
-1932 */{ 0 , 2 , 6 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-1933 */{ 5 , 1 , 26 , 27976 },/* 29 30 30 29 30 30 29 30 29 30 29 29 30 384
-1934 */{ 0 , 2 , 14 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 0 355
-1935 */{ 0 , 2 , 4 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1936 */{ 3 , 1 , 24 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 29 384
-1937 */{ 0 , 2 , 11 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1938 */{ 7 , 1 , 31 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-1939 */{ 0 , 2 , 19 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
-1940 */{ 0 , 2 , 8 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1941 */{ 6 , 1 , 27 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1942 */{ 0 , 2 , 15 , 46736 },/* 30 29 30 30 29 30 30 29 30 29 29 30 0 355
-1943 */{ 0 , 2 , 5 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1944 */{ 4 , 1 , 26 , 10968 },/* 29 29 30 29 30 29 30 29 30 30 29 30 30 384
-1945 */{ 0 , 2 , 13 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1946 */{ 0 , 2 , 2 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-1947 */{ 2 , 1 , 22 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-1948 */{ 0 , 2 , 10 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1949 */{ 7 , 1 , 29 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1950 */{ 0 , 2 , 17 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1951 */{ 0 , 2 , 6 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1952 */{ 5 , 1 , 27 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1953 */{ 0 , 2 , 14 , 19888 },/* 29 30 29 29 30 30 29 30 30 29 30 30 0 355
-1954 */{ 0 , 2 , 4 , 9648 },/* 29 29 30 29 29 30 29 30 30 29 30 30 0 354
-1955 */{ 3 , 1 , 24 , 37560 },/* 30 29 29 30 29 29 30 29 30 29 30 30 30 384
-1956 */{ 0 , 2 , 12 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1957 */{ 8 , 1 , 31 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1958 */{ 0 , 2 , 19 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1959 */{ 0 , 2 , 8 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1960 */{ 6 , 1 , 28 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1961 */{ 0 , 2 , 15 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1962 */{ 0 , 2 , 5 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1963 */{ 4 , 1 , 25 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1964 */{ 0 , 2 , 13 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1965 */{ 0 , 2 , 2 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
-1966 */{ 3 , 1 , 22 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 29 383
-1967 */{ 0 , 2 , 9 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1968 */{ 7 , 1 , 30 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
-1969 */{ 0 , 2 , 17 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1970 */{ 0 , 2 , 6 , 39632 },/* 30 29 29 30 30 29 30 29 30 30 29 30 0 355
-1971 */{ 5 , 1 , 27 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1972 */{ 0 , 2 , 15 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1973 */{ 0 , 2 , 3 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
-1974 */{ 4 , 1 , 23 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1975 */{ 0 , 2 , 11 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1976 */{ 8 , 1 , 31 , 54600 },/* 30 30 29 30 29 30 29 30 29 30 29 29 30 384
-1977 */{ 0 , 2 , 18 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1978 */{ 0 , 2 , 7 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 0 355
-1979 */{ 6 , 1 , 28 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1980 */{ 0 , 2 , 16 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1981 */{ 0 , 2 , 5 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1982 */{ 4 , 1 , 25 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1983 */{ 0 , 2 , 13 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1984 */{ 10 , 2 , 2 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1985 */{ 0 , 2 , 20 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1986 */{ 0 , 2 , 9 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1987 */{ 6 , 1 , 29 , 46504 },/* 30 29 30 30 29 30 29 30 30 29 30 29 30 385
-1988 */{ 0 , 2 , 18 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1989 */{ 0 , 2 , 6 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1990 */{ 5 , 1 , 27 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1991 */{ 0 , 2 , 15 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1992 */{ 0 , 2 , 4 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1993 */{ 3 , 1 , 23 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1994 */{ 0 , 2 , 10 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-1995 */{ 8 , 1 , 31 , 27976 },/* 29 30 30 29 30 30 29 30 29 30 29 29 30 384
-1996 */{ 0 , 2 , 19 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
-1997 */{ 0 , 2 , 8 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1998 */{ 5 , 1 , 28 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
-1999 */{ 0 , 2 , 16 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-2000 */{ 0 , 2 , 5 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-2001 */{ 4 , 1 , 24 , 58536 },/* 30 30 30 29 29 30 29 29 30 29 30 29 30 384
-2002 */{ 0 , 2 , 12 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-2003 */{ 0 , 2 , 1 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-2004 */{ 2 , 1 , 22 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-2005 */{ 0 , 2 , 9 , 22208 },/* 29 30 29 30 29 30 30 29 30 30 29 29 0 354
-2006 */{ 7 , 1 , 29 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
-2007 */{ 0 , 2 , 18 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-2008 */{ 0 , 2 , 7 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-2009 */{ 5 , 1 , 26 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-2010 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-2011 */{ 0 , 2 , 3 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-2012 */{ 3 , 1 , 23 , 47696 },/* 30 29 30 30 30 29 30 29 29 30 29 30 29 384
-2013 */{ 0 , 2 , 10 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-2014 */{ 9 , 1 , 31 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-2015 */{ 0 , 2 , 19 , 19360 },/* 29 30 29 29 30 29 30 30 30 29 30 29 0 354
-2016 */{ 0 , 2 , 8 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-2017 */{ 5 , 1 , 28 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-2018 */{ 0 , 2 , 16 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-2019 */{ 0 , 2 , 5 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-2020 */{ 4 , 1 , 25 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-2021 */{ 0 , 2 , 12 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-2022 */{ 0 , 2 , 1 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2023 */{ 2 , 1 , 22 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-2024 */{ 0 , 2 , 10 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-2025 */{ 6 , 1 , 29 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-2026 */{ 0 , 2 , 17 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-2027 */{ 0 , 2 , 7 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
-2028 */{ 5 , 1 , 27 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 29 383
-2029 */{ 0 , 2 , 13 , 55600 },/* 30 30 29 30 30 29 29 30 29 29 30 30 0 355
-2030 */{ 0 , 2 , 3 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-2031 */{ 3 , 1 , 23 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
-2032 */{ 0 , 2 , 11 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-2033 */{ 11 , 1 , 31 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-2034 */{ 0 , 2 , 19 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-2035 */{ 0 , 2 , 8 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-2036 */{ 6 , 1 , 28 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-2037 */{ 0 , 2 , 15 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-2038 */{ 0 , 2 , 4 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
-2039 */{ 5 , 1 , 24 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 29 384
-2040 */{ 0 , 2 , 12 , 46752 },/* 30 29 30 30 29 30 30 29 30 29 30 29 0 355
-2041 */{ 0 , 2 , 1 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-2042 */{ 2 , 1 , 22 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
-2043 */{ 0 , 2 , 10 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-2044 */{ 7 , 1 , 30 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-2045 */{ 0 , 2 , 17 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-2046 */{ 0 , 2 , 6 , 45648 },/* 30 29 30 30 29 29 30 29 29 30 29 30 0 354
-2047 */{ 5 , 1 , 26 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-2048 */{ 0 , 2 , 14 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-2049 */{ 0 , 2 , 2 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
-2050 */{ 3 , 1 , 23 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 29 384
- */};
-
-
- internal override int MinCalendarYear
- {
- get
- {
- return (MIN_LUNISOLAR_YEAR);
- }
- }
-
- internal override int MaxCalendarYear
- {
- get
- {
- return (MAX_LUNISOLAR_YEAR);
- }
- }
-
- internal override DateTime MinDate
- {
- get
- {
- return (minDate);
- }
- }
-
- internal override DateTime MaxDate
- {
- get
- {
- return (maxDate);
- }
- }
-
- internal override EraInfo[] CalEraInfo
- {
- get
- {
- return null;
- }
- }
-
- internal override int GetYearInfo(int lunarYear, int index)
- {
- if ((lunarYear < MIN_LUNISOLAR_YEAR) || (lunarYear > MAX_LUNISOLAR_YEAR))
- {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- MIN_LUNISOLAR_YEAR,
- MAX_LUNISOLAR_YEAR));
- }
- Contract.EndContractBlock();
- return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index];
- }
-
- internal override int GetYear(int year, DateTime time)
- {
- return year;
- }
-
- internal override int GetGregorianYear(int year, int era)
- {
- if (era != CurrentEra && era != GregorianEra)
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
-
- if (year < MIN_LUNISOLAR_YEAR || year > MAX_LUNISOLAR_YEAR)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range, MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR));
- }
- Contract.EndContractBlock();
-
- return year;
- }
-
- public KoreanLunisolarCalendar()
- {
- }
-
- public override int GetEra(DateTime time)
- {
- CheckTicksRange(time.Ticks);
- return (GregorianEra);
- }
-
- internal override CalendarId BaseCalendarID
- {
- get
- {
- return (CalendarId.KOREA);
- }
- }
-
- internal override CalendarId ID
- {
- get
- {
- return (CalendarId.KOREANLUNISOLAR);
- }
- }
-
-
-
- public override int[] Eras
- {
- get
- {
- return (new int[] { GregorianEra });
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/NumberFormatInfo.cs b/src/mscorlib/corefx/System/Globalization/NumberFormatInfo.cs
deleted file mode 100644
index 54cf492135..0000000000
--- a/src/mscorlib/corefx/System/Globalization/NumberFormatInfo.cs
+++ /dev/null
@@ -1,900 +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.Diagnostics.Contracts;
-using System.Runtime.Serialization;
-using System.Text;
-
-namespace System.Globalization
-{
- //
- // Property Default Description
- // PositiveSign '+' Character used to indicate positive values.
- // NegativeSign '-' Character used to indicate negative values.
- // NumberDecimalSeparator '.' The character used as the decimal separator.
- // NumberGroupSeparator ',' The character used to separate groups of
- // digits to the left of the decimal point.
- // NumberDecimalDigits 2 The default number of decimal places.
- // NumberGroupSizes 3 The number of digits in each group to the
- // left of the decimal point.
- // NaNSymbol "NaN" The string used to represent NaN values.
- // PositiveInfinitySymbol"Infinity" The string used to represent positive
- // infinities.
- // NegativeInfinitySymbol"-Infinity" The string used to represent negative
- // infinities.
- //
- //
- //
- // Property Default Description
- // CurrencyDecimalSeparator '.' The character used as the decimal
- // separator.
- // CurrencyGroupSeparator ',' The character used to separate groups
- // of digits to the left of the decimal
- // point.
- // CurrencyDecimalDigits 2 The default number of decimal places.
- // CurrencyGroupSizes 3 The number of digits in each group to
- // the left of the decimal point.
- // CurrencyPositivePattern 0 The format of positive values.
- // CurrencyNegativePattern 0 The format of negative values.
- // CurrencySymbol "$" String used as local monetary symbol.
- //
-
- [Serializable]
- sealed public class NumberFormatInfo : IFormatProvider, ICloneable
- {
- // invariantInfo is constant irrespective of your current culture.
- private static volatile NumberFormatInfo s_invariantInfo;
-
- // READTHIS READTHIS READTHIS
- // This class has an exact mapping onto a native structure defined in COMNumber.cpp
- // DO NOT UPDATE THIS WITHOUT UPDATING THAT STRUCTURE. IF YOU ADD BOOL, ADD THEM AT THE END.
- // ALSO MAKE SURE TO UPDATE mscorlib.h in the VM directory to check field offsets.
- // READTHIS READTHIS READTHIS
- internal int[] numberGroupSizes = new int[] { 3 };
- internal int[] currencyGroupSizes = new int[] { 3 };
- internal int[] percentGroupSizes = new int[] { 3 };
- internal String positiveSign = "+";
- internal String negativeSign = "-";
- internal String numberDecimalSeparator = ".";
- internal String numberGroupSeparator = ",";
- internal String currencyGroupSeparator = ",";
- internal String currencyDecimalSeparator = ".";
- internal String currencySymbol = "$"; // TODO: CoreFX #846 Restore to the original value "\x00a4"; // U+00a4 is the symbol for International Monetary Fund.
- internal String nanSymbol = "NaN";
- internal String positiveInfinitySymbol = "Infinity";
- internal String negativeInfinitySymbol = "-Infinity";
- internal String percentDecimalSeparator = ".";
- internal String percentGroupSeparator = ",";
- internal String percentSymbol = "%";
- internal String perMilleSymbol = "\u2030";
-
-
- [OptionalField(VersionAdded = 2)]
- internal String[] nativeDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
-
- internal int numberDecimalDigits = 2;
- internal int currencyDecimalDigits = 2;
- internal int currencyPositivePattern = 0;
- internal int currencyNegativePattern = 0;
- internal int numberNegativePattern = 1;
- internal int percentPositivePattern = 0;
- internal int percentNegativePattern = 0;
- internal int percentDecimalDigits = 2;
-
- [OptionalField(VersionAdded = 2)]
- internal int digitSubstitution = (int) DigitShapes.None;
-
- internal bool isReadOnly = false;
-
- // Is this NumberFormatInfo for invariant culture?
-
- [OptionalField(VersionAdded = 2)]
- internal bool m_isInvariant = false;
-
- public NumberFormatInfo() : this(null)
- {
- }
-
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx) { }
-
- [OnDeserializing]
- private void OnDeserializing(StreamingContext ctx) { }
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext ctx) { }
-
- private static void VerifyDecimalSeparator(String decSep, String propertyName)
- {
- if (decSep == null)
- {
- throw new ArgumentNullException(propertyName,
- SR.ArgumentNull_String);
- }
-
- if (decSep.Length == 0)
- {
- throw new ArgumentException(SR.Argument_EmptyDecString);
- }
- Contract.EndContractBlock();
- }
-
- private static void VerifyGroupSeparator(String groupSep, String propertyName)
- {
- if (groupSep == null)
- {
- throw new ArgumentNullException(propertyName,
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
- }
-
- private static void VerifyNativeDigits(string [] nativeDig, string propertyName)
- {
- if (nativeDig == null)
- {
- throw new ArgumentNullException(propertyName, SR.ArgumentNull_Array);
- }
-
- if (nativeDig.Length != 10)
- {
- throw new ArgumentException(SR.Argument_InvalidNativeDigitCount, propertyName);
- }
- Contract.EndContractBlock();
-
- for (int i = 0; i < nativeDig.Length; i++)
- {
- if (nativeDig[i] == null)
- {
- throw new ArgumentNullException(propertyName, SR.ArgumentNull_ArrayValue);
- }
-
- if (nativeDig[i].Length != 1)
- {
- if (nativeDig[i].Length != 2)
- {
- // Not 1 or 2 UTF-16 code points
- throw new ArgumentException(SR.Argument_InvalidNativeDigitValue, propertyName);
- }
- else if (!char.IsSurrogatePair(nativeDig[i][0], nativeDig[i][1]))
- {
- // 2 UTF-6 code points, but not a surrogate pair
- throw new ArgumentException(SR.Argument_InvalidNativeDigitValue, propertyName);
- }
- }
-
- if (CharUnicodeInfo.GetDecimalDigitValue(nativeDig[i], 0) != i &&
- CharUnicodeInfo.GetUnicodeCategory(nativeDig[i], 0) != UnicodeCategory.PrivateUse)
- {
- // Not the appropriate digit according to the Unicode data properties
- // (Digit 0 must be a 0, etc.).
- throw new ArgumentException(SR.Argument_InvalidNativeDigitValue, propertyName);
- }
- }
- }
-
- private static void VerifyDigitSubstitution(DigitShapes digitSub, string propertyName)
- {
- switch (digitSub)
- {
- case DigitShapes.Context:
- case DigitShapes.None:
- case DigitShapes.NativeNational:
- // Success.
- break;
-
- default:
- throw new ArgumentException(SR.Argument_InvalidDigitSubstitution, propertyName);
- }
- }
-
- internal NumberFormatInfo(CultureData cultureData)
- {
- if (cultureData != null)
- {
- // We directly use fields here since these data is coming from data table or Win32, so we
- // don't need to verify their values (except for invalid parsing situations).
- cultureData.GetNFIValues(this);
-
- if (cultureData.IsInvariantCulture)
- {
- // For invariant culture
- this.m_isInvariant = true;
- }
- }
- }
-
- [Pure]
- private void VerifyWritable()
- {
- if (isReadOnly)
- {
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- }
- Contract.EndContractBlock();
- }
-
- // Returns a default NumberFormatInfo that will be universally
- // supported and constant irrespective of the current culture.
- // Used by FromString methods.
- //
-
- public static NumberFormatInfo InvariantInfo
- {
- get
- {
- if (s_invariantInfo == null)
- {
- // Lazy create the invariant info. This cannot be done in a .cctor because exceptions can
- // be thrown out of a .cctor stack that will need this.
- NumberFormatInfo nfi = new NumberFormatInfo();
- nfi.m_isInvariant = true;
- s_invariantInfo = ReadOnly(nfi);
- }
- return s_invariantInfo;
- }
- }
-
- public static NumberFormatInfo GetInstance(IFormatProvider formatProvider)
- {
- // Fast case for a regular CultureInfo
- NumberFormatInfo info;
- CultureInfo cultureProvider = formatProvider as CultureInfo;
- if (cultureProvider != null && !cultureProvider.m_isInherited)
- {
- info = cultureProvider.numInfo;
- if (info != null)
- {
- return info;
- }
- else
- {
- return cultureProvider.NumberFormat;
- }
- }
- // Fast case for an NFI;
- info = formatProvider as NumberFormatInfo;
- if (info != null)
- {
- return info;
- }
- if (formatProvider != null)
- {
- info = formatProvider.GetFormat(typeof(NumberFormatInfo)) as NumberFormatInfo;
- if (info != null)
- {
- return info;
- }
- }
- return CurrentInfo;
- }
-
-
-
- public Object Clone()
- {
- NumberFormatInfo n = (NumberFormatInfo)MemberwiseClone();
- n.isReadOnly = false;
- return n;
- }
-
-
- public int CurrencyDecimalDigits
- {
- get { return currencyDecimalDigits; }
- set
- {
- if (value < 0 || value > 99)
- {
- throw new ArgumentOutOfRangeException(
- nameof(CurrencyDecimalDigits),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 99));
- }
- Contract.EndContractBlock();
- VerifyWritable();
- currencyDecimalDigits = value;
- }
- }
-
-
- public String CurrencyDecimalSeparator
- {
- get { return currencyDecimalSeparator; }
- set
- {
- VerifyWritable();
- VerifyDecimalSeparator(value, "CurrencyDecimalSeparator");
- currencyDecimalSeparator = value;
- }
- }
-
-
- public bool IsReadOnly
- {
- get
- {
- return isReadOnly;
- }
- }
-
- //
- // Check the values of the groupSize array.
- //
- // Every element in the groupSize array should be between 1 and 9
- // excpet the last element could be zero.
- //
- internal static void CheckGroupSize(String propName, int[] groupSize)
- {
- for (int i = 0; i < groupSize.Length; i++)
- {
- if (groupSize[i] < 1)
- {
- if (i == groupSize.Length - 1 && groupSize[i] == 0)
- return;
- throw new ArgumentException(SR.Argument_InvalidGroupSize, propName);
- }
- else if (groupSize[i] > 9)
- {
- throw new ArgumentException(SR.Argument_InvalidGroupSize, propName);
- }
- }
- }
-
-
- public int[] CurrencyGroupSizes
- {
- get
- {
- return ((int[])currencyGroupSizes.Clone());
- }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(CurrencyGroupSizes),
- SR.ArgumentNull_Obj);
- }
- Contract.EndContractBlock();
- VerifyWritable();
-
- Int32[] inputSizes = (Int32[])value.Clone();
- CheckGroupSize(nameof(CurrencyGroupSizes), inputSizes);
- currencyGroupSizes = inputSizes;
- }
- }
-
-
-
- public int[] NumberGroupSizes
- {
- get
- {
- return ((int[])numberGroupSizes.Clone());
- }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(NumberGroupSizes),
- SR.ArgumentNull_Obj);
- }
- Contract.EndContractBlock();
- VerifyWritable();
-
- Int32[] inputSizes = (Int32[])value.Clone();
- CheckGroupSize(nameof(NumberGroupSizes), inputSizes);
- numberGroupSizes = inputSizes;
- }
- }
-
-
- public int[] PercentGroupSizes
- {
- get
- {
- return ((int[])percentGroupSizes.Clone());
- }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException("PercentGroupSizes",
- SR.ArgumentNull_Obj);
- }
- Contract.EndContractBlock();
- VerifyWritable();
- Int32[] inputSizes = (Int32[])value.Clone();
- CheckGroupSize("PercentGroupSizes", inputSizes);
- percentGroupSizes = inputSizes;
- }
- }
-
-
- public String CurrencyGroupSeparator
- {
- get { return currencyGroupSeparator; }
- set
- {
- VerifyWritable();
- VerifyGroupSeparator(value, nameof(CurrencyGroupSeparator));
- currencyGroupSeparator = value;
- }
- }
-
-
- public String CurrencySymbol
- {
- get { return currencySymbol; }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(CurrencySymbol),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
- VerifyWritable();
- currencySymbol = value;
- }
- }
-
- // Returns the current culture's NumberFormatInfo. Used by Parse methods.
- //
-
- public static NumberFormatInfo CurrentInfo
- {
- get
- {
- System.Globalization.CultureInfo culture = CultureInfo.CurrentCulture;
- if (!culture.m_isInherited)
- {
- NumberFormatInfo info = culture.numInfo;
- if (info != null)
- {
- return info;
- }
- }
- return ((NumberFormatInfo)culture.GetFormat(typeof(NumberFormatInfo)));
- }
- }
-
-
- public String NaNSymbol
- {
- get
- {
- return nanSymbol;
- }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(NaNSymbol),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
- VerifyWritable();
- nanSymbol = value;
- }
- }
-
-
-
- public int CurrencyNegativePattern
- {
- get { return currencyNegativePattern; }
- set
- {
- if (value < 0 || value > 15)
- {
- throw new ArgumentOutOfRangeException(
- nameof(CurrencyNegativePattern),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 15));
- }
- Contract.EndContractBlock();
- VerifyWritable();
- currencyNegativePattern = value;
- }
- }
-
-
- public int NumberNegativePattern
- {
- get { return numberNegativePattern; }
- set
- {
- //
- // NOTENOTE: the range of value should correspond to negNumberFormats[] in vm\COMNumber.cpp.
- //
- if (value < 0 || value > 4)
- {
- throw new ArgumentOutOfRangeException(
- nameof(NumberNegativePattern),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 4));
- }
- Contract.EndContractBlock();
- VerifyWritable();
- numberNegativePattern = value;
- }
- }
-
-
- public int PercentPositivePattern
- {
- get { return percentPositivePattern; }
- set
- {
- //
- // NOTENOTE: the range of value should correspond to posPercentFormats[] in vm\COMNumber.cpp.
- //
- if (value < 0 || value > 3)
- {
- throw new ArgumentOutOfRangeException(
- nameof(PercentPositivePattern),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 3));
- }
- Contract.EndContractBlock();
- VerifyWritable();
- percentPositivePattern = value;
- }
- }
-
-
- public int PercentNegativePattern
- {
- get { return percentNegativePattern; }
- set
- {
- //
- // NOTENOTE: the range of value should correspond to posPercentFormats[] in vm\COMNumber.cpp.
- //
- if (value < 0 || value > 11)
- {
- throw new ArgumentOutOfRangeException(
- nameof(PercentNegativePattern),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 11));
- }
- Contract.EndContractBlock();
- VerifyWritable();
- percentNegativePattern = value;
- }
- }
-
-
- public String NegativeInfinitySymbol
- {
- get
- {
- return negativeInfinitySymbol;
- }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(NegativeInfinitySymbol),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
- VerifyWritable();
- negativeInfinitySymbol = value;
- }
- }
-
-
- public String NegativeSign
- {
- get { return negativeSign; }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(NegativeSign),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
- VerifyWritable();
- negativeSign = value;
- }
- }
-
-
- public int NumberDecimalDigits
- {
- get { return numberDecimalDigits; }
- set
- {
- if (value < 0 || value > 99)
- {
- throw new ArgumentOutOfRangeException(
- nameof(NumberDecimalDigits),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 99));
- }
- Contract.EndContractBlock();
- VerifyWritable();
- numberDecimalDigits = value;
- }
- }
-
-
- public String NumberDecimalSeparator
- {
- get { return numberDecimalSeparator; }
- set
- {
- VerifyWritable();
- VerifyDecimalSeparator(value, nameof(NumberDecimalSeparator));
- numberDecimalSeparator = value;
- }
- }
-
-
- public String NumberGroupSeparator
- {
- get { return numberGroupSeparator; }
- set
- {
- VerifyWritable();
- VerifyGroupSeparator(value, nameof(NumberGroupSeparator));
- numberGroupSeparator = value;
- }
- }
-
-
- public int CurrencyPositivePattern
- {
- get { return currencyPositivePattern; }
- set
- {
- if (value < 0 || value > 3)
- {
- throw new ArgumentOutOfRangeException(
- nameof(CurrencyPositivePattern),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 3));
- }
- Contract.EndContractBlock();
- VerifyWritable();
- currencyPositivePattern = value;
- }
- }
-
-
- public String PositiveInfinitySymbol
- {
- get
- {
- return positiveInfinitySymbol;
- }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(PositiveInfinitySymbol),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
- VerifyWritable();
- positiveInfinitySymbol = value;
- }
- }
-
-
- public String PositiveSign
- {
- get { return positiveSign; }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(PositiveSign),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
- VerifyWritable();
- positiveSign = value;
- }
- }
-
-
- public int PercentDecimalDigits
- {
- get { return percentDecimalDigits; }
- set
- {
- if (value < 0 || value > 99)
- {
- throw new ArgumentOutOfRangeException(
- nameof(PercentDecimalDigits),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 99));
- }
- Contract.EndContractBlock();
- VerifyWritable();
- percentDecimalDigits = value;
- }
- }
-
-
- public String PercentDecimalSeparator
- {
- get { return percentDecimalSeparator; }
- set
- {
- VerifyWritable();
- VerifyDecimalSeparator(value, nameof(PercentDecimalSeparator));
- percentDecimalSeparator = value;
- }
- }
-
-
- public String PercentGroupSeparator
- {
- get { return percentGroupSeparator; }
- set
- {
- VerifyWritable();
- VerifyGroupSeparator(value, nameof(PercentGroupSeparator));
- percentGroupSeparator = value;
- }
- }
-
-
- public String PercentSymbol
- {
- get
- {
- return percentSymbol;
- }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(PercentSymbol),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
- VerifyWritable();
- percentSymbol = value;
- }
- }
-
-
- public String PerMilleSymbol
- {
- get { return perMilleSymbol; }
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(PerMilleSymbol),
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
- VerifyWritable();
- perMilleSymbol = value;
- }
- }
-
- public string [] NativeDigits
- {
- get { return (String[]) nativeDigits.Clone(); }
- set
- {
- VerifyWritable();
- VerifyNativeDigits(value, nameof(NativeDigits));
- nativeDigits = value;
- }
- }
-
- public DigitShapes DigitSubstitution
- {
- get { return (DigitShapes) digitSubstitution; }
- set
- {
- VerifyWritable();
- VerifyDigitSubstitution(value, nameof(DigitSubstitution));
- digitSubstitution = (int) value;
- }
- }
-
- public Object GetFormat(Type formatType)
- {
- return formatType == typeof(NumberFormatInfo) ? this : null;
- }
-
- public static NumberFormatInfo ReadOnly(NumberFormatInfo nfi)
- {
- if (nfi == null)
- {
- throw new ArgumentNullException(nameof(nfi));
- }
- Contract.EndContractBlock();
- if (nfi.IsReadOnly)
- {
- return (nfi);
- }
- NumberFormatInfo info = (NumberFormatInfo)(nfi.MemberwiseClone());
- info.isReadOnly = true;
- return info;
- }
-
- // private const NumberStyles InvalidNumberStyles = unchecked((NumberStyles) 0xFFFFFC00);
- private const NumberStyles InvalidNumberStyles = ~(NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite
- | NumberStyles.AllowLeadingSign | NumberStyles.AllowTrailingSign
- | NumberStyles.AllowParentheses | NumberStyles.AllowDecimalPoint
- | NumberStyles.AllowThousands | NumberStyles.AllowExponent
- | NumberStyles.AllowCurrencySymbol | NumberStyles.AllowHexSpecifier);
-
- internal static void ValidateParseStyleInteger(NumberStyles style)
- {
- // Check for undefined flags
- if ((style & InvalidNumberStyles) != 0)
- {
- throw new ArgumentException(SR.Argument_InvalidNumberStyles, nameof(style));
- }
- Contract.EndContractBlock();
- if ((style & NumberStyles.AllowHexSpecifier) != 0)
- { // Check for hex number
- if ((style & ~NumberStyles.HexNumber) != 0)
- {
- throw new ArgumentException(SR.Arg_InvalidHexStyle);
- }
- }
- }
-
- internal static void ValidateParseStyleFloatingPoint(NumberStyles style)
- {
- // Check for undefined flags
- if ((style & InvalidNumberStyles) != 0)
- {
- throw new ArgumentException(SR.Argument_InvalidNumberStyles, nameof(style));
- }
- Contract.EndContractBlock();
- if ((style & NumberStyles.AllowHexSpecifier) != 0)
- { // Check for hex number
- throw new ArgumentException(SR.Arg_HexStyleNotSupported);
- }
- }
- } // NumberFormatInfo
-}
-
-
-
-
-
-
-
-
-
diff --git a/src/mscorlib/corefx/System/Globalization/PersianCalendar.cs b/src/mscorlib/corefx/System/Globalization/PersianCalendar.cs
deleted file mode 100644
index b8b3da6911..0000000000
--- a/src/mscorlib/corefx/System/Globalization/PersianCalendar.cs
+++ /dev/null
@@ -1,611 +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.Diagnostics;
-using System.Diagnostics.Contracts;
-
-namespace System.Globalization
-{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about PersianCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
- // Modern Persian calendar is a solar observation based calendar. Each new year begins on the day when the vernal equinox occurs before noon.
- // The epoch is the date of the vernal equinox prior to the epoch of the Islamic calendar (March 19, 622 Julian or March 22, 622 Gregorian)
-
- // There is no Persian year 0. Ordinary years have 365 days. Leap years have 366 days with the last month (Esfand) gaining the extra day.
- /*
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 0622/03/22 9999/12/31
- ** Persian 0001/01/01 9378/10/13
- */
-
- [Serializable]
- public class PersianCalendar : Calendar
- {
- public static readonly int PersianEra = 1;
-
- internal static long PersianEpoch = new DateTime(622, 3, 22).Ticks / GregorianCalendar.TicksPerDay;
- private const int ApproximateHalfYear = 180;
-
- internal const int DatePartYear = 0;
- internal const int DatePartDayOfYear = 1;
- internal const int DatePartMonth = 2;
- internal const int DatePartDay = 3;
- internal const int MonthsPerYear = 12;
-
- internal static int[] DaysToMonth = { 0, 31, 62, 93, 124, 155, 186, 216, 246, 276, 306, 336, 366 };
-
- internal const int MaxCalendarYear = 9378;
- internal const int MaxCalendarMonth = 10;
- internal const int MaxCalendarDay = 13;
-
- // Persian calendar (year: 1, month: 1, day:1 ) = Gregorian (year: 622, month: 3, day: 22)
- // This is the minimal Gregorian date that we support in the PersianCalendar.
- internal static DateTime minDate = new DateTime(622, 3, 22);
- internal static DateTime maxDate = DateTime.MaxValue;
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (minDate);
- }
- }
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (maxDate);
- }
- }
-
- public override CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.SolarCalendar;
- }
- }
-
- // Construct an instance of Persian calendar.
-
- public PersianCalendar()
- {
- }
-
-
- internal override CalendarId BaseCalendarID
- {
- get
- {
- return CalendarId.GREGORIAN;
- }
- }
-
- internal override CalendarId ID
- {
- get
- {
- return CalendarId.PERSIAN;
- }
- }
-
-
- /*=================================GetAbsoluteDatePersian==========================
- **Action: Gets the Absolute date for the given Persian date. The absolute date means
- ** the number of days from January 1st, 1 A.D.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
-
- private long GetAbsoluteDatePersian(int year, int month, int day)
- {
- if (year >= 1 && year <= MaxCalendarYear && month >= 1 && month <= 12)
- {
- int ordinalDay = DaysInPreviousMonths(month) + day - 1; // day is one based, make 0 based since this will be the number of days we add to beginning of year below
- int approximateDaysFromEpochForYearStart = (int)(CalendricalCalculationsHelper.MeanTropicalYearInDays * (year - 1));
- long yearStart = CalendricalCalculationsHelper.PersianNewYearOnOrBefore(PersianEpoch + approximateDaysFromEpochForYearStart + ApproximateHalfYear);
- yearStart += ordinalDay;
- return yearStart;
- }
- throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
- }
-
- internal static void CheckTicksRange(long ticks)
- {
- if (ticks < minDate.Ticks || ticks > maxDate.Ticks)
- {
- throw new ArgumentOutOfRangeException(
- "time",
- String.Format(
- CultureInfo.InvariantCulture,
- SR.ArgumentOutOfRange_CalendarRange,
- minDate,
- maxDate));
- }
- }
-
- internal static void CheckEraRange(int era)
- {
- if (era != CurrentEra && era != PersianEra)
- {
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
- }
-
- internal static void CheckYearRange(int year, int era)
- {
- CheckEraRange(era);
- if (year < 1 || year > MaxCalendarYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 1,
- MaxCalendarYear));
- }
- }
-
- internal static void CheckYearMonthRange(int year, int month, int era)
- {
- CheckYearRange(year, era);
- if (year == MaxCalendarYear)
- {
- if (month > MaxCalendarMonth)
- {
- throw new ArgumentOutOfRangeException(
- nameof(month),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 1,
- MaxCalendarMonth));
- }
- }
-
- if (month < 1 || month > 12)
- {
- throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
- }
- }
-
- private static int MonthFromOrdinalDay(int ordinalDay)
- {
- Debug.Assert(ordinalDay <= 366);
- int index = 0;
- while (ordinalDay > DaysToMonth[index])
- index++;
-
- return index;
- }
-
- private static int DaysInPreviousMonths(int month)
- {
- Debug.Assert(1 <= month && month <= 12);
- --month; // months are one based but for calculations use 0 based
- return DaysToMonth[month];
- }
-
- /*=================================GetDatePart==========================
- **Action: Returns a given date part of this <i>DateTime</i>. This method is used
- ** to compute the year, day-of-year, month, or day part.
- **Returns:
- **Arguments:
- **Exceptions: ArgumentException if part is incorrect.
- ============================================================================*/
-
- internal int GetDatePart(long ticks, int part)
- {
- long NumDays; // The calculation buffer in number of days.
-
- CheckTicksRange(ticks);
-
- //
- // Get the absolute date. The absolute date is the number of days from January 1st, 1 A.D.
- // 1/1/0001 is absolute date 1.
- //
- NumDays = ticks / GregorianCalendar.TicksPerDay + 1;
-
- //
- // Calculate the appromixate Persian Year.
- //
-
- long yearStart = CalendricalCalculationsHelper.PersianNewYearOnOrBefore(NumDays);
- int y = (int)(Math.Floor(((yearStart - PersianEpoch) / CalendricalCalculationsHelper.MeanTropicalYearInDays) + 0.5)) + 1;
- Debug.Assert(y >= 1);
-
- if (part == DatePartYear)
- {
- return y;
- }
-
- //
- // Calculate the Persian Month.
- //
-
- int ordinalDay = (int)(NumDays - CalendricalCalculationsHelper.GetNumberOfDays(this.ToDateTime(y, 1, 1, 0, 0, 0, 0, 1)));
-
- if (part == DatePartDayOfYear)
- {
- return ordinalDay;
- }
-
- int m = MonthFromOrdinalDay(ordinalDay);
- Debug.Assert(ordinalDay >= 1);
- Debug.Assert(m >= 1 && m <= 12);
- if (part == DatePartMonth)
- {
- return m;
- }
-
- int d = ordinalDay - DaysInPreviousMonths(m);
- Debug.Assert(1 <= d);
- Debug.Assert(d <= 31);
-
- //
- // Calculate the Persian Day.
- //
-
- if (part == DatePartDay)
- {
- return (d);
- }
-
- // Incorrect part value.
- throw new InvalidOperationException(SR.InvalidOperation_DateTimeParsing);
- }
-
- // Returns the DateTime resulting from adding the given number of
- // months to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year and month parts of the specified DateTime by
- // value months, and, if required, adjusting the day part of the
- // resulting date downwards to the last day of the resulting month in the
- // resulting year. The time-of-day part of the result is the same as the
- // time-of-day part of the specified DateTime.
- //
- // In more precise terms, considering the specified DateTime to be of the
- // form y / m / d + t, where y is the
- // year, m is the month, d is the day, and t is the
- // time-of-day, the result is y1 / m1 / d1 + t,
- // where y1 and m1 are computed by adding value months
- // to y and m, and d1 is the largest value less than
- // or equal to d that denotes a valid day in month m1 of year
- // y1.
- //
-
-
- public override DateTime AddMonths(DateTime time, int months)
- {
- if (months < -120000 || months > 120000)
- {
- throw new ArgumentOutOfRangeException(
- nameof(months),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- -120000,
- 120000));
- }
- Contract.EndContractBlock();
- // Get the date in Persian calendar.
- int y = GetDatePart(time.Ticks, DatePartYear);
- int m = GetDatePart(time.Ticks, DatePartMonth);
- int d = GetDatePart(time.Ticks, DatePartDay);
- int i = m - 1 + months;
- if (i >= 0)
- {
- m = i % 12 + 1;
- y = y + i / 12;
- }
- else
- {
- m = 12 + (i + 1) % 12;
- y = y + (i - 11) / 12;
- }
- int days = GetDaysInMonth(y, m);
- if (d > days)
- {
- d = days;
- }
- long ticks = GetAbsoluteDatePersian(y, m, d) * TicksPerDay + time.Ticks % TicksPerDay;
- Calendar.CheckAddResult(ticks, MinSupportedDateTime, MaxSupportedDateTime);
- return (new DateTime(ticks));
- }
-
- // Returns the DateTime resulting from adding the given number of
- // years to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year part of the specified DateTime by value
- // years. If the month and day of the specified DateTime is 2/29, and if the
- // resulting year is not a leap year, the month and day of the resulting
- // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
- // parts of the result are the same as those of the specified DateTime.
- //
-
-
- public override DateTime AddYears(DateTime time, int years)
- {
- return (AddMonths(time, years * 12));
- }
-
- // Returns the day-of-month part of the specified DateTime. The returned
- // value is an integer between 1 and 31.
- //
-
-
- public override int GetDayOfMonth(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartDay));
- }
-
- // Returns the day-of-week part of the specified DateTime. The returned value
- // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
- // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
- // Thursday, 5 indicates Friday, and 6 indicates Saturday.
- //
-
-
- public override DayOfWeek GetDayOfWeek(DateTime time)
- {
- return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
- }
-
- // Returns the day-of-year part of the specified DateTime. The returned value
- // is an integer between 1 and 366.
- //
-
-
- public override int GetDayOfYear(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartDayOfYear));
- }
-
- // Returns the number of days in the month given by the year and
- // month arguments.
- //
-
-
- public override int GetDaysInMonth(int year, int month, int era)
- {
- CheckYearMonthRange(year, month, era);
-
- if ((month == MaxCalendarMonth) && (year == MaxCalendarYear))
- {
- return MaxCalendarDay;
- }
-
- int daysInMonth = DaysToMonth[month] - DaysToMonth[month - 1];
- if ((month == MonthsPerYear) && !IsLeapYear(year))
- {
- Debug.Assert(daysInMonth == 30);
- --daysInMonth;
- }
- return daysInMonth;
- }
-
- // Returns the number of days in the year given by the year argument for the current era.
- //
-
- public override int GetDaysInYear(int year, int era)
- {
- CheckYearRange(year, era);
- if (year == MaxCalendarYear)
- {
- return DaysToMonth[MaxCalendarMonth - 1] + MaxCalendarDay;
- }
- // Common years have 365 days. Leap years have 366 days.
- return (IsLeapYear(year, CurrentEra) ? 366 : 365);
- }
-
- // Returns the era for the specified DateTime value.
-
-
- public override int GetEra(DateTime time)
- {
- CheckTicksRange(time.Ticks);
- return (PersianEra);
- }
-
-
-
- public override int[] Eras
- {
- get
- {
- return (new int[] { PersianEra });
- }
- }
-
- // Returns the month part of the specified DateTime. The returned value is an
- // integer between 1 and 12.
- //
-
-
- public override int GetMonth(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartMonth));
- }
-
- // Returns the number of months in the specified year and era.
-
-
- public override int GetMonthsInYear(int year, int era)
- {
- CheckYearRange(year, era);
- if (year == MaxCalendarYear)
- {
- return MaxCalendarMonth;
- }
- return (12);
- }
-
- // Returns the year part of the specified DateTime. The returned value is an
- // integer between 1 and MaxCalendarYear.
- //
-
-
- public override int GetYear(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartYear));
- }
-
- // Checks whether a given day in the specified era is a leap day. This method returns true if
- // the date is a leap day, or false if not.
- //
-
-
- public override bool IsLeapDay(int year, int month, int day, int era)
- {
- // The year/month/era value checking is done in GetDaysInMonth().
- int daysInMonth = GetDaysInMonth(year, month, era);
- if (day < 1 || day > daysInMonth)
- {
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Day,
- daysInMonth,
- month));
- }
- return (IsLeapYear(year, era) && month == 12 && day == 30);
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
-
- public override int GetLeapMonth(int year, int era)
- {
- CheckYearRange(year, era);
- return (0);
- }
-
- // Checks whether a given month in the specified era is a leap month. This method returns true if
- // month is a leap month, or false if not.
- //
-
-
- public override bool IsLeapMonth(int year, int month, int era)
- {
- CheckYearMonthRange(year, month, era);
- return (false);
- }
-
- // Checks whether a given year in the specified era is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
-
- public override bool IsLeapYear(int year, int era)
- {
- CheckYearRange(year, era);
-
- if (year == MaxCalendarYear)
- {
- return false;
- }
-
- return (GetAbsoluteDatePersian(year + 1, 1, 1) - GetAbsoluteDatePersian(year, 1, 1)) == 366;
- }
-
- // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
- //
-
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
- {
- // The year/month/era checking is done in GetDaysInMonth().
- int daysInMonth = GetDaysInMonth(year, month, era);
- if (day < 1 || day > daysInMonth)
- {
- // BCLDebug.Log("year = " + year + ", month = " + month + ", day = " + day);
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Day,
- daysInMonth,
- month));
- }
-
- long lDate = GetAbsoluteDatePersian(year, month, day);
-
- if (lDate >= 0)
- {
- return (new DateTime(lDate * GregorianCalendar.TicksPerDay + TimeToTicks(hour, minute, second, millisecond)));
- }
- else
- {
- throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
- }
- }
-
- private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 1410;
-
- public override int TwoDigitYearMax
- {
- get
- {
- if (twoDigitYearMax == -1)
- {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
- }
- return (twoDigitYearMax);
- }
-
- set
- {
- VerifyWritable();
- if (value < 99 || value > MaxCalendarYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(value),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 99,
- MaxCalendarYear));
- }
- twoDigitYearMax = value;
- }
- }
-
-
-
- public override int ToFourDigitYear(int year)
- {
- if (year < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(year),
- SR.ArgumentOutOfRange_NeedNonNegNum);
- }
- Contract.EndContractBlock();
-
- if (year < 100)
- {
- return (base.ToFourDigitYear(year));
- }
-
- if (year > MaxCalendarYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 1,
- MaxCalendarYear));
- }
- return (year);
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/RegionInfo.cs b/src/mscorlib/corefx/System/Globalization/RegionInfo.cs
deleted file mode 100644
index 15679d24dd..0000000000
--- a/src/mscorlib/corefx/System/Globalization/RegionInfo.cs
+++ /dev/null
@@ -1,421 +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.
-
-////////////////////////////////////////////////////////////////////////////
-//
-//
-// Purpose: This class represents settings specified by de jure or
-// de facto standards for a particular country/region. In
-// contrast to CultureInfo, the RegionInfo does not represent
-// preferences of the user and does not depend on the user's
-// language or culture.
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-using System.Runtime.Serialization;
-
-namespace System.Globalization
-{
- [Serializable]
- public class RegionInfo
- {
- //--------------------------------------------------------------------//
- // Internal Information //
- //--------------------------------------------------------------------//
-
- //
- // Variables.
- //
-
- //
- // Name of this region (ie: es-US): serialized, the field used for deserialization
- //
- internal String _name;
-
- //
- // The CultureData instance that we are going to read data from.
- //
- internal CultureData _cultureData;
-
- //
- // The RegionInfo for our current region
- //
- internal static volatile RegionInfo s_currentRegionInfo;
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // RegionInfo Constructors
- //
- // Note: We prefer that a region be created with a full culture name (ie: en-US)
- // because otherwise the native strings won't be right.
- //
- // In Silverlight we enforce that RegionInfos must be created with a full culture name
- //
- ////////////////////////////////////////////////////////////////////////
- public RegionInfo(String name)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
-
- if (name.Length == 0) //The InvariantCulture has no matching region
- {
- throw new ArgumentException(SR.Argument_NoRegionInvariantCulture, nameof(name));
- }
-
- Contract.EndContractBlock();
-
- //
- // For CoreCLR we only want the region names that are full culture names
- //
- _cultureData = CultureData.GetCultureDataForRegion(name, true);
- if (_cultureData == null)
- throw new ArgumentException(
- String.Format(
- CultureInfo.CurrentCulture,
- SR.Argument_InvalidCultureName, name), nameof(name));
-
-
- // Not supposed to be neutral
- if (_cultureData.IsNeutralCulture)
- throw new ArgumentException(SR.Format(SR.Argument_InvalidNeutralRegionName, name), nameof(name));
-
- SetName(name);
- }
-
- public RegionInfo(int culture)
- {
- if (culture == CultureInfo.LOCALE_INVARIANT) //The InvariantCulture has no matching region
- {
- throw new ArgumentException(SR.Argument_NoRegionInvariantCulture);
- }
-
- if (culture == CultureInfo.LOCALE_NEUTRAL)
- {
- // Not supposed to be neutral
- throw new ArgumentException(SR.Format(SR.Argument_CultureIsNeutral, culture), nameof(culture));
- }
-
- if (culture == CultureInfo.LOCALE_CUSTOM_DEFAULT)
- {
- // Not supposed to be neutral
- throw new ArgumentException(SR.Format(SR.Argument_CustomCultureCannotBePassedByNumber, culture), nameof(culture));
- }
-
- _cultureData = CultureData.GetCultureData(culture, true);
- _name = _cultureData.SREGIONNAME;
-
- if (_cultureData.IsNeutralCulture)
- {
- // Not supposed to be neutral
- throw new ArgumentException(SR.Format(SR.Argument_CultureIsNeutral, culture), nameof(culture));
- }
- }
-
- internal RegionInfo(CultureData cultureData)
- {
- _cultureData = cultureData;
- _name = _cultureData.SREGIONNAME;
- }
-
- private void SetName(string name)
- {
- // Use the name of the region we found
- _name = _cultureData.SREGIONNAME;
- }
-
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx) { }
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext ctx)
- {
- _cultureData = CultureData.GetCultureData(_name, true);
-
- if (_cultureData == null)
- {
- throw new ArgumentException(
- String.Format(CultureInfo.CurrentCulture, SR.Argument_InvalidCultureName, _name),
- "_name");
- }
-
- _name = _cultureData.SREGIONNAME;
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetCurrentRegion
- //
- // This instance provides methods based on the current user settings.
- // These settings are volatile and may change over the lifetime of the
- // thread.
- //
- ////////////////////////////////////////////////////////////////////////
- public static RegionInfo CurrentRegion
- {
- get
- {
- RegionInfo temp = s_currentRegionInfo;
- if (temp == null)
- {
- temp = new RegionInfo(CultureInfo.CurrentCulture.m_cultureData);
-
- // Need full name for custom cultures
- temp._name = temp._cultureData.SREGIONNAME;
- s_currentRegionInfo = temp;
- }
- return temp;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetName
- //
- // Returns the name of the region (ie: en-US)
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String Name
- {
- get
- {
- Debug.Assert(_name != null, "Expected RegionInfo._name to be populated already");
- return (_name);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetEnglishName
- //
- // Returns the name of the region in English. (ie: United States)
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String EnglishName
- {
- get
- {
- return (_cultureData.SENGCOUNTRY);
- }
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetDisplayName
- //
- // Returns the display name (localized) of the region. (ie: United States
- // if the current UI language is en-US)
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String DisplayName
- {
- get
- {
- return (_cultureData.SLOCALIZEDCOUNTRY);
- }
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetNativeName
- //
- // Returns the native name of the region. (ie: Deutschland)
- // WARNING: You need a full locale name for this to make sense.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String NativeName
- {
- get
- {
- return (_cultureData.SNATIVECOUNTRY);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // TwoLetterISORegionName
- //
- // Returns the two letter ISO region name (ie: US)
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String TwoLetterISORegionName
- {
- get
- {
- return (_cultureData.SISO3166CTRYNAME);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ThreeLetterISORegionName
- //
- // Returns the three letter ISO region name (ie: USA)
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String ThreeLetterISORegionName
- {
- get
- {
- return (_cultureData.SISO3166CTRYNAME2);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ThreeLetterWindowsRegionName
- //
- // Returns the three letter windows region name (ie: USA)
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String ThreeLetterWindowsRegionName
- {
- get
- {
- // ThreeLetterWindowsRegionName is really same as ThreeLetterISORegionName
- return ThreeLetterISORegionName;
- }
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // IsMetric
- //
- // Returns true if this region uses the metric measurement system
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual bool IsMetric
- {
- get
- {
- int value = _cultureData.IMEASURE;
- return (value == 0);
- }
- }
-
- public virtual int GeoId
- {
- get
- {
- return (_cultureData.IGEOID);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // CurrencyEnglishName
- //
- // English name for this region's currency, ie: Swiss Franc
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string CurrencyEnglishName
- {
- get
- {
- return (_cultureData.SENGLISHCURRENCY);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // CurrencyNativeName
- //
- // Native name for this region's currency, ie: Schweizer Franken
- // WARNING: You need a full locale name for this to make sense.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string CurrencyNativeName
- {
- get
- {
- return (_cultureData.SNATIVECURRENCY);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // CurrencySymbol
- //
- // Currency Symbol for this locale, ie: Fr. or $
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String CurrencySymbol
- {
- get
- {
- return (_cultureData.SCURRENCY);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ISOCurrencySymbol
- //
- // ISO Currency Symbol for this locale, ie: CHF
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String ISOCurrencySymbol
- {
- get
- {
- return (_cultureData.SINTLSYMBOL);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Equals
- //
- // Implements Object.Equals(). Returns a boolean indicating whether
- // or not object refers to the same RegionInfo as the current instance.
- //
- // RegionInfos are considered equal if and only if they have the same name
- // (ie: en-US)
- //
- ////////////////////////////////////////////////////////////////////////
- public override bool Equals(Object value)
- {
- RegionInfo that = value as RegionInfo;
- if (that != null)
- {
- return this.Name.Equals(that.Name);
- }
-
- return (false);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetHashCode
- //
- // Implements Object.GetHashCode(). Returns the hash code for the
- // CultureInfo. The hash code is guaranteed to be the same for RegionInfo
- // A and B where A.Equals(B) is true.
- //
- ////////////////////////////////////////////////////////////////////////
- public override int GetHashCode()
- {
- return (this.Name.GetHashCode());
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ToString
- //
- // Implements Object.ToString(). Returns the name of the Region, ie: es-US
- //
- ////////////////////////////////////////////////////////////////////////
- public override String ToString()
- {
- return (Name);
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/SortKey.cs b/src/mscorlib/corefx/System/Globalization/SortKey.cs
deleted file mode 100644
index 9e22a6f332..0000000000
--- a/src/mscorlib/corefx/System/Globalization/SortKey.cs
+++ /dev/null
@@ -1,208 +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.
-
-////////////////////////////////////////////////////////////////////////////
-//
-//
-// Purpose: This class implements a set of methods for retrieving
-// sort key information.
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
-namespace System.Globalization {
-
- using System;
- using System.Runtime.CompilerServices;
- using System.Runtime.Serialization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- [Serializable]
- public partial class SortKey
- {
- //--------------------------------------------------------------------//
- // Internal Information //
- //--------------------------------------------------------------------//
-
- //
- // Variables.
- //
-
- [OptionalField(VersionAdded = 3)]
- internal string _localeName; // locale identifier
-
- [OptionalField(VersionAdded = 1)] // LCID field so serialization is Whidbey compatible though we don't officially support it
- internal int _win32LCID;
- // Whidbey serialization
-
- internal CompareOptions _options; // options
- internal string _string; // original string
- internal byte[] _keyData; // sortkey data
-
- //
- // The following constructor is designed to be called from CompareInfo to get the
- // the sort key of specific string for synthetic culture
- //
- internal SortKey(String localeName, String str, CompareOptions options, byte[] keyData)
- {
- _keyData = keyData;
- _localeName = localeName;
- _options = options;
- _string = str;
- }
-
- [OnSerializing]
- private void OnSerializing(StreamingContext context)
- {
- //set LCID to proper value for Whidbey serialization (no other use)
- if (_win32LCID == 0)
- {
- _win32LCID = CultureInfo.GetCultureInfo(_localeName).LCID;
- }
- }
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext context)
- {
- //set locale name to proper value after Whidbey deserialization
- if (String.IsNullOrEmpty(_localeName) && _win32LCID != 0)
- {
- _localeName = CultureInfo.GetCultureInfo(_win32LCID).Name;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetOriginalString
- //
- // Returns the original string used to create the current instance
- // of SortKey.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String OriginalString
- {
- get
- {
- return (_string);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetKeyData
- //
- // Returns a byte array representing the current instance of the
- // sort key.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual byte[] KeyData
- {
- get
- {
- return (byte[])(_keyData.Clone());
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Compare
- //
- // Compares the two sort keys. Returns 0 if the two sort keys are
- // equal, a number less than 0 if sortkey1 is less than sortkey2,
- // and a number greater than 0 if sortkey1 is greater than sortkey2.
- //
- ////////////////////////////////////////////////////////////////////////
- public static int Compare(SortKey sortkey1, SortKey sortkey2)
- {
- if (sortkey1==null || sortkey2==null)
- {
- throw new ArgumentNullException((sortkey1 == null ? nameof(sortkey1) : nameof(sortkey2)));
- }
- Contract.EndContractBlock();
-
- byte[] key1Data = sortkey1._keyData;
- byte[] key2Data = sortkey2._keyData;
-
- Debug.Assert(key1Data != null, "key1Data != null");
- Debug.Assert(key2Data != null, "key2Data != null");
-
- if (key1Data.Length == 0)
- {
- if (key2Data.Length == 0)
- {
- return (0);
- }
- return (-1);
- }
- if (key2Data.Length == 0)
- {
- return (1);
- }
-
- int compLen = (key1Data.Length<key2Data.Length)?key1Data.Length:key2Data.Length;
-
- for (int i=0; i<compLen; i++)
- {
- if (key1Data[i]>key2Data[i])
- {
- return (1);
- }
- if (key1Data[i]<key2Data[i])
- {
- return (-1);
- }
- }
-
- return 0;
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Equals
- //
- // Implements Object.Equals(). Returns a boolean indicating whether
- // or not object refers to the same SortKey as the current instance.
- //
- ////////////////////////////////////////////////////////////////////////
- public override bool Equals(Object value)
- {
- SortKey that = value as SortKey;
-
- if (that != null)
- {
- return Compare(this, that) == 0;
- }
-
- return (false);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetHashCode
- //
- // Implements Object.GetHashCode(). Returns the hash code for the
- // SortKey. The hash code is guaranteed to be the same for
- // SortKey A and B where A.Equals(B) is true.
- //
- ////////////////////////////////////////////////////////////////////////
- public override int GetHashCode()
- {
- return (CompareInfo.GetCompareInfo(_localeName).GetHashCodeOfString(_string, _options));
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ToString
- //
- // Implements Object.ToString(). Returns a string describing the
- // SortKey.
- //
- ////////////////////////////////////////////////////////////////////////
- public override String ToString()
- {
- return ("SortKey - " + _localeName + ", " + _options + ", " + _string);
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/SortVersion.cs b/src/mscorlib/corefx/System/Globalization/SortVersion.cs
deleted file mode 100644
index 983179c149..0000000000
--- a/src/mscorlib/corefx/System/Globalization/SortVersion.cs
+++ /dev/null
@@ -1,101 +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.Diagnostics.Contracts;
-
-namespace System.Globalization
-{
- [Serializable]
- public sealed class SortVersion : IEquatable<SortVersion>
- {
- private int _nlsVersion;
- private Guid _sortId;
-
- public int FullVersion
- {
- get
- {
- return _nlsVersion;
- }
- }
-
- public Guid SortId
- {
- get
- {
- return _sortId;
- }
- }
-
- public SortVersion(int fullVersion, Guid sortId)
- {
- _sortId = sortId;
- _nlsVersion = fullVersion;
- }
-
- internal SortVersion(int nlsVersion, int effectiveId, Guid customVersion)
- {
- _nlsVersion = nlsVersion;
-
- if (customVersion == Guid.Empty)
- {
- byte b1 = (byte)(effectiveId >> 24);
- byte b2 = (byte)((effectiveId & 0x00FF0000) >> 16);
- byte b3 = (byte)((effectiveId & 0x0000FF00) >> 8);
- byte b4 = (byte)(effectiveId & 0xFF);
- customVersion = new Guid(0, 0, 0, 0, 0, 0, 0, b1, b2, b3, b4);
- }
-
- _sortId = customVersion;
- }
-
- public override bool Equals(object obj)
- {
- SortVersion n = obj as SortVersion;
- if (n != null)
- {
- return this.Equals(n);
- }
-
- return false;
- }
-
- public bool Equals(SortVersion other)
- {
- if (other == null)
- {
- return false;
- }
-
- return _nlsVersion == other._nlsVersion && _sortId == other._sortId;
- }
-
- public override int GetHashCode()
- {
- return _nlsVersion * 7 | _sortId.GetHashCode();
- }
-
- public static bool operator ==(SortVersion left, SortVersion right)
- {
- if (((object)left) != null)
- {
- return left.Equals(right);
- }
-
- if (((object)right) != null)
- {
- return right.Equals(left);
- }
-
- // Both null.
- return true;
- }
-
- public static bool operator !=(SortVersion left, SortVersion right)
- {
- return !(left == right);
- }
- }
-} \ No newline at end of file
diff --git a/src/mscorlib/corefx/System/Globalization/StringInfo.cs b/src/mscorlib/corefx/System/Globalization/StringInfo.cs
deleted file mode 100644
index f1dd30561b..0000000000
--- a/src/mscorlib/corefx/System/Globalization/StringInfo.cs
+++ /dev/null
@@ -1,374 +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.
-
-////////////////////////////////////////////////////////////////////////////
-//
-//
-// Purpose: This class defines behaviors specific to a writing system.
-// A writing system is the collection of scripts and
-// orthographic rules required to represent a language as text.
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
-using System;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-using System.Runtime.Serialization;
-
-namespace System.Globalization
-{
- [Serializable]
- public class StringInfo
- {
- [OptionalField(VersionAdded = 2)]
- private string _str;
-
- [NonSerialized]
- private int[] _indexes;
-
- // Legacy constructor
- public StringInfo() : this("") { }
-
- // Primary, useful constructor
- public StringInfo(string value)
- {
- this.String = value;
- }
-
- [OnDeserializing]
- private void OnDeserializing(StreamingContext ctx)
- {
- _str = String.Empty;
- }
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext ctx)
- {
- if (_str.Length == 0)
- {
- _indexes = null;
- }
- }
-
- public override bool Equals(Object value)
- {
- StringInfo that = value as StringInfo;
- if (that != null)
- {
- return (_str.Equals(that._str));
- }
- return (false);
- }
-
- public override int GetHashCode()
- {
- return _str.GetHashCode();
- }
-
-
- // Our zero-based array of index values into the string. Initialize if
- // our private array is not yet, in fact, initialized.
- private int[] Indexes
- {
- get
- {
- if ((null == _indexes) && (0 < this.String.Length))
- {
- _indexes = StringInfo.ParseCombiningCharacters(this.String);
- }
-
- return (_indexes);
- }
- }
-
- public string String
- {
- get
- {
- return (_str);
- }
- set
- {
- if (null == value)
- {
- throw new ArgumentNullException("String",
- SR.ArgumentNull_String);
- }
- Contract.EndContractBlock();
-
- _str = value;
- _indexes = null;
- }
- }
-
- public int LengthInTextElements
- {
- get
- {
- if (null == this.Indexes)
- {
- // Indexes not initialized, so assume length zero
- return (0);
- }
-
- return (this.Indexes.Length);
- }
- }
-
- public string SubstringByTextElements(int startingTextElement)
- {
- // If the string is empty, no sense going further.
- if (null == this.Indexes)
- {
- // Just decide which error to give depending on the param they gave us....
- if (startingTextElement < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(startingTextElement), SR.ArgumentOutOfRange_NeedPosNum);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(startingTextElement), SR.Arg_ArgumentOutOfRangeException);
- }
- }
- return (SubstringByTextElements(startingTextElement, Indexes.Length - startingTextElement));
- }
-
- public string SubstringByTextElements(int startingTextElement, int lengthInTextElements)
- {
- if (startingTextElement < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(startingTextElement), SR.ArgumentOutOfRange_NeedPosNum);
- }
-
- if (this.String.Length == 0 || startingTextElement >= Indexes.Length)
- {
- throw new ArgumentOutOfRangeException(nameof(startingTextElement), SR.Arg_ArgumentOutOfRangeException);
- }
-
- if (lengthInTextElements < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(lengthInTextElements), SR.ArgumentOutOfRange_NeedPosNum);
- }
-
- if (startingTextElement > Indexes.Length - lengthInTextElements)
- {
- throw new ArgumentOutOfRangeException(nameof(lengthInTextElements), SR.Arg_ArgumentOutOfRangeException);
- }
-
- int start = Indexes[startingTextElement];
-
- if (startingTextElement + lengthInTextElements == Indexes.Length)
- {
- // We are at the last text element in the string and because of that
- // must handle the call differently.
- return (this.String.Substring(start));
- }
- else
- {
- return (this.String.Substring(start, (Indexes[lengthInTextElements + startingTextElement] - start)));
- }
- }
-
- public static string GetNextTextElement(string str)
- {
- return (GetNextTextElement(str, 0));
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Get the code point count of the current text element.
- //
- // A combining class is defined as:
- // A character/surrogate that has the following Unicode category:
- // * NonSpacingMark (e.g. U+0300 COMBINING GRAVE ACCENT)
- // * SpacingCombiningMark (e.g. U+ 0903 DEVANGARI SIGN VISARGA)
- // * EnclosingMark (e.g. U+20DD COMBINING ENCLOSING CIRCLE)
- //
- // In the context of GetNextTextElement() and ParseCombiningCharacters(), a text element is defined as:
- //
- // 1. If a character/surrogate is in the following category, it is a text element.
- // It can NOT further combine with characters in the combinging class to form a text element.
- // * one of the Unicode category in the combinging class
- // * UnicodeCategory.Format
- // * UnicodeCateogry.Control
- // * UnicodeCategory.OtherNotAssigned
- // 2. Otherwise, the character/surrogate can be combined with characters in the combinging class to form a text element.
- //
- // Return:
- // The length of the current text element
- //
- // Parameters:
- // String str
- // index The starting index
- // len The total length of str (to define the upper boundary)
- // ucCurrent The Unicode category pointed by Index. It will be updated to the uc of next character if this is not the last text element.
- // currentCharCount The char count of an abstract char pointed by Index. It will be updated to the char count of next abstract character if this is not the last text element.
- //
- ////////////////////////////////////////////////////////////////////////
-
- internal static int GetCurrentTextElementLen(string str, int index, int len, ref UnicodeCategory ucCurrent, ref int currentCharCount)
- {
- Debug.Assert(index >= 0 && len >= 0, "StringInfo.GetCurrentTextElementLen() : index = " + index + ", len = " + len);
- Debug.Assert(index < len, "StringInfo.GetCurrentTextElementLen() : index = " + index + ", len = " + len);
- if (index + currentCharCount == len)
- {
- // This is the last character/surrogate in the string.
- return (currentCharCount);
- }
-
- // Call an internal GetUnicodeCategory, which will tell us both the unicode category, and also tell us if it is a surrogate pair or not.
- int nextCharCount;
- UnicodeCategory ucNext = CharUnicodeInfo.InternalGetUnicodeCategory(str, index + currentCharCount, out nextCharCount);
- if (CharUnicodeInfo.IsCombiningCategory(ucNext))
- {
- // The next element is a combining class.
- // Check if the current text element to see if it is a valid base category (i.e. it should not be a combining category,
- // not a format character, and not a control character).
-
- if (CharUnicodeInfo.IsCombiningCategory(ucCurrent)
- || (ucCurrent == UnicodeCategory.Format)
- || (ucCurrent == UnicodeCategory.Control)
- || (ucCurrent == UnicodeCategory.OtherNotAssigned)
- || (ucCurrent == UnicodeCategory.Surrogate)) // An unpair high surrogate or low surrogate
- {
- // Will fall thru and return the currentCharCount
- }
- else
- {
- int startIndex = index; // Remember the current index.
-
- // We have a valid base characters, and we have a character (or surrogate) that is combining.
- // Check if there are more combining characters to follow.
- // Check if the next character is a nonspacing character.
- index += currentCharCount + nextCharCount;
-
- while (index < len)
- {
- ucNext = CharUnicodeInfo.InternalGetUnicodeCategory(str, index, out nextCharCount);
- if (!CharUnicodeInfo.IsCombiningCategory(ucNext))
- {
- ucCurrent = ucNext;
- currentCharCount = nextCharCount;
- break;
- }
- index += nextCharCount;
- }
- return (index - startIndex);
- }
- }
- // The return value will be the currentCharCount.
- int ret = currentCharCount;
- ucCurrent = ucNext;
- // Update currentCharCount.
- currentCharCount = nextCharCount;
- return (ret);
- }
-
- // Returns the str containing the next text element in str starting at
- // index index. If index is not supplied, then it will start at the beginning
- // of str. It recognizes a base character plus one or more combining
- // characters or a properly formed surrogate pair as a text element. See also
- // the ParseCombiningCharacters() and the ParseSurrogates() methods.
- public static string GetNextTextElement(string str, int index)
- {
- //
- // Validate parameters.
- //
- if (str == null)
- {
- throw new ArgumentNullException(nameof(str));
- }
- Contract.EndContractBlock();
-
- int len = str.Length;
- if (index < 0 || index >= len)
- {
- if (index == len)
- {
- return (String.Empty);
- }
- throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
- }
-
- int charLen;
- UnicodeCategory uc = CharUnicodeInfo.InternalGetUnicodeCategory(str, index, out charLen);
- return (str.Substring(index, GetCurrentTextElementLen(str, index, len, ref uc, ref charLen)));
- }
-
- public static TextElementEnumerator GetTextElementEnumerator(string str)
- {
- return (GetTextElementEnumerator(str, 0));
- }
-
- public static TextElementEnumerator GetTextElementEnumerator(string str, int index)
- {
- //
- // Validate parameters.
- //
- if (str == null)
- {
- throw new ArgumentNullException(nameof(str));
- }
- Contract.EndContractBlock();
-
- int len = str.Length;
- if (index < 0 || (index > len))
- {
- throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
- }
-
- return (new TextElementEnumerator(str, index, len));
- }
-
- /*
- * Returns the indices of each base character or properly formed surrogate pair
- * within the str. It recognizes a base character plus one or more combining
- * characters or a properly formed surrogate pair as a text element and returns
- * the index of the base character or high surrogate. Each index is the
- * beginning of a text element within a str. The length of each element is
- * easily computed as the difference between successive indices. The length of
- * the array will always be less than or equal to the length of the str. For
- * example, given the str \u4f00\u302a\ud800\udc00\u4f01, this method would
- * return the indices: 0, 2, 4.
- */
-
- public static int[] ParseCombiningCharacters(string str)
- {
- if (str == null)
- {
- throw new ArgumentNullException(nameof(str));
- }
- Contract.EndContractBlock();
-
- int len = str.Length;
- int[] result = new int[len];
- if (len == 0)
- {
- return (result);
- }
-
- int resultCount = 0;
-
- int i = 0;
- int currentCharLen;
- UnicodeCategory currentCategory = CharUnicodeInfo.InternalGetUnicodeCategory(str, 0, out currentCharLen);
-
- while (i < len)
- {
- result[resultCount++] = i;
- i += GetCurrentTextElementLen(str, i, len, ref currentCategory, ref currentCharLen);
- }
-
- if (resultCount < len)
- {
- int[] returnArray = new int[resultCount];
- Array.Copy(result, returnArray, resultCount);
- return (returnArray);
- }
- return (result);
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/TaiwanLunisolarCalendar.cs b/src/mscorlib/corefx/System/Globalization/TaiwanLunisolarCalendar.cs
deleted file mode 100644
index 1f75ac9a04..0000000000
--- a/src/mscorlib/corefx/System/Globalization/TaiwanLunisolarCalendar.cs
+++ /dev/null
@@ -1,330 +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.Diagnostics.Contracts;
-
-namespace System.Globalization
-{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about TaiwanLunisolarCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
- /*
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 1912/02/18 2051/02/10
- ** TaiwanLunisolar 1912/01/01 2050/13/29
- */
-
- [Serializable]
- public class TaiwanLunisolarCalendar : EastAsianLunisolarCalendar
- {
- // Since
- // Gregorian Year = Era Year + yearOffset
- // When Gregorian Year 1912 is year 1, so that
- // 1912 = 1 + yearOffset
- // So yearOffset = 1911
- //m_EraInfo[0] = new EraInfo(1, new DateTime(1912, 1, 1).Ticks, 1911, 1, GregorianCalendar.MaxYear - 1911);
-
- // Initialize our era info.
- internal static EraInfo[] taiwanLunisolarEraInfo = new EraInfo[] {
- new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911) // era #, start year/month/day, yearOffset, minEraYear
- };
-
- internal GregorianCalendarHelper helper;
-
- internal const int MIN_LUNISOLAR_YEAR = 1912;
- internal const int MAX_LUNISOLAR_YEAR = 2050;
-
- internal const int MIN_GREGORIAN_YEAR = 1912;
- internal const int MIN_GREGORIAN_MONTH = 2;
- internal const int MIN_GREGORIAN_DAY = 18;
-
- internal const int MAX_GREGORIAN_YEAR = 2051;
- internal const int MAX_GREGORIAN_MONTH = 2;
- internal const int MAX_GREGORIAN_DAY = 10;
-
- internal static DateTime minDate = new DateTime(MIN_GREGORIAN_YEAR, MIN_GREGORIAN_MONTH, MIN_GREGORIAN_DAY);
- internal static DateTime maxDate = new DateTime((new DateTime(MAX_GREGORIAN_YEAR, MAX_GREGORIAN_MONTH, MAX_GREGORIAN_DAY, 23, 59, 59, 999)).Ticks + 9999);
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (minDate);
- }
- }
-
-
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (maxDate);
- }
- }
-
- protected override int DaysInYearBeforeMinSupportedYear
- {
- get
- {
- // 1911 from ChineseLunisolarCalendar
- return 384;
- }
- }
-
- private static readonly int[,] s_yinfo =
- {
- /*Y LM Lmon Lday DaysPerMonth D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 #Days
- 1912 */
- { 0 , 2 , 18 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1913 */{ 0 , 2 , 6 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1914 */{ 5 , 1 , 26 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
-1915 */{ 0 , 2 , 14 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1916 */{ 0 , 2 , 3 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 0 355
-1917 */{ 2 , 1 , 23 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1918 */{ 0 , 2 , 11 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1919 */{ 7 , 2 , 1 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1920 */{ 0 , 2 , 20 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1921 */{ 0 , 2 , 8 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1922 */{ 5 , 1 , 28 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1923 */{ 0 , 2 , 16 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1924 */{ 0 , 2 , 5 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1925 */{ 4 , 1 , 24 , 44456 },/* 30 29 30 29 30 30 29 30 30 29 30 29 30 385
-1926 */{ 0 , 2 , 13 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1927 */{ 0 , 2 , 2 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 0 355
-1928 */{ 2 , 1 , 23 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
-1929 */{ 0 , 2 , 10 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1930 */{ 6 , 1 , 30 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
-1931 */{ 0 , 2 , 17 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1932 */{ 0 , 2 , 6 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-1933 */{ 5 , 1 , 26 , 27976 },/* 29 30 30 29 30 30 29 30 29 30 29 29 30 384
-1934 */{ 0 , 2 , 14 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
-1935 */{ 0 , 2 , 4 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1936 */{ 3 , 1 , 24 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
-1937 */{ 0 , 2 , 11 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1938 */{ 7 , 1 , 31 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-1939 */{ 0 , 2 , 19 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
-1940 */{ 0 , 2 , 8 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1941 */{ 6 , 1 , 27 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1942 */{ 0 , 2 , 15 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1943 */{ 0 , 2 , 5 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1944 */{ 4 , 1 , 25 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
-1945 */{ 0 , 2 , 13 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1946 */{ 0 , 2 , 2 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-1947 */{ 2 , 1 , 22 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-1948 */{ 0 , 2 , 10 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1949 */{ 7 , 1 , 29 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-1950 */{ 0 , 2 , 17 , 27808 },/* 29 30 30 29 30 30 29 29 30 29 30 29 0 354
-1951 */{ 0 , 2 , 6 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1952 */{ 5 , 1 , 27 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-1953 */{ 0 , 2 , 14 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
-1954 */{ 0 , 2 , 3 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-1955 */{ 3 , 1 , 24 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1956 */{ 0 , 2 , 12 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1957 */{ 8 , 1 , 31 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 29 383
-1958 */{ 0 , 2 , 18 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
-1959 */{ 0 , 2 , 8 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1960 */{ 6 , 1 , 28 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1961 */{ 0 , 2 , 15 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1962 */{ 0 , 2 , 5 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1963 */{ 4 , 1 , 25 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1964 */{ 0 , 2 , 13 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1965 */{ 0 , 2 , 2 , 21088 },/* 29 30 29 30 29 29 30 29 29 30 30 29 0 353
-1966 */{ 3 , 1 , 21 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-1967 */{ 0 , 2 , 9 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1968 */{ 7 , 1 , 30 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1969 */{ 0 , 2 , 17 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1970 */{ 0 , 2 , 6 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-1971 */{ 5 , 1 , 27 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1972 */{ 0 , 2 , 15 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
-1973 */{ 0 , 2 , 3 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1974 */{ 4 , 1 , 23 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1975 */{ 0 , 2 , 11 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1976 */{ 8 , 1 , 31 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
-1977 */{ 0 , 2 , 18 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1978 */{ 0 , 2 , 7 , 46752 },/* 30 29 30 30 29 30 30 29 30 29 30 29 0 355
-1979 */{ 6 , 1 , 28 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1980 */{ 0 , 2 , 16 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1981 */{ 0 , 2 , 5 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1982 */{ 4 , 1 , 25 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-1983 */{ 0 , 2 , 13 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1984 */{ 10 , 2 , 2 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1985 */{ 0 , 2 , 20 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1986 */{ 0 , 2 , 9 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1987 */{ 6 , 1 , 29 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 29 384
-1988 */{ 0 , 2 , 17 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1989 */{ 0 , 2 , 6 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 0 355
-1990 */{ 5 , 1 , 27 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
-1991 */{ 0 , 2 , 15 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1992 */{ 0 , 2 , 4 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1993 */{ 3 , 1 , 23 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1994 */{ 0 , 2 , 10 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-1995 */{ 8 , 1 , 31 , 27432 },/* 29 30 30 29 30 29 30 30 29 29 30 29 30 384
-1996 */{ 0 , 2 , 19 , 23232 },/* 29 30 29 30 30 29 30 29 30 30 29 29 0 354
-1997 */{ 0 , 2 , 7 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1998 */{ 5 , 1 , 28 , 37736 },/* 30 29 29 30 29 29 30 30 29 30 30 29 30 384
-1999 */{ 0 , 2 , 16 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-2000 */{ 0 , 2 , 5 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-2001 */{ 4 , 1 , 24 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-2002 */{ 0 , 2 , 12 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-2003 */{ 0 , 2 , 1 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-2004 */{ 2 , 1 , 22 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-2005 */{ 0 , 2 , 9 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-2006 */{ 7 , 1 , 29 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
-2007 */{ 0 , 2 , 18 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-2008 */{ 0 , 2 , 7 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-2009 */{ 5 , 1 , 26 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-2010 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-2011 */{ 0 , 2 , 3 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-2012 */{ 4 , 1 , 23 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-2013 */{ 0 , 2 , 10 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2014 */{ 9 , 1 , 31 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-2015 */{ 0 , 2 , 19 , 19360 },/* 29 30 29 29 30 29 30 30 30 29 30 29 0 354
-2016 */{ 0 , 2 , 8 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-2017 */{ 6 , 1 , 28 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-2018 */{ 0 , 2 , 16 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-2019 */{ 0 , 2 , 5 , 43312 },/* 30 29 30 29 30 29 29 30 29 29 30 30 0 354
-2020 */{ 4 , 1 , 25 , 29864 },/* 29 30 30 30 29 30 29 29 30 29 30 29 30 384
-2021 */{ 0 , 2 , 12 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-2022 */{ 0 , 2 , 1 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2023 */{ 2 , 1 , 22 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
-2024 */{ 0 , 2 , 10 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-2025 */{ 6 , 1 , 29 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-2026 */{ 0 , 2 , 17 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
-2027 */{ 0 , 2 , 6 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-2028 */{ 5 , 1 , 26 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-2029 */{ 0 , 2 , 13 , 54576 },/* 30 30 29 30 29 30 29 30 29 29 30 30 0 355
-2030 */{ 0 , 2 , 3 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-2031 */{ 3 , 1 , 23 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
-2032 */{ 0 , 2 , 11 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-2033 */{ 11 , 1 , 31 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-2034 */{ 0 , 2 , 19 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
-2035 */{ 0 , 2 , 8 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-2036 */{ 6 , 1 , 28 , 53848 },/* 30 30 29 30 29 29 30 29 29 30 29 30 30 384
-2037 */{ 0 , 2 , 15 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-2038 */{ 0 , 2 , 4 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
-2039 */{ 5 , 1 , 24 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 29 384
-2040 */{ 0 , 2 , 12 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
-2041 */{ 0 , 2 , 1 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-2042 */{ 2 , 1 , 22 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
-2043 */{ 0 , 2 , 10 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-2044 */{ 7 , 1 , 30 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-2045 */{ 0 , 2 , 17 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-2046 */{ 0 , 2 , 6 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-2047 */{ 5 , 1 , 26 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-2048 */{ 0 , 2 , 14 , 27936 },/* 29 30 30 29 30 30 29 30 29 29 30 29 0 354
-2049 */{ 0 , 2 , 2 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
-2050 */{ 3 , 1 , 23 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
- */};
-
-
- internal override int MinCalendarYear
- {
- get
- {
- return (MIN_LUNISOLAR_YEAR);
- }
- }
-
- internal override int MaxCalendarYear
- {
- get
- {
- return (MAX_LUNISOLAR_YEAR);
- }
- }
-
- internal override DateTime MinDate
- {
- get
- {
- return (minDate);
- }
- }
-
- internal override DateTime MaxDate
- {
- get
- {
- return (maxDate);
- }
- }
-
- internal override EraInfo[] CalEraInfo
- {
- get
- {
- return (taiwanLunisolarEraInfo);
- }
- }
-
- internal override int GetYearInfo(int lunarYear, int index)
- {
- if ((lunarYear < MIN_LUNISOLAR_YEAR) || (lunarYear > MAX_LUNISOLAR_YEAR))
- {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- MIN_LUNISOLAR_YEAR,
- MAX_LUNISOLAR_YEAR));
- }
- Contract.EndContractBlock();
-
- return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index];
- }
-
- internal override int GetYear(int year, DateTime time)
- {
- return helper.GetYear(year, time);
- }
-
- internal override int GetGregorianYear(int year, int era)
- {
- return helper.GetGregorianYear(year, era);
- }
-
- public TaiwanLunisolarCalendar()
- {
- helper = new GregorianCalendarHelper(this, taiwanLunisolarEraInfo);
- }
-
- public override int GetEra(DateTime time)
- {
- return (helper.GetEra(time));
- }
-
- internal override CalendarId BaseCalendarID
- {
- get
- {
- return (CalendarId.TAIWAN);
- }
- }
-
- internal override CalendarId ID
- {
- get
- {
- return (CalendarId.TAIWANLUNISOLAR);
- }
- }
-
-
-
- public override int[] Eras
- {
- get
- {
- return (helper.Eras);
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/TextElementEnumerator.cs b/src/mscorlib/corefx/System/Globalization/TextElementEnumerator.cs
deleted file mode 100644
index 464897b03f..0000000000
--- a/src/mscorlib/corefx/System/Globalization/TextElementEnumerator.cs
+++ /dev/null
@@ -1,153 +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.
-
-////////////////////////////////////////////////////////////////////////////
-//
-//
-// Purpose:
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
-using System.Collections;
-using System.Diagnostics;
-using System.Runtime.Serialization;
-
-namespace System.Globalization
-{
- //
- // This is public because GetTextElement() is public.
- //
-
- [Serializable]
- public class TextElementEnumerator : IEnumerator
- {
- private String _str;
- private int _index;
- private int _startIndex;
-
- [NonSerialized]
- private int _strLen; // This is the length of the total string, counting from the beginning of string.
-
- [NonSerialized]
- private int _currTextElementLen; // The current text element lenght after MoveNext() is called.
-
- [OptionalField(VersionAdded = 2)]
- private UnicodeCategory _uc;
-
- [OptionalField(VersionAdded = 2)]
- private int _charLen; // The next abstract char to look at after MoveNext() is called. It could be 1 or 2, depending on if it is a surrogate or not.
-
- internal TextElementEnumerator(String str, int startIndex, int strLen)
- {
- Debug.Assert(str != null, "TextElementEnumerator(): str != null");
- Debug.Assert(startIndex >= 0 && strLen >= 0, "TextElementEnumerator(): startIndex >= 0 && strLen >= 0");
- Debug.Assert(strLen >= startIndex, "TextElementEnumerator(): strLen >= startIndex");
- _str = str;
- _startIndex = startIndex;
- _strLen = strLen;
- Reset();
- }
-
- // the following fields is defined to keep the compatibility with Everett.
- // don't change/remove the names/types of these fields.
- private int _endIndex;
- private int _nextTextElementLen;
-
- [OnDeserializing]
- private void OnDeserializing(StreamingContext ctx)
- {
- _charLen = -1;
- }
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext ctx)
- {
- _strLen = _endIndex + 1;
- _currTextElementLen = _nextTextElementLen;
-
- if (_charLen == -1)
- {
- _uc = CharUnicodeInfo.InternalGetUnicodeCategory(_str, _index, out _charLen);
- }
- }
-
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx)
- {
- _endIndex = _strLen - 1;
- _nextTextElementLen = _currTextElementLen;
- }
-
- public bool MoveNext()
- {
- if (_index >= _strLen)
- {
- // Make the _index to be greater than _strLen so that we can throw exception if GetTextElement() is called.
- _index = _strLen + 1;
- return (false);
- }
- _currTextElementLen = StringInfo.GetCurrentTextElementLen(_str, _index, _strLen, ref _uc, ref _charLen);
- _index += _currTextElementLen;
- return (true);
- }
-
- //
- // Get the current text element.
- //
-
- public Object Current
- {
- get
- {
- return (GetTextElement());
- }
- }
-
- //
- // Get the current text element.
- //
-
- public String GetTextElement()
- {
- if (_index == _startIndex)
- {
- throw new InvalidOperationException(SR.InvalidOperation_EnumNotStarted);
- }
- if (_index > _strLen)
- {
- throw new InvalidOperationException(SR.InvalidOperation_EnumEnded);
- }
-
- return (_str.Substring(_index - _currTextElementLen, _currTextElementLen));
- }
-
- //
- // Get the starting index of the current text element.
- //
-
- public int ElementIndex
- {
- get
- {
- if (_index == _startIndex)
- {
- throw new InvalidOperationException(SR.InvalidOperation_EnumNotStarted);
- }
- return (_index - _currTextElementLen);
- }
- }
-
-
- public void Reset()
- {
- _index = _startIndex;
- if (_index < _strLen)
- {
- // If we have more than 1 character, get the category of the current char.
- _uc = CharUnicodeInfo.InternalGetUnicodeCategory(_str, _index, out _charLen);
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs b/src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs
deleted file mode 100644
index 67836d89d6..0000000000
--- a/src/mscorlib/corefx/System/Globalization/TextInfo.Unix.cs
+++ /dev/null
@@ -1,126 +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.Diagnostics;
-using System.Diagnostics.Contracts;
-using System.Security;
-using System.Text;
-
-namespace System.Globalization
-{
- public partial class TextInfo
- {
- [NonSerialized]
- private Tristate _needsTurkishCasing = Tristate.NotInitialized;
-
- //////////////////////////////////////////////////////////////////////////
- ////
- //// TextInfo Constructors
- ////
- //// Implements CultureInfo.TextInfo.
- ////
- //////////////////////////////////////////////////////////////////////////
- internal unsafe TextInfo(CultureData cultureData)
- {
- _cultureData = cultureData;
- _cultureName = _cultureData.CultureName;
- _textInfoName = _cultureData.STEXTINFO;
- FinishInitialization(_textInfoName);
- }
-
- private void FinishInitialization(string textInfoName)
- {
- }
-
- private unsafe string ChangeCase(string s, bool toUpper)
- {
- Debug.Assert(s != null);
-
- if (s.Length == 0)
- {
- return string.Empty;
- }
-
- string result = string.FastAllocateString(s.Length);
-
- fixed (char* pSource = s)
- {
- fixed (char* pResult = result)
- {
- if (IsAsciiCasingSameAsInvariant && s.IsAscii())
- {
- int length = s.Length;
- char* a = pSource, b = pResult;
- if (toUpper)
- {
- while (length-- != 0)
- {
- *b++ = ToUpperAsciiInvariant(*a++);
- }
- }
- else
- {
- while (length-- != 0)
- {
- *b++ = ToLowerAsciiInvariant(*a++);
- }
- }
- }
- else
- {
- ChangeCase(pSource, s.Length, pResult, result.Length, toUpper);
- }
- }
- }
-
- return result;
- }
-
- private unsafe char ChangeCase(char c, bool toUpper)
- {
- char dst = default(char);
-
- ChangeCase(&c, 1, &dst, 1, toUpper);
-
- return dst;
- }
-
- // -----------------------------
- // ---- PAL layer ends here ----
- // -----------------------------
-
- private bool NeedsTurkishCasing(string localeName)
- {
- Debug.Assert(localeName != null);
-
- return CultureInfo.GetCultureInfo(localeName).CompareInfo.Compare("\u0131", "I", CompareOptions.IgnoreCase) == 0;
- }
-
- private bool IsInvariant { get { return _cultureName.Length == 0; } }
-
- internal unsafe void ChangeCase(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper)
- {
- if (IsInvariant)
- {
- Interop.GlobalizationInterop.ChangeCaseInvariant(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper);
- }
- else
- {
- if (_needsTurkishCasing == Tristate.NotInitialized)
- {
- _needsTurkishCasing = NeedsTurkishCasing(_textInfoName) ? Tristate.True : Tristate.False;
- }
- if (_needsTurkishCasing == Tristate.True)
- {
- Interop.GlobalizationInterop.ChangeCaseTurkish(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper);
- }
- else
- {
- Interop.GlobalizationInterop.ChangeCase(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper);
- }
- }
- }
-
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/TextInfo.Windows.cs b/src/mscorlib/corefx/System/Globalization/TextInfo.Windows.cs
deleted file mode 100644
index b2f692e2d0..0000000000
--- a/src/mscorlib/corefx/System/Globalization/TextInfo.Windows.cs
+++ /dev/null
@@ -1,121 +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.Diagnostics;
-
-namespace System.Globalization
-{
- public partial class TextInfo
- {
- //////////////////////////////////////////////////////////////////////////
- ////
- //// TextInfo Constructors
- ////
- //// Implements CultureInfo.TextInfo.
- ////
- //////////////////////////////////////////////////////////////////////////
- internal unsafe TextInfo(CultureData cultureData)
- {
- // This is our primary data source, we don't need most of the rest of this
- _cultureData = cultureData;
- _cultureName = _cultureData.CultureName;
- _textInfoName = _cultureData.STEXTINFO;
- FinishInitialization(_textInfoName);
- }
-
- private void FinishInitialization(string textInfoName)
- {
- const uint LCMAP_SORTHANDLE = 0x20000000;
-
- long handle;
- int ret = Interop.mincore.LCMapStringEx(_textInfoName, LCMAP_SORTHANDLE, null, 0, &handle, IntPtr.Size, null, null, IntPtr.Zero);
- _sortHandle = ret > 0 ? (IntPtr)handle : IntPtr.Zero;
- }
-
- private unsafe string ChangeCase(string s, bool toUpper)
- {
- Debug.Assert(s != null);
-
- //
- // Get the length of the string.
- //
- int nLengthInput = s.Length;
-
- //
- // Check if we have the empty string.
- //
- if (nLengthInput == 0)
- {
- return s;
- }
- else
- {
- int ret;
-
- // Check for Invariant to avoid A/V in LCMapStringEx
- uint linguisticCasing = IsInvariantLocale(_textInfoName) ? 0 : LCMAP_LINGUISTIC_CASING;
-
- //
- // Create the result string.
- //
- string result = string.FastAllocateString(nLengthInput);
-
- fixed (char* pSource = s)
- fixed (char* pResult = result)
- {
- ret = Interop.mincore.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _textInfoName,
- toUpper ? LCMAP_UPPERCASE | linguisticCasing : LCMAP_LOWERCASE | linguisticCasing,
- pSource,
- nLengthInput,
- pResult,
- nLengthInput,
- null,
- null,
- _sortHandle);
- }
-
- if (0 == ret)
- {
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- }
-
- Debug.Assert(ret == nLengthInput, "Expected getting the same length of the original string");
- return result;
- }
- }
-
- private unsafe char ChangeCase(char c, bool toUpper)
- {
- char retVal = '\0';
-
- // Check for Invariant to avoid A/V in LCMapStringEx
- uint linguisticCasing = IsInvariantLocale(_textInfoName) ? 0 : LCMAP_LINGUISTIC_CASING;
-
- Interop.mincore.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _textInfoName,
- toUpper ? LCMAP_UPPERCASE | linguisticCasing : LCMAP_LOWERCASE | linguisticCasing,
- &c,
- 1,
- &retVal,
- 1,
- null,
- null,
- _sortHandle);
-
- return retVal;
- }
-
- // PAL Ends here
-
- private readonly IntPtr _sortHandle;
-
- private const uint LCMAP_LINGUISTIC_CASING = 0x01000000;
- private const uint LCMAP_LOWERCASE = 0x00000100;
- private const uint LCMAP_UPPERCASE = 0x00000200;
-
- private static bool IsInvariantLocale(string localeName)
- {
- return localeName == "";
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/TextInfo.cs b/src/mscorlib/corefx/System/Globalization/TextInfo.cs
deleted file mode 100644
index 172bbd25b2..0000000000
--- a/src/mscorlib/corefx/System/Globalization/TextInfo.cs
+++ /dev/null
@@ -1,746 +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.
-
-////////////////////////////////////////////////////////////////////////////
-//
-//
-// Purpose: This Class defines behaviors specific to a writing system.
-// A writing system is the collection of scripts and
-// orthographic rules required to represent a language as text.
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-using System.Runtime.Serialization;
-using System.Text;
-
-namespace System.Globalization
-{
- [Serializable]
- public partial class TextInfo : ICloneable, IDeserializationCallback
- {
- ////--------------------------------------------------------------------//
- //// Internal Information //
- ////--------------------------------------------------------------------//
-
- private enum Tristate : byte
- {
- NotInitialized,
- True,
- False,
- }
-
- ////
- //// Variables.
- ////
-
- [OptionalField(VersionAdded = 2)]
- private String _listSeparator;
- [OptionalField(VersionAdded = 2)]
- private bool _isReadOnly = false;
-
- //// _cultureName is the name of the creating culture. Note that we consider this authoratative,
- //// if the culture's textinfo changes when deserializing, then behavior may change.
- //// (ala Whidbey behavior). This is the only string Arrowhead needs to serialize.
- //// _cultureData is the data that backs this class.
- //// _textInfoName is the actual name of the textInfo (from cultureData.STEXTINFO)
- //// this can be the same as _cultureName on Silverlight since the OS knows
- //// how to do the sorting. However in the desktop, when we call the sorting dll, it doesn't
- //// know how to resolve custom locle names to sort ids so we have to have alredy resolved this.
- ////
-
- [OptionalField(VersionAdded = 3)]
- private String _cultureName; // Name of the culture that created this text info
- [NonSerialized]
- private CultureData _cultureData; // Data record for the culture that made us, not for this textinfo
- [NonSerialized]
- private String _textInfoName; // Name of the text info we're using (ie: _cultureData.STEXTINFO)
- [NonSerialized]
- private Tristate _isAsciiCasingSameAsInvariant = Tristate.NotInitialized;
-
- // Invariant text info
- internal static TextInfo Invariant
- {
- get
- {
- if (s_Invariant == null)
- s_Invariant = new TextInfo(CultureData.Invariant);
- return s_Invariant;
- }
- }
- internal volatile static TextInfo s_Invariant;
-
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx) { }
-
- [OnDeserializing]
- private void OnDeserializing(StreamingContext ctx)
- {
- // Clear these so we can check if we've fixed them yet
- _cultureData = null;
- _cultureName = null;
- }
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext ctx)
- {
- OnDeserialized();
- }
-
- void IDeserializationCallback.OnDeserialization(Object sender)
- {
- OnDeserialized();
- }
-
- private void OnDeserialized()
- {
- // this method will be called twice because of the support of IDeserializationCallback
- if (_cultureData == null)
- {
- // Get the text info name belonging to that culture
- _cultureData = CultureInfo.GetCultureInfo(_cultureName).m_cultureData;
- _textInfoName = _cultureData.STEXTINFO;
- FinishInitialization(_textInfoName);
- }
- }
-
- //
- // Internal ordinal comparison functions
- //
-
- internal static int GetHashCodeOrdinalIgnoreCase(String s)
- {
- // This is the same as an case insensitive hash for Invariant
- // (not necessarily true for sorting, but OK for casing & then we apply normal hash code rules)
- return (Invariant.GetCaseInsensitiveHashCode(s));
- }
-
- // Currently we don't have native functions to do this, so we do it the hard way
- internal static int IndexOfStringOrdinalIgnoreCase(String source, String value, int startIndex, int count)
- {
- if (count > source.Length || count < 0 || startIndex < 0 || startIndex >= source.Length || startIndex + count > source.Length)
- {
- return -1;
- }
-
- return CompareInfo.IndexOfOrdinal(source, value, startIndex, count, ignoreCase: true);
- }
-
- // Currently we don't have native functions to do this, so we do it the hard way
- internal static int LastIndexOfStringOrdinalIgnoreCase(String source, String value, int startIndex, int count)
- {
- if (count > source.Length || count < 0 || startIndex < 0 || startIndex > source.Length - 1 || (startIndex - count + 1 < 0))
- {
- return -1;
- }
-
- return CompareInfo.LastIndexOfOrdinal(source, value, startIndex, count, ignoreCase: true);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // CodePage
- //
- // Returns the number of the code page used by this writing system.
- // The type parameter can be any of the following values:
- // ANSICodePage
- // OEMCodePage
- // MACCodePage
- //
- ////////////////////////////////////////////////////////////////////////
-
-
- public virtual int ANSICodePage
- {
- get
- {
- return (_cultureData.IDEFAULTANSICODEPAGE);
- }
- }
-
-
- public virtual int OEMCodePage
- {
- get
- {
- return (_cultureData.IDEFAULTOEMCODEPAGE);
- }
- }
-
-
- public virtual int MacCodePage
- {
- get
- {
- return (_cultureData.IDEFAULTMACCODEPAGE);
- }
- }
-
-
- public virtual int EBCDICCodePage
- {
- get
- {
- return (_cultureData.IDEFAULTEBCDICCODEPAGE);
- }
- }
-
- public int LCID
- {
- get
- {
- // Just use the LCID from our text info name
- return CultureInfo.GetCultureInfo(_textInfoName).LCID;
- }
- }
-
- //////////////////////////////////////////////////////////////////////////
- ////
- //// CultureName
- ////
- //// The name of the culture associated with the current TextInfo.
- ////
- //////////////////////////////////////////////////////////////////////////
- public string CultureName
- {
- get
- {
- return _textInfoName;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // IsReadOnly
- //
- // Detect if the object is readonly.
- //
- ////////////////////////////////////////////////////////////////////////
- public bool IsReadOnly
- {
- get { return (_isReadOnly); }
- }
-
- //////////////////////////////////////////////////////////////////////////
- ////
- //// Clone
- ////
- //// Is the implementation of ICloneable.
- ////
- //////////////////////////////////////////////////////////////////////////
- public virtual object Clone()
- {
- object o = MemberwiseClone();
- ((TextInfo)o).SetReadOnlyState(false);
- return (o);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ReadOnly
- //
- // Create a cloned readonly instance or return the input one if it is
- // readonly.
- //
- ////////////////////////////////////////////////////////////////////////
- public static TextInfo ReadOnly(TextInfo textInfo)
- {
- if (textInfo == null) { throw new ArgumentNullException(nameof(textInfo)); }
- Contract.EndContractBlock();
- if (textInfo.IsReadOnly) { return (textInfo); }
-
- TextInfo clonedTextInfo = (TextInfo)(textInfo.MemberwiseClone());
- clonedTextInfo.SetReadOnlyState(true);
-
- return (clonedTextInfo);
- }
-
- private void VerifyWritable()
- {
- if (_isReadOnly)
- {
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- }
- }
-
- internal void SetReadOnlyState(bool readOnly)
- {
- _isReadOnly = readOnly;
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ListSeparator
- //
- // Returns the string used to separate items in a list.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual String ListSeparator
- {
- get
- {
- if (_listSeparator == null)
- {
- _listSeparator = _cultureData.SLIST;
- }
- return (_listSeparator);
- }
-
- set
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String);
- }
- VerifyWritable();
- _listSeparator = value;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ToLower
- //
- // Converts the character or string to lower case. Certain locales
- // have different casing semantics from the file systems in Win32.
- //
- ////////////////////////////////////////////////////////////////////////
- public unsafe virtual char ToLower(char c)
- {
- if (IsAscii(c) && IsAsciiCasingSameAsInvariant)
- {
- return ToLowerAsciiInvariant(c);
- }
- return (ChangeCase(c, toUpper: false));
- }
-
- public unsafe virtual String ToLower(String str)
- {
- if (str == null) { throw new ArgumentNullException(nameof(str)); }
-
- return ChangeCase(str, toUpper: false);
- }
-
- private static Char ToLowerAsciiInvariant(Char c)
- {
- if ((uint)(c - 'A') <= (uint)('Z' - 'A'))
- {
- c = (Char)(c | 0x20);
- }
- return c;
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ToUpper
- //
- // Converts the character or string to upper case. Certain locales
- // have different casing semantics from the file systems in Win32.
- //
- ////////////////////////////////////////////////////////////////////////
- public unsafe virtual char ToUpper(char c)
- {
- if (IsAscii(c) && IsAsciiCasingSameAsInvariant)
- {
- return ToUpperAsciiInvariant(c);
- }
- return (ChangeCase(c, toUpper: true));
- }
-
- public unsafe virtual String ToUpper(String str)
- {
- if (str == null) { throw new ArgumentNullException(nameof(str)); }
-
- return ChangeCase(str, toUpper: true);
- }
-
- private static Char ToUpperAsciiInvariant(Char c)
- {
- if ((uint)(c - 'a') <= (uint)('z' - 'a'))
- {
- c = (Char)(c & ~0x20);
- }
- return c;
- }
-
- private static bool IsAscii(Char c)
- {
- return c < 0x80;
- }
-
- private bool IsAsciiCasingSameAsInvariant
- {
- get
- {
- if (_isAsciiCasingSameAsInvariant == Tristate.NotInitialized)
- {
- _isAsciiCasingSameAsInvariant = CultureInfo.GetCultureInfo(_textInfoName).CompareInfo.Compare("abcdefghijklmnopqrstuvwxyz",
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
- CompareOptions.IgnoreCase) == 0 ? Tristate.True : Tristate.False;
- }
- return _isAsciiCasingSameAsInvariant == Tristate.True;
- }
- }
-
- // IsRightToLeft
- //
- // Returns true if the dominant direction of text and UI such as the relative position of buttons and scroll bars
- //
- public bool IsRightToLeft
- {
- get
- {
- return _cultureData.IsRightToLeft;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Equals
- //
- // Implements Object.Equals(). Returns a boolean indicating whether
- // or not object refers to the same CultureInfo as the current instance.
- //
- ////////////////////////////////////////////////////////////////////////
- public override bool Equals(Object obj)
- {
- TextInfo that = obj as TextInfo;
-
- if (that != null)
- {
- return this.CultureName.Equals(that.CultureName);
- }
-
- return (false);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetHashCode
- //
- // Implements Object.GetHashCode(). Returns the hash code for the
- // CultureInfo. The hash code is guaranteed to be the same for CultureInfo A
- // and B where A.Equals(B) is true.
- //
- ////////////////////////////////////////////////////////////////////////
- public override int GetHashCode()
- {
- return (this.CultureName.GetHashCode());
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ToString
- //
- // Implements Object.ToString(). Returns a string describing the
- // TextInfo.
- //
- ////////////////////////////////////////////////////////////////////////
- public override String ToString()
- {
- return ("TextInfo - " + _cultureData.CultureName);
- }
-
- //
- // Titlecasing:
- // -----------
- // Titlecasing refers to a casing practice wherein the first letter of a word is an uppercase letter
- // and the rest of the letters are lowercase. The choice of which words to titlecase in headings
- // and titles is dependent on language and local conventions. For example, "The Merry Wives of Windor"
- // is the appropriate titlecasing of that play's name in English, with the word "of" not titlecased.
- // In German, however, the title is "Die lustigen Weiber von Windsor," and both "lustigen" and "von"
- // are not titlecased. In French even fewer words are titlecased: "Les joyeuses commeres de Windsor."
- //
- // Moreover, the determination of what actually constitutes a word is language dependent, and this can
- // influence which letter or letters of a "word" are uppercased when titlecasing strings. For example
- // "l'arbre" is considered two words in French, whereas "can't" is considered one word in English.
- //
- public unsafe String ToTitleCase(String str)
- {
- if (str == null)
- {
- throw new ArgumentNullException(nameof(str));
- }
- Contract.EndContractBlock();
- if (str.Length == 0)
- {
- return (str);
- }
-
- StringBuilder result = new StringBuilder();
- string lowercaseData = null;
-
- for (int i = 0; i < str.Length; i++)
- {
- UnicodeCategory charType;
- int charLen;
-
- charType = CharUnicodeInfo.InternalGetUnicodeCategory(str, i, out charLen);
- if (Char.CheckLetter(charType))
- {
- // Do the titlecasing for the first character of the word.
- i = AddTitlecaseLetter(ref result, ref str, i, charLen) + 1;
-
- //
- // Convert the characters until the end of the this word
- // to lowercase.
- //
- int lowercaseStart = i;
-
- //
- // Use hasLowerCase flag to prevent from lowercasing acronyms (like "URT", "USA", etc)
- // This is in line with Word 2000 behavior of titlecasing.
- //
- bool hasLowerCase = (charType == UnicodeCategory.LowercaseLetter);
- // Use a loop to find all of the other letters following this letter.
- while (i < str.Length)
- {
- charType = CharUnicodeInfo.InternalGetUnicodeCategory(str, i, out charLen);
- if (IsLetterCategory(charType))
- {
- if (charType == UnicodeCategory.LowercaseLetter)
- {
- hasLowerCase = true;
- }
- i += charLen;
- }
- else if (str[i] == '\'')
- {
- i++;
- if (hasLowerCase)
- {
- if (lowercaseData == null)
- {
- lowercaseData = this.ToLower(str);
- }
- result.Append(lowercaseData, lowercaseStart, i - lowercaseStart);
- }
- else
- {
- result.Append(str, lowercaseStart, i - lowercaseStart);
- }
- lowercaseStart = i;
- hasLowerCase = true;
- }
- else if (!IsWordSeparator(charType))
- {
- // This category is considered to be part of the word.
- // This is any category that is marked as false in wordSeprator array.
- i+= charLen;
- }
- else
- {
- // A word separator. Break out of the loop.
- break;
- }
- }
-
- int count = i - lowercaseStart;
-
- if (count > 0)
- {
- if (hasLowerCase)
- {
- if (lowercaseData == null)
- {
- lowercaseData = this.ToLower(str);
- }
- result.Append(lowercaseData, lowercaseStart, count);
- }
- else
- {
- result.Append(str, lowercaseStart, count);
- }
- }
-
- if (i < str.Length)
- {
- // not a letter, just append it
- i = AddNonLetter(ref result, ref str, i, charLen);
- }
- }
- else
- {
- // not a letter, just append it
- i = AddNonLetter(ref result, ref str, i, charLen);
- }
- }
- return (result.ToString());
- }
-
- private static int AddNonLetter(ref StringBuilder result, ref String input, int inputIndex, int charLen)
- {
- Debug.Assert(charLen == 1 || charLen == 2, "[TextInfo.AddNonLetter] CharUnicodeInfo.InternalGetUnicodeCategory returned an unexpected charLen!");
- if (charLen == 2)
- {
- // Surrogate pair
- result.Append(input[inputIndex++]);
- result.Append(input[inputIndex]);
- }
- else
- {
- result.Append(input[inputIndex]);
- }
- return inputIndex;
- }
-
- private int AddTitlecaseLetter(ref StringBuilder result, ref String input, int inputIndex, int charLen)
- {
- Debug.Assert(charLen == 1 || charLen == 2, "[TextInfo.AddTitlecaseLetter] CharUnicodeInfo.InternalGetUnicodeCategory returned an unexpected charLen!");
-
- // for surrogate pairs do a simple ToUpper operation on the substring
- if (charLen == 2)
- {
- // Surrogate pair
- result.Append(ToUpper(input.Substring(inputIndex, charLen)));
- inputIndex++;
- }
- else
- {
- switch (input[inputIndex])
- {
- //
- // For AppCompat, the Titlecase Case Mapping data from NDP 2.0 is used below.
- case (char) 0x01C4: // DZ with Caron -> Dz with Caron
- case (char) 0x01C5: // Dz with Caron -> Dz with Caron
- case (char) 0x01C6: // dz with Caron -> Dz with Caron
- result.Append((char) 0x01C5);
- break;
- case (char) 0x01C7: // LJ -> Lj
- case (char) 0x01C8: // Lj -> Lj
- case (char) 0x01C9: // lj -> Lj
- result.Append((char) 0x01C8);
- break;
- case (char) 0x01CA: // NJ -> Nj
- case (char) 0x01CB: // Nj -> Nj
- case (char) 0x01CC: // nj -> Nj
- result.Append((char) 0x01CB);
- break;
- case (char) 0x01F1: // DZ -> Dz
- case (char) 0x01F2: // Dz -> Dz
- case (char) 0x01F3: // dz -> Dz
- result.Append((char) 0x01F2);
- break;
- default:
- result.Append(ToUpper(input[inputIndex]));
- break;
- }
- }
- return inputIndex;
- }
-
- //
- // Used in ToTitleCase():
- // When we find a starting letter, the following array decides if a category should be
- // considered as word seprator or not.
- //
- private const int c_wordSeparatorMask =
- /* false */ (0 << 0) | // UppercaseLetter = 0,
- /* false */ (0 << 1) | // LowercaseLetter = 1,
- /* false */ (0 << 2) | // TitlecaseLetter = 2,
- /* false */ (0 << 3) | // ModifierLetter = 3,
- /* false */ (0 << 4) | // OtherLetter = 4,
- /* false */ (0 << 5) | // NonSpacingMark = 5,
- /* false */ (0 << 6) | // SpacingCombiningMark = 6,
- /* false */ (0 << 7) | // EnclosingMark = 7,
- /* false */ (0 << 8) | // DecimalDigitNumber = 8,
- /* false */ (0 << 9) | // LetterNumber = 9,
- /* false */ (0 << 10) | // OtherNumber = 10,
- /* true */ (1 << 11) | // SpaceSeparator = 11,
- /* true */ (1 << 12) | // LineSeparator = 12,
- /* true */ (1 << 13) | // ParagraphSeparator = 13,
- /* true */ (1 << 14) | // Control = 14,
- /* true */ (1 << 15) | // Format = 15,
- /* false */ (0 << 16) | // Surrogate = 16,
- /* false */ (0 << 17) | // PrivateUse = 17,
- /* true */ (1 << 18) | // ConnectorPunctuation = 18,
- /* true */ (1 << 19) | // DashPunctuation = 19,
- /* true */ (1 << 20) | // OpenPunctuation = 20,
- /* true */ (1 << 21) | // ClosePunctuation = 21,
- /* true */ (1 << 22) | // InitialQuotePunctuation = 22,
- /* true */ (1 << 23) | // FinalQuotePunctuation = 23,
- /* true */ (1 << 24) | // OtherPunctuation = 24,
- /* true */ (1 << 25) | // MathSymbol = 25,
- /* true */ (1 << 26) | // CurrencySymbol = 26,
- /* true */ (1 << 27) | // ModifierSymbol = 27,
- /* true */ (1 << 28) | // OtherSymbol = 28,
- /* false */ (0 << 29); // OtherNotAssigned = 29;
-
- private static bool IsWordSeparator(UnicodeCategory category)
- {
- return (c_wordSeparatorMask & (1 << (int) category)) != 0;
- }
-
- private static bool IsLetterCategory(UnicodeCategory uc)
- {
- return (uc == UnicodeCategory.UppercaseLetter
- || uc == UnicodeCategory.LowercaseLetter
- || uc == UnicodeCategory.TitlecaseLetter
- || uc == UnicodeCategory.ModifierLetter
- || uc == UnicodeCategory.OtherLetter);
- }
-
- //
- // Get case-insensitive hash code for the specified string.
- //
- internal unsafe int GetCaseInsensitiveHashCode(String str)
- {
- // Validate inputs
- if (str == null)
- {
- throw new ArgumentNullException(nameof(str));
- }
-
- // This code assumes that ASCII casing is safe for whatever context is passed in.
- // this is true today, because we only ever call these methods on Invariant. It would be ideal to refactor
- // these methods so they were correct by construction and we could only ever use Invariant.
-
- uint hash = 5381;
- uint c;
-
- // Note: We assume that str contains only ASCII characters until
- // we hit a non-ASCII character to optimize the common case.
- for (int i = 0; i < str.Length; i++)
- {
- c = str[i];
- if (c >= 0x80)
- {
- return GetCaseInsensitiveHashCodeSlow(str);
- }
-
- // If we have a lowercase character, ANDing off 0x20
- // will make it an uppercase character.
- if ((c - 'a') <= ('z' - 'a'))
- {
- c = (uint)((int)c & ~0x20);
- }
-
- hash = ((hash << 5) + hash) ^ c;
- }
-
- return (int)hash;
- }
-
- private unsafe int GetCaseInsensitiveHashCodeSlow(String str)
- {
- Debug.Assert(str != null);
-
- string upper = ToUpper(str);
-
- uint hash = 5381;
- uint c;
-
- for (int i = 0; i < upper.Length; i++)
- {
- c = upper[i];
- hash = ((hash << 5) + hash) ^ c;
- }
-
- return (int)hash;
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/UmAlQuraCalendar.cs b/src/mscorlib/corefx/System/Globalization/UmAlQuraCalendar.cs
deleted file mode 100644
index 7b47d9c02b..0000000000
--- a/src/mscorlib/corefx/System/Globalization/UmAlQuraCalendar.cs
+++ /dev/null
@@ -1,870 +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.Diagnostics;
-using System.Diagnostics.Contracts;
-
-namespace System.Globalization
-{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about UmAlQuraCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
- /*
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 1900/04/30 2077/05/13
- ** UmAlQura 1318/01/01 1500/12/30
- */
-
- [Serializable]
- public partial class UmAlQuraCalendar : Calendar
- {
- internal const int MinCalendarYear = 1318;
- internal const int MaxCalendarYear = 1500;
-
- internal struct DateMapping
- {
- internal DateMapping(int MonthsLengthFlags, int GYear, int GMonth, int GDay)
- {
- HijriMonthsLengthFlags = MonthsLengthFlags;
- GregorianDate = new DateTime(GYear, GMonth, GDay);
- }
- internal int HijriMonthsLengthFlags;
- internal DateTime GregorianDate;
- }
-
- private static readonly DateMapping[] s_hijriYearInfo = InitDateMapping();
-
- private static DateMapping[] InitDateMapping()
- {
- short[] rawData = new short[]
- {
- //These data is taken from Tables/Excel/UmAlQura.xls please make sure that the two places are in sync
- /* DaysPerM GY GM GD D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12
- 1318*/0x02EA, 1900, 4, 30,/* 0 1 0 1 0 1 1 1 0 1 0 0 4/30/1900
- 1319*/0x06E9, 1901, 4, 19,/* 1 0 0 1 0 1 1 1 0 1 1 0 4/19/1901
- 1320*/0x0ED2, 1902, 4, 9,/* 0 1 0 0 1 0 1 1 0 1 1 1 4/9/1902
- 1321*/0x0EA4, 1903, 3, 30,/* 0 0 1 0 0 1 0 1 0 1 1 1 3/30/1903
- 1322*/0x0D4A, 1904, 3, 18,/* 0 1 0 1 0 0 1 0 1 0 1 1 3/18/1904
- 1323*/0x0A96, 1905, 3, 7,/* 0 1 1 0 1 0 0 1 0 1 0 1 3/7/1905
- 1324*/0x0536, 1906, 2, 24,/* 0 1 1 0 1 1 0 0 1 0 1 0 2/24/1906
- 1325*/0x0AB5, 1907, 2, 13,/* 1 0 1 0 1 1 0 1 0 1 0 1 2/13/1907
- 1326*/0x0DAA, 1908, 2, 3,/* 0 1 0 1 0 1 0 1 1 0 1 1 2/3/1908
- 1327*/0x0BA4, 1909, 1, 23,/* 0 0 1 0 0 1 0 1 1 1 0 1 1/23/1909
- 1328*/0x0B49, 1910, 1, 12,/* 1 0 0 1 0 0 1 0 1 1 0 1 1/12/1910
- 1329*/0x0A93, 1911, 1, 1,/* 1 1 0 0 1 0 0 1 0 1 0 1 1/1/1911
- 1330*/0x052B, 1911, 12, 21,/* 1 1 0 1 0 1 0 0 1 0 1 0 12/21/1911
- 1331*/0x0A57, 1912, 12, 9,/* 1 1 1 0 1 0 1 0 0 1 0 1 12/9/1912
- 1332*/0x04B6, 1913, 11, 29,/* 0 1 1 0 1 1 0 1 0 0 1 0 11/29/1913
- 1333*/0x0AB5, 1914, 11, 18,/* 1 0 1 0 1 1 0 1 0 1 0 1 11/18/1914
- 1334*/0x05AA, 1915, 11, 8,/* 0 1 0 1 0 1 0 1 1 0 1 0 11/8/1915
- 1335*/0x0D55, 1916, 10, 27,/* 1 0 1 0 1 0 1 0 1 0 1 1 10/27/1916
- 1336*/0x0D2A, 1917, 10, 17,/* 0 1 0 1 0 1 0 0 1 0 1 1 10/17/1917
- 1337*/0x0A56, 1918, 10, 6,/* 0 1 1 0 1 0 1 0 0 1 0 1 10/6/1918
- 1338*/0x04AE, 1919, 9, 25,/* 0 1 1 1 0 1 0 1 0 0 1 0 9/25/1919
- 1339*/0x095D, 1920, 9, 13,/* 1 0 1 1 1 0 1 0 1 0 0 1 9/13/1920
- 1340*/0x02EC, 1921, 9, 3,/* 0 0 1 1 0 1 1 1 0 1 0 0 9/3/1921
- 1341*/0x06D5, 1922, 8, 23,/* 1 0 1 0 1 0 1 1 0 1 1 0 8/23/1922
- 1342*/0x06AA, 1923, 8, 13,/* 0 1 0 1 0 1 0 1 0 1 1 0 8/13/1923
- 1343*/0x0555, 1924, 8, 1,/* 1 0 1 0 1 0 1 0 1 0 1 0 8/1/1924
- 1344*/0x04AB, 1925, 7, 21,/* 1 1 0 1 0 1 0 1 0 0 1 0 7/21/1925
- 1345*/0x095B, 1926, 7, 10,/* 1 1 0 1 1 0 1 0 1 0 0 1 7/10/1926
- 1346*/0x02BA, 1927, 6, 30,/* 0 1 0 1 1 1 0 1 0 1 0 0 6/30/1927
- 1347*/0x0575, 1928, 6, 18,/* 1 0 1 0 1 1 1 0 1 0 1 0 6/18/1928
- 1348*/0x0BB2, 1929, 6, 8,/* 0 1 0 0 1 1 0 1 1 1 0 1 6/8/1929
- 1349*/0x0764, 1930, 5, 29,/* 0 0 1 0 0 1 1 0 1 1 1 0 5/29/1930
- 1350*/0x0749, 1931, 5, 18,/* 1 0 0 1 0 0 1 0 1 1 1 0 5/18/1931
- 1351*/0x0655, 1932, 5, 6,/* 1 0 1 0 1 0 1 0 0 1 1 0 5/6/1932
- 1352*/0x02AB, 1933, 4, 25,/* 1 1 0 1 0 1 0 1 0 1 0 0 4/25/1933
- 1353*/0x055B, 1934, 4, 14,/* 1 1 0 1 1 0 1 0 1 0 1 0 4/14/1934
- 1354*/0x0ADA, 1935, 4, 4,/* 0 1 0 1 1 0 1 1 0 1 0 1 4/4/1935
- 1355*/0x06D4, 1936, 3, 24,/* 0 0 1 0 1 0 1 1 0 1 1 0 3/24/1936
- 1356*/0x0EC9, 1937, 3, 13,/* 1 0 0 1 0 0 1 1 0 1 1 1 3/13/1937
- 1357*/0x0D92, 1938, 3, 3,/* 0 1 0 0 1 0 0 1 1 0 1 1 3/3/1938
- 1358*/0x0D25, 1939, 2, 20,/* 1 0 1 0 0 1 0 0 1 0 1 1 2/20/1939
- 1359*/0x0A4D, 1940, 2, 9,/* 1 0 1 1 0 0 1 0 0 1 0 1 2/9/1940
- 1360*/0x02AD, 1941, 1, 28,/* 1 0 1 1 0 1 0 1 0 1 0 0 1/28/1941
- 1361*/0x056D, 1942, 1, 17,/* 1 0 1 1 0 1 1 0 1 0 1 0 1/17/1942
- 1362*/0x0B6A, 1943, 1, 7,/* 0 1 0 1 0 1 1 0 1 1 0 1 1/7/1943
- 1363*/0x0B52, 1943, 12, 28,/* 0 1 0 0 1 0 1 0 1 1 0 1 12/28/1943
- 1364*/0x0AA5, 1944, 12, 16,/* 1 0 1 0 0 1 0 1 0 1 0 1 12/16/1944
- 1365*/0x0A4B, 1945, 12, 5,/* 1 1 0 1 0 0 1 0 0 1 0 1 12/5/1945
- 1366*/0x0497, 1946, 11, 24,/* 1 1 1 0 1 0 0 1 0 0 1 0 11/24/1946
- 1367*/0x0937, 1947, 11, 13,/* 1 1 1 0 1 1 0 0 1 0 0 1 11/13/1947
- 1368*/0x02B6, 1948, 11, 2,/* 0 1 1 0 1 1 0 1 0 1 0 0 11/2/1948
- 1369*/0x0575, 1949, 10, 22,/* 1 0 1 0 1 1 1 0 1 0 1 0 10/22/1949
- 1370*/0x0D6A, 1950, 10, 12,/* 0 1 0 1 0 1 1 0 1 0 1 1 10/12/1950
- 1371*/0x0D52, 1951, 10, 2,/* 0 1 0 0 1 0 1 0 1 0 1 1 10/2/1951
- 1372*/0x0A96, 1952, 9, 20,/* 0 1 1 0 1 0 0 1 0 1 0 1 9/20/1952
- 1373*/0x092D, 1953, 9, 9,/* 1 0 1 1 0 1 0 0 1 0 0 1 9/9/1953
- 1374*/0x025D, 1954, 8, 29,/* 1 0 1 1 1 0 1 0 0 1 0 0 8/29/1954
- 1375*/0x04DD, 1955, 8, 18,/* 1 0 1 1 1 0 1 1 0 0 1 0 8/18/1955
- 1376*/0x0ADA, 1956, 8, 7,/* 0 1 0 1 1 0 1 1 0 1 0 1 8/7/1956
- 1377*/0x05D4, 1957, 7, 28,/* 0 0 1 0 1 0 1 1 1 0 1 0 7/28/1957
- 1378*/0x0DA9, 1958, 7, 17,/* 1 0 0 1 0 1 0 1 1 0 1 1 7/17/1958
- 1379*/0x0D52, 1959, 7, 7,/* 0 1 0 0 1 0 1 0 1 0 1 1 7/7/1959
- 1380*/0x0AAA, 1960, 6, 25,/* 0 1 0 1 0 1 0 1 0 1 0 1 6/25/1960
- 1381*/0x04D6, 1961, 6, 14,/* 0 1 1 0 1 0 1 1 0 0 1 0 6/14/1961
- 1382*/0x09B6, 1962, 6, 3,/* 0 1 1 0 1 1 0 1 1 0 0 1 6/3/1962
- 1383*/0x0374, 1963, 5, 24,/* 0 0 1 0 1 1 1 0 1 1 0 0 5/24/1963
- 1384*/0x0769, 1964, 5, 12,/* 1 0 0 1 0 1 1 0 1 1 1 0 5/12/1964
- 1385*/0x0752, 1965, 5, 2,/* 0 1 0 0 1 0 1 0 1 1 1 0 5/2/1965
- 1386*/0x06A5, 1966, 4, 21,/* 1 0 1 0 0 1 0 1 0 1 1 0 4/21/1966
- 1387*/0x054B, 1967, 4, 10,/* 1 1 0 1 0 0 1 0 1 0 1 0 4/10/1967
- 1388*/0x0AAB, 1968, 3, 29,/* 1 1 0 1 0 1 0 1 0 1 0 1 3/29/1968
- 1389*/0x055A, 1969, 3, 19,/* 0 1 0 1 1 0 1 0 1 0 1 0 3/19/1969
- 1390*/0x0AD5, 1970, 3, 8,/* 1 0 1 0 1 0 1 1 0 1 0 1 3/8/1970
- 1391*/0x0DD2, 1971, 2, 26,/* 0 1 0 0 1 0 1 1 1 0 1 1 2/26/1971
- 1392*/0x0DA4, 1972, 2, 16,/* 0 0 1 0 0 1 0 1 1 0 1 1 2/16/1972
- 1393*/0x0D49, 1973, 2, 4,/* 1 0 0 1 0 0 1 0 1 0 1 1 2/4/1973
- 1394*/0x0A95, 1974, 1, 24,/* 1 0 1 0 1 0 0 1 0 1 0 1 1/24/1974
- 1395*/0x052D, 1975, 1, 13,/* 1 0 1 1 0 1 0 0 1 0 1 0 1/13/1975
- 1396*/0x0A5D, 1976, 1, 2,/* 1 0 1 1 1 0 1 0 0 1 0 1 1/2/1976
- 1397*/0x055A, 1976, 12, 22,/* 0 1 0 1 1 0 1 0 1 0 1 0 12/22/1976
- 1398*/0x0AD5, 1977, 12, 11,/* 1 0 1 0 1 0 1 1 0 1 0 1 12/11/1977
- 1399*/0x06AA, 1978, 12, 1,/* 0 1 0 1 0 1 0 1 0 1 1 0 12/1/1978
- 1400*/0x0695, 1979, 11, 20,/* 1 0 1 0 1 0 0 1 0 1 1 0 11/20/1979
- 1401*/0x052B, 1980, 11, 8,/* 1 1 0 1 0 1 0 0 1 0 1 0 11/8/1980
- 1402*/0x0A57, 1981, 10, 28,/* 1 1 1 0 1 0 1 0 0 1 0 1 10/28/1981
- 1403*/0x04AE, 1982, 10, 18,/* 0 1 1 1 0 1 0 1 0 0 1 0 10/18/1982
- 1404*/0x0976, 1983, 10, 7,/* 0 1 1 0 1 1 1 0 1 0 0 1 10/7/1983
- 1405*/0x056C, 1984, 9, 26,/* 0 0 1 1 0 1 1 0 1 0 1 0 9/26/1984
- 1406*/0x0B55, 1985, 9, 15,/* 1 0 1 0 1 0 1 0 1 1 0 1 9/15/1985
- 1407*/0x0AAA, 1986, 9, 5,/* 0 1 0 1 0 1 0 1 0 1 0 1 9/5/1986
- 1408*/0x0A55, 1987, 8, 25,/* 1 0 1 0 1 0 1 0 0 1 0 1 8/25/1987
- 1409*/0x04AD, 1988, 8, 13,/* 1 0 1 1 0 1 0 1 0 0 1 0 8/13/1988
- 1410*/0x095D, 1989, 8, 2,/* 1 0 1 1 1 0 1 0 1 0 0 1 8/2/1989
- 1411*/0x02DA, 1990, 7, 23,/* 0 1 0 1 1 0 1 1 0 1 0 0 7/23/1990
- 1412*/0x05D9, 1991, 7, 12,/* 1 0 0 1 1 0 1 1 1 0 1 0 7/12/1991
- 1413*/0x0DB2, 1992, 7, 1,/* 0 1 0 0 1 1 0 1 1 0 1 1 7/1/1992
- 1414*/0x0BA4, 1993, 6, 21,/* 0 0 1 0 0 1 0 1 1 1 0 1 6/21/1993
- 1415*/0x0B4A, 1994, 6, 10,/* 0 1 0 1 0 0 1 0 1 1 0 1 6/10/1994
- 1416*/0x0A55, 1995, 5, 30,/* 1 0 1 0 1 0 1 0 0 1 0 1 5/30/1995
- 1417*/0x02B5, 1996, 5, 18,/* 1 0 1 0 1 1 0 1 0 1 0 0 5/18/1996
- 1418*/0x0575, 1997, 5, 7,/* 1 0 1 0 1 1 1 0 1 0 1 0 5/7/1997
- 1419*/0x0B6A, 1998, 4, 27,/* 0 1 0 1 0 1 1 0 1 1 0 1 4/27/1998
- 1420*/0x0BD2, 1999, 4, 17,/* 0 1 0 0 1 0 1 1 1 1 0 1 4/17/1999
- 1421*/0x0BC4, 2000, 4, 6,/* 0 0 1 0 0 0 1 1 1 1 0 1 4/6/2000
- 1422*/0x0B89, 2001, 3, 26,/* 1 0 0 1 0 0 0 1 1 1 0 1 3/26/2001
- 1423*/0x0A95, 2002, 3, 15,/* 1 0 1 0 1 0 0 1 0 1 0 1 3/15/2002
- 1424*/0x052D, 2003, 3, 4,/* 1 0 1 1 0 1 0 0 1 0 1 0 3/4/2003
- 1425*/0x05AD, 2004, 2, 21,/* 1 0 1 1 0 1 0 1 1 0 1 0 2/21/2004
- 1426*/0x0B6A, 2005, 2, 10,/* 0 1 0 1 0 1 1 0 1 1 0 1 2/10/2005
- 1427*/0x06D4, 2006, 1, 31,/* 0 0 1 0 1 0 1 1 0 1 1 0 1/31/2006
- 1428*/0x0DC9, 2007, 1, 20,/* 1 0 0 1 0 0 1 1 1 0 1 1 1/20/2007
- 1429*/0x0D92, 2008, 1, 10,/* 0 1 0 0 1 0 0 1 1 0 1 1 1/10/2008
- 1430*/0x0AA6, 2008, 12, 29,/* 0 1 1 0 0 1 0 1 0 1 0 1 12/29/2008
- 1431*/0x0956, 2009, 12, 18,/* 0 1 1 0 1 0 1 0 1 0 0 1 12/18/2009
- 1432*/0x02AE, 2010, 12, 7,/* 0 1 1 1 0 1 0 1 0 1 0 0 12/7/2010
- 1433*/0x056D, 2011, 11, 26,/* 1 0 1 1 0 1 1 0 1 0 1 0 11/26/2011
- 1434*/0x036A, 2012, 11, 15,/* 0 1 0 1 0 1 1 0 1 1 0 0 11/15/2012
- 1435*/0x0B55, 2013, 11, 4,/* 1 0 1 0 1 0 1 0 1 1 0 1 11/4/2013
- 1436*/0x0AAA, 2014, 10, 25,/* 0 1 0 1 0 1 0 1 0 1 0 1 10/25/2014
- 1437*/0x094D, 2015, 10, 14,/* 1 0 1 1 0 0 1 0 1 0 0 1 10/14/2015
- 1438*/0x049D, 2016, 10, 2,/* 1 0 1 1 1 0 0 1 0 0 1 0 10/2/2016
- 1439*/0x095D, 2017, 9, 21,/* 1 0 1 1 1 0 1 0 1 0 0 1 9/21/2017
- 1440*/0x02BA, 2018, 9, 11,/* 0 1 0 1 1 1 0 1 0 1 0 0 9/11/2018
- 1441*/0x05B5, 2019, 8, 31,/* 1 0 1 0 1 1 0 1 1 0 1 0 8/31/2019
- 1442*/0x05AA, 2020, 8, 20,/* 0 1 0 1 0 1 0 1 1 0 1 0 8/20/2020
- 1443*/0x0D55, 2021, 8, 9,/* 1 0 1 0 1 0 1 0 1 0 1 1 8/9/2021
- 1444*/0x0A9A, 2022, 7, 30,/* 0 1 0 1 1 0 0 1 0 1 0 1 7/30/2022
- 1445*/0x092E, 2023, 7, 19,/* 0 1 1 1 0 1 0 0 1 0 0 1 7/19/2023
- 1446*/0x026E, 2024, 7, 7,/* 0 1 1 1 0 1 1 0 0 1 0 0 7/7/2024
- 1447*/0x055D, 2025, 6, 26,/* 1 0 1 1 1 0 1 0 1 0 1 0 6/26/2025
- 1448*/0x0ADA, 2026, 6, 16,/* 0 1 0 1 1 0 1 1 0 1 0 1 6/16/2026
- 1449*/0x06D4, 2027, 6, 6,/* 0 0 1 0 1 0 1 1 0 1 1 0 6/6/2027
- 1450*/0x06A5, 2028, 5, 25,/* 1 0 1 0 0 1 0 1 0 1 1 0 5/25/2028
- 1451*/0x054B, 2029, 5, 14,/* 1 1 0 1 0 0 1 0 1 0 1 0 5/14/2029
- 1452*/0x0A97, 2030, 5, 3,/* 1 1 1 0 1 0 0 1 0 1 0 1 5/3/2030
- 1453*/0x054E, 2031, 4, 23,/* 0 1 1 1 0 0 1 0 1 0 1 0 4/23/2031
- 1454*/0x0AAE, 2032, 4, 11,/* 0 1 1 1 0 1 0 1 0 1 0 1 4/11/2032
- 1455*/0x05AC, 2033, 4, 1,/* 0 0 1 1 0 1 0 1 1 0 1 0 4/1/2033
- 1456*/0x0BA9, 2034, 3, 21,/* 1 0 0 1 0 1 0 1 1 1 0 1 3/21/2034
- 1457*/0x0D92, 2035, 3, 11,/* 0 1 0 0 1 0 0 1 1 0 1 1 3/11/2035
- 1458*/0x0B25, 2036, 2, 28,/* 1 0 1 0 0 1 0 0 1 1 0 1 2/28/2036
- 1459*/0x064B, 2037, 2, 16,/* 1 1 0 1 0 0 1 0 0 1 1 0 2/16/2037
- 1460*/0x0CAB, 2038, 2, 5,/* 1 1 0 1 0 1 0 1 0 0 1 1 2/5/2038
- 1461*/0x055A, 2039, 1, 26,/* 0 1 0 1 1 0 1 0 1 0 1 0 1/26/2039
- 1462*/0x0B55, 2040, 1, 15,/* 1 0 1 0 1 0 1 0 1 1 0 1 1/15/2040
- 1463*/0x06D2, 2041, 1, 4,/* 0 1 0 0 1 0 1 1 0 1 1 0 1/4/2041
- 1464*/0x0EA5, 2041, 12, 24,/* 1 0 1 0 0 1 0 1 0 1 1 1 12/24/2041
- 1465*/0x0E4A, 2042, 12, 14,/* 0 1 0 1 0 0 1 0 0 1 1 1 12/14/2042
- 1466*/0x0A95, 2043, 12, 3,/* 1 0 1 0 1 0 0 1 0 1 0 1 12/3/2043
- 1467*/0x052D, 2044, 11, 21,/* 1 0 1 1 0 1 0 0 1 0 1 0 11/21/2044
- 1468*/0x0AAD, 2045, 11, 10,/* 1 0 1 1 0 1 0 1 0 1 0 1 11/10/2045
- 1469*/0x036C, 2046, 10, 31,/* 0 0 1 1 0 1 1 0 1 1 0 0 10/31/2046
- 1470*/0x0759, 2047, 10, 20,/* 1 0 0 1 1 0 1 0 1 1 1 0 10/20/2047
- 1471*/0x06D2, 2048, 10, 9,/* 0 1 0 0 1 0 1 1 0 1 1 0 10/9/2048
- 1472*/0x0695, 2049, 9, 28,/* 1 0 1 0 1 0 0 1 0 1 1 0 9/28/2049
- 1473*/0x052D, 2050, 9, 17,/* 1 0 1 1 0 1 0 0 1 0 1 0 9/17/2050
- 1474*/0x0A5B, 2051, 9, 6,/* 1 1 0 1 1 0 1 0 0 1 0 1 9/6/2051
- 1475*/0x04BA, 2052, 8, 26,/* 0 1 0 1 1 1 0 1 0 0 1 0 8/26/2052
- 1476*/0x09BA, 2053, 8, 15,/* 0 1 0 1 1 1 0 1 1 0 0 1 8/15/2053
- 1477*/0x03B4, 2054, 8, 5,/* 0 0 1 0 1 1 0 1 1 1 0 0 8/5/2054
- 1478*/0x0B69, 2055, 7, 25,/* 1 0 0 1 0 1 1 0 1 1 0 1 7/25/2055
- 1479*/0x0B52, 2056, 7, 14,/* 0 1 0 0 1 0 1 0 1 1 0 1 7/14/2056
- 1480*/0x0AA6, 2057, 7, 3,/* 0 1 1 0 0 1 0 1 0 1 0 1 7/3/2057
- 1481*/0x04B6, 2058, 6, 22,/* 0 1 1 0 1 1 0 1 0 0 1 0 6/22/2058
- 1482*/0x096D, 2059, 6, 11,/* 1 0 1 1 0 1 1 0 1 0 0 1 6/11/2059
- 1483*/0x02EC, 2060, 5, 31,/* 0 0 1 1 0 1 1 1 0 1 0 0 5/31/2060
- 1484*/0x06D9, 2061, 5, 20,/* 1 0 0 1 1 0 1 1 0 1 1 0 5/20/2061
- 1485*/0x0EB2, 2062, 5, 10,/* 0 1 0 0 1 1 0 1 0 1 1 1 5/10/2062
- 1486*/0x0D54, 2063, 4, 30,/* 0 0 1 0 1 0 1 0 1 0 1 1 4/30/2063
- 1487*/0x0D2A, 2064, 4, 18,/* 0 1 0 1 0 1 0 0 1 0 1 1 4/18/2064
- 1488*/0x0A56, 2065, 4, 7,/* 0 1 1 0 1 0 1 0 0 1 0 1 4/7/2065
- 1489*/0x04AE, 2066, 3, 27,/* 0 1 1 1 0 1 0 1 0 0 1 0 3/27/2066
- 1490*/0x096D, 2067, 3, 16,/* 1 0 1 1 0 1 1 0 1 0 0 1 3/16/2067
- 1491*/0x0D6A, 2068, 3, 5,/* 0 1 0 1 0 1 1 0 1 0 1 1 3/5/2068
- 1492*/0x0B54, 2069, 2, 23,/* 0 0 1 0 1 0 1 0 1 1 0 1 2/23/2069
- 1493*/0x0B29, 2070, 2, 12,/* 1 0 0 1 0 1 0 0 1 1 0 1 2/12/2070
- 1494*/0x0A93, 2071, 2, 1,/* 1 1 0 0 1 0 0 1 0 1 0 1 2/1/2071
- 1495*/0x052B, 2072, 1, 21,/* 1 1 0 1 0 1 0 0 1 0 1 0 1/21/2072
- 1496*/0x0A57, 2073, 1, 9,/* 1 1 1 0 1 0 1 0 0 1 0 1 1/9/2073
- 1497*/0x0536, 2073, 12, 30,/* 0 1 1 0 1 1 0 0 1 0 1 0 12/30/2073
- 1498*/0x0AB5, 2074, 12, 19,/* 1 0 1 0 1 1 0 1 0 1 0 1 12/19/2074
- 1499*/0x06AA, 2075, 12, 9,/* 0 1 0 1 0 1 0 1 0 1 1 0 12/9/2075
- 1500*/0x0E93, 2076, 11, 27,/* 1 1 0 0 1 0 0 1 0 1 1 1 11/27/2076
- 1501*/ 0, 2077, 11, 17,/* 0 0 0 0 0 0 0 0 0 0 0 0 11/17/2077
- */ };
- // Direct inline initialization of DateMapping array would produce a lot of code bloat.
-
- // We take advantage of C# compiler compiles inline initialization of primitive type array into very compact code.
- // So we start with raw data stored in primitive type array, and initialize the DateMapping out of it
-
- DateMapping[] mapping = new DateMapping[rawData.Length / 4];
- for (int i = 0; i < mapping.Length; i++)
- mapping[i] = new DateMapping(rawData[i * 4], rawData[i * 4 + 1], rawData[i * 4 + 2], rawData[i * 4 + 3]);
- return mapping;
- }
-
- public const int UmAlQuraEra = 1;
-
- internal const int DateCycle = 30;
- internal const int DatePartYear = 0;
- internal const int DatePartDayOfYear = 1;
- internal const int DatePartMonth = 2;
- internal const int DatePartDay = 3;
-
-
- // This is the minimal Gregorian date that we support in the UmAlQuraCalendar.
- internal static DateTime minDate = new DateTime(1900, 4, 30);
- internal static DateTime maxDate = new DateTime((new DateTime(2077, 11, 16, 23, 59, 59, 999)).Ticks + 9999);
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (minDate);
- }
- }
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (maxDate);
- }
- }
-
- public override CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.LunarCalendar;
- }
- }
-
- public UmAlQuraCalendar()
- {
- }
-
- internal override CalendarId BaseCalendarID
- {
- get
- {
- return (CalendarId.HIJRI);
- }
- }
-
- internal override CalendarId ID
- {
- get
- {
- return (CalendarId.UMALQURA);
- }
- }
-
- protected override int DaysInYearBeforeMinSupportedYear
- {
- get
- {
- // HijriCalendar has same number of days as UmAlQuraCalendar for any given year
- // HijriCalendar says year 1317 has 355 days.
- return 355;
- }
- }
-
- /*==========================ConvertHijriToGregorian==========================
- ** Purpose: convert Hdate(year,month,day) to Gdate(year,month,day)
- ** Arguments:
- ** Input/Ouput: Hijrah date: year:yh, month:mh, day:dh
- ** Output: Gregorian date: year:yg, month:mg, day:dg , day of week:dayweek
- ** and returns flag found:1 not found:0
- =========================ConvertHijriToGregorian============================*/
- private static void ConvertHijriToGregorian(int HijriYear, int HijriMonth, int HijriDay, ref int yg, ref int mg, ref int dg)
- {
- Debug.Assert((HijriYear >= MinCalendarYear) && (HijriYear <= MaxCalendarYear), "Hijri year is out of range.");
- Debug.Assert(HijriMonth >= 1, "Hijri month is out of range.");
- Debug.Assert(HijriDay >= 1, "Hijri day is out of range.");
- int index, b, nDays = HijriDay - 1;
- DateTime dt;
-
-
- index = HijriYear - MinCalendarYear;
- dt = s_hijriYearInfo[index].GregorianDate;
-
-
- b = s_hijriYearInfo[index].HijriMonthsLengthFlags;
-
- for (int m = 1; m < HijriMonth; m++)
- {
- nDays = nDays + 29 + (b & 1); /* Add the months lengths before mh */
- b = b >> 1;
- }
-
- dt = dt.AddDays(nDays);
- yg = dt.Year;
- mg = dt.Month;
- dg = dt.Day;
- }
-
- /*=================================GetAbsoluteDateUmAlQura==========================
- **Action: Gets the Absolute date for the given UmAlQura date. The absolute date means
- ** the number of days from January 1st, 1 A.D.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
- private static long GetAbsoluteDateUmAlQura(int year, int month, int day)
- {
- //Caller should check the validaty of year, month and day.
-
- int yg = 0, mg = 0, dg = 0;
- ConvertHijriToGregorian(year, month, day, ref yg, ref mg, ref dg);
- return GregorianCalendar.GetAbsoluteDate(yg, mg, dg);
- }
-
- internal static void CheckTicksRange(long ticks)
- {
- if (ticks < minDate.Ticks || ticks > maxDate.Ticks)
- {
- throw new ArgumentOutOfRangeException(
- "time",
- String.Format(
- CultureInfo.InvariantCulture,
- SR.ArgumentOutOfRange_CalendarRange,
- minDate,
- maxDate));
- }
- }
-
- internal static void CheckEraRange(int era)
- {
- if (era != CurrentEra && era != UmAlQuraEra)
- {
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
- }
- }
-
- internal static void CheckYearRange(int year, int era)
- {
- CheckEraRange(era);
- if (year < MinCalendarYear || year > MaxCalendarYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- MinCalendarYear,
- MaxCalendarYear));
- }
- }
-
- internal static void CheckYearMonthRange(int year, int month, int era)
- {
- CheckYearRange(year, era);
- if (month < 1 || month > 12)
- {
- throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
- }
- }
-
- /*========================ConvertGregorianToHijri============================
- ** Purpose: convert DateTime to Hdate(year,month,day)
- ** Arguments:
- ** Input: DateTime
- ** Output: Hijrah date: year:yh, month:mh, day:dh
- ============================================================================*/
- private static void ConvertGregorianToHijri(DateTime time, ref int HijriYear, ref int HijriMonth, ref int HijriDay)
- {
- int index, b, DaysPerThisMonth;
- double nDays;
- TimeSpan ts;
- int yh1 = 0, mh1 = 0, dh1 = 0;
-
- Debug.Assert((time.Ticks >= minDate.Ticks) && (time.Ticks <= maxDate.Ticks), "Gregorian date is out of range.");
-
- // Find the index where we should start our search by quessing the Hijri year that we will be in HijriYearInfo.
- // A Hijri year is 354 or 355 days. Use 355 days so that we will search from a lower index.
-
- index = (int)((time.Ticks - minDate.Ticks) / Calendar.TicksPerDay) / 355;
- do
- {
- } while (time.CompareTo(s_hijriYearInfo[++index].GregorianDate) > 0); //while greater
-
- if (time.CompareTo(s_hijriYearInfo[index].GregorianDate) != 0)
- {
- index--;
- }
-
- ts = time.Subtract(s_hijriYearInfo[index].GregorianDate);
- yh1 = index + MinCalendarYear;
-
- mh1 = 1;
- dh1 = 1;
- nDays = ts.TotalDays;
- b = s_hijriYearInfo[index].HijriMonthsLengthFlags;
- DaysPerThisMonth = 29 + (b & 1);
-
- while (nDays >= DaysPerThisMonth)
- {
- nDays -= DaysPerThisMonth;
- b = b >> 1;
- DaysPerThisMonth = 29 + (b & 1);
- mh1++;
- }
- dh1 += (int)nDays;
-
- HijriDay = dh1;
- HijriMonth = mh1;
- HijriYear = yh1;
- }
-
- /*=================================GetDatePart==========================
- **Action: Returns a given date part of this <i>DateTime</i>. This method is used
- ** to compute the year, day-of-year, month, or day part.
- **Returns:
- **Arguments:
- **Exceptions: ArgumentException if part is incorrect.
- **Notes:
- ** First, we get the absolute date (the number of days from January 1st, 1 A.C) for the given ticks.
- ** Use the formula (((AbsoluteDate - 226894) * 33) / (33 * 365 + 8)) + 1, we can a rough value for the UmAlQura year.
- ** In order to get the exact UmAlQura year, we compare the exact absolute date for UmAlQuraYear and (UmAlQuraYear + 1).
- ** From here, we can get the correct UmAlQura year.
- ============================================================================*/
-
- internal virtual int GetDatePart(DateTime time, int part)
- {
- int UmAlQuraYear = 0; // UmAlQura year
- int UmAlQuraMonth = 0; // UmAlQura month
- int UmAlQuraDay = 0; // UmAlQura day
- long ticks = time.Ticks;
- CheckTicksRange(ticks);
-
- ConvertGregorianToHijri(time, ref UmAlQuraYear, ref UmAlQuraMonth, ref UmAlQuraDay);
-
- if (part == DatePartYear)
- return (UmAlQuraYear);
-
- if (part == DatePartMonth)
- return (UmAlQuraMonth);
-
- if (part == DatePartDay)
- return (UmAlQuraDay);
-
- if (part == DatePartDayOfYear)
- return (int)(GetAbsoluteDateUmAlQura(UmAlQuraYear, UmAlQuraMonth, UmAlQuraDay) - GetAbsoluteDateUmAlQura(UmAlQuraYear, 1, 1) + 1);
-
- // Incorrect part value.
- throw new InvalidOperationException(SR.InvalidOperation_DateTimeParsing);
- }
-
- // Returns the DateTime resulting from adding the given number of
- // months to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year and month parts of the specified DateTime by
- // value months, and, if required, adjusting the day part of the
- // resulting date downwards to the last day of the resulting month in the
- // resulting year. The time-of-day part of the result is the same as the
- // time-of-day part of the specified DateTime.
- //
- // In more precise terms, considering the specified DateTime to be of the
- // form y / m / d + t, where y is the
- // year, m is the month, d is the day, and t is the
- // time-of-day, the result is y1 / m1 / d1 + t,
- // where y1 and m1 are computed by adding value months
- // to y and m, and d1 is the largest value less than
- // or equal to d that denotes a valid day in month m1 of year
- // y1.
- //
-
-
- public override DateTime AddMonths(DateTime time, int months)
- {
- if (months < -120000 || months > 120000)
- {
- throw new ArgumentOutOfRangeException(
- nameof(months),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- -120000,
- 120000));
- }
- Contract.EndContractBlock();
- // Get the date in UmAlQura calendar.
- int y = GetDatePart(time, DatePartYear);
- int m = GetDatePart(time, DatePartMonth);
- int d = GetDatePart(time, DatePartDay);
- int i = m - 1 + months;
-
- if (i >= 0)
- {
- m = i % 12 + 1;
- y = y + i / 12;
- }
- else
- {
- m = 12 + (i + 1) % 12;
- y = y + (i - 11) / 12;
- }
-
- if (d > 29)
- {
- int days = GetDaysInMonth(y, m);
- if (d > days)
- {
- d = days;
- }
- }
- CheckYearRange(y, UmAlQuraEra);
- DateTime dt = new DateTime(GetAbsoluteDateUmAlQura(y, m, d) * TicksPerDay + time.Ticks % TicksPerDay);
- Calendar.CheckAddResult(dt.Ticks, MinSupportedDateTime, MaxSupportedDateTime);
- return (dt);
- }
-
- // Returns the DateTime resulting from adding the given number of
- // years to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year part of the specified DateTime by value
- // years. If the month and day of the specified DateTime is 2/29, and if the
- // resulting year is not a leap year, the month and day of the resulting
- // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
- // parts of the result are the same as those of the specified DateTime.
- //
-
-
- public override DateTime AddYears(DateTime time, int years)
- {
- return (AddMonths(time, years * 12));
- }
-
- // Returns the day-of-month part of the specified DateTime. The returned
- // value is an integer between 1 and 31.
- //
-
-
- public override int GetDayOfMonth(DateTime time)
- {
- return (GetDatePart(time, DatePartDay));
- }
-
- // Returns the day-of-week part of the specified DateTime. The returned value
- // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
- // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
- // Thursday, 5 indicates Friday, and 6 indicates Saturday.
- //
-
-
- public override DayOfWeek GetDayOfWeek(DateTime time)
- {
- return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
- }
-
- // Returns the day-of-year part of the specified DateTime. The returned value
- // is an integer between 1 and 354 or 355.
- //
-
-
- public override int GetDayOfYear(DateTime time)
- {
- return (GetDatePart(time, DatePartDayOfYear));
- }
-
- /*
- internal bool CouldBeLeapYear(int year)
- {
- return ((((year * 11) + 14) % 30) < 11);
- }
- */
-
- // Returns the number of days in the month given by the year and
- // month arguments.
- //
-
-
- public override int GetDaysInMonth(int year, int month, int era)
- {
- CheckYearMonthRange(year, month, era);
-
- if ((s_hijriYearInfo[year - MinCalendarYear].HijriMonthsLengthFlags & (1 << month - 1)) == 0)
- return 29;
- else
- return 30;
- }
-
- internal static int RealGetDaysInYear(int year)
- {
- int days = 0, b;
-
- Debug.Assert((year >= MinCalendarYear) && (year <= MaxCalendarYear), "Hijri year is out of range.");
-
- b = s_hijriYearInfo[year - MinCalendarYear].HijriMonthsLengthFlags;
-
- for (int m = 1; m <= 12; m++)
- {
- days = days + 29 + (b & 1); /* Add the months lengths before mh */
- b = b >> 1;
- }
- Debug.Assert((days == 354) || (days == 355), "Hijri year has to be 354 or 355 days.");
- return days;
- }
-
- // Returns the number of days in the year given by the year argument for the current era.
- //
-
-
- public override int GetDaysInYear(int year, int era)
- {
- CheckYearRange(year, era);
- return (RealGetDaysInYear(year));
- }
-
- // Returns the era for the specified DateTime value.
-
-
- public override int GetEra(DateTime time)
- {
- CheckTicksRange(time.Ticks);
- return (UmAlQuraEra);
- }
-
-
-
- public override int[] Eras
- {
- get
- {
- return (new int[] { UmAlQuraEra });
- }
- }
-
- // Returns the month part of the specified DateTime. The returned value is an
- // integer between 1 and 12.
- //
-
-
- public override int GetMonth(DateTime time)
- {
- return (GetDatePart(time, DatePartMonth));
- }
-
- // Returns the number of months in the specified year and era.
-
-
- public override int GetMonthsInYear(int year, int era)
- {
- CheckYearRange(year, era);
- return (12);
- }
-
- // Returns the year part of the specified DateTime. The returned value is an
- // integer between MinCalendarYear and MaxCalendarYear.
- //
-
-
- public override int GetYear(DateTime time)
- {
- return (GetDatePart(time, DatePartYear));
- }
-
- // Checks whether a given day in the specified era is a leap day. This method returns true if
- // the date is a leap day, or false if not.
- //
-
-
- public override bool IsLeapDay(int year, int month, int day, int era)
- {
- if (day >= 1 && day <= 29)
- {
- CheckYearMonthRange(year, month, era);
- return (false);
- }
-
- // The year/month/era value checking is done in GetDaysInMonth().
- int daysInMonth = GetDaysInMonth(year, month, era);
- if (day < 1 || day > daysInMonth)
- {
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Day,
- daysInMonth,
- month));
- }
- return (false);
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
-
- public override int GetLeapMonth(int year, int era)
- {
- CheckYearRange(year, era);
- return (0);
- }
-
- // Checks whether a given month in the specified era is a leap month. This method returns true if
- // month is a leap month, or false if not.
- //
-
-
- public override bool IsLeapMonth(int year, int month, int era)
- {
- CheckYearMonthRange(year, month, era);
- return (false);
- }
-
- // Checks whether a given year in the specified era is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
-
-
- public override bool IsLeapYear(int year, int era)
- {
- CheckYearRange(year, era);
- if (RealGetDaysInYear(year) == 355)
- return true;
- else
- return false;
- }
-
- // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
- //
-
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
- {
- if (day >= 1 && day <= 29)
- {
- CheckYearMonthRange(year, month, era);
- goto DayInRang;
- }
-
- // The year/month/era value checking is done in GetDaysInMonth().
- int daysInMonth = GetDaysInMonth(year, month, era);
-
- if (day < 1 || day > daysInMonth)
- {
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Day,
- daysInMonth,
- month));
- }
- DayInRang:
- long lDate = GetAbsoluteDateUmAlQura(year, month, day);
-
- if (lDate >= 0)
- {
- return (new DateTime(lDate * GregorianCalendar.TicksPerDay + TimeToTicks(hour, minute, second, millisecond)));
- }
- else
- {
- throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
- }
- }
-
- private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 1451;
-
-
-
- public override int TwoDigitYearMax
- {
- get
- {
- if (twoDigitYearMax == -1)
- {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
- }
- return (twoDigitYearMax);
- }
-
- set
- {
- if (value != 99 && (value < MinCalendarYear || value > MaxCalendarYear))
- {
- throw new ArgumentOutOfRangeException(
- nameof(value),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- MinCalendarYear,
- MaxCalendarYear));
- }
- Contract.EndContractBlock();
- VerifyWritable();
- // We allow year 99 to be set so that one can make ToFourDigitYearMax a no-op by setting TwoDigitYearMax to 99.
- twoDigitYearMax = value;
- }
- }
-
-
-
- public override int ToFourDigitYear(int year)
- {
- if (year < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(year),
- SR.ArgumentOutOfRange_NeedNonNegNum);
- }
- Contract.EndContractBlock();
-
- if (year < 100)
- {
- return (base.ToFourDigitYear(year));
- }
-
- if ((year < MinCalendarYear) || (year > MaxCalendarYear))
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- MinCalendarYear,
- MaxCalendarYear));
- }
- return (year);
- }
- }
-}
-
diff --git a/src/mscorlib/corefx/System/Globalization/UnicodeCategory.cs b/src/mscorlib/corefx/System/Globalization/UnicodeCategory.cs
deleted file mode 100644
index 1c5e6bca56..0000000000
--- a/src/mscorlib/corefx/System/Globalization/UnicodeCategory.cs
+++ /dev/null
@@ -1,70 +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.
-
-namespace System.Globalization
-{
- [Serializable]
- public enum UnicodeCategory
- {
- UppercaseLetter = 0,
-
- LowercaseLetter = 1,
-
- TitlecaseLetter = 2,
-
- ModifierLetter = 3,
-
- OtherLetter = 4,
-
- NonSpacingMark = 5,
-
- SpacingCombiningMark = 6,
-
- EnclosingMark = 7,
-
- DecimalDigitNumber = 8,
-
- LetterNumber = 9,
-
- OtherNumber = 10,
-
- SpaceSeparator = 11,
-
- LineSeparator = 12,
-
- ParagraphSeparator = 13,
-
- Control = 14,
-
- Format = 15,
-
- Surrogate = 16,
-
- PrivateUse = 17,
-
- ConnectorPunctuation = 18,
-
- DashPunctuation = 19,
-
- OpenPunctuation = 20,
-
- ClosePunctuation = 21,
-
- InitialQuotePunctuation = 22,
-
- FinalQuotePunctuation = 23,
-
- OtherPunctuation = 24,
-
- MathSymbol = 25,
-
- CurrencySymbol = 26,
-
- ModifierSymbol = 27,
-
- OtherSymbol = 28,
-
- OtherNotAssigned = 29,
- }
-}
diff --git a/src/mscorlib/corefx/System/IO/Error.cs b/src/mscorlib/corefx/System/IO/Error.cs
deleted file mode 100644
index c8434ffad8..0000000000
--- a/src/mscorlib/corefx/System/IO/Error.cs
+++ /dev/null
@@ -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.
-
-using System;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Globalization;
-using System.Diagnostics.Contracts;
-
-namespace System.IO
-{
- /// <summary>
- /// Provides centralized methods for creating exceptions for System.IO.FileSystem.
- /// </summary>
- [Pure]
- internal static class Error
- {
- internal static Exception GetEndOfFile()
- {
- return new EndOfStreamException(SR.IO_EOF_ReadBeyondEOF);
- }
-
- internal static Exception GetFileNotOpen()
- {
- return new ObjectDisposedException(null, SR.ObjectDisposed_FileClosed);
- }
-
- internal static Exception GetReadNotSupported()
- {
- return new NotSupportedException(SR.NotSupported_UnreadableStream);
- }
-
- internal static Exception GetSeekNotSupported()
- {
- return new NotSupportedException(SR.NotSupported_UnseekableStream);
- }
-
- internal static Exception GetWriteNotSupported()
- {
- return new NotSupportedException(SR.NotSupported_UnwritableStream);
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/IO/FileStream.Unix.cs b/src/mscorlib/corefx/System/IO/FileStream.Unix.cs
deleted file mode 100644
index f83fc84259..0000000000
--- a/src/mscorlib/corefx/System/IO/FileStream.Unix.cs
+++ /dev/null
@@ -1,934 +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 Microsoft.Win32.SafeHandles;
-using System.Diagnostics;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace System.IO
-{
- /// <summary>Provides an implementation of a file stream for Unix files.</summary>
- public partial class FileStream : Stream
- {
- /// <summary>File mode.</summary>
- private FileMode _mode;
-
- /// <summary>Advanced options requested when opening the file.</summary>
- private FileOptions _options;
-
- /// <summary>If the file was opened with FileMode.Append, the length of the file when opened; otherwise, -1.</summary>
- private long _appendStart = -1;
-
- /// <summary>
- /// Extra state used by the file stream when _useAsyncIO is true. This includes
- /// the semaphore used to serialize all operation, the buffer/offset/count provided by the
- /// caller for ReadAsync/WriteAsync operations, and the last successful task returned
- /// synchronously from ReadAsync which can be reused if the count matches the next request.
- /// Only initialized when <see cref="_useAsyncIO"/> is true.
- /// </summary>
- private AsyncState _asyncState;
-
- /// <summary>Lazily-initialized value for whether the file supports seeking.</summary>
- private bool? _canSeek;
-
- private SafeFileHandle OpenHandle(FileMode mode, FileShare share, FileOptions options)
- {
- // FileStream performs most of the general argument validation. We can assume here that the arguments
- // are all checked and consistent (e.g. non-null-or-empty path; valid enums in mode, access, share, and options; etc.)
- // Store the arguments
- _mode = mode;
- _options = options;
-
- if (_useAsyncIO)
- _asyncState = new AsyncState();
-
- // Translate the arguments into arguments for an open call.
- Interop.Sys.OpenFlags openFlags = PreOpenConfigurationFromOptions(mode, _access, options); // FileShare currently ignored
-
- // If the file gets created a new, we'll select the permissions for it. Most Unix utilities by default use 666 (read and
- // write for all), so we do the same (even though this doesn't match Windows, where by default it's possible to write out
- // a file and then execute it). No matter what we choose, it'll be subject to the umask applied by the system, such that the
- // actual permissions will typically be less than what we select here.
- const Interop.Sys.Permissions OpenPermissions =
- Interop.Sys.Permissions.S_IRUSR | Interop.Sys.Permissions.S_IWUSR |
- Interop.Sys.Permissions.S_IRGRP | Interop.Sys.Permissions.S_IWGRP |
- Interop.Sys.Permissions.S_IROTH | Interop.Sys.Permissions.S_IWOTH;
-
- // Open the file and store the safe handle.
- return SafeFileHandle.Open(_path, openFlags, (int)OpenPermissions);
- }
-
- /// <summary>Initializes a stream for reading or writing a Unix file.</summary>
- /// <param name="mode">How the file should be opened.</param>
- /// <param name="share">What other access to the file should be allowed. This is currently ignored.</param>
- private void Init(FileMode mode, FileShare share)
- {
- _fileHandle.IsAsync = _useAsyncIO;
-
- // Lock the file if requested via FileShare. This is only advisory locking. FileShare.None implies an exclusive
- // lock on the file and all other modes use a shared lock. While this is not as granular as Windows, not mandatory,
- // and not atomic with file opening, it's better than nothing.
- Interop.Sys.LockOperations lockOperation = (share == FileShare.None) ? Interop.Sys.LockOperations.LOCK_EX : Interop.Sys.LockOperations.LOCK_SH;
- if (Interop.Sys.FLock(_fileHandle, lockOperation | Interop.Sys.LockOperations.LOCK_NB) < 0)
- {
- // The only error we care about is EWOULDBLOCK, which indicates that the file is currently locked by someone
- // else and we would block trying to access it. Other errors, such as ENOTSUP (locking isn't supported) or
- // EACCES (the file system doesn't allow us to lock), will only hamper FileStream's usage without providing value,
- // given again that this is only advisory / best-effort.
- Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo();
- if (errorInfo.Error == Interop.Error.EWOULDBLOCK)
- {
- throw Interop.GetExceptionForIoErrno(errorInfo, _path, isDirectory: false);
- }
- }
-
- // These provide hints around how the file will be accessed. Specifying both RandomAccess
- // and Sequential together doesn't make sense as they are two competing options on the same spectrum,
- // so if both are specified, we prefer RandomAccess (behavior on Windows is unspecified if both are provided).
- Interop.Sys.FileAdvice fadv =
- (_options & FileOptions.RandomAccess) != 0 ? Interop.Sys.FileAdvice.POSIX_FADV_RANDOM :
- (_options & FileOptions.SequentialScan) != 0 ? Interop.Sys.FileAdvice.POSIX_FADV_SEQUENTIAL :
- 0;
- if (fadv != 0)
- {
- CheckFileCall(Interop.Sys.PosixFAdvise(_fileHandle, 0, 0, fadv),
- ignoreNotSupported: true); // just a hint.
- }
-
- // Jump to the end of the file if opened as Append.
- if (_mode == FileMode.Append)
- {
- _appendStart = SeekCore(0, SeekOrigin.End);
- }
- }
-
- /// <summary>Initializes a stream from an already open file handle (file descriptor).</summary>
- /// <param name="handle">The handle to the file.</param>
- /// <param name="bufferSize">The size of the buffer to use when buffering.</param>
- /// <param name="useAsyncIO">Whether access to the stream is performed asynchronously.</param>
- private void InitFromHandle(SafeFileHandle handle)
- {
- if (_useAsyncIO)
- _asyncState = new AsyncState();
-
- if (CanSeekCore) // use non-virtual CanSeekCore rather than CanSeek to avoid making virtual call during ctor
- SeekCore(0, SeekOrigin.Current);
- }
-
- /// <summary>Translates the FileMode, FileAccess, and FileOptions values into flags to be passed when opening the file.</summary>
- /// <param name="mode">The FileMode provided to the stream's constructor.</param>
- /// <param name="access">The FileAccess provided to the stream's constructor</param>
- /// <param name="options">The FileOptions provided to the stream's constructor</param>
- /// <returns>The flags value to be passed to the open system call.</returns>
- private static Interop.Sys.OpenFlags PreOpenConfigurationFromOptions(FileMode mode, FileAccess access, FileOptions options)
- {
- // Translate FileMode. Most of the values map cleanly to one or more options for open.
- Interop.Sys.OpenFlags flags = default(Interop.Sys.OpenFlags);
- switch (mode)
- {
- default:
- case FileMode.Open: // Open maps to the default behavior for open(...). No flags needed.
- break;
-
- case FileMode.Append: // Append is the same as OpenOrCreate, except that we'll also separately jump to the end later
- case FileMode.OpenOrCreate:
- flags |= Interop.Sys.OpenFlags.O_CREAT;
- break;
-
- case FileMode.Create:
- flags |= (Interop.Sys.OpenFlags.O_CREAT | Interop.Sys.OpenFlags.O_TRUNC);
- break;
-
- case FileMode.CreateNew:
- flags |= (Interop.Sys.OpenFlags.O_CREAT | Interop.Sys.OpenFlags.O_EXCL);
- break;
-
- case FileMode.Truncate:
- flags |= Interop.Sys.OpenFlags.O_TRUNC;
- break;
- }
-
- // Translate FileAccess. All possible values map cleanly to corresponding values for open.
- switch (access)
- {
- case FileAccess.Read:
- flags |= Interop.Sys.OpenFlags.O_RDONLY;
- break;
-
- case FileAccess.ReadWrite:
- flags |= Interop.Sys.OpenFlags.O_RDWR;
- break;
-
- case FileAccess.Write:
- flags |= Interop.Sys.OpenFlags.O_WRONLY;
- break;
- }
-
- // Translate some FileOptions; some just aren't supported, and others will be handled after calling open.
- // - Asynchronous: Handled in ctor, setting _useAsync and SafeFileHandle.IsAsync to true
- // - DeleteOnClose: Doesn't have a Unix equivalent, but we approximate it in Dispose
- // - Encrypted: No equivalent on Unix and is ignored
- // - RandomAccess: Implemented after open if posix_fadvise is available
- // - SequentialScan: Implemented after open if posix_fadvise is available
- // - WriteThrough: Handled here
- if ((options & FileOptions.WriteThrough) != 0)
- {
- flags |= Interop.Sys.OpenFlags.O_SYNC;
- }
-
- return flags;
- }
-
- /// <summary>Gets a value indicating whether the current stream supports seeking.</summary>
- public override bool CanSeek => CanSeekCore;
-
- /// <summary>Gets a value indicating whether the current stream supports seeking.</summary>
- /// <remarks>Separated out of CanSeek to enable making non-virtual call to this logic.</remarks>
- private bool CanSeekCore
- {
- get
- {
- if (_fileHandle.IsClosed)
- {
- return false;
- }
-
- if (!_canSeek.HasValue)
- {
- // Lazily-initialize whether we're able to seek, tested by seeking to our current location.
- _canSeek = Interop.Sys.LSeek(_fileHandle, 0, Interop.Sys.SeekWhence.SEEK_CUR) >= 0;
- }
- return _canSeek.Value;
- }
- }
-
- private long GetLengthInternal()
- {
- // Get the length of the file as reported by the OS
- Interop.Sys.FileStatus status;
- CheckFileCall(Interop.Sys.FStat(_fileHandle, out status));
- long length = status.Size;
-
- // But we may have buffered some data to be written that puts our length
- // beyond what the OS is aware of. Update accordingly.
- if (_writePos > 0 && _filePosition + _writePos > length)
- {
- length = _writePos + _filePosition;
- }
-
- return length;
- }
-
- /// <summary>Releases the unmanaged resources used by the stream.</summary>
- /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
- protected override void Dispose(bool disposing)
- {
- try
- {
- if (_fileHandle != null && !_fileHandle.IsClosed)
- {
- // Flush any remaining data in the file
- FlushWriteBuffer();
-
- // If DeleteOnClose was requested when constructed, delete the file now.
- // (Unix doesn't directly support DeleteOnClose, so we mimic it here.)
- if (_path != null && (_options & FileOptions.DeleteOnClose) != 0)
- {
- // Since we still have the file open, this will end up deleting
- // it (assuming we're the only link to it) once it's closed, but the
- // name will be removed immediately.
- Interop.Sys.Unlink(_path); // ignore errors; it's valid that the path may no longer exist
- }
- }
- }
- finally
- {
- if (_fileHandle != null && !_fileHandle.IsClosed)
- {
- _fileHandle.Dispose();
- }
- base.Dispose(disposing);
- }
- }
-
- /// <summary>Flushes the OS buffer. This does not flush the internal read/write buffer.</summary>
- private void FlushOSBuffer()
- {
- if (Interop.Sys.FSync(_fileHandle) < 0)
- {
- Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo();
- switch (errorInfo.Error)
- {
- case Interop.Error.EROFS:
- case Interop.Error.EINVAL:
- case Interop.Error.ENOTSUP:
- // Ignore failures due to the FileStream being bound to a special file that
- // doesn't support synchronization. In such cases there's nothing to flush.
- break;
- default:
- throw Interop.GetExceptionForIoErrno(errorInfo, _path, isDirectory: false);
- }
- }
- }
-
- /// <summary>Writes any data in the write buffer to the underlying stream and resets the buffer.</summary>
- private void FlushWriteBuffer()
- {
- AssertBufferInvariants();
- if (_writePos > 0)
- {
- WriteNative(GetBuffer(), 0, _writePos);
- _writePos = 0;
- }
- }
-
- /// <summary>Asynchronously clears all buffers for this stream, causing any buffered data to be written to the underlying device.</summary>
- /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
- /// <returns>A task that represents the asynchronous flush operation.</returns>
- private Task FlushAsyncInternal(CancellationToken cancellationToken)
- {
- if (cancellationToken.IsCancellationRequested)
- {
- return Task.FromCanceled(cancellationToken);
- }
- if (_fileHandle.IsClosed)
- {
- throw Error.GetFileNotOpen();
- }
-
- // As with Win32FileStream, flush the buffers synchronously to avoid race conditions.
- try
- {
- FlushInternalBuffer();
- }
- catch (Exception e)
- {
- return Task.FromException(e);
- }
-
- // We then separately flush to disk asynchronously. This is only
- // necessary if we support writing; otherwise, we're done.
- if (CanWrite)
- {
- return Task.Factory.StartNew(
- state => ((FileStream)state).FlushOSBuffer(),
- this,
- cancellationToken,
- TaskCreationOptions.DenyChildAttach,
- TaskScheduler.Default);
- }
- else
- {
- return Task.CompletedTask;
- }
- }
-
- /// <summary>Sets the length of this stream to the given value.</summary>
- /// <param name="value">The new length of the stream.</param>
- private void SetLengthInternal(long value)
- {
- FlushInternalBuffer();
-
- if (_appendStart != -1 && value < _appendStart)
- {
- throw new IOException(SR.IO_SetLengthAppendTruncate);
- }
-
- long origPos = _filePosition;
-
- VerifyOSHandlePosition();
-
- if (_filePosition != value)
- {
- SeekCore(value, SeekOrigin.Begin);
- }
-
- CheckFileCall(Interop.Sys.FTruncate(_fileHandle, value));
-
- // Return file pointer to where it was before setting length
- if (origPos != value)
- {
- if (origPos < value)
- {
- SeekCore(origPos, SeekOrigin.Begin);
- }
- else
- {
- SeekCore(0, SeekOrigin.End);
- }
- }
- }
-
- /// <summary>Reads a block of bytes from the stream and writes the data in a given buffer.</summary>
- /// <param name="array">
- /// When this method returns, contains the specified byte array with the values between offset and
- /// (offset + count - 1) replaced by the bytes read from the current source.
- /// </param>
- /// <param name="offset">The byte offset in array at which the read bytes will be placed.</param>
- /// <param name="count">The maximum number of bytes to read. </param>
- /// <returns>
- /// The total number of bytes read into the buffer. This might be less than the number of bytes requested
- /// if that number of bytes are not currently available, or zero if the end of the stream is reached.
- /// </returns>
- public override int Read(byte[] array, int offset, int count)
- {
- ValidateReadWriteArgs(array, offset, count);
-
- if (_useAsyncIO)
- {
- _asyncState.Wait();
- try { return ReadCore(array, offset, count); }
- finally { _asyncState.Release(); }
- }
- else
- {
- return ReadCore(array, offset, count);
- }
- }
-
- /// <summary>Reads a block of bytes from the stream and writes the data in a given buffer.</summary>
- /// <param name="array">
- /// When this method returns, contains the specified byte array with the values between offset and
- /// (offset + count - 1) replaced by the bytes read from the current source.
- /// </param>
- /// <param name="offset">The byte offset in array at which the read bytes will be placed.</param>
- /// <param name="count">The maximum number of bytes to read. </param>
- /// <returns>
- /// The total number of bytes read into the buffer. This might be less than the number of bytes requested
- /// if that number of bytes are not currently available, or zero if the end of the stream is reached.
- /// </returns>
- private int ReadCore(byte[] array, int offset, int count)
- {
- PrepareForReading();
-
- // Are there any bytes available in the read buffer? If yes,
- // we can just return from the buffer. If the buffer is empty
- // or has no more available data in it, we can either refill it
- // (and then read from the buffer into the user's buffer) or
- // we can just go directly into the user's buffer, if they asked
- // for more data than we'd otherwise buffer.
- int numBytesAvailable = _readLength - _readPos;
- bool readFromOS = false;
- if (numBytesAvailable == 0)
- {
- // If we're not able to seek, then we're not able to rewind the stream (i.e. flushing
- // a read buffer), in which case we don't want to use a read buffer. Similarly, if
- // the user has asked for more data than we can buffer, we also want to skip the buffer.
- if (!CanSeek || (count >= _bufferLength))
- {
- // Read directly into the user's buffer
- _readPos = _readLength = 0;
- return ReadNative(array, offset, count);
- }
- else
- {
- // Read into our buffer.
- _readLength = numBytesAvailable = ReadNative(GetBuffer(), 0, _bufferLength);
- _readPos = 0;
- if (numBytesAvailable == 0)
- {
- return 0;
- }
-
- // Note that we did an OS read as part of this Read, so that later
- // we don't try to do one again if what's in the buffer doesn't
- // meet the user's request.
- readFromOS = true;
- }
- }
-
- // Now that we know there's data in the buffer, read from it into the user's buffer.
- Debug.Assert(numBytesAvailable > 0, "Data must be in the buffer to be here");
- int bytesRead = Math.Min(numBytesAvailable, count);
- Buffer.BlockCopy(GetBuffer(), _readPos, array, offset, bytesRead);
- _readPos += bytesRead;
-
- // We may not have had enough data in the buffer to completely satisfy the user's request.
- // While Read doesn't require that we return as much data as the user requested (any amount
- // up to the requested count is fine), FileStream on Windows tries to do so by doing a
- // subsequent read from the file if we tried to satisfy the request with what was in the
- // buffer but the buffer contained less than the requested count. To be consistent with that
- // behavior, we do the same thing here on Unix. Note that we may still get less the requested
- // amount, as the OS may give us back fewer than we request, either due to reaching the end of
- // file, or due to its own whims.
- if (!readFromOS && bytesRead < count)
- {
- Debug.Assert(_readPos == _readLength, "bytesToRead should only be < count if numBytesAvailable < count");
- _readPos = _readLength = 0; // no data left in the read buffer
- bytesRead += ReadNative(array, offset + bytesRead, count - bytesRead);
- }
-
- return bytesRead;
- }
-
- /// <summary>Unbuffered, reads a block of bytes from the stream and writes the data in a given buffer.</summary>
- /// <param name="array">
- /// When this method returns, contains the specified byte array with the values between offset and
- /// (offset + count - 1) replaced by the bytes read from the current source.
- /// </param>
- /// <param name="offset">The byte offset in array at which the read bytes will be placed.</param>
- /// <param name="count">The maximum number of bytes to read. </param>
- /// <returns>
- /// The total number of bytes read into the buffer. This might be less than the number of bytes requested
- /// if that number of bytes are not currently available, or zero if the end of the stream is reached.
- /// </returns>
- private unsafe int ReadNative(byte[] array, int offset, int count)
- {
- FlushWriteBuffer(); // we're about to read; dump the write buffer
-
- VerifyOSHandlePosition();
-
- int bytesRead;
- fixed (byte* bufPtr = array)
- {
- bytesRead = CheckFileCall(Interop.Sys.Read(_fileHandle, bufPtr + offset, count));
- Debug.Assert(bytesRead <= count);
- }
- _filePosition += bytesRead;
- return bytesRead;
- }
-
- /// <summary>
- /// Asynchronously reads a sequence of bytes from the current stream and advances
- /// the position within the stream by the number of bytes read.
- /// </summary>
- /// <param name="buffer">The buffer to write the data into.</param>
- /// <param name="offset">The byte offset in buffer at which to begin writing data from the stream.</param>
- /// <param name="count">The maximum number of bytes to read.</param>
- /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
- /// <returns>A task that represents the asynchronous read operation.</returns>
- private Task<int> ReadAsyncInternal(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
- {
- if (_useAsyncIO)
- {
- if (!CanRead) // match Windows behavior; this gets thrown synchronously
- {
- throw Error.GetReadNotSupported();
- }
-
- // Serialize operations using the semaphore.
- Task waitTask = _asyncState.WaitAsync();
-
- // If we got ownership immediately, and if there's enough data in our buffer
- // to satisfy the full request of the caller, hand back the buffered data.
- // While it would be a legal implementation of the Read contract, we don't
- // hand back here less than the amount requested so as to match the behavior
- // in ReadCore that will make a native call to try to fulfill the remainder
- // of the request.
- if (waitTask.Status == TaskStatus.RanToCompletion)
- {
- int numBytesAvailable = _readLength - _readPos;
- if (numBytesAvailable >= count)
- {
- try
- {
- PrepareForReading();
-
- Buffer.BlockCopy(GetBuffer(), _readPos, buffer, offset, count);
- _readPos += count;
-
- return _asyncState._lastSuccessfulReadTask != null && _asyncState._lastSuccessfulReadTask.Result == count ?
- _asyncState._lastSuccessfulReadTask :
- (_asyncState._lastSuccessfulReadTask = Task.FromResult(count));
- }
- catch (Exception exc)
- {
- return Task.FromException<int>(exc);
- }
- finally
- {
- _asyncState.Release();
- }
- }
- }
-
- // Otherwise, issue the whole request asynchronously.
- _asyncState.Update(buffer, offset, count);
- return waitTask.ContinueWith((t, s) =>
- {
- // The options available on Unix for writing asynchronously to an arbitrary file
- // handle typically amount to just using another thread to do the synchronous write,
- // which is exactly what this implementation does. This does mean there are subtle
- // differences in certain FileStream behaviors between Windows and Unix when multiple
- // asynchronous operations are issued against the stream to execute concurrently; on
- // Unix the operations will be serialized due to the usage of a semaphore, but the
- // position /length information won't be updated until after the write has completed,
- // whereas on Windows it may happen before the write has completed.
-
- Debug.Assert(t.Status == TaskStatus.RanToCompletion);
- var thisRef = (FileStream)s;
- try
- {
- byte[] b = thisRef._asyncState._buffer;
- thisRef._asyncState._buffer = null; // remove reference to user's buffer
- return thisRef.ReadCore(b, thisRef._asyncState._offset, thisRef._asyncState._count);
- }
- finally { thisRef._asyncState.Release(); }
- }, this, CancellationToken.None, TaskContinuationOptions.DenyChildAttach, TaskScheduler.Default);
- }
- else
- {
- return base.ReadAsync(buffer, offset, count, cancellationToken);
- }
- }
-
- /// <summary>
- /// Reads a byte from the stream and advances the position within the stream
- /// by one byte, or returns -1 if at the end of the stream.
- /// </summary>
- /// <returns>The unsigned byte cast to an Int32, or -1 if at the end of the stream.</returns>
- public override int ReadByte()
- {
- if (_useAsyncIO)
- {
- _asyncState.Wait();
- try { return ReadByteCore(); }
- finally { _asyncState.Release(); }
- }
- else
- {
- return ReadByteCore();
- }
- }
-
- /// <summary>Writes a block of bytes to the file stream.</summary>
- /// <param name="array">The buffer containing data to write to the stream.</param>
- /// <param name="offset">The zero-based byte offset in array from which to begin copying bytes to the stream.</param>
- /// <param name="count">The maximum number of bytes to write.</param>
- public override void Write(byte[] array, int offset, int count)
- {
- ValidateReadWriteArgs(array, offset, count);
-
- if (_useAsyncIO)
- {
- _asyncState.Wait();
- try { WriteCore(array, offset, count); }
- finally { _asyncState.Release(); }
- }
- else
- {
- WriteCore(array, offset, count);
- }
- }
-
- /// <summary>Writes a block of bytes to the file stream.</summary>
- /// <param name="array">The buffer containing data to write to the stream.</param>
- /// <param name="offset">The zero-based byte offset in array from which to begin copying bytes to the stream.</param>
- /// <param name="count">The maximum number of bytes to write.</param>
- private void WriteCore(byte[] array, int offset, int count)
- {
- PrepareForWriting();
-
- // If no data is being written, nothing more to do.
- if (count == 0)
- {
- return;
- }
-
- // If there's already data in our write buffer, then we need to go through
- // our buffer to ensure data isn't corrupted.
- if (_writePos > 0)
- {
- // If there's space remaining in the buffer, then copy as much as
- // we can from the user's buffer into ours.
- int spaceRemaining = _bufferLength - _writePos;
- if (spaceRemaining > 0)
- {
- int bytesToCopy = Math.Min(spaceRemaining, count);
- Buffer.BlockCopy(array, offset, GetBuffer(), _writePos, bytesToCopy);
- _writePos += bytesToCopy;
-
- // If we've successfully copied all of the user's data, we're done.
- if (count == bytesToCopy)
- {
- return;
- }
-
- // Otherwise, keep track of how much more data needs to be handled.
- offset += bytesToCopy;
- count -= bytesToCopy;
- }
-
- // At this point, the buffer is full, so flush it out.
- FlushWriteBuffer();
- }
-
- // Our buffer is now empty. If using the buffer would slow things down (because
- // the user's looking to write more data than we can store in the buffer),
- // skip the buffer. Otherwise, put the remaining data into the buffer.
- Debug.Assert(_writePos == 0);
- if (count >= _bufferLength)
- {
- WriteNative(array, offset, count);
- }
- else
- {
- Buffer.BlockCopy(array, offset, GetBuffer(), _writePos, count);
- _writePos = count;
- }
- }
-
- /// <summary>Unbuffered, writes a block of bytes to the file stream.</summary>
- /// <param name="array">The buffer containing data to write to the stream.</param>
- /// <param name="offset">The zero-based byte offset in array from which to begin copying bytes to the stream.</param>
- /// <param name="count">The maximum number of bytes to write.</param>
- private unsafe void WriteNative(byte[] array, int offset, int count)
- {
- VerifyOSHandlePosition();
-
- fixed (byte* bufPtr = array)
- {
- while (count > 0)
- {
- int bytesWritten = CheckFileCall(Interop.Sys.Write(_fileHandle, bufPtr + offset, count));
- Debug.Assert(bytesWritten <= count);
-
- _filePosition += bytesWritten;
- count -= bytesWritten;
- offset += bytesWritten;
- }
- }
- }
-
- /// <summary>
- /// Asynchronously writes a sequence of bytes to the current stream, advances
- /// the current position within this stream by the number of bytes written, and
- /// monitors cancellation requests.
- /// </summary>
- /// <param name="buffer">The buffer to write data from.</param>
- /// <param name="offset">The zero-based byte offset in buffer from which to begin copying bytes to the stream.</param>
- /// <param name="count">The maximum number of bytes to write.</param>
- /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
- /// <returns>A task that represents the asynchronous write operation.</returns>
- private Task WriteAsyncInternal(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
- {
- if (cancellationToken.IsCancellationRequested)
- return Task.FromCanceled(cancellationToken);
-
- if (_fileHandle.IsClosed)
- throw Error.GetFileNotOpen();
-
- if (_useAsyncIO)
- {
- if (!CanWrite) // match Windows behavior; this gets thrown synchronously
- {
- throw Error.GetWriteNotSupported();
- }
-
- // Serialize operations using the semaphore.
- Task waitTask = _asyncState.WaitAsync();
-
- // If we got ownership immediately, and if there's enough space in our buffer
- // to buffer the entire write request, then do so and we're done.
- if (waitTask.Status == TaskStatus.RanToCompletion)
- {
- int spaceRemaining = _bufferLength - _writePos;
- if (spaceRemaining >= count)
- {
- try
- {
- PrepareForWriting();
-
- Buffer.BlockCopy(buffer, offset, GetBuffer(), _writePos, count);
- _writePos += count;
-
- return Task.CompletedTask;
- }
- catch (Exception exc)
- {
- return Task.FromException(exc);
- }
- finally
- {
- _asyncState.Release();
- }
- }
- }
-
- // Otherwise, issue the whole request asynchronously.
- _asyncState.Update(buffer, offset, count);
- return waitTask.ContinueWith((t, s) =>
- {
- // The options available on Unix for writing asynchronously to an arbitrary file
- // handle typically amount to just using another thread to do the synchronous write,
- // which is exactly what this implementation does. This does mean there are subtle
- // differences in certain FileStream behaviors between Windows and Unix when multiple
- // asynchronous operations are issued against the stream to execute concurrently; on
- // Unix the operations will be serialized due to the usage of a semaphore, but the
- // position /length information won't be updated until after the write has completed,
- // whereas on Windows it may happen before the write has completed.
-
- Debug.Assert(t.Status == TaskStatus.RanToCompletion);
- var thisRef = (FileStream)s;
- try
- {
- byte[] b = thisRef._asyncState._buffer;
- thisRef._asyncState._buffer = null; // remove reference to user's buffer
- thisRef.WriteCore(b, thisRef._asyncState._offset, thisRef._asyncState._count);
- }
- finally { thisRef._asyncState.Release(); }
- }, this, CancellationToken.None, TaskContinuationOptions.DenyChildAttach, TaskScheduler.Default);
- }
- else
- {
- return base.WriteAsync(buffer, offset, count, cancellationToken);
- }
- }
-
- /// <summary>
- /// Writes a byte to the current position in the stream and advances the position
- /// within the stream by one byte.
- /// </summary>
- /// <param name="value">The byte to write to the stream.</param>
- public override void WriteByte(byte value) // avoids an array allocation in the base implementation
- {
- if (_useAsyncIO)
- {
- _asyncState.Wait();
- try { WriteByteCore(value); }
- finally { _asyncState.Release(); }
- }
- else
- {
- WriteByteCore(value);
- }
- }
-
- /// <summary>Prevents other processes from reading from or writing to the FileStream.</summary>
- /// <param name="position">The beginning of the range to lock.</param>
- /// <param name="length">The range to be locked.</param>
- private void LockInternal(long position, long length)
- {
- CheckFileCall(Interop.Sys.LockFileRegion(_fileHandle, position, length, Interop.Sys.LockType.F_WRLCK));
- }
-
- /// <summary>Allows access by other processes to all or part of a file that was previously locked.</summary>
- /// <param name="position">The beginning of the range to unlock.</param>
- /// <param name="length">The range to be unlocked.</param>
- private void UnlockInternal(long position, long length)
- {
- CheckFileCall(Interop.Sys.LockFileRegion(_fileHandle, position, length, Interop.Sys.LockType.F_UNLCK));
- }
-
- /// <summary>Sets the current position of this stream to the given value.</summary>
- /// <param name="offset">The point relative to origin from which to begin seeking. </param>
- /// <param name="origin">
- /// Specifies the beginning, the end, or the current position as a reference
- /// point for offset, using a value of type SeekOrigin.
- /// </param>
- /// <returns>The new position in the stream.</returns>
- public override long Seek(long offset, SeekOrigin origin)
- {
- if (origin < SeekOrigin.Begin || origin > SeekOrigin.End)
- {
- throw new ArgumentException(SR.Argument_InvalidSeekOrigin, nameof(origin));
- }
- if (_fileHandle.IsClosed)
- {
- throw Error.GetFileNotOpen();
- }
- if (!CanSeek)
- {
- throw Error.GetSeekNotSupported();
- }
-
- VerifyOSHandlePosition();
-
- // Flush our write/read buffer. FlushWrite will output any write buffer we have and reset _bufferWritePos.
- // We don't call FlushRead, as that will do an unnecessary seek to rewind the read buffer, and since we're
- // about to seek and update our position, we can simply update the offset as necessary and reset our read
- // position and length to 0. (In the future, for some simple cases we could potentially add an optimization
- // here to just move data around in the buffer for short jumps, to avoid re-reading the data from disk.)
- FlushWriteBuffer();
- if (origin == SeekOrigin.Current)
- {
- offset -= (_readLength - _readPos);
- }
- _readPos = _readLength = 0;
-
- // Keep track of where we were, in case we're in append mode and need to verify
- long oldPos = 0;
- if (_appendStart >= 0)
- {
- oldPos = SeekCore(0, SeekOrigin.Current);
- }
-
- // Jump to the new location
- long pos = SeekCore(offset, origin);
-
- // Prevent users from overwriting data in a file that was opened in append mode.
- if (_appendStart != -1 && pos < _appendStart)
- {
- SeekCore(oldPos, SeekOrigin.Begin);
- throw new IOException(SR.IO_SeekAppendOverwrite);
- }
-
- // Return the new position
- return pos;
- }
-
- /// <summary>Sets the current position of this stream to the given value.</summary>
- /// <param name="offset">The point relative to origin from which to begin seeking. </param>
- /// <param name="origin">
- /// Specifies the beginning, the end, or the current position as a reference
- /// point for offset, using a value of type SeekOrigin.
- /// </param>
- /// <returns>The new position in the stream.</returns>
- private long SeekCore(long offset, SeekOrigin origin)
- {
- Debug.Assert(!_fileHandle.IsClosed && (GetType() != typeof(FileStream) || CanSeek)); // verify that we can seek, but only if CanSeek won't be a virtual call (which could happen in the ctor)
- Debug.Assert(origin >= SeekOrigin.Begin && origin <= SeekOrigin.End);
-
- long pos = CheckFileCall(Interop.Sys.LSeek(_fileHandle, offset, (Interop.Sys.SeekWhence)(int)origin)); // SeekOrigin values are the same as Interop.libc.SeekWhence values
- _filePosition = pos;
- return pos;
- }
-
- private long CheckFileCall(long result, bool ignoreNotSupported = false)
- {
- if (result < 0)
- {
- Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo();
- if (!(ignoreNotSupported && errorInfo.Error == Interop.Error.ENOTSUP))
- {
- throw Interop.GetExceptionForIoErrno(errorInfo, _path, isDirectory: false);
- }
- }
-
- return result;
- }
-
- private int CheckFileCall(int result, bool ignoreNotSupported = false)
- {
- CheckFileCall((long)result, ignoreNotSupported);
-
- return result;
- }
-
- /// <summary>State used when the stream is in async mode.</summary>
- private sealed class AsyncState : SemaphoreSlim
- {
- /// <summary>The caller's buffer currently being used by the active async operation.</summary>
- internal byte[] _buffer;
- /// <summary>The caller's offset currently being used by the active async operation.</summary>
- internal int _offset;
- /// <summary>The caller's count currently being used by the active async operation.</summary>
- internal int _count;
- /// <summary>The last task successfully, synchronously returned task from ReadAsync.</summary>
- internal Task<int> _lastSuccessfulReadTask;
-
- /// <summary>Initialize the AsyncState.</summary>
- internal AsyncState() : base(initialCount: 1, maxCount: 1) { }
-
- /// <summary>Sets the active buffer, offset, and count.</summary>
- internal void Update(byte[] buffer, int offset, int count)
- {
- _buffer = buffer;
- _offset = offset;
- _count = count;
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/IO/FileStream.Win32.cs b/src/mscorlib/corefx/System/IO/FileStream.Win32.cs
deleted file mode 100644
index 683eef5e43..0000000000
--- a/src/mscorlib/corefx/System/IO/FileStream.Win32.cs
+++ /dev/null
@@ -1,1770 +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.Buffers;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Win32.SafeHandles;
-using System.Runtime.CompilerServices;
-
-/*
- * Win32FileStream supports different modes of accessing the disk - async mode
- * and sync mode. They are two completely different codepaths in the
- * sync & async methods (i.e. Read/Write vs. ReadAsync/WriteAsync). File
- * handles in NT can be opened in only sync or overlapped (async) mode,
- * and we have to deal with this pain. Stream has implementations of
- * the sync methods in terms of the async ones, so we'll
- * call through to our base class to get those methods when necessary.
- *
- * Also buffering is added into Win32FileStream as well. Folded in the
- * code from BufferedStream, so all the comments about it being mostly
- * aggressive (and the possible perf improvement) apply to Win32FileStream as
- * well. Also added some buffering to the async code paths.
- *
- * Class Invariants:
- * The class has one buffer, shared for reading & writing. It can only be
- * used for one or the other at any point in time - not both. The following
- * should be true:
- * 0 <= _readPos <= _readLen < _bufferSize
- * 0 <= _writePos < _bufferSize
- * _readPos == _readLen && _readPos > 0 implies the read buffer is valid,
- * but we're at the end of the buffer.
- * _readPos == _readLen == 0 means the read buffer contains garbage.
- * Either _writePos can be greater than 0, or _readLen & _readPos can be
- * greater than zero, but neither can be greater than zero at the same time.
- *
- */
-
-namespace System.IO
-{
- public partial class FileStream : Stream
- {
- private bool _canSeek;
- private bool _isPipe; // Whether to disable async buffering code.
- private long _appendStart; // When appending, prevent overwriting file.
-
- private static unsafe IOCompletionCallback s_ioCallback = FileStreamCompletionSource.IOCallback;
-
- private Task<int> _lastSynchronouslyCompletedTask = null; // cached task for read ops that complete synchronously
- private Task _activeBufferOperation = null; // tracks in-progress async ops using the buffer
- private PreAllocatedOverlapped _preallocatedOverlapped; // optimization for async ops to avoid per-op allocations
- private FileStreamCompletionSource _currentOverlappedOwner; // async op currently using the preallocated overlapped
-
- private SafeFileHandle OpenHandle(FileMode mode, FileShare share, FileOptions options)
- {
- Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(share);
-
- int fAccess =
- ((_access & FileAccess.Read) == FileAccess.Read ? GENERIC_READ : 0) |
- ((_access & FileAccess.Write) == FileAccess.Write ? GENERIC_WRITE : 0);
-
- // Our Inheritable bit was stolen from Windows, but should be set in
- // the security attributes class. Don't leave this bit set.
- share &= ~FileShare.Inheritable;
-
- // Must use a valid Win32 constant here...
- if (mode == FileMode.Append)
- mode = FileMode.OpenOrCreate;
-
- int flagsAndAttributes = (int)options;
-
- // For mitigating local elevation of privilege attack through named pipes
- // make sure we always call CreateFile with SECURITY_ANONYMOUS so that the
- // named pipe server can't impersonate a high privileged client security context
- flagsAndAttributes |= (Interop.Kernel32.SecurityOptions.SECURITY_SQOS_PRESENT | Interop.Kernel32.SecurityOptions.SECURITY_ANONYMOUS);
-
- // Don't pop up a dialog for reading from an empty floppy drive
- uint oldMode = Interop.Kernel32.SetErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS);
- try
- {
- SafeFileHandle fileHandle = Interop.Kernel32.SafeCreateFile(_path, fAccess, share, ref secAttrs, mode, flagsAndAttributes, IntPtr.Zero);
- fileHandle.IsAsync = _useAsyncIO;
-
- if (fileHandle.IsInvalid)
- {
- // Return a meaningful exception with the full path.
-
- // NT5 oddity - when trying to open "C:\" as a Win32FileStream,
- // we usually get ERROR_PATH_NOT_FOUND from the OS. We should
- // probably be consistent w/ every other directory.
- int errorCode = Marshal.GetLastWin32Error();
-
- if (errorCode == Interop.Errors.ERROR_PATH_NOT_FOUND && _path.Equals(Directory.InternalGetDirectoryRoot(_path)))
- errorCode = Interop.Errors.ERROR_ACCESS_DENIED;
-
- throw Win32Marshal.GetExceptionForWin32Error(errorCode, _path);
- }
-
- return fileHandle;
- }
- finally
- {
- Interop.Kernel32.SetErrorMode(oldMode);
- }
- }
-
- private void Init(FileMode mode, FileShare share)
- {
- // Disallow access to all non-file devices from the Win32FileStream
- // constructors that take a String. Everyone else can call
- // CreateFile themselves then use the constructor that takes an
- // IntPtr. Disallows "con:", "com1:", "lpt1:", etc.
- int fileType = Interop.Kernel32.GetFileType(_fileHandle);
- if (fileType != Interop.Kernel32.FileTypes.FILE_TYPE_DISK)
- {
- _fileHandle.Dispose();
- throw new NotSupportedException(SR.NotSupported_FileStreamOnNonFiles);
- }
-
- // This is necessary for async IO using IO Completion ports via our
- // managed Threadpool API's. This (theoretically) calls the OS's
- // BindIoCompletionCallback method, and passes in a stub for the
- // LPOVERLAPPED_COMPLETION_ROUTINE. This stub looks at the Overlapped
- // struct for this request and gets a delegate to a managed callback
- // from there, which it then calls on a threadpool thread. (We allocate
- // our native OVERLAPPED structs 2 pointers too large and store EE state
- // & GC handles there, one to an IAsyncResult, the other to a delegate.)
- if (_useAsyncIO)
- {
- try
- {
- _fileHandle.ThreadPoolBinding = ThreadPoolBoundHandle.BindHandle(_fileHandle);
- }
- catch (ArgumentException ex)
- {
- throw new IOException(SR.IO_BindHandleFailed, ex);
- }
- finally
- {
- if (_fileHandle.ThreadPoolBinding == null)
- {
- // We should close the handle so that the handle is not open until SafeFileHandle GC
- Debug.Assert(!_exposedHandle, "Are we closing handle that we exposed/not own, how?");
- _fileHandle.Dispose();
- }
- }
- }
-
- _canSeek = true;
-
- // For Append mode...
- if (mode == FileMode.Append)
- {
- _appendStart = SeekCore(0, SeekOrigin.End);
- }
- else
- {
- _appendStart = -1;
- }
- }
-
- private void InitFromHandle(SafeFileHandle handle)
- {
- int handleType = Interop.Kernel32.GetFileType(_fileHandle);
- Debug.Assert(handleType == Interop.Kernel32.FileTypes.FILE_TYPE_DISK || handleType == Interop.Kernel32.FileTypes.FILE_TYPE_PIPE || handleType == Interop.Kernel32.FileTypes.FILE_TYPE_CHAR, "FileStream was passed an unknown file type!");
-
- _canSeek = handleType == Interop.Kernel32.FileTypes.FILE_TYPE_DISK;
- _isPipe = handleType == Interop.Kernel32.FileTypes.FILE_TYPE_PIPE;
-
- // This is necessary for async IO using IO Completion ports via our
- // managed Threadpool API's. This calls the OS's
- // BindIoCompletionCallback method, and passes in a stub for the
- // LPOVERLAPPED_COMPLETION_ROUTINE. This stub looks at the Overlapped
- // struct for this request and gets a delegate to a managed callback
- // from there, which it then calls on a threadpool thread. (We allocate
- // our native OVERLAPPED structs 2 pointers too large and store EE
- // state & a handle to a delegate there.)
- //
- // If, however, we've already bound this file handle to our completion port,
- // don't try to bind it again because it will fail. A handle can only be
- // bound to a single completion port at a time.
- if (_useAsyncIO && !GetSuppressBindHandle(handle))
- {
- try
- {
- _fileHandle.ThreadPoolBinding = ThreadPoolBoundHandle.BindHandle(_fileHandle);
- }
- catch (Exception ex)
- {
- // If you passed in a synchronous handle and told us to use
- // it asynchronously, throw here.
- throw new ArgumentException(SR.Arg_HandleNotAsync, nameof(handle), ex);
- }
- }
- else if (!_useAsyncIO)
- {
- if (handleType != Interop.Kernel32.FileTypes.FILE_TYPE_PIPE)
- VerifyHandleIsSync();
- }
-
- if (_canSeek)
- SeekCore(0, SeekOrigin.Current);
- else
- _filePosition = 0;
- }
-
- private static bool GetSuppressBindHandle(SafeFileHandle handle)
- {
- return handle.IsAsync.HasValue ? handle.IsAsync.Value : false;
- }
-
- private unsafe static Interop.Kernel32.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share)
- {
- Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = default(Interop.Kernel32.SECURITY_ATTRIBUTES);
- if ((share & FileShare.Inheritable) != 0)
- {
- secAttrs = new Interop.Kernel32.SECURITY_ATTRIBUTES();
- secAttrs.nLength = (uint)sizeof(Interop.Kernel32.SECURITY_ATTRIBUTES);
-
- secAttrs.bInheritHandle = Interop.BOOL.TRUE;
- }
- return secAttrs;
- }
-
- // Verifies that this handle supports synchronous IO operations (unless you
- // didn't open it for either reading or writing).
- private unsafe void VerifyHandleIsSync()
- {
- Debug.Assert(!_useAsyncIO);
-
- // Do NOT use this method on pipes. Reading or writing to a pipe may
- // cause an app to block incorrectly, introducing a deadlock (depending
- // on whether a write will wake up an already-blocked thread or this
- // Win32FileStream's thread).
- Debug.Assert(Interop.Kernel32.GetFileType(_fileHandle) != Interop.Kernel32.FileTypes.FILE_TYPE_PIPE);
-
- byte* bytes = stackalloc byte[1];
- int numBytesReadWritten;
- int r = -1;
-
- // If the handle is a pipe, ReadFile will block until there
- // has been a write on the other end. We'll just have to deal with it,
- // For the read end of a pipe, you can mess up and
- // accidentally read synchronously from an async pipe.
- if ((_access & FileAccess.Read) != 0) // don't use the virtual CanRead or CanWrite, as this may be used in the ctor
- {
- r = Interop.Kernel32.ReadFile(_fileHandle, bytes, 0, out numBytesReadWritten, IntPtr.Zero);
- }
- else if ((_access & FileAccess.Write) != 0) // don't use the virtual CanRead or CanWrite, as this may be used in the ctor
- {
- r = Interop.Kernel32.WriteFile(_fileHandle, bytes, 0, out numBytesReadWritten, IntPtr.Zero);
- }
-
- if (r == 0)
- {
- int errorCode = GetLastWin32ErrorAndDisposeHandleIfInvalid(throwIfInvalidHandle: true);
- if (errorCode == ERROR_INVALID_PARAMETER)
- throw new ArgumentException(SR.Arg_HandleNotSync, "handle");
- }
- }
-
- private bool HasActiveBufferOperation
- {
- get { return _activeBufferOperation != null && !_activeBufferOperation.IsCompleted; }
- }
-
- public override bool CanSeek
- {
- get { return _canSeek; }
- }
-
- private long GetLengthInternal()
- {
- Interop.Kernel32.FILE_STANDARD_INFO info = new Interop.Kernel32.FILE_STANDARD_INFO();
-
- if (!Interop.Kernel32.GetFileInformationByHandleEx(_fileHandle, Interop.Kernel32.FILE_INFO_BY_HANDLE_CLASS.FileStandardInfo, out info, (uint)Marshal.SizeOf<Interop.Kernel32.FILE_STANDARD_INFO>()))
- throw Win32Marshal.GetExceptionForLastWin32Error();
- long len = info.EndOfFile;
- // If we're writing near the end of the file, we must include our
- // internal buffer in our Length calculation. Don't flush because
- // we use the length of the file in our async write method.
- if (_writePos > 0 && _filePosition + _writePos > len)
- len = _writePos + _filePosition;
- return len;
- }
-
- protected override void Dispose(bool disposing)
- {
- // Nothing will be done differently based on whether we are
- // disposing vs. finalizing. This is taking advantage of the
- // weak ordering between normal finalizable objects & critical
- // finalizable objects, which I included in the SafeHandle
- // design for Win32FileStream, which would often "just work" when
- // finalized.
- try
- {
- if (_fileHandle != null && !_fileHandle.IsClosed)
- {
- // Flush data to disk iff we were writing. After
- // thinking about this, we also don't need to flush
- // our read position, regardless of whether the handle
- // was exposed to the user. They probably would NOT
- // want us to do this.
- if (_writePos > 0)
- {
- FlushWriteBuffer(!disposing);
- }
- }
- }
- finally
- {
- if (_fileHandle != null && !_fileHandle.IsClosed)
- {
- if (_fileHandle.ThreadPoolBinding != null)
- _fileHandle.ThreadPoolBinding.Dispose();
-
- _fileHandle.Dispose();
- }
-
- if (_preallocatedOverlapped != null)
- _preallocatedOverlapped.Dispose();
-
- _canSeek = false;
-
- // Don't set the buffer to null, to avoid a NullReferenceException
- // when users have a race condition in their code (i.e. they call
- // Close when calling another method on Stream like Read).
- //_buffer = null;
- base.Dispose(disposing);
- }
- }
-
- private void FlushOSBuffer()
- {
- if (!Interop.Kernel32.FlushFileBuffers(_fileHandle))
- {
- throw Win32Marshal.GetExceptionForLastWin32Error();
- }
- }
-
- // Returns a task that flushes the internal write buffer
- private Task FlushWriteAsync(CancellationToken cancellationToken)
- {
- Debug.Assert(_useAsyncIO);
- Debug.Assert(_readPos == 0 && _readLength == 0, "FileStream: Read buffer must be empty in FlushWriteAsync!");
-
- // If the buffer is already flushed, don't spin up the OS write
- if (_writePos == 0) return Task.CompletedTask;
-
- Task flushTask = WriteInternalCoreAsync(GetBuffer(), 0, _writePos, cancellationToken);
- _writePos = 0;
-
- // Update the active buffer operation
- _activeBufferOperation = HasActiveBufferOperation ?
- Task.WhenAll(_activeBufferOperation, flushTask) :
- flushTask;
-
- return flushTask;
- }
-
- // Writes are buffered. Anytime the buffer fills up
- // (_writePos + delta > _bufferSize) or the buffer switches to reading
- // and there is left over data (_writePos > 0), this function must be called.
- private void FlushWriteBuffer(bool calledFromFinalizer = false)
- {
- if (_writePos == 0) return;
- Debug.Assert(_readPos == 0 && _readLength == 0, "FileStream: Read buffer must be empty in FlushWrite!");
-
- if (_useAsyncIO)
- {
- Task writeTask = FlushWriteAsync(CancellationToken.None);
- // With our Whidbey async IO & overlapped support for AD unloads,
- // we don't strictly need to block here to release resources
- // since that support takes care of the pinning & freeing the
- // overlapped struct. We need to do this when called from
- // Close so that the handle is closed when Close returns, but
- // we don't need to call EndWrite from the finalizer.
- // Additionally, if we do call EndWrite, we block forever
- // because AD unloads prevent us from running the managed
- // callback from the IO completion port. Blocking here when
- // called from the finalizer during AD unload is clearly wrong,
- // but we can't use any sort of test for whether the AD is
- // unloading because if we weren't unloading, an AD unload
- // could happen on a separate thread before we call EndWrite.
- if (!calledFromFinalizer)
- {
- writeTask.GetAwaiter().GetResult();
- }
- }
- else
- {
- WriteCore(GetBuffer(), 0, _writePos);
- }
-
- _writePos = 0;
- }
-
- private void SetLengthInternal(long value)
- {
- // Handle buffering updates.
- if (_writePos > 0)
- {
- FlushWriteBuffer();
- }
- else if (_readPos < _readLength)
- {
- FlushReadBuffer();
- }
- _readPos = 0;
- _readLength = 0;
-
- if (_appendStart != -1 && value < _appendStart)
- throw new IOException(SR.IO_SetLengthAppendTruncate);
- SetLengthCore(value);
- }
-
- // We absolutely need this method broken out so that WriteInternalCoreAsync can call
- // a method without having to go through buffering code that might call FlushWrite.
- private void SetLengthCore(long value)
- {
- Debug.Assert(value >= 0, "value >= 0");
- long origPos = _filePosition;
-
- VerifyOSHandlePosition();
- if (_filePosition != value)
- SeekCore(value, SeekOrigin.Begin);
- if (!Interop.Kernel32.SetEndOfFile(_fileHandle))
- {
- int errorCode = Marshal.GetLastWin32Error();
- if (errorCode == Interop.Errors.ERROR_INVALID_PARAMETER)
- throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_FileLengthTooBig);
- throw Win32Marshal.GetExceptionForWin32Error(errorCode);
- }
- // Return file pointer to where it was before setting length
- if (origPos != value)
- {
- if (origPos < value)
- SeekCore(origPos, SeekOrigin.Begin);
- else
- SeekCore(0, SeekOrigin.End);
- }
- }
-
- // Instance method to help code external to this MarshalByRefObject avoid
- // accessing its fields by ref. This avoids a compiler warning.
- private FileStreamCompletionSource CompareExchangeCurrentOverlappedOwner(FileStreamCompletionSource newSource, FileStreamCompletionSource existingSource) => Interlocked.CompareExchange(ref _currentOverlappedOwner, newSource, existingSource);
-
- public override int Read(byte[] array, int offset, int count)
- {
- ValidateReadWriteArgs(array, offset, count);
- return ReadCore(array, offset, count);
- }
-
- private int ReadCore(byte[] array, int offset, int count)
- {
- Debug.Assert((_readPos == 0 && _readLength == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLength),
- "We're either reading or writing, but not both.");
-
- bool isBlocked = false;
- int n = _readLength - _readPos;
- // if the read buffer is empty, read into either user's array or our
- // buffer, depending on number of bytes user asked for and buffer size.
- if (n == 0)
- {
- if (!CanRead) throw Error.GetReadNotSupported();
- if (_writePos > 0) FlushWriteBuffer();
- if (!CanSeek || (count >= _bufferLength))
- {
- n = ReadNative(array, offset, count);
- // Throw away read buffer.
- _readPos = 0;
- _readLength = 0;
- return n;
- }
- n = ReadNative(GetBuffer(), 0, _bufferLength);
- if (n == 0) return 0;
- isBlocked = n < _bufferLength;
- _readPos = 0;
- _readLength = n;
- }
- // Now copy min of count or numBytesAvailable (i.e. near EOF) to array.
- if (n > count) n = count;
- Buffer.BlockCopy(GetBuffer(), _readPos, array, offset, n);
- _readPos += n;
-
- // We may have read less than the number of bytes the user asked
- // for, but that is part of the Stream contract. Reading again for
- // more data may cause us to block if we're using a device with
- // no clear end of file, such as a serial port or pipe. If we
- // blocked here & this code was used with redirected pipes for a
- // process's standard output, this can lead to deadlocks involving
- // two processes. But leave this here for files to avoid what would
- // probably be a breaking change. --
-
- // If we are reading from a device with no clear EOF like a
- // serial port or a pipe, this will cause us to block incorrectly.
- if (!_isPipe)
- {
- // If we hit the end of the buffer and didn't have enough bytes, we must
- // read some more from the underlying stream. However, if we got
- // fewer bytes from the underlying stream than we asked for (i.e. we're
- // probably blocked), don't ask for more bytes.
- if (n < count && !isBlocked)
- {
- Debug.Assert(_readPos == _readLength, "Read buffer should be empty!");
- int moreBytesRead = ReadNative(array, offset + n, count - n);
- n += moreBytesRead;
- // We've just made our buffer inconsistent with our position
- // pointer. We must throw away the read buffer.
- _readPos = 0;
- _readLength = 0;
- }
- }
-
- return n;
- }
-
- [Conditional("DEBUG")]
- private void AssertCanRead(byte[] buffer, int offset, int count)
- {
- Debug.Assert(!_fileHandle.IsClosed, "!_fileHandle.IsClosed");
- Debug.Assert(CanRead, "CanRead");
- Debug.Assert(buffer != null, "buffer != null");
- Debug.Assert(_writePos == 0, "_writePos == 0");
- Debug.Assert(offset >= 0, "offset is negative");
- Debug.Assert(count >= 0, "count is negative");
- }
-
- private unsafe int ReadNative(byte[] buffer, int offset, int count)
- {
- AssertCanRead(buffer, offset, count);
-
- if (_useAsyncIO)
- return ReadNativeAsync(buffer, offset, count, 0, CancellationToken.None).GetAwaiter().GetResult();
-
- // Make sure we are reading from the right spot
- VerifyOSHandlePosition();
-
- int errorCode = 0;
- int r = ReadFileNative(_fileHandle, buffer, offset, count, null, out errorCode);
-
- if (r == -1)
- {
- // For pipes, ERROR_BROKEN_PIPE is the normal end of the pipe.
- if (errorCode == ERROR_BROKEN_PIPE)
- {
- r = 0;
- }
- else
- {
- if (errorCode == ERROR_INVALID_PARAMETER)
- throw new ArgumentException(SR.Arg_HandleNotSync, "_fileHandle");
-
- throw Win32Marshal.GetExceptionForWin32Error(errorCode);
- }
- }
- Debug.Assert(r >= 0, "FileStream's ReadNative is likely broken.");
- _filePosition += r;
-
- return r;
- }
-
- public override long Seek(long offset, SeekOrigin origin)
- {
- if (origin < SeekOrigin.Begin || origin > SeekOrigin.End)
- throw new ArgumentException(SR.Argument_InvalidSeekOrigin, nameof(origin));
- if (_fileHandle.IsClosed) throw Error.GetFileNotOpen();
- if (!CanSeek) throw Error.GetSeekNotSupported();
-
- Debug.Assert((_readPos == 0 && _readLength == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLength), "We're either reading or writing, but not both.");
-
- // If we've got bytes in our buffer to write, write them out.
- // If we've read in and consumed some bytes, we'll have to adjust
- // our seek positions ONLY IF we're seeking relative to the current
- // position in the stream. This simulates doing a seek to the new
- // position, then a read for the number of bytes we have in our buffer.
- if (_writePos > 0)
- {
- FlushWriteBuffer();
- }
- else if (origin == SeekOrigin.Current)
- {
- // Don't call FlushRead here, which would have caused an infinite
- // loop. Simply adjust the seek origin. This isn't necessary
- // if we're seeking relative to the beginning or end of the stream.
- offset -= (_readLength - _readPos);
- }
- _readPos = _readLength = 0;
-
- // Verify that internal position is in sync with the handle
- VerifyOSHandlePosition();
-
- long oldPos = _filePosition + (_readPos - _readLength);
- long pos = SeekCore(offset, origin);
-
- // Prevent users from overwriting data in a file that was opened in
- // append mode.
- if (_appendStart != -1 && pos < _appendStart)
- {
- SeekCore(oldPos, SeekOrigin.Begin);
- throw new IOException(SR.IO_SeekAppendOverwrite);
- }
-
- // We now must update the read buffer. We can in some cases simply
- // update _readPos within the buffer, copy around the buffer so our
- // Position property is still correct, and avoid having to do more
- // reads from the disk. Otherwise, discard the buffer's contents.
- if (_readLength > 0)
- {
- // We can optimize the following condition:
- // oldPos - _readPos <= pos < oldPos + _readLen - _readPos
- if (oldPos == pos)
- {
- if (_readPos > 0)
- {
- //Console.WriteLine("Seek: seeked for 0, adjusting buffer back by: "+_readPos+" _readLen: "+_readLen);
- Buffer.BlockCopy(GetBuffer(), _readPos, GetBuffer(), 0, _readLength - _readPos);
- _readLength -= _readPos;
- _readPos = 0;
- }
- // If we still have buffered data, we must update the stream's
- // position so our Position property is correct.
- if (_readLength > 0)
- SeekCore(_readLength, SeekOrigin.Current);
- }
- else if (oldPos - _readPos < pos && pos < oldPos + _readLength - _readPos)
- {
- int diff = (int)(pos - oldPos);
- //Console.WriteLine("Seek: diff was "+diff+", readpos was "+_readPos+" adjusting buffer - shrinking by "+ (_readPos + diff));
- Buffer.BlockCopy(GetBuffer(), _readPos + diff, GetBuffer(), 0, _readLength - (_readPos + diff));
- _readLength -= (_readPos + diff);
- _readPos = 0;
- if (_readLength > 0)
- SeekCore(_readLength, SeekOrigin.Current);
- }
- else
- {
- // Lose the read buffer.
- _readPos = 0;
- _readLength = 0;
- }
- Debug.Assert(_readLength >= 0 && _readPos <= _readLength, "_readLen should be nonnegative, and _readPos should be less than or equal _readLen");
- Debug.Assert(pos == Position, "Seek optimization: pos != Position! Buffer math was mangled.");
- }
- return pos;
- }
-
- // This doesn't do argument checking. Necessary for SetLength, which must
- // set the file pointer beyond the end of the file. This will update the
- // internal position
- // This is called during construction so it should avoid any virtual
- // calls
- private long SeekCore(long offset, SeekOrigin origin)
- {
- Debug.Assert(!_fileHandle.IsClosed && _canSeek, "!_handle.IsClosed && _parent.CanSeek");
- Debug.Assert(origin >= SeekOrigin.Begin && origin <= SeekOrigin.End, "origin>=SeekOrigin.Begin && origin<=SeekOrigin.End");
- long ret = 0;
-
- if (!Interop.Kernel32.SetFilePointerEx(_fileHandle, offset, out ret, (uint)origin))
- {
- int errorCode = GetLastWin32ErrorAndDisposeHandleIfInvalid();
- throw Win32Marshal.GetExceptionForWin32Error(errorCode);
- }
-
- _filePosition = ret;
- return ret;
- }
-
- partial void OnBufferAllocated()
- {
- Debug.Assert(_buffer != null);
- Debug.Assert(_preallocatedOverlapped == null);
-
- if (_useAsyncIO)
- _preallocatedOverlapped = new PreAllocatedOverlapped(s_ioCallback, this, _buffer);
- }
-
- public override void Write(byte[] array, int offset, int count)
- {
- ValidateReadWriteArgs(array, offset, count);
-
- if (_writePos == 0)
- {
- // Ensure we can write to the stream, and ready buffer for writing.
- if (!CanWrite) throw Error.GetWriteNotSupported();
- if (_readPos < _readLength) FlushReadBuffer();
- _readPos = 0;
- _readLength = 0;
- }
-
- // If our buffer has data in it, copy data from the user's array into
- // the buffer, and if we can fit it all there, return. Otherwise, write
- // the buffer to disk and copy any remaining data into our buffer.
- // The assumption here is memcpy is cheaper than disk (or net) IO.
- // (10 milliseconds to disk vs. ~20-30 microseconds for a 4K memcpy)
- // So the extra copying will reduce the total number of writes, in
- // non-pathological cases (i.e. write 1 byte, then write for the buffer
- // size repeatedly)
- if (_writePos > 0)
- {
- int numBytes = _bufferLength - _writePos; // space left in buffer
- if (numBytes > 0)
- {
- if (numBytes > count)
- numBytes = count;
- Buffer.BlockCopy(array, offset, GetBuffer(), _writePos, numBytes);
- _writePos += numBytes;
- if (count == numBytes) return;
- offset += numBytes;
- count -= numBytes;
- }
- // Reset our buffer. We essentially want to call FlushWrite
- // without calling Flush on the underlying Stream.
-
- if (_useAsyncIO)
- {
- WriteInternalCoreAsync(GetBuffer(), 0, _writePos, CancellationToken.None).GetAwaiter().GetResult();
- }
- else
- {
- WriteCore(GetBuffer(), 0, _writePos);
- }
- _writePos = 0;
- }
- // If the buffer would slow writes down, avoid buffer completely.
- if (count >= _bufferLength)
- {
- Debug.Assert(_writePos == 0, "FileStream cannot have buffered data to write here! Your stream will be corrupted.");
- WriteCore(array, offset, count);
- return;
- }
- else if (count == 0)
- {
- return; // Don't allocate a buffer then call memcpy for 0 bytes.
- }
-
- // Copy remaining bytes into buffer, to write at a later date.
- Buffer.BlockCopy(array, offset, GetBuffer(), _writePos, count);
- _writePos = count;
- return;
- }
-
- private unsafe void WriteCore(byte[] buffer, int offset, int count)
- {
- Debug.Assert(!_fileHandle.IsClosed, "!_handle.IsClosed");
- Debug.Assert(CanWrite, "_parent.CanWrite");
-
- Debug.Assert(buffer != null, "buffer != null");
- Debug.Assert(_readPos == _readLength, "_readPos == _readLen");
- Debug.Assert(offset >= 0, "offset is negative");
- Debug.Assert(count >= 0, "count is negative");
- if (_useAsyncIO)
- {
- WriteInternalCoreAsync(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult();
- return;
- }
-
- // Make sure we are writing to the position that we think we are
- VerifyOSHandlePosition();
-
- int errorCode = 0;
- int r = WriteFileNative(_fileHandle, buffer, offset, count, null, out errorCode);
-
- if (r == -1)
- {
- // For pipes, ERROR_NO_DATA is not an error, but the pipe is closing.
- if (errorCode == ERROR_NO_DATA)
- {
- r = 0;
- }
- else
- {
- // ERROR_INVALID_PARAMETER may be returned for writes
- // where the position is too large (i.e. writing at Int64.MaxValue
- // on Win9x) OR for synchronous writes to a handle opened
- // asynchronously.
- if (errorCode == ERROR_INVALID_PARAMETER)
- throw new IOException(SR.IO_FileTooLongOrHandleNotSync);
- throw Win32Marshal.GetExceptionForWin32Error(errorCode);
- }
- }
- Debug.Assert(r >= 0, "FileStream's WriteCore is likely broken.");
- _filePosition += r;
- return;
- }
-
- private Task<int> ReadAsyncInternal(byte[] array, int offset, int numBytes, CancellationToken cancellationToken)
- {
- // If async IO is not supported on this platform or
- // if this Win32FileStream was not opened with FileOptions.Asynchronous.
- if (!_useAsyncIO)
- {
- return base.ReadAsync(array, offset, numBytes, cancellationToken);
- }
-
- if (!CanRead) throw Error.GetReadNotSupported();
-
- Debug.Assert((_readPos == 0 && _readLength == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLength), "We're either reading or writing, but not both.");
-
- if (_isPipe)
- {
- // Pipes are tricky, at least when you have 2 different pipes
- // that you want to use simultaneously. When redirecting stdout
- // & stderr with the Process class, it's easy to deadlock your
- // parent & child processes when doing writes 4K at a time. The
- // OS appears to use a 4K buffer internally. If you write to a
- // pipe that is full, you will block until someone read from
- // that pipe. If you try reading from an empty pipe and
- // Win32FileStream's ReadAsync blocks waiting for data to fill it's
- // internal buffer, you will be blocked. In a case where a child
- // process writes to stdout & stderr while a parent process tries
- // reading from both, you can easily get into a deadlock here.
- // To avoid this deadlock, don't buffer when doing async IO on
- // pipes. But don't completely ignore buffered data either.
- if (_readPos < _readLength)
- {
- int n = _readLength - _readPos;
- if (n > numBytes) n = numBytes;
- Buffer.BlockCopy(GetBuffer(), _readPos, array, offset, n);
- _readPos += n;
-
- // Return a completed task
- return TaskFromResultOrCache(n);
- }
- else
- {
- Debug.Assert(_writePos == 0, "Win32FileStream must not have buffered write data here! Pipes should be unidirectional.");
- return ReadNativeAsync(array, offset, numBytes, 0, cancellationToken);
- }
- }
-
- Debug.Assert(!_isPipe, "Should not be a pipe.");
-
- // Handle buffering.
- if (_writePos > 0) FlushWriteBuffer();
- if (_readPos == _readLength)
- {
- // I can't see how to handle buffering of async requests when
- // filling the buffer asynchronously, without a lot of complexity.
- // The problems I see are issuing an async read, we do an async
- // read to fill the buffer, then someone issues another read
- // (either synchronously or asynchronously) before the first one
- // returns. This would involve some sort of complex buffer locking
- // that we probably don't want to get into, at least not in V1.
- // If we did a sync read to fill the buffer, we could avoid the
- // problem, and any async read less than 64K gets turned into a
- // synchronous read by NT anyways... --
-
- if (numBytes < _bufferLength)
- {
- Task<int> readTask = ReadNativeAsync(GetBuffer(), 0, _bufferLength, 0, cancellationToken);
- _readLength = readTask.GetAwaiter().GetResult();
- int n = _readLength;
- if (n > numBytes) n = numBytes;
- Buffer.BlockCopy(GetBuffer(), 0, array, offset, n);
- _readPos = n;
-
- // Return a completed task (recycling the one above if possible)
- return (_readLength == n ? readTask : TaskFromResultOrCache(n));
- }
- else
- {
- // Here we're making our position pointer inconsistent
- // with our read buffer. Throw away the read buffer's contents.
- _readPos = 0;
- _readLength = 0;
- return ReadNativeAsync(array, offset, numBytes, 0, cancellationToken);
- }
- }
- else
- {
- int n = _readLength - _readPos;
- if (n > numBytes) n = numBytes;
- Buffer.BlockCopy(GetBuffer(), _readPos, array, offset, n);
- _readPos += n;
-
- if (n >= numBytes)
- {
- // Return a completed task
- return TaskFromResultOrCache(n);
- }
- else
- {
- // For streams with no clear EOF like serial ports or pipes
- // we cannot read more data without causing an app to block
- // incorrectly. Pipes don't go down this path
- // though. This code needs to be fixed.
- // Throw away read buffer.
- _readPos = 0;
- _readLength = 0;
- return ReadNativeAsync(array, offset + n, numBytes - n, n, cancellationToken);
- }
- }
- }
-
- unsafe private Task<int> ReadNativeAsync(byte[] bytes, int offset, int numBytes, int numBufferedBytesRead, CancellationToken cancellationToken)
- {
- AssertCanRead(bytes, offset, numBytes);
- Debug.Assert(_useAsyncIO, "ReadNativeAsync doesn't work on synchronous file streams!");
-
- // Create and store async stream class library specific data in the async result
-
- FileStreamCompletionSource completionSource = new FileStreamCompletionSource(this, numBufferedBytesRead, bytes, cancellationToken);
- NativeOverlapped* intOverlapped = completionSource.Overlapped;
-
- // Calculate position in the file we should be at after the read is done
- if (CanSeek)
- {
- long len = Length;
-
- // Make sure we are reading from the position that we think we are
- VerifyOSHandlePosition();
-
- if (_filePosition + numBytes > len)
- {
- if (_filePosition <= len)
- numBytes = (int)(len - _filePosition);
- else
- numBytes = 0;
- }
-
- // Now set the position to read from in the NativeOverlapped struct
- // For pipes, we should leave the offset fields set to 0.
- intOverlapped->OffsetLow = unchecked((int)_filePosition);
- intOverlapped->OffsetHigh = (int)(_filePosition >> 32);
-
- // When using overlapped IO, the OS is not supposed to
- // touch the file pointer location at all. We will adjust it
- // ourselves. This isn't threadsafe.
-
- // WriteFile should not update the file pointer when writing
- // in overlapped mode, according to MSDN. But it does update
- // the file pointer when writing to a UNC path!
- // So changed the code below to seek to an absolute
- // location, not a relative one. ReadFile seems consistent though.
- SeekCore(numBytes, SeekOrigin.Current);
- }
-
- // queue an async ReadFile operation and pass in a packed overlapped
- int errorCode = 0;
- int r = ReadFileNative(_fileHandle, bytes, offset, numBytes, intOverlapped, out errorCode);
- // ReadFile, the OS version, will return 0 on failure. But
- // my ReadFileNative wrapper returns -1. My wrapper will return
- // the following:
- // On error, r==-1.
- // On async requests that are still pending, r==-1 w/ errorCode==ERROR_IO_PENDING
- // on async requests that completed sequentially, r==0
- // You will NEVER RELIABLY be able to get the number of bytes
- // read back from this call when using overlapped structures! You must
- // not pass in a non-null lpNumBytesRead to ReadFile when using
- // overlapped structures! This is by design NT behavior.
- if (r == -1 && numBytes != -1)
- {
- // For pipes, when they hit EOF, they will come here.
- if (errorCode == ERROR_BROKEN_PIPE)
- {
- // Not an error, but EOF. AsyncFSCallback will NOT be
- // called. Call the user callback here.
-
- // We clear the overlapped status bit for this special case.
- // Failure to do so looks like we are freeing a pending overlapped later.
- intOverlapped->InternalLow = IntPtr.Zero;
- completionSource.SetCompletedSynchronously(0);
- }
- else if (errorCode != ERROR_IO_PENDING)
- {
- if (!_fileHandle.IsClosed && CanSeek) // Update Position - It could be anywhere.
- {
- SeekCore(0, SeekOrigin.Current);
- }
-
- completionSource.ReleaseNativeResource();
-
- if (errorCode == ERROR_HANDLE_EOF)
- {
- throw Error.GetEndOfFile();
- }
- else
- {
- throw Win32Marshal.GetExceptionForWin32Error(errorCode);
- }
- }
- else
- {
- // Only once the IO is pending do we register for cancellation
- completionSource.RegisterForCancellation();
- }
- }
- else
- {
- // Due to a workaround for a race condition in NT's ReadFile &
- // WriteFile routines, we will always be returning 0 from ReadFileNative
- // when we do async IO instead of the number of bytes read,
- // irregardless of whether the operation completed
- // synchronously or asynchronously. We absolutely must not
- // set asyncResult._numBytes here, since will never have correct
- // results.
- //Console.WriteLine("ReadFile returned: "+r+" (0x"+Int32.Format(r, "x")+") The IO completed synchronously, but the user callback was called on a separate thread");
- }
-
- return completionSource.Task;
- }
-
- // Reads a byte from the file stream. Returns the byte cast to an int
- // or -1 if reading from the end of the stream.
- public override int ReadByte()
- {
- return ReadByteCore();
- }
-
- private Task WriteAsyncInternal(byte[] array, int offset, int numBytes, CancellationToken cancellationToken)
- {
- // If async IO is not supported on this platform or
- // if this Win32FileStream was not opened with FileOptions.Asynchronous.
- if (!_useAsyncIO)
- {
- return base.WriteAsync(array, offset, numBytes, cancellationToken);
- }
-
- if (!CanWrite) throw Error.GetWriteNotSupported();
-
- Debug.Assert((_readPos == 0 && _readLength == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLength), "We're either reading or writing, but not both.");
- Debug.Assert(!_isPipe || (_readPos == 0 && _readLength == 0), "Win32FileStream must not have buffered data here! Pipes should be unidirectional.");
-
- bool writeDataStoredInBuffer = false;
- if (!_isPipe) // avoid async buffering with pipes, as doing so can lead to deadlocks (see comments in ReadInternalAsyncCore)
- {
- // Ensure the buffer is clear for writing
- if (_writePos == 0)
- {
- if (_readPos < _readLength)
- {
- FlushReadBuffer();
- }
- _readPos = 0;
- _readLength = 0;
- }
-
- // Determine how much space remains in the buffer
- int remainingBuffer = _bufferLength - _writePos;
- Debug.Assert(remainingBuffer >= 0);
-
- // Simple/common case:
- // - The write is smaller than our buffer, such that it's worth considering buffering it.
- // - There's no active flush operation, such that we don't have to worry about the existing buffer being in use.
- // - And the data we're trying to write fits in the buffer, meaning it wasn't already filled by previous writes.
- // In that case, just store it in the buffer.
- if (numBytes < _bufferLength && !HasActiveBufferOperation && numBytes <= remainingBuffer)
- {
- Buffer.BlockCopy(array, offset, GetBuffer(), _writePos, numBytes);
- _writePos += numBytes;
- writeDataStoredInBuffer = true;
-
- // There is one special-but-common case, common because devs often use
- // byte[] sizes that are powers of 2 and thus fit nicely into our buffer, which is
- // also a power of 2. If after our write the buffer still has remaining space,
- // then we're done and can return a completed task now. But if we filled the buffer
- // completely, we want to do the asynchronous flush/write as part of this operation
- // rather than waiting until the next write that fills the buffer.
- if (numBytes != remainingBuffer)
- return Task.CompletedTask;
-
- Debug.Assert(_writePos == _bufferLength);
- }
- }
-
- // At this point, at least one of the following is true:
- // 1. There was an active flush operation (it could have completed by now, though).
- // 2. The data doesn't fit in the remaining buffer (or it's a pipe and we chose not to try).
- // 3. We wrote all of the data to the buffer, filling it.
- //
- // If there's an active operation, we can't touch the current buffer because it's in use.
- // That gives us a choice: we can either allocate a new buffer, or we can skip the buffer
- // entirely (even if the data would otherwise fit in it). For now, for simplicity, we do
- // the latter; it could also have performance wins due to OS-level optimizations, and we could
- // potentially add support for PreAllocatedOverlapped due to having a single buffer. (We can
- // switch to allocating a new buffer, potentially experimenting with buffer pooling, should
- // performance data suggest it's appropriate.)
- //
- // If the data doesn't fit in the remaining buffer, it could be because it's so large
- // it's greater than the entire buffer size, in which case we'd always skip the buffer,
- // or it could be because there's more data than just the space remaining. For the latter
- // case, we need to issue an asynchronous write to flush that data, which then turns this into
- // the first case above with an active operation.
- //
- // If we already stored the data, then we have nothing additional to write beyond what
- // we need to flush.
- //
- // In any of these cases, we have the same outcome:
- // - If there's data in the buffer, flush it by writing it out asynchronously.
- // - Then, if there's any data to be written, issue a write for it concurrently.
- // We return a Task that represents one or both.
-
- // Flush the buffer asynchronously if there's anything to flush
- Task flushTask = null;
- if (_writePos > 0)
- {
- flushTask = FlushWriteAsync(cancellationToken);
-
- // If we already copied all of the data into the buffer,
- // simply return the flush task here. Same goes for if the task has
- // already completed and was unsuccessful.
- if (writeDataStoredInBuffer ||
- flushTask.IsFaulted ||
- flushTask.IsCanceled)
- {
- return flushTask;
- }
- }
-
- Debug.Assert(!writeDataStoredInBuffer);
- Debug.Assert(_writePos == 0);
-
- // Finally, issue the write asynchronously, and return a Task that logically
- // represents the write operation, including any flushing done.
- Task writeTask = WriteInternalCoreAsync(array, offset, numBytes, cancellationToken);
- return
- (flushTask == null || flushTask.Status == TaskStatus.RanToCompletion) ? writeTask :
- (writeTask.Status == TaskStatus.RanToCompletion) ? flushTask :
- Task.WhenAll(flushTask, writeTask);
- }
-
- private unsafe Task WriteInternalCoreAsync(byte[] bytes, int offset, int numBytes, CancellationToken cancellationToken)
- {
- Debug.Assert(!_fileHandle.IsClosed, "!_handle.IsClosed");
- Debug.Assert(CanWrite, "_parent.CanWrite");
- Debug.Assert(bytes != null, "bytes != null");
- Debug.Assert(_readPos == _readLength, "_readPos == _readLen");
- Debug.Assert(_useAsyncIO, "WriteInternalCoreAsync doesn't work on synchronous file streams!");
- Debug.Assert(offset >= 0, "offset is negative");
- Debug.Assert(numBytes >= 0, "numBytes is negative");
-
- // Create and store async stream class library specific data in the async result
- FileStreamCompletionSource completionSource = new FileStreamCompletionSource(this, 0, bytes, cancellationToken);
- NativeOverlapped* intOverlapped = completionSource.Overlapped;
-
- if (CanSeek)
- {
- // Make sure we set the length of the file appropriately.
- long len = Length;
- //Console.WriteLine("WriteInternalCoreAsync - Calculating end pos. pos: "+pos+" len: "+len+" numBytes: "+numBytes);
-
- // Make sure we are writing to the position that we think we are
- VerifyOSHandlePosition();
-
- if (_filePosition + numBytes > len)
- {
- //Console.WriteLine("WriteInternalCoreAsync - Setting length to: "+(pos + numBytes));
- SetLengthCore(_filePosition + numBytes);
- }
-
- // Now set the position to read from in the NativeOverlapped struct
- // For pipes, we should leave the offset fields set to 0.
- intOverlapped->OffsetLow = (int)_filePosition;
- intOverlapped->OffsetHigh = (int)(_filePosition >> 32);
-
- // When using overlapped IO, the OS is not supposed to
- // touch the file pointer location at all. We will adjust it
- // ourselves. This isn't threadsafe.
- SeekCore(numBytes, SeekOrigin.Current);
- }
-
- //Console.WriteLine("WriteInternalCoreAsync finishing. pos: "+pos+" numBytes: "+numBytes+" _pos: "+_pos+" Position: "+Position);
-
- int errorCode = 0;
- // queue an async WriteFile operation and pass in a packed overlapped
- int r = WriteFileNative(_fileHandle, bytes, offset, numBytes, intOverlapped, out errorCode);
-
- // WriteFile, the OS version, will return 0 on failure. But
- // my WriteFileNative wrapper returns -1. My wrapper will return
- // the following:
- // On error, r==-1.
- // On async requests that are still pending, r==-1 w/ errorCode==ERROR_IO_PENDING
- // On async requests that completed sequentially, r==0
- // You will NEVER RELIABLY be able to get the number of bytes
- // written back from this call when using overlapped IO! You must
- // not pass in a non-null lpNumBytesWritten to WriteFile when using
- // overlapped structures! This is ByDesign NT behavior.
- if (r == -1 && numBytes != -1)
- {
- //Console.WriteLine("WriteFile returned 0; Write will complete asynchronously (if errorCode==3e5) errorCode: 0x{0:x}", errorCode);
-
- // For pipes, when they are closed on the other side, they will come here.
- if (errorCode == ERROR_NO_DATA)
- {
- // Not an error, but EOF. AsyncFSCallback will NOT be called.
- // Completing TCS and return cached task allowing the GC to collect TCS.
- completionSource.SetCompletedSynchronously(0);
- return Task.CompletedTask;
- }
- else if (errorCode != ERROR_IO_PENDING)
- {
- if (!_fileHandle.IsClosed && CanSeek) // Update Position - It could be anywhere.
- {
- SeekCore(0, SeekOrigin.Current);
- }
-
- completionSource.ReleaseNativeResource();
-
- if (errorCode == ERROR_HANDLE_EOF)
- {
- throw Error.GetEndOfFile();
- }
- else
- {
- throw Win32Marshal.GetExceptionForWin32Error(errorCode);
- }
- }
- else // ERROR_IO_PENDING
- {
- // Only once the IO is pending do we register for cancellation
- completionSource.RegisterForCancellation();
- }
- }
- else
- {
- // Due to a workaround for a race condition in NT's ReadFile &
- // WriteFile routines, we will always be returning 0 from WriteFileNative
- // when we do async IO instead of the number of bytes written,
- // irregardless of whether the operation completed
- // synchronously or asynchronously. We absolutely must not
- // set asyncResult._numBytes here, since will never have correct
- // results.
- //Console.WriteLine("WriteFile returned: "+r+" (0x"+Int32.Format(r, "x")+") The IO completed synchronously, but the user callback was called on another thread.");
- }
-
- return completionSource.Task;
- }
-
- public override void WriteByte(byte value)
- {
- WriteByteCore(value);
- }
-
- // Windows API definitions, from winbase.h and others
-
- private const int FILE_ATTRIBUTE_NORMAL = 0x00000080;
- private const int FILE_ATTRIBUTE_ENCRYPTED = 0x00004000;
- private const int FILE_FLAG_OVERLAPPED = 0x40000000;
- internal const int GENERIC_READ = unchecked((int)0x80000000);
- private const int GENERIC_WRITE = 0x40000000;
-
- private const int FILE_BEGIN = 0;
- private const int FILE_CURRENT = 1;
- private const int FILE_END = 2;
-
- // Error codes (not HRESULTS), from winerror.h
- internal const int ERROR_BROKEN_PIPE = 109;
- internal const int ERROR_NO_DATA = 232;
- private const int ERROR_HANDLE_EOF = 38;
- private const int ERROR_INVALID_PARAMETER = 87;
- private const int ERROR_IO_PENDING = 997;
-
- // __ConsoleStream also uses this code.
- private unsafe int ReadFileNative(SafeFileHandle handle, byte[] bytes, int offset, int count, NativeOverlapped* overlapped, out int errorCode)
- {
- Debug.Assert(handle != null, "handle != null");
- Debug.Assert(offset >= 0, "offset >= 0");
- Debug.Assert(count >= 0, "count >= 0");
- Debug.Assert(bytes != null, "bytes != null");
- // Don't corrupt memory when multiple threads are erroneously writing
- // to this stream simultaneously.
- if (bytes.Length - offset < count)
- throw new IndexOutOfRangeException(SR.IndexOutOfRange_IORaceCondition);
-
- Debug.Assert((_useAsyncIO && overlapped != null) || (!_useAsyncIO && overlapped == null), "Async IO and overlapped parameters inconsistent in call to ReadFileNative.");
-
- // You can't use the fixed statement on an array of length 0.
- if (bytes.Length == 0)
- {
- errorCode = 0;
- return 0;
- }
-
- int r = 0;
- int numBytesRead = 0;
-
- fixed (byte* p = &bytes[0])
- {
- if (_useAsyncIO)
- r = Interop.Kernel32.ReadFile(handle, p + offset, count, IntPtr.Zero, overlapped);
- else
- r = Interop.Kernel32.ReadFile(handle, p + offset, count, out numBytesRead, IntPtr.Zero);
- }
-
- if (r == 0)
- {
- errorCode = GetLastWin32ErrorAndDisposeHandleIfInvalid();
- return -1;
- }
- else
- {
- errorCode = 0;
- return numBytesRead;
- }
- }
-
- private unsafe int WriteFileNative(SafeFileHandle handle, byte[] bytes, int offset, int count, NativeOverlapped* overlapped, out int errorCode)
- {
- Debug.Assert(handle != null, "handle != null");
- Debug.Assert(offset >= 0, "offset >= 0");
- Debug.Assert(count >= 0, "count >= 0");
- Debug.Assert(bytes != null, "bytes != null");
- // Don't corrupt memory when multiple threads are erroneously writing
- // to this stream simultaneously. (the OS is reading from
- // the array we pass to WriteFile, but if we read beyond the end and
- // that memory isn't allocated, we could get an AV.)
- if (bytes.Length - offset < count)
- throw new IndexOutOfRangeException(SR.IndexOutOfRange_IORaceCondition);
-
- Debug.Assert((_useAsyncIO && overlapped != null) || (!_useAsyncIO && overlapped == null), "Async IO and overlapped parameters inconsistent in call to WriteFileNative.");
-
- // You can't use the fixed statement on an array of length 0.
- if (bytes.Length == 0)
- {
- errorCode = 0;
- return 0;
- }
-
- int numBytesWritten = 0;
- int r = 0;
-
- fixed (byte* p = &bytes[0])
- {
- if (_useAsyncIO)
- r = Interop.Kernel32.WriteFile(handle, p + offset, count, IntPtr.Zero, overlapped);
- else
- r = Interop.Kernel32.WriteFile(handle, p + offset, count, out numBytesWritten, IntPtr.Zero);
- }
-
- if (r == 0)
- {
- errorCode = GetLastWin32ErrorAndDisposeHandleIfInvalid();
- return -1;
- }
- else
- {
- errorCode = 0;
- return numBytesWritten;
- }
- }
-
- private int GetLastWin32ErrorAndDisposeHandleIfInvalid(bool throwIfInvalidHandle = false)
- {
- int errorCode = Marshal.GetLastWin32Error();
-
- // If ERROR_INVALID_HANDLE is returned, it doesn't suffice to set
- // the handle as invalid; the handle must also be closed.
- //
- // Marking the handle as invalid but not closing the handle
- // resulted in exceptions during finalization and locked column
- // values (due to invalid but unclosed handle) in SQL Win32FileStream
- // scenarios.
- //
- // A more mainstream scenario involves accessing a file on a
- // network share. ERROR_INVALID_HANDLE may occur because the network
- // connection was dropped and the server closed the handle. However,
- // the client side handle is still open and even valid for certain
- // operations.
- //
- // Note that _parent.Dispose doesn't throw so we don't need to special case.
- // SetHandleAsInvalid only sets _closed field to true (without
- // actually closing handle) so we don't need to call that as well.
- if (errorCode == Interop.Errors.ERROR_INVALID_HANDLE)
- {
- _fileHandle.Dispose();
-
- if (throwIfInvalidHandle)
- throw Win32Marshal.GetExceptionForWin32Error(errorCode);
- }
-
- return errorCode;
- }
-
- public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
- {
- // If we're in sync mode, just use the shared CopyToAsync implementation that does
- // typical read/write looping. We also need to take this path if this is a derived
- // instance from FileStream, as a derived type could have overridden ReadAsync, in which
- // case our custom CopyToAsync implementation isn't necessarily correct.
- if (!_useAsyncIO || GetType() != typeof(FileStream))
- {
- return base.CopyToAsync(destination, bufferSize, cancellationToken);
- }
-
- StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize);
-
- // Bail early for cancellation if cancellation has been requested
- if (cancellationToken.IsCancellationRequested)
- {
- return Task.FromCanceled<int>(cancellationToken);
- }
-
- // Fail if the file was closed
- if (_fileHandle.IsClosed)
- {
- throw Error.GetFileNotOpen();
- }
-
- // Do the async copy, with differing implementations based on whether the FileStream was opened as async or sync
- Debug.Assert((_readPos == 0 && _readLength == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLength), "We're either reading or writing, but not both.");
- return AsyncModeCopyToAsync(destination, bufferSize, cancellationToken);
- }
-
- private async Task AsyncModeCopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
- {
- Debug.Assert(_useAsyncIO, "This implementation is for async mode only");
- Debug.Assert(!_fileHandle.IsClosed, "!_handle.IsClosed");
- Debug.Assert(CanRead, "_parent.CanRead");
-
- // Make sure any pending writes have been flushed before we do a read.
- if (_writePos > 0)
- {
- await FlushWriteAsync(cancellationToken).ConfigureAwait(false);
- }
-
- // Typically CopyToAsync would be invoked as the only "read" on the stream, but it's possible some reading is
- // done and then the CopyToAsync is issued. For that case, see if we have any data available in the buffer.
- if (GetBuffer() != null)
- {
- int bufferedBytes = _readLength - _readPos;
- if (bufferedBytes > 0)
- {
- await destination.WriteAsync(GetBuffer(), _readPos, bufferedBytes, cancellationToken).ConfigureAwait(false);
- _readPos = _readLength = 0;
- }
- }
-
- // For efficiency, we avoid creating a new task and associated state for each asynchronous read.
- // Instead, we create a single reusable awaitable object that will be triggered when an await completes
- // and reset before going again.
- var readAwaitable = new AsyncCopyToAwaitable(this);
-
- // Make sure we are reading from the position that we think we are.
- // Only set the position in the awaitable if we can seek (e.g. not for pipes).
- bool canSeek = CanSeek;
- if (canSeek)
- {
- VerifyOSHandlePosition();
- readAwaitable._position = _filePosition;
- }
-
- // Get the buffer to use for the copy operation, as the base CopyToAsync does. We don't try to use
- // _buffer here, even if it's not null, as concurrent operations are allowed, and another operation may
- // actually be using the buffer already. Plus, it'll be rare for _buffer to be non-null, as typically
- // CopyToAsync is used as the only operation performed on the stream, and the buffer is lazily initialized.
- // Further, typically the CopyToAsync buffer size will be larger than that used by the FileStream, such that
- // we'd likely be unable to use it anyway. Instead, we rent the buffer from a pool.
- byte[] copyBuffer = ArrayPool<byte>.Shared.Rent(bufferSize);
- bufferSize = 0; // repurpose bufferSize to be the high water mark for the buffer, to avoid an extra field in the state machine
-
- // Allocate an Overlapped we can use repeatedly for all operations
- var awaitableOverlapped = new PreAllocatedOverlapped(AsyncCopyToAwaitable.s_callback, readAwaitable, copyBuffer);
- var cancellationReg = default(CancellationTokenRegistration);
- try
- {
- // Register for cancellation. We do this once for the whole copy operation, and just try to cancel
- // whatever read operation may currently be in progress, if there is one. It's possible the cancellation
- // request could come in between operations, in which case we flag that with explicit calls to ThrowIfCancellationRequested
- // in the read/write copy loop.
- if (cancellationToken.CanBeCanceled)
- {
- cancellationReg = cancellationToken.Register(s =>
- {
- var innerAwaitable = (AsyncCopyToAwaitable)s;
- unsafe
- {
- lock (innerAwaitable.CancellationLock) // synchronize with cleanup of the overlapped
- {
- if (innerAwaitable._nativeOverlapped != null)
- {
- // Try to cancel the I/O. We ignore the return value, as cancellation is opportunistic and we
- // don't want to fail the operation because we couldn't cancel it.
- Interop.Kernel32.CancelIoEx(innerAwaitable._fileStream._fileHandle, innerAwaitable._nativeOverlapped);
- }
- }
- }
- }, readAwaitable);
- }
-
- // Repeatedly read from this FileStream and write the results to the destination stream.
- while (true)
- {
- cancellationToken.ThrowIfCancellationRequested();
- readAwaitable.ResetForNextOperation();
-
- try
- {
- bool synchronousSuccess;
- int errorCode;
- unsafe
- {
- // Allocate a native overlapped for our reusable overlapped, and set position to read based on the next
- // desired address stored in the awaitable. (This position may be 0, if either we're at the beginning or
- // if the stream isn't seekable.)
- readAwaitable._nativeOverlapped = _fileHandle.ThreadPoolBinding.AllocateNativeOverlapped(awaitableOverlapped);
- if (canSeek)
- {
- readAwaitable._nativeOverlapped->OffsetLow = unchecked((int)readAwaitable._position);
- readAwaitable._nativeOverlapped->OffsetHigh = (int)(readAwaitable._position >> 32);
- }
-
- // Kick off the read.
- synchronousSuccess = ReadFileNative(_fileHandle, copyBuffer, 0, copyBuffer.Length, readAwaitable._nativeOverlapped, out errorCode) >= 0;
- }
-
- // If the operation did not synchronously succeed, it either failed or initiated the asynchronous operation.
- if (!synchronousSuccess)
- {
- switch (errorCode)
- {
- case ERROR_IO_PENDING:
- // Async operation in progress.
- break;
- case ERROR_BROKEN_PIPE:
- case ERROR_HANDLE_EOF:
- // We're at or past the end of the file, and the overlapped callback
- // won't be raised in these cases. Mark it as completed so that the await
- // below will see it as such.
- readAwaitable.MarkCompleted();
- break;
- default:
- // Everything else is an error (and there won't be a callback).
- throw Win32Marshal.GetExceptionForWin32Error(errorCode);
- }
- }
-
- // Wait for the async operation (which may or may not have already completed), then throw if it failed.
- await readAwaitable;
- switch (readAwaitable._errorCode)
- {
- case 0: // success
- Debug.Assert(readAwaitable._numBytes >= 0, $"Expected non-negative numBytes, got {readAwaitable._numBytes}");
- break;
- case ERROR_BROKEN_PIPE: // logically success with 0 bytes read (write end of pipe closed)
- case ERROR_HANDLE_EOF: // logically success with 0 bytes read (read at end of file)
- Debug.Assert(readAwaitable._numBytes == 0, $"Expected 0 bytes read, got {readAwaitable._numBytes}");
- break;
- case Interop.Errors.ERROR_OPERATION_ABORTED: // canceled
- throw new OperationCanceledException(cancellationToken.IsCancellationRequested ? cancellationToken : new CancellationToken(true));
- default: // error
- throw Win32Marshal.GetExceptionForWin32Error((int)readAwaitable._errorCode);
- }
-
- // Successful operation. If we got zero bytes, we're done: exit the read/write loop.
- int numBytesRead = (int)readAwaitable._numBytes;
- if (numBytesRead == 0)
- {
- break;
- }
-
- // Otherwise, update the read position for next time accordingly.
- if (canSeek)
- {
- readAwaitable._position += numBytesRead;
- }
-
- // (and keep track of the maximum number of bytes in the buffer we used, to avoid excessive and unnecessary
- // clearing of the buffer before we return it to the pool)
- if (numBytesRead > bufferSize)
- {
- bufferSize = numBytesRead;
- }
- }
- finally
- {
- // Free the resources for this read operation
- unsafe
- {
- NativeOverlapped* overlapped;
- lock (readAwaitable.CancellationLock) // just an Exchange, but we need this to be synchronized with cancellation, so using the same lock
- {
- overlapped = readAwaitable._nativeOverlapped;
- readAwaitable._nativeOverlapped = null;
- }
- if (overlapped != null)
- {
- _fileHandle.ThreadPoolBinding.FreeNativeOverlapped(overlapped);
- }
- }
- }
-
- // Write out the read data.
- await destination.WriteAsync(copyBuffer, 0, (int)readAwaitable._numBytes, cancellationToken).ConfigureAwait(false);
- }
- }
- finally
- {
- // Cleanup from the whole copy operation
- cancellationReg.Dispose();
- awaitableOverlapped.Dispose();
-
- Array.Clear(copyBuffer, 0, bufferSize);
- ArrayPool<byte>.Shared.Return(copyBuffer, clearArray: false);
-
- // Make sure the stream's current position reflects where we ended up
- if (!_fileHandle.IsClosed && CanSeek)
- {
- SeekCore(0, SeekOrigin.End);
- }
- }
- }
-
- /// <summary>Used by CopyToAsync to enable awaiting the result of an overlapped I/O operation with minimal overhead.</summary>
- private sealed unsafe class AsyncCopyToAwaitable : ICriticalNotifyCompletion
- {
- /// <summary>Sentinel object used to indicate that the I/O operation has completed before being awaited.</summary>
- private readonly static Action s_sentinel = () => { };
- /// <summary>Cached delegate to IOCallback.</summary>
- internal static readonly IOCompletionCallback s_callback = IOCallback;
-
- /// <summary>The FileStream that owns this instance.</summary>
- internal readonly FileStream _fileStream;
-
- /// <summary>Tracked position representing the next location from which to read.</summary>
- internal long _position;
- /// <summary>The current native overlapped pointer. This changes for each operation.</summary>
- internal NativeOverlapped* _nativeOverlapped;
- /// <summary>
- /// null if the operation is still in progress,
- /// s_sentinel if the I/O operation completed before the await,
- /// s_callback if it completed after the await yielded.
- /// </summary>
- internal Action _continuation;
- /// <summary>Last error code from completed operation.</summary>
- internal uint _errorCode;
- /// <summary>Last number of read bytes from completed operation.</summary>
- internal uint _numBytes;
-
- /// <summary>Lock object used to protect cancellation-related access to _nativeOverlapped.</summary>
- internal object CancellationLock => this;
-
- /// <summary>Initialize the awaitable.</summary>
- internal unsafe AsyncCopyToAwaitable(FileStream fileStream)
- {
- _fileStream = fileStream;
- }
-
- /// <summary>Reset state to prepare for the next read operation.</summary>
- internal void ResetForNextOperation()
- {
- Debug.Assert(_position >= 0, $"Expected non-negative position, got {_position}");
- _continuation = null;
- _errorCode = 0;
- _numBytes = 0;
- }
-
- /// <summary>Overlapped callback: store the results, then invoke the continuation delegate.</summary>
- internal unsafe static void IOCallback(uint errorCode, uint numBytes, NativeOverlapped* pOVERLAP)
- {
- var awaitable = (AsyncCopyToAwaitable)ThreadPoolBoundHandle.GetNativeOverlappedState(pOVERLAP);
-
- Debug.Assert(awaitable._continuation != s_sentinel, "Sentinel must not have already been set as the continuation");
- awaitable._errorCode = errorCode;
- awaitable._numBytes = numBytes;
-
- (awaitable._continuation ?? Interlocked.CompareExchange(ref awaitable._continuation, s_sentinel, null))?.Invoke();
- }
-
- /// <summary>
- /// Called when it's known that the I/O callback for an operation will not be invoked but we'll
- /// still be awaiting the awaitable.
- /// </summary>
- internal void MarkCompleted()
- {
- Debug.Assert(_continuation == null, "Expected null continuation");
- _continuation = s_sentinel;
- }
-
- public AsyncCopyToAwaitable GetAwaiter() => this;
- public bool IsCompleted => _continuation == s_sentinel;
- public void GetResult() { }
- public void OnCompleted(Action continuation) => UnsafeOnCompleted(continuation);
- public void UnsafeOnCompleted(Action continuation)
- {
- if (_continuation == s_sentinel ||
- Interlocked.CompareExchange(ref _continuation, continuation, null) != null)
- {
- Debug.Assert(_continuation == s_sentinel, $"Expected continuation set to s_sentinel, got ${_continuation}");
- Task.Run(continuation);
- }
- }
- }
-
- // Unlike Flush(), FlushAsync() always flushes to disk. This is intentional.
- // Legend is that we chose not to flush the OS file buffers in Flush() in fear of
- // perf problems with frequent, long running FlushFileBuffers() calls. But we don't
- // have that problem with FlushAsync() because we will call FlushFileBuffers() in the background.
- private Task FlushAsyncInternal(CancellationToken cancellationToken)
- {
- if (cancellationToken.IsCancellationRequested)
- return Task.FromCanceled(cancellationToken);
-
- if (_fileHandle.IsClosed)
- throw Error.GetFileNotOpen();
-
- // The always synchronous data transfer between the OS and the internal buffer is intentional
- // because this is needed to allow concurrent async IO requests. Concurrent data transfer
- // between the OS and the internal buffer will result in race conditions. Since FlushWrite and
- // FlushRead modify internal state of the stream and transfer data between the OS and the
- // internal buffer, they cannot be truly async. We will, however, flush the OS file buffers
- // asynchronously because it doesn't modify any internal state of the stream and is potentially
- // a long running process.
- try
- {
- FlushInternalBuffer();
- }
- catch (Exception e)
- {
- return Task.FromException(e);
- }
-
- if (CanWrite)
- {
- return Task.Factory.StartNew(
- state => ((FileStream)state).FlushOSBuffer(),
- this,
- cancellationToken,
- TaskCreationOptions.DenyChildAttach,
- TaskScheduler.Default);
- }
- else
- {
- return Task.CompletedTask;
- }
- }
-
- private Task<int> TaskFromResultOrCache(int result)
- {
- Task<int> completedTask = _lastSynchronouslyCompletedTask;
- Debug.Assert(completedTask == null || completedTask.Status == TaskStatus.RanToCompletion, "Cached task should have completed successfully");
-
- if ((completedTask == null) || (completedTask.Result != result))
- {
- completedTask = Task.FromResult(result);
- _lastSynchronouslyCompletedTask = completedTask;
- }
-
- return completedTask;
- }
-
- private void LockInternal(long position, long length)
- {
- int positionLow = unchecked((int)(position));
- int positionHigh = unchecked((int)(position >> 32));
- int lengthLow = unchecked((int)(length));
- int lengthHigh = unchecked((int)(length >> 32));
-
- if (!Interop.Kernel32.LockFile(_fileHandle, positionLow, positionHigh, lengthLow, lengthHigh))
- {
- throw Win32Marshal.GetExceptionForLastWin32Error();
- }
- }
-
- private void UnlockInternal(long position, long length)
- {
- int positionLow = unchecked((int)(position));
- int positionHigh = unchecked((int)(position >> 32));
- int lengthLow = unchecked((int)(length));
- int lengthHigh = unchecked((int)(length >> 32));
-
- if (!Interop.Kernel32.UnlockFile(_fileHandle, positionLow, positionHigh, lengthLow, lengthHigh))
- {
- throw Win32Marshal.GetExceptionForLastWin32Error();
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/IO/FileStreamCompletionSource.Win32.cs b/src/mscorlib/corefx/System/IO/FileStreamCompletionSource.Win32.cs
deleted file mode 100644
index 159e416e63..0000000000
--- a/src/mscorlib/corefx/System/IO/FileStreamCompletionSource.Win32.cs
+++ /dev/null
@@ -1,221 +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.Security;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Runtime.InteropServices;
-using System.Diagnostics;
-
-namespace System.IO
-{
- public partial class FileStream : Stream
- {
- // This is an internal object extending TaskCompletionSource with fields
- // for all of the relevant data necessary to complete the IO operation.
- // This is used by IOCallback and all of the async methods.
- unsafe private sealed class FileStreamCompletionSource : TaskCompletionSource<int>
- {
- private const long NoResult = 0;
- private const long ResultSuccess = (long)1 << 32;
- private const long ResultError = (long)2 << 32;
- private const long RegisteringCancellation = (long)4 << 32;
- private const long CompletedCallback = (long)8 << 32;
- private const ulong ResultMask = ((ulong)uint.MaxValue) << 32;
-
- private static Action<object> s_cancelCallback;
-
- private readonly FileStream _stream;
- private readonly int _numBufferedBytes;
- private readonly CancellationToken _cancellationToken;
- private CancellationTokenRegistration _cancellationRegistration;
-#if DEBUG
- private bool _cancellationHasBeenRegistered;
-#endif
- private NativeOverlapped* _overlapped; // Overlapped class responsible for operations in progress when an appdomain unload occurs
- private long _result; // Using long since this needs to be used in Interlocked APIs
-
- // Using RunContinuationsAsynchronously for compat reasons (old API used Task.Factory.StartNew for continuations)
- internal FileStreamCompletionSource(FileStream stream, int numBufferedBytes, byte[] bytes, CancellationToken cancellationToken)
- : base(TaskCreationOptions.RunContinuationsAsynchronously)
- {
- _numBufferedBytes = numBufferedBytes;
- _stream = stream;
- _result = NoResult;
- _cancellationToken = cancellationToken;
-
- // Create the native overlapped. We try to use the preallocated overlapped if possible:
- // it's possible if the byte buffer is the same one that's associated with the preallocated overlapped
- // and if no one else is currently using the preallocated overlapped. This is the fast-path for cases
- // where the user-provided buffer is smaller than the FileStream's buffer (such that the FileStream's
- // buffer is used) and where operations on the FileStream are not being performed concurrently.
- _overlapped = ReferenceEquals(bytes, _stream._buffer) && _stream.CompareExchangeCurrentOverlappedOwner(this, null) == null ?
- _stream._fileHandle.ThreadPoolBinding.AllocateNativeOverlapped(_stream._preallocatedOverlapped) :
- _stream._fileHandle.ThreadPoolBinding.AllocateNativeOverlapped(s_ioCallback, this, bytes);
- Debug.Assert(_overlapped != null, "AllocateNativeOverlapped returned null");
- }
-
- internal NativeOverlapped* Overlapped
- {
- get { return _overlapped; }
- }
-
- public void SetCompletedSynchronously(int numBytes)
- {
- ReleaseNativeResource();
- TrySetResult(numBytes + _numBufferedBytes);
- }
-
- public void RegisterForCancellation()
- {
-#if DEBUG
- Debug.Assert(!_cancellationHasBeenRegistered, "Cannot register for cancellation twice");
- _cancellationHasBeenRegistered = true;
-#endif
-
- // Quick check to make sure that the cancellation token supports cancellation, and that the IO hasn't completed
- if ((_cancellationToken.CanBeCanceled) && (_overlapped != null))
- {
- var cancelCallback = s_cancelCallback;
- if (cancelCallback == null) s_cancelCallback = cancelCallback = Cancel;
-
- // Register the cancellation only if the IO hasn't completed
- long packedResult = Interlocked.CompareExchange(ref _result, RegisteringCancellation, NoResult);
- if (packedResult == NoResult)
- {
- _cancellationRegistration = _cancellationToken.Register(cancelCallback, this);
-
- // Switch the result, just in case IO completed while we were setting the registration
- packedResult = Interlocked.Exchange(ref _result, NoResult);
- }
- else if (packedResult != CompletedCallback)
- {
- // Failed to set the result, IO is in the process of completing
- // Attempt to take the packed result
- packedResult = Interlocked.Exchange(ref _result, NoResult);
- }
-
- // If we have a callback that needs to be completed
- if ((packedResult != NoResult) && (packedResult != CompletedCallback) && (packedResult != RegisteringCancellation))
- {
- CompleteCallback((ulong)packedResult);
- }
- }
- }
-
- internal void ReleaseNativeResource()
- {
- // Ensure that cancellation has been completed and cleaned up.
- _cancellationRegistration.Dispose();
-
- // Free the overlapped.
- // NOTE: The cancellation must *NOT* be running at this point, or it may observe freed memory
- // (this is why we disposed the registration above).
- if (_overlapped != null)
- {
- _stream._fileHandle.ThreadPoolBinding.FreeNativeOverlapped(_overlapped);
- _overlapped = null;
- }
-
- // Ensure we're no longer set as the current completion source (we may not have been to begin with).
- // Only one operation at a time is eligible to use the preallocated overlapped,
- _stream.CompareExchangeCurrentOverlappedOwner(null, this);
- }
-
- // When doing IO asynchronously (i.e. _isAsync==true), this callback is
- // called by a free thread in the threadpool when the IO operation
- // completes.
- internal static unsafe void IOCallback(uint errorCode, uint numBytes, NativeOverlapped* pOverlapped)
- {
- // Extract the completion source from the overlapped. The state in the overlapped
- // will either be a Win32FileStream (in the case where the preallocated overlapped was used),
- // in which case the operation being completed is its _currentOverlappedOwner, or it'll
- // be directly the FileStreamCompletion that's completing (in the case where the preallocated
- // overlapped was already in use by another operation).
- object state = ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
- FileStream fs = state as FileStream;
- FileStreamCompletionSource completionSource = fs != null ?
- fs._currentOverlappedOwner :
- (FileStreamCompletionSource)state;
- Debug.Assert(completionSource._overlapped == pOverlapped, "Overlaps don't match");
-
- // Handle reading from & writing to closed pipes. While I'm not sure
- // this is entirely necessary anymore, maybe it's possible for
- // an async read on a pipe to be issued and then the pipe is closed,
- // returning this error. This may very well be necessary.
- ulong packedResult;
- if (errorCode != 0 && errorCode != ERROR_BROKEN_PIPE && errorCode != ERROR_NO_DATA)
- {
- packedResult = ((ulong)ResultError | errorCode);
- }
- else
- {
- packedResult = ((ulong)ResultSuccess | numBytes);
- }
-
- // Stow the result so that other threads can observe it
- // And, if no other thread is registering cancellation, continue
- if (NoResult == Interlocked.Exchange(ref completionSource._result, (long)packedResult))
- {
- // Successfully set the state, attempt to take back the callback
- if (Interlocked.Exchange(ref completionSource._result, CompletedCallback) != NoResult)
- {
- // Successfully got the callback, finish the callback
- completionSource.CompleteCallback(packedResult);
- }
- // else: Some other thread stole the result, so now it is responsible to finish the callback
- }
- // else: Some other thread is registering a cancellation, so it *must* finish the callback
- }
-
- private void CompleteCallback(ulong packedResult) {
- // Free up the native resource and cancellation registration
- ReleaseNativeResource();
-
- // Unpack the result and send it to the user
- long result = (long)(packedResult & ResultMask);
- if (result == ResultError)
- {
- int errorCode = unchecked((int)(packedResult & uint.MaxValue));
- if (errorCode == Interop.Errors.ERROR_OPERATION_ABORTED)
- {
- TrySetCanceled(_cancellationToken.IsCancellationRequested ? _cancellationToken : new CancellationToken(true));
- }
- else
- {
- TrySetException(Win32Marshal.GetExceptionForWin32Error(errorCode));
- }
- }
- else
- {
- Debug.Assert(result == ResultSuccess, "Unknown result");
- TrySetResult((int)(packedResult & uint.MaxValue) + _numBufferedBytes);
- }
- }
-
- private static void Cancel(object state)
- {
- // WARNING: This may potentially be called under a lock (during cancellation registration)
-
- FileStreamCompletionSource completionSource = state as FileStreamCompletionSource;
- Debug.Assert(completionSource != null, "Unknown state passed to cancellation");
- Debug.Assert(completionSource._overlapped != null && !completionSource.Task.IsCompleted, "IO should not have completed yet");
-
- // If the handle is still valid, attempt to cancel the IO
- if (!completionSource._stream._fileHandle.IsInvalid &&
- !Interop.Kernel32.CancelIoEx(completionSource._stream._fileHandle, completionSource._overlapped))
- {
- int errorCode = Marshal.GetLastWin32Error();
-
- // ERROR_NOT_FOUND is returned if CancelIoEx cannot find the request to cancel.
- // This probably means that the IO operation has completed.
- if (errorCode != Interop.Errors.ERROR_NOT_FOUND)
- {
- throw Win32Marshal.GetExceptionForWin32Error(errorCode);
- }
- }
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/IO/Path.Unix.cs b/src/mscorlib/corefx/System/IO/Path.Unix.cs
deleted file mode 100644
index c566fa0066..0000000000
--- a/src/mscorlib/corefx/System/IO/Path.Unix.cs
+++ /dev/null
@@ -1,216 +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.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace System.IO
-{
- public static partial class Path
- {
- public static char[] GetInvalidFileNameChars() => new char[] { '\0', '/' };
-
- public static char[] GetInvalidPathChars() => new char[] { '\0' };
-
- internal static int MaxPath => Interop.Sys.MaxPath;
-
- private static readonly bool s_isMac = Interop.Sys.GetUnixName() == "OSX";
-
- // Expands the given path to a fully qualified path.
- public static string GetFullPath(string path)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
-
- if (path.Length == 0)
- throw new ArgumentException(SR.Arg_PathIllegal);
-
- PathInternal.CheckInvalidPathChars(path);
-
- // Expand with current directory if necessary
- if (!IsPathRooted(path))
- {
- path = Combine(Interop.Sys.GetCwd(), path);
- }
-
- // We would ideally use realpath to do this, but it resolves symlinks, requires that the file actually exist,
- // and turns it into a full path, which we only want if fullCheck is true.
- string collapsedString = RemoveRelativeSegments(path);
-
- Debug.Assert(collapsedString.Length < path.Length || collapsedString.ToString() == path,
- "Either we've removed characters, or the string should be unmodified from the input path.");
-
- if (collapsedString.Length > Interop.Sys.MaxPath)
- {
- throw new PathTooLongException(SR.IO_PathTooLong);
- }
-
- string result = collapsedString.Length == 0 ? PathInternal.DirectorySeparatorCharAsString : collapsedString;
-
- return result;
- }
-
- /// <summary>
- /// Try to remove relative segments from the given path (without combining with a root).
- /// </summary>
- /// <param name="skip">Skip the specified number of characters before evaluating.</param>
- private static string RemoveRelativeSegments(string path, int skip = 0)
- {
- bool flippedSeparator = false;
-
- // Remove "//", "/./", and "/../" from the path by copying each character to the output,
- // except the ones we're removing, such that the builder contains the normalized path
- // at the end.
- var sb = StringBuilderCache.Acquire(path.Length);
- if (skip > 0)
- {
- sb.Append(path, 0, skip);
- }
-
- int componentCharCount = 0;
- for (int i = skip; i < path.Length; i++)
- {
- char c = path[i];
-
- if (PathInternal.IsDirectorySeparator(c) && i + 1 < path.Length)
- {
- componentCharCount = 0;
-
- // Skip this character if it's a directory separator and if the next character is, too,
- // e.g. "parent//child" => "parent/child"
- if (PathInternal.IsDirectorySeparator(path[i + 1]))
- {
- continue;
- }
-
- // Skip this character and the next if it's referring to the current directory,
- // e.g. "parent/./child" =? "parent/child"
- if ((i + 2 == path.Length || PathInternal.IsDirectorySeparator(path[i + 2])) &&
- path[i + 1] == '.')
- {
- i++;
- continue;
- }
-
- // Skip this character and the next two if it's referring to the parent directory,
- // e.g. "parent/child/../grandchild" => "parent/grandchild"
- if (i + 2 < path.Length &&
- (i + 3 == path.Length || PathInternal.IsDirectorySeparator(path[i + 3])) &&
- path[i + 1] == '.' && path[i + 2] == '.')
- {
- // Unwind back to the last slash (and if there isn't one, clear out everything).
- int s;
- for (s = sb.Length - 1; s >= 0; s--)
- {
- if (PathInternal.IsDirectorySeparator(sb[s]))
- {
- sb.Length = s;
- break;
- }
- }
- if (s < 0)
- {
- sb.Length = 0;
- }
-
- i += 2;
- continue;
- }
- }
-
- if (++componentCharCount > Interop.Sys.MaxName)
- {
- throw new PathTooLongException(SR.IO_PathTooLong);
- }
-
- // Normalize the directory separator if needed
- if (c != PathInternal.DirectorySeparatorChar && c == PathInternal.AltDirectorySeparatorChar)
- {
- c = PathInternal.DirectorySeparatorChar;
- flippedSeparator = true;
- }
-
- sb.Append(c);
- }
-
- if (flippedSeparator || sb.Length != path.Length)
- {
- return StringBuilderCache.GetStringAndRelease(sb);
- }
- else
- {
- // We haven't changed the source path, return the original
- StringBuilderCache.Release(sb);
- return path;
- }
- }
-
- private static string RemoveLongPathPrefix(string path)
- {
- return path; // nop. There's nothing special about "long" paths on Unix.
- }
-
- public static string GetTempPath()
- {
- const string TempEnvVar = "TMPDIR";
- const string DefaultTempPath = "/tmp/";
-
- // Get the temp path from the TMPDIR environment variable.
- // If it's not set, just return the default path.
- // If it is, return it, ensuring it ends with a slash.
- string path = Environment.GetEnvironmentVariable(TempEnvVar);
- return
- string.IsNullOrEmpty(path) ? DefaultTempPath :
- PathInternal.IsDirectorySeparator(path[path.Length - 1]) ? path :
- path + PathInternal.DirectorySeparatorChar;
- }
-
- public static string GetTempFileName()
- {
- const string Suffix = ".tmp";
- const int SuffixByteLength = 4;
-
- // mkstemps takes a char* and overwrites the XXXXXX with six characters
- // that'll result in a unique file name.
- string template = GetTempPath() + "tmpXXXXXX" + Suffix + "\0";
- byte[] name = Encoding.UTF8.GetBytes(template);
-
- // Create, open, and close the temp file.
- IntPtr fd = Interop.CheckIo(Interop.Sys.MksTemps(name, SuffixByteLength));
- Interop.Sys.Close(fd); // ignore any errors from close; nothing to do if cleanup isn't possible
-
- // 'name' is now the name of the file
- Debug.Assert(name[name.Length - 1] == '\0');
- return Encoding.UTF8.GetString(name, 0, name.Length - 1); // trim off the trailing '\0'
- }
-
- public static bool IsPathRooted(string path)
- {
- if (path == null)
- return false;
-
- PathInternal.CheckInvalidPathChars(path);
- return path.Length > 0 && path[0] == PathInternal.DirectorySeparatorChar;
- }
-
- public static string GetPathRoot(string path)
- {
- if (path == null) return null;
- return IsPathRooted(path) ? PathInternal.DirectorySeparatorCharAsString : String.Empty;
- }
-
- private static unsafe void GetCryptoRandomBytes(byte* bytes, int byteCount)
- {
- // We want to avoid dependencies on the Crypto library when compiling in CoreCLR. This
- // will use the existing PAL implementation.
- byte[] buffer = new byte[KeyLength];
- Microsoft.Win32.Win32Native.Random(bStrong: true, buffer: buffer, length: KeyLength);
- Runtime.InteropServices.Marshal.Copy(buffer, 0, (IntPtr)bytes, KeyLength);
- }
-
- /// <summary>Gets whether the system is case-sensitive.</summary>
- internal static bool IsCaseSensitive { get { return !s_isMac; } }
- }
-}
diff --git a/src/mscorlib/corefx/System/IO/Path.Win32.cs b/src/mscorlib/corefx/System/IO/Path.Win32.cs
deleted file mode 100644
index 8a9e62e6e5..0000000000
--- a/src/mscorlib/corefx/System/IO/Path.Win32.cs
+++ /dev/null
@@ -1,36 +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.Diagnostics;
-
-namespace System.IO
-{
- public static partial class Path
- {
- private static unsafe void GetCryptoRandomBytes(byte* bytes, int byteCount)
- {
- // We need to fill a byte array with cryptographically-strong random bytes, but we can't reference
- // System.Security.Cryptography.RandomNumberGenerator.dll due to layering. Instead, we just
- // call to BCryptGenRandom directly, which is all that RandomNumberGenerator does.
-
- Debug.Assert(bytes != null);
- Debug.Assert(byteCount >= 0);
-
- Interop.BCrypt.NTSTATUS status = Interop.BCrypt.BCryptGenRandom(bytes, byteCount);
- if (status == Interop.BCrypt.NTSTATUS.STATUS_SUCCESS)
- {
- return;
- }
- else if (status == Interop.BCrypt.NTSTATUS.STATUS_NO_MEMORY)
- {
- throw new OutOfMemoryException();
- }
- else
- {
- Debug.Fail("BCryptGenRandom should only fail due to OOM or invalid args / handle inputs.");
- throw new InvalidOperationException();
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/IO/Path.Windows.cs b/src/mscorlib/corefx/System/IO/Path.Windows.cs
deleted file mode 100644
index ce867efd2c..0000000000
--- a/src/mscorlib/corefx/System/IO/Path.Windows.cs
+++ /dev/null
@@ -1,155 +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.Diagnostics;
-using System.Text;
-
-namespace System.IO
-{
- public static partial class Path
- {
- public static char[] GetInvalidFileNameChars() => new char[]
- {
- '\"', '<', '>', '|', '\0',
- (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10,
- (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20,
- (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30,
- (char)31, ':', '*', '?', '\\', '/'
- };
-
- public static char[] GetInvalidPathChars() => new char[]
- {
- '|', '\0',
- (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10,
- (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20,
- (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30,
- (char)31
- };
-
- // The max total path is 260, and the max individual component length is 255.
- // For example, D:\<256 char file name> isn't legal, even though it's under 260 chars.
- internal const int MaxPath = 260;
-
- // Expands the given path to a fully qualified path.
- public static string GetFullPath(string path)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
-
- // Embedded null characters are the only invalid character case we want to check up front.
- // This is because the nulls will signal the end of the string to Win32 and therefore have
- // unpredictable results. Other invalid characters we give a chance to be normalized out.
- if (path.IndexOf('\0') != -1)
- throw new ArgumentException(SR.Argument_InvalidPathChars, nameof(path));
-
- if (PathInternal.IsExtended(path))
- {
- // We can't really know what is valid for all cases of extended paths.
- //
- // - object names can include other characters as well (':', '/', etc.)
- // - even file objects have different rules (pipe names can contain most characters)
- //
- // As such we will do no further analysis of extended paths to avoid blocking known and unknown
- // scenarios as well as minimizing compat breaks should we block now and need to unblock later.
- return path;
- }
-
- bool isDevice = PathInternal.IsDevice(path);
- if (!isDevice)
- {
- // Toss out paths with colons that aren't a valid drive specifier.
- // Cannot start with a colon and can only be of the form "C:".
- // (Note that we used to explicitly check "http:" and "file:"- these are caught by this check now.)
- int startIndex = PathInternal.PathStartSkip(path);
-
- // Move past the colon
- startIndex += 2;
-
- if ((path.Length > 0 && path[0] == PathInternal.VolumeSeparatorChar)
- || (path.Length >= startIndex && path[startIndex - 1] == PathInternal.VolumeSeparatorChar && !PathInternal.IsValidDriveChar(path[startIndex - 2]))
- || (path.Length > startIndex && path.IndexOf(PathInternal.VolumeSeparatorChar, startIndex) != -1))
- {
- throw new NotSupportedException(SR.Argument_PathFormatNotSupported);
- }
- }
-
- // Technically this doesn't matter but we used to throw for this case
- if (string.IsNullOrWhiteSpace(path))
- throw new ArgumentException(SR.Arg_PathIllegal);
-
- // We don't want to check invalid characters for device format- see comments for extended above
- string fullPath = PathHelper.Normalize(path, checkInvalidCharacters: !isDevice, expandShortPaths: true);
-
- if (!isDevice)
- {
- // Emulate FileIOPermissions checks, retained for compatibility (normal invalid characters have already been checked)
- if (PathInternal.HasWildCardCharacters(fullPath))
- throw new ArgumentException(SR.Argument_InvalidPathChars, nameof(path));
- }
-
- return fullPath;
- }
-
- public static string GetTempPath()
- {
- StringBuilder sb = StringBuilderCache.Acquire(MaxPath);
- uint r = Interop.Kernel32.GetTempPathW(MaxPath, sb);
- if (r == 0)
- throw Win32Marshal.GetExceptionForLastWin32Error();
- return GetFullPath(StringBuilderCache.GetStringAndRelease(sb));
- }
-
- // Returns a unique temporary file name, and creates a 0-byte file by that
- // name on disk.
- public static string GetTempFileName()
- {
- string path = GetTempPath();
-
- StringBuilder sb = StringBuilderCache.Acquire(MaxPath);
- uint r = Interop.Kernel32.GetTempFileNameW(path, "tmp", 0, sb);
- if (r == 0)
- throw Win32Marshal.GetExceptionForLastWin32Error();
- return StringBuilderCache.GetStringAndRelease(sb);
- }
-
- // Tests if the given path contains a root. A path is considered rooted
- // if it starts with a backslash ("\") or a drive letter and a colon (":").
- public static bool IsPathRooted(string path)
- {
- if (path != null)
- {
- PathInternal.CheckInvalidPathChars(path);
-
- int length = path.Length;
- if ((length >= 1 && PathInternal.IsDirectorySeparator(path[0])) ||
- (length >= 2 && path[1] == PathInternal.VolumeSeparatorChar))
- return true;
- }
- return false;
- }
-
- // Returns the root portion of the given path. The resulting string
- // consists of those rightmost characters of the path that constitute the
- // root of the path. Possible patterns for the resulting string are: An
- // empty string (a relative path on the current drive), "\" (an absolute
- // path on the current drive), "X:" (a relative path on a given drive,
- // where X is the drive letter), "X:\" (an absolute path on a given drive),
- // and "\\server\share" (a UNC path for a given server and share name).
- // The resulting string is null if path is null.
- public static string GetPathRoot(string path)
- {
- if (path == null) return null;
- PathInternal.CheckInvalidPathChars(path);
-
- // Need to return the normalized directory separator
- path = PathInternal.NormalizeDirectorySeparators(path);
-
- int pathRoot = PathInternal.GetRootLength(path);
- return pathRoot <= 0 ? string.Empty : path.Substring(0, pathRoot);
- }
-
- /// <summary>Gets whether the system is case-sensitive.</summary>
- internal static bool IsCaseSensitive { get { return false; } }
- }
-}
diff --git a/src/mscorlib/corefx/System/IO/Path.cs b/src/mscorlib/corefx/System/IO/Path.cs
deleted file mode 100644
index 77b213968b..0000000000
--- a/src/mscorlib/corefx/System/IO/Path.cs
+++ /dev/null
@@ -1,575 +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.Diagnostics;
-using System.Diagnostics.Contracts;
-using System.Text;
-
-namespace System.IO
-{
- // Provides methods for processing file system strings in a cross-platform manner.
- // Most of the methods don't do a complete parsing (such as examining a UNC hostname),
- // but they will handle most string operations.
- public static partial class Path
- {
- // Public static readonly variant of the separators. The Path implementation itself is using
- // internal const variant of the separators for better performance.
- public static readonly char DirectorySeparatorChar = PathInternal.DirectorySeparatorChar;
- public static readonly char AltDirectorySeparatorChar = PathInternal.AltDirectorySeparatorChar;
- public static readonly char VolumeSeparatorChar = PathInternal.VolumeSeparatorChar;
- public static readonly char PathSeparator = PathInternal.PathSeparator;
-
- // For generating random file names
- // 8 random bytes provides 12 chars in our encoding for the 8.3 name.
- const int KeyLength = 8;
-
- [Obsolete("Please use GetInvalidPathChars or GetInvalidFileNameChars instead.")]
- public static readonly char[] InvalidPathChars = GetInvalidPathChars();
-
- // Changes the extension of a file path. The path parameter
- // specifies a file path, and the extension parameter
- // specifies a file extension (with a leading period, such as
- // ".exe" or ".cs").
- //
- // The function returns a file path with the same root, directory, and base
- // name parts as path, but with the file extension changed to
- // the specified extension. If path is null, the function
- // returns null. If path does not contain a file extension,
- // the new file extension is appended to the path. If extension
- // is null, any existing extension is removed from path.
- public static string ChangeExtension(string path, string extension)
- {
- if (path != null)
- {
- PathInternal.CheckInvalidPathChars(path);
-
- string s = path;
- for (int i = path.Length - 1; i >= 0; i--)
- {
- char ch = path[i];
- if (ch == '.')
- {
- s = path.Substring(0, i);
- break;
- }
- if (PathInternal.IsDirectoryOrVolumeSeparator(ch)) break;
- }
-
- if (extension != null && path.Length != 0)
- {
- s = (extension.Length == 0 || extension[0] != '.') ?
- s + "." + extension :
- s + extension;
- }
-
- return s;
- }
- return null;
- }
-
- // Returns the directory path of a file path. This method effectively
- // removes the last element of the given file path, i.e. it returns a
- // string consisting of all characters up to but not including the last
- // backslash ("\") in the file path. The returned value is null if the file
- // path is null or if the file path denotes a root (such as "\", "C:", or
- // "\\server\share").
- public static string GetDirectoryName(string path)
- {
- if (path != null)
- {
- PathInternal.CheckInvalidPathChars(path);
- path = PathInternal.NormalizeDirectorySeparators(path);
- int root = PathInternal.GetRootLength(path);
-
- int i = path.Length;
- if (i > root)
- {
- while (i > root && !PathInternal.IsDirectorySeparator(path[--i])) ;
- return path.Substring(0, i);
- }
- }
- return null;
- }
-
- // Returns the extension of the given path. The returned value includes the
- // period (".") character of the extension except when you have a terminal period when you get string.Empty, such as ".exe" or
- // ".cpp". The returned value is null if the given path is
- // null or if the given path does not include an extension.
- [Pure]
- public static string GetExtension(string path)
- {
- if (path == null)
- return null;
-
- PathInternal.CheckInvalidPathChars(path);
- int length = path.Length;
- for (int i = length - 1; i >= 0; i--)
- {
- char ch = path[i];
- if (ch == '.')
- {
- if (i != length - 1)
- return path.Substring(i, length - i);
- else
- return string.Empty;
- }
- if (PathInternal.IsDirectoryOrVolumeSeparator(ch))
- break;
- }
- return string.Empty;
- }
-
- // Returns the name and extension parts of the given path. The resulting
- // string contains the characters of path that follow the last
- // separator in path. The resulting string is null if path is null.
- [Pure]
- public static string GetFileName(string path)
- {
- if (path == null)
- return null;
-
- int offset = PathInternal.FindFileNameIndex(path);
- int count = path.Length - offset;
- return path.Substring(offset, count);
- }
-
- [Pure]
- public static string GetFileNameWithoutExtension(string path)
- {
- if (path == null)
- return null;
-
- int length = path.Length;
- int offset = PathInternal.FindFileNameIndex(path);
-
- int end = path.LastIndexOf('.', length - 1, length - offset);
- return end == -1 ?
- path.Substring(offset) : // No extension was found
- path.Substring(offset, end - offset);
- }
-
- // Returns a cryptographically strong random 8.3 string that can be
- // used as either a folder name or a file name.
- public static unsafe string GetRandomFileName()
- {
-
- byte* pKey = stackalloc byte[KeyLength];
- GetCryptoRandomBytes(pKey, KeyLength);
-
- const int RandomFileNameLength = 12;
- char* pRandomFileName = stackalloc char[RandomFileNameLength];
- Populate83FileNameFromRandomBytes(pKey, KeyLength, pRandomFileName, RandomFileNameLength);
- return new string(pRandomFileName, 0, RandomFileNameLength);
- }
-
- // Tests if a path includes a file extension. The result is
- // true if the characters that follow the last directory
- // separator ('\\' or '/') or volume separator (':') in the path include
- // a period (".") other than a terminal period. The result is false otherwise.
- [Pure]
- public static bool HasExtension(string path)
- {
- if (path != null)
- {
- PathInternal.CheckInvalidPathChars(path);
-
- for (int i = path.Length - 1; i >= 0; i--)
- {
- char ch = path[i];
- if (ch == '.')
- {
- return i != path.Length - 1;
- }
- if (PathInternal.IsDirectoryOrVolumeSeparator(ch)) break;
- }
- }
- return false;
- }
-
- public static string Combine(string path1, string path2)
- {
- if (path1 == null || path2 == null)
- throw new ArgumentNullException((path1 == null) ? nameof(path1): nameof(path2));
- Contract.EndContractBlock();
-
- PathInternal.CheckInvalidPathChars(path1);
- PathInternal.CheckInvalidPathChars(path2);
-
- return CombineNoChecks(path1, path2);
- }
-
- public static string Combine(string path1, string path2, string path3)
- {
- if (path1 == null || path2 == null || path3 == null)
- throw new ArgumentNullException((path1 == null) ? nameof(path1): (path2 == null) ? nameof(path2): nameof(path3));
- Contract.EndContractBlock();
-
- PathInternal.CheckInvalidPathChars(path1);
- PathInternal.CheckInvalidPathChars(path2);
- PathInternal.CheckInvalidPathChars(path3);
-
- return CombineNoChecks(path1, path2, path3);
- }
-
- public static string Combine(string path1, string path2, string path3, string path4)
- {
- if (path1 == null || path2 == null || path3 == null || path4 == null)
- throw new ArgumentNullException((path1 == null) ? nameof(path1): (path2 == null) ? nameof(path2): (path3 == null) ? nameof(path3): nameof(path4));
- Contract.EndContractBlock();
-
- PathInternal.CheckInvalidPathChars(path1);
- PathInternal.CheckInvalidPathChars(path2);
- PathInternal.CheckInvalidPathChars(path3);
- PathInternal.CheckInvalidPathChars(path4);
-
- return CombineNoChecks(path1, path2, path3, path4);
- }
-
- public static string Combine(params string[] paths)
- {
- if (paths == null)
- {
- throw new ArgumentNullException(nameof(paths));
- }
- Contract.EndContractBlock();
-
- int finalSize = 0;
- int firstComponent = 0;
-
- // We have two passes, the first calculates how large a buffer to allocate and does some precondition
- // checks on the paths passed in. The second actually does the combination.
-
- for (int i = 0; i < paths.Length; i++)
- {
- if (paths[i] == null)
- {
- throw new ArgumentNullException(nameof(paths));
- }
-
- if (paths[i].Length == 0)
- {
- continue;
- }
-
- PathInternal.CheckInvalidPathChars(paths[i]);
-
- if (IsPathRooted(paths[i]))
- {
- firstComponent = i;
- finalSize = paths[i].Length;
- }
- else
- {
- finalSize += paths[i].Length;
- }
-
- char ch = paths[i][paths[i].Length - 1];
- if (!PathInternal.IsDirectoryOrVolumeSeparator(ch))
- finalSize++;
- }
-
- StringBuilder finalPath = StringBuilderCache.Acquire(finalSize);
-
- for (int i = firstComponent; i < paths.Length; i++)
- {
- if (paths[i].Length == 0)
- {
- continue;
- }
-
- if (finalPath.Length == 0)
- {
- finalPath.Append(paths[i]);
- }
- else
- {
- char ch = finalPath[finalPath.Length - 1];
- if (!PathInternal.IsDirectoryOrVolumeSeparator(ch))
- {
- finalPath.Append(PathInternal.DirectorySeparatorChar);
- }
-
- finalPath.Append(paths[i]);
- }
- }
-
- return StringBuilderCache.GetStringAndRelease(finalPath);
- }
-
- private static string CombineNoChecks(string path1, string path2)
- {
- if (path2.Length == 0)
- return path1;
-
- if (path1.Length == 0)
- return path2;
-
- if (IsPathRooted(path2))
- return path2;
-
- char ch = path1[path1.Length - 1];
- return PathInternal.IsDirectoryOrVolumeSeparator(ch) ?
- path1 + path2 :
- path1 + PathInternal.DirectorySeparatorCharAsString + path2;
- }
-
- private static string CombineNoChecks(string path1, string path2, string path3)
- {
- if (path1.Length == 0)
- return CombineNoChecks(path2, path3);
- if (path2.Length == 0)
- return CombineNoChecks(path1, path3);
- if (path3.Length == 0)
- return CombineNoChecks(path1, path2);
-
- if (IsPathRooted(path3))
- return path3;
- if (IsPathRooted(path2))
- return CombineNoChecks(path2, path3);
-
- bool hasSep1 = PathInternal.IsDirectoryOrVolumeSeparator(path1[path1.Length - 1]);
- bool hasSep2 = PathInternal.IsDirectoryOrVolumeSeparator(path2[path2.Length - 1]);
-
- if (hasSep1 && hasSep2)
- {
- return path1 + path2 + path3;
- }
- else if (hasSep1)
- {
- return path1 + path2 + PathInternal.DirectorySeparatorCharAsString + path3;
- }
- else if (hasSep2)
- {
- return path1 + PathInternal.DirectorySeparatorCharAsString + path2 + path3;
- }
- else
- {
- // string.Concat only has string-based overloads up to four arguments; after that requires allocating
- // a params string[]. Instead, try to use a cached StringBuilder.
- StringBuilder sb = StringBuilderCache.Acquire(path1.Length + path2.Length + path3.Length + 2);
- sb.Append(path1)
- .Append(PathInternal.DirectorySeparatorChar)
- .Append(path2)
- .Append(PathInternal.DirectorySeparatorChar)
- .Append(path3);
- return StringBuilderCache.GetStringAndRelease(sb);
- }
- }
-
- private static string CombineNoChecks(string path1, string path2, string path3, string path4)
- {
- if (path1.Length == 0)
- return CombineNoChecks(path2, path3, path4);
- if (path2.Length == 0)
- return CombineNoChecks(path1, path3, path4);
- if (path3.Length == 0)
- return CombineNoChecks(path1, path2, path4);
- if (path4.Length == 0)
- return CombineNoChecks(path1, path2, path3);
-
- if (IsPathRooted(path4))
- return path4;
- if (IsPathRooted(path3))
- return CombineNoChecks(path3, path4);
- if (IsPathRooted(path2))
- return CombineNoChecks(path2, path3, path4);
-
- bool hasSep1 = PathInternal.IsDirectoryOrVolumeSeparator(path1[path1.Length - 1]);
- bool hasSep2 = PathInternal.IsDirectoryOrVolumeSeparator(path2[path2.Length - 1]);
- bool hasSep3 = PathInternal.IsDirectoryOrVolumeSeparator(path3[path3.Length - 1]);
-
- if (hasSep1 && hasSep2 && hasSep3)
- {
- // Use string.Concat overload that takes four strings
- return path1 + path2 + path3 + path4;
- }
- else
- {
- // string.Concat only has string-based overloads up to four arguments; after that requires allocating
- // a params string[]. Instead, try to use a cached StringBuilder.
- StringBuilder sb = StringBuilderCache.Acquire(path1.Length + path2.Length + path3.Length + path4.Length + 3);
-
- sb.Append(path1);
- if (!hasSep1)
- {
- sb.Append(PathInternal.DirectorySeparatorChar);
- }
-
- sb.Append(path2);
- if (!hasSep2)
- {
- sb.Append(PathInternal.DirectorySeparatorChar);
- }
-
- sb.Append(path3);
- if (!hasSep3)
- {
- sb.Append(PathInternal.DirectorySeparatorChar);
- }
-
- sb.Append(path4);
-
- return StringBuilderCache.GetStringAndRelease(sb);
- }
- }
-
- private static readonly char[] s_base32Char = {
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
- 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
- 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
- 'y', 'z', '0', '1', '2', '3', '4', '5'};
-
- private static unsafe void Populate83FileNameFromRandomBytes(byte* bytes, int byteCount, char* chars, int charCount)
- {
- Debug.Assert(bytes != null);
- Debug.Assert(chars != null);
-
- // This method requires bytes of length 8 and chars of length 12.
- Debug.Assert(byteCount == 8, $"Unexpected {nameof(byteCount)}");
- Debug.Assert(charCount == 12, $"Unexpected {nameof(charCount)}");
-
- byte b0 = bytes[0];
- byte b1 = bytes[1];
- byte b2 = bytes[2];
- byte b3 = bytes[3];
- byte b4 = bytes[4];
-
- // Consume the 5 Least significant bits of the first 5 bytes
- chars[0] = s_base32Char[b0 & 0x1F];
- chars[1] = s_base32Char[b1 & 0x1F];
- chars[2] = s_base32Char[b2 & 0x1F];
- chars[3] = s_base32Char[b3 & 0x1F];
- chars[4] = s_base32Char[b4 & 0x1F];
-
- // Consume 3 MSB of b0, b1, MSB bits 6, 7 of b3, b4
- chars[5] = s_base32Char[(
- ((b0 & 0xE0) >> 5) |
- ((b3 & 0x60) >> 2))];
-
- chars[6] = s_base32Char[(
- ((b1 & 0xE0) >> 5) |
- ((b4 & 0x60) >> 2))];
-
- // Consume 3 MSB bits of b2, 1 MSB bit of b3, b4
- b2 >>= 5;
-
- Debug.Assert(((b2 & 0xF8) == 0), "Unexpected set bits");
-
- if ((b3 & 0x80) != 0)
- b2 |= 0x08;
- if ((b4 & 0x80) != 0)
- b2 |= 0x10;
-
- chars[7] = s_base32Char[b2];
-
- // Set the file extension separator
- chars[8] = '.';
-
- // Consume the 5 Least significant bits of the remaining 3 bytes
- chars[9] = s_base32Char[(bytes[5] & 0x1F)];
- chars[10] = s_base32Char[(bytes[6] & 0x1F)];
- chars[11] = s_base32Char[(bytes[7] & 0x1F)];
- }
-
- /// <summary>
- /// Create a relative path from one path to another. Paths will be resolved before calculating the difference.
- /// Default path comparison for the active platform will be used (OrdinalIgnoreCase for Windows or Mac, Ordinal for Unix).
- /// </summary>
- /// <param name="relativeTo">The source path the output should be relative to. This path is always considered to be a directory.</param>
- /// <param name="path">The destination path.</param>
- /// <returns>The relative path or <paramref name="path"/> if the paths don't share the same root.</returns>
- /// <exception cref="ArgumentNullException">Thrown if <paramref name="relativeTo"/> or <paramref name="path"/> is <c>null</c> or an empty string.</exception>
- public static string GetRelativePath(string relativeTo, string path)
- {
- return GetRelativePath(relativeTo, path, StringComparison);
- }
-
- private static string GetRelativePath(string relativeTo, string path, StringComparison comparisonType)
- {
- if (string.IsNullOrEmpty(relativeTo)) throw new ArgumentNullException(nameof(relativeTo));
- if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullException(nameof(path));
- Debug.Assert(comparisonType == StringComparison.Ordinal || comparisonType == StringComparison.OrdinalIgnoreCase);
-
- relativeTo = GetFullPath(relativeTo);
- path = GetFullPath(path);
-
- // Need to check if the roots are different- if they are we need to return the "to" path.
- if (!PathInternal.AreRootsEqual(relativeTo, path, comparisonType))
- return path;
-
- int commonLength = PathInternal.GetCommonPathLength(relativeTo, path, ignoreCase: comparisonType == StringComparison.OrdinalIgnoreCase);
-
- // If there is nothing in common they can't share the same root, return the "to" path as is.
- if (commonLength == 0)
- return path;
-
- // Trailing separators aren't significant for comparison
- int relativeToLength = relativeTo.Length;
- if (PathInternal.EndsInDirectorySeparator(relativeTo))
- relativeToLength--;
-
- bool pathEndsInSeparator = PathInternal.EndsInDirectorySeparator(path);
- int pathLength = path.Length;
- if (pathEndsInSeparator)
- pathLength--;
-
- // If we have effectively the same path, return "."
- if (relativeToLength == pathLength && commonLength >= relativeToLength) return ".";
-
- // We have the same root, we need to calculate the difference now using the
- // common Length and Segment count past the length.
- //
- // Some examples:
- //
- // C:\Foo C:\Bar L3, S1 -> ..\Bar
- // C:\Foo C:\Foo\Bar L6, S0 -> Bar
- // C:\Foo\Bar C:\Bar\Bar L3, S2 -> ..\..\Bar\Bar
- // C:\Foo\Foo C:\Foo\Bar L7, S1 -> ..\Bar
-
- StringBuilder sb = StringBuilderCache.Acquire(Math.Max(relativeTo.Length, path.Length));
-
- // Add parent segments for segments past the common on the "from" path
- if (commonLength < relativeToLength)
- {
- sb.Append(PathInternal.ParentDirectoryPrefix);
-
- for (int i = commonLength; i < relativeToLength; i++)
- {
- if (PathInternal.IsDirectorySeparator(relativeTo[i]))
- {
- sb.Append(PathInternal.ParentDirectoryPrefix);
- }
- }
- }
- else if (PathInternal.IsDirectorySeparator(path[commonLength]))
- {
- // No parent segments and we need to eat the initial separator
- // (C:\Foo C:\Foo\Bar case)
- commonLength++;
- }
-
- // Now add the rest of the "to" path, adding back the trailing separator
- int count = pathLength - commonLength;
- if (pathEndsInSeparator)
- count++;
-
- sb.Append(path, commonLength, count);
- return StringBuilderCache.GetStringAndRelease(sb);
- }
-
- // StringComparison and IsCaseSensitive are also available in PathInternal.CaseSensitivity but we are
- // too low in System.Runtime.Extensions to use it (no FileStream, etc.)
-
- /// <summary>Returns a comparison that can be used to compare file and directory names for equality.</summary>
- internal static StringComparison StringComparison
- {
- get
- {
- return IsCaseSensitive ?
- StringComparison.Ordinal :
- StringComparison.OrdinalIgnoreCase;
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.Windows.cs b/src/mscorlib/corefx/System/IO/PathInternal.Windows.cs
deleted file mode 100644
index 0ec9b30f99..0000000000
--- a/src/mscorlib/corefx/System/IO/PathInternal.Windows.cs
+++ /dev/null
@@ -1,442 +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.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Text;
-
-namespace System.IO
-{
- /// <summary>Contains internal path helpers that are shared between many projects.</summary>
- internal static partial class PathInternal
- {
- // All paths in Win32 ultimately end up becoming a path to a File object in the Windows object manager. Passed in paths get mapped through
- // DosDevice symbolic links in the object tree to actual File objects under \Devices. To illustrate, this is what happens with a typical
- // path "Foo" passed as a filename to any Win32 API:
- //
- // 1. "Foo" is recognized as a relative path and is appended to the current directory (say, "C:\" in our example)
- // 2. "C:\Foo" is prepended with the DosDevice namespace "\??\"
- // 3. CreateFile tries to create an object handle to the requested file "\??\C:\Foo"
- // 4. The Object Manager recognizes the DosDevices prefix and looks
- // a. First in the current session DosDevices ("\Sessions\1\DosDevices\" for example, mapped network drives go here)
- // b. If not found in the session, it looks in the Global DosDevices ("\GLOBAL??\")
- // 5. "C:" is found in DosDevices (in our case "\GLOBAL??\C:", which is a symbolic link to "\Device\HarddiskVolume6")
- // 6. The full path is now "\Device\HarddiskVolume6\Foo", "\Device\HarddiskVolume6" is a File object and parsing is handed off
- // to the registered parsing method for Files
- // 7. The registered open method for File objects is invoked to create the file handle which is then returned
- //
- // There are multiple ways to directly specify a DosDevices path. The final format of "\??\" is one way. It can also be specified
- // as "\\.\" (the most commonly documented way) and "\\?\". If the question mark syntax is used the path will skip normalization
- // (essentially GetFullPathName()) and path length checks.
-
- // Windows Kernel-Mode Object Manager
- // https://msdn.microsoft.com/en-us/library/windows/hardware/ff565763.aspx
- // https://channel9.msdn.com/Shows/Going+Deep/Windows-NT-Object-Manager
- //
- // Introduction to MS-DOS Device Names
- // https://msdn.microsoft.com/en-us/library/windows/hardware/ff548088.aspx
- //
- // Local and Global MS-DOS Device Names
- // https://msdn.microsoft.com/en-us/library/windows/hardware/ff554302.aspx
-
- internal const char DirectorySeparatorChar = '\\';
- internal const char AltDirectorySeparatorChar = '/';
- internal const char VolumeSeparatorChar = ':';
- internal const char PathSeparator = ';';
-
- internal const string DirectorySeparatorCharAsString = "\\";
-
- internal const string ExtendedPathPrefix = @"\\?\";
- internal const string UncPathPrefix = @"\\";
- internal const string UncExtendedPrefixToInsert = @"?\UNC\";
- internal const string UncExtendedPathPrefix = @"\\?\UNC\";
- internal const string DevicePathPrefix = @"\\.\";
- internal const string ParentDirectoryPrefix = @"..\";
-
- internal const int MaxShortPath = 260;
- internal const int MaxShortDirectoryPath = 248;
- internal const int MaxLongPath = short.MaxValue;
- // \\?\, \\.\, \??\
- internal const int DevicePrefixLength = 4;
- // \\
- internal const int UncPrefixLength = 2;
- // \\?\UNC\, \\.\UNC\
- internal const int UncExtendedPrefixLength = 8;
- internal const int MaxComponentLength = 255;
-
- /// <summary>
- /// Returns true if the given character is a valid drive letter
- /// </summary>
- internal static bool IsValidDriveChar(char value)
- {
- return ((value >= 'A' && value <= 'Z') || (value >= 'a' && value <= 'z'));
- }
-
- /// <summary>
- /// Adds the extended path prefix (\\?\) if not already a device path, IF the path is not relative,
- /// AND the path is more than 259 characters. (> MAX_PATH + null)
- /// </summary>
- internal static string EnsureExtendedPrefixOverMaxPath(string path)
- {
- if (path != null && path.Length >= MaxShortPath)
- {
- return EnsureExtendedPrefix(path);
- }
- else
- {
- return path;
- }
- }
-
- /// <summary>
- /// Adds the extended path prefix (\\?\) if not relative or already a device path.
- /// </summary>
- internal static string EnsureExtendedPrefix(string path)
- {
- // Putting the extended prefix on the path changes the processing of the path. It won't get normalized, which
- // means adding to relative paths will prevent them from getting the appropriate current directory inserted.
-
- // If it already has some variant of a device path (\??\, \\?\, \\.\, //./, etc.) we don't need to change it
- // as it is either correct or we will be changing the behavior. When/if Windows supports long paths implicitly
- // in the future we wouldn't want normalization to come back and break existing code.
-
- // In any case, all internal usages should be hitting normalize path (Path.GetFullPath) before they hit this
- // shimming method. (Or making a change that doesn't impact normalization, such as adding a filename to a
- // normalized base path.)
- if (IsPartiallyQualified(path) || IsDevice(path))
- return path;
-
- // Given \\server\share in longpath becomes \\?\UNC\server\share
- if (path.StartsWith(UncPathPrefix, StringComparison.OrdinalIgnoreCase))
- return path.Insert(2, UncExtendedPrefixToInsert);
-
- return ExtendedPathPrefix + path;
- }
-
- /// <summary>
- /// Returns true if the path uses any of the DOS device path syntaxes. ("\\.\", "\\?\", or "\??\")
- /// </summary>
- internal static bool IsDevice(string path)
- {
- // If the path begins with any two separators is will be recognized and normalized and prepped with
- // "\??\" for internal usage correctly. "\??\" is recognized and handled, "/??/" is not.
- return IsExtended(path)
- ||
- (
- path.Length >= DevicePrefixLength
- && IsDirectorySeparator(path[0])
- && IsDirectorySeparator(path[1])
- && (path[2] == '.' || path[2] == '?')
- && IsDirectorySeparator(path[3])
- );
- }
-
- /// <summary>
- /// Returns true if the path uses the canonical form of extended syntax ("\\?\" or "\??\"). If the
- /// path matches exactly (cannot use alternate directory separators) Windows will skip normalization
- /// and path length checks.
- /// </summary>
- internal static bool IsExtended(string path)
- {
- // While paths like "//?/C:/" will work, they're treated the same as "\\.\" paths.
- // Skipping of normalization will *only* occur if back slashes ('\') are used.
- return path.Length >= DevicePrefixLength
- && path[0] == '\\'
- && (path[1] == '\\' || path[1] == '?')
- && path[2] == '?'
- && path[3] == '\\';
- }
-
- /// <summary>
- /// Returns a value indicating if the given path contains invalid characters (", &lt;, &gt;, |
- /// NUL, or any ASCII char whose integer representation is in the range of 1 through 31).
- /// Does not check for wild card characters ? and *.
- /// </summary>
- internal static bool HasIllegalCharacters(string path)
- {
- // This is equivalent to IndexOfAny(InvalidPathChars) >= 0,
- // except faster since IndexOfAny grows slower as the input
- // array grows larger.
- // Since we know that some of the characters we're looking
- // for are contiguous in the alphabet-- the path cannot contain
- // characters 0-31-- we can optimize this for our specific use
- // case and use simple comparison operations.
-
- for (int i = 0; i < path.Length; i++)
- {
- char c = path[i];
- if (c <= '|') // fast path for common case - '|' is highest illegal character
- {
- if (c <= '\u001f' || c == '|')
- {
- return true;
- }
- }
- }
-
- return false;
- }
-
- /// <summary>
- /// Check for known wildcard characters. '*' and '?' are the most common ones.
- /// </summary>
- internal static bool HasWildCardCharacters(string path)
- {
- // Question mark is part of dos device syntax so we have to skip if we are
- int startIndex = IsDevice(path) ? ExtendedPathPrefix.Length : 0;
-
- // [MS - FSA] 2.1.4.4 Algorithm for Determining if a FileName Is in an Expression
- // https://msdn.microsoft.com/en-us/library/ff469270.aspx
- for (int i = startIndex; i < path.Length; i++)
- {
- char c = path[i];
- if (c <= '?') // fast path for common case - '?' is highest wildcard character
- {
- if (c == '\"' || c == '<' || c == '>' || c == '*' || c == '?')
- return true;
- }
- }
-
- return false;
- }
-
- /// <summary>
- /// Gets the length of the root of the path (drive, share, etc.).
- /// </summary>
- internal unsafe static int GetRootLength(string path)
- {
- fixed(char* value = path)
- {
- return GetRootLength(value, path.Length);
- }
- }
-
- private unsafe static int GetRootLength(char* path, int pathLength)
- {
- int i = 0;
- int volumeSeparatorLength = 2; // Length to the colon "C:"
- int uncRootLength = 2; // Length to the start of the server name "\\"
-
- bool extendedSyntax = StartsWithOrdinal(path, pathLength, ExtendedPathPrefix);
- bool extendedUncSyntax = StartsWithOrdinal(path, pathLength, UncExtendedPathPrefix);
- if (extendedSyntax)
- {
- // Shift the position we look for the root from to account for the extended prefix
- if (extendedUncSyntax)
- {
- // "\\" -> "\\?\UNC\"
- uncRootLength = UncExtendedPathPrefix.Length;
- }
- else
- {
- // "C:" -> "\\?\C:"
- volumeSeparatorLength += ExtendedPathPrefix.Length;
- }
- }
-
- if ((!extendedSyntax || extendedUncSyntax) && pathLength > 0 && IsDirectorySeparator(path[0]))
- {
- // UNC or simple rooted path (e.g. "\foo", NOT "\\?\C:\foo")
-
- i = 1; // Drive rooted (\foo) is one character
- if (extendedUncSyntax || (pathLength > 1 && IsDirectorySeparator(path[1])))
- {
- // UNC (\\?\UNC\ or \\), scan past the next two directory separators at most
- // (e.g. to \\?\UNC\Server\Share or \\Server\Share\)
- i = uncRootLength;
- int n = 2; // Maximum separators to skip
- while (i < pathLength && (!IsDirectorySeparator(path[i]) || --n > 0)) i++;
- }
- }
- else if (pathLength >= volumeSeparatorLength && path[volumeSeparatorLength - 1] == VolumeSeparatorChar)
- {
- // Path is at least longer than where we expect a colon, and has a colon (\\?\A:, A:)
- // If the colon is followed by a directory separator, move past it
- i = volumeSeparatorLength;
- if (pathLength >= volumeSeparatorLength + 1 && IsDirectorySeparator(path[volumeSeparatorLength])) i++;
- }
- return i;
- }
-
- private unsafe static bool StartsWithOrdinal(char* source, int sourceLength, string value)
- {
- if (sourceLength < value.Length) return false;
- for (int i = 0; i < value.Length; i++)
- {
- if (value[i] != source[i]) return false;
- }
- return true;
- }
-
- /// <summary>
- /// Returns true if the path specified is relative to the current drive or working directory.
- /// Returns false if the path is fixed to a specific drive or UNC path. This method does no
- /// validation of the path (URIs will be returned as relative as a result).
- /// </summary>
- /// <remarks>
- /// Handles paths that use the alternate directory separator. It is a frequent mistake to
- /// assume that rooted paths (Path.IsPathRooted) are not relative. This isn't the case.
- /// "C:a" is drive relative- meaning that it will be resolved against the current directory
- /// for C: (rooted, but relative). "C:\a" is rooted and not relative (the current directory
- /// will not be used to modify the path).
- /// </remarks>
- internal static bool IsPartiallyQualified(string path)
- {
- if (path.Length < 2)
- {
- // It isn't fixed, it must be relative. There is no way to specify a fixed
- // path with one character (or less).
- return true;
- }
-
- if (IsDirectorySeparator(path[0]))
- {
- // There is no valid way to specify a relative path with two initial slashes or
- // \? as ? isn't valid for drive relative paths and \??\ is equivalent to \\?\
- return !(path[1] == '?' || IsDirectorySeparator(path[1]));
- }
-
- // The only way to specify a fixed path that doesn't begin with two slashes
- // is the drive, colon, slash format- i.e. C:\
- return !((path.Length >= 3)
- && (path[1] == VolumeSeparatorChar)
- && IsDirectorySeparator(path[2])
- // To match old behavior we'll check the drive character for validity as the path is technically
- // not qualified if you don't have a valid drive. "=:\" is the "=" file's default data stream.
- && IsValidDriveChar(path[0]));
- }
-
- /// <summary>
- /// Returns the characters to skip at the start of the path if it starts with space(s) and a drive or directory separator.
- /// (examples are " C:", " \")
- /// This is a legacy behavior of Path.GetFullPath().
- /// </summary>
- /// <remarks>
- /// Note that this conflicts with IsPathRooted() which doesn't (and never did) such a skip.
- /// </remarks>
- internal static int PathStartSkip(string path)
- {
- int startIndex = 0;
- while (startIndex < path.Length && path[startIndex] == ' ') startIndex++;
-
- if (startIndex > 0 && (startIndex < path.Length && IsDirectorySeparator(path[startIndex]))
- || (startIndex + 1 < path.Length && path[startIndex + 1] == ':' && IsValidDriveChar(path[startIndex])))
- {
- // Go ahead and skip spaces as we're either " C:" or " \"
- return startIndex;
- }
-
- return 0;
- }
-
- /// <summary>
- /// True if the given character is a directory separator.
- /// </summary>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static bool IsDirectorySeparator(char c)
- {
- return c == DirectorySeparatorChar || c == AltDirectorySeparatorChar;
- }
-
- /// <summary>
- /// Normalize separators in the given path. Converts forward slashes into back slashes and compresses slash runs, keeping initial 2 if present.
- /// Also trims initial whitespace in front of "rooted" paths (see PathStartSkip).
- ///
- /// This effectively replicates the behavior of the legacy NormalizePath when it was called with fullCheck=false and expandShortpaths=false.
- /// The current NormalizePath gets directory separator normalization from Win32's GetFullPathName(), which will resolve relative paths and as
- /// such can't be used here (and is overkill for our uses).
- ///
- /// Like the current NormalizePath this will not try and analyze periods/spaces within directory segments.
- /// </summary>
- /// <remarks>
- /// The only callers that used to use Path.Normalize(fullCheck=false) were Path.GetDirectoryName() and Path.GetPathRoot(). Both usages do
- /// not need trimming of trailing whitespace here.
- ///
- /// GetPathRoot() could technically skip normalizing separators after the second segment- consider as a future optimization.
- ///
- /// For legacy desktop behavior with ExpandShortPaths:
- /// - It has no impact on GetPathRoot() so doesn't need consideration.
- /// - It could impact GetDirectoryName(), but only if the path isn't relative (C:\ or \\Server\Share).
- ///
- /// In the case of GetDirectoryName() the ExpandShortPaths behavior was undocumented and provided inconsistent results if the path was
- /// fixed/relative. For example: "C:\PROGRA~1\A.TXT" would return "C:\Program Files" while ".\PROGRA~1\A.TXT" would return ".\PROGRA~1". If you
- /// ultimately call GetFullPath() this doesn't matter, but if you don't or have any intermediate string handling could easily be tripped up by
- /// this undocumented behavior.
- ///
- /// We won't match this old behavior because:
- ///
- /// 1. It was undocumented
- /// 2. It was costly (extremely so if it actually contained '~')
- /// 3. Doesn't play nice with string logic
- /// 4. Isn't a cross-plat friendly concept/behavior
- /// </remarks>
- internal static string NormalizeDirectorySeparators(string path)
- {
- if (string.IsNullOrEmpty(path)) return path;
-
- char current;
- int start = PathStartSkip(path);
-
- if (start == 0)
- {
- // Make a pass to see if we need to normalize so we can potentially skip allocating
- bool normalized = true;
-
- for (int i = 0; i < path.Length; i++)
- {
- current = path[i];
- if (IsDirectorySeparator(current)
- && (current != DirectorySeparatorChar
- // Check for sequential separators past the first position (we need to keep initial two for UNC/extended)
- || (i > 0 && i + 1 < path.Length && IsDirectorySeparator(path[i + 1]))))
- {
- normalized = false;
- break;
- }
- }
-
- if (normalized) return path;
- }
-
- StringBuilder builder = new StringBuilder(path.Length);
-
- if (IsDirectorySeparator(path[start]))
- {
- start++;
- builder.Append(DirectorySeparatorChar);
- }
-
- for (int i = start; i < path.Length; i++)
- {
- current = path[i];
-
- // If we have a separator
- if (IsDirectorySeparator(current))
- {
- // If the next is a separator, skip adding this
- if (i + 1 < path.Length && IsDirectorySeparator(path[i + 1]))
- {
- continue;
- }
-
- // Ensure it is the primary separator
- current = DirectorySeparatorChar;
- }
-
- builder.Append(current);
- }
-
- return builder.ToString();
- }
-
- /// <summary>
- /// Returns true if the character is a directory or volume separator.
- /// </summary>
- /// <param name="ch">The character to test.</param>
- internal static bool IsDirectoryOrVolumeSeparator(char ch)
- {
- return IsDirectorySeparator(ch) || VolumeSeparatorChar == ch;
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.cs b/src/mscorlib/corefx/System/IO/PathInternal.cs
deleted file mode 100644
index 6b4c3b2d30..0000000000
--- a/src/mscorlib/corefx/System/IO/PathInternal.cs
+++ /dev/null
@@ -1,172 +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.Diagnostics;
-using System.Text;
-
-namespace System.IO
-{
- /// <summary>Contains internal path helpers that are shared between many projects.</summary>
- internal static partial class PathInternal
- {
- // Trim trailing white spaces, tabs etc but don't be aggressive in removing everything that has UnicodeCategory of trailing space.
- // string.WhitespaceChars will trim more aggressively than what the underlying FS does (for ex, NTFS, FAT).
- //
- // (This is for compatibility with old behavior.)
- internal static readonly char[] s_trimEndChars =
- {
- (char)0x9, // Horizontal tab
- (char)0xA, // Line feed
- (char)0xB, // Vertical tab
- (char)0xC, // Form feed
- (char)0xD, // Carriage return
- (char)0x20, // Space
- (char)0x85, // Next line
- (char)0xA0 // Non breaking space
- };
-
- /// <summary>
- /// Checks for invalid path characters in the given path.
- /// </summary>
- /// <exception cref="System.ArgumentNullException">Thrown if the path is null.</exception>
- /// <exception cref="System.ArgumentException">Thrown if the path has invalid characters.</exception>
- /// <param name="path">The path to check for invalid characters.</param>
- internal static void CheckInvalidPathChars(string path)
- {
- if (path == null)
- throw new ArgumentNullException(nameof(path));
-
- if (HasIllegalCharacters(path))
- throw new ArgumentException(SR.Argument_InvalidPathChars, nameof(path));
- }
-
- /// <summary>
- /// Returns the start index of the filename
- /// in the given path, or 0 if no directory
- /// or volume separator is found.
- /// </summary>
- /// <param name="path">The path in which to find the index of the filename.</param>
- /// <remarks>
- /// This method returns path.Length for
- /// inputs like "/usr/foo/" on Unix. As such,
- /// it is not safe for being used to index
- /// the string without additional verification.
- /// </remarks>
- internal static int FindFileNameIndex(string path)
- {
- Debug.Assert(path != null);
- CheckInvalidPathChars(path);
-
- for (int i = path.Length - 1; i >= 0; i--)
- {
- char ch = path[i];
- if (IsDirectoryOrVolumeSeparator(ch))
- return i + 1;
- }
-
- return 0; // the whole path is the filename
- }
-
- /// <summary>
- /// Returns true if the path ends in a directory separator.
- /// </summary>
- internal static bool EndsInDirectorySeparator(string path) =>
- !string.IsNullOrEmpty(path) && IsDirectorySeparator(path[path.Length - 1]);
-
- /// <summary>
- /// Get the common path length from the start of the string.
- /// </summary>
- internal static int GetCommonPathLength(string first, string second, bool ignoreCase)
- {
- int commonChars = EqualStartingCharacterCount(first, second, ignoreCase: ignoreCase);
-
- // If nothing matches
- if (commonChars == 0)
- return commonChars;
-
- // Or we're a full string and equal length or match to a separator
- if (commonChars == first.Length
- && (commonChars == second.Length || IsDirectorySeparator(second[commonChars])))
- return commonChars;
-
- if (commonChars == second.Length && IsDirectorySeparator(first[commonChars]))
- return commonChars;
-
- // It's possible we matched somewhere in the middle of a segment e.g. C:\Foodie and C:\Foobar.
- while (commonChars > 0 && !IsDirectorySeparator(first[commonChars - 1]))
- commonChars--;
-
- return commonChars;
- }
-
- /// <summary>
- /// Gets the count of common characters from the left optionally ignoring case
- /// </summary>
- unsafe internal static int EqualStartingCharacterCount(string first, string second, bool ignoreCase)
- {
- if (string.IsNullOrEmpty(first) || string.IsNullOrEmpty(second)) return 0;
-
- int commonChars = 0;
-
- fixed (char* f = first)
- fixed (char* s = second)
- {
- char* l = f;
- char* r = s;
- char* leftEnd = l + first.Length;
- char* rightEnd = r + second.Length;
-
- while (l != leftEnd && r != rightEnd
- && (*l == *r || (ignoreCase && char.ToUpperInvariant((*l)) == char.ToUpperInvariant((*r)))))
- {
- commonChars++;
- l++;
- r++;
- }
- }
-
- return commonChars;
- }
-
- /// <summary>
- /// Returns true if the two paths have the same root
- /// </summary>
- internal static bool AreRootsEqual(string first, string second, StringComparison comparisonType)
- {
- int firstRootLength = GetRootLength(first);
- int secondRootLength = GetRootLength(second);
-
- return firstRootLength == secondRootLength
- && string.Compare(
- strA: first,
- indexA: 0,
- strB: second,
- indexB: 0,
- length: firstRootLength,
- comparisonType: comparisonType) == 0;
- }
-
- /// <summary>
- /// Returns false for ".." unless it is specified as a part of a valid File/Directory name.
- /// (Used to avoid moving up directories.)
- ///
- /// Valid: a..b abc..d
- /// Invalid: ..ab ab.. .. abc..d\abc..
- /// </summary>
- internal static void CheckSearchPattern(string searchPattern)
- {
- int index;
- while ((index = searchPattern.IndexOf("..", StringComparison.Ordinal)) != -1)
- {
- // Terminal ".." . Files names cannot end in ".."
- if (index + 2 == searchPattern.Length
- || IsDirectorySeparator(searchPattern[index + 2]))
- throw new ArgumentException(SR.Arg_InvalidSearchPattern);
-
- searchPattern = searchPattern.Substring(index + 2);
- }
-
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Security/SafeBSTRHandle.cs b/src/mscorlib/corefx/System/Security/SafeBSTRHandle.cs
deleted file mode 100644
index 19d63d41e4..0000000000
--- a/src/mscorlib/corefx/System/Security/SafeBSTRHandle.cs
+++ /dev/null
@@ -1,81 +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.Diagnostics;
-using System.Runtime.InteropServices;
-
-namespace System.Security
-{
- internal sealed class SafeBSTRHandle : SafeBuffer
- {
- internal SafeBSTRHandle() : base(true) { }
-
- internal static SafeBSTRHandle Allocate(uint lenInChars)
- {
- uint lenInBytes = lenInChars * sizeof(char);
- SafeBSTRHandle bstr = Interop.OleAut32.SysAllocStringLen(IntPtr.Zero, lenInChars);
- if (bstr.IsInvalid) // SysAllocStringLen returns a NULL ptr when there's insufficient memory
- {
- throw new OutOfMemoryException();
- }
- bstr.Initialize(lenInBytes);
- return bstr;
- }
-
- override protected bool ReleaseHandle()
- {
- Interop.NtDll.ZeroMemory(handle, (UIntPtr)(Interop.OleAut32.SysStringLen(handle) * sizeof(char)));
- Interop.OleAut32.SysFreeString(handle);
- return true;
- }
-
- internal unsafe void ClearBuffer()
- {
- byte* bufferPtr = null;
- try
- {
- AcquirePointer(ref bufferPtr);
- Interop.NtDll.ZeroMemory((IntPtr)bufferPtr, (UIntPtr)(Interop.OleAut32.SysStringLen((IntPtr)bufferPtr) * sizeof(char)));
- }
- finally
- {
- if (bufferPtr != null)
- {
- ReleasePointer();
- }
- }
- }
-
- internal unsafe uint Length => Interop.OleAut32.SysStringLen(this);
-
- internal unsafe static void Copy(SafeBSTRHandle source, SafeBSTRHandle target, uint bytesToCopy)
- {
- if (bytesToCopy == 0)
- {
- return;
- }
-
- byte* sourcePtr = null, targetPtr = null;
- try
- {
- source.AcquirePointer(ref sourcePtr);
- target.AcquirePointer(ref targetPtr);
-
- Debug.Assert(source.ByteLength >= bytesToCopy, "Source buffer is too small.");
- Buffer.MemoryCopy(sourcePtr, targetPtr, target.ByteLength, bytesToCopy);
- }
- finally
- {
- if (targetPtr != null)
- {
- target.ReleasePointer();
- }
- if (sourcePtr != null)
- {
- source.ReleasePointer();
- }
- }
- }
- }
-}
diff --git a/src/mscorlib/corefx/System/Security/SecureString.Windows.cs b/src/mscorlib/corefx/System/Security/SecureString.Windows.cs
deleted file mode 100644
index 7ed0c6a15b..0000000000
--- a/src/mscorlib/corefx/System/Security/SecureString.Windows.cs
+++ /dev/null
@@ -1,310 +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.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Security.Cryptography;
-using Microsoft.Win32;
-
-namespace System.Security
-{
- public sealed partial class SecureString
- {
- internal SecureString(SecureString str)
- {
- Debug.Assert(str != null, "Expected non-null SecureString");
- Debug.Assert(str._buffer != null, "Expected other SecureString's buffer to be non-null");
- Debug.Assert(str._encrypted, "Expected to be used only on encrypted SecureStrings");
-
- AllocateBuffer(str._buffer.Length);
- SafeBSTRHandle.Copy(str._buffer, _buffer, str._buffer.Length * sizeof(char));
-
- _decryptedLength = str._decryptedLength;
- _encrypted = str._encrypted;
- }
-
- private unsafe void InitializeSecureString(char* value, int length)
- {
- Debug.Assert(length >= 0, $"Expected non-negative length, got {length}");
-
- AllocateBuffer((uint)length);
- _decryptedLength = length;
-
- byte* bufferPtr = null;
- try
- {
- _buffer.AcquirePointer(ref bufferPtr);
- Buffer.MemoryCopy((byte*)value, bufferPtr, (long)_buffer.ByteLength, length * sizeof(char));
- }
- finally
- {
- if (bufferPtr != null)
- {
- _buffer.ReleasePointer();
- }
- }
-
- ProtectMemory();
- }
-
- private void AppendCharCore(char c)
- {
- UnprotectMemory();
- try
- {
- EnsureCapacity(_decryptedLength + 1);
- _buffer.Write<char>((uint)_decryptedLength * sizeof(char), c);
- _decryptedLength++;
- }
- finally
- {
- ProtectMemory();
- }
- }
-
- private void ClearCore()
- {
- _decryptedLength = 0;
- _buffer.ClearBuffer();
- }
-
- private void DisposeCore()
- {
- if (_buffer != null)
- {
- _buffer.Dispose();
- _buffer = null;
- }
- }
-
- private unsafe void InsertAtCore(int index, char c)
- {
- byte* bufferPtr = null;
- UnprotectMemory();
- try
- {
- EnsureCapacity(_decryptedLength + 1);
-
- _buffer.AcquirePointer(ref bufferPtr);
- char* pBuffer = (char*)bufferPtr;
-
- for (int i = _decryptedLength; i > index; i--)
- {
- pBuffer[i] = pBuffer[i - 1];
- }
- pBuffer[index] = c;
- ++_decryptedLength;
- }
- finally
- {
- ProtectMemory();
- if (bufferPtr != null)
- {
- _buffer.ReleasePointer();
- }
- }
- }
-
- private unsafe void RemoveAtCore(int index)
- {
- byte* bufferPtr = null;
- UnprotectMemory();
- try
- {
- _buffer.AcquirePointer(ref bufferPtr);
- char* pBuffer = (char*)bufferPtr;
-
- for (int i = index; i < _decryptedLength - 1; i++)
- {
- pBuffer[i] = pBuffer[i + 1];
- }
- pBuffer[--_decryptedLength] = (char)0;
- }
- finally
- {
- ProtectMemory();
- if (bufferPtr != null)
- {
- _buffer.ReleasePointer();
- }
- }
- }
-
- private void SetAtCore(int index, char c)
- {
- UnprotectMemory();
- try
- {
- _buffer.Write<char>((uint)index * sizeof(char), c);
- }
- finally
- {
- ProtectMemory();
- }
- }
-
- internal unsafe IntPtr MarshalToBSTR()
- {
- int length = _decryptedLength;
- IntPtr ptr = IntPtr.Zero;
- IntPtr result = IntPtr.Zero;
- byte* bufferPtr = null;
-
- UnprotectMemory();
- try
- {
- _buffer.AcquirePointer(ref bufferPtr);
- int resultByteLength = (length + 1) * sizeof(char);
-
- ptr = Win32Native.SysAllocStringLen(null, length);
- if (ptr == IntPtr.Zero) {
- throw new OutOfMemoryException();
- }
-
- Buffer.MemoryCopy(bufferPtr, (byte*)ptr, resultByteLength, length * sizeof(char));
-
- result = ptr;
- }
- finally
- {
- ProtectMemory();
-
- // If we failed for any reason, free the new buffer
- if (result == IntPtr.Zero && ptr != IntPtr.Zero)
- {
- Interop.NtDll.ZeroMemory(ptr, (UIntPtr)(length * sizeof(char)));
- Win32Native.SysFreeString(ptr);
- }
-
- if (bufferPtr != null)
- {
- _buffer.ReleasePointer();
- }
- }
- return result;
- }
-
- internal unsafe IntPtr MarshalToStringCore(bool globalAlloc, bool unicode)
- {
- int length = _decryptedLength;
- IntPtr ptr = IntPtr.Zero;
- IntPtr result = IntPtr.Zero;
- byte* bufferPtr = null;
-
- UnprotectMemory();
- try
- {
- _buffer.AcquirePointer(ref bufferPtr);
- if (unicode)
- {
- int resultByteLength = (length + 1) * sizeof(char);
- ptr = globalAlloc ? Marshal.AllocHGlobal(resultByteLength) : Marshal.AllocCoTaskMem(resultByteLength);
- Buffer.MemoryCopy(bufferPtr, (byte*)ptr, resultByteLength, length * sizeof(char));
- *(length + (char*)ptr) = '\0';
- }
- else
- {
- uint defaultChar = '?';
- int resultByteLength = 1 + Interop.Kernel32.WideCharToMultiByte(
- Interop.Kernel32.CP_ACP, Interop.Kernel32.WC_NO_BEST_FIT_CHARS, (char*)bufferPtr, length, null, 0, (IntPtr)(&defaultChar), IntPtr.Zero);
- ptr = globalAlloc ? Marshal.AllocHGlobal(resultByteLength) : Marshal.AllocCoTaskMem(resultByteLength);
- Interop.Kernel32.WideCharToMultiByte(
- Interop.Kernel32.CP_ACP, Interop.Kernel32.WC_NO_BEST_FIT_CHARS, (char*)bufferPtr, length, (byte*)ptr, resultByteLength - 1, (IntPtr)(&defaultChar), IntPtr.Zero);
- *(resultByteLength - 1 + (byte*)ptr) = 0;
- }
- result = ptr;
- }
- finally
- {
- ProtectMemory();
-
- // If we failed for any reason, free the new buffer
- if (result == IntPtr.Zero && ptr != IntPtr.Zero)
- {
- Interop.NtDll.ZeroMemory(ptr, (UIntPtr)(length * sizeof(char)));
- MarshalFree(ptr, globalAlloc);
- }
-
- if (bufferPtr != null)
- {
- _buffer.ReleasePointer();
- }
- }
- return result;
- }
-
- private void EnsureNotDisposed()
- {
- if (_buffer == null)
- {
- throw new ObjectDisposedException(GetType().Name);
- }
- }
-
- // -----------------------------
- // ---- PAL layer ends here ----
- // -----------------------------
-
- private const int BlockSize = (int)Interop.Crypt32.CRYPTPROTECTMEMORY_BLOCK_SIZE / sizeof(char);
- private SafeBSTRHandle _buffer;
- private bool _encrypted;
-
- private void AllocateBuffer(uint size)
- {
- _buffer = SafeBSTRHandle.Allocate(GetAlignedSize(size));
- }
-
- private static uint GetAlignedSize(uint size) =>
- size == 0 || size % BlockSize != 0 ?
- BlockSize + ((size / BlockSize) * BlockSize) :
- size;
-
- private void EnsureCapacity(int capacity)
- {
- if (capacity > MaxLength)
- {
- throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_Capacity);
- }
-
- if (((uint)capacity * sizeof(char)) <= _buffer.ByteLength)
- {
- return;
- }
-
- var oldBuffer = _buffer;
- SafeBSTRHandle newBuffer = SafeBSTRHandle.Allocate(GetAlignedSize((uint)capacity));
- SafeBSTRHandle.Copy(oldBuffer, newBuffer, (uint)_decryptedLength * sizeof(char));
- _buffer = newBuffer;
- oldBuffer.Dispose();
- }
-
- private void ProtectMemory()
- {
- Debug.Assert(!_buffer.IsInvalid, "Invalid buffer!");
-
- if (_decryptedLength != 0 &&
- !_encrypted &&
- !Interop.Crypt32.CryptProtectMemory(_buffer, _buffer.Length * sizeof(char), Interop.Crypt32.CRYPTPROTECTMEMORY_SAME_PROCESS))
- {
- throw new CryptographicException(Marshal.GetLastWin32Error());
- }
-
- _encrypted = true;
- }
-
- private void UnprotectMemory()
- {
- Debug.Assert(!_buffer.IsInvalid, "Invalid buffer!");
-
- if (_decryptedLength != 0 &&
- _encrypted &&
- !Interop.Crypt32.CryptUnprotectMemory(_buffer, _buffer.Length * sizeof(char), Interop.Crypt32.CRYPTPROTECTMEMORY_SAME_PROCESS))
- {
- throw new CryptographicException(Marshal.GetLastWin32Error());
- }
-
- _encrypted = false;
- }
- }
-}
diff --git a/src/mscorlib/facade/mscorlib.csproj b/src/mscorlib/facade/mscorlib.csproj
deleted file mode 100644
index 038a698f23..0000000000
--- a/src/mscorlib/facade/mscorlib.csproj
+++ /dev/null
@@ -1,110 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
-
- <PropertyGroup>
- <AssemblyName>mscorlib</AssemblyName>
- <ProjectGuid>{263342A6-FC48-4CFC-B16A-2AF964D3536C}</ProjectGuid>
- <ClsCompliant>true</ClsCompliant>
- <AssemblyVersion>4.0.0.0</AssemblyVersion>
- <IsPartialFacadeAssembly>true</IsPartialFacadeAssembly>
- <OutputType>Library</OutputType>
- <ExcludeMscorlibFacade>true</ExcludeMscorlibFacade>
- <HighEntropyVA>true</HighEntropyVA>
-
- <!-- This prevents the default MsBuild targets from referencing System.Core.dll -->
- <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
- <!-- These prevent the default MsBuild targets from referencing System.dll and mscorlib.dll -->
- <NoStdLib>true</NoStdLib>
- <NoCompilerStandardLib>true</NoCompilerStandardLib>
-
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <AvailablePlatforms>amd64,x86,arm,armel,arm64</AvailablePlatforms>
- <Configuration Condition=" '$(Configuration)' == '' ">$(BuildType)</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">$(BuildArch)</Platform>
- <!-- The CLR properties use amd64 as their platform string, we want to keep in sync with those, so set Platform appropriately,
- though still use the 'x64' output path (see use of BuildArch below) -->
- <Platform Condition=" '$(Platform)' == 'x64' ">amd64</Platform>
- <Platform Condition=" '$(Platform)' == 'armel' ">arm</Platform>
-
- <!-- We want to exclude the transitive closure of the packages pulled in via project.json as that introduces ambiguity -->
- <OmitTransitiveCompileReferences>true</OmitTransitiveCompileReferences>
- <NuGetTargetMoniker>.NETStandard,Version=v1.3</NuGetTargetMoniker>
- </PropertyGroup>
-
- <!-- Default configurations to help VS understand the options -->
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcore50_Debug|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcore50_Release|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcore50aot_Debug|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcore50aot_Release|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net462_Debug|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net462_Release|AnyCPU'" />
-
- <!-- Roslyn does not support writing PDBs on Unix -->
- <PropertyGroup Condition="'$(OsEnvironment)' == 'Unix'">
- <DebugSymbols>false</DebugSymbols>
- <DebugType>none</DebugType>
- </PropertyGroup>
-
- <!-- Output paths -->
- <PropertyGroup>
- <BaseIntermediateOutputPath>$(RootBinDir)\obj</BaseIntermediateOutputPath>
- <!-- IntermediateOutputPath must have a trailing slash, however GenFacades
- surrounds the value in quotes when passing as the '-facadepath' argument.
- To avoid escaping the trailing quote, use a forward slash. -->
- <IntermediateOutputPath>$(BaseIntermediateOutputPath)\$(BuildOS).$(BuildArch).$(Configuration)\facade/</IntermediateOutputPath>
- <OutputPath>$(BinDir)\facade</OutputPath>
- </PropertyGroup>
-
- <ItemGroup>
- <ProjectReference Include="..\System.Private.CoreLib.csproj" />
- </ItemGroup>
-
- <ItemGroup>
- <None Include="project.json" />
- </ItemGroup>
-
- <PropertyGroup>
- <StrongNameSig>Silverlight</StrongNameSig>
- </PropertyGroup>
-
- <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-
- <PropertyGroup>
- <!-- Overwrite the key that we are going to use for signing -->
- <AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)..\Tools\Signing\mscorlib.snk</AssemblyOriginatorKeyFile>
- </PropertyGroup>
-
- <!-- the signing marker file is incorrectly named mscorlib.dll.requires_signing -->
- <Target Name="RenameSigningMarker" AfterTargets="WriteSigningRequired" Condition="Exists('$(TargetPath).requires_signing')">
- <Move SourceFiles="$(TargetPath).requires_signing" DestinationFiles="$(OutputPath)\System.Private.CoreLib.dll.requires_signing" />
- </Target>
-
- <ItemGroup>
- <SeedTypePreference Include="System.Console">
- <Assembly>System.Console</Assembly>
- </SeedTypePreference>
- <SeedTypePreference Include="System.IO.BinaryReader">
- <Assembly>System.IO</Assembly>
- </SeedTypePreference>
- <SeedTypePreference Include="System.IO.BinaryWriter">
- <Assembly>System.IO</Assembly>
- </SeedTypePreference>
- <SeedTypePreference Include="System.IO.EndOfStreamException">
- <Assembly>System.IO</Assembly>
- </SeedTypePreference>
- <SeedTypePreference Include="System.IO.MemoryStream">
- <Assembly>System.IO</Assembly>
- </SeedTypePreference>
- <SeedTypePreference Include="System.IO.SeekOrigin">
- <Assembly>System.IO</Assembly>
- </SeedTypePreference>
- <SeedTypePreference Include="System.IO.Stream">
- <Assembly>System.IO</Assembly>
- </SeedTypePreference>
- </ItemGroup>
-
-</Project>
diff --git a/src/mscorlib/facade/project.json b/src/mscorlib/facade/project.json
deleted file mode 100644
index b0b39a1264..0000000000
--- a/src/mscorlib/facade/project.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "dependencies": {
- "System.Console": "4.0.0",
- "System.IO": "4.1.0",
- "System.Security.Cryptography.Primitives": "4.0.0",
- "System.Security.Claims": "4.0.0",
- "System.Security.Principal": "4.0.0"
- },
- "frameworks": {
- "netstandard1.3": {
- "imports": [
- "dotnet5.4"
- ]
- }
- }
-} \ No newline at end of file
diff --git a/src/mscorlib/ref/mscorlib.cs b/src/mscorlib/ref/mscorlib.cs
deleted file mode 100644
index 680bf20675..0000000000
--- a/src/mscorlib/ref/mscorlib.cs
+++ /dev/null
@@ -1,13779 +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.
-
-namespace Internal.Runtime.Augments
-{
- public static partial class EnvironmentAugments
- {
- public static int CurrentManagedThreadId { get { throw null; } }
- public static int ExitCode { get { throw null; } set { } }
- public static bool HasShutdownStarted { get { throw null; } }
- public static string StackTrace { get { throw null; } }
- public static int TickCount { get { throw null; } }
- public static void Exit(int exitCode) { }
- public static void FailFast(string message, System.Exception error) { }
- public static string[] GetCommandLineArgs() { throw null; }
- }
- public partial class RuntimeThread : System.Runtime.ConstrainedExecution.CriticalFinalizerObject
- {
- public static Internal.Runtime.Augments.RuntimeThread CurrentThread { get { throw null; } }
- public bool IsAlive { get { throw null; } }
- public bool IsBackground { get { throw null; } set { } }
- public bool IsThreadPoolThread { get { throw null; } }
- public int ManagedThreadId { get { throw null; } }
- public string Name { get { throw null; } set { } }
- public System.Threading.ThreadPriority Priority { get { throw null; } set { } }
- public System.Threading.ThreadState ThreadState { get { throw null; } }
- ~RuntimeThread() { }
- public static Internal.Runtime.Augments.RuntimeThread Create(System.Threading.ThreadStart start) { throw null; }
- public static Internal.Runtime.Augments.RuntimeThread Create(System.Threading.ThreadStart start, int maxStackSize) { throw null; }
- public static Internal.Runtime.Augments.RuntimeThread Create(System.Threading.ParameterizedThreadStart start) { throw null; }
- public static Internal.Runtime.Augments.RuntimeThread Create(System.Threading.ParameterizedThreadStart start, int maxStackSize) { throw null; }
- public System.Threading.ApartmentState GetApartmentState() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public void Interrupt() { }
- public void Join() { }
- public bool Join(int millisecondsTimeout) { throw null; }
- public static void Sleep(int millisecondsTimeout) { }
- public static void SpinWait(int iterations) { }
- public void Start() { }
- public void Start(object parameter) { }
- public bool TrySetApartmentState(System.Threading.ApartmentState state) { throw null; }
- }
-}
-namespace Microsoft.Win32.SafeHandles
-{
- [System.Security.SecurityCriticalAttribute]
- public abstract partial class CriticalHandleMinusOneIsInvalid : System.Runtime.InteropServices.CriticalHandle
- {
- protected CriticalHandleMinusOneIsInvalid() : base(default(System.IntPtr)) { }
- public override bool IsInvalid { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- }
- [System.Security.SecurityCriticalAttribute]
- public abstract partial class CriticalHandleZeroOrMinusOneIsInvalid : System.Runtime.InteropServices.CriticalHandle
- {
- protected CriticalHandleZeroOrMinusOneIsInvalid() : base(default(System.IntPtr)) { }
- public override bool IsInvalid { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- }
- [System.Security.SecurityCriticalAttribute]
- public sealed partial class SafeFileHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
- {
- public SafeFileHandle(System.IntPtr preexistingHandle, bool ownsHandle) : base(default(bool)) { }
- public override bool IsInvalid { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- [System.Security.SecurityCriticalAttribute]
- protected override bool ReleaseHandle() { throw null; }
- }
- [System.Security.SecurityCriticalAttribute]
- public abstract partial class SafeHandleMinusOneIsInvalid : System.Runtime.InteropServices.SafeHandle
- {
- protected SafeHandleMinusOneIsInvalid(bool ownsHandle) { }
- public override bool IsInvalid { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- }
- [System.Security.SecurityCriticalAttribute]
- public abstract partial class SafeHandleZeroOrMinusOneIsInvalid : System.Runtime.InteropServices.SafeHandle
- {
- protected SafeHandleZeroOrMinusOneIsInvalid(bool ownsHandle) { }
- public override bool IsInvalid { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- }
- [System.Security.SecurityCriticalAttribute]
- public sealed partial class SafeWaitHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
- {
- public SafeWaitHandle(System.IntPtr existingHandle, bool ownsHandle) : base(ownsHandle) { }
- [System.Security.SecurityCriticalAttribute]
- protected override bool ReleaseHandle() { throw null; }
- }
-}
-namespace System
-{
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class AccessViolationException : System.SystemException
- {
- public AccessViolationException() { }
- public AccessViolationException(string message) { }
- public AccessViolationException(string message, System.Exception innerException) { }
- protected AccessViolationException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.CompilerServices.TypeForwardedFromAttribute("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
- public delegate void Action();
- public delegate void Action<in T>(T obj);
- [System.Runtime.CompilerServices.TypeForwardedFromAttribute("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
- public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
- [System.Runtime.CompilerServices.TypeForwardedFromAttribute("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
- public delegate void Action<in T1, in T2, in T3>(T1 arg1, T2 arg2, T3 arg3);
- [System.Runtime.CompilerServices.TypeForwardedFromAttribute("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
- public delegate void Action<in T1, in T2, in T3, in T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
- public delegate void Action<in T1, in T2, in T3, in T4, in T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
- public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
- public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
- public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class Activator
- {
- internal Activator() { }
- public static System.Runtime.Remoting.ObjectHandle CreateComInstanceFrom(string assemblyName, string typeName) { throw null; }
- public static System.Runtime.Remoting.ObjectHandle CreateComInstanceFrom(string assemblyName, string typeName, byte[] hashValue, System.Configuration.Assemblies.AssemblyHashAlgorithm hashAlgorithm) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Runtime.Remoting.ObjectHandle CreateInstance(string assemblyName, string typeName) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Runtime.Remoting.ObjectHandle CreateInstance(string assemblyName, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture, object[] activationAttributes) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Runtime.Remoting.ObjectHandle CreateInstance(string assemblyName, string typeName, object[] activationAttributes) { throw null; }
- public static object CreateInstance(System.Type type) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public static object CreateInstance(System.Type type, bool nonPublic) { throw null; }
- public static object CreateInstance(System.Type type, params object[] args) { throw null; }
- public static object CreateInstance(System.Type type, object[] args, object[] activationAttributes) { throw null; }
- public static object CreateInstance(System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static object CreateInstance(System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture, object[] activationAttributes) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public static T CreateInstance<T>() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.Runtime.Remoting.ObjectHandle CreateInstanceFrom(string assemblyFile, string typeName) { throw null; }
- public static System.Runtime.Remoting.ObjectHandle CreateInstanceFrom(string assemblyFile, string typeName, bool ignoreCase, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture, object[] activationAttributes) { throw null; }
- public static System.Runtime.Remoting.ObjectHandle CreateInstanceFrom(string assemblyFile, string typeName, object[] activationAttributes) { throw null; }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("Count = {InnerExceptionCount}")]
- public partial class AggregateException : System.Exception
- {
- public AggregateException() { }
- public AggregateException(System.Collections.Generic.IEnumerable<System.Exception> innerExceptions) { }
- public AggregateException(params System.Exception[] innerExceptions) { }
- public AggregateException(string message) { }
- public AggregateException(string message, System.Collections.Generic.IEnumerable<System.Exception> innerExceptions) { }
- public AggregateException(string message, System.Exception innerException) { }
- public AggregateException(string message, params System.Exception[] innerExceptions) { }
- protected AggregateException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- public System.Collections.ObjectModel.ReadOnlyCollection<System.Exception> InnerExceptions { get { throw null; } }
- public override string Message { get { throw null; } }
- public System.AggregateException Flatten() { throw null; }
- public override System.Exception GetBaseException() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public void Handle(System.Func<System.Exception, bool> predicate) { }
- public override string ToString() { throw null; }
- }
- public static partial class AppContext
- {
- public static string BaseDirectory { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public static string TargetFrameworkName { get { throw null; } }
- [System.Security.SecuritySafeCriticalAttribute]
- public static object GetData(string name) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void SetData(string name, object data) { }
- public static void SetSwitch(string switchName, bool isEnabled) { }
- public static bool TryGetSwitch(string switchName, out bool isEnabled) { isEnabled = default(bool); throw null; }
- public static event UnhandledExceptionEventHandler UnhandledException { add { } remove { } }
- public static event System.EventHandler<System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs> FirstChanceException { add { } remove { } }
- public static event System.EventHandler ProcessExit { add { } remove { } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ApplicationException : System.Exception
- {
- public ApplicationException() { }
- public ApplicationException(string message) { }
- public ApplicationException(string message, System.Exception innerException) { }
- protected ApplicationException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct ArgIterator
- {
- public override bool Equals(object o) { throw null; }
- public override int GetHashCode() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ArgumentException : System.SystemException, System.Runtime.Serialization.ISerializable
- {
- public ArgumentException() { }
- public ArgumentException(string message) { }
- public ArgumentException(string message, System.Exception innerException) { }
- public ArgumentException(string message, string paramName) { }
- public ArgumentException(string message, string paramName, System.Exception innerException) { }
- protected ArgumentException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- public override string Message { get { throw null; } }
- public virtual string ParamName { get { throw null; } }
- [System.Security.SecurityCriticalAttribute]
- public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ArgumentNullException : System.ArgumentException
- {
- public ArgumentNullException() { }
- public ArgumentNullException(string paramName) { }
- public ArgumentNullException(string message, System.Exception innerException) { }
- public ArgumentNullException(string paramName, string message) { }
- protected ArgumentNullException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ArgumentOutOfRangeException : System.ArgumentException, System.Runtime.Serialization.ISerializable
- {
- public ArgumentOutOfRangeException() { }
- public ArgumentOutOfRangeException(string paramName) { }
- public ArgumentOutOfRangeException(string message, System.Exception innerException) { }
- public ArgumentOutOfRangeException(string paramName, object actualValue, string message) { }
- public ArgumentOutOfRangeException(string paramName, string message) { }
- protected ArgumentOutOfRangeException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- public virtual object ActualValue { get { throw null; } }
- public override string Message { get { throw null; } }
- [System.Security.SecurityCriticalAttribute]
- public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ArithmeticException : System.SystemException
- {
- public ArithmeticException() { }
- public ArithmeticException(string message) { }
- public ArithmeticException(string message, System.Exception innerException) { }
- protected ArithmeticException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class Array : System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList, System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.ICloneable
- {
- internal Array() { }
- public bool IsFixedSize { get { throw null; } }
- public bool IsReadOnly { get { throw null; } }
- public bool IsSynchronized { get { throw null; } }
- public int Length { [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public long LongLength { [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } }
- public int Rank { [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } }
- public object SyncRoot { get { throw null; } }
- int System.Collections.ICollection.Count { get { throw null; } }
- object System.Collections.IList.this[int index] { get { throw null; } set { } }
- public static System.Collections.ObjectModel.ReadOnlyCollection<T> AsReadOnly<T>(T[] array) { throw null; }
- public static int BinarySearch(System.Array array, int index, int length, object value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static int BinarySearch(System.Array array, int index, int length, object value, System.Collections.IComparer comparer) { throw null; }
- public static int BinarySearch(System.Array array, object value) { throw null; }
- public static int BinarySearch(System.Array array, object value, System.Collections.IComparer comparer) { throw null; }
- public static int BinarySearch<T>(T[] array, T value) { throw null; }
- public static int BinarySearch<T>(T[] array, T value, System.Collections.Generic.IComparer<T> comparer) { throw null; }
- public static int BinarySearch<T>(T[] array, int index, int length, T value) { throw null; }
- public static int BinarySearch<T>(T[] array, int index, int length, T value, System.Collections.Generic.IComparer<T> comparer) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static void Clear(System.Array array, int index, int length) { }
- public object Clone() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void ConstrainedCopy(System.Array sourceArray, int sourceIndex, System.Array destinationArray, int destinationIndex, int length) { }
- public static TOutput[] ConvertAll<TInput, TOutput>(TInput[] array, System.Converter<TInput, TOutput> converter) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Copy(System.Array sourceArray, System.Array destinationArray, int length) { }
- public static void Copy(System.Array sourceArray, System.Array destinationArray, long length) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Copy(System.Array sourceArray, int sourceIndex, System.Array destinationArray, int destinationIndex, int length) { }
- public static void Copy(System.Array sourceArray, long sourceIndex, System.Array destinationArray, long destinationIndex, long length) { }
- public void CopyTo(System.Array array, int index) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public void CopyTo(System.Array array, long index) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Array CreateInstance(System.Type elementType, int length) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Array CreateInstance(System.Type elementType, int length1, int length2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Array CreateInstance(System.Type elementType, int length1, int length2, int length3) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Array CreateInstance(System.Type elementType, params int[] lengths) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Array CreateInstance(System.Type elementType, int[] lengths, int[] lowerBounds) { throw null; }
- public static System.Array CreateInstance(System.Type elementType, params long[] lengths) { throw null; }
- public static T[] Empty<T>() { throw null; }
- public static bool Exists<T>(T[] array, System.Predicate<T> match) { throw null; }
- public static T Find<T>(T[] array, System.Predicate<T> match) { throw null; }
- public static T[] FindAll<T>(T[] array, System.Predicate<T> match) { throw null; }
- public static int FindIndex<T>(T[] array, int startIndex, int count, System.Predicate<T> match) { throw null; }
- public static int FindIndex<T>(T[] array, int startIndex, System.Predicate<T> match) { throw null; }
- public static int FindIndex<T>(T[] array, System.Predicate<T> match) { throw null; }
- public static T FindLast<T>(T[] array, System.Predicate<T> match) { throw null; }
- public static int FindLastIndex<T>(T[] array, int startIndex, int count, System.Predicate<T> match) { throw null; }
- public static int FindLastIndex<T>(T[] array, int startIndex, System.Predicate<T> match) { throw null; }
- public static int FindLastIndex<T>(T[] array, System.Predicate<T> match) { throw null; }
- public static void ForEach<T>(T[] array, System.Action<T> action) { }
- public System.Collections.IEnumerator GetEnumerator() { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public int GetLength(int dimension) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public long GetLongLength(int dimension) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public int GetLowerBound(int dimension) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public int GetUpperBound(int dimension) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public object GetValue(int index) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public object GetValue(int index1, int index2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public object GetValue(int index1, int index2, int index3) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public object GetValue(params int[] indices) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public object GetValue(long index) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public object GetValue(long index1, long index2) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public object GetValue(long index1, long index2, long index3) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public object GetValue(params long[] indices) { throw null; }
- public static int IndexOf(System.Array array, object value) { throw null; }
- public static int IndexOf(System.Array array, object value, int startIndex) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static int IndexOf(System.Array array, object value, int startIndex, int count) { throw null; }
- public static int IndexOf<T>(T[] array, T value) { throw null; }
- public static int IndexOf<T>(T[] array, T value, int startIndex) { throw null; }
- public static int IndexOf<T>(T[] array, T value, int startIndex, int count) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public void Initialize() { }
- public static int LastIndexOf(System.Array array, object value) { throw null; }
- public static int LastIndexOf(System.Array array, object value, int startIndex) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static int LastIndexOf(System.Array array, object value, int startIndex, int count) { throw null; }
- public static int LastIndexOf<T>(T[] array, T value) { throw null; }
- public static int LastIndexOf<T>(T[] array, T value, int startIndex) { throw null; }
- public static int LastIndexOf<T>(T[] array, T value, int startIndex, int count) { throw null; }
- public static void Resize<T>(ref T[] array, int newSize) { }
- public static void Reverse(System.Array array) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Reverse(System.Array array, int index, int length) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetValue(object value, int index) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetValue(object value, int index1, int index2) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetValue(object value, int index1, int index2, int index3) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetValue(object value, params int[] indices) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public void SetValue(object value, long index) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public void SetValue(object value, long index1, long index2) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public void SetValue(object value, long index1, long index2, long index3) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public void SetValue(object value, params long[] indices) { }
- public static void Sort(System.Array array) { }
- public static void Sort(System.Array keys, System.Array items) { }
- public static void Sort(System.Array keys, System.Array items, System.Collections.IComparer comparer) { }
- public static void Sort(System.Array keys, System.Array items, int index, int length) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Sort(System.Array keys, System.Array items, int index, int length, System.Collections.IComparer comparer) { }
- public static void Sort(System.Array array, System.Collections.IComparer comparer) { }
- public static void Sort(System.Array array, int index, int length) { }
- public static void Sort(System.Array array, int index, int length, System.Collections.IComparer comparer) { }
- public static void Sort<T>(T[] array) { }
- public static void Sort<T>(T[] array, System.Collections.Generic.IComparer<T> comparer) { }
- public static void Sort<T>(T[] array, System.Comparison<T> comparison) { }
- public static void Sort<T>(T[] array, int index, int length) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Sort<T>(T[] array, int index, int length, System.Collections.Generic.IComparer<T> comparer) { }
- public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items) { }
- public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items, System.Collections.Generic.IComparer<TKey> comparer) { }
- public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items, int index, int length) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items, int index, int length, System.Collections.Generic.IComparer<TKey> comparer) { }
- int System.Collections.IList.Add(object value) { throw null; }
- void System.Collections.IList.Clear() { }
- bool System.Collections.IList.Contains(object value) { throw null; }
- int System.Collections.IList.IndexOf(object value) { throw null; }
- void System.Collections.IList.Insert(int index, object value) { }
- void System.Collections.IList.Remove(object value) { }
- void System.Collections.IList.RemoveAt(int index) { }
- int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; }
- bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; }
- int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; }
- public static bool TrueForAll<T>(T[] array, System.Predicate<T> match) { throw null; }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct ArraySegment<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>, System.Collections.IEnumerable
- {
- public ArraySegment(T[] array) { throw null;}
- public ArraySegment(T[] array, int offset, int count) { throw null;}
- public T[] Array { get { throw null; } }
- public int Count { get { throw null; } }
- public int Offset { get { throw null; } }
- bool System.Collections.Generic.ICollection<T>.IsReadOnly { get { throw null; } }
- T System.Collections.Generic.IList<T>.this[int index] { get { throw null; } set { } }
- T System.Collections.Generic.IReadOnlyList<T>.this[int index] { get { throw null; } }
- public bool Equals(System.ArraySegment<T> obj) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.ArraySegment<T> a, System.ArraySegment<T> b) { throw null; }
- public static bool operator !=(System.ArraySegment<T> a, System.ArraySegment<T> b) { throw null; }
- void System.Collections.Generic.ICollection<T>.Add(T item) { }
- void System.Collections.Generic.ICollection<T>.Clear() { }
- bool System.Collections.Generic.ICollection<T>.Contains(T item) { throw null; }
- void System.Collections.Generic.ICollection<T>.CopyTo(T[] array, int arrayIndex) { }
- bool System.Collections.Generic.ICollection<T>.Remove(T item) { throw null; }
- System.Collections.Generic.IEnumerator<T> System.Collections.Generic.IEnumerable<T>.GetEnumerator() { throw null; }
- int System.Collections.Generic.IList<T>.IndexOf(T item) { throw null; }
- void System.Collections.Generic.IList<T>.Insert(int index, T item) { }
- void System.Collections.Generic.IList<T>.RemoveAt(int index) { }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ArrayTypeMismatchException : System.SystemException
- {
- public ArrayTypeMismatchException() { }
- public ArrayTypeMismatchException(string message) { }
- public ArrayTypeMismatchException(string message, System.Exception innerException) { }
- protected ArrayTypeMismatchException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class AssemblyLoadEventArgs : System.EventArgs
- {
- public AssemblyLoadEventArgs(System.Reflection.Assembly loadedAssembly) { }
- public System.Reflection.Assembly LoadedAssembly { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public delegate void AssemblyLoadEventHandler(object sender, System.AssemblyLoadEventArgs args);
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public delegate void AsyncCallback(System.IAsyncResult ar);
- [System.AttributeUsageAttribute((System.AttributeTargets)(32767), Inherited = true, AllowMultiple = false)]
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class Attribute
- {
- protected Attribute() { }
- public virtual object TypeId { get { throw null; } }
- [System.Security.SecuritySafeCriticalAttribute]
- public override bool Equals(object obj) { throw null; }
- public static System.Attribute GetCustomAttribute(System.Reflection.Assembly element, System.Type attributeType) { throw null; }
- public static System.Attribute GetCustomAttribute(System.Reflection.Assembly element, System.Type attributeType, bool inherit) { throw null; }
- public static System.Attribute GetCustomAttribute(System.Reflection.MemberInfo element, System.Type attributeType) { throw null; }
- public static System.Attribute GetCustomAttribute(System.Reflection.MemberInfo element, System.Type attributeType, bool inherit) { throw null; }
- public static System.Attribute GetCustomAttribute(System.Reflection.Module element, System.Type attributeType) { throw null; }
- public static System.Attribute GetCustomAttribute(System.Reflection.Module element, System.Type attributeType, bool inherit) { throw null; }
- public static System.Attribute GetCustomAttribute(System.Reflection.ParameterInfo element, System.Type attributeType) { throw null; }
- public static System.Attribute GetCustomAttribute(System.Reflection.ParameterInfo element, System.Type attributeType, bool inherit) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.Assembly element) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.Assembly element, bool inherit) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.Assembly element, System.Type attributeType) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.Assembly element, System.Type attributeType, bool inherit) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.MemberInfo element) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.MemberInfo element, bool inherit) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.MemberInfo element, System.Type type) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.MemberInfo element, System.Type type, bool inherit) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.Module element) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.Module element, bool inherit) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.Module element, System.Type attributeType) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.Module element, System.Type attributeType, bool inherit) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.ParameterInfo element) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.ParameterInfo element, bool inherit) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.ParameterInfo element, System.Type attributeType) { throw null; }
- public static System.Attribute[] GetCustomAttributes(System.Reflection.ParameterInfo element, System.Type attributeType, bool inherit) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override int GetHashCode() { throw null; }
- public virtual bool IsDefaultAttribute() { throw null; }
- public static bool IsDefined(System.Reflection.Assembly element, System.Type attributeType) { throw null; }
- public static bool IsDefined(System.Reflection.Assembly element, System.Type attributeType, bool inherit) { throw null; }
- public static bool IsDefined(System.Reflection.MemberInfo element, System.Type attributeType) { throw null; }
- public static bool IsDefined(System.Reflection.MemberInfo element, System.Type attributeType, bool inherit) { throw null; }
- public static bool IsDefined(System.Reflection.Module element, System.Type attributeType) { throw null; }
- public static bool IsDefined(System.Reflection.Module element, System.Type attributeType, bool inherit) { throw null; }
- public static bool IsDefined(System.Reflection.ParameterInfo element, System.Type attributeType) { throw null; }
- public static bool IsDefined(System.Reflection.ParameterInfo element, System.Type attributeType, bool inherit) { throw null; }
- public virtual bool Match(object obj) { throw null; }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum AttributeTargets
- {
- All = 32767,
- Assembly = 1,
- Class = 4,
- Constructor = 32,
- Delegate = 4096,
- Enum = 16,
- Event = 512,
- Field = 256,
- GenericParameter = 16384,
- Interface = 1024,
- Method = 64,
- Module = 2,
- Parameter = 2048,
- Property = 128,
- ReturnValue = 8192,
- Struct = 8,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(4), Inherited=true)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AttributeUsageAttribute : System.Attribute
- {
- public AttributeUsageAttribute(System.AttributeTargets validOn) { }
- public bool AllowMultiple { get { throw null; } set { } }
- public bool Inherited { get { throw null; } set { } }
- public System.AttributeTargets ValidOn { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class BadImageFormatException : System.SystemException
- {
- public BadImageFormatException() { }
- protected BadImageFormatException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public BadImageFormatException(string message) { }
- public BadImageFormatException(string message, System.Exception inner) { }
- public BadImageFormatException(string message, string fileName) { }
- public BadImageFormatException(string message, string fileName, System.Exception inner) { }
- public string FileName { get { throw null; } }
- public string FusionLog { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public override string Message { get { throw null; } }
- [System.Security.SecurityCriticalAttribute]
- public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public override string ToString() { throw null; }
- }
- [System.FlagsAttribute]
- public enum Base64FormattingOptions
- {
- InsertLineBreaks = 1,
- None = 0,
- }
- public static partial class BitConverter
- {
- public static readonly bool IsLittleEndian;
- [System.Security.SecuritySafeCriticalAttribute]
- public static long DoubleToInt64Bits(double value) { throw null; }
- public static byte[] GetBytes(bool value) { throw null; }
- public static byte[] GetBytes(char value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static byte[] GetBytes(double value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static byte[] GetBytes(short value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static byte[] GetBytes(int value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static byte[] GetBytes(long value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static byte[] GetBytes(float value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static byte[] GetBytes(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static byte[] GetBytes(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static byte[] GetBytes(ulong value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static float Int32BitsToSingle(int value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static double Int64BitsToDouble(long value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static int SingleToInt32Bits(float value) { throw null; }
- public static bool ToBoolean(byte[] value, int startIndex) { throw null; }
- public static char ToChar(byte[] value, int startIndex) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static double ToDouble(byte[] value, int startIndex) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static short ToInt16(byte[] value, int startIndex) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static int ToInt32(byte[] value, int startIndex) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static long ToInt64(byte[] value, int startIndex) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static float ToSingle(byte[] value, int startIndex) { throw null; }
- public static string ToString(byte[] value) { throw null; }
- public static string ToString(byte[] value, int startIndex) { throw null; }
- public static string ToString(byte[] value, int startIndex, int length) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(byte[] value, int startIndex) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(byte[] value, int startIndex) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(byte[] value, int startIndex) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Boolean : System.IComparable, System.IComparable<bool>, System.IConvertible, System.IEquatable<bool>
- {
- public static readonly string FalseString;
- public static readonly string TrueString;
- public int CompareTo(System.Boolean value) { throw null; }
- public int CompareTo(object obj) { throw null; }
- public System.Boolean Equals(System.Boolean obj) { throw null; }
- public override System.Boolean Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- public static System.Boolean Parse(string value) { throw null; }
- System.Boolean System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- public override string ToString() { throw null; }
- public string ToString(System.IFormatProvider provider) { throw null; }
- public static System.Boolean TryParse(string value, out System.Boolean result) { result = default(bool); throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static partial class Buffer
- {
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static void BlockCopy(System.Array src, int srcOffset, System.Array dst, int dstOffset, int count) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static int ByteLength(System.Array array) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static byte GetByte(System.Array array, int index) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)][System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe static void MemoryCopy(void* source, void* destination, long destinationSizeInBytes, long sourceBytesToCopy) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)][System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe static void MemoryCopy(void* source, void* destination, ulong destinationSizeInBytes, ulong sourceBytesToCopy) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void SetByte(System.Array array, int index, byte value) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Byte : System.IComparable, System.IComparable<byte>, System.IConvertible, System.IEquatable<byte>, System.IFormattable
- {
- public const byte MaxValue = (byte)255;
- public const byte MinValue = (byte)0;
- public int CompareTo(System.Byte value) { throw null; }
- public int CompareTo(object value) { throw null; }
- public bool Equals(System.Byte obj) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- public static System.Byte Parse(string s) { throw null; }
- public static System.Byte Parse(string s, System.Globalization.NumberStyles style) { throw null; }
- public static System.Byte Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider) { throw null; }
- public static System.Byte Parse(string s, System.IFormatProvider provider) { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- System.Byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format, System.IFormatProvider provider) { throw null; }
- public static bool TryParse(string s, out System.Byte result) { result = default(byte); throw null; }
- public static bool TryParse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider, out System.Byte result) { result = default(byte); throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Char : System.IComparable, System.IComparable<char>, System.IConvertible, System.IEquatable<char>
- {
- public const char MaxValue = '\uFFFF';
- public const char MinValue = '\0';
- public int CompareTo(System.Char value) { throw null; }
- public int CompareTo(object value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static string ConvertFromUtf32(int utf32) { throw null; }
- public static int ConvertToUtf32(System.Char highSurrogate, System.Char lowSurrogate) { throw null; }
- public static int ConvertToUtf32(string s, int index) { throw null; }
- public bool Equals(System.Char obj) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static double GetNumericValue(System.Char c) { throw null; }
- public static double GetNumericValue(string s, int index) { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- public static System.Globalization.UnicodeCategory GetUnicodeCategory(System.Char c) { throw null; }
- public static System.Globalization.UnicodeCategory GetUnicodeCategory(string s, int index) { throw null; }
- public static bool IsControl(System.Char c) { throw null; }
- public static bool IsControl(string s, int index) { throw null; }
- public static bool IsDigit(System.Char c) { throw null; }
- public static bool IsDigit(string s, int index) { throw null; }
- public static bool IsHighSurrogate(System.Char c) { throw null; }
- public static bool IsHighSurrogate(string s, int index) { throw null; }
- public static bool IsLetter(System.Char c) { throw null; }
- public static bool IsLetter(string s, int index) { throw null; }
- public static bool IsLetterOrDigit(System.Char c) { throw null; }
- public static bool IsLetterOrDigit(string s, int index) { throw null; }
- public static bool IsLower(System.Char c) { throw null; }
- public static bool IsLower(string s, int index) { throw null; }
- public static bool IsLowSurrogate(System.Char c) { throw null; }
- public static bool IsLowSurrogate(string s, int index) { throw null; }
- public static bool IsNumber(System.Char c) { throw null; }
- public static bool IsNumber(string s, int index) { throw null; }
- public static bool IsPunctuation(System.Char c) { throw null; }
- public static bool IsPunctuation(string s, int index) { throw null; }
- public static bool IsSeparator(System.Char c) { throw null; }
- public static bool IsSeparator(string s, int index) { throw null; }
- public static bool IsSurrogate(System.Char c) { throw null; }
- public static bool IsSurrogate(string s, int index) { throw null; }
- public static bool IsSurrogatePair(System.Char highSurrogate, System.Char lowSurrogate) { throw null; }
- public static bool IsSurrogatePair(string s, int index) { throw null; }
- public static bool IsSymbol(System.Char c) { throw null; }
- public static bool IsSymbol(string s, int index) { throw null; }
- public static bool IsUpper(System.Char c) { throw null; }
- public static bool IsUpper(string s, int index) { throw null; }
- public static bool IsWhiteSpace(System.Char c) { throw null; }
- public static bool IsWhiteSpace(string s, int index) { throw null; }
- public static System.Char Parse(string s) { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- System.Char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- public static System.Char ToLower(System.Char c) { throw null; }
- public static System.Char ToLower(System.Char c, System.Globalization.CultureInfo culture) { throw null; }
- public static System.Char ToLowerInvariant(System.Char c) { throw null; }
- public override string ToString() { throw null; }
- public static string ToString(System.Char c) { throw null; }
- public string ToString(System.IFormatProvider provider) { throw null; }
- public static System.Char ToUpper(System.Char c) { throw null; }
- public static System.Char ToUpper(System.Char c, System.Globalization.CultureInfo culture) { throw null; }
- public static System.Char ToUpperInvariant(System.Char c) { throw null; }
- public static bool TryParse(string s, out System.Char result) { result = default(char); throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class CharEnumerator : System.Collections.Generic.IEnumerator<char>, System.Collections.IEnumerator, System.ICloneable, System.IDisposable
- {
- internal CharEnumerator() { }
- public char Current { get { throw null; } }
- object System.Collections.IEnumerator.Current { get { throw null; } }
- public object Clone() { throw null; }
- public void Dispose() { }
- public bool MoveNext() { throw null; }
- public void Reset() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(32767), Inherited=true, AllowMultiple=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class CLSCompliantAttribute : System.Attribute
- {
- public CLSCompliantAttribute(bool isCompliant) { }
- public bool IsCompliant { get { throw null; } }
- }
- public delegate int Comparison<in T>(T x, T y);
- public static partial class Console
- {
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Write(string value) { }
- public static void WriteLine() { }
- public static void WriteLine(string value) { }
- }
- public static partial class Convert
- {
- public static readonly object DBNull;
- public static object ChangeType(object value, System.Type conversionType) { throw null; }
- public static object ChangeType(object value, System.Type conversionType, System.IFormatProvider provider) { throw null; }
- public static object ChangeType(object value, System.TypeCode typeCode) { throw null; }
- public static object ChangeType(object value, System.TypeCode typeCode, System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static byte[] FromBase64CharArray(char[] inArray, int offset, int length) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static byte[] FromBase64String(string s) { throw null; }
- public static System.TypeCode GetTypeCode(object value) { throw null; }
- public static bool IsDBNull(object value) { throw null; }
- public static int ToBase64CharArray(byte[] inArray, int offsetIn, int length, char[] outArray, int offsetOut) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static int ToBase64CharArray(byte[] inArray, int offsetIn, int length, char[] outArray, int offsetOut, System.Base64FormattingOptions options) { throw null; }
- public static string ToBase64String(byte[] inArray) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public static string ToBase64String(byte[] inArray, System.Base64FormattingOptions options) { throw null; }
- public static string ToBase64String(byte[] inArray, int offset, int length) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static string ToBase64String(byte[] inArray, int offset, int length, System.Base64FormattingOptions options) { throw null; }
- public static bool ToBoolean(bool value) { throw null; }
- public static bool ToBoolean(byte value) { throw null; }
- public static bool ToBoolean(char value) { throw null; }
- public static bool ToBoolean(System.DateTime value) { throw null; }
- public static bool ToBoolean(decimal value) { throw null; }
- public static bool ToBoolean(double value) { throw null; }
- public static bool ToBoolean(short value) { throw null; }
- public static bool ToBoolean(int value) { throw null; }
- public static bool ToBoolean(long value) { throw null; }
- public static bool ToBoolean(object value) { throw null; }
- public static bool ToBoolean(object value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static bool ToBoolean(sbyte value) { throw null; }
- public static bool ToBoolean(float value) { throw null; }
- public static bool ToBoolean(string value) { throw null; }
- public static bool ToBoolean(string value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static bool ToBoolean(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static bool ToBoolean(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static bool ToBoolean(ulong value) { throw null; }
- public static byte ToByte(bool value) { throw null; }
- public static byte ToByte(byte value) { throw null; }
- public static byte ToByte(char value) { throw null; }
- public static byte ToByte(System.DateTime value) { throw null; }
- public static byte ToByte(decimal value) { throw null; }
- public static byte ToByte(double value) { throw null; }
- public static byte ToByte(short value) { throw null; }
- public static byte ToByte(int value) { throw null; }
- public static byte ToByte(long value) { throw null; }
- public static byte ToByte(object value) { throw null; }
- public static byte ToByte(object value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static byte ToByte(sbyte value) { throw null; }
- public static byte ToByte(float value) { throw null; }
- public static byte ToByte(string value) { throw null; }
- public static byte ToByte(string value, System.IFormatProvider provider) { throw null; }
- public static byte ToByte(string value, int fromBase) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static byte ToByte(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static byte ToByte(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static byte ToByte(ulong value) { throw null; }
- public static char ToChar(bool value) { throw null; }
- public static char ToChar(byte value) { throw null; }
- public static char ToChar(char value) { throw null; }
- public static char ToChar(System.DateTime value) { throw null; }
- public static char ToChar(decimal value) { throw null; }
- public static char ToChar(double value) { throw null; }
- public static char ToChar(short value) { throw null; }
- public static char ToChar(int value) { throw null; }
- public static char ToChar(long value) { throw null; }
- public static char ToChar(object value) { throw null; }
- public static char ToChar(object value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static char ToChar(sbyte value) { throw null; }
- public static char ToChar(float value) { throw null; }
- public static char ToChar(string value) { throw null; }
- public static char ToChar(string value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static char ToChar(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static char ToChar(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static char ToChar(ulong value) { throw null; }
- public static System.DateTime ToDateTime(bool value) { throw null; }
- public static System.DateTime ToDateTime(byte value) { throw null; }
- public static System.DateTime ToDateTime(char value) { throw null; }
- public static System.DateTime ToDateTime(System.DateTime value) { throw null; }
- public static System.DateTime ToDateTime(decimal value) { throw null; }
- public static System.DateTime ToDateTime(double value) { throw null; }
- public static System.DateTime ToDateTime(short value) { throw null; }
- public static System.DateTime ToDateTime(int value) { throw null; }
- public static System.DateTime ToDateTime(long value) { throw null; }
- public static System.DateTime ToDateTime(object value) { throw null; }
- public static System.DateTime ToDateTime(object value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.DateTime ToDateTime(sbyte value) { throw null; }
- public static System.DateTime ToDateTime(float value) { throw null; }
- public static System.DateTime ToDateTime(string value) { throw null; }
- public static System.DateTime ToDateTime(string value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.DateTime ToDateTime(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.DateTime ToDateTime(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.DateTime ToDateTime(ulong value) { throw null; }
- public static decimal ToDecimal(bool value) { throw null; }
- public static decimal ToDecimal(byte value) { throw null; }
- public static decimal ToDecimal(char value) { throw null; }
- public static decimal ToDecimal(System.DateTime value) { throw null; }
- public static decimal ToDecimal(decimal value) { throw null; }
- public static decimal ToDecimal(double value) { throw null; }
- public static decimal ToDecimal(short value) { throw null; }
- public static decimal ToDecimal(int value) { throw null; }
- public static decimal ToDecimal(long value) { throw null; }
- public static decimal ToDecimal(object value) { throw null; }
- public static decimal ToDecimal(object value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static decimal ToDecimal(sbyte value) { throw null; }
- public static decimal ToDecimal(float value) { throw null; }
- public static decimal ToDecimal(string value) { throw null; }
- public static decimal ToDecimal(string value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static decimal ToDecimal(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static decimal ToDecimal(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static decimal ToDecimal(ulong value) { throw null; }
- public static double ToDouble(bool value) { throw null; }
- public static double ToDouble(byte value) { throw null; }
- public static double ToDouble(char value) { throw null; }
- public static double ToDouble(System.DateTime value) { throw null; }
- public static double ToDouble(decimal value) { throw null; }
- public static double ToDouble(double value) { throw null; }
- public static double ToDouble(short value) { throw null; }
- public static double ToDouble(int value) { throw null; }
- public static double ToDouble(long value) { throw null; }
- public static double ToDouble(object value) { throw null; }
- public static double ToDouble(object value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static double ToDouble(sbyte value) { throw null; }
- public static double ToDouble(float value) { throw null; }
- public static double ToDouble(string value) { throw null; }
- public static double ToDouble(string value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static double ToDouble(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static double ToDouble(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static double ToDouble(ulong value) { throw null; }
- public static short ToInt16(bool value) { throw null; }
- public static short ToInt16(byte value) { throw null; }
- public static short ToInt16(char value) { throw null; }
- public static short ToInt16(System.DateTime value) { throw null; }
- public static short ToInt16(decimal value) { throw null; }
- public static short ToInt16(double value) { throw null; }
- public static short ToInt16(short value) { throw null; }
- public static short ToInt16(int value) { throw null; }
- public static short ToInt16(long value) { throw null; }
- public static short ToInt16(object value) { throw null; }
- public static short ToInt16(object value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static short ToInt16(sbyte value) { throw null; }
- public static short ToInt16(float value) { throw null; }
- public static short ToInt16(string value) { throw null; }
- public static short ToInt16(string value, System.IFormatProvider provider) { throw null; }
- public static short ToInt16(string value, int fromBase) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static short ToInt16(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static short ToInt16(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static short ToInt16(ulong value) { throw null; }
- public static int ToInt32(bool value) { throw null; }
- public static int ToInt32(byte value) { throw null; }
- public static int ToInt32(char value) { throw null; }
- public static int ToInt32(System.DateTime value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static int ToInt32(decimal value) { throw null; }
- public static int ToInt32(double value) { throw null; }
- public static int ToInt32(short value) { throw null; }
- public static int ToInt32(int value) { throw null; }
- public static int ToInt32(long value) { throw null; }
- public static int ToInt32(object value) { throw null; }
- public static int ToInt32(object value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static int ToInt32(sbyte value) { throw null; }
- public static int ToInt32(float value) { throw null; }
- public static int ToInt32(string value) { throw null; }
- public static int ToInt32(string value, System.IFormatProvider provider) { throw null; }
- public static int ToInt32(string value, int fromBase) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static int ToInt32(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static int ToInt32(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static int ToInt32(ulong value) { throw null; }
- public static long ToInt64(bool value) { throw null; }
- public static long ToInt64(byte value) { throw null; }
- public static long ToInt64(char value) { throw null; }
- public static long ToInt64(System.DateTime value) { throw null; }
- public static long ToInt64(decimal value) { throw null; }
- public static long ToInt64(double value) { throw null; }
- public static long ToInt64(short value) { throw null; }
- public static long ToInt64(int value) { throw null; }
- public static long ToInt64(long value) { throw null; }
- public static long ToInt64(object value) { throw null; }
- public static long ToInt64(object value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static long ToInt64(sbyte value) { throw null; }
- public static long ToInt64(float value) { throw null; }
- public static long ToInt64(string value) { throw null; }
- public static long ToInt64(string value, System.IFormatProvider provider) { throw null; }
- public static long ToInt64(string value, int fromBase) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static long ToInt64(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static long ToInt64(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static long ToInt64(ulong value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(bool value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(byte value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(char value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(System.DateTime value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(decimal value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(double value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(short value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(int value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(long value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(object value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(object value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(sbyte value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(float value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(string value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(string value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(string value, int fromBase) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(ulong value) { throw null; }
- public static float ToSingle(bool value) { throw null; }
- public static float ToSingle(byte value) { throw null; }
- public static float ToSingle(char value) { throw null; }
- public static float ToSingle(System.DateTime value) { throw null; }
- public static float ToSingle(decimal value) { throw null; }
- public static float ToSingle(double value) { throw null; }
- public static float ToSingle(short value) { throw null; }
- public static float ToSingle(int value) { throw null; }
- public static float ToSingle(long value) { throw null; }
- public static float ToSingle(object value) { throw null; }
- public static float ToSingle(object value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static float ToSingle(sbyte value) { throw null; }
- public static float ToSingle(float value) { throw null; }
- public static float ToSingle(string value) { throw null; }
- public static float ToSingle(string value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static float ToSingle(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static float ToSingle(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static float ToSingle(ulong value) { throw null; }
- public static string ToString(bool value) { throw null; }
- public static string ToString(bool value, System.IFormatProvider provider) { throw null; }
- public static string ToString(byte value) { throw null; }
- public static string ToString(byte value, System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static string ToString(byte value, int toBase) { throw null; }
- public static string ToString(char value) { throw null; }
- public static string ToString(char value, System.IFormatProvider provider) { throw null; }
- public static string ToString(System.DateTime value) { throw null; }
- public static string ToString(System.DateTime value, System.IFormatProvider provider) { throw null; }
- public static string ToString(decimal value) { throw null; }
- public static string ToString(decimal value, System.IFormatProvider provider) { throw null; }
- public static string ToString(double value) { throw null; }
- public static string ToString(double value, System.IFormatProvider provider) { throw null; }
- public static string ToString(short value) { throw null; }
- public static string ToString(short value, System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static string ToString(short value, int toBase) { throw null; }
- public static string ToString(int value) { throw null; }
- public static string ToString(int value, System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static string ToString(int value, int toBase) { throw null; }
- public static string ToString(long value) { throw null; }
- public static string ToString(long value, System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static string ToString(long value, int toBase) { throw null; }
- public static string ToString(object value) { throw null; }
- public static string ToString(object value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static string ToString(sbyte value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static string ToString(sbyte value, System.IFormatProvider provider) { throw null; }
- public static string ToString(float value) { throw null; }
- public static string ToString(float value, System.IFormatProvider provider) { throw null; }
- public static string ToString(string value) { throw null; }
- public static string ToString(string value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static string ToString(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static string ToString(ushort value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static string ToString(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static string ToString(uint value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static string ToString(ulong value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static string ToString(ulong value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(bool value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(byte value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(char value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(System.DateTime value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(decimal value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(double value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(short value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(int value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(long value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(object value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(object value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(sbyte value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(float value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(string value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(string value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(string value, int fromBase) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(ulong value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(bool value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(byte value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(char value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(System.DateTime value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(decimal value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(double value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(short value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(int value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(long value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(object value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(object value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(sbyte value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(float value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(string value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(string value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(string value, int fromBase) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint ToUInt32(ulong value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(bool value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(byte value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(char value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(System.DateTime value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(decimal value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(double value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(short value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(int value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(long value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(object value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(object value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(sbyte value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(float value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(string value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(string value, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(string value, int fromBase) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong ToUInt64(ulong value) { throw null; }
- }
- public delegate TOutput Converter<in TInput, out TOutput>(TInput input);
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DataMisalignedException : System.SystemException
- {
- public DataMisalignedException() { }
- public DataMisalignedException(string message) { }
- public DataMisalignedException(string message, System.Exception innerException) { }
- }
- public partial struct DateTime : System.IComparable, System.IComparable<System.DateTime>, System.IConvertible, System.IEquatable<System.DateTime>, System.IFormattable, System.Runtime.Serialization.ISerializable
- {
- public static readonly System.DateTime MaxValue;
- public static readonly System.DateTime MinValue;
- public DateTime(int year, int month, int day) { throw null;}
- public DateTime(int year, int month, int day, System.Globalization.Calendar calendar) { throw null;}
- public DateTime(int year, int month, int day, int hour, int minute, int second) { throw null;}
- public DateTime(int year, int month, int day, int hour, int minute, int second, System.DateTimeKind kind) { throw null;}
- public DateTime(int year, int month, int day, int hour, int minute, int second, System.Globalization.Calendar calendar) { throw null;}
- public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond) { throw null;}
- public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, System.DateTimeKind kind) { throw null;}
- public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, System.Globalization.Calendar calendar) { throw null;}
- public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, System.Globalization.Calendar calendar, System.DateTimeKind kind) { throw null;}
- public DateTime(long ticks) { throw null;}
- public DateTime(long ticks, System.DateTimeKind kind) { throw null;}
- public System.DateTime Date { get { throw null; } }
- public int Day { get { throw null; } }
- public System.DayOfWeek DayOfWeek { get { throw null; } }
- public int DayOfYear { get { throw null; } }
- public int Hour { get { throw null; } }
- public System.DateTimeKind Kind { get { throw null; } }
- public int Millisecond { get { throw null; } }
- public int Minute { get { throw null; } }
- public int Month { get { throw null; } }
- public static System.DateTime Now { get { throw null; } }
- public int Second { get { throw null; } }
- public long Ticks { get { throw null; } }
- public System.TimeSpan TimeOfDay { get { throw null; } }
- public static System.DateTime Today { get { throw null; } }
- public static System.DateTime UtcNow { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public int Year { get { throw null; } }
- public System.DateTime Add(System.TimeSpan value) { throw null; }
- public System.DateTime AddDays(double value) { throw null; }
- public System.DateTime AddHours(double value) { throw null; }
- public System.DateTime AddMilliseconds(double value) { throw null; }
- public System.DateTime AddMinutes(double value) { throw null; }
- public System.DateTime AddMonths(int months) { throw null; }
- public System.DateTime AddSeconds(double value) { throw null; }
- public System.DateTime AddTicks(long value) { throw null; }
- public System.DateTime AddYears(int value) { throw null; }
- public static int Compare(System.DateTime t1, System.DateTime t2) { throw null; }
- public int CompareTo(System.DateTime value) { throw null; }
- public int CompareTo(object value) { throw null; }
- public static int DaysInMonth(int year, int month) { throw null; }
- public bool Equals(System.DateTime value) { throw null; }
- public static bool Equals(System.DateTime t1, System.DateTime t2) { throw null; }
- public override bool Equals(object value) { throw null; }
- public static System.DateTime FromBinary(long dateData) { throw null; }
- public static System.DateTime FromFileTime(long fileTime) { throw null; }
- public static System.DateTime FromFileTimeUtc(long fileTime) { throw null; }
- public static System.DateTime FromOADate(double d) { throw null; }
- public string[] GetDateTimeFormats() { throw null; }
- public string[] GetDateTimeFormats(char format) { throw null; }
- public string[] GetDateTimeFormats(char format, System.IFormatProvider provider) { throw null; }
- public string[] GetDateTimeFormats(System.IFormatProvider provider) { throw null; }
- public override int GetHashCode() { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- public bool IsDaylightSavingTime() { throw null; }
- public static bool IsLeapYear(int year) { throw null; }
- public static System.DateTime operator +(System.DateTime d, System.TimeSpan t) { throw null; }
- public static bool operator ==(System.DateTime d1, System.DateTime d2) { throw null; }
- public static bool operator >(System.DateTime t1, System.DateTime t2) { throw null; }
- public static bool operator >=(System.DateTime t1, System.DateTime t2) { throw null; }
- public static bool operator !=(System.DateTime d1, System.DateTime d2) { throw null; }
- public static bool operator <(System.DateTime t1, System.DateTime t2) { throw null; }
- public static bool operator <=(System.DateTime t1, System.DateTime t2) { throw null; }
- public static System.TimeSpan operator -(System.DateTime d1, System.DateTime d2) { throw null; }
- public static System.DateTime operator -(System.DateTime d, System.TimeSpan t) { throw null; }
- public static System.DateTime Parse(string s) { throw null; }
- public static System.DateTime Parse(string s, System.IFormatProvider provider) { throw null; }
- public static System.DateTime Parse(string s, System.IFormatProvider provider, System.Globalization.DateTimeStyles styles) { throw null; }
- public static System.DateTime ParseExact(string s, string format, System.IFormatProvider provider) { throw null; }
- public static System.DateTime ParseExact(string s, string format, System.IFormatProvider provider, System.Globalization.DateTimeStyles style) { throw null; }
- public static System.DateTime ParseExact(string s, string[] formats, System.IFormatProvider provider, System.Globalization.DateTimeStyles style) { throw null; }
- public static System.DateTime SpecifyKind(System.DateTime value, System.DateTimeKind kind) { throw null; }
- public System.TimeSpan Subtract(System.DateTime value) { throw null; }
- public System.DateTime Subtract(System.TimeSpan value) { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public long ToBinary() { throw null; }
- public long ToFileTime() { throw null; }
- public long ToFileTimeUtc() { throw null; }
- public System.DateTime ToLocalTime() { throw null; }
- public string ToLongDateString() { throw null; }
- public string ToLongTimeString() { throw null; }
- public double ToOADate() { throw null; }
- public string ToShortDateString() { throw null; }
- public string ToShortTimeString() { throw null; }
- public override string ToString() { throw null; }
- public string ToString(System.IFormatProvider provider) { throw null; }
- public string ToString(string format) { throw null; }
- public string ToString(string format, System.IFormatProvider provider) { throw null; }
- public System.DateTime ToUniversalTime() { throw null; }
- public static bool TryParse(string s, out System.DateTime result) { result = default(System.DateTime); throw null; }
- public static bool TryParse(string s, System.IFormatProvider provider, System.Globalization.DateTimeStyles styles, out System.DateTime result) { result = default(System.DateTime); throw null; }
- public static bool TryParseExact(string s, string format, System.IFormatProvider provider, System.Globalization.DateTimeStyles style, out System.DateTime result) { result = default(System.DateTime); throw null; }
- public static bool TryParseExact(string s, string[] formats, System.IFormatProvider provider, System.Globalization.DateTimeStyles style, out System.DateTime result) { result = default(System.DateTime); throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum DateTimeKind
- {
- Local = 2,
- Unspecified = 0,
- Utc = 1,
- }
- public partial struct DateTimeOffset : System.IComparable, System.IComparable<System.DateTimeOffset>, System.IEquatable<System.DateTimeOffset>, System.IFormattable, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable
- {
- public static readonly System.DateTimeOffset MaxValue;
- public static readonly System.DateTimeOffset MinValue;
- public DateTimeOffset(System.DateTime dateTime) { throw null; }
- public DateTimeOffset(System.DateTime dateTime, System.TimeSpan offset) { throw null; }
- public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, int millisecond, System.Globalization.Calendar calendar, System.TimeSpan offset) { throw null; }
- public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, int millisecond, System.TimeSpan offset) { throw null; }
- public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, System.TimeSpan offset) { throw null; }
- public DateTimeOffset(long ticks, System.TimeSpan offset) { throw null; }
- public System.DateTime Date { get { throw null; } }
- public System.DateTime DateTime { get { throw null; } }
- public int Day { get { throw null; } }
- public System.DayOfWeek DayOfWeek { get { throw null; } }
- public int DayOfYear { get { throw null; } }
- public int Hour { get { throw null; } }
- public System.DateTime LocalDateTime { get { throw null; } }
- public int Millisecond { get { throw null; } }
- public int Minute { get { throw null; } }
- public int Month { get { throw null; } }
- public static System.DateTimeOffset Now { get { throw null; } }
- public System.TimeSpan Offset { get { throw null; } }
- public int Second { get { throw null; } }
- public long Ticks { get { throw null; } }
- public System.TimeSpan TimeOfDay { get { throw null; } }
- public System.DateTime UtcDateTime { get { throw null; } }
- public static System.DateTimeOffset UtcNow { get { throw null; } }
- public long UtcTicks { get { throw null; } }
- public int Year { get { throw null; } }
- public System.DateTimeOffset Add(System.TimeSpan timeSpan) { throw null; }
- public System.DateTimeOffset AddDays(double days) { throw null; }
- public System.DateTimeOffset AddHours(double hours) { throw null; }
- public System.DateTimeOffset AddMilliseconds(double milliseconds) { throw null; }
- public System.DateTimeOffset AddMinutes(double minutes) { throw null; }
- public System.DateTimeOffset AddMonths(int months) { throw null; }
- public System.DateTimeOffset AddSeconds(double seconds) { throw null; }
- public System.DateTimeOffset AddTicks(long ticks) { throw null; }
- public System.DateTimeOffset AddYears(int years) { throw null; }
- public static int Compare(System.DateTimeOffset first, System.DateTimeOffset second) { throw null; }
- public int CompareTo(System.DateTimeOffset other) { throw null; }
- public bool Equals(System.DateTimeOffset other) { throw null; }
- public static bool Equals(System.DateTimeOffset first, System.DateTimeOffset second) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public bool EqualsExact(System.DateTimeOffset other) { throw null; }
- public static System.DateTimeOffset FromFileTime(long fileTime) { throw null; }
- public static System.DateTimeOffset FromUnixTimeMilliseconds(long milliseconds) { throw null; }
- public static System.DateTimeOffset FromUnixTimeSeconds(long seconds) { throw null; }
- public override int GetHashCode() { throw null; }
- public static System.DateTimeOffset operator +(System.DateTimeOffset dateTimeOffset, System.TimeSpan timeSpan) { throw null; }
- public static bool operator ==(System.DateTimeOffset left, System.DateTimeOffset right) { throw null; }
- public static bool operator >(System.DateTimeOffset left, System.DateTimeOffset right) { throw null; }
- public static bool operator >=(System.DateTimeOffset left, System.DateTimeOffset right) { throw null; }
- public static implicit operator System.DateTimeOffset(System.DateTime dateTime) { throw null; }
- public static bool operator !=(System.DateTimeOffset left, System.DateTimeOffset right) { throw null; }
- public static bool operator <(System.DateTimeOffset left, System.DateTimeOffset right) { throw null; }
- public static bool operator <=(System.DateTimeOffset left, System.DateTimeOffset right) { throw null; }
- public static System.TimeSpan operator -(System.DateTimeOffset left, System.DateTimeOffset right) { throw null; }
- public static System.DateTimeOffset operator -(System.DateTimeOffset dateTimeOffset, System.TimeSpan timeSpan) { throw null; }
- public static System.DateTimeOffset Parse(string input) { throw null; }
- public static System.DateTimeOffset Parse(string input, System.IFormatProvider formatProvider) { throw null; }
- public static System.DateTimeOffset Parse(string input, System.IFormatProvider formatProvider, System.Globalization.DateTimeStyles styles) { throw null; }
- public static System.DateTimeOffset ParseExact(string input, string format, System.IFormatProvider formatProvider) { throw null; }
- public static System.DateTimeOffset ParseExact(string input, string format, System.IFormatProvider formatProvider, System.Globalization.DateTimeStyles styles) { throw null; }
- public static System.DateTimeOffset ParseExact(string input, string[] formats, System.IFormatProvider formatProvider, System.Globalization.DateTimeStyles styles) { throw null; }
- public System.TimeSpan Subtract(System.DateTimeOffset value) { throw null; }
- public System.DateTimeOffset Subtract(System.TimeSpan value) { throw null; }
- int System.IComparable.CompareTo(object obj) { throw null; }
- void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { }
- [System.Security.SecurityCriticalAttribute]
- void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public long ToFileTime() { throw null; }
- public System.DateTimeOffset ToLocalTime() { throw null; }
- public System.DateTimeOffset ToOffset(System.TimeSpan offset) { throw null; }
- public override string ToString() { throw null; }
- public string ToString(System.IFormatProvider formatProvider) { throw null; }
- public string ToString(string format) { throw null; }
- public string ToString(string format, System.IFormatProvider formatProvider) { throw null; }
- public System.DateTimeOffset ToUniversalTime() { throw null; }
- public long ToUnixTimeMilliseconds() { throw null; }
- public long ToUnixTimeSeconds() { throw null; }
- public static bool TryParse(string input, out System.DateTimeOffset result) { result = default(System.DateTimeOffset); throw null; }
- public static bool TryParse(string input, System.IFormatProvider formatProvider, System.Globalization.DateTimeStyles styles, out System.DateTimeOffset result) { result = default(System.DateTimeOffset); throw null; }
- public static bool TryParseExact(string input, string format, System.IFormatProvider formatProvider, System.Globalization.DateTimeStyles styles, out System.DateTimeOffset result) { result = default(System.DateTimeOffset); throw null; }
- public static bool TryParseExact(string input, string[] formats, System.IFormatProvider formatProvider, System.Globalization.DateTimeStyles styles, out System.DateTimeOffset result) { result = default(System.DateTimeOffset); throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum DayOfWeek
- {
- Friday = 5,
- Monday = 1,
- Saturday = 6,
- Sunday = 0,
- Thursday = 4,
- Tuesday = 2,
- Wednesday = 3,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DBNull : System.IConvertible, System.Runtime.Serialization.ISerializable
- {
- internal DBNull() { }
- public static readonly System.DBNull Value;
- [System.Security.SecurityCriticalAttribute]
- public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public System.TypeCode GetTypeCode() { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- public override string ToString() { throw null; }
- public string ToString(System.IFormatProvider provider) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Decimal : System.IComparable, System.IComparable<decimal>, System.IConvertible, System.IEquatable<decimal>, System.IFormattable, System.Runtime.Serialization.IDeserializationCallback
- {
- [System.Runtime.CompilerServices.DecimalConstantAttribute((byte)0, (byte)0, (uint)4294967295, (uint)4294967295, (uint)4294967295)]
- public static readonly decimal MaxValue;
- [System.Runtime.CompilerServices.DecimalConstantAttribute((byte)0, (byte)128, (uint)0, (uint)0, (uint)1)]
- public static readonly decimal MinusOne;
- [System.Runtime.CompilerServices.DecimalConstantAttribute((byte)0, (byte)128, (uint)4294967295, (uint)4294967295, (uint)4294967295)]
- public static readonly decimal MinValue;
- [System.Runtime.CompilerServices.DecimalConstantAttribute((byte)0, (byte)0, (uint)0, (uint)0, (uint)1)]
- public static readonly decimal One;
- [System.Runtime.CompilerServices.DecimalConstantAttribute((byte)0, (byte)0, (uint)0, (uint)0, (uint)0)]
- public static readonly decimal Zero;
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCriticalAttribute]
- public Decimal(double value) { throw null; }
- public Decimal(int value) { throw null; }
- public Decimal(int lo, int mid, int hi, bool isNegative, byte scale) { throw null; }
- public Decimal(int[] bits) { throw null; }
- public Decimal(long value) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCriticalAttribute]
- public Decimal(float value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public Decimal(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public Decimal(ulong value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Decimal Add(System.Decimal d1, System.Decimal d2) { throw null; }
- public static System.Decimal Ceiling(System.Decimal d) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static int Compare(System.Decimal d1, System.Decimal d2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public int CompareTo(System.Decimal value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public int CompareTo(object value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Decimal Divide(System.Decimal d1, System.Decimal d2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public bool Equals(System.Decimal value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool Equals(System.Decimal d1, System.Decimal d2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override bool Equals(object value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Decimal Floor(System.Decimal d) { throw null; }
- public static System.Decimal FromOACurrency(long cy) { throw null; }
- public static int[] GetBits(System.Decimal d) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCriticalAttribute]
- public override int GetHashCode() { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Decimal Multiply(System.Decimal d1, System.Decimal d2) { throw null; }
- public static System.Decimal Negate(System.Decimal d) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Decimal operator +(System.Decimal d1, System.Decimal d2) { throw null; }
- public static System.Decimal operator --(System.Decimal d) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Decimal operator /(System.Decimal d1, System.Decimal d2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool operator ==(System.Decimal d1, System.Decimal d2) { throw null; }
- public static explicit operator byte(System.Decimal value) { throw null; }
- public static explicit operator char(System.Decimal value) { throw null; }
- public static explicit operator double(System.Decimal value) { throw null; }
- public static explicit operator short(System.Decimal value) { throw null; }
- public static explicit operator int(System.Decimal value) { throw null; }
- public static explicit operator long(System.Decimal value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static explicit operator sbyte(System.Decimal value) { throw null; }
- public static explicit operator float(System.Decimal value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static explicit operator ushort(System.Decimal value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static explicit operator uint(System.Decimal value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static explicit operator ulong(System.Decimal value) { throw null; }
- public static explicit operator System.Decimal(double value) { throw null; }
- public static explicit operator System.Decimal(float value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool operator >(System.Decimal d1, System.Decimal d2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool operator >=(System.Decimal d1, System.Decimal d2) { throw null; }
- public static implicit operator System.Decimal(byte value) { throw null; }
- public static implicit operator System.Decimal(char value) { throw null; }
- public static implicit operator System.Decimal(short value) { throw null; }
- public static implicit operator System.Decimal(int value) { throw null; }
- public static implicit operator System.Decimal(long value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static implicit operator System.Decimal(sbyte value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static implicit operator System.Decimal(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static implicit operator System.Decimal(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static implicit operator System.Decimal(ulong value) { throw null; }
- public static System.Decimal operator ++(System.Decimal d) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool operator !=(System.Decimal d1, System.Decimal d2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool operator <(System.Decimal d1, System.Decimal d2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool operator <=(System.Decimal d1, System.Decimal d2) { throw null; }
- public static System.Decimal operator %(System.Decimal d1, System.Decimal d2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Decimal operator *(System.Decimal d1, System.Decimal d2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Decimal operator -(System.Decimal d1, System.Decimal d2) { throw null; }
- public static System.Decimal operator -(System.Decimal d) { throw null; }
- public static System.Decimal operator +(System.Decimal d) { throw null; }
- public static System.Decimal Parse(string s) { throw null; }
- public static System.Decimal Parse(string s, System.Globalization.NumberStyles style) { throw null; }
- public static System.Decimal Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider) { throw null; }
- public static System.Decimal Parse(string s, System.IFormatProvider provider) { throw null; }
- public static System.Decimal Remainder(System.Decimal d1, System.Decimal d2) { throw null; }
- public static System.Decimal Round(System.Decimal d) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Decimal Round(System.Decimal d, int decimals) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Decimal Round(System.Decimal d, int decimals, System.MidpointRounding mode) { throw null; }
- public static System.Decimal Round(System.Decimal d, System.MidpointRounding mode) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Decimal Subtract(System.Decimal d1, System.Decimal d2) { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- System.Decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { }
- public static byte ToByte(System.Decimal value) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static double ToDouble(System.Decimal d) { throw null; }
- public static short ToInt16(System.Decimal value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static int ToInt32(System.Decimal d) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static long ToInt64(System.Decimal d) { throw null; }
- public static long ToOACurrency(System.Decimal value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte ToSByte(System.Decimal value) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static float ToSingle(System.Decimal d) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort ToUInt16(System.Decimal value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static uint ToUInt32(System.Decimal d) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static ulong ToUInt64(System.Decimal d) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Decimal Truncate(System.Decimal d) { throw null; }
- public static bool TryParse(string s, out System.Decimal result) { result = default(decimal); throw null; }
- public static bool TryParse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider, out System.Decimal result) { result = default(decimal); throw null; }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(2))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class Delegate : System.ICloneable, System.Runtime.Serialization.ISerializable
- {
- [System.Security.SecuritySafeCriticalAttribute]
- protected Delegate(object target, string method) { }
- [System.Security.SecuritySafeCriticalAttribute]
- protected Delegate(System.Type target, string method) { }
- public System.Reflection.MethodInfo Method { get { throw null; } }
- public object Target { get { throw null; } }
- public virtual object Clone() { throw null; }
- public static System.Delegate Combine(System.Delegate a, System.Delegate b) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static System.Delegate Combine(params System.Delegate[] delegates) { throw null; }
- protected virtual System.Delegate CombineImpl(System.Delegate d) { throw null; }
- public static System.Delegate CreateDelegate(System.Type type, object firstArgument, System.Reflection.MethodInfo method) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public static System.Delegate CreateDelegate(System.Type type, object firstArgument, System.Reflection.MethodInfo method, bool throwOnBindFailure) { throw null; }
- public static System.Delegate CreateDelegate(System.Type type, object target, string method) { throw null; }
- public static System.Delegate CreateDelegate(System.Type type, object target, string method, bool ignoreCase) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Delegate CreateDelegate(System.Type type, object target, string method, bool ignoreCase, bool throwOnBindFailure) { throw null; }
- public static System.Delegate CreateDelegate(System.Type type, System.Reflection.MethodInfo method) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public static System.Delegate CreateDelegate(System.Type type, System.Reflection.MethodInfo method, bool throwOnBindFailure) { throw null; }
- public static System.Delegate CreateDelegate(System.Type type, System.Type target, string method) { throw null; }
- public static System.Delegate CreateDelegate(System.Type type, System.Type target, string method, bool ignoreCase) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Delegate CreateDelegate(System.Type type, System.Type target, string method, bool ignoreCase, bool throwOnBindFailure) { throw null; }
- public object DynamicInvoke(params object[] args) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- protected virtual object DynamicInvokeImpl(object[] args) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public virtual System.Delegate[] GetInvocationList() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- protected virtual System.Reflection.MethodInfo GetMethodImpl() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public static bool operator ==(System.Delegate d1, System.Delegate d2) { throw null; }
- public static bool operator !=(System.Delegate d1, System.Delegate d2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Delegate Remove(System.Delegate source, System.Delegate value) { throw null; }
- public static System.Delegate RemoveAll(System.Delegate source, System.Delegate value) { throw null; }
- protected virtual System.Delegate RemoveImpl(System.Delegate d) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class DivideByZeroException : System.ArithmeticException
- {
- public DivideByZeroException() { }
- public DivideByZeroException(string message) { }
- public DivideByZeroException(string message, System.Exception innerException) { }
- protected DivideByZeroException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class DllNotFoundException : System.TypeLoadException
- {
- public DllNotFoundException() { }
- public DllNotFoundException(string message) { }
- public DllNotFoundException(string message, System.Exception inner) { }
- protected DllNotFoundException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Double : System.IComparable, System.IComparable<double>, System.IConvertible, System.IEquatable<double>, System.IFormattable
- {
- public const double Epsilon = 4.94065645841247E-324;
- public const double MaxValue = 1.7976931348623157E+308;
- public const double MinValue = -1.7976931348623157E+308;
- public const double NaN = 0.0 / 0.0;
- public const double NegativeInfinity = -1.0 / 0.0;
- public const double PositiveInfinity = 1.0 / 0.0;
- public int CompareTo(System.Double value) { throw null; }
- public int CompareTo(object value) { throw null; }
- public bool Equals(System.Double obj) { throw null; }
- public override bool Equals(object obj) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override int GetHashCode() { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool IsInfinity(System.Double d) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool IsNaN(System.Double d) { throw null; }
- public static bool IsNegativeInfinity(System.Double d) { throw null; }
- public static bool IsPositiveInfinity(System.Double d) { throw null; }
- public static bool operator ==(System.Double left, System.Double right) { throw null; }
- public static bool operator >(System.Double left, System.Double right) { throw null; }
- public static bool operator >=(System.Double left, System.Double right) { throw null; }
- public static bool operator !=(System.Double left, System.Double right) { throw null; }
- public static bool operator <(System.Double left, System.Double right) { throw null; }
- public static bool operator <=(System.Double left, System.Double right) { throw null; }
- public static System.Double Parse(string s) { throw null; }
- public static System.Double Parse(string s, System.Globalization.NumberStyles style) { throw null; }
- public static System.Double Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider) { throw null; }
- public static System.Double Parse(string s, System.IFormatProvider provider) { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- System.Double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format, System.IFormatProvider provider) { throw null; }
- public static bool TryParse(string s, out System.Double result) { result = default(double); throw null; }
- public static bool TryParse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider, out System.Double result) { result = default(double); throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class DuplicateWaitObjectException : System.ArgumentException
- {
- public DuplicateWaitObjectException() { }
- public DuplicateWaitObjectException(string parameterName) { }
- public DuplicateWaitObjectException(string message, System.Exception innerException) { }
- public DuplicateWaitObjectException(string parameterName, string message) { }
- protected DuplicateWaitObjectException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class EntryPointNotFoundException : System.TypeLoadException
- {
- public EntryPointNotFoundException() { }
- public EntryPointNotFoundException(string message) { }
- public EntryPointNotFoundException(string message, System.Exception inner) { }
- protected EntryPointNotFoundException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class Enum : System.ValueType, System.IComparable, System.IConvertible, System.IFormattable
- {
- protected Enum() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public int CompareTo(object target) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public override bool Equals(object obj) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static string Format(System.Type enumType, object value, string format) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override int GetHashCode() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static string GetName(System.Type enumType, object value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static string[] GetNames(System.Type enumType) { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static System.Type GetUnderlyingType(System.Type enumType) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static System.Array GetValues(System.Type enumType) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public bool HasFlag(System.Enum flag) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static bool IsDefined(System.Type enumType, object value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static object Parse(System.Type enumType, string value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static object Parse(System.Type enumType, string value, bool ignoreCase) { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static object ToObject(System.Type enumType, byte value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static object ToObject(System.Type enumType, short value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static object ToObject(System.Type enumType, int value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static object ToObject(System.Type enumType, long value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static object ToObject(System.Type enumType, object value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static object ToObject(System.Type enumType, sbyte value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static object ToObject(System.Type enumType, ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static object ToObject(System.Type enumType, uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static object ToObject(System.Type enumType, ulong value) { throw null; }
- public override string ToString() { throw null; }
- [System.ObsoleteAttribute("The provider argument is not used. Please use ToString().")]
- public string ToString(System.IFormatProvider provider) { throw null; }
- public string ToString(string format) { throw null; }
- [System.ObsoleteAttribute("The provider argument is not used. Please use ToString(String).")]
- public string ToString(string format, System.IFormatProvider provider) { throw null; }
- public static bool TryParse<TEnum>(string value, out TEnum result) where TEnum : struct { result = default(TEnum); throw null; }
- public static bool TryParse<TEnum>(string value, bool ignoreCase, out TEnum result) where TEnum : struct { result = default(TEnum); throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static partial class Environment
- {
- public static int CurrentManagedThreadId { get { throw null; } }
- public static int ExitCode { [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]set { } }
- public static bool HasShutdownStarted { [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } }
- public static string MachineName { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public static string NewLine { get { throw null; } }
- public static int ProcessorCount { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public static string StackTrace { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public static int TickCount { [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } }
- public static System.Version Version { get { throw null; } }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Exit(int exitCode) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static string ExpandEnvironmentVariables(string name) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static void FailFast(string message) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static void FailFast(string message, System.Exception exception) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static string[] GetCommandLineArgs() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static string GetEnvironmentVariable(string variable) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Collections.IDictionary GetEnvironmentVariables() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void SetEnvironmentVariable(string variable, string value) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class EventArgs
- {
- public static readonly System.EventArgs Empty;
- public EventArgs() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public delegate void EventHandler(object sender, System.EventArgs e);
- public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class Exception : System.Runtime.Serialization.ISerializable
- {
- public Exception() { }
- [System.Security.SecuritySafeCriticalAttribute]
- protected Exception(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public Exception(string message) { }
- public Exception(string message, System.Exception innerException) { }
- public virtual System.Collections.IDictionary Data { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public virtual string HelpLink { get { throw null; } set { } }
- public int HResult { get { throw null; } protected set { } }
- public System.Exception InnerException { get { throw null; } }
- public virtual string Message { get { throw null; } }
- public virtual string Source { [System.Security.SecurityCriticalAttribute]get { throw null; } [System.Security.SecurityCriticalAttribute]set { } }
- public virtual string StackTrace { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public System.Reflection.MethodBase TargetSite { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- protected event System.EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs> SerializeObjectState { add { } remove { } }
- public virtual System.Exception GetBaseException() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public new System.Type GetType() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- }
- [System.ObsoleteAttribute("This type previously indicated an unspecified fatal error in the runtime. The runtime no longer raises this exception so this type is obsolete.")]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ExecutionEngineException : System.SystemException
- {
- public ExecutionEngineException() { }
- public ExecutionEngineException(string message) { }
- public ExecutionEngineException(string message, System.Exception innerException) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class FieldAccessException : System.MemberAccessException
- {
- public FieldAccessException() { }
- public FieldAccessException(string message) { }
- public FieldAccessException(string message, System.Exception inner) { }
- protected FieldAccessException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(16), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class FlagsAttribute : System.Attribute
- {
- public FlagsAttribute() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class FormatException : System.SystemException
- {
- public FormatException() { }
- public FormatException(string message) { }
- public FormatException(string message, System.Exception innerException) { }
- protected FormatException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- public abstract partial class FormattableString : System.IFormattable
- {
- protected FormattableString() { }
- public abstract int ArgumentCount { get; }
- public abstract string Format { get; }
- public abstract object GetArgument(int index);
- public abstract object[] GetArguments();
- public static string Invariant(System.FormattableString formattable) { throw null; }
- string System.IFormattable.ToString(string ignored, System.IFormatProvider formatProvider) { throw null; }
- public override string ToString() { throw null; }
- public abstract string ToString(System.IFormatProvider formatProvider);
- }
- [System.Runtime.CompilerServices.TypeForwardedFromAttribute("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
- public delegate TResult Func<out TResult>();
- [System.Runtime.CompilerServices.TypeForwardedFromAttribute("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
- public delegate TResult Func<in T, out TResult>(T arg);
- [System.Runtime.CompilerServices.TypeForwardedFromAttribute("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
- public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
- [System.Runtime.CompilerServices.TypeForwardedFromAttribute("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
- public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);
- [System.Runtime.CompilerServices.TypeForwardedFromAttribute("System.Core, Version=2.0.5.0, Culture=Neutral, PublicKeyToken=7cec85d7bea7798e")]
- public delegate TResult Func<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
- public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
- public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
- public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
- public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
- public static partial class GC
- {
- public static int MaxGeneration { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- [System.Security.SecurityCriticalAttribute]
- public static void AddMemoryPressure(long bytesAllocated) { }
- [System.Security.SecurityCriticalAttribute]
- public static void CancelFullGCNotification() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Collect() { }
- public static void Collect(int generation) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Collect(int generation, System.GCCollectionMode mode) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Collect(int generation, System.GCCollectionMode mode, bool blocking) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Collect(int generation, System.GCCollectionMode mode, bool blocking, bool compacting) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static int CollectionCount(int generation) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static int GetGeneration(object obj) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static int GetGeneration(System.WeakReference wo) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static long GetTotalMemory(bool forceFullCollection) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public static void KeepAlive(object obj) { }
- [System.Security.SecurityCriticalAttribute]
- public static void RegisterForFullGCNotification(int maxGenerationThreshold, int largeObjectHeapThreshold) { }
- [System.Security.SecurityCriticalAttribute]
- public static void RemoveMemoryPressure(long bytesAllocated) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void ReRegisterForFinalize(object obj) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void SuppressFinalize(object obj) { }
- [System.Security.SecurityCriticalAttribute]
- public static System.GCNotificationStatus WaitForFullGCApproach() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.GCNotificationStatus WaitForFullGCComplete() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void WaitForPendingFinalizers() { }
- }
- public enum GCNotificationStatus
- {
- Canceled = 2,
- Failed = 1,
- NotApplicable = 4,
- Succeeded = 0,
- Timeout = 3,
- }
- public enum GCCollectionMode
- {
- Default = 0,
- Forced = 1,
- Optimized = 2,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Guid : System.IComparable, System.IComparable<System.Guid>, System.IEquatable<System.Guid>, System.IFormattable
- {
- public static readonly System.Guid Empty;
- public Guid(byte[] b) { throw null;}
- public Guid(int a, short b, short c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k) { throw null;}
- public Guid(int a, short b, short c, byte[] d) { throw null;}
- public Guid(string g) { throw null;}
- [System.CLSCompliantAttribute(false)]
- public Guid(uint a, ushort b, ushort c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k) { throw null;}
- public int CompareTo(System.Guid value) { throw null; }
- public int CompareTo(object value) { throw null; }
- public bool Equals(System.Guid g) { throw null; }
- public override bool Equals(object o) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override int GetHashCode() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Guid NewGuid() { throw null; }
- public static bool operator ==(System.Guid a, System.Guid b) { throw null; }
- public static bool operator !=(System.Guid a, System.Guid b) { throw null; }
- public static System.Guid Parse(string input) { throw null; }
- public static System.Guid ParseExact(string input, string format) { throw null; }
- public byte[] ToByteArray() { throw null; }
- public override string ToString() { throw null; }
- public string ToString(string format) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format, System.IFormatProvider provider) { throw null; }
- public static bool TryParse(string input, out System.Guid result) { result = default(System.Guid); throw null; }
- public static bool TryParseExact(string input, string format, out System.Guid result) { result = default(System.Guid); throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IAsyncResult
- {
- object AsyncState { get; }
- System.Threading.WaitHandle AsyncWaitHandle { get; }
- bool CompletedSynchronously { get; }
- bool IsCompleted { get; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface ICloneable
- {
- object Clone();
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IComparable
- {
- int CompareTo(object obj);
- }
- public partial interface IComparable<in T>
- {
- int CompareTo(T other);
- }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IConvertible
- {
- System.TypeCode GetTypeCode();
- bool ToBoolean(System.IFormatProvider provider);
- byte ToByte(System.IFormatProvider provider);
- char ToChar(System.IFormatProvider provider);
- System.DateTime ToDateTime(System.IFormatProvider provider);
- decimal ToDecimal(System.IFormatProvider provider);
- double ToDouble(System.IFormatProvider provider);
- short ToInt16(System.IFormatProvider provider);
- int ToInt32(System.IFormatProvider provider);
- long ToInt64(System.IFormatProvider provider);
- sbyte ToSByte(System.IFormatProvider provider);
- float ToSingle(System.IFormatProvider provider);
- string ToString(System.IFormatProvider provider);
- object ToType(System.Type conversionType, System.IFormatProvider provider);
- ushort ToUInt16(System.IFormatProvider provider);
- uint ToUInt32(System.IFormatProvider provider);
- ulong ToUInt64(System.IFormatProvider provider);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface ICustomFormatter
- {
- string Format(string format, object arg, System.IFormatProvider formatProvider);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IDisposable
- {
- void Dispose();
- }
- public partial interface IEquatable<T>
- {
- bool Equals(T other);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IFormatProvider
- {
- object GetFormat(System.Type formatType);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IFormattable
- {
- string ToString(string format, System.IFormatProvider formatProvider);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class IndexOutOfRangeException : System.SystemException
- {
- public IndexOutOfRangeException() { }
- public IndexOutOfRangeException(string message) { }
- public IndexOutOfRangeException(string message, System.Exception innerException) { }
- }
- public sealed partial class InsufficientExecutionStackException : System.SystemException
- {
- public InsufficientExecutionStackException() { }
- public InsufficientExecutionStackException(string message) { }
- public InsufficientExecutionStackException(string message, System.Exception innerException) { }
- }
- public sealed partial class InsufficientMemoryException : System.OutOfMemoryException
- {
- public InsufficientMemoryException() { }
- public InsufficientMemoryException(string message) { }
- public InsufficientMemoryException(string message, System.Exception innerException) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Int16 : System.IComparable, System.IComparable<short>, System.IConvertible, System.IEquatable<short>, System.IFormattable
- {
- public const short MaxValue = (short)32767;
- public const short MinValue = (short)-32768;
- public int CompareTo(System.Int16 value) { throw null; }
- public int CompareTo(object value) { throw null; }
- public bool Equals(System.Int16 obj) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- public static System.Int16 Parse(string s) { throw null; }
- public static System.Int16 Parse(string s, System.Globalization.NumberStyles style) { throw null; }
- public static System.Int16 Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider) { throw null; }
- public static System.Int16 Parse(string s, System.IFormatProvider provider) { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- System.Int16 System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(System.IFormatProvider provider) { throw null; }
- public string ToString(string format) { throw null; }
- public string ToString(string format, System.IFormatProvider provider) { throw null; }
- public static bool TryParse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider, out System.Int16 result) { result = default(short); throw null; }
- public static bool TryParse(string s, out System.Int16 result) { result = default(short); throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Int32 : System.IComparable, System.IComparable<int>, System.IConvertible, System.IEquatable<int>, System.IFormattable
- {
- public const int MaxValue = 2147483647;
- public const int MinValue = -2147483648;
- public System.Int32 CompareTo(System.Int32 value) { throw null; }
- public System.Int32 CompareTo(object value) { throw null; }
- public bool Equals(System.Int32 obj) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public override System.Int32 GetHashCode() { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- public static System.Int32 Parse(string s) { throw null; }
- public static System.Int32 Parse(string s, System.Globalization.NumberStyles style) { throw null; }
- public static System.Int32 Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider) { throw null; }
- public static System.Int32 Parse(string s, System.IFormatProvider provider) { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- System.Int32 System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format, System.IFormatProvider provider) { throw null; }
- public static bool TryParse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider, out System.Int32 result) { result = default(int); throw null; }
- public static bool TryParse(string s, out System.Int32 result) { result = default(int); throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Int64 : System.IComparable, System.IComparable<long>, System.IConvertible, System.IEquatable<long>, System.IFormattable
- {
- public const long MaxValue = (long)9223372036854775807;
- public const long MinValue = (long)-9223372036854775808;
- public int CompareTo(System.Int64 value) { throw null; }
- public int CompareTo(object value) { throw null; }
- public bool Equals(System.Int64 obj) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- public static System.Int64 Parse(string s) { throw null; }
- public static System.Int64 Parse(string s, System.Globalization.NumberStyles style) { throw null; }
- public static System.Int64 Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider) { throw null; }
- public static System.Int64 Parse(string s, System.IFormatProvider provider) { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- System.Int64 System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format, System.IFormatProvider provider) { throw null; }
- public static bool TryParse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider, out System.Int64 result) { result = default(long); throw null; }
- public static bool TryParse(string s, out System.Int64 result) { result = default(long); throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct IntPtr : System.Runtime.Serialization.ISerializable
- {
- public static readonly System.IntPtr Zero;
- [System.Security.SecuritySafeCriticalAttribute]
- public IntPtr(int value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public IntPtr(long value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe IntPtr(void* value) { throw null; }
- public static int Size { get { throw null; } }
- public static System.IntPtr Add(System.IntPtr pointer, int offset) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override bool Equals(object obj) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override int GetHashCode() { throw null; }
- public static System.IntPtr operator +(System.IntPtr pointer, int offset) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool operator ==(System.IntPtr value1, System.IntPtr value2) { throw null; }
- public static explicit operator System.IntPtr(int value) { throw null; }
- public static explicit operator System.IntPtr(long value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static explicit operator int(System.IntPtr value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static explicit operator long(System.IntPtr value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public unsafe static explicit operator void* (System.IntPtr value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe static explicit operator System.IntPtr(void* value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool operator !=(System.IntPtr value1, System.IntPtr value2) { throw null; }
- public static System.IntPtr operator -(System.IntPtr pointer, int offset) { throw null; }
- public static System.IntPtr Subtract(System.IntPtr pointer, int offset) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public int ToInt32() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public long ToInt64() { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public unsafe void* ToPointer() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class InvalidCastException : System.SystemException
- {
- public InvalidCastException() { }
- public InvalidCastException(string message) { }
- public InvalidCastException(string message, System.Exception innerException) { }
- public InvalidCastException(string message, int errorCode) { }
- protected InvalidCastException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class InvalidOperationException : System.SystemException
- {
- public InvalidOperationException() { }
- public InvalidOperationException(string message) { }
- public InvalidOperationException(string message, System.Exception innerException) { }
- protected InvalidOperationException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class InvalidProgramException : System.SystemException
- {
- public InvalidProgramException() { }
- public InvalidProgramException(string message) { }
- public InvalidProgramException(string message, System.Exception inner) { }
- }
- [System.Runtime.CompilerServices.TypeForwardedFromAttribute("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
- public partial class InvalidTimeZoneException : System.Exception
- {
- public InvalidTimeZoneException() { }
- public InvalidTimeZoneException(string message) { }
- public InvalidTimeZoneException(string message, System.Exception innerException) { }
- protected InvalidTimeZoneException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- public partial interface IObservable<out T>
- {
- System.IDisposable Subscribe(System.IObserver<T> observer);
- }
- public partial interface IObserver<in T>
- {
- void OnCompleted();
- void OnError(System.Exception error);
- void OnNext(T value);
- }
- public partial interface IProgress<in T>
- {
- void Report(T value);
- }
- public partial interface IServiceProvider
- {
- object GetService(System.Type serviceType);
- }
- [System.Diagnostics.DebuggerDisplayAttribute("ThreadSafetyMode={Mode}, IsValueCreated={IsValueCreated}, IsValueFaulted={IsValueFaulted}, Value={ValueForDebugDisplay}")]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public partial class Lazy<T>
- {
- public Lazy() { }
- public Lazy(T value) { }
- public Lazy(bool isThreadSafe) { }
- public Lazy(System.Func<T> valueFactory) { }
- public Lazy(System.Func<T> valueFactory, bool isThreadSafe) { }
- public Lazy(System.Func<T> valueFactory, System.Threading.LazyThreadSafetyMode mode) { }
- public Lazy(System.Threading.LazyThreadSafetyMode mode) { }
- public bool IsValueCreated { get { throw null; } }
- [System.Diagnostics.DebuggerBrowsableAttribute((System.Diagnostics.DebuggerBrowsableState)(0))]
- public T Value { get { throw null; } }
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class MarshalByRefObject
- {
- protected MarshalByRefObject() { }
- public object GetLifetimeService() { throw null; }
- public virtual object InitializeLifetimeService() { throw null; }
- protected System.MarshalByRefObject MemberwiseClone(bool cloneIdentity) { throw null; }
-
- }
- public static partial class Math
- {
- public const double E = 2.7182818284590451;
- public const double PI = 3.1415926535897931;
- public static decimal Abs(decimal value) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Abs(double value) { throw null; }
- public static short Abs(short value) { throw null; }
- public static int Abs(int value) { throw null; }
- public static long Abs(long value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte Abs(sbyte value) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Abs(float value) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Acos(double d) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Asin(double d) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Atan(double d) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Atan2(double y, double x) { throw null; }
- public static long BigMul(int a, int b) { throw null; }
- public static decimal Ceiling(decimal d) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Ceiling(double a) { throw null; }
- public static byte Clamp(byte value, byte min, byte max) { throw null; }
- public static decimal Clamp(decimal value, decimal min, decimal max) { throw null; }
- public static double Clamp(double value, double min, double max) { throw null; }
- public static short Clamp(short value, short min, short max) { throw null; }
- public static int Clamp(int value, int min, int max) { throw null; }
- public static long Clamp(long value, long min, long max) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte Clamp(sbyte value, sbyte min, sbyte max) { throw null; }
- public static float Clamp(float value, float min, float max) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort Clamp(ushort value, ushort min, ushort max) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint Clamp(uint value, uint min, uint max) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong Clamp(ulong value, ulong min, ulong max) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Cos(double d) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Cosh(double value) { throw null; }
- public static int DivRem(int a, int b, out int result) { result = default(int); throw null; }
- public static long DivRem(long a, long b, out long result) { result = default(long); throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Exp(double d) { throw null; }
- public static decimal Floor(decimal d) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Floor(double d) { throw null; }
- public static double IEEERemainder(double x, double y) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Log(double d) { throw null; }
- public static double Log(double a, double newBase) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Log10(double d) { throw null; }
- public static byte Max(byte val1, byte val2) { throw null; }
- public static decimal Max(decimal val1, decimal val2) { throw null; }
- public static double Max(double val1, double val2) { throw null; }
- public static short Max(short val1, short val2) { throw null; }
- public static int Max(int val1, int val2) { throw null; }
- public static long Max(long val1, long val2) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte Max(sbyte val1, sbyte val2) { throw null; }
- public static float Max(float val1, float val2) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort Max(ushort val1, ushort val2) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint Max(uint val1, uint val2) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong Max(ulong val1, ulong val2) { throw null; }
- public static byte Min(byte val1, byte val2) { throw null; }
- public static decimal Min(decimal val1, decimal val2) { throw null; }
- public static double Min(double val1, double val2) { throw null; }
- public static short Min(short val1, short val2) { throw null; }
- public static int Min(int val1, int val2) { throw null; }
- public static long Min(long val1, long val2) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte Min(sbyte val1, sbyte val2) { throw null; }
- public static float Min(float val1, float val2) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort Min(ushort val1, ushort val2) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint Min(uint val1, uint val2) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ulong Min(ulong val1, ulong val2) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Pow(double x, double y) { throw null; }
- public static decimal Round(decimal d) { throw null; }
- public static decimal Round(decimal d, int decimals) { throw null; }
- public static decimal Round(decimal d, int decimals, System.MidpointRounding mode) { throw null; }
- public static decimal Round(decimal d, System.MidpointRounding mode) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Round(double a) { throw null; }
- public static double Round(double value, int digits) { throw null; }
- public static double Round(double value, int digits, System.MidpointRounding mode) { throw null; }
- public static double Round(double value, System.MidpointRounding mode) { throw null; }
- public static int Sign(decimal value) { throw null; }
- public static int Sign(double value) { throw null; }
- public static int Sign(short value) { throw null; }
- public static int Sign(int value) { throw null; }
- public static int Sign(long value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static int Sign(sbyte value) { throw null; }
- public static int Sign(float value) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Sin(double a) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Sinh(double value) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Sqrt(double d) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Tan(double a) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Tanh(double value) { throw null; }
- public static decimal Truncate(decimal d) { throw null; }
- public static double Truncate(double d) { throw null; }
- }
- public static partial class MathF
- {
- public const float E = 2.71828183f;
- public const float PI = 3.14159265f;
- public static float Abs(float x) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Acos(float x) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Asin(float x) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Atan(float x) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Atan2(float y, float x) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Ceiling(float x) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Cos(float x) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Cosh(float x) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Exp(float x) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Floor(float x) { throw null; }
- public static float IEEERemainder(float x, float y) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Log(float x) { throw null; }
- public static float Log(float x, float y) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Log10(float x) { throw null; }
- public static float Max(float x, float y) { throw null; }
- public static float Min(float x, float y) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Pow(float x, float y) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Round(float x) { throw null; }
- public static float Round(float x, int digits) { throw null; }
- public static float Round(float x, int digits, System.MidpointRounding mode) { throw null; }
- public static float Round(float x, System.MidpointRounding mode) { throw null; }
- public static int Sign(float x) { return default(int); }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Sin(float x) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Sinh(float x) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static float Sqrt(float x) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Tan(float x) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Tanh(float x) { throw null; }
- public static float Truncate(float x) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class MemberAccessException : System.SystemException
- {
- public MemberAccessException() { }
- public MemberAccessException(string message) { }
- public MemberAccessException(string message, System.Exception inner) { }
- protected MemberAccessException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class MethodAccessException : System.MemberAccessException
- {
- public MethodAccessException() { }
- public MethodAccessException(string message) { }
- public MethodAccessException(string message, System.Exception inner) { }
- protected MethodAccessException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum MidpointRounding
- {
- AwayFromZero = 1,
- ToEven = 0,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class MissingFieldException : System.MissingMemberException, System.Runtime.Serialization.ISerializable
- {
- public MissingFieldException() { }
- protected MissingFieldException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public MissingFieldException(string message) { }
- public MissingFieldException(string message, System.Exception inner) { }
- public MissingFieldException(string className, string fieldName) { }
- public override string Message { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class MissingMemberException : System.MemberAccessException, System.Runtime.Serialization.ISerializable
- {
- protected string ClassName;
- protected string MemberName;
- protected byte[] Signature;
- public MissingMemberException() { }
- protected MissingMemberException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public MissingMemberException(string message) { }
- public MissingMemberException(string message, System.Exception inner) { }
- public MissingMemberException(string className, string memberName) { }
- public override string Message { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- [System.Security.SecurityCriticalAttribute]
- public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class MissingMethodException : System.MissingMemberException, System.Runtime.Serialization.ISerializable
- {
- public MissingMethodException() { }
- protected MissingMethodException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public MissingMethodException(string message) { }
- public MissingMethodException(string message, System.Exception inner) { }
- public MissingMethodException(string className, string methodName) { }
- public override string Message { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public unsafe struct ModuleHandle
- {
- public static readonly System.ModuleHandle EmptyHandle;
- public int MDStreamVersion { get { throw null; } }
- public override int GetHashCode() { throw null; }
- public override bool Equals(object obj) { throw null; }
- public unsafe bool Equals(System.ModuleHandle handle) { throw null; }
- public static bool operator ==(System.ModuleHandle left, System.ModuleHandle right) { throw null; }
- public static bool operator !=(System.ModuleHandle left, System.ModuleHandle right) { throw null; }
- public System.RuntimeTypeHandle GetRuntimeTypeHandleFromMetadataToken(int typeToken) { throw null; }
- public System.RuntimeTypeHandle ResolveTypeHandle(int typeToken) { throw null; }
- public System.RuntimeTypeHandle ResolveTypeHandle(int typeToken, System.RuntimeTypeHandle[] typeInstantiationContext, System.RuntimeTypeHandle[] methodInstantiationContext) { throw null; }
- public System.RuntimeMethodHandle GetRuntimeMethodHandleFromMetadataToken(int methodToken) { throw null; }
- public System.RuntimeMethodHandle ResolveMethodHandle(int methodToken) { throw null; }
- public System.RuntimeMethodHandle ResolveMethodHandle(int methodToken, System.RuntimeTypeHandle[] typeInstantiationContext, System.RuntimeTypeHandle[] methodInstantiationContext) { throw null; }
- public System.RuntimeFieldHandle GetRuntimeFieldHandleFromMetadataToken(int fieldToken) { throw null; }
- public System.RuntimeFieldHandle ResolveFieldHandle(int fieldToken) { throw null; }
- public System.RuntimeFieldHandle ResolveFieldHandle(int fieldToken, System.RuntimeTypeHandle[] typeInstantiationContext, System.RuntimeTypeHandle[] methodInstantiationContext) { throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class MTAThreadAttribute : System.Attribute
- {
- public MTAThreadAttribute() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class MulticastDelegate : System.Delegate
- {
- protected MulticastDelegate(object target, string method) : base (default(object), default(string)) { }
- protected MulticastDelegate(System.Type target, string method) : base (default(object), default(string)) { }
- [System.Security.SecuritySafeCriticalAttribute]
- protected sealed override System.Delegate CombineImpl(System.Delegate follow) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public sealed override bool Equals(object obj) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public sealed override int GetHashCode() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public sealed override System.Delegate[] GetInvocationList() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- protected override System.Reflection.MethodInfo GetMethodImpl() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public static bool operator ==(System.MulticastDelegate d1, System.MulticastDelegate d2) { throw null; }
- public static bool operator !=(System.MulticastDelegate d1, System.MulticastDelegate d2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- protected sealed override System.Delegate RemoveImpl(System.Delegate value) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class MulticastNotSupportedException : System.SystemException
- {
- public MulticastNotSupportedException() { }
- public MulticastNotSupportedException(string message) { }
- public MulticastNotSupportedException(string message, System.Exception inner) { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(256), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class NonSerializedAttribute : System.Attribute
- {
- public NonSerializedAttribute() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class NotFiniteNumberException : System.ArithmeticException
- {
- public NotFiniteNumberException() { }
- public NotFiniteNumberException(double offendingNumber) { }
- public NotFiniteNumberException(string message) { }
- public NotFiniteNumberException(string message, double offendingNumber) { }
- public NotFiniteNumberException(string message, double offendingNumber, System.Exception innerException) { }
- public NotFiniteNumberException(string message, System.Exception innerException) { }
- protected NotFiniteNumberException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- public double OffendingNumber { get { throw null; } }
- [System.Security.SecurityCriticalAttribute]
- public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class NotImplementedException : System.SystemException
- {
- public NotImplementedException() { }
- public NotImplementedException(string message) { }
- public NotImplementedException(string message, System.Exception inner) { }
- protected NotImplementedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class NotSupportedException : System.SystemException
- {
- public NotSupportedException() { }
- public NotSupportedException(string message) { }
- public NotSupportedException(string message, System.Exception innerException) { }
- protected NotSupportedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static partial class Nullable
- {
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static int Compare<T>(System.Nullable<T> n1, System.Nullable<T> n2) where T : struct { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static bool Equals<T>(System.Nullable<T> n1, System.Nullable<T> n2) where T : struct { throw null; }
- public static System.Type GetUnderlyingType(System.Type nullableType) { throw null; }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Nullable<T> where T : struct
- {
- public Nullable(T value) { throw null;}
- public bool HasValue { get { throw null; } }
- public T Value { get { throw null; } }
- public override bool Equals(object other) { throw null; }
- public override int GetHashCode() { throw null; }
- public T GetValueOrDefault() { throw null; }
- public T GetValueOrDefault(T defaultValue) { throw null; }
- public static explicit operator T (System.Nullable<T> value) { throw null; }
- public static implicit operator System.Nullable<T> (T value) { throw null; }
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class NullReferenceException : System.SystemException
- {
- public NullReferenceException() { }
- public NullReferenceException(string message) { }
- public NullReferenceException(string message, System.Exception innerException) { }
- protected NullReferenceException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(2))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class Object
- {
- public Object() { }
- public virtual bool Equals(System.Object obj) { throw null; }
- public static bool Equals(System.Object objA, System.Object objB) { throw null; }
- ~Object() { }
- public virtual int GetHashCode() { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public System.Type GetType() { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- protected System.Object MemberwiseClone() { throw null; }
- public static bool ReferenceEquals(System.Object objA, System.Object objB) { throw null; }
- public virtual string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ObjectDisposedException : System.InvalidOperationException
- {
- public ObjectDisposedException(string objectName) { }
- public ObjectDisposedException(string message, System.Exception innerException) { }
- public ObjectDisposedException(string objectName, string message) { }
- protected ObjectDisposedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- public override string Message { get { throw null; } }
- public string ObjectName { get { throw null; } }
- [System.Security.SecurityCriticalAttribute]
- public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(6140), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ObsoleteAttribute : System.Attribute
- {
- public ObsoleteAttribute() { }
- public ObsoleteAttribute(string message) { }
- public ObsoleteAttribute(string message, bool error) { }
- public bool IsError { get { throw null; } }
- public string Message { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class OperationCanceledException : System.SystemException
- {
- public OperationCanceledException() { }
- public OperationCanceledException(string message) { }
- public OperationCanceledException(string message, System.Exception innerException) { }
- public OperationCanceledException(string message, System.Exception innerException, System.Threading.CancellationToken token) { }
- public OperationCanceledException(string message, System.Threading.CancellationToken token) { }
- public OperationCanceledException(System.Threading.CancellationToken token) { }
- protected OperationCanceledException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- public System.Threading.CancellationToken CancellationToken { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class OutOfMemoryException : System.SystemException
- {
- public OutOfMemoryException() { }
- public OutOfMemoryException(string message) { }
- public OutOfMemoryException(string message, System.Exception innerException) { }
- protected OutOfMemoryException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class OverflowException : System.ArithmeticException
- {
- public OverflowException() { }
- public OverflowException(string message) { }
- public OverflowException(string message, System.Exception innerException) { }
- protected OverflowException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(2048), Inherited=true, AllowMultiple=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ParamArrayAttribute : System.Attribute
- {
- public ParamArrayAttribute() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class PlatformNotSupportedException : System.NotSupportedException
- {
- public PlatformNotSupportedException() { }
- public PlatformNotSupportedException(string message) { }
- public PlatformNotSupportedException(string message, System.Exception inner) { }
- protected PlatformNotSupportedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- public delegate bool Predicate<in T>(T obj);
- public partial class Progress<T> : System.IProgress<T>
- {
- public Progress() { }
- public Progress(System.Action<T> handler) { }
- public event System.EventHandler<T> ProgressChanged { add { } remove { } }
- protected virtual void OnReport(T value) { }
- void System.IProgress<T>.Report(T value) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class Random
- {
- public Random() { }
- public Random(int Seed) { }
- public virtual int Next() { throw null; }
- public virtual int Next(int maxValue) { throw null; }
- public virtual int Next(int minValue, int maxValue) { throw null; }
- public virtual void NextBytes(byte[] buffer) { }
- public virtual double NextDouble() { throw null; }
- protected virtual double Sample() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class RankException : System.SystemException
- {
- public RankException() { }
- public RankException(string message) { }
- public RankException(string message, System.Exception innerException) { }
- protected RankException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ResolveEventArgs : System.EventArgs
- {
- public ResolveEventArgs(string name) { }
- public ResolveEventArgs(string name, System.Reflection.Assembly requestingAssembly) { }
- public string Name { get { throw null; } }
- public System.Reflection.Assembly RequestingAssembly { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public delegate System.Reflection.Assembly ResolveEventHandler(object sender, System.ResolveEventArgs args);
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct RuntimeArgumentHandle
- {
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct RuntimeFieldHandle : System.Runtime.Serialization.ISerializable
- {
- public System.IntPtr Value { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- [System.Security.SecuritySafeCriticalAttribute]
- public override bool Equals(object obj) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public bool Equals(System.RuntimeFieldHandle handle) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override int GetHashCode() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public static bool operator ==(System.RuntimeFieldHandle left, System.RuntimeFieldHandle right) { throw null; }
- public static bool operator !=(System.RuntimeFieldHandle left, System.RuntimeFieldHandle right) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct RuntimeMethodHandle : System.Runtime.Serialization.ISerializable
- {
- public System.IntPtr Value { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- [System.Security.SecuritySafeCriticalAttribute]
- public override bool Equals(object obj) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public bool Equals(System.RuntimeMethodHandle handle) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public System.IntPtr GetFunctionPointer() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override int GetHashCode() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public static bool operator ==(System.RuntimeMethodHandle left, System.RuntimeMethodHandle right) { throw null; }
- public static bool operator !=(System.RuntimeMethodHandle left, System.RuntimeMethodHandle right) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct RuntimeTypeHandle : System.Runtime.Serialization.ISerializable
- {
- public System.IntPtr Value { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.RuntimeTypeHandle handle) { throw null; }
- public override int GetHashCode() { throw null; }
- [System.CLSCompliantAttribute(false)]
- public System.ModuleHandle GetModuleHandle() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public static bool operator ==(object left, System.RuntimeTypeHandle right) { throw null; }
- public static bool operator ==(System.RuntimeTypeHandle left, object right) { throw null; }
- public static bool operator !=(object left, System.RuntimeTypeHandle right) { throw null; }
- public static bool operator !=(System.RuntimeTypeHandle left, object right) { throw null; }
- }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct SByte : System.IComparable, System.IComparable<sbyte>, System.IConvertible, System.IEquatable<sbyte>, System.IFormattable
- {
- public const sbyte MaxValue = (sbyte)127;
- public const sbyte MinValue = (sbyte)-128;
- public int CompareTo(object obj) { throw null; }
- public int CompareTo(System.SByte value) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.SByte obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.SByte Parse(string s) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.SByte Parse(string s, System.Globalization.NumberStyles style) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.SByte Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.SByte Parse(string s, System.IFormatProvider provider) { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- System.SByte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(System.IFormatProvider provider) { throw null; }
- public string ToString(string format) { throw null; }
- public string ToString(string format, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static bool TryParse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider, out System.SByte result) { result = default(sbyte); throw null; }
- [System.CLSCompliantAttribute(false)]
- public static bool TryParse(string s, out System.SByte result) { result = default(sbyte); throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(4124), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class SerializableAttribute : System.Attribute
- {
- public SerializableAttribute() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Single : System.IComparable, System.IComparable<float>, System.IConvertible, System.IEquatable<float>, System.IFormattable
- {
- public const float Epsilon = 1.401298E-45f;
- public const float MaxValue = 3.40282347E+38f;
- public const float MinValue = -3.40282347E+38f;
- public const float NaN = 0.0f / 0.0f;
- public const float NegativeInfinity = -1.0f / 0.0f;
- public const float PositiveInfinity = 1.0f / 0.0f;
- public int CompareTo(object value) { throw null; }
- public int CompareTo(System.Single value) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.Single obj) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override int GetHashCode() { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool IsInfinity(System.Single f) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool IsNaN(System.Single f) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool IsNegativeInfinity(System.Single f) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool IsPositiveInfinity(System.Single f) { throw null; }
- public static bool operator ==(System.Single left, System.Single right) { throw null; }
- public static bool operator >(System.Single left, System.Single right) { throw null; }
- public static bool operator >=(System.Single left, System.Single right) { throw null; }
- public static bool operator !=(System.Single left, System.Single right) { throw null; }
- public static bool operator <(System.Single left, System.Single right) { throw null; }
- public static bool operator <=(System.Single left, System.Single right) { throw null; }
- public static System.Single Parse(string s) { throw null; }
- public static System.Single Parse(string s, System.Globalization.NumberStyles style) { throw null; }
- public static System.Single Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider) { throw null; }
- public static System.Single Parse(string s, System.IFormatProvider provider) { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- System.Single System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format, System.IFormatProvider provider) { throw null; }
- public static bool TryParse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider, out System.Single result) { result = default(float); throw null; }
- public static bool TryParse(string s, out System.Single result) { result = default(float); throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class StackOverflowException : System.SystemException
- {
- public StackOverflowException() { }
- public StackOverflowException(string message) { }
- public StackOverflowException(string message, System.Exception innerException) { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class STAThreadAttribute : System.Attribute
- {
- public STAThreadAttribute() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class String : System.Collections.Generic.IEnumerable<char>, System.Collections.IEnumerable, System.ICloneable, System.IComparable, System.IComparable<string>, System.IConvertible, System.IEquatable<string>
- {
- public static readonly string Empty;
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe String(char* value) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe String(char* value, int startIndex, int length) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCriticalAttribute]
- public String(char c, int count) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCriticalAttribute]
- public String(char[] value) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCriticalAttribute]
- public String(char[] value, int startIndex, int length) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe String(sbyte* value) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe String(sbyte* value, int startIndex, int length) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe String(sbyte* value, int startIndex, int length, System.Text.Encoding enc) { }
- [System.Runtime.CompilerServices.IndexerName("Chars")]
- public char this[int index] { [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } }
- public int Length { [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } }
- public object Clone() { throw null; }
- public static int Compare(System.String strA, int indexA, System.String strB, int indexB, int length) { throw null; }
- public static int Compare(System.String strA, int indexA, System.String strB, int indexB, int length, bool ignoreCase) { throw null; }
- public static int Compare(System.String strA, int indexA, System.String strB, int indexB, int length, bool ignoreCase, System.Globalization.CultureInfo culture) { throw null; }
- public static int Compare(System.String strA, int indexA, System.String strB, int indexB, int length, System.Globalization.CultureInfo culture, System.Globalization.CompareOptions options) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static int Compare(System.String strA, int indexA, System.String strB, int indexB, int length, System.StringComparison comparisonType) { throw null; }
- public static int Compare(System.String strA, System.String strB) { throw null; }
- public static int Compare(System.String strA, System.String strB, bool ignoreCase) { throw null; }
- public static int Compare(System.String strA, System.String strB, bool ignoreCase, System.Globalization.CultureInfo culture) { throw null; }
- public static int Compare(System.String strA, System.String strB, System.Globalization.CultureInfo culture, System.Globalization.CompareOptions options) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static int Compare(System.String strA, System.String strB, System.StringComparison comparisonType) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static int CompareOrdinal(System.String strA, int indexA, System.String strB, int indexB, int length) { throw null; }
- public static int CompareOrdinal(System.String strA, System.String strB) { throw null; }
- public int CompareTo(object value) { throw null; }
- public int CompareTo(System.String strB) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public static System.String Concat(System.Collections.Generic.IEnumerable<string> values) { throw null; }
- public static System.String Concat(object arg0) { throw null; }
- public static System.String Concat(object arg0, object arg1) { throw null; }
- public static System.String Concat(object arg0, object arg1, object arg2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.String Concat(params object[] args) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.String Concat(System.String str0, System.String str1) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.String Concat(System.String str0, System.String str1, System.String str2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.String Concat(System.String str0, System.String str1, System.String str2, System.String str3) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.String Concat(params string[] values) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public static System.String Concat<T>(System.Collections.Generic.IEnumerable<T> values) { throw null; }
- public bool Contains(System.String value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.String Copy(System.String str) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count) { }
- public bool EndsWith(System.String value) { throw null; }
- public bool EndsWith(System.String value, bool ignoreCase, System.Globalization.CultureInfo culture) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public bool EndsWith(System.String value, System.StringComparison comparisonType) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.String value) { throw null; }
- public static bool Equals(System.String a, System.String b) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool Equals(System.String a, System.String b, System.StringComparison comparisonType) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public bool Equals(System.String value, System.StringComparison comparisonType) { throw null; }
- public static System.String Format(System.IFormatProvider provider, System.String format, object arg0) { throw null; }
- public static System.String Format(System.IFormatProvider provider, System.String format, object arg0, object arg1) { throw null; }
- public static System.String Format(System.IFormatProvider provider, System.String format, object arg0, object arg1, object arg2) { throw null; }
- public static System.String Format(System.IFormatProvider provider, System.String format, params object[] args) { throw null; }
- public static System.String Format(System.String format, object arg0) { throw null; }
- public static System.String Format(System.String format, object arg0, object arg1) { throw null; }
- public static System.String Format(System.String format, object arg0, object arg1, object arg2) { throw null; }
- public static System.String Format(System.String format, params object[] args) { throw null; }
- public System.CharEnumerator GetEnumerator() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override int GetHashCode() { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- public int IndexOf(char value) { throw null; }
- public int IndexOf(char value, int startIndex) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public int IndexOf(char value, int startIndex, int count) { throw null; }
- public int IndexOf(System.String value) { throw null; }
- public int IndexOf(System.String value, int startIndex) { throw null; }
- public int IndexOf(System.String value, int startIndex, int count) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public int IndexOf(System.String value, int startIndex, int count, System.StringComparison comparisonType) { throw null; }
- public int IndexOf(System.String value, int startIndex, System.StringComparison comparisonType) { throw null; }
- public int IndexOf(System.String value, System.StringComparison comparisonType) { throw null; }
- public int IndexOfAny(char[] anyOf) { throw null; }
- public int IndexOfAny(char[] anyOf, int startIndex) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCriticalAttribute]
- public int IndexOfAny(char[] anyOf, int startIndex, int count) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.String Insert(int startIndex, System.String value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.String Intern(System.String str) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.String IsInterned(System.String str) { throw null; }
- public bool IsNormalized() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public bool IsNormalized(System.Text.NormalizationForm normalizationForm) { throw null; }
- public static bool IsNullOrEmpty(System.String value) { throw null; }
- public static bool IsNullOrWhiteSpace(System.String value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public static System.String Join(System.String separator, System.Collections.Generic.IEnumerable<string> values) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public static System.String Join(System.String separator, params object[] values) { throw null; }
- public static System.String Join(System.String separator, params string[] value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.String Join(System.String separator, string[] value, int startIndex, int count) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public static System.String Join<T>(System.String separator, System.Collections.Generic.IEnumerable<T> values) { throw null; }
- public int LastIndexOf(char value) { throw null; }
- public int LastIndexOf(char value, int startIndex) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public int LastIndexOf(char value, int startIndex, int count) { throw null; }
- public int LastIndexOf(System.String value) { throw null; }
- public int LastIndexOf(System.String value, int startIndex) { throw null; }
- public int LastIndexOf(System.String value, int startIndex, int count) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public int LastIndexOf(System.String value, int startIndex, int count, System.StringComparison comparisonType) { throw null; }
- public int LastIndexOf(System.String value, int startIndex, System.StringComparison comparisonType) { throw null; }
- public int LastIndexOf(System.String value, System.StringComparison comparisonType) { throw null; }
- public int LastIndexOfAny(char[] anyOf) { throw null; }
- public int LastIndexOfAny(char[] anyOf, int startIndex) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.Security.SecuritySafeCriticalAttribute]
- public int LastIndexOfAny(char[] anyOf, int startIndex, int count) { throw null; }
- public System.String Normalize() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.String Normalize(System.Text.NormalizationForm normalizationForm) { throw null; }
- public static bool operator ==(System.String a, System.String b) { throw null; }
- public static bool operator !=(System.String a, System.String b) { throw null; }
- public System.String PadLeft(int totalWidth) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.String PadLeft(int totalWidth, char paddingChar) { throw null; }
- public System.String PadRight(int totalWidth) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.String PadRight(int totalWidth, char paddingChar) { throw null; }
- public System.String Remove(int startIndex) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.String Remove(int startIndex, int count) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.String Replace(char oldChar, char newChar) { throw null; }
- public System.String Replace(System.String oldValue, System.String newValue) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string[] Split(char separator, int count, System.StringSplitOptions options = (System.StringSplitOptions)(0)) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string[] Split(char separator, System.StringSplitOptions options = (System.StringSplitOptions)(0)) { throw null; }
- public string[] Split(params char[] separator) { throw null; }
- public string[] Split(char[] separator, int count) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string[] Split(char[] separator, int count, System.StringSplitOptions options) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string[] Split(char[] separator, System.StringSplitOptions options) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string[] Split(System.String separator, int count, System.StringSplitOptions options = (System.StringSplitOptions)(0)) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string[] Split(System.String separator, System.StringSplitOptions options = (System.StringSplitOptions)(0)) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string[] Split(string[] separator, int count, System.StringSplitOptions options) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string[] Split(string[] separator, System.StringSplitOptions options) { throw null; }
- public bool StartsWith(System.String value) { throw null; }
- public bool StartsWith(System.String value, bool ignoreCase, System.Globalization.CultureInfo culture) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public bool StartsWith(System.String value, System.StringComparison comparisonType) { throw null; }
- public System.String Substring(int startIndex) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.String Substring(int startIndex, int length) { throw null; }
- System.Collections.Generic.IEnumerator<char> System.Collections.Generic.IEnumerable<System.Char>.GetEnumerator() { throw null; }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public char[] ToCharArray() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public char[] ToCharArray(int startIndex, int length) { throw null; }
- public System.String ToLower() { throw null; }
- public System.String ToLower(System.Globalization.CultureInfo culture) { throw null; }
- public System.String ToLowerInvariant() { throw null; }
- public override System.String ToString() { throw null; }
- public System.String ToString(System.IFormatProvider provider) { throw null; }
- public System.String ToUpper() { throw null; }
- public System.String ToUpper(System.Globalization.CultureInfo culture) { throw null; }
- public System.String ToUpperInvariant() { throw null; }
- public System.String Trim() { throw null; }
- public System.String Trim(params char[] trimChars) { throw null; }
- public System.String TrimEnd(params char[] trimChars) { throw null; }
- public System.String TrimEnd() { throw null; }
- public System.String TrimStart(params char[] trimChars) { throw null; }
- public System.String TrimStart() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class StringComparer : System.Collections.Generic.IComparer<string>, System.Collections.Generic.IEqualityComparer<string>, System.Collections.IComparer, System.Collections.IEqualityComparer
- {
- protected StringComparer() { }
- public static System.StringComparer CurrentCulture { get { throw null; } }
- public static System.StringComparer CurrentCultureIgnoreCase { get { throw null; } }
- public static System.StringComparer InvariantCulture { get { throw null; } }
- public static System.StringComparer InvariantCultureIgnoreCase { get { throw null; } }
- public static System.StringComparer Ordinal { get { throw null; } }
- public static System.StringComparer OrdinalIgnoreCase { get { throw null; } }
- public int Compare(object x, object y) { throw null; }
- public abstract int Compare(string x, string y);
- public static System.StringComparer Create(System.Globalization.CultureInfo culture, bool ignoreCase) { throw null; }
- public new bool Equals(object x, object y) { throw null; }
- public abstract bool Equals(string x, string y);
- public int GetHashCode(object obj) { throw null; }
- public abstract int GetHashCode(string obj);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum StringComparison
- {
- CurrentCulture = 0,
- CurrentCultureIgnoreCase = 1,
- InvariantCulture = 2,
- InvariantCultureIgnoreCase = 3,
- Ordinal = 4,
- OrdinalIgnoreCase = 5,
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public enum StringSplitOptions
- {
- None = 0,
- RemoveEmptyEntries = 1,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class SystemException : System.Exception
- {
- public SystemException() { }
- public SystemException(string message) { }
- public SystemException(string message, System.Exception innerException) { }
- protected SystemException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(256), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ThreadStaticAttribute : System.Attribute
- {
- public ThreadStaticAttribute() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class TimeoutException : System.SystemException
- {
- public TimeoutException() { }
- public TimeoutException(string message) { }
- public TimeoutException(string message, System.Exception innerException) { }
- protected TimeoutException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct TimeSpan : System.IComparable, System.IComparable<System.TimeSpan>, System.IEquatable<System.TimeSpan>, System.IFormattable
- {
- public static readonly System.TimeSpan MaxValue;
- public static readonly System.TimeSpan MinValue;
- public const long TicksPerDay = (long)864000000000;
- public const long TicksPerHour = (long)36000000000;
- public const long TicksPerMillisecond = (long)10000;
- public const long TicksPerMinute = (long)600000000;
- public const long TicksPerSecond = (long)10000000;
- public static readonly System.TimeSpan Zero;
- public TimeSpan(int hours, int minutes, int seconds) { throw null;}
- public TimeSpan(int days, int hours, int minutes, int seconds) { throw null;}
- public TimeSpan(int days, int hours, int minutes, int seconds, int milliseconds) { throw null;}
- public TimeSpan(long ticks) { throw null;}
- public int Days { get { throw null; } }
- public int Hours { get { throw null; } }
- public int Milliseconds { get { throw null; } }
- public int Minutes { get { throw null; } }
- public int Seconds { get { throw null; } }
- public long Ticks { get { throw null; } }
- public double TotalDays { get { throw null; } }
- public double TotalHours { get { throw null; } }
- public double TotalMilliseconds { get { throw null; } }
- public double TotalMinutes { get { throw null; } }
- public double TotalSeconds { get { throw null; } }
- public System.TimeSpan Add(System.TimeSpan ts) { throw null; }
- public static int Compare(System.TimeSpan t1, System.TimeSpan t2) { throw null; }
- public int CompareTo(object value) { throw null; }
- public int CompareTo(System.TimeSpan value) { throw null; }
- public System.TimeSpan Duration() { throw null; }
- public override bool Equals(object value) { throw null; }
- public bool Equals(System.TimeSpan obj) { throw null; }
- public static bool Equals(System.TimeSpan t1, System.TimeSpan t2) { throw null; }
- public static System.TimeSpan FromDays(double value) { throw null; }
- public static System.TimeSpan FromHours(double value) { throw null; }
- public static System.TimeSpan FromMilliseconds(double value) { throw null; }
- public static System.TimeSpan FromMinutes(double value) { throw null; }
- public static System.TimeSpan FromSeconds(double value) { throw null; }
- public static System.TimeSpan FromTicks(long value) { throw null; }
- public override int GetHashCode() { throw null; }
- public System.TimeSpan Negate() { throw null; }
- public static System.TimeSpan operator +(System.TimeSpan t1, System.TimeSpan t2) { throw null; }
- public static bool operator ==(System.TimeSpan t1, System.TimeSpan t2) { throw null; }
- public static bool operator >(System.TimeSpan t1, System.TimeSpan t2) { throw null; }
- public static bool operator >=(System.TimeSpan t1, System.TimeSpan t2) { throw null; }
- public static bool operator !=(System.TimeSpan t1, System.TimeSpan t2) { throw null; }
- public static bool operator <(System.TimeSpan t1, System.TimeSpan t2) { throw null; }
- public static bool operator <=(System.TimeSpan t1, System.TimeSpan t2) { throw null; }
- public static System.TimeSpan operator -(System.TimeSpan t1, System.TimeSpan t2) { throw null; }
- public static System.TimeSpan operator -(System.TimeSpan t) { throw null; }
- public static System.TimeSpan operator +(System.TimeSpan t) { throw null; }
- public static System.TimeSpan Parse(string s) { throw null; }
- public static System.TimeSpan Parse(string input, System.IFormatProvider formatProvider) { throw null; }
- public static System.TimeSpan ParseExact(string input, string format, System.IFormatProvider formatProvider) { throw null; }
- public static System.TimeSpan ParseExact(string input, string format, System.IFormatProvider formatProvider, System.Globalization.TimeSpanStyles styles) { throw null; }
- public static System.TimeSpan ParseExact(string input, string[] formats, System.IFormatProvider formatProvider) { throw null; }
- public static System.TimeSpan ParseExact(string input, string[] formats, System.IFormatProvider formatProvider, System.Globalization.TimeSpanStyles styles) { throw null; }
- public System.TimeSpan Subtract(System.TimeSpan ts) { throw null; }
- public override string ToString() { throw null; }
- public string ToString(string format) { throw null; }
- public string ToString(string format, System.IFormatProvider formatProvider) { throw null; }
- public static bool TryParse(string input, System.IFormatProvider formatProvider, out System.TimeSpan result) { result = default(System.TimeSpan); throw null; }
- public static bool TryParse(string s, out System.TimeSpan result) { result = default(System.TimeSpan); throw null; }
- public static bool TryParseExact(string input, string format, System.IFormatProvider formatProvider, System.Globalization.TimeSpanStyles styles, out System.TimeSpan result) { result = default(System.TimeSpan); throw null; }
- public static bool TryParseExact(string input, string format, System.IFormatProvider formatProvider, out System.TimeSpan result) { result = default(System.TimeSpan); throw null; }
- public static bool TryParseExact(string input, string[] formats, System.IFormatProvider formatProvider, System.Globalization.TimeSpanStyles styles, out System.TimeSpan result) { result = default(System.TimeSpan); throw null; }
- public static bool TryParseExact(string input, string[] formats, System.IFormatProvider formatProvider, out System.TimeSpan result) { result = default(System.TimeSpan); throw null; }
- }
- [System.ObsoleteAttribute("System.TimeZone has been deprecated. Please investigate the use of System.TimeZoneInfo instead.")]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class TimeZone
- {
- protected TimeZone() { }
- public abstract string DaylightName { get; }
- public abstract string StandardName { get; }
- public abstract System.Globalization.DaylightTime GetDaylightChanges(int year);
- public abstract System.TimeSpan GetUtcOffset(System.DateTime time);
- public virtual bool IsDaylightSavingTime(System.DateTime time) { throw null; }
- public static bool IsDaylightSavingTime(System.DateTime time, System.Globalization.DaylightTime daylightTimes) { throw null; }
- public virtual System.DateTime ToUniversalTime(System.DateTime time) { throw null; }
- }
- public sealed partial class TimeZoneInfo : System.IEquatable<System.TimeZoneInfo>, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable
- {
- internal TimeZoneInfo() { }
- public System.TimeSpan BaseUtcOffset { get { throw null; } }
- public string DaylightName { get { throw null; } }
- public string DisplayName { get { throw null; } }
- public string Id { get { throw null; } }
- public static System.TimeZoneInfo Local { get { throw null; } }
- public string StandardName { get { throw null; } }
- public bool SupportsDaylightSavingTime { get { throw null; } }
- public static System.TimeZoneInfo Utc { get { throw null; } }
- public static void ClearCachedData() { }
- public static System.DateTime ConvertTime(System.DateTime dateTime, System.TimeZoneInfo destinationTimeZone) { throw null; }
- public static System.DateTime ConvertTime(System.DateTime dateTime, System.TimeZoneInfo sourceTimeZone, System.TimeZoneInfo destinationTimeZone) { throw null; }
- public static System.DateTimeOffset ConvertTime(System.DateTimeOffset dateTimeOffset, System.TimeZoneInfo destinationTimeZone) { throw null; }
- public static System.DateTime ConvertTimeFromUtc(System.DateTime dateTime, System.TimeZoneInfo destinationTimeZone) { throw null; }
- public static System.DateTime ConvertTimeToUtc(System.DateTime dateTime) { throw null; }
- public static System.DateTime ConvertTimeToUtc(System.DateTime dateTime, System.TimeZoneInfo sourceTimeZone) { throw null; }
- public static System.TimeZoneInfo CreateCustomTimeZone(string id, System.TimeSpan baseUtcOffset, string displayName, string standardDisplayName) { throw null; }
- public static System.TimeZoneInfo CreateCustomTimeZone(string id, System.TimeSpan baseUtcOffset, string displayName, string standardDisplayName, string daylightDisplayName, System.TimeZoneInfo.AdjustmentRule[] adjustmentRules) { throw null; }
- public static System.TimeZoneInfo CreateCustomTimeZone(string id, System.TimeSpan baseUtcOffset, string displayName, string standardDisplayName, string daylightDisplayName, System.TimeZoneInfo.AdjustmentRule[] adjustmentRules, bool disableDaylightSavingTime) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.TimeZoneInfo other) { throw null; }
- public static System.TimeZoneInfo FindSystemTimeZoneById(string id) { throw null; }
- public static System.TimeZoneInfo FromSerializedString(string source) { throw null; }
- public System.TimeZoneInfo.AdjustmentRule[] GetAdjustmentRules() { throw null; }
- public System.TimeSpan[] GetAmbiguousTimeOffsets(System.DateTime dateTime) { throw null; }
- public System.TimeSpan[] GetAmbiguousTimeOffsets(System.DateTimeOffset dateTimeOffset) { throw null; }
- public override int GetHashCode() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Collections.ObjectModel.ReadOnlyCollection<System.TimeZoneInfo> GetSystemTimeZones() { throw null; }
- public System.TimeSpan GetUtcOffset(System.DateTime dateTime) { throw null; }
- public System.TimeSpan GetUtcOffset(System.DateTimeOffset dateTimeOffset) { throw null; }
- public bool HasSameRules(System.TimeZoneInfo other) { throw null; }
- public bool IsAmbiguousTime(System.DateTime dateTime) { throw null; }
- public bool IsAmbiguousTime(System.DateTimeOffset dateTimeOffset) { throw null; }
- public bool IsDaylightSavingTime(System.DateTime dateTime) { throw null; }
- public bool IsDaylightSavingTime(System.DateTimeOffset dateTimeOffset) { throw null; }
- public bool IsInvalidTime(System.DateTime dateTime) { throw null; }
- void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { }
- [System.Security.SecurityCriticalAttribute]
- void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public string ToSerializedString() { throw null; }
- public override string ToString() { throw null; }
- public sealed partial class AdjustmentRule : System.IEquatable<System.TimeZoneInfo.AdjustmentRule>, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable
- {
- internal AdjustmentRule() { }
- public System.DateTime DateEnd { get { throw null; } }
- public System.DateTime DateStart { get { throw null; } }
- public System.TimeSpan DaylightDelta { get { throw null; } }
- public System.TimeZoneInfo.TransitionTime DaylightTransitionEnd { get { throw null; } }
- public System.TimeZoneInfo.TransitionTime DaylightTransitionStart { get { throw null; } }
- public static System.TimeZoneInfo.AdjustmentRule CreateAdjustmentRule(System.DateTime dateStart, System.DateTime dateEnd, System.TimeSpan daylightDelta, System.TimeZoneInfo.TransitionTime daylightTransitionStart, System.TimeZoneInfo.TransitionTime daylightTransitionEnd) { throw null; }
- public bool Equals(System.TimeZoneInfo.AdjustmentRule other) { throw null; }
- public override int GetHashCode() { throw null; }
- void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { }
- [System.Security.SecurityCriticalAttribute]
- void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct TransitionTime : System.IEquatable<System.TimeZoneInfo.TransitionTime>, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable
- {
- public int Day { get { throw null; } }
- public System.DayOfWeek DayOfWeek { get { throw null; } }
- public bool IsFixedDateRule { get { throw null; } }
- public int Month { get { throw null; } }
- public System.DateTime TimeOfDay { get { throw null; } }
- public int Week { get { throw null; } }
- public static System.TimeZoneInfo.TransitionTime CreateFixedDateRule(System.DateTime timeOfDay, int month, int day) { throw null; }
- public static System.TimeZoneInfo.TransitionTime CreateFloatingDateRule(System.DateTime timeOfDay, int month, int week, System.DayOfWeek dayOfWeek) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.TimeZoneInfo.TransitionTime other) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.TimeZoneInfo.TransitionTime t1, System.TimeZoneInfo.TransitionTime t2) { throw null; }
- public static bool operator !=(System.TimeZoneInfo.TransitionTime t1, System.TimeZoneInfo.TransitionTime t2) { throw null; }
- void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { }
- [System.Security.SecurityCriticalAttribute]
- void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
- }
- [System.Runtime.CompilerServices.TypeForwardedFromAttribute("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
- public partial class TimeZoneNotFoundException : System.Exception
- {
- public TimeZoneNotFoundException() { }
- protected TimeZoneNotFoundException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public TimeZoneNotFoundException(string message) { }
- public TimeZoneNotFoundException(string message, System.Exception innerException) { }
- }
- public static partial class Tuple
- {
- public static System.Tuple<T1> Create<T1>(T1 item1) { throw null; }
- public static System.Tuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2) { throw null; }
- public static System.Tuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3) { throw null; }
- public static System.Tuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 item1, T2 item2, T3 item3, T4 item4) { throw null; }
- public static System.Tuple<T1, T2, T3, T4, T5> Create<T1, T2, T3, T4, T5>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { throw null; }
- public static System.Tuple<T1, T2, T3, T4, T5, T6> Create<T1, T2, T3, T4, T5, T6>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { throw null; }
- public static System.Tuple<T1, T2, T3, T4, T5, T6, T7> Create<T1, T2, T3, T4, T5, T6, T7>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { throw null; }
- public static System.Tuple<T1, T2, T3, T4, T5, T6, T7, System.Tuple<T8>> Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) { throw null; }
- }
- public partial class Tuple<T1> : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable
- {
- public Tuple(T1 item1) { }
- public T1 Item1 { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; }
- bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; }
- int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; }
- int System.IComparable.CompareTo(object obj) { throw null; }
- public override string ToString() { throw null; }
- }
- public partial class Tuple<T1, T2> : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable
- {
- public Tuple(T1 item1, T2 item2) { }
- public T1 Item1 { get { throw null; } }
- public T2 Item2 { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; }
- bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; }
- int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; }
- int System.IComparable.CompareTo(object obj) { throw null; }
- public override string ToString() { throw null; }
- }
- public partial class Tuple<T1, T2, T3> : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable
- {
- public Tuple(T1 item1, T2 item2, T3 item3) { }
- public T1 Item1 { get { throw null; } }
- public T2 Item2 { get { throw null; } }
- public T3 Item3 { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; }
- bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; }
- int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; }
- int System.IComparable.CompareTo(object obj) { throw null; }
- public override string ToString() { throw null; }
- }
- public partial class Tuple<T1, T2, T3, T4> : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable
- {
- public Tuple(T1 item1, T2 item2, T3 item3, T4 item4) { }
- public T1 Item1 { get { throw null; } }
- public T2 Item2 { get { throw null; } }
- public T3 Item3 { get { throw null; } }
- public T4 Item4 { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; }
- bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; }
- int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; }
- int System.IComparable.CompareTo(object obj) { throw null; }
- public override string ToString() { throw null; }
- }
- public partial class Tuple<T1, T2, T3, T4, T5> : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable
- {
- public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { }
- public T1 Item1 { get { throw null; } }
- public T2 Item2 { get { throw null; } }
- public T3 Item3 { get { throw null; } }
- public T4 Item4 { get { throw null; } }
- public T5 Item5 { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; }
- bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; }
- int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; }
- int System.IComparable.CompareTo(object obj) { throw null; }
- public override string ToString() { throw null; }
- }
- public partial class Tuple<T1, T2, T3, T4, T5, T6> : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable
- {
- public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { }
- public T1 Item1 { get { throw null; } }
- public T2 Item2 { get { throw null; } }
- public T3 Item3 { get { throw null; } }
- public T4 Item4 { get { throw null; } }
- public T5 Item5 { get { throw null; } }
- public T6 Item6 { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; }
- bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; }
- int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; }
- int System.IComparable.CompareTo(object obj) { throw null; }
- public override string ToString() { throw null; }
- }
- public partial class Tuple<T1, T2, T3, T4, T5, T6, T7> : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable
- {
- public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { }
- public T1 Item1 { get { throw null; } }
- public T2 Item2 { get { throw null; } }
- public T3 Item3 { get { throw null; } }
- public T4 Item4 { get { throw null; } }
- public T5 Item5 { get { throw null; } }
- public T6 Item6 { get { throw null; } }
- public T7 Item7 { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; }
- bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; }
- int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; }
- int System.IComparable.CompareTo(object obj) { throw null; }
- public override string ToString() { throw null; }
- }
- public partial class Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> : System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IComparable
- {
- public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) { }
- public T1 Item1 { get { throw null; } }
- public T2 Item2 { get { throw null; } }
- public T3 Item3 { get { throw null; } }
- public T4 Item4 { get { throw null; } }
- public T5 Item5 { get { throw null; } }
- public T6 Item6 { get { throw null; } }
- public T7 Item7 { get { throw null; } }
- public TRest Rest { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- int System.Collections.IStructuralComparable.CompareTo(object other, System.Collections.IComparer comparer) { throw null; }
- bool System.Collections.IStructuralEquatable.Equals(object other, System.Collections.IEqualityComparer comparer) { throw null; }
- int System.Collections.IStructuralEquatable.GetHashCode(System.Collections.IEqualityComparer comparer) { throw null; }
- int System.IComparable.CompareTo(object obj) { throw null; }
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class Type : System.Reflection.MemberInfo, System.Reflection.IReflect
- {
- public static readonly char Delimiter;
- public static readonly System.Type[] EmptyTypes;
- public static readonly System.Reflection.MemberFilter FilterAttribute;
- public static readonly System.Reflection.MemberFilter FilterName;
- public static readonly System.Reflection.MemberFilter FilterNameIgnoreCase;
- public static readonly object Missing;
- protected Type() { }
- [System.Security.SecuritySafeCriticalAttribute][System.Diagnostics.Contracts.PureAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- public static bool operator ==(System.Type left, System.Type right) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute][System.Diagnostics.Contracts.PureAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- public static bool operator !=(System.Type left, System.Type right) { throw null; }
- public abstract System.Reflection.Assembly Assembly { get; }
- public abstract string AssemblyQualifiedName { get; }
- public System.Reflection.TypeAttributes Attributes { get { throw null; } }
- public abstract System.Type BaseType { get; }
- public virtual bool ContainsGenericParameters { get { throw null; } }
- public virtual System.Reflection.MethodBase DeclaringMethod { get { throw null; } }
- public override System.Type DeclaringType { get { throw null; } }
- public static System.Reflection.Binder DefaultBinder { get { throw null; } }
- public abstract string FullName { get; }
- public virtual System.Reflection.GenericParameterAttributes GenericParameterAttributes { get { throw null; } }
- public virtual int GenericParameterPosition { get { throw null; } }
- public virtual System.Type[] GenericTypeArguments { get { throw null; } }
- public abstract System.Guid GUID { get; }
- public bool HasElementType { get { throw null; } }
- public bool IsAbstract { get { throw null; } }
- public bool IsAnsiClass { get { throw null; } }
- public bool IsArray { get { throw null; } }
- public bool IsAutoClass { get { throw null; } }
- public bool IsAutoLayout { get { throw null; } }
- public bool IsByRef { get { throw null; } }
- public bool IsClass { get { throw null; } }
- public bool IsCOMObject { get { throw null; } }
- public virtual bool IsConstructedGenericType { get { throw null; } }
- public bool IsContextful { [System.Diagnostics.Contracts.PureAttribute]get { throw null;} }
- public bool IsEnum { get { throw null; } }
- public bool IsExplicitLayout { get { throw null; } }
- public virtual bool IsGenericParameter { get { throw null; } }
- public virtual bool IsGenericType { get { throw null; } }
- public virtual bool IsGenericTypeDefinition { get { throw null; } }
- public bool IsImport { get { throw null; } }
- public bool IsInterface { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public bool IsLayoutSequential { get { throw null; } }
- public bool IsMarshalByRef { get { throw null; } }
- public bool IsNested { get { throw null; } }
- public bool IsNestedAssembly { get { throw null; } }
- public bool IsNestedFamANDAssem { get { throw null; } }
- public bool IsNestedFamily { get { throw null; } }
- public bool IsNestedFamORAssem { get { throw null; } }
- public bool IsNestedPrivate { get { throw null; } }
- public bool IsNestedPublic { get { throw null; } }
- public bool IsNotPublic { get { throw null; } }
- public bool IsPointer { get { throw null; } }
- public bool IsPrimitive { get { throw null; } }
- public bool IsPublic { get { throw null; } }
- public bool IsSealed { get { throw null; } }
- public virtual bool IsSerializable { get { throw null; } }
- public bool IsSpecialName { get { throw null; } }
- public bool IsUnicodeClass { get { throw null; } }
- public bool IsValueType { get { throw null; } }
- public bool IsVisible { get { throw null; } }
- public override System.Reflection.MemberTypes MemberType { get { throw null; } }
- public abstract new System.Reflection.Module Module { get; }
- public abstract string Namespace { get; }
- public override System.Type ReflectedType { get { throw null; } }
- public virtual System.Runtime.InteropServices.StructLayoutAttribute StructLayoutAttribute { get { throw null; } }
- public virtual System.RuntimeTypeHandle TypeHandle { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public System.Reflection.ConstructorInfo TypeInitializer { get { throw null; } }
- public abstract System.Type UnderlyingSystemType { get; }
- public override bool Equals(object o) { throw null; }
- public bool Equals(System.Type o) { throw null; }
- public virtual System.Type[] FindInterfaces(System.Reflection.TypeFilter filter, object filterCriteria) { throw null; }
- public virtual System.Reflection.MemberInfo[] FindMembers(System.Reflection.MemberTypes memberType, System.Reflection.BindingFlags bindingAttr, System.Reflection.MemberFilter filter, object filterCriteria) { throw null; }
- public virtual int GetArrayRank() { throw null; }
- protected abstract System.Reflection.TypeAttributes GetAttributeFlagsImpl();
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public System.Reflection.ConstructorInfo GetConstructor(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public System.Reflection.ConstructorInfo GetConstructor(System.Type[] types) { throw null; }
- protected abstract System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers);
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public System.Reflection.ConstructorInfo[] GetConstructors() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr);
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public System.Reflection.ConstructorInfo GetConstructor(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- public virtual System.Reflection.MemberInfo[] GetDefaultMembers() { throw null; }
- public abstract System.Type GetElementType();
- public virtual string GetEnumName(object value) { throw null; }
- public virtual string[] GetEnumNames() { throw null; }
- public virtual System.Type GetEnumUnderlyingType() { throw null; }
- public virtual System.Array GetEnumValues() { throw null; }
- public System.Reflection.EventInfo GetEvent(string name) { throw null; }
- public abstract System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr);
- public virtual System.Reflection.EventInfo[] GetEvents() { throw null; }
- public abstract System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr);
- public System.Reflection.FieldInfo GetField(string name) { throw null; }
- public abstract System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr);
- public System.Reflection.FieldInfo[] GetFields() { throw null; }
- public abstract System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr);
- public virtual System.Type[] GetGenericArguments() { throw null; }
- public virtual System.Type[] GetGenericParameterConstraints() { throw null; }
- public virtual System.Type GetGenericTypeDefinition() { throw null; }
- public override int GetHashCode() { throw null; }
- public System.Type GetInterface(string name) { throw null; }
- public abstract System.Type GetInterface(string name, bool ignoreCase);
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public virtual System.Reflection.InterfaceMapping GetInterfaceMap(System.Type interfaceType) { throw null; }
- public abstract System.Type[] GetInterfaces();
- public System.Reflection.MemberInfo[] GetMember(string name) { throw null; }
- public virtual System.Reflection.MemberInfo[] GetMember(string name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public virtual System.Reflection.MemberInfo[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public System.Reflection.MemberInfo[] GetMembers() { throw null; }
- public abstract System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr);
- public System.Reflection.MethodInfo GetMethod(string name) { throw null; }
- public System.Reflection.MethodInfo GetMethod(string name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public System.Reflection.MethodInfo GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- public System.Reflection.MethodInfo GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- public System.Reflection.MethodInfo GetMethod(string name, System.Type[] types) { throw null; }
- public System.Reflection.MethodInfo GetMethod(string name, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- protected abstract System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers);
- public System.Reflection.MethodInfo[] GetMethods() { throw null; }
- public abstract System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr);
- public System.Type GetNestedType(string name) { throw null; }
- public abstract System.Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr);
- public System.Type[] GetNestedTypes() { throw null; }
- public abstract System.Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr);
- public System.Reflection.PropertyInfo[] GetProperties() { throw null; }
- public abstract System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr);
- public System.Reflection.PropertyInfo GetProperty(string name) { throw null; }
- public System.Reflection.PropertyInfo GetProperty(string name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public System.Reflection.PropertyInfo GetProperty(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Type returnType, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- public System.Reflection.PropertyInfo GetProperty(string name, System.Type returnType) { throw null; }
- public System.Reflection.PropertyInfo GetProperty(string name, System.Type returnType, System.Type[] types) { throw null; }
- public System.Reflection.PropertyInfo GetProperty(string name, System.Type returnType, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- public System.Reflection.PropertyInfo GetProperty(string name, System.Type[] types) { throw null; }
- protected abstract System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Type returnType, System.Type[] types, System.Reflection.ParameterModifier[] modifiers);
- public new System.Type GetType() { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public static System.Type GetType(string typeName) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public static System.Type GetType(string typeName, bool throwOnError) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public static System.Type GetType(string typeName, bool throwOnError, bool ignoreCase) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public static System.Type GetType(string typeName, System.Func<System.Reflection.AssemblyName, System.Reflection.Assembly> assemblyResolver, System.Func<System.Reflection.Assembly, string, bool, System.Type> typeResolver) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public static System.Type GetType(string typeName, System.Func<System.Reflection.AssemblyName, System.Reflection.Assembly> assemblyResolver, System.Func<System.Reflection.Assembly, string, bool, System.Type> typeResolver, bool throwOnError) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public static System.Type GetType(string typeName, System.Func<System.Reflection.AssemblyName, System.Reflection.Assembly> assemblyResolver, System.Func<System.Reflection.Assembly, string, bool, System.Type> typeResolver, bool throwOnError, bool ignoreCase) { throw null; }
- public static System.Type[] GetTypeArray(System.Object[] args) { throw null; }
- public static System.TypeCode GetTypeCode(System.Type type) { throw null; }
- protected virtual System.TypeCode GetTypeCodeImpl() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]public static System.Type GetTypeFromCLSID(System.Guid clsid) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]public static System.Type GetTypeFromCLSID(System.Guid clsid, bool throwOnError) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]public static System.Type GetTypeFromCLSID(System.Guid clsid, string server) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]public static System.Type GetTypeFromCLSID(System.Guid clsid, string server, bool throwOnError) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static System.Type GetTypeFromHandle(System.RuntimeTypeHandle handle) { throw null; }
- [System.Security.SecurityCriticalAttribute]public static System.Type GetTypeFromProgID(string progID) { throw null; }
- [System.Security.SecurityCriticalAttribute]public static System.Type GetTypeFromProgID(string progID, bool throwOnError) { throw null; }
- [System.Security.SecurityCriticalAttribute]public static System.Type GetTypeFromProgID(string progID, string server) { throw null; }
- [System.Security.SecurityCriticalAttribute]public static System.Type GetTypeFromProgID(string progID, string server, bool throwOnError) { throw null; }
- public static System.RuntimeTypeHandle GetTypeHandle(object o) { throw null; }
- protected abstract bool HasElementTypeImpl();
- [System.Diagnostics.DebuggerHiddenAttribute]
- [System.Diagnostics.DebuggerStepThroughAttribute]
- public object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args) { throw null; }
- [System.Diagnostics.DebuggerStepThroughAttribute][System.Diagnostics.DebuggerHiddenAttribute]
- public System.Object InvokeMember(System.String name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object target, System.Object[] args, System.Globalization.CultureInfo culture) { throw null; }
- public abstract object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters);
- protected abstract bool IsArrayImpl();
- public virtual bool IsAssignableFrom(System.Type c) { throw null; }
- protected abstract bool IsByRefImpl();
- protected abstract bool IsCOMObjectImpl();
- protected virtual bool IsContextfulImpl() { throw null; }
- public virtual bool IsEnumDefined(object value) { throw null; }
- public virtual bool IsEquivalentTo(System.Type other) { throw null; }
- public virtual bool IsInstanceOfType(object o) { throw null; }
- protected virtual bool IsMarshalByRefImpl() { throw null; }
- protected abstract bool IsPointerImpl();
- protected abstract bool IsPrimitiveImpl();
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public virtual bool IsSubclassOf(System.Type c) { throw null; }
- protected virtual bool IsValueTypeImpl() { throw null; }
- public virtual System.Type MakeArrayType() { throw null; }
- public virtual System.Type MakeArrayType(int rank) { throw null; }
- public virtual System.Type MakeByRefType() { throw null; }
- public virtual System.Type MakeGenericType(params System.Type[] typeArguments) { throw null; }
- public virtual System.Type MakePointerType() { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public static System.Type ReflectionOnlyGetType(System.String typeName, bool throwIfNotFound, bool ignoreCase) { throw null; }
- public override string ToString() { throw null; }
- }
- public partial class TypeAccessException : System.TypeLoadException
- {
- public TypeAccessException() { }
- public TypeAccessException(string message) { }
- public TypeAccessException(string message, System.Exception inner) { }
- protected TypeAccessException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum TypeCode
- {
- Boolean = 3,
- Byte = 6,
- Char = 4,
- DateTime = 16,
- DBNull = 2,
- Decimal = 15,
- Double = 14,
- Empty = 0,
- Int16 = 7,
- Int32 = 9,
- Int64 = 11,
- Object = 1,
- SByte = 5,
- Single = 13,
- String = 18,
- UInt16 = 8,
- UInt32 = 10,
- UInt64 = 12,
- }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct TypedReference
- {
- public override bool Equals(object o) { throw null; }
- public override int GetHashCode() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class TypeInitializationException : System.SystemException
- {
- public TypeInitializationException(string fullTypeName, System.Exception innerException) { }
- public string TypeName { get { throw null; } }
- [System.Security.SecurityCriticalAttribute]
- public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class TypeLoadException : System.SystemException, System.Runtime.Serialization.ISerializable
- {
- public TypeLoadException() { }
- public TypeLoadException(string message) { }
- public TypeLoadException(string message, System.Exception inner) { }
- protected TypeLoadException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- public override string Message { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public string TypeName { get { throw null; } }
- [System.Security.SecurityCriticalAttribute]
- public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class TypeUnloadedException : System.SystemException
- {
- public TypeUnloadedException() { }
- protected TypeUnloadedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public TypeUnloadedException(string message) { }
- public TypeUnloadedException(string message, System.Exception innerException) { }
- }
- internal sealed class TypeNameParser : System.IDisposable
- {
- [System.Security.SecuritySafeCriticalAttribute]public void Dispose() { throw null; }
- }
- [System.Security.SecurityCriticalAttribute]
- internal class SafeTypeNameParserHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
- {
- public SafeTypeNameParserHandle(): base(default(bool)) { }
- [System.Security.SecurityCriticalAttribute]
- protected override bool ReleaseHandle() { throw null; }
- }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct UInt16 : System.IComparable, System.IComparable<ushort>, System.IConvertible, System.IEquatable<ushort>, System.IFormattable
- {
- public const ushort MaxValue = (ushort)65535;
- public const ushort MinValue = (ushort)0;
- public int CompareTo(object value) { throw null; }
- public int CompareTo(System.UInt16 value) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.UInt16 obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.UInt16 Parse(string s) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.UInt16 Parse(string s, System.Globalization.NumberStyles style) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.UInt16 Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.UInt16 Parse(string s, System.IFormatProvider provider) { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- System.UInt16 System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static bool TryParse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider, out System.UInt16 result) { result = default(ushort); throw null; }
- [System.CLSCompliantAttribute(false)]
- public static bool TryParse(string s, out System.UInt16 result) { result = default(ushort); throw null; }
- }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct UInt32 : System.IComparable, System.IComparable<uint>, System.IConvertible, System.IEquatable<uint>, System.IFormattable
- {
- public const uint MaxValue = (uint)4294967295;
- public const uint MinValue = (uint)0;
- public int CompareTo(object value) { throw null; }
- public int CompareTo(System.UInt32 value) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.UInt32 obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.UInt32 Parse(string s) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.UInt32 Parse(string s, System.Globalization.NumberStyles style) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.UInt32 Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.UInt32 Parse(string s, System.IFormatProvider provider) { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- System.UInt32 System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- ulong System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static bool TryParse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider, out System.UInt32 result) { result = default(uint); throw null; }
- [System.CLSCompliantAttribute(false)]
- public static bool TryParse(string s, out System.UInt32 result) { result = default(uint); throw null; }
- }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct UInt64 : System.IComparable, System.IComparable<ulong>, System.IConvertible, System.IEquatable<ulong>, System.IFormattable
- {
- public const ulong MaxValue = (ulong)18446744073709551615;
- public const ulong MinValue = (ulong)0;
- public int CompareTo(object value) { throw null; }
- public int CompareTo(System.UInt64 value) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.UInt64 obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public System.TypeCode GetTypeCode() { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.UInt64 Parse(string s) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.UInt64 Parse(string s, System.Globalization.NumberStyles style) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.UInt64 Parse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.UInt64 Parse(string s, System.IFormatProvider provider) { throw null; }
- bool System.IConvertible.ToBoolean(System.IFormatProvider provider) { throw null; }
- byte System.IConvertible.ToByte(System.IFormatProvider provider) { throw null; }
- char System.IConvertible.ToChar(System.IFormatProvider provider) { throw null; }
- System.DateTime System.IConvertible.ToDateTime(System.IFormatProvider provider) { throw null; }
- decimal System.IConvertible.ToDecimal(System.IFormatProvider provider) { throw null; }
- double System.IConvertible.ToDouble(System.IFormatProvider provider) { throw null; }
- short System.IConvertible.ToInt16(System.IFormatProvider provider) { throw null; }
- int System.IConvertible.ToInt32(System.IFormatProvider provider) { throw null; }
- long System.IConvertible.ToInt64(System.IFormatProvider provider) { throw null; }
- sbyte System.IConvertible.ToSByte(System.IFormatProvider provider) { throw null; }
- float System.IConvertible.ToSingle(System.IFormatProvider provider) { throw null; }
- object System.IConvertible.ToType(System.Type type, System.IFormatProvider provider) { throw null; }
- ushort System.IConvertible.ToUInt16(System.IFormatProvider provider) { throw null; }
- uint System.IConvertible.ToUInt32(System.IFormatProvider provider) { throw null; }
- System.UInt64 System.IConvertible.ToUInt64(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(System.IFormatProvider provider) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(string format, System.IFormatProvider provider) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static bool TryParse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider, out System.UInt64 result) { result = default(ulong); throw null; }
- [System.CLSCompliantAttribute(false)]
- public static bool TryParse(string s, out System.UInt64 result) { result = default(ulong); throw null; }
- }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct UIntPtr : System.Runtime.Serialization.ISerializable
- {
- public static readonly System.UIntPtr Zero;
- [System.Security.SecuritySafeCriticalAttribute]
- public UIntPtr(uint value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public UIntPtr(ulong value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe UIntPtr(void* value) { throw null; }
- public static int Size { get { throw null; } }
- public static System.UIntPtr Add(System.UIntPtr pointer, int offset) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override bool Equals(object obj) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override int GetHashCode() { throw null; }
- public static System.UIntPtr operator +(System.UIntPtr pointer, int offset) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool operator ==(System.UIntPtr value1, System.UIntPtr value2) { throw null; }
- public static explicit operator System.UIntPtr(uint value) { throw null; }
- public static explicit operator System.UIntPtr(ulong value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static explicit operator uint(System.UIntPtr value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static explicit operator ulong(System.UIntPtr value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe static explicit operator void* (System.UIntPtr value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe static explicit operator System.UIntPtr(void* value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool operator !=(System.UIntPtr value1, System.UIntPtr value2) { throw null; }
- public static System.UIntPtr operator -(System.UIntPtr pointer, int offset) { throw null; }
- public static System.UIntPtr Subtract(System.UIntPtr pointer, int offset) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public unsafe void* ToPointer() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public uint ToUInt32() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public ulong ToUInt64() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class UnauthorizedAccessException : System.SystemException
- {
- public UnauthorizedAccessException() { }
- public UnauthorizedAccessException(string message) { }
- public UnauthorizedAccessException(string message, System.Exception inner) { }
- protected UnauthorizedAccessException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class UnhandledExceptionEventArgs : System.EventArgs
- {
- public UnhandledExceptionEventArgs(object exception, bool isTerminating) { }
- public object ExceptionObject { get { throw null; } }
- public bool IsTerminating { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public delegate void UnhandledExceptionEventHandler(object sender, System.UnhandledExceptionEventArgs e);
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class ValueType
- {
- protected ValueType() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public override bool Equals(object obj) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public override int GetHashCode() { throw null; }
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class Version : System.ICloneable, System.IComparable, System.IComparable<System.Version>, System.IEquatable<System.Version>
- {
- public Version(int major, int minor) { }
- public Version(int major, int minor, int build) { }
- public Version(int major, int minor, int build, int revision) { }
- public Version(string version) { }
- public Version() { }
- public int Build { get { throw null; } }
- public int Major { get { throw null; } }
- public short MajorRevision { get { throw null; } }
- public int Minor { get { throw null; } }
- public short MinorRevision { get { throw null; } }
- public int Revision { get { throw null; } }
- public object Clone() { throw null; }
- public int CompareTo(object version) { throw null; }
- public int CompareTo(System.Version value) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.Version obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Version v1, System.Version v2) { throw null; }
- public static bool operator >(System.Version v1, System.Version v2) { throw null; }
- public static bool operator >=(System.Version v1, System.Version v2) { throw null; }
- public static bool operator !=(System.Version v1, System.Version v2) { throw null; }
- public static bool operator <(System.Version v1, System.Version v2) { throw null; }
- public static bool operator <=(System.Version v1, System.Version v2) { throw null; }
- public static System.Version Parse(string input) { throw null; }
- public override string ToString() { throw null; }
- public string ToString(int fieldCount) { throw null; }
- public static bool TryParse(string input, out System.Version result) { result = default(System.Version); throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Size=1)]
- public partial struct Void
- {
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class WeakReference : System.Runtime.Serialization.ISerializable
- {
- [System.Security.SecuritySafeCriticalAttribute]
- protected WeakReference() { }
- public WeakReference(object target) { }
- public WeakReference(object target, bool trackResurrection) { }
- protected WeakReference(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public virtual bool IsAlive { [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } }
- public virtual object Target { [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]set { } }
- public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public virtual bool TrackResurrection { get { throw null; } }
- ~WeakReference() { }
- }
- public sealed partial class WeakReference<T> : System.Runtime.Serialization.ISerializable where T : class
- {
- public WeakReference(T target) { }
- public WeakReference(T target, bool trackResurrection) { }
- ~WeakReference() { }
- public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public void SetTarget(T target) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public bool TryGetTarget(out T target) { target = default(T); throw null; }
- }
-}
-namespace System.Collections
-{
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class CollectionBase : System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList
- {
- protected CollectionBase() { }
- public int Count { get { throw null; } }
- protected System.Collections.IList List { get { throw null; } }
- bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
- object System.Collections.ICollection.SyncRoot { get { throw null; } }
- bool System.Collections.IList.IsFixedSize { get { throw null; } }
- bool System.Collections.IList.IsReadOnly { get { throw null; } }
- object System.Collections.IList.this[int index] { get { throw null; } set { } }
- public void Clear() { }
- public System.Collections.IEnumerator GetEnumerator() { throw null; }
- public void RemoveAt(int index) { }
- void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
- int System.Collections.IList.Add(object value) { throw null; }
- bool System.Collections.IList.Contains(object value) { throw null; }
- int System.Collections.IList.IndexOf(object value) { throw null; }
- void System.Collections.IList.Insert(int index, object value) { }
- void System.Collections.IList.Remove(object value) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct DictionaryEntry
- {
- public DictionaryEntry(object key, object value) { throw null;}
- public object Key { get { throw null; } set { } }
- public object Value { get { throw null; } set { } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface ICollection : System.Collections.IEnumerable
- {
- int Count { get; }
- bool IsSynchronized { get; }
- object SyncRoot { get; }
- void CopyTo(System.Array array, int index);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IComparer
- {
- int Compare(object x, object y);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IDictionary : System.Collections.ICollection, System.Collections.IEnumerable
- {
- bool IsFixedSize { get; }
- bool IsReadOnly { get; }
- object this[object key] { get; set; }
- System.Collections.ICollection Keys { get; }
- System.Collections.ICollection Values { get; }
- void Add(object key, object value);
- void Clear();
- bool Contains(object key);
- new System.Collections.IDictionaryEnumerator GetEnumerator();
- void Remove(object key);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IDictionaryEnumerator : System.Collections.IEnumerator
- {
- System.Collections.DictionaryEntry Entry { get; }
- object Key { get; }
- object Value { get; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.GuidAttribute("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
- public partial interface IEnumerable
- {
- [System.Runtime.InteropServices.DispIdAttribute(-4)]
- System.Collections.IEnumerator GetEnumerator();
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.GuidAttribute("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
- public partial interface IEnumerator
- {
- object Current { get; }
- bool MoveNext();
- void Reset();
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IEqualityComparer
- {
- bool Equals(object x, object y);
- int GetHashCode(object obj);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IList : System.Collections.ICollection, System.Collections.IEnumerable
- {
- bool IsFixedSize { get; }
- bool IsReadOnly { get; }
- object this[int index] { get; set; }
- int Add(object value);
- void Clear();
- bool Contains(object value);
- int IndexOf(object value);
- void Insert(int index, object value);
- void Remove(object value);
- void RemoveAt(int index);
- }
- public partial interface IStructuralComparable
- {
- int CompareTo(object other, System.Collections.IComparer comparer);
- }
- public partial interface IStructuralEquatable
- {
- bool Equals(object other, System.Collections.IEqualityComparer comparer);
- int GetHashCode(System.Collections.IEqualityComparer comparer);
- }
- public static partial class StructuralComparisons
- {
- public static System.Collections.IComparer StructuralComparer { get { throw null; } }
- public static System.Collections.IEqualityComparer StructuralEqualityComparer { get { throw null; } }
- }
-}
-namespace System.Collections.Generic
-{
- public abstract partial class Comparer<T> : System.Collections.Generic.IComparer<T>, System.Collections.IComparer
- {
- protected Comparer() { }
- public static System.Collections.Generic.Comparer<T> Default { get { throw null; } }
- public abstract int Compare(T x, T y);
- public static System.Collections.Generic.Comparer<T> Create(System.Comparison<T> comparison) { throw null; }
- int System.Collections.IComparer.Compare(object x, object y) { throw null; }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("Count = {Count}")]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public partial class Dictionary<TKey, TValue> : System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.Generic.IDictionary<TKey, TValue>, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.Generic.IReadOnlyCollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.Generic.IReadOnlyDictionary<TKey, TValue>, System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable
- {
- public Dictionary() { }
- public Dictionary(System.Collections.Generic.IDictionary<TKey, TValue> dictionary) { }
- public Dictionary(System.Collections.Generic.IDictionary<TKey, TValue> dictionary, System.Collections.Generic.IEqualityComparer<TKey> comparer) { }
- public Dictionary(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TValue>> collection) { }
- public Dictionary(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TValue>> collection, System.Collections.Generic.IEqualityComparer<TKey> comparer) { }
- public Dictionary(System.Collections.Generic.IEqualityComparer<TKey> comparer) { }
- public Dictionary(int capacity) { }
- public Dictionary(int capacity, System.Collections.Generic.IEqualityComparer<TKey> comparer) { }
- protected Dictionary(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public System.Collections.Generic.IEqualityComparer<TKey> Comparer { get { throw null; } }
- public int Count { get { throw null; } }
- public TValue this[TKey key] { get { throw null; } set { } }
- public System.Collections.Generic.Dictionary<TKey, TValue>.KeyCollection Keys { get { throw null; } }
- bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.IsReadOnly { get { throw null; } }
- System.Collections.Generic.ICollection<TKey> System.Collections.Generic.IDictionary<TKey,TValue>.Keys { get { throw null; } }
- System.Collections.Generic.ICollection<TValue> System.Collections.Generic.IDictionary<TKey,TValue>.Values { get { throw null; } }
- System.Collections.Generic.IEnumerable<TKey> System.Collections.Generic.IReadOnlyDictionary<TKey,TValue>.Keys { get { throw null; } }
- System.Collections.Generic.IEnumerable<TValue> System.Collections.Generic.IReadOnlyDictionary<TKey,TValue>.Values { get { throw null; } }
- bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
- object System.Collections.ICollection.SyncRoot { get { throw null; } }
- bool System.Collections.IDictionary.IsFixedSize { get { throw null; } }
- bool System.Collections.IDictionary.IsReadOnly { get { throw null; } }
- object System.Collections.IDictionary.this[object key] { get { throw null; } set { } }
- System.Collections.ICollection System.Collections.IDictionary.Keys { get { throw null; } }
- System.Collections.ICollection System.Collections.IDictionary.Values { get { throw null; } }
- public System.Collections.Generic.Dictionary<TKey, TValue>.ValueCollection Values { get { throw null; } }
- public void Add(TKey key, TValue value) { }
- public void Clear() { }
- public bool ContainsKey(TKey key) { throw null; }
- public bool ContainsValue(TValue value) { throw null; }
- public System.Collections.Generic.Dictionary<TKey, TValue>.Enumerator GetEnumerator() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public virtual void OnDeserialization(object sender) { }
- public bool Remove(TKey key) { throw null; }
- void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.Add(System.Collections.Generic.KeyValuePair<TKey, TValue> keyValuePair) { }
- bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.Contains(System.Collections.Generic.KeyValuePair<TKey, TValue> keyValuePair) { throw null; }
- void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.CopyTo(System.Collections.Generic.KeyValuePair<TKey, TValue>[] array, int index) { }
- bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.Remove(System.Collections.Generic.KeyValuePair<TKey, TValue> keyValuePair) { throw null; }
- System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<TKey, TValue>> System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey,TValue>>.GetEnumerator() { throw null; }
- void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
- void System.Collections.IDictionary.Add(object key, object value) { }
- bool System.Collections.IDictionary.Contains(object key) { throw null; }
- System.Collections.IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator() { throw null; }
- void System.Collections.IDictionary.Remove(object key) { }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- public bool TryGetValue(TKey key, out TValue value) { value = default(TValue); throw null; }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Enumerator : System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.IDictionaryEnumerator, System.Collections.IEnumerator, System.IDisposable
- {
- public System.Collections.Generic.KeyValuePair<TKey, TValue> Current { get { throw null; } }
- System.Collections.DictionaryEntry System.Collections.IDictionaryEnumerator.Entry { get { throw null; } }
- object System.Collections.IDictionaryEnumerator.Key { get { throw null; } }
- object System.Collections.IDictionaryEnumerator.Value { get { throw null; } }
- object System.Collections.IEnumerator.Current { get { throw null; } }
- public void Dispose() { }
- public bool MoveNext() { throw null; }
- void System.Collections.IEnumerator.Reset() { }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("Count = {Count}")]
- public sealed partial class KeyCollection : System.Collections.Generic.ICollection<TKey>, System.Collections.Generic.IEnumerable<TKey>, System.Collections.Generic.IReadOnlyCollection<TKey>, System.Collections.ICollection, System.Collections.IEnumerable
- {
- public KeyCollection(System.Collections.Generic.Dictionary<TKey, TValue> dictionary) { }
- public int Count { get { throw null; } }
- bool System.Collections.Generic.ICollection<TKey>.IsReadOnly { get { throw null; } }
- bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
- object System.Collections.ICollection.SyncRoot { get { throw null; } }
- public void CopyTo(TKey[] array, int index) { }
- public System.Collections.Generic.Dictionary<TKey, TValue>.KeyCollection.Enumerator GetEnumerator() { throw null; }
- void System.Collections.Generic.ICollection<TKey>.Add(TKey item) { }
- void System.Collections.Generic.ICollection<TKey>.Clear() { }
- bool System.Collections.Generic.ICollection<TKey>.Contains(TKey item) { throw null; }
- bool System.Collections.Generic.ICollection<TKey>.Remove(TKey item) { throw null; }
- System.Collections.Generic.IEnumerator<TKey> System.Collections.Generic.IEnumerable<TKey>.GetEnumerator() { throw null; }
- void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Enumerator : System.Collections.Generic.IEnumerator<TKey>, System.Collections.IEnumerator, System.IDisposable
- {
- public TKey Current { get { throw null; } }
- object System.Collections.IEnumerator.Current { get { throw null; } }
- public void Dispose() { }
- public bool MoveNext() { throw null; }
- void System.Collections.IEnumerator.Reset() { }
- }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("Count = {Count}")]
- public sealed partial class ValueCollection : System.Collections.Generic.ICollection<TValue>, System.Collections.Generic.IEnumerable<TValue>, System.Collections.Generic.IReadOnlyCollection<TValue>, System.Collections.ICollection, System.Collections.IEnumerable
- {
- public ValueCollection(System.Collections.Generic.Dictionary<TKey, TValue> dictionary) { }
- public int Count { get { throw null; } }
- bool System.Collections.Generic.ICollection<TValue>.IsReadOnly { get { throw null; } }
- bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
- object System.Collections.ICollection.SyncRoot { get { throw null; } }
- public void CopyTo(TValue[] array, int index) { }
- public System.Collections.Generic.Dictionary<TKey, TValue>.ValueCollection.Enumerator GetEnumerator() { throw null; }
- void System.Collections.Generic.ICollection<TValue>.Add(TValue item) { }
- void System.Collections.Generic.ICollection<TValue>.Clear() { }
- bool System.Collections.Generic.ICollection<TValue>.Contains(TValue item) { throw null; }
- bool System.Collections.Generic.ICollection<TValue>.Remove(TValue item) { throw null; }
- System.Collections.Generic.IEnumerator<TValue> System.Collections.Generic.IEnumerable<TValue>.GetEnumerator() { throw null; }
- void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Enumerator : System.Collections.Generic.IEnumerator<TValue>, System.Collections.IEnumerator, System.IDisposable
- {
- public TValue Current { get { throw null; } }
- object System.Collections.IEnumerator.Current { get { throw null; } }
- public void Dispose() { }
- public bool MoveNext() { throw null; }
- void System.Collections.IEnumerator.Reset() { }
- }
- }
- }
- public abstract partial class EqualityComparer<T> : System.Collections.Generic.IEqualityComparer<T>, System.Collections.IEqualityComparer
- {
- protected EqualityComparer() { }
- public static System.Collections.Generic.EqualityComparer<T> Default { get { throw null; } }
- public abstract bool Equals(T x, T y);
- public abstract int GetHashCode(T obj);
- bool System.Collections.IEqualityComparer.Equals(object x, object y) { throw null; }
- int System.Collections.IEqualityComparer.GetHashCode(object obj) { throw null; }
- }
- public partial interface ICollection<T> : System.Collections.Generic.IEnumerable<T>, System.Collections.IEnumerable
- {
- int Count { get; }
- bool IsReadOnly { get; }
- void Add(T item);
- void Clear();
- bool Contains(T item);
- void CopyTo(T[] array, int arrayIndex);
- bool Remove(T item);
- }
- public partial interface IComparer<in T>
- {
- int Compare(T x, T y);
- }
- public partial interface IDictionary<TKey, TValue> : System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.IEnumerable
- {
- TValue this[TKey key] { get; set; }
- System.Collections.Generic.ICollection<TKey> Keys { get; }
- System.Collections.Generic.ICollection<TValue> Values { get; }
- void Add(TKey key, TValue value);
- bool ContainsKey(TKey key);
- bool Remove(TKey key);
- bool TryGetValue(TKey key, out TValue value);
- }
- public partial interface IEnumerable<out T> : System.Collections.IEnumerable
- {
- new System.Collections.Generic.IEnumerator<T> GetEnumerator();
- }
- public partial interface IEnumerator<out T> : System.Collections.IEnumerator, System.IDisposable
- {
- new T Current { get; }
- }
- public partial interface IEqualityComparer<in T>
- {
- bool Equals(T x, T y);
- int GetHashCode(T obj);
- }
- public partial interface IList<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.IEnumerable
- {
- T this[int index] { get; set; }
- int IndexOf(T item);
- void Insert(int index, T item);
- void RemoveAt(int index);
- }
- public partial interface IReadOnlyCollection<out T> : System.Collections.Generic.IEnumerable<T>, System.Collections.IEnumerable
- {
- int Count { get; }
- }
- public partial interface IReadOnlyDictionary<TKey, TValue> : System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.Generic.IReadOnlyCollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.IEnumerable
- {
- TValue this[TKey key] { get; }
- System.Collections.Generic.IEnumerable<TKey> Keys { get; }
- System.Collections.Generic.IEnumerable<TValue> Values { get; }
- bool ContainsKey(TKey key);
- bool TryGetValue(TKey key, out TValue value);
- }
- public partial interface IReadOnlyList<out T> : System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.IEnumerable
- {
- T this[int index] { get; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class KeyNotFoundException : System.SystemException, System.Runtime.Serialization.ISerializable
- {
- public KeyNotFoundException() { }
- public KeyNotFoundException(string message) { }
- public KeyNotFoundException(string message, System.Exception innerException) { }
- protected KeyNotFoundException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct KeyValuePair<TKey, TValue>
- {
- public KeyValuePair(TKey key, TValue value) { throw null;}
- public TKey Key { get { throw null; } }
- public TValue Value { get { throw null; } }
- public override string ToString() { throw null; }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("Count = {Count}")]
- public partial class List<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList
- {
- public List() { }
- public List(System.Collections.Generic.IEnumerable<T> collection) { }
- public List(int capacity) { }
- public int Capacity { get { throw null; } set { } }
- public int Count { get { throw null; } }
- public T this[int index] { get { throw null; } set { } }
- bool System.Collections.Generic.ICollection<T>.IsReadOnly { get { throw null; } }
- bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
- object System.Collections.ICollection.SyncRoot { get { throw null; } }
- bool System.Collections.IList.IsFixedSize { get { throw null; } }
- bool System.Collections.IList.IsReadOnly { get { throw null; } }
- object System.Collections.IList.this[int index] { get { throw null; } set { } }
- public void Add(T item) { }
- public void AddRange(System.Collections.Generic.IEnumerable<T> collection) { }
- public System.Collections.ObjectModel.ReadOnlyCollection<T> AsReadOnly() { throw null; }
- public int BinarySearch(T item) { throw null; }
- public int BinarySearch(T item, System.Collections.Generic.IComparer<T> comparer) { throw null; }
- public int BinarySearch(int index, int count, T item, System.Collections.Generic.IComparer<T> comparer) { throw null; }
- public void Clear() { }
- public bool Contains(T item) { throw null; }
- public System.Collections.Generic.List<TOutput> ConvertAll<TOutput>(System.Converter<T, TOutput> converter) { throw null; }
- public void CopyTo(T[] array) { }
- public void CopyTo(T[] array, int arrayIndex) { }
- public void CopyTo(int index, T[] array, int arrayIndex, int count) { }
- public bool Exists(System.Predicate<T> match) { throw null; }
- public T Find(System.Predicate<T> match) { throw null; }
- public System.Collections.Generic.List<T> FindAll(System.Predicate<T> match) { throw null; }
- public int FindIndex(int startIndex, int count, System.Predicate<T> match) { throw null; }
- public int FindIndex(int startIndex, System.Predicate<T> match) { throw null; }
- public int FindIndex(System.Predicate<T> match) { throw null; }
- public T FindLast(System.Predicate<T> match) { throw null; }
- public int FindLastIndex(int startIndex, int count, System.Predicate<T> match) { throw null; }
- public int FindLastIndex(int startIndex, System.Predicate<T> match) { throw null; }
- public int FindLastIndex(System.Predicate<T> match) { throw null; }
- public void ForEach(System.Action<T> action) { }
- public System.Collections.Generic.List<T>.Enumerator GetEnumerator() { throw null; }
- public System.Collections.Generic.List<T> GetRange(int index, int count) { throw null; }
- public int IndexOf(T item) { throw null; }
- public int IndexOf(T item, int index) { throw null; }
- public int IndexOf(T item, int index, int count) { throw null; }
- public void Insert(int index, T item) { }
- public void InsertRange(int index, System.Collections.Generic.IEnumerable<T> collection) { }
- public int LastIndexOf(T item) { throw null; }
- public int LastIndexOf(T item, int index) { throw null; }
- public int LastIndexOf(T item, int index, int count) { throw null; }
- public bool Remove(T item) { throw null; }
- public int RemoveAll(System.Predicate<T> match) { throw null; }
- public void RemoveAt(int index) { }
- public void RemoveRange(int index, int count) { }
- public void Reverse() { }
- public void Reverse(int index, int count) { }
- public void Sort() { }
- public void Sort(System.Collections.Generic.IComparer<T> comparer) { }
- public void Sort(System.Comparison<T> comparison) { }
- public void Sort(int index, int count, System.Collections.Generic.IComparer<T> comparer) { }
- System.Collections.Generic.IEnumerator<T> System.Collections.Generic.IEnumerable<T>.GetEnumerator() { throw null; }
- void System.Collections.ICollection.CopyTo(System.Array array, int arrayIndex) { }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- int System.Collections.IList.Add(object item) { throw null; }
- bool System.Collections.IList.Contains(object item) { throw null; }
- int System.Collections.IList.IndexOf(object item) { throw null; }
- void System.Collections.IList.Insert(int index, object item) { }
- void System.Collections.IList.Remove(object item) { }
- public T[] ToArray() { throw null; }
- public void TrimExcess() { }
- public bool TrueForAll(System.Predicate<T> match) { throw null; }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Enumerator : System.Collections.Generic.IEnumerator<T>, System.Collections.IEnumerator, System.IDisposable
- {
- public T Current { get { throw null; } }
- object System.Collections.IEnumerator.Current { get { throw null; } }
- public void Dispose() { }
- public bool MoveNext() { throw null; }
- void System.Collections.IEnumerator.Reset() { }
- }
- }
-}
-namespace System.Collections.ObjectModel
-{
- [System.Diagnostics.DebuggerDisplayAttribute("Count = {Count}")]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public partial class Collection<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList
- {
- public Collection() { }
- public Collection(System.Collections.Generic.IList<T> list) { }
- public int Count { get { throw null; } }
- public T this[int index] { get { throw null; } set { } }
- protected System.Collections.Generic.IList<T> Items { get { throw null; } }
- bool System.Collections.Generic.ICollection<T>.IsReadOnly { get { throw null; } }
- bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
- object System.Collections.ICollection.SyncRoot { get { throw null; } }
- bool System.Collections.IList.IsFixedSize { get { throw null; } }
- bool System.Collections.IList.IsReadOnly { get { throw null; } }
- object System.Collections.IList.this[int index] { get { throw null; } set { } }
- public void Add(T item) { }
- public void Clear() { }
- protected virtual void ClearItems() { }
- public bool Contains(T item) { throw null; }
- public void CopyTo(T[] array, int index) { }
- public System.Collections.Generic.IEnumerator<T> GetEnumerator() { throw null; }
- public int IndexOf(T item) { throw null; }
- public void Insert(int index, T item) { }
- protected virtual void InsertItem(int index, T item) { }
- public bool Remove(T item) { throw null; }
- public void RemoveAt(int index) { }
- protected virtual void RemoveItem(int index) { }
- protected virtual void SetItem(int index, T item) { }
- void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- int System.Collections.IList.Add(object value) { throw null; }
- bool System.Collections.IList.Contains(object value) { throw null; }
- int System.Collections.IList.IndexOf(object value) { throw null; }
- void System.Collections.IList.Insert(int index, object value) { }
- void System.Collections.IList.Remove(object value) { }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("Count = {Count}")]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public abstract partial class KeyedCollection<TKey, TItem> : System.Collections.ObjectModel.Collection<TItem>
- {
- protected KeyedCollection() { }
- protected KeyedCollection(System.Collections.Generic.IEqualityComparer<TKey> comparer) { }
- protected KeyedCollection(System.Collections.Generic.IEqualityComparer<TKey> comparer, int dictionaryCreationThreshold) { }
- public System.Collections.Generic.IEqualityComparer<TKey> Comparer { get { throw null; } }
- protected System.Collections.Generic.IDictionary<TKey, TItem> Dictionary { get { throw null; } }
- public TItem this[TKey key] { get { throw null; } }
- protected void ChangeItemKey(TItem item, TKey newKey) { }
- protected override void ClearItems() { }
- public bool Contains(TKey key) { throw null; }
- protected abstract TKey GetKeyForItem(TItem item);
- protected override void InsertItem(int index, TItem item) { }
- public bool Remove(TKey key) { throw null; }
- protected override void RemoveItem(int index) { }
- protected override void SetItem(int index, TItem item) { }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("Count = {Count}")]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public partial class ReadOnlyCollection<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList
- {
- public ReadOnlyCollection(System.Collections.Generic.IList<T> list) { }
- public int Count { get { throw null; } }
- public T this[int index] { get { throw null; } }
- protected System.Collections.Generic.IList<T> Items { get { throw null; } }
- bool System.Collections.Generic.ICollection<T>.IsReadOnly { get { throw null; } }
- T System.Collections.Generic.IList<T>.this[int index] { get { throw null; } set { } }
- bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
- object System.Collections.ICollection.SyncRoot { get { throw null; } }
- bool System.Collections.IList.IsFixedSize { get { throw null; } }
- bool System.Collections.IList.IsReadOnly { get { throw null; } }
- object System.Collections.IList.this[int index] { get { throw null; } set { } }
- public bool Contains(T value) { throw null; }
- public void CopyTo(T[] array, int index) { }
- public System.Collections.Generic.IEnumerator<T> GetEnumerator() { throw null; }
- public int IndexOf(T value) { throw null; }
- void System.Collections.Generic.ICollection<T>.Add(T value) { }
- void System.Collections.Generic.ICollection<T>.Clear() { }
- bool System.Collections.Generic.ICollection<T>.Remove(T value) { throw null; }
- void System.Collections.Generic.IList<T>.Insert(int index, T value) { }
- void System.Collections.Generic.IList<T>.RemoveAt(int index) { }
- void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- int System.Collections.IList.Add(object value) { throw null; }
- void System.Collections.IList.Clear() { }
- bool System.Collections.IList.Contains(object value) { throw null; }
- int System.Collections.IList.IndexOf(object value) { throw null; }
- void System.Collections.IList.Insert(int index, object value) { }
- void System.Collections.IList.Remove(object value) { }
- void System.Collections.IList.RemoveAt(int index) { }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("Count = {Count}")]
- public partial class ReadOnlyDictionary<TKey, TValue> : System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.Generic.IDictionary<TKey, TValue>, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.Generic.IReadOnlyCollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>, System.Collections.Generic.IReadOnlyDictionary<TKey, TValue>, System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable
- {
- public ReadOnlyDictionary(System.Collections.Generic.IDictionary<TKey, TValue> dictionary) { }
- public int Count { get { throw null; } }
- protected System.Collections.Generic.IDictionary<TKey, TValue> Dictionary { get { throw null; } }
- public TValue this[TKey key] { get { throw null; } }
- public System.Collections.ObjectModel.ReadOnlyDictionary<TKey, TValue>.KeyCollection Keys { get { throw null; } }
- bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.IsReadOnly { get { throw null; } }
- TValue System.Collections.Generic.IDictionary<TKey,TValue>.this[TKey key] { get { throw null; } set { } }
- System.Collections.Generic.ICollection<TKey> System.Collections.Generic.IDictionary<TKey,TValue>.Keys { get { throw null; } }
- System.Collections.Generic.ICollection<TValue> System.Collections.Generic.IDictionary<TKey,TValue>.Values { get { throw null; } }
- System.Collections.Generic.IEnumerable<TKey> System.Collections.Generic.IReadOnlyDictionary<TKey,TValue>.Keys { get { throw null; } }
- System.Collections.Generic.IEnumerable<TValue> System.Collections.Generic.IReadOnlyDictionary<TKey,TValue>.Values { get { throw null; } }
- bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
- object System.Collections.ICollection.SyncRoot { get { throw null; } }
- bool System.Collections.IDictionary.IsFixedSize { get { throw null; } }
- bool System.Collections.IDictionary.IsReadOnly { get { throw null; } }
- object System.Collections.IDictionary.this[object key] { get { throw null; } set { } }
- System.Collections.ICollection System.Collections.IDictionary.Keys { get { throw null; } }
- System.Collections.ICollection System.Collections.IDictionary.Values { get { throw null; } }
- public System.Collections.ObjectModel.ReadOnlyDictionary<TKey, TValue>.ValueCollection Values { get { throw null; } }
- public bool ContainsKey(TKey key) { throw null; }
- public System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<TKey, TValue>> GetEnumerator() { throw null; }
- void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.Add(System.Collections.Generic.KeyValuePair<TKey, TValue> item) { }
- void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.Clear() { }
- bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.Contains(System.Collections.Generic.KeyValuePair<TKey, TValue> item) { throw null; }
- void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.CopyTo(System.Collections.Generic.KeyValuePair<TKey, TValue>[] array, int arrayIndex) { }
- bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey,TValue>>.Remove(System.Collections.Generic.KeyValuePair<TKey, TValue> item) { throw null; }
- void System.Collections.Generic.IDictionary<TKey,TValue>.Add(TKey key, TValue value) { }
- bool System.Collections.Generic.IDictionary<TKey,TValue>.Remove(TKey key) { throw null; }
- void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
- void System.Collections.IDictionary.Add(object key, object value) { }
- void System.Collections.IDictionary.Clear() { }
- bool System.Collections.IDictionary.Contains(object key) { throw null; }
- System.Collections.IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator() { throw null; }
- void System.Collections.IDictionary.Remove(object key) { }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- public bool TryGetValue(TKey key, out TValue value) { value = default(TValue); throw null; }
- [System.Diagnostics.DebuggerDisplayAttribute("Count = {Count}")]
- public sealed partial class KeyCollection : System.Collections.Generic.ICollection<TKey>, System.Collections.Generic.IEnumerable<TKey>, System.Collections.Generic.IReadOnlyCollection<TKey>, System.Collections.ICollection, System.Collections.IEnumerable
- {
- internal KeyCollection() { }
- public int Count { get { throw null; } }
- bool System.Collections.Generic.ICollection<TKey>.IsReadOnly { get { throw null; } }
- bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
- object System.Collections.ICollection.SyncRoot { get { throw null; } }
- public void CopyTo(TKey[] array, int arrayIndex) { }
- public System.Collections.Generic.IEnumerator<TKey> GetEnumerator() { throw null; }
- void System.Collections.Generic.ICollection<TKey>.Add(TKey item) { }
- void System.Collections.Generic.ICollection<TKey>.Clear() { }
- bool System.Collections.Generic.ICollection<TKey>.Contains(TKey item) { throw null; }
- bool System.Collections.Generic.ICollection<TKey>.Remove(TKey item) { throw null; }
- void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("Count = {Count}")]
- public sealed partial class ValueCollection : System.Collections.Generic.ICollection<TValue>, System.Collections.Generic.IEnumerable<TValue>, System.Collections.Generic.IReadOnlyCollection<TValue>, System.Collections.ICollection, System.Collections.IEnumerable
- {
- internal ValueCollection() { }
- public int Count { get { throw null; } }
- bool System.Collections.Generic.ICollection<TValue>.IsReadOnly { get { throw null; } }
- bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
- object System.Collections.ICollection.SyncRoot { get { throw null; } }
- public void CopyTo(TValue[] array, int arrayIndex) { }
- public System.Collections.Generic.IEnumerator<TValue> GetEnumerator() { throw null; }
- void System.Collections.Generic.ICollection<TValue>.Add(TValue item) { }
- void System.Collections.Generic.ICollection<TValue>.Clear() { }
- bool System.Collections.Generic.ICollection<TValue>.Contains(TValue item) { throw null; }
- bool System.Collections.Generic.ICollection<TValue>.Remove(TValue item) { throw null; }
- void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- }
- }
-}
-namespace System.Configuration.Assemblies
-{
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum AssemblyHashAlgorithm
- {
- MD5 = 32771,
- None = 0,
- SHA1 = 32772,
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- SHA256 = 32780,
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- SHA384 = 32781,
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- SHA512 = 32782,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum AssemblyVersionCompatibility
- {
- SameMachine = 1,
- SameProcess = 2,
- SameDomain = 3,
- }
-}
-namespace System.Diagnostics
-{
- [System.AttributeUsageAttribute((System.AttributeTargets)(68), AllowMultiple=true)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ConditionalAttribute : System.Attribute
- {
- public ConditionalAttribute(string conditionString) { }
- public string ConditionString { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(3), AllowMultiple=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DebuggableAttribute : System.Attribute
- {
- public DebuggableAttribute(bool isJITTrackingEnabled, bool isJITOptimizerDisabled) { }
- public DebuggableAttribute(System.Diagnostics.DebuggableAttribute.DebuggingModes modes) { }
- public System.Diagnostics.DebuggableAttribute.DebuggingModes DebuggingFlags { get { throw null; } }
- public bool IsJITOptimizerDisabled { get { throw null; } }
- public bool IsJITTrackingEnabled { get { throw null; } }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum DebuggingModes
- {
- Default = 1,
- DisableOptimizations = 256,
- EnableEditAndContinue = 4,
- IgnoreSymbolStoreSequencePoints = 2,
- None = 0,
- }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class Debugger
- {
- public static readonly string DefaultCategory;
- [System.ObsoleteAttribute("Do not create instances of the Debugger class. Call the static methods directly on this type instead", true)]
- public Debugger() { }
- public static bool IsAttached { [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Break() { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static bool IsLogging() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool Launch() { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static void Log(int level, string category, string message) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public static void NotifyOfCrossThreadDependency() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(384), AllowMultiple=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DebuggerBrowsableAttribute : System.Attribute
- {
- public DebuggerBrowsableAttribute(System.Diagnostics.DebuggerBrowsableState state) { }
- public System.Diagnostics.DebuggerBrowsableState State { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum DebuggerBrowsableState
- {
- Collapsed = 2,
- Never = 0,
- RootHidden = 3,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(4509), AllowMultiple=true)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DebuggerDisplayAttribute : System.Attribute
- {
- public DebuggerDisplayAttribute(string value) { }
- public string Name { get { throw null; } set { } }
- public System.Type Target { get { throw null; } set { } }
- public string TargetTypeName { get { throw null; } set { } }
- public string Type { get { throw null; } set { } }
- public string Value { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(224), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DebuggerHiddenAttribute : System.Attribute
- {
- public DebuggerHiddenAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(236), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DebuggerNonUserCodeAttribute : System.Attribute
- {
- public DebuggerNonUserCodeAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(108), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DebuggerStepThroughAttribute : System.Attribute
- {
- public DebuggerStepThroughAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(13), AllowMultiple=true)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DebuggerTypeProxyAttribute : System.Attribute
- {
- public DebuggerTypeProxyAttribute(string typeName) { }
- public DebuggerTypeProxyAttribute(System.Type type) { }
- public string ProxyTypeName { get { throw null; } }
- public System.Type Target { get { throw null; } set { } }
- public string TargetTypeName { get { throw null; } set { } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class StackFrame
- {
- public const int OFFSET_UNKNOWN = -1;
- [System.Security.SecuritySafeCriticalAttribute]
- public StackFrame() { }
- [System.Security.SecurityCriticalAttribute]
- public StackFrame(bool fNeedFileInfo) { }
- public StackFrame(int skipFrames) { }
- [System.Security.SecurityCriticalAttribute]
- public StackFrame(int skipFrames, bool fNeedFileInfo) { }
- public StackFrame(string fileName, int lineNumber) { }
- public StackFrame(string fileName, int lineNumber, int colNumber) { }
- public virtual int GetFileColumnNumber() { throw null; }
- public virtual int GetFileLineNumber() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public virtual string GetFileName() { throw null; }
- public virtual int GetILOffset() { throw null; }
- public virtual System.Reflection.MethodBase GetMethod() { throw null; }
- public virtual int GetNativeOffset() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class StackTrace
- {
- public const int METHODS_TO_SKIP = 0;
- [System.Security.SecuritySafeCriticalAttribute]
- public StackTrace() { }
- [System.Security.SecurityCriticalAttribute]
- public StackTrace(bool fNeedFileInfo) { }
- public StackTrace(System.Diagnostics.StackFrame frame) { }
- public StackTrace(System.Exception e) { }
- [System.Security.SecurityCriticalAttribute]
- public StackTrace(System.Exception e, bool fNeedFileInfo) { }
- [System.Security.SecurityCriticalAttribute]
- public StackTrace(System.Exception e, int skipFrames) { }
- [System.Security.SecurityCriticalAttribute]
- public StackTrace(System.Exception e, int skipFrames, bool fNeedFileInfo) { }
- [System.Security.SecurityCriticalAttribute]
- public StackTrace(int skipFrames) { }
- [System.Security.SecurityCriticalAttribute]
- public StackTrace(int skipFrames, bool fNeedFileInfo) { }
- [System.ObsoleteAttribute("This constructor has been deprecated. Please use a constructor that does not require a Thread parameter. http://go.microsoft.com/fwlink/?linkid=14202")]
- [System.Security.SecurityCriticalAttribute]
- public StackTrace(System.Threading.Thread targetThread, bool needFileInfo) { }
- public virtual int FrameCount { get { throw null; } }
- public virtual System.Diagnostics.StackFrame GetFrame(int index) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Diagnostics.StackFrame[] GetFrames() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- }
-}
-namespace System.Diagnostics.CodeAnalysis
-{
- [System.AttributeUsageAttribute((System.AttributeTargets)(32767), Inherited=false, AllowMultiple=true)]
- [System.Diagnostics.ConditionalAttribute("CODE_ANALYSIS")]
- public sealed partial class SuppressMessageAttribute : System.Attribute
- {
- public SuppressMessageAttribute(string category, string checkId) { }
- public string Category { get { throw null; } }
- public string CheckId { get { throw null; } }
- public string Justification { get { throw null; } set { } }
- public string MessageId { get { throw null; } set { } }
- public string Scope { get { throw null; } set { } }
- public string Target { get { throw null; } set { } }
- }
-}
-namespace System.Diagnostics.Contracts
-{
- public static partial class Contract
- {
- public static event System.EventHandler<System.Diagnostics.Contracts.ContractFailedEventArgs> ContractFailed { add { } remove { } }
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- [System.Diagnostics.ConditionalAttribute("DEBUG")]
- public static void Assert(bool condition) { }
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- [System.Diagnostics.ConditionalAttribute("DEBUG")]
- public static void Assert(bool condition, string userMessage) { }
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- [System.Diagnostics.ConditionalAttribute("DEBUG")]
- public static void Assume(bool condition) { }
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- [System.Diagnostics.ConditionalAttribute("DEBUG")]
- public static void Assume(bool condition, string userMessage) { }
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public static void EndContractBlock() { }
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public static void Ensures(bool condition) { }
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public static void Ensures(bool condition, string userMessage) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification="Exception type used in tools.")]
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public static void EnsuresOnThrow<TException>(bool condition) where TException : System.Exception { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification="Exception type used in tools.")]
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public static void EnsuresOnThrow<TException>(bool condition, string userMessage) where TException : System.Exception { }
- public static bool Exists(int fromInclusive, int toExclusive, System.Predicate<int> predicate) { throw null; }
- public static bool Exists<T>(System.Collections.Generic.IEnumerable<T> collection, System.Predicate<T> predicate) { throw null; }
- public static bool ForAll(int fromInclusive, int toExclusive, System.Predicate<int> predicate) { throw null; }
- public static bool ForAll<T>(System.Collections.Generic.IEnumerable<T> collection, System.Predicate<T> predicate) { throw null; }
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public static void Invariant(bool condition) { }
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public static void Invariant(bool condition, string userMessage) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId="value")]
- public static T OldValue<T>(T value) { throw null; }
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public static void Requires(bool condition) { }
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public static void Requires(bool condition, string userMessage) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId="condition")]
- public static void Requires<TException>(bool condition) where TException : System.Exception { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId="condition")]
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId="userMessage")]
- public static void Requires<TException>(bool condition, string userMessage) where TException : System.Exception { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification="Not intended to be called at runtime.")]
- public static T Result<T>() { throw null; }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId="0#", Justification="Not intended to be called at runtime.")]
- public static T ValueAtReturn<T>(out T value) { value = default(T); throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64), AllowMultiple=false)]
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public sealed partial class ContractAbbreviatorAttribute : System.Attribute
- {
- public ContractAbbreviatorAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64), AllowMultiple=false)]
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public sealed partial class ContractArgumentValidatorAttribute : System.Attribute
- {
- public ContractArgumentValidatorAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(5124), AllowMultiple=false, Inherited=false)]
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- [System.Diagnostics.ConditionalAttribute("DEBUG")]
- public sealed partial class ContractClassAttribute : System.Attribute
- {
- public ContractClassAttribute(System.Type typeContainingContracts) { }
- public System.Type TypeContainingContracts { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(4), AllowMultiple=false, Inherited=false)]
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public sealed partial class ContractClassForAttribute : System.Attribute
- {
- public ContractClassForAttribute(System.Type typeContractsAreFor) { }
- public System.Type TypeContractsAreFor { get { throw null; } }
- }
- public sealed partial class ContractFailedEventArgs : System.EventArgs
- {
- public ContractFailedEventArgs(System.Diagnostics.Contracts.ContractFailureKind failureKind, string message, string condition, System.Exception originalException) { }
- public string Condition { get { throw null; } }
- public System.Diagnostics.Contracts.ContractFailureKind FailureKind { get { throw null; } }
- public bool Handled { get { throw null; } }
- public string Message { get { throw null; } }
- public System.Exception OriginalException { get { throw null; } }
- public bool Unwind { get { throw null; } }
- [System.Security.SecurityCriticalAttribute]
- public void SetHandled() { }
- [System.Security.SecurityCriticalAttribute]
- public void SetUnwind() { }
- }
- public enum ContractFailureKind
- {
- Assert = 4,
- Assume = 5,
- Invariant = 3,
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId="Postcondition")]
- Postcondition = 1,
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId="Postcondition")]
- PostconditionOnException = 2,
- Precondition = 0,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64), AllowMultiple=false, Inherited=false)]
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public sealed partial class ContractInvariantMethodAttribute : System.Attribute
- {
- public ContractInvariantMethodAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(32767), AllowMultiple=true, Inherited=false)]
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public sealed partial class ContractOptionAttribute : System.Attribute
- {
- public ContractOptionAttribute(string category, string setting, bool enabled) { }
- public ContractOptionAttribute(string category, string setting, string value) { }
- public string Category { get { throw null; } }
- public bool Enabled { get { throw null; } }
- public string Setting { get { throw null; } }
- public string Value { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(256))]
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", Justification="Thank you very much, but we like the names we've defined for the accessors")]
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public sealed partial class ContractPublicPropertyNameAttribute : System.Attribute
- {
- public ContractPublicPropertyNameAttribute(string name) { }
- public string Name { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1))]
- public sealed partial class ContractReferenceAssemblyAttribute : System.Attribute
- {
- public ContractReferenceAssemblyAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(192), AllowMultiple=false, Inherited=true)]
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public sealed partial class ContractRuntimeIgnoredAttribute : System.Attribute
- {
- public ContractRuntimeIgnoredAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(237))]
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public sealed partial class ContractVerificationAttribute : System.Attribute
- {
- public ContractVerificationAttribute(bool value) { }
- public bool Value { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(6884), AllowMultiple=false, Inherited=true)]
- [System.Diagnostics.ConditionalAttribute("CONTRACTS_FULL")]
- public sealed partial class PureAttribute : System.Attribute
- {
- public PureAttribute() { }
- }
-}
-namespace System.Diagnostics.Contracts.Internal
-{
- [System.ObsoleteAttribute("Use the ContractHelper class in the System.Runtime.CompilerServices namespace instead.")]
- public static partial class ContractHelper
- {
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")]
- [System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static string RaiseContractFailedEvent(System.Diagnostics.Contracts.ContractFailureKind failureKind, string userMessage, string conditionText, System.Exception innerException) { throw null; }
- [System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static void TriggerFailure(System.Diagnostics.Contracts.ContractFailureKind kind, string displayMessage, string userMessage, string conditionText, System.Exception innerException) { }
- }
-}
-namespace System.Diagnostics.SymbolStore
-{
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface ISymbolDocumentWriter
- {
- void SetCheckSum(System.Guid algorithmId, byte[] checkSum);
- void SetSource(byte[] source);
- }
-}
-namespace System.Diagnostics.Tracing
-{
- [System.FlagsAttribute]
- public enum EventActivityOptions
- {
- Detachable = 8,
- Disable = 2,
- None = 0,
- Recursive = 4,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64))]
- public sealed partial class EventAttribute : System.Attribute
- {
- public EventAttribute(int eventId) { }
- public System.Diagnostics.Tracing.EventActivityOptions ActivityOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
- public System.Diagnostics.Tracing.EventChannel Channel { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
- public int EventId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
- public System.Diagnostics.Tracing.EventKeywords Keywords { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
- public System.Diagnostics.Tracing.EventLevel Level { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
- public string Message { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
- public System.Diagnostics.Tracing.EventOpcode Opcode { get { throw null; } set { } }
- public System.Diagnostics.Tracing.EventTags Tags { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
- public System.Diagnostics.Tracing.EventTask Task { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
- public byte Version { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
- }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1028:EnumStorageShouldBeInt32", Justification="Backwards compatibility")]
- public enum EventChannel : byte
- {
- Admin = (byte)16,
- Analytic = (byte)18,
- Debug = (byte)19,
- None = (byte)0,
- Operational = (byte)17,
- }
- public enum EventCommand
- {
- Disable = -3,
- Enable = -2,
- SendManifest = -1,
- Update = 0,
- }
- public partial class EventCommandEventArgs : System.EventArgs
- {
- internal EventCommandEventArgs() { }
- public System.Collections.Generic.IDictionary<string, string> Arguments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
- public System.Diagnostics.Tracing.EventCommand Command { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
- public bool DisableEvent(int eventId) { throw null; }
- public bool EnableEvent(int eventId) { throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(12), Inherited=false)]
- public partial class EventDataAttribute : System.Attribute
- {
- public EventDataAttribute() { }
- public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(128))]
- public partial class EventFieldAttribute : System.Attribute
- {
- public EventFieldAttribute() { }
- public System.Diagnostics.Tracing.EventFieldFormat Format { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
- public System.Diagnostics.Tracing.EventFieldTags Tags { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
- }
- public enum EventFieldFormat
- {
- Boolean = 3,
- Default = 0,
- Hexadecimal = 4,
- HResult = 15,
- Json = 12,
- String = 2,
- Xml = 11,
- }
- [System.FlagsAttribute]
- public enum EventFieldTags
- {
- None = 0,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(128))]
- public partial class EventIgnoreAttribute : System.Attribute
- {
- public EventIgnoreAttribute() { }
- }
- [System.FlagsAttribute]
- public enum EventKeywords : long
- {
- All = (long)-1,
- AuditFailure = (long)4503599627370496,
- AuditSuccess = (long)9007199254740992,
- CorrelationHint = (long)4503599627370496,
- EventLogClassic = (long)36028797018963968,
- MicrosoftTelemetry = (long)562949953421312,
- None = (long)0,
- Sqm = (long)2251799813685248,
- WdiContext = (long)562949953421312,
- WdiDiagnostic = (long)1125899906842624,
- }
- public enum EventLevel
- {
- Critical = 1,
- Error = 2,
- Informational = 4,
- LogAlways = 0,
- Verbose = 5,
- Warning = 3,
- }
- public partial class EventListener : System.IDisposable
- {
- public EventListener() { }
- public void DisableEvents(System.Diagnostics.Tracing.EventSource eventSource) { }
- public virtual void Dispose() { }
- public void EnableEvents(System.Diagnostics.Tracing.EventSource eventSource, System.Diagnostics.Tracing.EventLevel level) { }
- public void EnableEvents(System.Diagnostics.Tracing.EventSource eventSource, System.Diagnostics.Tracing.EventLevel level, System.Diagnostics.Tracing.EventKeywords matchAnyKeyword) { }
- public void EnableEvents(System.Diagnostics.Tracing.EventSource eventSource, System.Diagnostics.Tracing.EventLevel level, System.Diagnostics.Tracing.EventKeywords matchAnyKeyword, System.Collections.Generic.IDictionary<string, string> arguments) { }
- public static int EventSourceIndex(System.Diagnostics.Tracing.EventSource eventSource) { throw null; }
- protected internal virtual void OnEventSourceCreated(System.Diagnostics.Tracing.EventSource eventSource) { }
- protected internal virtual void OnEventWritten(System.Diagnostics.Tracing.EventWrittenEventArgs eventData) { }
- }
- [System.FlagsAttribute]
- public enum EventManifestOptions
- {
- AllCultures = 2,
- AllowEventSourceOverride = 8,
- None = 0,
- OnlyIfNeededForRegistration = 4,
- Strict = 1,
- }
- public enum EventOpcode
- {
- DataCollectionStart = 3,
- DataCollectionStop = 4,
- Extension = 5,
- Info = 0,
- Receive = 240,
- Reply = 6,
- Resume = 7,
- Send = 9,
- Start = 1,
- Stop = 2,
- Suspend = 8,
- }
- public partial class EventSource : System.IDisposable
- {
- protected EventSource() { }
- protected EventSource(bool throwOnEventWriteErrors) { }
- protected EventSource(System.Diagnostics.Tracing.EventSourceSettings settings) { }
- protected EventSource(System.Diagnostics.Tracing.EventSourceSettings settings, params string[] traits) { }
- public EventSource(string eventSourceName) { }
- public EventSource(string eventSourceName, System.Diagnostics.Tracing.EventSourceSettings config) { }
- public EventSource(string eventSourceName, System.Diagnostics.Tracing.EventSourceSettings config, params string[] traits) { }
- public System.Exception ConstructionException { get { throw null; } }
- public static System.Guid CurrentThreadActivityId { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public System.Guid Guid { get { throw null; } }
- public string Name { get { throw null; } }
- public System.Diagnostics.Tracing.EventSourceSettings Settings { get { throw null; } }
- public event System.EventHandler<System.Diagnostics.Tracing.EventCommandEventArgs> EventCommandExecuted { add { } remove { } }
- public void Dispose() { }
- protected virtual void Dispose(bool disposing) { }
- ~EventSource() { }
- public static string GenerateManifest(System.Type eventSourceType, string assemblyPathToIncludeInManifest) { throw null; }
- public static string GenerateManifest(System.Type eventSourceType, string assemblyPathToIncludeInManifest, System.Diagnostics.Tracing.EventManifestOptions flags) { throw null; }
- public static System.Guid GetGuid(System.Type eventSourceType) { throw null; }
- public static string GetName(System.Type eventSourceType) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Diagnostics.Tracing.EventSource> GetSources() { throw null; }
- public string GetTrait(string key) { throw null; }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- public bool IsEnabled() { throw null; }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- public bool IsEnabled(System.Diagnostics.Tracing.EventLevel level, System.Diagnostics.Tracing.EventKeywords keywords) { throw null; }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- public bool IsEnabled(System.Diagnostics.Tracing.EventLevel level, System.Diagnostics.Tracing.EventKeywords keywords, System.Diagnostics.Tracing.EventChannel channel) { throw null; }
- protected virtual void OnEventCommand(System.Diagnostics.Tracing.EventCommandEventArgs command) { }
- public static void SendCommand(System.Diagnostics.Tracing.EventSource eventSource, System.Diagnostics.Tracing.EventCommand command, System.Collections.Generic.IDictionary<string, string> commandArguments) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void SetCurrentThreadActivityId(System.Guid activityId) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void SetCurrentThreadActivityId(System.Guid activityId, out System.Guid oldActivityThatWillContinue) { oldActivityThatWillContinue = default(System.Guid); }
- public override string ToString() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write(string eventName) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write(string eventName, System.Diagnostics.Tracing.EventSourceOptions options) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write<T>(string eventName, T data) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write<T>(string eventName, System.Diagnostics.Tracing.EventSourceOptions options, T data) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write<T>(string eventName, ref System.Diagnostics.Tracing.EventSourceOptions options, ref T data) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write<T>(string eventName, ref System.Diagnostics.Tracing.EventSourceOptions options, ref System.Guid activityId, ref System.Guid relatedActivityId, ref T data) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, byte[] arg1) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, int arg1) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, int arg1, int arg2) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, int arg1, int arg2, int arg3) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, int arg1, string arg2) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, long arg1) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, long arg1, byte[] arg2) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, long arg1, long arg2) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, long arg1, long arg2, long arg3) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, long arg1, string arg2) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, params object[] args) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, string arg1) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, string arg1, int arg2) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, string arg1, int arg2, int arg3) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, string arg1, long arg2) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, string arg1, string arg2) { }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Concurrency", "CA8001", Justification="This does not need to be correct when racing with other threads")]
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEvent(int eventId, string arg1, string arg2, string arg3) { }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- protected unsafe void WriteEventCore(int eventId, int eventDataCount, System.Diagnostics.Tracing.EventSource.EventData* data) { }
- [System.Security.SecuritySafeCriticalAttribute]
- protected void WriteEventWithRelatedActivityId(int eventId, System.Guid relatedActivityId, params object[] args) { }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- protected unsafe void WriteEventWithRelatedActivityIdCore(int eventId, System.Guid* relatedActivityId, int eventDataCount, System.Diagnostics.Tracing.EventSource.EventData* data) { }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- protected internal partial struct EventData
- {
- public System.IntPtr DataPointer { get { throw null; } set { } }
- public int Size { get { throw null; } set { } }
- }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(4))]
- public sealed partial class EventSourceAttribute : System.Attribute
- {
- public EventSourceAttribute() { }
- public string Guid { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
- public string LocalizationResources { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
- public string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
- }
- public partial class EventSourceException : System.Exception
- {
- public EventSourceException() { }
- public EventSourceException(string message) { }
- public EventSourceException(string message, System.Exception innerException) { }
- protected EventSourceException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct EventSourceOptions
- {
- public System.Diagnostics.Tracing.EventActivityOptions ActivityOptions { get { throw null; } set { } }
- public System.Diagnostics.Tracing.EventKeywords Keywords { get { throw null; } set { } }
- public System.Diagnostics.Tracing.EventLevel Level { get { throw null; } set { } }
- public System.Diagnostics.Tracing.EventOpcode Opcode { get { throw null; } set { } }
- public System.Diagnostics.Tracing.EventTags Tags { get { throw null; } set { } }
- }
- [System.FlagsAttribute]
- public enum EventSourceSettings
- {
- Default = 0,
- EtwManifestEventFormat = 4,
- EtwSelfDescribingEventFormat = 8,
- ThrowOnEventWriteErrors = 1,
- }
- [System.FlagsAttribute]
- public enum EventTags
- {
- None = 0,
- }
- public enum EventTask
- {
- None = 0,
- }
- public partial class EventWrittenEventArgs : System.EventArgs
- {
- internal EventWrittenEventArgs() { }
- public System.Guid ActivityId { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- public System.Diagnostics.Tracing.EventChannel Channel { get { throw null; } }
- public int EventId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
- public string EventName { get { throw null; } }
- public System.Diagnostics.Tracing.EventSource EventSource { get { throw null; } }
- public System.Diagnostics.Tracing.EventKeywords Keywords { get { throw null; } }
- public System.Diagnostics.Tracing.EventLevel Level { get { throw null; } }
- public string Message { get { throw null; } }
- public System.Diagnostics.Tracing.EventOpcode Opcode { get { throw null; } }
- public System.Collections.ObjectModel.ReadOnlyCollection<object> Payload { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
- public System.Collections.ObjectModel.ReadOnlyCollection<string> PayloadNames { get { throw null; } }
- public System.Guid RelatedActivityId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute, System.Security.SecurityCriticalAttribute]get { throw null; } }
- public System.Diagnostics.Tracing.EventTags Tags { get { throw null; } }
- public System.Diagnostics.Tracing.EventTask Task { get { throw null; } }
- public byte Version { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64))]
- public sealed partial class NonEventAttribute : System.Attribute
- {
- public NonEventAttribute() { }
- }
-}
-namespace System.Globalization
-{
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class Calendar : System.ICloneable
- {
- public const int CurrentEra = 0;
- protected Calendar() { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Globalization.CalendarAlgorithmType AlgorithmType { get { throw null; } }
- protected virtual int DaysInYearBeforeMinSupportedYear { get { throw null; } }
- public abstract int[] Eras { get; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public bool IsReadOnly { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.DateTime MaxSupportedDateTime { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.DateTime MinSupportedDateTime { get { throw null; } }
- public virtual int TwoDigitYearMax { get { throw null; } set { } }
- public virtual System.DateTime AddDays(System.DateTime time, int days) { throw null; }
- public virtual System.DateTime AddHours(System.DateTime time, int hours) { throw null; }
- public virtual System.DateTime AddMilliseconds(System.DateTime time, double milliseconds) { throw null; }
- public virtual System.DateTime AddMinutes(System.DateTime time, int minutes) { throw null; }
- public abstract System.DateTime AddMonths(System.DateTime time, int months);
- public virtual System.DateTime AddSeconds(System.DateTime time, int seconds) { throw null; }
- public virtual System.DateTime AddWeeks(System.DateTime time, int weeks) { throw null; }
- public abstract System.DateTime AddYears(System.DateTime time, int years);
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual object Clone() { throw null; }
- public abstract int GetDayOfMonth(System.DateTime time);
- public abstract System.DayOfWeek GetDayOfWeek(System.DateTime time);
- public abstract int GetDayOfYear(System.DateTime time);
- public virtual int GetDaysInMonth(int year, int month) { throw null; }
- public abstract int GetDaysInMonth(int year, int month, int era);
- public virtual int GetDaysInYear(int year) { throw null; }
- public abstract int GetDaysInYear(int year, int era);
- public abstract int GetEra(System.DateTime time);
- public virtual int GetHour(System.DateTime time) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual int GetLeapMonth(int year) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual int GetLeapMonth(int year, int era) { throw null; }
- public virtual double GetMilliseconds(System.DateTime time) { throw null; }
- public virtual int GetMinute(System.DateTime time) { throw null; }
- public abstract int GetMonth(System.DateTime time);
- public virtual int GetMonthsInYear(int year) { throw null; }
- public abstract int GetMonthsInYear(int year, int era);
- public virtual int GetSecond(System.DateTime time) { throw null; }
- public virtual int GetWeekOfYear(System.DateTime time, System.Globalization.CalendarWeekRule rule, System.DayOfWeek firstDayOfWeek) { throw null; }
- public abstract int GetYear(System.DateTime time);
- public virtual bool IsLeapDay(int year, int month, int day) { throw null; }
- public abstract bool IsLeapDay(int year, int month, int day, int era);
- public virtual bool IsLeapMonth(int year, int month) { throw null; }
- public abstract bool IsLeapMonth(int year, int month, int era);
- public virtual bool IsLeapYear(int year) { throw null; }
- public abstract bool IsLeapYear(int year, int era);
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public static System.Globalization.Calendar ReadOnly(System.Globalization.Calendar calendar) { throw null; }
- public virtual System.DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond) { throw null; }
- public abstract System.DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era);
- public virtual int ToFourDigitYear(int year) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum CalendarAlgorithmType
- {
- LunarCalendar = 2,
- LunisolarCalendar = 3,
- SolarCalendar = 1,
- Unknown = 0,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum CalendarWeekRule
- {
- FirstDay = 0,
- FirstFourDayWeek = 2,
- FirstFullWeek = 1,
- }
- public static partial class CharUnicodeInfo
- {
- public static int GetDecimalDigitValue(char ch) { throw null; }
- public static int GetDecimalDigitValue(string s, int index) { throw null; }
- public static int GetDigitValue(char ch) { throw null; }
- public static int GetDigitValue(string s, int index) { throw null; }
- public static double GetNumericValue(char ch) { throw null; }
- public static double GetNumericValue(string s, int index) { throw null; }
- public static System.Globalization.UnicodeCategory GetUnicodeCategory(char ch) { throw null; }
- public static System.Globalization.UnicodeCategory GetUnicodeCategory(string s, int index) { throw null; }
- }
- public partial class ChineseLunisolarCalendar : System.Globalization.EastAsianLunisolarCalendar
- {
- public const int ChineseEra = 1;
- public ChineseLunisolarCalendar() { }
- protected override int DaysInYearBeforeMinSupportedYear { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int[] Eras { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MaxSupportedDateTime { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MinSupportedDateTime { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetEra(System.DateTime time) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class CompareInfo : System.Runtime.Serialization.IDeserializationCallback
- {
- public int LCID { get { throw null; } }
- internal CompareInfo() { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual string Name { get { throw null; } }
- public virtual int Compare(string string1, int offset1, int length1, string string2, int offset2, int length2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual int Compare(string string1, int offset1, int length1, string string2, int offset2, int length2, System.Globalization.CompareOptions options) { throw null; }
- public virtual int Compare(string string1, int offset1, string string2, int offset2) { throw null; }
- public virtual int Compare(string string1, int offset1, string string2, int offset2, System.Globalization.CompareOptions options) { throw null; }
- public virtual int Compare(string string1, string string2) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual int Compare(string string1, string string2, System.Globalization.CompareOptions options) { throw null; }
- public override bool Equals(object value) { throw null; }
- public static System.Globalization.CompareInfo GetCompareInfo(int culture) { throw null; }
- public static System.Globalization.CompareInfo GetCompareInfo(int culture, System.Reflection.Assembly assembly) { throw null; }
- public static System.Globalization.CompareInfo GetCompareInfo(string name) { throw null; }
- public static System.Globalization.CompareInfo GetCompareInfo(string name, System.Reflection.Assembly assembly) { throw null; }
- public override int GetHashCode() { throw null; }
- public virtual int GetHashCode(string source, System.Globalization.CompareOptions options) { throw null; }
- public virtual System.Globalization.SortKey GetSortKey(string source) { throw null; }
- public virtual System.Globalization.SortKey GetSortKey(string source, System.Globalization.CompareOptions options) { throw null; }
- public virtual int IndexOf(string source, char value) { throw null; }
- public virtual int IndexOf(string source, char value, System.Globalization.CompareOptions options) { throw null; }
- public virtual int IndexOf(string source, char value, int startIndex) { throw null; }
- public virtual int IndexOf(string source, char value, int startIndex, System.Globalization.CompareOptions options) { throw null; }
- public virtual int IndexOf(string source, char value, int startIndex, int count) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual int IndexOf(string source, char value, int startIndex, int count, System.Globalization.CompareOptions options) { throw null; }
- public virtual int IndexOf(string source, string value) { throw null; }
- public virtual int IndexOf(string source, string value, System.Globalization.CompareOptions options) { throw null; }
- public virtual int IndexOf(string source, string value, int startIndex) { throw null; }
- public virtual int IndexOf(string source, string value, int startIndex, System.Globalization.CompareOptions options) { throw null; }
- public virtual int IndexOf(string source, string value, int startIndex, int count) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual int IndexOf(string source, string value, int startIndex, int count, System.Globalization.CompareOptions options) { throw null; }
- public virtual bool IsPrefix(string source, string prefix) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual bool IsPrefix(string source, string prefix, System.Globalization.CompareOptions options) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public static bool IsSortable(char ch) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool IsSortable(string text) { throw null; }
- public virtual bool IsSuffix(string source, string suffix) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual bool IsSuffix(string source, string suffix, System.Globalization.CompareOptions options) { throw null; }
- public virtual int LastIndexOf(string source, char value) { throw null; }
- public virtual int LastIndexOf(string source, char value, System.Globalization.CompareOptions options) { throw null; }
- public virtual int LastIndexOf(string source, char value, int startIndex) { throw null; }
- public virtual int LastIndexOf(string source, char value, int startIndex, System.Globalization.CompareOptions options) { throw null; }
- public virtual int LastIndexOf(string source, char value, int startIndex, int count) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual int LastIndexOf(string source, char value, int startIndex, int count, System.Globalization.CompareOptions options) { throw null; }
- public virtual int LastIndexOf(string source, string value) { throw null; }
- public virtual int LastIndexOf(string source, string value, System.Globalization.CompareOptions options) { throw null; }
- public virtual int LastIndexOf(string source, string value, int startIndex) { throw null; }
- public virtual int LastIndexOf(string source, string value, int startIndex, System.Globalization.CompareOptions options) { throw null; }
- public virtual int LastIndexOf(string source, string value, int startIndex, int count) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual int LastIndexOf(string source, string value, int startIndex, int count, System.Globalization.CompareOptions options) { throw null; }
- void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { }
- public override string ToString() { throw null; }
- public SortVersion Version { get { throw null; } }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum CompareOptions
- {
- IgnoreCase = 1,
- IgnoreKanaType = 8,
- IgnoreNonSpace = 2,
- IgnoreSymbols = 4,
- IgnoreWidth = 16,
- None = 0,
- Ordinal = 1073741824,
- OrdinalIgnoreCase = 268435456,
- StringSort = 536870912,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class CultureInfo : System.ICloneable, System.IFormatProvider
- {
- public CultureInfo(int culture) { throw null; }
- public CultureInfo(int culture, bool useUserOverride) { throw null; }
- public CultureInfo(string name) { }
- public CultureInfo(string name, bool useUserOverride) { throw null; }
- public virtual System.Globalization.Calendar Calendar { get { throw null; } }
- public virtual System.Globalization.CompareInfo CompareInfo { get { throw null; } }
- public System.Globalization.CultureTypes CultureTypes { get { throw null; } }
- public static System.Globalization.CultureInfo CurrentCulture { get { throw null; } set { } }
- public static System.Globalization.CultureInfo CurrentUICulture { get { throw null; } set { } }
- public virtual System.Globalization.DateTimeFormatInfo DateTimeFormat { get { throw null; } set { } }
- public static System.Globalization.CultureInfo DefaultThreadCurrentCulture { get { throw null; } [System.Security.SecuritySafeCriticalAttribute]set { } }
- public static System.Globalization.CultureInfo DefaultThreadCurrentUICulture { get { throw null; } [System.Security.SecuritySafeCriticalAttribute]set { } }
- public virtual string DisplayName { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public virtual string EnglishName { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public string IetfLanguageTag { get { throw null; } }
- public static System.Globalization.CultureInfo InstalledUICulture { get { throw null; } }
- public static System.Globalization.CultureInfo InvariantCulture { get { throw null; } }
- public virtual bool IsNeutralCulture { get { throw null; } }
- public bool IsReadOnly { get { throw null; } }
- public virtual int KeyboardLanguageId { get { throw null; } }
- public virtual int LCID { get { throw null; } }
- public virtual string Name { get { throw null; } }
- public virtual string NativeName { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public virtual System.Globalization.NumberFormatInfo NumberFormat { get { throw null; } set { } }
- public virtual System.Globalization.Calendar[] OptionalCalendars { get { throw null; } }
- public virtual System.Globalization.CultureInfo Parent { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public virtual System.Globalization.TextInfo TextInfo { get { throw null; } }
- public virtual string ThreeLetterISOLanguageName { get { throw null; } }
- public virtual string ThreeLetterWindowsLanguageName { get { throw null; } }
- public virtual string TwoLetterISOLanguageName { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public bool UseUserOverride { get { throw null; } }
- public void ClearCachedData() { throw null; }
- public virtual object Clone() { throw null; }
- public static System.Globalization.CultureInfo CreateSpecificCulture(string name) { throw null; }
- public override bool Equals(object value) { throw null; }
- public System.Globalization.CultureInfo GetConsoleFallbackUICulture() { throw null; }
- public static System.Globalization.CultureInfo GetCultureInfo(int culture) { throw null; }
- public static System.Globalization.CultureInfo GetCultureInfo(string name) { throw null; }
- public static System.Globalization.CultureInfo GetCultureInfo(string name, string altName) { throw null; }
- public static System.Globalization.CultureInfo GetCultureInfoByIetfLanguageTag(string name) { throw null; }
- public static System.Globalization.CultureInfo[] GetCultures(System.Globalization.CultureTypes types) { throw null; }
- public virtual object GetFormat(System.Type formatType) { throw null; }
- public override int GetHashCode() { throw null; }
- public static System.Globalization.CultureInfo ReadOnly(System.Globalization.CultureInfo ci) { throw null; }
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class CultureNotFoundException : System.ArgumentException, System.Runtime.Serialization.ISerializable
- {
- public CultureNotFoundException() { }
- public CultureNotFoundException(string message) { }
- public CultureNotFoundException(string message, System.Exception innerException) { }
- public CultureNotFoundException(string message, int invalidCultureId, System.Exception innerException) { }
- public CultureNotFoundException(string paramName, int invalidCultureId, string message) { }
- public CultureNotFoundException(string paramName, string message) { }
- public CultureNotFoundException(string message, string invalidCultureName, System.Exception innerException) { }
- public CultureNotFoundException(string paramName, string invalidCultureName, string message) { }
- protected CultureNotFoundException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- public virtual System.Nullable<int> InvalidCultureId { get { throw null; } }
- public virtual string InvalidCultureName { get { throw null; } }
- public override string Message { get { throw null; } }
- [System.Security.SecurityCriticalAttribute]
- public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DateTimeFormatInfo : System.ICloneable, System.IFormatProvider
- {
- public DateTimeFormatInfo() { }
- public string[] AbbreviatedDayNames { get { throw null; } set { } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string[] AbbreviatedMonthGenitiveNames { get { throw null; } set { } }
- public string[] AbbreviatedMonthNames { get { throw null; } set { } }
- public string AMDesignator { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } set { } }
- public System.Globalization.Calendar Calendar { get { throw null; } set { } }
- public System.Globalization.CalendarWeekRule CalendarWeekRule { get { throw null; } set { } }
- public static System.Globalization.DateTimeFormatInfo CurrentInfo { get { throw null; } }
- public string DateSeparator { get { throw null; } set { throw null; } }
- public string[] DayNames { get { throw null; } set { } }
- public System.DayOfWeek FirstDayOfWeek { get { throw null; } set { } }
- public string FullDateTimePattern { get { throw null; } set { } }
- public static System.Globalization.DateTimeFormatInfo InvariantInfo { get { throw null; } }
- public bool IsReadOnly { get { throw null; } }
- public string LongDatePattern { get { throw null; } set { } }
- public string LongTimePattern { get { throw null; } set { } }
- public string MonthDayPattern { get { throw null; } set { } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string[] MonthGenitiveNames { get { throw null; } set { } }
- public string[] MonthNames { get { throw null; } set { } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string NativeCalendarName { get { throw null; } }
- public string PMDesignator { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } set { } }
- public string RFC1123Pattern { get { throw null; } }
- public string ShortDatePattern { get { throw null; } set { } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string[] ShortestDayNames { get { throw null; } set { } }
- public string ShortTimePattern { get { throw null; } set { } }
- public string SortableDateTimePattern { get { throw null; } }
- public string TimeSeparator { get { throw null; } set { throw null; } }
- public string UniversalSortableDateTimePattern { get { throw null; } }
- public string YearMonthPattern { get { throw null; } set { } }
- public object Clone() { throw null; }
- public string GetAbbreviatedDayName(System.DayOfWeek dayofweek) { throw null; }
- public string GetAbbreviatedEraName(int era) { throw null; }
- public string GetAbbreviatedMonthName(int month) { throw null; }
- public string[] GetAllDateTimePatterns() { throw null; }
- public string[] GetAllDateTimePatterns(char format) { throw null; }
- public string GetDayName(System.DayOfWeek dayofweek) { throw null; }
- public int GetEra(string eraName) { throw null; }
- public string GetEraName(int era) { throw null; }
- public object GetFormat(System.Type formatType) { throw null; }
- public static System.Globalization.DateTimeFormatInfo GetInstance(System.IFormatProvider provider) { throw null; }
- public string GetMonthName(int month) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string GetShortestDayName(System.DayOfWeek dayOfWeek) { throw null; }
- public static System.Globalization.DateTimeFormatInfo ReadOnly(System.Globalization.DateTimeFormatInfo dtfi) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public void SetAllDateTimePatterns(string[] patterns, char format) { throw null; }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum DateTimeStyles
- {
- AdjustToUniversal = 16,
- AllowInnerWhite = 4,
- AllowLeadingWhite = 1,
- AllowTrailingWhite = 2,
- AllowWhiteSpaces = 7,
- AssumeLocal = 32,
- AssumeUniversal = 64,
- NoCurrentDateDefault = 8,
- None = 0,
- RoundtripKind = 128,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class DaylightTime
- {
- public DaylightTime(System.DateTime start, System.DateTime end, System.TimeSpan delta) { throw null; }
- public System.TimeSpan Delta { get { throw null; } }
- public System.DateTime End { get { throw null; } }
- public System.DateTime Start { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum DigitShapes
- {
- Context = 0,
- NativeNational = 2,
- None = 1,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class EastAsianLunisolarCalendar : System.Globalization.Calendar
- {
- internal EastAsianLunisolarCalendar() { }
-#if FEATURE_COREFX_GLOBALIZATION
- public override System.Globalization.CalendarAlgorithmType AlgorithmType { get { throw null; } }
-#endif
- public override int TwoDigitYearMax { get { throw null; } set { } }
- public override System.DateTime AddMonths(System.DateTime time, int months) { throw null; }
- public override System.DateTime AddYears(System.DateTime time, int years) { throw null; }
- public int GetCelestialStem(int sexagenaryYear) { throw null; }
- public override int GetDayOfMonth(System.DateTime time) { throw null; }
- public override System.DayOfWeek GetDayOfWeek(System.DateTime time) { throw null; }
- public override int GetDayOfYear(System.DateTime time) { throw null; }
- public override int GetDaysInMonth(int year, int month, int era) { throw null; }
- public override int GetDaysInYear(int year, int era) { throw null; }
- public override int GetLeapMonth(int year, int era) { throw null; }
- public override int GetMonth(System.DateTime time) { throw null; }
- public override int GetMonthsInYear(int year, int era) { throw null; }
- public virtual int GetSexagenaryYear(System.DateTime time) { throw null; }
- public int GetTerrestrialBranch(int sexagenaryYear) { throw null; }
- public override int GetYear(System.DateTime time) { throw null; }
- public override bool IsLeapDay(int year, int month, int day, int era) { throw null; }
- public override bool IsLeapMonth(int year, int month, int era) { throw null; }
- public override bool IsLeapYear(int year, int era) { throw null; }
- public override System.DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) { throw null; }
- public override int ToFourDigitYear(int year) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class GregorianCalendar : System.Globalization.Calendar
- {
- public const int ADEra = 1;
- public GregorianCalendar() { }
- public GregorianCalendar(System.Globalization.GregorianCalendarTypes type) { }
-#if FEATURE_COREFX_GLOBALIZATION
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Globalization.CalendarAlgorithmType AlgorithmType { get { throw null; } }
-#endif
- public virtual System.Globalization.GregorianCalendarTypes CalendarType { get { throw null; } set { } }
- public override int[] Eras { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MaxSupportedDateTime { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MinSupportedDateTime { get { throw null; } }
- public override int TwoDigitYearMax { get { throw null; } set { } }
- public override System.DateTime AddMonths(System.DateTime time, int months) { throw null; }
- public override System.DateTime AddYears(System.DateTime time, int years) { throw null; }
- public override int GetDayOfMonth(System.DateTime time) { throw null; }
- public override System.DayOfWeek GetDayOfWeek(System.DateTime time) { throw null; }
- public override int GetDayOfYear(System.DateTime time) { throw null; }
- public override int GetDaysInMonth(int year, int month, int era) { throw null; }
- public override int GetDaysInYear(int year, int era) { throw null; }
- public override int GetEra(System.DateTime time) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetLeapMonth(int year, int era) { throw null; }
- public override int GetMonth(System.DateTime time) { throw null; }
- public override int GetMonthsInYear(int year, int era) { throw null; }
- public override int GetYear(System.DateTime time) { throw null; }
- public override bool IsLeapDay(int year, int month, int day, int era) { throw null; }
- public override bool IsLeapMonth(int year, int month, int era) { throw null; }
- public override bool IsLeapYear(int year, int era) { throw null; }
- public override System.DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) { throw null; }
- public override int ToFourDigitYear(int year) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum GregorianCalendarTypes
- {
- Arabic = 10,
- Localized = 1,
- MiddleEastFrench = 9,
- TransliteratedEnglish = 11,
- TransliteratedFrench = 12,
- USEnglish = 2,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class HebrewCalendar : System.Globalization.Calendar
- {
- public static readonly int HebrewEra;
- public HebrewCalendar() { }
-#if FEATURE_COREFX_GLOBALIZATION
- public override System.Globalization.CalendarAlgorithmType AlgorithmType { get { throw null; } }
-#endif
- public override int[] Eras { get { throw null; } }
- public override System.DateTime MaxSupportedDateTime { get { throw null; } }
- public override System.DateTime MinSupportedDateTime { get { throw null; } }
- public override int TwoDigitYearMax { get { throw null; } set { } }
- public override System.DateTime AddMonths(System.DateTime time, int months) { throw null; }
- public override System.DateTime AddYears(System.DateTime time, int years) { throw null; }
- public override int GetDayOfMonth(System.DateTime time) { throw null; }
- public override System.DayOfWeek GetDayOfWeek(System.DateTime time) { throw null; }
- public override int GetDayOfYear(System.DateTime time) { throw null; }
- public override int GetDaysInMonth(int year, int month, int era) { throw null; }
- public override int GetDaysInYear(int year, int era) { throw null; }
- public override int GetEra(System.DateTime time) { throw null; }
- public override int GetLeapMonth(int year, int era) { throw null; }
- public override int GetMonth(System.DateTime time) { throw null; }
- public override int GetMonthsInYear(int year, int era) { throw null; }
- public override int GetYear(System.DateTime time) { throw null; }
- public override bool IsLeapDay(int year, int month, int day, int era) { throw null; }
- public override bool IsLeapMonth(int year, int month, int era) { throw null; }
- public override bool IsLeapYear(int year, int era) { throw null; }
- public override System.DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) { throw null; }
- public override int ToFourDigitYear(int year) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class HijriCalendar : System.Globalization.Calendar
- {
- public static readonly int HijriEra;
- public HijriCalendar() { }
-#if FEATURE_COREFX_GLOBALIZATION
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Globalization.CalendarAlgorithmType AlgorithmType { get { throw null; } }
-#endif
- protected override int DaysInYearBeforeMinSupportedYear { get { throw null; } }
- public override int[] Eras { get { throw null; } }
- public int HijriAdjustment { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } set { } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MaxSupportedDateTime { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MinSupportedDateTime { get { throw null; } }
- public override int TwoDigitYearMax { get { throw null; } set { } }
- public override System.DateTime AddMonths(System.DateTime time, int months) { throw null; }
- public override System.DateTime AddYears(System.DateTime time, int years) { throw null; }
- public override int GetDayOfMonth(System.DateTime time) { throw null; }
- public override System.DayOfWeek GetDayOfWeek(System.DateTime time) { throw null; }
- public override int GetDayOfYear(System.DateTime time) { throw null; }
- public override int GetDaysInMonth(int year, int month, int era) { throw null; }
- public override int GetDaysInYear(int year, int era) { throw null; }
- public override int GetEra(System.DateTime time) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetLeapMonth(int year, int era) { throw null; }
- public override int GetMonth(System.DateTime time) { throw null; }
- public override int GetMonthsInYear(int year, int era) { throw null; }
- public override int GetYear(System.DateTime time) { throw null; }
- public override bool IsLeapDay(int year, int month, int day, int era) { throw null; }
- public override bool IsLeapMonth(int year, int month, int era) { throw null; }
- public override bool IsLeapYear(int year, int era) { throw null; }
- public override System.DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) { throw null; }
- public override int ToFourDigitYear(int year) { throw null; }
- }
- public sealed partial class IdnMapping
- {
- public IdnMapping() { }
- public bool AllowUnassigned { get { throw null; } set { throw null; } }
- public bool UseStd3AsciiRules { get { throw null; } set { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public string GetAscii(string unicode) { throw null; }
- public string GetAscii(string unicode, int index) { throw null; }
- public string GetAscii(string unicode, int index, int count) { throw null; }
- public override int GetHashCode() { throw null; }
- public string GetUnicode(string ascii) { throw null; }
- public string GetUnicode(string ascii, int index) { throw null; }
- public string GetUnicode(string ascii, int index, int count) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class JapaneseCalendar : System.Globalization.Calendar
- {
- public JapaneseCalendar() { }
-#if FEATURE_COREFX_GLOBALIZATION
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Globalization.CalendarAlgorithmType AlgorithmType { get { throw null; } }
-#endif
- public override int[] Eras { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MaxSupportedDateTime { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MinSupportedDateTime { get { throw null; } }
- public override int TwoDigitYearMax { get { throw null; } set { } }
- public override System.DateTime AddMonths(System.DateTime time, int months) { throw null; }
- public override System.DateTime AddYears(System.DateTime time, int years) { throw null; }
- public override int GetDayOfMonth(System.DateTime time) { throw null; }
- public override System.DayOfWeek GetDayOfWeek(System.DateTime time) { throw null; }
- public override int GetDayOfYear(System.DateTime time) { throw null; }
- public override int GetDaysInMonth(int year, int month, int era) { throw null; }
- public override int GetDaysInYear(int year, int era) { throw null; }
- public override int GetEra(System.DateTime time) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetLeapMonth(int year, int era) { throw null; }
- public override int GetMonth(System.DateTime time) { throw null; }
- public override int GetMonthsInYear(int year, int era) { throw null; }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Contracts", "CC1055")]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetWeekOfYear(System.DateTime time, System.Globalization.CalendarWeekRule rule, System.DayOfWeek firstDayOfWeek) { throw null; }
- public override int GetYear(System.DateTime time) { throw null; }
- public override bool IsLeapDay(int year, int month, int day, int era) { throw null; }
- public override bool IsLeapMonth(int year, int month, int era) { throw null; }
- public override bool IsLeapYear(int year, int era) { throw null; }
- public override System.DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) { throw null; }
- public override int ToFourDigitYear(int year) { throw null; }
- }
- public partial class JapaneseLunisolarCalendar : System.Globalization.EastAsianLunisolarCalendar
- {
- public const int JapaneseEra = 1;
- public JapaneseLunisolarCalendar() { }
- protected override int DaysInYearBeforeMinSupportedYear { get { throw null; } }
- public override int[] Eras { get { throw null; } }
- public override System.DateTime MaxSupportedDateTime { get { throw null; } }
- public override System.DateTime MinSupportedDateTime { get { throw null; } }
- public override int GetEra(System.DateTime time) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class JulianCalendar : System.Globalization.Calendar
- {
- public static readonly int JulianEra;
- public JulianCalendar() { }
-#if FEATURE_COREFX_GLOBALIZATION
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Globalization.CalendarAlgorithmType AlgorithmType { get { throw null; } }
-#endif
- public override int[] Eras { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MaxSupportedDateTime { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MinSupportedDateTime { get { throw null; } }
- public override int TwoDigitYearMax { get { throw null; } set { } }
- public override System.DateTime AddMonths(System.DateTime time, int months) { throw null; }
- public override System.DateTime AddYears(System.DateTime time, int years) { throw null; }
- public override int GetDayOfMonth(System.DateTime time) { throw null; }
- public override System.DayOfWeek GetDayOfWeek(System.DateTime time) { throw null; }
- public override int GetDayOfYear(System.DateTime time) { throw null; }
- public override int GetDaysInMonth(int year, int month, int era) { throw null; }
- public override int GetDaysInYear(int year, int era) { throw null; }
- public override int GetEra(System.DateTime time) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetLeapMonth(int year, int era) { throw null; }
- public override int GetMonth(System.DateTime time) { throw null; }
- public override int GetMonthsInYear(int year, int era) { throw null; }
- public override int GetYear(System.DateTime time) { throw null; }
- public override bool IsLeapDay(int year, int month, int day, int era) { throw null; }
- public override bool IsLeapMonth(int year, int month, int era) { throw null; }
- public override bool IsLeapYear(int year, int era) { throw null; }
- public override System.DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) { throw null; }
- public override int ToFourDigitYear(int year) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class KoreanCalendar : System.Globalization.Calendar
- {
- public const int KoreanEra = 1;
- public KoreanCalendar() { }
-#if FEATURE_COREFX_GLOBALIZATION
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Globalization.CalendarAlgorithmType AlgorithmType { get { throw null; } }
-#endif
- public override int[] Eras { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MaxSupportedDateTime { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MinSupportedDateTime { get { throw null; } }
- public override int TwoDigitYearMax { get { throw null; } set { } }
- public override System.DateTime AddMonths(System.DateTime time, int months) { throw null; }
- public override System.DateTime AddYears(System.DateTime time, int years) { throw null; }
- public override int GetDayOfMonth(System.DateTime time) { throw null; }
- public override System.DayOfWeek GetDayOfWeek(System.DateTime time) { throw null; }
- public override int GetDayOfYear(System.DateTime time) { throw null; }
- public override int GetDaysInMonth(int year, int month, int era) { throw null; }
- public override int GetDaysInYear(int year, int era) { throw null; }
- public override int GetEra(System.DateTime time) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetLeapMonth(int year, int era) { throw null; }
- public override int GetMonth(System.DateTime time) { throw null; }
- public override int GetMonthsInYear(int year, int era) { throw null; }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Contracts", "CC1055")]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetWeekOfYear(System.DateTime time, System.Globalization.CalendarWeekRule rule, System.DayOfWeek firstDayOfWeek) { throw null; }
- public override int GetYear(System.DateTime time) { throw null; }
- public override bool IsLeapDay(int year, int month, int day, int era) { throw null; }
- public override bool IsLeapMonth(int year, int month, int era) { throw null; }
- public override bool IsLeapYear(int year, int era) { throw null; }
- public override System.DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) { throw null; }
- public override int ToFourDigitYear(int year) { throw null; }
- }
- public partial class KoreanLunisolarCalendar : System.Globalization.EastAsianLunisolarCalendar
- {
- public const int GregorianEra = 1;
- public KoreanLunisolarCalendar() { }
- protected override int DaysInYearBeforeMinSupportedYear { get { throw null; } }
- public override int[] Eras { get { throw null; } }
- public override System.DateTime MaxSupportedDateTime { get { throw null; } }
- public override System.DateTime MinSupportedDateTime { get { throw null; } }
- public override int GetEra(System.DateTime time) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class NumberFormatInfo : System.ICloneable, System.IFormatProvider
- {
- public NumberFormatInfo() { }
- public int CurrencyDecimalDigits { get { throw null; } set { } }
- public string CurrencyDecimalSeparator { get { throw null; } set { } }
- public string CurrencyGroupSeparator { get { throw null; } set { } }
- public int[] CurrencyGroupSizes { get { throw null; } set { } }
- public int CurrencyNegativePattern { get { throw null; } set { } }
- public int CurrencyPositivePattern { get { throw null; } set { } }
- public string CurrencySymbol { get { throw null; } set { } }
- public static System.Globalization.NumberFormatInfo CurrentInfo { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Globalization.DigitShapes DigitSubstitution { get { throw null; } set { throw null; } }
- public static System.Globalization.NumberFormatInfo InvariantInfo { get { throw null; } }
- public bool IsReadOnly { get { throw null; } }
- public string NaNSymbol { get { throw null; } set { } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string[] NativeDigits { get { throw null; } set { throw null; } }
- public string NegativeInfinitySymbol { get { throw null; } set { } }
- public string NegativeSign { get { throw null; } set { } }
- public int NumberDecimalDigits { get { throw null; } set { } }
- public string NumberDecimalSeparator { get { throw null; } set { } }
- public string NumberGroupSeparator { get { throw null; } set { } }
- public int[] NumberGroupSizes { get { throw null; } set { } }
- public int NumberNegativePattern { get { throw null; } set { } }
- public int PercentDecimalDigits { get { throw null; } set { } }
- public string PercentDecimalSeparator { get { throw null; } set { } }
- public string PercentGroupSeparator { get { throw null; } set { } }
- public int[] PercentGroupSizes { get { throw null; } set { } }
- public int PercentNegativePattern { get { throw null; } set { } }
- public int PercentPositivePattern { get { throw null; } set { } }
- public string PercentSymbol { get { throw null; } set { } }
- public string PerMilleSymbol { get { throw null; } set { } }
- public string PositiveInfinitySymbol { get { throw null; } set { } }
- public string PositiveSign { get { throw null; } set { } }
- public object Clone() { throw null; }
- public object GetFormat(System.Type formatType) { throw null; }
- public static System.Globalization.NumberFormatInfo GetInstance(System.IFormatProvider formatProvider) { throw null; }
- public static System.Globalization.NumberFormatInfo ReadOnly(System.Globalization.NumberFormatInfo nfi) { throw null; }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum NumberStyles
- {
- AllowCurrencySymbol = 256,
- AllowDecimalPoint = 32,
- AllowExponent = 128,
- AllowHexSpecifier = 512,
- AllowLeadingSign = 4,
- AllowLeadingWhite = 1,
- AllowParentheses = 16,
- AllowThousands = 64,
- AllowTrailingSign = 8,
- AllowTrailingWhite = 2,
- Any = 511,
- Currency = 383,
- Float = 167,
- HexNumber = 515,
- Integer = 7,
- None = 0,
- Number = 111,
- }
- public partial class PersianCalendar : System.Globalization.Calendar
- {
- public static readonly int PersianEra;
- public PersianCalendar() { }
-#if FEATURE_COREFX_GLOBALIZATION
- public override System.Globalization.CalendarAlgorithmType AlgorithmType { get { throw null; } }
-#endif
- public override int[] Eras { get { throw null; } }
- public override System.DateTime MaxSupportedDateTime { get { throw null; } }
- public override System.DateTime MinSupportedDateTime { get { throw null; } }
- public override int TwoDigitYearMax { get { throw null; } set { } }
- public override System.DateTime AddMonths(System.DateTime time, int months) { throw null; }
- public override System.DateTime AddYears(System.DateTime time, int years) { throw null; }
- public override int GetDayOfMonth(System.DateTime time) { throw null; }
- public override System.DayOfWeek GetDayOfWeek(System.DateTime time) { throw null; }
- public override int GetDayOfYear(System.DateTime time) { throw null; }
- public override int GetDaysInMonth(int year, int month, int era) { throw null; }
- public override int GetDaysInYear(int year, int era) { throw null; }
- public override int GetEra(System.DateTime time) { throw null; }
- public override int GetLeapMonth(int year, int era) { throw null; }
- public override int GetMonth(System.DateTime time) { throw null; }
- public override int GetMonthsInYear(int year, int era) { throw null; }
- public override int GetYear(System.DateTime time) { throw null; }
- public override bool IsLeapDay(int year, int month, int day, int era) { throw null; }
- public override bool IsLeapMonth(int year, int month, int era) { throw null; }
- public override bool IsLeapYear(int year, int era) { throw null; }
- public override System.DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) { throw null; }
- public override int ToFourDigitYear(int year) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class RegionInfo
- {
- public RegionInfo(int culture) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public RegionInfo(string name) { }
- public virtual string CurrencySymbol { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual string CurrencyEnglishName { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual string CurrencyNativeName { get { throw null; } }
- public static System.Globalization.RegionInfo CurrentRegion { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public virtual string DisplayName { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public virtual string EnglishName { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual int GeoId { get { throw null; } }
- public virtual bool IsMetric { get { throw null; } }
- public virtual string ISOCurrencySymbol { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public virtual string Name { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual string NativeName { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public virtual string ThreeLetterISORegionName { get { throw null; } }
- public virtual string ThreeLetterWindowsRegionName { get { throw null; } }
- public virtual string TwoLetterISORegionName { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public override bool Equals(object value) { throw null; }
- public override int GetHashCode() { throw null; }
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class SortKey
- {
- internal SortKey() { throw null; }
- public virtual byte[] KeyData { get { throw null; } }
- public virtual string OriginalString { get { throw null; } }
- public static int Compare(System.Globalization.SortKey sortkey1, System.Globalization.SortKey sortkey2) { throw null; }
- public override bool Equals(object value) { throw null; }
- public override int GetHashCode() { throw null; }
- public override string ToString() { throw null; }
- }
- public sealed partial class SortVersion : System.IEquatable<System.Globalization.SortVersion>
- {
- public SortVersion(int fullVersion, System.Guid sortId) { throw null; }
- public int FullVersion { get { throw null; } }
- public System.Guid SortId { get { throw null; } }
- public bool Equals(System.Globalization.SortVersion other) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Globalization.SortVersion left, System.Globalization.SortVersion right) { throw null; }
- public static bool operator !=(System.Globalization.SortVersion left, System.Globalization.SortVersion right) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class StringInfo
- {
- public StringInfo() { }
- public StringInfo(string value) { }
- public int LengthInTextElements { get { throw null; } }
- public string String { get { throw null; } set { } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override bool Equals(object value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetHashCode() { throw null; }
- public static string GetNextTextElement(string str) { throw null; }
- public static string GetNextTextElement(string str, int index) { throw null; }
- public static System.Globalization.TextElementEnumerator GetTextElementEnumerator(string str) { throw null; }
- public static System.Globalization.TextElementEnumerator GetTextElementEnumerator(string str, int index) { throw null; }
- public static int[] ParseCombiningCharacters(string str) { throw null; }
- public string SubstringByTextElements(int startingTextElement) { throw null; }
- public string SubstringByTextElements(int startingTextElement, int lengthInTextElements) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class TaiwanCalendar : System.Globalization.Calendar
- {
- public TaiwanCalendar() { }
-#if FEATURE_COREFX_GLOBALIZATION
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Globalization.CalendarAlgorithmType AlgorithmType { get { throw null; } }
-#endif
- public override int[] Eras { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MaxSupportedDateTime { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MinSupportedDateTime { get { throw null; } }
- public override int TwoDigitYearMax { get { throw null; } set { } }
- public override System.DateTime AddMonths(System.DateTime time, int months) { throw null; }
- public override System.DateTime AddYears(System.DateTime time, int years) { throw null; }
- public override int GetDayOfMonth(System.DateTime time) { throw null; }
- public override System.DayOfWeek GetDayOfWeek(System.DateTime time) { throw null; }
- public override int GetDayOfYear(System.DateTime time) { throw null; }
- public override int GetDaysInMonth(int year, int month, int era) { throw null; }
- public override int GetDaysInYear(int year, int era) { throw null; }
- public override int GetEra(System.DateTime time) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetLeapMonth(int year, int era) { throw null; }
- public override int GetMonth(System.DateTime time) { throw null; }
- public override int GetMonthsInYear(int year, int era) { throw null; }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Contracts", "CC1055")]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetWeekOfYear(System.DateTime time, System.Globalization.CalendarWeekRule rule, System.DayOfWeek firstDayOfWeek) { throw null; }
- public override int GetYear(System.DateTime time) { throw null; }
- public override bool IsLeapDay(int year, int month, int day, int era) { throw null; }
- public override bool IsLeapMonth(int year, int month, int era) { throw null; }
- public override bool IsLeapYear(int year, int era) { throw null; }
- public override System.DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) { throw null; }
- public override int ToFourDigitYear(int year) { throw null; }
- }
- public partial class TaiwanLunisolarCalendar : System.Globalization.EastAsianLunisolarCalendar
- {
- public TaiwanLunisolarCalendar() { }
- protected override int DaysInYearBeforeMinSupportedYear { get { throw null; } }
- public override int[] Eras { get { throw null; } }
- public override System.DateTime MaxSupportedDateTime { get { throw null; } }
- public override System.DateTime MinSupportedDateTime { get { throw null; } }
- public override int GetEra(System.DateTime time) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class TextElementEnumerator : System.Collections.IEnumerator
- {
- internal TextElementEnumerator() { }
- public object Current { get { throw null; } }
- public int ElementIndex { get { throw null; } }
- public string GetTextElement() { throw null; }
- public bool MoveNext() { throw null; }
- public void Reset() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class TextInfo : System.ICloneable, System.Runtime.Serialization.IDeserializationCallback
- {
- internal TextInfo() { }
- public virtual int ANSICodePage { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public string CultureName { get { throw null; } }
- public virtual int EBCDICCodePage { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public bool IsReadOnly { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public bool IsRightToLeft { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public int LCID { get { throw null; } }
- public virtual string ListSeparator { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } [System.Runtime.InteropServices.ComVisibleAttribute(false)]set { } }
- public virtual int MacCodePage { get { throw null; } }
- public virtual int OEMCodePage { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual object Clone() { throw null; }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public static System.Globalization.TextInfo ReadOnly(System.Globalization.TextInfo textInfo) { throw null; }
- void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual char ToLower(char c) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual string ToLower(string str) { throw null; }
- public override string ToString() { throw null; }
- public string ToTitleCase(string str) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual char ToUpper(char c) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual string ToUpper(string str) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ThaiBuddhistCalendar : System.Globalization.Calendar
- {
- public const int ThaiBuddhistEra = 1;
- public ThaiBuddhistCalendar() { }
-#if FEATURE_COREFX_GLOBALIZATION
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Globalization.CalendarAlgorithmType AlgorithmType { get { throw null; } }
-#endif
- public override int[] Eras { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MaxSupportedDateTime { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.DateTime MinSupportedDateTime { get { throw null; } }
- public override int TwoDigitYearMax { get { throw null; } set { } }
- public override System.DateTime AddMonths(System.DateTime time, int months) { throw null; }
- public override System.DateTime AddYears(System.DateTime time, int years) { throw null; }
- public override int GetDayOfMonth(System.DateTime time) { throw null; }
- public override System.DayOfWeek GetDayOfWeek(System.DateTime time) { throw null; }
- public override int GetDayOfYear(System.DateTime time) { throw null; }
- public override int GetDaysInMonth(int year, int month, int era) { throw null; }
- public override int GetDaysInYear(int year, int era) { throw null; }
- public override int GetEra(System.DateTime time) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetLeapMonth(int year, int era) { throw null; }
- public override int GetMonth(System.DateTime time) { throw null; }
- public override int GetMonthsInYear(int year, int era) { throw null; }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Contracts", "CC1055")]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetWeekOfYear(System.DateTime time, System.Globalization.CalendarWeekRule rule, System.DayOfWeek firstDayOfWeek) { throw null; }
- public override int GetYear(System.DateTime time) { throw null; }
- public override bool IsLeapDay(int year, int month, int day, int era) { throw null; }
- public override bool IsLeapMonth(int year, int month, int era) { throw null; }
- public override bool IsLeapYear(int year, int era) { throw null; }
- public override System.DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) { throw null; }
- public override int ToFourDigitYear(int year) { throw null; }
- }
- [System.FlagsAttribute]
- public enum TimeSpanStyles
- {
- AssumeNegative = 1,
- None = 0,
- }
- public partial class UmAlQuraCalendar : System.Globalization.Calendar
- {
- public const int UmAlQuraEra = 1;
- public UmAlQuraCalendar() { }
-#if FEATURE_COREFX_GLOBALIZATION
- public override System.Globalization.CalendarAlgorithmType AlgorithmType { get { throw null; } }
-#endif
- protected override int DaysInYearBeforeMinSupportedYear { get { throw null; } }
- public override int[] Eras { get { throw null; } }
- public override System.DateTime MaxSupportedDateTime { get { throw null; } }
- public override System.DateTime MinSupportedDateTime { get { throw null; } }
- public override int TwoDigitYearMax { get { throw null; } set { } }
- public override System.DateTime AddMonths(System.DateTime time, int months) { throw null; }
- public override System.DateTime AddYears(System.DateTime time, int years) { throw null; }
- public override int GetDayOfMonth(System.DateTime time) { throw null; }
- public override System.DayOfWeek GetDayOfWeek(System.DateTime time) { throw null; }
- public override int GetDayOfYear(System.DateTime time) { throw null; }
- public override int GetDaysInMonth(int year, int month, int era) { throw null; }
- public override int GetDaysInYear(int year, int era) { throw null; }
- public override int GetEra(System.DateTime time) { throw null; }
- public override int GetLeapMonth(int year, int era) { throw null; }
- public override int GetMonth(System.DateTime time) { throw null; }
- public override int GetMonthsInYear(int year, int era) { throw null; }
- public override int GetYear(System.DateTime time) { throw null; }
- public override bool IsLeapDay(int year, int month, int day, int era) { throw null; }
- public override bool IsLeapMonth(int year, int month, int era) { throw null; }
- public override bool IsLeapYear(int year, int era) { throw null; }
- public override System.DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) { throw null; }
- public override int ToFourDigitYear(int year) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum UnicodeCategory
- {
- ClosePunctuation = 21,
- ConnectorPunctuation = 18,
- Control = 14,
- CurrencySymbol = 26,
- DashPunctuation = 19,
- DecimalDigitNumber = 8,
- EnclosingMark = 7,
- FinalQuotePunctuation = 23,
- Format = 15,
- InitialQuotePunctuation = 22,
- LetterNumber = 9,
- LineSeparator = 12,
- LowercaseLetter = 1,
- MathSymbol = 25,
- ModifierLetter = 3,
- ModifierSymbol = 27,
- NonSpacingMark = 5,
- OpenPunctuation = 20,
- OtherLetter = 4,
- OtherNotAssigned = 29,
- OtherNumber = 10,
- OtherPunctuation = 24,
- OtherSymbol = 28,
- ParagraphSeparator = 13,
- PrivateUse = 17,
- SpaceSeparator = 11,
- SpacingCombiningMark = 6,
- Surrogate = 16,
- TitlecaseLetter = 2,
- UppercaseLetter = 0,
- }
-}
-namespace System.IO
-{
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class BinaryReader : System.IDisposable
- {
- public BinaryReader(System.IO.Stream input) { }
- public BinaryReader(System.IO.Stream input, System.Text.Encoding encoding) { }
- public BinaryReader(System.IO.Stream input, System.Text.Encoding encoding, bool leaveOpen) { }
- public virtual System.IO.Stream BaseStream { get { throw null; } }
- public virtual void Close() { }
- public void Dispose() { }
- protected virtual void Dispose(bool disposing) { }
- protected virtual void FillBuffer(int numBytes) { }
- public virtual int PeekChar() { throw null; }
- public virtual int Read() { throw null; }
- public virtual int Read(byte[] buffer, int index, int count) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual int Read(char[] buffer, int index, int count) { throw null; }
- protected internal int Read7BitEncodedInt() { throw null; }
- public virtual bool ReadBoolean() { throw null; }
- public virtual byte ReadByte() { throw null; }
- public virtual byte[] ReadBytes(int count) { throw null; }
- public virtual char ReadChar() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual char[] ReadChars(int count) { throw null; }
- public virtual decimal ReadDecimal() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual double ReadDouble() { throw null; }
- public virtual short ReadInt16() { throw null; }
- public virtual int ReadInt32() { throw null; }
- public virtual long ReadInt64() { throw null; }
- [System.CLSCompliantAttribute(false)]
- public virtual sbyte ReadSByte() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual float ReadSingle() { throw null; }
- public virtual string ReadString() { throw null; }
- [System.CLSCompliantAttribute(false)]
- public virtual ushort ReadUInt16() { throw null; }
- [System.CLSCompliantAttribute(false)]
- public virtual uint ReadUInt32() { throw null; }
- [System.CLSCompliantAttribute(false)]
- public virtual ulong ReadUInt64() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class BinaryWriter : System.IDisposable
- {
- public static readonly System.IO.BinaryWriter Null;
- protected System.IO.Stream OutStream;
- protected BinaryWriter() { }
- public BinaryWriter(System.IO.Stream output) { }
- public BinaryWriter(System.IO.Stream output, System.Text.Encoding encoding) { }
- public BinaryWriter(System.IO.Stream output, System.Text.Encoding encoding, bool leaveOpen) { }
- public virtual System.IO.Stream BaseStream { get { throw null; } }
- public virtual void Close() { }
- public void Dispose() { }
- protected virtual void Dispose(bool disposing) { }
- public virtual void Flush() { }
- public virtual long Seek(int offset, System.IO.SeekOrigin origin) { throw null; }
- public virtual void Write(bool value) { }
- public virtual void Write(byte value) { }
- public virtual void Write(byte[] buffer) { }
- public virtual void Write(byte[] buffer, int index, int count) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual void Write(char ch) { }
- public virtual void Write(char[] chars) { }
- public virtual void Write(char[] chars, int index, int count) { }
- public virtual void Write(decimal value) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual void Write(double value) { }
- public virtual void Write(short value) { }
- public virtual void Write(int value) { }
- public virtual void Write(long value) { }
- [System.CLSCompliantAttribute(false)]
- public virtual void Write(sbyte value) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual void Write(float value) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual void Write(string value) { }
- [System.CLSCompliantAttribute(false)]
- public virtual void Write(ushort value) { }
- [System.CLSCompliantAttribute(false)]
- public virtual void Write(uint value) { }
- [System.CLSCompliantAttribute(false)]
- public virtual void Write(ulong value) { }
- protected void Write7BitEncodedInt(int value) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class DirectoryNotFoundException : System.IO.IOException
- {
- public DirectoryNotFoundException() { }
- public DirectoryNotFoundException(string message) { }
- public DirectoryNotFoundException(string message, System.Exception innerException) { }
- protected DirectoryNotFoundException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class EndOfStreamException : System.IO.IOException
- {
- public EndOfStreamException() { }
- public EndOfStreamException(string message) { }
- public EndOfStreamException(string message, System.Exception innerException) { }
- protected EndOfStreamException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum FileAccess
- {
- Read = 1,
- ReadWrite = 3,
- Write = 2,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class FileLoadException : System.IO.IOException
- {
- public FileLoadException() { }
- public FileLoadException(string message) { }
- public FileLoadException(string message, System.Exception inner) { }
- public FileLoadException(string message, string fileName) { }
- public FileLoadException(string message, string fileName, System.Exception inner) { }
- protected FileLoadException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- public string FileName { get { throw null; } }
- public string FusionLog { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public override string Message { get { throw null; } }
- public override string ToString() { throw null; }
- }
- public enum FileMode
- {
- Append = 6,
- Create = 2,
- CreateNew = 1,
- Open = 3,
- OpenOrCreate = 4,
- Truncate = 5,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class FileNotFoundException : System.IO.IOException
- {
- public FileNotFoundException() { }
- public FileNotFoundException(string message) { }
- public FileNotFoundException(string message, System.Exception innerException) { }
- public FileNotFoundException(string message, string fileName) { }
- public FileNotFoundException(string message, string fileName, System.Exception innerException) { }
- protected FileNotFoundException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- public string FileName { get { throw null; } }
- public string FusionLog { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public override string Message { get { throw null; } }
- public override string ToString() { throw null; }
- }
- [System.FlagsAttribute]
- public enum FileOptions
- {
- Asynchronous = 1073741824,
- DeleteOnClose = 67108864,
- Encrypted = 16384,
- None = 0,
- RandomAccess = 268435456,
- SequentialScan = 134217728,
- WriteThrough = -2147483648,
- }
- [System.FlagsAttribute]
- public enum FileShare
- {
- Delete = 4,
- Inheritable = 16,
- None = 0,
- Read = 1,
- ReadWrite = 3,
- Write = 2,
- }
- public partial class FileStream : System.IO.Stream
- {
- public FileStream(Microsoft.Win32.SafeHandles.SafeFileHandle handle, System.IO.FileAccess access) { }
- public FileStream(Microsoft.Win32.SafeHandles.SafeFileHandle handle, System.IO.FileAccess access, int bufferSize) { }
- public FileStream(Microsoft.Win32.SafeHandles.SafeFileHandle handle, System.IO.FileAccess access, int bufferSize, bool isAsync) { }
- public FileStream(string path, System.IO.FileMode mode) { }
- public FileStream(string path, System.IO.FileMode mode, System.IO.FileAccess access) { }
- public FileStream(string path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share) { }
- public FileStream(string path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, int bufferSize) { }
- public FileStream(string path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, int bufferSize, bool useAsync) { }
- public FileStream(string path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, int bufferSize, System.IO.FileOptions options) { }
- public override bool CanRead { get { throw null; } }
- public override bool CanSeek { get { throw null; } }
- public override bool CanWrite { get { throw null; } }
- [Obsolete("This property has been deprecated. Please use FileStream's SafeFileHandle property instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- public virtual System.IntPtr Handle { get { throw null; } }
- public virtual bool IsAsync { get { throw null; } }
- public override long Length { get { throw null; } }
- public string Name { get { throw null; } }
- public override long Position { get { throw null; } set { } }
- public virtual Microsoft.Win32.SafeHandles.SafeFileHandle SafeFileHandle { get { throw null; } }
- protected override void Dispose(bool disposing) { }
- ~FileStream() { }
- public override void Flush() { }
- public virtual void Flush(bool flushToDisk) { }
- public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
- public override int Read(byte[] array, int offset, int count) { throw null; }
- public override System.Threading.Tasks.Task<int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
- public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { throw null; }
- public override int EndRead(IAsyncResult asyncResult) { throw null; }
- public virtual void Lock(long position, long length) { }
- public override int ReadByte() { throw null; }
- public override long Seek(long offset, System.IO.SeekOrigin origin) { throw null; }
- public override void SetLength(long value) { }
- public override void Write(byte[] array, int offset, int count) { }
- public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
- public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { throw null; }
- public override void EndWrite(IAsyncResult asyncResult) { }
- public override void WriteByte(byte value) { }
- public virtual void Unlock(long position, long length) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class IOException : System.SystemException
- {
- public IOException() { }
- public IOException(string message) { }
- public IOException(string message, System.Exception innerException) { }
- public IOException(string message, int hresult) { }
- protected IOException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class MemoryStream : System.IO.Stream
- {
- public MemoryStream() { }
- public MemoryStream(byte[] buffer) { }
- public MemoryStream(byte[] buffer, bool writable) { }
- public MemoryStream(byte[] buffer, int index, int count) { }
- public MemoryStream(byte[] buffer, int index, int count, bool writable) { }
- public MemoryStream(byte[] buffer, int index, int count, bool writable, bool publiclyVisible) { }
- public MemoryStream(int capacity) { }
- public override bool CanRead { get { throw null; } }
- public override bool CanSeek { get { throw null; } }
- public override bool CanWrite { get { throw null; } }
- public virtual int Capacity { get { throw null; } set { } }
- public override long Length { get { throw null; } }
- public override long Position { get { throw null; } set { } }
- public override System.Threading.Tasks.Task CopyToAsync(System.IO.Stream destination, int bufferSize, System.Threading.CancellationToken cancellationToken) { throw null; }
- protected override void Dispose(bool disposing) { }
- public override void Flush() { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
- public virtual byte[] GetBuffer() { throw null; }
- public override int Read(byte[] buffer, int offset, int count) { buffer = default(byte[]); throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task<int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
- public override int ReadByte() { throw null; }
- public override long Seek(long offset, System.IO.SeekOrigin loc) { throw null; }
- public override void SetLength(long value) { }
- public virtual byte[] ToArray() { throw null; }
- public virtual bool TryGetBuffer(out System.ArraySegment<byte> buffer) { buffer = default(System.ArraySegment<byte>); throw null; }
- public override void Write(byte[] buffer, int offset, int count) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
- public override void WriteByte(byte value) { }
- public virtual void WriteTo(System.IO.Stream stream) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static partial class Path
- {
- public static readonly char AltDirectorySeparatorChar;
- public static readonly char DirectorySeparatorChar;
- public static readonly char PathSeparator;
- public static readonly char VolumeSeparatorChar;
- public static string ChangeExtension(string path, string extension) { throw null; }
- public static string Combine(string path1, string path2) { throw null; }
- public static string Combine(string path1, string path2, string path3) { throw null; }
- public static string Combine(params string[] paths) { throw null; }
- public static string GetDirectoryName(string path) { throw null; }
- public static string GetExtension(string path) { throw null; }
- public static string GetFileName(string path) { throw null; }
- public static string GetFileNameWithoutExtension(string path) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static string GetFullPath(string path) { throw null; }
- public static char[] GetInvalidFileNameChars() { throw null; }
- public static char[] GetInvalidPathChars() { throw null; }
- public static string GetPathRoot(string path) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static string GetRandomFileName() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static string GetTempFileName() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static string GetTempPath() { throw null; }
- public static bool HasExtension(string path) { throw null; }
- public static bool IsPathRooted(string path) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class PathTooLongException : System.IO.IOException
- {
- public PathTooLongException() { }
- public PathTooLongException(string message) { }
- public PathTooLongException(string message, System.Exception innerException) { }
- protected PathTooLongException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum SeekOrigin
- {
- Begin = 0,
- Current = 1,
- End = 2,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class Stream : System.IDisposable
- {
- public static readonly System.IO.Stream Null;
- protected Stream() { }
- public abstract bool CanRead { get; }
- public abstract bool CanSeek { get; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual bool CanTimeout { get { throw null; } }
- public abstract bool CanWrite { get; }
- public abstract long Length { get; }
- public abstract long Position { get; set; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual int ReadTimeout { get { throw null; } set { } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual int WriteTimeout { get { throw null; } set { } }
- public virtual System.IAsyncResult BeginRead(byte[] buffer, int offset, int count, System.AsyncCallback callback, object state) { throw null; }
- public virtual System.IAsyncResult BeginWrite(byte[] buffer, int offset, int count, System.AsyncCallback callback, object state) { throw null; }
- public virtual void Close() { }
- public void CopyTo(System.IO.Stream destination) { }
- public void CopyTo(System.IO.Stream destination, int bufferSize) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Threading.Tasks.Task CopyToAsync(System.IO.Stream destination) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Threading.Tasks.Task CopyToAsync(System.IO.Stream destination, int bufferSize) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Threading.Tasks.Task CopyToAsync(System.IO.Stream destination, int bufferSize, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.ObsoleteAttribute("CreateWaitHandle will be removed eventually. Please use \"new ManualResetEvent(false)\" instead.")]
- protected virtual System.Threading.WaitHandle CreateWaitHandle() { return default(System.Threading.WaitHandle); }
- public void Dispose() { }
- protected virtual void Dispose(bool disposing) { }
- public virtual int EndRead(System.IAsyncResult asyncResult) { throw null; }
- public virtual void EndWrite(System.IAsyncResult asyncResult) { }
- public abstract void Flush();
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Threading.Tasks.Task FlushAsync() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.ObsoleteAttribute("Do not call or override this method.")]
- protected virtual void ObjectInvariant() { }
- public abstract int Read(byte[] buffer, int offset, int count);
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Threading.Tasks.Task<int> ReadAsync(byte[] buffer, int offset, int count) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Threading.Tasks.Task<int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
- public virtual int ReadByte() { throw null; }
- public abstract long Seek(long offset, System.IO.SeekOrigin origin);
- public abstract void SetLength(long value);
- public static System.IO.Stream Synchronized(System.IO.Stream stream) { throw null; }
- public abstract void Write(byte[] buffer, int offset, int count);
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
- public virtual void WriteByte(byte value) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class StreamWriter : System.IO.TextWriter
- {
- public static readonly new System.IO.StreamWriter Null;
- public StreamWriter(System.IO.Stream stream) { }
- public StreamWriter(System.IO.Stream stream, System.Text.Encoding encoding) { }
- public StreamWriter(System.IO.Stream stream, System.Text.Encoding encoding, int bufferSize) { }
- public StreamWriter(System.IO.Stream stream, System.Text.Encoding encoding, int bufferSize, bool leaveOpen) { }
- public StreamWriter(string path) { }
- public StreamWriter(string path, bool append) { }
- public StreamWriter(string path, bool append, System.Text.Encoding encoding) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public StreamWriter(string path, bool append, System.Text.Encoding encoding, int bufferSize) { }
- public virtual bool AutoFlush { get { throw null; } set { } }
- public virtual System.IO.Stream BaseStream { get { throw null; } }
- public override System.Text.Encoding Encoding { get { throw null; } }
- public override void Close() { }
- protected override void Dispose(bool disposing) { }
- public override void Flush() { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task FlushAsync() { throw null; }
- public override void Write(char value) { }
- public override void Write(char[] buffer) { }
- public override void Write(char[] buffer, int index, int count) { }
- public override void Write(string value) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task WriteAsync(char value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task WriteAsync(char[] buffer, int index, int count) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task WriteAsync(string value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task WriteLineAsync() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task WriteLineAsync(char value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task WriteLineAsync(char[] buffer, int index, int count) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task WriteLineAsync(string value) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class StringWriter : System.IO.TextWriter
- {
- public StringWriter() { }
- public StringWriter(System.IFormatProvider formatProvider) { }
- public StringWriter(System.Text.StringBuilder sb) { }
- public StringWriter(System.Text.StringBuilder sb, System.IFormatProvider formatProvider) { }
- public override System.Text.Encoding Encoding { get { throw null; } }
- public override void Close() { }
- protected override void Dispose(bool disposing) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task FlushAsync() { throw null; }
- public virtual System.Text.StringBuilder GetStringBuilder() { throw null; }
- public override string ToString() { throw null; }
- public override void Write(char value) { }
- public override void Write(char[] buffer, int index, int count) { }
- public override void Write(string value) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task WriteAsync(char value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task WriteAsync(char[] buffer, int index, int count) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task WriteAsync(string value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task WriteLineAsync(char value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task WriteLineAsync(char[] buffer, int index, int count) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task WriteLineAsync(string value) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class TextWriter : System.IDisposable
- {
- protected char[] CoreNewLine;
- public static readonly System.IO.TextWriter Null;
- protected TextWriter() { }
- protected TextWriter(System.IFormatProvider formatProvider) { }
- public abstract System.Text.Encoding Encoding { get; }
- public virtual System.IFormatProvider FormatProvider { get { throw null; } }
- public virtual string NewLine { get { throw null; } set { } }
- public virtual void Close() { }
- public void Dispose() { }
- protected virtual void Dispose(bool disposing) { }
- public virtual void Flush() { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Threading.Tasks.Task FlushAsync() { throw null; }
- public static System.IO.TextWriter Synchronized(System.IO.TextWriter writer) { throw null; }
- public virtual void Write(bool value) { }
- public virtual void Write(char value) { }
- public virtual void Write(char[] buffer) { }
- public virtual void Write(char[] buffer, int index, int count) { }
- public virtual void Write(decimal value) { }
- public virtual void Write(double value) { }
- public virtual void Write(int value) { }
- public virtual void Write(long value) { }
- public virtual void Write(object value) { }
- public virtual void Write(float value) { }
- public virtual void Write(string value) { }
- public virtual void Write(string format, object arg0) { }
- public virtual void Write(string format, object arg0, object arg1) { }
- public virtual void Write(string format, object arg0, object arg1, object arg2) { }
- public virtual void Write(string format, params object[] arg) { }
- [System.CLSCompliantAttribute(false)]
- public virtual void Write(uint value) { }
- [System.CLSCompliantAttribute(false)]
- public virtual void Write(ulong value) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Threading.Tasks.Task WriteAsync(char value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Threading.Tasks.Task WriteAsync(char[] buffer) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Threading.Tasks.Task WriteAsync(char[] buffer, int index, int count) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Threading.Tasks.Task WriteAsync(string value) { throw null; }
- public virtual void WriteLine() { }
- public virtual void WriteLine(bool value) { }
- public virtual void WriteLine(char value) { }
- public virtual void WriteLine(char[] buffer) { }
- public virtual void WriteLine(char[] buffer, int index, int count) { }
- public virtual void WriteLine(decimal value) { }
- public virtual void WriteLine(double value) { }
- public virtual void WriteLine(int value) { }
- public virtual void WriteLine(long value) { }
- public virtual void WriteLine(object value) { }
- public virtual void WriteLine(float value) { }
- public virtual void WriteLine(string value) { }
- public virtual void WriteLine(string format, object arg0) { }
- public virtual void WriteLine(string format, object arg0, object arg1) { }
- public virtual void WriteLine(string format, object arg0, object arg1, object arg2) { }
- public virtual void WriteLine(string format, params object[] arg) { }
- [System.CLSCompliantAttribute(false)]
- public virtual void WriteLine(uint value) { }
- [System.CLSCompliantAttribute(false)]
- public virtual void WriteLine(ulong value) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Threading.Tasks.Task WriteLineAsync() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Threading.Tasks.Task WriteLineAsync(char value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Threading.Tasks.Task WriteLineAsync(char[] buffer) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Threading.Tasks.Task WriteLineAsync(char[] buffer, int index, int count) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Threading.Tasks.Task WriteLineAsync(string value) { throw null; }
- }
- public partial class UnmanagedMemoryAccessor : System.IDisposable
- {
- protected UnmanagedMemoryAccessor() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public UnmanagedMemoryAccessor(System.Runtime.InteropServices.SafeBuffer buffer, long offset, long capacity) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public UnmanagedMemoryAccessor(System.Runtime.InteropServices.SafeBuffer buffer, long offset, long capacity, System.IO.FileAccess access) { }
- public bool CanRead { get { throw null; } }
- public bool CanWrite { get { throw null; } }
- public long Capacity { get { throw null; } }
- protected bool IsOpen { get { throw null; } }
- public void Dispose() { }
- protected virtual void Dispose(bool disposing) { }
- [System.Security.SecuritySafeCriticalAttribute]
- protected void Initialize(System.Runtime.InteropServices.SafeBuffer buffer, long offset, long capacity, System.IO.FileAccess access) { }
- [System.Security.SecurityCriticalAttribute]
- public void Read<T>(long position, out T structure) where T : struct { structure = default(T); throw null; }
- [System.Security.SecurityCriticalAttribute]
- public int ReadArray<T>(long position, T[] array, int offset, int count) where T : struct { throw null; }
- public bool ReadBoolean(long position) { throw null; }
- public byte ReadByte(long position) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public char ReadChar(long position) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public decimal ReadDecimal(long position) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public double ReadDouble(long position) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public short ReadInt16(long position) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public int ReadInt32(long position) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public long ReadInt64(long position) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public sbyte ReadSByte(long position) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public float ReadSingle(long position) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public ushort ReadUInt16(long position) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public uint ReadUInt32(long position) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public ulong ReadUInt64(long position) { throw null; }
- public void Write(long position, bool value) { }
- public void Write(long position, byte value) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write(long position, char value) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write(long position, decimal value) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write(long position, double value) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write(long position, short value) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write(long position, int value) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write(long position, long value) { }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write(long position, sbyte value) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write(long position, float value) { }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write(long position, ushort value) { }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write(long position, uint value) { }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public void Write(long position, ulong value) { }
- [System.Security.SecurityCriticalAttribute]
- public void Write<T>(long position, ref T structure) where T : struct { }
- [System.Security.SecurityCriticalAttribute]
- public void WriteArray<T>(long position, T[] array, int offset, int count) where T : struct { }
- }
- public partial class UnmanagedMemoryStream : System.IO.Stream
- {
- [System.Security.SecuritySafeCriticalAttribute]
- protected UnmanagedMemoryStream() { }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe UnmanagedMemoryStream(byte* pointer, long length) { }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, System.IO.FileAccess access) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public UnmanagedMemoryStream(System.Runtime.InteropServices.SafeBuffer buffer, long offset, long length) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public UnmanagedMemoryStream(System.Runtime.InteropServices.SafeBuffer buffer, long offset, long length, System.IO.FileAccess access) { }
- public override bool CanRead { get { throw null; } }
- public override bool CanSeek { get { throw null; } }
- public override bool CanWrite { get { throw null; } }
- public long Capacity { get { throw null; } }
- public override long Length { get { throw null; } }
- public override long Position { get { throw null; } [System.Security.SecuritySafeCriticalAttribute]set { } }
- [System.CLSCompliantAttribute(false)]
- public unsafe byte* PositionPointer { [System.Security.SecurityCriticalAttribute]get { throw null; } [System.Security.SecurityCriticalAttribute]set { } }
- [System.Security.SecuritySafeCriticalAttribute]
- protected override void Dispose(bool disposing) { }
- public override void Flush() { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- protected unsafe void Initialize(byte* pointer, long length, long capacity, System.IO.FileAccess access) { }
- [System.Security.SecuritySafeCriticalAttribute]
- protected void Initialize(System.Runtime.InteropServices.SafeBuffer buffer, long offset, long length, System.IO.FileAccess access) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public override int Read(byte[] buffer, int offset, int count) { buffer = default(byte[]); throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task<int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override int ReadByte() { throw null; }
- public override long Seek(long offset, System.IO.SeekOrigin loc) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override void SetLength(long value) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public override void Write(byte[] buffer, int offset, int count) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override void WriteByte(byte value) { }
- }
-}
-namespace System.Reflection
-{
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AmbiguousMatchException : System.SystemException
- {
- public AmbiguousMatchException() { }
- public AmbiguousMatchException(string message) { }
- public AmbiguousMatchException(string message, System.Exception inner) { }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class Assembly : System.Reflection.ICustomAttributeProvider, System.Runtime.Serialization.ISerializable
- {
- protected Assembly() { }
- public virtual string CodeBase { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- public virtual System.Collections.Generic.IEnumerable<System.Reflection.CustomAttributeData> CustomAttributes { get { throw null; } }
- public virtual System.Collections.Generic.IEnumerable<System.Reflection.TypeInfo> DefinedTypes { get { throw null; } }
- public virtual System.Reflection.MethodInfo EntryPoint { get { throw null; } }
- public virtual string EscapedCodeBase { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- public virtual System.Collections.Generic.IEnumerable<System.Type> ExportedTypes { get { throw null; } }
- public virtual string FullName { get { throw null; } }
- public virtual bool GlobalAssemblyCache { get { throw null; } }
- public virtual Int64 HostContext { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual string ImageRuntimeVersion { get { throw null; } }
- public virtual bool IsDynamic { get { throw null; } }
- public bool IsFullyTrusted { get { throw null; } }
- public virtual string Location { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Reflection.Module ManifestModule { get { throw null; } }
- public virtual event ModuleResolveEventHandler ModuleResolve { [System.Security.SecurityCriticalAttribute]add { } [System.Security.SecurityCriticalAttribute]remove { } }
- public virtual System.Collections.Generic.IEnumerable<System.Reflection.Module> Modules { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual bool ReflectionOnly { get { throw null; } }
- public virtual System.Security.SecurityRuleSet SecurityRuleSet { get { throw null; } }
- public object CreateInstance(string typeName) { throw null; }
- public object CreateInstance(string typeName, bool ignoreCase) { throw null; }
- public virtual object CreateInstance(String typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, System.Globalization.CultureInfo culture, Object[] activationAttributes) { throw null; }
- public static string CreateQualifiedName(string assemblyName, string typeName) { throw null; }
- public override bool Equals(object o) { throw null; }
- public static Assembly GetAssembly(Type type) { throw null; }
- public static bool operator ==(System.Reflection.Assembly left, System.Reflection.Assembly right) { throw null; }
- public static bool operator !=(System.Reflection.Assembly left, System.Reflection.Assembly right) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public static System.Reflection.Assembly GetCallingAssembly() { throw null; }
- public virtual object[] GetCustomAttributes(bool inherit) { throw null; }
- public virtual object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; }
- public virtual System.Collections.Generic.IList<CustomAttributeData> GetCustomAttributesData() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Reflection.Assembly GetEntryAssembly() { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public static System.Reflection.Assembly GetExecutingAssembly() { throw null; }
- public virtual System.Type[] GetExportedTypes() { throw null; }
- public virtual System.IO.FileStream GetFile(string name) { throw null; }
- public virtual System.IO.FileStream[] GetFiles() { throw null; }
- public virtual System.IO.FileStream[] GetFiles(bool getResourceModules) { throw null; }
- public override int GetHashCode() { throw null; }
- public System.Reflection.Module[] GetLoadedModules() { throw null; }
- public virtual System.Reflection.Module[] GetLoadedModules(bool getResourceModules) { throw null; }
- public virtual System.Reflection.ManifestResourceInfo GetManifestResourceInfo(string resourceName) { throw null; }
- public virtual string[] GetManifestResourceNames() { throw null; }
- public virtual System.IO.Stream GetManifestResourceStream(string name) { throw null; }
- public virtual System.IO.Stream GetManifestResourceStream(System.Type type, string name) { throw null; }
- public virtual System.Reflection.Module GetModule(String name) { throw null; }
- public System.Reflection.Module[] GetModules() { throw null; }
- public virtual System.Reflection.Module[] GetModules(bool getResourceModules) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public virtual System.Reflection.AssemblyName GetName(bool copiedName) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public virtual System.Reflection.AssemblyName GetName() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public virtual System.Reflection.AssemblyName[] GetReferencedAssemblies() { throw null; }
- public virtual System.Reflection.Assembly GetSatelliteAssembly(System.Globalization.CultureInfo culture) { throw null; }
- public virtual System.Reflection.Assembly GetSatelliteAssembly(System.Globalization.CultureInfo culture, System.Version version) { throw null; }
- public virtual System.Type GetType(string name) { throw null; }
- public virtual System.Type GetType(string name, bool throwOnError) { throw null; }
- public virtual System.Type GetType(string name, bool throwOnError, bool ignoreCase) { throw null; }
- public virtual System.Type[] GetTypes() { throw null; }
- public virtual bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecurityCriticalAttribute]
- public static System.Reflection.Assembly Load(byte[] rawAssembly) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecurityCriticalAttribute]
- public static System.Reflection.Assembly Load(byte[] rawAssembly, byte[] rawSymbolStore) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecurityCriticalAttribute]
- public static System.Reflection.Assembly Load(System.Reflection.AssemblyName assemblyRef) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public static System.Reflection.Assembly Load(string assemblyString) { throw null; }
- public static System.Reflection.Assembly LoadFile(String path) { throw null; }
- public static System.Reflection.Assembly LoadFrom(String path) { throw null; }
- public static Assembly LoadFrom(string assemblyFile, byte[] hashValue, System.Configuration.Assemblies.AssemblyHashAlgorithm hashAlgorithm) { throw null; }
- public System.Reflection.Module LoadModule(String moduleName, byte[] rawModule) { throw null; }
- public System.Reflection.Module LoadModule(String moduleName, byte[] rawModule, byte[] rawSymbolStore) { throw null; }
- [ObsoleteAttribute("This method has been deprecated. Please use Assembly.Load() instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- public static Assembly LoadWithPartialName(string partialName) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public static Assembly ReflectionOnlyLoad(byte[] rawAssembly) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public static Assembly ReflectionOnlyLoad(String assemblyString) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public static Assembly ReflectionOnlyLoadFrom(string assemblyFile) { throw null; }
- public override string ToString() { throw null; }
- public static Assembly UnsafeLoadFrom(string assemblyFile) { throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyAlgorithmIdAttribute : System.Attribute
- {
- public AssemblyAlgorithmIdAttribute(System.Configuration.Assemblies.AssemblyHashAlgorithm algorithmId) { }
- [System.CLSCompliantAttribute(false)]
- public AssemblyAlgorithmIdAttribute(uint algorithmId) { }
- [System.CLSCompliantAttribute(false)]
- public uint AlgorithmId { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyCompanyAttribute : System.Attribute
- {
- public AssemblyCompanyAttribute(string company) { }
- public string Company { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyConfigurationAttribute : System.Attribute
- {
- public AssemblyConfigurationAttribute(string configuration) { }
- public string Configuration { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public enum AssemblyContentType
- {
- Default = 0,
- WindowsRuntime = 1,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyCopyrightAttribute : System.Attribute
- {
- public AssemblyCopyrightAttribute(string copyright) { }
- public string Copyright { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyCultureAttribute : System.Attribute
- {
- public AssemblyCultureAttribute(string culture) { }
- public string Culture { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyDefaultAliasAttribute : System.Attribute
- {
- public AssemblyDefaultAliasAttribute(string defaultAlias) { }
- public string DefaultAlias { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyDelaySignAttribute : System.Attribute
- {
- public AssemblyDelaySignAttribute(bool delaySign) { }
- public bool DelaySign { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyDescriptionAttribute : System.Attribute
- {
- public AssemblyDescriptionAttribute(string description) { }
- public string Description { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyFileVersionAttribute : System.Attribute
- {
- public AssemblyFileVersionAttribute(string version) { }
- public string Version { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyFlagsAttribute : System.Attribute
- {
- [System.CLSCompliantAttribute(false)]
- public AssemblyFlagsAttribute(uint flags) { }
- public AssemblyFlagsAttribute(int assemblyFlags) { }
- public AssemblyFlagsAttribute(System.Reflection.AssemblyNameFlags assemblyFlags) { }
- public int AssemblyFlags { get { throw null; } }
- [System.CLSCompliantAttribute(false)]
- public uint Flags { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyInformationalVersionAttribute : System.Attribute
- {
- public AssemblyInformationalVersionAttribute(string informationalVersion) { }
- public string InformationalVersion { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyKeyFileAttribute : System.Attribute
- {
- public AssemblyKeyFileAttribute(string keyFile) { }
- public string KeyFile { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyKeyNameAttribute : System.Attribute
- {
- public AssemblyKeyNameAttribute(string keyName) { }
- public string KeyName { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=true, Inherited=false)]
- public sealed partial class AssemblyMetadataAttribute : System.Attribute
- {
- public AssemblyMetadataAttribute(string key, string value) { }
- public string Key { get { throw null; } }
- public string Value { get { throw null; } }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyName : System.ICloneable, System.Runtime.Serialization.ISerializable, System.Runtime.Serialization.IDeserializationCallback
- {
- public AssemblyName() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public AssemblyName(string assemblyName) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Reflection.AssemblyContentType ContentType { get { throw null; } set { } }
- public System.Globalization.CultureInfo CultureInfo { get { throw null; } set { } }
- public string CultureName { [System.Security.SecurityCriticalAttribute]get { throw null; } [System.Security.SecurityCriticalAttribute]set { } }
- public string CodeBase { get { throw null; } set { } }
- public string EscapedCodeBase { get { throw null; } }
- public System.Reflection.AssemblyNameFlags Flags { get { throw null; } set { } }
- public string FullName { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public System.Configuration.Assemblies.AssemblyHashAlgorithm HashAlgorithm { get { throw null; } set { } }
- public System.Reflection.StrongNameKeyPair KeyPair { get { throw null; } set { } }
- public System.Configuration.Assemblies.AssemblyVersionCompatibility VersionCompatibility { get { throw null; } set { } }
- public string Name { get { throw null; } set { } }
- public System.Reflection.ProcessorArchitecture ProcessorArchitecture { get { throw null; } set { } }
- public System.Version Version { get { throw null; } set { } }
- public object Clone() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Reflection.AssemblyName GetAssemblyName(System.String assemblyFile) { throw null; }
- public byte[] GetPublicKey() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public byte[] GetPublicKeyToken() { throw null; }
- public void SetPublicKey(byte[] publicKey) { }
- public void SetPublicKeyToken(byte[] publicKeyToken) { }
- public override string ToString() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { throw null; }
- public void OnDeserialization(Object sender) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool ReferenceMatchesDefinition(System.Reflection.AssemblyName reference, System.Reflection.AssemblyName definition) { throw null; }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum AssemblyNameFlags
- {
- EnableJITcompileOptimizer = 16384,
- EnableJITcompileTracking = 32768,
- None = 0,
- PublicKey = 1,
- Retargetable = 256,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyProductAttribute : System.Attribute
- {
- public AssemblyProductAttribute(string product) { }
- public string Product { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false, AllowMultiple=false)]
- public sealed partial class AssemblySignatureKeyAttribute : System.Attribute
- {
- public AssemblySignatureKeyAttribute(string publicKey, string countersignature) { }
- public string Countersignature { get { throw null; } }
- public string PublicKey { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyTitleAttribute : System.Attribute
- {
- public AssemblyTitleAttribute(string title) { }
- public string Title { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyTrademarkAttribute : System.Attribute
- {
- public AssemblyTrademarkAttribute(string trademark) { }
- public string Trademark { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyVersionAttribute : System.Attribute
- {
- public AssemblyVersionAttribute(string version) { }
- public string Version { get { throw null; } }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(2))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class Binder
- {
- protected Binder() { }
- public abstract System.Reflection.FieldInfo BindToField(System.Reflection.BindingFlags bindingAttr, System.Reflection.FieldInfo[] match, object value, System.Globalization.CultureInfo culture);
- public abstract System.Reflection.MethodBase BindToMethod(System.Reflection.BindingFlags bindingAttr, System.Reflection.MethodBase[] match, ref object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] names, out object state);
- public abstract object ChangeType(object value, System.Type type, System.Globalization.CultureInfo culture);
- public abstract void ReorderArgumentArray(ref object[] args, object state);
- public abstract System.Reflection.MethodBase SelectMethod(System.Reflection.BindingFlags bindingAttr, System.Reflection.MethodBase[] match, System.Type[] types, System.Reflection.ParameterModifier[] modifiers);
- public abstract System.Reflection.PropertyInfo SelectProperty(System.Reflection.BindingFlags bindingAttr, System.Reflection.PropertyInfo[] match, System.Type returnType, System.Type[] indexes, System.Reflection.ParameterModifier[] modifiers);
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum BindingFlags
- {
- CreateInstance = 512,
- DeclaredOnly = 2,
- Default = 0,
- ExactBinding = 65536,
- FlattenHierarchy = 64,
- GetField = 1024,
- GetProperty = 4096,
- IgnoreCase = 1,
- IgnoreReturn = 16777216,
- Instance = 4,
- InvokeMethod = 256,
- NonPublic = 32,
- OptionalParamBinding = 262144,
- Public = 16,
- PutDispProperty = 16384,
- PutRefDispProperty = 32768,
- SetField = 2048,
- SetProperty = 8192,
- Static = 8,
- SuppressChangeType = 131072,
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum CallingConventions
- {
- Any = 3,
- ExplicitThis = 64,
- HasThis = 32,
- Standard = 1,
- VarArgs = 2,
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class ConstructorInfo : System.Reflection.MethodBase
- {
- public static bool operator ==(System.Reflection.ConstructorInfo left, System.Reflection.ConstructorInfo right) { throw null; }
- public static bool operator !=(System.Reflection.ConstructorInfo left, System.Reflection.ConstructorInfo right) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static readonly string ConstructorName;
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static readonly string TypeConstructorName;
- protected ConstructorInfo() { }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public override System.Reflection.MemberTypes MemberType { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- [System.Diagnostics.DebuggerHiddenAttribute]
- [System.Diagnostics.DebuggerStepThroughAttribute]
- public object Invoke(object[] parameters) { throw null; }
- public abstract object Invoke(System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class CustomAttributeData
- {
- protected CustomAttributeData() { }
- public System.Type AttributeType { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public virtual System.Reflection.ConstructorInfo Constructor { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public virtual System.Collections.Generic.IList<System.Reflection.CustomAttributeTypedArgument> ConstructorArguments { get { throw null; } }
- public virtual System.Collections.Generic.IList<System.Reflection.CustomAttributeNamedArgument> NamedArguments { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public static System.Collections.Generic.IList<System.Reflection.CustomAttributeData> GetCustomAttributes(System.Reflection.Assembly target) { throw null; }
- public static System.Collections.Generic.IList<System.Reflection.CustomAttributeData> GetCustomAttributes(System.Reflection.MemberInfo target) { throw null; }
- public static System.Collections.Generic.IList<System.Reflection.CustomAttributeData> GetCustomAttributes(System.Reflection.Module target) { throw null; }
- public static System.Collections.Generic.IList<System.Reflection.CustomAttributeData> GetCustomAttributes(System.Reflection.ParameterInfo target) { throw null; }
- public override int GetHashCode() { throw null; }
- public override string ToString() { throw null; }
- }
- public static partial class CustomAttributeExtensions
- {
- public static System.Attribute GetCustomAttribute(this System.Reflection.Assembly element, System.Type attributeType) { throw null; }
- public static System.Attribute GetCustomAttribute(this System.Reflection.MemberInfo element, System.Type attributeType) { throw null; }
- public static System.Attribute GetCustomAttribute(this System.Reflection.MemberInfo element, System.Type attributeType, bool inherit) { throw null; }
- public static System.Attribute GetCustomAttribute(this System.Reflection.Module element, System.Type attributeType) { throw null; }
- public static System.Attribute GetCustomAttribute(this System.Reflection.ParameterInfo element, System.Type attributeType) { throw null; }
- public static System.Attribute GetCustomAttribute(this System.Reflection.ParameterInfo element, System.Type attributeType, bool inherit) { throw null; }
- public static T GetCustomAttribute<T>(this System.Reflection.Assembly element) where T : System.Attribute { throw null; }
- public static T GetCustomAttribute<T>(this System.Reflection.MemberInfo element) where T : System.Attribute { throw null; }
- public static T GetCustomAttribute<T>(this System.Reflection.MemberInfo element, bool inherit) where T : System.Attribute { throw null; }
- public static T GetCustomAttribute<T>(this System.Reflection.Module element) where T : System.Attribute { throw null; }
- public static T GetCustomAttribute<T>(this System.Reflection.ParameterInfo element) where T : System.Attribute { throw null; }
- public static T GetCustomAttribute<T>(this System.Reflection.ParameterInfo element, bool inherit) where T : System.Attribute { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Attribute> GetCustomAttributes(this System.Reflection.Assembly element) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Attribute> GetCustomAttributes(this System.Reflection.Assembly element, System.Type attributeType) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Attribute> GetCustomAttributes(this System.Reflection.MemberInfo element) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Attribute> GetCustomAttributes(this System.Reflection.MemberInfo element, bool inherit) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Attribute> GetCustomAttributes(this System.Reflection.MemberInfo element, System.Type attributeType) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Attribute> GetCustomAttributes(this System.Reflection.MemberInfo element, System.Type attributeType, bool inherit) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Attribute> GetCustomAttributes(this System.Reflection.Module element) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Attribute> GetCustomAttributes(this System.Reflection.Module element, System.Type attributeType) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Attribute> GetCustomAttributes(this System.Reflection.ParameterInfo element) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Attribute> GetCustomAttributes(this System.Reflection.ParameterInfo element, bool inherit) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Attribute> GetCustomAttributes(this System.Reflection.ParameterInfo element, System.Type attributeType) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Attribute> GetCustomAttributes(this System.Reflection.ParameterInfo element, System.Type attributeType, bool inherit) { throw null; }
- public static System.Collections.Generic.IEnumerable<T> GetCustomAttributes<T>(this System.Reflection.Assembly element) where T : System.Attribute { throw null; }
- public static System.Collections.Generic.IEnumerable<T> GetCustomAttributes<T>(this System.Reflection.MemberInfo element) where T : System.Attribute { throw null; }
- public static System.Collections.Generic.IEnumerable<T> GetCustomAttributes<T>(this System.Reflection.MemberInfo element, bool inherit) where T : System.Attribute { throw null; }
- public static System.Collections.Generic.IEnumerable<T> GetCustomAttributes<T>(this System.Reflection.Module element) where T : System.Attribute { throw null; }
- public static System.Collections.Generic.IEnumerable<T> GetCustomAttributes<T>(this System.Reflection.ParameterInfo element) where T : System.Attribute { throw null; }
- public static System.Collections.Generic.IEnumerable<T> GetCustomAttributes<T>(this System.Reflection.ParameterInfo element, bool inherit) where T : System.Attribute { throw null; }
- public static bool IsDefined(this System.Reflection.Assembly element, System.Type attributeType) { throw null; }
- public static bool IsDefined(this System.Reflection.MemberInfo element, System.Type attributeType) { throw null; }
- public static bool IsDefined(this System.Reflection.MemberInfo element, System.Type attributeType, bool inherit) { throw null; }
- public static bool IsDefined(this System.Reflection.Module element, System.Type attributeType) { throw null; }
- public static bool IsDefined(this System.Reflection.ParameterInfo element, System.Type attributeType) { throw null; }
- public static bool IsDefined(this System.Reflection.ParameterInfo element, System.Type attributeType, bool inherit) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class CustomAttributeFormatException : System.FormatException
- {
- public CustomAttributeFormatException() { }
- public CustomAttributeFormatException(string message) { }
- public CustomAttributeFormatException(string message, System.Exception inner) { }
- protected CustomAttributeFormatException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct CustomAttributeNamedArgument
- {
- public CustomAttributeNamedArgument(System.Reflection.MemberInfo memberInfo, object value) { }
- public CustomAttributeNamedArgument(System.Reflection.MemberInfo memberInfo, System.Reflection.CustomAttributeTypedArgument typedArgument) { }
- public bool IsField { get { throw null; } }
- public System.Reflection.MemberInfo MemberInfo { get { throw null; } }
- public string MemberName { get { throw null; } }
- public System.Reflection.CustomAttributeTypedArgument TypedValue { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Reflection.CustomAttributeNamedArgument left, System.Reflection.CustomAttributeNamedArgument right) { throw null; }
- public static bool operator !=(System.Reflection.CustomAttributeNamedArgument left, System.Reflection.CustomAttributeNamedArgument right) { throw null; }
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct CustomAttributeTypedArgument
- {
- public CustomAttributeTypedArgument(System.Type argumentType, object value) { }
- public CustomAttributeTypedArgument(object value) { }
- public System.Type ArgumentType { get { throw null; } }
- public object Value { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Reflection.CustomAttributeTypedArgument left, System.Reflection.CustomAttributeTypedArgument right) { throw null; }
- public static bool operator !=(System.Reflection.CustomAttributeTypedArgument left, System.Reflection.CustomAttributeTypedArgument right) { throw null; }
- public override string ToString() { throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1036))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DefaultMemberAttribute : System.Attribute
- {
- public DefaultMemberAttribute(string memberName) { }
- public string MemberName { get { throw null; } }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum EventAttributes
- {
- None = 0,
- ReservedMask = 1024,
- RTSpecialName = 1024,
- SpecialName = 512,
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class EventInfo : System.Reflection.MemberInfo
- {
- protected EventInfo() { }
- public static bool operator ==(System.Reflection.EventInfo left, System.Reflection.EventInfo right) { throw null; }
- public static bool operator !=(System.Reflection.EventInfo left, System.Reflection.EventInfo right) { throw null; }
- public virtual System.Reflection.MethodInfo AddMethod { get { throw null; } }
- public abstract System.Reflection.EventAttributes Attributes { get; }
- public virtual System.Type EventHandlerType { get { throw null; } }
- public virtual bool IsMulticast { get { throw null; } }
- public bool IsSpecialName { get { throw null; } }
- public override System.Reflection.MemberTypes MemberType { get { throw null; } }
- public virtual System.Reflection.MethodInfo RaiseMethod { get { throw null; } }
- public virtual System.Reflection.MethodInfo RemoveMethod { get { throw null; } }
- [System.Diagnostics.DebuggerHiddenAttribute]
- [System.Diagnostics.DebuggerStepThroughAttribute]
- public virtual void AddEventHandler(object target, System.Delegate handler) { }
- public override bool Equals(object obj) { throw null; }
- public System.Reflection.MethodInfo GetAddMethod() { throw null; }
- public abstract System.Reflection.MethodInfo GetAddMethod(bool nonPublic);
- public override int GetHashCode() { throw null; }
- public System.Reflection.MethodInfo[] GetOtherMethods() { throw null; }
- public virtual System.Reflection.MethodInfo[] GetOtherMethods(bool nonPublic) { throw null; }
- public System.Reflection.MethodInfo GetRaiseMethod() { throw null; }
- public abstract System.Reflection.MethodInfo GetRaiseMethod(bool nonPublic);
- public System.Reflection.MethodInfo GetRemoveMethod() { throw null; }
- public abstract System.Reflection.MethodInfo GetRemoveMethod(bool nonPublic);
- [System.Diagnostics.DebuggerHiddenAttribute]
- [System.Diagnostics.DebuggerStepThroughAttribute]
- public virtual void RemoveEventHandler(object target, System.Delegate handler) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public class ExceptionHandlingClause
- {
- protected ExceptionHandlingClause() { }
- public virtual System.Reflection.ExceptionHandlingClauseOptions Flags { get { throw null; } }
- public virtual int TryOffset { get { throw null; } }
- public virtual int TryLength { get { throw null; } }
- public virtual int HandlerOffset { get { throw null; } }
- public virtual int HandlerLength { get { throw null; } }
- public virtual int FilterOffset { get { throw null; } }
- public virtual System.Type CatchType { get { throw null; } }
- public override string ToString() { throw null; }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum ExceptionHandlingClauseOptions: int
- {
- Clause = 0,
- Filter = 1,
- Finally = 2,
- Fault = 4,
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum FieldAttributes
- {
- Assembly = 3,
- FamANDAssem = 2,
- Family = 4,
- FamORAssem = 5,
- FieldAccessMask = 7,
- HasDefault = 32768,
- HasFieldMarshal = 4096,
- HasFieldRVA = 256,
- InitOnly = 32,
- Literal = 64,
- NotSerialized = 128,
- PinvokeImpl = 8192,
- Private = 1,
- PrivateScope = 0,
- Public = 6,
- ReservedMask = 38144,
- RTSpecialName = 1024,
- SpecialName = 512,
- Static = 16,
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class FieldInfo : System.Reflection.MemberInfo
- {
- protected FieldInfo() { }
- public static bool operator ==(System.Reflection.FieldInfo left, System.Reflection.FieldInfo right) { throw null; }
- public static bool operator !=(System.Reflection.FieldInfo left, System.Reflection.FieldInfo right) { throw null; }
- public abstract System.Reflection.FieldAttributes Attributes { get; }
- public abstract System.RuntimeFieldHandle FieldHandle { get; }
- public abstract System.Type FieldType { get; }
- public bool IsAssembly { get { throw null; } }
- public bool IsFamily { get { throw null; } }
- public bool IsFamilyAndAssembly { get { throw null; } }
- public bool IsFamilyOrAssembly { get { throw null; } }
- public bool IsInitOnly { get { throw null; } }
- public bool IsLiteral { get { throw null; } }
- public bool IsNotSerialized { get { throw null; } }
- public bool IsPinvokeImpl { get { throw null; } }
- public bool IsPrivate { get { throw null; } }
- public bool IsPublic { get { throw null; } }
- public virtual bool IsSecurityCritical { get { throw null; } }
- public virtual bool IsSecuritySafeCritical { get { throw null; } }
- public virtual bool IsSecurityTransparent { get { throw null; } }
- public bool IsSpecialName { get { throw null; } }
- public bool IsStatic { get { throw null; } }
- public override System.Reflection.MemberTypes MemberType { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public static System.Reflection.FieldInfo GetFieldFromHandle(System.RuntimeFieldHandle handle) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public static System.Reflection.FieldInfo GetFieldFromHandle(System.RuntimeFieldHandle handle, System.RuntimeTypeHandle declaringType) { throw null; }
- public override int GetHashCode() { throw null; }
- public virtual System.Type[] GetOptionalCustomModifiers() { throw null; }
- public virtual object GetRawConstantValue() { throw null; }
- public virtual System.Type[] GetRequiredCustomModifiers() { throw null; }
- public abstract object GetValue(object obj);
- [System.Diagnostics.DebuggerHiddenAttribute]
- [System.Diagnostics.DebuggerStepThroughAttribute]
- public void SetValue(object obj, object value) { }
- public abstract void SetValue(object obj, object value, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Globalization.CultureInfo culture);
- }
- [System.FlagsAttribute]
- public enum GenericParameterAttributes
- {
- Contravariant = 2,
- Covariant = 1,
- DefaultConstructorConstraint = 16,
- None = 0,
- NotNullableValueTypeConstraint = 8,
- ReferenceTypeConstraint = 4,
- SpecialConstraintMask = 28,
- VarianceMask = 3,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface ICustomAttributeProvider
- {
- object[] GetCustomAttributes(bool inherit);
- object[] GetCustomAttributes(System.Type attributeType, bool inherit);
- bool IsDefined(System.Type attributeType, bool inherit);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum ImageFileMachine
- {
- I386 = 332,
- IA64 = 512,
- AMD64 = 34404,
- ARM = 452,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct InterfaceMapping
- {
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public System.Reflection.MethodInfo[] InterfaceMethods;
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public System.Type InterfaceType;
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public System.Reflection.MethodInfo[] TargetMethods;
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public System.Type TargetType;
- }
- public static partial class IntrospectionExtensions
- {
- public static System.Reflection.TypeInfo GetTypeInfo(this System.Type type) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class InvalidFilterCriteriaException : System.ApplicationException
- {
- public InvalidFilterCriteriaException() { }
- public InvalidFilterCriteriaException(string message) { }
- public InvalidFilterCriteriaException(string message, System.Exception inner) { }
- protected InvalidFilterCriteriaException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.GuidAttribute("AFBF15E5-C37C-11d2-B88E-00A0C9B471B8")]
- public partial interface IReflect
- {
- System.Type UnderlyingSystemType { get; }
- System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr);
- System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr);
- System.Reflection.MemberInfo[] GetMember(string name, System.Reflection.BindingFlags bindingAttr);
- System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr);
- System.Reflection.MethodInfo GetMethod(string name, System.Reflection.BindingFlags bindingAttr);
- System.Reflection.MethodInfo GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Type[] types, System.Reflection.ParameterModifier[] modifiers);
- System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr);
- System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr);
- System.Reflection.PropertyInfo GetProperty(string name, System.Reflection.BindingFlags bindingAttr);
- System.Reflection.PropertyInfo GetProperty(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Type returnType, System.Type[] types, System.Reflection.ParameterModifier[] modifiers);
- object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters);
- }
- public partial interface IReflectableType
- {
- System.Reflection.TypeInfo GetTypeInfo();
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class LocalVariableInfo
- {
- protected LocalVariableInfo() { }
- public virtual bool IsPinned { get { throw null; } }
- public virtual int LocalIndex { get { throw null; } }
- public virtual System.Type LocalType { get { throw null; } }
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ManifestResourceInfo
- {
- public ManifestResourceInfo(System.Reflection.Assembly containingAssembly, string containingFileName, System.Reflection.ResourceLocation resourceLocation) { }
- public virtual string FileName { get { throw null; } }
- public virtual System.Reflection.Assembly ReferencedAssembly { get { throw null; } }
- public virtual System.Reflection.ResourceLocation ResourceLocation { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public delegate bool MemberFilter(System.Reflection.MemberInfo m, object filterCriteria);
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class MemberInfo : System.Reflection.ICustomAttributeProvider
- {
- protected MemberInfo() { }
- public static bool operator ==(System.Reflection.MemberInfo left, System.Reflection.MemberInfo right) { throw null; }
- public static bool operator !=(System.Reflection.MemberInfo left, System.Reflection.MemberInfo right) { throw null; }
- public virtual System.Collections.Generic.IEnumerable<System.Reflection.CustomAttributeData> CustomAttributes { get { throw null; } }
- public abstract System.Type DeclaringType { get; }
- public abstract System.Reflection.MemberTypes MemberType { get; }
- public virtual int MetadataToken { get { throw null; } }
- public virtual System.Reflection.Module Module { get { throw null; } }
- public abstract string Name { get; }
- public abstract System.Type ReflectedType { get; }
- public override bool Equals(object obj) { throw null; }
- public abstract object[] GetCustomAttributes(bool inherit);
- public abstract object[] GetCustomAttributes(System.Type attributeType, bool inherit);
- public virtual System.Collections.Generic.IList<System.Reflection.CustomAttributeData> GetCustomAttributesData() { throw null; }
- public override int GetHashCode() { throw null; }
- public abstract bool IsDefined(System.Type attributeType, bool inherit);
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum MemberTypes
- {
- All = 191,
- Constructor = 1,
- Custom = 64,
- Event = 2,
- Field = 4,
- Method = 8,
- NestedType = 128,
- Property = 16,
- TypeInfo = 32,
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum MethodAttributes
- {
- Abstract = 1024,
- Assembly = 3,
- CheckAccessOnOverride = 512,
- FamANDAssem = 2,
- Family = 4,
- FamORAssem = 5,
- Final = 32,
- HasSecurity = 16384,
- HideBySig = 128,
- MemberAccessMask = 7,
- NewSlot = 256,
- PinvokeImpl = 8192,
- Private = 1,
- PrivateScope = 0,
- Public = 6,
- RequireSecObject = 32768,
- ReservedMask = 53248,
- ReuseSlot = 0,
- RTSpecialName = 4096,
- SpecialName = 2048,
- Static = 16,
- UnmanagedExport = 8,
- Virtual = 64,
- VtableLayoutMask = 256,
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class MethodBase : System.Reflection.MemberInfo
- {
- protected MethodBase() { }
- public abstract System.Reflection.MethodAttributes Attributes { get; }
- public virtual System.Reflection.CallingConventions CallingConvention { get { throw null; } }
- public virtual bool ContainsGenericParameters { get { throw null; } }
- public bool IsAbstract { get { throw null; } }
- public bool IsAssembly { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public bool IsConstructor { get { throw null; } }
- public bool IsFamily { get { throw null; } }
- public bool IsFamilyAndAssembly { get { throw null; } }
- public bool IsFamilyOrAssembly { get { throw null; } }
- public bool IsFinal { get { throw null; } }
- public virtual bool IsGenericMethod { get { throw null; } }
- public virtual bool IsGenericMethodDefinition { get { throw null; } }
- public bool IsHideBySig { get { throw null; } }
- public bool IsPrivate { get { throw null; } }
- public bool IsPublic { get { throw null; } }
- public bool IsSpecialName { get { throw null; } }
- public bool IsStatic { get { throw null; } }
- public bool IsVirtual { get { throw null; } }
- public virtual bool IsSecurityCritical { get { throw null; } }
- public virtual bool IsSecurityTransparent { get { throw null; } }
- public abstract System.RuntimeMethodHandle MethodHandle { get; }
- public virtual System.Reflection.MethodImplAttributes MethodImplementationFlags { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public static bool operator ==(System.Reflection.MethodBase left, System.Reflection.MethodBase right) { throw null; }
- public static bool operator !=(System.Reflection.MethodBase left, System.Reflection.MethodBase right) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public static System.Reflection.MethodBase GetCurrentMethod() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public virtual System.Type[] GetGenericArguments() { throw null; }
- public override int GetHashCode() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual System.Reflection.MethodBody GetMethodBody() { throw null; }
- public static System.Reflection.MethodBase GetMethodFromHandle(System.RuntimeMethodHandle handle) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public static System.Reflection.MethodBase GetMethodFromHandle(System.RuntimeMethodHandle handle, System.RuntimeTypeHandle declaringType) { throw null; }
- public abstract System.Reflection.MethodImplAttributes GetMethodImplementationFlags();
- public abstract System.Reflection.ParameterInfo[] GetParameters();
- [System.Diagnostics.DebuggerHiddenAttribute]
- [System.Diagnostics.DebuggerStepThroughAttribute]
- public object Invoke(object obj, object[] parameters) { throw null; }
- public abstract object Invoke(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public class MethodBody
- {
- protected MethodBody() { }
- public virtual int LocalSignatureMetadataToken { get { throw null; } }
- public virtual System.Collections.Generic.IList<LocalVariableInfo> LocalVariables { get { throw null; } }
- public virtual int MaxStackSize { get { throw null; } }
- public virtual bool InitLocals { get { throw null; } }
- public virtual byte[] GetILAsByteArray() { throw null; }
- public virtual System.Collections.Generic.IList<ExceptionHandlingClause> ExceptionHandlingClauses { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum MethodImplAttributes
- {
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- AggressiveInlining = 256,
- CodeTypeMask = 3,
- ForwardRef = 16,
- IL = 0,
- InternalCall = 4096,
- Managed = 0,
- ManagedMask = 4,
- MaxMethodImplVal = 65535,
- Native = 1,
- NoInlining = 8,
- NoOptimization = 64,
- OPTIL = 2,
- PreserveSig = 128,
- Runtime = 3,
- Synchronized = 32,
- Unmanaged = 4,
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class MethodInfo : System.Reflection.MethodBase
- {
- protected MethodInfo() { }
- public static bool operator ==(System.Reflection.MethodInfo left, System.Reflection.MethodInfo right) { throw null; }
- public static bool operator !=(System.Reflection.MethodInfo left, System.Reflection.MethodInfo right) { throw null; }
- public override System.Reflection.MemberTypes MemberType { get { throw null; } }
- public virtual System.Reflection.ParameterInfo ReturnParameter { get { throw null; } }
- public virtual System.Type ReturnType { get { throw null; } }
- public abstract System.Reflection.ICustomAttributeProvider ReturnTypeCustomAttributes { get; }
- public virtual System.Delegate CreateDelegate(System.Type delegateType) { throw null; }
- public virtual System.Delegate CreateDelegate(System.Type delegateType, object target) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public abstract System.Reflection.MethodInfo GetBaseDefinition();
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public override System.Type[] GetGenericArguments() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public virtual System.Reflection.MethodInfo GetGenericMethodDefinition() { throw null; }
- public override int GetHashCode() { throw null; }
- public virtual System.Reflection.MethodInfo MakeGenericMethod(params System.Type[] typeArguments) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class Missing : System.Runtime.Serialization.ISerializable
- {
- internal Missing() { }
- public static readonly System.Reflection.Missing Value;
- [System.Security.SecurityCriticalAttribute]
- void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class Module : System.Reflection.ICustomAttributeProvider, System.Runtime.Serialization.ISerializable
- {
- public static readonly System.Reflection.TypeFilter FilterTypeName;
- public static readonly System.Reflection.TypeFilter FilterTypeNameIgnoreCase;
- protected Module() { }
- public static bool operator ==(System.Reflection.Module left, System.Reflection.Module right) { throw null; }
- public static bool operator !=(System.Reflection.Module left, System.Reflection.Module right) { throw null; }
- public virtual System.Reflection.Assembly Assembly { get { throw null; } }
- public System.ModuleHandle ModuleHandle { get { throw null; } }
- public virtual System.Collections.Generic.IEnumerable<System.Reflection.CustomAttributeData> CustomAttributes { get { throw null; } }
- public virtual string FullyQualifiedName { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- public virtual int MDStreamVersion { get { throw null; } }
- public virtual int MetadataToken { get { throw null; } }
- public virtual System.Guid ModuleVersionId { get { throw null; } }
- public virtual string Name { get { throw null; } }
- public virtual string ScopeName { get { throw null; } }
- public override bool Equals(object o) { throw null; }
- public virtual System.Type[] FindTypes(System.Reflection.TypeFilter filter, object filterCriteria) { throw null; }
- public virtual object[] GetCustomAttributes(bool inherit) { throw null; }
- public virtual object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; }
- public System.Reflection.FieldInfo GetField(string name) { throw null; }
- public virtual System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public System.Reflection.FieldInfo[] GetFields() { throw null; }
- public virtual System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingFlags) { throw null; }
- public override int GetHashCode() { throw null; }
- public System.Reflection.MethodInfo GetMethod(string name) { throw null; }
- public System.Reflection.MethodInfo GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- public System.Reflection.MethodInfo GetMethod(string name, System.Type[] types) { throw null; }
- protected virtual System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- public System.Reflection.MethodInfo[] GetMethods() { throw null; }
- public virtual System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingFlags) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public virtual void GetPEKind(out System.Reflection.PortableExecutableKinds peKind, out System.Reflection.ImageFileMachine machine) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public virtual System.Type GetType(string className) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public virtual System.Type GetType(string className, bool ignoreCase) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public virtual System.Type GetType(string className, bool throwOnError, bool ignoreCase) { throw null; }
- public virtual System.Type[] GetTypes() { throw null; }
- public virtual bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
- public virtual bool IsResource() { throw null; }
- public virtual System.Collections.Generic.IList<CustomAttributeData> GetCustomAttributesData() { throw null; }
- public System.Reflection.FieldInfo ResolveField(int metadataToken) { throw null; }
- public virtual System.Reflection.FieldInfo ResolveField(int metadataToken, System.Type[] genericTypeArguments, System.Type[] genericMethodArguments) { throw null; }
- public System.Reflection.MemberInfo ResolveMember(int metadataToken) { throw null; }
- public virtual System.Reflection.MemberInfo ResolveMember(int metadataToken, System.Type[] genericTypeArguments, System.Type[] genericMethodArguments) { throw null; }
- public System.Reflection.MethodBase ResolveMethod(int metadataToken) { throw null; }
- public virtual System.Reflection.MethodBase ResolveMethod(int metadataToken, System.Type[] genericTypeArguments, System.Type[] genericMethodArguments) { throw null; }
- public virtual byte[] ResolveSignature(int metadataToken) { throw null; }
- public virtual string ResolveString(int metadataToken) { throw null; }
- public System.Type ResolveType(int metadataToken) { throw null; }
- public virtual System.Type ResolveType(int metadataToken, System.Type[] genericTypeArguments, System.Type[] genericMethodArguments) { throw null; }
- public override string ToString() { throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=false, Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed class ObfuscateAssemblyAttribute : System.Attribute
- {
- public ObfuscateAssemblyAttribute(bool assemblyIsPrivate) { throw null; }
- public bool AssemblyIsPrivate { get { throw null; } }
- public bool StripAfterObfuscation { get { throw null; } set { } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1) | (System.AttributeTargets)(4) | (System.AttributeTargets)(8) | (System.AttributeTargets)(64) | (System.AttributeTargets)(2048) | (System.AttributeTargets)(256) | (System.AttributeTargets)(128) | (System.AttributeTargets)(512) | (System.AttributeTargets)(1024) | (System.AttributeTargets)(16) | (System.AttributeTargets)(4096),
- AllowMultiple = true, Inherited = false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed class ObfuscationAttribute: System.Attribute
- {
- public ObfuscationAttribute() { }
- public bool StripAfterObfuscation { get { throw null; } set { } }
- public bool Exclude { get { throw null; } set { } }
- public bool ApplyToMembers { get { throw null; } set { } }
- public string Feature { get { throw null; } set { } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public delegate System.Reflection.Module ModuleResolveEventHandler(object sender, System.ResolveEventArgs e);
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum ParameterAttributes
- {
- HasDefault = 4096,
- HasFieldMarshal = 8192,
- In = 1,
- Lcid = 4,
- None = 0,
- Optional = 16,
- Out = 2,
- Reserved3 = 16384,
- Reserved4 = 32768,
- ReservedMask = 61440,
- Retval = 8,
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ParameterInfo : System.Reflection.ICustomAttributeProvider, System.Runtime.Serialization.IObjectReference
- {
- protected String NameImpl;
- protected Type ClassImpl;
- protected int PositionImpl;
- protected System.Reflection.ParameterAttributes AttrsImpl;
- protected Object DefaultValueImpl;
- protected MemberInfo MemberImpl;
- protected ParameterInfo() { }
- public virtual System.Reflection.ParameterAttributes Attributes { get { throw null; } }
- public virtual System.Collections.Generic.IEnumerable<System.Reflection.CustomAttributeData> CustomAttributes { get { throw null; } }
- public virtual object DefaultValue { get { throw null; } }
- public virtual bool HasDefaultValue { get { throw null; } }
- public bool IsIn { get { throw null; } }
- public bool IsLcid { get { throw null; } }
- public bool IsOptional { get { throw null; } }
- public bool IsOut { get { throw null; } }
- public bool IsRetval { get { throw null; } }
- public virtual System.Reflection.MemberInfo Member { get { throw null; } }
- public virtual int MetadataToken { get { throw null; } }
- public virtual string Name { get { throw null; } }
- public virtual System.Type ParameterType { get { throw null; } }
- public virtual int Position { get { throw null; } }
- public virtual object RawDefaultValue { get { throw null; } }
- public virtual object[] GetCustomAttributes(bool inherit) { throw null; }
- public virtual object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; }
- public virtual System.Collections.Generic.IList<System.Reflection.CustomAttributeData> GetCustomAttributesData() { throw null; }
- public virtual System.Type[] GetOptionalCustomModifiers() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public object GetRealObject(System.Runtime.Serialization.StreamingContext context) { throw null; }
- public virtual System.Type[] GetRequiredCustomModifiers() { throw null; }
- public virtual bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct ParameterModifier
- {
- public ParameterModifier(int parameterCount) { throw null;}
- public bool this[int index] { get { throw null; } set { } }
- }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed class Pointer : System.Runtime.Serialization.ISerializable
- {
- private Pointer() { }
- [System.Security.SecurityCriticalAttribute]
- public static unsafe Object Box(void *ptr, System.Type type) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static unsafe void* Unbox(object ptr) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- unsafe void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum PortableExecutableKinds
- {
- NotAPortableExecutableImage = 0,
- ILOnly = 1,
- Required32Bit = 2,
- PE32Plus = 4,
- Unmanaged32Bit = 8,
- [System.Runtime.InteropServices.ComVisible(false)]
- Preferred32Bit = 16,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum ProcessorArchitecture
- {
- Amd64 = 4,
- Arm = 5,
- IA64 = 3,
- MSIL = 1,
- None = 0,
- X86 = 2,
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum PropertyAttributes
- {
- HasDefault = 4096,
- None = 0,
- Reserved2 = 8192,
- Reserved3 = 16384,
- Reserved4 = 32768,
- ReservedMask = 62464,
- RTSpecialName = 1024,
- SpecialName = 512,
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class PropertyInfo : System.Reflection.MemberInfo
- {
- protected PropertyInfo() { }
- public static bool operator ==(System.Reflection.PropertyInfo left, System.Reflection.PropertyInfo right) { throw null; }
- public static bool operator !=(System.Reflection.PropertyInfo left, System.Reflection.PropertyInfo right) { throw null; }
- public abstract System.Reflection.PropertyAttributes Attributes { get; }
- public abstract bool CanRead { get; }
- public abstract bool CanWrite { get; }
- public virtual System.Reflection.MethodInfo GetMethod { get { throw null; } }
- public bool IsSpecialName { get { throw null; } }
- public override System.Reflection.MemberTypes MemberType { get { throw null; } }
- public abstract System.Type PropertyType { get; }
- public virtual System.Reflection.MethodInfo SetMethod { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public System.Reflection.MethodInfo[] GetAccessors() { throw null; }
- public abstract System.Reflection.MethodInfo[] GetAccessors(bool nonPublic);
- public virtual object GetConstantValue() { throw null; }
- public System.Reflection.MethodInfo GetGetMethod() { throw null; }
- public abstract System.Reflection.MethodInfo GetGetMethod(bool nonPublic);
- public override int GetHashCode() { throw null; }
- public abstract System.Reflection.ParameterInfo[] GetIndexParameters();
- public virtual System.Type[] GetOptionalCustomModifiers() { throw null; }
- public virtual object GetRawConstantValue() { throw null; }
- public virtual System.Type[] GetRequiredCustomModifiers() { throw null; }
- public System.Reflection.MethodInfo GetSetMethod() { throw null; }
- public abstract System.Reflection.MethodInfo GetSetMethod(bool nonPublic);
- [System.Diagnostics.DebuggerHiddenAttribute]
- [System.Diagnostics.DebuggerStepThroughAttribute]
- public object GetValue(object obj) { throw null; }
- [System.Diagnostics.DebuggerHiddenAttribute]
- [System.Diagnostics.DebuggerStepThroughAttribute]
- public virtual object GetValue(object obj, object[] index) { throw null; }
- public abstract object GetValue(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] index, System.Globalization.CultureInfo culture);
- [System.Diagnostics.DebuggerHiddenAttribute]
- [System.Diagnostics.DebuggerStepThroughAttribute]
- public void SetValue(object obj, object value) { }
- [System.Diagnostics.DebuggerHiddenAttribute]
- [System.Diagnostics.DebuggerStepThroughAttribute]
- public virtual void SetValue(object obj, object value, object[] index) { }
- public abstract void SetValue(object obj, object value, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] index, System.Globalization.CultureInfo culture);
- }
- public abstract partial class ReflectionContext
- {
- protected ReflectionContext() { }
- public virtual System.Reflection.TypeInfo GetTypeForObject(object value) { throw null; }
- public abstract System.Reflection.Assembly MapAssembly(System.Reflection.Assembly assembly);
- public abstract System.Reflection.TypeInfo MapType(System.Reflection.TypeInfo type);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ReflectionTypeLoadException : System.SystemException, System.Runtime.Serialization.ISerializable
- {
- public ReflectionTypeLoadException(System.Type[] classes, System.Exception[] exceptions) { }
- public ReflectionTypeLoadException(System.Type[] classes, System.Exception[] exceptions, string message) { }
- public System.Exception[] LoaderExceptions { get { throw null; } }
- public System.Type[] Types { get { throw null; } }
- [System.Security.SecurityCriticalAttribute]
- public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum ResourceAttributes
- {
- Private = 2,
- Public = 1,
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum ResourceLocation
- {
- ContainedInAnotherAssembly = 2,
- ContainedInManifestFile = 4,
- Embedded = 1,
- }
- public static partial class RuntimeReflectionExtensions
- {
- public static System.Reflection.MethodInfo GetMethodInfo(this System.Delegate del) { throw null; }
- public static System.Reflection.MethodInfo GetRuntimeBaseDefinition(this System.Reflection.MethodInfo method) { throw null; }
- public static System.Reflection.EventInfo GetRuntimeEvent(this System.Type type, string name) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Reflection.EventInfo> GetRuntimeEvents(this System.Type type) { throw null; }
- public static System.Reflection.FieldInfo GetRuntimeField(this System.Type type, string name) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Reflection.FieldInfo> GetRuntimeFields(this System.Type type) { throw null; }
- public static System.Reflection.InterfaceMapping GetRuntimeInterfaceMap(this System.Reflection.TypeInfo typeInfo, System.Type interfaceType) { throw null; }
- public static System.Reflection.MethodInfo GetRuntimeMethod(this System.Type type, string name, System.Type[] parameters) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Reflection.MethodInfo> GetRuntimeMethods(this System.Type type) { throw null; }
- public static System.Collections.Generic.IEnumerable<System.Reflection.PropertyInfo> GetRuntimeProperties(this System.Type type) { throw null; }
- public static System.Reflection.PropertyInfo GetRuntimeProperty(this System.Type type, string name) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class TargetException : System.ApplicationException
- {
- public TargetException() { }
- public TargetException(string message) { }
- public TargetException(string message, System.Exception inner) { }
- protected TargetException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class TargetInvocationException : System.ApplicationException
- {
- public TargetInvocationException(System.Exception inner) { }
- public TargetInvocationException(string message, System.Exception inner) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class TargetParameterCountException : System.ApplicationException
- {
- public TargetParameterCountException() { }
- public TargetParameterCountException(string message) { }
- public TargetParameterCountException(string message, System.Exception inner) { }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum TypeAttributes
- {
- Abstract = 128,
- AnsiClass = 0,
- AutoClass = 131072,
- AutoLayout = 0,
- BeforeFieldInit = 1048576,
- Class = 0,
- ClassSemanticsMask = 32,
- CustomFormatClass = 196608,
- CustomFormatMask = 12582912,
- ExplicitLayout = 16,
- HasSecurity = 262144,
- Import = 4096,
- Interface = 32,
- LayoutMask = 24,
- NestedAssembly = 5,
- NestedFamANDAssem = 6,
- NestedFamily = 4,
- NestedFamORAssem = 7,
- NestedPrivate = 3,
- NestedPublic = 2,
- NotPublic = 0,
- Public = 1,
- ReservedMask = 264192,
- RTSpecialName = 2048,
- Sealed = 256,
- SequentialLayout = 8,
- Serializable = 8192,
- SpecialName = 1024,
- StringFormatMask = 196608,
- UnicodeClass = 65536,
- VisibilityMask = 7,
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- WindowsRuntime = 16384,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public class TypeDelegator : System.Reflection.TypeInfo
- {
- protected System.Type typeImpl;
- public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- protected TypeDelegator() { }
- public TypeDelegator(System.Type delegatingType) { }
- public override System.Guid GUID { get { throw null; } }
- public override int MetadataToken { get { throw null; } }
- public override object InvokeMember(System.String name,System.Reflection.BindingFlags invokeAttr,System.Reflection.Binder binder,System.Object target, System.Object[] args,System.Reflection.ParameterModifier[] modifiers,System.Globalization.CultureInfo culture,System.String[] namedParameters) { throw null; }
- public override System.Reflection.Module Module { get { throw null; } }
- public override System.Reflection.Assembly Assembly { get { throw null; } }
- public override System.RuntimeTypeHandle TypeHandle { get { throw null; } }
- public override System.String Name { get { throw null; } }
- public override System.String FullName { get { throw null; } }
- public override System.String Namespace { get { throw null; } }
- public override System.String AssemblyQualifiedName { get { throw null; } }
- public override System.Type BaseType { get { throw null; } }
- protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr,System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { throw null; }
- protected override System.Reflection.MethodInfo GetMethodImpl(System.String name,System.Reflection.BindingFlags bindingAttr,System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types,System.Reflection.ParameterModifier[] modifiers) { throw null; }
- public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.FieldInfo GetField(System.String name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Type GetInterface(System.String name, bool ignoreCase) { throw null; }
- public override System.Type[] GetInterfaces() { throw null; }
- public override System.Reflection.EventInfo GetEvent(System.String name,System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.EventInfo[] GetEvents() { throw null; }
- protected override System.Reflection.PropertyInfo GetPropertyImpl(System.String name,System.Reflection.BindingFlags bindingAttr,System.Reflection.Binder binder, System.Type returnType, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Type GetNestedType(System.String name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.MemberInfo[] GetMember(System.String name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr) { throw null; }
- protected override TypeAttributes GetAttributeFlagsImpl() { throw null; }
- protected override bool IsArrayImpl() { throw null; }
- protected override bool IsPrimitiveImpl() { throw null; }
- protected override bool IsByRefImpl() { throw null; }
- protected override bool IsPointerImpl() { throw null; }
- protected override bool IsValueTypeImpl() { throw null; }
- protected override bool IsCOMObjectImpl() { throw null; }
- public override bool IsConstructedGenericType { get { throw null; } }
- public override System.Type GetElementType() { throw null; }
- protected override bool HasElementTypeImpl() { throw null; }
- public override System.Type UnderlyingSystemType { get { throw null; } }
- public override System.Object[] GetCustomAttributes(bool inherit) { throw null; }
- public override System.Object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; }
- public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public override System.Reflection.InterfaceMapping GetInterfaceMap(System.Type interfaceType) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public delegate bool TypeFilter(System.Type m, object filterCriteria);
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class TypeInfo : System.Type, System.Reflection.IReflectableType
- {
- internal TypeInfo() { }
- public virtual System.Collections.Generic.IEnumerable<System.Reflection.ConstructorInfo> DeclaredConstructors { get { throw null; } }
- public virtual System.Collections.Generic.IEnumerable<System.Reflection.EventInfo> DeclaredEvents { get { throw null; } }
- public virtual System.Collections.Generic.IEnumerable<System.Reflection.FieldInfo> DeclaredFields { get { throw null; } }
- public virtual System.Collections.Generic.IEnumerable<System.Reflection.MemberInfo> DeclaredMembers { get { throw null; } }
- public virtual System.Collections.Generic.IEnumerable<System.Reflection.MethodInfo> DeclaredMethods { get { throw null; } }
- public virtual System.Collections.Generic.IEnumerable<System.Reflection.TypeInfo> DeclaredNestedTypes { get { throw null; } }
- public virtual System.Collections.Generic.IEnumerable<System.Reflection.PropertyInfo> DeclaredProperties { get { throw null; } }
- public virtual System.Type[] GenericTypeParameters { get { throw null; } }
- public virtual System.Collections.Generic.IEnumerable<System.Type> ImplementedInterfaces { get { throw null; } }
- public virtual System.Type AsType() { throw null; }
- public virtual System.Reflection.EventInfo GetDeclaredEvent(string name) { throw null; }
- public virtual System.Reflection.FieldInfo GetDeclaredField(string name) { throw null; }
- public virtual System.Reflection.MethodInfo GetDeclaredMethod(string name) { throw null; }
- public virtual System.Collections.Generic.IEnumerable<System.Reflection.MethodInfo> GetDeclaredMethods(string name) { throw null; }
- public virtual System.Reflection.TypeInfo GetDeclaredNestedType(string name) { throw null; }
- public virtual System.Reflection.PropertyInfo GetDeclaredProperty(string name) { throw null; }
- public virtual bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo) { throw null; }
- System.Reflection.TypeInfo System.Reflection.IReflectableType.GetTypeInfo() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class StrongNameKeyPair : System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable
- {
- public StrongNameKeyPair(byte[] keyPairArray) { }
- protected StrongNameKeyPair(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public StrongNameKeyPair(string keyPairContainer) { }
- public byte[] PublicKey { [System.Security.SecuritySafeCriticalAttribute]get { return default(byte[]); } }
- void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object sender) { }
- void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
-}
-namespace System.Reflection.Emit
-{
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AssemblyBuilder : System.Reflection.Assembly
- {
- internal AssemblyBuilder() { }
- public override string CodeBase { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- public override System.Reflection.MethodInfo EntryPoint { get { throw null; } }
- public override string FullName { get { throw null; } }
- public override string ImageRuntimeVersion { get { throw null; } }
- public override bool IsDynamic { get { throw null; } }
- public override string Location { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- public override System.Reflection.Module ManifestModule { get { throw null; } }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public static System.Reflection.Emit.AssemblyBuilder DefineDynamicAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public static System.Reflection.Emit.AssemblyBuilder DefineDynamicAssembly(System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access, System.Collections.Generic.IEnumerable<System.Reflection.Emit.CustomAttributeBuilder> assemblyAttributes) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.ModuleBuilder DefineDynamicModule(string name) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.ModuleBuilder DefineDynamicModule(string name, bool emitSymbolInfo) { throw null; }
- public override bool Equals(object obj) { throw null; }
- public override object[] GetCustomAttributes(bool inherit) { throw null; }
- public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; }
- public System.Reflection.Emit.ModuleBuilder GetDynamicModule(string name) { throw null; }
- public override System.Type[] GetExportedTypes() { throw null; }
- public override int GetHashCode() { throw null; }
- public override System.Reflection.ManifestResourceInfo GetManifestResourceInfo(string resourceName) { throw null; }
- public override string[] GetManifestResourceNames() { throw null; }
- public override System.IO.Stream GetManifestResourceStream(string name) { throw null; }
- public override System.IO.Stream GetManifestResourceStream(System.Type type, string name) { throw null; }
- public override System.Reflection.AssemblyName[] GetReferencedAssemblies() { throw null; }
- public override System.Type GetType(string name, bool throwOnError, bool ignoreCase) { throw null; }
- public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum AssemblyBuilderAccess
- {
- Run = 1,
- RunAndCollect = 9,
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ConstructorBuilder : System.Reflection.ConstructorInfo
- {
- internal ConstructorBuilder() { }
- public override System.Reflection.MethodAttributes Attributes { get { throw null; } }
- public override System.Reflection.CallingConventions CallingConvention { get { throw null; } }
- public override System.Type DeclaringType { get { throw null; } }
- public bool InitLocals { get { throw null; } set { } }
- public override System.RuntimeMethodHandle MethodHandle { get { throw null; } }
- public override System.Reflection.Module Module { get { throw null; } }
- public override string Name { get { throw null; } }
- public override System.Type ReflectedType { get { throw null; } }
- public string Signature { get { throw null; } }
- public System.Reflection.Emit.ParameterBuilder DefineParameter(int iSequence, System.Reflection.ParameterAttributes attributes, string strParamName) { throw null; }
- public override object[] GetCustomAttributes(bool inherit) { throw null; }
- public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; }
- public System.Reflection.Emit.ILGenerator GetILGenerator() { throw null; }
- public System.Reflection.Emit.ILGenerator GetILGenerator(int streamSize) { throw null; }
- public override System.Reflection.MethodImplAttributes GetMethodImplementationFlags() { throw null; }
- public System.Reflection.Module GetModule() { throw null; }
- public override System.Reflection.ParameterInfo[] GetParameters() { throw null; }
- public System.Reflection.Emit.MethodToken GetToken() { throw null; }
- public override object Invoke(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture) { throw null; }
- public override object Invoke(System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture) { throw null; }
- public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { }
- public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { }
- public void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) { }
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class CustomAttributeBuilder
- {
- public CustomAttributeBuilder(System.Reflection.ConstructorInfo con, object[] constructorArgs) { }
- public CustomAttributeBuilder(System.Reflection.ConstructorInfo con, object[] constructorArgs, System.Reflection.FieldInfo[] namedFields, object[] fieldValues) { }
- public CustomAttributeBuilder(System.Reflection.ConstructorInfo con, object[] constructorArgs, System.Reflection.PropertyInfo[] namedProperties, object[] propertyValues) { }
- public CustomAttributeBuilder(System.Reflection.ConstructorInfo con, object[] constructorArgs, System.Reflection.PropertyInfo[] namedProperties, object[] propertyValues, System.Reflection.FieldInfo[] namedFields, object[] fieldValues) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DynamicMethod : System.Reflection.MethodInfo
- {
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecurityCriticalAttribute]
- public DynamicMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[] parameterTypes, System.Reflection.Module m, bool skipVisibility) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecurityCriticalAttribute]
- public DynamicMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[] parameterTypes, System.Type owner, bool skipVisibility) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public DynamicMethod(string name, System.Type returnType, System.Type[] parameterTypes) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public DynamicMethod(string name, System.Type returnType, System.Type[] parameterTypes, bool restrictedSkipVisibility) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecurityCriticalAttribute]
- public DynamicMethod(string name, System.Type returnType, System.Type[] parameterTypes, System.Reflection.Module m) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecurityCriticalAttribute]
- public DynamicMethod(string name, System.Type returnType, System.Type[] parameterTypes, System.Reflection.Module m, bool skipVisibility) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecurityCriticalAttribute]
- public DynamicMethod(string name, System.Type returnType, System.Type[] parameterTypes, System.Type owner) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecurityCriticalAttribute]
- public DynamicMethod(string name, System.Type returnType, System.Type[] parameterTypes, System.Type owner, bool skipVisibility) { }
- public override System.Reflection.MethodAttributes Attributes { get { throw null; } }
- public override System.Reflection.CallingConventions CallingConvention { get { throw null; } }
- public override System.Type DeclaringType { get { throw null; } }
- public bool InitLocals { get { throw null; } set { } }
- public override System.RuntimeMethodHandle MethodHandle { get { throw null; } }
- public override System.Reflection.Module Module { get { throw null; } }
- public override string Name { get { throw null; } }
- public override System.Type ReflectedType { get { throw null; } }
- public override System.Reflection.ParameterInfo ReturnParameter { get { throw null; } }
- public override System.Type ReturnType { get { throw null; } }
- public override System.Reflection.ICustomAttributeProvider ReturnTypeCustomAttributes { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public sealed override System.Delegate CreateDelegate(System.Type delegateType) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public sealed override System.Delegate CreateDelegate(System.Type delegateType, object target) { throw null; }
- public System.Reflection.Emit.ParameterBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string parameterName) { throw null; }
- public override System.Reflection.MethodInfo GetBaseDefinition() { throw null; }
- public override object[] GetCustomAttributes(bool inherit) { throw null; }
- public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; }
- public System.Reflection.Emit.ILGenerator GetILGenerator() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.ILGenerator GetILGenerator(int streamSize) { throw null; }
- public override System.Reflection.MethodImplAttributes GetMethodImplementationFlags() { throw null; }
- public override System.Reflection.ParameterInfo[] GetParameters() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override object Invoke(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture) { throw null; }
- public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class EnumBuilder : System.Reflection.TypeInfo
- {
- internal EnumBuilder() { }
- public override System.Reflection.Assembly Assembly { get { throw null; } }
- public override string AssemblyQualifiedName { get { throw null; } }
- public override System.Type BaseType { get { throw null; } }
- public override System.Type DeclaringType { get { throw null; } }
- public override string FullName { get { throw null; } }
- public override System.Guid GUID { get { throw null; } }
- public override bool IsConstructedGenericType { get { throw null; } }
- public override System.Reflection.Module Module { get { throw null; } }
- public override string Name { get { throw null; } }
- public override string Namespace { get { throw null; } }
- public override System.Type ReflectedType { get { throw null; } }
- public override System.RuntimeTypeHandle TypeHandle { get { throw null; } }
- public System.Reflection.Emit.TypeToken TypeToken { get { throw null; } }
- public System.Reflection.Emit.FieldBuilder UnderlyingField { get { throw null; } }
- public override System.Type UnderlyingSystemType { get { throw null; } }
- public System.Type CreateType() { throw null; }
- public System.Reflection.TypeInfo CreateTypeInfo() { throw null; }
- public System.Reflection.Emit.FieldBuilder DefineLiteral(string literalName, object literalValue) { throw null; }
- protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl() { throw null; }
- protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override object[] GetCustomAttributes(bool inherit) { throw null; }
- public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; }
- public override System.Type GetElementType() { throw null; }
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Contracts", "CC1055")]
- public override System.Type GetEnumUnderlyingType() { throw null; }
- public override System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.EventInfo[] GetEvents() { throw null; }
- public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Type GetInterface(string name, bool ignoreCase) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public override System.Reflection.InterfaceMapping GetInterfaceMap(System.Type interfaceType) { throw null; }
- public override System.Type[] GetInterfaces() { throw null; }
- public override System.Reflection.MemberInfo[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr) { throw null; }
- protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr) { throw null; }
- protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Type returnType, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- protected override bool HasElementTypeImpl() { throw null; }
- public override object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters) { throw null; }
- protected override bool IsArrayImpl() { throw null; }
- public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo) { throw null; }
- protected override bool IsByRefImpl() { throw null; }
- protected override bool IsCOMObjectImpl() { throw null; }
- public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
- protected override bool IsPointerImpl() { throw null; }
- protected override bool IsPrimitiveImpl() { throw null; }
- protected override bool IsValueTypeImpl() { throw null; }
- public override System.Type MakeArrayType() { throw null; }
- public override System.Type MakeArrayType(int rank) { throw null; }
- public override System.Type MakeByRefType() { throw null; }
- public override System.Type MakePointerType() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { }
- public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class EventBuilder
- {
- internal EventBuilder() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void AddOtherMethod(System.Reflection.Emit.MethodBuilder mdBuilder) { }
- public System.Reflection.Emit.EventToken GetEventToken() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetAddOnMethod(System.Reflection.Emit.MethodBuilder mdBuilder) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetRaiseMethod(System.Reflection.Emit.MethodBuilder mdBuilder) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetRemoveOnMethod(System.Reflection.Emit.MethodBuilder mdBuilder) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct EventToken
- {
- public static readonly System.Reflection.Emit.EventToken Empty;
- public int Token { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.Reflection.Emit.EventToken obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Reflection.Emit.EventToken a, System.Reflection.Emit.EventToken b) { throw null; }
- public static bool operator !=(System.Reflection.Emit.EventToken a, System.Reflection.Emit.EventToken b) { throw null; }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class FieldBuilder : System.Reflection.FieldInfo
- {
- internal FieldBuilder() { }
- public override System.Reflection.FieldAttributes Attributes { get { throw null; } }
- public override System.Type DeclaringType { get { throw null; } }
- public override System.RuntimeFieldHandle FieldHandle { get { throw null; } }
- public override System.Type FieldType { get { throw null; } }
- public override System.Reflection.Module Module { get { throw null; } }
- public override string Name { get { throw null; } }
- public override System.Type ReflectedType { get { throw null; } }
- public override object[] GetCustomAttributes(bool inherit) { throw null; }
- public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; }
- public System.Reflection.Emit.FieldToken GetToken() { throw null; }
- public override object GetValue(object obj) { throw null; }
- public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetConstant(object defaultValue) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { }
- [System.Security.SecurityCriticalAttribute]
- public void SetOffset(int iOffset) { }
- public override void SetValue(object obj, object val, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Globalization.CultureInfo culture) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct FieldToken
- {
- public static readonly System.Reflection.Emit.FieldToken Empty;
- public int Token { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.Reflection.Emit.FieldToken obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Reflection.Emit.FieldToken a, System.Reflection.Emit.FieldToken b) { throw null; }
- public static bool operator !=(System.Reflection.Emit.FieldToken a, System.Reflection.Emit.FieldToken b) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum FlowControl
- {
- Branch = 0,
- Break = 1,
- Call = 2,
- Cond_Branch = 3,
- Meta = 4,
- Next = 5,
- [Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")]
- Phi = 6,
- Return = 7,
- Throw = 8,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class GenericTypeParameterBuilder : System.Reflection.TypeInfo
- {
- internal GenericTypeParameterBuilder() { }
- public override System.Reflection.Assembly Assembly { get { throw null; } }
- public override string AssemblyQualifiedName { get { throw null; } }
- public override System.Type BaseType { get { throw null; } }
- public override bool ContainsGenericParameters { get { throw null; } }
- public override System.Reflection.MethodBase DeclaringMethod { get { throw null; } }
- public override System.Type DeclaringType { get { throw null; } }
- public override string FullName { get { throw null; } }
- public override System.Reflection.GenericParameterAttributes GenericParameterAttributes { get { throw null; } }
- public override int GenericParameterPosition { get { throw null; } }
- public override System.Guid GUID { get { throw null; } }
- public override bool IsConstructedGenericType { get { throw null; } }
- public override bool IsGenericParameter { get { throw null; } }
- public override bool IsGenericType { get { throw null; } }
- public override bool IsGenericTypeDefinition { get { throw null; } }
- public override System.Reflection.Module Module { get { throw null; } }
- public override string Name { get { throw null; } }
- public override string Namespace { get { throw null; } }
- public override System.Type ReflectedType { get { throw null; } }
- public override System.RuntimeTypeHandle TypeHandle { get { throw null; } }
- public override System.Type UnderlyingSystemType { get { throw null; } }
- public override bool Equals(object o) { throw null; }
- protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl() { throw null; }
- protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override object[] GetCustomAttributes(bool inherit) { throw null; }
- public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; }
- public override System.Type GetElementType() { throw null; }
- public override System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.EventInfo[] GetEvents() { throw null; }
- public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Type[] GetGenericArguments() { throw null; }
- public override System.Type GetGenericTypeDefinition() { throw null; }
- public override int GetHashCode() { throw null; }
- public override System.Type GetInterface(string name, bool ignoreCase) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public override System.Reflection.InterfaceMapping GetInterfaceMap(System.Type interfaceType) { throw null; }
- public override System.Type[] GetInterfaces() { throw null; }
- public override System.Reflection.MemberInfo[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr) { throw null; }
- protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr) { throw null; }
- protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Type returnType, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- protected override bool HasElementTypeImpl() { throw null; }
- public override object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters) { throw null; }
- protected override bool IsArrayImpl() { throw null; }
- public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo) { throw null; }
- public override bool IsAssignableFrom(System.Type c) { throw null; }
- protected override bool IsByRefImpl() { throw null; }
- protected override bool IsCOMObjectImpl() { throw null; }
- public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
- protected override bool IsPointerImpl() { throw null; }
- protected override bool IsPrimitiveImpl() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public override bool IsSubclassOf(System.Type c) { throw null; }
- protected override bool IsValueTypeImpl() { throw null; }
- public override System.Type MakeArrayType() { throw null; }
- public override System.Type MakeArrayType(int rank) { throw null; }
- public override System.Type MakeByRefType() { throw null; }
- public override System.Type MakeGenericType(params System.Type[] typeArguments) { throw null; }
- public override System.Type MakePointerType() { throw null; }
- public void SetBaseTypeConstraint(System.Type baseTypeConstraint) { }
- [System.Security.SecurityCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { }
- public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { }
- public void SetGenericParameterAttributes(System.Reflection.GenericParameterAttributes genericParameterAttributes) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public void SetInterfaceConstraints(params System.Type[] interfaceConstraints) { }
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ILGenerator
- {
- internal ILGenerator() { }
- public virtual int ILOffset { get { throw null; } }
- public virtual void BeginCatchBlock(System.Type exceptionType) { }
- public virtual void BeginExceptFilterBlock() { }
- public virtual System.Reflection.Emit.Label BeginExceptionBlock() { throw null; }
- public virtual void BeginFaultBlock() { }
- public virtual void BeginFinallyBlock() { }
- public virtual void BeginScope() { }
- public virtual System.Reflection.Emit.LocalBuilder DeclareLocal(System.Type localType) { throw null; }
- public virtual System.Reflection.Emit.LocalBuilder DeclareLocal(System.Type localType, bool pinned) { throw null; }
- public virtual System.Reflection.Emit.Label DefineLabel() { throw null; }
- public virtual void Emit(System.Reflection.Emit.OpCode opcode) { }
- public virtual void Emit(System.Reflection.Emit.OpCode opcode, byte arg) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual void Emit(System.Reflection.Emit.OpCode opcode, double arg) { }
- public virtual void Emit(System.Reflection.Emit.OpCode opcode, short arg) { }
- public virtual void Emit(System.Reflection.Emit.OpCode opcode, int arg) { }
- public virtual void Emit(System.Reflection.Emit.OpCode opcode, long arg) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con) { }
- public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label label) { }
- public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label[] labels) { }
- public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.LocalBuilder local) { }
- public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.SignatureHelper signature) { }
- public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.FieldInfo field) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo meth) { }
- [System.CLSCompliantAttribute(false)]
- public void Emit(System.Reflection.Emit.OpCode opcode, sbyte arg) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual void Emit(System.Reflection.Emit.OpCode opcode, float arg) { }
- public virtual void Emit(System.Reflection.Emit.OpCode opcode, string str) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Type cls) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual void EmitCall(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo methodInfo, System.Type[] optionalParameterTypes) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual void EmitCalli(System.Reflection.Emit.OpCode opcode, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[] parameterTypes, System.Type[] optionalParameterTypes) { }
- public virtual void EmitWriteLine(System.Reflection.Emit.LocalBuilder localBuilder) { }
- public virtual void EmitWriteLine(System.Reflection.FieldInfo fld) { }
- public virtual void EmitWriteLine(string value) { }
- public virtual void EndExceptionBlock() { }
- public virtual void EndScope() { }
- public virtual void MarkLabel(System.Reflection.Emit.Label loc) { }
- public virtual void MarkSequencePoint(System.Diagnostics.SymbolStore.ISymbolDocumentWriter document, int startLine, int startColumn, int endLine, int endColumn) { }
- public virtual void ThrowException(System.Type excType) { }
- public virtual void UsingNamespace(string usingNamespace) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct Label
- {
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.Reflection.Emit.Label obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Reflection.Emit.Label a, System.Reflection.Emit.Label b) { throw null; }
- public static bool operator !=(System.Reflection.Emit.Label a, System.Reflection.Emit.Label b) { throw null; }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class LocalBuilder : System.Reflection.LocalVariableInfo
- {
- internal LocalBuilder() { }
- public override bool IsPinned { get { throw null; } }
- public override int LocalIndex { get { throw null; } }
- public override System.Type LocalType { get { throw null; } }
- public void SetLocalSymInfo(string name) { }
- public void SetLocalSymInfo(string name, int startOffset, int endOffset) { }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class MethodBuilder : System.Reflection.MethodInfo
- {
- internal MethodBuilder() { }
- public override System.Reflection.MethodAttributes Attributes { get { throw null; } }
- public override System.Reflection.CallingConventions CallingConvention { get { throw null; } }
- public override bool ContainsGenericParameters { get { throw null; } }
- public override System.Type DeclaringType { get { throw null; } }
- public bool InitLocals { get { throw null; } set { } }
- public override bool IsGenericMethod { get { throw null; } }
- public override bool IsGenericMethodDefinition { get { throw null; } }
- public override System.RuntimeMethodHandle MethodHandle { get { throw null; } }
- public override System.Reflection.Module Module { get { throw null; } }
- public override string Name { get { throw null; } }
- public override System.Type ReflectedType { get { throw null; } }
- public override System.Reflection.ParameterInfo ReturnParameter { get { throw null; } }
- public override System.Type ReturnType { get { throw null; } }
- public override System.Reflection.ICustomAttributeProvider ReturnTypeCustomAttributes { get { throw null; } }
- public string Signature { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public System.Reflection.Emit.GenericTypeParameterBuilder[] DefineGenericParameters(params string[] names) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.ParameterBuilder DefineParameter(int position, System.Reflection.ParameterAttributes attributes, string strParamName) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override bool Equals(object obj) { throw null; }
- public override System.Reflection.MethodInfo GetBaseDefinition() { throw null; }
- public override object[] GetCustomAttributes(bool inherit) { throw null; }
- public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; }
- public override System.Type[] GetGenericArguments() { throw null; }
- public override System.Reflection.MethodInfo GetGenericMethodDefinition() { throw null; }
- public override int GetHashCode() { throw null; }
- public System.Reflection.Emit.ILGenerator GetILGenerator() { throw null; }
- public System.Reflection.Emit.ILGenerator GetILGenerator(int size) { throw null; }
- public override System.Reflection.MethodImplAttributes GetMethodImplementationFlags() { throw null; }
- public System.Reflection.Module GetModule() { throw null; }
- public override System.Reflection.ParameterInfo[] GetParameters() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.MethodToken GetToken() { throw null; }
- public override object Invoke(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture) { throw null; }
- public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
- public override System.Reflection.MethodInfo MakeGenericMethod(params System.Type[] typeArguments) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetImplementationFlags(System.Reflection.MethodImplAttributes attributes) { }
- public void SetParameters(params System.Type[] parameterTypes) { }
- public void SetReturnType(System.Type returnType) { }
- public void SetSignature(System.Type returnType, System.Type[] returnTypeRequiredCustomModifiers, System.Type[] returnTypeOptionalCustomModifiers, System.Type[] parameterTypes, System.Type[][] parameterTypeRequiredCustomModifiers, System.Type[][] parameterTypeOptionalCustomModifiers) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct MethodToken
- {
- public static readonly System.Reflection.Emit.MethodToken Empty;
- public int Token { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.Reflection.Emit.MethodToken obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Reflection.Emit.MethodToken a, System.Reflection.Emit.MethodToken b) { throw null; }
- public static bool operator !=(System.Reflection.Emit.MethodToken a, System.Reflection.Emit.MethodToken b) { throw null; }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ModuleBuilder : System.Reflection.Module
- {
- internal ModuleBuilder() { }
- public override System.Reflection.Assembly Assembly { get { throw null; } }
- public override string FullyQualifiedName { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- public override int MetadataToken { get { throw null; } }
- public override System.Guid ModuleVersionId { get { throw null; } }
- public override string Name { get { throw null; } }
- public override string ScopeName { get { throw null; } }
- public void CreateGlobalFunctions() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Diagnostics.SymbolStore.ISymbolDocumentWriter DefineDocument(string url, System.Guid language, System.Guid languageVendor, System.Guid documentType) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.EnumBuilder DefineEnum(string name, System.Reflection.TypeAttributes visibility, System.Type underlyingType) { throw null; }
- public System.Reflection.Emit.MethodBuilder DefineGlobalMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[] parameterTypes) { throw null; }
- public System.Reflection.Emit.MethodBuilder DefineGlobalMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[] requiredReturnTypeCustomModifiers, System.Type[] optionalReturnTypeCustomModifiers, System.Type[] parameterTypes, System.Type[][] requiredParameterTypeCustomModifiers, System.Type[][] optionalParameterTypeCustomModifiers) { throw null; }
- public System.Reflection.Emit.MethodBuilder DefineGlobalMethod(string name, System.Reflection.MethodAttributes attributes, System.Type returnType, System.Type[] parameterTypes) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public System.Reflection.Emit.FieldBuilder DefineInitializedData(string name, byte[] data, System.Reflection.FieldAttributes attributes) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.TypeBuilder DefineType(string name) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.TypeBuilder DefineType(string name, System.Reflection.TypeAttributes attr) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.TypeBuilder DefineType(string name, System.Reflection.TypeAttributes attr, System.Type parent) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public System.Reflection.Emit.TypeBuilder DefineType(string name, System.Reflection.TypeAttributes attr, System.Type parent, int typesize) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public System.Reflection.Emit.TypeBuilder DefineType(string name, System.Reflection.TypeAttributes attr, System.Type parent, System.Reflection.Emit.PackingSize packsize) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public System.Reflection.Emit.TypeBuilder DefineType(string name, System.Reflection.TypeAttributes attr, System.Type parent, System.Reflection.Emit.PackingSize packingSize, int typesize) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.TypeBuilder DefineType(string name, System.Reflection.TypeAttributes attr, System.Type parent, System.Type[] interfaces) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public System.Reflection.Emit.FieldBuilder DefineUninitializedData(string name, int size, System.Reflection.FieldAttributes attributes) { throw null; }
- public override bool Equals(object obj) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.MethodInfo GetArrayMethod(System.Type arrayClass, string methodName, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[] parameterTypes) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.MethodToken GetArrayMethodToken(System.Type arrayClass, string methodName, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[] parameterTypes) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.MethodToken GetConstructorToken(System.Reflection.ConstructorInfo con) { throw null; }
- public override object[] GetCustomAttributes(bool inherit) { throw null; }
- public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; }
- public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingFlags) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.FieldToken GetFieldToken(System.Reflection.FieldInfo field) { throw null; }
- public override int GetHashCode() { throw null; }
- protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingFlags) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.MethodToken GetMethodToken(System.Reflection.MethodInfo method) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.SignatureToken GetSignatureToken(byte[] sigBytes, int sigLength) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.SignatureToken GetSignatureToken(System.Reflection.Emit.SignatureHelper sigHelper) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.StringToken GetStringConstant(string str) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public override System.Type GetType(string className) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public override System.Type GetType(string className, bool ignoreCase) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public override System.Type GetType(string className, bool throwOnError, bool ignoreCase) { throw null; }
- public override System.Type[] GetTypes() { throw null; }
- public System.Reflection.Emit.TypeToken GetTypeToken(string name) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.TypeToken GetTypeToken(System.Type type) { throw null; }
- public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
- public bool IsTransient() { throw null; }
- public override System.Reflection.FieldInfo ResolveField(int metadataToken, System.Type[] genericTypeArguments, System.Type[] genericMethodArguments) { throw null; }
- public override System.Reflection.MethodBase ResolveMethod(int metadataToken, System.Type[] genericTypeArguments, System.Type[] genericMethodArguments) { throw null; }
- public override string ResolveString(int metadataToken) { throw null; }
- public override System.Type ResolveType(int metadataToken, System.Type[] genericTypeArguments, System.Type[] genericMethodArguments) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct OpCode
- {
- public System.Reflection.Emit.FlowControl FlowControl { get { throw null; } }
- public string Name { get { throw null; } }
- public System.Reflection.Emit.OpCodeType OpCodeType { get { throw null; } }
- public System.Reflection.Emit.OperandType OperandType { get { throw null; } }
- public int Size { get { throw null; } }
- public System.Reflection.Emit.StackBehaviour StackBehaviourPop { get { throw null; } }
- public System.Reflection.Emit.StackBehaviour StackBehaviourPush { get { throw null; } }
- public short Value { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.Reflection.Emit.OpCode obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Reflection.Emit.OpCode a, System.Reflection.Emit.OpCode b) { throw null; }
- public static bool operator !=(System.Reflection.Emit.OpCode a, System.Reflection.Emit.OpCode b) { throw null; }
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class OpCodes
- {
- internal OpCodes() { }
- public static readonly System.Reflection.Emit.OpCode Add;
- public static readonly System.Reflection.Emit.OpCode Add_Ovf;
- public static readonly System.Reflection.Emit.OpCode Add_Ovf_Un;
- public static readonly System.Reflection.Emit.OpCode And;
- public static readonly System.Reflection.Emit.OpCode Arglist;
- public static readonly System.Reflection.Emit.OpCode Beq;
- public static readonly System.Reflection.Emit.OpCode Beq_S;
- public static readonly System.Reflection.Emit.OpCode Bge;
- public static readonly System.Reflection.Emit.OpCode Bge_S;
- public static readonly System.Reflection.Emit.OpCode Bge_Un;
- public static readonly System.Reflection.Emit.OpCode Bge_Un_S;
- public static readonly System.Reflection.Emit.OpCode Bgt;
- public static readonly System.Reflection.Emit.OpCode Bgt_S;
- public static readonly System.Reflection.Emit.OpCode Bgt_Un;
- public static readonly System.Reflection.Emit.OpCode Bgt_Un_S;
- public static readonly System.Reflection.Emit.OpCode Ble;
- public static readonly System.Reflection.Emit.OpCode Ble_S;
- public static readonly System.Reflection.Emit.OpCode Ble_Un;
- public static readonly System.Reflection.Emit.OpCode Ble_Un_S;
- public static readonly System.Reflection.Emit.OpCode Blt;
- public static readonly System.Reflection.Emit.OpCode Blt_S;
- public static readonly System.Reflection.Emit.OpCode Blt_Un;
- public static readonly System.Reflection.Emit.OpCode Blt_Un_S;
- public static readonly System.Reflection.Emit.OpCode Bne_Un;
- public static readonly System.Reflection.Emit.OpCode Bne_Un_S;
- public static readonly System.Reflection.Emit.OpCode Box;
- public static readonly System.Reflection.Emit.OpCode Br;
- public static readonly System.Reflection.Emit.OpCode Br_S;
- public static readonly System.Reflection.Emit.OpCode Break;
- public static readonly System.Reflection.Emit.OpCode Brfalse;
- public static readonly System.Reflection.Emit.OpCode Brfalse_S;
- public static readonly System.Reflection.Emit.OpCode Brtrue;
- public static readonly System.Reflection.Emit.OpCode Brtrue_S;
- public static readonly System.Reflection.Emit.OpCode Call;
- public static readonly System.Reflection.Emit.OpCode Calli;
- public static readonly System.Reflection.Emit.OpCode Callvirt;
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static readonly System.Reflection.Emit.OpCode Castclass;
- public static readonly System.Reflection.Emit.OpCode Ceq;
- public static readonly System.Reflection.Emit.OpCode Cgt;
- public static readonly System.Reflection.Emit.OpCode Cgt_Un;
- public static readonly System.Reflection.Emit.OpCode Ckfinite;
- public static readonly System.Reflection.Emit.OpCode Clt;
- public static readonly System.Reflection.Emit.OpCode Clt_Un;
- public static readonly System.Reflection.Emit.OpCode Constrained;
- public static readonly System.Reflection.Emit.OpCode Conv_I;
- public static readonly System.Reflection.Emit.OpCode Conv_I1;
- public static readonly System.Reflection.Emit.OpCode Conv_I2;
- public static readonly System.Reflection.Emit.OpCode Conv_I4;
- public static readonly System.Reflection.Emit.OpCode Conv_I8;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_I;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_I_Un;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_I1;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_I1_Un;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_I2;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_I2_Un;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_I4;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_I4_Un;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_I8;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_I8_Un;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_U;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_U_Un;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_U1;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_U1_Un;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_U2;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_U2_Un;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_U4;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_U4_Un;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_U8;
- public static readonly System.Reflection.Emit.OpCode Conv_Ovf_U8_Un;
- public static readonly System.Reflection.Emit.OpCode Conv_R_Un;
- public static readonly System.Reflection.Emit.OpCode Conv_R4;
- public static readonly System.Reflection.Emit.OpCode Conv_R8;
- public static readonly System.Reflection.Emit.OpCode Conv_U;
- public static readonly System.Reflection.Emit.OpCode Conv_U1;
- public static readonly System.Reflection.Emit.OpCode Conv_U2;
- public static readonly System.Reflection.Emit.OpCode Conv_U4;
- public static readonly System.Reflection.Emit.OpCode Conv_U8;
- public static readonly System.Reflection.Emit.OpCode Cpblk;
- public static readonly System.Reflection.Emit.OpCode Cpobj;
- public static readonly System.Reflection.Emit.OpCode Div;
- public static readonly System.Reflection.Emit.OpCode Div_Un;
- public static readonly System.Reflection.Emit.OpCode Dup;
- public static readonly System.Reflection.Emit.OpCode Endfilter;
- public static readonly System.Reflection.Emit.OpCode Endfinally;
- public static readonly System.Reflection.Emit.OpCode Initblk;
- public static readonly System.Reflection.Emit.OpCode Initobj;
- public static readonly System.Reflection.Emit.OpCode Isinst;
- public static readonly System.Reflection.Emit.OpCode Jmp;
- public static readonly System.Reflection.Emit.OpCode Ldarg;
- public static readonly System.Reflection.Emit.OpCode Ldarg_0;
- public static readonly System.Reflection.Emit.OpCode Ldarg_1;
- public static readonly System.Reflection.Emit.OpCode Ldarg_2;
- public static readonly System.Reflection.Emit.OpCode Ldarg_3;
- public static readonly System.Reflection.Emit.OpCode Ldarg_S;
- public static readonly System.Reflection.Emit.OpCode Ldarga;
- public static readonly System.Reflection.Emit.OpCode Ldarga_S;
- public static readonly System.Reflection.Emit.OpCode Ldc_I4;
- public static readonly System.Reflection.Emit.OpCode Ldc_I4_0;
- public static readonly System.Reflection.Emit.OpCode Ldc_I4_1;
- public static readonly System.Reflection.Emit.OpCode Ldc_I4_2;
- public static readonly System.Reflection.Emit.OpCode Ldc_I4_3;
- public static readonly System.Reflection.Emit.OpCode Ldc_I4_4;
- public static readonly System.Reflection.Emit.OpCode Ldc_I4_5;
- public static readonly System.Reflection.Emit.OpCode Ldc_I4_6;
- public static readonly System.Reflection.Emit.OpCode Ldc_I4_7;
- public static readonly System.Reflection.Emit.OpCode Ldc_I4_8;
- public static readonly System.Reflection.Emit.OpCode Ldc_I4_M1;
- public static readonly System.Reflection.Emit.OpCode Ldc_I4_S;
- public static readonly System.Reflection.Emit.OpCode Ldc_I8;
- public static readonly System.Reflection.Emit.OpCode Ldc_R4;
- public static readonly System.Reflection.Emit.OpCode Ldc_R8;
- public static readonly System.Reflection.Emit.OpCode Ldelem;
- public static readonly System.Reflection.Emit.OpCode Ldelem_I;
- public static readonly System.Reflection.Emit.OpCode Ldelem_I1;
- public static readonly System.Reflection.Emit.OpCode Ldelem_I2;
- public static readonly System.Reflection.Emit.OpCode Ldelem_I4;
- public static readonly System.Reflection.Emit.OpCode Ldelem_I8;
- public static readonly System.Reflection.Emit.OpCode Ldelem_R4;
- public static readonly System.Reflection.Emit.OpCode Ldelem_R8;
- public static readonly System.Reflection.Emit.OpCode Ldelem_Ref;
- public static readonly System.Reflection.Emit.OpCode Ldelem_U1;
- public static readonly System.Reflection.Emit.OpCode Ldelem_U2;
- public static readonly System.Reflection.Emit.OpCode Ldelem_U4;
- public static readonly System.Reflection.Emit.OpCode Ldelema;
- public static readonly System.Reflection.Emit.OpCode Ldfld;
- public static readonly System.Reflection.Emit.OpCode Ldflda;
- public static readonly System.Reflection.Emit.OpCode Ldftn;
- public static readonly System.Reflection.Emit.OpCode Ldind_I;
- public static readonly System.Reflection.Emit.OpCode Ldind_I1;
- public static readonly System.Reflection.Emit.OpCode Ldind_I2;
- public static readonly System.Reflection.Emit.OpCode Ldind_I4;
- public static readonly System.Reflection.Emit.OpCode Ldind_I8;
- public static readonly System.Reflection.Emit.OpCode Ldind_R4;
- public static readonly System.Reflection.Emit.OpCode Ldind_R8;
- public static readonly System.Reflection.Emit.OpCode Ldind_Ref;
- public static readonly System.Reflection.Emit.OpCode Ldind_U1;
- public static readonly System.Reflection.Emit.OpCode Ldind_U2;
- public static readonly System.Reflection.Emit.OpCode Ldind_U4;
- public static readonly System.Reflection.Emit.OpCode Ldlen;
- public static readonly System.Reflection.Emit.OpCode Ldloc;
- public static readonly System.Reflection.Emit.OpCode Ldloc_0;
- public static readonly System.Reflection.Emit.OpCode Ldloc_1;
- public static readonly System.Reflection.Emit.OpCode Ldloc_2;
- public static readonly System.Reflection.Emit.OpCode Ldloc_3;
- public static readonly System.Reflection.Emit.OpCode Ldloc_S;
- public static readonly System.Reflection.Emit.OpCode Ldloca;
- public static readonly System.Reflection.Emit.OpCode Ldloca_S;
- public static readonly System.Reflection.Emit.OpCode Ldnull;
- public static readonly System.Reflection.Emit.OpCode Ldobj;
- public static readonly System.Reflection.Emit.OpCode Ldsfld;
- public static readonly System.Reflection.Emit.OpCode Ldsflda;
- public static readonly System.Reflection.Emit.OpCode Ldstr;
- public static readonly System.Reflection.Emit.OpCode Ldtoken;
- public static readonly System.Reflection.Emit.OpCode Ldvirtftn;
- public static readonly System.Reflection.Emit.OpCode Leave;
- public static readonly System.Reflection.Emit.OpCode Leave_S;
- public static readonly System.Reflection.Emit.OpCode Localloc;
- public static readonly System.Reflection.Emit.OpCode Mkrefany;
- public static readonly System.Reflection.Emit.OpCode Mul;
- public static readonly System.Reflection.Emit.OpCode Mul_Ovf;
- public static readonly System.Reflection.Emit.OpCode Mul_Ovf_Un;
- public static readonly System.Reflection.Emit.OpCode Neg;
- public static readonly System.Reflection.Emit.OpCode Newarr;
- public static readonly System.Reflection.Emit.OpCode Newobj;
- public static readonly System.Reflection.Emit.OpCode Nop;
- public static readonly System.Reflection.Emit.OpCode Not;
- public static readonly System.Reflection.Emit.OpCode Or;
- public static readonly System.Reflection.Emit.OpCode Pop;
- public static readonly System.Reflection.Emit.OpCode Prefix1;
- public static readonly System.Reflection.Emit.OpCode Prefix2;
- public static readonly System.Reflection.Emit.OpCode Prefix3;
- public static readonly System.Reflection.Emit.OpCode Prefix4;
- public static readonly System.Reflection.Emit.OpCode Prefix5;
- public static readonly System.Reflection.Emit.OpCode Prefix6;
- public static readonly System.Reflection.Emit.OpCode Prefix7;
- public static readonly System.Reflection.Emit.OpCode Prefixref;
- public static readonly System.Reflection.Emit.OpCode Readonly;
- public static readonly System.Reflection.Emit.OpCode Refanytype;
- public static readonly System.Reflection.Emit.OpCode Refanyval;
- public static readonly System.Reflection.Emit.OpCode Rem;
- public static readonly System.Reflection.Emit.OpCode Rem_Un;
- public static readonly System.Reflection.Emit.OpCode Ret;
- public static readonly System.Reflection.Emit.OpCode Rethrow;
- public static readonly System.Reflection.Emit.OpCode Shl;
- public static readonly System.Reflection.Emit.OpCode Shr;
- public static readonly System.Reflection.Emit.OpCode Shr_Un;
- public static readonly System.Reflection.Emit.OpCode Sizeof;
- public static readonly System.Reflection.Emit.OpCode Starg;
- public static readonly System.Reflection.Emit.OpCode Starg_S;
- public static readonly System.Reflection.Emit.OpCode Stelem;
- public static readonly System.Reflection.Emit.OpCode Stelem_I;
- public static readonly System.Reflection.Emit.OpCode Stelem_I1;
- public static readonly System.Reflection.Emit.OpCode Stelem_I2;
- public static readonly System.Reflection.Emit.OpCode Stelem_I4;
- public static readonly System.Reflection.Emit.OpCode Stelem_I8;
- public static readonly System.Reflection.Emit.OpCode Stelem_R4;
- public static readonly System.Reflection.Emit.OpCode Stelem_R8;
- public static readonly System.Reflection.Emit.OpCode Stelem_Ref;
- public static readonly System.Reflection.Emit.OpCode Stfld;
- public static readonly System.Reflection.Emit.OpCode Stind_I;
- public static readonly System.Reflection.Emit.OpCode Stind_I1;
- public static readonly System.Reflection.Emit.OpCode Stind_I2;
- public static readonly System.Reflection.Emit.OpCode Stind_I4;
- public static readonly System.Reflection.Emit.OpCode Stind_I8;
- public static readonly System.Reflection.Emit.OpCode Stind_R4;
- public static readonly System.Reflection.Emit.OpCode Stind_R8;
- public static readonly System.Reflection.Emit.OpCode Stind_Ref;
- public static readonly System.Reflection.Emit.OpCode Stloc;
- public static readonly System.Reflection.Emit.OpCode Stloc_0;
- public static readonly System.Reflection.Emit.OpCode Stloc_1;
- public static readonly System.Reflection.Emit.OpCode Stloc_2;
- public static readonly System.Reflection.Emit.OpCode Stloc_3;
- public static readonly System.Reflection.Emit.OpCode Stloc_S;
- public static readonly System.Reflection.Emit.OpCode Stobj;
- public static readonly System.Reflection.Emit.OpCode Stsfld;
- public static readonly System.Reflection.Emit.OpCode Sub;
- public static readonly System.Reflection.Emit.OpCode Sub_Ovf;
- public static readonly System.Reflection.Emit.OpCode Sub_Ovf_Un;
- public static readonly System.Reflection.Emit.OpCode Switch;
- public static readonly System.Reflection.Emit.OpCode Tailcall;
- public static readonly System.Reflection.Emit.OpCode Throw;
- public static readonly System.Reflection.Emit.OpCode Unaligned;
- public static readonly System.Reflection.Emit.OpCode Unbox;
- public static readonly System.Reflection.Emit.OpCode Unbox_Any;
- public static readonly System.Reflection.Emit.OpCode Volatile;
- public static readonly System.Reflection.Emit.OpCode Xor;
- public static bool TakesSingleByteArgument(System.Reflection.Emit.OpCode inst) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum OpCodeType
- {
- [Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")]
- Annotation = 0,
- Macro = 1,
- Nternal = 2,
- Objmodel = 3,
- Prefix = 4,
- Primitive = 5,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum OperandType
- {
- InlineBrTarget = 0,
- InlineField = 1,
- InlineI = 2,
- InlineI8 = 3,
- InlineMethod = 4,
- InlineNone = 5,
- [Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")]
- InlinePhi = 6,
- InlineR = 7,
- InlineSig = 9,
- InlineString = 10,
- InlineSwitch = 11,
- InlineTok = 12,
- InlineType = 13,
- InlineVar = 14,
- ShortInlineBrTarget = 15,
- ShortInlineI = 16,
- ShortInlineR = 17,
- ShortInlineVar = 18,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum PackingSize
- {
- Size1 = 1,
- Size128 = 128,
- Size16 = 16,
- Size2 = 2,
- Size32 = 32,
- Size4 = 4,
- Size64 = 64,
- Size8 = 8,
- Unspecified = 0,
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ParameterBuilder
- {
- internal ParameterBuilder() { }
- public virtual int Attributes { get { throw null; } }
- public bool IsIn { get { throw null; } }
- public bool IsOptional { get { throw null; } }
- public bool IsOut { get { throw null; } }
- public virtual string Name { get { throw null; } }
- public virtual int Position { get { throw null; } }
- public virtual System.Reflection.Emit.ParameterToken GetToken() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public virtual void SetConstant(object defaultValue) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct ParameterToken
- {
- public static readonly System.Reflection.Emit.ParameterToken Empty;
- public int Token { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.Reflection.Emit.ParameterToken obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Reflection.Emit.ParameterToken a, System.Reflection.Emit.ParameterToken b) { throw null; }
- public static bool operator !=(System.Reflection.Emit.ParameterToken a, System.Reflection.Emit.ParameterToken b) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum PEFileKinds
- {
- ConsoleApplication = 2,
- Dll = 1,
- WindowApplication = 3,
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class PropertyBuilder : System.Reflection.PropertyInfo
- {
- internal PropertyBuilder() { }
- public override System.Reflection.PropertyAttributes Attributes { get { throw null; } }
- public override bool CanRead { get { throw null; } }
- public override bool CanWrite { get { throw null; } }
- public override System.Type DeclaringType { get { throw null; } }
- public override System.Reflection.Module Module { get { throw null; } }
- public override string Name { get { throw null; } }
- public System.Reflection.Emit.PropertyToken PropertyToken { get { throw null; } }
- public override System.Type PropertyType { get { throw null; } }
- public override System.Type ReflectedType { get { throw null; } }
- [System.Security.SecuritySafeCriticalAttribute]
- public void AddOtherMethod(System.Reflection.Emit.MethodBuilder mdBuilder) { }
- public override System.Reflection.MethodInfo[] GetAccessors(bool nonPublic) { throw null; }
- public override object[] GetCustomAttributes(bool inherit) { throw null; }
- public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; }
- public override System.Reflection.MethodInfo GetGetMethod(bool nonPublic) { throw null; }
- public override System.Reflection.ParameterInfo[] GetIndexParameters() { throw null; }
- public override System.Reflection.MethodInfo GetSetMethod(bool nonPublic) { throw null; }
- public override object GetValue(object obj, object[] index) { throw null; }
- public override object GetValue(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] index, System.Globalization.CultureInfo culture) { throw null; }
- public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetConstant(object defaultValue) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetGetMethod(System.Reflection.Emit.MethodBuilder mdBuilder) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetSetMethod(System.Reflection.Emit.MethodBuilder mdBuilder) { }
- public override void SetValue(object obj, object value, object[] index) { }
- public override void SetValue(object obj, object value, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] index, System.Globalization.CultureInfo culture) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct PropertyToken
- {
- public static readonly System.Reflection.Emit.PropertyToken Empty;
- public int Token { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.Reflection.Emit.PropertyToken obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Reflection.Emit.PropertyToken a, System.Reflection.Emit.PropertyToken b) { throw null; }
- public static bool operator !=(System.Reflection.Emit.PropertyToken a, System.Reflection.Emit.PropertyToken b) { throw null; }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class SignatureHelper
- {
- internal SignatureHelper() { }
- public void AddArgument(System.Type clsArgument) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void AddArgument(System.Type argument, bool pinned) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void AddArgument(System.Type argument, System.Type[] requiredCustomModifiers, System.Type[] optionalCustomModifiers) { }
- public void AddArguments(System.Type[] arguments, System.Type[][] requiredCustomModifiers, System.Type[][] optionalCustomModifiers) { }
- public void AddSentinel() { }
- public override bool Equals(object obj) { throw null; }
- public static System.Reflection.Emit.SignatureHelper GetFieldSigHelper(System.Reflection.Module mod) { throw null; }
- public override int GetHashCode() { throw null; }
- public static System.Reflection.Emit.SignatureHelper GetLocalVarSigHelper() { throw null; }
- public static System.Reflection.Emit.SignatureHelper GetLocalVarSigHelper(System.Reflection.Module mod) { throw null; }
- public static System.Reflection.Emit.SignatureHelper GetMethodSigHelper(System.Reflection.CallingConventions callingConvention, System.Type returnType) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Reflection.Emit.SignatureHelper GetMethodSigHelper(System.Reflection.Module mod, System.Reflection.CallingConventions callingConvention, System.Type returnType) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Reflection.Emit.SignatureHelper GetMethodSigHelper(System.Reflection.Module mod, System.Runtime.InteropServices.CallingConvention unmanagedCallConv, System.Type returnType) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Reflection.Emit.SignatureHelper GetMethodSigHelper(System.Reflection.Module mod, System.Type returnType, System.Type[] parameterTypes) { throw null; }
- public static System.Reflection.Emit.SignatureHelper GetMethodSigHelper(System.Runtime.InteropServices.CallingConvention unmanagedCallingConvention, System.Type returnType) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Reflection.Emit.SignatureHelper GetPropertySigHelper(System.Reflection.Module mod, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[] requiredReturnTypeCustomModifiers, System.Type[] optionalReturnTypeCustomModifiers, System.Type[] parameterTypes, System.Type[][] requiredParameterTypeCustomModifiers, System.Type[][] optionalParameterTypeCustomModifiers) { throw null; }
- public static System.Reflection.Emit.SignatureHelper GetPropertySigHelper(System.Reflection.Module mod, System.Type returnType, System.Type[] parameterTypes) { throw null; }
- public static System.Reflection.Emit.SignatureHelper GetPropertySigHelper(System.Reflection.Module mod, System.Type returnType, System.Type[] requiredReturnTypeCustomModifiers, System.Type[] optionalReturnTypeCustomModifiers, System.Type[] parameterTypes, System.Type[][] requiredParameterTypeCustomModifiers, System.Type[][] optionalParameterTypeCustomModifiers) { throw null; }
- public byte[] GetSignature() { throw null; }
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct SignatureToken
- {
- public static readonly System.Reflection.Emit.SignatureToken Empty;
- public int Token { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.Reflection.Emit.SignatureToken obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Reflection.Emit.SignatureToken a, System.Reflection.Emit.SignatureToken b) { throw null; }
- public static bool operator !=(System.Reflection.Emit.SignatureToken a, System.Reflection.Emit.SignatureToken b) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum StackBehaviour
- {
- Pop0 = 0,
- Pop1 = 1,
- Pop1_pop1 = 2,
- Popi = 3,
- Popi_pop1 = 4,
- Popi_popi = 5,
- Popi_popi_popi = 7,
- Popi_popi8 = 6,
- Popi_popr4 = 8,
- Popi_popr8 = 9,
- Popref = 10,
- Popref_pop1 = 11,
- Popref_popi = 12,
- Popref_popi_pop1 = 28,
- Popref_popi_popi = 13,
- Popref_popi_popi8 = 14,
- Popref_popi_popr4 = 15,
- Popref_popi_popr8 = 16,
- Popref_popi_popref = 17,
- Push0 = 18,
- Push1 = 19,
- Push1_push1 = 20,
- Pushi = 21,
- Pushi8 = 22,
- Pushr4 = 23,
- Pushr8 = 24,
- Pushref = 25,
- Varpop = 26,
- Varpush = 27,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct StringToken
- {
- public int Token { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.Reflection.Emit.StringToken obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Reflection.Emit.StringToken a, System.Reflection.Emit.StringToken b) { throw null; }
- public static bool operator !=(System.Reflection.Emit.StringToken a, System.Reflection.Emit.StringToken b) { throw null; }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class TypeBuilder : System.Reflection.TypeInfo
- {
- internal TypeBuilder() { }
- public const int UnspecifiedTypeSize = 0;
- public override System.Reflection.Assembly Assembly { get { throw null; } }
- public override string AssemblyQualifiedName { get { throw null; } }
- public override System.Type BaseType { get { throw null; } }
- public override System.Reflection.MethodBase DeclaringMethod { get { throw null; } }
- public override System.Type DeclaringType { get { throw null; } }
- public override string FullName { get { throw null; } }
- public override System.Reflection.GenericParameterAttributes GenericParameterAttributes { get { throw null; } }
- public override int GenericParameterPosition { get { throw null; } }
- public override System.Guid GUID { get { throw null; } }
- public override bool IsConstructedGenericType { get { throw null; } }
- public override bool IsGenericParameter { get { throw null; } }
- public override bool IsGenericType { get { throw null; } }
- public override bool IsGenericTypeDefinition { get { throw null; } }
- public override System.Reflection.Module Module { get { throw null; } }
- public override string Name { get { throw null; } }
- public override string Namespace { get { throw null; } }
- public System.Reflection.Emit.PackingSize PackingSize { get { throw null; } }
- public override System.Type ReflectedType { get { throw null; } }
- public int Size { get { throw null; } }
- public override System.RuntimeTypeHandle TypeHandle { get { throw null; } }
- public System.Reflection.Emit.TypeToken TypeToken { get { throw null; } }
- public override System.Type UnderlyingSystemType { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public void AddInterfaceImplementation(System.Type interfaceType) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Type CreateType() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.TypeInfo CreateTypeInfo() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public System.Reflection.Emit.ConstructorBuilder DefineConstructor(System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type[] parameterTypes) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.ConstructorBuilder DefineConstructor(System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type[] parameterTypes, System.Type[][] requiredCustomModifiers, System.Type[][] optionalCustomModifiers) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public System.Reflection.Emit.ConstructorBuilder DefineDefaultConstructor(System.Reflection.MethodAttributes attributes) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.EventBuilder DefineEvent(string name, System.Reflection.EventAttributes attributes, System.Type eventtype) { throw null; }
- public System.Reflection.Emit.FieldBuilder DefineField(string fieldName, System.Type type, System.Reflection.FieldAttributes attributes) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.FieldBuilder DefineField(string fieldName, System.Type type, System.Type[] requiredCustomModifiers, System.Type[] optionalCustomModifiers, System.Reflection.FieldAttributes attributes) { throw null; }
- public System.Reflection.Emit.GenericTypeParameterBuilder[] DefineGenericParameters(params string[] names) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public System.Reflection.Emit.FieldBuilder DefineInitializedData(string name, byte[] data, System.Reflection.FieldAttributes attributes) { throw null; }
- public System.Reflection.Emit.MethodBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes) { throw null; }
- public System.Reflection.Emit.MethodBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention) { throw null; }
- public System.Reflection.Emit.MethodBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[] parameterTypes) { throw null; }
- public System.Reflection.Emit.MethodBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[] returnTypeRequiredCustomModifiers, System.Type[] returnTypeOptionalCustomModifiers, System.Type[] parameterTypes, System.Type[][] parameterTypeRequiredCustomModifiers, System.Type[][] parameterTypeOptionalCustomModifiers) { throw null; }
- public System.Reflection.Emit.MethodBuilder DefineMethod(string name, System.Reflection.MethodAttributes attributes, System.Type returnType, System.Type[] parameterTypes) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public void DefineMethodOverride(System.Reflection.MethodInfo methodInfoBody, System.Reflection.MethodInfo methodInfoDeclaration) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.TypeBuilder DefineNestedType(string name) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.TypeBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.TypeBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, System.Type parent) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public System.Reflection.Emit.TypeBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, System.Type parent, int typeSize) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public System.Reflection.Emit.TypeBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, System.Type parent, System.Reflection.Emit.PackingSize packSize) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public System.Reflection.Emit.TypeBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, System.Type parent, System.Reflection.Emit.PackingSize packSize, int typeSize) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.TypeBuilder DefineNestedType(string name, System.Reflection.TypeAttributes attr, System.Type parent, System.Type[] interfaces) { throw null; }
- public System.Reflection.Emit.PropertyBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[] parameterTypes) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.PropertyBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Reflection.CallingConventions callingConvention, System.Type returnType, System.Type[] returnTypeRequiredCustomModifiers, System.Type[] returnTypeOptionalCustomModifiers, System.Type[] parameterTypes, System.Type[][] parameterTypeRequiredCustomModifiers, System.Type[][] parameterTypeOptionalCustomModifiers) { throw null; }
- public System.Reflection.Emit.PropertyBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Type returnType, System.Type[] parameterTypes) { throw null; }
- public System.Reflection.Emit.PropertyBuilder DefineProperty(string name, System.Reflection.PropertyAttributes attributes, System.Type returnType, System.Type[] returnTypeRequiredCustomModifiers, System.Type[] returnTypeOptionalCustomModifiers, System.Type[] parameterTypes, System.Type[][] parameterTypeRequiredCustomModifiers, System.Type[][] parameterTypeOptionalCustomModifiers) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Reflection.Emit.ConstructorBuilder DefineTypeInitializer() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public System.Reflection.Emit.FieldBuilder DefineUninitializedData(string name, int size, System.Reflection.FieldAttributes attributes) { throw null; }
- protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl() { throw null; }
- public static System.Reflection.ConstructorInfo GetConstructor(System.Type type, System.Reflection.ConstructorInfo constructor) { throw null; }
- protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override object[] GetCustomAttributes(bool inherit) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; }
- public override System.Type GetElementType() { throw null; }
- public override System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.EventInfo[] GetEvents() { throw null; }
- public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public static System.Reflection.FieldInfo GetField(System.Type type, System.Reflection.FieldInfo field) { throw null; }
- public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Type[] GetGenericArguments() { throw null; }
- public override System.Type GetGenericTypeDefinition() { throw null; }
- public override System.Type GetInterface(string name, bool ignoreCase) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public override System.Reflection.InterfaceMapping GetInterfaceMap(System.Type interfaceType) { throw null; }
- public override System.Type[] GetInterfaces() { throw null; }
- public override System.Reflection.MemberInfo[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public static System.Reflection.MethodInfo GetMethod(System.Type type, System.Reflection.MethodInfo method) { throw null; }
- protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { throw null; }
- public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr) { throw null; }
- protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Type returnType, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; }
- protected override bool HasElementTypeImpl() { throw null; }
- public override object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParameters) { throw null; }
- protected override bool IsArrayImpl() { throw null; }
- public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo) { throw null; }
- public override bool IsAssignableFrom(System.Type c) { throw null; }
- protected override bool IsByRefImpl() { throw null; }
- protected override bool IsCOMObjectImpl() { throw null; }
- public bool IsCreated() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; }
- protected override bool IsPointerImpl() { throw null; }
- protected override bool IsPrimitiveImpl() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public override bool IsSubclassOf(System.Type c) { throw null; }
- public override System.Type MakeArrayType() { throw null; }
- public override System.Type MakeArrayType(int rank) { throw null; }
- public override System.Type MakeByRefType() { throw null; }
- public override System.Type MakeGenericType(params System.Type[] typeArguments) { throw null; }
- public override System.Type MakePointerType() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { }
- public void SetParent(System.Type parent) { }
- public override string ToString() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct TypeToken
- {
- public static readonly System.Reflection.Emit.TypeToken Empty;
- public int Token { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.Reflection.Emit.TypeToken obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Reflection.Emit.TypeToken a, System.Reflection.Emit.TypeToken b) { throw null; }
- public static bool operator !=(System.Reflection.Emit.TypeToken a, System.Reflection.Emit.TypeToken b) { throw null; }
- }
-}
-namespace System.Reflection.Metadata
-{
- public static partial class AssemblyExtensions
- {
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe static bool TryGetRawMetadata(this System.Reflection.Assembly assembly, out byte* blob, out int length) { blob = default(byte*); length = default(int); throw null; }
- }
-}
-namespace System.Resources
-{
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IResourceReader : System.Collections.IEnumerable, System.IDisposable
- {
- void Close();
- new System.Collections.IDictionaryEnumerator GetEnumerator();
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class MissingManifestResourceException : System.SystemException
- {
- public MissingManifestResourceException() { }
- protected MissingManifestResourceException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public MissingManifestResourceException(string message) { }
- public MissingManifestResourceException(string message, System.Exception inner) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class MissingSatelliteAssemblyException : System.SystemException
- {
- public MissingSatelliteAssemblyException() { }
- protected MissingSatelliteAssemblyException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public MissingSatelliteAssemblyException(string message) { }
- public MissingSatelliteAssemblyException(string message, System.Exception inner) { }
- public MissingSatelliteAssemblyException(string message, string cultureName) { }
- public string CultureName { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class NeutralResourcesLanguageAttribute : System.Attribute
- {
- public NeutralResourcesLanguageAttribute(string cultureName) { }
- public NeutralResourcesLanguageAttribute(string cultureName, System.Resources.UltimateResourceFallbackLocation location) { }
- public string CultureName { get { throw null; } }
- public System.Resources.UltimateResourceFallbackLocation Location { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ResourceManager
- {
- protected string BaseNameField;
- public static readonly int HeaderVersionNumber;
- public static readonly int MagicNumber;
- protected System.Reflection.Assembly MainAssembly;
- protected ResourceManager() { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public ResourceManager(string baseName, System.Reflection.Assembly assembly) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public ResourceManager(string baseName, System.Reflection.Assembly assembly, System.Type usingResourceSet) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public ResourceManager(System.Type resourceSource) { }
- public virtual string BaseName { get { throw null; } }
- protected System.Resources.UltimateResourceFallbackLocation FallbackLocation { get { throw null; } set { } }
- public virtual bool IgnoreCase { get { throw null; } set { } }
- public virtual System.Type ResourceSetType { get { throw null; } }
- public static System.Resources.ResourceManager CreateFileBasedResourceManager(string baseName, string resourceDir, System.Type usingResourceSet) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- protected static System.Globalization.CultureInfo GetNeutralResourcesLanguage(System.Reflection.Assembly a) { throw null; }
- public virtual object GetObject(string name) { throw null; }
- public virtual object GetObject(string name, System.Globalization.CultureInfo culture) { throw null; }
- protected virtual string GetResourceFileName(System.Globalization.CultureInfo culture) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public virtual System.Resources.ResourceSet GetResourceSet(System.Globalization.CultureInfo culture, bool createIfNotExists, bool tryParents) { throw null; }
- protected static System.Version GetSatelliteContractVersion(System.Reflection.Assembly a) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.IO.UnmanagedMemoryStream GetStream(string name) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.IO.UnmanagedMemoryStream GetStream(string name, System.Globalization.CultureInfo culture) { throw null; }
- public virtual string GetString(string name) { throw null; }
- public virtual string GetString(string name, System.Globalization.CultureInfo culture) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- protected virtual System.Resources.ResourceSet InternalGetResourceSet(System.Globalization.CultureInfo culture, bool createIfNotExists, bool tryParents) { throw null; }
- public virtual void ReleaseAllResources() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ResourceReader : System.Collections.IEnumerable, System.IDisposable, System.Resources.IResourceReader
- {
- [System.Security.SecurityCriticalAttribute]
- public ResourceReader(System.IO.Stream stream) { }
- [System.Security.SecurityCriticalAttribute]
- public ResourceReader(string fileName) { }
- public void Close() { }
- public void Dispose() { }
- public System.Collections.IDictionaryEnumerator GetEnumerator() { throw null; }
- public void GetResourceData(string resourceName, out string resourceType, out byte[] resourceData) { resourceType = default(string); resourceData = default(byte[]); }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ResourceSet : System.Collections.IEnumerable, System.IDisposable
- {
- protected System.Resources.IResourceReader Reader;
- protected ResourceSet() { }
- [System.Security.SecurityCriticalAttribute]
- public ResourceSet(System.IO.Stream stream) { }
- public ResourceSet(System.Resources.IResourceReader reader) { }
- [System.Security.SecurityCriticalAttribute]
- public ResourceSet(string fileName) { }
- public virtual void Close() { }
- public void Dispose() { }
- protected virtual void Dispose(bool disposing) { }
- public virtual System.Type GetDefaultReader() { throw null; }
- public virtual System.Type GetDefaultWriter() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual System.Collections.IDictionaryEnumerator GetEnumerator() { throw null; }
- public virtual object GetObject(string name) { throw null; }
- public virtual object GetObject(string name, bool ignoreCase) { throw null; }
- public virtual string GetString(string name) { throw null; }
- public virtual string GetString(string name, bool ignoreCase) { throw null; }
- protected virtual void ReadResources() { }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class SatelliteContractVersionAttribute : System.Attribute
- {
- public SatelliteContractVersionAttribute(string version) { }
- public string Version { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum UltimateResourceFallbackLocation
- {
- MainAssembly = 0,
- Satellite = 1,
- }
-}
-namespace System.Runtime
-{
- public enum GCLargeObjectHeapCompactionMode
- {
- CompactOnce = 2,
- Default = 1,
- }
- public enum GCLatencyMode
- {
- Batch = 0,
- Interactive = 1,
- LowLatency = 2,
- NoGCRegion = 4,
- SustainedLowLatency = 3,
- }
- public static partial class GCSettings
- {
- public static bool IsServerGC { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public static System.Runtime.GCLargeObjectHeapCompactionMode LargeObjectHeapCompactionMode { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } [System.Security.SecurityCriticalAttribute]set { } }
- public static System.Runtime.GCLatencyMode LatencyMode { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } [System.Security.SecurityCriticalAttribute]set { } }
- }
-
- public sealed partial class MemoryFailPoint : System.Runtime.ConstrainedExecution.CriticalFinalizerObject, System.IDisposable
- {
- [System.Security.SecurityCriticalAttribute]
- public MemoryFailPoint(int sizeInMegabytes) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Dispose() { }
- ~MemoryFailPoint() { }
- }
-}
-namespace System.Runtime.CompilerServices
-{
- [System.AttributeUsageAttribute((System.AttributeTargets)(256))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AccessedThroughPropertyAttribute : System.Attribute
- {
- public AccessedThroughPropertyAttribute(string propertyName) { }
- public string PropertyName { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64), Inherited=false, AllowMultiple=false)]
- public sealed partial class AsyncStateMachineAttribute : System.Runtime.CompilerServices.StateMachineAttribute
- {
- public AsyncStateMachineAttribute(System.Type stateMachineType) : base (default(System.Type)) { }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct AsyncTaskMethodBuilder
- {
- public System.Threading.Tasks.Task Task { get { throw null; } }
- public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.INotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
- public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.ICriticalNotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
- public static System.Runtime.CompilerServices.AsyncTaskMethodBuilder Create() { throw null; }
- public void SetException(System.Exception exception) { }
- public void SetResult() { }
- public void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine stateMachine) { }
- [System.Diagnostics.DebuggerStepThroughAttribute]
- [System.Security.SecuritySafeCriticalAttribute]
- public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct AsyncTaskMethodBuilder<TResult>
- {
- public System.Threading.Tasks.Task<TResult> Task { get { throw null; } }
- public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.INotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.ICriticalNotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
- public static System.Runtime.CompilerServices.AsyncTaskMethodBuilder<TResult> Create() { throw null; }
- public void SetException(System.Exception exception) { }
- public void SetResult(TResult result) { }
- public void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine stateMachine) { }
- [System.Diagnostics.DebuggerStepThroughAttribute]
- [System.Security.SecuritySafeCriticalAttribute]
- public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct AsyncVoidMethodBuilder
- {
- public void AwaitOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.INotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref TAwaiter awaiter, ref TStateMachine stateMachine) where TAwaiter : System.Runtime.CompilerServices.ICriticalNotifyCompletion where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
- public static System.Runtime.CompilerServices.AsyncVoidMethodBuilder Create() { throw null; }
- public void SetException(System.Exception exception) { }
- public void SetResult() { }
- public void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine stateMachine) { }
- [System.Diagnostics.DebuggerStepThroughAttribute]
- [System.Security.SecuritySafeCriticalAttribute]
- public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(2048), Inherited=false)]
- public sealed partial class CallerFilePathAttribute : System.Attribute
- {
- public CallerFilePathAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(2048), Inherited=false)]
- public sealed partial class CallerLineNumberAttribute : System.Attribute
- {
- public CallerLineNumberAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(2048), Inherited=false)]
- public sealed partial class CallerMemberNameAttribute : System.Attribute
- {
- public CallerMemberNameAttribute() { }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum CompilationRelaxations
- {
- NoStringInterning = 8,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(71))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class CompilationRelaxationsAttribute : System.Attribute
- {
- public CompilationRelaxationsAttribute(int relaxations) { }
- public CompilationRelaxationsAttribute(System.Runtime.CompilerServices.CompilationRelaxations relaxations) { }
- public int CompilationRelaxations { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(32767), Inherited=true)]
- public sealed partial class CompilerGeneratedAttribute : System.Attribute
- {
- public CompilerGeneratedAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(4))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class CompilerGlobalScopeAttribute : System.Attribute
- {
- public CompilerGlobalScopeAttribute() { }
- }
- public static partial class CompilerMarshalOverride
- {
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public sealed partial class ConditionalWeakTable<TKey, TValue> where TKey : class where TValue : class
- {
- [System.Security.SecuritySafeCriticalAttribute]
- public ConditionalWeakTable() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Add(TKey key, TValue value) { }
- ~ConditionalWeakTable() { }
- public TValue GetOrCreateValue(TKey key) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public TValue GetValue(TKey key, System.Runtime.CompilerServices.ConditionalWeakTable<TKey, TValue>.CreateValueCallback createValueCallback) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public bool Remove(TKey key) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public bool TryGetValue(TKey key, out TValue value) { value = default(TValue); throw null; }
- public delegate TValue CreateValueCallback(TKey key);
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct ConfiguredTaskAwaitable
- {
- public System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter GetAwaiter() { throw null; }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct ConfiguredTaskAwaiter : System.Runtime.CompilerServices.ICriticalNotifyCompletion, System.Runtime.CompilerServices.INotifyCompletion
- {
- public bool IsCompleted { get { throw null; } }
- public void GetResult() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void OnCompleted(System.Action continuation) { }
- [System.Security.SecurityCriticalAttribute]
- public void UnsafeOnCompleted(System.Action continuation) { }
- }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct ConfiguredTaskAwaitable<TResult>
- {
- public System.Runtime.CompilerServices.ConfiguredTaskAwaitable<TResult>.ConfiguredTaskAwaiter GetAwaiter() { throw null; }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct ConfiguredTaskAwaiter : System.Runtime.CompilerServices.ICriticalNotifyCompletion, System.Runtime.CompilerServices.INotifyCompletion
- {
- public bool IsCompleted { get { throw null; } }
- public TResult GetResult() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public void OnCompleted(System.Action continuation) { }
- [System.Security.SecurityCriticalAttribute]
- public void UnsafeOnCompleted(System.Action continuation) { }
- }
- }
- public static partial class ContractHelper
- {
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1030:UseEventsWhereAppropriate")]
- [System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static string RaiseContractFailedEvent(System.Diagnostics.Contracts.ContractFailureKind failureKind, string userMessage, string conditionText, System.Exception innerException) { throw null; }
- [System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static void TriggerFailure(System.Diagnostics.Contracts.ContractFailureKind kind, string displayMessage, string userMessage, string conditionText, System.Exception innerException) { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(2304), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class CustomConstantAttribute : System.Attribute
- {
- protected CustomConstantAttribute() { }
- public abstract object Value { get; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(2304), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DateTimeConstantAttribute : System.Runtime.CompilerServices.CustomConstantAttribute
- {
- public DateTimeConstantAttribute(long ticks) { }
- public override object Value { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(2304), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DecimalConstantAttribute : System.Attribute
- {
- public DecimalConstantAttribute(byte scale, byte sign, int hi, int mid, int low) { }
- [System.CLSCompliantAttribute(false)]
- public DecimalConstantAttribute(byte scale, byte sign, uint hi, uint mid, uint low) { }
- public decimal Value { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1))]
- public sealed partial class DefaultDependencyAttribute : System.Attribute
- {
- public DefaultDependencyAttribute(System.Runtime.CompilerServices.LoadHint loadHintArgument) { }
- public System.Runtime.CompilerServices.LoadHint LoadHint { get { return default(System.Runtime.CompilerServices.LoadHint); } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=true)]
- public sealed partial class DependencyAttribute : System.Attribute
- {
- public DependencyAttribute(string dependentAssemblyArgument, System.Runtime.CompilerServices.LoadHint loadHintArgument) { }
- public string DependentAssembly { get { return default(string); } }
- public System.Runtime.CompilerServices.LoadHint LoadHint { get { return default(System.Runtime.CompilerServices.LoadHint); } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=false, Inherited=false)]
- public sealed partial class DisablePrivateReflectionAttribute : System.Attribute
- {
- public DisablePrivateReflectionAttribute() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class DiscardableAttribute : System.Attribute
- {
- public DiscardableAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(69))]
- public sealed partial class ExtensionAttribute : System.Attribute
- {
- public ExtensionAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(256))]
- public sealed partial class FixedAddressValueTypeAttribute : System.Attribute
- {
- public FixedAddressValueTypeAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(256), Inherited=false)]
- public sealed partial class FixedBufferAttribute : System.Attribute
- {
- public FixedBufferAttribute(System.Type elementType, int length) { }
- public System.Type ElementType { get { throw null; } }
- public int Length { get { throw null; } }
- }
- public static partial class FormattableStringFactory
- {
- public static System.FormattableString Create(string format, params object[] arguments) { throw null; }
- }
- public partial interface IAsyncStateMachine
- {
- void MoveNext();
- void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine stateMachine);
- }
- public partial interface ICastable
- {
- System.RuntimeTypeHandle GetImplType(System.RuntimeTypeHandle interfaceType);
- bool IsInstanceOfInterface(System.RuntimeTypeHandle interfaceType, out System.Exception castError);
- }
- public partial interface ICriticalNotifyCompletion : System.Runtime.CompilerServices.INotifyCompletion
- {
- [System.Security.SecurityCriticalAttribute]
- void UnsafeOnCompleted(System.Action continuation);
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(128), Inherited=true)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class IndexerNameAttribute : System.Attribute
- {
- public IndexerNameAttribute(string indexerName) { }
- }
- public partial interface INotifyCompletion
- {
- void OnCompleted(System.Action continuation);
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=true, Inherited=false)]
- public sealed partial class InternalsVisibleToAttribute : System.Attribute
- {
- public InternalsVisibleToAttribute(string assemblyName) { }
- public bool AllInternalsVisible { get { throw null; } set { } }
- public string AssemblyName { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static partial class IsVolatile
- {
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64), Inherited=false, AllowMultiple=false)]
- public sealed partial class IteratorStateMachineAttribute : System.Runtime.CompilerServices.StateMachineAttribute
- {
- public IteratorStateMachineAttribute(System.Type stateMachineType) : base (default(System.Type)) { }
- }
- public enum LoadHint {
- Always = 1,
- Default = 0,
- Sometimes = 2,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum MethodCodeType
- {
- IL = 0,
- Native = 1,
- OPTIL = 2,
- Runtime = 3,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(96), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class MethodImplAttribute : System.Attribute
- {
- public System.Runtime.CompilerServices.MethodCodeType MethodCodeType;
- public MethodImplAttribute() { }
- public MethodImplAttribute(short value) { }
- public MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions methodImplOptions) { }
- public System.Runtime.CompilerServices.MethodImplOptions Value { get { throw null; } }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum MethodImplOptions
- {
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- AggressiveInlining = 256,
- ForwardRef = 16,
- InternalCall = 4096,
- NoInlining = 8,
- NoOptimization = 64,
- PreserveSig = 128,
- Synchronized = 32,
- Unmanaged = 4,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=false)]
- public sealed partial class ReferenceAssemblyAttribute : System.Attribute
- {
- public ReferenceAssemblyAttribute() { }
- public ReferenceAssemblyAttribute(string description) { }
- public string Description { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false, AllowMultiple=false)]
- public sealed partial class RuntimeCompatibilityAttribute : System.Attribute
- {
- public RuntimeCompatibilityAttribute() { }
- public bool WrapNonExceptionThrows { get { throw null; } set { } }
- }
- public static partial class RuntimeHelpers
- {
- public static new bool Equals(object o1, object o2) { throw null; }
- public static int OffsetToStringData { get { throw null; } }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static void EnsureSufficientExecutionStack() { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static int GetHashCode(object o) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static object GetObjectValue(object obj) { throw null; }
- public static object GetUninitializedObject(System.Type type) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static void InitializeArray(System.Array array, System.RuntimeFieldHandle fldHandle) { }
- public static void RunClassConstructor(System.RuntimeTypeHandle type) { }
- public static void RunModuleConstructor(System.ModuleHandle module) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static void ExecuteCodeWithGuaranteedCleanup(System.Runtime.CompilerServices.RuntimeHelpers.TryCode code, System.Runtime.CompilerServices.RuntimeHelpers.CleanupCode backoutCode, object userData) { }
- [System.Security.SecurityCriticalAttribute]
- public delegate void CleanupCode(object userData, bool exceptionThrown);
- [System.Security.SecurityCriticalAttribute]
- public delegate void TryCode(object userData);
- [System.Runtime.ConstrainedExecution.ReliabilityContractAttribute((System.Runtime.ConstrainedExecution.Consistency)(3), (System.Runtime.ConstrainedExecution.Cer)(1))]
- [System.Security.SecurityCriticalAttribute]
- public static void PrepareConstrainedRegions() { }
- [System.Runtime.ConstrainedExecution.ReliabilityContractAttribute((System.Runtime.ConstrainedExecution.Consistency)(3), (System.Runtime.ConstrainedExecution.Cer)(1))]
- [System.Security.SecurityCriticalAttribute]
- public static void PrepareConstrainedRegionsNoOP() { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static void PrepareContractedDelegate(System.Delegate d) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static void PrepareDelegate(System.Delegate d) { }
- [System.Security.SecurityCriticalAttribute]
- public static void PrepareMethod(System.RuntimeMethodHandle method) { }
- [System.Security.SecurityCriticalAttribute]
- public static void PrepareMethod(System.RuntimeMethodHandle method, System.RuntimeTypeHandle[] instantiation) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Runtime.ConstrainedExecution.ReliabilityContractAttribute((System.Runtime.ConstrainedExecution.Consistency)(3), (System.Runtime.ConstrainedExecution.Cer)(1))]
- [System.Security.SecurityCriticalAttribute]
- public static void ProbeForSufficientStack() { }
- }
- public sealed partial class RuntimeWrappedException : System.Exception
- {
- internal RuntimeWrappedException() { }
- public object WrappedException { get { return default(object); } }
- [System.Security.SecurityCriticalAttribute]
- public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(972))]
- public sealed partial class SpecialNameAttribute : System.Attribute
- {
- public SpecialNameAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)]
- public sealed partial class StringFreezingAttribute : System.Attribute
- {
- public StringFreezingAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64), Inherited=false, AllowMultiple=false)]
- public partial class StateMachineAttribute : System.Attribute
- {
- public StateMachineAttribute(System.Type stateMachineType) { }
- public System.Type StateMachineType { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
- }
- [System.AttributeUsage((System.AttributeTargets)(1) | (System.AttributeTargets)(2))]
- public sealed partial class SuppressIldasmAttribute : System.Attribute
- {
- public SuppressIldasmAttribute() { }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct TaskAwaiter : System.Runtime.CompilerServices.ICriticalNotifyCompletion, System.Runtime.CompilerServices.INotifyCompletion
- {
- public bool IsCompleted { get { throw null; } }
- public void GetResult() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void OnCompleted(System.Action continuation) { }
- [System.Security.SecurityCriticalAttribute]
- public void UnsafeOnCompleted(System.Action continuation) { }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct TaskAwaiter<TResult> : System.Runtime.CompilerServices.ICriticalNotifyCompletion, System.Runtime.CompilerServices.INotifyCompletion
- {
- public bool IsCompleted { get { throw null; } }
- public TResult GetResult() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public void OnCompleted(System.Action continuation) { }
- [System.Security.SecurityCriticalAttribute]
- public void UnsafeOnCompleted(System.Action continuation) { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(5148), Inherited=false, AllowMultiple=false)]
- public sealed partial class TypeForwardedFromAttribute : System.Attribute
- {
- public TypeForwardedFromAttribute(string assemblyFullName) { }
- public string AssemblyFullName { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=true, Inherited=false)]
- public sealed partial class TypeForwardedToAttribute : System.Attribute
- {
- public TypeForwardedToAttribute(System.Type destination) { }
- public System.Type Destination { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(8))]
- public sealed partial class UnsafeValueTypeAttribute : System.Attribute
- {
- public UnsafeValueTypeAttribute() { }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Size=1)]
- public partial struct YieldAwaitable
- {
- public System.Runtime.CompilerServices.YieldAwaitable.YieldAwaiter GetAwaiter() { throw null; }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Size=1)]
- public partial struct YieldAwaiter : System.Runtime.CompilerServices.ICriticalNotifyCompletion, System.Runtime.CompilerServices.INotifyCompletion
- {
- public bool IsCompleted { get { throw null; } }
- public void GetResult() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void OnCompleted(System.Action continuation) { }
- [System.Security.SecurityCriticalAttribute]
- public void UnsafeOnCompleted(System.Action continuation) { }
- }
- }
-}
-namespace System.Runtime.ConstrainedExecution
-{
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class CriticalFinalizerObject
- {
- [System.Security.SecuritySafeCriticalAttribute]
- protected CriticalFinalizerObject() { }
- ~CriticalFinalizerObject() { }
- }
-
- public enum Cer
- {
- MayFail = 1,
- None = 0,
- Success = 2,
- }
- public enum Consistency
- {
- MayCorruptAppDomain = 1,
- MayCorruptInstance = 2,
- MayCorruptProcess = 0,
- WillNotCorruptState = 3,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1133), Inherited=false)]
- public sealed partial class ReliabilityContractAttribute : System.Attribute
- {
- public ReliabilityContractAttribute(System.Runtime.ConstrainedExecution.Consistency consistencyGuarantee, System.Runtime.ConstrainedExecution.Cer cer) { }
- public System.Runtime.ConstrainedExecution.Cer Cer { get { return default(System.Runtime.ConstrainedExecution.Cer); } }
- public System.Runtime.ConstrainedExecution.Consistency ConsistencyGuarantee { get { return default(System.Runtime.ConstrainedExecution.Consistency); } }
- }
-}
-namespace System.Runtime.ExceptionServices
-{
- public sealed partial class ExceptionDispatchInfo
- {
- internal ExceptionDispatchInfo() { }
- public System.Exception SourceException { get { throw null; } }
- public static System.Runtime.ExceptionServices.ExceptionDispatchInfo Capture(System.Exception source) { throw null; }
- public void Throw() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64), AllowMultiple=false, Inherited=false)]
- public sealed partial class HandleProcessCorruptedStateExceptionsAttribute : System.Attribute
- {
- public HandleProcessCorruptedStateExceptionsAttribute() { }
- }
- public sealed partial class FirstChanceExceptionEventArgs : EventArgs
- {
- public FirstChanceExceptionEventArgs(Exception exception) { }
- public Exception Exception { get { throw null; } }
- }
-}
-namespace System.Runtime.InteropServices
-{
- [System.AttributeUsageAttribute((System.AttributeTargets)(64), AllowMultiple=false, Inherited=false)]
- public sealed partial class AllowReversePInvokeCallsAttribute : System.Attribute
- {
- public AllowReversePInvokeCallsAttribute() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct ArrayWithOffset
- {
- [System.Security.SecuritySafeCriticalAttribute]
- public ArrayWithOffset(object array, int offset) { throw null;}
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.Runtime.InteropServices.ArrayWithOffset obj) { throw null; }
- public object GetArray() { throw null; }
- public override int GetHashCode() { throw null; }
- public int GetOffset() { throw null; }
- public static bool operator ==(System.Runtime.InteropServices.ArrayWithOffset a, System.Runtime.InteropServices.ArrayWithOffset b) { throw null; }
- public static bool operator !=(System.Runtime.InteropServices.ArrayWithOffset a, System.Runtime.InteropServices.ArrayWithOffset b) { throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1037), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class BestFitMappingAttribute : System.Attribute
- {
- public bool ThrowOnUnmappableChar;
- public BestFitMappingAttribute(bool BestFitMapping) { }
- public bool BestFitMapping { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class BStrWrapper
- {
- [System.Security.SecuritySafeCriticalAttribute]
- public BStrWrapper(object value) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public BStrWrapper(string value) { }
- public string WrappedObject { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum CallingConvention
- {
- Cdecl = 2,
- FastCall = 5,
- StdCall = 3,
- ThisCall = 4,
- Winapi = 1,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum CharSet
- {
- Ansi = 2,
- Auto = 4,
- None = 1,
- Unicode = 3,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(5), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ClassInterfaceAttribute : System.Attribute
- {
- public ClassInterfaceAttribute(short classInterfaceType) { }
- public ClassInterfaceAttribute(System.Runtime.InteropServices.ClassInterfaceType classInterfaceType) { }
- public System.Runtime.InteropServices.ClassInterfaceType Value { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum ClassInterfaceType
- {
- AutoDispatch = 1,
- AutoDual = 2,
- None = 0,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1024), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class CoClassAttribute : System.Attribute
- {
- public CoClassAttribute(System.Type coClass) { }
- public System.Type CoClass { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(4), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ComDefaultInterfaceAttribute : System.Attribute
- {
- public ComDefaultInterfaceAttribute(System.Type defaultInterface) { }
- public System.Type Value { get { throw null; } }
- }
- public static partial class ComEventsHelper
- {
- [System.Security.SecurityCriticalAttribute]
- public static void Combine(object rcw, System.Guid iid, int dispid, System.Delegate d) { }
- [System.Security.SecurityCriticalAttribute]
- public static System.Delegate Remove(object rcw, System.Guid iid, int dispid, System.Delegate d) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class COMException : System.Runtime.InteropServices.ExternalException
- {
- public COMException() { }
- public COMException(string message) { }
- public COMException(string message, System.Exception inner) { }
- public COMException(string message, int errorCode) { }
- protected COMException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- public override string ToString() { throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1028), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ComImportAttribute : System.Attribute
- {
- public ComImportAttribute() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum ComInterfaceType
- {
- InterfaceIsDual = 0,
- InterfaceIsIDispatch = 2,
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- InterfaceIsIInspectable = 3,
- InterfaceIsIUnknown = 1,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum ComMemberType
- {
- Method = 0,
- PropGet = 1,
- PropSet = 2,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(4), Inherited=true)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ComSourceInterfacesAttribute : System.Attribute
- {
- public ComSourceInterfacesAttribute(string sourceInterfaces) { }
- public ComSourceInterfacesAttribute(System.Type sourceInterface) { }
- public ComSourceInterfacesAttribute(System.Type sourceInterface1, System.Type sourceInterface2) { }
- public ComSourceInterfacesAttribute(System.Type sourceInterface1, System.Type sourceInterface2, System.Type sourceInterface3) { }
- public ComSourceInterfacesAttribute(System.Type sourceInterface1, System.Type sourceInterface2, System.Type sourceInterface3, System.Type sourceInterface4) { }
- public string Value { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(5597), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ComVisibleAttribute : System.Attribute
- {
- public ComVisibleAttribute(bool visibility) { }
- public bool Value { get { throw null; } }
- }
- [System.Security.SecurityCriticalAttribute]
- public abstract partial class CriticalHandle : System.Runtime.ConstrainedExecution.CriticalFinalizerObject, System.IDisposable
- {
- protected System.IntPtr handle;
- protected CriticalHandle(System.IntPtr invalidHandleValue) { }
- public bool IsClosed { get { throw null; } }
- public abstract bool IsInvalid { get; }
- [System.Security.SecurityCriticalAttribute]
- public void Close() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Dispose() { }
- [System.Security.SecurityCriticalAttribute]
- protected virtual void Dispose(bool disposing) { }
- ~CriticalHandle() { }
- protected abstract bool ReleaseHandle();
- protected void SetHandle(System.IntPtr handle) { }
- public void SetHandleAsInvalid() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class CurrencyWrapper
- {
- public CurrencyWrapper(decimal obj) { }
- public CurrencyWrapper(object obj) { }
- public decimal WrappedObject { get { throw null; } }
- }
- public enum CustomQueryInterfaceMode
- {
- Allow = 1,
- Ignore = 0,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public enum CustomQueryInterfaceResult
- {
- Failed = 2,
- Handled = 0,
- NotHandled = 1,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(2), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DefaultCharSetAttribute : System.Attribute
- {
- public DefaultCharSetAttribute(System.Runtime.InteropServices.CharSet charSet) { }
- public System.Runtime.InteropServices.CharSet CharSet { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(65), AllowMultiple=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public sealed partial class DefaultDllImportSearchPathsAttribute : System.Attribute
- {
- public DefaultDllImportSearchPathsAttribute(System.Runtime.InteropServices.DllImportSearchPath paths) { }
- public System.Runtime.InteropServices.DllImportSearchPath Paths { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DispatchWrapper
- {
- [System.Security.SecuritySafeCriticalAttribute]
- public DispatchWrapper(object obj) { }
- public object WrappedObject { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(960), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DispIdAttribute : System.Attribute
- {
- public DispIdAttribute(int dispId) { }
- public int Value { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class DllImportAttribute : System.Attribute
- {
- public bool BestFitMapping;
- public System.Runtime.InteropServices.CallingConvention CallingConvention;
- public System.Runtime.InteropServices.CharSet CharSet;
- public string EntryPoint;
- public bool ExactSpelling;
- public bool PreserveSig;
- public bool SetLastError;
- public bool ThrowOnUnmappableChar;
- public DllImportAttribute(string dllName) { }
- public string Value { get { throw null; } }
- }
- [System.FlagsAttribute]
- public enum DllImportSearchPath
- {
- ApplicationDirectory = 512,
- AssemblyDirectory = 2,
- LegacyBehavior = 0,
- SafeDirectories = 4096,
- System32 = 2048,
- UseDllDirectoryForDependencies = 256,
- UserDirectories = 1024,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ErrorWrapper
- {
- [System.Security.SecuritySafeCriticalAttribute]
- public ErrorWrapper(System.Exception e) { }
- public ErrorWrapper(int errorCode) { }
- public ErrorWrapper(object errorCode) { }
- public int ErrorCode { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ExternalException : System.SystemException
- {
- public ExternalException() { }
- protected ExternalException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public ExternalException(string message) { }
- public ExternalException(string message, System.Exception inner) { }
- public ExternalException(string message, int errorCode) { }
- public virtual int ErrorCode { get { throw null; } }
- public override string ToString() { throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(256), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class FieldOffsetAttribute : System.Attribute
- {
- public FieldOffsetAttribute(int offset) { }
- public int Value { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct GCHandle
- {
- public bool IsAllocated { get { throw null; } }
- public object Target { [System.Security.SecurityCriticalAttribute]get { throw null; } [System.Security.SecurityCriticalAttribute]set { } }
- [System.Security.SecurityCriticalAttribute]
- public System.IntPtr AddrOfPinnedObject() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.Runtime.InteropServices.GCHandle Alloc(object value) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.Runtime.InteropServices.GCHandle Alloc(object value, System.Runtime.InteropServices.GCHandleType type) { throw null; }
- public override bool Equals(object o) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public void Free() { }
- [System.Security.SecurityCriticalAttribute]
- public static System.Runtime.InteropServices.GCHandle FromIntPtr(System.IntPtr value) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Runtime.InteropServices.GCHandle a, System.Runtime.InteropServices.GCHandle b) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static explicit operator System.Runtime.InteropServices.GCHandle (System.IntPtr value) { throw null; }
- public static explicit operator System.IntPtr (System.Runtime.InteropServices.GCHandle value) { throw null; }
- public static bool operator !=(System.Runtime.InteropServices.GCHandle a, System.Runtime.InteropServices.GCHandle b) { throw null; }
- public static System.IntPtr ToIntPtr(System.Runtime.InteropServices.GCHandle value) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum GCHandleType
- {
- Normal = 2,
- Pinned = 3,
- Weak = 0,
- WeakTrackResurrection = 1,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(5149), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class GuidAttribute : System.Attribute
- {
- public GuidAttribute(string guid) { }
- public string Value { get { throw null; } }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial struct HandleRef
- {
- public HandleRef(object wrapper, System.IntPtr handle) { throw null;}
- public System.IntPtr Handle { get { throw null; } }
- public object Wrapper { get { throw null; } }
- public static explicit operator System.IntPtr (System.Runtime.InteropServices.HandleRef value) { throw null; }
- public static System.IntPtr ToIntPtr(System.Runtime.InteropServices.HandleRef value) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface ICustomAdapter
- {
- object GetUnderlyingObject();
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface ICustomFactory
- {
- MarshalByRefObject CreateInstance(Type serverType);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface ICustomMarshaler
- {
- object MarshalNativeToManaged(System.IntPtr pNativeData);
- System.IntPtr MarshalManagedToNative(object ManagedObj);
- void CleanUpNativeData(System.IntPtr pNativeData);
- void CleanUpManagedData(object ManagedObj);
- int GetNativeDataSize();
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public partial interface ICustomQueryInterface
- {
- [System.Security.SecurityCriticalAttribute]
- System.Runtime.InteropServices.CustomQueryInterfaceResult GetInterface(ref System.Guid iid, out System.IntPtr ppv);
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(2048), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class InAttribute : System.Attribute
- {
- public InAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1024), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class InterfaceTypeAttribute : System.Attribute
- {
- public InterfaceTypeAttribute(short interfaceType) { }
- public InterfaceTypeAttribute(System.Runtime.InteropServices.ComInterfaceType interfaceType) { }
- public System.Runtime.InteropServices.ComInterfaceType Value { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class InvalidComObjectException : System.SystemException
- {
- public InvalidComObjectException() { }
- public InvalidComObjectException(string message) { }
- public InvalidComObjectException(string message, System.Exception inner) { }
- protected InvalidComObjectException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class InvalidOleVariantTypeException : System.SystemException
- {
- public InvalidOleVariantTypeException() { }
- public InvalidOleVariantTypeException(string message) { }
- public InvalidOleVariantTypeException(string message, System.Exception inner) { }
- protected InvalidOleVariantTypeException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum LayoutKind
- {
- Auto = 3,
- Explicit = 2,
- Sequential = 0,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class LCIDConversionAttribute : System.Attribute
- {
- public LCIDConversionAttribute(System.Int32 val) { }
- public System.Int32 Value { get { throw null; } }
- }
- [System.Security.SecurityCriticalAttribute]
- public static partial class Marshal
- {
- public static readonly int SystemDefaultCharSize;
- public static readonly int SystemMaxDBCSCharSize;
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static int AddRef(System.IntPtr pUnk) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr AllocCoTaskMem(int cb) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr AllocHGlobal(int cb) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr AllocHGlobal(System.IntPtr cb) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static bool AreComObjectsAvailableForCleanup() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static object BindToMoniker(string monikerName) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCritical]
- public static void ChangeWrapperHandleStrength(object otp, bool fIsWeak) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static void CleanupUnusedObjectsInCurrentContext() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(byte[] source, int startIndex, System.IntPtr destination, int length) { }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(char[] source, int startIndex, System.IntPtr destination, int length) { }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(double[] source, int startIndex, System.IntPtr destination, int length) { }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(short[] source, int startIndex, System.IntPtr destination, int length) { }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(int[] source, int startIndex, System.IntPtr destination, int length) { }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(long[] source, int startIndex, System.IntPtr destination, int length) { }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(System.IntPtr source, byte[] destination, int startIndex, int length) { }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(System.IntPtr source, char[] destination, int startIndex, int length) { }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(System.IntPtr source, double[] destination, int startIndex, int length) { }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(System.IntPtr source, short[] destination, int startIndex, int length) { }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(System.IntPtr source, int[] destination, int startIndex, int length) { }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(System.IntPtr source, long[] destination, int startIndex, int length) { }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(System.IntPtr source, System.IntPtr[] destination, int startIndex, int length) { }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(System.IntPtr source, float[] destination, int startIndex, int length) { }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(System.IntPtr[] source, int startIndex, System.IntPtr destination, int length) { }
- [System.Security.SecurityCriticalAttribute]
- public static void Copy(float[] source, int startIndex, System.IntPtr destination, int length) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static System.IntPtr CreateAggregatedObject(System.IntPtr pOuter, object o) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr CreateAggregatedObject<T>(System.IntPtr pOuter, T o) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static object CreateWrapperOfType(object o, System.Type t) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static TWrapper CreateWrapperOfType<T, TWrapper>(T o) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public static void DestroyStructure(System.IntPtr ptr, System.Type structuretype) { }
- [System.Security.SecurityCriticalAttribute]
- public static void DestroyStructure<T>(System.IntPtr ptr) { }
- [System.Security.SecurityCriticalAttribute]
- public static int FinalReleaseComObject(object o) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static void FreeBSTR(System.IntPtr ptr) { }
- [System.Security.SecurityCriticalAttribute]
- public static void FreeCoTaskMem(System.IntPtr ptr) { }
- [System.Security.SecurityCriticalAttribute]
- public static void FreeHGlobal(System.IntPtr hglobal) { }
- [System.Security.SecurityCriticalAttribute]
- public static Guid GenerateGuidForType(System.Type type) { throw null; }
- [System.Security.SecurityCritical]
- public static string GenerateProgIdForType(System.Type type) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr GetComInterfaceForObject(object o, System.Type T) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr GetComInterfaceForObject(object o, System.Type T, System.Runtime.InteropServices.CustomQueryInterfaceMode mode) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr GetComInterfaceForObject<T, TInterface>(T o) { throw null; }
- [System.Security.SecurityCritical]
- public static object GetComObjectData(object obj, object key) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.Delegate GetDelegateForFunctionPointer(System.IntPtr ptr, System.Type t) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static TDelegate GetDelegateForFunctionPointer<TDelegate>(System.IntPtr ptr) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static int GetExceptionCode() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.Exception GetExceptionForHR(int errorCode) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.Exception GetExceptionForHR(int errorCode, System.IntPtr errorInfo) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr GetFunctionPointerForDelegate(System.Delegate d) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr GetFunctionPointerForDelegate<TDelegate>(TDelegate d) { throw null; }
- [System.Security.SecurityCritical]
- public static System.IntPtr GetHINSTANCE(System.Reflection.Module m) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static int GetHRForException(System.Exception e) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static int GetHRForLastWin32Error() { throw null; }
- [System.Security.SecurityCritical]
- public static System.IntPtr GetIDispatchForObject(object o) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr GetIUnknownForObject(object o) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static int GetLastWin32Error() { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static void GetNativeVariantForObject(object obj, System.IntPtr pDstNativeVariant) { }
- [System.Security.SecurityCriticalAttribute]
- public static void GetNativeVariantForObject<T>(T obj, System.IntPtr pDstNativeVariant) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static object GetObjectForIUnknown(System.IntPtr pUnk) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static object GetObjectForNativeVariant(System.IntPtr pSrcNativeVariant) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static T GetObjectForNativeVariant<T>(System.IntPtr pSrcNativeVariant) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static object[] GetObjectsForNativeVariants(System.IntPtr aSrcNativeVariant, int cVars) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static T[] GetObjectsForNativeVariants<T>(System.IntPtr aSrcNativeVariant, int cVars) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static int GetStartComSlot(System.Type t) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCritical]
- public static object GetTypedObjectForIUnknown(System.IntPtr pUnk, System.Type t) { throw null; }
- public static System.Type GetTypeFromCLSID(System.Guid clsid) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static string GetTypeInfoName(System.Runtime.InteropServices.ComTypes.ITypeInfo typeInfo) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static object GetUniqueObjectForIUnknown(System.IntPtr unknown) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]public static bool IsComObject(object o) { throw null; }
- public static System.IntPtr OffsetOf(System.Type t, string fieldName) { throw null; }
- public static System.IntPtr OffsetOf<T>(string fieldName) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static void Prelink(System.Reflection.MethodInfo m) { }
- [System.Security.SecurityCriticalAttribute]
- public static void PrelinkAll(System.Type c) { }
- [System.Security.SecurityCriticalAttribute]
- public static string PtrToStringAnsi(System.IntPtr ptr) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static string PtrToStringAnsi(System.IntPtr ptr, int len) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static string PtrToStringAuto(System.IntPtr ptr) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static string PtrToStringAuto(System.IntPtr ptr, int len) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static string PtrToStringBSTR(System.IntPtr ptr) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static string PtrToStringUni(System.IntPtr ptr) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static string PtrToStringUni(System.IntPtr ptr, int len) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static string PtrToStringUTF8(System.IntPtr ptr) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static string PtrToStringUTF8(System.IntPtr ptr, int byteLen) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public static void PtrToStructure(System.IntPtr ptr, object structure) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public static object PtrToStructure(System.IntPtr ptr, System.Type structureType) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static T PtrToStructure<T>(System.IntPtr ptr) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static void PtrToStructure<T>(System.IntPtr ptr, T structure) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static int QueryInterface(System.IntPtr pUnk, ref System.Guid iid, out System.IntPtr ppv) { ppv = default(System.IntPtr); throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static byte ReadByte(System.IntPtr ptr) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static byte ReadByte(System.IntPtr ptr, int ofs) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static byte ReadByte(object ptr, int ofs) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static short ReadInt16(System.IntPtr ptr) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static short ReadInt16(System.IntPtr ptr, int ofs) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static short ReadInt16(object ptr, int ofs) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static int ReadInt32(System.IntPtr ptr) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static int ReadInt32(System.IntPtr ptr, int ofs) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static int ReadInt32(object ptr, int ofs) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static long ReadInt64(System.IntPtr ptr) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static long ReadInt64(System.IntPtr ptr, int ofs) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static long ReadInt64(object ptr, int ofs) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr ReadIntPtr(System.IntPtr ptr) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr ReadIntPtr(System.IntPtr ptr, int ofs) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr ReadIntPtr(object ptr, int ofs) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr ReAllocCoTaskMem(System.IntPtr pv, int cb) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr ReAllocHGlobal(System.IntPtr pv, System.IntPtr cb) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static int Release(System.IntPtr pUnk) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static int ReleaseComObject(object o) { throw null; }
- [System.Security.SecurityCritical]
- public static bool SetComObjectData(object obj, object key, object data) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static int SizeOf(object structure) { throw null; }
- public static int SizeOf(System.Type t) { throw null; }
- public static int SizeOf<T>() { throw null; }
- public static int SizeOf<T>(T structure) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr StringToBSTR(string s) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr StringToCoTaskMemAnsi(string s) { throw null; }
- [System.Security.SecurityCritical]
- public static System.IntPtr StringToCoTaskMemAuto(string s) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr StringToCoTaskMemUni(string s) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr StringToCoTaskMemUTF8(string s) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr StringToHGlobalAnsi(string s) { throw null; }
- [System.Security.SecurityCritical]
- public static System.IntPtr StringToHGlobalAuto(string s) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr StringToHGlobalUni(string s) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public static void StructureToPtr(object structure, System.IntPtr ptr, bool fDeleteOld) { }
- [System.Security.SecurityCriticalAttribute]
- public static void StructureToPtr<T>(T structure, System.IntPtr ptr, bool fDeleteOld) { }
- [System.Security.SecurityCriticalAttribute]
- public static void ThrowExceptionForHR(int errorCode) { }
- [System.Security.SecurityCriticalAttribute]
- public static void ThrowExceptionForHR(int errorCode, System.IntPtr errorInfo) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public static System.IntPtr UnsafeAddrOfPinnedArrayElement(System.Array arr, int index) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr UnsafeAddrOfPinnedArrayElement<T>(T[] arr, int index) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteByte(System.IntPtr ptr, byte val) { }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteByte(System.IntPtr ptr, int ofs, byte val) { }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteByte(object ptr, int ofs, byte val) { ptr = default(object); }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteInt16(System.IntPtr ptr, char val) { }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteInt16(System.IntPtr ptr, short val) { }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteInt16(System.IntPtr ptr, int ofs, char val) { }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteInt16(System.IntPtr ptr, int ofs, short val) { }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteInt16(object ptr, int ofs, char val) { ptr = default(object); }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteInt16(object ptr, int ofs, short val) { ptr = default(object); }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteInt32(System.IntPtr ptr, int val) { }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteInt32(System.IntPtr ptr, int ofs, int val) { }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteInt32(object ptr, int ofs, int val) { ptr = default(object); }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteInt64(System.IntPtr ptr, int ofs, long val) { }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteInt64(System.IntPtr ptr, long val) { }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteInt64(object ptr, int ofs, long val) { ptr = default(object); }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteIntPtr(System.IntPtr ptr, int ofs, System.IntPtr val) { }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteIntPtr(System.IntPtr ptr, System.IntPtr val) { }
- [System.Security.SecurityCriticalAttribute]
- public static void WriteIntPtr(object ptr, int ofs, System.IntPtr val) { ptr = default(object); }
- [System.Security.SecurityCriticalAttribute]
- public static void ZeroFreeBSTR(System.IntPtr s) { }
- [System.Security.SecurityCriticalAttribute]
- public static void ZeroFreeCoTaskMemAnsi(System.IntPtr s) { }
- [System.Security.SecurityCriticalAttribute]
- public static void ZeroFreeCoTaskMemUnicode(System.IntPtr s) { }
- [System.Security.SecurityCriticalAttribute]
- public static void ZeroFreeCoTaskMemUTF8(System.IntPtr s) { }
- [System.Security.SecurityCriticalAttribute]
- public static void ZeroFreeGlobalAllocAnsi(System.IntPtr s) { }
- [System.Security.SecurityCriticalAttribute]
- public static void ZeroFreeGlobalAllocUnicode(System.IntPtr s) { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(10496), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class MarshalAsAttribute : System.Attribute
- {
- public System.Runtime.InteropServices.UnmanagedType ArraySubType;
- public int IidParameterIndex;
- public string MarshalCookie;
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public string MarshalType;
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public System.Type MarshalTypeRef;
- public System.Runtime.InteropServices.VarEnum SafeArraySubType;
- public System.Type SafeArrayUserDefinedSubType;
- public int SizeConst;
- public short SizeParamIndex;
- public MarshalAsAttribute(short unmanagedType) { }
- public MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType unmanagedType) { }
- public System.Runtime.InteropServices.UnmanagedType Value { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class MarshalDirectiveException : System.SystemException
- {
- public MarshalDirectiveException() { }
- public MarshalDirectiveException(string message) { }
- public MarshalDirectiveException(string message, System.Exception inner) { }
- protected MarshalDirectiveException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64))]
- public sealed partial class NativeCallableAttribute : System.Attribute
- {
- public System.Runtime.InteropServices.CallingConvention CallingConvention;
- public string EntryPoint;
- public NativeCallableAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(2048), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class OptionalAttribute : System.Attribute
- {
- public OptionalAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(2048), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class OutAttribute : System.Attribute
- {
- public OutAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class PreserveSigAttribute : System.Attribute
- {
- public PreserveSigAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(4), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ProgIdAttribute : System.Attribute
- {
- public ProgIdAttribute(String val) { }
- public String Value { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class SafeArrayRankMismatchException : System.SystemException
- {
- public SafeArrayRankMismatchException() { }
- public SafeArrayRankMismatchException(string message) { }
- public SafeArrayRankMismatchException(string message, System.Exception inner) { }
- protected SafeArrayRankMismatchException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class SafeArrayTypeMismatchException : System.SystemException
- {
- public SafeArrayTypeMismatchException() { }
- public SafeArrayTypeMismatchException(string message) { }
- public SafeArrayTypeMismatchException(string message, System.Exception inner) { }
- protected SafeArrayTypeMismatchException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Security.SecurityCriticalAttribute]
- public abstract partial class SafeBuffer : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
- {
- protected SafeBuffer(bool ownsHandle) : base(ownsHandle) { }
- [System.CLSCompliantAttribute(false)]
- public ulong ByteLength { get { throw null; } }
- [System.CLSCompliantAttribute(false)]
- public unsafe void AcquirePointer(ref byte* pointer) { }
- [System.CLSCompliantAttribute(false)]
- public void Initialize(uint numElements, uint sizeOfEachElement) { }
- [System.CLSCompliantAttribute(false)]
- public void Initialize(ulong numBytes) { }
- [System.CLSCompliantAttribute(false)]
- public void Initialize<T>(uint numElements) where T : struct { }
- [System.CLSCompliantAttribute(false)]
- public T Read<T>(ulong byteOffset) where T : struct { throw null; }
- [System.CLSCompliantAttribute(false)]
- public void ReadArray<T>(ulong byteOffset, T[] array, int index, int count) where T : struct { }
- public void ReleasePointer() { }
- [System.CLSCompliantAttribute(false)]
- public void Write<T>(ulong byteOffset, T value) where T : struct { }
- [System.CLSCompliantAttribute(false)]
- public void WriteArray<T>(ulong byteOffset, T[] array, int index, int count) where T : struct { }
- }
- [System.Security.SecurityCriticalAttribute]
- public abstract partial class SafeHandle : System.Runtime.ConstrainedExecution.CriticalFinalizerObject, System.IDisposable
- {
- protected System.IntPtr handle;
- protected SafeHandle() { }
- protected SafeHandle(System.IntPtr invalidHandleValue, bool ownsHandle) { }
- public bool IsClosed { get { throw null; } }
- public abstract bool IsInvalid { get; }
- [System.Security.SecurityCriticalAttribute]
- public void Close() { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public void DangerousAddRef(ref bool success) { }
- public System.IntPtr DangerousGetHandle() { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public void DangerousRelease() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public void Dispose() { }
- [System.Security.SecurityCriticalAttribute]
- protected virtual void Dispose(bool disposing) { }
- ~SafeHandle() { }
- protected abstract bool ReleaseHandle();
- protected void SetHandle(System.IntPtr handle) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecurityCriticalAttribute]
- public void SetHandleAsInvalid() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class SEHException : System.Runtime.InteropServices.ExternalException
- {
- public SEHException() { }
- public SEHException(string message) { }
- public SEHException(string message, System.Exception inner) { }
- protected SEHException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- public virtual bool CanResume() { throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(12), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class StructLayoutAttribute : System.Attribute
- {
- public System.Runtime.InteropServices.CharSet CharSet;
- public int Pack;
- public int Size;
- public StructLayoutAttribute(short layoutKind) { }
- public StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind layoutKind) { }
- public System.Runtime.InteropServices.LayoutKind Value { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(5144), AllowMultiple=false, Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public sealed partial class TypeIdentifierAttribute : System.Attribute
- {
- public TypeIdentifierAttribute() { }
- public TypeIdentifierAttribute(string scope, string identifier) { }
- public string Identifier { get { throw null; } }
- public string Scope { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class UnknownWrapper
- {
- public UnknownWrapper(object obj) { }
- public object WrappedObject { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(4096), AllowMultiple=false, Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class UnmanagedFunctionPointerAttribute : System.Attribute
- {
- public bool BestFitMapping;
- public System.Runtime.InteropServices.CharSet CharSet;
- public bool SetLastError;
- public bool ThrowOnUnmappableChar;
- public UnmanagedFunctionPointerAttribute(System.Runtime.InteropServices.CallingConvention callingConvention) { }
- public System.Runtime.InteropServices.CallingConvention CallingConvention { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum UnmanagedType
- {
- AnsiBStr = 35,
- AsAny = 40,
- Bool = 2,
- BStr = 19,
- ByValArray = 30,
- ByValTStr = 23,
- Currency = 15,
- CustomMarshaler = 44,
- Error = 45,
- FunctionPtr = 38,
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- HString = 47,
- I1 = 3,
- I2 = 5,
- I4 = 7,
- I8 = 9,
- IDispatch = 26,
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- IInspectable = 46,
- Interface = 28,
- IUnknown = 25,
- LPArray = 42,
- LPStr = 20,
- LPStruct = 43,
- LPTStr = 22,
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- LPUTF8Str = 48,
- LPWStr = 21,
- R4 = 11,
- R8 = 12,
- SafeArray = 29,
- Struct = 27,
- SysInt = 31,
- SysUInt = 32,
- TBStr = 36,
- U1 = 4,
- U2 = 6,
- U4 = 8,
- U8 = 10,
- VariantBool = 37,
- VBByRefStr = 34,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum VarEnum
- {
- VT_ARRAY = 8192,
- VT_BLOB = 65,
- VT_BLOB_OBJECT = 70,
- VT_BOOL = 11,
- VT_BSTR = 8,
- VT_BYREF = 16384,
- VT_CARRAY = 28,
- VT_CF = 71,
- VT_CLSID = 72,
- VT_CY = 6,
- VT_DATE = 7,
- VT_DECIMAL = 14,
- VT_DISPATCH = 9,
- VT_EMPTY = 0,
- VT_ERROR = 10,
- VT_FILETIME = 64,
- VT_HRESULT = 25,
- VT_I1 = 16,
- VT_I2 = 2,
- VT_I4 = 3,
- VT_I8 = 20,
- VT_INT = 22,
- VT_LPSTR = 30,
- VT_LPWSTR = 31,
- VT_NULL = 1,
- VT_PTR = 26,
- VT_R4 = 4,
- VT_R8 = 5,
- VT_RECORD = 36,
- VT_SAFEARRAY = 27,
- VT_STORAGE = 67,
- VT_STORED_OBJECT = 69,
- VT_STREAM = 66,
- VT_STREAMED_OBJECT = 68,
- VT_UI1 = 17,
- VT_UI2 = 18,
- VT_UI4 = 19,
- VT_UI8 = 21,
- VT_UINT = 23,
- VT_UNKNOWN = 13,
- VT_USERDEFINED = 29,
- VT_VARIANT = 12,
- VT_VECTOR = 4096,
- VT_VOID = 24,
- }
- public sealed partial class VariantWrapper
- {
- public VariantWrapper(object obj) { }
- public object WrappedObject { get { throw null; } }
- }
-}
-namespace System.Runtime.InteropServices.ComTypes
-{
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct BIND_OPTS
- {
- public int cbStruct;
- public int dwTickCountDeadline;
- public int grfFlags;
- public int grfMode;
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Explicit)]
- public partial struct BINDPTR
- {
- [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
- public System.IntPtr lpfuncdesc;
- [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
- public System.IntPtr lptcomp;
- [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
- public System.IntPtr lpvardesc;
- }
- public enum CALLCONV
- {
- CC_CDECL = 1,
- CC_MACPASCAL = 3,
- CC_MAX = 9,
- CC_MPWCDECL = 7,
- CC_MPWPASCAL = 8,
- CC_MSCPASCAL = 2,
- CC_PASCAL = 2,
- CC_RESERVED = 5,
- CC_STDCALL = 4,
- CC_SYSCALL = 6,
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct CONNECTDATA
- {
- public int dwCookie;
- public object pUnk;
- }
- public enum DESCKIND
- {
- DESCKIND_FUNCDESC = 1,
- DESCKIND_IMPLICITAPPOBJ = 4,
- DESCKIND_MAX = 5,
- DESCKIND_NONE = 0,
- DESCKIND_TYPECOMP = 3,
- DESCKIND_VARDESC = 2,
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct DISPPARAMS
- {
- public int cArgs;
- public int cNamedArgs;
- public System.IntPtr rgdispidNamedArgs;
- public System.IntPtr rgvarg;
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct ELEMDESC
- {
- public System.Runtime.InteropServices.ComTypes.ELEMDESC.DESCUNION desc;
- public System.Runtime.InteropServices.ComTypes.TYPEDESC tdesc;
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Explicit)]
- public partial struct DESCUNION
- {
- [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
- public System.Runtime.InteropServices.ComTypes.IDLDESC idldesc;
- [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
- public System.Runtime.InteropServices.ComTypes.PARAMDESC paramdesc;
- }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct EXCEPINFO
- {
- public string bstrDescription;
- public string bstrHelpFile;
- public string bstrSource;
- public int dwHelpContext;
- public System.IntPtr pfnDeferredFillIn;
- public System.IntPtr pvReserved;
- public int scode;
- public short wCode;
- public short wReserved;
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct FILETIME
- {
- public int dwHighDateTime;
- public int dwLowDateTime;
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct FUNCDESC
- {
- public System.Runtime.InteropServices.ComTypes.CALLCONV callconv;
- public short cParams;
- public short cParamsOpt;
- public short cScodes;
- public System.Runtime.InteropServices.ComTypes.ELEMDESC elemdescFunc;
- public System.Runtime.InteropServices.ComTypes.FUNCKIND funckind;
- public System.Runtime.InteropServices.ComTypes.INVOKEKIND invkind;
- public System.IntPtr lprgelemdescParam;
- public System.IntPtr lprgscode;
- public int memid;
- public short oVft;
- public short wFuncFlags;
- }
- [System.FlagsAttribute]
- public enum FUNCFLAGS : short
- {
- FUNCFLAG_FBINDABLE = (short)4,
- FUNCFLAG_FDEFAULTBIND = (short)32,
- FUNCFLAG_FDEFAULTCOLLELEM = (short)256,
- FUNCFLAG_FDISPLAYBIND = (short)16,
- FUNCFLAG_FHIDDEN = (short)64,
- FUNCFLAG_FIMMEDIATEBIND = (short)4096,
- FUNCFLAG_FNONBROWSABLE = (short)1024,
- FUNCFLAG_FREPLACEABLE = (short)2048,
- FUNCFLAG_FREQUESTEDIT = (short)8,
- FUNCFLAG_FRESTRICTED = (short)1,
- FUNCFLAG_FSOURCE = (short)2,
- FUNCFLAG_FUIDEFAULT = (short)512,
- FUNCFLAG_FUSESGETLASTERROR = (short)128,
- }
- public enum FUNCKIND
- {
- FUNC_DISPATCH = 4,
- FUNC_NONVIRTUAL = 2,
- FUNC_PUREVIRTUAL = 1,
- FUNC_STATIC = 3,
- FUNC_VIRTUAL = 0,
- }
- [System.Runtime.InteropServices.GuidAttribute("0000000e-0000-0000-C000-000000000046")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface IBindCtx
- {
- void EnumObjectParam(out System.Runtime.InteropServices.ComTypes.IEnumString ppenum);
- void GetBindOptions(ref System.Runtime.InteropServices.ComTypes.BIND_OPTS pbindopts);
- void GetObjectParam(string pszKey, out object ppunk);
- void GetRunningObjectTable(out System.Runtime.InteropServices.ComTypes.IRunningObjectTable pprot);
- void RegisterObjectBound(object punk);
- void RegisterObjectParam(string pszKey, object punk);
- void ReleaseBoundObjects();
- void RevokeObjectBound(object punk);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int RevokeObjectParam(string pszKey);
- void SetBindOptions(ref System.Runtime.InteropServices.ComTypes.BIND_OPTS pbindopts);
- }
- [System.Runtime.InteropServices.GuidAttribute("B196B286-BAB4-101A-B69C-00AA00341D07")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface IConnectionPoint
- {
- void Advise(object pUnkSink, out int pdwCookie);
- void EnumConnections(out System.Runtime.InteropServices.ComTypes.IEnumConnections ppEnum);
- void GetConnectionInterface(out System.Guid pIID);
- void GetConnectionPointContainer(out System.Runtime.InteropServices.ComTypes.IConnectionPointContainer ppCPC);
- void Unadvise(int dwCookie);
- }
- [System.Runtime.InteropServices.GuidAttribute("B196B284-BAB4-101A-B69C-00AA00341D07")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface IConnectionPointContainer
- {
- void EnumConnectionPoints(out System.Runtime.InteropServices.ComTypes.IEnumConnectionPoints ppEnum);
- void FindConnectionPoint(ref System.Guid riid, out System.Runtime.InteropServices.ComTypes.IConnectionPoint ppCP);
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct IDLDESC
- {
- public System.IntPtr dwReserved;
- public System.Runtime.InteropServices.ComTypes.IDLFLAG wIDLFlags;
- }
- [System.FlagsAttribute]
- public enum IDLFLAG : short
- {
- IDLFLAG_FIN = (short)1,
- IDLFLAG_FLCID = (short)4,
- IDLFLAG_FOUT = (short)2,
- IDLFLAG_FRETVAL = (short)8,
- IDLFLAG_NONE = (short)0,
- }
- [System.Runtime.InteropServices.GuidAttribute("B196B285-BAB4-101A-B69C-00AA00341D07")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface IEnumConnectionPoints
- {
- void Clone(out System.Runtime.InteropServices.ComTypes.IEnumConnectionPoints ppenum);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int Next(int celt, System.Runtime.InteropServices.ComTypes.IConnectionPoint[] rgelt, System.IntPtr pceltFetched);
- void Reset();
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int Skip(int celt);
- }
- [System.Runtime.InteropServices.GuidAttribute("B196B287-BAB4-101A-B69C-00AA00341D07")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface IEnumConnections
- {
- void Clone(out System.Runtime.InteropServices.ComTypes.IEnumConnections ppenum);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int Next(int celt, System.Runtime.InteropServices.ComTypes.CONNECTDATA[] rgelt, System.IntPtr pceltFetched);
- void Reset();
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int Skip(int celt);
- }
- [System.Runtime.InteropServices.GuidAttribute("00000102-0000-0000-C000-000000000046")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface IEnumMoniker
- {
- void Clone(out System.Runtime.InteropServices.ComTypes.IEnumMoniker ppenum);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int Next(int celt, System.Runtime.InteropServices.ComTypes.IMoniker[] rgelt, System.IntPtr pceltFetched);
- void Reset();
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int Skip(int celt);
- }
- [System.Runtime.InteropServices.GuidAttribute("00000101-0000-0000-C000-000000000046")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface IEnumString
- {
- void Clone(out System.Runtime.InteropServices.ComTypes.IEnumString ppenum);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int Next(int celt, string[] rgelt, System.IntPtr pceltFetched);
- void Reset();
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int Skip(int celt);
- }
- [System.Runtime.InteropServices.GuidAttribute("00020404-0000-0000-C000-000000000046")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface IEnumVARIANT
- {
- System.Runtime.InteropServices.ComTypes.IEnumVARIANT Clone();
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int Next(int celt, object[] rgVar, System.IntPtr pceltFetched);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int Reset();
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int Skip(int celt);
- }
- [System.Runtime.InteropServices.GuidAttribute("0000000f-0000-0000-C000-000000000046")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface IMoniker
- {
- void BindToObject(System.Runtime.InteropServices.ComTypes.IBindCtx pbc, System.Runtime.InteropServices.ComTypes.IMoniker pmkToLeft, ref System.Guid riidResult, out object ppvResult);
- void BindToStorage(System.Runtime.InteropServices.ComTypes.IBindCtx pbc, System.Runtime.InteropServices.ComTypes.IMoniker pmkToLeft, ref System.Guid riid, out object ppvObj);
- void CommonPrefixWith(System.Runtime.InteropServices.ComTypes.IMoniker pmkOther, out System.Runtime.InteropServices.ComTypes.IMoniker ppmkPrefix);
- void ComposeWith(System.Runtime.InteropServices.ComTypes.IMoniker pmkRight, bool fOnlyIfNotGeneric, out System.Runtime.InteropServices.ComTypes.IMoniker ppmkComposite);
- void Enum(bool fForward, out System.Runtime.InteropServices.ComTypes.IEnumMoniker ppenumMoniker);
- void GetClassID(out System.Guid pClassID);
- void GetDisplayName(System.Runtime.InteropServices.ComTypes.IBindCtx pbc, System.Runtime.InteropServices.ComTypes.IMoniker pmkToLeft, out string ppszDisplayName);
- void GetSizeMax(out long pcbSize);
- void GetTimeOfLastChange(System.Runtime.InteropServices.ComTypes.IBindCtx pbc, System.Runtime.InteropServices.ComTypes.IMoniker pmkToLeft, out System.Runtime.InteropServices.ComTypes.FILETIME pFileTime);
- void Hash(out int pdwHash);
- void Inverse(out System.Runtime.InteropServices.ComTypes.IMoniker ppmk);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int IsDirty();
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int IsEqual(System.Runtime.InteropServices.ComTypes.IMoniker pmkOtherMoniker);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int IsRunning(System.Runtime.InteropServices.ComTypes.IBindCtx pbc, System.Runtime.InteropServices.ComTypes.IMoniker pmkToLeft, System.Runtime.InteropServices.ComTypes.IMoniker pmkNewlyRunning);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int IsSystemMoniker(out int pdwMksys);
- void Load(System.Runtime.InteropServices.ComTypes.IStream pStm);
- void ParseDisplayName(System.Runtime.InteropServices.ComTypes.IBindCtx pbc, System.Runtime.InteropServices.ComTypes.IMoniker pmkToLeft, string pszDisplayName, out int pchEaten, out System.Runtime.InteropServices.ComTypes.IMoniker ppmkOut);
- void Reduce(System.Runtime.InteropServices.ComTypes.IBindCtx pbc, int dwReduceHowFar, ref System.Runtime.InteropServices.ComTypes.IMoniker ppmkToLeft, out System.Runtime.InteropServices.ComTypes.IMoniker ppmkReduced);
- void RelativePathTo(System.Runtime.InteropServices.ComTypes.IMoniker pmkOther, out System.Runtime.InteropServices.ComTypes.IMoniker ppmkRelPath);
- void Save(System.Runtime.InteropServices.ComTypes.IStream pStm, bool fClearDirty);
- }
- [System.FlagsAttribute]
- public enum IMPLTYPEFLAGS
- {
- IMPLTYPEFLAG_FDEFAULT = 1,
- IMPLTYPEFLAG_FDEFAULTVTABLE = 8,
- IMPLTYPEFLAG_FRESTRICTED = 4,
- IMPLTYPEFLAG_FSOURCE = 2,
- }
- [System.FlagsAttribute]
- public enum INVOKEKIND
- {
- INVOKE_FUNC = 1,
- INVOKE_PROPERTYGET = 2,
- INVOKE_PROPERTYPUT = 4,
- INVOKE_PROPERTYPUTREF = 8,
- }
- [System.Runtime.InteropServices.GuidAttribute("0000010b-0000-0000-C000-000000000046")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface IPersistFile
- {
- void GetClassID(out System.Guid pClassID);
- void GetCurFile(out string ppszFileName);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int IsDirty();
- void Load(string pszFileName, int dwMode);
- void Save(string pszFileName, bool fRemember);
- void SaveCompleted(string pszFileName);
- }
- [System.Runtime.InteropServices.GuidAttribute("00000010-0000-0000-C000-000000000046")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface IRunningObjectTable
- {
- void EnumRunning(out System.Runtime.InteropServices.ComTypes.IEnumMoniker ppenumMoniker);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int GetObject(System.Runtime.InteropServices.ComTypes.IMoniker pmkObjectName, out object ppunkObject);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int GetTimeOfLastChange(System.Runtime.InteropServices.ComTypes.IMoniker pmkObjectName, out System.Runtime.InteropServices.ComTypes.FILETIME pfiletime);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int IsRunning(System.Runtime.InteropServices.ComTypes.IMoniker pmkObjectName);
- void NoteChangeTime(int dwRegister, ref System.Runtime.InteropServices.ComTypes.FILETIME pfiletime);
- int Register(int grfFlags, object punkObject, System.Runtime.InteropServices.ComTypes.IMoniker pmkObjectName);
- void Revoke(int dwRegister);
- }
- [System.Runtime.InteropServices.GuidAttribute("0000000c-0000-0000-C000-000000000046")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface IStream
- {
- void Clone(out System.Runtime.InteropServices.ComTypes.IStream ppstm);
- void Commit(int grfCommitFlags);
- void CopyTo(System.Runtime.InteropServices.ComTypes.IStream pstm, long cb, System.IntPtr pcbRead, System.IntPtr pcbWritten);
- void LockRegion(long libOffset, long cb, int dwLockType);
- void Read(byte[] pv, int cb, System.IntPtr pcbRead);
- void Revert();
- void Seek(long dlibMove, int dwOrigin, System.IntPtr plibNewPosition);
- void SetSize(long libNewSize);
- void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag);
- void UnlockRegion(long libOffset, long cb, int dwLockType);
- void Write(byte[] pv, int cb, System.IntPtr pcbWritten);
- }
- [System.Runtime.InteropServices.GuidAttribute("00020403-0000-0000-C000-000000000046")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface ITypeComp
- {
- void Bind(string szName, int lHashVal, short wFlags, out System.Runtime.InteropServices.ComTypes.ITypeInfo ppTInfo, out System.Runtime.InteropServices.ComTypes.DESCKIND pDescKind, out System.Runtime.InteropServices.ComTypes.BINDPTR pBindPtr);
- void BindType(string szName, int lHashVal, out System.Runtime.InteropServices.ComTypes.ITypeInfo ppTInfo, out System.Runtime.InteropServices.ComTypes.ITypeComp ppTComp);
- }
- [System.Runtime.InteropServices.GuidAttribute("00020401-0000-0000-C000-000000000046")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface ITypeInfo
- {
- void AddressOfMember(int memid, System.Runtime.InteropServices.ComTypes.INVOKEKIND invKind, out System.IntPtr ppv);
- void CreateInstance(object pUnkOuter, ref System.Guid riid, out object ppvObj);
- void GetContainingTypeLib(out System.Runtime.InteropServices.ComTypes.ITypeLib ppTLB, out int pIndex);
- void GetDllEntry(int memid, System.Runtime.InteropServices.ComTypes.INVOKEKIND invKind, System.IntPtr pBstrDllName, System.IntPtr pBstrName, System.IntPtr pwOrdinal);
- void GetDocumentation(int index, out string strName, out string strDocString, out int dwHelpContext, out string strHelpFile);
- void GetFuncDesc(int index, out System.IntPtr ppFuncDesc);
- void GetIDsOfNames(string[] rgszNames, int cNames, int[] pMemId);
- void GetImplTypeFlags(int index, out System.Runtime.InteropServices.ComTypes.IMPLTYPEFLAGS pImplTypeFlags);
- void GetMops(int memid, out string pBstrMops);
- void GetNames(int memid, string[] rgBstrNames, int cMaxNames, out int pcNames);
- void GetRefTypeInfo(int hRef, out System.Runtime.InteropServices.ComTypes.ITypeInfo ppTI);
- void GetRefTypeOfImplType(int index, out int href);
- void GetTypeAttr(out System.IntPtr ppTypeAttr);
- void GetTypeComp(out System.Runtime.InteropServices.ComTypes.ITypeComp ppTComp);
- void GetVarDesc(int index, out System.IntPtr ppVarDesc);
- void Invoke(object pvInstance, int memid, short wFlags, ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, System.IntPtr pVarResult, System.IntPtr pExcepInfo, out int puArgErr);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]void ReleaseFuncDesc(System.IntPtr pFuncDesc);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]void ReleaseTypeAttr(System.IntPtr pTypeAttr);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]void ReleaseVarDesc(System.IntPtr pVarDesc);
- }
- [System.Runtime.InteropServices.GuidAttribute("00020412-0000-0000-C000-000000000046")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface ITypeInfo2 : System.Runtime.InteropServices.ComTypes.ITypeInfo
- {
- new void AddressOfMember(int memid, System.Runtime.InteropServices.ComTypes.INVOKEKIND invKind, out System.IntPtr ppv);
- new void CreateInstance(object pUnkOuter, ref System.Guid riid, out object ppvObj);
- void GetAllCustData(System.IntPtr pCustData);
- void GetAllFuncCustData(int index, System.IntPtr pCustData);
- void GetAllImplTypeCustData(int index, System.IntPtr pCustData);
- void GetAllParamCustData(int indexFunc, int indexParam, System.IntPtr pCustData);
- void GetAllVarCustData(int index, System.IntPtr pCustData);
- new void GetContainingTypeLib(out System.Runtime.InteropServices.ComTypes.ITypeLib ppTLB, out int pIndex);
- void GetCustData(ref System.Guid guid, out object pVarVal);
- new void GetDllEntry(int memid, System.Runtime.InteropServices.ComTypes.INVOKEKIND invKind, System.IntPtr pBstrDllName, System.IntPtr pBstrName, System.IntPtr pwOrdinal);
- new void GetDocumentation(int index, out string strName, out string strDocString, out int dwHelpContext, out string strHelpFile);
- void GetDocumentation2(int memid, out string pbstrHelpString, out int pdwHelpStringContext, out string pbstrHelpStringDll);
- void GetFuncCustData(int index, ref System.Guid guid, out object pVarVal);
- new void GetFuncDesc(int index, out System.IntPtr ppFuncDesc);
- void GetFuncIndexOfMemId(int memid, System.Runtime.InteropServices.ComTypes.INVOKEKIND invKind, out int pFuncIndex);
- new void GetIDsOfNames(string[] rgszNames, int cNames, int[] pMemId);
- void GetImplTypeCustData(int index, ref System.Guid guid, out object pVarVal);
- new void GetImplTypeFlags(int index, out System.Runtime.InteropServices.ComTypes.IMPLTYPEFLAGS pImplTypeFlags);
- new void GetMops(int memid, out string pBstrMops);
- new void GetNames(int memid, string[] rgBstrNames, int cMaxNames, out int pcNames);
- void GetParamCustData(int indexFunc, int indexParam, ref System.Guid guid, out object pVarVal);
- new void GetRefTypeInfo(int hRef, out System.Runtime.InteropServices.ComTypes.ITypeInfo ppTI);
- new void GetRefTypeOfImplType(int index, out int href);
- new void GetTypeAttr(out System.IntPtr ppTypeAttr);
- new void GetTypeComp(out System.Runtime.InteropServices.ComTypes.ITypeComp ppTComp);
- void GetTypeFlags(out int pTypeFlags);
- void GetTypeKind(out System.Runtime.InteropServices.ComTypes.TYPEKIND pTypeKind);
- void GetVarCustData(int index, ref System.Guid guid, out object pVarVal);
- new void GetVarDesc(int index, out System.IntPtr ppVarDesc);
- void GetVarIndexOfMemId(int memid, out int pVarIndex);
- new void Invoke(object pvInstance, int memid, short wFlags, ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, System.IntPtr pVarResult, System.IntPtr pExcepInfo, out int puArgErr);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]new void ReleaseFuncDesc(System.IntPtr pFuncDesc);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]new void ReleaseTypeAttr(System.IntPtr pTypeAttr);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]new void ReleaseVarDesc(System.IntPtr pVarDesc);
- }
- [System.Runtime.InteropServices.GuidAttribute("00020402-0000-0000-C000-000000000046")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface ITypeLib
- {
- void FindName(string szNameBuf, int lHashVal, System.Runtime.InteropServices.ComTypes.ITypeInfo[] ppTInfo, int[] rgMemId, ref short pcFound);
- void GetDocumentation(int index, out string strName, out string strDocString, out int dwHelpContext, out string strHelpFile);
- void GetLibAttr(out System.IntPtr ppTLibAttr);
- void GetTypeComp(out System.Runtime.InteropServices.ComTypes.ITypeComp ppTComp);
- void GetTypeInfo(int index, out System.Runtime.InteropServices.ComTypes.ITypeInfo ppTI);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]int GetTypeInfoCount();
- void GetTypeInfoOfGuid(ref System.Guid guid, out System.Runtime.InteropServices.ComTypes.ITypeInfo ppTInfo);
- void GetTypeInfoType(int index, out System.Runtime.InteropServices.ComTypes.TYPEKIND pTKind);
- bool IsName(string szNameBuf, int lHashVal);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]void ReleaseTLibAttr(System.IntPtr pTLibAttr);
- }
- [System.Runtime.InteropServices.GuidAttribute("00020411-0000-0000-C000-000000000046")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- public partial interface ITypeLib2 : System.Runtime.InteropServices.ComTypes.ITypeLib
- {
- new void FindName(string szNameBuf, int lHashVal, System.Runtime.InteropServices.ComTypes.ITypeInfo[] ppTInfo, int[] rgMemId, ref short pcFound);
- void GetAllCustData(System.IntPtr pCustData);
- void GetCustData(ref System.Guid guid, out object pVarVal);
- new void GetDocumentation(int index, out string strName, out string strDocString, out int dwHelpContext, out string strHelpFile);
- void GetDocumentation2(int index, out string pbstrHelpString, out int pdwHelpStringContext, out string pbstrHelpStringDll);
- new void GetLibAttr(out System.IntPtr ppTLibAttr);
- void GetLibStatistics(System.IntPtr pcUniqueNames, out int pcchUniqueNames);
- new void GetTypeComp(out System.Runtime.InteropServices.ComTypes.ITypeComp ppTComp);
- new void GetTypeInfo(int index, out System.Runtime.InteropServices.ComTypes.ITypeInfo ppTI);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]new int GetTypeInfoCount();
- new void GetTypeInfoOfGuid(ref System.Guid guid, out System.Runtime.InteropServices.ComTypes.ITypeInfo ppTInfo);
- new void GetTypeInfoType(int index, out System.Runtime.InteropServices.ComTypes.TYPEKIND pTKind);
- new bool IsName(string szNameBuf, int lHashVal);
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]new void ReleaseTLibAttr(System.IntPtr pTLibAttr);
- }
- [System.FlagsAttribute]
- public enum LIBFLAGS : short
- {
- LIBFLAG_FCONTROL = (short)2,
- LIBFLAG_FHASDISKIMAGE = (short)8,
- LIBFLAG_FHIDDEN = (short)4,
- LIBFLAG_FRESTRICTED = (short)1,
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct PARAMDESC
- {
- public System.IntPtr lpVarValue;
- public System.Runtime.InteropServices.ComTypes.PARAMFLAG wParamFlags;
- }
- [System.FlagsAttribute]
- public enum PARAMFLAG : short
- {
- PARAMFLAG_FHASCUSTDATA = (short)64,
- PARAMFLAG_FHASDEFAULT = (short)32,
- PARAMFLAG_FIN = (short)1,
- PARAMFLAG_FLCID = (short)4,
- PARAMFLAG_FOPT = (short)16,
- PARAMFLAG_FOUT = (short)2,
- PARAMFLAG_FRETVAL = (short)8,
- PARAMFLAG_NONE = (short)0,
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct STATSTG
- {
- public System.Runtime.InteropServices.ComTypes.FILETIME atime;
- public long cbSize;
- public System.Guid clsid;
- public System.Runtime.InteropServices.ComTypes.FILETIME ctime;
- public int grfLocksSupported;
- public int grfMode;
- public int grfStateBits;
- public System.Runtime.InteropServices.ComTypes.FILETIME mtime;
- public string pwcsName;
- public int reserved;
- public int type;
- }
- public enum SYSKIND
- {
- SYS_MAC = 2,
- SYS_WIN16 = 0,
- SYS_WIN32 = 1,
- SYS_WIN64 = 3,
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct TYPEATTR
- {
- public short cbAlignment;
- public int cbSizeInstance;
- public short cbSizeVft;
- public short cFuncs;
- public short cImplTypes;
- public short cVars;
- public int dwReserved;
- public System.Guid guid;
- public System.Runtime.InteropServices.ComTypes.IDLDESC idldescType;
- public int lcid;
- public System.IntPtr lpstrSchema;
- public const int MEMBER_ID_NIL = -1;
- public int memidConstructor;
- public int memidDestructor;
- public System.Runtime.InteropServices.ComTypes.TYPEDESC tdescAlias;
- public System.Runtime.InteropServices.ComTypes.TYPEKIND typekind;
- public short wMajorVerNum;
- public short wMinorVerNum;
- public System.Runtime.InteropServices.ComTypes.TYPEFLAGS wTypeFlags;
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct TYPEDESC
- {
- public System.IntPtr lpValue;
- public short vt;
- }
- [System.FlagsAttribute]
- public enum TYPEFLAGS : short
- {
- TYPEFLAG_FAGGREGATABLE = (short)1024,
- TYPEFLAG_FAPPOBJECT = (short)1,
- TYPEFLAG_FCANCREATE = (short)2,
- TYPEFLAG_FCONTROL = (short)32,
- TYPEFLAG_FDISPATCHABLE = (short)4096,
- TYPEFLAG_FDUAL = (short)64,
- TYPEFLAG_FHIDDEN = (short)16,
- TYPEFLAG_FLICENSED = (short)4,
- TYPEFLAG_FNONEXTENSIBLE = (short)128,
- TYPEFLAG_FOLEAUTOMATION = (short)256,
- TYPEFLAG_FPREDECLID = (short)8,
- TYPEFLAG_FPROXY = (short)16384,
- TYPEFLAG_FREPLACEABLE = (short)2048,
- TYPEFLAG_FRESTRICTED = (short)512,
- TYPEFLAG_FREVERSEBIND = (short)8192,
- }
- public enum TYPEKIND
- {
- TKIND_ALIAS = 6,
- TKIND_COCLASS = 5,
- TKIND_DISPATCH = 4,
- TKIND_ENUM = 0,
- TKIND_INTERFACE = 3,
- TKIND_MAX = 8,
- TKIND_MODULE = 2,
- TKIND_RECORD = 1,
- TKIND_UNION = 7,
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct TYPELIBATTR
- {
- public System.Guid guid;
- public int lcid;
- public System.Runtime.InteropServices.ComTypes.SYSKIND syskind;
- public System.Runtime.InteropServices.ComTypes.LIBFLAGS wLibFlags;
- public short wMajorVerNum;
- public short wMinorVerNum;
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct VARDESC
- {
- public System.Runtime.InteropServices.ComTypes.VARDESC.DESCUNION desc;
- public System.Runtime.InteropServices.ComTypes.ELEMDESC elemdescVar;
- public string lpstrSchema;
- public int memid;
- public System.Runtime.InteropServices.ComTypes.VARKIND varkind;
- public short wVarFlags;
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Explicit)]
- public partial struct DESCUNION
- {
- [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
- public System.IntPtr lpvarValue;
- [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
- public int oInst;
- }
- }
- [System.FlagsAttribute]
- public enum VARFLAGS : short
- {
- VARFLAG_FBINDABLE = (short)4,
- VARFLAG_FDEFAULTBIND = (short)32,
- VARFLAG_FDEFAULTCOLLELEM = (short)256,
- VARFLAG_FDISPLAYBIND = (short)16,
- VARFLAG_FHIDDEN = (short)64,
- VARFLAG_FIMMEDIATEBIND = (short)4096,
- VARFLAG_FNONBROWSABLE = (short)1024,
- VARFLAG_FREADONLY = (short)1,
- VARFLAG_FREPLACEABLE = (short)2048,
- VARFLAG_FREQUESTEDIT = (short)8,
- VARFLAG_FRESTRICTED = (short)128,
- VARFLAG_FSOURCE = (short)2,
- VARFLAG_FUIDEFAULT = (short)512,
- }
- public enum VARKIND
- {
- VAR_CONST = 2,
- VAR_DISPATCH = 3,
- VAR_PERINSTANCE = 0,
- VAR_STATIC = 1,
- }
-}
-namespace System.Runtime.Loader
-{
- [System.Security.SecuritySafeCriticalAttribute]
- public abstract partial class AssemblyLoadContext
- {
- protected AssemblyLoadContext() { }
- public static System.Runtime.Loader.AssemblyLoadContext Default { get { throw null; } }
- public event System.Func<System.Runtime.Loader.AssemblyLoadContext, System.Reflection.AssemblyName, System.Reflection.Assembly> Resolving { add { } remove { } }
- public event System.Action<System.Runtime.Loader.AssemblyLoadContext> Unloading { add { } remove { } }
- public static event AssemblyLoadEventHandler AssemblyLoad { add { } remove { } }
- public static event ResolveEventHandler AssemblyResolve { add { } remove { } }
- public static event ResolveEventHandler TypeResolve { add { } remove { } }
- public static event ResolveEventHandler ResourceResolve { add { } remove { } }
- public static System.Reflection.AssemblyName GetAssemblyName(string assemblyPath) { throw null; }
- public static System.Runtime.Loader.AssemblyLoadContext GetLoadContext(System.Reflection.Assembly assembly) { throw null; }
- public static System.Reflection.Assembly[] GetLoadedAssemblies() { throw null; }
- protected abstract System.Reflection.Assembly Load(System.Reflection.AssemblyName assemblyName);
- public System.Reflection.Assembly LoadFromAssemblyName(System.Reflection.AssemblyName assemblyName) { throw null; }
- public System.Reflection.Assembly LoadFromAssemblyPath(string assemblyPath) { throw null; }
- public System.Reflection.Assembly LoadFromNativeImagePath(string nativeImagePath, string assemblyPath) { throw null; }
- public System.Reflection.Assembly LoadFromStream(System.IO.Stream assembly) { throw null; }
- public System.Reflection.Assembly LoadFromStream(System.IO.Stream assembly, System.IO.Stream assemblySymbols) { throw null; }
- protected virtual System.IntPtr LoadUnmanagedDll(string unmanagedDllName) { throw null; }
- protected System.IntPtr LoadUnmanagedDllFromPath(string unmanagedDllPath) { throw null; }
- public void SetProfileOptimizationRoot(string directoryPath) { }
- public void StartProfileOptimization(string profile) { }
- }
-}
-namespace System.Runtime.Remoting
-{
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(2))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ObjectHandle
- {
- internal ObjectHandle() { }
- }
-}
-namespace System.Runtime.Serialization
-{
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static partial class FormatterServices
- {
- [System.Security.SecurityCriticalAttribute]
- public static object GetUninitializedObject(System.Type type) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IDeserializationCallback
- {
- void OnDeserialization(object sender);
- }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IFormatterConverter
- {
- object Convert(object value, System.Type type);
- object Convert(object value, System.TypeCode typeCode);
- bool ToBoolean(object value);
- byte ToByte(object value);
- char ToChar(object value);
- System.DateTime ToDateTime(object value);
- decimal ToDecimal(object value);
- double ToDouble(object value);
- short ToInt16(object value);
- int ToInt32(object value);
- long ToInt64(object value);
- sbyte ToSByte(object value);
- float ToSingle(object value);
- string ToString(object value);
- ushort ToUInt16(object value);
- uint ToUInt32(object value);
- ulong ToUInt64(object value);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IObjectReference
- {
- [System.Security.SecurityCriticalAttribute]
- object GetRealObject(System.Runtime.Serialization.StreamingContext context);
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface ISerializable
- {
- [System.Security.SecurityCriticalAttribute]
- void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context);
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class OnDeserializedAttribute : System.Attribute
- {
- public OnDeserializedAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class OnDeserializingAttribute : System.Attribute
- {
- public OnDeserializingAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class OnSerializedAttribute : System.Attribute
- {
- public OnSerializedAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(64), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class OnSerializingAttribute : System.Attribute
- {
- public OnSerializingAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(256), Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class OptionalFieldAttribute : System.Attribute
- {
- public OptionalFieldAttribute() { }
- public int VersionAdded { get { throw null; } set { } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct SerializationEntry
- {
- public string Name { get { throw null; } }
- public System.Type ObjectType { get { throw null; } }
- public object Value { get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class SerializationException : System.SystemException
- {
- public SerializationException() { }
- public SerializationException(string message) { }
- public SerializationException(string message, System.Exception innerException) { }
- protected SerializationException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class SerializationInfo
- {
- [System.CLSCompliantAttribute(false)]
- public SerializationInfo(System.Type type, System.Runtime.Serialization.IFormatterConverter converter) { }
- [System.CLSCompliantAttribute(false)]
- public SerializationInfo(System.Type type, System.Runtime.Serialization.IFormatterConverter converter, bool requireSameTokenInPartialTrust) { }
- public string AssemblyName { get { throw null; } [System.Security.SecuritySafeCriticalAttribute]set { } }
- public string FullTypeName { get { throw null; } set { } }
- public bool IsAssemblyNameSetExplicit { get { throw null; } }
- public bool IsFullTypeNameSetExplicit { get { throw null; } }
- public int MemberCount { get { throw null; } }
- public System.Type ObjectType { get { throw null; } }
- public void AddValue(string name, bool value) { }
- public void AddValue(string name, byte value) { }
- public void AddValue(string name, char value) { }
- public void AddValue(string name, System.DateTime value) { }
- public void AddValue(string name, decimal value) { }
- public void AddValue(string name, double value) { }
- public void AddValue(string name, short value) { }
- public void AddValue(string name, int value) { }
- public void AddValue(string name, long value) { }
- public void AddValue(string name, object value) { }
- public void AddValue(string name, object value, System.Type type) { }
- [System.CLSCompliantAttribute(false)]
- public void AddValue(string name, sbyte value) { }
- public void AddValue(string name, float value) { }
- [System.CLSCompliantAttribute(false)]
- public void AddValue(string name, ushort value) { }
- [System.CLSCompliantAttribute(false)]
- public void AddValue(string name, uint value) { }
- [System.CLSCompliantAttribute(false)]
- public void AddValue(string name, ulong value) { }
- public bool GetBoolean(string name) { throw null; }
- public byte GetByte(string name) { throw null; }
- public char GetChar(string name) { throw null; }
- public System.DateTime GetDateTime(string name) { throw null; }
- public decimal GetDecimal(string name) { throw null; }
- public double GetDouble(string name) { throw null; }
- public System.Runtime.Serialization.SerializationInfoEnumerator GetEnumerator() { throw null; }
- public short GetInt16(string name) { throw null; }
- public int GetInt32(string name) { throw null; }
- public long GetInt64(string name) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public sbyte GetSByte(string name) { throw null; }
- public float GetSingle(string name) { throw null; }
- public string GetString(string name) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public ushort GetUInt16(string name) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public uint GetUInt32(string name) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public ulong GetUInt64(string name) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public object GetValue(string name, System.Type type) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public void SetType(System.Type type) { }
- public void UpdateValue(string name, object value, System.Type type) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class SerializationInfoEnumerator : System.Collections.IEnumerator
- {
- internal SerializationInfoEnumerator() { }
- public System.Runtime.Serialization.SerializationEntry Current { get { throw null; } }
- public string Name { get { throw null; } }
- public System.Type ObjectType { get { throw null; } }
- object System.Collections.IEnumerator.Current { get { throw null; } }
- public object Value { get { throw null; } }
- public bool MoveNext() { throw null; }
- public void Reset() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct StreamingContext
- {
- public StreamingContext(System.Runtime.Serialization.StreamingContextStates state) { throw null;}
- public StreamingContext(System.Runtime.Serialization.StreamingContextStates state, object additional) { throw null;}
- public object Context { get { throw null; } }
- public System.Runtime.Serialization.StreamingContextStates State { get { throw null; } }
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum StreamingContextStates
- {
- All = 255,
- Clone = 64,
- CrossAppDomain = 128,
- CrossMachine = 2,
- CrossProcess = 1,
- File = 4,
- Other = 32,
- Persistence = 8,
- Remoting = 16,
- }
- public sealed partial class SafeSerializationEventArgs : System.EventArgs
- {
- internal SafeSerializationEventArgs() { }
- public System.Runtime.Serialization.StreamingContext StreamingContext { get { throw null; } }
- public void AddSerializedState(System.Runtime.Serialization.ISafeSerializationData serializedState) { }
- }
- public partial interface ISafeSerializationData
- {
- void CompleteDeserialization(object deserialized);
- }
-}
-namespace System.Runtime.Versioning
-{
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=false, Inherited=false)]
- public sealed partial class TargetFrameworkAttribute : System.Attribute
- {
- public TargetFrameworkAttribute(string frameworkName) { }
- public string FrameworkDisplayName { get { throw null; } set { } }
- public string FrameworkName { get { throw null; } }
- }
-}
-namespace System.Security
-{
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=false, Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AllowPartiallyTrustedCallersAttribute : System.Attribute
- {
- public AllowPartiallyTrustedCallersAttribute() { }
- public System.Security.PartialTrustVisibilityLevel PartialTrustVisibilityLevel { get { throw null; } set { } }
- }
- public enum PartialTrustVisibilityLevel
- {
- NotVisibleByDefault = 1,
- VisibleToAllHosts = 0,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(5501), AllowMultiple=false, Inherited=false)]
- public sealed partial class SecurityCriticalAttribute : System.Attribute
- {
- public SecurityCriticalAttribute() { }
-#pragma warning disable 0618
- public SecurityCriticalAttribute(System.Security.SecurityCriticalScope scope) { }
-#pragma warning restore 0618
- [System.ObsoleteAttribute("SecurityCriticalScope is only used for .NET 2.0 transparency compatibility.")]
- public System.Security.SecurityCriticalScope Scope { get { throw null; } }
- }
- [System.ObsoleteAttribute("SecurityCriticalScope is only used for .NET 2.0 transparency compatibility.")]
- public enum SecurityCriticalScope
- {
- Everything = 1,
- Explicit = 0,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class SecurityException : System.SystemException
- {
- public SecurityException() { }
- protected SecurityException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public SecurityException(string message) { }
- public SecurityException(string message, System.Exception inner) { }
- public SecurityException(string message, System.Type type) { }
- public SecurityException(string message, System.Type type, string state) { }
- public object Demanded { get { throw null; } set { } }
- public object DenySetInstance { get { throw null; } set { } }
- public System.Reflection.AssemblyName FailedAssemblyInfo { get { throw null; } set { } }
- public string GrantedSet { get { throw null; } set { } }
- public System.Reflection.MethodInfo Method { get { throw null; } set { } }
- public string PermissionState { get { throw null; } set { } }
- public System.Type PermissionType { get { throw null; } set { } }
- public object PermitOnlySetInstance { get { throw null; } set { } }
- public string RefusedSet { get { throw null; } set { } }
- public string Url { get { throw null; } set { } }
- public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- public override string ToString() { throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=false)]
- public sealed partial class SecurityRulesAttribute : System.Attribute
- {
- public SecurityRulesAttribute(System.Security.SecurityRuleSet ruleSet) { }
- public System.Security.SecurityRuleSet RuleSet { get { throw null; } }
- public bool SkipVerificationInFullTrust { get { throw null; } set { } }
- }
- public enum SecurityRuleSet : byte
- {
- Level1 = (byte)1,
- Level2 = (byte)2,
- None = (byte)0,
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(5500), AllowMultiple=false, Inherited=false)]
- public sealed partial class SecuritySafeCriticalAttribute : System.Attribute
- {
- public SecuritySafeCriticalAttribute() { }
- }
- [System.Security.SecurityCriticalAttribute]
- public abstract partial class SecurityState
- {
- protected SecurityState() { }
- public abstract void EnsureState();
- [System.Security.SecurityCriticalAttribute]
- public bool IsStateAvailable() { throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=false, Inherited=false)]
- public sealed partial class SecurityTransparentAttribute : System.Attribute
- {
- public SecurityTransparentAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(5501), AllowMultiple=false, Inherited=false)]
- [System.ObsoleteAttribute("SecurityTreatAsSafe is only used for .NET 2.0 transparency compatibility. Please use the SecuritySafeCriticalAttribute instead.")]
- public sealed partial class SecurityTreatAsSafeAttribute : System.Attribute
- {
- public SecurityTreatAsSafeAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(5188), AllowMultiple=true, Inherited=false)]
- public sealed partial class SuppressUnmanagedCodeSecurityAttribute : System.Attribute
- {
- public SuppressUnmanagedCodeSecurityAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(2), AllowMultiple=true, Inherited=false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class UnverifiableCodeAttribute : System.Attribute
- {
- public UnverifiableCodeAttribute() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class VerificationException : System.SystemException
- {
- public VerificationException() { }
- public VerificationException(string message) { }
- public VerificationException(string message, System.Exception innerException) { }
- protected VerificationException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
-}
-namespace System.Security.Principal
-{
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IIdentity
- {
- string AuthenticationType { get; }
- bool IsAuthenticated { get; }
- string Name { get; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial interface IPrincipal
- {
- System.Security.Principal.IIdentity Identity { get; }
- bool IsInRole(string role);
- }
- public enum TokenImpersonationLevel
- {
- Anonymous = 1,
- Delegation = 4,
- Identification = 2,
- Impersonation = 3,
- None = 0,
- }
-}
-namespace System.Text
-{
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ASCIIEncoding : System.Text.Encoding
- {
- public ASCIIEncoding() { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override bool IsSingleByte { get { throw null; } }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetByteCount(char* chars, int count) { throw null; }
- public override int GetByteCount(char[] chars, int index, int count) { throw null; }
- public override int GetByteCount(string chars) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount) { throw null; }
- public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { throw null; }
- public override int GetBytes(string chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetCharCount(byte* bytes, int count) { throw null; }
- public override int GetCharCount(byte[] bytes, int index, int count) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount) { throw null; }
- public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Text.Decoder GetDecoder() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Text.Encoder GetEncoder() { throw null; }
- public override int GetMaxByteCount(int charCount) { throw null; }
- public override int GetMaxCharCount(int byteCount) { throw null; }
- public override string GetString(byte[] bytes, int byteIndex, int byteCount) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class Decoder
- {
- protected Decoder() { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Text.DecoderFallback Fallback { get { throw null; } set { } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Text.DecoderFallbackBuffer FallbackBuffer { get { throw null; } }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe virtual void Convert(byte* bytes, int byteCount, char* chars, int charCount, bool flush, out int bytesUsed, out int charsUsed, out bool completed) { bytesUsed = default(int); charsUsed = default(int); completed = default(bool); }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual void Convert(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, int charCount, bool flush, out int bytesUsed, out int charsUsed, out bool completed) { bytesUsed = default(int); charsUsed = default(int); completed = default(bool); }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe virtual int GetCharCount(byte* bytes, int count, bool flush) { throw null; }
- public abstract int GetCharCount(byte[] bytes, int index, int count);
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual int GetCharCount(byte[] bytes, int index, int count, bool flush) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe virtual int GetChars(byte* bytes, int byteCount, char* chars, int charCount, bool flush) { throw null; }
- public abstract int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex);
- public virtual int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, bool flush) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual void Reset() { }
- }
- public sealed partial class DecoderExceptionFallback : System.Text.DecoderFallback
- {
- public DecoderExceptionFallback() { }
- public override int MaxCharCount { get { throw null; } }
- public override System.Text.DecoderFallbackBuffer CreateFallbackBuffer() { throw null; }
- public override bool Equals(object value) { throw null; }
- public override int GetHashCode() { throw null; }
- }
- public sealed partial class DecoderExceptionFallbackBuffer : System.Text.DecoderFallbackBuffer
- {
- public DecoderExceptionFallbackBuffer() { }
- public override int Remaining { get { throw null; } }
- public override bool Fallback(byte[] bytesUnknown, int index) { throw null; }
- public override char GetNextChar() { throw null; }
- public override bool MovePrevious() { throw null; }
- }
- public abstract partial class DecoderFallback
- {
- protected DecoderFallback() { }
- public static System.Text.DecoderFallback ExceptionFallback { get { throw null; } }
- public abstract int MaxCharCount { get; }
- public static System.Text.DecoderFallback ReplacementFallback { get { throw null; } }
- public abstract System.Text.DecoderFallbackBuffer CreateFallbackBuffer();
- }
- public abstract partial class DecoderFallbackBuffer
- {
- protected DecoderFallbackBuffer() { }
- public abstract int Remaining { get; }
- public abstract bool Fallback(byte[] bytesUnknown, int index);
- public abstract char GetNextChar();
- public abstract bool MovePrevious();
- public virtual void Reset() { }
- }
- public sealed partial class DecoderFallbackException : System.ArgumentException
- {
- public DecoderFallbackException() { }
- public DecoderFallbackException(string message) { }
- public DecoderFallbackException(string message, byte[] bytesUnknown, int index) { }
- public DecoderFallbackException(string message, System.Exception innerException) { }
- public byte[] BytesUnknown { get { throw null; } }
- public int Index { get { throw null; } }
- }
- public sealed partial class DecoderReplacementFallback : System.Text.DecoderFallback
- {
- public DecoderReplacementFallback() { }
- public DecoderReplacementFallback(string replacement) { }
- public string DefaultString { get { throw null; } }
- public override int MaxCharCount { get { throw null; } }
- public override System.Text.DecoderFallbackBuffer CreateFallbackBuffer() { throw null; }
- public override bool Equals(object value) { throw null; }
- public override int GetHashCode() { throw null; }
- }
- public sealed partial class DecoderReplacementFallbackBuffer : System.Text.DecoderFallbackBuffer
- {
- public DecoderReplacementFallbackBuffer(System.Text.DecoderReplacementFallback fallback) { }
- public override int Remaining { get { throw null; } }
- public override bool Fallback(byte[] bytesUnknown, int index) { throw null; }
- public override char GetNextChar() { throw null; }
- public override bool MovePrevious() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override void Reset() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class Encoder
- {
- protected Encoder() { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Text.EncoderFallback Fallback { get { throw null; } set { } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Text.EncoderFallbackBuffer FallbackBuffer { get { throw null; } }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe virtual void Convert(char* chars, int charCount, byte* bytes, int byteCount, bool flush, out int charsUsed, out int bytesUsed, out bool completed) { charsUsed = default(int); bytesUsed = default(int); completed = default(bool); }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual void Convert(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex, int byteCount, bool flush, out int charsUsed, out int bytesUsed, out bool completed) { charsUsed = default(int); bytesUsed = default(int); completed = default(bool); }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe virtual int GetByteCount(char* chars, int count, bool flush) { throw null; }
- public abstract int GetByteCount(char[] chars, int index, int count, bool flush);
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe virtual int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, bool flush) { throw null; }
- public abstract int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex, bool flush);
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual void Reset() { }
- }
- public sealed partial class EncoderExceptionFallback : System.Text.EncoderFallback
- {
- public EncoderExceptionFallback() { }
- public override int MaxCharCount { get { throw null; } }
- public override System.Text.EncoderFallbackBuffer CreateFallbackBuffer() { throw null; }
- public override bool Equals(object value) { throw null; }
- public override int GetHashCode() { throw null; }
- }
- public sealed partial class EncoderExceptionFallbackBuffer : System.Text.EncoderFallbackBuffer
- {
- public EncoderExceptionFallbackBuffer() { }
- public override int Remaining { get { throw null; } }
- public override bool Fallback(char charUnknownHigh, char charUnknownLow, int index) { throw null; }
- public override bool Fallback(char charUnknown, int index) { throw null; }
- public override char GetNextChar() { throw null; }
- public override bool MovePrevious() { throw null; }
- }
- public abstract partial class EncoderFallback
- {
- protected EncoderFallback() { }
- public static System.Text.EncoderFallback ExceptionFallback { get { throw null; } }
- public abstract int MaxCharCount { get; }
- public static System.Text.EncoderFallback ReplacementFallback { get { throw null; } }
- public abstract System.Text.EncoderFallbackBuffer CreateFallbackBuffer();
- }
- public abstract partial class EncoderFallbackBuffer
- {
- protected EncoderFallbackBuffer() { }
- public abstract int Remaining { get; }
- public abstract bool Fallback(char charUnknownHigh, char charUnknownLow, int index);
- public abstract bool Fallback(char charUnknown, int index);
- public abstract char GetNextChar();
- public abstract bool MovePrevious();
- public virtual void Reset() { }
- }
- public sealed partial class EncoderFallbackException : System.ArgumentException
- {
- public EncoderFallbackException() { }
- public EncoderFallbackException(string message) { }
- public EncoderFallbackException(string message, System.Exception innerException) { }
- public char CharUnknown { get { throw null; } }
- public char CharUnknownHigh { get { throw null; } }
- public char CharUnknownLow { get { throw null; } }
- public int Index { get { throw null; } }
- public bool IsUnknownSurrogate() { throw null; }
- }
- public sealed partial class EncoderReplacementFallback : System.Text.EncoderFallback
- {
- public EncoderReplacementFallback() { }
- public EncoderReplacementFallback(string replacement) { }
- public string DefaultString { get { throw null; } }
- public override int MaxCharCount { get { throw null; } }
- public override System.Text.EncoderFallbackBuffer CreateFallbackBuffer() { throw null; }
- public override bool Equals(object value) { throw null; }
- public override int GetHashCode() { throw null; }
- }
- public sealed partial class EncoderReplacementFallbackBuffer : System.Text.EncoderFallbackBuffer
- {
- public EncoderReplacementFallbackBuffer(System.Text.EncoderReplacementFallback fallback) { }
- public override int Remaining { get { throw null; } }
- public override bool Fallback(char charUnknownHigh, char charUnknownLow, int index) { throw null; }
- public override bool Fallback(char charUnknown, int index) { throw null; }
- public override char GetNextChar() { throw null; }
- public override bool MovePrevious() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override void Reset() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class Encoding : System.ICloneable
- {
- protected Encoding() { }
- protected Encoding(int codePage) { }
- protected Encoding(int codePage, System.Text.EncoderFallback encoderFallback, System.Text.DecoderFallback decoderFallback) { }
- public static System.Text.Encoding ASCII { get { throw null; } }
- public static System.Text.Encoding BigEndianUnicode { get { throw null; } }
- public virtual string BodyName { get { throw null; } }
- public virtual int CodePage { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Text.DecoderFallback DecoderFallback { get { throw null; } set { } }
- public static System.Text.Encoding Default { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Text.EncoderFallback EncoderFallback { get { throw null; } set { } }
- public virtual string EncodingName { get { throw null; } }
- public virtual string HeaderName { get { throw null; } }
- public virtual bool IsBrowserDisplay { get { throw null; } }
- public virtual bool IsBrowserSave { get { throw null; } }
- public virtual bool IsMailNewsDisplay { get { throw null; } }
- public virtual bool IsMailNewsSave { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public bool IsReadOnly { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual bool IsSingleByte { get { throw null; } }
- public static System.Text.Encoding Unicode { get { throw null; } }
- public static System.Text.Encoding UTF32 { get { throw null; } }
- public static System.Text.Encoding UTF7 { get { throw null; } }
- public static System.Text.Encoding UTF8 { get { throw null; } }
- public virtual string WebName { get { throw null; } }
- public virtual int WindowsCodePage { get { throw null; } }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual object Clone() { throw null; }
- public static byte[] Convert(System.Text.Encoding srcEncoding, System.Text.Encoding dstEncoding, byte[] bytes) { throw null; }
- public static byte[] Convert(System.Text.Encoding srcEncoding, System.Text.Encoding dstEncoding, byte[] bytes, int index, int count) { throw null; }
- public override bool Equals(object value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe virtual int GetByteCount(char* chars, int count) { throw null; }
- public virtual int GetByteCount(char[] chars) { throw null; }
- public abstract int GetByteCount(char[] chars, int index, int count);
- public virtual int GetByteCount(string s) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe virtual int GetBytes(char* chars, int charCount, byte* bytes, int byteCount) { throw null; }
- public virtual byte[] GetBytes(char[] chars) { throw null; }
- public virtual byte[] GetBytes(char[] chars, int index, int count) { throw null; }
- public abstract int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex);
- public virtual byte[] GetBytes(string s) { throw null; }
- public virtual int GetBytes(string s, int charIndex, int charCount, byte[] bytes, int byteIndex) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe virtual int GetCharCount(byte* bytes, int count) { throw null; }
- public virtual int GetCharCount(byte[] bytes) { throw null; }
- public abstract int GetCharCount(byte[] bytes, int index, int count);
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe virtual int GetChars(byte* bytes, int byteCount, char* chars, int charCount) { throw null; }
- public virtual char[] GetChars(byte[] bytes) { throw null; }
- public virtual char[] GetChars(byte[] bytes, int index, int count) { throw null; }
- public abstract int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex);
- public virtual System.Text.Decoder GetDecoder() { throw null; }
- public virtual System.Text.Encoder GetEncoder() { throw null; }
- public static System.Text.Encoding GetEncoding(int codepage) { throw null; }
- public static System.Text.Encoding GetEncoding(int codepage, System.Text.EncoderFallback encoderFallback, System.Text.DecoderFallback decoderFallback) { throw null; }
- public static System.Text.Encoding GetEncoding(string name) { throw null; }
- public static System.Text.Encoding GetEncoding(string name, System.Text.EncoderFallback encoderFallback, System.Text.DecoderFallback decoderFallback) { throw null; }
- public static System.Text.EncodingInfo[] GetEncodings() { throw null; }
- public override int GetHashCode() { throw null; }
- public abstract int GetMaxByteCount(int charCount);
- public abstract int GetMaxCharCount(int byteCount);
- public virtual byte[] GetPreamble() { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe string GetString(byte* bytes, int byteCount) { throw null; }
- public virtual string GetString(byte[] bytes) { throw null; }
- public virtual string GetString(byte[] bytes, int index, int count) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public bool IsAlwaysNormalized() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public virtual bool IsAlwaysNormalized(System.Text.NormalizationForm form) { throw null; }
- public static void RegisterProvider(System.Text.EncodingProvider provider) { }
- }
- public sealed partial class EncodingInfo
- {
- internal EncodingInfo() { }
- public int CodePage { get { throw null; } }
- public string DisplayName { get { throw null; } }
- public string Name { get { throw null; } }
- public override bool Equals(object value) { throw null; }
- public System.Text.Encoding GetEncoding() { throw null; }
- public override int GetHashCode() { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class EncodingProvider
- {
- public EncodingProvider() { }
- public abstract System.Text.Encoding GetEncoding(int codepage);
- public virtual System.Text.Encoding GetEncoding(int codepage, System.Text.EncoderFallback encoderFallback, System.Text.DecoderFallback decoderFallback) { throw null; }
- public abstract System.Text.Encoding GetEncoding(string name);
- public virtual System.Text.Encoding GetEncoding(string name, System.Text.EncoderFallback encoderFallback, System.Text.DecoderFallback decoderFallback) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum NormalizationForm
- {
- FormC = 1,
- FormD = 2,
- FormKC = 5,
- FormKD = 6,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class StringBuilder
- {
- public StringBuilder() { }
- public StringBuilder(int capacity) { }
- public StringBuilder(int capacity, int maxCapacity) { }
- public StringBuilder(string value) { }
- public StringBuilder(string value, int capacity) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public StringBuilder(string value, int startIndex, int length, int capacity) { }
- public int Capacity { get { throw null; } set { } }
- [System.Runtime.CompilerServices.IndexerName("Chars")]
- public char this[int index] { get { throw null; } set { } }
- public int Length { get { throw null; } set { } }
- public int MaxCapacity { get { throw null; } }
- public System.Text.StringBuilder Append(bool value) { throw null; }
- public System.Text.StringBuilder Append(byte value) { throw null; }
- public System.Text.StringBuilder Append(char value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe System.Text.StringBuilder Append(char* value, int valueCount) { throw null; }
- public System.Text.StringBuilder Append(char value, int repeatCount) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Text.StringBuilder Append(char[] value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Text.StringBuilder Append(char[] value, int startIndex, int charCount) { throw null; }
- public System.Text.StringBuilder Append(decimal value) { throw null; }
- public System.Text.StringBuilder Append(double value) { throw null; }
- public System.Text.StringBuilder Append(short value) { throw null; }
- public System.Text.StringBuilder Append(int value) { throw null; }
- public System.Text.StringBuilder Append(long value) { throw null; }
- public System.Text.StringBuilder Append(object value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public System.Text.StringBuilder Append(sbyte value) { throw null; }
- public System.Text.StringBuilder Append(float value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Text.StringBuilder Append(string value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Text.StringBuilder Append(string value, int startIndex, int count) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public System.Text.StringBuilder Append(ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public System.Text.StringBuilder Append(uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public System.Text.StringBuilder Append(ulong value) { throw null; }
- public System.Text.StringBuilder AppendFormat(System.IFormatProvider provider, string format, object arg0) { throw null; }
- public System.Text.StringBuilder AppendFormat(System.IFormatProvider provider, string format, object arg0, object arg1) { throw null; }
- public System.Text.StringBuilder AppendFormat(System.IFormatProvider provider, string format, object arg0, object arg1, object arg2) { throw null; }
- public System.Text.StringBuilder AppendFormat(System.IFormatProvider provider, string format, params object[] args) { throw null; }
- public System.Text.StringBuilder AppendFormat(string format, object arg0) { throw null; }
- public System.Text.StringBuilder AppendFormat(string format, object arg0, object arg1) { throw null; }
- public System.Text.StringBuilder AppendFormat(string format, object arg0, object arg1, object arg2) { throw null; }
- public System.Text.StringBuilder AppendFormat(string format, params object[] args) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Text.StringBuilder AppendLine() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public System.Text.StringBuilder AppendLine(string value) { throw null; }
- public System.Text.StringBuilder Clear() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count) { }
- public int EnsureCapacity(int capacity) { throw null; }
- public bool Equals(System.Text.StringBuilder sb) { throw null; }
- public System.Text.StringBuilder Insert(int index, bool value) { throw null; }
- public System.Text.StringBuilder Insert(int index, byte value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Text.StringBuilder Insert(int index, char value) { throw null; }
- public System.Text.StringBuilder Insert(int index, char[] value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Text.StringBuilder Insert(int index, char[] value, int startIndex, int charCount) { throw null; }
- public System.Text.StringBuilder Insert(int index, decimal value) { throw null; }
- public System.Text.StringBuilder Insert(int index, double value) { throw null; }
- public System.Text.StringBuilder Insert(int index, short value) { throw null; }
- public System.Text.StringBuilder Insert(int index, int value) { throw null; }
- public System.Text.StringBuilder Insert(int index, long value) { throw null; }
- public System.Text.StringBuilder Insert(int index, object value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public System.Text.StringBuilder Insert(int index, sbyte value) { throw null; }
- public System.Text.StringBuilder Insert(int index, float value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Text.StringBuilder Insert(int index, string value) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public System.Text.StringBuilder Insert(int index, string value, int count) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public System.Text.StringBuilder Insert(int index, ushort value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public System.Text.StringBuilder Insert(int index, uint value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public System.Text.StringBuilder Insert(int index, ulong value) { throw null; }
- public System.Text.StringBuilder Remove(int startIndex, int length) { throw null; }
- public System.Text.StringBuilder Replace(char oldChar, char newChar) { throw null; }
- public System.Text.StringBuilder Replace(char oldChar, char newChar, int startIndex, int count) { throw null; }
- public System.Text.StringBuilder Replace(string oldValue, string newValue) { throw null; }
- public System.Text.StringBuilder Replace(string oldValue, string newValue, int startIndex, int count) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public override string ToString() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public string ToString(int startIndex, int length) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class UnicodeEncoding : System.Text.Encoding
- {
- public const int CharSize = 2;
- public UnicodeEncoding() { }
- public UnicodeEncoding(bool bigEndian, bool byteOrderMark) { }
- public UnicodeEncoding(bool bigEndian, bool byteOrderMark, bool throwOnInvalidBytes) { }
- public override bool Equals(object value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetByteCount(char* chars, int count) { throw null; }
- public override int GetByteCount(char[] chars, int index, int count) { throw null; }
- public override int GetByteCount(string s) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount) { throw null; }
- public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { throw null; }
- public override int GetBytes(string s, int charIndex, int charCount, byte[] bytes, int byteIndex) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetCharCount(byte* bytes, int count) { throw null; }
- public override int GetCharCount(byte[] bytes, int index, int count) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount) { throw null; }
- public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { throw null; }
- public override System.Text.Decoder GetDecoder() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override System.Text.Encoder GetEncoder() { throw null; }
- public override int GetHashCode() { throw null; }
- public override int GetMaxByteCount(int charCount) { throw null; }
- public override int GetMaxCharCount(int byteCount) { throw null; }
- public override byte[] GetPreamble() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override string GetString(byte[] bytes, int index, int count) { throw null; }
- }
- public sealed partial class UTF32Encoding : System.Text.Encoding
- {
- public UTF32Encoding() { }
- public UTF32Encoding(bool bigEndian, bool byteOrderMark) { }
- public UTF32Encoding(bool bigEndian, bool byteOrderMark, bool throwOnInvalidCharacters) { }
- public override bool Equals(object value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetByteCount(char* chars, int count) { throw null; }
- public override int GetByteCount(char[] chars, int index, int count) { throw null; }
- public override int GetByteCount(string s) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount) { throw null; }
- public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { throw null; }
- public override int GetBytes(string s, int charIndex, int charCount, byte[] bytes, int byteIndex) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetCharCount(byte* bytes, int count) { throw null; }
- public override int GetCharCount(byte[] bytes, int index, int count) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount) { throw null; }
- public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { throw null; }
- public override System.Text.Decoder GetDecoder() { throw null; }
- public override System.Text.Encoder GetEncoder() { throw null; }
- public override int GetHashCode() { throw null; }
- public override int GetMaxByteCount(int charCount) { throw null; }
- public override int GetMaxCharCount(int byteCount) { throw null; }
- public override byte[] GetPreamble() { throw null; }
- public override string GetString(byte[] bytes, int index, int count) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class UTF7Encoding : System.Text.Encoding
- {
- public UTF7Encoding() { }
- public UTF7Encoding(bool allowOptionals) { }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override bool Equals(object value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetByteCount(char* chars, int count) { throw null; }
- public override int GetByteCount(char[] chars, int index, int count) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetByteCount(string s) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount) { throw null; }
- public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetBytes(string s, int charIndex, int charCount, byte[] bytes, int byteIndex) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetCharCount(byte* bytes, int count) { throw null; }
- public override int GetCharCount(byte[] bytes, int index, int count) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount) { throw null; }
- public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { throw null; }
- public override System.Text.Decoder GetDecoder() { throw null; }
- public override System.Text.Encoder GetEncoder() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetHashCode() { throw null; }
- public override int GetMaxByteCount(int charCount) { throw null; }
- public override int GetMaxCharCount(int byteCount) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override string GetString(byte[] bytes, int index, int count) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class UTF8Encoding : System.Text.Encoding
- {
- public UTF8Encoding() { }
- public UTF8Encoding(bool encoderShouldEmitUTF8Identifier) { }
- public UTF8Encoding(bool encoderShouldEmitUTF8Identifier, bool throwOnInvalidBytes) { }
- public override bool Equals(object value) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetByteCount(char* chars, int count) { throw null; }
- public override int GetByteCount(char[] chars, int index, int count) { throw null; }
- public override int GetByteCount(string chars) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount) { throw null; }
- public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { throw null; }
- public override int GetBytes(string s, int charIndex, int charCount, byte[] bytes, int byteIndex) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetCharCount(byte* bytes, int count) { throw null; }
- public override int GetCharCount(byte[] bytes, int index, int count) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount) { throw null; }
- public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { throw null; }
- public override System.Text.Decoder GetDecoder() { throw null; }
- public override System.Text.Encoder GetEncoder() { throw null; }
- public override int GetHashCode() { throw null; }
- public override int GetMaxByteCount(int charCount) { throw null; }
- public override int GetMaxCharCount(int byteCount) { throw null; }
- public override byte[] GetPreamble() { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override string GetString(byte[] bytes, int index, int count) { throw null; }
- }
-}
-namespace System.Threading
-{
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public partial class AbandonedMutexException : System.SystemException
- {
- public AbandonedMutexException() { }
- public AbandonedMutexException(int location, System.Threading.WaitHandle handle) { }
- public AbandonedMutexException(string message) { }
- public AbandonedMutexException(string message, System.Exception inner) { }
- public AbandonedMutexException(string message, System.Exception inner, int location, System.Threading.WaitHandle handle) { }
- public AbandonedMutexException(string message, int location, System.Threading.WaitHandle handle) { }
- protected AbandonedMutexException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- public System.Threading.Mutex Mutex { get { throw null; } }
- public int MutexIndex { get { throw null; } }
- }
- public enum ApartmentState
- {
- MTA = 1,
- STA = 0,
- Unknown = 2,
- }
- public sealed partial class AsyncLocal<T>
- {
- public AsyncLocal() { }
- [System.Security.SecurityCriticalAttribute]
- public AsyncLocal(System.Action<System.Threading.AsyncLocalValueChangedArgs<T>> valueChangedHandler) { }
- public T Value { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } [System.Security.SecuritySafeCriticalAttribute]set { } }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct AsyncLocalValueChangedArgs<T>
- {
- public T CurrentValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
- public T PreviousValue { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
- public bool ThreadContextChanged { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class AutoResetEvent : System.Threading.EventWaitHandle
- {
- public AutoResetEvent(bool initialState) : base (default(bool), default(System.Threading.EventResetMode)) { }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("IsCancellationRequested = {IsCancellationRequested}")]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct CancellationToken
- {
- public CancellationToken(bool canceled) { throw null;}
- public bool CanBeCanceled { get { throw null; } }
- public bool IsCancellationRequested { get { throw null; } }
- public static System.Threading.CancellationToken None { get { throw null; } }
- public System.Threading.WaitHandle WaitHandle { get { throw null; } }
- public override bool Equals(object other) { throw null; }
- public bool Equals(System.Threading.CancellationToken other) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Threading.CancellationToken left, System.Threading.CancellationToken right) { throw null; }
- public static bool operator !=(System.Threading.CancellationToken left, System.Threading.CancellationToken right) { throw null; }
- public System.Threading.CancellationTokenRegistration Register(System.Action callback) { throw null; }
- public System.Threading.CancellationTokenRegistration Register(System.Action callback, bool useSynchronizationContext) { throw null; }
- public System.Threading.CancellationTokenRegistration Register(System.Action<object> callback, object state) { throw null; }
- public System.Threading.CancellationTokenRegistration Register(System.Action<object> callback, object state, bool useSynchronizationContext) { throw null; }
- public void ThrowIfCancellationRequested() { }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct CancellationTokenRegistration : System.IDisposable, System.IEquatable<System.Threading.CancellationTokenRegistration>
- {
- public void Dispose() { }
- public override bool Equals(object obj) { throw null; }
- public bool Equals(System.Threading.CancellationTokenRegistration other) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Threading.CancellationTokenRegistration left, System.Threading.CancellationTokenRegistration right) { throw null; }
- public static bool operator !=(System.Threading.CancellationTokenRegistration left, System.Threading.CancellationTokenRegistration right) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public partial class CancellationTokenSource : System.IDisposable
- {
- public CancellationTokenSource() { }
- public CancellationTokenSource(int millisecondsDelay) { }
- public CancellationTokenSource(System.TimeSpan delay) { }
- public bool IsCancellationRequested { get { throw null; } }
- public System.Threading.CancellationToken Token { get { throw null; } }
- public void Cancel() { }
- public void Cancel(bool throwOnFirstException) { }
- public void CancelAfter(int millisecondsDelay) { }
- public void CancelAfter(System.TimeSpan delay) { }
- public static System.Threading.CancellationTokenSource CreateLinkedTokenSource(System.Threading.CancellationToken token1, System.Threading.CancellationToken token2) { throw null; }
- public static System.Threading.CancellationTokenSource CreateLinkedTokenSource(params System.Threading.CancellationToken[] tokens) { throw null; }
- public void Dispose() { }
- protected virtual void Dispose(bool disposing) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public delegate void ContextCallback(object state);
- [System.Diagnostics.DebuggerDisplayAttribute("Initial Count={InitialCount}, Current Count={CurrentCount}")]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public partial class CountdownEvent : System.IDisposable
- {
- public CountdownEvent(int initialCount) { }
- public int CurrentCount { get { throw null; } }
- public int InitialCount { get { throw null; } }
- public bool IsSet { get { throw null; } }
- public System.Threading.WaitHandle WaitHandle { get { throw null; } }
- public void AddCount() { }
- public void AddCount(int signalCount) { }
- public void Dispose() { }
- protected virtual void Dispose(bool disposing) { }
- public void Reset() { }
- public void Reset(int count) { }
- public bool Signal() { throw null; }
- public bool Signal(int signalCount) { throw null; }
- public bool TryAddCount() { throw null; }
- public bool TryAddCount(int signalCount) { throw null; }
- public void Wait() { }
- public bool Wait(int millisecondsTimeout) { throw null; }
- public bool Wait(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) { throw null; }
- public void Wait(System.Threading.CancellationToken cancellationToken) { }
- public bool Wait(System.TimeSpan timeout) { throw null; }
- public bool Wait(System.TimeSpan timeout, System.Threading.CancellationToken cancellationToken) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public enum EventResetMode
- {
- AutoReset = 0,
- ManualReset = 1,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class EventWaitHandle : System.Threading.WaitHandle
- {
- [System.Security.SecuritySafeCriticalAttribute]
- public EventWaitHandle(bool initialState, System.Threading.EventResetMode mode) { }
- [System.Security.SecurityCriticalAttribute]
- public EventWaitHandle(bool initialState, System.Threading.EventResetMode mode, string name) { }
- [System.Security.SecurityCriticalAttribute]
- public EventWaitHandle(bool initialState, System.Threading.EventResetMode mode, string name, out bool createdNew) { createdNew = default(bool); }
- [System.Security.SecurityCriticalAttribute]
- public static System.Threading.EventWaitHandle OpenExisting(string name) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public bool Reset() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public bool Set() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static bool TryOpenExisting(string name, out System.Threading.EventWaitHandle result) { result = default(System.Threading.EventWaitHandle); throw null; }
- }
- public sealed partial class ExecutionContext : System.IDisposable
- {
- internal ExecutionContext() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Threading.ExecutionContext Capture() { throw null; }
- public void Dispose() { }
- [System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute]
- [System.Security.SecurityCriticalAttribute]
- public static void Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) { }
- }
- public static partial class Interlocked
- {
- public static int Add(ref int location1, int value) { throw null; }
- public static long Add(ref long location1, long value) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double CompareExchange(ref double location1, double value, double comparand) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static int CompareExchange(ref int location1, int value, int comparand) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static long CompareExchange(ref long location1, long value, long comparand) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static System.IntPtr CompareExchange(ref System.IntPtr location1, System.IntPtr value, System.IntPtr comparand) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static object CompareExchange(ref object location1, object value, object comparand) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float CompareExchange(ref float location1, float value, float comparand) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static T CompareExchange<T>(ref T location1, T value, T comparand) where T : class { throw null; }
- public static int Decrement(ref int location) { throw null; }
- public static long Decrement(ref long location) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static double Exchange(ref double location1, double value) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static int Exchange(ref int location1, int value) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static long Exchange(ref long location1, long value) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static System.IntPtr Exchange(ref System.IntPtr location1, System.IntPtr value) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static object Exchange(ref object location1, object value) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static float Exchange(ref float location1, float value) { throw null; }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static T Exchange<T>(ref T location1, T value) where T : class { throw null; }
- public static int Increment(ref int location) { throw null; }
- public static long Increment(ref long location) { throw null; }
- public static void MemoryBarrier() { }
- public static long Read(ref long location) { throw null; }
- }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe delegate void IOCompletionCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* pOVERLAP);
- public static partial class LazyInitializer
- {
- public static T EnsureInitialized<T>(ref T target) where T : class { throw null; }
- public static T EnsureInitialized<T>(ref T target, ref bool initialized, ref object syncLock) { throw null; }
- public static T EnsureInitialized<T>(ref T target, ref bool initialized, ref object syncLock, System.Func<T> valueFactory) { throw null; }
- public static T EnsureInitialized<T>(ref T target, System.Func<T> valueFactory) where T : class { throw null; }
- }
- public enum LazyThreadSafetyMode
- {
- ExecutionAndPublication = 2,
- None = 0,
- PublicationOnly = 1,
- }
- [System.Runtime.CompilerServices.TypeForwardedFromAttribute("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
- public partial class LockRecursionException : System.Exception
- {
- public LockRecursionException() { }
- public LockRecursionException(string message) { }
- public LockRecursionException(string message, System.Exception innerException) { }
- protected LockRecursionException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ManualResetEvent : System.Threading.EventWaitHandle
- {
- public ManualResetEvent(bool initialState) : base (default(bool), default(System.Threading.EventResetMode)) { }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("Set = {IsSet}")]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public partial class ManualResetEventSlim : System.IDisposable
- {
- public ManualResetEventSlim() { }
- public ManualResetEventSlim(bool initialState) { }
- public ManualResetEventSlim(bool initialState, int spinCount) { }
- public bool IsSet { get { throw null; } }
- public int SpinCount { get { throw null; } }
- public System.Threading.WaitHandle WaitHandle { get { throw null; } }
- public void Dispose() { }
- protected virtual void Dispose(bool disposing) { }
- public void Reset() { }
- public void Set() { }
- public void Wait() { }
- public bool Wait(int millisecondsTimeout) { throw null; }
- public bool Wait(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) { throw null; }
- public void Wait(System.Threading.CancellationToken cancellationToken) { }
- public bool Wait(System.TimeSpan timeout) { throw null; }
- public bool Wait(System.TimeSpan timeout, System.Threading.CancellationToken cancellationToken) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static partial class Monitor
- {
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static void Enter(object obj) { }
- public static void Enter(object obj, ref bool lockTaken) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static void Exit(object obj) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static bool IsEntered(object obj) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Pulse(object obj) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void PulseAll(object obj) { }
- public static bool TryEnter(object obj) { throw null; }
- public static void TryEnter(object obj, ref bool lockTaken) { }
- public static bool TryEnter(object obj, int millisecondsTimeout) { throw null; }
- public static void TryEnter(object obj, int millisecondsTimeout, ref bool lockTaken) { }
- public static bool TryEnter(object obj, System.TimeSpan timeout) { throw null; }
- public static void TryEnter(object obj, System.TimeSpan timeout, ref bool lockTaken) { }
- public static bool Wait(object obj) { throw null; }
- public static bool Wait(object obj, int millisecondsTimeout) { throw null; }
- public static bool Wait(object obj, int millisecondsTimeout, bool exitContext) { throw null; }
- public static bool Wait(object obj, System.TimeSpan timeout) { throw null; }
- public static bool Wait(object obj, System.TimeSpan timeout, bool exitContext) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class Mutex : System.Threading.WaitHandle
- {
- [System.Security.SecuritySafeCriticalAttribute]
- public Mutex() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public Mutex(bool initiallyOwned) { }
- [System.Security.SecurityCriticalAttribute]
- public Mutex(bool initiallyOwned, string name) { }
- [System.Security.SecurityCriticalAttribute]
- public Mutex(bool initiallyOwned, string name, out bool createdNew) { createdNew = default(bool); }
- [System.Security.SecurityCriticalAttribute]
- public static System.Threading.Mutex OpenExisting(string name) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public void ReleaseMutex() { }
- [System.Security.SecurityCriticalAttribute]
- public static bool TryOpenExisting(string name, out System.Threading.Mutex result) { result = default(System.Threading.Mutex); throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct NativeOverlapped
- {
- public System.IntPtr EventHandle;
- public System.IntPtr InternalHigh;
- public System.IntPtr InternalLow;
- public int OffsetHigh;
- public int OffsetLow;
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class Overlapped
- {
- [System.Security.SecuritySafeCriticalAttribute]
- public Overlapped() { }
- public System.IAsyncResult AsyncResult { get { throw null; } set { } }
- public int OffsetHigh { get { throw null; } set { } }
- public int OffsetLow { get { throw null; } set { } }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe static void Free(System.Threading.NativeOverlapped* nativeOverlappedPtr) { }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe System.Threading.NativeOverlapped* Pack(System.Threading.IOCompletionCallback iocb, object userData) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe static System.Threading.Overlapped Unpack(System.Threading.NativeOverlapped* nativeOverlappedPtr) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Security.SecurityCriticalAttribute]
- public unsafe System.Threading.NativeOverlapped* UnsafePack(System.Threading.IOCompletionCallback iocb, object userData) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public delegate void ParameterizedThreadStart(object obj);
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class RegisteredWaitHandle
- {
- internal RegisteredWaitHandle() { }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- [System.Security.SecuritySafeCriticalAttribute]
- public bool Unregister(System.Threading.WaitHandle waitObject) { throw null; }
- }
- public sealed partial class Semaphore : System.Threading.WaitHandle
- {
- [System.Security.SecuritySafeCriticalAttribute]
- public Semaphore(int initialCount, int maximumCount) { }
- [System.Security.SecurityCriticalAttribute]
- public Semaphore(int initialCount, int maximumCount, string name) { }
- [System.Security.SecurityCriticalAttribute]
- public Semaphore(int initialCount, int maximumCount, string name, out bool createdNew) { createdNew = default(bool); }
- [System.Security.SecurityCriticalAttribute]
- public static System.Threading.Semaphore OpenExisting(string name) { throw null; }
- public int Release() { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public int Release(int releaseCount) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static bool TryOpenExisting(string name, out System.Threading.Semaphore result) { result = default(System.Threading.Semaphore); throw null; }
- }
- [System.Runtime.CompilerServices.TypeForwardedFromAttribute("System, Version=2.0.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public partial class SemaphoreFullException : System.SystemException
- {
- public SemaphoreFullException() { }
- public SemaphoreFullException(string message) { }
- public SemaphoreFullException(string message, System.Exception innerException) { }
- protected SemaphoreFullException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("Current Count = {m_currentCount}")]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public partial class SemaphoreSlim : System.IDisposable
- {
- public SemaphoreSlim(int initialCount) { }
- public SemaphoreSlim(int initialCount, int maxCount) { }
- public System.Threading.WaitHandle AvailableWaitHandle { get { throw null; } }
- public int CurrentCount { get { throw null; } }
- public void Dispose() { }
- protected virtual void Dispose(bool disposing) { }
- public int Release() { throw null; }
- public int Release(int releaseCount) { throw null; }
- public void Wait() { }
- public bool Wait(int millisecondsTimeout) { throw null; }
- public bool Wait(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) { throw null; }
- public void Wait(System.Threading.CancellationToken cancellationToken) { }
- public bool Wait(System.TimeSpan timeout) { throw null; }
- public bool Wait(System.TimeSpan timeout, System.Threading.CancellationToken cancellationToken) { throw null; }
- public System.Threading.Tasks.Task WaitAsync() { throw null; }
- public System.Threading.Tasks.Task<bool> WaitAsync(int millisecondsTimeout) { throw null; }
- public System.Threading.Tasks.Task<bool> WaitAsync(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) { throw null; }
- public System.Threading.Tasks.Task WaitAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
- public System.Threading.Tasks.Task<bool> WaitAsync(System.TimeSpan timeout) { throw null; }
- public System.Threading.Tasks.Task<bool> WaitAsync(System.TimeSpan timeout, System.Threading.CancellationToken cancellationToken) { throw null; }
- }
- public delegate void SendOrPostCallback(object state);
- [System.Diagnostics.DebuggerDisplayAttribute("IsHeld = {IsHeld}")]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct SpinLock
- {
- public SpinLock(bool enableThreadOwnerTracking) { throw null;}
- public bool IsHeld { get { throw null; } }
- public bool IsHeldByCurrentThread { get { throw null; } }
- public bool IsThreadOwnerTrackingEnabled { get { throw null; } }
- public void Enter(ref bool lockTaken) { }
- public void Exit() { }
- public void Exit(bool useMemoryBarrier) { }
- public void TryEnter(ref bool lockTaken) { }
- public void TryEnter(int millisecondsTimeout, ref bool lockTaken) { }
- public void TryEnter(System.TimeSpan timeout, ref bool lockTaken) { }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct SpinWait
- {
- public int Count { get { throw null; } }
- public bool NextSpinWillYield { get { throw null; } }
- public void Reset() { }
- public void SpinOnce() { }
- public static void SpinUntil(System.Func<bool> condition) { }
- public static bool SpinUntil(System.Func<bool> condition, int millisecondsTimeout) { throw null; }
- public static bool SpinUntil(System.Func<bool> condition, System.TimeSpan timeout) { throw null; }
- }
- public partial class SynchronizationContext
- {
- public SynchronizationContext() { }
- public static System.Threading.SynchronizationContext Current { get { throw null; } }
- public virtual System.Threading.SynchronizationContext CreateCopy() { throw null; }
- public virtual void OperationCompleted() { }
- public virtual void OperationStarted() { }
- public virtual void Post(System.Threading.SendOrPostCallback d, object state) { }
- public virtual void Send(System.Threading.SendOrPostCallback d, object state) { }
- [System.Security.SecurityCriticalAttribute]
- public static void SetSynchronizationContext(System.Threading.SynchronizationContext syncContext) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class SynchronizationLockException : System.SystemException
- {
- public SynchronizationLockException() { }
- public SynchronizationLockException(string message) { }
- public SynchronizationLockException(string message, System.Exception innerException) { }
- protected SynchronizationLockException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ClassInterfaceAttribute((System.Runtime.InteropServices.ClassInterfaceType)(0))]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class Thread : Internal.Runtime.Augments.RuntimeThread
- {
- [System.Security.SecuritySafeCriticalAttribute]
- public Thread(System.Threading.ParameterizedThreadStart start) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public Thread(System.Threading.ThreadStart start) { }
- public System.Globalization.CultureInfo CurrentCulture { get { throw null; } [System.Security.SecuritySafeCriticalAttribute]set { } }
- public static new System.Threading.Thread CurrentThread { [System.Security.SecuritySafeCriticalAttribute]get { throw null; } }
- public System.Globalization.CultureInfo CurrentUICulture { get { throw null; } [System.Security.SecuritySafeCriticalAttribute]set { } }
- public new int ManagedThreadId { [System.Security.SecuritySafeCriticalAttribute][System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } }
- public new string Name { get { throw null; } [System.Security.SecuritySafeCriticalAttribute]set { } }
- ~Thread() { }
- [System.Security.SecuritySafeCriticalAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public override int GetHashCode() { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)][System.Security.SecuritySafeCriticalAttribute]
- public static void MemoryBarrier() { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static new void Sleep(int millisecondsTimeout) { }
- public static void Sleep(System.TimeSpan timeout) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static new void SpinWait(int iterations) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public new void Start() { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- public new void Start(object parameter) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class ThreadAbortException : System.SystemException
- {
- internal ThreadAbortException() { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ThreadInterruptedException : System.SystemException
- {
- public ThreadInterruptedException() { }
- public ThreadInterruptedException(string message) { }
- public ThreadInterruptedException(string message, System.Exception innerException) { }
- protected ThreadInterruptedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("IsValueCreated={IsValueCreated}, Value={ValueForDebugDisplay}, Count={ValuesCountForDebugDisplay}")]
- public partial class ThreadLocal<T> : System.IDisposable
- {
- public ThreadLocal() { }
- public ThreadLocal(bool trackAllValues) { }
- public ThreadLocal(System.Func<T> valueFactory) { }
- public ThreadLocal(System.Func<T> valueFactory, bool trackAllValues) { }
- public bool IsValueCreated { get { throw null; } }
- [System.Diagnostics.DebuggerBrowsableAttribute((System.Diagnostics.DebuggerBrowsableState)(0))]
- public T Value { get { throw null; } set { } }
- public System.Collections.Generic.IList<T> Values { get { throw null; } }
- public void Dispose() { }
- protected virtual void Dispose(bool disposing) { }
- ~ThreadLocal() { }
- public override string ToString() { throw null; }
- }
- public static partial class ThreadPool
- {
- [System.Security.SecurityCriticalAttribute]
- public static bool BindHandle(System.Runtime.InteropServices.SafeHandle osHandle) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void GetMaxThreads(out int workerThreads, out int completionPortThreads) { workerThreads = default(int); completionPortThreads = default(int); }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void GetMinThreads(out int workerThreads, out int completionPortThreads) { workerThreads = default(int); completionPortThreads = default(int); }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public static bool QueueUserWorkItem(System.Threading.WaitCallback callBack) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public static bool QueueUserWorkItem(System.Threading.WaitCallback callBack, object state) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public static System.Threading.RegisteredWaitHandle RegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object state, int millisecondsTimeOutInterval, bool executeOnlyOnce) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public static System.Threading.RegisteredWaitHandle RegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object state, long millisecondsTimeOutInterval, bool executeOnlyOnce) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public static System.Threading.RegisteredWaitHandle RegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object state, System.TimeSpan timeout, bool executeOnlyOnce) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static System.Threading.RegisteredWaitHandle RegisterWaitForSingleObject(System.Threading.WaitHandle waitObject, System.Threading.WaitOrTimerCallback callBack, object state, uint millisecondsTimeOutInterval, bool executeOnlyOnce) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static bool SetMaxThreads(int workerThreads, int completionPortThreads) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static bool SetMinThreads(int workerThreads, int completionPortThreads) { throw null; }
- }
- public enum ThreadPriority
- {
- AboveNormal = 3,
- BelowNormal = 1,
- Highest = 4,
- Lowest = 0,
- Normal = 2,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public delegate void ThreadStart();
- public sealed partial class ThreadStartException : System.SystemException
- {
- internal ThreadStartException() { }
- }
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum ThreadState
- {
- Aborted = 256,
- AbortRequested = 128,
- Background = 4,
- Running = 0,
- Stopped = 16,
- StopRequested = 1,
- Suspended = 64,
- SuspendRequested = 2,
- Unstarted = 8,
- WaitSleepJoin = 32,
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public partial class ThreadStateException : System.SystemException
- {
- public ThreadStateException() { }
- public ThreadStateException(string message) { }
- public ThreadStateException(string message, System.Exception innerException) { }
- protected ThreadStateException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public static partial class Timeout
- {
- public const int Infinite = -1;
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public static readonly System.TimeSpan InfiniteTimeSpan;
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public sealed partial class Timer : System.IDisposable
- {
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public Timer(System.Threading.TimerCallback callback) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public Timer(System.Threading.TimerCallback callback, object state, int dueTime, int period) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public Timer(System.Threading.TimerCallback callback, object state, long dueTime, long period) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.Security.SecuritySafeCriticalAttribute]
- public Timer(System.Threading.TimerCallback callback, object state, System.TimeSpan dueTime, System.TimeSpan period) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)][System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public Timer(System.Threading.TimerCallback callback, object state, uint dueTime, uint period) { }
- public bool Change(int dueTime, int period) { throw null; }
- public bool Change(long dueTime, long period) { throw null; }
- public bool Change(System.TimeSpan dueTime, System.TimeSpan period) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public bool Change(uint dueTime, uint period) { throw null; }
- public void Dispose() { }
- public bool Dispose(System.Threading.WaitHandle notifyObject) { throw null; }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public delegate void TimerCallback(object state);
- public static partial class Volatile
- {
- public static bool Read(ref bool location) { throw null; }
- public static byte Read(ref byte location) { throw null; }
- public static double Read(ref double location) { throw null; }
- public static short Read(ref short location) { throw null; }
- public static int Read(ref int location) { throw null; }
- public static long Read(ref long location) { throw null; }
- public static System.IntPtr Read(ref System.IntPtr location) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static sbyte Read(ref sbyte location) { throw null; }
- public static float Read(ref float location) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static ushort Read(ref ushort location) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static uint Read(ref uint location) { throw null; }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static ulong Read(ref ulong location) { throw null; }
- [System.CLSCompliantAttribute(false)]
- public static System.UIntPtr Read(ref System.UIntPtr location) { throw null; }
- [System.Security.SecuritySafeCriticalAttribute]
- public static T Read<T>(ref T location) where T : class { throw null; }
- public static void Write(ref bool location, bool value) { }
- public static void Write(ref byte location, byte value) { }
- public static void Write(ref double location, double value) { }
- public static void Write(ref short location, short value) { }
- public static void Write(ref int location, int value) { }
- public static void Write(ref long location, long value) { }
- public static void Write(ref System.IntPtr location, System.IntPtr value) { }
- [System.CLSCompliantAttribute(false)]
- public static void Write(ref sbyte location, sbyte value) { }
- public static void Write(ref float location, float value) { }
- [System.CLSCompliantAttribute(false)]
- public static void Write(ref ushort location, ushort value) { }
- [System.CLSCompliantAttribute(false)]
- public static void Write(ref uint location, uint value) { }
- [System.CLSCompliantAttribute(false)]
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Write(ref ulong location, ulong value) { }
- [System.CLSCompliantAttribute(false)]
- public static void Write(ref System.UIntPtr location, System.UIntPtr value) { }
- [System.Security.SecuritySafeCriticalAttribute]
- public static void Write<T>(ref T location, T value) where T : class { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public delegate void WaitCallback(object state);
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public abstract partial class WaitHandle : System.IDisposable
- {
- protected static readonly System.IntPtr InvalidHandle;
- public const int WaitTimeout = 258;
- protected WaitHandle() { }
- [System.ObsoleteAttribute("Use the SafeWaitHandle property instead.")]
- public virtual System.IntPtr Handle { [System.Security.SecuritySafeCriticalAttribute]get { return default(System.IntPtr); } [System.Security.SecurityCriticalAttribute]set { } }
- public Microsoft.Win32.SafeHandles.SafeWaitHandle SafeWaitHandle { [System.Security.SecurityCriticalAttribute]get { throw null; } [System.Security.SecurityCriticalAttribute]set { } }
- public virtual void Close() { }
- public void Dispose() { }
- [System.Security.SecuritySafeCriticalAttribute]
- protected virtual void Dispose(bool explicitDisposing) { }
- public static bool SignalAndWait(System.Threading.WaitHandle toSignal, System.Threading.WaitHandle toWaitOn) { return default(bool); }
- public static bool SignalAndWait(System.Threading.WaitHandle toSignal, System.Threading.WaitHandle toWaitOn, int millisecondsTimeout, bool exitContext) { return default(bool); }
- public static bool SignalAndWait(System.Threading.WaitHandle toSignal, System.Threading.WaitHandle toWaitOn, System.TimeSpan timeout, bool exitContext) { return default(bool); }
- public static bool WaitAll(System.Threading.WaitHandle[] waitHandles) { throw null; }
- public static bool WaitAll(System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout) { throw null; }
- public static bool WaitAll(System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext) { return default(bool); }
- public static bool WaitAll(System.Threading.WaitHandle[] waitHandles, System.TimeSpan timeout) { throw null; }
- public static bool WaitAll(System.Threading.WaitHandle[] waitHandles, System.TimeSpan timeout, bool exitContext) { return default(bool); }
- public static int WaitAny(System.Threading.WaitHandle[] waitHandles) { throw null; }
- public static int WaitAny(System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout) { throw null; }
- public static int WaitAny(System.Threading.WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext) { return default(int); }
- public static int WaitAny(System.Threading.WaitHandle[] waitHandles, System.TimeSpan timeout) { throw null; }
- public static int WaitAny(System.Threading.WaitHandle[] waitHandles, System.TimeSpan timeout, bool exitContext) { return default(int); }
- public virtual bool WaitOne() { throw null; }
- public virtual bool WaitOne(int millisecondsTimeout) { throw null; }
- public virtual bool WaitOne(int millisecondsTimeout, bool exitContext) { return default(bool); }
- public virtual bool WaitOne(System.TimeSpan timeout) { throw null; }
- public virtual bool WaitOne(System.TimeSpan timeout, bool exitContext) { return default(bool); }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(false)]
- public partial class WaitHandleCannotBeOpenedException : System.ApplicationException
- {
- public WaitHandleCannotBeOpenedException() { }
- public WaitHandleCannotBeOpenedException(string message) { }
- public WaitHandleCannotBeOpenedException(string message, System.Exception innerException) { }
- protected WaitHandleCannotBeOpenedException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public delegate void WaitOrTimerCallback(object state, bool timedOut);
-}
-namespace System.Threading.Tasks
-{
- [System.Diagnostics.DebuggerDisplayAttribute("Concurrent={ConcurrentTaskCountForDebugger}, Exclusive={ExclusiveTaskCountForDebugger}, Mode={ModeForDebugger}")]
- public partial class ConcurrentExclusiveSchedulerPair
- {
- public ConcurrentExclusiveSchedulerPair() { }
- public ConcurrentExclusiveSchedulerPair(System.Threading.Tasks.TaskScheduler taskScheduler) { }
- public ConcurrentExclusiveSchedulerPair(System.Threading.Tasks.TaskScheduler taskScheduler, int maxConcurrencyLevel) { }
- public ConcurrentExclusiveSchedulerPair(System.Threading.Tasks.TaskScheduler taskScheduler, int maxConcurrencyLevel, int maxItemsPerTask) { }
- public System.Threading.Tasks.Task Completion { get { throw null; } }
- public System.Threading.Tasks.TaskScheduler ConcurrentScheduler { get { throw null; } }
- public System.Threading.Tasks.TaskScheduler ExclusiveScheduler { get { throw null; } }
- public void Complete() { }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("Id = {Id}, Status = {Status}, Method = {DebuggerDisplayMethodDescription}")]
- public partial class Task : System.IAsyncResult, System.IDisposable
- {
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Action action) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Action action, System.Threading.CancellationToken cancellationToken) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Action action, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskCreationOptions creationOptions) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Action action, System.Threading.Tasks.TaskCreationOptions creationOptions) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Action<object> action, object state) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Action<object> action, object state, System.Threading.CancellationToken cancellationToken) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Action<object> action, object state, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskCreationOptions creationOptions) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Action<object> action, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { }
- public object AsyncState { get { throw null; } }
- public static System.Threading.Tasks.Task CompletedTask { get { throw null; } }
- public System.Threading.Tasks.TaskCreationOptions CreationOptions { get { throw null; } }
- public static System.Nullable<int> CurrentId { get { throw null; } }
- public System.AggregateException Exception { get { throw null; } }
- public static System.Threading.Tasks.TaskFactory Factory { get { throw null; } }
- public int Id { get { throw null; } }
- public bool IsCanceled { get { throw null; } }
- public bool IsCompleted { get { throw null; } }
- public bool IsFaulted { get { throw null; } }
- public System.Threading.Tasks.TaskStatus Status { get { throw null; } }
- System.Threading.WaitHandle System.IAsyncResult.AsyncWaitHandle { get { throw null; } }
- bool System.IAsyncResult.CompletedSynchronously { get { throw null; } }
- public System.Runtime.CompilerServices.ConfiguredTaskAwaitable ConfigureAwait(bool continueOnCapturedContext) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task, object> continuationAction, object state) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task, object> continuationAction, object state, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task, object> continuationAction, object state, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task, object> continuationAction, object state, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task, object> continuationAction, object state, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task> continuationAction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task> continuationAction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task> continuationAction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task> continuationAction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task> continuationAction, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWith<TResult>(System.Func<System.Threading.Tasks.Task, TResult> continuationFunction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWith<TResult>(System.Func<System.Threading.Tasks.Task, TResult> continuationFunction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWith<TResult>(System.Func<System.Threading.Tasks.Task, TResult> continuationFunction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWith<TResult>(System.Func<System.Threading.Tasks.Task, TResult> continuationFunction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWith<TResult>(System.Func<System.Threading.Tasks.Task, TResult> continuationFunction, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWith<TResult>(System.Func<System.Threading.Tasks.Task, object, TResult> continuationFunction, object state) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWith<TResult>(System.Func<System.Threading.Tasks.Task, object, TResult> continuationFunction, object state, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWith<TResult>(System.Func<System.Threading.Tasks.Task, object, TResult> continuationFunction, object state, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWith<TResult>(System.Func<System.Threading.Tasks.Task, object, TResult> continuationFunction, object state, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWith<TResult>(System.Func<System.Threading.Tasks.Task, object, TResult> continuationFunction, object state, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- public static System.Threading.Tasks.Task Delay(int millisecondsDelay) { throw null; }
- public static System.Threading.Tasks.Task Delay(int millisecondsDelay, System.Threading.CancellationToken cancellationToken) { throw null; }
- public static System.Threading.Tasks.Task Delay(System.TimeSpan delay) { throw null; }
- public static System.Threading.Tasks.Task Delay(System.TimeSpan delay, System.Threading.CancellationToken cancellationToken) { throw null; }
- public void Dispose() { }
- protected virtual void Dispose(bool disposing) { }
- public static System.Threading.Tasks.Task FromCanceled(System.Threading.CancellationToken cancellationToken) { throw null; }
- public static System.Threading.Tasks.Task<TResult> FromCanceled<TResult>(System.Threading.CancellationToken cancellationToken) { throw null; }
- public static System.Threading.Tasks.Task FromException(System.Exception exception) { throw null; }
- public static System.Threading.Tasks.Task<TResult> FromException<TResult>(System.Exception exception) { throw null; }
- public static System.Threading.Tasks.Task<TResult> FromResult<TResult>(TResult result) { throw null; }
- public System.Runtime.CompilerServices.TaskAwaiter GetAwaiter() { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public static System.Threading.Tasks.Task Run(System.Action action) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public static System.Threading.Tasks.Task Run(System.Action action, System.Threading.CancellationToken cancellationToken) { throw null; }
- public static System.Threading.Tasks.Task Run(System.Func<System.Threading.Tasks.Task> function) { throw null; }
- public static System.Threading.Tasks.Task Run(System.Func<System.Threading.Tasks.Task> function, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public static System.Threading.Tasks.Task<TResult> Run<TResult>(System.Func<TResult> function) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public static System.Threading.Tasks.Task<TResult> Run<TResult>(System.Func<TResult> function, System.Threading.CancellationToken cancellationToken) { throw null; }
- public static System.Threading.Tasks.Task<TResult> Run<TResult>(System.Func<System.Threading.Tasks.Task<TResult>> function) { throw null; }
- public static System.Threading.Tasks.Task<TResult> Run<TResult>(System.Func<System.Threading.Tasks.Task<TResult>> function, System.Threading.CancellationToken cancellationToken) { throw null; }
- public void RunSynchronously() { }
- public void RunSynchronously(System.Threading.Tasks.TaskScheduler scheduler) { }
- public void Start() { }
- public void Start(System.Threading.Tasks.TaskScheduler scheduler) { }
- public void Wait() { }
- public bool Wait(int millisecondsTimeout) { throw null; }
- public bool Wait(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) { throw null; }
- public void Wait(System.Threading.CancellationToken cancellationToken) { }
- public bool Wait(System.TimeSpan timeout) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)]public static void WaitAll(params System.Threading.Tasks.Task[] tasks) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)]public static bool WaitAll(System.Threading.Tasks.Task[] tasks, int millisecondsTimeout) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)]public static bool WaitAll(System.Threading.Tasks.Task[] tasks, int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)]public static void WaitAll(System.Threading.Tasks.Task[] tasks, System.Threading.CancellationToken cancellationToken) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)]public static bool WaitAll(System.Threading.Tasks.Task[] tasks, System.TimeSpan timeout) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)]public static int WaitAny(params System.Threading.Tasks.Task[] tasks) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)]public static int WaitAny(System.Threading.Tasks.Task[] tasks, int millisecondsTimeout) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)]public static int WaitAny(System.Threading.Tasks.Task[] tasks, int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)]public static int WaitAny(System.Threading.Tasks.Task[] tasks, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)]public static int WaitAny(System.Threading.Tasks.Task[] tasks, System.TimeSpan timeout) { throw null; }
- public static System.Threading.Tasks.Task WhenAll(System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task> tasks) { throw null; }
- public static System.Threading.Tasks.Task WhenAll(params System.Threading.Tasks.Task[] tasks) { throw null; }
- public static System.Threading.Tasks.Task<TResult[]> WhenAll<TResult>(System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task<TResult>> tasks) { throw null; }
- public static System.Threading.Tasks.Task<TResult[]> WhenAll<TResult>(params System.Threading.Tasks.Task<TResult>[] tasks) { throw null; }
- public static System.Threading.Tasks.Task<System.Threading.Tasks.Task> WhenAny(System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task> tasks) { throw null; }
- public static System.Threading.Tasks.Task<System.Threading.Tasks.Task> WhenAny(params System.Threading.Tasks.Task[] tasks) { throw null; }
- public static System.Threading.Tasks.Task<System.Threading.Tasks.Task<TResult>> WhenAny<TResult>(System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task<TResult>> tasks) { throw null; }
- public static System.Threading.Tasks.Task<System.Threading.Tasks.Task<TResult>> WhenAny<TResult>(params System.Threading.Tasks.Task<TResult>[] tasks) { throw null; }
- public static System.Runtime.CompilerServices.YieldAwaitable Yield() { throw null; }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("Id = {Id}, Status = {Status}, Method = {DebuggerDisplayMethodDescription}, Result = {DebuggerDisplayResultDescription}")]
- public partial class Task<TResult> : System.Threading.Tasks.Task
- {
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Func<TResult> function) : base (default(System.Action)) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Func<TResult> function, System.Threading.CancellationToken cancellationToken) : base (default(System.Action)) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Func<TResult> function, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskCreationOptions creationOptions) : base (default(System.Action)) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Func<TResult> function, System.Threading.Tasks.TaskCreationOptions creationOptions) : base (default(System.Action)) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Func<object, TResult> function, object state) : base (default(System.Action)) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Func<object, TResult> function, object state, System.Threading.CancellationToken cancellationToken) : base (default(System.Action)) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Func<object, TResult> function, object state, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskCreationOptions creationOptions) : base (default(System.Action)) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public Task(System.Func<object, TResult> function, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) : base (default(System.Action)) { }
- public static new System.Threading.Tasks.TaskFactory<TResult> Factory { get { throw null; } }
- [System.Diagnostics.DebuggerBrowsableAttribute((System.Diagnostics.DebuggerBrowsableState)(0))]
- public TResult Result { get { throw null; } }
- public new System.Runtime.CompilerServices.ConfiguredTaskAwaitable<TResult> ConfigureAwait(bool continueOnCapturedContext) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task<TResult>, object> continuationAction, object state) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task<TResult>, object> continuationAction, object state, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task<TResult>, object> continuationAction, object state, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task<TResult>, object> continuationAction, object state, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task<TResult>, object> continuationAction, object state, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task<TResult>> continuationAction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task<TResult>> continuationAction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task<TResult>> continuationAction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task<TResult>> continuationAction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWith(System.Action<System.Threading.Tasks.Task<TResult>> continuationAction, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TNewResult> ContinueWith<TNewResult>(System.Func<System.Threading.Tasks.Task<TResult>, TNewResult> continuationFunction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TNewResult> ContinueWith<TNewResult>(System.Func<System.Threading.Tasks.Task<TResult>, TNewResult> continuationFunction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TNewResult> ContinueWith<TNewResult>(System.Func<System.Threading.Tasks.Task<TResult>, TNewResult> continuationFunction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TNewResult> ContinueWith<TNewResult>(System.Func<System.Threading.Tasks.Task<TResult>, TNewResult> continuationFunction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TNewResult> ContinueWith<TNewResult>(System.Func<System.Threading.Tasks.Task<TResult>, TNewResult> continuationFunction, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TNewResult> ContinueWith<TNewResult>(System.Func<System.Threading.Tasks.Task<TResult>, object, TNewResult> continuationFunction, object state) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TNewResult> ContinueWith<TNewResult>(System.Func<System.Threading.Tasks.Task<TResult>, object, TNewResult> continuationFunction, object state, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TNewResult> ContinueWith<TNewResult>(System.Func<System.Threading.Tasks.Task<TResult>, object, TNewResult> continuationFunction, object state, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TNewResult> ContinueWith<TNewResult>(System.Func<System.Threading.Tasks.Task<TResult>, object, TNewResult> continuationFunction, object state, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TNewResult> ContinueWith<TNewResult>(System.Func<System.Threading.Tasks.Task<TResult>, object, TNewResult> continuationFunction, object state, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- public new System.Runtime.CompilerServices.TaskAwaiter<TResult> GetAwaiter() { throw null; }
- }
- public partial class TaskCanceledException : System.OperationCanceledException
- {
- public TaskCanceledException() { }
- public TaskCanceledException(string message) { }
- public TaskCanceledException(string message, System.Exception innerException) { }
- public TaskCanceledException(System.Threading.Tasks.Task task) { }
- protected TaskCanceledException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- public System.Threading.Tasks.Task Task { get { throw null; } }
- }
- public partial class TaskCompletionSource<TResult>
- {
- public TaskCompletionSource() { }
- public TaskCompletionSource(object state) { }
- public TaskCompletionSource(object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { }
- public TaskCompletionSource(System.Threading.Tasks.TaskCreationOptions creationOptions) { }
- public System.Threading.Tasks.Task<TResult> Task { get { throw null; } }
- public void SetCanceled() { }
- public void SetException(System.Collections.Generic.IEnumerable<System.Exception> exceptions) { }
- public void SetException(System.Exception exception) { }
- public void SetResult(TResult result) { }
- public bool TrySetCanceled() { throw null; }
- public bool TrySetCanceled(System.Threading.CancellationToken cancellationToken) { throw null; }
- public bool TrySetException(System.Collections.Generic.IEnumerable<System.Exception> exceptions) { throw null; }
- public bool TrySetException(System.Exception exception) { throw null; }
- public bool TrySetResult(TResult result) { throw null; }
- }
- [System.FlagsAttribute]
- public enum TaskContinuationOptions
- {
- AttachedToParent = 4,
- DenyChildAttach = 8,
- ExecuteSynchronously = 524288,
- HideScheduler = 16,
- LazyCancellation = 32,
- LongRunning = 2,
- None = 0,
- NotOnCanceled = 262144,
- NotOnFaulted = 131072,
- NotOnRanToCompletion = 65536,
- OnlyOnCanceled = 196608,
- OnlyOnFaulted = 327680,
- OnlyOnRanToCompletion = 393216,
- PreferFairness = 1,
- RunContinuationsAsynchronously = 64,
- }
- [System.FlagsAttribute]
- public enum TaskCreationOptions
- {
- AttachedToParent = 4,
- DenyChildAttach = 8,
- HideScheduler = 16,
- LongRunning = 2,
- None = 0,
- PreferFairness = 1,
- RunContinuationsAsynchronously = 64,
- }
- public partial class TaskFactory
- {
- public TaskFactory() { }
- public TaskFactory(System.Threading.CancellationToken cancellationToken) { }
- public TaskFactory(System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskCreationOptions creationOptions, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { }
- public TaskFactory(System.Threading.Tasks.TaskCreationOptions creationOptions, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { }
- public TaskFactory(System.Threading.Tasks.TaskScheduler scheduler) { }
- public System.Threading.CancellationToken CancellationToken { get { throw null; } }
- public System.Threading.Tasks.TaskContinuationOptions ContinuationOptions { get { throw null; } }
- public System.Threading.Tasks.TaskCreationOptions CreationOptions { get { throw null; } }
- public System.Threading.Tasks.TaskScheduler Scheduler { get { throw null; } }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAll(System.Threading.Tasks.Task[] tasks, System.Action<System.Threading.Tasks.Task[]> continuationAction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAll(System.Threading.Tasks.Task[] tasks, System.Action<System.Threading.Tasks.Task[]> continuationAction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAll(System.Threading.Tasks.Task[] tasks, System.Action<System.Threading.Tasks.Task[]> continuationAction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAll(System.Threading.Tasks.Task[] tasks, System.Action<System.Threading.Tasks.Task[]> continuationAction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll<TResult>(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task[], TResult> continuationFunction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll<TResult>(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task[], TResult> continuationFunction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll<TResult>(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task[], TResult> continuationFunction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll<TResult>(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task[], TResult> continuationFunction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAll<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Action<System.Threading.Tasks.Task<TAntecedentResult>[]> continuationAction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAll<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Action<System.Threading.Tasks.Task<TAntecedentResult>[]> continuationAction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAll<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Action<System.Threading.Tasks.Task<TAntecedentResult>[]> continuationAction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAll<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Action<System.Threading.Tasks.Task<TAntecedentResult>[]> continuationAction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>[], TResult> continuationFunction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>[], TResult> continuationFunction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>[], TResult> continuationFunction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll<TAntecedentResult, TResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>[], TResult> continuationFunction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAny(System.Threading.Tasks.Task[] tasks, System.Action<System.Threading.Tasks.Task> continuationAction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAny(System.Threading.Tasks.Task[] tasks, System.Action<System.Threading.Tasks.Task> continuationAction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAny(System.Threading.Tasks.Task[] tasks, System.Action<System.Threading.Tasks.Task> continuationAction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAny(System.Threading.Tasks.Task[] tasks, System.Action<System.Threading.Tasks.Task> continuationAction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny<TResult>(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task, TResult> continuationFunction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny<TResult>(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task, TResult> continuationFunction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny<TResult>(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task, TResult> continuationFunction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny<TResult>(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task, TResult> continuationFunction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAny<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Action<System.Threading.Tasks.Task<TAntecedentResult>> continuationAction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAny<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Action<System.Threading.Tasks.Task<TAntecedentResult>> continuationAction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAny<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Action<System.Threading.Tasks.Task<TAntecedentResult>> continuationAction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task ContinueWhenAny<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Action<System.Threading.Tasks.Task<TAntecedentResult>> continuationAction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>, TResult> continuationFunction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>, TResult> continuationFunction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>, TResult> continuationFunction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny<TAntecedentResult, TResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>, TResult> continuationFunction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- public System.Threading.Tasks.Task FromAsync(System.Func<System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Action<System.IAsyncResult> endMethod, object state) { throw null; }
- public System.Threading.Tasks.Task FromAsync(System.Func<System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Action<System.IAsyncResult> endMethod, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task FromAsync(System.IAsyncResult asyncResult, System.Action<System.IAsyncResult> endMethod) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task FromAsync(System.IAsyncResult asyncResult, System.Action<System.IAsyncResult> endMethod, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task FromAsync(System.IAsyncResult asyncResult, System.Action<System.IAsyncResult> endMethod, System.Threading.Tasks.TaskCreationOptions creationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- public System.Threading.Tasks.Task FromAsync<TArg1>(System.Func<TArg1, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Action<System.IAsyncResult> endMethod, TArg1 arg1, object state) { throw null; }
- public System.Threading.Tasks.Task FromAsync<TArg1>(System.Func<TArg1, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Action<System.IAsyncResult> endMethod, TArg1 arg1, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync<TResult>(System.Func<System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, object state) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync<TResult>(System.Func<System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> FromAsync<TResult>(System.IAsyncResult asyncResult, System.Func<System.IAsyncResult, TResult> endMethod) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> FromAsync<TResult>(System.IAsyncResult asyncResult, System.Func<System.IAsyncResult, TResult> endMethod, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> FromAsync<TResult>(System.IAsyncResult asyncResult, System.Func<System.IAsyncResult, TResult> endMethod, System.Threading.Tasks.TaskCreationOptions creationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- public System.Threading.Tasks.Task FromAsync<TArg1, TArg2>(System.Func<TArg1, TArg2, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Action<System.IAsyncResult> endMethod, TArg1 arg1, TArg2 arg2, object state) { throw null; }
- public System.Threading.Tasks.Task FromAsync<TArg1, TArg2>(System.Func<TArg1, TArg2, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Action<System.IAsyncResult> endMethod, TArg1 arg1, TArg2 arg2, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync<TArg1, TResult>(System.Func<TArg1, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, TArg1 arg1, object state) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync<TArg1, TResult>(System.Func<TArg1, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, TArg1 arg1, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- public System.Threading.Tasks.Task FromAsync<TArg1, TArg2, TArg3>(System.Func<TArg1, TArg2, TArg3, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Action<System.IAsyncResult> endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, object state) { throw null; }
- public System.Threading.Tasks.Task FromAsync<TArg1, TArg2, TArg3>(System.Func<TArg1, TArg2, TArg3, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Action<System.IAsyncResult> endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync<TArg1, TArg2, TResult>(System.Func<TArg1, TArg2, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, object state) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync<TArg1, TArg2, TResult>(System.Func<TArg1, TArg2, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync<TArg1, TArg2, TArg3, TResult>(System.Func<TArg1, TArg2, TArg3, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, object state) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync<TArg1, TArg2, TArg3, TResult>(System.Func<TArg1, TArg2, TArg3, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task StartNew(System.Action action) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task StartNew(System.Action action, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task StartNew(System.Action action, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskCreationOptions creationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task StartNew(System.Action action, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task StartNew(System.Action<object> action, object state) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task StartNew(System.Action<object> action, object state, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task StartNew(System.Action<object> action, object state, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskCreationOptions creationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task StartNew(System.Action<object> action, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew<TResult>(System.Func<TResult> function) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew<TResult>(System.Func<TResult> function, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew<TResult>(System.Func<TResult> function, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskCreationOptions creationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew<TResult>(System.Func<TResult> function, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew<TResult>(System.Func<object, TResult> function, object state) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew<TResult>(System.Func<object, TResult> function, object state, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew<TResult>(System.Func<object, TResult> function, object state, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskCreationOptions creationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew<TResult>(System.Func<object, TResult> function, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- }
- public partial class TaskFactory<TResult>
- {
- public TaskFactory() { }
- public TaskFactory(System.Threading.CancellationToken cancellationToken) { }
- public TaskFactory(System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskCreationOptions creationOptions, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { }
- public TaskFactory(System.Threading.Tasks.TaskCreationOptions creationOptions, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { }
- public TaskFactory(System.Threading.Tasks.TaskScheduler scheduler) { }
- public System.Threading.CancellationToken CancellationToken { get { throw null; } }
- public System.Threading.Tasks.TaskContinuationOptions ContinuationOptions { get { throw null; } }
- public System.Threading.Tasks.TaskCreationOptions CreationOptions { get { throw null; } }
- public System.Threading.Tasks.TaskScheduler Scheduler { get { throw null; } }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task[], TResult> continuationFunction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task[], TResult> continuationFunction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task[], TResult> continuationFunction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task[], TResult> continuationFunction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>[], TResult> continuationFunction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>[], TResult> continuationFunction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>[], TResult> continuationFunction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAll<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>[], TResult> continuationFunction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task, TResult> continuationFunction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task, TResult> continuationFunction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task, TResult> continuationFunction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny(System.Threading.Tasks.Task[] tasks, System.Func<System.Threading.Tasks.Task, TResult> continuationFunction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>, TResult> continuationFunction) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>, TResult> continuationFunction, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>, TResult> continuationFunction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> ContinueWhenAny<TAntecedentResult>(System.Threading.Tasks.Task<TAntecedentResult>[] tasks, System.Func<System.Threading.Tasks.Task<TAntecedentResult>, TResult> continuationFunction, System.Threading.Tasks.TaskContinuationOptions continuationOptions) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync(System.Func<System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, object state) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync(System.Func<System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> FromAsync(System.IAsyncResult asyncResult, System.Func<System.IAsyncResult, TResult> endMethod) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> FromAsync(System.IAsyncResult asyncResult, System.Func<System.IAsyncResult, TResult> endMethod, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> FromAsync(System.IAsyncResult asyncResult, System.Func<System.IAsyncResult, TResult> endMethod, System.Threading.Tasks.TaskCreationOptions creationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync<TArg1>(System.Func<TArg1, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, TArg1 arg1, object state) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync<TArg1>(System.Func<TArg1, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, TArg1 arg1, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync<TArg1, TArg2>(System.Func<TArg1, TArg2, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, object state) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync<TArg1, TArg2>(System.Func<TArg1, TArg2, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync<TArg1, TArg2, TArg3>(System.Func<TArg1, TArg2, TArg3, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, object state) { throw null; }
- public System.Threading.Tasks.Task<TResult> FromAsync<TArg1, TArg2, TArg3>(System.Func<TArg1, TArg2, TArg3, System.AsyncCallback, object, System.IAsyncResult> beginMethod, System.Func<System.IAsyncResult, TResult> endMethod, TArg1 arg1, TArg2 arg2, TArg3 arg3, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew(System.Func<TResult> function) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew(System.Func<TResult> function, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew(System.Func<TResult> function, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskCreationOptions creationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew(System.Func<TResult> function, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew(System.Func<object, TResult> function, object state) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew(System.Func<object, TResult> function, object state, System.Threading.CancellationToken cancellationToken) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew(System.Func<object, TResult> function, object state, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskCreationOptions creationOptions, System.Threading.Tasks.TaskScheduler scheduler) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]public System.Threading.Tasks.Task<TResult> StartNew(System.Func<object, TResult> function, object state, System.Threading.Tasks.TaskCreationOptions creationOptions) { throw null; }
- }
- [System.Diagnostics.DebuggerDisplayAttribute("Id={Id}")]
- public abstract partial class TaskScheduler
- {
- protected TaskScheduler() { }
- public static System.Threading.Tasks.TaskScheduler Current { get { throw null; } }
- public static System.Threading.Tasks.TaskScheduler Default { get { throw null; } }
- public int Id { get { throw null; } }
- public virtual int MaximumConcurrencyLevel { get { throw null; } }
- public static event System.EventHandler<System.Threading.Tasks.UnobservedTaskExceptionEventArgs> UnobservedTaskException { add { } remove { } }
- public static System.Threading.Tasks.TaskScheduler FromCurrentSynchronizationContext() { throw null; }
- [System.Security.SecurityCriticalAttribute]
- protected abstract System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task> GetScheduledTasks();
- [System.Security.SecurityCriticalAttribute]
- protected internal abstract void QueueTask(System.Threading.Tasks.Task task);
- [System.Security.SecurityCriticalAttribute]
- protected internal virtual bool TryDequeue(System.Threading.Tasks.Task task) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- protected bool TryExecuteTask(System.Threading.Tasks.Task task) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- protected abstract bool TryExecuteTaskInline(System.Threading.Tasks.Task task, bool taskWasPreviouslyQueued);
- }
- public partial class TaskSchedulerException : System.Exception
- {
- public TaskSchedulerException() { }
- public TaskSchedulerException(System.Exception innerException) { }
- public TaskSchedulerException(string message) { }
- public TaskSchedulerException(string message, System.Exception innerException) { }
- protected TaskSchedulerException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
- }
- public enum TaskStatus
- {
- Canceled = 6,
- Created = 0,
- Faulted = 7,
- RanToCompletion = 5,
- Running = 3,
- WaitingForActivation = 1,
- WaitingForChildrenToComplete = 4,
- WaitingToRun = 2,
- }
- public partial class UnobservedTaskExceptionEventArgs : System.EventArgs
- {
- public UnobservedTaskExceptionEventArgs(System.AggregateException exception) { }
- public System.AggregateException Exception { get { throw null; } }
- public bool Observed { get { throw null; } }
- public void SetObserved() { }
- }
-}
diff --git a/src/mscorlib/ref/mscorlib.csproj b/src/mscorlib/ref/mscorlib.csproj
deleted file mode 100644
index 30da2de8f3..0000000000
--- a/src/mscorlib/ref/mscorlib.csproj
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-
- <!-- Include common build properties -->
- <Import Project="..\..\..\dir.props" />
-
- <!-- Compilation options -->
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">$(BuildType)</Configuration>
- <PlatformTarget>AnyCPU</PlatformTarget>
-
- <ProjectGuid>{B8ADD332-40B6-4916-B418-FBB79E5898B3}</ProjectGuid>
-
- <OutputType>Library</OutputType>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-
- <!-- This prevents the default MsBuild targets from referencing System.Core.dll -->
- <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
- <!-- These prevent the default MsBuild targets from referencing System.dll and mscorlib.dll -->
- <NoStdLib>true</NoStdLib>
- <NoCompilerStandardLib>true</NoCompilerStandardLib>
-
- <ErrorReport>prompt</ErrorReport>
- <Optimize Condition="'$(Optimize)' == ''">true</Optimize>
- <CLSCompliant>true</CLSCompliant>
- <WarningLevel>4</WarningLevel>
- <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
- <WarningsNotAsErrors>$(WarningsNotAsErrors);618</WarningsNotAsErrors>
- <NoWarn>618,649,3019,414,169,3015,3021</NoWarn>
- <GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
-
- <SignAssembly>true</SignAssembly>
- <DelaySign>true</DelaySign>
- </PropertyGroup>
-
- <!-- On Windows we support FEATURE_COMINTEROP and FEATURE_COREFX_GLOBALIZATION -->
- <PropertyGroup Condition="'$(TargetsUnix)'!='true'">
- <DefineConstants>$(DefineConstants);FEATURE_COREFX_GLOBALIZATION;FEATURE_COMINTEROP</DefineConstants>
- </PropertyGroup>
-
- <!-- Roslyn does not support writing PDBs on Unix -->
- <PropertyGroup Condition="'$(OsEnvironment)' == 'Unix'">
- <DebugSymbols>false</DebugSymbols>
- <DebugType>none</DebugType>
- </PropertyGroup>
-
- <!-- Assembly attributes -->
- <PropertyGroup>
- <AssemblyName>mscorlib</AssemblyName>
- <AssemblyVersion>4.0.0.0</AssemblyVersion>
- <MajorVersion>4</MajorVersion>
- <MinorVersion>6</MinorVersion>
- </PropertyGroup>
-
- <!-- Output paths -->
- <PropertyGroup>
- <BaseIntermediateOutputPath>$(RootBinDir)\obj</BaseIntermediateOutputPath>
- <IntermediateOutputPath>$(BaseIntermediateOutputPath)\$(BuildOS).$(BuildArch).$(Configuration)\ref</IntermediateOutputPath>
- <OutputPath>$(BinDir)\ref</OutputPath>
- </PropertyGroup>
-
- <ItemGroup>
- <Compile Include="$(MSBuildThisFileDirectory)\mscorlib.cs" />
- <Compile Include="$(MSBuildThisFileDirectory)\mscorlib.manual.cs" />
- </ItemGroup>
-
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.Targets" />
-
- <PropertyGroup>
- <StrongNameSig>Silverlight</StrongNameSig>
- </PropertyGroup>
-
- <!-- Import signing tools -->
- <Import Condition="Exists('$(ToolsDir)\sign.targets')" Project="$(ToolsDir)\sign.targets" />
-
- <!-- Overwrite the key that we are going to use for signing -->
- <PropertyGroup>
- <AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)..\Tools\Signing\mscorlib.snk</AssemblyOriginatorKeyFile>
- </PropertyGroup>
-
- <Import Project="$(MSBuildThisFileDirectory)..\Tools\Versioning\GenerateVersionInfo.targets"/>
- <!-- Override versioning targets -->
- <Import Condition="Exists('$(ToolsDir)versioning.targets')" Project="$(ToolsDir)versioning.targets" />
- <Import Project="..\GenerateCompilerResponseFile.targets"/>
-</Project>
diff --git a/src/mscorlib/ref/mscorlib.manual.cs b/src/mscorlib/ref/mscorlib.manual.cs
deleted file mode 100644
index d7c1f5e274..0000000000
--- a/src/mscorlib/ref/mscorlib.manual.cs
+++ /dev/null
@@ -1,785 +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.
-
-[assembly:System.Runtime.CompilerServices.InternalsVisibleTo("System.Runtime.WindowsRuntime, PublicKey=00000000000000000400000000000000")]
-
-namespace System
-{
- partial class Exception
- {
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal void AddExceptionDataForRestrictedErrorInfo(string restrictedError, string restrictedErrorReference, string restrictedCapabilitySid, object restrictedErrorObject, bool hasrestrictedLanguageErrorObject = false) { }
- }
-}
-
-namespace System.Diagnostics.Tracing
-{
- [System.Diagnostics.Tracing.EventSourceAttribute(Guid = "8E9F5090-2D75-4d03-8A81-E5AFBF85DAF1", Name = "System.Diagnostics.Eventing.FrameworkEventSource")]
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal sealed partial class FrameworkEventSource : System.Diagnostics.Tracing.EventSource
- {
- internal static readonly System.Diagnostics.Tracing.FrameworkEventSource Log;
- private FrameworkEventSource() { }
- internal static bool IsInitialized { get { throw null; } }
- [System.Diagnostics.Tracing.EventAttribute(31, Level = (System.Diagnostics.Tracing.EventLevel)(5), Keywords = (System.Diagnostics.Tracing.EventKeywords)(18))]
- internal void ThreadPoolDequeueWork(long workID) { }
- [System.Diagnostics.Tracing.NonEventAttribute]
- [System.Security.SecuritySafeCriticalAttribute]
- internal void ThreadPoolDequeueWorkObject(object workID) { }
- [System.Diagnostics.Tracing.EventAttribute(30, Level = (System.Diagnostics.Tracing.EventLevel)(5), Keywords = (System.Diagnostics.Tracing.EventKeywords)(18))]
- internal void ThreadPoolEnqueueWork(long workID) { }
- [System.Diagnostics.Tracing.NonEventAttribute]
- [System.Security.SecuritySafeCriticalAttribute]
- internal void ThreadPoolEnqueueWorkObject(object workID) { }
- [System.Diagnostics.Tracing.EventAttribute(151, Level = (System.Diagnostics.Tracing.EventLevel)(4), Keywords = (System.Diagnostics.Tracing.EventKeywords)(16), Task = (System.Diagnostics.Tracing.EventTask)(3), Opcode = (System.Diagnostics.Tracing.EventOpcode)(240))]
- internal void ThreadTransferReceive(long id, int kind, string info) { }
- [System.Diagnostics.Tracing.NonEventAttribute]
- [System.Security.SecuritySafeCriticalAttribute]
- internal void ThreadTransferReceiveObj(object id, int kind, string info) { }
- [System.Diagnostics.Tracing.EventAttribute(150, Level = (System.Diagnostics.Tracing.EventLevel)(4), Keywords = (System.Diagnostics.Tracing.EventKeywords)(16), Task = (System.Diagnostics.Tracing.EventTask)(3), Opcode = (System.Diagnostics.Tracing.EventOpcode)(9))]
- internal void ThreadTransferSend(long id, int kind, string info, bool multiDequeues) { }
- [System.Diagnostics.Tracing.NonEventAttribute]
- [System.Security.SecuritySafeCriticalAttribute]
- internal void ThreadTransferSendObj(object id, int kind, string info, bool multiDequeues) { }
- [System.Diagnostics.Tracing.NonEventAttribute]
- [System.Security.SecuritySafeCriticalAttribute]
- private void WriteEvent(int eventId, long arg1, int arg2, string arg3) { }
- [System.Diagnostics.Tracing.NonEventAttribute]
- [System.Security.SecuritySafeCriticalAttribute]
- private void WriteEvent(int eventId, long arg1, int arg2, string arg3, bool arg4) { }
- public static partial class Keywords
- {
- public const System.Diagnostics.Tracing.EventKeywords DynamicTypeUsage = (System.Diagnostics.Tracing.EventKeywords)8;
- public const System.Diagnostics.Tracing.EventKeywords Loader = (System.Diagnostics.Tracing.EventKeywords)1;
- public const System.Diagnostics.Tracing.EventKeywords NetClient = (System.Diagnostics.Tracing.EventKeywords)4;
- public const System.Diagnostics.Tracing.EventKeywords ThreadPool = (System.Diagnostics.Tracing.EventKeywords)2;
- public const System.Diagnostics.Tracing.EventKeywords ThreadTransfer = (System.Diagnostics.Tracing.EventKeywords)16;
- }
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- public static partial class Opcodes
- {
- public const System.Diagnostics.Tracing.EventOpcode ReceiveHandled = (System.Diagnostics.Tracing.EventOpcode)11;
- }
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- public static partial class Tasks
- {
- public const System.Diagnostics.Tracing.EventTask GetRequestStream = (System.Diagnostics.Tracing.EventTask) 2;
- public const System.Diagnostics.Tracing.EventTask GetResponse = (System.Diagnostics.Tracing.EventTask)1;
- public const System.Diagnostics.Tracing.EventTask ThreadTransfer = (System.Diagnostics.Tracing.EventTask)3;
- }
- }
-}
-
-namespace System.Globalization
-{
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal partial class CultureData
- {
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal static System.Globalization.CultureData GetCultureData(string cultureName, bool useUserOverride) { throw null; }
- }
-
- [System.FlagsAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- public enum CultureTypes
- {
- AllCultures = 7,
- [System.ObsoleteAttribute("This value has been deprecated. Please use other values in CultureTypes.")]
- FrameworkCultures = 64,
- InstalledWin32Cultures = 4,
- NeutralCultures = 1,
- ReplacementCultures = 16,
- SpecificCultures = 2,
- UserCustomCulture = 8,
- [System.ObsoleteAttribute("This value has been deprecated. Please use other values in CultureTypes.")]
- WindowsOnlyCultures = 32,
- }
-}
-
-namespace System.IO
-{
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- [System.Runtime.InteropServices.ComVisibleAttribute(true)]
- internal sealed partial class BufferedStream : System.IO.Stream
- {
- private byte[] _buffer;
- private readonly int _bufferSize;
- private const int _DefaultBufferSize = 4096;
- private System.Threading.Tasks.Task<int> _lastSyncCompletedReadTask;
- private int _readLen;
- private int _readPos;
- private System.IO.Stream _stream;
- private int _writePos;
- private const int MaxShadowBufferSize = 81920;
- private BufferedStream() { }
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal BufferedStream(System.IO.Stream stream, int bufferSize) { }
- internal int BufferSize { [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]get { throw null; } }
- public override bool CanRead { get { throw null; } }
- public override bool CanSeek { get { throw null; } }
- public override bool CanWrite { get { throw null; } }
- public override long Length { get { throw null; } }
- public override long Position { get { throw null; } set { } }
- internal System.IO.Stream UnderlyingStream { [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]get { throw null; } }
- public override System.IAsyncResult BeginRead(byte[] buffer, int offset, int count, System.AsyncCallback callback, object state) { throw null; }
- private System.IAsyncResult BeginReadFromUnderlyingStream(byte[] buffer, int offset, int count, System.AsyncCallback callback, object state, int bytesAlreadySatisfied, System.Threading.Tasks.Task semaphoreLockTask) { throw null; }
- public override System.IAsyncResult BeginWrite(byte[] buffer, int offset, int count, System.AsyncCallback callback, object state) { throw null; }
- private System.IAsyncResult BeginWriteToUnderlyingStream(byte[] buffer, int offset, int count, System.AsyncCallback callback, object state, System.Threading.Tasks.Task semaphoreLockTask) { throw null; }
- private void ClearReadBufferBeforeWrite() { }
- protected override void Dispose(bool disposing) { }
- public override int EndRead(System.IAsyncResult asyncResult) { throw null; }
- public override void EndWrite(System.IAsyncResult asyncResult) { }
- private void EnsureBeginEndAwaitableAllocated() { }
- private void EnsureBufferAllocated() { }
- private void EnsureCanRead() { }
- private void EnsureCanSeek() { }
- private void EnsureCanWrite() { }
- private void EnsureNotClosed() { }
- private void EnsureShadowBufferAllocated() { }
- public override void Flush() { }
- public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
- private static System.Threading.Tasks.Task FlushAsyncInternal(System.Threading.CancellationToken cancellationToken, System.IO.BufferedStream _this, System.IO.Stream stream, int writePos, int readPos, int readLen) { throw null; }
- private void FlushRead() { }
- private void FlushWrite() { }
- private System.Threading.Tasks.Task FlushWriteAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
- private System.Threading.Tasks.Task<int> LastSyncCompletedReadTask(int val) { throw null; }
- public override int Read(byte[] array, int offset, int count) { array = default(byte[]); throw null; }
- public override System.Threading.Tasks.Task<int> ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
- public override int ReadByte() { throw null; }
- private int ReadFromBuffer(byte[] array, int offset, int count) { throw null; }
- private int ReadFromBuffer(byte[] array, int offset, int count, out System.Exception error) { error = default(System.Exception); throw null; }
- private System.Threading.Tasks.Task<int> ReadFromUnderlyingStreamAsync(byte[] array, int offset, int count, System.Threading.CancellationToken cancellationToken, int bytesAlreadySatisfied, System.Threading.Tasks.Task semaphoreLockTask, bool useApmPattern) { throw null; }
- public override long Seek(long offset, System.IO.SeekOrigin origin) { throw null; }
- public override void SetLength(long value) { }
- public override void Write(byte[] array, int offset, int count) { }
- public override System.Threading.Tasks.Task WriteAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; }
- public override void WriteByte(byte value) { }
- private void WriteToBuffer(byte[] array, ref int offset, ref int count) { }
- private void WriteToBuffer(byte[] array, ref int offset, ref int count, out System.Exception error) { error = default(System.Exception); }
- private System.Threading.Tasks.Task WriteToUnderlyingStreamAsync(byte[] array, int offset, int count, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.Task semaphoreLockTask, bool useApmPattern) { throw null; }
- }
-}
-
-namespace System.Resources
-{
- [System.Security.SecurityCriticalAttribute]
- internal partial class WindowsRuntimeResourceManagerBase
- {
- public WindowsRuntimeResourceManagerBase() { }
- public virtual System.Globalization.CultureInfo GlobalResourceContextBestFitCultureInfo { [System.Security.SecurityCriticalAttribute]get { throw null; } }
- [System.Security.SecurityCriticalAttribute]
- public virtual string GetString(string stringName, string startingCulture, string neutralResourcesCulture) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public virtual bool Initialize(string libpath, string reswFilename, out System.Resources.PRIExceptionInfo exceptionInfo) { exceptionInfo = default(System.Resources.PRIExceptionInfo); throw null; }
- [System.Security.SecurityCriticalAttribute]
- public virtual bool SetGlobalResourceContextDefaultCulture(System.Globalization.CultureInfo ci) { throw null; }
- }
-
- internal partial class PRIExceptionInfo
- {
- [System.CLSCompliantAttribute(false)]
- public string _PackageSimpleName;
- [System.CLSCompliantAttribute(false)]
- public string _ResWFile;
- public PRIExceptionInfo() { }
- }
-}
-
-namespace System.Runtime.CompilerServices
-{
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal static partial class JitHelpers
- {
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- [System.Security.SecurityCriticalAttribute]
- internal static T UnsafeCast<T>(object o) where T : class { throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(2044), AllowMultiple = false, Inherited = false)]
- internal sealed partial class FriendAccessAllowedAttribute : System.Attribute
- {
- public FriendAccessAllowedAttribute() { }
- }
- partial class ConditionalWeakTable<TKey, TValue>
- {
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- [System.Security.SecuritySafeCriticalAttribute]
- internal TKey FindEquivalentKeyUnsafe(TKey key, out TValue value) { value = default(TValue); throw null; }
- }
-}
-
-namespace System.Runtime.InteropServices.WindowsRuntime
-{
- [System.AttributeUsageAttribute((System.AttributeTargets)(5148), Inherited = false)]
- internal sealed partial class WindowsRuntimeImportAttribute : System.Attribute
- {
- internal WindowsRuntimeImportAttribute() { }
- }
-
- [System.Runtime.InteropServices.GuidAttribute("82BA7092-4C88-427D-A7BC-16DD93FEB67E")]
- [System.Runtime.InteropServices.InterfaceTypeAttribute((System.Runtime.InteropServices.ComInterfaceType)(1))]
- internal partial interface IRestrictedErrorInfo
- {
- void GetErrorDetails(out string description, out int error, out string restrictedDescription, out string capabilitySid);
- void GetReference(out string reference);
- }
-
-#if FEATURE_COMINTEROP
- [System.AttributeUsageAttribute((System.AttributeTargets)(1028), AllowMultiple=false, Inherited=false)]
- public sealed partial class DefaultInterfaceAttribute : System.Attribute
- {
- public DefaultInterfaceAttribute(System.Type defaultInterface) { }
- public System.Type DefaultInterface { get { throw null; } }
- }
- [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
- public partial struct EventRegistrationToken
- {
- public override bool Equals(object obj) { throw null; }
- public override int GetHashCode() { throw null; }
- public static bool operator ==(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken left, System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken right) { throw null; }
- public static bool operator !=(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken left, System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken right) { throw null; }
- }
- public sealed partial class EventRegistrationTokenTable<T> where T : class
- {
- public EventRegistrationTokenTable() { }
- public T InvocationList { get { throw null; } set { } }
- public System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken AddEventHandler(T handler) { throw null; }
- public static System.Runtime.InteropServices.WindowsRuntime.EventRegistrationTokenTable<T> GetOrCreateEventRegistrationTokenTable(ref System.Runtime.InteropServices.WindowsRuntime.EventRegistrationTokenTable<T> refEventTable) { throw null; }
- public void RemoveEventHandler(T handler) { }
- public void RemoveEventHandler(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken token) { }
-
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal T ExtractHandler(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken token) { throw null; }
- }
- [System.Runtime.InteropServices.GuidAttribute("00000035-0000-0000-C000-000000000046")]
- public partial interface IActivationFactory
- {
- object ActivateInstance();
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(1028), Inherited=false, AllowMultiple=true)]
- public sealed partial class InterfaceImplementedInVersionAttribute : System.Attribute
- {
- public InterfaceImplementedInVersionAttribute(System.Type interfaceType, byte majorVersion, byte minorVersion, byte buildVersion, byte revisionVersion) { }
- public byte BuildVersion { get { throw null; } }
- public System.Type InterfaceType { get { throw null; } }
- public byte MajorVersion { get { throw null; } }
- public byte MinorVersion { get { throw null; } }
- public byte RevisionVersion { get { throw null; } }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(2048), Inherited=false, AllowMultiple=false)]
- public sealed partial class ReadOnlyArrayAttribute : System.Attribute
- {
- public ReadOnlyArrayAttribute() { }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(12288), AllowMultiple=false, Inherited=false)]
- public sealed partial class ReturnValueNameAttribute : System.Attribute
- {
- public ReturnValueNameAttribute(string name) { }
- public string Name { get { throw null; } }
- }
- public static partial class WindowsRuntimeMarshal
- {
- [System.Security.SecurityCriticalAttribute]
- public static void AddEventHandler<T>(System.Func<T, System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken> addMethod, System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken> removeMethod, T handler) { }
- [System.Security.SecurityCriticalAttribute]
- public static void FreeHString(System.IntPtr ptr) { }
- [System.Security.SecurityCriticalAttribute]
- public static System.Runtime.InteropServices.WindowsRuntime.IActivationFactory GetActivationFactory(System.Type type) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static string PtrToStringHString(System.IntPtr ptr) { throw null; }
- [System.Security.SecurityCriticalAttribute]
- public static void RemoveAllEventHandlers(System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken> removeMethod) { }
- [System.Security.SecurityCriticalAttribute]
- public static void RemoveEventHandler<T>(System.Action<System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken> removeMethod, T handler) { }
- [System.Security.SecurityCriticalAttribute]
- public static System.IntPtr StringToHString(string s) { throw null; }
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- [System.Security.SecuritySafeCriticalAttribute]
- internal static bool ReportUnhandledError(System.Exception e) { throw null; }
- }
- [System.AttributeUsageAttribute((System.AttributeTargets)(2048), Inherited=false, AllowMultiple=false)]
- public sealed partial class WriteOnlyArrayAttribute : System.Attribute
- {
- public WriteOnlyArrayAttribute() { }
- }
-#endif //FEATURE_COMINTEROP
-}
-
-namespace System.StubHelpers
-{
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal static partial class EventArgsMarshaler
- {
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- [System.Security.SecurityCriticalAttribute]
- internal static System.IntPtr CreateNativeNCCEventArgsInstance(int action, object newItems, object oldItems, int newIndex, int oldIndex) { throw null; }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.PreserveSig)]
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- [System.Security.SecurityCriticalAttribute]
- internal static System.IntPtr CreateNativePCEventArgsInstance(string name) { throw null; }
- }
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal static partial class InterfaceMarshaler
- {
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal static object ConvertToManagedWithoutUnboxing(System.IntPtr pNative) { throw null; }
- }
-}
-
-namespace System.Threading
-{
- internal enum StackCrawlMark
- {
- LookForMe = 0,
- LookForMyCaller = 1,
- LookForMyCallersCaller = 2,
- LookForThread = 3,
- }
- [System.Security.SecurityCriticalAttribute]
- internal partial class WinRTSynchronizationContextFactoryBase
- {
- public WinRTSynchronizationContextFactoryBase() { }
- [System.Security.SecurityCriticalAttribute]
- public virtual System.Threading.SynchronizationContext Create(object coreDispatcher) { throw null; }
- }
- partial struct CancellationTokenRegistration
- {
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal bool TryDeregister() { throw null; }
- }
- partial class ExecutionContext
- {
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- [System.Security.SecurityCriticalAttribute]
- internal static void Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) { }
- internal static System.Threading.ExecutionContext FastCapture() { return default(System.Threading.ExecutionContext); }
- }
-}
-
-namespace System.Threading.Tasks
-{
-#if FEATURE_COMINTEROP
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal enum AsyncCausalityStatus
- {
- Canceled = 2,
- Completed = 1,
- Error = 3,
- Started = 0,
- }
- internal enum CausalityRelation
- {
- AssignDelegate = 0,
- Cancel = 3,
- Choice = 2,
- Error = 4,
- Join = 1,
- }
- internal enum CausalitySynchronousWork
- {
- CompletionNotification = 0,
- Execution = 2,
- ProgressNotification = 1,
- }
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal static partial class AsyncCausalityTracer
- {
- private static System.Threading.Tasks.AsyncCausalityTracer.Loggers f_LoggingOn;
- //private const Windows.Foundation.Diagnostics.CausalitySource s_CausalitySource = 1;
- private static readonly System.Guid s_PlatformId;
- private static Windows.Foundation.Diagnostics.IAsyncCausalityTracerStatics s_TracerFactory;
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal static bool LoggingOn { [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]get { throw null; } }
- internal static void EnableToETW(bool enabled) { }
- private static ulong GetOperationId(uint taskId) { throw null; }
- private static void LogAndDisable(System.Exception ex) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal static void TraceOperationCompletion(System.Threading.Tasks.CausalityTraceLevel traceLevel, int taskId, System.Threading.Tasks.AsyncCausalityStatus status) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal static void TraceOperationCreation(System.Threading.Tasks.CausalityTraceLevel traceLevel, int taskId, string operationName, ulong relatedContext) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- internal static void TraceOperationRelation(System.Threading.Tasks.CausalityTraceLevel traceLevel, int taskId, System.Threading.Tasks.CausalityRelation relation) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- internal static void TraceSynchronousWorkCompletion(System.Threading.Tasks.CausalityTraceLevel traceLevel, System.Threading.Tasks.CausalitySynchronousWork work) { }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- internal static void TraceSynchronousWorkStart(System.Threading.Tasks.CausalityTraceLevel traceLevel, int taskId, System.Threading.Tasks.CausalitySynchronousWork work) { }
- [System.Security.SecuritySafeCriticalAttribute]
- private static void TracingStatusChangedHandler(object sender, Windows.Foundation.Diagnostics.TracingStatusChangedEventArgs args) { }
- [System.FlagsAttribute]
- private enum Loggers : byte
- {
- CausalityTracer = (byte)1,
- ETW = (byte)2,
- }
- }
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal enum CausalityTraceLevel
- {
- Important = 1,
- Required = 0,
- Verbose = 2,
- }
-#endif
-
- partial class Task
- {
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal static bool s_asyncDebuggingEnabled;
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal static bool AddToActiveTasks(System.Threading.Tasks.Task task) { throw null; }
- [System.Runtime.CompilerServices.FriendAccessAllowedAttribute]
- internal static void RemoveFromActiveTasks(int taskId) { }
- }
-}
-
-namespace System.Security.Cryptography
-{
- public abstract class HashAlgorithm : System.IDisposable, System.Security.Cryptography.ICryptoTransform
- {
- protected internal byte[] HashValue;
- protected int HashSizeValue;
- protected int State;
- protected HashAlgorithm() { }
- public virtual bool CanReuseTransform { get { throw null; } }
- public virtual bool CanTransformMultipleBlocks { get { throw null; } }
- public virtual byte[] Hash { get { throw null; } }
- public virtual int HashSize { get { throw null; } }
- public virtual int InputBlockSize { get { throw null; } }
- public virtual int OutputBlockSize { get { throw null; } }
- public void Clear() { }
- public byte[] ComputeHash(byte[] buffer) { throw null; }
- public byte[] ComputeHash(byte[] buffer, int offset, int count) { throw null; }
- public byte[] ComputeHash(System.IO.Stream inputStream) { throw null; }
- public static HashAlgorithm Create() { throw null; }
- public static HashAlgorithm Create(string hashName) { throw null; }
- public void Dispose() { }
- protected virtual void Dispose(bool disposing) { }
- protected abstract void HashCore(byte[] array, int ibStart, int cbSize);
- protected abstract byte[] HashFinal();
- public abstract void Initialize();
- public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { throw null; }
- public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) { throw null; }
- }
-
- public abstract class SymmetricAlgorithm : System.IDisposable
- {
- protected byte[] IVValue;
- protected byte[] KeyValue;
- protected int BlockSizeValue;
- protected int FeedbackSizeValue;
- protected int KeySizeValue;
- protected CipherMode ModeValue;
- protected KeySizes[] LegalBlockSizesValue;
- protected KeySizes[] LegalKeySizesValue;
- protected PaddingMode PaddingValue;
- protected SymmetricAlgorithm() { }
- public virtual int BlockSize { get; set; }
- public virtual int FeedbackSize { get; set; }
- public virtual byte[] IV { get; set; }
- public virtual byte[] Key { get; set; }
- public virtual int KeySize { get; set; }
- public virtual KeySizes[] LegalBlockSizes { get; }
- public virtual KeySizes[] LegalKeySizes { get; }
- public virtual CipherMode Mode { get; set; }
- public virtual PaddingMode Padding { get; set; }
- public void Clear() { }
- public static SymmetricAlgorithm Create() { throw null; }
- public static SymmetricAlgorithm Create(string algName) { throw null; }
- public virtual ICryptoTransform CreateDecryptor() { throw null; }
- public abstract ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV);
- public virtual ICryptoTransform CreateEncryptor() { throw null; }
- public abstract ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV);
- public void Dispose() { }
- protected virtual void Dispose(bool disposing) { }
- public abstract void GenerateIV();
- public abstract void GenerateKey();
- public bool ValidKeySize(int bitLength) { throw null; }
- }
-
- public interface ICryptoTransform : System.IDisposable
- {
- int InputBlockSize { get; }
- int OutputBlockSize { get; }
- bool CanTransformMultipleBlocks { get; }
- bool CanReuseTransform { get; }
- int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset);
- byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount);
- }
-
- public sealed class KeySizes
- {
- public KeySizes(int minSize, int maxSize, int skipSize) { }
- public int MaxSize { get; }
- public int MinSize { get; }
- public int SkipSize { get; }
- }
-
- public enum PaddingMode
- {
- ANSIX923 = 4,
- ISO10126 = 5,
- None = 1,
- PKCS7 = 2,
- Zeros = 3,
- }
-
- public enum CipherMode
- {
- CBC = 1,
- CFB = 4,
- CTS = 5,
- ECB = 2,
- OFB = 3,
- }
-}
-
-#if FEATURE_COMINTEROP
-namespace Windows.Foundation.Diagnostics
-{
- internal enum AsyncCausalityStatus
- {
- Canceled = 2,
- Completed = 1,
- Error = 3,
- Started = 0,
- }
- internal enum CausalityRelation
- {
- AssignDelegate = 0,
- Cancel = 3,
- Choice = 2,
- Error = 4,
- Join = 1,
- }
- internal enum CausalitySource
- {
- Application = 0,
- Library = 1,
- System = 2,
- }
- internal enum CausalitySynchronousWork
- {
- CompletionNotification = 0,
- Execution = 2,
- ProgressNotification = 1,
- }
- internal enum CausalityTraceLevel
- {
- Important = 1,
- Required = 0,
- Verbose = 2,
- }
- [System.Runtime.InteropServices.GuidAttribute("50850B26-267E-451B-A890-AB6A370245EE")]
- internal partial interface IAsyncCausalityTracerStatics
- {
- System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken add_TracingStatusChanged(System.EventHandler<Windows.Foundation.Diagnostics.TracingStatusChangedEventArgs> eventHandler);
- void TraceOperationCompletion(Windows.Foundation.Diagnostics.CausalityTraceLevel traceLevel, Windows.Foundation.Diagnostics.CausalitySource source, System.Guid platformId, ulong operationId, Windows.Foundation.Diagnostics.AsyncCausalityStatus status);
- void TraceOperationCreation(Windows.Foundation.Diagnostics.CausalityTraceLevel traceLevel, Windows.Foundation.Diagnostics.CausalitySource source, System.Guid platformId, ulong operationId, string operationName, ulong relatedContext);
- void TraceOperationRelation(Windows.Foundation.Diagnostics.CausalityTraceLevel traceLevel, Windows.Foundation.Diagnostics.CausalitySource source, System.Guid platformId, ulong operationId, Windows.Foundation.Diagnostics.CausalityRelation relation);
- void TraceSynchronousWorkCompletion(Windows.Foundation.Diagnostics.CausalityTraceLevel traceLevel, Windows.Foundation.Diagnostics.CausalitySource source, Windows.Foundation.Diagnostics.CausalitySynchronousWork work);
- void TraceSynchronousWorkStart(Windows.Foundation.Diagnostics.CausalityTraceLevel traceLevel, Windows.Foundation.Diagnostics.CausalitySource source, System.Guid platformId, ulong operationId, Windows.Foundation.Diagnostics.CausalitySynchronousWork work);
- }
- [System.Runtime.InteropServices.GuidAttribute("410B7711-FF3B-477F-9C9A-D2EFDA302DC3")]
- internal partial interface ITracingStatusChangedEventArgs
- {
- bool Enabled { get; }
- Windows.Foundation.Diagnostics.CausalityTraceLevel TraceLevel { get; }
- }
- [System.Runtime.InteropServices.GuidAttribute("410B7711-FF3B-477F-9C9A-D2EFDA302DC3")]
- internal sealed partial class TracingStatusChangedEventArgs : Windows.Foundation.Diagnostics.ITracingStatusChangedEventArgs
- {
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- public TracingStatusChangedEventArgs() { }
- public bool Enabled { [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } }
- public Windows.Foundation.Diagnostics.CausalityTraceLevel TraceLevel { [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]get { throw null; } }
- }
-}
-#endif
-
-namespace System.Security.Claims
-{
- public partial class Claim
- {
- public Claim(System.IO.BinaryReader reader) { }
- public Claim(System.IO.BinaryReader reader, System.Security.Claims.ClaimsIdentity subject) { }
- protected Claim(System.Security.Claims.Claim other) { }
- protected Claim(System.Security.Claims.Claim other, System.Security.Claims.ClaimsIdentity subject) { }
- public Claim(string type, string value) { }
- public Claim(string type, string value, string valueType) { }
- public Claim(string type, string value, string valueType, string issuer) { }
- public Claim(string type, string value, string valueType, string issuer, string originalIssuer) { }
- public Claim(string type, string value, string valueType, string issuer, string originalIssuer, System.Security.Claims.ClaimsIdentity subject) { }
- protected virtual byte[] CustomSerializationData { get { throw null; } }
- public string Issuer { get { throw null; } }
- public string OriginalIssuer { get { throw null; } }
- public System.Collections.Generic.IDictionary<string, string> Properties { get { throw null; } }
- public System.Security.Claims.ClaimsIdentity Subject { get { throw null; } }
- public string Type { get { throw null; } }
- public string Value { get { throw null; } }
- public string ValueType { get { throw null; } }
- public virtual System.Security.Claims.Claim Clone() { throw null; }
- public virtual System.Security.Claims.Claim Clone(System.Security.Claims.ClaimsIdentity identity) { throw null; }
- public override string ToString() { throw null; }
- public virtual void WriteTo(System.IO.BinaryWriter writer) { }
- protected virtual void WriteTo(System.IO.BinaryWriter writer, byte[] userData) { }
- }
- public partial class ClaimsIdentity : System.Security.Principal.IIdentity
- {
- public const string DefaultIssuer = "LOCAL AUTHORITY";
- public const string DefaultNameClaimType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name";
- public const string DefaultRoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role";
- public ClaimsIdentity() { }
- public ClaimsIdentity(System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> claims) { }
- public ClaimsIdentity(System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> claims, string authenticationType) { }
- public ClaimsIdentity(System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> claims, string authenticationType, string nameType, string roleType) { }
- public ClaimsIdentity(System.IO.BinaryReader reader) { }
- protected ClaimsIdentity(System.Security.Claims.ClaimsIdentity other) { }
- public ClaimsIdentity(System.Security.Principal.IIdentity identity) { }
- public ClaimsIdentity(System.Security.Principal.IIdentity identity, System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> claims) { }
- public ClaimsIdentity(System.Security.Principal.IIdentity identity, System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> claims, string authenticationType, string nameType, string roleType) { }
- public ClaimsIdentity(string authenticationType) { }
- public ClaimsIdentity(string authenticationType, string nameType, string roleType) { }
- public System.Security.Claims.ClaimsIdentity Actor { get { throw null; } set { } }
- public virtual string AuthenticationType { get { throw null; } }
- public object BootstrapContext { get { throw null; } set { } }
- public virtual System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> Claims { get { throw null; } }
- protected virtual byte[] CustomSerializationData { get { throw null; } }
- public virtual bool IsAuthenticated { get { throw null; } }
- public string Label { get { throw null; } set { } }
- public virtual string Name { get { throw null; } }
- public string NameClaimType { get { throw null; } }
- public string RoleClaimType { get { throw null; } }
- public virtual void AddClaim(System.Security.Claims.Claim claim) { }
- public virtual void AddClaims(System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> claims) { }
- public virtual System.Security.Claims.ClaimsIdentity Clone() { throw null; }
- protected virtual System.Security.Claims.Claim CreateClaim(System.IO.BinaryReader reader) { throw null; }
- public virtual System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> FindAll(System.Predicate<System.Security.Claims.Claim> match) { throw null; }
- public virtual System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> FindAll(string type) { throw null; }
- public virtual System.Security.Claims.Claim FindFirst(System.Predicate<System.Security.Claims.Claim> match) { throw null; }
- public virtual System.Security.Claims.Claim FindFirst(string type) { throw null; }
- public virtual bool HasClaim(System.Predicate<System.Security.Claims.Claim> match) { throw null; }
- public virtual bool HasClaim(string type, string value) { throw null; }
- public virtual void RemoveClaim(System.Security.Claims.Claim claim) { }
- public virtual bool TryRemoveClaim(System.Security.Claims.Claim claim) { throw null; }
- public virtual void WriteTo(System.IO.BinaryWriter writer) { }
- protected virtual void WriteTo(System.IO.BinaryWriter writer, byte[] userData) { }
- }
- public partial class ClaimsPrincipal : System.Security.Principal.IPrincipal
- {
- public ClaimsPrincipal() { }
- public ClaimsPrincipal(System.Collections.Generic.IEnumerable<System.Security.Claims.ClaimsIdentity> identities) { }
- public ClaimsPrincipal(System.IO.BinaryReader reader) { }
- public ClaimsPrincipal(System.Security.Principal.IIdentity identity) { }
- public ClaimsPrincipal(System.Security.Principal.IPrincipal principal) { }
- public virtual System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> Claims { get { throw null; } }
- public static System.Func<System.Security.Claims.ClaimsPrincipal> ClaimsPrincipalSelector { get { throw null; } set { } }
- public static System.Security.Claims.ClaimsPrincipal Current { get { throw null; } }
- protected virtual byte[] CustomSerializationData { get { throw null; } }
- public virtual System.Collections.Generic.IEnumerable<System.Security.Claims.ClaimsIdentity> Identities { get { throw null; } }
- public virtual System.Security.Principal.IIdentity Identity { get { throw null; } }
- public static System.Func<System.Collections.Generic.IEnumerable<System.Security.Claims.ClaimsIdentity>, System.Security.Claims.ClaimsIdentity> PrimaryIdentitySelector { get { throw null; } set { } }
- public virtual void AddIdentities(System.Collections.Generic.IEnumerable<System.Security.Claims.ClaimsIdentity> identities) { }
- public virtual void AddIdentity(System.Security.Claims.ClaimsIdentity identity) { }
- public virtual System.Security.Claims.ClaimsPrincipal Clone() { throw null; }
- protected virtual System.Security.Claims.ClaimsIdentity CreateClaimsIdentity(System.IO.BinaryReader reader) { throw null; }
- public virtual System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> FindAll(System.Predicate<System.Security.Claims.Claim> match) { throw null; }
- public virtual System.Collections.Generic.IEnumerable<System.Security.Claims.Claim> FindAll(string type) { throw null; }
- public virtual System.Security.Claims.Claim FindFirst(System.Predicate<System.Security.Claims.Claim> match) { throw null; }
- public virtual System.Security.Claims.Claim FindFirst(string type) { throw null; }
- public virtual bool HasClaim(System.Predicate<System.Security.Claims.Claim> match) { throw null; }
- public virtual bool HasClaim(string type, string value) { throw null; }
- public virtual bool IsInRole(string role) { throw null; }
- public virtual void WriteTo(System.IO.BinaryWriter writer) { }
- protected virtual void WriteTo(System.IO.BinaryWriter writer, byte[] userData) { }
- }
- public static partial class ClaimTypes
- {
- public const string Actor = "http://schemas.xmlsoap.org/ws/2009/09/identity/claims/actor";
- public const string Anonymous = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/anonymous";
- public const string Authentication = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/authentication";
- public const string AuthenticationInstant = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant";
- public const string AuthenticationMethod = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod";
- public const string AuthorizationDecision = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/authorizationdecision";
- public const string CookiePath = "http://schemas.microsoft.com/ws/2008/06/identity/claims/cookiepath";
- public const string Country = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country";
- public const string DateOfBirth = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth";
- public const string DenyOnlyPrimaryGroupSid = "http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarygroupsid";
- public const string DenyOnlyPrimarySid = "http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlyprimarysid";
- public const string DenyOnlySid = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/denyonlysid";
- public const string DenyOnlyWindowsDeviceGroup = "http://schemas.microsoft.com/ws/2008/06/identity/claims/denyonlywindowsdevicegroup";
- public const string Dns = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dns";
- public const string Dsa = "http://schemas.microsoft.com/ws/2008/06/identity/claims/dsa";
- public const string Email = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress";
- public const string Expiration = "http://schemas.microsoft.com/ws/2008/06/identity/claims/expiration";
- public const string Expired = "http://schemas.microsoft.com/ws/2008/06/identity/claims/expired";
- public const string Gender = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/gender";
- public const string GivenName = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname";
- public const string GroupSid = "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid";
- public const string Hash = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/hash";
- public const string HomePhone = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/homephone";
- public const string IsPersistent = "http://schemas.microsoft.com/ws/2008/06/identity/claims/ispersistent";
- public const string Locality = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/locality";
- public const string MobilePhone = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mobilephone";
- public const string Name = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name";
- public const string NameIdentifier = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier";
- public const string OtherPhone = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/otherphone";
- public const string PostalCode = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postalcode";
- public const string PrimaryGroupSid = "http://schemas.microsoft.com/ws/2008/06/identity/claims/primarygroupsid";
- public const string PrimarySid = "http://schemas.microsoft.com/ws/2008/06/identity/claims/primarysid";
- public const string Role = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role";
- public const string Rsa = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/rsa";
- public const string SerialNumber = "http://schemas.microsoft.com/ws/2008/06/identity/claims/serialnumber";
- public const string Sid = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/sid";
- public const string Spn = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/spn";
- public const string StateOrProvince = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/stateorprovince";
- public const string StreetAddress = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/streetaddress";
- public const string Surname = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname";
- public const string System = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/system";
- public const string Thumbprint = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/thumbprint";
- public const string Upn = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn";
- public const string Uri = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/uri";
- public const string UserData = "http://schemas.microsoft.com/ws/2008/06/identity/claims/userdata";
- public const string Version = "http://schemas.microsoft.com/ws/2008/06/identity/claims/version";
- public const string Webpage = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/webpage";
- public const string WindowsAccountName = "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname";
- public const string WindowsDeviceClaim = "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsdeviceclaim";
- public const string WindowsDeviceGroup = "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsdevicegroup";
- public const string WindowsFqbnVersion = "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsfqbnversion";
- public const string WindowsSubAuthority = "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowssubauthority";
- public const string WindowsUserClaim = "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsuserclaim";
- public const string X500DistinguishedName = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/x500distinguishedname";
- }
- public static partial class ClaimValueTypes
- {
- public const string Base64Binary = "http://www.w3.org/2001/XMLSchema#base64Binary";
- public const string Base64Octet = "http://www.w3.org/2001/XMLSchema#base64Octet";
- public const string Boolean = "http://www.w3.org/2001/XMLSchema#boolean";
- public const string Date = "http://www.w3.org/2001/XMLSchema#date";
- public const string DateTime = "http://www.w3.org/2001/XMLSchema#dateTime";
- public const string DaytimeDuration = "http://www.w3.org/TR/2002/WD-xquery-operators-20020816#dayTimeDuration";
- public const string DnsName = "http://schemas.xmlsoap.org/claims/dns";
- public const string Double = "http://www.w3.org/2001/XMLSchema#double";
- public const string DsaKeyValue = "http://www.w3.org/2000/09/xmldsig#DSAKeyValue";
- public const string Email = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress";
- public const string Fqbn = "http://www.w3.org/2001/XMLSchema#fqbn";
- public const string HexBinary = "http://www.w3.org/2001/XMLSchema#hexBinary";
- public const string Integer = "http://www.w3.org/2001/XMLSchema#integer";
- public const string Integer32 = "http://www.w3.org/2001/XMLSchema#integer32";
- public const string Integer64 = "http://www.w3.org/2001/XMLSchema#integer64";
- public const string KeyInfo = "http://www.w3.org/2000/09/xmldsig#KeyInfo";
- public const string Rfc822Name = "urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name";
- public const string Rsa = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/rsa";
- public const string RsaKeyValue = "http://www.w3.org/2000/09/xmldsig#RSAKeyValue";
- public const string Sid = "http://www.w3.org/2001/XMLSchema#sid";
- public const string String = "http://www.w3.org/2001/XMLSchema#string";
- public const string Time = "http://www.w3.org/2001/XMLSchema#time";
- public const string UInteger32 = "http://www.w3.org/2001/XMLSchema#uinteger32";
- public const string UInteger64 = "http://www.w3.org/2001/XMLSchema#uinteger64";
- public const string UpnName = "http://schemas.xmlsoap.org/claims/UPN";
- public const string X500Name = "urn:oasis:names:tc:xacml:1.0:data-type:x500Name";
- public const string YearMonthDuration = "http://www.w3.org/TR/2002/WD-xquery-operators-20020816#yearMonthDuration";
- }
-} \ No newline at end of file
diff --git a/src/mscorlib/corefx/Interop/Unix/Interop.Errors.cs b/src/mscorlib/shared/Interop/Unix/Interop.Errors.cs
index 4248434db3..4248434db3 100644
--- a/src/mscorlib/corefx/Interop/Unix/Interop.Errors.cs
+++ b/src/mscorlib/shared/Interop/Unix/Interop.Errors.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/Interop.IOErrors.cs b/src/mscorlib/shared/Interop/Unix/Interop.IOErrors.cs
index e9d6ce61d6..e9d6ce61d6 100644
--- a/src/mscorlib/corefx/Interop/Unix/Interop.IOErrors.cs
+++ b/src/mscorlib/shared/Interop/Unix/Interop.IOErrors.cs
diff --git a/src/mscorlib/shared/Interop/Unix/Interop.Libraries.cs b/src/mscorlib/shared/Interop/Unix/Interop.Libraries.cs
new file mode 100644
index 0000000000..7b3dea453d
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Unix/Interop.Libraries.cs
@@ -0,0 +1,12 @@
+// 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 static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ internal const string GlobalizationInterop = "System.Globalization.Native";
+ internal const string SystemNative = "System.Native";
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs
index 7b3caeabdd..7b3caeabdd 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Casing.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Casing.cs
index 769506b8f6..769506b8f6 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Casing.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Casing.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Idna.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Idna.cs
index 43c72281ae..43c72281ae 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Idna.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Idna.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Locale.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Locale.cs
index fcea708ee8..fcea708ee8 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Locale.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Locale.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs
index c4cb9fb851..c4cb9fb851 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs
index cca6ae4dcb..cca6ae4dcb 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs
index 26a9fe0579..26a9fe0579 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Utils.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Utils.cs
index 33b10c0d74..33b10c0d74 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Globalization.Native/Interop.Utils.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Utils.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Close.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.Close.cs
index 8d192398a0..8d192398a0 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Close.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.Close.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FLock.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.FLock.cs
index 22934a3e77..22934a3e77 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FLock.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.FLock.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FSync.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.FSync.cs
index e3ab970931..e3ab970931 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FSync.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.FSync.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FTruncate.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.FTruncate.cs
index 5dad650362..5dad650362 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.FTruncate.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.FTruncate.cs
diff --git a/src/mscorlib/shared/Interop/Unix/System.Native/Interop.GetCwd.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.GetCwd.cs
new file mode 100644
index 0000000000..a27a35c9f5
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.GetCwd.cs
@@ -0,0 +1,74 @@
+// 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.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetCwd", SetLastError = true)]
+ private static unsafe extern byte* GetCwd(byte* buffer, int bufferLength);
+
+ internal static unsafe string GetCwd()
+ {
+ const int StackLimit = 256;
+
+ // First try to get the path into a buffer on the stack
+ byte* stackBuf = stackalloc byte[StackLimit];
+ string result = GetCwdHelper(stackBuf, StackLimit);
+ if (result != null)
+ {
+ return result;
+ }
+
+ // If that was too small, try increasing large buffer sizes
+ // until we get one that works or until we hit MaxPath.
+ int maxPath = Interop.Sys.MaxPath;
+ if (StackLimit < maxPath)
+ {
+ int bufferSize = StackLimit;
+ do
+ {
+ checked { bufferSize *= 2; }
+ var buf = new byte[Math.Min(bufferSize, maxPath)];
+ fixed (byte* ptr = &buf[0])
+ {
+ result = GetCwdHelper(ptr, buf.Length);
+ if (result != null)
+ {
+ return result;
+ }
+ }
+ }
+ while (bufferSize < maxPath);
+ }
+
+ // If we couldn't get the cwd with a MaxPath-sized buffer, something's wrong.
+ throw Interop.GetExceptionForIoErrno(new ErrorInfo(Interop.Error.ENAMETOOLONG));
+ }
+
+ private static unsafe string GetCwdHelper(byte* ptr, int bufferSize)
+ {
+ // Call the real getcwd
+ byte* result = GetCwd(ptr, bufferSize);
+
+ // If it returned non-null, the null-terminated path is in the buffer
+ if (result != null)
+ {
+ return Marshal.PtrToStringAnsi((IntPtr)ptr);
+ }
+
+ // Otherwise, if it failed due to the buffer being too small, return null;
+ // for anything else, throw.
+ ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo();
+ if (errorInfo.Error == Interop.Error.ERANGE)
+ {
+ return null;
+ }
+ throw Interop.GetExceptionForIoErrno(errorInfo);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/Interop/Unix/System.Native/Interop.GetRandomBytes.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.GetRandomBytes.cs
new file mode 100644
index 0000000000..62156e8d8e
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.GetRandomBytes.cs
@@ -0,0 +1,21 @@
+// 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.Diagnostics;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal unsafe partial class Sys
+ {
+ [DllImport(Interop.Libraries.SystemNative, EntryPoint = "SystemNative_GetNonCryptographicallySecureRandomBytes")]
+ internal static unsafe extern void GetNonCryptographicallySecureRandomBytes(byte* buffer, int length);
+ }
+
+ internal static unsafe void GetRandomBytes(byte* buffer, int length)
+ {
+ Sys.GetNonCryptographicallySecureRandomBytes(buffer, length);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.LSeek.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.LSeek.cs
index 7f8df7c6bf..7f8df7c6bf 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.LSeek.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.LSeek.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Fcntl.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.LockFileRegion.cs
index 23b48a4f5d..23b48a4f5d 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Fcntl.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.LockFileRegion.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.MksTemps.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.MksTemps.cs
index b8694d9007..b8694d9007 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.MksTemps.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.MksTemps.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Open.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.Open.cs
index a9a994c78c..a9a994c78c 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Open.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.Open.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.OpenFlags.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.OpenFlags.cs
index f9e54c3cbc..f9e54c3cbc 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.OpenFlags.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.OpenFlags.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.PathConf.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.PathConf.cs
index 4a1fcf67d0..4a1fcf67d0 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.PathConf.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.PathConf.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Permissions.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.Permissions.cs
index f1d13787d2..f1d13787d2 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Permissions.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.Permissions.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.PosixFAdvise.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.PosixFAdvise.cs
index 69e39b30d2..69e39b30d2 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.PosixFAdvise.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.PosixFAdvise.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Read.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.Read.cs
index 812ae348dc..812ae348dc 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Read.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.Read.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Stat.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.Stat.cs
index a8bc2ec7d1..a8bc2ec7d1 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Stat.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.Stat.cs
diff --git a/src/mscorlib/shared/Interop/Unix/System.Native/Interop.SysLog.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.SysLog.cs
new file mode 100644
index 0000000000..6b6a74b743
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.SysLog.cs
@@ -0,0 +1,58 @@
+// 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.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ internal enum SysLogPriority : int
+ {
+ // Priorities
+ LOG_EMERG = 0, /* system is unusable */
+ LOG_ALERT = 1, /* action must be taken immediately */
+ LOG_CRIT = 2, /* critical conditions */
+ LOG_ERR = 3, /* error conditions */
+ LOG_WARNING = 4, /* warning conditions */
+ LOG_NOTICE = 5, /* normal but significant condition */
+ LOG_INFO = 6, /* informational */
+ LOG_DEBUG = 7, /* debug-level messages */
+ // Facilities
+ LOG_KERN = (0<<3), /* kernel messages */
+ LOG_USER = (1<<3), /* random user-level messages */
+ LOG_MAIL = (2<<3), /* mail system */
+ LOG_DAEMON = (3<<3), /* system daemons */
+ LOG_AUTH = (4<<3), /* authorization messages */
+ LOG_SYSLOG = (5<<3), /* messages generated internally by syslogd */
+ LOG_LPR = (6<<3), /* line printer subsystem */
+ LOG_NEWS = (7<<3), /* network news subsystem */
+ LOG_UUCP = (8<<3), /* UUCP subsystem */
+ LOG_CRON = (9<<3), /* clock daemon */
+ LOG_AUTHPRIV = (10<<3), /* authorization messages (private) */
+ LOG_FTP = (11<<3), /* ftp daemon */
+ // Between FTP and Local is reserved for system use
+ LOG_LOCAL0 = (16<<3), /* reserved for local use */
+ LOG_LOCAL1 = (17<<3), /* reserved for local use */
+ LOG_LOCAL2 = (18<<3), /* reserved for local use */
+ LOG_LOCAL3 = (19<<3), /* reserved for local use */
+ LOG_LOCAL4 = (20<<3), /* reserved for local use */
+ LOG_LOCAL5 = (21<<3), /* reserved for local use */
+ LOG_LOCAL6 = (22<<3), /* reserved for local use */
+ LOG_LOCAL7 = (23<<3), /* reserved for local use */
+ }
+
+ /// <summary>
+ /// Write a message to the system logger, which in turn writes the message to the system console, log files, etc.
+ /// See man 3 syslog for more info
+ /// </summary>
+ /// <param name="priority">
+ /// The OR of a priority and facility in the SysLogPriority enum to declare the priority and facility of the log entry
+ /// </param>
+ /// <param name="message">The message to put in the log entry</param>
+ /// <param name="arg1">Like printf, the argument is passed to the variadic part of the C++ function to wildcards in the message</param>
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_SysLog")]
+ internal static extern void SysLog(SysLogPriority priority, string message, string arg1);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Unlink.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.Unlink.cs
index 829210fa7e..829210fa7e 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Unlink.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.Unlink.cs
diff --git a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Write.cs b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.Write.cs
index c14fc26263..c14fc26263 100644
--- a/src/mscorlib/corefx/Interop/Unix/System.Native/Interop.Write.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Native/Interop.Write.cs
diff --git a/src/mscorlib/shared/Interop/Windows/BCrypt/Interop.BCryptGenRandom.cs b/src/mscorlib/shared/Interop/Windows/BCrypt/Interop.BCryptGenRandom.cs
new file mode 100644
index 0000000000..bc357125b5
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/BCrypt/Interop.BCryptGenRandom.cs
@@ -0,0 +1,44 @@
+// 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.Diagnostics;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class BCrypt
+ {
+ internal static unsafe int BCryptGenRandom(byte* pbBuffer, int count)
+ {
+ Debug.Assert(pbBuffer != null);
+ Debug.Assert(count >= 0);
+
+ return BCryptGenRandom(IntPtr.Zero, pbBuffer, count, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
+ }
+
+ private const int BCRYPT_USE_SYSTEM_PREFERRED_RNG = 0x00000002;
+ internal const int STATUS_SUCCESS = 0x0;
+ internal const int STATUS_NO_MEMORY = unchecked((int)0xC0000017);
+
+ [DllImport(Libraries.BCrypt, CharSet = CharSet.Unicode)]
+ private static unsafe extern int BCryptGenRandom(IntPtr hAlgorithm, byte* pbBuffer, int cbBuffer, int dwFlags);
+ }
+
+ internal static unsafe void GetRandomBytes(byte* buffer, int length)
+ {
+ int status = BCrypt.BCryptGenRandom(buffer, length);
+ if (status != BCrypt.STATUS_SUCCESS)
+ {
+ if (status == BCrypt.STATUS_NO_MEMORY)
+ {
+ throw new OutOfMemoryException();
+ }
+ else
+ {
+ throw new InvalidOperationException();
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/Crypt32/Interop.CryptProtectMemory.cs b/src/mscorlib/shared/Interop/Windows/Crypt32/Interop.CryptProtectMemory.cs
index b10cb6a041..b10cb6a041 100644
--- a/src/mscorlib/corefx/Interop/Windows/Crypt32/Interop.CryptProtectMemory.cs
+++ b/src/mscorlib/shared/Interop/Windows/Crypt32/Interop.CryptProtectMemory.cs
diff --git a/src/mscorlib/corefx/Interop/Windows/Interop.BOOL.cs b/src/mscorlib/shared/Interop/Windows/Interop.BOOL.cs
index 9f4dab8935..9f4dab8935 100644
--- a/src/mscorlib/corefx/Interop/Windows/Interop.BOOL.cs
+++ b/src/mscorlib/shared/Interop/Windows/Interop.BOOL.cs
diff --git a/src/mscorlib/shared/Interop/Windows/Interop.Errors.cs b/src/mscorlib/shared/Interop/Windows/Interop.Errors.cs
new file mode 100644
index 0000000000..ff2653765c
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/Interop.Errors.cs
@@ -0,0 +1,44 @@
+// 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
+{
+ // As defined in winerror.h and https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382.aspx
+ internal partial class Errors
+ {
+ internal const int ERROR_SUCCESS = 0x0;
+ internal const int ERROR_FILE_NOT_FOUND = 0x2;
+ internal const int ERROR_PATH_NOT_FOUND = 0x3;
+ internal const int ERROR_ACCESS_DENIED = 0x5;
+ internal const int ERROR_INVALID_HANDLE = 0x6;
+ internal const int ERROR_NOT_ENOUGH_MEMORY = 0x8;
+ internal const int ERROR_INVALID_DRIVE = 0xF;
+ internal const int ERROR_NO_MORE_FILES = 0x12;
+ internal const int ERROR_NOT_READY = 0x15;
+ internal const int ERROR_SHARING_VIOLATION = 0x20;
+ internal const int ERROR_HANDLE_EOF = 0x26;
+ internal const int ERROR_FILE_EXISTS = 0x50;
+ internal const int ERROR_INVALID_PARAMETER = 0x57;
+ internal const int ERROR_BROKEN_PIPE = 0x6D;
+ internal const int ERROR_INSUFFICIENT_BUFFER = 0x7A;
+ internal const int ERROR_INVALID_NAME = 0x7B;
+ internal const int ERROR_BAD_PATHNAME = 0xA1;
+ internal const int ERROR_ALREADY_EXISTS = 0xB7;
+ internal const int ERROR_ENVVAR_NOT_FOUND = 0xCB;
+ internal const int ERROR_FILENAME_EXCED_RANGE = 0xCE;
+ internal const int ERROR_NO_DATA = 0xE8;
+ internal const int ERROR_MORE_DATA = 0xEA;
+ internal const int ERROR_NO_MORE_ITEMS = 0x103;
+ internal const int ERROR_NOT_OWNER = 0x120;
+ internal const int ERROR_TOO_MANY_POSTS = 0x12A;
+ internal const int ERROR_ARITHMETIC_OVERFLOW = 0x216;
+ internal const int ERROR_MUTANT_LIMIT_EXCEEDED = 0x24B;
+ internal const int ERROR_OPERATION_ABORTED = 0x3E3;
+ internal const int ERROR_IO_PENDING = 0x3E5;
+ internal const int ERROR_NO_UNICODE_TRANSLATION = 0x459;
+ internal const int ERROR_NOT_FOUND = 0x490;
+ internal const int ERROR_BAD_IMPERSONATION_LEVEL = 0x542;
+ internal const int E_FILENOTFOUND = unchecked((int)0x80070002);
+ }
+}
diff --git a/src/mscorlib/shared/Interop/Windows/Interop.Libraries.cs b/src/mscorlib/shared/Interop/Windows/Interop.Libraries.cs
new file mode 100644
index 0000000000..58bb12d637
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/Interop.Libraries.cs
@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ internal const string BCrypt = "BCrypt.dll";
+ internal const string Crypt32 = "crypt32.dll";
+ internal const string Kernel32 = "kernel32.dll";
+ internal const string NtDll = "ntdll.dll";
+ internal const string OleAut32 = "oleaut32.dll";
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.CancelIoEx.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.CancelIoEx.cs
index fc99e3052f..fc99e3052f 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.CancelIoEx.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.CancelIoEx.cs
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.CloseHandle.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.CloseHandle.cs
index 96ed922a84..96ed922a84 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.CloseHandle.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.CloseHandle.cs
diff --git a/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.CreateFile.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.CreateFile.cs
new file mode 100644
index 0000000000..9ee1e16fa6
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.CreateFile.cs
@@ -0,0 +1,40 @@
+// 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 Microsoft.Win32.SafeHandles;
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ /// <summary>
+ /// WARNING: This method does not implicitly handle long paths. Use CreateFile.
+ /// </summary>
+ [DllImport(Libraries.Kernel32, EntryPoint = "CreateFileW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
+ private static extern SafeFileHandle CreateFilePrivate(
+ string lpFileName,
+ int dwDesiredAccess,
+ System.IO.FileShare dwShareMode,
+ ref SECURITY_ATTRIBUTES securityAttrs,
+ System.IO.FileMode dwCreationDisposition,
+ int dwFlagsAndAttributes,
+ IntPtr hTemplateFile);
+
+ internal static SafeFileHandle CreateFile(
+ string lpFileName,
+ int dwDesiredAccess,
+ System.IO.FileShare dwShareMode,
+ ref SECURITY_ATTRIBUTES securityAttrs,
+ System.IO.FileMode dwCreationDisposition,
+ int dwFlagsAndAttributes,
+ IntPtr hTemplateFile)
+ {
+ lpFileName = PathInternal.EnsureExtendedPrefixOverMaxPath(lpFileName);
+ return CreateFilePrivate(lpFileName, dwDesiredAccess, dwShareMode, ref securityAttrs, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.CreateFile2.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.CreateFile2.cs
new file mode 100644
index 0000000000..0909d3a6c8
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.CreateFile2.cs
@@ -0,0 +1,31 @@
+// 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 Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ [DllImport(Libraries.Kernel32, EntryPoint = "CreateFile2", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
+ internal static extern unsafe SafeFileHandle CreateFile2(
+ string lpFileName,
+ int dwDesiredAccess,
+ System.IO.FileShare dwShareMode,
+ System.IO.FileMode dwCreationDisposition,
+ CREATEFILE2_EXTENDED_PARAMETERS* pCreateExParams);
+
+ internal unsafe struct CREATEFILE2_EXTENDED_PARAMETERS
+ {
+ internal uint dwSize;
+ internal uint dwFileAttributes;
+ internal uint dwFileFlags;
+ internal uint dwSecurityQosFlags;
+ internal SECURITY_ATTRIBUTES* lpSecurityAttributes;
+ internal IntPtr hTemplateFile;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetFileInformationByHandle.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.FILE_INFO_BY_HANDLE_CLASS.cs
index e31a453ba9..e31a453ba9 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetFileInformationByHandle.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.FILE_INFO_BY_HANDLE_CLASS.cs
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FileTypes.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.FileTypes.cs
index 1d306665b1..1d306665b1 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FileTypes.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.FileTypes.cs
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FlushFileBuffers.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.FlushFileBuffers.cs
index e10a2279cf..e10a2279cf 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FlushFileBuffers.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.FlushFileBuffers.cs
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FormatMessage.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.FormatMessage.cs
index 94722b6c8b..94722b6c8b 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FormatMessage.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.FormatMessage.cs
diff --git a/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFileInformationByHandleEx.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFileInformationByHandleEx.cs
new file mode 100644
index 0000000000..1106cff1c5
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFileInformationByHandleEx.cs
@@ -0,0 +1,25 @@
+// 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 Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ [DllImport(Libraries.Kernel32, SetLastError = true)]
+ internal static extern bool GetFileInformationByHandleEx(SafeFileHandle hFile, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, out FILE_STANDARD_INFO lpFileInformation, uint dwBufferSize);
+
+ internal struct FILE_STANDARD_INFO
+ {
+ internal long AllocationSize;
+ internal long EndOfFile;
+ internal uint NumberOfLinks;
+ internal BOOL DeletePending;
+ internal BOOL Directory;
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetFileType_SafeHandle.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFileType_SafeHandle.cs
index c07a1683a5..c07a1683a5 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetFileType_SafeHandle.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFileType_SafeHandle.cs
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetFullPathNameW.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFullPathNameW.cs
index 15dd581113..15dd581113 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetFullPathNameW.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetFullPathNameW.cs
diff --git a/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetLongPathNameW.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetLongPathNameW.cs
new file mode 100644
index 0000000000..ce04078af5
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetLongPathNameW.cs
@@ -0,0 +1,18 @@
+// 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.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ /// <summary>
+ /// WARNING: This method does not implicitly handle long paths. Use GetFullPath/PathHelper.
+ /// </summary>
+ [DllImport(Libraries.Kernel32, SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)]
+ internal static extern uint GetLongPathNameW(char[] lpszShortPath, char[] lpszLongPath, uint cchBuffer);
+ }
+}
diff --git a/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetTempFileNameW.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetTempFileNameW.cs
new file mode 100644
index 0000000000..36673895b4
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetTempFileNameW.cs
@@ -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.Text;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false)]
+ internal static extern uint GetTempFileNameW(string tmpPath, string prefix, uint uniqueIdOrZero, [Out]StringBuilder tmpFileName);
+ }
+}
diff --git a/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetTempPathW.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetTempPathW.cs
new file mode 100644
index 0000000000..ff2783be26
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.GetTempPathW.cs
@@ -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.IO;
+using System.Text;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, BestFitMapping = false)]
+ internal static extern uint GetTempPathW(int bufferLen, [Out]StringBuilder buffer);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.LockFile.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.LockFile.cs
index a21d00f4f6..a21d00f4f6 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.LockFile.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.LockFile.cs
diff --git a/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.OutputDebugString.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.OutputDebugString.cs
new file mode 100644
index 0000000000..8da50ff8ab
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.OutputDebugString.cs
@@ -0,0 +1,14 @@
+// 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.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ [DllImport(Interop.Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "OutputDebugStringW", ExactSpelling = true)]
+ internal static extern void OutputDebugString(string message);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.ReadFile_SafeHandle_IntPtr.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.ReadFile_SafeHandle_IntPtr.cs
index 076f7f136f..076f7f136f 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.ReadFile_SafeHandle_IntPtr.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.ReadFile_SafeHandle_IntPtr.cs
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.ReadFile_SafeHandle_NativeOverlapped.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.ReadFile_SafeHandle_NativeOverlapped.cs
index 3ae65a8806..3ae65a8806 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.ReadFile_SafeHandle_NativeOverlapped.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.ReadFile_SafeHandle_NativeOverlapped.cs
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SECURITY_ATTRIBUTES.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SECURITY_ATTRIBUTES.cs
index 8d31f8622f..8d31f8622f 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SECURITY_ATTRIBUTES.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SECURITY_ATTRIBUTES.cs
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SecurityOptions.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SecurityOptions.cs
index 4a4402484f..4a4402484f 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SecurityOptions.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SecurityOptions.cs
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetEndOfFile.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SetEndOfFile.cs
index e5d60041a8..e5d60041a8 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetEndOfFile.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SetEndOfFile.cs
diff --git a/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SetErrorMode.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SetErrorMode.cs
new file mode 100644
index 0000000000..276f49c519
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SetErrorMode.cs
@@ -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.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ [DllImport(Libraries.Kernel32, SetLastError = false, EntryPoint = "SetErrorMode", ExactSpelling = true)]
+ internal static extern uint SetErrorMode(uint newMode);
+
+ internal const uint SEM_FAILCRITICALERRORS = 1;
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetFilePointerEx.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SetFilePointerEx.cs
index c0e5247a52..c0e5247a52 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetFilePointerEx.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.SetFilePointerEx.cs
diff --git a/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.WideCharToMultiByte.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.WideCharToMultiByte.cs
new file mode 100644
index 0000000000..a06c9153f4
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.WideCharToMultiByte.cs
@@ -0,0 +1,22 @@
+// 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.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ [DllImport(Libraries.Kernel32)]
+ internal static extern unsafe int WideCharToMultiByte(
+ uint CodePage, uint dwFlags,
+ char* lpWideCharStr, int cchWideChar,
+ byte* lpMultiByteStr, int cbMultiByte,
+ IntPtr lpDefaultChar, IntPtr lpUsedDefaultChar);
+
+ internal const uint CP_ACP = 0;
+ internal const uint WC_NO_BEST_FIT_CHARS = 0x00000400;
+ }
+}
diff --git a/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.WriteFile_SafeHandle_IntPtr.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.WriteFile_SafeHandle_IntPtr.cs
new file mode 100644
index 0000000000..69651ca1ca
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.WriteFile_SafeHandle_IntPtr.cs
@@ -0,0 +1,23 @@
+// 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 Microsoft.Win32.SafeHandles;
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ // Note there are two different WriteFile prototypes - this is to use
+ // the type system to force you to not trip across a "feature" in
+ // Win32's async IO support. You can't do the following three things
+ // simultaneously: overlapped IO, free the memory for the overlapped
+ // struct in a callback (or an EndWrite method called by that callback),
+ // and pass in an address for the numBytesRead parameter.
+
+ [DllImport(Libraries.Kernel32, SetLastError = true)]
+ internal static extern unsafe int WriteFile(SafeHandle handle, byte* bytes, int numBytesToWrite, out int numBytesWritten, IntPtr mustBeZero);
+ }
+}
diff --git a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.WriteFile_SafeHandle_NativeOverlapped.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.WriteFile_SafeHandle_NativeOverlapped.cs
index dc1e97555b..dc1e97555b 100644
--- a/src/mscorlib/corefx/Interop/Windows/kernel32/Interop.WriteFile_SafeHandle_NativeOverlapped.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.WriteFile_SafeHandle_NativeOverlapped.cs
diff --git a/src/mscorlib/shared/Interop/Windows/NtDll/Interop.ZeroMemory.cs b/src/mscorlib/shared/Interop/Windows/NtDll/Interop.ZeroMemory.cs
new file mode 100644
index 0000000000..9bf7321f2a
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/NtDll/Interop.ZeroMemory.cs
@@ -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.InteropServices;
+using System.Security;
+
+internal partial class Interop
+{
+ internal partial class NtDll
+ {
+ [DllImport(Libraries.NtDll, CharSet = CharSet.Unicode, EntryPoint = "RtlZeroMemory")]
+ internal static extern void ZeroMemory(IntPtr address, UIntPtr length);
+ }
+}
diff --git a/src/mscorlib/shared/Interop/Windows/OleAut32/Interop.SysAllocStringLen.cs b/src/mscorlib/shared/Interop/Windows/OleAut32/Interop.SysAllocStringLen.cs
new file mode 100644
index 0000000000..1af2b3fce9
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/OleAut32/Interop.SysAllocStringLen.cs
@@ -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.InteropServices;
+using System.Security;
+
+internal partial class Interop
+{
+ internal partial class OleAut32
+ {
+ [DllImport(Libraries.OleAut32, CharSet = CharSet.Unicode)]
+ internal static extern SafeBSTRHandle SysAllocStringLen(IntPtr src, uint len);
+
+ [DllImport(Libraries.OleAut32, CharSet = CharSet.Unicode)]
+ internal static extern IntPtr SysAllocStringLen(String src, int len);
+ }
+}
diff --git a/src/mscorlib/shared/Interop/Windows/OleAut32/Interop.SysFreeString.cs b/src/mscorlib/shared/Interop/Windows/OleAut32/Interop.SysFreeString.cs
new file mode 100644
index 0000000000..8673cc6724
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/OleAut32/Interop.SysFreeString.cs
@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class OleAut32
+ {
+ [DllImport(Libraries.OleAut32)]
+ internal static extern void SysFreeString(IntPtr bstr);
+ }
+}
diff --git a/src/mscorlib/shared/Interop/Windows/OleAut32/Interop.SysStringLen.cs b/src/mscorlib/shared/Interop/Windows/OleAut32/Interop.SysStringLen.cs
new file mode 100644
index 0000000000..cf65d6b086
--- /dev/null
+++ b/src/mscorlib/shared/Interop/Windows/OleAut32/Interop.SysStringLen.cs
@@ -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.InteropServices;
+using System.Security;
+
+internal partial class Interop
+{
+ internal partial class OleAut32
+ {
+ [DllImport(Libraries.OleAut32)]
+ internal static extern uint SysStringLen(SafeBSTRHandle bstr);
+
+ [DllImport(Libraries.OleAut32)]
+ internal static extern uint SysStringLen(IntPtr bstr);
+ }
+}
diff --git a/src/mscorlib/shared/Microsoft/Win32/SafeHandles/CriticalHandleMinusOneIsInvalid.cs b/src/mscorlib/shared/Microsoft/Win32/SafeHandles/CriticalHandleMinusOneIsInvalid.cs
new file mode 100644
index 0000000000..a76c51d966
--- /dev/null
+++ b/src/mscorlib/shared/Microsoft/Win32/SafeHandles/CriticalHandleMinusOneIsInvalid.cs
@@ -0,0 +1,20 @@
+// 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.InteropServices;
+
+namespace Microsoft.Win32.SafeHandles
+{
+ // Class of critical handle which uses only -1 as an invalid handle.
+ public abstract class CriticalHandleMinusOneIsInvalid : CriticalHandle
+ {
+ protected CriticalHandleMinusOneIsInvalid()
+ : base(new IntPtr(-1))
+ {
+ }
+
+ public override bool IsInvalid => handle == new IntPtr(-1);
+ }
+}
diff --git a/src/mscorlib/shared/Microsoft/Win32/SafeHandles/CriticalHandleZeroOrMinusOneIsInvalid.cs b/src/mscorlib/shared/Microsoft/Win32/SafeHandles/CriticalHandleZeroOrMinusOneIsInvalid.cs
new file mode 100644
index 0000000000..195e48df76
--- /dev/null
+++ b/src/mscorlib/shared/Microsoft/Win32/SafeHandles/CriticalHandleZeroOrMinusOneIsInvalid.cs
@@ -0,0 +1,20 @@
+// 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.InteropServices;
+
+namespace Microsoft.Win32.SafeHandles
+{
+ // Class of critical handle which uses 0 or -1 as an invalid handle.
+ public abstract class CriticalHandleZeroOrMinusOneIsInvalid : CriticalHandle
+ {
+ protected CriticalHandleZeroOrMinusOneIsInvalid()
+ : base(IntPtr.Zero)
+ {
+ }
+
+ public override bool IsInvalid => handle.IsNull() || handle == new IntPtr(-1);
+ }
+}
diff --git a/src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs b/src/mscorlib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
index d13b536204..d13b536204 100644
--- a/src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
+++ b/src/mscorlib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
diff --git a/src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeFileHandle.Windows.cs b/src/mscorlib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Windows.cs
index 4eabe8f08c..4eabe8f08c 100644
--- a/src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeFileHandle.Windows.cs
+++ b/src/mscorlib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Windows.cs
diff --git a/src/mscorlib/shared/README.md b/src/mscorlib/shared/README.md
new file mode 100644
index 0000000000..d55f32576d
--- /dev/null
+++ b/src/mscorlib/shared/README.md
@@ -0,0 +1,19 @@
+# System.Private.CoreLib Shared Sources
+
+This directory contains the shared sources for System.Private.CoreLib. These are shared between [dotnet/corert](https://github.com/dotnet/corert/tree/master/src/System.Private.CoreLib/shared) and [dotnet/coreclr](https://github.com/dotnet/coreclr/tree/master/src/mscorlib/shared).
+
+The sources are synchronized with a mirroring tool that watches for new commits on either side and creates new pull requests (as @dotnet-bot) in the other repository.
+
+## Conventions
+
+Code in the shared directory should have no code specific to CoreCLR or CoreRT. Parts of classes that need to have different implementations on different runtimes should use partial classes and &#42;.CoreRT.cs/&#42;.CoreCLR.cs files in the non shared portion. Code that is different based on platform (Windows/Unix) is fine to leave in the shared portion. Remember to follow the [style guidelines](https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md).
+
+## Getting clean CI and merging the mirror PRs
+
+Once the mirror PR is created there is a chance that the new code will require changes to get a clean CI. Any changes can be added to the PR by checking out the PR branch and adding new commits. Please follow the following guidelines for modifying these PRs.
+
+ - **DO NOT** modify the commits made by @dotnet-bot in any way.
+ - **TRY** to only make changes outside of shared.
+ - Changes made in the shared folder in additional commits will get mirrored properly if the mirror PR is merged with a **REBASE**
+ - **ALWAYS** Merge the mirror PR with the **REBASE** option.
+ - Using one of the other options will cause the mirror to miss commits
diff --git a/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems
new file mode 100644
index 0000000000..6ef7fc1681
--- /dev/null
+++ b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems
@@ -0,0 +1,534 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
+ <HasSharedItems>true</HasSharedItems>
+ <SharedGUID>c5ed3c1d-b572-46f1-8f96-522a85ce1179</SharedGUID>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration">
+ <Import_RootNamespace/>
+ </PropertyGroup>
+ <PropertyGroup>
+ <TargetsWindows Condition="'$(TargetsWindows)' != 'true'">false</TargetsWindows>
+ <TargetsUnix Condition="'$(TargetsUnix)' != 'true'">false</TargetsUnix>
+ <TargetsOSX Condition="'$(TargetsOSX)' != 'true'">false</TargetsOSX>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\CriticalHandleMinusOneIsInvalid.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\CriticalHandleZeroOrMinusOneIsInvalid.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Action.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ApplicationException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ArgumentException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ArgumentNullException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ArithmeticException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ArrayTypeMismatchException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\AssemblyLoadEventArgs.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\AssemblyLoadEventHandler.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\AsyncCallback.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\AttributeTargets.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\AttributeUsageAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Buffers\ArrayPool.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Buffers\ConfigurableArrayPool.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Buffers\TlsOverPerCoreLockedStacksArrayPool.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Buffers\Utilities.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Char.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\CharEnumerator.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\CLSCompliantAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\DictionaryEntry.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\ICollection.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IComparer.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IDictionary.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IEnumerable.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IEnumerator.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IEqualityComparer.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IList.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IReadOnlyCollection.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IReadOnlyDictionary.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\IReadOnlyList.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\KeyNotFoundException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\Generic\KeyValuePair.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\ICollection.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\IComparer.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\IDictionary.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\IDictionaryEnumerator.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\IEnumerable.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\IEnumerator.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\IEqualityComparer.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\IList.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\IStructuralComparable.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Collections\IStructuralEquatable.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ComponentModel\DefaultValueAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ComponentModel\EditorBrowsableAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Configuration\Assemblies\AssemblyHashAlgorithm.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Configuration\Assemblies\AssemblyVersionCompatibility.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Convert.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\CurrentSystemTimeZone.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\DataMisalignedException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\DateTime.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\DateTimeKind.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\DateTimeOffset.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\DayOfWeek.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\DBNull.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\DefaultBinder.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\CodeAnalysis\SuppressMessageAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\ConditionalAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Debug.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\DivideByZeroException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\DuplicateWaitObjectException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\EntryPointNotFoundException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\EventArgs.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\EventHandler.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ExecutionEngineException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\FieldAccessException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\FlagsAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\FormatException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\FormattableString.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarAlgorithmType.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarWeekRule.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendricalCalculationsHelper.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\ChineseLunisolarCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureNotFoundException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureTypes.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DateTimeFormat.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DateTimeFormatInfo.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DateTimeFormatInfoScanner.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DateTimeParse.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DateTimeStyles.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DaylightTime.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DigitShapes.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\EastAsianLunisolarCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\GregorianCalendarTypes.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\HebrewCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\HebrewNumber.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\HijriCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\InternalGlobalizationHelper.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\JapaneseCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\JapaneseLunisolarCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\JulianCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\KoreanCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\KoreanLunisolarCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\NumberStyles.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\PersianCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\SortVersion.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TaiwanCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TaiwanLunisolarCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\ThaiBuddhistCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TimeSpanStyles.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\UmAlQuraCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\UnicodeCategory.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IAsyncResult.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ICloneable.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IComparable.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IConvertible.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ICustomFormatter.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IDisposable.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IEquatable.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IFormatProvider.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IFormattable.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IndexOutOfRangeException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\InsufficientExecutionStackException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\InvalidCastException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\InvalidOperationException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\InvalidProgramException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\InvalidTimeZoneException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\DirectoryNotFoundException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\EndOfStreamException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\Error.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileAccess.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileLoadException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileMode.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileNotFoundException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileOptions.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileShare.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\Path.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\PathInternal.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\PathTooLongException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\SeekOrigin.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\StreamHelpers.CopyValidation.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IObservable.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IObserver.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IProgress.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Lazy.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\MarshalByRefObject.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\MemberAccessException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\MethodAccessException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\MidpointRounding.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\MissingMethodException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\MulticastNotSupportedException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\NotFiniteNumberException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\NotImplementedException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\NotSupportedException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\NullReferenceException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ObjectDisposedException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ObsoleteAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\OverflowException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ParamArrayAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ParamsArray.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\PlatformNotSupportedException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Progress.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Random.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\RankException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AmbiguousMatchException.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\Assembly.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyAlgorithmIdAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyCompanyAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyConfigurationAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyContentType.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyCopyrightAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyCultureAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyDefaultAliasAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyDelaySignAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyDescriptionAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyFileVersionAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyFlagsAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyInformationalVersionAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyKeyFileAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyKeyNameAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyMetadataAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyNameFlags.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyProductAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblySignatureKeyAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyTitleAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyTrademarkAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\AssemblyVersionAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\Binder.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\BindingFlags.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\CallingConventions.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ConstructorInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\CustomAttributeFormatException.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\DefaultMemberAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\EventAttributes.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\EventInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ExceptionHandlingClauseOptions.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\FieldAttributes.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\FieldInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\GenericParameterAttributes.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ICustomAttributeProvider.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ImageFileMachine.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\InterfaceMapping.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\IntrospectionExtensions.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\InvalidFilterCriteriaException.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\IReflect.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\IReflectableType.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ManifestResourceInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\MemberFilter.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\MemberInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\MemberInfoSerializationHolder.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\MemberTypes.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\MethodAttributes.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\MethodBase.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\MethodImplAttributes.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\MethodInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\Missing.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\Module.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ModuleResolveEventHandler.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ObfuscateAssemblyAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ObfuscationAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ParameterAttributes.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ParameterInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ParameterModifier.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\Pointer.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\PortableExecutableKinds.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ProcessorArchitecture.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\PropertyAttributes.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\PropertyInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ReflectionContext.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ReflectionTypeLoadException.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ResourceAttributes.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\ResourceLocation.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\StrongNameKeyPair.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\TargetException.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\TargetInvocationException.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\TargetParameterCountException.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\TypeAttributes.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\TypeDelegator.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\TypeFilter.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Reflection\TypeInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\ResolveEventArgs.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\ResolveEventHandler.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Resources\IResourceReader.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Resources\MissingManifestResourceException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Resources\MissingSatelliteAssemblyException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Resources\NeutralResourcesLanguageAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Resources\ResourceTypeCode.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Resources\SatelliteContractVersionAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Resources\UltimateResourceFallbackLocation.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\AccessedThroughPropertyAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\AsyncStateMachineAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\CallerFilePathAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\CallerLineNumberAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\CallerMemberNameAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\CompilationRelaxations.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\CompilationRelaxationsAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\CompilerGeneratedAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\CompilerGlobalScopeAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\DefaultDependencyAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\DependencyAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\DisablePrivateReflectionAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\DiscardableAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\ExtensionAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\FixedAddressValueTypeAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\FixedBufferAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\FormattableStringFactory.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\IAsyncStateMachine.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\IndexerNameAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\InternalsVisibleToAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\INotifyCompletion.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\IsConst.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\IsVolatile.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\IteratorStateMachineAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\ITuple.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\LoadHint.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\MethodCodeType.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\MethodImplOptions.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\ReadOnlyAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\ReferenceAssemblyAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\RuntimeCompatibilityAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\RuntimeFeature.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\SpecialNameAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\StateMachineAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\StringFreezingAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\StrongBox.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\SuppressIldasmAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\TupleElementNamesAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\TypeForwardedFromAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\TypeForwardedToAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\UnsafeValueTypeAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\ConstrainedExecution\Cer.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\ConstrainedExecution\Consistency.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\ConstrainedExecution\ReliabilityContractAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\CallingConvention.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\CharSet.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\ComVisibleAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\ExternalException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\LayoutKind.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\StringBuffer.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\UnmanagedFunctionPointerAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\UnmanagedType.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\VarEnum.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\IDeserializationCallback.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\IFormatterConverter.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\IObjectReference.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\ISafeSerializationData.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\ISerializable.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\OnDeserializedAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\OnDeserializingAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\OnSerializedAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\OnSerializingAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\OptionalFieldAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\SafeSerializationEventArgs.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\SerializationException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\SerializationInfoEnumerator.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Serialization\StreamingContext.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Versioning\NonVersionableAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Versioning\TargetFrameworkAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\AllowPartiallyTrustedCallersAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\CryptographicException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\PartialTrustVisibilityLevel.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecureString.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecurityCriticalAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecurityCriticalScope.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecurityException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecurityRulesAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecurityRuleSet.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecuritySafeCriticalAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecurityTransparentAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecurityTreatAsSafeAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SuppressUnmanagedCodeSecurityAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\UnverifiableCodeAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\VerificationException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\StackOverflowException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\StringComparer.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\StringComparison.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\StringSplitOptions.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\SystemException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Text\ASCIIEncoding.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Text\Decoder.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Text\Encoder.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Text\EncodingInfo.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Text\EncodingNLS.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Text\EncodingProvider.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Text\Normalization.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Text\StringBuilder.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Text\UTF32Encoding.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Text\UTF8Encoding.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Text\UnicodeEncoding.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ThreadAttributes.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\AbandonedMutexException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\ApartmentState.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\AsyncLocal.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\AutoResetEvent.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\DeferredDisposableLifetime.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\EventResetMode.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\ExecutionContext.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\LazyThreadSafetyMode.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\LockRecursionException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\ManualResetEvent.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\ParameterizedThreadStart.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\SemaphoreFullException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\SendOrPostCallback.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\SynchronizationLockException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\TaskCanceledException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\TaskExtensions.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\TaskSchedulerException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\ThreadAbortException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\ThreadPriority.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\ThreadStart.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\ThreadStartException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\ThreadState.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\ThreadStateException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Timeout.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\TimeoutHelper.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\WaitHandleCannotBeOpenedException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ThreadStaticAttribute.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\TimeoutException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\TimeZone.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\TimeZoneNotFoundException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\TupleExtensions.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Type.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Type.Enum.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Type.Helpers.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\TypeAccessException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\TypeCode.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\TypeInitializationException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\TypeUnloadedException.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\UnauthorizedAccessException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\UnhandledExceptionEventArgs.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\UnhandledExceptionEventHandler.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\UnitySerializationHolder.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\ValueTuple.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Version.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Void.cs"/>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\ActivityTracker.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventActivityOptions.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventCounter.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventDescriptor.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventProvider.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventSource.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\EventSourceException.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\StubEnvironment.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\Winmeta.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\ArrayTypeInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\ConcurrentSet.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\ConcurrentSetItem.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\DataCollector.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\EmptyStruct.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\EnumerableTypeInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\EnumHelper.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\EventDataAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\EventFieldAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\EventFieldFormat.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\EventIgnoreAttribute.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\EventPayload.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\EventSourceActivity.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\EventSourceOptions.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\FieldMetadata.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\InvokeTypeInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\NameInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\PropertyAnalysis.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\PropertyValue.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\SimpleEventTypes.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\SimpleTypeInfos.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\Statics.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingDataCollector.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingDataType.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingEventSource.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingEventTraits.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingEventTypes.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingMetadataCollector.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TraceLoggingTypeInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Diagnostics\Tracing\TraceLogging\TypeAnalysis.cs" />
+ </ItemGroup>
+ <ItemGroup Condition="$(TargetsWindows)">
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\BCrypt\Interop.BCryptGenRandom.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Crypt32\Interop.CryptProtectMemory.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Interop.BOOL.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Interop.Errors.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Interop.Libraries.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.CancelIoEx.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.CloseHandle.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.CreateFile.cs" Condition="'$(IsProjectNLibrary)' != 'true'" />
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.CreateFile2.cs" Condition="'$(IsProjectNLibrary)' == 'true'" />
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FILE_INFO_BY_HANDLE_CLASS.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FileTypes.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FlushFileBuffers.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FormatMessage.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetFileInformationByHandleEx.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetFileType_SafeHandle.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetFullPathNameW.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetLongPathNameW.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetTempFileNameW.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetTempPathW.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.LockFile.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.OutputDebugString.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.ReadFile_SafeHandle_IntPtr.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.ReadFile_SafeHandle_NativeOverlapped.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SECURITY_ATTRIBUTES.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SecurityOptions.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SetEndOfFile.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SetErrorMode.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SetFilePointerEx.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.WideCharToMultiByte.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.WriteFile_SafeHandle_IntPtr.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.WriteFile_SafeHandle_NativeOverlapped.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\NtDll\Interop.ZeroMemory.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\OleAut32\Interop.SysAllocStringLen.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\OleAut32\Interop.SysFreeString.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\OleAut32\Interop.SysStringLen.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeFileHandle.Windows.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.Win32.cs" Condition="'$(IsProjectNLibrary)' != 'true'" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.Windows.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.WinRT.cs" Condition="'$(IsProjectNLibrary)' == 'true'" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStreamCompletionSource.Win32.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\Path.Windows.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\PathHelper.Windows.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\PathInternal.Windows.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\PathInternal.Windows.StringBuffer.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\Win32Marshal.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SafeBSTRHandle.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecureString.Windows.cs"/>
+ </ItemGroup>
+ <ItemGroup Condition="$(TargetsUnix)">
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\Interop.Errors.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\Interop.IOErrors.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\Interop.Libraries.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.Calendar.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.Casing.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.Idna.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.Locale.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.Normalization.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.ResultCode.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.TimeZoneInfo.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.Utils.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.Close.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.FLock.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.FSync.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.FTruncate.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.GetCwd.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.GetRandomBytes.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.LockFileRegion.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.LSeek.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.MksTemps.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.Open.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.OpenFlags.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.PathConf.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.Permissions.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.PosixFAdvise.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.Read.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.Stat.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.SysLog.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.Unlink.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.Write.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeFileHandle.Unix.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\LocaleData.Unix.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.OSX.cs" Condition="'$(TargetsOSX)' == 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.Linux.cs" Condition="'$(TargetsOSX)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.Unix.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\Path.Unix.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\PathInternal.Unix.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecureString.Unix.cs"/>
+ </ItemGroup>
+</Project>
diff --git a/src/mscorlib/shared/System.Private.CoreLib.Shared.shproj b/src/mscorlib/shared/System.Private.CoreLib.Shared.shproj
new file mode 100644
index 0000000000..af61b3b59e
--- /dev/null
+++ b/src/mscorlib/shared/System.Private.CoreLib.Shared.shproj
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>c5ed3c1d-b572-46f1-8f96-522a85ce1179</ProjectGuid>
+ <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
+ </PropertyGroup>
+ <!-- Set the properties to prevent any items from being excluded from the IDE view -->
+ <PropertyGroup>
+ <TargetsWindows>true</TargetsWindows>
+ <TargetsUnix>true</TargetsUnix>
+ <TargetsOSX>true</TargetsOSX>
+ </PropertyGroup>
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
+ <PropertyGroup />
+ <Import Project="System.Private.CoreLib.Shared.projitems" Label="Shared" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
+</Project>
diff --git a/src/mscorlib/shared/System/Action.cs b/src/mscorlib/shared/System/Action.cs
new file mode 100644
index 0000000000..b82c14d9dc
--- /dev/null
+++ b/src/mscorlib/shared/System/Action.cs
@@ -0,0 +1,35 @@
+// 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.
+
+namespace System
+{
+ public delegate void Action<in T>(T obj);
+
+ public delegate void Action();
+ public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
+ public delegate void Action<in T1, in T2, in T3>(T1 arg1, T2 arg2, T3 arg3);
+ public delegate void Action<in T1, in T2, in T3, in T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
+
+ public delegate TResult Func<out TResult>();
+ public delegate TResult Func<in T, out TResult>(T arg);
+ public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
+ public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);
+ public delegate TResult Func<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
+
+ public delegate void Action<in T1, in T2, in T3, in T4, in T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
+ public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
+ public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
+ public delegate void Action<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
+
+ public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
+ public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
+ public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
+ public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
+
+ public delegate int Comparison<in T>(T x, T y);
+
+ public delegate TOutput Converter<in TInput, out TOutput>(TInput input);
+
+ public delegate bool Predicate<in T>(T obj);
+}
diff --git a/src/mscorlib/src/System/ApplicationException.cs b/src/mscorlib/shared/System/ApplicationException.cs
index 900feb57f9..900feb57f9 100644
--- a/src/mscorlib/src/System/ApplicationException.cs
+++ b/src/mscorlib/shared/System/ApplicationException.cs
diff --git a/src/mscorlib/shared/System/ArgumentException.cs b/src/mscorlib/shared/System/ArgumentException.cs
new file mode 100644
index 0000000000..96afbe10d9
--- /dev/null
+++ b/src/mscorlib/shared/System/ArgumentException.cs
@@ -0,0 +1,97 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Exception class for invalid arguments to a method.
+**
+**
+=============================================================================*/
+
+using System.Globalization;
+using System.Runtime.Serialization;
+
+namespace System
+{
+ // The ArgumentException is thrown when an argument does not meet
+ // the contract of the method. Ideally it should give a meaningful error
+ // message describing what was wrong and which parameter is incorrect.
+ //
+ [Serializable]
+ public class ArgumentException : SystemException
+ {
+ private String _paramName;
+
+ // Creates a new ArgumentException with its message
+ // string set to the empty string.
+ public ArgumentException()
+ : base(SR.Arg_ArgumentException)
+ {
+ HResult = __HResults.COR_E_ARGUMENT;
+ }
+
+ // Creates a new ArgumentException with its message
+ // string set to message.
+ //
+ public ArgumentException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_ARGUMENT;
+ }
+
+ public ArgumentException(String message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_ARGUMENT;
+ }
+
+ public ArgumentException(String message, String paramName, Exception innerException)
+ : base(message, innerException)
+ {
+ _paramName = paramName;
+ HResult = __HResults.COR_E_ARGUMENT;
+ }
+
+ public ArgumentException(String message, String paramName)
+ : base(message)
+ {
+ _paramName = paramName;
+ HResult = __HResults.COR_E_ARGUMENT;
+ }
+
+ protected ArgumentException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ _paramName = info.GetString("ParamName");
+ }
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData(info, context);
+ info.AddValue("ParamName", _paramName, typeof(String));
+ }
+
+ public override String Message
+ {
+ get
+ {
+ String s = base.Message;
+ if (!String.IsNullOrEmpty(_paramName))
+ {
+ String resourceString = SR.Format(SR.Arg_ParamName_Name, _paramName);
+ return s + Environment.NewLine + resourceString;
+ }
+ else
+ return s;
+ }
+ }
+
+ public virtual String ParamName
+ {
+ get { return _paramName; }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/ArgumentNullException.cs b/src/mscorlib/shared/System/ArgumentNullException.cs
index 3a86223ccf..3a86223ccf 100644
--- a/src/mscorlib/src/System/ArgumentNullException.cs
+++ b/src/mscorlib/shared/System/ArgumentNullException.cs
diff --git a/src/mscorlib/src/System/ArithmeticException.cs b/src/mscorlib/shared/System/ArithmeticException.cs
index 081ba454f5..081ba454f5 100644
--- a/src/mscorlib/src/System/ArithmeticException.cs
+++ b/src/mscorlib/shared/System/ArithmeticException.cs
diff --git a/src/mscorlib/src/System/ArrayTypeMismatchException.cs b/src/mscorlib/shared/System/ArrayTypeMismatchException.cs
index 3e941fdf8e..3e941fdf8e 100644
--- a/src/mscorlib/src/System/ArrayTypeMismatchException.cs
+++ b/src/mscorlib/shared/System/ArrayTypeMismatchException.cs
diff --git a/src/mscorlib/shared/System/AssemblyLoadEventArgs.cs b/src/mscorlib/shared/System/AssemblyLoadEventArgs.cs
new file mode 100644
index 0000000000..d7e5249693
--- /dev/null
+++ b/src/mscorlib/shared/System/AssemblyLoadEventArgs.cs
@@ -0,0 +1,18 @@
+// 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.Reflection;
+
+namespace System
+{
+ public class AssemblyLoadEventArgs : EventArgs
+ {
+ public AssemblyLoadEventArgs(Assembly loadedAssembly)
+ {
+ LoadedAssembly = loadedAssembly;
+ }
+
+ public Assembly LoadedAssembly { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/AssemblyLoadEventHandler.cs b/src/mscorlib/shared/System/AssemblyLoadEventHandler.cs
new file mode 100644
index 0000000000..752379fdc7
--- /dev/null
+++ b/src/mscorlib/shared/System/AssemblyLoadEventHandler.cs
@@ -0,0 +1,8 @@
+// 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.
+
+namespace System
+{
+ public delegate void AssemblyLoadEventHandler(object sender, AssemblyLoadEventArgs args);
+}
diff --git a/src/mscorlib/src/System/AsyncCallback.cs b/src/mscorlib/shared/System/AsyncCallback.cs
index 5c49535cff..5c49535cff 100644
--- a/src/mscorlib/src/System/AsyncCallback.cs
+++ b/src/mscorlib/shared/System/AsyncCallback.cs
diff --git a/src/mscorlib/src/System/AttributeTargets.cs b/src/mscorlib/shared/System/AttributeTargets.cs
index fdfa4ab730..fdfa4ab730 100644
--- a/src/mscorlib/src/System/AttributeTargets.cs
+++ b/src/mscorlib/shared/System/AttributeTargets.cs
diff --git a/src/mscorlib/shared/System/AttributeUsageAttribute.cs b/src/mscorlib/shared/System/AttributeUsageAttribute.cs
new file mode 100644
index 0000000000..6f9aeb20f3
--- /dev/null
+++ b/src/mscorlib/shared/System/AttributeUsageAttribute.cs
@@ -0,0 +1,58 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose: The class denotes how to specify the usage of an attribute
+**
+**
+===========================================================*/
+
+using System.Reflection;
+
+namespace System
+{
+ /* By default, attributes are inherited and multiple attributes are not allowed */
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Class, Inherited = true)]
+ public sealed class AttributeUsageAttribute : Attribute
+ {
+ private AttributeTargets _attributeTarget = AttributeTargets.All; // Defaults to all
+ private bool _allowMultiple = false; // Defaults to false
+ private bool _inherited = true; // Defaults to true
+
+ internal static AttributeUsageAttribute Default = new AttributeUsageAttribute(AttributeTargets.All);
+
+ //Constructors
+ public AttributeUsageAttribute(AttributeTargets validOn)
+ {
+ _attributeTarget = validOn;
+ }
+ internal AttributeUsageAttribute(AttributeTargets validOn, bool allowMultiple, bool inherited)
+ {
+ _attributeTarget = validOn;
+ _allowMultiple = allowMultiple;
+ _inherited = inherited;
+ }
+
+ public AttributeTargets ValidOn
+ {
+ get { return _attributeTarget; }
+ }
+
+ public bool AllowMultiple
+ {
+ get { return _allowMultiple; }
+ set { _allowMultiple = value; }
+ }
+
+ public bool Inherited
+ {
+ get { return _inherited; }
+ set { _inherited = value; }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Buffers/ArrayPool.cs b/src/mscorlib/shared/System/Buffers/ArrayPool.cs
index 77a07f7fa5..77a07f7fa5 100644
--- a/src/mscorlib/corefx/System/Buffers/ArrayPool.cs
+++ b/src/mscorlib/shared/System/Buffers/ArrayPool.cs
diff --git a/src/mscorlib/corefx/System/Buffers/ConfigurableArrayPool.cs b/src/mscorlib/shared/System/Buffers/ConfigurableArrayPool.cs
index f7b6034d20..f7b6034d20 100644
--- a/src/mscorlib/corefx/System/Buffers/ConfigurableArrayPool.cs
+++ b/src/mscorlib/shared/System/Buffers/ConfigurableArrayPool.cs
diff --git a/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs b/src/mscorlib/shared/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs
index 64c5cebe85..64c5cebe85 100644
--- a/src/mscorlib/corefx/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs
+++ b/src/mscorlib/shared/System/Buffers/TlsOverPerCoreLockedStacksArrayPool.cs
diff --git a/src/mscorlib/shared/System/Buffers/Utilities.cs b/src/mscorlib/shared/System/Buffers/Utilities.cs
new file mode 100644
index 0000000000..4f115fe9dd
--- /dev/null
+++ b/src/mscorlib/shared/System/Buffers/Utilities.cs
@@ -0,0 +1,35 @@
+// 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.Diagnostics;
+using System.Runtime.CompilerServices;
+
+namespace System.Buffers
+{
+ internal static class Utilities
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static int SelectBucketIndex(int bufferSize)
+ {
+ uint bitsRemaining = ((uint)bufferSize - 1) >> 4;
+
+ int poolIndex = 0;
+ if (bitsRemaining > 0xFFFF) { bitsRemaining >>= 16; poolIndex = 16; }
+ if (bitsRemaining > 0xFF) { bitsRemaining >>= 8; poolIndex += 8; }
+ if (bitsRemaining > 0xF) { bitsRemaining >>= 4; poolIndex += 4; }
+ if (bitsRemaining > 0x3) { bitsRemaining >>= 2; poolIndex += 2; }
+ if (bitsRemaining > 0x1) { bitsRemaining >>= 1; poolIndex += 1; }
+
+ return poolIndex + (int)bitsRemaining;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static int GetMaxSizeForBucket(int binIndex)
+ {
+ int maxSize = 16 << binIndex;
+ Debug.Assert(maxSize >= 0);
+ return maxSize;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/CLSCompliantAttribute.cs b/src/mscorlib/shared/System/CLSCompliantAttribute.cs
index e03600d132..e03600d132 100644
--- a/src/mscorlib/src/System/CLSCompliantAttribute.cs
+++ b/src/mscorlib/shared/System/CLSCompliantAttribute.cs
diff --git a/src/mscorlib/shared/System/Char.cs b/src/mscorlib/shared/System/Char.cs
new file mode 100644
index 0000000000..2b3133a669
--- /dev/null
+++ b/src/mscorlib/shared/System/Char.cs
@@ -0,0 +1,1122 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose: This is the value class representing a Unicode character
+** Char methods until we create this functionality.
+**
+**
+===========================================================*/
+
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Runtime.InteropServices;
+
+namespace System
+{
+ [Serializable]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Char : IComparable, IComparable<Char>, IEquatable<Char>, IConvertible
+ {
+ //
+ // Member Variables
+ //
+ internal char m_value;
+
+ //
+ // Public Constants
+ //
+ // The maximum character value.
+ public const char MaxValue = (char)0xFFFF;
+ // The minimum character value.
+ public const char MinValue = (char)0x00;
+
+ // Unicode category values from Unicode U+0000 ~ U+00FF. Store them in byte[] array to save space.
+ private static readonly byte[] s_categoryForLatin1 = {
+ (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0000 - 0007
+ (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0008 - 000F
+ (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0010 - 0017
+ (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0018 - 001F
+ (byte)UnicodeCategory.SpaceSeparator, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.CurrencySymbol, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.OtherPunctuation, // 0020 - 0027
+ (byte)UnicodeCategory.OpenPunctuation, (byte)UnicodeCategory.ClosePunctuation, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.DashPunctuation, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.OtherPunctuation, // 0028 - 002F
+ (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, // 0030 - 0037
+ (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.OtherPunctuation, // 0038 - 003F
+ (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, // 0040 - 0047
+ (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, // 0048 - 004F
+ (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, // 0050 - 0057
+ (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.OpenPunctuation, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.ClosePunctuation, (byte)UnicodeCategory.ModifierSymbol, (byte)UnicodeCategory.ConnectorPunctuation, // 0058 - 005F
+ (byte)UnicodeCategory.ModifierSymbol, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, // 0060 - 0067
+ (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, // 0068 - 006F
+ (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, // 0070 - 0077
+ (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.OpenPunctuation, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.ClosePunctuation, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.Control, // 0078 - 007F
+ (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0080 - 0087
+ (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0088 - 008F
+ (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0090 - 0097
+ (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0098 - 009F
+ (byte)UnicodeCategory.SpaceSeparator, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.CurrencySymbol, (byte)UnicodeCategory.CurrencySymbol, (byte)UnicodeCategory.CurrencySymbol, (byte)UnicodeCategory.CurrencySymbol, (byte)UnicodeCategory.OtherSymbol, (byte)UnicodeCategory.OtherSymbol, // 00A0 - 00A7
+ (byte)UnicodeCategory.ModifierSymbol, (byte)UnicodeCategory.OtherSymbol, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.InitialQuotePunctuation, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.DashPunctuation, (byte)UnicodeCategory.OtherSymbol, (byte)UnicodeCategory.ModifierSymbol, // 00A8 - 00AF
+ (byte)UnicodeCategory.OtherSymbol, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.OtherNumber, (byte)UnicodeCategory.OtherNumber, (byte)UnicodeCategory.ModifierSymbol, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.OtherSymbol, (byte)UnicodeCategory.OtherPunctuation, // 00B0 - 00B7
+ (byte)UnicodeCategory.ModifierSymbol, (byte)UnicodeCategory.OtherNumber, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.FinalQuotePunctuation, (byte)UnicodeCategory.OtherNumber, (byte)UnicodeCategory.OtherNumber, (byte)UnicodeCategory.OtherNumber, (byte)UnicodeCategory.OtherPunctuation, // 00B8 - 00BF
+ (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, // 00C0 - 00C7
+ (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, // 00C8 - 00CF
+ (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.MathSymbol, // 00D0 - 00D7
+ (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.LowercaseLetter, // 00D8 - 00DF
+ (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, // 00E0 - 00E7
+ (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, // 00E8 - 00EF
+ (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.MathSymbol, // 00F0 - 00F7
+ (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, // 00F8 - 00FF
+ };
+
+ // Return true for all characters below or equal U+00ff, which is ASCII + Latin-1 Supplement.
+ private static bool IsLatin1(char ch)
+ {
+ return (ch <= '\x00ff');
+ }
+
+ // Return true for all characters below or equal U+007f, which is ASCII.
+ private static bool IsAscii(char ch)
+ {
+ return (ch <= '\x007f');
+ }
+
+ // Return the Unicode category for Unicode character <= 0x00ff.
+ private static UnicodeCategory GetLatin1UnicodeCategory(char ch)
+ {
+ Debug.Assert(IsLatin1(ch), "Char.GetLatin1UnicodeCategory(): ch should be <= 007f");
+ return (UnicodeCategory)(s_categoryForLatin1[(int)ch]);
+ }
+
+ //
+ // Private Constants
+ //
+
+ //
+ // Overriden Instance Methods
+ //
+
+ // Calculate a hashcode for a 2 byte Unicode character.
+ public override int GetHashCode()
+ {
+ return (int)m_value | ((int)m_value << 16);
+ }
+
+ // Used for comparing two boxed Char objects.
+ //
+ public override bool Equals(Object obj)
+ {
+ if (!(obj is Char))
+ {
+ return false;
+ }
+ return (m_value == ((Char)obj).m_value);
+ }
+
+ [System.Runtime.Versioning.NonVersionable]
+ public bool Equals(Char obj)
+ {
+ return m_value == obj;
+ }
+
+ // Compares this object to another object, returning an integer that
+ // indicates the relationship.
+ // Returns a value less than zero if this object
+ // null is considered to be less than any instance.
+ // If object is not of type Char, this method throws an ArgumentException.
+ //
+ [Pure]
+ public int CompareTo(Object value)
+ {
+ if (value == null)
+ {
+ return 1;
+ }
+ if (!(value is Char))
+ {
+ throw new ArgumentException(SR.Arg_MustBeChar);
+ }
+
+ return (m_value - ((Char)value).m_value);
+ }
+
+ [Pure]
+ public int CompareTo(Char value)
+ {
+ return (m_value - value);
+ }
+
+ // Overrides System.Object.ToString.
+ [Pure]
+ public override String ToString()
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+ return Char.ToString(m_value);
+ }
+
+ [Pure]
+ public String ToString(IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+ return Char.ToString(m_value);
+ }
+
+ //
+ // Formatting Methods
+ //
+
+ /*===================================ToString===================================
+ **This static methods takes a character and returns the String representation of it.
+ ==============================================================================*/
+ // Provides a string representation of a character.
+ [Pure]
+ public static string ToString(char c) => string.CreateFromChar(c);
+
+ public static char Parse(String s)
+ {
+ if (s == null)
+ {
+ throw new ArgumentNullException(nameof(s));
+ }
+ Contract.EndContractBlock();
+
+ if (s.Length != 1)
+ {
+ throw new FormatException(SR.Format_NeedSingleChar);
+ }
+ return s[0];
+ }
+
+ public static bool TryParse(String s, out Char result)
+ {
+ result = '\0';
+ if (s == null)
+ {
+ return false;
+ }
+ if (s.Length != 1)
+ {
+ return false;
+ }
+ result = s[0];
+ return true;
+ }
+
+ //
+ // Static Methods
+ //
+ /*=================================ISDIGIT======================================
+ **A wrapper for Char. Returns a boolean indicating whether **
+ **character c is considered to be a digit. **
+ ==============================================================================*/
+ // Determines whether a character is a digit.
+ [Pure]
+ public static bool IsDigit(char c)
+ {
+ if (IsLatin1(c))
+ {
+ return (c >= '0' && c <= '9');
+ }
+ return (CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber);
+ }
+
+
+ /*=================================CheckLetter=====================================
+ ** Check if the specified UnicodeCategory belongs to the letter categories.
+ ==============================================================================*/
+ internal static bool CheckLetter(UnicodeCategory uc)
+ {
+ switch (uc)
+ {
+ case (UnicodeCategory.UppercaseLetter):
+ case (UnicodeCategory.LowercaseLetter):
+ case (UnicodeCategory.TitlecaseLetter):
+ case (UnicodeCategory.ModifierLetter):
+ case (UnicodeCategory.OtherLetter):
+ return (true);
+ }
+ return (false);
+ }
+
+ /*=================================ISLETTER=====================================
+ **A wrapper for Char. Returns a boolean indicating whether **
+ **character c is considered to be a letter. **
+ ==============================================================================*/
+ // Determines whether a character is a letter.
+ [Pure]
+ public static bool IsLetter(char c)
+ {
+ if (IsLatin1(c))
+ {
+ if (IsAscii(c))
+ {
+ c |= (char)0x20;
+ return ((c >= 'a' && c <= 'z'));
+ }
+ return (CheckLetter(GetLatin1UnicodeCategory(c)));
+ }
+ return (CheckLetter(CharUnicodeInfo.GetUnicodeCategory(c)));
+ }
+
+ private static bool IsWhiteSpaceLatin1(char c)
+ {
+ // There are characters which belong to UnicodeCategory.Control but are considered as white spaces.
+ // We use code point comparisons for these characters here as a temporary fix.
+
+ // U+0009 = <control> HORIZONTAL TAB
+ // U+000a = <control> LINE FEED
+ // U+000b = <control> VERTICAL TAB
+ // U+000c = <contorl> FORM FEED
+ // U+000d = <control> CARRIAGE RETURN
+ // U+0085 = <control> NEXT LINE
+ // U+00a0 = NO-BREAK SPACE
+ if ((c == ' ') || (c >= '\x0009' && c <= '\x000d') || c == '\x00a0' || c == '\x0085')
+ {
+ return (true);
+ }
+ return (false);
+ }
+
+ /*===============================ISWHITESPACE===================================
+ **A wrapper for Char. Returns a boolean indicating whether **
+ **character c is considered to be a whitespace character. **
+ ==============================================================================*/
+ // Determines whether a character is whitespace.
+ [Pure]
+ public static bool IsWhiteSpace(char c)
+ {
+ if (IsLatin1(c))
+ {
+ return (IsWhiteSpaceLatin1(c));
+ }
+ return CharUnicodeInfo.IsWhiteSpace(c);
+ }
+
+
+ /*===================================IsUpper====================================
+ **Arguments: c -- the characater to be checked.
+ **Returns: True if c is an uppercase character.
+ ==============================================================================*/
+ // Determines whether a character is upper-case.
+ [Pure]
+ public static bool IsUpper(char c)
+ {
+ if (IsLatin1(c))
+ {
+ if (IsAscii(c))
+ {
+ return (c >= 'A' && c <= 'Z');
+ }
+ return (GetLatin1UnicodeCategory(c) == UnicodeCategory.UppercaseLetter);
+ }
+ return (CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.UppercaseLetter);
+ }
+
+ /*===================================IsLower====================================
+ **Arguments: c -- the characater to be checked.
+ **Returns: True if c is an lowercase character.
+ ==============================================================================*/
+ // Determines whether a character is lower-case.
+ [Pure]
+ public static bool IsLower(char c)
+ {
+ if (IsLatin1(c))
+ {
+ if (IsAscii(c))
+ {
+ return (c >= 'a' && c <= 'z');
+ }
+ return (GetLatin1UnicodeCategory(c) == UnicodeCategory.LowercaseLetter);
+ }
+ return (CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.LowercaseLetter);
+ }
+
+ internal static bool CheckPunctuation(UnicodeCategory uc)
+ {
+ switch (uc)
+ {
+ case UnicodeCategory.ConnectorPunctuation:
+ case UnicodeCategory.DashPunctuation:
+ case UnicodeCategory.OpenPunctuation:
+ case UnicodeCategory.ClosePunctuation:
+ case UnicodeCategory.InitialQuotePunctuation:
+ case UnicodeCategory.FinalQuotePunctuation:
+ case UnicodeCategory.OtherPunctuation:
+ return (true);
+ }
+ return (false);
+ }
+
+
+ /*================================IsPunctuation=================================
+ **Arguments: c -- the characater to be checked.
+ **Returns: True if c is an punctuation mark
+ ==============================================================================*/
+ // Determines whether a character is a punctuation mark.
+ [Pure]
+ public static bool IsPunctuation(char c)
+ {
+ if (IsLatin1(c))
+ {
+ return (CheckPunctuation(GetLatin1UnicodeCategory(c)));
+ }
+ return (CheckPunctuation(CharUnicodeInfo.GetUnicodeCategory(c)));
+ }
+
+ /*=================================CheckLetterOrDigit=====================================
+ ** Check if the specified UnicodeCategory belongs to the letter or digit categories.
+ ==============================================================================*/
+ internal static bool CheckLetterOrDigit(UnicodeCategory uc)
+ {
+ switch (uc)
+ {
+ case UnicodeCategory.UppercaseLetter:
+ case UnicodeCategory.LowercaseLetter:
+ case UnicodeCategory.TitlecaseLetter:
+ case UnicodeCategory.ModifierLetter:
+ case UnicodeCategory.OtherLetter:
+ case UnicodeCategory.DecimalDigitNumber:
+ return (true);
+ }
+ return (false);
+ }
+
+ // Determines whether a character is a letter or a digit.
+ [Pure]
+ public static bool IsLetterOrDigit(char c)
+ {
+ if (IsLatin1(c))
+ {
+ return (CheckLetterOrDigit(GetLatin1UnicodeCategory(c)));
+ }
+ return (CheckLetterOrDigit(CharUnicodeInfo.GetUnicodeCategory(c)));
+ }
+
+ /*===================================ToUpper====================================
+ **
+ ==============================================================================*/
+ // Converts a character to upper-case for the specified culture.
+ // <;<;Not fully implemented>;>;
+ public static char ToUpper(char c, CultureInfo culture)
+ {
+ if (culture == null)
+ throw new ArgumentNullException(nameof(culture));
+ Contract.EndContractBlock();
+ return culture.TextInfo.ToUpper(c);
+ }
+
+ /*=================================TOUPPER======================================
+ **A wrapper for Char.toUpperCase. Converts character c to its **
+ **uppercase equivalent. If c is already an uppercase character or is not an **
+ **alphabetic, nothing happens. **
+ ==============================================================================*/
+ // Converts a character to upper-case for the default culture.
+ //
+ public static char ToUpper(char c)
+ {
+ return ToUpper(c, CultureInfo.CurrentCulture);
+ }
+
+
+ // Converts a character to upper-case for invariant culture.
+ public static char ToUpperInvariant(char c)
+ {
+ return ToUpper(c, CultureInfo.InvariantCulture);
+ }
+
+
+ /*===================================ToLower====================================
+ **
+ ==============================================================================*/
+ // Converts a character to lower-case for the specified culture.
+ // <;<;Not fully implemented>;>;
+ public static char ToLower(char c, CultureInfo culture)
+ {
+ if (culture == null)
+ throw new ArgumentNullException(nameof(culture));
+ Contract.EndContractBlock();
+ return culture.TextInfo.ToLower(c);
+ }
+
+ /*=================================TOLOWER======================================
+ **A wrapper for Char.toLowerCase. Converts character c to its **
+ **lowercase equivalent. If c is already a lowercase character or is not an **
+ **alphabetic, nothing happens. **
+ ==============================================================================*/
+ // Converts a character to lower-case for the default culture.
+ public static char ToLower(char c)
+ {
+ return ToLower(c, CultureInfo.CurrentCulture);
+ }
+
+
+ // Converts a character to lower-case for invariant culture.
+ public static char ToLowerInvariant(char c)
+ {
+ return ToLower(c, CultureInfo.InvariantCulture);
+ }
+
+
+ //
+ // IConvertible implementation
+ //
+ [Pure]
+ public TypeCode GetTypeCode()
+ {
+ return TypeCode.Char;
+ }
+
+
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Char", "Boolean"));
+ }
+
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
+ return m_value;
+ }
+
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
+ return Convert.ToSByte(m_value);
+ }
+
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
+ return Convert.ToByte(m_value);
+ }
+
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
+ return Convert.ToInt16(m_value);
+ }
+
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
+ return Convert.ToUInt16(m_value);
+ }
+
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
+ return Convert.ToInt32(m_value);
+ }
+
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
+ return Convert.ToUInt32(m_value);
+ }
+
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
+ return Convert.ToInt64(m_value);
+ }
+
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
+ return Convert.ToUInt64(m_value);
+ }
+
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Char", "Single"));
+ }
+
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Char", "Double"));
+ }
+
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Char", "Decimal"));
+ }
+
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Char", "DateTime"));
+ }
+
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
+ return Convert.DefaultToType((IConvertible)this, type, provider);
+ }
+ public static bool IsControl(char c)
+ {
+ if (IsLatin1(c))
+ {
+ return (GetLatin1UnicodeCategory(c) == UnicodeCategory.Control);
+ }
+ return (CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.Control);
+ }
+
+ public static bool IsControl(String s, int index)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+ if (((uint)index) >= ((uint)s.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ char c = s[index];
+ if (IsLatin1(c))
+ {
+ return (GetLatin1UnicodeCategory(c) == UnicodeCategory.Control);
+ }
+ return (CharUnicodeInfo.GetUnicodeCategory(s, index) == UnicodeCategory.Control);
+ }
+
+
+ public static bool IsDigit(String s, int index)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+ if (((uint)index) >= ((uint)s.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ char c = s[index];
+ if (IsLatin1(c))
+ {
+ return (c >= '0' && c <= '9');
+ }
+ return (CharUnicodeInfo.GetUnicodeCategory(s, index) == UnicodeCategory.DecimalDigitNumber);
+ }
+
+ public static bool IsLetter(String s, int index)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+ if (((uint)index) >= ((uint)s.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ char c = s[index];
+ if (IsLatin1(c))
+ {
+ if (IsAscii(c))
+ {
+ c |= (char)0x20;
+ return ((c >= 'a' && c <= 'z'));
+ }
+ return (CheckLetter(GetLatin1UnicodeCategory(c)));
+ }
+ return (CheckLetter(CharUnicodeInfo.GetUnicodeCategory(s, index)));
+ }
+
+ public static bool IsLetterOrDigit(String s, int index)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+ if (((uint)index) >= ((uint)s.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ char c = s[index];
+ if (IsLatin1(c))
+ {
+ return CheckLetterOrDigit(GetLatin1UnicodeCategory(c));
+ }
+ return CheckLetterOrDigit(CharUnicodeInfo.GetUnicodeCategory(s, index));
+ }
+
+ public static bool IsLower(String s, int index)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+ if (((uint)index) >= ((uint)s.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ char c = s[index];
+ if (IsLatin1(c))
+ {
+ if (IsAscii(c))
+ {
+ return (c >= 'a' && c <= 'z');
+ }
+ return (GetLatin1UnicodeCategory(c) == UnicodeCategory.LowercaseLetter);
+ }
+
+ return (CharUnicodeInfo.GetUnicodeCategory(s, index) == UnicodeCategory.LowercaseLetter);
+ }
+
+ /*=================================CheckNumber=====================================
+ ** Check if the specified UnicodeCategory belongs to the number categories.
+ ==============================================================================*/
+
+ internal static bool CheckNumber(UnicodeCategory uc)
+ {
+ switch (uc)
+ {
+ case (UnicodeCategory.DecimalDigitNumber):
+ case (UnicodeCategory.LetterNumber):
+ case (UnicodeCategory.OtherNumber):
+ return (true);
+ }
+ return (false);
+ }
+
+ public static bool IsNumber(char c)
+ {
+ if (IsLatin1(c))
+ {
+ if (IsAscii(c))
+ {
+ return (c >= '0' && c <= '9');
+ }
+ return (CheckNumber(GetLatin1UnicodeCategory(c)));
+ }
+ return (CheckNumber(CharUnicodeInfo.GetUnicodeCategory(c)));
+ }
+
+ public static bool IsNumber(String s, int index)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+ if (((uint)index) >= ((uint)s.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ char c = s[index];
+ if (IsLatin1(c))
+ {
+ if (IsAscii(c))
+ {
+ return (c >= '0' && c <= '9');
+ }
+ return (CheckNumber(GetLatin1UnicodeCategory(c)));
+ }
+ return (CheckNumber(CharUnicodeInfo.GetUnicodeCategory(s, index)));
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // IsPunctuation
+ //
+ // Determines if the given character is a punctuation character.
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ public static bool IsPunctuation(String s, int index)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+ if (((uint)index) >= ((uint)s.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ char c = s[index];
+ if (IsLatin1(c))
+ {
+ return (CheckPunctuation(GetLatin1UnicodeCategory(c)));
+ }
+ return (CheckPunctuation(CharUnicodeInfo.GetUnicodeCategory(s, index)));
+ }
+
+
+ /*================================= CheckSeparator ============================
+ ** Check if the specified UnicodeCategory belongs to the seprator categories.
+ ==============================================================================*/
+
+ internal static bool CheckSeparator(UnicodeCategory uc)
+ {
+ switch (uc)
+ {
+ case UnicodeCategory.SpaceSeparator:
+ case UnicodeCategory.LineSeparator:
+ case UnicodeCategory.ParagraphSeparator:
+ return (true);
+ }
+ return (false);
+ }
+
+ private static bool IsSeparatorLatin1(char c)
+ {
+ // U+00a0 = NO-BREAK SPACE
+ // There is no LineSeparator or ParagraphSeparator in Latin 1 range.
+ return (c == '\x0020' || c == '\x00a0');
+ }
+
+ public static bool IsSeparator(char c)
+ {
+ if (IsLatin1(c))
+ {
+ return (IsSeparatorLatin1(c));
+ }
+ return (CheckSeparator(CharUnicodeInfo.GetUnicodeCategory(c)));
+ }
+
+ public static bool IsSeparator(String s, int index)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+ if (((uint)index) >= ((uint)s.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ char c = s[index];
+ if (IsLatin1(c))
+ {
+ return (IsSeparatorLatin1(c));
+ }
+ return (CheckSeparator(CharUnicodeInfo.GetUnicodeCategory(s, index)));
+ }
+
+ [Pure]
+ public static bool IsSurrogate(char c)
+ {
+ return (c >= HIGH_SURROGATE_START && c <= LOW_SURROGATE_END);
+ }
+
+ [Pure]
+ public static bool IsSurrogate(String s, int index)
+ {
+ if (s == null)
+ {
+ throw new ArgumentNullException(nameof(s));
+ }
+ if (((uint)index) >= ((uint)s.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ return (IsSurrogate(s[index]));
+ }
+
+ /*================================= CheckSymbol ============================
+ ** Check if the specified UnicodeCategory belongs to the symbol categories.
+ ==============================================================================*/
+
+ internal static bool CheckSymbol(UnicodeCategory uc)
+ {
+ switch (uc)
+ {
+ case (UnicodeCategory.MathSymbol):
+ case (UnicodeCategory.CurrencySymbol):
+ case (UnicodeCategory.ModifierSymbol):
+ case (UnicodeCategory.OtherSymbol):
+ return (true);
+ }
+ return (false);
+ }
+
+ public static bool IsSymbol(char c)
+ {
+ if (IsLatin1(c))
+ {
+ return (CheckSymbol(GetLatin1UnicodeCategory(c)));
+ }
+ return (CheckSymbol(CharUnicodeInfo.GetUnicodeCategory(c)));
+ }
+
+ public static bool IsSymbol(String s, int index)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+ if (((uint)index) >= ((uint)s.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ char c = s[index];
+ if (IsLatin1(c))
+ {
+ return (CheckSymbol(GetLatin1UnicodeCategory(c)));
+ }
+ return (CheckSymbol(CharUnicodeInfo.GetUnicodeCategory(s, index)));
+ }
+
+
+ public static bool IsUpper(String s, int index)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+ if (((uint)index) >= ((uint)s.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ char c = s[index];
+ if (IsLatin1(c))
+ {
+ if (IsAscii(c))
+ {
+ return (c >= 'A' && c <= 'Z');
+ }
+ return (GetLatin1UnicodeCategory(c) == UnicodeCategory.UppercaseLetter);
+ }
+
+ return (CharUnicodeInfo.GetUnicodeCategory(s, index) == UnicodeCategory.UppercaseLetter);
+ }
+
+ public static bool IsWhiteSpace(String s, int index)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+ if (((uint)index) >= ((uint)s.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+
+ if (IsLatin1(s[index]))
+ {
+ return IsWhiteSpaceLatin1(s[index]);
+ }
+
+ return CharUnicodeInfo.IsWhiteSpace(s, index);
+ }
+
+ public static UnicodeCategory GetUnicodeCategory(char c)
+ {
+ if (IsLatin1(c))
+ {
+ return (GetLatin1UnicodeCategory(c));
+ }
+ return CharUnicodeInfo.InternalGetUnicodeCategory(c);
+ }
+
+ public static UnicodeCategory GetUnicodeCategory(String s, int index)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+ if (((uint)index) >= ((uint)s.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ if (IsLatin1(s[index]))
+ {
+ return (GetLatin1UnicodeCategory(s[index]));
+ }
+ return CharUnicodeInfo.InternalGetUnicodeCategory(s, index);
+ }
+
+ public static double GetNumericValue(char c)
+ {
+ return CharUnicodeInfo.GetNumericValue(c);
+ }
+
+ public static double GetNumericValue(String s, int index)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+ if (((uint)index) >= ((uint)s.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ return CharUnicodeInfo.GetNumericValue(s, index);
+ }
+
+
+ /*================================= IsHighSurrogate ============================
+ ** Check if a char is a high surrogate.
+ ==============================================================================*/
+ [Pure]
+ public static bool IsHighSurrogate(char c)
+ {
+ return ((c >= CharUnicodeInfo.HIGH_SURROGATE_START) && (c <= CharUnicodeInfo.HIGH_SURROGATE_END));
+ }
+
+ [Pure]
+ public static bool IsHighSurrogate(String s, int index)
+ {
+ if (s == null)
+ {
+ throw new ArgumentNullException(nameof(s));
+ }
+ if (index < 0 || index >= s.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ return (IsHighSurrogate(s[index]));
+ }
+
+ /*================================= IsLowSurrogate ============================
+ ** Check if a char is a low surrogate.
+ ==============================================================================*/
+ [Pure]
+ public static bool IsLowSurrogate(char c)
+ {
+ return ((c >= CharUnicodeInfo.LOW_SURROGATE_START) && (c <= CharUnicodeInfo.LOW_SURROGATE_END));
+ }
+
+ [Pure]
+ public static bool IsLowSurrogate(String s, int index)
+ {
+ if (s == null)
+ {
+ throw new ArgumentNullException(nameof(s));
+ }
+ if (index < 0 || index >= s.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ return (IsLowSurrogate(s[index]));
+ }
+
+ /*================================= IsSurrogatePair ============================
+ ** Check if the string specified by the index starts with a surrogate pair.
+ ==============================================================================*/
+ [Pure]
+ public static bool IsSurrogatePair(String s, int index)
+ {
+ if (s == null)
+ {
+ throw new ArgumentNullException(nameof(s));
+ }
+ if (index < 0 || index >= s.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+ Contract.EndContractBlock();
+ if (index + 1 < s.Length)
+ {
+ return (IsSurrogatePair(s[index], s[index + 1]));
+ }
+ return (false);
+ }
+
+ [Pure]
+ public static bool IsSurrogatePair(char highSurrogate, char lowSurrogate)
+ {
+ return ((highSurrogate >= CharUnicodeInfo.HIGH_SURROGATE_START && highSurrogate <= CharUnicodeInfo.HIGH_SURROGATE_END) &&
+ (lowSurrogate >= CharUnicodeInfo.LOW_SURROGATE_START && lowSurrogate <= CharUnicodeInfo.LOW_SURROGATE_END));
+ }
+
+ internal const int UNICODE_PLANE00_END = 0x00ffff;
+ // The starting codepoint for Unicode plane 1. Plane 1 contains 0x010000 ~ 0x01ffff.
+ internal const int UNICODE_PLANE01_START = 0x10000;
+ // The end codepoint for Unicode plane 16. This is the maximum code point value allowed for Unicode.
+ // Plane 16 contains 0x100000 ~ 0x10ffff.
+ internal const int UNICODE_PLANE16_END = 0x10ffff;
+
+ internal const int HIGH_SURROGATE_START = 0x00d800;
+ internal const int LOW_SURROGATE_END = 0x00dfff;
+
+
+
+ /*================================= ConvertFromUtf32 ============================
+ ** Convert an UTF32 value into a surrogate pair.
+ ==============================================================================*/
+
+ public static String ConvertFromUtf32(int utf32)
+ {
+ // For UTF32 values from U+00D800 ~ U+00DFFF, we should throw. They
+ // are considered as irregular code unit sequence, but they are not illegal.
+ if ((utf32 < 0 || utf32 > UNICODE_PLANE16_END) || (utf32 >= HIGH_SURROGATE_START && utf32 <= LOW_SURROGATE_END))
+ {
+ throw new ArgumentOutOfRangeException(nameof(utf32), SR.ArgumentOutOfRange_InvalidUTF32);
+ }
+ Contract.EndContractBlock();
+
+ if (utf32 < UNICODE_PLANE01_START)
+ {
+ // This is a BMP character.
+ return (Char.ToString((char)utf32));
+ }
+
+ unsafe
+ {
+ // This is a supplementary character. Convert it to a surrogate pair in UTF-16.
+ utf32 -= UNICODE_PLANE01_START;
+ uint surrogate = 0; // allocate 2 chars worth of stack space
+ char* address = (char*)&surrogate;
+ address[0] = (char)((utf32 / 0x400) + (int)CharUnicodeInfo.HIGH_SURROGATE_START);
+ address[1] = (char)((utf32 % 0x400) + (int)CharUnicodeInfo.LOW_SURROGATE_START);
+ return new string(address, 0, 2);
+ }
+ }
+
+
+ /*=============================ConvertToUtf32===================================
+ ** Convert a surrogate pair to UTF32 value
+ ==============================================================================*/
+
+ public static int ConvertToUtf32(char highSurrogate, char lowSurrogate)
+ {
+ if (!IsHighSurrogate(highSurrogate))
+ {
+ throw new ArgumentOutOfRangeException(nameof(highSurrogate), SR.ArgumentOutOfRange_InvalidHighSurrogate);
+ }
+ if (!IsLowSurrogate(lowSurrogate))
+ {
+ throw new ArgumentOutOfRangeException(nameof(lowSurrogate), SR.ArgumentOutOfRange_InvalidLowSurrogate);
+ }
+ Contract.EndContractBlock();
+ return (((highSurrogate - CharUnicodeInfo.HIGH_SURROGATE_START) * 0x400) + (lowSurrogate - CharUnicodeInfo.LOW_SURROGATE_START) + UNICODE_PLANE01_START);
+ }
+
+ /*=============================ConvertToUtf32===================================
+ ** Convert a character or a surrogate pair starting at index of the specified string
+ ** to UTF32 value.
+ ** The char pointed by index should be a surrogate pair or a BMP character.
+ ** This method throws if a high-surrogate is not followed by a low surrogate.
+ ** This method throws if a low surrogate is seen without preceding a high-surrogate.
+ ==============================================================================*/
+
+ public static int ConvertToUtf32(String s, int index)
+ {
+ if (s == null)
+ {
+ throw new ArgumentNullException(nameof(s));
+ }
+
+ if (index < 0 || index >= s.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
+ }
+ Contract.EndContractBlock();
+ // Check if the character at index is a high surrogate.
+ int temp1 = (int)s[index] - CharUnicodeInfo.HIGH_SURROGATE_START;
+ if (temp1 >= 0 && temp1 <= 0x7ff)
+ {
+ // Found a surrogate char.
+ if (temp1 <= 0x3ff)
+ {
+ // Found a high surrogate.
+ if (index < s.Length - 1)
+ {
+ int temp2 = (int)s[index + 1] - CharUnicodeInfo.LOW_SURROGATE_START;
+ if (temp2 >= 0 && temp2 <= 0x3ff)
+ {
+ // Found a low surrogate.
+ return ((temp1 * 0x400) + temp2 + UNICODE_PLANE01_START);
+ }
+ else
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidHighSurrogate, index), nameof(s));
+ }
+ }
+ else
+ {
+ // Found a high surrogate at the end of the string.
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidHighSurrogate, index), nameof(s));
+ }
+ }
+ else
+ {
+ // Find a low surrogate at the character pointed by index.
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidLowSurrogate, index), nameof(s));
+ }
+ }
+ // Not a high-surrogate or low-surrogate. Genereate the UTF32 value for the BMP characters.
+ return ((int)s[index]);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/CharEnumerator.cs b/src/mscorlib/shared/System/CharEnumerator.cs
new file mode 100644
index 0000000000..ea9915a7c4
--- /dev/null
+++ b/src/mscorlib/shared/System/CharEnumerator.cs
@@ -0,0 +1,80 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose: Enumerates the characters on a string. skips range
+** checks.
+**
+**
+============================================================*/
+
+using System.Collections;
+using System.Collections.Generic;
+
+namespace System
+{
+ public sealed class CharEnumerator : IEnumerator, IEnumerator<char>, IDisposable, ICloneable
+ {
+ private String _str;
+ private int _index;
+ private char _currentElement;
+
+ internal CharEnumerator(String str)
+ {
+ _str = str;
+ _index = -1;
+ }
+
+ public object Clone()
+ {
+ return MemberwiseClone();
+ }
+
+ public bool MoveNext()
+ {
+ if (_index < (_str.Length - 1))
+ {
+ _index++;
+ _currentElement = _str[_index];
+ return true;
+ }
+ else
+ _index = _str.Length;
+ return false;
+ }
+
+ public void Dispose()
+ {
+ if (_str != null)
+ _index = _str.Length;
+ _str = null;
+ }
+
+ Object IEnumerator.Current
+ {
+ get { return Current; }
+ }
+
+ public char Current
+ {
+ get
+ {
+ if (_index == -1)
+ throw new InvalidOperationException(SR.InvalidOperation_EnumNotStarted);
+ if (_index >= _str.Length)
+ throw new InvalidOperationException(SR.InvalidOperation_EnumEnded);
+ return _currentElement;
+ }
+ }
+
+ public void Reset()
+ {
+ _currentElement = (char)0;
+ _index = -1;
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/DictionaryEntry.cs b/src/mscorlib/shared/System/Collections/DictionaryEntry.cs
new file mode 100644
index 0000000000..290306d006
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/DictionaryEntry.cs
@@ -0,0 +1,58 @@
+// 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.ComponentModel;
+
+namespace System.Collections
+{
+ // A DictionaryEntry holds a key and a value from a dictionary.
+ // It is returned by IDictionaryEnumerator::GetEntry().
+ [Serializable]
+ public struct DictionaryEntry
+ {
+ private Object _key;
+ private Object _value;
+
+ // Constructs a new DictionaryEnumerator by setting the Key
+ // and Value fields appropriately.
+ public DictionaryEntry(Object key, Object value)
+ {
+ _key = key;
+ _value = value;
+ }
+
+ public Object Key
+ {
+ get
+ {
+ return _key;
+ }
+
+ set
+ {
+ _key = value;
+ }
+ }
+
+ public Object Value
+ {
+ get
+ {
+ return _value;
+ }
+
+ set
+ {
+ _value = value;
+ }
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void Deconstruct(out object key, out object value)
+ {
+ key = Key;
+ value = Value;
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/Generic/ICollection.cs b/src/mscorlib/shared/System/Collections/Generic/ICollection.cs
new file mode 100644
index 0000000000..52852aa1fb
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/Generic/ICollection.cs
@@ -0,0 +1,35 @@
+// 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.Diagnostics.Contracts;
+
+namespace System.Collections.Generic
+{
+ // Base interface for all collections, defining enumerators, size, and
+ // synchronization methods.
+ public interface ICollection<T> : IEnumerable<T>
+ {
+ // Number of items in the collections.
+ int Count { get; }
+
+ bool IsReadOnly { get; }
+
+ void Add(T item);
+
+ void Clear();
+
+ bool Contains(T item);
+
+ // CopyTo copies a collection into an Array, starting at a particular
+ // index into the array.
+ //
+ void CopyTo(T[] array, int arrayIndex);
+
+ //void CopyTo(int sourceIndex, T[] destinationArray, int destinationIndex, int count);
+
+ bool Remove(T item);
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/Generic/IComparer.cs b/src/mscorlib/shared/System/Collections/Generic/IComparer.cs
new file mode 100644
index 0000000000..713d499cc8
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/Generic/IComparer.cs
@@ -0,0 +1,20 @@
+// 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;
+
+namespace System.Collections.Generic
+{
+ // The generic IComparer interface implements a method that compares
+ // two objects. It is used in conjunction with the Sort and
+ // BinarySearch methods on the Array, List, and SortedList classes.
+ public interface IComparer<in T>
+ {
+ // Compares two objects. An implementation of this method must return a
+ // value less than zero if x is less than y, zero if x is equal to y, or a
+ // value greater than zero if x is greater than y.
+ //
+ int Compare(T x, T y);
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/Generic/IDictionary.cs b/src/mscorlib/shared/System/Collections/Generic/IDictionary.cs
new file mode 100644
index 0000000000..a73a2f55bd
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/Generic/IDictionary.cs
@@ -0,0 +1,51 @@
+// 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.Diagnostics.Contracts;
+
+namespace System.Collections.Generic
+{
+ // An IDictionary is a possibly unordered set of key-value pairs.
+ // Keys can be any non-null object. Values can be any object.
+ // You can look up a value in an IDictionary via the default indexed
+ // property, Items.
+ public interface IDictionary<TKey, TValue> : ICollection<KeyValuePair<TKey, TValue>>
+ {
+ // Interfaces are not serializable
+ // The Item property provides methods to read and edit entries
+ // in the Dictionary.
+ TValue this[TKey key]
+ {
+ get;
+ set;
+ }
+
+ // Returns a collections of the keys in this dictionary.
+ ICollection<TKey> Keys
+ {
+ get;
+ }
+
+ // Returns a collections of the values in this dictionary.
+ ICollection<TValue> Values
+ {
+ get;
+ }
+
+ // Returns whether this dictionary contains a particular key.
+ //
+ bool ContainsKey(TKey key);
+
+ // Adds a key-value pair to the dictionary.
+ //
+ void Add(TKey key, TValue value);
+
+ // Removes a particular key from the dictionary.
+ //
+ bool Remove(TKey key);
+
+ bool TryGetValue(TKey key, out TValue value);
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/Generic/IEnumerable.cs b/src/mscorlib/shared/System/Collections/Generic/IEnumerable.cs
new file mode 100644
index 0000000000..84264d5cf0
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/Generic/IEnumerable.cs
@@ -0,0 +1,21 @@
+// 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.Collections;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.Contracts;
+
+namespace System.Collections.Generic
+{
+ // Implement this interface if you need to support foreach semantics.
+ public interface IEnumerable<out T> : IEnumerable
+ {
+ // Returns an IEnumerator for this enumerable Object. The enumerator provides
+ // a simple way to access all the contents of a collection.
+ /// <include file='doc\IEnumerable.uex' path='docs/doc[@for="IEnumerable.GetEnumerator"]/*' />
+ new IEnumerator<T> GetEnumerator();
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/Generic/IEnumerator.cs b/src/mscorlib/shared/System/Collections/Generic/IEnumerator.cs
new file mode 100644
index 0000000000..6360576974
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/Generic/IEnumerator.cs
@@ -0,0 +1,26 @@
+// 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.InteropServices;
+
+namespace System.Collections.Generic
+{
+ // Base interface for all generic enumerators, providing a simple approach
+ // to iterating over a collection.
+ public interface IEnumerator<out T> : IDisposable, IEnumerator
+ {
+ // Returns the current element of the enumeration. The returned value is
+ // undefined before the first call to MoveNext and following a
+ // call to MoveNext that returned false. Multiple calls to
+ // GetCurrent with no intervening calls to MoveNext
+ // will return the same object.
+ //
+ /// <include file='doc\IEnumerator.uex' path='docs/doc[@for="IEnumerator.Current"]/*' />
+ new T Current
+ {
+ get;
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/Generic/IEqualityComparer.cs b/src/mscorlib/shared/System/Collections/Generic/IEqualityComparer.cs
new file mode 100644
index 0000000000..543bdb5fce
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/Generic/IEqualityComparer.cs
@@ -0,0 +1,18 @@
+// 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;
+
+namespace System.Collections.Generic
+{
+ // The generic IEqualityComparer interface implements methods to if check two objects are equal
+ // and generate Hashcode for an object.
+ // It is use in Dictionary class.
+ public interface IEqualityComparer<in T>
+ {
+ bool Equals(T x, T y);
+ int GetHashCode(T obj);
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Collections/Generic/IList.cs b/src/mscorlib/shared/System/Collections/Generic/IList.cs
new file mode 100644
index 0000000000..43d6659da9
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/Generic/IList.cs
@@ -0,0 +1,37 @@
+// 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.Collections;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.Contracts;
+
+namespace System.Collections.Generic
+{
+ // An IList is an ordered collection of objects. The exact ordering
+ // is up to the implementation of the list, ranging from a sorted
+ // order to insertion order.
+ public interface IList<T> : ICollection<T>
+ {
+ // The Item property provides methods to read and edit entries in the List.
+ T this[int index]
+ {
+ get;
+ set;
+ }
+
+ // Returns the index of a particular item, if it is in the list.
+ // Returns -1 if the item isn't in the list.
+ int IndexOf(T item);
+
+ // Inserts value into the list at position index.
+ // index must be non-negative and less than or equal to the
+ // number of elements in the list. If index equals the number
+ // of items in the list, then value is appended to the end.
+ void Insert(int index, T item);
+
+ // Removes the item at position index.
+ void RemoveAt(int index);
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/Generic/IReadOnlyCollection.cs b/src/mscorlib/shared/System/Collections/Generic/IReadOnlyCollection.cs
new file mode 100644
index 0000000000..09ee89f035
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/Generic/IReadOnlyCollection.cs
@@ -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.Diagnostics.Contracts;
+using System.Runtime.CompilerServices;
+
+namespace System.Collections.Generic
+{
+ // Provides a read-only, covariant view of a generic list.
+ public interface IReadOnlyCollection<out T> : IEnumerable<T>
+ {
+ int Count { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/Generic/IReadOnlyDictionary.cs b/src/mscorlib/shared/System/Collections/Generic/IReadOnlyDictionary.cs
new file mode 100644
index 0000000000..169e2958bb
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/Generic/IReadOnlyDictionary.cs
@@ -0,0 +1,20 @@
+// 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.Diagnostics.Contracts;
+
+namespace System.Collections.Generic
+{
+ // Provides a read-only view of a generic dictionary.
+ public interface IReadOnlyDictionary<TKey, TValue> : IReadOnlyCollection<KeyValuePair<TKey, TValue>>
+ {
+ bool ContainsKey(TKey key);
+ bool TryGetValue(TKey key, out TValue value);
+
+ TValue this[TKey key] { get; }
+ IEnumerable<TKey> Keys { get; }
+ IEnumerable<TValue> Values { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/Generic/IReadOnlyList.cs b/src/mscorlib/shared/System/Collections/Generic/IReadOnlyList.cs
new file mode 100644
index 0000000000..00b5be65ff
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/Generic/IReadOnlyList.cs
@@ -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.Diagnostics.Contracts;
+using System.Runtime.CompilerServices;
+
+namespace System.Collections.Generic
+{
+ // Provides a read-only, covariant view of a generic list.
+ public interface IReadOnlyList<out T> : IReadOnlyCollection<T>
+ {
+ T this[int index] { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/Generic/KeyNotFoundException.cs b/src/mscorlib/shared/System/Collections/Generic/KeyNotFoundException.cs
new file mode 100644
index 0000000000..1fca7732ae
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/Generic/KeyNotFoundException.cs
@@ -0,0 +1,33 @@
+// 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.Serialization;
+
+namespace System.Collections.Generic
+{
+ [Serializable]
+ public class KeyNotFoundException : SystemException
+ {
+ public KeyNotFoundException()
+ : base(SR.Arg_KeyNotFound)
+ {
+ HResult = __HResults.COR_E_KEYNOTFOUND;
+ }
+
+ public KeyNotFoundException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_KEYNOTFOUND;
+ }
+
+ public KeyNotFoundException(String message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_KEYNOTFOUND;
+ }
+
+ protected KeyNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) { }
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/Generic/KeyValuePair.cs b/src/mscorlib/shared/System/Collections/Generic/KeyValuePair.cs
new file mode 100644
index 0000000000..fc51af25f8
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/Generic/KeyValuePair.cs
@@ -0,0 +1,82 @@
+// 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.ComponentModel;
+using System.Text;
+
+namespace System.Collections.Generic
+{
+ // Provides the Create factory method for KeyValuePair<TKey, TValue>.
+ public static class KeyValuePair
+ {
+ // Creates a new KeyValuePair<TKey, TValue> from the given values.
+ public static KeyValuePair<TKey, TValue> Create<TKey, TValue>(TKey key, TValue value)
+ {
+ return new KeyValuePair<TKey, TValue>(key, value);
+ }
+
+ /// <summary>
+ /// Used by KeyValuePair.ToString to reduce generic code
+ /// </summary>
+ internal static string PairToString(object key, object value)
+ {
+ StringBuilder s = StringBuilderCache.Acquire();
+ s.Append('[');
+
+ if (key != null)
+ {
+ s.Append(key);
+ }
+
+ s.Append(", ");
+
+ if (value != null)
+ {
+ s.Append(value);
+ }
+
+ s.Append(']');
+
+ return StringBuilderCache.GetStringAndRelease(s);
+ }
+ }
+
+ // A KeyValuePair holds a key and a value from a dictionary.
+ // It is used by the IEnumerable<T> implementation for both IDictionary<TKey, TValue>
+ // and IReadOnlyDictionary<TKey, TValue>.
+ [Serializable]
+ public struct KeyValuePair<TKey, TValue>
+ {
+ private TKey key; // DO NOT change the field name, it's required for compatibility with desktop .NET as it appears in serialization payload.
+ private TValue value; // DO NOT change the field name, it's required for compatibility with desktop .NET as it appears in serialization payload.
+
+ public KeyValuePair(TKey key, TValue value)
+ {
+ this.key = key;
+ this.value = value;
+ }
+
+ public TKey Key
+ {
+ get { return key; }
+ }
+
+ public TValue Value
+ {
+ get { return value; }
+ }
+
+ public override string ToString()
+ {
+ return KeyValuePair.PairToString(Key, Value);
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void Deconstruct(out TKey key, out TValue value)
+ {
+ key = Key;
+ value = Value;
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/ICollection.cs b/src/mscorlib/shared/System/Collections/ICollection.cs
new file mode 100644
index 0000000000..80ea092363
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/ICollection.cs
@@ -0,0 +1,70 @@
+// 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.Diagnostics.Contracts;
+
+namespace System.Collections
+{
+ // Base interface for all collections, defining enumerators, size, and
+ // synchronization methods.
+ public interface ICollection : IEnumerable
+ {
+ // Interfaces are not serialable
+ // CopyTo copies a collection into an Array, starting at a particular
+ // index into the array.
+ //
+ void CopyTo(Array array, int index);
+
+ // Number of items in the collections.
+ int Count
+ { get; }
+
+
+ // SyncRoot will return an Object to use for synchronization
+ // (thread safety). You can use this object in your code to take a
+ // lock on the collection, even if this collection is a wrapper around
+ // another collection. The intent is to tunnel through to a real
+ // implementation of a collection, and use one of the internal objects
+ // found in that code.
+ //
+ // In the absense of a static Synchronized method on a collection,
+ // the expected usage for SyncRoot would look like this:
+ //
+ // ICollection col = ...
+ // lock (col.SyncRoot) {
+ // // Some operation on the collection, which is now thread safe.
+ // // This may include multiple operations.
+ // }
+ //
+ //
+ // The system-provided collections have a static method called
+ // Synchronized which will create a thread-safe wrapper around the
+ // collection. All access to the collection that you want to be
+ // thread-safe should go through that wrapper collection. However, if
+ // you need to do multiple calls on that collection (such as retrieving
+ // two items, or checking the count then doing something), you should
+ // NOT use our thread-safe wrapper since it only takes a lock for the
+ // duration of a single method call. Instead, use Monitor.Enter/Exit
+ // or your language's equivalent to the C# lock keyword as mentioned
+ // above.
+ //
+ // For collections with no publically available underlying store, the
+ // expected implementation is to simply return the this pointer. Note
+ // that the this pointer may not be sufficient for collections that
+ // wrap other collections; those should return the underlying
+ // collection's SyncRoot property.
+ Object SyncRoot
+ { get; }
+
+ // Is this collection synchronized (i.e., thread-safe)? If you want a
+ // thread-safe collection, you can use SyncRoot as an object to
+ // synchronize your collection with. If you're using one of the
+ // collections in System.Collections, you could call the static
+ // Synchronized method to get a thread-safe wrapper around the
+ // underlying collection.
+ bool IsSynchronized
+ { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/IComparer.cs b/src/mscorlib/shared/System/Collections/IComparer.cs
new file mode 100644
index 0000000000..cef91c3ffa
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/IComparer.cs
@@ -0,0 +1,22 @@
+// 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;
+
+namespace System.Collections
+{
+ // The IComparer interface implements a method that compares two objects. It is
+ // used in conjunction with the Sort and BinarySearch methods on
+ // the Array and List classes.
+ //
+ // Interfaces are not serializable
+ public interface IComparer
+ {
+ // Compares two objects. An implementation of this method must return a
+ // value less than zero if x is less than y, zero if x is equal to y, or a
+ // value greater than zero if x is greater than y.
+ //
+ int Compare(Object x, Object y);
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/IDictionary.cs b/src/mscorlib/shared/System/Collections/IDictionary.cs
new file mode 100644
index 0000000000..8bc7fcf125
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/IDictionary.cs
@@ -0,0 +1,61 @@
+// 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.Diagnostics.Contracts;
+
+namespace System.Collections
+{
+ // An IDictionary is a possibly unordered set of key-value pairs.
+ // Keys can be any non-null object. Values can be any object.
+ // You can look up a value in an IDictionary via the default indexed
+ // property, Items.
+ public interface IDictionary : ICollection
+ {
+ // Interfaces are not serializable
+ // The Item property provides methods to read and edit entries
+ // in the Dictionary.
+ Object this[Object key]
+ {
+ get;
+ set;
+ }
+
+ // Returns a collections of the keys in this dictionary.
+ ICollection Keys
+ {
+ get;
+ }
+
+ // Returns a collections of the values in this dictionary.
+ ICollection Values
+ {
+ get;
+ }
+
+ // Returns whether this dictionary contains a particular key.
+ //
+ bool Contains(Object key);
+
+ // Adds a key-value pair to the dictionary.
+ //
+ void Add(Object key, Object value);
+
+ // Removes all pairs from the dictionary.
+ void Clear();
+
+ bool IsReadOnly
+ { get; }
+
+ bool IsFixedSize
+ { get; }
+
+ // Returns an IDictionaryEnumerator for this dictionary.
+ new IDictionaryEnumerator GetEnumerator();
+
+ // Removes a particular key from the dictionary.
+ //
+ void Remove(Object key);
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/IDictionaryEnumerator.cs b/src/mscorlib/shared/System/Collections/IDictionaryEnumerator.cs
new file mode 100644
index 0000000000..451cf68976
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/IDictionaryEnumerator.cs
@@ -0,0 +1,68 @@
+// 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.
+
+namespace System.Collections
+{
+ // This interface represents an enumerator that allows sequential access to the
+ // elements of a dictionary. Upon creation, an enumerator is conceptually
+ // positioned before the first element of the enumeration. The first call to the
+ // MoveNext method brings the first element of the enumeration into view,
+ // and each successive call to MoveNext brings the next element into
+ // view until MoveNext returns false, indicating that there are no more
+ // elements to enumerate. Following each call to MoveNext, the
+ // Key and Value methods are used to obtain the key and
+ // value of the element currently in view. The values returned by calls to
+ // Key and Value are undefined before the first call to
+ // MoveNext and following a call to MoveNext that returned false.
+ // Enumerators are typically used in while loops of the form
+ //
+ // IDictionaryEnumerator e = ...;
+ // while (e.MoveNext()) {
+ // Object key = e.Key;
+ // Object value = e.Value;
+ // ...
+ // }
+ //
+ // The IDictionaryEnumerator interface extends the IEnumerator
+ // inerface and can thus be used as a regular enumerator. The Current
+ // method of an IDictionaryEnumerator returns a DictionaryEntry containing
+ // the current key and value pair. However, the GetEntry method will
+ // return the same DictionaryEntry and avoids boxing the DictionaryEntry (boxing
+ // is somewhat expensive).
+ //
+ public interface IDictionaryEnumerator : IEnumerator
+ {
+ // Returns the key of the current element of the enumeration. The returned
+ // value is undefined before the first call to GetNext and following
+ // a call to GetNext that returned false. Multiple calls to
+ // GetKey with no intervening calls to GetNext will return
+ // the same object.
+ //
+ Object Key
+ {
+ get;
+ }
+
+ // Returns the value of the current element of the enumeration. The
+ // returned value is undefined before the first call to GetNext and
+ // following a call to GetNext that returned false. Multiple calls
+ // to GetValue with no intervening calls to GetNext will
+ // return the same object.
+ //
+ Object Value
+ {
+ get;
+ }
+
+ // GetBlock will copy dictionary values into the given Array. It will either
+ // fill up the array, or if there aren't enough elements, it will
+ // copy as much as possible into the Array. The number of elements
+ // copied is returned.
+ //
+ DictionaryEntry Entry
+ {
+ get;
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/IEnumerable.cs b/src/mscorlib/shared/System/Collections/IEnumerable.cs
new file mode 100644
index 0000000000..91aec62423
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/IEnumerable.cs
@@ -0,0 +1,18 @@
+// 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.Diagnostics.Contracts;
+using System.Runtime.InteropServices;
+
+namespace System.Collections
+{
+ public interface IEnumerable
+ {
+ // Returns an IEnumerator for this enumerable Object. The enumerator provides
+ // a simple way to access all the contents of a collection.
+ [Pure]
+ IEnumerator GetEnumerator();
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/IEnumerator.cs b/src/mscorlib/shared/System/Collections/IEnumerator.cs
new file mode 100644
index 0000000000..2c2c2e4a97
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/IEnumerator.cs
@@ -0,0 +1,41 @@
+// 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.InteropServices;
+
+namespace System.Collections
+{
+ // Base interface for all enumerators, providing a simple approach
+ // to iterating over a collection.
+ public interface IEnumerator
+ {
+ // Advances the enumerator to the next element of the enumeration and
+ // returns a boolean indicating whether an element is available. Upon
+ // creation, an enumerator is conceptually positioned before the first
+ // element of the enumeration, and the first call to MoveNext
+ // brings the first element of the enumeration into view.
+ //
+ bool MoveNext();
+
+ // Returns the current element of the enumeration. The returned value is
+ // undefined before the first call to MoveNext and following a
+ // call to MoveNext that returned false. Multiple calls to
+ // GetCurrent with no intervening calls to MoveNext
+ // will return the same object.
+ //
+ Object Current
+ {
+ get;
+ }
+
+ // Resets the enumerator to the beginning of the enumeration, starting over.
+ // The preferred behavior for Reset is to return the exact same enumeration.
+ // This means if you modify the underlying collection then call Reset, your
+ // IEnumerator will be invalid, just as it would have been if you had called
+ // MoveNext or Current.
+ //
+ void Reset();
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/IEqualityComparer.cs b/src/mscorlib/shared/System/Collections/IEqualityComparer.cs
new file mode 100644
index 0000000000..35513f577d
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/IEqualityComparer.cs
@@ -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;
+
+namespace System.Collections
+{
+ // An IEqualityComparer is a mechanism to consume custom performant comparison infrastructure
+ // that can be consumed by some of the common collections.
+ public interface IEqualityComparer
+ {
+ bool Equals(Object x, Object y);
+ int GetHashCode(Object obj);
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/IList.cs b/src/mscorlib/shared/System/Collections/IList.cs
new file mode 100644
index 0000000000..bb2e221cc1
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/IList.cs
@@ -0,0 +1,60 @@
+// 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.Diagnostics.Contracts;
+
+namespace System.Collections
+{
+ // An IList is an ordered collection of objects. The exact ordering
+ // is up to the implementation of the list, ranging from a sorted
+ // order to insertion order.
+ public interface IList : ICollection
+ {
+ // The Item property provides methods to read and edit entries in the List.
+ Object this[int index]
+ {
+ get;
+ set;
+ }
+
+ // Adds an item to the list. The exact position in the list is
+ // implementation-dependent, so while ArrayList may always insert
+ // in the last available location, a SortedList most likely would not.
+ // The return value is the position the new element was inserted in.
+ int Add(Object value);
+
+ // Returns whether the list contains a particular item.
+ bool Contains(Object value);
+
+ // Removes all items from the list.
+ void Clear();
+
+ bool IsReadOnly
+ { get; }
+
+
+ bool IsFixedSize
+ {
+ get;
+ }
+
+
+ // Returns the index of a particular item, if it is in the list.
+ // Returns -1 if the item isn't in the list.
+ int IndexOf(Object value);
+
+ // Inserts value into the list at position index.
+ // index must be non-negative and less than or equal to the
+ // number of elements in the list. If index equals the number
+ // of items in the list, then value is appended to the end.
+ void Insert(int index, Object value);
+
+ // Removes an item from the list.
+ void Remove(Object value);
+
+ // Removes the item at position index.
+ void RemoveAt(int index);
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/IStructuralComparable.cs b/src/mscorlib/shared/System/Collections/IStructuralComparable.cs
new file mode 100644
index 0000000000..a5e4834b9b
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/IStructuralComparable.cs
@@ -0,0 +1,13 @@
+// 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;
+
+namespace System.Collections
+{
+ public interface IStructuralComparable
+ {
+ Int32 CompareTo(Object other, IComparer comparer);
+ }
+}
diff --git a/src/mscorlib/shared/System/Collections/IStructuralEquatable.cs b/src/mscorlib/shared/System/Collections/IStructuralEquatable.cs
new file mode 100644
index 0000000000..4e61d5e75f
--- /dev/null
+++ b/src/mscorlib/shared/System/Collections/IStructuralEquatable.cs
@@ -0,0 +1,12 @@
+// 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.
+
+namespace System.Collections
+{
+ public interface IStructuralEquatable
+ {
+ Boolean Equals(Object other, IEqualityComparer comparer);
+ int GetHashCode(IEqualityComparer comparer);
+ }
+}
diff --git a/src/mscorlib/shared/System/ComponentModel/DefaultValueAttribute.cs b/src/mscorlib/shared/System/ComponentModel/DefaultValueAttribute.cs
new file mode 100644
index 0000000000..3cdc907297
--- /dev/null
+++ b/src/mscorlib/shared/System/ComponentModel/DefaultValueAttribute.cs
@@ -0,0 +1,228 @@
+// 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.ComponentModel;
+using System.Diagnostics;
+using System.Globalization;
+using System.Runtime.InteropServices;
+
+namespace System.ComponentModel
+{
+ /// <devdoc>
+ /// <para>Specifies the default value for a property.</para>
+ /// </devdoc>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes")]
+ [AttributeUsage(AttributeTargets.All)]
+ public class DefaultValueAttribute : Attribute
+ {
+ /// <devdoc>
+ /// This is the default value.
+ /// </devdoc>
+ private object _value;
+
+ /// <devdoc>
+ /// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class, converting the
+ /// specified value to the
+ /// specified type, and using the U.S. English culture as the
+ /// translation
+ /// context.</para>
+ /// </devdoc>
+ public DefaultValueAttribute(Type type, string value)
+ {
+ // The try/catch here is because attributes should never throw exceptions. We would fail to
+ // load an otherwise normal class.
+ try
+ {
+ if (type.IsSubclassOf(typeof(Enum)))
+ {
+ _value = Enum.Parse(type, value, true);
+ }
+ else if (type == typeof(TimeSpan))
+ {
+ _value = TimeSpan.Parse(value);
+ }
+ else
+ {
+ _value = Convert.ChangeType(value, type, CultureInfo.InvariantCulture);
+ }
+ }
+ catch
+ {
+ }
+ }
+
+ /// <devdoc>
+ /// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class using a Unicode
+ /// character.</para>
+ /// </devdoc>
+ public DefaultValueAttribute(char value)
+ {
+ _value = value;
+ }
+ /// <devdoc>
+ /// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class using an 8-bit unsigned
+ /// integer.</para>
+ /// </devdoc>
+ public DefaultValueAttribute(byte value)
+ {
+ _value = value;
+ }
+ /// <devdoc>
+ /// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class using a 16-bit signed
+ /// integer.</para>
+ /// </devdoc>
+ public DefaultValueAttribute(short value)
+ {
+ _value = value;
+ }
+ /// <devdoc>
+ /// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class using a 32-bit signed
+ /// integer.</para>
+ /// </devdoc>
+ public DefaultValueAttribute(int value)
+ {
+ _value = value;
+ }
+ /// <devdoc>
+ /// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class using a 64-bit signed
+ /// integer.</para>
+ /// </devdoc>
+ public DefaultValueAttribute(long value)
+ {
+ _value = value;
+ }
+ /// <devdoc>
+ /// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class using a
+ /// single-precision floating point
+ /// number.</para>
+ /// </devdoc>
+ public DefaultValueAttribute(float value)
+ {
+ _value = value;
+ }
+ /// <devdoc>
+ /// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class using a
+ /// double-precision floating point
+ /// number.</para>
+ /// </devdoc>
+ public DefaultValueAttribute(double value)
+ {
+ _value = value;
+ }
+ /// <devdoc>
+ /// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class using a <see cref='System.Boolean'/>
+ /// value.</para>
+ /// </devdoc>
+ public DefaultValueAttribute(bool value)
+ {
+ _value = value;
+ }
+ /// <devdoc>
+ /// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class using a <see cref='System.String'/>.</para>
+ /// </devdoc>
+ public DefaultValueAttribute(string value)
+ {
+ _value = value;
+ }
+
+ /// <devdoc>
+ /// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/>
+ /// class.</para>
+ /// </devdoc>
+ public DefaultValueAttribute(object value)
+ {
+ _value = value;
+ }
+
+ /// <devdoc>
+ /// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class using a <see cref='System.SByte'/>
+ /// value.</para>
+ /// </devdoc>
+ [CLSCompliant(false)]
+ public DefaultValueAttribute(sbyte value)
+ {
+ _value = value;
+ }
+
+ /// <devdoc>
+ /// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class using a <see cref='System.UInt16'/>
+ /// value.</para>
+ /// </devdoc>
+ [CLSCompliant(false)]
+ public DefaultValueAttribute(ushort value)
+ {
+ _value = value;
+ }
+
+ /// <devdoc>
+ /// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class using a <see cref='System.UInt32'/>
+ /// value.</para>
+ /// </devdoc>
+ [CLSCompliant(false)]
+ public DefaultValueAttribute(uint value)
+ {
+ _value = value;
+ }
+
+ /// <devdoc>
+ /// <para>Initializes a new instance of the <see cref='System.ComponentModel.DefaultValueAttribute'/> class using a <see cref='System.UInt64'/>
+ /// value.</para>
+ /// </devdoc>
+ [CLSCompliant(false)]
+ public DefaultValueAttribute(ulong value)
+ {
+ _value = value;
+ }
+
+ /// <devdoc>
+ /// <para>
+ /// Gets the default value of the property this
+ /// attribute is
+ /// bound to.
+ /// </para>
+ /// </devdoc>
+ public virtual object Value
+ {
+ get
+ {
+ return _value;
+ }
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ DefaultValueAttribute other = obj as DefaultValueAttribute;
+
+ if (other != null)
+ {
+ if (Value != null)
+ {
+ return Value.Equals(other.Value);
+ }
+ else
+ {
+ return (other.Value == null);
+ }
+ }
+ return false;
+ }
+
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+
+ protected void SetValue(object value)
+ {
+ _value = value;
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/ComponentModel/EditorBrowsableAttribute.cs b/src/mscorlib/shared/System/ComponentModel/EditorBrowsableAttribute.cs
new file mode 100644
index 0000000000..9b4d6e626e
--- /dev/null
+++ b/src/mscorlib/shared/System/ComponentModel/EditorBrowsableAttribute.cs
@@ -0,0 +1,48 @@
+// 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.
+
+namespace System.ComponentModel
+{
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Delegate | AttributeTargets.Interface)]
+ public sealed class EditorBrowsableAttribute : Attribute
+ {
+ private EditorBrowsableState browsableState;
+
+ public EditorBrowsableAttribute(EditorBrowsableState state)
+ {
+ browsableState = state;
+ }
+
+ public EditorBrowsableAttribute() : this(EditorBrowsableState.Always) { }
+
+ public EditorBrowsableState State
+ {
+ get { return browsableState; }
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+
+ EditorBrowsableAttribute other = obj as EditorBrowsableAttribute;
+
+ return (other != null) && other.browsableState == browsableState;
+ }
+
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+ }
+
+ public enum EditorBrowsableState
+ {
+ Always,
+ Never,
+ Advanced
+ }
+}
diff --git a/src/mscorlib/shared/System/Configuration/Assemblies/AssemblyHashAlgorithm.cs b/src/mscorlib/shared/System/Configuration/Assemblies/AssemblyHashAlgorithm.cs
new file mode 100644
index 0000000000..aca8da5932
--- /dev/null
+++ b/src/mscorlib/shared/System/Configuration/Assemblies/AssemblyHashAlgorithm.cs
@@ -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.
+
+namespace System.Configuration.Assemblies
+{
+ public enum AssemblyHashAlgorithm
+ {
+ None = 0,
+ MD5 = 0x8003,
+ SHA1 = 0x8004,
+ SHA256 = 0x800c,
+ SHA384 = 0x800d,
+ SHA512 = 0x800e,
+ }
+}
diff --git a/src/mscorlib/shared/System/Configuration/Assemblies/AssemblyVersionCompatibility.cs b/src/mscorlib/shared/System/Configuration/Assemblies/AssemblyVersionCompatibility.cs
new file mode 100644
index 0000000000..ef7b3eb45f
--- /dev/null
+++ b/src/mscorlib/shared/System/Configuration/Assemblies/AssemblyVersionCompatibility.cs
@@ -0,0 +1,13 @@
+// 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.
+
+namespace System.Configuration.Assemblies
+{
+ public enum AssemblyVersionCompatibility
+ {
+ SameMachine = 1,
+ SameProcess = 2,
+ SameDomain = 3,
+ }
+}
diff --git a/src/mscorlib/shared/System/Convert.cs b/src/mscorlib/shared/System/Convert.cs
new file mode 100644
index 0000000000..576f78f1f1
--- /dev/null
+++ b/src/mscorlib/shared/System/Convert.cs
@@ -0,0 +1,3031 @@
+// 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.Globalization;
+using System.Threading;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+using System.Security;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
+ [Flags]
+ public enum Base64FormattingOptions
+ {
+ None = 0,
+ InsertLineBreaks = 1
+ }
+
+ // Returns the type code of this object. An implementation of this method
+ // must not return TypeCode.Empty (which represents a null reference) or
+ // TypeCode.Object (which represents an object that doesn't implement the
+ // IConvertible interface). An implementation of this method should return
+ // TypeCode.DBNull if the value of this object is a database null. For
+ // example, a nullable integer type should return TypeCode.DBNull if the
+ // value of the object is the database null. Otherwise, an implementation
+ // of this method should return the TypeCode that best describes the
+ // internal representation of the object.
+ // The Value class provides conversion and querying methods for values. The
+ // Value class contains static members only, and it is not possible to create
+ // instances of the class.
+ //
+ // The statically typed conversion methods provided by the Value class are all
+ // of the form:
+ //
+ // public static XXX ToXXX(YYY value)
+ //
+ // where XXX is the target type and YYY is the source type. The matrix below
+ // shows the set of supported conversions. The set of conversions is symmetric
+ // such that for every ToXXX(YYY) there is also a ToYYY(XXX).
+ //
+ // From: To: Bol Chr SBy Byt I16 U16 I32 U32 I64 U64 Sgl Dbl Dec Dat Str
+ // ----------------------------------------------------------------------
+ // Boolean x x x x x x x x x x x x x
+ // Char x x x x x x x x x x
+ // SByte x x x x x x x x x x x x x x
+ // Byte x x x x x x x x x x x x x x
+ // Int16 x x x x x x x x x x x x x x
+ // UInt16 x x x x x x x x x x x x x x
+ // Int32 x x x x x x x x x x x x x x
+ // UInt32 x x x x x x x x x x x x x x
+ // Int64 x x x x x x x x x x x x x x
+ // UInt64 x x x x x x x x x x x x x x
+ // Single x x x x x x x x x x x x x
+ // Double x x x x x x x x x x x x x
+ // Decimal x x x x x x x x x x x x x
+ // DateTime x x
+ // String x x x x x x x x x x x x x x x
+ // ----------------------------------------------------------------------
+ //
+ // For dynamic conversions, the Value class provides a set of methods of the
+ // form:
+ //
+ // public static XXX ToXXX(object value)
+ //
+ // where XXX is the target type (Boolean, Char, SByte, Byte, Int16, UInt16,
+ // Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime,
+ // or String). The implementations of these methods all take the form:
+ //
+ // public static XXX toXXX(object value) {
+ // return value == null? XXX.Default: ((IConvertible)value).ToXXX();
+ // }
+ //
+ // The code first checks if the given value is a null reference (which is the
+ // same as Value.Empty), in which case it returns the default value for type
+ // XXX. Otherwise, a cast to IConvertible is performed, and the appropriate ToXXX()
+ // method is invoked on the object. An InvalidCastException is thrown if the
+ // cast to IConvertible fails, and that exception is simply allowed to propagate out
+ // of the conversion method.
+
+ // Constant representing the database null value. This value is used in
+ // database applications to indicate the absense of a known value. Note
+ // that Value.DBNull is NOT the same as a null object reference, which is
+ // represented by Value.Empty.
+ //
+ // The Equals() method of DBNull always returns false, even when the
+ // argument is itself DBNull.
+ //
+ // When passed Value.DBNull, the Value.GetTypeCode() method returns
+ // TypeCode.DBNull.
+ //
+ // When passed Value.DBNull, the Value.ToXXX() methods all throw an
+ // InvalidCastException.
+
+ public static class Convert
+ {
+ //A typeof operation is fairly expensive (does a system call), so we'll cache these here
+ //statically. These are exactly lined up with the TypeCode, eg. ConvertType[TypeCode.Int16]
+ //will give you the type of an Int16.
+ internal static readonly Type[] ConvertTypes = {
+ typeof(System.Empty),
+ typeof(Object),
+ typeof(System.DBNull),
+ typeof(Boolean),
+ typeof(Char),
+ typeof(SByte),
+ typeof(Byte),
+ typeof(Int16),
+ typeof(UInt16),
+ typeof(Int32),
+ typeof(UInt32),
+ typeof(Int64),
+ typeof(UInt64),
+ typeof(Single),
+ typeof(Double),
+ typeof(Decimal),
+ typeof(DateTime),
+ typeof(Object), //TypeCode is discontinuous so we need a placeholder.
+ typeof(String)
+ };
+
+ // Need to special case Enum because typecode will be underlying type, e.g. Int32
+ private static readonly Type EnumType = typeof(Enum);
+
+ internal static readonly char[] base64Table = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
+ 'P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d',
+ 'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s',
+ 't','u','v','w','x','y','z','0','1','2','3','4','5','6','7',
+ '8','9','+','/','=' };
+
+ private const Int32 base64LineBreakPosition = 76;
+
+#if _DEBUG
+ private static bool TriggerAsserts = DoAsserts();
+ private static bool DoAsserts()
+ {
+ Debug.Assert(ConvertTypes != null, "[Convert.cctor]ConvertTypes!=null");
+ Debug.Assert(ConvertTypes.Length == ((int)TypeCode.String + 1), "[Convert.cctor]ConvertTypes.Length == ((int)TypeCode.String + 1)");
+ Debug.Assert(ConvertTypes[(int)TypeCode.Empty] == typeof(System.Empty),
+ "[Convert.cctor]ConvertTypes[(int)TypeCode.Empty]==typeof(System.Empty)");
+ Debug.Assert(ConvertTypes[(int)TypeCode.String] == typeof(String),
+ "[Convert.cctor]ConvertTypes[(int)TypeCode.String]==typeof(System.String)");
+ Debug.Assert(ConvertTypes[(int)TypeCode.Int32] == typeof(int),
+ "[Convert.cctor]ConvertTypes[(int)TypeCode.Int32]==typeof(int)");
+ return true;
+ }
+#endif
+
+ public static readonly Object DBNull = System.DBNull.Value;
+
+ // Returns the type code for the given object. If the argument is null,
+ // the result is TypeCode.Empty. If the argument is not a value (i.e. if
+ // the object does not implement IConvertible), the result is TypeCode.Object.
+ // Otherwise, the result is the type code of the object, as determined by
+ // the object's implementation of IConvertible.
+ [Pure]
+ public static TypeCode GetTypeCode(object value)
+ {
+ if (value == null) return TypeCode.Empty;
+ IConvertible temp = value as IConvertible;
+ if (temp != null)
+ {
+ return temp.GetTypeCode();
+ }
+ return TypeCode.Object;
+ }
+
+ // Returns true if the given object is a database null. This operation
+ // corresponds to "value.GetTypeCode() == TypeCode.DBNull".
+ [Pure]
+ public static bool IsDBNull(object value)
+ {
+ if (value == System.DBNull.Value) return true;
+ IConvertible convertible = value as IConvertible;
+ return convertible != null ? convertible.GetTypeCode() == TypeCode.DBNull : false;
+ }
+
+ // Converts the given object to the given type. In general, this method is
+ // equivalent to calling the Value.ToXXX(value) method for the given
+ // typeCode and boxing the result.
+ //
+ // The method first checks if the given object implements IConvertible. If not,
+ // the only permitted conversion is from a null to TypeCode.Empty, the
+ // result of which is null.
+ //
+ // If the object does implement IConvertible, a check is made to see if the
+ // object already has the given type code, in which case the object is
+ // simply returned. Otherwise, the appropriate ToXXX() is invoked on the
+ // object's implementation of IConvertible.
+ public static Object ChangeType(Object value, TypeCode typeCode)
+ {
+ return ChangeType(value, typeCode, CultureInfo.CurrentCulture);
+ }
+
+ public static Object ChangeType(Object value, TypeCode typeCode, IFormatProvider provider)
+ {
+ if (value == null && (typeCode == TypeCode.Empty || typeCode == TypeCode.String || typeCode == TypeCode.Object))
+ {
+ return null;
+ }
+
+ IConvertible v = value as IConvertible;
+ if (v == null)
+ {
+ throw new InvalidCastException(SR.InvalidCast_IConvertible);
+ }
+
+ // This line is invalid for things like Enums that return a TypeCode
+ // of Int32, but the object can't actually be cast to an Int32.
+ // if (v.GetTypeCode() == typeCode) return value;
+ switch (typeCode)
+ {
+ case TypeCode.Boolean:
+ return v.ToBoolean(provider);
+ case TypeCode.Char:
+ return v.ToChar(provider);
+ case TypeCode.SByte:
+ return v.ToSByte(provider);
+ case TypeCode.Byte:
+ return v.ToByte(provider);
+ case TypeCode.Int16:
+ return v.ToInt16(provider);
+ case TypeCode.UInt16:
+ return v.ToUInt16(provider);
+ case TypeCode.Int32:
+ return v.ToInt32(provider);
+ case TypeCode.UInt32:
+ return v.ToUInt32(provider);
+ case TypeCode.Int64:
+ return v.ToInt64(provider);
+ case TypeCode.UInt64:
+ return v.ToUInt64(provider);
+ case TypeCode.Single:
+ return v.ToSingle(provider);
+ case TypeCode.Double:
+ return v.ToDouble(provider);
+ case TypeCode.Decimal:
+ return v.ToDecimal(provider);
+ case TypeCode.DateTime:
+ return v.ToDateTime(provider);
+ case TypeCode.String:
+ return v.ToString(provider);
+ case TypeCode.Object:
+ return value;
+ case TypeCode.DBNull:
+ throw new InvalidCastException(SR.InvalidCast_DBNull);
+ case TypeCode.Empty:
+ throw new InvalidCastException(SR.InvalidCast_Empty);
+ default:
+ throw new ArgumentException(SR.Arg_UnknownTypeCode);
+ }
+ }
+
+ internal static Object DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
+ {
+ Debug.Assert(value != null, "[Convert.DefaultToType]value!=null");
+ if (targetType == null)
+ {
+ throw new ArgumentNullException(nameof(targetType));
+ }
+ Contract.EndContractBlock();
+
+ if (ReferenceEquals(value.GetType(), targetType))
+ {
+ return value;
+ }
+
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Boolean]))
+ return value.ToBoolean(provider);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Char]))
+ return value.ToChar(provider);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.SByte]))
+ return value.ToSByte(provider);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Byte]))
+ return value.ToByte(provider);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Int16]))
+ return value.ToInt16(provider);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.UInt16]))
+ return value.ToUInt16(provider);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Int32]))
+ return value.ToInt32(provider);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.UInt32]))
+ return value.ToUInt32(provider);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Int64]))
+ return value.ToInt64(provider);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.UInt64]))
+ return value.ToUInt64(provider);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Single]))
+ return value.ToSingle(provider);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Double]))
+ return value.ToDouble(provider);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Decimal]))
+ return value.ToDecimal(provider);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.DateTime]))
+ return value.ToDateTime(provider);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.String]))
+ return value.ToString(provider);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Object]))
+ return (Object)value;
+ // Need to special case Enum because typecode will be underlying type, e.g. Int32
+ if (ReferenceEquals(targetType, EnumType))
+ return (Enum)value;
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.DBNull]))
+ throw new InvalidCastException(SR.InvalidCast_DBNull);
+ if (ReferenceEquals(targetType, ConvertTypes[(int)TypeCode.Empty]))
+ throw new InvalidCastException(SR.InvalidCast_Empty);
+
+ throw new InvalidCastException(string.Format(SR.InvalidCast_FromTo, value.GetType().FullName, targetType.FullName));
+ }
+
+ public static Object ChangeType(Object value, Type conversionType)
+ {
+ return ChangeType(value, conversionType, CultureInfo.CurrentCulture);
+ }
+
+ public static Object ChangeType(Object value, Type conversionType, IFormatProvider provider)
+ {
+ if (ReferenceEquals(conversionType, null))
+ {
+ throw new ArgumentNullException(nameof(conversionType));
+ }
+ Contract.EndContractBlock();
+
+ if (value == null)
+ {
+ if (conversionType.IsValueType)
+ {
+ throw new InvalidCastException(SR.InvalidCast_CannotCastNullToValueType);
+ }
+ return null;
+ }
+
+ IConvertible ic = value as IConvertible;
+ if (ic == null)
+ {
+ if (value.GetType() == conversionType)
+ {
+ return value;
+ }
+ throw new InvalidCastException(SR.InvalidCast_IConvertible);
+ }
+
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Boolean]))
+ return ic.ToBoolean(provider);
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Char]))
+ return ic.ToChar(provider);
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.SByte]))
+ return ic.ToSByte(provider);
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Byte]))
+ return ic.ToByte(provider);
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Int16]))
+ return ic.ToInt16(provider);
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.UInt16]))
+ return ic.ToUInt16(provider);
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Int32]))
+ return ic.ToInt32(provider);
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.UInt32]))
+ return ic.ToUInt32(provider);
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Int64]))
+ return ic.ToInt64(provider);
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.UInt64]))
+ return ic.ToUInt64(provider);
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Single]))
+ return ic.ToSingle(provider);
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Double]))
+ return ic.ToDouble(provider);
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Decimal]))
+ return ic.ToDecimal(provider);
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.DateTime]))
+ return ic.ToDateTime(provider);
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.String]))
+ return ic.ToString(provider);
+ if (ReferenceEquals(conversionType, ConvertTypes[(int)TypeCode.Object]))
+ return (Object)value;
+
+ return ic.ToType(conversionType, provider);
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void ThrowCharOverflowException() { throw new OverflowException(SR.Overflow_Char); }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void ThrowByteOverflowException() { throw new OverflowException(SR.Overflow_Byte); }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void ThrowSByteOverflowException() { throw new OverflowException(SR.Overflow_SByte); }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void ThrowInt16OverflowException() { throw new OverflowException(SR.Overflow_Int16); }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void ThrowUInt16OverflowException() { throw new OverflowException(SR.Overflow_UInt16); }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void ThrowInt32OverflowException() { throw new OverflowException(SR.Overflow_Int32); }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void ThrowUInt32OverflowException() { throw new OverflowException(SR.Overflow_UInt32); }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void ThrowInt64OverflowException() { throw new OverflowException(SR.Overflow_Int64); }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static void ThrowUInt64OverflowException() { throw new OverflowException(SR.Overflow_UInt64); }
+
+ // Conversions to Boolean
+ public static bool ToBoolean(Object value)
+ {
+ return value == null ? false : ((IConvertible)value).ToBoolean(null);
+ }
+
+ public static bool ToBoolean(Object value, IFormatProvider provider)
+ {
+ return value == null ? false : ((IConvertible)value).ToBoolean(provider);
+ }
+
+
+ public static bool ToBoolean(bool value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static bool ToBoolean(sbyte value)
+ {
+ return value != 0;
+ }
+
+ // To be consistent with IConvertible in the base data types else we get different semantics
+ // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
+ public static bool ToBoolean(char value)
+ {
+ return ((IConvertible)value).ToBoolean(null);
+ }
+
+ public static bool ToBoolean(byte value)
+ {
+ return value != 0;
+ }
+
+
+ public static bool ToBoolean(short value)
+ {
+ return value != 0;
+ }
+
+ [CLSCompliant(false)]
+ public static bool ToBoolean(ushort value)
+ {
+ return value != 0;
+ }
+
+ public static bool ToBoolean(int value)
+ {
+ return value != 0;
+ }
+
+ [CLSCompliant(false)]
+ public static bool ToBoolean(uint value)
+ {
+ return value != 0;
+ }
+
+ public static bool ToBoolean(long value)
+ {
+ return value != 0;
+ }
+
+ [CLSCompliant(false)]
+ public static bool ToBoolean(ulong value)
+ {
+ return value != 0;
+ }
+
+ public static bool ToBoolean(String value)
+ {
+ if (value == null)
+ return false;
+ return Boolean.Parse(value);
+ }
+
+ public static bool ToBoolean(String value, IFormatProvider provider)
+ {
+ if (value == null)
+ return false;
+ return Boolean.Parse(value);
+ }
+
+ public static bool ToBoolean(float value)
+ {
+ return value != 0;
+ }
+
+ public static bool ToBoolean(double value)
+ {
+ return value != 0;
+ }
+
+ public static bool ToBoolean(decimal value)
+ {
+ return value != 0;
+ }
+
+ public static bool ToBoolean(DateTime value)
+ {
+ return ((IConvertible)value).ToBoolean(null);
+ }
+
+ // Disallowed conversions to Boolean
+ // public static bool ToBoolean(TimeSpan value)
+
+ // Conversions to Char
+
+
+ public static char ToChar(object value)
+ {
+ return value == null ? (char)0 : ((IConvertible)value).ToChar(null);
+ }
+
+ public static char ToChar(object value, IFormatProvider provider)
+ {
+ return value == null ? (char)0 : ((IConvertible)value).ToChar(provider);
+ }
+
+ public static char ToChar(bool value)
+ {
+ return ((IConvertible)value).ToChar(null);
+ }
+
+ public static char ToChar(char value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static char ToChar(sbyte value)
+ {
+ if (value < 0) ThrowCharOverflowException();
+ Contract.EndContractBlock();
+ return (char)value;
+ }
+
+ public static char ToChar(byte value)
+ {
+ return (char)value;
+ }
+
+ public static char ToChar(short value)
+ {
+ if (value < 0) ThrowCharOverflowException();
+ Contract.EndContractBlock();
+ return (char)value;
+ }
+
+ [CLSCompliant(false)]
+ public static char ToChar(ushort value)
+ {
+ return (char)value;
+ }
+
+ public static char ToChar(int value)
+ {
+ if (value < 0 || value > Char.MaxValue) ThrowCharOverflowException();
+ Contract.EndContractBlock();
+ return (char)value;
+ }
+
+ [CLSCompliant(false)]
+ public static char ToChar(uint value)
+ {
+ if (value > Char.MaxValue) ThrowCharOverflowException();
+ Contract.EndContractBlock();
+ return (char)value;
+ }
+
+ public static char ToChar(long value)
+ {
+ if (value < 0 || value > Char.MaxValue) ThrowCharOverflowException();
+ Contract.EndContractBlock();
+ return (char)value;
+ }
+
+ [CLSCompliant(false)]
+ public static char ToChar(ulong value)
+ {
+ if (value > Char.MaxValue) ThrowCharOverflowException();
+ Contract.EndContractBlock();
+ return (char)value;
+ }
+
+ //
+ // @VariantSwitch
+ // Remove FormatExceptions;
+ //
+ public static char ToChar(String value)
+ {
+ return ToChar(value, null);
+ }
+
+ public static char ToChar(String value, IFormatProvider provider)
+ {
+ if (value == null)
+ throw new ArgumentNullException(nameof(value));
+ Contract.EndContractBlock();
+
+ if (value.Length != 1)
+ throw new FormatException(SR.Format_NeedSingleChar);
+
+ return value[0];
+ }
+
+ // To be consistent with IConvertible in the base data types else we get different semantics
+ // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
+ public static char ToChar(float value)
+ {
+ return ((IConvertible)value).ToChar(null);
+ }
+
+ // To be consistent with IConvertible in the base data types else we get different semantics
+ // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
+ public static char ToChar(double value)
+ {
+ return ((IConvertible)value).ToChar(null);
+ }
+
+ // To be consistent with IConvertible in the base data types else we get different semantics
+ // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
+ public static char ToChar(decimal value)
+ {
+ return ((IConvertible)value).ToChar(null);
+ }
+
+ public static char ToChar(DateTime value)
+ {
+ return ((IConvertible)value).ToChar(null);
+ }
+
+
+ // Disallowed conversions to Char
+ // public static char ToChar(TimeSpan value)
+
+ // Conversions to SByte
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(object value)
+ {
+ return value == null ? (sbyte)0 : ((IConvertible)value).ToSByte(null);
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(object value, IFormatProvider provider)
+ {
+ return value == null ? (sbyte)0 : ((IConvertible)value).ToSByte(provider);
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(bool value)
+ {
+ return value ? (sbyte)Boolean.True : (sbyte)Boolean.False;
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(sbyte value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(char value)
+ {
+ if (value > SByte.MaxValue) ThrowSByteOverflowException();
+ Contract.EndContractBlock();
+ return (sbyte)value;
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(byte value)
+ {
+ if (value > SByte.MaxValue) ThrowSByteOverflowException();
+ Contract.EndContractBlock();
+ return (sbyte)value;
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(short value)
+ {
+ if (value < SByte.MinValue || value > SByte.MaxValue) ThrowSByteOverflowException();
+ Contract.EndContractBlock();
+ return (sbyte)value;
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(ushort value)
+ {
+ if (value > SByte.MaxValue) ThrowSByteOverflowException();
+ Contract.EndContractBlock();
+ return (sbyte)value;
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(int value)
+ {
+ if (value < SByte.MinValue || value > SByte.MaxValue) ThrowSByteOverflowException();
+ Contract.EndContractBlock();
+ return (sbyte)value;
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(uint value)
+ {
+ if (value > SByte.MaxValue) ThrowSByteOverflowException();
+ Contract.EndContractBlock();
+ return (sbyte)value;
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(long value)
+ {
+ if (value < SByte.MinValue || value > SByte.MaxValue) ThrowSByteOverflowException();
+ Contract.EndContractBlock();
+ return (sbyte)value;
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(ulong value)
+ {
+ if (value > (ulong)SByte.MaxValue) ThrowSByteOverflowException();
+ Contract.EndContractBlock();
+ return (sbyte)value;
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(float value)
+ {
+ return ToSByte((double)value);
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(double value)
+ {
+ return ToSByte(ToInt32(value));
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(decimal value)
+ {
+ return Decimal.ToSByte(Decimal.Round(value, 0));
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(String value)
+ {
+ if (value == null)
+ return 0;
+ return SByte.Parse(value, CultureInfo.CurrentCulture);
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(String value, IFormatProvider provider)
+ {
+ return SByte.Parse(value, NumberStyles.Integer, provider);
+ }
+
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(DateTime value)
+ {
+ return ((IConvertible)value).ToSByte(null);
+ }
+
+ // Disallowed conversions to SByte
+ // public static sbyte ToSByte(TimeSpan value)
+
+ // Conversions to Byte
+
+ public static byte ToByte(object value)
+ {
+ return value == null ? (byte)0 : ((IConvertible)value).ToByte(null);
+ }
+
+ public static byte ToByte(object value, IFormatProvider provider)
+ {
+ return value == null ? (byte)0 : ((IConvertible)value).ToByte(provider);
+ }
+
+ public static byte ToByte(bool value)
+ {
+ return value ? (byte)Boolean.True : (byte)Boolean.False;
+ }
+
+ public static byte ToByte(byte value)
+ {
+ return value;
+ }
+
+ public static byte ToByte(char value)
+ {
+ if (value > Byte.MaxValue) ThrowByteOverflowException();
+ Contract.EndContractBlock();
+ return (byte)value;
+ }
+
+ [CLSCompliant(false)]
+ public static byte ToByte(sbyte value)
+ {
+ if (value < Byte.MinValue) ThrowByteOverflowException();
+ Contract.EndContractBlock();
+ return (byte)value;
+ }
+
+ public static byte ToByte(short value)
+ {
+ if (value < Byte.MinValue || value > Byte.MaxValue) ThrowByteOverflowException();
+ Contract.EndContractBlock();
+ return (byte)value;
+ }
+
+ [CLSCompliant(false)]
+ public static byte ToByte(ushort value)
+ {
+ if (value > Byte.MaxValue) ThrowByteOverflowException();
+ Contract.EndContractBlock();
+ return (byte)value;
+ }
+
+ public static byte ToByte(int value)
+ {
+ if (value < Byte.MinValue || value > Byte.MaxValue) ThrowByteOverflowException();
+ Contract.EndContractBlock();
+ return (byte)value;
+ }
+
+ [CLSCompliant(false)]
+ public static byte ToByte(uint value)
+ {
+ if (value > Byte.MaxValue) ThrowByteOverflowException();
+ Contract.EndContractBlock();
+ return (byte)value;
+ }
+
+ public static byte ToByte(long value)
+ {
+ if (value < Byte.MinValue || value > Byte.MaxValue) ThrowByteOverflowException();
+ Contract.EndContractBlock();
+ return (byte)value;
+ }
+
+ [CLSCompliant(false)]
+ public static byte ToByte(ulong value)
+ {
+ if (value > Byte.MaxValue) ThrowByteOverflowException();
+ Contract.EndContractBlock();
+ return (byte)value;
+ }
+
+ public static byte ToByte(float value)
+ {
+ return ToByte((double)value);
+ }
+
+ public static byte ToByte(double value)
+ {
+ return ToByte(ToInt32(value));
+ }
+
+ public static byte ToByte(decimal value)
+ {
+ return Decimal.ToByte(Decimal.Round(value, 0));
+ }
+
+ public static byte ToByte(String value)
+ {
+ if (value == null)
+ return 0;
+ return Byte.Parse(value, CultureInfo.CurrentCulture);
+ }
+
+ public static byte ToByte(String value, IFormatProvider provider)
+ {
+ if (value == null)
+ return 0;
+ return Byte.Parse(value, NumberStyles.Integer, provider);
+ }
+
+ public static byte ToByte(DateTime value)
+ {
+ return ((IConvertible)value).ToByte(null);
+ }
+
+
+ // Disallowed conversions to Byte
+ // public static byte ToByte(TimeSpan value)
+
+ // Conversions to Int16
+
+ public static short ToInt16(object value)
+ {
+ return value == null ? (short)0 : ((IConvertible)value).ToInt16(null);
+ }
+
+ public static short ToInt16(object value, IFormatProvider provider)
+ {
+ return value == null ? (short)0 : ((IConvertible)value).ToInt16(provider);
+ }
+
+ public static short ToInt16(bool value)
+ {
+ return value ? (short)Boolean.True : (short)Boolean.False;
+ }
+
+ public static short ToInt16(char value)
+ {
+ if (value > Int16.MaxValue) ThrowInt16OverflowException();
+ Contract.EndContractBlock();
+ return (short)value;
+ }
+
+ [CLSCompliant(false)]
+ public static short ToInt16(sbyte value)
+ {
+ return value;
+ }
+
+ public static short ToInt16(byte value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static short ToInt16(ushort value)
+ {
+ if (value > Int16.MaxValue) ThrowInt16OverflowException();
+ Contract.EndContractBlock();
+ return (short)value;
+ }
+
+ public static short ToInt16(int value)
+ {
+ if (value < Int16.MinValue || value > Int16.MaxValue) ThrowInt16OverflowException();
+ Contract.EndContractBlock();
+ return (short)value;
+ }
+
+ [CLSCompliant(false)]
+ public static short ToInt16(uint value)
+ {
+ if (value > Int16.MaxValue) ThrowInt16OverflowException();
+ Contract.EndContractBlock();
+ return (short)value;
+ }
+
+ public static short ToInt16(short value)
+ {
+ return value;
+ }
+
+ public static short ToInt16(long value)
+ {
+ if (value < Int16.MinValue || value > Int16.MaxValue) ThrowInt16OverflowException();
+ Contract.EndContractBlock();
+ return (short)value;
+ }
+
+ [CLSCompliant(false)]
+ public static short ToInt16(ulong value)
+ {
+ if (value > (ulong)Int16.MaxValue) ThrowInt16OverflowException();
+ Contract.EndContractBlock();
+ return (short)value;
+ }
+
+ public static short ToInt16(float value)
+ {
+ return ToInt16((double)value);
+ }
+
+ public static short ToInt16(double value)
+ {
+ return ToInt16(ToInt32(value));
+ }
+
+ public static short ToInt16(decimal value)
+ {
+ return Decimal.ToInt16(Decimal.Round(value, 0));
+ }
+
+ public static short ToInt16(String value)
+ {
+ if (value == null)
+ return 0;
+ return Int16.Parse(value, CultureInfo.CurrentCulture);
+ }
+
+ public static short ToInt16(String value, IFormatProvider provider)
+ {
+ if (value == null)
+ return 0;
+ return Int16.Parse(value, NumberStyles.Integer, provider);
+ }
+
+ public static short ToInt16(DateTime value)
+ {
+ return ((IConvertible)value).ToInt16(null);
+ }
+
+
+ // Disallowed conversions to Int16
+ // public static short ToInt16(TimeSpan value)
+
+ // Conversions to UInt16
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(object value)
+ {
+ return value == null ? (ushort)0 : ((IConvertible)value).ToUInt16(null);
+ }
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(object value, IFormatProvider provider)
+ {
+ return value == null ? (ushort)0 : ((IConvertible)value).ToUInt16(provider);
+ }
+
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(bool value)
+ {
+ return value ? (ushort)Boolean.True : (ushort)Boolean.False;
+ }
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(char value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(sbyte value)
+ {
+ if (value < 0) ThrowUInt16OverflowException();
+ Contract.EndContractBlock();
+ return (ushort)value;
+ }
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(byte value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(short value)
+ {
+ if (value < 0) ThrowUInt16OverflowException();
+ Contract.EndContractBlock();
+ return (ushort)value;
+ }
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(int value)
+ {
+ if (value < 0 || value > UInt16.MaxValue) ThrowUInt16OverflowException();
+ Contract.EndContractBlock();
+ return (ushort)value;
+ }
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(ushort value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(uint value)
+ {
+ if (value > UInt16.MaxValue) ThrowUInt16OverflowException();
+ Contract.EndContractBlock();
+ return (ushort)value;
+ }
+
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(long value)
+ {
+ if (value < 0 || value > UInt16.MaxValue) ThrowUInt16OverflowException();
+ Contract.EndContractBlock();
+ return (ushort)value;
+ }
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(ulong value)
+ {
+ if (value > UInt16.MaxValue) ThrowUInt16OverflowException();
+ Contract.EndContractBlock();
+ return (ushort)value;
+ }
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(float value)
+ {
+ return ToUInt16((double)value);
+ }
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(double value)
+ {
+ return ToUInt16(ToInt32(value));
+ }
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(decimal value)
+ {
+ return Decimal.ToUInt16(Decimal.Round(value, 0));
+ }
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(String value)
+ {
+ if (value == null)
+ return 0;
+ return UInt16.Parse(value, CultureInfo.CurrentCulture);
+ }
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(String value, IFormatProvider provider)
+ {
+ if (value == null)
+ return 0;
+ return UInt16.Parse(value, NumberStyles.Integer, provider);
+ }
+
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(DateTime value)
+ {
+ return ((IConvertible)value).ToUInt16(null);
+ }
+
+ // Disallowed conversions to UInt16
+ // public static ushort ToUInt16(TimeSpan value)
+
+ // Conversions to Int32
+
+ public static int ToInt32(object value)
+ {
+ return value == null ? 0 : ((IConvertible)value).ToInt32(null);
+ }
+
+ public static int ToInt32(object value, IFormatProvider provider)
+ {
+ return value == null ? 0 : ((IConvertible)value).ToInt32(provider);
+ }
+
+
+ public static int ToInt32(bool value)
+ {
+ return value ? Boolean.True : Boolean.False;
+ }
+
+ public static int ToInt32(char value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static int ToInt32(sbyte value)
+ {
+ return value;
+ }
+
+ public static int ToInt32(byte value)
+ {
+ return value;
+ }
+
+ public static int ToInt32(short value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static int ToInt32(ushort value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static int ToInt32(uint value)
+ {
+ if (value > Int32.MaxValue) ThrowInt32OverflowException();
+ Contract.EndContractBlock();
+ return (int)value;
+ }
+
+ public static int ToInt32(int value)
+ {
+ return value;
+ }
+
+ public static int ToInt32(long value)
+ {
+ if (value < Int32.MinValue || value > Int32.MaxValue) ThrowInt32OverflowException();
+ Contract.EndContractBlock();
+ return (int)value;
+ }
+
+ [CLSCompliant(false)]
+ public static int ToInt32(ulong value)
+ {
+ if (value > Int32.MaxValue) ThrowInt32OverflowException();
+ Contract.EndContractBlock();
+ return (int)value;
+ }
+
+ public static int ToInt32(float value)
+ {
+ return ToInt32((double)value);
+ }
+
+ public static int ToInt32(double value)
+ {
+ if (value >= 0)
+ {
+ if (value < 2147483647.5)
+ {
+ int result = (int)value;
+ double dif = value - result;
+ if (dif > 0.5 || dif == 0.5 && (result & 1) != 0) result++;
+ return result;
+ }
+ }
+ else
+ {
+ if (value >= -2147483648.5)
+ {
+ int result = (int)value;
+ double dif = value - result;
+ if (dif < -0.5 || dif == -0.5 && (result & 1) != 0) result--;
+ return result;
+ }
+ }
+ throw new OverflowException(SR.Overflow_Int32);
+ }
+
+ public static int ToInt32(decimal value)
+ {
+ return Decimal.ToInt32(Decimal.Round(value, 0));
+ }
+
+ public static int ToInt32(String value)
+ {
+ if (value == null)
+ return 0;
+ return Int32.Parse(value, CultureInfo.CurrentCulture);
+ }
+
+ public static int ToInt32(String value, IFormatProvider provider)
+ {
+ if (value == null)
+ return 0;
+ return Int32.Parse(value, NumberStyles.Integer, provider);
+ }
+
+ public static int ToInt32(DateTime value)
+ {
+ return ((IConvertible)value).ToInt32(null);
+ }
+
+
+ // Disallowed conversions to Int32
+ // public static int ToInt32(TimeSpan value)
+
+ // Conversions to UInt32
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(object value)
+ {
+ return value == null ? 0 : ((IConvertible)value).ToUInt32(null);
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(object value, IFormatProvider provider)
+ {
+ return value == null ? 0 : ((IConvertible)value).ToUInt32(provider);
+ }
+
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(bool value)
+ {
+ return value ? (uint)Boolean.True : (uint)Boolean.False;
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(char value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(sbyte value)
+ {
+ if (value < 0) ThrowUInt32OverflowException();
+ Contract.EndContractBlock();
+ return (uint)value;
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(byte value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(short value)
+ {
+ if (value < 0) ThrowUInt32OverflowException();
+ Contract.EndContractBlock();
+ return (uint)value;
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(ushort value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(int value)
+ {
+ if (value < 0) ThrowUInt32OverflowException();
+ Contract.EndContractBlock();
+ return (uint)value;
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(uint value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(long value)
+ {
+ if (value < 0 || value > UInt32.MaxValue) ThrowUInt32OverflowException();
+ Contract.EndContractBlock();
+ return (uint)value;
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(ulong value)
+ {
+ if (value > UInt32.MaxValue) ThrowUInt32OverflowException();
+ Contract.EndContractBlock();
+ return (uint)value;
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(float value)
+ {
+ return ToUInt32((double)value);
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(double value)
+ {
+ if (value >= -0.5 && value < 4294967295.5)
+ {
+ uint result = (uint)value;
+ double dif = value - result;
+ if (dif > 0.5 || dif == 0.5 && (result & 1) != 0) result++;
+ return result;
+ }
+ throw new OverflowException(SR.Overflow_UInt32);
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(decimal value)
+ {
+ return Decimal.ToUInt32(Decimal.Round(value, 0));
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(String value)
+ {
+ if (value == null)
+ return 0;
+ return UInt32.Parse(value, CultureInfo.CurrentCulture);
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(String value, IFormatProvider provider)
+ {
+ if (value == null)
+ return 0;
+ return UInt32.Parse(value, NumberStyles.Integer, provider);
+ }
+
+ [CLSCompliant(false)]
+ public static uint ToUInt32(DateTime value)
+ {
+ return ((IConvertible)value).ToUInt32(null);
+ }
+
+ // Disallowed conversions to UInt32
+ // public static uint ToUInt32(TimeSpan value)
+
+ // Conversions to Int64
+
+ public static long ToInt64(object value)
+ {
+ return value == null ? 0 : ((IConvertible)value).ToInt64(null);
+ }
+
+ public static long ToInt64(object value, IFormatProvider provider)
+ {
+ return value == null ? 0 : ((IConvertible)value).ToInt64(provider);
+ }
+
+
+ public static long ToInt64(bool value)
+ {
+ return value ? Boolean.True : Boolean.False;
+ }
+
+ public static long ToInt64(char value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static long ToInt64(sbyte value)
+ {
+ return value;
+ }
+
+ public static long ToInt64(byte value)
+ {
+ return value;
+ }
+
+ public static long ToInt64(short value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static long ToInt64(ushort value)
+ {
+ return value;
+ }
+
+ public static long ToInt64(int value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static long ToInt64(uint value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static long ToInt64(ulong value)
+ {
+ if (value > Int64.MaxValue) ThrowInt64OverflowException();
+ Contract.EndContractBlock();
+ return (long)value;
+ }
+
+ public static long ToInt64(long value)
+ {
+ return value;
+ }
+
+
+ public static long ToInt64(float value)
+ {
+ return ToInt64((double)value);
+ }
+
+ public static long ToInt64(double value)
+ {
+ return checked((long)Math.Round(value));
+ }
+
+ public static long ToInt64(decimal value)
+ {
+ return Decimal.ToInt64(Decimal.Round(value, 0));
+ }
+
+ public static long ToInt64(string value)
+ {
+ if (value == null)
+ return 0;
+ return Int64.Parse(value, CultureInfo.CurrentCulture);
+ }
+
+ public static long ToInt64(String value, IFormatProvider provider)
+ {
+ if (value == null)
+ return 0;
+ return Int64.Parse(value, NumberStyles.Integer, provider);
+ }
+
+ public static long ToInt64(DateTime value)
+ {
+ return ((IConvertible)value).ToInt64(null);
+ }
+
+ // Disallowed conversions to Int64
+ // public static long ToInt64(TimeSpan value)
+
+ // Conversions to UInt64
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(object value)
+ {
+ return value == null ? 0 : ((IConvertible)value).ToUInt64(null);
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(object value, IFormatProvider provider)
+ {
+ return value == null ? 0 : ((IConvertible)value).ToUInt64(provider);
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(bool value)
+ {
+ return value ? (ulong)Boolean.True : (ulong)Boolean.False;
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(char value)
+ {
+ return value;
+ }
+
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(sbyte value)
+ {
+ if (value < 0) ThrowUInt64OverflowException();
+ Contract.EndContractBlock();
+ return (ulong)value;
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(byte value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(short value)
+ {
+ if (value < 0) ThrowUInt64OverflowException();
+ Contract.EndContractBlock();
+ return (ulong)value;
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(ushort value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(int value)
+ {
+ if (value < 0) ThrowUInt64OverflowException();
+ Contract.EndContractBlock();
+ return (ulong)value;
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(uint value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(long value)
+ {
+ if (value < 0) ThrowUInt64OverflowException();
+ Contract.EndContractBlock();
+ return (ulong)value;
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(UInt64 value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(float value)
+ {
+ return ToUInt64((double)value);
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(double value)
+ {
+ return checked((ulong)Math.Round(value));
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(decimal value)
+ {
+ return Decimal.ToUInt64(Decimal.Round(value, 0));
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(String value)
+ {
+ if (value == null)
+ return 0;
+ return UInt64.Parse(value, CultureInfo.CurrentCulture);
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(String value, IFormatProvider provider)
+ {
+ if (value == null)
+ return 0;
+ return UInt64.Parse(value, NumberStyles.Integer, provider);
+ }
+
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(DateTime value)
+ {
+ return ((IConvertible)value).ToUInt64(null);
+ }
+
+ // Disallowed conversions to UInt64
+ // public static ulong ToUInt64(TimeSpan value)
+
+ // Conversions to Single
+
+ public static float ToSingle(object value)
+ {
+ return value == null ? 0 : ((IConvertible)value).ToSingle(null);
+ }
+
+ public static float ToSingle(object value, IFormatProvider provider)
+ {
+ return value == null ? 0 : ((IConvertible)value).ToSingle(provider);
+ }
+
+ [CLSCompliant(false)]
+ public static float ToSingle(sbyte value)
+ {
+ return value;
+ }
+
+ public static float ToSingle(byte value)
+ {
+ return value;
+ }
+
+ public static float ToSingle(char value)
+ {
+ return ((IConvertible)value).ToSingle(null);
+ }
+
+ public static float ToSingle(short value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static float ToSingle(ushort value)
+ {
+ return value;
+ }
+
+ public static float ToSingle(int value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static float ToSingle(uint value)
+ {
+ return value;
+ }
+
+ public static float ToSingle(long value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static float ToSingle(ulong value)
+ {
+ return value;
+ }
+
+ public static float ToSingle(float value)
+ {
+ return value;
+ }
+
+ public static float ToSingle(double value)
+ {
+ return (float)value;
+ }
+
+ public static float ToSingle(decimal value)
+ {
+ return (float)value;
+ }
+
+ public static float ToSingle(String value)
+ {
+ if (value == null)
+ return 0;
+ return Single.Parse(value, CultureInfo.CurrentCulture);
+ }
+
+ public static float ToSingle(String value, IFormatProvider provider)
+ {
+ if (value == null)
+ return 0;
+ return Single.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);
+ }
+
+
+ public static float ToSingle(bool value)
+ {
+ return value ? Boolean.True : Boolean.False;
+ }
+
+ public static float ToSingle(DateTime value)
+ {
+ return ((IConvertible)value).ToSingle(null);
+ }
+
+ // Disallowed conversions to Single
+ // public static float ToSingle(TimeSpan value)
+
+ // Conversions to Double
+
+ public static double ToDouble(object value)
+ {
+ return value == null ? 0 : ((IConvertible)value).ToDouble(null);
+ }
+
+ public static double ToDouble(object value, IFormatProvider provider)
+ {
+ return value == null ? 0 : ((IConvertible)value).ToDouble(provider);
+ }
+
+
+ [CLSCompliant(false)]
+ public static double ToDouble(sbyte value)
+ {
+ return value;
+ }
+
+ public static double ToDouble(byte value)
+ {
+ return value;
+ }
+
+ public static double ToDouble(short value)
+ {
+ return value;
+ }
+
+ public static double ToDouble(char value)
+ {
+ return ((IConvertible)value).ToDouble(null);
+ }
+
+ [CLSCompliant(false)]
+ public static double ToDouble(ushort value)
+ {
+ return value;
+ }
+
+ public static double ToDouble(int value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static double ToDouble(uint value)
+ {
+ return value;
+ }
+
+ public static double ToDouble(long value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static double ToDouble(ulong value)
+ {
+ return value;
+ }
+
+ public static double ToDouble(float value)
+ {
+ return value;
+ }
+
+ public static double ToDouble(double value)
+ {
+ return value;
+ }
+
+ public static double ToDouble(decimal value)
+ {
+ return (double)value;
+ }
+
+ public static double ToDouble(String value)
+ {
+ if (value == null)
+ return 0;
+ return Double.Parse(value, CultureInfo.CurrentCulture);
+ }
+
+ public static double ToDouble(String value, IFormatProvider provider)
+ {
+ if (value == null)
+ return 0;
+ return Double.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);
+ }
+
+ public static double ToDouble(bool value)
+ {
+ return value ? Boolean.True : Boolean.False;
+ }
+
+ public static double ToDouble(DateTime value)
+ {
+ return ((IConvertible)value).ToDouble(null);
+ }
+
+ // Disallowed conversions to Double
+ // public static double ToDouble(TimeSpan value)
+
+ // Conversions to Decimal
+
+ public static decimal ToDecimal(object value)
+ {
+ return value == null ? 0 : ((IConvertible)value).ToDecimal(null);
+ }
+
+ public static decimal ToDecimal(object value, IFormatProvider provider)
+ {
+ return value == null ? 0 : ((IConvertible)value).ToDecimal(provider);
+ }
+
+ [CLSCompliant(false)]
+ public static decimal ToDecimal(sbyte value)
+ {
+ return value;
+ }
+
+ public static decimal ToDecimal(byte value)
+ {
+ return value;
+ }
+
+ public static decimal ToDecimal(char value)
+ {
+ return ((IConvertible)value).ToDecimal(null);
+ }
+
+ public static decimal ToDecimal(short value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static decimal ToDecimal(ushort value)
+ {
+ return value;
+ }
+
+ public static decimal ToDecimal(int value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static decimal ToDecimal(uint value)
+ {
+ return value;
+ }
+
+ public static decimal ToDecimal(long value)
+ {
+ return value;
+ }
+
+ [CLSCompliant(false)]
+ public static decimal ToDecimal(ulong value)
+ {
+ return value;
+ }
+
+ public static decimal ToDecimal(float value)
+ {
+ return (decimal)value;
+ }
+
+ public static decimal ToDecimal(double value)
+ {
+ return (decimal)value;
+ }
+
+ public static decimal ToDecimal(String value)
+ {
+ if (value == null)
+ return 0m;
+ return Decimal.Parse(value, CultureInfo.CurrentCulture);
+ }
+
+ public static Decimal ToDecimal(String value, IFormatProvider provider)
+ {
+ if (value == null)
+ return 0m;
+ return Decimal.Parse(value, NumberStyles.Number, provider);
+ }
+
+ public static decimal ToDecimal(decimal value)
+ {
+ return value;
+ }
+
+ public static decimal ToDecimal(bool value)
+ {
+ return value ? Boolean.True : Boolean.False;
+ }
+
+ public static decimal ToDecimal(DateTime value)
+ {
+ return ((IConvertible)value).ToDecimal(null);
+ }
+
+ // Disallowed conversions to Decimal
+ // public static decimal ToDecimal(TimeSpan value)
+
+ // Conversions to DateTime
+
+ public static DateTime ToDateTime(DateTime value)
+ {
+ return value;
+ }
+
+ public static DateTime ToDateTime(object value)
+ {
+ return value == null ? DateTime.MinValue : ((IConvertible)value).ToDateTime(null);
+ }
+
+ public static DateTime ToDateTime(object value, IFormatProvider provider)
+ {
+ return value == null ? DateTime.MinValue : ((IConvertible)value).ToDateTime(provider);
+ }
+
+ public static DateTime ToDateTime(String value)
+ {
+ if (value == null)
+ return new DateTime(0);
+ return DateTime.Parse(value, CultureInfo.CurrentCulture);
+ }
+
+ public static DateTime ToDateTime(String value, IFormatProvider provider)
+ {
+ if (value == null)
+ return new DateTime(0);
+ return DateTime.Parse(value, provider);
+ }
+
+ [CLSCompliant(false)]
+ public static DateTime ToDateTime(sbyte value)
+ {
+ return ((IConvertible)value).ToDateTime(null);
+ }
+
+ public static DateTime ToDateTime(byte value)
+ {
+ return ((IConvertible)value).ToDateTime(null);
+ }
+
+ public static DateTime ToDateTime(short value)
+ {
+ return ((IConvertible)value).ToDateTime(null);
+ }
+
+ [CLSCompliant(false)]
+ public static DateTime ToDateTime(ushort value)
+ {
+ return ((IConvertible)value).ToDateTime(null);
+ }
+
+ public static DateTime ToDateTime(int value)
+ {
+ return ((IConvertible)value).ToDateTime(null);
+ }
+
+ [CLSCompliant(false)]
+ public static DateTime ToDateTime(uint value)
+ {
+ return ((IConvertible)value).ToDateTime(null);
+ }
+
+ public static DateTime ToDateTime(long value)
+ {
+ return ((IConvertible)value).ToDateTime(null);
+ }
+
+ [CLSCompliant(false)]
+ public static DateTime ToDateTime(ulong value)
+ {
+ return ((IConvertible)value).ToDateTime(null);
+ }
+
+ public static DateTime ToDateTime(bool value)
+ {
+ return ((IConvertible)value).ToDateTime(null);
+ }
+
+ public static DateTime ToDateTime(char value)
+ {
+ return ((IConvertible)value).ToDateTime(null);
+ }
+
+ public static DateTime ToDateTime(float value)
+ {
+ return ((IConvertible)value).ToDateTime(null);
+ }
+
+ public static DateTime ToDateTime(double value)
+ {
+ return ((IConvertible)value).ToDateTime(null);
+ }
+
+ public static DateTime ToDateTime(decimal value)
+ {
+ return ((IConvertible)value).ToDateTime(null);
+ }
+
+ // Disallowed conversions to DateTime
+ // public static DateTime ToDateTime(TimeSpan value)
+
+ // Conversions to String
+
+ public static string ToString(Object value)
+ {
+ return ToString(value, null);
+ }
+
+ public static string ToString(Object value, IFormatProvider provider)
+ {
+ IConvertible ic = value as IConvertible;
+ if (ic != null)
+ return ic.ToString(provider);
+ IFormattable formattable = value as IFormattable;
+ if (formattable != null)
+ return formattable.ToString(null, provider);
+ return value == null ? String.Empty : value.ToString();
+ }
+
+ public static string ToString(bool value)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString();
+ }
+
+ public static string ToString(bool value, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString();
+ }
+
+ public static string ToString(char value)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return Char.ToString(value);
+ }
+
+ public static string ToString(char value, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString();
+ }
+
+ [CLSCompliant(false)]
+ public static string ToString(sbyte value)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(CultureInfo.CurrentCulture);
+ }
+
+ [CLSCompliant(false)]
+ public static string ToString(sbyte value, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(provider);
+ }
+
+ public static string ToString(byte value)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(CultureInfo.CurrentCulture);
+ }
+
+ public static string ToString(byte value, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(provider);
+ }
+
+ public static string ToString(short value)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(CultureInfo.CurrentCulture);
+ }
+
+ public static string ToString(short value, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(provider);
+ }
+
+ [CLSCompliant(false)]
+ public static string ToString(ushort value)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(CultureInfo.CurrentCulture);
+ }
+
+ [CLSCompliant(false)]
+ public static string ToString(ushort value, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(provider);
+ }
+
+ public static string ToString(int value)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(CultureInfo.CurrentCulture);
+ }
+
+ public static string ToString(int value, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(provider);
+ }
+
+ [CLSCompliant(false)]
+ public static string ToString(uint value)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(CultureInfo.CurrentCulture);
+ }
+
+ [CLSCompliant(false)]
+ public static string ToString(uint value, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(provider);
+ }
+
+ public static string ToString(long value)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(CultureInfo.CurrentCulture);
+ }
+
+ public static string ToString(long value, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(provider);
+ }
+
+ [CLSCompliant(false)]
+ public static string ToString(ulong value)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(CultureInfo.CurrentCulture);
+ }
+
+ [CLSCompliant(false)]
+ public static string ToString(ulong value, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(provider);
+ }
+
+ public static string ToString(float value)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(CultureInfo.CurrentCulture);
+ }
+
+ public static string ToString(float value, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(provider);
+ }
+
+ public static string ToString(double value)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(CultureInfo.CurrentCulture);
+ }
+
+ public static string ToString(double value, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(provider);
+ }
+
+ public static string ToString(decimal value)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(CultureInfo.CurrentCulture);
+ }
+
+ public static string ToString(Decimal value, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(provider);
+ }
+
+ public static string ToString(DateTime value)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString();
+ }
+
+ public static string ToString(DateTime value, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<string>() != null);
+ return value.ToString(provider);
+ }
+
+ public static String ToString(String value)
+ {
+ Contract.Ensures(Contract.Result<string>() == value); // We were always skipping the null check here.
+ return value;
+ }
+
+ public static String ToString(String value, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<string>() == value); // We were always skipping the null check here.
+ return value; // avoid the null check
+ }
+
+
+ //
+ // Conversions which understand Base XXX numbers.
+ //
+ // Parses value in base base. base can only
+ // be 2, 8, 10, or 16. If base is 16, the number may be preceded
+ // by 0x; any other leading or trailing characters cause an error.
+ //
+ public static byte ToByte(String value, int fromBase)
+ {
+ if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
+ {
+ throw new ArgumentException(SR.Arg_InvalidBase);
+ }
+ Contract.EndContractBlock();
+ int r = ParseNumbers.StringToInt(value, fromBase, ParseNumbers.IsTight | ParseNumbers.TreatAsUnsigned);
+ if (r < Byte.MinValue || r > Byte.MaxValue)
+ ThrowByteOverflowException();
+ return (byte)r;
+ }
+
+ // Parses value in base fromBase. fromBase can only
+ // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
+ // by 0x; any other leading or trailing characters cause an error.
+ //
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(String value, int fromBase)
+ {
+ if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
+ {
+ throw new ArgumentException(SR.Arg_InvalidBase);
+ }
+ Contract.EndContractBlock();
+ int r = ParseNumbers.StringToInt(value, fromBase, ParseNumbers.IsTight | ParseNumbers.TreatAsI1);
+ if (fromBase != 10 && r <= Byte.MaxValue)
+ return (sbyte)r;
+
+ if (r < SByte.MinValue || r > SByte.MaxValue)
+ ThrowSByteOverflowException();
+ return (sbyte)r;
+ }
+
+ // Parses value in base fromBase. fromBase can only
+ // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
+ // by 0x; any other leading or trailing characters cause an error.
+ //
+ public static short ToInt16(String value, int fromBase)
+ {
+ if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
+ {
+ throw new ArgumentException(SR.Arg_InvalidBase);
+ }
+ Contract.EndContractBlock();
+ int r = ParseNumbers.StringToInt(value, fromBase, ParseNumbers.IsTight | ParseNumbers.TreatAsI2);
+ if (fromBase != 10 && r <= UInt16.MaxValue)
+ return (short)r;
+
+ if (r < Int16.MinValue || r > Int16.MaxValue)
+ ThrowInt16OverflowException();
+ return (short)r;
+ }
+
+ // Parses value in base fromBase. fromBase can only
+ // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
+ // by 0x; any other leading or trailing characters cause an error.
+ //
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(String value, int fromBase)
+ {
+ if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
+ {
+ throw new ArgumentException(SR.Arg_InvalidBase);
+ }
+ Contract.EndContractBlock();
+ int r = ParseNumbers.StringToInt(value, fromBase, ParseNumbers.IsTight | ParseNumbers.TreatAsUnsigned);
+ if (r < UInt16.MinValue || r > UInt16.MaxValue)
+ ThrowUInt16OverflowException();
+ return (ushort)r;
+ }
+
+ // Parses value in base fromBase. fromBase can only
+ // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
+ // by 0x; any other leading or trailing characters cause an error.
+ //
+ public static int ToInt32(String value, int fromBase)
+ {
+ if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
+ {
+ throw new ArgumentException(SR.Arg_InvalidBase);
+ }
+ Contract.EndContractBlock();
+ return ParseNumbers.StringToInt(value, fromBase, ParseNumbers.IsTight);
+ }
+
+ // Parses value in base fromBase. fromBase can only
+ // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
+ // by 0x; any other leading or trailing characters cause an error.
+ //
+ [CLSCompliant(false)]
+ public static uint ToUInt32(String value, int fromBase)
+ {
+ if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
+ {
+ throw new ArgumentException(SR.Arg_InvalidBase);
+ }
+ Contract.EndContractBlock();
+ return (uint)ParseNumbers.StringToInt(value, fromBase, ParseNumbers.TreatAsUnsigned | ParseNumbers.IsTight);
+ }
+
+ // Parses value in base fromBase. fromBase can only
+ // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
+ // by 0x; any other leading or trailing characters cause an error.
+ //
+ public static long ToInt64(String value, int fromBase)
+ {
+ if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
+ {
+ throw new ArgumentException(SR.Arg_InvalidBase);
+ }
+ Contract.EndContractBlock();
+ return ParseNumbers.StringToLong(value, fromBase, ParseNumbers.IsTight);
+ }
+
+ // Parses value in base fromBase. fromBase can only
+ // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
+ // by 0x; any other leading or trailing characters cause an error.
+ //
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(String value, int fromBase)
+ {
+ if (fromBase != 2 && fromBase != 8 && fromBase != 10 && fromBase != 16)
+ {
+ throw new ArgumentException(SR.Arg_InvalidBase);
+ }
+ Contract.EndContractBlock();
+ return (ulong)ParseNumbers.StringToLong(value, fromBase, ParseNumbers.TreatAsUnsigned | ParseNumbers.IsTight);
+ }
+
+ // Convert the byte value to a string in base fromBase
+ public static String ToString(byte value, int toBase)
+ {
+ if (toBase != 2 && toBase != 8 && toBase != 10 && toBase != 16)
+ {
+ throw new ArgumentException(SR.Arg_InvalidBase);
+ }
+ Contract.EndContractBlock();
+ return ParseNumbers.IntToString((int)value, toBase, -1, ' ', ParseNumbers.PrintAsI1);
+ }
+
+ // Convert the Int16 value to a string in base fromBase
+ public static String ToString(short value, int toBase)
+ {
+ if (toBase != 2 && toBase != 8 && toBase != 10 && toBase != 16)
+ {
+ throw new ArgumentException(SR.Arg_InvalidBase);
+ }
+ Contract.EndContractBlock();
+ return ParseNumbers.IntToString((int)value, toBase, -1, ' ', ParseNumbers.PrintAsI2);
+ }
+
+ // Convert the Int32 value to a string in base toBase
+ public static String ToString(int value, int toBase)
+ {
+ if (toBase != 2 && toBase != 8 && toBase != 10 && toBase != 16)
+ {
+ throw new ArgumentException(SR.Arg_InvalidBase);
+ }
+ Contract.EndContractBlock();
+ return ParseNumbers.IntToString(value, toBase, -1, ' ', 0);
+ }
+
+ // Convert the Int64 value to a string in base toBase
+ public static String ToString(long value, int toBase)
+ {
+ if (toBase != 2 && toBase != 8 && toBase != 10 && toBase != 16)
+ {
+ throw new ArgumentException(SR.Arg_InvalidBase);
+ }
+ Contract.EndContractBlock();
+ return ParseNumbers.LongToString(value, toBase, -1, ' ', 0);
+ }
+
+ public static String ToBase64String(byte[] inArray)
+ {
+ if (inArray == null)
+ {
+ throw new ArgumentNullException(nameof(inArray));
+ }
+ Contract.Ensures(Contract.Result<string>() != null);
+ Contract.EndContractBlock();
+ return ToBase64String(inArray, 0, inArray.Length, Base64FormattingOptions.None);
+ }
+
+ public static String ToBase64String(byte[] inArray, Base64FormattingOptions options)
+ {
+ if (inArray == null)
+ {
+ throw new ArgumentNullException(nameof(inArray));
+ }
+ Contract.Ensures(Contract.Result<string>() != null);
+ Contract.EndContractBlock();
+ return ToBase64String(inArray, 0, inArray.Length, options);
+ }
+
+ public static String ToBase64String(byte[] inArray, int offset, int length)
+ {
+ return ToBase64String(inArray, offset, length, Base64FormattingOptions.None);
+ }
+
+ public static unsafe String ToBase64String(byte[] inArray, int offset, int length, Base64FormattingOptions options)
+ {
+ //Do data verfication
+ if (inArray == null)
+ throw new ArgumentNullException(nameof(inArray));
+ if (length < 0)
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_Index);
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_GenericPositive);
+ if (options < Base64FormattingOptions.None || options > Base64FormattingOptions.InsertLineBreaks)
+ throw new ArgumentException(string.Format(SR.Arg_EnumIllegalVal, (int)options));
+ Contract.Ensures(Contract.Result<string>() != null);
+ Contract.EndContractBlock();
+
+ int inArrayLength;
+ int stringLength;
+
+ inArrayLength = inArray.Length;
+ if (offset > (inArrayLength - length))
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_OffsetLength);
+
+ if (inArrayLength == 0)
+ return String.Empty;
+
+ bool insertLineBreaks = (options == Base64FormattingOptions.InsertLineBreaks);
+ //Create the new string. This is the maximally required length.
+ stringLength = ToBase64_CalculateAndValidateOutputLength(length, insertLineBreaks);
+
+ string returnString = string.FastAllocateString(stringLength);
+ fixed (char* outChars = returnString)
+ {
+ fixed (byte* inData = &inArray[0])
+ {
+ int j = ConvertToBase64Array(outChars, inData, offset, length, insertLineBreaks);
+ Debug.Assert(returnString.Length == j, "returnString.Length == j");
+ return returnString;
+ }
+ }
+ }
+
+ public static int ToBase64CharArray(byte[] inArray, int offsetIn, int length, char[] outArray, int offsetOut)
+ {
+ Contract.Ensures(Contract.Result<int>() >= 0);
+ Contract.Ensures(Contract.Result<int>() <= outArray.Length);
+ Contract.EndContractBlock();
+
+ return ToBase64CharArray(inArray, offsetIn, length, outArray, offsetOut, Base64FormattingOptions.None);
+ }
+
+ public static unsafe int ToBase64CharArray(byte[] inArray, int offsetIn, int length, char[] outArray, int offsetOut, Base64FormattingOptions options)
+ {
+ //Do data verfication
+ if (inArray == null)
+ throw new ArgumentNullException(nameof(inArray));
+ if (outArray == null)
+ throw new ArgumentNullException(nameof(outArray));
+ if (length < 0)
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_Index);
+ if (offsetIn < 0)
+ throw new ArgumentOutOfRangeException(nameof(offsetIn), SR.ArgumentOutOfRange_GenericPositive);
+ if (offsetOut < 0)
+ throw new ArgumentOutOfRangeException(nameof(offsetOut), SR.ArgumentOutOfRange_GenericPositive);
+
+ if (options < Base64FormattingOptions.None || options > Base64FormattingOptions.InsertLineBreaks)
+ {
+ throw new ArgumentException(string.Format(SR.Arg_EnumIllegalVal, (int)options));
+ }
+ Contract.Ensures(Contract.Result<int>() >= 0);
+ Contract.Ensures(Contract.Result<int>() <= outArray.Length);
+ Contract.EndContractBlock();
+
+
+ int retVal;
+
+ int inArrayLength;
+ int outArrayLength;
+ int numElementsToCopy;
+
+ inArrayLength = inArray.Length;
+
+ if (offsetIn > (int)(inArrayLength - length))
+ throw new ArgumentOutOfRangeException(nameof(offsetIn), SR.ArgumentOutOfRange_OffsetLength);
+
+ if (inArrayLength == 0)
+ return 0;
+
+ bool insertLineBreaks = (options == Base64FormattingOptions.InsertLineBreaks);
+ //This is the maximally required length that must be available in the char array
+ outArrayLength = outArray.Length;
+
+ // Length of the char buffer required
+ numElementsToCopy = ToBase64_CalculateAndValidateOutputLength(length, insertLineBreaks);
+
+ if (offsetOut > (int)(outArrayLength - numElementsToCopy))
+ throw new ArgumentOutOfRangeException(nameof(offsetOut), SR.ArgumentOutOfRange_OffsetOut);
+
+ fixed (char* outChars = &outArray[offsetOut])
+ {
+ fixed (byte* inData = &inArray[0])
+ {
+ retVal = ConvertToBase64Array(outChars, inData, offsetIn, length, insertLineBreaks);
+ }
+ }
+
+ return retVal;
+ }
+
+ private static unsafe int ConvertToBase64Array(char* outChars, byte* inData, int offset, int length, bool insertLineBreaks)
+ {
+ int lengthmod3 = length % 3;
+ int calcLength = offset + (length - lengthmod3);
+ int j = 0;
+ int charcount = 0;
+ //Convert three bytes at a time to base64 notation. This will consume 4 chars.
+ int i;
+
+ // get a pointer to the base64Table to avoid unnecessary range checking
+ fixed (char* base64 = &base64Table[0])
+ {
+ for (i = offset; i < calcLength; i += 3)
+ {
+ if (insertLineBreaks)
+ {
+ if (charcount == base64LineBreakPosition)
+ {
+ outChars[j++] = '\r';
+ outChars[j++] = '\n';
+ charcount = 0;
+ }
+ charcount += 4;
+ }
+ outChars[j] = base64[(inData[i] & 0xfc) >> 2];
+ outChars[j + 1] = base64[((inData[i] & 0x03) << 4) | ((inData[i + 1] & 0xf0) >> 4)];
+ outChars[j + 2] = base64[((inData[i + 1] & 0x0f) << 2) | ((inData[i + 2] & 0xc0) >> 6)];
+ outChars[j + 3] = base64[(inData[i + 2] & 0x3f)];
+ j += 4;
+ }
+
+ //Where we left off before
+ i = calcLength;
+
+ if (insertLineBreaks && (lengthmod3 != 0) && (charcount == base64LineBreakPosition))
+ {
+ outChars[j++] = '\r';
+ outChars[j++] = '\n';
+ }
+
+ switch (lengthmod3)
+ {
+ case 2: //One character padding needed
+ outChars[j] = base64[(inData[i] & 0xfc) >> 2];
+ outChars[j + 1] = base64[((inData[i] & 0x03) << 4) | ((inData[i + 1] & 0xf0) >> 4)];
+ outChars[j + 2] = base64[(inData[i + 1] & 0x0f) << 2];
+ outChars[j + 3] = base64[64]; //Pad
+ j += 4;
+ break;
+ case 1: // Two character padding needed
+ outChars[j] = base64[(inData[i] & 0xfc) >> 2];
+ outChars[j + 1] = base64[(inData[i] & 0x03) << 4];
+ outChars[j + 2] = base64[64]; //Pad
+ outChars[j + 3] = base64[64]; //Pad
+ j += 4;
+ break;
+ }
+ }
+
+ return j;
+ }
+
+ private static int ToBase64_CalculateAndValidateOutputLength(int inputLength, bool insertLineBreaks)
+ {
+ long outlen = ((long)inputLength) / 3 * 4; // the base length - we want integer division here.
+ outlen += ((inputLength % 3) != 0) ? 4 : 0; // at most 4 more chars for the remainder
+
+ if (outlen == 0)
+ return 0;
+
+ if (insertLineBreaks)
+ {
+ long newLines = outlen / base64LineBreakPosition;
+ if ((outlen % base64LineBreakPosition) == 0)
+ {
+ --newLines;
+ }
+ outlen += newLines * 2; // the number of line break chars we'll add, "\r\n"
+ }
+
+ // If we overflow an int then we cannot allocate enough
+ // memory to output the value so throw
+ if (outlen > int.MaxValue)
+ throw new OutOfMemoryException();
+
+ return (int)outlen;
+ }
+
+
+ /// <summary>
+ /// Converts the specified string, which encodes binary data as Base64 digits, to the equivalent byte array.
+ /// </summary>
+ /// <param name="s">The string to convert</param>
+ /// <returns>The array of bytes represented by the specifed Base64 string.</returns>
+ public static Byte[] FromBase64String(String s)
+ {
+ // "s" is an unfortunate parameter name, but we need to keep it for backward compat.
+
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+
+ Contract.EndContractBlock();
+
+ unsafe
+ {
+ fixed (Char* sPtr = s)
+ {
+ return FromBase64CharPtr(sPtr, s.Length);
+ }
+ }
+ }
+
+
+ /// <summary>
+ /// Converts the specified range of a Char array, which encodes binary data as Base64 digits, to the equivalent byte array.
+ /// </summary>
+ /// <param name="inArray">Chars representing Base64 encoding characters</param>
+ /// <param name="offset">A position within the input array.</param>
+ /// <param name="length">Number of element to convert.</param>
+ /// <returns>The array of bytes represented by the specified Base64 encoding characters.</returns>
+ public static Byte[] FromBase64CharArray(Char[] inArray, Int32 offset, Int32 length)
+ {
+ if (inArray == null)
+ throw new ArgumentNullException(nameof(inArray));
+
+ if (length < 0)
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_Index);
+
+ if (offset < 0)
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_GenericPositive);
+
+ if (offset > inArray.Length - length)
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_OffsetLength);
+
+ Contract.EndContractBlock();
+
+ if (inArray.Length == 0)
+ {
+ return Array.Empty<byte>();
+ }
+
+ unsafe
+ {
+ fixed (Char* inArrayPtr = &inArray[0])
+ {
+ return FromBase64CharPtr(inArrayPtr + offset, length);
+ }
+ }
+ }
+
+
+
+ /// <summary>
+ /// Convert Base64 encoding characters to bytes:
+ /// - Compute result length exactly by actually walking the input;
+ /// - Allocate new result array based on computation;
+ /// - Decode input into the new array;
+ /// </summary>
+ /// <param name="inputPtr">Pointer to the first input char</param>
+ /// <param name="inputLength">Number of input chars</param>
+ /// <returns></returns>
+ private static unsafe Byte[] FromBase64CharPtr(Char* inputPtr, Int32 inputLength)
+ {
+ // The validity of parameters much be checked by callers, thus we are Critical here.
+
+ Debug.Assert(0 <= inputLength);
+
+ // We need to get rid of any trailing white spaces.
+ // Otherwise we would be rejecting input such as "abc= ":
+ while (inputLength > 0)
+ {
+ Int32 lastChar = inputPtr[inputLength - 1];
+ if (lastChar != (Int32)' ' && lastChar != (Int32)'\n' && lastChar != (Int32)'\r' && lastChar != (Int32)'\t')
+ break;
+ inputLength--;
+ }
+
+ // Compute the output length:
+ Int32 resultLength = FromBase64_ComputeResultLength(inputPtr, inputLength);
+
+ Debug.Assert(0 <= resultLength);
+
+ // resultLength can be zero. We will still enter FromBase64_Decode and process the input.
+ // It may either simply write no bytes (e.g. input = " ") or throw (e.g. input = "ab").
+
+ // Create result byte blob:
+ Byte[] decodedBytes = new Byte[resultLength];
+
+ // Convert Base64 chars into bytes:
+ Int32 actualResultLength;
+ fixed (Byte* decodedBytesPtr = decodedBytes)
+ actualResultLength = FromBase64_Decode(inputPtr, inputLength, decodedBytesPtr, resultLength);
+
+ // Note that actualResultLength can differ from resultLength if the caller is modifying the array
+ // as it is being converted. Silently ignore the failure.
+ // Consider throwing exception in an non in-place release.
+
+ // We are done:
+ return decodedBytes;
+ }
+
+
+ /// <summary>
+ /// Decode characters representing a Base64 encoding into bytes:
+ /// Walk the input. Every time 4 chars are read, convert them to the 3 corresponding output bytes.
+ /// This method is a bit lengthy on purpose. We are trying to avoid jumps to helpers in the loop
+ /// to aid performance.
+ /// </summary>
+ /// <param name="inputPtr">Pointer to first input char</param>
+ /// <param name="inputLength">Number of input chars</param>
+ /// <param name="destPtr">Pointer to location for the first result byte</param>
+ /// <param name="destLength">Max length of the preallocated result buffer</param>
+ /// <returns>If the result buffer was not large enough to write all result bytes, return -1;
+ /// Otherwise return the number of result bytes actually produced.</returns>
+ private static unsafe Int32 FromBase64_Decode(Char* startInputPtr, Int32 inputLength, Byte* startDestPtr, Int32 destLength)
+ {
+ // You may find this method weird to look at. It's written for performance, not aesthetics.
+ // You will find unrolled loops label jumps and bit manipulations.
+
+ const UInt32 intA = (UInt32)'A';
+ const UInt32 inta = (UInt32)'a';
+ const UInt32 int0 = (UInt32)'0';
+ const UInt32 intEq = (UInt32)'=';
+ const UInt32 intPlus = (UInt32)'+';
+ const UInt32 intSlash = (UInt32)'/';
+ const UInt32 intSpace = (UInt32)' ';
+ const UInt32 intTab = (UInt32)'\t';
+ const UInt32 intNLn = (UInt32)'\n';
+ const UInt32 intCRt = (UInt32)'\r';
+ const UInt32 intAtoZ = (UInt32)('Z' - 'A'); // = ('z' - 'a')
+ const UInt32 int0to9 = (UInt32)('9' - '0');
+
+ Char* inputPtr = startInputPtr;
+ Byte* destPtr = startDestPtr;
+
+ // Pointers to the end of input and output:
+ Char* endInputPtr = inputPtr + inputLength;
+ Byte* endDestPtr = destPtr + destLength;
+
+ // Current char code/value:
+ UInt32 currCode;
+
+ // This 4-byte integer will contain the 4 codes of the current 4-char group.
+ // Eeach char codes for 6 bits = 24 bits.
+ // The remaining byte will be FF, we use it as a marker when 4 chars have been processed.
+ UInt32 currBlockCodes = 0x000000FFu;
+
+ unchecked
+ {
+ while (true)
+ {
+ // break when done:
+ if (inputPtr >= endInputPtr)
+ goto _AllInputConsumed;
+
+ // Get current char:
+ currCode = (UInt32)(*inputPtr);
+ inputPtr++;
+
+ // Determine current char code:
+
+ if (currCode - intA <= intAtoZ)
+ currCode -= intA;
+
+ else if (currCode - inta <= intAtoZ)
+ currCode -= (inta - 26u);
+
+ else if (currCode - int0 <= int0to9)
+ currCode -= (int0 - 52u);
+
+ else
+ {
+ // Use the slower switch for less common cases:
+ switch (currCode)
+ {
+ // Significant chars:
+ case intPlus:
+ currCode = 62u;
+ break;
+
+ case intSlash:
+ currCode = 63u;
+ break;
+
+ // Legal no-value chars (we ignore these):
+ case intCRt:
+ case intNLn:
+ case intSpace:
+ case intTab:
+ continue;
+
+ // The equality char is only legal at the end of the input.
+ // Jump after the loop to make it easier for the JIT register predictor to do a good job for the loop itself:
+ case intEq:
+ goto _EqualityCharEncountered;
+
+ // Other chars are illegal:
+ default:
+ throw new FormatException(SR.Format_BadBase64Char);
+ }
+ }
+
+ // Ok, we got the code. Save it:
+ currBlockCodes = (currBlockCodes << 6) | currCode;
+
+ // Last bit in currBlockCodes will be on after in shifted right 4 times:
+ if ((currBlockCodes & 0x80000000u) != 0u)
+ {
+ if ((Int32)(endDestPtr - destPtr) < 3)
+ return -1;
+
+ *(destPtr) = (Byte)(currBlockCodes >> 16);
+ *(destPtr + 1) = (Byte)(currBlockCodes >> 8);
+ *(destPtr + 2) = (Byte)(currBlockCodes);
+ destPtr += 3;
+
+ currBlockCodes = 0x000000FFu;
+ }
+ }
+ } // unchecked while
+
+ // 'd be nice to have an assert that we never get here, but CS0162: Unreachable code detected.
+ // Debug.Assert(false, "We only leave the above loop by jumping; should never get here.");
+
+ // We jump here out of the loop if we hit an '=':
+ _EqualityCharEncountered:
+
+ Debug.Assert(currCode == intEq);
+
+ // Recall that inputPtr is now one position past where '=' was read.
+ // '=' can only be at the last input pos:
+ if (inputPtr == endInputPtr)
+ {
+ // Code is zero for trailing '=':
+ currBlockCodes <<= 6;
+
+ // The '=' did not complete a 4-group. The input must be bad:
+ if ((currBlockCodes & 0x80000000u) == 0u)
+ throw new FormatException(SR.Format_BadBase64CharArrayLength);
+
+ if ((int)(endDestPtr - destPtr) < 2) // Autch! We underestimated the output length!
+ return -1;
+
+ // We are good, store bytes form this past group. We had a single "=", so we take two bytes:
+ *(destPtr++) = (Byte)(currBlockCodes >> 16);
+ *(destPtr++) = (Byte)(currBlockCodes >> 8);
+
+ currBlockCodes = 0x000000FFu;
+ }
+ else
+ { // '=' can also be at the pre-last position iff the last is also a '=' excluding the white spaces:
+ // We need to get rid of any intermediate white spaces.
+ // Otherwise we would be rejecting input such as "abc= =":
+ while (inputPtr < (endInputPtr - 1))
+ {
+ Int32 lastChar = *(inputPtr);
+ if (lastChar != (Int32)' ' && lastChar != (Int32)'\n' && lastChar != (Int32)'\r' && lastChar != (Int32)'\t')
+ break;
+ inputPtr++;
+ }
+
+ if (inputPtr == (endInputPtr - 1) && *(inputPtr) == '=')
+ {
+ // Code is zero for each of the two '=':
+ currBlockCodes <<= 12;
+
+ // The '=' did not complete a 4-group. The input must be bad:
+ if ((currBlockCodes & 0x80000000u) == 0u)
+ throw new FormatException(SR.Format_BadBase64CharArrayLength);
+
+ if ((Int32)(endDestPtr - destPtr) < 1) // Autch! We underestimated the output length!
+ return -1;
+
+ // We are good, store bytes form this past group. We had a "==", so we take only one byte:
+ *(destPtr++) = (Byte)(currBlockCodes >> 16);
+
+ currBlockCodes = 0x000000FFu;
+ }
+ else // '=' is not ok at places other than the end:
+ throw new FormatException(SR.Format_BadBase64Char);
+ }
+
+ // We get here either from above or by jumping out of the loop:
+ _AllInputConsumed:
+
+ // The last block of chars has less than 4 items
+ if (currBlockCodes != 0x000000FFu)
+ throw new FormatException(SR.Format_BadBase64CharArrayLength);
+
+ // Return how many bytes were actually recovered:
+ return (Int32)(destPtr - startDestPtr);
+ } // Int32 FromBase64_Decode(...)
+
+
+ /// <summary>
+ /// Compute the number of bytes encoded in the specified Base 64 char array:
+ /// Walk the entire input counting white spaces and padding chars, then compute result length
+ /// based on 3 bytes per 4 chars.
+ /// </summary>
+ private static unsafe Int32 FromBase64_ComputeResultLength(Char* inputPtr, Int32 inputLength)
+ {
+ const UInt32 intEq = (UInt32)'=';
+ const UInt32 intSpace = (UInt32)' ';
+
+ Debug.Assert(0 <= inputLength);
+
+ Char* inputEndPtr = inputPtr + inputLength;
+ Int32 usefulInputLength = inputLength;
+ Int32 padding = 0;
+
+ while (inputPtr < inputEndPtr)
+ {
+ UInt32 c = (UInt32)(*inputPtr);
+ inputPtr++;
+
+ // We want to be as fast as possible and filter out spaces with as few comparisons as possible.
+ // We end up accepting a number of illegal chars as legal white-space chars.
+ // This is ok: as soon as we hit them during actual decode we will recognise them as illegal and throw.
+ if (c <= intSpace)
+ usefulInputLength--;
+
+ else if (c == intEq)
+ {
+ usefulInputLength--;
+ padding++;
+ }
+ }
+
+ Debug.Assert(0 <= usefulInputLength);
+
+ // For legal input, we can assume that 0 <= padding < 3. But it may be more for illegal input.
+ // We will notice it at decode when we see a '=' at the wrong place.
+ Debug.Assert(0 <= padding);
+
+ // Perf: reuse the variable that stored the number of '=' to store the number of bytes encoded by the
+ // last group that contains the '=':
+ if (padding != 0)
+ {
+ if (padding == 1)
+ padding = 2;
+ else if (padding == 2)
+ padding = 1;
+ else
+ throw new FormatException(SR.Format_BadBase64Char);
+ }
+
+ // Done:
+ return (usefulInputLength / 4) * 3 + padding;
+ }
+ } // class Convert
+} // namespace
+
diff --git a/src/mscorlib/shared/System/CurrentSystemTimeZone.cs b/src/mscorlib/shared/System/CurrentSystemTimeZone.cs
new file mode 100644
index 0000000000..2d848397a9
--- /dev/null
+++ b/src/mscorlib/shared/System/CurrentSystemTimeZone.cs
@@ -0,0 +1,199 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose:
+** This class represents the current system timezone. It is
+** the only meaningful implementation of the TimeZone class
+** available in this version.
+**
+** The only TimeZone that we support in version 1 is the
+** CurrentTimeZone as determined by the system timezone.
+**
+**
+============================================================*/
+
+using System;
+using System.Diagnostics.Contracts;
+using System.Text;
+using System.Collections;
+using System.Globalization;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+
+namespace System
+{
+ [Obsolete("System.CurrentSystemTimeZone has been deprecated. Please investigate the use of System.TimeZoneInfo.Local instead.")]
+ [Serializable]
+ internal partial class CurrentSystemTimeZone : TimeZone
+ {
+ // Standard offset in ticks to the Universal time if
+ // no daylight saving is in used.
+ // E.g. the offset for PST (Pacific Standard time) should be -8 * 60 * 60 * 1000 * 10000.
+ // (1 millisecond = 10000 ticks)
+ private long m_ticksOffset;
+ private String m_standardName;
+ private String m_daylightName;
+
+ internal CurrentSystemTimeZone()
+ {
+ TimeZoneInfo local = TimeZoneInfo.Local;
+
+ m_ticksOffset = local.BaseUtcOffset.Ticks;
+ m_standardName = local.StandardName;
+ m_daylightName = local.DaylightName;
+ }
+
+ public override String StandardName
+ {
+ get
+ {
+ return m_standardName;
+ }
+ }
+
+ public override String DaylightName
+ {
+ get
+ {
+ return m_daylightName;
+ }
+ }
+
+ internal long GetUtcOffsetFromUniversalTime(DateTime time, ref Boolean isAmbiguousLocalDst)
+ {
+ // Get the daylight changes for the year of the specified time.
+ TimeSpan offset = new TimeSpan(m_ticksOffset);
+ DaylightTime daylightTime = GetDaylightChanges(time.Year);
+ isAmbiguousLocalDst = false;
+
+ if (daylightTime == null || daylightTime.Delta.Ticks == 0)
+ {
+ return offset.Ticks;
+ }
+
+ // The start and end times represent the range of universal times that are in DST for that year.
+ // Within that there is an ambiguous hour, usually right at the end, but at the beginning in
+ // the unusual case of a negative daylight savings delta.
+ DateTime startTime = daylightTime.Start - offset;
+ DateTime endTime = daylightTime.End - offset - daylightTime.Delta;
+ DateTime ambiguousStart;
+ DateTime ambiguousEnd;
+
+ if (daylightTime.Delta.Ticks > 0)
+ {
+ ambiguousStart = endTime - daylightTime.Delta;
+ ambiguousEnd = endTime;
+ }
+ else
+ {
+ ambiguousStart = startTime;
+ ambiguousEnd = startTime - daylightTime.Delta;
+ }
+
+ Boolean isDst = false;
+ if (startTime > endTime)
+ {
+ // In southern hemisphere, the daylight saving time starts later in the year, and ends in the beginning of next year.
+ // Note, the summer in the southern hemisphere begins late in the year.
+ isDst = (time < endTime || time >= startTime);
+ }
+ else
+ {
+ // In northern hemisphere, the daylight saving time starts in the middle of the year.
+ isDst = (time >= startTime && time < endTime);
+ }
+
+ if (isDst)
+ {
+ offset += daylightTime.Delta;
+
+ // See if the resulting local time becomes ambiguous. This must be captured here or the
+ // DateTime will not be able to round-trip back to UTC accurately.
+ if (time >= ambiguousStart && time < ambiguousEnd)
+ {
+ isAmbiguousLocalDst = true;
+ }
+ }
+ return offset.Ticks;
+ }
+
+ public override DateTime ToLocalTime(DateTime time)
+ {
+ if (time.Kind == DateTimeKind.Local)
+ {
+ return time;
+ }
+ Boolean isAmbiguousLocalDst = false;
+ Int64 offset = GetUtcOffsetFromUniversalTime(time, ref isAmbiguousLocalDst);
+ long tick = time.Ticks + offset;
+ if (tick > DateTime.MaxTicks)
+ {
+ return new DateTime(DateTime.MaxTicks, DateTimeKind.Local);
+ }
+ if (tick < DateTime.MinTicks)
+ {
+ return new DateTime(DateTime.MinTicks, DateTimeKind.Local);
+ }
+ return new DateTime(tick, DateTimeKind.Local, isAmbiguousLocalDst);
+ }
+
+ public override DaylightTime GetDaylightChanges(int year)
+ {
+ if (year < 1 || year > 9999)
+ {
+ throw new ArgumentOutOfRangeException(nameof(year), SR.Format(SR.ArgumentOutOfRange_Range, 1, 9999));
+ }
+
+ return GetCachedDaylightChanges(year);
+ }
+
+ private static DaylightTime CreateDaylightChanges(int year)
+ {
+ DaylightTime currentDaylightChanges = null;
+
+ if (TimeZoneInfo.Local.SupportsDaylightSavingTime)
+ {
+ DateTime start;
+ DateTime end;
+ TimeSpan delta;
+
+ foreach (var rule in TimeZoneInfo.Local.GetAdjustmentRules())
+ {
+ if (rule.DateStart.Year <= year && rule.DateEnd.Year >= year && rule.DaylightDelta != TimeSpan.Zero)
+ {
+ start = TimeZoneInfo.TransitionTimeToDateTime(year, rule.DaylightTransitionStart);
+ end = TimeZoneInfo.TransitionTimeToDateTime(year, rule.DaylightTransitionEnd);
+ delta = rule.DaylightDelta;
+
+ currentDaylightChanges = new DaylightTime(start, end, delta);
+ break;
+ }
+ }
+ }
+
+ if (currentDaylightChanges == null)
+ {
+ currentDaylightChanges = new DaylightTime(DateTime.MinValue, DateTime.MinValue, TimeSpan.Zero);
+ }
+
+ return currentDaylightChanges;
+ }
+
+ public override TimeSpan GetUtcOffset(DateTime time)
+ {
+ if (time.Kind == DateTimeKind.Utc)
+ {
+ return TimeSpan.Zero;
+ }
+ else
+ {
+ return new TimeSpan(TimeZone.CalculateUtcOffset(time, GetDaylightChanges(time.Year)).Ticks + m_ticksOffset);
+ }
+ }
+ } // class CurrentSystemTimeZone
+}
diff --git a/src/mscorlib/shared/System/DBNull.cs b/src/mscorlib/shared/System/DBNull.cs
new file mode 100644
index 0000000000..486eb72f2a
--- /dev/null
+++ b/src/mscorlib/shared/System/DBNull.cs
@@ -0,0 +1,119 @@
+// 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.Runtime.Serialization;
+
+namespace System
+{
+ [Serializable]
+ public sealed class DBNull : ISerializable, IConvertible
+ {
+ private DBNull()
+ {
+ }
+
+ private DBNull(SerializationInfo info, StreamingContext context)
+ {
+ throw new NotSupportedException(SR.NotSupported_DBNullSerial);
+ }
+
+ public static readonly DBNull Value = new DBNull();
+
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ UnitySerializationHolder.GetUnitySerializationInfo(info, UnitySerializationHolder.NullUnity, null, null);
+ }
+
+ public override string ToString()
+ {
+ return string.Empty;
+ }
+
+ public string ToString(IFormatProvider provider)
+ {
+ return string.Empty;
+ }
+
+ public TypeCode GetTypeCode()
+ {
+ return TypeCode.DBNull;
+ }
+
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.InvalidCast_FromDBNull);
+ }
+
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.InvalidCast_FromDBNull);
+ }
+
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.InvalidCast_FromDBNull);
+ }
+
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.InvalidCast_FromDBNull);
+ }
+
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.InvalidCast_FromDBNull);
+ }
+
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.InvalidCast_FromDBNull);
+ }
+
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.InvalidCast_FromDBNull);
+ }
+
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.InvalidCast_FromDBNull);
+ }
+
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.InvalidCast_FromDBNull);
+ }
+
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.InvalidCast_FromDBNull);
+ }
+
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.InvalidCast_FromDBNull);
+ }
+
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.InvalidCast_FromDBNull);
+ }
+
+ decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.InvalidCast_FromDBNull);
+ }
+
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.InvalidCast_FromDBNull);
+ }
+
+ object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
+ return Convert.DefaultToType((IConvertible)this, type, provider);
+ }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/DataMisalignedException.cs b/src/mscorlib/shared/System/DataMisalignedException.cs
new file mode 100644
index 0000000000..b1991a048e
--- /dev/null
+++ b/src/mscorlib/shared/System/DataMisalignedException.cs
@@ -0,0 +1,39 @@
+// 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.
+
+/*=============================================================================
+**
+**
+** Purpose: The exception class for a misaligned access exception
+**
+=============================================================================*/
+
+using System.Runtime.Serialization;
+
+namespace System
+{
+ [Serializable]
+ public sealed class DataMisalignedException : SystemException
+ {
+ public DataMisalignedException()
+ : base(SR.Arg_DataMisalignedException)
+ {
+ HResult = __HResults.COR_E_DATAMISALIGNED;
+ }
+
+ public DataMisalignedException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_DATAMISALIGNED;
+ }
+
+ public DataMisalignedException(String message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_DATAMISALIGNED;
+ }
+
+ internal DataMisalignedException(SerializationInfo info, StreamingContext context) : base(info, context) { }
+ }
+}
diff --git a/src/mscorlib/shared/System/DateTime.cs b/src/mscorlib/shared/System/DateTime.cs
new file mode 100644
index 0000000000..ddb72da77d
--- /dev/null
+++ b/src/mscorlib/shared/System/DateTime.cs
@@ -0,0 +1,1516 @@
+// 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.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Threading;
+using System.Globalization;
+using System.Runtime;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
+using System.Runtime.Versioning;
+using System.Security;
+using CultureInfo = System.Globalization.CultureInfo;
+using Calendar = System.Globalization.Calendar;
+
+namespace System
+{
+
+ // This value type represents a date and time. Every DateTime
+ // object has a private field (Ticks) of type Int64 that stores the
+ // date and time as the number of 100 nanosecond intervals since
+ // 12:00 AM January 1, year 1 A.D. in the proleptic Gregorian Calendar.
+ //
+ // Starting from V2.0, DateTime also stored some context about its time
+ // zone in the form of a 3-state value representing Unspecified, Utc or
+ // Local. This is stored in the two top bits of the 64-bit numeric value
+ // with the remainder of the bits storing the tick count. This information
+ // is only used during time zone conversions and is not part of the
+ // identity of the DateTime. Thus, operations like Compare and Equals
+ // ignore this state. This is to stay compatible with earlier behavior
+ // and performance characteristics and to avoid forcing people into dealing
+ // with the effects of daylight savings. Note, that this has little effect
+ // on how the DateTime works except in a context where its specific time
+ // zone is needed, such as during conversions and some parsing and formatting
+ // cases.
+ //
+ // There is also 4th state stored that is a special type of Local value that
+ // is used to avoid data loss when round-tripping between local and UTC time.
+ // See below for more information on this 4th state, although it is
+ // effectively hidden from most users, who just see the 3-state DateTimeKind
+ // enumeration.
+ //
+ // For compatibility, DateTime does not serialize the Kind data when used in
+ // binary serialization.
+ //
+ // For a description of various calendar issues, look at
+ //
+ // Calendar Studies web site, at
+ // http://serendipity.nofadz.com/hermetic/cal_stud.htm.
+ //
+ //
+ [StructLayout(LayoutKind.Auto)]
+ [Serializable]
+ public partial struct DateTime : IComparable, IFormattable, IConvertible, IComparable<DateTime>, IEquatable<DateTime>, ISerializable
+ {
+ // Number of 100ns ticks per time unit
+ private const long TicksPerMillisecond = 10000;
+ private const long TicksPerSecond = TicksPerMillisecond * 1000;
+ private const long TicksPerMinute = TicksPerSecond * 60;
+ private const long TicksPerHour = TicksPerMinute * 60;
+ private const long TicksPerDay = TicksPerHour * 24;
+
+ // Number of milliseconds per time unit
+ private const int MillisPerSecond = 1000;
+ private const int MillisPerMinute = MillisPerSecond * 60;
+ private const int MillisPerHour = MillisPerMinute * 60;
+ private const int MillisPerDay = MillisPerHour * 24;
+
+ // Number of days in a non-leap year
+ private const int DaysPerYear = 365;
+ // Number of days in 4 years
+ private const int DaysPer4Years = DaysPerYear * 4 + 1; // 1461
+ // Number of days in 100 years
+ private const int DaysPer100Years = DaysPer4Years * 25 - 1; // 36524
+ // Number of days in 400 years
+ private const int DaysPer400Years = DaysPer100Years * 4 + 1; // 146097
+
+ // Number of days from 1/1/0001 to 12/31/1600
+ private const int DaysTo1601 = DaysPer400Years * 4; // 584388
+ // Number of days from 1/1/0001 to 12/30/1899
+ private const int DaysTo1899 = DaysPer400Years * 4 + DaysPer100Years * 3 - 367;
+ // Number of days from 1/1/0001 to 12/31/1969
+ internal const int DaysTo1970 = DaysPer400Years * 4 + DaysPer100Years * 3 + DaysPer4Years * 17 + DaysPerYear; // 719,162
+ // Number of days from 1/1/0001 to 12/31/9999
+ private const int DaysTo10000 = DaysPer400Years * 25 - 366; // 3652059
+
+ internal const long MinTicks = 0;
+ internal const long MaxTicks = DaysTo10000 * TicksPerDay - 1;
+ private const long MaxMillis = (long)DaysTo10000 * MillisPerDay;
+
+ private const long TicksTo1970 = DaysTo1970 * TicksPerDay;
+ private const long FileTimeOffset = DaysTo1601 * TicksPerDay;
+ private const long DoubleDateOffset = DaysTo1899 * TicksPerDay;
+ // The minimum OA date is 0100/01/01 (Note it's year 100).
+ // The maximum OA date is 9999/12/31
+ private const long OADateMinAsTicks = (DaysPer100Years - DaysPerYear) * TicksPerDay;
+ // All OA dates must be greater than (not >=) OADateMinAsDouble
+ private const double OADateMinAsDouble = -657435.0;
+ // All OA dates must be less than (not <=) OADateMaxAsDouble
+ private const double OADateMaxAsDouble = 2958466.0;
+
+ private const int DatePartYear = 0;
+ private const int DatePartDayOfYear = 1;
+ private const int DatePartMonth = 2;
+ private const int DatePartDay = 3;
+
+ private static readonly int[] s_daysToMonth365 = {
+ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
+ private static readonly int[] s_daysToMonth366 = {
+ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366};
+
+ public static readonly DateTime MinValue = new DateTime(MinTicks, DateTimeKind.Unspecified);
+ public static readonly DateTime MaxValue = new DateTime(MaxTicks, DateTimeKind.Unspecified);
+
+ private const UInt64 TicksMask = 0x3FFFFFFFFFFFFFFF;
+ private const UInt64 FlagsMask = 0xC000000000000000;
+ private const UInt64 LocalMask = 0x8000000000000000;
+ private const Int64 TicksCeiling = 0x4000000000000000;
+ private const UInt64 KindUnspecified = 0x0000000000000000;
+ private const UInt64 KindUtc = 0x4000000000000000;
+ private const UInt64 KindLocal = 0x8000000000000000;
+ private const UInt64 KindLocalAmbiguousDst = 0xC000000000000000;
+ private const Int32 KindShift = 62;
+
+ private const String TicksField = "ticks";
+ private const String DateDataField = "_dateData";
+
+ // The data is stored as an unsigned 64-bit integeter
+ // Bits 01-62: The value of 100-nanosecond ticks where 0 represents 1/1/0001 12:00am, up until the value
+ // 12/31/9999 23:59:59.9999999
+ // Bits 63-64: A four-state value that describes the DateTimeKind value of the date time, with a 2nd
+ // value for the rare case where the date time is local, but is in an overlapped daylight
+ // savings time hour and it is in daylight savings time. This allows distinction of these
+ // otherwise ambiguous local times and prevents data loss when round tripping from Local to
+ // UTC time.
+ private UInt64 _dateData;
+
+ // Constructs a DateTime from a tick count. The ticks
+ // argument specifies the date as the number of 100-nanosecond intervals
+ // that have elapsed since 1/1/0001 12:00am.
+ //
+ public DateTime(long ticks)
+ {
+ if (ticks < MinTicks || ticks > MaxTicks)
+ throw new ArgumentOutOfRangeException(nameof(ticks), SR.ArgumentOutOfRange_DateTimeBadTicks);
+ Contract.EndContractBlock();
+ _dateData = (UInt64)ticks;
+ }
+
+ private DateTime(UInt64 dateData)
+ {
+ this._dateData = dateData;
+ }
+
+ public DateTime(long ticks, DateTimeKind kind)
+ {
+ if (ticks < MinTicks || ticks > MaxTicks)
+ {
+ throw new ArgumentOutOfRangeException(nameof(ticks), SR.ArgumentOutOfRange_DateTimeBadTicks);
+ }
+ if (kind < DateTimeKind.Unspecified || kind > DateTimeKind.Local)
+ {
+ throw new ArgumentException(SR.Argument_InvalidDateTimeKind, nameof(kind));
+ }
+ Contract.EndContractBlock();
+ _dateData = ((UInt64)ticks | ((UInt64)kind << KindShift));
+ }
+
+ internal DateTime(long ticks, DateTimeKind kind, Boolean isAmbiguousDst)
+ {
+ if (ticks < MinTicks || ticks > MaxTicks)
+ {
+ throw new ArgumentOutOfRangeException(nameof(ticks), SR.ArgumentOutOfRange_DateTimeBadTicks);
+ }
+ Debug.Assert(kind == DateTimeKind.Local, "Internal Constructor is for local times only");
+ Contract.EndContractBlock();
+ _dateData = ((UInt64)ticks | (isAmbiguousDst ? KindLocalAmbiguousDst : KindLocal));
+ }
+
+ // Constructs a DateTime from a given year, month, and day. The
+ // time-of-day of the resulting DateTime is always midnight.
+ //
+ public DateTime(int year, int month, int day)
+ {
+ _dateData = (UInt64)DateToTicks(year, month, day);
+ }
+
+ // Constructs a DateTime from a given year, month, and day for
+ // the specified calendar. The
+ // time-of-day of the resulting DateTime is always midnight.
+ //
+ public DateTime(int year, int month, int day, Calendar calendar)
+ : this(year, month, day, 0, 0, 0, calendar)
+ {
+ }
+
+ // Constructs a DateTime from a given year, month, day, hour,
+ // minute, and second.
+ //
+ public DateTime(int year, int month, int day, int hour, int minute, int second)
+ {
+ _dateData = (UInt64)(DateToTicks(year, month, day) + TimeToTicks(hour, minute, second));
+ }
+
+ public DateTime(int year, int month, int day, int hour, int minute, int second, DateTimeKind kind)
+ {
+ if (kind < DateTimeKind.Unspecified || kind > DateTimeKind.Local)
+ {
+ throw new ArgumentException(SR.Argument_InvalidDateTimeKind, nameof(kind));
+ }
+ Contract.EndContractBlock();
+ Int64 ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
+ _dateData = ((UInt64)ticks | ((UInt64)kind << KindShift));
+ }
+
+ // Constructs a DateTime from a given year, month, day, hour,
+ // minute, and second for the specified calendar.
+ //
+ public DateTime(int year, int month, int day, int hour, int minute, int second, Calendar calendar)
+ {
+ if (calendar == null)
+ throw new ArgumentNullException(nameof(calendar));
+ Contract.EndContractBlock();
+ _dateData = (UInt64)calendar.ToDateTime(year, month, day, hour, minute, second, 0).Ticks;
+ }
+
+ // Constructs a DateTime from a given year, month, day, hour,
+ // minute, and second.
+ //
+ public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond)
+ {
+ if (millisecond < 0 || millisecond >= MillisPerSecond)
+ {
+ throw new ArgumentOutOfRangeException(nameof(millisecond), SR.Format(SR.ArgumentOutOfRange_Range, 0, MillisPerSecond - 1));
+ }
+ Contract.EndContractBlock();
+ Int64 ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
+ ticks += millisecond * TicksPerMillisecond;
+ if (ticks < MinTicks || ticks > MaxTicks)
+ throw new ArgumentException(SR.Arg_DateTimeRange);
+ _dateData = (UInt64)ticks;
+ }
+
+ public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, DateTimeKind kind)
+ {
+ if (millisecond < 0 || millisecond >= MillisPerSecond)
+ {
+ throw new ArgumentOutOfRangeException(nameof(millisecond), SR.Format(SR.ArgumentOutOfRange_Range, 0, MillisPerSecond - 1));
+ }
+ if (kind < DateTimeKind.Unspecified || kind > DateTimeKind.Local)
+ {
+ throw new ArgumentException(SR.Argument_InvalidDateTimeKind, nameof(kind));
+ }
+ Contract.EndContractBlock();
+ Int64 ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
+ ticks += millisecond * TicksPerMillisecond;
+ if (ticks < MinTicks || ticks > MaxTicks)
+ throw new ArgumentException(SR.Arg_DateTimeRange);
+ _dateData = ((UInt64)ticks | ((UInt64)kind << KindShift));
+ }
+
+ // Constructs a DateTime from a given year, month, day, hour,
+ // minute, and second for the specified calendar.
+ //
+ public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar)
+ {
+ if (calendar == null)
+ throw new ArgumentNullException(nameof(calendar));
+ if (millisecond < 0 || millisecond >= MillisPerSecond)
+ {
+ throw new ArgumentOutOfRangeException(nameof(millisecond), SR.Format(SR.ArgumentOutOfRange_Range, 0, MillisPerSecond - 1));
+ }
+ Contract.EndContractBlock();
+ Int64 ticks = calendar.ToDateTime(year, month, day, hour, minute, second, 0).Ticks;
+ ticks += millisecond * TicksPerMillisecond;
+ if (ticks < MinTicks || ticks > MaxTicks)
+ throw new ArgumentException(SR.Arg_DateTimeRange);
+ _dateData = (UInt64)ticks;
+ }
+
+ public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar, DateTimeKind kind)
+ {
+ if (calendar == null)
+ throw new ArgumentNullException(nameof(calendar));
+ if (millisecond < 0 || millisecond >= MillisPerSecond)
+ {
+ throw new ArgumentOutOfRangeException(nameof(millisecond), SR.Format(SR.ArgumentOutOfRange_Range, 0, MillisPerSecond - 1));
+ }
+ if (kind < DateTimeKind.Unspecified || kind > DateTimeKind.Local)
+ {
+ throw new ArgumentException(SR.Argument_InvalidDateTimeKind, nameof(kind));
+ }
+ Contract.EndContractBlock();
+ Int64 ticks = calendar.ToDateTime(year, month, day, hour, minute, second, 0).Ticks;
+ ticks += millisecond * TicksPerMillisecond;
+ if (ticks < MinTicks || ticks > MaxTicks)
+ throw new ArgumentException(SR.Arg_DateTimeRange);
+ _dateData = ((UInt64)ticks | ((UInt64)kind << KindShift));
+ }
+
+ private DateTime(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ Boolean foundTicks = false;
+ Boolean foundDateData = false;
+ Int64 serializedTicks = 0;
+ UInt64 serializedDateData = 0;
+
+
+ // Get the data
+ SerializationInfoEnumerator enumerator = info.GetEnumerator();
+ while (enumerator.MoveNext())
+ {
+ switch (enumerator.Name)
+ {
+ case TicksField:
+ serializedTicks = Convert.ToInt64(enumerator.Value, CultureInfo.InvariantCulture);
+ foundTicks = true;
+ break;
+ case DateDataField:
+ serializedDateData = Convert.ToUInt64(enumerator.Value, CultureInfo.InvariantCulture);
+ foundDateData = true;
+ break;
+ default:
+ // Ignore other fields for forward compatibility.
+ break;
+ }
+ }
+ if (foundDateData)
+ {
+ _dateData = serializedDateData;
+ }
+ else if (foundTicks)
+ {
+ _dateData = (UInt64)serializedTicks;
+ }
+ else
+ {
+ throw new SerializationException(SR.Serialization_MissingDateTimeData);
+ }
+ Int64 ticks = InternalTicks;
+ if (ticks < MinTicks || ticks > MaxTicks)
+ {
+ throw new SerializationException(SR.Serialization_DateTimeTicksOutOfRange);
+ }
+ }
+
+
+
+ internal Int64 InternalTicks
+ {
+ get
+ {
+ return (Int64)(_dateData & TicksMask);
+ }
+ }
+
+ private UInt64 InternalKind
+ {
+ get
+ {
+ return (_dateData & FlagsMask);
+ }
+ }
+
+ // Returns the DateTime resulting from adding the given
+ // TimeSpan to this DateTime.
+ //
+ public DateTime Add(TimeSpan value)
+ {
+ return AddTicks(value._ticks);
+ }
+
+ // Returns the DateTime resulting from adding a fractional number of
+ // time units to this DateTime.
+ private DateTime Add(double value, int scale)
+ {
+ long millis = (long)(value * scale + (value >= 0 ? 0.5 : -0.5));
+ if (millis <= -MaxMillis || millis >= MaxMillis)
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_AddValue);
+ return AddTicks(millis * TicksPerMillisecond);
+ }
+
+ // Returns the DateTime resulting from adding a fractional number of
+ // days to this DateTime. The result is computed by rounding the
+ // fractional number of days given by value to the nearest
+ // millisecond, and adding that interval to this DateTime. The
+ // value argument is permitted to be negative.
+ //
+ public DateTime AddDays(double value)
+ {
+ return Add(value, MillisPerDay);
+ }
+
+ // Returns the DateTime resulting from adding a fractional number of
+ // hours to this DateTime. The result is computed by rounding the
+ // fractional number of hours given by value to the nearest
+ // millisecond, and adding that interval to this DateTime. The
+ // value argument is permitted to be negative.
+ //
+ public DateTime AddHours(double value)
+ {
+ return Add(value, MillisPerHour);
+ }
+
+ // Returns the DateTime resulting from the given number of
+ // milliseconds to this DateTime. The result is computed by rounding
+ // the number of milliseconds given by value to the nearest integer,
+ // and adding that interval to this DateTime. The value
+ // argument is permitted to be negative.
+ //
+ public DateTime AddMilliseconds(double value)
+ {
+ return Add(value, 1);
+ }
+
+ // Returns the DateTime resulting from adding a fractional number of
+ // minutes to this DateTime. The result is computed by rounding the
+ // fractional number of minutes given by value to the nearest
+ // millisecond, and adding that interval to this DateTime. The
+ // value argument is permitted to be negative.
+ //
+ public DateTime AddMinutes(double value)
+ {
+ return Add(value, MillisPerMinute);
+ }
+
+ // Returns the DateTime resulting from adding the given number of
+ // months to this DateTime. The result is computed by incrementing
+ // (or decrementing) the year and month parts of this DateTime by
+ // months months, and, if required, adjusting the day part of the
+ // resulting date downwards to the last day of the resulting month in the
+ // resulting year. The time-of-day part of the result is the same as the
+ // time-of-day part of this DateTime.
+ //
+ // In more precise terms, considering this DateTime to be of the
+ // form y / m / d + t, where y is the
+ // year, m is the month, d is the day, and t is the
+ // time-of-day, the result is y1 / m1 / d1 + t,
+ // where y1 and m1 are computed by adding months months
+ // to y and m, and d1 is the largest value less than
+ // or equal to d that denotes a valid day in month m1 of year
+ // y1.
+ //
+ public DateTime AddMonths(int months)
+ {
+ if (months < -120000 || months > 120000) throw new ArgumentOutOfRangeException(nameof(months), SR.ArgumentOutOfRange_DateTimeBadMonths);
+ Contract.EndContractBlock();
+ int y = GetDatePart(DatePartYear);
+ int m = GetDatePart(DatePartMonth);
+ int d = GetDatePart(DatePartDay);
+ int i = m - 1 + months;
+ if (i >= 0)
+ {
+ m = i % 12 + 1;
+ y = y + i / 12;
+ }
+ else
+ {
+ m = 12 + (i + 1) % 12;
+ y = y + (i - 11) / 12;
+ }
+ if (y < 1 || y > 9999)
+ {
+ throw new ArgumentOutOfRangeException(nameof(months), SR.ArgumentOutOfRange_DateArithmetic);
+ }
+ int days = DaysInMonth(y, m);
+ if (d > days) d = days;
+ return new DateTime((UInt64)(DateToTicks(y, m, d) + InternalTicks % TicksPerDay) | InternalKind);
+ }
+
+ // Returns the DateTime resulting from adding a fractional number of
+ // seconds to this DateTime. The result is computed by rounding the
+ // fractional number of seconds given by value to the nearest
+ // millisecond, and adding that interval to this DateTime. The
+ // value argument is permitted to be negative.
+ //
+ public DateTime AddSeconds(double value)
+ {
+ return Add(value, MillisPerSecond);
+ }
+
+ // Returns the DateTime resulting from adding the given number of
+ // 100-nanosecond ticks to this DateTime. The value argument
+ // is permitted to be negative.
+ //
+ public DateTime AddTicks(long value)
+ {
+ long ticks = InternalTicks;
+ if (value > MaxTicks - ticks || value < MinTicks - ticks)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_DateArithmetic);
+ }
+ return new DateTime((UInt64)(ticks + value) | InternalKind);
+ }
+
+ // Returns the DateTime resulting from adding the given number of
+ // years to this DateTime. The result is computed by incrementing
+ // (or decrementing) the year part of this DateTime by value
+ // years. If the month and day of this DateTime is 2/29, and if the
+ // resulting year is not a leap year, the month and day of the resulting
+ // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
+ // parts of the result are the same as those of this DateTime.
+ //
+ public DateTime AddYears(int value)
+ {
+ if (value < -10000 || value > 10000)
+ {
+ // DateTimeOffset.AddYears(int years) is implemented on top of DateTime.AddYears(int value). Use the more appropriate
+ // parameter name out of the two for the exception.
+ throw new ArgumentOutOfRangeException("years", SR.ArgumentOutOfRange_DateTimeBadYears);
+ }
+ Contract.EndContractBlock();
+ return AddMonths(value * 12);
+ }
+
+ // Compares two DateTime values, returning an integer that indicates
+ // their relationship.
+ //
+ public static int Compare(DateTime t1, DateTime t2)
+ {
+ Int64 ticks1 = t1.InternalTicks;
+ Int64 ticks2 = t2.InternalTicks;
+ if (ticks1 > ticks2) return 1;
+ if (ticks1 < ticks2) return -1;
+ return 0;
+ }
+
+ // Compares this DateTime to a given object. This method provides an
+ // implementation of the IComparable interface. The object
+ // argument must be another DateTime, or otherwise an exception
+ // occurs. Null is considered less than any instance.
+ //
+ // Returns a value less than zero if this object
+ public int CompareTo(Object value)
+ {
+ if (value == null) return 1;
+ if (!(value is DateTime))
+ {
+ throw new ArgumentException(SR.Arg_MustBeDateTime);
+ }
+
+ return Compare(this, (DateTime)value);
+ }
+
+ public int CompareTo(DateTime value)
+ {
+ return Compare(this, value);
+ }
+
+ // Returns the tick count corresponding to the given year, month, and day.
+ // Will check the if the parameters are valid.
+ private static long DateToTicks(int year, int month, int day)
+ {
+ if (year >= 1 && year <= 9999 && month >= 1 && month <= 12)
+ {
+ int[] days = IsLeapYear(year) ? s_daysToMonth366 : s_daysToMonth365;
+ if (day >= 1 && day <= days[month] - days[month - 1])
+ {
+ int y = year - 1;
+ int n = y * 365 + y / 4 - y / 100 + y / 400 + days[month - 1] + day - 1;
+ return n * TicksPerDay;
+ }
+ }
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
+ }
+
+ // Return the tick count corresponding to the given hour, minute, second.
+ // Will check the if the parameters are valid.
+ private static long TimeToTicks(int hour, int minute, int second)
+ {
+ //TimeSpan.TimeToTicks is a family access function which does no error checking, so
+ //we need to put some error checking out here.
+ if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >= 0 && second < 60)
+ {
+ return (TimeSpan.TimeToTicks(hour, minute, second));
+ }
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
+ }
+
+ // Returns the number of days in the month given by the year and
+ // month arguments.
+ //
+ public static int DaysInMonth(int year, int month)
+ {
+ if (month < 1 || month > 12) throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
+ Contract.EndContractBlock();
+ // IsLeapYear checks the year argument
+ int[] days = IsLeapYear(year) ? s_daysToMonth366 : s_daysToMonth365;
+ return days[month] - days[month - 1];
+ }
+
+ // Converts an OLE Date to a tick count.
+ // This function is duplicated in COMDateTime.cpp
+ internal static long DoubleDateToTicks(double value)
+ {
+ // The check done this way will take care of NaN
+ if (!(value < OADateMaxAsDouble) || !(value > OADateMinAsDouble))
+ throw new ArgumentException(SR.Arg_OleAutDateInvalid);
+
+ // Conversion to long will not cause an overflow here, as at this point the "value" is in between OADateMinAsDouble and OADateMaxAsDouble
+ long millis = (long)(value * MillisPerDay + (value >= 0 ? 0.5 : -0.5));
+ // The interesting thing here is when you have a value like 12.5 it all positive 12 days and 12 hours from 01/01/1899
+ // However if you a value of -12.25 it is minus 12 days but still positive 6 hours, almost as though you meant -11.75 all negative
+ // This line below fixes up the millis in the negative case
+ if (millis < 0)
+ {
+ millis -= (millis % MillisPerDay) * 2;
+ }
+
+ millis += DoubleDateOffset / TicksPerMillisecond;
+
+ if (millis < 0 || millis >= MaxMillis) throw new ArgumentException(SR.Arg_OleAutDateScale);
+ return millis * TicksPerMillisecond;
+ }
+
+ // Checks if this DateTime is equal to a given object. Returns
+ // true if the given object is a boxed DateTime and its value
+ // is equal to the value of this DateTime. Returns false
+ // otherwise.
+ //
+ public override bool Equals(Object value)
+ {
+ if (value is DateTime)
+ {
+ return InternalTicks == ((DateTime)value).InternalTicks;
+ }
+ return false;
+ }
+
+ public bool Equals(DateTime value)
+ {
+ return InternalTicks == value.InternalTicks;
+ }
+
+ // Compares two DateTime values for equality. Returns true if
+ // the two DateTime values are equal, or false if they are
+ // not equal.
+ //
+ public static bool Equals(DateTime t1, DateTime t2)
+ {
+ return t1.InternalTicks == t2.InternalTicks;
+ }
+
+ public static DateTime FromBinary(Int64 dateData)
+ {
+ if ((dateData & (unchecked((Int64)LocalMask))) != 0)
+ {
+ // Local times need to be adjusted as you move from one time zone to another,
+ // just as they are when serializing in text. As such the format for local times
+ // changes to store the ticks of the UTC time, but with flags that look like a
+ // local date.
+ Int64 ticks = dateData & (unchecked((Int64)TicksMask));
+ // Negative ticks are stored in the top part of the range and should be converted back into a negative number
+ if (ticks > TicksCeiling - TicksPerDay)
+ {
+ ticks = ticks - TicksCeiling;
+ }
+ // Convert the ticks back to local. If the UTC ticks are out of range, we need to default to
+ // the UTC offset from MinValue and MaxValue to be consistent with Parse.
+ Boolean isAmbiguousLocalDst = false;
+ Int64 offsetTicks;
+ if (ticks < MinTicks)
+ {
+ offsetTicks = TimeZoneInfo.GetLocalUtcOffset(DateTime.MinValue, TimeZoneInfoOptions.NoThrowOnInvalidTime).Ticks;
+ }
+ else if (ticks > MaxTicks)
+ {
+ offsetTicks = TimeZoneInfo.GetLocalUtcOffset(DateTime.MaxValue, TimeZoneInfoOptions.NoThrowOnInvalidTime).Ticks;
+ }
+ else
+ {
+ // Because the ticks conversion between UTC and local is lossy, we need to capture whether the
+ // time is in a repeated hour so that it can be passed to the DateTime constructor.
+ DateTime utcDt = new DateTime(ticks, DateTimeKind.Utc);
+ Boolean isDaylightSavings = false;
+ offsetTicks = TimeZoneInfo.GetUtcOffsetFromUtc(utcDt, TimeZoneInfo.Local, out isDaylightSavings, out isAmbiguousLocalDst).Ticks;
+ }
+ ticks += offsetTicks;
+ // Another behaviour of parsing is to cause small times to wrap around, so that they can be used
+ // to compare times of day
+ if (ticks < 0)
+ {
+ ticks += TicksPerDay;
+ }
+ if (ticks < MinTicks || ticks > MaxTicks)
+ {
+ throw new ArgumentException(SR.Argument_DateTimeBadBinaryData, nameof(dateData));
+ }
+ return new DateTime(ticks, DateTimeKind.Local, isAmbiguousLocalDst);
+ }
+ else
+ {
+ return DateTime.FromBinaryRaw(dateData);
+ }
+ }
+
+ // A version of ToBinary that uses the real representation and does not adjust local times. This is needed for
+ // scenarios where the serialized data must maintain compatibility
+ internal static DateTime FromBinaryRaw(Int64 dateData)
+ {
+ Int64 ticks = dateData & (Int64)TicksMask;
+ if (ticks < MinTicks || ticks > MaxTicks)
+ throw new ArgumentException(SR.Argument_DateTimeBadBinaryData, nameof(dateData));
+ return new DateTime((UInt64)dateData);
+ }
+
+ // Creates a DateTime from a Windows filetime. A Windows filetime is
+ // a long representing the date and time as the number of
+ // 100-nanosecond intervals that have elapsed since 1/1/1601 12:00am.
+ //
+ public static DateTime FromFileTime(long fileTime)
+ {
+ return FromFileTimeUtc(fileTime).ToLocalTime();
+ }
+
+ public static DateTime FromFileTimeUtc(long fileTime)
+ {
+ if (fileTime < 0 || fileTime > MaxTicks - FileTimeOffset)
+ {
+ throw new ArgumentOutOfRangeException(nameof(fileTime), SR.ArgumentOutOfRange_FileTimeInvalid);
+ }
+ Contract.EndContractBlock();
+
+ // This is the ticks in Universal time for this fileTime.
+ long universalTicks = fileTime + FileTimeOffset;
+ return new DateTime(universalTicks, DateTimeKind.Utc);
+ }
+
+ // Creates a DateTime from an OLE Automation Date.
+ //
+ public static DateTime FromOADate(double d)
+ {
+ return new DateTime(DoubleDateToTicks(d), DateTimeKind.Unspecified);
+ }
+
+ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
+ throw new ArgumentNullException(nameof(info));
+ }
+ Contract.EndContractBlock();
+
+ // Serialize both the old and the new format
+ info.AddValue(TicksField, InternalTicks);
+ info.AddValue(DateDataField, _dateData);
+ }
+
+ public Boolean IsDaylightSavingTime()
+ {
+ if (Kind == DateTimeKind.Utc)
+ {
+ return false;
+ }
+ return TimeZoneInfo.Local.IsDaylightSavingTime(this, TimeZoneInfoOptions.NoThrowOnInvalidTime);
+ }
+
+ public static DateTime SpecifyKind(DateTime value, DateTimeKind kind)
+ {
+ return new DateTime(value.InternalTicks, kind);
+ }
+
+ public Int64 ToBinary()
+ {
+ if (Kind == DateTimeKind.Local)
+ {
+ // Local times need to be adjusted as you move from one time zone to another,
+ // just as they are when serializing in text. As such the format for local times
+ // changes to store the ticks of the UTC time, but with flags that look like a
+ // local date.
+
+ // To match serialization in text we need to be able to handle cases where
+ // the UTC value would be out of range. Unused parts of the ticks range are
+ // used for this, so that values just past max value are stored just past the
+ // end of the maximum range, and values just below minimum value are stored
+ // at the end of the ticks area, just below 2^62.
+ TimeSpan offset = TimeZoneInfo.GetLocalUtcOffset(this, TimeZoneInfoOptions.NoThrowOnInvalidTime);
+ Int64 ticks = Ticks;
+ Int64 storedTicks = ticks - offset.Ticks;
+ if (storedTicks < 0)
+ {
+ storedTicks = TicksCeiling + storedTicks;
+ }
+ return storedTicks | (unchecked((Int64)LocalMask));
+ }
+ else
+ {
+ return (Int64)_dateData;
+ }
+ }
+
+ // Returns the date part of this DateTime. The resulting value
+ // corresponds to this DateTime with the time-of-day part set to
+ // zero (midnight).
+ //
+ public DateTime Date
+ {
+ get
+ {
+ Int64 ticks = InternalTicks;
+ return new DateTime((UInt64)(ticks - ticks % TicksPerDay) | InternalKind);
+ }
+ }
+
+ // Returns a given date part of this DateTime. This method is used
+ // to compute the year, day-of-year, month, or day part.
+ private int GetDatePart(int part)
+ {
+ Int64 ticks = InternalTicks;
+ // n = number of days since 1/1/0001
+ int n = (int)(ticks / TicksPerDay);
+ // y400 = number of whole 400-year periods since 1/1/0001
+ int y400 = n / DaysPer400Years;
+ // n = day number within 400-year period
+ n -= y400 * DaysPer400Years;
+ // y100 = number of whole 100-year periods within 400-year period
+ int y100 = n / DaysPer100Years;
+ // Last 100-year period has an extra day, so decrement result if 4
+ if (y100 == 4) y100 = 3;
+ // n = day number within 100-year period
+ n -= y100 * DaysPer100Years;
+ // y4 = number of whole 4-year periods within 100-year period
+ int y4 = n / DaysPer4Years;
+ // n = day number within 4-year period
+ n -= y4 * DaysPer4Years;
+ // y1 = number of whole years within 4-year period
+ int y1 = n / DaysPerYear;
+ // Last year has an extra day, so decrement result if 4
+ if (y1 == 4) y1 = 3;
+ // If year was requested, compute and return it
+ if (part == DatePartYear)
+ {
+ return y400 * 400 + y100 * 100 + y4 * 4 + y1 + 1;
+ }
+ // n = day number within year
+ n -= y1 * DaysPerYear;
+ // If day-of-year was requested, return it
+ if (part == DatePartDayOfYear) return n + 1;
+ // Leap year calculation looks different from IsLeapYear since y1, y4,
+ // and y100 are relative to year 1, not year 0
+ bool leapYear = y1 == 3 && (y4 != 24 || y100 == 3);
+ int[] days = leapYear ? s_daysToMonth366 : s_daysToMonth365;
+ // All months have less than 32 days, so n >> 5 is a good conservative
+ // estimate for the month
+ int m = (n >> 5) + 1;
+ // m = 1-based month number
+ while (n >= days[m]) m++;
+ // If month was requested, return it
+ if (part == DatePartMonth) return m;
+ // Return 1-based day-of-month
+ return n - days[m - 1] + 1;
+ }
+
+ // Returns the day-of-month part of this DateTime. The returned
+ // value is an integer between 1 and 31.
+ //
+ public int Day
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<int>() >= 1);
+ Contract.Ensures(Contract.Result<int>() <= 31);
+ return GetDatePart(DatePartDay);
+ }
+ }
+
+ // Returns the day-of-week part of this DateTime. The returned value
+ // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
+ // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
+ // Thursday, 5 indicates Friday, and 6 indicates Saturday.
+ //
+ public DayOfWeek DayOfWeek
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<DayOfWeek>() >= DayOfWeek.Sunday);
+ Contract.Ensures(Contract.Result<DayOfWeek>() <= DayOfWeek.Saturday);
+ return (DayOfWeek)((InternalTicks / TicksPerDay + 1) % 7);
+ }
+ }
+
+ // Returns the day-of-year part of this DateTime. The returned value
+ // is an integer between 1 and 366.
+ //
+ public int DayOfYear
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<int>() >= 1);
+ Contract.Ensures(Contract.Result<int>() <= 366); // leap year
+ return GetDatePart(DatePartDayOfYear);
+ }
+ }
+
+ // Returns the hash code for this DateTime.
+ //
+ public override int GetHashCode()
+ {
+ Int64 ticks = InternalTicks;
+ return unchecked((int)ticks) ^ (int)(ticks >> 32);
+ }
+
+ // Returns the hour part of this DateTime. The returned value is an
+ // integer between 0 and 23.
+ //
+ public int Hour
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<int>() >= 0);
+ Contract.Ensures(Contract.Result<int>() < 24);
+ return (int)((InternalTicks / TicksPerHour) % 24);
+ }
+ }
+
+ internal Boolean IsAmbiguousDaylightSavingTime()
+ {
+ return (InternalKind == KindLocalAmbiguousDst);
+ }
+
+ [Pure]
+ public DateTimeKind Kind
+ {
+ get
+ {
+ switch (InternalKind)
+ {
+ case KindUnspecified:
+ return DateTimeKind.Unspecified;
+ case KindUtc:
+ return DateTimeKind.Utc;
+ default:
+ return DateTimeKind.Local;
+ }
+ }
+ }
+
+ // Returns the millisecond part of this DateTime. The returned value
+ // is an integer between 0 and 999.
+ //
+ public int Millisecond
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<int>() >= 0);
+ Contract.Ensures(Contract.Result<int>() < 1000);
+ return (int)((InternalTicks / TicksPerMillisecond) % 1000);
+ }
+ }
+
+ // Returns the minute part of this DateTime. The returned value is
+ // an integer between 0 and 59.
+ //
+ public int Minute
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<int>() >= 0);
+ Contract.Ensures(Contract.Result<int>() < 60);
+ return (int)((InternalTicks / TicksPerMinute) % 60);
+ }
+ }
+
+ // Returns the month part of this DateTime. The returned value is an
+ // integer between 1 and 12.
+ //
+ public int Month
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<int>() >= 1);
+ return GetDatePart(DatePartMonth);
+ }
+ }
+
+ // Returns a DateTime representing the current date and time. The
+ // resolution of the returned value depends on the system timer. For
+ // Windows NT 3.5 and later the timer resolution is approximately 10ms,
+ // for Windows NT 3.1 it is approximately 16ms, and for Windows 95 and 98
+ // it is approximately 55ms.
+ //
+ public static DateTime Now
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<DateTime>().Kind == DateTimeKind.Local);
+
+ DateTime utc = UtcNow;
+ Boolean isAmbiguousLocalDst = false;
+ Int64 offset = TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(utc, out isAmbiguousLocalDst).Ticks;
+ long tick = utc.Ticks + offset;
+ if (tick > DateTime.MaxTicks)
+ {
+ return new DateTime(DateTime.MaxTicks, DateTimeKind.Local);
+ }
+ if (tick < DateTime.MinTicks)
+ {
+ return new DateTime(DateTime.MinTicks, DateTimeKind.Local);
+ }
+ return new DateTime(tick, DateTimeKind.Local, isAmbiguousLocalDst);
+ }
+ }
+
+ // Returns the second part of this DateTime. The returned value is
+ // an integer between 0 and 59.
+ //
+ public int Second
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<int>() >= 0);
+ Contract.Ensures(Contract.Result<int>() < 60);
+ return (int)((InternalTicks / TicksPerSecond) % 60);
+ }
+ }
+
+ // Returns the tick count for this DateTime. The returned value is
+ // the number of 100-nanosecond intervals that have elapsed since 1/1/0001
+ // 12:00am.
+ //
+ public long Ticks
+ {
+ get
+ {
+ return InternalTicks;
+ }
+ }
+
+ // Returns the time-of-day part of this DateTime. The returned value
+ // is a TimeSpan that indicates the time elapsed since midnight.
+ //
+ public TimeSpan TimeOfDay
+ {
+ get
+ {
+ return new TimeSpan(InternalTicks % TicksPerDay);
+ }
+ }
+
+ // Returns a DateTime representing the current date. The date part
+ // of the returned value is the current date, and the time-of-day part of
+ // the returned value is zero (midnight).
+ //
+ public static DateTime Today
+ {
+ get
+ {
+ return DateTime.Now.Date;
+ }
+ }
+
+ // Returns the year part of this DateTime. The returned value is an
+ // integer between 1 and 9999.
+ //
+ public int Year
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<int>() >= 1 && Contract.Result<int>() <= 9999);
+ return GetDatePart(DatePartYear);
+ }
+ }
+
+ // Checks whether a given year is a leap year. This method returns true if
+ // year is a leap year, or false if not.
+ //
+ public static bool IsLeapYear(int year)
+ {
+ if (year < 1 || year > 9999)
+ {
+ throw new ArgumentOutOfRangeException(nameof(year), SR.ArgumentOutOfRange_Year);
+ }
+ Contract.EndContractBlock();
+ return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
+ }
+
+ // Constructs a DateTime from a string. The string must specify a
+ // date and optionally a time in a culture-specific or universal format.
+ // Leading and trailing whitespace characters are allowed.
+ //
+ public static DateTime Parse(String s)
+ {
+ return (DateTimeParse.Parse(s, DateTimeFormatInfo.CurrentInfo, DateTimeStyles.None));
+ }
+
+ // Constructs a DateTime from a string. The string must specify a
+ // date and optionally a time in a culture-specific or universal format.
+ // Leading and trailing whitespace characters are allowed.
+ //
+ public static DateTime Parse(String s, IFormatProvider provider)
+ {
+ return (DateTimeParse.Parse(s, DateTimeFormatInfo.GetInstance(provider), DateTimeStyles.None));
+ }
+
+ public static DateTime Parse(String s, IFormatProvider provider, DateTimeStyles styles)
+ {
+ DateTimeFormatInfo.ValidateStyles(styles, nameof(styles));
+ return (DateTimeParse.Parse(s, DateTimeFormatInfo.GetInstance(provider), styles));
+ }
+
+ // Constructs a DateTime from a string. The string must specify a
+ // date and optionally a time in a culture-specific or universal format.
+ // Leading and trailing whitespace characters are allowed.
+ //
+ public static DateTime ParseExact(String s, String format, IFormatProvider provider)
+ {
+ return (DateTimeParse.ParseExact(s, format, DateTimeFormatInfo.GetInstance(provider), DateTimeStyles.None));
+ }
+
+ // Constructs a DateTime from a string. The string must specify a
+ // date and optionally a time in a culture-specific or universal format.
+ // Leading and trailing whitespace characters are allowed.
+ //
+ public static DateTime ParseExact(String s, String format, IFormatProvider provider, DateTimeStyles style)
+ {
+ DateTimeFormatInfo.ValidateStyles(style, nameof(style));
+ return (DateTimeParse.ParseExact(s, format, DateTimeFormatInfo.GetInstance(provider), style));
+ }
+
+ public static DateTime ParseExact(String s, String[] formats, IFormatProvider provider, DateTimeStyles style)
+ {
+ DateTimeFormatInfo.ValidateStyles(style, nameof(style));
+ return DateTimeParse.ParseExactMultiple(s, formats, DateTimeFormatInfo.GetInstance(provider), style);
+ }
+
+ public TimeSpan Subtract(DateTime value)
+ {
+ return new TimeSpan(InternalTicks - value.InternalTicks);
+ }
+
+ public DateTime Subtract(TimeSpan value)
+ {
+ long ticks = InternalTicks;
+ long valueTicks = value._ticks;
+ if (ticks - MinTicks < valueTicks || ticks - MaxTicks > valueTicks)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_DateArithmetic);
+ }
+ return new DateTime((UInt64)(ticks - valueTicks) | InternalKind);
+ }
+
+ // This function is duplicated in COMDateTime.cpp
+ private static double TicksToOADate(long value)
+ {
+ if (value == 0)
+ return 0.0; // Returns OleAut's zero'ed date value.
+ if (value < TicksPerDay) // This is a fix for VB. They want the default day to be 1/1/0001 rathar then 12/30/1899.
+ value += DoubleDateOffset; // We could have moved this fix down but we would like to keep the bounds check.
+ if (value < OADateMinAsTicks)
+ throw new OverflowException(SR.Arg_OleAutDateInvalid);
+ // Currently, our max date == OA's max date (12/31/9999), so we don't
+ // need an overflow check in that direction.
+ long millis = (value - DoubleDateOffset) / TicksPerMillisecond;
+ if (millis < 0)
+ {
+ long frac = millis % MillisPerDay;
+ if (frac != 0) millis -= (MillisPerDay + frac) * 2;
+ }
+ return (double)millis / MillisPerDay;
+ }
+
+ // Converts the DateTime instance into an OLE Automation compatible
+ // double date.
+ public double ToOADate()
+ {
+ return TicksToOADate(InternalTicks);
+ }
+
+ public long ToFileTime()
+ {
+ // Treats the input as local if it is not specified
+ return ToUniversalTime().ToFileTimeUtc();
+ }
+
+ public long ToFileTimeUtc()
+ {
+ // Treats the input as universal if it is not specified
+ long ticks = ((InternalKind & LocalMask) != 0) ? ToUniversalTime().InternalTicks : this.InternalTicks;
+ ticks -= FileTimeOffset;
+ if (ticks < 0)
+ {
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_FileTimeInvalid);
+ }
+ return ticks;
+ }
+
+ public DateTime ToLocalTime()
+ {
+ return ToLocalTime(false);
+ }
+
+ internal DateTime ToLocalTime(bool throwOnOverflow)
+ {
+ if (Kind == DateTimeKind.Local)
+ {
+ return this;
+ }
+ Boolean isDaylightSavings = false;
+ Boolean isAmbiguousLocalDst = false;
+ Int64 offset = TimeZoneInfo.GetUtcOffsetFromUtc(this, TimeZoneInfo.Local, out isDaylightSavings, out isAmbiguousLocalDst).Ticks;
+ long tick = Ticks + offset;
+ if (tick > DateTime.MaxTicks)
+ {
+ if (throwOnOverflow)
+ throw new ArgumentException(SR.Arg_ArgumentOutOfRangeException);
+ else
+ return new DateTime(DateTime.MaxTicks, DateTimeKind.Local);
+ }
+ if (tick < DateTime.MinTicks)
+ {
+ if (throwOnOverflow)
+ throw new ArgumentException(SR.Arg_ArgumentOutOfRangeException);
+ else
+ return new DateTime(DateTime.MinTicks, DateTimeKind.Local);
+ }
+ return new DateTime(tick, DateTimeKind.Local, isAmbiguousLocalDst);
+ }
+
+ public String ToLongDateString()
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+ return DateTimeFormat.Format(this, "D", DateTimeFormatInfo.CurrentInfo);
+ }
+
+ public String ToLongTimeString()
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+ return DateTimeFormat.Format(this, "T", DateTimeFormatInfo.CurrentInfo);
+ }
+
+ public String ToShortDateString()
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+ return DateTimeFormat.Format(this, "d", DateTimeFormatInfo.CurrentInfo);
+ }
+
+ public String ToShortTimeString()
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+ return DateTimeFormat.Format(this, "t", DateTimeFormatInfo.CurrentInfo);
+ }
+
+ public override String ToString()
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+ return DateTimeFormat.Format(this, null, DateTimeFormatInfo.CurrentInfo);
+ }
+
+ public String ToString(String format)
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+ return DateTimeFormat.Format(this, format, DateTimeFormatInfo.CurrentInfo);
+ }
+
+ public String ToString(IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+ return DateTimeFormat.Format(this, null, DateTimeFormatInfo.GetInstance(provider));
+ }
+
+ public String ToString(String format, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+ return DateTimeFormat.Format(this, format, DateTimeFormatInfo.GetInstance(provider));
+ }
+
+ public DateTime ToUniversalTime()
+ {
+ return TimeZoneInfo.ConvertTimeToUtc(this, TimeZoneInfoOptions.NoThrowOnInvalidTime);
+ }
+
+ public static Boolean TryParse(String s, out DateTime result)
+ {
+ return DateTimeParse.TryParse(s, DateTimeFormatInfo.CurrentInfo, DateTimeStyles.None, out result);
+ }
+
+ public static Boolean TryParse(String s, IFormatProvider provider, DateTimeStyles styles, out DateTime result)
+ {
+ DateTimeFormatInfo.ValidateStyles(styles, nameof(styles));
+ return DateTimeParse.TryParse(s, DateTimeFormatInfo.GetInstance(provider), styles, out result);
+ }
+
+ public static Boolean TryParseExact(String s, String format, IFormatProvider provider, DateTimeStyles style, out DateTime result)
+ {
+ DateTimeFormatInfo.ValidateStyles(style, nameof(style));
+ return DateTimeParse.TryParseExact(s, format, DateTimeFormatInfo.GetInstance(provider), style, out result);
+ }
+
+ public static Boolean TryParseExact(String s, String[] formats, IFormatProvider provider, DateTimeStyles style, out DateTime result)
+ {
+ DateTimeFormatInfo.ValidateStyles(style, nameof(style));
+ return DateTimeParse.TryParseExactMultiple(s, formats, DateTimeFormatInfo.GetInstance(provider), style, out result);
+ }
+
+ public static DateTime operator +(DateTime d, TimeSpan t)
+ {
+ long ticks = d.InternalTicks;
+ long valueTicks = t._ticks;
+ if (valueTicks > MaxTicks - ticks || valueTicks < MinTicks - ticks)
+ {
+ throw new ArgumentOutOfRangeException(nameof(t), SR.ArgumentOutOfRange_DateArithmetic);
+ }
+ return new DateTime((UInt64)(ticks + valueTicks) | d.InternalKind);
+ }
+
+ public static DateTime operator -(DateTime d, TimeSpan t)
+ {
+ long ticks = d.InternalTicks;
+ long valueTicks = t._ticks;
+ if (ticks - MinTicks < valueTicks || ticks - MaxTicks > valueTicks)
+ {
+ throw new ArgumentOutOfRangeException(nameof(t), SR.ArgumentOutOfRange_DateArithmetic);
+ }
+ return new DateTime((UInt64)(ticks - valueTicks) | d.InternalKind);
+ }
+
+ public static TimeSpan operator -(DateTime d1, DateTime d2)
+ {
+ return new TimeSpan(d1.InternalTicks - d2.InternalTicks);
+ }
+
+ public static bool operator ==(DateTime d1, DateTime d2)
+ {
+ return d1.InternalTicks == d2.InternalTicks;
+ }
+
+ public static bool operator !=(DateTime d1, DateTime d2)
+ {
+ return d1.InternalTicks != d2.InternalTicks;
+ }
+
+ public static bool operator <(DateTime t1, DateTime t2)
+ {
+ return t1.InternalTicks < t2.InternalTicks;
+ }
+
+ public static bool operator <=(DateTime t1, DateTime t2)
+ {
+ return t1.InternalTicks <= t2.InternalTicks;
+ }
+
+ public static bool operator >(DateTime t1, DateTime t2)
+ {
+ return t1.InternalTicks > t2.InternalTicks;
+ }
+
+ public static bool operator >=(DateTime t1, DateTime t2)
+ {
+ return t1.InternalTicks >= t2.InternalTicks;
+ }
+
+
+ // Returns a string array containing all of the known date and time options for the
+ // current culture. The strings returned are properly formatted date and
+ // time strings for the current instance of DateTime.
+ public String[] GetDateTimeFormats()
+ {
+ Contract.Ensures(Contract.Result<String[]>() != null);
+ return (GetDateTimeFormats(CultureInfo.CurrentCulture));
+ }
+
+ // Returns a string array containing all of the known date and time options for the
+ // using the information provided by IFormatProvider. The strings returned are properly formatted date and
+ // time strings for the current instance of DateTime.
+ public String[] GetDateTimeFormats(IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<String[]>() != null);
+ return (DateTimeFormat.GetAllDateTimes(this, DateTimeFormatInfo.GetInstance(provider)));
+ }
+
+
+ // Returns a string array containing all of the date and time options for the
+ // given format format and current culture. The strings returned are properly formatted date and
+ // time strings for the current instance of DateTime.
+ public String[] GetDateTimeFormats(char format)
+ {
+ Contract.Ensures(Contract.Result<String[]>() != null);
+ return (GetDateTimeFormats(format, CultureInfo.CurrentCulture));
+ }
+
+ // Returns a string array containing all of the date and time options for the
+ // given format format and given culture. The strings returned are properly formatted date and
+ // time strings for the current instance of DateTime.
+ public String[] GetDateTimeFormats(char format, IFormatProvider provider)
+ {
+ Contract.Ensures(Contract.Result<String[]>() != null);
+ return (DateTimeFormat.GetAllDateTimes(this, format, DateTimeFormatInfo.GetInstance(provider)));
+ }
+
+ //
+ // IConvertible implementation
+ //
+
+ public TypeCode GetTypeCode()
+ {
+ return TypeCode.DateTime;
+ }
+
+
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "DateTime", "Boolean"));
+ }
+
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "DateTime", "Char"));
+ }
+
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "DateTime", "SByte"));
+ }
+
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "DateTime", "Byte"));
+ }
+
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "DateTime", "Int16"));
+ }
+
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "DateTime", "UInt16"));
+ }
+
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "DateTime", "Int32"));
+ }
+
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "DateTime", "UInt32"));
+ }
+
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "DateTime", "Int64"));
+ }
+
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "DateTime", "UInt64"));
+ }
+
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "DateTime", "Single"));
+ }
+
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "DateTime", "Double"));
+ }
+
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "DateTime", "Decimal"));
+ }
+
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
+ return this;
+ }
+
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
+ return Convert.DefaultToType((IConvertible)this, type, provider);
+ }
+
+ // Tries to construct a DateTime from a given year, month, day, hour,
+ // minute, second and millisecond.
+ //
+ internal static Boolean TryCreate(int year, int month, int day, int hour, int minute, int second, int millisecond, out DateTime result)
+ {
+ result = DateTime.MinValue;
+ if (year < 1 || year > 9999 || month < 1 || month > 12)
+ {
+ return false;
+ }
+ int[] days = IsLeapYear(year) ? s_daysToMonth366 : s_daysToMonth365;
+ if (day < 1 || day > days[month] - days[month - 1])
+ {
+ return false;
+ }
+ if (hour < 0 || hour >= 24 || minute < 0 || minute >= 60 || second < 0 || second >= 60)
+ {
+ return false;
+ }
+ if (millisecond < 0 || millisecond >= MillisPerSecond)
+ {
+ return false;
+ }
+ long ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
+
+ ticks += millisecond * TicksPerMillisecond;
+ if (ticks < MinTicks || ticks > MaxTicks)
+ {
+ return false;
+ }
+ result = new DateTime(ticks, DateTimeKind.Unspecified);
+ return true;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/DateTimeKind.cs b/src/mscorlib/shared/System/DateTimeKind.cs
index 6b5e690df0..6b5e690df0 100644
--- a/src/mscorlib/src/System/DateTimeKind.cs
+++ b/src/mscorlib/shared/System/DateTimeKind.cs
diff --git a/src/mscorlib/shared/System/DateTimeOffset.cs b/src/mscorlib/shared/System/DateTimeOffset.cs
new file mode 100644
index 0000000000..d5ccbd9195
--- /dev/null
+++ b/src/mscorlib/shared/System/DateTimeOffset.cs
@@ -0,0 +1,921 @@
+// 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.Diagnostics;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+
+namespace System
+{
+ // DateTimeOffset is a value type that consists of a DateTime and a time zone offset,
+ // ie. how far away the time is from GMT. The DateTime is stored whole, and the offset
+ // is stored as an Int16 internally to save space, but presented as a TimeSpan.
+ //
+ // The range is constrained so that both the represented clock time and the represented
+ // UTC time fit within the boundaries of MaxValue. This gives it the same range as DateTime
+ // for actual UTC times, and a slightly constrained range on one end when an offset is
+ // present.
+ //
+ // This class should be substitutable for date time in most cases; so most operations
+ // effectively work on the clock time. However, the underlying UTC time is what counts
+ // for the purposes of identity, sorting and subtracting two instances.
+ //
+ //
+ // There are theoretically two date times stored, the UTC and the relative local representation
+ // or the 'clock' time. It actually does not matter which is stored in m_dateTime, so it is desirable
+ // for most methods to go through the helpers UtcDateTime and ClockDateTime both to abstract this
+ // out and for internal readability.
+
+ [StructLayout(LayoutKind.Auto)]
+ [Serializable]
+ public struct DateTimeOffset : IComparable, IFormattable, IComparable<DateTimeOffset>, IEquatable<DateTimeOffset>, ISerializable, IDeserializationCallback
+ {
+ // Constants
+ internal const Int64 MaxOffset = TimeSpan.TicksPerHour * 14;
+ internal const Int64 MinOffset = -MaxOffset;
+
+ private const long UnixEpochTicks = TimeSpan.TicksPerDay * DateTime.DaysTo1970; // 621,355,968,000,000,000
+ private const long UnixEpochSeconds = UnixEpochTicks / TimeSpan.TicksPerSecond; // 62,135,596,800
+ private const long UnixEpochMilliseconds = UnixEpochTicks / TimeSpan.TicksPerMillisecond; // 62,135,596,800,000
+
+ internal const long UnixMinSeconds = DateTime.MinTicks / TimeSpan.TicksPerSecond - UnixEpochSeconds;
+ internal const long UnixMaxSeconds = DateTime.MaxTicks / TimeSpan.TicksPerSecond - UnixEpochSeconds;
+
+ // Static Fields
+ public static readonly DateTimeOffset MinValue = new DateTimeOffset(DateTime.MinTicks, TimeSpan.Zero);
+ public static readonly DateTimeOffset MaxValue = new DateTimeOffset(DateTime.MaxTicks, TimeSpan.Zero);
+
+ // Instance Fields
+ private DateTime _dateTime;
+ private Int16 _offsetMinutes;
+
+ // Constructors
+
+ // Constructs a DateTimeOffset from a tick count and offset
+ public DateTimeOffset(long ticks, TimeSpan offset)
+ {
+ _offsetMinutes = ValidateOffset(offset);
+ // Let the DateTime constructor do the range checks
+ DateTime dateTime = new DateTime(ticks);
+ _dateTime = ValidateDate(dateTime, offset);
+ }
+
+ // Constructs a DateTimeOffset from a DateTime. For Local and Unspecified kinds,
+ // extracts the local offset. For UTC, creates a UTC instance with a zero offset.
+ public DateTimeOffset(DateTime dateTime)
+ {
+ TimeSpan offset;
+ if (dateTime.Kind != DateTimeKind.Utc)
+ {
+ // Local and Unspecified are both treated as Local
+ offset = TimeZoneInfo.GetLocalUtcOffset(dateTime, TimeZoneInfoOptions.NoThrowOnInvalidTime);
+ }
+ else
+ {
+ offset = new TimeSpan(0);
+ }
+ _offsetMinutes = ValidateOffset(offset);
+ _dateTime = ValidateDate(dateTime, offset);
+ }
+
+ // Constructs a DateTimeOffset from a DateTime. And an offset. Always makes the clock time
+ // consistent with the DateTime. For Utc ensures the offset is zero. For local, ensures that
+ // the offset corresponds to the local.
+ public DateTimeOffset(DateTime dateTime, TimeSpan offset)
+ {
+ if (dateTime.Kind == DateTimeKind.Local)
+ {
+ if (offset != TimeZoneInfo.GetLocalUtcOffset(dateTime, TimeZoneInfoOptions.NoThrowOnInvalidTime))
+ {
+ throw new ArgumentException(SR.Argument_OffsetLocalMismatch, nameof(offset));
+ }
+ }
+ else if (dateTime.Kind == DateTimeKind.Utc)
+ {
+ if (offset != TimeSpan.Zero)
+ {
+ throw new ArgumentException(SR.Argument_OffsetUtcMismatch, nameof(offset));
+ }
+ }
+ _offsetMinutes = ValidateOffset(offset);
+ _dateTime = ValidateDate(dateTime, offset);
+ }
+
+ // Constructs a DateTimeOffset from a given year, month, day, hour,
+ // minute, second and offset.
+ public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, TimeSpan offset)
+ {
+ _offsetMinutes = ValidateOffset(offset);
+ _dateTime = ValidateDate(new DateTime(year, month, day, hour, minute, second), offset);
+ }
+
+ // Constructs a DateTimeOffset from a given year, month, day, hour,
+ // minute, second, millsecond and offset
+ public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, int millisecond, TimeSpan offset)
+ {
+ _offsetMinutes = ValidateOffset(offset);
+ _dateTime = ValidateDate(new DateTime(year, month, day, hour, minute, second, millisecond), offset);
+ }
+
+ // Constructs a DateTimeOffset from a given year, month, day, hour,
+ // minute, second, millsecond, Calendar and offset.
+ public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar, TimeSpan offset)
+ {
+ _offsetMinutes = ValidateOffset(offset);
+ _dateTime = ValidateDate(new DateTime(year, month, day, hour, minute, second, millisecond, calendar), offset);
+ }
+
+ // Returns a DateTimeOffset representing the current date and time. The
+ // resolution of the returned value depends on the system timer. For
+ // Windows NT 3.5 and later the timer resolution is approximately 10ms,
+ // for Windows NT 3.1 it is approximately 16ms, and for Windows 95 and 98
+ // it is approximately 55ms.
+ //
+ public static DateTimeOffset Now
+ {
+ get
+ {
+ return new DateTimeOffset(DateTime.Now);
+ }
+ }
+
+ public static DateTimeOffset UtcNow
+ {
+ get
+ {
+ return new DateTimeOffset(DateTime.UtcNow);
+ }
+ }
+
+ public DateTime DateTime
+ {
+ get
+ {
+ return ClockDateTime;
+ }
+ }
+
+ public DateTime UtcDateTime
+ {
+ get
+ {
+ return DateTime.SpecifyKind(_dateTime, DateTimeKind.Utc);
+ }
+ }
+
+ public DateTime LocalDateTime
+ {
+ get
+ {
+ return UtcDateTime.ToLocalTime();
+ }
+ }
+
+ // Adjust to a given offset with the same UTC time. Can throw ArgumentException
+ //
+ public DateTimeOffset ToOffset(TimeSpan offset)
+ {
+ return new DateTimeOffset((_dateTime + offset).Ticks, offset);
+ }
+
+
+ // Instance Properties
+
+ // The clock or visible time represented. This is just a wrapper around the internal date because this is
+ // the chosen storage mechanism. Going through this helper is good for readability and maintainability.
+ // This should be used for display but not identity.
+ private DateTime ClockDateTime
+ {
+ get
+ {
+ return new DateTime((_dateTime + Offset).Ticks, DateTimeKind.Unspecified);
+ }
+ }
+
+ // Returns the date part of this DateTimeOffset. The resulting value
+ // corresponds to this DateTimeOffset with the time-of-day part set to
+ // zero (midnight).
+ //
+ public DateTime Date
+ {
+ get
+ {
+ return ClockDateTime.Date;
+ }
+ }
+
+ // Returns the day-of-month part of this DateTimeOffset. The returned
+ // value is an integer between 1 and 31.
+ //
+ public int Day
+ {
+ get
+ {
+ return ClockDateTime.Day;
+ }
+ }
+
+ // Returns the day-of-week part of this DateTimeOffset. The returned value
+ // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
+ // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
+ // Thursday, 5 indicates Friday, and 6 indicates Saturday.
+ //
+ public DayOfWeek DayOfWeek
+ {
+ get
+ {
+ return ClockDateTime.DayOfWeek;
+ }
+ }
+
+ // Returns the day-of-year part of this DateTimeOffset. The returned value
+ // is an integer between 1 and 366.
+ //
+ public int DayOfYear
+ {
+ get
+ {
+ return ClockDateTime.DayOfYear;
+ }
+ }
+
+ // Returns the hour part of this DateTimeOffset. The returned value is an
+ // integer between 0 and 23.
+ //
+ public int Hour
+ {
+ get
+ {
+ return ClockDateTime.Hour;
+ }
+ }
+
+
+ // Returns the millisecond part of this DateTimeOffset. The returned value
+ // is an integer between 0 and 999.
+ //
+ public int Millisecond
+ {
+ get
+ {
+ return ClockDateTime.Millisecond;
+ }
+ }
+
+ // Returns the minute part of this DateTimeOffset. The returned value is
+ // an integer between 0 and 59.
+ //
+ public int Minute
+ {
+ get
+ {
+ return ClockDateTime.Minute;
+ }
+ }
+
+ // Returns the month part of this DateTimeOffset. The returned value is an
+ // integer between 1 and 12.
+ //
+ public int Month
+ {
+ get
+ {
+ return ClockDateTime.Month;
+ }
+ }
+
+ public TimeSpan Offset
+ {
+ get
+ {
+ return new TimeSpan(0, _offsetMinutes, 0);
+ }
+ }
+
+ // Returns the second part of this DateTimeOffset. The returned value is
+ // an integer between 0 and 59.
+ //
+ public int Second
+ {
+ get
+ {
+ return ClockDateTime.Second;
+ }
+ }
+
+ // Returns the tick count for this DateTimeOffset. The returned value is
+ // the number of 100-nanosecond intervals that have elapsed since 1/1/0001
+ // 12:00am.
+ //
+ public long Ticks
+ {
+ get
+ {
+ return ClockDateTime.Ticks;
+ }
+ }
+
+ public long UtcTicks
+ {
+ get
+ {
+ return UtcDateTime.Ticks;
+ }
+ }
+
+ // Returns the time-of-day part of this DateTimeOffset. The returned value
+ // is a TimeSpan that indicates the time elapsed since midnight.
+ //
+ public TimeSpan TimeOfDay
+ {
+ get
+ {
+ return ClockDateTime.TimeOfDay;
+ }
+ }
+
+ // Returns the year part of this DateTimeOffset. The returned value is an
+ // integer between 1 and 9999.
+ //
+ public int Year
+ {
+ get
+ {
+ return ClockDateTime.Year;
+ }
+ }
+
+ // Returns the DateTimeOffset resulting from adding the given
+ // TimeSpan to this DateTimeOffset.
+ //
+ public DateTimeOffset Add(TimeSpan timeSpan)
+ {
+ return new DateTimeOffset(ClockDateTime.Add(timeSpan), Offset);
+ }
+
+ // Returns the DateTimeOffset resulting from adding a fractional number of
+ // days to this DateTimeOffset. The result is computed by rounding the
+ // fractional number of days given by value to the nearest
+ // millisecond, and adding that interval to this DateTimeOffset. The
+ // value argument is permitted to be negative.
+ //
+ public DateTimeOffset AddDays(double days)
+ {
+ return new DateTimeOffset(ClockDateTime.AddDays(days), Offset);
+ }
+
+ // Returns the DateTimeOffset resulting from adding a fractional number of
+ // hours to this DateTimeOffset. The result is computed by rounding the
+ // fractional number of hours given by value to the nearest
+ // millisecond, and adding that interval to this DateTimeOffset. The
+ // value argument is permitted to be negative.
+ //
+ public DateTimeOffset AddHours(double hours)
+ {
+ return new DateTimeOffset(ClockDateTime.AddHours(hours), Offset);
+ }
+
+ // Returns the DateTimeOffset resulting from the given number of
+ // milliseconds to this DateTimeOffset. The result is computed by rounding
+ // the number of milliseconds given by value to the nearest integer,
+ // and adding that interval to this DateTimeOffset. The value
+ // argument is permitted to be negative.
+ //
+ public DateTimeOffset AddMilliseconds(double milliseconds)
+ {
+ return new DateTimeOffset(ClockDateTime.AddMilliseconds(milliseconds), Offset);
+ }
+
+ // Returns the DateTimeOffset resulting from adding a fractional number of
+ // minutes to this DateTimeOffset. The result is computed by rounding the
+ // fractional number of minutes given by value to the nearest
+ // millisecond, and adding that interval to this DateTimeOffset. The
+ // value argument is permitted to be negative.
+ //
+ public DateTimeOffset AddMinutes(double minutes)
+ {
+ return new DateTimeOffset(ClockDateTime.AddMinutes(minutes), Offset);
+ }
+
+ public DateTimeOffset AddMonths(int months)
+ {
+ return new DateTimeOffset(ClockDateTime.AddMonths(months), Offset);
+ }
+
+ // Returns the DateTimeOffset resulting from adding a fractional number of
+ // seconds to this DateTimeOffset. The result is computed by rounding the
+ // fractional number of seconds given by value to the nearest
+ // millisecond, and adding that interval to this DateTimeOffset. The
+ // value argument is permitted to be negative.
+ //
+ public DateTimeOffset AddSeconds(double seconds)
+ {
+ return new DateTimeOffset(ClockDateTime.AddSeconds(seconds), Offset);
+ }
+
+ // Returns the DateTimeOffset resulting from adding the given number of
+ // 100-nanosecond ticks to this DateTimeOffset. The value argument
+ // is permitted to be negative.
+ //
+ public DateTimeOffset AddTicks(long ticks)
+ {
+ return new DateTimeOffset(ClockDateTime.AddTicks(ticks), Offset);
+ }
+
+ // Returns the DateTimeOffset resulting from adding the given number of
+ // years to this DateTimeOffset. The result is computed by incrementing
+ // (or decrementing) the year part of this DateTimeOffset by value
+ // years. If the month and day of this DateTimeOffset is 2/29, and if the
+ // resulting year is not a leap year, the month and day of the resulting
+ // DateTimeOffset becomes 2/28. Otherwise, the month, day, and time-of-day
+ // parts of the result are the same as those of this DateTimeOffset.
+ //
+ public DateTimeOffset AddYears(int years)
+ {
+ return new DateTimeOffset(ClockDateTime.AddYears(years), Offset);
+ }
+
+ // Compares two DateTimeOffset values, returning an integer that indicates
+ // their relationship.
+ //
+ public static int Compare(DateTimeOffset first, DateTimeOffset second)
+ {
+ return DateTime.Compare(first.UtcDateTime, second.UtcDateTime);
+ }
+
+ // Compares this DateTimeOffset to a given object. This method provides an
+ // implementation of the IComparable interface. The object
+ // argument must be another DateTimeOffset, or otherwise an exception
+ // occurs. Null is considered less than any instance.
+ //
+ int IComparable.CompareTo(Object obj)
+ {
+ if (obj == null) return 1;
+ if (!(obj is DateTimeOffset))
+ {
+ throw new ArgumentException(SR.Arg_MustBeDateTimeOffset);
+ }
+
+ DateTime objUtc = ((DateTimeOffset)obj).UtcDateTime;
+ DateTime utc = UtcDateTime;
+ if (utc > objUtc) return 1;
+ if (utc < objUtc) return -1;
+ return 0;
+ }
+
+ public int CompareTo(DateTimeOffset other)
+ {
+ DateTime otherUtc = other.UtcDateTime;
+ DateTime utc = UtcDateTime;
+ if (utc > otherUtc) return 1;
+ if (utc < otherUtc) return -1;
+ return 0;
+ }
+
+
+ // Checks if this DateTimeOffset is equal to a given object. Returns
+ // true if the given object is a boxed DateTimeOffset and its value
+ // is equal to the value of this DateTimeOffset. Returns false
+ // otherwise.
+ //
+ public override bool Equals(Object obj)
+ {
+ if (obj is DateTimeOffset)
+ {
+ return UtcDateTime.Equals(((DateTimeOffset)obj).UtcDateTime);
+ }
+ return false;
+ }
+
+ public bool Equals(DateTimeOffset other)
+ {
+ return UtcDateTime.Equals(other.UtcDateTime);
+ }
+
+ public bool EqualsExact(DateTimeOffset other)
+ {
+ //
+ // returns true when the ClockDateTime, Kind, and Offset match
+ //
+ // currently the Kind should always be Unspecified, but there is always the possibility that a future version
+ // of DateTimeOffset overloads the Kind field
+ //
+ return (ClockDateTime == other.ClockDateTime && Offset == other.Offset && ClockDateTime.Kind == other.ClockDateTime.Kind);
+ }
+
+ // Compares two DateTimeOffset values for equality. Returns true if
+ // the two DateTimeOffset values are equal, or false if they are
+ // not equal.
+ //
+ public static bool Equals(DateTimeOffset first, DateTimeOffset second)
+ {
+ return DateTime.Equals(first.UtcDateTime, second.UtcDateTime);
+ }
+
+ // Creates a DateTimeOffset from a Windows filetime. A Windows filetime is
+ // a long representing the date and time as the number of
+ // 100-nanosecond intervals that have elapsed since 1/1/1601 12:00am.
+ //
+ public static DateTimeOffset FromFileTime(long fileTime)
+ {
+ return new DateTimeOffset(DateTime.FromFileTime(fileTime));
+ }
+
+ public static DateTimeOffset FromUnixTimeSeconds(long seconds)
+ {
+ if (seconds < UnixMinSeconds || seconds > UnixMaxSeconds)
+ {
+ throw new ArgumentOutOfRangeException(nameof(seconds),
+ SR.Format(SR.ArgumentOutOfRange_Range, UnixMinSeconds, UnixMaxSeconds));
+ }
+
+ long ticks = seconds * TimeSpan.TicksPerSecond + UnixEpochTicks;
+ return new DateTimeOffset(ticks, TimeSpan.Zero);
+ }
+
+ public static DateTimeOffset FromUnixTimeMilliseconds(long milliseconds)
+ {
+ const long MinMilliseconds = DateTime.MinTicks / TimeSpan.TicksPerMillisecond - UnixEpochMilliseconds;
+ const long MaxMilliseconds = DateTime.MaxTicks / TimeSpan.TicksPerMillisecond - UnixEpochMilliseconds;
+
+ if (milliseconds < MinMilliseconds || milliseconds > MaxMilliseconds)
+ {
+ throw new ArgumentOutOfRangeException(nameof(milliseconds),
+ SR.Format(SR.ArgumentOutOfRange_Range, MinMilliseconds, MaxMilliseconds));
+ }
+
+ long ticks = milliseconds * TimeSpan.TicksPerMillisecond + UnixEpochTicks;
+ return new DateTimeOffset(ticks, TimeSpan.Zero);
+ }
+
+ // ----- SECTION: private serialization instance methods ----------------*
+
+ void IDeserializationCallback.OnDeserialization(Object sender)
+ {
+ try
+ {
+ _offsetMinutes = ValidateOffset(Offset);
+ _dateTime = ValidateDate(ClockDateTime, Offset);
+ }
+ catch (ArgumentException e)
+ {
+ throw new SerializationException(SR.Serialization_InvalidData, e);
+ }
+ }
+
+
+ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
+ throw new ArgumentNullException(nameof(info));
+ }
+
+ info.AddValue("DateTime", _dateTime);
+ info.AddValue("OffsetMinutes", _offsetMinutes);
+ }
+
+
+ private DateTimeOffset(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
+ throw new ArgumentNullException(nameof(info));
+ }
+
+ _dateTime = (DateTime)info.GetValue("DateTime", typeof(DateTime));
+ _offsetMinutes = (Int16)info.GetValue("OffsetMinutes", typeof(Int16));
+ }
+
+ // Returns the hash code for this DateTimeOffset.
+ //
+ public override int GetHashCode()
+ {
+ return UtcDateTime.GetHashCode();
+ }
+
+ // Constructs a DateTimeOffset from a string. The string must specify a
+ // date and optionally a time in a culture-specific or universal format.
+ // Leading and trailing whitespace characters are allowed.
+ //
+ public static DateTimeOffset Parse(String input)
+ {
+ TimeSpan offset;
+ DateTime dateResult = DateTimeParse.Parse(input,
+ DateTimeFormatInfo.CurrentInfo,
+ DateTimeStyles.None,
+ out offset);
+ return new DateTimeOffset(dateResult.Ticks, offset);
+ }
+
+ // Constructs a DateTimeOffset from a string. The string must specify a
+ // date and optionally a time in a culture-specific or universal format.
+ // Leading and trailing whitespace characters are allowed.
+ //
+ public static DateTimeOffset Parse(String input, IFormatProvider formatProvider)
+ {
+ return Parse(input, formatProvider, DateTimeStyles.None);
+ }
+
+ public static DateTimeOffset Parse(String input, IFormatProvider formatProvider, DateTimeStyles styles)
+ {
+ styles = ValidateStyles(styles, nameof(styles));
+ TimeSpan offset;
+ DateTime dateResult = DateTimeParse.Parse(input,
+ DateTimeFormatInfo.GetInstance(formatProvider),
+ styles,
+ out offset);
+ return new DateTimeOffset(dateResult.Ticks, offset);
+ }
+
+ // Constructs a DateTimeOffset from a string. The string must specify a
+ // date and optionally a time in a culture-specific or universal format.
+ // Leading and trailing whitespace characters are allowed.
+ //
+ public static DateTimeOffset ParseExact(String input, String format, IFormatProvider formatProvider)
+ {
+ return ParseExact(input, format, formatProvider, DateTimeStyles.None);
+ }
+
+ // Constructs a DateTimeOffset from a string. The string must specify a
+ // date and optionally a time in a culture-specific or universal format.
+ // Leading and trailing whitespace characters are allowed.
+ //
+ public static DateTimeOffset ParseExact(String input, String format, IFormatProvider formatProvider, DateTimeStyles styles)
+ {
+ styles = ValidateStyles(styles, nameof(styles));
+ TimeSpan offset;
+ DateTime dateResult = DateTimeParse.ParseExact(input,
+ format,
+ DateTimeFormatInfo.GetInstance(formatProvider),
+ styles,
+ out offset);
+ return new DateTimeOffset(dateResult.Ticks, offset);
+ }
+
+ public static DateTimeOffset ParseExact(String input, String[] formats, IFormatProvider formatProvider, DateTimeStyles styles)
+ {
+ styles = ValidateStyles(styles, nameof(styles));
+ TimeSpan offset;
+ DateTime dateResult = DateTimeParse.ParseExactMultiple(input,
+ formats,
+ DateTimeFormatInfo.GetInstance(formatProvider),
+ styles,
+ out offset);
+ return new DateTimeOffset(dateResult.Ticks, offset);
+ }
+
+ public TimeSpan Subtract(DateTimeOffset value)
+ {
+ return UtcDateTime.Subtract(value.UtcDateTime);
+ }
+
+ public DateTimeOffset Subtract(TimeSpan value)
+ {
+ return new DateTimeOffset(ClockDateTime.Subtract(value), Offset);
+ }
+
+
+ public long ToFileTime()
+ {
+ return UtcDateTime.ToFileTime();
+ }
+
+ public long ToUnixTimeSeconds()
+ {
+ // Truncate sub-second precision before offsetting by the Unix Epoch to avoid
+ // the last digit being off by one for dates that result in negative Unix times.
+ //
+ // For example, consider the DateTimeOffset 12/31/1969 12:59:59.001 +0
+ // ticks = 621355967990010000
+ // ticksFromEpoch = ticks - UnixEpochTicks = -9990000
+ // secondsFromEpoch = ticksFromEpoch / TimeSpan.TicksPerSecond = 0
+ //
+ // Notice that secondsFromEpoch is rounded *up* by the truncation induced by integer division,
+ // whereas we actually always want to round *down* when converting to Unix time. This happens
+ // automatically for positive Unix time values. Now the example becomes:
+ // seconds = ticks / TimeSpan.TicksPerSecond = 62135596799
+ // secondsFromEpoch = seconds - UnixEpochSeconds = -1
+ //
+ // In other words, we want to consistently round toward the time 1/1/0001 00:00:00,
+ // rather than toward the Unix Epoch (1/1/1970 00:00:00).
+ long seconds = UtcDateTime.Ticks / TimeSpan.TicksPerSecond;
+ return seconds - UnixEpochSeconds;
+ }
+
+ public long ToUnixTimeMilliseconds()
+ {
+ // Truncate sub-millisecond precision before offsetting by the Unix Epoch to avoid
+ // the last digit being off by one for dates that result in negative Unix times
+ long milliseconds = UtcDateTime.Ticks / TimeSpan.TicksPerMillisecond;
+ return milliseconds - UnixEpochMilliseconds;
+ }
+
+ public DateTimeOffset ToLocalTime()
+ {
+ return ToLocalTime(false);
+ }
+
+ internal DateTimeOffset ToLocalTime(bool throwOnOverflow)
+ {
+ return new DateTimeOffset(UtcDateTime.ToLocalTime(throwOnOverflow));
+ }
+
+ public override String ToString()
+ {
+ return DateTimeFormat.Format(ClockDateTime, null, DateTimeFormatInfo.CurrentInfo, Offset);
+ }
+
+ public String ToString(String format)
+ {
+ return DateTimeFormat.Format(ClockDateTime, format, DateTimeFormatInfo.CurrentInfo, Offset);
+ }
+
+ public String ToString(IFormatProvider formatProvider)
+ {
+ return DateTimeFormat.Format(ClockDateTime, null, DateTimeFormatInfo.GetInstance(formatProvider), Offset);
+ }
+
+ public String ToString(String format, IFormatProvider formatProvider)
+ {
+ return DateTimeFormat.Format(ClockDateTime, format, DateTimeFormatInfo.GetInstance(formatProvider), Offset);
+ }
+
+ public DateTimeOffset ToUniversalTime()
+ {
+ return new DateTimeOffset(UtcDateTime);
+ }
+
+ public static Boolean TryParse(String input, out DateTimeOffset result)
+ {
+ TimeSpan offset;
+ DateTime dateResult;
+ Boolean parsed = DateTimeParse.TryParse(input,
+ DateTimeFormatInfo.CurrentInfo,
+ DateTimeStyles.None,
+ out dateResult,
+ out offset);
+ result = new DateTimeOffset(dateResult.Ticks, offset);
+ return parsed;
+ }
+
+ public static Boolean TryParse(String input, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result)
+ {
+ styles = ValidateStyles(styles, nameof(styles));
+ TimeSpan offset;
+ DateTime dateResult;
+ Boolean parsed = DateTimeParse.TryParse(input,
+ DateTimeFormatInfo.GetInstance(formatProvider),
+ styles,
+ out dateResult,
+ out offset);
+ result = new DateTimeOffset(dateResult.Ticks, offset);
+ return parsed;
+ }
+
+ public static Boolean TryParseExact(String input, String format, IFormatProvider formatProvider, DateTimeStyles styles,
+ out DateTimeOffset result)
+ {
+ styles = ValidateStyles(styles, nameof(styles));
+ TimeSpan offset;
+ DateTime dateResult;
+ Boolean parsed = DateTimeParse.TryParseExact(input,
+ format,
+ DateTimeFormatInfo.GetInstance(formatProvider),
+ styles,
+ out dateResult,
+ out offset);
+ result = new DateTimeOffset(dateResult.Ticks, offset);
+ return parsed;
+ }
+
+ public static Boolean TryParseExact(String input, String[] formats, IFormatProvider formatProvider, DateTimeStyles styles,
+ out DateTimeOffset result)
+ {
+ styles = ValidateStyles(styles, nameof(styles));
+ TimeSpan offset;
+ DateTime dateResult;
+ Boolean parsed = DateTimeParse.TryParseExactMultiple(input,
+ formats,
+ DateTimeFormatInfo.GetInstance(formatProvider),
+ styles,
+ out dateResult,
+ out offset);
+ result = new DateTimeOffset(dateResult.Ticks, offset);
+ return parsed;
+ }
+
+ // Ensures the TimeSpan is valid to go in a DateTimeOffset.
+ private static Int16 ValidateOffset(TimeSpan offset)
+ {
+ Int64 ticks = offset.Ticks;
+ if (ticks % TimeSpan.TicksPerMinute != 0)
+ {
+ throw new ArgumentException(SR.Argument_OffsetPrecision, nameof(offset));
+ }
+ if (ticks < MinOffset || ticks > MaxOffset)
+ {
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.Argument_OffsetOutOfRange);
+ }
+ return (Int16)(offset.Ticks / TimeSpan.TicksPerMinute);
+ }
+
+ // Ensures that the time and offset are in range.
+ private static DateTime ValidateDate(DateTime dateTime, TimeSpan offset)
+ {
+ // The key validation is that both the UTC and clock times fit. The clock time is validated
+ // by the DateTime constructor.
+ Debug.Assert(offset.Ticks >= MinOffset && offset.Ticks <= MaxOffset, "Offset not validated.");
+
+ // This operation cannot overflow because offset should have already been validated to be within
+ // 14 hours and the DateTime instance is more than that distance from the boundaries of Int64.
+ Int64 utcTicks = dateTime.Ticks - offset.Ticks;
+ if (utcTicks < DateTime.MinTicks || utcTicks > DateTime.MaxTicks)
+ {
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.Argument_UTCOutOfRange);
+ }
+ // make sure the Kind is set to Unspecified
+ //
+ return new DateTime(utcTicks, DateTimeKind.Unspecified);
+ }
+
+ private static DateTimeStyles ValidateStyles(DateTimeStyles style, String parameterName)
+ {
+ if ((style & DateTimeFormatInfo.InvalidDateTimeStyles) != 0)
+ {
+ throw new ArgumentException(SR.Argument_InvalidDateTimeStyles, parameterName);
+ }
+ if (((style & (DateTimeStyles.AssumeLocal)) != 0) && ((style & (DateTimeStyles.AssumeUniversal)) != 0))
+ {
+ throw new ArgumentException(SR.Argument_ConflictingDateTimeStyles, parameterName);
+ }
+ if ((style & DateTimeStyles.NoCurrentDateDefault) != 0)
+ {
+ throw new ArgumentException(SR.Argument_DateTimeOffsetInvalidDateTimeStyles, parameterName);
+ }
+
+ // RoundtripKind does not make sense for DateTimeOffset; ignore this flag for backward compatibility with DateTime
+ style &= ~DateTimeStyles.RoundtripKind;
+
+ // AssumeLocal is also ignored as that is what we do by default with DateTimeOffset.Parse
+ style &= ~DateTimeStyles.AssumeLocal;
+
+ return style;
+ }
+
+ // Operators
+
+ public static implicit operator DateTimeOffset(DateTime dateTime)
+ {
+ return new DateTimeOffset(dateTime);
+ }
+
+ public static DateTimeOffset operator +(DateTimeOffset dateTimeOffset, TimeSpan timeSpan)
+ {
+ return new DateTimeOffset(dateTimeOffset.ClockDateTime + timeSpan, dateTimeOffset.Offset);
+ }
+
+
+ public static DateTimeOffset operator -(DateTimeOffset dateTimeOffset, TimeSpan timeSpan)
+ {
+ return new DateTimeOffset(dateTimeOffset.ClockDateTime - timeSpan, dateTimeOffset.Offset);
+ }
+
+ public static TimeSpan operator -(DateTimeOffset left, DateTimeOffset right)
+ {
+ return left.UtcDateTime - right.UtcDateTime;
+ }
+
+ public static bool operator ==(DateTimeOffset left, DateTimeOffset right)
+ {
+ return left.UtcDateTime == right.UtcDateTime;
+ }
+
+ public static bool operator !=(DateTimeOffset left, DateTimeOffset right)
+ {
+ return left.UtcDateTime != right.UtcDateTime;
+ }
+
+ public static bool operator <(DateTimeOffset left, DateTimeOffset right)
+ {
+ return left.UtcDateTime < right.UtcDateTime;
+ }
+
+ public static bool operator <=(DateTimeOffset left, DateTimeOffset right)
+ {
+ return left.UtcDateTime <= right.UtcDateTime;
+ }
+
+ public static bool operator >(DateTimeOffset left, DateTimeOffset right)
+ {
+ return left.UtcDateTime > right.UtcDateTime;
+ }
+
+ public static bool operator >=(DateTimeOffset left, DateTimeOffset right)
+ {
+ return left.UtcDateTime >= right.UtcDateTime;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/DayOfWeek.cs b/src/mscorlib/shared/System/DayOfWeek.cs
index 5d84257158..5d84257158 100644
--- a/src/mscorlib/src/System/DayOfWeek.cs
+++ b/src/mscorlib/shared/System/DayOfWeek.cs
diff --git a/src/mscorlib/shared/System/DefaultBinder.cs b/src/mscorlib/shared/System/DefaultBinder.cs
new file mode 100644
index 0000000000..3b46d5f4d3
--- /dev/null
+++ b/src/mscorlib/shared/System/DefaultBinder.cs
@@ -0,0 +1,1201 @@
+// 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.Reflection;
+using System.Diagnostics;
+using CultureInfo = System.Globalization.CultureInfo;
+
+namespace System
+{
+ //Marked serializable even though it has no state.
+ [Serializable]
+#if CORECLR
+ internal
+#else
+ public sealed
+#endif
+ partial class DefaultBinder : Binder
+ {
+ // This method is passed a set of methods and must choose the best
+ // fit. The methods all have the same number of arguments and the object
+ // array args. On exit, this method will choice the best fit method
+ // and coerce the args to match that method. By match, we mean all primitive
+ // arguments are exact matchs and all object arguments are exact or subclasses
+ // of the target. If the target OR is an interface, the object must implement
+ // that interface. There are a couple of exceptions
+ // thrown when a method cannot be returned. If no method matchs the args and
+ // ArgumentException is thrown. If multiple methods match the args then
+ // an AmbiguousMatchException is thrown.
+ //
+ // The most specific match will be selected.
+ //
+ public sealed override MethodBase BindToMethod(
+ BindingFlags bindingAttr, MethodBase[] match, ref object[] args,
+ ParameterModifier[] modifiers, CultureInfo cultureInfo, string[] names, out object state)
+ {
+ if (match == null || match.Length == 0)
+ throw new ArgumentException(SR.Arg_EmptyArray, nameof(match));
+
+ MethodBase[] candidates = (MethodBase[])match.Clone();
+
+ int i;
+ int j;
+
+ state = null;
+
+#region Map named parameters to candidate parameter postions
+ // We are creating an paramOrder array to act as a mapping
+ // between the order of the args and the actual order of the
+ // parameters in the method. This order may differ because
+ // named parameters (names) may change the order. If names
+ // is not provided, then we assume the default mapping (0,1,...)
+ int[][] paramOrder = new int[candidates.Length][];
+
+ for (i = 0; i < candidates.Length; i++)
+ {
+ ParameterInfo[] par = candidates[i].GetParametersNoCopy();
+
+ // args.Length + 1 takes into account the possibility of a last paramArray that can be omitted
+ paramOrder[i] = new int[(par.Length > args.Length) ? par.Length : args.Length];
+
+ if (names == null)
+ {
+ // Default mapping
+ for (j = 0; j < args.Length; j++)
+ paramOrder[i][j] = j;
+ }
+ else
+ {
+ // Named parameters, reorder the mapping. If CreateParamOrder fails, it means that the method
+ // doesn't have a name that matchs one of the named parameters so we don't consider it any further.
+ if (!CreateParamOrder(paramOrder[i], par, names))
+ candidates[i] = null;
+ }
+ }
+#endregion
+
+ Type[] paramArrayTypes = new Type[candidates.Length];
+
+ Type[] argTypes = new Type[args.Length];
+
+#region Cache the type of the provided arguments
+ // object that contain a null are treated as if they were typeless (but match either object
+ // references or value classes). We mark this condition by placing a null in the argTypes array.
+ for (i = 0; i < args.Length; i++)
+ {
+ if (args[i] != null)
+ {
+ argTypes[i] = args[i].GetType();
+ }
+ }
+#endregion
+
+
+ // Find the method that matches...
+ int CurIdx = 0;
+ bool defaultValueBinding = ((bindingAttr & BindingFlags.OptionalParamBinding) != 0);
+
+ Type paramArrayType = null;
+
+#region Filter methods by parameter count and type
+ for (i = 0; i < candidates.Length; i++)
+ {
+ paramArrayType = null;
+
+ // If we have named parameters then we may have a hole in the candidates array.
+ if (candidates[i] == null)
+ continue;
+
+ // Validate the parameters.
+ ParameterInfo[] par = candidates[i].GetParametersNoCopy();
+
+#region Match method by parameter count
+ if (par.Length == 0)
+ {
+#region No formal parameters
+ if (args.Length != 0)
+ {
+ if ((candidates[i].CallingConvention & CallingConventions.VarArgs) == 0)
+ continue;
+ }
+
+ // This is a valid routine so we move it up the candidates list.
+ paramOrder[CurIdx] = paramOrder[i];
+ candidates[CurIdx++] = candidates[i];
+
+ continue;
+#endregion
+ }
+ else if (par.Length > args.Length)
+ {
+#region Shortage of provided parameters
+ // If the number of parameters is greater than the number of args then
+ // we are in the situation were we may be using default values.
+ for (j = args.Length; j < par.Length - 1; j++)
+ {
+ if (par[j].DefaultValue == System.DBNull.Value)
+ break;
+ }
+
+ if (j != par.Length - 1)
+ continue;
+
+ if (par[j].DefaultValue == System.DBNull.Value)
+ {
+ if (!par[j].ParameterType.IsArray)
+ continue;
+
+ if (!par[j].IsDefined(typeof(ParamArrayAttribute), true))
+ continue;
+
+ paramArrayType = par[j].ParameterType.GetElementType();
+ }
+#endregion
+ }
+ else if (par.Length < args.Length)
+ {
+#region Excess provided parameters
+ // test for the ParamArray case
+ int lastArgPos = par.Length - 1;
+
+ if (!par[lastArgPos].ParameterType.IsArray)
+ continue;
+
+ if (!par[lastArgPos].IsDefined(typeof(ParamArrayAttribute), true))
+ continue;
+
+ if (paramOrder[i][lastArgPos] != lastArgPos)
+ continue;
+
+ paramArrayType = par[lastArgPos].ParameterType.GetElementType();
+#endregion
+ }
+ else
+ {
+#region Test for paramArray, save paramArray type
+ int lastArgPos = par.Length - 1;
+
+ if (par[lastArgPos].ParameterType.IsArray
+ && par[lastArgPos].IsDefined(typeof(ParamArrayAttribute), true)
+ && paramOrder[i][lastArgPos] == lastArgPos)
+ {
+ if (!par[lastArgPos].ParameterType.IsAssignableFrom(argTypes[lastArgPos]))
+ paramArrayType = par[lastArgPos].ParameterType.GetElementType();
+ }
+#endregion
+ }
+#endregion
+
+ Type pCls = null;
+ int argsToCheck = (paramArrayType != null) ? par.Length - 1 : args.Length;
+
+#region Match method by parameter type
+ for (j = 0; j < argsToCheck; j++)
+ {
+#region Classic argument coersion checks
+ // get the formal type
+ pCls = par[j].ParameterType;
+
+ if (pCls.IsByRef)
+ pCls = pCls.GetElementType();
+
+ // the type is the same
+ if (pCls == argTypes[paramOrder[i][j]])
+ continue;
+
+ // a default value is available
+ if (defaultValueBinding && args[paramOrder[i][j]] == Type.Missing)
+ continue;
+
+ // the argument was null, so it matches with everything
+ if (args[paramOrder[i][j]] == null)
+ continue;
+
+ // the type is Object, so it will match everything
+ if (pCls == typeof(object))
+ continue;
+
+ // now do a "classic" type check
+ if (pCls.IsPrimitive)
+ {
+ if (argTypes[paramOrder[i][j]] == null || !CanChangePrimitiveObjectToType(args[paramOrder[i][j]], pCls))
+ {
+ break;
+ }
+ }
+ else
+ {
+ if (argTypes[paramOrder[i][j]] == null)
+ continue;
+
+ if (!pCls.IsAssignableFrom(argTypes[paramOrder[i][j]]))
+ {
+ if (argTypes[paramOrder[i][j]].IsCOMObject)
+ {
+ if (pCls.IsInstanceOfType(args[paramOrder[i][j]]))
+ continue;
+ }
+ break;
+ }
+ }
+#endregion
+ }
+
+ if (paramArrayType != null && j == par.Length - 1)
+ {
+#region Check that excess arguments can be placed in the param array
+ for (; j < args.Length; j++)
+ {
+ if (paramArrayType.IsPrimitive)
+ {
+ if (argTypes[j] == null || !CanChangePrimitiveObjectToType(args[j], paramArrayType))
+ break;
+ }
+ else
+ {
+ if (argTypes[j] == null)
+ continue;
+
+ if (!paramArrayType.IsAssignableFrom(argTypes[j]))
+ {
+ if (argTypes[j].IsCOMObject)
+ {
+ if (paramArrayType.IsInstanceOfType(args[j]))
+ continue;
+ }
+
+ break;
+ }
+ }
+ }
+#endregion
+ }
+#endregion
+
+ if (j == args.Length)
+ {
+#region This is a valid routine so we move it up the candidates list
+ paramOrder[CurIdx] = paramOrder[i];
+ paramArrayTypes[CurIdx] = paramArrayType;
+ candidates[CurIdx++] = candidates[i];
+#endregion
+ }
+ }
+#endregion
+
+ // If we didn't find a method
+ if (CurIdx == 0)
+ throw new MissingMethodException(SR.MissingMember);
+
+ if (CurIdx == 1)
+ {
+#region Found only one method
+ if (names != null)
+ {
+ state = new BinderState((int[])paramOrder[0].Clone(), args.Length, paramArrayTypes[0] != null);
+ ReorderParams(paramOrder[0], args);
+ }
+
+ // If the parameters and the args are not the same length or there is a paramArray
+ // then we need to create a argument array.
+ ParameterInfo[] parms = candidates[0].GetParametersNoCopy();
+
+ if (parms.Length == args.Length)
+ {
+ if (paramArrayTypes[0] != null)
+ {
+ object[] objs = new object[parms.Length];
+ int lastPos = parms.Length - 1;
+ Array.Copy(args, 0, objs, 0, lastPos);
+ objs[lastPos] = Array.CreateInstance(paramArrayTypes[0], 1);
+ ((Array)objs[lastPos]).SetValue(args[lastPos], 0);
+ args = objs;
+ }
+ }
+ else if (parms.Length > args.Length)
+ {
+ object[] objs = new object[parms.Length];
+
+ for (i = 0; i < args.Length; i++)
+ objs[i] = args[i];
+
+ for (; i < parms.Length - 1; i++)
+ objs[i] = parms[i].DefaultValue;
+
+ if (paramArrayTypes[0] != null)
+ objs[i] = Array.CreateInstance(paramArrayTypes[0], 0); // create an empty array for the
+
+ else
+ objs[i] = parms[i].DefaultValue;
+
+ args = objs;
+ }
+ else
+ {
+ if ((candidates[0].CallingConvention & CallingConventions.VarArgs) == 0)
+ {
+ object[] objs = new object[parms.Length];
+ int paramArrayPos = parms.Length - 1;
+ Array.Copy(args, 0, objs, 0, paramArrayPos);
+ objs[paramArrayPos] = Array.CreateInstance(paramArrayTypes[0], args.Length - paramArrayPos);
+ Array.Copy(args, paramArrayPos, (System.Array)objs[paramArrayPos], 0, args.Length - paramArrayPos);
+ args = objs;
+ }
+ }
+#endregion
+
+ return candidates[0];
+ }
+
+ int currentMin = 0;
+ bool ambig = false;
+ for (i = 1; i < CurIdx; i++)
+ {
+#region Walk all of the methods looking the most specific method to invoke
+ int newMin = FindMostSpecificMethod(candidates[currentMin], paramOrder[currentMin], paramArrayTypes[currentMin],
+ candidates[i], paramOrder[i], paramArrayTypes[i], argTypes, args);
+
+ if (newMin == 0)
+ {
+ ambig = true;
+ }
+ else if (newMin == 2)
+ {
+ currentMin = i;
+ ambig = false;
+ }
+#endregion
+ }
+
+ if (ambig)
+ throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
+
+ // Reorder (if needed)
+ if (names != null)
+ {
+ state = new BinderState((int[])paramOrder[currentMin].Clone(), args.Length, paramArrayTypes[currentMin] != null);
+ ReorderParams(paramOrder[currentMin], args);
+ }
+
+ // If the parameters and the args are not the same length or there is a paramArray
+ // then we need to create a argument array.
+ ParameterInfo[] parameters = candidates[currentMin].GetParametersNoCopy();
+ if (parameters.Length == args.Length)
+ {
+ if (paramArrayTypes[currentMin] != null)
+ {
+ object[] objs = new object[parameters.Length];
+ int lastPos = parameters.Length - 1;
+ Array.Copy(args, 0, objs, 0, lastPos);
+ objs[lastPos] = Array.CreateInstance(paramArrayTypes[currentMin], 1);
+ ((Array)objs[lastPos]).SetValue(args[lastPos], 0);
+ args = objs;
+ }
+ }
+ else if (parameters.Length > args.Length)
+ {
+ object[] objs = new object[parameters.Length];
+
+ for (i = 0; i < args.Length; i++)
+ objs[i] = args[i];
+
+ for (; i < parameters.Length - 1; i++)
+ objs[i] = parameters[i].DefaultValue;
+
+ if (paramArrayTypes[currentMin] != null)
+ {
+ objs[i] = Array.CreateInstance(paramArrayTypes[currentMin], 0);
+ }
+ else
+ {
+ objs[i] = parameters[i].DefaultValue;
+ }
+
+ args = objs;
+ }
+ else
+ {
+ if ((candidates[currentMin].CallingConvention & CallingConventions.VarArgs) == 0)
+ {
+ object[] objs = new object[parameters.Length];
+ int paramArrayPos = parameters.Length - 1;
+ Array.Copy(args, 0, objs, 0, paramArrayPos);
+ objs[paramArrayPos] = Array.CreateInstance(paramArrayTypes[currentMin], args.Length - paramArrayPos);
+ Array.Copy(args, paramArrayPos, (System.Array)objs[paramArrayPos], 0, args.Length - paramArrayPos);
+ args = objs;
+ }
+ }
+
+ return candidates[currentMin];
+ }
+
+
+ // Given a set of fields that match the base criteria, select a field.
+ // if value is null then we have no way to select a field
+ public sealed override FieldInfo BindToField(BindingFlags bindingAttr, FieldInfo[] match, object value, CultureInfo cultureInfo)
+ {
+ if (match == null)
+ {
+ throw new ArgumentNullException(nameof(match));
+ }
+
+ int i;
+ // Find the method that match...
+ int CurIdx = 0;
+
+ Type valueType = null;
+
+ FieldInfo[] candidates = (FieldInfo[])match.Clone();
+
+ // If we are a FieldSet, then use the value's type to disambiguate
+ if ((bindingAttr & BindingFlags.SetField) != 0)
+ {
+ valueType = value.GetType();
+
+ for (i = 0; i < candidates.Length; i++)
+ {
+ Type pCls = candidates[i].FieldType;
+ if (pCls == valueType)
+ {
+ candidates[CurIdx++] = candidates[i];
+ continue;
+ }
+ if (value == Empty.Value)
+ {
+ // the object passed in was null which would match any non primitive non value type
+ if (pCls.IsClass)
+ {
+ candidates[CurIdx++] = candidates[i];
+ continue;
+ }
+ }
+ if (pCls == typeof(object))
+ {
+ candidates[CurIdx++] = candidates[i];
+ continue;
+ }
+ if (pCls.IsPrimitive)
+ {
+ if (CanChangePrimitiveObjectToType(value, pCls))
+ {
+ candidates[CurIdx++] = candidates[i];
+ continue;
+ }
+ }
+ else
+ {
+ if (pCls.IsAssignableFrom(valueType))
+ {
+ candidates[CurIdx++] = candidates[i];
+ continue;
+ }
+ }
+ }
+ if (CurIdx == 0)
+ throw new MissingFieldException(SR.MissingField);
+ if (CurIdx == 1)
+ return candidates[0];
+ }
+
+ // Walk all of the methods looking the most specific method to invoke
+ int currentMin = 0;
+ bool ambig = false;
+ for (i = 1; i < CurIdx; i++)
+ {
+ int newMin = FindMostSpecificField(candidates[currentMin], candidates[i]);
+ if (newMin == 0)
+ ambig = true;
+ else
+ {
+ if (newMin == 2)
+ {
+ currentMin = i;
+ ambig = false;
+ }
+ }
+ }
+ if (ambig)
+ throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
+ return candidates[currentMin];
+ }
+
+ // Given a set of methods that match the base criteria, select a method based
+ // upon an array of types. This method should return null if no method matchs
+ // the criteria.
+ public sealed override MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers)
+ {
+ int i;
+ int j;
+
+ Type[] realTypes = new Type[types.Length];
+ for (i = 0; i < types.Length; i++)
+ {
+ realTypes[i] = types[i].UnderlyingSystemType;
+ if (!(realTypes[i].IsRuntimeImplemented()))
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(types));
+ }
+ types = realTypes;
+
+ // We don't automatically jump out on exact match.
+ if (match == null || match.Length == 0)
+ throw new ArgumentException(SR.Arg_EmptyArray, nameof(match));
+
+ MethodBase[] candidates = (MethodBase[])match.Clone();
+
+ // Find all the methods that can be described by the types parameter.
+ // Remove all of them that cannot.
+ int CurIdx = 0;
+ for (i = 0; i < candidates.Length; i++)
+ {
+ ParameterInfo[] par = candidates[i].GetParametersNoCopy();
+ if (par.Length != types.Length)
+ continue;
+ for (j = 0; j < types.Length; j++)
+ {
+ Type pCls = par[j].ParameterType;
+ if (pCls == types[j])
+ continue;
+ if (pCls == typeof(object))
+ continue;
+ if (pCls.IsPrimitive)
+ {
+ if (!(types[j].UnderlyingSystemType.IsRuntimeImplemented()) ||
+ !CanChangePrimitive(types[j].UnderlyingSystemType, pCls.UnderlyingSystemType))
+ break;
+ }
+ else
+ {
+ if (!pCls.IsAssignableFrom(types[j]))
+ break;
+ }
+ }
+ if (j == types.Length)
+ candidates[CurIdx++] = candidates[i];
+ }
+ if (CurIdx == 0)
+ return null;
+ if (CurIdx == 1)
+ return candidates[0];
+
+ // Walk all of the methods looking the most specific method to invoke
+ int currentMin = 0;
+ bool ambig = false;
+ int[] paramOrder = new int[types.Length];
+ for (i = 0; i < types.Length; i++)
+ paramOrder[i] = i;
+ for (i = 1; i < CurIdx; i++)
+ {
+ int newMin = FindMostSpecificMethod(candidates[currentMin], paramOrder, null, candidates[i], paramOrder, null, types, null);
+ if (newMin == 0)
+ ambig = true;
+ else
+ {
+ if (newMin == 2)
+ {
+ currentMin = i;
+ ambig = false;
+ currentMin = i;
+ }
+ }
+ }
+ if (ambig)
+ throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
+ return candidates[currentMin];
+ }
+
+ // Given a set of properties that match the base criteria, select one.
+ public sealed override PropertyInfo SelectProperty(BindingFlags bindingAttr, PropertyInfo[] match, Type returnType,
+ Type[] indexes, ParameterModifier[] modifiers)
+ {
+ // Allow a null indexes array. But if it is not null, every element must be non-null as well.
+ if (indexes != null)
+ {
+ foreach (Type index in indexes)
+ {
+ if (index == null)
+ throw new ArgumentNullException(nameof(indexes));
+ }
+ }
+
+ if (match == null || match.Length == 0)
+ throw new ArgumentException(SR.Arg_EmptyArray, nameof(match));
+
+ PropertyInfo[] candidates = (PropertyInfo[])match.Clone();
+
+ int i, j = 0;
+
+ // Find all the properties that can be described by type indexes parameter
+ int CurIdx = 0;
+ int indexesLength = (indexes != null) ? indexes.Length : 0;
+ for (i = 0; i < candidates.Length; i++)
+ {
+ if (indexes != null)
+ {
+ ParameterInfo[] par = candidates[i].GetIndexParameters();
+ if (par.Length != indexesLength)
+ continue;
+
+ for (j = 0; j < indexesLength; j++)
+ {
+ Type pCls = par[j].ParameterType;
+
+ // If the classes exactly match continue
+ if (pCls == indexes[j])
+ continue;
+ if (pCls == typeof(object))
+ continue;
+
+ if (pCls.IsPrimitive)
+ {
+ if (!(indexes[j].UnderlyingSystemType.IsRuntimeImplemented()) ||
+ !CanChangePrimitive(indexes[j].UnderlyingSystemType, pCls.UnderlyingSystemType))
+ break;
+ }
+ else
+ {
+ if (!pCls.IsAssignableFrom(indexes[j]))
+ break;
+ }
+ }
+ }
+
+ if (j == indexesLength)
+ {
+ if (returnType != null)
+ {
+ if (candidates[i].PropertyType.IsPrimitive)
+ {
+ if (!(returnType.UnderlyingSystemType.IsRuntimeImplemented()) ||
+ !CanChangePrimitive(returnType.UnderlyingSystemType, candidates[i].PropertyType.UnderlyingSystemType))
+ continue;
+ }
+ else
+ {
+ if (!candidates[i].PropertyType.IsAssignableFrom(returnType))
+ continue;
+ }
+ }
+ candidates[CurIdx++] = candidates[i];
+ }
+ }
+ if (CurIdx == 0)
+ return null;
+ if (CurIdx == 1)
+ return candidates[0];
+
+ // Walk all of the properties looking the most specific method to invoke
+ int currentMin = 0;
+ bool ambig = false;
+ int[] paramOrder = new int[indexesLength];
+ for (i = 0; i < indexesLength; i++)
+ paramOrder[i] = i;
+ for (i = 1; i < CurIdx; i++)
+ {
+ int newMin = FindMostSpecificType(candidates[currentMin].PropertyType, candidates[i].PropertyType, returnType);
+ if (newMin == 0 && indexes != null)
+ newMin = FindMostSpecific(candidates[currentMin].GetIndexParameters(),
+ paramOrder,
+ null,
+ candidates[i].GetIndexParameters(),
+ paramOrder,
+ null,
+ indexes,
+ null);
+ if (newMin == 0)
+ {
+ newMin = FindMostSpecificProperty(candidates[currentMin], candidates[i]);
+ if (newMin == 0)
+ ambig = true;
+ }
+ if (newMin == 2)
+ {
+ ambig = false;
+ currentMin = i;
+ }
+ }
+
+ if (ambig)
+ throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
+ return candidates[currentMin];
+ }
+
+ // ChangeType
+ // The default binder doesn't support any change type functionality.
+ // This is because the default is built into the low level invoke code.
+ public override object ChangeType(object value, Type type, CultureInfo cultureInfo)
+ {
+ throw new NotSupportedException(SR.NotSupported_ChangeType);
+ }
+
+ public sealed override void ReorderArgumentArray(ref object[] args, object state)
+ {
+ BinderState binderState = (BinderState)state;
+ ReorderParams(binderState._argsMap, args);
+ if (binderState._isParamArray)
+ {
+ int paramArrayPos = args.Length - 1;
+ if (args.Length == binderState._originalSize)
+ args[paramArrayPos] = ((object[])args[paramArrayPos])[0];
+ else
+ {
+ // must be args.Length < state.originalSize
+ object[] newArgs = new object[args.Length];
+ Array.Copy(args, 0, newArgs, 0, paramArrayPos);
+ for (int i = paramArrayPos, j = 0; i < newArgs.Length; i++, j++)
+ {
+ newArgs[i] = ((object[])args[paramArrayPos])[j];
+ }
+ args = newArgs;
+ }
+ }
+ else
+ {
+ if (args.Length > binderState._originalSize)
+ {
+ object[] newArgs = new object[binderState._originalSize];
+ Array.Copy(args, 0, newArgs, 0, binderState._originalSize);
+ args = newArgs;
+ }
+ }
+ }
+
+ // Return any exact bindings that may exist. (This method is not defined on the
+ // Binder and is used by RuntimeType.)
+ public static MethodBase ExactBinding(MethodBase[] match, Type[] types, ParameterModifier[] modifiers)
+ {
+ if (match == null)
+ throw new ArgumentNullException(nameof(match));
+
+ MethodBase[] aExactMatches = new MethodBase[match.Length];
+ int cExactMatches = 0;
+
+ for (int i = 0; i < match.Length; i++)
+ {
+ ParameterInfo[] par = match[i].GetParametersNoCopy();
+ if (par.Length == 0)
+ {
+ continue;
+ }
+ int j;
+ for (j = 0; j < types.Length; j++)
+ {
+ Type pCls = par[j].ParameterType;
+
+ // If the classes exactly match continue
+ if (!pCls.Equals(types[j]))
+ break;
+ }
+ if (j < types.Length)
+ continue;
+
+ // Add the exact match to the array of exact matches.
+ aExactMatches[cExactMatches] = match[i];
+ cExactMatches++;
+ }
+
+ if (cExactMatches == 0)
+ return null;
+
+ if (cExactMatches == 1)
+ return aExactMatches[0];
+
+ return FindMostDerivedNewSlotMeth(aExactMatches, cExactMatches);
+ }
+
+ // Return any exact bindings that may exist. (This method is not defined on the
+ // Binder and is used by RuntimeType.)
+ public static PropertyInfo ExactPropertyBinding(PropertyInfo[] match, Type returnType, Type[] types, ParameterModifier[] modifiers)
+ {
+ if (match == null)
+ throw new ArgumentNullException(nameof(match));
+
+ PropertyInfo bestMatch = null;
+ int typesLength = (types != null) ? types.Length : 0;
+ for (int i = 0; i < match.Length; i++)
+ {
+ ParameterInfo[] par = match[i].GetIndexParameters();
+ int j;
+ for (j = 0; j < typesLength; j++)
+ {
+ Type pCls = par[j].ParameterType;
+
+ // If the classes exactly match continue
+ if (pCls != types[j])
+ break;
+ }
+ if (j < typesLength)
+ continue;
+ if (returnType != null && returnType != match[i].PropertyType)
+ continue;
+
+ if (bestMatch != null)
+ throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
+
+ bestMatch = match[i];
+ }
+ return bestMatch;
+ }
+
+ private static int FindMostSpecific(ParameterInfo[] p1, int[] paramOrder1, Type paramArrayType1,
+ ParameterInfo[] p2, int[] paramOrder2, Type paramArrayType2,
+ Type[] types, object[] args)
+ {
+ // A method using params is always less specific than one not using params
+ if (paramArrayType1 != null && paramArrayType2 == null) return 2;
+ if (paramArrayType2 != null && paramArrayType1 == null) return 1;
+
+ // now either p1 and p2 both use params or neither does.
+
+ bool p1Less = false;
+ bool p2Less = false;
+
+ for (int i = 0; i < types.Length; i++)
+ {
+ if (args != null && args[i] == Type.Missing)
+ continue;
+
+ Type c1, c2;
+
+ // If a param array is present, then either
+ // the user re-ordered the parameters in which case
+ // the argument to the param array is either an array
+ // in which case the params is conceptually ignored and so paramArrayType1 == null
+ // or the argument to the param array is a single element
+ // in which case paramOrder[i] == p1.Length - 1 for that element
+ // or the user did not re-order the parameters in which case
+ // the paramOrder array could contain indexes larger than p.Length - 1 (see VSW 577286)
+ // so any index >= p.Length - 1 is being put in the param array
+
+ if (paramArrayType1 != null && paramOrder1[i] >= p1.Length - 1)
+ c1 = paramArrayType1;
+ else
+ c1 = p1[paramOrder1[i]].ParameterType;
+
+ if (paramArrayType2 != null && paramOrder2[i] >= p2.Length - 1)
+ c2 = paramArrayType2;
+ else
+ c2 = p2[paramOrder2[i]].ParameterType;
+
+ if (c1 == c2) continue;
+
+ switch (FindMostSpecificType(c1, c2, types[i]))
+ {
+ case 0: return 0;
+ case 1: p1Less = true; break;
+ case 2: p2Less = true; break;
+ }
+ }
+
+ // Two way p1Less and p2Less can be equal. All the arguments are the
+ // same they both equal false, otherwise there were things that both
+ // were the most specific type on....
+ if (p1Less == p2Less)
+ {
+ // if we cannot tell which is a better match based on parameter types (p1Less == p2Less),
+ // let's see which one has the most matches without using the params array (the longer one wins).
+ if (!p1Less && args != null)
+ {
+ if (p1.Length > p2.Length)
+ {
+ return 1;
+ }
+ else if (p2.Length > p1.Length)
+ {
+ return 2;
+ }
+ }
+
+ return 0;
+ }
+ else
+ {
+ return (p1Less == true) ? 1 : 2;
+ }
+ }
+
+ private static int FindMostSpecificType(Type c1, Type c2, Type t)
+ {
+ // If the two types are exact move on...
+ if (c1 == c2)
+ return 0;
+
+ if (c1 == t)
+ return 1;
+
+ if (c2 == t)
+ return 2;
+
+ bool c1FromC2;
+ bool c2FromC1;
+
+ if (c1.IsByRef || c2.IsByRef)
+ {
+ if (c1.IsByRef && c2.IsByRef)
+ {
+ c1 = c1.GetElementType();
+ c2 = c2.GetElementType();
+ }
+ else if (c1.IsByRef)
+ {
+ if (c1.GetElementType() == c2)
+ return 2;
+
+ c1 = c1.GetElementType();
+ }
+ else
+ {
+ if (c2.GetElementType() == c1)
+ return 1;
+
+ c2 = c2.GetElementType();
+ }
+ }
+
+
+ if (c1.IsPrimitive && c2.IsPrimitive)
+ {
+ c1FromC2 = CanChangePrimitive(c2, c1);
+ c2FromC1 = CanChangePrimitive(c1, c2);
+ }
+ else
+ {
+ c1FromC2 = c1.IsAssignableFrom(c2);
+ c2FromC1 = c2.IsAssignableFrom(c1);
+ }
+
+ if (c1FromC2 == c2FromC1)
+ return 0;
+
+ if (c1FromC2)
+ {
+ return 2;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+
+ private static int FindMostSpecificMethod(MethodBase m1, int[] paramOrder1, Type paramArrayType1,
+ MethodBase m2, int[] paramOrder2, Type paramArrayType2,
+ Type[] types, object[] args)
+ {
+ // Find the most specific method based on the parameters.
+ int res = FindMostSpecific(m1.GetParametersNoCopy(), paramOrder1, paramArrayType1,
+ m2.GetParametersNoCopy(), paramOrder2, paramArrayType2, types, args);
+
+ // If the match was not ambigous then return the result.
+ if (res != 0)
+ return res;
+
+ // Check to see if the methods have the exact same name and signature.
+ if (CompareMethodSig(m1, m2))
+ {
+ // Determine the depth of the declaring types for both methods.
+ int hierarchyDepth1 = GetHierarchyDepth(m1.DeclaringType);
+ int hierarchyDepth2 = GetHierarchyDepth(m2.DeclaringType);
+
+ // The most derived method is the most specific one.
+ if (hierarchyDepth1 == hierarchyDepth2)
+ {
+ return 0;
+ }
+ else if (hierarchyDepth1 < hierarchyDepth2)
+ {
+ return 2;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+
+ // The match is ambigous.
+ return 0;
+ }
+
+ private static int FindMostSpecificField(FieldInfo cur1, FieldInfo cur2)
+ {
+ // Check to see if the fields have the same name.
+ if (cur1.Name == cur2.Name)
+ {
+ int hierarchyDepth1 = GetHierarchyDepth(cur1.DeclaringType);
+ int hierarchyDepth2 = GetHierarchyDepth(cur2.DeclaringType);
+
+ if (hierarchyDepth1 == hierarchyDepth2)
+ {
+ Debug.Assert(cur1.IsStatic != cur2.IsStatic, "hierarchyDepth1 == hierarchyDepth2");
+ return 0;
+ }
+ else if (hierarchyDepth1 < hierarchyDepth2)
+ return 2;
+ else
+ return 1;
+ }
+
+ // The match is ambigous.
+ return 0;
+ }
+
+ private static int FindMostSpecificProperty(PropertyInfo cur1, PropertyInfo cur2)
+ {
+ // Check to see if the fields have the same name.
+ if (cur1.Name == cur2.Name)
+ {
+ int hierarchyDepth1 = GetHierarchyDepth(cur1.DeclaringType);
+ int hierarchyDepth2 = GetHierarchyDepth(cur2.DeclaringType);
+
+ if (hierarchyDepth1 == hierarchyDepth2)
+ {
+ return 0;
+ }
+ else if (hierarchyDepth1 < hierarchyDepth2)
+ return 2;
+ else
+ return 1;
+ }
+
+ // The match is ambigous.
+ return 0;
+ }
+
+ public static bool CompareMethodSig(MethodBase m1, MethodBase m2)
+ {
+ ParameterInfo[] params1 = m1.GetParametersNoCopy();
+ ParameterInfo[] params2 = m2.GetParametersNoCopy();
+
+ if (params1.Length != params2.Length)
+ return false;
+
+ int numParams = params1.Length;
+ for (int i = 0; i < numParams; i++)
+ {
+ if (params1[i].ParameterType != params2[i].ParameterType)
+ return false;
+ }
+
+ return true;
+ }
+
+ private static int GetHierarchyDepth(Type t)
+ {
+ int depth = 0;
+
+ Type currentType = t;
+ do
+ {
+ depth++;
+ currentType = currentType.BaseType;
+ } while (currentType != null);
+
+ return depth;
+ }
+
+ internal static MethodBase FindMostDerivedNewSlotMeth(MethodBase[] match, int cMatches)
+ {
+ int deepestHierarchy = 0;
+ MethodBase methWithDeepestHierarchy = null;
+
+ for (int i = 0; i < cMatches; i++)
+ {
+ // Calculate the depth of the hierarchy of the declaring type of the
+ // current method.
+ int currentHierarchyDepth = GetHierarchyDepth(match[i].DeclaringType);
+
+ // The two methods have the same name, signature, and hierarchy depth.
+ // This can only happen if at least one is vararg or generic.
+ if (currentHierarchyDepth == deepestHierarchy)
+ {
+ throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
+ }
+
+ // Check to see if this method is on the most derived class.
+ if (currentHierarchyDepth > deepestHierarchy)
+ {
+ deepestHierarchy = currentHierarchyDepth;
+ methWithDeepestHierarchy = match[i];
+ }
+ }
+
+ return methWithDeepestHierarchy;
+ }
+
+ // This method will sort the vars array into the mapping order stored
+ // in the paramOrder array.
+ private static void ReorderParams(int[] paramOrder, object[] vars)
+ {
+ object[] varsCopy = new object[vars.Length];
+ for (int i = 0; i < vars.Length; i++)
+ varsCopy[i] = vars[i];
+
+ for (int i = 0; i < vars.Length; i++)
+ vars[i] = varsCopy[paramOrder[i]];
+ }
+
+ // This method will create the mapping between the Parameters and the underlying
+ // data based upon the names array. The names array is stored in the same order
+ // as the values and maps to the parameters of the method. We store the mapping
+ // from the parameters to the names in the paramOrder array. All parameters that
+ // don't have matching names are then stored in the array in order.
+ private static bool CreateParamOrder(int[] paramOrder, ParameterInfo[] pars, string[] names)
+ {
+ bool[] used = new bool[pars.Length];
+
+ // Mark which parameters have not been found in the names list
+ for (int i = 0; i < pars.Length; i++)
+ paramOrder[i] = -1;
+ // Find the parameters with names.
+ for (int i = 0; i < names.Length; i++)
+ {
+ int j;
+ for (j = 0; j < pars.Length; j++)
+ {
+ if (names[i].Equals(pars[j].Name))
+ {
+ paramOrder[j] = i;
+ used[i] = true;
+ break;
+ }
+ }
+ // This is an error condition. The name was not found. This
+ // method must not match what we sent.
+ if (j == pars.Length)
+ return false;
+ }
+
+ // Now we fill in the holes with the parameters that are unused.
+ int pos = 0;
+ for (int i = 0; i < pars.Length; i++)
+ {
+ if (paramOrder[i] == -1)
+ {
+ for (; pos < pars.Length; pos++)
+ {
+ if (!used[pos])
+ {
+ paramOrder[i] = pos;
+ pos++;
+ break;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ internal class BinderState
+ {
+ internal readonly int[] _argsMap;
+ internal readonly int _originalSize;
+ internal readonly bool _isParamArray;
+
+ internal BinderState(int[] argsMap, int originalSize, bool isParamArray)
+ {
+ _argsMap = argsMap;
+ _originalSize = originalSize;
+ _isParamArray = isParamArray;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Diagnostics/CodeAnalysis/SuppressMessageAttribute.cs b/src/mscorlib/shared/System/Diagnostics/CodeAnalysis/SuppressMessageAttribute.cs
new file mode 100644
index 0000000000..893d7b8bc9
--- /dev/null
+++ b/src/mscorlib/shared/System/Diagnostics/CodeAnalysis/SuppressMessageAttribute.cs
@@ -0,0 +1,39 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** An attribute to suppress violation messages/warnings
+** by static code analysis tools.
+**
+**
+===========================================================*/
+
+namespace System.Diagnostics.CodeAnalysis
+{
+ [AttributeUsage(
+ AttributeTargets.All,
+ Inherited = false,
+ AllowMultiple = true
+ )
+ ]
+ [Conditional("CODE_ANALYSIS")]
+ public sealed class SuppressMessageAttribute : Attribute
+ {
+ public SuppressMessageAttribute(string category, string checkId)
+ {
+ Category = category;
+ CheckId = checkId;
+ }
+
+ public string Category { get; }
+ public string CheckId { get; }
+ public string Scope { get; set; }
+ public string Target { get; set; }
+ public string MessageId { get; set; }
+ public string Justification { get; set; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Diagnostics/ConditionalAttribute.cs b/src/mscorlib/shared/System/Diagnostics/ConditionalAttribute.cs
new file mode 100644
index 0000000000..d5bca6e208
--- /dev/null
+++ b/src/mscorlib/shared/System/Diagnostics/ConditionalAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Diagnostics
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
+ public sealed class ConditionalAttribute : Attribute
+ {
+ public ConditionalAttribute(string conditionString)
+ {
+ ConditionString = conditionString;
+ }
+
+ public string ConditionString { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Diagnostics/Debug.cs b/src/mscorlib/shared/System/Diagnostics/Debug.cs
new file mode 100644
index 0000000000..59f3c378da
--- /dev/null
+++ b/src/mscorlib/shared/System/Diagnostics/Debug.cs
@@ -0,0 +1,323 @@
+// 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.
+
+// Do not remove this, it is needed to retain calls to these conditional methods in release builds
+#define DEBUG
+
+namespace System.Diagnostics
+{
+ /// <summary>
+ /// Provides a set of properties and methods for debugging code.
+ /// </summary>
+ public static partial class Debug
+ {
+ private static readonly object s_lock = new object();
+
+ public static bool AutoFlush { get { return true; } set { } }
+
+ [ThreadStatic]
+ private static int s_indentLevel;
+ public static int IndentLevel
+ {
+ get
+ {
+ return s_indentLevel;
+ }
+ set
+ {
+ s_indentLevel = value < 0 ? 0 : value;
+ }
+ }
+
+ private static int s_indentSize = 4;
+ public static int IndentSize
+ {
+ get
+ {
+ return s_indentSize;
+ }
+ set
+ {
+ s_indentSize = value < 0 ? 0 : value;
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Close() { }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Flush() { }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Indent()
+ {
+ IndentLevel++;
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Unindent()
+ {
+ IndentLevel--;
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Print(string message)
+ {
+ Write(message);
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Print(string format, params object[] args)
+ {
+ Write(string.Format(null, format, args));
+ }
+
+ private static readonly object s_ForLock = new Object();
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Assert(bool condition)
+ {
+ Assert(condition, string.Empty, string.Empty);
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Assert(bool condition, string message)
+ {
+ Assert(condition, message, string.Empty);
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Assert(bool condition, string message, string detailMessage)
+ {
+ if (!condition)
+ {
+ string stackTrace;
+
+ try
+ {
+ stackTrace = Internal.Runtime.Augments.EnvironmentAugments.StackTrace;
+ }
+ catch
+ {
+ stackTrace = "";
+ }
+
+ WriteLine(FormatAssert(stackTrace, message, detailMessage));
+ s_ShowAssertDialog(stackTrace, message, detailMessage);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Fail(string message)
+ {
+ Assert(false, message, string.Empty);
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Fail(string message, string detailMessage)
+ {
+ Assert(false, message, detailMessage);
+ }
+
+ private static string FormatAssert(string stackTrace, string message, string detailMessage)
+ {
+ string newLine = GetIndentString() + Environment.NewLine;
+ return SR.DebugAssertBanner + newLine
+ + SR.DebugAssertShortMessage + newLine
+ + message + newLine
+ + SR.DebugAssertLongMessage + newLine
+ + detailMessage + newLine
+ + stackTrace;
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Assert(bool condition, string message, string detailMessageFormat, params object[] args)
+ {
+ Assert(condition, message, string.Format(detailMessageFormat, args));
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLine(string message)
+ {
+ Write(message + Environment.NewLine);
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Write(string message)
+ {
+ lock (s_lock)
+ {
+ if (message == null)
+ {
+ s_WriteCore(string.Empty);
+ return;
+ }
+ if (s_needIndent)
+ {
+ message = GetIndentString() + message;
+ s_needIndent = false;
+ }
+ s_WriteCore(message);
+ if (message.EndsWith(Environment.NewLine))
+ {
+ s_needIndent = true;
+ }
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLine(object value)
+ {
+ WriteLine(value?.ToString());
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLine(object value, string category)
+ {
+ WriteLine(value?.ToString(), category);
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLine(string format, params object[] args)
+ {
+ WriteLine(string.Format(null, format, args));
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLine(string message, string category)
+ {
+ if (category == null)
+ {
+ WriteLine(message);
+ }
+ else
+ {
+ WriteLine(category + ":" + message);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Write(object value)
+ {
+ Write(value?.ToString());
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Write(string message, string category)
+ {
+ if (category == null)
+ {
+ Write(message);
+ }
+ else
+ {
+ Write(category + ":" + message);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Write(object value, string category)
+ {
+ Write(value?.ToString(), category);
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteIf(bool condition, string message)
+ {
+ if (condition)
+ {
+ Write(message);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteIf(bool condition, object value)
+ {
+ if (condition)
+ {
+ Write(value);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteIf(bool condition, string message, string category)
+ {
+ if (condition)
+ {
+ Write(message, category);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteIf(bool condition, object value, string category)
+ {
+ if (condition)
+ {
+ Write(value, category);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLineIf(bool condition, object value)
+ {
+ if (condition)
+ {
+ WriteLine(value);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLineIf(bool condition, object value, string category)
+ {
+ if (condition)
+ {
+ WriteLine(value, category);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLineIf(bool condition, string message)
+ {
+ if (condition)
+ {
+ WriteLine(message);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLineIf(bool condition, string message, string category)
+ {
+ if (condition)
+ {
+ WriteLine(message, category);
+ }
+ }
+
+ private static bool s_needIndent;
+
+ private static string s_indentString;
+
+ private static string GetIndentString()
+ {
+ int indentCount = IndentSize * IndentLevel;
+ if (s_indentString?.Length == indentCount)
+ {
+ return s_indentString;
+ }
+ return s_indentString = new string(' ', indentCount);
+ }
+
+ private sealed class DebugAssertException : Exception
+ {
+ internal DebugAssertException(string message, string detailMessage, string stackTrace) :
+ base(message + Environment.NewLine + detailMessage + Environment.NewLine + stackTrace)
+ {
+ }
+ }
+
+ // internal and not readonly so that the tests can swap this out.
+ internal static Action<string, string, string> s_ShowAssertDialog = ShowAssertDialog;
+ internal static Action<string> s_WriteCore = WriteCore;
+ }
+}
diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/ActivityTracker.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/ActivityTracker.cs
new file mode 100644
index 0000000000..e32abd2895
--- /dev/null
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/ActivityTracker.cs
@@ -0,0 +1,665 @@
+// 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.Diagnostics;
+using System.Threading;
+#if !ES_BUILD_AGAINST_DOTNET_V35
+using Contract = System.Diagnostics.Contracts.Contract;
+#else
+using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract;
+#endif
+
+#if ES_BUILD_STANDALONE
+namespace Microsoft.Diagnostics.Tracing
+#else
+using System.Threading.Tasks;
+namespace System.Diagnostics.Tracing
+#endif
+{
+ /// <summary>
+ /// Tracks activities. This is meant to be a singleton (accessed by the ActivityTracer.Instance static property)
+ ///
+ /// Logically this is simply holds the m_current variable that holds the async local that holds the current ActivityInfo
+ /// An ActivityInfo is represents a activity (which knows its creator and thus knows its path).
+ ///
+ /// Most of the magic is in the async local (it gets copied to new tasks)
+ ///
+ /// On every start event call OnStart
+ ///
+ /// Guid activityID;
+ /// Guid relatedActivityID;
+ /// if (OnStart(activityName, out activityID, out relatedActivityID, ForceStop, options))
+ /// // Log Start event with activityID and relatedActivityID
+ ///
+ /// On every stop event call OnStop
+ ///
+ /// Guid activityID;
+ /// if (OnStop(activityName, ref activityID ForceStop))
+ /// // Stop event with activityID
+ ///
+ /// On any normal event log the event with activityTracker.CurrentActivityId
+ /// </summary>
+ internal class ActivityTracker
+ {
+
+ /// <summary>
+ /// Called on work item begins. The activity name = providerName + activityName without 'Start' suffix.
+ /// It updates CurrentActivityId to track.
+ ///
+ /// It returns true if the Start should be logged, otherwise (if it is illegal recursion) it return false.
+ ///
+ /// The start event should use as its activity ID the CurrentActivityId AFTER calling this routine and its
+ /// RelatedActivityID the CurrentActivityId BEFORE calling this routine (the creator).
+ ///
+ /// If activity tracing is not on, then activityId and relatedActivityId are not set
+ /// </summary>
+ public void OnStart(string providerName, string activityName, int task, ref Guid activityId, ref Guid relatedActivityId, EventActivityOptions options)
+ {
+ if (m_current == null) // We are not enabled
+ {
+ // We used to rely on the TPL provider turning us on, but that has the disadvantage that you don't get Start-Stop tracking
+ // until you use Tasks for the first time (which you may never do). Thus we change it to pull rather tan push for whether
+ // we are enabled.
+ if (m_checkedForEnable)
+ return;
+ m_checkedForEnable = true;
+ if (TplEtwProvider.Log.IsEnabled(EventLevel.Informational, TplEtwProvider.Keywords.TasksFlowActivityIds))
+ Enable();
+ if (m_current == null)
+ return;
+ }
+
+
+ Debug.Assert((options & EventActivityOptions.Disable) == 0);
+
+ var currentActivity = m_current.Value;
+ var fullActivityName = NormalizeActivityName(providerName, activityName, task);
+
+ var etwLog = TplEtwProvider.Log;
+ if (etwLog.Debug)
+ {
+ etwLog.DebugFacilityMessage("OnStartEnter", fullActivityName);
+ etwLog.DebugFacilityMessage("OnStartEnterActivityState", ActivityInfo.LiveActivities(currentActivity));
+ }
+
+ if (currentActivity != null)
+ {
+ // Stop activity tracking if we reached the maximum allowed depth
+ if (currentActivity.m_level >= MAX_ACTIVITY_DEPTH)
+ {
+ activityId = Guid.Empty;
+ relatedActivityId = Guid.Empty;
+ if (etwLog.Debug)
+ etwLog.DebugFacilityMessage("OnStartRET", "Fail");
+ return;
+ }
+ // Check for recursion, and force-stop any activities if the activity already started.
+ if ((options & EventActivityOptions.Recursive) == 0)
+ {
+ ActivityInfo existingActivity = FindActiveActivity(fullActivityName, currentActivity);
+ if (existingActivity != null)
+ {
+ OnStop(providerName, activityName, task, ref activityId);
+ currentActivity = m_current.Value;
+ }
+ }
+ }
+
+ // Get a unique ID for this activity.
+ long id;
+ if (currentActivity == null)
+ id = Interlocked.Increment(ref m_nextId);
+ else
+ id = Interlocked.Increment(ref currentActivity.m_lastChildID);
+
+ // The previous ID is my 'causer' and becomes my related activity ID
+ relatedActivityId = EventSource.CurrentThreadActivityId;
+
+ // Add to the list of started but not stopped activities.
+ ActivityInfo newActivity = new ActivityInfo(fullActivityName, id, currentActivity, relatedActivityId, options);
+ m_current.Value = newActivity;
+
+ // Remember the current ID so we can log it
+ activityId = newActivity.ActivityId;
+
+ if (etwLog.Debug)
+ {
+ etwLog.DebugFacilityMessage("OnStartRetActivityState", ActivityInfo.LiveActivities(newActivity));
+ etwLog.DebugFacilityMessage1("OnStartRet", activityId.ToString(), relatedActivityId.ToString());
+ }
+ }
+
+ /// <summary>
+ /// Called when a work item stops. The activity name = providerName + activityName without 'Stop' suffix.
+ /// It updates m_current variable to track this fact. The Stop event associated with stop should log the ActivityID associated with the event.
+ ///
+ /// If activity tracing is not on, then activityId and relatedActivityId are not set
+ /// </summary>
+ public void OnStop(string providerName, string activityName, int task, ref Guid activityId)
+ {
+ if (m_current == null) // We are not enabled
+ return;
+
+ var fullActivityName = NormalizeActivityName(providerName, activityName, task);
+
+ var etwLog = TplEtwProvider.Log;
+ if (etwLog.Debug)
+ {
+ etwLog.DebugFacilityMessage("OnStopEnter", fullActivityName);
+ etwLog.DebugFacilityMessage("OnStopEnterActivityState", ActivityInfo.LiveActivities(m_current.Value));
+ }
+
+ for (; ; ) // This is a retry loop.
+ {
+ ActivityInfo currentActivity = m_current.Value;
+ ActivityInfo newCurrentActivity = null; // if we have seen any live activities (orphans), at he first one we have seen.
+
+ // Search to find the activity to stop in one pass. This insures that we don't let one mistake
+ // (stopping something that was not started) cause all active starts to be stopped
+ // By first finding the target start to stop we are more robust.
+ ActivityInfo activityToStop = FindActiveActivity(fullActivityName, currentActivity);
+
+ // ignore stops where we can't find a start because we may have popped them previously.
+ if (activityToStop == null)
+ {
+ activityId = Guid.Empty;
+ // TODO add some logging about this. Basically could not find matching start.
+ if (etwLog.Debug)
+ etwLog.DebugFacilityMessage("OnStopRET", "Fail");
+ return;
+ }
+
+ activityId = activityToStop.ActivityId;
+
+ // See if there are any orphans that need to be stopped.
+ ActivityInfo orphan = currentActivity;
+ while (orphan != activityToStop && orphan != null)
+ {
+ if (orphan.m_stopped != 0) // Skip dead activities.
+ {
+ orphan = orphan.m_creator;
+ continue;
+ }
+ if (orphan.CanBeOrphan())
+ {
+ // We can't pop anything after we see a valid orphan, remember this for later when we update m_current.
+ if (newCurrentActivity == null)
+ newCurrentActivity = orphan;
+ }
+ else
+ {
+ orphan.m_stopped = 1;
+ Debug.Assert(orphan.m_stopped != 0);
+ }
+ orphan = orphan.m_creator;
+ }
+
+ // try to Stop the activity atomically. Other threads may be trying to do this as well.
+ if (Interlocked.CompareExchange(ref activityToStop.m_stopped, 1, 0) == 0)
+ {
+ // I succeeded stopping this activity. Now we update our m_current pointer
+
+ // If I haven't yet determined the new current activity, it is my creator.
+ if (newCurrentActivity == null)
+ newCurrentActivity = activityToStop.m_creator;
+
+ m_current.Value = newCurrentActivity;
+
+ if (etwLog.Debug)
+ {
+ etwLog.DebugFacilityMessage("OnStopRetActivityState", ActivityInfo.LiveActivities(newCurrentActivity));
+ etwLog.DebugFacilityMessage("OnStopRet", activityId.ToString());
+ }
+ return;
+ }
+ // We failed to stop it. We must have hit a race to stop it. Just start over and try again.
+ }
+ }
+
+ /// <summary>
+ /// Turns on activity tracking. It is sticky, once on it stays on (race issues otherwise)
+ /// </summary>
+ public void Enable()
+ {
+ if (m_current == null)
+ {
+ // Catch the not Implemented
+ try
+ {
+ m_current = new AsyncLocal<ActivityInfo>(ActivityChanging);
+ }
+ catch (NotImplementedException) {
+#if (!ES_BUILD_PCL && ! ES_BUILD_PN)
+ // send message to debugger without delay
+ System.Diagnostics.Debugger.Log(0, null, "Activity Enabled() called but AsyncLocals Not Supported (pre V4.6). Ignoring Enable");
+#endif
+ }
+ }
+ }
+
+ /// <summary>
+ /// An activity tracker is a singleton, this is how you get the one and only instance.
+ /// </summary>
+ public static ActivityTracker Instance { get { return s_activityTrackerInstance; } }
+
+
+ #region private
+
+ /// <summary>
+ /// The current activity ID. Use this to log normal events.
+ /// </summary>
+ private Guid CurrentActivityId { get { return m_current.Value.ActivityId; } }
+
+ /// <summary>
+ /// Searched for a active (nonstopped) activity with the given name. Returns null if not found.
+ /// </summary>
+ private ActivityInfo FindActiveActivity(string name, ActivityInfo startLocation)
+ {
+ var activity = startLocation;
+ while (activity != null)
+ {
+ if (name == activity.m_name && activity.m_stopped == 0)
+ return activity;
+ activity = activity.m_creator;
+ }
+ return null;
+ }
+
+ /// <summary>
+ /// Strip out "Start" or "End" suffix from activity name and add providerName prefix.
+ /// If 'task' it does not end in Start or Stop and Task is non-zero use that as the name of the activity
+ /// </summary>
+ private string NormalizeActivityName(string providerName, string activityName, int task)
+ {
+ if (activityName.EndsWith(EventSource.s_ActivityStartSuffix, StringComparison.Ordinal))
+ activityName = activityName.Substring(0, activityName.Length - EventSource.s_ActivityStartSuffix.Length);
+ else if (activityName.EndsWith(EventSource.s_ActivityStopSuffix, StringComparison.Ordinal))
+ activityName = activityName.Substring(0, activityName.Length - EventSource.s_ActivityStopSuffix.Length);
+ else if (task != 0)
+ activityName = "task" + task.ToString();
+
+ // We use provider name to distinguish between activities from different providers.
+ return providerName + activityName;
+ }
+
+ // *******************************************************************************
+ /// <summary>
+ /// An ActivityInfo represents a particular activity. It is almost read-only. The only
+ /// fields that change after creation are
+ /// m_lastChildID - used to generate unique IDs for the children activities and for the most part can be ignored.
+ /// m_stopped - indicates that this activity is dead
+ /// This read-only-ness is important because an activity's m_creator chain forms the
+ /// 'Path of creation' for the activity (which is also its unique ID) but is also used as
+ /// the 'list of live parents' which indicate of those ancestors, which are alive (if they
+ /// are not marked dead they are alive).
+ /// </summary>
+ private class ActivityInfo
+ {
+ public ActivityInfo(string name, long uniqueId, ActivityInfo creator, Guid activityIDToRestore, EventActivityOptions options)
+ {
+ m_name = name;
+ m_eventOptions = options;
+ m_creator = creator;
+ m_uniqueId = uniqueId;
+ m_level = creator != null ? creator.m_level + 1 : 0;
+ m_activityIdToRestore = activityIDToRestore;
+
+ // Create a nice GUID that encodes the chain of activities that started this one.
+ CreateActivityPathGuid(out m_guid, out m_activityPathGuidOffset);
+ }
+
+ public Guid ActivityId
+ {
+ get
+ {
+ return m_guid;
+ }
+ }
+
+ public static string Path(ActivityInfo activityInfo)
+ {
+ if (activityInfo == null)
+ return ("");
+ return Path(activityInfo.m_creator) + "/" + activityInfo.m_uniqueId.ToString();
+ }
+
+ public override string ToString()
+ {
+ return m_name + "(" + Path(this) + (m_stopped != 0 ? ",DEAD)" : ")");
+ }
+
+ public static string LiveActivities(ActivityInfo list)
+ {
+ if (list == null)
+ return "";
+ return list.ToString() + ";" + LiveActivities(list.m_creator);
+ }
+
+ public bool CanBeOrphan()
+ {
+ if ((m_eventOptions & EventActivityOptions.Detachable) != 0)
+ return true;
+ return false;
+ }
+
+ #region private
+
+ #region CreateActivityPathGuid
+ /// <summary>
+ /// Logically every activity Path (see Path()) that describes the activities that caused this
+ /// (rooted in an activity that predates activity tracking.
+ ///
+ /// We wish to encode this path in the Guid to the extent that we can. Many of the paths have
+ /// many small numbers in them and we take advantage of this in the encoding to output as long
+ /// a path in the GUID as possible.
+ ///
+ /// Because of the possibility of GUID collision, we only use 96 of the 128 bits of the GUID
+ /// for encoding the path. The last 32 bits are a simple checksum (and random number) that
+ /// identifies this as using the convention defined here.
+ ///
+ /// It returns both the GUID which has the path as well as the offset that points just beyond
+ /// the end of the activity (so it can be appended to). Note that if the end is in a nibble
+ /// (it uses nibbles instead of bytes as the unit of encoding, then it will point at the unfinished
+ /// byte (since the top nibble can't be zero you can determine if this is true by seeing if
+ /// this byte is nonZero. This offset is needed to efficiently create the ID for child activities.
+ /// </summary>
+ private unsafe void CreateActivityPathGuid(out Guid idRet, out int activityPathGuidOffset)
+ {
+ fixed (Guid* outPtr = &idRet)
+ {
+ int activityPathGuidOffsetStart = 0;
+ if (m_creator != null)
+ {
+ activityPathGuidOffsetStart = m_creator.m_activityPathGuidOffset;
+ idRet = m_creator.m_guid;
+ }
+ else
+ {
+ // TODO FIXME - differentiate between AD inside PCL
+ int appDomainID = 0;
+#if (!ES_BUILD_STANDALONE && !ES_BUILD_PN)
+ appDomainID = System.Threading.Thread.GetDomainID();
+#endif
+ // We start with the appdomain number to make this unique among appdomains.
+ activityPathGuidOffsetStart = AddIdToGuid(outPtr, activityPathGuidOffsetStart, (uint)appDomainID);
+ }
+
+ activityPathGuidOffset = AddIdToGuid(outPtr, activityPathGuidOffsetStart, (uint)m_uniqueId);
+
+
+ // If the path does not fit, Make a GUID by incrementing rather than as a path, keeping as much of the path as possible
+ if (12 < activityPathGuidOffset)
+ CreateOverflowGuid(outPtr);
+ }
+ }
+
+ /// <summary>
+ /// If we can't fit the activity Path into the GUID we come here. What we do is simply
+ /// generate a 4 byte number (s_nextOverflowId). Then look for an ancestor that has
+ /// sufficient space for this ID. By doing this, we preserve the fact that this activity
+ /// is a child (of unknown depth) from that ancestor.
+ /// </summary>
+ private unsafe void CreateOverflowGuid(Guid* outPtr)
+ {
+ // Search backwards for an ancestor that has sufficient space to put the ID.
+ for (ActivityInfo ancestor = m_creator; ancestor != null; ancestor = ancestor.m_creator)
+ {
+ if (ancestor.m_activityPathGuidOffset <= 10) // we need at least 2 bytes.
+ {
+ uint id = unchecked((uint)Interlocked.Increment(ref ancestor.m_lastChildID)); // Get a unique ID
+ // Try to put the ID into the GUID
+ *outPtr = ancestor.m_guid;
+ int endId = AddIdToGuid(outPtr, ancestor.m_activityPathGuidOffset, id, true);
+
+ // Does it fit?
+ if (endId <= 12)
+ break;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The encoding for a list of numbers used to make Activity GUIDs. Basically
+ /// we operate on nibbles (which are nice because they show up as hex digits). The
+ /// list is ended with a end nibble (0) and depending on the nibble value (Below)
+ /// the value is either encoded into nibble itself or it can spill over into the
+ /// bytes that follow.
+ /// </summary>
+ enum NumberListCodes : byte
+ {
+ End = 0x0, // ends the list. No valid value has this prefix.
+ LastImmediateValue = 0xA,
+
+ PrefixCode = 0xB, // all the 'long' encodings go here. If the next nibble is MultiByte1-4
+ // than this is a 'overflow' id. Unlike the hierarchical IDs these are
+ // allocated densely but don't tell you anything about nesting. we use
+ // these when we run out of space in the GUID to store the path.
+
+ MultiByte1 = 0xC, // 1 byte follows. If this Nibble is in the high bits, it the high bits of the number are stored in the low nibble.
+ // commented out because the code does not explicitly reference the names (but they are logically defined).
+ // MultiByte2 = 0xD, // 2 bytes follow (we don't bother with the nibble optimization)
+ // MultiByte3 = 0xE, // 3 bytes follow (we don't bother with the nibble optimization)
+ // MultiByte4 = 0xF, // 4 bytes follow (we don't bother with the nibble optimization)
+ }
+
+ /// Add the activity id 'id' to the output Guid 'outPtr' starting at the offset 'whereToAddId'
+ /// Thus if this number is 6 that is where 'id' will be added. This will return 13 (12
+ /// is the maximum number of bytes that fit in a GUID) if the path did not fit.
+ /// If 'overflow' is true, then the number is encoded as an 'overflow number (which has a
+ /// special (longer prefix) that indicates that this ID is allocated differently
+ private static unsafe int AddIdToGuid(Guid* outPtr, int whereToAddId, uint id, bool overflow = false)
+ {
+ byte* ptr = (byte*)outPtr;
+ byte* endPtr = ptr + 12;
+ ptr += whereToAddId;
+ if (endPtr <= ptr)
+ return 13; // 12 means we might exactly fit, 13 means we definately did not fit
+
+ if (0 < id && id <= (uint)NumberListCodes.LastImmediateValue && !overflow)
+ WriteNibble(ref ptr, endPtr, id);
+ else
+ {
+ uint len = 4;
+ if (id <= 0xFF)
+ len = 1;
+ else if (id <= 0xFFFF)
+ len = 2;
+ else if (id <= 0xFFFFFF)
+ len = 3;
+
+ if (overflow)
+ {
+ if (endPtr <= ptr + 2) // I need at least 2 bytes
+ return 13;
+
+ // Write out the prefix code nibble and the length nibble
+ WriteNibble(ref ptr, endPtr, (uint)NumberListCodes.PrefixCode);
+ }
+ // The rest is the same for overflow and non-overflow case
+ WriteNibble(ref ptr, endPtr, (uint)NumberListCodes.MultiByte1 + (len - 1));
+
+ // Do we have an odd nibble? If so flush it or use it for the 12 byte case.
+ if (ptr < endPtr && *ptr != 0)
+ {
+ // If the value < 4096 we can use the nibble we are otherwise just outputting as padding.
+ if (id < 4096)
+ {
+ // Indicate this is a 1 byte multicode with 4 high order bits in the lower nibble.
+ *ptr = (byte)(((uint)NumberListCodes.MultiByte1 << 4) + (id >> 8));
+ id &= 0xFF; // Now we only want the low order bits.
+ }
+ ptr++;
+ }
+
+ // Write out the bytes.
+ while (0 < len)
+ {
+ if (endPtr <= ptr)
+ {
+ ptr++; // Indicate that we have overflowed
+ break;
+ }
+ *ptr++ = (byte)id;
+ id = (id >> 8);
+ --len;
+ }
+ }
+
+ // Compute the checksum
+ uint* sumPtr = (uint*)outPtr;
+ // We set the last DWORD the sum of the first 3 DWORDS in the GUID. This
+ sumPtr[3] = sumPtr[0] + sumPtr[1] + sumPtr[2] + 0x599D99AD; // This last number is a random number (it identifies us as us)
+
+ return (int)(ptr - ((byte*)outPtr));
+ }
+
+ /// <summary>
+ /// Write a single Nible 'value' (must be 0-15) to the byte buffer represented by *ptr.
+ /// Will not go past 'endPtr'. Also it assumes that we never write 0 so we can detect
+ /// whether a nibble has already been written to ptr because it will be nonzero.
+ /// Thus if it is non-zero it adds to the current byte, otherwise it advances and writes
+ /// the new byte (in the high bits) of the next byte.
+ /// </summary>
+ private static unsafe void WriteNibble(ref byte* ptr, byte* endPtr, uint value)
+ {
+ Debug.Assert(0 <= value && value < 16);
+ Debug.Assert(ptr < endPtr);
+
+ if (*ptr != 0)
+ *ptr++ |= (byte)value;
+ else
+ *ptr = (byte)(value << 4);
+ }
+
+ #endregion // CreateGuidForActivityPath
+
+ readonly internal string m_name; // The name used in the 'start' and 'stop' APIs to help match up
+ readonly long m_uniqueId; // a small number that makes this activity unique among its siblings
+ internal readonly Guid m_guid; // Activity Guid, it is basically an encoding of the Path() (see CreateActivityPathGuid)
+ internal readonly int m_activityPathGuidOffset; // Keeps track of where in m_guid the causality path stops (used to generated child GUIDs)
+ internal readonly int m_level; // current depth of the Path() of the activity (used to keep recursion under control)
+ readonly internal EventActivityOptions m_eventOptions; // Options passed to start.
+ internal long m_lastChildID; // used to create a unique ID for my children activities
+ internal int m_stopped; // This work item has stopped
+ readonly internal ActivityInfo m_creator; // My parent (creator). Forms the Path() for the activity.
+ readonly internal Guid m_activityIdToRestore; // The Guid to restore after a stop.
+ #endregion
+ }
+
+ // This callback is used to initialize the m_current AsyncLocal Variable.
+ // Its job is to keep the ETW Activity ID (part of thread local storage) in sync
+ // with m_current.ActivityID
+ void ActivityChanging(AsyncLocalValueChangedArgs<ActivityInfo> args)
+ {
+ ActivityInfo cur = args.CurrentValue;
+ ActivityInfo prev = args.PreviousValue;
+
+ // Are we popping off a value? (we have a prev, and it creator is cur)
+ // Then check if we should use the GUID at the time of the start event
+ if (prev != null && prev.m_creator == cur)
+ {
+ // If the saved activity ID is not the same as the creator activity
+ // that takes precedence (it means someone explicitly did a SetActivityID)
+ // Set it to that and get out
+ if (cur == null || prev.m_activityIdToRestore != cur.ActivityId)
+ {
+ EventSource.SetCurrentThreadActivityId(prev.m_activityIdToRestore);
+ return;
+ }
+ }
+
+ // OK we did not have an explicit SetActivityID set. Then we should be
+ // setting the activity to current ActivityInfo. However that activity
+ // might be dead, in which case we should skip it, so we never set
+ // the ID to dead things.
+ while (cur != null)
+ {
+ // We found a live activity (typically the first time), set it to that.
+ if (cur.m_stopped == 0)
+ {
+ EventSource.SetCurrentThreadActivityId(cur.ActivityId);
+ return;
+ }
+ cur = cur.m_creator;
+ }
+ // we can get here if there is no information on our activity stack (everything is dead)
+ // currently we do nothing, as that seems better than setting to Guid.Emtpy.
+ }
+
+ /// <summary>
+ /// Async local variables have the property that the are automatically copied whenever a task is created and used
+ /// while that task is running. Thus m_current 'flows' to any task that is caused by the current thread that
+ /// last set it.
+ ///
+ /// This variable points a a linked list that represents all Activities that have started but have not stopped.
+ /// </summary>
+ AsyncLocal<ActivityInfo> m_current;
+ bool m_checkedForEnable;
+
+ // Singleton
+ private static ActivityTracker s_activityTrackerInstance = new ActivityTracker();
+
+ // Used to create unique IDs at the top level. Not used for nested Ids (each activity has its own id generator)
+ static long m_nextId = 0;
+ private const ushort MAX_ACTIVITY_DEPTH = 100; // Limit maximum depth of activities to be tracked at 100.
+ // This will avoid leaking memory in case of activities that are never stopped.
+
+ #endregion
+ }
+
+#if ES_BUILD_STANDALONE || ES_BUILD_PN
+ /******************************** SUPPORT *****************************/
+ /// <summary>
+ /// This is supplied by the framework. It is has the semantics that the value is copied to any new Tasks that is created
+ /// by the current task. Thus all causally related code gets this value. Note that reads and writes to this VARIABLE
+ /// (not what it points it) to this does not need to be protected by locks because it is inherently thread local (you always
+ /// only get your thread local copy which means that you never have races.
+ /// </summary>
+ ///
+#if ES_BUILD_STANDALONE
+ [EventSource(Name = "Microsoft.Tasks.Nuget")]
+#else
+ [EventSource(Name = "System.Diagnostics.Tracing.TplEtwProvider")]
+#endif
+ internal class TplEtwProvider : EventSource
+ {
+ public class Keywords
+ {
+ public const EventKeywords TasksFlowActivityIds = (EventKeywords)0x80;
+ public const EventKeywords Debug = (EventKeywords)0x20000;
+ }
+
+ public static TplEtwProvider Log = new TplEtwProvider();
+ public bool Debug { get { return IsEnabled(EventLevel.Verbose, Keywords.Debug); } }
+
+ public void DebugFacilityMessage(string Facility, string Message) { WriteEvent(1, Facility, Message); }
+ public void DebugFacilityMessage1(string Facility, string Message, string Arg) { WriteEvent(2, Facility, Message, Arg); }
+ public void SetActivityId(Guid Id) { WriteEvent(3, Id); }
+ }
+#endif
+
+#if ES_BUILD_AGAINST_DOTNET_V35 || ES_BUILD_PCL || NO_ASYNC_LOCAL
+ // In these cases we don't have any Async local support. Do nothing.
+ internal sealed class AsyncLocalValueChangedArgs<T>
+ {
+ public T PreviousValue { get { return default(T); } }
+ public T CurrentValue { get { return default(T); } }
+
+ }
+
+ internal sealed class AsyncLocal<T>
+ {
+ public AsyncLocal(Action<AsyncLocalValueChangedArgs<T>> valueChangedHandler) {
+ throw new NotImplementedException("AsyncLocal only available on V4.6 and above");
+ }
+ public T Value
+ {
+ get { return default(T); }
+ set { }
+ }
+ }
+#endif
+
+}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventActivityOptions.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/EventActivityOptions.cs
index 782afbf869..782afbf869 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventActivityOptions.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/EventActivityOptions.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventCounter.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/EventCounter.cs
index b1f946464e..b1f946464e 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventCounter.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/EventCounter.cs
diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/EventDescriptor.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/EventDescriptor.cs
new file mode 100644
index 0000000000..8fb471a99f
--- /dev/null
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/EventDescriptor.cs
@@ -0,0 +1,209 @@
+// 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.InteropServices;
+
+#if ES_BUILD_STANDALONE
+using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment;
+#endif
+
+#if !ES_BUILD_AGAINST_DOTNET_V35
+using Contract = System.Diagnostics.Contracts.Contract;
+#else
+using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract;
+#endif
+
+#if ES_BUILD_STANDALONE
+namespace Microsoft.Diagnostics.Tracing
+#else
+namespace System.Diagnostics.Tracing
+#endif
+{
+ [StructLayout(LayoutKind.Explicit, Size = 16)]
+#if !CORECLR && !ES_BUILD_PN
+ [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
+#endif // !CORECLR && !ES_BUILD_PN
+
+ /*
+ EventDescriptor was public in the separate System.Diagnostics.Tracing assembly(pre NS2.0),
+ now the move to CoreLib marked them as private.
+ While they are technically private (it's a contract used between the library and the ILC toolchain),
+ we need them to be rooted and exported from shared library for the system to work.
+ For now I'm simply marking them as public again.A cleaner solution might be to use.rd.xml to
+ root them and modify shared library definition to force export them.
+ */
+#if ES_BUILD_PN
+ public
+#else
+ internal
+#endif
+ struct EventDescriptor
+ {
+ # region private
+ [FieldOffset(0)]
+ private int m_traceloggingId;
+ [FieldOffset(0)]
+ private ushort m_id;
+ [FieldOffset(2)]
+ private byte m_version;
+ [FieldOffset(3)]
+ private byte m_channel;
+ [FieldOffset(4)]
+ private byte m_level;
+ [FieldOffset(5)]
+ private byte m_opcode;
+ [FieldOffset(6)]
+ private ushort m_task;
+ [FieldOffset(8)]
+ private long m_keywords;
+ #endregion
+
+ public EventDescriptor(
+ int traceloggingId,
+ byte level,
+ byte opcode,
+ long keywords
+ )
+ {
+ this.m_id = 0;
+ this.m_version = 0;
+ this.m_channel = 0;
+ this.m_traceloggingId = traceloggingId;
+ this.m_level = level;
+ this.m_opcode = opcode;
+ this.m_task = 0;
+ this.m_keywords = keywords;
+ }
+
+ public EventDescriptor(
+ int id,
+ byte version,
+ byte channel,
+ byte level,
+ byte opcode,
+ int task,
+ long keywords
+ )
+ {
+ if (id < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(id), Resources.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ }
+
+ if (id > ushort.MaxValue)
+ {
+ throw new ArgumentOutOfRangeException(nameof(id), Resources.GetResourceString("ArgumentOutOfRange_NeedValidId", 1, ushort.MaxValue));
+ }
+
+ m_traceloggingId = 0;
+ m_id = (ushort)id;
+ m_version = version;
+ m_channel = channel;
+ m_level = level;
+ m_opcode = opcode;
+ m_keywords = keywords;
+
+ if (task < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(task), Resources.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ }
+
+ if (task > ushort.MaxValue)
+ {
+ throw new ArgumentOutOfRangeException(nameof(task), Resources.GetResourceString("ArgumentOutOfRange_NeedValidId", 1, ushort.MaxValue));
+ }
+
+ m_task = (ushort)task;
+ }
+
+ public int EventId
+ {
+ get
+ {
+ return m_id;
+ }
+ }
+ public byte Version
+ {
+ get
+ {
+ return m_version;
+ }
+ }
+ public byte Channel
+ {
+ get
+ {
+ return m_channel;
+ }
+ }
+ public byte Level
+ {
+ get
+ {
+ return m_level;
+ }
+ }
+ public byte Opcode
+ {
+ get
+ {
+ return m_opcode;
+ }
+ }
+ public int Task
+ {
+ get
+ {
+ return m_task;
+ }
+ }
+ public long Keywords
+ {
+ get
+ {
+ return m_keywords;
+ }
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (!(obj is EventDescriptor))
+ return false;
+
+ return Equals((EventDescriptor) obj);
+ }
+
+ public override int GetHashCode()
+ {
+ return m_id ^ m_version ^ m_channel ^ m_level ^ m_opcode ^ m_task ^ (int)m_keywords;
+ }
+
+ public bool Equals(EventDescriptor other)
+ {
+ if ((m_id != other.m_id) ||
+ (m_version != other.m_version) ||
+ (m_channel != other.m_channel) ||
+ (m_level != other.m_level) ||
+ (m_opcode != other.m_opcode) ||
+ (m_task != other.m_task) ||
+ (m_keywords != other.m_keywords))
+ {
+ return false;
+ }
+ return true;
+ }
+
+ public static bool operator ==(EventDescriptor event1, EventDescriptor event2)
+ {
+ return event1.Equals(event2);
+ }
+
+ public static bool operator !=(EventDescriptor event1, EventDescriptor event2)
+ {
+ return !event1.Equals(event2);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/EventProvider.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/EventProvider.cs
new file mode 100644
index 0000000000..57d550dc8c
--- /dev/null
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/EventProvider.cs
@@ -0,0 +1,1207 @@
+// 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 Microsoft.Win32;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Security;
+#if !CORECLR && !ES_BUILD_PN
+using System.Security.Permissions;
+#endif // !CORECLR && !ES_BUILD_PN
+using System.Threading;
+using System;
+
+#if !ES_BUILD_AGAINST_DOTNET_V35
+using Contract = System.Diagnostics.Contracts.Contract;
+#else
+using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract;
+#endif
+
+#if ES_BUILD_AGAINST_DOTNET_V35
+using Microsoft.Internal; // for Tuple (can't define alias for open generic types so we "use" the whole namespace)
+#endif
+
+#if ES_BUILD_STANDALONE
+namespace Microsoft.Diagnostics.Tracing
+#else
+namespace System.Diagnostics.Tracing
+#endif
+{
+ // New in CLR4.0
+ internal enum ControllerCommand
+ {
+ // Strictly Positive numbers are for provider-specific commands, negative number are for 'shared' commands. 256
+ // The first 256 negative numbers are reserved for the framework.
+ Update = 0, // Not used by EventPrividerBase.
+ SendManifest = -1,
+ Enable = -2,
+ Disable = -3,
+ };
+
+ /// <summary>
+ /// Only here because System.Diagnostics.EventProvider needs one more extensibility hook (when it gets a
+ /// controller callback)
+ /// </summary>
+#if !CORECLR && !ES_BUILD_PN
+ [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
+#endif // !CORECLR && !ES_BUILD_PN
+ internal partial class EventProvider : IDisposable
+ {
+ // This is the windows EVENT_DATA_DESCRIPTOR structure. We expose it because this is what
+ // subclasses of EventProvider use when creating efficient (but unsafe) version of
+ // EventWrite. We do make it a nested type because we really don't expect anyone to use
+ // it except subclasses (and then only rarely).
+ public struct EventData
+ {
+ internal unsafe ulong Ptr;
+ internal uint Size;
+ internal uint Reserved;
+ }
+
+ /// <summary>
+ /// A struct characterizing ETW sessions (identified by the etwSessionId) as
+ /// activity-tracing-aware or legacy. A session that's activity-tracing-aware
+ /// has specified one non-zero bit in the reserved range 44-47 in the
+ /// 'allKeywords' value it passed in for a specific EventProvider.
+ /// </summary>
+ public struct SessionInfo
+ {
+ internal int sessionIdBit; // the index of the bit used for tracing in the "reserved" field of AllKeywords
+ internal int etwSessionId; // the machine-wide ETW session ID
+
+ internal SessionInfo(int sessionIdBit_, int etwSessionId_)
+ { sessionIdBit = sessionIdBit_; etwSessionId = etwSessionId_; }
+ }
+
+ private static bool m_setInformationMissing;
+
+ UnsafeNativeMethods.ManifestEtw.EtwEnableCallback m_etwCallback; // Trace Callback function
+ private long m_regHandle; // Trace Registration Handle
+ private byte m_level; // Tracing Level
+ private long m_anyKeywordMask; // Trace Enable Flags
+ private long m_allKeywordMask; // Match all keyword
+ private List<SessionInfo> m_liveSessions; // current live sessions (Tuple<sessionIdBit, etwSessionId>)
+ private bool m_enabled; // Enabled flag from Trace callback
+ private Guid m_providerId; // Control Guid
+ internal bool m_disposed; // when true provider has unregistered
+
+ [ThreadStatic]
+ private static WriteEventErrorCode s_returnCode; // The last return code
+
+ private const int s_basicTypeAllocationBufferSize = 16;
+ private const int s_etwMaxNumberArguments = 128;
+ private const int s_etwAPIMaxRefObjCount = 8;
+ private const int s_maxEventDataDescriptors = 128;
+ private const int s_traceEventMaximumSize = 65482;
+ private const int s_traceEventMaximumStringSize = 32724;
+
+ [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
+ public enum WriteEventErrorCode : int
+ {
+ //check mapping to runtime codes
+ NoError = 0,
+ NoFreeBuffers = 1,
+ EventTooBig = 2,
+ NullInput = 3,
+ TooManyArgs = 4,
+ Other = 5,
+ };
+
+ // Because callbacks happen on registration, and we need the callbacks for those setup
+ // we can't call Register in the constructor.
+ //
+ // Note that EventProvider should ONLY be used by EventSource. In particular because
+ // it registers a callback from native code you MUST dispose it BEFORE shutdown, otherwise
+ // you may get native callbacks during shutdown when we have destroyed the delegate.
+ // EventSource has special logic to do this, no one else should be calling EventProvider.
+ internal EventProvider()
+ {
+ }
+
+ /// <summary>
+ /// This method registers the controlGuid of this class with ETW. We need to be running on
+ /// Vista or above. If not a PlatformNotSupported exception will be thrown. If for some
+ /// reason the ETW Register call failed a NotSupported exception will be thrown.
+ /// </summary>
+ // <SecurityKernel Critical="True" Ring="0">
+ // <CallsSuppressUnmanagedCode Name="UnsafeNativeMethods.ManifestEtw.EventRegister(System.Guid&,Microsoft.Win32.UnsafeNativeMethods.ManifestEtw+EtwEnableCallback,System.Void*,System.Int64&):System.UInt32" />
+ // <SatisfiesLinkDemand Name="Win32Exception..ctor(System.Int32)" />
+ // <ReferencesCritical Name="Method: EtwEnableCallBack(Guid&, Int32, Byte, Int64, Int64, Void*, Void*):Void" Ring="1" />
+ // </SecurityKernel>
+ internal unsafe void Register(Guid providerGuid)
+ {
+ m_providerId = providerGuid;
+ uint status;
+ m_etwCallback = new UnsafeNativeMethods.ManifestEtw.EtwEnableCallback(EtwEnableCallBack);
+
+ status = EventRegister(ref m_providerId, m_etwCallback);
+ if (status != 0)
+ {
+ throw new ArgumentException(Win32Native.GetMessage(unchecked((int)status)));
+ }
+ }
+
+ //
+ // implement Dispose Pattern to early deregister from ETW insted of waiting for
+ // the finalizer to call deregistration.
+ // Once the user is done with the provider it needs to call Close() or Dispose()
+ // If neither are called the finalizer will unregister the provider anyway
+ //
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ // <SecurityKernel Critical="True" TreatAsSafe="Does not expose critical resource" Ring="1">
+ // <ReferencesCritical Name="Method: Deregister():Void" Ring="1" />
+ // </SecurityKernel>
+ protected virtual void Dispose(bool disposing)
+ {
+ //
+ // explicit cleanup is done by calling Dispose with true from
+ // Dispose() or Close(). The disposing arguement is ignored because there
+ // are no unmanaged resources.
+ // The finalizer calls Dispose with false.
+ //
+
+ //
+ // check if the object has been allready disposed
+ //
+ if (m_disposed) return;
+
+ // Disable the provider.
+ m_enabled = false;
+
+ // Do most of the work under a lock to avoid shutdown race.
+
+ long registrationHandle = 0;
+ lock (EventListener.EventListenersLock)
+ {
+ // Double check
+ if (m_disposed)
+ return;
+
+ registrationHandle = m_regHandle;
+ m_regHandle = 0;
+ m_disposed = true;
+ }
+
+ // We do the Unregistration outside the EventListenerLock because there is a lock
+ // inside the ETW routines. This lock is taken before ETW issues commands
+ // Thus the ETW lock gets taken first and then our EventListenersLock gets taken
+ // in SendCommand(), and also here. If we called EventUnregister after taking
+ // the EventListenersLock then the take-lock order is reversed and we can have
+ // deadlocks in race conditions (dispose racing with an ETW command).
+ //
+ // We solve by Unregistering after releasing the EventListenerLock.
+ if (registrationHandle != 0)
+ EventUnregister(registrationHandle);
+
+ }
+
+ /// <summary>
+ /// This method deregisters the controlGuid of this class with ETW.
+ ///
+ /// </summary>
+ public virtual void Close()
+ {
+ Dispose();
+ }
+
+ ~EventProvider()
+ {
+ Dispose(false);
+ }
+
+ // <SecurityKernel Critical="True" Ring="0">
+ // <UsesUnsafeCode Name="Parameter filterData of type: Void*" />
+ // <UsesUnsafeCode Name="Parameter callbackContext of type: Void*" />
+ // </SecurityKernel>
+ unsafe void EtwEnableCallBack(
+ [In] ref System.Guid sourceId,
+ [In] int controlCode,
+ [In] byte setLevel,
+ [In] long anyKeyword,
+ [In] long allKeyword,
+ [In] UnsafeNativeMethods.ManifestEtw.EVENT_FILTER_DESCRIPTOR* filterData,
+ [In] void* callbackContext
+ )
+ {
+ // This is an optional callback API. We will therefore ignore any failures that happen as a
+ // result of turning on this provider as to not crash the app.
+ // EventSource has code to validate whether initialization it expected to occur actually occurred
+ try
+ {
+ ControllerCommand command = ControllerCommand.Update;
+ IDictionary<string, string> args = null;
+ bool skipFinalOnControllerCommand = false;
+ if (controlCode == UnsafeNativeMethods.ManifestEtw.EVENT_CONTROL_CODE_ENABLE_PROVIDER)
+ {
+ m_enabled = true;
+ m_level = setLevel;
+ m_anyKeywordMask = anyKeyword;
+ m_allKeywordMask = allKeyword;
+
+ // ES_SESSION_INFO is a marker for additional places we #ifdeffed out to remove
+ // references to EnumerateTraceGuidsEx. This symbol is actually not used because
+ // today we use FEATURE_ACTIVITYSAMPLING to determine if this code is there or not.
+ // However we put it in the #if so that we don't lose the fact that this feature
+ // switch is at least partially independent of FEATURE_ACTIVITYSAMPLING
+
+ List<Tuple<SessionInfo, bool>> sessionsChanged = GetSessions();
+ foreach (var session in sessionsChanged)
+ {
+ int sessionChanged = session.Item1.sessionIdBit;
+ int etwSessionId = session.Item1.etwSessionId;
+ bool bEnabling = session.Item2;
+
+ skipFinalOnControllerCommand = true;
+ args = null; // reinitialize args for every session...
+
+ // if we get more than one session changed we have no way
+ // of knowing which one "filterData" belongs to
+ if (sessionsChanged.Count > 1)
+ filterData = null;
+
+ // read filter data only when a session is being *added*
+ byte[] data;
+ int keyIndex;
+ if (bEnabling &&
+ GetDataFromController(etwSessionId, filterData, out command, out data, out keyIndex))
+ {
+ args = new Dictionary<string, string>(4);
+ while (keyIndex < data.Length)
+ {
+ int keyEnd = FindNull(data, keyIndex);
+ int valueIdx = keyEnd + 1;
+ int valueEnd = FindNull(data, valueIdx);
+ if (valueEnd < data.Length)
+ {
+ string key = System.Text.Encoding.UTF8.GetString(data, keyIndex, keyEnd - keyIndex);
+ string value = System.Text.Encoding.UTF8.GetString(data, valueIdx, valueEnd - valueIdx);
+ args[key] = value;
+ }
+ keyIndex = valueEnd + 1;
+ }
+ }
+
+ // execute OnControllerCommand once for every session that has changed.
+ OnControllerCommand(command, args, (bEnabling ? sessionChanged : -sessionChanged), etwSessionId);
+ }
+ }
+ else if (controlCode == UnsafeNativeMethods.ManifestEtw.EVENT_CONTROL_CODE_DISABLE_PROVIDER)
+ {
+ m_enabled = false;
+ m_level = 0;
+ m_anyKeywordMask = 0;
+ m_allKeywordMask = 0;
+ m_liveSessions = null;
+ }
+ else if (controlCode == UnsafeNativeMethods.ManifestEtw.EVENT_CONTROL_CODE_CAPTURE_STATE)
+ {
+ command = ControllerCommand.SendManifest;
+ }
+ else
+ return; // per spec you ignore commands you don't recognize.
+
+ if (!skipFinalOnControllerCommand)
+ OnControllerCommand(command, args, 0, 0);
+ }
+ catch (Exception)
+ {
+ // We want to ignore any failures that happen as a result of turning on this provider as to
+ // not crash the app.
+ }
+ }
+
+ // New in CLR4.0
+ protected virtual void OnControllerCommand(ControllerCommand command, IDictionary<string, string> arguments, int sessionId, int etwSessionId) { }
+ protected EventLevel Level { get { return (EventLevel)m_level; } set { m_level = (byte)value; } }
+ protected EventKeywords MatchAnyKeyword { get { return (EventKeywords)m_anyKeywordMask; } set { m_anyKeywordMask = unchecked((long)value); } }
+ protected EventKeywords MatchAllKeyword { get { return (EventKeywords)m_allKeywordMask; } set { m_allKeywordMask = unchecked((long)value); } }
+
+ static private int FindNull(byte[] buffer, int idx)
+ {
+ while (idx < buffer.Length && buffer[idx] != 0)
+ idx++;
+ return idx;
+ }
+
+ /// <summary>
+ /// Determines the ETW sessions that have been added and/or removed to the set of
+ /// sessions interested in the current provider. It does so by (1) enumerating over all
+ /// ETW sessions that enabled 'this.m_Guid' for the current process ID, and (2)
+ /// comparing the current list with a list it cached on the previous invocation.
+ ///
+ /// The return value is a list of tuples, where the SessionInfo specifies the
+ /// ETW session that was added or remove, and the bool specifies whether the
+ /// session was added or whether it was removed from the set.
+ /// </summary>
+ private List<Tuple<SessionInfo, bool>> GetSessions()
+ {
+ List<SessionInfo> liveSessionList = null;
+
+ GetSessionInfo(
+ (int etwSessionId, long matchAllKeywords, ref List<SessionInfo> sessionList) =>
+ GetSessionInfoCallback(etwSessionId, matchAllKeywords, ref sessionList),
+ ref liveSessionList);
+
+ List<Tuple<SessionInfo, bool>> changedSessionList = new List<Tuple<SessionInfo, bool>>();
+
+ // first look for sessions that have gone away (or have changed)
+ // (present in the m_liveSessions but not in the new liveSessionList)
+ if (m_liveSessions != null)
+ {
+ foreach (SessionInfo s in m_liveSessions)
+ {
+ int idx;
+ if ((idx = IndexOfSessionInList(liveSessionList, s.etwSessionId)) < 0 ||
+ (liveSessionList[idx].sessionIdBit != s.sessionIdBit))
+ changedSessionList.Add(Tuple.Create(s, false));
+
+ }
+ }
+ // next look for sessions that were created since the last callback (or have changed)
+ // (present in the new liveSessionList but not in m_liveSessions)
+ if (liveSessionList != null)
+ {
+ foreach (SessionInfo s in liveSessionList)
+ {
+ int idx;
+ if ((idx = IndexOfSessionInList(m_liveSessions, s.etwSessionId)) < 0 ||
+ (m_liveSessions[idx].sessionIdBit != s.sessionIdBit))
+ changedSessionList.Add(Tuple.Create(s, true));
+ }
+ }
+
+ m_liveSessions = liveSessionList;
+ return changedSessionList;
+ }
+
+
+ /// <summary>
+ /// This method is the callback used by GetSessions() when it calls into GetSessionInfo().
+ /// It updates a List{SessionInfo} based on the etwSessionId and matchAllKeywords that
+ /// GetSessionInfo() passes in.
+ /// </summary>
+ private static void GetSessionInfoCallback(int etwSessionId, long matchAllKeywords,
+ ref List<SessionInfo> sessionList)
+ {
+ uint sessionIdBitMask = (uint)SessionMask.FromEventKeywords(unchecked((ulong)matchAllKeywords));
+ // an ETW controller that specifies more than the mandated bit for our EventSource
+ // will be ignored...
+ if (bitcount(sessionIdBitMask) > 1)
+ return;
+
+ if (sessionList == null)
+ sessionList = new List<SessionInfo>(8);
+
+ if (bitcount(sessionIdBitMask) == 1)
+ {
+ // activity-tracing-aware etw session
+ sessionList.Add(new SessionInfo(bitindex(sessionIdBitMask) + 1, etwSessionId));
+ }
+ else
+ {
+ // legacy etw session
+ sessionList.Add(new SessionInfo(bitcount((uint)SessionMask.All) + 1, etwSessionId));
+ }
+ }
+
+ private delegate void SessionInfoCallback(int etwSessionId, long matchAllKeywords, ref List<SessionInfo> sessionList);
+
+ /// <summary>
+ /// This method enumerates over all active ETW sessions that have enabled 'this.m_Guid'
+ /// for the current process ID, calling 'action' for each session, and passing it the
+ /// ETW session and the 'AllKeywords' the session enabled for the current provider.
+ /// </summary>
+ private unsafe void GetSessionInfo(SessionInfoCallback action, ref List<SessionInfo> sessionList)
+ {
+ // We wish the EventSource package to be legal for Windows Store applications.
+ // Currently EnumerateTraceGuidsEx is not an allowed API, so we avoid its use here
+ // and use the information in the registry instead. This means that ETW controllers
+ // that do not publish their intent to the registry (basically all controllers EXCEPT
+ // TraceEventSesion) will not work properly
+
+ // However the framework version of EventSource DOES have ES_SESSION_INFO defined and thus
+ // does not have this issue.
+#if ES_SESSION_INFO || !ES_BUILD_STANDALONE
+ int buffSize = 256; // An initial guess that probably works most of the time.
+ byte* buffer;
+ for (; ; )
+ {
+ var space = stackalloc byte[buffSize];
+ buffer = space;
+ var hr = 0;
+
+ fixed (Guid* provider = &m_providerId)
+ {
+ hr = UnsafeNativeMethods.ManifestEtw.EnumerateTraceGuidsEx(UnsafeNativeMethods.ManifestEtw.TRACE_QUERY_INFO_CLASS.TraceGuidQueryInfo,
+ provider, sizeof(Guid), buffer, buffSize, ref buffSize);
+ }
+ if (hr == 0)
+ break;
+ if (hr != 122 /* ERROR_INSUFFICIENT_BUFFER */)
+ return;
+ }
+
+ var providerInfos = (UnsafeNativeMethods.ManifestEtw.TRACE_GUID_INFO*)buffer;
+ var providerInstance = (UnsafeNativeMethods.ManifestEtw.TRACE_PROVIDER_INSTANCE_INFO*)&providerInfos[1];
+ int processId = unchecked((int)Win32Native.GetCurrentProcessId());
+ // iterate over the instances of the EventProvider in all processes
+ for (int i = 0; i < providerInfos->InstanceCount; i++)
+ {
+ if (providerInstance->Pid == processId)
+ {
+ var enabledInfos = (UnsafeNativeMethods.ManifestEtw.TRACE_ENABLE_INFO*)&providerInstance[1];
+ // iterate over the list of active ETW sessions "listening" to the current provider
+ for (int j = 0; j < providerInstance->EnableCount; j++)
+ action(enabledInfos[j].LoggerId, enabledInfos[j].MatchAllKeyword, ref sessionList);
+ }
+ if (providerInstance->NextOffset == 0)
+ break;
+ Debug.Assert(0 <= providerInstance->NextOffset && providerInstance->NextOffset < buffSize);
+ var structBase = (byte*)providerInstance;
+ providerInstance = (UnsafeNativeMethods.ManifestEtw.TRACE_PROVIDER_INSTANCE_INFO*)&structBase[providerInstance->NextOffset];
+ }
+#else
+#if !ES_BUILD_PCL && !FEATURE_PAL // TODO command arguments don't work on PCL builds...
+ // This code is only used in the Nuget Package Version of EventSource. because
+ // the code above is using APIs baned from UWP apps.
+ //
+ // TODO: In addition to only working when TraceEventSession enables the provider, this code
+ // also has a problem because TraceEvent does not clean up if the registry is stale
+ // It is unclear if it is worth keeping, but for now we leave it as it does work
+ // at least some of the time.
+
+ // Determine our session from what is in the registry.
+ string regKey = @"\Microsoft\Windows\CurrentVersion\Winevt\Publishers\{" + m_providerId + "}";
+ if (System.Runtime.InteropServices.Marshal.SizeOf(typeof(IntPtr)) == 8)
+ regKey = @"Software" + @"\Wow6432Node" + regKey;
+ else
+ regKey = @"Software" + regKey;
+
+ var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regKey);
+ if (key != null)
+ {
+ foreach (string valueName in key.GetValueNames())
+ {
+ if (valueName.StartsWith("ControllerData_Session_", StringComparison.Ordinal))
+ {
+ string strId = valueName.Substring(23); // strip of the ControllerData_Session_
+ int etwSessionId;
+ if (int.TryParse(strId, out etwSessionId))
+ {
+ // we need to assert this permission for partial trust scenarios
+ (new RegistryPermission(RegistryPermissionAccess.Read, regKey)).Assert();
+ var data = key.GetValue(valueName) as byte[];
+ if (data != null)
+ {
+ var dataAsString = System.Text.Encoding.UTF8.GetString(data);
+ int keywordIdx = dataAsString.IndexOf("EtwSessionKeyword", StringComparison.Ordinal);
+ if (0 <= keywordIdx)
+ {
+ int startIdx = keywordIdx + 18;
+ int endIdx = dataAsString.IndexOf('\0', startIdx);
+ string keywordBitString = dataAsString.Substring(startIdx, endIdx-startIdx);
+ int keywordBit;
+ if (0 < endIdx && int.TryParse(keywordBitString, out keywordBit))
+ action(etwSessionId, 1L << keywordBit, ref sessionList);
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+#endif
+ }
+
+ /// <summary>
+ /// Returns the index of the SesisonInfo from 'sessions' that has the specified 'etwSessionId'
+ /// or -1 if the value is not present.
+ /// </summary>
+ private static int IndexOfSessionInList(List<SessionInfo> sessions, int etwSessionId)
+ {
+ if (sessions == null)
+ return -1;
+ // for non-coreclr code we could use List<T>.FindIndex(Predicate<T>), but we need this to compile
+ // on coreclr as well
+ for (int i = 0; i < sessions.Count; ++i)
+ if (sessions[i].etwSessionId == etwSessionId)
+ return i;
+
+ return -1;
+ }
+
+ /// <summary>
+ /// Gets any data to be passed from the controller to the provider. It starts with what is passed
+ /// into the callback, but unfortunately this data is only present for when the provider is active
+ /// at the time the controller issues the command. To allow for providers to activate after the
+ /// controller issued a command, we also check the registry and use that to get the data. The function
+ /// returns an array of bytes representing the data, the index into that byte array where the data
+ /// starts, and the command being issued associated with that data.
+ /// </summary>
+ private unsafe bool GetDataFromController(int etwSessionId,
+ UnsafeNativeMethods.ManifestEtw.EVENT_FILTER_DESCRIPTOR* filterData, out ControllerCommand command, out byte[] data, out int dataStart)
+ {
+ data = null;
+ dataStart = 0;
+ if (filterData == null)
+ {
+#if (!ES_BUILD_PCL && !ES_BUILD_PN && !FEATURE_PAL)
+ string regKey = @"\Microsoft\Windows\CurrentVersion\Winevt\Publishers\{" + m_providerId + "}";
+ if (Marshal.SizeOf(typeof(IntPtr)) == 8)
+ regKey = @"Software" + @"\Wow6432Node" + regKey;
+ else
+ regKey = @"Software" + regKey;
+
+ string valueName = "ControllerData_Session_" + etwSessionId.ToString(CultureInfo.InvariantCulture);
+
+ using (RegistryKey key = Registry.LocalMachine.OpenSubKey(regKey, writable: false))
+ {
+ data = key.GetValue(valueName) as byte[];
+ }
+
+ if (data != null)
+ {
+ // We only used the persisted data from the registry for updates.
+ command = ControllerCommand.Update;
+ return true;
+ }
+#endif
+ }
+ else
+ {
+ if (filterData->Ptr != 0 && 0 < filterData->Size && filterData->Size <= 1024)
+ {
+ data = new byte[filterData->Size];
+ Marshal.Copy((IntPtr)filterData->Ptr, data, 0, data.Length);
+ }
+ command = (ControllerCommand)filterData->Type;
+ return true;
+ }
+
+ command = ControllerCommand.Update;
+ return false;
+ }
+
+ /// <summary>
+ /// IsEnabled, method used to test if provider is enabled
+ /// </summary>
+ public bool IsEnabled()
+ {
+ return m_enabled;
+ }
+
+ /// <summary>
+ /// IsEnabled, method used to test if event is enabled
+ /// </summary>
+ /// <param name="level">
+ /// Level to test
+ /// </param>
+ /// <param name="keywords">
+ /// Keyword to test
+ /// </param>
+ public bool IsEnabled(byte level, long keywords)
+ {
+ //
+ // If not enabled at all, return false.
+ //
+ if (!m_enabled)
+ {
+ return false;
+ }
+
+ // This also covers the case of Level == 0.
+ if ((level <= m_level) ||
+ (m_level == 0))
+ {
+
+ //
+ // Check if Keyword is enabled
+ //
+
+ if ((keywords == 0) ||
+ (((keywords & m_anyKeywordMask) != 0) &&
+ ((keywords & m_allKeywordMask) == m_allKeywordMask)))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
+ public static WriteEventErrorCode GetLastWriteEventError()
+ {
+ return s_returnCode;
+ }
+
+ //
+ // Helper function to set the last error on the thread
+ //
+ private static void SetLastError(int error)
+ {
+ switch (error)
+ {
+ case UnsafeNativeMethods.ManifestEtw.ERROR_ARITHMETIC_OVERFLOW:
+ case UnsafeNativeMethods.ManifestEtw.ERROR_MORE_DATA:
+ s_returnCode = WriteEventErrorCode.EventTooBig;
+ break;
+ case UnsafeNativeMethods.ManifestEtw.ERROR_NOT_ENOUGH_MEMORY:
+ s_returnCode = WriteEventErrorCode.NoFreeBuffers;
+ break;
+ }
+ }
+
+ // <SecurityKernel Critical="True" Ring="0">
+ // <UsesUnsafeCode Name="Local intptrPtr of type: IntPtr*" />
+ // <UsesUnsafeCode Name="Local intptrPtr of type: Int32*" />
+ // <UsesUnsafeCode Name="Local longptr of type: Int64*" />
+ // <UsesUnsafeCode Name="Local uintptr of type: UInt32*" />
+ // <UsesUnsafeCode Name="Local ulongptr of type: UInt64*" />
+ // <UsesUnsafeCode Name="Local charptr of type: Char*" />
+ // <UsesUnsafeCode Name="Local byteptr of type: Byte*" />
+ // <UsesUnsafeCode Name="Local shortptr of type: Int16*" />
+ // <UsesUnsafeCode Name="Local sbyteptr of type: SByte*" />
+ // <UsesUnsafeCode Name="Local ushortptr of type: UInt16*" />
+ // <UsesUnsafeCode Name="Local floatptr of type: Single*" />
+ // <UsesUnsafeCode Name="Local doubleptr of type: Double*" />
+ // <UsesUnsafeCode Name="Local boolptr of type: Boolean*" />
+ // <UsesUnsafeCode Name="Local guidptr of type: Guid*" />
+ // <UsesUnsafeCode Name="Local decimalptr of type: Decimal*" />
+ // <UsesUnsafeCode Name="Local booleanptr of type: Boolean*" />
+ // <UsesUnsafeCode Name="Parameter dataDescriptor of type: EventData*" />
+ // <UsesUnsafeCode Name="Parameter dataBuffer of type: Byte*" />
+ // </SecurityKernel>
+ private static unsafe object EncodeObject(ref object data, ref EventData* dataDescriptor, ref byte* dataBuffer, ref uint totalEventSize)
+ /*++
+
+ Routine Description:
+
+ This routine is used by WriteEvent to unbox the object type and
+ to fill the passed in ETW data descriptor.
+
+ Arguments:
+
+ data - argument to be decoded
+
+ dataDescriptor - pointer to the descriptor to be filled (updated to point to the next empty entry)
+
+ dataBuffer - storage buffer for storing user data, needed because cant get the address of the object
+ (updated to point to the next empty entry)
+
+ Return Value:
+
+ null if the object is a basic type other than string or byte[]. String otherwise
+
+ --*/
+ {
+ Again:
+ dataDescriptor->Reserved = 0;
+
+ string sRet = data as string;
+ byte[] blobRet = null;
+
+ if (sRet != null)
+ {
+ dataDescriptor->Size = ((uint)sRet.Length + 1) * 2;
+ }
+ else if ((blobRet = data as byte[]) != null)
+ {
+ // first store array length
+ *(int*)dataBuffer = blobRet.Length;
+ dataDescriptor->Ptr = (ulong)dataBuffer;
+ dataDescriptor->Size = 4;
+ totalEventSize += dataDescriptor->Size;
+
+ // then the array parameters
+ dataDescriptor++;
+ dataBuffer += s_basicTypeAllocationBufferSize;
+ dataDescriptor->Size = (uint)blobRet.Length;
+ }
+ else if (data is IntPtr)
+ {
+ dataDescriptor->Size = (uint)sizeof(IntPtr);
+ IntPtr* intptrPtr = (IntPtr*)dataBuffer;
+ *intptrPtr = (IntPtr)data;
+ dataDescriptor->Ptr = (ulong)intptrPtr;
+ }
+ else if (data is int)
+ {
+ dataDescriptor->Size = (uint)sizeof(int);
+ int* intptr = (int*)dataBuffer;
+ *intptr = (int)data;
+ dataDescriptor->Ptr = (ulong)intptr;
+ }
+ else if (data is long)
+ {
+ dataDescriptor->Size = (uint)sizeof(long);
+ long* longptr = (long*)dataBuffer;
+ *longptr = (long)data;
+ dataDescriptor->Ptr = (ulong)longptr;
+ }
+ else if (data is uint)
+ {
+ dataDescriptor->Size = (uint)sizeof(uint);
+ uint* uintptr = (uint*)dataBuffer;
+ *uintptr = (uint)data;
+ dataDescriptor->Ptr = (ulong)uintptr;
+ }
+ else if (data is UInt64)
+ {
+ dataDescriptor->Size = (uint)sizeof(ulong);
+ UInt64* ulongptr = (ulong*)dataBuffer;
+ *ulongptr = (ulong)data;
+ dataDescriptor->Ptr = (ulong)ulongptr;
+ }
+ else if (data is char)
+ {
+ dataDescriptor->Size = (uint)sizeof(char);
+ char* charptr = (char*)dataBuffer;
+ *charptr = (char)data;
+ dataDescriptor->Ptr = (ulong)charptr;
+ }
+ else if (data is byte)
+ {
+ dataDescriptor->Size = (uint)sizeof(byte);
+ byte* byteptr = (byte*)dataBuffer;
+ *byteptr = (byte)data;
+ dataDescriptor->Ptr = (ulong)byteptr;
+ }
+ else if (data is short)
+ {
+ dataDescriptor->Size = (uint)sizeof(short);
+ short* shortptr = (short*)dataBuffer;
+ *shortptr = (short)data;
+ dataDescriptor->Ptr = (ulong)shortptr;
+ }
+ else if (data is sbyte)
+ {
+ dataDescriptor->Size = (uint)sizeof(sbyte);
+ sbyte* sbyteptr = (sbyte*)dataBuffer;
+ *sbyteptr = (sbyte)data;
+ dataDescriptor->Ptr = (ulong)sbyteptr;
+ }
+ else if (data is ushort)
+ {
+ dataDescriptor->Size = (uint)sizeof(ushort);
+ ushort* ushortptr = (ushort*)dataBuffer;
+ *ushortptr = (ushort)data;
+ dataDescriptor->Ptr = (ulong)ushortptr;
+ }
+ else if (data is float)
+ {
+ dataDescriptor->Size = (uint)sizeof(float);
+ float* floatptr = (float*)dataBuffer;
+ *floatptr = (float)data;
+ dataDescriptor->Ptr = (ulong)floatptr;
+ }
+ else if (data is double)
+ {
+ dataDescriptor->Size = (uint)sizeof(double);
+ double* doubleptr = (double*)dataBuffer;
+ *doubleptr = (double)data;
+ dataDescriptor->Ptr = (ulong)doubleptr;
+ }
+ else if (data is bool)
+ {
+ // WIN32 Bool is 4 bytes
+ dataDescriptor->Size = 4;
+ int* intptr = (int*)dataBuffer;
+ if (((bool)data))
+ {
+ *intptr = 1;
+ }
+ else
+ {
+ *intptr = 0;
+ }
+ dataDescriptor->Ptr = (ulong)intptr;
+ }
+ else if (data is Guid)
+ {
+ dataDescriptor->Size = (uint)sizeof(Guid);
+ Guid* guidptr = (Guid*)dataBuffer;
+ *guidptr = (Guid)data;
+ dataDescriptor->Ptr = (ulong)guidptr;
+ }
+ else if (data is decimal)
+ {
+ dataDescriptor->Size = (uint)sizeof(decimal);
+ decimal* decimalptr = (decimal*)dataBuffer;
+ *decimalptr = (decimal)data;
+ dataDescriptor->Ptr = (ulong)decimalptr;
+ }
+ else if (data is DateTime)
+ {
+ const long UTCMinTicks = 504911232000000000;
+ long dateTimeTicks = 0;
+ // We cannot translate dates sooner than 1/1/1601 in UTC.
+ // To avoid getting an ArgumentOutOfRangeException we compare with 1/1/1601 DateTime ticks
+ if (((DateTime)data).Ticks > UTCMinTicks)
+ dateTimeTicks = ((DateTime)data).ToFileTimeUtc();
+ dataDescriptor->Size = (uint)sizeof(long);
+ long* longptr = (long*)dataBuffer;
+ *longptr = dateTimeTicks;
+ dataDescriptor->Ptr = (ulong)longptr;
+ }
+ else
+ {
+ if (data is System.Enum)
+ {
+ Type underlyingType = Enum.GetUnderlyingType(data.GetType());
+ if (underlyingType == typeof(int))
+ {
+#if !ES_BUILD_PCL
+ data = ((IConvertible)data).ToInt32(null);
+#else
+ data = (int)data;
+#endif
+ goto Again;
+ }
+ else if (underlyingType == typeof(long))
+ {
+#if !ES_BUILD_PCL
+ data = ((IConvertible)data).ToInt64(null);
+#else
+ data = (long)data;
+#endif
+ goto Again;
+ }
+ }
+
+ // To our eyes, everything else is a just a string
+ if (data == null)
+ sRet = "";
+ else
+ sRet = data.ToString();
+ dataDescriptor->Size = ((uint)sRet.Length + 1) * 2;
+ }
+
+ totalEventSize += dataDescriptor->Size;
+
+ // advance buffers
+ dataDescriptor++;
+ dataBuffer += s_basicTypeAllocationBufferSize;
+
+ return (object)sRet ?? (object)blobRet;
+ }
+
+ /// <summary>
+ /// WriteEvent, method to write a parameters with event schema properties
+ /// </summary>
+ /// <param name="eventDescriptor">
+ /// Event Descriptor for this event.
+ /// </param>
+ /// <param name="activityID">
+ /// A pointer to the activity ID GUID to log
+ /// </param>
+ /// <param name="childActivityID">
+ /// childActivityID is marked as 'related' to the current activity ID.
+ /// </param>
+ /// <param name="eventPayload">
+ /// Payload for the ETW event.
+ /// </param>
+ // <SecurityKernel Critical="True" Ring="0">
+ // <CallsSuppressUnmanagedCode Name="UnsafeNativeMethods.ManifestEtw.EventWrite(System.Int64,EventDescriptor&,System.UInt32,System.Void*):System.UInt32" />
+ // <UsesUnsafeCode Name="Local dataBuffer of type: Byte*" />
+ // <UsesUnsafeCode Name="Local pdata of type: Char*" />
+ // <UsesUnsafeCode Name="Local userData of type: EventData*" />
+ // <UsesUnsafeCode Name="Local userDataPtr of type: EventData*" />
+ // <UsesUnsafeCode Name="Local currentBuffer of type: Byte*" />
+ // <UsesUnsafeCode Name="Local v0 of type: Char*" />
+ // <UsesUnsafeCode Name="Local v1 of type: Char*" />
+ // <UsesUnsafeCode Name="Local v2 of type: Char*" />
+ // <UsesUnsafeCode Name="Local v3 of type: Char*" />
+ // <UsesUnsafeCode Name="Local v4 of type: Char*" />
+ // <UsesUnsafeCode Name="Local v5 of type: Char*" />
+ // <UsesUnsafeCode Name="Local v6 of type: Char*" />
+ // <UsesUnsafeCode Name="Local v7 of type: Char*" />
+ // <ReferencesCritical Name="Method: EncodeObject(Object&, EventData*, Byte*):String" Ring="1" />
+ // </SecurityKernel>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Performance-critical code")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
+ internal unsafe bool WriteEvent(ref EventDescriptor eventDescriptor, Guid* activityID, Guid* childActivityID, params object[] eventPayload)
+ {
+ int status = 0;
+
+ if (IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords))
+ {
+ int argCount = 0;
+ unsafe
+ {
+ argCount = eventPayload.Length;
+
+ if (argCount > s_etwMaxNumberArguments)
+ {
+ s_returnCode = WriteEventErrorCode.TooManyArgs;
+ return false;
+ }
+
+ uint totalEventSize = 0;
+ int index;
+ int refObjIndex = 0;
+ List<int> refObjPosition = new List<int>(s_etwAPIMaxRefObjCount);
+ List<object> dataRefObj = new List<object>(s_etwAPIMaxRefObjCount);
+ EventData* userData = stackalloc EventData[2 * argCount];
+ EventData* userDataPtr = (EventData*)userData;
+ byte* dataBuffer = stackalloc byte[s_basicTypeAllocationBufferSize * 2 * argCount]; // Assume 16 chars for non-string argument
+ byte* currentBuffer = dataBuffer;
+
+ //
+ // The loop below goes through all the arguments and fills in the data
+ // descriptors. For strings save the location in the dataString array.
+ // Calculates the total size of the event by adding the data descriptor
+ // size value set in EncodeObject method.
+ //
+ bool hasNonStringRefArgs = false;
+ for (index = 0; index < eventPayload.Length; index++)
+ {
+ if (eventPayload[index] != null)
+ {
+ object supportedRefObj;
+ supportedRefObj = EncodeObject(ref eventPayload[index], ref userDataPtr, ref currentBuffer, ref totalEventSize);
+
+ if (supportedRefObj != null)
+ {
+ // EncodeObject advanced userDataPtr to the next empty slot
+ int idx = (int)(userDataPtr - userData - 1);
+ if (!(supportedRefObj is string))
+ {
+ if (eventPayload.Length + idx + 1 - index > s_etwMaxNumberArguments)
+ {
+ s_returnCode = WriteEventErrorCode.TooManyArgs;
+ return false;
+ }
+ hasNonStringRefArgs = true;
+ }
+ dataRefObj.Add(supportedRefObj);
+ refObjPosition.Add(idx);
+ refObjIndex++;
+ }
+ }
+ else
+ {
+ s_returnCode = WriteEventErrorCode.NullInput;
+ return false;
+ }
+ }
+
+ // update argCount based on actual number of arguments written to 'userData'
+ argCount = (int)(userDataPtr - userData);
+
+ if (totalEventSize > s_traceEventMaximumSize)
+ {
+ s_returnCode = WriteEventErrorCode.EventTooBig;
+ return false;
+ }
+
+ // the optimized path (using "fixed" instead of allocating pinned GCHandles
+ if (!hasNonStringRefArgs && (refObjIndex < s_etwAPIMaxRefObjCount))
+ {
+ // Fast path: at most 8 string arguments
+
+ // ensure we have at least s_etwAPIMaxStringCount in dataString, so that
+ // the "fixed" statement below works
+ while (refObjIndex < s_etwAPIMaxRefObjCount)
+ {
+ dataRefObj.Add(null);
+ ++refObjIndex;
+ }
+
+ //
+ // now fix any string arguments and set the pointer on the data descriptor
+ //
+ fixed (char* v0 = (string)dataRefObj[0], v1 = (string)dataRefObj[1], v2 = (string)dataRefObj[2], v3 = (string)dataRefObj[3],
+ v4 = (string)dataRefObj[4], v5 = (string)dataRefObj[5], v6 = (string)dataRefObj[6], v7 = (string)dataRefObj[7])
+ {
+ userDataPtr = (EventData*)userData;
+ if (dataRefObj[0] != null)
+ {
+ userDataPtr[refObjPosition[0]].Ptr = (ulong)v0;
+ }
+ if (dataRefObj[1] != null)
+ {
+ userDataPtr[refObjPosition[1]].Ptr = (ulong)v1;
+ }
+ if (dataRefObj[2] != null)
+ {
+ userDataPtr[refObjPosition[2]].Ptr = (ulong)v2;
+ }
+ if (dataRefObj[3] != null)
+ {
+ userDataPtr[refObjPosition[3]].Ptr = (ulong)v3;
+ }
+ if (dataRefObj[4] != null)
+ {
+ userDataPtr[refObjPosition[4]].Ptr = (ulong)v4;
+ }
+ if (dataRefObj[5] != null)
+ {
+ userDataPtr[refObjPosition[5]].Ptr = (ulong)v5;
+ }
+ if (dataRefObj[6] != null)
+ {
+ userDataPtr[refObjPosition[6]].Ptr = (ulong)v6;
+ }
+ if (dataRefObj[7] != null)
+ {
+ userDataPtr[refObjPosition[7]].Ptr = (ulong)v7;
+ }
+
+ status = UnsafeNativeMethods.ManifestEtw.EventWriteTransferWrapper(m_regHandle, ref eventDescriptor, activityID, childActivityID, argCount, userData);
+ }
+ }
+ else
+ {
+ // Slow path: use pinned handles
+ userDataPtr = (EventData*)userData;
+
+ GCHandle[] rgGCHandle = new GCHandle[refObjIndex];
+ for (int i = 0; i < refObjIndex; ++i)
+ {
+ // below we still use "fixed" to avoid taking dependency on the offset of the first field
+ // in the object (the way we would need to if we used GCHandle.AddrOfPinnedObject)
+ rgGCHandle[i] = GCHandle.Alloc(dataRefObj[i], GCHandleType.Pinned);
+ if (dataRefObj[i] is string)
+ {
+ fixed (char* p = (string)dataRefObj[i])
+ userDataPtr[refObjPosition[i]].Ptr = (ulong)p;
+ }
+ else
+ {
+ fixed (byte* p = (byte[])dataRefObj[i])
+ userDataPtr[refObjPosition[i]].Ptr = (ulong)p;
+ }
+ }
+
+ status = UnsafeNativeMethods.ManifestEtw.EventWriteTransferWrapper(m_regHandle, ref eventDescriptor, activityID, childActivityID, argCount, userData);
+
+ for (int i = 0; i < refObjIndex; ++i)
+ {
+ rgGCHandle[i].Free();
+ }
+ }
+ }
+ }
+
+ if (status != 0)
+ {
+ SetLastError((int)status);
+ return false;
+ }
+
+ return true;
+ }
+
+ /// <summary>
+ /// WriteEvent, method to be used by generated code on a derived class
+ /// </summary>
+ /// <param name="eventDescriptor">
+ /// Event Descriptor for this event.
+ /// </param>
+ /// <param name="activityID">
+ /// A pointer to the activity ID to log
+ /// </param>
+ /// <param name="childActivityID">
+ /// If this event is generating a child activity (WriteEventTransfer related activity) this is child activity
+ /// This can be null for events that do not generate a child activity.
+ /// </param>
+ /// <param name="dataCount">
+ /// number of event descriptors
+ /// </param>
+ /// <param name="data">
+ /// pointer do the event data
+ /// </param>
+ // <SecurityKernel Critical="True" Ring="0">
+ // <CallsSuppressUnmanagedCode Name="UnsafeNativeMethods.ManifestEtw.EventWrite(System.Int64,EventDescriptor&,System.UInt32,System.Void*):System.UInt32" />
+ // </SecurityKernel>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
+ internal unsafe protected bool WriteEvent(ref EventDescriptor eventDescriptor, Guid* activityID, Guid* childActivityID, int dataCount, IntPtr data)
+ {
+ if (childActivityID != null)
+ {
+ // activity transfers are supported only for events that specify the Send or Receive opcode
+ Debug.Assert((EventOpcode)eventDescriptor.Opcode == EventOpcode.Send ||
+ (EventOpcode)eventDescriptor.Opcode == EventOpcode.Receive ||
+ (EventOpcode)eventDescriptor.Opcode == EventOpcode.Start ||
+ (EventOpcode)eventDescriptor.Opcode == EventOpcode.Stop);
+ }
+
+ int status = UnsafeNativeMethods.ManifestEtw.EventWriteTransferWrapper(m_regHandle, ref eventDescriptor, activityID, childActivityID, dataCount, (EventData*)data);
+
+ if (status != 0)
+ {
+ SetLastError(status);
+ return false;
+ }
+ return true;
+ }
+
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
+ internal unsafe bool WriteEventRaw(
+ ref EventDescriptor eventDescriptor,
+ Guid* activityID,
+ Guid* relatedActivityID,
+ int dataCount,
+ IntPtr data)
+ {
+ int status;
+
+ status = UnsafeNativeMethods.ManifestEtw.EventWriteTransferWrapper(
+ m_regHandle,
+ ref eventDescriptor,
+ activityID,
+ relatedActivityID,
+ dataCount,
+ (EventData*)data);
+
+ if (status != 0)
+ {
+ SetLastError(status);
+ return false;
+ }
+ return true;
+ }
+
+
+ // These are look-alikes to the Manifest based ETW OS APIs that have been shimmed to work
+ // either with Manifest ETW or Classic ETW (if Manifest based ETW is not available).
+ private unsafe uint EventRegister(ref Guid providerId, UnsafeNativeMethods.ManifestEtw.EtwEnableCallback enableCallback)
+ {
+ m_providerId = providerId;
+ m_etwCallback = enableCallback;
+ return UnsafeNativeMethods.ManifestEtw.EventRegister(ref providerId, enableCallback, null, ref m_regHandle);
+ }
+
+ private uint EventUnregister(long registrationHandle)
+ {
+ return UnsafeNativeMethods.ManifestEtw.EventUnregister(registrationHandle);
+ }
+
+ static int[] nibblebits = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+ private static int bitcount(uint n)
+ {
+ int count = 0;
+ for (; n != 0; n = n >> 4)
+ count += nibblebits[n & 0x0f];
+ return count;
+ }
+ private static int bitindex(uint n)
+ {
+ Debug.Assert(bitcount(n) == 1);
+ int idx = 0;
+ while ((n & (1 << idx)) == 0)
+ idx++;
+ return idx;
+ }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/EventSource.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/EventSource.cs
new file mode 100644
index 0000000000..cf4901de6f
--- /dev/null
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/EventSource.cs
@@ -0,0 +1,6942 @@
+// 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.
+
+// This program uses code hyperlinks available as part of the HyperAddin Visual Studio plug-in.
+// It is available from http://www.codeplex.com/hyperAddin
+#if PLATFORM_WINDOWS
+
+#define FEATURE_MANAGED_ETW
+
+#if !ES_BUILD_STANDALONE && !CORECLR && !ES_BUILD_PN
+#define FEATURE_ACTIVITYSAMPLING
+#endif // !ES_BUILD_STANDALONE
+
+#endif // PLATFORM_WINDOWS
+
+#if ES_BUILD_STANDALONE
+#define FEATURE_MANAGED_ETW_CHANNELS
+// #define FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
+#endif
+
+/* DESIGN NOTES DESIGN NOTES DESIGN NOTES DESIGN NOTES */
+// DESIGN NOTES
+// Over the years EventSource has become more complex and so it is important to understand
+// the basic structure of the code to insure that it does not grow more complex.
+//
+// Basic Model
+//
+// PRINCIPLE: EventSource - ETW decoupling
+//
+// Conceptually and EventSouce is something takes event logging data from the source methods
+// To the EventListener that can subscribe them. Note that CONCEPTUALLY EVENTSOURCES DON'T
+// KNOW ABOUT ETW!. The MODEL of the system is that there is a special EventListern Which
+// we will call the EtwEventListener, that forwards commands from ETW to EventSources and
+// listeners to the EventSources and forwards on those events to ETW. THus the model should
+// be that you DON'T NEED ETW.
+//
+// Now in actual practice, EventSouce have rather intimate knowledge of ETW and send events
+// to it directly, but this can be VIEWED AS AN OPTIMIATION.
+//
+// Basic Event Data Flow:
+//
+// There are two ways for event Data to enter the system
+// 1) WriteEvent* and friends. This is called the 'contract' based approach because
+// you write a method per event which forms a contract that is know at compile time.
+// In this scheme each event is given an EVENTID (small integer). which is its identity
+// 2) Write<T> methods. This is called the 'dynamic' approach because new events
+// can be created on the fly. Event identity is determined by the event NAME, and these
+// are not quite as efficient at runtime since you have at least a hash table lookup
+// on every event write.
+//
+// EventSource-EventListener transfer fully support both ways of writing events (either contract
+// based (WriteEvent*) or dynamic (Write<T>). Both way fully support the same set of data
+// types. It is suggested, however, that you use the contract based approach when the event scheme
+// is known at compile time (that is whenever possible). It is more efficient, but more importantly
+// it makes the contract very explicit, and centralizes all policy about logging. These are good
+// things. The Write<T> API is really meant for more ad-hoc
+//
+// Allowed Data.
+//
+// Note that EventSource-EventListeners have a conceptual serialization-deserialization that happens
+// during the transfer. In particular object identity is not preserved, some objects are morphed,
+// and not all data types are supported. In particular you can pass
+//
+// A Valid type to log to an EventSource include
+// * Primitive data types
+// * IEnumerable<T> of valid types T (this include arrays) (* New for V4.6)
+// * Explicitly Opted in class or struct with public property Getters over Valid types. (* New for V4.6)
+//
+// This set of types is roughly a generalization of JSON support (Basically primitives, bags, and arrays).
+//
+// Explicitly allowed structs include (* New for V4.6)
+// * Marked with the EventData attribute
+// * implicitly defined (e.g the C# new {x = 3, y = 5} syntax)
+// * KeyValuePair<K,V> (thus dictionaries can be passed since they are an IEnumerable of KeyValuePair)
+//
+// When classes are returned in an EventListener, what is returned is something that implements
+// IDictionary<string, T>. Thus when objects are passed to an EventSource they are transformed
+// into a key-value bag (the IDictionary<string, T>) for consumption in the listener. These
+// are obvious NOT the original objects.
+//
+// ETWserialization formats:
+//
+// As mentioned conceptually EventSource's send data to EventListeners and there is a conceptual
+// copy/morph of that data as described above. In addition the .NET framework supports a conceptual
+// ETWListener that will send the data to then ETW stream. If you use this feature, the data needs
+// to be serialized in a way that ETW supports. ETW supports the following serialization formats
+//
+// 1) Manifest Based serialization.
+// 2) SelfDescribing serialization (TraceLogging style in the TraceLogging directory)
+//
+// A key factor is that the Write<T> method, which support on the fly definition of events, can't
+// support the manifest based serialization because the manifest needs the schema of all events
+// to be known before any events are emitted. This implies the following
+//
+// If you use Write<T> and the output goes to ETW it will use the SelfDescribing format.
+// If you use the EventSource(string) constructor for an eventSource (in which you don't
+// create a subclass), the default is also to use Self-Describing serialization. In addition
+// you can use the EventSoruce(EventSourceSettings) constructor to also explicitly specify
+// Self-Describing serialization format. These effect the WriteEvent* APIs going to ETW.
+//
+// Note that none of this ETW serialization logic affects EventListeners. Only the ETW listener.
+//
+// *************************************************************************************
+// *** INTERNALS: Event Propagation
+//
+// Data enters the system either though
+//
+// 1) A user defined method in the user defined subclass of EventSource which calls
+// A) A typesafe type specific overload of WriteEvent(ID, ...) e.g. WriteEvent(ID, string, string)
+// * which calls into the unsafe WriteEventCore(ID COUNT EventData*) WriteEventWithRelatedActivityIdCore()
+// B) The typesafe overload WriteEvent(ID, object[]) which calls the private helper WriteEventVarargs(ID, Guid* object[])
+// C) Directly into the unsafe WriteEventCore(ID, COUNT EventData*) or WriteEventWithRelatedActivityIdCore()
+//
+// All event data eventually flows to one of
+// * WriteEventWithRelatedActivityIdCore(ID, Guid*, COUNT, EventData*)
+// * WriteEventVarargs(ID, Guid*, object[])
+//
+// 2) A call to one of the overloads of Write<T>. All these overloads end up in
+// * WriteImpl<T>(EventName, Options, Data, Guid*, Guid*)
+//
+// On output there are the following routines
+// Writing to all listeners that are NOT ETW, we have the following routines
+// * WriteToAllListeners(ID, Guid*, COUNT, EventData*)
+// * WriteToAllListeners(ID, Guid*, object[])
+// * WriteToAllListeners(NAME, Guid*, EventPayload)
+//
+// EventPayload is the internal type that implements the IDictionary<string, object> interface
+// The EventListeners will pass back for serialized classes for nested object, but
+// WriteToAllListeners(NAME, Guid*, EventPayload) unpacks this uses the fields as if they
+// were parameters to a method.
+//
+// The first two are used for the WriteEvent* case, and the later is used for the Write<T> case.
+//
+// Writing to ETW, Manifest Based
+// EventProvider.WriteEvent(EventDescriptor, Guid*, COUNT, EventData*)
+// EventProvider.WriteEvent(EventDescriptor, Guid*, object[])
+// Writing to ETW, Self-Describing format
+// WriteMultiMerge(NAME, Options, Types, EventData*)
+// WriteMultiMerge(NAME, Options, Types, object[])
+// WriteImpl<T> has logic that knows how to serialize (like WriteMultiMerge) but also knows
+// will write it to
+//
+// All ETW writes eventually call
+// EventWriteTransfer (native PINVOKE wrapper)
+// EventWriteTransferWrapper (fixes compat problem if you pass null as the related activityID)
+// EventProvider.WriteEventRaw - sets last error
+// EventSource.WriteEventRaw - Does EventSource exception handling logic
+// WriteMultiMerge
+// WriteImpl<T>
+// EventProvider.WriteEvent(EventDescriptor, Guid*, COUNT, EventData*)
+// EventProvider.WriteEvent(EventDescriptor, Guid*, object[])
+//
+// Serialization: We have a bit of a hodge-podge of serializers right now. Only the one for ETW knows
+// how to deal with nested classes or arrays. I will call this serializer the 'TypeInfo' serializer
+// since it is the TraceLoggingTypeInfo structure that knows how to do this. Effectively for a type you
+// can call one of these
+// WriteMetadata - transforms the type T into serialization meta data blob for that type
+// WriteObjectData - transforms an object of T into serialization meta data blob for that type
+// GetData - transforms an object of T into its deserialized form suitable for passing to EventListener.
+// The first two are used to serialize something for ETW. The second one is used to transform the object
+// for use by the EventListener. We also have a 'DecodeObject' method that will take a EventData* and
+// deserialize to pass to an EventListener, but it only works on primitive types (types supported in version V4.5).
+//
+// It is an important observation that while EventSource does support users directly calling with EventData*
+// blobs, we ONLY support that for the primitive types (V4.5 level support). Thus while there is a EventData*
+// path through the system it is only for some types. The object[] path is the more general (but less efficient) path.
+//
+// TODO There is cleanup needed There should be no divergence until WriteEventRaw.
+//
+// TODO: We should have a single choke point (right now we always have this parallel EventData* and object[] path. This
+// was historical (at one point we tried to pass object directly from EventSoruce to EventListener. That was always
+// fragile and a compatibility headache, but we have finally been forced into the idea that there is always a transformation.
+// This allows us to use the EventData* form to be the canonical data format in the low level APIs. This also gives us the
+// opportunity to expose this format to EventListeners in the future.
+//
+using System;
+using System.Runtime.CompilerServices;
+#if FEATURE_ACTIVITYSAMPLING
+using System.Collections.Concurrent;
+#endif
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Reflection;
+using System.Resources;
+using System.Security;
+#if !CORECLR && !ES_BUILD_PN
+using System.Security.Permissions;
+#endif // !CORECLR && !ES_BUILD_PN
+
+using System.Text;
+using System.Threading;
+using Microsoft.Win32;
+
+#if ES_BUILD_STANDALONE
+using EventDescriptor = Microsoft.Diagnostics.Tracing.EventDescriptor;
+#else
+using System.Threading.Tasks;
+#endif
+
+using Microsoft.Reflection;
+
+#if !ES_BUILD_AGAINST_DOTNET_V35
+using Contract = System.Diagnostics.Contracts.Contract;
+#else
+using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract;
+#endif
+
+#if CORECLR || ES_BUILD_PN
+using Internal.Runtime.Augments;
+#endif
+
+#if ES_BUILD_STANDALONE
+namespace Microsoft.Diagnostics.Tracing
+#else
+namespace System.Diagnostics.Tracing
+#endif
+{
+ /// <summary>
+ /// This class is meant to be inherited by a user-defined event source in order to define a managed
+ /// ETW provider. Please See DESIGN NOTES above for the internal architecture.
+ /// The minimal definition of an EventSource simply specifies a number of ETW event methods that
+ /// call one of the EventSource.WriteEvent overloads, <see cref="EventSource.WriteEventCore"/>,
+ /// or <see cref="EventSource.WriteEventWithRelatedActivityIdCore"/> to log them. This functionality
+ /// is sufficient for many users.
+ /// <para>
+ /// To achieve more control over the ETW provider manifest exposed by the event source type, the
+ /// [<see cref="EventAttribute"/>] attributes can be specified for the ETW event methods.
+ /// </para><para>
+ /// For very advanced EventSources, it is possible to intercept the commands being given to the
+ /// eventSource and change what filtering is done (see EventListener.EnableEvents and
+ /// <see cref="EventListener.DisableEvents"/>) or cause actions to be performed by the eventSource,
+ /// e.g. dumping a data structure (see EventSource.SendCommand and
+ /// <see cref="EventSource.OnEventCommand"/>).
+ /// </para><para>
+ /// The eventSources can be turned on with Windows ETW controllers (e.g. logman), immediately.
+ /// It is also possible to control and intercept the data dispatcher programmatically. See
+ /// <see cref="EventListener"/> for more.
+ /// </para>
+ /// </summary>
+ /// <remarks>
+ /// This is a minimal definition for a custom event source:
+ /// <code>
+ /// [EventSource(Name="Samples-Demos-Minimal")]
+ /// sealed class MinimalEventSource : EventSource
+ /// {
+ /// public static MinimalEventSource Log = new MinimalEventSource();
+ /// public void Load(long ImageBase, string Name) { WriteEvent(1, ImageBase, Name); }
+ /// public void Unload(long ImageBase) { WriteEvent(2, ImageBase); }
+ /// private MinimalEventSource() {}
+ /// }
+ /// </code>
+ /// </remarks>
+ public partial class EventSource : IDisposable
+ {
+
+#if FEATURE_EVENTSOURCE_XPLAT
+ private static readonly EventListener persistent_Xplat_Listener = XplatEventLogger.InitializePersistentListener();
+#endif //FEATURE_EVENTSOURCE_XPLAT
+
+ /// <summary>
+ /// The human-friendly name of the eventSource. It defaults to the simple name of the class
+ /// </summary>
+ public string Name { get { return m_name; } }
+ /// <summary>
+ /// Every eventSource is assigned a GUID to uniquely identify it to the system.
+ /// </summary>
+ public Guid Guid { get { return m_guid; } }
+
+ /// <summary>
+ /// Returns true if the eventSource has been enabled at all. This is the prefered test
+ /// to be performed before a relatively expensive EventSource operation.
+ /// </summary>
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ public bool IsEnabled()
+ {
+ return m_eventSourceEnabled;
+ }
+
+ /// <summary>
+ /// Returns true if events with greater than or equal 'level' and have one of 'keywords' set are enabled.
+ ///
+ /// Note that the result of this function is only an approximation on whether a particular
+ /// event is active or not. It is only meant to be used as way of avoiding expensive
+ /// computation for logging when logging is not on, therefore it sometimes returns false
+ /// positives (but is always accurate when returning false). EventSources are free to
+ /// have additional filtering.
+ /// </summary>
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ public bool IsEnabled(EventLevel level, EventKeywords keywords)
+ {
+ return IsEnabled(level, keywords, EventChannel.None);
+ }
+
+ /// <summary>
+ /// Returns true if events with greater than or equal 'level' and have one of 'keywords' set are enabled, or
+ /// if 'keywords' specifies a channel bit for a channel that is enabled.
+ ///
+ /// Note that the result of this function only an approximation on whether a particular
+ /// event is active or not. It is only meant to be used as way of avoiding expensive
+ /// computation for logging when logging is not on, therefore it sometimes returns false
+ /// positives (but is always accurate when returning false). EventSources are free to
+ /// have additional filtering.
+ /// </summary>
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ public bool IsEnabled(EventLevel level, EventKeywords keywords, EventChannel channel)
+ {
+ if (!m_eventSourceEnabled)
+ return false;
+
+ if (!IsEnabledCommon(m_eventSourceEnabled, m_level, m_matchAnyKeyword, level, keywords, channel))
+ return false;
+
+#if !FEATURE_ACTIVITYSAMPLING
+
+ return true;
+
+#else // FEATURE_ACTIVITYSAMPLING
+
+ return true;
+
+#if OPTIMIZE_IS_ENABLED
+ //================================================================================
+ // 2013/03/06 - The code below is a possible optimization for IsEnabled(level, kwd)
+ // in case activity tracing/sampling is enabled. The added complexity of this
+ // code however weighs against having it "on" until we know it's really needed.
+ // For now we'll have this #ifdef-ed out in case we see evidence this is needed.
+ //================================================================================
+
+ // At this point we believe the event is enabled, however we now need to check
+ // if we filter because of activity
+
+ // Optimization, all activity filters also register a delegate here, so if there
+ // is no delegate, we know there are no activity filters, which means that there
+ // is no additional filtering, which means that we can return true immediately.
+ if (s_activityDying == null)
+ return true;
+
+ // if there's at least one legacy ETW listener we can't filter this
+ if (m_legacySessions != null && m_legacySessions.Count > 0)
+ return true;
+
+ // if any event ID that triggers a new activity, or "transfers" activities
+ // is covered by 'keywords' we can't filter this
+ if (unchecked(((long)keywords & m_keywordTriggers)) != 0)
+ return true;
+
+ // See if all listeners have activity filters that would block the event.
+ for (int perEventSourceSessionId = 0; perEventSourceSessionId < SessionMask.MAX; ++perEventSourceSessionId)
+ {
+ EtwSession etwSession = m_etwSessionIdMap[perEventSourceSessionId];
+ if (etwSession == null)
+ continue;
+
+ ActivityFilter activityFilter = etwSession.m_activityFilter;
+ if (activityFilter == null ||
+ ActivityFilter.GetFilter(activityFilter, this) == null)
+ {
+ // No activity filter for ETW, if event is active for ETW, we can't filter.
+ for (int i = 0; i < m_eventData.Length; i++)
+ if (m_eventData[i].EnabledForETW)
+ return true;
+ }
+ else if (ActivityFilter.IsCurrentActivityActive(activityFilter))
+ return true;
+ }
+
+ // for regular event listeners
+ var curDispatcher = m_Dispatchers;
+ while (curDispatcher != null)
+ {
+ ActivityFilter activityFilter = curDispatcher.m_Listener.m_activityFilter;
+ if (activityFilter == null)
+ {
+ // See if any event is enabled.
+ for (int i = 0; i < curDispatcher.m_EventEnabled.Length; i++)
+ if (curDispatcher.m_EventEnabled[i])
+ return true;
+ }
+ else if (ActivityFilter.IsCurrentActivityActive(activityFilter))
+ return true;
+ curDispatcher = curDispatcher.m_Next;
+ }
+
+ // Every listener has an activity filter that is blocking writing the event,
+ // thus the event is not enabled.
+ return false;
+#endif // OPTIMIZE_IS_ENABLED
+
+#endif // FEATURE_ACTIVITYSAMPLING
+ }
+
+ /// <summary>
+ /// Returns the settings for the event source instance
+ /// </summary>
+ public EventSourceSettings Settings
+ {
+ get { return m_config; }
+ }
+
+ // Manifest support
+ /// <summary>
+ /// Returns the GUID that uniquely identifies the eventSource defined by 'eventSourceType'.
+ /// This API allows you to compute this without actually creating an instance of the EventSource.
+ /// It only needs to reflect over the type.
+ /// </summary>
+ public static Guid GetGuid(Type eventSourceType)
+ {
+ if (eventSourceType == null)
+ throw new ArgumentNullException(nameof(eventSourceType));
+ Contract.EndContractBlock();
+
+ EventSourceAttribute attrib = (EventSourceAttribute)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute));
+ string name = eventSourceType.Name;
+ if (attrib != null)
+ {
+ if (attrib.Guid != null)
+ {
+ Guid g = Guid.Empty;
+#if !ES_BUILD_AGAINST_DOTNET_V35
+ if (Guid.TryParse(attrib.Guid, out g))
+ return g;
+#else
+ try { return new Guid(attrib.Guid); }
+ catch (Exception) { }
+#endif
+ }
+
+ if (attrib.Name != null)
+ name = attrib.Name;
+ }
+
+ if (name == null)
+ {
+ throw new ArgumentException(Resources.GetResourceString("Argument_InvalidTypeName"), nameof(eventSourceType));
+ }
+ return GenerateGuidFromName(name.ToUpperInvariant()); // Make it case insensitive.
+ }
+ /// <summary>
+ /// Returns the official ETW Provider name for the eventSource defined by 'eventSourceType'.
+ /// This API allows you to compute this without actually creating an instance of the EventSource.
+ /// It only needs to reflect over the type.
+ /// </summary>
+ public static string GetName(Type eventSourceType)
+ {
+ return GetName(eventSourceType, EventManifestOptions.None);
+ }
+
+ /// <summary>
+ /// Returns a string of the XML manifest associated with the eventSourceType. The scheme for this XML is
+ /// documented at in EventManifest Schema http://msdn.microsoft.com/en-us/library/aa384043(VS.85).aspx.
+ /// This is the preferred way of generating a manifest to be embedded in the ETW stream as it is fast and
+ /// the fact that it only includes localized entries for the current UI culture is an acceptable tradeoff.
+ /// </summary>
+ /// <param name="eventSourceType">The type of the event source class for which the manifest is generated</param>
+ /// <param name="assemblyPathToIncludeInManifest">The manifest XML fragment contains the string name of the DLL name in
+ /// which it is embedded. This parameter specifies what name will be used</param>
+ /// <returns>The XML data string</returns>
+ public static string GenerateManifest(Type eventSourceType, string assemblyPathToIncludeInManifest)
+ {
+ return GenerateManifest(eventSourceType, assemblyPathToIncludeInManifest, EventManifestOptions.None);
+ }
+ /// <summary>
+ /// Returns a string of the XML manifest associated with the eventSourceType. The scheme for this XML is
+ /// documented at in EventManifest Schema http://msdn.microsoft.com/en-us/library/aa384043(VS.85).aspx.
+ /// Pass EventManifestOptions.AllCultures when generating a manifest to be registered on the machine. This
+ /// ensures that the entries in the event log will be "optimally" localized.
+ /// </summary>
+ /// <param name="eventSourceType">The type of the event source class for which the manifest is generated</param>
+ /// <param name="assemblyPathToIncludeInManifest">The manifest XML fragment contains the string name of the DLL name in
+ /// which it is embedded. This parameter specifies what name will be used</param>
+ /// <param name="flags">The flags to customize manifest generation. If flags has bit OnlyIfNeededForRegistration specified
+ /// this returns null when the eventSourceType does not require explicit registration</param>
+ /// <returns>The XML data string or null</returns>
+ public static string GenerateManifest(Type eventSourceType, string assemblyPathToIncludeInManifest, EventManifestOptions flags)
+ {
+ if (eventSourceType == null)
+ throw new ArgumentNullException(nameof(eventSourceType));
+ Contract.EndContractBlock();
+
+ byte[] manifestBytes = EventSource.CreateManifestAndDescriptors(eventSourceType, assemblyPathToIncludeInManifest, null, flags);
+ return (manifestBytes == null) ? null : Encoding.UTF8.GetString(manifestBytes, 0, manifestBytes.Length);
+ }
+
+ // EventListener support
+ /// <summary>
+ /// returns a list (IEnumerable) of all sources in the appdomain). EventListeners typically need this.
+ /// </summary>
+ /// <returns></returns>
+ public static IEnumerable<EventSource> GetSources()
+ {
+ var ret = new List<EventSource>();
+ lock (EventListener.EventListenersLock)
+ {
+ foreach (WeakReference eventSourceRef in EventListener.s_EventSources)
+ {
+ EventSource eventSource = eventSourceRef.Target as EventSource;
+ if (eventSource != null && !eventSource.IsDisposed)
+ ret.Add(eventSource);
+ }
+ }
+ return ret;
+ }
+
+ /// <summary>
+ /// Send a command to a particular EventSource identified by 'eventSource'.
+ /// Calling this routine simply forwards the command to the EventSource.OnEventCommand
+ /// callback. What the EventSource does with the command and its arguments are from
+ /// that point EventSource-specific.
+ /// </summary>
+ /// <param name="eventSource">The instance of EventSource to send the command to</param>
+ /// <param name="command">A positive user-defined EventCommand, or EventCommand.SendManifest</param>
+ /// <param name="commandArguments">A set of (name-argument, value-argument) pairs associated with the command</param>
+ public static void SendCommand(EventSource eventSource, EventCommand command, IDictionary<string, string> commandArguments)
+ {
+ if (eventSource == null)
+ throw new ArgumentNullException(nameof(eventSource));
+
+ // User-defined EventCommands should not conflict with the reserved commands.
+ if ((int)command <= (int)EventCommand.Update && (int)command != (int)EventCommand.SendManifest)
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_InvalidCommand"), nameof(command));
+ }
+
+ eventSource.SendCommand(null, 0, 0, command, true, EventLevel.LogAlways, EventKeywords.None, commandArguments);
+ }
+
+#if !ES_BUILD_STANDALONE
+ /// <summary>
+ /// This property allows EventSource code to appropriately handle as "different"
+ /// activities started on different threads that have not had an activity created on them.
+ /// </summary>
+ internal static Guid InternalCurrentThreadActivityId
+ {
+ get
+ {
+ Guid retval = CurrentThreadActivityId;
+ if (retval == Guid.Empty)
+ {
+ retval = FallbackActivityId;
+ }
+ return retval;
+ }
+ }
+
+ internal static Guid FallbackActivityId
+ {
+ get
+ {
+#pragma warning disable 612, 618
+ int threadID = AppDomain.GetCurrentThreadId();
+
+ // Managed thread IDs are more aggressively re-used than native thread IDs,
+ // so we'll use the latter...
+ return new Guid(unchecked((uint)threadID),
+ unchecked((ushort)s_currentPid), unchecked((ushort)(s_currentPid >> 16)),
+ 0x94, 0x1b, 0x87, 0xd5, 0xa6, 0x5c, 0x36, 0x64);
+#pragma warning restore 612, 618
+ }
+ }
+#endif // !ES_BUILD_STANDALONE
+
+ // Error APIs. (We don't throw by default, but you can probe for status)
+ /// <summary>
+ /// Because
+ ///
+ /// 1) Logging is often optional and thus should not generate fatal errors (exceptions)
+ /// 2) EventSources are often initialized in class constructors (which propagate exceptions poorly)
+ ///
+ /// The event source constructor does not throw exceptions. Instead we remember any exception that
+ /// was generated (it is also logged to Trace.WriteLine).
+ /// </summary>
+ public Exception ConstructionException { get { return m_constructionException; } }
+
+ /// <summary>
+ /// EventSources can have arbitrary string key-value pairs associated with them called Traits.
+ /// These traits are not interpreted by the EventSource but may be interpreted by EventListeners
+ /// (e.g. like the built in ETW listener). These traits are specififed at EventSource
+ /// construction time and can be retrieved by using this GetTrait API.
+ /// </summary>
+ /// <param name="key">The key to look up in the set of key-value pairs passed to the EventSource constructor</param>
+ /// <returns>The value string associated iwth key. Will return null if there is no such key.</returns>
+ public string GetTrait(string key)
+ {
+ if (m_traits != null)
+ {
+ for (int i = 0; i < m_traits.Length - 1; i += 2)
+ {
+ if (m_traits[i] == key)
+ return m_traits[i + 1];
+ }
+ }
+ return null;
+ }
+
+ /// <summary>
+ /// Displays the name and GUID for the eventSource for debugging purposes.
+ /// </summary>
+ public override string ToString()
+ {
+ return Resources.GetResourceString("EventSource_ToString", Name, Guid);
+ }
+
+ /// <summary>
+ /// Fires when a Command (e.g. Enable) comes from a an EventListener.
+ /// </summary>
+ public event EventHandler<EventCommandEventArgs> EventCommandExecuted
+ {
+ add
+ {
+ m_eventCommandExecuted += value;
+
+ // If we have an EventHandler<EventCommandEventArgs> attached to the EventSource before the first command arrives
+ // It should get a chance to handle the deferred commands.
+ EventCommandEventArgs deferredCommands = m_deferredCommands;
+ while (deferredCommands != null)
+ {
+ value(this, deferredCommands);
+ deferredCommands = deferredCommands.nextCommand;
+ }
+ }
+ remove
+ {
+ m_eventCommandExecuted -= value;
+ }
+ }
+
+ #region protected
+ /// <summary>
+ /// This is the constructor that most users will use to create their eventSource. It takes
+ /// no parameters. The ETW provider name and GUID of the EventSource are determined by the EventSource
+ /// custom attribute (so you can determine these things declaratively). If the GUID for the eventSource
+ /// is not specified in the EventSourceAttribute (recommended), it is Generated by hashing the name.
+ /// If the ETW provider name of the EventSource is not given, the name of the EventSource class is used as
+ /// the ETW provider name.
+ /// </summary>
+ protected EventSource()
+ : this(EventSourceSettings.EtwManifestEventFormat)
+ {
+ }
+
+ /// <summary>
+ /// By default calling the 'WriteEvent' methods do NOT throw on errors (they silently discard the event).
+ /// This is because in most cases users assume logging is not 'precious' and do NOT wish to have logging failures
+ /// crash the program. However for those applications where logging is 'precious' and if it fails the caller
+ /// wishes to react, setting 'throwOnEventWriteErrors' will cause an exception to be thrown if WriteEvent
+ /// fails. Note the fact that EventWrite succeeds does not necessarily mean that the event reached its destination
+ /// only that operation of writing it did not fail. These EventSources will not generate self-describing ETW events.
+ ///
+ /// For compatibility only use the EventSourceSettings.ThrowOnEventWriteErrors flag instead.
+ /// </summary>
+ // [Obsolete("Use the EventSource(EventSourceSettings) overload")]
+ protected EventSource(bool throwOnEventWriteErrors)
+ : this(EventSourceSettings.EtwManifestEventFormat | (throwOnEventWriteErrors ? EventSourceSettings.ThrowOnEventWriteErrors : 0))
+ { }
+
+ /// <summary>
+ /// Construct an EventSource with additional non-default settings (see EventSourceSettings for more)
+ /// </summary>
+ protected EventSource(EventSourceSettings settings) : this(settings, null) { }
+
+ /// <summary>
+ /// Construct an EventSource with additional non-default settings.
+ ///
+ /// Also specify a list of key-value pairs called traits (you must pass an even number of strings).
+ /// The first string is the key and the second is the value. These are not interpreted by EventSource
+ /// itself but may be interprated the listeners. Can be fetched with GetTrait(string).
+ /// </summary>
+ /// <param name="settings">See EventSourceSettings for more.</param>
+ /// <param name="traits">A collection of key-value strings (must be an even number).</param>
+ protected EventSource(EventSourceSettings settings, params string[] traits)
+ {
+ m_config = ValidateSettings(settings);
+
+ Guid eventSourceGuid;
+ string eventSourceName;
+
+ EventMetadata[] eventDescriptors;
+ byte[] manifest;
+ GetMetadata(out eventSourceGuid, out eventSourceName, out eventDescriptors, out manifest);
+
+ if (eventSourceGuid.Equals(Guid.Empty) || eventSourceName == null)
+ {
+ var myType = this.GetType();
+ eventSourceGuid = GetGuid(myType);
+ eventSourceName = GetName(myType);
+ }
+
+ Initialize(eventSourceGuid, eventSourceName, traits);
+ }
+
+ internal virtual void GetMetadata(out Guid eventSourceGuid, out string eventSourceName, out EventMetadata[] eventData, out byte[] manifestBytes)
+ {
+ //
+ // In ProjectN subclasses need to override this method, and return the data from their EventSourceAttribute and EventAttribute annotations.
+ // On other architectures it is a no-op.
+ //
+ // eventDescriptors needs to contain one EventDescriptor for each event; the event's ID should be the same as its index in this array.
+ // manifestBytes is a UTF-8 encoding of the ETW manifest for the type.
+ //
+ // This will be implemented by an IL rewriter, so we can't make this method abstract or the initial build of the subclass would fail.
+ //
+ eventSourceGuid = Guid.Empty;
+ eventSourceName = null;
+ eventData = null;
+ manifestBytes = null;
+
+ return;
+ }
+
+ /// <summary>
+ /// This method is called when the eventSource is updated by the controller.
+ /// </summary>
+ protected virtual void OnEventCommand(EventCommandEventArgs command) { }
+
+#pragma warning disable 1591
+ // optimized for common signatures (no args)
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId)
+ {
+ WriteEventCore(eventId, 0, null);
+ }
+
+ // optimized for common signatures (ints)
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, int arg1)
+ {
+ if (m_eventSourceEnabled)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[1];
+ descrs[0].DataPointer = (IntPtr)(&arg1);
+ descrs[0].Size = 4;
+ WriteEventCore(eventId, 1, descrs);
+ }
+ }
+
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, int arg1, int arg2)
+ {
+ if (m_eventSourceEnabled)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
+ descrs[0].DataPointer = (IntPtr)(&arg1);
+ descrs[0].Size = 4;
+ descrs[1].DataPointer = (IntPtr)(&arg2);
+ descrs[1].Size = 4;
+ WriteEventCore(eventId, 2, descrs);
+ }
+ }
+
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, int arg1, int arg2, int arg3)
+ {
+ if (m_eventSourceEnabled)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[3];
+ descrs[0].DataPointer = (IntPtr)(&arg1);
+ descrs[0].Size = 4;
+ descrs[1].DataPointer = (IntPtr)(&arg2);
+ descrs[1].Size = 4;
+ descrs[2].DataPointer = (IntPtr)(&arg3);
+ descrs[2].Size = 4;
+ WriteEventCore(eventId, 3, descrs);
+ }
+ }
+
+ // optimized for common signatures (longs)
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, long arg1)
+ {
+ if (m_eventSourceEnabled)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[1];
+ descrs[0].DataPointer = (IntPtr)(&arg1);
+ descrs[0].Size = 8;
+ WriteEventCore(eventId, 1, descrs);
+ }
+ }
+
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, long arg1, long arg2)
+ {
+ if (m_eventSourceEnabled)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
+ descrs[0].DataPointer = (IntPtr)(&arg1);
+ descrs[0].Size = 8;
+ descrs[1].DataPointer = (IntPtr)(&arg2);
+ descrs[1].Size = 8;
+ WriteEventCore(eventId, 2, descrs);
+ }
+ }
+
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, long arg1, long arg2, long arg3)
+ {
+ if (m_eventSourceEnabled)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[3];
+ descrs[0].DataPointer = (IntPtr)(&arg1);
+ descrs[0].Size = 8;
+ descrs[1].DataPointer = (IntPtr)(&arg2);
+ descrs[1].Size = 8;
+ descrs[2].DataPointer = (IntPtr)(&arg3);
+ descrs[2].Size = 8;
+ WriteEventCore(eventId, 3, descrs);
+ }
+ }
+
+ // optimized for common signatures (strings)
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, string arg1)
+ {
+ if (m_eventSourceEnabled)
+ {
+ if (arg1 == null) arg1 = "";
+ fixed (char* string1Bytes = arg1)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[1];
+ descrs[0].DataPointer = (IntPtr)string1Bytes;
+ descrs[0].Size = ((arg1.Length + 1) * 2);
+ WriteEventCore(eventId, 1, descrs);
+ }
+ }
+ }
+
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, string arg1, string arg2)
+ {
+ if (m_eventSourceEnabled)
+ {
+ if (arg1 == null) arg1 = "";
+ if (arg2 == null) arg2 = "";
+ fixed (char* string1Bytes = arg1)
+ fixed (char* string2Bytes = arg2)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
+ descrs[0].DataPointer = (IntPtr)string1Bytes;
+ descrs[0].Size = ((arg1.Length + 1) * 2);
+ descrs[1].DataPointer = (IntPtr)string2Bytes;
+ descrs[1].Size = ((arg2.Length + 1) * 2);
+ WriteEventCore(eventId, 2, descrs);
+ }
+ }
+ }
+
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, string arg1, string arg2, string arg3)
+ {
+ if (m_eventSourceEnabled)
+ {
+ if (arg1 == null) arg1 = "";
+ if (arg2 == null) arg2 = "";
+ if (arg3 == null) arg3 = "";
+ fixed (char* string1Bytes = arg1)
+ fixed (char* string2Bytes = arg2)
+ fixed (char* string3Bytes = arg3)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[3];
+ descrs[0].DataPointer = (IntPtr)string1Bytes;
+ descrs[0].Size = ((arg1.Length + 1) * 2);
+ descrs[1].DataPointer = (IntPtr)string2Bytes;
+ descrs[1].Size = ((arg2.Length + 1) * 2);
+ descrs[2].DataPointer = (IntPtr)string3Bytes;
+ descrs[2].Size = ((arg3.Length + 1) * 2);
+ WriteEventCore(eventId, 3, descrs);
+ }
+ }
+ }
+
+ // optimized for common signatures (string and ints)
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, string arg1, int arg2)
+ {
+ if (m_eventSourceEnabled)
+ {
+ if (arg1 == null) arg1 = "";
+ fixed (char* string1Bytes = arg1)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
+ descrs[0].DataPointer = (IntPtr)string1Bytes;
+ descrs[0].Size = ((arg1.Length + 1) * 2);
+ descrs[1].DataPointer = (IntPtr)(&arg2);
+ descrs[1].Size = 4;
+ WriteEventCore(eventId, 2, descrs);
+ }
+ }
+ }
+
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, string arg1, int arg2, int arg3)
+ {
+ if (m_eventSourceEnabled)
+ {
+ if (arg1 == null) arg1 = "";
+ fixed (char* string1Bytes = arg1)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[3];
+ descrs[0].DataPointer = (IntPtr)string1Bytes;
+ descrs[0].Size = ((arg1.Length + 1) * 2);
+ descrs[1].DataPointer = (IntPtr)(&arg2);
+ descrs[1].Size = 4;
+ descrs[2].DataPointer = (IntPtr)(&arg3);
+ descrs[2].Size = 4;
+ WriteEventCore(eventId, 3, descrs);
+ }
+ }
+ }
+
+ // optimized for common signatures (string and longs)
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, string arg1, long arg2)
+ {
+ if (m_eventSourceEnabled)
+ {
+ if (arg1 == null) arg1 = "";
+ fixed (char* string1Bytes = arg1)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
+ descrs[0].DataPointer = (IntPtr)string1Bytes;
+ descrs[0].Size = ((arg1.Length + 1) * 2);
+ descrs[1].DataPointer = (IntPtr)(&arg2);
+ descrs[1].Size = 8;
+ WriteEventCore(eventId, 2, descrs);
+ }
+ }
+ }
+
+ // optimized for common signatures (long and string)
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, long arg1, string arg2)
+ {
+ if (m_eventSourceEnabled)
+ {
+ if (arg2 == null) arg2 = "";
+ fixed (char* string2Bytes = arg2)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
+ descrs[0].DataPointer = (IntPtr)(&arg1);
+ descrs[0].Size = 8;
+ descrs[1].DataPointer = (IntPtr)string2Bytes;
+ descrs[1].Size = ((arg2.Length + 1) * 2);
+ WriteEventCore(eventId, 2, descrs);
+ }
+ }
+ }
+
+ // optimized for common signatures (int and string)
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, int arg1, string arg2)
+ {
+ if (m_eventSourceEnabled)
+ {
+ if (arg2 == null) arg2 = "";
+ fixed (char* string2Bytes = arg2)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
+ descrs[0].DataPointer = (IntPtr)(&arg1);
+ descrs[0].Size = 4;
+ descrs[1].DataPointer = (IntPtr)string2Bytes;
+ descrs[1].Size = ((arg2.Length + 1) * 2);
+ WriteEventCore(eventId, 2, descrs);
+ }
+ }
+ }
+
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, byte[] arg1)
+ {
+ if (m_eventSourceEnabled)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
+ if (arg1 == null || arg1.Length == 0)
+ {
+ int blobSize = 0;
+ descrs[0].DataPointer = (IntPtr)(&blobSize);
+ descrs[0].Size = 4;
+ descrs[1].DataPointer = (IntPtr)(&blobSize); // valid address instead of empty content
+ descrs[1].Size = 0;
+ WriteEventCore(eventId, 2, descrs);
+ }
+ else
+ {
+ int blobSize = arg1.Length;
+ fixed (byte* blob = &arg1[0])
+ {
+ descrs[0].DataPointer = (IntPtr)(&blobSize);
+ descrs[0].Size = 4;
+ descrs[1].DataPointer = (IntPtr)blob;
+ descrs[1].Size = blobSize;
+ WriteEventCore(eventId, 2, descrs);
+ }
+ }
+ }
+ }
+
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, long arg1, byte[] arg2)
+ {
+ if (m_eventSourceEnabled)
+ {
+ EventSource.EventData* descrs = stackalloc EventSource.EventData[3];
+ descrs[0].DataPointer = (IntPtr)(&arg1);
+ descrs[0].Size = 8;
+ if (arg2 == null || arg2.Length == 0)
+ {
+ int blobSize = 0;
+ descrs[1].DataPointer = (IntPtr)(&blobSize);
+ descrs[1].Size = 4;
+ descrs[2].DataPointer = (IntPtr)(&blobSize); // valid address instead of empty contents
+ descrs[2].Size = 0;
+ WriteEventCore(eventId, 3, descrs);
+ }
+ else
+ {
+ int blobSize = arg2.Length;
+ fixed (byte* blob = &arg2[0])
+ {
+ descrs[1].DataPointer = (IntPtr)(&blobSize);
+ descrs[1].Size = 4;
+ descrs[2].DataPointer = (IntPtr)blob;
+ descrs[2].Size = blobSize;
+ WriteEventCore(eventId, 3, descrs);
+ }
+ }
+ }
+ }
+
+#pragma warning restore 1591
+
+ /// <summary>
+ /// Used to construct the data structure to be passed to the native ETW APIs - EventWrite and EventWriteTransfer.
+ /// </summary>
+ protected internal struct EventData
+ {
+ /// <summary>
+ /// Address where the one argument lives (if this points to managed memory you must ensure the
+ /// managed object is pinned.
+ /// </summary>
+ public IntPtr DataPointer { get { return (IntPtr)m_Ptr; } set { m_Ptr = unchecked((long)value); } }
+ /// <summary>
+ /// Size of the argument referenced by DataPointer
+ /// </summary>
+ public int Size { get { return m_Size; } set { m_Size = value; } }
+
+ #region private
+ /// <summary>
+ /// Initializes the members of this EventData object to point at a previously-pinned
+ /// tracelogging-compatible metadata blob.
+ /// </summary>
+ /// <param name="pointer">Pinned tracelogging-compatible metadata blob.</param>
+ /// <param name="size">The size of the metadata blob.</param>
+ /// <param name="reserved">Value for reserved: 2 for per-provider metadata, 1 for per-event metadata</param>
+ internal unsafe void SetMetadata(byte* pointer, int size, int reserved)
+ {
+ this.m_Ptr = (long)(ulong)(UIntPtr)pointer;
+ this.m_Size = size;
+ this.m_Reserved = reserved; // Mark this descriptor as containing tracelogging-compatible metadata.
+ }
+
+ //Important, we pass this structure directly to the Win32 EventWrite API, so this structure must be layed out exactly
+ // the way EventWrite wants it.
+ internal long m_Ptr;
+ internal int m_Size;
+#pragma warning disable 0649
+ internal int m_Reserved; // Used to pad the size to match the Win32 API
+#pragma warning restore 0649
+ #endregion
+ }
+
+ /// <summary>
+ /// This routine allows you to create efficient WriteEvent helpers, however the code that you use to
+ /// do this, while straightforward, is unsafe.
+ /// </summary>
+ /// <remarks>
+ /// <code>
+ /// protected unsafe void WriteEvent(int eventId, string arg1, long arg2)
+ /// {
+ /// if (IsEnabled())
+ /// {
+ /// if (arg2 == null) arg2 = "";
+ /// fixed (char* string2Bytes = arg2)
+ /// {
+ /// EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
+ /// descrs[0].DataPointer = (IntPtr)(&amp;arg1);
+ /// descrs[0].Size = 8;
+ /// descrs[1].DataPointer = (IntPtr)string2Bytes;
+ /// descrs[1].Size = ((arg2.Length + 1) * 2);
+ /// WriteEventCore(eventId, 2, descrs);
+ /// }
+ /// }
+ /// }
+ /// </code>
+ /// </remarks>
+ [CLSCompliant(false)]
+ protected unsafe void WriteEventCore(int eventId, int eventDataCount, EventSource.EventData* data)
+ {
+ WriteEventWithRelatedActivityIdCore(eventId, null, eventDataCount, data);
+ }
+
+ /// <summary>
+ /// This routine allows you to create efficient WriteEventWithRelatedActivityId helpers, however the code
+ /// that you use to do this, while straightforward, is unsafe. The only difference from
+ /// <see cref="WriteEventCore"/> is that you pass the relatedActivityId from caller through to this API
+ /// </summary>
+ /// <remarks>
+ /// <code>
+ /// protected unsafe void WriteEventWithRelatedActivityId(int eventId, Guid relatedActivityId, string arg1, long arg2)
+ /// {
+ /// if (IsEnabled())
+ /// {
+ /// if (arg2 == null) arg2 = "";
+ /// fixed (char* string2Bytes = arg2)
+ /// {
+ /// EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
+ /// descrs[0].DataPointer = (IntPtr)(&amp;arg1);
+ /// descrs[0].Size = 8;
+ /// descrs[1].DataPointer = (IntPtr)string2Bytes;
+ /// descrs[1].Size = ((arg2.Length + 1) * 2);
+ /// WriteEventWithRelatedActivityIdCore(eventId, relatedActivityId, 2, descrs);
+ /// }
+ /// }
+ /// }
+ /// </code>
+ /// </remarks>
+ [CLSCompliant(false)]
+ protected unsafe void WriteEventWithRelatedActivityIdCore(int eventId, Guid* relatedActivityId, int eventDataCount, EventSource.EventData* data)
+ {
+ if (m_eventSourceEnabled)
+ {
+ try
+ {
+ Debug.Assert(m_eventData != null); // You must have initialized this if you enabled the source.
+ if (relatedActivityId != null)
+ ValidateEventOpcodeForTransfer(ref m_eventData[eventId], m_eventData[eventId].Name);
+
+ EventOpcode opcode = (EventOpcode)m_eventData[eventId].Descriptor.Opcode;
+ EventActivityOptions activityOptions = m_eventData[eventId].ActivityOptions;
+ Guid* pActivityId = null;
+ Guid activityId = Guid.Empty;
+ Guid relActivityId = Guid.Empty;
+
+ if (opcode != EventOpcode.Info && relatedActivityId == null &&
+ ((activityOptions & EventActivityOptions.Disable) == 0))
+ {
+ if (opcode == EventOpcode.Start)
+ {
+ m_activityTracker.OnStart(m_name, m_eventData[eventId].Name, m_eventData[eventId].Descriptor.Task, ref activityId, ref relActivityId, m_eventData[eventId].ActivityOptions);
+ }
+ else if (opcode == EventOpcode.Stop)
+ {
+ m_activityTracker.OnStop(m_name, m_eventData[eventId].Name, m_eventData[eventId].Descriptor.Task, ref activityId);
+ }
+
+ if (activityId != Guid.Empty)
+ pActivityId = &activityId;
+ if (relActivityId != Guid.Empty)
+ relatedActivityId = &relActivityId;
+ }
+
+#if FEATURE_MANAGED_ETW
+ if (m_eventData[eventId].EnabledForETW)
+ {
+
+#if FEATURE_ACTIVITYSAMPLING
+ // this code should be kept in sync with WriteEventVarargs().
+ SessionMask etwSessions = SessionMask.All;
+ // only compute etwSessions if there are *any* ETW filters enabled...
+ if ((ulong)m_curLiveSessions != 0)
+ etwSessions = GetEtwSessionMask(eventId, relatedActivityId);
+ // OutputDebugString(string.Format("{0}.WriteEvent(id {1}) -> to sessions {2:x}",
+ // m_name, m_eventData[eventId].Name, (ulong) etwSessions));
+
+ if ((ulong)etwSessions != 0 || m_legacySessions != null && m_legacySessions.Count > 0)
+ {
+ if (!SelfDescribingEvents)
+ {
+ if (etwSessions.IsEqualOrSupersetOf(m_curLiveSessions))
+ {
+ // OutputDebugString(string.Format(" (1) id {0}, kwd {1:x}",
+ // m_eventData[eventId].Name, m_eventData[eventId].Descriptor.Keywords));
+ // by default the Descriptor.Keyword will have the perEventSourceSessionId bit
+ // mask set to 0x0f so, when all ETW sessions want the event we don't need to
+ // synthesize a new one
+ if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, pActivityId, relatedActivityId, eventDataCount, (IntPtr)data))
+ ThrowEventSourceException(m_eventData[eventId].Name);
+ }
+ else
+ {
+ long origKwd = unchecked((long)((ulong)m_eventData[eventId].Descriptor.Keywords & ~(SessionMask.All.ToEventKeywords())));
+ // OutputDebugString(string.Format(" (2) id {0}, kwd {1:x}",
+ // m_eventData[eventId].Name, etwSessions.ToEventKeywords() | (ulong) origKwd));
+ // only some of the ETW sessions will receive this event. Synthesize a new
+ // Descriptor whose Keywords field will have the appropriate bits set.
+ // etwSessions might be 0, if there are legacy ETW listeners that want this event
+ var desc = new EventDescriptor(
+ m_eventData[eventId].Descriptor.EventId,
+ m_eventData[eventId].Descriptor.Version,
+ m_eventData[eventId].Descriptor.Channel,
+ m_eventData[eventId].Descriptor.Level,
+ m_eventData[eventId].Descriptor.Opcode,
+ m_eventData[eventId].Descriptor.Task,
+ unchecked((long)etwSessions.ToEventKeywords() | origKwd));
+
+ if (!m_provider.WriteEvent(ref desc, pActivityId, relatedActivityId, eventDataCount, (IntPtr)data))
+ ThrowEventSourceException(m_eventData[eventId].Name);
+ }
+ }
+ else
+ {
+ TraceLoggingEventTypes tlet = m_eventData[eventId].TraceLoggingEventTypes;
+ if (tlet == null)
+ {
+ tlet = new TraceLoggingEventTypes(m_eventData[eventId].Name,
+ EventTags.None,
+ m_eventData[eventId].Parameters);
+ Interlocked.CompareExchange(ref m_eventData[eventId].TraceLoggingEventTypes, tlet, null);
+
+ }
+ long origKwd = unchecked((long)((ulong)m_eventData[eventId].Descriptor.Keywords & ~(SessionMask.All.ToEventKeywords())));
+ // TODO: activity ID support
+ EventSourceOptions opt = new EventSourceOptions
+ {
+ Keywords = (EventKeywords)unchecked((long)etwSessions.ToEventKeywords() | origKwd),
+ Level = (EventLevel)m_eventData[eventId].Descriptor.Level,
+ Opcode = (EventOpcode)m_eventData[eventId].Descriptor.Opcode
+ };
+
+ WriteMultiMerge(m_eventData[eventId].Name, ref opt, tlet, pActivityId, relatedActivityId, data);
+ }
+ }
+#else
+ if (!SelfDescribingEvents)
+ {
+ if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, pActivityId, relatedActivityId, eventDataCount, (IntPtr)data))
+ ThrowEventSourceException(m_eventData[eventId].Name);
+ }
+ else
+ {
+ TraceLoggingEventTypes tlet = m_eventData[eventId].TraceLoggingEventTypes;
+ if (tlet == null)
+ {
+ tlet = new TraceLoggingEventTypes(m_eventData[eventId].Name,
+ m_eventData[eventId].Tags,
+ m_eventData[eventId].Parameters);
+ Interlocked.CompareExchange(ref m_eventData[eventId].TraceLoggingEventTypes, tlet, null);
+
+ }
+ EventSourceOptions opt = new EventSourceOptions
+ {
+ Keywords = (EventKeywords)m_eventData[eventId].Descriptor.Keywords,
+ Level = (EventLevel)m_eventData[eventId].Descriptor.Level,
+ Opcode = (EventOpcode)m_eventData[eventId].Descriptor.Opcode
+ };
+
+ WriteMultiMerge(m_eventData[eventId].Name, ref opt, tlet, pActivityId, relatedActivityId, data);
+ }
+#endif // FEATURE_ACTIVITYSAMPLING
+ }
+#endif // FEATURE_MANAGED_ETW
+
+ if (m_Dispatchers != null && m_eventData[eventId].EnabledForAnyListener)
+ WriteToAllListeners(eventId, relatedActivityId, eventDataCount, data);
+ }
+ catch (Exception ex)
+ {
+ if (ex is EventSourceException)
+ throw;
+ else
+ ThrowEventSourceException(m_eventData[eventId].Name, ex);
+ }
+ }
+ }
+
+ // fallback varags helpers.
+ /// <summary>
+ /// This is the varargs helper for writing an event. It does create an array and box all the arguments so it is
+ /// relatively inefficient and should only be used for relatively rare events (e.g. less than 100 / sec). If your
+ /// rates are faster than that you should use <see cref="WriteEventCore"/> to create fast helpers for your particular
+ /// method signature. Even if you use this for rare events, this call should be guarded by an <see cref="IsEnabled()"/>
+ /// check so that the varargs call is not made when the EventSource is not active.
+ /// </summary>
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ protected unsafe void WriteEvent(int eventId, params object[] args)
+ {
+ WriteEventVarargs(eventId, null, args);
+ }
+
+ /// <summary>
+ /// This is the varargs helper for writing an event which also specifies a related activity. It is completely analogous
+ /// to corresponding WriteEvent (they share implementation). It does create an array and box all the arguments so it is
+ /// relatively inefficient and should only be used for relatively rare events (e.g. less than 100 / sec). If your
+ /// rates are faster than that you should use <see cref="WriteEventWithRelatedActivityIdCore"/> to create fast helpers for your
+ /// particular method signature. Even if you use this for rare events, this call should be guarded by an <see cref="IsEnabled()"/>
+ /// check so that the varargs call is not made when the EventSource is not active.
+ /// </summary>
+ protected unsafe void WriteEventWithRelatedActivityId(int eventId, Guid relatedActivityId, params object[] args)
+ {
+ WriteEventVarargs(eventId, &relatedActivityId, args);
+ }
+
+ #endregion
+
+ #region IDisposable Members
+ /// <summary>
+ /// Disposes of an EventSource.
+ /// </summary>
+ public void Dispose()
+ {
+ this.Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ /// <summary>
+ /// Disposes of an EventSource.
+ /// </summary>
+ /// <remarks>
+ /// Called from Dispose() with disposing=true, and from the finalizer (~EventSource) with disposing=false.
+ /// Guidelines:
+ /// 1. We may be called more than once: do nothing after the first call.
+ /// 2. Avoid throwing exceptions if disposing is false, i.e. if we're being finalized.
+ /// </remarks>
+ /// <param name="disposing">True if called from Dispose(), false if called from the finalizer.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+#if FEATURE_MANAGED_ETW
+ // Send the manifest one more time to ensure circular buffers have a chance to get to this information
+ // even in scenarios with a high volume of ETW events.
+ if (m_eventSourceEnabled)
+ {
+ try
+ {
+ SendManifest(m_rawManifest);
+ }
+ catch (Exception)
+ { } // If it fails, simply give up.
+ m_eventSourceEnabled = false;
+ }
+ if (m_provider != null)
+ {
+ m_provider.Dispose();
+ m_provider = null;
+ }
+#endif
+ }
+ m_eventSourceEnabled = false;
+ m_eventSourceDisposed = true;
+ }
+ /// <summary>
+ /// Finalizer for EventSource
+ /// </summary>
+ ~EventSource()
+ {
+ this.Dispose(false);
+ }
+ #endregion
+
+ #region private
+#if FEATURE_ACTIVITYSAMPLING
+ internal void WriteStringToListener(EventListener listener, string msg, SessionMask m)
+ {
+ Debug.Assert(listener == null || (uint)m == (uint)SessionMask.FromId(0));
+
+ if (m_eventSourceEnabled)
+ {
+ if (listener == null)
+ {
+ WriteEventString(0, unchecked((long)m.ToEventKeywords()), msg);
+ }
+ else
+ {
+ EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this);
+ eventCallbackArgs.EventId = 0;
+ eventCallbackArgs.Message = msg;
+ eventCallbackArgs.Payload = new ReadOnlyCollection<object>(new List<object>() { msg });
+ eventCallbackArgs.PayloadNames = new ReadOnlyCollection<string>(new List<string> { "message" });
+ eventCallbackArgs.EventName = "EventSourceMessage";
+ listener.OnEventWritten(eventCallbackArgs);
+ }
+ }
+ }
+#endif
+
+ private unsafe void WriteEventRaw(
+ string eventName,
+ ref EventDescriptor eventDescriptor,
+ Guid* activityID,
+ Guid* relatedActivityID,
+ int dataCount,
+ IntPtr data)
+ {
+#if FEATURE_MANAGED_ETW
+ if (m_provider == null)
+ {
+ ThrowEventSourceException(eventName);
+ }
+ else
+ {
+ if (!m_provider.WriteEventRaw(ref eventDescriptor, activityID, relatedActivityID, dataCount, data))
+ ThrowEventSourceException(eventName);
+ }
+#endif // FEATURE_MANAGED_ETW
+ }
+
+ // FrameworkEventSource is on the startup path for the framework, so we have this internal overload that it can use
+ // to prevent the working set hit from looking at the custom attributes on the type to get the Guid.
+ internal EventSource(Guid eventSourceGuid, string eventSourceName)
+ : this(eventSourceGuid, eventSourceName, EventSourceSettings.EtwManifestEventFormat)
+ { }
+
+ // Used by the internal FrameworkEventSource constructor and the TraceLogging-style event source constructor
+ internal EventSource(Guid eventSourceGuid, string eventSourceName, EventSourceSettings settings, string[] traits = null)
+ {
+ m_config = ValidateSettings(settings);
+ Initialize(eventSourceGuid, eventSourceName, traits);
+ }
+
+ /// <summary>
+ /// This method is responsible for the common initialization path from our constructors. It must
+ /// not leak any exceptions (otherwise, since most EventSource classes define a static member,
+ /// "Log", such an exception would become a cached exception for the initialization of the static
+ /// member, and any future access to the "Log" would throw the cached exception).
+ /// </summary>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "guid")]
+ private unsafe void Initialize(Guid eventSourceGuid, string eventSourceName, string[] traits)
+ {
+ try
+ {
+ m_traits = traits;
+ if (m_traits != null && m_traits.Length % 2 != 0)
+ {
+ throw new ArgumentException(Resources.GetResourceString("TraitEven"), nameof(traits));
+ }
+
+ if (eventSourceGuid == Guid.Empty)
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_NeedGuid"));
+ }
+
+ if (eventSourceName == null)
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_NeedName"));
+ }
+
+ m_name = eventSourceName;
+ m_guid = eventSourceGuid;
+#if FEATURE_ACTIVITYSAMPLING
+ m_curLiveSessions = new SessionMask(0);
+ m_etwSessionIdMap = new EtwSession[SessionMask.MAX];
+#endif // FEATURE_ACTIVITYSAMPLING
+
+ //Enable Implicit Activity tracker
+ m_activityTracker = ActivityTracker.Instance;
+
+#if FEATURE_MANAGED_ETW
+ // Create and register our provider traits. We do this early because it is needed to log errors
+ // In the self-describing event case.
+ this.InitializeProviderMetadata();
+
+ // Register the provider with ETW
+ var provider = new OverideEventProvider(this);
+ provider.Register(eventSourceGuid);
+#endif
+ // Add the eventSource to the global (weak) list.
+ // This also sets m_id, which is the index in the list.
+ EventListener.AddEventSource(this);
+
+#if FEATURE_MANAGED_ETW
+ // OK if we get this far without an exception, then we can at least write out error messages.
+ // Set m_provider, which allows this.
+ m_provider = provider;
+
+#if (!ES_BUILD_STANDALONE && !ES_BUILD_PN)
+ // API available on OS >= Win 8 and patched Win 7.
+ // Disable only for FrameworkEventSource to avoid recursion inside exception handling.
+ if (this.Name != "System.Diagnostics.Eventing.FrameworkEventSource" || Environment.IsWindows8OrAbove)
+#endif
+ {
+ int setInformationResult;
+ System.Runtime.InteropServices.GCHandle metadataHandle =
+ System.Runtime.InteropServices.GCHandle.Alloc(this.providerMetadata, System.Runtime.InteropServices.GCHandleType.Pinned);
+ IntPtr providerMetadata = metadataHandle.AddrOfPinnedObject();
+
+ setInformationResult = m_provider.SetInformation(
+ UnsafeNativeMethods.ManifestEtw.EVENT_INFO_CLASS.SetTraits,
+ providerMetadata,
+ (uint)this.providerMetadata.Length);
+
+ metadataHandle.Free();
+ }
+#endif // FEATURE_MANAGED_ETW
+
+ Debug.Assert(!m_eventSourceEnabled); // We can't be enabled until we are completely initted.
+ // We are logically completely initialized at this point.
+ m_completelyInited = true;
+ }
+ catch (Exception e)
+ {
+ if (m_constructionException == null)
+ m_constructionException = e;
+ ReportOutOfBandMessage("ERROR: Exception during construction of EventSource " + Name + ": " + e.Message, true);
+ }
+
+ // Once m_completelyInited is set, you can have concurrency, so all work is under the lock.
+ lock (EventListener.EventListenersLock)
+ {
+ // If there are any deferred commands, we can do them now.
+ // This is the most likely place for exceptions to happen.
+ // Note that we are NOT resetting m_deferredCommands to NULL here,
+ // We are giving for EventHandler<EventCommandEventArgs> that will be attached later
+ EventCommandEventArgs deferredCommands = m_deferredCommands;
+ while (deferredCommands != null)
+ {
+ DoCommand(deferredCommands); // This can never throw, it catches them and reports the errors.
+ deferredCommands = deferredCommands.nextCommand;
+ }
+ }
+ }
+
+ private static string GetName(Type eventSourceType, EventManifestOptions flags)
+ {
+ if (eventSourceType == null)
+ throw new ArgumentNullException(nameof(eventSourceType));
+ Contract.EndContractBlock();
+
+ EventSourceAttribute attrib = (EventSourceAttribute)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute), flags);
+ if (attrib != null && attrib.Name != null)
+ return attrib.Name;
+
+ return eventSourceType.Name;
+ }
+
+ /// <summary>
+ /// Implements the SHA1 hashing algorithm. Note that this
+ /// implementation is for hashing public information. Do not
+ /// use this code to hash private data, as this implementation does
+ /// not take any steps to avoid information disclosure.
+ /// </summary>
+ private struct Sha1ForNonSecretPurposes
+ {
+ private long length; // Total message length in bits
+ private uint[] w; // Workspace
+ private int pos; // Length of current chunk in bytes
+
+ /// <summary>
+ /// Call Start() to initialize the hash object.
+ /// </summary>
+ public void Start()
+ {
+ if (this.w == null)
+ {
+ this.w = new uint[85];
+ }
+
+ this.length = 0;
+ this.pos = 0;
+ this.w[80] = 0x67452301;
+ this.w[81] = 0xEFCDAB89;
+ this.w[82] = 0x98BADCFE;
+ this.w[83] = 0x10325476;
+ this.w[84] = 0xC3D2E1F0;
+ }
+
+ /// <summary>
+ /// Adds an input byte to the hash.
+ /// </summary>
+ /// <param name="input">Data to include in the hash.</param>
+ public void Append(byte input)
+ {
+ this.w[this.pos / 4] = (this.w[this.pos / 4] << 8) | input;
+ if (64 == ++this.pos)
+ {
+ this.Drain();
+ }
+ }
+
+ /// <summary>
+ /// Adds input bytes to the hash.
+ /// </summary>
+ /// <param name="input">
+ /// Data to include in the hash. Must not be null.
+ /// </param>
+ public void Append(byte[] input)
+ {
+ foreach (var b in input)
+ {
+ this.Append(b);
+ }
+ }
+
+ /// <summary>
+ /// Retrieves the hash value.
+ /// Note that after calling this function, the hash object should
+ /// be considered uninitialized. Subsequent calls to Append or
+ /// Finish will produce useless results. Call Start() to
+ /// reinitialize.
+ /// </summary>
+ /// <param name="output">
+ /// Buffer to receive the hash value. Must not be null.
+ /// Up to 20 bytes of hash will be written to the output buffer.
+ /// If the buffer is smaller than 20 bytes, the remaining hash
+ /// bytes will be lost. If the buffer is larger than 20 bytes, the
+ /// rest of the buffer is left unmodified.
+ /// </param>
+ public void Finish(byte[] output)
+ {
+ long l = this.length + 8 * this.pos;
+ this.Append(0x80);
+ while (this.pos != 56)
+ {
+ this.Append(0x00);
+ }
+
+ unchecked
+ {
+ this.Append((byte)(l >> 56));
+ this.Append((byte)(l >> 48));
+ this.Append((byte)(l >> 40));
+ this.Append((byte)(l >> 32));
+ this.Append((byte)(l >> 24));
+ this.Append((byte)(l >> 16));
+ this.Append((byte)(l >> 8));
+ this.Append((byte)l);
+
+ int end = output.Length < 20 ? output.Length : 20;
+ for (int i = 0; i != end; i++)
+ {
+ uint temp = this.w[80 + i / 4];
+ output[i] = (byte)(temp >> 24);
+ this.w[80 + i / 4] = temp << 8;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Called when this.pos reaches 64.
+ /// </summary>
+ private void Drain()
+ {
+ for (int i = 16; i != 80; i++)
+ {
+ this.w[i] = Rol1((this.w[i - 3] ^ this.w[i - 8] ^ this.w[i - 14] ^ this.w[i - 16]));
+ }
+
+ unchecked
+ {
+ uint a = this.w[80];
+ uint b = this.w[81];
+ uint c = this.w[82];
+ uint d = this.w[83];
+ uint e = this.w[84];
+
+ for (int i = 0; i != 20; i++)
+ {
+ const uint k = 0x5A827999;
+ uint f = (b & c) | ((~b) & d);
+ uint temp = Rol5(a) + f + e + k + this.w[i]; e = d; d = c; c = Rol30(b); b = a; a = temp;
+ }
+
+ for (int i = 20; i != 40; i++)
+ {
+ uint f = b ^ c ^ d;
+ const uint k = 0x6ED9EBA1;
+ uint temp = Rol5(a) + f + e + k + this.w[i]; e = d; d = c; c = Rol30(b); b = a; a = temp;
+ }
+
+ for (int i = 40; i != 60; i++)
+ {
+ uint f = (b & c) | (b & d) | (c & d);
+ const uint k = 0x8F1BBCDC;
+ uint temp = Rol5(a) + f + e + k + this.w[i]; e = d; d = c; c = Rol30(b); b = a; a = temp;
+ }
+
+ for (int i = 60; i != 80; i++)
+ {
+ uint f = b ^ c ^ d;
+ const uint k = 0xCA62C1D6;
+ uint temp = Rol5(a) + f + e + k + this.w[i]; e = d; d = c; c = Rol30(b); b = a; a = temp;
+ }
+
+ this.w[80] += a;
+ this.w[81] += b;
+ this.w[82] += c;
+ this.w[83] += d;
+ this.w[84] += e;
+ }
+
+ this.length += 512; // 64 bytes == 512 bits
+ this.pos = 0;
+ }
+
+ private static uint Rol1(uint input)
+ {
+ return (input << 1) | (input >> 31);
+ }
+
+ private static uint Rol5(uint input)
+ {
+ return (input << 5) | (input >> 27);
+ }
+
+ private static uint Rol30(uint input)
+ {
+ return (input << 30) | (input >> 2);
+ }
+ }
+
+ private static Guid GenerateGuidFromName(string name)
+ {
+ byte[] bytes = Encoding.BigEndianUnicode.GetBytes(name);
+ var hash = new Sha1ForNonSecretPurposes();
+ hash.Start();
+ hash.Append(namespaceBytes);
+ hash.Append(bytes);
+ Array.Resize(ref bytes, 16);
+ hash.Finish(bytes);
+
+ bytes[7] = unchecked((byte)((bytes[7] & 0x0F) | 0x50)); // Set high 4 bits of octet 7 to 5, as per RFC 4122
+ return new Guid(bytes);
+ }
+
+ private unsafe object DecodeObject(int eventId, int parameterId, ref EventSource.EventData* data)
+ {
+ // TODO FIX : We use reflection which in turn uses EventSource, right now we carefully avoid
+ // the recursion, but can we do this in a robust way?
+
+ IntPtr dataPointer = data->DataPointer;
+ // advance to next EventData in array
+ ++data;
+
+ Type dataType = GetDataType(m_eventData[eventId], parameterId);
+
+ Again:
+ if (dataType == typeof(IntPtr))
+ {
+ return *((IntPtr*)dataPointer);
+ }
+ else if (dataType == typeof(int))
+ {
+ return *((int*)dataPointer);
+ }
+ else if (dataType == typeof(uint))
+ {
+ return *((uint*)dataPointer);
+ }
+ else if (dataType == typeof(long))
+ {
+ return *((long*)dataPointer);
+ }
+ else if (dataType == typeof(ulong))
+ {
+ return *((ulong*)dataPointer);
+ }
+ else if (dataType == typeof(byte))
+ {
+ return *((byte*)dataPointer);
+ }
+ else if (dataType == typeof(sbyte))
+ {
+ return *((sbyte*)dataPointer);
+ }
+ else if (dataType == typeof(short))
+ {
+ return *((short*)dataPointer);
+ }
+ else if (dataType == typeof(ushort))
+ {
+ return *((ushort*)dataPointer);
+ }
+ else if (dataType == typeof(float))
+ {
+ return *((float*)dataPointer);
+ }
+ else if (dataType == typeof(double))
+ {
+ return *((double*)dataPointer);
+ }
+ else if (dataType == typeof(decimal))
+ {
+ return *((decimal*)dataPointer);
+ }
+ else if (dataType == typeof(bool))
+ {
+ // The manifest defines a bool as a 32bit type (WIN32 BOOL), not 1 bit as CLR Does.
+ if (*((int*)dataPointer) == 1)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else if (dataType == typeof(Guid))
+ {
+ return *((Guid*)dataPointer);
+ }
+ else if (dataType == typeof(char))
+ {
+ return *((char*)dataPointer);
+ }
+ else if (dataType == typeof(DateTime))
+ {
+ long dateTimeTicks = *((long*)dataPointer);
+ return DateTime.FromFileTimeUtc(dateTimeTicks);
+ }
+ else if (dataType == typeof(byte[]))
+ {
+ // byte[] are written to EventData* as an int followed by a blob
+ int cbSize = *((int*)dataPointer);
+ byte[] blob = new byte[cbSize];
+ dataPointer = data->DataPointer;
+ data++;
+ for (int i = 0; i < cbSize; ++i)
+ blob[i] = *((byte*)(dataPointer + i));
+ return blob;
+ }
+ else if (dataType == typeof(byte*))
+ {
+ // TODO: how do we want to handle this? For now we ignore it...
+ return null;
+ }
+ else
+ {
+ if (m_EventSourcePreventRecursion && m_EventSourceInDecodeObject)
+ {
+ return null;
+ }
+
+ try
+ {
+ m_EventSourceInDecodeObject = true;
+
+ if (dataType.IsEnum())
+ {
+ dataType = Enum.GetUnderlyingType(dataType);
+ goto Again;
+ }
+
+
+ // Everything else is marshaled as a string.
+ // ETW strings are NULL-terminated, so marshal everything up to the first
+ // null in the string.
+ //return System.Runtime.InteropServices.Marshal.PtrToStringUni(dataPointer);
+ if(dataPointer == IntPtr.Zero)
+ {
+ return null;
+ }
+
+ return new string((char *)dataPointer);
+
+ }
+ finally
+ {
+ m_EventSourceInDecodeObject = false;
+ }
+ }
+ }
+
+ // Finds the Dispatcher (which holds the filtering state), for a given dispatcher for the current
+ // eventSource).
+ private EventDispatcher GetDispatcher(EventListener listener)
+ {
+ EventDispatcher dispatcher = m_Dispatchers;
+ while (dispatcher != null)
+ {
+ if (dispatcher.m_Listener == listener)
+ return dispatcher;
+ dispatcher = dispatcher.m_Next;
+ }
+ return dispatcher;
+ }
+
+ private unsafe void WriteEventVarargs(int eventId, Guid* childActivityID, object[] args)
+ {
+ if (m_eventSourceEnabled)
+ {
+ try
+ {
+ Debug.Assert(m_eventData != null); // You must have initialized this if you enabled the source.
+ if (childActivityID != null)
+ {
+ ValidateEventOpcodeForTransfer(ref m_eventData[eventId], m_eventData[eventId].Name);
+
+ // If you use WriteEventWithRelatedActivityID you MUST declare the first argument to be a GUID
+ // with the name 'relatedActivityID, and NOT pass this argument to the WriteEvent method.
+ // During manifest creation we modify the ParameterInfo[] that we store to strip out any
+ // first parameter that is of type Guid and named "relatedActivityId." Thus, if you call
+ // WriteEventWithRelatedActivityID from a method that doesn't name its first parameter correctly
+ // we can end up in a state where the ParameterInfo[] doesn't have its first parameter stripped,
+ // and this leads to a mismatch between the number of arguments and the number of ParameterInfos,
+ // which would cause a cryptic IndexOutOfRangeException later if we don't catch it here.
+ if (!m_eventData[eventId].HasRelatedActivityID)
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_NoRelatedActivityId"));
+ }
+ }
+
+ LogEventArgsMismatches(m_eventData[eventId].Parameters, args);
+
+ Guid* pActivityId = null;
+ Guid activityId = Guid.Empty;
+ Guid relatedActivityId = Guid.Empty;
+ EventOpcode opcode = (EventOpcode)m_eventData[eventId].Descriptor.Opcode;
+ EventActivityOptions activityOptions = m_eventData[eventId].ActivityOptions;
+
+ if (childActivityID == null &&
+ ((activityOptions & EventActivityOptions.Disable) == 0))
+ {
+ if (opcode == EventOpcode.Start)
+ {
+ m_activityTracker.OnStart(m_name, m_eventData[eventId].Name, m_eventData[eventId].Descriptor.Task, ref activityId, ref relatedActivityId, m_eventData[eventId].ActivityOptions);
+ }
+ else if (opcode == EventOpcode.Stop)
+ {
+ m_activityTracker.OnStop(m_name, m_eventData[eventId].Name, m_eventData[eventId].Descriptor.Task, ref activityId);
+ }
+
+ if (activityId != Guid.Empty)
+ pActivityId = &activityId;
+ if (relatedActivityId != Guid.Empty)
+ childActivityID = &relatedActivityId;
+ }
+
+#if FEATURE_MANAGED_ETW
+ if (m_eventData[eventId].EnabledForETW)
+ {
+#if FEATURE_ACTIVITYSAMPLING
+ // this code should be kept in sync with WriteEventWithRelatedActivityIdCore().
+ SessionMask etwSessions = SessionMask.All;
+ // only compute etwSessions if there are *any* ETW filters enabled...
+ if ((ulong)m_curLiveSessions != 0)
+ etwSessions = GetEtwSessionMask(eventId, childActivityID);
+
+ if ((ulong)etwSessions != 0 || m_legacySessions != null && m_legacySessions.Count > 0)
+ {
+ if (!SelfDescribingEvents)
+ {
+ if (etwSessions.IsEqualOrSupersetOf(m_curLiveSessions))
+ {
+ // by default the Descriptor.Keyword will have the perEventSourceSessionId bit
+ // mask set to 0x0f so, when all ETW sessions want the event we don't need to
+ // synthesize a new one
+ if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, pActivityId, childActivityID, args))
+ ThrowEventSourceException(m_eventData[eventId].Name);
+ }
+ else
+ {
+ long origKwd = unchecked((long)((ulong)m_eventData[eventId].Descriptor.Keywords & ~(SessionMask.All.ToEventKeywords())));
+ // only some of the ETW sessions will receive this event. Synthesize a new
+ // Descriptor whose Keywords field will have the appropriate bits set.
+ var desc = new EventDescriptor(
+ m_eventData[eventId].Descriptor.EventId,
+ m_eventData[eventId].Descriptor.Version,
+ m_eventData[eventId].Descriptor.Channel,
+ m_eventData[eventId].Descriptor.Level,
+ m_eventData[eventId].Descriptor.Opcode,
+ m_eventData[eventId].Descriptor.Task,
+ unchecked((long)etwSessions.ToEventKeywords() | origKwd));
+
+ if (!m_provider.WriteEvent(ref desc, pActivityId, childActivityID, args))
+ ThrowEventSourceException(m_eventData[eventId].Name);
+ }
+ }
+ else
+ {
+ TraceLoggingEventTypes tlet = m_eventData[eventId].TraceLoggingEventTypes;
+ if (tlet == null)
+ {
+ tlet = new TraceLoggingEventTypes(m_eventData[eventId].Name,
+ EventTags.None,
+ m_eventData[eventId].Parameters);
+ Interlocked.CompareExchange(ref m_eventData[eventId].TraceLoggingEventTypes, tlet, null);
+
+ }
+ long origKwd = unchecked((long)((ulong)m_eventData[eventId].Descriptor.Keywords & ~(SessionMask.All.ToEventKeywords())));
+ // TODO: activity ID support
+ EventSourceOptions opt = new EventSourceOptions
+ {
+ Keywords = (EventKeywords)unchecked((long)etwSessions.ToEventKeywords() | origKwd),
+ Level = (EventLevel)m_eventData[eventId].Descriptor.Level,
+ Opcode = (EventOpcode)m_eventData[eventId].Descriptor.Opcode
+ };
+
+ WriteMultiMerge(m_eventData[eventId].Name, ref opt, tlet, pActivityId, childActivityID, args);
+ }
+ }
+#else
+ if (!SelfDescribingEvents)
+ {
+ if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, pActivityId, childActivityID, args))
+ ThrowEventSourceException(m_eventData[eventId].Name);
+ }
+ else
+ {
+ TraceLoggingEventTypes tlet = m_eventData[eventId].TraceLoggingEventTypes;
+ if (tlet == null)
+ {
+ tlet = new TraceLoggingEventTypes(m_eventData[eventId].Name,
+ EventTags.None,
+ m_eventData[eventId].Parameters);
+ Interlocked.CompareExchange(ref m_eventData[eventId].TraceLoggingEventTypes, tlet, null);
+
+ }
+ // TODO: activity ID support
+ EventSourceOptions opt = new EventSourceOptions
+ {
+ Keywords = (EventKeywords)m_eventData[eventId].Descriptor.Keywords,
+ Level = (EventLevel)m_eventData[eventId].Descriptor.Level,
+ Opcode = (EventOpcode)m_eventData[eventId].Descriptor.Opcode
+ };
+
+ WriteMultiMerge(m_eventData[eventId].Name, ref opt, tlet, pActivityId, childActivityID, args);
+ }
+#endif // FEATURE_ACTIVITYSAMPLING
+ }
+#endif // FEATURE_MANAGED_ETW
+ if (m_Dispatchers != null && m_eventData[eventId].EnabledForAnyListener)
+ {
+#if (!ES_BUILD_STANDALONE && !ES_BUILD_PN)
+ // Maintain old behavior - object identity is preserved
+ if (AppContextSwitches.PreserveEventListnerObjectIdentity)
+ {
+ WriteToAllListeners(eventId, childActivityID, args);
+ }
+ else
+#endif // !ES_BUILD_STANDALONE
+ {
+ object[] serializedArgs = SerializeEventArgs(eventId, args);
+ WriteToAllListeners(eventId, childActivityID, serializedArgs);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ if (ex is EventSourceException)
+ throw;
+ else
+ ThrowEventSourceException(m_eventData[eventId].Name, ex);
+ }
+ }
+ }
+
+ unsafe private object[] SerializeEventArgs(int eventId, object[] args)
+ {
+ TraceLoggingEventTypes eventTypes = m_eventData[eventId].TraceLoggingEventTypes;
+ if (eventTypes == null)
+ {
+ eventTypes = new TraceLoggingEventTypes(m_eventData[eventId].Name,
+ EventTags.None,
+ m_eventData[eventId].Parameters);
+ Interlocked.CompareExchange(ref m_eventData[eventId].TraceLoggingEventTypes, eventTypes, null);
+ }
+ var eventData = new object[eventTypes.typeInfos.Length];
+ for (int i = 0; i < eventTypes.typeInfos.Length; i++)
+ {
+ eventData[i] = eventTypes.typeInfos[i].GetData(args[i]);
+ }
+ return eventData;
+ }
+
+ /// <summary>
+ /// We expect that the arguments to the Event method and the arguments to WriteEvent match. This function
+ /// checks that they in fact match and logs a warning to the debugger if they don't.
+ /// </summary>
+ /// <param name="infos"></param>
+ /// <param name="args"></param>
+ private void LogEventArgsMismatches(ParameterInfo[] infos, object[] args)
+ {
+#if (!ES_BUILD_PCL && !ES_BUILD_PN)
+ // It would be nice to have this on PCL builds, but it would be pointless since there isn't support for
+ // writing to the debugger log on PCL.
+ bool typesMatch = args.Length == infos.Length;
+
+ int i = 0;
+ while (typesMatch && i < args.Length)
+ {
+ Type pType = infos[i].ParameterType;
+
+ // Checking to see if the Parameter types (from the Event method) match the supplied argument types.
+ // Fail if one of two things hold : either the argument type is not equal to the parameter type, or the
+ // argument is null and the parameter type is non-nullable.
+ if ((args[i] != null && (args[i].GetType() != pType))
+ || (args[i] == null && (!(pType.IsGenericType && pType.GetGenericTypeDefinition() == typeof(Nullable<>))))
+ )
+ {
+ typesMatch = false;
+ break;
+ }
+
+ ++i;
+ }
+
+ if (!typesMatch)
+ {
+ System.Diagnostics.Debugger.Log(0, null, Resources.GetResourceString("EventSource_VarArgsParameterMismatch") + "\r\n");
+ }
+#endif //!ES_BUILD_PCL
+ }
+
+ private int GetParamLenghtIncludingByteArray(ParameterInfo[] parameters)
+ {
+ int sum = 0;
+ foreach (ParameterInfo info in parameters)
+ {
+ if (info.ParameterType == typeof(byte[]))
+ {
+ sum += 2;
+ }
+ else
+ {
+ sum++;
+ }
+ }
+
+ return sum;
+ }
+
+ unsafe private void WriteToAllListeners(int eventId, Guid* childActivityID, int eventDataCount, EventSource.EventData* data)
+ {
+ // We represent a byte[] as a integer denoting the length and then a blob of bytes in the data pointer. This causes a spurious
+ // warning because eventDataCount is off by one for the byte[] case since a byte[] has 2 items associated it. So we want to check
+ // that the number of parameters is correct against the byte[] case, but also we the args array would be one too long if
+ // we just used the modifiedParamCount here -- so we need both.
+ int paramCount = m_eventData[eventId].Parameters.Length;
+ int modifiedParamCount = GetParamLenghtIncludingByteArray(m_eventData[eventId].Parameters);
+ if (eventDataCount != modifiedParamCount)
+ {
+ ReportOutOfBandMessage(Resources.GetResourceString("EventSource_EventParametersMismatch", eventId, eventDataCount, paramCount), true);
+ paramCount = Math.Min(paramCount, eventDataCount);
+ }
+
+ object[] args = new object[paramCount];
+
+ EventSource.EventData* dataPtr = data;
+ for (int i = 0; i < paramCount; i++)
+ args[i] = DecodeObject(eventId, i, ref dataPtr);
+ WriteToAllListeners(eventId, childActivityID, args);
+ }
+
+ // helper for writing to all EventListeners attached the current eventSource.
+ unsafe private void WriteToAllListeners(int eventId, Guid* childActivityID, params object[] args)
+ {
+ EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this);
+ eventCallbackArgs.EventId = eventId;
+ if (childActivityID != null)
+ eventCallbackArgs.RelatedActivityId = *childActivityID;
+ eventCallbackArgs.EventName = m_eventData[eventId].Name;
+ eventCallbackArgs.Message = m_eventData[eventId].Message;
+ eventCallbackArgs.Payload = new ReadOnlyCollection<object>(args);
+
+ DispatchToAllListeners(eventId, childActivityID, eventCallbackArgs);
+ }
+
+ private unsafe void DispatchToAllListeners(int eventId, Guid* childActivityID, EventWrittenEventArgs eventCallbackArgs)
+ {
+ Exception lastThrownException = null;
+ for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next)
+ {
+ Debug.Assert(dispatcher.m_EventEnabled != null);
+ if (eventId == -1 || dispatcher.m_EventEnabled[eventId])
+ {
+#if FEATURE_ACTIVITYSAMPLING
+ var activityFilter = dispatcher.m_Listener.m_activityFilter;
+ // order below is important as PassesActivityFilter will "flow" active activities
+ // even when the current EventSource doesn't have filtering enabled. This allows
+ // interesting activities to be updated so that sources that do sample can get
+ // accurate data
+ if (activityFilter == null ||
+ ActivityFilter.PassesActivityFilter(activityFilter, childActivityID,
+ m_eventData[eventId].TriggersActivityTracking > 0,
+ this, eventId) ||
+ !dispatcher.m_activityFilteringEnabled)
+#endif // FEATURE_ACTIVITYSAMPLING
+ {
+ try
+ {
+ dispatcher.m_Listener.OnEventWritten(eventCallbackArgs);
+ }
+ catch (Exception e)
+ {
+ ReportOutOfBandMessage("ERROR: Exception during EventSource.OnEventWritten: "
+ + e.Message, false);
+ lastThrownException = e;
+ }
+ }
+ }
+ }
+
+ if (lastThrownException != null)
+ {
+ throw new EventSourceException(lastThrownException);
+ }
+ }
+
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ private unsafe void WriteEventString(EventLevel level, long keywords, string msgString)
+ {
+#if FEATURE_MANAGED_ETW
+ if (m_provider != null)
+ {
+ string eventName = "EventSourceMessage";
+ if (SelfDescribingEvents)
+ {
+ EventSourceOptions opt = new EventSourceOptions
+ {
+ Keywords = (EventKeywords)unchecked(keywords),
+ Level = level
+ };
+ var msg = new { message = msgString };
+ var tlet = new TraceLoggingEventTypes(eventName, EventTags.None, new Type[] { msg.GetType() });
+ WriteMultiMergeInner(eventName, ref opt, tlet, null, null, msg);
+ }
+ else
+ {
+ // We want the name of the provider to show up so if we don't have a manifest we create
+ // on that at least has the provider name (I don't define any events).
+ if (m_rawManifest == null && m_outOfBandMessageCount == 1)
+ {
+ ManifestBuilder manifestBuilder = new ManifestBuilder(Name, Guid, Name, null, EventManifestOptions.None);
+ manifestBuilder.StartEvent(eventName, new EventAttribute(0) { Level = EventLevel.LogAlways, Task = (EventTask)0xFFFE });
+ manifestBuilder.AddEventParameter(typeof(string), "message");
+ manifestBuilder.EndEvent();
+ SendManifest(manifestBuilder.CreateManifest());
+ }
+
+ // We use this low level routine to to bypass the enabled checking, since the eventSource itself is only partially inited.
+ fixed (char* msgStringPtr = msgString)
+ {
+ EventDescriptor descr = new EventDescriptor(0, 0, 0, (byte)level, 0, 0, keywords);
+ EventProvider.EventData data = new EventProvider.EventData();
+ data.Ptr = (ulong)msgStringPtr;
+ data.Size = (uint)(2 * (msgString.Length + 1));
+ data.Reserved = 0;
+ m_provider.WriteEvent(ref descr, null, null, 1, (IntPtr)((void*)&data));
+ }
+ }
+ }
+#endif // FEATURE_MANAGED_ETW
+ }
+
+ /// <summary>
+ /// Since this is a means of reporting errors (see ReportoutOfBandMessage) any failure encountered
+ /// while writing the message to any one of the listeners will be silently ignored.
+ /// </summary>
+ private void WriteStringToAllListeners(string eventName, string msg)
+ {
+ EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this);
+ eventCallbackArgs.EventId = 0;
+ eventCallbackArgs.Message = msg;
+ eventCallbackArgs.Payload = new ReadOnlyCollection<object>(new List<object>() { msg });
+ eventCallbackArgs.PayloadNames = new ReadOnlyCollection<string>(new List<string> { "message" });
+ eventCallbackArgs.EventName = eventName;
+
+ for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next)
+ {
+ bool dispatcherEnabled = false;
+ if (dispatcher.m_EventEnabled == null)
+ {
+ // if the listeners that weren't correctly initialized, we will send to it
+ // since this is an error message and we want to see it go out.
+ dispatcherEnabled = true;
+ }
+ else
+ {
+ // if there's *any* enabled event on the dispatcher we'll write out the string
+ // otherwise we'll treat the listener as disabled and skip it
+ for (int evtId = 0; evtId < dispatcher.m_EventEnabled.Length; ++evtId)
+ {
+ if (dispatcher.m_EventEnabled[evtId])
+ {
+ dispatcherEnabled = true;
+ break;
+ }
+ }
+ }
+ try
+ {
+ if (dispatcherEnabled)
+ dispatcher.m_Listener.OnEventWritten(eventCallbackArgs);
+ }
+ catch
+ {
+ // ignore any exceptions thrown by listeners' OnEventWritten
+ }
+ }
+ }
+
+#if FEATURE_ACTIVITYSAMPLING
+ unsafe private SessionMask GetEtwSessionMask(int eventId, Guid* childActivityID)
+ {
+ SessionMask etwSessions = new SessionMask();
+
+ for (int i = 0; i < SessionMask.MAX; ++i)
+ {
+ EtwSession etwSession = m_etwSessionIdMap[i];
+ if (etwSession != null)
+ {
+ ActivityFilter activityFilter = etwSession.m_activityFilter;
+ // PassesActivityFilter() will flow "interesting" activities, so make sure
+ // to perform this test first, before ORing with ~m_activityFilteringForETWEnabled
+ // (note: the first test for !m_activityFilteringForETWEnabled[i] ensures we
+ // do not fire events indiscriminately, when no filters are specified, but only
+ // if, in addition, the session did not also enable ActivitySampling)
+ if (activityFilter == null && !m_activityFilteringForETWEnabled[i] ||
+ activityFilter != null &&
+ ActivityFilter.PassesActivityFilter(activityFilter, childActivityID,
+ m_eventData[eventId].TriggersActivityTracking > 0, this, eventId) ||
+ !m_activityFilteringForETWEnabled[i])
+ {
+ etwSessions[i] = true;
+ }
+ }
+ }
+ // flow "interesting" activities for all legacy sessions in which there's some
+ // level of activity tracing enabled (even other EventSources)
+ if (m_legacySessions != null && m_legacySessions.Count > 0 &&
+ (EventOpcode)m_eventData[eventId].Descriptor.Opcode == EventOpcode.Send)
+ {
+ // only calculate InternalCurrentThreadActivityId once
+ Guid* pCurrentActivityId = null;
+ Guid currentActivityId;
+ foreach (var legacyEtwSession in m_legacySessions)
+ {
+ if (legacyEtwSession == null)
+ continue;
+
+ ActivityFilter activityFilter = legacyEtwSession.m_activityFilter;
+ if (activityFilter != null)
+ {
+ if (pCurrentActivityId == null)
+ {
+ currentActivityId = InternalCurrentThreadActivityId;
+ pCurrentActivityId = &currentActivityId;
+ }
+ ActivityFilter.FlowActivityIfNeeded(activityFilter, pCurrentActivityId, childActivityID);
+ }
+ }
+ }
+
+ return etwSessions;
+ }
+#endif // FEATURE_ACTIVITYSAMPLING
+
+ /// <summary>
+ /// Returns true if 'eventNum' is enabled if you only consider the level and matchAnyKeyword filters.
+ /// It is possible that eventSources turn off the event based on additional filtering criteria.
+ /// </summary>
+ private bool IsEnabledByDefault(int eventNum, bool enable, EventLevel currentLevel, EventKeywords currentMatchAnyKeyword)
+ {
+ if (!enable)
+ return false;
+
+ EventLevel eventLevel = (EventLevel)m_eventData[eventNum].Descriptor.Level;
+ EventKeywords eventKeywords = unchecked((EventKeywords)((ulong)m_eventData[eventNum].Descriptor.Keywords & (~(SessionMask.All.ToEventKeywords()))));
+
+#if FEATURE_MANAGED_ETW_CHANNELS
+ EventChannel channel = unchecked((EventChannel)m_eventData[eventNum].Descriptor.Channel);
+#else
+ EventChannel channel = EventChannel.None;
+#endif
+
+ return IsEnabledCommon(enable, currentLevel, currentMatchAnyKeyword, eventLevel, eventKeywords, channel);
+ }
+
+ private bool IsEnabledCommon(bool enabled, EventLevel currentLevel, EventKeywords currentMatchAnyKeyword,
+ EventLevel eventLevel, EventKeywords eventKeywords, EventChannel eventChannel)
+ {
+ if (!enabled)
+ return false;
+
+ // does is pass the level test?
+ if ((currentLevel != 0) && (currentLevel < eventLevel))
+ return false;
+
+ // if yes, does it pass the keywords test?
+ if (currentMatchAnyKeyword != 0 && eventKeywords != 0)
+ {
+#if FEATURE_MANAGED_ETW_CHANNELS
+ // is there a channel with keywords that match currentMatchAnyKeyword?
+ if (eventChannel != EventChannel.None && this.m_channelData != null && this.m_channelData.Length > (int)eventChannel)
+ {
+ EventKeywords channel_keywords = unchecked((EventKeywords)(m_channelData[(int)eventChannel] | (ulong)eventKeywords));
+ if (channel_keywords != 0 && (channel_keywords & currentMatchAnyKeyword) == 0)
+ return false;
+ }
+ else
+#endif
+ {
+ if ((unchecked((ulong)eventKeywords & (ulong)currentMatchAnyKeyword)) == 0)
+ return false;
+ }
+ }
+ return true;
+
+ }
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ private void ThrowEventSourceException(string eventName, Exception innerEx = null)
+ {
+ // If we fail during out of band logging we may end up trying
+ // to throw another EventSourceException, thus hitting a StackOverflowException.
+ // Avoid StackOverflow by making sure we do not recursively call this method.
+ if (m_EventSourceExceptionRecurenceCount > 0)
+ return;
+ try
+ {
+ m_EventSourceExceptionRecurenceCount++;
+
+ string errorPrefix = "EventSourceException";
+ if (eventName != null)
+ {
+ errorPrefix += " while processing event \"" + eventName + "\"";
+ }
+
+ // TODO Create variations of EventSourceException that indicate more information using the error code.
+ switch (EventProvider.GetLastWriteEventError())
+ {
+ case EventProvider.WriteEventErrorCode.EventTooBig:
+ ReportOutOfBandMessage(errorPrefix + ": " + Resources.GetResourceString("EventSource_EventTooBig"), true);
+ if (ThrowOnEventWriteErrors) throw new EventSourceException(Resources.GetResourceString("EventSource_EventTooBig"), innerEx);
+ break;
+ case EventProvider.WriteEventErrorCode.NoFreeBuffers:
+ ReportOutOfBandMessage(errorPrefix + ": " + Resources.GetResourceString("EventSource_NoFreeBuffers"), true);
+ if (ThrowOnEventWriteErrors) throw new EventSourceException(Resources.GetResourceString("EventSource_NoFreeBuffers"), innerEx);
+ break;
+ case EventProvider.WriteEventErrorCode.NullInput:
+ ReportOutOfBandMessage(errorPrefix + ": " + Resources.GetResourceString("EventSource_NullInput"), true);
+ if (ThrowOnEventWriteErrors) throw new EventSourceException(Resources.GetResourceString("EventSource_NullInput"), innerEx);
+ break;
+ case EventProvider.WriteEventErrorCode.TooManyArgs:
+ ReportOutOfBandMessage(errorPrefix + ": " + Resources.GetResourceString("EventSource_TooManyArgs"), true);
+ if (ThrowOnEventWriteErrors) throw new EventSourceException(Resources.GetResourceString("EventSource_TooManyArgs"), innerEx);
+ break;
+ default:
+ if (innerEx != null)
+ ReportOutOfBandMessage(errorPrefix + ": " + innerEx.GetType() + ":" + innerEx.Message, true);
+ else
+ ReportOutOfBandMessage(errorPrefix, true);
+ if (ThrowOnEventWriteErrors) throw new EventSourceException(innerEx);
+ break;
+ }
+ }
+ finally
+ {
+ m_EventSourceExceptionRecurenceCount--;
+ }
+ }
+
+ private void ValidateEventOpcodeForTransfer(ref EventMetadata eventData, string eventName)
+ {
+ if ((EventOpcode)eventData.Descriptor.Opcode != EventOpcode.Send &&
+ (EventOpcode)eventData.Descriptor.Opcode != EventOpcode.Receive &&
+ (EventOpcode)eventData.Descriptor.Opcode != EventOpcode.Start)
+ {
+ ThrowEventSourceException(eventName);
+ }
+ }
+
+ internal static EventOpcode GetOpcodeWithDefault(EventOpcode opcode, string eventName)
+ {
+ if (opcode == EventOpcode.Info && eventName != null)
+ {
+ if (eventName.EndsWith(s_ActivityStartSuffix, StringComparison.Ordinal))
+ {
+ return EventOpcode.Start;
+ }
+ else if (eventName.EndsWith(s_ActivityStopSuffix, StringComparison.Ordinal))
+ {
+ return EventOpcode.Stop;
+ }
+ }
+
+ return opcode;
+ }
+
+#if FEATURE_MANAGED_ETW
+ /// <summary>
+ /// This class lets us hook the 'OnEventCommand' from the eventSource.
+ /// </summary>
+ private class OverideEventProvider : EventProvider
+ {
+ public OverideEventProvider(EventSource eventSource)
+ {
+ this.m_eventSource = eventSource;
+ }
+ protected override void OnControllerCommand(ControllerCommand command, IDictionary<string, string> arguments,
+ int perEventSourceSessionId, int etwSessionId)
+ {
+ // We use null to represent the ETW EventListener.
+ EventListener listener = null;
+ m_eventSource.SendCommand(listener, perEventSourceSessionId, etwSessionId,
+ (EventCommand)command, IsEnabled(), Level, MatchAnyKeyword, arguments);
+ }
+ private EventSource m_eventSource;
+ }
+#endif
+
+ /// <summary>
+ /// Used to hold all the static information about an event. This includes everything in the event
+ /// descriptor as well as some stuff we added specifically for EventSource. see the
+ /// code:m_eventData for where we use this.
+ /// </summary>
+
+ /*
+ EventMetadata was public in the separate System.Diagnostics.Tracing assembly(pre NS2.0),
+ now the move to CoreLib marked them as private.
+ While they are technically private (it's a contract used between the library and the ILC toolchain),
+ we need them to be rooted and exported from shared library for the system to work.
+ For now I'm simply marking them as public again.A cleaner solution might be to use.rd.xml to
+ root them and modify shared library definition to force export them.
+ */
+#if ES_BUILD_PN
+ public
+#else
+ internal
+#endif
+ partial struct EventMetadata
+ {
+ public EventDescriptor Descriptor;
+ public EventTags Tags;
+ public bool EnabledForAnyListener; // true if any dispatcher has this event turned on
+ public bool EnabledForETW; // is this event on for the OS ETW data dispatcher?
+
+ public bool HasRelatedActivityID; // Set if the event method's first parameter is a Guid named 'relatedActivityId'
+#if !FEATURE_ACTIVITYSAMPLING
+#pragma warning disable 0649
+#endif
+ public byte TriggersActivityTracking; // count of listeners that marked this event as trigger for start of activity logging.
+#if !FEATURE_ACTIVITYSAMPLING
+#pragma warning restore 0649
+#endif
+ public string Name; // the name of the event
+ public string Message; // If the event has a message associated with it, this is it.
+ public ParameterInfo[] Parameters; // TODO can we remove?
+
+ public TraceLoggingEventTypes TraceLoggingEventTypes;
+ public EventActivityOptions ActivityOptions;
+
+#if ES_BUILD_PN
+ public EventParameterType[] ParameterTypes;
+#endif
+ };
+
+ // This is the internal entry point that code:EventListeners call when wanting to send a command to a
+ // eventSource. The logic is as follows
+ //
+ // * if Command == Update
+ // * perEventSourceSessionId specifies the per-provider ETW session ID that the command applies
+ // to (if listener != null)
+ // perEventSourceSessionId = 0 - reserved for EventListeners
+ // perEventSourceSessionId = 1..SessionMask.MAX - reserved for activity tracing aware ETW sessions
+ // perEventSourceSessionId-1 represents the bit in the reserved field (bits 44..47) in
+ // Keywords that identifies the session
+ // perEventSourceSessionId = SessionMask.MAX+1 - reserved for legacy ETW sessions; these are
+ // discriminated by etwSessionId
+ // * etwSessionId specifies a machine-wide ETW session ID; this allows correlation of
+ // activity tracing across different providers (which might have different sessionIds
+ // for the same ETW session)
+ // * enable, level, matchAnyKeywords are used to set a default for all events for the
+ // eventSource. In particular, if 'enabled' is false, 'level' and
+ // 'matchAnyKeywords' are not used.
+ // * OnEventCommand is invoked, which may cause calls to
+ // code:EventSource.EnableEventForDispatcher which may cause changes in the filtering
+ // depending on the logic in that routine.
+ // * else (command != Update)
+ // * Simply call OnEventCommand. The expectation is that filtering is NOT changed.
+ // * The 'enabled' 'level', matchAnyKeyword' arguments are ignored (must be true, 0, 0).
+ //
+ // dispatcher == null has special meaning. It is the 'ETW' dispatcher.
+ internal void SendCommand(EventListener listener, int perEventSourceSessionId, int etwSessionId,
+ EventCommand command, bool enable,
+ EventLevel level, EventKeywords matchAnyKeyword,
+ IDictionary<string, string> commandArguments)
+ {
+ var commandArgs = new EventCommandEventArgs(command, commandArguments, this, listener, perEventSourceSessionId, etwSessionId, enable, level, matchAnyKeyword);
+ lock (EventListener.EventListenersLock)
+ {
+ if (m_completelyInited)
+ {
+ // After the first command arrive after construction, we are ready to get rid of the deferred commands
+ this.m_deferredCommands = null;
+ // We are fully initialized, do the command
+ DoCommand(commandArgs);
+ }
+ else
+ {
+ // We can't do the command, simply remember it and we do it when we are fully constructed.
+ commandArgs.nextCommand = m_deferredCommands;
+ m_deferredCommands = commandArgs;
+ }
+ }
+ }
+
+ /// <summary>
+ /// We want the eventSource to be fully initialized when we do commands because that way we can send
+ /// error messages and other logging directly to the event stream. Unfortunately we can get callbacks
+ /// when we are not fully initialized. In that case we store them in 'commandArgs' and do them later.
+ /// This helper actually does all actual command logic.
+ /// </summary>
+ internal void DoCommand(EventCommandEventArgs commandArgs)
+ {
+ // PRECONDITION: We should be holding the EventListener.EventListenersLock
+ // We defer commands until we are completely inited. This allows error messages to be sent.
+ Debug.Assert(m_completelyInited);
+
+#if FEATURE_MANAGED_ETW
+ if (m_provider == null) // If we failed to construct
+ return;
+#endif // FEATURE_MANAGED_ETW
+
+ m_outOfBandMessageCount = 0;
+ bool shouldReport = (commandArgs.perEventSourceSessionId > 0) && (commandArgs.perEventSourceSessionId <= SessionMask.MAX);
+ try
+ {
+ EnsureDescriptorsInitialized();
+ Debug.Assert(m_eventData != null);
+
+ // Find the per-EventSource dispatcher corresponding to registered dispatcher
+ commandArgs.dispatcher = GetDispatcher(commandArgs.listener);
+ if (commandArgs.dispatcher == null && commandArgs.listener != null) // dispatcher == null means ETW dispatcher
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_ListenerNotFound"));
+ }
+
+ if (commandArgs.Arguments == null)
+ commandArgs.Arguments = new Dictionary<string, string>();
+
+ if (commandArgs.Command == EventCommand.Update)
+ {
+ // Set it up using the 'standard' filtering bitfields (use the "global" enable, not session specific one)
+ for (int i = 0; i < m_eventData.Length; i++)
+ EnableEventForDispatcher(commandArgs.dispatcher, i, IsEnabledByDefault(i, commandArgs.enable, commandArgs.level, commandArgs.matchAnyKeyword));
+
+ if (commandArgs.enable)
+ {
+ if (!m_eventSourceEnabled)
+ {
+ // EventSource turned on for the first time, simply copy the bits.
+ m_level = commandArgs.level;
+ m_matchAnyKeyword = commandArgs.matchAnyKeyword;
+ }
+ else
+ {
+ // Already enabled, make it the most verbose of the existing and new filter
+ if (commandArgs.level > m_level)
+ m_level = commandArgs.level;
+ if (commandArgs.matchAnyKeyword == 0)
+ m_matchAnyKeyword = 0;
+ else if (m_matchAnyKeyword != 0)
+ m_matchAnyKeyword = unchecked(m_matchAnyKeyword | commandArgs.matchAnyKeyword);
+ }
+ }
+
+ // interpret perEventSourceSessionId's sign, and adjust perEventSourceSessionId to
+ // represent 0-based positive values
+ bool bSessionEnable = (commandArgs.perEventSourceSessionId >= 0);
+ if (commandArgs.perEventSourceSessionId == 0 && commandArgs.enable == false)
+ bSessionEnable = false;
+
+ if (commandArgs.listener == null)
+ {
+ if (!bSessionEnable)
+ commandArgs.perEventSourceSessionId = -commandArgs.perEventSourceSessionId;
+ // for "global" enable/disable (passed in with listener == null and
+ // perEventSourceSessionId == 0) perEventSourceSessionId becomes -1
+ --commandArgs.perEventSourceSessionId;
+ }
+
+ commandArgs.Command = bSessionEnable ? EventCommand.Enable : EventCommand.Disable;
+
+ // perEventSourceSessionId = -1 when ETW sent a notification, but the set of active sessions
+ // hasn't changed.
+ // sesisonId = SessionMask.MAX when one of the legacy ETW sessions changed
+ // 0 <= perEventSourceSessionId < SessionMask.MAX for activity-tracing aware sessions
+ Debug.Assert(commandArgs.perEventSourceSessionId >= -1 && commandArgs.perEventSourceSessionId <= SessionMask.MAX);
+
+ // Send the manifest if we are enabling an ETW session
+ if (bSessionEnable && commandArgs.dispatcher == null)
+ {
+ // eventSourceDispatcher == null means this is the ETW manifest
+
+ // Note that we unconditionally send the manifest whenever we are enabled, even if
+ // we were already enabled. This is because there may be multiple sessions active
+ // and we can't know that all the sessions have seen the manifest.
+ if (!SelfDescribingEvents)
+ SendManifest(m_rawManifest);
+ }
+
+#if FEATURE_ACTIVITYSAMPLING
+ if (bSessionEnable && commandArgs.perEventSourceSessionId != -1)
+ {
+ bool participateInSampling = false;
+ string activityFilters;
+ int sessionIdBit;
+
+ ParseCommandArgs(commandArgs.Arguments, out participateInSampling,
+ out activityFilters, out sessionIdBit);
+
+ if (commandArgs.listener == null && commandArgs.Arguments.Count > 0 && commandArgs.perEventSourceSessionId != sessionIdBit)
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_SessionIdError",
+ commandArgs.perEventSourceSessionId + SessionMask.SHIFT_SESSION_TO_KEYWORD,
+ sessionIdBit + SessionMask.SHIFT_SESSION_TO_KEYWORD));
+ }
+
+ if (commandArgs.listener == null)
+ {
+ UpdateEtwSession(commandArgs.perEventSourceSessionId, commandArgs.etwSessionId, true, activityFilters, participateInSampling);
+ }
+ else
+ {
+ ActivityFilter.UpdateFilter(ref commandArgs.listener.m_activityFilter, this, 0, activityFilters);
+ commandArgs.dispatcher.m_activityFilteringEnabled = participateInSampling;
+ }
+ }
+ else if (!bSessionEnable && commandArgs.listener == null)
+ {
+ // if we disable an ETW session, indicate that in a synthesized command argument
+ if (commandArgs.perEventSourceSessionId >= 0 && commandArgs.perEventSourceSessionId < SessionMask.MAX)
+ {
+ commandArgs.Arguments["EtwSessionKeyword"] = (commandArgs.perEventSourceSessionId + SessionMask.SHIFT_SESSION_TO_KEYWORD).ToString(CultureInfo.InvariantCulture);
+ }
+ }
+#endif // FEATURE_ACTIVITYSAMPLING
+
+ // Turn on the enable bit before making the OnEventCommand callback This allows you to do useful
+ // things like log messages, or test if keywords are enabled in the callback.
+ if (commandArgs.enable)
+ {
+ Debug.Assert(m_eventData != null);
+ m_eventSourceEnabled = true;
+ }
+
+ this.OnEventCommand(commandArgs);
+ var eventCommandCallback = this.m_eventCommandExecuted;
+ if (eventCommandCallback != null)
+ eventCommandCallback(this, commandArgs);
+
+#if FEATURE_ACTIVITYSAMPLING
+ if (commandArgs.listener == null && !bSessionEnable && commandArgs.perEventSourceSessionId != -1)
+ {
+ // if we disable an ETW session, complete disabling it
+ UpdateEtwSession(commandArgs.perEventSourceSessionId, commandArgs.etwSessionId, false, null, false);
+ }
+#endif // FEATURE_ACTIVITYSAMPLING
+
+ if (!commandArgs.enable)
+ {
+ // If we are disabling, maybe we can turn on 'quick checks' to filter
+ // quickly. These are all just optimizations (since later checks will still filter)
+
+#if FEATURE_ACTIVITYSAMPLING
+ // Turn off (and forget) any information about Activity Tracing.
+ if (commandArgs.listener == null)
+ {
+ // reset all filtering information for activity-tracing-aware sessions
+ for (int i = 0; i < SessionMask.MAX; ++i)
+ {
+ EtwSession etwSession = m_etwSessionIdMap[i];
+ if (etwSession != null)
+ ActivityFilter.DisableFilter(ref etwSession.m_activityFilter, this);
+ }
+ m_activityFilteringForETWEnabled = new SessionMask(0);
+ m_curLiveSessions = new SessionMask(0);
+ // reset activity-tracing-aware sessions
+ if (m_etwSessionIdMap != null)
+ for (int i = 0; i < SessionMask.MAX; ++i)
+ m_etwSessionIdMap[i] = null;
+ // reset legacy sessions
+ if (m_legacySessions != null)
+ m_legacySessions.Clear();
+ }
+ else
+ {
+ ActivityFilter.DisableFilter(ref commandArgs.listener.m_activityFilter, this);
+ commandArgs.dispatcher.m_activityFilteringEnabled = false;
+ }
+#endif // FEATURE_ACTIVITYSAMPLING
+
+ // There is a good chance EnabledForAnyListener are not as accurate as
+ // they could be, go ahead and get a better estimate.
+ for (int i = 0; i < m_eventData.Length; i++)
+ {
+ bool isEnabledForAnyListener = false;
+ for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next)
+ {
+ if (dispatcher.m_EventEnabled[i])
+ {
+ isEnabledForAnyListener = true;
+ break;
+ }
+ }
+ m_eventData[i].EnabledForAnyListener = isEnabledForAnyListener;
+ }
+
+ // If no events are enabled, disable the global enabled bit.
+ if (!AnyEventEnabled())
+ {
+ m_level = 0;
+ m_matchAnyKeyword = 0;
+ m_eventSourceEnabled = false;
+ }
+ }
+#if FEATURE_ACTIVITYSAMPLING
+ UpdateKwdTriggers(commandArgs.enable);
+#endif // FEATURE_ACTIVITYSAMPLING
+ }
+ else
+ {
+ if (commandArgs.Command == EventCommand.SendManifest)
+ {
+ // TODO: should we generate the manifest here if we hadn't already?
+ if (m_rawManifest != null)
+ SendManifest(m_rawManifest);
+ }
+
+ // These are not used for non-update commands and thus should always be 'default' values
+ // Debug.Assert(enable == true);
+ // Debug.Assert(level == EventLevel.LogAlways);
+ // Debug.Assert(matchAnyKeyword == EventKeywords.None);
+
+ this.OnEventCommand(commandArgs);
+ var eventCommandCallback = m_eventCommandExecuted;
+ if (eventCommandCallback != null)
+ eventCommandCallback(this, commandArgs);
+ }
+
+#if FEATURE_ACTIVITYSAMPLING
+ if (m_completelyInited && (commandArgs.listener != null || shouldReport))
+ {
+ SessionMask m = SessionMask.FromId(commandArgs.perEventSourceSessionId);
+ ReportActivitySamplingInfo(commandArgs.listener, m);
+ }
+#endif // FEATURE_ACTIVITYSAMPLING
+ }
+ catch (Exception e)
+ {
+ // When the ETW session is created after the EventSource has registered with the ETW system
+ // we can send any error messages here.
+ ReportOutOfBandMessage("ERROR: Exception in Command Processing for EventSource " + Name + ": " + e.Message, true);
+ // We never throw when doing a command.
+ }
+ }
+
+#if FEATURE_ACTIVITYSAMPLING
+
+ internal void UpdateEtwSession(
+ int sessionIdBit,
+ int etwSessionId,
+ bool bEnable,
+ string activityFilters,
+ bool participateInSampling)
+ {
+ if (sessionIdBit < SessionMask.MAX)
+ {
+ // activity-tracing-aware etw session
+ if (bEnable)
+ {
+ var etwSession = EtwSession.GetEtwSession(etwSessionId, true);
+ ActivityFilter.UpdateFilter(ref etwSession.m_activityFilter, this, sessionIdBit, activityFilters);
+ m_etwSessionIdMap[sessionIdBit] = etwSession;
+ m_activityFilteringForETWEnabled[sessionIdBit] = participateInSampling;
+ }
+ else
+ {
+ var etwSession = EtwSession.GetEtwSession(etwSessionId);
+ m_etwSessionIdMap[sessionIdBit] = null;
+ m_activityFilteringForETWEnabled[sessionIdBit] = false;
+ if (etwSession != null)
+ {
+ ActivityFilter.DisableFilter(ref etwSession.m_activityFilter, this);
+ // the ETW session is going away; remove it from the global list
+ EtwSession.RemoveEtwSession(etwSession);
+ }
+ }
+ m_curLiveSessions[sessionIdBit] = bEnable;
+ }
+ else
+ {
+ // legacy etw session
+ if (bEnable)
+ {
+ if (m_legacySessions == null)
+ m_legacySessions = new List<EtwSession>(8);
+ var etwSession = EtwSession.GetEtwSession(etwSessionId, true);
+ if (!m_legacySessions.Contains(etwSession))
+ m_legacySessions.Add(etwSession);
+ }
+ else
+ {
+ var etwSession = EtwSession.GetEtwSession(etwSessionId);
+ if (etwSession != null)
+ {
+ if (m_legacySessions != null)
+ m_legacySessions.Remove(etwSession);
+ // the ETW session is going away; remove it from the global list
+ EtwSession.RemoveEtwSession(etwSession);
+ }
+ }
+ }
+ }
+
+ internal static bool ParseCommandArgs(
+ IDictionary<string, string> commandArguments,
+ out bool participateInSampling,
+ out string activityFilters,
+ out int sessionIdBit)
+ {
+ bool res = true;
+ participateInSampling = false;
+ string activityFilterString;
+ if (commandArguments.TryGetValue("ActivitySamplingStartEvent", out activityFilters))
+ {
+ // if a start event is specified default the event source to participate in sampling
+ participateInSampling = true;
+ }
+
+ if (commandArguments.TryGetValue("ActivitySampling", out activityFilterString))
+ {
+ if (string.Compare(activityFilterString, "false", StringComparison.OrdinalIgnoreCase) == 0 ||
+ activityFilterString == "0")
+ participateInSampling = false;
+ else
+ participateInSampling = true;
+ }
+
+ string sSessionKwd;
+ int sessionKwd = -1;
+ if (!commandArguments.TryGetValue("EtwSessionKeyword", out sSessionKwd) ||
+ !int.TryParse(sSessionKwd, out sessionKwd) ||
+ sessionKwd < SessionMask.SHIFT_SESSION_TO_KEYWORD ||
+ sessionKwd >= SessionMask.SHIFT_SESSION_TO_KEYWORD + SessionMask.MAX)
+ {
+ sessionIdBit = -1;
+ res = false;
+ }
+ else
+ {
+ sessionIdBit = sessionKwd - SessionMask.SHIFT_SESSION_TO_KEYWORD;
+ }
+ return res;
+ }
+
+ internal void UpdateKwdTriggers(bool enable)
+ {
+ if (enable)
+ {
+ // recompute m_keywordTriggers
+ ulong gKeywords = unchecked((ulong)m_matchAnyKeyword);
+ if (gKeywords == 0)
+ gKeywords = 0xFFFFffffFFFFffff;
+
+ m_keywordTriggers = 0;
+ for (int sessId = 0; sessId < SessionMask.MAX; ++sessId)
+ {
+ EtwSession etwSession = m_etwSessionIdMap[sessId];
+ if (etwSession == null)
+ continue;
+
+ ActivityFilter activityFilter = etwSession.m_activityFilter;
+ ActivityFilter.UpdateKwdTriggers(activityFilter, m_guid, this, unchecked((EventKeywords)gKeywords));
+ }
+ }
+ else
+ {
+ m_keywordTriggers = 0;
+ }
+ }
+
+#endif // FEATURE_ACTIVITYSAMPLING
+
+ /// <summary>
+ /// If 'value is 'true' then set the eventSource so that 'dispatcher' will receive event with the eventId
+ /// of 'eventId. If value is 'false' disable the event for that dispatcher. If 'eventId' is out of
+ /// range return false, otherwise true.
+ /// </summary>
+ internal bool EnableEventForDispatcher(EventDispatcher dispatcher, int eventId, bool value)
+ {
+ if (dispatcher == null)
+ {
+ if (eventId >= m_eventData.Length)
+ return false;
+#if FEATURE_MANAGED_ETW
+ if (m_provider != null)
+ m_eventData[eventId].EnabledForETW = value;
+#endif
+ }
+ else
+ {
+ if (eventId >= dispatcher.m_EventEnabled.Length)
+ return false;
+ dispatcher.m_EventEnabled[eventId] = value;
+ if (value)
+ m_eventData[eventId].EnabledForAnyListener = true;
+ }
+ return true;
+ }
+
+ /// <summary>
+ /// Returns true if any event at all is on.
+ /// </summary>
+ private bool AnyEventEnabled()
+ {
+ for (int i = 0; i < m_eventData.Length; i++)
+ if (m_eventData[i].EnabledForETW || m_eventData[i].EnabledForAnyListener)
+ return true;
+ return false;
+ }
+
+ private bool IsDisposed
+ {
+ get { return m_eventSourceDisposed; }
+ }
+
+ private void EnsureDescriptorsInitialized()
+ {
+#if !ES_BUILD_STANDALONE
+ Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
+#endif
+ if (m_eventData == null)
+ {
+ Guid eventSourceGuid = Guid.Empty;
+ string eventSourceName = null;
+ EventMetadata[] eventData = null;
+ byte[] manifest = null;
+
+ // Try the GetMetadata provided by the ILTransform in ProjectN. The default sets all to null, and in that case we fall back
+ // to the reflection approach.
+ GetMetadata(out eventSourceGuid, out eventSourceName, out eventData, out manifest);
+
+ if (eventSourceGuid.Equals(Guid.Empty) || eventSourceName == null || eventData == null || manifest == null)
+ {
+ // GetMetadata failed, so we have to set it via reflection.
+ Debug.Assert(m_rawManifest == null);
+ m_rawManifest = CreateManifestAndDescriptors(this.GetType(), Name, this);
+ Debug.Assert(m_eventData != null);
+
+ }
+ else
+ {
+ // GetMetadata worked, so set the fields as appropriate.
+ m_name = eventSourceName;
+ m_guid = eventSourceGuid;
+ m_eventData = eventData;
+ m_rawManifest = manifest;
+ }
+ // TODO Enforce singleton pattern
+ foreach (WeakReference eventSourceRef in EventListener.s_EventSources)
+ {
+ EventSource eventSource = eventSourceRef.Target as EventSource;
+ if (eventSource != null && eventSource.Guid == m_guid && !eventSource.IsDisposed)
+ {
+ if (eventSource != this)
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_EventSourceGuidInUse", m_guid));
+ }
+ }
+ }
+
+ // Make certain all dispatchers also have their arrays initialized
+ EventDispatcher dispatcher = m_Dispatchers;
+ while (dispatcher != null)
+ {
+ if (dispatcher.m_EventEnabled == null)
+ dispatcher.m_EventEnabled = new bool[m_eventData.Length];
+ dispatcher = dispatcher.m_Next;
+ }
+ }
+ if (s_currentPid == 0)
+ {
+#if ES_BUILD_STANDALONE && !ES_BUILD_PCL && !CORECLR
+ // for non-BCL EventSource we must assert SecurityPermission
+ new SecurityPermission(PermissionState.Unrestricted).Assert();
+#endif
+ s_currentPid = Win32Native.GetCurrentProcessId();
+ }
+ }
+
+ // Send out the ETW manifest XML out to ETW
+ // Today, we only send the manifest to ETW, custom listeners don't get it.
+ private unsafe bool SendManifest(byte[] rawManifest)
+ {
+ bool success = true;
+
+ if (rawManifest == null)
+ return false;
+
+ Debug.Assert(!SelfDescribingEvents);
+
+#if FEATURE_MANAGED_ETW
+ fixed (byte* dataPtr = rawManifest)
+ {
+ // we don't want the manifest to show up in the event log channels so we specify as keywords
+ // everything but the first 8 bits (reserved for the 8 channels)
+ var manifestDescr = new EventDescriptor(0xFFFE, 1, 0, 0, 0xFE, 0xFFFE, 0x00ffFFFFffffFFFF);
+ ManifestEnvelope envelope = new ManifestEnvelope();
+
+ envelope.Format = ManifestEnvelope.ManifestFormats.SimpleXmlFormat;
+ envelope.MajorVersion = 1;
+ envelope.MinorVersion = 0;
+ envelope.Magic = 0x5B; // An unusual number that can be checked for consistency.
+ int dataLeft = rawManifest.Length;
+ envelope.ChunkNumber = 0;
+
+ EventProvider.EventData* dataDescrs = stackalloc EventProvider.EventData[2];
+
+ dataDescrs[0].Ptr = (ulong)&envelope;
+ dataDescrs[0].Size = (uint)sizeof(ManifestEnvelope);
+ dataDescrs[0].Reserved = 0;
+
+ dataDescrs[1].Ptr = (ulong)dataPtr;
+ dataDescrs[1].Reserved = 0;
+
+ int chunkSize = ManifestEnvelope.MaxChunkSize;
+ TRY_AGAIN_WITH_SMALLER_CHUNK_SIZE:
+ envelope.TotalChunks = (ushort)((dataLeft + (chunkSize - 1)) / chunkSize);
+ while (dataLeft > 0)
+ {
+ dataDescrs[1].Size = (uint)Math.Min(dataLeft, chunkSize);
+ if (m_provider != null)
+ {
+ if (!m_provider.WriteEvent(ref manifestDescr, null, null, 2, (IntPtr)dataDescrs))
+ {
+ // Turns out that if users set the BufferSize to something less than 64K then WriteEvent
+ // can fail. If we get this failure on the first chunk try again with something smaller
+ // The smallest BufferSize is 1K so if we get to 256 (to account for envelope overhead), we can give up making it smaller.
+ if (EventProvider.GetLastWriteEventError() == EventProvider.WriteEventErrorCode.EventTooBig)
+ {
+ if (envelope.ChunkNumber == 0 && chunkSize > 256)
+ {
+ chunkSize = chunkSize / 2;
+ goto TRY_AGAIN_WITH_SMALLER_CHUNK_SIZE;
+ }
+ }
+ success = false;
+ if (ThrowOnEventWriteErrors)
+ ThrowEventSourceException("SendManifest");
+ break;
+ }
+ }
+ dataLeft -= chunkSize;
+ dataDescrs[1].Ptr += (uint)chunkSize;
+ envelope.ChunkNumber++;
+
+ // For large manifests we want to not overflow any receiver's buffer. Most manifests will fit within
+ // 5 chunks, so only the largest manifests will hit the pause.
+ if ((envelope.ChunkNumber % 5) == 0)
+ {
+ RuntimeThread.Sleep(15);
+ }
+ }
+ }
+#endif // FEATURE_MANAGED_ETW
+ return success;
+ }
+
+#if (ES_BUILD_PCL)
+ internal static Attribute GetCustomAttributeHelper(Type type, Type attributeType, EventManifestOptions flags = EventManifestOptions.None)
+ {
+ return GetCustomAttributeHelper(type.GetTypeInfo(), attributeType, flags);
+ }
+#endif
+
+ // Helper to deal with the fact that the type we are reflecting over might be loaded in the ReflectionOnly context.
+ // When that is the case, we have the build the custom assemblies on a member by hand.
+ internal static Attribute GetCustomAttributeHelper(MemberInfo member, Type attributeType, EventManifestOptions flags = EventManifestOptions.None)
+ {
+ if (!member.Module.Assembly.ReflectionOnly() && (flags & EventManifestOptions.AllowEventSourceOverride) == 0)
+ {
+ // Let the runtime to the work for us, since we can execute code in this context.
+ Attribute firstAttribute = null;
+ foreach (var attribute in member.GetCustomAttributes(attributeType, false))
+ {
+ firstAttribute = (Attribute)attribute;
+ break;
+ }
+ return firstAttribute;
+ }
+
+#if (!ES_BUILD_PCL && !ES_BUILD_PN)
+ // In the reflection only context, we have to do things by hand.
+ string fullTypeNameToFind = attributeType.FullName;
+
+#if EVENT_SOURCE_LEGACY_NAMESPACE_SUPPORT
+ fullTypeNameToFind = fullTypeNameToFind.Replace("System.Diagnostics.Eventing", "System.Diagnostics.Tracing");
+#endif
+
+ foreach (CustomAttributeData data in CustomAttributeData.GetCustomAttributes(member))
+ {
+ if (AttributeTypeNamesMatch(attributeType, data.Constructor.ReflectedType))
+ {
+ Attribute attr = null;
+
+ Debug.Assert(data.ConstructorArguments.Count <= 1);
+
+ if (data.ConstructorArguments.Count == 1)
+ {
+ attr = (Attribute)Activator.CreateInstance(attributeType, new object[] { data.ConstructorArguments[0].Value });
+ }
+ else if (data.ConstructorArguments.Count == 0)
+ {
+ attr = (Attribute)Activator.CreateInstance(attributeType);
+ }
+
+ if (attr != null)
+ {
+ Type t = attr.GetType();
+
+ foreach (CustomAttributeNamedArgument namedArgument in data.NamedArguments)
+ {
+ PropertyInfo p = t.GetProperty(namedArgument.MemberInfo.Name, BindingFlags.Public | BindingFlags.Instance);
+ object value = namedArgument.TypedValue.Value;
+
+ if (p.PropertyType.IsEnum)
+ {
+ value = Enum.Parse(p.PropertyType, value.ToString());
+ }
+
+ p.SetValue(attr, value, null);
+ }
+
+ return attr;
+ }
+ }
+ }
+
+ return null;
+#else // ES_BUILD_PCL && ES_BUILD_PN
+ // Don't use nameof here because the resource doesn't exist on some platforms, which results in a compilation error.
+ throw new ArgumentException(Resources.GetResourceString("EventSource", "EventSource_PCLPlatformNotSupportedReflection"));
+#endif
+ }
+
+ /// <summary>
+ /// Evaluates if two related "EventSource"-domain types should be considered the same
+ /// </summary>
+ /// <param name="attributeType">The attribute type in the load context - it's associated with the running
+ /// EventSource type. This type may be different fromt he base type of the user-defined EventSource.</param>
+ /// <param name="reflectedAttributeType">The attribute type in the reflection context - it's associated with
+ /// the user-defined EventSource, and is in the same assembly as the eventSourceType passed to
+ /// </param>
+ /// <returns>True - if the types should be considered equivalent, False - otherwise</returns>
+ private static bool AttributeTypeNamesMatch(Type attributeType, Type reflectedAttributeType)
+ {
+ return
+ // are these the same type?
+ attributeType == reflectedAttributeType ||
+ // are the full typenames equal?
+ string.Equals(attributeType.FullName, reflectedAttributeType.FullName, StringComparison.Ordinal) ||
+ // are the typenames equal and the namespaces under "Diagnostics.Tracing" (typically
+ // either Microsoft.Diagnostics.Tracing or System.Diagnostics.Tracing)?
+ string.Equals(attributeType.Name, reflectedAttributeType.Name, StringComparison.Ordinal) &&
+ attributeType.Namespace.EndsWith("Diagnostics.Tracing", StringComparison.Ordinal) &&
+ (reflectedAttributeType.Namespace.EndsWith("Diagnostics.Tracing", StringComparison.Ordinal)
+#if EVENT_SOURCE_LEGACY_NAMESPACE_SUPPORT
+ || reflectedAttributeType.Namespace.EndsWith("Diagnostics.Eventing", StringComparison.Ordinal)
+#endif
+);
+ }
+
+ private static Type GetEventSourceBaseType(Type eventSourceType, bool allowEventSourceOverride, bool reflectionOnly)
+ {
+ // return false for "object" and interfaces
+ if (eventSourceType.BaseType() == null)
+ return null;
+
+ // now go up the inheritance chain until hitting a concrete type ("object" at worse)
+ do
+ {
+ eventSourceType = eventSourceType.BaseType();
+ }
+ while (eventSourceType != null && eventSourceType.IsAbstract());
+
+ if (eventSourceType != null)
+ {
+ if (!allowEventSourceOverride)
+ {
+ if (reflectionOnly && eventSourceType.FullName != typeof(EventSource).FullName ||
+ !reflectionOnly && eventSourceType != typeof(EventSource))
+ return null;
+ }
+ else
+ {
+ if (eventSourceType.Name != "EventSource")
+ return null;
+ }
+ }
+ return eventSourceType;
+ }
+
+ // Use reflection to look at the attributes of a class, and generate a manifest for it (as UTF8) and
+ // return the UTF8 bytes. It also sets up the code:EventData structures needed to dispatch events
+ // at run time. 'source' is the event source to place the descriptors. If it is null,
+ // then the descriptors are not creaed, and just the manifest is generated.
+ private static byte[] CreateManifestAndDescriptors(Type eventSourceType, string eventSourceDllName, EventSource source,
+ EventManifestOptions flags = EventManifestOptions.None)
+ {
+ ManifestBuilder manifest = null;
+ bool bNeedsManifest = source != null ? !source.SelfDescribingEvents : true;
+ Exception exception = null; // exception that might get raised during validation b/c we couldn't/didn't recover from a previous error
+ byte[] res = null;
+
+ if (eventSourceType.IsAbstract() && (flags & EventManifestOptions.Strict) == 0)
+ return null;
+
+#if DEBUG && ES_BUILD_STANDALONE
+ TestSupport.TestHooks.MaybeThrow(eventSourceType,
+ TestSupport.Category.ManifestError,
+ "EventSource_CreateManifestAndDescriptors",
+ new ArgumentException("EventSource_CreateManifestAndDescriptors"));
+#endif
+
+ try
+ {
+ MethodInfo[] methods = eventSourceType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
+ EventAttribute defaultEventAttribute;
+ int eventId = 1; // The number given to an event that does not have a explicitly given ID.
+ EventMetadata[] eventData = null;
+ Dictionary<string, string> eventsByName = null;
+ if (source != null || (flags & EventManifestOptions.Strict) != 0)
+ {
+ eventData = new EventMetadata[methods.Length + 1];
+ eventData[0].Name = ""; // Event 0 is the 'write messages string' event, and has an empty name.
+ }
+
+ // See if we have localization information.
+ ResourceManager resources = null;
+ EventSourceAttribute eventSourceAttrib = (EventSourceAttribute)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute), flags);
+ if (eventSourceAttrib != null && eventSourceAttrib.LocalizationResources != null)
+ resources = new ResourceManager(eventSourceAttrib.LocalizationResources, eventSourceType.Assembly());
+
+ manifest = new ManifestBuilder(GetName(eventSourceType, flags), GetGuid(eventSourceType), eventSourceDllName,
+ resources, flags);
+
+ // Add an entry unconditionally for event ID 0 which will be for a string message.
+ manifest.StartEvent("EventSourceMessage", new EventAttribute(0) { Level = EventLevel.LogAlways, Task = (EventTask)0xFFFE });
+ manifest.AddEventParameter(typeof(string), "message");
+ manifest.EndEvent();
+
+ // eventSourceType must be sealed and must derive from this EventSource
+ if ((flags & EventManifestOptions.Strict) != 0)
+ {
+ bool typeMatch = GetEventSourceBaseType(eventSourceType, (flags & EventManifestOptions.AllowEventSourceOverride) != 0, eventSourceType.Assembly().ReflectionOnly()) != null;
+
+ if (!typeMatch)
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_TypeMustDeriveFromEventSource"));
+ }
+ if (!eventSourceType.IsAbstract() && !eventSourceType.IsSealed())
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_TypeMustBeSealedOrAbstract"));
+ }
+ }
+
+ // Collect task, opcode, keyword and channel information
+#if FEATURE_MANAGED_ETW_CHANNELS && FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
+ foreach (var providerEnumKind in new string[] { "Keywords", "Tasks", "Opcodes", "Channels" })
+#else
+ foreach (var providerEnumKind in new string[] { "Keywords", "Tasks", "Opcodes" })
+#endif
+ {
+ Type nestedType = eventSourceType.GetNestedType(providerEnumKind);
+ if (nestedType != null)
+ {
+ if (eventSourceType.IsAbstract())
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_AbstractMustNotDeclareKTOC", nestedType.Name));
+ }
+ else
+ {
+ foreach (FieldInfo staticField in nestedType.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static))
+ {
+ AddProviderEnumKind(manifest, staticField, providerEnumKind);
+ }
+ }
+ }
+ }
+ // ensure we have keywords for the session-filtering reserved bits
+ {
+ manifest.AddKeyword("Session3", (long)0x1000 << 32);
+ manifest.AddKeyword("Session2", (long)0x2000 << 32);
+ manifest.AddKeyword("Session1", (long)0x4000 << 32);
+ manifest.AddKeyword("Session0", (long)0x8000 << 32);
+ }
+
+ if (eventSourceType != typeof(EventSource))
+ {
+ for (int i = 0; i < methods.Length; i++)
+ {
+ MethodInfo method = methods[i];
+ ParameterInfo[] args = method.GetParameters();
+
+ // Get the EventDescriptor (from the Custom attributes)
+ EventAttribute eventAttribute = (EventAttribute)GetCustomAttributeHelper(method, typeof(EventAttribute), flags);
+
+ // Compat: until v4.5.1 we ignored any non-void returning methods as well as virtual methods for
+ // the only reason of limiting the number of methods considered to be events. This broke a common
+ // design of having event sources implement specific interfaces. To fix this in a compatible way
+ // we will now allow both non-void returning and virtual methods to be Event methods, as long
+ // as they are marked with the [Event] attribute
+ if (/* method.IsVirtual || */ method.IsStatic)
+ {
+ continue;
+ }
+
+ if (eventSourceType.IsAbstract())
+ {
+ if (eventAttribute != null)
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_AbstractMustNotDeclareEventMethods", method.Name, eventAttribute.EventId));
+ }
+ continue;
+ }
+ else if (eventAttribute == null)
+ {
+ // Methods that don't return void can't be events, if they're NOT marked with [Event].
+ // (see Compat comment above)
+ if (method.ReturnType != typeof(void))
+ {
+ continue;
+ }
+
+ // Continue to ignore virtual methods if they do NOT have the [Event] attribute
+ // (see Compat comment above)
+ if (method.IsVirtual)
+ {
+ continue;
+ }
+
+ // If we explicitly mark the method as not being an event, then honor that.
+ if (GetCustomAttributeHelper(method, typeof(NonEventAttribute), flags) != null)
+ continue;
+
+ defaultEventAttribute = new EventAttribute(eventId);
+ eventAttribute = defaultEventAttribute;
+ }
+ else if (eventAttribute.EventId <= 0)
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_NeedPositiveId", method.Name), true);
+ continue; // don't validate anything else for this event
+ }
+ if (method.Name.LastIndexOf('.') >= 0)
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_EventMustNotBeExplicitImplementation", method.Name, eventAttribute.EventId));
+ }
+
+ eventId++;
+ string eventName = method.Name;
+
+ if (eventAttribute.Opcode == EventOpcode.Info) // We are still using the default opcode.
+ {
+ // By default pick a task ID derived from the EventID, starting with the highest task number and working back
+ bool noTask = (eventAttribute.Task == EventTask.None);
+ if (noTask)
+ eventAttribute.Task = (EventTask)(0xFFFE - eventAttribute.EventId);
+
+ // Unless we explicitly set the opcode to Info (to override the auto-generate of Start or Stop opcodes,
+ // pick a default opcode based on the event name (either Info or start or stop if the name ends with that suffix).
+ if (!eventAttribute.IsOpcodeSet)
+ eventAttribute.Opcode = GetOpcodeWithDefault(EventOpcode.Info, eventName);
+
+ // Make the stop opcode have the same task as the start opcode.
+ if (noTask)
+ {
+ if (eventAttribute.Opcode == EventOpcode.Start)
+ {
+ string taskName = eventName.Substring(0, eventName.Length - s_ActivityStartSuffix.Length); // Remove the Stop suffix to get the task name
+ if (string.Compare(eventName, 0, taskName, 0, taskName.Length) == 0 &&
+ string.Compare(eventName, taskName.Length, s_ActivityStartSuffix, 0, Math.Max(eventName.Length - taskName.Length, s_ActivityStartSuffix.Length)) == 0)
+ {
+ // Add a task that is just the task name for the start event. This suppress the auto-task generation
+ // That would otherwise happen (and create 'TaskName'Start as task name rather than just 'TaskName'
+ manifest.AddTask(taskName, (int)eventAttribute.Task);
+ }
+ }
+ else if (eventAttribute.Opcode == EventOpcode.Stop)
+ {
+ // Find the start associated with this stop event. We require start to be immediately before the stop
+ int startEventId = eventAttribute.EventId - 1;
+ if (eventData != null && startEventId < eventData.Length)
+ {
+ Debug.Assert(0 <= startEventId); // Since we reserve id 0, we know that id-1 is <= 0
+ EventMetadata startEventMetadata = eventData[startEventId];
+
+ // If you remove the Stop and add a Start does that name match the Start Event's Name?
+ // Ideally we would throw an error
+ string taskName = eventName.Substring(0, eventName.Length - s_ActivityStopSuffix.Length); // Remove the Stop suffix to get the task name
+ if (startEventMetadata.Descriptor.Opcode == (byte)EventOpcode.Start &&
+ string.Compare(startEventMetadata.Name, 0, taskName, 0, taskName.Length) == 0 &&
+ string.Compare(startEventMetadata.Name, taskName.Length, s_ActivityStartSuffix, 0, Math.Max(startEventMetadata.Name.Length - taskName.Length, s_ActivityStartSuffix.Length)) == 0)
+ {
+
+ // Make the stop event match the start event
+ eventAttribute.Task = (EventTask)startEventMetadata.Descriptor.Task;
+ noTask = false;
+ }
+ }
+ if (noTask && (flags & EventManifestOptions.Strict) != 0) // Throw an error if we can compatibly.
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_StopsFollowStarts"));
+ }
+ }
+ }
+ }
+
+ bool hasRelatedActivityID = RemoveFirstArgIfRelatedActivityId(ref args);
+ if (!(source != null && source.SelfDescribingEvents))
+ {
+ manifest.StartEvent(eventName, eventAttribute);
+ for (int fieldIdx = 0; fieldIdx < args.Length; fieldIdx++)
+ {
+ manifest.AddEventParameter(args[fieldIdx].ParameterType, args[fieldIdx].Name);
+ }
+ manifest.EndEvent();
+ }
+
+ if (source != null || (flags & EventManifestOptions.Strict) != 0)
+ {
+ // Do checking for user errors (optional, but not a big deal so we do it).
+ DebugCheckEvent(ref eventsByName, eventData, method, eventAttribute, manifest, flags);
+
+#if FEATURE_MANAGED_ETW_CHANNELS
+ // add the channel keyword for Event Viewer channel based filters. This is added for creating the EventDescriptors only
+ // and is not required for the manifest
+ if (eventAttribute.Channel != EventChannel.None)
+ {
+ unchecked
+ {
+ eventAttribute.Keywords |= (EventKeywords)manifest.GetChannelKeyword(eventAttribute.Channel, (ulong)eventAttribute.Keywords);
+ }
+ }
+#endif
+ string eventKey = "event_" + eventName;
+ string msg = manifest.GetLocalizedMessage(eventKey, CultureInfo.CurrentUICulture, etwFormat: false);
+ // overwrite inline message with the localized message
+ if (msg != null) eventAttribute.Message = msg;
+
+ AddEventDescriptor(ref eventData, eventName, eventAttribute, args, hasRelatedActivityID);
+ }
+ }
+ }
+
+ // Tell the TraceLogging stuff where to start allocating its own IDs.
+ NameInfo.ReserveEventIDsBelow(eventId);
+
+ if (source != null)
+ {
+ TrimEventDescriptors(ref eventData);
+ source.m_eventData = eventData; // officially initialize it. We do this at most once (it is racy otherwise).
+#if FEATURE_MANAGED_ETW_CHANNELS
+ source.m_channelData = manifest.GetChannelData();
+#endif
+ }
+
+ // if this is an abstract event source we've already performed all the validation we can
+ if (!eventSourceType.IsAbstract() && (source == null || !source.SelfDescribingEvents))
+ {
+ bNeedsManifest = (flags & EventManifestOptions.OnlyIfNeededForRegistration) == 0
+#if FEATURE_MANAGED_ETW_CHANNELS
+ || manifest.GetChannelData().Length > 0
+#endif
+;
+
+ // if the manifest is not needed and we're not requested to validate the event source return early
+ if (!bNeedsManifest && (flags & EventManifestOptions.Strict) == 0)
+ return null;
+
+ res = manifest.CreateManifest();
+ }
+ }
+ catch (Exception e)
+ {
+ // if this is a runtime manifest generation let the exception propagate
+ if ((flags & EventManifestOptions.Strict) == 0)
+ throw;
+ // else store it to include it in the Argument exception we raise below
+ exception = e;
+ }
+
+ if ((flags & EventManifestOptions.Strict) != 0 && (manifest.Errors.Count > 0 || exception != null))
+ {
+ string msg = String.Empty;
+ if (manifest.Errors.Count > 0)
+ {
+ bool firstError = true;
+ foreach (string error in manifest.Errors)
+ {
+ if (!firstError)
+ msg += Environment.NewLine;
+ firstError = false;
+ msg += error;
+ }
+ }
+ else
+ msg = "Unexpected error: " + exception.Message;
+
+ throw new ArgumentException(msg, exception);
+ }
+
+ return bNeedsManifest ? res : null;
+ }
+
+ private static bool RemoveFirstArgIfRelatedActivityId(ref ParameterInfo[] args)
+ {
+ // If the first parameter is (case insensitive) 'relatedActivityId' then skip it.
+ if (args.Length > 0 && args[0].ParameterType == typeof(Guid) &&
+ string.Compare(args[0].Name, "relatedActivityId", StringComparison.OrdinalIgnoreCase) == 0)
+ {
+ var newargs = new ParameterInfo[args.Length - 1];
+ Array.Copy(args, 1, newargs, 0, args.Length - 1);
+ args = newargs;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ // adds a enumeration (keyword, opcode, task or channel) represented by 'staticField'
+ // to the manifest.
+ private static void AddProviderEnumKind(ManifestBuilder manifest, FieldInfo staticField, string providerEnumKind)
+ {
+ bool reflectionOnly = staticField.Module.Assembly.ReflectionOnly();
+ Type staticFieldType = staticField.FieldType;
+ if (!reflectionOnly && (staticFieldType == typeof(EventOpcode)) || AttributeTypeNamesMatch(staticFieldType, typeof(EventOpcode)))
+ {
+ if (providerEnumKind != "Opcodes") goto Error;
+ int value = (int)staticField.GetRawConstantValue();
+ manifest.AddOpcode(staticField.Name, value);
+ }
+ else if (!reflectionOnly && (staticFieldType == typeof(EventTask)) || AttributeTypeNamesMatch(staticFieldType, typeof(EventTask)))
+ {
+ if (providerEnumKind != "Tasks") goto Error;
+ int value = (int)staticField.GetRawConstantValue();
+ manifest.AddTask(staticField.Name, value);
+ }
+ else if (!reflectionOnly && (staticFieldType == typeof(EventKeywords)) || AttributeTypeNamesMatch(staticFieldType, typeof(EventKeywords)))
+ {
+ if (providerEnumKind != "Keywords") goto Error;
+ ulong value = unchecked((ulong)(long)staticField.GetRawConstantValue());
+ manifest.AddKeyword(staticField.Name, value);
+ }
+#if FEATURE_MANAGED_ETW_CHANNELS && FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
+ else if (!reflectionOnly && (staticFieldType == typeof(EventChannel)) || AttributeTypeNamesMatch(staticFieldType, typeof(EventChannel)))
+ {
+ if (providerEnumKind != "Channels") goto Error;
+ var channelAttribute = (EventChannelAttribute)GetCustomAttributeHelper(staticField, typeof(EventChannelAttribute));
+ manifest.AddChannel(staticField.Name, (byte)staticField.GetRawConstantValue(), channelAttribute);
+ }
+#endif
+ return;
+ Error:
+ manifest.ManifestError(Resources.GetResourceString("EventSource_EnumKindMismatch", staticField.Name, staticField.FieldType.Name, providerEnumKind));
+ }
+
+ // Helper used by code:CreateManifestAndDescriptors to add a code:EventData descriptor for a method
+ // with the code:EventAttribute 'eventAttribute'. resourceManger may be null in which case we populate it
+ // it is populated if we need to look up message resources
+ private static void AddEventDescriptor(ref EventMetadata[] eventData, string eventName,
+ EventAttribute eventAttribute, ParameterInfo[] eventParameters,
+ bool hasRelatedActivityID)
+ {
+ if (eventData == null || eventData.Length <= eventAttribute.EventId)
+ {
+ EventMetadata[] newValues = new EventMetadata[Math.Max(eventData.Length + 16, eventAttribute.EventId + 1)];
+ Array.Copy(eventData, 0, newValues, 0, eventData.Length);
+ eventData = newValues;
+ }
+
+ eventData[eventAttribute.EventId].Descriptor = new EventDescriptor(
+ eventAttribute.EventId,
+ eventAttribute.Version,
+#if FEATURE_MANAGED_ETW_CHANNELS
+ (byte)eventAttribute.Channel,
+#else
+ (byte)0,
+#endif
+ (byte)eventAttribute.Level,
+ (byte)eventAttribute.Opcode,
+ (int)eventAttribute.Task,
+ unchecked((long)((ulong)eventAttribute.Keywords | SessionMask.All.ToEventKeywords())));
+
+ eventData[eventAttribute.EventId].Tags = eventAttribute.Tags;
+ eventData[eventAttribute.EventId].Name = eventName;
+ eventData[eventAttribute.EventId].Parameters = eventParameters;
+ eventData[eventAttribute.EventId].Message = eventAttribute.Message;
+ eventData[eventAttribute.EventId].ActivityOptions = eventAttribute.ActivityOptions;
+ eventData[eventAttribute.EventId].HasRelatedActivityID = hasRelatedActivityID;
+ }
+
+ // Helper used by code:CreateManifestAndDescriptors that trims the m_eventData array to the correct
+ // size after all event descriptors have been added.
+ private static void TrimEventDescriptors(ref EventMetadata[] eventData)
+ {
+ int idx = eventData.Length;
+ while (0 < idx)
+ {
+ --idx;
+ if (eventData[idx].Descriptor.EventId != 0)
+ break;
+ }
+ if (eventData.Length - idx > 2) // allow one wasted slot.
+ {
+ EventMetadata[] newValues = new EventMetadata[idx + 1];
+ Array.Copy(eventData, 0, newValues, 0, newValues.Length);
+ eventData = newValues;
+ }
+ }
+
+ // Helper used by code:EventListener.AddEventSource and code:EventListener.EventListener
+ // when a listener gets attached to a eventSource
+ internal void AddListener(EventListener listener)
+ {
+ lock (EventListener.EventListenersLock)
+ {
+ bool[] enabledArray = null;
+ if (m_eventData != null)
+ enabledArray = new bool[m_eventData.Length];
+ m_Dispatchers = new EventDispatcher(m_Dispatchers, enabledArray, listener);
+ listener.OnEventSourceCreated(this);
+ }
+ }
+
+ // Helper used by code:CreateManifestAndDescriptors to find user mistakes like reusing an event
+ // index for two distinct events etc. Throws exceptions when it finds something wrong.
+ private static void DebugCheckEvent(ref Dictionary<string, string> eventsByName,
+ EventMetadata[] eventData, MethodInfo method, EventAttribute eventAttribute,
+ ManifestBuilder manifest, EventManifestOptions options)
+ {
+ int evtId = eventAttribute.EventId;
+ string evtName = method.Name;
+ int eventArg = GetHelperCallFirstArg(method);
+ if (eventArg >= 0 && evtId != eventArg)
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_MismatchIdToWriteEvent", evtName, evtId, eventArg), true);
+ }
+
+ if (evtId < eventData.Length && eventData[evtId].Descriptor.EventId != 0)
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_EventIdReused", evtName, evtId, eventData[evtId].Name), true);
+ }
+
+ // We give a task to things if they don't have one.
+ // TODO this is moderately expensive (N*N). We probably should not even bother....
+ Debug.Assert(eventAttribute.Task != EventTask.None || eventAttribute.Opcode != EventOpcode.Info);
+ for (int idx = 0; idx < eventData.Length; ++idx)
+ {
+ // skip unused Event IDs.
+ if (eventData[idx].Name == null)
+ continue;
+
+ if (eventData[idx].Descriptor.Task == (int)eventAttribute.Task && eventData[idx].Descriptor.Opcode == (int)eventAttribute.Opcode)
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_TaskOpcodePairReused",
+ evtName, evtId, eventData[idx].Name, idx));
+ // If we are not strict stop on first error. We have had problems with really large providers taking forever. because of many errors.
+ if ((options & EventManifestOptions.Strict) == 0)
+ break;
+ }
+ }
+
+ // for non-default event opcodes the user must define a task!
+ if (eventAttribute.Opcode != EventOpcode.Info)
+ {
+ bool failure = false;
+ if (eventAttribute.Task == EventTask.None)
+ failure = true;
+ else
+ {
+ // If you have the auto-assigned Task, then you did not explicitly set one.
+ // This is OK for Start events because we have special logic to assign the task to a prefix derived from the event name
+ // But all other cases we want to catch the omission.
+ var autoAssignedTask = (EventTask)(0xFFFE - evtId);
+ if ((eventAttribute.Opcode != EventOpcode.Start && eventAttribute.Opcode != EventOpcode.Stop) && eventAttribute.Task == autoAssignedTask)
+ failure = true;
+ }
+ if (failure)
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_EventMustHaveTaskIfNonDefaultOpcode", evtName, evtId));
+ }
+ }
+
+ // If we ever want to enforce the rule: MethodName = TaskName + OpcodeName here's how:
+ // (the reason we don't is backwards compat and the need for handling this as a non-fatal error
+ // by eventRegister.exe)
+ // taskName & opcodeName could be passed in by the caller which has opTab & taskTab handy
+ // if (!(((int)eventAttribute.Opcode == 0 && evtName == taskName) || (evtName == taskName+opcodeName)))
+ // {
+ // throw new WarningException(Resources.GetResourceString("EventSource_EventNameDoesNotEqualTaskPlusOpcode"));
+ // }
+
+ if (eventsByName == null)
+ eventsByName = new Dictionary<string, string>();
+
+ if (eventsByName.ContainsKey(evtName))
+ {
+ manifest.ManifestError(Resources.GetResourceString("EventSource_EventNameReused", evtName), true);
+ }
+
+ eventsByName[evtName] = evtName;
+ }
+
+ /// <summary>
+ /// This method looks at the IL and tries to pattern match against the standard
+ /// 'boilerplate' event body
+ /// <code>
+ /// { if (Enabled()) WriteEvent(#, ...) }
+ /// </code>
+ /// If the pattern matches, it returns the literal number passed as the first parameter to
+ /// the WriteEvent. This is used to find common user errors (mismatching this
+ /// number with the EventAttribute ID). It is only used for validation.
+ /// </summary>
+ /// <param name="method">The method to probe.</param>
+ /// <returns>The literal value or -1 if the value could not be determined. </returns>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Switch statement is clearer than alternatives")]
+ static private int GetHelperCallFirstArg(MethodInfo method)
+ {
+#if (!ES_BUILD_PCL && !ES_BUILD_PN)
+ // Currently searches for the following pattern
+ //
+ // ... // CAN ONLY BE THE INSTRUCTIONS BELOW
+ // LDARG0
+ // LDC.I4 XXX
+ // ... // CAN ONLY BE THE INSTRUCTIONS BELOW CAN'T BE A BRANCH OR A CALL
+ // CALL
+ // NOP // 0 or more times
+ // RET
+ //
+ // If we find this pattern we return the XXX. Otherwise we return -1.
+#if !CORECLR
+ (new ReflectionPermission(ReflectionPermissionFlag.MemberAccess)).Assert();
+#endif
+ byte[] instrs = method.GetMethodBody().GetILAsByteArray();
+ int retVal = -1;
+ for (int idx = 0; idx < instrs.Length;)
+ {
+ switch (instrs[idx])
+ {
+ case 0: // NOP
+ case 1: // BREAK
+ case 2: // LDARG_0
+ case 3: // LDARG_1
+ case 4: // LDARG_2
+ case 5: // LDARG_3
+ case 6: // LDLOC_0
+ case 7: // LDLOC_1
+ case 8: // LDLOC_2
+ case 9: // LDLOC_3
+ case 10: // STLOC_0
+ case 11: // STLOC_1
+ case 12: // STLOC_2
+ case 13: // STLOC_3
+ break;
+ case 14: // LDARG_S
+ case 16: // STARG_S
+ idx++;
+ break;
+ case 20: // LDNULL
+ break;
+ case 21: // LDC_I4_M1
+ case 22: // LDC_I4_0
+ case 23: // LDC_I4_1
+ case 24: // LDC_I4_2
+ case 25: // LDC_I4_3
+ case 26: // LDC_I4_4
+ case 27: // LDC_I4_5
+ case 28: // LDC_I4_6
+ case 29: // LDC_I4_7
+ case 30: // LDC_I4_8
+ if (idx > 0 && instrs[idx - 1] == 2) // preceeded by LDARG0
+ retVal = instrs[idx] - 22;
+ break;
+ case 31: // LDC_I4_S
+ if (idx > 0 && instrs[idx - 1] == 2) // preceeded by LDARG0
+ retVal = instrs[idx + 1];
+ idx++;
+ break;
+ case 32: // LDC_I4
+ idx += 4;
+ break;
+ case 37: // DUP
+ break;
+ case 40: // CALL
+ idx += 4;
+
+ if (retVal >= 0)
+ {
+ // Is this call just before return?
+ for (int search = idx + 1; search < instrs.Length; search++)
+ {
+ if (instrs[search] == 42) // RET
+ return retVal;
+ if (instrs[search] != 0) // NOP
+ break;
+ }
+ }
+ retVal = -1;
+ break;
+ case 44: // BRFALSE_S
+ case 45: // BRTRUE_S
+ retVal = -1;
+ idx++;
+ break;
+ case 57: // BRFALSE
+ case 58: // BRTRUE
+ retVal = -1;
+ idx += 4;
+ break;
+ case 103: // CONV_I1
+ case 104: // CONV_I2
+ case 105: // CONV_I4
+ case 106: // CONV_I8
+ case 109: // CONV_U4
+ case 110: // CONV_U8
+ break;
+ case 140: // BOX
+ case 141: // NEWARR
+ idx += 4;
+ break;
+ case 162: // STELEM_REF
+ break;
+ case 254: // PREFIX
+ idx++;
+ // Covers the CEQ instructions used in debug code for some reason.
+ if (idx >= instrs.Length || instrs[idx] >= 6)
+ goto default;
+ break;
+ default:
+ /* Debug.Assert(false, "Warning: User validation code sub-optimial: Unsuported opcode " + instrs[idx] +
+ " at " + idx + " in method " + method.Name); */
+ return -1;
+ }
+ idx++;
+ }
+#endif
+ return -1;
+ }
+
+#if false // This routine is not needed at all, it was used for unit test debugging.
+ [Conditional("DEBUG")]
+ private static void OutputDebugString(string msg)
+ {
+#if !ES_BUILD_PCL
+ msg = msg.TrimEnd('\r', '\n') +
+ string.Format(CultureInfo.InvariantCulture, ", Thrd({0})" + Environment.NewLine, Thread.CurrentThread.ManagedThreadId);
+ System.Diagnostics.Debugger.Log(0, null, msg);
+#endif
+ }
+#endif
+
+ /// <summary>
+ /// Sends an error message to the debugger (outputDebugString), as well as the EventListeners
+ /// It will do this even if the EventSource is not enabled.
+ /// TODO remove flush parameter it is not used.
+ /// </summary>
+ [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
+ internal void ReportOutOfBandMessage(string msg, bool flush)
+ {
+ try
+ {
+#if (!ES_BUILD_PCL && !ES_BUILD_PN)
+ // send message to debugger without delay
+ System.Diagnostics.Debugger.Log(0, null, String.Format("EventSource Error: {0}{1}", msg, Environment.NewLine));
+#endif
+
+ // Send it to all listeners.
+ if (m_outOfBandMessageCount < 16 - 1) // Note this is only if size byte
+ m_outOfBandMessageCount++;
+ else
+ {
+ if (m_outOfBandMessageCount == 16)
+ return;
+ m_outOfBandMessageCount = 16; // Mark that we hit the limit. Notify them that this is the case.
+ msg = "Reached message limit. End of EventSource error messages.";
+ }
+
+ WriteEventString(EventLevel.LogAlways, -1, msg);
+ WriteStringToAllListeners("EventSourceMessage", msg);
+ }
+ catch (Exception) { } // If we fail during last chance logging, well, we have to give up....
+ }
+
+ private EventSourceSettings ValidateSettings(EventSourceSettings settings)
+ {
+ var evtFormatMask = EventSourceSettings.EtwManifestEventFormat |
+ EventSourceSettings.EtwSelfDescribingEventFormat;
+ if ((settings & evtFormatMask) == evtFormatMask)
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_InvalidEventFormat"), nameof(settings));
+ }
+
+ // If you did not explicitly ask for manifest, you get self-describing.
+ if ((settings & evtFormatMask) == 0)
+ settings |= EventSourceSettings.EtwSelfDescribingEventFormat;
+ return settings;
+ }
+
+ private bool ThrowOnEventWriteErrors
+ {
+ get { return (m_config & EventSourceSettings.ThrowOnEventWriteErrors) != 0; }
+ set
+ {
+ if (value) m_config |= EventSourceSettings.ThrowOnEventWriteErrors;
+ else m_config &= ~EventSourceSettings.ThrowOnEventWriteErrors;
+ }
+ }
+
+ private bool SelfDescribingEvents
+ {
+ get
+ {
+ Debug.Assert(((m_config & EventSourceSettings.EtwManifestEventFormat) != 0) !=
+ ((m_config & EventSourceSettings.EtwSelfDescribingEventFormat) != 0));
+ return (m_config & EventSourceSettings.EtwSelfDescribingEventFormat) != 0;
+ }
+ set
+ {
+ if (!value)
+ {
+ m_config |= EventSourceSettings.EtwManifestEventFormat;
+ m_config &= ~EventSourceSettings.EtwSelfDescribingEventFormat;
+ }
+ else
+ {
+ m_config |= EventSourceSettings.EtwSelfDescribingEventFormat;
+ m_config &= ~EventSourceSettings.EtwManifestEventFormat;
+ }
+ }
+ }
+
+#if FEATURE_ACTIVITYSAMPLING
+ private void ReportActivitySamplingInfo(EventListener listener, SessionMask sessions)
+ {
+ Debug.Assert(listener == null || (uint)sessions == (uint)SessionMask.FromId(0));
+
+ for (int perEventSourceSessionId = 0; perEventSourceSessionId < SessionMask.MAX; ++perEventSourceSessionId)
+ {
+ if (!sessions[perEventSourceSessionId])
+ continue;
+
+ ActivityFilter af;
+ if (listener == null)
+ {
+ EtwSession etwSession = m_etwSessionIdMap[perEventSourceSessionId];
+ Debug.Assert(etwSession != null);
+ af = etwSession.m_activityFilter;
+ }
+ else
+ {
+ af = listener.m_activityFilter;
+ }
+
+ if (af == null)
+ continue;
+
+ SessionMask m = new SessionMask();
+ m[perEventSourceSessionId] = true;
+
+ foreach (var t in af.GetFilterAsTuple(m_guid))
+ {
+ WriteStringToListener(listener, string.Format(CultureInfo.InvariantCulture, "Session {0}: {1} = {2}", perEventSourceSessionId, t.Item1, t.Item2), m);
+ }
+
+ bool participateInSampling = (listener == null) ?
+ m_activityFilteringForETWEnabled[perEventSourceSessionId] :
+ GetDispatcher(listener).m_activityFilteringEnabled;
+ WriteStringToListener(listener, string.Format(CultureInfo.InvariantCulture, "Session {0}: Activity Sampling support: {1}",
+ perEventSourceSessionId, participateInSampling ? "enabled" : "disabled"), m);
+ }
+ }
+#endif // FEATURE_ACTIVITYSAMPLING
+
+ // private instance state
+ private string m_name; // My friendly name (privided in ctor)
+ internal int m_id; // A small integer that is unique to this instance.
+ private Guid m_guid; // GUID representing the ETW eventSource to the OS.
+ internal volatile EventMetadata[] m_eventData; // None per-event data
+ private volatile byte[] m_rawManifest; // Bytes to send out representing the event schema
+
+ private EventHandler<EventCommandEventArgs> m_eventCommandExecuted;
+
+ private EventSourceSettings m_config; // configuration information
+
+ private bool m_eventSourceDisposed; // has Dispose been called.
+
+ // Enabling bits
+ private bool m_eventSourceEnabled; // am I enabled (any of my events are enabled for any dispatcher)
+ internal EventLevel m_level; // highest level enabled by any output dispatcher
+ internal EventKeywords m_matchAnyKeyword; // the logical OR of all levels enabled by any output dispatcher (zero is a special case) meaning 'all keywords'
+
+ // Dispatching state
+ internal volatile EventDispatcher m_Dispatchers; // Linked list of code:EventDispatchers we write the data to (we also do ETW specially)
+#if FEATURE_MANAGED_ETW
+ private volatile OverideEventProvider m_provider; // This hooks up ETW commands to our 'OnEventCommand' callback
+#endif
+ private bool m_completelyInited; // The EventSource constructor has returned without exception.
+ private Exception m_constructionException; // If there was an exception construction, this is it
+ private byte m_outOfBandMessageCount; // The number of out of band messages sent (we throttle them
+ private EventCommandEventArgs m_deferredCommands;// If we get commands before we are fully we store them here and run the when we are fully inited.
+
+ private string[] m_traits; // Used to implement GetTraits
+
+ internal static uint s_currentPid; // current process id, used in synthesizing quasi-GUIDs
+ [ThreadStatic]
+ private static byte m_EventSourceExceptionRecurenceCount = 0; // current recursion count inside ThrowEventSourceException
+
+ [ThreadStatic]
+ private static bool m_EventSourceInDecodeObject = false;
+
+#if FEATURE_MANAGED_ETW_CHANNELS
+ internal volatile ulong[] m_channelData;
+#endif
+
+#if FEATURE_ACTIVITYSAMPLING
+ private SessionMask m_curLiveSessions; // the activity-tracing aware sessions' bits
+ private EtwSession[] m_etwSessionIdMap; // the activity-tracing aware sessions
+ private List<EtwSession> m_legacySessions; // the legacy ETW sessions listening to this source
+ internal long m_keywordTriggers; // a bit is set if it corresponds to a keyword that's part of an enabled triggering event
+ internal SessionMask m_activityFilteringForETWEnabled; // does THIS EventSource have activity filtering turned on for each ETW session
+ static internal Action<Guid> s_activityDying; // Fires when something calls SetCurrentThreadToActivity()
+ // Also used to mark that activity tracing is on for some case
+#endif // FEATURE_ACTIVITYSAMPLING
+
+ // We use a single instance of ActivityTracker for all EventSources instances to allow correlation between multiple event providers.
+ // We have m_activityTracker field simply because instance field is more efficient than static field fetch.
+ ActivityTracker m_activityTracker;
+ internal const string s_ActivityStartSuffix = "Start";
+ internal const string s_ActivityStopSuffix = "Stop";
+
+ // used for generating GUID from eventsource name
+ private static readonly byte[] namespaceBytes = new byte[] {
+ 0x48, 0x2C, 0x2D, 0xB2, 0xC3, 0x90, 0x47, 0xC8,
+ 0x87, 0xF8, 0x1A, 0x15, 0xBF, 0xC1, 0x30, 0xFB,
+ };
+
+ #endregion
+ }
+
+ /// <summary>
+ /// Enables specifying event source configuration options to be used in the EventSource constructor.
+ /// </summary>
+ [Flags]
+ public enum EventSourceSettings
+ {
+ /// <summary>
+ /// This specifies none of the special configuration options should be enabled.
+ /// </summary>
+ Default = 0,
+ /// <summary>
+ /// Normally an EventSource NEVER throws; setting this option will tell it to throw when it encounters errors.
+ /// </summary>
+ ThrowOnEventWriteErrors = 1,
+ /// <summary>
+ /// Setting this option is a directive to the ETW listener should use manifest-based format when
+ /// firing events. This is the default option when defining a type derived from EventSource
+ /// (using the protected EventSource constructors).
+ /// Only one of EtwManifestEventFormat or EtwSelfDescribingEventFormat should be specified
+ /// </summary>
+ EtwManifestEventFormat = 4,
+ /// <summary>
+ /// Setting this option is a directive to the ETW listener should use self-describing event format
+ /// when firing events. This is the default option when creating a new instance of the EventSource
+ /// type (using the public EventSource constructors).
+ /// Only one of EtwManifestEventFormat or EtwSelfDescribingEventFormat should be specified
+ /// </summary>
+ EtwSelfDescribingEventFormat = 8,
+ }
+
+ /// <summary>
+ /// An EventListener represents a target for the events generated by EventSources (that is subclasses
+ /// of <see cref="EventSource"/>), in the current appdomain. When a new EventListener is created
+ /// it is logically attached to all eventSources in that appdomain. When the EventListener is Disposed, then
+ /// it is disconnected from the event eventSources. Note that there is a internal list of STRONG references
+ /// to EventListeners, which means that relying on the lack of references to EventListeners to clean up
+ /// EventListeners will NOT work. You must call EventListener.Dispose explicitly when a dispatcher is no
+ /// longer needed.
+ /// <para>
+ /// Once created, EventListeners can enable or disable on a per-eventSource basis using verbosity levels
+ /// (<see cref="EventLevel"/>) and bitfields (<see cref="EventKeywords"/>) to further restrict the set of
+ /// events to be sent to the dispatcher. The dispatcher can also send arbitrary commands to a particular
+ /// eventSource using the 'SendCommand' method. The meaning of the commands are eventSource specific.
+ /// </para><para>
+ /// The Null Guid (that is (new Guid()) has special meaning as a wildcard for 'all current eventSources in
+ /// the appdomain'. Thus it is relatively easy to turn on all events in the appdomain if desired.
+ /// </para><para>
+ /// It is possible for there to be many EventListener's defined in a single appdomain. Each dispatcher is
+ /// logically independent of the other listeners. Thus when one dispatcher enables or disables events, it
+ /// affects only that dispatcher (other listeners get the events they asked for). It is possible that
+ /// commands sent with 'SendCommand' would do a semantic operation that would affect the other listeners
+ /// (like doing a GC, or flushing data ...), but this is the exception rather than the rule.
+ /// </para><para>
+ /// Thus the model is that each EventSource keeps a list of EventListeners that it is sending events
+ /// to. Associated with each EventSource-dispatcher pair is a set of filtering criteria that determine for
+ /// that eventSource what events that dispatcher will receive.
+ /// </para><para>
+ /// Listeners receive the events on their 'OnEventWritten' method. Thus subclasses of EventListener must
+ /// override this method to do something useful with the data.
+ /// </para><para>
+ /// In addition, when new eventSources are created, the 'OnEventSourceCreate' method is called. The
+ /// invariant associated with this callback is that every eventSource gets exactly one
+ /// 'OnEventSourceCreate' call for ever eventSource that can potentially send it log messages. In
+ /// particular when a EventListener is created, typically a series of OnEventSourceCreate' calls are
+ /// made to notify the new dispatcher of all the eventSources that existed before the EventListener was
+ /// created.
+ /// </para>
+ /// </summary>
+ public class EventListener : IDisposable
+ {
+ private event EventHandler<EventSourceCreatedEventArgs> _EventSourceCreated;
+
+ /// <summary>
+ /// This event is raised whenever a new eventSource is 'attached' to the dispatcher.
+ /// This can happen for all existing EventSources when the EventListener is created
+ /// as well as for any EventSources that come into existence after the EventListener
+ /// has been created.
+ ///
+ /// These 'catch up' events are called during the construction of the EventListener.
+ /// Subclasses need to be prepared for that.
+ ///
+ /// In a multi-threaded environment, it is possible that 'EventSourceEventWrittenCallback'
+ /// events for a particular eventSource to occur BEFORE the EventSourceCreatedCallback is issued.
+ /// </summary>
+ public event EventHandler<EventSourceCreatedEventArgs> EventSourceCreated
+ {
+ add
+ {
+ CallBackForExistingEventSources(false, value);
+
+ this._EventSourceCreated = (EventHandler<EventSourceCreatedEventArgs>)Delegate.Combine(_EventSourceCreated, value);
+ }
+ remove
+ {
+ this._EventSourceCreated = (EventHandler<EventSourceCreatedEventArgs>)Delegate.Remove(_EventSourceCreated, value);
+ }
+ }
+
+ /// <summary>
+ /// This event is raised whenever an event has been written by a EventSource for which
+ /// the EventListener has enabled events.
+ /// </summary>
+ public event EventHandler<EventWrittenEventArgs> EventWritten;
+
+ /// <summary>
+ /// Create a new EventListener in which all events start off turned off (use EnableEvents to turn
+ /// them on).
+ /// </summary>
+ public EventListener()
+ {
+ // This will cause the OnEventSourceCreated callback to fire.
+ CallBackForExistingEventSources(true, (obj, args) => args.EventSource.AddListener((EventListener)obj));
+ }
+
+ /// <summary>
+ /// Dispose should be called when the EventListener no longer desires 'OnEvent*' callbacks. Because
+ /// there is an internal list of strong references to all EventListeners, calling 'Dispose' directly
+ /// is the only way to actually make the listen die. Thus it is important that users of EventListener
+ /// call Dispose when they are done with their logging.
+ /// </summary>
+#if ES_BUILD_STANDALONE
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly")]
+#endif
+ public virtual void Dispose()
+ {
+ lock (EventListenersLock)
+ {
+ if (s_Listeners != null)
+ {
+ if (this == s_Listeners)
+ {
+ EventListener cur = s_Listeners;
+ s_Listeners = this.m_Next;
+ RemoveReferencesToListenerInEventSources(cur);
+ }
+ else
+ {
+ // Find 'this' from the s_Listeners linked list.
+ EventListener prev = s_Listeners;
+ for (;;)
+ {
+ EventListener cur = prev.m_Next;
+ if (cur == null)
+ break;
+ if (cur == this)
+ {
+ // Found our Listener, remove references to to it in the eventSources
+ prev.m_Next = cur.m_Next; // Remove entry.
+ RemoveReferencesToListenerInEventSources(cur);
+ break;
+ }
+ prev = cur;
+ }
+ }
+ }
+ Validate();
+ }
+ }
+ // We don't expose a Dispose(bool), because the contract is that you don't have any non-syncronous
+ // 'cleanup' associated with this object
+
+ /// <summary>
+ /// Enable all events from the eventSource identified by 'eventSource' to the current
+ /// dispatcher that have a verbosity level of 'level' or lower.
+ ///
+ /// This call can have the effect of REDUCING the number of events sent to the
+ /// dispatcher if 'level' indicates a less verbose level than was previously enabled.
+ ///
+ /// This call never has an effect on other EventListeners.
+ ///
+ /// </summary>
+ public void EnableEvents(EventSource eventSource, EventLevel level)
+ {
+ EnableEvents(eventSource, level, EventKeywords.None);
+ }
+ /// <summary>
+ /// Enable all events from the eventSource identified by 'eventSource' to the current
+ /// dispatcher that have a verbosity level of 'level' or lower and have a event keyword
+ /// matching any of the bits in 'matchAnyKeyword'.
+ ///
+ /// This call can have the effect of REDUCING the number of events sent to the
+ /// dispatcher if 'level' indicates a less verbose level than was previously enabled or
+ /// if 'matchAnyKeyword' has fewer keywords set than where previously set.
+ ///
+ /// This call never has an effect on other EventListeners.
+ /// </summary>
+ public void EnableEvents(EventSource eventSource, EventLevel level, EventKeywords matchAnyKeyword)
+ {
+ EnableEvents(eventSource, level, matchAnyKeyword, null);
+ }
+ /// <summary>
+ /// Enable all events from the eventSource identified by 'eventSource' to the current
+ /// dispatcher that have a verbosity level of 'level' or lower and have a event keyword
+ /// matching any of the bits in 'matchAnyKeyword' as well as any (eventSource specific)
+ /// effect passing additional 'key-value' arguments 'arguments' might have.
+ ///
+ /// This call can have the effect of REDUCING the number of events sent to the
+ /// dispatcher if 'level' indicates a less verbose level than was previously enabled or
+ /// if 'matchAnyKeyword' has fewer keywords set than where previously set.
+ ///
+ /// This call never has an effect on other EventListeners.
+ /// </summary>
+ public void EnableEvents(EventSource eventSource, EventLevel level, EventKeywords matchAnyKeyword, IDictionary<string, string> arguments)
+ {
+ if (eventSource == null)
+ {
+ throw new ArgumentNullException(nameof(eventSource));
+ }
+ Contract.EndContractBlock();
+
+ eventSource.SendCommand(this, 0, 0, EventCommand.Update, true, level, matchAnyKeyword, arguments);
+ }
+ /// <summary>
+ /// Disables all events coming from eventSource identified by 'eventSource'.
+ ///
+ /// This call never has an effect on other EventListeners.
+ /// </summary>
+ public void DisableEvents(EventSource eventSource)
+ {
+ if (eventSource == null)
+ {
+ throw new ArgumentNullException(nameof(eventSource));
+ }
+ Contract.EndContractBlock();
+
+ eventSource.SendCommand(this, 0, 0, EventCommand.Update, false, EventLevel.LogAlways, EventKeywords.None, null);
+ }
+
+ /// <summary>
+ /// EventSourceIndex is small non-negative integer (suitable for indexing in an array)
+ /// identifying EventSource. It is unique per-appdomain. Some EventListeners might find
+ /// it useful to store additional information about each eventSource connected to it,
+ /// and EventSourceIndex allows this extra information to be efficiently stored in a
+ /// (growable) array (eg List(T)).
+ /// </summary>
+ public static int EventSourceIndex(EventSource eventSource) { return eventSource.m_id; }
+
+ /// <summary>
+ /// This method is called whenever a new eventSource is 'attached' to the dispatcher.
+ /// This can happen for all existing EventSources when the EventListener is created
+ /// as well as for any EventSources that come into existence after the EventListener
+ /// has been created.
+ ///
+ /// These 'catch up' events are called during the construction of the EventListener.
+ /// Subclasses need to be prepared for that.
+ ///
+ /// In a multi-threaded environment, it is possible that 'OnEventWritten' callbacks
+ /// for a particular eventSource to occur BEFORE the OnEventSourceCreated is issued.
+ /// </summary>
+ /// <param name="eventSource"></param>
+ internal protected virtual void OnEventSourceCreated(EventSource eventSource)
+ {
+ EventHandler<EventSourceCreatedEventArgs> callBack = this._EventSourceCreated;
+ if (callBack != null)
+ {
+ EventSourceCreatedEventArgs args = new EventSourceCreatedEventArgs();
+ args.EventSource = eventSource;
+ callBack(this, args);
+ }
+ }
+
+ /// <summary>
+ /// This method is called whenever an event has been written by a EventSource for which
+ /// the EventListener has enabled events.
+ /// </summary>
+ /// <param name="eventData"></param>
+ internal protected virtual void OnEventWritten(EventWrittenEventArgs eventData)
+ {
+ EventHandler<EventWrittenEventArgs> callBack = this.EventWritten;
+ if (callBack != null)
+ {
+ callBack(this, eventData);
+ }
+ }
+
+
+ #region private
+ /// <summary>
+ /// This routine adds newEventSource to the global list of eventSources, it also assigns the
+ /// ID to the eventSource (which is simply the ordinal in the global list).
+ ///
+ /// EventSources currently do not pro-actively remove themselves from this list. Instead
+ /// when eventSources's are GCed, the weak handle in this list naturally gets nulled, and
+ /// we will reuse the slot. Today this list never shrinks (but we do reuse entries
+ /// that are in the list). This seems OK since the expectation is that EventSources
+ /// tend to live for the lifetime of the appdomain anyway (they tend to be used in
+ /// global variables).
+ /// </summary>
+ /// <param name="newEventSource"></param>
+ internal static void AddEventSource(EventSource newEventSource)
+ {
+ lock (EventListenersLock)
+ {
+ if (s_EventSources == null)
+ s_EventSources = new List<WeakReference>(2);
+
+ if (!s_EventSourceShutdownRegistered)
+ {
+ s_EventSourceShutdownRegistered = true;
+ }
+
+
+ // Periodically search the list for existing entries to reuse, this avoids
+ // unbounded memory use if we keep recycling eventSources (an unlikely thing).
+ int newIndex = -1;
+ if (s_EventSources.Count % 64 == 63) // on every block of 64, fill up the block before continuing
+ {
+ int i = s_EventSources.Count; // Work from the top down.
+ while (0 < i)
+ {
+ --i;
+ WeakReference weakRef = s_EventSources[i];
+ if (!weakRef.IsAlive)
+ {
+ newIndex = i;
+ weakRef.Target = newEventSource;
+ break;
+ }
+ }
+ }
+ if (newIndex < 0)
+ {
+ newIndex = s_EventSources.Count;
+ s_EventSources.Add(new WeakReference(newEventSource));
+ }
+ newEventSource.m_id = newIndex;
+
+ // Add every existing dispatcher to the new EventSource
+ for (EventListener listener = s_Listeners; listener != null; listener = listener.m_Next)
+ newEventSource.AddListener(listener);
+
+ Validate();
+ }
+ }
+
+ // Whenver we have async callbacks from native code, there is an ugly issue where
+ // during .NET shutdown native code could be calling the callback, but the CLR
+ // has already prohibited callbacks to managed code in the appdomain, causing the CLR
+ // to throw a COMPLUS_BOOT_EXCEPTION. The guideline we give is that you must unregister
+ // such callbacks on process shutdown or appdomain so that unmanaged code will never
+ // do this. This is what this callback is for.
+ // See bug 724140 for more
+ private static void DisposeOnShutdown(object sender, EventArgs e)
+ {
+ lock (EventListenersLock)
+ {
+ foreach (var esRef in s_EventSources)
+ {
+ EventSource es = esRef.Target as EventSource;
+ if (es != null)
+ es.Dispose();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Helper used in code:Dispose that removes any references to 'listenerToRemove' in any of the
+ /// eventSources in the appdomain.
+ ///
+ /// The EventListenersLock must be held before calling this routine.
+ /// </summary>
+ private static void RemoveReferencesToListenerInEventSources(EventListener listenerToRemove)
+ {
+#if !ES_BUILD_STANDALONE
+ Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
+#endif
+ // Foreach existing EventSource in the appdomain
+ foreach (WeakReference eventSourceRef in s_EventSources)
+ {
+ EventSource eventSource = eventSourceRef.Target as EventSource;
+ if (eventSource != null)
+ {
+ // Is the first output dispatcher the dispatcher we are removing?
+ if (eventSource.m_Dispatchers.m_Listener == listenerToRemove)
+ eventSource.m_Dispatchers = eventSource.m_Dispatchers.m_Next;
+ else
+ {
+ // Remove 'listenerToRemove' from the eventSource.m_Dispatchers linked list.
+ EventDispatcher prev = eventSource.m_Dispatchers;
+ for (;;)
+ {
+ EventDispatcher cur = prev.m_Next;
+ if (cur == null)
+ {
+ Debug.Assert(false, "EventSource did not have a registered EventListener!");
+ break;
+ }
+ if (cur.m_Listener == listenerToRemove)
+ {
+ prev.m_Next = cur.m_Next; // Remove entry.
+ break;
+ }
+ prev = cur;
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Checks internal consistency of EventSources/Listeners.
+ /// </summary>
+ [Conditional("DEBUG")]
+ internal static void Validate()
+ {
+ lock (EventListenersLock)
+ {
+ // Get all listeners
+ Dictionary<EventListener, bool> allListeners = new Dictionary<EventListener, bool>();
+ EventListener cur = s_Listeners;
+ while (cur != null)
+ {
+ allListeners.Add(cur, true);
+ cur = cur.m_Next;
+ }
+
+ // For all eventSources
+ int id = -1;
+ foreach (WeakReference eventSourceRef in s_EventSources)
+ {
+ id++;
+ EventSource eventSource = eventSourceRef.Target as EventSource;
+ if (eventSource == null)
+ continue;
+ Debug.Assert(eventSource.m_id == id, "Unexpected event source ID.");
+
+ // None listeners on eventSources exist in the dispatcher list.
+ EventDispatcher dispatcher = eventSource.m_Dispatchers;
+ while (dispatcher != null)
+ {
+ Debug.Assert(allListeners.ContainsKey(dispatcher.m_Listener), "EventSource has a listener not on the global list.");
+ dispatcher = dispatcher.m_Next;
+ }
+
+ // Every dispatcher is on Dispatcher List of every eventSource.
+ foreach (EventListener listener in allListeners.Keys)
+ {
+ dispatcher = eventSource.m_Dispatchers;
+ for (;;)
+ {
+ Debug.Assert(dispatcher != null, "Listener is not on all eventSources.");
+ if (dispatcher.m_Listener == listener)
+ break;
+ dispatcher = dispatcher.m_Next;
+ }
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets a global lock that is intended to protect the code:s_Listeners linked list and the
+ /// code:s_EventSources WeakReference list. (We happen to use the s_EventSources list as
+ /// the lock object)
+ /// </summary>
+ internal static object EventListenersLock
+ {
+ get
+ {
+ if (s_EventSources == null)
+ Interlocked.CompareExchange(ref s_EventSources, new List<WeakReference>(2), null);
+ return s_EventSources;
+ }
+ }
+
+ private void CallBackForExistingEventSources(bool addToListenersList, EventHandler<EventSourceCreatedEventArgs> callback)
+ {
+ lock (EventListenersLock)
+ {
+ // Disallow creating EventListener reentrancy.
+ if (s_CreatingListener)
+ {
+ throw new InvalidOperationException(Resources.GetResourceString("EventSource_ListenerCreatedInsideCallback"));
+ }
+
+ try
+ {
+ s_CreatingListener = true;
+
+ if (addToListenersList)
+ {
+ // Add to list of listeners in the system, do this BEFORE firing the 'OnEventSourceCreated' so that
+ // Those added sources see this listener.
+ this.m_Next = s_Listeners;
+ s_Listeners = this;
+ }
+
+ // Find all existing eventSources call OnEventSourceCreated to 'catchup'
+ // Note that we DO have reentrancy here because 'AddListener' calls out to user code (via OnEventSourceCreated callback)
+ // We tolerate this by iterating over a copy of the list here. New event sources will take care of adding listeners themselves
+ // EventSources are not guaranteed to be added at the end of the s_EventSource list -- We re-use slots when a new source
+ // is created.
+ WeakReference[] eventSourcesSnapshot = s_EventSources.ToArray();
+
+ for (int i = 0; i < eventSourcesSnapshot.Length; i++)
+ {
+ WeakReference eventSourceRef = eventSourcesSnapshot[i];
+ EventSource eventSource = eventSourceRef.Target as EventSource;
+ if (eventSource != null)
+ {
+ EventSourceCreatedEventArgs args = new EventSourceCreatedEventArgs();
+ args.EventSource = eventSource;
+ callback(this, args);
+ }
+ }
+
+ Validate();
+ }
+ finally
+ {
+ s_CreatingListener = false;
+ }
+ }
+
+ }
+
+ // Instance fields
+ internal volatile EventListener m_Next; // These form a linked list in s_Listeners
+#if FEATURE_ACTIVITYSAMPLING
+ internal ActivityFilter m_activityFilter; // If we are filtering by activity on this Listener, this keeps track of it.
+#endif // FEATURE_ACTIVITYSAMPLING
+
+ // static fields
+
+ /// <summary>
+ /// The list of all listeners in the appdomain. Listeners must be explicitly disposed to remove themselves
+ /// from this list. Note that EventSources point to their listener but NOT the reverse.
+ /// </summary>
+ internal static EventListener s_Listeners;
+ /// <summary>
+ /// The list of all active eventSources in the appdomain. Note that eventSources do NOT
+ /// remove themselves from this list this is a weak list and the GC that removes them may
+ /// not have happened yet. Thus it can contain event sources that are dead (thus you have
+ /// to filter those out.
+ /// </summary>
+ internal static List<WeakReference> s_EventSources;
+
+ /// <summary>
+ /// Used to disallow reentrancy.
+ /// </summary>
+ private static bool s_CreatingListener = false;
+
+ /// <summary>
+ /// Used to register AD/Process shutdown callbacks.
+ /// </summary>
+ private static bool s_EventSourceShutdownRegistered = false;
+ #endregion
+ }
+
+ /// <summary>
+ /// Passed to the code:EventSource.OnEventCommand callback
+ /// </summary>
+ public class EventCommandEventArgs : EventArgs
+ {
+ /// <summary>
+ /// Gets the command for the callback.
+ /// </summary>
+ public EventCommand Command { get; internal set; }
+
+ /// <summary>
+ /// Gets the arguments for the callback.
+ /// </summary>
+ public IDictionary<String, String> Arguments { get; internal set; }
+
+ /// <summary>
+ /// Enables the event that has the specified identifier.
+ /// </summary>
+ /// <param name="eventId">Event ID of event to be enabled</param>
+ /// <returns>true if eventId is in range</returns>
+ public bool EnableEvent(int eventId)
+ {
+ if (Command != EventCommand.Enable && Command != EventCommand.Disable)
+ throw new InvalidOperationException();
+ return eventSource.EnableEventForDispatcher(dispatcher, eventId, true);
+ }
+
+ /// <summary>
+ /// Disables the event that have the specified identifier.
+ /// </summary>
+ /// <param name="eventId">Event ID of event to be disabled</param>
+ /// <returns>true if eventId is in range</returns>
+ public bool DisableEvent(int eventId)
+ {
+ if (Command != EventCommand.Enable && Command != EventCommand.Disable)
+ throw new InvalidOperationException();
+ return eventSource.EnableEventForDispatcher(dispatcher, eventId, false);
+ }
+
+ #region private
+
+ internal EventCommandEventArgs(EventCommand command, IDictionary<string, string> arguments, EventSource eventSource,
+ EventListener listener, int perEventSourceSessionId, int etwSessionId, bool enable, EventLevel level, EventKeywords matchAnyKeyword)
+ {
+ this.Command = command;
+ this.Arguments = arguments;
+ this.eventSource = eventSource;
+ this.listener = listener;
+ this.perEventSourceSessionId = perEventSourceSessionId;
+ this.etwSessionId = etwSessionId;
+ this.enable = enable;
+ this.level = level;
+ this.matchAnyKeyword = matchAnyKeyword;
+ }
+
+ internal EventSource eventSource;
+ internal EventDispatcher dispatcher;
+
+ // These are the arguments of sendCommand and are only used for deferring commands until after we are fully initialized.
+ internal EventListener listener;
+ internal int perEventSourceSessionId;
+ internal int etwSessionId;
+ internal bool enable;
+ internal EventLevel level;
+ internal EventKeywords matchAnyKeyword;
+ internal EventCommandEventArgs nextCommand; // We form a linked list of these deferred commands.
+
+ #endregion
+ }
+
+ /// <summary>
+ /// EventSourceCreatedEventArgs is passed to <see cref="EventListener.EventSourceCreated"/>
+ /// </summary>
+ public class EventSourceCreatedEventArgs : EventArgs
+ {
+ /// <summary>
+ /// The EventSource that is attaching to the listener.
+ /// </summary>
+ public EventSource EventSource
+ {
+ get;
+ internal set;
+ }
+ }
+
+ /// <summary>
+ /// EventWrittenEventArgs is passed to the user-provided override for
+ /// <see cref="EventListener.OnEventWritten"/> when an event is fired.
+ /// </summary>
+ public class EventWrittenEventArgs : EventArgs
+ {
+ /// <summary>
+ /// The name of the event.
+ /// </summary>
+ public string EventName
+ {
+ get
+ {
+ if (m_eventName != null || EventId < 0) // TraceLogging convention EventID == -1
+ {
+ return m_eventName;
+ }
+ else
+ return m_eventSource.m_eventData[EventId].Name;
+ }
+ internal set
+ {
+ m_eventName = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the event ID for the event that was written.
+ /// </summary>
+ public int EventId { get; internal set; }
+
+ /// <summary>
+ /// Gets the activity ID for the thread on which the event was written.
+ /// </summary>
+ public Guid ActivityId
+ {
+ get { return EventSource.CurrentThreadActivityId; }
+ }
+
+ /// <summary>
+ /// Gets the related activity ID if one was specified when the event was written.
+ /// </summary>
+ public Guid RelatedActivityId
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// Gets the payload for the event.
+ /// </summary>
+ public ReadOnlyCollection<Object> Payload { get; internal set; }
+
+ /// <summary>
+ /// Gets the payload argument names.
+ /// </summary>
+ public ReadOnlyCollection<string> PayloadNames
+ {
+ get
+ {
+ // For contract based events we create the list lazily.
+ if (m_payloadNames == null)
+ {
+ // Self described events are identified by id -1.
+ Debug.Assert(EventId != -1);
+
+ var names = new List<string>();
+ foreach (var parameter in m_eventSource.m_eventData[EventId].Parameters)
+ {
+ names.Add(parameter.Name);
+ }
+ m_payloadNames = new ReadOnlyCollection<string>(names);
+ }
+
+ return m_payloadNames;
+ }
+
+ internal set
+ {
+ m_payloadNames = value;
+ }
+ }
+
+ /// <summary>
+ /// Gets the event source object.
+ /// </summary>
+ public EventSource EventSource { get { return m_eventSource; } }
+
+ /// <summary>
+ /// Gets the keywords for the event.
+ /// </summary>
+ public EventKeywords Keywords
+ {
+ get
+ {
+ if (EventId < 0) // TraceLogging convention EventID == -1
+ return m_keywords;
+
+ return (EventKeywords)m_eventSource.m_eventData[EventId].Descriptor.Keywords;
+ }
+ }
+
+ /// <summary>
+ /// Gets the operation code for the event.
+ /// </summary>
+ public EventOpcode Opcode
+ {
+ get
+ {
+ if (EventId <= 0) // TraceLogging convention EventID == -1
+ return m_opcode;
+ return (EventOpcode)m_eventSource.m_eventData[EventId].Descriptor.Opcode;
+ }
+ }
+
+ /// <summary>
+ /// Gets the task for the event.
+ /// </summary>
+ public EventTask Task
+ {
+ get
+ {
+ if (EventId <= 0) // TraceLogging convention EventID == -1
+ return EventTask.None;
+
+ return (EventTask)m_eventSource.m_eventData[EventId].Descriptor.Task;
+ }
+ }
+
+ /// <summary>
+ /// Any provider/user defined options associated with the event.
+ /// </summary>
+ public EventTags Tags
+ {
+ get
+ {
+ if (EventId <= 0) // TraceLogging convention EventID == -1
+ return m_tags;
+ return m_eventSource.m_eventData[EventId].Tags;
+ }
+ }
+
+ /// <summary>
+ /// Gets the message for the event. If the message has {N} parameters they are NOT substituted.
+ /// </summary>
+ public string Message
+ {
+ get
+ {
+ if (EventId <= 0) // TraceLogging convention EventID == -1
+ return m_message;
+ else
+ return m_eventSource.m_eventData[EventId].Message;
+ }
+ internal set
+ {
+ m_message = value;
+ }
+ }
+
+
+#if FEATURE_MANAGED_ETW_CHANNELS
+ /// <summary>
+ /// Gets the channel for the event.
+ /// </summary>
+ public EventChannel Channel
+ {
+ get
+ {
+ if (EventId <= 0) // TraceLogging convention EventID == -1
+ return EventChannel.None;
+ return (EventChannel)m_eventSource.m_eventData[EventId].Descriptor.Channel;
+ }
+ }
+#endif
+
+ /// <summary>
+ /// Gets the version of the event.
+ /// </summary>
+ public byte Version
+ {
+ get
+ {
+ if (EventId <= 0) // TraceLogging convention EventID == -1
+ return 0;
+ return m_eventSource.m_eventData[EventId].Descriptor.Version;
+ }
+ }
+
+ /// <summary>
+ /// Gets the level for the event.
+ /// </summary>
+ public EventLevel Level
+ {
+ get
+ {
+ if (EventId <= 0) // TraceLogging convention EventID == -1
+ return m_level;
+ return (EventLevel)m_eventSource.m_eventData[EventId].Descriptor.Level;
+ }
+ }
+
+ #region private
+ internal EventWrittenEventArgs(EventSource eventSource)
+ {
+ m_eventSource = eventSource;
+ }
+ private string m_message;
+ private string m_eventName;
+ private EventSource m_eventSource;
+ private ReadOnlyCollection<string> m_payloadNames;
+ internal EventTags m_tags;
+ internal EventOpcode m_opcode;
+ internal EventLevel m_level;
+ internal EventKeywords m_keywords;
+ #endregion
+ }
+
+ /// <summary>
+ /// Allows customizing defaults and specifying localization support for the event source class to which it is applied.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class)]
+ public sealed class EventSourceAttribute : Attribute
+ {
+ /// <summary>
+ /// Overrides the ETW name of the event source (which defaults to the class name)
+ /// </summary>
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Overrides the default (calculated) Guid of an EventSource type. Explicitly defining a GUID is discouraged,
+ /// except when upgrading existing ETW providers to using event sources.
+ /// </summary>
+ public string Guid { get; set; }
+
+ /// <summary>
+ /// <para>
+ /// EventSources support localization of events. The names used for events, opcodes, tasks, keywords and maps
+ /// can be localized to several languages if desired. This works by creating a ResX style string table
+ /// (by simply adding a 'Resource File' to your project). This resource file is given a name e.g.
+ /// 'DefaultNameSpace.ResourceFileName' which can be passed to the ResourceManager constructor to read the
+ /// resources. This name is the value of the LocalizationResources property.
+ /// </para><para>
+ /// If LocalizationResources property is non-null, then EventSource will look up the localized strings for events by
+ /// using the following resource naming scheme
+ /// </para>
+ /// <para>* event_EVENTNAME</para>
+ /// <para>* task_TASKNAME</para>
+ /// <para>* keyword_KEYWORDNAME</para>
+ /// <para>* map_MAPNAME</para>
+ /// <para>
+ /// where the capitalized name is the name of the event, task, keyword, or map value that should be localized.
+ /// Note that the localized string for an event corresponds to the Message string, and can have {0} values
+ /// which represent the payload values.
+ /// </para>
+ /// </summary>
+ public string LocalizationResources { get; set; }
+ }
+
+ /// <summary>
+ /// Any instance methods in a class that subclasses <see cref="EventSource"/> and that return void are
+ /// assumed by default to be methods that generate an ETW event. Enough information can be deduced from the
+ /// name of the method and its signature to generate basic schema information for the event. The
+ /// <see cref="EventAttribute"/> class allows you to specify additional event schema information for an event if
+ /// desired.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Method)]
+ public sealed class EventAttribute : Attribute
+ {
+ /// <summary>Construct an EventAttribute with specified eventId</summary>
+ /// <param name="eventId">ID of the ETW event (an integer between 1 and 65535)</param>
+ public EventAttribute(int eventId) { this.EventId = eventId; Level = EventLevel.Informational; this.m_opcodeSet = false; }
+ /// <summary>Event's ID</summary>
+ public int EventId { get; private set; }
+ /// <summary>Event's severity level: indicates the severity or verbosity of the event</summary>
+ public EventLevel Level { get; set; }
+ /// <summary>Event's keywords: allows classification of events by "categories"</summary>
+ public EventKeywords Keywords { get; set; }
+ /// <summary>Event's operation code: allows defining operations, generally used with Tasks</summary>
+ public EventOpcode Opcode
+ {
+ get
+ {
+ return m_opcode;
+ }
+ set
+ {
+ this.m_opcode = value;
+ this.m_opcodeSet = true;
+ }
+ }
+
+ internal bool IsOpcodeSet
+ {
+ get
+ {
+ return m_opcodeSet;
+ }
+ }
+
+ /// <summary>Event's task: allows logical grouping of events</summary>
+ public EventTask Task { get; set; }
+#if FEATURE_MANAGED_ETW_CHANNELS
+ /// <summary>Event's channel: defines an event log as an additional destination for the event</summary>
+ public EventChannel Channel { get; set; }
+#endif
+ /// <summary>Event's version</summary>
+ public byte Version { get; set; }
+
+ /// <summary>
+ /// This can be specified to enable formatting and localization of the event's payload. You can
+ /// use standard .NET substitution operators (eg {1}) in the string and they will be replaced
+ /// with the 'ToString()' of the corresponding part of the event payload.
+ /// </summary>
+ public string Message { get; set; }
+
+ /// <summary>
+ /// User defined options associated with the event. These do not have meaning to the EventSource but
+ /// are passed through to listeners which given them semantics.
+ /// </summary>
+ public EventTags Tags { get; set; }
+
+ /// <summary>
+ /// Allows fine control over the Activity IDs generated by start and stop events
+ /// </summary>
+ public EventActivityOptions ActivityOptions { get; set; }
+
+ #region private
+ EventOpcode m_opcode;
+ private bool m_opcodeSet;
+ #endregion
+ }
+
+ /// <summary>
+ /// By default all instance methods in a class that subclasses code:EventSource that and return
+ /// void are assumed to be methods that generate an event. This default can be overridden by specifying
+ /// the code:NonEventAttribute
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Method)]
+ public sealed class NonEventAttribute : Attribute
+ {
+ /// <summary>
+ /// Constructs a default NonEventAttribute
+ /// </summary>
+ public NonEventAttribute() { }
+ }
+
+ // FUTURE we may want to expose this at some point once we have a partner that can help us validate the design.
+#if FEATURE_MANAGED_ETW_CHANNELS
+ /// <summary>
+ /// EventChannelAttribute allows customizing channels supported by an EventSource. This attribute must be
+ /// applied to an member of type EventChannel defined in a Channels class nested in the EventSource class:
+ /// <code>
+ /// public static class Channels
+ /// {
+ /// [Channel(Enabled = true, EventChannelType = EventChannelType.Admin)]
+ /// public const EventChannel Admin = (EventChannel)16;
+ ///
+ /// [Channel(Enabled = false, EventChannelType = EventChannelType.Operational)]
+ /// public const EventChannel Operational = (EventChannel)17;
+ /// }
+ /// </code>
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Field)]
+#if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
+ public
+#endif
+ class EventChannelAttribute : Attribute
+ {
+ /// <summary>
+ /// Specified whether the channel is enabled by default
+ /// </summary>
+ public bool Enabled { get; set; }
+
+ /// <summary>
+ /// Legal values are in EventChannelType
+ /// </summary>
+ public EventChannelType EventChannelType { get; set; }
+
+#if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
+ /// <summary>
+ /// Specifies the isolation for the channel
+ /// </summary>
+ public EventChannelIsolation Isolation { get; set; }
+
+ /// <summary>
+ /// Specifies an SDDL access descriptor that controls access to the log file that backs the channel.
+ /// See MSDN ((http://msdn.microsoft.com/en-us/library/windows/desktop/aa382741.aspx) for details.
+ /// </summary>
+ public string Access { get; set; }
+
+ /// <summary>
+ /// Allows importing channels defined in external manifests
+ /// </summary>
+ public string ImportChannel { get; set; }
+#endif
+
+ // TODO: there is a convention that the name is the Provider/Type Should we provide an override?
+ // public string Name { get; set; }
+ }
+
+ /// <summary>
+ /// Allowed channel types
+ /// </summary>
+#if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
+ public
+#endif
+ enum EventChannelType
+ {
+ /// <summary>The admin channel</summary>
+ Admin = 1,
+ /// <summary>The operational channel</summary>
+ Operational,
+ /// <summary>The Analytic channel</summary>
+ Analytic,
+ /// <summary>The debug channel</summary>
+ Debug,
+ }
+
+#if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
+ /// <summary>
+ /// Allowed isolation levels. See MSDN (http://msdn.microsoft.com/en-us/library/windows/desktop/aa382741.aspx)
+ /// for the default permissions associated with each level. EventChannelIsolation and Access allows control over the
+ /// access permissions for the channel and backing file.
+ /// </summary>
+ public
+ enum EventChannelIsolation
+ {
+ /// <summary>
+ /// This is the default isolation level. All channels that specify Application isolation use the same ETW session
+ /// </summary>
+ Application = 1,
+ /// <summary>
+ /// All channels that specify System isolation use the same ETW session
+ /// </summary>
+ System,
+ /// <summary>
+ /// Use sparingly! When specifying Custom isolation, a separate ETW session is created for the channel.
+ /// Using Custom isolation lets you control the access permissions for the channel and backing file.
+ /// Because there are only 64 ETW sessions available, you should limit your use of Custom isolation.
+ /// </summary>
+ Custom,
+ }
+#endif
+#endif
+
+ /// <summary>
+ /// Describes the pre-defined command (EventCommandEventArgs.Command property) that is passed to the OnEventCommand callback.
+ /// </summary>
+ public enum EventCommand
+ {
+ /// <summary>
+ /// Update EventSource state
+ /// </summary>
+ Update = 0,
+ /// <summary>
+ /// Request EventSource to generate and send its manifest
+ /// </summary>
+ SendManifest = -1,
+ /// <summary>
+ /// Enable event
+ /// </summary>
+ Enable = -2,
+ /// <summary>
+ /// Disable event
+ /// </summary>
+ Disable = -3
+ };
+
+
+ #region private classes
+
+#if FEATURE_ACTIVITYSAMPLING
+
+ /// <summary>
+ /// ActivityFilter is a helper structure that is used to keep track of run-time state
+ /// associated with activity filtering. It is 1-1 with EventListeners (logically
+ /// every listener has one of these, however we actually allocate them lazily), as well
+ /// as 1-to-1 with tracing-aware EtwSessions.
+ ///
+ /// This structure also keeps track of the sampling counts associated with 'trigger'
+ /// events. Because these trigger events are rare, and you typically only have one of
+ /// them, we store them here as a linked list.
+ /// </summary>
+ internal sealed class ActivityFilter : IDisposable
+ {
+ /// <summary>
+ /// Disable all activity filtering for the listener associated with 'filterList',
+ /// (in the session associated with it) that is triggered by any event in 'source'.
+ /// </summary>
+ public static void DisableFilter(ref ActivityFilter filterList, EventSource source)
+ {
+#if !ES_BUILD_STANDALONE
+ Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
+#endif
+
+ if (filterList == null)
+ return;
+
+ ActivityFilter cur;
+ // Remove it from anywhere in the list (except the first element, which has to
+ // be treated specially)
+ ActivityFilter prev = filterList;
+ cur = prev.m_next;
+ while (cur != null)
+ {
+ if (cur.m_providerGuid == source.Guid)
+ {
+ // update TriggersActivityTracking bit
+ if (cur.m_eventId >= 0 && cur.m_eventId < source.m_eventData.Length)
+ --source.m_eventData[cur.m_eventId].TriggersActivityTracking;
+
+ // Remove it from the linked list.
+ prev.m_next = cur.m_next;
+ // dispose of the removed node
+ cur.Dispose();
+ // update cursor
+ cur = prev.m_next;
+ }
+ else
+ {
+ // update cursors
+ prev = cur;
+ cur = prev.m_next;
+ }
+ }
+
+ // Sadly we have to treat the first element specially in linked list removal in C#
+ if (filterList.m_providerGuid == source.Guid)
+ {
+ // update TriggersActivityTracking bit
+ if (filterList.m_eventId >= 0 && filterList.m_eventId < source.m_eventData.Length)
+ --source.m_eventData[filterList.m_eventId].TriggersActivityTracking;
+
+ // We are the first element in the list.
+ var first = filterList;
+ filterList = first.m_next;
+ // dispose of the removed node
+ first.Dispose();
+ }
+ // the above might have removed the one ActivityFilter in the session that contains the
+ // cleanup delegate; re-create the delegate if needed
+ if (filterList != null)
+ {
+ EnsureActivityCleanupDelegate(filterList);
+ }
+ }
+
+ /// <summary>
+ /// Currently this has "override" semantics. We first disable all filters
+ /// associated with 'source', and next we add new filters for each entry in the
+ /// string 'startEvents'. participateInSampling specifies whether non-startEvents
+ /// always trigger or only trigger when current activity is 'active'.
+ /// </summary>
+ public static void UpdateFilter(
+ ref ActivityFilter filterList,
+ EventSource source,
+ int perEventSourceSessionId,
+ string startEvents)
+ {
+#if !ES_BUILD_STANDALONE
+ Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
+#endif
+
+ // first remove all filters associated with 'source'
+ DisableFilter(ref filterList, source);
+
+ if (!string.IsNullOrEmpty(startEvents))
+ {
+ // ActivitySamplingStartEvents is a space-separated list of Event:Frequency pairs.
+ // The Event may be specified by name or by ID. Errors in parsing such a pair
+ // result in the error being reported to the listeners, and the pair being ignored.
+ // E.g. "CustomActivityStart:1000 12:10" specifies that for event CustomActivityStart
+ // we should initiate activity tracing once every 1000 events, *and* for event ID 12
+ // we should initiate activity tracing once every 10 events.
+ string[] activityFilterStrings = startEvents.Split(' ');
+
+ for (int i = 0; i < activityFilterStrings.Length; ++i)
+ {
+ string activityFilterString = activityFilterStrings[i];
+ int sampleFreq = 1;
+ int eventId = -1;
+ int colonIdx = activityFilterString.IndexOf(':');
+ if (colonIdx < 0)
+ {
+ source.ReportOutOfBandMessage("ERROR: Invalid ActivitySamplingStartEvent specification: " +
+ activityFilterString, false);
+ // ignore failure...
+ continue;
+ }
+ string sFreq = activityFilterString.Substring(colonIdx + 1);
+ if (!int.TryParse(sFreq, out sampleFreq))
+ {
+ source.ReportOutOfBandMessage("ERROR: Invalid sampling frequency specification: " + sFreq, false);
+ continue;
+ }
+ activityFilterString = activityFilterString.Substring(0, colonIdx);
+ if (!int.TryParse(activityFilterString, out eventId))
+ {
+ // reset eventId
+ eventId = -1;
+ // see if it's an event name
+ for (int j = 0; j < source.m_eventData.Length; j++)
+ {
+ EventSource.EventMetadata[] ed = source.m_eventData;
+ if (ed[j].Name != null && ed[j].Name.Length == activityFilterString.Length &&
+ string.Compare(ed[j].Name, activityFilterString, StringComparison.OrdinalIgnoreCase) == 0)
+ {
+ eventId = ed[j].Descriptor.EventId;
+ break;
+ }
+ }
+ }
+ if (eventId < 0 || eventId >= source.m_eventData.Length)
+ {
+ source.ReportOutOfBandMessage("ERROR: Invalid eventId specification: " + activityFilterString, false);
+ continue;
+ }
+ EnableFilter(ref filterList, source, perEventSourceSessionId, eventId, sampleFreq);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns the first ActivityFilter from 'filterList' corresponding to 'source'.
+ /// </summary>
+ public static ActivityFilter GetFilter(ActivityFilter filterList, EventSource source)
+ {
+ for (var af = filterList; af != null; af = af.m_next)
+ {
+ if (af.m_providerGuid == source.Guid && af.m_samplingFreq != -1)
+ return af;
+ }
+ return null;
+ }
+
+ /// <summary>
+ /// Returns a session mask representing all sessions in which the activity
+ /// associated with the current thread is allowed through the activity filter.
+ /// If 'triggeringEvent' is true the event MAY be a triggering event. Ideally
+ /// most of the time this is false as you can guarentee this event is NOT a
+ /// triggering event. If 'triggeringEvent' is true, then it checks the
+ /// 'EventSource' and 'eventID' of the event being logged to see if it is actually
+ /// a trigger. If so it activates the current activity.
+ ///
+ /// If 'childActivityID' is present, it will be added to the active set if the
+ /// current activity is active.
+ /// </summary>
+ unsafe public static bool PassesActivityFilter(
+ ActivityFilter filterList,
+ Guid* childActivityID,
+ bool triggeringEvent,
+ EventSource source,
+ int eventId)
+ {
+ Debug.Assert(filterList != null && filterList.m_activeActivities != null);
+ bool shouldBeLogged = false;
+ if (triggeringEvent)
+ {
+ for (ActivityFilter af = filterList; af != null; af = af.m_next)
+ {
+ if (eventId == af.m_eventId && source.Guid == af.m_providerGuid)
+ {
+ // Update the sampling count with wrap-around
+ int curSampleCount, newSampleCount;
+ do
+ {
+ curSampleCount = af.m_curSampleCount;
+ if (curSampleCount <= 1)
+ newSampleCount = af.m_samplingFreq; // Wrap around, counting down to 1
+ else
+ newSampleCount = curSampleCount - 1;
+ }
+ while (Interlocked.CompareExchange(ref af.m_curSampleCount, newSampleCount, curSampleCount) != curSampleCount);
+ // If we hit zero, then start tracking the activity.
+ if (curSampleCount <= 1)
+ {
+ Guid currentActivityId = EventSource.InternalCurrentThreadActivityId;
+ Tuple<Guid, int> startId;
+ // only add current activity if it's not already a root activity
+ if (!af.m_rootActiveActivities.TryGetValue(currentActivityId, out startId))
+ {
+ // EventSource.OutputDebugString(string.Format(" PassesAF - Triggering(session {0}, evt {1})", af.m_perEventSourceSessionId, eventId));
+ shouldBeLogged = true;
+ af.m_activeActivities[currentActivityId] = Environment.TickCount;
+ af.m_rootActiveActivities[currentActivityId] = Tuple.Create(source.Guid, eventId);
+ }
+ }
+ else
+ {
+ // a start event following a triggering start event
+ Guid currentActivityId = EventSource.InternalCurrentThreadActivityId;
+ Tuple<Guid, int> startId;
+ // only remove current activity if we added it
+ if (af.m_rootActiveActivities.TryGetValue(currentActivityId, out startId) &&
+ startId.Item1 == source.Guid && startId.Item2 == eventId)
+ {
+ // EventSource.OutputDebugString(string.Format("Activity dying: {0} -> StartEvent({1})", currentActivityId, eventId));
+ // remove activity only from current logging scope (af)
+ int dummy;
+ af.m_activeActivities.TryRemove(currentActivityId, out dummy);
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ var activeActivities = GetActiveActivities(filterList);
+ if (activeActivities != null)
+ {
+ // if we hadn't already determined this should be logged, test further
+ if (!shouldBeLogged)
+ {
+ shouldBeLogged = !activeActivities.IsEmpty &&
+ activeActivities.ContainsKey(EventSource.InternalCurrentThreadActivityId);
+ }
+ if (shouldBeLogged && childActivityID != null &&
+ ((EventOpcode)source.m_eventData[eventId].Descriptor.Opcode == EventOpcode.Send))
+ {
+ FlowActivityIfNeeded(filterList, null, childActivityID);
+ // EventSource.OutputDebugString(string.Format(" PassesAF - activity {0}", *childActivityID));
+ }
+ }
+ // EventSource.OutputDebugString(string.Format(" PassesAF - shouldBeLogged(evt {0}) = {1:x}", eventId, shouldBeLogged));
+ return shouldBeLogged;
+ }
+
+ public static bool IsCurrentActivityActive(ActivityFilter filterList)
+ {
+ var activeActivities = GetActiveActivities(filterList);
+ if (activeActivities != null &&
+ activeActivities.ContainsKey(EventSource.InternalCurrentThreadActivityId))
+ return true;
+
+ return false;
+ }
+
+ /// <summary>
+ /// For the EventListener/EtwSession associated with 'filterList', add 'childActivityid'
+ /// to list of active activities IF 'currentActivityId' is also active. Passing in a null
+ /// value for 'currentActivityid' is an indication tha caller has already verified
+ /// that the current activity is active.
+ /// </summary>
+ unsafe public static void FlowActivityIfNeeded(ActivityFilter filterList, Guid* currentActivityId, Guid* childActivityID)
+ {
+ Debug.Assert(childActivityID != null);
+
+ var activeActivities = GetActiveActivities(filterList);
+ Debug.Assert(activeActivities != null);
+
+ // take currentActivityId == null to mean we *know* the current activity is "active"
+ if (currentActivityId != null && !activeActivities.ContainsKey(*currentActivityId))
+ return;
+
+ if (activeActivities.Count > MaxActivityTrackCount)
+ {
+ TrimActiveActivityStore(activeActivities);
+ // make sure current activity is still in the set:
+ activeActivities[EventSource.InternalCurrentThreadActivityId] = Environment.TickCount;
+ }
+ // add child activity to list of actives
+ activeActivities[*childActivityID] = Environment.TickCount;
+
+ }
+
+ /// <summary>
+ /// </summary>
+ public static void UpdateKwdTriggers(ActivityFilter activityFilter, Guid sourceGuid, EventSource source, EventKeywords sessKeywords)
+ {
+ for (var af = activityFilter; af != null; af = af.m_next)
+ {
+ if ((sourceGuid == af.m_providerGuid) &&
+ (source.m_eventData[af.m_eventId].TriggersActivityTracking > 0 ||
+ ((EventOpcode)source.m_eventData[af.m_eventId].Descriptor.Opcode == EventOpcode.Send)))
+ {
+ // we could be more precise here, if we tracked 'anykeywords' per session
+ unchecked
+ {
+ source.m_keywordTriggers |= (source.m_eventData[af.m_eventId].Descriptor.Keywords & (long)sessKeywords);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// For the EventSource specified by 'sourceGuid' and the EventListener/EtwSession
+ /// associated with 'this' ActivityFilter list, return configured sequence of
+ /// [eventId, sampleFreq] pairs that defines the sampling policy.
+ /// </summary>
+ public IEnumerable<Tuple<int, int>> GetFilterAsTuple(Guid sourceGuid)
+ {
+ for (ActivityFilter af = this; af != null; af = af.m_next)
+ {
+ if (af.m_providerGuid == sourceGuid)
+ yield return Tuple.Create(af.m_eventId, af.m_samplingFreq);
+ }
+ }
+
+ /// <summary>
+ /// The cleanup being performed consists of removing the m_myActivityDelegate from
+ /// the static s_activityDying, therefore allowing the ActivityFilter to be reclaimed.
+ /// </summary>
+ public void Dispose()
+ {
+#if !ES_BUILD_STANDALONE
+ Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
+#endif
+ // m_myActivityDelegate is still alive (held by the static EventSource.s_activityDying).
+ // Therefore we are ok to take a dependency on m_myActivityDelegate being valid even
+ // during the finalization of the ActivityFilter
+ if (m_myActivityDelegate != null)
+ {
+ EventSource.s_activityDying = (Action<Guid>)Delegate.Remove(EventSource.s_activityDying, m_myActivityDelegate);
+ m_myActivityDelegate = null;
+ }
+ }
+
+ #region private
+
+ /// <summary>
+ /// Creates a new ActivityFilter that is triggered by 'eventId' from 'source' ever
+ /// 'samplingFreq' times the event fires. You can have several of these forming a
+ /// linked list.
+ /// </summary>
+ private ActivityFilter(EventSource source, int perEventSourceSessionId, int eventId, int samplingFreq, ActivityFilter existingFilter = null)
+ {
+ m_providerGuid = source.Guid;
+ m_perEventSourceSessionId = perEventSourceSessionId;
+ m_eventId = eventId;
+ m_samplingFreq = samplingFreq;
+ m_next = existingFilter;
+
+ Debug.Assert(existingFilter == null ||
+ (existingFilter.m_activeActivities == null) == (existingFilter.m_rootActiveActivities == null));
+
+ // if this is the first filter we add for this session, we need to create a new
+ // table of activities. m_activeActivities is common across EventSources in the same
+ // session
+ ConcurrentDictionary<Guid, int> activeActivities = null;
+ if (existingFilter == null ||
+ (activeActivities = GetActiveActivities(existingFilter)) == null)
+ {
+ m_activeActivities = new ConcurrentDictionary<Guid, int>();
+ m_rootActiveActivities = new ConcurrentDictionary<Guid, Tuple<Guid, int>>();
+
+ // Add a delegate to the 'SetCurrentThreadToActivity callback so that I remove 'dead' activities
+ m_myActivityDelegate = GetActivityDyingDelegate(this);
+ EventSource.s_activityDying = (Action<Guid>)Delegate.Combine(EventSource.s_activityDying, m_myActivityDelegate);
+ }
+ else
+ {
+ m_activeActivities = activeActivities;
+ m_rootActiveActivities = existingFilter.m_rootActiveActivities;
+ }
+
+ }
+
+ /// <summary>
+ /// Ensure there's at least one ActivityFilter in the 'filterList' that contains an
+ /// activity-removing delegate for the listener/session associated with 'filterList'.
+ /// </summary>
+ private static void EnsureActivityCleanupDelegate(ActivityFilter filterList)
+ {
+ if (filterList == null)
+ return;
+
+ for (ActivityFilter af = filterList; af != null; af = af.m_next)
+ {
+ if (af.m_myActivityDelegate != null)
+ return;
+ }
+
+ // we didn't find a delegate
+ filterList.m_myActivityDelegate = GetActivityDyingDelegate(filterList);
+ EventSource.s_activityDying = (Action<Guid>)Delegate.Combine(EventSource.s_activityDying, filterList.m_myActivityDelegate);
+ }
+
+ /// <summary>
+ /// Builds the delegate to be called when an activity is dying. This is responsible
+ /// for performing whatever cleanup is needed for the ActivityFilter list passed in.
+ /// This gets "added" to EventSource.s_activityDying and ends up being called from
+ /// EventSource.SetCurrentThreadActivityId and ActivityFilter.PassesActivityFilter.
+ /// </summary>
+ /// <returns>The delegate to be called when an activity is dying</returns>
+ private static Action<Guid> GetActivityDyingDelegate(ActivityFilter filterList)
+ {
+ return (Guid oldActivity) =>
+ {
+ int dummy;
+ filterList.m_activeActivities.TryRemove(oldActivity, out dummy);
+ Tuple<Guid, int> dummyTuple;
+ filterList.m_rootActiveActivities.TryRemove(oldActivity, out dummyTuple);
+ };
+ }
+
+ /// <summary>
+ /// Enables activity filtering for the listener associated with 'filterList', triggering on
+ /// the event 'eventID' from 'source' with a sampling frequency of 'samplingFreq'
+ ///
+ /// if 'eventID' is out of range (e.g. negative), it means we are not triggering (but we are
+ /// activitySampling if something else triggered).
+ /// </summary>
+ /// <returns>true if activity sampling is enabled the samplingFreq is non-zero </returns>
+ private static bool EnableFilter(ref ActivityFilter filterList, EventSource source, int perEventSourceSessionId, int eventId, int samplingFreq)
+ {
+#if !ES_BUILD_STANDALONE
+ Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
+#endif
+ Debug.Assert(samplingFreq > 0);
+ Debug.Assert(eventId >= 0);
+
+ filterList = new ActivityFilter(source, perEventSourceSessionId, eventId, samplingFreq, filterList);
+
+ // Mark the 'quick Check' that indicates this is a trigger event.
+ // If eventId is out of range then this mark is not done which has the effect of ignoring
+ // the trigger.
+ if (0 <= eventId && eventId < source.m_eventData.Length)
+ ++source.m_eventData[eventId].TriggersActivityTracking;
+
+ return true;
+ }
+
+ /// <summary>
+ /// Normally this code never runs, it is here just to prevent run-away resource usage.
+ /// </summary>
+ private static void TrimActiveActivityStore(ConcurrentDictionary<Guid, int> activities)
+ {
+ if (activities.Count > MaxActivityTrackCount)
+ {
+ // Remove half of the oldest activity ids.
+ var keyValues = activities.ToArray();
+ var tickNow = Environment.TickCount;
+
+ // Sort by age, taking into account wrap-around. As long as x and y are within
+ // 23 days of now then (0x7FFFFFFF & (tickNow - x.Value)) is the delta (even if
+ // TickCount wraps). I then sort by DESCENDING age. (that is oldest value first)
+ Array.Sort(keyValues, (x, y) => (0x7FFFFFFF & (tickNow - y.Value)) - (0x7FFFFFFF & (tickNow - x.Value)));
+ for (int i = 0; i < keyValues.Length / 2; i++)
+ {
+ int dummy;
+ activities.TryRemove(keyValues[i].Key, out dummy);
+ }
+ }
+ }
+
+ private static ConcurrentDictionary<Guid, int> GetActiveActivities(
+ ActivityFilter filterList)
+ {
+ for (ActivityFilter af = filterList; af != null; af = af.m_next)
+ {
+ if (af.m_activeActivities != null)
+ return af.m_activeActivities;
+ }
+ return null;
+ }
+
+ // m_activeActivities always points to the sample dictionary for EVERY ActivityFilter
+ // in the m_next list. The 'int' value in the m_activities set is a timestamp
+ // (Environment.TickCount) of when the entry was put in the system and is used to
+ // remove 'old' entries that if the set gets too big.
+ ConcurrentDictionary<Guid, int> m_activeActivities;
+
+ // m_rootActiveActivities holds the "root" active activities, i.e. the activities
+ // that were marked as active because a Start event fired on them. We need to keep
+ // track of these to enable sampling in the scenario of an app's main thread that
+ // never explicitly sets distinct activity IDs as it executes. To handle these
+ // situations we manufacture a Guid from the thread's ID, and:
+ // (a) we consider the firing of a start event when the sampling counter reaches
+ // zero to mark the beginning of an interesting activity, and
+ // (b) we consider the very next firing of the same start event to mark the
+ // ending of that activity.
+ // We use a ConcurrentDictionary to avoid taking explicit locks.
+ // The key (a guid) represents the activity ID of the root active activity
+ // The value is made up of the Guid of the event provider and the eventId of
+ // the start event.
+ ConcurrentDictionary<Guid, Tuple<Guid, int>> m_rootActiveActivities;
+ Guid m_providerGuid; // We use the GUID rather than object identity because we don't want to keep the eventSource alive
+ int m_eventId; // triggering event
+ int m_samplingFreq; // Counter reset to this when it hits 0
+ int m_curSampleCount; // We count down to 0 and then activate the activity.
+ int m_perEventSourceSessionId; // session ID bit for ETW, 0 for EventListeners
+
+ const int MaxActivityTrackCount = 100000; // maximum number of tracked activities
+
+ ActivityFilter m_next; // We create a linked list of these
+ Action<Guid> m_myActivityDelegate;
+ #endregion
+ };
+
+
+ /// <summary>
+ /// An EtwSession instance represents an activity-tracing-aware ETW session. Since these
+ /// are limited to 8 concurrent sessions per machine (currently) we're going to store
+ /// the active ones in a singly linked list.
+ /// </summary>
+ internal class EtwSession
+ {
+ public static EtwSession GetEtwSession(int etwSessionId, bool bCreateIfNeeded = false)
+ {
+ if (etwSessionId < 0)
+ return null;
+
+ EtwSession etwSession;
+ foreach (var wrEtwSession in s_etwSessions)
+ {
+#if ES_BUILD_STANDALONE
+ if ((etwSession = (EtwSession) wrEtwSession.Target) != null && etwSession.m_etwSessionId == etwSessionId)
+ return etwSession;
+#else
+ if (wrEtwSession.TryGetTarget(out etwSession) && etwSession.m_etwSessionId == etwSessionId)
+ return etwSession;
+#endif
+ }
+
+ if (!bCreateIfNeeded)
+ return null;
+
+#if ES_BUILD_STANDALONE
+ if (s_etwSessions == null)
+ s_etwSessions = new List<WeakReference>();
+
+ etwSession = new EtwSession(etwSessionId);
+ s_etwSessions.Add(new WeakReference(etwSession));
+#else
+ if (s_etwSessions == null)
+ s_etwSessions = new List<WeakReference<EtwSession>>();
+
+ etwSession = new EtwSession(etwSessionId);
+ s_etwSessions.Add(new WeakReference<EtwSession>(etwSession));
+#endif
+
+ if (s_etwSessions.Count > s_thrSessionCount)
+ TrimGlobalList();
+
+ return etwSession;
+
+ }
+
+ public static void RemoveEtwSession(EtwSession etwSession)
+ {
+ Debug.Assert(etwSession != null);
+ if (s_etwSessions == null || etwSession == null)
+ return;
+
+ s_etwSessions.RemoveAll((wrEtwSession) =>
+ {
+ EtwSession session;
+#if ES_BUILD_STANDALONE
+ return (session = (EtwSession) wrEtwSession.Target) != null &&
+ (session.m_etwSessionId == etwSession.m_etwSessionId);
+#else
+ return wrEtwSession.TryGetTarget(out session) &&
+ (session.m_etwSessionId == etwSession.m_etwSessionId);
+#endif
+ });
+
+ if (s_etwSessions.Count > s_thrSessionCount)
+ TrimGlobalList();
+ }
+
+ private static void TrimGlobalList()
+ {
+ if (s_etwSessions == null)
+ return;
+
+ s_etwSessions.RemoveAll((wrEtwSession) =>
+ {
+#if ES_BUILD_STANDALONE
+ return wrEtwSession.Target == null;
+#else
+ EtwSession session;
+ return !wrEtwSession.TryGetTarget(out session);
+#endif
+ });
+ }
+
+ private EtwSession(int etwSessionId)
+ {
+ m_etwSessionId = etwSessionId;
+ }
+
+ public readonly int m_etwSessionId; // ETW session ID (as retrieved by EventProvider)
+ public ActivityFilter m_activityFilter; // all filters enabled for this session
+
+#if ES_BUILD_STANDALONE
+ private static List<WeakReference> s_etwSessions = new List<WeakReference>();
+#else
+ private static List<WeakReference<EtwSession>> s_etwSessions = new List<WeakReference<EtwSession>>();
+#endif
+ private const int s_thrSessionCount = 16;
+ }
+
+#endif // FEATURE_ACTIVITYSAMPLING
+
+ // holds a bitfield representing a session mask
+ /// <summary>
+ /// A SessionMask represents a set of (at most MAX) sessions as a bit mask. The perEventSourceSessionId
+ /// is the index in the SessionMask of the bit that will be set. These can translate to
+ /// EventSource's reserved keywords bits using the provided ToEventKeywords() and
+ /// FromEventKeywords() methods.
+ /// </summary>
+ internal struct SessionMask
+ {
+ public SessionMask(SessionMask m)
+ { m_mask = m.m_mask; }
+
+ public SessionMask(uint mask = 0)
+ { m_mask = mask & MASK; }
+
+ public bool IsEqualOrSupersetOf(SessionMask m)
+ {
+ return (this.m_mask | m.m_mask) == this.m_mask;
+ }
+
+ public static SessionMask All
+ {
+ get { return new SessionMask(MASK); }
+ }
+
+ public static SessionMask FromId(int perEventSourceSessionId)
+ {
+ Debug.Assert(perEventSourceSessionId < MAX);
+ return new SessionMask((uint)1 << perEventSourceSessionId);
+ }
+
+ public ulong ToEventKeywords()
+ {
+ return (ulong)m_mask << SHIFT_SESSION_TO_KEYWORD;
+ }
+
+ public static SessionMask FromEventKeywords(ulong m)
+ {
+ return new SessionMask((uint)(m >> SHIFT_SESSION_TO_KEYWORD));
+ }
+
+ public bool this[int perEventSourceSessionId]
+ {
+ get
+ {
+ Debug.Assert(perEventSourceSessionId < MAX);
+ return (m_mask & (1 << perEventSourceSessionId)) != 0;
+ }
+ set
+ {
+ Debug.Assert(perEventSourceSessionId < MAX);
+ if (value) m_mask |= ((uint)1 << perEventSourceSessionId);
+ else m_mask &= ~((uint)1 << perEventSourceSessionId);
+ }
+ }
+
+ public static SessionMask operator |(SessionMask m1, SessionMask m2)
+ {
+ return new SessionMask(m1.m_mask | m2.m_mask);
+ }
+
+ public static SessionMask operator &(SessionMask m1, SessionMask m2)
+ {
+ return new SessionMask(m1.m_mask & m2.m_mask);
+ }
+
+ public static SessionMask operator ^(SessionMask m1, SessionMask m2)
+ {
+ return new SessionMask(m1.m_mask ^ m2.m_mask);
+ }
+
+ public static SessionMask operator ~(SessionMask m)
+ {
+ return new SessionMask(MASK & ~(m.m_mask));
+ }
+
+ public static explicit operator ulong(SessionMask m)
+ { return m.m_mask; }
+
+ public static explicit operator uint(SessionMask m)
+ { return m.m_mask; }
+
+ private uint m_mask;
+
+ internal const int SHIFT_SESSION_TO_KEYWORD = 44; // bits 44-47 inclusive are reserved
+ internal const uint MASK = 0x0fU; // the mask of 4 reserved bits
+ internal const uint MAX = 4; // maximum number of simultaneous ETW sessions supported
+ }
+
+ /// <summary>
+ /// code:EventDispatchers are a simple 'helper' structure that holds the filtering state
+ /// (m_EventEnabled) for a particular EventSource X EventListener tuple
+ ///
+ /// Thus a single EventListener may have many EventDispatchers (one for every EventSource
+ /// that that EventListener has activate) and a Single EventSource may also have many
+ /// event Dispatchers (one for every EventListener that has activated it).
+ ///
+ /// Logically a particular EventDispatcher belongs to exactly one EventSource and exactly
+ /// one EventListener (alhtough EventDispatcher does not 'remember' the EventSource it is
+ /// associated with.
+ /// </summary>
+ internal class EventDispatcher
+ {
+ internal EventDispatcher(EventDispatcher next, bool[] eventEnabled, EventListener listener)
+ {
+ m_Next = next;
+ m_EventEnabled = eventEnabled;
+ m_Listener = listener;
+ }
+
+ // Instance fields
+ readonly internal EventListener m_Listener; // The dispatcher this entry is for
+ internal bool[] m_EventEnabled; // For every event in a the eventSource, is it enabled?
+#if FEATURE_ACTIVITYSAMPLING
+ internal bool m_activityFilteringEnabled; // does THIS EventSource have activity filtering turned on for this listener?
+#endif // FEATURE_ACTIVITYSAMPLING
+
+ // Only guaranteed to exist after a InsureInit()
+ internal EventDispatcher m_Next; // These form a linked list in code:EventSource.m_Dispatchers
+ // Of all listeners for that eventSource.
+ }
+
+ /// <summary>
+ /// Flags that can be used with EventSource.GenerateManifest to control how the ETW manifest for the EventSource is
+ /// generated.
+ /// </summary>
+ [Flags]
+ public enum EventManifestOptions
+ {
+ /// <summary>
+ /// Only the resources associated with current UI culture are included in the manifest
+ /// </summary>
+ None = 0x0,
+ /// <summary>
+ /// Throw exceptions for any inconsistency encountered
+ /// </summary>
+ Strict = 0x1,
+ /// <summary>
+ /// Generate a "resources" node under "localization" for every satellite assembly provided
+ /// </summary>
+ AllCultures = 0x2,
+ /// <summary>
+ /// Generate the manifest only if the event source needs to be registered on the machine,
+ /// otherwise return null (but still perform validation if Strict is specified)
+ /// </summary>
+ OnlyIfNeededForRegistration = 0x4,
+ /// <summary>
+ /// When generating the manifest do *not* enforce the rule that the current EventSource class
+ /// must be the base class for the user-defined type passed in. This allows validation of .net
+ /// event sources using the new validation code
+ /// </summary>
+ AllowEventSourceOverride = 0x8,
+ }
+
+ /// <summary>
+ /// ManifestBuilder is designed to isolate the details of the message of the event from the
+ /// rest of EventSource. This one happens to create XML.
+ /// </summary>
+ internal partial class ManifestBuilder
+ {
+ /// <summary>
+ /// Build a manifest for 'providerName' with the given GUID, which will be packaged into 'dllName'.
+ /// 'resources, is a resource manager. If specified all messages are localized using that manager.
+ /// </summary>
+ public ManifestBuilder(string providerName, Guid providerGuid, string dllName, ResourceManager resources,
+ EventManifestOptions flags)
+ {
+#if FEATURE_MANAGED_ETW_CHANNELS
+ this.providerName = providerName;
+#endif
+ this.flags = flags;
+
+ this.resources = resources;
+ sb = new StringBuilder();
+ events = new StringBuilder();
+ templates = new StringBuilder();
+ opcodeTab = new Dictionary<int, string>();
+ stringTab = new Dictionary<string, string>();
+ errors = new List<string>();
+ perEventByteArrayArgIndices = new Dictionary<string, List<int>>();
+
+ sb.AppendLine("<instrumentationManifest xmlns=\"http://schemas.microsoft.com/win/2004/08/events\">");
+ sb.AppendLine(" <instrumentation xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:win=\"http://manifests.microsoft.com/win/2004/08/windows/events\">");
+ sb.AppendLine(" <events xmlns=\"http://schemas.microsoft.com/win/2004/08/events\">");
+ sb.Append("<provider name=\"").Append(providerName).
+ Append("\" guid=\"{").Append(providerGuid.ToString()).Append("}");
+ if (dllName != null)
+ sb.Append("\" resourceFileName=\"").Append(dllName).Append("\" messageFileName=\"").Append(dllName);
+
+ var symbolsName = providerName.Replace("-", "").Replace(".", "_"); // Period and - are illegal replace them.
+ sb.Append("\" symbol=\"").Append(symbolsName);
+ sb.Append("\">").AppendLine();
+ }
+
+ public void AddOpcode(string name, int value)
+ {
+ if ((flags & EventManifestOptions.Strict) != 0)
+ {
+ if (value <= 10 || value >= 239)
+ {
+ ManifestError(Resources.GetResourceString("EventSource_IllegalOpcodeValue", name, value));
+ }
+ string prevName;
+ if (opcodeTab.TryGetValue(value, out prevName) && !name.Equals(prevName, StringComparison.Ordinal))
+ {
+ ManifestError(Resources.GetResourceString("EventSource_OpcodeCollision", name, prevName, value));
+ }
+ }
+ opcodeTab[value] = name;
+ }
+ public void AddTask(string name, int value)
+ {
+ if ((flags & EventManifestOptions.Strict) != 0)
+ {
+ if (value <= 0 || value >= 65535)
+ {
+ ManifestError(Resources.GetResourceString("EventSource_IllegalTaskValue", name, value));
+ }
+ string prevName;
+ if (taskTab != null && taskTab.TryGetValue(value, out prevName) && !name.Equals(prevName, StringComparison.Ordinal))
+ {
+ ManifestError(Resources.GetResourceString("EventSource_TaskCollision", name, prevName, value));
+ }
+ }
+ if (taskTab == null)
+ taskTab = new Dictionary<int, string>();
+ taskTab[value] = name;
+ }
+ public void AddKeyword(string name, ulong value)
+ {
+ if ((value & (value - 1)) != 0) // Is it a power of 2?
+ {
+ ManifestError(Resources.GetResourceString("EventSource_KeywordNeedPowerOfTwo", "0x" + value.ToString("x", CultureInfo.CurrentCulture), name), true);
+ }
+ if ((flags & EventManifestOptions.Strict) != 0)
+ {
+ if (value >= 0x0000100000000000UL && !name.StartsWith("Session", StringComparison.Ordinal))
+ {
+ ManifestError(Resources.GetResourceString("EventSource_IllegalKeywordsValue", name, "0x" + value.ToString("x", CultureInfo.CurrentCulture)));
+ }
+ string prevName;
+ if (keywordTab != null && keywordTab.TryGetValue(value, out prevName) && !name.Equals(prevName, StringComparison.Ordinal))
+ {
+ ManifestError(Resources.GetResourceString("EventSource_KeywordCollision", name, prevName, "0x" + value.ToString("x", CultureInfo.CurrentCulture)));
+ }
+ }
+ if (keywordTab == null)
+ keywordTab = new Dictionary<ulong, string>();
+ keywordTab[value] = name;
+ }
+
+#if FEATURE_MANAGED_ETW_CHANNELS
+ /// <summary>
+ /// Add a channel. channelAttribute can be null
+ /// </summary>
+ public void AddChannel(string name, int value, EventChannelAttribute channelAttribute)
+ {
+ EventChannel chValue = (EventChannel)value;
+ if (value < (int)EventChannel.Admin || value > 255)
+ ManifestError(Resources.GetResourceString("EventSource_EventChannelOutOfRange", name, value));
+ else if (chValue >= EventChannel.Admin && chValue <= EventChannel.Debug &&
+ channelAttribute != null && EventChannelToChannelType(chValue) != channelAttribute.EventChannelType)
+ {
+ // we want to ensure developers do not define EventChannels that conflict with the builtin ones,
+ // but we want to allow them to override the default ones...
+ ManifestError(Resources.GetResourceString("EventSource_ChannelTypeDoesNotMatchEventChannelValue",
+ name, ((EventChannel)value).ToString()));
+ }
+
+ // TODO: validate there are no conflicting manifest exposed names (generally following the format "provider/type")
+
+ ulong kwd = GetChannelKeyword(chValue);
+
+ if (channelTab == null)
+ channelTab = new Dictionary<int, ChannelInfo>(4);
+ channelTab[value] = new ChannelInfo { Name = name, Keywords = kwd, Attribs = channelAttribute };
+ }
+
+ private EventChannelType EventChannelToChannelType(EventChannel channel)
+ {
+#if !ES_BUILD_STANDALONE
+ Debug.Assert(channel >= EventChannel.Admin && channel <= EventChannel.Debug);
+#endif
+ return (EventChannelType)((int)channel - (int)EventChannel.Admin + (int)EventChannelType.Admin);
+ }
+ private EventChannelAttribute GetDefaultChannelAttribute(EventChannel channel)
+ {
+ EventChannelAttribute attrib = new EventChannelAttribute();
+ attrib.EventChannelType = EventChannelToChannelType(channel);
+ if (attrib.EventChannelType <= EventChannelType.Operational)
+ attrib.Enabled = true;
+ return attrib;
+ }
+
+ public ulong[] GetChannelData()
+ {
+ if (this.channelTab == null)
+ {
+ return new ulong[0];
+ }
+
+ // We create an array indexed by the channel id for fast look up.
+ // E.g. channelMask[Admin] will give you the bit mask for Admin channel.
+ int maxkey = -1;
+ foreach (var item in this.channelTab.Keys)
+ {
+ if (item > maxkey)
+ {
+ maxkey = item;
+ }
+ }
+
+ ulong[] channelMask = new ulong[maxkey + 1];
+ foreach (var item in this.channelTab)
+ {
+ channelMask[item.Key] = item.Value.Keywords;
+ }
+
+ return channelMask;
+ }
+
+#endif
+ public void StartEvent(string eventName, EventAttribute eventAttribute)
+ {
+ Debug.Assert(numParams == 0);
+ Debug.Assert(this.eventName == null);
+ this.eventName = eventName;
+ numParams = 0;
+ byteArrArgIndices = null;
+
+ events.Append(" <event").
+ Append(" value=\"").Append(eventAttribute.EventId).Append("\"").
+ Append(" version=\"").Append(eventAttribute.Version).Append("\"").
+ Append(" level=\"").Append(GetLevelName(eventAttribute.Level)).Append("\"").
+ Append(" symbol=\"").Append(eventName).Append("\"");
+
+ // at this point we add to the manifest's stringTab a message that is as-of-yet
+ // "untranslated to manifest convention", b/c we don't have the number or position
+ // of any byte[] args (which require string format index updates)
+ WriteMessageAttrib(events, "event", eventName, eventAttribute.Message);
+
+ if (eventAttribute.Keywords != 0)
+ events.Append(" keywords=\"").Append(GetKeywords((ulong)eventAttribute.Keywords, eventName)).Append("\"");
+ if (eventAttribute.Opcode != 0)
+ events.Append(" opcode=\"").Append(GetOpcodeName(eventAttribute.Opcode, eventName)).Append("\"");
+ if (eventAttribute.Task != 0)
+ events.Append(" task=\"").Append(GetTaskName(eventAttribute.Task, eventName)).Append("\"");
+#if FEATURE_MANAGED_ETW_CHANNELS
+ if (eventAttribute.Channel != 0)
+ {
+ events.Append(" channel=\"").Append(GetChannelName(eventAttribute.Channel, eventName, eventAttribute.Message)).Append("\"");
+ }
+#endif
+ }
+
+ public void AddEventParameter(Type type, string name)
+ {
+ if (numParams == 0)
+ templates.Append(" <template tid=\"").Append(eventName).Append("Args\">").AppendLine();
+ if (type == typeof(byte[]))
+ {
+ // mark this index as "extraneous" (it has no parallel in the managed signature)
+ // we use these values in TranslateToManifestConvention()
+ if (byteArrArgIndices == null)
+ byteArrArgIndices = new List<int>(4);
+ byteArrArgIndices.Add(numParams);
+
+ // add an extra field to the template representing the length of the binary blob
+ numParams++;
+ templates.Append(" <data name=\"").Append(name).Append("Size\" inType=\"win:UInt32\"/>").AppendLine();
+ }
+ numParams++;
+ templates.Append(" <data name=\"").Append(name).Append("\" inType=\"").Append(GetTypeName(type)).Append("\"");
+ // TODO: for 'byte*' types it assumes the user provided length is named using the same naming convention
+ // as for 'byte[]' args (blob_arg_name + "Size")
+ if ((type.IsArray || type.IsPointer) && type.GetElementType() == typeof(byte))
+ {
+ // add "length" attribute to the "blob" field in the template (referencing the field added above)
+ templates.Append(" length=\"").Append(name).Append("Size\"");
+ }
+ // ETW does not support 64-bit value maps, so we don't specify these as ETW maps
+ if (type.IsEnum() && Enum.GetUnderlyingType(type) != typeof(UInt64) && Enum.GetUnderlyingType(type) != typeof(Int64))
+ {
+ templates.Append(" map=\"").Append(type.Name).Append("\"");
+ if (mapsTab == null)
+ mapsTab = new Dictionary<string, Type>();
+ if (!mapsTab.ContainsKey(type.Name))
+ mapsTab.Add(type.Name, type); // Remember that we need to dump the type enumeration
+ }
+
+ templates.Append("/>").AppendLine();
+ }
+ public void EndEvent()
+ {
+ if (numParams > 0)
+ {
+ templates.Append(" </template>").AppendLine();
+ events.Append(" template=\"").Append(eventName).Append("Args\"");
+ }
+ events.Append("/>").AppendLine();
+
+ if (byteArrArgIndices != null)
+ perEventByteArrayArgIndices[eventName] = byteArrArgIndices;
+
+ // at this point we have all the information we need to translate the C# Message
+ // to the manifest string we'll put in the stringTab
+ string msg;
+ if (stringTab.TryGetValue("event_" + eventName, out msg))
+ {
+ msg = TranslateToManifestConvention(msg, eventName);
+ stringTab["event_" + eventName] = msg;
+ }
+
+ eventName = null;
+ numParams = 0;
+ byteArrArgIndices = null;
+ }
+
+#if FEATURE_MANAGED_ETW_CHANNELS
+ // Channel keywords are generated one per channel to allow channel based filtering in event viewer. These keywords are autogenerated
+ // by mc.exe for compiling a manifest and are based on the order of the channels (fields) in the Channels inner class (when advanced
+ // channel support is enabled), or based on the order the predefined channels appear in the EventAttribute properties (for simple
+ // support). The manifest generated *MUST* have the channels specified in the same order (that's how our computed keywords are mapped
+ // to channels by the OS infrastructure).
+ // If channelKeyworkds is present, and has keywords bits in the ValidPredefinedChannelKeywords then it is
+ // assumed that that the keyword for that channel should be that bit.
+ // otherwise we allocate a channel bit for the channel.
+ // explicit channel bits are only used by WCF to mimic an existing manifest,
+ // so we don't dont do error checking.
+ public ulong GetChannelKeyword(EventChannel channel, ulong channelKeyword = 0)
+ {
+ // strip off any non-channel keywords, since we are only interested in channels here.
+ channelKeyword &= ValidPredefinedChannelKeywords;
+ if (channelTab == null)
+ {
+ channelTab = new Dictionary<int, ChannelInfo>(4);
+ }
+
+ if (channelTab.Count == MaxCountChannels)
+ ManifestError(Resources.GetResourceString("EventSource_MaxChannelExceeded"));
+
+ ChannelInfo info;
+ if (!channelTab.TryGetValue((int)channel, out info))
+ {
+ // If we were not given an explicit channel, allocate one.
+ if (channelKeyword != 0)
+ {
+ channelKeyword = nextChannelKeywordBit;
+ nextChannelKeywordBit >>= 1;
+ }
+ }
+ else
+ {
+ channelKeyword = info.Keywords;
+ }
+
+ return channelKeyword;
+ }
+#endif
+
+ public byte[] CreateManifest()
+ {
+ string str = CreateManifestString();
+ return Encoding.UTF8.GetBytes(str);
+ }
+
+ public IList<string> Errors { get { return errors; } }
+
+ /// <summary>
+ /// When validating an event source it adds the error to the error collection.
+ /// When not validating it throws an exception if runtimeCritical is "true".
+ /// Otherwise the error is ignored.
+ /// </summary>
+ /// <param name="msg"></param>
+ /// <param name="runtimeCritical"></param>
+ public void ManifestError(string msg, bool runtimeCritical = false)
+ {
+ if ((flags & EventManifestOptions.Strict) != 0)
+ errors.Add(msg);
+ else if (runtimeCritical)
+ throw new ArgumentException(msg);
+ }
+
+ private string CreateManifestString()
+ {
+
+#if FEATURE_MANAGED_ETW_CHANNELS
+ // Write out the channels
+ if (channelTab != null)
+ {
+ sb.Append(" <channels>").AppendLine();
+ var sortedChannels = new List<KeyValuePair<int, ChannelInfo>>();
+ foreach (KeyValuePair<int, ChannelInfo> p in channelTab) { sortedChannels.Add(p); }
+ sortedChannels.Sort((p1, p2) => -Comparer<ulong>.Default.Compare(p1.Value.Keywords, p2.Value.Keywords));
+ foreach (var kvpair in sortedChannels)
+ {
+ int channel = kvpair.Key;
+ ChannelInfo channelInfo = kvpair.Value;
+
+ string channelType = null;
+ string elementName = "channel";
+ bool enabled = false;
+ string fullName = null;
+#if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
+ string isolation = null;
+ string access = null;
+#endif
+ if (channelInfo.Attribs != null)
+ {
+ var attribs = channelInfo.Attribs;
+ if (Enum.IsDefined(typeof(EventChannelType), attribs.EventChannelType))
+ channelType = attribs.EventChannelType.ToString();
+ enabled = attribs.Enabled;
+#if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
+ if (attribs.ImportChannel != null)
+ {
+ fullName = attribs.ImportChannel;
+ elementName = "importChannel";
+ }
+ if (Enum.IsDefined(typeof(EventChannelIsolation), attribs.Isolation))
+ isolation = attribs.Isolation.ToString();
+ access = attribs.Access;
+#endif
+ }
+ if (fullName == null)
+ fullName = providerName + "/" + channelInfo.Name;
+
+ sb.Append(" <").Append(elementName);
+ sb.Append(" chid=\"").Append(channelInfo.Name).Append("\"");
+ sb.Append(" name=\"").Append(fullName).Append("\"");
+ if (elementName == "channel") // not applicable to importChannels.
+ {
+ WriteMessageAttrib(sb, "channel", channelInfo.Name, null);
+ sb.Append(" value=\"").Append(channel).Append("\"");
+ if (channelType != null)
+ sb.Append(" type=\"").Append(channelType).Append("\"");
+ sb.Append(" enabled=\"").Append(enabled.ToString().ToLower()).Append("\"");
+#if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
+ if (access != null)
+ sb.Append(" access=\"").Append(access).Append("\"");
+ if (isolation != null)
+ sb.Append(" isolation=\"").Append(isolation).Append("\"");
+#endif
+ }
+ sb.Append("/>").AppendLine();
+ }
+ sb.Append(" </channels>").AppendLine();
+ }
+#endif
+
+ // Write out the tasks
+ if (taskTab != null)
+ {
+
+ sb.Append(" <tasks>").AppendLine();
+ var sortedTasks = new List<int>(taskTab.Keys);
+ sortedTasks.Sort();
+ foreach (int task in sortedTasks)
+ {
+ sb.Append(" <task");
+ WriteNameAndMessageAttribs(sb, "task", taskTab[task]);
+ sb.Append(" value=\"").Append(task).Append("\"/>").AppendLine();
+ }
+ sb.Append(" </tasks>").AppendLine();
+ }
+
+ // Write out the maps
+ if (mapsTab != null)
+ {
+ sb.Append(" <maps>").AppendLine();
+ foreach (Type enumType in mapsTab.Values)
+ {
+ bool isbitmap = EventSource.GetCustomAttributeHelper(enumType, typeof(FlagsAttribute), flags) != null;
+ string mapKind = isbitmap ? "bitMap" : "valueMap";
+ sb.Append(" <").Append(mapKind).Append(" name=\"").Append(enumType.Name).Append("\">").AppendLine();
+
+ // write out each enum value
+ FieldInfo[] staticFields = enumType.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static);
+ foreach (FieldInfo staticField in staticFields)
+ {
+ object constantValObj = staticField.GetRawConstantValue();
+ if (constantValObj != null)
+ {
+ long hexValue;
+ if (constantValObj is int)
+ hexValue = ((int)constantValObj);
+ else if (constantValObj is long)
+ hexValue = ((long)constantValObj);
+ else
+ continue;
+
+ // ETW requires all bitmap values to be powers of 2. Skip the ones that are not.
+ // TODO: Warn people about the dropping of values.
+ if (isbitmap && ((hexValue & (hexValue - 1)) != 0 || hexValue == 0))
+ continue;
+
+ sb.Append(" <map value=\"0x").Append(hexValue.ToString("x", CultureInfo.InvariantCulture)).Append("\"");
+ WriteMessageAttrib(sb, "map", enumType.Name + "." + staticField.Name, staticField.Name);
+ sb.Append("/>").AppendLine();
+ }
+ }
+ sb.Append(" </").Append(mapKind).Append(">").AppendLine();
+ }
+ sb.Append(" </maps>").AppendLine();
+ }
+
+ // Write out the opcodes
+ sb.Append(" <opcodes>").AppendLine();
+ var sortedOpcodes = new List<int>(opcodeTab.Keys);
+ sortedOpcodes.Sort();
+ foreach (int opcode in sortedOpcodes)
+ {
+ sb.Append(" <opcode");
+ WriteNameAndMessageAttribs(sb, "opcode", opcodeTab[opcode]);
+ sb.Append(" value=\"").Append(opcode).Append("\"/>").AppendLine();
+ }
+ sb.Append(" </opcodes>").AppendLine();
+
+ // Write out the keywords
+ if (keywordTab != null)
+ {
+ sb.Append(" <keywords>").AppendLine();
+ var sortedKeywords = new List<ulong>(keywordTab.Keys);
+ sortedKeywords.Sort();
+ foreach (ulong keyword in sortedKeywords)
+ {
+ sb.Append(" <keyword");
+ WriteNameAndMessageAttribs(sb, "keyword", keywordTab[keyword]);
+ sb.Append(" mask=\"0x").Append(keyword.ToString("x", CultureInfo.InvariantCulture)).Append("\"/>").AppendLine();
+ }
+ sb.Append(" </keywords>").AppendLine();
+ }
+
+ sb.Append(" <events>").AppendLine();
+ sb.Append(events);
+ sb.Append(" </events>").AppendLine();
+
+ sb.Append(" <templates>").AppendLine();
+ if (templates.Length > 0)
+ {
+ sb.Append(templates);
+ }
+ else
+ {
+ // Work around a cornercase ETW issue where a manifest with no templates causes
+ // ETW events to not get sent to their associated channel.
+ sb.Append(" <template tid=\"_empty\"></template>").AppendLine();
+ }
+ sb.Append(" </templates>").AppendLine();
+
+ sb.Append("</provider>").AppendLine();
+ sb.Append("</events>").AppendLine();
+ sb.Append("</instrumentation>").AppendLine();
+
+ // Output the localization information.
+ sb.Append("<localization>").AppendLine();
+
+ List<CultureInfo> cultures = null;
+ if (resources != null && (flags & EventManifestOptions.AllCultures) != 0)
+ {
+ cultures = GetSupportedCultures(resources);
+ }
+ else
+ {
+ cultures = new List<CultureInfo>();
+ cultures.Add(CultureInfo.CurrentUICulture);
+ }
+#if ES_BUILD_STANDALONE || ES_BUILD_PN
+ var sortedStrings = new List<string>(stringTab.Keys);
+ sortedStrings.Sort();
+#else
+ // DD 947936
+ var sortedStrings = new string[stringTab.Keys.Count];
+ stringTab.Keys.CopyTo(sortedStrings, 0);
+ // Avoid using public Array.Sort as that attempts to access BinaryCompatibility. Unfortunately FrameworkEventSource gets called
+ // very early in the app domain creation, when _FusionStore is not set up yet, resulting in a failure to run the static constructory
+ // for BinaryCompatibility. This failure is then cached and a TypeInitializationException is thrown every time some code attampts to
+ // access BinaryCompatibility.
+ ArraySortHelper<string>.IntrospectiveSort(sortedStrings, 0, sortedStrings.Length, string.Compare);
+#endif
+ foreach (var ci in cultures)
+ {
+ sb.Append(" <resources culture=\"").Append(ci.Name).Append("\">").AppendLine();
+ sb.Append(" <stringTable>").AppendLine();
+
+ foreach (var stringKey in sortedStrings)
+ {
+ string val = GetLocalizedMessage(stringKey, ci, etwFormat: true);
+ sb.Append(" <string id=\"").Append(stringKey).Append("\" value=\"").Append(val).Append("\"/>").AppendLine();
+ }
+ sb.Append(" </stringTable>").AppendLine();
+ sb.Append(" </resources>").AppendLine();
+ }
+ sb.Append("</localization>").AppendLine();
+ sb.AppendLine("</instrumentationManifest>");
+ return sb.ToString();
+ }
+
+ #region private
+ private void WriteNameAndMessageAttribs(StringBuilder stringBuilder, string elementName, string name)
+ {
+ stringBuilder.Append(" name=\"").Append(name).Append("\"");
+ WriteMessageAttrib(sb, elementName, name, name);
+ }
+ private void WriteMessageAttrib(StringBuilder stringBuilder, string elementName, string name, string value)
+ {
+ string key = elementName + "_" + name;
+ // See if the user wants things localized.
+ if (resources != null)
+ {
+ // resource fallback: strings in the neutral culture will take precedence over inline strings
+ string localizedString = resources.GetString(key, CultureInfo.InvariantCulture);
+ if (localizedString != null)
+ value = localizedString;
+ }
+ if (value == null)
+ return;
+
+ stringBuilder.Append(" message=\"$(string.").Append(key).Append(")\"");
+ string prevValue;
+ if (stringTab.TryGetValue(key, out prevValue) && !prevValue.Equals(value))
+ {
+ ManifestError(Resources.GetResourceString("EventSource_DuplicateStringKey", key), true);
+ return;
+ }
+
+ stringTab[key] = value;
+ }
+ internal string GetLocalizedMessage(string key, CultureInfo ci, bool etwFormat)
+ {
+ string value = null;
+ if (resources != null)
+ {
+ string localizedString = resources.GetString(key, ci);
+ if (localizedString != null)
+ {
+ value = localizedString;
+ if (etwFormat && key.StartsWith("event_", StringComparison.Ordinal))
+ {
+ var evtName = key.Substring("event_".Length);
+ value = TranslateToManifestConvention(value, evtName);
+ }
+ }
+ }
+ if (etwFormat && value == null)
+ stringTab.TryGetValue(key, out value);
+
+ return value;
+ }
+
+ /// <summary>
+ /// There's no API to enumerate all languages an assembly is localized into, so instead
+ /// we enumerate through all the "known" cultures and attempt to load a corresponding satellite
+ /// assembly
+ /// </summary>
+ /// <param name="resources"></param>
+ /// <returns></returns>
+ private static List<CultureInfo> GetSupportedCultures(ResourceManager resources)
+ {
+ var cultures = new List<CultureInfo>();
+
+ if (!cultures.Contains(CultureInfo.CurrentUICulture))
+ cultures.Insert(0, CultureInfo.CurrentUICulture);
+ return cultures;
+ }
+
+ private static string GetLevelName(EventLevel level)
+ {
+ return (((int)level >= 16) ? "" : "win:") + level.ToString();
+ }
+
+#if FEATURE_MANAGED_ETW_CHANNELS
+ private string GetChannelName(EventChannel channel, string eventName, string eventMessage)
+ {
+ ChannelInfo info = null;
+ if (channelTab == null || !channelTab.TryGetValue((int)channel, out info))
+ {
+ if (channel < EventChannel.Admin) // || channel > EventChannel.Debug)
+ ManifestError(Resources.GetResourceString("EventSource_UndefinedChannel", channel, eventName));
+
+ // allow channels to be auto-defined. The well known ones get their well known names, and the
+ // rest get names Channel<N>. This allows users to modify the Manifest if they want more advanced features.
+ if (channelTab == null)
+ channelTab = new Dictionary<int, ChannelInfo>(4);
+
+ string channelName = channel.ToString(); // For well know channels this is a nice name, otherwise a number
+ if (EventChannel.Debug < channel)
+ channelName = "Channel" + channelName; // Add a 'Channel' prefix for numbers.
+
+ AddChannel(channelName, (int)channel, GetDefaultChannelAttribute(channel));
+ if (!channelTab.TryGetValue((int)channel, out info))
+ ManifestError(Resources.GetResourceString("EventSource_UndefinedChannel", channel, eventName));
+ }
+ // events that specify admin channels *must* have non-null "Message" attributes
+ if (resources != null && eventMessage == null)
+ eventMessage = resources.GetString("event_" + eventName, CultureInfo.InvariantCulture);
+ if (info.Attribs.EventChannelType == EventChannelType.Admin && eventMessage == null)
+ ManifestError(Resources.GetResourceString("EventSource_EventWithAdminChannelMustHaveMessage", eventName, info.Name));
+ return info.Name;
+ }
+#endif
+ private string GetTaskName(EventTask task, string eventName)
+ {
+ if (task == EventTask.None)
+ return "";
+
+ string ret;
+ if (taskTab == null)
+ taskTab = new Dictionary<int, string>();
+ if (!taskTab.TryGetValue((int)task, out ret))
+ ret = taskTab[(int)task] = eventName;
+ return ret;
+ }
+
+ private string GetOpcodeName(EventOpcode opcode, string eventName)
+ {
+ switch (opcode)
+ {
+ case EventOpcode.Info:
+ return "win:Info";
+ case EventOpcode.Start:
+ return "win:Start";
+ case EventOpcode.Stop:
+ return "win:Stop";
+ case EventOpcode.DataCollectionStart:
+ return "win:DC_Start";
+ case EventOpcode.DataCollectionStop:
+ return "win:DC_Stop";
+ case EventOpcode.Extension:
+ return "win:Extension";
+ case EventOpcode.Reply:
+ return "win:Reply";
+ case EventOpcode.Resume:
+ return "win:Resume";
+ case EventOpcode.Suspend:
+ return "win:Suspend";
+ case EventOpcode.Send:
+ return "win:Send";
+ case EventOpcode.Receive:
+ return "win:Receive";
+ }
+
+ string ret;
+ if (opcodeTab == null || !opcodeTab.TryGetValue((int)opcode, out ret))
+ {
+ ManifestError(Resources.GetResourceString("EventSource_UndefinedOpcode", opcode, eventName), true);
+ ret = null;
+ }
+ return ret;
+ }
+
+ private string GetKeywords(ulong keywords, string eventName)
+ {
+#if FEATURE_MANAGED_ETW_CHANNELS
+ // ignore keywords associate with channels
+ // See ValidPredefinedChannelKeywords def for more.
+ keywords &= ~ValidPredefinedChannelKeywords;
+#endif
+
+ string ret = "";
+ for (ulong bit = 1; bit != 0; bit <<= 1)
+ {
+ if ((keywords & bit) != 0)
+ {
+ string keyword = null;
+ if ((keywordTab == null || !keywordTab.TryGetValue(bit, out keyword)) &&
+ (bit >= (ulong)0x1000000000000))
+ {
+ // do not report Windows reserved keywords in the manifest (this allows the code
+ // to be resilient to potential renaming of these keywords)
+ keyword = string.Empty;
+ }
+ if (keyword == null)
+ {
+ ManifestError(Resources.GetResourceString("EventSource_UndefinedKeyword", "0x" + bit.ToString("x", CultureInfo.CurrentCulture), eventName), true);
+ keyword = string.Empty;
+ }
+ if (ret.Length != 0 && keyword.Length != 0)
+ ret = ret + " ";
+ ret = ret + keyword;
+ }
+ }
+ return ret;
+ }
+
+ private string GetTypeName(Type type)
+ {
+ if (type.IsEnum())
+ {
+ FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
+ var typeName = GetTypeName(fields[0].FieldType);
+ return typeName.Replace("win:Int", "win:UInt"); // ETW requires enums to be unsigned.
+ }
+
+ return GetTypeNameHelper(type);
+ }
+
+ private static void UpdateStringBuilder(ref StringBuilder stringBuilder, string eventMessage, int startIndex, int count)
+ {
+ if (stringBuilder == null)
+ stringBuilder = new StringBuilder();
+ stringBuilder.Append(eventMessage, startIndex, count);
+ }
+
+ private static readonly string[] s_escapes = { "&amp;", "&lt;", "&gt;", "&apos;", "&quot;", "%r", "%n", "%t" };
+ // Manifest messages use %N conventions for their message substitutions. Translate from
+ // .NET conventions. We can't use RegEx for this (we are in mscorlib), so we do it 'by hand'
+ private string TranslateToManifestConvention(string eventMessage, string evtName)
+ {
+ StringBuilder stringBuilder = null; // We lazily create this
+ int writtenSoFar = 0;
+ int chIdx = -1;
+ for (int i = 0; ;)
+ {
+ if (i >= eventMessage.Length)
+ {
+ if (stringBuilder == null)
+ return eventMessage;
+ UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
+ return stringBuilder.ToString();
+ }
+
+ if (eventMessage[i] == '%')
+ {
+ // handle format message escaping character '%' by escaping it
+ UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
+ stringBuilder.Append("%%");
+ i++;
+ writtenSoFar = i;
+ }
+ else if (i < eventMessage.Length - 1 &&
+ (eventMessage[i] == '{' && eventMessage[i + 1] == '{' || eventMessage[i] == '}' && eventMessage[i + 1] == '}'))
+ {
+ // handle C# escaped '{" and '}'
+ UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
+ stringBuilder.Append(eventMessage[i]);
+ i++; i++;
+ writtenSoFar = i;
+ }
+ else if (eventMessage[i] == '{')
+ {
+ int leftBracket = i;
+ i++;
+ int argNum = 0;
+ while (i < eventMessage.Length && Char.IsDigit(eventMessage[i]))
+ {
+ argNum = argNum * 10 + eventMessage[i] - '0';
+ i++;
+ }
+ if (i < eventMessage.Length && eventMessage[i] == '}')
+ {
+ i++;
+ UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, leftBracket - writtenSoFar);
+ int manIndex = TranslateIndexToManifestConvention(argNum, evtName);
+ stringBuilder.Append('%').Append(manIndex);
+ // An '!' after the insert specifier {n} will be interpreted as a literal.
+ // We'll escape it so that mc.exe does not attempt to consider it the
+ // beginning of a format string.
+ if (i < eventMessage.Length && eventMessage[i] == '!')
+ {
+ i++;
+ stringBuilder.Append("%!");
+ }
+ writtenSoFar = i;
+ }
+ else
+ {
+ ManifestError(Resources.GetResourceString("EventSource_UnsupportedMessageProperty", evtName, eventMessage));
+ }
+ }
+ else if ((chIdx = "&<>'\"\r\n\t".IndexOf(eventMessage[i])) >= 0)
+ {
+ UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
+ i++;
+ stringBuilder.Append(s_escapes[chIdx]);
+ writtenSoFar = i;
+ }
+ else
+ i++;
+ }
+ }
+
+ private int TranslateIndexToManifestConvention(int idx, string evtName)
+ {
+ List<int> byteArrArgIndices;
+ if (perEventByteArrayArgIndices.TryGetValue(evtName, out byteArrArgIndices))
+ {
+ foreach (var byArrIdx in byteArrArgIndices)
+ {
+ if (idx >= byArrIdx)
+ ++idx;
+ else
+ break;
+ }
+ }
+ return idx + 1;
+ }
+
+#if FEATURE_MANAGED_ETW_CHANNELS
+ class ChannelInfo
+ {
+ public string Name;
+ public ulong Keywords;
+ public EventChannelAttribute Attribs;
+ }
+#endif
+
+ Dictionary<int, string> opcodeTab;
+ Dictionary<int, string> taskTab;
+#if FEATURE_MANAGED_ETW_CHANNELS
+ Dictionary<int, ChannelInfo> channelTab;
+#endif
+ Dictionary<ulong, string> keywordTab;
+ Dictionary<string, Type> mapsTab;
+
+ Dictionary<string, string> stringTab; // Maps unlocalized strings to localized ones
+
+#if FEATURE_MANAGED_ETW_CHANNELS
+ // WCF used EventSource to mimic a existing ETW manifest. To support this
+ // in just their case, we allowed them to specify the keywords associated
+ // with their channels explicitly. ValidPredefinedChannelKeywords is
+ // this set of channel keywords that we allow to be explicitly set. You
+ // can ignore these bits otherwise.
+ internal const ulong ValidPredefinedChannelKeywords = 0xF000000000000000;
+ ulong nextChannelKeywordBit = 0x8000000000000000; // available Keyword bit to be used for next channel definition, grows down
+ const int MaxCountChannels = 8; // a manifest can defined at most 8 ETW channels
+#endif
+
+ StringBuilder sb; // Holds the provider information.
+ StringBuilder events; // Holds the events.
+ StringBuilder templates;
+
+#if FEATURE_MANAGED_ETW_CHANNELS
+ string providerName;
+#endif
+ ResourceManager resources; // Look up localized strings here.
+ EventManifestOptions flags;
+ IList<string> errors; // list of currently encountered errors
+ Dictionary<string, List<int>> perEventByteArrayArgIndices; // "event_name" -> List_of_Indices_of_Byte[]_Arg
+
+ // State we track between StartEvent and EndEvent.
+ string eventName; // Name of the event currently being processed.
+ int numParams; // keeps track of the number of args the event has.
+ List<int> byteArrArgIndices; // keeps track of the index of each byte[] argument
+ #endregion
+ }
+
+ /// <summary>
+ /// Used to send the m_rawManifest into the event dispatcher as a series of events.
+ /// </summary>
+ internal struct ManifestEnvelope
+ {
+ public const int MaxChunkSize = 0xFF00;
+ public enum ManifestFormats : byte
+ {
+ SimpleXmlFormat = 1, // simply dump the XML manifest as UTF8
+ }
+
+#if FEATURE_MANAGED_ETW
+ public ManifestFormats Format;
+ public byte MajorVersion;
+ public byte MinorVersion;
+ public byte Magic;
+ public ushort TotalChunks;
+ public ushort ChunkNumber;
+#endif
+ };
+
+ #endregion
+}
+
diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/EventSourceException.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/EventSourceException.cs
new file mode 100644
index 0000000000..88b8da93cd
--- /dev/null
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/EventSourceException.cs
@@ -0,0 +1,53 @@
+// 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.Serialization;
+
+#if ES_BUILD_STANDALONE
+using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment;
+#endif
+
+#if ES_BUILD_STANDALONE
+namespace Microsoft.Diagnostics.Tracing
+#else
+namespace System.Diagnostics.Tracing
+#endif
+{
+ /// <summary>
+ /// Exception that is thrown when an error occurs during EventSource operation.
+ /// </summary>
+#if !ES_BUILD_PCL
+ [Serializable]
+#endif
+ public class EventSourceException : Exception
+ {
+ /// <summary>
+ /// Initializes a new instance of the EventSourceException class.
+ /// </summary>
+ public EventSourceException() :
+ base(Resources.GetResourceString("EventSource_ListenerWriteFailure")) { }
+
+ /// <summary>
+ /// Initializes a new instance of the EventSourceException class with a specified error message.
+ /// </summary>
+ public EventSourceException(string message) : base(message) { }
+
+ /// <summary>
+ /// Initializes a new instance of the EventSourceException class with a specified error message
+ /// and a reference to the inner exception that is the cause of this exception.
+ /// </summary>
+ public EventSourceException(string message, Exception innerException) : base(message, innerException) { }
+
+#if !ES_BUILD_PCL
+ /// <summary>
+ /// Initializes a new instance of the EventSourceException class with serialized data.
+ /// </summary>
+ protected EventSourceException(SerializationInfo info, StreamingContext context) : base(info, context) { }
+#endif
+
+ internal EventSourceException(Exception innerException) :
+ base(Resources.GetResourceString("EventSource_ListenerWriteFailure"), innerException) { }
+ }
+}
diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/StubEnvironment.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/StubEnvironment.cs
new file mode 100644
index 0000000000..b365841d5f
--- /dev/null
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/StubEnvironment.cs
@@ -0,0 +1,381 @@
+// 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.Collections.Generic;
+
+#if ES_BUILD_STANDALONE
+namespace Microsoft.Diagnostics.Tracing.Internal
+#else
+namespace System.Diagnostics.Tracing.Internal
+#endif
+{
+#if ES_BUILD_AGAINST_DOTNET_V35
+ using Microsoft.Internal;
+#endif
+ using Microsoft.Reflection;
+ using System.Reflection;
+
+ internal static class Environment
+ {
+ public static readonly string NewLine = System.Environment.NewLine;
+
+ public static int TickCount
+ { get { return System.Environment.TickCount; } }
+
+ public static string GetResourceString(string key, params object[] args)
+ {
+ string fmt = rm.GetString(key);
+ if (fmt != null)
+ return string.Format(fmt, args);
+
+ string sargs = String.Empty;
+ foreach(var arg in args)
+ {
+ if (sargs != String.Empty)
+ sargs += ", ";
+ sargs += arg.ToString();
+ }
+
+ return key + " (" + sargs + ")";
+ }
+
+ public static string GetRuntimeResourceString(string key, params object[] args)
+ {
+ return GetResourceString(key, args);
+ }
+
+ private static System.Resources.ResourceManager rm = new System.Resources.ResourceManager("Microsoft.Diagnostics.Tracing.Messages", typeof(Environment).Assembly());
+ }
+}
+
+#if ES_BUILD_AGAINST_DOTNET_V35
+
+namespace Microsoft.Diagnostics.Contracts.Internal
+{
+ internal class Contract
+ {
+ public static void Assert(bool invariant)
+ {
+ Assert(invariant, string.Empty);
+ }
+ public static void Assert(bool invariant, string message)
+ {
+ if (!invariant)
+ {
+ if (System.Diagnostics.Debugger.IsAttached)
+ System.Diagnostics.Debugger.Break();
+ throw new Exception("Assertion failed: " + message);
+ }
+ }
+ public static void EndContractBlock()
+ { }
+ }
+}
+
+
+namespace Microsoft.Internal
+{
+ using System.Text;
+
+ internal static class Tuple
+ {
+ public static Tuple<T1> Create<T1>(T1 item1)
+ {
+ return new Tuple<T1>(item1);
+ }
+
+ public static Tuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2)
+ {
+ return new Tuple<T1, T2>(item1, item2);
+ }
+ }
+
+ [Serializable]
+ internal class Tuple<T1>
+ {
+ private readonly T1 m_Item1;
+
+ public T1 Item1 { get { return m_Item1; } }
+
+ public Tuple(T1 item1)
+ {
+ m_Item1 = item1;
+ }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append("(");
+ sb.Append(m_Item1);
+ sb.Append(")");
+ return sb.ToString();
+ }
+
+ int Size
+ {
+ get
+ {
+ return 1;
+ }
+ }
+ }
+
+ [Serializable]
+ public class Tuple<T1, T2>
+ {
+ private readonly T1 m_Item1;
+ private readonly T2 m_Item2;
+
+ public T1 Item1 { get { return m_Item1; } }
+ public T2 Item2 { get { return m_Item2; } }
+
+ public Tuple(T1 item1, T2 item2)
+ {
+ m_Item1 = item1;
+ m_Item2 = item2;
+ }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.Append("(");
+ sb.Append(m_Item1);
+ sb.Append(", ");
+ sb.Append(m_Item2);
+ sb.Append(")");
+ return sb.ToString();
+ }
+
+ int Size
+ {
+ get
+ {
+ return 2;
+ }
+ }
+ }
+}
+
+#endif
+
+namespace Microsoft.Reflection
+{
+ using System.Reflection;
+
+#if ES_BUILD_PCL
+ [Flags]
+ public enum BindingFlags
+ {
+ DeclaredOnly = 0x02, // Only look at the members declared on the Type
+ Instance = 0x04, // Include Instance members in search
+ Static = 0x08, // Include Static members in search
+ Public = 0x10, // Include Public members in search
+ NonPublic = 0x20, // Include Non-Public members in search
+ }
+
+ public enum TypeCode {
+ Empty = 0, // Null reference
+ Object = 1, // Instance that isn't a value
+ DBNull = 2, // Database null value
+ Boolean = 3, // Boolean
+ Char = 4, // Unicode character
+ SByte = 5, // Signed 8-bit integer
+ Byte = 6, // Unsigned 8-bit integer
+ Int16 = 7, // Signed 16-bit integer
+ UInt16 = 8, // Unsigned 16-bit integer
+ Int32 = 9, // Signed 32-bit integer
+ UInt32 = 10, // Unsigned 32-bit integer
+ Int64 = 11, // Signed 64-bit integer
+ UInt64 = 12, // Unsigned 64-bit integer
+ Single = 13, // IEEE 32-bit float
+ Double = 14, // IEEE 64-bit double
+ Decimal = 15, // Decimal
+ DateTime = 16, // DateTime
+ String = 18, // Unicode character string
+ }
+#endif
+ static class ReflectionExtensions
+ {
+#if (!ES_BUILD_PCL && !ES_BUILD_PN)
+
+ //
+ // Type extension methods
+ //
+ public static bool IsEnum(this Type type) { return type.IsEnum; }
+ public static bool IsAbstract(this Type type) { return type.IsAbstract; }
+ public static bool IsSealed(this Type type) { return type.IsSealed; }
+ public static bool IsValueType(this Type type) { return type.IsValueType; }
+ public static bool IsGenericType(this Type type) { return type.IsGenericType; }
+ public static Type BaseType(this Type type) { return type.BaseType; }
+ public static Assembly Assembly(this Type type) { return type.Assembly; }
+ public static TypeCode GetTypeCode(this Type type) { return Type.GetTypeCode(type); }
+
+ public static bool ReflectionOnly(this Assembly assm) { return assm.ReflectionOnly; }
+
+#else // ES_BUILD_PCL
+
+ //
+ // Type extension methods
+ //
+ public static bool IsEnum(this Type type) { return type.GetTypeInfo().IsEnum; }
+ public static bool IsAbstract(this Type type) { return type.GetTypeInfo().IsAbstract; }
+ public static bool IsSealed(this Type type) { return type.GetTypeInfo().IsSealed; }
+ public static bool IsValueType(this Type type) { return type.GetTypeInfo().IsValueType; }
+ public static bool IsGenericType(this Type type) { return type.IsConstructedGenericType; }
+ public static Type BaseType(this Type type) { return type.GetTypeInfo().BaseType; }
+ public static Assembly Assembly(this Type type) { return type.GetTypeInfo().Assembly; }
+ public static IEnumerable<PropertyInfo> GetProperties(this Type type)
+ {
+#if ES_BUILD_PN
+ return type.GetProperties();
+#else
+ return type.GetRuntimeProperties();
+#endif
+ }
+ public static MethodInfo GetGetMethod(this PropertyInfo propInfo) { return propInfo.GetMethod; }
+ public static Type[] GetGenericArguments(this Type type) { return type.GenericTypeArguments; }
+
+ public static MethodInfo[] GetMethods(this Type type, BindingFlags flags)
+ {
+ // Minimal implementation to cover only the cases we need
+ System.Diagnostics.Debug.Assert((flags & BindingFlags.DeclaredOnly) != 0);
+ System.Diagnostics.Debug.Assert((flags & ~(BindingFlags.DeclaredOnly|BindingFlags.Instance|BindingFlags.Static|BindingFlags.Public|BindingFlags.NonPublic)) == 0);
+ Func<MethodInfo, bool> visFilter;
+ Func<MethodInfo, bool> instFilter;
+ switch (flags & (BindingFlags.Public | BindingFlags.NonPublic))
+ {
+ case 0: visFilter = mi => false; break;
+ case BindingFlags.Public: visFilter = mi => mi.IsPublic; break;
+ case BindingFlags.NonPublic: visFilter = mi => !mi.IsPublic; break;
+ default: visFilter = mi => true; break;
+ }
+ switch (flags & (BindingFlags.Instance | BindingFlags.Static))
+ {
+ case 0: instFilter = mi => false; break;
+ case BindingFlags.Instance: instFilter = mi => !mi.IsStatic; break;
+ case BindingFlags.Static: instFilter = mi => mi.IsStatic; break;
+ default: instFilter = mi => true; break;
+ }
+ List<MethodInfo> methodInfos = new List<MethodInfo>();
+ foreach (var declaredMethod in type.GetTypeInfo().DeclaredMethods)
+ {
+ if (visFilter(declaredMethod) && instFilter(declaredMethod))
+ methodInfos.Add(declaredMethod);
+ }
+ return methodInfos.ToArray();
+ }
+ public static FieldInfo[] GetFields(this Type type, BindingFlags flags)
+ {
+ // Minimal implementation to cover only the cases we need
+ System.Diagnostics.Debug.Assert((flags & BindingFlags.DeclaredOnly) != 0);
+ System.Diagnostics.Debug.Assert((flags & ~(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) == 0);
+ Func<FieldInfo, bool> visFilter;
+ Func<FieldInfo, bool> instFilter;
+ switch (flags & (BindingFlags.Public | BindingFlags.NonPublic))
+ {
+ case 0: visFilter = fi => false; break;
+ case BindingFlags.Public: visFilter = fi => fi.IsPublic; break;
+ case BindingFlags.NonPublic: visFilter = fi => !fi.IsPublic; break;
+ default: visFilter = fi => true; break;
+ }
+ switch (flags & (BindingFlags.Instance | BindingFlags.Static))
+ {
+ case 0: instFilter = fi => false; break;
+ case BindingFlags.Instance: instFilter = fi => !fi.IsStatic; break;
+ case BindingFlags.Static: instFilter = fi => fi.IsStatic; break;
+ default: instFilter = fi => true; break;
+ }
+ List<FieldInfo> fieldInfos = new List<FieldInfo>();
+ foreach (var declaredField in type.GetTypeInfo().DeclaredFields)
+ {
+ if (visFilter(declaredField) && instFilter(declaredField))
+ fieldInfos.Add(declaredField);
+ }
+ return fieldInfos.ToArray();
+ }
+ public static Type GetNestedType(this Type type, string nestedTypeName)
+ {
+ TypeInfo ti = null;
+ foreach(var nt in type.GetTypeInfo().DeclaredNestedTypes)
+ {
+ if (nt.Name == nestedTypeName)
+ {
+ ti = nt;
+ break;
+ }
+ }
+ return ti == null ? null : ti.AsType();
+ }
+ public static TypeCode GetTypeCode(this Type type)
+ {
+ if (type == typeof(bool)) return TypeCode.Boolean;
+ else if (type == typeof(byte)) return TypeCode.Byte;
+ else if (type == typeof(char)) return TypeCode.Char;
+ else if (type == typeof(ushort)) return TypeCode.UInt16;
+ else if (type == typeof(uint)) return TypeCode.UInt32;
+ else if (type == typeof(ulong)) return TypeCode.UInt64;
+ else if (type == typeof(sbyte)) return TypeCode.SByte;
+ else if (type == typeof(short)) return TypeCode.Int16;
+ else if (type == typeof(int)) return TypeCode.Int32;
+ else if (type == typeof(long)) return TypeCode.Int64;
+ else if (type == typeof(string)) return TypeCode.String;
+ else if (type == typeof(float)) return TypeCode.Single;
+ else if (type == typeof(double)) return TypeCode.Double;
+ else if (type == typeof(DateTime)) return TypeCode.DateTime;
+ else if (type == (typeof(Decimal))) return TypeCode.Decimal;
+ else return TypeCode.Object;
+ }
+
+ //
+ // FieldInfo extension methods
+ //
+ public static object GetRawConstantValue(this FieldInfo fi)
+ { return fi.GetValue(null); }
+
+ //
+ // Assembly extension methods
+ //
+ public static bool ReflectionOnly(this Assembly assm)
+ {
+ // In PCL we can't load in reflection-only context
+ return false;
+ }
+
+#endif
+ }
+}
+
+// Defining some no-ops in PCL builds
+#if ES_BUILD_PCL
+namespace System.Security
+{
+ class SuppressUnmanagedCodeSecurityAttribute : Attribute { }
+
+ enum SecurityAction { Demand }
+}
+
+namespace System.Security.Permissions
+{
+ class HostProtectionAttribute : Attribute { public bool MayLeakOnAbort { get; set; } }
+ class PermissionSetAttribute : Attribute
+ {
+ public PermissionSetAttribute(System.Security.SecurityAction action) { }
+ public bool Unrestricted { get; set; }
+ }
+}
+#endif
+
+#if ES_BUILD_PN
+namespace System
+{
+ internal static class AppDomain
+ {
+ public static int GetCurrentThreadId()
+ {
+ return Internal.Runtime.Augments.RuntimeThread.CurrentThread.ManagedThreadId;
+ }
+ }
+}
+#endif
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/ArrayTypeInfo.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/ArrayTypeInfo.cs
index 5771354f67..5771354f67 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/ArrayTypeInfo.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/ArrayTypeInfo.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/ConcurrentSet.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/ConcurrentSet.cs
index 76c01c6c06..76c01c6c06 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/ConcurrentSet.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/ConcurrentSet.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/ConcurrentSetItem.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/ConcurrentSetItem.cs
index 558dbf670b..558dbf670b 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/ConcurrentSetItem.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/ConcurrentSetItem.cs
diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs
new file mode 100644
index 0000000000..27aae820e9
--- /dev/null
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/DataCollector.cs
@@ -0,0 +1,318 @@
+// 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.InteropServices;
+using System.Security;
+
+#if ES_BUILD_STANDALONE
+using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment;
+namespace Microsoft.Diagnostics.Tracing
+#else
+namespace System.Diagnostics.Tracing
+#endif
+{
+ /// <summary>
+ /// TraceLogging: This is the implementation of the DataCollector
+ /// functionality. To enable safe access to the DataCollector from
+ /// untrusted code, there is one thread-local instance of this structure
+ /// per thread. The instance must be Enabled before any data is written to
+ /// it. The instance must be Finished before the data is passed to
+ /// EventWrite. The instance must be Disabled before the arrays referenced
+ /// by the pointers are freed or unpinned.
+ /// </summary>
+ internal unsafe struct DataCollector
+ {
+ [ThreadStatic]
+ internal static DataCollector ThreadInstance;
+
+ private byte* scratchEnd;
+ private EventSource.EventData* datasEnd;
+ private GCHandle* pinsEnd;
+ private EventSource.EventData* datasStart;
+ private byte* scratch;
+ private EventSource.EventData* datas;
+ private GCHandle* pins;
+ private byte[] buffer;
+ private int bufferPos;
+ private int bufferNesting; // We may merge many fields int a single blob. If we are doing this we increment this.
+ private bool writingScalars;
+
+ internal void Enable(
+ byte* scratch,
+ int scratchSize,
+ EventSource.EventData* datas,
+ int dataCount,
+ GCHandle* pins,
+ int pinCount)
+ {
+ this.datasStart = datas;
+ this.scratchEnd = scratch + scratchSize;
+ this.datasEnd = datas + dataCount;
+ this.pinsEnd = pins + pinCount;
+ this.scratch = scratch;
+ this.datas = datas;
+ this.pins = pins;
+ this.writingScalars = false;
+ }
+
+ internal void Disable()
+ {
+ this = new DataCollector();
+ }
+
+ /// <summary>
+ /// Completes the list of scalars. Finish must be called before the data
+ /// descriptor array is passed to EventWrite.
+ /// </summary>
+ /// <returns>
+ /// A pointer to the next unused data descriptor, or datasEnd if they were
+ /// all used. (Descriptors may be unused if a string or array was null.)
+ /// </returns>
+ internal EventSource.EventData* Finish()
+ {
+ this.ScalarsEnd();
+ return this.datas;
+ }
+
+ internal void AddScalar(void* value, int size)
+ {
+ var pb = (byte*)value;
+ if (this.bufferNesting == 0)
+ {
+ var scratchOld = this.scratch;
+ var scratchNew = scratchOld + size;
+ if (this.scratchEnd < scratchNew)
+ {
+ throw new IndexOutOfRangeException(Resources.GetResourceString("EventSource_AddScalarOutOfRange"));
+ }
+
+ this.ScalarsBegin();
+ this.scratch = scratchNew;
+
+ for (int i = 0; i != size; i++)
+ {
+ scratchOld[i] = pb[i];
+ }
+ }
+ else
+ {
+ var oldPos = this.bufferPos;
+ this.bufferPos = checked(this.bufferPos + size);
+ this.EnsureBuffer();
+ for (int i = 0; i != size; i++, oldPos++)
+ {
+ this.buffer[oldPos] = pb[i];
+ }
+ }
+ }
+
+ internal void AddBinary(string value, int size)
+ {
+ if (size > ushort.MaxValue)
+ {
+ size = ushort.MaxValue - 1;
+ }
+
+ if (this.bufferNesting != 0)
+ {
+ this.EnsureBuffer(size + 2);
+ }
+
+ this.AddScalar(&size, 2);
+
+ if (size != 0)
+ {
+ if (this.bufferNesting == 0)
+ {
+ this.ScalarsEnd();
+ this.PinArray(value, size);
+ }
+ else
+ {
+ var oldPos = this.bufferPos;
+ this.bufferPos = checked(this.bufferPos + size);
+ this.EnsureBuffer();
+ fixed (void* p = value)
+ {
+ Marshal.Copy((IntPtr)p, buffer, oldPos, size);
+ }
+ }
+ }
+ }
+
+ internal void AddBinary(Array value, int size)
+ {
+ this.AddArray(value, size, 1);
+ }
+
+ internal void AddArray(Array value, int length, int itemSize)
+ {
+ if (length > ushort.MaxValue)
+ {
+ length = ushort.MaxValue;
+ }
+
+ var size = length * itemSize;
+ if (this.bufferNesting != 0)
+ {
+ this.EnsureBuffer(size + 2);
+ }
+
+ this.AddScalar(&length, 2);
+
+ if (length != 0)
+ {
+ if (this.bufferNesting == 0)
+ {
+ this.ScalarsEnd();
+ this.PinArray(value, size);
+ }
+ else
+ {
+ var oldPos = this.bufferPos;
+ this.bufferPos = checked(this.bufferPos + size);
+ this.EnsureBuffer();
+ Buffer.BlockCopy(value, 0, this.buffer, oldPos, size);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Marks the start of a non-blittable array or enumerable.
+ /// </summary>
+ /// <returns>Bookmark to be passed to EndBufferedArray.</returns>
+ internal int BeginBufferedArray()
+ {
+ this.BeginBuffered();
+ this.bufferPos += 2; // Reserve space for the array length (filled in by EndEnumerable)
+ return this.bufferPos;
+ }
+
+ /// <summary>
+ /// Marks the end of a non-blittable array or enumerable.
+ /// </summary>
+ /// <param name="bookmark">The value returned by BeginBufferedArray.</param>
+ /// <param name="count">The number of items in the array.</param>
+ internal void EndBufferedArray(int bookmark, int count)
+ {
+ this.EnsureBuffer();
+ this.buffer[bookmark - 2] = unchecked((byte)count);
+ this.buffer[bookmark - 1] = unchecked((byte)(count >> 8));
+ this.EndBuffered();
+ }
+
+ /// <summary>
+ /// Marks the start of dynamically-buffered data.
+ /// </summary>
+ internal void BeginBuffered()
+ {
+ this.ScalarsEnd();
+ this.bufferNesting += 1;
+ }
+
+ /// <summary>
+ /// Marks the end of dynamically-buffered data.
+ /// </summary>
+ internal void EndBuffered()
+ {
+ this.bufferNesting -= 1;
+
+ if (this.bufferNesting == 0)
+ {
+ /*
+ TODO (perf): consider coalescing adjacent buffered regions into a
+ single buffer, similar to what we're already doing for adjacent
+ scalars. In addition, if a type contains a buffered region adjacent
+ to a blittable array, and the blittable array is small, it would be
+ more efficient to buffer the array instead of pinning it.
+ */
+
+ this.EnsureBuffer();
+ this.PinArray(this.buffer, this.bufferPos);
+ this.buffer = null;
+ this.bufferPos = 0;
+ }
+ }
+
+ private void EnsureBuffer()
+ {
+ var required = this.bufferPos;
+ if (this.buffer == null || this.buffer.Length < required)
+ {
+ this.GrowBuffer(required);
+ }
+ }
+
+ private void EnsureBuffer(int additionalSize)
+ {
+ var required = this.bufferPos + additionalSize;
+ if (this.buffer == null || this.buffer.Length < required)
+ {
+ this.GrowBuffer(required);
+ }
+ }
+
+ private void GrowBuffer(int required)
+ {
+ var newSize = this.buffer == null ? 64 : this.buffer.Length;
+
+ do
+ {
+ newSize *= 2;
+ }
+ while (newSize < required);
+
+ Array.Resize(ref this.buffer, newSize);
+ }
+
+ private void PinArray(object value, int size)
+ {
+ var pinsTemp = this.pins;
+ if (this.pinsEnd <= pinsTemp)
+ {
+ throw new IndexOutOfRangeException(Resources.GetResourceString("EventSource_PinArrayOutOfRange"));
+ }
+
+ var datasTemp = this.datas;
+ if (this.datasEnd <= datasTemp)
+ {
+ throw new IndexOutOfRangeException(Resources.GetResourceString("EventSource_DataDescriptorsOutOfRange"));
+ }
+
+ this.pins = pinsTemp + 1;
+ this.datas = datasTemp + 1;
+
+ *pinsTemp = GCHandle.Alloc(value, GCHandleType.Pinned);
+ datasTemp->m_Ptr = (long)(ulong)(UIntPtr)(void*)pinsTemp->AddrOfPinnedObject();
+ datasTemp->m_Size = size;
+ }
+
+ private void ScalarsBegin()
+ {
+ if (!this.writingScalars)
+ {
+ var datasTemp = this.datas;
+ if (this.datasEnd <= datasTemp)
+ {
+ throw new IndexOutOfRangeException(Resources.GetResourceString("EventSource_DataDescriptorsOutOfRange"));
+ }
+
+ datasTemp->m_Ptr = (long)(ulong)(UIntPtr)this.scratch;
+ this.writingScalars = true;
+ }
+ }
+
+ private void ScalarsEnd()
+ {
+ if (this.writingScalars)
+ {
+ var datasTemp = this.datas;
+ datasTemp->m_Size = checked((int)(this.scratch - (byte*)datasTemp->m_Ptr));
+ this.datas = datasTemp + 1;
+ this.writingScalars = false;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EmptyStruct.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EmptyStruct.cs
index bc7fb8c346..bc7fb8c346 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EmptyStruct.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EmptyStruct.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumHelper.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EnumHelper.cs
index 7a23378bb1..7a23378bb1 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumHelper.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EnumHelper.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumerableTypeInfo.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EnumerableTypeInfo.cs
index 74a3fa27b2..74a3fa27b2 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EnumerableTypeInfo.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EnumerableTypeInfo.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventDataAttribute.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventDataAttribute.cs
index cdedf13c64..cdedf13c64 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventDataAttribute.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventDataAttribute.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventFieldAttribute.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventFieldAttribute.cs
index 1a298c2851..1a298c2851 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventFieldAttribute.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventFieldAttribute.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventFieldFormat.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventFieldFormat.cs
index fd77b07965..fd77b07965 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventFieldFormat.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventFieldFormat.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventIgnoreAttribute.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventIgnoreAttribute.cs
index 769345f78e..769345f78e 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventIgnoreAttribute.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventIgnoreAttribute.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventPayload.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs
index 5967ad6ab5..5967ad6ab5 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventPayload.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceActivity.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceActivity.cs
index 38c1767462..38c1767462 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceActivity.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceActivity.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceOptions.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceOptions.cs
index 26305a5708..26305a5708 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/EventSourceOptions.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/EventSourceOptions.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/FieldMetadata.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/FieldMetadata.cs
index 309226b84d..309226b84d 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/FieldMetadata.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/FieldMetadata.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/InvokeTypeInfo.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/InvokeTypeInfo.cs
index 3e5997bc9b..3e5997bc9b 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/InvokeTypeInfo.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/InvokeTypeInfo.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/NameInfo.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs
index 668043ae68..668043ae68 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/NameInfo.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/NameInfo.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyAnalysis.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyAnalysis.cs
index 1f07539b52..1f07539b52 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyAnalysis.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyAnalysis.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs
index 3ea781252f..3ea781252f 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/PropertyValue.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleEventTypes.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleEventTypes.cs
index cdced968f0..cdced968f0 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleEventTypes.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleEventTypes.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleTypeInfos.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs
index 901a0ed1a2..901a0ed1a2 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/SimpleTypeInfos.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/SimpleTypeInfos.cs
diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/Statics.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/Statics.cs
new file mode 100644
index 0000000000..9fa776753d
--- /dev/null
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/Statics.cs
@@ -0,0 +1,727 @@
+// 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.Collections.Generic;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using Encoding = System.Text.Encoding;
+
+using Microsoft.Reflection;
+
+#if ES_BUILD_STANDALONE
+using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment;
+namespace Microsoft.Diagnostics.Tracing
+#else
+namespace System.Diagnostics.Tracing
+#endif
+{
+ /// <summary>
+ /// TraceLogging: Constants and utility functions.
+ /// </summary>
+ internal static class Statics
+ {
+ #region Constants
+
+ public const byte DefaultLevel = 5;
+ public const byte TraceLoggingChannel = 0xb;
+ public const byte InTypeMask = 31;
+ public const byte InTypeFixedCountFlag = 32;
+ public const byte InTypeVariableCountFlag = 64;
+ public const byte InTypeCustomCountFlag = 96;
+ public const byte InTypeCountMask = 96;
+ public const byte InTypeChainFlag = 128;
+ public const byte OutTypeMask = 127;
+ public const byte OutTypeChainFlag = 128;
+ public const EventTags EventTagsMask = (EventTags)0xfffffff;
+
+ public static readonly TraceLoggingDataType IntPtrType = IntPtr.Size == 8
+ ? TraceLoggingDataType.Int64
+ : TraceLoggingDataType.Int32;
+ public static readonly TraceLoggingDataType UIntPtrType = IntPtr.Size == 8
+ ? TraceLoggingDataType.UInt64
+ : TraceLoggingDataType.UInt32;
+ public static readonly TraceLoggingDataType HexIntPtrType = IntPtr.Size == 8
+ ? TraceLoggingDataType.HexInt64
+ : TraceLoggingDataType.HexInt32;
+
+ #endregion
+
+ #region Metadata helpers
+
+ /// <summary>
+ /// A complete metadata chunk can be expressed as:
+ /// length16 + prefix + null-terminated-utf8-name + suffix + additionalData.
+ /// We assume that excludedData will be provided by some other means,
+ /// but that its size is known. This function returns a blob containing
+ /// length16 + prefix + name + suffix, with prefix and suffix initialized
+ /// to 0's. The length16 value is initialized to the length of the returned
+ /// blob plus additionalSize, so that the concatenation of the returned blob
+ /// plus a blob of size additionalSize constitutes a valid metadata blob.
+ /// </summary>
+ /// <param name="name">
+ /// The name to include in the blob.
+ /// </param>
+ /// <param name="prefixSize">
+ /// Amount of space to reserve before name. For provider or field blobs, this
+ /// should be 0. For event blobs, this is used for the tags field and will vary
+ /// from 1 to 4, depending on how large the tags field needs to be.
+ /// </param>
+ /// <param name="suffixSize">
+ /// Amount of space to reserve after name. For example, a provider blob with no
+ /// traits would reserve 0 extra bytes, but a provider blob with a single GroupId
+ /// field would reserve 19 extra bytes.
+ /// </param>
+ /// <param name="additionalSize">
+ /// Amount of additional data in another blob. This value will be counted in the
+ /// blob's length field, but will not be included in the returned byte[] object.
+ /// The complete blob would then be the concatenation of the returned byte[] object
+ /// with another byte[] object of length additionalSize.
+ /// </param>
+ /// <returns>
+ /// A byte[] object with the length and name fields set, with room reserved for
+ /// prefix and suffix. If additionalSize was 0, the byte[] object is a complete
+ /// blob. Otherwise, another byte[] of size additionalSize must be concatenated
+ /// with this one to form a complete blob.
+ /// </returns>
+ public static byte[] MetadataForString(
+ string name,
+ int prefixSize,
+ int suffixSize,
+ int additionalSize)
+ {
+ Statics.CheckName(name);
+ int metadataSize = Encoding.UTF8.GetByteCount(name) + 3 + prefixSize + suffixSize;
+ var metadata = new byte[metadataSize];
+ ushort totalSize = checked((ushort)(metadataSize + additionalSize));
+ metadata[0] = unchecked((byte)totalSize);
+ metadata[1] = unchecked((byte)(totalSize >> 8));
+ Encoding.UTF8.GetBytes(name, 0, name.Length, metadata, 2 + prefixSize);
+ return metadata;
+ }
+
+ /// <summary>
+ /// Serialize the low 28 bits of the tags value into the metadata stream,
+ /// starting at the index given by pos. Updates pos. Writes 1 to 4 bytes,
+ /// depending on the value of the tags variable. Usable for event tags and
+ /// field tags.
+ ///
+ /// Note that 'metadata' can be null, in which case it only updates 'pos'.
+ /// This is useful for a two pass approach where you figure out how big to
+ /// make the array, and then you fill it in.
+ /// </summary>
+ public static void EncodeTags(int tags, ref int pos, byte[] metadata)
+ {
+ // We transmit the low 28 bits of tags, high bits first, 7 bits at a time.
+ var tagsLeft = tags & 0xfffffff;
+ bool more;
+ do
+ {
+ byte current = (byte)((tagsLeft >> 21) & 0x7f);
+ more = (tagsLeft & 0x1fffff) != 0;
+ current |= (byte)(more ? 0x80 : 0x00);
+ tagsLeft = tagsLeft << 7;
+
+ if (metadata != null)
+ {
+ metadata[pos] = current;
+ }
+ pos += 1;
+ }
+ while (more);
+ }
+
+ public static byte Combine(
+ int settingValue,
+ byte defaultValue)
+ {
+ unchecked
+ {
+ return (byte)settingValue == settingValue
+ ? (byte)settingValue
+ : defaultValue;
+ }
+ }
+
+ public static byte Combine(
+ int settingValue1,
+ int settingValue2,
+ byte defaultValue)
+ {
+ unchecked
+ {
+ return (byte)settingValue1 == settingValue1
+ ? (byte)settingValue1
+ : (byte)settingValue2 == settingValue2
+ ? (byte)settingValue2
+ : defaultValue;
+ }
+ }
+
+ public static int Combine(
+ int settingValue1,
+ int settingValue2)
+ {
+ unchecked
+ {
+ return (byte)settingValue1 == settingValue1
+ ? settingValue1
+ : settingValue2;
+ }
+ }
+
+ public static void CheckName(string name)
+ {
+ if (name != null && 0 <= name.IndexOf('\0'))
+ {
+ throw new ArgumentOutOfRangeException(nameof(name));
+ }
+ }
+
+ public static bool ShouldOverrideFieldName(string fieldName)
+ {
+ return (fieldName.Length <= 2 && fieldName[0] == '_');
+ }
+
+ public static TraceLoggingDataType MakeDataType(
+ TraceLoggingDataType baseType,
+ EventFieldFormat format)
+ {
+ return (TraceLoggingDataType)(((int)baseType & 0x1f) | ((int)format << 8));
+ }
+
+ /// <summary>
+ /// Adjusts the native type based on format.
+ /// - If format is default, return native.
+ /// - If format is recognized, return the canonical type for that format.
+ /// - Otherwise remove existing format from native and apply the requested format.
+ /// </summary>
+ public static TraceLoggingDataType Format8(
+ EventFieldFormat format,
+ TraceLoggingDataType native)
+ {
+ switch (format)
+ {
+ case EventFieldFormat.Default:
+ return native;
+ case EventFieldFormat.String:
+ return TraceLoggingDataType.Char8;
+ case EventFieldFormat.Boolean:
+ return TraceLoggingDataType.Boolean8;
+ case EventFieldFormat.Hexadecimal:
+ return TraceLoggingDataType.HexInt8;
+#if false
+ case EventSourceFieldFormat.Signed:
+ return TraceLoggingDataType.Int8;
+ case EventSourceFieldFormat.Unsigned:
+ return TraceLoggingDataType.UInt8;
+#endif
+ default:
+ return MakeDataType(native, format);
+ }
+ }
+
+ /// <summary>
+ /// Adjusts the native type based on format.
+ /// - If format is default, return native.
+ /// - If format is recognized, return the canonical type for that format.
+ /// - Otherwise remove existing format from native and apply the requested format.
+ /// </summary>
+ public static TraceLoggingDataType Format16(
+ EventFieldFormat format,
+ TraceLoggingDataType native)
+ {
+ switch (format)
+ {
+ case EventFieldFormat.Default:
+ return native;
+ case EventFieldFormat.String:
+ return TraceLoggingDataType.Char16;
+ case EventFieldFormat.Hexadecimal:
+ return TraceLoggingDataType.HexInt16;
+#if false
+ case EventSourceFieldFormat.Port:
+ return TraceLoggingDataType.Port;
+ case EventSourceFieldFormat.Signed:
+ return TraceLoggingDataType.Int16;
+ case EventSourceFieldFormat.Unsigned:
+ return TraceLoggingDataType.UInt16;
+#endif
+ default:
+ return MakeDataType(native, format);
+ }
+ }
+
+ /// <summary>
+ /// Adjusts the native type based on format.
+ /// - If format is default, return native.
+ /// - If format is recognized, return the canonical type for that format.
+ /// - Otherwise remove existing format from native and apply the requested format.
+ /// </summary>
+ public static TraceLoggingDataType Format32(
+ EventFieldFormat format,
+ TraceLoggingDataType native)
+ {
+ switch (format)
+ {
+ case EventFieldFormat.Default:
+ return native;
+ case EventFieldFormat.Boolean:
+ return TraceLoggingDataType.Boolean32;
+ case EventFieldFormat.Hexadecimal:
+ return TraceLoggingDataType.HexInt32;
+#if false
+ case EventSourceFieldFormat.Ipv4Address:
+ return TraceLoggingDataType.Ipv4Address;
+ case EventSourceFieldFormat.ProcessId:
+ return TraceLoggingDataType.ProcessId;
+ case EventSourceFieldFormat.ThreadId:
+ return TraceLoggingDataType.ThreadId;
+ case EventSourceFieldFormat.Win32Error:
+ return TraceLoggingDataType.Win32Error;
+ case EventSourceFieldFormat.NTStatus:
+ return TraceLoggingDataType.NTStatus;
+#endif
+ case EventFieldFormat.HResult:
+ return TraceLoggingDataType.HResult;
+#if false
+ case EventSourceFieldFormat.Signed:
+ return TraceLoggingDataType.Int32;
+ case EventSourceFieldFormat.Unsigned:
+ return TraceLoggingDataType.UInt32;
+#endif
+ default:
+ return MakeDataType(native, format);
+ }
+ }
+
+ /// <summary>
+ /// Adjusts the native type based on format.
+ /// - If format is default, return native.
+ /// - If format is recognized, return the canonical type for that format.
+ /// - Otherwise remove existing format from native and apply the requested format.
+ /// </summary>
+ public static TraceLoggingDataType Format64(
+ EventFieldFormat format,
+ TraceLoggingDataType native)
+ {
+ switch (format)
+ {
+ case EventFieldFormat.Default:
+ return native;
+ case EventFieldFormat.Hexadecimal:
+ return TraceLoggingDataType.HexInt64;
+#if false
+ case EventSourceFieldFormat.FileTime:
+ return TraceLoggingDataType.FileTime;
+ case EventSourceFieldFormat.Signed:
+ return TraceLoggingDataType.Int64;
+ case EventSourceFieldFormat.Unsigned:
+ return TraceLoggingDataType.UInt64;
+#endif
+ default:
+ return MakeDataType(native, format);
+ }
+ }
+
+ /// <summary>
+ /// Adjusts the native type based on format.
+ /// - If format is default, return native.
+ /// - If format is recognized, return the canonical type for that format.
+ /// - Otherwise remove existing format from native and apply the requested format.
+ /// </summary>
+ public static TraceLoggingDataType FormatPtr(
+ EventFieldFormat format,
+ TraceLoggingDataType native)
+ {
+ switch (format)
+ {
+ case EventFieldFormat.Default:
+ return native;
+ case EventFieldFormat.Hexadecimal:
+ return HexIntPtrType;
+#if false
+ case EventSourceFieldFormat.Signed:
+ return IntPtrType;
+ case EventSourceFieldFormat.Unsigned:
+ return UIntPtrType;
+#endif
+ default:
+ return MakeDataType(native, format);
+ }
+ }
+
+ #endregion
+
+ #region Reflection helpers
+
+ /*
+ All TraceLogging use of reflection APIs should go through wrappers here.
+ This helps with portability, and it also makes it easier to audit what
+ kinds of reflection operations are being done.
+ */
+
+ public static object CreateInstance(Type type, params object[] parameters)
+ {
+ return Activator.CreateInstance(type, parameters);
+ }
+
+ public static bool IsValueType(Type type)
+ {
+ bool result = type.IsValueType();
+ return result;
+ }
+
+ public static bool IsEnum(Type type)
+ {
+ bool result = type.IsEnum();
+ return result;
+ }
+
+ public static IEnumerable<PropertyInfo> GetProperties(Type type)
+ {
+ IEnumerable<PropertyInfo> result = type.GetProperties();
+ return result;
+ }
+
+ public static MethodInfo GetGetMethod(PropertyInfo propInfo)
+ {
+ MethodInfo result = propInfo.GetGetMethod();
+ return result;
+ }
+
+ public static MethodInfo GetDeclaredStaticMethod(Type declaringType, string name)
+ {
+ MethodInfo result;
+#if (ES_BUILD_PCL || ES_BUILD_PN)
+ result = declaringType.GetTypeInfo().GetDeclaredMethod(name);
+#else
+ result = declaringType.GetMethod(
+ name,
+ BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.NonPublic);
+#endif
+ return result;
+ }
+
+ public static bool HasCustomAttribute(
+ PropertyInfo propInfo,
+ Type attributeType)
+ {
+ bool result;
+#if (ES_BUILD_PCL || ES_BUILD_PN)
+ result = propInfo.IsDefined(attributeType);
+#else
+ var attributes = propInfo.GetCustomAttributes(
+ attributeType,
+ false);
+ result = attributes.Length != 0;
+#endif
+ return result;
+ }
+
+ public static AttributeType GetCustomAttribute<AttributeType>(PropertyInfo propInfo)
+ where AttributeType : Attribute
+ {
+ AttributeType result = null;
+#if (ES_BUILD_PCL || ES_BUILD_PN)
+ foreach (var attrib in propInfo.GetCustomAttributes<AttributeType>(false))
+ {
+ result = attrib;
+ break;
+ }
+#else
+ var attributes = propInfo.GetCustomAttributes(typeof(AttributeType), false);
+ if (attributes.Length != 0)
+ {
+ result = (AttributeType)attributes[0];
+ }
+#endif
+ return result;
+ }
+
+ public static AttributeType GetCustomAttribute<AttributeType>(Type type)
+ where AttributeType : Attribute
+ {
+ AttributeType result = null;
+#if (ES_BUILD_PCL || ES_BUILD_PN)
+ foreach (var attrib in type.GetTypeInfo().GetCustomAttributes<AttributeType>(false))
+ {
+ result = attrib;
+ break;
+ }
+#else
+ var attributes = type.GetCustomAttributes(typeof(AttributeType), false);
+ if (attributes.Length != 0)
+ {
+ result = (AttributeType)attributes[0];
+ }
+#endif
+ return result;
+ }
+
+ public static Type[] GetGenericArguments(Type type)
+ {
+ return type.GetGenericArguments();
+ }
+
+ public static Type FindEnumerableElementType(Type type)
+ {
+ Type elementType = null;
+
+ if (IsGenericMatch(type, typeof(IEnumerable<>)))
+ {
+ elementType = GetGenericArguments(type)[0];
+ }
+ else
+ {
+#if (ES_BUILD_PCL || ES_BUILD_PN)
+ var ifaceTypes = type.GetTypeInfo().ImplementedInterfaces;
+#else
+ var ifaceTypes = type.FindInterfaces(IsGenericMatch, typeof(IEnumerable<>));
+#endif
+
+ foreach (var ifaceType in ifaceTypes)
+ {
+#if (ES_BUILD_PCL || ES_BUILD_PN)
+ if (!IsGenericMatch(ifaceType, typeof(IEnumerable<>)))
+ {
+ continue;
+ }
+#endif
+
+ if (elementType != null)
+ {
+ // ambiguous match. report no match at all.
+ elementType = null;
+ break;
+ }
+
+ elementType = GetGenericArguments(ifaceType)[0];
+ }
+ }
+
+ return elementType;
+ }
+
+ public static bool IsGenericMatch(Type type, object openType)
+ {
+ return type.IsGenericType() && type.GetGenericTypeDefinition() == (Type)openType;
+ }
+
+ public static Delegate CreateDelegate(Type delegateType, MethodInfo methodInfo)
+ {
+ Delegate result;
+#if (ES_BUILD_PCL || ES_BUILD_PN)
+ result = methodInfo.CreateDelegate(
+ delegateType);
+#else
+ result = Delegate.CreateDelegate(
+ delegateType,
+ methodInfo);
+#endif
+ return result;
+ }
+
+ public static TraceLoggingTypeInfo CreateDefaultTypeInfo(
+ Type dataType,
+ List<Type> recursionCheck)
+ {
+ TraceLoggingTypeInfo result;
+
+ if (recursionCheck.Contains(dataType))
+ {
+ throw new NotSupportedException(Resources.GetResourceString("EventSource_RecursiveTypeDefinition"));
+ }
+
+ recursionCheck.Add(dataType);
+
+ var eventAttrib = Statics.GetCustomAttribute<EventDataAttribute>(dataType);
+ if (eventAttrib != null ||
+ Statics.GetCustomAttribute<CompilerGeneratedAttribute>(dataType) != null ||
+ IsGenericMatch(dataType, typeof(KeyValuePair<,>)))
+ {
+ var analysis = new TypeAnalysis(dataType, eventAttrib, recursionCheck);
+ result = new InvokeTypeInfo(dataType, analysis);
+ }
+ else if (dataType.IsArray)
+ {
+ var elementType = dataType.GetElementType();
+ if (elementType == typeof(Boolean))
+ {
+ result = ScalarArrayTypeInfo.Boolean();
+ }
+ else if (elementType == typeof(Byte))
+ {
+ result = ScalarArrayTypeInfo.Byte();
+ }
+ else if (elementType == typeof(SByte))
+ {
+ result = ScalarArrayTypeInfo.SByte();
+ }
+ else if (elementType == typeof(Int16))
+ {
+ result = ScalarArrayTypeInfo.Int16();
+ }
+ else if (elementType == typeof(UInt16))
+ {
+ result = ScalarArrayTypeInfo.UInt16();
+ }
+ else if (elementType == typeof(Int32))
+ {
+ result = ScalarArrayTypeInfo.Int32();
+ }
+ else if (elementType == typeof(UInt32))
+ {
+ result = ScalarArrayTypeInfo.UInt32();
+ }
+ else if (elementType == typeof(Int64))
+ {
+ result = ScalarArrayTypeInfo.Int64();
+ }
+ else if (elementType == typeof(UInt64))
+ {
+ result = ScalarArrayTypeInfo.UInt64();
+ }
+ else if (elementType == typeof(Char))
+ {
+ result = ScalarArrayTypeInfo.Char();
+ }
+ else if (elementType == typeof(Double))
+ {
+ result = ScalarArrayTypeInfo.Double();
+ }
+ else if (elementType == typeof(Single))
+ {
+ result = ScalarArrayTypeInfo.Single();
+ }
+ else if (elementType == typeof(IntPtr))
+ {
+ result = ScalarArrayTypeInfo.IntPtr();
+ }
+ else if (elementType == typeof(UIntPtr))
+ {
+ result = ScalarArrayTypeInfo.UIntPtr();
+ }
+ else if (elementType == typeof(Guid))
+ {
+ result = ScalarArrayTypeInfo.Guid();
+ }
+ else
+ {
+ result = new ArrayTypeInfo(dataType, TraceLoggingTypeInfo.GetInstance(elementType, recursionCheck));
+ }
+ }
+ else
+ {
+ if (Statics.IsEnum(dataType))
+ dataType = Enum.GetUnderlyingType(dataType);
+
+ if (dataType == typeof(String))
+ {
+ result = new StringTypeInfo();
+ }
+ else if (dataType == typeof(Boolean))
+ {
+ result = ScalarTypeInfo.Boolean();
+ }
+ else if (dataType == typeof(Byte))
+ {
+ result = ScalarTypeInfo.Byte();
+ }
+ else if (dataType == typeof(SByte))
+ {
+ result = ScalarTypeInfo.SByte();
+ }
+ else if (dataType == typeof(Int16))
+ {
+ result = ScalarTypeInfo.Int16();
+ }
+ else if (dataType == typeof(UInt16))
+ {
+ result = ScalarTypeInfo.UInt16();
+ }
+ else if (dataType == typeof(Int32))
+ {
+ result = ScalarTypeInfo.Int32();
+ }
+ else if (dataType == typeof(UInt32))
+ {
+ result = ScalarTypeInfo.UInt32();
+ }
+ else if (dataType == typeof(Int64))
+ {
+ result = ScalarTypeInfo.Int64();
+ }
+ else if (dataType == typeof(UInt64))
+ {
+ result = ScalarTypeInfo.UInt64();
+ }
+ else if (dataType == typeof(Char))
+ {
+ result = ScalarTypeInfo.Char();
+ }
+ else if (dataType == typeof(Double))
+ {
+ result = ScalarTypeInfo.Double();
+ }
+ else if (dataType == typeof(Single))
+ {
+ result = ScalarTypeInfo.Single();
+ }
+ else if (dataType == typeof(DateTime))
+ {
+ result = new DateTimeTypeInfo();
+ }
+ else if (dataType == typeof(Decimal))
+ {
+ result = new DecimalTypeInfo();
+ }
+ else if (dataType == typeof(IntPtr))
+ {
+ result = ScalarTypeInfo.IntPtr();
+ }
+ else if (dataType == typeof(UIntPtr))
+ {
+ result = ScalarTypeInfo.UIntPtr();
+ }
+ else if (dataType == typeof(Guid))
+ {
+ result = ScalarTypeInfo.Guid();
+ }
+ else if (dataType == typeof(TimeSpan))
+ {
+ result = new TimeSpanTypeInfo();
+ }
+ else if (dataType == typeof(DateTimeOffset))
+ {
+ result = new DateTimeOffsetTypeInfo();
+ }
+ else if (dataType == typeof(EmptyStruct))
+ {
+ result = new NullTypeInfo();
+ }
+ else if (IsGenericMatch(dataType, typeof(Nullable<>)))
+ {
+ result = new NullableTypeInfo(dataType, recursionCheck);
+ }
+ else
+ {
+ var elementType = FindEnumerableElementType(dataType);
+ if (elementType != null)
+ {
+ result = new EnumerableTypeInfo(dataType, TraceLoggingTypeInfo.GetInstance(elementType, recursionCheck));
+ }
+ else
+ {
+ throw new ArgumentException(Resources.GetResourceString("EventSource_NonCompliantTypeError", dataType.Name));
+ }
+ }
+ }
+
+ return result;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataCollector.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataCollector.cs
index 04a047fb35..04a047fb35 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataCollector.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataCollector.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataType.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataType.cs
index 529948daf8..529948daf8 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingDataType.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingDataType.cs
diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs
new file mode 100644
index 0000000000..e73339949a
--- /dev/null
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs
@@ -0,0 +1,890 @@
+// 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.
+
+// This program uses code hyperlinks available as part of the HyperAddin Visual Studio plug-in.
+// It is available from http://www.codeplex.com/hyperAddin
+
+#if PLATFORM_WINDOWS
+#define FEATURE_MANAGED_ETW
+
+#if !ES_BUILD_STANDALONE
+#define FEATURE_ACTIVITYSAMPLING
+#endif
+#endif // PLATFORM_WINDOWS
+
+#if ES_BUILD_STANDALONE
+#define FEATURE_MANAGED_ETW_CHANNELS
+// #define FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
+#endif
+
+#if ES_BUILD_STANDALONE
+using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment;
+using EventDescriptor = Microsoft.Diagnostics.Tracing.EventDescriptor;
+#endif
+
+using System;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Collections.ObjectModel;
+
+#if !ES_BUILD_AGAINST_DOTNET_V35
+using Contract = System.Diagnostics.Contracts.Contract;
+using System.Collections.Generic;
+using System.Text;
+#else
+using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract;
+using System.Collections.Generic;
+using System.Text;
+#endif
+
+#if ES_BUILD_STANDALONE
+namespace Microsoft.Diagnostics.Tracing
+#else
+namespace System.Diagnostics.Tracing
+#endif
+{
+ public partial class EventSource
+ {
+#if FEATURE_MANAGED_ETW
+ private byte[] providerMetadata;
+#endif
+
+ /// <summary>
+ /// Construct an EventSource with a given name for non-contract based events (e.g. those using the Write() API).
+ /// </summary>
+ /// <param name="eventSourceName">
+ /// The name of the event source. Must not be null.
+ /// </param>
+ public EventSource(
+ string eventSourceName)
+ : this(eventSourceName, EventSourceSettings.EtwSelfDescribingEventFormat)
+ { }
+
+ /// <summary>
+ /// Construct an EventSource with a given name for non-contract based events (e.g. those using the Write() API).
+ /// </summary>
+ /// <param name="eventSourceName">
+ /// The name of the event source. Must not be null.
+ /// </param>
+ /// <param name="config">
+ /// Configuration options for the EventSource as a whole.
+ /// </param>
+ public EventSource(
+ string eventSourceName,
+ EventSourceSettings config)
+ : this(eventSourceName, config, null) { }
+
+ /// <summary>
+ /// Construct an EventSource with a given name for non-contract based events (e.g. those using the Write() API).
+ ///
+ /// Also specify a list of key-value pairs called traits (you must pass an even number of strings).
+ /// The first string is the key and the second is the value. These are not interpreted by EventSource
+ /// itself but may be interprated the listeners. Can be fetched with GetTrait(string).
+ /// </summary>
+ /// <param name="eventSourceName">
+ /// The name of the event source. Must not be null.
+ /// </param>
+ /// <param name="config">
+ /// Configuration options for the EventSource as a whole.
+ /// </param>
+ /// <param name="traits">A collection of key-value strings (must be an even number).</param>
+ public EventSource(
+ string eventSourceName,
+ EventSourceSettings config,
+ params string[] traits)
+ : this(
+ eventSourceName == null ? new Guid() : GenerateGuidFromName(eventSourceName.ToUpperInvariant()),
+ eventSourceName,
+ config, traits)
+ {
+ if (eventSourceName == null)
+ {
+ throw new ArgumentNullException(nameof(eventSourceName));
+ }
+ Contract.EndContractBlock();
+ }
+
+ /// <summary>
+ /// Writes an event with no fields and default options.
+ /// (Native API: EventWriteTransfer)
+ /// </summary>
+ /// <param name="eventName">The name of the event. Must not be null.</param>
+ public unsafe void Write(string eventName)
+ {
+ if (eventName == null)
+ {
+ throw new ArgumentNullException(nameof(eventName));
+ }
+
+ Contract.EndContractBlock();
+
+ if (!this.IsEnabled())
+ {
+ return;
+ }
+
+ var options = new EventSourceOptions();
+ this.WriteImpl(eventName, ref options, null, null, null, SimpleEventTypes<EmptyStruct>.Instance);
+ }
+
+ /// <summary>
+ /// Writes an event with no fields.
+ /// (Native API: EventWriteTransfer)
+ /// </summary>
+ /// <param name="eventName">The name of the event. Must not be null.</param>
+ /// <param name="options">
+ /// Options for the event, such as the level, keywords, and opcode. Unset
+ /// options will be set to default values.
+ /// </param>
+ public unsafe void Write(string eventName, EventSourceOptions options)
+ {
+ if (eventName == null)
+ {
+ throw new ArgumentNullException(nameof(eventName));
+ }
+
+ Contract.EndContractBlock();
+
+ if (!this.IsEnabled())
+ {
+ return;
+ }
+
+ this.WriteImpl(eventName, ref options, null, null, null, SimpleEventTypes<EmptyStruct>.Instance);
+ }
+
+ /// <summary>
+ /// Writes an event.
+ /// (Native API: EventWriteTransfer)
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type that defines the event and its payload. This must be an
+ /// anonymous type or a type with an [EventData] attribute.
+ /// </typeparam>
+ /// <param name="eventName">
+ /// The name for the event. If null, the event name is automatically
+ /// determined based on T, either from the Name property of T's EventData
+ /// attribute or from typeof(T).Name.
+ /// </param>
+ /// <param name="data">
+ /// The object containing the event payload data. The type T must be
+ /// an anonymous type or a type with an [EventData] attribute. The
+ /// public instance properties of data will be written recursively to
+ /// create the fields of the event.
+ /// </param>
+ public unsafe void Write<T>(
+ string eventName,
+ T data)
+ {
+ if (!this.IsEnabled())
+ {
+ return;
+ }
+
+ var options = new EventSourceOptions();
+ this.WriteImpl(eventName, ref options, data, null, null, SimpleEventTypes<T>.Instance);
+ }
+
+ /// <summary>
+ /// Writes an event.
+ /// (Native API: EventWriteTransfer)
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type that defines the event and its payload. This must be an
+ /// anonymous type or a type with an [EventData] attribute.
+ /// </typeparam>
+ /// <param name="eventName">
+ /// The name for the event. If null, the event name is automatically
+ /// determined based on T, either from the Name property of T's EventData
+ /// attribute or from typeof(T).Name.
+ /// </param>
+ /// <param name="options">
+ /// Options for the event, such as the level, keywords, and opcode. Unset
+ /// options will be set to default values.
+ /// </param>
+ /// <param name="data">
+ /// The object containing the event payload data. The type T must be
+ /// an anonymous type or a type with an [EventData] attribute. The
+ /// public instance properties of data will be written recursively to
+ /// create the fields of the event.
+ /// </param>
+ public unsafe void Write<T>(
+ string eventName,
+ EventSourceOptions options,
+ T data)
+ {
+ if (!this.IsEnabled())
+ {
+ return;
+ }
+
+ this.WriteImpl(eventName, ref options, data, null, null, SimpleEventTypes<T>.Instance);
+ }
+
+ /// <summary>
+ /// Writes an event.
+ /// This overload is for use with extension methods that wish to efficiently
+ /// forward the options or data parameter without performing an extra copy.
+ /// (Native API: EventWriteTransfer)
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type that defines the event and its payload. This must be an
+ /// anonymous type or a type with an [EventData] attribute.
+ /// </typeparam>
+ /// <param name="eventName">
+ /// The name for the event. If null, the event name is automatically
+ /// determined based on T, either from the Name property of T's EventData
+ /// attribute or from typeof(T).Name.
+ /// </param>
+ /// <param name="options">
+ /// Options for the event, such as the level, keywords, and opcode. Unset
+ /// options will be set to default values.
+ /// </param>
+ /// <param name="data">
+ /// The object containing the event payload data. The type T must be
+ /// an anonymous type or a type with an [EventData] attribute. The
+ /// public instance properties of data will be written recursively to
+ /// create the fields of the event.
+ /// </param>
+ public unsafe void Write<T>(
+ string eventName,
+ ref EventSourceOptions options,
+ ref T data)
+ {
+ if (!this.IsEnabled())
+ {
+ return;
+ }
+
+ this.WriteImpl(eventName, ref options, data, null, null, SimpleEventTypes<T>.Instance);
+ }
+
+ /// <summary>
+ /// Writes an event.
+ /// This overload is meant for clients that need to manipuate the activityId
+ /// and related ActivityId for the event.
+ /// </summary>
+ /// <typeparam name="T">
+ /// The type that defines the event and its payload. This must be an
+ /// anonymous type or a type with an [EventData] attribute.
+ /// </typeparam>
+ /// <param name="eventName">
+ /// The name for the event. If null, the event name is automatically
+ /// determined based on T, either from the Name property of T's EventData
+ /// attribute or from typeof(T).Name.
+ /// </param>
+ /// <param name="options">
+ /// Options for the event, such as the level, keywords, and opcode. Unset
+ /// options will be set to default values.
+ /// </param>
+ /// <param name="activityId">
+ /// The GUID of the activity associated with this event.
+ /// </param>
+ /// <param name="relatedActivityId">
+ /// The GUID of another activity that is related to this activity, or Guid.Empty
+ /// if there is no related activity. Most commonly, the Start operation of a
+ /// new activity specifies a parent activity as its related activity.
+ /// </param>
+ /// <param name="data">
+ /// The object containing the event payload data. The type T must be
+ /// an anonymous type or a type with an [EventData] attribute. The
+ /// public instance properties of data will be written recursively to
+ /// create the fields of the event.
+ /// </param>
+ public unsafe void Write<T>(
+ string eventName,
+ ref EventSourceOptions options,
+ ref Guid activityId,
+ ref Guid relatedActivityId,
+ ref T data)
+ {
+ if (!this.IsEnabled())
+ {
+ return;
+ }
+
+ fixed (Guid* pActivity = &activityId, pRelated = &relatedActivityId)
+ {
+ this.WriteImpl(
+ eventName,
+ ref options,
+ data,
+ pActivity,
+ relatedActivityId == Guid.Empty ? null : pRelated,
+ SimpleEventTypes<T>.Instance);
+ }
+ }
+
+ /// <summary>
+ /// Writes an extended event, where the values of the event are the
+ /// combined properties of any number of values. This method is
+ /// intended for use in advanced logging scenarios that support a
+ /// dynamic set of event context providers.
+ /// This method does a quick check on whether this event is enabled.
+ /// </summary>
+ /// <param name="eventName">
+ /// The name for the event. If null, the name from eventTypes is used.
+ /// (Note that providing the event name via the name parameter is slightly
+ /// less efficient than using the name from eventTypes.)
+ /// </param>
+ /// <param name="options">
+ /// Optional overrides for the event, such as the level, keyword, opcode,
+ /// activityId, and relatedActivityId. Any settings not specified by options
+ /// are obtained from eventTypes.
+ /// </param>
+ /// <param name="eventTypes">
+ /// Information about the event and the types of the values in the event.
+ /// Must not be null. Note that the eventTypes object should be created once and
+ /// saved. It should not be recreated for each event.
+ /// </param>
+ /// <param name="activityID">
+ /// A pointer to the activity ID GUID to log
+ /// </param>
+ /// <param name="childActivityID">
+ /// A pointer to the child activity ID to log (can be null) </param>
+ /// <param name="values">
+ /// The values to include in the event. Must not be null. The number and types of
+ /// the values must match the number and types of the fields described by the
+ /// eventTypes parameter.
+ /// </param>
+ private unsafe void WriteMultiMerge(
+ string eventName,
+ ref EventSourceOptions options,
+ TraceLoggingEventTypes eventTypes,
+ Guid* activityID,
+ Guid* childActivityID,
+ params object[] values)
+ {
+ if (!this.IsEnabled())
+ {
+ return;
+ }
+ byte level = (options.valuesSet & EventSourceOptions.levelSet) != 0
+ ? options.level
+ : eventTypes.level;
+ EventKeywords keywords = (options.valuesSet & EventSourceOptions.keywordsSet) != 0
+ ? options.keywords
+ : eventTypes.keywords;
+
+ if (this.IsEnabled((EventLevel)level, keywords))
+ {
+ WriteMultiMergeInner(eventName, ref options, eventTypes, activityID, childActivityID, values);
+ }
+ }
+
+ /// <summary>
+ /// Writes an extended event, where the values of the event are the
+ /// combined properties of any number of values. This method is
+ /// intended for use in advanced logging scenarios that support a
+ /// dynamic set of event context providers.
+ /// Attention: This API does not check whether the event is enabled or not.
+ /// Please use WriteMultiMerge to avoid spending CPU cycles for events that are
+ /// not enabled.
+ /// </summary>
+ /// <param name="eventName">
+ /// The name for the event. If null, the name from eventTypes is used.
+ /// (Note that providing the event name via the name parameter is slightly
+ /// less efficient than using the name from eventTypes.)
+ /// </param>
+ /// <param name="options">
+ /// Optional overrides for the event, such as the level, keyword, opcode,
+ /// activityId, and relatedActivityId. Any settings not specified by options
+ /// are obtained from eventTypes.
+ /// </param>
+ /// <param name="eventTypes">
+ /// Information about the event and the types of the values in the event.
+ /// Must not be null. Note that the eventTypes object should be created once and
+ /// saved. It should not be recreated for each event.
+ /// </param>
+ /// <param name="activityID">
+ /// A pointer to the activity ID GUID to log
+ /// </param>
+ /// <param name="childActivityID">
+ /// A pointer to the child activity ID to log (can be null)
+ /// </param>
+ /// <param name="values">
+ /// The values to include in the event. Must not be null. The number and types of
+ /// the values must match the number and types of the fields described by the
+ /// eventTypes parameter.
+ /// </param>
+ private unsafe void WriteMultiMergeInner(
+ string eventName,
+ ref EventSourceOptions options,
+ TraceLoggingEventTypes eventTypes,
+ Guid* activityID,
+ Guid* childActivityID,
+ params object[] values)
+ {
+#if FEATURE_MANAGED_ETW
+ int identity = 0;
+ byte level = (options.valuesSet & EventSourceOptions.levelSet) != 0
+ ? options.level
+ : eventTypes.level;
+ byte opcode = (options.valuesSet & EventSourceOptions.opcodeSet) != 0
+ ? options.opcode
+ : eventTypes.opcode;
+ EventTags tags = (options.valuesSet & EventSourceOptions.tagsSet) != 0
+ ? options.tags
+ : eventTypes.Tags;
+ EventKeywords keywords = (options.valuesSet & EventSourceOptions.keywordsSet) != 0
+ ? options.keywords
+ : eventTypes.keywords;
+
+ var nameInfo = eventTypes.GetNameInfo(eventName ?? eventTypes.Name, tags);
+ if (nameInfo == null)
+ {
+ return;
+ }
+ identity = nameInfo.identity;
+ EventDescriptor descriptor = new EventDescriptor(identity, level, opcode, (long)keywords);
+
+ var pinCount = eventTypes.pinCount;
+ var scratch = stackalloc byte[eventTypes.scratchSize];
+ var descriptors = stackalloc EventData[eventTypes.dataCount + 3];
+ var pins = stackalloc GCHandle[pinCount];
+
+ fixed (byte*
+ pMetadata0 = this.providerMetadata,
+ pMetadata1 = nameInfo.nameMetadata,
+ pMetadata2 = eventTypes.typeMetadata)
+ {
+ descriptors[0].SetMetadata(pMetadata0, this.providerMetadata.Length, 2);
+ descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1);
+ descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1);
+
+#if (!ES_BUILD_PCL && !ES_BUILD_PN)
+ System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions();
+#endif
+ try
+ {
+ DataCollector.ThreadInstance.Enable(
+ scratch,
+ eventTypes.scratchSize,
+ descriptors + 3,
+ eventTypes.dataCount,
+ pins,
+ pinCount);
+
+ for (int i = 0; i < eventTypes.typeInfos.Length; i++)
+ {
+ var info = eventTypes.typeInfos[i];
+ info.WriteData(TraceLoggingDataCollector.Instance, info.PropertyValueFactory(values[i]));
+ }
+
+ this.WriteEventRaw(
+ eventName,
+ ref descriptor,
+ activityID,
+ childActivityID,
+ (int)(DataCollector.ThreadInstance.Finish() - descriptors),
+ (IntPtr)descriptors);
+ }
+ finally
+ {
+ this.WriteCleanup(pins, pinCount);
+ }
+ }
+#endif // FEATURE_MANAGED_ETW
+ }
+
+ /// <summary>
+ /// Writes an extended event, where the values of the event have already
+ /// been serialized in "data".
+ /// </summary>
+ /// <param name="eventName">
+ /// The name for the event. If null, the name from eventTypes is used.
+ /// (Note that providing the event name via the name parameter is slightly
+ /// less efficient than using the name from eventTypes.)
+ /// </param>
+ /// <param name="options">
+ /// Optional overrides for the event, such as the level, keyword, opcode,
+ /// activityId, and relatedActivityId. Any settings not specified by options
+ /// are obtained from eventTypes.
+ /// </param>
+ /// <param name="eventTypes">
+ /// Information about the event and the types of the values in the event.
+ /// Must not be null. Note that the eventTypes object should be created once and
+ /// saved. It should not be recreated for each event.
+ /// </param>
+ /// <param name="activityID">
+ /// A pointer to the activity ID GUID to log
+ /// </param>
+ /// <param name="childActivityID">
+ /// A pointer to the child activity ID to log (can be null)
+ /// </param>
+ /// <param name="data">
+ /// The previously serialized values to include in the event. Must not be null.
+ /// The number and types of the values must match the number and types of the
+ /// fields described by the eventTypes parameter.
+ /// </param>
+ internal unsafe void WriteMultiMerge(
+ string eventName,
+ ref EventSourceOptions options,
+ TraceLoggingEventTypes eventTypes,
+ Guid* activityID,
+ Guid* childActivityID,
+ EventData* data)
+ {
+#if FEATURE_MANAGED_ETW
+ if (!this.IsEnabled())
+ {
+ return;
+ }
+
+ fixed (EventSourceOptions* pOptions = &options)
+ {
+ EventDescriptor descriptor;
+ var nameInfo = this.UpdateDescriptor(eventName, eventTypes, ref options, out descriptor);
+ if (nameInfo == null)
+ {
+ return;
+ }
+
+ // We make a descriptor for each EventData, and because we morph strings to counted strings
+ // we may have 2 for each arg, so we allocate enough for this.
+ var descriptors = stackalloc EventData[eventTypes.dataCount + eventTypes.typeInfos.Length * 2 + 3];
+
+ fixed (byte*
+ pMetadata0 = this.providerMetadata,
+ pMetadata1 = nameInfo.nameMetadata,
+ pMetadata2 = eventTypes.typeMetadata)
+ {
+ descriptors[0].SetMetadata(pMetadata0, this.providerMetadata.Length, 2);
+ descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1);
+ descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1);
+ int numDescrs = 3;
+
+ for (int i = 0; i < eventTypes.typeInfos.Length; i++)
+ {
+ // Until M3, we need to morph strings to a counted representation
+ // When TDH supports null terminated strings, we can remove this.
+ if (eventTypes.typeInfos[i].DataType == typeof(string))
+ {
+ // Write out the size of the string
+ descriptors[numDescrs].m_Ptr = (long)&descriptors[numDescrs + 1].m_Size;
+ descriptors[numDescrs].m_Size = 2;
+ numDescrs++;
+
+ descriptors[numDescrs].m_Ptr = data[i].m_Ptr;
+ descriptors[numDescrs].m_Size = data[i].m_Size - 2; // Remove the null terminator
+ numDescrs++;
+ }
+ else
+ {
+ descriptors[numDescrs].m_Ptr = data[i].m_Ptr;
+ descriptors[numDescrs].m_Size = data[i].m_Size;
+
+ // old conventions for bool is 4 bytes, but meta-data assumes 1.
+ if (data[i].m_Size == 4 && eventTypes.typeInfos[i].DataType == typeof(bool))
+ descriptors[numDescrs].m_Size = 1;
+
+ numDescrs++;
+ }
+ }
+
+ this.WriteEventRaw(
+ eventName,
+ ref descriptor,
+ activityID,
+ childActivityID,
+ numDescrs,
+ (IntPtr)descriptors);
+ }
+ }
+#endif // FEATURE_MANAGED_ETW
+ }
+
+ private unsafe void WriteImpl(
+ string eventName,
+ ref EventSourceOptions options,
+ object data,
+ Guid* pActivityId,
+ Guid* pRelatedActivityId,
+ TraceLoggingEventTypes eventTypes)
+ {
+ try
+ {
+ fixed (EventSourceOptions* pOptions = &options)
+ {
+ EventDescriptor descriptor;
+ options.Opcode = options.IsOpcodeSet ? options.Opcode : GetOpcodeWithDefault(options.Opcode, eventName);
+ var nameInfo = this.UpdateDescriptor(eventName, eventTypes, ref options, out descriptor);
+ if (nameInfo == null)
+ {
+ return;
+ }
+
+#if FEATURE_MANAGED_ETW
+ var pinCount = eventTypes.pinCount;
+ var scratch = stackalloc byte[eventTypes.scratchSize];
+ var descriptors = stackalloc EventData[eventTypes.dataCount + 3];
+ var pins = stackalloc GCHandle[pinCount];
+
+ fixed (byte*
+ pMetadata0 = this.providerMetadata,
+ pMetadata1 = nameInfo.nameMetadata,
+ pMetadata2 = eventTypes.typeMetadata)
+ {
+ descriptors[0].SetMetadata(pMetadata0, this.providerMetadata.Length, 2);
+ descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1);
+ descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1);
+#endif // FEATURE_MANAGED_ETW
+
+#if (!ES_BUILD_PCL && !ES_BUILD_PN)
+ System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions();
+#endif
+ EventOpcode opcode = (EventOpcode)descriptor.Opcode;
+
+ Guid activityId = Guid.Empty;
+ Guid relatedActivityId = Guid.Empty;
+ if (pActivityId == null && pRelatedActivityId == null &&
+ ((options.ActivityOptions & EventActivityOptions.Disable) == 0))
+ {
+ if (opcode == EventOpcode.Start)
+ {
+ m_activityTracker.OnStart(m_name, eventName, 0, ref activityId, ref relatedActivityId, options.ActivityOptions);
+ }
+ else if (opcode == EventOpcode.Stop)
+ {
+ m_activityTracker.OnStop(m_name, eventName, 0, ref activityId);
+ }
+ if (activityId != Guid.Empty)
+ pActivityId = &activityId;
+ if (relatedActivityId != Guid.Empty)
+ pRelatedActivityId = &relatedActivityId;
+ }
+
+ try
+ {
+#if FEATURE_MANAGED_ETW
+ DataCollector.ThreadInstance.Enable(
+ scratch,
+ eventTypes.scratchSize,
+ descriptors + 3,
+ eventTypes.dataCount,
+ pins,
+ pinCount);
+
+ var info = eventTypes.typeInfos[0];
+ info.WriteData(TraceLoggingDataCollector.Instance, info.PropertyValueFactory(data));
+
+ this.WriteEventRaw(
+ eventName,
+ ref descriptor,
+ pActivityId,
+ pRelatedActivityId,
+ (int)(DataCollector.ThreadInstance.Finish() - descriptors),
+ (IntPtr)descriptors);
+#endif // FEATURE_MANAGED_ETW
+
+ // TODO enable filtering for listeners.
+ if (m_Dispatchers != null)
+ {
+ var eventData = (EventPayload)(eventTypes.typeInfos[0].GetData(data));
+ WriteToAllListeners(eventName, ref descriptor, nameInfo.tags, pActivityId, eventData);
+ }
+
+ }
+ catch (Exception ex)
+ {
+ if (ex is EventSourceException)
+ throw;
+ else
+ ThrowEventSourceException(eventName, ex);
+ }
+#if FEATURE_MANAGED_ETW
+ finally
+ {
+ this.WriteCleanup(pins, pinCount);
+ }
+ }
+#endif // FEATURE_MANAGED_ETW
+ }
+ }
+ catch (Exception ex)
+ {
+ if (ex is EventSourceException)
+ throw;
+ else
+ ThrowEventSourceException(eventName, ex);
+ }
+ }
+
+ private unsafe void WriteToAllListeners(string eventName, ref EventDescriptor eventDescriptor, EventTags tags, Guid* pActivityId, EventPayload payload)
+ {
+ EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this);
+ eventCallbackArgs.EventName = eventName;
+ eventCallbackArgs.m_level = (EventLevel) eventDescriptor.Level;
+ eventCallbackArgs.m_keywords = (EventKeywords) eventDescriptor.Keywords;
+ eventCallbackArgs.m_opcode = (EventOpcode) eventDescriptor.Opcode;
+ eventCallbackArgs.m_tags = tags;
+
+ // Self described events do not have an id attached. We mark it internally with -1.
+ eventCallbackArgs.EventId = -1;
+ if (pActivityId != null)
+ eventCallbackArgs.RelatedActivityId = *pActivityId;
+
+ if (payload != null)
+ {
+ eventCallbackArgs.Payload = new ReadOnlyCollection<object>((IList<object>)payload.Values);
+ eventCallbackArgs.PayloadNames = new ReadOnlyCollection<string>((IList<string>)payload.Keys);
+ }
+
+ DispatchToAllListeners(-1, pActivityId, eventCallbackArgs);
+ }
+
+#if (!ES_BUILD_PCL && !ES_BUILD_PN)
+ [System.Runtime.ConstrainedExecution.ReliabilityContract(
+ System.Runtime.ConstrainedExecution.Consistency.WillNotCorruptState,
+ System.Runtime.ConstrainedExecution.Cer.Success)]
+#endif
+ [NonEvent]
+ private unsafe void WriteCleanup(GCHandle* pPins, int cPins)
+ {
+ DataCollector.ThreadInstance.Disable();
+
+ for (int i = 0; i != cPins; i++)
+ {
+ if (IntPtr.Zero != (IntPtr)pPins[i])
+ {
+ pPins[i].Free();
+ }
+ }
+ }
+
+ private void InitializeProviderMetadata()
+ {
+#if FEATURE_MANAGED_ETW
+ if (m_traits != null)
+ {
+ List<byte> traitMetaData = new List<byte>(100);
+ for (int i = 0; i < m_traits.Length - 1; i += 2)
+ {
+ if (m_traits[i].StartsWith("ETW_", StringComparison.Ordinal))
+ {
+ string etwTrait = m_traits[i].Substring(4);
+ byte traitNum;
+ if (!byte.TryParse(etwTrait, out traitNum))
+ {
+ if (etwTrait == "GROUP")
+ {
+ traitNum = 1;
+ }
+ else
+ {
+ throw new ArgumentException(Resources.GetResourceString("UnknownEtwTrait", etwTrait), "traits");
+ }
+ }
+ string value = m_traits[i + 1];
+ int lenPos = traitMetaData.Count;
+ traitMetaData.Add(0); // Emit size (to be filled in later)
+ traitMetaData.Add(0);
+ traitMetaData.Add(traitNum); // Emit Trait number
+ var valueLen = AddValueToMetaData(traitMetaData, value) + 3; // Emit the value bytes +3 accounts for 3 bytes we emited above.
+ traitMetaData[lenPos] = unchecked((byte)valueLen); // Fill in size
+ traitMetaData[lenPos + 1] = unchecked((byte)(valueLen >> 8));
+ }
+ }
+ providerMetadata = Statics.MetadataForString(this.Name, 0, traitMetaData.Count, 0);
+ int startPos = providerMetadata.Length - traitMetaData.Count;
+ foreach (var b in traitMetaData)
+ providerMetadata[startPos++] = b;
+ }
+ else
+ providerMetadata = Statics.MetadataForString(this.Name, 0, 0, 0);
+#endif //FEATURE_MANAGED_ETW
+ }
+
+ private static int AddValueToMetaData(List<byte> metaData, string value)
+ {
+ if (value.Length == 0)
+ return 0;
+
+ int startPos = metaData.Count;
+ char firstChar = value[0];
+
+ if (firstChar == '@')
+ metaData.AddRange(Encoding.UTF8.GetBytes(value.Substring(1)));
+ else if (firstChar == '{')
+ metaData.AddRange(new Guid(value).ToByteArray());
+ else if (firstChar == '#')
+ {
+ for (int i = 1; i < value.Length; i++)
+ {
+ if (value[i] != ' ') // Skip spaces between bytes.
+ {
+ if (!(i + 1 < value.Length))
+ {
+ throw new ArgumentException(Resources.GetResourceString("EvenHexDigits"), "traits");
+ }
+ metaData.Add((byte)(HexDigit(value[i]) * 16 + HexDigit(value[i + 1])));
+ i++;
+ }
+ }
+ }
+ else if ('A' <= firstChar || ' ' == firstChar) // Is it alphabetic or space (excludes digits and most punctuation).
+ {
+ metaData.AddRange(Encoding.UTF8.GetBytes(value));
+ }
+ else
+ {
+ throw new ArgumentException(Resources.GetResourceString("IllegalValue", value), "traits");
+ }
+
+ return metaData.Count - startPos;
+ }
+
+ /// <summary>
+ /// Returns a value 0-15 if 'c' is a hexadecimal digit. If it throws an argument exception.
+ /// </summary>
+ private static int HexDigit(char c)
+ {
+ if ('0' <= c && c <= '9')
+ {
+ return (c - '0');
+ }
+ if ('a' <= c)
+ {
+ c = unchecked((char)(c - ('a' - 'A'))); // Convert to lower case
+ }
+ if ('A' <= c && c <= 'F')
+ {
+ return (c - 'A' + 10);
+ }
+
+ throw new ArgumentException(Resources.GetResourceString("BadHexDigit", c), "traits");
+ }
+
+ private NameInfo UpdateDescriptor(
+ string name,
+ TraceLoggingEventTypes eventInfo,
+ ref EventSourceOptions options,
+ out EventDescriptor descriptor)
+ {
+ NameInfo nameInfo = null;
+ int identity = 0;
+ byte level = (options.valuesSet & EventSourceOptions.levelSet) != 0
+ ? options.level
+ : eventInfo.level;
+ byte opcode = (options.valuesSet & EventSourceOptions.opcodeSet) != 0
+ ? options.opcode
+ : eventInfo.opcode;
+ EventTags tags = (options.valuesSet & EventSourceOptions.tagsSet) != 0
+ ? options.tags
+ : eventInfo.Tags;
+ EventKeywords keywords = (options.valuesSet & EventSourceOptions.keywordsSet) != 0
+ ? options.keywords
+ : eventInfo.keywords;
+
+ if (this.IsEnabled((EventLevel)level, keywords))
+ {
+ nameInfo = eventInfo.GetNameInfo(name ?? eventInfo.Name, tags);
+ identity = nameInfo.identity;
+ }
+
+ descriptor = new EventDescriptor(identity, level, opcode, (long)keywords);
+ return nameInfo;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTraits.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventTraits.cs
index e808a8823c..e808a8823c 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTraits.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventTraits.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTypes.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventTypes.cs
index c2239671bb..c2239671bb 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventTypes.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventTypes.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingMetadataCollector.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs
index 41225c8626..41225c8626 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingMetadataCollector.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingMetadataCollector.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingTypeInfo.cs
index d68e106b0b..d68e106b0b 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingTypeInfo.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TraceLoggingTypeInfo.cs
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TypeAnalysis.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TypeAnalysis.cs
index 42cdde5f6a..42cdde5f6a 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TypeAnalysis.cs
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/TraceLogging/TypeAnalysis.cs
diff --git a/src/mscorlib/shared/System/Diagnostics/Tracing/Winmeta.cs b/src/mscorlib/shared/System/Diagnostics/Tracing/Winmeta.cs
new file mode 100644
index 0000000000..ac756b6059
--- /dev/null
+++ b/src/mscorlib/shared/System/Diagnostics/Tracing/Winmeta.cs
@@ -0,0 +1,196 @@
+// 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.
+
+/*============================================================
+**
+**
+** Purpose:
+** Contains eventing constants defined by the Windows
+** environment.
+**
+============================================================*/
+#if ES_BUILD_STANDALONE
+#define FEATURE_MANAGED_ETW_CHANNELS
+#endif
+
+#if ES_BUILD_STANDALONE
+namespace Microsoft.Diagnostics.Tracing
+#else
+namespace System.Diagnostics.Tracing
+#endif
+{
+ using System;
+
+ /// <summary>
+ /// WindowsEventLevel. Custom values must be in the range from 16 through 255
+ /// </summary>
+ public enum EventLevel
+ {
+ /// <summary>
+ /// Log always
+ /// </summary>
+ LogAlways = 0,
+ /// <summary>
+ /// Only critical errors
+ /// </summary>
+ Critical,
+ /// <summary>
+ /// All errors, including previous levels
+ /// </summary>
+ Error,
+ /// <summary>
+ /// All warnings, including previous levels
+ /// </summary>
+ Warning,
+ /// <summary>
+ /// All informational events, including previous levels
+ /// </summary>
+ Informational,
+ /// <summary>
+ /// All events, including previous levels
+ /// </summary>
+ Verbose
+ }
+ /// <summary>
+ /// WindowsEventTask. Custom values must be in the range from 1 through 65534
+ /// </summary>
+#if (!ES_BUILD_STANDALONE && !ES_BUILD_PN)
+ [System.Runtime.CompilerServices.FriendAccessAllowed]
+#endif
+ public enum EventTask
+ {
+ /// <summary>
+ /// Undefined task
+ /// </summary>
+ None = 0
+ }
+ /// <summary>
+ /// EventOpcode. Custom values must be in the range from 11 through 239
+ /// </summary>
+#if (!ES_BUILD_STANDALONE && !ES_BUILD_PN)
+ [System.Runtime.CompilerServices.FriendAccessAllowed]
+#endif
+ public enum EventOpcode
+ {
+ /// <summary>
+ /// An informational event
+ /// </summary>
+ Info = 0,
+ /// <summary>
+ /// An activity start event
+ /// </summary>
+ Start,
+ /// <summary>
+ /// An activity end event
+ /// </summary>
+ Stop,
+ /// <summary>
+ /// A trace collection start event
+ /// </summary>
+ DataCollectionStart,
+ /// <summary>
+ /// A trace collection end event
+ /// </summary>
+ DataCollectionStop,
+ /// <summary>
+ /// An extensional event
+ /// </summary>
+ Extension,
+ /// <summary>
+ /// A reply event
+ /// </summary>
+ Reply,
+ /// <summary>
+ /// An event representing the activity resuming from the suspension
+ /// </summary>
+ Resume,
+ /// <summary>
+ /// An event representing the activity is suspended, pending another activity's completion
+ /// </summary>
+ Suspend,
+ /// <summary>
+ /// An event representing the activity is transferred to another component, and can continue to work
+ /// </summary>
+ Send,
+ /// <summary>
+ /// An event representing receiving an activity transfer from another component
+ /// </summary>
+ Receive = 240
+ }
+
+ // Added for CLR V4
+ /// <summary>
+ /// EventChannel. Custom values must be in the range from 16 through 255. Currently only predefined values allowed.
+ /// </summary>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1028:EnumStorageShouldBeInt32", Justification = "Backwards compatibility")]
+#if (!ES_BUILD_STANDALONE && !ES_BUILD_PN)
+ [System.Runtime.CompilerServices.FriendAccessAllowed]
+#endif
+ public enum EventChannel : byte
+ {
+ /// <summary>
+ /// No channel
+ /// </summary>
+ None = 0,
+ // Channels 1 - 15 are reserved...
+ /// <summary>The admin channel</summary>
+ Admin = 16,
+ /// <summary>The operational channel</summary>
+ Operational = 17,
+ /// <summary>The analytic channel</summary>
+ Analytic = 18,
+ /// <summary>The debug channel</summary>
+ Debug = 19,
+
+ };
+
+ /// <summary>
+ /// EventOpcode
+ /// </summary>
+ [Flags]
+ public enum EventKeywords : long
+ {
+ /// <summary>
+ /// No events.
+ /// </summary>
+ None = 0x0,
+ /// <summary>
+ /// All Events
+ /// </summary>
+ All = ~0,
+ /// <summary>
+ /// Telemetry events
+ /// </summary>
+ MicrosoftTelemetry = 0x02000000000000,
+ /// <summary>
+ /// WDI context events
+ /// </summary>
+ WdiContext = 0x02000000000000,
+ /// <summary>
+ /// WDI diagnostic events
+ /// </summary>
+ WdiDiagnostic = 0x04000000000000,
+ /// <summary>
+ /// SQM events
+ /// </summary>
+ Sqm = 0x08000000000000,
+ /// <summary>
+ /// Failed security audits
+ /// </summary>
+ AuditFailure = 0x10000000000000,
+ /// <summary>
+ /// Successful security audits
+ /// </summary>
+ AuditSuccess = 0x20000000000000,
+ /// <summary>
+ /// Transfer events where the related Activity ID is a computed value and not a GUID
+ /// N.B. The correct value for this field is 0x40000000000000.
+ /// </summary>
+ CorrelationHint = 0x10000000000000,
+ /// <summary>
+ /// Events raised using classic eventlog API
+ /// </summary>
+ EventLogClassic = 0x80000000000000
+ }
+}
diff --git a/src/mscorlib/src/System/DivideByZeroException.cs b/src/mscorlib/shared/System/DivideByZeroException.cs
index 4abd43adaf..4abd43adaf 100644
--- a/src/mscorlib/src/System/DivideByZeroException.cs
+++ b/src/mscorlib/shared/System/DivideByZeroException.cs
diff --git a/src/mscorlib/src/System/DuplicateWaitObjectException.cs b/src/mscorlib/shared/System/DuplicateWaitObjectException.cs
index da29e2ad76..da29e2ad76 100644
--- a/src/mscorlib/src/System/DuplicateWaitObjectException.cs
+++ b/src/mscorlib/shared/System/DuplicateWaitObjectException.cs
diff --git a/src/mscorlib/src/System/EntryPointNotFoundException.cs b/src/mscorlib/shared/System/EntryPointNotFoundException.cs
index 835d33413d..835d33413d 100644
--- a/src/mscorlib/src/System/EntryPointNotFoundException.cs
+++ b/src/mscorlib/shared/System/EntryPointNotFoundException.cs
diff --git a/src/mscorlib/src/System/EventArgs.cs b/src/mscorlib/shared/System/EventArgs.cs
index c0356613de..c0356613de 100644
--- a/src/mscorlib/src/System/EventArgs.cs
+++ b/src/mscorlib/shared/System/EventArgs.cs
diff --git a/src/mscorlib/src/System/EventHandler.cs b/src/mscorlib/shared/System/EventHandler.cs
index e6923cf637..e6923cf637 100644
--- a/src/mscorlib/src/System/EventHandler.cs
+++ b/src/mscorlib/shared/System/EventHandler.cs
diff --git a/src/mscorlib/src/System/ExecutionEngineException.cs b/src/mscorlib/shared/System/ExecutionEngineException.cs
index bebfd493a0..bebfd493a0 100644
--- a/src/mscorlib/src/System/ExecutionEngineException.cs
+++ b/src/mscorlib/shared/System/ExecutionEngineException.cs
diff --git a/src/mscorlib/src/System/FieldAccessException.cs b/src/mscorlib/shared/System/FieldAccessException.cs
index ac62c0fcac..ac62c0fcac 100644
--- a/src/mscorlib/src/System/FieldAccessException.cs
+++ b/src/mscorlib/shared/System/FieldAccessException.cs
diff --git a/src/mscorlib/src/System/FlagsAttribute.cs b/src/mscorlib/shared/System/FlagsAttribute.cs
index 5f8c108ae4..5f8c108ae4 100644
--- a/src/mscorlib/src/System/FlagsAttribute.cs
+++ b/src/mscorlib/shared/System/FlagsAttribute.cs
diff --git a/src/mscorlib/src/System/FormatException.cs b/src/mscorlib/shared/System/FormatException.cs
index c5758e11cd..c5758e11cd 100644
--- a/src/mscorlib/src/System/FormatException.cs
+++ b/src/mscorlib/shared/System/FormatException.cs
diff --git a/src/mscorlib/src/System/FormattableString.cs b/src/mscorlib/shared/System/FormattableString.cs
index 6369363b5d..6369363b5d 100644
--- a/src/mscorlib/src/System/FormattableString.cs
+++ b/src/mscorlib/shared/System/FormattableString.cs
diff --git a/src/mscorlib/shared/System/Globalization/CalendarAlgorithmType.cs b/src/mscorlib/shared/System/Globalization/CalendarAlgorithmType.cs
new file mode 100644
index 0000000000..4ddc307abf
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/CalendarAlgorithmType.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Globalization
+{
+ public enum CalendarAlgorithmType
+ {
+ Unknown = 0, // This is the default value to return in the Calendar base class.
+ SolarCalendar = 1, // Solar-base calendar, such as GregorianCalendar, jaoaneseCalendar, JulianCalendar, etc.
+ // Solar calendars are based on the solar year and seasons.
+ LunarCalendar = 2, // Lunar-based calendar, such as Hijri and UmAlQuraCalendar.
+ // Lunar calendars are based on the path of the moon. The seasons are not accurately represented.
+ LunisolarCalendar = 3 // Lunisolar-based calendar which use leap month rule, such as HebrewCalendar and Asian Lunisolar calendars.
+ // Lunisolar calendars are based on the cycle of the moon, but consider the seasons as a secondary consideration,
+ // so they align with the seasons as well as lunar events.
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/CalendarWeekRule.cs b/src/mscorlib/shared/System/Globalization/CalendarWeekRule.cs
new file mode 100644
index 0000000000..b381b5c544
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/CalendarWeekRule.cs
@@ -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.
+
+namespace System.Globalization
+{
+ [Serializable]
+ public enum CalendarWeekRule
+ {
+ FirstDay = 0, // Week 1 begins on the first day of the year
+
+ FirstFullWeek = 1, // Week 1 begins on first FirstDayOfWeek not before the first day of the year
+
+ FirstFourDayWeek = 2 // Week 1 begins on first FirstDayOfWeek such that FirstDayOfWeek+3 is not before the first day of the year
+ };
+}
diff --git a/src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs b/src/mscorlib/shared/System/Globalization/CalendricalCalculationsHelper.cs
index 7de75d6aee..7de75d6aee 100644
--- a/src/mscorlib/corefx/System/Globalization/CalendricalCalculationsHelper.cs
+++ b/src/mscorlib/shared/System/Globalization/CalendricalCalculationsHelper.cs
diff --git a/src/mscorlib/shared/System/Globalization/ChineseLunisolarCalendar.cs b/src/mscorlib/shared/System/Globalization/ChineseLunisolarCalendar.cs
new file mode 100644
index 0000000000..404add0936
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/ChineseLunisolarCalendar.cs
@@ -0,0 +1,390 @@
+// 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.Diagnostics.Contracts;
+
+namespace System.Globalization
+{
+ /*
+ ** Calendar support range:
+ ** Calendar Minimum Maximum
+ ** ========== ========== ==========
+ ** Gregorian 1901/02/19 2101/01/28
+ ** ChineseLunisolar 1901/01/01 2100/12/29
+ */
+
+ [Serializable]
+ public class ChineseLunisolarCalendar : EastAsianLunisolarCalendar
+ {
+ //
+ // The era value for the current era.
+ //
+
+ public const int ChineseEra = 1;
+
+ internal const int MIN_LUNISOLAR_YEAR = 1901;
+ internal const int MAX_LUNISOLAR_YEAR = 2100;
+
+ internal const int MIN_GREGORIAN_YEAR = 1901;
+ internal const int MIN_GREGORIAN_MONTH = 2;
+ internal const int MIN_GREGORIAN_DAY = 19;
+
+ internal const int MAX_GREGORIAN_YEAR = 2101;
+ internal const int MAX_GREGORIAN_MONTH = 1;
+ internal const int MAX_GREGORIAN_DAY = 28;
+
+ internal static DateTime minDate = new DateTime(MIN_GREGORIAN_YEAR, MIN_GREGORIAN_MONTH, MIN_GREGORIAN_DAY);
+ internal static DateTime maxDate = new DateTime((new DateTime(MAX_GREGORIAN_YEAR, MAX_GREGORIAN_MONTH, MAX_GREGORIAN_DAY, 23, 59, 59, 999)).Ticks + 9999);
+
+ public override DateTime MinSupportedDateTime
+ {
+ get
+ {
+ return (minDate);
+ }
+ }
+
+
+ public override DateTime MaxSupportedDateTime
+ {
+ get
+ {
+ return (maxDate);
+ }
+ }
+
+ protected override int DaysInYearBeforeMinSupportedYear
+ {
+ get
+ {
+ // 1900: 1-29 2-30 3-29 4-29 5-30 6-29 7-30 8-30 Leap8-29 9-30 10-30 11-29 12-30 from Calendrical Tabulations
+ return 384;
+ }
+ }
+
+
+ private static readonly int[,] s_yinfo =
+ {
+ /*Y LM Lmon Lday DaysPerMonth D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 #Days
+ 1901 */
+ { 0 , 2 , 19 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1902 */{ 0 , 2 , 8 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1903 */{ 5 , 1 , 29 , 21096 },/* 29 30 29 30 29 29 30 29 29 30 30 29 30 383
+1904 */{ 0 , 2 , 16 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
+1905 */{ 0 , 2 , 4 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
+1906 */{ 4 , 1 , 25 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
+1907 */{ 0 , 2 , 13 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1908 */{ 0 , 2 , 2 , 39632 },/* 30 29 29 30 30 29 30 29 30 30 29 30 0 355
+1909 */{ 2 , 1 , 22 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+1910 */{ 0 , 2 , 10 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1911 */{ 6 , 1 , 30 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
+1912 */{ 0 , 2 , 18 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1913 */{ 0 , 2 , 6 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
+1914 */{ 5 , 1 , 26 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
+1915 */{ 0 , 2 , 14 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
+1916 */{ 0 , 2 , 3 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 0 355
+1917 */{ 2 , 1 , 23 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
+1918 */{ 0 , 2 , 11 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1919 */{ 7 , 2 , 1 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
+1920 */{ 0 , 2 , 20 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1921 */{ 0 , 2 , 8 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1922 */{ 5 , 1 , 28 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
+1923 */{ 0 , 2 , 16 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
+1924 */{ 0 , 2 , 5 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
+1925 */{ 4 , 1 , 24 , 44456 },/* 30 29 30 29 30 30 29 30 30 29 30 29 30 385
+1926 */{ 0 , 2 , 13 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1927 */{ 0 , 2 , 2 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 0 355
+1928 */{ 2 , 1 , 23 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
+1929 */{ 0 , 2 , 10 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1930 */{ 6 , 1 , 30 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
+1931 */{ 0 , 2 , 17 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1932 */{ 0 , 2 , 6 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
+1933 */{ 5 , 1 , 26 , 27976 },/* 29 30 30 29 30 30 29 30 29 30 29 29 30 384
+1934 */{ 0 , 2 , 14 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
+1935 */{ 0 , 2 , 4 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1936 */{ 3 , 1 , 24 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
+1937 */{ 0 , 2 , 11 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+1938 */{ 7 , 1 , 31 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
+1939 */{ 0 , 2 , 19 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
+1940 */{ 0 , 2 , 8 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1941 */{ 6 , 1 , 27 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
+1942 */{ 0 , 2 , 15 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1943 */{ 0 , 2 , 5 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1944 */{ 4 , 1 , 25 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
+1945 */{ 0 , 2 , 13 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+1946 */{ 0 , 2 , 2 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
+1947 */{ 2 , 1 , 22 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
+1948 */{ 0 , 2 , 10 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1949 */{ 7 , 1 , 29 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
+1950 */{ 0 , 2 , 17 , 27808 },/* 29 30 30 29 30 30 29 29 30 29 30 29 0 354
+1951 */{ 0 , 2 , 6 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1952 */{ 5 , 1 , 27 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
+1953 */{ 0 , 2 , 14 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
+1954 */{ 0 , 2 , 3 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
+1955 */{ 3 , 1 , 24 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
+1956 */{ 0 , 2 , 12 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1957 */{ 8 , 1 , 31 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 29 383
+1958 */{ 0 , 2 , 18 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
+1959 */{ 0 , 2 , 8 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+1960 */{ 6 , 1 , 28 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
+1961 */{ 0 , 2 , 15 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
+1962 */{ 0 , 2 , 5 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+1963 */{ 4 , 1 , 25 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
+1964 */{ 0 , 2 , 13 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1965 */{ 0 , 2 , 2 , 21088 },/* 29 30 29 30 29 29 30 29 29 30 30 29 0 353
+1966 */{ 3 , 1 , 21 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
+1967 */{ 0 , 2 , 9 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
+1968 */{ 7 , 1 , 30 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
+1969 */{ 0 , 2 , 17 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1970 */{ 0 , 2 , 6 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
+1971 */{ 5 , 1 , 27 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+1972 */{ 0 , 2 , 15 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
+1973 */{ 0 , 2 , 3 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1974 */{ 4 , 1 , 23 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
+1975 */{ 0 , 2 , 11 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
+1976 */{ 8 , 1 , 31 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
+1977 */{ 0 , 2 , 18 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
+1978 */{ 0 , 2 , 7 , 46752 },/* 30 29 30 30 29 30 30 29 30 29 30 29 0 355
+1979 */{ 6 , 1 , 28 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
+1980 */{ 0 , 2 , 16 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1981 */{ 0 , 2 , 5 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+1982 */{ 4 , 1 , 25 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
+1983 */{ 0 , 2 , 13 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1984 */{ 10 , 2 , 2 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
+1985 */{ 0 , 2 , 20 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
+1986 */{ 0 , 2 , 9 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
+1987 */{ 6 , 1 , 29 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 29 384
+1988 */{ 0 , 2 , 17 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
+1989 */{ 0 , 2 , 6 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 0 355
+1990 */{ 5 , 1 , 27 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
+1991 */{ 0 , 2 , 15 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1992 */{ 0 , 2 , 4 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
+1993 */{ 3 , 1 , 23 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
+1994 */{ 0 , 2 , 10 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
+1995 */{ 8 , 1 , 31 , 27432 },/* 29 30 30 29 30 29 30 30 29 29 30 29 30 384
+1996 */{ 0 , 2 , 19 , 23232 },/* 29 30 29 30 30 29 30 29 30 30 29 29 0 354
+1997 */{ 0 , 2 , 7 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
+1998 */{ 5 , 1 , 28 , 37736 },/* 30 29 29 30 29 29 30 30 29 30 30 29 30 384
+1999 */{ 0 , 2 , 16 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+2000 */{ 0 , 2 , 5 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
+2001 */{ 4 , 1 , 24 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+2002 */{ 0 , 2 , 12 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+2003 */{ 0 , 2 , 1 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
+2004 */{ 2 , 1 , 22 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
+2005 */{ 0 , 2 , 9 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+2006 */{ 7 , 1 , 29 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
+2007 */{ 0 , 2 , 18 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+2008 */{ 0 , 2 , 7 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
+2009 */{ 5 , 1 , 26 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
+2010 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+2011 */{ 0 , 2 , 3 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
+2012 */{ 4 , 1 , 23 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
+2013 */{ 0 , 2 , 10 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+2014 */{ 9 , 1 , 31 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
+2015 */{ 0 , 2 , 19 , 19360 },/* 29 30 29 29 30 29 30 30 30 29 30 29 0 354
+2016 */{ 0 , 2 , 8 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
+2017 */{ 6 , 1 , 28 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
+2018 */{ 0 , 2 , 16 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+2019 */{ 0 , 2 , 5 , 43312 },/* 30 29 30 29 30 29 29 30 29 29 30 30 0 354
+2020 */{ 4 , 1 , 25 , 29864 },/* 29 30 30 30 29 30 29 29 30 29 30 29 30 384
+2021 */{ 0 , 2 , 12 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+2022 */{ 0 , 2 , 1 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+2023 */{ 2 , 1 , 22 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
+2024 */{ 0 , 2 , 10 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+2025 */{ 6 , 1 , 29 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
+2026 */{ 0 , 2 , 17 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
+2027 */{ 0 , 2 , 6 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
+2028 */{ 5 , 1 , 26 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
+2029 */{ 0 , 2 , 13 , 54576 },/* 30 30 29 30 29 30 29 30 29 29 30 30 0 355
+2030 */{ 0 , 2 , 3 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+2031 */{ 3 , 1 , 23 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
+2032 */{ 0 , 2 , 11 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
+2033 */{ 11 , 1 , 31 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+2034 */{ 0 , 2 , 19 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
+2035 */{ 0 , 2 , 8 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+2036 */{ 6 , 1 , 28 , 53848 },/* 30 30 29 30 29 29 30 29 29 30 29 30 30 384
+2037 */{ 0 , 2 , 15 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
+2038 */{ 0 , 2 , 4 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
+2039 */{ 5 , 1 , 24 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 29 384
+2040 */{ 0 , 2 , 12 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
+2041 */{ 0 , 2 , 1 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
+2042 */{ 2 , 1 , 22 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
+2043 */{ 0 , 2 , 10 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+2044 */{ 7 , 1 , 30 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
+2045 */{ 0 , 2 , 17 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+2046 */{ 0 , 2 , 6 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
+2047 */{ 5 , 1 , 26 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
+2048 */{ 0 , 2 , 14 , 27936 },/* 29 30 30 29 30 30 29 30 29 29 30 29 0 354
+2049 */{ 0 , 2 , 2 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
+2050 */{ 3 , 1 , 23 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
+2051 */{ 0 , 2 , 11 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
+2052 */{ 8 , 2 , 1 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
+2053 */{ 0 , 2 , 19 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+2054 */{ 0 , 2 , 8 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
+2055 */{ 6 , 1 , 28 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
+2056 */{ 0 , 2 , 15 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
+2057 */{ 0 , 2 , 4 , 27424 },/* 29 30 30 29 30 29 30 30 29 29 30 29 0 354
+2058 */{ 4 , 1 , 24 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 29 384
+2059 */{ 0 , 2 , 12 , 43744 },/* 30 29 30 29 30 29 30 29 30 30 30 29 0 355
+2060 */{ 0 , 2 , 2 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+2061 */{ 3 , 1 , 21 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 29 384
+2062 */{ 0 , 2 , 9 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
+2063 */{ 7 , 1 , 29 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+2064 */{ 0 , 2 , 17 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+2065 */{ 0 , 2 , 5 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
+2066 */{ 5 , 1 , 26 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
+2067 */{ 0 , 2 , 14 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+2068 */{ 0 , 2 , 3 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
+2069 */{ 4 , 1 , 23 , 21224 },/* 29 30 29 30 29 29 30 29 30 30 30 29 30 384
+2070 */{ 0 , 2 , 11 , 21200 },/* 29 30 29 30 29 29 30 29 30 30 29 30 0 354
+2071 */{ 8 , 1 , 31 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
+2072 */{ 0 , 2 , 19 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+2073 */{ 0 , 2 , 7 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
+2074 */{ 6 , 1 , 27 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
+2075 */{ 0 , 2 , 15 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+2076 */{ 0 , 2 , 5 , 21920 },/* 29 30 29 30 29 30 29 30 30 29 30 29 0 354
+2077 */{ 4 , 1 , 24 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 29 384
+2078 */{ 0 , 2 , 12 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
+2079 */{ 0 , 2 , 2 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+2080 */{ 3 , 1 , 22 , 43320 },/* 30 29 30 29 30 29 29 30 29 29 30 30 30 384
+2081 */{ 0 , 2 , 9 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 0 354
+2082 */{ 7 , 1 , 29 , 29336 },/* 29 30 30 30 29 29 30 29 30 29 29 30 30 384
+2083 */{ 0 , 2 , 17 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+2084 */{ 0 , 2 , 6 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+2085 */{ 5 , 1 , 26 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
+2086 */{ 0 , 2 , 14 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+2087 */{ 0 , 2 , 3 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+2088 */{ 4 , 1 , 24 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 29 383
+2089 */{ 0 , 2 , 10 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
+2090 */{ 8 , 1 , 30 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
+2091 */{ 0 , 2 , 18 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
+2092 */{ 0 , 2 , 7 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
+2093 */{ 6 , 1 , 27 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
+2094 */{ 0 , 2 , 15 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
+2095 */{ 0 , 2 , 5 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+2096 */{ 4 , 1 , 25 , 42216 },/* 30 29 30 29 29 30 29 29 30 30 30 29 30 384
+2097 */{ 0 , 2 , 12 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+2098 */{ 0 , 2 , 1 , 53584 },/* 30 30 29 30 29 29 29 30 29 30 29 30 0 354
+2099 */{ 2 , 1 , 21 , 55592 },/* 30 30 29 30 30 29 29 30 29 29 30 29 30 384
+2100 */{ 0 , 2 , 9 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
+ */};
+
+
+ internal override int MinCalendarYear
+ {
+ get
+ {
+ return (MIN_LUNISOLAR_YEAR);
+ }
+ }
+
+ internal override int MaxCalendarYear
+ {
+ get
+ {
+ return (MAX_LUNISOLAR_YEAR);
+ }
+ }
+
+ internal override DateTime MinDate
+ {
+ get
+ {
+ return (minDate);
+ }
+ }
+
+ internal override DateTime MaxDate
+ {
+ get
+ {
+ return (maxDate);
+ }
+ }
+
+ internal override EraInfo[] CalEraInfo
+ {
+ get
+ {
+ return (null);
+ }
+ }
+
+ internal override int GetYearInfo(int lunarYear, int index)
+ {
+ if ((lunarYear < MIN_LUNISOLAR_YEAR) || (lunarYear > MAX_LUNISOLAR_YEAR))
+ {
+ throw new ArgumentOutOfRangeException(
+ "year",
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range, MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR));
+ }
+ Contract.EndContractBlock();
+
+ return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index];
+ }
+
+ internal override int GetYear(int year, DateTime time)
+ {
+ return year;
+ }
+
+ internal override int GetGregorianYear(int year, int era)
+ {
+ if (era != CurrentEra && era != ChineseEra)
+ {
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
+ }
+
+ if (year < MIN_LUNISOLAR_YEAR || year > MAX_LUNISOLAR_YEAR)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(year),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range, MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR));
+ }
+ Contract.EndContractBlock();
+
+ return year;
+ }
+
+ public ChineseLunisolarCalendar()
+ {
+ }
+
+ public override int GetEra(DateTime time)
+ {
+ CheckTicksRange(time.Ticks);
+ return (ChineseEra);
+ }
+
+ internal override CalendarId ID
+ {
+ get
+ {
+ return (CalendarId.CHINESELUNISOLAR);
+ }
+ }
+
+ internal override CalendarId BaseCalendarID
+ {
+ get
+ {
+ //Use CAL_GREGORIAN just to get CurrentEraValue as 1 since we do not have data under the ID CAL_ChineseLunisolar yet
+ return (CalendarId.GREGORIAN);
+ }
+ }
+
+
+ public override int[] Eras
+ {
+ get
+ {
+ return (new int[] { ChineseEra });
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/CultureNotFoundException.cs b/src/mscorlib/shared/System/Globalization/CultureNotFoundException.cs
new file mode 100644
index 0000000000..929f4bb000
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/CultureNotFoundException.cs
@@ -0,0 +1,120 @@
+// 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.Runtime.Serialization;
+
+namespace System.Globalization
+{
+ [Serializable]
+ public class CultureNotFoundException : ArgumentException
+ {
+ private string _invalidCultureName; // unrecognized culture name
+ private int? _invalidCultureId; // unrecognized culture Lcid
+
+ public CultureNotFoundException()
+ : base(DefaultMessage)
+ {
+ }
+
+ public CultureNotFoundException(String message)
+ : base(message)
+ {
+ }
+
+ public CultureNotFoundException(String paramName, String message)
+ : base(message, paramName)
+ {
+ }
+
+ public CultureNotFoundException(String message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+ public CultureNotFoundException(String paramName, string invalidCultureName, String message)
+ : base(message, paramName)
+ {
+ _invalidCultureName = invalidCultureName;
+ }
+
+ public CultureNotFoundException(String message, string invalidCultureName, Exception innerException)
+ : base(message, innerException)
+ {
+ _invalidCultureName = invalidCultureName;
+ }
+
+ public CultureNotFoundException(string message, int invalidCultureId, Exception innerException)
+ : base(message, innerException)
+ {
+ _invalidCultureId = invalidCultureId;
+ }
+
+ public CultureNotFoundException(string paramName, int invalidCultureId, string message)
+ : base(message, paramName)
+ {
+ _invalidCultureId = invalidCultureId;
+ }
+
+ protected CultureNotFoundException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ _invalidCultureId = (int?)info.GetValue("InvalidCultureId", typeof(int?));
+ _invalidCultureName = (string)info.GetValue("InvalidCultureName", typeof(string));
+ }
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData(info, context);
+ info.AddValue("InvalidCultureId", _invalidCultureId, typeof(int?));
+ info.AddValue("InvalidCultureName", _invalidCultureName, typeof(string));
+ }
+
+ public virtual Nullable<int> InvalidCultureId
+ {
+ get { return _invalidCultureId; }
+ }
+
+ public virtual string InvalidCultureName
+ {
+ get { return _invalidCultureName; }
+ }
+
+ private static String DefaultMessage
+ {
+ get
+ {
+ return SR.Argument_CultureNotSupported;
+ }
+ }
+
+ private String FormatedInvalidCultureId
+ {
+ get
+ {
+ return InvalidCultureId != null ?
+ String.Format(CultureInfo.InvariantCulture, "{0} (0x{0:x4})", (int)InvalidCultureId) :
+ InvalidCultureName;
+ }
+ }
+
+ public override String Message
+ {
+ get
+ {
+ String s = base.Message;
+ if (_invalidCultureId != null || _invalidCultureName != null)
+ {
+ String valueMessage = SR.Format(SR.Argument_CultureInvalidIdentifier, FormatedInvalidCultureId);
+ if (s == null)
+ {
+ return valueMessage;
+ }
+
+ return s + Environment.NewLine + valueMessage;
+ }
+ return s;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/CultureTypes.cs b/src/mscorlib/shared/System/Globalization/CultureTypes.cs
new file mode 100644
index 0000000000..f52ac82a83
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/CultureTypes.cs
@@ -0,0 +1,27 @@
+// 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.
+
+// The enumeration constants used in CultureInfo.GetCultures().
+// On Linux platforms, the only enum values used there is NeutralCultures and SpecificCultures
+// the rest are obsolete or not valid on Linux
+
+namespace System.Globalization
+{
+ [Flags]
+ public enum CultureTypes
+ {
+ NeutralCultures = 0x0001, // Neutral cultures are cultures like "en", "de", "zh", etc, for enumeration this includes ALL neutrals regardless of other flags
+ SpecificCultures = 0x0002, // Non-netural cultuers. Examples are "en-us", "zh-tw", etc., for enumeration this includes ALL specifics regardless of other flags
+ InstalledWin32Cultures = 0x0004, // Win32 installed cultures in the system and exists in the framework too., this is effectively all cultures
+
+ AllCultures = NeutralCultures | SpecificCultures | InstalledWin32Cultures,
+
+ UserCustomCulture = 0x0008, // User defined custom culture
+ ReplacementCultures = 0x0010, // User defined replacement custom culture.
+ [Obsolete("This value has been deprecated. Please use other values in CultureTypes.")]
+ WindowsOnlyCultures = 0x0020, // this will always return empty list.
+ [Obsolete("This value has been deprecated. Please use other values in CultureTypes.")]
+ FrameworkCultures = 0x0040, // will return only the v2 cultures marked as Framework culture.
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/DateTimeFormat.cs b/src/mscorlib/shared/System/Globalization/DateTimeFormat.cs
new file mode 100644
index 0000000000..840409f55a
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/DateTimeFormat.cs
@@ -0,0 +1,1206 @@
+// 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.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Text;
+
+namespace System
+{
+ /*
+ Customized format patterns:
+ P.S. Format in the table below is the internal number format used to display the pattern.
+
+ Patterns Format Description Example
+ ========= ========== ===================================== ========
+ "h" "0" hour (12-hour clock)w/o leading zero 3
+ "hh" "00" hour (12-hour clock)with leading zero 03
+ "hh*" "00" hour (12-hour clock)with leading zero 03
+
+ "H" "0" hour (24-hour clock)w/o leading zero 8
+ "HH" "00" hour (24-hour clock)with leading zero 08
+ "HH*" "00" hour (24-hour clock) 08
+
+ "m" "0" minute w/o leading zero
+ "mm" "00" minute with leading zero
+ "mm*" "00" minute with leading zero
+
+ "s" "0" second w/o leading zero
+ "ss" "00" second with leading zero
+ "ss*" "00" second with leading zero
+
+ "f" "0" second fraction (1 digit)
+ "ff" "00" second fraction (2 digit)
+ "fff" "000" second fraction (3 digit)
+ "ffff" "0000" second fraction (4 digit)
+ "fffff" "00000" second fraction (5 digit)
+ "ffffff" "000000" second fraction (6 digit)
+ "fffffff" "0000000" second fraction (7 digit)
+
+ "F" "0" second fraction (up to 1 digit)
+ "FF" "00" second fraction (up to 2 digit)
+ "FFF" "000" second fraction (up to 3 digit)
+ "FFFF" "0000" second fraction (up to 4 digit)
+ "FFFFF" "00000" second fraction (up to 5 digit)
+ "FFFFFF" "000000" second fraction (up to 6 digit)
+ "FFFFFFF" "0000000" second fraction (up to 7 digit)
+
+ "t" first character of AM/PM designator A
+ "tt" AM/PM designator AM
+ "tt*" AM/PM designator PM
+
+ "d" "0" day w/o leading zero 1
+ "dd" "00" day with leading zero 01
+ "ddd" short weekday name (abbreviation) Mon
+ "dddd" full weekday name Monday
+ "dddd*" full weekday name Monday
+
+
+ "M" "0" month w/o leading zero 2
+ "MM" "00" month with leading zero 02
+ "MMM" short month name (abbreviation) Feb
+ "MMMM" full month name Febuary
+ "MMMM*" full month name Febuary
+
+ "y" "0" two digit year (year % 100) w/o leading zero 0
+ "yy" "00" two digit year (year % 100) with leading zero 00
+ "yyy" "D3" year 2000
+ "yyyy" "D4" year 2000
+ "yyyyy" "D5" year 2000
+ ...
+
+ "z" "+0;-0" timezone offset w/o leading zero -8
+ "zz" "+00;-00" timezone offset with leading zero -08
+ "zzz" "+00;-00" for hour offset, "00" for minute offset full timezone offset -07:30
+ "zzz*" "+00;-00" for hour offset, "00" for minute offset full timezone offset -08:00
+
+ "K" -Local "zzz", e.g. -08:00
+ -Utc "'Z'", representing UTC
+ -Unspecified ""
+ -DateTimeOffset "zzzzz" e.g -07:30:15
+
+ "g*" the current era name A.D.
+
+ ":" time separator : -- DEPRECATED - Insert separator directly into pattern (eg: "H.mm.ss")
+ "/" date separator /-- DEPRECATED - Insert separator directly into pattern (eg: "M-dd-yyyy")
+ "'" quoted string 'ABC' will insert ABC into the formatted string.
+ '"' quoted string "ABC" will insert ABC into the formatted string.
+ "%" used to quote a single pattern characters E.g.The format character "%y" is to print two digit year.
+ "\" escaped character E.g. '\d' insert the character 'd' into the format string.
+ other characters insert the character into the format string.
+
+ Pre-defined format characters:
+ (U) to indicate Universal time is used.
+ (G) to indicate Gregorian calendar is used.
+
+ Format Description Real format Example
+ ========= ================================= ====================== =======================
+ "d" short date culture-specific 10/31/1999
+ "D" long data culture-specific Sunday, October 31, 1999
+ "f" full date (long date + short time) culture-specific Sunday, October 31, 1999 2:00 AM
+ "F" full date (long date + long time) culture-specific Sunday, October 31, 1999 2:00:00 AM
+ "g" general date (short date + short time) culture-specific 10/31/1999 2:00 AM
+ "G" general date (short date + long time) culture-specific 10/31/1999 2:00:00 AM
+ "m"/"M" Month/Day date culture-specific October 31
+(G) "o"/"O" Round Trip XML "yyyy-MM-ddTHH:mm:ss.fffffffK" 1999-10-31 02:00:00.0000000Z
+(G) "r"/"R" RFC 1123 date, "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'" Sun, 31 Oct 1999 10:00:00 GMT
+(G) "s" Sortable format, based on ISO 8601. "yyyy-MM-dd'T'HH:mm:ss" 1999-10-31T02:00:00
+ ('T' for local time)
+ "t" short time culture-specific 2:00 AM
+ "T" long time culture-specific 2:00:00 AM
+(G) "u" Universal time with sortable format, "yyyy'-'MM'-'dd HH':'mm':'ss'Z'" 1999-10-31 10:00:00Z
+ based on ISO 8601.
+(U) "U" Universal time with full culture-specific Sunday, October 31, 1999 10:00:00 AM
+ (long date + long time) format
+ "y"/"Y" Year/Month day culture-specific October, 1999
+
+ */
+
+ //This class contains only static members and does not require the serializable attribute.
+ internal static
+ class DateTimeFormat
+ {
+ internal const int MaxSecondsFractionDigits = 7;
+ internal static readonly TimeSpan NullOffset = TimeSpan.MinValue;
+
+ internal static char[] allStandardFormats =
+ {
+ 'd', 'D', 'f', 'F', 'g', 'G',
+ 'm', 'M', 'o', 'O', 'r', 'R',
+ 's', 't', 'T', 'u', 'U', 'y', 'Y',
+ };
+
+ internal const String RoundtripFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK";
+ internal const String RoundtripDateTimeUnfixed = "yyyy'-'MM'-'ddTHH':'mm':'ss zzz";
+
+ private const int DEFAULT_ALL_DATETIMES_SIZE = 132;
+
+ internal static readonly DateTimeFormatInfo InvariantFormatInfo = CultureInfo.InvariantCulture.DateTimeFormat;
+ internal static readonly string[] InvariantAbbreviatedMonthNames = InvariantFormatInfo.AbbreviatedMonthNames;
+ internal static readonly string[] InvariantAbbreviatedDayNames = InvariantFormatInfo.AbbreviatedDayNames;
+ internal const string Gmt = "GMT";
+
+ internal static String[] fixedNumberFormats = new String[] {
+ "0",
+ "00",
+ "000",
+ "0000",
+ "00000",
+ "000000",
+ "0000000",
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Format the positive integer value to a string and perfix with assigned
+ // length of leading zero.
+ //
+ // Parameters:
+ // value: The value to format
+ // len: The maximum length for leading zero.
+ // If the digits of the value is greater than len, no leading zero is added.
+ //
+ // Notes:
+ // The function can format to Int32.MaxValue.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+ internal static void FormatDigits(StringBuilder outputBuffer, int value, int len)
+ {
+ Debug.Assert(value >= 0, "DateTimeFormat.FormatDigits(): value >= 0");
+ FormatDigits(outputBuffer, value, len, false);
+ }
+
+ internal unsafe static void FormatDigits(StringBuilder outputBuffer, int value, int len, bool overrideLengthLimit)
+ {
+ Debug.Assert(value >= 0, "DateTimeFormat.FormatDigits(): value >= 0");
+
+ // Limit the use of this function to be two-digits, so that we have the same behavior
+ // as RTM bits.
+ if (!overrideLengthLimit && len > 2)
+ {
+ len = 2;
+ }
+
+ char* buffer = stackalloc char[16];
+ char* p = buffer + 16;
+ int n = value;
+ do
+ {
+ *--p = (char)(n % 10 + '0');
+ n /= 10;
+ } while ((n != 0) && (p > buffer));
+
+ int digits = (int)(buffer + 16 - p);
+
+ //If the repeat count is greater than 0, we're trying
+ //to emulate the "00" format, so we have to prepend
+ //a zero if the string only has one character.
+ while ((digits < len) && (p > buffer))
+ {
+ *--p = '0';
+ digits++;
+ }
+ outputBuffer.Append(p, digits);
+ }
+
+ private static void HebrewFormatDigits(StringBuilder outputBuffer, int digits)
+ {
+ outputBuffer.Append(HebrewNumber.ToString(digits));
+ }
+
+ internal static int ParseRepeatPattern(String format, int pos, char patternChar)
+ {
+ int len = format.Length;
+ int index = pos + 1;
+ while ((index < len) && (format[index] == patternChar))
+ {
+ index++;
+ }
+ return (index - pos);
+ }
+
+ private static String FormatDayOfWeek(int dayOfWeek, int repeat, DateTimeFormatInfo dtfi)
+ {
+ Debug.Assert(dayOfWeek >= 0 && dayOfWeek <= 6, "dayOfWeek >= 0 && dayOfWeek <= 6");
+ if (repeat == 3)
+ {
+ return (dtfi.GetAbbreviatedDayName((DayOfWeek)dayOfWeek));
+ }
+ // Call dtfi.GetDayName() here, instead of accessing DayNames property, because we don't
+ // want a clone of DayNames, which will hurt perf.
+ return (dtfi.GetDayName((DayOfWeek)dayOfWeek));
+ }
+
+ private static String FormatMonth(int month, int repeatCount, DateTimeFormatInfo dtfi)
+ {
+ Debug.Assert(month >= 1 && month <= 12, "month >=1 && month <= 12");
+ if (repeatCount == 3)
+ {
+ return (dtfi.GetAbbreviatedMonthName(month));
+ }
+ // Call GetMonthName() here, instead of accessing MonthNames property, because we don't
+ // want a clone of MonthNames, which will hurt perf.
+ return (dtfi.GetMonthName(month));
+ }
+
+ //
+ // FormatHebrewMonthName
+ //
+ // Action: Return the Hebrew month name for the specified DateTime.
+ // Returns: The month name string for the specified DateTime.
+ // Arguments:
+ // time the time to format
+ // month The month is the value of HebrewCalendar.GetMonth(time).
+ // repeat Return abbreviated month name if repeat=3, or full month name if repeat=4
+ // dtfi The DateTimeFormatInfo which uses the Hebrew calendars as its calendar.
+ // Exceptions: None.
+ //
+
+ /* Note:
+ If DTFI is using Hebrew calendar, GetMonthName()/GetAbbreviatedMonthName() will return month names like this:
+ 1 Hebrew 1st Month
+ 2 Hebrew 2nd Month
+ .. ...
+ 6 Hebrew 6th Month
+ 7 Hebrew 6th Month II (used only in a leap year)
+ 8 Hebrew 7th Month
+ 9 Hebrew 8th Month
+ 10 Hebrew 9th Month
+ 11 Hebrew 10th Month
+ 12 Hebrew 11th Month
+ 13 Hebrew 12th Month
+
+ Therefore, if we are in a regular year, we have to increment the month name if moth is greater or eqaul to 7.
+ */
+ private static String FormatHebrewMonthName(DateTime time, int month, int repeatCount, DateTimeFormatInfo dtfi)
+ {
+ Debug.Assert(repeatCount != 3 || repeatCount != 4, "repeateCount should be 3 or 4");
+ if (dtfi.Calendar.IsLeapYear(dtfi.Calendar.GetYear(time)))
+ {
+ // This month is in a leap year
+ return (dtfi.internalGetMonthName(month, MonthNameStyles.LeapYear, (repeatCount == 3)));
+ }
+ // This is in a regular year.
+ if (month >= 7)
+ {
+ month++;
+ }
+ if (repeatCount == 3)
+ {
+ return (dtfi.GetAbbreviatedMonthName(month));
+ }
+ return (dtfi.GetMonthName(month));
+ }
+
+ //
+ // The pos should point to a quote character. This method will
+ // append to the result StringBuilder the string encloed by the quote character.
+ //
+ internal static int ParseQuoteString(String format, int pos, StringBuilder result)
+ {
+ //
+ // NOTE : pos will be the index of the quote character in the 'format' string.
+ //
+ int formatLen = format.Length;
+ int beginPos = pos;
+ char quoteChar = format[pos++]; // Get the character used to quote the following string.
+
+ bool foundQuote = false;
+ while (pos < formatLen)
+ {
+ char ch = format[pos++];
+ if (ch == quoteChar)
+ {
+ foundQuote = true;
+ break;
+ }
+ else if (ch == '\\')
+ {
+ // The following are used to support escaped character.
+ // Escaped character is also supported in the quoted string.
+ // Therefore, someone can use a format like "'minute:' mm\"" to display:
+ // minute: 45"
+ // because the second double quote is escaped.
+ if (pos < formatLen)
+ {
+ result.Append(format[pos++]);
+ }
+ else
+ {
+ //
+ // This means that '\' is at the end of the formatting string.
+ //
+ throw new FormatException(SR.Format_InvalidString);
+ }
+ }
+ else
+ {
+ result.Append(ch);
+ }
+ }
+
+ if (!foundQuote)
+ {
+ // Here we can't find the matching quote.
+ throw new FormatException(
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.Format_BadQuote, quoteChar));
+ }
+
+ //
+ // Return the character count including the begin/end quote characters and enclosed string.
+ //
+ return (pos - beginPos);
+ }
+
+ //
+ // Get the next character at the index of 'pos' in the 'format' string.
+ // Return value of -1 means 'pos' is already at the end of the 'format' string.
+ // Otherwise, return value is the int value of the next character.
+ //
+ internal static int ParseNextChar(String format, int pos)
+ {
+ if (pos >= format.Length - 1)
+ {
+ return (-1);
+ }
+ return ((int)format[pos + 1]);
+ }
+
+ //
+ // IsUseGenitiveForm
+ //
+ // Actions: Check the format to see if we should use genitive month in the formatting.
+ // Starting at the position (index) in the (format) string, look back and look ahead to
+ // see if there is "d" or "dd". In the case like "d MMMM" or "MMMM dd", we can use
+ // genitive form. Genitive form is not used if there is more than two "d".
+ // Arguments:
+ // format The format string to be scanned.
+ // index Where we should start the scanning. This is generally where "M" starts.
+ // tokenLen The len of the current pattern character. This indicates how many "M" that we have.
+ // patternToMatch The pattern that we want to search. This generally uses "d"
+ //
+ private static bool IsUseGenitiveForm(String format, int index, int tokenLen, char patternToMatch)
+ {
+ int i;
+ int repeat = 0;
+ //
+ // Look back to see if we can find "d" or "ddd"
+ //
+
+ // Find first "d".
+ for (i = index - 1; i >= 0 && format[i] != patternToMatch; i--) { /*Do nothing here */ };
+
+ if (i >= 0)
+ {
+ // Find a "d", so look back to see how many "d" that we can find.
+ while (--i >= 0 && format[i] == patternToMatch)
+ {
+ repeat++;
+ }
+ //
+ // repeat == 0 means that we have one (patternToMatch)
+ // repeat == 1 means that we have two (patternToMatch)
+ //
+ if (repeat <= 1)
+ {
+ return (true);
+ }
+ // Note that we can't just stop here. We may find "ddd" while looking back, and we have to look
+ // ahead to see if there is "d" or "dd".
+ }
+
+ //
+ // If we can't find "d" or "dd" by looking back, try look ahead.
+ //
+
+ // Find first "d"
+ for (i = index + tokenLen; i < format.Length && format[i] != patternToMatch; i++) { /* Do nothing here */ };
+
+ if (i < format.Length)
+ {
+ repeat = 0;
+ // Find a "d", so contine the walk to see how may "d" that we can find.
+ while (++i < format.Length && format[i] == patternToMatch)
+ {
+ repeat++;
+ }
+ //
+ // repeat == 0 means that we have one (patternToMatch)
+ // repeat == 1 means that we have two (patternToMatch)
+ //
+ if (repeat <= 1)
+ {
+ return (true);
+ }
+ }
+ return (false);
+ }
+
+
+ //
+ // FormatCustomized
+ //
+ // Actions: Format the DateTime instance using the specified format.
+ //
+ private static String FormatCustomized(DateTime dateTime, String format, DateTimeFormatInfo dtfi, TimeSpan offset)
+ {
+ Calendar cal = dtfi.Calendar;
+ StringBuilder result = StringBuilderCache.Acquire();
+ // This is a flag to indicate if we are format the dates using Hebrew calendar.
+
+ bool isHebrewCalendar = (cal.ID == CalendarId.HEBREW);
+ // This is a flag to indicate if we are formating hour/minute/second only.
+ bool bTimeOnly = true;
+
+ int i = 0;
+ int tokenLen, hour12;
+
+ while (i < format.Length)
+ {
+ char ch = format[i];
+ int nextChar;
+ switch (ch)
+ {
+ case 'g':
+ tokenLen = ParseRepeatPattern(format, i, ch);
+ result.Append(dtfi.GetEraName(cal.GetEra(dateTime)));
+ break;
+ case 'h':
+ tokenLen = ParseRepeatPattern(format, i, ch);
+ hour12 = dateTime.Hour % 12;
+ if (hour12 == 0)
+ {
+ hour12 = 12;
+ }
+ FormatDigits(result, hour12, tokenLen);
+ break;
+ case 'H':
+ tokenLen = ParseRepeatPattern(format, i, ch);
+ FormatDigits(result, dateTime.Hour, tokenLen);
+ break;
+ case 'm':
+ tokenLen = ParseRepeatPattern(format, i, ch);
+ FormatDigits(result, dateTime.Minute, tokenLen);
+ break;
+ case 's':
+ tokenLen = ParseRepeatPattern(format, i, ch);
+ FormatDigits(result, dateTime.Second, tokenLen);
+ break;
+ case 'f':
+ case 'F':
+ tokenLen = ParseRepeatPattern(format, i, ch);
+ if (tokenLen <= MaxSecondsFractionDigits)
+ {
+ long fraction = (dateTime.Ticks % Calendar.TicksPerSecond);
+ fraction = fraction / (long)Math.Pow(10, 7 - tokenLen);
+ if (ch == 'f')
+ {
+ result.Append(((int)fraction).ToString(fixedNumberFormats[tokenLen - 1], CultureInfo.InvariantCulture));
+ }
+ else
+ {
+ int effectiveDigits = tokenLen;
+ while (effectiveDigits > 0)
+ {
+ if (fraction % 10 == 0)
+ {
+ fraction = fraction / 10;
+ effectiveDigits--;
+ }
+ else
+ {
+ break;
+ }
+ }
+ if (effectiveDigits > 0)
+ {
+ result.Append(((int)fraction).ToString(fixedNumberFormats[effectiveDigits - 1], CultureInfo.InvariantCulture));
+ }
+ else
+ {
+ // No fraction to emit, so see if we should remove decimal also.
+ if (result.Length > 0 && result[result.Length - 1] == '.')
+ {
+ result.Remove(result.Length - 1, 1);
+ }
+ }
+ }
+ }
+ else
+ {
+ throw new FormatException(SR.Format_InvalidString);
+ }
+ break;
+ case 't':
+ tokenLen = ParseRepeatPattern(format, i, ch);
+ if (tokenLen == 1)
+ {
+ if (dateTime.Hour < 12)
+ {
+ if (dtfi.AMDesignator.Length >= 1)
+ {
+ result.Append(dtfi.AMDesignator[0]);
+ }
+ }
+ else
+ {
+ if (dtfi.PMDesignator.Length >= 1)
+ {
+ result.Append(dtfi.PMDesignator[0]);
+ }
+ }
+ }
+ else
+ {
+ result.Append((dateTime.Hour < 12 ? dtfi.AMDesignator : dtfi.PMDesignator));
+ }
+ break;
+ case 'd':
+ //
+ // tokenLen == 1 : Day of month as digits with no leading zero.
+ // tokenLen == 2 : Day of month as digits with leading zero for single-digit months.
+ // tokenLen == 3 : Day of week as a three-leter abbreviation.
+ // tokenLen >= 4 : Day of week as its full name.
+ //
+ tokenLen = ParseRepeatPattern(format, i, ch);
+ if (tokenLen <= 2)
+ {
+ int day = cal.GetDayOfMonth(dateTime);
+ if (isHebrewCalendar)
+ {
+ // For Hebrew calendar, we need to convert numbers to Hebrew text for yyyy, MM, and dd values.
+ HebrewFormatDigits(result, day);
+ }
+ else
+ {
+ FormatDigits(result, day, tokenLen);
+ }
+ }
+ else
+ {
+ int dayOfWeek = (int)cal.GetDayOfWeek(dateTime);
+ result.Append(FormatDayOfWeek(dayOfWeek, tokenLen, dtfi));
+ }
+ bTimeOnly = false;
+ break;
+ case 'M':
+ //
+ // tokenLen == 1 : Month as digits with no leading zero.
+ // tokenLen == 2 : Month as digits with leading zero for single-digit months.
+ // tokenLen == 3 : Month as a three-letter abbreviation.
+ // tokenLen >= 4 : Month as its full name.
+ //
+ tokenLen = ParseRepeatPattern(format, i, ch);
+ int month = cal.GetMonth(dateTime);
+ if (tokenLen <= 2)
+ {
+ if (isHebrewCalendar)
+ {
+ // For Hebrew calendar, we need to convert numbers to Hebrew text for yyyy, MM, and dd values.
+ HebrewFormatDigits(result, month);
+ }
+ else
+ {
+ FormatDigits(result, month, tokenLen);
+ }
+ }
+ else
+ {
+ if (isHebrewCalendar)
+ {
+ result.Append(FormatHebrewMonthName(dateTime, month, tokenLen, dtfi));
+ }
+ else
+ {
+ if ((dtfi.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != 0 && tokenLen >= 4)
+ {
+ result.Append(
+ dtfi.internalGetMonthName(
+ month,
+ IsUseGenitiveForm(format, i, tokenLen, 'd') ? MonthNameStyles.Genitive : MonthNameStyles.Regular,
+ false));
+ }
+ else
+ {
+ result.Append(FormatMonth(month, tokenLen, dtfi));
+ }
+ }
+ }
+ bTimeOnly = false;
+ break;
+ case 'y':
+ // Notes about OS behavior:
+ // y: Always print (year % 100). No leading zero.
+ // yy: Always print (year % 100) with leading zero.
+ // yyy/yyyy/yyyyy/... : Print year value. No leading zero.
+
+ int year = cal.GetYear(dateTime);
+ tokenLen = ParseRepeatPattern(format, i, ch);
+ if (dtfi.HasForceTwoDigitYears)
+ {
+ FormatDigits(result, year, tokenLen <= 2 ? tokenLen : 2);
+ }
+ else if (cal.ID == CalendarId.HEBREW)
+ {
+ HebrewFormatDigits(result, year);
+ }
+ else
+ {
+ if (tokenLen <= 2)
+ {
+ FormatDigits(result, year % 100, tokenLen);
+ }
+ else
+ {
+ String fmtPattern = "D" + tokenLen.ToString();
+ result.Append(year.ToString(fmtPattern, CultureInfo.InvariantCulture));
+ }
+ }
+ bTimeOnly = false;
+ break;
+ case 'z':
+ tokenLen = ParseRepeatPattern(format, i, ch);
+ FormatCustomizedTimeZone(dateTime, offset, format, tokenLen, bTimeOnly, result);
+ break;
+ case 'K':
+ tokenLen = 1;
+ FormatCustomizedRoundripTimeZone(dateTime, offset, result);
+ break;
+ case ':':
+ result.Append(dtfi.TimeSeparator);
+ tokenLen = 1;
+ break;
+ case '/':
+ result.Append(dtfi.DateSeparator);
+ tokenLen = 1;
+ break;
+ case '\'':
+ case '\"':
+ tokenLen = ParseQuoteString(format, i, result);
+ break;
+ case '%':
+ // Optional format character.
+ // For example, format string "%d" will print day of month
+ // without leading zero. Most of the cases, "%" can be ignored.
+ nextChar = ParseNextChar(format, i);
+ // nextChar will be -1 if we already reach the end of the format string.
+ // Besides, we will not allow "%%" appear in the pattern.
+ if (nextChar >= 0 && nextChar != (int)'%')
+ {
+ result.Append(FormatCustomized(dateTime, ((char)nextChar).ToString(), dtfi, offset));
+ tokenLen = 2;
+ }
+ else
+ {
+ //
+ // This means that '%' is at the end of the format string or
+ // "%%" appears in the format string.
+ //
+ throw new FormatException(SR.Format_InvalidString);
+ }
+ break;
+ case '\\':
+ // Escaped character. Can be used to insert character into the format string.
+ // For exmple, "\d" will insert the character 'd' into the string.
+ //
+ // NOTENOTE : we can remove this format character if we enforce the enforced quote
+ // character rule.
+ // That is, we ask everyone to use single quote or double quote to insert characters,
+ // then we can remove this character.
+ //
+ nextChar = ParseNextChar(format, i);
+ if (nextChar >= 0)
+ {
+ result.Append(((char)nextChar));
+ tokenLen = 2;
+ }
+ else
+ {
+ //
+ // This means that '\' is at the end of the formatting string.
+ //
+ throw new FormatException(SR.Format_InvalidString);
+ }
+ break;
+ default:
+ // NOTENOTE : we can remove this rule if we enforce the enforced quote
+ // character rule.
+ // That is, if we ask everyone to use single quote or double quote to insert characters,
+ // then we can remove this default block.
+ result.Append(ch);
+ tokenLen = 1;
+ break;
+ }
+ i += tokenLen;
+ }
+ return StringBuilderCache.GetStringAndRelease(result);
+ }
+
+
+ // output the 'z' famliy of formats, which output a the offset from UTC, e.g. "-07:30"
+ private static void FormatCustomizedTimeZone(DateTime dateTime, TimeSpan offset, String format, Int32 tokenLen, Boolean timeOnly, StringBuilder result)
+ {
+ // See if the instance already has an offset
+ Boolean dateTimeFormat = (offset == NullOffset);
+ if (dateTimeFormat)
+ {
+ // No offset. The instance is a DateTime and the output should be the local time zone
+
+ if (timeOnly && dateTime.Ticks < Calendar.TicksPerDay)
+ {
+ // For time only format and a time only input, the time offset on 0001/01/01 is less
+ // accurate than the system's current offset because of daylight saving time.
+ offset = TimeZoneInfo.GetLocalUtcOffset(DateTime.Now, TimeZoneInfoOptions.NoThrowOnInvalidTime);
+ }
+ else if (dateTime.Kind == DateTimeKind.Utc)
+ {
+ offset = TimeSpan.Zero;
+ }
+ else
+ {
+ offset = TimeZoneInfo.GetLocalUtcOffset(dateTime, TimeZoneInfoOptions.NoThrowOnInvalidTime);
+ }
+ }
+ if (offset >= TimeSpan.Zero)
+ {
+ result.Append('+');
+ }
+ else
+ {
+ result.Append('-');
+ // get a positive offset, so that you don't need a separate code path for the negative numbers.
+ offset = offset.Negate();
+ }
+
+ if (tokenLen <= 1)
+ {
+ // 'z' format e.g "-7"
+ result.AppendFormat(CultureInfo.InvariantCulture, "{0:0}", offset.Hours);
+ }
+ else
+ {
+ // 'zz' or longer format e.g "-07"
+ result.AppendFormat(CultureInfo.InvariantCulture, "{0:00}", offset.Hours);
+ if (tokenLen >= 3)
+ {
+ // 'zzz*' or longer format e.g "-07:30"
+ result.AppendFormat(CultureInfo.InvariantCulture, ":{0:00}", offset.Minutes);
+ }
+ }
+ }
+
+ // output the 'K' format, which is for round-tripping the data
+ private static void FormatCustomizedRoundripTimeZone(DateTime dateTime, TimeSpan offset, StringBuilder result)
+ {
+ // The objective of this format is to round trip the data in the type
+ // For DateTime it should round-trip the Kind value and preserve the time zone.
+ // DateTimeOffset instance, it should do so by using the internal time zone.
+
+ if (offset == NullOffset)
+ {
+ // source is a date time, so behavior depends on the kind.
+ switch (dateTime.Kind)
+ {
+ case DateTimeKind.Local:
+ // This should output the local offset, e.g. "-07:30"
+ offset = TimeZoneInfo.GetLocalUtcOffset(dateTime, TimeZoneInfoOptions.NoThrowOnInvalidTime);
+ // fall through to shared time zone output code
+ break;
+ case DateTimeKind.Utc:
+ // The 'Z' constant is a marker for a UTC date
+ result.Append("Z");
+ return;
+ default:
+ // If the kind is unspecified, we output nothing here
+ return;
+ }
+ }
+ if (offset >= TimeSpan.Zero)
+ {
+ result.Append('+');
+ }
+ else
+ {
+ result.Append('-');
+ // get a positive offset, so that you don't need a separate code path for the negative numbers.
+ offset = offset.Negate();
+ }
+
+ AppendNumber(result, offset.Hours, 2);
+ result.Append(':');
+ AppendNumber(result, offset.Minutes, 2);
+ }
+
+
+ internal static String GetRealFormat(String format, DateTimeFormatInfo dtfi)
+ {
+ String realFormat = null;
+
+ switch (format[0])
+ {
+ case 'd': // Short Date
+ realFormat = dtfi.ShortDatePattern;
+ break;
+ case 'D': // Long Date
+ realFormat = dtfi.LongDatePattern;
+ break;
+ case 'f': // Full (long date + short time)
+ realFormat = dtfi.LongDatePattern + " " + dtfi.ShortTimePattern;
+ break;
+ case 'F': // Full (long date + long time)
+ realFormat = dtfi.FullDateTimePattern;
+ break;
+ case 'g': // General (short date + short time)
+ realFormat = dtfi.GeneralShortTimePattern;
+ break;
+ case 'G': // General (short date + long time)
+ realFormat = dtfi.GeneralLongTimePattern;
+ break;
+ case 'm':
+ case 'M': // Month/Day Date
+ realFormat = dtfi.MonthDayPattern;
+ break;
+ case 'o':
+ case 'O':
+ realFormat = RoundtripFormat;
+ break;
+ case 'r':
+ case 'R': // RFC 1123 Standard
+ realFormat = dtfi.RFC1123Pattern;
+ break;
+ case 's': // Sortable without Time Zone Info
+ realFormat = dtfi.SortableDateTimePattern;
+ break;
+ case 't': // Short Time
+ realFormat = dtfi.ShortTimePattern;
+ break;
+ case 'T': // Long Time
+ realFormat = dtfi.LongTimePattern;
+ break;
+ case 'u': // Universal with Sortable format
+ realFormat = dtfi.UniversalSortableDateTimePattern;
+ break;
+ case 'U': // Universal with Full (long date + long time) format
+ realFormat = dtfi.FullDateTimePattern;
+ break;
+ case 'y':
+ case 'Y': // Year/Month Date
+ realFormat = dtfi.YearMonthPattern;
+ break;
+ default:
+ throw new FormatException(SR.Format_InvalidString);
+ }
+ return (realFormat);
+ }
+
+
+ // Expand a pre-defined format string (like "D" for long date) to the real format that
+ // we are going to use in the date time parsing.
+ // This method also convert the dateTime if necessary (e.g. when the format is in Universal time),
+ // and change dtfi if necessary (e.g. when the format should use invariant culture).
+ //
+ private static String ExpandPredefinedFormat(String format, ref DateTime dateTime, ref DateTimeFormatInfo dtfi, ref TimeSpan offset)
+ {
+ switch (format[0])
+ {
+ case 'o':
+ case 'O': // Round trip format
+ dtfi = DateTimeFormatInfo.InvariantInfo;
+ break;
+ case 'r':
+ case 'R': // RFC 1123 Standard
+ if (offset != NullOffset)
+ {
+ // Convert to UTC invariants mean this will be in range
+ dateTime = dateTime - offset;
+ }
+ else if (dateTime.Kind == DateTimeKind.Local)
+ {
+ InvalidFormatForLocal(format, dateTime);
+ }
+ dtfi = DateTimeFormatInfo.InvariantInfo;
+ break;
+ case 's': // Sortable without Time Zone Info
+ dtfi = DateTimeFormatInfo.InvariantInfo;
+ break;
+ case 'u': // Universal time in sortable format.
+ if (offset != NullOffset)
+ {
+ // Convert to UTC invariants mean this will be in range
+ dateTime = dateTime - offset;
+ }
+ else if (dateTime.Kind == DateTimeKind.Local)
+ {
+ InvalidFormatForLocal(format, dateTime);
+ }
+ dtfi = DateTimeFormatInfo.InvariantInfo;
+ break;
+ case 'U': // Universal time in culture dependent format.
+ if (offset != NullOffset)
+ {
+ // This format is not supported by DateTimeOffset
+ throw new FormatException(SR.Format_InvalidString);
+ }
+ // Universal time is always in Greogrian calendar.
+ //
+ // Change the Calendar to be Gregorian Calendar.
+ //
+ dtfi = (DateTimeFormatInfo)dtfi.Clone();
+ if (dtfi.Calendar.GetType() != typeof(GregorianCalendar))
+ {
+ dtfi.Calendar = GregorianCalendar.GetDefaultInstance();
+ }
+ dateTime = dateTime.ToUniversalTime();
+ break;
+ }
+ format = GetRealFormat(format, dtfi);
+ return (format);
+ }
+
+ internal static String Format(DateTime dateTime, String format, DateTimeFormatInfo dtfi)
+ {
+ return Format(dateTime, format, dtfi, NullOffset);
+ }
+
+
+ internal static String Format(DateTime dateTime, String format, DateTimeFormatInfo dtfi, TimeSpan offset)
+ {
+ Contract.Requires(dtfi != null);
+ if (format == null || format.Length == 0)
+ {
+ Boolean timeOnlySpecialCase = false;
+ if (dateTime.Ticks < Calendar.TicksPerDay)
+ {
+ // If the time is less than 1 day, consider it as time of day.
+ // Just print out the short time format.
+ //
+ // This is a workaround for VB, since they use ticks less then one day to be
+ // time of day. In cultures which use calendar other than Gregorian calendar, these
+ // alternative calendar may not support ticks less than a day.
+ // For example, Japanese calendar only supports date after 1868/9/8.
+ // This will pose a problem when people in VB get the time of day, and use it
+ // to call ToString(), which will use the general format (short date + long time).
+ // Since Japanese calendar does not support Gregorian year 0001, an exception will be
+ // thrown when we try to get the Japanese year for Gregorian year 0001.
+ // Therefore, the workaround allows them to call ToString() for time of day from a DateTime by
+ // formatting as ISO 8601 format.
+ switch (dtfi.Calendar.ID)
+ {
+ case CalendarId.JAPAN:
+ case CalendarId.TAIWAN:
+ case CalendarId.HIJRI:
+ case CalendarId.HEBREW:
+ case CalendarId.JULIAN:
+ case CalendarId.UMALQURA:
+ case CalendarId.PERSIAN:
+ timeOnlySpecialCase = true;
+ dtfi = DateTimeFormatInfo.InvariantInfo;
+ break;
+ }
+ }
+ if (offset == NullOffset)
+ {
+ // Default DateTime.ToString case.
+ if (timeOnlySpecialCase)
+ {
+ format = "s";
+ }
+ else
+ {
+ format = "G";
+ }
+ }
+ else
+ {
+ // Default DateTimeOffset.ToString case.
+ if (timeOnlySpecialCase)
+ {
+ format = RoundtripDateTimeUnfixed;
+ }
+ else
+ {
+ format = dtfi.DateTimeOffsetPattern;
+ }
+ }
+ }
+
+ if (format.Length == 1)
+ {
+ switch (format[0])
+ {
+ case 'O':
+ case 'o':
+ return FastFormatRoundtrip(dateTime, offset);
+ case 'R':
+ case 'r':
+ return FastFormatRfc1123(dateTime, offset, dtfi);
+ }
+
+ format = ExpandPredefinedFormat(format, ref dateTime, ref dtfi, ref offset);
+ }
+
+ return (FormatCustomized(dateTime, format, dtfi, offset));
+ }
+
+ internal static string FastFormatRfc1123(DateTime dateTime, TimeSpan offset, DateTimeFormatInfo dtfi)
+ {
+ // ddd, dd MMM yyyy HH:mm:ss GMT
+ const int Rfc1123FormatLength = 29;
+ StringBuilder result = StringBuilderCache.Acquire(Rfc1123FormatLength);
+
+ if (offset != NullOffset)
+ {
+ // Convert to UTC invariants
+ dateTime = dateTime - offset;
+ }
+
+ result.Append(InvariantAbbreviatedDayNames[(int)dateTime.DayOfWeek]);
+ result.Append(',');
+ result.Append(' ');
+ AppendNumber(result, dateTime.Day, 2);
+ result.Append(' ');
+ result.Append(InvariantAbbreviatedMonthNames[dateTime.Month - 1]);
+ result.Append(' ');
+ AppendNumber(result, dateTime.Year, 4);
+ result.Append(' ');
+ AppendHHmmssTimeOfDay(result, dateTime);
+ result.Append(' ');
+ result.Append(Gmt);
+
+ return StringBuilderCache.GetStringAndRelease(result);
+ }
+
+ internal static string FastFormatRoundtrip(DateTime dateTime, TimeSpan offset)
+ {
+ // yyyy-MM-ddTHH:mm:ss.fffffffK
+ const int roundTripFormatLength = 28;
+ StringBuilder result = StringBuilderCache.Acquire(roundTripFormatLength);
+
+ AppendNumber(result, dateTime.Year, 4);
+ result.Append('-');
+ AppendNumber(result, dateTime.Month, 2);
+ result.Append('-');
+ AppendNumber(result, dateTime.Day, 2);
+ result.Append('T');
+ AppendHHmmssTimeOfDay(result, dateTime);
+ result.Append('.');
+
+ long fraction = dateTime.Ticks % TimeSpan.TicksPerSecond;
+ AppendNumber(result, fraction, 7);
+
+ FormatCustomizedRoundripTimeZone(dateTime, offset, result);
+
+ return StringBuilderCache.GetStringAndRelease(result);
+ }
+
+ private static void AppendHHmmssTimeOfDay(StringBuilder result, DateTime dateTime)
+ {
+ // HH:mm:ss
+ AppendNumber(result, dateTime.Hour, 2);
+ result.Append(':');
+ AppendNumber(result, dateTime.Minute, 2);
+ result.Append(':');
+ AppendNumber(result, dateTime.Second, 2);
+ }
+
+ internal static void AppendNumber(StringBuilder builder, long val, int digits)
+ {
+ for (int i = 0; i < digits; i++)
+ {
+ builder.Append('0');
+ }
+
+ int index = 1;
+ while (val > 0 && index <= digits)
+ {
+ builder[builder.Length - index] = (char)('0' + (val % 10));
+ val = val / 10;
+ index++;
+ }
+
+ Debug.Assert(val == 0, "DateTimeFormat.AppendNumber(): digits less than size of val");
+ }
+
+ internal static String[] GetAllDateTimes(DateTime dateTime, char format, DateTimeFormatInfo dtfi)
+ {
+ Contract.Requires(dtfi != null);
+ String[] allFormats = null;
+ String[] results = null;
+
+ switch (format)
+ {
+ case 'd':
+ case 'D':
+ case 'f':
+ case 'F':
+ case 'g':
+ case 'G':
+ case 'm':
+ case 'M':
+ case 't':
+ case 'T':
+ case 'y':
+ case 'Y':
+ allFormats = dtfi.GetAllDateTimePatterns(format);
+ results = new String[allFormats.Length];
+ for (int i = 0; i < allFormats.Length; i++)
+ {
+ results[i] = Format(dateTime, allFormats[i], dtfi);
+ }
+ break;
+ case 'U':
+ DateTime universalTime = dateTime.ToUniversalTime();
+ allFormats = dtfi.GetAllDateTimePatterns(format);
+ results = new String[allFormats.Length];
+ for (int i = 0; i < allFormats.Length; i++)
+ {
+ results[i] = Format(universalTime, allFormats[i], dtfi);
+ }
+ break;
+ //
+ // The following ones are special cases because these patterns are read-only in
+ // DateTimeFormatInfo.
+ //
+ case 'r':
+ case 'R':
+ case 'o':
+ case 'O':
+ case 's':
+ case 'u':
+ results = new String[] { Format(dateTime, new String(format, 1), dtfi) };
+ break;
+ default:
+ throw new FormatException(SR.Format_InvalidString);
+ }
+ return (results);
+ }
+
+ internal static String[] GetAllDateTimes(DateTime dateTime, DateTimeFormatInfo dtfi)
+ {
+ List<String> results = new List<String>(DEFAULT_ALL_DATETIMES_SIZE);
+
+ for (int i = 0; i < allStandardFormats.Length; i++)
+ {
+ String[] strings = GetAllDateTimes(dateTime, allStandardFormats[i], dtfi);
+ for (int j = 0; j < strings.Length; j++)
+ {
+ results.Add(strings[j]);
+ }
+ }
+ String[] value = new String[results.Count];
+ results.CopyTo(0, value, 0, results.Count);
+ return (value);
+ }
+
+ // This is a placeholder for an MDA to detect when the user is using a
+ // local DateTime with a format that will be interpreted as UTC.
+ internal static void InvalidFormatForLocal(String format, DateTime dateTime)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/DateTimeFormatInfo.cs b/src/mscorlib/shared/System/Globalization/DateTimeFormatInfo.cs
new file mode 100644
index 0000000000..d3f1ea9a45
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/DateTimeFormatInfo.cs
@@ -0,0 +1,3028 @@
+// 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.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+
+namespace System.Globalization
+{
+ //
+ // Flags used to indicate different styles of month names.
+ // This is an internal flag used by internalGetMonthName().
+ // Use flag here in case that we need to provide a combination of these styles
+ // (such as month name of a leap year in genitive form. Not likely for now,
+ // but would like to keep the option open).
+ //
+
+ [Flags]
+ internal enum MonthNameStyles
+ {
+ Regular = 0x00000000,
+ Genitive = 0x00000001,
+ LeapYear = 0x00000002,
+ }
+
+ //
+ // Flags used to indicate special rule used in parsing/formatting
+ // for a specific DateTimeFormatInfo instance.
+ // This is an internal flag.
+ //
+ // This flag is different from MonthNameStyles because this flag
+ // can be expanded to accomodate parsing behaviors like CJK month names
+ // or alternative month names, etc.
+
+ [Flags]
+ internal enum DateTimeFormatFlags
+ {
+ None = 0x00000000,
+ UseGenitiveMonth = 0x00000001,
+ UseLeapYearMonth = 0x00000002,
+ UseSpacesInMonthNames = 0x00000004, // Has spaces or non-breaking space in the month names.
+ UseHebrewRule = 0x00000008, // Format/Parse using the Hebrew calendar rule.
+ UseSpacesInDayNames = 0x00000010, // Has spaces or non-breaking space in the day names.
+ UseDigitPrefixInTokens = 0x00000020, // Has token starting with numbers.
+
+ NotInitialized = -1,
+ }
+
+
+ [Serializable]
+ public sealed class DateTimeFormatInfo : IFormatProvider, ICloneable
+ {
+ // cache for the invariant culture.
+ // invariantInfo is constant irrespective of your current culture.
+ private static volatile DateTimeFormatInfo s_invariantInfo;
+
+ // an index which points to a record in Culture Data Table.
+ [NonSerialized]
+ private CultureData _cultureData;
+
+ // The culture name used to create this DTFI.
+
+ [OptionalField(VersionAdded = 2)]
+ private String _name = null;
+
+ // The language name of the culture used to create this DTFI.
+ [NonSerialized]
+ private String _langName = null;
+
+ // CompareInfo usually used by the parser.
+ [NonSerialized]
+ private CompareInfo _compareInfo = null;
+
+ // Culture matches current DTFI. mainly used for string comparisons during parsing.
+ [NonSerialized]
+ private CultureInfo _cultureInfo = null;
+
+ //
+ // Caches for various properties.
+ //
+
+ private String amDesignator = null;
+ private String pmDesignator = null;
+
+ private String dateSeparator = null; // derived from short date (whidbey expects, arrowhead doesn't)
+
+ private String generalShortTimePattern = null; // short date + short time (whidbey expects, arrowhead doesn't)
+
+ private String generalLongTimePattern = null; // short date + long time (whidbey expects, arrowhead doesn't)
+
+ private String timeSeparator = null; // derived from long time (whidbey expects, arrowhead doesn't)
+ private String monthDayPattern = null;
+ // added in .NET Framework Release {2.0SP1/3.0SP1/3.5RTM}
+ private String dateTimeOffsetPattern = null;
+
+ //
+ // The following are constant values.
+ //
+ private const String rfc1123Pattern = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'";
+
+ // The sortable pattern is based on ISO 8601.
+ private const String sortableDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss";
+ private const String universalSortableDateTimePattern = "yyyy'-'MM'-'dd HH':'mm':'ss'Z'";
+
+ //
+ // The following are affected by calendar settings.
+ //
+ private Calendar calendar = null;
+
+ private int firstDayOfWeek = -1;
+ private int calendarWeekRule = -1;
+
+
+ private String fullDateTimePattern = null; // long date + long time (whidbey expects, arrowhead doesn't)
+
+ private String[] abbreviatedDayNames = null;
+
+
+ private String[] m_superShortDayNames = null;
+
+ private String[] dayNames = null;
+ private String[] abbreviatedMonthNames = null;
+ private String[] monthNames = null;
+ // Cache the genitive month names that we retrieve from the data table.
+
+ private String[] genitiveMonthNames = null;
+
+ // Cache the abbreviated genitive month names that we retrieve from the data table.
+
+ private String[] m_genitiveAbbreviatedMonthNames = null;
+
+ // Cache the month names of a leap year that we retrieve from the data table.
+
+ private String[] leapYearMonthNames = null;
+
+ // For our "patterns" arrays we have 2 variables, a string and a string[]
+ //
+ // The string[] contains the list of patterns, EXCEPT the default may not be included.
+ // The string contains the default pattern.
+ // When we initially construct our string[], we set the string to string[0]
+
+ // The "default" Date/time patterns
+ private String longDatePattern = null;
+ private String shortDatePattern = null;
+ private String yearMonthPattern = null;
+ private String longTimePattern = null;
+ private String shortTimePattern = null;
+
+ [OptionalField(VersionAdded = 3)]
+ private String[] allYearMonthPatterns = null;
+
+ private String[] allShortDatePatterns = null;
+ private String[] allLongDatePatterns = null;
+ private String[] allShortTimePatterns = null;
+ private String[] allLongTimePatterns = null;
+
+ // Cache the era names for this DateTimeFormatInfo instance.
+ private String[] m_eraNames = null;
+ private String[] m_abbrevEraNames = null;
+ private String[] m_abbrevEnglishEraNames = null;
+
+ private CalendarId[] optionalCalendars = null;
+
+ private const int DEFAULT_ALL_DATETIMES_SIZE = 132;
+
+ // CultureInfo updates this
+ internal bool _isReadOnly = false;
+
+ // This flag gives hints about if formatting/parsing should perform special code path for things like
+ // genitive form or leap year month names.
+
+ private DateTimeFormatFlags formatFlags = DateTimeFormatFlags.NotInitialized;
+
+ private String CultureName
+ {
+ get
+ {
+ if (_name == null)
+ {
+ _name = _cultureData.CultureName;
+ }
+ return (_name);
+ }
+ }
+
+ private CultureInfo Culture
+ {
+ get
+ {
+ if (_cultureInfo == null)
+ {
+ _cultureInfo = CultureInfo.GetCultureInfo(this.CultureName);
+ }
+ return _cultureInfo;
+ }
+ }
+
+ // TODO: This ignores other cultures that might want to do something similar
+ private String LanguageName
+ {
+ get
+ {
+ if (_langName == null)
+ {
+ _langName = _cultureData.SISO639LANGNAME;
+ }
+ return (_langName);
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Create an array of string which contains the abbreviated day names.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ private String[] internalGetAbbreviatedDayOfWeekNames()
+ {
+ if (this.abbreviatedDayNames == null)
+ {
+ // Get the abbreviated day names for our current calendar
+ this.abbreviatedDayNames = _cultureData.AbbreviatedDayNames(Calendar.ID);
+ Debug.Assert(this.abbreviatedDayNames.Length == 7, "[DateTimeFormatInfo.GetAbbreviatedDayOfWeekNames] Expected 7 day names in a week");
+ }
+ return (this.abbreviatedDayNames);
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Action: Returns the string array of the one-letter day of week names.
+ // Returns:
+ // an array of one-letter day of week names
+ // Arguments:
+ // None
+ // Exceptions:
+ // None
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ private String[] internalGetSuperShortDayNames()
+ {
+ if (this.m_superShortDayNames == null)
+ {
+ // Get the super short day names for our current calendar
+ this.m_superShortDayNames = _cultureData.SuperShortDayNames(Calendar.ID);
+ Debug.Assert(this.m_superShortDayNames.Length == 7, "[DateTimeFormatInfo.internalGetSuperShortDayNames] Expected 7 day names in a week");
+ }
+ return (this.m_superShortDayNames);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Create an array of string which contains the day names.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ private String[] internalGetDayOfWeekNames()
+ {
+ if (this.dayNames == null)
+ {
+ // Get the day names for our current calendar
+ this.dayNames = _cultureData.DayNames(Calendar.ID);
+ Debug.Assert(this.dayNames.Length == 7, "[DateTimeFormatInfo.GetDayOfWeekNames] Expected 7 day names in a week");
+ }
+ return (this.dayNames);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Create an array of string which contains the abbreviated month names.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ private String[] internalGetAbbreviatedMonthNames()
+ {
+ if (this.abbreviatedMonthNames == null)
+ {
+ // Get the month names for our current calendar
+ this.abbreviatedMonthNames = _cultureData.AbbreviatedMonthNames(Calendar.ID);
+ Debug.Assert(this.abbreviatedMonthNames.Length == 12 || this.abbreviatedMonthNames.Length == 13,
+ "[DateTimeFormatInfo.GetAbbreviatedMonthNames] Expected 12 or 13 month names in a year");
+ }
+ return (this.abbreviatedMonthNames);
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Create an array of string which contains the month names.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ private String[] internalGetMonthNames()
+ {
+ if (this.monthNames == null)
+ {
+ // Get the month names for our current calendar
+ this.monthNames = _cultureData.MonthNames(Calendar.ID);
+ Debug.Assert(this.monthNames.Length == 12 || this.monthNames.Length == 13,
+ "[DateTimeFormatInfo.GetMonthNames] Expected 12 or 13 month names in a year");
+ }
+
+ return (this.monthNames);
+ }
+
+
+ //
+ // Invariant DateTimeFormatInfo doesn't have user-overriden values
+ // Default calendar is gregorian
+ public DateTimeFormatInfo()
+ : this(CultureInfo.InvariantCulture._cultureData, GregorianCalendar.GetDefaultInstance())
+ {
+ }
+
+ internal DateTimeFormatInfo(CultureData cultureData, Calendar cal)
+ {
+ Debug.Assert(cultureData != null);
+ Debug.Assert(cal != null);
+
+ // Remember our culture
+ _cultureData = cultureData;
+
+ this.Calendar = cal;
+ }
+
+ private void InitializeOverridableProperties(CultureData cultureData, CalendarId calendarId)
+ {
+ Debug.Assert(cultureData != null);
+ Debug.Assert(calendarId != CalendarId.UNINITIALIZED_VALUE, "[DateTimeFormatInfo.Populate] Expected initalized calendarId");
+
+ if (this.firstDayOfWeek == -1) { this.firstDayOfWeek = cultureData.IFIRSTDAYOFWEEK; }
+ if (this.calendarWeekRule == -1) { this.calendarWeekRule = cultureData.IFIRSTWEEKOFYEAR; }
+
+ if (this.amDesignator == null) { this.amDesignator = cultureData.SAM1159; }
+ if (this.pmDesignator == null) { this.pmDesignator = cultureData.SPM2359; }
+ if (this.timeSeparator == null) { this.timeSeparator = cultureData.TimeSeparator; }
+ if (this.dateSeparator == null) { this.dateSeparator = cultureData.DateSeparator(calendarId); }
+
+ this.allLongTimePatterns = _cultureData.LongTimes;
+ Debug.Assert(this.allLongTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long time patterns");
+
+ this.allShortTimePatterns = _cultureData.ShortTimes;
+ Debug.Assert(this.allShortTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short time patterns");
+
+ this.allLongDatePatterns = cultureData.LongDates(calendarId);
+ Debug.Assert(this.allLongDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long date patterns");
+
+ this.allShortDatePatterns = cultureData.ShortDates(calendarId);
+ Debug.Assert(this.allShortDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short date patterns");
+
+ this.allYearMonthPatterns = cultureData.YearMonths(calendarId);
+ Debug.Assert(this.allYearMonthPatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some year month patterns");
+ }
+
+ [OptionalField(VersionAdded = 1)]
+ private bool _useUserOverride;
+
+ // This was synthesized by Whidbey so we knew what words might appear in the middle of a date string
+ // Now we always synthesize so its not helpful
+
+ internal String[] m_dateWords = null;
+
+ [OnSerializing]
+ private void OnSerializing(StreamingContext ctx)
+ {
+ _name = this.CultureName; // make sure the _name is initialized.
+ _useUserOverride = _cultureData.UseUserOverride;
+
+ // Important to initialize these fields otherwise we may run into exception when deserializing on Whidbey
+ // because Whidbey try to initialize some of these fields using calendar data which could be null values
+ // and then we get exceptions. So we call the accessors to force the caches to get loaded.
+ Object o;
+ o = this.LongTimePattern;
+ o = this.LongDatePattern;
+ o = this.ShortTimePattern;
+ o = this.ShortDatePattern;
+ o = this.YearMonthPattern;
+ o = this.AllLongTimePatterns;
+ o = this.AllLongDatePatterns;
+ o = this.AllShortTimePatterns;
+ o = this.AllShortDatePatterns;
+ o = this.AllYearMonthPatterns;
+ }
+
+ [OnDeserialized]
+ private void OnDeserialized(StreamingContext ctx)
+ {
+ if (_name != null)
+ {
+ _cultureData = CultureData.GetCultureData(_name, _useUserOverride);
+ if (_cultureData == null)
+ {
+ throw new CultureNotFoundException("_name", _name, SR.Argument_CultureNotSupported);
+ }
+ }
+
+ if (calendar == null)
+ {
+ calendar = (Calendar)GregorianCalendar.GetDefaultInstance().Clone();
+ calendar.SetReadOnlyState(_isReadOnly);
+ }
+
+ InitializeOverridableProperties(_cultureData, calendar.ID);
+
+ //
+ // turn off read only state till we finish initializing all fields and then store read only state after we are done.
+ //
+ bool isReadOnly = _isReadOnly;
+ _isReadOnly = false;
+
+ // If we deserialized defaults ala Whidbey, make sure they're still defaults
+ // Whidbey's arrays could get a bit mixed up.
+ if (longDatePattern != null) this.LongDatePattern = longDatePattern;
+ if (shortDatePattern != null) this.ShortDatePattern = shortDatePattern;
+ if (yearMonthPattern != null) this.YearMonthPattern = yearMonthPattern;
+ if (longTimePattern != null) this.LongTimePattern = longTimePattern;
+ if (shortTimePattern != null) this.ShortTimePattern = shortTimePattern;
+
+ _isReadOnly = isReadOnly;
+ }
+
+ // Returns a default DateTimeFormatInfo that will be universally
+ // supported and constant irrespective of the current culture.
+ // Used by FromString methods.
+ //
+
+ public static DateTimeFormatInfo InvariantInfo
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<DateTimeFormatInfo>() != null);
+ if (s_invariantInfo == null)
+ {
+ DateTimeFormatInfo info = new DateTimeFormatInfo();
+ info.Calendar.SetReadOnlyState(true);
+ info._isReadOnly = true;
+ s_invariantInfo = info;
+ }
+ return (s_invariantInfo);
+ }
+ }
+
+ // Returns the current culture's DateTimeFormatInfo. Used by Parse methods.
+ //
+
+ public static DateTimeFormatInfo CurrentInfo
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<DateTimeFormatInfo>() != null);
+ System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CurrentCulture;
+ if (!culture._isInherited)
+ {
+ DateTimeFormatInfo info = culture.dateTimeInfo;
+ if (info != null)
+ {
+ return info;
+ }
+ }
+ return (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo));
+ }
+ }
+
+
+ public static DateTimeFormatInfo GetInstance(IFormatProvider provider)
+ {
+ // Fast case for a regular CultureInfo
+ DateTimeFormatInfo info;
+ CultureInfo cultureProvider = provider as CultureInfo;
+ if (cultureProvider != null && !cultureProvider._isInherited)
+ {
+ return cultureProvider.DateTimeFormat;
+ }
+ // Fast case for a DTFI;
+ info = provider as DateTimeFormatInfo;
+ if (info != null)
+ {
+ return info;
+ }
+ // Wasn't cultureInfo or DTFI, do it the slower way
+ if (provider != null)
+ {
+ info = provider.GetFormat(typeof(DateTimeFormatInfo)) as DateTimeFormatInfo;
+ if (info != null)
+ {
+ return info;
+ }
+ }
+ // Couldn't get anything, just use currentInfo as fallback
+ return CurrentInfo;
+ }
+
+
+ public Object GetFormat(Type formatType)
+ {
+ return (formatType == typeof(DateTimeFormatInfo) ? this : null);
+ }
+
+
+ public Object Clone()
+ {
+ DateTimeFormatInfo n = (DateTimeFormatInfo)MemberwiseClone();
+ // We can use the data member calendar in the setter, instead of the property Calendar,
+ // since the cloned copy should have the same state as the original copy.
+ n.calendar = (Calendar)this.Calendar.Clone();
+ n._isReadOnly = false;
+ return n;
+ }
+
+
+ public String AMDesignator
+ {
+ get
+ {
+ if (this.amDesignator == null)
+ {
+ this.amDesignator = _cultureData.SAM1159;
+ }
+ Debug.Assert(this.amDesignator != null, "DateTimeFormatInfo.AMDesignator, amDesignator != null");
+ return (this.amDesignator);
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_String);
+ }
+ Contract.EndContractBlock();
+ ClearTokenHashTable();
+ amDesignator = value;
+ }
+ }
+
+
+ public Calendar Calendar
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<Calendar>() != null);
+
+ Debug.Assert(this.calendar != null, "DateTimeFormatInfo.Calendar: calendar != null");
+ return (this.calendar);
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value), SR.ArgumentNull_Obj);
+ }
+ Contract.EndContractBlock();
+ if (value == calendar)
+ {
+ return;
+ }
+
+ for (int i = 0; i < this.OptionalCalendars.Length; i++)
+ {
+ if (this.OptionalCalendars[i] == value.ID)
+ {
+ // We can use this one, so do so.
+
+ // Clean related properties if we already had a calendar set
+ if (calendar != null)
+ {
+ // clean related properties which are affected by the calendar setting,
+ // so that they will be refreshed when they are accessed next time.
+ //
+
+ // These properites are in the order as appearing in calendar.xml.
+ m_eraNames = null;
+ m_abbrevEraNames = null;
+ m_abbrevEnglishEraNames = null;
+
+ monthDayPattern = null;
+
+ dayNames = null;
+ abbreviatedDayNames = null;
+ m_superShortDayNames = null;
+ monthNames = null;
+ abbreviatedMonthNames = null;
+ genitiveMonthNames = null;
+ m_genitiveAbbreviatedMonthNames = null;
+ leapYearMonthNames = null;
+ formatFlags = DateTimeFormatFlags.NotInitialized;
+
+ allShortDatePatterns = null;
+ allLongDatePatterns = null;
+ allYearMonthPatterns = null;
+ dateTimeOffsetPattern = null;
+
+ // The defaults need reset as well:
+ longDatePattern = null;
+ shortDatePattern = null;
+ yearMonthPattern = null;
+
+ // These properies are not in the OS data, but they are dependent on the values like shortDatePattern.
+ fullDateTimePattern = null; // Long date + long time
+ generalShortTimePattern = null; // short date + short time
+ generalLongTimePattern = null; // short date + long time
+
+ // Derived item that changes
+ dateSeparator = null;
+
+ // We don't need to do these because they are not changed by changing calendar
+ // amDesignator
+ // pmDesignator
+ // timeSeparator
+ // longTimePattern
+ // firstDayOfWeek
+ // calendarWeekRule
+
+ // remember to reload tokens
+ ClearTokenHashTable();
+ }
+
+ // Remember the new calendar
+ calendar = value;
+ InitializeOverridableProperties(_cultureData, calendar.ID);
+
+ // We succeeded, return
+ return;
+ }
+ }
+
+ // The assigned calendar is not a valid calendar for this culture, throw
+ throw new ArgumentOutOfRangeException(nameof(value), SR.Argument_InvalidCalendar);
+ }
+ }
+
+ private CalendarId[] OptionalCalendars
+ {
+ get
+ {
+ if (this.optionalCalendars == null)
+ {
+ this.optionalCalendars = _cultureData.CalendarIds;
+ }
+ return (this.optionalCalendars);
+ }
+ }
+
+ /*=================================GetEra==========================
+ **Action: Get the era value by parsing the name of the era.
+ **Returns: The era value for the specified era name.
+ ** -1 if the name of the era is not valid or not supported.
+ **Arguments: eraName the name of the era.
+ **Exceptions: None.
+ ============================================================================*/
+
+
+ public int GetEra(String eraName)
+ {
+ if (eraName == null)
+ {
+ throw new ArgumentNullException(nameof(eraName),
+ SR.ArgumentNull_String);
+ }
+ Contract.EndContractBlock();
+
+ // The Era Name and Abbreviated Era Name
+ // for Taiwan Calendar on non-Taiwan SKU returns empty string (which
+ // would be matched below) but we don't want the empty string to give
+ // us an Era number
+ // confer 85900 DTFI.GetEra("") should fail on all cultures
+ if (eraName.Length == 0)
+ {
+ return (-1);
+ }
+
+ // The following is based on the assumption that the era value is starting from 1, and has a
+ // serial values.
+ // If that ever changes, the code has to be changed.
+
+ // The calls to String.Compare should use the current culture for the string comparisons, but the
+ // invariant culture when comparing against the english names.
+ for (int i = 0; i < EraNames.Length; i++)
+ {
+ // Compare the era name in a case-insensitive way for the appropriate culture.
+ if (m_eraNames[i].Length > 0)
+ {
+ if (this.Culture.CompareInfo.Compare(eraName, m_eraNames[i], CompareOptions.IgnoreCase) == 0)
+ {
+ return (i + 1);
+ }
+ }
+ }
+ for (int i = 0; i < AbbreviatedEraNames.Length; i++)
+ {
+ // Compare the abbreviated era name in a case-insensitive way for the appropriate culture.
+ if (this.Culture.CompareInfo.Compare(eraName, m_abbrevEraNames[i], CompareOptions.IgnoreCase) == 0)
+ {
+ return (i + 1);
+ }
+ }
+ for (int i = 0; i < AbbreviatedEnglishEraNames.Length; i++)
+ {
+ // this comparison should use the InvariantCulture. The English name could have linguistically
+ // interesting characters.
+ if (CultureInfo.InvariantCulture.CompareInfo.Compare(eraName, m_abbrevEnglishEraNames[i], CompareOptions.IgnoreCase) == 0)
+ {
+ return (i + 1);
+ }
+ }
+ return (-1);
+ }
+
+
+ internal String[] EraNames
+ {
+ get
+ {
+ if (this.m_eraNames == null)
+ {
+ this.m_eraNames = _cultureData.EraNames(Calendar.ID); ;
+ }
+ return (this.m_eraNames);
+ }
+ }
+
+ /*=================================GetEraName==========================
+ **Action: Get the name of the era for the specified era value.
+ **Returns: The name of the specified era.
+ **Arguments:
+ ** era the era value.
+ **Exceptions:
+ ** ArguementException if the era valie is invalid.
+ ============================================================================*/
+
+ // Era names are 1 indexed
+ public String GetEraName(int era)
+ {
+ if (era == Calendar.CurrentEra)
+ {
+ era = Calendar.CurrentEraValue;
+ }
+
+ // The following is based on the assumption that the era value is starting from 1, and has a
+ // serial values.
+ // If that ever changes, the code has to be changed.
+ if ((--era) < EraNames.Length && (era >= 0))
+ {
+ return (m_eraNames[era]);
+ }
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
+ }
+
+ internal String[] AbbreviatedEraNames
+ {
+ get
+ {
+ if (this.m_abbrevEraNames == null)
+ {
+ this.m_abbrevEraNames = _cultureData.AbbrevEraNames(Calendar.ID);
+ }
+ return (this.m_abbrevEraNames);
+ }
+ }
+
+ // Era names are 1 indexed
+ public String GetAbbreviatedEraName(int era)
+ {
+ if (AbbreviatedEraNames.Length == 0)
+ {
+ // If abbreviation era name is not used in this culture,
+ // return the full era name.
+ return (GetEraName(era));
+ }
+ if (era == Calendar.CurrentEra)
+ {
+ era = Calendar.CurrentEraValue;
+ }
+ if ((--era) < m_abbrevEraNames.Length && (era >= 0))
+ {
+ return (m_abbrevEraNames[era]);
+ }
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
+ }
+
+ internal String[] AbbreviatedEnglishEraNames
+ {
+ get
+ {
+ if (this.m_abbrevEnglishEraNames == null)
+ {
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.AbbreviatedEnglishEraNames] Expected Calendar.ID > 0");
+ this.m_abbrevEnglishEraNames = _cultureData.AbbreviatedEnglishEraNames(Calendar.ID);
+ }
+ return (this.m_abbrevEnglishEraNames);
+ }
+ }
+
+ // Note that cultureData derives this from the short date format (unless someone's set this previously)
+ // Note that this property is quite undesirable.
+ public string DateSeparator
+ {
+ get
+ {
+ if (dateSeparator == null)
+ {
+ dateSeparator = _cultureData.DateSeparator(Calendar.ID);
+ }
+ Debug.Assert(this.dateSeparator != null, "DateTimeFormatInfo.DateSeparator, dateSeparator != null");
+ return dateSeparator;
+ }
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String);
+ }
+ Contract.EndContractBlock();
+ ClearTokenHashTable();
+ dateSeparator = value;
+ }
+ }
+
+ public DayOfWeek FirstDayOfWeek
+ {
+ get
+ {
+ if (this.firstDayOfWeek == -1)
+ {
+ this.firstDayOfWeek = _cultureData.IFIRSTDAYOFWEEK;
+ }
+ Debug.Assert(this.firstDayOfWeek != -1, "DateTimeFormatInfo.FirstDayOfWeek, firstDayOfWeek != -1");
+
+ return ((DayOfWeek)this.firstDayOfWeek);
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value >= DayOfWeek.Sunday && value <= DayOfWeek.Saturday)
+ {
+ firstDayOfWeek = (int)value;
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(value), SR.Format(SR.ArgumentOutOfRange_Range,
+ DayOfWeek.Sunday, DayOfWeek.Saturday));
+ }
+ }
+ }
+
+ public CalendarWeekRule CalendarWeekRule
+ {
+ get
+ {
+ if (this.calendarWeekRule == -1)
+ {
+ this.calendarWeekRule = _cultureData.IFIRSTWEEKOFYEAR;
+ }
+ Debug.Assert(this.calendarWeekRule != -1, "DateTimeFormatInfo.CalendarWeekRule, calendarWeekRule != -1");
+ return ((CalendarWeekRule)this.calendarWeekRule);
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value >= CalendarWeekRule.FirstDay && value <= CalendarWeekRule.FirstFourDayWeek)
+ {
+ calendarWeekRule = (int)value;
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(value), SR.Format(SR.ArgumentOutOfRange_Range,
+ CalendarWeekRule.FirstDay, CalendarWeekRule.FirstFourDayWeek));
+ }
+ }
+ }
+
+ public String FullDateTimePattern
+ {
+ get
+ {
+ if (fullDateTimePattern == null)
+ {
+ fullDateTimePattern = LongDatePattern + " " + LongTimePattern;
+ }
+ return (fullDateTimePattern);
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_String);
+ }
+ Contract.EndContractBlock();
+ fullDateTimePattern = value;
+ }
+ }
+
+
+ // For our "patterns" arrays we have 2 variables, a string and a string[]
+ //
+ // The string[] contains the list of patterns, EXCEPT the default may not be included.
+ // The string contains the default pattern.
+ // When we initially construct our string[], we set the string to string[0]
+ public String LongDatePattern
+ {
+ get
+ {
+ // Initialize our long date pattern from the 1st array value if not set
+ if (this.longDatePattern == null)
+ {
+ // Initialize our data
+ this.longDatePattern = this.UnclonedLongDatePatterns[0];
+ }
+
+ return this.longDatePattern;
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_String);
+ }
+ Contract.EndContractBlock();
+
+ // Remember the new string
+ this.longDatePattern = value;
+
+ // Clear the token hash table
+ ClearTokenHashTable();
+
+ // Clean up cached values that will be affected by this property.
+ this.fullDateTimePattern = null;
+ }
+ }
+
+ // For our "patterns" arrays we have 2 variables, a string and a string[]
+ //
+ // The string[] contains the list of patterns, EXCEPT the default may not be included.
+ // The string contains the default pattern.
+ // When we initially construct our string[], we set the string to string[0]
+ public String LongTimePattern
+ {
+ get
+ {
+ // Initialize our long time pattern from the 1st array value if not set
+ if (this.longTimePattern == null)
+ {
+ // Initialize our data
+ this.longTimePattern = this.UnclonedLongTimePatterns[0];
+ }
+
+ return this.longTimePattern;
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_String);
+ }
+ Contract.EndContractBlock();
+
+ // Remember the new string
+ this.longTimePattern = value;
+
+ // Clear the token hash table
+ ClearTokenHashTable();
+
+ // Clean up cached values that will be affected by this property.
+ this.fullDateTimePattern = null; // Full date = long date + long Time
+ this.generalLongTimePattern = null; // General long date = short date + long Time
+ this.dateTimeOffsetPattern = null;
+ }
+ }
+
+
+ // Note: just to be confusing there's only 1 month day pattern, not a whole list
+ public String MonthDayPattern
+ {
+ get
+ {
+ if (this.monthDayPattern == null)
+ {
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.MonthDayPattern] Expected calID > 0");
+ this.monthDayPattern = _cultureData.MonthDay(Calendar.ID);
+ }
+ Debug.Assert(this.monthDayPattern != null, "DateTimeFormatInfo.MonthDayPattern, monthDayPattern != null");
+ return (this.monthDayPattern);
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_String);
+ }
+ Contract.EndContractBlock();
+
+ this.monthDayPattern = value;
+ }
+ }
+
+
+ public String PMDesignator
+ {
+ get
+ {
+ if (this.pmDesignator == null)
+ {
+ this.pmDesignator = _cultureData.SPM2359;
+ }
+ Debug.Assert(this.pmDesignator != null, "DateTimeFormatInfo.PMDesignator, pmDesignator != null");
+ return (this.pmDesignator);
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_String);
+ }
+ Contract.EndContractBlock();
+ ClearTokenHashTable();
+
+ pmDesignator = value;
+ }
+ }
+
+
+ public String RFC1123Pattern
+ {
+ get
+ {
+ return (rfc1123Pattern);
+ }
+ }
+
+ // For our "patterns" arrays we have 2 variables, a string and a string[]
+ //
+ // The string[] contains the list of patterns, EXCEPT the default may not be included.
+ // The string contains the default pattern.
+ // When we initially construct our string[], we set the string to string[0]
+ public String ShortDatePattern
+ {
+ get
+ {
+ // Initialize our short date pattern from the 1st array value if not set
+ if (this.shortDatePattern == null)
+ {
+ // Initialize our data
+ this.shortDatePattern = this.UnclonedShortDatePatterns[0];
+ }
+
+ return this.shortDatePattern;
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_String);
+ Contract.EndContractBlock();
+
+ // Remember the new string
+ this.shortDatePattern = value;
+
+ // Clear the token hash table, note that even short dates could require this
+ ClearTokenHashTable();
+
+ // Clean up cached values that will be affected by this property.
+ generalLongTimePattern = null; // General long time = short date + long time
+ generalShortTimePattern = null; // General short time = short date + short Time
+ dateTimeOffsetPattern = null;
+ }
+ }
+
+
+ // For our "patterns" arrays we have 2 variables, a string and a string[]
+ //
+ // The string[] contains the list of patterns, EXCEPT the default may not be included.
+ // The string contains the default pattern.
+ // When we initially construct our string[], we set the string to string[0]
+ public String ShortTimePattern
+ {
+ get
+ {
+ // Initialize our short time pattern from the 1st array value if not set
+ if (this.shortTimePattern == null)
+ {
+ // Initialize our data
+ this.shortTimePattern = this.UnclonedShortTimePatterns[0];
+ }
+ return this.shortTimePattern;
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_String);
+ }
+ Contract.EndContractBlock();
+
+ // Remember the new string
+ this.shortTimePattern = value;
+
+ // Clear the token hash table, note that even short times could require this
+ ClearTokenHashTable();
+
+ // Clean up cached values that will be affected by this property.
+ generalShortTimePattern = null; // General short date = short date + short time.
+ }
+ }
+
+
+ public String SortableDateTimePattern
+ {
+ get
+ {
+ return (sortableDateTimePattern);
+ }
+ }
+
+ /*=================================GeneralShortTimePattern=====================
+ **Property: Return the pattern for 'g' general format: shortDate + short time
+ **Note: This is used by DateTimeFormat.cs to get the pattern for 'g'
+ ** We put this internal property here so that we can avoid doing the
+ ** concatation every time somebody asks for the general format.
+ ==============================================================================*/
+
+ internal String GeneralShortTimePattern
+ {
+ get
+ {
+ if (generalShortTimePattern == null)
+ {
+ generalShortTimePattern = ShortDatePattern + " " + ShortTimePattern;
+ }
+ return (generalShortTimePattern);
+ }
+ }
+
+ /*=================================GeneralLongTimePattern=====================
+ **Property: Return the pattern for 'g' general format: shortDate + Long time
+ **Note: This is used by DateTimeFormat.cs to get the pattern for 'g'
+ ** We put this internal property here so that we can avoid doing the
+ ** concatation every time somebody asks for the general format.
+ ==============================================================================*/
+
+ internal String GeneralLongTimePattern
+ {
+ get
+ {
+ if (generalLongTimePattern == null)
+ {
+ generalLongTimePattern = ShortDatePattern + " " + LongTimePattern;
+ }
+ return (generalLongTimePattern);
+ }
+ }
+
+ /*=================================DateTimeOffsetPattern==========================
+ **Property: Return the default pattern DateTimeOffset : shortDate + long time + time zone offset
+ **Note: This is used by DateTimeFormat.cs to get the pattern for short Date + long time + time zone offset
+ ** We put this internal property here so that we can avoid doing the
+ ** concatation every time somebody uses this form
+ ==============================================================================*/
+
+ /*=================================DateTimeOffsetPattern==========================
+ **Property: Return the default pattern DateTimeOffset : shortDate + long time + time zone offset
+ **Note: This is used by DateTimeFormat.cs to get the pattern for short Date + long time + time zone offset
+ ** We put this internal property here so that we can avoid doing the
+ ** concatation every time somebody uses this form
+ ==============================================================================*/
+
+ internal String DateTimeOffsetPattern
+ {
+ get
+ {
+ if (dateTimeOffsetPattern == null)
+ {
+ string dateTimePattern = ShortDatePattern + " " + LongTimePattern;
+
+ /* LongTimePattern might contain a "z" as part of the format string in which case we don't want to append a time zone offset */
+
+ bool foundZ = false;
+ bool inQuote = false;
+ char quote = '\'';
+ for (int i = 0; !foundZ && i < LongTimePattern.Length; i++)
+ {
+ switch (LongTimePattern[i])
+ {
+ case 'z':
+ /* if we aren't in a quote, we've found a z */
+ foundZ = !inQuote;
+ /* we'll fall out of the loop now because the test includes !foundZ */
+ break;
+ case '\'':
+ case '\"':
+ if (inQuote && (quote == LongTimePattern[i]))
+ {
+ /* we were in a quote and found a matching exit quote, so we are outside a quote now */
+ inQuote = false;
+ }
+ else if (!inQuote)
+ {
+ quote = LongTimePattern[i];
+ inQuote = true;
+ }
+ else
+ {
+ /* we were in a quote and saw the other type of quote character, so we are still in a quote */
+ }
+ break;
+ case '%':
+ case '\\':
+ i++; /* skip next character that is escaped by this backslash */
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!foundZ)
+ {
+ dateTimePattern = dateTimePattern + " zzz";
+ }
+
+ dateTimeOffsetPattern = dateTimePattern;
+ }
+ return (dateTimeOffsetPattern);
+ }
+ }
+
+ // Note that cultureData derives this from the long time format (unless someone's set this previously)
+ // Note that this property is quite undesirable.
+ public string TimeSeparator
+ {
+ get
+ {
+ if (timeSeparator == null)
+ {
+ timeSeparator = _cultureData.TimeSeparator;
+ }
+ Debug.Assert(this.timeSeparator != null, "DateTimeFormatInfo.TimeSeparator, timeSeparator != null");
+ return (timeSeparator);
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String);
+ }
+
+ Contract.EndContractBlock();
+ ClearTokenHashTable();
+
+ timeSeparator = value;
+ }
+ }
+
+ public String UniversalSortableDateTimePattern
+ {
+ get
+ {
+ return (universalSortableDateTimePattern);
+ }
+ }
+
+ // For our "patterns" arrays we have 2 variables, a string and a string[]
+ //
+ // The string[] contains the list of patterns, EXCEPT the default may not be included.
+ // The string contains the default pattern.
+ // When we initially construct our string[], we set the string to string[0]
+ public String YearMonthPattern
+ {
+ get
+ {
+ // Initialize our year/month pattern from the 1st array value if not set
+ if (this.yearMonthPattern == null)
+ {
+ // Initialize our data
+ this.yearMonthPattern = this.UnclonedYearMonthPatterns[0];
+ }
+ return this.yearMonthPattern;
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_String);
+ }
+ Contract.EndContractBlock();
+
+ // Remember the new string
+ this.yearMonthPattern = value;
+
+ // Clear the token hash table, note that even short times could require this
+ ClearTokenHashTable();
+ }
+ }
+
+ //
+ // Check if a string array contains a null value, and throw ArgumentNullException with parameter name "value"
+ //
+ private static void CheckNullValue(String[] values, int length)
+ {
+ Debug.Assert(values != null, "value != null");
+ Debug.Assert(values.Length >= length);
+ for (int i = 0; i < length; i++)
+ {
+ if (values[i] == null)
+ {
+ throw new ArgumentNullException("value",
+ SR.ArgumentNull_ArrayValue);
+ }
+ }
+ }
+
+
+ public String[] AbbreviatedDayNames
+ {
+ get
+ {
+ return ((String[])internalGetAbbreviatedDayOfWeekNames().Clone());
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_Array);
+ }
+ if (value.Length != 7)
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value));
+ }
+ Contract.EndContractBlock();
+ CheckNullValue(value, value.Length);
+ ClearTokenHashTable();
+
+ abbreviatedDayNames = value;
+ }
+ }
+
+ // Returns the string array of the one-letter day of week names.
+ public String[] ShortestDayNames
+ {
+ get
+ {
+ return ((String[])internalGetSuperShortDayNames().Clone());
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_Array);
+ }
+ if (value.Length != 7)
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value));
+ }
+ Contract.EndContractBlock();
+ CheckNullValue(value, value.Length);
+ this.m_superShortDayNames = value;
+ }
+ }
+
+
+ public String[] DayNames
+ {
+ get
+ {
+ return ((String[])internalGetDayOfWeekNames().Clone());
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_Array);
+ }
+ if (value.Length != 7)
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value));
+ }
+ Contract.EndContractBlock();
+ CheckNullValue(value, value.Length);
+ ClearTokenHashTable();
+
+ dayNames = value;
+ }
+ }
+
+
+ public String[] AbbreviatedMonthNames
+ {
+ get
+ {
+ return ((String[])internalGetAbbreviatedMonthNames().Clone());
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_Array);
+ }
+ if (value.Length != 13)
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
+ }
+ Contract.EndContractBlock();
+ CheckNullValue(value, value.Length - 1);
+ ClearTokenHashTable();
+ abbreviatedMonthNames = value;
+ }
+ }
+
+
+ public String[] MonthNames
+ {
+ get
+ {
+ return ((String[])internalGetMonthNames().Clone());
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_Array);
+ }
+ if (value.Length != 13)
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
+ }
+ Contract.EndContractBlock();
+ CheckNullValue(value, value.Length - 1);
+ monthNames = value;
+ ClearTokenHashTable();
+ }
+ }
+
+ // Whitespaces that we allow in the month names.
+ // U+00a0 is non-breaking space.
+ private static readonly char[] s_monthSpaces = { ' ', '\u00a0' };
+
+ internal bool HasSpacesInMonthNames
+ {
+ get
+ {
+ return (FormatFlags & DateTimeFormatFlags.UseSpacesInMonthNames) != 0;
+ }
+ }
+
+ internal bool HasSpacesInDayNames
+ {
+ get
+ {
+ return (FormatFlags & DateTimeFormatFlags.UseSpacesInDayNames) != 0;
+ }
+ }
+
+
+ //
+ // internalGetMonthName
+ //
+ // Actions: Return the month name using the specified MonthNameStyles in either abbreviated form
+ // or full form.
+ // Arguments:
+ // month
+ // style To indicate a form like regular/genitive/month name in a leap year.
+ // abbreviated When true, return abbreviated form. Otherwise, return a full form.
+ // Exceptions:
+ // ArgumentOutOfRangeException When month name is invalid.
+ //
+ internal String internalGetMonthName(int month, MonthNameStyles style, bool abbreviated)
+ {
+ //
+ // Right now, style is mutual exclusive, but I make the style to be flag so that
+ // maybe we can combine flag if there is such a need.
+ //
+ String[] monthNamesArray = null;
+ switch (style)
+ {
+ case MonthNameStyles.Genitive:
+ monthNamesArray = internalGetGenitiveMonthNames(abbreviated);
+ break;
+ case MonthNameStyles.LeapYear:
+ monthNamesArray = internalGetLeapYearMonthNames(/*abbreviated*/);
+ break;
+ default:
+ monthNamesArray = (abbreviated ? internalGetAbbreviatedMonthNames() : internalGetMonthNames());
+ break;
+ }
+ // The month range is from 1 ~ this.m_monthNames.Length
+ // (actually is 13 right now for all cases)
+ if ((month < 1) || (month > monthNamesArray.Length))
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
+ 1, monthNamesArray.Length));
+ }
+ return (monthNamesArray[month - 1]);
+ }
+
+ //
+ // internalGetGenitiveMonthNames
+ //
+ // Action: Retrieve the array which contains the month names in genitive form.
+ // If this culture does not use the gentive form, the normal month name is returned.
+ // Arguments:
+ // abbreviated When true, return abbreviated form. Otherwise, return a full form.
+ //
+ private String[] internalGetGenitiveMonthNames(bool abbreviated)
+ {
+ if (abbreviated)
+ {
+ if (this.m_genitiveAbbreviatedMonthNames == null)
+ {
+ this.m_genitiveAbbreviatedMonthNames = _cultureData.AbbreviatedGenitiveMonthNames(this.Calendar.ID);
+ Debug.Assert(this.m_genitiveAbbreviatedMonthNames.Length == 13,
+ "[DateTimeFormatInfo.GetGenitiveMonthNames] Expected 13 abbreviated genitive month names in a year");
+ }
+ return (this.m_genitiveAbbreviatedMonthNames);
+ }
+
+ if (this.genitiveMonthNames == null)
+ {
+ this.genitiveMonthNames = _cultureData.GenitiveMonthNames(this.Calendar.ID);
+ Debug.Assert(this.genitiveMonthNames.Length == 13,
+ "[DateTimeFormatInfo.GetGenitiveMonthNames] Expected 13 genitive month names in a year");
+ }
+ return (this.genitiveMonthNames);
+ }
+
+ //
+ // internalGetLeapYearMonthNames
+ //
+ // Actions: Retrieve the month names used in a leap year.
+ // If this culture does not have different month names in a leap year, the normal month name is returned.
+ // Agruments: None. (can use abbreviated later if needed)
+ //
+ internal String[] internalGetLeapYearMonthNames(/*bool abbreviated*/)
+ {
+ if (this.leapYearMonthNames == null)
+ {
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.internalGetLeapYearMonthNames] Expected Calendar.ID > 0");
+ this.leapYearMonthNames = _cultureData.LeapYearMonthNames(Calendar.ID);
+ Debug.Assert(this.leapYearMonthNames.Length == 13,
+ "[DateTimeFormatInfo.internalGetLeapYearMonthNames] Expepcted 13 leap year month names");
+ }
+ return (leapYearMonthNames);
+ }
+
+
+ public String GetAbbreviatedDayName(DayOfWeek dayofweek)
+ {
+ if ((int)dayofweek < 0 || (int)dayofweek > 6)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(dayofweek), SR.Format(SR.ArgumentOutOfRange_Range,
+ DayOfWeek.Sunday, DayOfWeek.Saturday));
+ }
+ Contract.EndContractBlock();
+ //
+ // Don't call the public property AbbreviatedDayNames here since a clone is needed in that
+ // property, so it will be slower. Instead, use GetAbbreviatedDayOfWeekNames() directly.
+ //
+ return (internalGetAbbreviatedDayOfWeekNames()[(int)dayofweek]);
+ }
+
+ // Returns the super short day of week names for the specified day of week.
+ public string GetShortestDayName(DayOfWeek dayOfWeek)
+ {
+ if ((int)dayOfWeek < 0 || (int)dayOfWeek > 6)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(dayOfWeek), SR.Format(SR.ArgumentOutOfRange_Range,
+ DayOfWeek.Sunday, DayOfWeek.Saturday));
+ }
+ Contract.EndContractBlock();
+ //
+ // Don't call the public property SuperShortDayNames here since a clone is needed in that
+ // property, so it will be slower. Instead, use internalGetSuperShortDayNames() directly.
+ //
+ return (internalGetSuperShortDayNames()[(int)dayOfWeek]);
+ }
+
+ // Get all possible combination of inputs
+ private static String[] GetCombinedPatterns(String[] patterns1, String[] patterns2, String connectString)
+ {
+ Debug.Assert(patterns1 != null);
+ Debug.Assert(patterns2 != null);
+
+ // Get array size
+ String[] result = new String[patterns1.Length * patterns2.Length];
+
+ // Counter of actual results
+ int k = 0;
+ for (int i = 0; i < patterns1.Length; i++)
+ {
+ for (int j = 0; j < patterns2.Length; j++)
+ {
+ // Can't combine if null or empty
+ result[k++] = patterns1[i] + connectString + patterns2[j];
+ }
+ }
+
+ // Return the combinations
+ return (result);
+ }
+
+ public string[] GetAllDateTimePatterns()
+ {
+ List<String> results = new List<String>(DEFAULT_ALL_DATETIMES_SIZE);
+
+ for (int i = 0; i < DateTimeFormat.allStandardFormats.Length; i++)
+ {
+ String[] strings = GetAllDateTimePatterns(DateTimeFormat.allStandardFormats[i]);
+ for (int j = 0; j < strings.Length; j++)
+ {
+ results.Add(strings[j]);
+ }
+ }
+ return results.ToArray();
+ }
+
+ public string[] GetAllDateTimePatterns(char format)
+ {
+ Contract.Ensures(Contract.Result<String[]>() != null);
+ String[] result = null;
+
+ switch (format)
+ {
+ case 'd':
+ result = this.AllShortDatePatterns;
+ break;
+ case 'D':
+ result = this.AllLongDatePatterns;
+ break;
+ case 'f':
+ result = GetCombinedPatterns(AllLongDatePatterns, AllShortTimePatterns, " ");
+ break;
+ case 'F':
+ case 'U':
+ result = GetCombinedPatterns(AllLongDatePatterns, AllLongTimePatterns, " ");
+ break;
+ case 'g':
+ result = GetCombinedPatterns(AllShortDatePatterns, AllShortTimePatterns, " ");
+ break;
+ case 'G':
+ result = GetCombinedPatterns(AllShortDatePatterns, AllLongTimePatterns, " ");
+ break;
+ case 'm':
+ case 'M':
+ result = new String[] { MonthDayPattern };
+ break;
+ case 'o':
+ case 'O':
+ result = new String[] { RoundtripFormat };
+ break;
+ case 'r':
+ case 'R':
+ result = new String[] { rfc1123Pattern };
+ break;
+ case 's':
+ result = new String[] { sortableDateTimePattern };
+ break;
+ case 't':
+ result = this.AllShortTimePatterns;
+ break;
+ case 'T':
+ result = this.AllLongTimePatterns;
+ break;
+ case 'u':
+ result = new String[] { UniversalSortableDateTimePattern };
+ break;
+ case 'y':
+ case 'Y':
+ result = this.AllYearMonthPatterns;
+ break;
+ default:
+ throw new ArgumentException(SR.Format_BadFormatSpecifier, nameof(format));
+ }
+ return (result);
+ }
+
+
+ public String GetDayName(DayOfWeek dayofweek)
+ {
+ if ((int)dayofweek < 0 || (int)dayofweek > 6)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(dayofweek), SR.Format(SR.ArgumentOutOfRange_Range,
+ DayOfWeek.Sunday, DayOfWeek.Saturday));
+ }
+ Contract.EndContractBlock();
+
+ // Use the internal one so that we don't clone the array unnecessarily
+ return (internalGetDayOfWeekNames()[(int)dayofweek]);
+ }
+
+
+
+ public String GetAbbreviatedMonthName(int month)
+ {
+ if (month < 1 || month > 13)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
+ 1, 13));
+ }
+ Contract.EndContractBlock();
+ // Use the internal one so we don't clone the array unnecessarily
+ return (internalGetAbbreviatedMonthNames()[month - 1]);
+ }
+
+
+ public String GetMonthName(int month)
+ {
+ if (month < 1 || month > 13)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
+ 1, 13));
+ }
+ Contract.EndContractBlock();
+ // Use the internal one so we don't clone the array unnecessarily
+ return (internalGetMonthNames()[month - 1]);
+ }
+
+ // For our "patterns" arrays we have 2 variables, a string and a string[]
+ //
+ // The string[] contains the list of patterns, EXCEPT the default may not be included.
+ // The string contains the default pattern.
+ // When we initially construct our string[], we set the string to string[0]
+ //
+ // The resulting [] can get returned to the calling app, so clone it.
+ private static string[] GetMergedPatterns(string[] patterns, string defaultPattern)
+ {
+ Debug.Assert(patterns != null && patterns.Length > 0,
+ "[DateTimeFormatInfo.GetMergedPatterns]Expected array of at least one pattern");
+ Debug.Assert(defaultPattern != null,
+ "[DateTimeFormatInfo.GetMergedPatterns]Expected non null default string");
+
+ // If the default happens to be the first in the list just return (a cloned) copy
+ if (defaultPattern == patterns[0])
+ {
+ return (string[])patterns.Clone();
+ }
+
+ // We either need a bigger list, or the pattern from the list.
+ int i;
+ for (i = 0; i < patterns.Length; i++)
+ {
+ // Stop if we found it
+ if (defaultPattern == patterns[i])
+ break;
+ }
+
+ // Either way we're going to need a new array
+ string[] newPatterns;
+
+ // Did we find it
+ if (i < patterns.Length)
+ {
+ // Found it, output will be same size
+ newPatterns = (string[])patterns.Clone();
+
+ // Have to move [0] item to [i] so we can re-write default at [0]
+ // (remember defaultPattern == [i] so this is OK)
+ newPatterns[i] = newPatterns[0];
+ }
+ else
+ {
+ // Not found, make room for it
+ newPatterns = new String[patterns.Length + 1];
+
+ // Copy existing array
+ Array.Copy(patterns, 0, newPatterns, 1, patterns.Length);
+ }
+
+ // Remember the default
+ newPatterns[0] = defaultPattern;
+
+ // Return the reconstructed list
+ return newPatterns;
+ }
+
+ // Needed by DateTimeFormatInfo and DateTimeFormat
+ internal const String RoundtripFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK";
+ internal const String RoundtripDateTimeUnfixed = "yyyy'-'MM'-'ddTHH':'mm':'ss zzz";
+
+ // Default string isn't necessarily in our string array, so get the
+ // merged patterns of both
+ private String[] AllYearMonthPatterns
+ {
+ get
+ {
+ return GetMergedPatterns(this.UnclonedYearMonthPatterns, this.YearMonthPattern);
+ }
+ }
+
+ private String[] AllShortDatePatterns
+ {
+ get
+ {
+ return GetMergedPatterns(this.UnclonedShortDatePatterns, this.ShortDatePattern);
+ }
+ }
+
+ private String[] AllShortTimePatterns
+ {
+ get
+ {
+ return GetMergedPatterns(this.UnclonedShortTimePatterns, this.ShortTimePattern);
+ }
+ }
+
+ private String[] AllLongDatePatterns
+ {
+ get
+ {
+ return GetMergedPatterns(this.UnclonedLongDatePatterns, this.LongDatePattern);
+ }
+ }
+
+ private String[] AllLongTimePatterns
+ {
+ get
+ {
+ return GetMergedPatterns(this.UnclonedLongTimePatterns, this.LongTimePattern);
+ }
+ }
+
+ // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
+ // This won't include default, call AllYearMonthPatterns
+ private String[] UnclonedYearMonthPatterns
+ {
+ get
+ {
+ if (allYearMonthPatterns == null)
+ {
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedYearMonthPatterns] Expected Calendar.ID > 0");
+ this.allYearMonthPatterns = _cultureData.YearMonths(this.Calendar.ID);
+ Debug.Assert(this.allYearMonthPatterns.Length > 0,
+ "[DateTimeFormatInfo.UnclonedYearMonthPatterns] Expected some year month patterns");
+ }
+
+ return allYearMonthPatterns;
+ }
+ }
+
+
+ // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
+ // This won't include default, call AllShortDatePatterns
+ private String[] UnclonedShortDatePatterns
+ {
+ get
+ {
+ if (allShortDatePatterns == null)
+ {
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedShortDatePatterns] Expected Calendar.ID > 0");
+ this.allShortDatePatterns = _cultureData.ShortDates(this.Calendar.ID);
+ Debug.Assert(this.allShortDatePatterns.Length > 0,
+ "[DateTimeFormatInfo.UnclonedShortDatePatterns] Expected some short date patterns");
+ }
+
+ return this.allShortDatePatterns;
+ }
+ }
+
+ // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
+ // This won't include default, call AllLongDatePatterns
+ private String[] UnclonedLongDatePatterns
+ {
+ get
+ {
+ if (allLongDatePatterns == null)
+ {
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedLongDatePatterns] Expected Calendar.ID > 0");
+ this.allLongDatePatterns = _cultureData.LongDates(this.Calendar.ID);
+ Debug.Assert(this.allLongDatePatterns.Length > 0,
+ "[DateTimeFormatInfo.UnclonedLongDatePatterns] Expected some long date patterns");
+ }
+
+ return this.allLongDatePatterns;
+ }
+ }
+
+ // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
+ // This won't include default, call AllShortTimePatterns
+ private String[] UnclonedShortTimePatterns
+ {
+ get
+ {
+ if (this.allShortTimePatterns == null)
+ {
+ this.allShortTimePatterns = _cultureData.ShortTimes;
+ Debug.Assert(this.allShortTimePatterns.Length > 0,
+ "[DateTimeFormatInfo.UnclonedShortTimePatterns] Expected some short time patterns");
+ }
+
+ return this.allShortTimePatterns;
+ }
+ }
+
+ // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
+ // This won't include default, call AllLongTimePatterns
+ private String[] UnclonedLongTimePatterns
+ {
+ get
+ {
+ if (this.allLongTimePatterns == null)
+ {
+ this.allLongTimePatterns = _cultureData.LongTimes;
+ Debug.Assert(this.allLongTimePatterns.Length > 0,
+ "[DateTimeFormatInfo.UnclonedLongTimePatterns] Expected some long time patterns");
+ }
+
+ return this.allLongTimePatterns;
+ }
+ }
+
+ public static DateTimeFormatInfo ReadOnly(DateTimeFormatInfo dtfi)
+ {
+ if (dtfi == null)
+ {
+ throw new ArgumentNullException(nameof(dtfi),
+ SR.ArgumentNull_Obj);
+ }
+ Contract.EndContractBlock();
+ if (dtfi.IsReadOnly)
+ {
+ return (dtfi);
+ }
+ DateTimeFormatInfo newInfo = (DateTimeFormatInfo)(dtfi.MemberwiseClone());
+ // We can use the data member calendar in the setter, instead of the property Calendar,
+ // since the cloned copy should have the same state as the original copy.
+ newInfo.calendar = Calendar.ReadOnly(dtfi.Calendar);
+ newInfo._isReadOnly = true;
+ return (newInfo);
+ }
+
+ public bool IsReadOnly
+ {
+ get
+ {
+ return (_isReadOnly);
+ }
+ }
+
+ // Return the native name for the calendar in DTFI.Calendar. The native name is referred to
+ // the culture used to create the DTFI. E.g. in the following example, the native language is Japanese.
+ // DateTimeFormatInfo dtfi = new CultureInfo("ja-JP", false).DateTimeFormat.Calendar = new JapaneseCalendar();
+ // String nativeName = dtfi.NativeCalendarName; // Get the Japanese name for the Japanese calendar.
+ // DateTimeFormatInfo dtfi = new CultureInfo("ja-JP", false).DateTimeFormat.Calendar = new GregorianCalendar(GregorianCalendarTypes.Localized);
+ // String nativeName = dtfi.NativeCalendarName; // Get the Japanese name for the Gregorian calendar.
+ public string NativeCalendarName
+ {
+ get
+ {
+ return _cultureData.CalendarName(Calendar.ID);
+ }
+ }
+
+ //
+ // Used by custom cultures and others to set the list of available formats. Note that none of them are
+ // explicitly used unless someone calls GetAllDateTimePatterns and subsequently uses one of the items
+ // from the list.
+ //
+ // Most of the format characters that can be used in GetAllDateTimePatterns are
+ // not really needed since they are one of the following:
+ //
+ // r/R/s/u locale-independent constants -- cannot be changed!
+ // m/M/y/Y fields with a single string in them -- that can be set through props directly
+ // f/F/g/G/U derived fields based on combinations of various of the below formats
+ //
+ // NOTE: No special validation is done here beyond what is done when the actual respective fields
+ // are used (what would be the point of disallowing here what we allow in the appropriate property?)
+ //
+ // WARNING: If more validation is ever done in one place, it should be done in the other.
+ //
+ public void SetAllDateTimePatterns(String[] patterns, char format)
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+
+ if (patterns == null)
+ {
+ throw new ArgumentNullException(nameof(patterns), SR.ArgumentNull_Array);
+ }
+
+ if (patterns.Length == 0)
+ {
+ throw new ArgumentException(SR.Arg_ArrayZeroError, nameof(patterns));
+ }
+
+ Contract.EndContractBlock();
+
+ for (int i = 0; i < patterns.Length; i++)
+ {
+ if (patterns[i] == null)
+ {
+ throw new ArgumentNullException("patterns[" + i + "]", SR.ArgumentNull_ArrayValue);
+ }
+ }
+
+ // Remember the patterns, and use the 1st as default
+ switch (format)
+ {
+ case 'd':
+ allShortDatePatterns = patterns;
+ shortDatePattern = allShortDatePatterns[0];
+ break;
+
+ case 'D':
+ allLongDatePatterns = patterns;
+ longDatePattern = allLongDatePatterns[0];
+ break;
+
+ case 't':
+ allShortTimePatterns = patterns;
+ shortTimePattern = allShortTimePatterns[0];
+ break;
+
+ case 'T':
+ allLongTimePatterns = patterns;
+ longTimePattern = allLongTimePatterns[0];
+ break;
+
+ case 'y':
+ case 'Y':
+ allYearMonthPatterns = patterns;
+ yearMonthPattern = allYearMonthPatterns[0];
+ break;
+
+ default:
+ throw new ArgumentException(SR.Format_BadFormatSpecifier, nameof(format));
+ }
+
+ // Clear the token hash table, note that even short dates could require this
+ ClearTokenHashTable();
+ }
+
+ public String[] AbbreviatedMonthGenitiveNames
+ {
+ get
+ {
+ return ((String[])internalGetGenitiveMonthNames(true).Clone());
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_Array);
+ }
+ if (value.Length != 13)
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
+ }
+ Contract.EndContractBlock();
+ CheckNullValue(value, value.Length - 1);
+ ClearTokenHashTable();
+ this.m_genitiveAbbreviatedMonthNames = value;
+ }
+ }
+
+ public String[] MonthGenitiveNames
+ {
+ get
+ {
+ return ((String[])internalGetGenitiveMonthNames(false).Clone());
+ }
+
+ set
+ {
+ if (IsReadOnly)
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value),
+ SR.ArgumentNull_Array);
+ }
+ if (value.Length != 13)
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
+ }
+ Contract.EndContractBlock();
+ CheckNullValue(value, value.Length - 1);
+ genitiveMonthNames = value;
+ ClearTokenHashTable();
+ }
+ }
+
+ //
+ // Positive TimeSpan Pattern
+ //
+ [NonSerialized]
+ private string _fullTimeSpanPositivePattern;
+ internal String FullTimeSpanPositivePattern
+ {
+ get
+ {
+ if (_fullTimeSpanPositivePattern == null)
+ {
+ CultureData cultureDataWithoutUserOverrides;
+ if (_cultureData.UseUserOverride)
+ cultureDataWithoutUserOverrides = CultureData.GetCultureData(_cultureData.CultureName, false);
+ else
+ cultureDataWithoutUserOverrides = _cultureData;
+ String decimalSeparator = new NumberFormatInfo(cultureDataWithoutUserOverrides).NumberDecimalSeparator;
+
+ _fullTimeSpanPositivePattern = "d':'h':'mm':'ss'" + decimalSeparator + "'FFFFFFF";
+ }
+ return _fullTimeSpanPositivePattern;
+ }
+ }
+
+ //
+ // Negative TimeSpan Pattern
+ //
+ [NonSerialized]
+ private string _fullTimeSpanNegativePattern;
+ internal String FullTimeSpanNegativePattern
+ {
+ get
+ {
+ if (_fullTimeSpanNegativePattern == null)
+ _fullTimeSpanNegativePattern = "'-'" + FullTimeSpanPositivePattern;
+ return _fullTimeSpanNegativePattern;
+ }
+ }
+
+ //
+ // Get suitable CompareInfo from current DTFI object.
+ //
+ internal CompareInfo CompareInfo
+ {
+ get
+ {
+ if (_compareInfo == null)
+ {
+ // We use the regular GetCompareInfo here to make sure the created CompareInfo object is stored in the
+ // CompareInfo cache. otherwise we would just create CompareInfo using _cultureData.
+ _compareInfo = CompareInfo.GetCompareInfo(_cultureData.SCOMPAREINFO);
+ }
+
+ return _compareInfo;
+ }
+ }
+
+
+ internal const DateTimeStyles InvalidDateTimeStyles = ~(DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite
+ | DateTimeStyles.AllowInnerWhite | DateTimeStyles.NoCurrentDateDefault
+ | DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeLocal
+ | DateTimeStyles.AssumeUniversal | DateTimeStyles.RoundtripKind);
+
+ internal static void ValidateStyles(DateTimeStyles style, String parameterName)
+ {
+ if ((style & InvalidDateTimeStyles) != 0)
+ {
+ throw new ArgumentException(SR.Argument_InvalidDateTimeStyles, parameterName);
+ }
+ if (((style & (DateTimeStyles.AssumeLocal)) != 0) && ((style & (DateTimeStyles.AssumeUniversal)) != 0))
+ {
+ throw new ArgumentException(SR.Argument_ConflictingDateTimeStyles, parameterName);
+ }
+ Contract.EndContractBlock();
+ if (((style & DateTimeStyles.RoundtripKind) != 0)
+ && ((style & (DateTimeStyles.AssumeLocal | DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)) != 0))
+ {
+ throw new ArgumentException(SR.Argument_ConflictingDateTimeRoundtripStyles, parameterName);
+ }
+ }
+
+ //
+ // Actions: Return the internal flag used in formatting and parsing.
+ // The flag can be used to indicate things like if genitive forms is used in this DTFi, or if leap year gets different month names.
+ //
+ internal DateTimeFormatFlags FormatFlags
+ {
+ get
+ {
+ if (formatFlags == DateTimeFormatFlags.NotInitialized)
+ {
+ // Build the format flags from the data in this DTFI
+ formatFlags = DateTimeFormatFlags.None;
+ formatFlags |= (DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagGenitiveMonth(
+ MonthNames, internalGetGenitiveMonthNames(false), AbbreviatedMonthNames, internalGetGenitiveMonthNames(true));
+ formatFlags |= (DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagUseSpaceInMonthNames(
+ MonthNames, internalGetGenitiveMonthNames(false), AbbreviatedMonthNames, internalGetGenitiveMonthNames(true));
+ formatFlags |= (DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagUseSpaceInDayNames(DayNames, AbbreviatedDayNames);
+ formatFlags |= (DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagUseHebrewCalendar((int)Calendar.ID);
+ }
+ return (formatFlags);
+ }
+ }
+
+ internal Boolean HasForceTwoDigitYears
+ {
+ get
+ {
+ switch (calendar.ID)
+ {
+ // Handle Japanese and Taiwan cases.
+ // If is y/yy, do not get (year % 100). "y" will print
+ // year without leading zero. "yy" will print year with two-digit in leading zero.
+ // If pattern is yyy/yyyy/..., print year value with two-digit in leading zero.
+ // So year 5 is "05", and year 125 is "125".
+ // The reason for not doing (year % 100) is for Taiwan calendar.
+ // If year 125, then output 125 and not 25.
+ // Note: OS uses "yyyy" for Taiwan calendar by default.
+ case (CalendarId.JAPAN):
+ case (CalendarId.TAIWAN):
+ return true;
+ }
+ return false;
+ }
+ }
+
+ // Returns whether the YearMonthAdjustment function has any fix-up work to do for this culture/calendar.
+ internal Boolean HasYearMonthAdjustment
+ {
+ get
+ {
+ return ((FormatFlags & DateTimeFormatFlags.UseHebrewRule) != 0);
+ }
+ }
+
+ // This is a callback that the parser can make back into the DTFI to let it fiddle with special
+ // cases associated with that culture or calendar. Currently this only has special cases for
+ // the Hebrew calendar, but this could be extended to other cultures.
+ //
+ // The return value is whether the year and month are actually valid for this calendar.
+ internal Boolean YearMonthAdjustment(ref int year, ref int month, Boolean parsedMonthName)
+ {
+ if ((FormatFlags & DateTimeFormatFlags.UseHebrewRule) != 0)
+ {
+ // Special rules to fix up the Hebrew year/month
+
+ // When formatting, we only format up to the hundred digit of the Hebrew year, although Hebrew year is now over 5000.
+ // E.g. if the year is 5763, we only format as 763.
+ if (year < 1000)
+ {
+ year += 5000;
+ }
+
+ // Because we need to calculate leap year, we should fall out now for an invalid year.
+ if (year < Calendar.GetYear(Calendar.MinSupportedDateTime) || year > Calendar.GetYear(Calendar.MaxSupportedDateTime))
+ {
+ return false;
+ }
+
+ // To handle leap months, the set of month names in the symbol table does not always correspond to the numbers.
+ // For non-leap years, month 7 (Adar Bet) is not present, so we need to make using this month invalid and
+ // shuffle the other months down.
+ if (parsedMonthName)
+ {
+ if (!Calendar.IsLeapYear(year))
+ {
+ if (month >= 8)
+ {
+ month--;
+ }
+ else if (month == 7)
+ {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ //
+ // DateTimeFormatInfo tokenizer. This is used by DateTime.Parse() to break input string into tokens.
+ //
+ [NonSerialized]
+ private TokenHashValue[] _dtfiTokenHash;
+
+ private const int TOKEN_HASH_SIZE = 199;
+ private const int SECOND_PRIME = 197;
+ private const String dateSeparatorOrTimeZoneOffset = "-";
+ private const String invariantDateSeparator = "/";
+ private const String invariantTimeSeparator = ":";
+
+ //
+ // Common Ignorable Symbols
+ //
+ internal const String IgnorablePeriod = ".";
+ internal const String IgnorableComma = ",";
+
+ //
+ // Year/Month/Day suffixes
+ //
+ internal const String CJKYearSuff = "\u5e74";
+ internal const String CJKMonthSuff = "\u6708";
+ internal const String CJKDaySuff = "\u65e5";
+
+ internal const String KoreanYearSuff = "\ub144";
+ internal const String KoreanMonthSuff = "\uc6d4";
+ internal const String KoreanDaySuff = "\uc77c";
+
+ internal const String KoreanHourSuff = "\uc2dc";
+ internal const String KoreanMinuteSuff = "\ubd84";
+ internal const String KoreanSecondSuff = "\ucd08";
+
+ internal const String CJKHourSuff = "\u6642";
+ internal const String ChineseHourSuff = "\u65f6";
+
+ internal const String CJKMinuteSuff = "\u5206";
+ internal const String CJKSecondSuff = "\u79d2";
+
+ internal const String LocalTimeMark = "T";
+
+ internal const String GMTName = "GMT";
+ internal const String ZuluName = "Z";
+
+ internal const String KoreanLangName = "ko";
+ internal const String JapaneseLangName = "ja";
+ internal const String EnglishLangName = "en";
+
+ private static volatile DateTimeFormatInfo s_jajpDTFI;
+ private static volatile DateTimeFormatInfo s_zhtwDTFI;
+
+ //
+ // Create a Japanese DTFI which uses JapaneseCalendar. This is used to parse
+ // date string with Japanese era name correctly even when the supplied DTFI
+ // does not use Japanese calendar.
+ // The created instance is stored in global s_jajpDTFI.
+ //
+ internal static DateTimeFormatInfo GetJapaneseCalendarDTFI()
+ {
+ DateTimeFormatInfo temp = s_jajpDTFI;
+ if (temp == null)
+ {
+ temp = new CultureInfo("ja-JP", false).DateTimeFormat;
+ temp.Calendar = JapaneseCalendar.GetDefaultInstance();
+ s_jajpDTFI = temp;
+ }
+ return (temp);
+ }
+
+ // Create a Taiwan DTFI which uses TaiwanCalendar. This is used to parse
+ // date string with era name correctly even when the supplied DTFI
+ // does not use Taiwan calendar.
+ // The created instance is stored in global s_zhtwDTFI.
+ internal static DateTimeFormatInfo GetTaiwanCalendarDTFI()
+ {
+ DateTimeFormatInfo temp = s_zhtwDTFI;
+ if (temp == null)
+ {
+ temp = new CultureInfo("zh-TW", false).DateTimeFormat;
+ temp.Calendar = TaiwanCalendar.GetDefaultInstance();
+ s_zhtwDTFI = temp;
+ }
+ return (temp);
+ }
+
+
+ // DTFI properties should call this when the setter are called.
+ private void ClearTokenHashTable()
+ {
+ _dtfiTokenHash = null;
+ formatFlags = DateTimeFormatFlags.NotInitialized;
+ }
+
+ internal TokenHashValue[] CreateTokenHashTable()
+ {
+ TokenHashValue[] temp = _dtfiTokenHash;
+ if (temp == null)
+ {
+ temp = new TokenHashValue[TOKEN_HASH_SIZE];
+
+ bool koreanLanguage = LanguageName.Equals(KoreanLangName);
+
+ string sep = this.TimeSeparator.Trim();
+ if (IgnorableComma != sep) InsertHash(temp, IgnorableComma, TokenType.IgnorableSymbol, 0);
+ if (IgnorablePeriod != sep) InsertHash(temp, IgnorablePeriod, TokenType.IgnorableSymbol, 0);
+
+ if (KoreanHourSuff != sep && CJKHourSuff != sep && ChineseHourSuff != sep)
+ {
+ //
+ // On the Macintosh, the default TimeSeparator is identical to the KoreanHourSuff, CJKHourSuff, or ChineseHourSuff for some cultures like
+ // ja-JP and ko-KR. In these cases having the same symbol inserted into the hash table with multiple TokenTypes causes undesirable
+ // DateTime.Parse behavior. For instance, the DateTimeFormatInfo.Tokenize() method might return SEP_DateOrOffset for KoreanHourSuff
+ // instead of SEP_HourSuff.
+ //
+ InsertHash(temp, this.TimeSeparator, TokenType.SEP_Time, 0);
+ }
+
+ InsertHash(temp, this.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
+ InsertHash(temp, this.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
+
+ // TODO: This ignores similar custom cultures
+ if (LanguageName.Equals("sq"))
+ {
+ // Albanian allows time formats like "12:00.PD"
+ InsertHash(temp, IgnorablePeriod + this.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
+ InsertHash(temp, IgnorablePeriod + this.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
+ }
+
+ // CJK suffix
+ InsertHash(temp, CJKYearSuff, TokenType.SEP_YearSuff, 0);
+ InsertHash(temp, KoreanYearSuff, TokenType.SEP_YearSuff, 0);
+ InsertHash(temp, CJKMonthSuff, TokenType.SEP_MonthSuff, 0);
+ InsertHash(temp, KoreanMonthSuff, TokenType.SEP_MonthSuff, 0);
+ InsertHash(temp, CJKDaySuff, TokenType.SEP_DaySuff, 0);
+ InsertHash(temp, KoreanDaySuff, TokenType.SEP_DaySuff, 0);
+
+ InsertHash(temp, CJKHourSuff, TokenType.SEP_HourSuff, 0);
+ InsertHash(temp, ChineseHourSuff, TokenType.SEP_HourSuff, 0);
+ InsertHash(temp, CJKMinuteSuff, TokenType.SEP_MinuteSuff, 0);
+ InsertHash(temp, CJKSecondSuff, TokenType.SEP_SecondSuff, 0);
+
+ // TODO: This ignores other custom cultures that might want to do something similar
+ if (koreanLanguage)
+ {
+ // Korean suffix
+ InsertHash(temp, KoreanHourSuff, TokenType.SEP_HourSuff, 0);
+ InsertHash(temp, KoreanMinuteSuff, TokenType.SEP_MinuteSuff, 0);
+ InsertHash(temp, KoreanSecondSuff, TokenType.SEP_SecondSuff, 0);
+ }
+
+ if (LanguageName.Equals("ky"))
+ {
+ // For some cultures, the date separator works more like a comma, being allowed before or after any date part
+ InsertHash(temp, dateSeparatorOrTimeZoneOffset, TokenType.IgnorableSymbol, 0);
+ }
+ else
+ {
+ InsertHash(temp, dateSeparatorOrTimeZoneOffset, TokenType.SEP_DateOrOffset, 0);
+ }
+
+ String[] dateWords = null;
+ DateTimeFormatInfoScanner scanner = null;
+
+ // We need to rescan the date words since we're always synthetic
+ scanner = new DateTimeFormatInfoScanner();
+ m_dateWords = dateWords = scanner.GetDateWordsOfDTFI(this);
+ // Ensure the formatflags is initialized.
+ DateTimeFormatFlags flag = FormatFlags;
+
+ // For some cultures, the date separator works more like a comma, being allowed before or after any date part.
+ // In these cultures, we do not use normal date separator since we disallow date separator after a date terminal state.
+ // This is determined in DateTimeFormatInfoScanner. Use this flag to determine if we should treat date separator as ignorable symbol.
+ bool useDateSepAsIgnorableSymbol = false;
+
+ String monthPostfix = null;
+ if (dateWords != null)
+ {
+ // There are DateWords. It could be a real date word (such as "de"), or a monthPostfix.
+ // The monthPostfix starts with '\xfffe' (MonthPostfixChar), followed by the real monthPostfix.
+ for (int i = 0; i < dateWords.Length; i++)
+ {
+ switch (dateWords[i][0])
+ {
+ // This is a month postfix
+ case DateTimeFormatInfoScanner.MonthPostfixChar:
+ // Get the real month postfix.
+ monthPostfix = dateWords[i].Substring(1);
+ // Add the month name + postfix into the token.
+ AddMonthNames(temp, monthPostfix);
+ break;
+ case DateTimeFormatInfoScanner.IgnorableSymbolChar:
+ String symbol = dateWords[i].Substring(1);
+ InsertHash(temp, symbol, TokenType.IgnorableSymbol, 0);
+ if (this.DateSeparator.Trim(null).Equals(symbol))
+ {
+ // The date separator is the same as the ignorable symbol.
+ useDateSepAsIgnorableSymbol = true;
+ }
+ break;
+ default:
+ InsertHash(temp, dateWords[i], TokenType.DateWordToken, 0);
+ // TODO: This ignores similar custom cultures
+ if (LanguageName.Equals("eu"))
+ {
+ // Basque has date words with leading dots
+ InsertHash(temp, IgnorablePeriod + dateWords[i], TokenType.DateWordToken, 0);
+ }
+ break;
+ }
+ }
+ }
+
+ if (!useDateSepAsIgnorableSymbol)
+ {
+ // Use the normal date separator.
+ InsertHash(temp, this.DateSeparator, TokenType.SEP_Date, 0);
+ }
+ // Add the regular month names.
+ AddMonthNames(temp, null);
+
+ // Add the abbreviated month names.
+ for (int i = 1; i <= 13; i++)
+ {
+ InsertHash(temp, GetAbbreviatedMonthName(i), TokenType.MonthToken, i);
+ }
+
+
+ if ((FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != 0)
+ {
+ for (int i = 1; i <= 13; i++)
+ {
+ String str;
+ str = internalGetMonthName(i, MonthNameStyles.Genitive, false);
+ InsertHash(temp, str, TokenType.MonthToken, i);
+ }
+ }
+
+ if ((FormatFlags & DateTimeFormatFlags.UseLeapYearMonth) != 0)
+ {
+ for (int i = 1; i <= 13; i++)
+ {
+ String str;
+ str = internalGetMonthName(i, MonthNameStyles.LeapYear, false);
+ InsertHash(temp, str, TokenType.MonthToken, i);
+ }
+ }
+
+ for (int i = 0; i < 7; i++)
+ {
+ //String str = GetDayOfWeekNames()[i];
+ // We have to call public methods here to work with inherited DTFI.
+ String str = GetDayName((DayOfWeek)i);
+ InsertHash(temp, str, TokenType.DayOfWeekToken, i);
+
+ str = GetAbbreviatedDayName((DayOfWeek)i);
+ InsertHash(temp, str, TokenType.DayOfWeekToken, i);
+ }
+
+ int[] eras = calendar.Eras;
+ for (int i = 1; i <= eras.Length; i++)
+ {
+ InsertHash(temp, GetEraName(i), TokenType.EraToken, i);
+ InsertHash(temp, GetAbbreviatedEraName(i), TokenType.EraToken, i);
+ }
+
+ // TODO: This ignores other cultures that might want to do something similar
+ if (LanguageName.Equals(JapaneseLangName))
+ {
+ // Japanese allows day of week forms like: "(Tue)"
+ for (int i = 0; i < 7; i++)
+ {
+ String specialDayOfWeek = "(" + GetAbbreviatedDayName((DayOfWeek)i) + ")";
+ InsertHash(temp, specialDayOfWeek, TokenType.DayOfWeekToken, i);
+ }
+ if (this.Calendar.GetType() != typeof(JapaneseCalendar))
+ {
+ // Special case for Japanese. If this is a Japanese DTFI, and the calendar is not Japanese calendar,
+ // we will check Japanese Era name as well when the calendar is Gregorian.
+ DateTimeFormatInfo jaDtfi = GetJapaneseCalendarDTFI();
+ for (int i = 1; i <= jaDtfi.Calendar.Eras.Length; i++)
+ {
+ InsertHash(temp, jaDtfi.GetEraName(i), TokenType.JapaneseEraToken, i);
+ InsertHash(temp, jaDtfi.GetAbbreviatedEraName(i), TokenType.JapaneseEraToken, i);
+ // m_abbrevEnglishEraNames[0] contains the name for era 1, so the token value is i+1.
+ InsertHash(temp, jaDtfi.AbbreviatedEnglishEraNames[i - 1], TokenType.JapaneseEraToken, i);
+ }
+ }
+ }
+ // TODO: This prohibits similar custom cultures, but we hard coded the name
+ else if (CultureName.Equals("zh-TW"))
+ {
+ DateTimeFormatInfo twDtfi = GetTaiwanCalendarDTFI();
+ for (int i = 1; i <= twDtfi.Calendar.Eras.Length; i++)
+ {
+ if (twDtfi.GetEraName(i).Length > 0)
+ {
+ InsertHash(temp, twDtfi.GetEraName(i), TokenType.TEraToken, i);
+ }
+ }
+ }
+
+ InsertHash(temp, InvariantInfo.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
+ InsertHash(temp, InvariantInfo.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
+
+ // Add invariant month names and day names.
+ for (int i = 1; i <= 12; i++)
+ {
+ String str;
+ // We have to call public methods here to work with inherited DTFI.
+ // Insert the month name first, so that they are at the front of abbrevaited
+ // month names.
+ str = InvariantInfo.GetMonthName(i);
+ InsertHash(temp, str, TokenType.MonthToken, i);
+ str = InvariantInfo.GetAbbreviatedMonthName(i);
+ InsertHash(temp, str, TokenType.MonthToken, i);
+ }
+
+ for (int i = 0; i < 7; i++)
+ {
+ // We have to call public methods here to work with inherited DTFI.
+ String str = InvariantInfo.GetDayName((DayOfWeek)i);
+ InsertHash(temp, str, TokenType.DayOfWeekToken, i);
+
+ str = InvariantInfo.GetAbbreviatedDayName((DayOfWeek)i);
+ InsertHash(temp, str, TokenType.DayOfWeekToken, i);
+ }
+
+ for (int i = 0; i < AbbreviatedEnglishEraNames.Length; i++)
+ {
+ // m_abbrevEnglishEraNames[0] contains the name for era 1, so the token value is i+1.
+ InsertHash(temp, AbbreviatedEnglishEraNames[i], TokenType.EraToken, i + 1);
+ }
+
+ InsertHash(temp, LocalTimeMark, TokenType.SEP_LocalTimeMark, 0);
+ InsertHash(temp, GMTName, TokenType.TimeZoneToken, 0);
+ InsertHash(temp, ZuluName, TokenType.TimeZoneToken, 0);
+
+ InsertHash(temp, invariantDateSeparator, TokenType.SEP_Date, 0);
+ InsertHash(temp, invariantTimeSeparator, TokenType.SEP_Time, 0);
+
+ _dtfiTokenHash = temp;
+ }
+ return (temp);
+ }
+
+ private void AddMonthNames(TokenHashValue[] temp, String monthPostfix)
+ {
+ for (int i = 1; i <= 13; i++)
+ {
+ String str;
+ //str = internalGetMonthName(i, MonthNameStyles.Regular, false);
+ // We have to call public methods here to work with inherited DTFI.
+ // Insert the month name first, so that they are at the front of abbrevaited
+ // month names.
+ str = GetMonthName(i);
+ if (str.Length > 0)
+ {
+ if (monthPostfix != null)
+ {
+ // Insert the month name with the postfix first, so it can be matched first.
+ InsertHash(temp, str + monthPostfix, TokenType.MonthToken, i);
+ }
+ else
+ {
+ InsertHash(temp, str, TokenType.MonthToken, i);
+ }
+ }
+ str = GetAbbreviatedMonthName(i);
+ InsertHash(temp, str, TokenType.MonthToken, i);
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Actions:
+ // Try to parse the current word to see if it is a Hebrew number.
+ // Tokens will be updated accordingly.
+ // This is called by the Lexer of DateTime.Parse().
+ //
+ // Unlike most of the functions in this class, the return value indicates
+ // whether or not it started to parse. The badFormat parameter indicates
+ // if parsing began, but the format was bad.
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ private static bool TryParseHebrewNumber(
+ ref __DTString str,
+ out Boolean badFormat,
+ out int number)
+ {
+ number = -1;
+ badFormat = false;
+
+ int i = str.Index;
+ if (!HebrewNumber.IsDigit(str.Value[i]))
+ {
+ // If the current character is not a Hebrew digit, just return false.
+ // There is no chance that we can parse a valid Hebrew number from here.
+ return (false);
+ }
+ // The current character is a Hebrew digit. Try to parse this word as a Hebrew number.
+ HebrewNumberParsingContext context = new HebrewNumberParsingContext(0);
+ HebrewNumberParsingState state;
+
+ do
+ {
+ state = HebrewNumber.ParseByChar(str.Value[i++], ref context);
+ switch (state)
+ {
+ case HebrewNumberParsingState.InvalidHebrewNumber: // Not a valid Hebrew number.
+ case HebrewNumberParsingState.NotHebrewDigit: // The current character is not a Hebrew digit character.
+ // Break out so that we don't continue to try parse this as a Hebrew number.
+ return (false);
+ }
+ } while (i < str.Value.Length && (state != HebrewNumberParsingState.FoundEndOfHebrewNumber));
+
+ // When we are here, we are either at the end of the string, or we find a valid Hebrew number.
+ Debug.Assert(state == HebrewNumberParsingState.ContinueParsing || state == HebrewNumberParsingState.FoundEndOfHebrewNumber,
+ "Invalid returned state from HebrewNumber.ParseByChar()");
+
+ if (state != HebrewNumberParsingState.FoundEndOfHebrewNumber)
+ {
+ // We reach end of the string but we can't find a terminal state in parsing Hebrew number.
+ return (false);
+ }
+
+ // We have found a valid Hebrew number. Update the index.
+ str.Advance(i - str.Index);
+
+ // Get the final Hebrew number value from the HebrewNumberParsingContext.
+ number = context.result;
+
+ return (true);
+ }
+
+ private static bool IsHebrewChar(char ch)
+ {
+ return (ch >= '\x0590' && ch <= '\x05ff');
+ }
+
+ internal bool Tokenize(TokenType TokenMask, out TokenType tokenType, out int tokenValue,
+ ref __DTString str)
+ {
+ tokenType = TokenType.UnknownToken;
+ tokenValue = 0;
+
+ TokenHashValue value;
+ Debug.Assert(str.Index < str.Value.Length, "DateTimeFormatInfo.Tokenize(): start < value.Length");
+
+ char ch = str.m_current;
+ bool isLetter = Char.IsLetter(ch);
+ if (isLetter)
+ {
+ ch = this.Culture.TextInfo.ToLower(ch);
+ if (IsHebrewChar(ch) && TokenMask == TokenType.RegularTokenMask)
+ {
+ bool badFormat;
+ if (TryParseHebrewNumber(ref str, out badFormat, out tokenValue))
+ {
+ if (badFormat)
+ {
+ tokenType = TokenType.UnknownToken;
+ return (false);
+ }
+ // This is a Hebrew number.
+ // Do nothing here. TryParseHebrewNumber() will update token accordingly.
+ tokenType = TokenType.HebrewNumber;
+ return (true);
+ }
+ }
+ }
+
+
+ int hashcode = ch % TOKEN_HASH_SIZE;
+ int hashProbe = 1 + ch % SECOND_PRIME;
+ int remaining = str.len - str.Index;
+ int i = 0;
+
+ TokenHashValue[] hashTable = _dtfiTokenHash;
+ if (hashTable == null)
+ {
+ hashTable = CreateTokenHashTable();
+ }
+ do
+ {
+ value = hashTable[hashcode];
+ if (value == null)
+ {
+ // Not found.
+ break;
+ }
+ // Check this value has the right category (regular token or separator token) that we are looking for.
+ if (((int)value.tokenType & (int)TokenMask) > 0 && value.tokenString.Length <= remaining)
+ {
+ bool compareStrings = true;
+ if (isLetter)
+ {
+ // If this token starts with a letter, make sure that we won't allow partial match. So you can't tokenize "MarchWed" separately.
+ // Also an optimization to avoid string comparison
+ int nextCharIndex = str.Index + value.tokenString.Length;
+ if (nextCharIndex > str.len)
+ {
+ compareStrings = false;
+ }
+ else if (nextCharIndex < str.len)
+ {
+ // Check word boundary. The next character should NOT be a letter.
+ char nextCh = str.Value[nextCharIndex];
+ compareStrings = !(Char.IsLetter(nextCh));
+ }
+ }
+ if (compareStrings && CompareStringIgnoreCaseOptimized(str.Value, str.Index, value.tokenString.Length, value.tokenString, 0, value.tokenString.Length))
+ {
+ tokenType = value.tokenType & TokenMask;
+ tokenValue = value.tokenValue;
+ str.Advance(value.tokenString.Length);
+ return (true);
+ }
+ else if ((value.tokenType == TokenType.MonthToken && HasSpacesInMonthNames) ||
+ (value.tokenType == TokenType.DayOfWeekToken && HasSpacesInDayNames))
+ {
+ // For month or day token, we will match the names which have spaces.
+ int matchStrLen = 0;
+ if (str.MatchSpecifiedWords(value.tokenString, true, ref matchStrLen))
+ {
+ tokenType = value.tokenType & TokenMask;
+ tokenValue = value.tokenValue;
+ str.Advance(matchStrLen);
+ return (true);
+ }
+ }
+ }
+ i++;
+ hashcode += hashProbe;
+ if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
+ } while (i < TOKEN_HASH_SIZE);
+
+ return (false);
+ }
+
+ private void InsertAtCurrentHashNode(TokenHashValue[] hashTable, String str, char ch, TokenType tokenType, int tokenValue, int pos, int hashcode, int hashProbe)
+ {
+ // Remember the current slot.
+ TokenHashValue previousNode = hashTable[hashcode];
+
+ //// Console.WriteLine(" Insert Key: {0} in {1}", str, slotToInsert);
+ // Insert the new node into the current slot.
+ hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue); ;
+
+ while (++pos < TOKEN_HASH_SIZE)
+ {
+ hashcode += hashProbe;
+ if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
+ // Remember this slot
+ TokenHashValue temp = hashTable[hashcode];
+
+ if (temp != null && this.Culture.TextInfo.ToLower(temp.tokenString[0]) != ch)
+ {
+ continue;
+ }
+ // Put the previous slot into this slot.
+ hashTable[hashcode] = previousNode;
+ //// Console.WriteLine(" Move {0} to slot {1}", previousNode.tokenString, hashcode);
+ if (temp == null)
+ {
+ // Done
+ return;
+ }
+ previousNode = temp;
+ };
+ Debug.Assert(false, "The hashtable is full. This should not happen.");
+ }
+
+ private void InsertHash(TokenHashValue[] hashTable, String str, TokenType tokenType, int tokenValue)
+ {
+ // The month of the 13th month is allowed to be null, so make sure that we ignore null value here.
+ if (str == null || str.Length == 0)
+ {
+ return;
+ }
+ TokenHashValue value;
+ int i = 0;
+ // If there is whitespace characters in the beginning and end of the string, trim them since whitespaces are skipped by
+ // DateTime.Parse().
+ if (Char.IsWhiteSpace(str[0]) || Char.IsWhiteSpace(str[str.Length - 1]))
+ {
+ str = str.Trim(null); // Trim white space characters.
+ // Could have space for separators
+ if (str.Length == 0)
+ return;
+ }
+ char ch = this.Culture.TextInfo.ToLower(str[0]);
+ int hashcode = ch % TOKEN_HASH_SIZE;
+ int hashProbe = 1 + ch % SECOND_PRIME;
+ do
+ {
+ value = hashTable[hashcode];
+ if (value == null)
+ {
+ //// Console.WriteLine(" Put Key: {0} in {1}", str, hashcode);
+ hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue);
+ return;
+ }
+ else
+ {
+ // Collision happens. Find another slot.
+ if (str.Length >= value.tokenString.Length)
+ {
+ // If there are two tokens with the same prefix, we have to make sure that the longer token should be at the front of
+ // the shorter ones.
+ if (this.CompareStringIgnoreCaseOptimized(str, 0, value.tokenString.Length, value.tokenString, 0, value.tokenString.Length))
+ {
+ if (str.Length > value.tokenString.Length)
+ {
+ // The str to be inserted has the same prefix as the current token, and str is longer.
+ // Insert str into this node, and shift every node behind it.
+ InsertAtCurrentHashNode(hashTable, str, ch, tokenType, tokenValue, i, hashcode, hashProbe);
+ return;
+ }
+ else
+ {
+ // Same token. If they have different types (regular token vs separator token). Add them.
+ // If we have the same regular token or separator token in the hash already, do NOT update the hash.
+ // Therefore, the order of inserting token is significant here regarding what tokenType will be kept in the hash.
+
+
+ //
+ // Check the current value of RegularToken (stored in the lower 8-bit of tokenType) , and insert the tokenType into the hash ONLY when we don't have a RegularToken yet.
+ // Also check the current value of SeparatorToken (stored in the upper 8-bit of token), and insert the tokenType into the hash ONLY when we don't have the SeparatorToken yet.
+ //
+
+ int nTokenType = (int)tokenType;
+ int nCurrentTokenTypeInHash = (int)value.tokenType;
+
+ //
+ // The folowing is the fix for the issue of throwing FormatException when "mar" is passed in string of the short date format dd/MMM/yyyy for es-MX
+ //
+
+ if (((nCurrentTokenTypeInHash & (int)TokenType.RegularTokenMask) == 0) && ((nTokenType & (int)TokenType.RegularTokenMask) != 0) ||
+ ((nCurrentTokenTypeInHash & (int)TokenType.SeparatorTokenMask) == 0) && ((nTokenType & (int)TokenType.SeparatorTokenMask) != 0))
+ {
+ value.tokenType |= tokenType;
+ if (tokenValue != 0)
+ {
+ value.tokenValue = tokenValue;
+ }
+ }
+ // The token to be inserted is already in the table. Skip it.
+ return;
+ }
+ }
+ }
+ }
+ //// Console.WriteLine(" COLLISION. Old Key: {0}, New Key: {1}", hashTable[hashcode].tokenString, str);
+ i++;
+ hashcode += hashProbe;
+ if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
+ } while (i < TOKEN_HASH_SIZE);
+ Debug.Assert(false, "The hashtable is full. This should not happen.");
+ }
+
+ private bool CompareStringIgnoreCaseOptimized(string string1, int offset1, int length1, string string2, int offset2, int length2)
+ {
+ // Optimize for one character cases which are common due to date and time separators (/ and :)
+ if (length1 == 1 && length2 == 1 && string1[offset1] == string2[offset2])
+ {
+ return true;
+ }
+
+ return (this.Culture.CompareInfo.Compare(string1, offset1, length1, string2, offset2, length2, CompareOptions.IgnoreCase) == 0);
+ }
+
+ // class DateTimeFormatInfo
+
+ internal class TokenHashValue
+ {
+ internal String tokenString;
+ internal TokenType tokenType;
+ internal int tokenValue;
+
+ internal TokenHashValue(String tokenString, TokenType tokenType, int tokenValue)
+ {
+ this.tokenString = tokenString;
+ this.tokenType = tokenType;
+ this.tokenValue = tokenValue;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/DateTimeFormatInfoScanner.cs b/src/mscorlib/shared/System/Globalization/DateTimeFormatInfoScanner.cs
new file mode 100644
index 0000000000..15af1b7d84
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/DateTimeFormatInfoScanner.cs
@@ -0,0 +1,739 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////
+//
+// DateTimeFormatInfoScanner
+//
+// Scan a specified DateTimeFormatInfo to search for data used in DateTime.Parse()
+//
+// The data includes:
+//
+// DateWords: such as "de" used in es-ES (Spanish) LongDatePattern.
+// Postfix: such as "ta" used in fi-FI after the month name.
+//
+// This class is shared among mscorlib.dll and sysglobl.dll.
+// Use conditional CULTURE_AND_REGIONINFO_BUILDER_ONLY to differentiate between
+// methods for mscorlib.dll and sysglobl.dll.
+//
+////////////////////////////////////////////////////////////////////////////
+
+using System.Collections.Generic;
+using System.Text;
+
+namespace System.Globalization
+{
+
+#if CORECLR
+ using StringStringDictionary = Dictionary<string, string>;
+ using StringList = List<string>;
+#else
+ using StringStringDictionary = LowLevelDictionary<string, string>;
+ using StringList = LowLevelList<string>;
+#endif
+
+ //
+ // from LocaleEx.txt header
+ //
+ //; IFORMATFLAGS
+ //; Parsing/formatting flags.
+ internal enum FORMATFLAGS
+ {
+ None = 0x00000000,
+ UseGenitiveMonth = 0x00000001,
+ UseLeapYearMonth = 0x00000002,
+ UseSpacesInMonthNames = 0x00000004,
+ UseHebrewParsing = 0x00000008,
+ UseSpacesInDayNames = 0x00000010, // Has spaces or non-breaking space in the day names.
+ UseDigitPrefixInTokens = 0x00000020, // Has token starting with numbers.
+ }
+
+ internal enum CalendarId : ushort
+ {
+ UNINITIALIZED_VALUE = 0,
+ GREGORIAN = 1, // Gregorian (localized) calendar
+ GREGORIAN_US = 2, // Gregorian (U.S.) calendar
+ JAPAN = 3, // Japanese Emperor Era calendar
+ /* SSS_WARNINGS_OFF */
+ TAIWAN = 4, // Taiwan Era calendar /* SSS_WARNINGS_ON */
+ KOREA = 5, // Korean Tangun Era calendar
+ HIJRI = 6, // Hijri (Arabic Lunar) calendar
+ THAI = 7, // Thai calendar
+ HEBREW = 8, // Hebrew (Lunar) calendar
+ GREGORIAN_ME_FRENCH = 9, // Gregorian Middle East French calendar
+ GREGORIAN_ARABIC = 10, // Gregorian Arabic calendar
+ GREGORIAN_XLIT_ENGLISH = 11, // Gregorian Transliterated English calendar
+ GREGORIAN_XLIT_FRENCH = 12,
+ // Note that all calendars after this point are MANAGED ONLY for now.
+ JULIAN = 13,
+ JAPANESELUNISOLAR = 14,
+ CHINESELUNISOLAR = 15,
+ SAKA = 16, // reserved to match Office but not implemented in our code
+ LUNAR_ETO_CHN = 17, // reserved to match Office but not implemented in our code
+ LUNAR_ETO_KOR = 18, // reserved to match Office but not implemented in our code
+ LUNAR_ETO_ROKUYOU = 19, // reserved to match Office but not implemented in our code
+ KOREANLUNISOLAR = 20,
+ TAIWANLUNISOLAR = 21,
+ PERSIAN = 22,
+ UMALQURA = 23,
+ LAST_CALENDAR = 23 // Last calendar ID
+ }
+
+ internal class DateTimeFormatInfoScanner
+ {
+ // Special prefix-like flag char in DateWord array.
+
+ // Use char in PUA area since we won't be using them in real data.
+ // The char used to tell a read date word or a month postfix. A month postfix
+ // is "ta" in the long date pattern like "d. MMMM'ta 'yyyy" for fi-FI.
+ // In this case, it will be stored as "\xfffeta" in the date word array.
+ internal const char MonthPostfixChar = '\xe000';
+
+ // Add ignorable symbol in a DateWord array.
+
+ // hu-HU has:
+ // shrot date pattern: yyyy. MM. dd.;yyyy-MM-dd;yy-MM-dd
+ // long date pattern: yyyy. MMMM d.
+ // Here, "." is the date separator (derived from short date pattern). However,
+ // "." also appear at the end of long date pattern. In this case, we just
+ // "." as ignorable symbol so that the DateTime.Parse() state machine will not
+ // treat the additional date separator at the end of y,m,d pattern as an error
+ // condition.
+ internal const char IgnorableSymbolChar = '\xe001';
+
+ // Known CJK suffix
+ internal const String CJKYearSuff = "\u5e74";
+ internal const String CJKMonthSuff = "\u6708";
+ internal const String CJKDaySuff = "\u65e5";
+
+ internal const String KoreanYearSuff = "\ub144";
+ internal const String KoreanMonthSuff = "\uc6d4";
+ internal const String KoreanDaySuff = "\uc77c";
+
+ internal const String KoreanHourSuff = "\uc2dc";
+ internal const String KoreanMinuteSuff = "\ubd84";
+ internal const String KoreanSecondSuff = "\ucd08";
+
+ internal const String CJKHourSuff = "\u6642";
+ internal const String ChineseHourSuff = "\u65f6";
+
+ internal const String CJKMinuteSuff = "\u5206";
+ internal const String CJKSecondSuff = "\u79d2";
+
+ // The collection fo date words & postfix.
+ internal StringList m_dateWords = new StringList();
+ // Hashtable for the known words.
+ private static volatile StringStringDictionary s_knownWords;
+
+ static StringStringDictionary KnownWords
+ {
+ get
+ {
+ if (s_knownWords == null)
+ {
+ StringStringDictionary temp = new StringStringDictionary();
+ // Add known words into the hash table.
+
+ // Skip these special symbols.
+ temp.Add("/", String.Empty);
+ temp.Add("-", String.Empty);
+ temp.Add(".", String.Empty);
+ // Skip known CJK suffixes.
+ temp.Add(CJKYearSuff, String.Empty);
+ temp.Add(CJKMonthSuff, String.Empty);
+ temp.Add(CJKDaySuff, String.Empty);
+ temp.Add(KoreanYearSuff, String.Empty);
+ temp.Add(KoreanMonthSuff, String.Empty);
+ temp.Add(KoreanDaySuff, String.Empty);
+ temp.Add(KoreanHourSuff, String.Empty);
+ temp.Add(KoreanMinuteSuff, String.Empty);
+ temp.Add(KoreanSecondSuff, String.Empty);
+ temp.Add(CJKHourSuff, String.Empty);
+ temp.Add(ChineseHourSuff, String.Empty);
+ temp.Add(CJKMinuteSuff, String.Empty);
+ temp.Add(CJKSecondSuff, String.Empty);
+
+ s_knownWords = temp;
+ }
+ return (s_knownWords);
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Parameters:
+ // pattern: The pattern to be scanned.
+ // currentIndex: the current index to start the scan.
+ //
+ // Returns:
+ // Return the index with the first character that is a letter, which will
+ // be the start of a date word.
+ // Note that the index can be pattern.Length if we reach the end of the string.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+ internal static int SkipWhiteSpacesAndNonLetter(String pattern, int currentIndex)
+ {
+ while (currentIndex < pattern.Length)
+ {
+ char ch = pattern[currentIndex];
+ if (ch == '\\')
+ {
+ // Escaped character. Look ahead one character.
+ currentIndex++;
+ if (currentIndex < pattern.Length)
+ {
+ ch = pattern[currentIndex];
+ if (ch == '\'')
+ {
+ // Skip the leading single quote. We will
+ // stop at the first letter.
+ continue;
+ }
+ // Fall thru to check if this is a letter.
+ }
+ else
+ {
+ // End of string
+ break;
+ }
+ }
+ if (Char.IsLetter(ch) || ch == '\'' || ch == '.')
+ {
+ break;
+ }
+ // Skip the current char since it is not a letter.
+ currentIndex++;
+ }
+ return (currentIndex);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // A helper to add the found date word or month postfix into ArrayList for date words.
+ //
+ // Parameters:
+ // formatPostfix: What kind of postfix this is.
+ // Possible values:
+ // null: This is a regular date word
+ // "MMMM": month postfix
+ // word: The date word or postfix to be added.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+ internal void AddDateWordOrPostfix(String formatPostfix, String str)
+ {
+ if (str.Length > 0)
+ {
+ // Some cultures use . like an abbreviation
+ if (str.Equals("."))
+ {
+ AddIgnorableSymbols(".");
+ return;
+ }
+ String words;
+ if (KnownWords.TryGetValue(str, out words) == false)
+ {
+ if (m_dateWords == null)
+ {
+ m_dateWords = new StringList();
+ }
+ if (formatPostfix == "MMMM")
+ {
+ // Add the word into the ArrayList as "\xfffe" + real month postfix.
+ String temp = MonthPostfixChar + str;
+ if (!m_dateWords.Contains(temp))
+ {
+ m_dateWords.Add(temp);
+ }
+ }
+ else
+ {
+ if (!m_dateWords.Contains(str))
+ {
+ m_dateWords.Add(str);
+ }
+ if (str[str.Length - 1] == '.')
+ {
+ // Old version ignore the trialing dot in the date words. Support this as well.
+ String strWithoutDot = str.Substring(0, str.Length - 1);
+ if (!m_dateWords.Contains(strWithoutDot))
+ {
+ m_dateWords.Add(strWithoutDot);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Scan the pattern from the specified index and add the date word/postfix
+ // when appropriate.
+ //
+ // Parameters:
+ // pattern: The pattern to be scanned.
+ // index: The starting index to be scanned.
+ // formatPostfix: The kind of postfix to be scanned.
+ // Possible values:
+ // null: This is a regular date word
+ // "MMMM": month postfix
+ //
+ //
+ ////////////////////////////////////////////////////////////////////////////
+ internal int AddDateWords(String pattern, int index, String formatPostfix)
+ {
+ // Skip any whitespaces so we will start from a letter.
+ int newIndex = SkipWhiteSpacesAndNonLetter(pattern, index);
+ if (newIndex != index && formatPostfix != null)
+ {
+ // There are whitespaces. This will not be a postfix.
+ formatPostfix = null;
+ }
+ index = newIndex;
+
+ // This is the first char added into dateWord.
+ // Skip all non-letter character. We will add the first letter into DateWord.
+ StringBuilder dateWord = new StringBuilder();
+ // We assume that date words should start with a letter.
+ // Skip anything until we see a letter.
+
+ while (index < pattern.Length)
+ {
+ char ch = pattern[index];
+ if (ch == '\'')
+ {
+ // We have seen the end of quote. Add the word if we do not see it before,
+ // and break the while loop.
+ AddDateWordOrPostfix(formatPostfix, dateWord.ToString());
+ index++;
+ break;
+ }
+ else if (ch == '\\')
+ {
+ //
+ // Escaped character. Look ahead one character
+ //
+
+ // Skip escaped backslash.
+ index++;
+ if (index < pattern.Length)
+ {
+ dateWord.Append(pattern[index]);
+ index++;
+ }
+ }
+ else if (Char.IsWhiteSpace(ch))
+ {
+ // Found a whitespace. We have to add the current date word/postfix.
+ AddDateWordOrPostfix(formatPostfix, dateWord.ToString());
+ if (formatPostfix != null)
+ {
+ // Done with postfix. The rest will be regular date word.
+ formatPostfix = null;
+ }
+ // Reset the dateWord.
+ dateWord.Length = 0;
+ index++;
+ }
+ else
+ {
+ dateWord.Append(ch);
+ index++;
+ }
+ }
+ return (index);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // A simple helper to find the repeat count for a specified char.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+ internal static int ScanRepeatChar(String pattern, char ch, int index, out int count)
+ {
+ count = 1;
+ while (++index < pattern.Length && pattern[index] == ch)
+ {
+ count++;
+ }
+ // Return the updated position.
+ return (index);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Add the text that is a date separator but is treated like ignroable symbol.
+ // E.g.
+ // hu-HU has:
+ // shrot date pattern: yyyy. MM. dd.;yyyy-MM-dd;yy-MM-dd
+ // long date pattern: yyyy. MMMM d.
+ // Here, "." is the date separator (derived from short date pattern). However,
+ // "." also appear at the end of long date pattern. In this case, we just
+ // "." as ignorable symbol so that the DateTime.Parse() state machine will not
+ // treat the additional date separator at the end of y,m,d pattern as an error
+ // condition.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ internal void AddIgnorableSymbols(String text)
+ {
+ if (m_dateWords == null)
+ {
+ // Create the date word array.
+ m_dateWords = new StringList();
+ }
+ // Add the ignorable symbol into the ArrayList.
+ String temp = IgnorableSymbolChar + text;
+ if (!m_dateWords.Contains(temp))
+ {
+ m_dateWords.Add(temp);
+ }
+ }
+
+
+ //
+ // Flag used to trace the date patterns (yy/yyyyy/M/MM/MMM/MMM/d/dd) that we have seen.
+ //
+ private enum FoundDatePattern
+ {
+ None = 0x0000,
+ FoundYearPatternFlag = 0x0001,
+ FoundMonthPatternFlag = 0x0002,
+ FoundDayPatternFlag = 0x0004,
+ FoundYMDPatternFlag = 0x0007, // FoundYearPatternFlag | FoundMonthPatternFlag | FoundDayPatternFlag;
+ }
+
+ // Check if we have found all of the year/month/day pattern.
+ private FoundDatePattern _ymdFlags = FoundDatePattern.None;
+
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Given a date format pattern, scan for date word or postfix.
+ //
+ // A date word should be always put in a single quoted string. And it will
+ // start from a letter, so whitespace and symbols will be ignored before
+ // the first letter.
+ //
+ // Examples of date word:
+ // 'de' in es-SP: dddd, dd' de 'MMMM' de 'yyyy
+ // "\x0443." in bg-BG: dd.M.yyyy '\x0433.'
+ //
+ // Example of postfix:
+ // month postfix:
+ // "ta" in fi-FI: d. MMMM'ta 'yyyy
+ // Currently, only month postfix is supported.
+ //
+ // Usage:
+ // Always call this with Framework-style pattern, instead of Windows style pattern.
+ // Windows style pattern uses '' for single quote, while .NET uses \'
+ //
+ ////////////////////////////////////////////////////////////////////////////
+ internal void ScanDateWord(String pattern)
+ {
+ // Check if we have found all of the year/month/day pattern.
+ _ymdFlags = FoundDatePattern.None;
+
+ int i = 0;
+ while (i < pattern.Length)
+ {
+ char ch = pattern[i];
+ int chCount;
+
+ switch (ch)
+ {
+ case '\'':
+ // Find a beginning quote. Search until the end quote.
+ i = AddDateWords(pattern, i + 1, null);
+ break;
+ case 'M':
+ i = ScanRepeatChar(pattern, 'M', i, out chCount);
+ if (chCount >= 4)
+ {
+ if (i < pattern.Length && pattern[i] == '\'')
+ {
+ i = AddDateWords(pattern, i + 1, "MMMM");
+ }
+ }
+ _ymdFlags |= FoundDatePattern.FoundMonthPatternFlag;
+ break;
+ case 'y':
+ i = ScanRepeatChar(pattern, 'y', i, out chCount);
+ _ymdFlags |= FoundDatePattern.FoundYearPatternFlag;
+ break;
+ case 'd':
+ i = ScanRepeatChar(pattern, 'd', i, out chCount);
+ if (chCount <= 2)
+ {
+ // Only count "d" & "dd".
+ // ddd, dddd are day names. Do not count them.
+ _ymdFlags |= FoundDatePattern.FoundDayPatternFlag;
+ }
+ break;
+ case '\\':
+ // Found a escaped char not in a quoted string. Skip the current backslash
+ // and its next character.
+ i += 2;
+ break;
+ case '.':
+ if (_ymdFlags == FoundDatePattern.FoundYMDPatternFlag)
+ {
+ // If we find a dot immediately after the we have seen all of the y, m, d pattern.
+ // treat it as a ignroable symbol. Check for comments in AddIgnorableSymbols for
+ // more details.
+ AddIgnorableSymbols(".");
+ _ymdFlags = FoundDatePattern.None;
+ }
+ i++;
+ break;
+ default:
+ if (_ymdFlags == FoundDatePattern.FoundYMDPatternFlag && !Char.IsWhiteSpace(ch))
+ {
+ // We are not seeing "." after YMD. Clear the flag.
+ _ymdFlags = FoundDatePattern.None;
+ }
+ // We are not in quote. Skip the current character.
+ i++;
+ break;
+ }
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Given a DTFI, get all of the date words from date patterns and time patterns.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ internal String[] GetDateWordsOfDTFI(DateTimeFormatInfo dtfi)
+ {
+ // Enumarate all LongDatePatterns, and get the DateWords and scan for month postfix.
+ String[] datePatterns = dtfi.GetAllDateTimePatterns('D');
+ int i;
+
+ // Scan the long date patterns
+ for (i = 0; i < datePatterns.Length; i++)
+ {
+ ScanDateWord(datePatterns[i]);
+ }
+
+ // Scan the short date patterns
+ datePatterns = dtfi.GetAllDateTimePatterns('d');
+ for (i = 0; i < datePatterns.Length; i++)
+ {
+ ScanDateWord(datePatterns[i]);
+ }
+ // Scan the YearMonth patterns.
+ datePatterns = dtfi.GetAllDateTimePatterns('y');
+ for (i = 0; i < datePatterns.Length; i++)
+ {
+ ScanDateWord(datePatterns[i]);
+ }
+
+ // Scan the month/day pattern
+ ScanDateWord(dtfi.MonthDayPattern);
+
+ // Scan the long time patterns.
+ datePatterns = dtfi.GetAllDateTimePatterns('T');
+ for (i = 0; i < datePatterns.Length; i++)
+ {
+ ScanDateWord(datePatterns[i]);
+ }
+
+ // Scan the short time patterns.
+ datePatterns = dtfi.GetAllDateTimePatterns('t');
+ for (i = 0; i < datePatterns.Length; i++)
+ {
+ ScanDateWord(datePatterns[i]);
+ }
+
+ String[] result = null;
+ if (m_dateWords != null && m_dateWords.Count > 0)
+ {
+ result = new String[m_dateWords.Count];
+ for (i = 0; i < m_dateWords.Count; i++)
+ {
+ result[i] = m_dateWords[i];
+ }
+ }
+ return (result);
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Scan the month names to see if genitive month names are used, and return
+ // the format flag.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+ internal static FORMATFLAGS GetFormatFlagGenitiveMonth(String[] monthNames, String[] genitveMonthNames, String[] abbrevMonthNames, String[] genetiveAbbrevMonthNames)
+ {
+ // If we have different names in regular and genitive month names, use genitive month flag.
+ return ((!EqualStringArrays(monthNames, genitveMonthNames) || !EqualStringArrays(abbrevMonthNames, genetiveAbbrevMonthNames))
+ ? FORMATFLAGS.UseGenitiveMonth : 0);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Scan the month names to see if spaces are used or start with a digit, and return the format flag
+ //
+ ////////////////////////////////////////////////////////////////////////////
+ internal static FORMATFLAGS GetFormatFlagUseSpaceInMonthNames(String[] monthNames, String[] genitveMonthNames, String[] abbrevMonthNames, String[] genetiveAbbrevMonthNames)
+ {
+ FORMATFLAGS formatFlags = 0;
+ formatFlags |= (ArrayElementsBeginWithDigit(monthNames) ||
+ ArrayElementsBeginWithDigit(genitveMonthNames) ||
+ ArrayElementsBeginWithDigit(abbrevMonthNames) ||
+ ArrayElementsBeginWithDigit(genetiveAbbrevMonthNames)
+ ? FORMATFLAGS.UseDigitPrefixInTokens : 0);
+
+ formatFlags |= (ArrayElementsHaveSpace(monthNames) ||
+ ArrayElementsHaveSpace(genitveMonthNames) ||
+ ArrayElementsHaveSpace(abbrevMonthNames) ||
+ ArrayElementsHaveSpace(genetiveAbbrevMonthNames)
+ ? FORMATFLAGS.UseSpacesInMonthNames : 0);
+ return (formatFlags);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Scan the day names and set the correct format flag.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+ internal static FORMATFLAGS GetFormatFlagUseSpaceInDayNames(String[] dayNames, String[] abbrevDayNames)
+ {
+ return ((ArrayElementsHaveSpace(dayNames) ||
+ ArrayElementsHaveSpace(abbrevDayNames))
+ ? FORMATFLAGS.UseSpacesInDayNames : 0);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Check the calendar to see if it is HebrewCalendar and set the Hebrew format flag if necessary.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+ internal static FORMATFLAGS GetFormatFlagUseHebrewCalendar(int calID)
+ {
+ return (calID == (int)CalendarId.HEBREW ?
+ FORMATFLAGS.UseHebrewParsing | FORMATFLAGS.UseLeapYearMonth : 0);
+ }
+
+
+ //-----------------------------------------------------------------------------
+ // EqualStringArrays
+ // compares two string arrays and return true if all elements of the first
+ // array equals to all elmentsof the second array.
+ // otherwise it returns false.
+ //-----------------------------------------------------------------------------
+
+ private static bool EqualStringArrays(string[] array1, string[] array2)
+ {
+ // Shortcut if they're the same array
+ if (array1 == array2)
+ {
+ return true;
+ }
+
+ // This is effectively impossible
+ if (array1.Length != array2.Length)
+ {
+ return false;
+ }
+
+ // Check each string
+ for (int i = 0; i < array1.Length; i++)
+ {
+ if (!array1[i].Equals(array2[i]))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ //-----------------------------------------------------------------------------
+ // ArrayElementsHaveSpace
+ // It checks all input array elements if any of them has space character
+ // returns true if found space character in one of the array elements.
+ // otherwise returns false.
+ //-----------------------------------------------------------------------------
+
+ private static bool ArrayElementsHaveSpace(string[] array)
+ {
+ for (int i = 0; i < array.Length; i++)
+ {
+ // it is faster to check for space character manually instead of calling IndexOf
+ // so we don't have to go to native code side.
+ for (int j = 0; j < array[i].Length; j++)
+ {
+ if (Char.IsWhiteSpace(array[i][j]))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Check if any element of the array start with a digit.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+ private static bool ArrayElementsBeginWithDigit(string[] array)
+ {
+ for (int i = 0; i < array.Length; i++)
+ {
+ // it is faster to check for space character manually instead of calling IndexOf
+ // so we don't have to go to native code side.
+ if (array[i].Length > 0 &&
+ array[i][0] >= '0' && array[i][0] <= '9')
+ {
+ int index = 1;
+ while (index < array[i].Length && array[i][index] >= '0' && array[i][index] <= '9')
+ {
+ // Skip other digits.
+ index++;
+ }
+ if (index == array[i].Length)
+ {
+ return (false);
+ }
+
+ if (index == array[i].Length - 1)
+ {
+ // Skip known CJK month suffix.
+ // CJK uses month name like "1\x6708", since \x6708 is a known month suffix,
+ // we don't need the UseDigitPrefixInTokens since it is slower.
+ switch (array[i][index])
+ {
+ case '\x6708': // CJKMonthSuff
+ case '\xc6d4': // KoreanMonthSuff
+ return (false);
+ }
+ }
+
+ if (index == array[i].Length - 4)
+ {
+ // Skip known CJK month suffix.
+ // Starting with Windows 8, the CJK months for some cultures looks like: "1' \x6708'"
+ // instead of just "1\x6708"
+ if (array[i][index] == '\'' && array[i][index + 1] == ' ' &&
+ array[i][index + 2] == '\x6708' && array[i][index + 3] == '\'')
+ {
+ return (false);
+ }
+ }
+ return (true);
+ }
+ }
+
+ return false;
+ }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Globalization/DateTimeParse.cs b/src/mscorlib/shared/System/Globalization/DateTimeParse.cs
new file mode 100644
index 0000000000..910fbf2ff0
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/DateTimeParse.cs
@@ -0,0 +1,5672 @@
+// 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.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Text;
+
+namespace System
+{
+ internal static class DateTimeParse
+ {
+ internal const Int32 MaxDateTimeNumberDigits = 8;
+
+ internal delegate bool MatchNumberDelegate(ref __DTString str, int digitLen, out int result);
+
+ internal static MatchNumberDelegate m_hebrewNumberParser = new MatchNumberDelegate(DateTimeParse.MatchHebrewDigits);
+
+ internal static DateTime ParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style)
+ {
+ DateTimeResult result = new DateTimeResult(); // The buffer to store the parsing result.
+ result.Init();
+ if (TryParseExact(s, format, dtfi, style, ref result))
+ {
+ return result.parsedDate;
+ }
+ else
+ {
+ throw GetDateTimeParseException(ref result);
+ }
+ }
+
+ internal static DateTime ParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style, out TimeSpan offset)
+ {
+ DateTimeResult result = new DateTimeResult(); // The buffer to store the parsing result.
+ offset = TimeSpan.Zero;
+ result.Init();
+ result.flags |= ParseFlags.CaptureOffset;
+ if (TryParseExact(s, format, dtfi, style, ref result))
+ {
+ offset = result.timeZoneOffset;
+ return result.parsedDate;
+ }
+ else
+ {
+ throw GetDateTimeParseException(ref result);
+ }
+ }
+
+ internal static bool TryParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style, out DateTime result)
+ {
+ result = DateTime.MinValue;
+ DateTimeResult resultData = new DateTimeResult(); // The buffer to store the parsing result.
+ resultData.Init();
+ if (TryParseExact(s, format, dtfi, style, ref resultData))
+ {
+ result = resultData.parsedDate;
+ return true;
+ }
+ return false;
+ }
+
+ internal static bool TryParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style, out DateTime result, out TimeSpan offset)
+ {
+ result = DateTime.MinValue;
+ offset = TimeSpan.Zero;
+ DateTimeResult resultData = new DateTimeResult(); // The buffer to store the parsing result.
+ resultData.Init();
+ resultData.flags |= ParseFlags.CaptureOffset;
+ if (TryParseExact(s, format, dtfi, style, ref resultData))
+ {
+ result = resultData.parsedDate;
+ offset = resultData.timeZoneOffset;
+ return true;
+ }
+ return false;
+ }
+
+ internal static bool TryParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style, ref DateTimeResult result)
+ {
+ if (s == null)
+ {
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(s));
+ return false;
+ }
+ if (format == null)
+ {
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(format));
+ return false;
+ }
+ if (s.Length == 0)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ if (format.Length == 0)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null);
+ return false;
+ }
+
+ Debug.Assert(dtfi != null, "dtfi == null");
+
+ return DoStrictParse(s, format, style, dtfi, ref result);
+ }
+
+ internal static DateTime ParseExactMultiple(String s, String[] formats,
+ DateTimeFormatInfo dtfi, DateTimeStyles style)
+ {
+ DateTimeResult result = new DateTimeResult(); // The buffer to store the parsing result.
+ result.Init();
+ if (TryParseExactMultiple(s, formats, dtfi, style, ref result))
+ {
+ return result.parsedDate;
+ }
+ else
+ {
+ throw GetDateTimeParseException(ref result);
+ }
+ }
+
+
+ internal static DateTime ParseExactMultiple(String s, String[] formats,
+ DateTimeFormatInfo dtfi, DateTimeStyles style, out TimeSpan offset)
+ {
+ DateTimeResult result = new DateTimeResult(); // The buffer to store the parsing result.
+ offset = TimeSpan.Zero;
+ result.Init();
+ result.flags |= ParseFlags.CaptureOffset;
+ if (TryParseExactMultiple(s, formats, dtfi, style, ref result))
+ {
+ offset = result.timeZoneOffset;
+ return result.parsedDate;
+ }
+ else
+ {
+ throw GetDateTimeParseException(ref result);
+ }
+ }
+
+ internal static bool TryParseExactMultiple(String s, String[] formats,
+ DateTimeFormatInfo dtfi, DateTimeStyles style, out DateTime result, out TimeSpan offset)
+ {
+ result = DateTime.MinValue;
+ offset = TimeSpan.Zero;
+ DateTimeResult resultData = new DateTimeResult(); // The buffer to store the parsing result.
+ resultData.Init();
+ resultData.flags |= ParseFlags.CaptureOffset;
+ if (TryParseExactMultiple(s, formats, dtfi, style, ref resultData))
+ {
+ result = resultData.parsedDate;
+ offset = resultData.timeZoneOffset;
+ return true;
+ }
+ return false;
+ }
+
+
+ internal static bool TryParseExactMultiple(String s, String[] formats,
+ DateTimeFormatInfo dtfi, DateTimeStyles style, out DateTime result)
+ {
+ result = DateTime.MinValue;
+ DateTimeResult resultData = new DateTimeResult(); // The buffer to store the parsing result.
+ resultData.Init();
+ if (TryParseExactMultiple(s, formats, dtfi, style, ref resultData))
+ {
+ result = resultData.parsedDate;
+ return true;
+ }
+ return false;
+ }
+
+ internal static bool TryParseExactMultiple(String s, String[] formats,
+ DateTimeFormatInfo dtfi, DateTimeStyles style, ref DateTimeResult result)
+ {
+ if (s == null)
+ {
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(s));
+ return false;
+ }
+ if (formats == null)
+ {
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(formats));
+ return false;
+ }
+
+ if (s.Length == 0)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ if (formats.Length == 0)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null);
+ return false;
+ }
+
+ Debug.Assert(dtfi != null, "dtfi == null");
+
+ //
+ // Do a loop through the provided formats and see if we can parse succesfully in
+ // one of the formats.
+ //
+ for (int i = 0; i < formats.Length; i++)
+ {
+ if (formats[i] == null || formats[i].Length == 0)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null);
+ return false;
+ }
+ // Create a new result each time to ensure the runs are independent. Carry through
+ // flags from the caller and return the result.
+ DateTimeResult innerResult = new DateTimeResult(); // The buffer to store the parsing result.
+ innerResult.Init();
+ innerResult.flags = result.flags;
+ if (TryParseExact(s, formats[i], dtfi, style, ref innerResult))
+ {
+ result.parsedDate = innerResult.parsedDate;
+ result.timeZoneOffset = innerResult.timeZoneOffset;
+ return (true);
+ }
+ }
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Date Token Types
+ //
+ // Following is the set of tokens that can be generated from a date
+ // string. Notice that the legal set of trailing separators have been
+ // folded in with the date number, and month name tokens. This set
+ // of tokens is chosen to reduce the number of date parse states.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ internal enum DTT : int
+ {
+ End = 0, // '\0'
+ NumEnd = 1, // Num[ ]*[\0]
+ NumAmpm = 2, // Num[ ]+AmPm
+ NumSpace = 3, // Num[ ]+^[Dsep|Tsep|'0\']
+ NumDatesep = 4, // Num[ ]*Dsep
+ NumTimesep = 5, // Num[ ]*Tsep
+ MonthEnd = 6, // Month[ ]*'\0'
+ MonthSpace = 7, // Month[ ]+^[Dsep|Tsep|'\0']
+ MonthDatesep = 8, // Month[ ]*Dsep
+ NumDatesuff = 9, // Month[ ]*DSuff
+ NumTimesuff = 10, // Month[ ]*TSuff
+ DayOfWeek = 11, // Day of week name
+ YearSpace = 12, // Year+^[Dsep|Tsep|'0\']
+ YearDateSep = 13, // Year+Dsep
+ YearEnd = 14, // Year+['\0']
+ TimeZone = 15, // timezone name
+ Era = 16, // era name
+ NumUTCTimeMark = 17, // Num + 'Z'
+ // When you add a new token which will be in the
+ // state table, add it after NumLocalTimeMark.
+ Unk = 18, // unknown
+ NumLocalTimeMark = 19, // Num + 'T'
+ Max = 20, // marker
+ }
+
+ internal enum TM
+ {
+ NotSet = -1,
+ AM = 0,
+ PM = 1,
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // DateTime parsing state enumeration (DS.*)
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ internal enum DS
+ {
+ BEGIN = 0,
+ N = 1, // have one number
+ NN = 2, // have two numbers
+
+ // The following are known to be part of a date
+
+ D_Nd = 3, // date string: have number followed by date separator
+ D_NN = 4, // date string: have two numbers
+ D_NNd = 5, // date string: have two numbers followed by date separator
+
+ D_M = 6, // date string: have a month
+ D_MN = 7, // date string: have a month and a number
+ D_NM = 8, // date string: have a number and a month
+ D_MNd = 9, // date string: have a month and number followed by date separator
+ D_NDS = 10, // date string: have one number followed a date suffix.
+
+ D_Y = 11, // date string: have a year.
+ D_YN = 12, // date string: have a year and a number
+ D_YNd = 13, // date string: have a year and a number and a date separator
+ D_YM = 14, // date string: have a year and a month
+ D_YMd = 15, // date string: have a year and a month and a date separator
+ D_S = 16, // have numbers followed by a date suffix.
+ T_S = 17, // have numbers followed by a time suffix.
+
+ // The following are known to be part of a time
+
+ T_Nt = 18, // have num followed by time separator
+ T_NNt = 19, // have two numbers followed by time separator
+
+
+ ERROR = 20,
+
+ // The following are terminal states. These all have an action
+ // associated with them; and transition back to BEGIN.
+
+ DX_NN = 21, // day from two numbers
+ DX_NNN = 22, // day from three numbers
+ DX_MN = 23, // day from month and one number
+ DX_NM = 24, // day from month and one number
+ DX_MNN = 25, // day from month and two numbers
+ DX_DS = 26, // a set of date suffixed numbers.
+ DX_DSN = 27, // day from date suffixes and one number.
+ DX_NDS = 28, // day from one number and date suffixes .
+ DX_NNDS = 29, // day from one number and date suffixes .
+
+ DX_YNN = 30, // date string: have a year and two number
+ DX_YMN = 31, // date string: have a year, a month, and a number.
+ DX_YN = 32, // date string: have a year and one number
+ DX_YM = 33, // date string: have a year, a month.
+ TX_N = 34, // time from one number (must have ampm)
+ TX_NN = 35, // time from two numbers
+ TX_NNN = 36, // time from three numbers
+ TX_TS = 37, // a set of time suffixed numbers.
+ DX_NNY = 38,
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // NOTE: The following state machine table is dependent on the order of the
+ // DS and DTT enumerations.
+ //
+ // For each non terminal state, the following table defines the next state
+ // for each given date token type.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ // End NumEnd NumAmPm NumSpace NumDaySep NumTimesep MonthEnd MonthSpace MonthDSep NumDateSuff NumTimeSuff DayOfWeek YearSpace YearDateSep YearEnd TimeZone Era UTCTimeMark
+ private static DS[][] dateParsingStates = {
+// DS.BEGIN // DS.BEGIN
+new DS[] { DS.BEGIN, DS.ERROR, DS.TX_N, DS.N, DS.D_Nd, DS.T_Nt, DS.ERROR, DS.D_M, DS.D_M, DS.D_S, DS.T_S, DS.BEGIN, DS.D_Y, DS.D_Y, DS.ERROR, DS.BEGIN, DS.BEGIN, DS.ERROR},
+
+// DS.N // DS.N
+new DS[] { DS.ERROR, DS.DX_NN, DS.ERROR, DS.NN, DS.D_NNd, DS.ERROR, DS.DX_NM, DS.D_NM, DS.D_MNd, DS.D_NDS, DS.ERROR, DS.N, DS.D_YN, DS.D_YNd, DS.DX_YN, DS.N, DS.N, DS.ERROR},
+
+// DS.NN // DS.NN
+new DS[] { DS.DX_NN, DS.DX_NNN, DS.TX_N, DS.DX_NNN, DS.ERROR, DS.T_Nt, DS.DX_MNN, DS.DX_MNN, DS.ERROR, DS.ERROR, DS.T_S, DS.NN, DS.DX_NNY, DS.ERROR, DS.DX_NNY, DS.NN, DS.NN, DS.ERROR},
+
+// DS.D_Nd // DS.D_Nd
+new DS[] { DS.ERROR, DS.DX_NN, DS.ERROR, DS.D_NN, DS.D_NNd, DS.ERROR, DS.DX_NM, DS.D_MN, DS.D_MNd, DS.ERROR, DS.ERROR, DS.D_Nd, DS.D_YN, DS.D_YNd, DS.DX_YN, DS.ERROR, DS.D_Nd, DS.ERROR},
+
+// DS.D_NN // DS.D_NN
+new DS[] { DS.DX_NN, DS.DX_NNN, DS.TX_N, DS.DX_NNN, DS.ERROR, DS.T_Nt, DS.DX_MNN, DS.DX_MNN, DS.ERROR, DS.DX_DS, DS.T_S, DS.D_NN, DS.DX_NNY, DS.ERROR, DS.DX_NNY, DS.ERROR, DS.D_NN, DS.ERROR},
+
+// DS.D_NNd // DS.D_NNd
+new DS[] { DS.ERROR, DS.DX_NNN, DS.DX_NNN, DS.DX_NNN, DS.ERROR, DS.ERROR, DS.DX_MNN, DS.DX_MNN, DS.ERROR, DS.DX_DS, DS.ERROR, DS.D_NNd, DS.DX_NNY, DS.ERROR, DS.DX_NNY, DS.ERROR, DS.D_NNd, DS.ERROR},
+
+// DS.D_M // DS.D_M
+new DS[] { DS.ERROR, DS.DX_MN, DS.ERROR, DS.D_MN, DS.D_MNd, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_M, DS.D_YM, DS.D_YMd, DS.DX_YM, DS.ERROR, DS.D_M, DS.ERROR},
+
+// DS.D_MN // DS.D_MN
+new DS[] { DS.DX_MN, DS.DX_MNN, DS.DX_MNN, DS.DX_MNN, DS.ERROR, DS.T_Nt, DS.ERROR, DS.ERROR, DS.ERROR, DS.DX_DS, DS.T_S, DS.D_MN, DS.DX_YMN, DS.ERROR, DS.DX_YMN, DS.ERROR, DS.D_MN, DS.ERROR},
+
+// DS.D_NM // DS.D_NM
+new DS[] { DS.DX_NM, DS.DX_MNN, DS.DX_MNN, DS.DX_MNN, DS.ERROR, DS.T_Nt, DS.ERROR, DS.ERROR, DS.ERROR, DS.DX_DS, DS.T_S, DS.D_NM, DS.DX_YMN, DS.ERROR, DS.DX_YMN, DS.ERROR, DS.D_NM, DS.ERROR},
+
+// DS.D_MNd // DS.D_MNd
+new DS[] { DS.ERROR, DS.DX_MNN, DS.ERROR, DS.DX_MNN, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_MNd, DS.DX_YMN, DS.ERROR, DS.DX_YMN, DS.ERROR, DS.D_MNd, DS.ERROR},
+
+// DS.D_NDS, // DS.D_NDS,
+new DS[] { DS.DX_NDS,DS.DX_NNDS, DS.DX_NNDS, DS.DX_NNDS, DS.ERROR, DS.T_Nt, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_NDS, DS.T_S, DS.D_NDS, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_NDS, DS.ERROR},
+
+// DS.D_Y // DS.D_Y
+new DS[] { DS.ERROR, DS.DX_YN, DS.ERROR, DS.D_YN, DS.D_YNd, DS.ERROR, DS.DX_YM, DS.D_YM, DS.D_YMd, DS.D_YM, DS.ERROR, DS.D_Y, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_Y, DS.ERROR},
+
+// DS.D_YN // DS.D_YN
+new DS[] { DS.DX_YN, DS.DX_YNN, DS.DX_YNN, DS.DX_YNN, DS.ERROR, DS.ERROR, DS.DX_YMN, DS.DX_YMN, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YN, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YN, DS.ERROR},
+
+// DS.D_YNd // DS.D_YNd
+new DS[] { DS.ERROR, DS.DX_YNN, DS.DX_YNN, DS.DX_YNN, DS.ERROR, DS.ERROR, DS.DX_YMN, DS.DX_YMN, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YN, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YN, DS.ERROR},
+
+// DS.D_YM // DS.D_YM
+new DS[] { DS.DX_YM, DS.DX_YMN, DS.DX_YMN, DS.DX_YMN, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YM, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YM, DS.ERROR},
+
+// DS.D_YMd // DS.D_YMd
+new DS[] { DS.ERROR, DS.DX_YMN, DS.DX_YMN, DS.DX_YMN, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YM, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YM, DS.ERROR},
+
+// DS.D_S // DS.D_S
+new DS[] { DS.DX_DS, DS.DX_DSN, DS.TX_N, DS.T_Nt, DS.ERROR, DS.T_Nt, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_S, DS.T_S, DS.D_S, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_S, DS.ERROR},
+
+// DS.T_S // DS.T_S
+new DS[] { DS.TX_TS, DS.TX_TS, DS.TX_TS, DS.T_Nt, DS.D_Nd, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_S, DS.T_S, DS.T_S, DS.ERROR, DS.ERROR, DS.ERROR, DS.T_S, DS.T_S, DS.ERROR},
+
+// DS.T_Nt // DS.T_Nt
+new DS[] { DS.ERROR, DS.TX_NN, DS.TX_NN, DS.TX_NN, DS.ERROR, DS.T_NNt, DS.DX_NM, DS.D_NM, DS.ERROR, DS.ERROR, DS.T_S, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.T_Nt, DS.T_Nt, DS.TX_NN},
+
+// DS.T_NNt // DS.T_NNt
+new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.T_S, DS.T_NNt, DS.ERROR, DS.ERROR, DS.ERROR, DS.T_NNt, DS.T_NNt, DS.TX_NNN},
+};
+ // End NumEnd NumAmPm NumSpace NumDaySep NumTimesep MonthEnd MonthSpace MonthDSep NumDateSuff NumTimeSuff DayOfWeek YearSpace YearDateSep YearEnd TimeZone Era UTCMark
+
+ internal const String GMTName = "GMT";
+ internal const String ZuluName = "Z";
+
+ //
+ // Search from the index of str at str.Index to see if the target string exists in the str.
+ //
+ private static bool MatchWord(ref __DTString str, String target)
+ {
+ int length = target.Length;
+ if (length > (str.Value.Length - str.Index))
+ {
+ return false;
+ }
+
+ if (str.CompareInfo.Compare(str.Value, str.Index, length,
+ target, 0, length, CompareOptions.IgnoreCase) != 0)
+ {
+ return (false);
+ }
+
+ int nextCharIndex = str.Index + target.Length;
+
+ if (nextCharIndex < str.Value.Length)
+ {
+ char nextCh = str.Value[nextCharIndex];
+ if (Char.IsLetter(nextCh))
+ {
+ return (false);
+ }
+ }
+ str.Index = nextCharIndex;
+ if (str.Index < str.len)
+ {
+ str.m_current = str.Value[str.Index];
+ }
+
+ return (true);
+ }
+
+
+ //
+ // Check the word at the current index to see if it matches GMT name or Zulu name.
+ //
+ private static bool GetTimeZoneName(ref __DTString str)
+ {
+ if (MatchWord(ref str, GMTName))
+ {
+ return (true);
+ }
+
+ if (MatchWord(ref str, ZuluName))
+ {
+ return (true);
+ }
+
+ return (false);
+ }
+
+ internal static bool IsDigit(char ch)
+ {
+ return (ch >= '0' && ch <= '9');
+ }
+
+
+ /*=================================ParseFraction==========================
+ **Action: Starting at the str.Index, which should be a decimal symbol.
+ ** if the current character is a digit, parse the remaining
+ ** numbers as fraction. For example, if the sub-string starting at str.Index is "123", then
+ ** the method will return 0.123
+ **Returns: The fraction number.
+ **Arguments:
+ ** str the parsing string
+ **Exceptions:
+ ============================================================================*/
+
+ private static bool ParseFraction(ref __DTString str, out double result)
+ {
+ result = 0;
+ double decimalBase = 0.1;
+ int digits = 0;
+ char ch;
+ while (str.GetNext()
+ && IsDigit(ch = str.m_current))
+ {
+ result += (ch - '0') * decimalBase;
+ decimalBase *= 0.1;
+ digits++;
+ }
+ return (digits > 0);
+ }
+
+ /*=================================ParseTimeZone==========================
+ **Action: Parse the timezone offset in the following format:
+ ** "+8", "+08", "+0800", "+0800"
+ ** This method is used by DateTime.Parse().
+ **Returns: The TimeZone offset.
+ **Arguments:
+ ** str the parsing string
+ **Exceptions:
+ ** FormatException if invalid timezone format is found.
+ ============================================================================*/
+
+ private static bool ParseTimeZone(ref __DTString str, ref TimeSpan result)
+ {
+ // The hour/minute offset for timezone.
+ int hourOffset = 0;
+ int minuteOffset = 0;
+ DTSubString sub;
+
+ // Consume the +/- character that has already been read
+ sub = str.GetSubString();
+ if (sub.length != 1)
+ {
+ return false;
+ }
+ char offsetChar = sub[0];
+ if (offsetChar != '+' && offsetChar != '-')
+ {
+ return false;
+ }
+ str.ConsumeSubString(sub);
+
+ sub = str.GetSubString();
+ if (sub.type != DTSubStringType.Number)
+ {
+ return false;
+ }
+ int value = sub.value;
+ int length = sub.length;
+ if (length == 1 || length == 2)
+ {
+ // Parsing "+8" or "+08"
+ hourOffset = value;
+ str.ConsumeSubString(sub);
+ // See if we have minutes
+ sub = str.GetSubString();
+ if (sub.length == 1 && sub[0] == ':')
+ {
+ // Parsing "+8:00" or "+08:00"
+ str.ConsumeSubString(sub);
+ sub = str.GetSubString();
+ if (sub.type != DTSubStringType.Number || sub.length < 1 || sub.length > 2)
+ {
+ return false;
+ }
+ minuteOffset = sub.value;
+ str.ConsumeSubString(sub);
+ }
+ }
+ else if (length == 3 || length == 4)
+ {
+ // Parsing "+800" or "+0800"
+ hourOffset = value / 100;
+ minuteOffset = value % 100;
+ str.ConsumeSubString(sub);
+ }
+ else
+ {
+ // Wrong number of digits
+ return false;
+ }
+ Debug.Assert(hourOffset >= 0 && hourOffset <= 99, "hourOffset >= 0 && hourOffset <= 99");
+ Debug.Assert(minuteOffset >= 0 && minuteOffset <= 99, "minuteOffset >= 0 && minuteOffset <= 99");
+ if (minuteOffset < 0 || minuteOffset >= 60)
+ {
+ return false;
+ }
+
+ result = new TimeSpan(hourOffset, minuteOffset, 0);
+ if (offsetChar == '-')
+ {
+ result = result.Negate();
+ }
+ return true;
+ }
+
+ // This is the helper function to handle timezone in string in the format like +/-0800
+ private static bool HandleTimeZone(ref __DTString str, ref DateTimeResult result)
+ {
+ if ((str.Index < str.len - 1))
+ {
+ char nextCh = str.Value[str.Index];
+ // Skip whitespace, but don't update the index unless we find a time zone marker
+ int whitespaceCount = 0;
+ while (Char.IsWhiteSpace(nextCh) && str.Index + whitespaceCount < str.len - 1)
+ {
+ whitespaceCount++;
+ nextCh = str.Value[str.Index + whitespaceCount];
+ }
+ if (nextCh == '+' || nextCh == '-')
+ {
+ str.Index += whitespaceCount;
+ if ((result.flags & ParseFlags.TimeZoneUsed) != 0)
+ {
+ // Should not have two timezone offsets.
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ result.flags |= ParseFlags.TimeZoneUsed;
+ if (!ParseTimeZone(ref str, ref result.timeZoneOffset))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ //
+ // This is the lexer. Check the character at the current index, and put the found token in dtok and
+ // some raw date/time information in raw.
+ //
+ private static Boolean Lex(DS dps, ref __DTString str, ref DateTimeToken dtok, ref DateTimeRawInfo raw, ref DateTimeResult result, ref DateTimeFormatInfo dtfi, DateTimeStyles styles)
+ {
+ TokenType tokenType;
+ int tokenValue;
+ int indexBeforeSeparator;
+ char charBeforeSeparator;
+
+ TokenType sep;
+ dtok.dtt = DTT.Unk; // Assume the token is unkown.
+
+ str.GetRegularToken(out tokenType, out tokenValue, dtfi);
+
+#if _LOGGING
+ // Builds with _LOGGING defined (x86dbg, amd64chk, etc) support tracing
+ // Set the following internal-only/unsupported environment variables to enable DateTime tracing to the console:
+ //
+ // COMPlus_LogEnable=1
+ // COMPlus_LogToConsole=1
+ // COMPlus_LogLevel=9
+ // COMPlus_ManagedLogFacility=0x00001000
+ if (_tracingEnabled)
+ {
+ BCLDebug.Trace("DATETIME", "[DATETIME] Lex({0})\tpos:{1}({2}), {3}, DS.{4}", Hex(str.Value),
+ str.Index, Hex(str.m_current), tokenType, dps);
+ }
+#endif // _LOGGING
+
+ // Look at the regular token.
+ switch (tokenType)
+ {
+ case TokenType.NumberToken:
+ case TokenType.YearNumberToken:
+ if (raw.numCount == 3 || tokenValue == -1)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0010", dps);
+ return false;
+ }
+ //
+ // This is a digit.
+ //
+ // If the previous parsing state is DS.T_NNt (like 12:01), and we got another number,
+ // so we will have a terminal state DS.TX_NNN (like 12:01:02).
+ // If the previous parsing state is DS.T_Nt (like 12:), and we got another number,
+ // so we will have a terminal state DS.TX_NN (like 12:01).
+ //
+ // Look ahead to see if the following character is a decimal point or timezone offset.
+ // This enables us to parse time in the forms of:
+ // "11:22:33.1234" or "11:22:33-08".
+ if (dps == DS.T_NNt)
+ {
+ if ((str.Index < str.len - 1))
+ {
+ char nextCh = str.Value[str.Index];
+ if (nextCh == '.')
+ {
+ // While ParseFraction can fail, it just means that there were no digits after
+ // the dot. In this case ParseFraction just removes the dot. This is actually
+ // valid for cultures like Albanian, that join the time marker to the time with
+ // with a dot: e.g. "9:03.MD"
+ ParseFraction(ref str, out raw.fraction);
+ }
+ }
+ }
+ if (dps == DS.T_NNt || dps == DS.T_Nt)
+ {
+ if ((str.Index < str.len - 1))
+ {
+ if (false == HandleTimeZone(ref str, ref result))
+ {
+ LexTraceExit("0020 (value like \"12:01\" or \"12:\" followed by a non-TZ number", dps);
+ return false;
+ }
+ }
+ }
+
+ dtok.num = tokenValue;
+ if (tokenType == TokenType.YearNumberToken)
+ {
+ if (raw.year == -1)
+ {
+ raw.year = tokenValue;
+ //
+ // If we have number which has 3 or more digits (like "001" or "0001"),
+ // we assume this number is a year. Save the currnet raw.numCount in
+ // raw.year.
+ //
+ switch (sep = str.GetSeparatorToken(dtfi, out indexBeforeSeparator, out charBeforeSeparator))
+ {
+ case TokenType.SEP_End:
+ dtok.dtt = DTT.YearEnd;
+ break;
+ case TokenType.SEP_Am:
+ case TokenType.SEP_Pm:
+ if (raw.timeMark == TM.NotSet)
+ {
+ raw.timeMark = (sep == TokenType.SEP_Am ? TM.AM : TM.PM);
+ dtok.dtt = DTT.YearSpace;
+ }
+ else
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0030 (TM.AM/TM.PM Happened more than 1x)", dps);
+ }
+ break;
+ case TokenType.SEP_Space:
+ dtok.dtt = DTT.YearSpace;
+ break;
+ case TokenType.SEP_Date:
+ dtok.dtt = DTT.YearDateSep;
+ break;
+ case TokenType.SEP_Time:
+ if (!raw.hasSameDateAndTimeSeparators)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0040 (Invalid separator after number)", dps);
+ return false;
+ }
+
+ // we have the date and time separators are same and getting a year number, then change the token to YearDateSep as
+ // we are sure we are not parsing time.
+ dtok.dtt = DTT.YearDateSep;
+ break;
+ case TokenType.SEP_DateOrOffset:
+ // The separator is either a date separator or the start of a time zone offset. If the token will complete the date then
+ // process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset.
+ if ((dateParsingStates[(int)dps][(int)DTT.YearDateSep] == DS.ERROR)
+ && (dateParsingStates[(int)dps][(int)DTT.YearSpace] > DS.ERROR))
+ {
+ str.Index = indexBeforeSeparator;
+ str.m_current = charBeforeSeparator;
+ dtok.dtt = DTT.YearSpace;
+ }
+ else
+ {
+ dtok.dtt = DTT.YearDateSep;
+ }
+ break;
+ case TokenType.SEP_YearSuff:
+ case TokenType.SEP_MonthSuff:
+ case TokenType.SEP_DaySuff:
+ dtok.dtt = DTT.NumDatesuff;
+ dtok.suffix = sep;
+ break;
+ case TokenType.SEP_HourSuff:
+ case TokenType.SEP_MinuteSuff:
+ case TokenType.SEP_SecondSuff:
+ dtok.dtt = DTT.NumTimesuff;
+ dtok.suffix = sep;
+ break;
+ default:
+ // Invalid separator after number number.
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0040 (Invalid separator after number)", dps);
+ return false;
+ }
+ //
+ // Found the token already. Return now.
+ //
+ LexTraceExit("0050 (success)", dps);
+ return true;
+ }
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0060", dps);
+ return false;
+ }
+ switch (sep = str.GetSeparatorToken(dtfi, out indexBeforeSeparator, out charBeforeSeparator))
+ {
+ //
+ // Note here we check if the numCount is less than three.
+ // When we have more than three numbers, it will be caught as error in the state machine.
+ //
+ case TokenType.SEP_End:
+ dtok.dtt = DTT.NumEnd;
+ raw.AddNumber(dtok.num);
+ break;
+ case TokenType.SEP_Am:
+ case TokenType.SEP_Pm:
+ if (raw.timeMark == TM.NotSet)
+ {
+ raw.timeMark = (sep == TokenType.SEP_Am ? TM.AM : TM.PM);
+ dtok.dtt = DTT.NumAmpm;
+ // Fix AM/PM parsing case, e.g. "1/10 5 AM"
+ if (dps == DS.D_NN)
+ {
+ if (!ProcessTerminaltState(DS.DX_NN, ref result, ref styles, ref raw, dtfi))
+ {
+ return false;
+ }
+ }
+
+ raw.AddNumber(dtok.num);
+ }
+ else
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ break;
+ }
+ if (dps == DS.T_NNt || dps == DS.T_Nt)
+ {
+ if (false == HandleTimeZone(ref str, ref result))
+ {
+ LexTraceExit("0070 (HandleTimeZone returned false)", dps);
+ return false;
+ }
+ }
+ break;
+ case TokenType.SEP_Space:
+ dtok.dtt = DTT.NumSpace;
+ raw.AddNumber(dtok.num);
+ break;
+ case TokenType.SEP_Date:
+ dtok.dtt = DTT.NumDatesep;
+ raw.AddNumber(dtok.num);
+ break;
+ case TokenType.SEP_DateOrOffset:
+ // The separator is either a date separator or the start of a time zone offset. If the token will complete the date then
+ // process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset.
+ if ((dateParsingStates[(int)dps][(int)DTT.NumDatesep] == DS.ERROR)
+ && (dateParsingStates[(int)dps][(int)DTT.NumSpace] > DS.ERROR))
+ {
+ str.Index = indexBeforeSeparator;
+ str.m_current = charBeforeSeparator;
+ dtok.dtt = DTT.NumSpace;
+ }
+ else
+ {
+ dtok.dtt = DTT.NumDatesep;
+ }
+ raw.AddNumber(dtok.num);
+ break;
+ case TokenType.SEP_Time:
+ if (raw.hasSameDateAndTimeSeparators &&
+ (dps == DS.D_Y || dps == DS.D_YN || dps == DS.D_YNd || dps == DS.D_YM || dps == DS.D_YMd))
+ {
+ // we are parsing a date and we have the time separator same as date separator, so we mark the token as date separator
+ dtok.dtt = DTT.NumDatesep;
+ raw.AddNumber(dtok.num);
+ break;
+ }
+ dtok.dtt = DTT.NumTimesep;
+ raw.AddNumber(dtok.num);
+ break;
+ case TokenType.SEP_YearSuff:
+ try
+ {
+ dtok.num = dtfi.Calendar.ToFourDigitYear(tokenValue);
+ }
+ catch (ArgumentOutOfRangeException e)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", e);
+ LexTraceExit("0075 (Calendar.ToFourDigitYear failed)", dps);
+ return false;
+ }
+ dtok.dtt = DTT.NumDatesuff;
+ dtok.suffix = sep;
+ break;
+ case TokenType.SEP_MonthSuff:
+ case TokenType.SEP_DaySuff:
+ dtok.dtt = DTT.NumDatesuff;
+ dtok.suffix = sep;
+ break;
+ case TokenType.SEP_HourSuff:
+ case TokenType.SEP_MinuteSuff:
+ case TokenType.SEP_SecondSuff:
+ dtok.dtt = DTT.NumTimesuff;
+ dtok.suffix = sep;
+ break;
+ case TokenType.SEP_LocalTimeMark:
+ dtok.dtt = DTT.NumLocalTimeMark;
+ raw.AddNumber(dtok.num);
+ break;
+ default:
+ // Invalid separator after number number.
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0080", dps);
+ return false;
+ }
+ break;
+ case TokenType.HebrewNumber:
+ if (tokenValue >= 100)
+ {
+ // This is a year number
+ if (raw.year == -1)
+ {
+ raw.year = tokenValue;
+ //
+ // If we have number which has 3 or more digits (like "001" or "0001"),
+ // we assume this number is a year. Save the currnet raw.numCount in
+ // raw.year.
+ //
+ switch (sep = str.GetSeparatorToken(dtfi, out indexBeforeSeparator, out charBeforeSeparator))
+ {
+ case TokenType.SEP_End:
+ dtok.dtt = DTT.YearEnd;
+ break;
+ case TokenType.SEP_Space:
+ dtok.dtt = DTT.YearSpace;
+ break;
+ case TokenType.SEP_DateOrOffset:
+ // The separator is either a date separator or the start of a time zone offset. If the token will complete the date then
+ // process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset.
+ if (dateParsingStates[(int)dps][(int)DTT.YearSpace] > DS.ERROR)
+ {
+ str.Index = indexBeforeSeparator;
+ str.m_current = charBeforeSeparator;
+ dtok.dtt = DTT.YearSpace;
+ break;
+ }
+ goto default;
+ default:
+ // Invalid separator after number number.
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0090", dps);
+ return false;
+ }
+ }
+ else
+ {
+ // Invalid separator after number number.
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0100", dps);
+ return false;
+ }
+ }
+ else
+ {
+ // This is a day number
+ dtok.num = tokenValue;
+ raw.AddNumber(dtok.num);
+
+ switch (sep = str.GetSeparatorToken(dtfi, out indexBeforeSeparator, out charBeforeSeparator))
+ {
+ //
+ // Note here we check if the numCount is less than three.
+ // When we have more than three numbers, it will be caught as error in the state machine.
+ //
+ case TokenType.SEP_End:
+ dtok.dtt = DTT.NumEnd;
+ break;
+ case TokenType.SEP_Space:
+ case TokenType.SEP_Date:
+ dtok.dtt = DTT.NumDatesep;
+ break;
+ case TokenType.SEP_DateOrOffset:
+ // The separator is either a date separator or the start of a time zone offset. If the token will complete the date then
+ // process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset.
+ if ((dateParsingStates[(int)dps][(int)DTT.NumDatesep] == DS.ERROR)
+ && (dateParsingStates[(int)dps][(int)DTT.NumSpace] > DS.ERROR))
+ {
+ str.Index = indexBeforeSeparator;
+ str.m_current = charBeforeSeparator;
+ dtok.dtt = DTT.NumSpace;
+ }
+ else
+ {
+ dtok.dtt = DTT.NumDatesep;
+ }
+ break;
+ default:
+ // Invalid separator after number number.
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0110", dps);
+ return false;
+ }
+ }
+ break;
+ case TokenType.DayOfWeekToken:
+ if (raw.dayOfWeek == -1)
+ {
+ //
+ // This is a day of week name.
+ //
+ raw.dayOfWeek = tokenValue;
+ dtok.dtt = DTT.DayOfWeek;
+ }
+ else
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0120 (DayOfWeek seen more than 1x)", dps);
+ return false;
+ }
+ break;
+ case TokenType.MonthToken:
+ if (raw.month == -1)
+ {
+ //
+ // This is a month name
+ //
+ switch (sep = str.GetSeparatorToken(dtfi, out indexBeforeSeparator, out charBeforeSeparator))
+ {
+ case TokenType.SEP_End:
+ dtok.dtt = DTT.MonthEnd;
+ break;
+ case TokenType.SEP_Space:
+ dtok.dtt = DTT.MonthSpace;
+ break;
+ case TokenType.SEP_Date:
+ dtok.dtt = DTT.MonthDatesep;
+ break;
+ case TokenType.SEP_Time:
+ if (!raw.hasSameDateAndTimeSeparators)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0130 (Invalid separator after month name)", dps);
+ return false;
+ }
+
+ // we have the date and time separators are same and getting a Month name, then change the token to MonthDatesep as
+ // we are sure we are not parsing time.
+ dtok.dtt = DTT.MonthDatesep;
+ break;
+ case TokenType.SEP_DateOrOffset:
+ // The separator is either a date separator or the start of a time zone offset. If the token will complete the date then
+ // process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset.
+ if ((dateParsingStates[(int)dps][(int)DTT.MonthDatesep] == DS.ERROR)
+ && (dateParsingStates[(int)dps][(int)DTT.MonthSpace] > DS.ERROR))
+ {
+ str.Index = indexBeforeSeparator;
+ str.m_current = charBeforeSeparator;
+ dtok.dtt = DTT.MonthSpace;
+ }
+ else
+ {
+ dtok.dtt = DTT.MonthDatesep;
+ }
+ break;
+ default:
+ //Invalid separator after month name
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0130 (Invalid separator after month name)", dps);
+ return false;
+ }
+ raw.month = tokenValue;
+ }
+ else
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0140 (MonthToken seen more than 1x)", dps);
+ return false;
+ }
+ break;
+ case TokenType.EraToken:
+ if (result.era != -1)
+ {
+ result.era = tokenValue;
+ dtok.dtt = DTT.Era;
+ }
+ else
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0150 (EraToken seen when result.era already set)", dps);
+ return false;
+ }
+ break;
+ case TokenType.JapaneseEraToken:
+ // Special case for Japanese. We allow Japanese era name to be used even if the calendar is not Japanese Calendar.
+ result.calendar = JapaneseCalendar.GetDefaultInstance();
+ dtfi = DateTimeFormatInfo.GetJapaneseCalendarDTFI();
+ if (result.era != -1)
+ {
+ result.era = tokenValue;
+ dtok.dtt = DTT.Era;
+ }
+ else
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0160 (JapaneseEraToken seen when result.era already set)", dps);
+ return false;
+ }
+ break;
+ case TokenType.TEraToken:
+ result.calendar = TaiwanCalendar.GetDefaultInstance();
+ dtfi = DateTimeFormatInfo.GetTaiwanCalendarDTFI();
+ if (result.era != -1)
+ {
+ result.era = tokenValue;
+ dtok.dtt = DTT.Era;
+ }
+ else
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0170 (TEraToken seen when result.era already set)", dps);
+ return false;
+ }
+ break;
+ case TokenType.TimeZoneToken:
+ //
+ // This is a timezone designator
+ //
+ // NOTENOTE : for now, we only support "GMT" and "Z" (for Zulu time).
+ //
+ if ((result.flags & ParseFlags.TimeZoneUsed) != 0)
+ {
+ // Should not have two timezone offsets.
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0180 (seen GMT or Z more than 1x)", dps);
+ return false;
+ }
+ dtok.dtt = DTT.TimeZone;
+ result.flags |= ParseFlags.TimeZoneUsed;
+ result.timeZoneOffset = new TimeSpan(0);
+ result.flags |= ParseFlags.TimeZoneUtc;
+ break;
+ case TokenType.EndOfString:
+ dtok.dtt = DTT.End;
+ break;
+ case TokenType.DateWordToken:
+ case TokenType.IgnorableSymbol:
+ // Date words and ignorable symbols can just be skipped over
+ break;
+ case TokenType.Am:
+ case TokenType.Pm:
+ if (raw.timeMark == TM.NotSet)
+ {
+ raw.timeMark = (TM)tokenValue;
+ }
+ else
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0190 (AM/PM timeMark already set)", dps);
+ return false;
+ }
+ break;
+ case TokenType.UnknownToken:
+ if (Char.IsLetter(str.m_current))
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_UnknowDateTimeWord", str.Index);
+ LexTraceExit("0200", dps);
+ return (false);
+ }
+
+ if ((str.m_current == '-' || str.m_current == '+') && ((result.flags & ParseFlags.TimeZoneUsed) == 0))
+ {
+ Int32 originalIndex = str.Index;
+ if (ParseTimeZone(ref str, ref result.timeZoneOffset))
+ {
+ result.flags |= ParseFlags.TimeZoneUsed;
+ LexTraceExit("0220 (success)", dps);
+ return true;
+ }
+ else
+ {
+ // Time zone parse attempt failed. Fall through to punctuation handling.
+ str.Index = originalIndex;
+ }
+ }
+
+ // Visual Basic implements string to date conversions on top of DateTime.Parse:
+ // CDate("#10/10/95#")
+ //
+ if (VerifyValidPunctuation(ref str))
+ {
+ LexTraceExit("0230 (success)", dps);
+ return true;
+ }
+
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ LexTraceExit("0240", dps);
+ return false;
+ }
+
+ LexTraceExit("0250 (success)", dps);
+ return true;
+ }
+
+ private static Boolean VerifyValidPunctuation(ref __DTString str)
+ {
+ // Compatability Behavior. Allow trailing nulls and surrounding hashes
+ Char ch = str.Value[str.Index];
+ if (ch == '#')
+ {
+ bool foundStart = false;
+ bool foundEnd = false;
+ for (int i = 0; i < str.len; i++)
+ {
+ ch = str.Value[i];
+ if (ch == '#')
+ {
+ if (foundStart)
+ {
+ if (foundEnd)
+ {
+ // Having more than two hashes is invalid
+ return false;
+ }
+ else
+ {
+ foundEnd = true;
+ }
+ }
+ else
+ {
+ foundStart = true;
+ }
+ }
+ else if (ch == '\0')
+ {
+ // Allow nulls only at the end
+ if (!foundEnd)
+ {
+ return false;
+ }
+ }
+ else if ((!Char.IsWhiteSpace(ch)))
+ {
+ // Anthyhing other than whitespace outside hashes is invalid
+ if (!foundStart || foundEnd)
+ {
+ return false;
+ }
+ }
+ }
+ if (!foundEnd)
+ {
+ // The has was un-paired
+ return false;
+ }
+ // Valid Hash usage: eat the hash and continue.
+ str.GetNext();
+ return true;
+ }
+ else if (ch == '\0')
+ {
+ for (int i = str.Index; i < str.len; i++)
+ {
+ if (str.Value[i] != '\0')
+ {
+ // Nulls are only valid if they are the only trailing character
+ return false;
+ }
+ }
+ // Move to the end of the string
+ str.Index = str.len;
+ return true;
+ }
+ return false;
+ }
+
+ private const int ORDER_YMD = 0; // The order of date is Year/Month/Day.
+ private const int ORDER_MDY = 1; // The order of date is Month/Day/Year.
+ private const int ORDER_DMY = 2; // The order of date is Day/Month/Year.
+ private const int ORDER_YDM = 3; // The order of date is Year/Day/Month
+ private const int ORDER_YM = 4; // Year/Month order.
+ private const int ORDER_MY = 5; // Month/Year order.
+ private const int ORDER_MD = 6; // Month/Day order.
+ private const int ORDER_DM = 7; // Day/Month order.
+
+ //
+ // Decide the year/month/day order from the datePattern.
+ //
+ // Return 0 for YMD, 1 for MDY, 2 for DMY, otherwise -1.
+ //
+ private static Boolean GetYearMonthDayOrder(String datePattern, DateTimeFormatInfo dtfi, out int order)
+ {
+ int yearOrder = -1;
+ int monthOrder = -1;
+ int dayOrder = -1;
+ int orderCount = 0;
+
+ bool inQuote = false;
+
+ for (int i = 0; i < datePattern.Length && orderCount < 3; i++)
+ {
+ char ch = datePattern[i];
+ if (ch == '\\' || ch == '%')
+ {
+ i++;
+ continue; // Skip next character that is escaped by this backslash
+ }
+
+ if (ch == '\'' || ch == '"')
+ {
+ inQuote = !inQuote;
+ }
+
+ if (!inQuote)
+ {
+ if (ch == 'y')
+ {
+ yearOrder = orderCount++;
+
+ //
+ // Skip all year pattern charaters.
+ //
+ for (; i + 1 < datePattern.Length && datePattern[i + 1] == 'y'; i++)
+ {
+ // Do nothing here.
+ }
+ }
+ else if (ch == 'M')
+ {
+ monthOrder = orderCount++;
+ //
+ // Skip all month pattern characters.
+ //
+ for (; i + 1 < datePattern.Length && datePattern[i + 1] == 'M'; i++)
+ {
+ // Do nothing here.
+ }
+ }
+ else if (ch == 'd')
+ {
+ int patternCount = 1;
+ //
+ // Skip all day pattern characters.
+ //
+ for (; i + 1 < datePattern.Length && datePattern[i + 1] == 'd'; i++)
+ {
+ patternCount++;
+ }
+ //
+ // Make sure this is not "ddd" or "dddd", which means day of week.
+ //
+ if (patternCount <= 2)
+ {
+ dayOrder = orderCount++;
+ }
+ }
+ }
+ }
+
+ if (yearOrder == 0 && monthOrder == 1 && dayOrder == 2)
+ {
+ order = ORDER_YMD;
+ return true;
+ }
+ if (monthOrder == 0 && dayOrder == 1 && yearOrder == 2)
+ {
+ order = ORDER_MDY;
+ return true;
+ }
+ if (dayOrder == 0 && monthOrder == 1 && yearOrder == 2)
+ {
+ order = ORDER_DMY;
+ return true;
+ }
+ if (yearOrder == 0 && dayOrder == 1 && monthOrder == 2)
+ {
+ order = ORDER_YDM;
+ return true;
+ }
+ order = -1;
+ return false;
+ }
+
+ //
+ // Decide the year/month order from the pattern.
+ //
+ // Return 0 for YM, 1 for MY, otherwise -1.
+ //
+ private static Boolean GetYearMonthOrder(String pattern, DateTimeFormatInfo dtfi, out int order)
+ {
+ int yearOrder = -1;
+ int monthOrder = -1;
+ int orderCount = 0;
+
+ bool inQuote = false;
+ for (int i = 0; i < pattern.Length && orderCount < 2; i++)
+ {
+ char ch = pattern[i];
+ if (ch == '\\' || ch == '%')
+ {
+ i++;
+ continue; // Skip next character that is escaped by this backslash
+ }
+
+ if (ch == '\'' || ch == '"')
+ {
+ inQuote = !inQuote;
+ }
+
+ if (!inQuote)
+ {
+ if (ch == 'y')
+ {
+ yearOrder = orderCount++;
+
+ //
+ // Skip all year pattern charaters.
+ //
+ for (; i + 1 < pattern.Length && pattern[i + 1] == 'y'; i++)
+ {
+ }
+ }
+ else if (ch == 'M')
+ {
+ monthOrder = orderCount++;
+ //
+ // Skip all month pattern characters.
+ //
+ for (; i + 1 < pattern.Length && pattern[i + 1] == 'M'; i++)
+ {
+ }
+ }
+ }
+ }
+
+ if (yearOrder == 0 && monthOrder == 1)
+ {
+ order = ORDER_YM;
+ return true;
+ }
+ if (monthOrder == 0 && yearOrder == 1)
+ {
+ order = ORDER_MY;
+ return true;
+ }
+ order = -1;
+ return false;
+ }
+
+ //
+ // Decide the month/day order from the pattern.
+ //
+ // Return 0 for MD, 1 for DM, otherwise -1.
+ //
+ private static Boolean GetMonthDayOrder(String pattern, DateTimeFormatInfo dtfi, out int order)
+ {
+ int monthOrder = -1;
+ int dayOrder = -1;
+ int orderCount = 0;
+
+ bool inQuote = false;
+ for (int i = 0; i < pattern.Length && orderCount < 2; i++)
+ {
+ char ch = pattern[i];
+ if (ch == '\\' || ch == '%')
+ {
+ i++;
+ continue; // Skip next character that is escaped by this backslash
+ }
+
+ if (ch == '\'' || ch == '"')
+ {
+ inQuote = !inQuote;
+ }
+
+ if (!inQuote)
+ {
+ if (ch == 'd')
+ {
+ int patternCount = 1;
+ //
+ // Skip all day pattern charaters.
+ //
+ for (; i + 1 < pattern.Length && pattern[i + 1] == 'd'; i++)
+ {
+ patternCount++;
+ }
+
+ //
+ // Make sure this is not "ddd" or "dddd", which means day of week.
+ //
+ if (patternCount <= 2)
+ {
+ dayOrder = orderCount++;
+ }
+ }
+ else if (ch == 'M')
+ {
+ monthOrder = orderCount++;
+ //
+ // Skip all month pattern characters.
+ //
+ for (; i + 1 < pattern.Length && pattern[i + 1] == 'M'; i++)
+ {
+ }
+ }
+ }
+ }
+
+ if (monthOrder == 0 && dayOrder == 1)
+ {
+ order = ORDER_MD;
+ return true;
+ }
+ if (dayOrder == 0 && monthOrder == 1)
+ {
+ order = ORDER_DM;
+ return true;
+ }
+ order = -1;
+ return false;
+ }
+
+ //
+ // Adjust the two-digit year if necessary.
+ //
+ private static bool TryAdjustYear(ref DateTimeResult result, int year, out int adjustedYear)
+ {
+ if (year < 100)
+ {
+ try
+ {
+ // the Calendar classes need some real work. Many of the calendars that throw
+ // don't implement a fast/non-allocating (and non-throwing) IsValid{Year|Day|Month} method.
+ // we are making a targeted try/catch fix in the in-place release but will revisit this code
+ // in the next side-by-side release.
+ year = result.calendar.ToFourDigitYear(year);
+ }
+ catch (ArgumentOutOfRangeException)
+ {
+ adjustedYear = -1;
+ return false;
+ }
+ }
+ adjustedYear = year;
+ return true;
+ }
+
+ private static bool SetDateYMD(ref DateTimeResult result, int year, int month, int day)
+ {
+ // Note, longer term these checks should be done at the end of the parse. This current
+ // way of checking creates order dependence with parsing the era name.
+ if (result.calendar.IsValidDay(year, month, day, result.era))
+ {
+ result.SetDate(year, month, day); // YMD
+ return (true);
+ }
+ return (false);
+ }
+
+ private static bool SetDateMDY(ref DateTimeResult result, int month, int day, int year)
+ {
+ return (SetDateYMD(ref result, year, month, day));
+ }
+
+ private static bool SetDateDMY(ref DateTimeResult result, int day, int month, int year)
+ {
+ return (SetDateYMD(ref result, year, month, day));
+ }
+
+ private static bool SetDateYDM(ref DateTimeResult result, int year, int day, int month)
+ {
+ return (SetDateYMD(ref result, year, month, day));
+ }
+
+ private static void GetDefaultYear(ref DateTimeResult result, ref DateTimeStyles styles)
+ {
+ result.Year = result.calendar.GetYear(GetDateTimeNow(ref result, ref styles));
+ result.flags |= ParseFlags.YearDefault;
+ }
+
+ // Processing teriminal case: DS.DX_NN
+ private static Boolean GetDayOfNN(ref DateTimeResult result, ref DateTimeStyles styles, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
+ {
+ if ((result.flags & ParseFlags.HaveDate) != 0)
+ {
+ // Multiple dates in the input string
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ int n1 = raw.GetNumber(0);
+ int n2 = raw.GetNumber(1);
+
+ GetDefaultYear(ref result, ref styles);
+
+ int order;
+ if (!GetMonthDayOrder(dtfi.MonthDayPattern, dtfi, out order))
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.MonthDayPattern);
+ return false;
+ }
+
+ if (order == ORDER_MD)
+ {
+ if (SetDateYMD(ref result, result.Year, n1, n2)) // MD
+ {
+ result.flags |= ParseFlags.HaveDate;
+ return true;
+ }
+ }
+ else
+ {
+ // ORDER_DM
+ if (SetDateYMD(ref result, result.Year, n2, n1)) // DM
+ {
+ result.flags |= ParseFlags.HaveDate;
+ return true;
+ }
+ }
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ // Processing teriminal case: DS.DX_NNN
+ private static Boolean GetDayOfNNN(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
+ {
+ if ((result.flags & ParseFlags.HaveDate) != 0)
+ {
+ // Multiple dates in the input string
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ int n1 = raw.GetNumber(0);
+ int n2 = raw.GetNumber(1); ;
+ int n3 = raw.GetNumber(2);
+
+ int order;
+ if (!GetYearMonthDayOrder(dtfi.ShortDatePattern, dtfi, out order))
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.ShortDatePattern);
+ return false;
+ }
+ int year;
+
+ if (order == ORDER_YMD)
+ {
+ if (TryAdjustYear(ref result, n1, out year) && SetDateYMD(ref result, year, n2, n3)) // YMD
+ {
+ result.flags |= ParseFlags.HaveDate;
+ return true;
+ }
+ }
+ else if (order == ORDER_MDY)
+ {
+ if (TryAdjustYear(ref result, n3, out year) && SetDateMDY(ref result, n1, n2, year)) // MDY
+ {
+ result.flags |= ParseFlags.HaveDate;
+ return true;
+ }
+ }
+ else if (order == ORDER_DMY)
+ {
+ if (TryAdjustYear(ref result, n3, out year) && SetDateDMY(ref result, n1, n2, year)) // DMY
+ {
+ result.flags |= ParseFlags.HaveDate;
+ return true;
+ }
+ }
+ else if (order == ORDER_YDM)
+ {
+ if (TryAdjustYear(ref result, n1, out year) && SetDateYDM(ref result, year, n2, n3)) // YDM
+ {
+ result.flags |= ParseFlags.HaveDate;
+ return true;
+ }
+ }
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ private static Boolean GetDayOfMN(ref DateTimeResult result, ref DateTimeStyles styles, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
+ {
+ if ((result.flags & ParseFlags.HaveDate) != 0)
+ {
+ // Multiple dates in the input string
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ // The interpretation is based on the MonthDayPattern and YearMonthPattern
+ //
+ // MonthDayPattern YearMonthPattern Interpretation
+ // --------------- ---------------- ---------------
+ // MMMM dd MMMM yyyy Day
+ // MMMM dd yyyy MMMM Day
+ // dd MMMM MMMM yyyy Year
+ // dd MMMM yyyy MMMM Day
+ //
+ // In the first and last cases, it could be either or neither, but a day is a better default interpretation
+ // than a 2 digit year.
+
+ int monthDayOrder;
+ if (!GetMonthDayOrder(dtfi.MonthDayPattern, dtfi, out monthDayOrder))
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.MonthDayPattern);
+ return false;
+ }
+ if (monthDayOrder == ORDER_DM)
+ {
+ int yearMonthOrder;
+ if (!GetYearMonthOrder(dtfi.YearMonthPattern, dtfi, out yearMonthOrder))
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.YearMonthPattern);
+ return false;
+ }
+ if (yearMonthOrder == ORDER_MY)
+ {
+ int year;
+ if (!TryAdjustYear(ref result, raw.GetNumber(0), out year) || !SetDateYMD(ref result, year, raw.month, 1))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ return true;
+ }
+ }
+
+ GetDefaultYear(ref result, ref styles);
+ if (!SetDateYMD(ref result, result.Year, raw.month, raw.GetNumber(0)))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ return true;
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+ // Actions:
+ // Deal with the terminal state for Hebrew Month/Day pattern
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ private static Boolean GetHebrewDayOfNM(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
+ {
+ int monthDayOrder;
+ if (!GetMonthDayOrder(dtfi.MonthDayPattern, dtfi, out monthDayOrder))
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.MonthDayPattern);
+ return false;
+ }
+ result.Month = raw.month;
+ if (monthDayOrder == ORDER_DM || monthDayOrder == ORDER_MD)
+ {
+ if (result.calendar.IsValidDay(result.Year, result.Month, raw.GetNumber(0), result.era))
+ {
+ result.Day = raw.GetNumber(0);
+ return true;
+ }
+ }
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ private static Boolean GetDayOfNM(ref DateTimeResult result, ref DateTimeStyles styles, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
+ {
+ if ((result.flags & ParseFlags.HaveDate) != 0)
+ {
+ // Multiple dates in the input string
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ // The interpretation is based on the MonthDayPattern and YearMonthPattern
+ //
+ // MonthDayPattern YearMonthPattern Interpretation
+ // --------------- ---------------- ---------------
+ // MMMM dd MMMM yyyy Day
+ // MMMM dd yyyy MMMM Year
+ // dd MMMM MMMM yyyy Day
+ // dd MMMM yyyy MMMM Day
+ //
+ // In the first and last cases, it could be either or neither, but a day is a better default interpretation
+ // than a 2 digit year.
+
+ int monthDayOrder;
+ if (!GetMonthDayOrder(dtfi.MonthDayPattern, dtfi, out monthDayOrder))
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.MonthDayPattern);
+ return false;
+ }
+ if (monthDayOrder == ORDER_MD)
+ {
+ int yearMonthOrder;
+ if (!GetYearMonthOrder(dtfi.YearMonthPattern, dtfi, out yearMonthOrder))
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.YearMonthPattern);
+ return false;
+ }
+ if (yearMonthOrder == ORDER_YM)
+ {
+ int year;
+ if (!TryAdjustYear(ref result, raw.GetNumber(0), out year) || !SetDateYMD(ref result, year, raw.month, 1))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ return true;
+ }
+ }
+
+ GetDefaultYear(ref result, ref styles);
+ if (!SetDateYMD(ref result, result.Year, raw.month, raw.GetNumber(0)))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ return true;
+ }
+
+ private static Boolean GetDayOfMNN(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
+ {
+ if ((result.flags & ParseFlags.HaveDate) != 0)
+ {
+ // Multiple dates in the input string
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ int n1 = raw.GetNumber(0);
+ int n2 = raw.GetNumber(1);
+
+ int order;
+ if (!GetYearMonthDayOrder(dtfi.ShortDatePattern, dtfi, out order))
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.ShortDatePattern);
+ return false;
+ }
+ int year;
+
+ if (order == ORDER_MDY)
+ {
+ if (TryAdjustYear(ref result, n2, out year) && result.calendar.IsValidDay(year, raw.month, n1, result.era))
+ {
+ result.SetDate(year, raw.month, n1); // MDY
+ result.flags |= ParseFlags.HaveDate;
+ return true;
+ }
+ else if (TryAdjustYear(ref result, n1, out year) && result.calendar.IsValidDay(year, raw.month, n2, result.era))
+ {
+ result.SetDate(year, raw.month, n2); // YMD
+ result.flags |= ParseFlags.HaveDate;
+ return true;
+ }
+ }
+ else if (order == ORDER_YMD)
+ {
+ if (TryAdjustYear(ref result, n1, out year) && result.calendar.IsValidDay(year, raw.month, n2, result.era))
+ {
+ result.SetDate(year, raw.month, n2); // YMD
+ result.flags |= ParseFlags.HaveDate;
+ return true;
+ }
+ else if (TryAdjustYear(ref result, n2, out year) && result.calendar.IsValidDay(year, raw.month, n1, result.era))
+ {
+ result.SetDate(year, raw.month, n1); // DMY
+ result.flags |= ParseFlags.HaveDate;
+ return true;
+ }
+ }
+ else if (order == ORDER_DMY)
+ {
+ if (TryAdjustYear(ref result, n2, out year) && result.calendar.IsValidDay(year, raw.month, n1, result.era))
+ {
+ result.SetDate(year, raw.month, n1); // DMY
+ result.flags |= ParseFlags.HaveDate;
+ return true;
+ }
+ else if (TryAdjustYear(ref result, n1, out year) && result.calendar.IsValidDay(year, raw.month, n2, result.era))
+ {
+ result.SetDate(year, raw.month, n2); // YMD
+ result.flags |= ParseFlags.HaveDate;
+ return true;
+ }
+ }
+
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ private static Boolean GetDayOfYNN(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
+ {
+ if ((result.flags & ParseFlags.HaveDate) != 0)
+ {
+ // Multiple dates in the input string
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ int n1 = raw.GetNumber(0);
+ int n2 = raw.GetNumber(1);
+ String pattern = dtfi.ShortDatePattern;
+
+ // For compatibility, don't throw if we can't determine the order, but default to YMD instead
+ int order;
+ if (GetYearMonthDayOrder(pattern, dtfi, out order) && order == ORDER_YDM)
+ {
+ if (SetDateYMD(ref result, raw.year, n2, n1))
+ {
+ result.flags |= ParseFlags.HaveDate;
+ return true; // Year + DM
+ }
+ }
+ else
+ {
+ if (SetDateYMD(ref result, raw.year, n1, n2))
+ {
+ result.flags |= ParseFlags.HaveDate;
+ return true; // Year + MD
+ }
+ }
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ private static Boolean GetDayOfNNY(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
+ {
+ if ((result.flags & ParseFlags.HaveDate) != 0)
+ {
+ // Multiple dates in the input string
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ int n1 = raw.GetNumber(0);
+ int n2 = raw.GetNumber(1);
+
+ int order;
+ if (!GetYearMonthDayOrder(dtfi.ShortDatePattern, dtfi, out order))
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.ShortDatePattern);
+ return false;
+ }
+
+ if (order == ORDER_MDY || order == ORDER_YMD)
+ {
+ if (SetDateYMD(ref result, raw.year, n1, n2))
+ {
+ result.flags |= ParseFlags.HaveDate;
+ return true; // MD + Year
+ }
+ }
+ else
+ {
+ if (SetDateYMD(ref result, raw.year, n2, n1))
+ {
+ result.flags |= ParseFlags.HaveDate;
+ return true; // DM + Year
+ }
+ }
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+
+ private static Boolean GetDayOfYMN(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
+ {
+ if ((result.flags & ParseFlags.HaveDate) != 0)
+ {
+ // Multiple dates in the input string
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ if (SetDateYMD(ref result, raw.year, raw.month, raw.GetNumber(0)))
+ {
+ result.flags |= ParseFlags.HaveDate;
+ return true;
+ }
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ private static Boolean GetDayOfYN(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
+ {
+ if ((result.flags & ParseFlags.HaveDate) != 0)
+ {
+ // Multiple dates in the input string
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ if (SetDateYMD(ref result, raw.year, raw.GetNumber(0), 1))
+ {
+ result.flags |= ParseFlags.HaveDate;
+ return true;
+ }
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ private static Boolean GetDayOfYM(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
+ {
+ if ((result.flags & ParseFlags.HaveDate) != 0)
+ {
+ // Multiple dates in the input string
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ if (SetDateYMD(ref result, raw.year, raw.month, 1))
+ {
+ result.flags |= ParseFlags.HaveDate;
+ return true;
+ }
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ private static void AdjustTimeMark(DateTimeFormatInfo dtfi, ref DateTimeRawInfo raw)
+ {
+ // Specail case for culture which uses AM as empty string.
+ // E.g. af-ZA (0x0436)
+ // S1159 \x0000
+ // S2359 nm
+ // In this case, if we are parsing a string like "2005/09/14 12:23", we will assume this is in AM.
+
+ if (raw.timeMark == TM.NotSet)
+ {
+ if (dtfi.AMDesignator != null && dtfi.PMDesignator != null)
+ {
+ if (dtfi.AMDesignator.Length == 0 && dtfi.PMDesignator.Length != 0)
+ {
+ raw.timeMark = TM.AM;
+ }
+ if (dtfi.PMDesignator.Length == 0 && dtfi.AMDesignator.Length != 0)
+ {
+ raw.timeMark = TM.PM;
+ }
+ }
+ }
+ }
+
+ //
+ // Adjust hour according to the time mark.
+ //
+ private static Boolean AdjustHour(ref int hour, TM timeMark)
+ {
+ if (timeMark != TM.NotSet)
+ {
+ if (timeMark == TM.AM)
+ {
+ if (hour < 0 || hour > 12)
+ {
+ return false;
+ }
+ hour = (hour == 12) ? 0 : hour;
+ }
+ else
+ {
+ if (hour < 0 || hour > 23)
+ {
+ return false;
+ }
+ if (hour < 12)
+ {
+ hour += 12;
+ }
+ }
+ }
+ return true;
+ }
+
+ private static Boolean GetTimeOfN(DateTimeFormatInfo dtfi, ref DateTimeResult result, ref DateTimeRawInfo raw)
+ {
+ if ((result.flags & ParseFlags.HaveTime) != 0)
+ {
+ // Multiple times in the input string
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ //
+ // In this case, we need a time mark. Check if so.
+ //
+ if (raw.timeMark == TM.NotSet)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ result.Hour = raw.GetNumber(0);
+ result.flags |= ParseFlags.HaveTime;
+ return true;
+ }
+
+ private static Boolean GetTimeOfNN(DateTimeFormatInfo dtfi, ref DateTimeResult result, ref DateTimeRawInfo raw)
+ {
+ Debug.Assert(raw.numCount >= 2, "raw.numCount >= 2");
+ if ((result.flags & ParseFlags.HaveTime) != 0)
+ {
+ // Multiple times in the input string
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ result.Hour = raw.GetNumber(0);
+ result.Minute = raw.GetNumber(1);
+ result.flags |= ParseFlags.HaveTime;
+ return true;
+ }
+
+ private static Boolean GetTimeOfNNN(DateTimeFormatInfo dtfi, ref DateTimeResult result, ref DateTimeRawInfo raw)
+ {
+ if ((result.flags & ParseFlags.HaveTime) != 0)
+ {
+ // Multiple times in the input string
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ Debug.Assert(raw.numCount >= 3, "raw.numCount >= 3");
+ result.Hour = raw.GetNumber(0);
+ result.Minute = raw.GetNumber(1);
+ result.Second = raw.GetNumber(2);
+ result.flags |= ParseFlags.HaveTime;
+ return true;
+ }
+
+ //
+ // Processing terminal state: A Date suffix followed by one number.
+ //
+ private static Boolean GetDateOfDSN(ref DateTimeResult result, ref DateTimeRawInfo raw)
+ {
+ if (raw.numCount != 1 || result.Day != -1)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ result.Day = raw.GetNumber(0);
+ return true;
+ }
+
+ private static Boolean GetDateOfNDS(ref DateTimeResult result, ref DateTimeRawInfo raw)
+ {
+ if (result.Month == -1)
+ {
+ //Should have a month suffix
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ if (result.Year != -1)
+ {
+ // Aleady has a year suffix
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ if (!TryAdjustYear(ref result, raw.GetNumber(0), out result.Year))
+ {
+ // the year value is out of range
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ result.Day = 1;
+ return true;
+ }
+
+ private static Boolean GetDateOfNNDS(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
+ {
+ // For partial CJK Dates, the only valid formats are with a specified year, followed by two numbers, which
+ // will be the Month and Day, and with a specified Month, when the numbers are either the year and day or
+ // day and year, depending on the short date pattern.
+
+ if ((result.flags & ParseFlags.HaveYear) != 0)
+ {
+ if (((result.flags & ParseFlags.HaveMonth) == 0) && ((result.flags & ParseFlags.HaveDay) == 0))
+ {
+ if (TryAdjustYear(ref result, raw.year, out result.Year) && SetDateYMD(ref result, result.Year, raw.GetNumber(0), raw.GetNumber(1)))
+ {
+ return true;
+ }
+ }
+ }
+ else if ((result.flags & ParseFlags.HaveMonth) != 0)
+ {
+ if (((result.flags & ParseFlags.HaveYear) == 0) && ((result.flags & ParseFlags.HaveDay) == 0))
+ {
+ int order;
+ if (!GetYearMonthDayOrder(dtfi.ShortDatePattern, dtfi, out order))
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.ShortDatePattern);
+ return false;
+ }
+ int year;
+ if (order == ORDER_YMD)
+ {
+ if (TryAdjustYear(ref result, raw.GetNumber(0), out year) && SetDateYMD(ref result, year, result.Month, raw.GetNumber(1)))
+ {
+ return true;
+ }
+ }
+ else
+ {
+ if (TryAdjustYear(ref result, raw.GetNumber(1), out year) && SetDateYMD(ref result, year, result.Month, raw.GetNumber(0)))
+ {
+ return true;
+ }
+ }
+ }
+ }
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ //
+ // A date suffix is found, use this method to put the number into the result.
+ //
+ private static bool ProcessDateTimeSuffix(ref DateTimeResult result, ref DateTimeRawInfo raw, ref DateTimeToken dtok)
+ {
+ switch (dtok.suffix)
+ {
+ case TokenType.SEP_YearSuff:
+ if ((result.flags & ParseFlags.HaveYear) != 0)
+ {
+ return false;
+ }
+ result.flags |= ParseFlags.HaveYear;
+ result.Year = raw.year = dtok.num;
+ break;
+ case TokenType.SEP_MonthSuff:
+ if ((result.flags & ParseFlags.HaveMonth) != 0)
+ {
+ return false;
+ }
+ result.flags |= ParseFlags.HaveMonth;
+ result.Month = raw.month = dtok.num;
+ break;
+ case TokenType.SEP_DaySuff:
+ if ((result.flags & ParseFlags.HaveDay) != 0)
+ {
+ return false;
+ }
+ result.flags |= ParseFlags.HaveDay;
+ result.Day = dtok.num;
+ break;
+ case TokenType.SEP_HourSuff:
+ if ((result.flags & ParseFlags.HaveHour) != 0)
+ {
+ return false;
+ }
+ result.flags |= ParseFlags.HaveHour;
+ result.Hour = dtok.num;
+ break;
+ case TokenType.SEP_MinuteSuff:
+ if ((result.flags & ParseFlags.HaveMinute) != 0)
+ {
+ return false;
+ }
+ result.flags |= ParseFlags.HaveMinute;
+ result.Minute = dtok.num;
+ break;
+ case TokenType.SEP_SecondSuff:
+ if ((result.flags & ParseFlags.HaveSecond) != 0)
+ {
+ return false;
+ }
+ result.flags |= ParseFlags.HaveSecond;
+ result.Second = dtok.num;
+ break;
+ }
+ return true;
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Actions:
+ // This is used by DateTime.Parse().
+ // Process the terminal state for the Hebrew calendar parsing.
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ internal static Boolean ProcessHebrewTerminalState(DS dps, ref DateTimeResult result, ref DateTimeStyles styles, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
+ {
+ // The following are accepted terminal state for Hebrew date.
+ switch (dps)
+ {
+ case DS.DX_MNN:
+ // Deal with the default long/short date format when the year number is ambigous (i.e. year < 100).
+ raw.year = raw.GetNumber(1);
+ if (!dtfi.YearMonthAdjustment(ref raw.year, ref raw.month, true))
+ {
+ result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
+ return false;
+ }
+ if (!GetDayOfMNN(ref result, ref raw, dtfi))
+ {
+ return false;
+ }
+ break;
+ case DS.DX_YMN:
+ // Deal with the default long/short date format when the year number is NOT ambigous (i.e. year >= 100).
+ if (!dtfi.YearMonthAdjustment(ref raw.year, ref raw.month, true))
+ {
+ result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
+ return false;
+ }
+ if (!GetDayOfYMN(ref result, ref raw, dtfi))
+ {
+ return false;
+ }
+ break;
+ case DS.DX_NM:
+ case DS.DX_MN:
+ // Deal with Month/Day pattern.
+ GetDefaultYear(ref result, ref styles);
+ if (!dtfi.YearMonthAdjustment(ref result.Year, ref raw.month, true))
+ {
+ result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
+ return false;
+ }
+ if (!GetHebrewDayOfNM(ref result, ref raw, dtfi))
+ {
+ return false;
+ }
+ break;
+ case DS.DX_YM:
+ // Deal with Year/Month pattern.
+ if (!dtfi.YearMonthAdjustment(ref raw.year, ref raw.month, true))
+ {
+ result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
+ return false;
+ }
+ if (!GetDayOfYM(ref result, ref raw, dtfi))
+ {
+ return false;
+ }
+ break;
+ case DS.TX_N:
+ // Deal hour + AM/PM
+ if (!GetTimeOfN(dtfi, ref result, ref raw))
+ {
+ return false;
+ }
+ break;
+ case DS.TX_NN:
+ if (!GetTimeOfNN(dtfi, ref result, ref raw))
+ {
+ return false;
+ }
+ break;
+ case DS.TX_NNN:
+ if (!GetTimeOfNNN(dtfi, ref result, ref raw))
+ {
+ return false;
+ }
+ break;
+ default:
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ if (dps > DS.ERROR)
+ {
+ //
+ // We have reached a terminal state. Reset the raw num count.
+ //
+ raw.numCount = 0;
+ }
+ return true;
+ }
+
+ //
+ // A terminal state has been reached, call the appropriate function to fill in the parsing result.
+ // Return true if the state is a terminal state.
+ //
+ internal static Boolean ProcessTerminaltState(DS dps, ref DateTimeResult result, ref DateTimeStyles styles, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
+ {
+ bool passed = true;
+ switch (dps)
+ {
+ case DS.DX_NN:
+ passed = GetDayOfNN(ref result, ref styles, ref raw, dtfi);
+ break;
+ case DS.DX_NNN:
+ passed = GetDayOfNNN(ref result, ref raw, dtfi);
+ break;
+ case DS.DX_MN:
+ passed = GetDayOfMN(ref result, ref styles, ref raw, dtfi);
+ break;
+ case DS.DX_NM:
+ passed = GetDayOfNM(ref result, ref styles, ref raw, dtfi);
+ break;
+ case DS.DX_MNN:
+ passed = GetDayOfMNN(ref result, ref raw, dtfi);
+ break;
+ case DS.DX_DS:
+ // The result has got the correct value. No need to process.
+ passed = true;
+ break;
+ case DS.DX_YNN:
+ passed = GetDayOfYNN(ref result, ref raw, dtfi);
+ break;
+ case DS.DX_NNY:
+ passed = GetDayOfNNY(ref result, ref raw, dtfi);
+ break;
+ case DS.DX_YMN:
+ passed = GetDayOfYMN(ref result, ref raw, dtfi);
+ break;
+ case DS.DX_YN:
+ passed = GetDayOfYN(ref result, ref raw, dtfi);
+ break;
+ case DS.DX_YM:
+ passed = GetDayOfYM(ref result, ref raw, dtfi);
+ break;
+ case DS.TX_N:
+ passed = GetTimeOfN(dtfi, ref result, ref raw);
+ break;
+ case DS.TX_NN:
+ passed = GetTimeOfNN(dtfi, ref result, ref raw);
+ break;
+ case DS.TX_NNN:
+ passed = GetTimeOfNNN(dtfi, ref result, ref raw);
+ break;
+ case DS.TX_TS:
+ // The result has got the correct value. Nothing to do.
+ passed = true;
+ break;
+ case DS.DX_DSN:
+ passed = GetDateOfDSN(ref result, ref raw);
+ break;
+ case DS.DX_NDS:
+ passed = GetDateOfNDS(ref result, ref raw);
+ break;
+ case DS.DX_NNDS:
+ passed = GetDateOfNNDS(ref result, ref raw, dtfi);
+ break;
+ }
+
+ PTSTraceExit(dps, passed);
+ if (!passed)
+ {
+ return false;
+ }
+
+ if (dps > DS.ERROR)
+ {
+ //
+ // We have reached a terminal state. Reset the raw num count.
+ //
+ raw.numCount = 0;
+ }
+ return true;
+ }
+
+ internal static DateTime Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)
+ {
+ DateTimeResult result = new DateTimeResult(); // The buffer to store the parsing result.
+ result.Init();
+ if (TryParse(s, dtfi, styles, ref result))
+ {
+ return result.parsedDate;
+ }
+ else
+ {
+ throw GetDateTimeParseException(ref result);
+ }
+ }
+
+ internal static DateTime Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles, out TimeSpan offset)
+ {
+ DateTimeResult result = new DateTimeResult(); // The buffer to store the parsing result.
+ result.Init();
+ result.flags |= ParseFlags.CaptureOffset;
+ if (TryParse(s, dtfi, styles, ref result))
+ {
+ offset = result.timeZoneOffset;
+ return result.parsedDate;
+ }
+ else
+ {
+ throw GetDateTimeParseException(ref result);
+ }
+ }
+
+
+ internal static bool TryParse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles, out DateTime result)
+ {
+ result = DateTime.MinValue;
+ DateTimeResult resultData = new DateTimeResult(); // The buffer to store the parsing result.
+ resultData.Init();
+ if (TryParse(s, dtfi, styles, ref resultData))
+ {
+ result = resultData.parsedDate;
+ return true;
+ }
+ return false;
+ }
+
+ internal static bool TryParse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles, out DateTime result, out TimeSpan offset)
+ {
+ result = DateTime.MinValue;
+ offset = TimeSpan.Zero;
+ DateTimeResult parseResult = new DateTimeResult(); // The buffer to store the parsing result.
+ parseResult.Init();
+ parseResult.flags |= ParseFlags.CaptureOffset;
+ if (TryParse(s, dtfi, styles, ref parseResult))
+ {
+ result = parseResult.parsedDate;
+ offset = parseResult.timeZoneOffset;
+ return true;
+ }
+ return false;
+ }
+
+
+ //
+ // This is the real method to do the parsing work.
+ //
+ internal static bool TryParse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles, ref DateTimeResult result)
+ {
+ if (s == null)
+ {
+ result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(s));
+ return false;
+ }
+ if (s.Length == 0)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ Debug.Assert(dtfi != null, "dtfi == null");
+
+#if _LOGGING
+ DTFITrace(dtfi);
+#endif
+
+ DateTime time;
+ //
+ // First try the predefined format.
+ //
+
+ DS dps = DS.BEGIN; // Date Parsing State.
+ bool reachTerminalState = false;
+
+ DateTimeToken dtok = new DateTimeToken(); // The buffer to store the parsing token.
+ dtok.suffix = TokenType.SEP_Unk;
+ DateTimeRawInfo raw = new DateTimeRawInfo(); // The buffer to store temporary parsing information.
+ unsafe
+ {
+ Int32* numberPointer = stackalloc Int32[3];
+ raw.Init(numberPointer);
+ }
+ raw.hasSameDateAndTimeSeparators = dtfi.DateSeparator.Equals(dtfi.TimeSeparator, StringComparison.Ordinal);
+
+ result.calendar = dtfi.Calendar;
+ result.era = Calendar.CurrentEra;
+
+ //
+ // The string to be parsed. Use a __DTString wrapper so that we can trace the index which
+ // indicates the begining of next token.
+ //
+ __DTString str = new __DTString(s, dtfi);
+
+ str.GetNext();
+
+ //
+ // The following loop will break out when we reach the end of the str.
+ //
+ do
+ {
+ //
+ // Call the lexer to get the next token.
+ //
+ // If we find a era in Lex(), the era value will be in raw.era.
+ if (!Lex(dps, ref str, ref dtok, ref raw, ref result, ref dtfi, styles))
+ {
+ TPTraceExit("0000", dps);
+ return false;
+ }
+
+ //
+ // If the token is not unknown, process it.
+ // Otherwise, just discard it.
+ //
+ if (dtok.dtt != DTT.Unk)
+ {
+ //
+ // Check if we got any CJK Date/Time suffix.
+ // Since the Date/Time suffix tells us the number belongs to year/month/day/hour/minute/second,
+ // store the number in the appropriate field in the result.
+ //
+ if (dtok.suffix != TokenType.SEP_Unk)
+ {
+ if (!ProcessDateTimeSuffix(ref result, ref raw, ref dtok))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ TPTraceExit("0010", dps);
+ return false;
+ }
+
+ dtok.suffix = TokenType.SEP_Unk; // Reset suffix to SEP_Unk;
+ }
+
+ if (dtok.dtt == DTT.NumLocalTimeMark)
+ {
+ if (dps == DS.D_YNd || dps == DS.D_YN)
+ {
+ // Consider this as ISO 8601 format:
+ // "yyyy-MM-dd'T'HH:mm:ss" 1999-10-31T02:00:00
+ TPTraceExit("0020", dps);
+ return (ParseISO8601(ref raw, ref str, styles, ref result));
+ }
+ else
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ TPTraceExit("0030", dps);
+ return false;
+ }
+ }
+
+ if (raw.hasSameDateAndTimeSeparators)
+ {
+ if (dtok.dtt == DTT.YearEnd || dtok.dtt == DTT.YearSpace || dtok.dtt == DTT.YearDateSep)
+ {
+ // When time and date separators are same and we are hitting a year number while the first parsed part of the string was recognized
+ // as part of time (and not a date) DS.T_Nt, DS.T_NNt then change the state to be a date so we try to parse it as a date instead
+ if (dps == DS.T_Nt)
+ {
+ dps = DS.D_Nd;
+ }
+ if (dps == DS.T_NNt)
+ {
+ dps = DS.D_NNd;
+ }
+ }
+
+ bool atEnd = str.AtEnd();
+ if (dateParsingStates[(int)dps][(int)dtok.dtt] == DS.ERROR || atEnd)
+ {
+ switch (dtok.dtt)
+ {
+ // we have the case of Serbia have dates in forms 'd.M.yyyy.' so we can expect '.' after the date parts.
+ // changing the token to end with space instead of Date Separator will avoid failing the parsing.
+
+ case DTT.YearDateSep: dtok.dtt = atEnd ? DTT.YearEnd : DTT.YearSpace; break;
+ case DTT.NumDatesep: dtok.dtt = atEnd ? DTT.NumEnd : DTT.NumSpace; break;
+ case DTT.NumTimesep: dtok.dtt = atEnd ? DTT.NumEnd : DTT.NumSpace; break;
+ case DTT.MonthDatesep: dtok.dtt = atEnd ? DTT.MonthEnd : DTT.MonthSpace; break;
+ }
+ }
+ }
+
+ //
+ // Advance to the next state, and continue
+ //
+ dps = dateParsingStates[(int)dps][(int)dtok.dtt];
+
+ if (dps == DS.ERROR)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ TPTraceExit("0040 (invalid state transition)", dps);
+ return false;
+ }
+ else if (dps > DS.ERROR)
+ {
+ if ((dtfi.FormatFlags & DateTimeFormatFlags.UseHebrewRule) != 0)
+ {
+ if (!ProcessHebrewTerminalState(dps, ref result, ref styles, ref raw, dtfi))
+ {
+ TPTraceExit("0050 (ProcessHebrewTerminalState)", dps);
+ return false;
+ }
+ }
+ else
+ {
+ if (!ProcessTerminaltState(dps, ref result, ref styles, ref raw, dtfi))
+ {
+ TPTraceExit("0060 (ProcessTerminaltState)", dps);
+ return false;
+ }
+ }
+ reachTerminalState = true;
+
+ //
+ // If we have reached a terminal state, start over from DS.BEGIN again.
+ // For example, when we parsed "1999-12-23 13:30", we will reach a terminal state at "1999-12-23",
+ // and we start over so we can continue to parse "12:30".
+ //
+ dps = DS.BEGIN;
+ }
+ }
+ } while (dtok.dtt != DTT.End && dtok.dtt != DTT.NumEnd && dtok.dtt != DTT.MonthEnd);
+
+ if (!reachTerminalState)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ TPTraceExit("0070 (did not reach terminal state)", dps);
+ return false;
+ }
+
+ AdjustTimeMark(dtfi, ref raw);
+ if (!AdjustHour(ref result.Hour, raw.timeMark))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ TPTraceExit("0080 (AdjustHour)", dps);
+ return false;
+ }
+
+ // Check if the parased string only contains hour/minute/second values.
+ bool bTimeOnly = (result.Year == -1 && result.Month == -1 && result.Day == -1);
+
+ //
+ // Check if any year/month/day is missing in the parsing string.
+ // If yes, get the default value from today's date.
+ //
+ if (!CheckDefaultDateTime(ref result, ref result.calendar, styles))
+ {
+ TPTraceExit("0090 (failed to fill in missing year/month/day defaults)", dps);
+ return false;
+ }
+
+ if (!result.calendar.TryToDateTime(result.Year, result.Month, result.Day,
+ result.Hour, result.Minute, result.Second, 0, result.era, out time))
+ {
+ result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
+ TPTraceExit("0100 (result.calendar.TryToDateTime)", dps);
+ return false;
+ }
+ if (raw.fraction > 0)
+ {
+ time = time.AddTicks((long)Math.Round(raw.fraction * Calendar.TicksPerSecond));
+ }
+
+ //
+ // We have to check day of week before we adjust to the time zone.
+ // Otherwise, the value of day of week may change after adjustting to the time zone.
+ //
+ if (raw.dayOfWeek != -1)
+ {
+ //
+ // Check if day of week is correct.
+ //
+ if (raw.dayOfWeek != (int)result.calendar.GetDayOfWeek(time))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDayOfWeek", null);
+ TPTraceExit("0110 (dayOfWeek check)", dps);
+ return false;
+ }
+ }
+
+ result.parsedDate = time;
+
+ if (!DetermineTimeZoneAdjustments(ref result, styles, bTimeOnly))
+ {
+ TPTraceExit("0120 (DetermineTimeZoneAdjustments)", dps);
+ return false;
+ }
+ TPTraceExit("0130 (success)", dps);
+ return true;
+ }
+
+
+ // Handles time zone adjustments and sets DateTimeKind values as required by the styles
+ private static Boolean DetermineTimeZoneAdjustments(ref DateTimeResult result, DateTimeStyles styles, Boolean bTimeOnly)
+ {
+ if ((result.flags & ParseFlags.CaptureOffset) != 0)
+ {
+ // This is a DateTimeOffset parse, so the offset will actually be captured directly, and
+ // no adjustment is required in most cases
+ return DateTimeOffsetTimeZonePostProcessing(ref result, styles);
+ }
+ else
+ {
+ Int64 offsetTicks = result.timeZoneOffset.Ticks;
+
+ // the DateTime offset must be within +- 14:00 hours.
+ if (offsetTicks < DateTimeOffset.MinOffset || offsetTicks > DateTimeOffset.MaxOffset)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_OffsetOutOfRange", null);
+ return false;
+ }
+ }
+
+ // The flags AssumeUniveral and AssumeLocal only apply when the input does not have a time zone
+ if ((result.flags & ParseFlags.TimeZoneUsed) == 0)
+ {
+ // If AssumeLocal or AssumeLocal is used, there will always be a kind specified. As in the
+ // case when a time zone is present, it will default to being local unless AdjustToUniversal
+ // is present. These comparisons determine whether setting the kind is sufficient, or if a
+ // time zone adjustment is required. For consistentcy with the rest of parsing, it is desirable
+ // to fall through to the Adjust methods below, so that there is consist handling of boundary
+ // cases like wrapping around on time-only dates and temporarily allowing an adjusted date
+ // to exceed DateTime.MaxValue
+ if ((styles & DateTimeStyles.AssumeLocal) != 0)
+ {
+ if ((styles & DateTimeStyles.AdjustToUniversal) != 0)
+ {
+ result.flags |= ParseFlags.TimeZoneUsed;
+ result.timeZoneOffset = TimeZoneInfo.GetLocalUtcOffset(result.parsedDate, TimeZoneInfoOptions.NoThrowOnInvalidTime);
+ }
+ else
+ {
+ result.parsedDate = DateTime.SpecifyKind(result.parsedDate, DateTimeKind.Local);
+ return true;
+ }
+ }
+ else if ((styles & DateTimeStyles.AssumeUniversal) != 0)
+ {
+ if ((styles & DateTimeStyles.AdjustToUniversal) != 0)
+ {
+ result.parsedDate = DateTime.SpecifyKind(result.parsedDate, DateTimeKind.Utc);
+ return true;
+ }
+ else
+ {
+ result.flags |= ParseFlags.TimeZoneUsed;
+ result.timeZoneOffset = TimeSpan.Zero;
+ }
+ }
+ else
+ {
+ // No time zone and no Assume flags, so DateTimeKind.Unspecified is fine
+ Debug.Assert(result.parsedDate.Kind == DateTimeKind.Unspecified, "result.parsedDate.Kind == DateTimeKind.Unspecified");
+ return true;
+ }
+ }
+
+ if (((styles & DateTimeStyles.RoundtripKind) != 0) && ((result.flags & ParseFlags.TimeZoneUtc) != 0))
+ {
+ result.parsedDate = DateTime.SpecifyKind(result.parsedDate, DateTimeKind.Utc);
+ return true;
+ }
+
+ if ((styles & DateTimeStyles.AdjustToUniversal) != 0)
+ {
+ return (AdjustTimeZoneToUniversal(ref result));
+ }
+ return (AdjustTimeZoneToLocal(ref result, bTimeOnly));
+ }
+
+ // Apply validation and adjustments specific to DateTimeOffset
+ private static Boolean DateTimeOffsetTimeZonePostProcessing(ref DateTimeResult result, DateTimeStyles styles)
+ {
+ // For DateTimeOffset, default to the Utc or Local offset when an offset was not specified by
+ // the input string.
+ if ((result.flags & ParseFlags.TimeZoneUsed) == 0)
+ {
+ if ((styles & DateTimeStyles.AssumeUniversal) != 0)
+ {
+ // AssumeUniversal causes the offset to default to zero (0)
+ result.timeZoneOffset = TimeSpan.Zero;
+ }
+ else
+ {
+ // AssumeLocal causes the offset to default to Local. This flag is on by default for DateTimeOffset.
+ result.timeZoneOffset = TimeZoneInfo.GetLocalUtcOffset(result.parsedDate, TimeZoneInfoOptions.NoThrowOnInvalidTime);
+ }
+ }
+
+ Int64 offsetTicks = result.timeZoneOffset.Ticks;
+
+ // there should be no overflow, because the offset can be no more than -+100 hours and the date already
+ // fits within a DateTime.
+ Int64 utcTicks = result.parsedDate.Ticks - offsetTicks;
+
+ // For DateTimeOffset, both the parsed time and the corresponding UTC value must be within the boundaries
+ // of a DateTime instance.
+ if (utcTicks < DateTime.MinTicks || utcTicks > DateTime.MaxTicks)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_UTCOutOfRange", null);
+ return false;
+ }
+
+ // the offset must be within +- 14:00 hours.
+ if (offsetTicks < DateTimeOffset.MinOffset || offsetTicks > DateTimeOffset.MaxOffset)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_OffsetOutOfRange", null);
+ return false;
+ }
+
+ // DateTimeOffset should still honor the AdjustToUniversal flag for consistency with DateTime. It means you
+ // want to return an adjusted UTC value, so store the utcTicks in the DateTime and set the offset to zero
+ if ((styles & DateTimeStyles.AdjustToUniversal) != 0)
+ {
+ if (((result.flags & ParseFlags.TimeZoneUsed) == 0) && ((styles & DateTimeStyles.AssumeUniversal) == 0))
+ {
+ // Handle the special case where the timeZoneOffset was defaulted to Local
+ Boolean toUtcResult = AdjustTimeZoneToUniversal(ref result);
+ result.timeZoneOffset = TimeSpan.Zero;
+ return toUtcResult;
+ }
+
+ // The constructor should always succeed because of the range check earlier in the function
+ // Althought it is UTC, internally DateTimeOffset does not use this flag
+ result.parsedDate = new DateTime(utcTicks, DateTimeKind.Utc);
+ result.timeZoneOffset = TimeSpan.Zero;
+ }
+
+ return true;
+ }
+
+
+ //
+ // Adjust the specified time to universal time based on the supplied timezone.
+ // E.g. when parsing "2001/06/08 14:00-07:00",
+ // the time is 2001/06/08 14:00, and timeZoneOffset = -07:00.
+ // The result will be "2001/06/08 21:00"
+ //
+ private static Boolean AdjustTimeZoneToUniversal(ref DateTimeResult result)
+ {
+ long resultTicks = result.parsedDate.Ticks;
+ resultTicks -= result.timeZoneOffset.Ticks;
+ if (resultTicks < 0)
+ {
+ resultTicks += Calendar.TicksPerDay;
+ }
+
+ if (resultTicks < DateTime.MinTicks || resultTicks > DateTime.MaxTicks)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_DateOutOfRange", null);
+ return false;
+ }
+ result.parsedDate = new DateTime(resultTicks, DateTimeKind.Utc);
+ return true;
+ }
+
+ //
+ // Adjust the specified time to universal time based on the supplied timezone,
+ // and then convert to local time.
+ // E.g. when parsing "2001/06/08 14:00-04:00", and local timezone is GMT-7.
+ // the time is 2001/06/08 14:00, and timeZoneOffset = -05:00.
+ // The result will be "2001/06/08 11:00"
+ //
+ private static Boolean AdjustTimeZoneToLocal(ref DateTimeResult result, bool bTimeOnly)
+ {
+ long resultTicks = result.parsedDate.Ticks;
+ // Convert to local ticks
+ TimeZoneInfo tz = TimeZoneInfo.Local;
+ Boolean isAmbiguousLocalDst = false;
+ if (resultTicks < Calendar.TicksPerDay)
+ {
+ //
+ // This is time of day.
+ //
+
+ // Adjust timezone.
+ resultTicks -= result.timeZoneOffset.Ticks;
+ // If the time is time of day, use the current timezone offset.
+ resultTicks += tz.GetUtcOffset(bTimeOnly ? DateTime.Now : result.parsedDate, TimeZoneInfoOptions.NoThrowOnInvalidTime).Ticks;
+
+ if (resultTicks < 0)
+ {
+ resultTicks += Calendar.TicksPerDay;
+ }
+ }
+ else
+ {
+ // Adjust timezone to GMT.
+ resultTicks -= result.timeZoneOffset.Ticks;
+ if (resultTicks < DateTime.MinTicks || resultTicks > DateTime.MaxTicks)
+ {
+ // If the result ticks is greater than DateTime.MaxValue, we can not create a DateTime from this ticks.
+ // In this case, keep using the old code.
+ resultTicks += tz.GetUtcOffset(result.parsedDate, TimeZoneInfoOptions.NoThrowOnInvalidTime).Ticks;
+ }
+ else
+ {
+ // Convert the GMT time to local time.
+ DateTime utcDt = new DateTime(resultTicks, DateTimeKind.Utc);
+ Boolean isDaylightSavings = false;
+ resultTicks += TimeZoneInfo.GetUtcOffsetFromUtc(utcDt, TimeZoneInfo.Local, out isDaylightSavings, out isAmbiguousLocalDst).Ticks;
+ }
+ }
+ if (resultTicks < DateTime.MinTicks || resultTicks > DateTime.MaxTicks)
+ {
+ result.parsedDate = DateTime.MinValue;
+ result.SetFailure(ParseFailureKind.Format, "Format_DateOutOfRange", null);
+ return false;
+ }
+ result.parsedDate = new DateTime(resultTicks, DateTimeKind.Local, isAmbiguousLocalDst);
+ return true;
+ }
+
+ //
+ // Parse the ISO8601 format string found during Parse();
+ //
+ //
+ private static bool ParseISO8601(ref DateTimeRawInfo raw, ref __DTString str, DateTimeStyles styles, ref DateTimeResult result)
+ {
+ if (raw.year < 0 || raw.GetNumber(0) < 0 || raw.GetNumber(1) < 0)
+ {
+ }
+ str.Index--;
+ int hour, minute;
+ int second = 0;
+ double partSecond = 0;
+
+ str.SkipWhiteSpaces();
+ if (!ParseDigits(ref str, 2, out hour))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ str.SkipWhiteSpaces();
+ if (!str.Match(':'))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ str.SkipWhiteSpaces();
+ if (!ParseDigits(ref str, 2, out minute))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ str.SkipWhiteSpaces();
+ if (str.Match(':'))
+ {
+ str.SkipWhiteSpaces();
+ if (!ParseDigits(ref str, 2, out second))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ if (str.Match('.'))
+ {
+ if (!ParseFraction(ref str, out partSecond))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ str.Index--;
+ }
+ str.SkipWhiteSpaces();
+ }
+ if (str.GetNext())
+ {
+ char ch = str.GetChar();
+ if (ch == '+' || ch == '-')
+ {
+ result.flags |= ParseFlags.TimeZoneUsed;
+ if (!ParseTimeZone(ref str, ref result.timeZoneOffset))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ }
+ else if (ch == 'Z' || ch == 'z')
+ {
+ result.flags |= ParseFlags.TimeZoneUsed;
+ result.timeZoneOffset = TimeSpan.Zero;
+ result.flags |= ParseFlags.TimeZoneUtc;
+ }
+ else
+ {
+ str.Index--;
+ }
+ str.SkipWhiteSpaces();
+ if (str.Match('#'))
+ {
+ if (!VerifyValidPunctuation(ref str))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ str.SkipWhiteSpaces();
+ }
+ if (str.Match('\0'))
+ {
+ if (!VerifyValidPunctuation(ref str))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ }
+ if (str.GetNext())
+ {
+ // If this is true, there were non-white space characters remaining in the DateTime
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ }
+
+ DateTime time;
+ Calendar calendar = GregorianCalendar.GetDefaultInstance();
+ if (!calendar.TryToDateTime(raw.year, raw.GetNumber(0), raw.GetNumber(1),
+ hour, minute, second, 0, result.era, out time))
+ {
+ result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
+ return false;
+ }
+
+ time = time.AddTicks((long)Math.Round(partSecond * Calendar.TicksPerSecond));
+ result.parsedDate = time;
+ if (!DetermineTimeZoneAdjustments(ref result, styles, false))
+ {
+ return false;
+ }
+ return true;
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Actions:
+ // Parse the current word as a Hebrew number.
+ // This is used by DateTime.ParseExact().
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ internal static bool MatchHebrewDigits(ref __DTString str, int digitLen, out int number)
+ {
+ number = 0;
+
+ // Create a context object so that we can parse the Hebrew number text character by character.
+ HebrewNumberParsingContext context = new HebrewNumberParsingContext(0);
+
+ // Set this to ContinueParsing so that we will run the following while loop in the first time.
+ HebrewNumberParsingState state = HebrewNumberParsingState.ContinueParsing;
+
+ while (state == HebrewNumberParsingState.ContinueParsing && str.GetNext())
+ {
+ state = HebrewNumber.ParseByChar(str.GetChar(), ref context);
+ }
+
+ if (state == HebrewNumberParsingState.FoundEndOfHebrewNumber)
+ {
+ // If we have reached a terminal state, update the result and returns.
+ number = context.result;
+ return (true);
+ }
+
+ // If we run out of the character before reaching FoundEndOfHebrewNumber, or
+ // the state is InvalidHebrewNumber or ContinueParsing, we fail to match a Hebrew number.
+ // Return an error.
+ return false;
+ }
+
+ /*=================================ParseDigits==================================
+ **Action: Parse the number string in __DTString that are formatted using
+ ** the following patterns:
+ ** "0", "00", and "000..0"
+ **Returns: the integer value
+ **Arguments: str: a __DTString. The parsing will start from the
+ ** next character after str.Index.
+ **Exceptions: FormatException if error in parsing number.
+ ==============================================================================*/
+
+ internal static bool ParseDigits(ref __DTString str, int digitLen, out int result)
+ {
+ if (digitLen == 1)
+ {
+ // 1 really means 1 or 2 for this call
+ return ParseDigits(ref str, 1, 2, out result);
+ }
+ else
+ {
+ return ParseDigits(ref str, digitLen, digitLen, out result);
+ }
+ }
+
+ internal static bool ParseDigits(ref __DTString str, int minDigitLen, int maxDigitLen, out int result)
+ {
+ Debug.Assert(minDigitLen > 0, "minDigitLen > 0");
+ Debug.Assert(maxDigitLen < 9, "maxDigitLen < 9");
+ Debug.Assert(minDigitLen <= maxDigitLen, "minDigitLen <= maxDigitLen");
+ result = 0;
+ int startingIndex = str.Index;
+ int tokenLength = 0;
+ while (tokenLength < maxDigitLen)
+ {
+ if (!str.GetNextDigit())
+ {
+ str.Index--;
+ break;
+ }
+ result = result * 10 + str.GetDigit();
+ tokenLength++;
+ }
+ if (tokenLength < minDigitLen)
+ {
+ str.Index = startingIndex;
+ return false;
+ }
+ return true;
+ }
+
+ /*=================================ParseFractionExact==================================
+ **Action: Parse the number string in __DTString that are formatted using
+ ** the following patterns:
+ ** "0", "00", and "000..0"
+ **Returns: the fraction value
+ **Arguments: str: a __DTString. The parsing will start from the
+ ** next character after str.Index.
+ **Exceptions: FormatException if error in parsing number.
+ ==============================================================================*/
+
+ private static bool ParseFractionExact(ref __DTString str, int maxDigitLen, ref double result)
+ {
+ if (!str.GetNextDigit())
+ {
+ str.Index--;
+ return false;
+ }
+ result = str.GetDigit();
+
+ int digitLen = 1;
+ for (; digitLen < maxDigitLen; digitLen++)
+ {
+ if (!str.GetNextDigit())
+ {
+ str.Index--;
+ break;
+ }
+ result = result * 10 + str.GetDigit();
+ }
+
+ result = ((double)result / Math.Pow(10, digitLen));
+ return (digitLen == maxDigitLen);
+ }
+
+ /*=================================ParseSign==================================
+ **Action: Parse a positive or a negative sign.
+ **Returns: true if postive sign. flase if negative sign.
+ **Arguments: str: a __DTString. The parsing will start from the
+ ** next character after str.Index.
+ **Exceptions: FormatException if end of string is encountered or a sign
+ ** symbol is not found.
+ ==============================================================================*/
+
+ private static bool ParseSign(ref __DTString str, ref bool result)
+ {
+ if (!str.GetNext())
+ {
+ // A sign symbol ('+' or '-') is expected. However, end of string is encountered.
+ return false;
+ }
+ char ch = str.GetChar();
+ if (ch == '+')
+ {
+ result = true;
+ return (true);
+ }
+ else if (ch == '-')
+ {
+ result = false;
+ return (true);
+ }
+ // A sign symbol ('+' or '-') is expected.
+ return false;
+ }
+
+ /*=================================ParseTimeZoneOffset==================================
+ **Action: Parse the string formatted using "z", "zz", "zzz" in DateTime.Format().
+ **Returns: the TimeSpan for the parsed timezone offset.
+ **Arguments: str: a __DTString. The parsing will start from the
+ ** next character after str.Index.
+ ** len: the repeated number of the "z"
+ **Exceptions: FormatException if errors in parsing.
+ ==============================================================================*/
+
+ private static bool ParseTimeZoneOffset(ref __DTString str, int len, ref TimeSpan result)
+ {
+ bool isPositive = true;
+ int hourOffset;
+ int minuteOffset = 0;
+
+ switch (len)
+ {
+ case 1:
+ case 2:
+ if (!ParseSign(ref str, ref isPositive))
+ {
+ return (false);
+ }
+ if (!ParseDigits(ref str, len, out hourOffset))
+ {
+ return (false);
+ }
+ break;
+ default:
+ if (!ParseSign(ref str, ref isPositive))
+ {
+ return (false);
+ }
+
+ // Parsing 1 digit will actually parse 1 or 2.
+ if (!ParseDigits(ref str, 1, out hourOffset))
+ {
+ return (false);
+ }
+ // ':' is optional.
+ if (str.Match(":"))
+ {
+ // Found ':'
+ if (!ParseDigits(ref str, 2, out minuteOffset))
+ {
+ return (false);
+ }
+ }
+ else
+ {
+ // Since we can not match ':', put the char back.
+ str.Index--;
+ if (!ParseDigits(ref str, 2, out minuteOffset))
+ {
+ return (false);
+ }
+ }
+ break;
+ }
+ if (minuteOffset < 0 || minuteOffset >= 60)
+ {
+ return false;
+ }
+
+ result = (new TimeSpan(hourOffset, minuteOffset, 0));
+ if (!isPositive)
+ {
+ result = result.Negate();
+ }
+ return (true);
+ }
+
+ /*=================================MatchAbbreviatedMonthName==================================
+ **Action: Parse the abbreviated month name from string starting at str.Index.
+ **Returns: A value from 1 to 12 for the first month to the twelveth month.
+ **Arguments: str: a __DTString. The parsing will start from the
+ ** next character after str.Index.
+ **Exceptions: FormatException if an abbreviated month name can not be found.
+ ==============================================================================*/
+
+ private static bool MatchAbbreviatedMonthName(ref __DTString str, DateTimeFormatInfo dtfi, ref int result)
+ {
+ int maxMatchStrLen = 0;
+ result = -1;
+ if (str.GetNext())
+ {
+ //
+ // Scan the month names (note that some calendars has 13 months) and find
+ // the matching month name which has the max string length.
+ // We need to do this because some cultures (e.g. "cs-CZ") which have
+ // abbreviated month names with the same prefix.
+ //
+ int monthsInYear = (dtfi.GetMonthName(13).Length == 0 ? 12 : 13);
+ for (int i = 1; i <= monthsInYear; i++)
+ {
+ String searchStr = dtfi.GetAbbreviatedMonthName(i);
+ int matchStrLen = searchStr.Length;
+ if (dtfi.HasSpacesInMonthNames
+ ? str.MatchSpecifiedWords(searchStr, false, ref matchStrLen)
+ : str.MatchSpecifiedWord(searchStr))
+ {
+ if (matchStrLen > maxMatchStrLen)
+ {
+ maxMatchStrLen = matchStrLen;
+ result = i;
+ }
+ }
+ }
+
+ // Search leap year form.
+ if ((dtfi.FormatFlags & DateTimeFormatFlags.UseLeapYearMonth) != 0)
+ {
+ int tempResult = str.MatchLongestWords(dtfi.internalGetLeapYearMonthNames(), ref maxMatchStrLen);
+ // We found a longer match in the leap year month name. Use this as the result.
+ // The result from MatchLongestWords is 0 ~ length of word array.
+ // So we increment the result by one to become the month value.
+ if (tempResult >= 0)
+ {
+ result = tempResult + 1;
+ }
+ }
+ }
+ if (result > 0)
+ {
+ str.Index += (maxMatchStrLen - 1);
+ return (true);
+ }
+ return false;
+ }
+
+ /*=================================MatchMonthName==================================
+ **Action: Parse the month name from string starting at str.Index.
+ **Returns: A value from 1 to 12 indicating the first month to the twelveth month.
+ **Arguments: str: a __DTString. The parsing will start from the
+ ** next character after str.Index.
+ **Exceptions: FormatException if a month name can not be found.
+ ==============================================================================*/
+
+ private static bool MatchMonthName(ref __DTString str, DateTimeFormatInfo dtfi, ref int result)
+ {
+ int maxMatchStrLen = 0;
+ result = -1;
+ if (str.GetNext())
+ {
+ //
+ // Scan the month names (note that some calendars has 13 months) and find
+ // the matching month name which has the max string length.
+ // We need to do this because some cultures (e.g. "vi-VN") which have
+ // month names with the same prefix.
+ //
+ int monthsInYear = (dtfi.GetMonthName(13).Length == 0 ? 12 : 13);
+ for (int i = 1; i <= monthsInYear; i++)
+ {
+ String searchStr = dtfi.GetMonthName(i);
+ int matchStrLen = searchStr.Length;
+ if (dtfi.HasSpacesInMonthNames
+ ? str.MatchSpecifiedWords(searchStr, false, ref matchStrLen)
+ : str.MatchSpecifiedWord(searchStr))
+ {
+ if (matchStrLen > maxMatchStrLen)
+ {
+ maxMatchStrLen = matchStrLen;
+ result = i;
+ }
+ }
+ }
+
+ // Search genitive form.
+ if ((dtfi.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != 0)
+ {
+ int tempResult = str.MatchLongestWords(dtfi.MonthGenitiveNames, ref maxMatchStrLen);
+ // We found a longer match in the genitive month name. Use this as the result.
+ // The result from MatchLongestWords is 0 ~ length of word array.
+ // So we increment the result by one to become the month value.
+ if (tempResult >= 0)
+ {
+ result = tempResult + 1;
+ }
+ }
+
+ // Search leap year form.
+ if ((dtfi.FormatFlags & DateTimeFormatFlags.UseLeapYearMonth) != 0)
+ {
+ int tempResult = str.MatchLongestWords(dtfi.internalGetLeapYearMonthNames(), ref maxMatchStrLen);
+ // We found a longer match in the leap year month name. Use this as the result.
+ // The result from MatchLongestWords is 0 ~ length of word array.
+ // So we increment the result by one to become the month value.
+ if (tempResult >= 0)
+ {
+ result = tempResult + 1;
+ }
+ }
+ }
+
+ if (result > 0)
+ {
+ str.Index += (maxMatchStrLen - 1);
+ return (true);
+ }
+ return false;
+ }
+
+ /*=================================MatchAbbreviatedDayName==================================
+ **Action: Parse the abbreviated day of week name from string starting at str.Index.
+ **Returns: A value from 0 to 6 indicating Sunday to Saturday.
+ **Arguments: str: a __DTString. The parsing will start from the
+ ** next character after str.Index.
+ **Exceptions: FormatException if a abbreviated day of week name can not be found.
+ ==============================================================================*/
+
+ private static bool MatchAbbreviatedDayName(ref __DTString str, DateTimeFormatInfo dtfi, ref int result)
+ {
+ int maxMatchStrLen = 0;
+ result = -1;
+ if (str.GetNext())
+ {
+ for (DayOfWeek i = DayOfWeek.Sunday; i <= DayOfWeek.Saturday; i++)
+ {
+ String searchStr = dtfi.GetAbbreviatedDayName(i);
+ int matchStrLen = searchStr.Length;
+ if (dtfi.HasSpacesInDayNames
+ ? str.MatchSpecifiedWords(searchStr, false, ref matchStrLen)
+ : str.MatchSpecifiedWord(searchStr))
+ {
+ if (matchStrLen > maxMatchStrLen)
+ {
+ maxMatchStrLen = matchStrLen;
+ result = (int)i;
+ }
+ }
+ }
+ }
+ if (result >= 0)
+ {
+ str.Index += maxMatchStrLen - 1;
+ return (true);
+ }
+ return false;
+ }
+
+ /*=================================MatchDayName==================================
+ **Action: Parse the day of week name from string starting at str.Index.
+ **Returns: A value from 0 to 6 indicating Sunday to Saturday.
+ **Arguments: str: a __DTString. The parsing will start from the
+ ** next character after str.Index.
+ **Exceptions: FormatException if a day of week name can not be found.
+ ==============================================================================*/
+
+ private static bool MatchDayName(ref __DTString str, DateTimeFormatInfo dtfi, ref int result)
+ {
+ // Turkish (tr-TR) got day names with the same prefix.
+ int maxMatchStrLen = 0;
+ result = -1;
+ if (str.GetNext())
+ {
+ for (DayOfWeek i = DayOfWeek.Sunday; i <= DayOfWeek.Saturday; i++)
+ {
+ String searchStr = dtfi.GetDayName(i);
+ int matchStrLen = searchStr.Length;
+ if (dtfi.HasSpacesInDayNames
+ ? str.MatchSpecifiedWords(searchStr, false, ref matchStrLen)
+ : str.MatchSpecifiedWord(searchStr))
+ {
+ if (matchStrLen > maxMatchStrLen)
+ {
+ maxMatchStrLen = matchStrLen;
+ result = (int)i;
+ }
+ }
+ }
+ }
+ if (result >= 0)
+ {
+ str.Index += maxMatchStrLen - 1;
+ return (true);
+ }
+ return false;
+ }
+
+ /*=================================MatchEraName==================================
+ **Action: Parse era name from string starting at str.Index.
+ **Returns: An era value.
+ **Arguments: str: a __DTString. The parsing will start from the
+ ** next character after str.Index.
+ **Exceptions: FormatException if an era name can not be found.
+ ==============================================================================*/
+
+ private static bool MatchEraName(ref __DTString str, DateTimeFormatInfo dtfi, ref int result)
+ {
+ if (str.GetNext())
+ {
+ int[] eras = dtfi.Calendar.Eras;
+
+ if (eras != null)
+ {
+ for (int i = 0; i < eras.Length; i++)
+ {
+ String searchStr = dtfi.GetEraName(eras[i]);
+ if (str.MatchSpecifiedWord(searchStr))
+ {
+ str.Index += (searchStr.Length - 1);
+ result = eras[i];
+ return (true);
+ }
+ searchStr = dtfi.GetAbbreviatedEraName(eras[i]);
+ if (str.MatchSpecifiedWord(searchStr))
+ {
+ str.Index += (searchStr.Length - 1);
+ result = eras[i];
+ return (true);
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /*=================================MatchTimeMark==================================
+ **Action: Parse the time mark (AM/PM) from string starting at str.Index.
+ **Returns: TM_AM or TM_PM.
+ **Arguments: str: a __DTString. The parsing will start from the
+ ** next character after str.Index.
+ **Exceptions: FormatException if a time mark can not be found.
+ ==============================================================================*/
+
+ private static bool MatchTimeMark(ref __DTString str, DateTimeFormatInfo dtfi, ref TM result)
+ {
+ result = TM.NotSet;
+ // In some cultures have empty strings in AM/PM mark. E.g. af-ZA (0x0436), the AM mark is "", and PM mark is "nm".
+ if (dtfi.AMDesignator.Length == 0)
+ {
+ result = TM.AM;
+ }
+ if (dtfi.PMDesignator.Length == 0)
+ {
+ result = TM.PM;
+ }
+
+ if (str.GetNext())
+ {
+ String searchStr = dtfi.AMDesignator;
+ if (searchStr.Length > 0)
+ {
+ if (str.MatchSpecifiedWord(searchStr))
+ {
+ // Found an AM timemark with length > 0.
+ str.Index += (searchStr.Length - 1);
+ result = TM.AM;
+ return (true);
+ }
+ }
+ searchStr = dtfi.PMDesignator;
+ if (searchStr.Length > 0)
+ {
+ if (str.MatchSpecifiedWord(searchStr))
+ {
+ // Found a PM timemark with length > 0.
+ str.Index += (searchStr.Length - 1);
+ result = TM.PM;
+ return (true);
+ }
+ }
+ str.Index--; // Undo the GetNext call.
+ }
+ if (result != TM.NotSet)
+ {
+ // If one of the AM/PM marks is empty string, return the result.
+ return (true);
+ }
+ return false;
+ }
+
+ /*=================================MatchAbbreviatedTimeMark==================================
+ **Action: Parse the abbreviated time mark (AM/PM) from string starting at str.Index.
+ **Returns: TM_AM or TM_PM.
+ **Arguments: str: a __DTString. The parsing will start from the
+ ** next character after str.Index.
+ **Exceptions: FormatException if a abbreviated time mark can not be found.
+ ==============================================================================*/
+
+ private static bool MatchAbbreviatedTimeMark(ref __DTString str, DateTimeFormatInfo dtfi, ref TM result)
+ {
+ // NOTENOTE : the assumption here is that abbreviated time mark is the first
+ // character of the AM/PM designator. If this invariant changes, we have to
+ // change the code below.
+ if (str.GetNext())
+ {
+ if (str.GetChar() == dtfi.AMDesignator[0])
+ {
+ result = TM.AM;
+ return (true);
+ }
+ if (str.GetChar() == dtfi.PMDesignator[0])
+ {
+ result = TM.PM;
+ return (true);
+ }
+ }
+ return false;
+ }
+
+ /*=================================CheckNewValue==================================
+ **Action: Check if currentValue is initialized. If not, return the newValue.
+ ** If yes, check if the current value is equal to newValue. Return false
+ ** if they are not equal. This is used to check the case like "d" and "dd" are both
+ ** used to format a string.
+ **Returns: the correct value for currentValue.
+ **Arguments:
+ **Exceptions:
+ ==============================================================================*/
+
+ private static bool CheckNewValue(ref int currentValue, int newValue, char patternChar, ref DateTimeResult result)
+ {
+ if (currentValue == -1)
+ {
+ currentValue = newValue;
+ return (true);
+ }
+ else
+ {
+ if (newValue != currentValue)
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", patternChar);
+ return (false);
+ }
+ }
+ return (true);
+ }
+
+ private static DateTime GetDateTimeNow(ref DateTimeResult result, ref DateTimeStyles styles)
+ {
+ if ((result.flags & ParseFlags.CaptureOffset) != 0)
+ {
+ if ((result.flags & ParseFlags.TimeZoneUsed) != 0)
+ {
+ // use the supplied offset to calculate 'Now'
+ return new DateTime(DateTime.UtcNow.Ticks + result.timeZoneOffset.Ticks, DateTimeKind.Unspecified);
+ }
+ else if ((styles & DateTimeStyles.AssumeUniversal) != 0)
+ {
+ // assume the offset is Utc
+ return DateTime.UtcNow;
+ }
+ }
+
+ // assume the offset is Local
+ return DateTime.Now;
+ }
+
+ private static bool CheckDefaultDateTime(ref DateTimeResult result, ref Calendar cal, DateTimeStyles styles)
+ {
+ if ((result.flags & ParseFlags.CaptureOffset) != 0)
+ {
+ // DateTimeOffset.Parse should allow dates without a year, but only if there is also no time zone marker;
+ // e.g. "May 1 5pm" is OK, but "May 1 5pm -08:30" is not. This is somewhat pragmatic, since we would
+ // have to rearchitect parsing completely to allow this one case to correctly handle things like leap
+ // years and leap months. Is is an extremely corner case, and DateTime is basically incorrect in that
+ // case today.
+ //
+ // values like "11:00Z" or "11:00 -3:00" are also acceptable
+ //
+ // if ((month or day is set) and (year is not set and time zone is set))
+ //
+ if (((result.Month != -1) || (result.Day != -1))
+ && ((result.Year == -1 || ((result.flags & ParseFlags.YearDefault) != 0)) && (result.flags & ParseFlags.TimeZoneUsed) != 0))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_MissingIncompleteDate", null);
+ return false;
+ }
+ }
+
+
+ if ((result.Year == -1) || (result.Month == -1) || (result.Day == -1))
+ {
+ /*
+ The following table describes the behaviors of getting the default value
+ when a certain year/month/day values are missing.
+
+ An "X" means that the value exists. And "--" means that value is missing.
+
+ Year Month Day => ResultYear ResultMonth ResultDay Note
+
+ X X X Parsed year Parsed month Parsed day
+ X X -- Parsed Year Parsed month First day If we have year and month, assume the first day of that month.
+ X -- X Parsed year First month Parsed day If the month is missing, assume first month of that year.
+ X -- -- Parsed year First month First day If we have only the year, assume the first day of that year.
+
+ -- X X CurrentYear Parsed month Parsed day If the year is missing, assume the current year.
+ -- X -- CurrentYear Parsed month First day If we have only a month value, assume the current year and current day.
+ -- -- X CurrentYear First month Parsed day If we have only a day value, assume current year and first month.
+ -- -- -- CurrentYear Current month Current day So this means that if the date string only contains time, you will get current date.
+
+ */
+
+ DateTime now = GetDateTimeNow(ref result, ref styles);
+ if (result.Month == -1 && result.Day == -1)
+ {
+ if (result.Year == -1)
+ {
+ if ((styles & DateTimeStyles.NoCurrentDateDefault) != 0)
+ {
+ // If there is no year/month/day values, and NoCurrentDateDefault flag is used,
+ // set the year/month/day value to the beginning year/month/day of DateTime().
+ // Note we should be using Gregorian for the year/month/day.
+ cal = GregorianCalendar.GetDefaultInstance();
+ result.Year = result.Month = result.Day = 1;
+ }
+ else
+ {
+ // Year/Month/Day are all missing.
+ result.Year = cal.GetYear(now);
+ result.Month = cal.GetMonth(now);
+ result.Day = cal.GetDayOfMonth(now);
+ }
+ }
+ else
+ {
+ // Month/Day are both missing.
+ result.Month = 1;
+ result.Day = 1;
+ }
+ }
+ else
+ {
+ if (result.Year == -1)
+ {
+ result.Year = cal.GetYear(now);
+ }
+ if (result.Month == -1)
+ {
+ result.Month = 1;
+ }
+ if (result.Day == -1)
+ {
+ result.Day = 1;
+ }
+ }
+ }
+ // Set Hour/Minute/Second to zero if these value are not in str.
+ if (result.Hour == -1) result.Hour = 0;
+ if (result.Minute == -1) result.Minute = 0;
+ if (result.Second == -1) result.Second = 0;
+ if (result.era == -1) result.era = Calendar.CurrentEra;
+ return true;
+ }
+
+ // Expand a pre-defined format string (like "D" for long date) to the real format that
+ // we are going to use in the date time parsing.
+ // This method also set the dtfi according/parseInfo to some special pre-defined
+ // formats.
+ //
+ private static String ExpandPredefinedFormat(String format, ref DateTimeFormatInfo dtfi, ref ParsingInfo parseInfo, ref DateTimeResult result)
+ {
+ //
+ // Check the format to see if we need to override the dtfi to be InvariantInfo,
+ // and see if we need to set up the userUniversalTime flag.
+ //
+ switch (format[0])
+ {
+ case 'o':
+ case 'O': // Round Trip Format
+ parseInfo.calendar = GregorianCalendar.GetDefaultInstance();
+ dtfi = DateTimeFormatInfo.InvariantInfo;
+ break;
+ case 'r':
+ case 'R': // RFC 1123 Standard. (in Universal time)
+ parseInfo.calendar = GregorianCalendar.GetDefaultInstance();
+ dtfi = DateTimeFormatInfo.InvariantInfo;
+
+ if ((result.flags & ParseFlags.CaptureOffset) != 0)
+ {
+ result.flags |= ParseFlags.Rfc1123Pattern;
+ }
+ break;
+ case 's': // Sortable format (in local time)
+ dtfi = DateTimeFormatInfo.InvariantInfo;
+ parseInfo.calendar = GregorianCalendar.GetDefaultInstance();
+ break;
+ case 'u': // Universal time format in sortable format.
+ parseInfo.calendar = GregorianCalendar.GetDefaultInstance();
+ dtfi = DateTimeFormatInfo.InvariantInfo;
+
+ if ((result.flags & ParseFlags.CaptureOffset) != 0)
+ {
+ result.flags |= ParseFlags.UtcSortPattern;
+ }
+ break;
+ case 'U': // Universal time format with culture-dependent format.
+ parseInfo.calendar = GregorianCalendar.GetDefaultInstance();
+ result.flags |= ParseFlags.TimeZoneUsed;
+ result.timeZoneOffset = new TimeSpan(0);
+ result.flags |= ParseFlags.TimeZoneUtc;
+ if (dtfi.Calendar.GetType() != typeof(GregorianCalendar))
+ {
+ dtfi = (DateTimeFormatInfo)dtfi.Clone();
+ dtfi.Calendar = GregorianCalendar.GetDefaultInstance();
+ }
+ break;
+ }
+
+ //
+ // Expand the pre-defined format character to the real format from DateTimeFormatInfo.
+ //
+ return (DateTimeFormat.GetRealFormat(format, dtfi));
+ }
+
+
+
+
+
+ // Given a specified format character, parse and update the parsing result.
+ //
+ private static bool ParseByFormat(
+ ref __DTString str,
+ ref __DTString format,
+ ref ParsingInfo parseInfo,
+ DateTimeFormatInfo dtfi,
+ ref DateTimeResult result)
+ {
+ int tokenLen = 0;
+ int tempYear = 0, tempMonth = 0, tempDay = 0, tempDayOfWeek = 0, tempHour = 0, tempMinute = 0, tempSecond = 0;
+ double tempFraction = 0;
+ TM tempTimeMark = 0;
+
+ char ch = format.GetChar();
+
+ switch (ch)
+ {
+ case 'y':
+ tokenLen = format.GetRepeatCount();
+ bool parseResult;
+ if (dtfi.HasForceTwoDigitYears)
+ {
+ parseResult = ParseDigits(ref str, 1, 4, out tempYear);
+ }
+ else
+ {
+ if (tokenLen <= 2)
+ {
+ parseInfo.fUseTwoDigitYear = true;
+ }
+ parseResult = ParseDigits(ref str, tokenLen, out tempYear);
+ }
+ if (!parseResult && parseInfo.fCustomNumberParser)
+ {
+ parseResult = parseInfo.parseNumberDelegate(ref str, tokenLen, out tempYear);
+ }
+ if (!parseResult)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ if (!CheckNewValue(ref result.Year, tempYear, ch, ref result))
+ {
+ return (false);
+ }
+ break;
+ case 'M':
+ tokenLen = format.GetRepeatCount();
+ if (tokenLen <= 2)
+ {
+ if (!ParseDigits(ref str, tokenLen, out tempMonth))
+ {
+ if (!parseInfo.fCustomNumberParser ||
+ !parseInfo.parseNumberDelegate(ref str, tokenLen, out tempMonth))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ }
+ }
+ else
+ {
+ if (tokenLen == 3)
+ {
+ if (!MatchAbbreviatedMonthName(ref str, dtfi, ref tempMonth))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ }
+ else
+ {
+ if (!MatchMonthName(ref str, dtfi, ref tempMonth))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ }
+ result.flags |= ParseFlags.ParsedMonthName;
+ }
+ if (!CheckNewValue(ref result.Month, tempMonth, ch, ref result))
+ {
+ return (false);
+ }
+ break;
+ case 'd':
+ // Day & Day of week
+ tokenLen = format.GetRepeatCount();
+ if (tokenLen <= 2)
+ {
+ // "d" & "dd"
+
+ if (!ParseDigits(ref str, tokenLen, out tempDay))
+ {
+ if (!parseInfo.fCustomNumberParser ||
+ !parseInfo.parseNumberDelegate(ref str, tokenLen, out tempDay))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ }
+ if (!CheckNewValue(ref result.Day, tempDay, ch, ref result))
+ {
+ return (false);
+ }
+ }
+ else
+ {
+ if (tokenLen == 3)
+ {
+ // "ddd"
+ if (!MatchAbbreviatedDayName(ref str, dtfi, ref tempDayOfWeek))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ }
+ else
+ {
+ // "dddd*"
+ if (!MatchDayName(ref str, dtfi, ref tempDayOfWeek))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ }
+ if (!CheckNewValue(ref parseInfo.dayOfWeek, tempDayOfWeek, ch, ref result))
+ {
+ return (false);
+ }
+ }
+ break;
+ case 'g':
+ tokenLen = format.GetRepeatCount();
+ // Put the era value in result.era.
+ if (!MatchEraName(ref str, dtfi, ref result.era))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ break;
+ case 'h':
+ parseInfo.fUseHour12 = true;
+ tokenLen = format.GetRepeatCount();
+ if (!ParseDigits(ref str, (tokenLen < 2 ? 1 : 2), out tempHour))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ if (!CheckNewValue(ref result.Hour, tempHour, ch, ref result))
+ {
+ return (false);
+ }
+ break;
+ case 'H':
+ tokenLen = format.GetRepeatCount();
+ if (!ParseDigits(ref str, (tokenLen < 2 ? 1 : 2), out tempHour))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ if (!CheckNewValue(ref result.Hour, tempHour, ch, ref result))
+ {
+ return (false);
+ }
+ break;
+ case 'm':
+ tokenLen = format.GetRepeatCount();
+ if (!ParseDigits(ref str, (tokenLen < 2 ? 1 : 2), out tempMinute))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ if (!CheckNewValue(ref result.Minute, tempMinute, ch, ref result))
+ {
+ return (false);
+ }
+ break;
+ case 's':
+ tokenLen = format.GetRepeatCount();
+ if (!ParseDigits(ref str, (tokenLen < 2 ? 1 : 2), out tempSecond))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ if (!CheckNewValue(ref result.Second, tempSecond, ch, ref result))
+ {
+ return (false);
+ }
+ break;
+ case 'f':
+ case 'F':
+ tokenLen = format.GetRepeatCount();
+ if (tokenLen <= DateTimeFormat.MaxSecondsFractionDigits)
+ {
+ if (!ParseFractionExact(ref str, tokenLen, ref tempFraction))
+ {
+ if (ch == 'f')
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ }
+ if (result.fraction < 0)
+ {
+ result.fraction = tempFraction;
+ }
+ else
+ {
+ if (tempFraction != result.fraction)
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", ch);
+ return (false);
+ }
+ }
+ }
+ else
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ break;
+ case 't':
+ // AM/PM designator
+ tokenLen = format.GetRepeatCount();
+ if (tokenLen == 1)
+ {
+ if (!MatchAbbreviatedTimeMark(ref str, dtfi, ref tempTimeMark))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ }
+ else
+ {
+ if (!MatchTimeMark(ref str, dtfi, ref tempTimeMark))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ }
+
+ if (parseInfo.timeMark == TM.NotSet)
+ {
+ parseInfo.timeMark = tempTimeMark;
+ }
+ else
+ {
+ if (parseInfo.timeMark != tempTimeMark)
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", ch);
+ return (false);
+ }
+ }
+ break;
+ case 'z':
+ // timezone offset
+ tokenLen = format.GetRepeatCount();
+ {
+ TimeSpan tempTimeZoneOffset = new TimeSpan(0);
+ if (!ParseTimeZoneOffset(ref str, tokenLen, ref tempTimeZoneOffset))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ if ((result.flags & ParseFlags.TimeZoneUsed) != 0 && tempTimeZoneOffset != result.timeZoneOffset)
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'z');
+ return (false);
+ }
+ result.timeZoneOffset = tempTimeZoneOffset;
+ result.flags |= ParseFlags.TimeZoneUsed;
+ }
+ break;
+ case 'Z':
+ if ((result.flags & ParseFlags.TimeZoneUsed) != 0 && result.timeZoneOffset != TimeSpan.Zero)
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'Z');
+ return (false);
+ }
+
+ result.flags |= ParseFlags.TimeZoneUsed;
+ result.timeZoneOffset = new TimeSpan(0);
+ result.flags |= ParseFlags.TimeZoneUtc;
+
+ // The updating of the indexes is to reflect that ParseExact MatchXXX methods assume that
+ // they need to increment the index and Parse GetXXX do not. Since we are calling a Parse
+ // method from inside ParseExact we need to adjust this. Long term, we should try to
+ // eliminate this discrepancy.
+ str.Index++;
+ if (!GetTimeZoneName(ref str))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ str.Index--;
+ break;
+ case 'K':
+ // This should parse either as a blank, the 'Z' character or a local offset like "-07:00"
+ if (str.Match('Z'))
+ {
+ if ((result.flags & ParseFlags.TimeZoneUsed) != 0 && result.timeZoneOffset != TimeSpan.Zero)
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'K');
+ return (false);
+ }
+
+ result.flags |= ParseFlags.TimeZoneUsed;
+ result.timeZoneOffset = new TimeSpan(0);
+ result.flags |= ParseFlags.TimeZoneUtc;
+ }
+ else if (str.Match('+') || str.Match('-'))
+ {
+ str.Index--; // Put the character back for the parser
+ TimeSpan tempTimeZoneOffset = new TimeSpan(0);
+ if (!ParseTimeZoneOffset(ref str, 3, ref tempTimeZoneOffset))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return (false);
+ }
+ if ((result.flags & ParseFlags.TimeZoneUsed) != 0 && tempTimeZoneOffset != result.timeZoneOffset)
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'K');
+ return (false);
+ }
+ result.timeZoneOffset = tempTimeZoneOffset;
+ result.flags |= ParseFlags.TimeZoneUsed;
+ }
+ // Otherwise it is unspecified and we consume no characters
+ break;
+ case ':':
+ // We match the separator in time pattern with the character in the time string if both equal to ':' or the date separator is matching the characters in the date string
+ // We have to exclude the case when the time separator is more than one character and starts with ':' something like "::" for instance.
+ if (((dtfi.TimeSeparator.Length > 1 && dtfi.TimeSeparator[0] == ':') || !str.Match(':')) &&
+ !str.Match(dtfi.TimeSeparator))
+ {
+ // A time separator is expected.
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ break;
+ case '/':
+ // We match the separator in date pattern with the character in the date string if both equal to '/' or the date separator is matching the characters in the date string
+ // We have to exclude the case when the date separator is more than one character and starts with '/' something like "//" for instance.
+ if (((dtfi.DateSeparator.Length > 1 && dtfi.DateSeparator[0] == '/') || !str.Match('/')) &&
+ !str.Match(dtfi.DateSeparator))
+ {
+ // A date separator is expected.
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ break;
+ case '\"':
+ case '\'':
+ StringBuilder enquotedString = new StringBuilder();
+ // Use ParseQuoteString so that we can handle escape characters within the quoted string.
+ if (!TryParseQuoteString(format.Value, format.Index, enquotedString, out tokenLen))
+ {
+ result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadQuote", ch);
+ return (false);
+ }
+ format.Index += tokenLen - 1;
+
+ // Some cultures uses space in the quoted string. E.g. Spanish has long date format as:
+ // "dddd, dd' de 'MMMM' de 'yyyy". When inner spaces flag is set, we should skip whitespaces if there is space
+ // in the quoted string.
+ String quotedStr = enquotedString.ToString();
+
+ for (int i = 0; i < quotedStr.Length; i++)
+ {
+ if (quotedStr[i] == ' ' && parseInfo.fAllowInnerWhite)
+ {
+ str.SkipWhiteSpaces();
+ }
+ else if (!str.Match(quotedStr[i]))
+ {
+ // Can not find the matching quoted string.
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ }
+
+ // The "r" and "u" formats incorrectly quoted 'GMT' and 'Z', respectively. We cannot
+ // correct this mistake for DateTime.ParseExact for compatibility reasons, but we can
+ // fix it for DateTimeOffset.ParseExact as DateTimeOffset has not been publically released
+ // with this issue.
+ if ((result.flags & ParseFlags.CaptureOffset) != 0)
+ {
+ if ((result.flags & ParseFlags.Rfc1123Pattern) != 0 && quotedStr == GMTName)
+ {
+ result.flags |= ParseFlags.TimeZoneUsed;
+ result.timeZoneOffset = TimeSpan.Zero;
+ }
+ else if ((result.flags & ParseFlags.UtcSortPattern) != 0 && quotedStr == ZuluName)
+ {
+ result.flags |= ParseFlags.TimeZoneUsed;
+ result.timeZoneOffset = TimeSpan.Zero;
+ }
+ }
+
+ break;
+ case '%':
+ // Skip this so we can get to the next pattern character.
+ // Used in case like "%d", "%y"
+
+ // Make sure the next character is not a '%' again.
+ if (format.Index >= format.Value.Length - 1 || format.Value[format.Index + 1] == '%')
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null);
+ return false;
+ }
+ break;
+ case '\\':
+ // Escape character. For example, "\d".
+ // Get the next character in format, and see if we can
+ // find a match in str.
+ if (format.GetNext())
+ {
+ if (!str.Match(format.GetChar()))
+ {
+ // Can not find a match for the escaped character.
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ }
+ else
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null);
+ return false;
+ }
+ break;
+ case '.':
+ if (!str.Match(ch))
+ {
+ if (format.GetNext())
+ {
+ // If we encounter the pattern ".F", and the dot is not present, it is an optional
+ // second fraction and we can skip this format.
+ if (format.Match('F'))
+ {
+ format.GetRepeatCount();
+ break;
+ }
+ }
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ break;
+ default:
+ if (ch == ' ')
+ {
+ if (parseInfo.fAllowInnerWhite)
+ {
+ // Skip whitespaces if AllowInnerWhite.
+ // Do nothing here.
+ }
+ else
+ {
+ if (!str.Match(ch))
+ {
+ // If the space does not match, and trailing space is allowed, we do
+ // one more step to see if the next format character can lead to
+ // successful parsing.
+ // This is used to deal with special case that a empty string can match
+ // a specific pattern.
+ // The example here is af-ZA, which has a time format like "hh:mm:ss tt". However,
+ // its AM symbol is "" (empty string). If fAllowTrailingWhite is used, and time is in
+ // the AM, we will trim the whitespaces at the end, which will lead to a failure
+ // when we are trying to match the space before "tt".
+ if (parseInfo.fAllowTrailingWhite)
+ {
+ if (format.GetNext())
+ {
+ if (ParseByFormat(ref str, ref format, ref parseInfo, dtfi, ref result))
+ {
+ return (true);
+ }
+ }
+ }
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ // Found a macth.
+ }
+ }
+ else
+ {
+ if (format.MatchSpecifiedWord(GMTName))
+ {
+ format.Index += (GMTName.Length - 1);
+ // Found GMT string in format. This means the DateTime string
+ // is in GMT timezone.
+ result.flags |= ParseFlags.TimeZoneUsed;
+ result.timeZoneOffset = TimeSpan.Zero;
+ if (!str.Match(GMTName))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ }
+ else if (!str.Match(ch))
+ {
+ // ch is expected.
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ }
+ break;
+ } // switch
+ return (true);
+ }
+
+ //
+ // The pos should point to a quote character. This method will
+ // get the string enclosed by the quote character.
+ //
+ internal static bool TryParseQuoteString(String format, int pos, StringBuilder result, out int returnValue)
+ {
+ //
+ // NOTE : pos will be the index of the quote character in the 'format' string.
+ //
+ returnValue = 0;
+ int formatLen = format.Length;
+ int beginPos = pos;
+ char quoteChar = format[pos++]; // Get the character used to quote the following string.
+
+ bool foundQuote = false;
+ while (pos < formatLen)
+ {
+ char ch = format[pos++];
+ if (ch == quoteChar)
+ {
+ foundQuote = true;
+ break;
+ }
+ else if (ch == '\\')
+ {
+ // The following are used to support escaped character.
+ // Escaped character is also supported in the quoted string.
+ // Therefore, someone can use a format like "'minute:' mm\"" to display:
+ // minute: 45"
+ // because the second double quote is escaped.
+ if (pos < formatLen)
+ {
+ result.Append(format[pos++]);
+ }
+ else
+ {
+ //
+ // This means that '\' is at the end of the formatting string.
+ //
+ return false;
+ }
+ }
+ else
+ {
+ result.Append(ch);
+ }
+ }
+
+ if (!foundQuote)
+ {
+ // Here we can't find the matching quote.
+ return false;
+ }
+
+ //
+ // Return the character count including the begin/end quote characters and enclosed string.
+ //
+ returnValue = (pos - beginPos);
+ return true;
+ }
+
+
+
+
+ /*=================================DoStrictParse==================================
+ **Action: Do DateTime parsing using the format in formatParam.
+ **Returns: The parsed DateTime.
+ **Arguments:
+ **Exceptions:
+ **
+ **Notes:
+ ** When the following general formats are used, InvariantInfo is used in dtfi:
+ ** 'r', 'R', 's'.
+ ** When the following general formats are used, the time is assumed to be in Universal time.
+ **
+ **Limitations:
+ ** Only GregarianCalendar is supported for now.
+ ** Only support GMT timezone.
+ ==============================================================================*/
+
+ private static bool DoStrictParse(
+ String s,
+ String formatParam,
+ DateTimeStyles styles,
+ DateTimeFormatInfo dtfi,
+ ref DateTimeResult result)
+ {
+ ParsingInfo parseInfo = new ParsingInfo();
+ parseInfo.Init();
+
+ parseInfo.calendar = dtfi.Calendar;
+ parseInfo.fAllowInnerWhite = ((styles & DateTimeStyles.AllowInnerWhite) != 0);
+ parseInfo.fAllowTrailingWhite = ((styles & DateTimeStyles.AllowTrailingWhite) != 0);
+
+ // We need the original values of the following two below.
+ String originalFormat = formatParam;
+
+ if (formatParam.Length == 1)
+ {
+ if (((result.flags & ParseFlags.CaptureOffset) != 0) && formatParam[0] == 'U')
+ {
+ // The 'U' format is not allowed for DateTimeOffset
+ result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null);
+ return false;
+ }
+ formatParam = ExpandPredefinedFormat(formatParam, ref dtfi, ref parseInfo, ref result);
+ }
+
+ bool bTimeOnly = false;
+ result.calendar = parseInfo.calendar;
+
+ if (parseInfo.calendar.ID == CalendarId.HEBREW)
+ {
+ parseInfo.parseNumberDelegate = m_hebrewNumberParser;
+ parseInfo.fCustomNumberParser = true;
+ }
+
+ // Reset these values to negative one so that we could throw exception
+ // if we have parsed every item twice.
+ result.Hour = result.Minute = result.Second = -1;
+
+ __DTString format = new __DTString(formatParam, dtfi, false);
+ __DTString str = new __DTString(s, dtfi, false);
+
+ if (parseInfo.fAllowTrailingWhite)
+ {
+ // Trim trailing spaces if AllowTrailingWhite.
+ format.TrimTail();
+ format.RemoveTrailingInQuoteSpaces();
+ str.TrimTail();
+ }
+
+ if ((styles & DateTimeStyles.AllowLeadingWhite) != 0)
+ {
+ format.SkipWhiteSpaces();
+ format.RemoveLeadingInQuoteSpaces();
+ str.SkipWhiteSpaces();
+ }
+
+ //
+ // Scan every character in format and match the pattern in str.
+ //
+ while (format.GetNext())
+ {
+ // We trim inner spaces here, so that we will not eat trailing spaces when
+ // AllowTrailingWhite is not used.
+ if (parseInfo.fAllowInnerWhite)
+ {
+ str.SkipWhiteSpaces();
+ }
+ if (!ParseByFormat(ref str, ref format, ref parseInfo, dtfi, ref result))
+ {
+ return (false);
+ }
+ }
+
+ if (str.Index < str.Value.Length - 1)
+ {
+ // There are still remaining character in str.
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+
+ if (parseInfo.fUseTwoDigitYear && ((dtfi.FormatFlags & DateTimeFormatFlags.UseHebrewRule) == 0))
+ {
+ // A two digit year value is expected. Check if the parsed year value is valid.
+ if (result.Year >= 100)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ try
+ {
+ result.Year = parseInfo.calendar.ToFourDigitYear(result.Year);
+ }
+ catch (ArgumentOutOfRangeException e)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", e);
+ return false;
+ }
+ }
+
+ if (parseInfo.fUseHour12)
+ {
+ if (parseInfo.timeMark == TM.NotSet)
+ {
+ // hh is used, but no AM/PM designator is specified.
+ // Assume the time is AM.
+ // Don't throw exceptions in here becasue it is very confusing for the caller.
+ // I always got confused myself when I use "hh:mm:ss" to parse a time string,
+ // and ParseExact() throws on me (because I didn't use the 24-hour clock 'HH').
+ parseInfo.timeMark = TM.AM;
+ }
+ if (result.Hour > 12)
+ {
+ // AM/PM is used, but the value for HH is too big.
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ if (parseInfo.timeMark == TM.AM)
+ {
+ if (result.Hour == 12)
+ {
+ result.Hour = 0;
+ }
+ }
+ else
+ {
+ result.Hour = (result.Hour == 12) ? 12 : result.Hour + 12;
+ }
+ }
+ else
+ {
+ // Military (24-hour time) mode
+ //
+ // AM cannot be set with a 24-hour time like 17:15.
+ // PM cannot be set with a 24-hour time like 03:15.
+ if ((parseInfo.timeMark == TM.AM && result.Hour >= 12)
+ || (parseInfo.timeMark == TM.PM && result.Hour < 12))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
+ return false;
+ }
+ }
+
+
+ // Check if the parased string only contains hour/minute/second values.
+ bTimeOnly = (result.Year == -1 && result.Month == -1 && result.Day == -1);
+ if (!CheckDefaultDateTime(ref result, ref parseInfo.calendar, styles))
+ {
+ return false;
+ }
+
+ if (!bTimeOnly && dtfi.HasYearMonthAdjustment)
+ {
+ if (!dtfi.YearMonthAdjustment(ref result.Year, ref result.Month, ((result.flags & ParseFlags.ParsedMonthName) != 0)))
+ {
+ result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
+ return false;
+ }
+ }
+ if (!parseInfo.calendar.TryToDateTime(result.Year, result.Month, result.Day,
+ result.Hour, result.Minute, result.Second, 0, result.era, out result.parsedDate))
+ {
+ result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
+ return false;
+ }
+ if (result.fraction > 0)
+ {
+ result.parsedDate = result.parsedDate.AddTicks((long)Math.Round(result.fraction * Calendar.TicksPerSecond));
+ }
+
+ //
+ // We have to check day of week before we adjust to the time zone.
+ // It is because the value of day of week may change after adjusting
+ // to the time zone.
+ //
+ if (parseInfo.dayOfWeek != -1)
+ {
+ //
+ // Check if day of week is correct.
+ //
+ if (parseInfo.dayOfWeek != (int)parseInfo.calendar.GetDayOfWeek(result.parsedDate))
+ {
+ result.SetFailure(ParseFailureKind.Format, "Format_BadDayOfWeek", null);
+ return false;
+ }
+ }
+
+
+ if (!DetermineTimeZoneAdjustments(ref result, styles, bTimeOnly))
+ {
+ return false;
+ }
+ return true;
+ }
+
+ private static Exception GetDateTimeParseException(ref DateTimeResult result)
+ {
+ switch (result.failure)
+ {
+ case ParseFailureKind.ArgumentNull:
+ return new ArgumentNullException(result.failureArgumentName, SR.GetResourceString(result.failureMessageID));
+ case ParseFailureKind.Format:
+ return new FormatException(SR.GetResourceString(result.failureMessageID));
+ case ParseFailureKind.FormatWithParameter:
+ return new FormatException(SR.Format(SR.GetResourceString(result.failureMessageID), result.failureMessageFormatArgument));
+ case ParseFailureKind.FormatBadDateTimeCalendar:
+ return new FormatException(SR.Format(SR.GetResourceString(result.failureMessageID), result.calendar));
+ default:
+ Debug.Assert(false, "Unkown DateTimeParseFailure: " + result);
+ return null;
+ }
+ }
+
+ // Builds with _LOGGING defined (x86dbg, amd64chk, etc) support tracing
+ // Set the following internal-only/unsupported environment variables to enable DateTime tracing to the console:
+ //
+ // COMPlus_LogEnable=1
+ // COMPlus_LogToConsole=1
+ // COMPlus_LogLevel=9
+ // COMPlus_ManagedLogFacility=0x00001000
+ [Pure]
+ [Conditional("_LOGGING")]
+ internal static void LexTraceExit(string message, DS dps)
+ {
+#if _LOGGING
+ if (!_tracingEnabled)
+ return;
+ BCLDebug.Trace("DATETIME", "[DATETIME] Lex return {0}, DS.{1}", message, dps);
+#endif // _LOGGING
+ }
+ [Pure]
+ [Conditional("_LOGGING")]
+ internal static void PTSTraceExit(DS dps, bool passed)
+ {
+#if _LOGGING
+ if (!_tracingEnabled)
+ return;
+ BCLDebug.Trace("DATETIME", "[DATETIME] ProcessTerminalState {0} @ DS.{1}", passed ? "passed" : "failed", dps);
+#endif // _LOGGING
+ }
+ [Pure]
+ [Conditional("_LOGGING")]
+ internal static void TPTraceExit(string message, DS dps)
+ {
+#if _LOGGING
+ if (!_tracingEnabled)
+ return;
+ BCLDebug.Trace("DATETIME", "[DATETIME] TryParse return {0}, DS.{1}", message, dps);
+#endif // _LOGGING
+ }
+ [Pure]
+ [Conditional("_LOGGING")]
+ internal static void DTFITrace(DateTimeFormatInfo dtfi)
+ {
+#if _LOGGING
+ if (!_tracingEnabled)
+ return;
+
+ BCLDebug.Trace("DATETIME", "[DATETIME] DateTimeFormatInfo Properties");
+#if !FEATURE_COREFX_GLOBALIZATION
+ BCLDebug.Trace("DATETIME", " NativeCalendarName {0}", Hex(dtfi.NativeCalendarName));
+#endif
+ BCLDebug.Trace("DATETIME", " AMDesignator {0}", Hex(dtfi.AMDesignator));
+ BCLDebug.Trace("DATETIME", " PMDesignator {0}", Hex(dtfi.PMDesignator));
+ BCLDebug.Trace("DATETIME", " TimeSeparator {0}", Hex(dtfi.TimeSeparator));
+ BCLDebug.Trace("DATETIME", " AbbrvDayNames {0}", Hex(dtfi.AbbreviatedDayNames));
+ BCLDebug.Trace("DATETIME", " ShortestDayNames {0}", Hex(dtfi.ShortestDayNames));
+ BCLDebug.Trace("DATETIME", " DayNames {0}", Hex(dtfi.DayNames));
+ BCLDebug.Trace("DATETIME", " AbbrvMonthNames {0}", Hex(dtfi.AbbreviatedMonthNames));
+ BCLDebug.Trace("DATETIME", " MonthNames {0}", Hex(dtfi.MonthNames));
+ BCLDebug.Trace("DATETIME", " AbbrvMonthGenNames {0}", Hex(dtfi.AbbreviatedMonthGenitiveNames));
+ BCLDebug.Trace("DATETIME", " MonthGenNames {0}", Hex(dtfi.MonthGenitiveNames));
+#endif // _LOGGING
+ }
+#if _LOGGING
+ [Pure]
+ // return a string in the form: "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+ internal static string Hex(string[] strs)
+ {
+ if (strs == null || strs.Length == 0)
+ return String.Empty;
+ if (strs.Length == 1)
+ return Hex(strs[0]);
+
+ int curLineLength = 0;
+ int maxLineLength = 55;
+ int newLinePadding = 20;
+
+
+ //invariant: strs.Length >= 2
+ StringBuilder buffer = new StringBuilder();
+ buffer.Append(Hex(strs[0]));
+ curLineLength = buffer.Length;
+ String s;
+
+ for (int i = 1; i < strs.Length - 1; i++)
+ {
+ s = Hex(strs[i]);
+
+ if (s.Length > maxLineLength || (curLineLength + s.Length + 2) > maxLineLength)
+ {
+ buffer.Append(',');
+ buffer.Append(Environment.NewLine);
+ buffer.Append(' ', newLinePadding);
+ curLineLength = 0;
+ }
+ else
+ {
+ buffer.Append(", ");
+ curLineLength += 2;
+ }
+ buffer.Append(s);
+ curLineLength += s.Length;
+ }
+
+ buffer.Append(',');
+ s = Hex(strs[strs.Length - 1]);
+ if (s.Length > maxLineLength || (curLineLength + s.Length + 6) > maxLineLength)
+ {
+ buffer.Append(Environment.NewLine);
+ buffer.Append(' ', newLinePadding);
+ }
+ else
+ {
+ buffer.Append(' ');
+ }
+ buffer.Append(s);
+ return buffer.ToString();
+ }
+ [Pure]
+ // return a string in the form: "Sun"
+ internal static string Hex(string str)
+ {
+ StringBuilder buffer = new StringBuilder();
+ buffer.Append("\"");
+ for (int i = 0; i < str.Length; i++)
+ {
+ if (str[i] <= '\x007f')
+ buffer.Append(str[i]);
+ else
+ buffer.Append("\\u" + ((int)str[i]).ToString("x4", CultureInfo.InvariantCulture));
+ }
+ buffer.Append("\"");
+ return buffer.ToString();
+ }
+ [Pure]
+ // return an unicode escaped string form of char c
+ internal static String Hex(char c)
+ {
+ if (c <= '\x007f')
+ return c.ToString(CultureInfo.InvariantCulture);
+ else
+ return "\\u" + ((int)c).ToString("x4", CultureInfo.InvariantCulture);
+ }
+
+ internal static bool _tracingEnabled = BCLDebug.CheckEnabled("DATETIME");
+#endif // _LOGGING
+ }
+
+
+ //
+ // This is a string parsing helper which wraps a String object.
+ // It has a Index property which tracks
+ // the current parsing pointer of the string.
+ //
+ internal
+ struct __DTString
+ {
+ //
+ // Value propery: stores the real string to be parsed.
+ //
+ internal String Value;
+
+ //
+ // Index property: points to the character that we are currently parsing.
+ //
+ internal int Index;
+
+ // The length of Value string.
+ internal int len;
+
+ // The current chracter to be looked at.
+ internal char m_current;
+
+ private CompareInfo m_info;
+ // Flag to indicate if we encouter an digit, we should check for token or not.
+ // In some cultures, such as mn-MN, it uses "\x0031\x00a0\x0434\x04af\x0433\x044d\x044d\x0440\x00a0\x0441\x0430\x0440" in month names.
+ private bool m_checkDigitToken;
+
+ internal __DTString(String str, DateTimeFormatInfo dtfi, bool checkDigitToken) : this(str, dtfi)
+ {
+ m_checkDigitToken = checkDigitToken;
+ }
+
+ internal __DTString(String str, DateTimeFormatInfo dtfi)
+ {
+ Index = -1;
+ Value = str;
+ len = Value.Length;
+
+ m_current = '\0';
+ if (dtfi != null)
+ {
+ m_info = dtfi.CompareInfo;
+ m_checkDigitToken = ((dtfi.FormatFlags & DateTimeFormatFlags.UseDigitPrefixInTokens) != 0);
+ }
+ else
+ {
+ m_info = CultureInfo.CurrentCulture.CompareInfo;
+ m_checkDigitToken = false;
+ }
+ }
+
+ internal CompareInfo CompareInfo
+ {
+ get { return m_info; }
+ }
+
+ //
+ // Advance the Index.
+ // Return true if Index is NOT at the end of the string.
+ //
+ // Typical usage:
+ // while (str.GetNext())
+ // {
+ // char ch = str.GetChar()
+ // }
+ internal bool GetNext()
+ {
+ Index++;
+ if (Index < len)
+ {
+ m_current = Value[Index];
+ return (true);
+ }
+ return (false);
+ }
+
+ internal bool AtEnd()
+ {
+ return Index < len ? false : true;
+ }
+
+ internal bool Advance(int count)
+ {
+ Debug.Assert(Index + count <= len, "__DTString::Advance: Index + count <= len");
+ Index += count;
+ if (Index < len)
+ {
+ m_current = Value[Index];
+ return (true);
+ }
+ return (false);
+ }
+
+
+ // Used by DateTime.Parse() to get the next token.
+ internal void GetRegularToken(out TokenType tokenType, out int tokenValue, DateTimeFormatInfo dtfi)
+ {
+ tokenValue = 0;
+ if (Index >= len)
+ {
+ tokenType = TokenType.EndOfString;
+ return;
+ }
+
+ tokenType = TokenType.UnknownToken;
+
+ Start:
+ if (DateTimeParse.IsDigit(m_current))
+ {
+ // This is a digit.
+ tokenValue = m_current - '0';
+ int value;
+ int start = Index;
+
+ //
+ // Collect other digits.
+ //
+ while (++Index < len)
+ {
+ m_current = Value[Index];
+ value = m_current - '0';
+ if (value >= 0 && value <= 9)
+ {
+ tokenValue = tokenValue * 10 + value;
+ }
+ else
+ {
+ break;
+ }
+ }
+ if (Index - start > DateTimeParse.MaxDateTimeNumberDigits)
+ {
+ tokenType = TokenType.NumberToken;
+ tokenValue = -1;
+ }
+ else if (Index - start < 3)
+ {
+ tokenType = TokenType.NumberToken;
+ }
+ else
+ {
+ // If there are more than 3 digits, assume that it's a year value.
+ tokenType = TokenType.YearNumberToken;
+ }
+ if (m_checkDigitToken)
+ {
+ int save = Index;
+ char saveCh = m_current;
+ // Re-scan using the staring Index to see if this is a token.
+ Index = start; // To include the first digit.
+ m_current = Value[Index];
+ TokenType tempType;
+ int tempValue;
+ // This DTFI has tokens starting with digits.
+ // E.g. mn-MN has month name like "\x0031\x00a0\x0434\x04af\x0433\x044d\x044d\x0440\x00a0\x0441\x0430\x0440"
+ if (dtfi.Tokenize(TokenType.RegularTokenMask, out tempType, out tempValue, ref this))
+ {
+ tokenType = tempType;
+ tokenValue = tempValue;
+ // This is a token, so the Index has been advanced propertly in DTFI.Tokenizer().
+ }
+ else
+ {
+ // Use the number token value.
+ // Restore the index.
+ Index = save;
+ m_current = saveCh;
+ }
+ }
+ }
+ else if (Char.IsWhiteSpace(m_current))
+ {
+ // Just skip to the next character.
+ while (++Index < len)
+ {
+ m_current = Value[Index];
+ if (!(Char.IsWhiteSpace(m_current)))
+ {
+ goto Start;
+ }
+ }
+ // We have reached the end of string.
+ tokenType = TokenType.EndOfString;
+ }
+ else
+ {
+ dtfi.Tokenize(TokenType.RegularTokenMask, out tokenType, out tokenValue, ref this);
+ }
+ }
+
+ internal TokenType GetSeparatorToken(DateTimeFormatInfo dtfi, out int indexBeforeSeparator, out char charBeforeSeparator)
+ {
+ indexBeforeSeparator = Index;
+ charBeforeSeparator = m_current;
+ TokenType tokenType;
+ if (!SkipWhiteSpaceCurrent())
+ {
+ // Reach the end of the string.
+ return (TokenType.SEP_End);
+ }
+ if (!DateTimeParse.IsDigit(m_current))
+ {
+ // Not a digit. Tokenize it.
+ int tokenValue;
+ bool found = dtfi.Tokenize(TokenType.SeparatorTokenMask, out tokenType, out tokenValue, ref this);
+ if (!found)
+ {
+ tokenType = TokenType.SEP_Space;
+ }
+ }
+ else
+ {
+ // Do nothing here. If we see a number, it will not be a separator. There is no need wasting time trying to find the
+ // separator token.
+ tokenType = TokenType.SEP_Space;
+ }
+ return (tokenType);
+ }
+
+ internal bool MatchSpecifiedWord(String target)
+ {
+ return MatchSpecifiedWord(target, target.Length + Index);
+ }
+
+ internal bool MatchSpecifiedWord(String target, int endIndex)
+ {
+ int count = endIndex - Index;
+
+ if (count != target.Length)
+ {
+ return false;
+ }
+
+ if (Index + count > len)
+ {
+ return false;
+ }
+
+ return (m_info.Compare(Value, Index, count, target, 0, count, CompareOptions.IgnoreCase) == 0);
+ }
+
+ private static Char[] WhiteSpaceChecks = new Char[] { ' ', '\u00A0' };
+
+ internal bool MatchSpecifiedWords(String target, bool checkWordBoundary, ref int matchLength)
+ {
+ int valueRemaining = Value.Length - Index;
+ matchLength = target.Length;
+
+ if (matchLength > valueRemaining || m_info.Compare(Value, Index, matchLength, target, 0, matchLength, CompareOptions.IgnoreCase) != 0)
+ {
+ // Check word by word
+ int targetPosition = 0; // Where we are in the target string
+ int thisPosition = Index; // Where we are in this string
+ int wsIndex = target.IndexOfAny(WhiteSpaceChecks, targetPosition);
+ if (wsIndex == -1)
+ {
+ return false;
+ }
+ do
+ {
+ int segmentLength = wsIndex - targetPosition;
+ if (thisPosition >= Value.Length - segmentLength)
+ { // Subtraction to prevent overflow.
+ return false;
+ }
+ if (segmentLength == 0)
+ {
+ // If segmentLength == 0, it means that we have leading space in the target string.
+ // In that case, skip the leading spaces in the target and this string.
+ matchLength--;
+ }
+ else
+ {
+ // Make sure we also have whitespace in the input string
+ if (!Char.IsWhiteSpace(Value[thisPosition + segmentLength]))
+ {
+ return false;
+ }
+ if (m_info.Compare(Value, thisPosition, segmentLength, target, targetPosition, segmentLength, CompareOptions.IgnoreCase) != 0)
+ {
+ return false;
+ }
+ // Advance the input string
+ thisPosition = thisPosition + segmentLength + 1;
+ }
+ // Advance our target string
+ targetPosition = wsIndex + 1;
+
+
+ // Skip past multiple whitespace
+ while (thisPosition < Value.Length && Char.IsWhiteSpace(Value[thisPosition]))
+ {
+ thisPosition++;
+ matchLength++;
+ }
+ } while ((wsIndex = target.IndexOfAny(WhiteSpaceChecks, targetPosition)) >= 0);
+ // now check the last segment;
+ if (targetPosition < target.Length)
+ {
+ int segmentLength = target.Length - targetPosition;
+ if (thisPosition > Value.Length - segmentLength)
+ {
+ return false;
+ }
+ if (m_info.Compare(Value, thisPosition, segmentLength, target, targetPosition, segmentLength, CompareOptions.IgnoreCase) != 0)
+ {
+ return false;
+ }
+ }
+ }
+
+ if (checkWordBoundary)
+ {
+ int nextCharIndex = Index + matchLength;
+ if (nextCharIndex < Value.Length)
+ {
+ if (Char.IsLetter(Value[nextCharIndex]))
+ {
+ return (false);
+ }
+ }
+ }
+ return (true);
+ }
+
+ //
+ // Check to see if the string starting from Index is a prefix of
+ // str.
+ // If a match is found, true value is returned and Index is updated to the next character to be parsed.
+ // Otherwise, Index is unchanged.
+ //
+ internal bool Match(String str)
+ {
+ if (++Index >= len)
+ {
+ return (false);
+ }
+
+ if (str.Length > (Value.Length - Index))
+ {
+ return false;
+ }
+
+ if (m_info.Compare(Value, Index, str.Length, str, 0, str.Length, CompareOptions.Ordinal) == 0)
+ {
+ // Update the Index to the end of the matching string.
+ // So the following GetNext()/Match() opeartion will get
+ // the next character to be parsed.
+ Index += (str.Length - 1);
+ return (true);
+ }
+ return (false);
+ }
+
+ internal bool Match(char ch)
+ {
+ if (++Index >= len)
+ {
+ return (false);
+ }
+ if (Value[Index] == ch)
+ {
+ m_current = ch;
+ return (true);
+ }
+ Index--;
+ return (false);
+ }
+
+ //
+ // Actions: From the current position, try matching the longest word in the specified string array.
+ // E.g. words[] = {"AB", "ABC", "ABCD"}, if the current position points to a substring like "ABC DEF",
+ // MatchLongestWords(words, ref MaxMatchStrLen) will return 1 (the index), and maxMatchLen will be 3.
+ // Returns:
+ // The index that contains the longest word to match
+ // Arguments:
+ // words The string array that contains words to search.
+ // maxMatchStrLen [in/out] the initailized maximum length. This parameter can be used to
+ // find the longest match in two string arrays.
+ //
+ internal int MatchLongestWords(String[] words, ref int maxMatchStrLen)
+ {
+ int result = -1;
+ for (int i = 0; i < words.Length; i++)
+ {
+ String word = words[i];
+ int matchLength = word.Length;
+ if (MatchSpecifiedWords(word, false, ref matchLength))
+ {
+ if (matchLength > maxMatchStrLen)
+ {
+ maxMatchStrLen = matchLength;
+ result = i;
+ }
+ }
+ }
+
+ return (result);
+ }
+
+ //
+ // Get the number of repeat character after the current character.
+ // For a string "hh:mm:ss" at Index of 3. GetRepeatCount() = 2, and Index
+ // will point to the second ':'.
+ //
+ internal int GetRepeatCount()
+ {
+ char repeatChar = Value[Index];
+ int pos = Index + 1;
+ while ((pos < len) && (Value[pos] == repeatChar))
+ {
+ pos++;
+ }
+ int repeatCount = (pos - Index);
+ // Update the Index to the end of the repeated characters.
+ // So the following GetNext() opeartion will get
+ // the next character to be parsed.
+ Index = pos - 1;
+ return (repeatCount);
+ }
+
+ // Return false when end of string is encountered or a non-digit character is found.
+ internal bool GetNextDigit()
+ {
+ if (++Index >= len)
+ {
+ return (false);
+ }
+ return (DateTimeParse.IsDigit(Value[Index]));
+ }
+
+ //
+ // Get the current character.
+ //
+ internal char GetChar()
+ {
+ Debug.Assert(Index >= 0 && Index < len, "Index >= 0 && Index < len");
+ return (Value[Index]);
+ }
+
+ //
+ // Convert the current character to a digit, and return it.
+ //
+ internal int GetDigit()
+ {
+ Debug.Assert(Index >= 0 && Index < len, "Index >= 0 && Index < len");
+ Debug.Assert(DateTimeParse.IsDigit(Value[Index]), "IsDigit(Value[Index])");
+ return (Value[Index] - '0');
+ }
+
+ //
+ // Eat White Space ahead of the current position
+ //
+ // Return false if end of string is encountered.
+ //
+ internal void SkipWhiteSpaces()
+ {
+ // Look ahead to see if the next character
+ // is a whitespace.
+ while (Index + 1 < len)
+ {
+ char ch = Value[Index + 1];
+ if (!Char.IsWhiteSpace(ch))
+ {
+ return;
+ }
+ Index++;
+ }
+ return;
+ }
+
+ //
+ // Skip white spaces from the current position
+ //
+ // Return false if end of string is encountered.
+ //
+ internal bool SkipWhiteSpaceCurrent()
+ {
+ if (Index >= len)
+ {
+ return (false);
+ }
+
+ if (!Char.IsWhiteSpace(m_current))
+ {
+ return (true);
+ }
+
+ while (++Index < len)
+ {
+ m_current = Value[Index];
+ if (!Char.IsWhiteSpace(m_current))
+ {
+ return (true);
+ }
+ // Nothing here.
+ }
+ return (false);
+ }
+
+ internal void TrimTail()
+ {
+ int i = len - 1;
+ while (i >= 0 && Char.IsWhiteSpace(Value[i]))
+ {
+ i--;
+ }
+ Value = Value.Substring(0, i + 1);
+ len = Value.Length;
+ }
+
+ // Trim the trailing spaces within a quoted string.
+ // Call this after TrimTail() is done.
+ internal void RemoveTrailingInQuoteSpaces()
+ {
+ int i = len - 1;
+ if (i <= 1)
+ {
+ return;
+ }
+ char ch = Value[i];
+ // Check if the last character is a quote.
+ if (ch == '\'' || ch == '\"')
+ {
+ if (Char.IsWhiteSpace(Value[i - 1]))
+ {
+ i--;
+ while (i >= 1 && Char.IsWhiteSpace(Value[i - 1]))
+ {
+ i--;
+ }
+ Value = Value.Remove(i, Value.Length - 1 - i);
+ len = Value.Length;
+ }
+ }
+ }
+
+ // Trim the leading spaces within a quoted string.
+ // Call this after the leading spaces before quoted string are trimmed.
+ internal void RemoveLeadingInQuoteSpaces()
+ {
+ if (len <= 2)
+ {
+ return;
+ }
+ int i = 0;
+ char ch = Value[i];
+ // Check if the last character is a quote.
+ if (ch == '\'' || ch == '\"')
+ {
+ while ((i + 1) < len && Char.IsWhiteSpace(Value[i + 1]))
+ {
+ i++;
+ }
+ if (i != 0)
+ {
+ Value = Value.Remove(1, i);
+ len = Value.Length;
+ }
+ }
+ }
+
+ internal DTSubString GetSubString()
+ {
+ DTSubString sub = new DTSubString();
+ sub.index = Index;
+ sub.s = Value;
+ while (Index + sub.length < len)
+ {
+ DTSubStringType currentType;
+ Char ch = Value[Index + sub.length];
+ if (ch >= '0' && ch <= '9')
+ {
+ currentType = DTSubStringType.Number;
+ }
+ else
+ {
+ currentType = DTSubStringType.Other;
+ }
+
+ if (sub.length == 0)
+ {
+ sub.type = currentType;
+ }
+ else
+ {
+ if (sub.type != currentType)
+ {
+ break;
+ }
+ }
+ sub.length++;
+ if (currentType == DTSubStringType.Number)
+ {
+ // Incorporate the number into the value
+ // Limit the digits to prevent overflow
+ if (sub.length > DateTimeParse.MaxDateTimeNumberDigits)
+ {
+ sub.type = DTSubStringType.Invalid;
+ return sub;
+ }
+ int number = ch - '0';
+ Debug.Assert(number >= 0 && number <= 9, "number >= 0 && number <= 9");
+ sub.value = sub.value * 10 + number;
+ }
+ else
+ {
+ // For non numbers, just return this length 1 token. This should be expanded
+ // to more types of thing if this parsing approach is used for things other
+ // than numbers and single characters
+ break;
+ }
+ }
+ if (sub.length == 0)
+ {
+ sub.type = DTSubStringType.End;
+ return sub;
+ }
+
+ return sub;
+ }
+
+ internal void ConsumeSubString(DTSubString sub)
+ {
+ Debug.Assert(sub.index == Index, "sub.index == Index");
+ Debug.Assert(sub.index + sub.length <= len, "sub.index + sub.length <= len");
+ Index = sub.index + sub.length;
+ if (Index < len)
+ {
+ m_current = Value[Index];
+ }
+ }
+ }
+
+ internal enum DTSubStringType
+ {
+ Unknown = 0,
+ Invalid = 1,
+ Number = 2,
+ End = 3,
+ Other = 4,
+ }
+
+ internal struct DTSubString
+ {
+ internal String s;
+ internal Int32 index;
+ internal Int32 length;
+ internal DTSubStringType type;
+ internal Int32 value;
+
+ internal Char this[Int32 relativeIndex]
+ {
+ get
+ {
+ return s[index + relativeIndex];
+ }
+ }
+ }
+
+ //
+ // The buffer to store the parsing token.
+ //
+ internal
+ struct DateTimeToken
+ {
+ internal DateTimeParse.DTT dtt; // Store the token
+ internal TokenType suffix; // Store the CJK Year/Month/Day suffix (if any)
+ internal int num; // Store the number that we are parsing (if any)
+ }
+
+ //
+ // The buffer to store temporary parsing information.
+ //
+ internal
+ unsafe struct DateTimeRawInfo
+ {
+ private int* num;
+ internal int numCount;
+ internal int month;
+ internal int year;
+ internal int dayOfWeek;
+ internal int era;
+ internal DateTimeParse.TM timeMark;
+ internal double fraction;
+ internal bool hasSameDateAndTimeSeparators;
+
+ internal void Init(int* numberBuffer)
+ {
+ month = -1;
+ year = -1;
+ dayOfWeek = -1;
+ era = -1;
+ timeMark = DateTimeParse.TM.NotSet;
+ fraction = -1;
+ num = numberBuffer;
+ }
+ internal unsafe void AddNumber(int value)
+ {
+ num[numCount++] = value;
+ }
+ internal unsafe int GetNumber(int index)
+ {
+ return num[index];
+ }
+ }
+
+ internal enum ParseFailureKind
+ {
+ None = 0,
+ ArgumentNull = 1,
+ Format = 2,
+ FormatWithParameter = 3,
+ FormatBadDateTimeCalendar = 4, // FormatException when ArgumentOutOfRange is thrown by a Calendar.TryToDateTime().
+ };
+
+ [Flags]
+ internal enum ParseFlags
+ {
+ HaveYear = 0x00000001,
+ HaveMonth = 0x00000002,
+ HaveDay = 0x00000004,
+ HaveHour = 0x00000008,
+ HaveMinute = 0x00000010,
+ HaveSecond = 0x00000020,
+ HaveTime = 0x00000040,
+ HaveDate = 0x00000080,
+ TimeZoneUsed = 0x00000100,
+ TimeZoneUtc = 0x00000200,
+ ParsedMonthName = 0x00000400,
+ CaptureOffset = 0x00000800,
+ YearDefault = 0x00001000,
+ Rfc1123Pattern = 0x00002000,
+ UtcSortPattern = 0x00004000,
+ }
+
+ //
+ // This will store the result of the parsing. And it will be eventually
+ // used to construct a DateTime instance.
+ //
+ internal
+ struct DateTimeResult
+ {
+ internal int Year;
+ internal int Month;
+ internal int Day;
+ //
+ // Set time defualt to 00:00:00.
+ //
+ internal int Hour;
+ internal int Minute;
+ internal int Second;
+ internal double fraction;
+
+ internal int era;
+
+ internal ParseFlags flags;
+
+ internal TimeSpan timeZoneOffset;
+
+ internal Calendar calendar;
+
+ internal DateTime parsedDate;
+
+ internal ParseFailureKind failure;
+ internal string failureMessageID;
+ internal object failureMessageFormatArgument;
+ internal string failureArgumentName;
+
+ internal void Init()
+ {
+ Year = -1;
+ Month = -1;
+ Day = -1;
+ fraction = -1;
+ era = -1;
+ }
+
+ internal void SetDate(int year, int month, int day)
+ {
+ Year = year;
+ Month = month;
+ Day = day;
+ }
+ internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument)
+ {
+ this.failure = failure;
+ this.failureMessageID = failureMessageID;
+ this.failureMessageFormatArgument = failureMessageFormatArgument;
+ }
+
+ internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument, string failureArgumentName)
+ {
+ this.failure = failure;
+ this.failureMessageID = failureMessageID;
+ this.failureMessageFormatArgument = failureMessageFormatArgument;
+ this.failureArgumentName = failureArgumentName;
+ }
+ }
+
+ // This is the helper data structure used in ParseExact().
+ internal struct ParsingInfo
+ {
+ internal Calendar calendar;
+ internal int dayOfWeek;
+ internal DateTimeParse.TM timeMark;
+
+ internal bool fUseHour12;
+ internal bool fUseTwoDigitYear;
+ internal bool fAllowInnerWhite;
+ internal bool fAllowTrailingWhite;
+ internal bool fCustomNumberParser;
+ internal DateTimeParse.MatchNumberDelegate parseNumberDelegate;
+
+ internal void Init()
+ {
+ dayOfWeek = -1;
+ timeMark = DateTimeParse.TM.NotSet;
+ }
+ }
+
+ //
+ // The type of token that will be returned by DateTimeFormatInfo.Tokenize().
+ //
+ internal enum TokenType
+ {
+ // The valid token should start from 1.
+
+ // Regular tokens. The range is from 0x00 ~ 0xff.
+ NumberToken = 1, // The number. E.g. "12"
+ YearNumberToken = 2, // The number which is considered as year number, which has 3 or more digits. E.g. "2003"
+ Am = 3, // AM timemark. E.g. "AM"
+ Pm = 4, // PM timemark. E.g. "PM"
+ MonthToken = 5, // A word (or words) that represents a month name. E.g. "March"
+ EndOfString = 6, // End of string
+ DayOfWeekToken = 7, // A word (or words) that represents a day of week name. E.g. "Monday" or "Mon"
+ TimeZoneToken = 8, // A word that represents a timezone name. E.g. "GMT"
+ EraToken = 9, // A word that represents a era name. E.g. "A.D."
+ DateWordToken = 10, // A word that can appear in a DateTime string, but serves no parsing semantics. E.g. "de" in Spanish culture.
+ UnknownToken = 11, // An unknown word, which signals an error in parsing.
+ HebrewNumber = 12, // A number that is composed of Hebrew text. Hebrew calendar uses Hebrew digits for year values, month values, and day values.
+ JapaneseEraToken = 13, // Era name for JapaneseCalendar
+ TEraToken = 14, // Era name for TaiwanCalendar
+ IgnorableSymbol = 15, // A separator like "," that is equivalent to whitespace
+
+
+ // Separator tokens.
+ SEP_Unk = 0x100, // Unknown separator.
+ SEP_End = 0x200, // The end of the parsing string.
+ SEP_Space = 0x300, // Whitespace (including comma).
+ SEP_Am = 0x400, // AM timemark. E.g. "AM"
+ SEP_Pm = 0x500, // PM timemark. E.g. "PM"
+ SEP_Date = 0x600, // date separator. E.g. "/"
+ SEP_Time = 0x700, // time separator. E.g. ":"
+ SEP_YearSuff = 0x800, // Chinese/Japanese/Korean year suffix.
+ SEP_MonthSuff = 0x900, // Chinese/Japanese/Korean month suffix.
+ SEP_DaySuff = 0xa00, // Chinese/Japanese/Korean day suffix.
+ SEP_HourSuff = 0xb00, // Chinese/Japanese/Korean hour suffix.
+ SEP_MinuteSuff = 0xc00, // Chinese/Japanese/Korean minute suffix.
+ SEP_SecondSuff = 0xd00, // Chinese/Japanese/Korean second suffix.
+ SEP_LocalTimeMark = 0xe00, // 'T', used in ISO 8601 format.
+ SEP_DateOrOffset = 0xf00, // '-' which could be a date separator or start of a time zone offset
+
+ RegularTokenMask = 0x00ff,
+ SeparatorTokenMask = 0xff00,
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/DateTimeStyles.cs b/src/mscorlib/shared/System/Globalization/DateTimeStyles.cs
new file mode 100644
index 0000000000..79232ff199
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/DateTimeStyles.cs
@@ -0,0 +1,49 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose: Contains valid formats for DateTime recognized by
+** the DateTime class' parsing code.
+**
+**
+===========================================================*/
+
+namespace System.Globalization
+{
+ [Flags]
+ public enum DateTimeStyles
+ {
+ // Bit flag indicating that leading whitespace is allowed. Character values
+ // 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, and 0x0020 are considered to be
+ // whitespace.
+
+
+ None = 0x00000000,
+
+ AllowLeadingWhite = 0x00000001,
+
+ AllowTrailingWhite = 0x00000002, //Bitflag indicating trailing whitespace is allowed.
+
+ AllowInnerWhite = 0x00000004,
+
+ AllowWhiteSpaces = AllowLeadingWhite | AllowInnerWhite | AllowTrailingWhite,
+ // When parsing a date/time string, if all year/month/day are missing, set the default date
+ // to 0001/1/1, instead of the current year/month/day.
+
+ NoCurrentDateDefault = 0x00000008,
+ // When parsing a date/time string, if a timezone specifier ("GMT","Z","+xxxx", "-xxxx" exists), we will
+ // ajdust the parsed time based to GMT.
+
+ AdjustToUniversal = 0x00000010,
+
+ AssumeLocal = 0x00000020,
+
+ AssumeUniversal = 0x00000040,
+ // Attempt to preserve whether the input is unspecified, local or UTC
+ RoundtripKind = 0x00000080,
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/DaylightTime.cs b/src/mscorlib/shared/System/Globalization/DaylightTime.cs
new file mode 100644
index 0000000000..b3c70e1d10
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/DaylightTime.cs
@@ -0,0 +1,50 @@
+// 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.
+
+namespace System.Globalization
+{
+ // This class represents a starting/ending time for a period of daylight saving time.
+ [Serializable]
+ public class DaylightTime
+ {
+ private readonly DateTime _start;
+ private readonly DateTime _end;
+ private readonly TimeSpan _delta;
+
+ private DaylightTime()
+ {
+ }
+
+ public DaylightTime(DateTime start, DateTime end, TimeSpan delta)
+ {
+ _start = start;
+ _end = end;
+ _delta = delta;
+ }
+
+ // The start date of a daylight saving period.
+ public DateTime Start => _start;
+
+ // The end date of a daylight saving period.
+ public DateTime End => _end;
+
+ // Delta to stardard offset in ticks.
+ public TimeSpan Delta => _delta;
+ }
+
+ // Value type version of DaylightTime
+ internal struct DaylightTimeStruct
+ {
+ public DaylightTimeStruct(DateTime start, DateTime end, TimeSpan delta)
+ {
+ Start = start;
+ End = end;
+ Delta = delta;
+ }
+
+ public readonly DateTime Start;
+ public readonly DateTime End;
+ public readonly TimeSpan Delta;
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/DigitShapes.cs b/src/mscorlib/shared/System/Globalization/DigitShapes.cs
new file mode 100644
index 0000000000..1ce45dbeb6
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/DigitShapes.cs
@@ -0,0 +1,13 @@
+// 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.
+
+namespace System.Globalization
+{
+ public enum DigitShapes : int
+ {
+ Context = 0x0000, // The shape depends on the previous text in the same output.
+ None = 0x0001, // Gives full Unicode compatibility.
+ NativeNational = 0x0002 // National shapes
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/EastAsianLunisolarCalendar.cs b/src/mscorlib/shared/System/Globalization/EastAsianLunisolarCalendar.cs
new file mode 100644
index 0000000000..d06b13cd7d
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/EastAsianLunisolarCalendar.cs
@@ -0,0 +1,710 @@
+// 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.Diagnostics.Contracts;
+
+namespace System.Globalization
+{
+ [Serializable]
+ public abstract class EastAsianLunisolarCalendar : Calendar
+ {
+ internal const int LeapMonth = 0;
+ internal const int Jan1Month = 1;
+ internal const int Jan1Date = 2;
+ internal const int nDaysPerMonth = 3;
+
+ // # of days so far in the solar year
+ internal static readonly int[] DaysToMonth365 =
+ {
+ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+ };
+
+ internal static readonly int[] DaysToMonth366 =
+ {
+ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335
+ };
+
+ internal const int DatePartYear = 0;
+ internal const int DatePartDayOfYear = 1;
+ internal const int DatePartMonth = 2;
+ internal const int DatePartDay = 3;
+
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.LunisolarCalendar;
+ }
+ }
+
+ // Return the year number in the 60-year cycle.
+ //
+
+ public virtual int GetSexagenaryYear(DateTime time)
+ {
+ CheckTicksRange(time.Ticks);
+
+ int year = 0, month = 0, day = 0;
+ TimeToLunar(time, ref year, ref month, ref day);
+
+ return ((year - 4) % 60) + 1;
+ }
+
+ // Return the celestial year from the 60-year cycle.
+ // The returned value is from 1 ~ 10.
+ //
+
+ public int GetCelestialStem(int sexagenaryYear)
+ {
+ if ((sexagenaryYear < 1) || (sexagenaryYear > 60))
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(sexagenaryYear),
+ SR.Format(SR.ArgumentOutOfRange_Range, 1, 60));
+ }
+ Contract.EndContractBlock();
+
+ return ((sexagenaryYear - 1) % 10) + 1;
+ }
+
+ // Return the Terrestial Branch from the the 60-year cycle.
+ // The returned value is from 1 ~ 12.
+ //
+
+ public int GetTerrestrialBranch(int sexagenaryYear)
+ {
+ if ((sexagenaryYear < 1) || (sexagenaryYear > 60))
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(sexagenaryYear),
+ SR.Format(SR.ArgumentOutOfRange_Range, 1, 60));
+ }
+ Contract.EndContractBlock();
+
+ return ((sexagenaryYear - 1) % 12) + 1;
+ }
+
+ internal abstract int GetYearInfo(int LunarYear, int Index);
+ internal abstract int GetYear(int year, DateTime time);
+ internal abstract int GetGregorianYear(int year, int era);
+
+ internal abstract int MinCalendarYear { get; }
+ internal abstract int MaxCalendarYear { get; }
+ internal abstract EraInfo[] CalEraInfo { get; }
+ internal abstract DateTime MinDate { get; }
+ internal abstract DateTime MaxDate { get; }
+
+ internal const int MaxCalendarMonth = 13;
+ internal const int MaxCalendarDay = 30;
+
+ internal int MinEraCalendarYear(int era)
+ {
+ EraInfo[] mEraInfo = CalEraInfo;
+ //ChineseLunisolarCalendar does not has m_EraInfo it is going to retuen null
+ if (mEraInfo == null)
+ {
+ return MinCalendarYear;
+ }
+
+ if (era == Calendar.CurrentEra)
+ {
+ era = CurrentEraValue;
+ }
+ //era has to be in the supported range otherwise we will throw exception in CheckEraRange()
+ if (era == GetEra(MinDate))
+ {
+ return (GetYear(MinCalendarYear, MinDate));
+ }
+
+ for (int i = 0; i < mEraInfo.Length; i++)
+ {
+ if (era == mEraInfo[i].era)
+ {
+ return (mEraInfo[i].minEraYear);
+ }
+ }
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
+ }
+
+ internal int MaxEraCalendarYear(int era)
+ {
+ EraInfo[] mEraInfo = CalEraInfo;
+ //ChineseLunisolarCalendar does not has m_EraInfo it is going to retuen null
+ if (mEraInfo == null)
+ {
+ return MaxCalendarYear;
+ }
+
+ if (era == Calendar.CurrentEra)
+ {
+ era = CurrentEraValue;
+ }
+ //era has to be in the supported range otherwise we will throw exception in CheckEraRange()
+ if (era == GetEra(MaxDate))
+ {
+ return (GetYear(MaxCalendarYear, MaxDate));
+ }
+
+ for (int i = 0; i < mEraInfo.Length; i++)
+ {
+ if (era == mEraInfo[i].era)
+ {
+ return (mEraInfo[i].maxEraYear);
+ }
+ }
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
+ }
+
+ internal EastAsianLunisolarCalendar()
+ {
+ }
+
+ internal void CheckTicksRange(long ticks)
+ {
+ if (ticks < MinSupportedDateTime.Ticks || ticks > MaxSupportedDateTime.Ticks)
+ {
+ throw new ArgumentOutOfRangeException(
+ "time",
+ String.Format(CultureInfo.InvariantCulture, SR.ArgumentOutOfRange_CalendarRange,
+ MinSupportedDateTime, MaxSupportedDateTime));
+ }
+ Contract.EndContractBlock();
+ }
+
+ internal void CheckEraRange(int era)
+ {
+ if (era == Calendar.CurrentEra)
+ {
+ era = CurrentEraValue;
+ }
+
+ if ((era < GetEra(MinDate)) || (era > GetEra(MaxDate)))
+ {
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
+ }
+ }
+
+ internal int CheckYearRange(int year, int era)
+ {
+ CheckEraRange(era);
+ year = GetGregorianYear(year, era);
+
+ if ((year < MinCalendarYear) || (year > MaxCalendarYear))
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(year),
+ SR.Format(SR.ArgumentOutOfRange_Range, MinEraCalendarYear(era), MaxEraCalendarYear(era)));
+ }
+ return year;
+ }
+
+ internal int CheckYearMonthRange(int year, int month, int era)
+ {
+ year = CheckYearRange(year, era);
+
+ if (month == 13)
+ {
+ //Reject if there is no leap month this year
+ if (GetYearInfo(year, LeapMonth) == 0)
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
+ }
+
+ if (month < 1 || month > 13)
+ {
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
+ }
+ return year;
+ }
+
+ internal int InternalGetDaysInMonth(int year, int month)
+ {
+ int nDays;
+ int mask; // mask for extracting bits
+
+ mask = 0x8000;
+ // convert the lunar day into a lunar month/date
+ mask >>= (month - 1);
+ if ((GetYearInfo(year, nDaysPerMonth) & mask) == 0)
+ nDays = 29;
+ else
+ nDays = 30;
+ return nDays;
+ }
+
+ // Returns the number of days in the month given by the year and
+ // month arguments.
+ //
+
+ public override int GetDaysInMonth(int year, int month, int era)
+ {
+ year = CheckYearMonthRange(year, month, era);
+ return InternalGetDaysInMonth(year, month);
+ }
+
+ private static int GregorianIsLeapYear(int y)
+ {
+ return ((((y) % 4) != 0) ? 0 : ((((y) % 100) != 0) ? 1 : ((((y) % 400) != 0) ? 0 : 1)));
+ }
+
+ // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
+ //
+
+ public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
+ {
+ year = CheckYearMonthRange(year, month, era);
+ int daysInMonth = InternalGetDaysInMonth(year, month);
+ if (day < 1 || day > daysInMonth)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(day),
+ SR.Format(SR.ArgumentOutOfRange_Day, daysInMonth, month));
+ }
+
+ int gy = 0; int gm = 0; int gd = 0;
+
+ if (LunarToGregorian(year, month, day, ref gy, ref gm, ref gd))
+ {
+ return new DateTime(gy, gm, gd, hour, minute, second, millisecond);
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
+ }
+ }
+
+
+ //
+ // GregorianToLunar calculates lunar calendar info for the given gregorian year, month, date.
+ // The input date should be validated before calling this method.
+ //
+ internal void GregorianToLunar(int nSYear, int nSMonth, int nSDate, ref int nLYear, ref int nLMonth, ref int nLDate)
+ {
+ // unsigned int nLYear, nLMonth, nLDate; // lunar ymd
+ int nSolarDay; // day # in solar year
+ int nLunarDay; // day # in lunar year
+ int fLeap; // is it a solar leap year?
+ int LDpM; // lunar days/month bitfield
+ int mask; // mask for extracting bits
+ int nDays; // # days this lunar month
+ int nJan1Month, nJan1Date;
+
+ // calc the solar day of year
+ fLeap = GregorianIsLeapYear(nSYear);
+ nSolarDay = (fLeap == 1) ? DaysToMonth366[nSMonth - 1] : DaysToMonth365[nSMonth - 1];
+ nSolarDay += nSDate;
+
+ // init lunar year info
+ nLunarDay = nSolarDay;
+ nLYear = nSYear;
+ if (nLYear == (MaxCalendarYear + 1))
+ {
+ nLYear--;
+ nLunarDay += ((GregorianIsLeapYear(nLYear) == 1) ? 366 : 365);
+ nJan1Month = GetYearInfo(nLYear, Jan1Month);
+ nJan1Date = GetYearInfo(nLYear, Jan1Date);
+ }
+ else
+ {
+ nJan1Month = GetYearInfo(nLYear, Jan1Month);
+ nJan1Date = GetYearInfo(nLYear, Jan1Date);
+
+ // check if this solar date is actually part of the previous
+ // lunar year
+ if ((nSMonth < nJan1Month) ||
+ (nSMonth == nJan1Month && nSDate < nJan1Date))
+ {
+ // the corresponding lunar day is actually part of the previous
+ // lunar year
+ nLYear--;
+
+ // add a solar year to the lunar day #
+ nLunarDay += ((GregorianIsLeapYear(nLYear) == 1) ? 366 : 365);
+
+ // update the new start of year
+ nJan1Month = GetYearInfo(nLYear, Jan1Month);
+ nJan1Date = GetYearInfo(nLYear, Jan1Date);
+ }
+ }
+
+ // convert solar day into lunar day.
+ // subtract off the beginning part of the solar year which is not
+ // part of the lunar year. since this part is always in Jan or Feb,
+ // we don't need to handle Leap Year (LY only affects March
+ // and later).
+ nLunarDay -= DaysToMonth365[nJan1Month - 1];
+ nLunarDay -= (nJan1Date - 1);
+
+ // convert the lunar day into a lunar month/date
+ mask = 0x8000;
+ LDpM = GetYearInfo(nLYear, nDaysPerMonth);
+ nDays = ((LDpM & mask) != 0) ? 30 : 29;
+ nLMonth = 1;
+ while (nLunarDay > nDays)
+ {
+ nLunarDay -= nDays;
+ nLMonth++;
+ mask >>= 1;
+ nDays = ((LDpM & mask) != 0) ? 30 : 29;
+ }
+ nLDate = nLunarDay;
+ }
+
+ /*
+ //Convert from Lunar to Gregorian
+ //Highly inefficient, but it works based on the forward conversion
+ */
+ internal bool LunarToGregorian(int nLYear, int nLMonth, int nLDate, ref int nSolarYear, ref int nSolarMonth, ref int nSolarDay)
+ {
+ int numLunarDays;
+
+ if (nLDate < 1 || nLDate > 30)
+ return false;
+
+ numLunarDays = nLDate - 1;
+
+ //Add previous months days to form the total num of days from the first of the month.
+ for (int i = 1; i < nLMonth; i++)
+ {
+ numLunarDays += InternalGetDaysInMonth(nLYear, i);
+ }
+
+ //Get Gregorian First of year
+ int nJan1Month = GetYearInfo(nLYear, Jan1Month);
+ int nJan1Date = GetYearInfo(nLYear, Jan1Date);
+
+ // calc the solar day of year of 1 Lunar day
+ int fLeap = GregorianIsLeapYear(nLYear);
+ int[] days = (fLeap == 1) ? DaysToMonth366 : DaysToMonth365;
+
+ nSolarDay = nJan1Date;
+
+ if (nJan1Month > 1)
+ nSolarDay += days[nJan1Month - 1];
+
+ // Add the actual lunar day to get the solar day we want
+ nSolarDay = nSolarDay + numLunarDays;// - 1;
+
+ if (nSolarDay > (fLeap + 365))
+ {
+ nSolarYear = nLYear + 1;
+ nSolarDay -= (fLeap + 365);
+ }
+ else
+ {
+ nSolarYear = nLYear;
+ }
+
+ for (nSolarMonth = 1; nSolarMonth < 12; nSolarMonth++)
+ {
+ if (days[nSolarMonth] >= nSolarDay)
+ break;
+ }
+
+ nSolarDay -= days[nSolarMonth - 1];
+ return true;
+ }
+
+ internal DateTime LunarToTime(DateTime time, int year, int month, int day)
+ {
+ int gy = 0; int gm = 0; int gd = 0;
+ LunarToGregorian(year, month, day, ref gy, ref gm, ref gd);
+ return (GregorianCalendar.GetDefaultInstance().ToDateTime(gy, gm, gd, time.Hour, time.Minute, time.Second, time.Millisecond));
+ }
+
+ internal void TimeToLunar(DateTime time, ref int year, ref int month, ref int day)
+ {
+ int gy = 0; int gm = 0; int gd = 0;
+
+ Calendar Greg = GregorianCalendar.GetDefaultInstance();
+ gy = Greg.GetYear(time);
+ gm = Greg.GetMonth(time);
+ gd = Greg.GetDayOfMonth(time);
+
+ GregorianToLunar(gy, gm, gd, ref year, ref month, ref day);
+ }
+
+ // Returns the DateTime resulting from adding the given number of
+ // months to the specified DateTime. The result is computed by incrementing
+ // (or decrementing) the year and month parts of the specified DateTime by
+ // value months, and, if required, adjusting the day part of the
+ // resulting date downwards to the last day of the resulting month in the
+ // resulting year. The time-of-day part of the result is the same as the
+ // time-of-day part of the specified DateTime.
+ //
+
+ public override DateTime AddMonths(DateTime time, int months)
+ {
+ if (months < -120000 || months > 120000)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(months),
+ SR.Format(SR.ArgumentOutOfRange_Range, -120000, 120000));
+ }
+ Contract.EndContractBlock();
+
+ CheckTicksRange(time.Ticks);
+
+ int y = 0; int m = 0; int d = 0;
+ TimeToLunar(time, ref y, ref m, ref d);
+
+ int i = m + months;
+ if (i > 0)
+ {
+ int monthsInYear = InternalIsLeapYear(y) ? 13 : 12;
+
+ while (i - monthsInYear > 0)
+ {
+ i -= monthsInYear;
+ y++;
+ monthsInYear = InternalIsLeapYear(y) ? 13 : 12;
+ }
+ m = i;
+ }
+ else
+ {
+ int monthsInYear;
+ while (i <= 0)
+ {
+ monthsInYear = InternalIsLeapYear(y - 1) ? 13 : 12;
+ i += monthsInYear;
+ y--;
+ }
+ m = i;
+ }
+
+ int days = InternalGetDaysInMonth(y, m);
+ if (d > days)
+ {
+ d = days;
+ }
+ DateTime dt = LunarToTime(time, y, m, d);
+
+ CheckAddResult(dt.Ticks, MinSupportedDateTime, MaxSupportedDateTime);
+ return (dt);
+ }
+
+
+ public override DateTime AddYears(DateTime time, int years)
+ {
+ CheckTicksRange(time.Ticks);
+
+ int y = 0; int m = 0; int d = 0;
+ TimeToLunar(time, ref y, ref m, ref d);
+
+ y += years;
+
+ if (m == 13 && !InternalIsLeapYear(y))
+ {
+ m = 12;
+ d = InternalGetDaysInMonth(y, m);
+ }
+ int DaysInMonths = InternalGetDaysInMonth(y, m);
+ if (d > DaysInMonths)
+ {
+ d = DaysInMonths;
+ }
+
+ DateTime dt = LunarToTime(time, y, m, d);
+ CheckAddResult(dt.Ticks, MinSupportedDateTime, MaxSupportedDateTime);
+ return (dt);
+ }
+
+ // Returns the day-of-year part of the specified DateTime. The returned value
+ // is an integer between 1 and [354|355 |383|384].
+ //
+
+ public override int GetDayOfYear(DateTime time)
+ {
+ CheckTicksRange(time.Ticks);
+
+ int y = 0; int m = 0; int d = 0;
+ TimeToLunar(time, ref y, ref m, ref d);
+
+ for (int i = 1; i < m; i++)
+ {
+ d = d + InternalGetDaysInMonth(y, i);
+ }
+ return d;
+ }
+
+ // Returns the day-of-month part of the specified DateTime. The returned
+ // value is an integer between 1 and 29 or 30.
+ //
+
+ public override int GetDayOfMonth(DateTime time)
+ {
+ CheckTicksRange(time.Ticks);
+
+ int y = 0; int m = 0; int d = 0;
+ TimeToLunar(time, ref y, ref m, ref d);
+
+ return d;
+ }
+
+ // Returns the number of days in the year given by the year argument for the current era.
+ //
+
+ public override int GetDaysInYear(int year, int era)
+ {
+ year = CheckYearRange(year, era);
+
+ int Days = 0;
+ int monthsInYear = InternalIsLeapYear(year) ? 13 : 12;
+
+ while (monthsInYear != 0)
+ Days += InternalGetDaysInMonth(year, monthsInYear--);
+
+ return Days;
+ }
+
+ // Returns the month part of the specified DateTime. The returned value is an
+ // integer between 1 and 13.
+ //
+
+ public override int GetMonth(DateTime time)
+ {
+ CheckTicksRange(time.Ticks);
+
+ int y = 0; int m = 0; int d = 0;
+ TimeToLunar(time, ref y, ref m, ref d);
+
+ return m;
+ }
+
+ // Returns the year part of the specified DateTime. The returned value is an
+ // integer between 1 and MaxCalendarYear.
+ //
+
+ public override int GetYear(DateTime time)
+ {
+ CheckTicksRange(time.Ticks);
+
+ int y = 0; int m = 0; int d = 0;
+ TimeToLunar(time, ref y, ref m, ref d);
+
+ return GetYear(y, time);
+ }
+
+ // Returns the day-of-week part of the specified DateTime. The returned value
+ // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
+ // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
+ // Thursday, 5 indicates Friday, and 6 indicates Saturday.
+ //
+
+ public override DayOfWeek GetDayOfWeek(DateTime time)
+ {
+ CheckTicksRange(time.Ticks);
+ return ((DayOfWeek)((int)(time.Ticks / Calendar.TicksPerDay + 1) % 7));
+ }
+
+ // Returns the number of months in the specified year and era.
+
+ public override int GetMonthsInYear(int year, int era)
+ {
+ year = CheckYearRange(year, era);
+ return (InternalIsLeapYear(year) ? 13 : 12);
+ }
+
+ // Checks whether a given day in the specified era is a leap day. This method returns true if
+ // the date is a leap day, or false if not.
+ //
+
+ public override bool IsLeapDay(int year, int month, int day, int era)
+ {
+ year = CheckYearMonthRange(year, month, era);
+ int daysInMonth = InternalGetDaysInMonth(year, month);
+
+ if (day < 1 || day > daysInMonth)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(day),
+ SR.Format(SR.ArgumentOutOfRange_Day, daysInMonth, month));
+ }
+ int m = GetYearInfo(year, LeapMonth);
+ return ((m != 0) && (month == (m + 1)));
+ }
+
+ // Checks whether a given month in the specified era is a leap month. This method returns true if
+ // month is a leap month, or false if not.
+ //
+
+ public override bool IsLeapMonth(int year, int month, int era)
+ {
+ year = CheckYearMonthRange(year, month, era);
+ int m = GetYearInfo(year, LeapMonth);
+ return ((m != 0) && (month == (m + 1)));
+ }
+
+ // Returns the leap month in a calendar year of the specified era. This method returns 0
+ // if this this year is not a leap year.
+ //
+
+ public override int GetLeapMonth(int year, int era)
+ {
+ year = CheckYearRange(year, era);
+ int month = GetYearInfo(year, LeapMonth);
+ if (month > 0)
+ {
+ return (month + 1);
+ }
+ return 0;
+ }
+
+ internal bool InternalIsLeapYear(int year)
+ {
+ return (GetYearInfo(year, LeapMonth) != 0);
+ }
+ // Checks whether a given year in the specified era is a leap year. This method returns true if
+ // year is a leap year, or false if not.
+ //
+
+ public override bool IsLeapYear(int year, int era)
+ {
+ year = CheckYearRange(year, era);
+ return InternalIsLeapYear(year);
+ }
+
+ private const int DEFAULT_GREGORIAN_TWO_DIGIT_YEAR_MAX = 2029;
+
+
+ public override int TwoDigitYearMax
+ {
+ get
+ {
+ if (twoDigitYearMax == -1)
+ {
+ twoDigitYearMax = GetSystemTwoDigitYearSetting(BaseCalendarID, GetYear(new DateTime(DEFAULT_GREGORIAN_TWO_DIGIT_YEAR_MAX, 1, 1)));
+ }
+ return (twoDigitYearMax);
+ }
+
+ set
+ {
+ VerifyWritable();
+ if (value < 99 || value > MaxCalendarYear)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(value),
+ SR.Format(SR.ArgumentOutOfRange_Range, 99, MaxCalendarYear));
+ }
+ twoDigitYearMax = value;
+ }
+ }
+
+
+ public override int ToFourDigitYear(int year)
+ {
+ if (year < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(year),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ }
+ Contract.EndContractBlock();
+
+ year = base.ToFourDigitYear(year);
+ CheckYearRange(year, CurrentEra);
+ return (year);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/GregorianCalendarTypes.cs b/src/mscorlib/shared/System/Globalization/GregorianCalendarTypes.cs
new file mode 100644
index 0000000000..1b61e5256e
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/GregorianCalendarTypes.cs
@@ -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.
+
+namespace System.Globalization
+{
+ // Note: The values of the members of this enum must match the coresponding values
+ // in the CalendarId enum (since we cast between GregorianCalendarTypes and CalendarId).
+ [Serializable]
+ public enum GregorianCalendarTypes
+ {
+ Localized = CalendarId.GREGORIAN,
+ USEnglish = CalendarId.GREGORIAN_US,
+ MiddleEastFrench = CalendarId.GREGORIAN_ME_FRENCH,
+ Arabic = CalendarId.GREGORIAN_ARABIC,
+ TransliteratedEnglish = CalendarId.GREGORIAN_XLIT_ENGLISH,
+ TransliteratedFrench = CalendarId.GREGORIAN_XLIT_FRENCH,
+ }
+}
diff --git a/src/mscorlib/corefx/System/Globalization/HebrewCalendar.cs b/src/mscorlib/shared/System/Globalization/HebrewCalendar.cs
index b4f54f8fbb..b4f54f8fbb 100644
--- a/src/mscorlib/corefx/System/Globalization/HebrewCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/HebrewCalendar.cs
diff --git a/src/mscorlib/shared/System/Globalization/HebrewNumber.cs b/src/mscorlib/shared/System/Globalization/HebrewNumber.cs
new file mode 100644
index 0000000000..1e8fff2bcb
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/HebrewNumber.cs
@@ -0,0 +1,457 @@
+// 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.Text;
+using System.Diagnostics;
+
+namespace System.Globalization
+{
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Used in HebrewNumber.ParseByChar to maintain the context information (
+ // the state in the state machine and current Hebrew number values, etc.)
+ // when parsing Hebrew number character by character.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ internal struct HebrewNumberParsingContext
+ {
+ // The current state of the state machine for parsing Hebrew numbers.
+ internal HebrewNumber.HS state;
+ // The current value of the Hebrew number.
+ // The final value is determined when state is FoundEndOfHebrewNumber.
+ internal int result;
+
+ public HebrewNumberParsingContext(int result)
+ {
+ // Set the start state of the state machine for parsing Hebrew numbers.
+ state = HebrewNumber.HS.Start;
+ this.result = result;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Please see ParseByChar() for comments about different states defined here.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ internal enum HebrewNumberParsingState
+ {
+ InvalidHebrewNumber,
+ NotHebrewDigit,
+ FoundEndOfHebrewNumber,
+ ContinueParsing,
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // class HebrewNumber
+ //
+ // Provides static methods for formatting integer values into
+ // Hebrew text and parsing Hebrew number text.
+ //
+ // Limitations:
+ // Parse can only handles value 1 ~ 999.
+ // ToString() can only handles 1 ~ 999. If value is greater than 5000,
+ // 5000 will be subtracted from the value.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ internal class HebrewNumber
+ {
+ // This class contains only static methods. Add a private ctor so that
+ // compiler won't generate a default one for us.
+ private HebrewNumber()
+ {
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // ToString
+ //
+ // Converts the given number to Hebrew letters according to the numeric
+ // value of each Hebrew letter. Basically, this converts the lunar year
+ // and the lunar month to letters.
+ //
+ // The character of a year is described by three letters of the Hebrew
+ // alphabet, the first and third giving, respectively, the days of the
+ // weeks on which the New Year occurs and Passover begins, while the
+ // second is the initial of the Hebrew word for defective, normal, or
+ // complete.
+ //
+ // Defective Year : Both Heshvan and Kislev are defective (353 or 383 days)
+ // Normal Year : Heshvan is defective, Kislev is full (354 or 384 days)
+ // Complete Year : Both Heshvan and Kislev are full (355 or 385 days)
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ internal static String ToString(int Number)
+ {
+ char cTens = '\x0';
+ char cUnits; // tens and units chars
+ int Hundreds, Tens; // hundreds and tens values
+ StringBuilder szHebrew = new StringBuilder();
+
+
+ //
+ // Adjust the number if greater than 5000.
+ //
+ if (Number > 5000)
+ {
+ Number -= 5000;
+ }
+
+ Debug.Assert(Number > 0 && Number <= 999, "Number is out of range."); ;
+
+ //
+ // Get the Hundreds.
+ //
+ Hundreds = Number / 100;
+
+ if (Hundreds > 0)
+ {
+ Number -= Hundreds * 100;
+ // \x05e7 = 100
+ // \x05e8 = 200
+ // \x05e9 = 300
+ // \x05ea = 400
+ // If the number is greater than 400, use the multiples of 400.
+ for (int i = 0; i < (Hundreds / 4); i++)
+ {
+ szHebrew.Append('\x05ea');
+ }
+
+ int remains = Hundreds % 4;
+ if (remains > 0)
+ {
+ szHebrew.Append((char)((int)'\x05e6' + remains));
+ }
+ }
+
+ //
+ // Get the Tens.
+ //
+ Tens = Number / 10;
+ Number %= 10;
+
+ switch (Tens)
+ {
+ case (0):
+ cTens = '\x0';
+ break;
+ case (1):
+ cTens = '\x05d9'; // Hebrew Letter Yod
+ break;
+ case (2):
+ cTens = '\x05db'; // Hebrew Letter Kaf
+ break;
+ case (3):
+ cTens = '\x05dc'; // Hebrew Letter Lamed
+ break;
+ case (4):
+ cTens = '\x05de'; // Hebrew Letter Mem
+ break;
+ case (5):
+ cTens = '\x05e0'; // Hebrew Letter Nun
+ break;
+ case (6):
+ cTens = '\x05e1'; // Hebrew Letter Samekh
+ break;
+ case (7):
+ cTens = '\x05e2'; // Hebrew Letter Ayin
+ break;
+ case (8):
+ cTens = '\x05e4'; // Hebrew Letter Pe
+ break;
+ case (9):
+ cTens = '\x05e6'; // Hebrew Letter Tsadi
+ break;
+ }
+
+ //
+ // Get the Units.
+ //
+ cUnits = (char)(Number > 0 ? ((int)'\x05d0' + Number - 1) : 0);
+
+ if ((cUnits == '\x05d4') && // Hebrew Letter He (5)
+ (cTens == '\x05d9'))
+ { // Hebrew Letter Yod (10)
+ cUnits = '\x05d5'; // Hebrew Letter Vav (6)
+ cTens = '\x05d8'; // Hebrew Letter Tet (9)
+ }
+
+ if ((cUnits == '\x05d5') && // Hebrew Letter Vav (6)
+ (cTens == '\x05d9'))
+ { // Hebrew Letter Yod (10)
+ cUnits = '\x05d6'; // Hebrew Letter Zayin (7)
+ cTens = '\x05d8'; // Hebrew Letter Tet (9)
+ }
+
+ //
+ // Copy the appropriate info to the given buffer.
+ //
+
+ if (cTens != '\x0')
+ {
+ szHebrew.Append(cTens);
+ }
+
+ if (cUnits != '\x0')
+ {
+ szHebrew.Append(cUnits);
+ }
+
+ if (szHebrew.Length > 1)
+ {
+ szHebrew.Insert(szHebrew.Length - 1, '"');
+ }
+ else
+ {
+ szHebrew.Append('\'');
+ }
+
+ //
+ // Return success.
+ //
+ return (szHebrew.ToString());
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Token used to tokenize a Hebrew word into tokens so that we can use in the
+ // state machine.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ private enum HebrewToken : short
+ {
+ Invalid = -1,
+ Digit400 = 0,
+ Digit200_300 = 1,
+ Digit100 = 2,
+ Digit10 = 3, // 10 ~ 90
+ Digit1 = 4, // 1, 2, 3, 4, 5, 8,
+ Digit6_7 = 5,
+ Digit7 = 6,
+ Digit9 = 7,
+ SingleQuote = 8,
+ DoubleQuote = 9,
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // This class is used to map a token into its Hebrew digit value.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ private struct HebrewValue
+ {
+ internal HebrewToken token;
+ internal short value;
+ internal HebrewValue(HebrewToken token, short value)
+ {
+ this.token = token;
+ this.value = value;
+ }
+ }
+
+ //
+ // Map a Hebrew character from U+05D0 ~ U+05EA to its digit value.
+ // The value is -1 if the Hebrew character does not have a associated value.
+ //
+ private static readonly HebrewValue[] s_hebrewValues = {
+ new HebrewValue(HebrewToken.Digit1, 1) , // '\x05d0
+ new HebrewValue(HebrewToken.Digit1, 2) , // '\x05d1
+ new HebrewValue(HebrewToken.Digit1, 3) , // '\x05d2
+ new HebrewValue(HebrewToken.Digit1, 4) , // '\x05d3
+ new HebrewValue(HebrewToken.Digit1, 5) , // '\x05d4
+ new HebrewValue(HebrewToken.Digit6_7,6) , // '\x05d5
+ new HebrewValue(HebrewToken.Digit6_7,7) , // '\x05d6
+ new HebrewValue(HebrewToken.Digit1, 8) , // '\x05d7
+ new HebrewValue(HebrewToken.Digit9, 9) , // '\x05d8
+ new HebrewValue(HebrewToken.Digit10, 10) , // '\x05d9; // Hebrew Letter Yod
+ new HebrewValue(HebrewToken.Invalid, -1) , // '\x05da;
+ new HebrewValue(HebrewToken.Digit10, 20) , // '\x05db; // Hebrew Letter Kaf
+ new HebrewValue(HebrewToken.Digit10, 30) , // '\x05dc; // Hebrew Letter Lamed
+ new HebrewValue(HebrewToken.Invalid, -1) , // '\x05dd;
+ new HebrewValue(HebrewToken.Digit10, 40) , // '\x05de; // Hebrew Letter Mem
+ new HebrewValue(HebrewToken.Invalid, -1) , // '\x05df;
+ new HebrewValue(HebrewToken.Digit10, 50) , // '\x05e0; // Hebrew Letter Nun
+ new HebrewValue(HebrewToken.Digit10, 60) , // '\x05e1; // Hebrew Letter Samekh
+ new HebrewValue(HebrewToken.Digit10, 70) , // '\x05e2; // Hebrew Letter Ayin
+ new HebrewValue(HebrewToken.Invalid, -1) , // '\x05e3;
+ new HebrewValue(HebrewToken.Digit10, 80) , // '\x05e4; // Hebrew Letter Pe
+ new HebrewValue(HebrewToken.Invalid, -1) , // '\x05e5;
+ new HebrewValue(HebrewToken.Digit10, 90) , // '\x05e6; // Hebrew Letter Tsadi
+ new HebrewValue(HebrewToken.Digit100, 100) , // '\x05e7;
+ new HebrewValue(HebrewToken.Digit200_300, 200) , // '\x05e8;
+ new HebrewValue(HebrewToken.Digit200_300, 300) , // '\x05e9;
+ new HebrewValue(HebrewToken.Digit400, 400) , // '\x05ea;
+ };
+
+ private const int minHebrewNumberCh = 0x05d0;
+ private static char s_maxHebrewNumberCh = (char)(minHebrewNumberCh + s_hebrewValues.Length - 1);
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Hebrew number parsing State
+ // The current state and the next token will lead to the next state in the state machine.
+ // DQ = Double Quote
+ //
+ ////////////////////////////////////////////////////////////////////////////
+
+ internal enum HS : sbyte
+ {
+ _err = -1, // an error state
+ Start = 0,
+ S400 = 1, // a Hebrew digit 400
+ S400_400 = 2, // Two Hebrew digit 400
+ S400_X00 = 3, // Two Hebrew digit 400 and followed by 100
+ S400_X0 = 4, // Hebrew digit 400 and followed by 10 ~ 90
+ X00_DQ = 5, // A hundred number and followed by a double quote.
+ S400_X00_X0 = 6,
+ X0_DQ = 7, // A two-digit number and followed by a double quote.
+ X = 8, // A single digit Hebrew number.
+ X0 = 9, // A two-digit Hebrew number
+ X00 = 10, // A three-digit Hebrew number
+ S400_DQ = 11, // A Hebrew digit 400 and followed by a double quote.
+ S400_400_DQ = 12,
+ S400_400_100 = 13,
+ S9 = 14, // Hebrew digit 9
+ X00_S9 = 15, // A hundered number and followed by a digit 9
+ S9_DQ = 16, // Hebrew digit 9 and followed by a double quote
+ END = 100, // A terminial state is reached.
+ }
+
+ //
+ // The state machine for Hebrew number pasing.
+ //
+ private static readonly HS[] s_numberPasingState =
+ {
+ // 400 300/200 100 90~10 8~1 6, 7, 9, ' "
+ /* 0 */
+ HS.S400, HS.X00, HS.X00, HS.X0, HS.X, HS.X, HS.X, HS.S9, HS._err, HS._err,
+ /* 1: S400 */
+ HS.S400_400, HS.S400_X00, HS.S400_X00, HS.S400_X0, HS._err, HS._err, HS._err, HS.X00_S9 ,HS.END, HS.S400_DQ,
+ /* 2: S400_400 */
+ HS._err, HS._err, HS.S400_400_100,HS.S400_X0, HS._err, HS._err, HS._err, HS.X00_S9 ,HS._err, HS.S400_400_DQ,
+ /* 3: S400_X00 */
+ HS._err, HS._err, HS._err, HS.S400_X00_X0, HS._err, HS._err, HS._err, HS.X00_S9 ,HS._err, HS.X00_DQ,
+ /* 4: S400_X0 */
+ HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.X0_DQ,
+ /* 5: X00_DQ */
+ HS._err, HS._err, HS._err, HS.END, HS.END, HS.END, HS.END, HS.END, HS._err, HS._err,
+ /* 6: S400_X00_X0 */
+ HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.X0_DQ,
+ /* 7: X0_DQ */
+ HS._err, HS._err, HS._err, HS._err, HS.END, HS.END, HS.END, HS.END, HS._err, HS._err,
+ /* 8: X */
+ HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.END, HS._err,
+ /* 9: X0 */
+ HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.END, HS.X0_DQ,
+ /* 10: X00 */
+ HS._err, HS._err, HS._err, HS.S400_X0, HS._err, HS._err, HS._err, HS.X00_S9, HS.END, HS.X00_DQ,
+ /* 11: S400_DQ */
+ HS.END, HS.END, HS.END, HS.END, HS.END, HS.END, HS.END, HS.END, HS._err, HS._err,
+ /* 12: S400_400_DQ*/
+ HS._err, HS._err, HS.END, HS.END, HS.END, HS.END, HS.END, HS.END, HS._err, HS._err,
+ /* 13: S400_400_100*/
+ HS._err, HS._err, HS._err, HS.S400_X00_X0, HS._err, HS._err, HS._err, HS.X00_S9, HS._err, HS.X00_DQ,
+ /* 14: S9 */
+ HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.END, HS.S9_DQ,
+ /* 15: X00_S9 */
+ HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.S9_DQ,
+ /* 16: S9_DQ */
+ HS._err, HS._err, HS._err, HS._err, HS._err, HS.END, HS.END, HS._err, HS._err, HS._err
+ };
+
+ // Count of valid HebrewToken, column count in the NumberPasingState array
+ private const int HebrewTokenCount = 10;
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Actions:
+ // Parse the Hebrew number by passing one character at a time.
+ // The state between characters are maintained at HebrewNumberPasingContext.
+ // Returns:
+ // Return a enum of HebrewNumberParsingState.
+ // NotHebrewDigit: The specified ch is not a valid Hebrew digit.
+ // InvalidHebrewNumber: After parsing the specified ch, it will lead into
+ // an invalid Hebrew number text.
+ // FoundEndOfHebrewNumber: A terminal state is reached. This means that
+ // we find a valid Hebrew number text after the specified ch is parsed.
+ // ContinueParsing: The specified ch is a valid Hebrew digit, and
+ // it will lead into a valid state in the state machine, we should
+ // continue to parse incoming characters.
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ internal static HebrewNumberParsingState ParseByChar(char ch, ref HebrewNumberParsingContext context)
+ {
+ Debug.Assert(s_numberPasingState.Length == HebrewTokenCount * ((int)HS.S9_DQ + 1));
+
+ HebrewToken token;
+ if (ch == '\'')
+ {
+ token = HebrewToken.SingleQuote;
+ }
+ else if (ch == '\"')
+ {
+ token = HebrewToken.DoubleQuote;
+ }
+ else
+ {
+ int index = (int)ch - minHebrewNumberCh;
+ if (index >= 0 && index < s_hebrewValues.Length)
+ {
+ token = s_hebrewValues[index].token;
+ if (token == HebrewToken.Invalid)
+ {
+ return (HebrewNumberParsingState.NotHebrewDigit);
+ }
+ context.result += s_hebrewValues[index].value;
+ }
+ else
+ {
+ // Not in valid Hebrew digit range.
+ return (HebrewNumberParsingState.NotHebrewDigit);
+ }
+ }
+ context.state = s_numberPasingState[(int)context.state * (int)HebrewTokenCount + (int)token];
+ if (context.state == HS._err)
+ {
+ // Invalid Hebrew state. This indicates an incorrect Hebrew number.
+ return (HebrewNumberParsingState.InvalidHebrewNumber);
+ }
+ if (context.state == HS.END)
+ {
+ // Reach a terminal state.
+ return (HebrewNumberParsingState.FoundEndOfHebrewNumber);
+ }
+ // We should continue to parse.
+ return (HebrewNumberParsingState.ContinueParsing);
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Actions:
+ // Check if the ch is a valid Hebrew number digit.
+ // This function will return true if the specified char is a legal Hebrew
+ // digit character, single quote, or double quote.
+ // Returns:
+ // true if the specified character is a valid Hebrew number character.
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ internal static bool IsDigit(char ch)
+ {
+ if (ch >= minHebrewNumberCh && ch <= s_maxHebrewNumberCh)
+ {
+ return (s_hebrewValues[ch - minHebrewNumberCh].value >= 0);
+ }
+ return (ch == '\'' || ch == '\"');
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/HijriCalendar.cs b/src/mscorlib/shared/System/Globalization/HijriCalendar.cs
new file mode 100644
index 0000000000..cafde5fbb8
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/HijriCalendar.cs
@@ -0,0 +1,677 @@
+// 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.Diagnostics.Contracts;
+
+namespace System.Globalization
+{
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Rules for the Hijri calendar:
+ // - The Hijri calendar is a strictly Lunar calendar.
+ // - Days begin at sunset.
+ // - Islamic Year 1 (Muharram 1, 1 A.H.) is equivalent to absolute date
+ // 227015 (Friday, July 16, 622 C.E. - Julian).
+ // - Leap Years occur in the 2, 5, 7, 10, 13, 16, 18, 21, 24, 26, & 29th
+ // years of a 30-year cycle. Year = leap iff ((11y+14) mod 30 < 11).
+ // - There are 12 months which contain alternately 30 and 29 days.
+ // - The 12th month, Dhu al-Hijjah, contains 30 days instead of 29 days
+ // in a leap year.
+ // - Common years have 354 days. Leap years have 355 days.
+ // - There are 10,631 days in a 30-year cycle.
+ // - The Islamic months are:
+ // 1. Muharram (30 days) 7. Rajab (30 days)
+ // 2. Safar (29 days) 8. Sha'ban (29 days)
+ // 3. Rabi I (30 days) 9. Ramadan (30 days)
+ // 4. Rabi II (29 days) 10. Shawwal (29 days)
+ // 5. Jumada I (30 days) 11. Dhu al-Qada (30 days)
+ // 6. Jumada II (29 days) 12. Dhu al-Hijjah (29 days) {30}
+ //
+ // NOTENOTE
+ // The calculation of the HijriCalendar is based on the absolute date. And the
+ // absolute date means the number of days from January 1st, 1 A.D.
+ // Therefore, we do not support the days before the January 1st, 1 A.D.
+ //
+ ////////////////////////////////////////////////////////////////////////////
+ /*
+ ** Calendar support range:
+ ** Calendar Minimum Maximum
+ ** ========== ========== ==========
+ ** Gregorian 0622/07/18 9999/12/31
+ ** Hijri 0001/01/01 9666/04/03
+ */
+
+ [Serializable]
+ public partial class HijriCalendar : Calendar
+ {
+ public static readonly int HijriEra = 1;
+
+ internal const int DatePartYear = 0;
+ internal const int DatePartDayOfYear = 1;
+ internal const int DatePartMonth = 2;
+ internal const int DatePartDay = 3;
+
+ internal const int MinAdvancedHijri = -2;
+ internal const int MaxAdvancedHijri = 2;
+
+ internal static readonly int[] HijriMonthDays = { 0, 30, 59, 89, 118, 148, 177, 207, 236, 266, 295, 325, 355 };
+
+ private int _hijriAdvance = Int32.MinValue;
+
+ // DateTime.MaxValue = Hijri calendar (year:9666, month: 4, day: 3).
+ internal const int MaxCalendarYear = 9666;
+ internal const int MaxCalendarMonth = 4;
+ internal const int MaxCalendarDay = 3;
+ // Hijri calendar (year: 1, month: 1, day:1 ) = Gregorian (year: 622, month: 7, day: 18)
+ // This is the minimal Gregorian date that we support in the HijriCalendar.
+ internal static readonly DateTime calendarMinValue = new DateTime(622, 7, 18);
+ internal static readonly DateTime calendarMaxValue = DateTime.MaxValue;
+
+
+ public override DateTime MinSupportedDateTime
+ {
+ get
+ {
+ return (calendarMinValue);
+ }
+ }
+
+
+ public override DateTime MaxSupportedDateTime
+ {
+ get
+ {
+ return (calendarMaxValue);
+ }
+ }
+
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.LunarCalendar;
+ }
+ }
+
+ public HijriCalendar()
+ {
+ }
+
+ internal override CalendarId ID
+ {
+ get
+ {
+ return CalendarId.HIJRI;
+ }
+ }
+
+ protected override int DaysInYearBeforeMinSupportedYear
+ {
+ get
+ {
+ // the year before the 1st year of the cycle would have been the 30th year
+ // of the previous cycle which is not a leap year. Common years have 354 days.
+ return 354;
+ }
+ }
+
+
+
+ /*=================================GetAbsoluteDateHijri==========================
+ **Action: Gets the Absolute date for the given Hijri date. The absolute date means
+ ** the number of days from January 1st, 1 A.D.
+ **Returns:
+ **Arguments:
+ **Exceptions:
+ ============================================================================*/
+
+ private long GetAbsoluteDateHijri(int y, int m, int d)
+ {
+ return (long)(DaysUpToHijriYear(y) + HijriMonthDays[m - 1] + d - 1 - HijriAdjustment);
+ }
+
+ /*=================================DaysUpToHijriYear==========================
+ **Action: Gets the total number of days (absolute date) up to the given Hijri Year.
+ ** The absolute date means the number of days from January 1st, 1 A.D.
+ **Returns: Gets the total number of days (absolute date) up to the given Hijri Year.
+ **Arguments: HijriYear year value in Hijri calendar.
+ **Exceptions: None
+ **Notes:
+ ============================================================================*/
+
+ private long DaysUpToHijriYear(int HijriYear)
+ {
+ long NumDays; // number of absolute days
+ int NumYear30; // number of years up to current 30 year cycle
+ int NumYearsLeft; // number of years into 30 year cycle
+
+ //
+ // Compute the number of years up to the current 30 year cycle.
+ //
+ NumYear30 = ((HijriYear - 1) / 30) * 30;
+
+ //
+ // Compute the number of years left. This is the number of years
+ // into the 30 year cycle for the given year.
+ //
+ NumYearsLeft = HijriYear - NumYear30 - 1;
+
+ //
+ // Compute the number of absolute days up to the given year.
+ //
+ NumDays = ((NumYear30 * 10631L) / 30L) + 227013L;
+ while (NumYearsLeft > 0)
+ {
+ // Common year is 354 days, and leap year is 355 days.
+ NumDays += 354 + (IsLeapYear(NumYearsLeft, CurrentEra) ? 1 : 0);
+ NumYearsLeft--;
+ }
+
+ //
+ // Return the number of absolute days.
+ //
+ return (NumDays);
+ }
+
+ public int HijriAdjustment
+ {
+ get
+ {
+ if (_hijriAdvance == Int32.MinValue)
+ {
+ // Never been set before. Use the system value from registry.
+ _hijriAdvance = GetHijriDateAdjustment();
+ }
+ return (_hijriAdvance);
+ }
+
+ set
+ {
+ // NOTE: Check the value of Min/MaxAdavncedHijri with Arabic speakers to see if the assumption is good.
+ if (value < MinAdvancedHijri || value > MaxAdvancedHijri)
+ {
+ throw new ArgumentOutOfRangeException(
+ "HijriAdjustment",
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Bounds_Lower_Upper,
+ MinAdvancedHijri,
+ MaxAdvancedHijri));
+ }
+ Contract.EndContractBlock();
+ VerifyWritable();
+
+ _hijriAdvance = value;
+ }
+ }
+
+ internal static void CheckTicksRange(long ticks)
+ {
+ if (ticks < calendarMinValue.Ticks || ticks > calendarMaxValue.Ticks)
+ {
+ throw new ArgumentOutOfRangeException(
+ "time",
+ String.Format(
+ CultureInfo.InvariantCulture,
+ SR.ArgumentOutOfRange_CalendarRange,
+ calendarMinValue,
+ calendarMaxValue));
+ }
+ }
+
+ internal static void CheckEraRange(int era)
+ {
+ if (era != CurrentEra && era != HijriEra)
+ {
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
+ }
+ }
+
+ internal static void CheckYearRange(int year, int era)
+ {
+ CheckEraRange(era);
+ if (year < 1 || year > MaxCalendarYear)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(year),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ 1,
+ MaxCalendarYear));
+ }
+ }
+
+ internal static void CheckYearMonthRange(int year, int month, int era)
+ {
+ CheckYearRange(year, era);
+ if (year == MaxCalendarYear)
+ {
+ if (month > MaxCalendarMonth)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(month),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ 1,
+ MaxCalendarMonth));
+ }
+ }
+
+ if (month < 1 || month > 12)
+ {
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
+ }
+ }
+
+ /*=================================GetDatePart==========================
+ **Action: Returns a given date part of this <i>DateTime</i>. This method is used
+ ** to compute the year, day-of-year, month, or day part.
+ **Returns:
+ **Arguments:
+ **Exceptions: ArgumentException if part is incorrect.
+ **Notes:
+ ** First, we get the absolute date (the number of days from January 1st, 1 A.C) for the given ticks.
+ ** Use the formula (((AbsoluteDate - 227013) * 30) / 10631) + 1, we can a rough value for the Hijri year.
+ ** In order to get the exact Hijri year, we compare the exact absolute date for HijriYear and (HijriYear + 1).
+ ** From here, we can get the correct Hijri year.
+ ============================================================================*/
+
+ internal virtual int GetDatePart(long ticks, int part)
+ {
+ int HijriYear; // Hijri year
+ int HijriMonth; // Hijri month
+ int HijriDay; // Hijri day
+ long NumDays; // The calculation buffer in number of days.
+
+ CheckTicksRange(ticks);
+
+ //
+ // Get the absolute date. The absolute date is the number of days from January 1st, 1 A.D.
+ // 1/1/0001 is absolute date 1.
+ //
+ NumDays = ticks / GregorianCalendar.TicksPerDay + 1;
+
+ //
+ // See how much we need to backup or advance
+ //
+ NumDays += HijriAdjustment;
+
+ //
+ // Calculate the appromixate Hijri Year from this magic formula.
+ //
+ HijriYear = (int)(((NumDays - 227013) * 30) / 10631) + 1;
+
+ long daysToHijriYear = DaysUpToHijriYear(HijriYear); // The absoulte date for HijriYear
+ long daysOfHijriYear = GetDaysInYear(HijriYear, CurrentEra); // The number of days for (HijriYear+1) year.
+
+ if (NumDays < daysToHijriYear)
+ {
+ daysToHijriYear -= daysOfHijriYear;
+ HijriYear--;
+ }
+ else if (NumDays == daysToHijriYear)
+ {
+ HijriYear--;
+ daysToHijriYear -= GetDaysInYear(HijriYear, CurrentEra);
+ }
+ else
+ {
+ if (NumDays > daysToHijriYear + daysOfHijriYear)
+ {
+ daysToHijriYear += daysOfHijriYear;
+ HijriYear++;
+ }
+ }
+ if (part == DatePartYear)
+ {
+ return (HijriYear);
+ }
+
+ //
+ // Calculate the Hijri Month.
+ //
+
+ HijriMonth = 1;
+ NumDays -= daysToHijriYear;
+
+ if (part == DatePartDayOfYear)
+ {
+ return ((int)NumDays);
+ }
+
+ while ((HijriMonth <= 12) && (NumDays > HijriMonthDays[HijriMonth - 1]))
+ {
+ HijriMonth++;
+ }
+ HijriMonth--;
+
+ if (part == DatePartMonth)
+ {
+ return (HijriMonth);
+ }
+
+ //
+ // Calculate the Hijri Day.
+ //
+ HijriDay = (int)(NumDays - HijriMonthDays[HijriMonth - 1]);
+
+ if (part == DatePartDay)
+ {
+ return (HijriDay);
+ }
+ // Incorrect part value.
+ throw new InvalidOperationException(SR.InvalidOperation_DateTimeParsing);
+ }
+
+ // Returns the DateTime resulting from adding the given number of
+ // months to the specified DateTime. The result is computed by incrementing
+ // (or decrementing) the year and month parts of the specified DateTime by
+ // value months, and, if required, adjusting the day part of the
+ // resulting date downwards to the last day of the resulting month in the
+ // resulting year. The time-of-day part of the result is the same as the
+ // time-of-day part of the specified DateTime.
+ //
+ // In more precise terms, considering the specified DateTime to be of the
+ // form y / m / d + t, where y is the
+ // year, m is the month, d is the day, and t is the
+ // time-of-day, the result is y1 / m1 / d1 + t,
+ // where y1 and m1 are computed by adding value months
+ // to y and m, and d1 is the largest value less than
+ // or equal to d that denotes a valid day in month m1 of year
+ // y1.
+ //
+
+ public override DateTime AddMonths(DateTime time, int months)
+ {
+ if (months < -120000 || months > 120000)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(months),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ -120000,
+ 120000));
+ }
+ Contract.EndContractBlock();
+ // Get the date in Hijri calendar.
+ int y = GetDatePart(time.Ticks, DatePartYear);
+ int m = GetDatePart(time.Ticks, DatePartMonth);
+ int d = GetDatePart(time.Ticks, DatePartDay);
+ int i = m - 1 + months;
+ if (i >= 0)
+ {
+ m = i % 12 + 1;
+ y = y + i / 12;
+ }
+ else
+ {
+ m = 12 + (i + 1) % 12;
+ y = y + (i - 11) / 12;
+ }
+ int days = GetDaysInMonth(y, m);
+ if (d > days)
+ {
+ d = days;
+ }
+ long ticks = GetAbsoluteDateHijri(y, m, d) * TicksPerDay + (time.Ticks % TicksPerDay);
+ Calendar.CheckAddResult(ticks, MinSupportedDateTime, MaxSupportedDateTime);
+ return (new DateTime(ticks));
+ }
+
+ // Returns the DateTime resulting from adding the given number of
+ // years to the specified DateTime. The result is computed by incrementing
+ // (or decrementing) the year part of the specified DateTime by value
+ // years. If the month and day of the specified DateTime is 2/29, and if the
+ // resulting year is not a leap year, the month and day of the resulting
+ // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
+ // parts of the result are the same as those of the specified DateTime.
+ //
+
+ public override DateTime AddYears(DateTime time, int years)
+ {
+ return (AddMonths(time, years * 12));
+ }
+
+ // Returns the day-of-month part of the specified DateTime. The returned
+ // value is an integer between 1 and 31.
+ //
+
+ public override int GetDayOfMonth(DateTime time)
+ {
+ return (GetDatePart(time.Ticks, DatePartDay));
+ }
+
+ // Returns the day-of-week part of the specified DateTime. The returned value
+ // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
+ // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
+ // Thursday, 5 indicates Friday, and 6 indicates Saturday.
+ //
+
+ public override DayOfWeek GetDayOfWeek(DateTime time)
+ {
+ return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
+ }
+
+ // Returns the day-of-year part of the specified DateTime. The returned value
+ // is an integer between 1 and 366.
+ //
+
+ public override int GetDayOfYear(DateTime time)
+ {
+ return (GetDatePart(time.Ticks, DatePartDayOfYear));
+ }
+
+ // Returns the number of days in the month given by the year and
+ // month arguments.
+ //
+ [Pure]
+ public override int GetDaysInMonth(int year, int month, int era)
+ {
+ CheckYearMonthRange(year, month, era);
+ if (month == 12)
+ {
+ // For the 12th month, leap year has 30 days, and common year has 29 days.
+ return (IsLeapYear(year, CurrentEra) ? 30 : 29);
+ }
+ // Other months contain 30 and 29 days alternatively. The 1st month has 30 days.
+ return (((month % 2) == 1) ? 30 : 29);
+ }
+
+ // Returns the number of days in the year given by the year argument for the current era.
+ //
+
+ public override int GetDaysInYear(int year, int era)
+ {
+ CheckYearRange(year, era);
+ // Common years have 354 days. Leap years have 355 days.
+ return (IsLeapYear(year, CurrentEra) ? 355 : 354);
+ }
+
+ // Returns the era for the specified DateTime value.
+
+ public override int GetEra(DateTime time)
+ {
+ CheckTicksRange(time.Ticks);
+ return (HijriEra);
+ }
+
+
+ public override int[] Eras
+ {
+ get
+ {
+ return (new int[] { HijriEra });
+ }
+ }
+
+ // Returns the month part of the specified DateTime. The returned value is an
+ // integer between 1 and 12.
+ //
+
+ public override int GetMonth(DateTime time)
+ {
+ return (GetDatePart(time.Ticks, DatePartMonth));
+ }
+
+ // Returns the number of months in the specified year and era.
+
+ public override int GetMonthsInYear(int year, int era)
+ {
+ CheckYearRange(year, era);
+ return (12);
+ }
+
+ // Returns the year part of the specified DateTime. The returned value is an
+ // integer between 1 and MaxCalendarYear.
+ //
+
+ public override int GetYear(DateTime time)
+ {
+ return (GetDatePart(time.Ticks, DatePartYear));
+ }
+
+ // Checks whether a given day in the specified era is a leap day. This method returns true if
+ // the date is a leap day, or false if not.
+ //
+
+ public override bool IsLeapDay(int year, int month, int day, int era)
+ {
+ // The year/month/era value checking is done in GetDaysInMonth().
+ int daysInMonth = GetDaysInMonth(year, month, era);
+ if (day < 1 || day > daysInMonth)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(day),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Day,
+ daysInMonth,
+ month));
+ }
+ return (IsLeapYear(year, era) && month == 12 && day == 30);
+ }
+
+ // Returns the leap month in a calendar year of the specified era. This method returns 0
+ // if this calendar does not have leap month, or this year is not a leap year.
+ //
+
+ public override int GetLeapMonth(int year, int era)
+ {
+ CheckYearRange(year, era);
+ return (0);
+ }
+
+ // Checks whether a given month in the specified era is a leap month. This method returns true if
+ // month is a leap month, or false if not.
+ //
+
+ public override bool IsLeapMonth(int year, int month, int era)
+ {
+ CheckYearMonthRange(year, month, era);
+ return (false);
+ }
+
+ // Checks whether a given year in the specified era is a leap year. This method returns true if
+ // year is a leap year, or false if not.
+ //
+
+ public override bool IsLeapYear(int year, int era)
+ {
+ CheckYearRange(year, era);
+ return ((((year * 11) + 14) % 30) < 11);
+ }
+
+ // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
+ //
+
+ public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
+ {
+ // The year/month/era checking is done in GetDaysInMonth().
+ int daysInMonth = GetDaysInMonth(year, month, era);
+ if (day < 1 || day > daysInMonth)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(day),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Day,
+ daysInMonth,
+ month));
+ }
+
+ long lDate = GetAbsoluteDateHijri(year, month, day);
+
+ if (lDate >= 0)
+ {
+ return (new DateTime(lDate * GregorianCalendar.TicksPerDay + TimeToTicks(hour, minute, second, millisecond)));
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
+ }
+ }
+
+ private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 1451;
+
+
+ public override int TwoDigitYearMax
+ {
+ get
+ {
+ if (twoDigitYearMax == -1)
+ {
+ twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
+ }
+ return (twoDigitYearMax);
+ }
+
+ set
+ {
+ VerifyWritable();
+ if (value < 99 || value > MaxCalendarYear)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(value),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ 99,
+ MaxCalendarYear));
+ }
+ twoDigitYearMax = value;
+ }
+ }
+
+
+ public override int ToFourDigitYear(int year)
+ {
+ if (year < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(year),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ }
+ Contract.EndContractBlock();
+
+ if (year < 100)
+ {
+ return (base.ToFourDigitYear(year));
+ }
+
+ if (year > MaxCalendarYear)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(year),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ 1,
+ MaxCalendarYear));
+ }
+ return (year);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/InternalGlobalizationHelper.cs b/src/mscorlib/shared/System/Globalization/InternalGlobalizationHelper.cs
new file mode 100644
index 0000000000..f5eea1b629
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/InternalGlobalizationHelper.cs
@@ -0,0 +1,48 @@
+// 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.
+
+namespace System.Globalization
+{
+ internal class InternalGlobalizationHelper
+ {
+ // Copied from the TimeSpan to be used inside the globalization code and avoid internal dependancy on TimeSpan class
+ internal static long TimeToTicks(int hour, int minute, int second)
+ {
+ // totalSeconds is bounded by 2^31 * 2^12 + 2^31 * 2^8 + 2^31,
+ // which is less than 2^44, meaning we won't overflow totalSeconds.
+ long totalSeconds = (long)hour * 3600 + (long)minute * 60 + (long)second;
+ if (totalSeconds > MaxSeconds || totalSeconds < MinSeconds)
+ throw new ArgumentOutOfRangeException(null, SR.Overflow_TimeSpanTooLong);
+ return totalSeconds * TicksPerSecond;
+ }
+
+
+ //
+ // Define needed constants so globalization code can be independant from any other types
+ //
+
+ internal const long TicksPerMillisecond = 10000;
+ internal const long TicksPerTenthSecond = TicksPerMillisecond * 100;
+ internal const long TicksPerSecond = TicksPerMillisecond * 1000; // 10,000,000
+ internal const long MaxSeconds = Int64.MaxValue / TicksPerSecond;
+ internal const long MinSeconds = Int64.MinValue / TicksPerSecond;
+ private const int DaysPerYear = 365;
+ private const int DaysPer4Years = DaysPerYear * 4 + 1; // 1461
+ private const int DaysPer100Years = DaysPer4Years * 25 - 1; // 36524
+ private const int DaysPer400Years = DaysPer100Years * 4 + 1; // 146097
+ private const int DaysTo10000 = DaysPer400Years * 25 - 366; // 3652059
+ private const long TicksPerMinute = TicksPerSecond * 60;
+ private const long TicksPerHour = TicksPerMinute * 60;
+ private const long TicksPerDay = TicksPerHour * 24;
+ internal const long MaxTicks = DaysTo10000 * TicksPerDay - 1;
+ internal const long MinTicks = 0;
+ internal const long MaxMilliSeconds = Int64.MaxValue / TicksPerMillisecond;
+ internal const long MinMilliSeconds = Int64.MinValue / TicksPerMillisecond;
+
+ internal const int StringBuilderDefaultCapacity = 16;
+
+ internal const Int64 MaxOffset = TimeSpan.TicksPerHour * 14;
+ internal const Int64 MinOffset = -MaxOffset;
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/JapaneseCalendar.cs b/src/mscorlib/shared/System/Globalization/JapaneseCalendar.cs
new file mode 100644
index 0000000000..4655e08a4e
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/JapaneseCalendar.cs
@@ -0,0 +1,409 @@
+// 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.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+
+namespace System.Globalization
+{
+ /*=================================JapaneseCalendar==========================
+ **
+ ** JapaneseCalendar is based on Gregorian calendar. The month and day values are the same as
+ ** Gregorian calendar. However, the year value is an offset to the Gregorian
+ ** year based on the era.
+ **
+ ** This system is adopted by Emperor Meiji in 1868. The year value is counted based on the reign of an emperor,
+ ** and the era begins on the day an emperor ascends the throne and continues until his death.
+ ** The era changes at 12:00AM.
+ **
+ ** For example, the current era is Heisei. It started on 1989/1/8 A.D. Therefore, Gregorian year 1989 is also Heisei 1st.
+ ** 1989/1/8 A.D. is also Heisei 1st 1/8.
+ **
+ ** Any date in the year during which era is changed can be reckoned in either era. For example,
+ ** 1989/1/1 can be 1/1 Heisei 1st year or 1/1 Showa 64th year.
+ **
+ ** Note:
+ ** The DateTime can be represented by the JapaneseCalendar are limited to two factors:
+ ** 1. The min value and max value of DateTime class.
+ ** 2. The available era information.
+ **
+ ** Calendar support range:
+ ** Calendar Minimum Maximum
+ ** ========== ========== ==========
+ ** Gregorian 1868/09/08 9999/12/31
+ ** Japanese Meiji 01/01 Heisei 8011/12/31
+ ============================================================================*/
+
+
+ [Serializable]
+ public partial class JapaneseCalendar : Calendar
+ {
+ internal static readonly DateTime calendarMinValue = new DateTime(1868, 9, 8);
+
+
+ public override DateTime MinSupportedDateTime
+ {
+ get
+ {
+ return (calendarMinValue);
+ }
+ }
+
+ public override DateTime MaxSupportedDateTime
+ {
+ get
+ {
+ return (DateTime.MaxValue);
+ }
+ }
+
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.SolarCalendar;
+ }
+ }
+
+ //
+ // Using a field initializer rather than a static constructor so that the whole class can be lazy
+ // init.
+ internal static volatile EraInfo[] japaneseEraInfo;
+
+ //
+ // Read our era info
+ //
+ // m_EraInfo must be listed in reverse chronological order. The most recent era
+ // should be the first element.
+ // That is, m_EraInfo[0] contains the most recent era.
+ //
+ // We know about 4 built-in eras, however users may add additional era(s) from the
+ // registry, by adding values to HKLM\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras
+ // we don't read the registry and instead we call WinRT to get the needed informatio
+ //
+ // Registry values look like:
+ // yyyy.mm.dd=era_abbrev_english_englishabbrev
+ //
+ // Where yyyy.mm.dd is the registry value name, and also the date of the era start.
+ // yyyy, mm, and dd are the year, month & day the era begins (4, 2 & 2 digits long)
+ // era is the Japanese Era name
+ // abbrev is the Abbreviated Japanese Era Name
+ // english is the English name for the Era (unused)
+ // englishabbrev is the Abbreviated English name for the era.
+ // . is a delimiter, but the value of . doesn't matter.
+ // '_' marks the space between the japanese era name, japanese abbreviated era name
+ // english name, and abbreviated english names.
+ //
+ internal static EraInfo[] GetEraInfo()
+ {
+ // See if we need to build it
+ if (japaneseEraInfo == null)
+ {
+ japaneseEraInfo = GetJapaneseEras();
+ // See if we have to use the built-in eras
+ if (japaneseEraInfo == null)
+ {
+ // We know about some built-in ranges
+ EraInfo[] defaultEraRanges = new EraInfo[4];
+ defaultEraRanges[0] = new EraInfo(4, 1989, 1, 8, 1988, 1, GregorianCalendar.MaxYear - 1988,
+ "\x5e73\x6210", "\x5e73", "H"); // era #4 start year/month/day, yearOffset, minEraYear
+ defaultEraRanges[1] = new EraInfo(3, 1926, 12, 25, 1925, 1, 1989 - 1925,
+ "\x662d\x548c", "\x662d", "S"); // era #3,start year/month/day, yearOffset, minEraYear
+ defaultEraRanges[2] = new EraInfo(2, 1912, 7, 30, 1911, 1, 1926 - 1911,
+ "\x5927\x6b63", "\x5927", "T"); // era #2,start year/month/day, yearOffset, minEraYear
+ defaultEraRanges[3] = new EraInfo(1, 1868, 1, 1, 1867, 1, 1912 - 1867,
+ "\x660e\x6cbb", "\x660e", "M"); // era #1,start year/month/day, yearOffset, minEraYear
+
+ // Remember the ranges we built
+ japaneseEraInfo = defaultEraRanges;
+ }
+ }
+
+ // return the era we found/made
+ return japaneseEraInfo;
+ }
+
+ internal static volatile Calendar s_defaultInstance;
+ internal GregorianCalendarHelper helper;
+
+ /*=================================GetDefaultInstance==========================
+ **Action: Internal method to provide a default intance of JapaneseCalendar. Used by NLS+ implementation
+ ** and other calendars.
+ **Returns:
+ **Arguments:
+ **Exceptions:
+ ============================================================================*/
+
+ internal static Calendar GetDefaultInstance()
+ {
+ if (s_defaultInstance == null)
+ {
+ s_defaultInstance = new JapaneseCalendar();
+ }
+ return (s_defaultInstance);
+ }
+
+
+ public JapaneseCalendar()
+ {
+ try
+ {
+ new CultureInfo("ja-JP");
+ }
+ catch (ArgumentException e)
+ {
+ throw new TypeInitializationException(this.GetType().ToString(), e);
+ }
+ helper = new GregorianCalendarHelper(this, GetEraInfo());
+ }
+
+ internal override CalendarId ID
+ {
+ get
+ {
+ return CalendarId.JAPAN;
+ }
+ }
+
+
+ public override DateTime AddMonths(DateTime time, int months)
+ {
+ return (helper.AddMonths(time, months));
+ }
+
+
+ public override DateTime AddYears(DateTime time, int years)
+ {
+ return (helper.AddYears(time, years));
+ }
+
+ /*=================================GetDaysInMonth==========================
+ **Action: Returns the number of days in the month given by the year and month arguments.
+ **Returns: The number of days in the given month.
+ **Arguments:
+ ** year The year in Japanese calendar.
+ ** month The month
+ ** era The Japanese era value.
+ **Exceptions
+ ** ArgumentException If month is less than 1 or greater * than 12.
+ ============================================================================*/
+
+
+ public override int GetDaysInMonth(int year, int month, int era)
+ {
+ return (helper.GetDaysInMonth(year, month, era));
+ }
+
+
+ public override int GetDaysInYear(int year, int era)
+ {
+ return (helper.GetDaysInYear(year, era));
+ }
+
+
+ public override int GetDayOfMonth(DateTime time)
+ {
+ return (helper.GetDayOfMonth(time));
+ }
+
+
+ public override DayOfWeek GetDayOfWeek(DateTime time)
+ {
+ return (helper.GetDayOfWeek(time));
+ }
+
+
+ public override int GetDayOfYear(DateTime time)
+ {
+ return (helper.GetDayOfYear(time));
+ }
+
+
+ public override int GetMonthsInYear(int year, int era)
+ {
+ return (helper.GetMonthsInYear(year, era));
+ }
+
+
+ [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
+ public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
+ {
+ return (helper.GetWeekOfYear(time, rule, firstDayOfWeek));
+ }
+
+ /*=================================GetEra==========================
+ **Action: Get the era value of the specified time.
+ **Returns: The era value for the specified time.
+ **Arguments:
+ ** time the specified date time.
+ **Exceptions: ArgumentOutOfRangeException if time is out of the valid era ranges.
+ ============================================================================*/
+
+
+ public override int GetEra(DateTime time)
+ {
+ return (helper.GetEra(time));
+ }
+
+
+ public override int GetMonth(DateTime time)
+ {
+ return (helper.GetMonth(time));
+ }
+
+
+ public override int GetYear(DateTime time)
+ {
+ return (helper.GetYear(time));
+ }
+
+
+ public override bool IsLeapDay(int year, int month, int day, int era)
+ {
+ return (helper.IsLeapDay(year, month, day, era));
+ }
+
+
+ public override bool IsLeapYear(int year, int era)
+ {
+ return (helper.IsLeapYear(year, era));
+ }
+
+ // Returns the leap month in a calendar year of the specified era. This method returns 0
+ // if this calendar does not have leap month, or this year is not a leap year.
+ //
+
+ public override int GetLeapMonth(int year, int era)
+ {
+ return (helper.GetLeapMonth(year, era));
+ }
+
+
+ public override bool IsLeapMonth(int year, int month, int era)
+ {
+ return (helper.IsLeapMonth(year, month, era));
+ }
+
+
+ public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
+ {
+ return (helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era));
+ }
+
+ // For Japanese calendar, four digit year is not used. Few emperors will live for more than one hundred years.
+ // Therefore, for any two digit number, we just return the original number.
+
+ public override int ToFourDigitYear(int year)
+ {
+ if (year <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(year),
+ SR.ArgumentOutOfRange_NeedPosNum);
+ }
+ Contract.EndContractBlock();
+
+ if (year > helper.MaxYear)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(year),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ 1,
+ helper.MaxYear));
+ }
+ return (year);
+ }
+
+
+ public override int[] Eras
+ {
+ get
+ {
+ return (helper.Eras);
+ }
+ }
+
+ //
+ // Return the various era strings
+ // Note: The arrays are backwards of the eras
+ //
+ internal static String[] EraNames()
+ {
+ EraInfo[] eras = GetEraInfo();
+ String[] eraNames = new String[eras.Length];
+
+ for (int i = 0; i < eras.Length; i++)
+ {
+ // Strings are in chronological order, eras are backwards order.
+ eraNames[i] = eras[eras.Length - i - 1].eraName;
+ }
+
+ return eraNames;
+ }
+
+ internal static String[] AbbrevEraNames()
+ {
+ EraInfo[] eras = GetEraInfo();
+ String[] erasAbbrev = new String[eras.Length];
+
+ for (int i = 0; i < eras.Length; i++)
+ {
+ // Strings are in chronological order, eras are backwards order.
+ erasAbbrev[i] = eras[eras.Length - i - 1].abbrevEraName;
+ }
+
+ return erasAbbrev;
+ }
+
+ internal static String[] EnglishEraNames()
+ {
+ EraInfo[] eras = GetEraInfo();
+ String[] erasEnglish = new String[eras.Length];
+
+ for (int i = 0; i < eras.Length; i++)
+ {
+ // Strings are in chronological order, eras are backwards order.
+ erasEnglish[i] = eras[eras.Length - i - 1].englishEraName;
+ }
+
+ return erasEnglish;
+ }
+
+ private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 99;
+
+ internal override bool IsValidYear(int year, int era)
+ {
+ return helper.IsValidYear(year, era);
+ }
+
+ public override int TwoDigitYearMax
+ {
+ get
+ {
+ if (twoDigitYearMax == -1)
+ {
+ twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
+ }
+ return (twoDigitYearMax);
+ }
+
+ set
+ {
+ VerifyWritable();
+ if (value < 99 || value > helper.MaxYear)
+ {
+ throw new ArgumentOutOfRangeException(
+ "year",
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ 99,
+ helper.MaxYear));
+ }
+ twoDigitYearMax = value;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/JapaneseLunisolarCalendar.cs b/src/mscorlib/shared/System/Globalization/JapaneseLunisolarCalendar.cs
new file mode 100644
index 0000000000..95e87f85d7
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/JapaneseLunisolarCalendar.cs
@@ -0,0 +1,305 @@
+// 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.Diagnostics.Contracts;
+
+namespace System.Globalization
+{
+ /*
+ ** Calendar support range:
+ ** Calendar Minimum Maximum
+ ** ========== ========== ==========
+ ** Gregorian 1960/01/28 2050/01/22
+ ** JapaneseLunisolar 1960/01/01 2049/12/29
+ */
+
+ [Serializable]
+ public class JapaneseLunisolarCalendar : EastAsianLunisolarCalendar
+ {
+ //
+ // The era value for the current era.
+ //
+
+ public const int JapaneseEra = 1;
+
+ internal GregorianCalendarHelper helper;
+
+ internal const int MIN_LUNISOLAR_YEAR = 1960;
+ internal const int MAX_LUNISOLAR_YEAR = 2049;
+
+ internal const int MIN_GREGORIAN_YEAR = 1960;
+ internal const int MIN_GREGORIAN_MONTH = 1;
+ internal const int MIN_GREGORIAN_DAY = 28;
+
+ internal const int MAX_GREGORIAN_YEAR = 2050;
+ internal const int MAX_GREGORIAN_MONTH = 1;
+ internal const int MAX_GREGORIAN_DAY = 22;
+
+ internal static DateTime minDate = new DateTime(MIN_GREGORIAN_YEAR, MIN_GREGORIAN_MONTH, MIN_GREGORIAN_DAY);
+ internal static DateTime maxDate = new DateTime((new DateTime(MAX_GREGORIAN_YEAR, MAX_GREGORIAN_MONTH, MAX_GREGORIAN_DAY, 23, 59, 59, 999)).Ticks + 9999);
+
+ public override DateTime MinSupportedDateTime
+ {
+ get
+ {
+ return (minDate);
+ }
+ }
+
+
+ public override DateTime MaxSupportedDateTime
+ {
+ get
+ {
+ return (maxDate);
+ }
+ }
+ protected override int DaysInYearBeforeMinSupportedYear
+ {
+ get
+ {
+ // 1959 from ChineseLunisolarCalendar
+ return 354;
+ }
+ }
+
+ private static readonly int[,] s_yinfo =
+ {
+ /*Y LM Lmon Lday DaysPerMonth D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 #Days
+ 1960 */
+ { 6 , 1 , 28 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
+1961 */{ 0 , 2 , 15 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
+1962 */{ 0 , 2 , 5 , 19808 },/* 29 30 29 29 30 30 29 30 29 30 30 29 0 354
+1963 */{ 4 , 1 , 25 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
+1964 */{ 0 , 2 , 13 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1965 */{ 0 , 2 , 2 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
+1966 */{ 3 , 1 , 22 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 29 383
+1967 */{ 0 , 2 , 9 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
+1968 */{ 7 , 1 , 30 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
+1969 */{ 0 , 2 , 17 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1970 */{ 0 , 2 , 6 , 39632 },/* 30 29 29 30 30 29 30 29 30 30 29 30 0 355
+1971 */{ 5 , 1 , 27 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+1972 */{ 0 , 2 , 15 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1973 */{ 0 , 2 , 3 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
+1974 */{ 4 , 1 , 23 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
+1975 */{ 0 , 2 , 11 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
+1976 */{ 8 , 1 , 31 , 54600 },/* 30 30 29 30 29 30 29 30 29 30 29 29 30 384
+1977 */{ 0 , 2 , 18 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
+1978 */{ 0 , 2 , 7 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 0 355
+1979 */{ 6 , 1 , 28 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
+1980 */{ 0 , 2 , 16 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1981 */{ 0 , 2 , 5 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+1982 */{ 4 , 1 , 25 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
+1983 */{ 0 , 2 , 13 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1984 */{ 10 , 2 , 2 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
+1985 */{ 0 , 2 , 20 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
+1986 */{ 0 , 2 , 9 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
+1987 */{ 6 , 1 , 29 , 46504 },/* 30 29 30 30 29 30 29 30 30 29 30 29 30 385
+1988 */{ 0 , 2 , 18 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1989 */{ 0 , 2 , 6 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1990 */{ 5 , 1 , 27 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
+1991 */{ 0 , 2 , 15 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1992 */{ 0 , 2 , 4 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
+1993 */{ 3 , 1 , 23 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
+1994 */{ 0 , 2 , 10 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
+1995 */{ 8 , 1 , 31 , 27976 },/* 29 30 30 29 30 30 29 30 29 30 29 29 30 384
+1996 */{ 0 , 2 , 19 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
+1997 */{ 0 , 2 , 8 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1998 */{ 5 , 1 , 28 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
+1999 */{ 0 , 2 , 16 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+2000 */{ 0 , 2 , 5 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
+2001 */{ 4 , 1 , 24 , 58536 },/* 30 30 30 29 29 30 29 29 30 29 30 29 30 384
+2002 */{ 0 , 2 , 12 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+2003 */{ 0 , 2 , 1 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
+2004 */{ 2 , 1 , 22 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
+2005 */{ 0 , 2 , 9 , 22208 },/* 29 30 29 30 29 30 30 29 30 30 29 29 0 354
+2006 */{ 7 , 1 , 29 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
+2007 */{ 0 , 2 , 18 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+2008 */{ 0 , 2 , 7 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
+2009 */{ 5 , 1 , 26 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
+2010 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+2011 */{ 0 , 2 , 3 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
+2012 */{ 3 , 1 , 23 , 47696 },/* 30 29 30 30 30 29 30 29 29 30 29 30 29 384
+2013 */{ 0 , 2 , 10 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+2014 */{ 9 , 1 , 31 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
+2015 */{ 0 , 2 , 19 , 19360 },/* 29 30 29 29 30 29 30 30 30 29 30 29 0 354
+2016 */{ 0 , 2 , 8 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
+2017 */{ 5 , 1 , 28 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
+2018 */{ 0 , 2 , 16 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+2019 */{ 0 , 2 , 5 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+2020 */{ 4 , 1 , 25 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
+2021 */{ 0 , 2 , 12 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+2022 */{ 0 , 2 , 1 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+2023 */{ 2 , 1 , 22 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
+2024 */{ 0 , 2 , 10 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+2025 */{ 6 , 1 , 29 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
+2026 */{ 0 , 2 , 17 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+2027 */{ 0 , 2 , 7 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
+2028 */{ 5 , 1 , 27 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 29 383
+2029 */{ 0 , 2 , 13 , 55600 },/* 30 30 29 30 30 29 29 30 29 29 30 30 0 355
+2030 */{ 0 , 2 , 3 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+2031 */{ 3 , 1 , 23 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
+2032 */{ 0 , 2 , 11 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
+2033 */{ 11 , 1 , 31 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+2034 */{ 0 , 2 , 19 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+2035 */{ 0 , 2 , 8 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+2036 */{ 6 , 1 , 28 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
+2037 */{ 0 , 2 , 15 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
+2038 */{ 0 , 2 , 4 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
+2039 */{ 5 , 1 , 24 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 29 384
+2040 */{ 0 , 2 , 12 , 46752 },/* 30 29 30 30 29 30 30 29 30 29 30 29 0 355
+2041 */{ 0 , 2 , 1 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
+2042 */{ 2 , 1 , 22 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
+2043 */{ 0 , 2 , 10 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+2044 */{ 7 , 1 , 30 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
+2045 */{ 0 , 2 , 17 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+2046 */{ 0 , 2 , 6 , 45648 },/* 30 29 30 30 29 29 30 29 29 30 29 30 0 354
+2047 */{ 5 , 1 , 26 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
+2048 */{ 0 , 2 , 14 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
+2049 */{ 0 , 2 , 2 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
+ */ };
+
+ internal override int MinCalendarYear
+ {
+ get
+ {
+ return (MIN_LUNISOLAR_YEAR);
+ }
+ }
+
+ internal override int MaxCalendarYear
+ {
+ get
+ {
+ return (MAX_LUNISOLAR_YEAR);
+ }
+ }
+
+ internal override DateTime MinDate
+ {
+ get
+ {
+ return (minDate);
+ }
+ }
+
+ internal override DateTime MaxDate
+ {
+ get
+ {
+ return (maxDate);
+ }
+ }
+
+ internal override EraInfo[] CalEraInfo
+ {
+ get
+ {
+ return (JapaneseCalendar.GetEraInfo());
+ }
+ }
+
+ internal override int GetYearInfo(int lunarYear, int index)
+ {
+ if ((lunarYear < MIN_LUNISOLAR_YEAR) || (lunarYear > MAX_LUNISOLAR_YEAR))
+ {
+ throw new ArgumentOutOfRangeException(
+ "year",
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ MIN_LUNISOLAR_YEAR,
+ MAX_LUNISOLAR_YEAR));
+ }
+ Contract.EndContractBlock();
+
+ return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index];
+ }
+
+ internal override int GetYear(int year, DateTime time)
+ {
+ return helper.GetYear(year, time);
+ }
+
+ internal override int GetGregorianYear(int year, int era)
+ {
+ return helper.GetGregorianYear(year, era);
+ }
+
+ // Trim off the eras that are before our date range
+ private static EraInfo[] TrimEras(EraInfo[] baseEras)
+ {
+ EraInfo[] newEras = new EraInfo[baseEras.Length];
+ int newIndex = 0;
+
+ // Eras have most recent first, so start with that
+ for (int i = 0; i < baseEras.Length; i++)
+ {
+ // If this one's minimum year is bigger than our maximum year
+ // then we can't use it.
+ if (baseEras[i].yearOffset + baseEras[i].minEraYear >= MAX_LUNISOLAR_YEAR)
+ {
+ // skip this one.
+ continue;
+ }
+
+ // If this one's maximum era is less than our minimum era
+ // then we've gotten too low in the era #s, so we're done
+ if (baseEras[i].yearOffset + baseEras[i].maxEraYear < MIN_LUNISOLAR_YEAR)
+ {
+ break;
+ }
+
+ // Wasn't too large or too small, can use this one
+ newEras[newIndex] = baseEras[i];
+ newIndex++;
+ }
+
+ // If we didn't copy any then something was wrong, just return base
+ if (newIndex == 0) return baseEras;
+
+ // Resize the output array
+ Array.Resize(ref newEras, newIndex);
+ return newEras;
+ }
+
+
+ // Construct an instance of JapaneseLunisolar calendar.
+ public JapaneseLunisolarCalendar()
+ {
+ helper = new GregorianCalendarHelper(this, TrimEras(JapaneseCalendar.GetEraInfo()));
+ }
+
+
+ public override int GetEra(DateTime time)
+ {
+ return (helper.GetEra(time));
+ }
+
+ internal override CalendarId BaseCalendarID
+ {
+ get
+ {
+ return (CalendarId.JAPAN);
+ }
+ }
+
+ internal override CalendarId ID
+ {
+ get
+ {
+ return (CalendarId.JAPANESELUNISOLAR);
+ }
+ }
+
+
+ public override int[] Eras
+ {
+ get
+ {
+ return (helper.Eras);
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/JulianCalendar.cs b/src/mscorlib/shared/System/Globalization/JulianCalendar.cs
new file mode 100644
index 0000000000..f4678c1a85
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/JulianCalendar.cs
@@ -0,0 +1,443 @@
+// 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.Diagnostics.Contracts;
+
+namespace System.Globalization
+{
+ //
+ // This class implements the Julian calendar. In 48 B.C. Julius Caesar ordered a calendar reform, and this calendar
+ // is called Julian calendar. It consisted of a solar year of twelve months and of 365 days with an extra day
+ // every fourth year.
+ //*
+ //* Calendar support range:
+ //* Calendar Minimum Maximum
+ //* ========== ========== ==========
+ //* Gregorian 0001/01/01 9999/12/31
+ //* Julia 0001/01/03 9999/10/19
+
+ [Serializable]
+ public class JulianCalendar : Calendar
+ {
+ public static readonly int JulianEra = 1;
+
+ private const int DatePartYear = 0;
+ private const int DatePartDayOfYear = 1;
+ private const int DatePartMonth = 2;
+ private const int DatePartDay = 3;
+
+ // Number of days in a non-leap year
+ private const int JulianDaysPerYear = 365;
+ // Number of days in 4 years
+ private const int JulianDaysPer4Years = JulianDaysPerYear * 4 + 1;
+
+ private static readonly int[] s_daysToMonth365 =
+ {
+ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
+ };
+
+ private static readonly int[] s_daysToMonth366 =
+ {
+ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366
+ };
+
+ // Gregorian Calendar 9999/12/31 = Julian Calendar 9999/10/19
+ // keep it as variable field for serialization compat.
+ internal int MaxYear = 9999;
+
+
+ public override DateTime MinSupportedDateTime
+ {
+ get
+ {
+ return (DateTime.MinValue);
+ }
+ }
+
+ public override DateTime MaxSupportedDateTime
+ {
+ get
+ {
+ return (DateTime.MaxValue);
+ }
+ }
+
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.SolarCalendar;
+ }
+ }
+
+ public JulianCalendar()
+ {
+ // There is no system setting of TwoDigitYear max, so set the value here.
+ twoDigitYearMax = 2029;
+ }
+
+ internal override CalendarId ID
+ {
+ get
+ {
+ return CalendarId.JULIAN;
+ }
+ }
+
+ internal static void CheckEraRange(int era)
+ {
+ if (era != CurrentEra && era != JulianEra)
+ {
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
+ }
+ }
+
+ internal void CheckYearEraRange(int year, int era)
+ {
+ CheckEraRange(era);
+ if (year <= 0 || year > MaxYear)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(year),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ 1,
+ MaxYear));
+ }
+ }
+
+ internal static void CheckMonthRange(int month)
+ {
+ if (month < 1 || month > 12)
+ {
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
+ }
+ }
+
+ /*===================================CheckDayRange============================
+ **Action: Check for if the day value is valid.
+ **Returns:
+ **Arguments:
+ **Exceptions:
+ **Notes:
+ ** Before calling this method, call CheckYearEraRange()/CheckMonthRange() to make
+ ** sure year/month values are correct.
+ ============================================================================*/
+
+ internal static void CheckDayRange(int year, int month, int day)
+ {
+ if (year == 1 && month == 1)
+ {
+ // The mimimum supported Julia date is Julian 0001/01/03.
+ if (day < 3)
+ {
+ throw new ArgumentOutOfRangeException(null,
+ SR.ArgumentOutOfRange_BadYearMonthDay);
+ }
+ }
+ bool isLeapYear = (year % 4) == 0;
+ int[] days = isLeapYear ? s_daysToMonth366 : s_daysToMonth365;
+ int monthDays = days[month] - days[month - 1];
+ if (day < 1 || day > monthDays)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(day),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ 1,
+ monthDays));
+ }
+ }
+
+
+ // Returns a given date part of this DateTime. This method is used
+ // to compute the year, day-of-year, month, or day part.
+ internal static int GetDatePart(long ticks, int part)
+ {
+ // Gregorian 1/1/0001 is Julian 1/3/0001. Remember DateTime(0) is refered to Gregorian 1/1/0001.
+ // The following line convert Gregorian ticks to Julian ticks.
+ long julianTicks = ticks + TicksPerDay * 2;
+ // n = number of days since 1/1/0001
+ int n = (int)(julianTicks / TicksPerDay);
+ // y4 = number of whole 4-year periods within 100-year period
+ int y4 = n / JulianDaysPer4Years;
+ // n = day number within 4-year period
+ n -= y4 * JulianDaysPer4Years;
+ // y1 = number of whole years within 4-year period
+ int y1 = n / JulianDaysPerYear;
+ // Last year has an extra day, so decrement result if 4
+ if (y1 == 4) y1 = 3;
+ // If year was requested, compute and return it
+ if (part == DatePartYear)
+ {
+ return (y4 * 4 + y1 + 1);
+ }
+ // n = day number within year
+ n -= y1 * JulianDaysPerYear;
+ // If day-of-year was requested, return it
+ if (part == DatePartDayOfYear)
+ {
+ return (n + 1);
+ }
+ // Leap year calculation looks different from IsLeapYear since y1, y4,
+ // and y100 are relative to year 1, not year 0
+ bool leapYear = (y1 == 3);
+ int[] days = leapYear ? s_daysToMonth366 : s_daysToMonth365;
+ // All months have less than 32 days, so n >> 5 is a good conservative
+ // estimate for the month
+ int m = (n >> 5) + 1;
+ // m = 1-based month number
+ while (n >= days[m]) m++;
+ // If month was requested, return it
+ if (part == DatePartMonth) return (m);
+ // Return 1-based day-of-month
+ return (n - days[m - 1] + 1);
+ }
+
+ // Returns the tick count corresponding to the given year, month, and day.
+ internal static long DateToTicks(int year, int month, int day)
+ {
+ int[] days = (year % 4 == 0) ? s_daysToMonth366 : s_daysToMonth365;
+ int y = year - 1;
+ int n = y * 365 + y / 4 + days[month - 1] + day - 1;
+ // Gregorian 1/1/0001 is Julian 1/3/0001. n * TicksPerDay is the ticks in JulianCalendar.
+ // Therefore, we subtract two days in the following to convert the ticks in JulianCalendar
+ // to ticks in Gregorian calendar.
+ return ((n - 2) * TicksPerDay);
+ }
+
+
+ public override DateTime AddMonths(DateTime time, int months)
+ {
+ if (months < -120000 || months > 120000)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(months),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ -120000,
+ 120000));
+ }
+ Contract.EndContractBlock();
+ int y = GetDatePart(time.Ticks, DatePartYear);
+ int m = GetDatePart(time.Ticks, DatePartMonth);
+ int d = GetDatePart(time.Ticks, DatePartDay);
+ int i = m - 1 + months;
+ if (i >= 0)
+ {
+ m = i % 12 + 1;
+ y = y + i / 12;
+ }
+ else
+ {
+ m = 12 + (i + 1) % 12;
+ y = y + (i - 11) / 12;
+ }
+ int[] daysArray = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? s_daysToMonth366 : s_daysToMonth365;
+ int days = (daysArray[m] - daysArray[m - 1]);
+
+ if (d > days)
+ {
+ d = days;
+ }
+ long ticks = DateToTicks(y, m, d) + time.Ticks % TicksPerDay;
+ Calendar.CheckAddResult(ticks, MinSupportedDateTime, MaxSupportedDateTime);
+ return (new DateTime(ticks));
+ }
+
+
+ public override DateTime AddYears(DateTime time, int years)
+ {
+ return (AddMonths(time, years * 12));
+ }
+
+
+ public override int GetDayOfMonth(DateTime time)
+ {
+ return (GetDatePart(time.Ticks, DatePartDay));
+ }
+
+
+ public override DayOfWeek GetDayOfWeek(DateTime time)
+ {
+ return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
+ }
+
+
+ public override int GetDayOfYear(DateTime time)
+ {
+ return (GetDatePart(time.Ticks, DatePartDayOfYear));
+ }
+
+
+ public override int GetDaysInMonth(int year, int month, int era)
+ {
+ CheckYearEraRange(year, era);
+ CheckMonthRange(month);
+ int[] days = (year % 4 == 0) ? s_daysToMonth366 : s_daysToMonth365;
+ return (days[month] - days[month - 1]);
+ }
+
+
+ public override int GetDaysInYear(int year, int era)
+ {
+ // Year/Era range is done in IsLeapYear().
+ return (IsLeapYear(year, era) ? 366 : 365);
+ }
+
+
+ public override int GetEra(DateTime time)
+ {
+ return (JulianEra);
+ }
+
+
+ public override int GetMonth(DateTime time)
+ {
+ return (GetDatePart(time.Ticks, DatePartMonth));
+ }
+
+
+ public override int[] Eras
+ {
+ get
+ {
+ return (new int[] { JulianEra });
+ }
+ }
+
+
+ public override int GetMonthsInYear(int year, int era)
+ {
+ CheckYearEraRange(year, era);
+ return (12);
+ }
+
+
+ public override int GetYear(DateTime time)
+ {
+ return (GetDatePart(time.Ticks, DatePartYear));
+ }
+
+
+ public override bool IsLeapDay(int year, int month, int day, int era)
+ {
+ CheckMonthRange(month);
+ // Year/Era range check is done in IsLeapYear().
+ if (IsLeapYear(year, era))
+ {
+ CheckDayRange(year, month, day);
+ return (month == 2 && day == 29);
+ }
+ CheckDayRange(year, month, day);
+ return (false);
+ }
+
+ // Returns the leap month in a calendar year of the specified era. This method returns 0
+ // if this calendar does not have leap month, or this year is not a leap year.
+ //
+
+ public override int GetLeapMonth(int year, int era)
+ {
+ CheckYearEraRange(year, era);
+ return (0);
+ }
+
+
+ public override bool IsLeapMonth(int year, int month, int era)
+ {
+ CheckYearEraRange(year, era);
+ CheckMonthRange(month);
+ return (false);
+ }
+
+ // Checks whether a given year in the specified era is a leap year. This method returns true if
+ // year is a leap year, or false if not.
+ //
+
+ public override bool IsLeapYear(int year, int era)
+ {
+ CheckYearEraRange(year, era);
+ return (year % 4 == 0);
+ }
+
+
+ public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
+ {
+ CheckYearEraRange(year, era);
+ CheckMonthRange(month);
+ CheckDayRange(year, month, day);
+ if (millisecond < 0 || millisecond >= MillisPerSecond)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(millisecond),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ 0,
+ MillisPerSecond - 1));
+ }
+
+ if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >= 0 && second < 60)
+ {
+ return new DateTime(DateToTicks(year, month, day) + (new TimeSpan(0, hour, minute, second, millisecond)).Ticks);
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
+ }
+ }
+
+
+ public override int TwoDigitYearMax
+ {
+ get
+ {
+ return (twoDigitYearMax);
+ }
+
+ set
+ {
+ VerifyWritable();
+ if (value < 99 || value > MaxYear)
+ {
+ throw new ArgumentOutOfRangeException(
+ "year",
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ 99,
+ MaxYear));
+ }
+ twoDigitYearMax = value;
+ }
+ }
+
+
+ public override int ToFourDigitYear(int year)
+ {
+ if (year < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(year),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ }
+ Contract.EndContractBlock();
+
+ if (year > MaxYear)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(year),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Bounds_Lower_Upper,
+ 1,
+ MaxYear));
+ }
+ return (base.ToFourDigitYear(year));
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/KoreanCalendar.cs b/src/mscorlib/shared/System/Globalization/KoreanCalendar.cs
new file mode 100644
index 0000000000..b962b1c427
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/KoreanCalendar.cs
@@ -0,0 +1,266 @@
+// 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.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+
+namespace System.Globalization
+{
+ /*=================================KoreanCalendar==========================
+ **
+ ** Korean calendar is based on the Gregorian calendar. And the year is an offset to Gregorian calendar.
+ ** That is,
+ ** Korean year = Gregorian year + 2333. So 2000/01/01 A.D. is Korean 4333/01/01
+ **
+ ** 0001/1/1 A.D. is Korean year 2334.
+ **
+ ** Calendar support range:
+ ** Calendar Minimum Maximum
+ ** ========== ========== ==========
+ ** Gregorian 0001/01/01 9999/12/31
+ ** Korean 2334/01/01 12332/12/31
+ ============================================================================*/
+
+
+ [Serializable]
+ public class KoreanCalendar : Calendar
+ {
+ //
+ // The era value for the current era.
+ //
+
+ public const int KoreanEra = 1;
+
+ // Since
+ // Gregorian Year = Era Year + yearOffset
+ // Gregorian Year 1 is Korean year 2334, so that
+ // 1 = 2334 + yearOffset
+ // So yearOffset = -2333
+ // Gregorian year 2001 is Korean year 4334.
+
+ //m_EraInfo[0] = new EraInfo(1, new DateTime(1, 1, 1).Ticks, -2333, 2334, GregorianCalendar.MaxYear + 2333);
+
+ // Initialize our era info.
+ internal static EraInfo[] koreanEraInfo = new EraInfo[] {
+ new EraInfo( 1, 1, 1, 1, -2333, 2334, GregorianCalendar.MaxYear + 2333) // era #, start year/month/day, yearOffset, minEraYear
+ };
+
+ internal GregorianCalendarHelper helper;
+
+
+ public override DateTime MinSupportedDateTime
+ {
+ get
+ {
+ return (DateTime.MinValue);
+ }
+ }
+
+ public override DateTime MaxSupportedDateTime
+ {
+ get
+ {
+ return (DateTime.MaxValue);
+ }
+ }
+
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.SolarCalendar;
+ }
+ }
+
+ public KoreanCalendar()
+ {
+ try
+ {
+ new CultureInfo("ko-KR");
+ }
+ catch (ArgumentException e)
+ {
+ throw new TypeInitializationException(this.GetType().ToString(), e);
+ }
+ helper = new GregorianCalendarHelper(this, koreanEraInfo);
+ }
+
+ internal override CalendarId ID
+ {
+ get
+ {
+ return CalendarId.KOREA;
+ }
+ }
+
+
+ public override DateTime AddMonths(DateTime time, int months)
+ {
+ return (helper.AddMonths(time, months));
+ }
+
+
+ public override DateTime AddYears(DateTime time, int years)
+ {
+ return (helper.AddYears(time, years));
+ }
+
+ /*=================================GetDaysInMonth==========================
+ **Action: Returns the number of days in the month given by the year and month arguments.
+ **Returns: The number of days in the given month.
+ **Arguments:
+ ** year The year in Korean calendar.
+ ** month The month
+ ** era The Japanese era value.
+ **Exceptions
+ ** ArgumentException If month is less than 1 or greater * than 12.
+ ============================================================================*/
+
+
+ public override int GetDaysInMonth(int year, int month, int era)
+ {
+ return (helper.GetDaysInMonth(year, month, era));
+ }
+
+
+ public override int GetDaysInYear(int year, int era)
+ {
+ return (helper.GetDaysInYear(year, era));
+ }
+
+
+ public override int GetDayOfMonth(DateTime time)
+ {
+ return (helper.GetDayOfMonth(time));
+ }
+
+
+ public override DayOfWeek GetDayOfWeek(DateTime time)
+ {
+ return (helper.GetDayOfWeek(time));
+ }
+
+
+ public override int GetDayOfYear(DateTime time)
+ {
+ return (helper.GetDayOfYear(time));
+ }
+
+
+ public override int GetMonthsInYear(int year, int era)
+ {
+ return (helper.GetMonthsInYear(year, era));
+ }
+
+
+ [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
+ public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
+ {
+ return (helper.GetWeekOfYear(time, rule, firstDayOfWeek));
+ }
+
+
+ public override int GetEra(DateTime time)
+ {
+ return (helper.GetEra(time));
+ }
+
+ public override int GetMonth(DateTime time)
+ {
+ return (helper.GetMonth(time));
+ }
+
+
+ public override int GetYear(DateTime time)
+ {
+ return (helper.GetYear(time));
+ }
+
+
+ public override bool IsLeapDay(int year, int month, int day, int era)
+ {
+ return (helper.IsLeapDay(year, month, day, era));
+ }
+
+
+ public override bool IsLeapYear(int year, int era)
+ {
+ return (helper.IsLeapYear(year, era));
+ }
+
+ // Returns the leap month in a calendar year of the specified era. This method returns 0
+ // if this calendar does not have leap month, or this year is not a leap year.
+ //
+
+ public override int GetLeapMonth(int year, int era)
+ {
+ return (helper.GetLeapMonth(year, era));
+ }
+
+
+ public override bool IsLeapMonth(int year, int month, int era)
+ {
+ return (helper.IsLeapMonth(year, month, era));
+ }
+
+
+ public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
+ {
+ return (helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era));
+ }
+
+
+ public override int[] Eras
+ {
+ get
+ {
+ return (helper.Eras);
+ }
+ }
+
+ private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 4362;
+
+
+ public override int TwoDigitYearMax
+ {
+ get
+ {
+ if (twoDigitYearMax == -1)
+ {
+ twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
+ }
+ return (twoDigitYearMax);
+ }
+
+ set
+ {
+ VerifyWritable();
+ if (value < 99 || value > helper.MaxYear)
+ {
+ throw new ArgumentOutOfRangeException(
+ "year",
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ 99,
+ helper.MaxYear));
+ }
+ twoDigitYearMax = value;
+ }
+ }
+
+
+ public override int ToFourDigitYear(int year)
+ {
+ if (year < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(year),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ }
+ Contract.EndContractBlock();
+
+ return (helper.ToFourDigitYear(year, this.TwoDigitYearMax));
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/KoreanLunisolarCalendar.cs b/src/mscorlib/shared/System/Globalization/KoreanLunisolarCalendar.cs
new file mode 100644
index 0000000000..d4c71632aa
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/KoreanLunisolarCalendar.cs
@@ -0,0 +1,1323 @@
+// 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.Diagnostics.Contracts;
+
+namespace System.Globalization
+{
+ /*
+ ** Calendar support range:
+ ** Calendar Minimum Maximum
+ ** ========== ========== ==========
+ ** Gregorian 918/02/14 2051/02/10
+ ** KoreanLunisolar 918/01/01 2050/13/29
+ */
+
+ [Serializable]
+ public class KoreanLunisolarCalendar : EastAsianLunisolarCalendar
+ {
+ //
+ // The era value for the current era.
+ //
+
+ public const int GregorianEra = 1;
+
+ internal const int MIN_LUNISOLAR_YEAR = 918;
+ internal const int MAX_LUNISOLAR_YEAR = 2050;
+
+ internal const int MIN_GREGORIAN_YEAR = 918;
+ internal const int MIN_GREGORIAN_MONTH = 2;
+ internal const int MIN_GREGORIAN_DAY = 14;
+
+ internal const int MAX_GREGORIAN_YEAR = 2051;
+ internal const int MAX_GREGORIAN_MONTH = 2;
+ internal const int MAX_GREGORIAN_DAY = 10;
+
+ internal static DateTime minDate = new DateTime(MIN_GREGORIAN_YEAR, MIN_GREGORIAN_MONTH, MIN_GREGORIAN_DAY);
+ internal static DateTime maxDate = new DateTime((new DateTime(MAX_GREGORIAN_YEAR, MAX_GREGORIAN_MONTH, MAX_GREGORIAN_DAY, 23, 59, 59, 999)).Ticks + 9999);
+
+ public override DateTime MinSupportedDateTime
+ {
+ get
+ {
+ return (minDate);
+ }
+ }
+
+
+
+ public override DateTime MaxSupportedDateTime
+ {
+ get
+ {
+ return (maxDate);
+ }
+ }
+
+ protected override int DaysInYearBeforeMinSupportedYear
+ {
+ get
+ {
+ // 917 -- From http://emr.cs.iit.edu/home/reingold/calendar-book/Calendrica.html
+ // using ChineseLunisolar
+ return 384;
+ }
+ }
+
+ private static readonly int[,] s_yinfo =
+ {
+ /*Y LM Lmon Lday DaysPerMonth D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 #Days
+ 918 */
+ { 0 , 2 , 14 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
+919 */{ 0 , 2 , 4 , 17872 },/* 29 30 29 29 29 30 29 30 30 30 29 30 0 354
+920 */{ 6 , 1 , 24 , 41688 },/* 30 29 30 29 29 29 30 29 30 30 29 30 30 384
+921 */{ 0 , 2 , 11 , 41648 },/* 30 29 30 29 29 29 30 29 30 29 30 30 0 354
+922 */{ 0 , 1 , 31 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+923 */{ 4 , 1 , 20 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
+924 */{ 0 , 2 , 8 , 27936 },/* 29 30 30 29 30 30 29 30 29 29 30 29 0 354
+925 */{ 12 , 1 , 27 , 44384 },/* 30 29 30 29 30 30 29 30 29 30 30 29 29 384
+926 */{ 0 , 2 , 15 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
+927 */{ 0 , 2 , 5 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
+928 */{ 8 , 1 , 26 , 17848 },/* 29 30 29 29 29 30 29 30 30 29 30 30 30 384
+929 */{ 0 , 2 , 13 , 17776 },/* 29 30 29 29 29 30 29 30 29 30 30 30 0 354
+930 */{ 0 , 2 , 2 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+931 */{ 5 , 1 , 22 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 29 383
+932 */{ 0 , 2 , 9 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
+933 */{ 0 , 1 , 29 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+934 */{ 1 , 1 , 18 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
+935 */{ 0 , 2 , 6 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
+936 */{ 11 , 1 , 27 , 21344 },/* 29 30 29 30 29 29 30 30 29 30 30 29 29 383
+937 */{ 0 , 2 , 13 , 51904 },/* 30 30 29 29 30 29 30 29 30 30 29 29 0 354
+938 */{ 0 , 2 , 2 , 58720 },/* 30 30 30 29 29 30 29 30 29 30 30 29 0 355
+939 */{ 7 , 1 , 23 , 53928 },/* 30 30 29 30 29 29 30 29 30 29 30 29 30 384
+940 */{ 0 , 2 , 11 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
+941 */{ 0 , 1 , 30 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
+942 */{ 3 , 1 , 20 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
+943 */{ 0 , 2 , 8 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+944 */{ 12 , 1 , 28 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 29 384
+945 */{ 0 , 2 , 15 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
+946 */{ 0 , 2 , 5 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
+947 */{ 7 , 1 , 25 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
+948 */{ 0 , 2 , 13 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+949 */{ 0 , 2 , 1 , 45664 },/* 30 29 30 30 29 29 30 29 29 30 30 29 0 354
+950 */{ 5 , 1 , 21 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
+951 */{ 0 , 2 , 9 , 45936 },/* 30 29 30 30 29 30 29 30 29 30 29 0 0 325
+952 */{ 0 , 12 , 31 , 43728 },/* 30 29 30 29 30 29 30 29 30 30 29 30 29 384
+953 */{ 1 , 1 , 18 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 29 384
+954 */{ 0 , 2 , 6 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+955 */{ 9 , 1 , 27 , 19128 },/* 29 30 29 29 30 29 30 29 30 29 30 30 30 384
+956 */{ 0 , 2 , 15 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+957 */{ 0 , 2 , 3 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+958 */{ 7 , 1 , 23 , 43672 },/* 30 29 30 29 30 29 30 29 30 29 29 30 30 384
+959 */{ 0 , 2 , 11 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+960 */{ 0 , 1 , 31 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+961 */{ 3 , 1 , 20 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
+962 */{ 0 , 2 , 8 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+963 */{ 12 , 1 , 28 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 29 384
+964 */{ 0 , 2 , 16 , 41840 },/* 30 29 30 29 29 29 30 30 29 30 30 30 0 355
+965 */{ 0 , 2 , 5 , 20848 },/* 29 30 29 30 29 29 29 30 29 30 30 30 0 354
+966 */{ 8 , 1 , 25 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
+967 */{ 0 , 2 , 12 , 54448 },/* 30 30 29 30 29 30 29 29 30 29 30 30 0 355
+968 */{ 0 , 2 , 2 , 23184 },/* 29 30 29 30 30 29 30 29 30 29 29 30 0 354
+969 */{ 5 , 1 , 21 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
+970 */{ 0 , 2 , 9 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
+971 */{ 0 , 1 , 30 , 10976 },/* 29 29 30 29 30 29 30 29 30 30 30 29 0 354
+972 */{ 2 , 1 , 19 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
+973 */{ 0 , 2 , 6 , 41696 },/* 30 29 30 29 29 29 30 29 30 30 30 29 0 354
+974 */{ 10 , 1 , 26 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
+975 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+976 */{ 0 , 2 , 3 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+977 */{ 7 , 1 , 22 , 55952 },/* 30 30 29 30 30 29 30 29 30 29 29 30 29 384
+978 */{ 0 , 2 , 10 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
+979 */{ 0 , 1 , 31 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
+980 */{ 3 , 1 , 21 , 10968 },/* 29 29 30 29 30 29 30 29 30 30 29 30 30 384
+981 */{ 0 , 2 , 8 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+982 */{ 12 , 1 , 28 , 37592 },/* 30 29 29 30 29 29 30 29 30 30 29 30 30 384
+983 */{ 0 , 2 , 16 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
+984 */{ 0 , 2 , 5 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+985 */{ 9 , 1 , 24 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
+986 */{ 0 , 2 , 12 , 44192 },/* 30 29 30 29 30 30 29 29 30 29 30 29 0 354
+987 */{ 0 , 2 , 1 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+988 */{ 5 , 1 , 22 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
+989 */{ 0 , 2 , 9 , 19376 },/* 29 30 29 29 30 29 30 30 30 29 30 30 0 355
+990 */{ 0 , 1 , 30 , 9648 },/* 29 29 30 29 29 30 29 30 30 29 30 30 0 354
+991 */{ 2 , 1 , 19 , 37560 },/* 30 29 29 30 29 29 30 29 30 29 30 30 30 384
+992 */{ 0 , 2 , 7 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+993 */{ 10 , 1 , 26 , 26968 },/* 29 30 30 29 30 29 29 30 29 30 29 30 30 384
+994 */{ 0 , 2 , 14 , 22864 },/* 29 30 29 30 30 29 29 30 29 30 29 30 0 354
+995 */{ 0 , 2 , 3 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+996 */{ 7 , 1 , 23 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
+997 */{ 0 , 2 , 10 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
+998 */{ 0 , 1 , 31 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+999 */{ 3 , 1 , 20 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
+1000 */{ 0 , 2 , 8 , 9584 },/* 29 29 30 29 29 30 29 30 29 30 30 30 0 354
+1001 */{ 12 , 1 , 28 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 29 383
+1002 */{ 0 , 2 , 15 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
+1003 */{ 0 , 2 , 4 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
+1004 */{ 9 , 1 , 25 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
+1005 */{ 0 , 2 , 12 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1006 */{ 0 , 2 , 1 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
+1007 */{ 5 , 1 , 22 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+1008 */{ 0 , 2 , 10 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
+1009 */{ 0 , 1 , 29 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1010 */{ 2 , 1 , 18 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
+1011 */{ 0 , 2 , 6 , 45664 },/* 30 29 30 30 29 29 30 29 29 30 30 29 0 354
+1012 */{ 10 , 1 , 26 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
+1013 */{ 0 , 2 , 13 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+1014 */{ 0 , 2 , 3 , 13728 },/* 29 29 30 30 29 30 29 30 30 29 30 29 0 354
+1015 */{ 6 , 1 , 23 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 29 384
+1016 */{ 0 , 2 , 11 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1017 */{ 0 , 1 , 31 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+1018 */{ 4 , 1 , 20 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
+1019 */{ 0 , 2 , 8 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1020 */{ 12 , 1 , 28 , 43608 },/* 30 29 30 29 30 29 30 29 29 30 29 30 30 384
+1021 */{ 0 , 2 , 15 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+1022 */{ 0 , 2 , 4 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+1023 */{ 9 , 1 , 25 , 11688 },/* 29 29 30 29 30 30 29 30 30 29 30 29 30 384
+1024 */{ 0 , 2 , 13 , 11088 },/* 29 29 30 29 30 29 30 30 29 30 29 30 0 354
+1025 */{ 0 , 2 , 1 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 0 355
+1026 */{ 5 , 1 , 22 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 29 383
+1027 */{ 0 , 2 , 9 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 0 355
+1028 */{ 0 , 1 , 30 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
+1029 */{ 2 , 1 , 18 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
+1030 */{ 0 , 2 , 5 , 55952 },/* 30 30 29 30 30 29 30 29 30 29 29 30 0 355
+1031 */{ 10 , 1 , 26 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
+1032 */{ 0 , 2 , 14 , 26320 },/* 29 30 30 29 29 30 30 29 30 30 29 30 0 355
+1033 */{ 0 , 2 , 3 , 9952 },/* 29 29 30 29 29 30 30 29 30 30 30 29 0 354
+1034 */{ 6 , 1 , 23 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
+1035 */{ 0 , 2 , 11 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+1036 */{ 0 , 1 , 31 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
+1037 */{ 4 , 1 , 19 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+1038 */{ 0 , 2 , 7 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1039 */{ 12 , 1 , 27 , 54928 },/* 30 30 29 30 29 30 30 29 30 29 29 30 29 384
+1040 */{ 0 , 2 , 15 , 46464 },/* 30 29 30 30 29 30 29 30 30 29 29 29 0 354
+1041 */{ 0 , 2 , 3 , 54960 },/* 30 30 29 30 29 30 30 29 30 29 30 30 0 356
+1042 */{ 9 , 1 , 25 , 9944 },/* 29 29 30 29 29 30 30 29 30 30 29 30 30 384
+1043 */{ 0 , 2 , 13 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+1044 */{ 0 , 2 , 2 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
+1045 */{ 5 , 1 , 21 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
+1046 */{ 0 , 2 , 9 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1047 */{ 0 , 1 , 29 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
+1048 */{ 1 , 1 , 18 , 46424 },/* 30 29 30 30 29 30 29 30 29 30 29 30 30 385
+1049 */{ 0 , 2 , 6 , 11600 },/* 29 29 30 29 30 30 29 30 29 30 29 30 0 354
+1050 */{ 11 , 1 , 26 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
+1051 */{ 0 , 2 , 14 , 19376 },/* 29 30 29 29 30 29 30 30 30 29 30 30 0 355
+1052 */{ 0 , 2 , 4 , 9648 },/* 29 29 30 29 29 30 29 30 30 29 30 30 0 354
+1053 */{ 7 , 1 , 23 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
+1054 */{ 0 , 2 , 11 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1055 */{ 0 , 1 , 31 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
+1056 */{ 3 , 1 , 20 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
+1057 */{ 0 , 2 , 7 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+1058 */{ 12 , 1 , 27 , 43864 },/* 30 29 30 29 30 29 30 30 29 30 29 30 30 385
+1059 */{ 0 , 2 , 16 , 10064 },/* 29 29 30 29 29 30 30 30 29 30 29 30 0 354
+1060 */{ 0 , 2 , 5 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+1061 */{ 8 , 1 , 24 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
+1062 */{ 0 , 2 , 12 , 42336 },/* 30 29 30 29 29 30 29 30 29 30 30 29 0 354
+1063 */{ 0 , 2 , 1 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
+1064 */{ 5 , 1 , 21 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
+1065 */{ 0 , 2 , 8 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
+1066 */{ 0 , 1 , 29 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+1067 */{ 1 , 1 , 18 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
+1068 */{ 0 , 2 , 6 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
+1069 */{ 11 , 1 , 26 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+1070 */{ 0 , 2 , 14 , 18896 },/* 29 30 29 29 30 29 29 30 30 30 29 30 0 354
+1071 */{ 0 , 2 , 3 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1072 */{ 7 , 1 , 23 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
+1073 */{ 0 , 2 , 10 , 43616 },/* 30 29 30 29 30 29 30 29 29 30 30 29 0 354
+1074 */{ 0 , 1 , 30 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1075 */{ 4 , 1 , 20 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
+1076 */{ 0 , 2 , 8 , 13728 },/* 29 29 30 30 29 30 29 30 30 29 30 29 0 354
+1077 */{ 0 , 1 , 27 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
+1078 */{ 1 , 1 , 17 , 19352 },/* 29 30 29 29 30 29 30 30 30 29 29 30 30 384
+1079 */{ 0 , 2 , 5 , 17840 },/* 29 30 29 29 29 30 29 30 30 29 30 30 0 354
+1080 */{ 9 , 1 , 25 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
+1081 */{ 0 , 2 , 12 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
+1082 */{ 0 , 2 , 1 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
+1083 */{ 6 , 1 , 21 , 46408 },/* 30 29 30 30 29 30 29 30 29 30 29 29 30 384
+1084 */{ 0 , 2 , 9 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 0 355
+1085 */{ 0 , 1 , 29 , 11680 },/* 29 29 30 29 30 30 29 30 30 29 30 29 0 354
+1086 */{ 2 , 1 , 18 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 29 384
+1087 */{ 0 , 2 , 6 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
+1088 */{ 12 , 1 , 27 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 29 383
+1089 */{ 0 , 2 , 13 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 0 355
+1090 */{ 0 , 2 , 3 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
+1091 */{ 8 , 1 , 23 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
+1092 */{ 0 , 2 , 10 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
+1093 */{ 0 , 1 , 30 , 23360 },/* 29 30 29 30 30 29 30 30 29 30 29 29 0 354
+1094 */{ 4 , 1 , 19 , 43880 },/* 30 29 30 29 30 29 30 30 29 30 30 29 30 385
+1095 */{ 0 , 2 , 8 , 10976 },/* 29 29 30 29 30 29 30 29 30 30 30 29 0 354
+1096 */{ 0 , 1 , 28 , 58896 },/* 30 30 30 29 29 30 30 29 29 29 29 30 0 354
+1097 */{ 2 , 1 , 16 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 29 384
+1098 */{ 0 , 2 , 4 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
+1099 */{ 9 , 1 , 24 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+1100 */{ 0 , 2 , 12 , 21664 },/* 29 30 29 30 29 30 29 29 30 29 30 29 0 353
+1101 */{ 0 , 1 , 31 , 54864 },/* 30 30 29 30 29 30 30 29 29 30 29 30 0 355
+1102 */{ 6 , 1 , 21 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
+1103 */{ 0 , 2 , 9 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
+1104 */{ 0 , 1 , 30 , 9936 },/* 29 29 30 29 29 30 30 29 30 30 29 30 0 354
+1105 */{ 2 , 1 , 18 , 37608 },/* 30 29 29 30 29 29 30 29 30 30 30 29 30 384
+1106 */{ 0 , 2 , 6 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
+1107 */{ 10 , 1 , 26 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
+1108 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1109 */{ 0 , 2 , 2 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
+1110 */{ 8 , 1 , 22 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
+1111 */{ 0 , 2 , 10 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+1112 */{ 0 , 1 , 31 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
+1113 */{ 4 , 1 , 20 , 9656 },/* 29 29 30 29 29 30 29 30 30 29 30 30 30 384
+1114 */{ 0 , 2 , 8 , 17776 },/* 29 30 29 29 29 30 29 30 29 30 30 30 0 354
+1115 */{ 0 , 1 , 28 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1116 */{ 1 , 1 , 17 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
+1117 */{ 0 , 2 , 4 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
+1118 */{ 9 , 1 , 24 , 29352 },/* 29 30 30 30 29 29 30 29 30 29 30 29 30 384
+1119 */{ 0 , 2 , 12 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+1120 */{ 0 , 2 , 1 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
+1121 */{ 5 , 1 , 21 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
+1122 */{ 0 , 2 , 9 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+1123 */{ 0 , 1 , 29 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1124 */{ 3 , 1 , 19 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 29 383
+1125 */{ 0 , 2 , 5 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
+1126 */{ 11 , 1 , 25 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
+1127 */{ 0 , 2 , 13 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
+1128 */{ 0 , 2 , 3 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+1129 */{ 8 , 1 , 22 , 39824 },/* 30 29 29 30 30 29 30 30 30 29 29 30 29 384
+1130 */{ 0 , 2 , 10 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
+1131 */{ 0 , 1 , 31 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1132 */{ 4 , 1 , 20 , 42216 },/* 30 29 30 29 29 30 29 29 30 30 30 29 30 384
+1133 */{ 0 , 2 , 7 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1134 */{ 0 , 1 , 27 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
+1135 */{ 2 , 1 , 16 , 55592 },/* 30 30 29 30 30 29 29 30 29 29 30 29 30 384
+1136 */{ 0 , 2 , 4 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
+1137 */{ 10 , 1 , 23 , 54952 },/* 30 30 29 30 29 30 30 29 30 29 30 29 30 385
+1138 */{ 0 , 2 , 12 , 11680 },/* 29 29 30 29 30 30 29 30 30 29 30 29 0 354
+1139 */{ 0 , 2 , 1 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
+1140 */{ 6 , 1 , 22 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
+1141 */{ 0 , 2 , 9 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+1142 */{ 0 , 1 , 29 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1143 */{ 4 , 1 , 18 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
+1144 */{ 0 , 2 , 6 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
+1145 */{ 11 , 1 , 25 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
+1146 */{ 0 , 2 , 13 , 27456 },/* 29 30 30 29 30 29 30 30 29 30 29 29 0 354
+1147 */{ 0 , 2 , 2 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
+1148 */{ 8 , 1 , 23 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 29 384
+1149 */{ 0 , 2 , 10 , 39280 },/* 30 29 29 30 30 29 29 30 29 30 30 30 0 355
+1150 */{ 0 , 1 , 31 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1151 */{ 4 , 1 , 20 , 25784 },/* 29 30 30 29 29 30 29 29 30 29 30 30 30 384
+1152 */{ 0 , 2 , 8 , 21680 },/* 29 30 29 30 29 30 29 29 30 29 30 30 0 354
+1153 */{ 12 , 1 , 27 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
+1154 */{ 0 , 2 , 14 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
+1155 */{ 0 , 2 , 4 , 23232 },/* 29 30 29 30 30 29 30 29 30 30 29 29 0 354
+1156 */{ 10 , 1 , 24 , 43880 },/* 30 29 30 29 30 29 30 30 29 30 30 29 30 385
+1157 */{ 0 , 2 , 12 , 9952 },/* 29 29 30 29 29 30 30 29 30 30 30 29 0 354
+1158 */{ 0 , 2 , 1 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+1159 */{ 6 , 1 , 21 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 29 384
+1160 */{ 0 , 2 , 9 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
+1161 */{ 0 , 1 , 28 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1162 */{ 2 , 1 , 17 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
+1163 */{ 0 , 2 , 5 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
+1164 */{ 11 , 1 , 26 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
+1165 */{ 0 , 2 , 13 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
+1166 */{ 0 , 2 , 3 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+1167 */{ 7 , 1 , 23 , 37608 },/* 30 29 29 30 29 29 30 29 30 30 30 29 30 384
+1168 */{ 0 , 2 , 11 , 37488 },/* 30 29 29 30 29 29 30 29 29 30 30 30 0 354
+1169 */{ 0 , 1 , 30 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1170 */{ 5 , 1 , 19 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+1171 */{ 0 , 2 , 7 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
+1172 */{ 0 , 1 , 27 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1173 */{ 1 , 1 , 16 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
+1174 */{ 0 , 2 , 4 , 19888 },/* 29 30 29 29 30 30 29 30 30 29 30 30 0 355
+1175 */{ 9 , 1 , 25 , 9648 },/* 29 29 30 29 29 30 29 30 30 29 30 30 29 383
+1176 */{ 0 , 2 , 12 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1177 */{ 0 , 2 , 1 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1178 */{ 6 , 1 , 21 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
+1179 */{ 0 , 2 , 9 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
+1180 */{ 0 , 1 , 29 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+1181 */{ 3 , 1 , 17 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
+1182 */{ 0 , 2 , 5 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
+1183 */{ 11 , 1 , 26 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
+1184 */{ 0 , 2 , 14 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1185 */{ 0 , 2 , 2 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1186 */{ 7 , 1 , 23 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 29 383
+1187 */{ 0 , 2 , 10 , 53392 },/* 30 30 29 30 29 29 30 29 29 30 30 0 0 325
+1188 */{ 0 , 1 , 1 , 29848 },/* 29 30 30 30 29 30 29 29 30 29 29 30 30 384
+1189 */{ 5 , 1 , 19 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
+1190 */{ 0 , 2 , 7 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+1191 */{ 0 , 1 , 27 , 39760 },/* 30 29 29 30 30 29 30 30 29 30 29 30 0 355
+1192 */{ 2 , 1 , 17 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
+1193 */{ 0 , 2 , 4 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1194 */{ 10 , 1 , 24 , 42216 },/* 30 29 30 29 29 30 29 29 30 30 30 29 30 384
+1195 */{ 0 , 2 , 12 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1196 */{ 0 , 2 , 1 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
+1197 */{ 6 , 1 , 20 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
+1198 */{ 0 , 2 , 8 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
+1199 */{ 0 , 1 , 28 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 0 355
+1200 */{ 2 , 1 , 18 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
+1201 */{ 0 , 2 , 5 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
+1202 */{ 12 , 1 , 26 , 18904 },/* 29 30 29 29 30 29 29 30 30 30 29 30 30 384
+1203 */{ 0 , 2 , 14 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+1204 */{ 0 , 2 , 3 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1205 */{ 8 , 1 , 22 , 43608 },/* 30 29 30 29 30 29 30 29 29 30 29 30 30 384
+1206 */{ 0 , 2 , 10 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
+1207 */{ 0 , 1 , 30 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
+1208 */{ 4 , 1 , 19 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 29 384
+1209 */{ 0 , 2 , 6 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
+1210 */{ 0 , 1 , 27 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1211 */{ 2 , 1 , 17 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
+1212 */{ 0 , 2 , 5 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1213 */{ 9 , 1 , 24 , 25784 },/* 29 30 30 29 29 30 29 29 30 29 30 30 30 384
+1214 */{ 0 , 2 , 12 , 21680 },/* 29 30 29 30 29 30 29 29 30 29 30 30 0 354
+1215 */{ 0 , 2 , 1 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
+1216 */{ 7 , 1 , 21 , 27944 },/* 29 30 30 29 30 30 29 30 29 29 30 29 30 384
+1217 */{ 0 , 2 , 8 , 23232 },/* 29 30 29 30 30 29 30 29 30 30 29 29 0 354
+1218 */{ 0 , 1 , 28 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
+1219 */{ 3 , 1 , 18 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
+1220 */{ 0 , 2 , 6 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+1221 */{ 12 , 1 , 25 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 29 384
+1222 */{ 0 , 2 , 13 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
+1223 */{ 0 , 2 , 2 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1224 */{ 8 , 1 , 22 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
+1225 */{ 0 , 2 , 9 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1226 */{ 0 , 1 , 30 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1227 */{ 5 , 1 , 19 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
+1228 */{ 0 , 2 , 8 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+1229 */{ 0 , 1 , 27 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+1230 */{ 2 , 1 , 16 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
+1231 */{ 0 , 2 , 4 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1232 */{ 9 , 1 , 24 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+1233 */{ 0 , 2 , 11 , 45728 },/* 30 29 30 30 29 29 30 29 30 29 30 29 0 354
+1234 */{ 0 , 1 , 31 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1235 */{ 7 , 1 , 21 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
+1236 */{ 0 , 2 , 9 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
+1237 */{ 0 , 1 , 28 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
+1238 */{ 4 , 1 , 18 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
+1239 */{ 0 , 2 , 6 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1240 */{ 12 , 1 , 26 , 43320 },/* 30 29 30 29 30 29 29 30 29 29 30 30 30 384
+1241 */{ 0 , 2 , 13 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 0 354
+1242 */{ 0 , 2 , 2 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+1243 */{ 8 , 1 , 22 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
+1244 */{ 0 , 2 , 10 , 44624 },/* 30 29 30 29 30 30 30 29 29 30 29 30 0 355
+1245 */{ 0 , 1 , 30 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+1246 */{ 4 , 1 , 19 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
+1247 */{ 0 , 2 , 7 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1248 */{ 0 , 1 , 28 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
+1249 */{ 2 , 1 , 16 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 29 383
+1250 */{ 0 , 2 , 3 , 58672 },/* 30 30 30 29 29 30 29 30 29 29 30 30 0 355
+1251 */{ 10 , 1 , 24 , 27800 },/* 29 30 30 29 30 30 29 29 30 29 29 30 30 384
+1252 */{ 0 , 2 , 12 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+1253 */{ 0 , 1 , 31 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
+1254 */{ 6 , 1 , 21 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
+1255 */{ 0 , 2 , 9 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1256 */{ 0 , 1 , 29 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
+1257 */{ 4 , 1 , 17 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
+1258 */{ 0 , 2 , 5 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
+1259 */{ 11 , 1 , 25 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
+1260 */{ 0 , 2 , 13 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
+1261 */{ 0 , 2 , 1 , 46752 },/* 30 29 30 30 29 30 30 29 30 29 30 29 0 355
+1262 */{ 9 , 1 , 22 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
+1263 */{ 0 , 2 , 10 , 21872 },/* 29 30 29 30 29 30 29 30 29 30 30 30 0 355
+1264 */{ 0 , 1 , 31 , 18896 },/* 29 30 29 29 30 29 29 30 30 30 29 30 0 354
+1265 */{ 5 , 1 , 19 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
+1266 */{ 0 , 2 , 7 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1267 */{ 0 , 1 , 27 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
+1268 */{ 1 , 1 , 16 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
+1269 */{ 0 , 2 , 3 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
+1270 */{ 11 , 1 , 23 , 46528 },/* 30 29 30 30 29 30 29 30 30 30 29 29 29 384
+1271 */{ 0 , 2 , 11 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
+1272 */{ 0 , 2 , 1 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1273 */{ 6 , 1 , 21 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
+1274 */{ 0 , 2 , 9 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1275 */{ 0 , 1 , 29 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
+1276 */{ 3 , 1 , 18 , 27224 },/* 29 30 30 29 30 29 30 29 29 30 29 30 30 384
+1277 */{ 0 , 2 , 5 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
+1278 */{ 11 , 1 , 25 , 27432 },/* 29 30 30 29 30 29 30 30 29 29 30 29 30 384
+1279 */{ 0 , 2 , 13 , 23232 },/* 29 30 29 30 30 29 30 29 30 30 29 29 0 354
+1280 */{ 0 , 2 , 2 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
+1281 */{ 8 , 1 , 22 , 10984 },/* 29 29 30 29 30 29 30 29 30 30 30 29 30 384
+1282 */{ 0 , 2 , 10 , 18912 },/* 29 30 29 29 30 29 29 30 30 30 30 29 0 354
+1283 */{ 0 , 1 , 30 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1284 */{ 5 , 1 , 19 , 53848 },/* 30 30 29 30 29 29 30 29 29 30 29 30 30 384
+1285 */{ 0 , 2 , 6 , 45648 },/* 30 29 30 30 29 29 30 29 29 30 29 30 0 354
+1286 */{ 0 , 1 , 26 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
+1287 */{ 2 , 1 , 15 , 62096 },/* 30 30 30 30 29 29 30 29 30 29 29 30 29 384
+1288 */{ 0 , 2 , 3 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
+1289 */{ 10 , 1 , 23 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 29 384
+1290 */{ 0 , 2 , 11 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1291 */{ 0 , 2 , 1 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+1292 */{ 6 , 1 , 21 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
+1293 */{ 0 , 2 , 8 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1294 */{ 0 , 1 , 28 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
+1295 */{ 4 , 1 , 17 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
+1296 */{ 0 , 2 , 5 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
+1297 */{ 12 , 1 , 24 , 44384 },/* 30 29 30 29 30 30 29 30 29 30 30 29 29 384
+1298 */{ 0 , 2 , 12 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
+1299 */{ 0 , 2 , 2 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
+1300 */{ 8 , 1 , 23 , 2424 },/* 29 29 29 29 30 29 29 30 29 30 30 30 30 383
+1301 */{ 0 , 2 , 10 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1302 */{ 0 , 1 , 30 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
+1303 */{ 5 , 1 , 19 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
+1304 */{ 0 , 2 , 6 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
+1305 */{ 0 , 1 , 26 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+1306 */{ 1 , 1 , 15 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 29 384
+1307 */{ 0 , 2 , 3 , 42720 },/* 30 29 30 29 29 30 30 29 30 30 30 29 0 355
+1308 */{ 11 , 1 , 24 , 37608 },/* 30 29 29 30 29 29 30 29 30 30 30 29 30 384
+1309 */{ 0 , 2 , 11 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+1310 */{ 0 , 1 , 31 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
+1311 */{ 7 , 1 , 20 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+1312 */{ 0 , 2 , 8 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1313 */{ 0 , 1 , 27 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
+1314 */{ 3 , 1 , 17 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
+1315 */{ 0 , 2 , 5 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1316 */{ 0 , 1 , 25 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
+1317 */{ 1 , 1 , 14 , 37608 },/* 30 29 29 30 29 29 30 29 30 30 30 29 30 384
+1318 */{ 0 , 2 , 2 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
+1319 */{ 8 , 1 , 22 , 42328 },/* 30 29 30 29 29 30 29 30 29 30 29 30 30 384
+1320 */{ 0 , 2 , 10 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1321 */{ 0 , 1 , 29 , 45728 },/* 30 29 30 30 29 29 30 29 30 29 30 29 0 354
+1322 */{ 5 , 1 , 18 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
+1323 */{ 0 , 2 , 6 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+1324 */{ 0 , 1 , 27 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
+1325 */{ 1 , 1 , 15 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 29 384
+1326 */{ 0 , 2 , 3 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1327 */{ 9 , 1 , 24 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
+1328 */{ 0 , 2 , 12 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
+1329 */{ 0 , 1 , 31 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 0 354
+1330 */{ 7 , 1 , 20 , 27288 },/* 29 30 30 29 30 29 30 29 30 29 29 30 30 384
+1331 */{ 0 , 2 , 8 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+1332 */{ 0 , 1 , 28 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
+1333 */{ 3 , 1 , 17 , 19368 },/* 29 30 29 29 30 29 30 30 30 29 30 29 30 384
+1334 */{ 0 , 2 , 5 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+1335 */{ 12 , 1 , 25 , 42608 },/* 30 29 30 29 29 30 30 29 29 30 30 30 29 384
+1336 */{ 0 , 2 , 13 , 41696 },/* 30 29 30 29 29 29 30 29 30 30 30 29 0 354
+1337 */{ 0 , 2 , 1 , 53600 },/* 30 30 29 30 29 29 29 30 29 30 30 29 0 354
+1338 */{ 8 , 1 , 21 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
+1339 */{ 0 , 2 , 9 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1340 */{ 0 , 1 , 29 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
+1341 */{ 5 , 1 , 18 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 29 384
+1342 */{ 0 , 2 , 6 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
+1343 */{ 0 , 1 , 27 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1344 */{ 2 , 1 , 16 , 41704 },/* 30 29 30 29 29 29 30 29 30 30 30 29 30 384
+1345 */{ 0 , 2 , 3 , 41680 },/* 30 29 30 29 29 29 30 29 30 30 29 30 0 354
+1346 */{ 10 , 1 , 23 , 53592 },/* 30 30 29 30 29 29 29 30 29 30 29 30 30 384
+1347 */{ 0 , 2 , 11 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
+1348 */{ 0 , 1 , 31 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
+1349 */{ 7 , 1 , 19 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 29 384
+1350 */{ 0 , 2 , 7 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
+1351 */{ 0 , 1 , 28 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
+1352 */{ 3 , 1 , 18 , 18904 },/* 29 30 29 29 30 29 29 30 30 30 29 30 30 384
+1353 */{ 0 , 2 , 5 , 17840 },/* 29 30 29 29 29 30 29 30 30 29 30 30 0 354
+1354 */{ 0 , 1 , 25 , 41648 },/* 30 29 30 29 29 29 30 29 30 29 30 30 0 354
+1355 */{ 1 , 1 , 14 , 53592 },/* 30 30 29 30 29 29 29 30 29 30 29 30 30 384
+1356 */{ 0 , 2 , 2 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
+1357 */{ 9 , 1 , 21 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
+1358 */{ 0 , 2 , 9 , 27424 },/* 29 30 30 29 30 29 30 30 29 29 30 29 0 354
+1359 */{ 0 , 1 , 29 , 44384 },/* 30 29 30 29 30 30 29 30 29 30 30 29 0 355
+1360 */{ 5 , 1 , 19 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
+1361 */{ 0 , 2 , 6 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
+1362 */{ 0 , 1 , 27 , 17776 },/* 29 30 29 29 29 30 29 30 29 30 30 30 0 354
+1363 */{ 3 , 1 , 16 , 41656 },/* 30 29 30 29 29 29 30 29 30 29 30 30 30 384
+1364 */{ 0 , 2 , 4 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1365 */{ 10 , 1 , 23 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 29 383
+1366 */{ 0 , 2 , 10 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
+1367 */{ 0 , 1 , 31 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+1368 */{ 7 , 1 , 20 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 29 384
+1369 */{ 0 , 2 , 7 , 42720 },/* 30 29 30 29 29 30 30 29 30 30 30 29 0 355
+1370 */{ 0 , 1 , 28 , 21216 },/* 29 30 29 30 29 29 30 29 30 30 30 29 0 354
+1371 */{ 3 , 1 , 17 , 50544 },/* 30 30 29 29 29 30 29 30 29 30 30 30 29 384
+1372 */{ 0 , 2 , 5 , 42336 },/* 30 29 30 29 29 30 29 30 29 30 30 29 0 354
+1373 */{ 11 , 1 , 24 , 53928 },/* 30 30 29 30 29 29 30 29 30 29 30 29 30 384
+1374 */{ 0 , 2 , 12 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
+1375 */{ 0 , 2 , 1 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
+1376 */{ 9 , 1 , 22 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
+1377 */{ 0 , 2 , 9 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1378 */{ 0 , 1 , 29 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
+1379 */{ 5 , 1 , 19 , 21224 },/* 29 30 29 30 29 29 30 29 30 30 30 29 30 384
+1380 */{ 0 , 2 , 7 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1381 */{ 0 , 1 , 26 , 43216 },/* 30 29 30 29 30 29 29 29 30 30 29 30 0 354
+1382 */{ 2 , 1 , 15 , 53928 },/* 30 30 29 30 29 29 30 29 30 29 30 29 30 384
+1383 */{ 0 , 2 , 3 , 45728 },/* 30 29 30 30 29 29 30 29 30 29 30 29 0 354
+1384 */{ 10 , 1 , 23 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
+1385 */{ 0 , 2 , 10 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+1386 */{ 0 , 1 , 31 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
+1387 */{ 6 , 1 , 20 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 29 384
+1388 */{ 0 , 2 , 8 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1389 */{ 0 , 1 , 28 , 20912 },/* 29 30 29 30 29 29 29 30 30 29 30 30 0 354
+1390 */{ 4 , 1 , 17 , 43192 },/* 30 29 30 29 30 29 29 29 30 29 30 30 30 384
+1391 */{ 0 , 2 , 5 , 25904 },/* 29 30 30 29 29 30 29 30 29 29 30 30 0 354
+1392 */{ 12 , 1 , 25 , 27288 },/* 29 30 30 29 30 29 30 29 30 29 29 30 30 384
+1393 */{ 0 , 2 , 12 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+1394 */{ 0 , 2 , 1 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
+1395 */{ 9 , 1 , 22 , 11176 },/* 29 29 30 29 30 29 30 30 30 29 30 29 30 384
+1396 */{ 0 , 2 , 10 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1397 */{ 0 , 1 , 29 , 50032 },/* 30 30 29 29 29 29 30 30 29 30 30 30 0 355
+1398 */{ 5 , 1 , 19 , 20848 },/* 29 30 29 30 29 29 29 30 29 30 30 30 29 383
+1399 */{ 0 , 2 , 6 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
+1400 */{ 0 , 1 , 26 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1401 */{ 3 , 1 , 15 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 29 383
+1402 */{ 0 , 2 , 2 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
+1403 */{ 11 , 1 , 23 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 29 384
+1404 */{ 0 , 2 , 11 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
+1405 */{ 0 , 1 , 31 , 10976 },/* 29 29 30 29 30 29 30 29 30 30 30 29 0 354
+1406 */{ 7 , 1 , 20 , 41704 },/* 30 29 30 29 29 29 30 29 30 30 30 29 30 384
+1407 */{ 0 , 2 , 8 , 41680 },/* 30 29 30 29 29 29 30 29 30 30 29 30 0 354
+1408 */{ 0 , 1 , 28 , 53584 },/* 30 30 29 30 29 29 29 30 29 30 29 30 0 354
+1409 */{ 4 , 1 , 16 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+1410 */{ 0 , 2 , 4 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
+1411 */{ 12 , 1 , 24 , 46736 },/* 30 29 30 30 29 30 30 29 30 29 29 30 29 384
+1412 */{ 0 , 2 , 12 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
+1413 */{ 0 , 2 , 1 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
+1414 */{ 9 , 1 , 22 , 9688 },/* 29 29 30 29 29 30 29 30 30 30 29 30 30 384
+1415 */{ 0 , 2 , 10 , 17840 },/* 29 30 29 29 29 30 29 30 30 29 30 30 0 354
+1416 */{ 0 , 1 , 30 , 41648 },/* 30 29 30 29 29 29 30 29 30 29 30 30 0 354
+1417 */{ 5 , 1 , 18 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
+1418 */{ 0 , 2 , 6 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1419 */{ 0 , 1 , 26 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
+1420 */{ 1 , 1 , 15 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
+1421 */{ 0 , 2 , 2 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
+1422 */{ 12 , 1 , 23 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
+1423 */{ 0 , 2 , 11 , 19312 },/* 29 30 29 29 30 29 30 30 29 30 30 30 0 355
+1424 */{ 0 , 2 , 1 , 17776 },/* 29 30 29 29 29 30 29 30 29 30 30 30 0 354
+1425 */{ 7 , 1 , 20 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
+1426 */{ 0 , 2 , 8 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1427 */{ 0 , 1 , 28 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
+1428 */{ 4 , 1 , 17 , 27816 },/* 29 30 30 29 30 30 29 29 30 29 30 29 30 384
+1429 */{ 0 , 2 , 4 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+1430 */{ 12 , 1 , 24 , 39760 },/* 30 29 29 30 30 29 30 30 29 30 29 30 29 384
+1431 */{ 0 , 2 , 12 , 42720 },/* 30 29 30 29 29 30 30 29 30 30 30 29 0 355
+1432 */{ 0 , 2 , 2 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1433 */{ 8 , 1 , 21 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
+1434 */{ 0 , 2 , 9 , 42336 },/* 30 29 30 29 29 30 29 30 29 30 30 29 0 354
+1435 */{ 0 , 1 , 29 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
+1436 */{ 6 , 1 , 18 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 29 384
+1437 */{ 0 , 2 , 5 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
+1438 */{ 0 , 1 , 26 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1439 */{ 2 , 1 , 15 , 43728 },/* 30 29 30 29 30 29 30 29 30 30 29 30 29 384
+1440 */{ 0 , 2 , 3 , 38368 },/* 30 29 29 30 29 30 29 30 30 30 30 29 0 355
+1441 */{ 11 , 1 , 23 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+1442 */{ 0 , 2 , 11 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+1443 */{ 0 , 1 , 31 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1444 */{ 7 , 1 , 20 , 53872 },/* 30 30 29 30 29 29 30 29 29 30 30 30 29 384
+1445 */{ 0 , 2 , 7 , 45728 },/* 30 29 30 30 29 29 30 29 30 29 30 29 0 354
+1446 */{ 0 , 1 , 27 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1447 */{ 4 , 1 , 17 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
+1448 */{ 0 , 2 , 5 , 11680 },/* 29 29 30 29 30 30 29 30 30 29 30 29 0 354
+1449 */{ 0 , 1 , 24 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1450 */{ 1 , 1 , 14 , 19128 },/* 29 30 29 29 30 29 30 29 30 29 30 30 30 384
+1451 */{ 0 , 2 , 2 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+1452 */{ 9 , 1 , 22 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
+1453 */{ 0 , 2 , 9 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
+1454 */{ 0 , 1 , 29 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 0 354
+1455 */{ 6 , 1 , 18 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
+1456 */{ 0 , 2 , 6 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 0 355
+1457 */{ 0 , 1 , 26 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1458 */{ 2 , 1 , 15 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 29 384
+1459 */{ 0 , 2 , 3 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
+1460 */{ 11 , 1 , 24 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 29 383
+1461 */{ 0 , 2 , 10 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
+1462 */{ 0 , 1 , 30 , 58544 },/* 30 30 30 29 29 30 29 29 30 29 30 30 0 355
+1463 */{ 7 , 1 , 20 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 29 383
+1464 */{ 0 , 2 , 7 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
+1465 */{ 0 , 1 , 27 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
+1466 */{ 3 , 1 , 17 , 11112 },/* 29 29 30 29 30 29 30 30 29 30 30 29 30 384
+1467 */{ 0 , 2 , 5 , 9952 },/* 29 29 30 29 29 30 30 29 30 30 30 29 0 354
+1468 */{ 0 , 1 , 25 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+1469 */{ 2 , 1 , 13 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
+1470 */{ 0 , 2 , 1 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
+1471 */{ 9 , 1 , 21 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+1472 */{ 0 , 2 , 9 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
+1473 */{ 0 , 1 , 28 , 46736 },/* 30 29 30 30 29 30 30 29 30 29 29 30 0 355
+1474 */{ 6 , 1 , 18 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
+1475 */{ 0 , 2 , 6 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
+1476 */{ 0 , 1 , 27 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+1477 */{ 2 , 1 , 15 , 37592 },/* 30 29 29 30 29 29 30 29 30 30 29 30 30 384
+1478 */{ 0 , 2 , 3 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
+1479 */{ 10 , 1 , 23 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
+1480 */{ 0 , 2 , 11 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
+1481 */{ 0 , 1 , 30 , 29856 },/* 29 30 30 30 29 30 29 29 30 29 30 29 0 354
+1482 */{ 8 , 1 , 19 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
+1483 */{ 0 , 2 , 7 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
+1484 */{ 0 , 1 , 28 , 21424 },/* 29 30 29 30 29 29 30 30 30 29 30 30 0 355
+1485 */{ 4 , 1 , 17 , 9656 },/* 29 29 30 29 29 30 29 30 30 29 30 30 30 384
+1486 */{ 0 , 2 , 5 , 9584 },/* 29 29 30 29 29 30 29 30 29 30 30 30 0 354
+1487 */{ 0 , 1 , 25 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1488 */{ 1 , 1 , 14 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
+1489 */{ 0 , 2 , 1 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
+1490 */{ 9 , 1 , 21 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
+1491 */{ 0 , 2 , 9 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+1492 */{ 0 , 1 , 29 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
+1493 */{ 5 , 1 , 18 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
+1494 */{ 0 , 2 , 6 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1495 */{ 0 , 1 , 26 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1496 */{ 3 , 1 , 16 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 29 383
+1497 */{ 0 , 2 , 2 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
+1498 */{ 11 , 1 , 22 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 29 384
+1499 */{ 0 , 2 , 10 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1500 */{ 0 , 1 , 31 , 5792 },/* 29 29 29 30 29 30 30 29 30 29 30 29 0 353
+1501 */{ 7 , 1 , 19 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
+1502 */{ 0 , 2 , 7 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
+1503 */{ 0 , 1 , 28 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1504 */{ 4 , 1 , 17 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
+1505 */{ 0 , 2 , 4 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1506 */{ 0 , 1 , 24 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
+1507 */{ 1 , 1 , 13 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 29 384
+1508 */{ 0 , 2 , 1 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1509 */{ 9 , 1 , 21 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
+1510 */{ 0 , 2 , 9 , 11680 },/* 29 29 30 29 30 30 29 30 30 29 30 29 0 354
+1511 */{ 0 , 1 , 29 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1512 */{ 5 , 1 , 19 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
+1513 */{ 0 , 2 , 6 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1514 */{ 0 , 1 , 26 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1515 */{ 4 , 1 , 15 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
+1516 */{ 0 , 2 , 3 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 0 354
+1517 */{ 12 , 1 , 22 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
+1518 */{ 0 , 2 , 10 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 0 355
+1519 */{ 0 , 1 , 31 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1520 */{ 8 , 1 , 20 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 29 384
+1521 */{ 0 , 2 , 7 , 37616 },/* 30 29 29 30 29 29 30 29 30 30 30 30 0 355
+1522 */{ 0 , 1 , 28 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1523 */{ 4 , 1 , 17 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
+1524 */{ 0 , 2 , 4 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1525 */{ 12 , 1 , 23 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 29 384
+1526 */{ 0 , 2 , 11 , 54928 },/* 30 30 29 30 29 30 30 29 30 29 29 30 0 355
+1527 */{ 0 , 2 , 1 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
+1528 */{ 10 , 1 , 22 , 11112 },/* 29 29 30 29 30 29 30 30 29 30 30 29 30 384
+1529 */{ 0 , 2 , 9 , 9952 },/* 29 29 30 29 29 30 30 29 30 30 30 29 0 354
+1530 */{ 0 , 1 , 29 , 21216 },/* 29 30 29 30 29 29 30 29 30 30 30 29 0 354
+1531 */{ 6 , 1 , 18 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
+1532 */{ 0 , 2 , 6 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
+1533 */{ 0 , 1 , 25 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1534 */{ 2 , 1 , 14 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
+1535 */{ 0 , 2 , 2 , 46480 },/* 30 29 30 30 29 30 29 30 30 29 29 30 0 355
+1536 */{ 12 , 1 , 23 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
+1537 */{ 0 , 2 , 10 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
+1538 */{ 0 , 1 , 31 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+1539 */{ 7 , 1 , 20 , 37592 },/* 30 29 29 30 29 29 30 29 30 30 29 30 30 384
+1540 */{ 0 , 2 , 8 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
+1541 */{ 0 , 1 , 27 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1542 */{ 5 , 1 , 16 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
+1543 */{ 0 , 2 , 4 , 27808 },/* 29 30 30 29 30 30 29 29 30 29 30 29 0 354
+1544 */{ 0 , 1 , 24 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+1545 */{ 1 , 1 , 13 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
+1546 */{ 0 , 2 , 1 , 19376 },/* 29 30 29 29 30 29 30 30 30 29 30 30 0 355
+1547 */{ 9 , 1 , 22 , 9656 },/* 29 29 30 29 29 30 29 30 30 29 30 30 30 384
+1548 */{ 0 , 2 , 10 , 9584 },/* 29 29 30 29 29 30 29 30 29 30 30 30 0 354
+1549 */{ 0 , 1 , 29 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1550 */{ 6 , 1 , 18 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 29 383
+1551 */{ 0 , 2 , 5 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
+1552 */{ 0 , 1 , 26 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+1553 */{ 3 , 1 , 14 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
+1554 */{ 0 , 2 , 2 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
+1555 */{ 11 , 1 , 23 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
+1556 */{ 0 , 2 , 11 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1557 */{ 0 , 1 , 30 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1558 */{ 7 , 1 , 20 , 21096 },/* 29 30 29 30 29 29 30 29 29 30 30 29 30 383
+1559 */{ 0 , 2 , 7 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
+1560 */{ 0 , 1 , 27 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
+1561 */{ 5 , 1 , 16 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
+1562 */{ 0 , 2 , 4 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1563 */{ 0 , 1 , 24 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
+1564 */{ 2 , 1 , 14 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+1565 */{ 0 , 2 , 1 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1566 */{ 10 , 1 , 21 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
+1567 */{ 0 , 2 , 9 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1568 */{ 0 , 1 , 29 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
+1569 */{ 6 , 1 , 17 , 54600 },/* 30 30 29 30 29 30 29 30 29 30 29 29 30 384
+1570 */{ 0 , 2 , 5 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1571 */{ 0 , 1 , 26 , 13728 },/* 29 29 30 30 29 30 29 30 30 29 30 29 0 354
+1572 */{ 2 , 1 , 15 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 29 384
+1573 */{ 0 , 2 , 2 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1574 */{ 12 , 1 , 23 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
+1575 */{ 0 , 2 , 11 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1576 */{ 0 , 1 , 31 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1577 */{ 8 , 1 , 19 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
+1578 */{ 0 , 2 , 7 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
+1579 */{ 0 , 1 , 27 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
+1580 */{ 4 , 1 , 16 , 44456 },/* 30 29 30 29 30 30 29 30 30 29 30 29 30 385
+1581 */{ 0 , 2 , 4 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1582 */{ 0 , 1 , 24 , 39024 },/* 30 29 29 30 29 29 30 30 39 30 30 30 0 365
+1583 */{ 2 , 1 , 24 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
+1584 */{ 0 , 2 , 12 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1585 */{ 9 , 1 , 31 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
+1586 */{ 0 , 2 , 18 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+1587 */{ 0 , 3 , 9 , 53968 },/* 30 30 29 30 29 30 29 29 30 29 30 0 0 325
+1588 */{ 6 , 1 , 28 , 27464 },/* 29 30 30 29 30 29 30 30 29 30 29 29 30 384
+1589 */{ 0 , 2 , 15 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
+1590 */{ 0 , 2 , 5 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1591 */{ 3 , 1 , 25 , 37616 },/* 30 29 29 30 29 29 30 29 30 30 30 30 29 384
+1592 */{ 0 , 2 , 13 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+1593 */{ 11 , 2 , 1 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
+1594 */{ 0 , 2 , 20 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1595 */{ 0 , 2 , 9 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1596 */{ 8 , 1 , 29 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
+1597 */{ 0 , 2 , 16 , 46288 },/* 30 29 30 30 29 30 29 29 30 30 29 30 0 355
+1598 */{ 0 , 2 , 6 , 22192 },/* 29 30 29 30 29 30 30 29 30 29 30 30 0 355
+1599 */{ 4 , 1 , 27 , 9944 },/* 29 29 30 29 29 30 30 29 30 30 29 30 30 384
+1600 */{ 0 , 2 , 15 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+1601 */{ 0 , 2 , 3 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
+1602 */{ 2 , 1 , 23 , 51608 },/* 30 30 29 29 30 29 29 30 30 29 29 30 30 384
+1603 */{ 0 , 2 , 11 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1604 */{ 9 , 1 , 31 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
+1605 */{ 0 , 2 , 18 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+1606 */{ 0 , 2 , 7 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+1607 */{ 6 , 1 , 28 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
+1608 */{ 0 , 2 , 16 , 19376 },/* 29 30 29 29 30 29 30 30 30 29 30 30 0 355
+1609 */{ 0 , 2 , 5 , 9648 },/* 29 29 30 29 29 30 29 30 30 29 30 30 0 354
+1610 */{ 3 , 1 , 25 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
+1611 */{ 0 , 2 , 13 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1612 */{ 11 , 2 , 2 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 29 383
+1613 */{ 0 , 2 , 19 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
+1614 */{ 0 , 2 , 9 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+1615 */{ 8 , 1 , 29 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
+1616 */{ 0 , 2 , 17 , 39760 },/* 30 29 29 30 30 29 30 30 29 30 29 30 0 355
+1617 */{ 0 , 2 , 6 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+1618 */{ 4 , 1 , 26 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
+1619 */{ 0 , 2 , 14 , 42224 },/* 30 29 30 29 29 30 29 29 30 30 30 30 0 355
+1620 */{ 0 , 2 , 4 , 21088 },/* 29 30 29 30 29 29 30 29 29 30 30 29 0 353
+1621 */{ 2 , 1 , 22 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
+1622 */{ 0 , 2 , 10 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
+1623 */{ 10 , 1 , 31 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
+1624 */{ 0 , 2 , 19 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1625 */{ 0 , 2 , 7 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
+1626 */{ 6 , 1 , 28 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+1627 */{ 0 , 2 , 16 , 18912 },/* 29 30 29 29 30 29 29 30 30 30 30 29 0 354
+1628 */{ 0 , 2 , 5 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1629 */{ 4 , 1 , 24 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
+1630 */{ 0 , 2 , 12 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
+1631 */{ 11 , 2 , 1 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
+1632 */{ 0 , 2 , 20 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
+1633 */{ 0 , 2 , 8 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
+1634 */{ 8 , 1 , 29 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 29 384
+1635 */{ 0 , 2 , 17 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1636 */{ 0 , 2 , 7 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+1637 */{ 4 , 1 , 26 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
+1638 */{ 0 , 2 , 14 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1639 */{ 0 , 2 , 3 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
+1640 */{ 1 , 1 , 23 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
+1641 */{ 0 , 2 , 10 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
+1642 */{ 11 , 1 , 30 , 44456 },/* 30 29 30 29 30 30 29 30 30 29 30 29 30 385
+1643 */{ 0 , 2 , 19 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1644 */{ 0 , 2 , 8 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
+1645 */{ 6 , 1 , 28 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
+1646 */{ 0 , 2 , 16 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1647 */{ 0 , 2 , 5 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
+1648 */{ 3 , 1 , 24 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
+1649 */{ 0 , 2 , 11 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
+1650 */{ 11 , 2 , 1 , 27464 },/* 29 30 30 29 30 29 30 30 29 30 29 29 30 384
+1651 */{ 0 , 2 , 20 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
+1652 */{ 0 , 2 , 10 , 11168 },/* 29 29 30 29 30 29 30 30 30 29 30 29 0 354
+1653 */{ 7 , 1 , 29 , 37616 },/* 30 29 29 30 29 29 30 29 30 30 30 30 29 384
+1654 */{ 0 , 2 , 17 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+1655 */{ 0 , 2 , 6 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
+1656 */{ 5 , 1 , 26 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+1657 */{ 0 , 2 , 13 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1658 */{ 0 , 2 , 2 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
+1659 */{ 3 , 1 , 23 , 39592 },/* 30 29 29 30 30 29 30 29 30 29 30 29 30 384
+1660 */{ 0 , 2 , 11 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1661 */{ 7 , 1 , 30 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 29 384
+1662 */{ 0 , 2 , 18 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 0 355
+1663 */{ 0 , 2 , 8 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
+1664 */{ 6 , 1 , 28 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
+1665 */{ 0 , 2 , 15 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1666 */{ 0 , 2 , 4 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
+1667 */{ 4 , 1 , 24 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
+1668 */{ 0 , 2 , 12 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+1669 */{ 0 , 2 , 1 , 21920 },/* 29 30 29 30 29 30 29 30 30 29 30 29 0 354
+1670 */{ 2 , 1 , 21 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 29 384
+1671 */{ 0 , 2 , 9 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
+1672 */{ 7 , 1 , 30 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
+1673 */{ 0 , 2 , 17 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1674 */{ 0 , 2 , 6 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 0 354
+1675 */{ 5 , 1 , 26 , 29864 },/* 29 30 30 30 29 30 29 29 30 29 30 29 30 384
+1676 */{ 0 , 2 , 14 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+1677 */{ 0 , 2 , 2 , 44432 },/* 30 29 30 29 30 30 29 30 30 29 29 30 0 355
+1678 */{ 3 , 1 , 23 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
+1679 */{ 0 , 2 , 11 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+1680 */{ 8 , 1 , 31 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
+1681 */{ 0 , 2 , 18 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
+1682 */{ 0 , 2 , 7 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
+1683 */{ 6 , 1 , 27 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
+1684 */{ 0 , 2 , 15 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
+1685 */{ 0 , 2 , 3 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
+1686 */{ 4 , 1 , 24 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
+1687 */{ 0 , 2 , 12 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
+1688 */{ 0 , 2 , 2 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1689 */{ 3 , 1 , 21 , 42216 },/* 30 29 30 29 29 30 29 29 30 30 30 29 30 384
+1690 */{ 0 , 2 , 9 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1691 */{ 7 , 1 , 29 , 53848 },/* 30 30 29 30 29 29 30 29 29 30 29 30 30 384
+1692 */{ 0 , 2 , 17 , 45136 },/* 30 29 29 32 29 29 29 29 29 30 29 30 0 354
+1693 */{ 0 , 2 , 5 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
+1694 */{ 5 , 1 , 25 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 29 384
+1695 */{ 0 , 2 , 13 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
+1696 */{ 0 , 2 , 3 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
+1697 */{ 3 , 1 , 23 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
+1698 */{ 0 , 2 , 11 , 18896 },/* 29 30 29 29 30 29 29 30 30 30 29 30 0 354
+1699 */{ 7 , 1 , 31 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
+1700 */{ 0 , 2 , 19 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1701 */{ 0 , 2 , 8 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
+1702 */{ 6 , 1 , 28 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
+1703 */{ 0 , 2 , 16 , 27936 },/* 29 30 30 29 30 30 29 30 29 29 30 29 0 354
+1704 */{ 0 , 2 , 5 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
+1705 */{ 4 , 1 , 25 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
+1706 */{ 0 , 2 , 13 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
+1707 */{ 0 , 2 , 3 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1708 */{ 3 , 1 , 23 , 25784 },/* 29 30 30 29 29 30 29 29 30 29 30 30 30 384
+1709 */{ 0 , 2 , 10 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1710 */{ 7 , 1 , 30 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
+1711 */{ 0 , 2 , 17 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
+1712 */{ 0 , 2 , 7 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+1713 */{ 5 , 1 , 26 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 29 384
+1714 */{ 0 , 2 , 14 , 43744 },/* 30 29 30 29 30 29 30 29 30 30 30 29 0 355
+1715 */{ 0 , 2 , 4 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+1716 */{ 3 , 1 , 24 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 29 384
+1717 */{ 0 , 2 , 11 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
+1718 */{ 8 , 1 , 31 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+1719 */{ 0 , 2 , 19 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1720 */{ 0 , 2 , 8 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
+1721 */{ 6 , 1 , 28 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
+1722 */{ 0 , 2 , 16 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1723 */{ 0 , 2 , 5 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
+1724 */{ 4 , 1 , 26 , 21224 },/* 29 30 29 30 29 29 30 29 30 30 30 29 30 384
+1725 */{ 0 , 2 , 13 , 21200 },/* 29 30 29 30 29 29 30 29 30 30 29 30 0 354
+1726 */{ 0 , 2 , 2 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1727 */{ 3 , 1 , 22 , 58536 },/* 30 30 30 29 29 30 29 29 30 29 30 29 30 384
+1728 */{ 0 , 2 , 10 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
+1729 */{ 7 , 1 , 29 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
+1730 */{ 0 , 2 , 17 , 40272 },/* 30 29 29 30 30 30 29 30 29 30 29 30 0 355
+1731 */{ 0 , 2 , 7 , 21920 },/* 29 30 29 30 29 30 29 30 30 29 30 29 0 354
+1732 */{ 5 , 1 , 27 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 29 384
+1733 */{ 0 , 2 , 14 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
+1734 */{ 0 , 2 , 4 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1735 */{ 4 , 1 , 24 , 43192 },/* 30 29 30 29 30 29 29 29 30 29 30 30 30 384
+1736 */{ 0 , 2 , 12 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 0 354
+1737 */{ 9 , 1 , 31 , 27288 },/* 29 30 30 29 30 29 30 29 30 29 29 30 30 384
+1738 */{ 0 , 2 , 19 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+1739 */{ 0 , 2 , 8 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
+1740 */{ 6 , 1 , 29 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
+1741 */{ 0 , 2 , 16 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+1742 */{ 0 , 2 , 5 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1743 */{ 4 , 1 , 26 , 20848 },/* 29 30 29 30 29 29 29 30 29 30 30 30 29 383
+1744 */{ 0 , 2 , 13 , 53600 },/* 30 30 29 30 29 29 29 30 29 30 30 29 0 354
+1745 */{ 0 , 2 , 1 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 0 355
+1746 */{ 3 , 1 , 22 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 29 383
+1747 */{ 0 , 2 , 9 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
+1748 */{ 7 , 1 , 30 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 29 384
+1749 */{ 0 , 2 , 17 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
+1750 */{ 0 , 2 , 7 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1751 */{ 5 , 1 , 27 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
+1752 */{ 0 , 2 , 15 , 41680 },/* 30 29 30 29 29 29 30 29 30 30 29 30 0 354
+1753 */{ 0 , 2 , 3 , 53592 },/* 30 30 29 30 29 29 29 30 29 30 29 30 30 384
+1754 */{ 4 , 2 , 22 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
+1755 */{ 0 , 2 , 11 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
+1756 */{ 9 , 1 , 31 , 54928 },/* 30 30 29 30 29 30 30 29 30 29 29 30 29 384
+1757 */{ 0 , 2 , 18 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
+1758 */{ 0 , 2 , 8 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
+1759 */{ 6 , 1 , 29 , 10968 },/* 29 29 30 29 30 29 30 29 30 30 29 30 30 384
+1760 */{ 0 , 2 , 17 , 17840 },/* 29 30 29 29 29 30 29 30 30 29 30 30 0 354
+1761 */{ 0 , 2 , 5 , 41648 },/* 30 29 30 29 29 29 30 29 30 29 30 30 0 354
+1762 */{ 5 , 1 , 25 , 45400 },/* 30 29 30 30 29 29 29 30 29 30 29 30 30 384
+1763 */{ 0 , 2 , 13 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1764 */{ 0 , 2 , 2 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
+1765 */{ 2 , 1 , 21 , 46480 },/* 30 29 30 30 29 30 29 30 30 29 29 30 29 384
+1766 */{ 0 , 2 , 9 , 44384 },/* 30 29 30 29 30 30 29 30 29 30 30 29 0 355
+1767 */{ 7 , 1 , 30 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
+1768 */{ 0 , 2 , 18 , 21360 },/* 29 30 29 30 29 29 30 30 29 30 30 30 0 355
+1769 */{ 0 , 2 , 7 , 17776 },/* 29 30 29 29 29 30 29 30 29 30 30 30 0 354
+1770 */{ 5 , 1 , 27 , 25272 },/* 29 30 30 29 29 29 30 29 30 29 30 30 30 384
+1771 */{ 0 , 2 , 15 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1772 */{ 0 , 2 , 4 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
+1773 */{ 3 , 1 , 23 , 27816 },/* 29 30 30 29 30 30 29 29 30 29 30 29 30 384
+1774 */{ 0 , 2 , 11 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+1775 */{ 10 , 1 , 31 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
+1776 */{ 0 , 2 , 19 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
+1777 */{ 0 , 2 , 8 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1778 */{ 6 , 1 , 28 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 29 384
+1779 */{ 0 , 2 , 16 , 42336 },/* 30 29 30 29 29 30 29 30 29 30 30 29 0 354
+1780 */{ 0 , 2 , 5 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
+1781 */{ 5 , 1 , 24 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 29 384
+1782 */{ 0 , 2 , 12 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
+1783 */{ 0 , 2 , 2 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+1784 */{ 3 , 1 , 22 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
+1785 */{ 0 , 2 , 9 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
+1786 */{ 7 , 1 , 30 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+1787 */{ 0 , 2 , 18 , 19120 },/* 29 30 29 29 30 29 30 29 30 29 30 30 0 354
+1788 */{ 0 , 2 , 7 , 43216 },/* 30 29 30 29 30 29 29 29 30 30 29 30 0 354
+1789 */{ 5 , 1 , 26 , 53928 },/* 30 30 29 30 29 29 30 29 30 29 30 29 30 384
+1790 */{ 0 , 2 , 14 , 45728 },/* 30 29 30 30 29 29 30 29 30 29 30 29 0 354
+1791 */{ 0 , 2 , 3 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1792 */{ 4 , 1 , 24 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
+1793 */{ 0 , 2 , 11 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
+1794 */{ 0 , 1 , 31 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
+1795 */{ 2 , 1 , 21 , 19128 },/* 29 30 29 29 30 29 30 29 30 29 30 30 30 384
+1796 */{ 0 , 2 , 9 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+1797 */{ 6 , 1 , 28 , 43192 },/* 30 29 30 29 30 29 29 29 30 29 30 30 30 384
+1798 */{ 0 , 2 , 16 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
+1799 */{ 0 , 2 , 5 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 0 354
+1800 */{ 4 , 1 , 25 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
+1801 */{ 0 , 2 , 13 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 0 355
+1802 */{ 0 , 2 , 3 , 11168 },/* 29 29 30 29 30 29 30 30 30 29 30 29 0 354
+1803 */{ 2 , 1 , 23 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 29 384
+1804 */{ 0 , 2 , 11 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
+1805 */{ 6 , 1 , 31 , 20848 },/* 29 30 29 30 29 29 29 30 29 30 30 30 29 383
+1806 */{ 0 , 2 , 18 , 53600 },/* 30 30 29 30 29 29 29 30 29 30 30 29 0 354
+1807 */{ 0 , 2 , 7 , 58544 },/* 30 30 30 29 29 30 29 29 30 29 30 30 0 355
+1808 */{ 5 , 1 , 28 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 29 383
+1809 */{ 0 , 2 , 14 , 55952 },/* 30 30 29 30 30 29 30 29 30 29 29 30 0 355
+1810 */{ 0 , 2 , 4 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 0 355
+1811 */{ 3 , 1 , 25 , 11112 },/* 29 29 30 29 30 29 30 30 29 30 30 29 30 384
+1812 */{ 0 , 2 , 13 , 10976 },/* 29 29 30 29 30 29 30 29 30 30 30 29 0 354
+1813 */{ 0 , 2 , 1 , 41696 },/* 30 29 30 29 29 29 30 29 30 30 30 29 0 354
+1814 */{ 2 , 1 , 21 , 53608 },/* 30 30 29 30 29 29 29 30 29 30 30 29 30 384
+1815 */{ 0 , 2 , 9 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
+1816 */{ 6 , 1 , 29 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+1817 */{ 0 , 2 , 16 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
+1818 */{ 0 , 2 , 5 , 46736 },/* 30 29 30 30 29 30 30 29 30 29 29 30 0 355
+1819 */{ 4 , 1 , 26 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
+1820 */{ 0 , 2 , 14 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
+1821 */{ 0 , 2 , 3 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+1822 */{ 3 , 1 , 23 , 41688 },/* 30 29 30 29 29 29 30 29 30 30 29 30 30 384
+1823 */{ 0 , 2 , 11 , 41648 },/* 30 29 30 29 29 29 30 29 30 29 30 30 0 354
+1824 */{ 7 , 1 , 31 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
+1825 */{ 0 , 2 , 18 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1826 */{ 0 , 2 , 7 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
+1827 */{ 5 , 1 , 27 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
+1828 */{ 0 , 2 , 15 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+1829 */{ 0 , 2 , 4 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
+1830 */{ 4 , 1 , 25 , 9656 },/* 29 29 30 29 29 30 29 30 30 29 30 30 30 384
+1831 */{ 0 , 2 , 13 , 9584 },/* 29 29 30 29 29 30 29 30 29 30 30 30 0 354
+1832 */{ 9 , 2 , 2 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
+1833 */{ 0 , 2 , 20 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1834 */{ 0 , 2 , 9 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
+1835 */{ 6 , 1 , 29 , 27816 },/* 29 30 30 29 30 30 29 29 30 29 30 29 30 384
+1836 */{ 0 , 2 , 17 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+1837 */{ 0 , 2 , 5 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
+1838 */{ 4 , 1 , 26 , 21352 },/* 29 30 29 30 29 29 30 30 29 30 30 29 30 384
+1839 */{ 0 , 2 , 14 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1840 */{ 0 , 2 , 3 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1841 */{ 3 , 1 , 23 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 29 383
+1842 */{ 0 , 2 , 10 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
+1843 */{ 7 , 1 , 30 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 29 384
+1844 */{ 0 , 2 , 18 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
+1845 */{ 0 , 2 , 7 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+1846 */{ 5 , 1 , 27 , 43728 },/* 30 29 30 29 30 29 30 29 30 30 29 30 29 384
+1847 */{ 0 , 2 , 15 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
+1848 */{ 0 , 2 , 5 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1849 */{ 4 , 1 , 24 , 42328 },/* 30 29 30 29 29 30 29 30 29 30 29 30 30 384
+1850 */{ 0 , 2 , 12 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1851 */{ 8 , 2 , 1 , 53848 },/* 30 30 29 30 29 29 30 29 29 30 29 30 30 384
+1852 */{ 0 , 2 , 20 , 45712 },/* 30 29 30 30 29 29 30 29 30 29 29 30 0 354
+1853 */{ 0 , 2 , 8 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1854 */{ 7 , 1 , 29 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
+1855 */{ 0 , 2 , 17 , 11680 },/* 29 29 30 29 30 30 29 30 30 29 30 29 0 354
+1856 */{ 0 , 2 , 6 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
+1857 */{ 5 , 1 , 26 , 19128 },/* 29 30 29 29 30 29 30 29 30 29 30 30 30 384
+1858 */{ 0 , 2 , 14 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+1859 */{ 0 , 2 , 3 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1860 */{ 3 , 1 , 23 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
+1861 */{ 0 , 2 , 10 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 0 354
+1862 */{ 8 , 1 , 30 , 44360 },/* 30 29 30 29 30 30 29 30 29 30 29 29 30 384
+1863 */{ 0 , 2 , 18 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 0 355
+1864 */{ 0 , 2 , 8 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1865 */{ 5 , 1 , 27 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 29 384
+1866 */{ 0 , 2 , 15 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
+1867 */{ 0 , 2 , 5 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1868 */{ 4 , 1 , 25 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
+1869 */{ 0 , 2 , 11 , 58528 },/* 30 30 30 29 29 30 29 29 30 29 30 29 0 354
+1870 */{ 10 , 1 , 31 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 29 384
+1871 */{ 0 , 2 , 19 , 55952 },/* 30 30 29 30 30 29 30 29 30 29 29 30 0 355
+1872 */{ 0 , 2 , 9 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
+1873 */{ 6 , 1 , 29 , 11112 },/* 29 29 30 29 30 29 30 30 29 30 30 29 30 384
+1874 */{ 0 , 2 , 17 , 10976 },/* 29 29 30 29 30 29 30 29 30 30 30 29 0 354
+1875 */{ 0 , 2 , 6 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+1876 */{ 5 , 1 , 26 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
+1877 */{ 0 , 2 , 13 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
+1878 */{ 0 , 2 , 2 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1879 */{ 3 , 1 , 22 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
+1880 */{ 0 , 2 , 10 , 46736 },/* 30 29 30 30 29 30 30 29 30 29 29 30 0 355
+1881 */{ 7 , 1 , 30 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
+1882 */{ 0 , 2 , 18 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
+1883 */{ 0 , 2 , 8 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+1884 */{ 5 , 1 , 28 , 37592 },/* 30 29 29 30 29 29 30 29 30 30 29 30 30 384
+1885 */{ 0 , 2 , 15 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
+1886 */{ 0 , 2 , 4 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1887 */{ 4 , 1 , 24 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+1888 */{ 0 , 2 , 12 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
+1889 */{ 0 , 1 , 31 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1890 */{ 2 , 1 , 21 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
+1891 */{ 0 , 2 , 9 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
+1892 */{ 6 , 1 , 30 , 9656 },/* 29 29 30 29 29 30 29 30 30 29 30 30 30 384
+1893 */{ 0 , 2 , 17 , 9584 },/* 29 29 30 29 29 30 29 30 29 30 30 30 0 354
+1894 */{ 0 , 2 , 6 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1895 */{ 5 , 1 , 26 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 29 383
+1896 */{ 0 , 2 , 13 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
+1897 */{ 0 , 2 , 2 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+1898 */{ 3 , 1 , 22 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
+1899 */{ 0 , 2 , 10 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
+1900 */{ 8 , 1 , 31 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
+1901 */{ 0 , 2 , 19 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1902 */{ 0 , 2 , 8 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1903 */{ 5 , 1 , 29 , 21096 },/* 29 30 29 30 29 29 30 29 29 30 30 29 30 383
+1904 */{ 0 , 2 , 16 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
+1905 */{ 0 , 2 , 4 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
+1906 */{ 4 , 1 , 25 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
+1907 */{ 0 , 2 , 13 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1908 */{ 0 , 2 , 2 , 39632 },/* 30 29 29 30 30 29 30 29 30 30 29 30 0 355
+1909 */{ 2 , 1 , 22 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+1910 */{ 0 , 2 , 10 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1911 */{ 6 , 1 , 30 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
+1912 */{ 0 , 2 , 18 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1913 */{ 0 , 2 , 6 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
+1914 */{ 5 , 1 , 26 , 55624 },/* 30 30 29 30 30 29 29 30 29 30 29 29 30 384
+1915 */{ 0 , 2 , 14 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1916 */{ 0 , 2 , 4 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1917 */{ 2 , 1 , 23 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
+1918 */{ 0 , 2 , 11 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
+1919 */{ 7 , 2 , 1 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
+1920 */{ 0 , 2 , 20 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+1921 */{ 0 , 2 , 8 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1922 */{ 5 , 1 , 28 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
+1923 */{ 0 , 2 , 16 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 0 354
+1924 */{ 0 , 2 , 5 , 44352 },/* 30 29 30 29 30 30 29 30 29 30 29 29 0 354
+1925 */{ 4 , 1 , 24 , 46504 },/* 30 29 30 30 29 30 29 30 30 29 30 29 30 385
+1926 */{ 0 , 2 , 13 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1927 */{ 0 , 2 , 2 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1928 */{ 2 , 1 , 23 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
+1929 */{ 0 , 2 , 10 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1930 */{ 6 , 1 , 30 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
+1931 */{ 0 , 2 , 17 , 58528 },/* 30 30 30 29 29 30 29 29 30 29 30 29 0 354
+1932 */{ 0 , 2 , 6 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
+1933 */{ 5 , 1 , 26 , 27976 },/* 29 30 30 29 30 30 29 30 29 30 29 29 30 384
+1934 */{ 0 , 2 , 14 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 0 355
+1935 */{ 0 , 2 , 4 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1936 */{ 3 , 1 , 24 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 29 384
+1937 */{ 0 , 2 , 11 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+1938 */{ 7 , 1 , 31 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
+1939 */{ 0 , 2 , 19 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
+1940 */{ 0 , 2 , 8 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1941 */{ 6 , 1 , 27 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
+1942 */{ 0 , 2 , 15 , 46736 },/* 30 29 30 30 29 30 30 29 30 29 29 30 0 355
+1943 */{ 0 , 2 , 5 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
+1944 */{ 4 , 1 , 26 , 10968 },/* 29 29 30 29 30 29 30 29 30 30 29 30 30 384
+1945 */{ 0 , 2 , 13 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+1946 */{ 0 , 2 , 2 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
+1947 */{ 2 , 1 , 22 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
+1948 */{ 0 , 2 , 10 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1949 */{ 7 , 1 , 29 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+1950 */{ 0 , 2 , 17 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
+1951 */{ 0 , 2 , 6 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1952 */{ 5 , 1 , 27 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
+1953 */{ 0 , 2 , 14 , 19888 },/* 29 30 29 29 30 30 29 30 30 29 30 30 0 355
+1954 */{ 0 , 2 , 4 , 9648 },/* 29 29 30 29 29 30 29 30 30 29 30 30 0 354
+1955 */{ 3 , 1 , 24 , 37560 },/* 30 29 29 30 29 29 30 29 30 29 30 30 30 384
+1956 */{ 0 , 2 , 12 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1957 */{ 8 , 1 , 31 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
+1958 */{ 0 , 2 , 19 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
+1959 */{ 0 , 2 , 8 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+1960 */{ 6 , 1 , 28 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
+1961 */{ 0 , 2 , 15 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
+1962 */{ 0 , 2 , 5 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+1963 */{ 4 , 1 , 25 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
+1964 */{ 0 , 2 , 13 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1965 */{ 0 , 2 , 2 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
+1966 */{ 3 , 1 , 22 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 29 383
+1967 */{ 0 , 2 , 9 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
+1968 */{ 7 , 1 , 30 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
+1969 */{ 0 , 2 , 17 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1970 */{ 0 , 2 , 6 , 39632 },/* 30 29 29 30 30 29 30 29 30 30 29 30 0 355
+1971 */{ 5 , 1 , 27 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+1972 */{ 0 , 2 , 15 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+1973 */{ 0 , 2 , 3 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
+1974 */{ 4 , 1 , 23 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
+1975 */{ 0 , 2 , 11 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
+1976 */{ 8 , 1 , 31 , 54600 },/* 30 30 29 30 29 30 29 30 29 30 29 29 30 384
+1977 */{ 0 , 2 , 18 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
+1978 */{ 0 , 2 , 7 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 0 355
+1979 */{ 6 , 1 , 28 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
+1980 */{ 0 , 2 , 16 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1981 */{ 0 , 2 , 5 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+1982 */{ 4 , 1 , 25 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
+1983 */{ 0 , 2 , 13 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1984 */{ 10 , 2 , 2 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
+1985 */{ 0 , 2 , 20 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
+1986 */{ 0 , 2 , 9 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
+1987 */{ 6 , 1 , 29 , 46504 },/* 30 29 30 30 29 30 29 30 30 29 30 29 30 385
+1988 */{ 0 , 2 , 18 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1989 */{ 0 , 2 , 6 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1990 */{ 5 , 1 , 27 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
+1991 */{ 0 , 2 , 15 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1992 */{ 0 , 2 , 4 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
+1993 */{ 3 , 1 , 23 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
+1994 */{ 0 , 2 , 10 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
+1995 */{ 8 , 1 , 31 , 27976 },/* 29 30 30 29 30 30 29 30 29 30 29 29 30 384
+1996 */{ 0 , 2 , 19 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
+1997 */{ 0 , 2 , 8 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1998 */{ 5 , 1 , 28 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
+1999 */{ 0 , 2 , 16 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+2000 */{ 0 , 2 , 5 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
+2001 */{ 4 , 1 , 24 , 58536 },/* 30 30 30 29 29 30 29 29 30 29 30 29 30 384
+2002 */{ 0 , 2 , 12 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+2003 */{ 0 , 2 , 1 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
+2004 */{ 2 , 1 , 22 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
+2005 */{ 0 , 2 , 9 , 22208 },/* 29 30 29 30 29 30 30 29 30 30 29 29 0 354
+2006 */{ 7 , 1 , 29 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
+2007 */{ 0 , 2 , 18 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+2008 */{ 0 , 2 , 7 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
+2009 */{ 5 , 1 , 26 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
+2010 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+2011 */{ 0 , 2 , 3 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
+2012 */{ 3 , 1 , 23 , 47696 },/* 30 29 30 30 30 29 30 29 29 30 29 30 29 384
+2013 */{ 0 , 2 , 10 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+2014 */{ 9 , 1 , 31 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
+2015 */{ 0 , 2 , 19 , 19360 },/* 29 30 29 29 30 29 30 30 30 29 30 29 0 354
+2016 */{ 0 , 2 , 8 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
+2017 */{ 5 , 1 , 28 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
+2018 */{ 0 , 2 , 16 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+2019 */{ 0 , 2 , 5 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+2020 */{ 4 , 1 , 25 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
+2021 */{ 0 , 2 , 12 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+2022 */{ 0 , 2 , 1 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+2023 */{ 2 , 1 , 22 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
+2024 */{ 0 , 2 , 10 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+2025 */{ 6 , 1 , 29 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
+2026 */{ 0 , 2 , 17 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+2027 */{ 0 , 2 , 7 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
+2028 */{ 5 , 1 , 27 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 29 383
+2029 */{ 0 , 2 , 13 , 55600 },/* 30 30 29 30 30 29 29 30 29 29 30 30 0 355
+2030 */{ 0 , 2 , 3 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+2031 */{ 3 , 1 , 23 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
+2032 */{ 0 , 2 , 11 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
+2033 */{ 11 , 1 , 31 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+2034 */{ 0 , 2 , 19 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
+2035 */{ 0 , 2 , 8 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+2036 */{ 6 , 1 , 28 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
+2037 */{ 0 , 2 , 15 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
+2038 */{ 0 , 2 , 4 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
+2039 */{ 5 , 1 , 24 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 29 384
+2040 */{ 0 , 2 , 12 , 46752 },/* 30 29 30 30 29 30 30 29 30 29 30 29 0 355
+2041 */{ 0 , 2 , 1 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
+2042 */{ 2 , 1 , 22 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
+2043 */{ 0 , 2 , 10 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+2044 */{ 7 , 1 , 30 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
+2045 */{ 0 , 2 , 17 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+2046 */{ 0 , 2 , 6 , 45648 },/* 30 29 30 30 29 29 30 29 29 30 29 30 0 354
+2047 */{ 5 , 1 , 26 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
+2048 */{ 0 , 2 , 14 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
+2049 */{ 0 , 2 , 2 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
+2050 */{ 3 , 1 , 23 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 29 384
+ */};
+
+
+ internal override int MinCalendarYear
+ {
+ get
+ {
+ return (MIN_LUNISOLAR_YEAR);
+ }
+ }
+
+ internal override int MaxCalendarYear
+ {
+ get
+ {
+ return (MAX_LUNISOLAR_YEAR);
+ }
+ }
+
+ internal override DateTime MinDate
+ {
+ get
+ {
+ return (minDate);
+ }
+ }
+
+ internal override DateTime MaxDate
+ {
+ get
+ {
+ return (maxDate);
+ }
+ }
+
+ internal override EraInfo[] CalEraInfo
+ {
+ get
+ {
+ return null;
+ }
+ }
+
+ internal override int GetYearInfo(int lunarYear, int index)
+ {
+ if ((lunarYear < MIN_LUNISOLAR_YEAR) || (lunarYear > MAX_LUNISOLAR_YEAR))
+ {
+ throw new ArgumentOutOfRangeException(
+ "year",
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ MIN_LUNISOLAR_YEAR,
+ MAX_LUNISOLAR_YEAR));
+ }
+ Contract.EndContractBlock();
+ return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index];
+ }
+
+ internal override int GetYear(int year, DateTime time)
+ {
+ return year;
+ }
+
+ internal override int GetGregorianYear(int year, int era)
+ {
+ if (era != CurrentEra && era != GregorianEra)
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
+
+ if (year < MIN_LUNISOLAR_YEAR || year > MAX_LUNISOLAR_YEAR)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(year),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range, MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR));
+ }
+ Contract.EndContractBlock();
+
+ return year;
+ }
+
+ public KoreanLunisolarCalendar()
+ {
+ }
+
+ public override int GetEra(DateTime time)
+ {
+ CheckTicksRange(time.Ticks);
+ return (GregorianEra);
+ }
+
+ internal override CalendarId BaseCalendarID
+ {
+ get
+ {
+ return (CalendarId.KOREA);
+ }
+ }
+
+ internal override CalendarId ID
+ {
+ get
+ {
+ return (CalendarId.KOREANLUNISOLAR);
+ }
+ }
+
+
+
+ public override int[] Eras
+ {
+ get
+ {
+ return (new int[] { GregorianEra });
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Globalization/LocaleData.Unix.cs b/src/mscorlib/shared/System/Globalization/LocaleData.Unix.cs
index d4c58d8a3d..d4c58d8a3d 100644
--- a/src/mscorlib/corefx/System/Globalization/LocaleData.Unix.cs
+++ b/src/mscorlib/shared/System/Globalization/LocaleData.Unix.cs
diff --git a/src/mscorlib/shared/System/Globalization/NumberStyles.cs b/src/mscorlib/shared/System/Globalization/NumberStyles.cs
new file mode 100644
index 0000000000..5909d65a2c
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/NumberStyles.cs
@@ -0,0 +1,65 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose: Contains valid formats for Numbers recognized by
+** the Number class' parsing code.
+**
+**
+===========================================================*/
+
+namespace System.Globalization
+{
+ [Flags]
+ public enum NumberStyles
+ {
+ // Bit flag indicating that leading whitespace is allowed. Character values
+ // 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, and 0x0020 are considered to be
+ // whitespace.
+
+ None = 0x00000000,
+
+ AllowLeadingWhite = 0x00000001,
+
+ AllowTrailingWhite = 0x00000002, //Bitflag indicating trailing whitespace is allowed.
+
+ AllowLeadingSign = 0x00000004, //Can the number start with a sign char.
+ //Specified by NumberFormatInfo.PositiveSign and NumberFormatInfo.NegativeSign
+
+ AllowTrailingSign = 0x00000008, //Allow the number to end with a sign char
+
+ AllowParentheses = 0x00000010, //Allow the number to be enclosed in parens
+
+ AllowDecimalPoint = 0x00000020, //Allow a decimal point
+
+ AllowThousands = 0x00000040, //Allow thousands separators (more properly, allow group separators)
+
+ AllowExponent = 0x00000080, //Allow an exponent
+
+ AllowCurrencySymbol = 0x00000100, //Allow a currency symbol.
+
+ AllowHexSpecifier = 0x00000200, //Allow specifiying hexadecimal.
+ //Common uses. These represent some of the most common combinations of these flags.
+
+
+ Integer = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign,
+
+ HexNumber = AllowLeadingWhite | AllowTrailingWhite | AllowHexSpecifier,
+
+ Number = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | AllowTrailingSign |
+ AllowDecimalPoint | AllowThousands,
+
+ Float = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign |
+ AllowDecimalPoint | AllowExponent,
+
+ Currency = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | AllowTrailingSign |
+ AllowParentheses | AllowDecimalPoint | AllowThousands | AllowCurrencySymbol,
+
+ Any = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | AllowTrailingSign |
+ AllowParentheses | AllowDecimalPoint | AllowThousands | AllowCurrencySymbol | AllowExponent,
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/PersianCalendar.cs b/src/mscorlib/shared/System/Globalization/PersianCalendar.cs
new file mode 100644
index 0000000000..445bbd6d0c
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/PersianCalendar.cs
@@ -0,0 +1,606 @@
+// 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.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System.Globalization
+{
+ // Modern Persian calendar is a solar observation based calendar. Each new year begins on the day when the vernal equinox occurs before noon.
+ // The epoch is the date of the vernal equinox prior to the epoch of the Islamic calendar (March 19, 622 Julian or March 22, 622 Gregorian)
+
+ // There is no Persian year 0. Ordinary years have 365 days. Leap years have 366 days with the last month (Esfand) gaining the extra day.
+ /*
+ ** Calendar support range:
+ ** Calendar Minimum Maximum
+ ** ========== ========== ==========
+ ** Gregorian 0622/03/22 9999/12/31
+ ** Persian 0001/01/01 9378/10/13
+ */
+
+ [Serializable]
+ public class PersianCalendar : Calendar
+ {
+ public static readonly int PersianEra = 1;
+
+ internal static long PersianEpoch = new DateTime(622, 3, 22).Ticks / GregorianCalendar.TicksPerDay;
+ private const int ApproximateHalfYear = 180;
+
+ internal const int DatePartYear = 0;
+ internal const int DatePartDayOfYear = 1;
+ internal const int DatePartMonth = 2;
+ internal const int DatePartDay = 3;
+ internal const int MonthsPerYear = 12;
+
+ internal static int[] DaysToMonth = { 0, 31, 62, 93, 124, 155, 186, 216, 246, 276, 306, 336, 366 };
+
+ internal const int MaxCalendarYear = 9378;
+ internal const int MaxCalendarMonth = 10;
+ internal const int MaxCalendarDay = 13;
+
+ // Persian calendar (year: 1, month: 1, day:1 ) = Gregorian (year: 622, month: 3, day: 22)
+ // This is the minimal Gregorian date that we support in the PersianCalendar.
+ internal static DateTime minDate = new DateTime(622, 3, 22);
+ internal static DateTime maxDate = DateTime.MaxValue;
+
+ public override DateTime MinSupportedDateTime
+ {
+ get
+ {
+ return (minDate);
+ }
+ }
+
+ public override DateTime MaxSupportedDateTime
+ {
+ get
+ {
+ return (maxDate);
+ }
+ }
+
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.SolarCalendar;
+ }
+ }
+
+ // Construct an instance of Persian calendar.
+
+ public PersianCalendar()
+ {
+ }
+
+
+ internal override CalendarId BaseCalendarID
+ {
+ get
+ {
+ return CalendarId.GREGORIAN;
+ }
+ }
+
+ internal override CalendarId ID
+ {
+ get
+ {
+ return CalendarId.PERSIAN;
+ }
+ }
+
+
+ /*=================================GetAbsoluteDatePersian==========================
+ **Action: Gets the Absolute date for the given Persian date. The absolute date means
+ ** the number of days from January 1st, 1 A.D.
+ **Returns:
+ **Arguments:
+ **Exceptions:
+ ============================================================================*/
+
+ private long GetAbsoluteDatePersian(int year, int month, int day)
+ {
+ if (year >= 1 && year <= MaxCalendarYear && month >= 1 && month <= 12)
+ {
+ int ordinalDay = DaysInPreviousMonths(month) + day - 1; // day is one based, make 0 based since this will be the number of days we add to beginning of year below
+ int approximateDaysFromEpochForYearStart = (int)(CalendricalCalculationsHelper.MeanTropicalYearInDays * (year - 1));
+ long yearStart = CalendricalCalculationsHelper.PersianNewYearOnOrBefore(PersianEpoch + approximateDaysFromEpochForYearStart + ApproximateHalfYear);
+ yearStart += ordinalDay;
+ return yearStart;
+ }
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
+ }
+
+ internal static void CheckTicksRange(long ticks)
+ {
+ if (ticks < minDate.Ticks || ticks > maxDate.Ticks)
+ {
+ throw new ArgumentOutOfRangeException(
+ "time",
+ String.Format(
+ CultureInfo.InvariantCulture,
+ SR.ArgumentOutOfRange_CalendarRange,
+ minDate,
+ maxDate));
+ }
+ }
+
+ internal static void CheckEraRange(int era)
+ {
+ if (era != CurrentEra && era != PersianEra)
+ {
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
+ }
+ }
+
+ internal static void CheckYearRange(int year, int era)
+ {
+ CheckEraRange(era);
+ if (year < 1 || year > MaxCalendarYear)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(year),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ 1,
+ MaxCalendarYear));
+ }
+ }
+
+ internal static void CheckYearMonthRange(int year, int month, int era)
+ {
+ CheckYearRange(year, era);
+ if (year == MaxCalendarYear)
+ {
+ if (month > MaxCalendarMonth)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(month),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ 1,
+ MaxCalendarMonth));
+ }
+ }
+
+ if (month < 1 || month > 12)
+ {
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
+ }
+ }
+
+ private static int MonthFromOrdinalDay(int ordinalDay)
+ {
+ Debug.Assert(ordinalDay <= 366);
+ int index = 0;
+ while (ordinalDay > DaysToMonth[index])
+ index++;
+
+ return index;
+ }
+
+ private static int DaysInPreviousMonths(int month)
+ {
+ Debug.Assert(1 <= month && month <= 12);
+ --month; // months are one based but for calculations use 0 based
+ return DaysToMonth[month];
+ }
+
+ /*=================================GetDatePart==========================
+ **Action: Returns a given date part of this <i>DateTime</i>. This method is used
+ ** to compute the year, day-of-year, month, or day part.
+ **Returns:
+ **Arguments:
+ **Exceptions: ArgumentException if part is incorrect.
+ ============================================================================*/
+
+ internal int GetDatePart(long ticks, int part)
+ {
+ long NumDays; // The calculation buffer in number of days.
+
+ CheckTicksRange(ticks);
+
+ //
+ // Get the absolute date. The absolute date is the number of days from January 1st, 1 A.D.
+ // 1/1/0001 is absolute date 1.
+ //
+ NumDays = ticks / GregorianCalendar.TicksPerDay + 1;
+
+ //
+ // Calculate the appromixate Persian Year.
+ //
+
+ long yearStart = CalendricalCalculationsHelper.PersianNewYearOnOrBefore(NumDays);
+ int y = (int)(Math.Floor(((yearStart - PersianEpoch) / CalendricalCalculationsHelper.MeanTropicalYearInDays) + 0.5)) + 1;
+ Debug.Assert(y >= 1);
+
+ if (part == DatePartYear)
+ {
+ return y;
+ }
+
+ //
+ // Calculate the Persian Month.
+ //
+
+ int ordinalDay = (int)(NumDays - CalendricalCalculationsHelper.GetNumberOfDays(this.ToDateTime(y, 1, 1, 0, 0, 0, 0, 1)));
+
+ if (part == DatePartDayOfYear)
+ {
+ return ordinalDay;
+ }
+
+ int m = MonthFromOrdinalDay(ordinalDay);
+ Debug.Assert(ordinalDay >= 1);
+ Debug.Assert(m >= 1 && m <= 12);
+ if (part == DatePartMonth)
+ {
+ return m;
+ }
+
+ int d = ordinalDay - DaysInPreviousMonths(m);
+ Debug.Assert(1 <= d);
+ Debug.Assert(d <= 31);
+
+ //
+ // Calculate the Persian Day.
+ //
+
+ if (part == DatePartDay)
+ {
+ return (d);
+ }
+
+ // Incorrect part value.
+ throw new InvalidOperationException(SR.InvalidOperation_DateTimeParsing);
+ }
+
+ // Returns the DateTime resulting from adding the given number of
+ // months to the specified DateTime. The result is computed by incrementing
+ // (or decrementing) the year and month parts of the specified DateTime by
+ // value months, and, if required, adjusting the day part of the
+ // resulting date downwards to the last day of the resulting month in the
+ // resulting year. The time-of-day part of the result is the same as the
+ // time-of-day part of the specified DateTime.
+ //
+ // In more precise terms, considering the specified DateTime to be of the
+ // form y / m / d + t, where y is the
+ // year, m is the month, d is the day, and t is the
+ // time-of-day, the result is y1 / m1 / d1 + t,
+ // where y1 and m1 are computed by adding value months
+ // to y and m, and d1 is the largest value less than
+ // or equal to d that denotes a valid day in month m1 of year
+ // y1.
+ //
+
+
+ public override DateTime AddMonths(DateTime time, int months)
+ {
+ if (months < -120000 || months > 120000)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(months),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ -120000,
+ 120000));
+ }
+ Contract.EndContractBlock();
+ // Get the date in Persian calendar.
+ int y = GetDatePart(time.Ticks, DatePartYear);
+ int m = GetDatePart(time.Ticks, DatePartMonth);
+ int d = GetDatePart(time.Ticks, DatePartDay);
+ int i = m - 1 + months;
+ if (i >= 0)
+ {
+ m = i % 12 + 1;
+ y = y + i / 12;
+ }
+ else
+ {
+ m = 12 + (i + 1) % 12;
+ y = y + (i - 11) / 12;
+ }
+ int days = GetDaysInMonth(y, m);
+ if (d > days)
+ {
+ d = days;
+ }
+ long ticks = GetAbsoluteDatePersian(y, m, d) * TicksPerDay + time.Ticks % TicksPerDay;
+ Calendar.CheckAddResult(ticks, MinSupportedDateTime, MaxSupportedDateTime);
+ return (new DateTime(ticks));
+ }
+
+ // Returns the DateTime resulting from adding the given number of
+ // years to the specified DateTime. The result is computed by incrementing
+ // (or decrementing) the year part of the specified DateTime by value
+ // years. If the month and day of the specified DateTime is 2/29, and if the
+ // resulting year is not a leap year, the month and day of the resulting
+ // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
+ // parts of the result are the same as those of the specified DateTime.
+ //
+
+
+ public override DateTime AddYears(DateTime time, int years)
+ {
+ return (AddMonths(time, years * 12));
+ }
+
+ // Returns the day-of-month part of the specified DateTime. The returned
+ // value is an integer between 1 and 31.
+ //
+
+
+ public override int GetDayOfMonth(DateTime time)
+ {
+ return (GetDatePart(time.Ticks, DatePartDay));
+ }
+
+ // Returns the day-of-week part of the specified DateTime. The returned value
+ // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
+ // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
+ // Thursday, 5 indicates Friday, and 6 indicates Saturday.
+ //
+
+
+ public override DayOfWeek GetDayOfWeek(DateTime time)
+ {
+ return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
+ }
+
+ // Returns the day-of-year part of the specified DateTime. The returned value
+ // is an integer between 1 and 366.
+ //
+
+
+ public override int GetDayOfYear(DateTime time)
+ {
+ return (GetDatePart(time.Ticks, DatePartDayOfYear));
+ }
+
+ // Returns the number of days in the month given by the year and
+ // month arguments.
+ //
+
+
+ public override int GetDaysInMonth(int year, int month, int era)
+ {
+ CheckYearMonthRange(year, month, era);
+
+ if ((month == MaxCalendarMonth) && (year == MaxCalendarYear))
+ {
+ return MaxCalendarDay;
+ }
+
+ int daysInMonth = DaysToMonth[month] - DaysToMonth[month - 1];
+ if ((month == MonthsPerYear) && !IsLeapYear(year))
+ {
+ Debug.Assert(daysInMonth == 30);
+ --daysInMonth;
+ }
+ return daysInMonth;
+ }
+
+ // Returns the number of days in the year given by the year argument for the current era.
+ //
+
+ public override int GetDaysInYear(int year, int era)
+ {
+ CheckYearRange(year, era);
+ if (year == MaxCalendarYear)
+ {
+ return DaysToMonth[MaxCalendarMonth - 1] + MaxCalendarDay;
+ }
+ // Common years have 365 days. Leap years have 366 days.
+ return (IsLeapYear(year, CurrentEra) ? 366 : 365);
+ }
+
+ // Returns the era for the specified DateTime value.
+
+
+ public override int GetEra(DateTime time)
+ {
+ CheckTicksRange(time.Ticks);
+ return (PersianEra);
+ }
+
+
+
+ public override int[] Eras
+ {
+ get
+ {
+ return (new int[] { PersianEra });
+ }
+ }
+
+ // Returns the month part of the specified DateTime. The returned value is an
+ // integer between 1 and 12.
+ //
+
+
+ public override int GetMonth(DateTime time)
+ {
+ return (GetDatePart(time.Ticks, DatePartMonth));
+ }
+
+ // Returns the number of months in the specified year and era.
+
+
+ public override int GetMonthsInYear(int year, int era)
+ {
+ CheckYearRange(year, era);
+ if (year == MaxCalendarYear)
+ {
+ return MaxCalendarMonth;
+ }
+ return (12);
+ }
+
+ // Returns the year part of the specified DateTime. The returned value is an
+ // integer between 1 and MaxCalendarYear.
+ //
+
+
+ public override int GetYear(DateTime time)
+ {
+ return (GetDatePart(time.Ticks, DatePartYear));
+ }
+
+ // Checks whether a given day in the specified era is a leap day. This method returns true if
+ // the date is a leap day, or false if not.
+ //
+
+
+ public override bool IsLeapDay(int year, int month, int day, int era)
+ {
+ // The year/month/era value checking is done in GetDaysInMonth().
+ int daysInMonth = GetDaysInMonth(year, month, era);
+ if (day < 1 || day > daysInMonth)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(day),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Day,
+ daysInMonth,
+ month));
+ }
+ return (IsLeapYear(year, era) && month == 12 && day == 30);
+ }
+
+ // Returns the leap month in a calendar year of the specified era. This method returns 0
+ // if this calendar does not have leap month, or this year is not a leap year.
+ //
+
+
+ public override int GetLeapMonth(int year, int era)
+ {
+ CheckYearRange(year, era);
+ return (0);
+ }
+
+ // Checks whether a given month in the specified era is a leap month. This method returns true if
+ // month is a leap month, or false if not.
+ //
+
+
+ public override bool IsLeapMonth(int year, int month, int era)
+ {
+ CheckYearMonthRange(year, month, era);
+ return (false);
+ }
+
+ // Checks whether a given year in the specified era is a leap year. This method returns true if
+ // year is a leap year, or false if not.
+ //
+
+ public override bool IsLeapYear(int year, int era)
+ {
+ CheckYearRange(year, era);
+
+ if (year == MaxCalendarYear)
+ {
+ return false;
+ }
+
+ return (GetAbsoluteDatePersian(year + 1, 1, 1) - GetAbsoluteDatePersian(year, 1, 1)) == 366;
+ }
+
+ // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
+ //
+
+
+ public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
+ {
+ // The year/month/era checking is done in GetDaysInMonth().
+ int daysInMonth = GetDaysInMonth(year, month, era);
+ if (day < 1 || day > daysInMonth)
+ {
+ // BCLDebug.Log("year = " + year + ", month = " + month + ", day = " + day);
+ throw new ArgumentOutOfRangeException(
+ nameof(day),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Day,
+ daysInMonth,
+ month));
+ }
+
+ long lDate = GetAbsoluteDatePersian(year, month, day);
+
+ if (lDate >= 0)
+ {
+ return (new DateTime(lDate * GregorianCalendar.TicksPerDay + TimeToTicks(hour, minute, second, millisecond)));
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
+ }
+ }
+
+ private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 1410;
+
+ public override int TwoDigitYearMax
+ {
+ get
+ {
+ if (twoDigitYearMax == -1)
+ {
+ twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
+ }
+ return (twoDigitYearMax);
+ }
+
+ set
+ {
+ VerifyWritable();
+ if (value < 99 || value > MaxCalendarYear)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(value),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ 99,
+ MaxCalendarYear));
+ }
+ twoDigitYearMax = value;
+ }
+ }
+
+
+
+ public override int ToFourDigitYear(int year)
+ {
+ if (year < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(year),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ }
+ Contract.EndContractBlock();
+
+ if (year < 100)
+ {
+ return (base.ToFourDigitYear(year));
+ }
+
+ if (year > MaxCalendarYear)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(year),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ 1,
+ MaxCalendarYear));
+ }
+ return (year);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/SortVersion.cs b/src/mscorlib/shared/System/Globalization/SortVersion.cs
new file mode 100644
index 0000000000..a7aef6d84b
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/SortVersion.cs
@@ -0,0 +1,98 @@
+// 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.
+
+namespace System.Globalization
+{
+ [Serializable]
+ public sealed class SortVersion : IEquatable<SortVersion>
+ {
+ private int _nlsVersion;
+ private Guid _sortId;
+
+ public int FullVersion
+ {
+ get
+ {
+ return _nlsVersion;
+ }
+ }
+
+ public Guid SortId
+ {
+ get
+ {
+ return _sortId;
+ }
+ }
+
+ public SortVersion(int fullVersion, Guid sortId)
+ {
+ _sortId = sortId;
+ _nlsVersion = fullVersion;
+ }
+
+ internal SortVersion(int nlsVersion, int effectiveId, Guid customVersion)
+ {
+ _nlsVersion = nlsVersion;
+
+ if (customVersion == Guid.Empty)
+ {
+ byte b1 = (byte)(effectiveId >> 24);
+ byte b2 = (byte)((effectiveId & 0x00FF0000) >> 16);
+ byte b3 = (byte)((effectiveId & 0x0000FF00) >> 8);
+ byte b4 = (byte)(effectiveId & 0xFF);
+ customVersion = new Guid(0, 0, 0, 0, 0, 0, 0, b1, b2, b3, b4);
+ }
+
+ _sortId = customVersion;
+ }
+
+ public override bool Equals(object obj)
+ {
+ SortVersion n = obj as SortVersion;
+ if (n != null)
+ {
+ return this.Equals(n);
+ }
+
+ return false;
+ }
+
+ public bool Equals(SortVersion other)
+ {
+ if (other == null)
+ {
+ return false;
+ }
+
+ return _nlsVersion == other._nlsVersion && _sortId == other._sortId;
+ }
+
+ public override int GetHashCode()
+ {
+ return _nlsVersion * 7 | _sortId.GetHashCode();
+ }
+
+ public static bool operator ==(SortVersion left, SortVersion right)
+ {
+ if (((object)left) != null)
+ {
+ return left.Equals(right);
+ }
+
+ if (((object)right) != null)
+ {
+ return right.Equals(left);
+ }
+
+ // Both null.
+ return true;
+ }
+
+ public static bool operator !=(SortVersion left, SortVersion right)
+ {
+ return !(left == right);
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Globalization/TaiwanCalendar.cs b/src/mscorlib/shared/System/Globalization/TaiwanCalendar.cs
index 2e735e0cb9..2e735e0cb9 100644
--- a/src/mscorlib/corefx/System/Globalization/TaiwanCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/TaiwanCalendar.cs
diff --git a/src/mscorlib/shared/System/Globalization/TaiwanLunisolarCalendar.cs b/src/mscorlib/shared/System/Globalization/TaiwanLunisolarCalendar.cs
new file mode 100644
index 0000000000..8ba1f278e7
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/TaiwanLunisolarCalendar.cs
@@ -0,0 +1,325 @@
+// 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.Diagnostics.Contracts;
+
+namespace System.Globalization
+{
+ /*
+ ** Calendar support range:
+ ** Calendar Minimum Maximum
+ ** ========== ========== ==========
+ ** Gregorian 1912/02/18 2051/02/10
+ ** TaiwanLunisolar 1912/01/01 2050/13/29
+ */
+
+ [Serializable]
+ public class TaiwanLunisolarCalendar : EastAsianLunisolarCalendar
+ {
+ // Since
+ // Gregorian Year = Era Year + yearOffset
+ // When Gregorian Year 1912 is year 1, so that
+ // 1912 = 1 + yearOffset
+ // So yearOffset = 1911
+ //m_EraInfo[0] = new EraInfo(1, new DateTime(1912, 1, 1).Ticks, 1911, 1, GregorianCalendar.MaxYear - 1911);
+
+ // Initialize our era info.
+ internal static EraInfo[] taiwanLunisolarEraInfo = new EraInfo[] {
+ new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911) // era #, start year/month/day, yearOffset, minEraYear
+ };
+
+ internal GregorianCalendarHelper helper;
+
+ internal const int MIN_LUNISOLAR_YEAR = 1912;
+ internal const int MAX_LUNISOLAR_YEAR = 2050;
+
+ internal const int MIN_GREGORIAN_YEAR = 1912;
+ internal const int MIN_GREGORIAN_MONTH = 2;
+ internal const int MIN_GREGORIAN_DAY = 18;
+
+ internal const int MAX_GREGORIAN_YEAR = 2051;
+ internal const int MAX_GREGORIAN_MONTH = 2;
+ internal const int MAX_GREGORIAN_DAY = 10;
+
+ internal static DateTime minDate = new DateTime(MIN_GREGORIAN_YEAR, MIN_GREGORIAN_MONTH, MIN_GREGORIAN_DAY);
+ internal static DateTime maxDate = new DateTime((new DateTime(MAX_GREGORIAN_YEAR, MAX_GREGORIAN_MONTH, MAX_GREGORIAN_DAY, 23, 59, 59, 999)).Ticks + 9999);
+
+ public override DateTime MinSupportedDateTime
+ {
+ get
+ {
+ return (minDate);
+ }
+ }
+
+
+
+ public override DateTime MaxSupportedDateTime
+ {
+ get
+ {
+ return (maxDate);
+ }
+ }
+
+ protected override int DaysInYearBeforeMinSupportedYear
+ {
+ get
+ {
+ // 1911 from ChineseLunisolarCalendar
+ return 384;
+ }
+ }
+
+ private static readonly int[,] s_yinfo =
+ {
+ /*Y LM Lmon Lday DaysPerMonth D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 #Days
+ 1912 */
+ { 0 , 2 , 18 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1913 */{ 0 , 2 , 6 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
+1914 */{ 5 , 1 , 26 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
+1915 */{ 0 , 2 , 14 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
+1916 */{ 0 , 2 , 3 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 0 355
+1917 */{ 2 , 1 , 23 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
+1918 */{ 0 , 2 , 11 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1919 */{ 7 , 2 , 1 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
+1920 */{ 0 , 2 , 20 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1921 */{ 0 , 2 , 8 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1922 */{ 5 , 1 , 28 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
+1923 */{ 0 , 2 , 16 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
+1924 */{ 0 , 2 , 5 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
+1925 */{ 4 , 1 , 24 , 44456 },/* 30 29 30 29 30 30 29 30 30 29 30 29 30 385
+1926 */{ 0 , 2 , 13 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1927 */{ 0 , 2 , 2 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 0 355
+1928 */{ 2 , 1 , 23 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
+1929 */{ 0 , 2 , 10 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1930 */{ 6 , 1 , 30 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
+1931 */{ 0 , 2 , 17 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1932 */{ 0 , 2 , 6 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
+1933 */{ 5 , 1 , 26 , 27976 },/* 29 30 30 29 30 30 29 30 29 30 29 29 30 384
+1934 */{ 0 , 2 , 14 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
+1935 */{ 0 , 2 , 4 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
+1936 */{ 3 , 1 , 24 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
+1937 */{ 0 , 2 , 11 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+1938 */{ 7 , 1 , 31 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
+1939 */{ 0 , 2 , 19 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
+1940 */{ 0 , 2 , 8 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+1941 */{ 6 , 1 , 27 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
+1942 */{ 0 , 2 , 15 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1943 */{ 0 , 2 , 5 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1944 */{ 4 , 1 , 25 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
+1945 */{ 0 , 2 , 13 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+1946 */{ 0 , 2 , 2 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
+1947 */{ 2 , 1 , 22 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
+1948 */{ 0 , 2 , 10 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+1949 */{ 7 , 1 , 29 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
+1950 */{ 0 , 2 , 17 , 27808 },/* 29 30 30 29 30 30 29 29 30 29 30 29 0 354
+1951 */{ 0 , 2 , 6 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
+1952 */{ 5 , 1 , 27 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
+1953 */{ 0 , 2 , 14 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
+1954 */{ 0 , 2 , 3 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
+1955 */{ 3 , 1 , 24 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
+1956 */{ 0 , 2 , 12 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+1957 */{ 8 , 1 , 31 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 29 383
+1958 */{ 0 , 2 , 18 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
+1959 */{ 0 , 2 , 8 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+1960 */{ 6 , 1 , 28 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
+1961 */{ 0 , 2 , 15 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
+1962 */{ 0 , 2 , 5 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+1963 */{ 4 , 1 , 25 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
+1964 */{ 0 , 2 , 13 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
+1965 */{ 0 , 2 , 2 , 21088 },/* 29 30 29 30 29 29 30 29 29 30 30 29 0 353
+1966 */{ 3 , 1 , 21 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
+1967 */{ 0 , 2 , 9 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
+1968 */{ 7 , 1 , 30 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
+1969 */{ 0 , 2 , 17 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+1970 */{ 0 , 2 , 6 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
+1971 */{ 5 , 1 , 27 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+1972 */{ 0 , 2 , 15 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
+1973 */{ 0 , 2 , 3 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+1974 */{ 4 , 1 , 23 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
+1975 */{ 0 , 2 , 11 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
+1976 */{ 8 , 1 , 31 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
+1977 */{ 0 , 2 , 18 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
+1978 */{ 0 , 2 , 7 , 46752 },/* 30 29 30 30 29 30 30 29 30 29 30 29 0 355
+1979 */{ 6 , 1 , 28 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
+1980 */{ 0 , 2 , 16 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
+1981 */{ 0 , 2 , 5 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+1982 */{ 4 , 1 , 25 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
+1983 */{ 0 , 2 , 13 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+1984 */{ 10 , 2 , 2 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
+1985 */{ 0 , 2 , 20 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
+1986 */{ 0 , 2 , 9 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
+1987 */{ 6 , 1 , 29 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 29 384
+1988 */{ 0 , 2 , 17 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
+1989 */{ 0 , 2 , 6 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 0 355
+1990 */{ 5 , 1 , 27 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
+1991 */{ 0 , 2 , 15 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
+1992 */{ 0 , 2 , 4 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
+1993 */{ 3 , 1 , 23 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
+1994 */{ 0 , 2 , 10 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
+1995 */{ 8 , 1 , 31 , 27432 },/* 29 30 30 29 30 29 30 30 29 29 30 29 30 384
+1996 */{ 0 , 2 , 19 , 23232 },/* 29 30 29 30 30 29 30 29 30 30 29 29 0 354
+1997 */{ 0 , 2 , 7 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
+1998 */{ 5 , 1 , 28 , 37736 },/* 30 29 29 30 29 29 30 30 29 30 30 29 30 384
+1999 */{ 0 , 2 , 16 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
+2000 */{ 0 , 2 , 5 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
+2001 */{ 4 , 1 , 24 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
+2002 */{ 0 , 2 , 12 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
+2003 */{ 0 , 2 , 1 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
+2004 */{ 2 , 1 , 22 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
+2005 */{ 0 , 2 , 9 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
+2006 */{ 7 , 1 , 29 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
+2007 */{ 0 , 2 , 18 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
+2008 */{ 0 , 2 , 7 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
+2009 */{ 5 , 1 , 26 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
+2010 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
+2011 */{ 0 , 2 , 3 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
+2012 */{ 4 , 1 , 23 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
+2013 */{ 0 , 2 , 10 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+2014 */{ 9 , 1 , 31 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
+2015 */{ 0 , 2 , 19 , 19360 },/* 29 30 29 29 30 29 30 30 30 29 30 29 0 354
+2016 */{ 0 , 2 , 8 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
+2017 */{ 6 , 1 , 28 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
+2018 */{ 0 , 2 , 16 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
+2019 */{ 0 , 2 , 5 , 43312 },/* 30 29 30 29 30 29 29 30 29 29 30 30 0 354
+2020 */{ 4 , 1 , 25 , 29864 },/* 29 30 30 30 29 30 29 29 30 29 30 29 30 384
+2021 */{ 0 , 2 , 12 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
+2022 */{ 0 , 2 , 1 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
+2023 */{ 2 , 1 , 22 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
+2024 */{ 0 , 2 , 10 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
+2025 */{ 6 , 1 , 29 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
+2026 */{ 0 , 2 , 17 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
+2027 */{ 0 , 2 , 6 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
+2028 */{ 5 , 1 , 26 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
+2029 */{ 0 , 2 , 13 , 54576 },/* 30 30 29 30 29 30 29 30 29 29 30 30 0 355
+2030 */{ 0 , 2 , 3 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
+2031 */{ 3 , 1 , 23 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
+2032 */{ 0 , 2 , 11 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
+2033 */{ 11 , 1 , 31 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
+2034 */{ 0 , 2 , 19 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
+2035 */{ 0 , 2 , 8 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
+2036 */{ 6 , 1 , 28 , 53848 },/* 30 30 29 30 29 29 30 29 29 30 29 30 30 384
+2037 */{ 0 , 2 , 15 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
+2038 */{ 0 , 2 , 4 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
+2039 */{ 5 , 1 , 24 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 29 384
+2040 */{ 0 , 2 , 12 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
+2041 */{ 0 , 2 , 1 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
+2042 */{ 2 , 1 , 22 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
+2043 */{ 0 , 2 , 10 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
+2044 */{ 7 , 1 , 30 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
+2045 */{ 0 , 2 , 17 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
+2046 */{ 0 , 2 , 6 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
+2047 */{ 5 , 1 , 26 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
+2048 */{ 0 , 2 , 14 , 27936 },/* 29 30 30 29 30 30 29 30 29 29 30 29 0 354
+2049 */{ 0 , 2 , 2 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
+2050 */{ 3 , 1 , 23 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
+ */};
+
+
+ internal override int MinCalendarYear
+ {
+ get
+ {
+ return (MIN_LUNISOLAR_YEAR);
+ }
+ }
+
+ internal override int MaxCalendarYear
+ {
+ get
+ {
+ return (MAX_LUNISOLAR_YEAR);
+ }
+ }
+
+ internal override DateTime MinDate
+ {
+ get
+ {
+ return (minDate);
+ }
+ }
+
+ internal override DateTime MaxDate
+ {
+ get
+ {
+ return (maxDate);
+ }
+ }
+
+ internal override EraInfo[] CalEraInfo
+ {
+ get
+ {
+ return (taiwanLunisolarEraInfo);
+ }
+ }
+
+ internal override int GetYearInfo(int lunarYear, int index)
+ {
+ if ((lunarYear < MIN_LUNISOLAR_YEAR) || (lunarYear > MAX_LUNISOLAR_YEAR))
+ {
+ throw new ArgumentOutOfRangeException(
+ "year",
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ MIN_LUNISOLAR_YEAR,
+ MAX_LUNISOLAR_YEAR));
+ }
+ Contract.EndContractBlock();
+
+ return s_yinfo[lunarYear - MIN_LUNISOLAR_YEAR, index];
+ }
+
+ internal override int GetYear(int year, DateTime time)
+ {
+ return helper.GetYear(year, time);
+ }
+
+ internal override int GetGregorianYear(int year, int era)
+ {
+ return helper.GetGregorianYear(year, era);
+ }
+
+ public TaiwanLunisolarCalendar()
+ {
+ helper = new GregorianCalendarHelper(this, taiwanLunisolarEraInfo);
+ }
+
+ public override int GetEra(DateTime time)
+ {
+ return (helper.GetEra(time));
+ }
+
+ internal override CalendarId BaseCalendarID
+ {
+ get
+ {
+ return (CalendarId.TAIWAN);
+ }
+ }
+
+ internal override CalendarId ID
+ {
+ get
+ {
+ return (CalendarId.TAIWANLUNISOLAR);
+ }
+ }
+
+
+
+ public override int[] Eras
+ {
+ get
+ {
+ return (helper.Eras);
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Globalization/ThaiBuddhistCalendar.cs b/src/mscorlib/shared/System/Globalization/ThaiBuddhistCalendar.cs
index 9e6e30406c..9e6e30406c 100644
--- a/src/mscorlib/corefx/System/Globalization/ThaiBuddhistCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/ThaiBuddhistCalendar.cs
diff --git a/src/mscorlib/corefx/System/Globalization/TimeSpanStyles.cs b/src/mscorlib/shared/System/Globalization/TimeSpanStyles.cs
index 68a47bcbe6..68a47bcbe6 100644
--- a/src/mscorlib/corefx/System/Globalization/TimeSpanStyles.cs
+++ b/src/mscorlib/shared/System/Globalization/TimeSpanStyles.cs
diff --git a/src/mscorlib/shared/System/Globalization/UmAlQuraCalendar.cs b/src/mscorlib/shared/System/Globalization/UmAlQuraCalendar.cs
new file mode 100644
index 0000000000..b7ba6d0112
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/UmAlQuraCalendar.cs
@@ -0,0 +1,865 @@
+// 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.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System.Globalization
+{
+ /*
+ ** Calendar support range:
+ ** Calendar Minimum Maximum
+ ** ========== ========== ==========
+ ** Gregorian 1900/04/30 2077/05/13
+ ** UmAlQura 1318/01/01 1500/12/30
+ */
+
+ [Serializable]
+ public partial class UmAlQuraCalendar : Calendar
+ {
+ internal const int MinCalendarYear = 1318;
+ internal const int MaxCalendarYear = 1500;
+
+ internal struct DateMapping
+ {
+ internal DateMapping(int MonthsLengthFlags, int GYear, int GMonth, int GDay)
+ {
+ HijriMonthsLengthFlags = MonthsLengthFlags;
+ GregorianDate = new DateTime(GYear, GMonth, GDay);
+ }
+ internal int HijriMonthsLengthFlags;
+ internal DateTime GregorianDate;
+ }
+
+ private static readonly DateMapping[] s_hijriYearInfo = InitDateMapping();
+
+ private static DateMapping[] InitDateMapping()
+ {
+ short[] rawData = new short[]
+ {
+ //These data is taken from Tables/Excel/UmAlQura.xls please make sure that the two places are in sync
+ /* DaysPerM GY GM GD D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12
+ 1318*/0x02EA, 1900, 4, 30,/* 0 1 0 1 0 1 1 1 0 1 0 0 4/30/1900
+ 1319*/0x06E9, 1901, 4, 19,/* 1 0 0 1 0 1 1 1 0 1 1 0 4/19/1901
+ 1320*/0x0ED2, 1902, 4, 9,/* 0 1 0 0 1 0 1 1 0 1 1 1 4/9/1902
+ 1321*/0x0EA4, 1903, 3, 30,/* 0 0 1 0 0 1 0 1 0 1 1 1 3/30/1903
+ 1322*/0x0D4A, 1904, 3, 18,/* 0 1 0 1 0 0 1 0 1 0 1 1 3/18/1904
+ 1323*/0x0A96, 1905, 3, 7,/* 0 1 1 0 1 0 0 1 0 1 0 1 3/7/1905
+ 1324*/0x0536, 1906, 2, 24,/* 0 1 1 0 1 1 0 0 1 0 1 0 2/24/1906
+ 1325*/0x0AB5, 1907, 2, 13,/* 1 0 1 0 1 1 0 1 0 1 0 1 2/13/1907
+ 1326*/0x0DAA, 1908, 2, 3,/* 0 1 0 1 0 1 0 1 1 0 1 1 2/3/1908
+ 1327*/0x0BA4, 1909, 1, 23,/* 0 0 1 0 0 1 0 1 1 1 0 1 1/23/1909
+ 1328*/0x0B49, 1910, 1, 12,/* 1 0 0 1 0 0 1 0 1 1 0 1 1/12/1910
+ 1329*/0x0A93, 1911, 1, 1,/* 1 1 0 0 1 0 0 1 0 1 0 1 1/1/1911
+ 1330*/0x052B, 1911, 12, 21,/* 1 1 0 1 0 1 0 0 1 0 1 0 12/21/1911
+ 1331*/0x0A57, 1912, 12, 9,/* 1 1 1 0 1 0 1 0 0 1 0 1 12/9/1912
+ 1332*/0x04B6, 1913, 11, 29,/* 0 1 1 0 1 1 0 1 0 0 1 0 11/29/1913
+ 1333*/0x0AB5, 1914, 11, 18,/* 1 0 1 0 1 1 0 1 0 1 0 1 11/18/1914
+ 1334*/0x05AA, 1915, 11, 8,/* 0 1 0 1 0 1 0 1 1 0 1 0 11/8/1915
+ 1335*/0x0D55, 1916, 10, 27,/* 1 0 1 0 1 0 1 0 1 0 1 1 10/27/1916
+ 1336*/0x0D2A, 1917, 10, 17,/* 0 1 0 1 0 1 0 0 1 0 1 1 10/17/1917
+ 1337*/0x0A56, 1918, 10, 6,/* 0 1 1 0 1 0 1 0 0 1 0 1 10/6/1918
+ 1338*/0x04AE, 1919, 9, 25,/* 0 1 1 1 0 1 0 1 0 0 1 0 9/25/1919
+ 1339*/0x095D, 1920, 9, 13,/* 1 0 1 1 1 0 1 0 1 0 0 1 9/13/1920
+ 1340*/0x02EC, 1921, 9, 3,/* 0 0 1 1 0 1 1 1 0 1 0 0 9/3/1921
+ 1341*/0x06D5, 1922, 8, 23,/* 1 0 1 0 1 0 1 1 0 1 1 0 8/23/1922
+ 1342*/0x06AA, 1923, 8, 13,/* 0 1 0 1 0 1 0 1 0 1 1 0 8/13/1923
+ 1343*/0x0555, 1924, 8, 1,/* 1 0 1 0 1 0 1 0 1 0 1 0 8/1/1924
+ 1344*/0x04AB, 1925, 7, 21,/* 1 1 0 1 0 1 0 1 0 0 1 0 7/21/1925
+ 1345*/0x095B, 1926, 7, 10,/* 1 1 0 1 1 0 1 0 1 0 0 1 7/10/1926
+ 1346*/0x02BA, 1927, 6, 30,/* 0 1 0 1 1 1 0 1 0 1 0 0 6/30/1927
+ 1347*/0x0575, 1928, 6, 18,/* 1 0 1 0 1 1 1 0 1 0 1 0 6/18/1928
+ 1348*/0x0BB2, 1929, 6, 8,/* 0 1 0 0 1 1 0 1 1 1 0 1 6/8/1929
+ 1349*/0x0764, 1930, 5, 29,/* 0 0 1 0 0 1 1 0 1 1 1 0 5/29/1930
+ 1350*/0x0749, 1931, 5, 18,/* 1 0 0 1 0 0 1 0 1 1 1 0 5/18/1931
+ 1351*/0x0655, 1932, 5, 6,/* 1 0 1 0 1 0 1 0 0 1 1 0 5/6/1932
+ 1352*/0x02AB, 1933, 4, 25,/* 1 1 0 1 0 1 0 1 0 1 0 0 4/25/1933
+ 1353*/0x055B, 1934, 4, 14,/* 1 1 0 1 1 0 1 0 1 0 1 0 4/14/1934
+ 1354*/0x0ADA, 1935, 4, 4,/* 0 1 0 1 1 0 1 1 0 1 0 1 4/4/1935
+ 1355*/0x06D4, 1936, 3, 24,/* 0 0 1 0 1 0 1 1 0 1 1 0 3/24/1936
+ 1356*/0x0EC9, 1937, 3, 13,/* 1 0 0 1 0 0 1 1 0 1 1 1 3/13/1937
+ 1357*/0x0D92, 1938, 3, 3,/* 0 1 0 0 1 0 0 1 1 0 1 1 3/3/1938
+ 1358*/0x0D25, 1939, 2, 20,/* 1 0 1 0 0 1 0 0 1 0 1 1 2/20/1939
+ 1359*/0x0A4D, 1940, 2, 9,/* 1 0 1 1 0 0 1 0 0 1 0 1 2/9/1940
+ 1360*/0x02AD, 1941, 1, 28,/* 1 0 1 1 0 1 0 1 0 1 0 0 1/28/1941
+ 1361*/0x056D, 1942, 1, 17,/* 1 0 1 1 0 1 1 0 1 0 1 0 1/17/1942
+ 1362*/0x0B6A, 1943, 1, 7,/* 0 1 0 1 0 1 1 0 1 1 0 1 1/7/1943
+ 1363*/0x0B52, 1943, 12, 28,/* 0 1 0 0 1 0 1 0 1 1 0 1 12/28/1943
+ 1364*/0x0AA5, 1944, 12, 16,/* 1 0 1 0 0 1 0 1 0 1 0 1 12/16/1944
+ 1365*/0x0A4B, 1945, 12, 5,/* 1 1 0 1 0 0 1 0 0 1 0 1 12/5/1945
+ 1366*/0x0497, 1946, 11, 24,/* 1 1 1 0 1 0 0 1 0 0 1 0 11/24/1946
+ 1367*/0x0937, 1947, 11, 13,/* 1 1 1 0 1 1 0 0 1 0 0 1 11/13/1947
+ 1368*/0x02B6, 1948, 11, 2,/* 0 1 1 0 1 1 0 1 0 1 0 0 11/2/1948
+ 1369*/0x0575, 1949, 10, 22,/* 1 0 1 0 1 1 1 0 1 0 1 0 10/22/1949
+ 1370*/0x0D6A, 1950, 10, 12,/* 0 1 0 1 0 1 1 0 1 0 1 1 10/12/1950
+ 1371*/0x0D52, 1951, 10, 2,/* 0 1 0 0 1 0 1 0 1 0 1 1 10/2/1951
+ 1372*/0x0A96, 1952, 9, 20,/* 0 1 1 0 1 0 0 1 0 1 0 1 9/20/1952
+ 1373*/0x092D, 1953, 9, 9,/* 1 0 1 1 0 1 0 0 1 0 0 1 9/9/1953
+ 1374*/0x025D, 1954, 8, 29,/* 1 0 1 1 1 0 1 0 0 1 0 0 8/29/1954
+ 1375*/0x04DD, 1955, 8, 18,/* 1 0 1 1 1 0 1 1 0 0 1 0 8/18/1955
+ 1376*/0x0ADA, 1956, 8, 7,/* 0 1 0 1 1 0 1 1 0 1 0 1 8/7/1956
+ 1377*/0x05D4, 1957, 7, 28,/* 0 0 1 0 1 0 1 1 1 0 1 0 7/28/1957
+ 1378*/0x0DA9, 1958, 7, 17,/* 1 0 0 1 0 1 0 1 1 0 1 1 7/17/1958
+ 1379*/0x0D52, 1959, 7, 7,/* 0 1 0 0 1 0 1 0 1 0 1 1 7/7/1959
+ 1380*/0x0AAA, 1960, 6, 25,/* 0 1 0 1 0 1 0 1 0 1 0 1 6/25/1960
+ 1381*/0x04D6, 1961, 6, 14,/* 0 1 1 0 1 0 1 1 0 0 1 0 6/14/1961
+ 1382*/0x09B6, 1962, 6, 3,/* 0 1 1 0 1 1 0 1 1 0 0 1 6/3/1962
+ 1383*/0x0374, 1963, 5, 24,/* 0 0 1 0 1 1 1 0 1 1 0 0 5/24/1963
+ 1384*/0x0769, 1964, 5, 12,/* 1 0 0 1 0 1 1 0 1 1 1 0 5/12/1964
+ 1385*/0x0752, 1965, 5, 2,/* 0 1 0 0 1 0 1 0 1 1 1 0 5/2/1965
+ 1386*/0x06A5, 1966, 4, 21,/* 1 0 1 0 0 1 0 1 0 1 1 0 4/21/1966
+ 1387*/0x054B, 1967, 4, 10,/* 1 1 0 1 0 0 1 0 1 0 1 0 4/10/1967
+ 1388*/0x0AAB, 1968, 3, 29,/* 1 1 0 1 0 1 0 1 0 1 0 1 3/29/1968
+ 1389*/0x055A, 1969, 3, 19,/* 0 1 0 1 1 0 1 0 1 0 1 0 3/19/1969
+ 1390*/0x0AD5, 1970, 3, 8,/* 1 0 1 0 1 0 1 1 0 1 0 1 3/8/1970
+ 1391*/0x0DD2, 1971, 2, 26,/* 0 1 0 0 1 0 1 1 1 0 1 1 2/26/1971
+ 1392*/0x0DA4, 1972, 2, 16,/* 0 0 1 0 0 1 0 1 1 0 1 1 2/16/1972
+ 1393*/0x0D49, 1973, 2, 4,/* 1 0 0 1 0 0 1 0 1 0 1 1 2/4/1973
+ 1394*/0x0A95, 1974, 1, 24,/* 1 0 1 0 1 0 0 1 0 1 0 1 1/24/1974
+ 1395*/0x052D, 1975, 1, 13,/* 1 0 1 1 0 1 0 0 1 0 1 0 1/13/1975
+ 1396*/0x0A5D, 1976, 1, 2,/* 1 0 1 1 1 0 1 0 0 1 0 1 1/2/1976
+ 1397*/0x055A, 1976, 12, 22,/* 0 1 0 1 1 0 1 0 1 0 1 0 12/22/1976
+ 1398*/0x0AD5, 1977, 12, 11,/* 1 0 1 0 1 0 1 1 0 1 0 1 12/11/1977
+ 1399*/0x06AA, 1978, 12, 1,/* 0 1 0 1 0 1 0 1 0 1 1 0 12/1/1978
+ 1400*/0x0695, 1979, 11, 20,/* 1 0 1 0 1 0 0 1 0 1 1 0 11/20/1979
+ 1401*/0x052B, 1980, 11, 8,/* 1 1 0 1 0 1 0 0 1 0 1 0 11/8/1980
+ 1402*/0x0A57, 1981, 10, 28,/* 1 1 1 0 1 0 1 0 0 1 0 1 10/28/1981
+ 1403*/0x04AE, 1982, 10, 18,/* 0 1 1 1 0 1 0 1 0 0 1 0 10/18/1982
+ 1404*/0x0976, 1983, 10, 7,/* 0 1 1 0 1 1 1 0 1 0 0 1 10/7/1983
+ 1405*/0x056C, 1984, 9, 26,/* 0 0 1 1 0 1 1 0 1 0 1 0 9/26/1984
+ 1406*/0x0B55, 1985, 9, 15,/* 1 0 1 0 1 0 1 0 1 1 0 1 9/15/1985
+ 1407*/0x0AAA, 1986, 9, 5,/* 0 1 0 1 0 1 0 1 0 1 0 1 9/5/1986
+ 1408*/0x0A55, 1987, 8, 25,/* 1 0 1 0 1 0 1 0 0 1 0 1 8/25/1987
+ 1409*/0x04AD, 1988, 8, 13,/* 1 0 1 1 0 1 0 1 0 0 1 0 8/13/1988
+ 1410*/0x095D, 1989, 8, 2,/* 1 0 1 1 1 0 1 0 1 0 0 1 8/2/1989
+ 1411*/0x02DA, 1990, 7, 23,/* 0 1 0 1 1 0 1 1 0 1 0 0 7/23/1990
+ 1412*/0x05D9, 1991, 7, 12,/* 1 0 0 1 1 0 1 1 1 0 1 0 7/12/1991
+ 1413*/0x0DB2, 1992, 7, 1,/* 0 1 0 0 1 1 0 1 1 0 1 1 7/1/1992
+ 1414*/0x0BA4, 1993, 6, 21,/* 0 0 1 0 0 1 0 1 1 1 0 1 6/21/1993
+ 1415*/0x0B4A, 1994, 6, 10,/* 0 1 0 1 0 0 1 0 1 1 0 1 6/10/1994
+ 1416*/0x0A55, 1995, 5, 30,/* 1 0 1 0 1 0 1 0 0 1 0 1 5/30/1995
+ 1417*/0x02B5, 1996, 5, 18,/* 1 0 1 0 1 1 0 1 0 1 0 0 5/18/1996
+ 1418*/0x0575, 1997, 5, 7,/* 1 0 1 0 1 1 1 0 1 0 1 0 5/7/1997
+ 1419*/0x0B6A, 1998, 4, 27,/* 0 1 0 1 0 1 1 0 1 1 0 1 4/27/1998
+ 1420*/0x0BD2, 1999, 4, 17,/* 0 1 0 0 1 0 1 1 1 1 0 1 4/17/1999
+ 1421*/0x0BC4, 2000, 4, 6,/* 0 0 1 0 0 0 1 1 1 1 0 1 4/6/2000
+ 1422*/0x0B89, 2001, 3, 26,/* 1 0 0 1 0 0 0 1 1 1 0 1 3/26/2001
+ 1423*/0x0A95, 2002, 3, 15,/* 1 0 1 0 1 0 0 1 0 1 0 1 3/15/2002
+ 1424*/0x052D, 2003, 3, 4,/* 1 0 1 1 0 1 0 0 1 0 1 0 3/4/2003
+ 1425*/0x05AD, 2004, 2, 21,/* 1 0 1 1 0 1 0 1 1 0 1 0 2/21/2004
+ 1426*/0x0B6A, 2005, 2, 10,/* 0 1 0 1 0 1 1 0 1 1 0 1 2/10/2005
+ 1427*/0x06D4, 2006, 1, 31,/* 0 0 1 0 1 0 1 1 0 1 1 0 1/31/2006
+ 1428*/0x0DC9, 2007, 1, 20,/* 1 0 0 1 0 0 1 1 1 0 1 1 1/20/2007
+ 1429*/0x0D92, 2008, 1, 10,/* 0 1 0 0 1 0 0 1 1 0 1 1 1/10/2008
+ 1430*/0x0AA6, 2008, 12, 29,/* 0 1 1 0 0 1 0 1 0 1 0 1 12/29/2008
+ 1431*/0x0956, 2009, 12, 18,/* 0 1 1 0 1 0 1 0 1 0 0 1 12/18/2009
+ 1432*/0x02AE, 2010, 12, 7,/* 0 1 1 1 0 1 0 1 0 1 0 0 12/7/2010
+ 1433*/0x056D, 2011, 11, 26,/* 1 0 1 1 0 1 1 0 1 0 1 0 11/26/2011
+ 1434*/0x036A, 2012, 11, 15,/* 0 1 0 1 0 1 1 0 1 1 0 0 11/15/2012
+ 1435*/0x0B55, 2013, 11, 4,/* 1 0 1 0 1 0 1 0 1 1 0 1 11/4/2013
+ 1436*/0x0AAA, 2014, 10, 25,/* 0 1 0 1 0 1 0 1 0 1 0 1 10/25/2014
+ 1437*/0x094D, 2015, 10, 14,/* 1 0 1 1 0 0 1 0 1 0 0 1 10/14/2015
+ 1438*/0x049D, 2016, 10, 2,/* 1 0 1 1 1 0 0 1 0 0 1 0 10/2/2016
+ 1439*/0x095D, 2017, 9, 21,/* 1 0 1 1 1 0 1 0 1 0 0 1 9/21/2017
+ 1440*/0x02BA, 2018, 9, 11,/* 0 1 0 1 1 1 0 1 0 1 0 0 9/11/2018
+ 1441*/0x05B5, 2019, 8, 31,/* 1 0 1 0 1 1 0 1 1 0 1 0 8/31/2019
+ 1442*/0x05AA, 2020, 8, 20,/* 0 1 0 1 0 1 0 1 1 0 1 0 8/20/2020
+ 1443*/0x0D55, 2021, 8, 9,/* 1 0 1 0 1 0 1 0 1 0 1 1 8/9/2021
+ 1444*/0x0A9A, 2022, 7, 30,/* 0 1 0 1 1 0 0 1 0 1 0 1 7/30/2022
+ 1445*/0x092E, 2023, 7, 19,/* 0 1 1 1 0 1 0 0 1 0 0 1 7/19/2023
+ 1446*/0x026E, 2024, 7, 7,/* 0 1 1 1 0 1 1 0 0 1 0 0 7/7/2024
+ 1447*/0x055D, 2025, 6, 26,/* 1 0 1 1 1 0 1 0 1 0 1 0 6/26/2025
+ 1448*/0x0ADA, 2026, 6, 16,/* 0 1 0 1 1 0 1 1 0 1 0 1 6/16/2026
+ 1449*/0x06D4, 2027, 6, 6,/* 0 0 1 0 1 0 1 1 0 1 1 0 6/6/2027
+ 1450*/0x06A5, 2028, 5, 25,/* 1 0 1 0 0 1 0 1 0 1 1 0 5/25/2028
+ 1451*/0x054B, 2029, 5, 14,/* 1 1 0 1 0 0 1 0 1 0 1 0 5/14/2029
+ 1452*/0x0A97, 2030, 5, 3,/* 1 1 1 0 1 0 0 1 0 1 0 1 5/3/2030
+ 1453*/0x054E, 2031, 4, 23,/* 0 1 1 1 0 0 1 0 1 0 1 0 4/23/2031
+ 1454*/0x0AAE, 2032, 4, 11,/* 0 1 1 1 0 1 0 1 0 1 0 1 4/11/2032
+ 1455*/0x05AC, 2033, 4, 1,/* 0 0 1 1 0 1 0 1 1 0 1 0 4/1/2033
+ 1456*/0x0BA9, 2034, 3, 21,/* 1 0 0 1 0 1 0 1 1 1 0 1 3/21/2034
+ 1457*/0x0D92, 2035, 3, 11,/* 0 1 0 0 1 0 0 1 1 0 1 1 3/11/2035
+ 1458*/0x0B25, 2036, 2, 28,/* 1 0 1 0 0 1 0 0 1 1 0 1 2/28/2036
+ 1459*/0x064B, 2037, 2, 16,/* 1 1 0 1 0 0 1 0 0 1 1 0 2/16/2037
+ 1460*/0x0CAB, 2038, 2, 5,/* 1 1 0 1 0 1 0 1 0 0 1 1 2/5/2038
+ 1461*/0x055A, 2039, 1, 26,/* 0 1 0 1 1 0 1 0 1 0 1 0 1/26/2039
+ 1462*/0x0B55, 2040, 1, 15,/* 1 0 1 0 1 0 1 0 1 1 0 1 1/15/2040
+ 1463*/0x06D2, 2041, 1, 4,/* 0 1 0 0 1 0 1 1 0 1 1 0 1/4/2041
+ 1464*/0x0EA5, 2041, 12, 24,/* 1 0 1 0 0 1 0 1 0 1 1 1 12/24/2041
+ 1465*/0x0E4A, 2042, 12, 14,/* 0 1 0 1 0 0 1 0 0 1 1 1 12/14/2042
+ 1466*/0x0A95, 2043, 12, 3,/* 1 0 1 0 1 0 0 1 0 1 0 1 12/3/2043
+ 1467*/0x052D, 2044, 11, 21,/* 1 0 1 1 0 1 0 0 1 0 1 0 11/21/2044
+ 1468*/0x0AAD, 2045, 11, 10,/* 1 0 1 1 0 1 0 1 0 1 0 1 11/10/2045
+ 1469*/0x036C, 2046, 10, 31,/* 0 0 1 1 0 1 1 0 1 1 0 0 10/31/2046
+ 1470*/0x0759, 2047, 10, 20,/* 1 0 0 1 1 0 1 0 1 1 1 0 10/20/2047
+ 1471*/0x06D2, 2048, 10, 9,/* 0 1 0 0 1 0 1 1 0 1 1 0 10/9/2048
+ 1472*/0x0695, 2049, 9, 28,/* 1 0 1 0 1 0 0 1 0 1 1 0 9/28/2049
+ 1473*/0x052D, 2050, 9, 17,/* 1 0 1 1 0 1 0 0 1 0 1 0 9/17/2050
+ 1474*/0x0A5B, 2051, 9, 6,/* 1 1 0 1 1 0 1 0 0 1 0 1 9/6/2051
+ 1475*/0x04BA, 2052, 8, 26,/* 0 1 0 1 1 1 0 1 0 0 1 0 8/26/2052
+ 1476*/0x09BA, 2053, 8, 15,/* 0 1 0 1 1 1 0 1 1 0 0 1 8/15/2053
+ 1477*/0x03B4, 2054, 8, 5,/* 0 0 1 0 1 1 0 1 1 1 0 0 8/5/2054
+ 1478*/0x0B69, 2055, 7, 25,/* 1 0 0 1 0 1 1 0 1 1 0 1 7/25/2055
+ 1479*/0x0B52, 2056, 7, 14,/* 0 1 0 0 1 0 1 0 1 1 0 1 7/14/2056
+ 1480*/0x0AA6, 2057, 7, 3,/* 0 1 1 0 0 1 0 1 0 1 0 1 7/3/2057
+ 1481*/0x04B6, 2058, 6, 22,/* 0 1 1 0 1 1 0 1 0 0 1 0 6/22/2058
+ 1482*/0x096D, 2059, 6, 11,/* 1 0 1 1 0 1 1 0 1 0 0 1 6/11/2059
+ 1483*/0x02EC, 2060, 5, 31,/* 0 0 1 1 0 1 1 1 0 1 0 0 5/31/2060
+ 1484*/0x06D9, 2061, 5, 20,/* 1 0 0 1 1 0 1 1 0 1 1 0 5/20/2061
+ 1485*/0x0EB2, 2062, 5, 10,/* 0 1 0 0 1 1 0 1 0 1 1 1 5/10/2062
+ 1486*/0x0D54, 2063, 4, 30,/* 0 0 1 0 1 0 1 0 1 0 1 1 4/30/2063
+ 1487*/0x0D2A, 2064, 4, 18,/* 0 1 0 1 0 1 0 0 1 0 1 1 4/18/2064
+ 1488*/0x0A56, 2065, 4, 7,/* 0 1 1 0 1 0 1 0 0 1 0 1 4/7/2065
+ 1489*/0x04AE, 2066, 3, 27,/* 0 1 1 1 0 1 0 1 0 0 1 0 3/27/2066
+ 1490*/0x096D, 2067, 3, 16,/* 1 0 1 1 0 1 1 0 1 0 0 1 3/16/2067
+ 1491*/0x0D6A, 2068, 3, 5,/* 0 1 0 1 0 1 1 0 1 0 1 1 3/5/2068
+ 1492*/0x0B54, 2069, 2, 23,/* 0 0 1 0 1 0 1 0 1 1 0 1 2/23/2069
+ 1493*/0x0B29, 2070, 2, 12,/* 1 0 0 1 0 1 0 0 1 1 0 1 2/12/2070
+ 1494*/0x0A93, 2071, 2, 1,/* 1 1 0 0 1 0 0 1 0 1 0 1 2/1/2071
+ 1495*/0x052B, 2072, 1, 21,/* 1 1 0 1 0 1 0 0 1 0 1 0 1/21/2072
+ 1496*/0x0A57, 2073, 1, 9,/* 1 1 1 0 1 0 1 0 0 1 0 1 1/9/2073
+ 1497*/0x0536, 2073, 12, 30,/* 0 1 1 0 1 1 0 0 1 0 1 0 12/30/2073
+ 1498*/0x0AB5, 2074, 12, 19,/* 1 0 1 0 1 1 0 1 0 1 0 1 12/19/2074
+ 1499*/0x06AA, 2075, 12, 9,/* 0 1 0 1 0 1 0 1 0 1 1 0 12/9/2075
+ 1500*/0x0E93, 2076, 11, 27,/* 1 1 0 0 1 0 0 1 0 1 1 1 11/27/2076
+ 1501*/ 0, 2077, 11, 17,/* 0 0 0 0 0 0 0 0 0 0 0 0 11/17/2077
+ */ };
+ // Direct inline initialization of DateMapping array would produce a lot of code bloat.
+
+ // We take advantage of C# compiler compiles inline initialization of primitive type array into very compact code.
+ // So we start with raw data stored in primitive type array, and initialize the DateMapping out of it
+
+ DateMapping[] mapping = new DateMapping[rawData.Length / 4];
+ for (int i = 0; i < mapping.Length; i++)
+ mapping[i] = new DateMapping(rawData[i * 4], rawData[i * 4 + 1], rawData[i * 4 + 2], rawData[i * 4 + 3]);
+ return mapping;
+ }
+
+ public const int UmAlQuraEra = 1;
+
+ internal const int DateCycle = 30;
+ internal const int DatePartYear = 0;
+ internal const int DatePartDayOfYear = 1;
+ internal const int DatePartMonth = 2;
+ internal const int DatePartDay = 3;
+
+
+ // This is the minimal Gregorian date that we support in the UmAlQuraCalendar.
+ internal static DateTime minDate = new DateTime(1900, 4, 30);
+ internal static DateTime maxDate = new DateTime((new DateTime(2077, 11, 16, 23, 59, 59, 999)).Ticks + 9999);
+
+ public override DateTime MinSupportedDateTime
+ {
+ get
+ {
+ return (minDate);
+ }
+ }
+
+ public override DateTime MaxSupportedDateTime
+ {
+ get
+ {
+ return (maxDate);
+ }
+ }
+
+ public override CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.LunarCalendar;
+ }
+ }
+
+ public UmAlQuraCalendar()
+ {
+ }
+
+ internal override CalendarId BaseCalendarID
+ {
+ get
+ {
+ return (CalendarId.HIJRI);
+ }
+ }
+
+ internal override CalendarId ID
+ {
+ get
+ {
+ return (CalendarId.UMALQURA);
+ }
+ }
+
+ protected override int DaysInYearBeforeMinSupportedYear
+ {
+ get
+ {
+ // HijriCalendar has same number of days as UmAlQuraCalendar for any given year
+ // HijriCalendar says year 1317 has 355 days.
+ return 355;
+ }
+ }
+
+ /*==========================ConvertHijriToGregorian==========================
+ ** Purpose: convert Hdate(year,month,day) to Gdate(year,month,day)
+ ** Arguments:
+ ** Input/Ouput: Hijrah date: year:yh, month:mh, day:dh
+ ** Output: Gregorian date: year:yg, month:mg, day:dg , day of week:dayweek
+ ** and returns flag found:1 not found:0
+ =========================ConvertHijriToGregorian============================*/
+ private static void ConvertHijriToGregorian(int HijriYear, int HijriMonth, int HijriDay, ref int yg, ref int mg, ref int dg)
+ {
+ Debug.Assert((HijriYear >= MinCalendarYear) && (HijriYear <= MaxCalendarYear), "Hijri year is out of range.");
+ Debug.Assert(HijriMonth >= 1, "Hijri month is out of range.");
+ Debug.Assert(HijriDay >= 1, "Hijri day is out of range.");
+ int index, b, nDays = HijriDay - 1;
+ DateTime dt;
+
+
+ index = HijriYear - MinCalendarYear;
+ dt = s_hijriYearInfo[index].GregorianDate;
+
+
+ b = s_hijriYearInfo[index].HijriMonthsLengthFlags;
+
+ for (int m = 1; m < HijriMonth; m++)
+ {
+ nDays = nDays + 29 + (b & 1); /* Add the months lengths before mh */
+ b = b >> 1;
+ }
+
+ dt = dt.AddDays(nDays);
+ yg = dt.Year;
+ mg = dt.Month;
+ dg = dt.Day;
+ }
+
+ /*=================================GetAbsoluteDateUmAlQura==========================
+ **Action: Gets the Absolute date for the given UmAlQura date. The absolute date means
+ ** the number of days from January 1st, 1 A.D.
+ **Returns:
+ **Arguments:
+ **Exceptions:
+ ============================================================================*/
+ private static long GetAbsoluteDateUmAlQura(int year, int month, int day)
+ {
+ //Caller should check the validaty of year, month and day.
+
+ int yg = 0, mg = 0, dg = 0;
+ ConvertHijriToGregorian(year, month, day, ref yg, ref mg, ref dg);
+ return GregorianCalendar.GetAbsoluteDate(yg, mg, dg);
+ }
+
+ internal static void CheckTicksRange(long ticks)
+ {
+ if (ticks < minDate.Ticks || ticks > maxDate.Ticks)
+ {
+ throw new ArgumentOutOfRangeException(
+ "time",
+ String.Format(
+ CultureInfo.InvariantCulture,
+ SR.ArgumentOutOfRange_CalendarRange,
+ minDate,
+ maxDate));
+ }
+ }
+
+ internal static void CheckEraRange(int era)
+ {
+ if (era != CurrentEra && era != UmAlQuraEra)
+ {
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
+ }
+ }
+
+ internal static void CheckYearRange(int year, int era)
+ {
+ CheckEraRange(era);
+ if (year < MinCalendarYear || year > MaxCalendarYear)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(year),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ MinCalendarYear,
+ MaxCalendarYear));
+ }
+ }
+
+ internal static void CheckYearMonthRange(int year, int month, int era)
+ {
+ CheckYearRange(year, era);
+ if (month < 1 || month > 12)
+ {
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
+ }
+ }
+
+ /*========================ConvertGregorianToHijri============================
+ ** Purpose: convert DateTime to Hdate(year,month,day)
+ ** Arguments:
+ ** Input: DateTime
+ ** Output: Hijrah date: year:yh, month:mh, day:dh
+ ============================================================================*/
+ private static void ConvertGregorianToHijri(DateTime time, ref int HijriYear, ref int HijriMonth, ref int HijriDay)
+ {
+ int index, b, DaysPerThisMonth;
+ double nDays;
+ TimeSpan ts;
+ int yh1 = 0, mh1 = 0, dh1 = 0;
+
+ Debug.Assert((time.Ticks >= minDate.Ticks) && (time.Ticks <= maxDate.Ticks), "Gregorian date is out of range.");
+
+ // Find the index where we should start our search by quessing the Hijri year that we will be in HijriYearInfo.
+ // A Hijri year is 354 or 355 days. Use 355 days so that we will search from a lower index.
+
+ index = (int)((time.Ticks - minDate.Ticks) / Calendar.TicksPerDay) / 355;
+ do
+ {
+ } while (time.CompareTo(s_hijriYearInfo[++index].GregorianDate) > 0); //while greater
+
+ if (time.CompareTo(s_hijriYearInfo[index].GregorianDate) != 0)
+ {
+ index--;
+ }
+
+ ts = time.Subtract(s_hijriYearInfo[index].GregorianDate);
+ yh1 = index + MinCalendarYear;
+
+ mh1 = 1;
+ dh1 = 1;
+ nDays = ts.TotalDays;
+ b = s_hijriYearInfo[index].HijriMonthsLengthFlags;
+ DaysPerThisMonth = 29 + (b & 1);
+
+ while (nDays >= DaysPerThisMonth)
+ {
+ nDays -= DaysPerThisMonth;
+ b = b >> 1;
+ DaysPerThisMonth = 29 + (b & 1);
+ mh1++;
+ }
+ dh1 += (int)nDays;
+
+ HijriDay = dh1;
+ HijriMonth = mh1;
+ HijriYear = yh1;
+ }
+
+ /*=================================GetDatePart==========================
+ **Action: Returns a given date part of this <i>DateTime</i>. This method is used
+ ** to compute the year, day-of-year, month, or day part.
+ **Returns:
+ **Arguments:
+ **Exceptions: ArgumentException if part is incorrect.
+ **Notes:
+ ** First, we get the absolute date (the number of days from January 1st, 1 A.C) for the given ticks.
+ ** Use the formula (((AbsoluteDate - 226894) * 33) / (33 * 365 + 8)) + 1, we can a rough value for the UmAlQura year.
+ ** In order to get the exact UmAlQura year, we compare the exact absolute date for UmAlQuraYear and (UmAlQuraYear + 1).
+ ** From here, we can get the correct UmAlQura year.
+ ============================================================================*/
+
+ internal virtual int GetDatePart(DateTime time, int part)
+ {
+ int UmAlQuraYear = 0; // UmAlQura year
+ int UmAlQuraMonth = 0; // UmAlQura month
+ int UmAlQuraDay = 0; // UmAlQura day
+ long ticks = time.Ticks;
+ CheckTicksRange(ticks);
+
+ ConvertGregorianToHijri(time, ref UmAlQuraYear, ref UmAlQuraMonth, ref UmAlQuraDay);
+
+ if (part == DatePartYear)
+ return (UmAlQuraYear);
+
+ if (part == DatePartMonth)
+ return (UmAlQuraMonth);
+
+ if (part == DatePartDay)
+ return (UmAlQuraDay);
+
+ if (part == DatePartDayOfYear)
+ return (int)(GetAbsoluteDateUmAlQura(UmAlQuraYear, UmAlQuraMonth, UmAlQuraDay) - GetAbsoluteDateUmAlQura(UmAlQuraYear, 1, 1) + 1);
+
+ // Incorrect part value.
+ throw new InvalidOperationException(SR.InvalidOperation_DateTimeParsing);
+ }
+
+ // Returns the DateTime resulting from adding the given number of
+ // months to the specified DateTime. The result is computed by incrementing
+ // (or decrementing) the year and month parts of the specified DateTime by
+ // value months, and, if required, adjusting the day part of the
+ // resulting date downwards to the last day of the resulting month in the
+ // resulting year. The time-of-day part of the result is the same as the
+ // time-of-day part of the specified DateTime.
+ //
+ // In more precise terms, considering the specified DateTime to be of the
+ // form y / m / d + t, where y is the
+ // year, m is the month, d is the day, and t is the
+ // time-of-day, the result is y1 / m1 / d1 + t,
+ // where y1 and m1 are computed by adding value months
+ // to y and m, and d1 is the largest value less than
+ // or equal to d that denotes a valid day in month m1 of year
+ // y1.
+ //
+
+
+ public override DateTime AddMonths(DateTime time, int months)
+ {
+ if (months < -120000 || months > 120000)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(months),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ -120000,
+ 120000));
+ }
+ Contract.EndContractBlock();
+ // Get the date in UmAlQura calendar.
+ int y = GetDatePart(time, DatePartYear);
+ int m = GetDatePart(time, DatePartMonth);
+ int d = GetDatePart(time, DatePartDay);
+ int i = m - 1 + months;
+
+ if (i >= 0)
+ {
+ m = i % 12 + 1;
+ y = y + i / 12;
+ }
+ else
+ {
+ m = 12 + (i + 1) % 12;
+ y = y + (i - 11) / 12;
+ }
+
+ if (d > 29)
+ {
+ int days = GetDaysInMonth(y, m);
+ if (d > days)
+ {
+ d = days;
+ }
+ }
+ CheckYearRange(y, UmAlQuraEra);
+ DateTime dt = new DateTime(GetAbsoluteDateUmAlQura(y, m, d) * TicksPerDay + time.Ticks % TicksPerDay);
+ Calendar.CheckAddResult(dt.Ticks, MinSupportedDateTime, MaxSupportedDateTime);
+ return (dt);
+ }
+
+ // Returns the DateTime resulting from adding the given number of
+ // years to the specified DateTime. The result is computed by incrementing
+ // (or decrementing) the year part of the specified DateTime by value
+ // years. If the month and day of the specified DateTime is 2/29, and if the
+ // resulting year is not a leap year, the month and day of the resulting
+ // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
+ // parts of the result are the same as those of the specified DateTime.
+ //
+
+
+ public override DateTime AddYears(DateTime time, int years)
+ {
+ return (AddMonths(time, years * 12));
+ }
+
+ // Returns the day-of-month part of the specified DateTime. The returned
+ // value is an integer between 1 and 31.
+ //
+
+
+ public override int GetDayOfMonth(DateTime time)
+ {
+ return (GetDatePart(time, DatePartDay));
+ }
+
+ // Returns the day-of-week part of the specified DateTime. The returned value
+ // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
+ // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
+ // Thursday, 5 indicates Friday, and 6 indicates Saturday.
+ //
+
+
+ public override DayOfWeek GetDayOfWeek(DateTime time)
+ {
+ return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
+ }
+
+ // Returns the day-of-year part of the specified DateTime. The returned value
+ // is an integer between 1 and 354 or 355.
+ //
+
+
+ public override int GetDayOfYear(DateTime time)
+ {
+ return (GetDatePart(time, DatePartDayOfYear));
+ }
+
+ /*
+ internal bool CouldBeLeapYear(int year)
+ {
+ return ((((year * 11) + 14) % 30) < 11);
+ }
+ */
+
+ // Returns the number of days in the month given by the year and
+ // month arguments.
+ //
+
+
+ public override int GetDaysInMonth(int year, int month, int era)
+ {
+ CheckYearMonthRange(year, month, era);
+
+ if ((s_hijriYearInfo[year - MinCalendarYear].HijriMonthsLengthFlags & (1 << month - 1)) == 0)
+ return 29;
+ else
+ return 30;
+ }
+
+ internal static int RealGetDaysInYear(int year)
+ {
+ int days = 0, b;
+
+ Debug.Assert((year >= MinCalendarYear) && (year <= MaxCalendarYear), "Hijri year is out of range.");
+
+ b = s_hijriYearInfo[year - MinCalendarYear].HijriMonthsLengthFlags;
+
+ for (int m = 1; m <= 12; m++)
+ {
+ days = days + 29 + (b & 1); /* Add the months lengths before mh */
+ b = b >> 1;
+ }
+ Debug.Assert((days == 354) || (days == 355), "Hijri year has to be 354 or 355 days.");
+ return days;
+ }
+
+ // Returns the number of days in the year given by the year argument for the current era.
+ //
+
+
+ public override int GetDaysInYear(int year, int era)
+ {
+ CheckYearRange(year, era);
+ return (RealGetDaysInYear(year));
+ }
+
+ // Returns the era for the specified DateTime value.
+
+
+ public override int GetEra(DateTime time)
+ {
+ CheckTicksRange(time.Ticks);
+ return (UmAlQuraEra);
+ }
+
+
+
+ public override int[] Eras
+ {
+ get
+ {
+ return (new int[] { UmAlQuraEra });
+ }
+ }
+
+ // Returns the month part of the specified DateTime. The returned value is an
+ // integer between 1 and 12.
+ //
+
+
+ public override int GetMonth(DateTime time)
+ {
+ return (GetDatePart(time, DatePartMonth));
+ }
+
+ // Returns the number of months in the specified year and era.
+
+
+ public override int GetMonthsInYear(int year, int era)
+ {
+ CheckYearRange(year, era);
+ return (12);
+ }
+
+ // Returns the year part of the specified DateTime. The returned value is an
+ // integer between MinCalendarYear and MaxCalendarYear.
+ //
+
+
+ public override int GetYear(DateTime time)
+ {
+ return (GetDatePart(time, DatePartYear));
+ }
+
+ // Checks whether a given day in the specified era is a leap day. This method returns true if
+ // the date is a leap day, or false if not.
+ //
+
+
+ public override bool IsLeapDay(int year, int month, int day, int era)
+ {
+ if (day >= 1 && day <= 29)
+ {
+ CheckYearMonthRange(year, month, era);
+ return (false);
+ }
+
+ // The year/month/era value checking is done in GetDaysInMonth().
+ int daysInMonth = GetDaysInMonth(year, month, era);
+ if (day < 1 || day > daysInMonth)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(day),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Day,
+ daysInMonth,
+ month));
+ }
+ return (false);
+ }
+
+ // Returns the leap month in a calendar year of the specified era. This method returns 0
+ // if this calendar does not have leap month, or this year is not a leap year.
+ //
+
+
+ public override int GetLeapMonth(int year, int era)
+ {
+ CheckYearRange(year, era);
+ return (0);
+ }
+
+ // Checks whether a given month in the specified era is a leap month. This method returns true if
+ // month is a leap month, or false if not.
+ //
+
+
+ public override bool IsLeapMonth(int year, int month, int era)
+ {
+ CheckYearMonthRange(year, month, era);
+ return (false);
+ }
+
+ // Checks whether a given year in the specified era is a leap year. This method returns true if
+ // year is a leap year, or false if not.
+ //
+
+
+ public override bool IsLeapYear(int year, int era)
+ {
+ CheckYearRange(year, era);
+ if (RealGetDaysInYear(year) == 355)
+ return true;
+ else
+ return false;
+ }
+
+ // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
+ //
+
+
+ public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
+ {
+ if (day >= 1 && day <= 29)
+ {
+ CheckYearMonthRange(year, month, era);
+ goto DayInRang;
+ }
+
+ // The year/month/era value checking is done in GetDaysInMonth().
+ int daysInMonth = GetDaysInMonth(year, month, era);
+
+ if (day < 1 || day > daysInMonth)
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(day),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Day,
+ daysInMonth,
+ month));
+ }
+ DayInRang:
+ long lDate = GetAbsoluteDateUmAlQura(year, month, day);
+
+ if (lDate >= 0)
+ {
+ return (new DateTime(lDate * GregorianCalendar.TicksPerDay + TimeToTicks(hour, minute, second, millisecond)));
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
+ }
+ }
+
+ private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 1451;
+
+
+
+ public override int TwoDigitYearMax
+ {
+ get
+ {
+ if (twoDigitYearMax == -1)
+ {
+ twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
+ }
+ return (twoDigitYearMax);
+ }
+
+ set
+ {
+ if (value != 99 && (value < MinCalendarYear || value > MaxCalendarYear))
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(value),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ MinCalendarYear,
+ MaxCalendarYear));
+ }
+ Contract.EndContractBlock();
+ VerifyWritable();
+ // We allow year 99 to be set so that one can make ToFourDigitYearMax a no-op by setting TwoDigitYearMax to 99.
+ twoDigitYearMax = value;
+ }
+ }
+
+
+
+ public override int ToFourDigitYear(int year)
+ {
+ if (year < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(year),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ }
+ Contract.EndContractBlock();
+
+ if (year < 100)
+ {
+ return (base.ToFourDigitYear(year));
+ }
+
+ if ((year < MinCalendarYear) || (year > MaxCalendarYear))
+ {
+ throw new ArgumentOutOfRangeException(
+ nameof(year),
+ String.Format(
+ CultureInfo.CurrentCulture,
+ SR.ArgumentOutOfRange_Range,
+ MinCalendarYear,
+ MaxCalendarYear));
+ }
+ return (year);
+ }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Globalization/UnicodeCategory.cs b/src/mscorlib/shared/System/Globalization/UnicodeCategory.cs
new file mode 100644
index 0000000000..f0ae1fdfd9
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/UnicodeCategory.cs
@@ -0,0 +1,40 @@
+// 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.
+
+namespace System.Globalization
+{
+ public enum UnicodeCategory
+ {
+ UppercaseLetter = 0,
+ LowercaseLetter = 1,
+ TitlecaseLetter = 2,
+ ModifierLetter = 3,
+ OtherLetter = 4,
+ NonSpacingMark = 5,
+ SpacingCombiningMark = 6,
+ EnclosingMark = 7,
+ DecimalDigitNumber = 8,
+ LetterNumber = 9,
+ OtherNumber = 10,
+ SpaceSeparator = 11,
+ LineSeparator = 12,
+ ParagraphSeparator = 13,
+ Control = 14,
+ Format = 15,
+ Surrogate = 16,
+ PrivateUse = 17,
+ ConnectorPunctuation = 18,
+ DashPunctuation = 19,
+ OpenPunctuation = 20,
+ ClosePunctuation = 21,
+ InitialQuotePunctuation = 22,
+ FinalQuotePunctuation = 23,
+ OtherPunctuation = 24,
+ MathSymbol = 25,
+ CurrencySymbol = 26,
+ ModifierSymbol = 27,
+ OtherSymbol = 28,
+ OtherNotAssigned = 29,
+ }
+}
diff --git a/src/mscorlib/src/System/IAsyncResult.cs b/src/mscorlib/shared/System/IAsyncResult.cs
index 0abeaca525..0abeaca525 100644
--- a/src/mscorlib/src/System/IAsyncResult.cs
+++ b/src/mscorlib/shared/System/IAsyncResult.cs
diff --git a/src/mscorlib/shared/System/ICloneable.cs b/src/mscorlib/shared/System/ICloneable.cs
new file mode 100644
index 0000000000..9f123e45c8
--- /dev/null
+++ b/src/mscorlib/shared/System/ICloneable.cs
@@ -0,0 +1,11 @@
+// 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.
+
+namespace System
+{
+ public interface ICloneable
+ {
+ object Clone();
+ }
+}
diff --git a/src/mscorlib/src/System/IComparable.cs b/src/mscorlib/shared/System/IComparable.cs
index 72aeeb027c..72aeeb027c 100644
--- a/src/mscorlib/src/System/IComparable.cs
+++ b/src/mscorlib/shared/System/IComparable.cs
diff --git a/src/mscorlib/src/System/IConvertible.cs b/src/mscorlib/shared/System/IConvertible.cs
index 87351127f2..87351127f2 100644
--- a/src/mscorlib/src/System/IConvertible.cs
+++ b/src/mscorlib/shared/System/IConvertible.cs
diff --git a/src/mscorlib/src/System/ICustomFormatter.cs b/src/mscorlib/shared/System/ICustomFormatter.cs
index 47340f3093..47340f3093 100644
--- a/src/mscorlib/src/System/ICustomFormatter.cs
+++ b/src/mscorlib/shared/System/ICustomFormatter.cs
diff --git a/src/mscorlib/src/System/IDisposable.cs b/src/mscorlib/shared/System/IDisposable.cs
index 24f0740edc..24f0740edc 100644
--- a/src/mscorlib/src/System/IDisposable.cs
+++ b/src/mscorlib/shared/System/IDisposable.cs
diff --git a/src/mscorlib/src/System/IEquatable.cs b/src/mscorlib/shared/System/IEquatable.cs
index 1264fdd57a..1264fdd57a 100644
--- a/src/mscorlib/src/System/IEquatable.cs
+++ b/src/mscorlib/shared/System/IEquatable.cs
diff --git a/src/mscorlib/src/System/IFormatProvider.cs b/src/mscorlib/shared/System/IFormatProvider.cs
index 0c17354af3..0c17354af3 100644
--- a/src/mscorlib/src/System/IFormatProvider.cs
+++ b/src/mscorlib/shared/System/IFormatProvider.cs
diff --git a/src/mscorlib/src/System/IFormattable.cs b/src/mscorlib/shared/System/IFormattable.cs
index 28a7d70571..28a7d70571 100644
--- a/src/mscorlib/src/System/IFormattable.cs
+++ b/src/mscorlib/shared/System/IFormattable.cs
diff --git a/src/mscorlib/shared/System/IO/DirectoryNotFoundException.cs b/src/mscorlib/shared/System/IO/DirectoryNotFoundException.cs
new file mode 100644
index 0000000000..786c2106a3
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/DirectoryNotFoundException.cs
@@ -0,0 +1,41 @@
+// 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.Runtime.Serialization;
+
+namespace System.IO
+{
+ /*
+ * Thrown when trying to access a directory that doesn't exist on disk.
+ * From COM Interop, this exception is thrown for 2 HRESULTS:
+ * the Win32 errorcode-as-HRESULT ERROR_PATH_NOT_FOUND (0x80070003)
+ * and STG_E_PATHNOTFOUND (0x80030003).
+ */
+ [Serializable]
+ public class DirectoryNotFoundException : IOException
+ {
+ public DirectoryNotFoundException()
+ : base(SR.Arg_DirectoryNotFoundException)
+ {
+ HResult = __HResults.COR_E_DIRECTORYNOTFOUND;
+ }
+
+ public DirectoryNotFoundException(string message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_DIRECTORYNOTFOUND;
+ }
+
+ public DirectoryNotFoundException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_DIRECTORYNOTFOUND;
+ }
+
+ protected DirectoryNotFoundException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/EndOfStreamException.cs b/src/mscorlib/shared/System/IO/EndOfStreamException.cs
new file mode 100644
index 0000000000..7c4b2b744f
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/EndOfStreamException.cs
@@ -0,0 +1,35 @@
+// 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.Runtime.Serialization;
+
+namespace System.IO
+{
+ [Serializable]
+ public class EndOfStreamException : IOException
+ {
+ public EndOfStreamException()
+ : base(SR.Arg_EndOfStreamException)
+ {
+ HResult = __HResults.COR_E_ENDOFSTREAM;
+ }
+
+ public EndOfStreamException(string message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_ENDOFSTREAM;
+ }
+
+ public EndOfStreamException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_ENDOFSTREAM;
+ }
+
+ protected EndOfStreamException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/Error.cs b/src/mscorlib/shared/System/IO/Error.cs
new file mode 100644
index 0000000000..2aef895181
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/Error.cs
@@ -0,0 +1,49 @@
+// 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.InteropServices;
+using System.Text;
+using System.Globalization;
+using System.Diagnostics.Contracts;
+
+namespace System.IO
+{
+ /// <summary>
+ /// Provides centralized methods for creating exceptions for System.IO.FileSystem.
+ /// </summary>
+ [Pure]
+ internal static class Error
+ {
+ internal static Exception GetStreamIsClosed()
+ {
+ return new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed);
+ }
+
+ internal static Exception GetEndOfFile()
+ {
+ return new EndOfStreamException(SR.IO_EOF_ReadBeyondEOF);
+ }
+
+ internal static Exception GetFileNotOpen()
+ {
+ return new ObjectDisposedException(null, SR.ObjectDisposed_FileClosed);
+ }
+
+ internal static Exception GetReadNotSupported()
+ {
+ return new NotSupportedException(SR.NotSupported_UnreadableStream);
+ }
+
+ internal static Exception GetSeekNotSupported()
+ {
+ return new NotSupportedException(SR.NotSupported_UnseekableStream);
+ }
+
+ internal static Exception GetWriteNotSupported()
+ {
+ return new NotSupportedException(SR.NotSupported_UnwritableStream);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/FileAccess.cs b/src/mscorlib/shared/System/IO/FileAccess.cs
new file mode 100644
index 0000000000..c6e583b34a
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/FileAccess.cs
@@ -0,0 +1,29 @@
+// 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;
+
+namespace System.IO
+{
+ // Contains constants for specifying the access you want for a file.
+ // You can have Read, Write or ReadWrite access.
+ //
+ [Serializable]
+ [Flags]
+ public enum FileAccess
+ {
+ // Specifies read access to the file. Data can be read from the file and
+ // the file pointer can be moved. Combine with WRITE for read-write access.
+ Read = 1,
+
+ // Specifies write access to the file. Data can be written to the file and
+ // the file pointer can be moved. Combine with READ for read-write access.
+ Write = 2,
+
+ // Specifies read and write access to the file. Data can be written to the
+ // file and the file pointer can be moved. Data can also be read from the
+ // file.
+ ReadWrite = 3,
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/FileLoadException.cs b/src/mscorlib/shared/System/IO/FileLoadException.cs
new file mode 100644
index 0000000000..b5e197c143
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/FileLoadException.cs
@@ -0,0 +1,102 @@
+// 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.Runtime.Serialization;
+
+namespace System.IO
+{
+ [Serializable]
+ public partial class FileLoadException : IOException
+ {
+ public FileLoadException()
+ : base(SR.IO_FileLoad)
+ {
+ HResult = __HResults.COR_E_FILELOAD;
+ }
+
+ public FileLoadException(string message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_FILELOAD;
+ }
+
+ public FileLoadException(string message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_FILELOAD;
+ }
+
+ public FileLoadException(string message, string fileName) : base(message)
+ {
+ HResult = __HResults.COR_E_FILELOAD;
+ FileName = fileName;
+ }
+
+ public FileLoadException(string message, string fileName, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_FILELOAD;
+ FileName = fileName;
+ }
+
+ public override string Message
+ {
+ get
+ {
+ if (_message == null)
+ {
+ _message = FormatFileLoadExceptionMessage(FileName, HResult);
+ }
+ return _message;
+ }
+ }
+
+ public string FileName { get; }
+ public string FusionLog { get; }
+
+ public override string ToString()
+ {
+ string s = GetType().ToString() + ": " + Message;
+
+ if (FileName != null && FileName.Length != 0)
+ s += Environment.NewLine + SR.Format(SR.IO_FileName_Name, FileName);
+
+ if (InnerException != null)
+ s = s + " ---> " + InnerException.ToString();
+
+ if (StackTrace != null)
+ s += Environment.NewLine + StackTrace;
+
+ if (FusionLog != null)
+ {
+ if (s == null)
+ s = " ";
+ s += Environment.NewLine;
+ s += Environment.NewLine;
+ s += FusionLog;
+ }
+
+ return s;
+ }
+
+ protected FileLoadException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ // Base class constructor will check info != null.
+
+ FileName = info.GetString("FileLoad_FileName");
+ FusionLog = info.GetString("FileLoad_FusionLog");
+ }
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ // Serialize data for our base classes. base will verify info != null.
+ base.GetObjectData(info, context);
+
+ // Serialize data for this class
+ info.AddValue("FileLoad_FileName", FileName, typeof(string));
+ info.AddValue("FileLoad_FusionLog", FusionLog, typeof(string));
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/FileMode.cs b/src/mscorlib/shared/System/IO/FileMode.cs
new file mode 100644
index 0000000000..77f2fe6f20
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/FileMode.cs
@@ -0,0 +1,38 @@
+// 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.
+
+namespace System.IO
+{
+ // Contains constants for specifying how the OS should open a file.
+ // These will control whether you overwrite a file, open an existing
+ // file, or some combination thereof.
+ //
+ // To append to a file, use Append (which maps to OpenOrCreate then we seek
+ // to the end of the file). To truncate a file or create it if it doesn't
+ // exist, use Create.
+ //
+ public enum FileMode
+ {
+ // Creates a new file. An exception is raised if the file already exists.
+ CreateNew = 1,
+
+ // Creates a new file. If the file already exists, it is overwritten.
+ Create = 2,
+
+ // Opens an existing file. An exception is raised if the file does not exist.
+ Open = 3,
+
+ // Opens the file if it exists. Otherwise, creates a new file.
+ OpenOrCreate = 4,
+
+ // Opens an existing file. Once opened, the file is truncated so that its
+ // size is zero bytes. The calling process must open the file with at least
+ // WRITE access. An exception is raised if the file does not exist.
+ Truncate = 5,
+
+ // Opens the file if it exists and seeks to the end. Otherwise,
+ // creates a new file.
+ Append = 6,
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/FileNotFoundException.cs b/src/mscorlib/shared/System/IO/FileNotFoundException.cs
new file mode 100644
index 0000000000..5d86b8f635
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/FileNotFoundException.cs
@@ -0,0 +1,114 @@
+// 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.Runtime.Serialization;
+
+namespace System.IO
+{
+ // Thrown when trying to access a file that doesn't exist on disk.
+ [Serializable]
+ public partial class FileNotFoundException : IOException
+ {
+ public FileNotFoundException()
+ : base(SR.IO_FileNotFound)
+ {
+ HResult = __HResults.COR_E_FILENOTFOUND;
+ }
+
+ public FileNotFoundException(string message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_FILENOTFOUND;
+ }
+
+ public FileNotFoundException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_FILENOTFOUND;
+ }
+
+ public FileNotFoundException(string message, string fileName)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_FILENOTFOUND;
+ FileName = fileName;
+ }
+
+ public FileNotFoundException(string message, string fileName, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_FILENOTFOUND;
+ FileName = fileName;
+ }
+
+ public override string Message
+ {
+ get
+ {
+ SetMessageField();
+ return _message;
+ }
+ }
+
+ private void SetMessageField()
+ {
+ if (_message == null)
+ {
+ if ((FileName == null) &&
+ (HResult == System.__HResults.COR_E_EXCEPTION))
+ _message = SR.IO_FileNotFound;
+
+ else if (FileName != null)
+ _message = FileLoadException.FormatFileLoadExceptionMessage(FileName, HResult);
+ }
+ }
+
+ public string FileName { get; }
+ public string FusionLog { get; }
+
+ public override string ToString()
+ {
+ string s = GetType().ToString() + ": " + Message;
+
+ if (FileName != null && FileName.Length != 0)
+ s += Environment.NewLine + SR.Format(SR.IO_FileName_Name, FileName);
+
+ if (InnerException != null)
+ s = s + " ---> " + InnerException.ToString();
+
+ if (StackTrace != null)
+ s += Environment.NewLine + StackTrace;
+
+ if (FusionLog != null)
+ {
+ if (s == null)
+ s = " ";
+ s += Environment.NewLine;
+ s += Environment.NewLine;
+ s += FusionLog;
+ }
+ return s;
+ }
+
+ protected FileNotFoundException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ // Base class constructor will check info != null.
+
+ FileName = info.GetString("FileNotFound_FileName");
+ FusionLog = info.GetString("FileNotFound_FusionLog");
+ }
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ // Serialize data for our base classes. base will verify info != null.
+ base.GetObjectData(info, context);
+
+ // Serialize data for this class
+ info.AddValue("FileNotFound_FileName", FileName, typeof(string));
+ info.AddValue("FileNotFound_FusionLog", FusionLog, typeof(string));
+ }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/IO/FileOptions.cs b/src/mscorlib/shared/System/IO/FileOptions.cs
new file mode 100644
index 0000000000..ae8396a588
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/FileOptions.cs
@@ -0,0 +1,33 @@
+// 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.InteropServices;
+
+namespace System.IO
+{
+ // Maps to FILE_FLAG_DELETE_ON_CLOSE and similar values from winbase.h.
+ // We didn't expose a number of these values because we didn't believe
+ // a number of them made sense in managed code, at least not yet.
+ [Flags]
+ public enum FileOptions
+ {
+ // NOTE: any change to FileOptions enum needs to be
+ // matched in the FileStream ctor for error validation
+ None = 0,
+ WriteThrough = unchecked((int)0x80000000),
+ Asynchronous = unchecked((int)0x40000000), // FILE_FLAG_OVERLAPPED
+ // NoBuffering = 0x20000000,
+ RandomAccess = 0x10000000,
+ DeleteOnClose = 0x04000000,
+ SequentialScan = 0x08000000,
+ // AllowPosix = 0x01000000, // FILE_FLAG_POSIX_SEMANTICS
+ // BackupOrRestore,
+ // DisallowReparsePoint = 0x00200000, // FILE_FLAG_OPEN_REPARSE_POINT
+ // NoRemoteRecall = 0x00100000, // FILE_FLAG_OPEN_NO_RECALL
+ // FirstPipeInstance = 0x00080000, // FILE_FLAG_FIRST_PIPE_INSTANCE
+ Encrypted = 0x00004000, // FILE_ATTRIBUTE_ENCRYPTED
+ }
+}
+
diff --git a/src/mscorlib/shared/System/IO/FileShare.cs b/src/mscorlib/shared/System/IO/FileShare.cs
new file mode 100644
index 0000000000..e9b9b5e32f
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/FileShare.cs
@@ -0,0 +1,45 @@
+// 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;
+
+namespace System.IO
+{
+ // Contains constants for controlling file sharing options while
+ // opening files. You can specify what access other processes trying
+ // to open the same file concurrently can have.
+ //
+ // Note these values currently match the values for FILE_SHARE_READ,
+ // FILE_SHARE_WRITE, and FILE_SHARE_DELETE in winnt.h
+ //
+ [Flags]
+ public enum FileShare
+ {
+ // No sharing. Any request to open the file (by this process or another
+ // process) will fail until the file is closed.
+ None = 0,
+
+ // Allows subsequent opening of the file for reading. If this flag is not
+ // specified, any request to open the file for reading (by this process or
+ // another process) will fail until the file is closed.
+ Read = 1,
+
+ // Allows subsequent opening of the file for writing. If this flag is not
+ // specified, any request to open the file for writing (by this process or
+ // another process) will fail until the file is closed.
+ Write = 2,
+
+ // Allows subsequent opening of the file for writing or reading. If this flag
+ // is not specified, any request to open the file for writing or reading (by
+ // this process or another process) will fail until the file is closed.
+ ReadWrite = 3,
+
+ // Open the file, but allow someone else to delete the file.
+ Delete = 4,
+
+ // Whether the file handle should be inheritable by child processes.
+ // Note this is not directly supported like this by Win32.
+ Inheritable = 0x10,
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/FileStream.Linux.cs b/src/mscorlib/shared/System/IO/FileStream.Linux.cs
new file mode 100644
index 0000000000..873c4eb559
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/FileStream.Linux.cs
@@ -0,0 +1,30 @@
+// 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 Microsoft.Win32.SafeHandles;
+using System.Diagnostics;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace System.IO
+{
+ public partial class FileStream : Stream
+ {
+ /// <summary>Prevents other processes from reading from or writing to the FileStream.</summary>
+ /// <param name="position">The beginning of the range to lock.</param>
+ /// <param name="length">The range to be locked.</param>
+ private void LockInternal(long position, long length)
+ {
+ CheckFileCall(Interop.Sys.LockFileRegion(_fileHandle, position, length, Interop.Sys.LockType.F_WRLCK));
+ }
+
+ /// <summary>Allows access by other processes to all or part of a file that was previously locked.</summary>
+ /// <param name="position">The beginning of the range to unlock.</param>
+ /// <param name="length">The range to be unlocked.</param>
+ private void UnlockInternal(long position, long length)
+ {
+ CheckFileCall(Interop.Sys.LockFileRegion(_fileHandle, position, length, Interop.Sys.LockType.F_UNLCK));
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/FileStream.OSX.cs b/src/mscorlib/shared/System/IO/FileStream.OSX.cs
new file mode 100644
index 0000000000..f29e922337
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/FileStream.OSX.cs
@@ -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.
+
+namespace System.IO
+{
+ public partial class FileStream : Stream
+ {
+ private void LockInternal(long position, long length)
+ {
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_OSXFileLocking);
+ }
+
+ private void UnlockInternal(long position, long length)
+ {
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_OSXFileLocking);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/FileStream.Unix.cs b/src/mscorlib/shared/System/IO/FileStream.Unix.cs
new file mode 100644
index 0000000000..7d860ac2fe
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/FileStream.Unix.cs
@@ -0,0 +1,933 @@
+// 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 Microsoft.Win32.SafeHandles;
+using System.Diagnostics;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace System.IO
+{
+ /// <summary>Provides an implementation of a file stream for Unix files.</summary>
+ public partial class FileStream : Stream
+ {
+ /// <summary>File mode.</summary>
+ private FileMode _mode;
+
+ /// <summary>Advanced options requested when opening the file.</summary>
+ private FileOptions _options;
+
+ /// <summary>If the file was opened with FileMode.Append, the length of the file when opened; otherwise, -1.</summary>
+ private long _appendStart = -1;
+
+ /// <summary>
+ /// Extra state used by the file stream when _useAsyncIO is true. This includes
+ /// the semaphore used to serialize all operation, the buffer/offset/count provided by the
+ /// caller for ReadAsync/WriteAsync operations, and the last successful task returned
+ /// synchronously from ReadAsync which can be reused if the count matches the next request.
+ /// Only initialized when <see cref="_useAsyncIO"/> is true.
+ /// </summary>
+ private AsyncState _asyncState;
+
+ /// <summary>Lazily-initialized value for whether the file supports seeking.</summary>
+ private bool? _canSeek;
+
+ private SafeFileHandle OpenHandle(FileMode mode, FileShare share, FileOptions options)
+ {
+ // FileStream performs most of the general argument validation. We can assume here that the arguments
+ // are all checked and consistent (e.g. non-null-or-empty path; valid enums in mode, access, share, and options; etc.)
+ // Store the arguments
+ _mode = mode;
+ _options = options;
+
+ if (_useAsyncIO)
+ _asyncState = new AsyncState();
+
+ // Translate the arguments into arguments for an open call.
+ Interop.Sys.OpenFlags openFlags = PreOpenConfigurationFromOptions(mode, _access, share, options);
+
+ // If the file gets created a new, we'll select the permissions for it. Most Unix utilities by default use 666 (read and
+ // write for all), so we do the same (even though this doesn't match Windows, where by default it's possible to write out
+ // a file and then execute it). No matter what we choose, it'll be subject to the umask applied by the system, such that the
+ // actual permissions will typically be less than what we select here.
+ const Interop.Sys.Permissions OpenPermissions =
+ Interop.Sys.Permissions.S_IRUSR | Interop.Sys.Permissions.S_IWUSR |
+ Interop.Sys.Permissions.S_IRGRP | Interop.Sys.Permissions.S_IWGRP |
+ Interop.Sys.Permissions.S_IROTH | Interop.Sys.Permissions.S_IWOTH;
+
+ // Open the file and store the safe handle.
+ return SafeFileHandle.Open(_path, openFlags, (int)OpenPermissions);
+ }
+
+ /// <summary>Initializes a stream for reading or writing a Unix file.</summary>
+ /// <param name="mode">How the file should be opened.</param>
+ /// <param name="share">What other access to the file should be allowed. This is currently ignored.</param>
+ private void Init(FileMode mode, FileShare share)
+ {
+ _fileHandle.IsAsync = _useAsyncIO;
+
+ // Lock the file if requested via FileShare. This is only advisory locking. FileShare.None implies an exclusive
+ // lock on the file and all other modes use a shared lock. While this is not as granular as Windows, not mandatory,
+ // and not atomic with file opening, it's better than nothing.
+ Interop.Sys.LockOperations lockOperation = (share == FileShare.None) ? Interop.Sys.LockOperations.LOCK_EX : Interop.Sys.LockOperations.LOCK_SH;
+ if (Interop.Sys.FLock(_fileHandle, lockOperation | Interop.Sys.LockOperations.LOCK_NB) < 0)
+ {
+ // The only error we care about is EWOULDBLOCK, which indicates that the file is currently locked by someone
+ // else and we would block trying to access it. Other errors, such as ENOTSUP (locking isn't supported) or
+ // EACCES (the file system doesn't allow us to lock), will only hamper FileStream's usage without providing value,
+ // given again that this is only advisory / best-effort.
+ Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo();
+ if (errorInfo.Error == Interop.Error.EWOULDBLOCK)
+ {
+ throw Interop.GetExceptionForIoErrno(errorInfo, _path, isDirectory: false);
+ }
+ }
+
+ // These provide hints around how the file will be accessed. Specifying both RandomAccess
+ // and Sequential together doesn't make sense as they are two competing options on the same spectrum,
+ // so if both are specified, we prefer RandomAccess (behavior on Windows is unspecified if both are provided).
+ Interop.Sys.FileAdvice fadv =
+ (_options & FileOptions.RandomAccess) != 0 ? Interop.Sys.FileAdvice.POSIX_FADV_RANDOM :
+ (_options & FileOptions.SequentialScan) != 0 ? Interop.Sys.FileAdvice.POSIX_FADV_SEQUENTIAL :
+ 0;
+ if (fadv != 0)
+ {
+ CheckFileCall(Interop.Sys.PosixFAdvise(_fileHandle, 0, 0, fadv),
+ ignoreNotSupported: true); // just a hint.
+ }
+
+ // Jump to the end of the file if opened as Append.
+ if (_mode == FileMode.Append)
+ {
+ _appendStart = SeekCore(0, SeekOrigin.End);
+ }
+ }
+
+ /// <summary>Initializes a stream from an already open file handle (file descriptor).</summary>
+ /// <param name="handle">The handle to the file.</param>
+ /// <param name="bufferSize">The size of the buffer to use when buffering.</param>
+ /// <param name="useAsyncIO">Whether access to the stream is performed asynchronously.</param>
+ private void InitFromHandle(SafeFileHandle handle)
+ {
+ if (_useAsyncIO)
+ _asyncState = new AsyncState();
+
+ if (CanSeekCore) // use non-virtual CanSeekCore rather than CanSeek to avoid making virtual call during ctor
+ SeekCore(0, SeekOrigin.Current);
+ }
+
+ /// <summary>Translates the FileMode, FileAccess, and FileOptions values into flags to be passed when opening the file.</summary>
+ /// <param name="mode">The FileMode provided to the stream's constructor.</param>
+ /// <param name="access">The FileAccess provided to the stream's constructor</param>
+ /// <param name="share">The FileShare provided to the stream's constructor</param>
+ /// <param name="options">The FileOptions provided to the stream's constructor</param>
+ /// <returns>The flags value to be passed to the open system call.</returns>
+ private static Interop.Sys.OpenFlags PreOpenConfigurationFromOptions(FileMode mode, FileAccess access, FileShare share, FileOptions options)
+ {
+ // Translate FileMode. Most of the values map cleanly to one or more options for open.
+ Interop.Sys.OpenFlags flags = default(Interop.Sys.OpenFlags);
+ switch (mode)
+ {
+ default:
+ case FileMode.Open: // Open maps to the default behavior for open(...). No flags needed.
+ break;
+
+ case FileMode.Append: // Append is the same as OpenOrCreate, except that we'll also separately jump to the end later
+ case FileMode.OpenOrCreate:
+ flags |= Interop.Sys.OpenFlags.O_CREAT;
+ break;
+
+ case FileMode.Create:
+ flags |= (Interop.Sys.OpenFlags.O_CREAT | Interop.Sys.OpenFlags.O_TRUNC);
+ break;
+
+ case FileMode.CreateNew:
+ flags |= (Interop.Sys.OpenFlags.O_CREAT | Interop.Sys.OpenFlags.O_EXCL);
+ break;
+
+ case FileMode.Truncate:
+ flags |= Interop.Sys.OpenFlags.O_TRUNC;
+ break;
+ }
+
+ // Translate FileAccess. All possible values map cleanly to corresponding values for open.
+ switch (access)
+ {
+ case FileAccess.Read:
+ flags |= Interop.Sys.OpenFlags.O_RDONLY;
+ break;
+
+ case FileAccess.ReadWrite:
+ flags |= Interop.Sys.OpenFlags.O_RDWR;
+ break;
+
+ case FileAccess.Write:
+ flags |= Interop.Sys.OpenFlags.O_WRONLY;
+ break;
+ }
+
+ // Handle Inheritable, other FileShare flags are handled by Init
+ if ((share & FileShare.Inheritable) == 0)
+ {
+ flags |= Interop.Sys.OpenFlags.O_CLOEXEC;
+ }
+
+ // Translate some FileOptions; some just aren't supported, and others will be handled after calling open.
+ // - Asynchronous: Handled in ctor, setting _useAsync and SafeFileHandle.IsAsync to true
+ // - DeleteOnClose: Doesn't have a Unix equivalent, but we approximate it in Dispose
+ // - Encrypted: No equivalent on Unix and is ignored
+ // - RandomAccess: Implemented after open if posix_fadvise is available
+ // - SequentialScan: Implemented after open if posix_fadvise is available
+ // - WriteThrough: Handled here
+ if ((options & FileOptions.WriteThrough) != 0)
+ {
+ flags |= Interop.Sys.OpenFlags.O_SYNC;
+ }
+
+ return flags;
+ }
+
+ /// <summary>Gets a value indicating whether the current stream supports seeking.</summary>
+ public override bool CanSeek => CanSeekCore;
+
+ /// <summary>Gets a value indicating whether the current stream supports seeking.</summary>
+ /// <remarks>Separated out of CanSeek to enable making non-virtual call to this logic.</remarks>
+ private bool CanSeekCore
+ {
+ get
+ {
+ if (_fileHandle.IsClosed)
+ {
+ return false;
+ }
+
+ if (!_canSeek.HasValue)
+ {
+ // Lazily-initialize whether we're able to seek, tested by seeking to our current location.
+ _canSeek = Interop.Sys.LSeek(_fileHandle, 0, Interop.Sys.SeekWhence.SEEK_CUR) >= 0;
+ }
+ return _canSeek.Value;
+ }
+ }
+
+ private long GetLengthInternal()
+ {
+ // Get the length of the file as reported by the OS
+ Interop.Sys.FileStatus status;
+ CheckFileCall(Interop.Sys.FStat(_fileHandle, out status));
+ long length = status.Size;
+
+ // But we may have buffered some data to be written that puts our length
+ // beyond what the OS is aware of. Update accordingly.
+ if (_writePos > 0 && _filePosition + _writePos > length)
+ {
+ length = _writePos + _filePosition;
+ }
+
+ return length;
+ }
+
+ /// <summary>Releases the unmanaged resources used by the stream.</summary>
+ /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
+ protected override void Dispose(bool disposing)
+ {
+ try
+ {
+ if (_fileHandle != null && !_fileHandle.IsClosed)
+ {
+ // Flush any remaining data in the file
+ try
+ {
+ FlushWriteBuffer();
+ }
+ catch (IOException) when (!disposing)
+ {
+ // On finalization, ignore failures from trying to flush the write buffer,
+ // e.g. if this stream is wrapping a pipe and the pipe is now broken.
+ }
+
+ // If DeleteOnClose was requested when constructed, delete the file now.
+ // (Unix doesn't directly support DeleteOnClose, so we mimic it here.)
+ if (_path != null && (_options & FileOptions.DeleteOnClose) != 0)
+ {
+ // Since we still have the file open, this will end up deleting
+ // it (assuming we're the only link to it) once it's closed, but the
+ // name will be removed immediately.
+ Interop.Sys.Unlink(_path); // ignore errors; it's valid that the path may no longer exist
+ }
+ }
+ }
+ finally
+ {
+ if (_fileHandle != null && !_fileHandle.IsClosed)
+ {
+ _fileHandle.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+ }
+
+ /// <summary>Flushes the OS buffer. This does not flush the internal read/write buffer.</summary>
+ private void FlushOSBuffer()
+ {
+ if (Interop.Sys.FSync(_fileHandle) < 0)
+ {
+ Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo();
+ switch (errorInfo.Error)
+ {
+ case Interop.Error.EROFS:
+ case Interop.Error.EINVAL:
+ case Interop.Error.ENOTSUP:
+ // Ignore failures due to the FileStream being bound to a special file that
+ // doesn't support synchronization. In such cases there's nothing to flush.
+ break;
+ default:
+ throw Interop.GetExceptionForIoErrno(errorInfo, _path, isDirectory: false);
+ }
+ }
+ }
+
+ /// <summary>Writes any data in the write buffer to the underlying stream and resets the buffer.</summary>
+ private void FlushWriteBuffer()
+ {
+ AssertBufferInvariants();
+ if (_writePos > 0)
+ {
+ WriteNative(GetBuffer(), 0, _writePos);
+ _writePos = 0;
+ }
+ }
+
+ /// <summary>Asynchronously clears all buffers for this stream, causing any buffered data to be written to the underlying device.</summary>
+ /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
+ /// <returns>A task that represents the asynchronous flush operation.</returns>
+ private Task FlushAsyncInternal(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return Task.FromCanceled(cancellationToken);
+ }
+ if (_fileHandle.IsClosed)
+ {
+ throw Error.GetFileNotOpen();
+ }
+
+ // As with Win32FileStream, flush the buffers synchronously to avoid race conditions.
+ try
+ {
+ FlushInternalBuffer();
+ }
+ catch (Exception e)
+ {
+ return Task.FromException(e);
+ }
+
+ // We then separately flush to disk asynchronously. This is only
+ // necessary if we support writing; otherwise, we're done.
+ if (CanWrite)
+ {
+ return Task.Factory.StartNew(
+ state => ((FileStream)state).FlushOSBuffer(),
+ this,
+ cancellationToken,
+ TaskCreationOptions.DenyChildAttach,
+ TaskScheduler.Default);
+ }
+ else
+ {
+ return Task.CompletedTask;
+ }
+ }
+
+ /// <summary>Sets the length of this stream to the given value.</summary>
+ /// <param name="value">The new length of the stream.</param>
+ private void SetLengthInternal(long value)
+ {
+ FlushInternalBuffer();
+
+ if (_appendStart != -1 && value < _appendStart)
+ {
+ throw new IOException(SR.IO_SetLengthAppendTruncate);
+ }
+
+ long origPos = _filePosition;
+
+ VerifyOSHandlePosition();
+
+ if (_filePosition != value)
+ {
+ SeekCore(value, SeekOrigin.Begin);
+ }
+
+ CheckFileCall(Interop.Sys.FTruncate(_fileHandle, value));
+
+ // Return file pointer to where it was before setting length
+ if (origPos != value)
+ {
+ if (origPos < value)
+ {
+ SeekCore(origPos, SeekOrigin.Begin);
+ }
+ else
+ {
+ SeekCore(0, SeekOrigin.End);
+ }
+ }
+ }
+
+ /// <summary>Reads a block of bytes from the stream and writes the data in a given buffer.</summary>
+ /// <param name="array">
+ /// When this method returns, contains the specified byte array with the values between offset and
+ /// (offset + count - 1) replaced by the bytes read from the current source.
+ /// </param>
+ /// <param name="offset">The byte offset in array at which the read bytes will be placed.</param>
+ /// <param name="count">The maximum number of bytes to read. </param>
+ /// <returns>
+ /// The total number of bytes read into the buffer. This might be less than the number of bytes requested
+ /// if that number of bytes are not currently available, or zero if the end of the stream is reached.
+ /// </returns>
+ public override int Read(byte[] array, int offset, int count)
+ {
+ ValidateReadWriteArgs(array, offset, count);
+
+ if (_useAsyncIO)
+ {
+ _asyncState.Wait();
+ try { return ReadCore(array, offset, count); }
+ finally { _asyncState.Release(); }
+ }
+ else
+ {
+ return ReadCore(array, offset, count);
+ }
+ }
+
+ /// <summary>Reads a block of bytes from the stream and writes the data in a given buffer.</summary>
+ /// <param name="array">
+ /// When this method returns, contains the specified byte array with the values between offset and
+ /// (offset + count - 1) replaced by the bytes read from the current source.
+ /// </param>
+ /// <param name="offset">The byte offset in array at which the read bytes will be placed.</param>
+ /// <param name="count">The maximum number of bytes to read. </param>
+ /// <returns>
+ /// The total number of bytes read into the buffer. This might be less than the number of bytes requested
+ /// if that number of bytes are not currently available, or zero if the end of the stream is reached.
+ /// </returns>
+ private int ReadCore(byte[] array, int offset, int count)
+ {
+ PrepareForReading();
+
+ // Are there any bytes available in the read buffer? If yes,
+ // we can just return from the buffer. If the buffer is empty
+ // or has no more available data in it, we can either refill it
+ // (and then read from the buffer into the user's buffer) or
+ // we can just go directly into the user's buffer, if they asked
+ // for more data than we'd otherwise buffer.
+ int numBytesAvailable = _readLength - _readPos;
+ bool readFromOS = false;
+ if (numBytesAvailable == 0)
+ {
+ // If we're not able to seek, then we're not able to rewind the stream (i.e. flushing
+ // a read buffer), in which case we don't want to use a read buffer. Similarly, if
+ // the user has asked for more data than we can buffer, we also want to skip the buffer.
+ if (!CanSeek || (count >= _bufferLength))
+ {
+ // Read directly into the user's buffer
+ _readPos = _readLength = 0;
+ return ReadNative(array, offset, count);
+ }
+ else
+ {
+ // Read into our buffer.
+ _readLength = numBytesAvailable = ReadNative(GetBuffer(), 0, _bufferLength);
+ _readPos = 0;
+ if (numBytesAvailable == 0)
+ {
+ return 0;
+ }
+
+ // Note that we did an OS read as part of this Read, so that later
+ // we don't try to do one again if what's in the buffer doesn't
+ // meet the user's request.
+ readFromOS = true;
+ }
+ }
+
+ // Now that we know there's data in the buffer, read from it into the user's buffer.
+ Debug.Assert(numBytesAvailable > 0, "Data must be in the buffer to be here");
+ int bytesRead = Math.Min(numBytesAvailable, count);
+ Buffer.BlockCopy(GetBuffer(), _readPos, array, offset, bytesRead);
+ _readPos += bytesRead;
+
+ // We may not have had enough data in the buffer to completely satisfy the user's request.
+ // While Read doesn't require that we return as much data as the user requested (any amount
+ // up to the requested count is fine), FileStream on Windows tries to do so by doing a
+ // subsequent read from the file if we tried to satisfy the request with what was in the
+ // buffer but the buffer contained less than the requested count. To be consistent with that
+ // behavior, we do the same thing here on Unix. Note that we may still get less the requested
+ // amount, as the OS may give us back fewer than we request, either due to reaching the end of
+ // file, or due to its own whims.
+ if (!readFromOS && bytesRead < count)
+ {
+ Debug.Assert(_readPos == _readLength, "bytesToRead should only be < count if numBytesAvailable < count");
+ _readPos = _readLength = 0; // no data left in the read buffer
+ bytesRead += ReadNative(array, offset + bytesRead, count - bytesRead);
+ }
+
+ return bytesRead;
+ }
+
+ /// <summary>Unbuffered, reads a block of bytes from the stream and writes the data in a given buffer.</summary>
+ /// <param name="array">
+ /// When this method returns, contains the specified byte array with the values between offset and
+ /// (offset + count - 1) replaced by the bytes read from the current source.
+ /// </param>
+ /// <param name="offset">The byte offset in array at which the read bytes will be placed.</param>
+ /// <param name="count">The maximum number of bytes to read. </param>
+ /// <returns>
+ /// The total number of bytes read into the buffer. This might be less than the number of bytes requested
+ /// if that number of bytes are not currently available, or zero if the end of the stream is reached.
+ /// </returns>
+ private unsafe int ReadNative(byte[] array, int offset, int count)
+ {
+ FlushWriteBuffer(); // we're about to read; dump the write buffer
+
+ VerifyOSHandlePosition();
+
+ int bytesRead;
+ fixed (byte* bufPtr = array)
+ {
+ bytesRead = CheckFileCall(Interop.Sys.Read(_fileHandle, bufPtr + offset, count));
+ Debug.Assert(bytesRead <= count);
+ }
+ _filePosition += bytesRead;
+ return bytesRead;
+ }
+
+ /// <summary>
+ /// Asynchronously reads a sequence of bytes from the current stream and advances
+ /// the position within the stream by the number of bytes read.
+ /// </summary>
+ /// <param name="buffer">The buffer to write the data into.</param>
+ /// <param name="offset">The byte offset in buffer at which to begin writing data from the stream.</param>
+ /// <param name="count">The maximum number of bytes to read.</param>
+ /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
+ /// <returns>A task that represents the asynchronous read operation.</returns>
+ private Task<int> ReadAsyncInternal(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ {
+ if (_useAsyncIO)
+ {
+ if (!CanRead) // match Windows behavior; this gets thrown synchronously
+ {
+ throw Error.GetReadNotSupported();
+ }
+
+ // Serialize operations using the semaphore.
+ Task waitTask = _asyncState.WaitAsync();
+
+ // If we got ownership immediately, and if there's enough data in our buffer
+ // to satisfy the full request of the caller, hand back the buffered data.
+ // While it would be a legal implementation of the Read contract, we don't
+ // hand back here less than the amount requested so as to match the behavior
+ // in ReadCore that will make a native call to try to fulfill the remainder
+ // of the request.
+ if (waitTask.Status == TaskStatus.RanToCompletion)
+ {
+ int numBytesAvailable = _readLength - _readPos;
+ if (numBytesAvailable >= count)
+ {
+ try
+ {
+ PrepareForReading();
+
+ Buffer.BlockCopy(GetBuffer(), _readPos, buffer, offset, count);
+ _readPos += count;
+
+ return _asyncState._lastSuccessfulReadTask != null && _asyncState._lastSuccessfulReadTask.Result == count ?
+ _asyncState._lastSuccessfulReadTask :
+ (_asyncState._lastSuccessfulReadTask = Task.FromResult(count));
+ }
+ catch (Exception exc)
+ {
+ return Task.FromException<int>(exc);
+ }
+ finally
+ {
+ _asyncState.Release();
+ }
+ }
+ }
+
+ // Otherwise, issue the whole request asynchronously.
+ _asyncState.Update(buffer, offset, count);
+ return waitTask.ContinueWith((t, s) =>
+ {
+ // The options available on Unix for writing asynchronously to an arbitrary file
+ // handle typically amount to just using another thread to do the synchronous write,
+ // which is exactly what this implementation does. This does mean there are subtle
+ // differences in certain FileStream behaviors between Windows and Unix when multiple
+ // asynchronous operations are issued against the stream to execute concurrently; on
+ // Unix the operations will be serialized due to the usage of a semaphore, but the
+ // position /length information won't be updated until after the write has completed,
+ // whereas on Windows it may happen before the write has completed.
+
+ Debug.Assert(t.Status == TaskStatus.RanToCompletion);
+ var thisRef = (FileStream)s;
+ try
+ {
+ byte[] b = thisRef._asyncState._buffer;
+ thisRef._asyncState._buffer = null; // remove reference to user's buffer
+ return thisRef.ReadCore(b, thisRef._asyncState._offset, thisRef._asyncState._count);
+ }
+ finally { thisRef._asyncState.Release(); }
+ }, this, CancellationToken.None, TaskContinuationOptions.DenyChildAttach, TaskScheduler.Default);
+ }
+ else
+ {
+ return base.ReadAsync(buffer, offset, count, cancellationToken);
+ }
+ }
+
+ /// <summary>
+ /// Reads a byte from the stream and advances the position within the stream
+ /// by one byte, or returns -1 if at the end of the stream.
+ /// </summary>
+ /// <returns>The unsigned byte cast to an Int32, or -1 if at the end of the stream.</returns>
+ public override int ReadByte()
+ {
+ if (_useAsyncIO)
+ {
+ _asyncState.Wait();
+ try { return ReadByteCore(); }
+ finally { _asyncState.Release(); }
+ }
+ else
+ {
+ return ReadByteCore();
+ }
+ }
+
+ /// <summary>Writes a block of bytes to the file stream.</summary>
+ /// <param name="array">The buffer containing data to write to the stream.</param>
+ /// <param name="offset">The zero-based byte offset in array from which to begin copying bytes to the stream.</param>
+ /// <param name="count">The maximum number of bytes to write.</param>
+ public override void Write(byte[] array, int offset, int count)
+ {
+ ValidateReadWriteArgs(array, offset, count);
+
+ if (_useAsyncIO)
+ {
+ _asyncState.Wait();
+ try { WriteCore(array, offset, count); }
+ finally { _asyncState.Release(); }
+ }
+ else
+ {
+ WriteCore(array, offset, count);
+ }
+ }
+
+ /// <summary>Writes a block of bytes to the file stream.</summary>
+ /// <param name="array">The buffer containing data to write to the stream.</param>
+ /// <param name="offset">The zero-based byte offset in array from which to begin copying bytes to the stream.</param>
+ /// <param name="count">The maximum number of bytes to write.</param>
+ private void WriteCore(byte[] array, int offset, int count)
+ {
+ PrepareForWriting();
+
+ // If no data is being written, nothing more to do.
+ if (count == 0)
+ {
+ return;
+ }
+
+ // If there's already data in our write buffer, then we need to go through
+ // our buffer to ensure data isn't corrupted.
+ if (_writePos > 0)
+ {
+ // If there's space remaining in the buffer, then copy as much as
+ // we can from the user's buffer into ours.
+ int spaceRemaining = _bufferLength - _writePos;
+ if (spaceRemaining > 0)
+ {
+ int bytesToCopy = Math.Min(spaceRemaining, count);
+ Buffer.BlockCopy(array, offset, GetBuffer(), _writePos, bytesToCopy);
+ _writePos += bytesToCopy;
+
+ // If we've successfully copied all of the user's data, we're done.
+ if (count == bytesToCopy)
+ {
+ return;
+ }
+
+ // Otherwise, keep track of how much more data needs to be handled.
+ offset += bytesToCopy;
+ count -= bytesToCopy;
+ }
+
+ // At this point, the buffer is full, so flush it out.
+ FlushWriteBuffer();
+ }
+
+ // Our buffer is now empty. If using the buffer would slow things down (because
+ // the user's looking to write more data than we can store in the buffer),
+ // skip the buffer. Otherwise, put the remaining data into the buffer.
+ Debug.Assert(_writePos == 0);
+ if (count >= _bufferLength)
+ {
+ WriteNative(array, offset, count);
+ }
+ else
+ {
+ Buffer.BlockCopy(array, offset, GetBuffer(), _writePos, count);
+ _writePos = count;
+ }
+ }
+
+ /// <summary>Unbuffered, writes a block of bytes to the file stream.</summary>
+ /// <param name="array">The buffer containing data to write to the stream.</param>
+ /// <param name="offset">The zero-based byte offset in array from which to begin copying bytes to the stream.</param>
+ /// <param name="count">The maximum number of bytes to write.</param>
+ private unsafe void WriteNative(byte[] array, int offset, int count)
+ {
+ VerifyOSHandlePosition();
+
+ fixed (byte* bufPtr = array)
+ {
+ while (count > 0)
+ {
+ int bytesWritten = CheckFileCall(Interop.Sys.Write(_fileHandle, bufPtr + offset, count));
+ Debug.Assert(bytesWritten <= count);
+
+ _filePosition += bytesWritten;
+ count -= bytesWritten;
+ offset += bytesWritten;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Asynchronously writes a sequence of bytes to the current stream, advances
+ /// the current position within this stream by the number of bytes written, and
+ /// monitors cancellation requests.
+ /// </summary>
+ /// <param name="buffer">The buffer to write data from.</param>
+ /// <param name="offset">The zero-based byte offset in buffer from which to begin copying bytes to the stream.</param>
+ /// <param name="count">The maximum number of bytes to write.</param>
+ /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
+ /// <returns>A task that represents the asynchronous write operation.</returns>
+ private Task WriteAsyncInternal(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ return Task.FromCanceled(cancellationToken);
+
+ if (_fileHandle.IsClosed)
+ throw Error.GetFileNotOpen();
+
+ if (_useAsyncIO)
+ {
+ if (!CanWrite) // match Windows behavior; this gets thrown synchronously
+ {
+ throw Error.GetWriteNotSupported();
+ }
+
+ // Serialize operations using the semaphore.
+ Task waitTask = _asyncState.WaitAsync();
+
+ // If we got ownership immediately, and if there's enough space in our buffer
+ // to buffer the entire write request, then do so and we're done.
+ if (waitTask.Status == TaskStatus.RanToCompletion)
+ {
+ int spaceRemaining = _bufferLength - _writePos;
+ if (spaceRemaining >= count)
+ {
+ try
+ {
+ PrepareForWriting();
+
+ Buffer.BlockCopy(buffer, offset, GetBuffer(), _writePos, count);
+ _writePos += count;
+
+ return Task.CompletedTask;
+ }
+ catch (Exception exc)
+ {
+ return Task.FromException(exc);
+ }
+ finally
+ {
+ _asyncState.Release();
+ }
+ }
+ }
+
+ // Otherwise, issue the whole request asynchronously.
+ _asyncState.Update(buffer, offset, count);
+ return waitTask.ContinueWith((t, s) =>
+ {
+ // The options available on Unix for writing asynchronously to an arbitrary file
+ // handle typically amount to just using another thread to do the synchronous write,
+ // which is exactly what this implementation does. This does mean there are subtle
+ // differences in certain FileStream behaviors between Windows and Unix when multiple
+ // asynchronous operations are issued against the stream to execute concurrently; on
+ // Unix the operations will be serialized due to the usage of a semaphore, but the
+ // position /length information won't be updated until after the write has completed,
+ // whereas on Windows it may happen before the write has completed.
+
+ Debug.Assert(t.Status == TaskStatus.RanToCompletion);
+ var thisRef = (FileStream)s;
+ try
+ {
+ byte[] b = thisRef._asyncState._buffer;
+ thisRef._asyncState._buffer = null; // remove reference to user's buffer
+ thisRef.WriteCore(b, thisRef._asyncState._offset, thisRef._asyncState._count);
+ }
+ finally { thisRef._asyncState.Release(); }
+ }, this, CancellationToken.None, TaskContinuationOptions.DenyChildAttach, TaskScheduler.Default);
+ }
+ else
+ {
+ return base.WriteAsync(buffer, offset, count, cancellationToken);
+ }
+ }
+
+ /// <summary>
+ /// Writes a byte to the current position in the stream and advances the position
+ /// within the stream by one byte.
+ /// </summary>
+ /// <param name="value">The byte to write to the stream.</param>
+ public override void WriteByte(byte value) // avoids an array allocation in the base implementation
+ {
+ if (_useAsyncIO)
+ {
+ _asyncState.Wait();
+ try { WriteByteCore(value); }
+ finally { _asyncState.Release(); }
+ }
+ else
+ {
+ WriteByteCore(value);
+ }
+ }
+
+ /// <summary>Sets the current position of this stream to the given value.</summary>
+ /// <param name="offset">The point relative to origin from which to begin seeking. </param>
+ /// <param name="origin">
+ /// Specifies the beginning, the end, or the current position as a reference
+ /// point for offset, using a value of type SeekOrigin.
+ /// </param>
+ /// <returns>The new position in the stream.</returns>
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ if (origin < SeekOrigin.Begin || origin > SeekOrigin.End)
+ {
+ throw new ArgumentException(SR.Argument_InvalidSeekOrigin, nameof(origin));
+ }
+ if (_fileHandle.IsClosed)
+ {
+ throw Error.GetFileNotOpen();
+ }
+ if (!CanSeek)
+ {
+ throw Error.GetSeekNotSupported();
+ }
+
+ VerifyOSHandlePosition();
+
+ // Flush our write/read buffer. FlushWrite will output any write buffer we have and reset _bufferWritePos.
+ // We don't call FlushRead, as that will do an unnecessary seek to rewind the read buffer, and since we're
+ // about to seek and update our position, we can simply update the offset as necessary and reset our read
+ // position and length to 0. (In the future, for some simple cases we could potentially add an optimization
+ // here to just move data around in the buffer for short jumps, to avoid re-reading the data from disk.)
+ FlushWriteBuffer();
+ if (origin == SeekOrigin.Current)
+ {
+ offset -= (_readLength - _readPos);
+ }
+ _readPos = _readLength = 0;
+
+ // Keep track of where we were, in case we're in append mode and need to verify
+ long oldPos = 0;
+ if (_appendStart >= 0)
+ {
+ oldPos = SeekCore(0, SeekOrigin.Current);
+ }
+
+ // Jump to the new location
+ long pos = SeekCore(offset, origin);
+
+ // Prevent users from overwriting data in a file that was opened in append mode.
+ if (_appendStart != -1 && pos < _appendStart)
+ {
+ SeekCore(oldPos, SeekOrigin.Begin);
+ throw new IOException(SR.IO_SeekAppendOverwrite);
+ }
+
+ // Return the new position
+ return pos;
+ }
+
+ /// <summary>Sets the current position of this stream to the given value.</summary>
+ /// <param name="offset">The point relative to origin from which to begin seeking. </param>
+ /// <param name="origin">
+ /// Specifies the beginning, the end, or the current position as a reference
+ /// point for offset, using a value of type SeekOrigin.
+ /// </param>
+ /// <returns>The new position in the stream.</returns>
+ private long SeekCore(long offset, SeekOrigin origin)
+ {
+ Debug.Assert(!_fileHandle.IsClosed && (GetType() != typeof(FileStream) || CanSeek)); // verify that we can seek, but only if CanSeek won't be a virtual call (which could happen in the ctor)
+ Debug.Assert(origin >= SeekOrigin.Begin && origin <= SeekOrigin.End);
+
+ long pos = CheckFileCall(Interop.Sys.LSeek(_fileHandle, offset, (Interop.Sys.SeekWhence)(int)origin)); // SeekOrigin values are the same as Interop.libc.SeekWhence values
+ _filePosition = pos;
+ return pos;
+ }
+
+ private long CheckFileCall(long result, bool ignoreNotSupported = false)
+ {
+ if (result < 0)
+ {
+ Interop.ErrorInfo errorInfo = Interop.Sys.GetLastErrorInfo();
+ if (!(ignoreNotSupported && errorInfo.Error == Interop.Error.ENOTSUP))
+ {
+ throw Interop.GetExceptionForIoErrno(errorInfo, _path, isDirectory: false);
+ }
+ }
+
+ return result;
+ }
+
+ private int CheckFileCall(int result, bool ignoreNotSupported = false)
+ {
+ CheckFileCall((long)result, ignoreNotSupported);
+
+ return result;
+ }
+
+ /// <summary>State used when the stream is in async mode.</summary>
+ private sealed class AsyncState : SemaphoreSlim
+ {
+ /// <summary>The caller's buffer currently being used by the active async operation.</summary>
+ internal byte[] _buffer;
+ /// <summary>The caller's offset currently being used by the active async operation.</summary>
+ internal int _offset;
+ /// <summary>The caller's count currently being used by the active async operation.</summary>
+ internal int _count;
+ /// <summary>The last task successfully, synchronously returned task from ReadAsync.</summary>
+ internal Task<int> _lastSuccessfulReadTask;
+
+ /// <summary>Initialize the AsyncState.</summary>
+ internal AsyncState() : base(initialCount: 1, maxCount: 1) { }
+
+ /// <summary>Sets the active buffer, offset, and count.</summary>
+ internal void Update(byte[] buffer, int offset, int count)
+ {
+ _buffer = buffer;
+ _offset = offset;
+ _count = count;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/FileStream.Win32.cs b/src/mscorlib/shared/System/IO/FileStream.Win32.cs
new file mode 100644
index 0000000000..0045ebeaf8
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/FileStream.Win32.cs
@@ -0,0 +1,77 @@
+// 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.Buffers;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Win32.SafeHandles;
+using System.Runtime.CompilerServices;
+
+namespace System.IO
+{
+ public partial class FileStream : Stream
+ {
+ private SafeFileHandle OpenHandle(FileMode mode, FileShare share, FileOptions options)
+ {
+ Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(share);
+
+ int fAccess =
+ ((_access & FileAccess.Read) == FileAccess.Read ? GENERIC_READ : 0) |
+ ((_access & FileAccess.Write) == FileAccess.Write ? GENERIC_WRITE : 0);
+
+ // Our Inheritable bit was stolen from Windows, but should be set in
+ // the security attributes class. Don't leave this bit set.
+ share &= ~FileShare.Inheritable;
+
+ // Must use a valid Win32 constant here...
+ if (mode == FileMode.Append)
+ mode = FileMode.OpenOrCreate;
+
+ int flagsAndAttributes = (int)options;
+
+ // For mitigating local elevation of privilege attack through named pipes
+ // make sure we always call CreateFile with SECURITY_ANONYMOUS so that the
+ // named pipe server can't impersonate a high privileged client security context
+ flagsAndAttributes |= (Interop.Kernel32.SecurityOptions.SECURITY_SQOS_PRESENT | Interop.Kernel32.SecurityOptions.SECURITY_ANONYMOUS);
+
+ // Don't pop up a dialog for reading from an empty floppy drive
+ uint oldMode = Interop.Kernel32.SetErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS);
+ try
+ {
+ SafeFileHandle fileHandle = Interop.Kernel32.CreateFile(_path, fAccess, share, ref secAttrs, mode, flagsAndAttributes, IntPtr.Zero);
+ fileHandle.IsAsync = _useAsyncIO;
+
+ if (fileHandle.IsInvalid)
+ {
+ // Return a meaningful exception with the full path.
+
+ // NT5 oddity - when trying to open "C:\" as a Win32FileStream,
+ // we usually get ERROR_PATH_NOT_FOUND from the OS. We should
+ // probably be consistent w/ every other directory.
+ int errorCode = Marshal.GetLastWin32Error();
+
+ if (errorCode == Interop.Errors.ERROR_PATH_NOT_FOUND && _path.Length == PathInternal.GetRootLength(_path))
+ errorCode = Interop.Errors.ERROR_ACCESS_DENIED;
+
+ throw Win32Marshal.GetExceptionForWin32Error(errorCode, _path);
+ }
+
+ int fileType = Interop.Kernel32.GetFileType(fileHandle);
+ if (fileType != Interop.Kernel32.FileTypes.FILE_TYPE_DISK)
+ {
+ fileHandle.Dispose();
+ throw new NotSupportedException(SR.NotSupported_FileStreamOnNonFiles);
+ }
+
+ return fileHandle;
+ }
+ finally
+ {
+ Interop.Kernel32.SetErrorMode(oldMode);
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/FileStream.WinRT.cs b/src/mscorlib/shared/System/IO/FileStream.WinRT.cs
new file mode 100644
index 0000000000..062b160b57
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/FileStream.WinRT.cs
@@ -0,0 +1,78 @@
+// 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 Microsoft.Win32.SafeHandles;
+using System.Runtime.InteropServices;
+
+namespace System.IO
+{
+ public partial class FileStream : Stream
+ {
+ private unsafe SafeFileHandle OpenHandle(FileMode mode, FileShare share, FileOptions options)
+ {
+ Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(share);
+
+ int fAccess =
+ ((_access & FileAccess.Read) == FileAccess.Read ? GENERIC_READ : 0) |
+ ((_access & FileAccess.Write) == FileAccess.Write ? GENERIC_WRITE : 0);
+
+ // Our Inheritable bit was stolen from Windows, but should be set in
+ // the security attributes class. Don't leave this bit set.
+ share &= ~FileShare.Inheritable;
+
+ // Must use a valid Win32 constant here...
+ if (mode == FileMode.Append)
+ mode = FileMode.OpenOrCreate;
+
+ Interop.Kernel32.CREATEFILE2_EXTENDED_PARAMETERS parameters = new Interop.Kernel32.CREATEFILE2_EXTENDED_PARAMETERS();
+ parameters.dwSize = (uint)sizeof(Interop.Kernel32.CREATEFILE2_EXTENDED_PARAMETERS);
+ parameters.dwFileFlags = (uint)options;
+ parameters.lpSecurityAttributes = &secAttrs;
+
+ SafeFileHandle fileHandle = Interop.Kernel32.CreateFile2(
+ lpFileName: _path,
+ dwDesiredAccess: fAccess,
+ dwShareMode: share,
+ dwCreationDisposition: mode,
+ pCreateExParams: &parameters);
+
+ fileHandle.IsAsync = _useAsyncIO;
+
+ if (fileHandle.IsInvalid)
+ {
+ // Return a meaningful exception with the full path.
+
+ // NT5 oddity - when trying to open "C:\" as a Win32FileStream,
+ // we usually get ERROR_PATH_NOT_FOUND from the OS. We should
+ // probably be consistent w/ every other directory.
+ int errorCode = Marshal.GetLastWin32Error();
+
+ if (errorCode == Interop.Errors.ERROR_PATH_NOT_FOUND && _path.Length == PathInternal.GetRootLength(_path))
+ errorCode = Interop.Errors.ERROR_ACCESS_DENIED;
+
+ throw Win32Marshal.GetExceptionForWin32Error(errorCode, $"{_path} {options} {fAccess} {share} {mode}");
+ }
+
+ return fileHandle;
+ }
+
+#if PROJECTN
+ // TODO: These internal methods should be removed once we start consuming updated CoreFX builds
+ public static FileStream InternalOpen(string path, int bufferSize = 4096, bool useAsync = true)
+ {
+ return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, useAsync);
+ }
+
+ public static FileStream InternalCreate(string path, int bufferSize = 4096, bool useAsync = true)
+ {
+ return new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, bufferSize, useAsync);
+ }
+
+ public static FileStream InternalAppend(string path, int bufferSize = 4096, bool useAsync = true)
+ {
+ return new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Read, bufferSize, useAsync);
+ }
+#endif
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/FileStream.Windows.cs b/src/mscorlib/shared/System/IO/FileStream.Windows.cs
new file mode 100644
index 0000000000..7c09ae1a1c
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/FileStream.Windows.cs
@@ -0,0 +1,1717 @@
+// 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.Buffers;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Win32.SafeHandles;
+using System.Runtime.CompilerServices;
+
+/*
+ * Win32FileStream supports different modes of accessing the disk - async mode
+ * and sync mode. They are two completely different codepaths in the
+ * sync & async methods (i.e. Read/Write vs. ReadAsync/WriteAsync). File
+ * handles in NT can be opened in only sync or overlapped (async) mode,
+ * and we have to deal with this pain. Stream has implementations of
+ * the sync methods in terms of the async ones, so we'll
+ * call through to our base class to get those methods when necessary.
+ *
+ * Also buffering is added into Win32FileStream as well. Folded in the
+ * code from BufferedStream, so all the comments about it being mostly
+ * aggressive (and the possible perf improvement) apply to Win32FileStream as
+ * well. Also added some buffering to the async code paths.
+ *
+ * Class Invariants:
+ * The class has one buffer, shared for reading & writing. It can only be
+ * used for one or the other at any point in time - not both. The following
+ * should be true:
+ * 0 <= _readPos <= _readLen < _bufferSize
+ * 0 <= _writePos < _bufferSize
+ * _readPos == _readLen && _readPos > 0 implies the read buffer is valid,
+ * but we're at the end of the buffer.
+ * _readPos == _readLen == 0 means the read buffer contains garbage.
+ * Either _writePos can be greater than 0, or _readLen & _readPos can be
+ * greater than zero, but neither can be greater than zero at the same time.
+ *
+ */
+
+namespace System.IO
+{
+ public partial class FileStream : Stream
+ {
+ private bool _canSeek;
+ private bool _isPipe; // Whether to disable async buffering code.
+ private long _appendStart; // When appending, prevent overwriting file.
+
+ private static unsafe IOCompletionCallback s_ioCallback = FileStreamCompletionSource.IOCallback;
+
+ private Task<int> _lastSynchronouslyCompletedTask = null; // cached task for read ops that complete synchronously
+ private Task _activeBufferOperation = null; // tracks in-progress async ops using the buffer
+ private PreAllocatedOverlapped _preallocatedOverlapped; // optimization for async ops to avoid per-op allocations
+ private FileStreamCompletionSource _currentOverlappedOwner; // async op currently using the preallocated overlapped
+
+ private void Init(FileMode mode, FileShare share)
+ {
+ // Disallow access to all non-file devices from the Win32FileStream
+ // constructors that take a String. Everyone else can call
+ // CreateFile themselves then use the constructor that takes an
+ // IntPtr. Disallows "con:", "com1:", "lpt1:", etc.
+ int fileType = Interop.Kernel32.GetFileType(_fileHandle);
+ if (fileType != Interop.Kernel32.FileTypes.FILE_TYPE_DISK)
+ {
+ _fileHandle.Dispose();
+ throw new NotSupportedException(SR.NotSupported_FileStreamOnNonFiles);
+ }
+
+ // This is necessary for async IO using IO Completion ports via our
+ // managed Threadpool API's. This (theoretically) calls the OS's
+ // BindIoCompletionCallback method, and passes in a stub for the
+ // LPOVERLAPPED_COMPLETION_ROUTINE. This stub looks at the Overlapped
+ // struct for this request and gets a delegate to a managed callback
+ // from there, which it then calls on a threadpool thread. (We allocate
+ // our native OVERLAPPED structs 2 pointers too large and store EE state
+ // & GC handles there, one to an IAsyncResult, the other to a delegate.)
+ if (_useAsyncIO)
+ {
+ try
+ {
+ _fileHandle.ThreadPoolBinding = ThreadPoolBoundHandle.BindHandle(_fileHandle);
+ }
+ catch (ArgumentException ex)
+ {
+ throw new IOException(SR.IO_BindHandleFailed, ex);
+ }
+ finally
+ {
+ if (_fileHandle.ThreadPoolBinding == null)
+ {
+ // We should close the handle so that the handle is not open until SafeFileHandle GC
+ Debug.Assert(!_exposedHandle, "Are we closing handle that we exposed/not own, how?");
+ _fileHandle.Dispose();
+ }
+ }
+ }
+
+ _canSeek = true;
+
+ // For Append mode...
+ if (mode == FileMode.Append)
+ {
+ _appendStart = SeekCore(0, SeekOrigin.End);
+ }
+ else
+ {
+ _appendStart = -1;
+ }
+ }
+
+ private void InitFromHandle(SafeFileHandle handle)
+ {
+ int handleType = Interop.Kernel32.GetFileType(_fileHandle);
+ Debug.Assert(handleType == Interop.Kernel32.FileTypes.FILE_TYPE_DISK || handleType == Interop.Kernel32.FileTypes.FILE_TYPE_PIPE || handleType == Interop.Kernel32.FileTypes.FILE_TYPE_CHAR, "FileStream was passed an unknown file type!");
+
+ _canSeek = handleType == Interop.Kernel32.FileTypes.FILE_TYPE_DISK;
+ _isPipe = handleType == Interop.Kernel32.FileTypes.FILE_TYPE_PIPE;
+
+ // This is necessary for async IO using IO Completion ports via our
+ // managed Threadpool API's. This calls the OS's
+ // BindIoCompletionCallback method, and passes in a stub for the
+ // LPOVERLAPPED_COMPLETION_ROUTINE. This stub looks at the Overlapped
+ // struct for this request and gets a delegate to a managed callback
+ // from there, which it then calls on a threadpool thread. (We allocate
+ // our native OVERLAPPED structs 2 pointers too large and store EE
+ // state & a handle to a delegate there.)
+ //
+ // If, however, we've already bound this file handle to our completion port,
+ // don't try to bind it again because it will fail. A handle can only be
+ // bound to a single completion port at a time.
+ if (_useAsyncIO && !GetSuppressBindHandle(handle))
+ {
+ try
+ {
+ _fileHandle.ThreadPoolBinding = ThreadPoolBoundHandle.BindHandle(_fileHandle);
+ }
+ catch (Exception ex)
+ {
+ // If you passed in a synchronous handle and told us to use
+ // it asynchronously, throw here.
+ throw new ArgumentException(SR.Arg_HandleNotAsync, nameof(handle), ex);
+ }
+ }
+ else if (!_useAsyncIO)
+ {
+ if (handleType != Interop.Kernel32.FileTypes.FILE_TYPE_PIPE)
+ VerifyHandleIsSync();
+ }
+
+ if (_canSeek)
+ SeekCore(0, SeekOrigin.Current);
+ else
+ _filePosition = 0;
+ }
+
+ private static bool GetSuppressBindHandle(SafeFileHandle handle)
+ {
+ return handle.IsAsync.HasValue ? handle.IsAsync.Value : false;
+ }
+
+ private unsafe static Interop.Kernel32.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share)
+ {
+ Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = default(Interop.Kernel32.SECURITY_ATTRIBUTES);
+ if ((share & FileShare.Inheritable) != 0)
+ {
+ secAttrs = new Interop.Kernel32.SECURITY_ATTRIBUTES();
+ secAttrs.nLength = (uint)sizeof(Interop.Kernel32.SECURITY_ATTRIBUTES);
+
+ secAttrs.bInheritHandle = Interop.BOOL.TRUE;
+ }
+ return secAttrs;
+ }
+
+ // Verifies that this handle supports synchronous IO operations (unless you
+ // didn't open it for either reading or writing).
+ private unsafe void VerifyHandleIsSync()
+ {
+ Debug.Assert(!_useAsyncIO);
+
+ // Do NOT use this method on pipes. Reading or writing to a pipe may
+ // cause an app to block incorrectly, introducing a deadlock (depending
+ // on whether a write will wake up an already-blocked thread or this
+ // Win32FileStream's thread).
+ Debug.Assert(Interop.Kernel32.GetFileType(_fileHandle) != Interop.Kernel32.FileTypes.FILE_TYPE_PIPE);
+
+ byte* bytes = stackalloc byte[1];
+ int numBytesReadWritten;
+ int r = -1;
+
+ // If the handle is a pipe, ReadFile will block until there
+ // has been a write on the other end. We'll just have to deal with it,
+ // For the read end of a pipe, you can mess up and
+ // accidentally read synchronously from an async pipe.
+ if ((_access & FileAccess.Read) != 0) // don't use the virtual CanRead or CanWrite, as this may be used in the ctor
+ {
+ r = Interop.Kernel32.ReadFile(_fileHandle, bytes, 0, out numBytesReadWritten, IntPtr.Zero);
+ }
+ else if ((_access & FileAccess.Write) != 0) // don't use the virtual CanRead or CanWrite, as this may be used in the ctor
+ {
+ r = Interop.Kernel32.WriteFile(_fileHandle, bytes, 0, out numBytesReadWritten, IntPtr.Zero);
+ }
+
+ if (r == 0)
+ {
+ int errorCode = GetLastWin32ErrorAndDisposeHandleIfInvalid(throwIfInvalidHandle: true);
+ if (errorCode == ERROR_INVALID_PARAMETER)
+ throw new ArgumentException(SR.Arg_HandleNotSync, "handle");
+ }
+ }
+
+ private bool HasActiveBufferOperation
+ {
+ get { return _activeBufferOperation != null && !_activeBufferOperation.IsCompleted; }
+ }
+
+ public override bool CanSeek
+ {
+ get { return _canSeek; }
+ }
+
+ private unsafe long GetLengthInternal()
+ {
+ Interop.Kernel32.FILE_STANDARD_INFO info = new Interop.Kernel32.FILE_STANDARD_INFO();
+
+ if (!Interop.Kernel32.GetFileInformationByHandleEx(_fileHandle, Interop.Kernel32.FILE_INFO_BY_HANDLE_CLASS.FileStandardInfo, out info, (uint)sizeof(Interop.Kernel32.FILE_STANDARD_INFO)))
+ throw Win32Marshal.GetExceptionForLastWin32Error();
+ long len = info.EndOfFile;
+ // If we're writing near the end of the file, we must include our
+ // internal buffer in our Length calculation. Don't flush because
+ // we use the length of the file in our async write method.
+ if (_writePos > 0 && _filePosition + _writePos > len)
+ len = _writePos + _filePosition;
+ return len;
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ // Nothing will be done differently based on whether we are
+ // disposing vs. finalizing. This is taking advantage of the
+ // weak ordering between normal finalizable objects & critical
+ // finalizable objects, which I included in the SafeHandle
+ // design for Win32FileStream, which would often "just work" when
+ // finalized.
+ try
+ {
+ if (_fileHandle != null && !_fileHandle.IsClosed)
+ {
+ // Flush data to disk iff we were writing. After
+ // thinking about this, we also don't need to flush
+ // our read position, regardless of whether the handle
+ // was exposed to the user. They probably would NOT
+ // want us to do this.
+ if (_writePos > 0)
+ {
+ FlushWriteBuffer(!disposing);
+ }
+ }
+ }
+ finally
+ {
+ if (_fileHandle != null && !_fileHandle.IsClosed)
+ {
+ if (_fileHandle.ThreadPoolBinding != null)
+ _fileHandle.ThreadPoolBinding.Dispose();
+
+ _fileHandle.Dispose();
+ }
+
+ if (_preallocatedOverlapped != null)
+ _preallocatedOverlapped.Dispose();
+
+ _canSeek = false;
+
+ // Don't set the buffer to null, to avoid a NullReferenceException
+ // when users have a race condition in their code (i.e. they call
+ // Close when calling another method on Stream like Read).
+ //_buffer = null;
+ base.Dispose(disposing);
+ }
+ }
+
+ private void FlushOSBuffer()
+ {
+ if (!Interop.Kernel32.FlushFileBuffers(_fileHandle))
+ {
+ throw Win32Marshal.GetExceptionForLastWin32Error();
+ }
+ }
+
+ // Returns a task that flushes the internal write buffer
+ private Task FlushWriteAsync(CancellationToken cancellationToken)
+ {
+ Debug.Assert(_useAsyncIO);
+ Debug.Assert(_readPos == 0 && _readLength == 0, "FileStream: Read buffer must be empty in FlushWriteAsync!");
+
+ // If the buffer is already flushed, don't spin up the OS write
+ if (_writePos == 0) return Task.CompletedTask;
+
+ Task flushTask = WriteInternalCoreAsync(GetBuffer(), 0, _writePos, cancellationToken);
+ _writePos = 0;
+
+ // Update the active buffer operation
+ _activeBufferOperation = HasActiveBufferOperation ?
+ Task.WhenAll(_activeBufferOperation, flushTask) :
+ flushTask;
+
+ return flushTask;
+ }
+
+ // Writes are buffered. Anytime the buffer fills up
+ // (_writePos + delta > _bufferSize) or the buffer switches to reading
+ // and there is left over data (_writePos > 0), this function must be called.
+ private void FlushWriteBuffer(bool calledFromFinalizer = false)
+ {
+ if (_writePos == 0) return;
+ Debug.Assert(_readPos == 0 && _readLength == 0, "FileStream: Read buffer must be empty in FlushWrite!");
+
+ if (_useAsyncIO)
+ {
+ Task writeTask = FlushWriteAsync(CancellationToken.None);
+ // With our Whidbey async IO & overlapped support for AD unloads,
+ // we don't strictly need to block here to release resources
+ // since that support takes care of the pinning & freeing the
+ // overlapped struct. We need to do this when called from
+ // Close so that the handle is closed when Close returns, but
+ // we don't need to call EndWrite from the finalizer.
+ // Additionally, if we do call EndWrite, we block forever
+ // because AD unloads prevent us from running the managed
+ // callback from the IO completion port. Blocking here when
+ // called from the finalizer during AD unload is clearly wrong,
+ // but we can't use any sort of test for whether the AD is
+ // unloading because if we weren't unloading, an AD unload
+ // could happen on a separate thread before we call EndWrite.
+ if (!calledFromFinalizer)
+ {
+ writeTask.GetAwaiter().GetResult();
+ }
+ }
+ else
+ {
+ WriteCore(GetBuffer(), 0, _writePos);
+ }
+
+ _writePos = 0;
+ }
+
+ private void SetLengthInternal(long value)
+ {
+ // Handle buffering updates.
+ if (_writePos > 0)
+ {
+ FlushWriteBuffer();
+ }
+ else if (_readPos < _readLength)
+ {
+ FlushReadBuffer();
+ }
+ _readPos = 0;
+ _readLength = 0;
+
+ if (_appendStart != -1 && value < _appendStart)
+ throw new IOException(SR.IO_SetLengthAppendTruncate);
+ SetLengthCore(value);
+ }
+
+ // We absolutely need this method broken out so that WriteInternalCoreAsync can call
+ // a method without having to go through buffering code that might call FlushWrite.
+ private void SetLengthCore(long value)
+ {
+ Debug.Assert(value >= 0, "value >= 0");
+ long origPos = _filePosition;
+
+ VerifyOSHandlePosition();
+ if (_filePosition != value)
+ SeekCore(value, SeekOrigin.Begin);
+ if (!Interop.Kernel32.SetEndOfFile(_fileHandle))
+ {
+ int errorCode = Marshal.GetLastWin32Error();
+ if (errorCode == Interop.Errors.ERROR_INVALID_PARAMETER)
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_FileLengthTooBig);
+ throw Win32Marshal.GetExceptionForWin32Error(errorCode);
+ }
+ // Return file pointer to where it was before setting length
+ if (origPos != value)
+ {
+ if (origPos < value)
+ SeekCore(origPos, SeekOrigin.Begin);
+ else
+ SeekCore(0, SeekOrigin.End);
+ }
+ }
+
+ // Instance method to help code external to this MarshalByRefObject avoid
+ // accessing its fields by ref. This avoids a compiler warning.
+ private FileStreamCompletionSource CompareExchangeCurrentOverlappedOwner(FileStreamCompletionSource newSource, FileStreamCompletionSource existingSource) => Interlocked.CompareExchange(ref _currentOverlappedOwner, newSource, existingSource);
+
+ public override int Read(byte[] array, int offset, int count)
+ {
+ ValidateReadWriteArgs(array, offset, count);
+ return ReadCore(array, offset, count);
+ }
+
+ private int ReadCore(byte[] array, int offset, int count)
+ {
+ Debug.Assert((_readPos == 0 && _readLength == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLength),
+ "We're either reading or writing, but not both.");
+
+ bool isBlocked = false;
+ int n = _readLength - _readPos;
+ // if the read buffer is empty, read into either user's array or our
+ // buffer, depending on number of bytes user asked for and buffer size.
+ if (n == 0)
+ {
+ if (!CanRead) throw Error.GetReadNotSupported();
+ if (_writePos > 0) FlushWriteBuffer();
+ if (!CanSeek || (count >= _bufferLength))
+ {
+ n = ReadNative(array, offset, count);
+ // Throw away read buffer.
+ _readPos = 0;
+ _readLength = 0;
+ return n;
+ }
+ n = ReadNative(GetBuffer(), 0, _bufferLength);
+ if (n == 0) return 0;
+ isBlocked = n < _bufferLength;
+ _readPos = 0;
+ _readLength = n;
+ }
+ // Now copy min of count or numBytesAvailable (i.e. near EOF) to array.
+ if (n > count) n = count;
+ Buffer.BlockCopy(GetBuffer(), _readPos, array, offset, n);
+ _readPos += n;
+
+ // We may have read less than the number of bytes the user asked
+ // for, but that is part of the Stream contract. Reading again for
+ // more data may cause us to block if we're using a device with
+ // no clear end of file, such as a serial port or pipe. If we
+ // blocked here & this code was used with redirected pipes for a
+ // process's standard output, this can lead to deadlocks involving
+ // two processes. But leave this here for files to avoid what would
+ // probably be a breaking change. --
+
+ // If we are reading from a device with no clear EOF like a
+ // serial port or a pipe, this will cause us to block incorrectly.
+ if (!_isPipe)
+ {
+ // If we hit the end of the buffer and didn't have enough bytes, we must
+ // read some more from the underlying stream. However, if we got
+ // fewer bytes from the underlying stream than we asked for (i.e. we're
+ // probably blocked), don't ask for more bytes.
+ if (n < count && !isBlocked)
+ {
+ Debug.Assert(_readPos == _readLength, "Read buffer should be empty!");
+ int moreBytesRead = ReadNative(array, offset + n, count - n);
+ n += moreBytesRead;
+ // We've just made our buffer inconsistent with our position
+ // pointer. We must throw away the read buffer.
+ _readPos = 0;
+ _readLength = 0;
+ }
+ }
+
+ return n;
+ }
+
+ [Conditional("DEBUG")]
+ private void AssertCanRead(byte[] buffer, int offset, int count)
+ {
+ Debug.Assert(!_fileHandle.IsClosed, "!_fileHandle.IsClosed");
+ Debug.Assert(CanRead, "CanRead");
+ Debug.Assert(buffer != null, "buffer != null");
+ Debug.Assert(_writePos == 0, "_writePos == 0");
+ Debug.Assert(offset >= 0, "offset is negative");
+ Debug.Assert(count >= 0, "count is negative");
+ }
+
+ private unsafe int ReadNative(byte[] buffer, int offset, int count)
+ {
+ AssertCanRead(buffer, offset, count);
+
+ if (_useAsyncIO)
+ return ReadNativeAsync(buffer, offset, count, 0, CancellationToken.None).GetAwaiter().GetResult();
+
+ // Make sure we are reading from the right spot
+ VerifyOSHandlePosition();
+
+ int errorCode = 0;
+ int r = ReadFileNative(_fileHandle, buffer, offset, count, null, out errorCode);
+
+ if (r == -1)
+ {
+ // For pipes, ERROR_BROKEN_PIPE is the normal end of the pipe.
+ if (errorCode == ERROR_BROKEN_PIPE)
+ {
+ r = 0;
+ }
+ else
+ {
+ if (errorCode == ERROR_INVALID_PARAMETER)
+ throw new ArgumentException(SR.Arg_HandleNotSync, "_fileHandle");
+
+ throw Win32Marshal.GetExceptionForWin32Error(errorCode);
+ }
+ }
+ Debug.Assert(r >= 0, "FileStream's ReadNative is likely broken.");
+ _filePosition += r;
+
+ return r;
+ }
+
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ if (origin < SeekOrigin.Begin || origin > SeekOrigin.End)
+ throw new ArgumentException(SR.Argument_InvalidSeekOrigin, nameof(origin));
+ if (_fileHandle.IsClosed) throw Error.GetFileNotOpen();
+ if (!CanSeek) throw Error.GetSeekNotSupported();
+
+ Debug.Assert((_readPos == 0 && _readLength == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLength), "We're either reading or writing, but not both.");
+
+ // If we've got bytes in our buffer to write, write them out.
+ // If we've read in and consumed some bytes, we'll have to adjust
+ // our seek positions ONLY IF we're seeking relative to the current
+ // position in the stream. This simulates doing a seek to the new
+ // position, then a read for the number of bytes we have in our buffer.
+ if (_writePos > 0)
+ {
+ FlushWriteBuffer();
+ }
+ else if (origin == SeekOrigin.Current)
+ {
+ // Don't call FlushRead here, which would have caused an infinite
+ // loop. Simply adjust the seek origin. This isn't necessary
+ // if we're seeking relative to the beginning or end of the stream.
+ offset -= (_readLength - _readPos);
+ }
+ _readPos = _readLength = 0;
+
+ // Verify that internal position is in sync with the handle
+ VerifyOSHandlePosition();
+
+ long oldPos = _filePosition + (_readPos - _readLength);
+ long pos = SeekCore(offset, origin);
+
+ // Prevent users from overwriting data in a file that was opened in
+ // append mode.
+ if (_appendStart != -1 && pos < _appendStart)
+ {
+ SeekCore(oldPos, SeekOrigin.Begin);
+ throw new IOException(SR.IO_SeekAppendOverwrite);
+ }
+
+ // We now must update the read buffer. We can in some cases simply
+ // update _readPos within the buffer, copy around the buffer so our
+ // Position property is still correct, and avoid having to do more
+ // reads from the disk. Otherwise, discard the buffer's contents.
+ if (_readLength > 0)
+ {
+ // We can optimize the following condition:
+ // oldPos - _readPos <= pos < oldPos + _readLen - _readPos
+ if (oldPos == pos)
+ {
+ if (_readPos > 0)
+ {
+ //Console.WriteLine("Seek: seeked for 0, adjusting buffer back by: "+_readPos+" _readLen: "+_readLen);
+ Buffer.BlockCopy(GetBuffer(), _readPos, GetBuffer(), 0, _readLength - _readPos);
+ _readLength -= _readPos;
+ _readPos = 0;
+ }
+ // If we still have buffered data, we must update the stream's
+ // position so our Position property is correct.
+ if (_readLength > 0)
+ SeekCore(_readLength, SeekOrigin.Current);
+ }
+ else if (oldPos - _readPos < pos && pos < oldPos + _readLength - _readPos)
+ {
+ int diff = (int)(pos - oldPos);
+ //Console.WriteLine("Seek: diff was "+diff+", readpos was "+_readPos+" adjusting buffer - shrinking by "+ (_readPos + diff));
+ Buffer.BlockCopy(GetBuffer(), _readPos + diff, GetBuffer(), 0, _readLength - (_readPos + diff));
+ _readLength -= (_readPos + diff);
+ _readPos = 0;
+ if (_readLength > 0)
+ SeekCore(_readLength, SeekOrigin.Current);
+ }
+ else
+ {
+ // Lose the read buffer.
+ _readPos = 0;
+ _readLength = 0;
+ }
+ Debug.Assert(_readLength >= 0 && _readPos <= _readLength, "_readLen should be nonnegative, and _readPos should be less than or equal _readLen");
+ Debug.Assert(pos == Position, "Seek optimization: pos != Position! Buffer math was mangled.");
+ }
+ return pos;
+ }
+
+ // This doesn't do argument checking. Necessary for SetLength, which must
+ // set the file pointer beyond the end of the file. This will update the
+ // internal position
+ // This is called during construction so it should avoid any virtual
+ // calls
+ private long SeekCore(long offset, SeekOrigin origin)
+ {
+ Debug.Assert(!_fileHandle.IsClosed && _canSeek, "!_handle.IsClosed && _parent.CanSeek");
+ Debug.Assert(origin >= SeekOrigin.Begin && origin <= SeekOrigin.End, "origin>=SeekOrigin.Begin && origin<=SeekOrigin.End");
+ long ret = 0;
+
+ if (!Interop.Kernel32.SetFilePointerEx(_fileHandle, offset, out ret, (uint)origin))
+ {
+ int errorCode = GetLastWin32ErrorAndDisposeHandleIfInvalid();
+ throw Win32Marshal.GetExceptionForWin32Error(errorCode);
+ }
+
+ _filePosition = ret;
+ return ret;
+ }
+
+ partial void OnBufferAllocated()
+ {
+ Debug.Assert(_buffer != null);
+ Debug.Assert(_preallocatedOverlapped == null);
+
+ if (_useAsyncIO)
+ _preallocatedOverlapped = new PreAllocatedOverlapped(s_ioCallback, this, _buffer);
+ }
+
+ public override void Write(byte[] array, int offset, int count)
+ {
+ ValidateReadWriteArgs(array, offset, count);
+
+ if (_writePos == 0)
+ {
+ // Ensure we can write to the stream, and ready buffer for writing.
+ if (!CanWrite) throw Error.GetWriteNotSupported();
+ if (_readPos < _readLength) FlushReadBuffer();
+ _readPos = 0;
+ _readLength = 0;
+ }
+
+ // If our buffer has data in it, copy data from the user's array into
+ // the buffer, and if we can fit it all there, return. Otherwise, write
+ // the buffer to disk and copy any remaining data into our buffer.
+ // The assumption here is memcpy is cheaper than disk (or net) IO.
+ // (10 milliseconds to disk vs. ~20-30 microseconds for a 4K memcpy)
+ // So the extra copying will reduce the total number of writes, in
+ // non-pathological cases (i.e. write 1 byte, then write for the buffer
+ // size repeatedly)
+ if (_writePos > 0)
+ {
+ int numBytes = _bufferLength - _writePos; // space left in buffer
+ if (numBytes > 0)
+ {
+ if (numBytes > count)
+ numBytes = count;
+ Buffer.BlockCopy(array, offset, GetBuffer(), _writePos, numBytes);
+ _writePos += numBytes;
+ if (count == numBytes) return;
+ offset += numBytes;
+ count -= numBytes;
+ }
+ // Reset our buffer. We essentially want to call FlushWrite
+ // without calling Flush on the underlying Stream.
+
+ if (_useAsyncIO)
+ {
+ WriteInternalCoreAsync(GetBuffer(), 0, _writePos, CancellationToken.None).GetAwaiter().GetResult();
+ }
+ else
+ {
+ WriteCore(GetBuffer(), 0, _writePos);
+ }
+ _writePos = 0;
+ }
+ // If the buffer would slow writes down, avoid buffer completely.
+ if (count >= _bufferLength)
+ {
+ Debug.Assert(_writePos == 0, "FileStream cannot have buffered data to write here! Your stream will be corrupted.");
+ WriteCore(array, offset, count);
+ return;
+ }
+ else if (count == 0)
+ {
+ return; // Don't allocate a buffer then call memcpy for 0 bytes.
+ }
+
+ // Copy remaining bytes into buffer, to write at a later date.
+ Buffer.BlockCopy(array, offset, GetBuffer(), _writePos, count);
+ _writePos = count;
+ return;
+ }
+
+ private unsafe void WriteCore(byte[] buffer, int offset, int count)
+ {
+ Debug.Assert(!_fileHandle.IsClosed, "!_handle.IsClosed");
+ Debug.Assert(CanWrite, "_parent.CanWrite");
+
+ Debug.Assert(buffer != null, "buffer != null");
+ Debug.Assert(_readPos == _readLength, "_readPos == _readLen");
+ Debug.Assert(offset >= 0, "offset is negative");
+ Debug.Assert(count >= 0, "count is negative");
+ if (_useAsyncIO)
+ {
+ WriteInternalCoreAsync(buffer, offset, count, CancellationToken.None).GetAwaiter().GetResult();
+ return;
+ }
+
+ // Make sure we are writing to the position that we think we are
+ VerifyOSHandlePosition();
+
+ int errorCode = 0;
+ int r = WriteFileNative(_fileHandle, buffer, offset, count, null, out errorCode);
+
+ if (r == -1)
+ {
+ // For pipes, ERROR_NO_DATA is not an error, but the pipe is closing.
+ if (errorCode == ERROR_NO_DATA)
+ {
+ r = 0;
+ }
+ else
+ {
+ // ERROR_INVALID_PARAMETER may be returned for writes
+ // where the position is too large (i.e. writing at Int64.MaxValue
+ // on Win9x) OR for synchronous writes to a handle opened
+ // asynchronously.
+ if (errorCode == ERROR_INVALID_PARAMETER)
+ throw new IOException(SR.IO_FileTooLongOrHandleNotSync);
+ throw Win32Marshal.GetExceptionForWin32Error(errorCode);
+ }
+ }
+ Debug.Assert(r >= 0, "FileStream's WriteCore is likely broken.");
+ _filePosition += r;
+ return;
+ }
+
+ private Task<int> ReadAsyncInternal(byte[] array, int offset, int numBytes, CancellationToken cancellationToken)
+ {
+ // If async IO is not supported on this platform or
+ // if this Win32FileStream was not opened with FileOptions.Asynchronous.
+ if (!_useAsyncIO)
+ {
+ return base.ReadAsync(array, offset, numBytes, cancellationToken);
+ }
+
+ if (!CanRead) throw Error.GetReadNotSupported();
+
+ Debug.Assert((_readPos == 0 && _readLength == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLength), "We're either reading or writing, but not both.");
+
+ if (_isPipe)
+ {
+ // Pipes are tricky, at least when you have 2 different pipes
+ // that you want to use simultaneously. When redirecting stdout
+ // & stderr with the Process class, it's easy to deadlock your
+ // parent & child processes when doing writes 4K at a time. The
+ // OS appears to use a 4K buffer internally. If you write to a
+ // pipe that is full, you will block until someone read from
+ // that pipe. If you try reading from an empty pipe and
+ // Win32FileStream's ReadAsync blocks waiting for data to fill it's
+ // internal buffer, you will be blocked. In a case where a child
+ // process writes to stdout & stderr while a parent process tries
+ // reading from both, you can easily get into a deadlock here.
+ // To avoid this deadlock, don't buffer when doing async IO on
+ // pipes. But don't completely ignore buffered data either.
+ if (_readPos < _readLength)
+ {
+ int n = _readLength - _readPos;
+ if (n > numBytes) n = numBytes;
+ Buffer.BlockCopy(GetBuffer(), _readPos, array, offset, n);
+ _readPos += n;
+
+ // Return a completed task
+ return TaskFromResultOrCache(n);
+ }
+ else
+ {
+ Debug.Assert(_writePos == 0, "Win32FileStream must not have buffered write data here! Pipes should be unidirectional.");
+ return ReadNativeAsync(array, offset, numBytes, 0, cancellationToken);
+ }
+ }
+
+ Debug.Assert(!_isPipe, "Should not be a pipe.");
+
+ // Handle buffering.
+ if (_writePos > 0) FlushWriteBuffer();
+ if (_readPos == _readLength)
+ {
+ // I can't see how to handle buffering of async requests when
+ // filling the buffer asynchronously, without a lot of complexity.
+ // The problems I see are issuing an async read, we do an async
+ // read to fill the buffer, then someone issues another read
+ // (either synchronously or asynchronously) before the first one
+ // returns. This would involve some sort of complex buffer locking
+ // that we probably don't want to get into, at least not in V1.
+ // If we did a sync read to fill the buffer, we could avoid the
+ // problem, and any async read less than 64K gets turned into a
+ // synchronous read by NT anyways... --
+
+ if (numBytes < _bufferLength)
+ {
+ Task<int> readTask = ReadNativeAsync(GetBuffer(), 0, _bufferLength, 0, cancellationToken);
+ _readLength = readTask.GetAwaiter().GetResult();
+ int n = _readLength;
+ if (n > numBytes) n = numBytes;
+ Buffer.BlockCopy(GetBuffer(), 0, array, offset, n);
+ _readPos = n;
+
+ // Return a completed task (recycling the one above if possible)
+ return (_readLength == n ? readTask : TaskFromResultOrCache(n));
+ }
+ else
+ {
+ // Here we're making our position pointer inconsistent
+ // with our read buffer. Throw away the read buffer's contents.
+ _readPos = 0;
+ _readLength = 0;
+ return ReadNativeAsync(array, offset, numBytes, 0, cancellationToken);
+ }
+ }
+ else
+ {
+ int n = _readLength - _readPos;
+ if (n > numBytes) n = numBytes;
+ Buffer.BlockCopy(GetBuffer(), _readPos, array, offset, n);
+ _readPos += n;
+
+ if (n >= numBytes)
+ {
+ // Return a completed task
+ return TaskFromResultOrCache(n);
+ }
+ else
+ {
+ // For streams with no clear EOF like serial ports or pipes
+ // we cannot read more data without causing an app to block
+ // incorrectly. Pipes don't go down this path
+ // though. This code needs to be fixed.
+ // Throw away read buffer.
+ _readPos = 0;
+ _readLength = 0;
+ return ReadNativeAsync(array, offset + n, numBytes - n, n, cancellationToken);
+ }
+ }
+ }
+
+ unsafe private Task<int> ReadNativeAsync(byte[] bytes, int offset, int numBytes, int numBufferedBytesRead, CancellationToken cancellationToken)
+ {
+ AssertCanRead(bytes, offset, numBytes);
+ Debug.Assert(_useAsyncIO, "ReadNativeAsync doesn't work on synchronous file streams!");
+
+ // Create and store async stream class library specific data in the async result
+
+ FileStreamCompletionSource completionSource = new FileStreamCompletionSource(this, numBufferedBytesRead, bytes, cancellationToken);
+ NativeOverlapped* intOverlapped = completionSource.Overlapped;
+
+ // Calculate position in the file we should be at after the read is done
+ if (CanSeek)
+ {
+ long len = Length;
+
+ // Make sure we are reading from the position that we think we are
+ VerifyOSHandlePosition();
+
+ if (_filePosition + numBytes > len)
+ {
+ if (_filePosition <= len)
+ numBytes = (int)(len - _filePosition);
+ else
+ numBytes = 0;
+ }
+
+ // Now set the position to read from in the NativeOverlapped struct
+ // For pipes, we should leave the offset fields set to 0.
+ intOverlapped->OffsetLow = unchecked((int)_filePosition);
+ intOverlapped->OffsetHigh = (int)(_filePosition >> 32);
+
+ // When using overlapped IO, the OS is not supposed to
+ // touch the file pointer location at all. We will adjust it
+ // ourselves. This isn't threadsafe.
+
+ // WriteFile should not update the file pointer when writing
+ // in overlapped mode, according to MSDN. But it does update
+ // the file pointer when writing to a UNC path!
+ // So changed the code below to seek to an absolute
+ // location, not a relative one. ReadFile seems consistent though.
+ SeekCore(numBytes, SeekOrigin.Current);
+ }
+
+ // queue an async ReadFile operation and pass in a packed overlapped
+ int errorCode = 0;
+ int r = ReadFileNative(_fileHandle, bytes, offset, numBytes, intOverlapped, out errorCode);
+ // ReadFile, the OS version, will return 0 on failure. But
+ // my ReadFileNative wrapper returns -1. My wrapper will return
+ // the following:
+ // On error, r==-1.
+ // On async requests that are still pending, r==-1 w/ errorCode==ERROR_IO_PENDING
+ // on async requests that completed sequentially, r==0
+ // You will NEVER RELIABLY be able to get the number of bytes
+ // read back from this call when using overlapped structures! You must
+ // not pass in a non-null lpNumBytesRead to ReadFile when using
+ // overlapped structures! This is by design NT behavior.
+ if (r == -1 && numBytes != -1)
+ {
+ // For pipes, when they hit EOF, they will come here.
+ if (errorCode == ERROR_BROKEN_PIPE)
+ {
+ // Not an error, but EOF. AsyncFSCallback will NOT be
+ // called. Call the user callback here.
+
+ // We clear the overlapped status bit for this special case.
+ // Failure to do so looks like we are freeing a pending overlapped later.
+ intOverlapped->InternalLow = IntPtr.Zero;
+ completionSource.SetCompletedSynchronously(0);
+ }
+ else if (errorCode != ERROR_IO_PENDING)
+ {
+ if (!_fileHandle.IsClosed && CanSeek) // Update Position - It could be anywhere.
+ {
+ SeekCore(0, SeekOrigin.Current);
+ }
+
+ completionSource.ReleaseNativeResource();
+
+ if (errorCode == ERROR_HANDLE_EOF)
+ {
+ throw Error.GetEndOfFile();
+ }
+ else
+ {
+ throw Win32Marshal.GetExceptionForWin32Error(errorCode);
+ }
+ }
+ else
+ {
+ // Only once the IO is pending do we register for cancellation
+ completionSource.RegisterForCancellation();
+ }
+ }
+ else
+ {
+ // Due to a workaround for a race condition in NT's ReadFile &
+ // WriteFile routines, we will always be returning 0 from ReadFileNative
+ // when we do async IO instead of the number of bytes read,
+ // irregardless of whether the operation completed
+ // synchronously or asynchronously. We absolutely must not
+ // set asyncResult._numBytes here, since will never have correct
+ // results.
+ //Console.WriteLine("ReadFile returned: "+r+" (0x"+Int32.Format(r, "x")+") The IO completed synchronously, but the user callback was called on a separate thread");
+ }
+
+ return completionSource.Task;
+ }
+
+ // Reads a byte from the file stream. Returns the byte cast to an int
+ // or -1 if reading from the end of the stream.
+ public override int ReadByte()
+ {
+ return ReadByteCore();
+ }
+
+ private Task WriteAsyncInternal(byte[] array, int offset, int numBytes, CancellationToken cancellationToken)
+ {
+ // If async IO is not supported on this platform or
+ // if this Win32FileStream was not opened with FileOptions.Asynchronous.
+ if (!_useAsyncIO)
+ {
+ return base.WriteAsync(array, offset, numBytes, cancellationToken);
+ }
+
+ if (!CanWrite) throw Error.GetWriteNotSupported();
+
+ Debug.Assert((_readPos == 0 && _readLength == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLength), "We're either reading or writing, but not both.");
+ Debug.Assert(!_isPipe || (_readPos == 0 && _readLength == 0), "Win32FileStream must not have buffered data here! Pipes should be unidirectional.");
+
+ bool writeDataStoredInBuffer = false;
+ if (!_isPipe) // avoid async buffering with pipes, as doing so can lead to deadlocks (see comments in ReadInternalAsyncCore)
+ {
+ // Ensure the buffer is clear for writing
+ if (_writePos == 0)
+ {
+ if (_readPos < _readLength)
+ {
+ FlushReadBuffer();
+ }
+ _readPos = 0;
+ _readLength = 0;
+ }
+
+ // Determine how much space remains in the buffer
+ int remainingBuffer = _bufferLength - _writePos;
+ Debug.Assert(remainingBuffer >= 0);
+
+ // Simple/common case:
+ // - The write is smaller than our buffer, such that it's worth considering buffering it.
+ // - There's no active flush operation, such that we don't have to worry about the existing buffer being in use.
+ // - And the data we're trying to write fits in the buffer, meaning it wasn't already filled by previous writes.
+ // In that case, just store it in the buffer.
+ if (numBytes < _bufferLength && !HasActiveBufferOperation && numBytes <= remainingBuffer)
+ {
+ Buffer.BlockCopy(array, offset, GetBuffer(), _writePos, numBytes);
+ _writePos += numBytes;
+ writeDataStoredInBuffer = true;
+
+ // There is one special-but-common case, common because devs often use
+ // byte[] sizes that are powers of 2 and thus fit nicely into our buffer, which is
+ // also a power of 2. If after our write the buffer still has remaining space,
+ // then we're done and can return a completed task now. But if we filled the buffer
+ // completely, we want to do the asynchronous flush/write as part of this operation
+ // rather than waiting until the next write that fills the buffer.
+ if (numBytes != remainingBuffer)
+ return Task.CompletedTask;
+
+ Debug.Assert(_writePos == _bufferLength);
+ }
+ }
+
+ // At this point, at least one of the following is true:
+ // 1. There was an active flush operation (it could have completed by now, though).
+ // 2. The data doesn't fit in the remaining buffer (or it's a pipe and we chose not to try).
+ // 3. We wrote all of the data to the buffer, filling it.
+ //
+ // If there's an active operation, we can't touch the current buffer because it's in use.
+ // That gives us a choice: we can either allocate a new buffer, or we can skip the buffer
+ // entirely (even if the data would otherwise fit in it). For now, for simplicity, we do
+ // the latter; it could also have performance wins due to OS-level optimizations, and we could
+ // potentially add support for PreAllocatedOverlapped due to having a single buffer. (We can
+ // switch to allocating a new buffer, potentially experimenting with buffer pooling, should
+ // performance data suggest it's appropriate.)
+ //
+ // If the data doesn't fit in the remaining buffer, it could be because it's so large
+ // it's greater than the entire buffer size, in which case we'd always skip the buffer,
+ // or it could be because there's more data than just the space remaining. For the latter
+ // case, we need to issue an asynchronous write to flush that data, which then turns this into
+ // the first case above with an active operation.
+ //
+ // If we already stored the data, then we have nothing additional to write beyond what
+ // we need to flush.
+ //
+ // In any of these cases, we have the same outcome:
+ // - If there's data in the buffer, flush it by writing it out asynchronously.
+ // - Then, if there's any data to be written, issue a write for it concurrently.
+ // We return a Task that represents one or both.
+
+ // Flush the buffer asynchronously if there's anything to flush
+ Task flushTask = null;
+ if (_writePos > 0)
+ {
+ flushTask = FlushWriteAsync(cancellationToken);
+
+ // If we already copied all of the data into the buffer,
+ // simply return the flush task here. Same goes for if the task has
+ // already completed and was unsuccessful.
+ if (writeDataStoredInBuffer ||
+ flushTask.IsFaulted ||
+ flushTask.IsCanceled)
+ {
+ return flushTask;
+ }
+ }
+
+ Debug.Assert(!writeDataStoredInBuffer);
+ Debug.Assert(_writePos == 0);
+
+ // Finally, issue the write asynchronously, and return a Task that logically
+ // represents the write operation, including any flushing done.
+ Task writeTask = WriteInternalCoreAsync(array, offset, numBytes, cancellationToken);
+ return
+ (flushTask == null || flushTask.Status == TaskStatus.RanToCompletion) ? writeTask :
+ (writeTask.Status == TaskStatus.RanToCompletion) ? flushTask :
+ Task.WhenAll(flushTask, writeTask);
+ }
+
+ private unsafe Task WriteInternalCoreAsync(byte[] bytes, int offset, int numBytes, CancellationToken cancellationToken)
+ {
+ Debug.Assert(!_fileHandle.IsClosed, "!_handle.IsClosed");
+ Debug.Assert(CanWrite, "_parent.CanWrite");
+ Debug.Assert(bytes != null, "bytes != null");
+ Debug.Assert(_readPos == _readLength, "_readPos == _readLen");
+ Debug.Assert(_useAsyncIO, "WriteInternalCoreAsync doesn't work on synchronous file streams!");
+ Debug.Assert(offset >= 0, "offset is negative");
+ Debug.Assert(numBytes >= 0, "numBytes is negative");
+
+ // Create and store async stream class library specific data in the async result
+ FileStreamCompletionSource completionSource = new FileStreamCompletionSource(this, 0, bytes, cancellationToken);
+ NativeOverlapped* intOverlapped = completionSource.Overlapped;
+
+ if (CanSeek)
+ {
+ // Make sure we set the length of the file appropriately.
+ long len = Length;
+ //Console.WriteLine("WriteInternalCoreAsync - Calculating end pos. pos: "+pos+" len: "+len+" numBytes: "+numBytes);
+
+ // Make sure we are writing to the position that we think we are
+ VerifyOSHandlePosition();
+
+ if (_filePosition + numBytes > len)
+ {
+ //Console.WriteLine("WriteInternalCoreAsync - Setting length to: "+(pos + numBytes));
+ SetLengthCore(_filePosition + numBytes);
+ }
+
+ // Now set the position to read from in the NativeOverlapped struct
+ // For pipes, we should leave the offset fields set to 0.
+ intOverlapped->OffsetLow = (int)_filePosition;
+ intOverlapped->OffsetHigh = (int)(_filePosition >> 32);
+
+ // When using overlapped IO, the OS is not supposed to
+ // touch the file pointer location at all. We will adjust it
+ // ourselves. This isn't threadsafe.
+ SeekCore(numBytes, SeekOrigin.Current);
+ }
+
+ //Console.WriteLine("WriteInternalCoreAsync finishing. pos: "+pos+" numBytes: "+numBytes+" _pos: "+_pos+" Position: "+Position);
+
+ int errorCode = 0;
+ // queue an async WriteFile operation and pass in a packed overlapped
+ int r = WriteFileNative(_fileHandle, bytes, offset, numBytes, intOverlapped, out errorCode);
+
+ // WriteFile, the OS version, will return 0 on failure. But
+ // my WriteFileNative wrapper returns -1. My wrapper will return
+ // the following:
+ // On error, r==-1.
+ // On async requests that are still pending, r==-1 w/ errorCode==ERROR_IO_PENDING
+ // On async requests that completed sequentially, r==0
+ // You will NEVER RELIABLY be able to get the number of bytes
+ // written back from this call when using overlapped IO! You must
+ // not pass in a non-null lpNumBytesWritten to WriteFile when using
+ // overlapped structures! This is ByDesign NT behavior.
+ if (r == -1 && numBytes != -1)
+ {
+ //Console.WriteLine("WriteFile returned 0; Write will complete asynchronously (if errorCode==3e5) errorCode: 0x{0:x}", errorCode);
+
+ // For pipes, when they are closed on the other side, they will come here.
+ if (errorCode == ERROR_NO_DATA)
+ {
+ // Not an error, but EOF. AsyncFSCallback will NOT be called.
+ // Completing TCS and return cached task allowing the GC to collect TCS.
+ completionSource.SetCompletedSynchronously(0);
+ return Task.CompletedTask;
+ }
+ else if (errorCode != ERROR_IO_PENDING)
+ {
+ if (!_fileHandle.IsClosed && CanSeek) // Update Position - It could be anywhere.
+ {
+ SeekCore(0, SeekOrigin.Current);
+ }
+
+ completionSource.ReleaseNativeResource();
+
+ if (errorCode == ERROR_HANDLE_EOF)
+ {
+ throw Error.GetEndOfFile();
+ }
+ else
+ {
+ throw Win32Marshal.GetExceptionForWin32Error(errorCode);
+ }
+ }
+ else // ERROR_IO_PENDING
+ {
+ // Only once the IO is pending do we register for cancellation
+ completionSource.RegisterForCancellation();
+ }
+ }
+ else
+ {
+ // Due to a workaround for a race condition in NT's ReadFile &
+ // WriteFile routines, we will always be returning 0 from WriteFileNative
+ // when we do async IO instead of the number of bytes written,
+ // irregardless of whether the operation completed
+ // synchronously or asynchronously. We absolutely must not
+ // set asyncResult._numBytes here, since will never have correct
+ // results.
+ //Console.WriteLine("WriteFile returned: "+r+" (0x"+Int32.Format(r, "x")+") The IO completed synchronously, but the user callback was called on another thread.");
+ }
+
+ return completionSource.Task;
+ }
+
+ public override void WriteByte(byte value)
+ {
+ WriteByteCore(value);
+ }
+
+ // Windows API definitions, from winbase.h and others
+
+ private const int FILE_ATTRIBUTE_NORMAL = 0x00000080;
+ private const int FILE_ATTRIBUTE_ENCRYPTED = 0x00004000;
+ private const int FILE_FLAG_OVERLAPPED = 0x40000000;
+ internal const int GENERIC_READ = unchecked((int)0x80000000);
+ private const int GENERIC_WRITE = 0x40000000;
+
+ private const int FILE_BEGIN = 0;
+ private const int FILE_CURRENT = 1;
+ private const int FILE_END = 2;
+
+ // Error codes (not HRESULTS), from winerror.h
+ internal const int ERROR_BROKEN_PIPE = 109;
+ internal const int ERROR_NO_DATA = 232;
+ private const int ERROR_HANDLE_EOF = 38;
+ private const int ERROR_INVALID_PARAMETER = 87;
+ private const int ERROR_IO_PENDING = 997;
+
+ // __ConsoleStream also uses this code.
+ private unsafe int ReadFileNative(SafeFileHandle handle, byte[] bytes, int offset, int count, NativeOverlapped* overlapped, out int errorCode)
+ {
+ Debug.Assert(handle != null, "handle != null");
+ Debug.Assert(offset >= 0, "offset >= 0");
+ Debug.Assert(count >= 0, "count >= 0");
+ Debug.Assert(bytes != null, "bytes != null");
+ // Don't corrupt memory when multiple threads are erroneously writing
+ // to this stream simultaneously.
+ if (bytes.Length - offset < count)
+ throw new IndexOutOfRangeException(SR.IndexOutOfRange_IORaceCondition);
+
+ Debug.Assert((_useAsyncIO && overlapped != null) || (!_useAsyncIO && overlapped == null), "Async IO and overlapped parameters inconsistent in call to ReadFileNative.");
+
+ // You can't use the fixed statement on an array of length 0.
+ if (bytes.Length == 0)
+ {
+ errorCode = 0;
+ return 0;
+ }
+
+ int r = 0;
+ int numBytesRead = 0;
+
+ fixed (byte* p = &bytes[0])
+ {
+ if (_useAsyncIO)
+ r = Interop.Kernel32.ReadFile(handle, p + offset, count, IntPtr.Zero, overlapped);
+ else
+ r = Interop.Kernel32.ReadFile(handle, p + offset, count, out numBytesRead, IntPtr.Zero);
+ }
+
+ if (r == 0)
+ {
+ errorCode = GetLastWin32ErrorAndDisposeHandleIfInvalid();
+ return -1;
+ }
+ else
+ {
+ errorCode = 0;
+ return numBytesRead;
+ }
+ }
+
+ private unsafe int WriteFileNative(SafeFileHandle handle, byte[] bytes, int offset, int count, NativeOverlapped* overlapped, out int errorCode)
+ {
+ Debug.Assert(handle != null, "handle != null");
+ Debug.Assert(offset >= 0, "offset >= 0");
+ Debug.Assert(count >= 0, "count >= 0");
+ Debug.Assert(bytes != null, "bytes != null");
+ // Don't corrupt memory when multiple threads are erroneously writing
+ // to this stream simultaneously. (the OS is reading from
+ // the array we pass to WriteFile, but if we read beyond the end and
+ // that memory isn't allocated, we could get an AV.)
+ if (bytes.Length - offset < count)
+ throw new IndexOutOfRangeException(SR.IndexOutOfRange_IORaceCondition);
+
+ Debug.Assert((_useAsyncIO && overlapped != null) || (!_useAsyncIO && overlapped == null), "Async IO and overlapped parameters inconsistent in call to WriteFileNative.");
+
+ // You can't use the fixed statement on an array of length 0.
+ if (bytes.Length == 0)
+ {
+ errorCode = 0;
+ return 0;
+ }
+
+ int numBytesWritten = 0;
+ int r = 0;
+
+ fixed (byte* p = &bytes[0])
+ {
+ if (_useAsyncIO)
+ r = Interop.Kernel32.WriteFile(handle, p + offset, count, IntPtr.Zero, overlapped);
+ else
+ r = Interop.Kernel32.WriteFile(handle, p + offset, count, out numBytesWritten, IntPtr.Zero);
+ }
+
+ if (r == 0)
+ {
+ errorCode = GetLastWin32ErrorAndDisposeHandleIfInvalid();
+ return -1;
+ }
+ else
+ {
+ errorCode = 0;
+ return numBytesWritten;
+ }
+ }
+
+ private int GetLastWin32ErrorAndDisposeHandleIfInvalid(bool throwIfInvalidHandle = false)
+ {
+ int errorCode = Marshal.GetLastWin32Error();
+
+ // If ERROR_INVALID_HANDLE is returned, it doesn't suffice to set
+ // the handle as invalid; the handle must also be closed.
+ //
+ // Marking the handle as invalid but not closing the handle
+ // resulted in exceptions during finalization and locked column
+ // values (due to invalid but unclosed handle) in SQL Win32FileStream
+ // scenarios.
+ //
+ // A more mainstream scenario involves accessing a file on a
+ // network share. ERROR_INVALID_HANDLE may occur because the network
+ // connection was dropped and the server closed the handle. However,
+ // the client side handle is still open and even valid for certain
+ // operations.
+ //
+ // Note that _parent.Dispose doesn't throw so we don't need to special case.
+ // SetHandleAsInvalid only sets _closed field to true (without
+ // actually closing handle) so we don't need to call that as well.
+ if (errorCode == Interop.Errors.ERROR_INVALID_HANDLE)
+ {
+ _fileHandle.Dispose();
+
+ if (throwIfInvalidHandle)
+ throw Win32Marshal.GetExceptionForWin32Error(errorCode);
+ }
+
+ return errorCode;
+ }
+
+ public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
+ {
+ // If we're in sync mode, just use the shared CopyToAsync implementation that does
+ // typical read/write looping. We also need to take this path if this is a derived
+ // instance from FileStream, as a derived type could have overridden ReadAsync, in which
+ // case our custom CopyToAsync implementation isn't necessarily correct.
+ if (!_useAsyncIO || GetType() != typeof(FileStream))
+ {
+ return base.CopyToAsync(destination, bufferSize, cancellationToken);
+ }
+
+ StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize);
+
+ // Bail early for cancellation if cancellation has been requested
+ if (cancellationToken.IsCancellationRequested)
+ {
+ return Task.FromCanceled<int>(cancellationToken);
+ }
+
+ // Fail if the file was closed
+ if (_fileHandle.IsClosed)
+ {
+ throw Error.GetFileNotOpen();
+ }
+
+ // Do the async copy, with differing implementations based on whether the FileStream was opened as async or sync
+ Debug.Assert((_readPos == 0 && _readLength == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLength), "We're either reading or writing, but not both.");
+ return AsyncModeCopyToAsync(destination, bufferSize, cancellationToken);
+ }
+
+ private async Task AsyncModeCopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
+ {
+ Debug.Assert(_useAsyncIO, "This implementation is for async mode only");
+ Debug.Assert(!_fileHandle.IsClosed, "!_handle.IsClosed");
+ Debug.Assert(CanRead, "_parent.CanRead");
+
+ // Make sure any pending writes have been flushed before we do a read.
+ if (_writePos > 0)
+ {
+ await FlushWriteAsync(cancellationToken).ConfigureAwait(false);
+ }
+
+ // Typically CopyToAsync would be invoked as the only "read" on the stream, but it's possible some reading is
+ // done and then the CopyToAsync is issued. For that case, see if we have any data available in the buffer.
+ if (GetBuffer() != null)
+ {
+ int bufferedBytes = _readLength - _readPos;
+ if (bufferedBytes > 0)
+ {
+ await destination.WriteAsync(GetBuffer(), _readPos, bufferedBytes, cancellationToken).ConfigureAwait(false);
+ _readPos = _readLength = 0;
+ }
+ }
+
+ // For efficiency, we avoid creating a new task and associated state for each asynchronous read.
+ // Instead, we create a single reusable awaitable object that will be triggered when an await completes
+ // and reset before going again.
+ var readAwaitable = new AsyncCopyToAwaitable(this);
+
+ // Make sure we are reading from the position that we think we are.
+ // Only set the position in the awaitable if we can seek (e.g. not for pipes).
+ bool canSeek = CanSeek;
+ if (canSeek)
+ {
+ VerifyOSHandlePosition();
+ readAwaitable._position = _filePosition;
+ }
+
+ // Get the buffer to use for the copy operation, as the base CopyToAsync does. We don't try to use
+ // _buffer here, even if it's not null, as concurrent operations are allowed, and another operation may
+ // actually be using the buffer already. Plus, it'll be rare for _buffer to be non-null, as typically
+ // CopyToAsync is used as the only operation performed on the stream, and the buffer is lazily initialized.
+ // Further, typically the CopyToAsync buffer size will be larger than that used by the FileStream, such that
+ // we'd likely be unable to use it anyway. Instead, we rent the buffer from a pool.
+ byte[] copyBuffer = ArrayPool<byte>.Shared.Rent(bufferSize);
+ bufferSize = 0; // repurpose bufferSize to be the high water mark for the buffer, to avoid an extra field in the state machine
+
+ // Allocate an Overlapped we can use repeatedly for all operations
+ var awaitableOverlapped = new PreAllocatedOverlapped(AsyncCopyToAwaitable.s_callback, readAwaitable, copyBuffer);
+ var cancellationReg = default(CancellationTokenRegistration);
+ try
+ {
+ // Register for cancellation. We do this once for the whole copy operation, and just try to cancel
+ // whatever read operation may currently be in progress, if there is one. It's possible the cancellation
+ // request could come in between operations, in which case we flag that with explicit calls to ThrowIfCancellationRequested
+ // in the read/write copy loop.
+ if (cancellationToken.CanBeCanceled)
+ {
+ cancellationReg = cancellationToken.Register(s =>
+ {
+ var innerAwaitable = (AsyncCopyToAwaitable)s;
+ unsafe
+ {
+ lock (innerAwaitable.CancellationLock) // synchronize with cleanup of the overlapped
+ {
+ if (innerAwaitable._nativeOverlapped != null)
+ {
+ // Try to cancel the I/O. We ignore the return value, as cancellation is opportunistic and we
+ // don't want to fail the operation because we couldn't cancel it.
+ Interop.Kernel32.CancelIoEx(innerAwaitable._fileStream._fileHandle, innerAwaitable._nativeOverlapped);
+ }
+ }
+ }
+ }, readAwaitable);
+ }
+
+ // Repeatedly read from this FileStream and write the results to the destination stream.
+ while (true)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+ readAwaitable.ResetForNextOperation();
+
+ try
+ {
+ bool synchronousSuccess;
+ int errorCode;
+ unsafe
+ {
+ // Allocate a native overlapped for our reusable overlapped, and set position to read based on the next
+ // desired address stored in the awaitable. (This position may be 0, if either we're at the beginning or
+ // if the stream isn't seekable.)
+ readAwaitable._nativeOverlapped = _fileHandle.ThreadPoolBinding.AllocateNativeOverlapped(awaitableOverlapped);
+ if (canSeek)
+ {
+ readAwaitable._nativeOverlapped->OffsetLow = unchecked((int)readAwaitable._position);
+ readAwaitable._nativeOverlapped->OffsetHigh = (int)(readAwaitable._position >> 32);
+ }
+
+ // Kick off the read.
+ synchronousSuccess = ReadFileNative(_fileHandle, copyBuffer, 0, copyBuffer.Length, readAwaitable._nativeOverlapped, out errorCode) >= 0;
+ }
+
+ // If the operation did not synchronously succeed, it either failed or initiated the asynchronous operation.
+ if (!synchronousSuccess)
+ {
+ switch (errorCode)
+ {
+ case ERROR_IO_PENDING:
+ // Async operation in progress.
+ break;
+ case ERROR_BROKEN_PIPE:
+ case ERROR_HANDLE_EOF:
+ // We're at or past the end of the file, and the overlapped callback
+ // won't be raised in these cases. Mark it as completed so that the await
+ // below will see it as such.
+ readAwaitable.MarkCompleted();
+ break;
+ default:
+ // Everything else is an error (and there won't be a callback).
+ throw Win32Marshal.GetExceptionForWin32Error(errorCode);
+ }
+ }
+
+ // Wait for the async operation (which may or may not have already completed), then throw if it failed.
+ await readAwaitable;
+ switch (readAwaitable._errorCode)
+ {
+ case 0: // success
+ Debug.Assert(readAwaitable._numBytes >= 0, $"Expected non-negative numBytes, got {readAwaitable._numBytes}");
+ break;
+ case ERROR_BROKEN_PIPE: // logically success with 0 bytes read (write end of pipe closed)
+ case ERROR_HANDLE_EOF: // logically success with 0 bytes read (read at end of file)
+ Debug.Assert(readAwaitable._numBytes == 0, $"Expected 0 bytes read, got {readAwaitable._numBytes}");
+ break;
+ case Interop.Errors.ERROR_OPERATION_ABORTED: // canceled
+ throw new OperationCanceledException(cancellationToken.IsCancellationRequested ? cancellationToken : new CancellationToken(true));
+ default: // error
+ throw Win32Marshal.GetExceptionForWin32Error((int)readAwaitable._errorCode);
+ }
+
+ // Successful operation. If we got zero bytes, we're done: exit the read/write loop.
+ int numBytesRead = (int)readAwaitable._numBytes;
+ if (numBytesRead == 0)
+ {
+ break;
+ }
+
+ // Otherwise, update the read position for next time accordingly.
+ if (canSeek)
+ {
+ readAwaitable._position += numBytesRead;
+ }
+
+ // (and keep track of the maximum number of bytes in the buffer we used, to avoid excessive and unnecessary
+ // clearing of the buffer before we return it to the pool)
+ if (numBytesRead > bufferSize)
+ {
+ bufferSize = numBytesRead;
+ }
+ }
+ finally
+ {
+ // Free the resources for this read operation
+ unsafe
+ {
+ NativeOverlapped* overlapped;
+ lock (readAwaitable.CancellationLock) // just an Exchange, but we need this to be synchronized with cancellation, so using the same lock
+ {
+ overlapped = readAwaitable._nativeOverlapped;
+ readAwaitable._nativeOverlapped = null;
+ }
+ if (overlapped != null)
+ {
+ _fileHandle.ThreadPoolBinding.FreeNativeOverlapped(overlapped);
+ }
+ }
+ }
+
+ // Write out the read data.
+ await destination.WriteAsync(copyBuffer, 0, (int)readAwaitable._numBytes, cancellationToken).ConfigureAwait(false);
+ }
+ }
+ finally
+ {
+ // Cleanup from the whole copy operation
+ cancellationReg.Dispose();
+ awaitableOverlapped.Dispose();
+
+ Array.Clear(copyBuffer, 0, bufferSize);
+ ArrayPool<byte>.Shared.Return(copyBuffer, clearArray: false);
+
+ // Make sure the stream's current position reflects where we ended up
+ if (!_fileHandle.IsClosed && CanSeek)
+ {
+ SeekCore(0, SeekOrigin.End);
+ }
+ }
+ }
+
+ /// <summary>Used by CopyToAsync to enable awaiting the result of an overlapped I/O operation with minimal overhead.</summary>
+ private sealed unsafe class AsyncCopyToAwaitable : ICriticalNotifyCompletion
+ {
+ /// <summary>Sentinel object used to indicate that the I/O operation has completed before being awaited.</summary>
+ private readonly static Action s_sentinel = () => { };
+ /// <summary>Cached delegate to IOCallback.</summary>
+ internal static readonly IOCompletionCallback s_callback = IOCallback;
+
+ /// <summary>The FileStream that owns this instance.</summary>
+ internal readonly FileStream _fileStream;
+
+ /// <summary>Tracked position representing the next location from which to read.</summary>
+ internal long _position;
+ /// <summary>The current native overlapped pointer. This changes for each operation.</summary>
+ internal NativeOverlapped* _nativeOverlapped;
+ /// <summary>
+ /// null if the operation is still in progress,
+ /// s_sentinel if the I/O operation completed before the await,
+ /// s_callback if it completed after the await yielded.
+ /// </summary>
+ internal Action _continuation;
+ /// <summary>Last error code from completed operation.</summary>
+ internal uint _errorCode;
+ /// <summary>Last number of read bytes from completed operation.</summary>
+ internal uint _numBytes;
+
+ /// <summary>Lock object used to protect cancellation-related access to _nativeOverlapped.</summary>
+ internal object CancellationLock => this;
+
+ /// <summary>Initialize the awaitable.</summary>
+ internal unsafe AsyncCopyToAwaitable(FileStream fileStream)
+ {
+ _fileStream = fileStream;
+ }
+
+ /// <summary>Reset state to prepare for the next read operation.</summary>
+ internal void ResetForNextOperation()
+ {
+ Debug.Assert(_position >= 0, $"Expected non-negative position, got {_position}");
+ _continuation = null;
+ _errorCode = 0;
+ _numBytes = 0;
+ }
+
+ /// <summary>Overlapped callback: store the results, then invoke the continuation delegate.</summary>
+ internal unsafe static void IOCallback(uint errorCode, uint numBytes, NativeOverlapped* pOVERLAP)
+ {
+ var awaitable = (AsyncCopyToAwaitable)ThreadPoolBoundHandle.GetNativeOverlappedState(pOVERLAP);
+
+ Debug.Assert(awaitable._continuation != s_sentinel, "Sentinel must not have already been set as the continuation");
+ awaitable._errorCode = errorCode;
+ awaitable._numBytes = numBytes;
+
+ (awaitable._continuation ?? Interlocked.CompareExchange(ref awaitable._continuation, s_sentinel, null))?.Invoke();
+ }
+
+ /// <summary>
+ /// Called when it's known that the I/O callback for an operation will not be invoked but we'll
+ /// still be awaiting the awaitable.
+ /// </summary>
+ internal void MarkCompleted()
+ {
+ Debug.Assert(_continuation == null, "Expected null continuation");
+ _continuation = s_sentinel;
+ }
+
+ public AsyncCopyToAwaitable GetAwaiter() => this;
+ public bool IsCompleted => _continuation == s_sentinel;
+ public void GetResult() { }
+ public void OnCompleted(Action continuation) => UnsafeOnCompleted(continuation);
+ public void UnsafeOnCompleted(Action continuation)
+ {
+ if (_continuation == s_sentinel ||
+ Interlocked.CompareExchange(ref _continuation, continuation, null) != null)
+ {
+ Debug.Assert(_continuation == s_sentinel, $"Expected continuation set to s_sentinel, got ${_continuation}");
+ Task.Run(continuation);
+ }
+ }
+ }
+
+ // Unlike Flush(), FlushAsync() always flushes to disk. This is intentional.
+ // Legend is that we chose not to flush the OS file buffers in Flush() in fear of
+ // perf problems with frequent, long running FlushFileBuffers() calls. But we don't
+ // have that problem with FlushAsync() because we will call FlushFileBuffers() in the background.
+ private Task FlushAsyncInternal(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ return Task.FromCanceled(cancellationToken);
+
+ if (_fileHandle.IsClosed)
+ throw Error.GetFileNotOpen();
+
+ // The always synchronous data transfer between the OS and the internal buffer is intentional
+ // because this is needed to allow concurrent async IO requests. Concurrent data transfer
+ // between the OS and the internal buffer will result in race conditions. Since FlushWrite and
+ // FlushRead modify internal state of the stream and transfer data between the OS and the
+ // internal buffer, they cannot be truly async. We will, however, flush the OS file buffers
+ // asynchronously because it doesn't modify any internal state of the stream and is potentially
+ // a long running process.
+ try
+ {
+ FlushInternalBuffer();
+ }
+ catch (Exception e)
+ {
+ return Task.FromException(e);
+ }
+
+ if (CanWrite)
+ {
+ return Task.Factory.StartNew(
+ state => ((FileStream)state).FlushOSBuffer(),
+ this,
+ cancellationToken,
+ TaskCreationOptions.DenyChildAttach,
+ TaskScheduler.Default);
+ }
+ else
+ {
+ return Task.CompletedTask;
+ }
+ }
+
+ private Task<int> TaskFromResultOrCache(int result)
+ {
+ Task<int> completedTask = _lastSynchronouslyCompletedTask;
+ Debug.Assert(completedTask == null || completedTask.Status == TaskStatus.RanToCompletion, "Cached task should have completed successfully");
+
+ if ((completedTask == null) || (completedTask.Result != result))
+ {
+ completedTask = Task.FromResult(result);
+ _lastSynchronouslyCompletedTask = completedTask;
+ }
+
+ return completedTask;
+ }
+
+ private void LockInternal(long position, long length)
+ {
+ int positionLow = unchecked((int)(position));
+ int positionHigh = unchecked((int)(position >> 32));
+ int lengthLow = unchecked((int)(length));
+ int lengthHigh = unchecked((int)(length >> 32));
+
+ if (!Interop.Kernel32.LockFile(_fileHandle, positionLow, positionHigh, lengthLow, lengthHigh))
+ {
+ throw Win32Marshal.GetExceptionForLastWin32Error();
+ }
+ }
+
+ private void UnlockInternal(long position, long length)
+ {
+ int positionLow = unchecked((int)(position));
+ int positionHigh = unchecked((int)(position >> 32));
+ int lengthLow = unchecked((int)(length));
+ int lengthHigh = unchecked((int)(length >> 32));
+
+ if (!Interop.Kernel32.UnlockFile(_fileHandle, positionLow, positionHigh, lengthLow, lengthHigh))
+ {
+ throw Win32Marshal.GetExceptionForLastWin32Error();
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/IO/FileStream.cs b/src/mscorlib/shared/System/IO/FileStream.cs
index 7db8518435..7db8518435 100644
--- a/src/mscorlib/corefx/System/IO/FileStream.cs
+++ b/src/mscorlib/shared/System/IO/FileStream.cs
diff --git a/src/mscorlib/shared/System/IO/FileStreamCompletionSource.Win32.cs b/src/mscorlib/shared/System/IO/FileStreamCompletionSource.Win32.cs
new file mode 100644
index 0000000000..7dca13335e
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/FileStreamCompletionSource.Win32.cs
@@ -0,0 +1,222 @@
+// 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.Security;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+using System.Diagnostics;
+
+namespace System.IO
+{
+ public partial class FileStream : Stream
+ {
+ // This is an internal object extending TaskCompletionSource with fields
+ // for all of the relevant data necessary to complete the IO operation.
+ // This is used by IOCallback and all of the async methods.
+ unsafe private sealed class FileStreamCompletionSource : TaskCompletionSource<int>
+ {
+ private const long NoResult = 0;
+ private const long ResultSuccess = (long)1 << 32;
+ private const long ResultError = (long)2 << 32;
+ private const long RegisteringCancellation = (long)4 << 32;
+ private const long CompletedCallback = (long)8 << 32;
+ private const ulong ResultMask = ((ulong)uint.MaxValue) << 32;
+
+ private static Action<object> s_cancelCallback;
+
+ private readonly FileStream _stream;
+ private readonly int _numBufferedBytes;
+ private readonly CancellationToken _cancellationToken;
+ private CancellationTokenRegistration _cancellationRegistration;
+#if DEBUG
+ private bool _cancellationHasBeenRegistered;
+#endif
+ private NativeOverlapped* _overlapped; // Overlapped class responsible for operations in progress when an appdomain unload occurs
+ private long _result; // Using long since this needs to be used in Interlocked APIs
+
+ // Using RunContinuationsAsynchronously for compat reasons (old API used Task.Factory.StartNew for continuations)
+ internal FileStreamCompletionSource(FileStream stream, int numBufferedBytes, byte[] bytes, CancellationToken cancellationToken)
+ : base(TaskCreationOptions.RunContinuationsAsynchronously)
+ {
+ _numBufferedBytes = numBufferedBytes;
+ _stream = stream;
+ _result = NoResult;
+ _cancellationToken = cancellationToken;
+
+ // Create the native overlapped. We try to use the preallocated overlapped if possible:
+ // it's possible if the byte buffer is the same one that's associated with the preallocated overlapped
+ // and if no one else is currently using the preallocated overlapped. This is the fast-path for cases
+ // where the user-provided buffer is smaller than the FileStream's buffer (such that the FileStream's
+ // buffer is used) and where operations on the FileStream are not being performed concurrently.
+ _overlapped = ReferenceEquals(bytes, _stream._buffer) && _stream.CompareExchangeCurrentOverlappedOwner(this, null) == null ?
+ _stream._fileHandle.ThreadPoolBinding.AllocateNativeOverlapped(_stream._preallocatedOverlapped) :
+ _stream._fileHandle.ThreadPoolBinding.AllocateNativeOverlapped(s_ioCallback, this, bytes);
+ Debug.Assert(_overlapped != null, "AllocateNativeOverlapped returned null");
+ }
+
+ internal NativeOverlapped* Overlapped
+ {
+ get { return _overlapped; }
+ }
+
+ public void SetCompletedSynchronously(int numBytes)
+ {
+ ReleaseNativeResource();
+ TrySetResult(numBytes + _numBufferedBytes);
+ }
+
+ public void RegisterForCancellation()
+ {
+#if DEBUG
+ Debug.Assert(!_cancellationHasBeenRegistered, "Cannot register for cancellation twice");
+ _cancellationHasBeenRegistered = true;
+#endif
+
+ // Quick check to make sure that the cancellation token supports cancellation, and that the IO hasn't completed
+ if ((_cancellationToken.CanBeCanceled) && (_overlapped != null))
+ {
+ var cancelCallback = s_cancelCallback;
+ if (cancelCallback == null) s_cancelCallback = cancelCallback = Cancel;
+
+ // Register the cancellation only if the IO hasn't completed
+ long packedResult = Interlocked.CompareExchange(ref _result, RegisteringCancellation, NoResult);
+ if (packedResult == NoResult)
+ {
+ _cancellationRegistration = _cancellationToken.Register(cancelCallback, this);
+
+ // Switch the result, just in case IO completed while we were setting the registration
+ packedResult = Interlocked.Exchange(ref _result, NoResult);
+ }
+ else if (packedResult != CompletedCallback)
+ {
+ // Failed to set the result, IO is in the process of completing
+ // Attempt to take the packed result
+ packedResult = Interlocked.Exchange(ref _result, NoResult);
+ }
+
+ // If we have a callback that needs to be completed
+ if ((packedResult != NoResult) && (packedResult != CompletedCallback) && (packedResult != RegisteringCancellation))
+ {
+ CompleteCallback((ulong)packedResult);
+ }
+ }
+ }
+
+ internal void ReleaseNativeResource()
+ {
+ // Ensure that cancellation has been completed and cleaned up.
+ _cancellationRegistration.Dispose();
+
+ // Free the overlapped.
+ // NOTE: The cancellation must *NOT* be running at this point, or it may observe freed memory
+ // (this is why we disposed the registration above).
+ if (_overlapped != null)
+ {
+ _stream._fileHandle.ThreadPoolBinding.FreeNativeOverlapped(_overlapped);
+ _overlapped = null;
+ }
+
+ // Ensure we're no longer set as the current completion source (we may not have been to begin with).
+ // Only one operation at a time is eligible to use the preallocated overlapped,
+ _stream.CompareExchangeCurrentOverlappedOwner(null, this);
+ }
+
+ // When doing IO asynchronously (i.e. _isAsync==true), this callback is
+ // called by a free thread in the threadpool when the IO operation
+ // completes.
+ internal static unsafe void IOCallback(uint errorCode, uint numBytes, NativeOverlapped* pOverlapped)
+ {
+ // Extract the completion source from the overlapped. The state in the overlapped
+ // will either be a Win32FileStream (in the case where the preallocated overlapped was used),
+ // in which case the operation being completed is its _currentOverlappedOwner, or it'll
+ // be directly the FileStreamCompletion that's completing (in the case where the preallocated
+ // overlapped was already in use by another operation).
+ object state = ThreadPoolBoundHandle.GetNativeOverlappedState(pOverlapped);
+ FileStream fs = state as FileStream;
+ FileStreamCompletionSource completionSource = fs != null ?
+ fs._currentOverlappedOwner :
+ (FileStreamCompletionSource)state;
+ Debug.Assert(completionSource._overlapped == pOverlapped, "Overlaps don't match");
+
+ // Handle reading from & writing to closed pipes. While I'm not sure
+ // this is entirely necessary anymore, maybe it's possible for
+ // an async read on a pipe to be issued and then the pipe is closed,
+ // returning this error. This may very well be necessary.
+ ulong packedResult;
+ if (errorCode != 0 && errorCode != ERROR_BROKEN_PIPE && errorCode != ERROR_NO_DATA)
+ {
+ packedResult = ((ulong)ResultError | errorCode);
+ }
+ else
+ {
+ packedResult = ((ulong)ResultSuccess | numBytes);
+ }
+
+ // Stow the result so that other threads can observe it
+ // And, if no other thread is registering cancellation, continue
+ if (NoResult == Interlocked.Exchange(ref completionSource._result, (long)packedResult))
+ {
+ // Successfully set the state, attempt to take back the callback
+ if (Interlocked.Exchange(ref completionSource._result, CompletedCallback) != NoResult)
+ {
+ // Successfully got the callback, finish the callback
+ completionSource.CompleteCallback(packedResult);
+ }
+ // else: Some other thread stole the result, so now it is responsible to finish the callback
+ }
+ // else: Some other thread is registering a cancellation, so it *must* finish the callback
+ }
+
+ private void CompleteCallback(ulong packedResult)
+ {
+ // Free up the native resource and cancellation registration
+ ReleaseNativeResource();
+
+ // Unpack the result and send it to the user
+ long result = (long)(packedResult & ResultMask);
+ if (result == ResultError)
+ {
+ int errorCode = unchecked((int)(packedResult & uint.MaxValue));
+ if (errorCode == Interop.Errors.ERROR_OPERATION_ABORTED)
+ {
+ TrySetCanceled(_cancellationToken.IsCancellationRequested ? _cancellationToken : new CancellationToken(true));
+ }
+ else
+ {
+ TrySetException(Win32Marshal.GetExceptionForWin32Error(errorCode));
+ }
+ }
+ else
+ {
+ Debug.Assert(result == ResultSuccess, "Unknown result");
+ TrySetResult((int)(packedResult & uint.MaxValue) + _numBufferedBytes);
+ }
+ }
+
+ private static void Cancel(object state)
+ {
+ // WARNING: This may potentially be called under a lock (during cancellation registration)
+
+ FileStreamCompletionSource completionSource = state as FileStreamCompletionSource;
+ Debug.Assert(completionSource != null, "Unknown state passed to cancellation");
+ Debug.Assert(completionSource._overlapped != null && !completionSource.Task.IsCompleted, "IO should not have completed yet");
+
+ // If the handle is still valid, attempt to cancel the IO
+ if (!completionSource._stream._fileHandle.IsInvalid &&
+ !Interop.Kernel32.CancelIoEx(completionSource._stream._fileHandle, completionSource._overlapped))
+ {
+ int errorCode = Marshal.GetLastWin32Error();
+
+ // ERROR_NOT_FOUND is returned if CancelIoEx cannot find the request to cancel.
+ // This probably means that the IO operation has completed.
+ if (errorCode != Interop.Errors.ERROR_NOT_FOUND)
+ {
+ throw Win32Marshal.GetExceptionForWin32Error(errorCode);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/Path.Unix.cs b/src/mscorlib/shared/System/IO/Path.Unix.cs
new file mode 100644
index 0000000000..500c60aa8c
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/Path.Unix.cs
@@ -0,0 +1,215 @@
+// 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.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace System.IO
+{
+ public static partial class Path
+ {
+ public static char[] GetInvalidFileNameChars() => new char[] { '\0', '/' };
+
+ public static char[] GetInvalidPathChars() => new char[] { '\0' };
+
+ internal static int MaxPath => Interop.Sys.MaxPath;
+
+ // Expands the given path to a fully qualified path.
+ public static string GetFullPath(string path)
+ {
+ if (path == null)
+ throw new ArgumentNullException(nameof(path));
+
+ if (path.Length == 0)
+ throw new ArgumentException(SR.Arg_PathIllegal);
+
+ PathInternal.CheckInvalidPathChars(path);
+
+ // Expand with current directory if necessary
+ if (!IsPathRooted(path))
+ {
+ path = Combine(Interop.Sys.GetCwd(), path);
+ }
+
+ // We would ideally use realpath to do this, but it resolves symlinks, requires that the file actually exist,
+ // and turns it into a full path, which we only want if fullCheck is true.
+ string collapsedString = RemoveRelativeSegments(path);
+
+ Debug.Assert(collapsedString.Length < path.Length || collapsedString.ToString() == path,
+ "Either we've removed characters, or the string should be unmodified from the input path.");
+
+ if (collapsedString.Length > Interop.Sys.MaxPath)
+ {
+ throw new PathTooLongException(SR.IO_PathTooLong);
+ }
+
+ string result = collapsedString.Length == 0 ? PathInternal.DirectorySeparatorCharAsString : collapsedString;
+
+ return result;
+ }
+
+ /// <summary>
+ /// Try to remove relative segments from the given path (without combining with a root).
+ /// </summary>
+ /// <param name="skip">Skip the specified number of characters before evaluating.</param>
+ private static string RemoveRelativeSegments(string path, int skip = 0)
+ {
+ bool flippedSeparator = false;
+
+ // Remove "//", "/./", and "/../" from the path by copying each character to the output,
+ // except the ones we're removing, such that the builder contains the normalized path
+ // at the end.
+ var sb = StringBuilderCache.Acquire(path.Length);
+ if (skip > 0)
+ {
+ sb.Append(path, 0, skip);
+ }
+
+ int componentCharCount = 0;
+ for (int i = skip; i < path.Length; i++)
+ {
+ char c = path[i];
+
+ if (PathInternal.IsDirectorySeparator(c) && i + 1 < path.Length)
+ {
+ componentCharCount = 0;
+
+ // Skip this character if it's a directory separator and if the next character is, too,
+ // e.g. "parent//child" => "parent/child"
+ if (PathInternal.IsDirectorySeparator(path[i + 1]))
+ {
+ continue;
+ }
+
+ // Skip this character and the next if it's referring to the current directory,
+ // e.g. "parent/./child" =? "parent/child"
+ if ((i + 2 == path.Length || PathInternal.IsDirectorySeparator(path[i + 2])) &&
+ path[i + 1] == '.')
+ {
+ i++;
+ continue;
+ }
+
+ // Skip this character and the next two if it's referring to the parent directory,
+ // e.g. "parent/child/../grandchild" => "parent/grandchild"
+ if (i + 2 < path.Length &&
+ (i + 3 == path.Length || PathInternal.IsDirectorySeparator(path[i + 3])) &&
+ path[i + 1] == '.' && path[i + 2] == '.')
+ {
+ // Unwind back to the last slash (and if there isn't one, clear out everything).
+ int s;
+ for (s = sb.Length - 1; s >= 0; s--)
+ {
+ if (PathInternal.IsDirectorySeparator(sb[s]))
+ {
+ sb.Length = s;
+ break;
+ }
+ }
+ if (s < 0)
+ {
+ sb.Length = 0;
+ }
+
+ i += 2;
+ continue;
+ }
+ }
+
+ if (++componentCharCount > Interop.Sys.MaxName)
+ {
+ throw new PathTooLongException(SR.IO_PathTooLong);
+ }
+
+ // Normalize the directory separator if needed
+ if (c != PathInternal.DirectorySeparatorChar && c == PathInternal.AltDirectorySeparatorChar)
+ {
+ c = PathInternal.DirectorySeparatorChar;
+ flippedSeparator = true;
+ }
+
+ sb.Append(c);
+ }
+
+ if (flippedSeparator || sb.Length != path.Length)
+ {
+ return StringBuilderCache.GetStringAndRelease(sb);
+ }
+ else
+ {
+ // We haven't changed the source path, return the original
+ StringBuilderCache.Release(sb);
+ return path;
+ }
+ }
+
+ private static string RemoveLongPathPrefix(string path)
+ {
+ return path; // nop. There's nothing special about "long" paths on Unix.
+ }
+
+ public static string GetTempPath()
+ {
+ const string TempEnvVar = "TMPDIR";
+ const string DefaultTempPath = "/tmp/";
+
+ // Get the temp path from the TMPDIR environment variable.
+ // If it's not set, just return the default path.
+ // If it is, return it, ensuring it ends with a slash.
+ string path = Environment.GetEnvironmentVariable(TempEnvVar);
+ return
+ string.IsNullOrEmpty(path) ? DefaultTempPath :
+ PathInternal.IsDirectorySeparator(path[path.Length - 1]) ? path :
+ path + PathInternal.DirectorySeparatorChar;
+ }
+
+ public static string GetTempFileName()
+ {
+ const string Suffix = ".tmp";
+ const int SuffixByteLength = 4;
+
+ // mkstemps takes a char* and overwrites the XXXXXX with six characters
+ // that'll result in a unique file name.
+ string template = GetTempPath() + "tmpXXXXXX" + Suffix + "\0";
+ byte[] name = Encoding.UTF8.GetBytes(template);
+
+ // Create, open, and close the temp file.
+ IntPtr fd = Interop.CheckIo(Interop.Sys.MksTemps(name, SuffixByteLength));
+ Interop.Sys.Close(fd); // ignore any errors from close; nothing to do if cleanup isn't possible
+
+ // 'name' is now the name of the file
+ Debug.Assert(name[name.Length - 1] == '\0');
+ return Encoding.UTF8.GetString(name, 0, name.Length - 1); // trim off the trailing '\0'
+ }
+
+ public static bool IsPathRooted(string path)
+ {
+ if (path == null)
+ return false;
+
+ PathInternal.CheckInvalidPathChars(path);
+ return path.Length > 0 && path[0] == PathInternal.DirectorySeparatorChar;
+ }
+
+ public static string GetPathRoot(string path)
+ {
+ if (path == null) return null;
+ return IsPathRooted(path) ? PathInternal.DirectorySeparatorCharAsString : String.Empty;
+ }
+
+ /// <summary>Gets whether the system is case-sensitive.</summary>
+ internal static bool IsCaseSensitive
+ {
+ get
+ {
+ #if PLATFORM_OSX
+ return false;
+ #else
+ return true;
+ #endif
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/Path.Windows.cs b/src/mscorlib/shared/System/IO/Path.Windows.cs
new file mode 100644
index 0000000000..d6f0c628c3
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/Path.Windows.cs
@@ -0,0 +1,155 @@
+// 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.Diagnostics;
+using System.Text;
+
+namespace System.IO
+{
+ public static partial class Path
+ {
+ public static char[] GetInvalidFileNameChars() => new char[]
+ {
+ '\"', '<', '>', '|', '\0',
+ (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10,
+ (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20,
+ (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30,
+ (char)31, ':', '*', '?', '\\', '/'
+ };
+
+ public static char[] GetInvalidPathChars() => new char[]
+ {
+ '|', '\0',
+ (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10,
+ (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20,
+ (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30,
+ (char)31
+ };
+
+ // The max total path is 260, and the max individual component length is 255.
+ // For example, D:\<256 char file name> isn't legal, even though it's under 260 chars.
+ internal const int MaxPath = 260;
+
+ // Expands the given path to a fully qualified path.
+ public static string GetFullPath(string path)
+ {
+ if (path == null)
+ throw new ArgumentNullException(nameof(path));
+
+ // Embedded null characters are the only invalid character case we want to check up front.
+ // This is because the nulls will signal the end of the string to Win32 and therefore have
+ // unpredictable results. Other invalid characters we give a chance to be normalized out.
+ if (path.IndexOf('\0') != -1)
+ throw new ArgumentException(SR.Argument_InvalidPathChars, nameof(path));
+
+ if (PathInternal.IsExtended(path))
+ {
+ // We can't really know what is valid for all cases of extended paths.
+ //
+ // - object names can include other characters as well (':', '/', etc.)
+ // - even file objects have different rules (pipe names can contain most characters)
+ //
+ // As such we will do no further analysis of extended paths to avoid blocking known and unknown
+ // scenarios as well as minimizing compat breaks should we block now and need to unblock later.
+ return path;
+ }
+
+ bool isDevice = PathInternal.IsDevice(path);
+ if (!isDevice)
+ {
+ // Toss out paths with colons that aren't a valid drive specifier.
+ // Cannot start with a colon and can only be of the form "C:".
+ // (Note that we used to explicitly check "http:" and "file:"- these are caught by this check now.)
+ int startIndex = PathInternal.PathStartSkip(path);
+
+ // Move past the colon
+ startIndex += 2;
+
+ if ((path.Length > 0 && path[0] == PathInternal.VolumeSeparatorChar)
+ || (path.Length >= startIndex && path[startIndex - 1] == PathInternal.VolumeSeparatorChar && !PathInternal.IsValidDriveChar(path[startIndex - 2]))
+ || (path.Length > startIndex && path.IndexOf(PathInternal.VolumeSeparatorChar, startIndex) != -1))
+ {
+ throw new NotSupportedException(SR.Argument_PathFormatNotSupported);
+ }
+ }
+
+ // Technically this doesn't matter but we used to throw for this case
+ if (string.IsNullOrWhiteSpace(path))
+ throw new ArgumentException(SR.Arg_PathIllegal);
+
+ // We don't want to check invalid characters for device format- see comments for extended above
+ string fullPath = PathHelper.Normalize(path, checkInvalidCharacters: !isDevice, expandShortPaths: true);
+
+ if (!isDevice)
+ {
+ // Emulate FileIOPermissions checks, retained for compatibility (normal invalid characters have already been checked)
+ if (PathInternal.HasWildCardCharacters(fullPath))
+ throw new ArgumentException(SR.Argument_InvalidPathChars, nameof(path));
+ }
+
+ return fullPath;
+ }
+
+ public static string GetTempPath()
+ {
+ StringBuilder sb = StringBuilderCache.Acquire(MaxPath);
+ uint r = Interop.Kernel32.GetTempPathW(MaxPath, sb);
+ if (r == 0)
+ throw Win32Marshal.GetExceptionForLastWin32Error();
+ return GetFullPath(StringBuilderCache.GetStringAndRelease(sb));
+ }
+
+ // Returns a unique temporary file name, and creates a 0-byte file by that
+ // name on disk.
+ public static string GetTempFileName()
+ {
+ string path = GetTempPath();
+
+ StringBuilder sb = StringBuilderCache.Acquire(MaxPath);
+ uint r = Interop.Kernel32.GetTempFileNameW(path, "tmp", 0, sb);
+ if (r == 0)
+ throw Win32Marshal.GetExceptionForLastWin32Error();
+ return StringBuilderCache.GetStringAndRelease(sb);
+ }
+
+ // Tests if the given path contains a root. A path is considered rooted
+ // if it starts with a backslash ("\") or a valid drive letter and a colon (":").
+ public static bool IsPathRooted(string path)
+ {
+ if (path != null)
+ {
+ PathInternal.CheckInvalidPathChars(path);
+
+ int length = path.Length;
+ if ((length >= 1 && PathInternal.IsDirectorySeparator(path[0])) ||
+ (length >= 2 && PathInternal.IsValidDriveChar(path[0]) && path[1] == PathInternal.VolumeSeparatorChar))
+ return true;
+ }
+ return false;
+ }
+
+ // Returns the root portion of the given path. The resulting string
+ // consists of those rightmost characters of the path that constitute the
+ // root of the path. Possible patterns for the resulting string are: An
+ // empty string (a relative path on the current drive), "\" (an absolute
+ // path on the current drive), "X:" (a relative path on a given drive,
+ // where X is the drive letter), "X:\" (an absolute path on a given drive),
+ // and "\\server\share" (a UNC path for a given server and share name).
+ // The resulting string is null if path is null.
+ public static string GetPathRoot(string path)
+ {
+ if (path == null) return null;
+ PathInternal.CheckInvalidPathChars(path);
+
+ // Need to return the normalized directory separator
+ path = PathInternal.NormalizeDirectorySeparators(path);
+
+ int pathRoot = PathInternal.GetRootLength(path);
+ return pathRoot <= 0 ? string.Empty : path.Substring(0, pathRoot);
+ }
+
+ /// <summary>Gets whether the system is case-sensitive.</summary>
+ internal static bool IsCaseSensitive { get { return false; } }
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/Path.cs b/src/mscorlib/shared/System/IO/Path.cs
new file mode 100644
index 0000000000..b3a8783c32
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/Path.cs
@@ -0,0 +1,574 @@
+// 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.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Text;
+
+namespace System.IO
+{
+ // Provides methods for processing file system strings in a cross-platform manner.
+ // Most of the methods don't do a complete parsing (such as examining a UNC hostname),
+ // but they will handle most string operations.
+ public static partial class Path
+ {
+ // Public static readonly variant of the separators. The Path implementation itself is using
+ // internal const variant of the separators for better performance.
+ public static readonly char DirectorySeparatorChar = PathInternal.DirectorySeparatorChar;
+ public static readonly char AltDirectorySeparatorChar = PathInternal.AltDirectorySeparatorChar;
+ public static readonly char VolumeSeparatorChar = PathInternal.VolumeSeparatorChar;
+ public static readonly char PathSeparator = PathInternal.PathSeparator;
+
+ // For generating random file names
+ // 8 random bytes provides 12 chars in our encoding for the 8.3 name.
+ private const int KeyLength = 8;
+
+ [Obsolete("Please use GetInvalidPathChars or GetInvalidFileNameChars instead.")]
+ public static readonly char[] InvalidPathChars = GetInvalidPathChars();
+
+ // Changes the extension of a file path. The path parameter
+ // specifies a file path, and the extension parameter
+ // specifies a file extension (with a leading period, such as
+ // ".exe" or ".cs").
+ //
+ // The function returns a file path with the same root, directory, and base
+ // name parts as path, but with the file extension changed to
+ // the specified extension. If path is null, the function
+ // returns null. If path does not contain a file extension,
+ // the new file extension is appended to the path. If extension
+ // is null, any existing extension is removed from path.
+ public static string ChangeExtension(string path, string extension)
+ {
+ if (path != null)
+ {
+ PathInternal.CheckInvalidPathChars(path);
+
+ string s = path;
+ for (int i = path.Length - 1; i >= 0; i--)
+ {
+ char ch = path[i];
+ if (ch == '.')
+ {
+ s = path.Substring(0, i);
+ break;
+ }
+ if (PathInternal.IsDirectoryOrVolumeSeparator(ch)) break;
+ }
+
+ if (extension != null && path.Length != 0)
+ {
+ s = (extension.Length == 0 || extension[0] != '.') ?
+ s + "." + extension :
+ s + extension;
+ }
+
+ return s;
+ }
+ return null;
+ }
+
+ // Returns the directory path of a file path. This method effectively
+ // removes the last element of the given file path, i.e. it returns a
+ // string consisting of all characters up to but not including the last
+ // backslash ("\") in the file path. The returned value is null if the file
+ // path is null or if the file path denotes a root (such as "\", "C:", or
+ // "\\server\share").
+ public static string GetDirectoryName(string path)
+ {
+ if (path != null)
+ {
+ PathInternal.CheckInvalidPathChars(path);
+ path = PathInternal.NormalizeDirectorySeparators(path);
+ int root = PathInternal.GetRootLength(path);
+
+ int i = path.Length;
+ if (i > root)
+ {
+ while (i > root && !PathInternal.IsDirectorySeparator(path[--i])) ;
+ return path.Substring(0, i);
+ }
+ }
+ return null;
+ }
+
+ // Returns the extension of the given path. The returned value includes the
+ // period (".") character of the extension except when you have a terminal period when you get string.Empty, such as ".exe" or
+ // ".cpp". The returned value is null if the given path is
+ // null or if the given path does not include an extension.
+ [Pure]
+ public static string GetExtension(string path)
+ {
+ if (path == null)
+ return null;
+
+ PathInternal.CheckInvalidPathChars(path);
+ int length = path.Length;
+ for (int i = length - 1; i >= 0; i--)
+ {
+ char ch = path[i];
+ if (ch == '.')
+ {
+ if (i != length - 1)
+ return path.Substring(i, length - i);
+ else
+ return string.Empty;
+ }
+ if (PathInternal.IsDirectoryOrVolumeSeparator(ch))
+ break;
+ }
+ return string.Empty;
+ }
+
+ // Returns the name and extension parts of the given path. The resulting
+ // string contains the characters of path that follow the last
+ // separator in path. The resulting string is null if path is null.
+ [Pure]
+ public static string GetFileName(string path)
+ {
+ if (path == null)
+ return null;
+
+ int offset = PathInternal.FindFileNameIndex(path);
+ int count = path.Length - offset;
+ return path.Substring(offset, count);
+ }
+
+ [Pure]
+ public static string GetFileNameWithoutExtension(string path)
+ {
+ if (path == null)
+ return null;
+
+ int length = path.Length;
+ int offset = PathInternal.FindFileNameIndex(path);
+
+ int end = path.LastIndexOf('.', length - 1, length - offset);
+ return end == -1 ?
+ path.Substring(offset) : // No extension was found
+ path.Substring(offset, end - offset);
+ }
+
+ // Returns a cryptographically strong random 8.3 string that can be
+ // used as either a folder name or a file name.
+ public static unsafe string GetRandomFileName()
+ {
+ byte* pKey = stackalloc byte[KeyLength];
+ Interop.GetRandomBytes(pKey, KeyLength);
+
+ const int RandomFileNameLength = 12;
+ char* pRandomFileName = stackalloc char[RandomFileNameLength];
+ Populate83FileNameFromRandomBytes(pKey, KeyLength, pRandomFileName, RandomFileNameLength);
+ return new string(pRandomFileName, 0, RandomFileNameLength);
+ }
+
+ // Tests if a path includes a file extension. The result is
+ // true if the characters that follow the last directory
+ // separator ('\\' or '/') or volume separator (':') in the path include
+ // a period (".") other than a terminal period. The result is false otherwise.
+ [Pure]
+ public static bool HasExtension(string path)
+ {
+ if (path != null)
+ {
+ PathInternal.CheckInvalidPathChars(path);
+
+ for (int i = path.Length - 1; i >= 0; i--)
+ {
+ char ch = path[i];
+ if (ch == '.')
+ {
+ return i != path.Length - 1;
+ }
+ if (PathInternal.IsDirectoryOrVolumeSeparator(ch)) break;
+ }
+ }
+ return false;
+ }
+
+ public static string Combine(string path1, string path2)
+ {
+ if (path1 == null || path2 == null)
+ throw new ArgumentNullException((path1 == null) ? nameof(path1) : nameof(path2));
+ Contract.EndContractBlock();
+
+ PathInternal.CheckInvalidPathChars(path1);
+ PathInternal.CheckInvalidPathChars(path2);
+
+ return CombineNoChecks(path1, path2);
+ }
+
+ public static string Combine(string path1, string path2, string path3)
+ {
+ if (path1 == null || path2 == null || path3 == null)
+ throw new ArgumentNullException((path1 == null) ? nameof(path1) : (path2 == null) ? nameof(path2) : nameof(path3));
+ Contract.EndContractBlock();
+
+ PathInternal.CheckInvalidPathChars(path1);
+ PathInternal.CheckInvalidPathChars(path2);
+ PathInternal.CheckInvalidPathChars(path3);
+
+ return CombineNoChecks(path1, path2, path3);
+ }
+
+ public static string Combine(string path1, string path2, string path3, string path4)
+ {
+ if (path1 == null || path2 == null || path3 == null || path4 == null)
+ throw new ArgumentNullException((path1 == null) ? nameof(path1) : (path2 == null) ? nameof(path2) : (path3 == null) ? nameof(path3) : nameof(path4));
+ Contract.EndContractBlock();
+
+ PathInternal.CheckInvalidPathChars(path1);
+ PathInternal.CheckInvalidPathChars(path2);
+ PathInternal.CheckInvalidPathChars(path3);
+ PathInternal.CheckInvalidPathChars(path4);
+
+ return CombineNoChecks(path1, path2, path3, path4);
+ }
+
+ public static string Combine(params string[] paths)
+ {
+ if (paths == null)
+ {
+ throw new ArgumentNullException(nameof(paths));
+ }
+ Contract.EndContractBlock();
+
+ int finalSize = 0;
+ int firstComponent = 0;
+
+ // We have two passes, the first calculates how large a buffer to allocate and does some precondition
+ // checks on the paths passed in. The second actually does the combination.
+
+ for (int i = 0; i < paths.Length; i++)
+ {
+ if (paths[i] == null)
+ {
+ throw new ArgumentNullException(nameof(paths));
+ }
+
+ if (paths[i].Length == 0)
+ {
+ continue;
+ }
+
+ PathInternal.CheckInvalidPathChars(paths[i]);
+
+ if (IsPathRooted(paths[i]))
+ {
+ firstComponent = i;
+ finalSize = paths[i].Length;
+ }
+ else
+ {
+ finalSize += paths[i].Length;
+ }
+
+ char ch = paths[i][paths[i].Length - 1];
+ if (!PathInternal.IsDirectoryOrVolumeSeparator(ch))
+ finalSize++;
+ }
+
+ StringBuilder finalPath = StringBuilderCache.Acquire(finalSize);
+
+ for (int i = firstComponent; i < paths.Length; i++)
+ {
+ if (paths[i].Length == 0)
+ {
+ continue;
+ }
+
+ if (finalPath.Length == 0)
+ {
+ finalPath.Append(paths[i]);
+ }
+ else
+ {
+ char ch = finalPath[finalPath.Length - 1];
+ if (!PathInternal.IsDirectoryOrVolumeSeparator(ch))
+ {
+ finalPath.Append(PathInternal.DirectorySeparatorChar);
+ }
+
+ finalPath.Append(paths[i]);
+ }
+ }
+
+ return StringBuilderCache.GetStringAndRelease(finalPath);
+ }
+
+ private static string CombineNoChecks(string path1, string path2)
+ {
+ if (path2.Length == 0)
+ return path1;
+
+ if (path1.Length == 0)
+ return path2;
+
+ if (IsPathRooted(path2))
+ return path2;
+
+ char ch = path1[path1.Length - 1];
+ return PathInternal.IsDirectoryOrVolumeSeparator(ch) ?
+ path1 + path2 :
+ path1 + PathInternal.DirectorySeparatorCharAsString + path2;
+ }
+
+ private static string CombineNoChecks(string path1, string path2, string path3)
+ {
+ if (path1.Length == 0)
+ return CombineNoChecks(path2, path3);
+ if (path2.Length == 0)
+ return CombineNoChecks(path1, path3);
+ if (path3.Length == 0)
+ return CombineNoChecks(path1, path2);
+
+ if (IsPathRooted(path3))
+ return path3;
+ if (IsPathRooted(path2))
+ return CombineNoChecks(path2, path3);
+
+ bool hasSep1 = PathInternal.IsDirectoryOrVolumeSeparator(path1[path1.Length - 1]);
+ bool hasSep2 = PathInternal.IsDirectoryOrVolumeSeparator(path2[path2.Length - 1]);
+
+ if (hasSep1 && hasSep2)
+ {
+ return path1 + path2 + path3;
+ }
+ else if (hasSep1)
+ {
+ return path1 + path2 + PathInternal.DirectorySeparatorCharAsString + path3;
+ }
+ else if (hasSep2)
+ {
+ return path1 + PathInternal.DirectorySeparatorCharAsString + path2 + path3;
+ }
+ else
+ {
+ // string.Concat only has string-based overloads up to four arguments; after that requires allocating
+ // a params string[]. Instead, try to use a cached StringBuilder.
+ StringBuilder sb = StringBuilderCache.Acquire(path1.Length + path2.Length + path3.Length + 2);
+ sb.Append(path1)
+ .Append(PathInternal.DirectorySeparatorChar)
+ .Append(path2)
+ .Append(PathInternal.DirectorySeparatorChar)
+ .Append(path3);
+ return StringBuilderCache.GetStringAndRelease(sb);
+ }
+ }
+
+ private static string CombineNoChecks(string path1, string path2, string path3, string path4)
+ {
+ if (path1.Length == 0)
+ return CombineNoChecks(path2, path3, path4);
+ if (path2.Length == 0)
+ return CombineNoChecks(path1, path3, path4);
+ if (path3.Length == 0)
+ return CombineNoChecks(path1, path2, path4);
+ if (path4.Length == 0)
+ return CombineNoChecks(path1, path2, path3);
+
+ if (IsPathRooted(path4))
+ return path4;
+ if (IsPathRooted(path3))
+ return CombineNoChecks(path3, path4);
+ if (IsPathRooted(path2))
+ return CombineNoChecks(path2, path3, path4);
+
+ bool hasSep1 = PathInternal.IsDirectoryOrVolumeSeparator(path1[path1.Length - 1]);
+ bool hasSep2 = PathInternal.IsDirectoryOrVolumeSeparator(path2[path2.Length - 1]);
+ bool hasSep3 = PathInternal.IsDirectoryOrVolumeSeparator(path3[path3.Length - 1]);
+
+ if (hasSep1 && hasSep2 && hasSep3)
+ {
+ // Use string.Concat overload that takes four strings
+ return path1 + path2 + path3 + path4;
+ }
+ else
+ {
+ // string.Concat only has string-based overloads up to four arguments; after that requires allocating
+ // a params string[]. Instead, try to use a cached StringBuilder.
+ StringBuilder sb = StringBuilderCache.Acquire(path1.Length + path2.Length + path3.Length + path4.Length + 3);
+
+ sb.Append(path1);
+ if (!hasSep1)
+ {
+ sb.Append(PathInternal.DirectorySeparatorChar);
+ }
+
+ sb.Append(path2);
+ if (!hasSep2)
+ {
+ sb.Append(PathInternal.DirectorySeparatorChar);
+ }
+
+ sb.Append(path3);
+ if (!hasSep3)
+ {
+ sb.Append(PathInternal.DirectorySeparatorChar);
+ }
+
+ sb.Append(path4);
+
+ return StringBuilderCache.GetStringAndRelease(sb);
+ }
+ }
+
+ private static readonly char[] s_base32Char = {
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+ 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+ 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'y', 'z', '0', '1', '2', '3', '4', '5'};
+
+ private static unsafe void Populate83FileNameFromRandomBytes(byte* bytes, int byteCount, char* chars, int charCount)
+ {
+ Debug.Assert(bytes != null);
+ Debug.Assert(chars != null);
+
+ // This method requires bytes of length 8 and chars of length 12.
+ Debug.Assert(byteCount == 8, $"Unexpected {nameof(byteCount)}");
+ Debug.Assert(charCount == 12, $"Unexpected {nameof(charCount)}");
+
+ byte b0 = bytes[0];
+ byte b1 = bytes[1];
+ byte b2 = bytes[2];
+ byte b3 = bytes[3];
+ byte b4 = bytes[4];
+
+ // Consume the 5 Least significant bits of the first 5 bytes
+ chars[0] = s_base32Char[b0 & 0x1F];
+ chars[1] = s_base32Char[b1 & 0x1F];
+ chars[2] = s_base32Char[b2 & 0x1F];
+ chars[3] = s_base32Char[b3 & 0x1F];
+ chars[4] = s_base32Char[b4 & 0x1F];
+
+ // Consume 3 MSB of b0, b1, MSB bits 6, 7 of b3, b4
+ chars[5] = s_base32Char[(
+ ((b0 & 0xE0) >> 5) |
+ ((b3 & 0x60) >> 2))];
+
+ chars[6] = s_base32Char[(
+ ((b1 & 0xE0) >> 5) |
+ ((b4 & 0x60) >> 2))];
+
+ // Consume 3 MSB bits of b2, 1 MSB bit of b3, b4
+ b2 >>= 5;
+
+ Debug.Assert(((b2 & 0xF8) == 0), "Unexpected set bits");
+
+ if ((b3 & 0x80) != 0)
+ b2 |= 0x08;
+ if ((b4 & 0x80) != 0)
+ b2 |= 0x10;
+
+ chars[7] = s_base32Char[b2];
+
+ // Set the file extension separator
+ chars[8] = '.';
+
+ // Consume the 5 Least significant bits of the remaining 3 bytes
+ chars[9] = s_base32Char[(bytes[5] & 0x1F)];
+ chars[10] = s_base32Char[(bytes[6] & 0x1F)];
+ chars[11] = s_base32Char[(bytes[7] & 0x1F)];
+ }
+
+ /// <summary>
+ /// Create a relative path from one path to another. Paths will be resolved before calculating the difference.
+ /// Default path comparison for the active platform will be used (OrdinalIgnoreCase for Windows or Mac, Ordinal for Unix).
+ /// </summary>
+ /// <param name="relativeTo">The source path the output should be relative to. This path is always considered to be a directory.</param>
+ /// <param name="path">The destination path.</param>
+ /// <returns>The relative path or <paramref name="path"/> if the paths don't share the same root.</returns>
+ /// <exception cref="ArgumentNullException">Thrown if <paramref name="relativeTo"/> or <paramref name="path"/> is <c>null</c> or an empty string.</exception>
+ public static string GetRelativePath(string relativeTo, string path)
+ {
+ return GetRelativePath(relativeTo, path, StringComparison);
+ }
+
+ private static string GetRelativePath(string relativeTo, string path, StringComparison comparisonType)
+ {
+ if (string.IsNullOrEmpty(relativeTo)) throw new ArgumentNullException(nameof(relativeTo));
+ if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullException(nameof(path));
+ Debug.Assert(comparisonType == StringComparison.Ordinal || comparisonType == StringComparison.OrdinalIgnoreCase);
+
+ relativeTo = GetFullPath(relativeTo);
+ path = GetFullPath(path);
+
+ // Need to check if the roots are different- if they are we need to return the "to" path.
+ if (!PathInternal.AreRootsEqual(relativeTo, path, comparisonType))
+ return path;
+
+ int commonLength = PathInternal.GetCommonPathLength(relativeTo, path, ignoreCase: comparisonType == StringComparison.OrdinalIgnoreCase);
+
+ // If there is nothing in common they can't share the same root, return the "to" path as is.
+ if (commonLength == 0)
+ return path;
+
+ // Trailing separators aren't significant for comparison
+ int relativeToLength = relativeTo.Length;
+ if (PathInternal.EndsInDirectorySeparator(relativeTo))
+ relativeToLength--;
+
+ bool pathEndsInSeparator = PathInternal.EndsInDirectorySeparator(path);
+ int pathLength = path.Length;
+ if (pathEndsInSeparator)
+ pathLength--;
+
+ // If we have effectively the same path, return "."
+ if (relativeToLength == pathLength && commonLength >= relativeToLength) return ".";
+
+ // We have the same root, we need to calculate the difference now using the
+ // common Length and Segment count past the length.
+ //
+ // Some examples:
+ //
+ // C:\Foo C:\Bar L3, S1 -> ..\Bar
+ // C:\Foo C:\Foo\Bar L6, S0 -> Bar
+ // C:\Foo\Bar C:\Bar\Bar L3, S2 -> ..\..\Bar\Bar
+ // C:\Foo\Foo C:\Foo\Bar L7, S1 -> ..\Bar
+
+ StringBuilder sb = StringBuilderCache.Acquire(Math.Max(relativeTo.Length, path.Length));
+
+ // Add parent segments for segments past the common on the "from" path
+ if (commonLength < relativeToLength)
+ {
+ sb.Append(PathInternal.ParentDirectoryPrefix);
+
+ for (int i = commonLength; i < relativeToLength; i++)
+ {
+ if (PathInternal.IsDirectorySeparator(relativeTo[i]))
+ {
+ sb.Append(PathInternal.ParentDirectoryPrefix);
+ }
+ }
+ }
+ else if (PathInternal.IsDirectorySeparator(path[commonLength]))
+ {
+ // No parent segments and we need to eat the initial separator
+ // (C:\Foo C:\Foo\Bar case)
+ commonLength++;
+ }
+
+ // Now add the rest of the "to" path, adding back the trailing separator
+ int count = pathLength - commonLength;
+ if (pathEndsInSeparator)
+ count++;
+
+ sb.Append(path, commonLength, count);
+ return StringBuilderCache.GetStringAndRelease(sb);
+ }
+
+ // StringComparison and IsCaseSensitive are also available in PathInternal.CaseSensitivity but we are
+ // too low in System.Runtime.Extensions to use it (no FileStream, etc.)
+
+ /// <summary>Returns a comparison that can be used to compare file and directory names for equality.</summary>
+ internal static StringComparison StringComparison
+ {
+ get
+ {
+ return IsCaseSensitive ?
+ StringComparison.Ordinal :
+ StringComparison.OrdinalIgnoreCase;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/IO/PathHelper.Windows.cs b/src/mscorlib/shared/System/IO/PathHelper.Windows.cs
index e2ead93185..e2ead93185 100644
--- a/src/mscorlib/corefx/System/IO/PathHelper.Windows.cs
+++ b/src/mscorlib/shared/System/IO/PathHelper.Windows.cs
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.Unix.cs b/src/mscorlib/shared/System/IO/PathInternal.Unix.cs
index 08dc1d0251..08dc1d0251 100644
--- a/src/mscorlib/corefx/System/IO/PathInternal.Unix.cs
+++ b/src/mscorlib/shared/System/IO/PathInternal.Unix.cs
diff --git a/src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs b/src/mscorlib/shared/System/IO/PathInternal.Windows.StringBuffer.cs
index 84953df37b..84953df37b 100644
--- a/src/mscorlib/corefx/System/IO/PathInternal.Windows.StringBuffer.cs
+++ b/src/mscorlib/shared/System/IO/PathInternal.Windows.StringBuffer.cs
diff --git a/src/mscorlib/shared/System/IO/PathInternal.Windows.cs b/src/mscorlib/shared/System/IO/PathInternal.Windows.cs
new file mode 100644
index 0000000000..ee0dd54383
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/PathInternal.Windows.cs
@@ -0,0 +1,442 @@
+// 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.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Text;
+
+namespace System.IO
+{
+ /// <summary>Contains internal path helpers that are shared between many projects.</summary>
+ internal static partial class PathInternal
+ {
+ // All paths in Win32 ultimately end up becoming a path to a File object in the Windows object manager. Passed in paths get mapped through
+ // DosDevice symbolic links in the object tree to actual File objects under \Devices. To illustrate, this is what happens with a typical
+ // path "Foo" passed as a filename to any Win32 API:
+ //
+ // 1. "Foo" is recognized as a relative path and is appended to the current directory (say, "C:\" in our example)
+ // 2. "C:\Foo" is prepended with the DosDevice namespace "\??\"
+ // 3. CreateFile tries to create an object handle to the requested file "\??\C:\Foo"
+ // 4. The Object Manager recognizes the DosDevices prefix and looks
+ // a. First in the current session DosDevices ("\Sessions\1\DosDevices\" for example, mapped network drives go here)
+ // b. If not found in the session, it looks in the Global DosDevices ("\GLOBAL??\")
+ // 5. "C:" is found in DosDevices (in our case "\GLOBAL??\C:", which is a symbolic link to "\Device\HarddiskVolume6")
+ // 6. The full path is now "\Device\HarddiskVolume6\Foo", "\Device\HarddiskVolume6" is a File object and parsing is handed off
+ // to the registered parsing method for Files
+ // 7. The registered open method for File objects is invoked to create the file handle which is then returned
+ //
+ // There are multiple ways to directly specify a DosDevices path. The final format of "\??\" is one way. It can also be specified
+ // as "\\.\" (the most commonly documented way) and "\\?\". If the question mark syntax is used the path will skip normalization
+ // (essentially GetFullPathName()) and path length checks.
+
+ // Windows Kernel-Mode Object Manager
+ // https://msdn.microsoft.com/en-us/library/windows/hardware/ff565763.aspx
+ // https://channel9.msdn.com/Shows/Going+Deep/Windows-NT-Object-Manager
+ //
+ // Introduction to MS-DOS Device Names
+ // https://msdn.microsoft.com/en-us/library/windows/hardware/ff548088.aspx
+ //
+ // Local and Global MS-DOS Device Names
+ // https://msdn.microsoft.com/en-us/library/windows/hardware/ff554302.aspx
+
+ internal const char DirectorySeparatorChar = '\\';
+ internal const char AltDirectorySeparatorChar = '/';
+ internal const char VolumeSeparatorChar = ':';
+ internal const char PathSeparator = ';';
+
+ internal const string DirectorySeparatorCharAsString = "\\";
+
+ internal const string ExtendedPathPrefix = @"\\?\";
+ internal const string UncPathPrefix = @"\\";
+ internal const string UncExtendedPrefixToInsert = @"?\UNC\";
+ internal const string UncExtendedPathPrefix = @"\\?\UNC\";
+ internal const string DevicePathPrefix = @"\\.\";
+ internal const string ParentDirectoryPrefix = @"..\";
+
+ internal const int MaxShortPath = 260;
+ internal const int MaxShortDirectoryPath = 248;
+ internal const int MaxLongPath = short.MaxValue;
+ // \\?\, \\.\, \??\
+ internal const int DevicePrefixLength = 4;
+ // \\
+ internal const int UncPrefixLength = 2;
+ // \\?\UNC\, \\.\UNC\
+ internal const int UncExtendedPrefixLength = 8;
+ internal const int MaxComponentLength = 255;
+
+ /// <summary>
+ /// Returns true if the given character is a valid drive letter
+ /// </summary>
+ internal static bool IsValidDriveChar(char value)
+ {
+ return ((value >= 'A' && value <= 'Z') || (value >= 'a' && value <= 'z'));
+ }
+
+ /// <summary>
+ /// Adds the extended path prefix (\\?\) if not already a device path, IF the path is not relative,
+ /// AND the path is more than 259 characters. (> MAX_PATH + null)
+ /// </summary>
+ internal static string EnsureExtendedPrefixOverMaxPath(string path)
+ {
+ if (path != null && path.Length >= MaxShortPath)
+ {
+ return EnsureExtendedPrefix(path);
+ }
+ else
+ {
+ return path;
+ }
+ }
+
+ /// <summary>
+ /// Adds the extended path prefix (\\?\) if not relative or already a device path.
+ /// </summary>
+ internal static string EnsureExtendedPrefix(string path)
+ {
+ // Putting the extended prefix on the path changes the processing of the path. It won't get normalized, which
+ // means adding to relative paths will prevent them from getting the appropriate current directory inserted.
+
+ // If it already has some variant of a device path (\??\, \\?\, \\.\, //./, etc.) we don't need to change it
+ // as it is either correct or we will be changing the behavior. When/if Windows supports long paths implicitly
+ // in the future we wouldn't want normalization to come back and break existing code.
+
+ // In any case, all internal usages should be hitting normalize path (Path.GetFullPath) before they hit this
+ // shimming method. (Or making a change that doesn't impact normalization, such as adding a filename to a
+ // normalized base path.)
+ if (IsPartiallyQualified(path) || IsDevice(path))
+ return path;
+
+ // Given \\server\share in longpath becomes \\?\UNC\server\share
+ if (path.StartsWith(UncPathPrefix, StringComparison.OrdinalIgnoreCase))
+ return path.Insert(2, UncExtendedPrefixToInsert);
+
+ return ExtendedPathPrefix + path;
+ }
+
+ /// <summary>
+ /// Returns true if the path uses any of the DOS device path syntaxes. ("\\.\", "\\?\", or "\??\")
+ /// </summary>
+ internal static bool IsDevice(string path)
+ {
+ // If the path begins with any two separators is will be recognized and normalized and prepped with
+ // "\??\" for internal usage correctly. "\??\" is recognized and handled, "/??/" is not.
+ return IsExtended(path)
+ ||
+ (
+ path.Length >= DevicePrefixLength
+ && IsDirectorySeparator(path[0])
+ && IsDirectorySeparator(path[1])
+ && (path[2] == '.' || path[2] == '?')
+ && IsDirectorySeparator(path[3])
+ );
+ }
+
+ /// <summary>
+ /// Returns true if the path uses the canonical form of extended syntax ("\\?\" or "\??\"). If the
+ /// path matches exactly (cannot use alternate directory separators) Windows will skip normalization
+ /// and path length checks.
+ /// </summary>
+ internal static bool IsExtended(string path)
+ {
+ // While paths like "//?/C:/" will work, they're treated the same as "\\.\" paths.
+ // Skipping of normalization will *only* occur if back slashes ('\') are used.
+ return path.Length >= DevicePrefixLength
+ && path[0] == '\\'
+ && (path[1] == '\\' || path[1] == '?')
+ && path[2] == '?'
+ && path[3] == '\\';
+ }
+
+ /// <summary>
+ /// Returns a value indicating if the given path contains invalid characters (", &lt;, &gt;, |
+ /// NUL, or any ASCII char whose integer representation is in the range of 1 through 31).
+ /// Does not check for wild card characters ? and *.
+ /// </summary>
+ internal static bool HasIllegalCharacters(string path)
+ {
+ // This is equivalent to IndexOfAny(InvalidPathChars) >= 0,
+ // except faster since IndexOfAny grows slower as the input
+ // array grows larger.
+ // Since we know that some of the characters we're looking
+ // for are contiguous in the alphabet-- the path cannot contain
+ // characters 0-31-- we can optimize this for our specific use
+ // case and use simple comparison operations.
+
+ for (int i = 0; i < path.Length; i++)
+ {
+ char c = path[i];
+ if (c <= '|') // fast path for common case - '|' is highest illegal character
+ {
+ if (c <= '\u001f' || c == '|')
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Check for known wildcard characters. '*' and '?' are the most common ones.
+ /// </summary>
+ internal static bool HasWildCardCharacters(string path)
+ {
+ // Question mark is part of dos device syntax so we have to skip if we are
+ int startIndex = IsDevice(path) ? ExtendedPathPrefix.Length : 0;
+
+ // [MS - FSA] 2.1.4.4 Algorithm for Determining if a FileName Is in an Expression
+ // https://msdn.microsoft.com/en-us/library/ff469270.aspx
+ for (int i = startIndex; i < path.Length; i++)
+ {
+ char c = path[i];
+ if (c <= '?') // fast path for common case - '?' is highest wildcard character
+ {
+ if (c == '\"' || c == '<' || c == '>' || c == '*' || c == '?')
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /// <summary>
+ /// Gets the length of the root of the path (drive, share, etc.).
+ /// </summary>
+ internal unsafe static int GetRootLength(string path)
+ {
+ fixed (char* value = path)
+ {
+ return GetRootLength(value, path.Length);
+ }
+ }
+
+ private unsafe static int GetRootLength(char* path, int pathLength)
+ {
+ int i = 0;
+ int volumeSeparatorLength = 2; // Length to the colon "C:"
+ int uncRootLength = 2; // Length to the start of the server name "\\"
+
+ bool extendedSyntax = StartsWithOrdinal(path, pathLength, ExtendedPathPrefix);
+ bool extendedUncSyntax = StartsWithOrdinal(path, pathLength, UncExtendedPathPrefix);
+ if (extendedSyntax)
+ {
+ // Shift the position we look for the root from to account for the extended prefix
+ if (extendedUncSyntax)
+ {
+ // "\\" -> "\\?\UNC\"
+ uncRootLength = UncExtendedPathPrefix.Length;
+ }
+ else
+ {
+ // "C:" -> "\\?\C:"
+ volumeSeparatorLength += ExtendedPathPrefix.Length;
+ }
+ }
+
+ if ((!extendedSyntax || extendedUncSyntax) && pathLength > 0 && IsDirectorySeparator(path[0]))
+ {
+ // UNC or simple rooted path (e.g. "\foo", NOT "\\?\C:\foo")
+
+ i = 1; // Drive rooted (\foo) is one character
+ if (extendedUncSyntax || (pathLength > 1 && IsDirectorySeparator(path[1])))
+ {
+ // UNC (\\?\UNC\ or \\), scan past the next two directory separators at most
+ // (e.g. to \\?\UNC\Server\Share or \\Server\Share\)
+ i = uncRootLength;
+ int n = 2; // Maximum separators to skip
+ while (i < pathLength && (!IsDirectorySeparator(path[i]) || --n > 0)) i++;
+ }
+ }
+ else if (pathLength >= volumeSeparatorLength && path[volumeSeparatorLength - 1] == VolumeSeparatorChar)
+ {
+ // Path is at least longer than where we expect a colon, and has a colon (\\?\A:, A:)
+ // If the colon is followed by a directory separator, move past it
+ i = volumeSeparatorLength;
+ if (pathLength >= volumeSeparatorLength + 1 && IsDirectorySeparator(path[volumeSeparatorLength])) i++;
+ }
+ return i;
+ }
+
+ private unsafe static bool StartsWithOrdinal(char* source, int sourceLength, string value)
+ {
+ if (sourceLength < value.Length) return false;
+ for (int i = 0; i < value.Length; i++)
+ {
+ if (value[i] != source[i]) return false;
+ }
+ return true;
+ }
+
+ /// <summary>
+ /// Returns true if the path specified is relative to the current drive or working directory.
+ /// Returns false if the path is fixed to a specific drive or UNC path. This method does no
+ /// validation of the path (URIs will be returned as relative as a result).
+ /// </summary>
+ /// <remarks>
+ /// Handles paths that use the alternate directory separator. It is a frequent mistake to
+ /// assume that rooted paths (Path.IsPathRooted) are not relative. This isn't the case.
+ /// "C:a" is drive relative- meaning that it will be resolved against the current directory
+ /// for C: (rooted, but relative). "C:\a" is rooted and not relative (the current directory
+ /// will not be used to modify the path).
+ /// </remarks>
+ internal static bool IsPartiallyQualified(string path)
+ {
+ if (path.Length < 2)
+ {
+ // It isn't fixed, it must be relative. There is no way to specify a fixed
+ // path with one character (or less).
+ return true;
+ }
+
+ if (IsDirectorySeparator(path[0]))
+ {
+ // There is no valid way to specify a relative path with two initial slashes or
+ // \? as ? isn't valid for drive relative paths and \??\ is equivalent to \\?\
+ return !(path[1] == '?' || IsDirectorySeparator(path[1]));
+ }
+
+ // The only way to specify a fixed path that doesn't begin with two slashes
+ // is the drive, colon, slash format- i.e. C:\
+ return !((path.Length >= 3)
+ && (path[1] == VolumeSeparatorChar)
+ && IsDirectorySeparator(path[2])
+ // To match old behavior we'll check the drive character for validity as the path is technically
+ // not qualified if you don't have a valid drive. "=:\" is the "=" file's default data stream.
+ && IsValidDriveChar(path[0]));
+ }
+
+ /// <summary>
+ /// Returns the characters to skip at the start of the path if it starts with space(s) and a drive or directory separator.
+ /// (examples are " C:", " \")
+ /// This is a legacy behavior of Path.GetFullPath().
+ /// </summary>
+ /// <remarks>
+ /// Note that this conflicts with IsPathRooted() which doesn't (and never did) such a skip.
+ /// </remarks>
+ internal static int PathStartSkip(string path)
+ {
+ int startIndex = 0;
+ while (startIndex < path.Length && path[startIndex] == ' ') startIndex++;
+
+ if (startIndex > 0 && (startIndex < path.Length && IsDirectorySeparator(path[startIndex]))
+ || (startIndex + 1 < path.Length && path[startIndex + 1] == ':' && IsValidDriveChar(path[startIndex])))
+ {
+ // Go ahead and skip spaces as we're either " C:" or " \"
+ return startIndex;
+ }
+
+ return 0;
+ }
+
+ /// <summary>
+ /// True if the given character is a directory separator.
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static bool IsDirectorySeparator(char c)
+ {
+ return c == DirectorySeparatorChar || c == AltDirectorySeparatorChar;
+ }
+
+ /// <summary>
+ /// Normalize separators in the given path. Converts forward slashes into back slashes and compresses slash runs, keeping initial 2 if present.
+ /// Also trims initial whitespace in front of "rooted" paths (see PathStartSkip).
+ ///
+ /// This effectively replicates the behavior of the legacy NormalizePath when it was called with fullCheck=false and expandShortpaths=false.
+ /// The current NormalizePath gets directory separator normalization from Win32's GetFullPathName(), which will resolve relative paths and as
+ /// such can't be used here (and is overkill for our uses).
+ ///
+ /// Like the current NormalizePath this will not try and analyze periods/spaces within directory segments.
+ /// </summary>
+ /// <remarks>
+ /// The only callers that used to use Path.Normalize(fullCheck=false) were Path.GetDirectoryName() and Path.GetPathRoot(). Both usages do
+ /// not need trimming of trailing whitespace here.
+ ///
+ /// GetPathRoot() could technically skip normalizing separators after the second segment- consider as a future optimization.
+ ///
+ /// For legacy desktop behavior with ExpandShortPaths:
+ /// - It has no impact on GetPathRoot() so doesn't need consideration.
+ /// - It could impact GetDirectoryName(), but only if the path isn't relative (C:\ or \\Server\Share).
+ ///
+ /// In the case of GetDirectoryName() the ExpandShortPaths behavior was undocumented and provided inconsistent results if the path was
+ /// fixed/relative. For example: "C:\PROGRA~1\A.TXT" would return "C:\Program Files" while ".\PROGRA~1\A.TXT" would return ".\PROGRA~1". If you
+ /// ultimately call GetFullPath() this doesn't matter, but if you don't or have any intermediate string handling could easily be tripped up by
+ /// this undocumented behavior.
+ ///
+ /// We won't match this old behavior because:
+ ///
+ /// 1. It was undocumented
+ /// 2. It was costly (extremely so if it actually contained '~')
+ /// 3. Doesn't play nice with string logic
+ /// 4. Isn't a cross-plat friendly concept/behavior
+ /// </remarks>
+ internal static string NormalizeDirectorySeparators(string path)
+ {
+ if (string.IsNullOrEmpty(path)) return path;
+
+ char current;
+ int start = PathStartSkip(path);
+
+ if (start == 0)
+ {
+ // Make a pass to see if we need to normalize so we can potentially skip allocating
+ bool normalized = true;
+
+ for (int i = 0; i < path.Length; i++)
+ {
+ current = path[i];
+ if (IsDirectorySeparator(current)
+ && (current != DirectorySeparatorChar
+ // Check for sequential separators past the first position (we need to keep initial two for UNC/extended)
+ || (i > 0 && i + 1 < path.Length && IsDirectorySeparator(path[i + 1]))))
+ {
+ normalized = false;
+ break;
+ }
+ }
+
+ if (normalized) return path;
+ }
+
+ StringBuilder builder = new StringBuilder(path.Length);
+
+ if (IsDirectorySeparator(path[start]))
+ {
+ start++;
+ builder.Append(DirectorySeparatorChar);
+ }
+
+ for (int i = start; i < path.Length; i++)
+ {
+ current = path[i];
+
+ // If we have a separator
+ if (IsDirectorySeparator(current))
+ {
+ // If the next is a separator, skip adding this
+ if (i + 1 < path.Length && IsDirectorySeparator(path[i + 1]))
+ {
+ continue;
+ }
+
+ // Ensure it is the primary separator
+ current = DirectorySeparatorChar;
+ }
+
+ builder.Append(current);
+ }
+
+ return builder.ToString();
+ }
+
+ /// <summary>
+ /// Returns true if the character is a directory or volume separator.
+ /// </summary>
+ /// <param name="ch">The character to test.</param>
+ internal static bool IsDirectoryOrVolumeSeparator(char ch)
+ {
+ return IsDirectorySeparator(ch) || VolumeSeparatorChar == ch;
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/PathInternal.cs b/src/mscorlib/shared/System/IO/PathInternal.cs
new file mode 100644
index 0000000000..0dab5b968a
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/PathInternal.cs
@@ -0,0 +1,171 @@
+// 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.Diagnostics;
+using System.Text;
+
+namespace System.IO
+{
+ /// <summary>Contains internal path helpers that are shared between many projects.</summary>
+ internal static partial class PathInternal
+ {
+ // Trim trailing white spaces, tabs etc but don't be aggressive in removing everything that has UnicodeCategory of trailing space.
+ // string.WhitespaceChars will trim more aggressively than what the underlying FS does (for ex, NTFS, FAT).
+ //
+ // (This is for compatibility with old behavior.)
+ internal static readonly char[] s_trimEndChars =
+ {
+ (char)0x9, // Horizontal tab
+ (char)0xA, // Line feed
+ (char)0xB, // Vertical tab
+ (char)0xC, // Form feed
+ (char)0xD, // Carriage return
+ (char)0x20, // Space
+ (char)0x85, // Next line
+ (char)0xA0 // Non breaking space
+ };
+
+ /// <summary>
+ /// Checks for invalid path characters in the given path.
+ /// </summary>
+ /// <exception cref="System.ArgumentNullException">Thrown if the path is null.</exception>
+ /// <exception cref="System.ArgumentException">Thrown if the path has invalid characters.</exception>
+ /// <param name="path">The path to check for invalid characters.</param>
+ internal static void CheckInvalidPathChars(string path)
+ {
+ if (path == null)
+ throw new ArgumentNullException(nameof(path));
+
+ if (HasIllegalCharacters(path))
+ throw new ArgumentException(SR.Argument_InvalidPathChars, nameof(path));
+ }
+
+ /// <summary>
+ /// Returns the start index of the filename
+ /// in the given path, or 0 if no directory
+ /// or volume separator is found.
+ /// </summary>
+ /// <param name="path">The path in which to find the index of the filename.</param>
+ /// <remarks>
+ /// This method returns path.Length for
+ /// inputs like "/usr/foo/" on Unix. As such,
+ /// it is not safe for being used to index
+ /// the string without additional verification.
+ /// </remarks>
+ internal static int FindFileNameIndex(string path)
+ {
+ Debug.Assert(path != null);
+ CheckInvalidPathChars(path);
+
+ for (int i = path.Length - 1; i >= 0; i--)
+ {
+ char ch = path[i];
+ if (IsDirectoryOrVolumeSeparator(ch))
+ return i + 1;
+ }
+
+ return 0; // the whole path is the filename
+ }
+
+ /// <summary>
+ /// Returns true if the path ends in a directory separator.
+ /// </summary>
+ internal static bool EndsInDirectorySeparator(string path) =>
+ !string.IsNullOrEmpty(path) && IsDirectorySeparator(path[path.Length - 1]);
+
+ /// <summary>
+ /// Get the common path length from the start of the string.
+ /// </summary>
+ internal static int GetCommonPathLength(string first, string second, bool ignoreCase)
+ {
+ int commonChars = EqualStartingCharacterCount(first, second, ignoreCase: ignoreCase);
+
+ // If nothing matches
+ if (commonChars == 0)
+ return commonChars;
+
+ // Or we're a full string and equal length or match to a separator
+ if (commonChars == first.Length
+ && (commonChars == second.Length || IsDirectorySeparator(second[commonChars])))
+ return commonChars;
+
+ if (commonChars == second.Length && IsDirectorySeparator(first[commonChars]))
+ return commonChars;
+
+ // It's possible we matched somewhere in the middle of a segment e.g. C:\Foodie and C:\Foobar.
+ while (commonChars > 0 && !IsDirectorySeparator(first[commonChars - 1]))
+ commonChars--;
+
+ return commonChars;
+ }
+
+ /// <summary>
+ /// Gets the count of common characters from the left optionally ignoring case
+ /// </summary>
+ unsafe internal static int EqualStartingCharacterCount(string first, string second, bool ignoreCase)
+ {
+ if (string.IsNullOrEmpty(first) || string.IsNullOrEmpty(second)) return 0;
+
+ int commonChars = 0;
+
+ fixed (char* f = first)
+ fixed (char* s = second)
+ {
+ char* l = f;
+ char* r = s;
+ char* leftEnd = l + first.Length;
+ char* rightEnd = r + second.Length;
+
+ while (l != leftEnd && r != rightEnd
+ && (*l == *r || (ignoreCase && char.ToUpperInvariant((*l)) == char.ToUpperInvariant((*r)))))
+ {
+ commonChars++;
+ l++;
+ r++;
+ }
+ }
+
+ return commonChars;
+ }
+
+ /// <summary>
+ /// Returns true if the two paths have the same root
+ /// </summary>
+ internal static bool AreRootsEqual(string first, string second, StringComparison comparisonType)
+ {
+ int firstRootLength = GetRootLength(first);
+ int secondRootLength = GetRootLength(second);
+
+ return firstRootLength == secondRootLength
+ && string.Compare(
+ strA: first,
+ indexA: 0,
+ strB: second,
+ indexB: 0,
+ length: firstRootLength,
+ comparisonType: comparisonType) == 0;
+ }
+
+ /// <summary>
+ /// Returns false for ".." unless it is specified as a part of a valid File/Directory name.
+ /// (Used to avoid moving up directories.)
+ ///
+ /// Valid: a..b abc..d
+ /// Invalid: ..ab ab.. .. abc..d\abc..
+ /// </summary>
+ internal static void CheckSearchPattern(string searchPattern)
+ {
+ int index;
+ while ((index = searchPattern.IndexOf("..", StringComparison.Ordinal)) != -1)
+ {
+ // Terminal ".." . Files names cannot end in ".."
+ if (index + 2 == searchPattern.Length
+ || IsDirectorySeparator(searchPattern[index + 2]))
+ throw new ArgumentException(SR.Arg_InvalidSearchPattern);
+
+ searchPattern = searchPattern.Substring(index + 2);
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/PathTooLongException.cs b/src/mscorlib/shared/System/IO/PathTooLongException.cs
new file mode 100644
index 0000000000..613af051ca
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/PathTooLongException.cs
@@ -0,0 +1,37 @@
+// 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.Serialization;
+
+namespace System.IO
+{
+ [Serializable]
+ public class PathTooLongException : IOException
+ {
+ public PathTooLongException()
+ : base(SR.IO_PathTooLong)
+ {
+ HResult = __HResults.COR_E_PATHTOOLONG;
+ }
+
+ public PathTooLongException(string message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_PATHTOOLONG;
+ }
+
+ public PathTooLongException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_PATHTOOLONG;
+ }
+
+ protected PathTooLongException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/SeekOrigin.cs b/src/mscorlib/shared/System/IO/SeekOrigin.cs
new file mode 100644
index 0000000000..3798a0ce70
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/SeekOrigin.cs
@@ -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.
+
+namespace System.IO
+{
+ // Provides seek reference points. To seek to the end of a stream,
+ // call stream.Seek(0, SeekOrigin.End).
+ public enum SeekOrigin
+ {
+ // These constants match Win32's FILE_BEGIN, FILE_CURRENT, and FILE_END
+ Begin = 0,
+ Current = 1,
+ End = 2,
+ }
+}
diff --git a/src/mscorlib/shared/System/IO/StreamHelpers.CopyValidation.cs b/src/mscorlib/shared/System/IO/StreamHelpers.CopyValidation.cs
new file mode 100644
index 0000000000..45bbd816df
--- /dev/null
+++ b/src/mscorlib/shared/System/IO/StreamHelpers.CopyValidation.cs
@@ -0,0 +1,46 @@
+// 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.
+
+namespace System.IO
+{
+ /// <summary>Provides methods to help in the implementation of Stream-derived types.</summary>
+ internal static partial class StreamHelpers
+ {
+ /// <summary>Validate the arguments to CopyTo, as would Stream.CopyTo.</summary>
+ public static void ValidateCopyToArgs(Stream source, Stream destination, int bufferSize)
+ {
+ if (destination == null)
+ {
+ throw new ArgumentNullException(nameof(destination));
+ }
+
+ if (bufferSize <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(bufferSize), bufferSize, SR.ArgumentOutOfRange_NeedPosNum);
+ }
+
+ bool sourceCanRead = source.CanRead;
+ if (!sourceCanRead && !source.CanWrite)
+ {
+ throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed);
+ }
+
+ bool destinationCanWrite = destination.CanWrite;
+ if (!destinationCanWrite && !destination.CanRead)
+ {
+ throw new ObjectDisposedException(nameof(destination), SR.ObjectDisposed_StreamClosed);
+ }
+
+ if (!sourceCanRead)
+ {
+ throw new NotSupportedException(SR.NotSupported_UnreadableStream);
+ }
+
+ if (!destinationCanWrite)
+ {
+ throw new NotSupportedException(SR.NotSupported_UnwritableStream);
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/IO/Win32Marshal.cs b/src/mscorlib/shared/System/IO/Win32Marshal.cs
index ef76c27010..ef76c27010 100644
--- a/src/mscorlib/corefx/System/IO/Win32Marshal.cs
+++ b/src/mscorlib/shared/System/IO/Win32Marshal.cs
diff --git a/src/mscorlib/src/System/IObservable.cs b/src/mscorlib/shared/System/IObservable.cs
index aabb0b8fb4..aabb0b8fb4 100644
--- a/src/mscorlib/src/System/IObservable.cs
+++ b/src/mscorlib/shared/System/IObservable.cs
diff --git a/src/mscorlib/src/System/IObserver.cs b/src/mscorlib/shared/System/IObserver.cs
index 39e123de8d..39e123de8d 100644
--- a/src/mscorlib/src/System/IObserver.cs
+++ b/src/mscorlib/shared/System/IObserver.cs
diff --git a/src/mscorlib/src/System/IProgress.cs b/src/mscorlib/shared/System/IProgress.cs
index 724c7bdce9..724c7bdce9 100644
--- a/src/mscorlib/src/System/IProgress.cs
+++ b/src/mscorlib/shared/System/IProgress.cs
diff --git a/src/mscorlib/src/System/IndexOutOfRangeException.cs b/src/mscorlib/shared/System/IndexOutOfRangeException.cs
index 4969c2b86d..4969c2b86d 100644
--- a/src/mscorlib/src/System/IndexOutOfRangeException.cs
+++ b/src/mscorlib/shared/System/IndexOutOfRangeException.cs
diff --git a/src/mscorlib/src/System/InsufficientExecutionStackException.cs b/src/mscorlib/shared/System/InsufficientExecutionStackException.cs
index b9a4a12ddd..b9a4a12ddd 100644
--- a/src/mscorlib/src/System/InsufficientExecutionStackException.cs
+++ b/src/mscorlib/shared/System/InsufficientExecutionStackException.cs
diff --git a/src/mscorlib/src/System/InvalidCastException.cs b/src/mscorlib/shared/System/InvalidCastException.cs
index 01d92b2837..01d92b2837 100644
--- a/src/mscorlib/src/System/InvalidCastException.cs
+++ b/src/mscorlib/shared/System/InvalidCastException.cs
diff --git a/src/mscorlib/src/System/InvalidOperationException.cs b/src/mscorlib/shared/System/InvalidOperationException.cs
index 24a08c8089..24a08c8089 100644
--- a/src/mscorlib/src/System/InvalidOperationException.cs
+++ b/src/mscorlib/shared/System/InvalidOperationException.cs
diff --git a/src/mscorlib/src/System/InvalidProgramException.cs b/src/mscorlib/shared/System/InvalidProgramException.cs
index 401b3a0ddb..401b3a0ddb 100644
--- a/src/mscorlib/src/System/InvalidProgramException.cs
+++ b/src/mscorlib/shared/System/InvalidProgramException.cs
diff --git a/src/mscorlib/src/System/InvalidTimeZoneException.cs b/src/mscorlib/shared/System/InvalidTimeZoneException.cs
index 8f0751c426..8f0751c426 100644
--- a/src/mscorlib/src/System/InvalidTimeZoneException.cs
+++ b/src/mscorlib/shared/System/InvalidTimeZoneException.cs
diff --git a/src/mscorlib/shared/System/Lazy.cs b/src/mscorlib/shared/System/Lazy.cs
new file mode 100644
index 0000000000..55f915b65d
--- /dev/null
+++ b/src/mscorlib/shared/System/Lazy.cs
@@ -0,0 +1,561 @@
+// 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.
+
+// --------------------------------------------------------------------------------------
+//
+// A class that provides a simple, lightweight implementation of lazy initialization,
+// obviating the need for a developer to implement a custom, thread-safe lazy initialization
+// solution.
+//
+// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+#pragma warning disable 0420
+
+using System.Diagnostics;
+using System.Runtime.ExceptionServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+using System.Threading;
+
+namespace System
+{
+ internal enum LazyState
+ {
+ NoneViaConstructor = 0,
+ NoneViaFactory = 1,
+ NoneException = 2,
+
+ PublicationOnlyViaConstructor = 3,
+ PublicationOnlyViaFactory = 4,
+ PublicationOnlyWait = 5,
+ PublicationOnlyException = 6,
+
+ ExecutionAndPublicationViaConstructor = 7,
+ ExecutionAndPublicationViaFactory = 8,
+ ExecutionAndPublicationException = 9,
+ }
+
+ /// <summary>
+ /// LazyHelper serves multiples purposes
+ /// - minimizing code size of Lazy&lt;T&gt; by implementing as much of the code that is not generic
+ /// this reduces generic code bloat, making faster class initialization
+ /// - contains singleton objects that are used to handle threading primitives for PublicationOnly mode
+ /// - allows for instantiation for ExecutionAndPublication so as to create an object for locking on
+ /// - holds exception information.
+ /// </summary>
+ internal class LazyHelper
+ {
+ internal readonly static LazyHelper NoneViaConstructor = new LazyHelper(LazyState.NoneViaConstructor);
+ internal readonly static LazyHelper NoneViaFactory = new LazyHelper(LazyState.NoneViaFactory);
+ internal readonly static LazyHelper PublicationOnlyViaConstructor = new LazyHelper(LazyState.PublicationOnlyViaConstructor);
+ internal readonly static LazyHelper PublicationOnlyViaFactory = new LazyHelper(LazyState.PublicationOnlyViaFactory);
+ internal readonly static LazyHelper PublicationOnlyWaitForOtherThreadToPublish = new LazyHelper(LazyState.PublicationOnlyWait);
+
+ internal LazyState State { get; }
+
+ private readonly ExceptionDispatchInfo _exceptionDispatch;
+
+ /// <summary>
+ /// Constructor that defines the state
+ /// </summary>
+ internal LazyHelper(LazyState state)
+ {
+ State = state;
+ }
+
+ /// <summary>
+ /// Constructor used for exceptions
+ /// </summary>
+ internal LazyHelper(LazyThreadSafetyMode mode, Exception exception)
+ {
+ switch(mode)
+ {
+ case LazyThreadSafetyMode.ExecutionAndPublication:
+ State = LazyState.ExecutionAndPublicationException;
+ break;
+
+ case LazyThreadSafetyMode.None:
+ State = LazyState.NoneException;
+ break;
+
+ case LazyThreadSafetyMode.PublicationOnly:
+ State = LazyState.PublicationOnlyException;
+ break;
+
+ default:
+ Debug.Assert(false, "internal constructor, this should never occur");
+ break;
+ }
+
+ _exceptionDispatch = ExceptionDispatchInfo.Capture(exception);
+ }
+
+ internal void ThrowException()
+ {
+ Debug.Assert(_exceptionDispatch != null, "execution path is invalid");
+
+ _exceptionDispatch.Throw();
+ }
+
+ private LazyThreadSafetyMode GetMode()
+ {
+ switch (State)
+ {
+ case LazyState.NoneViaConstructor:
+ case LazyState.NoneViaFactory:
+ case LazyState.NoneException:
+ return LazyThreadSafetyMode.None;
+
+ case LazyState.PublicationOnlyViaConstructor:
+ case LazyState.PublicationOnlyViaFactory:
+ case LazyState.PublicationOnlyWait:
+ case LazyState.PublicationOnlyException:
+ return LazyThreadSafetyMode.PublicationOnly;
+
+ case LazyState.ExecutionAndPublicationViaConstructor:
+ case LazyState.ExecutionAndPublicationViaFactory:
+ case LazyState.ExecutionAndPublicationException:
+ return LazyThreadSafetyMode.ExecutionAndPublication;
+
+ default:
+ Debug.Assert(false, "Invalid logic; State should always have a valid value");
+ return default(LazyThreadSafetyMode);
+ }
+ }
+
+ internal static LazyThreadSafetyMode? GetMode(LazyHelper state)
+ {
+ if (state == null)
+ return null; // we don't know the mode anymore
+ return state.GetMode();
+ }
+
+ internal static bool GetIsValueFaulted(LazyHelper state) => state?._exceptionDispatch != null;
+
+ internal static LazyHelper Create(LazyThreadSafetyMode mode, bool useDefaultConstructor)
+ {
+ switch (mode)
+ {
+ case LazyThreadSafetyMode.None:
+ return useDefaultConstructor ? NoneViaConstructor : NoneViaFactory;
+
+ case LazyThreadSafetyMode.PublicationOnly:
+ return useDefaultConstructor ? PublicationOnlyViaConstructor : PublicationOnlyViaFactory;
+
+ case LazyThreadSafetyMode.ExecutionAndPublication:
+ // we need to create an object for ExecutionAndPublication because we use Monitor-based locking
+ var state = useDefaultConstructor ? LazyState.ExecutionAndPublicationViaConstructor : LazyState.ExecutionAndPublicationViaFactory;
+ return new LazyHelper(state);
+
+ default:
+ throw new ArgumentOutOfRangeException(nameof(mode), SR.Lazy_ctor_ModeInvalid);
+ }
+ }
+
+ internal static object CreateViaDefaultConstructor(Type type)
+ {
+ try
+ {
+ return Activator.CreateInstance(type);
+ }
+ catch (MissingMethodException)
+ {
+ throw new MissingMemberException(SR.Lazy_CreateValue_NoParameterlessCtorForT);
+ }
+ }
+
+ internal static LazyThreadSafetyMode GetModeFromIsThreadSafe(bool isThreadSafe)
+ {
+ return isThreadSafe ? LazyThreadSafetyMode.ExecutionAndPublication : LazyThreadSafetyMode.None;
+ }
+ }
+
+ /// <summary>
+ /// Provides support for lazy initialization.
+ /// </summary>
+ /// <typeparam name="T">Specifies the type of element being lazily initialized.</typeparam>
+ /// <remarks>
+ /// <para>
+ /// By default, all public and protected members of <see cref="Lazy{T}"/> are thread-safe and may be used
+ /// concurrently from multiple threads. These thread-safety guarantees may be removed optionally and per instance
+ /// using parameters to the type's constructors.
+ /// </para>
+ /// </remarks>
+ [Serializable]
+ [DebuggerTypeProxy(typeof(System_LazyDebugView<>))]
+ [DebuggerDisplay("ThreadSafetyMode={Mode}, IsValueCreated={IsValueCreated}, IsValueFaulted={IsValueFaulted}, Value={ValueForDebugDisplay}")]
+ public class Lazy<T>
+ {
+ private static T CreateViaDefaultConstructor()
+ {
+ return (T)LazyHelper.CreateViaDefaultConstructor(typeof(T));
+ }
+
+ // _state, a volatile reference, is set to null after m_value has been set
+ [NonSerialized]
+ private volatile LazyHelper _state;
+
+ // we ensure that _factory when finished is set to null to allow garbage collector to clean up
+ // any referenced items
+ [NonSerialized]
+ private Func<T> _factory;
+
+ // _value eventually stores the lazily created value. It is valid when _state = null.
+ private T _value;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/> class that
+ /// uses <typeparamref name="T"/>'s default constructor for lazy initialization.
+ /// </summary>
+ /// <remarks>
+ /// An instance created with this constructor may be used concurrently from multiple threads.
+ /// </remarks>
+ public Lazy()
+ : this(null, LazyThreadSafetyMode.ExecutionAndPublication, useDefaultConstructor:true)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/> class that
+ /// uses a pre-initialized specified value.
+ /// </summary>
+ /// <remarks>
+ /// An instance created with this constructor should be usable by multiple threads
+ // concurrently.
+ /// </remarks>
+ public Lazy(T value)
+ {
+ _value = value;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/> class that uses a
+ /// specified initialization function.
+ /// </summary>
+ /// <param name="valueFactory">
+ /// The <see cref="T:System.Func{T}"/> invoked to produce the lazily-initialized value when it is
+ /// needed.
+ /// </param>
+ /// <exception cref="System.ArgumentNullException"><paramref name="valueFactory"/> is a null
+ /// reference (Nothing in Visual Basic).</exception>
+ /// <remarks>
+ /// An instance created with this constructor may be used concurrently from multiple threads.
+ /// </remarks>
+ public Lazy(Func<T> valueFactory)
+ : this(valueFactory, LazyThreadSafetyMode.ExecutionAndPublication, useDefaultConstructor:false)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/>
+ /// class that uses <typeparamref name="T"/>'s default constructor and a specified thread-safety mode.
+ /// </summary>
+ /// <param name="isThreadSafe">true if this instance should be usable by multiple threads concurrently; false if the instance will only be used by one thread at a time.
+ /// </param>
+ public Lazy(bool isThreadSafe) :
+ this(null, LazyHelper.GetModeFromIsThreadSafe(isThreadSafe), useDefaultConstructor:true)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/>
+ /// class that uses <typeparamref name="T"/>'s default constructor and a specified thread-safety mode.
+ /// </summary>
+ /// <param name="mode">The lazy thread-safety mode mode</param>
+ /// <exception cref="System.ArgumentOutOfRangeException"><paramref name="mode"/> mode contains an invalid valuee</exception>
+ public Lazy(LazyThreadSafetyMode mode) :
+ this(null, mode, useDefaultConstructor:true)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/> class
+ /// that uses a specified initialization function and a specified thread-safety mode.
+ /// </summary>
+ /// <param name="valueFactory">
+ /// The <see cref="T:System.Func{T}"/> invoked to produce the lazily-initialized value when it is needed.
+ /// </param>
+ /// <param name="isThreadSafe">true if this instance should be usable by multiple threads concurrently; false if the instance will only be used by one thread at a time.
+ /// </param>
+ /// <exception cref="System.ArgumentNullException"><paramref name="valueFactory"/> is
+ /// a null reference (Nothing in Visual Basic).</exception>
+ public Lazy(Func<T> valueFactory, bool isThreadSafe) :
+ this(valueFactory, LazyHelper.GetModeFromIsThreadSafe(isThreadSafe), useDefaultConstructor:false)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/> class
+ /// that uses a specified initialization function and a specified thread-safety mode.
+ /// </summary>
+ /// <param name="valueFactory">
+ /// The <see cref="T:System.Func{T}"/> invoked to produce the lazily-initialized value when it is needed.
+ /// </param>
+ /// <param name="mode">The lazy thread-safety mode.</param>
+ /// <exception cref="System.ArgumentNullException"><paramref name="valueFactory"/> is
+ /// a null reference (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.ArgumentOutOfRangeException"><paramref name="mode"/> mode contains an invalid value.</exception>
+ public Lazy(Func<T> valueFactory, LazyThreadSafetyMode mode)
+ : this(valueFactory, mode, useDefaultConstructor:false)
+ {
+ }
+
+ private Lazy(Func<T> valueFactory, LazyThreadSafetyMode mode, bool useDefaultConstructor)
+ {
+ if (valueFactory == null && !useDefaultConstructor)
+ throw new ArgumentNullException(nameof(valueFactory));
+
+ _factory = valueFactory;
+ _state = LazyHelper.Create(mode, useDefaultConstructor);
+ }
+
+ private void ViaConstructor()
+ {
+ _value = CreateViaDefaultConstructor();
+ _state = null; // volatile write, must occur after setting _value
+ }
+
+ private void ViaFactory(LazyThreadSafetyMode mode)
+ {
+ try
+ {
+ Func<T> factory = _factory;
+ if (factory == null)
+ throw new InvalidOperationException(SR.Lazy_Value_RecursiveCallsToValue);
+ _factory = null;
+
+ _value = factory();
+ _state = null; // volatile write, must occur after setting _value
+ }
+ catch (Exception exception)
+ {
+ _state = new LazyHelper(mode, exception);
+ throw;
+ }
+ }
+
+ private void ExecutionAndPublication(LazyHelper executionAndPublication, bool useDefaultConstructor)
+ {
+ lock (executionAndPublication)
+ {
+ // it's possible for multiple calls to have piled up behind the lock, so we need to check
+ // to see if the ExecutionAndPublication object is still the current implementation.
+ if (ReferenceEquals(_state, executionAndPublication))
+ {
+ if (useDefaultConstructor)
+ {
+ ViaConstructor();
+ }
+ else
+ {
+ ViaFactory(LazyThreadSafetyMode.ExecutionAndPublication);
+ }
+ }
+ }
+ }
+
+ private void PublicationOnly(LazyHelper publicationOnly, T possibleValue)
+ {
+ LazyHelper previous = Interlocked.CompareExchange(ref _state, LazyHelper.PublicationOnlyWaitForOtherThreadToPublish, publicationOnly);
+ if (previous == publicationOnly)
+ {
+ _factory = null;
+ _value = possibleValue;
+ _state = null; // volatile write, must occur after setting _value
+ }
+ }
+
+ private void PublicationOnlyViaConstructor(LazyHelper initializer)
+ {
+ PublicationOnly(initializer, CreateViaDefaultConstructor());
+ }
+
+ private void PublicationOnlyViaFactory(LazyHelper initializer)
+ {
+ Func<T> factory = _factory;
+ if (factory == null)
+ {
+ PublicationOnlyWaitForOtherThreadToPublish();
+ }
+ else
+ {
+ PublicationOnly(initializer, factory());
+ }
+ }
+
+ private void PublicationOnlyWaitForOtherThreadToPublish()
+ {
+ var spinWait = new SpinWait();
+ while (!ReferenceEquals(_state, null))
+ {
+ // We get here when PublicationOnly temporarily sets _state to LazyHelper.PublicationOnlyWaitForOtherThreadToPublish.
+ // This temporary state should be quickly followed by _state being set to null.
+ spinWait.SpinOnce();
+ }
+ }
+
+ private T CreateValue()
+ {
+ // we have to create a copy of state here, and use the copy exclusively from here on in
+ // so as to ensure thread safety.
+ var state = _state;
+ if (state != null)
+ {
+ switch (state.State)
+ {
+ case LazyState.NoneViaConstructor:
+ ViaConstructor();
+ break;
+
+ case LazyState.NoneViaFactory:
+ ViaFactory(LazyThreadSafetyMode.None);
+ break;
+
+ case LazyState.PublicationOnlyViaConstructor:
+ PublicationOnlyViaConstructor(state);
+ break;
+
+ case LazyState.PublicationOnlyViaFactory:
+ PublicationOnlyViaFactory(state);
+ break;
+
+ case LazyState.PublicationOnlyWait:
+ PublicationOnlyWaitForOtherThreadToPublish();
+ break;
+
+ case LazyState.ExecutionAndPublicationViaConstructor:
+ ExecutionAndPublication(state, useDefaultConstructor:true);
+ break;
+
+ case LazyState.ExecutionAndPublicationViaFactory:
+ ExecutionAndPublication(state, useDefaultConstructor:false);
+ break;
+
+ default:
+ state.ThrowException();
+ break;
+ }
+ }
+ return Value;
+ }
+
+ /// <summary>Forces initialization during serialization.</summary>
+ /// <param name="context">The StreamingContext for the serialization operation.</param>
+ [OnSerializing]
+ private void OnSerializing(StreamingContext context)
+ {
+ // Force initialization
+ T dummy = Value;
+ }
+
+ /// <summary>Creates and returns a string representation of this instance.</summary>
+ /// <returns>The result of calling <see cref="System.Object.ToString"/> on the <see
+ /// cref="Value"/>.</returns>
+ /// <exception cref="T:System.NullReferenceException">
+ /// The <see cref="Value"/> is null.
+ /// </exception>
+ public override string ToString()
+ {
+ return IsValueCreated ? Value.ToString() : SR.Lazy_ToString_ValueNotCreated;
+ }
+
+ /// <summary>Gets the value of the Lazy&lt;T&gt; for debugging display purposes.</summary>
+ internal T ValueForDebugDisplay
+ {
+ get
+ {
+ if (!IsValueCreated)
+ {
+ return default(T);
+ }
+ return _value;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether this instance may be used concurrently from multiple threads.
+ /// </summary>
+ internal LazyThreadSafetyMode? Mode => LazyHelper.GetMode(_state);
+
+ /// <summary>
+ /// Gets whether the value creation is faulted or not
+ /// </summary>
+ internal bool IsValueFaulted => LazyHelper.GetIsValueFaulted(_state);
+
+ /// <summary>Gets a value indicating whether the <see cref="T:System.Lazy{T}"/> has been initialized.
+ /// </summary>
+ /// <value>true if the <see cref="T:System.Lazy{T}"/> instance has been initialized;
+ /// otherwise, false.</value>
+ /// <remarks>
+ /// The initialization of a <see cref="T:System.Lazy{T}"/> instance may result in either
+ /// a value being produced or an exception being thrown. If an exception goes unhandled during initialization,
+ /// <see cref="IsValueCreated"/> will return false.
+ /// </remarks>
+ public bool IsValueCreated => _state == null;
+
+ /// <summary>Gets the lazily initialized value of the current <see
+ /// cref="T:System.Threading.Lazy{T}"/>.</summary>
+ /// <value>The lazily initialized value of the current <see
+ /// cref="T:System.Threading.Lazy{T}"/>.</value>
+ /// <exception cref="T:System.MissingMemberException">
+ /// The <see cref="T:System.Threading.Lazy{T}"/> was initialized to use the default constructor
+ /// of the type being lazily initialized, and that type does not have a public, parameterless constructor.
+ /// </exception>
+ /// <exception cref="T:System.MemberAccessException">
+ /// The <see cref="T:System.Threading.Lazy{T}"/> was initialized to use the default constructor
+ /// of the type being lazily initialized, and permissions to access the constructor were missing.
+ /// </exception>
+ /// <exception cref="T:System.InvalidOperationException">
+ /// The <see cref="T:System.Threading.Lazy{T}"/> was constructed with the <see cref="T:System.Threading.LazyThreadSafetyMode.ExecutionAndPublication"/> or
+ /// <see cref="T:System.Threading.LazyThreadSafetyMode.None"/> and the initialization function attempted to access <see cref="Value"/> on this instance.
+ /// </exception>
+ /// <remarks>
+ /// If <see cref="IsValueCreated"/> is false, accessing <see cref="Value"/> will force initialization.
+ /// Please <see cref="System.Threading.LazyThreadSafetyMode"> for more information on how <see cref="T:System.Threading.Lazy{T}"/> will behave if an exception is thrown
+ /// from initialization delegate.
+ /// </remarks>
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ public T Value => _state == null ? _value : CreateValue();
+ }
+
+ /// <summary>A debugger view of the Lazy&lt;T&gt; to surface additional debugging properties and
+ /// to ensure that the Lazy&lt;T&gt; does not become initialized if it was not already.</summary>
+ internal sealed class System_LazyDebugView<T>
+ {
+ //The Lazy object being viewed.
+ private readonly Lazy<T> _lazy;
+
+ /// <summary>Constructs a new debugger view object for the provided Lazy object.</summary>
+ /// <param name="lazy">A Lazy object to browse in the debugger.</param>
+ public System_LazyDebugView(Lazy<T> lazy)
+ {
+ _lazy = lazy;
+ }
+
+ /// <summary>Returns whether the Lazy object is initialized or not.</summary>
+ public bool IsValueCreated
+ {
+ get { return _lazy.IsValueCreated; }
+ }
+
+ /// <summary>Returns the value of the Lazy object.</summary>
+ public T Value
+ {
+ get
+ { return _lazy.ValueForDebugDisplay; }
+ }
+
+ /// <summary>Returns the execution mode of the Lazy object</summary>
+ public LazyThreadSafetyMode? Mode
+ {
+ get { return _lazy.Mode; }
+ }
+
+ /// <summary>Returns the execution mode of the Lazy object</summary>
+ public bool IsValueFaulted
+ {
+ get { return _lazy.IsValueFaulted; }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/MarshalByRefObject.cs b/src/mscorlib/shared/System/MarshalByRefObject.cs
new file mode 100644
index 0000000000..1f1739b9cb
--- /dev/null
+++ b/src/mscorlib/shared/System/MarshalByRefObject.cs
@@ -0,0 +1,30 @@
+// 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.
+
+namespace System
+{
+ [Serializable]
+ public abstract class MarshalByRefObject
+ {
+ protected MarshalByRefObject()
+ {
+ }
+
+ public object GetLifetimeService()
+ {
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_Remoting);
+ }
+
+ public virtual object InitializeLifetimeService()
+ {
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_Remoting);
+ }
+
+ protected MarshalByRefObject MemberwiseClone(bool cloneIdentity)
+ {
+ MarshalByRefObject mbr = (MarshalByRefObject)base.MemberwiseClone();
+ return mbr;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/MemberAccessException.cs b/src/mscorlib/shared/System/MemberAccessException.cs
index 54eee67b07..54eee67b07 100644
--- a/src/mscorlib/src/System/MemberAccessException.cs
+++ b/src/mscorlib/shared/System/MemberAccessException.cs
diff --git a/src/mscorlib/src/System/MethodAccessException.cs b/src/mscorlib/shared/System/MethodAccessException.cs
index 2ecbd14d6d..2ecbd14d6d 100644
--- a/src/mscorlib/src/System/MethodAccessException.cs
+++ b/src/mscorlib/shared/System/MethodAccessException.cs
diff --git a/src/mscorlib/src/System/MidpointRounding.cs b/src/mscorlib/shared/System/MidpointRounding.cs
index a75de43e65..a75de43e65 100644
--- a/src/mscorlib/src/System/MidpointRounding.cs
+++ b/src/mscorlib/shared/System/MidpointRounding.cs
diff --git a/src/mscorlib/shared/System/MissingMethodException.cs b/src/mscorlib/shared/System/MissingMethodException.cs
new file mode 100644
index 0000000000..07d428967b
--- /dev/null
+++ b/src/mscorlib/shared/System/MissingMethodException.cs
@@ -0,0 +1,60 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: The exception class for class loading failures.
+**
+**
+=============================================================================*/
+
+using System.Runtime.Serialization;
+
+namespace System
+{
+ [Serializable]
+ public class MissingMethodException : MissingMemberException
+ {
+ public MissingMethodException()
+ : base(SR.Arg_MissingMethodException)
+ {
+ HResult = __HResults.COR_E_MISSINGMETHOD;
+ }
+
+ public MissingMethodException(string message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_MISSINGMETHOD;
+ }
+
+ public MissingMethodException(string message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_MISSINGMETHOD;
+ }
+
+ public MissingMethodException(string className, string methodName)
+ {
+ ClassName = className;
+ MemberName = methodName;
+ }
+
+ protected MissingMethodException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+
+ public override string Message
+ {
+ get
+ {
+ return ClassName == null ? base.Message :
+ SR.Format(SR.MissingMethod_Name, ClassName + "." + MemberName +
+ (Signature != null ? " " + FormatSignature(Signature) : string.Empty));
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/MulticastNotSupportedException.cs b/src/mscorlib/shared/System/MulticastNotSupportedException.cs
index 4fcaa9857d..4fcaa9857d 100644
--- a/src/mscorlib/src/System/MulticastNotSupportedException.cs
+++ b/src/mscorlib/shared/System/MulticastNotSupportedException.cs
diff --git a/src/mscorlib/shared/System/NotFiniteNumberException.cs b/src/mscorlib/shared/System/NotFiniteNumberException.cs
new file mode 100644
index 0000000000..5bc8df1e28
--- /dev/null
+++ b/src/mscorlib/shared/System/NotFiniteNumberException.cs
@@ -0,0 +1,71 @@
+// 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.Runtime.Serialization;
+
+namespace System
+{
+ [Serializable]
+ public class NotFiniteNumberException : ArithmeticException
+ {
+ private double _offendingNumber;
+
+ public NotFiniteNumberException()
+ : base(SR.Arg_NotFiniteNumberException)
+ {
+ _offendingNumber = 0;
+ HResult = __HResults.COR_E_NOTFINITENUMBER;
+ }
+
+ public NotFiniteNumberException(double offendingNumber)
+ : base()
+ {
+ _offendingNumber = offendingNumber;
+ HResult = __HResults.COR_E_NOTFINITENUMBER;
+ }
+
+ public NotFiniteNumberException(String message)
+ : base(message)
+ {
+ _offendingNumber = 0;
+ HResult = __HResults.COR_E_NOTFINITENUMBER;
+ }
+
+ public NotFiniteNumberException(String message, double offendingNumber)
+ : base(message)
+ {
+ _offendingNumber = offendingNumber;
+ HResult = __HResults.COR_E_NOTFINITENUMBER;
+ }
+
+ public NotFiniteNumberException(String message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_NOTFINITENUMBER;
+ }
+
+ public NotFiniteNumberException(String message, double offendingNumber, Exception innerException)
+ : base(message, innerException)
+ {
+ _offendingNumber = offendingNumber;
+ HResult = __HResults.COR_E_NOTFINITENUMBER;
+ }
+
+ protected NotFiniteNumberException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ _offendingNumber = info.GetInt32("OffendingNumber");
+ }
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData(info, context);
+ info.AddValue("OffendingNumber", _offendingNumber, typeof(Int32));
+ }
+
+ public double OffendingNumber
+ {
+ get { return _offendingNumber; }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/NotImplementedException.cs b/src/mscorlib/shared/System/NotImplementedException.cs
index 4d141eac8c..4d141eac8c 100644
--- a/src/mscorlib/src/System/NotImplementedException.cs
+++ b/src/mscorlib/shared/System/NotImplementedException.cs
diff --git a/src/mscorlib/src/System/NotSupportedException.cs b/src/mscorlib/shared/System/NotSupportedException.cs
index 21b2d54a46..21b2d54a46 100644
--- a/src/mscorlib/src/System/NotSupportedException.cs
+++ b/src/mscorlib/shared/System/NotSupportedException.cs
diff --git a/src/mscorlib/src/System/NullReferenceException.cs b/src/mscorlib/shared/System/NullReferenceException.cs
index 0aa5c6197a..0aa5c6197a 100644
--- a/src/mscorlib/src/System/NullReferenceException.cs
+++ b/src/mscorlib/shared/System/NullReferenceException.cs
diff --git a/src/mscorlib/shared/System/ObjectDisposedException.cs b/src/mscorlib/shared/System/ObjectDisposedException.cs
new file mode 100644
index 0000000000..abb7c89dae
--- /dev/null
+++ b/src/mscorlib/shared/System/ObjectDisposedException.cs
@@ -0,0 +1,82 @@
+// 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.Globalization;
+using System.Runtime.Serialization;
+
+namespace System
+{
+ /// <devdoc>
+ /// <para> The exception that is thrown when accessing an object that was
+ /// disposed.</para>
+ /// </devdoc>
+ [Serializable]
+ public class ObjectDisposedException : InvalidOperationException
+ {
+ private String _objectName;
+
+ // This constructor should only be called by the EE (COMPlusThrow)
+ private ObjectDisposedException() :
+ this(null, SR.ObjectDisposed_Generic)
+ {
+ }
+
+ public ObjectDisposedException(String objectName) :
+ this(objectName, SR.ObjectDisposed_Generic)
+ {
+ }
+
+ public ObjectDisposedException(String objectName, String message) : base(message)
+ {
+ HResult = __HResults.COR_E_OBJECTDISPOSED;
+ _objectName = objectName;
+ }
+
+ public ObjectDisposedException(String message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_OBJECTDISPOSED;
+ }
+
+ protected ObjectDisposedException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ _objectName = info.GetString("ObjectName");
+ }
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData(info, context);
+ info.AddValue("ObjectName", ObjectName, typeof(String));
+ }
+
+ /// <devdoc>
+ /// <para>Gets the text for the message for this exception.</para>
+ /// </devdoc>
+ public override String Message
+ {
+ get
+ {
+ String name = ObjectName;
+ if (name == null || name.Length == 0)
+ return base.Message;
+
+ String objectDisposed = SR.Format(SR.ObjectDisposed_ObjectName_Name, name);
+ return base.Message + Environment.NewLine + objectDisposed;
+ }
+ }
+
+ public String ObjectName
+ {
+ get
+ {
+ if ((_objectName == null)) // && !CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
+ {
+ return String.Empty;
+ }
+ return _objectName;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/ObsoleteAttribute.cs b/src/mscorlib/shared/System/ObsoleteAttribute.cs
index f183685998..f183685998 100644
--- a/src/mscorlib/src/System/ObsoleteAttribute.cs
+++ b/src/mscorlib/shared/System/ObsoleteAttribute.cs
diff --git a/src/mscorlib/src/System/OverflowException.cs b/src/mscorlib/shared/System/OverflowException.cs
index e28c688dd6..e28c688dd6 100644
--- a/src/mscorlib/src/System/OverflowException.cs
+++ b/src/mscorlib/shared/System/OverflowException.cs
diff --git a/src/mscorlib/src/System/ParamArrayAttribute.cs b/src/mscorlib/shared/System/ParamArrayAttribute.cs
index d3c3d46d56..d3c3d46d56 100644
--- a/src/mscorlib/src/System/ParamArrayAttribute.cs
+++ b/src/mscorlib/shared/System/ParamArrayAttribute.cs
diff --git a/src/mscorlib/shared/System/ParamsArray.cs b/src/mscorlib/shared/System/ParamsArray.cs
new file mode 100644
index 0000000000..1c73bc5856
--- /dev/null
+++ b/src/mscorlib/shared/System/ParamsArray.cs
@@ -0,0 +1,82 @@
+// 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.
+
+namespace System
+{
+ internal struct ParamsArray
+ {
+ // Sentinel fixed-length arrays eliminate the need for a "count" field keeping this
+ // struct down to just 4 fields. These are only used for their "Length" property,
+ // that is, their elements are never set or referenced.
+ private static readonly object[] s_oneArgArray = new object[1];
+ private static readonly object[] s_twoArgArray = new object[2];
+ private static readonly object[] s_threeArgArray = new object[3];
+
+ private readonly object _arg0;
+ private readonly object _arg1;
+ private readonly object _arg2;
+
+ // After construction, the first three elements of this array will never be accessed
+ // because the indexer will retrieve those values from arg0, arg1, and arg2.
+ private readonly object[] _args;
+
+ public ParamsArray(object arg0)
+ {
+ _arg0 = arg0;
+ _arg1 = null;
+ _arg2 = null;
+
+ // Always assign this.args to make use of its "Length" property
+ _args = s_oneArgArray;
+ }
+
+ public ParamsArray(object arg0, object arg1)
+ {
+ _arg0 = arg0;
+ _arg1 = arg1;
+ _arg2 = null;
+
+ // Always assign this.args to make use of its "Length" property
+ _args = s_twoArgArray;
+ }
+
+ public ParamsArray(object arg0, object arg1, object arg2)
+ {
+ _arg0 = arg0;
+ _arg1 = arg1;
+ _arg2 = arg2;
+
+ // Always assign this.args to make use of its "Length" property
+ _args = s_threeArgArray;
+ }
+
+ public ParamsArray(object[] args)
+ {
+ int len = args.Length;
+ _arg0 = len > 0 ? args[0] : null;
+ _arg1 = len > 1 ? args[1] : null;
+ _arg2 = len > 2 ? args[2] : null;
+ _args = args;
+ }
+
+ public int Length
+ {
+ get { return _args.Length; }
+ }
+
+ public object this[int index]
+ {
+ get { return index == 0 ? _arg0 : GetAtSlow(index); }
+ }
+
+ private object GetAtSlow(int index)
+ {
+ if (index == 1)
+ return _arg1;
+ if (index == 2)
+ return _arg2;
+ return _args[index];
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/PlatformNotSupportedException.cs b/src/mscorlib/shared/System/PlatformNotSupportedException.cs
index d2370b3924..d2370b3924 100644
--- a/src/mscorlib/src/System/PlatformNotSupportedException.cs
+++ b/src/mscorlib/shared/System/PlatformNotSupportedException.cs
diff --git a/src/mscorlib/src/System/Progress.cs b/src/mscorlib/shared/System/Progress.cs
index 755e7719fe..755e7719fe 100644
--- a/src/mscorlib/src/System/Progress.cs
+++ b/src/mscorlib/shared/System/Progress.cs
diff --git a/src/mscorlib/shared/System/Random.cs b/src/mscorlib/shared/System/Random.cs
new file mode 100644
index 0000000000..a66a9ea423
--- /dev/null
+++ b/src/mscorlib/shared/System/Random.cs
@@ -0,0 +1,274 @@
+// 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.
+
+/*============================================================
+**
+**
+** Purpose: A random number generator.
+**
+**
+===========================================================*/
+
+using System;
+using System.Runtime;
+using System.Runtime.CompilerServices;
+using System.Globalization;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
+ [Serializable]
+ public class Random
+ {
+ //
+ // Private Constants
+ //
+ private const int MBIG = Int32.MaxValue;
+ private const int MSEED = 161803398;
+ private const int MZ = 0;
+
+
+ //
+ // Member Variables
+ //
+ private int _inext;
+ private int _inextp;
+ private int[] _seedArray = new int[56];
+
+ //
+ // Public Constants
+ //
+
+ //
+ // Native Declarations
+ //
+
+ //
+ // Constructors
+ //
+
+ /*=========================================================================================
+ **Action: Initializes a new instance of the Random class, using a default seed value
+ ===========================================================================================*/
+ public Random()
+ : this(GenerateSeed())
+ {
+ }
+
+ /*=========================================================================================
+ **Action: Initializes a new instance of the Random class, using a specified seed value
+ ===========================================================================================*/
+ public Random(int Seed)
+ {
+ int ii = 0;
+ int mj, mk;
+
+ //Initialize our Seed array.
+ int subtraction = (Seed == Int32.MinValue) ? Int32.MaxValue : Math.Abs(Seed);
+ mj = MSEED - subtraction;
+ _seedArray[55] = mj;
+ mk = 1;
+ for (int i = 1; i < 55; i++)
+ { //Apparently the range [1..55] is special (Knuth) and so we're wasting the 0'th position.
+ if ((ii += 21) >= 55) ii -= 55;
+ _seedArray[ii] = mk;
+ mk = mj - mk;
+ if (mk < 0) mk += MBIG;
+ mj = _seedArray[ii];
+ }
+ for (int k = 1; k < 5; k++)
+ {
+ for (int i = 1; i < 56; i++)
+ {
+ int n = i + 30;
+ if (n >= 55) n -= 55;
+ _seedArray[i] -= _seedArray[1 + n];
+ if (_seedArray[i] < 0) _seedArray[i] += MBIG;
+ }
+ }
+ _inext = 0;
+ _inextp = 21;
+ Seed = 1;
+ }
+
+ //
+ // Package Private Methods
+ //
+
+ /*====================================Sample====================================
+ **Action: Return a new random number [0..1) and reSeed the Seed array.
+ **Returns: A double [0..1)
+ **Arguments: None
+ **Exceptions: None
+ ==============================================================================*/
+ protected virtual double Sample()
+ {
+ //Including this division at the end gives us significantly improved
+ //random number distribution.
+ return (InternalSample() * (1.0 / MBIG));
+ }
+
+ private int InternalSample()
+ {
+ int retVal;
+ int locINext = _inext;
+ int locINextp = _inextp;
+
+ if (++locINext >= 56) locINext = 1;
+ if (++locINextp >= 56) locINextp = 1;
+
+ retVal = _seedArray[locINext] - _seedArray[locINextp];
+
+ if (retVal == MBIG) retVal--;
+ if (retVal < 0) retVal += MBIG;
+
+ _seedArray[locINext] = retVal;
+
+ _inext = locINext;
+ _inextp = locINextp;
+
+ return retVal;
+ }
+
+ [ThreadStatic]
+ private static Random t_threadRandom;
+ private static readonly Random s_globalRandom = new Random(GenerateGlobalSeed());
+
+ /*=====================================GenerateSeed=====================================
+ **Returns: An integer that can be used as seed values for consecutively
+ creating lots of instances on the same thread within a short period of time.
+ ========================================================================================*/
+ private static int GenerateSeed()
+ {
+ Random rnd = t_threadRandom;
+ if (rnd == null)
+ {
+ int seed;
+ lock (s_globalRandom)
+ {
+ seed = s_globalRandom.Next();
+ }
+ rnd = new Random(seed);
+ t_threadRandom = rnd;
+ }
+ return rnd.Next();
+ }
+
+ /*==================================GenerateGlobalSeed====================================
+ **Action: Creates a number to use as global seed.
+ **Returns: An integer that is safe to use as seed values for thread-local seed generators.
+ ==========================================================================================*/
+ private static unsafe int GenerateGlobalSeed()
+ {
+ int result;
+ Interop.GetRandomBytes((byte*)&result, sizeof(int));
+ return result;
+ }
+
+ //
+ // Public Instance Methods
+ //
+
+
+ /*=====================================Next=====================================
+ **Returns: An int [0..Int32.MaxValue)
+ **Arguments: None
+ **Exceptions: None.
+ ==============================================================================*/
+ public virtual int Next()
+ {
+ return InternalSample();
+ }
+
+ private double GetSampleForLargeRange()
+ {
+ // The distribution of double value returned by Sample
+ // is not distributed well enough for a large range.
+ // If we use Sample for a range [Int32.MinValue..Int32.MaxValue)
+ // We will end up getting even numbers only.
+
+ int result = InternalSample();
+ // Note we can't use addition here. The distribution will be bad if we do that.
+ bool negative = (InternalSample() % 2 == 0) ? true : false; // decide the sign based on second sample
+ if (negative)
+ {
+ result = -result;
+ }
+ double d = result;
+ d += (Int32.MaxValue - 1); // get a number in range [0 .. 2 * Int32MaxValue - 1)
+ d /= 2 * (uint)Int32.MaxValue - 1;
+ return d;
+ }
+
+
+ /*=====================================Next=====================================
+ **Returns: An int [minvalue..maxvalue)
+ **Arguments: minValue -- the least legal value for the Random number.
+ ** maxValue -- One greater than the greatest legal return value.
+ **Exceptions: None.
+ ==============================================================================*/
+ public virtual int Next(int minValue, int maxValue)
+ {
+ if (minValue > maxValue)
+ {
+ throw new ArgumentOutOfRangeException(nameof(minValue), SR.Format(SR.Argument_MinMaxValue, nameof(minValue), nameof(maxValue)));
+ }
+ Contract.EndContractBlock();
+
+ long range = (long)maxValue - minValue;
+ if (range <= (long)Int32.MaxValue)
+ {
+ return ((int)(Sample() * range) + minValue);
+ }
+ else
+ {
+ return (int)((long)(GetSampleForLargeRange() * range) + minValue);
+ }
+ }
+
+
+ /*=====================================Next=====================================
+ **Returns: An int [0..maxValue)
+ **Arguments: maxValue -- One more than the greatest legal return value.
+ **Exceptions: None.
+ ==============================================================================*/
+ public virtual int Next(int maxValue)
+ {
+ if (maxValue < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(maxValue), SR.Format(SR.ArgumentOutOfRange_MustBePositive, nameof(maxValue)));
+ }
+ Contract.EndContractBlock();
+ return (int)(Sample() * maxValue);
+ }
+
+
+ /*=====================================Next=====================================
+ **Returns: A double [0..1)
+ **Arguments: None
+ **Exceptions: None
+ ==============================================================================*/
+ public virtual double NextDouble()
+ {
+ return Sample();
+ }
+
+
+ /*==================================NextBytes===================================
+ **Action: Fills the byte array with random bytes [0..0x7f]. The entire array is filled.
+ **Returns:Void
+ **Arguments: buffer -- the array to be filled.
+ **Exceptions: None
+ ==============================================================================*/
+ public virtual void NextBytes(byte[] buffer)
+ {
+ if (buffer == null) throw new ArgumentNullException(nameof(buffer));
+ Contract.EndContractBlock();
+ for (int i = 0; i < buffer.Length; i++)
+ {
+ buffer[i] = (byte)(InternalSample() % (Byte.MaxValue + 1));
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/RankException.cs b/src/mscorlib/shared/System/RankException.cs
index 612d0f086c..612d0f086c 100644
--- a/src/mscorlib/src/System/RankException.cs
+++ b/src/mscorlib/shared/System/RankException.cs
diff --git a/src/mscorlib/shared/System/Reflection/AmbiguousMatchException.cs b/src/mscorlib/shared/System/Reflection/AmbiguousMatchException.cs
new file mode 100644
index 0000000000..459a19cb71
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AmbiguousMatchException.cs
@@ -0,0 +1,35 @@
+// 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.Runtime.Serialization;
+
+namespace System.Reflection
+{
+ [Serializable]
+ public sealed class AmbiguousMatchException : SystemException
+ {
+ public AmbiguousMatchException()
+ : base(SR.RFLCT_Ambiguous)
+ {
+ HResult = __HResults.COR_E_AMBIGUOUSMATCH;
+ }
+
+ public AmbiguousMatchException(string message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_AMBIGUOUSMATCH;
+ }
+
+ public AmbiguousMatchException(string message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_AMBIGUOUSMATCH;
+ }
+
+ internal AmbiguousMatchException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/Assembly.cs b/src/mscorlib/shared/System/Reflection/Assembly.cs
new file mode 100644
index 0000000000..d35ffc7066
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/Assembly.cs
@@ -0,0 +1,200 @@
+// 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.IO;
+using System.Globalization;
+using System.Collections.Generic;
+using System.Configuration.Assemblies;
+using System.Runtime.Serialization;
+using System.Security;
+
+namespace System.Reflection
+{
+ public abstract partial class Assembly : ICustomAttributeProvider, ISerializable
+ {
+ protected Assembly() { }
+
+ public virtual IEnumerable<TypeInfo> DefinedTypes
+ {
+ get
+ {
+ Type[] types = GetTypes();
+ TypeInfo[] typeinfos = new TypeInfo[types.Length];
+ for (int i = 0; i < types.Length; i++)
+ {
+ TypeInfo typeinfo = types[i].GetTypeInfo();
+ if (typeinfo == null)
+ throw new NotSupportedException(SR.Format(SR.NotSupported_NoTypeInfo, types[i].FullName));
+
+ typeinfos[i] = typeinfo;
+ }
+ return typeinfos;
+ }
+ }
+
+ public virtual Type[] GetTypes()
+ {
+ Module[] m = GetModules(false);
+
+ int finalLength = 0;
+ Type[][] moduleTypes = new Type[m.Length][];
+
+ for (int i = 0; i < moduleTypes.Length; i++)
+ {
+ moduleTypes[i] = m[i].GetTypes();
+ finalLength += moduleTypes[i].Length;
+ }
+
+ int current = 0;
+ Type[] ret = new Type[finalLength];
+ for (int i = 0; i < moduleTypes.Length; i++)
+ {
+ int length = moduleTypes[i].Length;
+ Array.Copy(moduleTypes[i], 0, ret, current, length);
+ current += length;
+ }
+
+ return ret;
+ }
+
+ public virtual IEnumerable<Type> ExportedTypes => GetExportedTypes();
+ public virtual Type[] GetExportedTypes() { throw NotImplemented.ByDesign; }
+
+ public virtual string CodeBase { get { throw NotImplemented.ByDesign; } }
+ public virtual MethodInfo EntryPoint { get { throw NotImplemented.ByDesign; } }
+ public virtual string FullName { get { throw NotImplemented.ByDesign; } }
+ public virtual string ImageRuntimeVersion { get { throw NotImplemented.ByDesign; } }
+ public virtual bool IsDynamic => false;
+ public virtual string Location { get { throw NotImplemented.ByDesign; } }
+ public virtual bool ReflectionOnly { get { throw NotImplemented.ByDesign; } }
+
+ public virtual ManifestResourceInfo GetManifestResourceInfo(string resourceName) { throw NotImplemented.ByDesign; }
+ public virtual string[] GetManifestResourceNames() { throw NotImplemented.ByDesign; }
+ public virtual Stream GetManifestResourceStream(string name) { throw NotImplemented.ByDesign; }
+ public virtual Stream GetManifestResourceStream(Type type, string name) { throw NotImplemented.ByDesign; }
+
+ public bool IsFullyTrusted => true;
+
+ public virtual AssemblyName GetName() => GetName(copiedName: false);
+ public virtual AssemblyName GetName(bool copiedName) { throw NotImplemented.ByDesign; }
+
+ public virtual Type GetType(string name) => GetType(name, throwOnError: false, ignoreCase: false);
+ public virtual Type GetType(string name, bool throwOnError) => GetType(name, throwOnError: throwOnError, ignoreCase: false);
+ public virtual Type GetType(string name, bool throwOnError, bool ignoreCase) { throw NotImplemented.ByDesign; }
+
+ public virtual bool IsDefined(Type attributeType, bool inherit) { throw NotImplemented.ByDesign; }
+
+ public virtual IEnumerable<CustomAttributeData> CustomAttributes => GetCustomAttributesData();
+ public virtual IList<CustomAttributeData> GetCustomAttributesData() { throw NotImplemented.ByDesign; }
+
+ public virtual object[] GetCustomAttributes(bool inherit) { throw NotImplemented.ByDesign; }
+ public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) { throw NotImplemented.ByDesign; }
+
+ public virtual string EscapedCodeBase => AssemblyName.EscapeCodeBase(CodeBase);
+
+ public object CreateInstance(string typeName) => CreateInstance(typeName, false, BindingFlags.Public | BindingFlags.Instance, binder: null, args: null, culture: null, activationAttributes: null);
+ public object CreateInstance(string typeName, bool ignoreCase) => CreateInstance(typeName, ignoreCase, BindingFlags.Public | BindingFlags.Instance, binder: null, args: null, culture: null, activationAttributes: null);
+ public virtual object CreateInstance(string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes)
+ {
+ Type t = GetType(typeName, throwOnError: false, ignoreCase: ignoreCase);
+ if (t == null)
+ return null;
+
+ return Activator.CreateInstance(t, bindingAttr, binder, args, culture, activationAttributes);
+ }
+
+ public virtual event ModuleResolveEventHandler ModuleResolve { add { throw NotImplemented.ByDesign; } remove { throw NotImplemented.ByDesign; } }
+
+ public virtual Module ManifestModule { get { throw NotImplemented.ByDesign; } }
+ public virtual Module GetModule(string name) { throw NotImplemented.ByDesign; }
+
+ public Module[] GetModules() => GetModules(getResourceModules: false);
+ public virtual Module[] GetModules(bool getResourceModules) { throw NotImplemented.ByDesign; }
+
+ public virtual IEnumerable<Module> Modules => GetLoadedModules(getResourceModules: true);
+ public Module[] GetLoadedModules() => GetLoadedModules(getResourceModules: false);
+ public virtual Module[] GetLoadedModules(bool getResourceModules) { throw NotImplemented.ByDesign; }
+
+ public virtual AssemblyName[] GetReferencedAssemblies() { throw NotImplemented.ByDesign; }
+
+ public virtual Assembly GetSatelliteAssembly(CultureInfo culture) { throw NotImplemented.ByDesign; }
+ public virtual Assembly GetSatelliteAssembly(CultureInfo culture, Version version) { throw NotImplemented.ByDesign; }
+
+ public virtual FileStream GetFile(string name) { throw NotImplemented.ByDesign; }
+ public virtual FileStream[] GetFiles() => GetFiles(getResourceModules: false);
+ public virtual FileStream[] GetFiles(bool getResourceModules) { throw NotImplemented.ByDesign; }
+
+ public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { throw NotImplemented.ByDesign; }
+
+ public override string ToString()
+ {
+ string displayName = FullName;
+ if (displayName == null)
+ return base.ToString();
+ else
+ return displayName;
+ }
+
+ /*
+ Returns true if the assembly was loaded from the global assembly cache.
+ */
+ public virtual bool GlobalAssemblyCache { get { throw NotImplemented.ByDesign; } }
+ public virtual Int64 HostContext { get { throw NotImplemented.ByDesign; } }
+
+ public override bool Equals(object o) => base.Equals(o);
+ public override int GetHashCode() => base.GetHashCode();
+
+ public static bool operator ==(Assembly left, Assembly right)
+ {
+ if (object.ReferenceEquals(left, right))
+ return true;
+
+ if ((object)left == null || (object)right == null)
+ return false;
+
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(Assembly left, Assembly right)
+ {
+ return !(left == right);
+ }
+
+ public static string CreateQualifiedName(string assemblyName, string typeName) => typeName + ", " + assemblyName;
+
+ public static Assembly GetAssembly(Type type)
+ {
+ if (type == null)
+ throw new ArgumentNullException(nameof(type));
+
+ Module m = type.Module;
+ if (m == null)
+ return null;
+ else
+ return m.Assembly;
+ }
+
+ public static Assembly Load(byte[] rawAssembly) => Load(rawAssembly, rawSymbolStore: null);
+
+ [Obsolete("This method has been deprecated. Please use Assembly.Load() instead. http://go.microsoft.com/fwlink/?linkid=14202")]
+ public static Assembly LoadWithPartialName(string partialName)
+ {
+ if (partialName == null)
+ throw new ArgumentNullException(nameof(partialName));
+
+ return Load(partialName);
+ }
+
+ public static Assembly UnsafeLoadFrom(string assemblyFile) => LoadFrom(assemblyFile);
+
+ public Module LoadModule(string moduleName, byte[] rawModule) => LoadModule(moduleName, rawModule, null);
+ public virtual Module LoadModule(string moduleName, byte[] rawModule, byte[] rawSymbolStore) { throw NotImplemented.ByDesign; }
+
+ public static Assembly ReflectionOnlyLoad(byte[] rawAssembly) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ReflectionOnly); }
+ public static Assembly ReflectionOnlyLoad(string assemblyString) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ReflectionOnly); }
+ public static Assembly ReflectionOnlyLoadFrom(string assemblyFile) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ReflectionOnly); }
+
+ public virtual SecurityRuleSet SecurityRuleSet => SecurityRuleSet.None;
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyAlgorithmIdAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyAlgorithmIdAttribute.cs
new file mode 100644
index 0000000000..fe24f353be
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyAlgorithmIdAttribute.cs
@@ -0,0 +1,27 @@
+// 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.Configuration.Assemblies;
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyAlgorithmIdAttribute : Attribute
+ {
+ public AssemblyAlgorithmIdAttribute(AssemblyHashAlgorithm algorithmId)
+ {
+ AlgorithmId = (uint)algorithmId;
+ }
+
+ [CLSCompliant(false)]
+ public AssemblyAlgorithmIdAttribute(uint algorithmId)
+ {
+ AlgorithmId = algorithmId;
+ }
+
+ [CLSCompliant(false)]
+ public uint AlgorithmId { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyCompanyAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyCompanyAttribute.cs
new file mode 100644
index 0000000000..d986db60a3
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyCompanyAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyCompanyAttribute : Attribute
+ {
+ public AssemblyCompanyAttribute(string company)
+ {
+ Company = company;
+ }
+
+ public string Company { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyConfigurationAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyConfigurationAttribute.cs
new file mode 100644
index 0000000000..195c4d0ca6
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyConfigurationAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyConfigurationAttribute : Attribute
+ {
+ public AssemblyConfigurationAttribute(string configuration)
+ {
+ Configuration = configuration;
+ }
+
+ public string Configuration { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyContentType.cs b/src/mscorlib/shared/System/Reflection/AssemblyContentType.cs
new file mode 100644
index 0000000000..2ee1a00818
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyContentType.cs
@@ -0,0 +1,13 @@
+// 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.
+
+namespace System.Reflection
+{
+ public enum AssemblyContentType
+ {
+ Default = 0,
+ WindowsRuntime = 1,
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyCopyrightAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyCopyrightAttribute.cs
new file mode 100644
index 0000000000..e50e19932b
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyCopyrightAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyCopyrightAttribute : Attribute
+ {
+ public AssemblyCopyrightAttribute(string copyright)
+ {
+ Copyright = copyright;
+ }
+
+ public string Copyright { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyCultureAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyCultureAttribute.cs
new file mode 100644
index 0000000000..e31c6f9c1c
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyCultureAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyCultureAttribute : Attribute
+ {
+ public AssemblyCultureAttribute(string culture)
+ {
+ Culture = culture;
+ }
+
+ public string Culture { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyDefaultAliasAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyDefaultAliasAttribute.cs
new file mode 100644
index 0000000000..ced35ed3fd
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyDefaultAliasAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyDefaultAliasAttribute : Attribute
+ {
+ public AssemblyDefaultAliasAttribute(string defaultAlias)
+ {
+ DefaultAlias = defaultAlias;
+ }
+
+ public string DefaultAlias { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyDelaySignAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyDelaySignAttribute.cs
new file mode 100644
index 0000000000..eae2cf613c
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyDelaySignAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyDelaySignAttribute : Attribute
+ {
+ public AssemblyDelaySignAttribute(bool delaySign)
+ {
+ DelaySign = delaySign;
+ }
+
+ public bool DelaySign { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyDescriptionAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyDescriptionAttribute.cs
new file mode 100644
index 0000000000..50f57c96a6
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyDescriptionAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyDescriptionAttribute : Attribute
+ {
+ public AssemblyDescriptionAttribute(string description)
+ {
+ Description = description;
+ }
+
+ public string Description { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyFileVersionAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyFileVersionAttribute.cs
new file mode 100644
index 0000000000..b5face65bc
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyFileVersionAttribute.cs
@@ -0,0 +1,20 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyFileVersionAttribute : Attribute
+ {
+ public AssemblyFileVersionAttribute(string version)
+ {
+ if (version == null)
+ throw new ArgumentNullException(nameof(version));
+ Version = version;
+ }
+
+ public string Version { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyFlagsAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyFlagsAttribute.cs
new file mode 100644
index 0000000000..103413340c
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyFlagsAttribute.cs
@@ -0,0 +1,43 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyFlagsAttribute : Attribute
+ {
+ private AssemblyNameFlags _flags;
+
+ [Obsolete("This constructor has been deprecated. Please use AssemblyFlagsAttribute(AssemblyNameFlags) instead. http://go.microsoft.com/fwlink/?linkid=14202")]
+ [CLSCompliant(false)]
+ public AssemblyFlagsAttribute(uint flags)
+ {
+ _flags = (AssemblyNameFlags)flags;
+ }
+
+ [Obsolete("This property has been deprecated. Please use AssemblyFlags instead. http://go.microsoft.com/fwlink/?linkid=14202")]
+ [CLSCompliant(false)]
+ public uint Flags
+ {
+ get { return (uint)_flags; }
+ }
+
+ public int AssemblyFlags
+ {
+ get { return (int)_flags; }
+ }
+
+ [Obsolete("This constructor has been deprecated. Please use AssemblyFlagsAttribute(AssemblyNameFlags) instead. http://go.microsoft.com/fwlink/?linkid=14202")]
+ public AssemblyFlagsAttribute(int assemblyFlags)
+ {
+ _flags = (AssemblyNameFlags)assemblyFlags;
+ }
+
+ public AssemblyFlagsAttribute(AssemblyNameFlags assemblyFlags)
+ {
+ _flags = assemblyFlags;
+ }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyInformationalVersionAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyInformationalVersionAttribute.cs
new file mode 100644
index 0000000000..915b973ab9
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyInformationalVersionAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyInformationalVersionAttribute : Attribute
+ {
+ public AssemblyInformationalVersionAttribute(string informationalVersion)
+ {
+ InformationalVersion = informationalVersion;
+ }
+
+ public string InformationalVersion { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyKeyFileAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyKeyFileAttribute.cs
new file mode 100644
index 0000000000..9f7387d8af
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyKeyFileAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyKeyFileAttribute : Attribute
+ {
+ public AssemblyKeyFileAttribute(string keyFile)
+ {
+ KeyFile = keyFile;
+ }
+
+ public string KeyFile { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyKeyNameAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyKeyNameAttribute.cs
new file mode 100644
index 0000000000..4cf51754ea
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyKeyNameAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyKeyNameAttribute : Attribute
+ {
+ public AssemblyKeyNameAttribute(string keyName)
+ {
+ KeyName = keyName;
+ }
+
+ public string KeyName { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyMetadataAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyMetadataAttribute.cs
new file mode 100644
index 0000000000..de9f6351ec
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyMetadataAttribute.cs
@@ -0,0 +1,21 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
+ public sealed class AssemblyMetadataAttribute : Attribute
+ {
+ public AssemblyMetadataAttribute(string key, string value)
+ {
+ Key = key;
+ Value = value;
+ }
+
+ public string Key { get; }
+
+ public string Value { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyNameFlags.cs b/src/mscorlib/shared/System/Reflection/AssemblyNameFlags.cs
new file mode 100644
index 0000000000..d321032031
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyNameFlags.cs
@@ -0,0 +1,21 @@
+// 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.
+
+namespace System.Reflection
+{
+ [Flags]
+ public enum AssemblyNameFlags
+ {
+ None = 0x0000,
+ // Flag used to indicate that an assembly ref contains the full public key, not the compressed token.
+ // Must match afPublicKey in CorHdr.h.
+ PublicKey = 0x0001,
+ //ProcArchMask = 0x00F0, // Bits describing the processor architecture
+ // Accessible via AssemblyName.ProcessorArchitecture
+ EnableJITcompileOptimizer = 0x4000,
+ EnableJITcompileTracking = 0x8000,
+ Retargetable = 0x0100,
+ //ContentType = 0x0E00, // Bits describing the ContentType are accessible via AssemblyName.ContentType
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyProductAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyProductAttribute.cs
new file mode 100644
index 0000000000..43cb62df99
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyProductAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyProductAttribute : Attribute
+ {
+ public AssemblyProductAttribute(string product)
+ {
+ Product = product;
+ }
+
+ public string Product { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblySignatureKeyAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblySignatureKeyAttribute.cs
new file mode 100644
index 0000000000..e6ec8af1b3
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblySignatureKeyAttribute.cs
@@ -0,0 +1,21 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)]
+ public sealed class AssemblySignatureKeyAttribute : Attribute
+ {
+ public AssemblySignatureKeyAttribute(string publicKey, string countersignature)
+ {
+ PublicKey = publicKey;
+ Countersignature = countersignature;
+ }
+
+ public string PublicKey { get; }
+
+ public string Countersignature { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyTitleAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyTitleAttribute.cs
new file mode 100644
index 0000000000..26d7a2e66c
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyTitleAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyTitleAttribute : Attribute
+ {
+ public AssemblyTitleAttribute(string title)
+ {
+ Title = title;
+ }
+
+ public string Title { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyTrademarkAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyTrademarkAttribute.cs
new file mode 100644
index 0000000000..1d3edf51d5
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyTrademarkAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyTrademarkAttribute : Attribute
+ {
+ public AssemblyTrademarkAttribute(string trademark)
+ {
+ Trademark = trademark;
+ }
+
+ public string Trademark { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/AssemblyVersionAttribute.cs b/src/mscorlib/shared/System/Reflection/AssemblyVersionAttribute.cs
new file mode 100644
index 0000000000..b3557bac97
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/AssemblyVersionAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class AssemblyVersionAttribute : Attribute
+ {
+ public AssemblyVersionAttribute(string version)
+ {
+ Version = version;
+ }
+
+ public string Version { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/Binder.cs b/src/mscorlib/shared/System/Reflection/Binder.cs
new file mode 100644
index 0000000000..3dc5665d52
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/Binder.cs
@@ -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.Globalization;
+
+namespace System.Reflection
+{
+ public abstract class Binder
+ {
+ protected Binder() { }
+ public abstract FieldInfo BindToField(BindingFlags bindingAttr, FieldInfo[] match, object value, CultureInfo culture);
+ public abstract MethodBase BindToMethod(BindingFlags bindingAttr, MethodBase[] match, ref object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] names, out object state);
+ public abstract object ChangeType(object value, Type type, CultureInfo culture);
+ public abstract void ReorderArgumentArray(ref object[] args, object state);
+ public abstract MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers);
+ public abstract PropertyInfo SelectProperty(BindingFlags bindingAttr, PropertyInfo[] match, Type returnType, Type[] indexes, ParameterModifier[] modifiers);
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/BindingFlags.cs b/src/mscorlib/shared/System/Reflection/BindingFlags.cs
new file mode 100644
index 0000000000..26c875d0f9
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/BindingFlags.cs
@@ -0,0 +1,50 @@
+// 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.
+
+namespace System.Reflection
+{
+ [Flags]
+ public enum BindingFlags
+ {
+ // NOTES: We have lookup masks defined in RuntimeType and Activator. If we
+ // change the lookup values then these masks may need to change also.
+
+ // a place holder for no flag specifed
+ Default = 0x00,
+
+ // These flags indicate what to search for when binding
+ IgnoreCase = 0x01, // Ignore the case of Names while searching
+ DeclaredOnly = 0x02, // Only look at the members declared on the Type
+ Instance = 0x04, // Include Instance members in search
+ Static = 0x08, // Include Static members in search
+ Public = 0x10, // Include Public members in search
+ NonPublic = 0x20, // Include Non-Public members in search
+ FlattenHierarchy = 0x40, // Rollup the statics into the class.
+
+ // These flags are used by InvokeMember to determine
+ // what type of member we are trying to Invoke.
+ // BindingAccess = 0xFF00;
+ InvokeMethod = 0x0100,
+ CreateInstance = 0x0200,
+ GetField = 0x0400,
+ SetField = 0x0800,
+ GetProperty = 0x1000,
+ SetProperty = 0x2000,
+
+ // These flags are also used by InvokeMember but they should only
+ // be used when calling InvokeMember on a COM object.
+ PutDispProperty = 0x4000,
+ PutRefDispProperty = 0x8000,
+
+ ExactBinding = 0x010000, // Bind with Exact Type matching, No Change type
+ SuppressChangeType = 0x020000,
+
+ // DefaultValueBinding will return the set of methods having ArgCount or
+ // more parameters. This is used for default values, etc.
+ OptionalParamBinding = 0x040000,
+
+ // These are a couple of misc attributes used
+ IgnoreReturn = 0x01000000, // This is used in COM Interop
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/CallingConventions.cs b/src/mscorlib/shared/System/Reflection/CallingConventions.cs
new file mode 100644
index 0000000000..bb6d6cd809
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/CallingConventions.cs
@@ -0,0 +1,20 @@
+// 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.
+
+// CallingConventions is a set of Bits representing the calling conventions in the system.
+
+namespace System.Reflection
+{
+ [Flags]
+ public enum CallingConventions
+ {
+ //NOTE: If you change this please update COMMember.cpp. These
+ // are defined there.
+ Standard = 0x0001,
+ VarArgs = 0x0002,
+ Any = Standard | VarArgs,
+ HasThis = 0x0020,
+ ExplicitThis = 0x0040,
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/ConstructorInfo.cs b/src/mscorlib/shared/System/Reflection/ConstructorInfo.cs
new file mode 100644
index 0000000000..3ee1dbf855
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ConstructorInfo.cs
@@ -0,0 +1,40 @@
+// 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.Diagnostics;
+using System.Globalization;
+
+namespace System.Reflection
+{
+ public abstract partial class ConstructorInfo : MethodBase
+ {
+ protected ConstructorInfo() { }
+
+ public override MemberTypes MemberType => MemberTypes.Constructor;
+
+ [DebuggerHidden]
+ [DebuggerStepThrough]
+ public object Invoke(object[] parameters) => Invoke(BindingFlags.Default, binder: null, parameters: parameters, culture: null);
+ public abstract object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture);
+
+ public override bool Equals(object obj) => base.Equals(obj);
+ public override int GetHashCode() => base.GetHashCode();
+
+ public static bool operator ==(ConstructorInfo left, ConstructorInfo right)
+ {
+ if (object.ReferenceEquals(left, right))
+ return true;
+
+ if ((object)left == null || (object)right == null)
+ return false;
+
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(ConstructorInfo left, ConstructorInfo right) => !(left == right);
+
+ public static readonly string ConstructorName = ".ctor";
+ public static readonly string TypeConstructorName = ".cctor";
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/CustomAttributeFormatException.cs b/src/mscorlib/shared/System/Reflection/CustomAttributeFormatException.cs
new file mode 100644
index 0000000000..6e11540505
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/CustomAttributeFormatException.cs
@@ -0,0 +1,33 @@
+// 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.Runtime.Serialization;
+
+namespace System.Reflection
+{
+ [Serializable]
+ public class CustomAttributeFormatException : FormatException
+ {
+ public CustomAttributeFormatException()
+ : this(SR.Arg_CustomAttributeFormatException)
+ {
+ }
+
+ public CustomAttributeFormatException(string message)
+ : this(message, null)
+ {
+ }
+
+ public CustomAttributeFormatException(string message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_CUSTOMATTRIBUTEFORMAT;
+ }
+
+ protected CustomAttributeFormatException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/DefaultMemberAttribute.cs b/src/mscorlib/shared/System/Reflection/DefaultMemberAttribute.cs
new file mode 100644
index 0000000000..3511433713
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/DefaultMemberAttribute.cs
@@ -0,0 +1,22 @@
+// 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.
+
+namespace System.Reflection
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface)]
+ public sealed class DefaultMemberAttribute : Attribute
+ {
+ // You must provide the name of the member, this is required
+ public DefaultMemberAttribute(string memberName)
+ {
+ MemberName = memberName;
+ }
+
+ // A get accessor to return the name from the attribute.
+ // NOTE: There is no setter because the name must be provided
+ // to the constructor. The name is not optional.
+ public string MemberName { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/EventAttributes.cs b/src/mscorlib/shared/System/Reflection/EventAttributes.cs
new file mode 100644
index 0000000000..fbc2972f69
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/EventAttributes.cs
@@ -0,0 +1,22 @@
+// 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.
+
+// EventAttributes are an enum defining the attributes associated with and Event.
+// These are defined in CorHdr.h and are a combination of bits and enums.
+
+namespace System.Reflection
+{
+ [Flags]
+ public enum EventAttributes
+ {
+ None = 0x0000,
+
+ // This Enum matchs the CorEventAttr defined in CorHdr.h
+ SpecialName = 0x0200, // event is special. Name describes how.
+
+ RTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding.
+
+ ReservedMask = 0x0400,
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/EventInfo.cs b/src/mscorlib/shared/System/Reflection/EventInfo.cs
new file mode 100644
index 0000000000..ccd9acf648
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/EventInfo.cs
@@ -0,0 +1,115 @@
+// 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.Diagnostics;
+
+#if FEATURE_COMINTEROP
+using EventRegistrationToken = System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken;
+#endif //#if FEATURE_COMINTEROP
+
+namespace System.Reflection
+{
+ public abstract class EventInfo : MemberInfo
+ {
+ protected EventInfo() { }
+
+ public override MemberTypes MemberType => MemberTypes.Event;
+
+ public abstract EventAttributes Attributes { get; }
+ public bool IsSpecialName => (Attributes & EventAttributes.SpecialName) != 0;
+
+ public MethodInfo[] GetOtherMethods() => GetOtherMethods(nonPublic: false);
+ public virtual MethodInfo[] GetOtherMethods(bool nonPublic) { throw NotImplemented.ByDesign; }
+
+ public virtual MethodInfo AddMethod => GetAddMethod(nonPublic: true);
+ public virtual MethodInfo RemoveMethod => GetRemoveMethod(nonPublic: true);
+ public virtual MethodInfo RaiseMethod => GetRaiseMethod(nonPublic: true);
+
+ public MethodInfo GetAddMethod() => GetAddMethod(nonPublic: false);
+ public MethodInfo GetRemoveMethod() => GetRemoveMethod(nonPublic: false);
+ public MethodInfo GetRaiseMethod() => GetRaiseMethod(nonPublic: false);
+
+ public abstract MethodInfo GetAddMethod(bool nonPublic);
+ public abstract MethodInfo GetRemoveMethod(bool nonPublic);
+ public abstract MethodInfo GetRaiseMethod(bool nonPublic);
+
+ public virtual bool IsMulticast
+ {
+ get
+ {
+ Type cl = EventHandlerType;
+ Type mc = typeof(MulticastDelegate);
+ return mc.IsAssignableFrom(cl);
+ }
+ }
+
+ public virtual Type EventHandlerType
+ {
+ get
+ {
+ MethodInfo m = GetAddMethod(true);
+ ParameterInfo[] p = m.GetParametersNoCopy();
+ Type del = typeof(Delegate);
+ for (int i = 0; i < p.Length; i++)
+ {
+ Type c = p[i].ParameterType;
+ if (c.IsSubclassOf(del))
+ return c;
+ }
+ return null;
+ }
+ }
+
+ [DebuggerHidden]
+ [DebuggerStepThrough]
+ public virtual void AddEventHandler(object target, Delegate handler)
+ {
+ MethodInfo addMethod = GetAddMethod(nonPublic: false);
+
+ if (addMethod == null)
+ throw new InvalidOperationException(SR.InvalidOperation_NoPublicAddMethod);
+
+#if FEATURE_COMINTEROP
+ if (addMethod.ReturnType == typeof(EventRegistrationToken))
+ throw new InvalidOperationException(SR.InvalidOperation_NotSupportedOnWinRTEvent);
+#endif //#if FEATURE_COMINTEROP
+
+ addMethod.Invoke(target, new object[] { handler });
+ }
+
+ [DebuggerHidden]
+ [DebuggerStepThrough]
+ public virtual void RemoveEventHandler(object target, Delegate handler)
+ {
+ MethodInfo removeMethod = GetRemoveMethod(nonPublic: false);
+
+ if (removeMethod == null)
+ throw new InvalidOperationException(SR.InvalidOperation_NoPublicRemoveMethod);
+
+#if FEATURE_COMINTEROP
+ ParameterInfo[] parameters = removeMethod.GetParametersNoCopy();
+ if (parameters[0].ParameterType == typeof(EventRegistrationToken))
+ throw new InvalidOperationException(SR.InvalidOperation_NotSupportedOnWinRTEvent);
+#endif //#if FEATURE_COMINTEROP
+
+ removeMethod.Invoke(target, new object[] { handler });
+ }
+
+ public override bool Equals(object obj) => base.Equals(obj);
+ public override int GetHashCode() => base.GetHashCode();
+
+ public static bool operator ==(EventInfo left, EventInfo right)
+ {
+ if (object.ReferenceEquals(left, right))
+ return true;
+
+ if ((object)left == null || (object)right == null)
+ return false;
+
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(EventInfo left, EventInfo right) => !(left == right);
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/ExceptionHandlingClauseOptions.cs b/src/mscorlib/shared/System/Reflection/ExceptionHandlingClauseOptions.cs
new file mode 100644
index 0000000000..46285f7c82
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ExceptionHandlingClauseOptions.cs
@@ -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.
+
+namespace System.Reflection
+{
+ [Flags]
+ public enum ExceptionHandlingClauseOptions : int
+ {
+ Clause = 0x0,
+ Filter = 0x1,
+ Finally = 0x2,
+ Fault = 0x4,
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/FieldAttributes.cs b/src/mscorlib/shared/System/Reflection/FieldAttributes.cs
new file mode 100644
index 0000000000..048d0e7031
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/FieldAttributes.cs
@@ -0,0 +1,40 @@
+// 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.
+
+namespace System.Reflection
+{
+ // This Enum matchs the CorFieldAttr defined in CorHdr.h
+ [Flags]
+ public enum FieldAttributes
+ {
+ // member access mask - Use this mask to retrieve accessibility information.
+ FieldAccessMask = 0x0007,
+ PrivateScope = 0x0000, // Member not referenceable.
+ Private = 0x0001, // Accessible only by the parent type.
+ FamANDAssem = 0x0002, // Accessible by sub-types only in this Assembly.
+ Assembly = 0x0003, // Accessibly by anyone in the Assembly.
+ Family = 0x0004, // Accessible only by type and sub-types.
+ FamORAssem = 0x0005, // Accessibly by sub-types anywhere, plus anyone in assembly.
+ Public = 0x0006, // Accessibly by anyone who has visibility to this scope.
+ // end member access mask
+
+ // field contract attributes.
+ Static = 0x0010, // Defined on type, else per instance.
+ InitOnly = 0x0020, // Field may only be initialized, not written to after init.
+ Literal = 0x0040, // Value is compile time constant.
+ NotSerialized = 0x0080, // Field does not have to be serialized when type is remoted.
+
+ SpecialName = 0x0200, // field is special. Name describes how.
+
+ // interop attributes
+ PinvokeImpl = 0x2000, // Implementation is forwarded through pinvoke.
+
+ RTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding.
+ HasFieldMarshal = 0x1000, // Field has marshalling information.
+ HasDefault = 0x8000, // Field has default.
+ HasFieldRVA = 0x0100, // Field has RVA.
+
+ ReservedMask = 0x9500,
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/FieldInfo.cs b/src/mscorlib/shared/System/Reflection/FieldInfo.cs
new file mode 100644
index 0000000000..0863c2b019
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/FieldInfo.cs
@@ -0,0 +1,72 @@
+// 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.Diagnostics;
+using System.Globalization;
+
+namespace System.Reflection
+{
+ public abstract partial class FieldInfo : MemberInfo
+ {
+ protected FieldInfo() { }
+
+ public override MemberTypes MemberType => MemberTypes.Field;
+
+ public abstract FieldAttributes Attributes { get; }
+ public abstract Type FieldType { get; }
+
+ public bool IsInitOnly => (Attributes & FieldAttributes.InitOnly) != 0;
+ public bool IsLiteral => (Attributes & FieldAttributes.Literal) != 0;
+ public bool IsNotSerialized => (Attributes & FieldAttributes.NotSerialized) != 0;
+ public bool IsPinvokeImpl => (Attributes & FieldAttributes.PinvokeImpl) != 0;
+ public bool IsSpecialName => (Attributes & FieldAttributes.SpecialName) != 0;
+ public bool IsStatic => (Attributes & FieldAttributes.Static) != 0;
+
+ public bool IsAssembly => (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Assembly;
+ public bool IsFamily => (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Family;
+ public bool IsFamilyAndAssembly => (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamANDAssem;
+ public bool IsFamilyOrAssembly => (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamORAssem;
+ public bool IsPrivate => (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Private;
+ public bool IsPublic => (Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public;
+
+ public virtual bool IsSecurityCritical => true;
+ public virtual bool IsSecuritySafeCritical => false;
+ public virtual bool IsSecurityTransparent => false;
+
+ public abstract RuntimeFieldHandle FieldHandle { get; }
+
+ public override bool Equals(object obj) => base.Equals(obj);
+ public override int GetHashCode() => base.GetHashCode();
+
+ public static bool operator ==(FieldInfo left, FieldInfo right)
+ {
+ if (object.ReferenceEquals(left, right))
+ return true;
+
+ if ((object)left == null || (object)right == null)
+ return false;
+
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(FieldInfo left, FieldInfo right) => !(left == right);
+
+ public abstract object GetValue(object obj);
+
+ [DebuggerHidden]
+ [DebuggerStepThrough]
+ public void SetValue(object obj, object value) => SetValue(obj, value, BindingFlags.Default, Type.DefaultBinder, null);
+ public abstract void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture);
+
+ [CLSCompliant(false)]
+ public virtual void SetValueDirect(TypedReference obj, object value) { throw new NotSupportedException(SR.NotSupported_AbstractNonCLS); }
+ [CLSCompliant(false)]
+ public virtual object GetValueDirect(TypedReference obj) { throw new NotSupportedException(SR.NotSupported_AbstractNonCLS); }
+
+ public virtual object GetRawConstantValue() { throw new NotSupportedException(SR.NotSupported_AbstractNonCLS); }
+
+ public virtual Type[] GetOptionalCustomModifiers() { throw NotImplemented.ByDesign; }
+ public virtual Type[] GetRequiredCustomModifiers() { throw NotImplemented.ByDesign; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/GenericParameterAttributes.cs b/src/mscorlib/shared/System/Reflection/GenericParameterAttributes.cs
new file mode 100644
index 0000000000..4b579d273e
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/GenericParameterAttributes.cs
@@ -0,0 +1,20 @@
+// 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.
+
+namespace System.Reflection
+{
+ [Flags]
+ public enum GenericParameterAttributes
+ {
+ None = 0x0000,
+ VarianceMask = 0x0003,
+ Covariant = 0x0001,
+ Contravariant = 0x0002,
+ SpecialConstraintMask = 0x001C,
+ ReferenceTypeConstraint = 0x0004,
+ NotNullableValueTypeConstraint = 0x0008,
+ DefaultConstructorConstraint = 0x0010,
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/ICustomAttributeProvider.cs b/src/mscorlib/shared/System/Reflection/ICustomAttributeProvider.cs
new file mode 100644
index 0000000000..3cae295bc4
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ICustomAttributeProvider.cs
@@ -0,0 +1,13 @@
+// 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.
+
+namespace System.Reflection
+{
+ public interface ICustomAttributeProvider
+ {
+ object[] GetCustomAttributes(bool inherit);
+ object[] GetCustomAttributes(Type attributeType, bool inherit);
+ bool IsDefined(Type attributeType, bool inherit);
+ }
+} \ No newline at end of file
diff --git a/src/mscorlib/shared/System/Reflection/IReflect.cs b/src/mscorlib/shared/System/Reflection/IReflect.cs
new file mode 100644
index 0000000000..51141ae47c
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/IReflect.cs
@@ -0,0 +1,76 @@
+// 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.Globalization;
+
+namespace System.Reflection
+{
+ public interface IReflect
+ {
+ // Return the requested method if it is implemented by the Reflection object. The
+ // match is based upon the name and DescriptorInfo which describes the signature
+ // of the method.
+ MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers);
+
+ // Return the requested method if it is implemented by the Reflection object. The
+ // match is based upon the name of the method. If the object implementes multiple methods
+ // with the same name an AmbiguousMatchException is thrown.
+ MethodInfo GetMethod(string name, BindingFlags bindingAttr);
+
+ MethodInfo[] GetMethods(BindingFlags bindingAttr);
+
+ // Return the requestion field if it is implemented by the Reflection object. The
+ // match is based upon a name. There cannot be more than a single field with
+ // a name.
+ FieldInfo GetField(string name, BindingFlags bindingAttr);
+
+ FieldInfo[] GetFields(BindingFlags bindingAttr);
+
+ // Return the property based upon name. If more than one property has the given
+ // name an AmbiguousMatchException will be thrown. Returns null if no property
+ // is found.
+ PropertyInfo GetProperty(string name, BindingFlags bindingAttr);
+
+ // Return the property based upon the name and Descriptor info describing the property
+ // indexing. Return null if no property is found.
+ PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers);
+
+ // Returns an array of PropertyInfos for all the properties defined on
+ // the Reflection object.
+ PropertyInfo[] GetProperties(BindingFlags bindingAttr);
+
+ // Return an array of members which match the passed in name.
+ MemberInfo[] GetMember(string name, BindingFlags bindingAttr);
+
+ // Return an array of all of the members defined for this object.
+ MemberInfo[] GetMembers(BindingFlags bindingAttr);
+
+ // Description of the Binding Process.
+ // We must invoke a method that is accessable and for which the provided
+ // parameters have the most specific match. A method may be called if
+ // 1. The number of parameters in the method declaration equals the number of
+ // arguments provided to the invocation
+ // 2. The type of each argument can be converted by the binder to the
+ // type of the type of the parameter.
+ //
+ // The binder will find all of the matching methods. These method are found based
+ // upon the type of binding requested (MethodInvoke, Get/Set Properties). The set
+ // of methods is filtered by the name, number of arguments and a set of search modifiers
+ // defined in the Binder.
+ //
+ // After the method is selected, it will be invoked. Accessability is checked
+ // at that point. The search may be control which set of methods are searched based
+ // upon the accessibility attribute associated with the method.
+ //
+ // The BindToMethod method is responsible for selecting the method to be invoked.
+ // For the default binder, the most specific method will be selected.
+ //
+ // This will invoke a specific member...
+ object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters);
+
+ // Return the underlying Type that represents the IReflect Object. For expando object,
+ // this is the (Object) IReflectInstance.GetType(). For Type object it is this.
+ Type UnderlyingSystemType { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/IReflectableType.cs b/src/mscorlib/shared/System/Reflection/IReflectableType.cs
new file mode 100644
index 0000000000..5e2c0edab4
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/IReflectableType.cs
@@ -0,0 +1,12 @@
+// 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.
+
+namespace System.Reflection
+{
+ public interface IReflectableType
+ {
+ TypeInfo GetTypeInfo();
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/ImageFileMachine.cs b/src/mscorlib/shared/System/Reflection/ImageFileMachine.cs
new file mode 100644
index 0000000000..230bc952e5
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ImageFileMachine.cs
@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Reflection
+{
+ public enum ImageFileMachine
+ {
+ I386 = 0x014c,
+ IA64 = 0x0200,
+ AMD64 = 0x8664,
+ ARM = 0x01c4,
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/InterfaceMapping.cs b/src/mscorlib/shared/System/Reflection/InterfaceMapping.cs
new file mode 100644
index 0000000000..2e0c0d8a28
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/InterfaceMapping.cs
@@ -0,0 +1,14 @@
+// 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.
+
+namespace System.Reflection
+{
+ public struct InterfaceMapping
+ {
+ public Type TargetType; // The type implementing the interface
+ public Type InterfaceType; // The type representing the interface
+ public MethodInfo[] TargetMethods; // The methods implementing the interface
+ public MethodInfo[] InterfaceMethods; // The methods defined on the interface
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/IntrospectionExtensions.cs b/src/mscorlib/shared/System/Reflection/IntrospectionExtensions.cs
new file mode 100644
index 0000000000..6a18fdaa72
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/IntrospectionExtensions.cs
@@ -0,0 +1,20 @@
+// 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.Diagnostics;
+
+namespace System.Reflection
+{
+ public static class IntrospectionExtensions
+ {
+ public static TypeInfo GetTypeInfo(this Type type)
+ {
+ if (type == null)
+ throw new ArgumentNullException(nameof(type));
+
+ return ((IReflectableType)type).GetTypeInfo(); // Unguarded cast is unbecoming but kept for compatibility.
+ }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/InvalidFilterCriteriaException.cs b/src/mscorlib/shared/System/Reflection/InvalidFilterCriteriaException.cs
new file mode 100644
index 0000000000..e3f882c409
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/InvalidFilterCriteriaException.cs
@@ -0,0 +1,33 @@
+// 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.Runtime.Serialization;
+
+namespace System.Reflection
+{
+ [Serializable]
+ public class InvalidFilterCriteriaException : ApplicationException
+ {
+ public InvalidFilterCriteriaException()
+ : this(SR.Arg_InvalidFilterCriteriaException)
+ {
+ }
+
+ public InvalidFilterCriteriaException(string message)
+ : this(message, null)
+ {
+ }
+
+ public InvalidFilterCriteriaException(string message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_INVALIDFILTERCRITERIA;
+ }
+
+ protected InvalidFilterCriteriaException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/ManifestResourceInfo.cs b/src/mscorlib/shared/System/Reflection/ManifestResourceInfo.cs
new file mode 100644
index 0000000000..b9c56ab857
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ManifestResourceInfo.cs
@@ -0,0 +1,23 @@
+// 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.
+
+namespace System.Reflection
+{
+ public class ManifestResourceInfo
+ {
+ public ManifestResourceInfo(Assembly containingAssembly,
+ string containingFileName,
+ ResourceLocation resourceLocation)
+ {
+ ReferencedAssembly = containingAssembly;
+ FileName = containingFileName;
+ ResourceLocation = resourceLocation;
+ }
+
+ public virtual Assembly ReferencedAssembly { get; }
+ public virtual string FileName { get; }
+ public virtual ResourceLocation ResourceLocation { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/MemberFilter.cs b/src/mscorlib/shared/System/Reflection/MemberFilter.cs
new file mode 100644
index 0000000000..bb1b15796a
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/MemberFilter.cs
@@ -0,0 +1,8 @@
+// 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.
+
+namespace System.Reflection
+{
+ public delegate bool MemberFilter(MemberInfo m, object filterCriteria);
+} \ No newline at end of file
diff --git a/src/mscorlib/shared/System/Reflection/MemberInfo.cs b/src/mscorlib/shared/System/Reflection/MemberInfo.cs
new file mode 100644
index 0000000000..1275cc15a0
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/MemberInfo.cs
@@ -0,0 +1,75 @@
+// 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.Collections.Generic;
+
+namespace System.Reflection
+{
+ public abstract partial class MemberInfo : ICustomAttributeProvider
+ {
+ protected MemberInfo() { }
+
+ public abstract MemberTypes MemberType { get; }
+ public abstract string Name { get; }
+ public abstract Type DeclaringType { get; }
+ public abstract Type ReflectedType { get; }
+
+ public virtual Module Module
+ {
+ get
+ {
+ // This check is necessary because for some reason, Type adds a new "Module" property that hides the inherited one instead
+ // of overriding.
+
+ Type type = this as Type;
+ if (type != null)
+ return type.Module;
+
+ throw NotImplemented.ByDesign;
+ }
+ }
+
+ public abstract bool IsDefined(Type attributeType, bool inherit);
+ public abstract object[] GetCustomAttributes(bool inherit);
+ public abstract object[] GetCustomAttributes(Type attributeType, bool inherit);
+
+ public virtual IEnumerable<CustomAttributeData> CustomAttributes => GetCustomAttributesData();
+ public virtual IList<CustomAttributeData> GetCustomAttributesData() { throw NotImplemented.ByDesign; }
+
+ public virtual int MetadataToken { get { throw new InvalidOperationException(); } }
+
+ public override bool Equals(object obj) => base.Equals(obj);
+ public override int GetHashCode() => base.GetHashCode();
+
+ public static bool operator ==(MemberInfo left, MemberInfo right)
+ {
+ if (object.ReferenceEquals(left, right))
+ return true;
+
+ if ((object)left == null || (object)right == null)
+ return false;
+
+ Type type1, type2;
+ MethodBase method1, method2;
+ FieldInfo field1, field2;
+ EventInfo event1, event2;
+ PropertyInfo property1, property2;
+
+ if ((type1 = left as Type) != null && (type2 = right as Type) != null)
+ return type1 == type2;
+ else if ((method1 = left as MethodBase) != null && (method2 = right as MethodBase) != null)
+ return method1 == method2;
+ else if ((field1 = left as FieldInfo) != null && (field2 = right as FieldInfo) != null)
+ return field1 == field2;
+ else if ((event1 = left as EventInfo) != null && (event2 = right as EventInfo) != null)
+ return event1 == event2;
+ else if ((property1 = left as PropertyInfo) != null && (property2 = right as PropertyInfo) != null)
+ return property1 == property2;
+
+ return false;
+ }
+
+ public static bool operator !=(MemberInfo left, MemberInfo right) => !(left == right);
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/MemberInfoSerializationHolder.cs b/src/mscorlib/shared/System/Reflection/MemberInfoSerializationHolder.cs
new file mode 100644
index 0000000000..dfc56667bd
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/MemberInfoSerializationHolder.cs
@@ -0,0 +1,315 @@
+// 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.Serialization;
+using System.Globalization;
+using System.Diagnostics.Contracts;
+
+namespace System.Reflection
+{
+ [Serializable]
+#if CORECLR
+ internal
+#else
+ public // On CoreRT, this must be public because of the Reflection.Core/CoreLib divide and the need to whitelist past the ReflectionBlock.
+#endif
+ class MemberInfoSerializationHolder : ISerializable, IObjectReference
+ {
+ #region Staitc Public Members
+ public static void GetSerializationInfo(SerializationInfo info, FieldInfo f)
+ {
+ // Compat: Serializing ToString() since the full framework does it but the deserialization logic makes no use of it.
+ GetSerializationInfo(info, f.Name, f.ReflectedType, f.ToString(), MemberTypes.Field);
+ }
+
+ public static void GetSerializationInfo(SerializationInfo info, EventInfo e)
+ {
+ GetSerializationInfo(info, e.Name, e.ReflectedType, null, MemberTypes.Event);
+ }
+
+ public static void GetSerializationInfo(SerializationInfo info, ConstructorInfo c)
+ {
+ GetSerializationInfo(info, c.Name, c.ReflectedType, c.ToString(), c.SerializationToString(), MemberTypes.Constructor, genericArguments: null);
+ }
+
+ public static void GetSerializationInfo(SerializationInfo info, MethodInfo m)
+ {
+ Type[] genericArguments = m.IsConstructedGenericMethod ? m.GetGenericArguments() : null;
+ GetSerializationInfo(info, m.Name, m.ReflectedType, m.ToString(), m.SerializationToString(), MemberTypes.Method, genericArguments);
+ }
+
+ public static void GetSerializationInfo(SerializationInfo info, PropertyInfo p)
+ {
+ GetSerializationInfo(info, p.Name, p.ReflectedType, p.ToString(), p.SerializationToString(), MemberTypes.Property, genericArguments: null);
+ }
+ #endregion
+
+ #region Private Static Members
+ private static void GetSerializationInfo(SerializationInfo info, string name, Type reflectedClass, string signature, MemberTypes type)
+ {
+ GetSerializationInfo(info, name, reflectedClass, signature, null, type, null);
+ }
+
+ private static void GetSerializationInfo(
+ SerializationInfo info,
+ string name,
+ Type reflectedClass,
+ string signature,
+ string signature2,
+ MemberTypes type,
+ Type[] genericArguments)
+ {
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ string assemblyName = reflectedClass.Module.Assembly.FullName;
+ string typeName = reflectedClass.FullName;
+
+ info.SetType(typeof(MemberInfoSerializationHolder));
+ info.AddValue("Name", name, typeof(string));
+ info.AddValue("AssemblyName", assemblyName, typeof(string));
+ info.AddValue("ClassName", typeName, typeof(string));
+ info.AddValue("Signature", signature, typeof(string));
+ info.AddValue("Signature2", signature2, typeof(string));
+ info.AddValue("MemberType", (int)type);
+ info.AddValue("GenericArguments", genericArguments, typeof(Type[]));
+ }
+ #endregion
+
+ #region Private Data Members
+ private readonly string _memberName;
+ private readonly Type _reflectedType;
+ // _signature stores the ToString() representation of the member which is sometimes ambiguous.
+ // Mulitple overloads of the same methods or properties can identical ToString().
+ // _signature2 stores the SerializationToString() representation which should be unique for each member.
+ // It is only written and used by post 4.0 CLR versions.
+ private readonly string _signature;
+ private readonly string _signature2;
+ private readonly MemberTypes _memberType;
+ private readonly SerializationInfo _info;
+ #endregion
+
+ #region Constructor
+ // Needs to be public so it can be whitelisted in Reflection.
+ public MemberInfoSerializationHolder(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ string assemblyName = info.GetString("AssemblyName");
+ string typeName = info.GetString("ClassName");
+
+ if (assemblyName == null || typeName == null)
+ throw new SerializationException(SR.Serialization_InsufficientState);
+
+ Assembly assem = Assembly.Load(assemblyName);
+ _reflectedType = assem.GetType(typeName, true, false);
+ _memberName = info.GetString("Name");
+ _signature = info.GetString("Signature");
+ // Only v4.0 and later generates and consumes Signature2
+ _signature2 = (string)info.GetValueNoThrow("Signature2", typeof(string));
+ _memberType = (MemberTypes)info.GetInt32("MemberType");
+ _info = info;
+ }
+ #endregion
+
+ #region ISerializable
+ public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ throw new NotSupportedException();
+ }
+ #endregion
+
+ #region IObjectReference
+ public virtual object GetRealObject(StreamingContext context)
+ {
+ if (_memberName == null || _reflectedType == null || _memberType == 0)
+ throw new SerializationException(SR.Serialization_InsufficientState);
+
+ BindingFlags bindingFlags =
+ BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic |
+ BindingFlags.Static | BindingFlags.OptionalParamBinding;
+
+ switch (_memberType)
+ {
+ #region case MemberTypes.Field:
+ case MemberTypes.Field:
+ {
+ FieldInfo[] fields = _reflectedType.GetMember(_memberName, MemberTypes.Field, bindingFlags) as FieldInfo[];
+
+ if (fields.Length == 0)
+ throw new SerializationException(SR.Format(SR.Serialization_UnknownMember, _memberName));
+
+ return fields[0];
+ }
+ #endregion
+
+ #region case MemberTypes.Event:
+ case MemberTypes.Event:
+ {
+ EventInfo[] events = _reflectedType.GetMember(_memberName, MemberTypes.Event, bindingFlags) as EventInfo[];
+
+ if (events.Length == 0)
+ throw new SerializationException(SR.Format(SR.Serialization_UnknownMember, _memberName));
+
+ return events[0];
+ }
+ #endregion
+
+ #region case MemberTypes.Property:
+ case MemberTypes.Property:
+ {
+ PropertyInfo[] properties = _reflectedType.GetMember(_memberName, MemberTypes.Property, bindingFlags) as PropertyInfo[];
+
+ if (properties.Length == 0)
+ throw new SerializationException(SR.Format(SR.Serialization_UnknownMember, _memberName));
+
+ if (properties.Length == 1)
+ return properties[0];
+
+ if (properties.Length > 1)
+ {
+ for (int i = 0; i < properties.Length; i++)
+ {
+ if (_signature2 != null)
+ {
+ if (properties[i].SerializationToString().Equals(_signature2))
+ return properties[i];
+ }
+ else
+ {
+ if ((properties[i]).ToString().Equals(_signature))
+ return properties[i];
+ }
+ }
+ }
+
+ throw new SerializationException(SR.Format(SR.Serialization_UnknownMember, _memberName));
+ }
+ #endregion
+
+ #region case MemberTypes.Constructor:
+ case MemberTypes.Constructor:
+ {
+ if (_signature == null)
+ throw new SerializationException(SR.Serialization_NullSignature);
+
+ ConstructorInfo[] constructors = _reflectedType.GetMember(_memberName, MemberTypes.Constructor, bindingFlags) as ConstructorInfo[];
+
+ if (constructors.Length == 1)
+ return constructors[0];
+
+ if (constructors.Length > 1)
+ {
+ for (int i = 0; i < constructors.Length; i++)
+ {
+ if (_signature2 != null)
+ {
+ if (constructors[i].SerializationToString().Equals(_signature2))
+ return constructors[i];
+ }
+ else
+ {
+ if (constructors[i].ToString().Equals(_signature))
+ return constructors[i];
+ }
+ }
+ }
+
+ throw new SerializationException(SR.Format(SR.Serialization_UnknownMember, _memberName));
+ }
+ #endregion
+
+ #region case MemberTypes.Method:
+ case MemberTypes.Method:
+ {
+ MethodInfo methodInfo = null;
+
+ if (_signature == null)
+ throw new SerializationException(SR.Serialization_NullSignature);
+
+ Type[] genericArguments = _info.GetValueNoThrow("GenericArguments", typeof(Type[])) as Type[];
+
+ MethodInfo[] methods = _reflectedType.GetMember(_memberName, MemberTypes.Method, bindingFlags) as MethodInfo[];
+
+ if (methods.Length == 1)
+ methodInfo = methods[0];
+
+ else if (methods.Length > 1)
+ {
+ for (int i = 0; i < methods.Length; i++)
+ {
+ if (_signature2 != null)
+ {
+ if (methods[i].SerializationToString().Equals(_signature2))
+ {
+ methodInfo = methods[i];
+ break;
+ }
+ }
+ else
+ {
+ if (methods[i].ToString().Equals(_signature))
+ {
+ methodInfo = methods[i];
+ break;
+ }
+ }
+
+ // Handle generic methods specially since the signature match above probably won't work (the candidate
+ // method info hasn't been instantiated). If our target method is generic as well we can skip this.
+ if (genericArguments != null && methods[i].IsGenericMethod)
+ {
+ if (methods[i].GetGenericArguments().Length == genericArguments.Length)
+ {
+ MethodInfo candidateMethod = methods[i].MakeGenericMethod(genericArguments);
+
+ if (_signature2 != null)
+ {
+ if (candidateMethod.SerializationToString().Equals(_signature2))
+ {
+ methodInfo = candidateMethod;
+ break;
+ }
+ }
+ else
+ {
+ if (candidateMethod.ToString().Equals(_signature))
+ {
+ methodInfo = candidateMethod;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (methodInfo == null)
+ throw new SerializationException(SR.Format(SR.Serialization_UnknownMember, _memberName));
+
+ if (!methodInfo.IsGenericMethodDefinition)
+ return methodInfo;
+
+ if (genericArguments == null)
+ return methodInfo;
+
+ if (genericArguments[0] == null)
+ return null;
+
+ return methodInfo.MakeGenericMethod(genericArguments);
+ }
+ #endregion
+
+ default:
+ throw new ArgumentException(SR.Serialization_MemberTypeNotRecognized);
+ }
+ }
+ #endregion
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/MemberTypes.cs b/src/mscorlib/shared/System/Reflection/MemberTypes.cs
new file mode 100644
index 0000000000..57072dcfbe
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/MemberTypes.cs
@@ -0,0 +1,20 @@
+// 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.
+
+namespace System.Reflection
+{
+ [Flags]
+ public enum MemberTypes
+ {
+ Constructor = 0x01,
+ Event = 0x02,
+ Field = 0x04,
+ Method = 0x08,
+ Property = 0x10,
+ TypeInfo = 0x20,
+ Custom = 0x40,
+ NestedType = 0x80,
+ All = Constructor | Event | Field | Method | Property | TypeInfo | NestedType,
+ }
+} \ No newline at end of file
diff --git a/src/mscorlib/shared/System/Reflection/MethodAttributes.cs b/src/mscorlib/shared/System/Reflection/MethodAttributes.cs
new file mode 100644
index 0000000000..1a7c7bf154
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/MethodAttributes.cs
@@ -0,0 +1,50 @@
+// 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.
+
+namespace System.Reflection
+{
+ [Flags]
+ public enum MethodAttributes
+ {
+ // NOTE: This Enum matchs the CorMethodAttr defined in CorHdr.h
+
+ // member access mask - Use this mask to retrieve accessibility information.
+ MemberAccessMask = 0x0007,
+ PrivateScope = 0x0000, // Member not referenceable.
+ Private = 0x0001, // Accessible only by the parent type.
+ FamANDAssem = 0x0002, // Accessible by sub-types only in this Assembly.
+ Assembly = 0x0003, // Accessibly by anyone in the Assembly.
+ Family = 0x0004, // Accessible only by type and sub-types.
+ FamORAssem = 0x0005, // Accessibly by sub-types anywhere, plus anyone in assembly.
+ Public = 0x0006, // Accessibly by anyone who has visibility to this scope.
+ // end member access mask
+
+ // method contract attributes.
+ Static = 0x0010, // Defined on type, else per instance.
+ Final = 0x0020, // Method may not be overridden.
+ Virtual = 0x0040, // Method virtual.
+ HideBySig = 0x0080, // Method hides by name+sig, else just by name.
+ CheckAccessOnOverride = 0x0200,
+
+ // vtable layout mask - Use this mask to retrieve vtable attributes.
+ VtableLayoutMask = 0x0100,
+ ReuseSlot = 0x0000, // The default.
+ NewSlot = 0x0100, // Method always gets a new slot in the vtable.
+ // end vtable layout mask
+
+ // method implementation attributes.
+ Abstract = 0x0400, // Method does not provide an implementation.
+ SpecialName = 0x0800, // Method is special. Name describes how.
+
+ // interop attributes
+ PinvokeImpl = 0x2000, // Implementation is forwarded through pinvoke.
+ UnmanagedExport = 0x0008, // Managed method exported via thunk to unmanaged code.
+ RTSpecialName = 0x1000, // Runtime should check name encoding.
+
+ HasSecurity = 0x4000, // Method has security associate with it.
+ RequireSecObject = 0x8000, // Method calls another method containing security code.
+
+ ReservedMask = 0xd000,
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/MethodBase.cs b/src/mscorlib/shared/System/Reflection/MethodBase.cs
new file mode 100644
index 0000000000..0037c74f4c
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/MethodBase.cs
@@ -0,0 +1,86 @@
+// 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.Globalization;
+using System.Diagnostics;
+
+namespace System.Reflection
+{
+ public abstract partial class MethodBase : MemberInfo
+ {
+ protected MethodBase() { }
+
+ public abstract ParameterInfo[] GetParameters();
+ public abstract MethodAttributes Attributes { get; }
+ public virtual MethodImplAttributes MethodImplementationFlags => GetMethodImplementationFlags();
+ public abstract MethodImplAttributes GetMethodImplementationFlags();
+ public virtual MethodBody GetMethodBody() { throw new InvalidOperationException(); }
+ public virtual CallingConventions CallingConvention => CallingConventions.Standard;
+
+ public bool IsAbstract => (Attributes & MethodAttributes.Abstract) != 0;
+ public bool IsConstructor
+ {
+ get
+ {
+ // To be backward compatible we only return true for instance RTSpecialName ctors.
+ return (this is ConstructorInfo &&
+ !IsStatic &&
+ ((Attributes & MethodAttributes.RTSpecialName) == MethodAttributes.RTSpecialName));
+ }
+ }
+ public bool IsFinal => (Attributes & MethodAttributes.Final) != 0;
+ public bool IsHideBySig => (Attributes & MethodAttributes.HideBySig) != 0;
+ public bool IsSpecialName => (Attributes & MethodAttributes.SpecialName) != 0;
+ public bool IsStatic => (Attributes & MethodAttributes.Static) != 0;
+ public bool IsVirtual => (Attributes & MethodAttributes.Virtual) != 0;
+
+ public bool IsAssembly => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly;
+ public bool IsFamily => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family;
+ public bool IsFamilyAndAssembly => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem;
+ public bool IsFamilyOrAssembly => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem;
+ public bool IsPrivate => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;
+ public bool IsPublic => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
+
+ public virtual bool IsConstructedGenericMethod => IsGenericMethod && !IsGenericMethodDefinition;
+ public virtual bool IsGenericMethod => false;
+ public virtual bool IsGenericMethodDefinition => false;
+ public virtual Type[] GetGenericArguments() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+ public virtual bool ContainsGenericParameters => false;
+
+ [DebuggerHidden]
+ [DebuggerStepThrough]
+ public object Invoke(object obj, object[] parameters) => Invoke(obj, BindingFlags.Default, binder: null, parameters: parameters, culture: null);
+ public abstract object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture);
+
+ public abstract RuntimeMethodHandle MethodHandle { get; }
+
+ public virtual bool IsSecurityCritical { get { throw NotImplemented.ByDesign; } }
+ public virtual bool IsSecuritySafeCritical { get { throw NotImplemented.ByDesign; } }
+ public virtual bool IsSecurityTransparent { get { throw NotImplemented.ByDesign; } }
+
+ public override bool Equals(object obj) => base.Equals(obj);
+ public override int GetHashCode() => base.GetHashCode();
+
+ public static bool operator ==(MethodBase left, MethodBase right)
+ {
+ if (object.ReferenceEquals(left, right))
+ return true;
+
+ if ((object)left == null || (object)right == null)
+ return false;
+
+ MethodInfo method1, method2;
+ ConstructorInfo constructor1, constructor2;
+
+ if ((method1 = left as MethodInfo) != null && (method2 = right as MethodInfo) != null)
+ return method1 == method2;
+ else if ((constructor1 = left as ConstructorInfo) != null && (constructor2 = right as ConstructorInfo) != null)
+ return constructor1 == constructor2;
+
+ return false;
+ }
+
+ public static bool operator !=(MethodBase left, MethodBase right) => !(left == right);
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/MethodImplAttributes.cs b/src/mscorlib/shared/System/Reflection/MethodImplAttributes.cs
new file mode 100644
index 0000000000..a1ed326002
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/MethodImplAttributes.cs
@@ -0,0 +1,37 @@
+// 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.
+
+namespace System.Reflection
+{
+ // This Enum matchs the CorMethodImpl defined in CorHdr.h
+ public enum MethodImplAttributes
+ {
+ // code impl mask
+ CodeTypeMask = 0x0003, // Flags about code type.
+ IL = 0x0000, // Method impl is IL.
+ Native = 0x0001, // Method impl is native.
+ OPTIL = 0x0002, // Method impl is OPTIL
+ Runtime = 0x0003, // Method impl is provided by the runtime.
+ // end code impl mask
+
+ // managed mask
+ ManagedMask = 0x0004, // Flags specifying whether the code is managed or unmanaged.
+ Unmanaged = 0x0004, // Method impl is unmanaged, otherwise managed.
+ Managed = 0x0000, // Method impl is managed.
+ // end managed mask
+
+ // implementation info and interop
+ ForwardRef = 0x0010, // Indicates method is not defined; used primarily in merge scenarios.
+ PreserveSig = 0x0080, // Indicates method sig is exported exactly as declared.
+
+ InternalCall = 0x1000, // Internal Call...
+
+ Synchronized = 0x0020, // Method is single threaded through the body.
+ NoInlining = 0x0008, // Method may not be inlined.
+ AggressiveInlining = 0x0100, // Method should be inlined if possible.
+ NoOptimization = 0x0040, // Method may not be optimized.
+
+ MaxMethodImplVal = 0xffff,
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/MethodInfo.cs b/src/mscorlib/shared/System/Reflection/MethodInfo.cs
new file mode 100644
index 0000000000..3f60149e87
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/MethodInfo.cs
@@ -0,0 +1,43 @@
+// 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.
+
+namespace System.Reflection
+{
+ public abstract class MethodInfo : MethodBase
+ {
+ protected MethodInfo() { }
+
+ public override MemberTypes MemberType => MemberTypes.Method;
+
+ public virtual ParameterInfo ReturnParameter { get { throw NotImplemented.ByDesign; } }
+ public virtual Type ReturnType { get { throw NotImplemented.ByDesign; } }
+
+ public override Type[] GetGenericArguments() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+ public virtual MethodInfo GetGenericMethodDefinition() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+ public virtual MethodInfo MakeGenericMethod(params Type[] typeArguments) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+
+ public abstract MethodInfo GetBaseDefinition();
+
+ public abstract ICustomAttributeProvider ReturnTypeCustomAttributes { get; }
+
+ public virtual Delegate CreateDelegate(Type delegateType) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+ public virtual Delegate CreateDelegate(Type delegateType, object target) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+
+ public override bool Equals(object obj) => base.Equals(obj);
+ public override int GetHashCode() => base.GetHashCode();
+
+ public static bool operator ==(MethodInfo left, MethodInfo right)
+ {
+ if (object.ReferenceEquals(left, right))
+ return true;
+
+ if ((object)left == null || (object)right == null)
+ return false;
+
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(MethodInfo left, MethodInfo right) => !(left == right);
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/Missing.cs b/src/mscorlib/shared/System/Reflection/Missing.cs
new file mode 100644
index 0000000000..fa32d43ccb
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/Missing.cs
@@ -0,0 +1,24 @@
+// 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.Runtime.Serialization;
+
+namespace System.Reflection
+{
+ [Serializable]
+ public sealed class Missing : ISerializable
+ {
+ public static readonly Missing Value = new Missing();
+
+ private Missing() { }
+
+ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
+
+ UnitySerializationHolder.GetUnitySerializationInfo(info, this);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/Module.cs b/src/mscorlib/shared/System/Reflection/Module.cs
new file mode 100644
index 0000000000..56f83c40d9
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/Module.cs
@@ -0,0 +1,182 @@
+// 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.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace System.Reflection
+{
+ public abstract class Module : ICustomAttributeProvider, ISerializable
+ {
+ protected Module() { }
+
+ public virtual Assembly Assembly { get { throw NotImplemented.ByDesign; } }
+ public virtual string FullyQualifiedName { get { throw NotImplemented.ByDesign; } }
+ public virtual string Name { get { throw NotImplemented.ByDesign; } }
+
+ public virtual int MDStreamVersion { get { throw NotImplemented.ByDesign; } }
+ public virtual Guid ModuleVersionId { get { throw NotImplemented.ByDesign; } }
+ public virtual string ScopeName { get { throw NotImplemented.ByDesign; } }
+ public ModuleHandle ModuleHandle => GetModuleHandleImpl();
+ protected virtual ModuleHandle GetModuleHandleImpl() => ModuleHandle.EmptyHandle; // Not an api but declared protected because of Reflection.Core/Corelib divide (when built by CoreRt)
+ public virtual void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine) { throw NotImplemented.ByDesign; }
+ public virtual bool IsResource() { throw NotImplemented.ByDesign; }
+
+ public virtual bool IsDefined(Type attributeType, bool inherit) { throw NotImplemented.ByDesign; }
+ public virtual IEnumerable<CustomAttributeData> CustomAttributes => GetCustomAttributesData();
+ public virtual IList<CustomAttributeData> GetCustomAttributesData() { throw NotImplemented.ByDesign; }
+ public virtual object[] GetCustomAttributes(bool inherit) { throw NotImplemented.ByDesign; }
+ public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) { throw NotImplemented.ByDesign; }
+
+ public MethodInfo GetMethod(string name)
+ {
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+
+ return GetMethodImpl(name, Module.DefaultLookup, null, CallingConventions.Any, null, null);
+ }
+
+ public MethodInfo GetMethod(string name, Type[] types) => GetMethod(name, Module.DefaultLookup, null, CallingConventions.Any, types, null);
+ public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
+ {
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+ if (types == null)
+ throw new ArgumentNullException(nameof(types));
+ for (int i = 0; i < types.Length; i++)
+ {
+ if (types[i] == null)
+ throw new ArgumentNullException(nameof(types));
+ }
+ return GetMethodImpl(name, bindingAttr, binder, callConvention, types, modifiers);
+ }
+
+ protected virtual MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { throw NotImplemented.ByDesign; }
+
+ public MethodInfo[] GetMethods() => GetMethods(Module.DefaultLookup);
+ public virtual MethodInfo[] GetMethods(BindingFlags bindingFlags) { throw NotImplemented.ByDesign; }
+
+ public FieldInfo GetField(string name) => GetField(name, Module.DefaultLookup);
+ public virtual FieldInfo GetField(string name, BindingFlags bindingAttr) { throw NotImplemented.ByDesign; }
+
+ public FieldInfo[] GetFields() => GetFields(Module.DefaultLookup);
+ public virtual FieldInfo[] GetFields(BindingFlags bindingFlags) { throw NotImplemented.ByDesign; }
+
+ public virtual Type[] GetTypes() { throw NotImplemented.ByDesign; }
+
+ public virtual Type GetType(string className) => GetType(className, throwOnError: false, ignoreCase: false);
+ public virtual Type GetType(string className, bool ignoreCase) => GetType(className, throwOnError: false, ignoreCase: ignoreCase);
+ public virtual Type GetType(string className, bool throwOnError, bool ignoreCase) { throw NotImplemented.ByDesign; }
+
+ public virtual Type[] FindTypes(TypeFilter filter, object filterCriteria)
+ {
+ Type[] c = GetTypes();
+ int cnt = 0;
+ for (int i = 0; i < c.Length; i++)
+ {
+ if (filter != null && !filter(c[i], filterCriteria))
+ c[i] = null;
+ else
+ cnt++;
+ }
+ if (cnt == c.Length)
+ return c;
+
+ Type[] ret = new Type[cnt];
+ cnt = 0;
+ for (int i = 0; i < c.Length; i++)
+ {
+ if (c[i] != null)
+ ret[cnt++] = c[i];
+ }
+ return ret;
+ }
+
+ public virtual int MetadataToken { get { throw NotImplemented.ByDesign; } }
+
+ public FieldInfo ResolveField(int metadataToken) => ResolveField(metadataToken, null, null);
+ public virtual FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) { throw NotImplemented.ByDesign; }
+
+ public MemberInfo ResolveMember(int metadataToken) => ResolveMember(metadataToken, null, null);
+ public virtual MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) { throw NotImplemented.ByDesign; }
+
+ public MethodBase ResolveMethod(int metadataToken) => ResolveMethod(metadataToken, null, null);
+ public virtual MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) { throw NotImplemented.ByDesign; }
+
+ public virtual byte[] ResolveSignature(int metadataToken) { throw NotImplemented.ByDesign; }
+ public virtual string ResolveString(int metadataToken) { throw NotImplemented.ByDesign; }
+
+ public Type ResolveType(int metadataToken) => ResolveType(metadataToken, null, null);
+ public virtual Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) { throw NotImplemented.ByDesign; }
+
+ public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { throw NotImplemented.ByDesign; }
+
+ public override bool Equals(object o) => base.Equals(o);
+ public override int GetHashCode() => base.GetHashCode();
+
+ public static bool operator ==(Module left, Module right)
+ {
+ if (object.ReferenceEquals(left, right))
+ return true;
+
+ if ((object)left == null || (object)right == null)
+ return false;
+
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(Module left, Module right) => !(left == right);
+
+ public override string ToString() => ScopeName;
+
+ public static readonly TypeFilter FilterTypeName = FilterTypeNameImpl;
+ public static readonly TypeFilter FilterTypeNameIgnoreCase = FilterTypeNameIgnoreCaseImpl;
+
+ private const BindingFlags DefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
+
+ // FilterTypeName
+ // This method will filter the class based upon the name. It supports
+ // a trailing wild card.
+ private static bool FilterTypeNameImpl(Type cls, object filterCriteria)
+ {
+ // Check that the criteria object is a String object
+ if (filterCriteria == null || !(filterCriteria is string))
+ throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritString);
+
+ string str = (string)filterCriteria;
+
+ // Check to see if this is a prefix or exact match requirement
+ if (str.Length > 0 && str[str.Length - 1] == '*')
+ {
+ str = str.Substring(0, str.Length - 1);
+ return cls.Name.StartsWith(str, StringComparison.Ordinal);
+ }
+
+ return cls.Name.Equals(str);
+ }
+
+ // FilterFieldNameIgnoreCase
+ // This method filter the Type based upon name, it ignores case.
+ private static bool FilterTypeNameIgnoreCaseImpl(Type cls, object filterCriteria)
+ {
+ // Check that the criteria object is a String object
+ if (filterCriteria == null || !(filterCriteria is string))
+ throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritString);
+
+ string str = (string)filterCriteria;
+
+ // Check to see if this is a prefix or exact match requirement
+ if (str.Length > 0 && str[str.Length - 1] == '*')
+ {
+ str = str.Substring(0, str.Length - 1);
+ string name = cls.Name;
+ if (name.Length >= str.Length)
+ return (string.Compare(name, 0, str, 0, str.Length, StringComparison.OrdinalIgnoreCase) == 0);
+ else
+ return false;
+ }
+ return (string.Compare(str, cls.Name, StringComparison.OrdinalIgnoreCase) == 0);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/ModuleResolveEventHandler.cs b/src/mscorlib/shared/System/Reflection/ModuleResolveEventHandler.cs
new file mode 100644
index 0000000000..eb8926b5db
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ModuleResolveEventHandler.cs
@@ -0,0 +1,9 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Reflection
+{
+ public delegate Module ModuleResolveEventHandler(object sender, ResolveEventArgs e);
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/ObfuscateAssemblyAttribute.cs b/src/mscorlib/shared/System/Reflection/ObfuscateAssemblyAttribute.cs
new file mode 100644
index 0000000000..f8f765ced2
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ObfuscateAssemblyAttribute.cs
@@ -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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
+ public sealed class ObfuscateAssemblyAttribute : Attribute
+ {
+ public ObfuscateAssemblyAttribute(bool assemblyIsPrivate)
+ {
+ AssemblyIsPrivate = assemblyIsPrivate;
+ }
+
+ public bool AssemblyIsPrivate { get; }
+ public bool StripAfterObfuscation { get; set; } = true;
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/ObfuscationAttribute.cs b/src/mscorlib/shared/System/Reflection/ObfuscationAttribute.cs
new file mode 100644
index 0000000000..11d93b6313
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ObfuscationAttribute.cs
@@ -0,0 +1,21 @@
+// 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.
+
+namespace System.Reflection
+{
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Delegate,
+ AllowMultiple = true, Inherited = false)]
+ public sealed class ObfuscationAttribute : Attribute
+ {
+ public ObfuscationAttribute()
+ {
+ }
+
+ public bool StripAfterObfuscation { get; set; } = true;
+ public bool Exclude { get; set; } = true;
+ public bool ApplyToMembers { get; set; } = true;
+ public string Feature { get; set; } = "all";
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/ParameterAttributes.cs b/src/mscorlib/shared/System/Reflection/ParameterAttributes.cs
new file mode 100644
index 0000000000..ce195897c2
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ParameterAttributes.cs
@@ -0,0 +1,29 @@
+// 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.
+
+// ParameterAttributes is an enum defining the attributes that may be
+// associated with a Parameter. These are defined in CorHdr.h.
+
+namespace System.Reflection
+{
+ // This Enum matchs the CorParamAttr defined in CorHdr.h
+ [Flags]
+ public enum ParameterAttributes
+ {
+ None = 0x0000, // no flag is specified
+ In = 0x0001, // Param is [In]
+ Out = 0x0002, // Param is [Out]
+ Lcid = 0x0004, // Param is [lcid]
+
+ Retval = 0x0008, // Param is [Retval]
+ Optional = 0x0010, // Param is optional
+
+ HasDefault = 0x1000, // Param has default value.
+ HasFieldMarshal = 0x2000, // Param has FieldMarshal.
+
+ Reserved3 = 0x4000,
+ Reserved4 = 0x8000,
+ ReservedMask = 0xf000,
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/ParameterInfo.cs b/src/mscorlib/shared/System/Reflection/ParameterInfo.cs
new file mode 100644
index 0000000000..94bfffaa53
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ParameterInfo.cs
@@ -0,0 +1,110 @@
+// 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.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace System.Reflection
+{
+ public class ParameterInfo : ICustomAttributeProvider, IObjectReference
+ {
+ protected ParameterInfo() { }
+
+ public virtual ParameterAttributes Attributes => AttrsImpl;
+ public virtual MemberInfo Member => MemberImpl;
+ public virtual string Name => NameImpl;
+ public virtual Type ParameterType => ClassImpl;
+ public virtual int Position => PositionImpl;
+
+ public bool IsIn => (Attributes & ParameterAttributes.In) != 0;
+ public bool IsLcid => (Attributes & ParameterAttributes.Lcid) != 0;
+ public bool IsOptional => (Attributes & ParameterAttributes.Optional) != 0;
+ public bool IsOut => (Attributes & ParameterAttributes.Out) != 0;
+ public bool IsRetval => (Attributes & ParameterAttributes.Retval) != 0;
+
+ public virtual object DefaultValue { get { throw NotImplemented.ByDesign; } }
+ public virtual object RawDefaultValue { get { throw NotImplemented.ByDesign; } }
+ public virtual bool HasDefaultValue { get { throw NotImplemented.ByDesign; } }
+
+ public virtual bool IsDefined(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+
+ return false;
+ }
+
+ public virtual IEnumerable<CustomAttributeData> CustomAttributes => GetCustomAttributesData();
+ public virtual IList<CustomAttributeData> GetCustomAttributesData() { throw NotImplemented.ByDesign; }
+
+ public virtual object[] GetCustomAttributes(bool inherit) => Array.Empty<object>();
+ public virtual object[] GetCustomAttributes(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+
+ return Array.Empty<object>();
+ }
+
+ public virtual Type[] GetOptionalCustomModifiers() => Array.Empty<Type>();
+ public virtual Type[] GetRequiredCustomModifiers() => Array.Empty<Type>();
+
+ public virtual int MetadataToken => MetadataToken_ParamDef;
+
+ public object GetRealObject(StreamingContext context)
+ {
+ // Once all the serializable fields have come in we can set up the real
+ // instance based on just two of them (MemberImpl and PositionImpl).
+
+ if (MemberImpl == null)
+ throw new SerializationException(SR.Serialization_InsufficientState);
+
+ ParameterInfo[] args = null;
+
+ switch (MemberImpl.MemberType)
+ {
+ case MemberTypes.Constructor:
+ case MemberTypes.Method:
+ if (PositionImpl == -1)
+ {
+ if (MemberImpl.MemberType == MemberTypes.Method)
+ return ((MethodInfo)MemberImpl).ReturnParameter;
+ else
+ throw new SerializationException(SR.Serialization_BadParameterInfo);
+ }
+ else
+ {
+ args = ((MethodBase)MemberImpl).GetParametersNoCopy();
+
+ if (args != null && PositionImpl < args.Length)
+ return args[PositionImpl];
+ else
+ throw new SerializationException(SR.Serialization_BadParameterInfo);
+ }
+
+ case MemberTypes.Property:
+ args = ((PropertyInfo)MemberImpl).GetIndexParameters();
+
+ if (args != null && PositionImpl > -1 && PositionImpl < args.Length)
+ return args[PositionImpl];
+ else
+ throw new SerializationException(SR.Serialization_BadParameterInfo);
+
+ default:
+ throw new SerializationException(SR.Serialization_NoParameterInfo);
+ }
+ }
+
+ public override string ToString() => ParameterType.FormatTypeName() + " " + Name;
+
+ protected ParameterAttributes AttrsImpl;
+ protected Type ClassImpl;
+ protected object DefaultValueImpl;
+ protected MemberInfo MemberImpl;
+ protected string NameImpl;
+ protected int PositionImpl;
+
+ private const int MetadataToken_ParamDef = 0x08000000;
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/ParameterModifier.cs b/src/mscorlib/shared/System/Reflection/ParameterModifier.cs
new file mode 100644
index 0000000000..18d6cf669d
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ParameterModifier.cs
@@ -0,0 +1,36 @@
+// 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.
+
+namespace System.Reflection
+{
+ [Serializable]
+ public struct ParameterModifier
+ {
+ private readonly bool[] _byRef;
+
+ public ParameterModifier(int parameterCount)
+ {
+ if (parameterCount <= 0)
+ throw new ArgumentException(SR.Arg_ParmArraySize);
+
+ _byRef = new bool[parameterCount];
+ }
+
+ public bool this[int index]
+ {
+ get
+ {
+ return _byRef[index];
+ }
+ set
+ {
+ _byRef[index] = value;
+ }
+ }
+
+#if CORECLR
+ internal bool[] IsByRefArray => _byRef;
+#endif
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/Pointer.cs b/src/mscorlib/shared/System/Reflection/Pointer.cs
new file mode 100644
index 0000000000..13a5efff46
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/Pointer.cs
@@ -0,0 +1,61 @@
+// 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.Diagnostics;
+using System.Runtime.Serialization;
+
+namespace System.Reflection
+{
+ [Serializable]
+ [CLSCompliant(false)]
+ public sealed unsafe class Pointer : ISerializable
+ {
+ // CoreCLR: Do not add or remove fields without updating the ReflectionPointer class in runtimehandles.h
+ private readonly void* _ptr;
+ private readonly Type _ptrType;
+
+ private Pointer(void* ptr, Type ptrType)
+ {
+ Debug.Assert(ptrType.IsRuntimeImplemented()); // CoreCLR: For CoreRT's sake, _ptrType has to be declared as "Type", but in fact, it is always a RuntimeType. Code on CoreCLR expects this.
+ _ptr = ptr;
+ _ptrType = ptrType;
+ }
+
+ private Pointer(SerializationInfo info, StreamingContext context)
+ {
+ _ptr = ((IntPtr)(info.GetValue("_ptr", typeof(IntPtr)))).ToPointer();
+ _ptrType = (Type)info.GetValue("_ptrType", typeof(Type));
+ if (!_ptrType.IsRuntimeImplemented())
+ throw new SerializationException(SR.Arg_MustBeType);
+ }
+
+ public static object Box(void* ptr, Type type)
+ {
+ if (type == null)
+ throw new ArgumentNullException(nameof(type));
+ if (!type.IsPointer)
+ throw new ArgumentException(SR.Arg_MustBePointer, nameof(ptr));
+ if (!type.IsRuntimeImplemented())
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(ptr));
+
+ return new Pointer(ptr, type);
+ }
+
+ public static void* Unbox(object ptr)
+ {
+ if (!(ptr is Pointer))
+ throw new ArgumentException(SR.Arg_MustBePointer, nameof(ptr));
+ return ((Pointer)ptr)._ptr;
+ }
+
+ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ info.AddValue("_ptr", new IntPtr(_ptr));
+ info.AddValue("_ptrType", _ptrType);
+ }
+
+ internal Type GetPointerType() => _ptrType;
+ internal object GetPointerValue() => (IntPtr)_ptr;
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/PortableExecutableKinds.cs b/src/mscorlib/shared/System/Reflection/PortableExecutableKinds.cs
new file mode 100644
index 0000000000..79be338685
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/PortableExecutableKinds.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Reflection
+{
+ [Flags]
+ public enum PortableExecutableKinds
+ {
+ NotAPortableExecutableImage = 0x0,
+ ILOnly = 0x1,
+ Required32Bit = 0x2,
+ PE32Plus = 0x4,
+ Unmanaged32Bit = 0x8,
+ Preferred32Bit = 0x10,
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/ProcessorArchitecture.cs b/src/mscorlib/shared/System/Reflection/ProcessorArchitecture.cs
new file mode 100644
index 0000000000..becb346c4f
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ProcessorArchitecture.cs
@@ -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.
+
+namespace System.Reflection
+{
+ public enum ProcessorArchitecture
+ {
+ None = 0x0000,
+ MSIL = 0x0001,
+ X86 = 0x0002,
+ IA64 = 0x0003,
+ Amd64 = 0x0004,
+ Arm = 0x0005
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/PropertyAttributes.cs b/src/mscorlib/shared/System/Reflection/PropertyAttributes.cs
new file mode 100644
index 0000000000..31e7a653bb
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/PropertyAttributes.cs
@@ -0,0 +1,25 @@
+// 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.
+
+// PropertyAttributes is an enum which defines the attributes that may be associated
+// with a property. The values here are defined in Corhdr.h.
+
+namespace System.Reflection
+{
+ // This Enum matchs the CorPropertyAttr defined in CorHdr.h
+ [Flags]
+ public enum PropertyAttributes
+ {
+ None = 0x0000,
+ SpecialName = 0x0200, // property is special. Name describes how.
+
+ RTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding.
+ HasDefault = 0x1000, // Property has default
+
+ Reserved2 = 0x2000,
+ Reserved3 = 0x4000,
+ Reserved4 = 0x8000,
+ ReservedMask = 0xf400,
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/PropertyInfo.cs b/src/mscorlib/shared/System/Reflection/PropertyInfo.cs
new file mode 100644
index 0000000000..ff8a02e96d
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/PropertyInfo.cs
@@ -0,0 +1,74 @@
+// 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.Diagnostics;
+using System.Globalization;
+
+namespace System.Reflection
+{
+ public abstract class PropertyInfo : MemberInfo
+ {
+ protected PropertyInfo() { }
+
+ public override MemberTypes MemberType => MemberTypes.Property;
+
+ public abstract Type PropertyType { get; }
+ public abstract ParameterInfo[] GetIndexParameters();
+
+ public abstract PropertyAttributes Attributes { get; }
+ public bool IsSpecialName => (Attributes & PropertyAttributes.SpecialName) != 0;
+
+ public abstract bool CanRead { get; }
+ public abstract bool CanWrite { get; }
+
+ public MethodInfo[] GetAccessors() => GetAccessors(nonPublic: false);
+ public abstract MethodInfo[] GetAccessors(bool nonPublic);
+
+ public virtual MethodInfo GetMethod => GetGetMethod(nonPublic: true);
+ public MethodInfo GetGetMethod() => GetGetMethod(nonPublic: false);
+ public abstract MethodInfo GetGetMethod(bool nonPublic);
+
+ public virtual MethodInfo SetMethod => GetSetMethod(nonPublic: true);
+ public MethodInfo GetSetMethod() => GetSetMethod(nonPublic: false);
+ public abstract MethodInfo GetSetMethod(bool nonPublic);
+
+ public virtual Type[] GetOptionalCustomModifiers() => Array.Empty<Type>();
+ public virtual Type[] GetRequiredCustomModifiers() => Array.Empty<Type>();
+
+ [DebuggerHidden]
+ [DebuggerStepThrough]
+ public object GetValue(object obj) => GetValue(obj, index: null);
+ [DebuggerHidden]
+ [DebuggerStepThrough]
+ public virtual object GetValue(object obj, object[] index) => GetValue(obj, BindingFlags.Default, binder: null, index: index, culture: null);
+ public abstract object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture);
+
+ public virtual object GetConstantValue() { throw NotImplemented.ByDesign; }
+ public virtual object GetRawConstantValue() { throw NotImplemented.ByDesign; }
+
+ [DebuggerHidden]
+ [DebuggerStepThrough]
+ public void SetValue(object obj, object value) => SetValue(obj, value, index: null);
+ [DebuggerHidden]
+ [DebuggerStepThrough]
+ public virtual void SetValue(object obj, object value, object[] index) => SetValue(obj, value, BindingFlags.Default, binder: null, index: index, culture: null);
+ public abstract void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture);
+
+ public override bool Equals(object obj) => base.Equals(obj);
+ public override int GetHashCode() => base.GetHashCode();
+
+ public static bool operator ==(PropertyInfo left, PropertyInfo right)
+ {
+ if (object.ReferenceEquals(left, right))
+ return true;
+
+ if ((object)left == null || (object)right == null)
+ return false;
+
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(PropertyInfo left, PropertyInfo right) => !(left == right);
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/ReflectionContext.cs b/src/mscorlib/shared/System/Reflection/ReflectionContext.cs
new file mode 100644
index 0000000000..e9e93dab81
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ReflectionContext.cs
@@ -0,0 +1,24 @@
+// 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.
+
+namespace System.Reflection
+{
+ public abstract class ReflectionContext
+ {
+ protected ReflectionContext() { }
+
+ public abstract Assembly MapAssembly(Assembly assembly);
+
+ public abstract TypeInfo MapType(TypeInfo type);
+
+ public virtual TypeInfo GetTypeForObject(object value)
+ {
+ if (value == null)
+ throw new ArgumentNullException(nameof(value));
+
+ return MapType(value.GetType().GetTypeInfo());
+ }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/ReflectionTypeLoadException.cs b/src/mscorlib/shared/System/Reflection/ReflectionTypeLoadException.cs
new file mode 100644
index 0000000000..772620cf84
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ReflectionTypeLoadException.cs
@@ -0,0 +1,46 @@
+// 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.Runtime.Serialization;
+
+namespace System.Reflection
+{
+ [Serializable]
+ public sealed class ReflectionTypeLoadException : SystemException, ISerializable
+ {
+ public ReflectionTypeLoadException(Type[] classes, Exception[] exceptions)
+ : base(null)
+ {
+ Types = classes;
+ LoaderExceptions = exceptions;
+ HResult = __HResults.COR_E_REFLECTIONTYPELOAD;
+ }
+
+ public ReflectionTypeLoadException(Type[] classes, Exception[] exceptions, string message)
+ : base(message)
+ {
+ Types = classes;
+ LoaderExceptions = exceptions;
+ HResult = __HResults.COR_E_REFLECTIONTYPELOAD;
+ }
+
+ internal ReflectionTypeLoadException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ Types = (Type[])(info.GetValue("Types", typeof(Type[])));
+ LoaderExceptions = (Exception[])(info.GetValue("Exceptions", typeof(Exception[])));
+ }
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ base.GetObjectData(info, context);
+ info.AddValue("Types", Types, typeof(Type[]));
+ info.AddValue("Exceptions", LoaderExceptions, typeof(Exception[]));
+ }
+
+ public Type[] Types { get; }
+
+ public Exception[] LoaderExceptions { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/ResourceAttributes.cs b/src/mscorlib/shared/System/Reflection/ResourceAttributes.cs
new file mode 100644
index 0000000000..2d03f42ba0
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ResourceAttributes.cs
@@ -0,0 +1,14 @@
+// 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.
+
+namespace System.Reflection
+{
+ [Flags]
+ public enum ResourceAttributes
+ {
+ Public = 0x0001,
+ Private = 0x0002,
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/ResourceLocation.cs b/src/mscorlib/shared/System/Reflection/ResourceLocation.cs
new file mode 100644
index 0000000000..4902333ac0
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/ResourceLocation.cs
@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Reflection
+{
+ [Flags]
+ public enum ResourceLocation
+ {
+ ContainedInAnotherAssembly = 2,
+ ContainedInManifestFile = 4,
+ Embedded = 1,
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Reflection/StrongNameKeyPair.cs b/src/mscorlib/shared/System/Reflection/StrongNameKeyPair.cs
new file mode 100644
index 0000000000..c04ddd6d1a
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/StrongNameKeyPair.cs
@@ -0,0 +1,74 @@
+// 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.IO;
+using System.Runtime.Serialization;
+
+namespace System.Reflection
+{
+ [Serializable]
+ public class StrongNameKeyPair : IDeserializationCallback, ISerializable
+ {
+ private bool _keyPairExported;
+ private byte[] _keyPairArray;
+ private string _keyPairContainer;
+ private byte[] _publicKey;
+
+ // Build key pair from file.
+ public StrongNameKeyPair(FileStream keyPairFile)
+ {
+ if (keyPairFile == null)
+ throw new ArgumentNullException(nameof(keyPairFile));
+
+ int length = (int)keyPairFile.Length;
+ _keyPairArray = new byte[length];
+ keyPairFile.Read(_keyPairArray, 0, length);
+
+ _keyPairExported = true;
+ }
+
+ // Build key pair from byte array in memory.
+ public StrongNameKeyPair(byte[] keyPairArray)
+ {
+ if (keyPairArray == null)
+ throw new ArgumentNullException(nameof(keyPairArray));
+
+ _keyPairArray = new byte[keyPairArray.Length];
+ Array.Copy(keyPairArray, _keyPairArray, keyPairArray.Length);
+
+ _keyPairExported = true;
+ }
+
+ protected StrongNameKeyPair(SerializationInfo info, StreamingContext context)
+ {
+ _keyPairExported = (bool)info.GetValue("_keyPairExported", typeof(bool));
+ _keyPairArray = (byte[])info.GetValue("_keyPairArray", typeof(byte[]));
+ _keyPairContainer = (string)info.GetValue("_keyPairContainer", typeof(string));
+ _publicKey = (byte[])info.GetValue("_publicKey", typeof(byte[]));
+ }
+
+ public StrongNameKeyPair(string keyPairContainer)
+ {
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_StrongNameSigning);
+ }
+
+ public byte[] PublicKey
+ {
+ get
+ {
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_StrongNameSigning);
+ }
+ }
+
+ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ info.AddValue("_keyPairExported", _keyPairExported);
+ info.AddValue("_keyPairArray", _keyPairArray);
+ info.AddValue("_keyPairContainer", _keyPairContainer);
+ info.AddValue("_publicKey", _publicKey);
+ }
+
+ void IDeserializationCallback.OnDeserialization(object sender) { }
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/TargetException.cs b/src/mscorlib/shared/System/Reflection/TargetException.cs
new file mode 100644
index 0000000000..03f8730cdd
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/TargetException.cs
@@ -0,0 +1,33 @@
+// 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.Runtime.Serialization;
+
+namespace System.Reflection
+{
+ [Serializable]
+ public class TargetException : ApplicationException
+ {
+ public TargetException()
+ : this(null)
+ {
+ }
+
+ public TargetException(string message)
+ : this(message, null)
+ {
+ }
+
+ public TargetException(string message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_TARGET;
+ }
+
+ protected TargetException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/TargetInvocationException.cs b/src/mscorlib/shared/System/Reflection/TargetInvocationException.cs
new file mode 100644
index 0000000000..e934e5bde7
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/TargetInvocationException.cs
@@ -0,0 +1,29 @@
+// 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.Runtime.Serialization;
+
+namespace System.Reflection
+{
+ [Serializable]
+ public sealed class TargetInvocationException : ApplicationException
+ {
+ public TargetInvocationException(Exception inner)
+ : base(SR.Arg_TargetInvocationException, inner)
+ {
+ HResult = __HResults.COR_E_TARGETINVOCATION;
+ }
+
+ public TargetInvocationException(string message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_TARGETINVOCATION;
+ }
+
+ internal TargetInvocationException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/TargetParameterCountException.cs b/src/mscorlib/shared/System/Reflection/TargetParameterCountException.cs
new file mode 100644
index 0000000000..c3604548e6
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/TargetParameterCountException.cs
@@ -0,0 +1,35 @@
+// 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.Runtime.Serialization;
+
+namespace System.Reflection
+{
+ [Serializable]
+ public sealed class TargetParameterCountException : ApplicationException
+ {
+ public TargetParameterCountException()
+ : base(SR.Arg_TargetParameterCountException)
+ {
+ HResult = __HResults.COR_E_TARGETPARAMCOUNT;
+ }
+
+ public TargetParameterCountException(string message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_TARGETPARAMCOUNT;
+ }
+
+ public TargetParameterCountException(string message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_TARGETPARAMCOUNT;
+ }
+
+ internal TargetParameterCountException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/TypeAttributes.cs b/src/mscorlib/shared/System/Reflection/TypeAttributes.cs
new file mode 100644
index 0000000000..aa30331856
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/TypeAttributes.cs
@@ -0,0 +1,63 @@
+// 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.Runtime.InteropServices;
+
+namespace System.Reflection
+{
+ // This Enum matchs the CorTypeAttr defined in CorHdr.h
+ [Flags]
+ public enum TypeAttributes
+ {
+ VisibilityMask = 0x00000007,
+ NotPublic = 0x00000000, // Class is not public scope.
+ Public = 0x00000001, // Class is public scope.
+ NestedPublic = 0x00000002, // Class is nested with public visibility.
+ NestedPrivate = 0x00000003, // Class is nested with private visibility.
+ NestedFamily = 0x00000004, // Class is nested with family visibility.
+ NestedAssembly = 0x00000005, // Class is nested with assembly visibility.
+ NestedFamANDAssem = 0x00000006, // Class is nested with family and assembly visibility.
+ NestedFamORAssem = 0x00000007, // Class is nested with family or assembly visibility.
+
+ // Use this mask to retrieve class layout informaiton
+ // 0 is AutoLayout, 0x2 is SequentialLayout, 4 is ExplicitLayout
+ LayoutMask = 0x00000018,
+ AutoLayout = 0x00000000, // Class fields are auto-laid out
+ SequentialLayout = 0x00000008, // Class fields are laid out sequentially
+ ExplicitLayout = 0x00000010, // Layout is supplied explicitly
+ // end layout mask
+
+ // Use this mask to distinguish whether a type declaration is an interface. (Class vs. ValueType done based on whether it subclasses S.ValueType)
+ ClassSemanticsMask = 0x00000020,
+ Class = 0x00000000, // Type is a class (or a value type).
+ Interface = 0x00000020, // Type is an interface.
+
+ // Special semantics in addition to class semantics.
+ Abstract = 0x00000080, // Class is abstract
+ Sealed = 0x00000100, // Class is concrete and may not be extended
+ SpecialName = 0x00000400, // Class name is special. Name describes how.
+
+ // Implementation attributes.
+ Import = 0x00001000, // Class / interface is imported
+ Serializable = 0x00002000, // The class is Serializable.
+ WindowsRuntime = 0x00004000, // Type is a Windows Runtime type.
+
+ // Use tdStringFormatMask to retrieve string information for native interop
+ StringFormatMask = 0x00030000,
+ AnsiClass = 0x00000000, // LPTSTR is interpreted as ANSI in this class
+ UnicodeClass = 0x00010000, // LPTSTR is interpreted as UNICODE
+ AutoClass = 0x00020000, // LPTSTR is interpreted automatically
+ CustomFormatClass = 0x00030000, // A non-standard encoding specified by CustomFormatMask
+ CustomFormatMask = 0x00C00000, // Use this mask to retrieve non-standard encoding information for native interop. The meaning of the values of these 2 bits is unspecified.
+
+ // end string format mask
+
+ BeforeFieldInit = 0x00100000, // Initialize the class any time before first static field access.
+
+ RTSpecialName = 0x00000800, // Runtime should check name encoding.
+ HasSecurity = 0x00040000, // Class has security associate with it.
+
+ ReservedMask = 0x00040800,
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/TypeDelegator.cs b/src/mscorlib/shared/System/Reflection/TypeDelegator.cs
new file mode 100644
index 0000000000..7f928d2486
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/TypeDelegator.cs
@@ -0,0 +1,124 @@
+// 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.
+
+// TypeDelegator
+//
+// This class wraps a Type object and delegates all methods to that Type.
+
+using CultureInfo = System.Globalization.CultureInfo;
+
+namespace System.Reflection
+{
+ [Serializable]
+ public class TypeDelegator : TypeInfo
+ {
+ public override bool IsAssignableFrom(TypeInfo typeInfo)
+ {
+ if (typeInfo == null)
+ return false;
+ return IsAssignableFrom(typeInfo.AsType());
+ }
+
+ protected Type typeImpl;
+
+ protected TypeDelegator() { }
+
+ public TypeDelegator(Type delegatingType)
+ {
+ if (delegatingType == null)
+ throw new ArgumentNullException(nameof(delegatingType));
+
+ typeImpl = delegatingType;
+ }
+
+ public override Guid GUID => typeImpl.GUID;
+ public override int MetadataToken => typeImpl.MetadataToken;
+
+ public override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target,
+ object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
+ {
+ return typeImpl.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
+ }
+
+ public override Module Module => typeImpl.Module;
+ public override Assembly Assembly => typeImpl.Assembly;
+ public override RuntimeTypeHandle TypeHandle => typeImpl.TypeHandle;
+ public override string Name => typeImpl.Name;
+ public override string FullName => typeImpl.FullName;
+ public override string Namespace => typeImpl.Namespace;
+ public override string AssemblyQualifiedName => typeImpl.AssemblyQualifiedName;
+ public override Type BaseType => typeImpl.BaseType;
+
+ protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder,
+ CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
+ {
+ return typeImpl.GetConstructor(bindingAttr, binder, callConvention, types, modifiers);
+ }
+
+ public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) => typeImpl.GetConstructors(bindingAttr);
+
+ protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder,
+ CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
+ {
+ // This is interesting there are two paths into the impl. One that validates
+ // type as non-null and one where type may be null.
+ if (types == null)
+ return typeImpl.GetMethod(name, bindingAttr);
+ else
+ return typeImpl.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers);
+ }
+
+ public override MethodInfo[] GetMethods(BindingFlags bindingAttr) => typeImpl.GetMethods(bindingAttr);
+
+ public override FieldInfo GetField(string name, BindingFlags bindingAttr) => typeImpl.GetField(name, bindingAttr);
+ public override FieldInfo[] GetFields(BindingFlags bindingAttr) => typeImpl.GetFields(bindingAttr);
+
+ public override Type GetInterface(string name, bool ignoreCase) => typeImpl.GetInterface(name, ignoreCase);
+
+ public override Type[] GetInterfaces() => typeImpl.GetInterfaces();
+
+ public override EventInfo GetEvent(string name, BindingFlags bindingAttr) => typeImpl.GetEvent(name, bindingAttr);
+
+ public override EventInfo[] GetEvents() => typeImpl.GetEvents();
+
+ protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder,
+ Type returnType, Type[] types, ParameterModifier[] modifiers)
+ {
+ if (returnType == null && types == null)
+ return typeImpl.GetProperty(name, bindingAttr);
+ else
+ return typeImpl.GetProperty(name, bindingAttr, binder, returnType, types, modifiers);
+ }
+
+ public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) => typeImpl.GetProperties(bindingAttr);
+ public override EventInfo[] GetEvents(BindingFlags bindingAttr) => typeImpl.GetEvents(bindingAttr);
+ public override Type[] GetNestedTypes(BindingFlags bindingAttr) => typeImpl.GetNestedTypes(bindingAttr);
+ public override Type GetNestedType(string name, BindingFlags bindingAttr) => typeImpl.GetNestedType(name, bindingAttr);
+ public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) => typeImpl.GetMember(name, type, bindingAttr);
+ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) => typeImpl.GetMembers(bindingAttr);
+
+ protected override TypeAttributes GetAttributeFlagsImpl() => typeImpl.Attributes;
+
+ public override bool IsSZArray => typeImpl.IsSZArray;
+
+ protected override bool IsArrayImpl() => typeImpl.IsArray;
+ protected override bool IsPrimitiveImpl() => typeImpl.IsPrimitive;
+ protected override bool IsByRefImpl() => typeImpl.IsByRef;
+ protected override bool IsPointerImpl() => typeImpl.IsPointer;
+ protected override bool IsValueTypeImpl() => typeImpl.IsValueType;
+ protected override bool IsCOMObjectImpl() => typeImpl.IsCOMObject;
+ public override bool IsConstructedGenericType => typeImpl.IsConstructedGenericType;
+ public override Type GetElementType() => typeImpl.GetElementType();
+ protected override bool HasElementTypeImpl() => typeImpl.HasElementType;
+
+ public override Type UnderlyingSystemType => typeImpl.UnderlyingSystemType;
+
+ // ICustomAttributeProvider
+ public override object[] GetCustomAttributes(bool inherit) => typeImpl.GetCustomAttributes(inherit);
+ public override object[] GetCustomAttributes(Type attributeType, bool inherit) => typeImpl.GetCustomAttributes(attributeType, inherit);
+
+ public override bool IsDefined(Type attributeType, bool inherit) => typeImpl.IsDefined(attributeType, inherit);
+ public override InterfaceMapping GetInterfaceMap(Type interfaceType) => typeImpl.GetInterfaceMap(interfaceType);
+ }
+}
diff --git a/src/mscorlib/shared/System/Reflection/TypeFilter.cs b/src/mscorlib/shared/System/Reflection/TypeFilter.cs
new file mode 100644
index 0000000000..eb049f81f9
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/TypeFilter.cs
@@ -0,0 +1,8 @@
+// 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.
+
+namespace System.Reflection
+{
+ public delegate bool TypeFilter(Type m, object filterCriteria);
+}
diff --git a/src/mscorlib/shared/System/Reflection/TypeInfo.cs b/src/mscorlib/shared/System/Reflection/TypeInfo.cs
new file mode 100644
index 0000000000..f4add736f4
--- /dev/null
+++ b/src/mscorlib/shared/System/Reflection/TypeInfo.cs
@@ -0,0 +1,84 @@
+// 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.Collections.Generic;
+
+namespace System.Reflection
+{
+ public abstract partial class TypeInfo : Type, IReflectableType
+ {
+ protected TypeInfo() { }
+
+ TypeInfo IReflectableType.GetTypeInfo() => this;
+ public virtual Type AsType() => this;
+
+ public virtual Type[] GenericTypeParameters => IsGenericTypeDefinition ? GetGenericArguments() : Type.EmptyTypes;
+
+ public virtual EventInfo GetDeclaredEvent(string name) => GetEvent(name, TypeInfo.DeclaredOnlyLookup);
+ public virtual FieldInfo GetDeclaredField(string name) => GetField(name, TypeInfo.DeclaredOnlyLookup);
+ public virtual MethodInfo GetDeclaredMethod(string name) => GetMethod(name, TypeInfo.DeclaredOnlyLookup);
+ public virtual TypeInfo GetDeclaredNestedType(string name) => GetNestedType(name, TypeInfo.DeclaredOnlyLookup)?.GetTypeInfo();
+ public virtual PropertyInfo GetDeclaredProperty(string name) => GetProperty(name, TypeInfo.DeclaredOnlyLookup);
+
+ public virtual IEnumerable<MethodInfo> GetDeclaredMethods(string name)
+ {
+ foreach (MethodInfo method in GetMethods(TypeInfo.DeclaredOnlyLookup))
+ {
+ if (method.Name == name)
+ yield return method;
+ }
+ }
+
+ public virtual IEnumerable<ConstructorInfo> DeclaredConstructors => GetConstructors(TypeInfo.DeclaredOnlyLookup);
+ public virtual IEnumerable<EventInfo> DeclaredEvents => GetEvents(TypeInfo.DeclaredOnlyLookup);
+ public virtual IEnumerable<FieldInfo> DeclaredFields => GetFields(TypeInfo.DeclaredOnlyLookup);
+ public virtual IEnumerable<MemberInfo> DeclaredMembers => GetMembers(TypeInfo.DeclaredOnlyLookup);
+ public virtual IEnumerable<MethodInfo> DeclaredMethods => GetMethods(TypeInfo.DeclaredOnlyLookup);
+ public virtual IEnumerable<System.Reflection.TypeInfo> DeclaredNestedTypes
+ {
+ get
+ {
+ foreach (Type t in GetNestedTypes(TypeInfo.DeclaredOnlyLookup))
+ {
+ yield return t.GetTypeInfo();
+ }
+ }
+ }
+ public virtual IEnumerable<PropertyInfo> DeclaredProperties => GetProperties(TypeInfo.DeclaredOnlyLookup);
+
+ public virtual IEnumerable<Type> ImplementedInterfaces => GetInterfaces();
+
+ //a re-implementation of ISAF from Type, skipping the use of UnderlyingType
+ public virtual bool IsAssignableFrom(TypeInfo typeInfo)
+ {
+ if (typeInfo == null)
+ return false;
+
+ if (this == typeInfo)
+ return true;
+
+ // If c is a subclass of this class, then c can be cast to this type.
+ if (typeInfo.IsSubclassOf(this))
+ return true;
+
+ if (this.IsInterface)
+ {
+ return typeInfo.ImplementInterface(this);
+ }
+ else if (IsGenericParameter)
+ {
+ Type[] constraints = GetGenericParameterConstraints();
+ for (int i = 0; i < constraints.Length; i++)
+ if (!constraints[i].IsAssignableFrom(typeInfo))
+ return false;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ private const BindingFlags DeclaredOnlyLookup = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
+ }
+}
diff --git a/src/mscorlib/shared/System/ResolveEventArgs.cs b/src/mscorlib/shared/System/ResolveEventArgs.cs
new file mode 100644
index 0000000000..6196947bb5
--- /dev/null
+++ b/src/mscorlib/shared/System/ResolveEventArgs.cs
@@ -0,0 +1,25 @@
+// 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.Reflection;
+
+namespace System
+{
+ public class ResolveEventArgs : EventArgs
+ {
+ public ResolveEventArgs(string name)
+ {
+ Name = name;
+ }
+
+ public ResolveEventArgs(string name, Assembly requestingAssembly)
+ {
+ Name = name;
+ RequestingAssembly = requestingAssembly;
+ }
+
+ public string Name { get; }
+ public Assembly RequestingAssembly { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/ResolveEventHandler.cs b/src/mscorlib/shared/System/ResolveEventHandler.cs
new file mode 100644
index 0000000000..cb9af5de66
--- /dev/null
+++ b/src/mscorlib/shared/System/ResolveEventHandler.cs
@@ -0,0 +1,10 @@
+// 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.Reflection;
+
+namespace System
+{
+ public delegate Assembly ResolveEventHandler(object sender, ResolveEventArgs args);
+}
diff --git a/src/mscorlib/shared/System/Resources/IResourceReader.cs b/src/mscorlib/shared/System/Resources/IResourceReader.cs
new file mode 100644
index 0000000000..543a5a67de
--- /dev/null
+++ b/src/mscorlib/shared/System/Resources/IResourceReader.cs
@@ -0,0 +1,30 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+**
+**
+** Purpose: Abstraction to read streams of resources.
+**
+**
+===========================================================*/
+
+using System;
+using System.Collections;
+
+namespace System.Resources
+{
+ public interface IResourceReader : IEnumerable, IDisposable
+ {
+ // Interface does not need to be marked with the serializable attribute
+ // Closes the ResourceReader, releasing any resources associated with it.
+ // This could close a network connection, a file, or do nothing.
+ void Close();
+
+ new IDictionaryEnumerator GetEnumerator();
+ }
+}
diff --git a/src/mscorlib/shared/System/Resources/MissingManifestResourceException.cs b/src/mscorlib/shared/System/Resources/MissingManifestResourceException.cs
new file mode 100644
index 0000000000..70f41f4d9e
--- /dev/null
+++ b/src/mscorlib/shared/System/Resources/MissingManifestResourceException.cs
@@ -0,0 +1,36 @@
+// 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.Serialization;
+
+namespace System.Resources
+{
+ [Serializable]
+ public class MissingManifestResourceException : SystemException
+ {
+ public MissingManifestResourceException()
+ : base(SR.Arg_MissingManifestResourceException)
+ {
+ HResult = System.__HResults.COR_E_MISSINGMANIFESTRESOURCE;
+ }
+
+ public MissingManifestResourceException(string message)
+ : base(message)
+ {
+ HResult = System.__HResults.COR_E_MISSINGMANIFESTRESOURCE;
+ }
+
+ public MissingManifestResourceException(string message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = System.__HResults.COR_E_MISSINGMANIFESTRESOURCE;
+ }
+
+ protected MissingManifestResourceException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Resources/MissingSatelliteAssemblyException.cs b/src/mscorlib/shared/System/Resources/MissingSatelliteAssemblyException.cs
new file mode 100644
index 0000000000..b343e0cfbc
--- /dev/null
+++ b/src/mscorlib/shared/System/Resources/MissingSatelliteAssemblyException.cs
@@ -0,0 +1,63 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+**
+**
+** Purpose: Exception for a missing satellite assembly needed
+** for ultimate resource fallback. This usually
+** indicates a setup and/or deployment problem.
+**
+**
+===========================================================*/
+
+using System;
+using System.Runtime.Serialization;
+
+namespace System.Resources
+{
+ [Serializable]
+ public class MissingSatelliteAssemblyException : SystemException
+ {
+ private String _cultureName;
+
+ public MissingSatelliteAssemblyException()
+ : base(SR.MissingSatelliteAssembly_Default)
+ {
+ HResult = System.__HResults.COR_E_MISSINGSATELLITEASSEMBLY;
+ }
+
+ public MissingSatelliteAssemblyException(string message)
+ : base(message)
+ {
+ HResult = System.__HResults.COR_E_MISSINGSATELLITEASSEMBLY;
+ }
+
+ public MissingSatelliteAssemblyException(string message, String cultureName)
+ : base(message)
+ {
+ HResult = System.__HResults.COR_E_MISSINGSATELLITEASSEMBLY;
+ _cultureName = cultureName;
+ }
+
+ public MissingSatelliteAssemblyException(string message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = System.__HResults.COR_E_MISSINGSATELLITEASSEMBLY;
+ }
+
+ protected MissingSatelliteAssemblyException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+
+ public String CultureName
+ {
+ get { return _cultureName; }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Resources/NeutralResourcesLanguageAttribute.cs b/src/mscorlib/shared/System/Resources/NeutralResourcesLanguageAttribute.cs
new file mode 100644
index 0000000000..495c5205b2
--- /dev/null
+++ b/src/mscorlib/shared/System/Resources/NeutralResourcesLanguageAttribute.cs
@@ -0,0 +1,33 @@
+// 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.
+
+namespace System.Resources
+{
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
+ public sealed class NeutralResourcesLanguageAttribute : Attribute
+ {
+ public NeutralResourcesLanguageAttribute(string cultureName)
+ {
+ if (cultureName == null)
+ throw new ArgumentNullException(nameof(cultureName));
+
+ CultureName = cultureName;
+ Location = UltimateResourceFallbackLocation.MainAssembly;
+ }
+
+ public NeutralResourcesLanguageAttribute(string cultureName, UltimateResourceFallbackLocation location)
+ {
+ if (cultureName == null)
+ throw new ArgumentNullException(nameof(cultureName));
+ if (!Enum.IsDefined(typeof(UltimateResourceFallbackLocation), location))
+ throw new ArgumentException(SR.Format(SR.Arg_InvalidNeutralResourcesLanguage_FallbackLoc, location));
+
+ CultureName = cultureName;
+ Location = location;
+ }
+
+ public string CultureName { get; }
+ public UltimateResourceFallbackLocation Location { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Resources/ResourceTypeCode.cs b/src/mscorlib/shared/System/Resources/ResourceTypeCode.cs
new file mode 100644
index 0000000000..b0ceb61df4
--- /dev/null
+++ b/src/mscorlib/shared/System/Resources/ResourceTypeCode.cs
@@ -0,0 +1,58 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+**
+**
+** Purpose: Marker for types in .resources files
+**
+**
+===========================================================*/
+
+namespace System.Resources
+{
+ /* An internal implementation detail for .resources files, describing
+ what type an object is.
+ Ranges:
+ 0 - 0x1F Primitives and reserved values
+ 0x20 - 0x3F Specially recognized types, like byte[] and Streams
+
+ Note this data must be included in any documentation describing the
+ internals of .resources files.
+ */
+ internal enum ResourceTypeCode
+ {
+ // Primitives
+ Null = 0,
+ String = 1,
+ Boolean = 2,
+ Char = 3,
+ Byte = 4,
+ SByte = 5,
+ Int16 = 6,
+ UInt16 = 7,
+ Int32 = 8,
+ UInt32 = 9,
+ Int64 = 0xa,
+ UInt64 = 0xb,
+ Single = 0xc,
+ Double = 0xd,
+ Decimal = 0xe,
+ DateTime = 0xf,
+ TimeSpan = 0x10,
+
+ // A meta-value - change this if you add new primitives
+ LastPrimitive = TimeSpan,
+
+ // Types with a special representation, like byte[] and Stream
+ ByteArray = 0x20,
+ Stream = 0x21,
+
+ // User types - serialized using the binary formatter.
+ StartOfUserTypes = 0x40
+ }
+}
diff --git a/src/mscorlib/shared/System/Resources/SatelliteContractVersionAttribute.cs b/src/mscorlib/shared/System/Resources/SatelliteContractVersionAttribute.cs
new file mode 100644
index 0000000000..0707447677
--- /dev/null
+++ b/src/mscorlib/shared/System/Resources/SatelliteContractVersionAttribute.cs
@@ -0,0 +1,31 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+**
+**
+** Purpose: Specifies which version of a satellite assembly
+** the ResourceManager should ask for.
+**
+**
+===========================================================*/
+
+namespace System.Resources
+{
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
+ public sealed class SatelliteContractVersionAttribute : Attribute
+ {
+ public SatelliteContractVersionAttribute(String version)
+ {
+ if (version == null)
+ throw new ArgumentNullException(nameof(version));
+ Version = version;
+ }
+
+ public String Version { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Resources/UltimateResourceFallbackLocation.cs b/src/mscorlib/shared/System/Resources/UltimateResourceFallbackLocation.cs
new file mode 100644
index 0000000000..83640ec9fe
--- /dev/null
+++ b/src/mscorlib/shared/System/Resources/UltimateResourceFallbackLocation.cs
@@ -0,0 +1,25 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+**
+** Purpose: Tells the ResourceManager where to find the
+** ultimate fallback resources for your assembly.
+**
+**
+===========================================================*/
+
+using System;
+
+namespace System.Resources
+{
+ public enum UltimateResourceFallbackLocation
+ {
+ MainAssembly,
+ Satellite
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs
new file mode 100644
index 0000000000..25efcafa3f
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs
@@ -0,0 +1,17 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Field)]
+ public sealed class AccessedThroughPropertyAttribute : Attribute
+ {
+ public AccessedThroughPropertyAttribute(string propertyName)
+ {
+ PropertyName = propertyName;
+ }
+
+ public string PropertyName { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs
new file mode 100644
index 0000000000..198ed3d0e7
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs
@@ -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.
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
+ public sealed class AsyncStateMachineAttribute : StateMachineAttribute
+ {
+ public AsyncStateMachineAttribute(Type stateMachineType)
+ : base(stateMachineType)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/CallerFilePathAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/CallerFilePathAttribute.cs
new file mode 100644
index 0000000000..5858634b42
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/CallerFilePathAttribute.cs
@@ -0,0 +1,14 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ public sealed class CallerFilePathAttribute : Attribute
+ {
+ public CallerFilePathAttribute()
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/CallerLineNumberAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/CallerLineNumberAttribute.cs
new file mode 100644
index 0000000000..5bd2fcb91b
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/CallerLineNumberAttribute.cs
@@ -0,0 +1,14 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ public sealed class CallerLineNumberAttribute : Attribute
+ {
+ public CallerLineNumberAttribute()
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/CallerMemberNameAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/CallerMemberNameAttribute.cs
new file mode 100644
index 0000000000..8b046335b5
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/CallerMemberNameAttribute.cs
@@ -0,0 +1,14 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ public sealed class CallerMemberNameAttribute : Attribute
+ {
+ public CallerMemberNameAttribute()
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/CompilationRelaxations.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/CompilationRelaxations.cs
new file mode 100644
index 0000000000..4da95024c5
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/CompilationRelaxations.cs
@@ -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.
+
+namespace System.Runtime.CompilerServices
+{
+ /// IMPORTANT: Keep this in sync with corhdr.h
+ [Flags]
+ [Serializable]
+ public enum CompilationRelaxations : int
+ {
+ NoStringInterning = 0x0008 // Start in 0x0008, we had other non public flags in this enum before,
+ // so we'll start here just in case somebody used them. This flag is only
+ // valid when set for Assemblies.
+ }
+} \ No newline at end of file
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/CompilationRelaxationsAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/CompilationRelaxationsAttribute.cs
new file mode 100644
index 0000000000..1f100bd415
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/CompilationRelaxationsAttribute.cs
@@ -0,0 +1,23 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Method)]
+ public class CompilationRelaxationsAttribute : Attribute
+ {
+ public CompilationRelaxationsAttribute(int relaxations)
+ {
+ CompilationRelaxations = relaxations;
+ }
+
+ public CompilationRelaxationsAttribute(CompilationRelaxations relaxations)
+ {
+ CompilationRelaxations = (int)relaxations;
+ }
+
+ public int CompilationRelaxations { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs
new file mode 100644
index 0000000000..3da2a95aeb
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs
@@ -0,0 +1,13 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.All, Inherited = true)]
+ public sealed class CompilerGeneratedAttribute : Attribute
+ {
+ public CompilerGeneratedAttribute() { }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs
new file mode 100644
index 0000000000..22fa694200
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs
@@ -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.
+
+namespace System.Runtime.CompilerServices
+{
+ // Attribute used to communicate to the VS7 debugger that a class should be treated as if it has global scope.
+
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Class)]
+ public class CompilerGlobalScopeAttribute : Attribute
+ {
+ public CompilerGlobalScopeAttribute() { }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/DefaultDependencyAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/DefaultDependencyAttribute.cs
new file mode 100644
index 0000000000..f5419d413b
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/DefaultDependencyAttribute.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Assembly)]
+ public sealed class DefaultDependencyAttribute : Attribute
+ {
+ public DefaultDependencyAttribute(LoadHint loadHintArgument)
+ {
+ LoadHint = loadHintArgument;
+ }
+
+ public LoadHint LoadHint { get; }
+ }
+} \ No newline at end of file
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/DependencyAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/DependencyAttribute.cs
new file mode 100644
index 0000000000..56f4242bb1
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/DependencyAttribute.cs
@@ -0,0 +1,20 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
+ public sealed class DependencyAttribute : Attribute
+ {
+ public DependencyAttribute(String dependentAssemblyArgument, LoadHint loadHintArgument)
+ {
+ DependentAssembly = dependentAssemblyArgument;
+ LoadHint = loadHintArgument;
+ }
+
+ public String DependentAssembly { get; }
+ public LoadHint LoadHint { get; }
+ }
+} \ No newline at end of file
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs
new file mode 100644
index 0000000000..4fc00e10ed
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs
@@ -0,0 +1,13 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
+ public sealed class DisablePrivateReflectionAttribute : Attribute
+ {
+ public DisablePrivateReflectionAttribute() { }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/DiscardableAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/DiscardableAttribute.cs
new file mode 100644
index 0000000000..c88b3a7599
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/DiscardableAttribute.cs
@@ -0,0 +1,13 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ // Custom attribute to indicating a TypeDef is a discardable attribute.
+
+ public class DiscardableAttribute : Attribute
+ {
+ public DiscardableAttribute() { }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/ExtensionAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/ExtensionAttribute.cs
new file mode 100644
index 0000000000..92170880f1
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/ExtensionAttribute.cs
@@ -0,0 +1,14 @@
+// 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;
+
+namespace System.Runtime.CompilerServices
+{
+ /// <summary>
+ /// Indicates that a method is an extension method, or that a class or assembly contains extension methods.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
+ public sealed class ExtensionAttribute : Attribute { }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs
new file mode 100644
index 0000000000..baf5824241
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs
@@ -0,0 +1,13 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Field)]
+ public sealed class FixedAddressValueTypeAttribute : Attribute
+ {
+ public FixedAddressValueTypeAttribute() { }
+ }
+} \ No newline at end of file
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/FixedBufferAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/FixedBufferAttribute.cs
new file mode 100644
index 0000000000..bb8f00f686
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/FixedBufferAttribute.cs
@@ -0,0 +1,32 @@
+// 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.
+
+/*============================================================
+**
+**
+** Purpose: Used by a compiler for generating value types
+** in-place within other value types containing a certain
+** number of elements of the given (primitive) type. Somewhat
+** similar to P/Invoke's ByValTStr attribute.
+** Used by C# with this syntax: "fixed int buffer[10];"
+**
+===========================================================*/
+
+using System;
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Field, Inherited = false)]
+ public sealed class FixedBufferAttribute : Attribute
+ {
+ public FixedBufferAttribute(Type elementType, int length)
+ {
+ ElementType = elementType;
+ Length = length;
+ }
+
+ public Type ElementType { get; }
+ public int Length { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/FormattableStringFactory.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/FormattableStringFactory.cs
new file mode 100644
index 0000000000..23d03860ed
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/FormattableStringFactory.cs
@@ -0,0 +1,58 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose: implementation of the FormattableStringFactory
+** class.
+**
+===========================================================*/
+
+namespace System.Runtime.CompilerServices
+{
+ /// <summary>
+ /// A factory type used by compilers to create instances of the type <see cref="FormattableString"/>.
+ /// </summary>
+ public static class FormattableStringFactory
+ {
+ /// <summary>
+ /// Create a <see cref="FormattableString"/> from a composite format string and object
+ /// array containing zero or more objects to format.
+ /// </summary>
+ public static FormattableString Create(string format, params object[] arguments)
+ {
+ if (format == null)
+ {
+ throw new ArgumentNullException(nameof(format));
+ }
+
+ if (arguments == null)
+ {
+ throw new ArgumentNullException(nameof(arguments));
+ }
+
+ return new ConcreteFormattableString(format, arguments);
+ }
+
+ private sealed class ConcreteFormattableString : FormattableString
+ {
+ private readonly string _format;
+ private readonly object[] _arguments;
+
+ internal ConcreteFormattableString(string format, object[] arguments)
+ {
+ _format = format;
+ _arguments = arguments;
+ }
+
+ public override string Format { get { return _format; } }
+ public override object[] GetArguments() { return _arguments; }
+ public override int ArgumentCount { get { return _arguments.Length; } }
+ public override object GetArgument(int index) { return _arguments[index]; }
+ public override string ToString(IFormatProvider formatProvider) { return string.Format(formatProvider, _format, _arguments); }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IAsyncStateMachine.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/IAsyncStateMachine.cs
index 7fb7ea5395..7fb7ea5395 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IAsyncStateMachine.cs
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/IAsyncStateMachine.cs
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/INotifyCompletion.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/INotifyCompletion.cs
index aba0a0691f..aba0a0691f 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/INotifyCompletion.cs
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/INotifyCompletion.cs
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/ITuple.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/ITuple.cs
index cafee11f8a..cafee11f8a 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/ITuple.cs
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/ITuple.cs
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/IndexerNameAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/IndexerNameAttribute.cs
new file mode 100644
index 0000000000..65653a44d9
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/IndexerNameAttribute.cs
@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Property, Inherited = true)]
+ public sealed class IndexerNameAttribute : Attribute
+ {
+ public IndexerNameAttribute(String indexerName)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs
new file mode 100644
index 0000000000..f754694815
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs
@@ -0,0 +1,21 @@
+// 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;
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
+ public sealed class InternalsVisibleToAttribute : Attribute
+ {
+ public InternalsVisibleToAttribute(string assemblyName)
+ {
+ AssemblyName = assemblyName;
+ }
+
+ public string AssemblyName { get; }
+ public bool AllInternalsVisible { get; set; } = true;
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/IsConst.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/IsConst.cs
new file mode 100644
index 0000000000..7f948b608a
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/IsConst.cs
@@ -0,0 +1,10 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ public static partial class IsConst
+ {
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/IsVolatile.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/IsVolatile.cs
new file mode 100644
index 0000000000..fd1c6a1b12
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/IsVolatile.cs
@@ -0,0 +1,12 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ public static class IsVolatile
+ {
+ // no instantiation, please!
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs
new file mode 100644
index 0000000000..5ac3918028
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs
@@ -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.
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
+ public sealed class IteratorStateMachineAttribute : StateMachineAttribute
+ {
+ public IteratorStateMachineAttribute(Type stateMachineType)
+ : base(stateMachineType)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/LoadHint.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/LoadHint.cs
new file mode 100644
index 0000000000..ae6d9b9372
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/LoadHint.cs
@@ -0,0 +1,14 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ public enum LoadHint
+ {
+ Default = 0x0000, // No preference specified
+ Always = 0x0001, // Dependency is always loaded
+ Sometimes = 0x0002, // Dependency is sometimes loaded
+ }
+} \ No newline at end of file
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/MethodCodeType.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/MethodCodeType.cs
new file mode 100644
index 0000000000..e82993a5de
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/MethodCodeType.cs
@@ -0,0 +1,17 @@
+// 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.Reflection;
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ public enum MethodCodeType
+ {
+ IL = MethodImplAttributes.IL,
+ Native = MethodImplAttributes.Native,
+ OPTIL = MethodImplAttributes.OPTIL,
+ Runtime = MethodImplAttributes.Runtime
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/MethodImplOptions.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/MethodImplOptions.cs
new file mode 100644
index 0000000000..2b5affc699
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/MethodImplOptions.cs
@@ -0,0 +1,21 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ // This Enum matchs the miImpl flags defined in corhdr.h. It is used to specify
+ // certain method properties.
+ [Flags]
+ public enum MethodImplOptions
+ {
+ Unmanaged = 0x0004,
+ NoInlining = 0x0008,
+ ForwardRef = 0x0010,
+ Synchronized = 0x0020,
+ NoOptimization = 0x0040,
+ PreserveSig = 0x0080,
+ AggressiveInlining = 0x0100,
+ InternalCall = 0x1000
+ }
+} \ No newline at end of file
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/ReadOnlyAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/ReadOnlyAttribute.cs
new file mode 100644
index 0000000000..aad7310412
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/ReadOnlyAttribute.cs
@@ -0,0 +1,21 @@
+// 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.ComponentModel;
+
+namespace System.Runtime.CompilerServices
+{
+ /// <summary>
+ /// Reserved to be used by the compiler for tracking metadata.
+ /// This attribute should not be used by developers in source code.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [AttributeUsage(AttributeTargets.All, Inherited = false)]
+ public sealed class ReadOnlyAttribute : Attribute
+ {
+ public ReadOnlyAttribute()
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs
new file mode 100644
index 0000000000..6e307e72af
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs
@@ -0,0 +1,33 @@
+// 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.
+
+/*============================================================
+**
+** Attribute: ReferenceAssemblyAttribute
+**
+** Purpose: Identifies an assembly as being a "reference
+** assembly", meaning it contains public surface area but
+** no usable implementation. Reference assemblies
+** should be loadable for introspection, but not execution.
+**
+============================================================*/
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
+ public sealed class ReferenceAssemblyAttribute : Attribute
+ {
+ public ReferenceAssemblyAttribute()
+ {
+ }
+
+ public ReferenceAssemblyAttribute(String description)
+ {
+ Description = description;
+ }
+
+ public String Description { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs
new file mode 100644
index 0000000000..55dba0d113
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs
@@ -0,0 +1,31 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Mark up the program to indicate various legacy or new opt-in behaviors.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)]
+ public sealed class RuntimeCompatibilityAttribute : Attribute
+ {
+ public RuntimeCompatibilityAttribute()
+ {
+ // legacy behavior is the default, and WrapNonExceptionThrows is implicitly
+ // false thanks to the CLR's guarantee of zeroed memory.
+ }
+
+ // If a non-CLSCompliant exception (i.e. one that doesn't derive from System.Exception) is
+ // thrown, should it be wrapped up in a System.Runtime.CompilerServices.RuntimeWrappedException
+ // instance when presented to catch handlers?
+ public bool WrapNonExceptionThrows { get; set; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/RuntimeFeature.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/RuntimeFeature.cs
new file mode 100644
index 0000000000..b93c435439
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/RuntimeFeature.cs
@@ -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.
+
+namespace System.Runtime.CompilerServices
+{
+ public static class RuntimeFeature
+ {
+ /// <summary>
+ /// Checks whether a certain feature is supported by the Runtime.
+ /// </summary>
+ public static bool IsSupported(string feature)
+ {
+ // No features are supported for now.
+ // These features should be added as public static readonly string fields in the same class.
+ return false;
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/SpecialNameAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/SpecialNameAttribute.cs
new file mode 100644
index 0000000000..b18e62895f
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/SpecialNameAttribute.cs
@@ -0,0 +1,12 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Struct)]
+ public sealed class SpecialNameAttribute : Attribute
+ {
+ public SpecialNameAttribute() { }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/StateMachineAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/StateMachineAttribute.cs
new file mode 100644
index 0000000000..94ed5b5c74
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/StateMachineAttribute.cs
@@ -0,0 +1,20 @@
+// 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;
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
+ public class StateMachineAttribute : Attribute
+ {
+ public StateMachineAttribute(Type stateMachineType)
+ {
+ StateMachineType = stateMachineType;
+ }
+
+ public Type StateMachineType { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/StringFreezingAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/StringFreezingAttribute.cs
new file mode 100644
index 0000000000..7772a1a263
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/StringFreezingAttribute.cs
@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Runtime.CompilerServices
+{
+ // Custom attribute to indicate that strings should be frozen.
+
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
+ public sealed class StringFreezingAttribute : Attribute
+ {
+ public StringFreezingAttribute() { }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/StrongBox.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/StrongBox.cs
new file mode 100644
index 0000000000..0a1a565f54
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/StrongBox.cs
@@ -0,0 +1,59 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ /// <summary>
+ /// Holds a reference to a value.
+ /// </summary>
+ /// <typeparam name="T">The type of the value that the <see cref = "StrongBox{T}"></see> references.</typeparam>
+ public class StrongBox<T> : IStrongBox
+ {
+ /// <summary>
+ /// Gets the strongly typed value associated with the <see cref = "StrongBox{T}"></see>
+ /// <remarks>This is explicitly exposed as a field instead of a property to enable loading the address of the field.</remarks>
+ /// </summary>
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")]
+ public T Value;
+
+ /// <summary>
+ /// Initializes a new StrongBox which can receive a value when used in a reference call.
+ /// </summary>
+ public StrongBox()
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new <see cref = "StrongBox{T}"></see> with the specified value.
+ /// </summary>
+ /// <param name="value">A value that the <see cref = "StrongBox{T}"></see> will reference.</param>
+ public StrongBox(T value)
+ {
+ Value = value;
+ }
+
+ object IStrongBox.Value
+ {
+ get
+ {
+ return Value;
+ }
+ set
+ {
+ Value = (T)value;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Defines a property for accessing the value that an object references.
+ /// </summary>
+ public interface IStrongBox
+ {
+ /// <summary>
+ /// Gets or sets the value the object references.
+ /// </summary>
+ object Value { get; set; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs
new file mode 100644
index 0000000000..b4224b1c89
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs
@@ -0,0 +1,13 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module)]
+ public sealed class SuppressIldasmAttribute : Attribute
+ {
+ public SuppressIldasmAttribute() { }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs
new file mode 100644
index 0000000000..ad923dfae5
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs
@@ -0,0 +1,57 @@
+// 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.Collections.Generic;
+
+namespace System.Runtime.CompilerServices
+{
+ /// <summary>
+ /// Indicates that the use of <see cref="System.ValueTuple"/> on a member is meant to be treated as a tuple with element names.
+ /// </summary>
+ [CLSCompliant(false)]
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Event)]
+ public sealed class TupleElementNamesAttribute : Attribute
+ {
+ private readonly string[] _transformNames;
+
+ /// <summary>
+ /// Initializes a new instance of the <see
+ /// cref="TupleElementNamesAttribute"/> class.
+ /// </summary>
+ /// <param name="transformNames">
+ /// Specifies, in a pre-order depth-first traversal of a type's
+ /// construction, which <see cref="System.ValueType"/> occurrences are
+ /// meant to carry element names.
+ /// </param>
+ /// <remarks>
+ /// This constructor is meant to be used on types that contain an
+ /// instantiation of <see cref="System.ValueType"/> that contains
+ /// element names. For instance, if <c>C</c> is a generic type with
+ /// two type parameters, then a use of the constructed type <c>C{<see
+ /// cref="System.ValueTuple{T1, T2}"/>, <see
+ /// cref="System.ValueTuple{T1, T2, T3}"/></c> might be intended to
+ /// treat the first type argument as a tuple with element names and the
+ /// second as a tuple without element names. In which case, the
+ /// appropriate attribute specification should use a
+ /// <c>transformNames</c> value of <c>{ "name1", "name2", null, null,
+ /// null }</c>.
+ /// </remarks>
+ public TupleElementNamesAttribute(string[] transformNames)
+ {
+ if (transformNames == null)
+ {
+ throw new ArgumentNullException(nameof(transformNames));
+ }
+
+ _transformNames = transformNames;
+ }
+
+ /// <summary>
+ /// Specifies, in a pre-order depth-first traversal of a type's
+ /// construction, which <see cref="System.ValueTuple"/> elements are
+ /// meant to carry element names.
+ /// </summary>
+ public IList<string> TransformNames => _transformNames;
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs
new file mode 100644
index 0000000000..c4a8558243
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs
@@ -0,0 +1,17 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
+ public sealed class TypeForwardedFromAttribute : Attribute
+ {
+ public TypeForwardedFromAttribute(string assemblyFullName)
+ {
+ AssemblyFullName = assemblyFullName;
+ }
+
+ public string AssemblyFullName { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs
new file mode 100644
index 0000000000..85d5c030c1
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs
@@ -0,0 +1,17 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
+ public sealed class TypeForwardedToAttribute : Attribute
+ {
+ public TypeForwardedToAttribute(Type destination)
+ {
+ Destination = destination;
+ }
+
+ public Type Destination { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs b/src/mscorlib/shared/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs
new file mode 100644
index 0000000000..162676efe8
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs
@@ -0,0 +1,12 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Struct)]
+ sealed public class UnsafeValueTypeAttribute : Attribute
+ {
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/ConstrainedExecution/Cer.cs b/src/mscorlib/shared/System/Runtime/ConstrainedExecution/Cer.cs
new file mode 100644
index 0000000000..c142ec9ecc
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/ConstrainedExecution/Cer.cs
@@ -0,0 +1,14 @@
+// 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.
+
+namespace System.Runtime.ConstrainedExecution
+{
+ [Serializable]
+ public enum Cer : int
+ {
+ None = 0,
+ MayFail = 1, // Might fail, but the method will say it failed
+ Success = 2,
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/ConstrainedExecution/Consistency.cs b/src/mscorlib/shared/System/Runtime/ConstrainedExecution/Consistency.cs
new file mode 100644
index 0000000000..7ee8480e89
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/ConstrainedExecution/Consistency.cs
@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Runtime.ConstrainedExecution
+{
+ [Serializable]
+ public enum Consistency : int
+ {
+ MayCorruptProcess = 0,
+ MayCorruptAppDomain = 1,
+ MayCorruptInstance = 2,
+ WillNotCorruptState = 3,
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/ConstrainedExecution/ReliabilityContractAttribute.cs b/src/mscorlib/shared/System/Runtime/ConstrainedExecution/ReliabilityContractAttribute.cs
new file mode 100644
index 0000000000..b3cb0143fa
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/ConstrainedExecution/ReliabilityContractAttribute.cs
@@ -0,0 +1,33 @@
+// 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.
+
+//
+/*============================================================
+**
+**
+**
+** Purpose: Defines a publically documentable contract for
+** reliability between a method and its callers, expressing
+** what state will remain consistent in the presence of
+** failures (ie async exceptions like thread abort) and whether
+** the method needs to be called from within a CER.
+**
+**
+===========================================================*/
+
+namespace System.Runtime.ConstrainedExecution
+{
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Interface /* | AttributeTargets.Delegate*/, Inherited = false)]
+ public sealed class ReliabilityContractAttribute : Attribute
+ {
+ public ReliabilityContractAttribute(Consistency consistencyGuarantee, Cer cer)
+ {
+ ConsistencyGuarantee = consistencyGuarantee;
+ Cer = cer;
+ }
+
+ public Consistency ConsistencyGuarantee { get; }
+ public Cer Cer { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/InteropServices/CallingConvention.cs b/src/mscorlib/shared/System/Runtime/InteropServices/CallingConvention.cs
new file mode 100644
index 0000000000..3b18fdee3a
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/InteropServices/CallingConvention.cs
@@ -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.
+
+namespace System.Runtime.InteropServices
+{
+ // Used for the CallingConvention named argument to the DllImport and NativeCallable attribute
+ public enum CallingConvention
+ {
+ Winapi = 1,
+ Cdecl = 2,
+ StdCall = 3,
+ ThisCall = 4,
+ FastCall = 5,
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/InteropServices/CharSet.cs b/src/mscorlib/shared/System/Runtime/InteropServices/CharSet.cs
new file mode 100644
index 0000000000..d587ec006b
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/InteropServices/CharSet.cs
@@ -0,0 +1,21 @@
+// 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.
+
+namespace System.Runtime.InteropServices
+{
+ // Use this in P/Invoke function prototypes to specify
+ // which character set to use when marshalling Strings.
+ // Using Ansi will marshal the strings as 1 byte char*'s.
+ // Using Unicode will marshal the strings as 2 byte wchar*'s.
+ // Generally you probably want to use Auto, which does the
+ // right thing 99% of the time.
+
+ public enum CharSet
+ {
+ None = 1, // User didn't specify how to marshal strings.
+ Ansi = 2, // Strings should be marshalled as ANSI 1 byte chars.
+ Unicode = 3, // Strings should be marshalled as Unicode 2 byte chars.
+ Auto = 4, // Marshal Strings in the right way for the target system.
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/InteropServices/ComVisibleAttribute.cs b/src/mscorlib/shared/System/Runtime/InteropServices/ComVisibleAttribute.cs
new file mode 100644
index 0000000000..84b9505a5a
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/InteropServices/ComVisibleAttribute.cs
@@ -0,0 +1,17 @@
+// 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.
+
+namespace System.Runtime.InteropServices
+{
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Delegate | AttributeTargets.Enum | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, Inherited = false)]
+ public sealed class ComVisibleAttribute : Attribute
+ {
+ public ComVisibleAttribute(bool visibility)
+ {
+ Value = visibility;
+ }
+
+ public bool Value { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/InteropServices/ExternalException.cs b/src/mscorlib/shared/System/Runtime/InteropServices/ExternalException.cs
new file mode 100644
index 0000000000..d7bde79c43
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/InteropServices/ExternalException.cs
@@ -0,0 +1,89 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Exception base class for all errors from Interop or Structured
+** Exception Handling code.
+**
+**
+=============================================================================*/
+
+using System;
+using System.Globalization;
+using System.Runtime.Serialization;
+
+namespace System.Runtime.InteropServices
+{
+ // Base exception for COM Interop errors &; Structured Exception Handler
+ // exceptions.
+ //
+ [Serializable]
+ public class ExternalException : SystemException
+ {
+ public ExternalException()
+ : base(SR.Arg_ExternalException)
+ {
+ HResult = __HResults.E_FAIL;
+ }
+
+ public ExternalException(string message)
+ : base(message)
+ {
+ HResult = __HResults.E_FAIL;
+ }
+
+ public ExternalException(string message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.E_FAIL;
+ }
+
+ public ExternalException(string message, int errorCode)
+ : base(message)
+ {
+ HResult = errorCode;
+ }
+
+ protected ExternalException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+
+ public virtual int ErrorCode
+ {
+ get
+ {
+ return HResult;
+ }
+ }
+
+ public override string ToString()
+ {
+ string message = Message;
+ string className = GetType().ToString();
+
+ string s = className + " (0x" + HResult.ToString("X8", CultureInfo.InvariantCulture) + ")";
+
+ if (!(String.IsNullOrEmpty(message)))
+ {
+ s = s + ": " + message;
+ }
+
+ Exception innerException = InnerException;
+
+ if (innerException != null)
+ {
+ s = s + " ---> " + innerException.ToString();
+ }
+
+ if (StackTrace != null)
+ s += Environment.NewLine + StackTrace;
+
+ return s;
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/InteropServices/LayoutKind.cs b/src/mscorlib/shared/System/Runtime/InteropServices/LayoutKind.cs
new file mode 100644
index 0000000000..dbd7ec62d5
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/InteropServices/LayoutKind.cs
@@ -0,0 +1,14 @@
+// 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.
+
+namespace System.Runtime.InteropServices
+{
+ // Used in the StructLayoutAttribute class
+ public enum LayoutKind
+ {
+ Sequential = 0,
+ Explicit = 2,
+ Auto = 3,
+ }
+}
diff --git a/src/mscorlib/corefx/System/Runtime/InteropServices/StringBuffer.cs b/src/mscorlib/shared/System/Runtime/InteropServices/StringBuffer.cs
index fdd0b95590..fdd0b95590 100644
--- a/src/mscorlib/corefx/System/Runtime/InteropServices/StringBuffer.cs
+++ b/src/mscorlib/shared/System/Runtime/InteropServices/StringBuffer.cs
diff --git a/src/mscorlib/shared/System/Runtime/InteropServices/UnmanagedFunctionPointerAttribute.cs b/src/mscorlib/shared/System/Runtime/InteropServices/UnmanagedFunctionPointerAttribute.cs
new file mode 100644
index 0000000000..2d69c95afe
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/InteropServices/UnmanagedFunctionPointerAttribute.cs
@@ -0,0 +1,27 @@
+// 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.
+
+namespace System.Runtime.InteropServices
+{
+ [AttributeUsage(AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
+ public sealed class UnmanagedFunctionPointerAttribute : Attribute
+ {
+ public bool BestFitMapping;
+ public bool SetLastError;
+ public bool ThrowOnUnmappableChar;
+ public CharSet CharSet;
+
+ public UnmanagedFunctionPointerAttribute()
+ {
+ CallingConvention = CallingConvention.Winapi;
+ }
+
+ public UnmanagedFunctionPointerAttribute(CallingConvention callingConvention)
+ {
+ CallingConvention = callingConvention;
+ }
+
+ public CallingConvention CallingConvention { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/InteropServices/UnmanagedType.cs b/src/mscorlib/shared/System/Runtime/InteropServices/UnmanagedType.cs
new file mode 100644
index 0000000000..4deca7fe0c
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/InteropServices/UnmanagedType.cs
@@ -0,0 +1,48 @@
+// 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.
+
+namespace System.Runtime.InteropServices
+{
+ public enum UnmanagedType
+ {
+ Bool = 0x2, // 4 byte boolean value (true != 0, false == 0)
+ I1 = 0x3, // 1 byte signed value
+ U1 = 0x4, // 1 byte unsigned value
+ I2 = 0x5, // 2 byte signed value
+ U2 = 0x6, // 2 byte unsigned value
+ I4 = 0x7, // 4 byte signed value
+ U4 = 0x8, // 4 byte unsigned value
+ I8 = 0x9, // 8 byte signed value
+ U8 = 0xa, // 8 byte unsigned value
+ R4 = 0xb, // 4 byte floating point
+ R8 = 0xc, // 8 byte floating point
+ Currency = 0xf, // A currency
+ BStr = 0x13, // OLE Unicode BSTR
+ LPStr = 0x14, // Ptr to SBCS string
+ LPWStr = 0x15, // Ptr to Unicode string
+ LPTStr = 0x16, // Ptr to OS preferred (SBCS/Unicode) string
+ ByValTStr = 0x17, // OS preferred (SBCS/Unicode) inline string (only valid in structs)
+ IUnknown = 0x19, // COM IUnknown pointer.
+ IDispatch = 0x1a, // COM IDispatch pointer
+ Struct = 0x1b, // Structure
+ Interface = 0x1c, // COM interface
+ SafeArray = 0x1d, // OLE SafeArray
+ ByValArray = 0x1e, // Array of fixed size (only valid in structs)
+ SysInt = 0x1f, // Hardware natural sized signed integer
+ SysUInt = 0x20,
+ VBByRefStr = 0x22,
+ AnsiBStr = 0x23, // OLE BSTR containing SBCS characters
+ TBStr = 0x24, // Ptr to OS preferred (SBCS/Unicode) BSTR
+ VariantBool = 0x25, // OLE defined BOOLEAN (2 bytes, true == -1, false == 0)
+ FunctionPtr = 0x26, // Function pointer
+ AsAny = 0x28, // Paired with Object type and does runtime marshalling determination
+ LPArray = 0x2a, // C style array
+ LPStruct = 0x2b, // Pointer to a structure
+ CustomMarshaler = 0x2c,
+ Error = 0x2d,
+ IInspectable = 0x2e,
+ HString = 0x2f, // Windows Runtime HSTRING
+ LPUTF8Str = 0x30, // UTF8 string
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/InteropServices/VarEnum.cs b/src/mscorlib/shared/System/Runtime/InteropServices/VarEnum.cs
new file mode 100644
index 0000000000..495aeca6d1
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/InteropServices/VarEnum.cs
@@ -0,0 +1,54 @@
+// 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.
+
+namespace System.Runtime.InteropServices
+{
+ public enum VarEnum
+ {
+ VT_EMPTY = 0,
+ VT_NULL = 1,
+ VT_I2 = 2,
+ VT_I4 = 3,
+ VT_R4 = 4,
+ VT_R8 = 5,
+ VT_CY = 6,
+ VT_DATE = 7,
+ VT_BSTR = 8,
+ VT_DISPATCH = 9,
+ VT_ERROR = 10,
+ VT_BOOL = 11,
+ VT_VARIANT = 12,
+ VT_UNKNOWN = 13,
+ VT_DECIMAL = 14,
+ VT_I1 = 16,
+ VT_UI1 = 17,
+ VT_UI2 = 18,
+ VT_UI4 = 19,
+ VT_I8 = 20,
+ VT_UI8 = 21,
+ VT_INT = 22,
+ VT_UINT = 23,
+ VT_VOID = 24,
+ VT_HRESULT = 25,
+ VT_PTR = 26,
+ VT_SAFEARRAY = 27,
+ VT_CARRAY = 28,
+ VT_USERDEFINED = 29,
+ VT_LPSTR = 30,
+ VT_LPWSTR = 31,
+ VT_RECORD = 36,
+ VT_FILETIME = 64,
+ VT_BLOB = 65,
+ VT_STREAM = 66,
+ VT_STORAGE = 67,
+ VT_STREAMED_OBJECT = 68,
+ VT_STORED_OBJECT = 69,
+ VT_BLOB_OBJECT = 70,
+ VT_CF = 71,
+ VT_CLSID = 72,
+ VT_VECTOR = 0x1000,
+ VT_ARRAY = 0x2000,
+ VT_BYREF = 0x4000
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Serialization/IDeserializationCallback.cs b/src/mscorlib/shared/System/Runtime/Serialization/IDeserializationCallback.cs
new file mode 100644
index 0000000000..a1c1671a8b
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Serialization/IDeserializationCallback.cs
@@ -0,0 +1,11 @@
+// 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.
+
+namespace System.Runtime.Serialization
+{
+ public interface IDeserializationCallback
+ {
+ void OnDeserialization(object sender);
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Serialization/IFormatterConverter.cs b/src/mscorlib/shared/System/Runtime/Serialization/IFormatterConverter.cs
new file mode 100644
index 0000000000..c173144854
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Serialization/IFormatterConverter.cs
@@ -0,0 +1,28 @@
+// 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.
+
+namespace System.Runtime.Serialization
+{
+ [CLSCompliant(false)]
+ public interface IFormatterConverter
+ {
+ object Convert(object value, Type type);
+ object Convert(object value, TypeCode typeCode);
+ bool ToBoolean(object value);
+ char ToChar(object value);
+ sbyte ToSByte(object value);
+ byte ToByte(object value);
+ short ToInt16(object value);
+ ushort ToUInt16(object value);
+ int ToInt32(object value);
+ uint ToUInt32(object value);
+ long ToInt64(object value);
+ ulong ToUInt64(object value);
+ float ToSingle(object value);
+ double ToDouble(object value);
+ decimal ToDecimal(object value);
+ DateTime ToDateTime(object value);
+ string ToString(object value);
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Serialization/IObjectReference.cs b/src/mscorlib/shared/System/Runtime/Serialization/IObjectReference.cs
new file mode 100644
index 0000000000..d41bc50dde
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Serialization/IObjectReference.cs
@@ -0,0 +1,11 @@
+// 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.
+
+namespace System.Runtime.Serialization
+{
+ public interface IObjectReference
+ {
+ object GetRealObject(StreamingContext context);
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Serialization/ISafeSerializationData.cs b/src/mscorlib/shared/System/Runtime/Serialization/ISafeSerializationData.cs
new file mode 100644
index 0000000000..5089d134c3
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Serialization/ISafeSerializationData.cs
@@ -0,0 +1,207 @@
+// 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.
+
+namespace System.Runtime.Serialization
+{
+ //
+ // #SafeSerialization
+ //
+ // Types which are serializable via the ISerializable interface have a problem when it comes to allowing
+ // transparent subtypes which can allow themselves to serialize since the GetObjectData method is
+ // SecurityCritical.
+ //
+ // For instance, System.Exception implements ISerializable, however it is also desirable to have
+ // transparent exceptions with their own fields that need to be serialized. (For instance, in transparent
+ // assemblies such as the DLR and F#, or even in partial trust application code). Since overriding
+ // GetObjectData requires that the overriding method be security critical, this won't work directly.
+ //
+ // SafeSerializationManager solves this problem by allowing any partial trust code to contribute
+ // individual chunks of serializable data to be included in the serialized version of the derived class.
+ // These chunks are then deserialized back out of the serialized type and notified that they should
+ // populate the fields of the deserialized object when serialization is complete. This allows partial
+ // trust or transparent code to participate in serialization of an ISerializable type without having to
+ // override GetObjectData or implement the ISerializable constructor.
+ //
+ // On the serialization side, SafeSerializationManager has an event SerializeObjectState which it will
+ // fire in response to serialization in order to gather the units of serializable data that should be
+ // stored with the rest of the object during serialization. Methods which respond to these events
+ // create serializable objects which implement the ISafeSerializationData interface and add them to the
+ // collection of other serialized data by calling AddSerializedState on the SafeSerializationEventArgs
+ // passed into the event.
+ //
+ // By using an event rather than a virtual method on the base ISerializable object, we allow multiple
+ // potentially untrusted subclasses to participate in serialization, without each one having to ensure
+ // that it calls up to the base type in order for the whole system to work. (For instance Exception :
+ // TrustedException : UntrustedException, in this scenario UntrustedException would be able to override
+ // the virtual method an prevent TrustedException from ever seeing the method call, either accidentally
+ // or maliciously).
+ //
+ // Further, by only allowing additions of new chunks of serialization state rather than exposing the
+ // whole underlying list, we avoid exposing potentially sensitive serialized state to any of the
+ // potentially untrusted subclasses.
+ //
+ // At deserialization time, SafeSerializationManager performs the reverse operation. It deserializes the
+ // chunks of serialized state, and then notifies them that the object they belong to is deserialized by
+ // calling their CompleteSerialization method. In repsonse to this call, the state objects populate the
+ // fields of the object being deserialized with the state that they held.
+ //
+ // From a security perspective, the chunks of serialized state can only contain data that the specific
+ // subclass itself had access to read (otherwise it wouldn't be able to populate the type with that
+ // data), as opposed to having access to far more data in the SerializationInfo that GetObjectData uses.
+ // Similarly, at deserialization time, the serialized state can only modify fields that the type itself
+ // has access to (again, as opposed to the full SerializationInfo which could be modified).
+ //
+ // Individual types which wish to participate in safe serialization do so by containing an instance of a
+ // SafeSerializationManager and exposing its serialization event. During GetObjectData, the
+ // SafeSerializationManager is serialized just like any other field of the containing type. However, at
+ // the end of serialization it is called back one last time to CompleteSerialization.
+ //
+ // In CompleteSerialization, if the SafeSerializationManager detects that it has extra chunks of
+ // data to handle, it substitutes the root type being serialized (formerly the real type hosting the
+ // SafeSerializationManager) with itself. This allows it to gain more control over the deserialization
+ // process. It also saves away an extra bit of state in the serialization info indicating the real type
+ // of object that should be recreated during deserialization.
+ //
+ // At this point the serialized state looks like this:
+ // Data:
+ // realSerializedData1
+ // ...
+ // realSerializedDataN
+ // safeSerializationData -> this is the serialization data member of the parent type
+ // _serializedState -> list of saved serialized states from subclasses responding to the safe
+ // serialization event
+ // RealTypeSerializationName -> type which is using safe serialization
+ // Type:
+ // SafeSerializationManager
+ //
+ // That is, the serialized data claims to be of type SafeSerializationManager, however contains only the
+ // data from the real object being serialized along with one bit of safe serialization metadata.
+ //
+ // At deserialization time, since the serialized data claims to be of type SafeSerializationManager, the
+ // root object being created is an instance of the SafeSerializationManager class. However, it detects
+ // that this isn't a real SafeSerializationManager (by looking for the real type field in the metadata),
+ // and simply saves away the SerializationInfo and the real type being deserialized.
+ //
+ // Since SafeSerializationManager implements IObjectReference, the next step of deserialization is the
+ // GetRealObject callback. This callback is the one responsible for getting the
+ // SafeSerializationManager out of the way and instead creating an instance of the actual type which was
+ // serialized.
+ //
+ // It does this by first creating an instance of the real type being deserialzed (saved away in the
+ // deserialzation constructor), but not running any of its constructors. Instead, it walks the
+ // inheritance hierarchy (moving toward the most derived type) looking for the last full trust type to
+ // implement the standard ISerializable constructor before any type does not implement the constructor.
+ // It is this last type's deserialization constructor which is then invoked, passing in the saved
+ // SerializationInfo. Once the constructors are run, we return this object as the real deserialized
+ // object.
+ //
+ // The reason that we do this walk is so that ISerializable types can protect themselves from malicious
+ // input during deserialization by making their deserialization constructors unavailable to partial
+ // trust code. By not requiring every type have a copy of this constructor, partial trust code can
+ // participate in safe serialization and not be required to have access to the parent's constructor.
+ //
+ // It should be noted however, that this heuristic means that if a full trust type does derive from
+ // a transparent or partial trust type using this safe serialization mechanism, that full trust type
+ // will not have its constructor called. Further, the protection of not invoking partial trust
+ // deserialization constructors only comes into play if SafeSerializationManager is in control of
+ // deserialization, which means there must be at least one (even empty) safe serialization event
+ // handler registered.
+ //
+ // Another interesting note is that at this point there are now two SafeSerializationManagers alive for
+ // this deserialization. The first object is the one which is controlling the deserialization and was
+ // created as the root object of the deserialization. The second one is the object which contains the
+ // serialized data chunks and is a data member of the real object being deserialized. For this reason,
+ // the data objects cannot be notified that the deserialization is complete during GetRealObject since
+ // the ISafeSerializationData objects are not members of the active SafeSerializationManager instance.
+ //
+ // The next step is the OnDeserialized callback, which comes to SafeSerializableObject since it was
+ // pretending to be the root object of the deserialization. It responds to this callback by calling
+ // any existing OnDeserialized callback on the real type that was deserialized.
+ //
+ // The real type needs to call its data member SafeSerializationData object's CompleteDeserialization
+ // method in response to the OnDeserialized call. This CompleteDeserialization call will then iterate
+ // through the ISafeSerializationData objects calling each of their CompleteDeserialization methods so
+ // that they can plug the nearly-complete object with their saved data.
+ //
+ // The reason for having a new ISafeSerializationData interface which is basically identical to
+ // IDeserializationCallback is that IDeserializationCallback will be called on the stored data chunks
+ // by the serialization code when they are deserialized, and that's not a desirable behavior.
+ // Essentially, we need to change the meaning of the object parameter to mean "parent object which
+ // participated in safe serialization", rather than "this object".
+ //
+ // Implementing safe serialization on an ISerialiable type is relatively straight forward. (For an
+ // example, see System.Exception):
+ //
+ // 1. Include a data member of type SafeSerializationManager:
+ //
+ // private SafeSerializationManager _safeSerializationManager;
+ //
+ // 2. Add a protected SerializeObjectState event, which passes through to the SafeSerializationManager:
+ //
+ // protected event EventHandler<SafeSerializationEventArgs> SerializeObjectState
+ // {
+ // add { _safeSerializationManager.SerializeObjectState += value; }
+ // remove { _safeSerializationManager.SerializeObjectState -= value; }
+ // }
+ //
+ // 3. Serialize the safe serialization object in GetObjectData, and call its CompleteSerialization method:
+ //
+ // {
+ // info.AddValue("_safeSerializationManager", _safeSerializationManager, typeof(SafeSerializationManager));
+ // _safeSerializationManager.CompleteSerialization(this, info, context);
+ // }
+ //
+ // 4. Add an OnDeserialized handler if one doesn't already exist, and call CompleteDeserialization in it:
+ //
+ // [OnDeserialized]
+ // private void OnDeserialized(StreamingContext context)
+ // {
+ // _safeSerializationManager.CompleteDeserialization(this);
+ // }
+ //
+ // On the client side, using safe serialization is also pretty easy. For example:
+ //
+ // [Serializable]
+ // public class TransparentException : Exception
+ // {
+ // [Serializable]
+ // private struct TransparentExceptionState : ISafeSerializationData
+ // {
+ // public string _extraData;
+ //
+ // void ISafeSerializationData.CompleteDeserialization(object obj)
+ // {
+ // TransparentException exception = obj as TransparentException;
+ // exception._state = this;
+ // }
+ // }
+ //
+ // [NonSerialized]
+ // private TransparentExceptionState _state = new TransparentExceptionState();
+ //
+ // public TransparentException()
+ // {
+ // SerializeObjectState += delegate(object exception, SafeSerializationEventArgs eventArgs)
+ // {
+ // eventArgs.AddSerializedState(_state);
+ // };
+ // }
+ //
+ // public string ExtraData
+ // {
+ // get { return _state._extraData; }
+ // set { _state._extraData = value; }
+ // }
+ // }
+ //
+
+ // Interface to be supported by objects which are stored in safe serialization stores
+ public interface ISafeSerializationData
+ {
+ // CompleteDeserialization is called when the object to which the extra serialized data was attached
+ // has completed its deserialization, and now needs to be populated with the extra data stored in
+ // this object.
+ void CompleteDeserialization(object deserialized);
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Serialization/ISerializable.cs b/src/mscorlib/shared/System/Runtime/Serialization/ISerializable.cs
new file mode 100644
index 0000000000..383b3f07af
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Serialization/ISerializable.cs
@@ -0,0 +1,11 @@
+// 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.
+
+namespace System.Runtime.Serialization
+{
+ public interface ISerializable
+ {
+ void GetObjectData(SerializationInfo info, StreamingContext context);
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Serialization/OnDeserializedAttribute.cs b/src/mscorlib/shared/System/Runtime/Serialization/OnDeserializedAttribute.cs
new file mode 100644
index 0000000000..408a55ccf9
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Serialization/OnDeserializedAttribute.cs
@@ -0,0 +1,11 @@
+// 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.
+
+namespace System.Runtime.Serialization
+{
+ [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+ public sealed class OnDeserializedAttribute : Attribute
+ {
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Serialization/OnDeserializingAttribute.cs b/src/mscorlib/shared/System/Runtime/Serialization/OnDeserializingAttribute.cs
new file mode 100644
index 0000000000..162857e8d3
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Serialization/OnDeserializingAttribute.cs
@@ -0,0 +1,11 @@
+// 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.
+
+namespace System.Runtime.Serialization
+{
+ [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+ public sealed class OnDeserializingAttribute : Attribute
+ {
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Serialization/OnSerializedAttribute.cs b/src/mscorlib/shared/System/Runtime/Serialization/OnSerializedAttribute.cs
new file mode 100644
index 0000000000..020dd0257c
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Serialization/OnSerializedAttribute.cs
@@ -0,0 +1,11 @@
+// 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.
+
+namespace System.Runtime.Serialization
+{
+ [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+ public sealed class OnSerializedAttribute : Attribute
+ {
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Serialization/OnSerializingAttribute.cs b/src/mscorlib/shared/System/Runtime/Serialization/OnSerializingAttribute.cs
new file mode 100644
index 0000000000..8dc8af3f23
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Serialization/OnSerializingAttribute.cs
@@ -0,0 +1,11 @@
+// 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.
+
+namespace System.Runtime.Serialization
+{
+ [AttributeUsage(AttributeTargets.Method, Inherited = false)]
+ public sealed class OnSerializingAttribute : Attribute
+ {
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Serialization/OptionalFieldAttribute.cs b/src/mscorlib/shared/System/Runtime/Serialization/OptionalFieldAttribute.cs
new file mode 100644
index 0000000000..84daa539be
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Serialization/OptionalFieldAttribute.cs
@@ -0,0 +1,25 @@
+// 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.
+
+namespace System.Runtime.Serialization
+{
+ [AttributeUsage(AttributeTargets.Field, Inherited = false)]
+ public sealed class OptionalFieldAttribute : Attribute
+ {
+ private int _versionAdded = 1;
+
+ public int VersionAdded
+ {
+ get { return _versionAdded; }
+ set
+ {
+ if (value < 1)
+ {
+ throw new ArgumentException(SR.Serialization_OptionalFieldVersionValue);
+ }
+ _versionAdded = value;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Serialization/SafeSerializationEventArgs.cs b/src/mscorlib/shared/System/Runtime/Serialization/SafeSerializationEventArgs.cs
new file mode 100644
index 0000000000..896b91fca0
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Serialization/SafeSerializationEventArgs.cs
@@ -0,0 +1,31 @@
+// 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.Collections.Generic;
+
+namespace System.Runtime.Serialization
+{
+ // SafeSerializationEventArgs are provided to the delegates which do safe serialization. Each delegate
+ // serializes its own state into an IDeserializationCallback instance which must, itself, be serializable.
+ // These indivdiual states are then added to the SafeSerializationEventArgs in order to be saved away when
+ // the original ISerializable type is serialized.
+ public sealed class SafeSerializationEventArgs : EventArgs
+ {
+ private readonly List<object> _serializedStates = new List<object>();
+
+ internal SafeSerializationEventArgs() { }
+
+ public void AddSerializedState(ISafeSerializationData serializedState)
+ {
+ if (serializedState == null)
+ throw new ArgumentNullException(nameof(serializedState));
+ if (!serializedState.GetType().IsSerializable)
+ throw new ArgumentException(SR.Format(SR.Serialization_NonSerType, serializedState.GetType(), serializedState.GetType().Assembly.FullName));
+
+ _serializedStates.Add(serializedState);
+ }
+
+ public StreamingContext StreamingContext { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Serialization/SerializationException.cs b/src/mscorlib/shared/System/Runtime/Serialization/SerializationException.cs
new file mode 100644
index 0000000000..a359daf4f9
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Serialization/SerializationException.cs
@@ -0,0 +1,39 @@
+// 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.Runtime.Serialization;
+
+namespace System.Runtime.Serialization
+{
+ [Serializable]
+ public class SerializationException : SystemException
+ {
+ private static String s_nullMessage = SR.SerializationException;
+
+ // Creates a new SerializationException with its message
+ // string set to a default message.
+ public SerializationException()
+ : base(s_nullMessage)
+ {
+ HResult = __HResults.COR_E_SERIALIZATION;
+ }
+
+ public SerializationException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_SERIALIZATION;
+ }
+
+ public SerializationException(String message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_SERIALIZATION;
+ }
+
+ protected SerializationException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Serialization/SerializationInfoEnumerator.cs b/src/mscorlib/shared/System/Runtime/Serialization/SerializationInfoEnumerator.cs
new file mode 100644
index 0000000000..6399510736
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Serialization/SerializationInfoEnumerator.cs
@@ -0,0 +1,127 @@
+// 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.Collections;
+using System.Diagnostics;
+
+namespace System.Runtime.Serialization
+{
+ public struct SerializationEntry
+ {
+ private string _name;
+ private object _value;
+ private Type _type;
+
+ internal SerializationEntry(string entryName, object entryValue, Type entryType)
+ {
+ _name = entryName;
+ _value = entryValue;
+ _type = entryType;
+ }
+
+ public object Value => _value;
+ public string Name => _name;
+ public Type ObjectType => _type;
+ }
+
+ public sealed class SerializationInfoEnumerator : IEnumerator
+ {
+ private readonly string[] _members;
+ private readonly object[] _data;
+ private readonly Type[] _types;
+ private readonly int _numItems;
+ private int _currItem;
+ private bool _current;
+
+ internal SerializationInfoEnumerator(string[] members, object[] info, Type[] types, int numItems)
+ {
+ Debug.Assert(members != null, "[SerializationInfoEnumerator.ctor]members!=null");
+ Debug.Assert(info != null, "[SerializationInfoEnumerator.ctor]info!=null");
+ Debug.Assert(types != null, "[SerializationInfoEnumerator.ctor]types!=null");
+ Debug.Assert(numItems >= 0, "[SerializationInfoEnumerator.ctor]numItems>=0");
+ Debug.Assert(members.Length >= numItems, "[SerializationInfoEnumerator.ctor]members.Length>=numItems");
+ Debug.Assert(info.Length >= numItems, "[SerializationInfoEnumerator.ctor]info.Length>=numItems");
+ Debug.Assert(types.Length >= numItems, "[SerializationInfoEnumerator.ctor]types.Length>=numItems");
+
+ _members = members;
+ _data = info;
+ _types = types;
+
+ //The MoveNext semantic is much easier if we enforce that [0..m_numItems] are valid entries
+ //in the enumerator, hence we subtract 1.
+ _numItems = numItems - 1;
+ _currItem = -1;
+ _current = false;
+ }
+
+ public bool MoveNext()
+ {
+ if (_currItem < _numItems)
+ {
+ _currItem++;
+ _current = true;
+ }
+ else
+ {
+ _current = false;
+ }
+
+ return _current;
+ }
+
+ object IEnumerator.Current => Current;
+
+ public SerializationEntry Current
+ {
+ get
+ {
+ if (_current == false)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
+ }
+ return new SerializationEntry(_members[_currItem], _data[_currItem], _types[_currItem]);
+ }
+ }
+
+ public void Reset()
+ {
+ _currItem = -1;
+ _current = false;
+ }
+
+ public string Name
+ {
+ get
+ {
+ if (_current == false)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
+ }
+ return _members[_currItem];
+ }
+ }
+ public object Value
+ {
+ get
+ {
+ if (_current == false)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
+ }
+ return _data[_currItem];
+ }
+ }
+ public Type ObjectType
+ {
+ get
+ {
+ if (_current == false)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
+ }
+ return _types[_currItem];
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Serialization/StreamingContext.cs b/src/mscorlib/shared/System/Runtime/Serialization/StreamingContext.cs
new file mode 100644
index 0000000000..1026a87d1e
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Serialization/StreamingContext.cs
@@ -0,0 +1,53 @@
+// 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.
+
+namespace System.Runtime.Serialization
+{
+ [Serializable]
+ public struct StreamingContext
+ {
+ private readonly object _additionalContext;
+ private readonly StreamingContextStates _state;
+
+ public StreamingContext(StreamingContextStates state) : this(state, null)
+ {
+ }
+
+ public StreamingContext(StreamingContextStates state, object additional)
+ {
+ _state = state;
+ _additionalContext = additional;
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (!(obj is StreamingContext))
+ {
+ return false;
+ }
+ StreamingContext ctx = (StreamingContext)obj;
+ return ctx._additionalContext == _additionalContext && ctx._state == _state;
+ }
+
+ public override int GetHashCode() => (int)_state;
+
+ public StreamingContextStates State => _state;
+
+ public object Context => _additionalContext;
+ }
+
+ [Flags]
+ public enum StreamingContextStates
+ {
+ CrossProcess = 0x01,
+ CrossMachine = 0x02,
+ File = 0x04,
+ Persistence = 0x08,
+ Remoting = 0x10,
+ Other = 0x20,
+ Clone = 0x40,
+ CrossAppDomain = 0x80,
+ All = 0xFF,
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Versioning/NonVersionableAttribute.cs b/src/mscorlib/shared/System/Runtime/Versioning/NonVersionableAttribute.cs
new file mode 100644
index 0000000000..e4809953bc
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Versioning/NonVersionableAttribute.cs
@@ -0,0 +1,36 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** The [NonVersionable] attribute is applied to indicate that the implementation
+** of a particular member or layout of a struct cannot be changed for given platform in incompatible way.
+** This allows cross-module inlining of methods and data structures whose implementation
+** is never changed in ReadyToRun native images. Any changes to such members or types would be
+** breaking changes for ReadyToRun.
+**
+** Applying this type also has the side effect that the inlining tables in R2R images will not
+** report that inlining of NonVersionable attributed methods occured. These inlining tables are used
+** by profilers to figure out the set of methods that need to be rejited when one method is instrumented,
+** so in effect NonVersionable methods are also non-instrumentable. Generally this is OK for
+** extremely trivial low level methods where NonVersionable gets used, but if there is any plan to
+** significantly extend its usage or allow 3rd parties to use it please discuss with the diagnostics team.
+===========================================================*/
+
+using System;
+using System.Diagnostics;
+
+namespace System.Runtime.Versioning
+{
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Constructor,
+ AllowMultiple = false, Inherited = false)]
+ internal sealed class NonVersionableAttribute : Attribute
+ {
+ public NonVersionableAttribute()
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Runtime/Versioning/TargetFrameworkAttribute.cs b/src/mscorlib/shared/System/Runtime/Versioning/TargetFrameworkAttribute.cs
new file mode 100644
index 0000000000..54ccdf2c81
--- /dev/null
+++ b/src/mscorlib/shared/System/Runtime/Versioning/TargetFrameworkAttribute.cs
@@ -0,0 +1,48 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose: Identifies which SKU and version of the .NET
+** Framework that a particular library was compiled against.
+** Emitted by VS, and can help catch deployment problems.
+**
+===========================================================*/
+
+using System;
+using System.Diagnostics.Contracts;
+
+namespace System.Runtime.Versioning
+{
+ [AttributeUsageAttribute(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
+ public sealed class TargetFrameworkAttribute : Attribute
+ {
+ private String _frameworkName; // A target framework moniker
+ private String _frameworkDisplayName;
+
+ // The frameworkName parameter is intended to be the string form of a FrameworkName instance.
+ public TargetFrameworkAttribute(String frameworkName)
+ {
+ if (frameworkName == null)
+ throw new ArgumentNullException(nameof(frameworkName));
+ Contract.EndContractBlock();
+ _frameworkName = frameworkName;
+ }
+
+ // The target framework moniker that this assembly was compiled against.
+ // Use the FrameworkName class to interpret target framework monikers.
+ public String FrameworkName
+ {
+ get { return _frameworkName; }
+ }
+
+ public String FrameworkDisplayName
+ {
+ get { return _frameworkDisplayName; }
+ set { _frameworkDisplayName = value; }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Security/AllowPartiallyTrustedCallersAttribute.cs b/src/mscorlib/shared/System/Security/AllowPartiallyTrustedCallersAttribute.cs
new file mode 100644
index 0000000000..84ad65c4c0
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/AllowPartiallyTrustedCallersAttribute.cs
@@ -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.
+
+namespace System.Security
+{
+ // AllowPartiallyTrustedCallersAttribute:
+ // Indicates that the Assembly is secure and can be used by untrusted
+ // and semitrusted clients
+ // For v.1, this is valid only on Assemblies, but could be expanded to
+ // include Module, Method, class
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
+ public sealed class AllowPartiallyTrustedCallersAttribute : Attribute
+ {
+ public AllowPartiallyTrustedCallersAttribute() { }
+ public PartialTrustVisibilityLevel PartialTrustVisibilityLevel { get; set; }
+ }
+}
+
diff --git a/src/mscorlib/corefx/System/Security/CryptographicException.cs b/src/mscorlib/shared/System/Security/CryptographicException.cs
index 89cb658aa9..89cb658aa9 100644
--- a/src/mscorlib/corefx/System/Security/CryptographicException.cs
+++ b/src/mscorlib/shared/System/Security/CryptographicException.cs
diff --git a/src/mscorlib/shared/System/Security/PartialTrustVisibilityLevel.cs b/src/mscorlib/shared/System/Security/PartialTrustVisibilityLevel.cs
new file mode 100644
index 0000000000..a0cb5789ac
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/PartialTrustVisibilityLevel.cs
@@ -0,0 +1,13 @@
+// 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.
+
+namespace System.Security
+{
+ public enum PartialTrustVisibilityLevel
+ {
+ VisibleToAllHosts = 0,
+ NotVisibleByDefault = 1
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Security/SafeBSTRHandle.cs b/src/mscorlib/shared/System/Security/SafeBSTRHandle.cs
new file mode 100644
index 0000000000..a1164dce91
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/SafeBSTRHandle.cs
@@ -0,0 +1,81 @@
+// 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.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace System.Security
+{
+ internal sealed class SafeBSTRHandle : SafeBuffer
+ {
+ internal SafeBSTRHandle() : base(true) { }
+
+ internal static SafeBSTRHandle Allocate(uint lenInChars)
+ {
+ ulong lenInBytes = (ulong)lenInChars * sizeof(char);
+ SafeBSTRHandle bstr = Interop.OleAut32.SysAllocStringLen(IntPtr.Zero, lenInChars);
+ if (bstr.IsInvalid) // SysAllocStringLen returns a NULL ptr when there's insufficient memory
+ {
+ throw new OutOfMemoryException();
+ }
+ bstr.Initialize(lenInBytes);
+ return bstr;
+ }
+
+ override protected bool ReleaseHandle()
+ {
+ Interop.NtDll.ZeroMemory(handle, (UIntPtr)(Interop.OleAut32.SysStringLen(handle) * sizeof(char)));
+ Interop.OleAut32.SysFreeString(handle);
+ return true;
+ }
+
+ internal unsafe void ClearBuffer()
+ {
+ byte* bufferPtr = null;
+ try
+ {
+ AcquirePointer(ref bufferPtr);
+ Interop.NtDll.ZeroMemory((IntPtr)bufferPtr, (UIntPtr)(Interop.OleAut32.SysStringLen((IntPtr)bufferPtr) * sizeof(char)));
+ }
+ finally
+ {
+ if (bufferPtr != null)
+ {
+ ReleasePointer();
+ }
+ }
+ }
+
+ internal unsafe uint Length => Interop.OleAut32.SysStringLen(this);
+
+ internal unsafe static void Copy(SafeBSTRHandle source, SafeBSTRHandle target, uint bytesToCopy)
+ {
+ if (bytesToCopy == 0)
+ {
+ return;
+ }
+
+ byte* sourcePtr = null, targetPtr = null;
+ try
+ {
+ source.AcquirePointer(ref sourcePtr);
+ target.AcquirePointer(ref targetPtr);
+
+ Debug.Assert(source.ByteLength >= bytesToCopy, "Source buffer is too small.");
+ Buffer.MemoryCopy(sourcePtr, targetPtr, target.ByteLength, bytesToCopy);
+ }
+ finally
+ {
+ if (targetPtr != null)
+ {
+ target.ReleasePointer();
+ }
+ if (sourcePtr != null)
+ {
+ source.ReleasePointer();
+ }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Security/SecureString.Unix.cs b/src/mscorlib/shared/System/Security/SecureString.Unix.cs
index 0ef38e40ee..0ef38e40ee 100644
--- a/src/mscorlib/corefx/System/Security/SecureString.Unix.cs
+++ b/src/mscorlib/shared/System/Security/SecureString.Unix.cs
diff --git a/src/mscorlib/shared/System/Security/SecureString.Windows.cs b/src/mscorlib/shared/System/Security/SecureString.Windows.cs
new file mode 100644
index 0000000000..13f75a37e9
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/SecureString.Windows.cs
@@ -0,0 +1,311 @@
+// 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.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Security.Cryptography;
+using Microsoft.Win32;
+
+namespace System.Security
+{
+ public sealed partial class SecureString
+ {
+ internal SecureString(SecureString str)
+ {
+ Debug.Assert(str != null, "Expected non-null SecureString");
+ Debug.Assert(str._buffer != null, "Expected other SecureString's buffer to be non-null");
+ Debug.Assert(str._encrypted, "Expected to be used only on encrypted SecureStrings");
+
+ AllocateBuffer(str._buffer.Length);
+ SafeBSTRHandle.Copy(str._buffer, _buffer, str._buffer.Length * sizeof(char));
+
+ _decryptedLength = str._decryptedLength;
+ _encrypted = str._encrypted;
+ }
+
+ private unsafe void InitializeSecureString(char* value, int length)
+ {
+ Debug.Assert(length >= 0, $"Expected non-negative length, got {length}");
+
+ AllocateBuffer((uint)length);
+ _decryptedLength = length;
+
+ byte* bufferPtr = null;
+ try
+ {
+ _buffer.AcquirePointer(ref bufferPtr);
+ Buffer.MemoryCopy((byte*)value, bufferPtr, (long)_buffer.ByteLength, length * sizeof(char));
+ }
+ finally
+ {
+ if (bufferPtr != null)
+ {
+ _buffer.ReleasePointer();
+ }
+ }
+
+ ProtectMemory();
+ }
+
+ private void AppendCharCore(char c)
+ {
+ UnprotectMemory();
+ try
+ {
+ EnsureCapacity(_decryptedLength + 1);
+ _buffer.Write<char>((uint)_decryptedLength * sizeof(char), c);
+ _decryptedLength++;
+ }
+ finally
+ {
+ ProtectMemory();
+ }
+ }
+
+ private void ClearCore()
+ {
+ _decryptedLength = 0;
+ _buffer.ClearBuffer();
+ }
+
+ private void DisposeCore()
+ {
+ if (_buffer != null)
+ {
+ _buffer.Dispose();
+ _buffer = null;
+ }
+ }
+
+ private unsafe void InsertAtCore(int index, char c)
+ {
+ byte* bufferPtr = null;
+ UnprotectMemory();
+ try
+ {
+ EnsureCapacity(_decryptedLength + 1);
+
+ _buffer.AcquirePointer(ref bufferPtr);
+ char* pBuffer = (char*)bufferPtr;
+
+ for (int i = _decryptedLength; i > index; i--)
+ {
+ pBuffer[i] = pBuffer[i - 1];
+ }
+ pBuffer[index] = c;
+ ++_decryptedLength;
+ }
+ finally
+ {
+ ProtectMemory();
+ if (bufferPtr != null)
+ {
+ _buffer.ReleasePointer();
+ }
+ }
+ }
+
+ private unsafe void RemoveAtCore(int index)
+ {
+ byte* bufferPtr = null;
+ UnprotectMemory();
+ try
+ {
+ _buffer.AcquirePointer(ref bufferPtr);
+ char* pBuffer = (char*)bufferPtr;
+
+ for (int i = index; i < _decryptedLength - 1; i++)
+ {
+ pBuffer[i] = pBuffer[i + 1];
+ }
+ pBuffer[--_decryptedLength] = (char)0;
+ }
+ finally
+ {
+ ProtectMemory();
+ if (bufferPtr != null)
+ {
+ _buffer.ReleasePointer();
+ }
+ }
+ }
+
+ private void SetAtCore(int index, char c)
+ {
+ UnprotectMemory();
+ try
+ {
+ _buffer.Write<char>((uint)index * sizeof(char), c);
+ }
+ finally
+ {
+ ProtectMemory();
+ }
+ }
+
+ internal unsafe IntPtr MarshalToBSTR()
+ {
+ int length = _decryptedLength;
+ IntPtr ptr = IntPtr.Zero;
+ IntPtr result = IntPtr.Zero;
+ byte* bufferPtr = null;
+
+ UnprotectMemory();
+ try
+ {
+ _buffer.AcquirePointer(ref bufferPtr);
+ int resultByteLength = (length + 1) * sizeof(char);
+
+ ptr = Interop.OleAut32.SysAllocStringLen(null, length);
+ if (ptr == IntPtr.Zero)
+ {
+ throw new OutOfMemoryException();
+ }
+
+ Buffer.MemoryCopy(bufferPtr, (byte*)ptr, resultByteLength, length * sizeof(char));
+
+ result = ptr;
+ }
+ finally
+ {
+ ProtectMemory();
+
+ // If we failed for any reason, free the new buffer
+ if (result == IntPtr.Zero && ptr != IntPtr.Zero)
+ {
+ Interop.NtDll.ZeroMemory(ptr, (UIntPtr)(length * sizeof(char)));
+ Interop.OleAut32.SysFreeString(ptr);
+ }
+
+ if (bufferPtr != null)
+ {
+ _buffer.ReleasePointer();
+ }
+ }
+ return result;
+ }
+
+ internal unsafe IntPtr MarshalToStringCore(bool globalAlloc, bool unicode)
+ {
+ int length = _decryptedLength;
+ IntPtr ptr = IntPtr.Zero;
+ IntPtr result = IntPtr.Zero;
+ byte* bufferPtr = null;
+
+ UnprotectMemory();
+ try
+ {
+ _buffer.AcquirePointer(ref bufferPtr);
+ if (unicode)
+ {
+ int resultByteLength = (length + 1) * sizeof(char);
+ ptr = globalAlloc ? Marshal.AllocHGlobal(resultByteLength) : Marshal.AllocCoTaskMem(resultByteLength);
+ Buffer.MemoryCopy(bufferPtr, (byte*)ptr, resultByteLength, length * sizeof(char));
+ *(length + (char*)ptr) = '\0';
+ }
+ else
+ {
+ uint defaultChar = '?';
+ int resultByteLength = 1 + Interop.Kernel32.WideCharToMultiByte(
+ Interop.Kernel32.CP_ACP, Interop.Kernel32.WC_NO_BEST_FIT_CHARS, (char*)bufferPtr, length, null, 0, (IntPtr)(&defaultChar), IntPtr.Zero);
+ ptr = globalAlloc ? Marshal.AllocHGlobal(resultByteLength) : Marshal.AllocCoTaskMem(resultByteLength);
+ Interop.Kernel32.WideCharToMultiByte(
+ Interop.Kernel32.CP_ACP, Interop.Kernel32.WC_NO_BEST_FIT_CHARS, (char*)bufferPtr, length, (byte*)ptr, resultByteLength - 1, (IntPtr)(&defaultChar), IntPtr.Zero);
+ *(resultByteLength - 1 + (byte*)ptr) = 0;
+ }
+ result = ptr;
+ }
+ finally
+ {
+ ProtectMemory();
+
+ // If we failed for any reason, free the new buffer
+ if (result == IntPtr.Zero && ptr != IntPtr.Zero)
+ {
+ Interop.NtDll.ZeroMemory(ptr, (UIntPtr)(length * sizeof(char)));
+ MarshalFree(ptr, globalAlloc);
+ }
+
+ if (bufferPtr != null)
+ {
+ _buffer.ReleasePointer();
+ }
+ }
+ return result;
+ }
+
+ private void EnsureNotDisposed()
+ {
+ if (_buffer == null)
+ {
+ throw new ObjectDisposedException(GetType().Name);
+ }
+ }
+
+ // -----------------------------
+ // ---- PAL layer ends here ----
+ // -----------------------------
+
+ private const int BlockSize = (int)Interop.Crypt32.CRYPTPROTECTMEMORY_BLOCK_SIZE / sizeof(char);
+ private SafeBSTRHandle _buffer;
+ private bool _encrypted;
+
+ private void AllocateBuffer(uint size)
+ {
+ _buffer = SafeBSTRHandle.Allocate(GetAlignedSize(size));
+ }
+
+ private static uint GetAlignedSize(uint size) =>
+ size == 0 || size % BlockSize != 0 ?
+ BlockSize + ((size / BlockSize) * BlockSize) :
+ size;
+
+ private void EnsureCapacity(int capacity)
+ {
+ if (capacity > MaxLength)
+ {
+ throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_Capacity);
+ }
+
+ if (((uint)capacity * sizeof(char)) <= _buffer.ByteLength)
+ {
+ return;
+ }
+
+ var oldBuffer = _buffer;
+ SafeBSTRHandle newBuffer = SafeBSTRHandle.Allocate(GetAlignedSize((uint)capacity));
+ SafeBSTRHandle.Copy(oldBuffer, newBuffer, (uint)_decryptedLength * sizeof(char));
+ _buffer = newBuffer;
+ oldBuffer.Dispose();
+ }
+
+ private void ProtectMemory()
+ {
+ Debug.Assert(!_buffer.IsInvalid, "Invalid buffer!");
+
+ if (_decryptedLength != 0 &&
+ !_encrypted &&
+ !Interop.Crypt32.CryptProtectMemory(_buffer, _buffer.Length * sizeof(char), Interop.Crypt32.CRYPTPROTECTMEMORY_SAME_PROCESS))
+ {
+ throw new CryptographicException(Marshal.GetLastWin32Error());
+ }
+
+ _encrypted = true;
+ }
+
+ private void UnprotectMemory()
+ {
+ Debug.Assert(!_buffer.IsInvalid, "Invalid buffer!");
+
+ if (_decryptedLength != 0 &&
+ _encrypted &&
+ !Interop.Crypt32.CryptUnprotectMemory(_buffer, _buffer.Length * sizeof(char), Interop.Crypt32.CRYPTPROTECTMEMORY_SAME_PROCESS))
+ {
+ throw new CryptographicException(Marshal.GetLastWin32Error());
+ }
+
+ _encrypted = false;
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Security/SecureString.cs b/src/mscorlib/shared/System/Security/SecureString.cs
index 9059f90e60..9059f90e60 100644
--- a/src/mscorlib/corefx/System/Security/SecureString.cs
+++ b/src/mscorlib/shared/System/Security/SecureString.cs
diff --git a/src/mscorlib/shared/System/Security/SecurityCriticalAttribute.cs b/src/mscorlib/shared/System/Security/SecurityCriticalAttribute.cs
new file mode 100644
index 0000000000..2bf1700afb
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/SecurityCriticalAttribute.cs
@@ -0,0 +1,36 @@
+// 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.
+
+namespace System.Security
+{
+ // SecurityCriticalAttribute
+ // Indicates that the decorated code or assembly performs security critical operations (e.g. Assert, "unsafe", LinkDemand, etc.)
+ // The attribute can be placed on most targets, except on arguments/return values.
+ [AttributeUsage(AttributeTargets.Assembly |
+ AttributeTargets.Class |
+ AttributeTargets.Struct |
+ AttributeTargets.Enum |
+ AttributeTargets.Constructor |
+ AttributeTargets.Method |
+ AttributeTargets.Field |
+ AttributeTargets.Interface |
+ AttributeTargets.Delegate,
+ AllowMultiple = false,
+ Inherited = false)]
+ public sealed class SecurityCriticalAttribute : Attribute
+ {
+#pragma warning disable 618 // We still use SecurityCriticalScope for v2 compat
+ public SecurityCriticalAttribute() { }
+
+ public SecurityCriticalAttribute(SecurityCriticalScope scope)
+ {
+ Scope = scope;
+ }
+
+ [Obsolete("SecurityCriticalScope is only used for .NET 2.0 transparency compatibility.")]
+ public SecurityCriticalScope Scope { get; }
+#pragma warning restore 618
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Security/SecurityCriticalScope.cs b/src/mscorlib/shared/System/Security/SecurityCriticalScope.cs
new file mode 100644
index 0000000000..e0f5a8e2cd
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/SecurityCriticalScope.cs
@@ -0,0 +1,14 @@
+// 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.
+
+namespace System.Security
+{
+ [Obsolete("SecurityCriticalScope is only used for .NET 2.0 transparency compatibility.")]
+ public enum SecurityCriticalScope
+ {
+ Explicit = 0,
+ Everything = 0x1
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Security/SecurityException.cs b/src/mscorlib/shared/System/Security/SecurityException.cs
new file mode 100644
index 0000000000..86e3cd4631
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/SecurityException.cs
@@ -0,0 +1,66 @@
+// 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.Reflection;
+using System.Runtime.Serialization;
+
+namespace System.Security
+{
+ [Serializable]
+ public class SecurityException : SystemException
+ {
+ public SecurityException()
+ : base(SR.Arg_SecurityException)
+ {
+ HResult = __HResults.COR_E_SECURITY;
+ }
+
+ public SecurityException(string message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_SECURITY;
+ }
+
+ public SecurityException(string message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_SECURITY;
+ }
+
+ public SecurityException(string message, Type type)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_SECURITY;
+ PermissionType = type;
+ }
+
+ public SecurityException(string message, Type type, string state)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_SECURITY;
+ PermissionType = type;
+ PermissionState = state;
+ }
+
+ protected SecurityException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+
+ public override string ToString() => base.ToString();
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context) => base.GetObjectData(info, context);
+
+ public object Demanded { get; set; }
+ public object DenySetInstance { get; set; }
+ public AssemblyName FailedAssemblyInfo { get; set; }
+ public string GrantedSet { get; set; }
+ public MethodInfo Method { get; set; }
+ public string PermissionState { get; set; }
+ public Type PermissionType { get; set; }
+ public object PermitOnlySetInstance { get; set; }
+ public string RefusedSet { get; set; }
+ public string Url { get; set; }
+ }
+}
diff --git a/src/mscorlib/shared/System/Security/SecurityRuleSet.cs b/src/mscorlib/shared/System/Security/SecurityRuleSet.cs
new file mode 100644
index 0000000000..1b62fd4e7d
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/SecurityRuleSet.cs
@@ -0,0 +1,14 @@
+// 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.
+
+namespace System.Security
+{
+ public enum SecurityRuleSet : byte
+ {
+ None = 0,
+ Level1 = 1, // v2.0 transparency model
+ Level2 = 2, // v4.0 transparency model
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Security/SecurityRulesAttribute.cs b/src/mscorlib/shared/System/Security/SecurityRulesAttribute.cs
new file mode 100644
index 0000000000..ad17087f8b
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/SecurityRulesAttribute.cs
@@ -0,0 +1,28 @@
+// 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.
+
+namespace System.Security
+{
+ // SecurityRulesAttribute
+ //
+ // Indicates which set of security rules an assembly was authored against, and therefore which set of
+ // rules the runtime should enforce on the assembly. For instance, an assembly marked with
+ // [SecurityRules(SecurityRuleSet.Level1)] will follow the v2.0 transparency rules, where transparent code
+ // can call a LinkDemand by converting it to a full demand, public critical methods are implicitly
+ // treat as safe, and the remainder of the v2.0 rules apply.
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
+ public sealed class SecurityRulesAttribute : Attribute
+ {
+ public SecurityRulesAttribute(SecurityRuleSet ruleSet)
+ {
+ RuleSet = ruleSet;
+ }
+
+ // Should fully trusted transparent code skip IL verification
+ public bool SkipVerificationInFullTrust { get; set; }
+
+ public SecurityRuleSet RuleSet { get; }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Security/SecuritySafeCriticalAttribute.cs b/src/mscorlib/shared/System/Security/SecuritySafeCriticalAttribute.cs
new file mode 100644
index 0000000000..ee2e4b0499
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/SecuritySafeCriticalAttribute.cs
@@ -0,0 +1,30 @@
+// 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.
+
+namespace System.Security
+{
+ // SecuritySafeCriticalAttribute:
+ // Indicates that the code may contain violations to the security critical rules (e.g. transitions from
+ // critical to non-public transparent, transparent to non-public critical, etc.), has been audited for
+ // security concerns and is considered security clean. Also indicates that the code is considered SecurityCritical.
+ // The effect of this attribute is as if the code was marked [SecurityCritical][SecurityTreatAsSafe].
+ // At assembly-scope, all rule checks will be suppressed within the assembly and for calls made against the assembly.
+ // At type-scope, all rule checks will be suppressed for members within the type and for calls made against the type.
+ // At member level (e.g. field and method) the code will be treated as public - i.e. no rule checks for the members.
+
+ [AttributeUsage(AttributeTargets.Class |
+ AttributeTargets.Struct |
+ AttributeTargets.Enum |
+ AttributeTargets.Constructor |
+ AttributeTargets.Method |
+ AttributeTargets.Field |
+ AttributeTargets.Interface |
+ AttributeTargets.Delegate,
+ AllowMultiple = false,
+ Inherited = false)]
+ public sealed class SecuritySafeCriticalAttribute : Attribute
+ {
+ public SecuritySafeCriticalAttribute() { }
+ }
+}
diff --git a/src/mscorlib/shared/System/Security/SecurityTransparentAttribute.cs b/src/mscorlib/shared/System/Security/SecurityTransparentAttribute.cs
new file mode 100644
index 0000000000..03f41387ae
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/SecurityTransparentAttribute.cs
@@ -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.
+
+namespace System.Security
+{
+ // SecurityTransparentAttribute:
+ // Indicates the assembly contains only transparent code.
+ // Security critical actions will be restricted or converted into less critical actions. For example,
+ // Assert will be restricted, SuppressUnmanagedCode, LinkDemand, unsafe, and unverifiable code will be converted
+ // into Full-Demands.
+
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
+ public sealed class SecurityTransparentAttribute : Attribute
+ {
+ public SecurityTransparentAttribute() { }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Security/SecurityTreatAsSafeAttribute.cs b/src/mscorlib/shared/System/Security/SecurityTreatAsSafeAttribute.cs
new file mode 100644
index 0000000000..7a95122bf0
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/SecurityTreatAsSafeAttribute.cs
@@ -0,0 +1,32 @@
+// 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.
+
+namespace System.Security
+{
+ // SecurityTreatAsSafeAttribute:
+ // Indicates that the code may contain violations to the security critical rules (e.g. transitions from
+ // critical to non-public transparent, transparent to non-public critical, etc.), has been audited for
+ // security concerns and is considered security clean.
+ // At assembly-scope, all rule checks will be suppressed within the assembly and for calls made against the assembly.
+ // At type-scope, all rule checks will be suppressed for members within the type and for calls made against the type.
+ // At member level (e.g. field and method) the code will be treated as public - i.e. no rule checks for the members.
+
+ [AttributeUsage(AttributeTargets.Assembly |
+ AttributeTargets.Class |
+ AttributeTargets.Struct |
+ AttributeTargets.Enum |
+ AttributeTargets.Constructor |
+ AttributeTargets.Method |
+ AttributeTargets.Field |
+ AttributeTargets.Interface |
+ AttributeTargets.Delegate,
+ AllowMultiple = false,
+ Inherited = false)]
+ [Obsolete("SecurityTreatAsSafe is only used for .NET 2.0 transparency compatibility. Please use the SecuritySafeCriticalAttribute instead.")]
+ public sealed class SecurityTreatAsSafeAttribute : Attribute
+ {
+ public SecurityTreatAsSafeAttribute() { }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Security/SuppressUnmanagedCodeSecurityAttribute.cs b/src/mscorlib/shared/System/Security/SuppressUnmanagedCodeSecurityAttribute.cs
new file mode 100644
index 0000000000..a60b8d3668
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/SuppressUnmanagedCodeSecurityAttribute.cs
@@ -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.
+
+namespace System.Security
+{
+ // SuppressUnmanagedCodeSecurityAttribute:
+ // Indicates that the target P/Invoke method(s) should skip the per-call
+ // security checked for unmanaged code permission.
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = true, Inherited = false)]
+ public sealed class SuppressUnmanagedCodeSecurityAttribute : Attribute
+ {
+ public SuppressUnmanagedCodeSecurityAttribute() { }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Security/UnverifiableCodeAttribute.cs b/src/mscorlib/shared/System/Security/UnverifiableCodeAttribute.cs
new file mode 100644
index 0000000000..1560b6617b
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/UnverifiableCodeAttribute.cs
@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Security
+{
+ // UnverifiableCodeAttribute:
+ // Indicates that the target module contains unverifiable code.
+ [AttributeUsage(AttributeTargets.Module, AllowMultiple = true, Inherited = false)]
+ public sealed class UnverifiableCodeAttribute : Attribute
+ {
+ public UnverifiableCodeAttribute() { }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Security/VerificationException.cs b/src/mscorlib/shared/System/Security/VerificationException.cs
new file mode 100644
index 0000000000..9641e1aa46
--- /dev/null
+++ b/src/mscorlib/shared/System/Security/VerificationException.cs
@@ -0,0 +1,35 @@
+// 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.Runtime.Serialization;
+
+namespace System.Security
+{
+ [Serializable]
+ public class VerificationException : SystemException
+ {
+ public VerificationException()
+ : base(SR.Verification_Exception)
+ {
+ HResult = __HResults.COR_E_VERIFICATION;
+ }
+
+ public VerificationException(string message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_VERIFICATION;
+ }
+
+ public VerificationException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_VERIFICATION;
+ }
+
+ protected VerificationException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/StackOverflowException.cs b/src/mscorlib/shared/System/StackOverflowException.cs
index 0a875e7373..0a875e7373 100644
--- a/src/mscorlib/src/System/StackOverflowException.cs
+++ b/src/mscorlib/shared/System/StackOverflowException.cs
diff --git a/src/mscorlib/shared/System/StringComparer.cs b/src/mscorlib/shared/System/StringComparer.cs
new file mode 100644
index 0000000000..b327e770d5
--- /dev/null
+++ b/src/mscorlib/shared/System/StringComparer.cs
@@ -0,0 +1,274 @@
+// 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.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
+ [Serializable]
+ public abstract class StringComparer : IComparer, IEqualityComparer, IComparer<string>, IEqualityComparer<string>
+ {
+ private static readonly CultureAwareComparer s_invariantCulture = new CultureAwareComparer(CultureInfo.InvariantCulture, false);
+ private static readonly CultureAwareComparer s_invariantCultureIgnoreCase = new CultureAwareComparer(CultureInfo.InvariantCulture, true);
+ private static readonly OrdinalComparer s_ordinal = new OrdinalComparer();
+ private static readonly OrdinalIgnoreCaseComparer s_ordinalIgnoreCase = new OrdinalIgnoreCaseComparer();
+
+ public static StringComparer InvariantCulture
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<StringComparer>() != null);
+ return s_invariantCulture;
+ }
+ }
+
+ public static StringComparer InvariantCultureIgnoreCase
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<StringComparer>() != null);
+ return s_invariantCultureIgnoreCase;
+ }
+ }
+
+ public static StringComparer CurrentCulture
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<StringComparer>() != null);
+ return new CultureAwareComparer(CultureInfo.CurrentCulture, false);
+ }
+ }
+
+ public static StringComparer CurrentCultureIgnoreCase
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<StringComparer>() != null);
+ return new CultureAwareComparer(CultureInfo.CurrentCulture, true);
+ }
+ }
+
+ public static StringComparer Ordinal
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<StringComparer>() != null);
+ return s_ordinal;
+ }
+ }
+
+ public static StringComparer OrdinalIgnoreCase
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<StringComparer>() != null);
+ return s_ordinalIgnoreCase;
+ }
+ }
+
+ // Convert a StringComparison to a StringComparer
+ public static StringComparer FromComparison(StringComparison comparisonType)
+ {
+ switch (comparisonType)
+ {
+ case StringComparison.CurrentCulture:
+ return CurrentCulture;
+ case StringComparison.CurrentCultureIgnoreCase:
+ return CurrentCultureIgnoreCase;
+ case StringComparison.InvariantCulture:
+ return InvariantCulture;
+ case StringComparison.InvariantCultureIgnoreCase:
+ return InvariantCultureIgnoreCase;
+ case StringComparison.Ordinal:
+ return Ordinal;
+ case StringComparison.OrdinalIgnoreCase:
+ return OrdinalIgnoreCase;
+ default:
+ throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType));
+ }
+ }
+
+ public static StringComparer Create(CultureInfo culture, bool ignoreCase)
+ {
+ if (culture == null)
+ {
+ throw new ArgumentNullException(nameof(culture));
+ }
+ Contract.Ensures(Contract.Result<StringComparer>() != null);
+ Contract.EndContractBlock();
+
+ return new CultureAwareComparer(culture, ignoreCase);
+ }
+
+ public int Compare(object x, object y)
+ {
+ if (x == y) return 0;
+ if (x == null) return -1;
+ if (y == null) return 1;
+
+ String sa = x as String;
+ if (sa != null)
+ {
+ String sb = y as String;
+ if (sb != null)
+ {
+ return Compare(sa, sb);
+ }
+ }
+
+ IComparable ia = x as IComparable;
+ if (ia != null)
+ {
+ return ia.CompareTo(y);
+ }
+
+ throw new ArgumentException(SR.Argument_ImplementIComparable);
+ }
+
+
+ public new bool Equals(Object x, Object y)
+ {
+ if (x == y) return true;
+ if (x == null || y == null) return false;
+
+ String sa = x as String;
+ if (sa != null)
+ {
+ String sb = y as String;
+ if (sb != null)
+ {
+ return Equals(sa, sb);
+ }
+ }
+ return x.Equals(y);
+ }
+
+ public int GetHashCode(object obj)
+ {
+ if (obj == null)
+ {
+ throw new ArgumentNullException(nameof(obj));
+ }
+ Contract.EndContractBlock();
+
+ string s = obj as string;
+ if (s != null)
+ {
+ return GetHashCode(s);
+ }
+ return obj.GetHashCode();
+ }
+
+ public abstract int Compare(String x, String y);
+ public abstract bool Equals(String x, String y);
+ public abstract int GetHashCode(string obj);
+ }
+
+ [Serializable]
+ internal sealed class CultureAwareComparer : StringComparer
+ {
+ private readonly CompareInfo _compareInfo;
+ private readonly CompareOptions _options;
+
+ internal CultureAwareComparer(CultureInfo culture, bool ignoreCase)
+ {
+ _compareInfo = culture.CompareInfo;
+ _options = ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None;
+ }
+
+ public override int Compare(string x, string y)
+ {
+ if (object.ReferenceEquals(x, y)) return 0;
+ if (x == null) return -1;
+ if (y == null) return 1;
+ return _compareInfo.Compare(x, y, _options);
+ }
+
+ public override bool Equals(string x, string y)
+ {
+ if (object.ReferenceEquals(x, y)) return true;
+ if (x == null || y == null) return false;
+ return _compareInfo.Compare(x, y, _options) == 0;
+ }
+
+ public override int GetHashCode(string obj)
+ {
+ if (obj == null)
+ {
+ throw new ArgumentNullException(nameof(obj));
+ }
+ return _compareInfo.GetHashCodeOfString(obj, _options);
+ }
+
+ // Equals method for the comparer itself.
+ public override bool Equals(object obj)
+ {
+ CultureAwareComparer comparer = obj as CultureAwareComparer;
+ return
+ comparer != null &&
+ _options == comparer._options &&
+ _compareInfo.Equals(comparer._compareInfo);
+ }
+
+ public override int GetHashCode()
+ {
+ int hashCode = _compareInfo.GetHashCode();
+ return _options == CompareOptions.None ? hashCode : ~hashCode;
+ }
+ }
+
+ [Serializable]
+ internal sealed class OrdinalComparer : StringComparer
+ {
+ public override int Compare(string x, string y) => string.CompareOrdinal(x, y);
+
+ public override bool Equals(string x, string y) => string.Equals(x, y);
+
+ public override int GetHashCode(string obj)
+ {
+ if (obj == null)
+ {
+#if CORECLR
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.obj);
+#else
+ throw new ArgumentNullException(nameof(obj));
+#endif
+ }
+ return obj.GetHashCode();
+ }
+
+ // Equals/GetHashCode methods for the comparer itself.
+ public override bool Equals(object obj) => obj is OrdinalComparer;
+ public override int GetHashCode() => nameof(OrdinalComparer).GetHashCode();
+ }
+
+ [Serializable]
+ internal sealed class OrdinalIgnoreCaseComparer : StringComparer
+ {
+ public override int Compare(string x, string y) => string.Compare(x, y, StringComparison.OrdinalIgnoreCase);
+
+ public override bool Equals(string x, string y) => string.Equals(x, y, StringComparison.OrdinalIgnoreCase);
+
+ public override int GetHashCode(string obj)
+ {
+ if (obj == null)
+ {
+#if CORECLR
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.obj);
+#else
+ throw new ArgumentNullException(nameof(obj));
+#endif
+ }
+ return TextInfo.GetHashCodeOrdinalIgnoreCase(obj);
+ }
+
+ // Equals/GetHashCode methods for the comparer itself.
+ public override bool Equals(object obj) => obj is OrdinalIgnoreCaseComparer;
+ public override int GetHashCode() => nameof(OrdinalIgnoreCaseComparer).GetHashCode();
+ }
+}
diff --git a/src/mscorlib/shared/System/StringComparison.cs b/src/mscorlib/shared/System/StringComparison.cs
new file mode 100644
index 0000000000..8b4e2ae2fe
--- /dev/null
+++ b/src/mscorlib/shared/System/StringComparison.cs
@@ -0,0 +1,17 @@
+// 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.
+
+namespace System
+{
+ [Serializable]
+ public enum StringComparison
+ {
+ CurrentCulture = 0,
+ CurrentCultureIgnoreCase = 1,
+ InvariantCulture = 2,
+ InvariantCultureIgnoreCase = 3,
+ Ordinal = 4,
+ OrdinalIgnoreCase = 5,
+ }
+}
diff --git a/src/mscorlib/shared/System/StringSplitOptions.cs b/src/mscorlib/shared/System/StringSplitOptions.cs
new file mode 100644
index 0000000000..d7020559a1
--- /dev/null
+++ b/src/mscorlib/shared/System/StringSplitOptions.cs
@@ -0,0 +1,13 @@
+// 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.
+
+namespace System
+{
+ [Flags]
+ public enum StringSplitOptions
+ {
+ None = 0,
+ RemoveEmptyEntries = 1
+ }
+}
diff --git a/src/mscorlib/src/System/SystemException.cs b/src/mscorlib/shared/System/SystemException.cs
index f4779a2cd4..f4779a2cd4 100644
--- a/src/mscorlib/src/System/SystemException.cs
+++ b/src/mscorlib/shared/System/SystemException.cs
diff --git a/src/mscorlib/shared/System/Text/ASCIIEncoding.cs b/src/mscorlib/shared/System/Text/ASCIIEncoding.cs
new file mode 100644
index 0000000000..e5c1194849
--- /dev/null
+++ b/src/mscorlib/shared/System/Text/ASCIIEncoding.cs
@@ -0,0 +1,973 @@
+// 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.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+
+namespace System.Text
+{
+ // ASCIIEncoding
+ //
+ // Note that ASCIIEncoding is optimized with no best fit and ? for fallback.
+ // It doesn't come in other flavors.
+ //
+ // Note: ASCIIEncoding is the only encoding that doesn't do best fit (windows has best fit).
+ //
+ // Note: IsAlwaysNormalized remains false because 1/2 the code points are unassigned, so they'd
+ // use fallbacks, and we cannot guarantee that fallbacks are normalized.
+
+ [Serializable]
+ public class ASCIIEncoding : Encoding
+ {
+ // Allow for devirtualization (see https://github.com/dotnet/coreclr/pull/9230)
+ [Serializable]
+ internal sealed class ASCIIEncodingSealed : ASCIIEncoding { }
+
+ // Used by Encoding.ASCII for lazy initialization
+ // The initialization code will not be run until a static member of the class is referenced
+ internal static readonly ASCIIEncodingSealed s_default = new ASCIIEncodingSealed();
+
+ public ASCIIEncoding() : base(Encoding.CodePageASCII)
+ {
+ }
+
+ internal override void SetDefaultFallbacks()
+ {
+ // For ASCIIEncoding we just use default replacement fallback
+ this.encoderFallback = EncoderFallback.ReplacementFallback;
+ this.decoderFallback = DecoderFallback.ReplacementFallback;
+ }
+
+ // WARNING: GetByteCount(string chars), GetBytes(string chars,...), and GetString(byte[] byteIndex...)
+ // WARNING: have different variable names than EncodingNLS.cs, so this can't just be cut & pasted,
+ // WARNING: or it'll break VB's way of calling these.
+ //
+ // The following methods are copied from EncodingNLS.cs.
+ // Unfortunately EncodingNLS.cs is internal and we're public, so we have to re-implement them here.
+ // These should be kept in sync for the following classes:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ // Returns the number of bytes required to encode a range of characters in
+ // a character array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetByteCount(char[] chars, int index, int count)
+ {
+ // Validate input parameters
+ if (chars == null)
+ throw new ArgumentNullException("chars", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (chars.Length - index < count)
+ throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // If no input, return 0, avoid fixed empty array problem
+ if (count == 0)
+ return 0;
+
+ // Just call the pointer version
+ fixed (char* pChars = chars)
+ return GetByteCount(pChars + index, count, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetByteCount(String chars)
+ {
+ // Validate input
+ if (chars==null)
+ throw new ArgumentNullException("chars");
+ Contract.EndContractBlock();
+
+ fixed (char* pChars = chars)
+ return GetByteCount(pChars, chars.Length, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public override unsafe int GetByteCount(char* chars, int count)
+ {
+ // Validate Parameters
+ if (chars == null)
+ throw new ArgumentNullException("chars", SR.ArgumentNull_Array);
+
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Call it with empty encoder
+ return GetByteCount(chars, count, null);
+ }
+
+ // Parent method is safe.
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ public override unsafe int GetBytes(String chars, int charIndex, int charCount,
+ byte[] bytes, int byteIndex)
+ {
+ if (chars == null || bytes == null)
+ throw new ArgumentNullException((chars == null ? "chars" : "bytes"), SR.ArgumentNull_Array);
+
+ if (charIndex < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? "charIndex" : "charCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (chars.Length - charIndex < charCount)
+ throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCount);
+
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ int byteCount = bytes.Length - byteIndex;
+
+ // Fixed doesn't like empty byte arrays
+ if (bytes.Length == 0)
+ bytes = new byte[1];
+
+ fixed (char* pChars = chars) fixed (byte* pBytes = &bytes[0])
+ return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
+ }
+
+ // Encodes a range of characters in a character array into a range of bytes
+ // in a byte array. An exception occurs if the byte array is not large
+ // enough to hold the complete encoding of the characters. The
+ // GetByteCount method can be used to determine the exact number of
+ // bytes that will be produced for a given range of characters.
+ // Alternatively, the GetMaxByteCount method can be used to
+ // determine the maximum number of bytes that will be produced for a given
+ // number of characters, regardless of the actual character values.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetBytes(char[] chars, int charIndex, int charCount,
+ byte[] bytes, int byteIndex)
+ {
+ // Validate parameters
+ if (chars == null || bytes == null)
+ throw new ArgumentNullException((chars == null ? "chars" : "bytes"), SR.ArgumentNull_Array);
+
+ if (charIndex < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? "charIndex" : "charCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (chars.Length - charIndex < charCount)
+ throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer);
+
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ // If nothing to encode return 0, avoid fixed problem
+ if (charCount == 0)
+ return 0;
+
+ // Just call pointer version
+ int byteCount = bytes.Length - byteIndex;
+
+ // Fixed doesn't like empty byte arrays
+ if (bytes.Length == 0)
+ bytes = new byte[1];
+
+ fixed (char* pChars = chars) fixed (byte* pBytes = &bytes[0])
+ // Remember that byteCount is # to decode, not size of array.
+ return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
+ {
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (charCount < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetBytes(chars, charCount, bytes, byteCount, null);
+ }
+
+ // Returns the number of characters produced by decoding a range of bytes
+ // in a byte array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetCharCount(byte[] bytes, int index, int count)
+ {
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (bytes.Length - index < count)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // If no input just return 0, fixed doesn't like 0 length arrays
+ if (count == 0)
+ return 0;
+
+ // Just call pointer version
+ fixed (byte* pBytes = bytes)
+ return GetCharCount(pBytes + index, count, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public override unsafe int GetCharCount(byte* bytes, int count)
+ {
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetCharCount(bytes, count, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ char[] chars, int charIndex)
+ {
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (byteIndex < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((byteIndex < 0 ? "byteIndex" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if ( bytes.Length - byteIndex < byteCount)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+
+ if (charIndex < 0 || charIndex > chars.Length)
+ throw new ArgumentOutOfRangeException("charIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ // If no input, return 0 & avoid fixed problem
+ if (byteCount == 0)
+ return 0;
+
+ // Just call pointer version
+ int charCount = chars.Length - charIndex;
+
+ // Fixed doesn't like empty char arrays
+ if (chars.Length == 0)
+ chars = new char[1];
+
+ fixed (byte* pBytes = bytes) fixed (char* pChars = &chars[0])
+ // Remember that charCount is # to decode, not size of array
+ return GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
+ {
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (charCount < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetChars(bytes, byteCount, chars, charCount, null);
+ }
+
+ // Returns a string containing the decoded representation of a range of
+ // bytes in a byte array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe String GetString(byte[] bytes, int byteIndex, int byteCount)
+ {
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (byteIndex < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((byteIndex < 0 ? "byteIndex" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+
+ if (bytes.Length - byteIndex < byteCount)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // Avoid problems with empty input buffer
+ if (byteCount == 0) return String.Empty;
+
+ fixed (byte* pBytes = bytes)
+ return String.CreateStringFromEncoding(
+ pBytes + byteIndex, byteCount, this);
+ }
+
+ //
+ // End of standard methods copied from EncodingNLS.cs
+ //
+
+ // GetByteCount
+ // Note: We start by assuming that the output will be the same as count. Having
+ // an encoder or fallback may change that assumption
+ internal override unsafe int GetByteCount(char* chars, int charCount, EncoderNLS encoder)
+ {
+ // Just need to ASSERT, this is called by something else internal that checked parameters already
+ Debug.Assert(charCount >= 0, "[ASCIIEncoding.GetByteCount]count is negative");
+ Debug.Assert(chars != null, "[ASCIIEncoding.GetByteCount]chars is null");
+
+ // Assert because we shouldn't be able to have a null encoder.
+ Debug.Assert(encoderFallback != null, "[ASCIIEncoding.GetByteCount]Attempting to use null fallback encoder");
+
+ char charLeftOver = (char)0;
+ EncoderReplacementFallback fallback = null;
+
+ // Start by assuming default count, then +/- for fallback characters
+ char* charEnd = chars + charCount;
+
+ // For fallback we may need a fallback buffer, we know we aren't default fallback.
+ EncoderFallbackBuffer fallbackBuffer = null;
+ char* charsForFallback;
+
+ if (encoder != null)
+ {
+ charLeftOver = encoder.charLeftOver;
+ Debug.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
+ "[ASCIIEncoding.GetByteCount]leftover character should be high surrogate");
+
+ fallback = encoder.Fallback as EncoderReplacementFallback;
+
+ // We mustn't have left over fallback data when counting
+ if (encoder.InternalHasFallbackBuffer)
+ {
+ // We always need the fallback buffer in get bytes so we can flush any remaining ones if necessary
+ fallbackBuffer = encoder.FallbackBuffer;
+ if (fallbackBuffer.Remaining > 0 && encoder.m_throwOnOverflow)
+ throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(chars, charEnd, encoder, false);
+ }
+
+ // Verify that we have no fallbackbuffer, for ASCII its always empty, so just assert
+ Debug.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
+ encoder.FallbackBuffer.Remaining == 0,
+ "[ASCIICodePageEncoding.GetByteCount]Expected empty fallback buffer");
+ }
+ else
+ {
+ fallback = this.EncoderFallback as EncoderReplacementFallback;
+ }
+
+ // If we have an encoder AND we aren't using default fallback,
+ // then we may have a complicated count.
+ if (fallback != null && fallback.MaxCharCount == 1)
+ {
+ // Replacement fallback encodes surrogate pairs as two ?? (or two whatever), so return size is always
+ // same as input size.
+ // Note that no existing SBCS code pages map code points to supplimentary characters, so this is easy.
+
+ // We could however have 1 extra byte if the last call had an encoder and a funky fallback and
+ // if we don't use the funky fallback this time.
+
+ // Do we have an extra char left over from last time?
+ if (charLeftOver > 0)
+ charCount++;
+
+ return (charCount);
+ }
+
+ // Count is more complicated if you have a funky fallback
+ // For fallback we may need a fallback buffer, we know we're not default fallback
+ int byteCount = 0;
+
+ // We may have a left over character from last time, try and process it.
+ if (charLeftOver > 0)
+ {
+ Debug.Assert(Char.IsHighSurrogate(charLeftOver), "[ASCIIEncoding.GetByteCount]leftover character should be high surrogate");
+ Debug.Assert(encoder != null, "[ASCIIEncoding.GetByteCount]Expected encoder");
+
+ // Since left over char was a surrogate, it'll have to be fallen back.
+ // Get Fallback
+ fallbackBuffer = encoder.FallbackBuffer;
+ fallbackBuffer.InternalInitialize(chars, charEnd, encoder, false);
+
+ // This will fallback a pair if *chars is a low surrogate
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ fallbackBuffer.InternalFallback(charLeftOver, ref charsForFallback);
+ chars = charsForFallback;
+ }
+
+ // Now we may have fallback char[] already from the encoder
+
+ // Go ahead and do it, including the fallback.
+ char ch;
+ while ((ch = (fallbackBuffer == null) ? '\0' : fallbackBuffer.InternalGetNextChar()) != 0 ||
+ chars < charEnd)
+ {
+ // First unwind any fallback
+ if (ch == 0)
+ {
+ // No fallback, just get next char
+ ch = *chars;
+ chars++;
+ }
+
+ // Check for fallback, this'll catch surrogate pairs too.
+ // no chars >= 0x80 are allowed.
+ if (ch > 0x7f)
+ {
+ if (fallbackBuffer == null)
+ {
+ // Initialize the buffer
+ if (encoder == null)
+ fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = encoder.FallbackBuffer;
+ fallbackBuffer.InternalInitialize(charEnd - charCount, charEnd, encoder, false);
+ }
+
+ // Get Fallback
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ fallbackBuffer.InternalFallback(ch, ref charsForFallback);
+ chars = charsForFallback;
+ continue;
+ }
+
+ // We'll use this one
+ byteCount++;
+ }
+
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ "[ASCIIEncoding.GetByteCount]Expected Empty fallback buffer");
+
+ return byteCount;
+ }
+
+ internal override unsafe int GetBytes(char* chars, int charCount,
+ byte* bytes, int byteCount, EncoderNLS encoder)
+ {
+ // Just need to ASSERT, this is called by something else internal that checked parameters already
+ Debug.Assert(bytes != null, "[ASCIIEncoding.GetBytes]bytes is null");
+ Debug.Assert(byteCount >= 0, "[ASCIIEncoding.GetBytes]byteCount is negative");
+ Debug.Assert(chars != null, "[ASCIIEncoding.GetBytes]chars is null");
+ Debug.Assert(charCount >= 0, "[ASCIIEncoding.GetBytes]charCount is negative");
+
+ // Assert because we shouldn't be able to have a null encoder.
+ Debug.Assert(encoderFallback != null, "[ASCIIEncoding.GetBytes]Attempting to use null encoder fallback");
+
+ // Get any left over characters
+ char charLeftOver = (char)0;
+ EncoderReplacementFallback fallback = null;
+
+ // For fallback we may need a fallback buffer, we know we aren't default fallback.
+ EncoderFallbackBuffer fallbackBuffer = null;
+ char* charsForFallback;
+
+ // prepare our end
+ char* charEnd = chars + charCount;
+ byte* byteStart = bytes;
+ char* charStart = chars;
+
+ if (encoder != null)
+ {
+ charLeftOver = encoder.charLeftOver;
+ fallback = encoder.Fallback as EncoderReplacementFallback;
+
+ // We mustn't have left over fallback data when counting
+ if (encoder.InternalHasFallbackBuffer)
+ {
+ // We always need the fallback buffer in get bytes so we can flush any remaining ones if necessary
+ fallbackBuffer = encoder.FallbackBuffer;
+ if (fallbackBuffer.Remaining > 0 && encoder.m_throwOnOverflow)
+ throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, true);
+ }
+
+ Debug.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
+ "[ASCIIEncoding.GetBytes]leftover character should be high surrogate");
+
+ // Verify that we have no fallbackbuffer, for ASCII its always empty, so just assert
+ Debug.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
+ encoder.FallbackBuffer.Remaining == 0,
+ "[ASCIICodePageEncoding.GetBytes]Expected empty fallback buffer");
+ }
+ else
+ {
+ fallback = this.EncoderFallback as EncoderReplacementFallback;
+ }
+
+
+ // See if we do the fast default or slightly slower fallback
+ if (fallback != null && fallback.MaxCharCount == 1)
+ {
+ // Fast version
+ char cReplacement = fallback.DefaultString[0];
+
+ // Check for replacements in range, otherwise fall back to slow version.
+ if (cReplacement <= (char)0x7f)
+ {
+ // We should have exactly as many output bytes as input bytes, unless there's a left
+ // over character, in which case we may need one more.
+ // If we had a left over character will have to add a ? (This happens if they had a funky
+ // fallback last time, but not this time.) (We can't spit any out though
+ // because with fallback encoder each surrogate is treated as a seperate code point)
+ if (charLeftOver > 0)
+ {
+ // Have to have room
+ // Throw even if doing no throw version because this is just 1 char,
+ // so buffer will never be big enough
+ if (byteCount == 0)
+ ThrowBytesOverflow(encoder, true);
+
+ // This'll make sure we still have more room and also make sure our return value is correct.
+ *(bytes++) = (byte)cReplacement;
+ byteCount--; // We used one of the ones we were counting.
+ }
+
+ // This keeps us from overrunning our output buffer
+ if (byteCount < charCount)
+ {
+ // Throw or make buffer smaller?
+ ThrowBytesOverflow(encoder, byteCount < 1);
+
+ // Just use what we can
+ charEnd = chars + byteCount;
+ }
+
+ // We just do a quick copy
+ while (chars < charEnd)
+ {
+ char ch2 = *(chars++);
+ if (ch2 >= 0x0080) *(bytes++) = (byte)cReplacement;
+ else *(bytes++) = unchecked((byte)(ch2));
+ }
+
+ // Clear encoder
+ if (encoder != null)
+ {
+ encoder.charLeftOver = (char)0;
+ encoder.m_charsUsed = (int)(chars - charStart);
+ }
+
+ return (int)(bytes - byteStart);
+ }
+ }
+
+ // Slower version, have to do real fallback.
+
+ // prepare our end
+ byte* byteEnd = bytes + byteCount;
+
+ // We may have a left over character from last time, try and process it.
+ if (charLeftOver > 0)
+ {
+ // Initialize the buffer
+ Debug.Assert(encoder != null,
+ "[ASCIIEncoding.GetBytes]Expected non null encoder if we have surrogate left over");
+ fallbackBuffer = encoder.FallbackBuffer;
+ fallbackBuffer.InternalInitialize(chars, charEnd, encoder, true);
+
+ // Since left over char was a surrogate, it'll have to be fallen back.
+ // Get Fallback
+ // This will fallback a pair if *chars is a low surrogate
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ fallbackBuffer.InternalFallback(charLeftOver, ref charsForFallback);
+ chars = charsForFallback;
+ }
+
+ // Now we may have fallback char[] already from the encoder
+
+ // Go ahead and do it, including the fallback.
+ char ch;
+ while ((ch = (fallbackBuffer == null) ? '\0' : fallbackBuffer.InternalGetNextChar()) != 0 ||
+ chars < charEnd)
+ {
+ // First unwind any fallback
+ if (ch == 0)
+ {
+ // No fallback, just get next char
+ ch = *chars;
+ chars++;
+ }
+
+ // Check for fallback, this'll catch surrogate pairs too.
+ // All characters >= 0x80 must fall back.
+ if (ch > 0x7f)
+ {
+ // Initialize the buffer
+ if (fallbackBuffer == null)
+ {
+ if (encoder == null)
+ fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = encoder.FallbackBuffer;
+ fallbackBuffer.InternalInitialize(charEnd - charCount, charEnd, encoder, true);
+ }
+
+ // Get Fallback
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ fallbackBuffer.InternalFallback(ch, ref charsForFallback);
+ chars = charsForFallback;
+
+ // Go ahead & continue (& do the fallback)
+ continue;
+ }
+
+ // We'll use this one
+ // Bounds check
+ if (bytes >= byteEnd)
+ {
+ // didn't use this char, we'll throw or use buffer
+ if (fallbackBuffer == null || fallbackBuffer.bFallingBack == false)
+ {
+ Debug.Assert(chars > charStart || bytes == byteStart,
+ "[ASCIIEncoding.GetBytes]Expected chars to have advanced already.");
+ chars--; // don't use last char
+ }
+ else
+ fallbackBuffer.MovePrevious();
+
+ // Are we throwing or using buffer?
+ ThrowBytesOverflow(encoder, bytes == byteStart); // throw?
+ break; // don't throw, stop
+ }
+
+ // Go ahead and add it
+ *bytes = unchecked((byte)ch);
+ bytes++;
+ }
+
+ // Need to do encoder stuff
+ if (encoder != null)
+ {
+ // Fallback stuck it in encoder if necessary, but we have to clear MustFlush cases
+ if (fallbackBuffer != null && !fallbackBuffer.bUsedEncoder)
+ // Clear it in case of MustFlush
+ encoder.charLeftOver = (char)0;
+
+ // Set our chars used count
+ encoder.m_charsUsed = (int)(chars - charStart);
+ }
+
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0 ||
+ (encoder != null && !encoder.m_throwOnOverflow),
+ "[ASCIIEncoding.GetBytes]Expected Empty fallback buffer at end");
+
+ return (int)(bytes - byteStart);
+ }
+
+ // This is internal and called by something else,
+ internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS decoder)
+ {
+ // Just assert, we're called internally so these should be safe, checked already
+ Debug.Assert(bytes != null, "[ASCIIEncoding.GetCharCount]bytes is null");
+ Debug.Assert(count >= 0, "[ASCIIEncoding.GetCharCount]byteCount is negative");
+
+ // ASCII doesn't do best fit, so don't have to check for it, find out which decoder fallback we're using
+ DecoderReplacementFallback fallback = null;
+
+ if (decoder == null)
+ fallback = this.DecoderFallback as DecoderReplacementFallback;
+ else
+ {
+ fallback = decoder.Fallback as DecoderReplacementFallback;
+ Debug.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer ||
+ decoder.FallbackBuffer.Remaining == 0,
+ "[ASCIICodePageEncoding.GetCharCount]Expected empty fallback buffer");
+ }
+
+ if (fallback != null && fallback.MaxCharCount == 1)
+ {
+ // Just return length, SBCS stay the same length because they don't map to surrogate
+ // pairs and we don't have a decoder fallback.
+
+ return count;
+ }
+
+ // Only need decoder fallback buffer if not using default replacement fallback, no best fit for ASCII
+ DecoderFallbackBuffer fallbackBuffer = null;
+
+ // Have to do it the hard way.
+ // Assume charCount will be == count
+ int charCount = count;
+ byte[] byteBuffer = new byte[1];
+
+ // Do it our fast way
+ byte* byteEnd = bytes + count;
+
+ // Quick loop
+ while (bytes < byteEnd)
+ {
+ // Faster if don't use *bytes++;
+ byte b = *bytes;
+ bytes++;
+
+ // If unknown we have to do fallback count
+ if (b >= 0x80)
+ {
+ if (fallbackBuffer == null)
+ {
+ if (decoder == null)
+ fallbackBuffer = this.DecoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = decoder.FallbackBuffer;
+ fallbackBuffer.InternalInitialize(byteEnd - count, null);
+ }
+
+ // Use fallback buffer
+ byteBuffer[0] = b;
+ charCount--; // Have to unreserve the one we already allocated for b
+ charCount += fallbackBuffer.InternalFallback(byteBuffer, bytes);
+ }
+ }
+
+ // Fallback buffer must be empty
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ "[ASCIIEncoding.GetCharCount]Expected Empty fallback buffer");
+
+ // Converted sequence is same length as input
+ return charCount;
+ }
+
+ internal override unsafe int GetChars(byte* bytes, int byteCount,
+ char* chars, int charCount, DecoderNLS decoder)
+ {
+ // Just need to ASSERT, this is called by something else internal that checked parameters already
+ Debug.Assert(bytes != null, "[ASCIIEncoding.GetChars]bytes is null");
+ Debug.Assert(byteCount >= 0, "[ASCIIEncoding.GetChars]byteCount is negative");
+ Debug.Assert(chars != null, "[ASCIIEncoding.GetChars]chars is null");
+ Debug.Assert(charCount >= 0, "[ASCIIEncoding.GetChars]charCount is negative");
+
+ // Do it fast way if using ? replacement fallback
+ byte* byteEnd = bytes + byteCount;
+ byte* byteStart = bytes;
+ char* charStart = chars;
+
+ // Note: ASCII doesn't do best fit, but we have to fallback if they use something > 0x7f
+ // Only need decoder fallback buffer if not using ? fallback.
+ // ASCII doesn't do best fit, so don't have to check for it, find out which decoder fallback we're using
+ DecoderReplacementFallback fallback = null;
+ char* charsForFallback;
+
+ if (decoder == null)
+ fallback = this.DecoderFallback as DecoderReplacementFallback;
+ else
+ {
+ fallback = decoder.Fallback as DecoderReplacementFallback;
+ Debug.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer ||
+ decoder.FallbackBuffer.Remaining == 0,
+ "[ASCIICodePageEncoding.GetChars]Expected empty fallback buffer");
+ }
+
+ if (fallback != null && fallback.MaxCharCount == 1)
+ {
+ // Try it the fast way
+ char replacementChar = fallback.DefaultString[0];
+
+ // Need byteCount chars, otherwise too small buffer
+ if (charCount < byteCount)
+ {
+ // Need at least 1 output byte, throw if must throw
+ ThrowCharsOverflow(decoder, charCount < 1);
+
+ // Not throwing, use what we can
+ byteEnd = bytes + charCount;
+ }
+
+ // Quick loop, just do '?' replacement because we don't have fallbacks for decodings.
+ while (bytes < byteEnd)
+ {
+ byte b = *(bytes++);
+ if (b >= 0x80)
+ // This is an invalid byte in the ASCII encoding.
+ *(chars++) = replacementChar;
+ else
+ *(chars++) = unchecked((char)b);
+ }
+
+ // bytes & chars used are the same
+ if (decoder != null)
+ decoder.m_bytesUsed = (int)(bytes - byteStart);
+ return (int)(chars - charStart);
+ }
+
+ // Slower way's going to need a fallback buffer
+ DecoderFallbackBuffer fallbackBuffer = null;
+ byte[] byteBuffer = new byte[1];
+ char* charEnd = chars + charCount;
+
+ // Not quite so fast loop
+ while (bytes < byteEnd)
+ {
+ // Faster if don't use *bytes++;
+ byte b = *(bytes);
+ bytes++;
+
+ if (b >= 0x80)
+ {
+ // This is an invalid byte in the ASCII encoding.
+ if (fallbackBuffer == null)
+ {
+ if (decoder == null)
+ fallbackBuffer = this.DecoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = decoder.FallbackBuffer;
+ fallbackBuffer.InternalInitialize(byteEnd - byteCount, charEnd);
+ }
+
+ // Use fallback buffer
+ byteBuffer[0] = b;
+
+ // Note that chars won't get updated unless this succeeds
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ bool fallbackResult = fallbackBuffer.InternalFallback(byteBuffer, bytes, ref charsForFallback);
+ chars = charsForFallback;
+
+ if (!fallbackResult)
+ {
+ // May or may not throw, but we didn't get this byte
+ Debug.Assert(bytes > byteStart || chars == charStart,
+ "[ASCIIEncoding.GetChars]Expected bytes to have advanced already (fallback case)");
+ bytes--; // unused byte
+ fallbackBuffer.InternalReset(); // Didn't fall this back
+ ThrowCharsOverflow(decoder, chars == charStart); // throw?
+ break; // don't throw, but stop loop
+ }
+ }
+ else
+ {
+ // Make sure we have buffer space
+ if (chars >= charEnd)
+ {
+ Debug.Assert(bytes > byteStart || chars == charStart,
+ "[ASCIIEncoding.GetChars]Expected bytes to have advanced already (normal case)");
+ bytes--; // unused byte
+ ThrowCharsOverflow(decoder, chars == charStart); // throw?
+ break; // don't throw, but stop loop
+ }
+
+ *(chars) = unchecked((char)b);
+ chars++;
+ }
+ }
+
+ // Might have had decoder fallback stuff.
+ if (decoder != null)
+ decoder.m_bytesUsed = (int)(bytes - byteStart);
+
+ // Expect Empty fallback buffer for GetChars
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ "[ASCIIEncoding.GetChars]Expected Empty fallback buffer");
+
+ return (int)(chars - charStart);
+ }
+
+
+ public override int GetMaxByteCount(int charCount)
+ {
+ if (charCount < 0)
+ throw new ArgumentOutOfRangeException(nameof(charCount),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Characters would be # of characters + 1 in case high surrogate is ? * max fallback
+ long byteCount = (long)charCount + 1;
+
+ if (EncoderFallback.MaxCharCount > 1)
+ byteCount *= EncoderFallback.MaxCharCount;
+
+ // 1 to 1 for most characters. Only surrogates with fallbacks have less.
+
+ if (byteCount > 0x7fffffff)
+ throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_GetByteCountOverflow);
+ return (int)byteCount;
+ }
+
+
+ public override int GetMaxCharCount(int byteCount)
+ {
+ if (byteCount < 0)
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Just return length, SBCS stay the same length because they don't map to surrogate
+ long charCount = (long)byteCount;
+
+ // 1 to 1 for most characters. Only surrogates with fallbacks have less, unknown fallbacks could be longer.
+ if (DecoderFallback.MaxCharCount > 1)
+ charCount *= DecoderFallback.MaxCharCount;
+
+ if (charCount > 0x7fffffff)
+ throw new ArgumentOutOfRangeException(nameof(byteCount), SR.ArgumentOutOfRange_GetCharCountOverflow);
+
+ return (int)charCount;
+ }
+
+ // True if and only if the encoding only uses single byte code points. (Ie, ASCII, 1252, etc)
+
+ public override bool IsSingleByte
+ {
+ get
+ {
+ return true;
+ }
+ }
+
+ public override Decoder GetDecoder()
+ {
+ return new DecoderNLS(this);
+ }
+
+
+ public override Encoder GetEncoder()
+ {
+ return new EncoderNLS(this);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Text/Decoder.cs b/src/mscorlib/shared/System/Text/Decoder.cs
new file mode 100644
index 0000000000..b2a003037b
--- /dev/null
+++ b/src/mscorlib/shared/System/Text/Decoder.cs
@@ -0,0 +1,339 @@
+// 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.Runtime.Serialization;
+using System.Text;
+using System;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System.Text
+{
+ // A Decoder is used to decode a sequence of blocks of bytes into a
+ // sequence of blocks of characters. Following instantiation of a decoder,
+ // sequential blocks of bytes are converted into blocks of characters through
+ // calls to the GetChars method. The decoder maintains state between the
+ // conversions, allowing it to correctly decode byte sequences that span
+ // adjacent blocks.
+ //
+ // Instances of specific implementations of the Decoder abstract base
+ // class are typically obtained through calls to the GetDecoder method
+ // of Encoding objects.
+ //
+ [Serializable]
+ public abstract class Decoder
+ {
+ internal DecoderFallback m_fallback = null;
+
+ [NonSerialized]
+ internal DecoderFallbackBuffer m_fallbackBuffer = null;
+
+ internal void SerializeDecoder(SerializationInfo info)
+ {
+ info.AddValue("m_fallback", this.m_fallback);
+ }
+
+ protected Decoder()
+ {
+ // We don't call default reset because default reset probably isn't good if we aren't initialized.
+ }
+
+ public DecoderFallback Fallback
+ {
+ get
+ {
+ return m_fallback;
+ }
+
+ set
+ {
+ if (value == null)
+ throw new ArgumentNullException(nameof(value));
+ Contract.EndContractBlock();
+
+ // Can't change fallback if buffer is wrong
+ if (m_fallbackBuffer != null && m_fallbackBuffer.Remaining > 0)
+ throw new ArgumentException(
+ SR.Argument_FallbackBufferNotEmpty, nameof(value));
+
+ m_fallback = value;
+ m_fallbackBuffer = null;
+ }
+ }
+
+ // Note: we don't test for threading here because async access to Encoders and Decoders
+ // doesn't work anyway.
+ public DecoderFallbackBuffer FallbackBuffer
+ {
+ get
+ {
+ if (m_fallbackBuffer == null)
+ {
+ if (m_fallback != null)
+ m_fallbackBuffer = m_fallback.CreateFallbackBuffer();
+ else
+ m_fallbackBuffer = DecoderFallback.ReplacementFallback.CreateFallbackBuffer();
+ }
+
+ return m_fallbackBuffer;
+ }
+ }
+
+ internal bool InternalHasFallbackBuffer
+ {
+ get
+ {
+ return m_fallbackBuffer != null;
+ }
+ }
+
+ // Reset the Decoder
+ //
+ // Normally if we call GetChars() and an error is thrown we don't change the state of the Decoder. This
+ // would allow the caller to correct the error condition and try again (such as if they need a bigger buffer.)
+ //
+ // If the caller doesn't want to try again after GetChars() throws an error, then they need to call Reset().
+ //
+ // Virtual implementation has to call GetChars with flush and a big enough buffer to clear a 0 byte string
+ // We avoid GetMaxCharCount() because a) we can't call the base encoder and b) it might be really big.
+ public virtual void Reset()
+ {
+ byte[] byteTemp = Array.Empty<byte>();
+ char[] charTemp = new char[GetCharCount(byteTemp, 0, 0, true)];
+ GetChars(byteTemp, 0, 0, charTemp, 0, true);
+ if (m_fallbackBuffer != null)
+ m_fallbackBuffer.Reset();
+ }
+
+ // Returns the number of characters the next call to GetChars will
+ // produce if presented with the given range of bytes. The returned value
+ // takes into account the state in which the decoder was left following the
+ // last call to GetChars. The state of the decoder is not affected
+ // by a call to this method.
+ //
+ public abstract int GetCharCount(byte[] bytes, int index, int count);
+
+ public virtual int GetCharCount(byte[] bytes, int index, int count, bool flush)
+ {
+ return GetCharCount(bytes, index, count);
+ }
+
+ // We expect this to be the workhorse for NLS Encodings, but for existing
+ // ones we need a working (if slow) default implementation)
+ [CLSCompliant(false)]
+ public virtual unsafe int GetCharCount(byte* bytes, int count, bool flush)
+ {
+ // Validate input parameters
+ if (bytes == null)
+ throw new ArgumentNullException(nameof(bytes),
+ SR.ArgumentNull_Array);
+
+ if (count < 0)
+ throw new ArgumentOutOfRangeException(nameof(count),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ byte[] arrbyte = new byte[count];
+ int index;
+
+ for (index = 0; index < count; index++)
+ arrbyte[index] = bytes[index];
+
+ return GetCharCount(arrbyte, 0, count);
+ }
+
+ // Decodes a range of bytes in a byte array into a range of characters
+ // in a character array. The method decodes byteCount bytes from
+ // bytes starting at index byteIndex, storing the resulting
+ // characters in chars starting at index charIndex. The
+ // decoding takes into account the state in which the decoder was left
+ // following the last call to this method.
+ //
+ // An exception occurs if the character array is not large enough to
+ // hold the complete decoding of the bytes. The GetCharCount method
+ // can be used to determine the exact number of characters that will be
+ // produced for a given range of bytes. Alternatively, the
+ // GetMaxCharCount method of the Encoding that produced this
+ // decoder can be used to determine the maximum number of characters that
+ // will be produced for a given number of bytes, regardless of the actual
+ // byte values.
+ //
+ public abstract int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ char[] chars, int charIndex);
+
+ public virtual int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ char[] chars, int charIndex, bool flush)
+ {
+ return GetChars(bytes, byteIndex, byteCount, chars, charIndex);
+ }
+
+ // We expect this to be the workhorse for NLS Encodings, but for existing
+ // ones we need a working (if slow) default implementation)
+ //
+ // WARNING WARNING WARNING
+ //
+ // WARNING: If this breaks it could be a security threat. Obviously we
+ // call this internally, so you need to make sure that your pointers, counts
+ // and indexes are correct when you call this method.
+ //
+ // In addition, we have internal code, which will be marked as "safe" calling
+ // this code. However this code is dependent upon the implementation of an
+ // external GetChars() method, which could be overridden by a third party and
+ // the results of which cannot be guaranteed. We use that result to copy
+ // the char[] to our char* output buffer. If the result count was wrong, we
+ // could easily overflow our output buffer. Therefore we do an extra test
+ // when we copy the buffer so that we don't overflow charCount either.
+ [CLSCompliant(false)]
+ public virtual unsafe int GetChars(byte* bytes, int byteCount,
+ char* chars, int charCount, bool flush)
+ {
+ // Validate input parameters
+ if (chars == null || bytes == null)
+ throw new ArgumentNullException(chars == null ? nameof(chars) : nameof(bytes),
+ SR.ArgumentNull_Array);
+
+ if (byteCount < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((byteCount < 0 ? nameof(byteCount) : nameof(charCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Get the byte array to convert
+ byte[] arrByte = new byte[byteCount];
+
+ int index;
+ for (index = 0; index < byteCount; index++)
+ arrByte[index] = bytes[index];
+
+ // Get the char array to fill
+ char[] arrChar = new char[charCount];
+
+ // Do the work
+ int result = GetChars(arrByte, 0, byteCount, arrChar, 0, flush);
+
+ Debug.Assert(result <= charCount, "Returned more chars than we have space for");
+
+ // Copy the char array
+ // WARNING: We MUST make sure that we don't copy too many chars. We can't
+ // rely on result because it could be a 3rd party implementation. We need
+ // to make sure we never copy more than charCount chars no matter the value
+ // of result
+ if (result < charCount)
+ charCount = result;
+
+ // We check both result and charCount so that we don't accidentally overrun
+ // our pointer buffer just because of an issue in GetChars
+ for (index = 0; index < charCount; index++)
+ chars[index] = arrChar[index];
+
+ return charCount;
+ }
+
+ // This method is used when the output buffer might not be large enough.
+ // It will decode until it runs out of bytes, and then it will return
+ // true if it the entire input was converted. In either case it
+ // will also return the number of converted bytes and output characters used.
+ // It will only throw a buffer overflow exception if the entire lenght of chars[] is
+ // too small to store the next char. (like 0 or maybe 1 or 4 for some encodings)
+ // We're done processing this buffer only if completed returns true.
+ //
+ // Might consider checking Max...Count to avoid the extra counting step.
+ //
+ // Note that if all of the input bytes are not consumed, then we'll do a /2, which means
+ // that its likely that we didn't consume as many bytes as we could have. For some
+ // applications this could be slow. (Like trying to exactly fill an output buffer from a bigger stream)
+ public virtual void Convert(byte[] bytes, int byteIndex, int byteCount,
+ char[] chars, int charIndex, int charCount, bool flush,
+ out int bytesUsed, out int charsUsed, out bool completed)
+ {
+ // Validate parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException((bytes == null ? nameof(bytes) : nameof(chars)),
+ SR.ArgumentNull_Array);
+
+ if (byteIndex < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((byteIndex < 0 ? nameof(byteIndex) : nameof(byteCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (charIndex < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? nameof(charIndex) : nameof(charCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (bytes.Length - byteIndex < byteCount)
+ throw new ArgumentOutOfRangeException(nameof(bytes),
+ SR.ArgumentOutOfRange_IndexCountBuffer);
+
+ if (chars.Length - charIndex < charCount)
+ throw new ArgumentOutOfRangeException(nameof(chars),
+ SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ bytesUsed = byteCount;
+
+ // Its easy to do if it won't overrun our buffer.
+ while (bytesUsed > 0)
+ {
+ if (GetCharCount(bytes, byteIndex, bytesUsed, flush) <= charCount)
+ {
+ charsUsed = GetChars(bytes, byteIndex, bytesUsed, chars, charIndex, flush);
+ completed = (bytesUsed == byteCount &&
+ (m_fallbackBuffer == null || m_fallbackBuffer.Remaining == 0));
+ return;
+ }
+
+ // Try again with 1/2 the count, won't flush then 'cause won't read it all
+ flush = false;
+ bytesUsed /= 2;
+ }
+
+ // Oops, we didn't have anything, we'll have to throw an overflow
+ throw new ArgumentException(SR.Argument_ConversionOverflow);
+ }
+
+ // This is the version that uses *.
+ // We're done processing this buffer only if completed returns true.
+ //
+ // Might consider checking Max...Count to avoid the extra counting step.
+ //
+ // Note that if all of the input bytes are not consumed, then we'll do a /2, which means
+ // that its likely that we didn't consume as many bytes as we could have. For some
+ // applications this could be slow. (Like trying to exactly fill an output buffer from a bigger stream)
+ [CLSCompliant(false)]
+ public virtual unsafe void Convert(byte* bytes, int byteCount,
+ char* chars, int charCount, bool flush,
+ out int bytesUsed, out int charsUsed, out bool completed)
+ {
+ // Validate input parameters
+ if (chars == null || bytes == null)
+ throw new ArgumentNullException(chars == null ? nameof(chars) : nameof(bytes),
+ SR.ArgumentNull_Array);
+
+ if (byteCount < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((byteCount < 0 ? nameof(byteCount) : nameof(charCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Get ready to do it
+ bytesUsed = byteCount;
+
+ // Its easy to do if it won't overrun our buffer.
+ while (bytesUsed > 0)
+ {
+ if (GetCharCount(bytes, bytesUsed, flush) <= charCount)
+ {
+ charsUsed = GetChars(bytes, bytesUsed, chars, charCount, flush);
+ completed = (bytesUsed == byteCount &&
+ (m_fallbackBuffer == null || m_fallbackBuffer.Remaining == 0));
+ return;
+ }
+
+ // Try again with 1/2 the count, won't flush then 'cause won't read it all
+ flush = false;
+ bytesUsed /= 2;
+ }
+
+ // Oops, we didn't have anything, we'll have to throw an overflow
+ throw new ArgumentException(SR.Argument_ConversionOverflow);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Text/Encoder.cs b/src/mscorlib/shared/System/Text/Encoder.cs
new file mode 100644
index 0000000000..e4e91765e1
--- /dev/null
+++ b/src/mscorlib/shared/System/Text/Encoder.cs
@@ -0,0 +1,333 @@
+// 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.Runtime.Serialization;
+using System.Text;
+using System;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System.Text
+{
+ // An Encoder is used to encode a sequence of blocks of characters into
+ // a sequence of blocks of bytes. Following instantiation of an encoder,
+ // sequential blocks of characters are converted into blocks of bytes through
+ // calls to the GetBytes method. The encoder maintains state between the
+ // conversions, allowing it to correctly encode character sequences that span
+ // adjacent blocks.
+ //
+ // Instances of specific implementations of the Encoder abstract base
+ // class are typically obtained through calls to the GetEncoder method
+ // of Encoding objects.
+ //
+ [Serializable]
+ public abstract class Encoder
+ {
+ internal EncoderFallback m_fallback = null;
+
+ [NonSerialized]
+ internal EncoderFallbackBuffer m_fallbackBuffer = null;
+
+ internal void SerializeEncoder(SerializationInfo info)
+ {
+ info.AddValue("m_fallback", this.m_fallback);
+ }
+
+ protected Encoder()
+ {
+ // We don't call default reset because default reset probably isn't good if we aren't initialized.
+ }
+
+ public EncoderFallback Fallback
+ {
+ get
+ {
+ return m_fallback;
+ }
+
+ set
+ {
+ if (value == null)
+ throw new ArgumentNullException(nameof(value));
+ Contract.EndContractBlock();
+
+ // Can't change fallback if buffer is wrong
+ if (m_fallbackBuffer != null && m_fallbackBuffer.Remaining > 0)
+ throw new ArgumentException(
+ SR.Argument_FallbackBufferNotEmpty, nameof(value));
+
+ m_fallback = value;
+ m_fallbackBuffer = null;
+ }
+ }
+
+ // Note: we don't test for threading here because async access to Encoders and Decoders
+ // doesn't work anyway.
+ public EncoderFallbackBuffer FallbackBuffer
+ {
+ get
+ {
+ if (m_fallbackBuffer == null)
+ {
+ if (m_fallback != null)
+ m_fallbackBuffer = m_fallback.CreateFallbackBuffer();
+ else
+ m_fallbackBuffer = EncoderFallback.ReplacementFallback.CreateFallbackBuffer();
+ }
+
+ return m_fallbackBuffer;
+ }
+ }
+
+ internal bool InternalHasFallbackBuffer
+ {
+ get
+ {
+ return m_fallbackBuffer != null;
+ }
+ }
+
+ // Reset the Encoder
+ //
+ // Normally if we call GetBytes() and an error is thrown we don't change the state of the encoder. This
+ // would allow the caller to correct the error condition and try again (such as if they need a bigger buffer.)
+ //
+ // If the caller doesn't want to try again after GetBytes() throws an error, then they need to call Reset().
+ //
+ // Virtual implementation has to call GetBytes with flush and a big enough buffer to clear a 0 char string
+ // We avoid GetMaxByteCount() because a) we can't call the base encoder and b) it might be really big.
+ public virtual void Reset()
+ {
+ char[] charTemp = { };
+ byte[] byteTemp = new byte[GetByteCount(charTemp, 0, 0, true)];
+ GetBytes(charTemp, 0, 0, byteTemp, 0, true);
+ if (m_fallbackBuffer != null)
+ m_fallbackBuffer.Reset();
+ }
+
+ // Returns the number of bytes the next call to GetBytes will
+ // produce if presented with the given range of characters and the given
+ // value of the flush parameter. The returned value takes into
+ // account the state in which the encoder was left following the last call
+ // to GetBytes. The state of the encoder is not affected by a call
+ // to this method.
+ //
+ public abstract int GetByteCount(char[] chars, int index, int count, bool flush);
+
+ // We expect this to be the workhorse for NLS encodings
+ // unfortunately for existing overrides, it has to call the [] version,
+ // which is really slow, so avoid this method if you might be calling external encodings.
+ [CLSCompliant(false)]
+ public virtual unsafe int GetByteCount(char* chars, int count, bool flush)
+ {
+ // Validate input parameters
+ if (chars == null)
+ throw new ArgumentNullException(nameof(chars),
+ SR.ArgumentNull_Array);
+
+ if (count < 0)
+ throw new ArgumentOutOfRangeException(nameof(count),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ char[] arrChar = new char[count];
+ int index;
+
+ for (index = 0; index < count; index++)
+ arrChar[index] = chars[index];
+
+ return GetByteCount(arrChar, 0, count, flush);
+ }
+
+ // Encodes a range of characters in a character array into a range of bytes
+ // in a byte array. The method encodes charCount characters from
+ // chars starting at index charIndex, storing the resulting
+ // bytes in bytes starting at index byteIndex. The encoding
+ // takes into account the state in which the encoder was left following the
+ // last call to this method. The flush parameter indicates whether
+ // the encoder should flush any shift-states and partial characters at the
+ // end of the conversion. To ensure correct termination of a sequence of
+ // blocks of encoded bytes, the last call to GetBytes should specify
+ // a value of true for the flush parameter.
+ //
+ // An exception occurs if the byte array is not large enough to hold the
+ // complete encoding of the characters. The GetByteCount method can
+ // be used to determine the exact number of bytes that will be produced for
+ // a given range of characters. Alternatively, the GetMaxByteCount
+ // method of the Encoding that produced this encoder can be used to
+ // determine the maximum number of bytes that will be produced for a given
+ // number of characters, regardless of the actual character values.
+ //
+ public abstract int GetBytes(char[] chars, int charIndex, int charCount,
+ byte[] bytes, int byteIndex, bool flush);
+
+ // We expect this to be the workhorse for NLS Encodings, but for existing
+ // ones we need a working (if slow) default implementation)
+ //
+ // WARNING WARNING WARNING
+ //
+ // WARNING: If this breaks it could be a security threat. Obviously we
+ // call this internally, so you need to make sure that your pointers, counts
+ // and indexes are correct when you call this method.
+ //
+ // In addition, we have internal code, which will be marked as "safe" calling
+ // this code. However this code is dependent upon the implementation of an
+ // external GetBytes() method, which could be overridden by a third party and
+ // the results of which cannot be guaranteed. We use that result to copy
+ // the byte[] to our byte* output buffer. If the result count was wrong, we
+ // could easily overflow our output buffer. Therefore we do an extra test
+ // when we copy the buffer so that we don't overflow byteCount either.
+ [CLSCompliant(false)]
+ public virtual unsafe int GetBytes(char* chars, int charCount,
+ byte* bytes, int byteCount, bool flush)
+ {
+ // Validate input parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars),
+ SR.ArgumentNull_Array);
+
+ if (charCount < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((charCount < 0 ? nameof(charCount) : nameof(byteCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Get the char array to convert
+ char[] arrChar = new char[charCount];
+
+ int index;
+ for (index = 0; index < charCount; index++)
+ arrChar[index] = chars[index];
+
+ // Get the byte array to fill
+ byte[] arrByte = new byte[byteCount];
+
+ // Do the work
+ int result = GetBytes(arrChar, 0, charCount, arrByte, 0, flush);
+
+ Debug.Assert(result <= byteCount, "Returned more bytes than we have space for");
+
+ // Copy the byte array
+ // WARNING: We MUST make sure that we don't copy too many bytes. We can't
+ // rely on result because it could be a 3rd party implementation. We need
+ // to make sure we never copy more than byteCount bytes no matter the value
+ // of result
+ if (result < byteCount)
+ byteCount = result;
+
+ // Don't copy too many bytes!
+ for (index = 0; index < byteCount; index++)
+ bytes[index] = arrByte[index];
+
+ return byteCount;
+ }
+
+ // This method is used to avoid running out of output buffer space.
+ // It will encode until it runs out of chars, and then it will return
+ // true if it the entire input was converted. In either case it
+ // will also return the number of converted chars and output bytes used.
+ // It will only throw a buffer overflow exception if the entire lenght of bytes[] is
+ // too small to store the next byte. (like 0 or maybe 1 or 4 for some encodings)
+ // We're done processing this buffer only if completed returns true.
+ //
+ // Might consider checking Max...Count to avoid the extra counting step.
+ //
+ // Note that if all of the input chars are not consumed, then we'll do a /2, which means
+ // that its likely that we didn't consume as many chars as we could have. For some
+ // applications this could be slow. (Like trying to exactly fill an output buffer from a bigger stream)
+ public virtual void Convert(char[] chars, int charIndex, int charCount,
+ byte[] bytes, int byteIndex, int byteCount, bool flush,
+ out int charsUsed, out int bytesUsed, out bool completed)
+ {
+ // Validate parameters
+ if (chars == null || bytes == null)
+ throw new ArgumentNullException((chars == null ? nameof(chars) : nameof(bytes)),
+ SR.ArgumentNull_Array);
+
+ if (charIndex < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? nameof(charIndex) : nameof(charCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (byteIndex < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((byteIndex < 0 ? nameof(byteIndex) : nameof(byteCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (chars.Length - charIndex < charCount)
+ throw new ArgumentOutOfRangeException(nameof(chars),
+ SR.ArgumentOutOfRange_IndexCountBuffer);
+
+ if (bytes.Length - byteIndex < byteCount)
+ throw new ArgumentOutOfRangeException(nameof(bytes),
+ SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ charsUsed = charCount;
+
+ // Its easy to do if it won't overrun our buffer.
+ // Note: We don't want to call unsafe version because that might be an untrusted version
+ // which could be really unsafe and we don't want to mix it up.
+ while (charsUsed > 0)
+ {
+ if (GetByteCount(chars, charIndex, charsUsed, flush) <= byteCount)
+ {
+ bytesUsed = GetBytes(chars, charIndex, charsUsed, bytes, byteIndex, flush);
+ completed = (charsUsed == charCount &&
+ (m_fallbackBuffer == null || m_fallbackBuffer.Remaining == 0));
+ return;
+ }
+
+ // Try again with 1/2 the count, won't flush then 'cause won't read it all
+ flush = false;
+ charsUsed /= 2;
+ }
+
+ // Oops, we didn't have anything, we'll have to throw an overflow
+ throw new ArgumentException(SR.Argument_ConversionOverflow);
+ }
+
+ // Same thing, but using pointers
+ //
+ // Might consider checking Max...Count to avoid the extra counting step.
+ //
+ // Note that if all of the input chars are not consumed, then we'll do a /2, which means
+ // that its likely that we didn't consume as many chars as we could have. For some
+ // applications this could be slow. (Like trying to exactly fill an output buffer from a bigger stream)
+ [CLSCompliant(false)]
+ public virtual unsafe void Convert(char* chars, int charCount,
+ byte* bytes, int byteCount, bool flush,
+ out int charsUsed, out int bytesUsed, out bool completed)
+ {
+ // Validate input parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars),
+ SR.ArgumentNull_Array);
+ if (charCount < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((charCount < 0 ? nameof(charCount) : nameof(byteCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Get ready to do it
+ charsUsed = charCount;
+
+ // Its easy to do if it won't overrun our buffer.
+ while (charsUsed > 0)
+ {
+ if (GetByteCount(chars, charsUsed, flush) <= byteCount)
+ {
+ bytesUsed = GetBytes(chars, charsUsed, bytes, byteCount, flush);
+ completed = (charsUsed == charCount &&
+ (m_fallbackBuffer == null || m_fallbackBuffer.Remaining == 0));
+ return;
+ }
+
+ // Try again with 1/2 the count, won't flush then 'cause won't read it all
+ flush = false;
+ charsUsed /= 2;
+ }
+
+ // Oops, we didn't have anything, we'll have to throw an overflow
+ throw new ArgumentException(SR.Argument_ConversionOverflow);
+ }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Text/EncodingInfo.cs b/src/mscorlib/shared/System/Text/EncodingInfo.cs
new file mode 100644
index 0000000000..360dd7f638
--- /dev/null
+++ b/src/mscorlib/shared/System/Text/EncodingInfo.cs
@@ -0,0 +1,72 @@
+// 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.Text;
+
+namespace System.Text
+{
+ [Serializable]
+ public sealed class EncodingInfo
+ {
+ private int iCodePage; // Code Page #
+ private string strEncodingName; // Short name (web name)
+ private string strDisplayName; // Full localized name
+
+ internal EncodingInfo(int codePage, string name, string displayName)
+ {
+ iCodePage = codePage;
+ strEncodingName = name;
+ strDisplayName = displayName;
+ }
+
+
+ public int CodePage
+ {
+ get
+ {
+ return iCodePage;
+ }
+ }
+
+
+ public string Name
+ {
+ get
+ {
+ return strEncodingName;
+ }
+ }
+
+
+ public string DisplayName
+ {
+ get
+ {
+ return strDisplayName;
+ }
+ }
+
+
+ public Encoding GetEncoding()
+ {
+ return Encoding.GetEncoding(iCodePage);
+ }
+
+ public override bool Equals(Object value)
+ {
+ EncodingInfo that = value as EncodingInfo;
+ if (that != null)
+ {
+ return (this.CodePage == that.CodePage);
+ }
+ return (false);
+ }
+
+ public override int GetHashCode()
+ {
+ return this.CodePage;
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Text/EncodingNLS.cs b/src/mscorlib/shared/System/Text/EncodingNLS.cs
new file mode 100644
index 0000000000..205ae26902
--- /dev/null
+++ b/src/mscorlib/shared/System/Text/EncodingNLS.cs
@@ -0,0 +1,322 @@
+// 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.Diagnostics.Contracts;
+using System.Collections;
+using System.Globalization;
+using System.Threading;
+
+namespace System.Text
+{
+ // This class overrides Encoding with the things we need for our NLS Encodings
+ //
+ // All of the GetBytes/Chars GetByte/CharCount methods are just wrappers for the pointer
+ // plus decoder/encoder method that is our real workhorse. Note that this is an internal
+ // class, so our public classes cannot derive from this class. Because of this, all of the
+ // GetBytes/Chars GetByte/CharCount wrapper methods are duplicated in all of our public
+ // encodings, which currently include:
+ //
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, & UnicodeEncoding
+ //
+ // So if you change the wrappers in this class, you must change the wrappers in the other classes
+ // as well because they should have the same behavior.
+
+ [Serializable]
+ internal abstract class EncodingNLS : Encoding
+ {
+ protected EncodingNLS(int codePage) : base(codePage)
+ {
+ }
+
+ // Returns the number of bytes required to encode a range of characters in
+ // a character array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+ public override unsafe int GetByteCount(char[] chars, int index, int count)
+ {
+ // Validate input parameters
+ if (chars == null)
+ throw new ArgumentNullException("chars", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (chars.Length - index < count)
+ throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // If no input, return 0, avoid fixed empty array problem
+ if (count == 0)
+ return 0;
+
+ // Just call the pointer version
+ fixed (char* pChars = chars)
+ return GetByteCount(pChars + index, count, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+ public override unsafe int GetByteCount(String s)
+ {
+ // Validate input
+ if (s==null)
+ throw new ArgumentNullException("s");
+ Contract.EndContractBlock();
+
+ fixed (char* pChars = s)
+ return GetByteCount(pChars, s.Length, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ public override unsafe int GetByteCount(char* chars, int count)
+ {
+ // Validate Parameters
+ if (chars == null)
+ throw new ArgumentNullException("chars", SR.ArgumentNull_Array);
+
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Call it with empty encoder
+ return GetByteCount(chars, count, null);
+ }
+
+ // Parent method is safe.
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ public override unsafe int GetBytes(String s, int charIndex, int charCount,
+ byte[] bytes, int byteIndex)
+ {
+ if (s == null || bytes == null)
+ throw new ArgumentNullException((s == null ? "s" : "bytes"), SR.ArgumentNull_Array);
+
+ if (charIndex < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? "charIndex" : "charCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (s.Length - charIndex < charCount)
+ throw new ArgumentOutOfRangeException("s", SR.ArgumentOutOfRange_IndexCount);
+
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ int byteCount = bytes.Length - byteIndex;
+
+ // Fixed doesn't like empty arrays
+ if (bytes.Length == 0)
+ bytes = new byte[1];
+
+ fixed (char* pChars = s) fixed (byte* pBytes = &bytes[0])
+ return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
+ }
+
+ // Encodes a range of characters in a character array into a range of bytes
+ // in a byte array. An exception occurs if the byte array is not large
+ // enough to hold the complete encoding of the characters. The
+ // GetByteCount method can be used to determine the exact number of
+ // bytes that will be produced for a given range of characters.
+ // Alternatively, the GetMaxByteCount method can be used to
+ // determine the maximum number of bytes that will be produced for a given
+ // number of characters, regardless of the actual character values.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+ public override unsafe int GetBytes(char[] chars, int charIndex, int charCount,
+ byte[] bytes, int byteIndex)
+ {
+ // Validate parameters
+ if (chars == null || bytes == null)
+ throw new ArgumentNullException((chars == null ? "chars" : "bytes"), SR.ArgumentNull_Array);
+
+ if (charIndex < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? "charIndex" : "charCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (chars.Length - charIndex < charCount)
+ throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer);
+
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ // If nothing to encode return 0, avoid fixed problem
+ if (charCount == 0)
+ return 0;
+
+ // Just call pointer version
+ int byteCount = bytes.Length - byteIndex;
+
+ // Fixed doesn't like empty arrays
+ if (bytes.Length == 0)
+ bytes = new byte[1];
+
+ fixed (char* pChars = chars) fixed (byte* pBytes = &bytes[0])
+ // Remember that byteCount is # to decode, not size of array.
+ return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
+ {
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (charCount < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetBytes(chars, charCount, bytes, byteCount, null);
+ }
+
+ // Returns the number of characters produced by decoding a range of bytes
+ // in a byte array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+ public override unsafe int GetCharCount(byte[] bytes, int index, int count)
+ {
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (bytes.Length - index < count)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // If no input just return 0, fixed doesn't like 0 length arrays
+ if (count == 0)
+ return 0;
+
+ // Just call pointer version
+ fixed (byte* pBytes = bytes)
+ return GetCharCount(pBytes + index, count, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ public override unsafe int GetCharCount(byte* bytes, int count)
+ {
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetCharCount(bytes, count, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+ public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ char[] chars, int charIndex)
+ {
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (byteIndex < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((byteIndex < 0 ? "byteIndex" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if ( bytes.Length - byteIndex < byteCount)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+
+ if (charIndex < 0 || charIndex > chars.Length)
+ throw new ArgumentOutOfRangeException("charIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ // If no input, return 0 & avoid fixed problem
+ if (byteCount == 0)
+ return 0;
+
+ // Just call pointer version
+ int charCount = chars.Length - charIndex;
+
+ // Fixed doesn't like empty arrays
+ if (chars.Length == 0)
+ chars = new char[1];
+
+ fixed (byte* pBytes = bytes) fixed (char* pChars = &chars[0])
+ // Remember that charCount is # to decode, not size of array
+ return GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
+ {
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (charCount < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetChars(bytes, byteCount, chars, charCount, null);
+ }
+
+ // Returns a string containing the decoded representation of a range of
+ // bytes in a byte array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+ public override unsafe String GetString(byte[] bytes, int index, int count)
+ {
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (bytes.Length - index < count)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // Avoid problems with empty input buffer
+ if (count == 0) return String.Empty;
+
+ fixed (byte* pBytes = bytes)
+ return String.CreateStringFromEncoding(
+ pBytes + index, count, this);
+ }
+
+ public override Decoder GetDecoder()
+ {
+ return new DecoderNLS(this);
+ }
+
+ public override Encoder GetEncoder()
+ {
+ return new EncoderNLS(this);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Text/EncodingProvider.cs b/src/mscorlib/shared/System/Text/EncodingProvider.cs
new file mode 100644
index 0000000000..ce8c3e0208
--- /dev/null
+++ b/src/mscorlib/shared/System/Text/EncodingProvider.cs
@@ -0,0 +1,136 @@
+// 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.Collections;
+using System.Collections.Generic;
+
+namespace System.Text
+{
+ public abstract class EncodingProvider
+ {
+ public EncodingProvider() { }
+ public abstract Encoding GetEncoding(string name);
+ public abstract Encoding GetEncoding(int codepage);
+
+ // GetEncoding should return either valid encoding or null. shouldn't throw any exception except on null name
+ public virtual Encoding GetEncoding(string name, EncoderFallback encoderFallback, DecoderFallback decoderFallback)
+ {
+ Encoding enc = GetEncoding(name);
+ if (enc != null)
+ {
+ enc = (Encoding)GetEncoding(name).Clone();
+ enc.EncoderFallback = encoderFallback;
+ enc.DecoderFallback = decoderFallback;
+ }
+
+ return enc;
+ }
+
+ public virtual Encoding GetEncoding(int codepage, EncoderFallback encoderFallback, DecoderFallback decoderFallback)
+ {
+ Encoding enc = GetEncoding(codepage);
+ if (enc != null)
+ {
+ enc = (Encoding)GetEncoding(codepage).Clone();
+ enc.EncoderFallback = encoderFallback;
+ enc.DecoderFallback = decoderFallback;
+ }
+
+ return enc;
+ }
+
+ internal static void AddProvider(EncodingProvider provider)
+ {
+ if (provider == null)
+ throw new ArgumentNullException(nameof(provider));
+
+ lock (s_InternalSyncObject)
+ {
+ if (s_providers == null)
+ {
+ s_providers = new EncodingProvider[1] { provider };
+ return;
+ }
+
+ if (Array.IndexOf(s_providers, provider) >= 0)
+ {
+ return;
+ }
+
+ EncodingProvider[] providers = new EncodingProvider[s_providers.Length + 1];
+ Array.Copy(s_providers, providers, s_providers.Length);
+ providers[providers.Length - 1] = provider;
+ s_providers = providers;
+ }
+ }
+
+ internal static Encoding GetEncodingFromProvider(int codepage)
+ {
+ if (s_providers == null)
+ return null;
+
+ EncodingProvider[] providers = s_providers;
+ foreach (EncodingProvider provider in providers)
+ {
+ Encoding enc = provider.GetEncoding(codepage);
+ if (enc != null)
+ return enc;
+ }
+
+ return null;
+ }
+
+ internal static Encoding GetEncodingFromProvider(string encodingName)
+ {
+ if (s_providers == null)
+ return null;
+
+ EncodingProvider[] providers = s_providers;
+ foreach (EncodingProvider provider in providers)
+ {
+ Encoding enc = provider.GetEncoding(encodingName);
+ if (enc != null)
+ return enc;
+ }
+
+ return null;
+ }
+
+ internal static Encoding GetEncodingFromProvider(int codepage, EncoderFallback enc, DecoderFallback dec)
+ {
+ if (s_providers == null)
+ return null;
+
+ EncodingProvider[] providers = s_providers;
+ foreach (EncodingProvider provider in providers)
+ {
+ Encoding encing = provider.GetEncoding(codepage, enc, dec);
+ if (encing != null)
+ return encing;
+ }
+
+ return null;
+ }
+
+ internal static Encoding GetEncodingFromProvider(string encodingName, EncoderFallback enc, DecoderFallback dec)
+ {
+ if (s_providers == null)
+ return null;
+
+ EncodingProvider[] providers = s_providers;
+ foreach (EncodingProvider provider in providers)
+ {
+ Encoding encoding = provider.GetEncoding(encodingName, enc, dec);
+ if (encoding != null)
+ return encoding;
+ }
+
+ return null;
+ }
+
+ private static Object s_InternalSyncObject = new Object();
+ private static volatile EncodingProvider[] s_providers;
+ }
+}
diff --git a/src/mscorlib/shared/System/Text/Normalization.cs b/src/mscorlib/shared/System/Text/Normalization.cs
new file mode 100644
index 0000000000..dc8bc2af71
--- /dev/null
+++ b/src/mscorlib/shared/System/Text/Normalization.cs
@@ -0,0 +1,29 @@
+// 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.
+
+namespace System.Text
+{
+ // This is the enumeration for Normalization Forms
+ public enum NormalizationForm
+ {
+ FormC = 1,
+ FormD = 2,
+ FormKC = 5,
+ FormKD = 6
+ }
+
+ internal enum ExtendedNormalizationForms
+ {
+ FormC = 1,
+ FormD = 2,
+ FormKC = 5,
+ FormKD = 6,
+ FormIdna = 0xd,
+ FormCDisallowUnassigned = 0x101,
+ FormDDisallowUnassigned = 0x102,
+ FormKCDisallowUnassigned = 0x105,
+ FormKDDisallowUnassigned = 0x106,
+ FormIdnaDisallowUnassigned = 0x10d
+ }
+}
diff --git a/src/mscorlib/shared/System/Text/StringBuilder.cs b/src/mscorlib/shared/System/Text/StringBuilder.cs
new file mode 100644
index 0000000000..df1a889823
--- /dev/null
+++ b/src/mscorlib/shared/System/Text/StringBuilder.cs
@@ -0,0 +1,2409 @@
+// 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.Text;
+using System.Runtime;
+using System.Runtime.Serialization;
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+using System.Security;
+using System.Threading;
+using System.Globalization;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Collections.Generic;
+
+namespace System.Text
+{
+ // This class represents a mutable string. It is convenient for situations in
+ // which it is desirable to modify a string, perhaps by removing, replacing, or
+ // inserting characters, without creating a new String subsequent to
+ // each modification.
+ //
+ // The methods contained within this class do not return a new StringBuilder
+ // object unless specified otherwise. This class may be used in conjunction with the String
+ // class to carry out modifications upon strings.
+ //
+ // When passing null into a constructor in VJ and VC, the null
+ // should be explicitly type cast.
+ // For Example:
+ // StringBuilder sb1 = new StringBuilder((StringBuilder)null);
+ // StringBuilder sb2 = new StringBuilder((String)null);
+ // Console.WriteLine(sb1);
+ // Console.WriteLine(sb2);
+ //
+ [Serializable]
+ public sealed partial class StringBuilder : ISerializable
+ {
+ // A StringBuilder is internally represented as a linked list of blocks each of which holds
+ // a chunk of the string. It turns out string as a whole can also be represented as just a chunk,
+ // so that is what we do.
+
+ //
+ //
+ // CLASS VARIABLES
+ //
+ //
+ internal char[] m_ChunkChars; // The characters in this block
+ internal StringBuilder m_ChunkPrevious; // Link to the block logically before this block
+ internal int m_ChunkLength; // The index in m_ChunkChars that represent the end of the block
+ internal int m_ChunkOffset; // The logical offset (sum of all characters in previous blocks)
+ internal int m_MaxCapacity = 0;
+
+ //
+ //
+ // STATIC CONSTANTS
+ //
+ //
+ internal const int DefaultCapacity = 16;
+ private const String CapacityField = "Capacity";
+ private const String MaxCapacityField = "m_MaxCapacity";
+ private const String StringValueField = "m_StringValue";
+ private const String ThreadIDField = "m_currentThread";
+ // We want to keep chunk arrays out of large object heap (< 85K bytes ~ 40K chars) to be sure.
+ // Making the maximum chunk size big means less allocation code called, but also more waste
+ // in unused characters and slower inserts / replaces (since you do need to slide characters over
+ // within a buffer).
+ internal const int MaxChunkSize = 8000;
+
+ //
+ //
+ //CONSTRUCTORS
+ //
+ //
+
+ // Creates a new empty string builder (i.e., it represents String.Empty)
+ // with the default capacity (16 characters).
+ public StringBuilder()
+ {
+ m_MaxCapacity = int.MaxValue;
+ m_ChunkChars = new char[DefaultCapacity];
+ }
+
+ // Create a new empty string builder (i.e., it represents String.Empty)
+ // with the specified capacity.
+ public StringBuilder(int capacity)
+ : this(capacity, int.MaxValue)
+ {
+ }
+
+ // Creates a new string builder from the specified string. If value
+ // is a null String (i.e., if it represents String.NullString)
+ // then the new string builder will also be null (i.e., it will also represent
+ // String.NullString).
+ //
+ public StringBuilder(String value)
+ : this(value, DefaultCapacity)
+ {
+ }
+
+ // Creates a new string builder from the specified string with the specified
+ // capacity. If value is a null String (i.e., if it represents
+ // String.NullString) then the new string builder will also be null
+ // (i.e., it will also represent String.NullString).
+ // The maximum number of characters this string may contain is set by capacity.
+ //
+ public StringBuilder(String value, int capacity)
+ : this(value, 0, ((value != null) ? value.Length : 0), capacity)
+ {
+ }
+
+ // Creates a new string builder from the specifed substring with the specified
+ // capacity. The maximum number of characters is set by capacity.
+ //
+ public StringBuilder(String value, int startIndex, int length, int capacity)
+ {
+ if (capacity < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(capacity),
+ SR.Format(SR.ArgumentOutOfRange_MustBePositive, nameof(capacity)));
+ }
+ if (length < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(length),
+ SR.Format(SR.ArgumentOutOfRange_MustBeNonNegNum, nameof(length)));
+ }
+ if (startIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex);
+ }
+ Contract.EndContractBlock();
+
+ if (value == null)
+ {
+ value = String.Empty;
+ }
+ if (startIndex > value.Length - length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_IndexLength);
+ }
+ m_MaxCapacity = Int32.MaxValue;
+ if (capacity == 0)
+ {
+ capacity = DefaultCapacity;
+ }
+ if (capacity < length)
+ capacity = length;
+
+ m_ChunkChars = new char[capacity];
+ m_ChunkLength = length;
+
+ unsafe
+ {
+ fixed (char* sourcePtr = value)
+ ThreadSafeCopy(sourcePtr + startIndex, m_ChunkChars, 0, length);
+ }
+ }
+
+ // Creates an empty StringBuilder with a minimum capacity of capacity
+ // and a maximum capacity of maxCapacity.
+ public StringBuilder(int capacity, int maxCapacity)
+ {
+ if (capacity > maxCapacity)
+ {
+ throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_Capacity);
+ }
+ if (maxCapacity < 1)
+ {
+ throw new ArgumentOutOfRangeException(nameof(maxCapacity), SR.ArgumentOutOfRange_SmallMaxCapacity);
+ }
+ if (capacity < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(capacity),
+ SR.Format(SR.ArgumentOutOfRange_MustBePositive, nameof(capacity)));
+ }
+ Contract.EndContractBlock();
+
+ if (capacity == 0)
+ {
+ capacity = Math.Min(DefaultCapacity, maxCapacity);
+ }
+
+ m_MaxCapacity = maxCapacity;
+ m_ChunkChars = new char[capacity];
+ }
+
+ private StringBuilder(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ int persistedCapacity = 0;
+ string persistedString = null;
+ int persistedMaxCapacity = Int32.MaxValue;
+ bool capacityPresent = false;
+
+ // Get the data
+ SerializationInfoEnumerator enumerator = info.GetEnumerator();
+ while (enumerator.MoveNext())
+ {
+ switch (enumerator.Name)
+ {
+ case MaxCapacityField:
+ persistedMaxCapacity = info.GetInt32(MaxCapacityField);
+ break;
+ case StringValueField:
+ persistedString = info.GetString(StringValueField);
+ break;
+ case CapacityField:
+ persistedCapacity = info.GetInt32(CapacityField);
+ capacityPresent = true;
+ break;
+ default:
+ // Ignore other fields for forward compatibility.
+ break;
+ }
+ }
+
+ // Check values and set defaults
+ if (persistedString == null)
+ {
+ persistedString = String.Empty;
+ }
+ if (persistedMaxCapacity < 1 || persistedString.Length > persistedMaxCapacity)
+ {
+ throw new SerializationException(SR.Serialization_StringBuilderMaxCapacity);
+ }
+
+ if (!capacityPresent)
+ {
+ // StringBuilder in V1.X did not persist the Capacity, so this is a valid legacy code path.
+ persistedCapacity = DefaultCapacity;
+ if (persistedCapacity < persistedString.Length)
+ {
+ persistedCapacity = persistedString.Length;
+ }
+ if (persistedCapacity > persistedMaxCapacity)
+ {
+ persistedCapacity = persistedMaxCapacity;
+ }
+ }
+ if (persistedCapacity < 0 || persistedCapacity < persistedString.Length || persistedCapacity > persistedMaxCapacity)
+ {
+ throw new SerializationException(SR.Serialization_StringBuilderCapacity);
+ }
+
+ // Assign
+ m_MaxCapacity = persistedMaxCapacity;
+ m_ChunkChars = new char[persistedCapacity];
+ persistedString.CopyTo(0, m_ChunkChars, 0, persistedString.Length);
+ m_ChunkLength = persistedString.Length;
+ m_ChunkPrevious = null;
+ VerifyClassInvariant();
+ }
+
+ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
+ throw new ArgumentNullException(nameof(info));
+ }
+ Contract.EndContractBlock();
+
+ VerifyClassInvariant();
+ info.AddValue(MaxCapacityField, m_MaxCapacity);
+ info.AddValue(CapacityField, Capacity);
+ info.AddValue(StringValueField, ToString());
+ // Note: persist "m_currentThread" to be compatible with old versions
+ info.AddValue(ThreadIDField, 0);
+ }
+
+ [System.Diagnostics.Conditional("_DEBUG")]
+ private void VerifyClassInvariant()
+ {
+ Debug.Assert((uint)(m_ChunkOffset + m_ChunkChars.Length) >= m_ChunkOffset, "Integer Overflow");
+ StringBuilder currentBlock = this;
+ int maxCapacity = this.m_MaxCapacity;
+ for (;;)
+ {
+ // All blocks have copy of the maxCapacity.
+ Debug.Assert(currentBlock.m_MaxCapacity == maxCapacity, "Bad maxCapacity");
+ Debug.Assert(currentBlock.m_ChunkChars != null, "Empty Buffer");
+
+ Debug.Assert(currentBlock.m_ChunkLength <= currentBlock.m_ChunkChars.Length, "Out of range length");
+ Debug.Assert(currentBlock.m_ChunkLength >= 0, "Negative length");
+ Debug.Assert(currentBlock.m_ChunkOffset >= 0, "Negative offset");
+
+ StringBuilder prevBlock = currentBlock.m_ChunkPrevious;
+ if (prevBlock == null)
+ {
+ Debug.Assert(currentBlock.m_ChunkOffset == 0, "First chunk's offset is not 0");
+ break;
+ }
+ // There are no gaps in the blocks.
+ Debug.Assert(currentBlock.m_ChunkOffset == prevBlock.m_ChunkOffset + prevBlock.m_ChunkLength, "There is a gap between chunks!");
+ currentBlock = prevBlock;
+ }
+ }
+
+ public int Capacity
+ {
+ get { return m_ChunkChars.Length + m_ChunkOffset; }
+ set
+ {
+ if (value < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_NegativeCapacity);
+ }
+ if (value > MaxCapacity)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_Capacity);
+ }
+ if (value < Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_SmallCapacity);
+ }
+ Contract.EndContractBlock();
+
+ if (Capacity != value)
+ {
+ int newLen = value - m_ChunkOffset;
+ char[] newArray = new char[newLen];
+ Array.Copy(m_ChunkChars, 0, newArray, 0, m_ChunkLength);
+ m_ChunkChars = newArray;
+ }
+ }
+ }
+
+ public int MaxCapacity
+ {
+ get { return m_MaxCapacity; }
+ }
+
+ // Ensures that the capacity of this string builder is at least the specified value.
+ // If capacity is greater than the capacity of this string builder, then the capacity
+ // is set to capacity; otherwise the capacity is unchanged.
+ //
+ public int EnsureCapacity(int capacity)
+ {
+ if (capacity < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_NegativeCapacity);
+ }
+ Contract.EndContractBlock();
+
+ if (Capacity < capacity)
+ Capacity = capacity;
+ return Capacity;
+ }
+
+ public override String ToString()
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+
+ VerifyClassInvariant();
+
+ if (Length == 0)
+ return String.Empty;
+
+ string ret = string.FastAllocateString(Length);
+ StringBuilder chunk = this;
+ unsafe
+ {
+ fixed (char* destinationPtr = ret)
+ {
+ do
+ {
+ if (chunk.m_ChunkLength > 0)
+ {
+ // Copy these into local variables so that they are stable even in the presence of race conditions
+ char[] sourceArray = chunk.m_ChunkChars;
+ int chunkOffset = chunk.m_ChunkOffset;
+ int chunkLength = chunk.m_ChunkLength;
+
+ // Check that we will not overrun our boundaries.
+ if ((uint)(chunkLength + chunkOffset) <= (uint)ret.Length && (uint)chunkLength <= (uint)sourceArray.Length)
+ {
+ fixed (char* sourcePtr = &sourceArray[0])
+ string.wstrcpy(destinationPtr + chunkOffset, sourcePtr, chunkLength);
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(chunkLength), SR.ArgumentOutOfRange_Index);
+ }
+ }
+ chunk = chunk.m_ChunkPrevious;
+ } while (chunk != null);
+
+ return ret;
+ }
+ }
+ }
+
+
+ // Converts a substring of this string builder to a String.
+ public String ToString(int startIndex, int length)
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+
+ int currentLength = this.Length;
+ if (startIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex);
+ }
+ if (startIndex > currentLength)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndexLargerThanLength);
+ }
+ if (length < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NegativeLength);
+ }
+ if (startIndex > (currentLength - length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_IndexLength);
+ }
+
+ VerifyClassInvariant();
+
+ StringBuilder chunk = this;
+ int sourceEndIndex = startIndex + length;
+
+ string ret = string.FastAllocateString(length);
+ int curDestIndex = length;
+ unsafe
+ {
+ fixed (char* destinationPtr = ret)
+ {
+ while (curDestIndex > 0)
+ {
+ int chunkEndIndex = sourceEndIndex - chunk.m_ChunkOffset;
+ if (chunkEndIndex >= 0)
+ {
+ if (chunkEndIndex > chunk.m_ChunkLength)
+ chunkEndIndex = chunk.m_ChunkLength;
+
+ int countLeft = curDestIndex;
+ int chunkCount = countLeft;
+ int chunkStartIndex = chunkEndIndex - countLeft;
+ if (chunkStartIndex < 0)
+ {
+ chunkCount += chunkStartIndex;
+ chunkStartIndex = 0;
+ }
+ curDestIndex -= chunkCount;
+
+ if (chunkCount > 0)
+ {
+ // work off of local variables so that they are stable even in the presence of race conditions
+ char[] sourceArray = chunk.m_ChunkChars;
+
+ // Check that we will not overrun our boundaries.
+ if ((uint)(chunkCount + curDestIndex) <= (uint)length && (uint)(chunkCount + chunkStartIndex) <= (uint)sourceArray.Length)
+ {
+ fixed (char* sourcePtr = &sourceArray[chunkStartIndex])
+ string.wstrcpy(destinationPtr + curDestIndex, sourcePtr, chunkCount);
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(chunkCount), SR.ArgumentOutOfRange_Index);
+ }
+ }
+ }
+ chunk = chunk.m_ChunkPrevious;
+ }
+
+ return ret;
+ }
+ }
+ }
+
+ // Convenience method for sb.Length=0;
+ public StringBuilder Clear()
+ {
+ this.Length = 0;
+ return this;
+ }
+
+ // Sets the length of the String in this buffer. If length is less than the current
+ // instance, the StringBuilder is truncated. If length is greater than the current
+ // instance, nulls are appended. The capacity is adjusted to be the same as the length.
+
+ public int Length
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<int>() >= 0);
+ return m_ChunkOffset + m_ChunkLength;
+ }
+ set
+ {
+ //If the new length is less than 0 or greater than our Maximum capacity, bail.
+ if (value < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_NegativeLength);
+ }
+
+ if (value > MaxCapacity)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_SmallCapacity);
+ }
+ Contract.EndContractBlock();
+
+ int originalCapacity = Capacity;
+
+ if (value == 0 && m_ChunkPrevious == null)
+ {
+ m_ChunkLength = 0;
+ m_ChunkOffset = 0;
+ Debug.Assert(Capacity >= originalCapacity, "setting the Length should never decrease the Capacity");
+ return;
+ }
+
+ int delta = value - Length;
+ // if the specified length is greater than the current length
+ if (delta > 0)
+ {
+ // the end of the string value of the current StringBuilder object is padded with the Unicode NULL character
+ Append('\0', delta); // We could improve on this, but who does this anyway?
+ }
+ // if the specified length is less than or equal to the current length
+ else
+ {
+ StringBuilder chunk = FindChunkForIndex(value);
+ if (chunk != this)
+ {
+ // we crossed a chunk boundary when reducing the Length, we must replace this middle-chunk with a new
+ // larger chunk to ensure the original capacity is preserved
+ int newLen = originalCapacity - chunk.m_ChunkOffset;
+ char[] newArray = new char[newLen];
+
+ Debug.Assert(newLen > chunk.m_ChunkChars.Length, "the new chunk should be larger than the one it is replacing");
+ Array.Copy(chunk.m_ChunkChars, 0, newArray, 0, chunk.m_ChunkLength);
+
+ m_ChunkChars = newArray;
+ m_ChunkPrevious = chunk.m_ChunkPrevious;
+ m_ChunkOffset = chunk.m_ChunkOffset;
+ }
+ m_ChunkLength = value - chunk.m_ChunkOffset;
+ VerifyClassInvariant();
+ }
+ Debug.Assert(Capacity >= originalCapacity, "setting the Length should never decrease the Capacity");
+ }
+ }
+
+ [System.Runtime.CompilerServices.IndexerName("Chars")]
+ public char this[int index]
+ {
+ get
+ {
+ StringBuilder chunk = this;
+ for (;;)
+ {
+ int indexInBlock = index - chunk.m_ChunkOffset;
+ if (indexInBlock >= 0)
+ {
+ if (indexInBlock >= chunk.m_ChunkLength)
+ throw new IndexOutOfRangeException();
+ return chunk.m_ChunkChars[indexInBlock];
+ }
+ chunk = chunk.m_ChunkPrevious;
+ if (chunk == null)
+ throw new IndexOutOfRangeException();
+ }
+ }
+ set
+ {
+ StringBuilder chunk = this;
+ for (;;)
+ {
+ int indexInBlock = index - chunk.m_ChunkOffset;
+ if (indexInBlock >= 0)
+ {
+ if (indexInBlock >= chunk.m_ChunkLength)
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
+ chunk.m_ChunkChars[indexInBlock] = value;
+ return;
+ }
+ chunk = chunk.m_ChunkPrevious;
+ if (chunk == null)
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
+ }
+ }
+ }
+
+ // Appends a character at the end of this string builder. The capacity is adjusted as needed.
+ public StringBuilder Append(char value, int repeatCount)
+ {
+ if (repeatCount < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(repeatCount), SR.ArgumentOutOfRange_NegativeCount);
+ }
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ Contract.EndContractBlock();
+
+ if (repeatCount == 0)
+ {
+ return this;
+ }
+
+ // this is where we can check if the repeatCount will put us over m_MaxCapacity
+ // We are doing the check here to prevent the corruption of the StringBuilder.
+ int newLength = Length + repeatCount;
+ if (newLength > m_MaxCapacity || newLength < repeatCount)
+ {
+ throw new ArgumentOutOfRangeException(nameof(repeatCount), SR.ArgumentOutOfRange_LengthGreaterThanCapacity);
+ }
+
+ int idx = m_ChunkLength;
+ while (repeatCount > 0)
+ {
+ if (idx < m_ChunkChars.Length)
+ {
+ m_ChunkChars[idx++] = value;
+ --repeatCount;
+ }
+ else
+ {
+ m_ChunkLength = idx;
+ ExpandByABlock(repeatCount);
+ Debug.Assert(m_ChunkLength == 0, "Expand should create a new block");
+ idx = 0;
+ }
+ }
+ m_ChunkLength = idx;
+ VerifyClassInvariant();
+ return this;
+ }
+
+ // Appends an array of characters at the end of this string builder. The capacity is adjusted as needed.
+ public StringBuilder Append(char[] value, int startIndex, int charCount)
+ {
+ if (startIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_GenericPositive);
+ }
+ if (charCount < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_GenericPositive);
+ }
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ Contract.EndContractBlock();
+
+ if (value == null)
+ {
+ if (startIndex == 0 && charCount == 0)
+ {
+ return this;
+ }
+ throw new ArgumentNullException(nameof(value));
+ }
+ if (charCount > value.Length - startIndex)
+ {
+ throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_Index);
+ }
+
+ if (charCount == 0)
+ {
+ return this;
+ }
+ unsafe
+ {
+ fixed (char* valueChars = &value[startIndex])
+ {
+ Append(valueChars, charCount);
+
+ return this;
+ }
+ }
+ }
+
+
+ // Appends a copy of this string at the end of this string builder.
+ public StringBuilder Append(String value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+
+ if (value != null)
+ {
+ // This is a hand specialization of the 'AppendHelper' code below.
+ // We could have just called AppendHelper.
+ char[] chunkChars = m_ChunkChars;
+ int chunkLength = m_ChunkLength;
+ int valueLen = value.Length;
+ int newCurrentIndex = chunkLength + valueLen;
+ if (newCurrentIndex < chunkChars.Length) // Use strictly < to avoid issue if count == 0, newIndex == length
+ {
+ if (valueLen <= 2)
+ {
+ if (valueLen > 0)
+ chunkChars[chunkLength] = value[0];
+ if (valueLen > 1)
+ chunkChars[chunkLength + 1] = value[1];
+ }
+ else
+ {
+ unsafe
+ {
+ fixed (char* valuePtr = value)
+ fixed (char* destPtr = &chunkChars[chunkLength])
+ string.wstrcpy(destPtr, valuePtr, valueLen);
+ }
+ }
+ m_ChunkLength = newCurrentIndex;
+ }
+ else
+ AppendHelper(value);
+ }
+ return this;
+ }
+
+
+ // We put this fixed in its own helper to avoid the cost zero initing valueChars in the
+ // case we don't actually use it.
+ private void AppendHelper(string value)
+ {
+ unsafe
+ {
+ fixed (char* valueChars = value)
+ Append(valueChars, value.Length);
+ }
+ }
+
+ // Appends a copy of the characters in value from startIndex to startIndex +
+ // count at the end of this string builder.
+ public StringBuilder Append(String value, int startIndex, int count)
+ {
+ if (startIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
+ }
+
+ if (count < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_GenericPositive);
+ }
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+
+ //If the value being added is null, eat the null
+ //and return.
+ if (value == null)
+ {
+ if (startIndex == 0 && count == 0)
+ {
+ return this;
+ }
+ throw new ArgumentNullException(nameof(value));
+ }
+
+ if (count == 0)
+ {
+ return this;
+ }
+
+ if (startIndex > value.Length - count)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
+ }
+
+ unsafe
+ {
+ fixed (char* valueChars = value)
+ {
+ Append(valueChars + startIndex, count);
+
+ return this;
+ }
+ }
+ }
+
+ public StringBuilder AppendLine()
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Append(Environment.NewLine);
+ }
+
+ public StringBuilder AppendLine(string value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ Append(value);
+ return Append(Environment.NewLine);
+ }
+
+ public void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count)
+ {
+ if (destination == null)
+ {
+ throw new ArgumentNullException(nameof(destination));
+ }
+
+ if (count < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), SR.Arg_NegativeArgCount);
+ }
+
+ if (destinationIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(destinationIndex),
+ SR.Format(SR.ArgumentOutOfRange_MustBeNonNegNum, nameof(destinationIndex)));
+ }
+
+ if (destinationIndex > destination.Length - count)
+ {
+ throw new ArgumentException(SR.ArgumentOutOfRange_OffsetOut);
+ }
+
+ if ((uint)sourceIndex > (uint)Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(sourceIndex), SR.ArgumentOutOfRange_Index);
+ }
+
+ if (sourceIndex > Length - count)
+ {
+ throw new ArgumentException(SR.Arg_LongerThanSrcString);
+ }
+ Contract.EndContractBlock();
+
+ VerifyClassInvariant();
+
+ StringBuilder chunk = this;
+ int sourceEndIndex = sourceIndex + count;
+ int curDestIndex = destinationIndex + count;
+ while (count > 0)
+ {
+ int chunkEndIndex = sourceEndIndex - chunk.m_ChunkOffset;
+ if (chunkEndIndex >= 0)
+ {
+ if (chunkEndIndex > chunk.m_ChunkLength)
+ chunkEndIndex = chunk.m_ChunkLength;
+
+ int chunkCount = count;
+ int chunkStartIndex = chunkEndIndex - count;
+ if (chunkStartIndex < 0)
+ {
+ chunkCount += chunkStartIndex;
+ chunkStartIndex = 0;
+ }
+ curDestIndex -= chunkCount;
+ count -= chunkCount;
+
+ // SafeCritical: we ensure that chunkStartIndex + chunkCount are within range of m_chunkChars
+ // as well as ensuring that curDestIndex + chunkCount are within range of destination
+ ThreadSafeCopy(chunk.m_ChunkChars, chunkStartIndex, destination, curDestIndex, chunkCount);
+ }
+ chunk = chunk.m_ChunkPrevious;
+ }
+ }
+
+ // Inserts multiple copies of a string into this string builder at the specified position.
+ // Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, this
+ // string builder is not changed.
+ //
+ public StringBuilder Insert(int index, String value, int count)
+ {
+ if (count < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
+ }
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ Contract.EndContractBlock();
+
+ //Range check the index.
+ int currentLength = Length;
+ if ((uint)index > (uint)currentLength)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
+ }
+
+ //If value is null, empty or count is 0, do nothing. This is ECMA standard.
+ if (value == null || value.Length == 0 || count == 0)
+ {
+ return this;
+ }
+
+ //Ensure we don't insert more chars than we can hold, and we don't
+ //have any integer overflow in our inserted characters.
+ long insertingChars = (long)value.Length * count;
+ if (insertingChars > MaxCapacity - this.Length)
+ {
+ throw new OutOfMemoryException();
+ }
+ Debug.Assert(insertingChars + this.Length < Int32.MaxValue);
+
+ StringBuilder chunk;
+ int indexInChunk;
+ MakeRoom(index, (int)insertingChars, out chunk, out indexInChunk, false);
+ unsafe
+ {
+ fixed (char* valuePtr = value)
+ {
+ while (count > 0)
+ {
+ ReplaceInPlaceAtChunk(ref chunk, ref indexInChunk, valuePtr, value.Length);
+ --count;
+ }
+
+ return this;
+ }
+ }
+ }
+
+ // Removes the specified characters from this string builder.
+ // The length of this string builder is reduced by
+ // length, but the capacity is unaffected.
+ //
+ public StringBuilder Remove(int startIndex, int length)
+ {
+ if (length < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NegativeLength);
+ }
+
+ if (startIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex);
+ }
+
+ if (length > Length - startIndex)
+ {
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_Index);
+ }
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ Contract.EndContractBlock();
+
+ if (Length == length && startIndex == 0)
+ {
+ // Optimization. If we are deleting everything
+ Length = 0;
+ return this;
+ }
+
+ if (length > 0)
+ {
+ StringBuilder chunk;
+ int indexInChunk;
+ Remove(startIndex, length, out chunk, out indexInChunk);
+ }
+ return this;
+ }
+
+ // Appends a boolean to the end of this string builder.
+ // The capacity is adjusted as needed.
+ public StringBuilder Append(bool value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Append(value.ToString());
+ }
+
+ // Appends an sbyte to this string builder.
+ // The capacity is adjusted as needed.
+ [CLSCompliant(false)]
+ public StringBuilder Append(sbyte value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Append(value.ToString());
+ }
+
+ // Appends a ubyte to this string builder.
+ // The capacity is adjusted as needed.
+ public StringBuilder Append(byte value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Append(value.ToString());
+ }
+
+ // Appends a character at the end of this string builder. The capacity is adjusted as needed.
+ public StringBuilder Append(char value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+
+ if (m_ChunkLength < m_ChunkChars.Length)
+ m_ChunkChars[m_ChunkLength++] = value;
+ else
+ Append(value, 1);
+ return this;
+ }
+
+ // Appends a short to this string builder.
+ // The capacity is adjusted as needed.
+ public StringBuilder Append(short value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Append(value.ToString());
+ }
+
+ // Appends an int to this string builder.
+ // The capacity is adjusted as needed.
+ public StringBuilder Append(int value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Append(value.ToString());
+ }
+
+ // Appends a long to this string builder.
+ // The capacity is adjusted as needed.
+ public StringBuilder Append(long value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Append(value.ToString());
+ }
+
+ // Appends a float to this string builder.
+ // The capacity is adjusted as needed.
+ public StringBuilder Append(float value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Append(value.ToString());
+ }
+
+ // Appends a double to this string builder.
+ // The capacity is adjusted as needed.
+ public StringBuilder Append(double value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Append(value.ToString());
+ }
+
+ public StringBuilder Append(decimal value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Append(value.ToString());
+ }
+
+ // Appends an ushort to this string builder.
+ // The capacity is adjusted as needed.
+ [CLSCompliant(false)]
+ public StringBuilder Append(ushort value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Append(value.ToString());
+ }
+
+ // Appends an uint to this string builder.
+ // The capacity is adjusted as needed.
+ [CLSCompliant(false)]
+ public StringBuilder Append(uint value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Append(value.ToString());
+ }
+
+ // Appends an unsigned long to this string builder.
+ // The capacity is adjusted as needed.
+ [CLSCompliant(false)]
+ public StringBuilder Append(ulong value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Append(value.ToString());
+ }
+
+ // Appends an Object to this string builder.
+ // The capacity is adjusted as needed.
+ public StringBuilder Append(Object value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+
+ if (null == value)
+ {
+ //Appending null is now a no-op.
+ return this;
+ }
+ return Append(value.ToString());
+ }
+
+ // Appends all of the characters in value to the current instance.
+ public StringBuilder Append(char[] value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+
+ if (null != value && value.Length > 0)
+ {
+ unsafe
+ {
+ fixed (char* valueChars = &value[0])
+ Append(valueChars, value.Length);
+ }
+ }
+ return this;
+ }
+
+ // Append joined values with a separator between each value.
+ public unsafe StringBuilder AppendJoin<T>(char separator, params T[] values)
+ {
+ // Defer argument validation to the internal function
+ return AppendJoinCore(&separator, 1, values);
+ }
+
+ public unsafe StringBuilder AppendJoin<T>(string separator, params T[] values)
+ {
+ separator = separator ?? string.Empty;
+ fixed (char* pSeparator = separator)
+ {
+ // Defer argument validation to the internal function
+ return AppendJoinCore(pSeparator, separator.Length, values);
+ }
+ }
+
+ public unsafe StringBuilder AppendJoin<T>(char separator, IEnumerable<T> values)
+ {
+ // Defer argument validation to the internal function
+ return AppendJoinCore(&separator, 1, values);
+ }
+
+ public unsafe StringBuilder AppendJoin<T>(string separator, IEnumerable<T> values)
+ {
+ separator = separator ?? string.Empty;
+ fixed (char* pSeparator = separator)
+ {
+ // Defer argument validation to the internal function
+ return AppendJoinCore(pSeparator, separator.Length, values);
+ }
+ }
+
+ private unsafe StringBuilder AppendJoinCore<T>(char* separator, int separatorLength, params T[] values)
+ {
+ if (values == null)
+ throw new ArgumentNullException(nameof(values));
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+
+ if (values.Length == 0)
+ return this;
+
+ var value = values[0];
+ if (value != null)
+ Append(value.ToString());
+
+ for (var i = 1; i < values.Length; i++)
+ {
+ Append(separator, separatorLength);
+ value = values[i];
+ if (value != null)
+ Append(value.ToString());
+ }
+ return this;
+ }
+
+ private unsafe StringBuilder AppendJoinCore<T>(char* separator, int separatorLength, IEnumerable<T> values)
+ {
+ if (values == null)
+ throw new ArgumentNullException(nameof(values));
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+
+ using (var en = values.GetEnumerator())
+ {
+ if (!en.MoveNext())
+ return this;
+
+ var value = en.Current;
+ if (value != null)
+ Append(value.ToString());
+
+ while (en.MoveNext())
+ {
+ Append(separator, separatorLength);
+ value = en.Current;
+ if (value != null)
+ Append(value.ToString());
+ }
+ }
+ return this;
+ }
+
+ /*====================================Insert====================================
+ **
+ ==============================================================================*/
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed.
+ //
+ public StringBuilder Insert(int index, String value)
+ {
+ if ((uint)index > (uint)Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
+ }
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ Contract.EndContractBlock();
+
+ if (value != null)
+ {
+ unsafe
+ {
+ fixed (char* sourcePtr = value)
+ Insert(index, sourcePtr, value.Length);
+ }
+ }
+ return this;
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed.
+ //
+ public StringBuilder Insert(int index, bool value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Insert(index, value.ToString(), 1);
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed.
+ //
+ [CLSCompliant(false)]
+ public StringBuilder Insert(int index, sbyte value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Insert(index, value.ToString(), 1);
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed.
+ //
+ public StringBuilder Insert(int index, byte value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Insert(index, value.ToString(), 1);
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed.
+ //
+ public StringBuilder Insert(int index, short value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Insert(index, value.ToString(), 1);
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed.
+ public StringBuilder Insert(int index, char value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+
+ unsafe
+ {
+ Insert(index, &value, 1);
+ }
+ return this;
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed.
+ //
+ public StringBuilder Insert(int index, char[] value)
+ {
+ if ((uint)index > (uint)Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
+ }
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ Contract.EndContractBlock();
+
+ if (value != null)
+ Insert(index, value, 0, value.Length);
+ return this;
+ }
+
+ // Returns a reference to the StringBuilder with charCount characters from
+ // value inserted into the buffer at index. Existing characters are shifted
+ // to make room for the new text and capacity is adjusted as required. If value is null, the StringBuilder
+ // is unchanged. Characters are taken from value starting at position startIndex.
+ public StringBuilder Insert(int index, char[] value, int startIndex, int charCount)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+
+ int currentLength = Length;
+ if ((uint)index > (uint)currentLength)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
+ }
+
+ //If they passed in a null char array, just jump out quickly.
+ if (value == null)
+ {
+ if (startIndex == 0 && charCount == 0)
+ {
+ return this;
+ }
+ throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String);
+ }
+
+ //Range check the array.
+ if (startIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex);
+ }
+
+ if (charCount < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_GenericPositive);
+ }
+
+ if (startIndex > value.Length - charCount)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
+ }
+
+ if (charCount > 0)
+ {
+ unsafe
+ {
+ fixed (char* sourcePtr = &value[startIndex])
+ Insert(index, sourcePtr, charCount);
+ }
+ }
+ return this;
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed.
+ //
+ public StringBuilder Insert(int index, int value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Insert(index, value.ToString(), 1);
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed.
+ //
+ public StringBuilder Insert(int index, long value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Insert(index, value.ToString(), 1);
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed.
+ //
+ public StringBuilder Insert(int index, float value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Insert(index, value.ToString(), 1);
+ }
+
+ // Returns a reference to the StringBuilder with ; value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed.
+ //
+ public StringBuilder Insert(int index, double value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Insert(index, value.ToString(), 1);
+ }
+
+ public StringBuilder Insert(int index, decimal value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Insert(index, value.ToString(), 1);
+ }
+
+ // Returns a reference to the StringBuilder with value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed.
+ //
+ [CLSCompliant(false)]
+ public StringBuilder Insert(int index, ushort value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Insert(index, value.ToString(), 1);
+ }
+
+ // Returns a reference to the StringBuilder with value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed.
+ //
+ [CLSCompliant(false)]
+ public StringBuilder Insert(int index, uint value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Insert(index, value.ToString(), 1);
+ }
+
+ // Returns a reference to the StringBuilder with value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the new text.
+ // The capacity is adjusted as needed.
+ //
+ [CLSCompliant(false)]
+ public StringBuilder Insert(int index, ulong value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Insert(index, value.ToString(), 1);
+ }
+
+ // Returns a reference to this string builder with value inserted into
+ // the buffer at index. Existing characters are shifted to make room for the
+ // new text. The capacity is adjusted as needed. If value equals String.Empty, the
+ // StringBuilder is not changed. No changes are made if value is null.
+ //
+ public StringBuilder Insert(int index, Object value)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ if (null == value)
+ {
+ return this;
+ }
+ return Insert(index, value.ToString(), 1);
+ }
+
+ public StringBuilder AppendFormat(String format, Object arg0)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return AppendFormatHelper(null, format, new ParamsArray(arg0));
+ }
+
+ public StringBuilder AppendFormat(String format, Object arg0, Object arg1)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return AppendFormatHelper(null, format, new ParamsArray(arg0, arg1));
+ }
+
+ public StringBuilder AppendFormat(String format, Object arg0, Object arg1, Object arg2)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return AppendFormatHelper(null, format, new ParamsArray(arg0, arg1, arg2));
+ }
+
+ public StringBuilder AppendFormat(String format, params Object[] args)
+ {
+ if (args == null)
+ {
+ // To preserve the original exception behavior, throw an exception about format if both
+ // args and format are null. The actual null check for format is in AppendFormatHelper.
+ throw new ArgumentNullException((format == null) ? nameof(format) : nameof(args));
+ }
+ Contract.Ensures(Contract.Result<String>() != null);
+ Contract.EndContractBlock();
+
+ return AppendFormatHelper(null, format, new ParamsArray(args));
+ }
+
+ public StringBuilder AppendFormat(IFormatProvider provider, String format, Object arg0)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return AppendFormatHelper(provider, format, new ParamsArray(arg0));
+ }
+
+ public StringBuilder AppendFormat(IFormatProvider provider, String format, Object arg0, Object arg1)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return AppendFormatHelper(provider, format, new ParamsArray(arg0, arg1));
+ }
+
+ public StringBuilder AppendFormat(IFormatProvider provider, String format, Object arg0, Object arg1, Object arg2)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return AppendFormatHelper(provider, format, new ParamsArray(arg0, arg1, arg2));
+ }
+
+ public StringBuilder AppendFormat(IFormatProvider provider, String format, params Object[] args)
+ {
+ if (args == null)
+ {
+ // To preserve the original exception behavior, throw an exception about format if both
+ // args and format are null. The actual null check for format is in AppendFormatHelper.
+ throw new ArgumentNullException((format == null) ? nameof(format) : nameof(args));
+ }
+ Contract.Ensures(Contract.Result<String>() != null);
+ Contract.EndContractBlock();
+
+ return AppendFormatHelper(provider, format, new ParamsArray(args));
+ }
+
+ private static void FormatError()
+ {
+ throw new FormatException(SR.Format_InvalidString);
+ }
+
+ // undocumented exclusive limits on the range for Argument Hole Index and Argument Hole Alignment.
+ private const int Index_Limit = 1000000; // Note: 0 <= ArgIndex < Index_Limit
+ private const int Width_Limit = 1000000; // Note: -Width_Limit < ArgAlign < Width_Limit
+
+ internal StringBuilder AppendFormatHelper(IFormatProvider provider, String format, ParamsArray args)
+ {
+ if (format == null)
+ {
+ throw new ArgumentNullException(nameof(format));
+ }
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ Contract.EndContractBlock();
+
+ int pos = 0;
+ int len = format.Length;
+ char ch = '\x0';
+ StringBuilder unescapedItemFormat = null;
+
+ ICustomFormatter cf = null;
+ if (provider != null)
+ {
+ cf = (ICustomFormatter)provider.GetFormat(typeof(ICustomFormatter));
+ }
+
+ while (true)
+ {
+ while (pos < len)
+ {
+ ch = format[pos];
+
+ pos++;
+ // Is it a closing brace?
+ if (ch == '}')
+ {
+ // Check next character (if there is one) to see if it is escaped. eg }}
+ if (pos < len && format[pos] == '}')
+ pos++;
+ else
+ // Otherwise treat it as an error (Mismatched closing brace)
+ FormatError();
+ }
+ // Is it a opening brace?
+ if (ch == '{')
+ {
+ // Check next character (if there is one) to see if it is escaped. eg {{
+ if (pos < len && format[pos] == '{')
+ pos++;
+ else
+ {
+ // Otherwise treat it as the opening brace of an Argument Hole.
+ pos--;
+ break;
+ }
+ }
+ // If it neither then treat the character as just text.
+ Append(ch);
+ }
+
+ //
+ // Start of parsing of Argument Hole.
+ // Argument Hole ::= { Index (, WS* Alignment WS*)? (: Formatting)? }
+ //
+ if (pos == len) break;
+
+ //
+ // Start of parsing required Index parameter.
+ // Index ::= ('0'-'9')+ WS*
+ //
+ pos++;
+ // If reached end of text then error (Unexpected end of text)
+ // or character is not a digit then error (Unexpected Character)
+ if (pos == len || (ch = format[pos]) < '0' || ch > '9') FormatError();
+ int index = 0;
+ do
+ {
+ index = index * 10 + ch - '0';
+ pos++;
+ // If reached end of text then error (Unexpected end of text)
+ if (pos == len) FormatError();
+ ch = format[pos];
+ // so long as character is digit and value of the index is less than 1000000 ( index limit )
+ } while (ch >= '0' && ch <= '9' && index < Index_Limit);
+
+ // If value of index is not within the range of the arguments passed in then error (Index out of range)
+ if (index >= args.Length) throw new FormatException(SR.Format_IndexOutOfRange);
+
+ // Consume optional whitespace.
+ while (pos < len && (ch = format[pos]) == ' ') pos++;
+ // End of parsing index parameter.
+
+ //
+ // Start of parsing of optional Alignment
+ // Alignment ::= comma WS* minus? ('0'-'9')+ WS*
+ //
+ bool leftJustify = false;
+ int width = 0;
+ // Is the character a comma, which indicates the start of alignment parameter.
+ if (ch == ',')
+ {
+ pos++;
+
+ // Consume Optional whitespace
+ while (pos < len && format[pos] == ' ') pos++;
+
+ // If reached the end of the text then error (Unexpected end of text)
+ if (pos == len) FormatError();
+
+ // Is there a minus sign?
+ ch = format[pos];
+ if (ch == '-')
+ {
+ // Yes, then alignment is left justified.
+ leftJustify = true;
+ pos++;
+ // If reached end of text then error (Unexpected end of text)
+ if (pos == len) FormatError();
+ ch = format[pos];
+ }
+
+ // If current character is not a digit then error (Unexpected character)
+ if (ch < '0' || ch > '9') FormatError();
+ // Parse alignment digits.
+ do
+ {
+ width = width * 10 + ch - '0';
+ pos++;
+ // If reached end of text then error. (Unexpected end of text)
+ if (pos == len) FormatError();
+ ch = format[pos];
+ // So long a current character is a digit and the value of width is less than 100000 ( width limit )
+ } while (ch >= '0' && ch <= '9' && width < Width_Limit);
+ // end of parsing Argument Alignment
+ }
+
+ // Consume optional whitespace
+ while (pos < len && (ch = format[pos]) == ' ') pos++;
+
+ //
+ // Start of parsing of optional formatting parameter.
+ //
+ Object arg = args[index];
+ String itemFormat = null;
+ // Is current character a colon? which indicates start of formatting parameter.
+ if (ch == ':')
+ {
+ pos++;
+ int startPos = pos;
+
+ while (true)
+ {
+ // If reached end of text then error. (Unexpected end of text)
+ if (pos == len) FormatError();
+ ch = format[pos];
+ pos++;
+
+ // Is character a opening or closing brace?
+ if (ch == '}' || ch == '{')
+ {
+ if (ch == '{')
+ {
+ // Yes, is next character also a opening brace, then treat as escaped. eg {{
+ if (pos < len && format[pos] == '{')
+ pos++;
+ else
+ // Error Argument Holes can not be nested.
+ FormatError();
+ }
+ else
+ {
+ // Yes, is next character also a closing brace, then treat as escaped. eg }}
+ if (pos < len && format[pos] == '}')
+ pos++;
+ else
+ {
+ // No, then treat it as the closing brace of an Arg Hole.
+ pos--;
+ break;
+ }
+ }
+
+ // Reaching here means the brace has been escaped
+ // so we need to build up the format string in segments
+ if (unescapedItemFormat == null)
+ {
+ unescapedItemFormat = new StringBuilder();
+ }
+ unescapedItemFormat.Append(format, startPos, pos - startPos - 1);
+ startPos = pos;
+ }
+ }
+
+ if (unescapedItemFormat == null || unescapedItemFormat.Length == 0)
+ {
+ if (startPos != pos)
+ {
+ // There was no brace escaping, extract the item format as a single string
+ itemFormat = format.Substring(startPos, pos - startPos);
+ }
+ }
+ else
+ {
+ unescapedItemFormat.Append(format, startPos, pos - startPos);
+ itemFormat = unescapedItemFormat.ToString();
+ unescapedItemFormat.Clear();
+ }
+ }
+ // If current character is not a closing brace then error. (Unexpected Character)
+ if (ch != '}') FormatError();
+ // Construct the output for this arg hole.
+ pos++;
+ String s = null;
+ if (cf != null)
+ {
+ s = cf.Format(itemFormat, arg, provider);
+ }
+
+ if (s == null)
+ {
+ IFormattable formattableArg = arg as IFormattable;
+
+ if (formattableArg != null)
+ {
+ s = formattableArg.ToString(itemFormat, provider);
+ }
+ else if (arg != null)
+ {
+ s = arg.ToString();
+ }
+ }
+ // Append it to the final output of the Format String.
+ if (s == null) s = String.Empty;
+ int pad = width - s.Length;
+ if (!leftJustify && pad > 0) Append(' ', pad);
+ Append(s);
+ if (leftJustify && pad > 0) Append(' ', pad);
+ // Continue to parse other characters.
+ }
+ return this;
+ }
+
+ // Returns a reference to the current StringBuilder with all instances of oldString
+ // replaced with newString. If startIndex and count are specified,
+ // we only replace strings completely contained in the range of startIndex to startIndex +
+ // count. The strings to be replaced are checked on an ordinal basis (e.g. not culture aware). If
+ // newValue is null, instances of oldValue are removed (e.g. replaced with nothing.).
+ //
+ public StringBuilder Replace(String oldValue, String newValue)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+ return Replace(oldValue, newValue, 0, Length);
+ }
+
+ public bool Equals(StringBuilder sb)
+ {
+ if (sb == null)
+ return false;
+ if (Capacity != sb.Capacity || MaxCapacity != sb.MaxCapacity || Length != sb.Length)
+ return false;
+ if (sb == this)
+ return true;
+
+ StringBuilder thisChunk = this;
+ int thisChunkIndex = thisChunk.m_ChunkLength;
+ StringBuilder sbChunk = sb;
+ int sbChunkIndex = sbChunk.m_ChunkLength;
+ for (;;)
+ {
+ // Decrement the pointer to the 'this' StringBuilder
+ --thisChunkIndex;
+ --sbChunkIndex;
+
+ while (thisChunkIndex < 0)
+ {
+ thisChunk = thisChunk.m_ChunkPrevious;
+ if (thisChunk == null)
+ break;
+ thisChunkIndex = thisChunk.m_ChunkLength + thisChunkIndex;
+ }
+
+ // Decrement the pointer to the 'this' StringBuilder
+ while (sbChunkIndex < 0)
+ {
+ sbChunk = sbChunk.m_ChunkPrevious;
+ if (sbChunk == null)
+ break;
+ sbChunkIndex = sbChunk.m_ChunkLength + sbChunkIndex;
+ }
+
+ if (thisChunkIndex < 0)
+ return sbChunkIndex < 0;
+ if (sbChunkIndex < 0)
+ return false;
+ if (thisChunk.m_ChunkChars[thisChunkIndex] != sbChunk.m_ChunkChars[sbChunkIndex])
+ return false;
+ }
+ }
+
+ public StringBuilder Replace(String oldValue, String newValue, int startIndex, int count)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+
+ int currentLength = Length;
+ if ((uint)startIndex > (uint)currentLength)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
+ }
+ if (count < 0 || startIndex > currentLength - count)
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Index);
+ }
+ if (oldValue == null)
+ {
+ throw new ArgumentNullException(nameof(oldValue));
+ }
+ if (oldValue.Length == 0)
+ {
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(oldValue));
+ }
+
+ if (newValue == null)
+ newValue = "";
+
+ int deltaLength = newValue.Length - oldValue.Length;
+
+ int[] replacements = null; // A list of replacement positions in a chunk to apply
+ int replacementsCount = 0;
+
+ // Find the chunk, indexInChunk for the starting point
+ StringBuilder chunk = FindChunkForIndex(startIndex);
+ int indexInChunk = startIndex - chunk.m_ChunkOffset;
+ while (count > 0)
+ {
+ // Look for a match in the chunk,indexInChunk pointer
+ if (StartsWith(chunk, indexInChunk, count, oldValue))
+ {
+ // Push it on my replacements array (with growth), we will do all replacements in a
+ // given chunk in one operation below (see ReplaceAllInChunk) so we don't have to slide
+ // many times.
+ if (replacements == null)
+ replacements = new int[5];
+ else if (replacementsCount >= replacements.Length)
+ {
+ Array.Resize(ref replacements, replacements.Length * 3 / 2 + 4); // grow by 1.5X but more in the beginning
+ }
+ replacements[replacementsCount++] = indexInChunk;
+ indexInChunk += oldValue.Length;
+ count -= oldValue.Length;
+ }
+ else
+ {
+ indexInChunk++;
+ --count;
+ }
+
+ if (indexInChunk >= chunk.m_ChunkLength || count == 0) // Have we moved out of the current chunk
+ {
+ // Replacing mutates the blocks, so we need to convert to logical index and back afterward.
+ int index = indexInChunk + chunk.m_ChunkOffset;
+ int indexBeforeAdjustment = index;
+
+ // See if we accumulated any replacements, if so apply them
+ ReplaceAllInChunk(replacements, replacementsCount, chunk, oldValue.Length, newValue);
+ // The replacement has affected the logical index. Adjust it.
+ index += ((newValue.Length - oldValue.Length) * replacementsCount);
+ replacementsCount = 0;
+
+ chunk = FindChunkForIndex(index);
+ indexInChunk = index - chunk.m_ChunkOffset;
+ Debug.Assert(chunk != null || count == 0, "Chunks ended prematurely");
+ }
+ }
+ VerifyClassInvariant();
+ return this;
+ }
+
+ // Returns a StringBuilder with all instances of oldChar replaced with
+ // newChar. The size of the StringBuilder is unchanged because we're only
+ // replacing characters. If startIndex and count are specified, we
+ // only replace characters in the range from startIndex to startIndex+count
+ //
+ public StringBuilder Replace(char oldChar, char newChar)
+ {
+ return Replace(oldChar, newChar, 0, Length);
+ }
+ public StringBuilder Replace(char oldChar, char newChar, int startIndex, int count)
+ {
+ Contract.Ensures(Contract.Result<StringBuilder>() != null);
+
+ int currentLength = Length;
+ if ((uint)startIndex > (uint)currentLength)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
+ }
+
+ if (count < 0 || startIndex > currentLength - count)
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Index);
+ }
+
+ int endIndex = startIndex + count;
+ StringBuilder chunk = this;
+ for (;;)
+ {
+ int endIndexInChunk = endIndex - chunk.m_ChunkOffset;
+ int startIndexInChunk = startIndex - chunk.m_ChunkOffset;
+ if (endIndexInChunk >= 0)
+ {
+ int curInChunk = Math.Max(startIndexInChunk, 0);
+ int endInChunk = Math.Min(chunk.m_ChunkLength, endIndexInChunk);
+ while (curInChunk < endInChunk)
+ {
+ if (chunk.m_ChunkChars[curInChunk] == oldChar)
+ chunk.m_ChunkChars[curInChunk] = newChar;
+ curInChunk++;
+ }
+ }
+ if (startIndexInChunk >= 0)
+ break;
+ chunk = chunk.m_ChunkPrevious;
+ }
+ return this;
+ }
+
+ /// <summary>
+ /// Appends 'value' of length 'count' to the stringBuilder.
+ /// </summary>
+ [CLSCompliant(false)]
+ public unsafe StringBuilder Append(char* value, int valueCount)
+ {
+ // We don't check null value as this case will throw null reference exception anyway
+ if (valueCount < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(valueCount), SR.ArgumentOutOfRange_NegativeCount);
+ }
+
+ // this is where we can check if the valueCount will put us over m_MaxCapacity
+ // We are doing the check here to prevent the corruption of the StringBuilder.
+ int newLength = Length + valueCount;
+ if (newLength > m_MaxCapacity || newLength < valueCount)
+ {
+ throw new ArgumentOutOfRangeException(nameof(valueCount), SR.ArgumentOutOfRange_LengthGreaterThanCapacity);
+ }
+
+ // This case is so common we want to optimize for it heavily.
+ int newIndex = valueCount + m_ChunkLength;
+ if (newIndex <= m_ChunkChars.Length)
+ {
+ ThreadSafeCopy(value, m_ChunkChars, m_ChunkLength, valueCount);
+ m_ChunkLength = newIndex;
+ }
+ else
+ {
+ // Copy the first chunk
+ int firstLength = m_ChunkChars.Length - m_ChunkLength;
+ if (firstLength > 0)
+ {
+ ThreadSafeCopy(value, m_ChunkChars, m_ChunkLength, firstLength);
+ m_ChunkLength = m_ChunkChars.Length;
+ }
+
+ // Expand the builder to add another chunk.
+ int restLength = valueCount - firstLength;
+ ExpandByABlock(restLength);
+ Debug.Assert(m_ChunkLength == 0, "Expand did not make a new block");
+
+ // Copy the second chunk
+ ThreadSafeCopy(value + firstLength, m_ChunkChars, 0, restLength);
+ m_ChunkLength = restLength;
+ }
+ VerifyClassInvariant();
+ return this;
+ }
+
+ /// <summary>
+ /// Inserts 'value' of length 'cou
+ /// </summary>
+ unsafe private void Insert(int index, char* value, int valueCount)
+ {
+ if ((uint)index > (uint)Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
+ }
+
+ if (valueCount > 0)
+ {
+ StringBuilder chunk;
+ int indexInChunk;
+ MakeRoom(index, valueCount, out chunk, out indexInChunk, false);
+ ReplaceInPlaceAtChunk(ref chunk, ref indexInChunk, value, valueCount);
+ }
+ }
+
+ /// <summary>
+ /// 'replacements' is a list of index (relative to the begining of the 'chunk' to remove
+ /// 'removeCount' characters and replace them with 'value'. This routine does all those
+ /// replacements in bulk (and therefore very efficiently.
+ /// with the string 'value'.
+ /// </summary>
+ private void ReplaceAllInChunk(int[] replacements, int replacementsCount, StringBuilder sourceChunk, int removeCount, string value)
+ {
+ if (replacementsCount <= 0)
+ return;
+
+ unsafe
+ {
+ fixed (char* valuePtr = value)
+ {
+ // calculate the total amount of extra space or space needed for all the replacements.
+ int delta = (value.Length - removeCount) * replacementsCount;
+
+ StringBuilder targetChunk = sourceChunk; // the target as we copy chars down
+ int targetIndexInChunk = replacements[0];
+
+ // Make the room needed for all the new characters if needed.
+ if (delta > 0)
+ MakeRoom(targetChunk.m_ChunkOffset + targetIndexInChunk, delta, out targetChunk, out targetIndexInChunk, true);
+ // We made certain that characters after the insertion point are not moved,
+ int i = 0;
+ for (;;)
+ {
+ // Copy in the new string for the ith replacement
+ ReplaceInPlaceAtChunk(ref targetChunk, ref targetIndexInChunk, valuePtr, value.Length);
+ int gapStart = replacements[i] + removeCount;
+ i++;
+ if (i >= replacementsCount)
+ break;
+
+ int gapEnd = replacements[i];
+ Debug.Assert(gapStart < sourceChunk.m_ChunkChars.Length, "gap starts at end of buffer. Should not happen");
+ Debug.Assert(gapStart <= gapEnd, "negative gap size");
+ Debug.Assert(gapEnd <= sourceChunk.m_ChunkLength, "gap too big");
+ if (delta != 0) // can skip the sliding of gaps if source an target string are the same size.
+ {
+ // Copy the gap data between the current replacement and the the next replacement
+ fixed (char* sourcePtr = &sourceChunk.m_ChunkChars[gapStart])
+ ReplaceInPlaceAtChunk(ref targetChunk, ref targetIndexInChunk, sourcePtr, gapEnd - gapStart);
+ }
+ else
+ {
+ targetIndexInChunk += gapEnd - gapStart;
+ Debug.Assert(targetIndexInChunk <= targetChunk.m_ChunkLength, "gap not in chunk");
+ }
+ }
+
+ // Remove extra space if necessary.
+ if (delta < 0)
+ Remove(targetChunk.m_ChunkOffset + targetIndexInChunk, -delta, out targetChunk, out targetIndexInChunk);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns true if the string that is starts at 'chunk' and 'indexInChunk, and has a logical
+ /// length of 'count' starts with the string 'value'.
+ /// </summary>
+ private bool StartsWith(StringBuilder chunk, int indexInChunk, int count, string value)
+ {
+ for (int i = 0; i < value.Length; i++)
+ {
+ if (count == 0)
+ return false;
+ if (indexInChunk >= chunk.m_ChunkLength)
+ {
+ chunk = Next(chunk);
+ if (chunk == null)
+ return false;
+ indexInChunk = 0;
+ }
+
+ // See if there no match, break out of the inner for loop
+ if (value[i] != chunk.m_ChunkChars[indexInChunk])
+ return false;
+
+ indexInChunk++;
+ --count;
+ }
+ return true;
+ }
+
+ /// <summary>
+ /// ReplaceInPlaceAtChunk is the logical equivalent of 'memcpy'. Given a chunk and ann index in
+ /// that chunk, it copies in 'count' characters from 'value' and updates 'chunk, and indexInChunk to
+ /// point at the end of the characters just copyied (thus you can splice in strings from multiple
+ /// places by calling this mulitple times.
+ /// </summary>
+ unsafe private void ReplaceInPlaceAtChunk(ref StringBuilder chunk, ref int indexInChunk, char* value, int count)
+ {
+ if (count != 0)
+ {
+ for (;;)
+ {
+ int lengthInChunk = chunk.m_ChunkLength - indexInChunk;
+ Debug.Assert(lengthInChunk >= 0, "index not in chunk");
+
+ int lengthToCopy = Math.Min(lengthInChunk, count);
+ ThreadSafeCopy(value, chunk.m_ChunkChars, indexInChunk, lengthToCopy);
+
+ // Advance the index.
+ indexInChunk += lengthToCopy;
+ if (indexInChunk >= chunk.m_ChunkLength)
+ {
+ chunk = Next(chunk);
+ indexInChunk = 0;
+ }
+ count -= lengthToCopy;
+ if (count == 0)
+ break;
+ value += lengthToCopy;
+ }
+ }
+ }
+
+ /// <summary>
+ /// We have to prevent modification off the end of an array.
+ /// The only way to do this is to copy all interesting variables out of the heap and then do the
+ /// bounds check. This is what we do here.
+ /// </summary>
+ private static unsafe void ThreadSafeCopy(char* sourcePtr, char[] destination, int destinationIndex, int count)
+ {
+ if (count > 0)
+ {
+ if ((uint)destinationIndex <= (uint)destination.Length && (destinationIndex + count) <= destination.Length)
+ {
+ fixed (char* destinationPtr = &destination[destinationIndex])
+ string.wstrcpy(destinationPtr, sourcePtr, count);
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(destinationIndex), SR.ArgumentOutOfRange_Index);
+ }
+ }
+ }
+
+ private static void ThreadSafeCopy(char[] source, int sourceIndex, char[] destination, int destinationIndex, int count)
+ {
+ if (count > 0)
+ {
+ if ((uint)sourceIndex <= (uint)source.Length && (sourceIndex + count) <= source.Length)
+ {
+ unsafe
+ {
+ fixed (char* sourcePtr = &source[sourceIndex])
+ ThreadSafeCopy(sourcePtr, destination, destinationIndex, count);
+ }
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(sourceIndex), SR.ArgumentOutOfRange_Index);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Finds the chunk for the logical index (number of characters in the whole stringbuilder) 'index'
+ /// YOu can then get the offset in this chunk by subtracting the m_BlockOffset field from 'index'
+ /// </summary>
+ /// <param name="index"></param>
+ /// <returns></returns>
+ private StringBuilder FindChunkForIndex(int index)
+ {
+ Debug.Assert(0 <= index && index <= Length, "index not in string");
+
+ StringBuilder ret = this;
+ while (ret.m_ChunkOffset > index)
+ ret = ret.m_ChunkPrevious;
+
+ Debug.Assert(ret != null, "index not in string");
+ return ret;
+ }
+
+ /// <summary>
+ /// Finds the chunk for the logical byte index 'byteIndex'
+ /// </summary>
+ /// <param name="index"></param>
+ /// <returns></returns>
+ private StringBuilder FindChunkForByte(int byteIndex)
+ {
+ Debug.Assert(0 <= byteIndex && byteIndex <= Length * sizeof(char), "Byte Index not in string");
+
+ StringBuilder ret = this;
+ while (ret.m_ChunkOffset * sizeof(char) > byteIndex)
+ ret = ret.m_ChunkPrevious;
+
+ Debug.Assert(ret != null, "Byte Index not in string");
+ return ret;
+ }
+
+ /// <summary>
+ /// Finds the chunk that logically follows the 'chunk' chunk. Chunks only persist the pointer to
+ /// the chunk that is logically before it, so this routine has to start at the this pointer (which
+ /// is a assumed to point at the chunk representing the whole stringbuilder) and search
+ /// until it finds the current chunk (thus is O(n)). So it is more expensive than a field fetch!
+ /// </summary>
+ private StringBuilder Next(StringBuilder chunk)
+ {
+ if (chunk == this)
+ return null;
+ return FindChunkForIndex(chunk.m_ChunkOffset + chunk.m_ChunkLength);
+ }
+
+ /// <summary>
+ /// Assumes that 'this' is the last chunk in the list and that it is full. Upon return the 'this'
+ /// block is updated so that it is a new block that has at least 'minBlockCharCount' characters.
+ /// that can be used to copy characters into it.
+ /// </summary>
+ private void ExpandByABlock(int minBlockCharCount)
+ {
+ Contract.Requires(Capacity == Length, "Expand expect to be called only when there is no space left"); // We are currently full
+ Contract.Requires(minBlockCharCount > 0, "Expansion request must be positive");
+
+ VerifyClassInvariant();
+
+ if ((minBlockCharCount + Length) > m_MaxCapacity || minBlockCharCount + Length < minBlockCharCount)
+ throw new ArgumentOutOfRangeException("requiredLength", SR.ArgumentOutOfRange_SmallCapacity);
+
+ // Compute the length of the new block we need
+ // We make the new chunk at least big enough for the current need (minBlockCharCount)
+ // But also as big as the current length (thus doubling capacity), up to a maximum
+ // (so we stay in the small object heap, and never allocate really big chunks even if
+ // the string gets really big.
+ int newBlockLength = Math.Max(minBlockCharCount, Math.Min(Length, MaxChunkSize));
+
+ // Copy the current block to the new block, and initialize this to point at the new buffer.
+ m_ChunkPrevious = new StringBuilder(this);
+ m_ChunkOffset += m_ChunkLength;
+ m_ChunkLength = 0;
+
+ // Check for integer overflow (logical buffer size > int.MaxInt)
+ if (m_ChunkOffset + newBlockLength < newBlockLength)
+ {
+ m_ChunkChars = null;
+ throw new OutOfMemoryException();
+ }
+ m_ChunkChars = new char[newBlockLength];
+
+ VerifyClassInvariant();
+ }
+
+ /// <summary>
+ /// Used by ExpandByABlock to create a new chunk. The new chunk is a copied from 'from'
+ /// In particular the buffer is shared. It is expected that 'from' chunk (which represents
+ /// the whole list, is then updated to point to point to this new chunk.
+ /// </summary>
+ private StringBuilder(StringBuilder from)
+ {
+ m_ChunkLength = from.m_ChunkLength;
+ m_ChunkOffset = from.m_ChunkOffset;
+ m_ChunkChars = from.m_ChunkChars;
+ m_ChunkPrevious = from.m_ChunkPrevious;
+ m_MaxCapacity = from.m_MaxCapacity;
+ VerifyClassInvariant();
+ }
+
+ /// <summary>
+ /// Creates a gap of size 'count' at the logical offset (count of characters in the whole string
+ /// builder) 'index'. It returns the 'chunk' and 'indexInChunk' which represents a pointer to
+ /// this gap that was just created. You can then use 'ReplaceInPlaceAtChunk' to fill in the
+ /// chunk
+ ///
+ /// ReplaceAllChunks relies on the fact that indexes above 'index' are NOT moved outside 'chunk'
+ /// by this process (because we make the space by creating the cap BEFORE the chunk). If we
+ /// change this ReplaceAllChunks needs to be updated.
+ ///
+ /// If dontMoveFollowingChars is true, then the room must be made by inserting a chunk BEFORE the
+ /// current chunk (this is what it does most of the time anyway)
+ /// </summary>
+ private void MakeRoom(int index, int count, out StringBuilder chunk, out int indexInChunk, bool doneMoveFollowingChars)
+ {
+ VerifyClassInvariant();
+ Debug.Assert(count > 0, "Count must be strictly positive");
+ Debug.Assert(index >= 0, "Index can't be negative");
+ if (count + Length > m_MaxCapacity || count + Length < count)
+ throw new ArgumentOutOfRangeException("requiredLength", SR.ArgumentOutOfRange_SmallCapacity);
+
+ chunk = this;
+ while (chunk.m_ChunkOffset > index)
+ {
+ chunk.m_ChunkOffset += count;
+ chunk = chunk.m_ChunkPrevious;
+ }
+ indexInChunk = index - chunk.m_ChunkOffset;
+
+ // Cool, we have some space in this block, and you don't have to copy much to get it, go ahead
+ // and use it. This happens typically when you repeatedly insert small strings at a spot
+ // (typically the absolute front) of the buffer.
+ if (!doneMoveFollowingChars && chunk.m_ChunkLength <= DefaultCapacity * 2 && chunk.m_ChunkChars.Length - chunk.m_ChunkLength >= count)
+ {
+ for (int i = chunk.m_ChunkLength; i > indexInChunk;)
+ {
+ --i;
+ chunk.m_ChunkChars[i + count] = chunk.m_ChunkChars[i];
+ }
+ chunk.m_ChunkLength += count;
+ return;
+ }
+
+ // Allocate space for the new chunk (will go before this one)
+ StringBuilder newChunk = new StringBuilder(Math.Max(count, DefaultCapacity), chunk.m_MaxCapacity, chunk.m_ChunkPrevious);
+ newChunk.m_ChunkLength = count;
+
+ // Copy the head of the buffer to the new buffer.
+ int copyCount1 = Math.Min(count, indexInChunk);
+ if (copyCount1 > 0)
+ {
+ unsafe
+ {
+ fixed (char* chunkCharsPtr = &chunk.m_ChunkChars[0])
+ {
+ ThreadSafeCopy(chunkCharsPtr, newChunk.m_ChunkChars, 0, copyCount1);
+
+ // Slide characters in the current buffer over to make room.
+ int copyCount2 = indexInChunk - copyCount1;
+ if (copyCount2 >= 0)
+ {
+ ThreadSafeCopy(chunkCharsPtr + copyCount1, chunk.m_ChunkChars, 0, copyCount2);
+ indexInChunk = copyCount2;
+ }
+ }
+ }
+ }
+
+ chunk.m_ChunkPrevious = newChunk; // Wire in the new chunk
+ chunk.m_ChunkOffset += count;
+ if (copyCount1 < count)
+ {
+ chunk = newChunk;
+ indexInChunk = copyCount1;
+ }
+
+ VerifyClassInvariant();
+ }
+
+ /// <summary>
+ /// Used by MakeRoom to allocate another chunk.
+ /// </summary>
+ private StringBuilder(int size, int maxCapacity, StringBuilder previousBlock)
+ {
+ Debug.Assert(size > 0, "size not positive");
+ Debug.Assert(maxCapacity > 0, "maxCapacity not positive");
+ m_ChunkChars = new char[size];
+ m_MaxCapacity = maxCapacity;
+ m_ChunkPrevious = previousBlock;
+ if (previousBlock != null)
+ m_ChunkOffset = previousBlock.m_ChunkOffset + previousBlock.m_ChunkLength;
+ VerifyClassInvariant();
+ }
+
+ /// <summary>
+ /// Removes 'count' characters from the logical index 'startIndex' and returns the chunk and
+ /// index in the chunk of that logical index in the out parameters.
+ /// </summary>
+ private void Remove(int startIndex, int count, out StringBuilder chunk, out int indexInChunk)
+ {
+ VerifyClassInvariant();
+ Debug.Assert(startIndex >= 0 && startIndex < Length, "startIndex not in string");
+
+ int endIndex = startIndex + count;
+
+ // Find the chunks for the start and end of the block to delete.
+ chunk = this;
+ StringBuilder endChunk = null;
+ int endIndexInChunk = 0;
+ for (;;)
+ {
+ if (endIndex - chunk.m_ChunkOffset >= 0)
+ {
+ if (endChunk == null)
+ {
+ endChunk = chunk;
+ endIndexInChunk = endIndex - endChunk.m_ChunkOffset;
+ }
+ if (startIndex - chunk.m_ChunkOffset >= 0)
+ {
+ indexInChunk = startIndex - chunk.m_ChunkOffset;
+ break;
+ }
+ }
+ else
+ {
+ chunk.m_ChunkOffset -= count;
+ }
+ chunk = chunk.m_ChunkPrevious;
+ }
+ Debug.Assert(chunk != null, "fell off beginning of string!");
+
+ int copyTargetIndexInChunk = indexInChunk;
+ int copyCount = endChunk.m_ChunkLength - endIndexInChunk;
+ if (endChunk != chunk)
+ {
+ copyTargetIndexInChunk = 0;
+ // Remove the characters after startIndex to end of the chunk
+ chunk.m_ChunkLength = indexInChunk;
+
+ // Remove the characters in chunks between start and end chunk
+ endChunk.m_ChunkPrevious = chunk;
+ endChunk.m_ChunkOffset = chunk.m_ChunkOffset + chunk.m_ChunkLength;
+
+ // If the start is 0 then we can throw away the whole start chunk
+ if (indexInChunk == 0)
+ {
+ endChunk.m_ChunkPrevious = chunk.m_ChunkPrevious;
+ chunk = endChunk;
+ }
+ }
+ endChunk.m_ChunkLength -= (endIndexInChunk - copyTargetIndexInChunk);
+
+ // SafeCritical: We ensure that endIndexInChunk + copyCount is within range of m_ChunkChars and
+ // also ensure that copyTargetIndexInChunk + copyCount is within the chunk
+ //
+ // Remove any characters in the end chunk, by sliding the characters down.
+ if (copyTargetIndexInChunk != endIndexInChunk) // Sometimes no move is necessary
+ ThreadSafeCopy(endChunk.m_ChunkChars, endIndexInChunk, endChunk.m_ChunkChars, copyTargetIndexInChunk, copyCount);
+
+ Debug.Assert(chunk != null, "fell off beginning of string!");
+ VerifyClassInvariant();
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Text/UTF32Encoding.cs b/src/mscorlib/shared/System/Text/UTF32Encoding.cs
new file mode 100644
index 0000000000..e4cd6c960e
--- /dev/null
+++ b/src/mscorlib/shared/System/Text/UTF32Encoding.cs
@@ -0,0 +1,1234 @@
+// 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.
+
+//
+// Don't override IsAlwaysNormalized because it is just a Unicode Transformation and could be confused.
+//
+
+using System;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+
+namespace System.Text
+{
+ // Encodes text into and out of UTF-32. UTF-32 is a way of writing
+ // Unicode characters with a single storage unit (32 bits) per character,
+ //
+ // The UTF-32 byte order mark is simply the Unicode byte order mark
+ // (0x00FEFF) written in UTF-32 (0x0000FEFF or 0xFFFE0000). The byte order
+ // mark is used mostly to distinguish UTF-32 text from other encodings, and doesn't
+ // switch the byte orderings.
+
+ [Serializable]
+ public sealed class UTF32Encoding : Encoding
+ {
+ /*
+ words bits UTF-32 representation
+ ----- ---- -----------------------------------
+ 1 16 00000000 00000000 xxxxxxxx xxxxxxxx
+ 2 21 00000000 000xxxxx hhhhhhll llllllll
+ ----- ---- -----------------------------------
+
+ Surrogate:
+ Real Unicode value = (HighSurrogate - 0xD800) * 0x400 + (LowSurrogate - 0xDC00) + 0x10000
+ */
+
+ // Used by Encoding.UTF32/BigEndianUTF32 for lazy initialization
+ // The initialization code will not be run until a static member of the class is referenced
+ internal static readonly UTF32Encoding s_default = new UTF32Encoding(bigEndian: false, byteOrderMark: true);
+ internal static readonly UTF32Encoding s_bigEndianDefault = new UTF32Encoding(bigEndian: true, byteOrderMark: true);
+
+ private bool _emitUTF32ByteOrderMark = false;
+ private bool _isThrowException = false;
+ private bool _bigEndian = false;
+
+
+ public UTF32Encoding() : this(false, true, false)
+ {
+ }
+
+
+ public UTF32Encoding(bool bigEndian, bool byteOrderMark) :
+ this(bigEndian, byteOrderMark, false)
+ {
+ }
+
+
+ public UTF32Encoding(bool bigEndian, bool byteOrderMark, bool throwOnInvalidCharacters) :
+ base(bigEndian ? 12001 : 12000)
+ {
+ _bigEndian = bigEndian;
+ _emitUTF32ByteOrderMark = byteOrderMark;
+ _isThrowException = throwOnInvalidCharacters;
+
+ // Encoding constructor already did this, but it'll be wrong if we're throwing exceptions
+ if (_isThrowException)
+ SetDefaultFallbacks();
+ }
+
+ internal override void SetDefaultFallbacks()
+ {
+ // For UTF-X encodings, we use a replacement fallback with an empty string
+ if (_isThrowException)
+ {
+ this.encoderFallback = EncoderFallback.ExceptionFallback;
+ this.decoderFallback = DecoderFallback.ExceptionFallback;
+ }
+ else
+ {
+ this.encoderFallback = new EncoderReplacementFallback("\xFFFD");
+ this.decoderFallback = new DecoderReplacementFallback("\xFFFD");
+ }
+ }
+
+
+ // The following methods are copied from EncodingNLS.cs.
+ // Unfortunately EncodingNLS.cs is internal and we're public, so we have to reimpliment them here.
+ // These should be kept in sync for the following classes:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ // Returns the number of bytes required to encode a range of characters in
+ // a character array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetByteCount(char[] chars, int index, int count)
+ {
+ // Validate input parameters
+ if (chars == null)
+ throw new ArgumentNullException("chars", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (chars.Length - index < count)
+ throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // If no input, return 0, avoid fixed empty array problem
+ if (count == 0)
+ return 0;
+
+ // Just call the pointer version
+ fixed (char* pChars = chars)
+ return GetByteCount(pChars + index, count, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetByteCount(String s)
+ {
+ // Validate input
+ if (s==null)
+ throw new ArgumentNullException("s");
+ Contract.EndContractBlock();
+
+ fixed (char* pChars = s)
+ return GetByteCount(pChars, s.Length, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public override unsafe int GetByteCount(char* chars, int count)
+ {
+ // Validate Parameters
+ if (chars == null)
+ throw new ArgumentNullException("chars", SR.ArgumentNull_Array);
+
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Call it with empty encoder
+ return GetByteCount(chars, count, null);
+ }
+
+ // Parent method is safe.
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ public override unsafe int GetBytes(String s, int charIndex, int charCount,
+ byte[] bytes, int byteIndex)
+ {
+ if (s == null || bytes == null)
+ throw new ArgumentNullException((s == null ? "s" : "bytes"), SR.ArgumentNull_Array);
+
+ if (charIndex < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? "charIndex" : "charCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (s.Length - charIndex < charCount)
+ throw new ArgumentOutOfRangeException("s", SR.ArgumentOutOfRange_IndexCount);
+
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ int byteCount = bytes.Length - byteIndex;
+
+ // Fix our input array if 0 length because fixed doesn't like 0 length arrays
+ if (bytes.Length == 0)
+ bytes = new byte[1];
+
+ fixed (char* pChars = s) fixed (byte* pBytes = &bytes[0])
+ return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
+ }
+
+ // Encodes a range of characters in a character array into a range of bytes
+ // in a byte array. An exception occurs if the byte array is not large
+ // enough to hold the complete encoding of the characters. The
+ // GetByteCount method can be used to determine the exact number of
+ // bytes that will be produced for a given range of characters.
+ // Alternatively, the GetMaxByteCount method can be used to
+ // determine the maximum number of bytes that will be produced for a given
+ // number of characters, regardless of the actual character values.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetBytes(char[] chars, int charIndex, int charCount,
+ byte[] bytes, int byteIndex)
+ {
+ // Validate parameters
+ if (chars == null || bytes == null)
+ throw new ArgumentNullException((chars == null ? "chars" : "bytes"), SR.ArgumentNull_Array);
+
+ if (charIndex < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? "charIndex" : "charCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (chars.Length - charIndex < charCount)
+ throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer);
+
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ // If nothing to encode return 0, avoid fixed problem
+ if (charCount == 0)
+ return 0;
+
+ // Just call pointer version
+ int byteCount = bytes.Length - byteIndex;
+
+ // Fix our input array if 0 length because fixed doesn't like 0 length arrays
+ if (bytes.Length == 0)
+ bytes = new byte[1];
+
+ fixed (char* pChars = chars) fixed (byte* pBytes = &bytes[0])
+ // Remember that byteCount is # to decode, not size of array.
+ return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
+ {
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (charCount < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetBytes(chars, charCount, bytes, byteCount, null);
+ }
+
+ // Returns the number of characters produced by decoding a range of bytes
+ // in a byte array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetCharCount(byte[] bytes, int index, int count)
+ {
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (bytes.Length - index < count)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // If no input just return 0, fixed doesn't like 0 length arrays.
+ if (count == 0)
+ return 0;
+
+ // Just call pointer version
+ fixed (byte* pBytes = bytes)
+ return GetCharCount(pBytes + index, count, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public override unsafe int GetCharCount(byte* bytes, int count)
+ {
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetCharCount(bytes, count, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ char[] chars, int charIndex)
+ {
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (byteIndex < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((byteIndex < 0 ? "byteIndex" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if ( bytes.Length - byteIndex < byteCount)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+
+ if (charIndex < 0 || charIndex > chars.Length)
+ throw new ArgumentOutOfRangeException("charIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ // If no input, return 0 & avoid fixed problem
+ if (byteCount == 0)
+ return 0;
+
+ // Just call pointer version
+ int charCount = chars.Length - charIndex;
+
+ // Fix our input array if 0 length because fixed doesn't like 0 length arrays
+ if (chars.Length == 0)
+ chars = new char[1];
+
+ fixed (byte* pBytes = bytes) fixed (char* pChars = &chars[0])
+ // Remember that charCount is # to decode, not size of array
+ return GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
+ {
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (charCount < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetChars(bytes, byteCount, chars, charCount, null);
+ }
+
+ // Returns a string containing the decoded representation of a range of
+ // bytes in a byte array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe String GetString(byte[] bytes, int index, int count)
+ {
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (bytes.Length - index < count)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // Avoid problems with empty input buffer
+ if (count == 0) return String.Empty;
+
+ fixed (byte* pBytes = bytes)
+ return String.CreateStringFromEncoding(
+ pBytes + index, count, this);
+ }
+
+ //
+ // End of standard methods copied from EncodingNLS.cs
+ //
+
+ internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS encoder)
+ {
+ Debug.Assert(chars != null, "[UTF32Encoding.GetByteCount]chars!=null");
+ Debug.Assert(count >= 0, "[UTF32Encoding.GetByteCount]count >=0");
+
+ char* end = chars + count;
+ char* charStart = chars;
+ int byteCount = 0;
+
+ char highSurrogate = '\0';
+
+ // For fallback we may need a fallback buffer
+ EncoderFallbackBuffer fallbackBuffer = null;
+ char* charsForFallback;
+
+ if (encoder != null)
+ {
+ highSurrogate = encoder.charLeftOver;
+ fallbackBuffer = encoder.FallbackBuffer;
+
+ // We mustn't have left over fallback data when counting
+ if (fallbackBuffer.Remaining > 0)
+ throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
+ }
+ else
+ {
+ fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
+ }
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(charStart, end, encoder, false);
+
+ char ch;
+ TryAgain:
+
+ while (((ch = fallbackBuffer.InternalGetNextChar()) != 0) || chars < end)
+ {
+ // First unwind any fallback
+ if (ch == 0)
+ {
+ // No fallback, just get next char
+ ch = *chars;
+ chars++;
+ }
+
+ // Do we need a low surrogate?
+ if (highSurrogate != '\0')
+ {
+ //
+ // In previous char, we encounter a high surrogate, so we are expecting a low surrogate here.
+ //
+ if (Char.IsLowSurrogate(ch))
+ {
+ // They're all legal
+ highSurrogate = '\0';
+
+ //
+ // One surrogate pair will be translated into 4 bytes UTF32.
+ //
+
+ byteCount += 4;
+ continue;
+ }
+
+ // We are missing our low surrogate, decrement chars and fallback the high surrogate
+ // The high surrogate may have come from the encoder, but nothing else did.
+ Debug.Assert(chars > charStart,
+ "[UTF32Encoding.GetByteCount]Expected chars to have advanced if no low surrogate");
+ chars--;
+
+ // Do the fallback
+ charsForFallback = chars;
+ fallbackBuffer.InternalFallback(highSurrogate, ref charsForFallback);
+ chars = charsForFallback;
+
+ // We're going to fallback the old high surrogate.
+ highSurrogate = '\0';
+ continue;
+ }
+
+ // Do we have another high surrogate?
+ if (Char.IsHighSurrogate(ch))
+ {
+ //
+ // We'll have a high surrogate to check next time.
+ //
+ highSurrogate = ch;
+ continue;
+ }
+
+ // Check for illegal characters
+ if (Char.IsLowSurrogate(ch))
+ {
+ // We have a leading low surrogate, do the fallback
+ charsForFallback = chars;
+ fallbackBuffer.InternalFallback(ch, ref charsForFallback);
+ chars = charsForFallback;
+
+ // Try again with fallback buffer
+ continue;
+ }
+
+ // We get to add the character (4 bytes UTF32)
+ byteCount += 4;
+ }
+
+ // May have to do our last surrogate
+ if ((encoder == null || encoder.MustFlush) && highSurrogate > 0)
+ {
+ // We have to do the fallback for the lonely high surrogate
+ charsForFallback = chars;
+ fallbackBuffer.InternalFallback(highSurrogate, ref charsForFallback);
+ chars = charsForFallback;
+
+ highSurrogate = (char)0;
+ goto TryAgain;
+ }
+
+ // Check for overflows.
+ if (byteCount < 0)
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_GetByteCountOverflow);
+
+ // Shouldn't have anything in fallback buffer for GetByteCount
+ // (don't have to check m_throwOnOverflow for count)
+ Debug.Assert(fallbackBuffer.Remaining == 0,
+ "[UTF32Encoding.GetByteCount]Expected empty fallback buffer at end");
+
+ // Return our count
+ return byteCount;
+ }
+
+ internal override unsafe int GetBytes(char* chars, int charCount,
+ byte* bytes, int byteCount, EncoderNLS encoder)
+ {
+ Debug.Assert(chars != null, "[UTF32Encoding.GetBytes]chars!=null");
+ Debug.Assert(bytes != null, "[UTF32Encoding.GetBytes]bytes!=null");
+ Debug.Assert(byteCount >= 0, "[UTF32Encoding.GetBytes]byteCount >=0");
+ Debug.Assert(charCount >= 0, "[UTF32Encoding.GetBytes]charCount >=0");
+
+ char* charStart = chars;
+ char* charEnd = chars + charCount;
+ byte* byteStart = bytes;
+ byte* byteEnd = bytes + byteCount;
+
+ char highSurrogate = '\0';
+
+ // For fallback we may need a fallback buffer
+ EncoderFallbackBuffer fallbackBuffer = null;
+ char* charsForFallback;
+
+ if (encoder != null)
+ {
+ highSurrogate = encoder.charLeftOver;
+ fallbackBuffer = encoder.FallbackBuffer;
+
+ // We mustn't have left over fallback data when not converting
+ if (encoder.m_throwOnOverflow && fallbackBuffer.Remaining > 0)
+ throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
+ }
+ else
+ {
+ fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
+ }
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, true);
+
+ char ch;
+ TryAgain:
+
+ while (((ch = fallbackBuffer.InternalGetNextChar()) != 0) || chars < charEnd)
+ {
+ // First unwind any fallback
+ if (ch == 0)
+ {
+ // No fallback, just get next char
+ ch = *chars;
+ chars++;
+ }
+
+ // Do we need a low surrogate?
+ if (highSurrogate != '\0')
+ {
+ //
+ // In previous char, we encountered a high surrogate, so we are expecting a low surrogate here.
+ //
+ if (Char.IsLowSurrogate(ch))
+ {
+ // Is it a legal one?
+ uint iTemp = GetSurrogate(highSurrogate, ch);
+ highSurrogate = '\0';
+
+ //
+ // One surrogate pair will be translated into 4 bytes UTF32.
+ //
+ if (bytes + 3 >= byteEnd)
+ {
+ // Don't have 4 bytes
+ if (fallbackBuffer.bFallingBack)
+ {
+ fallbackBuffer.MovePrevious(); // Aren't using these 2 fallback chars
+ fallbackBuffer.MovePrevious();
+ }
+ else
+ {
+ // If we don't have enough room, then either we should've advanced a while
+ // or we should have bytes==byteStart and throw below
+ Debug.Assert(chars > charStart + 1 || bytes == byteStart,
+ "[UnicodeEncoding.GetBytes]Expected chars to have when no room to add surrogate pair");
+ chars -= 2; // Aren't using those 2 chars
+ }
+ ThrowBytesOverflow(encoder, bytes == byteStart); // Throw maybe (if no bytes written)
+ highSurrogate = (char)0; // Nothing left over (we backed up to start of pair if supplimentary)
+ break;
+ }
+
+ if (_bigEndian)
+ {
+ *(bytes++) = (byte)(0x00);
+ *(bytes++) = (byte)(iTemp >> 16); // Implies & 0xFF, which isn't needed cause high are all 0
+ *(bytes++) = (byte)(iTemp >> 8); // Implies & 0xFF
+ *(bytes++) = (byte)(iTemp); // Implies & 0xFF
+ }
+ else
+ {
+ *(bytes++) = (byte)(iTemp); // Implies & 0xFF
+ *(bytes++) = (byte)(iTemp >> 8); // Implies & 0xFF
+ *(bytes++) = (byte)(iTemp >> 16); // Implies & 0xFF, which isn't needed cause high are all 0
+ *(bytes++) = (byte)(0x00);
+ }
+ continue;
+ }
+
+ // We are missing our low surrogate, decrement chars and fallback the high surrogate
+ // The high surrogate may have come from the encoder, but nothing else did.
+ Debug.Assert(chars > charStart,
+ "[UTF32Encoding.GetBytes]Expected chars to have advanced if no low surrogate");
+ chars--;
+
+ // Do the fallback
+ charsForFallback = chars;
+ fallbackBuffer.InternalFallback(highSurrogate, ref charsForFallback);
+ chars = charsForFallback;
+
+ // We're going to fallback the old high surrogate.
+ highSurrogate = '\0';
+ continue;
+ }
+
+ // Do we have another high surrogate?, if so remember it
+ if (Char.IsHighSurrogate(ch))
+ {
+ //
+ // We'll have a high surrogate to check next time.
+ //
+ highSurrogate = ch;
+ continue;
+ }
+
+ // Check for illegal characters (low surrogate)
+ if (Char.IsLowSurrogate(ch))
+ {
+ // We have a leading low surrogate, do the fallback
+ charsForFallback = chars;
+ fallbackBuffer.InternalFallback(ch, ref charsForFallback);
+ chars = charsForFallback;
+
+ // Try again with fallback buffer
+ continue;
+ }
+
+ // We get to add the character, yippee.
+ if (bytes + 3 >= byteEnd)
+ {
+ // Don't have 4 bytes
+ if (fallbackBuffer.bFallingBack)
+ fallbackBuffer.MovePrevious(); // Aren't using this fallback char
+ else
+ {
+ // Must've advanced already
+ Debug.Assert(chars > charStart,
+ "[UTF32Encoding.GetBytes]Expected chars to have advanced if normal character");
+ chars--; // Aren't using this char
+ }
+ ThrowBytesOverflow(encoder, bytes == byteStart); // Throw maybe (if no bytes written)
+ break; // Didn't throw, stop
+ }
+
+ if (_bigEndian)
+ {
+ *(bytes++) = (byte)(0x00);
+ *(bytes++) = (byte)(0x00);
+ *(bytes++) = (byte)((uint)ch >> 8); // Implies & 0xFF
+ *(bytes++) = (byte)(ch); // Implies & 0xFF
+ }
+ else
+ {
+ *(bytes++) = (byte)(ch); // Implies & 0xFF
+ *(bytes++) = (byte)((uint)ch >> 8); // Implies & 0xFF
+ *(bytes++) = (byte)(0x00);
+ *(bytes++) = (byte)(0x00);
+ }
+ }
+
+ // May have to do our last surrogate
+ if ((encoder == null || encoder.MustFlush) && highSurrogate > 0)
+ {
+ // We have to do the fallback for the lonely high surrogate
+ charsForFallback = chars;
+ fallbackBuffer.InternalFallback(highSurrogate, ref charsForFallback);
+ chars = charsForFallback;
+
+ highSurrogate = (char)0;
+ goto TryAgain;
+ }
+
+ // Fix our encoder if we have one
+ Debug.Assert(highSurrogate == 0 || (encoder != null && !encoder.MustFlush),
+ "[UTF32Encoding.GetBytes]Expected encoder to be flushed.");
+
+ if (encoder != null)
+ {
+ // Remember our left over surrogate (or 0 if flushing)
+ encoder.charLeftOver = highSurrogate;
+
+ // Need # chars used
+ encoder.m_charsUsed = (int)(chars - charStart);
+ }
+
+ // return the new length
+ return (int)(bytes - byteStart);
+ }
+
+ internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
+ {
+ Debug.Assert(bytes != null, "[UTF32Encoding.GetCharCount]bytes!=null");
+ Debug.Assert(count >= 0, "[UTF32Encoding.GetCharCount]count >=0");
+
+ UTF32Decoder decoder = (UTF32Decoder)baseDecoder;
+
+ // None so far!
+ int charCount = 0;
+ byte* end = bytes + count;
+ byte* byteStart = bytes;
+
+ // Set up decoder
+ int readCount = 0;
+ uint iChar = 0;
+
+ // For fallback we may need a fallback buffer
+ DecoderFallbackBuffer fallbackBuffer = null;
+
+ // See if there's anything in our decoder
+ if (decoder != null)
+ {
+ readCount = decoder.readByteCount;
+ iChar = (uint)decoder.iChar;
+ fallbackBuffer = decoder.FallbackBuffer;
+
+ // Shouldn't have anything in fallback buffer for GetCharCount
+ // (don't have to check m_throwOnOverflow for chars or count)
+ Debug.Assert(fallbackBuffer.Remaining == 0,
+ "[UTF32Encoding.GetCharCount]Expected empty fallback buffer at start");
+ }
+ else
+ {
+ fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
+ }
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(byteStart, null);
+
+ // Loop through our input, 4 characters at a time!
+ while (bytes < end && charCount >= 0)
+ {
+ // Get our next character
+ if (_bigEndian)
+ {
+ // Scoot left and add it to the bottom
+ iChar <<= 8;
+ iChar += *(bytes++);
+ }
+ else
+ {
+ // Scoot right and add it to the top
+ iChar >>= 8;
+ iChar += (uint)(*(bytes++)) << 24;
+ }
+
+ readCount++;
+
+ // See if we have all the bytes yet
+ if (readCount < 4)
+ continue;
+
+ // Have the bytes
+ readCount = 0;
+
+ // See if its valid to encode
+ if (iChar > 0x10FFFF || (iChar >= 0xD800 && iChar <= 0xDFFF))
+ {
+ // Need to fall back these 4 bytes
+ byte[] fallbackBytes;
+ if (_bigEndian)
+ {
+ fallbackBytes = new byte[] {
+ unchecked((byte)(iChar>>24)), unchecked((byte)(iChar>>16)),
+ unchecked((byte)(iChar>>8)), unchecked((byte)(iChar)) };
+ }
+ else
+ {
+ fallbackBytes = new byte[] {
+ unchecked((byte)(iChar)), unchecked((byte)(iChar>>8)),
+ unchecked((byte)(iChar>>16)), unchecked((byte)(iChar>>24)) };
+ }
+
+ charCount += fallbackBuffer.InternalFallback(fallbackBytes, bytes);
+
+ // Ignore the illegal character
+ iChar = 0;
+ continue;
+ }
+
+ // Ok, we have something we can add to our output
+ if (iChar >= 0x10000)
+ {
+ // Surrogates take 2
+ charCount++;
+ }
+
+ // Add the rest of the surrogate or our normal character
+ charCount++;
+
+ // iChar is back to 0
+ iChar = 0;
+ }
+
+ // See if we have something left over that has to be decoded
+ if (readCount > 0 && (decoder == null || decoder.MustFlush))
+ {
+ // Oops, there's something left over with no place to go.
+ byte[] fallbackBytes = new byte[readCount];
+ if (_bigEndian)
+ {
+ while (readCount > 0)
+ {
+ fallbackBytes[--readCount] = unchecked((byte)iChar);
+ iChar >>= 8;
+ }
+ }
+ else
+ {
+ while (readCount > 0)
+ {
+ fallbackBytes[--readCount] = unchecked((byte)(iChar >> 24));
+ iChar <<= 8;
+ }
+ }
+
+ charCount += fallbackBuffer.InternalFallback(fallbackBytes, bytes);
+ }
+
+ // Check for overflows.
+ if (charCount < 0)
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_GetByteCountOverflow);
+
+ // Shouldn't have anything in fallback buffer for GetCharCount
+ // (don't have to check m_throwOnOverflow for chars or count)
+ Debug.Assert(fallbackBuffer.Remaining == 0,
+ "[UTF32Encoding.GetCharCount]Expected empty fallback buffer at end");
+
+ // Return our count
+ return charCount;
+ }
+
+ internal override unsafe int GetChars(byte* bytes, int byteCount,
+ char* chars, int charCount, DecoderNLS baseDecoder)
+ {
+ Debug.Assert(chars != null, "[UTF32Encoding.GetChars]chars!=null");
+ Debug.Assert(bytes != null, "[UTF32Encoding.GetChars]bytes!=null");
+ Debug.Assert(byteCount >= 0, "[UTF32Encoding.GetChars]byteCount >=0");
+ Debug.Assert(charCount >= 0, "[UTF32Encoding.GetChars]charCount >=0");
+
+ UTF32Decoder decoder = (UTF32Decoder)baseDecoder;
+
+ // None so far!
+ char* charStart = chars;
+ char* charEnd = chars + charCount;
+
+ byte* byteStart = bytes;
+ byte* byteEnd = bytes + byteCount;
+
+ // See if there's anything in our decoder (but don't clear it yet)
+ int readCount = 0;
+ uint iChar = 0;
+
+ // For fallback we may need a fallback buffer
+ DecoderFallbackBuffer fallbackBuffer = null;
+ char* charsForFallback;
+
+ // See if there's anything in our decoder
+ if (decoder != null)
+ {
+ readCount = decoder.readByteCount;
+ iChar = (uint)decoder.iChar;
+ fallbackBuffer = baseDecoder.FallbackBuffer;
+
+ // Shouldn't have anything in fallback buffer for GetChars
+ // (don't have to check m_throwOnOverflow for chars)
+ Debug.Assert(fallbackBuffer.Remaining == 0,
+ "[UTF32Encoding.GetChars]Expected empty fallback buffer at start");
+ }
+ else
+ {
+ fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
+ }
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(bytes, chars + charCount);
+
+ // Loop through our input, 4 characters at a time!
+ while (bytes < byteEnd)
+ {
+ // Get our next character
+ if (_bigEndian)
+ {
+ // Scoot left and add it to the bottom
+ iChar <<= 8;
+ iChar += *(bytes++);
+ }
+ else
+ {
+ // Scoot right and add it to the top
+ iChar >>= 8;
+ iChar += (uint)(*(bytes++)) << 24;
+ }
+
+ readCount++;
+
+ // See if we have all the bytes yet
+ if (readCount < 4)
+ continue;
+
+ // Have the bytes
+ readCount = 0;
+
+ // See if its valid to encode
+ if (iChar > 0x10FFFF || (iChar >= 0xD800 && iChar <= 0xDFFF))
+ {
+ // Need to fall back these 4 bytes
+ byte[] fallbackBytes;
+ if (_bigEndian)
+ {
+ fallbackBytes = new byte[] {
+ unchecked((byte)(iChar>>24)), unchecked((byte)(iChar>>16)),
+ unchecked((byte)(iChar>>8)), unchecked((byte)(iChar)) };
+ }
+ else
+ {
+ fallbackBytes = new byte[] {
+ unchecked((byte)(iChar)), unchecked((byte)(iChar>>8)),
+ unchecked((byte)(iChar>>16)), unchecked((byte)(iChar>>24)) };
+ }
+
+ // Chars won't be updated unless this works.
+ charsForFallback = chars;
+ bool fallbackResult = fallbackBuffer.InternalFallback(fallbackBytes, bytes, ref charsForFallback);
+ chars = charsForFallback;
+
+ if (!fallbackResult)
+ {
+
+ // Couldn't fallback, throw or wait til next time
+ // We either read enough bytes for bytes-=4 to work, or we're
+ // going to throw in ThrowCharsOverflow because chars == charStart
+ Debug.Assert(bytes >= byteStart + 4 || chars == charStart,
+ "[UTF32Encoding.GetChars]Expected to have consumed bytes or throw (bad surrogate)");
+ bytes -= 4; // get back to where we were
+ iChar = 0; // Remembering nothing
+ fallbackBuffer.InternalReset();
+ ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
+ break; // Stop here, didn't throw
+ }
+
+ // Ignore the illegal character
+ iChar = 0;
+ continue;
+ }
+
+
+ // Ok, we have something we can add to our output
+ if (iChar >= 0x10000)
+ {
+ // Surrogates take 2
+ if (chars >= charEnd - 1)
+ {
+ // Throwing or stopping
+ // We either read enough bytes for bytes-=4 to work, or we're
+ // going to throw in ThrowCharsOverflow because chars == charStart
+ Debug.Assert(bytes >= byteStart + 4 || chars == charStart,
+ "[UTF32Encoding.GetChars]Expected to have consumed bytes or throw (surrogate)");
+ bytes -= 4; // get back to where we were
+ iChar = 0; // Remembering nothing
+ ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
+ break; // Stop here, didn't throw
+ }
+
+ *(chars++) = GetHighSurrogate(iChar);
+ iChar = GetLowSurrogate(iChar);
+ }
+ // Bounds check for normal character
+ else if (chars >= charEnd)
+ {
+ // Throwing or stopping
+ // We either read enough bytes for bytes-=4 to work, or we're
+ // going to throw in ThrowCharsOverflow because chars == charStart
+ Debug.Assert(bytes >= byteStart + 4 || chars == charStart,
+ "[UTF32Encoding.GetChars]Expected to have consumed bytes or throw (normal char)");
+ bytes -= 4; // get back to where we were
+ iChar = 0; // Remembering nothing
+ ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
+ break; // Stop here, didn't throw
+ }
+
+ // Add the rest of the surrogate or our normal character
+ *(chars++) = (char)iChar;
+
+ // iChar is back to 0
+ iChar = 0;
+ }
+
+ // See if we have something left over that has to be decoded
+ if (readCount > 0 && (decoder == null || decoder.MustFlush))
+ {
+ // Oops, there's something left over with no place to go.
+ byte[] fallbackBytes = new byte[readCount];
+ int tempCount = readCount;
+ if (_bigEndian)
+ {
+ while (tempCount > 0)
+ {
+ fallbackBytes[--tempCount] = unchecked((byte)iChar);
+ iChar >>= 8;
+ }
+ }
+ else
+ {
+ while (tempCount > 0)
+ {
+ fallbackBytes[--tempCount] = unchecked((byte)(iChar >> 24));
+ iChar <<= 8;
+ }
+ }
+
+ charsForFallback = chars;
+ bool fallbackResult = fallbackBuffer.InternalFallback(fallbackBytes, bytes, ref charsForFallback);
+ chars = charsForFallback;
+
+ if (!fallbackResult)
+ {
+ // Couldn't fallback.
+ fallbackBuffer.InternalReset();
+ ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
+ // Stop here, didn't throw, backed up, so still nothing in buffer
+ }
+ else
+ {
+ // Don't clear our decoder unless we could fall it back.
+ // If we caught the if above, then we're a convert() and will catch this next time.
+ readCount = 0;
+ iChar = 0;
+ }
+ }
+
+ // Remember any left over stuff, clearing buffer as well for MustFlush
+ if (decoder != null)
+ {
+ decoder.iChar = (int)iChar;
+ decoder.readByteCount = readCount;
+ decoder.m_bytesUsed = (int)(bytes - byteStart);
+ }
+
+ // Shouldn't have anything in fallback buffer for GetChars
+ // (don't have to check m_throwOnOverflow for chars)
+ Debug.Assert(fallbackBuffer.Remaining == 0,
+ "[UTF32Encoding.GetChars]Expected empty fallback buffer at end");
+
+ // Return our count
+ return (int)(chars - charStart);
+ }
+
+
+ private uint GetSurrogate(char cHigh, char cLow)
+ {
+ return (((uint)cHigh - 0xD800) * 0x400) + ((uint)cLow - 0xDC00) + 0x10000;
+ }
+
+ private char GetHighSurrogate(uint iChar)
+ {
+ return (char)((iChar - 0x10000) / 0x400 + 0xD800);
+ }
+
+ private char GetLowSurrogate(uint iChar)
+ {
+ return (char)((iChar - 0x10000) % 0x400 + 0xDC00);
+ }
+
+
+ public override Decoder GetDecoder()
+ {
+ return new UTF32Decoder(this);
+ }
+
+
+ public override Encoder GetEncoder()
+ {
+ return new EncoderNLS(this);
+ }
+
+
+ public override int GetMaxByteCount(int charCount)
+ {
+ if (charCount < 0)
+ throw new ArgumentOutOfRangeException(nameof(charCount),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Characters would be # of characters + 1 in case left over high surrogate is ? * max fallback
+ long byteCount = (long)charCount + 1;
+
+ if (EncoderFallback.MaxCharCount > 1)
+ byteCount *= EncoderFallback.MaxCharCount;
+
+ // 4 bytes per char
+ byteCount *= 4;
+
+ if (byteCount > 0x7fffffff)
+ throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_GetByteCountOverflow);
+
+ return (int)byteCount;
+ }
+
+
+ public override int GetMaxCharCount(int byteCount)
+ {
+ if (byteCount < 0)
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // A supplementary character becomes 2 surrogate characters, so 4 input bytes becomes 2 chars,
+ // plus we may have 1 surrogate char left over if the decoder has 3 bytes in it already for a non-bmp char.
+ // Have to add another one because 1/2 == 0, but 3 bytes left over could be 2 char surrogate pair
+ int charCount = (byteCount / 2) + 2;
+
+ // Also consider fallback because our input bytes could be out of range of unicode.
+ // Since fallback would fallback 4 bytes at a time, we'll only fall back 1/2 of MaxCharCount.
+ if (DecoderFallback.MaxCharCount > 2)
+ {
+ // Multiply time fallback size
+ charCount *= DecoderFallback.MaxCharCount;
+
+ // We were already figuring 2 chars per 4 bytes, but fallback will be different #
+ charCount /= 2;
+ }
+
+ if (charCount > 0x7fffffff)
+ throw new ArgumentOutOfRangeException(nameof(byteCount), SR.ArgumentOutOfRange_GetCharCountOverflow);
+
+ return (int)charCount;
+ }
+
+
+ public override byte[] GetPreamble()
+ {
+ if (_emitUTF32ByteOrderMark)
+ {
+ // Allocate new array to prevent users from modifying it.
+ if (_bigEndian)
+ {
+ return new byte[4] { 0x00, 0x00, 0xFE, 0xFF };
+ }
+ else
+ {
+ return new byte[4] { 0xFF, 0xFE, 0x00, 0x00 }; // 00 00 FE FF
+ }
+ }
+ else
+ return Array.Empty<byte>();
+ }
+
+
+ public override bool Equals(Object value)
+ {
+ UTF32Encoding that = value as UTF32Encoding;
+ if (that != null)
+ {
+ return (_emitUTF32ByteOrderMark == that._emitUTF32ByteOrderMark) &&
+ (_bigEndian == that._bigEndian) &&
+ (EncoderFallback.Equals(that.EncoderFallback)) &&
+ (DecoderFallback.Equals(that.DecoderFallback));
+ }
+ return (false);
+ }
+
+
+ public override int GetHashCode()
+ {
+ //Not great distribution, but this is relatively unlikely to be used as the key in a hashtable.
+ return this.EncoderFallback.GetHashCode() + this.DecoderFallback.GetHashCode() +
+ CodePage + (_emitUTF32ByteOrderMark ? 4 : 0) + (_bigEndian ? 8 : 0);
+ }
+
+ [Serializable]
+ private sealed class UTF32Decoder : DecoderNLS
+ {
+ // Need a place to store any extra bytes we may have picked up
+ internal int iChar = 0;
+ internal int readByteCount = 0;
+
+ public UTF32Decoder(UTF32Encoding encoding) : base(encoding)
+ {
+ // base calls reset
+ }
+
+ public override void Reset()
+ {
+ this.iChar = 0;
+ this.readByteCount = 0;
+ if (m_fallbackBuffer != null)
+ m_fallbackBuffer.Reset();
+ }
+
+ // Anything left in our decoder?
+ internal override bool HasState
+ {
+ get
+ {
+ // ReadByteCount is our flag. (iChar==0 doesn't mean much).
+ return (this.readByteCount != 0);
+ }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Text/UTF8Encoding.cs b/src/mscorlib/shared/System/Text/UTF8Encoding.cs
new file mode 100644
index 0000000000..5cfa89018a
--- /dev/null
+++ b/src/mscorlib/shared/System/Text/UTF8Encoding.cs
@@ -0,0 +1,2668 @@
+// 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.
+
+// The worker functions in this file was optimized for performance. If you make changes
+// you should use care to consider all of the interesting cases.
+
+// The code of all worker functions in this file is written twice: Once as as a slow loop, and the
+// second time as a fast loop. The slow loops handles all special cases, throws exceptions, etc.
+// The fast loops attempts to blaze through as fast as possible with optimistic range checks,
+// processing multiple characters at a time, and falling back to the slow loop for all special cases.
+
+// This define can be used to turn off the fast loops. Useful for finding whether
+// the problem is fastloop-specific.
+#define FASTLOOP
+
+using System;
+using System.Runtime.Serialization;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+
+namespace System.Text
+{
+ // Encodes text into and out of UTF-8. UTF-8 is a way of writing
+ // Unicode characters with variable numbers of bytes per character,
+ // optimized for the lower 127 ASCII characters. It's an efficient way
+ // of encoding US English in an internationalizable way.
+ //
+ // Don't override IsAlwaysNormalized because it is just a Unicode Transformation and could be confused.
+ //
+ // The UTF-8 byte order mark is simply the Unicode byte order mark
+ // (0xFEFF) written in UTF-8 (0xEF 0xBB 0xBF). The byte order mark is
+ // used mostly to distinguish UTF-8 text from other encodings, and doesn't
+ // switch the byte orderings.
+
+ [Serializable]
+ public class UTF8Encoding : Encoding
+ {
+ /*
+ bytes bits UTF-8 representation
+ ----- ---- -----------------------------------
+ 1 7 0vvvvvvv
+ 2 11 110vvvvv 10vvvvvv
+ 3 16 1110vvvv 10vvvvvv 10vvvvvv
+ 4 21 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv
+ ----- ---- -----------------------------------
+
+ Surrogate:
+ Real Unicode value = (HighSurrogate - 0xD800) * 0x400 + (LowSurrogate - 0xDC00) + 0x10000
+ */
+
+ private const int UTF8_CODEPAGE = 65001;
+
+ // Allow for devirtualization (see https://github.com/dotnet/coreclr/pull/9230)
+ [Serializable]
+ internal sealed class UTF8EncodingSealed : UTF8Encoding
+ {
+ public UTF8EncodingSealed(bool encoderShouldEmitUTF8Identifier) : base(encoderShouldEmitUTF8Identifier) { }
+ }
+
+ // Used by Encoding.UTF8 for lazy initialization
+ // The initialization code will not be run until a static member of the class is referenced
+ internal static readonly UTF8EncodingSealed s_default = new UTF8EncodingSealed(encoderShouldEmitUTF8Identifier: true);
+
+ // Yes, the idea of emitting U+FEFF as a UTF-8 identifier has made it into
+ // the standard.
+ private bool _emitUTF8Identifier = false;
+
+ private bool _isThrowException = false;
+
+
+ public UTF8Encoding() : this(false)
+ {
+ }
+
+
+ public UTF8Encoding(bool encoderShouldEmitUTF8Identifier) :
+ this(encoderShouldEmitUTF8Identifier, false)
+ {
+ }
+
+
+ public UTF8Encoding(bool encoderShouldEmitUTF8Identifier, bool throwOnInvalidBytes) :
+ base(UTF8_CODEPAGE)
+ {
+ _emitUTF8Identifier = encoderShouldEmitUTF8Identifier;
+ _isThrowException = throwOnInvalidBytes;
+
+ // Encoding's constructor already did this, but it'll be wrong if we're throwing exceptions
+ if (_isThrowException)
+ SetDefaultFallbacks();
+ }
+
+ internal override void SetDefaultFallbacks()
+ {
+ // For UTF-X encodings, we use a replacement fallback with an empty string
+ if (_isThrowException)
+ {
+ this.encoderFallback = EncoderFallback.ExceptionFallback;
+ this.decoderFallback = DecoderFallback.ExceptionFallback;
+ }
+ else
+ {
+ this.encoderFallback = new EncoderReplacementFallback("\xFFFD");
+ this.decoderFallback = new DecoderReplacementFallback("\xFFFD");
+ }
+ }
+
+
+ // WARNING: GetByteCount(string chars)
+ // WARNING: has different variable names than EncodingNLS.cs, so this can't just be cut & pasted,
+ // WARNING: otherwise it'll break VB's way of declaring these.
+ //
+ // The following methods are copied from EncodingNLS.cs.
+ // Unfortunately EncodingNLS.cs is internal and we're public, so we have to reimpliment them here.
+ // These should be kept in sync for the following classes:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ // Returns the number of bytes required to encode a range of characters in
+ // a character array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetByteCount(char[] chars, int index, int count)
+ {
+ // Validate input parameters
+ if (chars == null)
+ throw new ArgumentNullException("chars", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (chars.Length - index < count)
+ throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // If no input, return 0, avoid fixed empty array problem
+ if (count == 0)
+ return 0;
+
+ // Just call the pointer version
+ fixed (char* pChars = chars)
+ return GetByteCount(pChars + index, count, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetByteCount(String chars)
+ {
+ // Validate input
+ if (chars==null)
+ throw new ArgumentNullException("s");
+ Contract.EndContractBlock();
+
+ fixed (char* pChars = chars)
+ return GetByteCount(pChars, chars.Length, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public override unsafe int GetByteCount(char* chars, int count)
+ {
+ // Validate Parameters
+ if (chars == null)
+ throw new ArgumentNullException("chars", SR.ArgumentNull_Array);
+
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Call it with empty encoder
+ return GetByteCount(chars, count, null);
+ }
+
+ // Parent method is safe.
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ public override unsafe int GetBytes(String s, int charIndex, int charCount,
+ byte[] bytes, int byteIndex)
+ {
+ if (s == null || bytes == null)
+ throw new ArgumentNullException((s == null ? "s" : "bytes"), SR.ArgumentNull_Array);
+
+ if (charIndex < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? "charIndex" : "charCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (s.Length - charIndex < charCount)
+ throw new ArgumentOutOfRangeException("s", SR.ArgumentOutOfRange_IndexCount);
+
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ int byteCount = bytes.Length - byteIndex;
+
+ // Fixed doesn't like 0 length arrays.
+ if (bytes.Length == 0)
+ bytes = new byte[1];
+
+ fixed (char* pChars = s) fixed (byte* pBytes = &bytes[0])
+ return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
+ }
+
+ // Encodes a range of characters in a character array into a range of bytes
+ // in a byte array. An exception occurs if the byte array is not large
+ // enough to hold the complete encoding of the characters. The
+ // GetByteCount method can be used to determine the exact number of
+ // bytes that will be produced for a given range of characters.
+ // Alternatively, the GetMaxByteCount method can be used to
+ // determine the maximum number of bytes that will be produced for a given
+ // number of characters, regardless of the actual character values.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetBytes(char[] chars, int charIndex, int charCount,
+ byte[] bytes, int byteIndex)
+ {
+ // Validate parameters
+ if (chars == null || bytes == null)
+ throw new ArgumentNullException((chars == null ? "chars" : "bytes"), SR.ArgumentNull_Array);
+
+ if (charIndex < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? "charIndex" : "charCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (chars.Length - charIndex < charCount)
+ throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer);
+
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ // If nothing to encode return 0, avoid fixed problem
+ if (charCount == 0)
+ return 0;
+
+ // Just call pointer version
+ int byteCount = bytes.Length - byteIndex;
+
+ // Fixed doesn't like 0 length arrays.
+ if (bytes.Length == 0)
+ bytes = new byte[1];
+
+ fixed (char* pChars = chars) fixed (byte* pBytes = &bytes[0])
+ // Remember that byteCount is # to decode, not size of array.
+ return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
+ {
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (charCount < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetBytes(chars, charCount, bytes, byteCount, null);
+ }
+
+ // Returns the number of characters produced by decoding a range of bytes
+ // in a byte array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetCharCount(byte[] bytes, int index, int count)
+ {
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (bytes.Length - index < count)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // If no input just return 0, fixed doesn't like 0 length arrays.
+ if (count == 0)
+ return 0;
+
+ // Just call pointer version
+ fixed (byte* pBytes = bytes)
+ return GetCharCount(pBytes + index, count, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public override unsafe int GetCharCount(byte* bytes, int count)
+ {
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetCharCount(bytes, count, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ char[] chars, int charIndex)
+ {
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (byteIndex < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((byteIndex < 0 ? "byteIndex" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if ( bytes.Length - byteIndex < byteCount)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+
+ if (charIndex < 0 || charIndex > chars.Length)
+ throw new ArgumentOutOfRangeException("charIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ // If no input, return 0 & avoid fixed problem
+ if (byteCount == 0)
+ return 0;
+
+ // Just call pointer version
+ int charCount = chars.Length - charIndex;
+
+ // Fixed doesn't like 0 length arrays.
+ if (chars.Length == 0)
+ chars = new char[1];
+
+ fixed (byte* pBytes = bytes) fixed (char* pChars = &chars[0])
+ // Remember that charCount is # to decode, not size of array
+ return GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
+ {
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (charCount < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetChars(bytes, byteCount, chars, charCount, null);
+ }
+
+ // Returns a string containing the decoded representation of a range of
+ // bytes in a byte array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe String GetString(byte[] bytes, int index, int count)
+ {
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (bytes.Length - index < count)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // Avoid problems with empty input buffer
+ if (count == 0) return String.Empty;
+
+ fixed (byte* pBytes = bytes)
+ return String.CreateStringFromEncoding(
+ pBytes + index, count, this);
+ }
+
+ //
+ // End of standard methods copied from EncodingNLS.cs
+ //
+
+ // To simplify maintenance, the structure of GetByteCount and GetBytes should be
+ // kept the same as much as possible
+ internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS baseEncoder)
+ {
+ // For fallback we may need a fallback buffer.
+ // We wait to initialize it though in case we don't have any broken input unicode
+ EncoderFallbackBuffer fallbackBuffer = null;
+ char* pSrcForFallback;
+
+ char* pSrc = chars;
+ char* pEnd = pSrc + count;
+
+ // Start by assuming we have as many as count
+ int byteCount = count;
+
+ int ch = 0;
+
+ if (baseEncoder != null)
+ {
+ UTF8Encoder encoder = (UTF8Encoder)baseEncoder;
+ ch = encoder.surrogateChar;
+
+ // We mustn't have left over fallback data when counting
+ if (encoder.InternalHasFallbackBuffer)
+ {
+ fallbackBuffer = encoder.FallbackBuffer;
+ if (fallbackBuffer.Remaining > 0)
+ throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(chars, pEnd, encoder, false);
+ }
+ }
+
+ for (;;)
+ {
+ // SLOWLOOP: does all range checks, handles all special cases, but it is slow
+ if (pSrc >= pEnd)
+ {
+ if (ch == 0)
+ {
+ // Unroll any fallback that happens at the end
+ ch = fallbackBuffer != null ? fallbackBuffer.InternalGetNextChar() : 0;
+ if (ch > 0)
+ {
+ byteCount++;
+ goto ProcessChar;
+ }
+ }
+ else
+ {
+ // Case of surrogates in the fallback.
+ if (fallbackBuffer != null && fallbackBuffer.bFallingBack)
+ {
+ Debug.Assert(ch >= 0xD800 && ch <= 0xDBFF,
+ "[UTF8Encoding.GetBytes]expected high surrogate, not 0x" + ((int)ch).ToString("X4", CultureInfo.InvariantCulture));
+
+ ch = fallbackBuffer.InternalGetNextChar();
+ byteCount++;
+
+ if (InRange(ch, CharUnicodeInfo.LOW_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END))
+ {
+ ch = 0xfffd;
+ byteCount++;
+ goto EncodeChar;
+ }
+ else if (ch > 0)
+ {
+ goto ProcessChar;
+ }
+ else
+ {
+ byteCount--; // ignore last one.
+ break;
+ }
+ }
+ }
+
+ if (ch <= 0)
+ {
+ break;
+ }
+ if (baseEncoder != null && !baseEncoder.MustFlush)
+ {
+ break;
+ }
+
+ // attempt to encode the partial surrogate (will fallback or ignore it), it'll also subtract 1.
+ byteCount++;
+ goto EncodeChar;
+ }
+
+ if (ch > 0)
+ {
+ Debug.Assert(ch >= 0xD800 && ch <= 0xDBFF,
+ "[UTF8Encoding.GetBytes]expected high surrogate, not 0x" + ((int)ch).ToString("X4", CultureInfo.InvariantCulture));
+
+ // use separate helper variables for local contexts so that the jit optimizations
+ // won't get confused about the variable lifetimes
+ int cha = *pSrc;
+
+ // count the pending surrogate
+ byteCount++;
+
+ // In previous byte, we encountered a high surrogate, so we are expecting a low surrogate here.
+ // if (IsLowSurrogate(cha)) {
+ if (InRange(cha, CharUnicodeInfo.LOW_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END))
+ {
+ // Don't need a real # because we're just counting, anything > 0x7ff ('cept surrogate) will do.
+ ch = 0xfffd;
+ // ch = cha + (ch << 10) +
+ // (0x10000
+ // - CharUnicodeInfo.LOW_SURROGATE_START
+ // - (CharUnicodeInfo.HIGH_SURROGATE_START << 10) );
+
+ // Use this next char
+ pSrc++;
+ }
+ // else ch is still high surrogate and encoding will fail (so don't add count)
+
+ // attempt to encode the surrogate or partial surrogate
+ goto EncodeChar;
+ }
+
+ // If we've used a fallback, then we have to check for it
+ if (fallbackBuffer != null)
+ {
+ ch = fallbackBuffer.InternalGetNextChar();
+ if (ch > 0)
+ {
+ // We have an extra byte we weren't expecting.
+ byteCount++;
+ goto ProcessChar;
+ }
+ }
+
+ // read next char. The JIT optimization seems to be getting confused when
+ // compiling "ch = *pSrc++;", so rather use "ch = *pSrc; pSrc++;" instead
+ ch = *pSrc;
+ pSrc++;
+
+ ProcessChar:
+ // if (IsHighSurrogate(ch)) {
+ if (InRange(ch, CharUnicodeInfo.HIGH_SURROGATE_START, CharUnicodeInfo.HIGH_SURROGATE_END))
+ {
+ // we will count this surrogate next time around
+ byteCount--;
+ continue;
+ }
+ // either good char or partial surrogate
+
+ EncodeChar:
+ // throw exception on partial surrogate if necessary
+ // if (IsLowSurrogate(ch) || IsHighSurrogate(ch))
+ if (InRange(ch, CharUnicodeInfo.HIGH_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END))
+ {
+ // Lone surrogates aren't allowed
+ // Have to make a fallback buffer if we don't have one
+ if (fallbackBuffer == null)
+ {
+ // wait on fallbacks if we can
+ // For fallback we may need a fallback buffer
+ if (baseEncoder == null)
+ fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = baseEncoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(chars, chars + count, baseEncoder, false);
+ }
+
+ // Do our fallback. Actually we already know its a mixed up surrogate,
+ // so the ref pSrc isn't gonna do anything.
+ pSrcForFallback = pSrc; // Avoid passing pSrc by reference to allow it to be enregistered
+ fallbackBuffer.InternalFallback(unchecked((char)ch), ref pSrcForFallback);
+ pSrc = pSrcForFallback;
+
+ // Ignore it if we don't throw (we had preallocated this ch)
+ byteCount--;
+ ch = 0;
+ continue;
+ }
+
+ // Count them
+ if (ch > 0x7F)
+ {
+ if (ch > 0x7FF)
+ {
+ // the extra surrogate byte was compensated by the second surrogate character
+ // (2 surrogates make 4 bytes. We've already counted 2 bytes, 1 per char)
+ byteCount++;
+ }
+ byteCount++;
+ }
+
+#if BIT64
+ // check for overflow
+ if (byteCount < 0)
+ {
+ break;
+ }
+#endif
+
+#if FASTLOOP
+ // If still have fallback don't do fast loop
+ if (fallbackBuffer != null && (ch = fallbackBuffer.InternalGetNextChar()) != 0)
+ {
+ // We're reserving 1 byte for each char by default
+ byteCount++;
+ goto ProcessChar;
+ }
+
+ int availableChars = PtrDiff(pEnd, pSrc);
+
+ // don't fall into the fast decoding loop if we don't have enough characters
+ if (availableChars <= 13)
+ {
+ // try to get over the remainder of the ascii characters fast though
+ char* pLocalEnd = pEnd; // hint to get pLocalEnd enregistered
+ while (pSrc < pLocalEnd)
+ {
+ ch = *pSrc;
+ pSrc++;
+ if (ch > 0x7F)
+ goto ProcessChar;
+ }
+
+ // we are done
+ break;
+ }
+
+#if BIT64
+ // make sure that we won't get a silent overflow inside the fast loop
+ // (Fall out to slow loop if we have this many characters)
+ availableChars &= 0x0FFFFFFF;
+#endif
+
+ // To compute the upper bound, assume that all characters are ASCII characters at this point,
+ // the boundary will be decreased for every non-ASCII character we encounter
+ // Also, we need 3 + 4 chars reserve for the unrolled ansi decoding loop and for decoding of surrogates
+ char* pStop = pSrc + availableChars - (3 + 4);
+
+ while (pSrc < pStop)
+ {
+ ch = *pSrc;
+ pSrc++;
+
+ if (ch > 0x7F) // Not ASCII
+ {
+ if (ch > 0x7FF) // Not 2 Byte
+ {
+ if ((ch & 0xF800) == 0xD800) // See if its a Surrogate
+ goto LongCode;
+ byteCount++;
+ }
+ byteCount++;
+ }
+
+ // get pSrc aligned
+ if ((unchecked((int)pSrc) & 0x2) != 0)
+ {
+ ch = *pSrc;
+ pSrc++;
+ if (ch > 0x7F) // Not ASCII
+ {
+ if (ch > 0x7FF) // Not 2 Byte
+ {
+ if ((ch & 0xF800) == 0xD800) // See if its a Surrogate
+ goto LongCode;
+ byteCount++;
+ }
+ byteCount++;
+ }
+ }
+
+ // Run 2 * 4 characters at a time!
+ while (pSrc < pStop)
+ {
+ ch = *(int*)pSrc;
+ int chc = *(int*)(pSrc + 2);
+ if (((ch | chc) & unchecked((int)0xFF80FF80)) != 0) // See if not ASCII
+ {
+ if (((ch | chc) & unchecked((int)0xF800F800)) != 0) // See if not 2 Byte
+ {
+ goto LongCodeWithMask;
+ }
+
+
+ if ((ch & unchecked((int)0xFF800000)) != 0) // Actually 0x07800780 is all we care about (4 bits)
+ byteCount++;
+ if ((ch & unchecked((int)0xFF80)) != 0)
+ byteCount++;
+ if ((chc & unchecked((int)0xFF800000)) != 0)
+ byteCount++;
+ if ((chc & unchecked((int)0xFF80)) != 0)
+ byteCount++;
+ }
+ pSrc += 4;
+
+ ch = *(int*)pSrc;
+ chc = *(int*)(pSrc + 2);
+ if (((ch | chc) & unchecked((int)0xFF80FF80)) != 0) // See if not ASCII
+ {
+ if (((ch | chc) & unchecked((int)0xF800F800)) != 0) // See if not 2 Byte
+ {
+ goto LongCodeWithMask;
+ }
+
+ if ((ch & unchecked((int)0xFF800000)) != 0)
+ byteCount++;
+ if ((ch & unchecked((int)0xFF80)) != 0)
+ byteCount++;
+ if ((chc & unchecked((int)0xFF800000)) != 0)
+ byteCount++;
+ if ((chc & unchecked((int)0xFF80)) != 0)
+ byteCount++;
+ }
+ pSrc += 4;
+ }
+ break;
+
+ LongCodeWithMask:
+#if BIGENDIAN
+ // be careful about the sign extension
+ ch = (int)(((uint)ch) >> 16);
+#else // BIGENDIAN
+ ch = (char)ch;
+#endif // BIGENDIAN
+ pSrc++;
+
+ if (ch <= 0x7F)
+ {
+ continue;
+ }
+
+ LongCode:
+ // use separate helper variables for slow and fast loop so that the jit optimizations
+ // won't get confused about the variable lifetimes
+ if (ch > 0x7FF)
+ {
+ // if (IsLowSurrogate(ch) || IsHighSurrogate(ch))
+ if (InRange(ch, CharUnicodeInfo.HIGH_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END))
+ {
+ // 4 byte encoding - high surrogate + low surrogate
+
+ int chd = *pSrc;
+ if (
+ // !IsHighSurrogate(ch) // low without high -> bad
+ ch > CharUnicodeInfo.HIGH_SURROGATE_END ||
+ // !IsLowSurrogate(chd) // high not followed by low -> bad
+ !InRange(chd, CharUnicodeInfo.LOW_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END))
+ {
+ // Back up and drop out to slow loop to figure out error
+ pSrc--;
+ break;
+ }
+ pSrc++;
+
+ // byteCount - this byte is compensated by the second surrogate character
+ }
+ byteCount++;
+ }
+ byteCount++;
+
+ // byteCount - the last byte is already included
+ }
+#endif // FASTLOOP
+
+ // no pending char at this point
+ ch = 0;
+ }
+
+#if BIT64
+ // check for overflow
+ if (byteCount < 0)
+ {
+ throw new ArgumentException(
+ SR.Argument_ConversionOverflow);
+ }
+#endif
+
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ "[UTF8Encoding.GetByteCount]Expected Empty fallback buffer");
+
+ return byteCount;
+ }
+
+ // diffs two char pointers using unsigned arithmetic. The unsigned arithmetic
+ // is good enough for us, and it tends to generate better code than the signed
+ // arithmetic generated by default
+ unsafe private static int PtrDiff(char* a, char* b)
+ {
+ return (int)(((uint)((byte*)a - (byte*)b)) >> 1);
+ }
+
+ // byte* flavor just for parity
+ unsafe private static int PtrDiff(byte* a, byte* b)
+ {
+ return (int)(a - b);
+ }
+
+ private static bool InRange(int ch, int start, int end)
+ {
+ return (uint)(ch - start) <= (uint)(end - start);
+ }
+
+ // Our workhorse
+ // Note: We ignore mismatched surrogates, unless the exception flag is set in which case we throw
+ internal override unsafe int GetBytes(char* chars, int charCount,
+ byte* bytes, int byteCount, EncoderNLS baseEncoder)
+ {
+ Debug.Assert(chars != null, "[UTF8Encoding.GetBytes]chars!=null");
+ Debug.Assert(byteCount >= 0, "[UTF8Encoding.GetBytes]byteCount >=0");
+ Debug.Assert(charCount >= 0, "[UTF8Encoding.GetBytes]charCount >=0");
+ Debug.Assert(bytes != null, "[UTF8Encoding.GetBytes]bytes!=null");
+
+ UTF8Encoder encoder = null;
+
+ // For fallback we may need a fallback buffer.
+ // We wait to initialize it though in case we don't have any broken input unicode
+ EncoderFallbackBuffer fallbackBuffer = null;
+ char* pSrcForFallback;
+
+ char* pSrc = chars;
+ byte* pTarget = bytes;
+
+ char* pEnd = pSrc + charCount;
+ byte* pAllocatedBufferEnd = pTarget + byteCount;
+
+ int ch = 0;
+
+ // assume that JIT will enregister pSrc, pTarget and ch
+
+ if (baseEncoder != null)
+ {
+ encoder = (UTF8Encoder)baseEncoder;
+ ch = encoder.surrogateChar;
+
+ // We mustn't have left over fallback data when counting
+ if (encoder.InternalHasFallbackBuffer)
+ {
+ // We always need the fallback buffer in get bytes so we can flush any remaining ones if necessary
+ fallbackBuffer = encoder.FallbackBuffer;
+ if (fallbackBuffer.Remaining > 0 && encoder.m_throwOnOverflow)
+ throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(chars, pEnd, encoder, true);
+ }
+ }
+
+ for (;;)
+ {
+ // SLOWLOOP: does all range checks, handles all special cases, but it is slow
+
+ if (pSrc >= pEnd)
+ {
+ if (ch == 0)
+ {
+ // Check if there's anthing left to get out of the fallback buffer
+ ch = fallbackBuffer != null ? fallbackBuffer.InternalGetNextChar() : 0;
+ if (ch > 0)
+ {
+ goto ProcessChar;
+ }
+ }
+ else
+ {
+ // Case of leftover surrogates in the fallback buffer
+ if (fallbackBuffer != null && fallbackBuffer.bFallingBack)
+ {
+ Debug.Assert(ch >= 0xD800 && ch <= 0xDBFF,
+ "[UTF8Encoding.GetBytes]expected high surrogate, not 0x" + ((int)ch).ToString("X4", CultureInfo.InvariantCulture));
+
+ int cha = ch;
+
+ ch = fallbackBuffer.InternalGetNextChar();
+
+ if (InRange(ch, CharUnicodeInfo.LOW_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END))
+ {
+ ch = ch + (cha << 10) + (0x10000 - CharUnicodeInfo.LOW_SURROGATE_START - (CharUnicodeInfo.HIGH_SURROGATE_START << 10));
+ goto EncodeChar;
+ }
+ else if (ch > 0)
+ {
+ goto ProcessChar;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ // attempt to encode the partial surrogate (will fail or ignore)
+ if (ch > 0 && (encoder == null || encoder.MustFlush))
+ goto EncodeChar;
+
+ // We're done
+ break;
+ }
+
+ if (ch > 0)
+ {
+ // We have a high surrogate left over from a previous loop.
+ Debug.Assert(ch >= 0xD800 && ch <= 0xDBFF,
+ "[UTF8Encoding.GetBytes]expected high surrogate, not 0x" + ((int)ch).ToString("X4", CultureInfo.InvariantCulture));
+
+ // use separate helper variables for local contexts so that the jit optimizations
+ // won't get confused about the variable lifetimes
+ int cha = *pSrc;
+
+ // In previous byte, we encountered a high surrogate, so we are expecting a low surrogate here.
+ // if (IsLowSurrogate(cha)) {
+ if (InRange(cha, CharUnicodeInfo.LOW_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END))
+ {
+ ch = cha + (ch << 10) +
+ (0x10000
+ - CharUnicodeInfo.LOW_SURROGATE_START
+ - (CharUnicodeInfo.HIGH_SURROGATE_START << 10));
+
+ pSrc++;
+ }
+ // else ch is still high surrogate and encoding will fail
+
+ // attempt to encode the surrogate or partial surrogate
+ goto EncodeChar;
+ }
+
+ // If we've used a fallback, then we have to check for it
+ if (fallbackBuffer != null)
+ {
+ ch = fallbackBuffer.InternalGetNextChar();
+ if (ch > 0) goto ProcessChar;
+ }
+
+ // read next char. The JIT optimization seems to be getting confused when
+ // compiling "ch = *pSrc++;", so rather use "ch = *pSrc; pSrc++;" instead
+ ch = *pSrc;
+ pSrc++;
+
+ ProcessChar:
+ // if (IsHighSurrogate(ch)) {
+ if (InRange(ch, CharUnicodeInfo.HIGH_SURROGATE_START, CharUnicodeInfo.HIGH_SURROGATE_END))
+ {
+ continue;
+ }
+ // either good char or partial surrogate
+
+ EncodeChar:
+ // throw exception on partial surrogate if necessary
+ // if (IsLowSurrogate(ch) || IsHighSurrogate(ch))
+ if (InRange(ch, CharUnicodeInfo.HIGH_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END))
+ {
+ // Lone surrogates aren't allowed, we have to do fallback for them
+ // Have to make a fallback buffer if we don't have one
+ if (fallbackBuffer == null)
+ {
+ // wait on fallbacks if we can
+ // For fallback we may need a fallback buffer
+ if (baseEncoder == null)
+ fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = baseEncoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(chars, pEnd, baseEncoder, true);
+ }
+
+ // Do our fallback. Actually we already know its a mixed up surrogate,
+ // so the ref pSrc isn't gonna do anything.
+ pSrcForFallback = pSrc; // Avoid passing pSrc by reference to allow it to be enregistered
+ fallbackBuffer.InternalFallback(unchecked((char)ch), ref pSrcForFallback);
+ pSrc = pSrcForFallback;
+
+ // Ignore it if we don't throw
+ ch = 0;
+ continue;
+ }
+
+ // Count bytes needed
+ int bytesNeeded = 1;
+ if (ch > 0x7F)
+ {
+ if (ch > 0x7FF)
+ {
+ if (ch > 0xFFFF)
+ {
+ bytesNeeded++; // 4 bytes (surrogate pair)
+ }
+ bytesNeeded++; // 3 bytes (800-FFFF)
+ }
+ bytesNeeded++; // 2 bytes (80-7FF)
+ }
+
+ if (pTarget > pAllocatedBufferEnd - bytesNeeded)
+ {
+ // Left over surrogate from last time will cause pSrc == chars, so we'll throw
+ if (fallbackBuffer != null && fallbackBuffer.bFallingBack)
+ {
+ fallbackBuffer.MovePrevious(); // Didn't use this fallback char
+ if (ch > 0xFFFF)
+ fallbackBuffer.MovePrevious(); // Was surrogate, didn't use 2nd part either
+ }
+ else
+ {
+ pSrc--; // Didn't use this char
+ if (ch > 0xFFFF)
+ pSrc--; // Was surrogate, didn't use 2nd part either
+ }
+ Debug.Assert(pSrc >= chars || pTarget == bytes,
+ "[UTF8Encoding.GetBytes]Expected pSrc to be within buffer or to throw with insufficient room.");
+ ThrowBytesOverflow(encoder, pTarget == bytes); // Throw if we must
+ ch = 0; // Nothing left over (we backed up to start of pair if supplimentary)
+ break;
+ }
+
+ if (ch <= 0x7F)
+ {
+ *pTarget = (byte)ch;
+ }
+ else
+ {
+ // use separate helper variables for local contexts so that the jit optimizations
+ // won't get confused about the variable lifetimes
+ int chb;
+ if (ch <= 0x7FF)
+ {
+ // 2 byte encoding
+ chb = (byte)(unchecked((sbyte)0xC0) | (ch >> 6));
+ }
+ else
+ {
+ if (ch <= 0xFFFF)
+ {
+ chb = (byte)(unchecked((sbyte)0xE0) | (ch >> 12));
+ }
+ else
+ {
+ *pTarget = (byte)(unchecked((sbyte)0xF0) | (ch >> 18));
+ pTarget++;
+
+ chb = unchecked((sbyte)0x80) | (ch >> 12) & 0x3F;
+ }
+ *pTarget = (byte)chb;
+ pTarget++;
+
+ chb = unchecked((sbyte)0x80) | (ch >> 6) & 0x3F;
+ }
+ *pTarget = (byte)chb;
+ pTarget++;
+
+ *pTarget = (byte)(unchecked((sbyte)0x80) | ch & 0x3F);
+ }
+ pTarget++;
+
+
+#if FASTLOOP
+ // If still have fallback don't do fast loop
+ if (fallbackBuffer != null && (ch = fallbackBuffer.InternalGetNextChar()) != 0)
+ goto ProcessChar;
+
+ int availableChars = PtrDiff(pEnd, pSrc);
+ int availableBytes = PtrDiff(pAllocatedBufferEnd, pTarget);
+
+ // don't fall into the fast decoding loop if we don't have enough characters
+ // Note that if we don't have enough bytes, pStop will prevent us from entering the fast loop.
+ if (availableChars <= 13)
+ {
+ // we are hoping for 1 byte per char
+ if (availableBytes < availableChars)
+ {
+ // not enough output room. no pending bits at this point
+ ch = 0;
+ continue;
+ }
+
+ // try to get over the remainder of the ascii characters fast though
+ char* pLocalEnd = pEnd; // hint to get pLocalEnd enregistered
+ while (pSrc < pLocalEnd)
+ {
+ ch = *pSrc;
+ pSrc++;
+
+ // Not ASCII, need more than 1 byte per char
+ if (ch > 0x7F)
+ goto ProcessChar;
+
+ *pTarget = (byte)ch;
+ pTarget++;
+ }
+ // we are done, let ch be 0 to clear encoder
+ ch = 0;
+ break;
+ }
+
+ // we need at least 1 byte per character, but Convert might allow us to convert
+ // only part of the input, so try as much as we can. Reduce charCount if necessary
+ if (availableBytes < availableChars)
+ {
+ availableChars = availableBytes;
+ }
+
+ // FASTLOOP:
+ // - optimistic range checks
+ // - fallbacks to the slow loop for all special cases, exception throwing, etc.
+
+ // To compute the upper bound, assume that all characters are ASCII characters at this point,
+ // the boundary will be decreased for every non-ASCII character we encounter
+ // Also, we need 5 chars reserve for the unrolled ansi decoding loop and for decoding of surrogates
+ // If there aren't enough bytes for the output, then pStop will be <= pSrc and will bypass the loop.
+ char* pStop = pSrc + availableChars - 5;
+
+ while (pSrc < pStop)
+ {
+ ch = *pSrc;
+ pSrc++;
+
+ if (ch > 0x7F)
+ {
+ goto LongCode;
+ }
+ *pTarget = (byte)ch;
+ pTarget++;
+
+ // get pSrc aligned
+ if ((unchecked((int)pSrc) & 0x2) != 0)
+ {
+ ch = *pSrc;
+ pSrc++;
+ if (ch > 0x7F)
+ {
+ goto LongCode;
+ }
+ *pTarget = (byte)ch;
+ pTarget++;
+ }
+
+ // Run 4 characters at a time!
+ while (pSrc < pStop)
+ {
+ ch = *(int*)pSrc;
+ int chc = *(int*)(pSrc + 2);
+ if (((ch | chc) & unchecked((int)0xFF80FF80)) != 0)
+ {
+ goto LongCodeWithMask;
+ }
+
+ // Unfortunately, this is endianess sensitive
+#if BIGENDIAN
+ *pTarget = (byte)(ch>>16);
+ *(pTarget+1) = (byte)ch;
+ pSrc += 4;
+ *(pTarget+2) = (byte)(chc>>16);
+ *(pTarget+3) = (byte)chc;
+ pTarget += 4;
+#else // BIGENDIAN
+ *pTarget = (byte)ch;
+ *(pTarget + 1) = (byte)(ch >> 16);
+ pSrc += 4;
+ *(pTarget + 2) = (byte)chc;
+ *(pTarget + 3) = (byte)(chc >> 16);
+ pTarget += 4;
+#endif // BIGENDIAN
+ }
+ continue;
+
+ LongCodeWithMask:
+#if BIGENDIAN
+ // be careful about the sign extension
+ ch = (int)(((uint)ch) >> 16);
+#else // BIGENDIAN
+ ch = (char)ch;
+#endif // BIGENDIAN
+ pSrc++;
+
+ if (ch > 0x7F)
+ {
+ goto LongCode;
+ }
+ *pTarget = (byte)ch;
+ pTarget++;
+ continue;
+
+ LongCode:
+ // use separate helper variables for slow and fast loop so that the jit optimizations
+ // won't get confused about the variable lifetimes
+ int chd;
+ if (ch <= 0x7FF)
+ {
+ // 2 byte encoding
+ chd = unchecked((sbyte)0xC0) | (ch >> 6);
+ }
+ else
+ {
+ // if (!IsLowSurrogate(ch) && !IsHighSurrogate(ch))
+ if (!InRange(ch, CharUnicodeInfo.HIGH_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END))
+ {
+ // 3 byte encoding
+ chd = unchecked((sbyte)0xE0) | (ch >> 12);
+ }
+ else
+ {
+ // 4 byte encoding - high surrogate + low surrogate
+ // if (!IsHighSurrogate(ch))
+ if (ch > CharUnicodeInfo.HIGH_SURROGATE_END)
+ {
+ // low without high -> bad, try again in slow loop
+ pSrc -= 1;
+ break;
+ }
+
+ chd = *pSrc;
+ pSrc++;
+
+ // if (!IsLowSurrogate(chd)) {
+ if (!InRange(chd, CharUnicodeInfo.LOW_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END))
+ {
+ // high not followed by low -> bad, try again in slow loop
+ pSrc -= 2;
+ break;
+ }
+
+ ch = chd + (ch << 10) +
+ (0x10000
+ - CharUnicodeInfo.LOW_SURROGATE_START
+ - (CharUnicodeInfo.HIGH_SURROGATE_START << 10));
+
+ *pTarget = (byte)(unchecked((sbyte)0xF0) | (ch >> 18));
+ // pStop - this byte is compensated by the second surrogate character
+ // 2 input chars require 4 output bytes. 2 have been anticipated already
+ // and 2 more will be accounted for by the 2 pStop-- calls below.
+ pTarget++;
+
+ chd = unchecked((sbyte)0x80) | (ch >> 12) & 0x3F;
+ }
+ *pTarget = (byte)chd;
+ pStop--; // 3 byte sequence for 1 char, so need pStop-- and the one below too.
+ pTarget++;
+
+ chd = unchecked((sbyte)0x80) | (ch >> 6) & 0x3F;
+ }
+ *pTarget = (byte)chd;
+ pStop--; // 2 byte sequence for 1 char so need pStop--.
+ pTarget++;
+
+ *pTarget = (byte)(unchecked((sbyte)0x80) | ch & 0x3F);
+ // pStop - this byte is already included
+ pTarget++;
+ }
+
+ Debug.Assert(pTarget <= pAllocatedBufferEnd, "[UTF8Encoding.GetBytes]pTarget <= pAllocatedBufferEnd");
+
+#endif // FASTLOOP
+
+ // no pending char at this point
+ ch = 0;
+ }
+
+ // Do we have to set the encoder bytes?
+ if (encoder != null)
+ {
+ Debug.Assert(!encoder.MustFlush || ch == 0,
+ "[UTF8Encoding.GetBytes] Expected no mustflush or 0 leftover ch " + ch.ToString("X2", CultureInfo.InvariantCulture));
+
+ encoder.surrogateChar = ch;
+ encoder.m_charsUsed = (int)(pSrc - chars);
+ }
+
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0 ||
+ baseEncoder == null || !baseEncoder.m_throwOnOverflow,
+ "[UTF8Encoding.GetBytes]Expected empty fallback buffer if not converting");
+
+ return (int)(pTarget - bytes);
+ }
+
+
+ // These are bitmasks used to maintain the state in the decoder. They occupy the higher bits
+ // while the actual character is being built in the lower bits. They are shifted together
+ // with the actual bits of the character.
+
+ // bits 30 & 31 are used for pending bits fixup
+ private const int FinalByte = 1 << 29;
+ private const int SupplimentarySeq = 1 << 28;
+ private const int ThreeByteSeq = 1 << 27;
+
+ // Note: We throw exceptions on individually encoded surrogates and other non-shortest forms.
+ // If exceptions aren't turned on, then we drop all non-shortest &individual surrogates.
+ //
+ // To simplify maintenance, the structure of GetCharCount and GetChars should be
+ // kept the same as much as possible
+ internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
+ {
+ Debug.Assert(count >= 0, "[UTF8Encoding.GetCharCount]count >=0");
+ Debug.Assert(bytes != null, "[UTF8Encoding.GetCharCount]bytes!=null");
+
+ // Initialize stuff
+ byte* pSrc = bytes;
+ byte* pEnd = pSrc + count;
+
+ // Start by assuming we have as many as count, charCount always includes the adjustment
+ // for the character being decoded
+ int charCount = count;
+ int ch = 0;
+ DecoderFallbackBuffer fallback = null;
+
+ if (baseDecoder != null)
+ {
+ UTF8Decoder decoder = (UTF8Decoder)baseDecoder;
+ ch = decoder.bits;
+ charCount -= (ch >> 30); // Adjust char count for # of expected bytes and expected output chars.
+
+ // Shouldn't have anything in fallback buffer for GetCharCount
+ // (don't have to check m_throwOnOverflow for count)
+ Debug.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
+ "[UTF8Encoding.GetCharCount]Expected empty fallback buffer at start");
+ }
+
+ for (;;)
+ {
+ // SLOWLOOP: does all range checks, handles all special cases, but it is slow
+
+ if (pSrc >= pEnd)
+ {
+ break;
+ }
+
+ if (ch == 0)
+ {
+ // no pending bits
+ goto ReadChar;
+ }
+
+ // read next byte. The JIT optimization seems to be getting confused when
+ // compiling "ch = *pSrc++;", so rather use "ch = *pSrc; pSrc++;" instead
+ int cha = *pSrc;
+ pSrc++;
+
+ // we are expecting to see trailing bytes like 10vvvvvv
+ if ((cha & unchecked((sbyte)0xC0)) != 0x80)
+ {
+ // This can be a valid starting byte for another UTF8 byte sequence, so let's put
+ // the current byte back, and try to see if this is a valid byte for another UTF8 byte sequence
+ pSrc--;
+ charCount += (ch >> 30);
+ goto InvalidByteSequence;
+ }
+
+ // fold in the new byte
+ ch = (ch << 6) | (cha & 0x3F);
+
+ if ((ch & FinalByte) == 0)
+ {
+ Debug.Assert((ch & (SupplimentarySeq | ThreeByteSeq)) != 0,
+ "[UTF8Encoding.GetChars]Invariant volation");
+
+ if ((ch & SupplimentarySeq) != 0)
+ {
+ if ((ch & (FinalByte >> 6)) != 0)
+ {
+ // this is 3rd byte (of 4 byte supplimentary) - nothing to do
+ continue;
+ }
+
+ // 2nd byte, check for non-shortest form of supplimentary char and the valid
+ // supplimentary characters in range 0x010000 - 0x10FFFF at the same time
+ if (!InRange(ch & 0x1F0, 0x10, 0x100))
+ {
+ goto InvalidByteSequence;
+ }
+ }
+ else
+ {
+ // Must be 2nd byte of a 3-byte sequence
+ // check for non-shortest form of 3 byte seq
+ if ((ch & (0x1F << 5)) == 0 || // non-shortest form
+ (ch & (0xF800 >> 6)) == (0xD800 >> 6)) // illegal individually encoded surrogate
+ {
+ goto InvalidByteSequence;
+ }
+ }
+ continue;
+ }
+
+ // ready to punch
+
+ // adjust for surrogates in non-shortest form
+ if ((ch & (SupplimentarySeq | 0x1F0000)) == SupplimentarySeq)
+ {
+ charCount--;
+ }
+ goto EncodeChar;
+
+ InvalidByteSequence:
+ // this code fragment should be close to the gotos referencing it
+ // Have to do fallback for invalid bytes
+ if (fallback == null)
+ {
+ if (baseDecoder == null)
+ fallback = this.decoderFallback.CreateFallbackBuffer();
+ else
+ fallback = baseDecoder.FallbackBuffer;
+ fallback.InternalInitialize(bytes, null);
+ }
+ charCount += FallbackInvalidByteSequence(pSrc, ch, fallback);
+
+ ch = 0;
+ continue;
+
+ ReadChar:
+ ch = *pSrc;
+ pSrc++;
+
+ ProcessChar:
+ if (ch > 0x7F)
+ {
+ // If its > 0x7F, its start of a new multi-byte sequence
+
+ // Long sequence, so unreserve our char.
+ charCount--;
+
+ // bit 6 has to be non-zero for start of multibyte chars.
+ if ((ch & 0x40) == 0)
+ {
+ // Unexpected trail byte
+ goto InvalidByteSequence;
+ }
+
+ // start a new long code
+ if ((ch & 0x20) != 0)
+ {
+ if ((ch & 0x10) != 0)
+ {
+ // 4 byte encoding - supplimentary character (2 surrogates)
+
+ ch &= 0x0F;
+
+ // check that bit 4 is zero and the valid supplimentary character
+ // range 0x000000 - 0x10FFFF at the same time
+ if (ch > 0x04)
+ {
+ ch |= 0xf0;
+ goto InvalidByteSequence;
+ }
+
+ // Add bit flags so that when we check new characters & rotate we'll be flagged correctly.
+ // Final byte flag, count fix if we don't make final byte & supplimentary sequence flag.
+ ch |= (FinalByte >> 3 * 6) | // Final byte is 3 more bytes from now
+ (1 << 30) | // If it dies on next byte we'll need an extra char
+ (3 << (30 - 2 * 6)) | // If it dies on last byte we'll need to subtract a char
+ (SupplimentarySeq) | (SupplimentarySeq >> 6) |
+ (SupplimentarySeq >> 2 * 6) | (SupplimentarySeq >> 3 * 6);
+
+ // Our character count will be 2 characters for these 4 bytes, so subtract another char
+ charCount--;
+ }
+ else
+ {
+ // 3 byte encoding
+ // Add bit flags so that when we check new characters & rotate we'll be flagged correctly.
+ ch = (ch & 0x0F) | ((FinalByte >> 2 * 6) | (1 << 30) |
+ (ThreeByteSeq) | (ThreeByteSeq >> 6) | (ThreeByteSeq >> 2 * 6));
+
+ // We'll expect 1 character for these 3 bytes, so subtract another char.
+ charCount--;
+ }
+ }
+ else
+ {
+ // 2 byte encoding
+
+ ch &= 0x1F;
+
+ // check for non-shortest form
+ if (ch <= 1)
+ {
+ ch |= 0xc0;
+ goto InvalidByteSequence;
+ }
+
+ // Add bit flags so we'll be flagged correctly
+ ch |= (FinalByte >> 6);
+ }
+ continue;
+ }
+
+ EncodeChar:
+
+#if FASTLOOP
+ int availableBytes = PtrDiff(pEnd, pSrc);
+
+ // don't fall into the fast decoding loop if we don't have enough bytes
+ if (availableBytes <= 13)
+ {
+ // try to get over the remainder of the ascii characters fast though
+ byte* pLocalEnd = pEnd; // hint to get pLocalEnd enregistered
+ while (pSrc < pLocalEnd)
+ {
+ ch = *pSrc;
+ pSrc++;
+
+ if (ch > 0x7F)
+ goto ProcessChar;
+ }
+ // we are done
+ ch = 0;
+ break;
+ }
+
+ // To compute the upper bound, assume that all characters are ASCII characters at this point,
+ // the boundary will be decreased for every non-ASCII character we encounter
+ // Also, we need 7 chars reserve for the unrolled ansi decoding loop and for decoding of multibyte sequences
+ byte* pStop = pSrc + availableBytes - 7;
+
+ while (pSrc < pStop)
+ {
+ ch = *pSrc;
+ pSrc++;
+
+ if (ch > 0x7F)
+ {
+ goto LongCode;
+ }
+
+ // get pSrc 2-byte aligned
+ if ((unchecked((int)pSrc) & 0x1) != 0)
+ {
+ ch = *pSrc;
+ pSrc++;
+ if (ch > 0x7F)
+ {
+ goto LongCode;
+ }
+ }
+
+ // get pSrc 4-byte aligned
+ if ((unchecked((int)pSrc) & 0x2) != 0)
+ {
+ ch = *(ushort*)pSrc;
+ if ((ch & 0x8080) != 0)
+ {
+ goto LongCodeWithMask16;
+ }
+ pSrc += 2;
+ }
+
+ // Run 8 + 8 characters at a time!
+ while (pSrc < pStop)
+ {
+ ch = *(int*)pSrc;
+ int chb = *(int*)(pSrc + 4);
+ if (((ch | chb) & unchecked((int)0x80808080)) != 0)
+ {
+ goto LongCodeWithMask32;
+ }
+ pSrc += 8;
+
+ // This is a really small loop - unroll it
+ if (pSrc >= pStop)
+ break;
+
+ ch = *(int*)pSrc;
+ chb = *(int*)(pSrc + 4);
+ if (((ch | chb) & unchecked((int)0x80808080)) != 0)
+ {
+ goto LongCodeWithMask32;
+ }
+ pSrc += 8;
+ }
+ break;
+
+#if BIGENDIAN
+ LongCodeWithMask32:
+ // be careful about the sign extension
+ ch = (int)(((uint)ch) >> 16);
+ LongCodeWithMask16:
+ ch = (int)(((uint)ch) >> 8);
+#else // BIGENDIAN
+ LongCodeWithMask32:
+ LongCodeWithMask16:
+ ch &= 0xFF;
+#endif // BIGENDIAN
+ pSrc++;
+ if (ch <= 0x7F)
+ {
+ continue;
+ }
+
+ LongCode:
+ int chc = *pSrc;
+ pSrc++;
+
+ if (
+ // bit 6 has to be zero
+ (ch & 0x40) == 0 ||
+ // we are expecting to see trailing bytes like 10vvvvvv
+ (chc & unchecked((sbyte)0xC0)) != 0x80)
+ {
+ goto BadLongCode;
+ }
+
+ chc &= 0x3F;
+
+ // start a new long code
+ if ((ch & 0x20) != 0)
+ {
+ // fold the first two bytes together
+ chc |= (ch & 0x0F) << 6;
+
+ if ((ch & 0x10) != 0)
+ {
+ // 4 byte encoding - surrogate
+ ch = *pSrc;
+ if (
+ // check that bit 4 is zero, the non-shortest form of surrogate
+ // and the valid surrogate range 0x000000 - 0x10FFFF at the same time
+ !InRange(chc >> 4, 0x01, 0x10) ||
+ // we are expecting to see trailing bytes like 10vvvvvv
+ (ch & unchecked((sbyte)0xC0)) != 0x80)
+ {
+ goto BadLongCode;
+ }
+
+ chc = (chc << 6) | (ch & 0x3F);
+
+ ch = *(pSrc + 1);
+ // we are expecting to see trailing bytes like 10vvvvvv
+ if ((ch & unchecked((sbyte)0xC0)) != 0x80)
+ {
+ goto BadLongCode;
+ }
+ pSrc += 2;
+
+ // extra byte
+ charCount--;
+ }
+ else
+ {
+ // 3 byte encoding
+ ch = *pSrc;
+ if (
+ // check for non-shortest form of 3 byte seq
+ (chc & (0x1F << 5)) == 0 ||
+ // Can't have surrogates here.
+ (chc & (0xF800 >> 6)) == (0xD800 >> 6) ||
+ // we are expecting to see trailing bytes like 10vvvvvv
+ (ch & unchecked((sbyte)0xC0)) != 0x80)
+ {
+ goto BadLongCode;
+ }
+ pSrc++;
+
+ // extra byte
+ charCount--;
+ }
+ }
+ else
+ {
+ // 2 byte encoding
+
+ // check for non-shortest form
+ if ((ch & 0x1E) == 0)
+ {
+ goto BadLongCode;
+ }
+ }
+
+ // extra byte
+ charCount--;
+ }
+#endif // FASTLOOP
+
+ // no pending bits at this point
+ ch = 0;
+ continue;
+
+ BadLongCode:
+ pSrc -= 2;
+ ch = 0;
+ continue;
+ }
+
+ // May have a problem if we have to flush
+ if (ch != 0)
+ {
+ // We were already adjusting for these, so need to unadjust
+ charCount += (ch >> 30);
+ if (baseDecoder == null || baseDecoder.MustFlush)
+ {
+ // Have to do fallback for invalid bytes
+ if (fallback == null)
+ {
+ if (baseDecoder == null)
+ fallback = this.decoderFallback.CreateFallbackBuffer();
+ else
+ fallback = baseDecoder.FallbackBuffer;
+ fallback.InternalInitialize(bytes, null);
+ }
+ charCount += FallbackInvalidByteSequence(pSrc, ch, fallback);
+ }
+ }
+
+ // Shouldn't have anything in fallback buffer for GetCharCount
+ // (don't have to check m_throwOnOverflow for count)
+ Debug.Assert(fallback == null || fallback.Remaining == 0,
+ "[UTF8Encoding.GetCharCount]Expected empty fallback buffer at end");
+
+ return charCount;
+ }
+
+ // WARNING: If we throw an error, then System.Resources.ResourceReader calls this method.
+ // So if we're really broken, then that could also throw an error... recursively.
+ // So try to make sure GetChars can at least process all uses by
+ // System.Resources.ResourceReader!
+ //
+ // Note: We throw exceptions on individually encoded surrogates and other non-shortest forms.
+ // If exceptions aren't turned on, then we drop all non-shortest &individual surrogates.
+ //
+ // To simplify maintenance, the structure of GetCharCount and GetChars should be
+ // kept the same as much as possible
+ internal override unsafe int GetChars(byte* bytes, int byteCount,
+ char* chars, int charCount, DecoderNLS baseDecoder)
+ {
+ Debug.Assert(chars != null, "[UTF8Encoding.GetChars]chars!=null");
+ Debug.Assert(byteCount >= 0, "[UTF8Encoding.GetChars]count >=0");
+ Debug.Assert(charCount >= 0, "[UTF8Encoding.GetChars]charCount >=0");
+ Debug.Assert(bytes != null, "[UTF8Encoding.GetChars]bytes!=null");
+
+ byte* pSrc = bytes;
+ char* pTarget = chars;
+
+ byte* pEnd = pSrc + byteCount;
+ char* pAllocatedBufferEnd = pTarget + charCount;
+
+ int ch = 0;
+
+ DecoderFallbackBuffer fallback = null;
+ byte* pSrcForFallback;
+ char* pTargetForFallback;
+ if (baseDecoder != null)
+ {
+ UTF8Decoder decoder = (UTF8Decoder)baseDecoder;
+ ch = decoder.bits;
+
+ // Shouldn't have anything in fallback buffer for GetChars
+ // (don't have to check m_throwOnOverflow for chars, we always use all or none so always should be empty)
+ Debug.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
+ "[UTF8Encoding.GetChars]Expected empty fallback buffer at start");
+ }
+
+ for (;;)
+ {
+ // SLOWLOOP: does all range checks, handles all special cases, but it is slow
+
+ if (pSrc >= pEnd)
+ {
+ break;
+ }
+
+ if (ch == 0)
+ {
+ // no pending bits
+ goto ReadChar;
+ }
+
+ // read next byte. The JIT optimization seems to be getting confused when
+ // compiling "ch = *pSrc++;", so rather use "ch = *pSrc; pSrc++;" instead
+ int cha = *pSrc;
+ pSrc++;
+
+ // we are expecting to see trailing bytes like 10vvvvvv
+ if ((cha & unchecked((sbyte)0xC0)) != 0x80)
+ {
+ // This can be a valid starting byte for another UTF8 byte sequence, so let's put
+ // the current byte back, and try to see if this is a valid byte for another UTF8 byte sequence
+ pSrc--;
+ goto InvalidByteSequence;
+ }
+
+ // fold in the new byte
+ ch = (ch << 6) | (cha & 0x3F);
+
+ if ((ch & FinalByte) == 0)
+ {
+ // Not at last byte yet
+ Debug.Assert((ch & (SupplimentarySeq | ThreeByteSeq)) != 0,
+ "[UTF8Encoding.GetChars]Invariant volation");
+
+ if ((ch & SupplimentarySeq) != 0)
+ {
+ // Its a 4-byte supplimentary sequence
+ if ((ch & (FinalByte >> 6)) != 0)
+ {
+ // this is 3rd byte of 4 byte sequence - nothing to do
+ continue;
+ }
+
+ // 2nd byte of 4 bytes
+ // check for non-shortest form of surrogate and the valid surrogate
+ // range 0x000000 - 0x10FFFF at the same time
+ if (!InRange(ch & 0x1F0, 0x10, 0x100))
+ {
+ goto InvalidByteSequence;
+ }
+ }
+ else
+ {
+ // Must be 2nd byte of a 3-byte sequence
+ // check for non-shortest form of 3 byte seq
+ if ((ch & (0x1F << 5)) == 0 || // non-shortest form
+ (ch & (0xF800 >> 6)) == (0xD800 >> 6)) // illegal individually encoded surrogate
+ {
+ goto InvalidByteSequence;
+ }
+ }
+ continue;
+ }
+
+ // ready to punch
+
+ // surrogate in shortest form?
+ // Might be possible to get rid of this? Already did non-shortest check for 4-byte sequence when reading 2nd byte?
+ if ((ch & (SupplimentarySeq | 0x1F0000)) > SupplimentarySeq)
+ {
+ // let the range check for the second char throw the exception
+ if (pTarget < pAllocatedBufferEnd)
+ {
+ *pTarget = (char)(((ch >> 10) & 0x7FF) +
+ unchecked((short)((CharUnicodeInfo.HIGH_SURROGATE_START - (0x10000 >> 10)))));
+ pTarget++;
+
+ ch = (ch & 0x3FF) +
+ unchecked((int)(CharUnicodeInfo.LOW_SURROGATE_START));
+ }
+ }
+
+ goto EncodeChar;
+
+ InvalidByteSequence:
+ // this code fragment should be close to the gotos referencing it
+ // Have to do fallback for invalid bytes
+ if (fallback == null)
+ {
+ if (baseDecoder == null)
+ fallback = this.decoderFallback.CreateFallbackBuffer();
+ else
+ fallback = baseDecoder.FallbackBuffer;
+ fallback.InternalInitialize(bytes, pAllocatedBufferEnd);
+ }
+ // This'll back us up the appropriate # of bytes if we didn't get anywhere
+ pSrcForFallback = pSrc; // Avoid passing pSrc by reference to allow it to be enregistered
+ pTargetForFallback = pTarget; // Avoid passing pTarget by reference to allow it to be enregistered
+ bool fallbackResult = FallbackInvalidByteSequence(ref pSrcForFallback, ch, fallback, ref pTargetForFallback);
+ pSrc = pSrcForFallback;
+ pTarget = pTargetForFallback;
+
+ if (!fallbackResult)
+ {
+ // Ran out of buffer space
+ // Need to throw an exception?
+ Debug.Assert(pSrc >= bytes || pTarget == chars,
+ "[UTF8Encoding.GetChars]Expected to throw or remain in byte buffer after fallback");
+ fallback.InternalReset();
+ ThrowCharsOverflow(baseDecoder, pTarget == chars);
+ ch = 0;
+ break;
+ }
+ Debug.Assert(pSrc >= bytes,
+ "[UTF8Encoding.GetChars]Expected invalid byte sequence to have remained within the byte array");
+ ch = 0;
+ continue;
+
+ ReadChar:
+ ch = *pSrc;
+ pSrc++;
+
+ ProcessChar:
+ if (ch > 0x7F)
+ {
+ // If its > 0x7F, its start of a new multi-byte sequence
+
+ // bit 6 has to be non-zero
+ if ((ch & 0x40) == 0)
+ {
+ goto InvalidByteSequence;
+ }
+
+ // start a new long code
+ if ((ch & 0x20) != 0)
+ {
+ if ((ch & 0x10) != 0)
+ {
+ // 4 byte encoding - supplimentary character (2 surrogates)
+
+ ch &= 0x0F;
+
+ // check that bit 4 is zero and the valid supplimentary character
+ // range 0x000000 - 0x10FFFF at the same time
+ if (ch > 0x04)
+ {
+ ch |= 0xf0;
+ goto InvalidByteSequence;
+ }
+
+ ch |= (FinalByte >> 3 * 6) | (1 << 30) | (3 << (30 - 2 * 6)) |
+ (SupplimentarySeq) | (SupplimentarySeq >> 6) |
+ (SupplimentarySeq >> 2 * 6) | (SupplimentarySeq >> 3 * 6);
+ }
+ else
+ {
+ // 3 byte encoding
+ ch = (ch & 0x0F) | ((FinalByte >> 2 * 6) | (1 << 30) |
+ (ThreeByteSeq) | (ThreeByteSeq >> 6) | (ThreeByteSeq >> 2 * 6));
+ }
+ }
+ else
+ {
+ // 2 byte encoding
+
+ ch &= 0x1F;
+
+ // check for non-shortest form
+ if (ch <= 1)
+ {
+ ch |= 0xc0;
+ goto InvalidByteSequence;
+ }
+
+ ch |= (FinalByte >> 6);
+ }
+ continue;
+ }
+
+ EncodeChar:
+ // write the pending character
+ if (pTarget >= pAllocatedBufferEnd)
+ {
+ // Fix chars so we make sure to throw if we didn't output anything
+ ch &= 0x1fffff;
+ if (ch > 0x7f)
+ {
+ if (ch > 0x7ff)
+ {
+ if (ch >= CharUnicodeInfo.LOW_SURROGATE_START &&
+ ch <= CharUnicodeInfo.LOW_SURROGATE_END)
+ {
+ pSrc--; // It was 4 bytes
+ pTarget--; // 1 was stored already, but we can't remember 1/2, so back up
+ }
+ else if (ch > 0xffff)
+ {
+ pSrc--; // It was 4 bytes, nothing was stored
+ }
+ pSrc--; // It was at least 3 bytes
+ }
+ pSrc--; // It was at least 2 bytes
+ }
+ pSrc--;
+
+ // Throw that we don't have enough room (pSrc could be < chars if we had started to process
+ // a 4 byte sequence alredy)
+ Debug.Assert(pSrc >= bytes || pTarget == chars,
+ "[UTF8Encoding.GetChars]Expected pSrc to be within input buffer or throw due to no output]");
+ ThrowCharsOverflow(baseDecoder, pTarget == chars);
+
+ // Don't store ch in decoder, we already backed up to its start
+ ch = 0;
+
+ // Didn't throw, just use this buffer size.
+ break;
+ }
+ *pTarget = (char)ch;
+ pTarget++;
+
+#if FASTLOOP
+ int availableChars = PtrDiff(pAllocatedBufferEnd, pTarget);
+ int availableBytes = PtrDiff(pEnd, pSrc);
+
+ // don't fall into the fast decoding loop if we don't have enough bytes
+ // Test for availableChars is done because pStop would be <= pTarget.
+ if (availableBytes <= 13)
+ {
+ // we may need as many as 1 character per byte
+ if (availableChars < availableBytes)
+ {
+ // not enough output room. no pending bits at this point
+ ch = 0;
+ continue;
+ }
+
+ // try to get over the remainder of the ascii characters fast though
+ byte* pLocalEnd = pEnd; // hint to get pLocalEnd enregistered
+ while (pSrc < pLocalEnd)
+ {
+ ch = *pSrc;
+ pSrc++;
+
+ if (ch > 0x7F)
+ goto ProcessChar;
+
+ *pTarget = (char)ch;
+ pTarget++;
+ }
+ // we are done
+ ch = 0;
+ break;
+ }
+
+ // we may need as many as 1 character per byte, so reduce the byte count if necessary.
+ // If availableChars is too small, pStop will be before pTarget and we won't do fast loop.
+ if (availableChars < availableBytes)
+ {
+ availableBytes = availableChars;
+ }
+
+ // To compute the upper bound, assume that all characters are ASCII characters at this point,
+ // the boundary will be decreased for every non-ASCII character we encounter
+ // Also, we need 7 chars reserve for the unrolled ansi decoding loop and for decoding of multibyte sequences
+ char* pStop = pTarget + availableBytes - 7;
+
+ while (pTarget < pStop)
+ {
+ ch = *pSrc;
+ pSrc++;
+
+ if (ch > 0x7F)
+ {
+ goto LongCode;
+ }
+ *pTarget = (char)ch;
+ pTarget++;
+
+ // get pSrc to be 2-byte aligned
+ if ((unchecked((int)pSrc) & 0x1) != 0)
+ {
+ ch = *pSrc;
+ pSrc++;
+ if (ch > 0x7F)
+ {
+ goto LongCode;
+ }
+ *pTarget = (char)ch;
+ pTarget++;
+ }
+
+ // get pSrc to be 4-byte aligned
+ if ((unchecked((int)pSrc) & 0x2) != 0)
+ {
+ ch = *(ushort*)pSrc;
+ if ((ch & 0x8080) != 0)
+ {
+ goto LongCodeWithMask16;
+ }
+
+ // Unfortunately, this is endianess sensitive
+#if BIGENDIAN
+ *pTarget = (char)((ch >> 8) & 0x7F);
+ pSrc += 2;
+ *(pTarget+1) = (char)(ch & 0x7F);
+ pTarget += 2;
+#else // BIGENDIAN
+ *pTarget = (char)(ch & 0x7F);
+ pSrc += 2;
+ *(pTarget + 1) = (char)((ch >> 8) & 0x7F);
+ pTarget += 2;
+#endif // BIGENDIAN
+ }
+
+ // Run 8 characters at a time!
+ while (pTarget < pStop)
+ {
+ ch = *(int*)pSrc;
+ int chb = *(int*)(pSrc + 4);
+ if (((ch | chb) & unchecked((int)0x80808080)) != 0)
+ {
+ goto LongCodeWithMask32;
+ }
+
+ // Unfortunately, this is endianess sensitive
+#if BIGENDIAN
+ *pTarget = (char)((ch >> 24) & 0x7F);
+ *(pTarget+1) = (char)((ch >> 16) & 0x7F);
+ *(pTarget+2) = (char)((ch >> 8) & 0x7F);
+ *(pTarget+3) = (char)(ch & 0x7F);
+ pSrc += 8;
+ *(pTarget+4) = (char)((chb >> 24) & 0x7F);
+ *(pTarget+5) = (char)((chb >> 16) & 0x7F);
+ *(pTarget+6) = (char)((chb >> 8) & 0x7F);
+ *(pTarget+7) = (char)(chb & 0x7F);
+ pTarget += 8;
+#else // BIGENDIAN
+ *pTarget = (char)(ch & 0x7F);
+ *(pTarget + 1) = (char)((ch >> 8) & 0x7F);
+ *(pTarget + 2) = (char)((ch >> 16) & 0x7F);
+ *(pTarget + 3) = (char)((ch >> 24) & 0x7F);
+ pSrc += 8;
+ *(pTarget + 4) = (char)(chb & 0x7F);
+ *(pTarget + 5) = (char)((chb >> 8) & 0x7F);
+ *(pTarget + 6) = (char)((chb >> 16) & 0x7F);
+ *(pTarget + 7) = (char)((chb >> 24) & 0x7F);
+ pTarget += 8;
+#endif // BIGENDIAN
+ }
+ break;
+
+#if BIGENDIAN
+ LongCodeWithMask32:
+ // be careful about the sign extension
+ ch = (int)(((uint)ch) >> 16);
+ LongCodeWithMask16:
+ ch = (int)(((uint)ch) >> 8);
+#else // BIGENDIAN
+ LongCodeWithMask32:
+ LongCodeWithMask16:
+ ch &= 0xFF;
+#endif // BIGENDIAN
+ pSrc++;
+ if (ch <= 0x7F)
+ {
+ *pTarget = (char)ch;
+ pTarget++;
+ continue;
+ }
+
+ LongCode:
+ int chc = *pSrc;
+ pSrc++;
+
+ if (
+ // bit 6 has to be zero
+ (ch & 0x40) == 0 ||
+ // we are expecting to see trailing bytes like 10vvvvvv
+ (chc & unchecked((sbyte)0xC0)) != 0x80)
+ {
+ goto BadLongCode;
+ }
+
+ chc &= 0x3F;
+
+ // start a new long code
+ if ((ch & 0x20) != 0)
+ {
+ // fold the first two bytes together
+ chc |= (ch & 0x0F) << 6;
+
+ if ((ch & 0x10) != 0)
+ {
+ // 4 byte encoding - surrogate
+ ch = *pSrc;
+ if (
+ // check that bit 4 is zero, the non-shortest form of surrogate
+ // and the valid surrogate range 0x000000 - 0x10FFFF at the same time
+ !InRange(chc >> 4, 0x01, 0x10) ||
+ // we are expecting to see trailing bytes like 10vvvvvv
+ (ch & unchecked((sbyte)0xC0)) != 0x80)
+ {
+ goto BadLongCode;
+ }
+
+ chc = (chc << 6) | (ch & 0x3F);
+
+ ch = *(pSrc + 1);
+ // we are expecting to see trailing bytes like 10vvvvvv
+ if ((ch & unchecked((sbyte)0xC0)) != 0x80)
+ {
+ goto BadLongCode;
+ }
+ pSrc += 2;
+
+ ch = (chc << 6) | (ch & 0x3F);
+
+ *pTarget = (char)(((ch >> 10) & 0x7FF) +
+ unchecked((short)(CharUnicodeInfo.HIGH_SURROGATE_START - (0x10000 >> 10))));
+ pTarget++;
+
+ ch = (ch & 0x3FF) +
+ unchecked((short)(CharUnicodeInfo.LOW_SURROGATE_START));
+
+ // extra byte, we're already planning 2 chars for 2 of these bytes,
+ // but the big loop is testing the target against pStop, so we need
+ // to subtract 2 more or we risk overrunning the input. Subtract
+ // one here and one below.
+ pStop--;
+ }
+ else
+ {
+ // 3 byte encoding
+ ch = *pSrc;
+ if (
+ // check for non-shortest form of 3 byte seq
+ (chc & (0x1F << 5)) == 0 ||
+ // Can't have surrogates here.
+ (chc & (0xF800 >> 6)) == (0xD800 >> 6) ||
+ // we are expecting to see trailing bytes like 10vvvvvv
+ (ch & unchecked((sbyte)0xC0)) != 0x80)
+ {
+ goto BadLongCode;
+ }
+ pSrc++;
+
+ ch = (chc << 6) | (ch & 0x3F);
+
+ // extra byte, we're only expecting 1 char for each of these 3 bytes,
+ // but the loop is testing the target (not source) against pStop, so
+ // we need to subtract 2 more or we risk overrunning the input.
+ // Subtract 1 here and one more below
+ pStop--;
+ }
+ }
+ else
+ {
+ // 2 byte encoding
+
+ ch &= 0x1F;
+
+ // check for non-shortest form
+ if (ch <= 1)
+ {
+ goto BadLongCode;
+ }
+ ch = (ch << 6) | chc;
+ }
+
+ *pTarget = (char)ch;
+ pTarget++;
+
+ // extra byte, we're only expecting 1 char for each of these 2 bytes,
+ // but the loop is testing the target (not source) against pStop.
+ // subtract an extra count from pStop so that we don't overrun the input.
+ pStop--;
+ }
+#endif // FASTLOOP
+
+ Debug.Assert(pTarget <= pAllocatedBufferEnd, "[UTF8Encoding.GetChars]pTarget <= pAllocatedBufferEnd");
+
+ // no pending bits at this point
+ ch = 0;
+ continue;
+
+ BadLongCode:
+ pSrc -= 2;
+ ch = 0;
+ continue;
+ }
+
+ if (ch != 0 && (baseDecoder == null || baseDecoder.MustFlush))
+ {
+ // Have to do fallback for invalid bytes
+ if (fallback == null)
+ {
+ if (baseDecoder == null)
+ fallback = this.decoderFallback.CreateFallbackBuffer();
+ else
+ fallback = baseDecoder.FallbackBuffer;
+ fallback.InternalInitialize(bytes, pAllocatedBufferEnd);
+ }
+
+ // This'll back us up the appropriate # of bytes if we didn't get anywhere
+ pSrcForFallback = pSrc; // Avoid passing pSrc by reference to allow it to be enregistered
+ pTargetForFallback = pTarget; // Avoid passing pTarget by reference to allow it to be enregistered
+ bool fallbackResult = FallbackInvalidByteSequence(ref pSrcForFallback, ch, fallback, ref pTargetForFallback);
+ pSrc = pSrcForFallback;
+ pTarget = pTargetForFallback;
+
+ if (!fallbackResult)
+ {
+ Debug.Assert(pSrc >= bytes || pTarget == chars,
+ "[UTF8Encoding.GetChars]Expected to throw or remain in byte buffer while flushing");
+
+ // Ran out of buffer space
+ // Need to throw an exception?
+ fallback.InternalReset();
+ ThrowCharsOverflow(baseDecoder, pTarget == chars);
+ }
+ Debug.Assert(pSrc >= bytes,
+ "[UTF8Encoding.GetChars]Expected flushing invalid byte sequence to have remained within the byte array");
+ ch = 0;
+ }
+
+ if (baseDecoder != null)
+ {
+ UTF8Decoder decoder = (UTF8Decoder)baseDecoder;
+
+ // If we're storing flush data we expect all bits to be used or else
+ // we're stuck in the middle of a conversion
+ Debug.Assert(!baseDecoder.MustFlush || ch == 0 || !baseDecoder.m_throwOnOverflow,
+ "[UTF8Encoding.GetChars]Expected no must flush or no left over bits or no throw on overflow.");
+
+ // Remember our leftover bits.
+ decoder.bits = ch;
+
+ baseDecoder.m_bytesUsed = (int)(pSrc - bytes);
+ }
+
+ // Shouldn't have anything in fallback buffer for GetChars
+ // (don't have to check m_throwOnOverflow for chars)
+ Debug.Assert(fallback == null || fallback.Remaining == 0,
+ "[UTF8Encoding.GetChars]Expected empty fallback buffer at end");
+
+ return PtrDiff(pTarget, chars);
+ }
+
+ // During GetChars we had an invalid byte sequence
+ // pSrc is backed up to the start of the bad sequence if we didn't have room to
+ // fall it back. Otherwise pSrc remains wher it is.
+ private unsafe bool FallbackInvalidByteSequence(
+ ref byte* pSrc, int ch, DecoderFallbackBuffer fallback, ref char* pTarget)
+ {
+ // Get our byte[]
+ byte* pStart = pSrc;
+ byte[] bytesUnknown = GetBytesUnknown(ref pStart, ch);
+
+ // Do the actual fallback
+ if (!fallback.InternalFallback(bytesUnknown, pSrc, ref pTarget))
+ {
+ // Oops, it failed, back up to pStart
+ pSrc = pStart;
+ return false;
+ }
+
+ // It worked
+ return true;
+ }
+
+ // During GetCharCount we had an invalid byte sequence
+ // pSrc is used to find the index that points to the invalid bytes,
+ // however the byte[] contains the fallback bytes (in case the index is -1)
+ private unsafe int FallbackInvalidByteSequence(
+ byte* pSrc, int ch, DecoderFallbackBuffer fallback)
+ {
+ // Get our byte[]
+ byte[] bytesUnknown = GetBytesUnknown(ref pSrc, ch);
+
+ // Do the actual fallback
+ int count = fallback.InternalFallback(bytesUnknown, pSrc);
+
+ // # of fallback chars expected.
+ // Note that we only get here for "long" sequences, and have already unreserved
+ // the count that we prereserved for the input bytes
+ return count;
+ }
+
+ // Note that some of these bytes may have come from a previous fallback, so we cannot
+ // just decrement the pointer and use the values we read. In those cases we have
+ // to regenerate the original values.
+ private unsafe byte[] GetBytesUnknown(ref byte* pSrc, int ch)
+ {
+ // Get our byte[]
+ byte[] bytesUnknown = null;
+
+ // See if it was a plain char
+ // (have to check >= 0 because we have all sorts of wierd bit flags)
+ if (ch < 0x100 && ch >= 0)
+ {
+ pSrc--;
+ bytesUnknown = new byte[] { unchecked((byte)ch) };
+ }
+ // See if its an unfinished 2 byte sequence
+ else if ((ch & (SupplimentarySeq | ThreeByteSeq)) == 0)
+ {
+ pSrc--;
+ bytesUnknown = new byte[] { unchecked((byte)((ch & 0x1F) | 0xc0)) };
+ }
+ // So now we're either 2nd byte of 3 or 4 byte sequence or
+ // we hit a non-trail byte or we ran out of space for 3rd byte of 4 byte sequence
+ // 1st check if its a 4 byte sequence
+ else if ((ch & SupplimentarySeq) != 0)
+ {
+ // 3rd byte of 4 byte sequence?
+ if ((ch & (FinalByte >> 6)) != 0)
+ {
+ // 3rd byte of 4 byte sequence
+ pSrc -= 3;
+ bytesUnknown = new byte[] {
+ unchecked((byte)(((ch >> 12) & 0x07) | 0xF0)),
+ unchecked((byte)(((ch >> 6) & 0x3F) | 0x80)),
+ unchecked((byte)(((ch) & 0x3F) | 0x80)) };
+ }
+ else if ((ch & (FinalByte >> 12)) != 0)
+ {
+ // 2nd byte of a 4 byte sequence
+ pSrc -= 2;
+ bytesUnknown = new byte[] {
+ unchecked((byte)(((ch >> 6) & 0x07) | 0xF0)),
+ unchecked((byte)(((ch) & 0x3F) | 0x80)) };
+ }
+ else
+ {
+ // 4th byte of a 4 byte sequence
+ pSrc--;
+ bytesUnknown = new byte[] { unchecked((byte)(((ch) & 0x07) | 0xF0)) };
+ }
+ }
+ else
+ {
+ // 2nd byte of 3 byte sequence?
+ if ((ch & (FinalByte >> 6)) != 0)
+ {
+ // So its 2nd byte of a 3 byte sequence
+ pSrc -= 2;
+ bytesUnknown = new byte[] {
+ unchecked((byte)(((ch >> 6) & 0x0F) | 0xE0)), unchecked ((byte)(((ch) & 0x3F) | 0x80)) };
+ }
+ else
+ {
+ // 1st byte of a 3 byte sequence
+ pSrc--;
+ bytesUnknown = new byte[] { unchecked((byte)(((ch) & 0x0F) | 0xE0)) };
+ }
+ }
+
+ return bytesUnknown;
+ }
+
+
+ public override Decoder GetDecoder()
+ {
+ return new UTF8Decoder(this);
+ }
+
+
+ public override Encoder GetEncoder()
+ {
+ return new UTF8Encoder(this);
+ }
+
+
+ public override int GetMaxByteCount(int charCount)
+ {
+ if (charCount < 0)
+ throw new ArgumentOutOfRangeException(nameof(charCount),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Characters would be # of characters + 1 in case left over high surrogate is ? * max fallback
+ long byteCount = (long)charCount + 1;
+
+ if (EncoderFallback.MaxCharCount > 1)
+ byteCount *= EncoderFallback.MaxCharCount;
+
+ // Max 3 bytes per char. (4 bytes per 2 chars for surrogates)
+ byteCount *= 3;
+
+ if (byteCount > 0x7fffffff)
+ throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_GetByteCountOverflow);
+
+ return (int)byteCount;
+ }
+
+
+ public override int GetMaxCharCount(int byteCount)
+ {
+ if (byteCount < 0)
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Figure out our length, 1 char per input byte + 1 char if 1st byte is last byte of 4 byte surrogate pair
+ long charCount = ((long)byteCount + 1);
+
+ // Non-shortest form would fall back, so get max count from fallback.
+ // So would 11... followed by 11..., so you could fall back every byte
+ if (DecoderFallback.MaxCharCount > 1)
+ {
+ charCount *= DecoderFallback.MaxCharCount;
+ }
+
+ if (charCount > 0x7fffffff)
+ throw new ArgumentOutOfRangeException(nameof(byteCount), SR.ArgumentOutOfRange_GetCharCountOverflow);
+
+ return (int)charCount;
+ }
+
+
+ public override byte[] GetPreamble()
+ {
+ if (_emitUTF8Identifier)
+ {
+ // Allocate new array to prevent users from modifying it.
+ return new byte[3] { 0xEF, 0xBB, 0xBF };
+ }
+ else
+ return Array.Empty<byte>();
+ }
+
+
+ public override bool Equals(Object value)
+ {
+ UTF8Encoding that = value as UTF8Encoding;
+ if (that != null)
+ {
+ return (_emitUTF8Identifier == that._emitUTF8Identifier) &&
+ (EncoderFallback.Equals(that.EncoderFallback)) &&
+ (DecoderFallback.Equals(that.DecoderFallback));
+ }
+ return (false);
+ }
+
+
+ public override int GetHashCode()
+ {
+ //Not great distribution, but this is relatively unlikely to be used as the key in a hashtable.
+ return this.EncoderFallback.GetHashCode() + this.DecoderFallback.GetHashCode() +
+ UTF8_CODEPAGE + (_emitUTF8Identifier ? 1 : 0);
+ }
+
+ [Serializable]
+ private sealed class UTF8Encoder : EncoderNLS, ISerializable
+ {
+ // We must save a high surrogate value until the next call, looking
+ // for a low surrogate value.
+ internal int surrogateChar;
+
+ public UTF8Encoder(UTF8Encoding encoding) : base(encoding)
+ {
+ // base calls reset
+ }
+
+ // Constructor called by serialization, have to handle deserializing from Everett
+ internal UTF8Encoder(SerializationInfo info, StreamingContext context)
+ {
+ // Any info?
+ if (info == null) throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ // Get common info
+ this.m_encoding = (Encoding)info.GetValue("encoding", typeof(Encoding));
+
+ // SurrogateChar happens to mean the same thing
+ this.surrogateChar = (int)info.GetValue("surrogateChar", typeof(int));
+
+ try
+ {
+ this.m_fallback = (EncoderFallback)info.GetValue("m_fallback", typeof(EncoderFallback));
+ }
+ catch (SerializationException)
+ {
+ this.m_fallback = null;
+ }
+ }
+
+ // ISerializable implementation, get data for this object
+ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ // Any info?
+ if (info == null) throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ // Save Whidbey data
+ // Just need Everett maxCharSize (BaseCodePageEncoding) or m_maxByteSize (MLangBaseCodePageEncoding)
+ info.AddValue("encoding", this.m_encoding);
+ info.AddValue("surrogateChar", this.surrogateChar);
+
+ info.AddValue("m_fallback", this.m_fallback);
+
+ // Extra stuff for Everett that Whidbey doesn't use
+ info.AddValue("storedSurrogate", this.surrogateChar > 0 ? true : false);
+ info.AddValue("mustFlush", false); // Everett doesn't actually use this either, but it accidently serialized it!
+ }
+
+ public override void Reset()
+
+ {
+ this.surrogateChar = 0;
+ if (m_fallbackBuffer != null)
+ m_fallbackBuffer.Reset();
+ }
+
+ // Anything left in our encoder?
+ internal override bool HasState
+ {
+ get
+ {
+ return (this.surrogateChar != 0);
+ }
+ }
+ }
+
+ [Serializable]
+ private sealed class UTF8Decoder : DecoderNLS, ISerializable
+ {
+ // We'll need to remember the previous information. See the comments around definition
+ // of FinalByte for details.
+ internal int bits;
+
+ public UTF8Decoder(UTF8Encoding encoding) : base(encoding)
+ {
+ // base calls reset
+ }
+
+ // Constructor called by serialization, have to handle deserializing from Everett
+ internal UTF8Decoder(SerializationInfo info, StreamingContext context)
+ {
+ // Any info?
+ if (info == null) throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ // Get common info
+ this.m_encoding = (Encoding)info.GetValue("encoding", typeof(Encoding));
+
+ try
+ {
+ // Get whidbey version of bits
+ this.bits = (int)info.GetValue("wbits", typeof(int));
+ this.m_fallback = (DecoderFallback)info.GetValue("m_fallback", typeof(DecoderFallback));
+ }
+ catch (SerializationException)
+ {
+ // Everett calls bits bits instead of wbits, so this is Everett
+ this.bits = 0;
+ this.m_fallback = null;
+ }
+ }
+
+ // ISerializable implementation, get data for this object
+ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ // Any info?
+ if (info == null) throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ // Save new Whidbey data
+ info.AddValue("encoding", this.m_encoding);
+ info.AddValue("wbits", this.bits); // Special whidbey bits name
+ info.AddValue("m_fallback", this.m_fallback);
+
+ // Everett has extra stuff, we set it all to 0 in case this deserializes in Everett
+ info.AddValue("bits", (int)0);
+ info.AddValue("trailCount", (int)0);
+ info.AddValue("isSurrogate", false);
+ info.AddValue("byteSequence", (int)0);
+ }
+
+ public override void Reset()
+ {
+ this.bits = 0;
+ if (m_fallbackBuffer != null)
+ m_fallbackBuffer.Reset();
+ }
+
+ // Anything left in our decoder?
+ internal override bool HasState
+ {
+ get
+ {
+ return (this.bits != 0);
+ }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Text/UnicodeEncoding.cs b/src/mscorlib/shared/System/Text/UnicodeEncoding.cs
new file mode 100644
index 0000000000..0e4db9aaad
--- /dev/null
+++ b/src/mscorlib/shared/System/Text/UnicodeEncoding.cs
@@ -0,0 +1,2058 @@
+// 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.
+
+//
+// Don't override IsAlwaysNormalized because it is just a Unicode Transformation and could be confused.
+//
+
+using System;
+using System.Globalization;
+using System.Runtime.Serialization;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System.Text
+{
+ [Serializable]
+ public class UnicodeEncoding : Encoding
+ {
+ // Used by Encoding.BigEndianUnicode/Unicode for lazy initialization
+ // The initialization code will not be run until a static member of the class is referenced
+ internal static readonly UnicodeEncoding s_bigEndianDefault = new UnicodeEncoding(bigEndian: true, byteOrderMark: true);
+ internal static readonly UnicodeEncoding s_littleEndianDefault = new UnicodeEncoding(bigEndian: false, byteOrderMark: true);
+
+ [OptionalField(VersionAdded = 2)]
+ internal bool isThrowException = false;
+
+ internal bool bigEndian = false;
+ internal bool byteOrderMark = true;
+
+ // Unicode version 2.0 character size in bytes
+ public const int CharSize = 2;
+
+
+ public UnicodeEncoding()
+ : this(false, true)
+ {
+ }
+
+
+ public UnicodeEncoding(bool bigEndian, bool byteOrderMark)
+ : this(bigEndian, byteOrderMark, false)
+ {
+ }
+
+
+ public UnicodeEncoding(bool bigEndian, bool byteOrderMark, bool throwOnInvalidBytes)
+ : base(bigEndian ? 1201 : 1200) //Set the data item.
+ {
+ this.isThrowException = throwOnInvalidBytes;
+ this.bigEndian = bigEndian;
+ this.byteOrderMark = byteOrderMark;
+
+ // Encoding constructor already did this, but it'll be wrong if we're throwing exceptions
+ if (this.isThrowException)
+ SetDefaultFallbacks();
+ }
+
+ #region Serialization
+ [OnDeserializing]
+ private void OnDeserializing(StreamingContext ctx)
+ {
+ // In Everett it is false. Whidbey will overwrite this value.
+ isThrowException = false;
+ }
+ #endregion Serialization
+
+ internal override void SetDefaultFallbacks()
+ {
+ // For UTF-X encodings, we use a replacement fallback with an empty string
+ if (this.isThrowException)
+ {
+ this.encoderFallback = EncoderFallback.ExceptionFallback;
+ this.decoderFallback = DecoderFallback.ExceptionFallback;
+ }
+ else
+ {
+ this.encoderFallback = new EncoderReplacementFallback("\xFFFD");
+ this.decoderFallback = new DecoderReplacementFallback("\xFFFD");
+ }
+ }
+
+ // The following methods are copied from EncodingNLS.cs.
+ // Unfortunately EncodingNLS.cs is internal and we're public, so we have to reimpliment them here.
+ // These should be kept in sync for the following classes:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ //
+
+ // Returns the number of bytes required to encode a range of characters in
+ // a character array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetByteCount(char[] chars, int index, int count)
+ {
+ // Validate input parameters
+ if (chars == null)
+ throw new ArgumentNullException("chars", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (chars.Length - index < count)
+ throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // If no input, return 0, avoid fixed empty array problem
+ if (count == 0)
+ return 0;
+
+ // Just call the pointer version
+ fixed (char* pChars = chars)
+ return GetByteCount(pChars + index, count, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetByteCount(String s)
+ {
+ // Validate input
+ if (s==null)
+ throw new ArgumentNullException("s");
+ Contract.EndContractBlock();
+
+ fixed (char* pChars = s)
+ return GetByteCount(pChars, s.Length, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public override unsafe int GetByteCount(char* chars, int count)
+ {
+ // Validate Parameters
+ if (chars == null)
+ throw new ArgumentNullException("chars", SR.ArgumentNull_Array);
+
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Call it with empty encoder
+ return GetByteCount(chars, count, null);
+ }
+
+ // Parent method is safe.
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ public override unsafe int GetBytes(String s, int charIndex, int charCount,
+ byte[] bytes, int byteIndex)
+ {
+ if (s == null || bytes == null)
+ throw new ArgumentNullException((s == null ? "s" : "bytes"), SR.ArgumentNull_Array);
+
+ if (charIndex < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? "charIndex" : "charCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (s.Length - charIndex < charCount)
+ throw new ArgumentOutOfRangeException("s", SR.ArgumentOutOfRange_IndexCount);
+
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ int byteCount = bytes.Length - byteIndex;
+
+ // Fixed doesn't like 0 length arrays.
+ if (bytes.Length == 0)
+ bytes = new byte[1];
+
+ fixed (char* pChars = s) fixed (byte* pBytes = &bytes[0])
+ return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
+ }
+
+ // Encodes a range of characters in a character array into a range of bytes
+ // in a byte array. An exception occurs if the byte array is not large
+ // enough to hold the complete encoding of the characters. The
+ // GetByteCount method can be used to determine the exact number of
+ // bytes that will be produced for a given range of characters.
+ // Alternatively, the GetMaxByteCount method can be used to
+ // determine the maximum number of bytes that will be produced for a given
+ // number of characters, regardless of the actual character values.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetBytes(char[] chars, int charIndex, int charCount,
+ byte[] bytes, int byteIndex)
+ {
+ // Validate parameters
+ if (chars == null || bytes == null)
+ throw new ArgumentNullException((chars == null ? "chars" : "bytes"), SR.ArgumentNull_Array);
+
+ if (charIndex < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? "charIndex" : "charCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (chars.Length - charIndex < charCount)
+ throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer);
+
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ // If nothing to encode return 0, avoid fixed problem
+ if (charCount == 0)
+ return 0;
+
+ // Just call pointer version
+ int byteCount = bytes.Length - byteIndex;
+
+ // Fixed doesn't like 0 length arrays.
+ if (bytes.Length == 0)
+ bytes = new byte[1];
+
+ fixed (char* pChars = chars) fixed (byte* pBytes = &bytes[0])
+ // Remember that byteCount is # to decode, not size of array.
+ return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
+ {
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (charCount < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetBytes(chars, charCount, bytes, byteCount, null);
+ }
+
+ // Returns the number of characters produced by decoding a range of bytes
+ // in a byte array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetCharCount(byte[] bytes, int index, int count)
+ {
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (bytes.Length - index < count)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // If no input just return 0, fixed doesn't like 0 length arrays
+ if (count == 0)
+ return 0;
+
+ // Just call pointer version
+ fixed (byte* pBytes = bytes)
+ return GetCharCount(pBytes + index, count, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public override unsafe int GetCharCount(byte* bytes, int count)
+ {
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetCharCount(bytes, count, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ char[] chars, int charIndex)
+ {
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (byteIndex < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((byteIndex < 0 ? "byteIndex" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if ( bytes.Length - byteIndex < byteCount)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+
+ if (charIndex < 0 || charIndex > chars.Length)
+ throw new ArgumentOutOfRangeException("charIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ // If no input, return 0 & avoid fixed problem
+ if (byteCount == 0)
+ return 0;
+
+ // Just call pointer version
+ int charCount = chars.Length - charIndex;
+
+ // Fixed doesn't like 0 length arrays.
+ if (chars.Length == 0)
+ chars = new char[1];
+
+ fixed (byte* pBytes = bytes) fixed (char* pChars = &chars[0])
+ // Remember that charCount is # to decode, not size of array
+ return GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, null);
+ }
+
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ [CLSCompliant(false)]
+ public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
+ {
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (charCount < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetChars(bytes, byteCount, chars, charCount, null);
+ }
+
+ // Returns a string containing the decoded representation of a range of
+ // bytes in a byte array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe string GetString(byte[] bytes, int index, int count)
+ {
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (bytes.Length - index < count)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // Avoid problems with empty input buffer
+ if (count == 0) return String.Empty;
+
+ fixed (byte* pBytes = bytes)
+ return String.CreateStringFromEncoding(
+ pBytes + index, count, this);
+ }
+
+ //
+ // End of standard methods copied from EncodingNLS.cs
+ //
+
+ internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS encoder)
+ {
+ Debug.Assert(chars != null, "[UnicodeEncoding.GetByteCount]chars!=null");
+ Debug.Assert(count >= 0, "[UnicodeEncoding.GetByteCount]count >=0");
+
+ // Start by assuming each char gets 2 bytes
+ int byteCount = count << 1;
+
+ // Check for overflow in byteCount
+ // (If they were all invalid chars, this would actually be wrong,
+ // but that's a ridiculously large # so we're not concerned about that case)
+ if (byteCount < 0)
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_GetByteCountOverflow);
+
+ char* charStart = chars;
+ char* charEnd = chars + count;
+ char charLeftOver = (char)0;
+
+ bool wasHereBefore = false;
+
+ // Need -1 to check 2 at a time. If we have an even #, longChars will go
+ // from longEnd - 1/2 long to longEnd + 1/2 long. If we're odd, longChars
+ // will go from longEnd - 1 long to longEnd. (Might not get to use this)
+ ulong* longEnd = (ulong*)(charEnd - 3);
+
+ // For fallback we may need a fallback buffer
+ EncoderFallbackBuffer fallbackBuffer = null;
+ char* charsForFallback;
+
+ if (encoder != null)
+ {
+ charLeftOver = encoder.charLeftOver;
+
+ // Assume extra bytes to encode charLeftOver if it existed
+ if (charLeftOver > 0)
+ byteCount += 2;
+
+ // We mustn't have left over fallback data when counting
+ if (encoder.InternalHasFallbackBuffer)
+ {
+ fallbackBuffer = encoder.FallbackBuffer;
+ if (fallbackBuffer.Remaining > 0)
+ throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, false);
+ }
+ }
+
+ char ch;
+ TryAgain:
+
+ while (((ch = (fallbackBuffer == null) ? (char)0 : fallbackBuffer.InternalGetNextChar()) != 0) || chars < charEnd)
+ {
+ // First unwind any fallback
+ if (ch == 0)
+ {
+ // No fallback, maybe we can do it fast
+#if !NO_FAST_UNICODE_LOOP
+#if BIGENDIAN // If endianess is backwards then each pair of bytes would be backwards.
+ if ( bigEndian &&
+#else
+ if (!bigEndian &&
+#endif // BIGENDIAN
+
+#if BIT64 // 64 bit CPU needs to be long aligned for this to work.
+ charLeftOver == 0 && (unchecked((long)chars) & 7) == 0)
+#else
+ charLeftOver == 0 && (unchecked((int)chars) & 3) == 0)
+#endif
+ {
+ // Need new char* so we can check 4 at a time
+ ulong* longChars = (ulong*)chars;
+
+ while (longChars < longEnd)
+ {
+ // See if we potentially have surrogates (0x8000 bit set)
+ // (We're either big endian on a big endian machine or little endian on
+ // a little endian machine so this'll work)
+ if ((0x8000800080008000 & *longChars) != 0)
+ {
+ // See if any of these are high or low surrogates (0xd800 - 0xdfff). If the high
+ // 5 bits looks like 11011, then its a high or low surrogate.
+ // We do the & f800 to filter the 5 bits, then ^ d800 to ensure the 0 isn't set.
+ // Note that we expect BMP characters to be more common than surrogates
+ // & each char with 11111... then ^ with 11011. Zeroes then indicate surrogates
+ ulong uTemp = (0xf800f800f800f800 & *longChars) ^ 0xd800d800d800d800;
+
+ // Check each of the 4 chars. 0 for those 16 bits means it was a surrogate
+ // but no clue if they're high or low.
+ // If each of the 4 characters are non-zero, then none are surrogates.
+ if ((uTemp & 0xFFFF000000000000) == 0 ||
+ (uTemp & 0x0000FFFF00000000) == 0 ||
+ (uTemp & 0x00000000FFFF0000) == 0 ||
+ (uTemp & 0x000000000000FFFF) == 0)
+ {
+ // It has at least 1 surrogate, but we don't know if they're high or low surrogates,
+ // or if there's 1 or 4 surrogates
+
+ // If they happen to be high/low/high/low, we may as well continue. Check the next
+ // bit to see if its set (low) or not (high) in the right pattern
+#if BIGENDIAN
+ if (((0xfc00fc00fc00fc00 & *longChars) ^ 0xd800dc00d800dc00) != 0)
+#else
+ if (((0xfc00fc00fc00fc00 & *longChars) ^ 0xdc00d800dc00d800) != 0)
+#endif
+ {
+ // Either there weren't 4 surrogates, or the 0x0400 bit was set when a high
+ // was hoped for or the 0x0400 bit wasn't set where a low was hoped for.
+
+ // Drop out to the slow loop to resolve the surrogates
+ break;
+ }
+ // else they are all surrogates in High/Low/High/Low order, so we can use them.
+ }
+ // else none are surrogates, so we can use them.
+ }
+ // else all < 0x8000 so we can use them
+
+ // We already counted these four chars, go to next long.
+ longChars++;
+ }
+
+ chars = (char*)longChars;
+
+ if (chars >= charEnd)
+ break;
+ }
+#endif // !NO_FAST_UNICODE_LOOP
+
+ // No fallback, just get next char
+ ch = *chars;
+ chars++;
+ }
+ else
+ {
+ // We weren't preallocating fallback space.
+ byteCount += 2;
+ }
+
+ // Check for high or low surrogates
+ if (ch >= 0xd800 && ch <= 0xdfff)
+ {
+ // Was it a high surrogate?
+ if (ch <= 0xdbff)
+ {
+ // Its a high surrogate, if we already had a high surrogate do its fallback
+ if (charLeftOver > 0)
+ {
+ // Unwind the current character, this should be safe because we
+ // don't have leftover data in the fallback, so chars must have
+ // advanced already.
+ Debug.Assert(chars > charStart,
+ "[UnicodeEncoding.GetByteCount]Expected chars to have advanced in unexpected high surrogate");
+ chars--;
+
+ // If previous high surrogate deallocate 2 bytes
+ byteCount -= 2;
+
+ // Fallback the previous surrogate
+ // Need to initialize fallback buffer?
+ if (fallbackBuffer == null)
+ {
+ if (encoder == null)
+ fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = encoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, false);
+ }
+
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ fallbackBuffer.InternalFallback(charLeftOver, ref charsForFallback);
+ chars = charsForFallback;
+
+ // Now no high surrogate left over
+ charLeftOver = (char)0;
+ continue;
+ }
+
+ // Remember this high surrogate
+ charLeftOver = ch;
+ continue;
+ }
+
+
+ // Its a low surrogate
+ if (charLeftOver == 0)
+ {
+ // Expected a previous high surrogate.
+ // Don't count this one (we'll count its fallback if necessary)
+ byteCount -= 2;
+
+ // fallback this one
+ // Need to initialize fallback buffer?
+ if (fallbackBuffer == null)
+ {
+ if (encoder == null)
+ fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = encoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, false);
+ }
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ fallbackBuffer.InternalFallback(ch, ref charsForFallback);
+ chars = charsForFallback;
+ continue;
+ }
+
+ // Valid surrogate pair, add our charLeftOver
+ charLeftOver = (char)0;
+ continue;
+ }
+ else if (charLeftOver > 0)
+ {
+ // Expected a low surrogate, but this char is normal
+
+ // Rewind the current character, fallback previous character.
+ // this should be safe because we don't have leftover data in the
+ // fallback, so chars must have advanced already.
+ Debug.Assert(chars > charStart,
+ "[UnicodeEncoding.GetByteCount]Expected chars to have advanced when expected low surrogate");
+ chars--;
+
+ // fallback previous chars
+ // Need to initialize fallback buffer?
+ if (fallbackBuffer == null)
+ {
+ if (encoder == null)
+ fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = encoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, false);
+ }
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ fallbackBuffer.InternalFallback(charLeftOver, ref charsForFallback);
+ chars = charsForFallback;
+
+ // Ignore charLeftOver or throw
+ byteCount -= 2;
+ charLeftOver = (char)0;
+
+ continue;
+ }
+
+ // Ok we had something to add (already counted)
+ }
+
+ // Don't allocate space for left over char
+ if (charLeftOver > 0)
+ {
+ byteCount -= 2;
+
+ // If we have to flush, stick it in fallback and try again
+ if (encoder == null || encoder.MustFlush)
+ {
+ if (wasHereBefore)
+ {
+ // Throw it, using our complete character
+ throw new ArgumentException(
+ SR.Format(SR.Argument_RecursiveFallback, charLeftOver), nameof(chars));
+ }
+ else
+ {
+ // Need to initialize fallback buffer?
+ if (fallbackBuffer == null)
+ {
+ if (encoder == null)
+ fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = encoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, false);
+ }
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ fallbackBuffer.InternalFallback(charLeftOver, ref charsForFallback);
+ chars = charsForFallback;
+ charLeftOver = (char)0;
+ wasHereBefore = true;
+ goto TryAgain;
+ }
+ }
+ }
+
+ // Shouldn't have anything in fallback buffer for GetByteCount
+ // (don't have to check m_throwOnOverflow for count)
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ "[UnicodeEncoding.GetByteCount]Expected empty fallback buffer at end");
+
+ // Don't remember fallbackBuffer.encoder for counting
+ return byteCount;
+ }
+
+ internal override unsafe int GetBytes(char* chars, int charCount,
+ byte* bytes, int byteCount, EncoderNLS encoder)
+ {
+ Debug.Assert(chars != null, "[UnicodeEncoding.GetBytes]chars!=null");
+ Debug.Assert(byteCount >= 0, "[UnicodeEncoding.GetBytes]byteCount >=0");
+ Debug.Assert(charCount >= 0, "[UnicodeEncoding.GetBytes]charCount >=0");
+ Debug.Assert(bytes != null, "[UnicodeEncoding.GetBytes]bytes!=null");
+
+ char charLeftOver = (char)0;
+ char ch;
+ bool wasHereBefore = false;
+
+
+ byte* byteEnd = bytes + byteCount;
+ char* charEnd = chars + charCount;
+ byte* byteStart = bytes;
+ char* charStart = chars;
+
+ // For fallback we may need a fallback buffer
+ EncoderFallbackBuffer fallbackBuffer = null;
+ char* charsForFallback;
+
+ // Get our encoder, but don't clear it yet.
+ if (encoder != null)
+ {
+ charLeftOver = encoder.charLeftOver;
+
+ // We mustn't have left over fallback data when counting
+ if (encoder.InternalHasFallbackBuffer)
+ {
+ // We always need the fallback buffer in get bytes so we can flush any remaining ones if necessary
+ fallbackBuffer = encoder.FallbackBuffer;
+ if (fallbackBuffer.Remaining > 0 && encoder.m_throwOnOverflow)
+ throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, false);
+ }
+ }
+
+ TryAgain:
+ while (((ch = (fallbackBuffer == null) ?
+ (char)0 : fallbackBuffer.InternalGetNextChar()) != 0) ||
+ chars < charEnd)
+ {
+ // First unwind any fallback
+ if (ch == 0)
+ {
+ // No fallback, maybe we can do it fast
+#if !NO_FAST_UNICODE_LOOP
+#if BIGENDIAN // If endianess is backwards then each pair of bytes would be backwards.
+ if ( bigEndian &&
+#else
+ if (!bigEndian &&
+#endif // BIGENDIAN
+#if BIT64 // 64 bit CPU needs to be long aligned for this to work, 32 bit CPU needs to be 32 bit aligned
+ (unchecked((long)chars) & 7) == 0 && (unchecked((long)bytes) & 7) == 0 &&
+#else
+ (unchecked((int)chars) & 3) == 0 && (unchecked((int)bytes) & 3) == 0 &&
+#endif // BIT64
+ charLeftOver == 0)
+ {
+ // Need -1 to check 2 at a time. If we have an even #, longChars will go
+ // from longEnd - 1/2 long to longEnd + 1/2 long. If we're odd, longChars
+ // will go from longEnd - 1 long to longEnd. (Might not get to use this)
+ // We can only go iCount units (limited by shorter of char or byte buffers.
+ ulong* longEnd = (ulong*)(chars - 3 +
+ (((byteEnd - bytes) >> 1 < charEnd - chars) ?
+ (byteEnd - bytes) >> 1 : charEnd - chars));
+
+ // Need new char* so we can check 4 at a time
+ ulong* longChars = (ulong*)chars;
+ ulong* longBytes = (ulong*)bytes;
+
+ while (longChars < longEnd)
+ {
+ // See if we potentially have surrogates (0x8000 bit set)
+ // (We're either big endian on a big endian machine or little endian on
+ // a little endian machine so this'll work)
+ if ((0x8000800080008000 & *longChars) != 0)
+ {
+ // See if any of these are high or low surrogates (0xd800 - 0xdfff). If the high
+ // 5 bits looks like 11011, then its a high or low surrogate.
+ // We do the & f800 to filter the 5 bits, then ^ d800 to ensure the 0 isn't set.
+ // Note that we expect BMP characters to be more common than surrogates
+ // & each char with 11111... then ^ with 11011. Zeroes then indicate surrogates
+ ulong uTemp = (0xf800f800f800f800 & *longChars) ^ 0xd800d800d800d800;
+
+ // Check each of the 4 chars. 0 for those 16 bits means it was a surrogate
+ // but no clue if they're high or low.
+ // If each of the 4 characters are non-zero, then none are surrogates.
+ if ((uTemp & 0xFFFF000000000000) == 0 ||
+ (uTemp & 0x0000FFFF00000000) == 0 ||
+ (uTemp & 0x00000000FFFF0000) == 0 ||
+ (uTemp & 0x000000000000FFFF) == 0)
+ {
+ // It has at least 1 surrogate, but we don't know if they're high or low surrogates,
+ // or if there's 1 or 4 surrogates
+
+ // If they happen to be high/low/high/low, we may as well continue. Check the next
+ // bit to see if its set (low) or not (high) in the right pattern
+#if BIGENDIAN
+ if (((0xfc00fc00fc00fc00 & *longChars) ^ 0xd800dc00d800dc00) != 0)
+#else
+ if (((0xfc00fc00fc00fc00 & *longChars) ^ 0xdc00d800dc00d800) != 0)
+#endif
+ {
+ // Either there weren't 4 surrogates, or the 0x0400 bit was set when a high
+ // was hoped for or the 0x0400 bit wasn't set where a low was hoped for.
+
+ // Drop out to the slow loop to resolve the surrogates
+ break;
+ }
+ // else they are all surrogates in High/Low/High/Low order, so we can use them.
+ }
+ // else none are surrogates, so we can use them.
+ }
+ // else all < 0x8000 so we can use them
+
+ // We can use these 4 chars.
+ *longBytes = *longChars;
+ longChars++;
+ longBytes++;
+ }
+
+ chars = (char*)longChars;
+ bytes = (byte*)longBytes;
+
+ if (chars >= charEnd)
+ break;
+ }
+ // Not aligned, but maybe we can still be somewhat faster
+ // Also somehow this optimizes the above loop? It seems to cause something above
+ // to get enregistered, but I haven't figured out how to make that happen without this loop.
+ else if ((charLeftOver == 0) &&
+#if BIGENDIAN
+ bigEndian &&
+#else
+ !bigEndian &&
+#endif // BIGENDIAN
+
+#if BIT64
+ (unchecked((long)chars) & 7) != (unchecked((long)bytes) & 7) && // Only do this if chars & bytes are out of line, otherwise faster loop'll be faster next time
+#else
+ (unchecked((int)chars) & 3) != (unchecked((int)bytes) & 3) && // Only do this if chars & bytes are out of line, otherwise faster loop'll be faster next time
+#endif // BIT64
+ (unchecked((int)(bytes)) & 1) == 0)
+ {
+ // # to use
+ long iCount = ((byteEnd - bytes) >> 1 < charEnd - chars) ?
+ (byteEnd - bytes) >> 1 : charEnd - chars;
+
+ // Need new char*
+ char* charOut = ((char*)bytes); // a char* for our output
+ char* tempEnd = chars + iCount - 1; // Our end pointer
+
+ while (chars < tempEnd)
+ {
+ if (*chars >= (char)0xd800 && *chars <= (char)0xdfff)
+ {
+ // break for fallback for low surrogate
+ if (*chars >= 0xdc00)
+ break;
+
+ // break if next one's not a low surrogate (will do fallback)
+ if (*(chars + 1) < 0xdc00 || *(chars + 1) > 0xdfff)
+ break;
+
+ // They both exist, use them
+ }
+ // If 2nd char is surrogate & this one isn't then only add one
+ else if (*(chars + 1) >= (char)0xd800 && *(chars + 1) <= 0xdfff)
+ {
+ *charOut = *chars;
+ charOut++;
+ chars++;
+ continue;
+ }
+
+ *charOut = *chars;
+ *(charOut + 1) = *(chars + 1);
+ charOut += 2;
+ chars += 2;
+ }
+
+ bytes = (byte*)charOut;
+
+ if (chars >= charEnd)
+ break;
+ }
+#endif // !NO_FAST_UNICODE_LOOP
+
+ // No fallback, just get next char
+ ch = *chars;
+ chars++;
+ }
+
+ // Check for high or low surrogates
+ if (ch >= 0xd800 && ch <= 0xdfff)
+ {
+ // Was it a high surrogate?
+ if (ch <= 0xdbff)
+ {
+ // Its a high surrogate, see if we already had a high surrogate
+ if (charLeftOver > 0)
+ {
+ // Unwind the current character, this should be safe because we
+ // don't have leftover data in the fallback, so chars must have
+ // advanced already.
+ Debug.Assert(chars > charStart,
+ "[UnicodeEncoding.GetBytes]Expected chars to have advanced in unexpected high surrogate");
+ chars--;
+
+ // Fallback the previous surrogate
+ // Might need to create our fallback buffer
+ if (fallbackBuffer == null)
+ {
+ if (encoder == null)
+ fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = encoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, true);
+ }
+
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ fallbackBuffer.InternalFallback(charLeftOver, ref charsForFallback);
+ chars = charsForFallback;
+
+ charLeftOver = (char)0;
+ continue;
+ }
+
+ // Remember this high surrogate
+ charLeftOver = ch;
+ continue;
+ }
+
+ // Its a low surrogate
+ if (charLeftOver == 0)
+ {
+ // We'll fall back this one
+ // Might need to create our fallback buffer
+ if (fallbackBuffer == null)
+ {
+ if (encoder == null)
+ fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = encoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, true);
+ }
+
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ fallbackBuffer.InternalFallback(ch, ref charsForFallback);
+ chars = charsForFallback;
+ continue;
+ }
+
+ // Valid surrogate pair, add our charLeftOver
+ if (bytes + 3 >= byteEnd)
+ {
+ // Not enough room to add this surrogate pair
+ if (fallbackBuffer != null && fallbackBuffer.bFallingBack)
+ {
+ // These must have both been from the fallbacks.
+ // Both of these MUST have been from a fallback because if the 1st wasn't
+ // from a fallback, then a high surrogate followed by an illegal char
+ // would've caused the high surrogate to fall back. If a high surrogate
+ // fell back, then it was consumed and both chars came from the fallback.
+ fallbackBuffer.MovePrevious(); // Didn't use either fallback surrogate
+ fallbackBuffer.MovePrevious();
+ }
+ else
+ {
+ // If we don't have enough room, then either we should've advanced a while
+ // or we should have bytes==byteStart and throw below
+ Debug.Assert(chars > charStart + 1 || bytes == byteStart,
+ "[UnicodeEncoding.GetBytes]Expected chars to have when no room to add surrogate pair");
+ chars -= 2; // Didn't use either surrogate
+ }
+ ThrowBytesOverflow(encoder, bytes == byteStart); // Throw maybe (if no bytes written)
+ charLeftOver = (char)0; // we'll retry it later
+ break; // Didn't throw, but stop 'til next time.
+ }
+
+ if (bigEndian)
+ {
+ *(bytes++) = (byte)(charLeftOver >> 8);
+ *(bytes++) = (byte)charLeftOver;
+ }
+ else
+ {
+ *(bytes++) = (byte)charLeftOver;
+ *(bytes++) = (byte)(charLeftOver >> 8);
+ }
+
+ charLeftOver = (char)0;
+ }
+ else if (charLeftOver > 0)
+ {
+ // Expected a low surrogate, but this char is normal
+
+ // Rewind the current character, fallback previous character.
+ // this should be safe because we don't have leftover data in the
+ // fallback, so chars must have advanced already.
+ Debug.Assert(chars > charStart,
+ "[UnicodeEncoding.GetBytes]Expected chars to have advanced after expecting low surrogate");
+ chars--;
+
+ // fallback previous chars
+ // Might need to create our fallback buffer
+ if (fallbackBuffer == null)
+ {
+ if (encoder == null)
+ fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = encoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, true);
+ }
+
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ fallbackBuffer.InternalFallback(charLeftOver, ref charsForFallback);
+ chars = charsForFallback;
+
+ // Ignore charLeftOver or throw
+ charLeftOver = (char)0;
+ continue;
+ }
+
+ // Ok, we have a char to add
+ if (bytes + 1 >= byteEnd)
+ {
+ // Couldn't add this char
+ if (fallbackBuffer != null && fallbackBuffer.bFallingBack)
+ fallbackBuffer.MovePrevious(); // Not using this fallback char
+ else
+ {
+ // Lonely charLeftOver (from previous call) would've been caught up above,
+ // so this must be a case where we've already read an input char.
+ Debug.Assert(chars > charStart,
+ "[UnicodeEncoding.GetBytes]Expected chars to have advanced for failed fallback");
+ chars--; // Not using this char
+ }
+ ThrowBytesOverflow(encoder, bytes == byteStart); // Throw maybe (if no bytes written)
+ break; // didn't throw, just stop
+ }
+
+ if (bigEndian)
+ {
+ *(bytes++) = (byte)(ch >> 8);
+ *(bytes++) = (byte)ch;
+ }
+ else
+ {
+ *(bytes++) = (byte)ch;
+ *(bytes++) = (byte)(ch >> 8);
+ }
+ }
+
+ // Don't allocate space for left over char
+ if (charLeftOver > 0)
+ {
+ // If we aren't flushing we need to fall this back
+ if (encoder == null || encoder.MustFlush)
+ {
+ if (wasHereBefore)
+ {
+ // Throw it, using our complete character
+ throw new ArgumentException(
+ SR.Format(SR.Argument_RecursiveFallback, charLeftOver), nameof(chars));
+ }
+ else
+ {
+ // If we have to flush, stick it in fallback and try again
+ // Might need to create our fallback buffer
+ if (fallbackBuffer == null)
+ {
+ if (encoder == null)
+ fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = encoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, true);
+ }
+
+ // If we're not flushing, this'll remember the left over character.
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ fallbackBuffer.InternalFallback(charLeftOver, ref charsForFallback);
+ chars = charsForFallback;
+
+ charLeftOver = (char)0;
+ wasHereBefore = true;
+ goto TryAgain;
+ }
+ }
+ }
+
+ // Not flushing, remember it in the encoder
+ if (encoder != null)
+ {
+ encoder.charLeftOver = charLeftOver;
+ encoder.m_charsUsed = (int)(chars - charStart);
+ }
+
+ // Remember charLeftOver if we must, or clear it if we're flushing
+ // (charLeftOver should be 0 if we're flushing)
+ Debug.Assert((encoder != null && !encoder.MustFlush) || charLeftOver == (char)0,
+ "[UnicodeEncoding.GetBytes] Expected no left over characters if flushing");
+
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0 ||
+ encoder == null || !encoder.m_throwOnOverflow,
+ "[UnicodeEncoding.GetBytes]Expected empty fallback buffer if not converting");
+
+ // We used to copy it fast, but this doesn't check for surrogates
+ // System.IO.__UnmanagedMemoryStream.memcpyimpl(bytes, (byte*)chars, usedByteCount);
+
+ return (int)(bytes - byteStart);
+ }
+
+ internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
+ {
+ Debug.Assert(bytes != null, "[UnicodeEncoding.GetCharCount]bytes!=null");
+ Debug.Assert(count >= 0, "[UnicodeEncoding.GetCharCount]count >=0");
+
+ UnicodeEncoding.Decoder decoder = (UnicodeEncoding.Decoder)baseDecoder;
+
+ byte* byteEnd = bytes + count;
+ byte* byteStart = bytes;
+
+ // Need last vars
+ int lastByte = -1;
+ char lastChar = (char)0;
+
+ // Start by assuming same # of chars as bytes
+ int charCount = count >> 1;
+
+ // Need -1 to check 2 at a time. If we have an even #, longBytes will go
+ // from longEnd - 1/2 long to longEnd + 1/2 long. If we're odd, longBytes
+ // will go from longEnd - 1 long to longEnd. (Might not get to use this)
+ ulong* longEnd = (ulong*)(byteEnd - 7);
+
+ // For fallback we may need a fallback buffer
+ DecoderFallbackBuffer fallbackBuffer = null;
+
+ if (decoder != null)
+ {
+ lastByte = decoder.lastByte;
+ lastChar = decoder.lastChar;
+
+ // Assume extra char if last char was around
+ if (lastChar > 0)
+ charCount++;
+
+ // Assume extra char if extra last byte makes up odd # of input bytes
+ if (lastByte >= 0 && (count & 1) == 1)
+ {
+ charCount++;
+ }
+
+ // Shouldn't have anything in fallback buffer for GetCharCount
+ // (don't have to check m_throwOnOverflow for count)
+ Debug.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
+ "[UnicodeEncoding.GetCharCount]Expected empty fallback buffer at start");
+ }
+
+ while (bytes < byteEnd)
+ {
+ // If we're aligned then maybe we can do it fast
+ // This'll hurt if we're unaligned because we'll always test but never be aligned
+#if !NO_FAST_UNICODE_LOOP
+#if BIGENDIAN
+ if (bigEndian &&
+#else // BIGENDIAN
+ if (!bigEndian &&
+#endif // BIGENDIAN
+#if BIT64 // win64 has to be long aligned
+ (unchecked((long)bytes) & 7) == 0 &&
+#else
+ (unchecked((int)bytes) & 3) == 0 &&
+#endif // BIT64
+ lastByte == -1 && lastChar == 0)
+ {
+ // Need new char* so we can check 4 at a time
+ ulong* longBytes = (ulong*)bytes;
+
+ while (longBytes < longEnd)
+ {
+ // See if we potentially have surrogates (0x8000 bit set)
+ // (We're either big endian on a big endian machine or little endian on
+ // a little endian machine so this'll work)
+ if ((0x8000800080008000 & *longBytes) != 0)
+ {
+ // See if any of these are high or low surrogates (0xd800 - 0xdfff). If the high
+ // 5 bits looks like 11011, then its a high or low surrogate.
+ // We do the & f800 to filter the 5 bits, then ^ d800 to ensure the 0 isn't set.
+ // Note that we expect BMP characters to be more common than surrogates
+ // & each char with 11111... then ^ with 11011. Zeroes then indicate surrogates
+ ulong uTemp = (0xf800f800f800f800 & *longBytes) ^ 0xd800d800d800d800;
+
+ // Check each of the 4 chars. 0 for those 16 bits means it was a surrogate
+ // but no clue if they're high or low.
+ // If each of the 4 characters are non-zero, then none are surrogates.
+ if ((uTemp & 0xFFFF000000000000) == 0 ||
+ (uTemp & 0x0000FFFF00000000) == 0 ||
+ (uTemp & 0x00000000FFFF0000) == 0 ||
+ (uTemp & 0x000000000000FFFF) == 0)
+ {
+ // It has at least 1 surrogate, but we don't know if they're high or low surrogates,
+ // or if there's 1 or 4 surrogates
+
+ // If they happen to be high/low/high/low, we may as well continue. Check the next
+ // bit to see if its set (low) or not (high) in the right pattern
+#if BIGENDIAN
+ if (((0xfc00fc00fc00fc00 & *longBytes) ^ 0xd800dc00d800dc00) != 0)
+#else
+ if (((0xfc00fc00fc00fc00 & *longBytes) ^ 0xdc00d800dc00d800) != 0)
+#endif
+ {
+ // Either there weren't 4 surrogates, or the 0x0400 bit was set when a high
+ // was hoped for or the 0x0400 bit wasn't set where a low was hoped for.
+
+ // Drop out to the slow loop to resolve the surrogates
+ break;
+ }
+ // else they are all surrogates in High/Low/High/Low order, so we can use them.
+ }
+ // else none are surrogates, so we can use them.
+ }
+ // else all < 0x8000 so we can use them
+
+ // We can use these 4 chars.
+ longBytes++;
+ }
+
+ bytes = (byte*)longBytes;
+
+ if (bytes >= byteEnd)
+ break;
+ }
+#endif // !NO_FAST_UNICODE_LOOP
+
+ // Get 1st byte
+ if (lastByte < 0)
+ {
+ lastByte = *bytes++;
+ if (bytes >= byteEnd) break;
+ }
+
+ // Get full char
+ char ch;
+ if (bigEndian)
+ {
+ ch = (char)(lastByte << 8 | *(bytes++));
+ }
+ else
+ {
+ ch = (char)(*(bytes++) << 8 | lastByte);
+ }
+ lastByte = -1;
+
+ // See if the char's valid
+ if (ch >= 0xd800 && ch <= 0xdfff)
+ {
+ // Was it a high surrogate?
+ if (ch <= 0xdbff)
+ {
+ // Its a high surrogate, if we had one then do fallback for previous one
+ if (lastChar > 0)
+ {
+ // Ignore previous bad high surrogate
+ charCount--;
+
+ // Get fallback for previous high surrogate
+ // Note we have to reconstruct bytes because some may have been in decoder
+ byte[] byteBuffer = null;
+ if (bigEndian)
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)(lastChar >> 8)), unchecked((byte)lastChar) };
+ }
+ else
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)lastChar), unchecked((byte)(lastChar >> 8)) };
+ }
+
+ if (fallbackBuffer == null)
+ {
+ if (decoder == null)
+ fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = decoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(byteStart, null);
+ }
+
+ // Get fallback.
+ charCount += fallbackBuffer.InternalFallback(byteBuffer, bytes);
+ }
+
+ // Ignore the last one which fell back already,
+ // and remember the new high surrogate
+ lastChar = ch;
+ continue;
+ }
+
+ // Its a low surrogate
+ if (lastChar == 0)
+ {
+ // Expected a previous high surrogate
+ charCount--;
+
+ // Get fallback for this low surrogate
+ // Note we have to reconstruct bytes because some may have been in decoder
+ byte[] byteBuffer = null;
+ if (bigEndian)
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)(ch >> 8)), unchecked((byte)ch) };
+ }
+ else
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)ch), unchecked((byte)(ch >> 8)) };
+ }
+
+ if (fallbackBuffer == null)
+ {
+ if (decoder == null)
+ fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = decoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(byteStart, null);
+ }
+
+ charCount += fallbackBuffer.InternalFallback(byteBuffer, bytes);
+
+ // Ignore this one (we already did its fallback)
+ continue;
+ }
+
+ // Valid surrogate pair, already counted.
+ lastChar = (char)0;
+ }
+ else if (lastChar > 0)
+ {
+ // Had a high surrogate, expected a low surrogate
+ // Uncount the last high surrogate
+ charCount--;
+
+ // fall back the high surrogate.
+ byte[] byteBuffer = null;
+ if (bigEndian)
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)(lastChar >> 8)), unchecked((byte)lastChar) };
+ }
+ else
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)lastChar), unchecked((byte)(lastChar >> 8)) };
+ }
+
+ if (fallbackBuffer == null)
+ {
+ if (decoder == null)
+ fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = decoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(byteStart, null);
+ }
+
+ // Already subtracted high surrogate
+ charCount += fallbackBuffer.InternalFallback(byteBuffer, bytes);
+
+ // Not left over now, clear previous high surrogate and continue to add current char
+ lastChar = (char)0;
+ }
+
+ // Valid char, already counted
+ }
+
+ // Extra space if we can't use decoder
+ if (decoder == null || decoder.MustFlush)
+ {
+ if (lastChar > 0)
+ {
+ // No hanging high surrogates allowed, do fallback and remove count for it
+ charCount--;
+ byte[] byteBuffer = null;
+ if (bigEndian)
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)(lastChar >> 8)), unchecked((byte)lastChar) };
+ }
+ else
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)lastChar), unchecked((byte)(lastChar >> 8)) };
+ }
+
+ if (fallbackBuffer == null)
+ {
+ if (decoder == null)
+ fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = decoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(byteStart, null);
+ }
+
+ charCount += fallbackBuffer.InternalFallback(byteBuffer, bytes);
+
+ lastChar = (char)0;
+ }
+
+ if (lastByte >= 0)
+ {
+ if (fallbackBuffer == null)
+ {
+ if (decoder == null)
+ fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = decoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(byteStart, null);
+ }
+
+ // No hanging odd bytes allowed if must flush
+ charCount += fallbackBuffer.InternalFallback(new byte[] { unchecked((byte)lastByte) }, bytes);
+ lastByte = -1;
+ }
+ }
+
+ // If we had a high surrogate left over, we can't count it
+ if (lastChar > 0)
+ charCount--;
+
+ // Shouldn't have anything in fallback buffer for GetCharCount
+ // (don't have to check m_throwOnOverflow for count)
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ "[UnicodeEncoding.GetCharCount]Expected empty fallback buffer at end");
+
+ return charCount;
+ }
+
+ internal override unsafe int GetChars(byte* bytes, int byteCount,
+ char* chars, int charCount, DecoderNLS baseDecoder)
+ {
+ Debug.Assert(chars != null, "[UnicodeEncoding.GetChars]chars!=null");
+ Debug.Assert(byteCount >= 0, "[UnicodeEncoding.GetChars]byteCount >=0");
+ Debug.Assert(charCount >= 0, "[UnicodeEncoding.GetChars]charCount >=0");
+ Debug.Assert(bytes != null, "[UnicodeEncoding.GetChars]bytes!=null");
+
+ UnicodeEncoding.Decoder decoder = (UnicodeEncoding.Decoder)baseDecoder;
+
+ // Need last vars
+ int lastByte = -1;
+ char lastChar = (char)0;
+
+ // Get our decoder (but don't clear it yet)
+ if (decoder != null)
+ {
+ lastByte = decoder.lastByte;
+ lastChar = decoder.lastChar;
+
+ // Shouldn't have anything in fallback buffer for GetChars
+ // (don't have to check m_throwOnOverflow for chars)
+ Debug.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
+ "[UnicodeEncoding.GetChars]Expected empty fallback buffer at start");
+ }
+
+ // For fallback we may need a fallback buffer
+ DecoderFallbackBuffer fallbackBuffer = null;
+ char* charsForFallback;
+
+ byte* byteEnd = bytes + byteCount;
+ char* charEnd = chars + charCount;
+ byte* byteStart = bytes;
+ char* charStart = chars;
+
+ while (bytes < byteEnd)
+ {
+ // If we're aligned then maybe we can do it fast
+ // This'll hurt if we're unaligned because we'll always test but never be aligned
+#if !NO_FAST_UNICODE_LOOP
+#if BIGENDIAN
+ if (bigEndian &&
+#else // BIGENDIAN
+ if (!bigEndian &&
+#endif // BIGENDIAN
+#if BIT64 // win64 has to be long aligned
+ (unchecked((long)chars) & 7) == 0 && (unchecked((long)bytes) & 7) == 0 &&
+#else
+ (unchecked((int)chars) & 3) == 0 && (unchecked((int)bytes) & 3) == 0 &&
+#endif // BIT64
+ lastByte == -1 && lastChar == 0)
+ {
+ // Need -1 to check 2 at a time. If we have an even #, longChars will go
+ // from longEnd - 1/2 long to longEnd + 1/2 long. If we're odd, longChars
+ // will go from longEnd - 1 long to longEnd. (Might not get to use this)
+ // We can only go iCount units (limited by shorter of char or byte buffers.
+ ulong* longEnd = (ulong*)(bytes - 7 +
+ (((byteEnd - bytes) >> 1 < charEnd - chars) ?
+ (byteEnd - bytes) : (charEnd - chars) << 1));
+
+ // Need new char* so we can check 4 at a time
+ ulong* longBytes = (ulong*)bytes;
+ ulong* longChars = (ulong*)chars;
+
+ while (longBytes < longEnd)
+ {
+ // See if we potentially have surrogates (0x8000 bit set)
+ // (We're either big endian on a big endian machine or little endian on
+ // a little endian machine so this'll work)
+ if ((0x8000800080008000 & *longBytes) != 0)
+ {
+ // See if any of these are high or low surrogates (0xd800 - 0xdfff). If the high
+ // 5 bits looks like 11011, then its a high or low surrogate.
+ // We do the & f800 to filter the 5 bits, then ^ d800 to ensure the 0 isn't set.
+ // Note that we expect BMP characters to be more common than surrogates
+ // & each char with 11111... then ^ with 11011. Zeroes then indicate surrogates
+ ulong uTemp = (0xf800f800f800f800 & *longBytes) ^ 0xd800d800d800d800;
+
+ // Check each of the 4 chars. 0 for those 16 bits means it was a surrogate
+ // but no clue if they're high or low.
+ // If each of the 4 characters are non-zero, then none are surrogates.
+ if ((uTemp & 0xFFFF000000000000) == 0 ||
+ (uTemp & 0x0000FFFF00000000) == 0 ||
+ (uTemp & 0x00000000FFFF0000) == 0 ||
+ (uTemp & 0x000000000000FFFF) == 0)
+ {
+ // It has at least 1 surrogate, but we don't know if they're high or low surrogates,
+ // or if there's 1 or 4 surrogates
+
+ // If they happen to be high/low/high/low, we may as well continue. Check the next
+ // bit to see if its set (low) or not (high) in the right pattern
+#if BIGENDIAN
+ if (((0xfc00fc00fc00fc00 & *longBytes) ^ 0xd800dc00d800dc00) != 0)
+#else
+ if (((0xfc00fc00fc00fc00 & *longBytes) ^ 0xdc00d800dc00d800) != 0)
+#endif
+ {
+ // Either there weren't 4 surrogates, or the 0x0400 bit was set when a high
+ // was hoped for or the 0x0400 bit wasn't set where a low was hoped for.
+
+ // Drop out to the slow loop to resolve the surrogates
+ break;
+ }
+ // else they are all surrogates in High/Low/High/Low order, so we can use them.
+ }
+ // else none are surrogates, so we can use them.
+ }
+ // else all < 0x8000 so we can use them
+
+ // We can use these 4 chars.
+ *longChars = *longBytes;
+ longBytes++;
+ longChars++;
+ }
+
+ chars = (char*)longChars;
+ bytes = (byte*)longBytes;
+
+ if (bytes >= byteEnd)
+ break;
+ }
+#endif // !NO_FAST_UNICODE_LOOP
+
+ // Get 1st byte
+ if (lastByte < 0)
+ {
+ lastByte = *bytes++;
+ continue;
+ }
+
+ // Get full char
+ char ch;
+ if (bigEndian)
+ {
+ ch = (char)(lastByte << 8 | *(bytes++));
+ }
+ else
+ {
+ ch = (char)(*(bytes++) << 8 | lastByte);
+ }
+ lastByte = -1;
+
+ // See if the char's valid
+ if (ch >= 0xd800 && ch <= 0xdfff)
+ {
+ // Was it a high surrogate?
+ if (ch <= 0xdbff)
+ {
+ // Its a high surrogate, if we had one then do fallback for previous one
+ if (lastChar > 0)
+ {
+ // Get fallback for previous high surrogate
+ // Note we have to reconstruct bytes because some may have been in decoder
+ byte[] byteBuffer = null;
+ if (bigEndian)
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)(lastChar >> 8)), unchecked((byte)lastChar) };
+ }
+ else
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)lastChar), unchecked((byte)(lastChar >> 8)) };
+ }
+
+ if (fallbackBuffer == null)
+ {
+ if (decoder == null)
+ fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = decoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(byteStart, charEnd);
+ }
+
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ bool fallbackResult = fallbackBuffer.InternalFallback(byteBuffer, bytes, ref charsForFallback);
+ chars = charsForFallback;
+
+ if (!fallbackResult)
+ {
+ // couldn't fall back lonely surrogate
+ // We either advanced bytes or chars should == charStart and throw below
+ Debug.Assert(bytes >= byteStart + 2 || chars == charStart,
+ "[UnicodeEncoding.GetChars]Expected bytes to have advanced or no output (bad surrogate)");
+ bytes -= 2; // didn't use these 2 bytes
+ fallbackBuffer.InternalReset();
+ ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
+ break; // couldn't fallback but didn't throw
+ }
+ }
+
+ // Ignore the previous high surrogate which fell back already,
+ // yet remember the current high surrogate for next time.
+ lastChar = ch;
+ continue;
+ }
+
+ // Its a low surrogate
+ if (lastChar == 0)
+ {
+ // Expected a previous high surrogate
+ // Get fallback for this low surrogate
+ // Note we have to reconstruct bytes because some may have been in decoder
+ byte[] byteBuffer = null;
+ if (bigEndian)
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)(ch >> 8)), unchecked((byte)ch) };
+ }
+ else
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)ch), unchecked((byte)(ch >> 8)) };
+ }
+
+ if (fallbackBuffer == null)
+ {
+ if (decoder == null)
+ fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = decoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(byteStart, charEnd);
+ }
+
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ bool fallbackResult = fallbackBuffer.InternalFallback(byteBuffer, bytes, ref charsForFallback);
+ chars = charsForFallback;
+
+ if (!fallbackResult)
+ {
+ // couldn't fall back lonely surrogate
+ // We either advanced bytes or chars should == charStart and throw below
+ Debug.Assert(bytes >= byteStart + 2 || chars == charStart,
+ "[UnicodeEncoding.GetChars]Expected bytes to have advanced or no output (lonely surrogate)");
+ bytes -= 2; // didn't use these 2 bytes
+ fallbackBuffer.InternalReset();
+ ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
+ break; // couldn't fallback but didn't throw
+ }
+
+ // Didn't throw, ignore this one (we already did its fallback)
+ continue;
+ }
+
+ // Valid surrogate pair, add our lastChar (will need 2 chars)
+ if (chars >= charEnd - 1)
+ {
+ // couldn't find room for this surrogate pair
+ // We either advanced bytes or chars should == charStart and throw below
+ Debug.Assert(bytes >= byteStart + 2 || chars == charStart,
+ "[UnicodeEncoding.GetChars]Expected bytes to have advanced or no output (surrogate pair)");
+ bytes -= 2; // didn't use these 2 bytes
+ ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
+ // Leave lastChar for next call to Convert()
+ break; // couldn't fallback but didn't throw
+ }
+
+ *chars++ = lastChar;
+ lastChar = (char)0;
+ }
+ else if (lastChar > 0)
+ {
+ // Had a high surrogate, expected a low surrogate, fall back the high surrogate.
+ byte[] byteBuffer = null;
+ if (bigEndian)
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)(lastChar >> 8)), unchecked((byte)lastChar) };
+ }
+ else
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)lastChar), unchecked((byte)(lastChar >> 8)) };
+ }
+
+ if (fallbackBuffer == null)
+ {
+ if (decoder == null)
+ fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = decoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(byteStart, charEnd);
+ }
+
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ bool fallbackResult = fallbackBuffer.InternalFallback(byteBuffer, bytes, ref charsForFallback);
+ chars = charsForFallback;
+
+ if (!fallbackResult)
+ {
+ // couldn't fall back high surrogate, or char that would be next
+ // We either advanced bytes or chars should == charStart and throw below
+ Debug.Assert(bytes >= byteStart + 2 || chars == charStart,
+ "[UnicodeEncoding.GetChars]Expected bytes to have advanced or no output (no low surrogate)");
+ bytes -= 2; // didn't use these 2 bytes
+ fallbackBuffer.InternalReset();
+ ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
+ break; // couldn't fallback but didn't throw
+ }
+
+ // Not left over now, clear previous high surrogate and continue to add current char
+ lastChar = (char)0;
+ }
+
+ // Valid char, room for it?
+ if (chars >= charEnd)
+ {
+ // 2 bytes couldn't fall back
+ // We either advanced bytes or chars should == charStart and throw below
+ Debug.Assert(bytes >= byteStart + 2 || chars == charStart,
+ "[UnicodeEncoding.GetChars]Expected bytes to have advanced or no output (normal)");
+ bytes -= 2; // didn't use these bytes
+ ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
+ break; // couldn't fallback but didn't throw
+ }
+
+ // add it
+ *chars++ = ch;
+ }
+
+ // Remember our decoder if we must
+ if (decoder == null || decoder.MustFlush)
+ {
+ if (lastChar > 0)
+ {
+ // No hanging high surrogates allowed, do fallback and remove count for it
+ byte[] byteBuffer = null;
+ if (bigEndian)
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)(lastChar >> 8)), unchecked((byte)lastChar) };
+ }
+ else
+ {
+ byteBuffer = new byte[]
+ { unchecked((byte)lastChar), unchecked((byte)(lastChar >> 8)) };
+ }
+
+ if (fallbackBuffer == null)
+ {
+ if (decoder == null)
+ fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = decoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(byteStart, charEnd);
+ }
+
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ bool fallbackResult = fallbackBuffer.InternalFallback(byteBuffer, bytes, ref charsForFallback);
+ chars = charsForFallback;
+
+ if (!fallbackResult)
+ {
+ // 2 bytes couldn't fall back
+ // We either advanced bytes or chars should == charStart and throw below
+ Debug.Assert(bytes >= byteStart + 2 || chars == charStart,
+ "[UnicodeEncoding.GetChars]Expected bytes to have advanced or no output (decoder)");
+ bytes -= 2; // didn't use these bytes
+ if (lastByte >= 0)
+ bytes--; // had an extra last byte hanging around
+ fallbackBuffer.InternalReset();
+ ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
+ // We'll remember these in our decoder though
+ bytes += 2;
+ if (lastByte >= 0)
+ bytes++;
+ goto End;
+ }
+
+ // done with this one
+ lastChar = (char)0;
+ }
+
+ if (lastByte >= 0)
+ {
+ if (fallbackBuffer == null)
+ {
+ if (decoder == null)
+ fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
+ else
+ fallbackBuffer = decoder.FallbackBuffer;
+
+ // Set our internal fallback interesting things.
+ fallbackBuffer.InternalInitialize(byteStart, charEnd);
+ }
+
+ // No hanging odd bytes allowed if must flush
+ charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
+ bool fallbackResult = fallbackBuffer.InternalFallback(new byte[] { unchecked((byte)lastByte) }, bytes, ref charsForFallback);
+ chars = charsForFallback;
+
+ if (!fallbackResult)
+ {
+ // odd byte couldn't fall back
+ bytes--; // didn't use this byte
+ fallbackBuffer.InternalReset();
+ ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
+ // didn't throw, but we'll remember it in the decoder
+ bytes++;
+ goto End;
+ }
+
+ // Didn't fail, clear buffer
+ lastByte = -1;
+ }
+ }
+
+ End:
+
+ // Remember our decoder if we must
+ if (decoder != null)
+ {
+ Debug.Assert((decoder.MustFlush == false) || ((lastChar == (char)0) && (lastByte == -1)),
+ "[UnicodeEncoding.GetChars] Expected no left over chars or bytes if flushing"
+ // + " " + ((int)lastChar).ToString("X4") + " " + lastByte.ToString("X2")
+ );
+
+ decoder.m_bytesUsed = (int)(bytes - byteStart);
+ decoder.lastChar = lastChar;
+ decoder.lastByte = lastByte;
+ }
+
+ // Used to do this the old way
+ // System.IO.__UnmanagedMemoryStream.memcpyimpl((byte*)chars, bytes, byteCount);
+
+ // Shouldn't have anything in fallback buffer for GetChars
+ // (don't have to check m_throwOnOverflow for count or chars)
+ Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
+ "[UnicodeEncoding.GetChars]Expected empty fallback buffer at end");
+
+ return (int)(chars - charStart);
+ }
+
+
+ public override System.Text.Encoder GetEncoder()
+ {
+ return new EncoderNLS(this);
+ }
+
+
+ public override System.Text.Decoder GetDecoder()
+ {
+ return new UnicodeEncoding.Decoder(this);
+ }
+
+
+ public override byte[] GetPreamble()
+ {
+ if (byteOrderMark)
+ {
+ // Note - we must allocate new byte[]'s here to prevent someone
+ // from modifying a cached byte[].
+ if (bigEndian)
+ return new byte[2] { 0xfe, 0xff };
+ else
+ return new byte[2] { 0xff, 0xfe };
+ }
+ return Array.Empty<Byte>();
+ }
+
+
+ public override int GetMaxByteCount(int charCount)
+ {
+ if (charCount < 0)
+ throw new ArgumentOutOfRangeException(nameof(charCount),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Characters would be # of characters + 1 in case left over high surrogate is ? * max fallback
+ long byteCount = (long)charCount + 1;
+
+ if (EncoderFallback.MaxCharCount > 1)
+ byteCount *= EncoderFallback.MaxCharCount;
+
+ // 2 bytes per char
+ byteCount <<= 1;
+
+ if (byteCount > 0x7fffffff)
+ throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_GetByteCountOverflow);
+
+ return (int)byteCount;
+ }
+
+
+ public override int GetMaxCharCount(int byteCount)
+ {
+ if (byteCount < 0)
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // long because byteCount could be biggest int.
+ // 1 char per 2 bytes. Round up in case 1 left over in decoder.
+ // Round up using &1 in case byteCount is max size
+ // Might also need an extra 1 if there's a left over high surrogate in the decoder.
+ long charCount = (long)(byteCount >> 1) + (byteCount & 1) + 1;
+
+ // Don't forget fallback (in case they have a bunch of lonely surrogates or something bizzare like that)
+ if (DecoderFallback.MaxCharCount > 1)
+ charCount *= DecoderFallback.MaxCharCount;
+
+ if (charCount > 0x7fffffff)
+ throw new ArgumentOutOfRangeException(nameof(byteCount), SR.ArgumentOutOfRange_GetCharCountOverflow);
+
+ return (int)charCount;
+ }
+
+
+ public override bool Equals(Object value)
+ {
+ UnicodeEncoding that = value as UnicodeEncoding;
+ if (that != null)
+ {
+ //
+ // Big Endian Unicode has different code page (1201) than small Endian one (1200),
+ // so we still have to check m_codePage here.
+ //
+ return (CodePage == that.CodePage) &&
+ byteOrderMark == that.byteOrderMark &&
+ // isThrowException == that.isThrowException && // Same as Encoder/Decoder being exception fallbacks
+ bigEndian == that.bigEndian &&
+ (EncoderFallback.Equals(that.EncoderFallback)) &&
+ (DecoderFallback.Equals(that.DecoderFallback));
+ }
+ return (false);
+ }
+
+ public override int GetHashCode()
+ {
+ return CodePage + this.EncoderFallback.GetHashCode() + this.DecoderFallback.GetHashCode() +
+ (byteOrderMark ? 4 : 0) + (bigEndian ? 8 : 0);
+ }
+
+ [Serializable]
+ private sealed class Decoder : System.Text.DecoderNLS, ISerializable
+ {
+ internal int lastByte = -1;
+ internal char lastChar = '\0';
+
+ public Decoder(UnicodeEncoding encoding) : base(encoding)
+ {
+ // base calls reset
+ }
+
+ // Constructor called by serialization, have to handle deserializing from Everett
+ internal Decoder(SerializationInfo info, StreamingContext context)
+ {
+ // Any info?
+ if (info == null) throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ // Get Common Info
+ this.lastByte = (int)info.GetValue("lastByte", typeof(int));
+
+ try
+ {
+ // Try the encoding, which is only serialized in Whidbey
+ this.m_encoding = (Encoding)info.GetValue("m_encoding", typeof(Encoding));
+ this.lastChar = (char)info.GetValue("lastChar", typeof(char));
+ this.m_fallback = (DecoderFallback)info.GetValue("m_fallback", typeof(DecoderFallback));
+ }
+ catch (SerializationException)
+ {
+ // Everett didn't serialize the UnicodeEncoding, get the default one
+ bool bigEndian = (bool)info.GetValue("bigEndian", typeof(bool));
+ this.m_encoding = new UnicodeEncoding(bigEndian, false);
+ }
+ }
+
+ // ISerializable implementation, get data for this object
+ void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ // Any info?
+ if (info == null) throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ // Save Whidbey data
+ info.AddValue("m_encoding", this.m_encoding);
+ info.AddValue("m_fallback", this.m_fallback);
+ info.AddValue("lastChar", this.lastChar); // Unused by everett so it'll probably get lost
+ info.AddValue("lastByte", this.lastByte);
+
+ // Everett Only
+ info.AddValue("bigEndian", ((UnicodeEncoding)(this.m_encoding)).bigEndian);
+ }
+
+ public override void Reset()
+ {
+ lastByte = -1;
+ lastChar = '\0';
+ if (m_fallbackBuffer != null)
+ m_fallbackBuffer.Reset();
+ }
+
+ // Anything left in our decoder?
+ internal override bool HasState
+ {
+ get
+ {
+ return (this.lastByte != -1 || this.lastChar != '\0');
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/mscorlib/src/System/ThreadAttributes.cs b/src/mscorlib/shared/System/ThreadAttributes.cs
index 6248736107..6248736107 100644
--- a/src/mscorlib/src/System/ThreadAttributes.cs
+++ b/src/mscorlib/shared/System/ThreadAttributes.cs
diff --git a/src/mscorlib/src/System/ThreadStaticAttribute.cs b/src/mscorlib/shared/System/ThreadStaticAttribute.cs
index 3755e65a7b..3755e65a7b 100644
--- a/src/mscorlib/src/System/ThreadStaticAttribute.cs
+++ b/src/mscorlib/shared/System/ThreadStaticAttribute.cs
diff --git a/src/mscorlib/shared/System/Threading/AbandonedMutexException.cs b/src/mscorlib/shared/System/Threading/AbandonedMutexException.cs
new file mode 100644
index 0000000000..8056a3b330
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/AbandonedMutexException.cs
@@ -0,0 +1,77 @@
+// 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.
+//
+// AbandonedMutexException
+// Thrown when a wait completes because one or more mutexes was abandoned.
+// AbandonedMutexs indicate serious error in user code or machine state.
+////////////////////////////////////////////////////////////////////////////////
+
+using System;
+using System.Threading;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+
+namespace System.Threading
+{
+ [Serializable]
+ public class AbandonedMutexException : SystemException
+ {
+ private int _mutexIndex = -1;
+ private Mutex _mutex = null;
+
+ public AbandonedMutexException()
+ : base(SR.Threading_AbandonedMutexException)
+ {
+ HResult = __HResults.COR_E_ABANDONEDMUTEX;
+ }
+
+ public AbandonedMutexException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_ABANDONEDMUTEX;
+ }
+
+ public AbandonedMutexException(String message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_ABANDONEDMUTEX;
+ }
+
+ public AbandonedMutexException(int location, WaitHandle handle)
+ : base(SR.Threading_AbandonedMutexException)
+ {
+ HResult = __HResults.COR_E_ABANDONEDMUTEX;
+ SetupException(location, handle);
+ }
+
+ public AbandonedMutexException(String message, int location, WaitHandle handle)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_ABANDONEDMUTEX;
+ SetupException(location, handle);
+ }
+
+ public AbandonedMutexException(String message, Exception inner, int location, WaitHandle handle)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_ABANDONEDMUTEX;
+ SetupException(location, handle);
+ }
+
+ protected AbandonedMutexException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+
+ private void SetupException(int location, WaitHandle handle)
+ {
+ _mutexIndex = location;
+ if (handle != null)
+ _mutex = handle as Mutex;
+ }
+
+ public Mutex Mutex => _mutex;
+ public int MutexIndex => _mutexIndex;
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/ApartmentState.cs b/src/mscorlib/shared/System/Threading/ApartmentState.cs
new file mode 100644
index 0000000000..47c1677cb5
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/ApartmentState.cs
@@ -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.
+
+namespace System.Threading
+{
+ public enum ApartmentState
+ {
+ /*=========================================================================
+ ** Constants for thread apartment states.
+ =========================================================================*/
+ STA = 0,
+ MTA = 1,
+ Unknown = 2
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/AsyncLocal.cs b/src/mscorlib/shared/System/Threading/AsyncLocal.cs
new file mode 100644
index 0000000000..59c8fb3c88
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/AsyncLocal.cs
@@ -0,0 +1,484 @@
+// 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.Collections.Generic;
+using System.Diagnostics;
+
+namespace System.Threading
+{
+ //
+ // AsyncLocal<T> represents "ambient" data that is local to a given asynchronous control flow, such as an
+ // async method. For example, say you want to associate a culture with a given async flow:
+ //
+ // static AsyncLocal<Culture> s_currentCulture = new AsyncLocal<Culture>();
+ //
+ // static async Task SomeOperationAsync(Culture culture)
+ // {
+ // s_currentCulture.Value = culture;
+ //
+ // await FooAsync();
+ // }
+ //
+ // static async Task FooAsync()
+ // {
+ // PrintStringWithCulture(s_currentCulture.Value);
+ // }
+ //
+ // AsyncLocal<T> also provides optional notifications when the value associated with the current thread
+ // changes, either because it was explicitly changed by setting the Value property, or implicitly changed
+ // when the thread encountered an "await" or other context transition. For example, we might want our
+ // current culture to be communicated to the OS as well:
+ //
+ // static AsyncLocal<Culture> s_currentCulture = new AsyncLocal<Culture>(
+ // args =>
+ // {
+ // NativeMethods.SetThreadCulture(args.CurrentValue.LCID);
+ // });
+ //
+ public sealed class AsyncLocal<T> : IAsyncLocal
+ {
+ private readonly Action<AsyncLocalValueChangedArgs<T>> m_valueChangedHandler;
+
+ //
+ // Constructs an AsyncLocal<T> that does not receive change notifications.
+ //
+ public AsyncLocal()
+ {
+ }
+
+ //
+ // Constructs an AsyncLocal<T> with a delegate that is called whenever the current value changes
+ // on any thread.
+ //
+ public AsyncLocal(Action<AsyncLocalValueChangedArgs<T>> valueChangedHandler)
+ {
+ m_valueChangedHandler = valueChangedHandler;
+ }
+
+ public T Value
+ {
+ get
+ {
+ object obj = ExecutionContext.GetLocalValue(this);
+ return (obj == null) ? default(T) : (T)obj;
+ }
+ set
+ {
+ ExecutionContext.SetLocalValue(this, value, m_valueChangedHandler != null);
+ }
+ }
+
+ void IAsyncLocal.OnValueChanged(object previousValueObj, object currentValueObj, bool contextChanged)
+ {
+ Debug.Assert(m_valueChangedHandler != null);
+ T previousValue = previousValueObj == null ? default(T) : (T)previousValueObj;
+ T currentValue = currentValueObj == null ? default(T) : (T)currentValueObj;
+ m_valueChangedHandler(new AsyncLocalValueChangedArgs<T>(previousValue, currentValue, contextChanged));
+ }
+ }
+
+ //
+ // Interface to allow non-generic code in ExecutionContext to call into the generic AsyncLocal<T> type.
+ //
+ internal interface IAsyncLocal
+ {
+ void OnValueChanged(object previousValue, object currentValue, bool contextChanged);
+ }
+
+ public struct AsyncLocalValueChangedArgs<T>
+ {
+ public T PreviousValue { get; private set; }
+ public T CurrentValue { get; private set; }
+
+ //
+ // If the value changed because we changed to a different ExecutionContext, this is true. If it changed
+ // because someone set the Value property, this is false.
+ //
+ public bool ThreadContextChanged { get; private set; }
+
+ internal AsyncLocalValueChangedArgs(T previousValue, T currentValue, bool contextChanged)
+ : this()
+ {
+ PreviousValue = previousValue;
+ CurrentValue = currentValue;
+ ThreadContextChanged = contextChanged;
+ }
+ }
+
+ //
+ // Interface used to store an IAsyncLocal => object mapping in ExecutionContext.
+ // Implementations are specialized based on the number of elements in the immutable
+ // map in order to minimize memory consumption and look-up times.
+ //
+ internal interface IAsyncLocalValueMap
+ {
+ bool TryGetValue(IAsyncLocal key, out object value);
+ IAsyncLocalValueMap Set(IAsyncLocal key, object value);
+ }
+
+ //
+ // Utility functions for getting/creating instances of IAsyncLocalValueMap
+ //
+ internal static class AsyncLocalValueMap
+ {
+ public static IAsyncLocalValueMap Empty { get; } = new EmptyAsyncLocalValueMap();
+
+ // Instance without any key/value pairs. Used as a singleton/
+ private sealed class EmptyAsyncLocalValueMap : IAsyncLocalValueMap
+ {
+ public IAsyncLocalValueMap Set(IAsyncLocal key, object value)
+ {
+ // If the value isn't null, then create a new one-element map to store
+ // the key/value pair. If it is null, then we're still empty.
+ return value != null ?
+ new OneElementAsyncLocalValueMap(key, value) :
+ (IAsyncLocalValueMap)this;
+ }
+
+ public bool TryGetValue(IAsyncLocal key, out object value)
+ {
+ value = null;
+ return false;
+ }
+ }
+
+ // Instance with one key/value pair.
+ private sealed class OneElementAsyncLocalValueMap : IAsyncLocalValueMap
+ {
+ private readonly IAsyncLocal _key1;
+ private readonly object _value1;
+
+ public OneElementAsyncLocalValueMap(IAsyncLocal key, object value)
+ {
+ _key1 = key; _value1 = value;
+ }
+
+ public IAsyncLocalValueMap Set(IAsyncLocal key, object value)
+ {
+ if (value != null)
+ {
+ // The value is non-null. If the key matches one already contained in this map,
+ // then create a new one-element map with the updated value, otherwise create
+ // a two-element map with the additional key/value.
+ return ReferenceEquals(key, _key1) ?
+ new OneElementAsyncLocalValueMap(key, value) :
+ (IAsyncLocalValueMap)new TwoElementAsyncLocalValueMap(_key1, _value1, key, value);
+ }
+ else
+ {
+ // The value is null. If the key exists in this map, remove it by downgrading to an empty map.
+ // Otherwise, there's nothing to add or remove, so just return this map.
+ return ReferenceEquals(key, _key1) ?
+ Empty :
+ (IAsyncLocalValueMap)this;
+ }
+ }
+
+ public bool TryGetValue(IAsyncLocal key, out object value)
+ {
+ if (ReferenceEquals(key, _key1))
+ {
+ value = _value1;
+ return true;
+ }
+ else
+ {
+ value = null;
+ return false;
+ }
+ }
+ }
+
+ // Instance with two key/value pairs.
+ private sealed class TwoElementAsyncLocalValueMap : IAsyncLocalValueMap
+ {
+ private readonly IAsyncLocal _key1, _key2;
+ private readonly object _value1, _value2;
+
+ public TwoElementAsyncLocalValueMap(IAsyncLocal key1, object value1, IAsyncLocal key2, object value2)
+ {
+ _key1 = key1; _value1 = value1;
+ _key2 = key2; _value2 = value2;
+ }
+
+ public IAsyncLocalValueMap Set(IAsyncLocal key, object value)
+ {
+ if (value != null)
+ {
+ // The value is non-null. If the key matches one already contained in this map,
+ // then create a new two-element map with the updated value, otherwise create
+ // a three-element map with the additional key/value.
+ return
+ ReferenceEquals(key, _key1) ? new TwoElementAsyncLocalValueMap(key, value, _key2, _value2) :
+ ReferenceEquals(key, _key2) ? new TwoElementAsyncLocalValueMap(_key1, _value1, key, value) :
+ (IAsyncLocalValueMap)new ThreeElementAsyncLocalValueMap(_key1, _value1, _key2, _value2, key, value);
+ }
+ else
+ {
+ // The value is null. If the key exists in this map, remove it by downgrading to a one-element map
+ // without the key. Otherwise, there's nothing to add or remove, so just return this map.
+ return
+ ReferenceEquals(key, _key1) ? new OneElementAsyncLocalValueMap(_key2, _value2) :
+ ReferenceEquals(key, _key2) ? new OneElementAsyncLocalValueMap(_key1, _value1) :
+ (IAsyncLocalValueMap)this;
+ }
+ }
+
+ public bool TryGetValue(IAsyncLocal key, out object value)
+ {
+ if (ReferenceEquals(key, _key1))
+ {
+ value = _value1;
+ return true;
+ }
+ else if (ReferenceEquals(key, _key2))
+ {
+ value = _value2;
+ return true;
+ }
+ else
+ {
+ value = null;
+ return false;
+ }
+ }
+ }
+
+ // Instance with three key/value pairs.
+ private sealed class ThreeElementAsyncLocalValueMap : IAsyncLocalValueMap
+ {
+ private readonly IAsyncLocal _key1, _key2, _key3;
+ private readonly object _value1, _value2, _value3;
+
+ public ThreeElementAsyncLocalValueMap(IAsyncLocal key1, object value1, IAsyncLocal key2, object value2, IAsyncLocal key3, object value3)
+ {
+ _key1 = key1; _value1 = value1;
+ _key2 = key2; _value2 = value2;
+ _key3 = key3; _value3 = value3;
+ }
+
+ public IAsyncLocalValueMap Set(IAsyncLocal key, object value)
+ {
+ if (value != null)
+ {
+ // The value is non-null. If the key matches one already contained in this map,
+ // then create a new three-element map with the updated value.
+ if (ReferenceEquals(key, _key1)) return new ThreeElementAsyncLocalValueMap(key, value, _key2, _value2, _key3, _value3);
+ if (ReferenceEquals(key, _key2)) return new ThreeElementAsyncLocalValueMap(_key1, _value1, key, value, _key3, _value3);
+ if (ReferenceEquals(key, _key3)) return new ThreeElementAsyncLocalValueMap(_key1, _value1, _key2, _value2, key, value);
+
+ // The key doesn't exist in this map, so upgrade to a multi map that contains
+ // the additional key/value pair.
+ var multi = new MultiElementAsyncLocalValueMap(4);
+ multi.UnsafeStore(0, _key1, _value1);
+ multi.UnsafeStore(1, _key2, _value2);
+ multi.UnsafeStore(2, _key3, _value3);
+ multi.UnsafeStore(3, key, value);
+ return multi;
+ }
+ else
+ {
+ // The value is null. If the key exists in this map, remove it by downgrading to a two-element map
+ // without the key. Otherwise, there's nothing to add or remove, so just return this map.
+ return
+ ReferenceEquals(key, _key1) ? new TwoElementAsyncLocalValueMap(_key2, _value2, _key3, _value3) :
+ ReferenceEquals(key, _key2) ? new TwoElementAsyncLocalValueMap(_key1, _value1, _key3, _value3) :
+ ReferenceEquals(key, _key3) ? new TwoElementAsyncLocalValueMap(_key1, _value1, _key2, _value2) :
+ (IAsyncLocalValueMap)this;
+ }
+ }
+
+ public bool TryGetValue(IAsyncLocal key, out object value)
+ {
+ if (ReferenceEquals(key, _key1))
+ {
+ value = _value1;
+ return true;
+ }
+ else if (ReferenceEquals(key, _key2))
+ {
+ value = _value2;
+ return true;
+ }
+ else if (ReferenceEquals(key, _key3))
+ {
+ value = _value3;
+ return true;
+ }
+ else
+ {
+ value = null;
+ return false;
+ }
+ }
+ }
+
+ // Instance with up to 16 key/value pairs.
+ private sealed class MultiElementAsyncLocalValueMap : IAsyncLocalValueMap
+ {
+ internal const int MaxMultiElements = 16;
+ private readonly KeyValuePair<IAsyncLocal, object>[] _keyValues;
+
+ internal MultiElementAsyncLocalValueMap(int count)
+ {
+ Debug.Assert(count <= MaxMultiElements);
+ _keyValues = new KeyValuePair<IAsyncLocal, object>[count];
+ }
+
+ internal void UnsafeStore(int index, IAsyncLocal key, object value)
+ {
+ Debug.Assert(index < _keyValues.Length);
+ _keyValues[index] = new KeyValuePair<IAsyncLocal, object>(key, value);
+ }
+
+ public IAsyncLocalValueMap Set(IAsyncLocal key, object value)
+ {
+ // Find the key in this map.
+ for (int i = 0; i < _keyValues.Length; i++)
+ {
+ if (ReferenceEquals(key, _keyValues[i].Key))
+ {
+ // The key is in the map. If the value isn't null, then create a new map of the same
+ // size that has all of the same pairs, with this new key/value pair overwriting the old.
+ if (value != null)
+ {
+ var multi = new MultiElementAsyncLocalValueMap(_keyValues.Length);
+ Array.Copy(_keyValues, 0, multi._keyValues, 0, _keyValues.Length);
+ multi._keyValues[i] = new KeyValuePair<IAsyncLocal, object>(key, value);
+ return multi;
+ }
+ else if (_keyValues.Length == 4)
+ {
+ // The value is null, and we only have four elements, one of which we're removing,
+ // so downgrade to a three-element map, without the matching element.
+ return
+ i == 0 ? new ThreeElementAsyncLocalValueMap(_keyValues[1].Key, _keyValues[1].Value, _keyValues[2].Key, _keyValues[2].Value, _keyValues[3].Key, _keyValues[3].Value) :
+ i == 1 ? new ThreeElementAsyncLocalValueMap(_keyValues[0].Key, _keyValues[0].Value, _keyValues[2].Key, _keyValues[2].Value, _keyValues[3].Key, _keyValues[3].Value) :
+ i == 2 ? new ThreeElementAsyncLocalValueMap(_keyValues[0].Key, _keyValues[0].Value, _keyValues[1].Key, _keyValues[1].Value, _keyValues[3].Key, _keyValues[3].Value) :
+ (IAsyncLocalValueMap)new ThreeElementAsyncLocalValueMap(_keyValues[0].Key, _keyValues[0].Value, _keyValues[1].Key, _keyValues[1].Value, _keyValues[2].Key, _keyValues[2].Value);
+ }
+ else
+ {
+ // The value is null, and we have enough elements remaining to warrant a multi map.
+ // Create a new one and copy all of the elements from this one, except the one to be removed.
+ var multi = new MultiElementAsyncLocalValueMap(_keyValues.Length - 1);
+ if (i != 0) Array.Copy(_keyValues, 0, multi._keyValues, 0, i);
+ if (i != _keyValues.Length - 1) Array.Copy(_keyValues, i + 1, multi._keyValues, i, _keyValues.Length - i - 1);
+ return multi;
+ }
+ }
+ }
+
+ // The key does not already exist in this map.
+
+ // If the value is null, then we can simply return this same map, as there's nothing to add or remove.
+ if (value == null)
+ {
+ return this;
+ }
+
+ // We need to create a new map that has the additional key/value pair.
+ // If with the addition we can still fit in a multi map, create one.
+ if (_keyValues.Length < MaxMultiElements)
+ {
+ var multi = new MultiElementAsyncLocalValueMap(_keyValues.Length + 1);
+ Array.Copy(_keyValues, 0, multi._keyValues, 0, _keyValues.Length);
+ multi._keyValues[_keyValues.Length] = new KeyValuePair<IAsyncLocal, object>(key, value);
+ return multi;
+ }
+
+ // Otherwise, upgrade to a many map.
+ var many = new ManyElementAsyncLocalValueMap(MaxMultiElements + 1);
+ foreach (KeyValuePair<IAsyncLocal, object> pair in _keyValues)
+ {
+ many[pair.Key] = pair.Value;
+ }
+ many[key] = value;
+ return many;
+ }
+
+ public bool TryGetValue(IAsyncLocal key, out object value)
+ {
+ foreach (KeyValuePair<IAsyncLocal, object> pair in _keyValues)
+ {
+ if (ReferenceEquals(key, pair.Key))
+ {
+ value = pair.Value;
+ return true;
+ }
+ }
+ value = null;
+ return false;
+ }
+ }
+
+ // Instance with any number of key/value pairs.
+ private sealed class ManyElementAsyncLocalValueMap : Dictionary<IAsyncLocal, object>, IAsyncLocalValueMap
+ {
+ public ManyElementAsyncLocalValueMap(int capacity) : base(capacity) { }
+
+ public IAsyncLocalValueMap Set(IAsyncLocal key, object value)
+ {
+ int count = Count;
+ bool containsKey = ContainsKey(key);
+
+ // If the value being set exists, create a new many map, copy all of the elements from this one,
+ // and then store the new key/value pair into it. This is the most common case.
+ if (value != null)
+ {
+ var map = new ManyElementAsyncLocalValueMap(count + (containsKey ? 0 : 1));
+ foreach (KeyValuePair<IAsyncLocal, object> pair in this)
+ {
+ map[pair.Key] = pair.Value;
+ }
+ map[key] = value;
+ return map;
+ }
+
+ // Otherwise, the value is null, which means null is being stored into an AsyncLocal.Value.
+ // Since there's no observable difference at the API level between storing null and the key
+ // not existing at all, we can downgrade to a smaller map rather than storing null.
+
+ // If the key is contained in this map, we're going to create a new map that's one pair smaller.
+ if (containsKey)
+ {
+ // If the new count would be within range of a multi map instead of a many map,
+ // downgrade to the many map, which uses less memory and is faster to access.
+ // Otherwise, just create a new many map that's missing this key.
+ if (count == MultiElementAsyncLocalValueMap.MaxMultiElements + 1)
+ {
+ var multi = new MultiElementAsyncLocalValueMap(MultiElementAsyncLocalValueMap.MaxMultiElements);
+ int index = 0;
+ foreach (KeyValuePair<IAsyncLocal, object> pair in this)
+ {
+ if (!ReferenceEquals(key, pair.Key))
+ {
+ multi.UnsafeStore(index++, pair.Key, pair.Value);
+ }
+ }
+ Debug.Assert(index == MultiElementAsyncLocalValueMap.MaxMultiElements);
+ return multi;
+ }
+ else
+ {
+ var map = new ManyElementAsyncLocalValueMap(count - 1);
+ foreach (KeyValuePair<IAsyncLocal, object> pair in this)
+ {
+ if (!ReferenceEquals(key, pair.Key))
+ {
+ map[pair.Key] = pair.Value;
+ }
+ }
+ Debug.Assert(map.Count == count - 1);
+ return map;
+ }
+ }
+
+ // We were storing null, but the key wasn't in the map, so there's nothing to change.
+ // Just return this instance.
+ return this;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/AutoResetEvent.cs b/src/mscorlib/shared/System/Threading/AutoResetEvent.cs
new file mode 100644
index 0000000000..8320d7ad5a
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/AutoResetEvent.cs
@@ -0,0 +1,12 @@
+// 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.
+
+namespace System.Threading
+{
+ public sealed class AutoResetEvent : EventWaitHandle
+ {
+ public AutoResetEvent(bool initialState) : base(initialState, EventResetMode.AutoReset) { }
+ }
+}
+
diff --git a/src/mscorlib/corefx/System/Threading/DeferredDisposableLifetime.cs b/src/mscorlib/shared/System/Threading/DeferredDisposableLifetime.cs
index 89380fee60..89380fee60 100644
--- a/src/mscorlib/corefx/System/Threading/DeferredDisposableLifetime.cs
+++ b/src/mscorlib/shared/System/Threading/DeferredDisposableLifetime.cs
diff --git a/src/mscorlib/shared/System/Threading/EventResetMode.cs b/src/mscorlib/shared/System/Threading/EventResetMode.cs
new file mode 100644
index 0000000000..7aac0f51eb
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/EventResetMode.cs
@@ -0,0 +1,22 @@
+// 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.
+
+/*=============================================================================
+**
+** Enum: EventResetMode
+**
+**
+** Purpose: Enum to determine the Event type to create
+**
+**
+=============================================================================*/
+
+namespace System.Threading
+{
+ public enum EventResetMode
+ {
+ AutoReset = 0,
+ ManualReset = 1
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/ExecutionContext.cs b/src/mscorlib/shared/System/Threading/ExecutionContext.cs
new file mode 100644
index 0000000000..67857e9b11
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/ExecutionContext.cs
@@ -0,0 +1,370 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose: Capture execution context for a thread
+**
+**
+===========================================================*/
+
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.ExceptionServices;
+using System.Runtime.Serialization;
+
+using Thread = Internal.Runtime.Augments.RuntimeThread;
+
+namespace System.Threading
+{
+ public delegate void ContextCallback(Object state);
+
+ internal struct ExecutionContextSwitcher
+ {
+ internal ExecutionContext m_ec;
+ internal SynchronizationContext m_sc;
+
+ internal void Undo(Thread currentThread)
+ {
+ Debug.Assert(currentThread == Thread.CurrentThread);
+
+ // The common case is that these have not changed, so avoid the cost of a write if not needed.
+ if (currentThread.SynchronizationContext != m_sc)
+ {
+ currentThread.SynchronizationContext = m_sc;
+ }
+
+ if (currentThread.ExecutionContext != m_ec)
+ {
+ ExecutionContext.Restore(currentThread, m_ec);
+ }
+ }
+ }
+
+ [Serializable]
+ public sealed class ExecutionContext : IDisposable, ISerializable
+ {
+ internal static readonly ExecutionContext Default = new ExecutionContext();
+
+ private readonly IAsyncLocalValueMap m_localValues;
+ private readonly IAsyncLocal[] m_localChangeNotifications;
+ private readonly bool m_isFlowSuppressed;
+
+ private ExecutionContext()
+ {
+ m_localValues = AsyncLocalValueMap.Empty;
+ m_localChangeNotifications = Array.Empty<IAsyncLocal>();
+ }
+
+ private ExecutionContext(
+ IAsyncLocalValueMap localValues,
+ IAsyncLocal[] localChangeNotifications,
+ bool isFlowSuppressed)
+ {
+ m_localValues = localValues;
+ m_localChangeNotifications = localChangeNotifications;
+ m_isFlowSuppressed = isFlowSuppressed;
+ }
+
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
+ throw new ArgumentNullException(nameof(info));
+ }
+ Contract.EndContractBlock();
+ }
+
+ private ExecutionContext(SerializationInfo info, StreamingContext context)
+ {
+ }
+
+ public static ExecutionContext Capture()
+ {
+ ExecutionContext executionContext = Thread.CurrentThread.ExecutionContext;
+ return
+ executionContext == null ? Default :
+ executionContext.m_isFlowSuppressed ? null :
+ executionContext;
+ }
+
+ private ExecutionContext ShallowClone(bool isFlowSuppressed)
+ {
+ Debug.Assert(isFlowSuppressed != m_isFlowSuppressed);
+
+ if (!isFlowSuppressed &&
+ m_localValues == Default.m_localValues &&
+ m_localChangeNotifications == Default.m_localChangeNotifications)
+ {
+ return null; // implies the default context
+ }
+ return new ExecutionContext(m_localValues, m_localChangeNotifications, isFlowSuppressed);
+ }
+
+ public static AsyncFlowControl SuppressFlow()
+ {
+ Thread currentThread = Thread.CurrentThread;
+ ExecutionContext executionContext = currentThread.ExecutionContext ?? Default;
+ if (executionContext.m_isFlowSuppressed)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_CannotSupressFlowMultipleTimes);
+ }
+ Contract.EndContractBlock();
+
+ executionContext = executionContext.ShallowClone(isFlowSuppressed: true);
+ var asyncFlowControl = new AsyncFlowControl();
+ currentThread.ExecutionContext = executionContext;
+ asyncFlowControl.Initialize(currentThread);
+ return asyncFlowControl;
+ }
+
+ public static void RestoreFlow()
+ {
+ Thread currentThread = Thread.CurrentThread;
+ ExecutionContext executionContext = currentThread.ExecutionContext;
+ if (executionContext == null || !executionContext.m_isFlowSuppressed)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_CannotRestoreUnsupressedFlow);
+ }
+ Contract.EndContractBlock();
+
+ currentThread.ExecutionContext = executionContext.ShallowClone(isFlowSuppressed: false);
+ }
+
+ public static bool IsFlowSuppressed()
+ {
+ ExecutionContext executionContext = Thread.CurrentThread.ExecutionContext;
+ return executionContext != null && executionContext.m_isFlowSuppressed;
+ }
+
+ public static void Run(ExecutionContext executionContext, ContextCallback callback, Object state)
+ {
+ if (executionContext == null)
+ throw new InvalidOperationException(SR.InvalidOperation_NullContext);
+
+ Thread currentThread = Thread.CurrentThread;
+ ExecutionContextSwitcher ecsw = default(ExecutionContextSwitcher);
+ try
+ {
+ EstablishCopyOnWriteScope(currentThread, ref ecsw);
+ ExecutionContext.Restore(currentThread, executionContext);
+ callback(state);
+ }
+ catch
+ {
+ // Note: we have a "catch" rather than a "finally" because we want
+ // to stop the first pass of EH here. That way we can restore the previous
+ // context before any of our callers' EH filters run. That means we need to
+ // end the scope separately in the non-exceptional case below.
+ ecsw.Undo(currentThread);
+ throw;
+ }
+ ecsw.Undo(currentThread);
+ }
+
+ internal static void Restore(Thread currentThread, ExecutionContext executionContext)
+ {
+ Debug.Assert(currentThread == Thread.CurrentThread);
+
+ ExecutionContext previous = currentThread.ExecutionContext ?? Default;
+ currentThread.ExecutionContext = executionContext;
+
+ // New EC could be null if that's what ECS.Undo saved off.
+ // For the purposes of dealing with context change, treat this as the default EC
+ executionContext = executionContext ?? Default;
+
+ if (previous != executionContext)
+ {
+ OnContextChanged(previous, executionContext);
+ }
+ }
+
+ internal static void EstablishCopyOnWriteScope(Thread currentThread, ref ExecutionContextSwitcher ecsw)
+ {
+ Debug.Assert(currentThread == Thread.CurrentThread);
+
+ ecsw.m_ec = currentThread.ExecutionContext;
+ ecsw.m_sc = currentThread.SynchronizationContext;
+ }
+
+ private static void OnContextChanged(ExecutionContext previous, ExecutionContext current)
+ {
+ Debug.Assert(previous != null);
+ Debug.Assert(current != null);
+ Debug.Assert(previous != current);
+
+ foreach (IAsyncLocal local in previous.m_localChangeNotifications)
+ {
+ object previousValue;
+ object currentValue;
+ previous.m_localValues.TryGetValue(local, out previousValue);
+ current.m_localValues.TryGetValue(local, out currentValue);
+
+ if (previousValue != currentValue)
+ local.OnValueChanged(previousValue, currentValue, true);
+ }
+
+ if (current.m_localChangeNotifications != previous.m_localChangeNotifications)
+ {
+ try
+ {
+ foreach (IAsyncLocal local in current.m_localChangeNotifications)
+ {
+ // If the local has a value in the previous context, we already fired the event for that local
+ // in the code above.
+ object previousValue;
+ if (!previous.m_localValues.TryGetValue(local, out previousValue))
+ {
+ object currentValue;
+ current.m_localValues.TryGetValue(local, out currentValue);
+
+ if (previousValue != currentValue)
+ local.OnValueChanged(previousValue, currentValue, true);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Environment.FailFast(
+ SR.ExecutionContext_ExceptionInAsyncLocalNotification,
+ ex);
+ }
+ }
+ }
+
+ internal static object GetLocalValue(IAsyncLocal local)
+ {
+ ExecutionContext current = Thread.CurrentThread.ExecutionContext;
+ if (current == null)
+ return null;
+
+ object value;
+ current.m_localValues.TryGetValue(local, out value);
+ return value;
+ }
+
+ internal static void SetLocalValue(IAsyncLocal local, object newValue, bool needChangeNotifications)
+ {
+ ExecutionContext current = Thread.CurrentThread.ExecutionContext ?? ExecutionContext.Default;
+
+ object previousValue;
+ bool hadPreviousValue = current.m_localValues.TryGetValue(local, out previousValue);
+
+ if (previousValue == newValue)
+ return;
+
+ IAsyncLocalValueMap newValues = current.m_localValues.Set(local, newValue);
+
+ //
+ // Either copy the change notification array, or create a new one, depending on whether we need to add a new item.
+ //
+ IAsyncLocal[] newChangeNotifications = current.m_localChangeNotifications;
+ if (needChangeNotifications)
+ {
+ if (hadPreviousValue)
+ {
+ Debug.Assert(Array.IndexOf(newChangeNotifications, local) >= 0);
+ }
+ else
+ {
+ int newNotificationIndex = newChangeNotifications.Length;
+ Array.Resize(ref newChangeNotifications, newNotificationIndex + 1);
+ newChangeNotifications[newNotificationIndex] = local;
+ }
+ }
+
+ Thread.CurrentThread.ExecutionContext =
+ new ExecutionContext(newValues, newChangeNotifications, current.m_isFlowSuppressed);
+
+ if (needChangeNotifications)
+ {
+ local.OnValueChanged(previousValue, newValue, false);
+ }
+ }
+
+ public ExecutionContext CreateCopy()
+ {
+ return this; // since CoreCLR's ExecutionContext is immutable, we don't need to create copies.
+ }
+
+ public void Dispose()
+ {
+ // For CLR compat only
+ }
+ }
+
+ public struct AsyncFlowControl : IDisposable
+ {
+ private Thread _thread;
+
+ internal void Initialize(Thread currentThread)
+ {
+ Debug.Assert(currentThread == Thread.CurrentThread);
+ _thread = currentThread;
+ }
+
+ public void Undo()
+ {
+ if (_thread == null)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_CannotUseAFCMultiple);
+ }
+ if (Thread.CurrentThread != _thread)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_CannotUseAFCOtherThread);
+ }
+
+ // An async flow control cannot be undone when a different execution context is applied. The desktop framework
+ // mutates the execution context when its state changes, and only changes the instance when an execution context
+ // is applied (for instance, through ExecutionContext.Run). The framework prevents a suppressed-flow execution
+ // context from being applied by returning null from ExecutionContext.Capture, so the only type of execution
+ // context that can be applied is one whose flow is not suppressed. After suppressing flow and changing an async
+ // local's value, the desktop framework verifies that a different execution context has not been applied by
+ // checking the execution context instance against the one saved from when flow was suppressed. In .NET Core,
+ // since the execution context instance will change after changing the async local's value, it verifies that a
+ // different execution context has not been applied, by instead ensuring that the current execution context's
+ // flow is suppressed.
+ if (!ExecutionContext.IsFlowSuppressed())
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_AsyncFlowCtrlCtxMismatch);
+ }
+ Contract.EndContractBlock();
+
+ _thread = null;
+ ExecutionContext.RestoreFlow();
+ }
+
+ public void Dispose()
+ {
+ Undo();
+ }
+
+ public override bool Equals(object obj)
+ {
+ return obj is AsyncFlowControl && Equals((AsyncFlowControl)obj);
+ }
+
+ public bool Equals(AsyncFlowControl obj)
+ {
+ return _thread == obj._thread;
+ }
+
+ public override int GetHashCode()
+ {
+ return _thread?.GetHashCode() ?? 0;
+ }
+
+ public static bool operator ==(AsyncFlowControl a, AsyncFlowControl b)
+ {
+ return a.Equals(b);
+ }
+
+ public static bool operator !=(AsyncFlowControl a, AsyncFlowControl b)
+ {
+ return !(a == b);
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/LazyThreadSafetyMode.cs b/src/mscorlib/shared/System/Threading/LazyThreadSafetyMode.cs
new file mode 100644
index 0000000000..2d13f23762
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/LazyThreadSafetyMode.cs
@@ -0,0 +1,44 @@
+// 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.
+
+// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+//
+// a set of lightweight static helpers for lazy initialization.
+//
+// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+namespace System.Threading
+{
+ /// <summary>
+ /// Specifies how a <see cref="T:System.Threading.Lazy{T}"/> instance should synchronize access among multiple threads.
+ /// </summary>
+ public enum LazyThreadSafetyMode
+ {
+ /// <summary>
+ /// This mode makes no guarantees around the thread-safety of the <see cref="T:System.Threading.Lazy{T}"/> instance. If used from multiple threads, the behavior of the <see cref="T:System.Threading.Lazy{T}"/> is undefined.
+ /// This mode should be used when a <see cref="T:System.Threading.Lazy{T}"/> is guaranteed to never be initialized from more than one thread simultaneously and high performance is crucial.
+ /// If valueFactory throws an exception when the <see cref="T:System.Threading.Lazy{T}"/> is initialized, the exception will be cached and returned on subsequent accesses to Value. Also, if valueFactory recursively
+ /// accesses Value on this <see cref="T:System.Threading.Lazy{T}"/> instance, a <see cref="T:System.InvalidOperationException"/> will be thrown.
+ /// </summary>
+ None,
+
+ /// <summary>
+ /// When multiple threads attempt to simultaneously initialize a <see cref="T:System.Threading.Lazy{T}"/> instance, this mode allows each thread to execute the
+ /// valueFactory but only the first thread to complete initialization will be allowed to set the final value of the <see cref="T:System.Threading.Lazy{T}"/>.
+ /// Once initialized successfully, any future calls to Value will return the cached result. If valueFactory throws an exception on any thread, that exception will be
+ /// propagated out of Value. If any thread executes valueFactory without throwing an exception and, therefore, successfully sets the value, that value will be returned on
+ /// subsequent accesses to Value from any thread. If no thread succeeds in setting the value, IsValueCreated will remain false and subsequent accesses to Value will result in
+ /// the valueFactory delegate re-executing. Also, if valueFactory recursively accesses Value on this <see cref="T:System.Threading.Lazy{T}"/> instance, an exception will NOT be thrown.
+ /// </summary>
+ PublicationOnly,
+
+ /// <summary>
+ /// This mode uses locks to ensure that only a single thread can initialize a <see cref="T:System.Threading.Lazy{T}"/> instance in a thread-safe manner. In general,
+ /// taken if this mode is used in conjunction with a <see cref="T:System.Threading.Lazy{T}"/> valueFactory delegate that uses locks internally, a deadlock can occur if not
+ /// handled carefully. If valueFactory throws an exception when the<see cref="T:System.Threading.Lazy{T}"/> is initialized, the exception will be cached and returned on
+ /// subsequent accesses to Value. Also, if valueFactory recursively accesses Value on this <see cref="T:System.Threading.Lazy{T}"/> instance, a <see cref="T:System.InvalidOperationException"/> will be thrown.
+ /// </summary>
+ ExecutionAndPublication
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/LockRecursionException.cs b/src/mscorlib/shared/System/Threading/LockRecursionException.cs
new file mode 100644
index 0000000000..2f296cb14e
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/LockRecursionException.cs
@@ -0,0 +1,29 @@
+// 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.Serialization;
+
+namespace System.Threading
+{
+ [Serializable]
+ public class LockRecursionException : System.Exception
+ {
+ public LockRecursionException()
+ {
+ }
+
+ public LockRecursionException(string message)
+ : base(message)
+ {
+ }
+
+ public LockRecursionException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+
+ protected LockRecursionException(SerializationInfo info, StreamingContext context) : base(info, context) { }
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/ManualResetEvent.cs b/src/mscorlib/shared/System/Threading/ManualResetEvent.cs
new file mode 100644
index 0000000000..4b8d61f960
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/ManualResetEvent.cs
@@ -0,0 +1,12 @@
+// 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.
+
+namespace System.Threading
+{
+ public sealed class ManualResetEvent : EventWaitHandle
+ {
+ public ManualResetEvent(bool initialState) : base(initialState, EventResetMode.ManualReset) { }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Threading/ParameterizedThreadStart.cs b/src/mscorlib/shared/System/Threading/ParameterizedThreadStart.cs
new file mode 100644
index 0000000000..c0f29e8e80
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/ParameterizedThreadStart.cs
@@ -0,0 +1,18 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: This class is a Delegate which defines the start method
+** for starting a thread. That method must match this delegate.
+**
+**
+=============================================================================*/
+
+namespace System.Threading
+{
+ public delegate void ParameterizedThreadStart(object obj);
+}
diff --git a/src/mscorlib/shared/System/Threading/SemaphoreFullException.cs b/src/mscorlib/shared/System/Threading/SemaphoreFullException.cs
new file mode 100644
index 0000000000..19ac19d6e0
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/SemaphoreFullException.cs
@@ -0,0 +1,29 @@
+// 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.Serialization;
+
+namespace System.Threading
+{
+ [Serializable]
+ public class SemaphoreFullException : SystemException
+ {
+ public SemaphoreFullException() : base(SR.Threading_SemaphoreFullException)
+ {
+ }
+
+ public SemaphoreFullException(String message) : base(message)
+ {
+ }
+
+ public SemaphoreFullException(String message, Exception innerException) : base(message, innerException)
+ {
+ }
+
+ protected SemaphoreFullException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/SendOrPostCallback.cs b/src/mscorlib/shared/System/Threading/SendOrPostCallback.cs
new file mode 100644
index 0000000000..6692d35ab2
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/SendOrPostCallback.cs
@@ -0,0 +1,8 @@
+// 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.
+
+namespace System.Threading
+{
+ public delegate void SendOrPostCallback(Object state);
+}
diff --git a/src/mscorlib/shared/System/Threading/SynchronizationLockException.cs b/src/mscorlib/shared/System/Threading/SynchronizationLockException.cs
new file mode 100644
index 0000000000..120577fdcf
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/SynchronizationLockException.cs
@@ -0,0 +1,44 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: Wait(), Notify() or NotifyAll() was called from an unsynchronized
+** block of code.
+**
+**
+=============================================================================*/
+
+using System.Runtime.Serialization;
+
+namespace System.Threading
+{
+ [Serializable]
+ public class SynchronizationLockException : SystemException
+ {
+ public SynchronizationLockException()
+ : base(SR.Arg_SynchronizationLockException)
+ {
+ HResult = __HResults.COR_E_SYNCHRONIZATIONLOCK;
+ }
+
+ public SynchronizationLockException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_SYNCHRONIZATIONLOCK;
+ }
+
+ public SynchronizationLockException(String message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_SYNCHRONIZATIONLOCK;
+ }
+
+ protected SynchronizationLockException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/Tasks/TaskCanceledException.cs b/src/mscorlib/shared/System/Threading/Tasks/TaskCanceledException.cs
new file mode 100644
index 0000000000..d7690d4c7c
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/Tasks/TaskCanceledException.cs
@@ -0,0 +1,89 @@
+// 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.
+
+// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+//
+//
+//
+// An exception for task cancellations.
+//
+// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+
+namespace System.Threading.Tasks
+{
+ /// <summary>
+ /// Represents an exception used to communicate task cancellation.
+ /// </summary>
+ [Serializable]
+ public class TaskCanceledException : OperationCanceledException
+ {
+ [NonSerialized]
+ private Task m_canceledTask; // The task which has been canceled.
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskCanceledException"/> class.
+ /// </summary>
+ public TaskCanceledException() : base(SR.TaskCanceledException_ctor_DefaultMessage)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskCanceledException"/>
+ /// class with a specified error message.
+ /// </summary>
+ /// <param name="message">The error message that explains the reason for the exception.</param>
+ public TaskCanceledException(string message) : base(message)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskCanceledException"/>
+ /// class with a specified error message and a reference to the inner exception that is the cause of
+ /// this exception.
+ /// </summary>
+ /// <param name="message">The error message that explains the reason for the exception.</param>
+ /// <param name="innerException">The exception that is the cause of the current exception.</param>
+ public TaskCanceledException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskCanceledException"/> class
+ /// with a reference to the <see cref="T:System.Threading.Tasks.Task"/> that has been canceled.
+ /// </summary>
+ /// <param name="task">A task that has been canceled.</param>
+ public TaskCanceledException(Task task) :
+ base(SR.TaskCanceledException_ctor_DefaultMessage, task != null ? task.CancellationToken : new CancellationToken())
+ {
+ m_canceledTask = task;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskCanceledException"/>
+ /// class with serialized data.
+ /// </summary>
+ /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
+ /// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination. </param>
+ protected TaskCanceledException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ }
+
+ /// <summary>
+ /// Gets the task associated with this exception.
+ /// </summary>
+ /// <remarks>
+ /// It is permissible for no Task to be associated with a
+ /// <see cref="T:System.Threading.Tasks.TaskCanceledException"/>, in which case
+ /// this property will return null.
+ /// </remarks>
+ public Task Task
+ {
+ get { return m_canceledTask; }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/Tasks/TaskExtensions.cs b/src/mscorlib/shared/System/Threading/Tasks/TaskExtensions.cs
new file mode 100644
index 0000000000..1098299517
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/Tasks/TaskExtensions.cs
@@ -0,0 +1,48 @@
+// 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.
+
+namespace System.Threading.Tasks
+{
+ /// <summary>Provides a set of static methods for working with specific kinds of <see cref="Task"/> instances.</summary>
+ public static class TaskExtensions
+ {
+ /// <summary>Creates a proxy <see cref="Task"/> that represents the asynchronous operation of a <see cref="Task{Task}"/>.</summary>
+ /// <param name="task">The <see cref="Task{Task}"/> to unwrap.</param>
+ /// <returns>A <see cref="Task"/> that represents the asynchronous operation of the provided <see cref="Task{Task}"/>.</returns>
+ public static Task Unwrap(this Task<Task> task)
+ {
+ if (task == null)
+ {
+ throw new ArgumentNullException(nameof(task));
+ }
+
+ // If the task hasn't completed or was faulted/canceled, wrap it in an unwrap promise. Otherwise,
+ // it completed successfully. Return its inner task to avoid unnecessary wrapping, or if the inner
+ // task is null, return a canceled task to match the same semantics as CreateUnwrapPromise.
+ return
+ !task.IsRanToCompletion ? Task.CreateUnwrapPromise<VoidTaskResult>(task, lookForOce: false) :
+ task.Result ??
+ Task.FromCanceled(new CancellationToken(true));
+ }
+
+ /// <summary>Creates a proxy <see cref="Task{TResult}"/> that represents the asynchronous operation of a <see cref="Task{Task{TResult}}"/>.</summary>
+ /// <param name="task">The <see cref="Task{Task{TResult}}"/> to unwrap.</param>
+ /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous operation of the provided <see cref="Task{Task{TResult}}"/>.</returns>
+ public static Task<TResult> Unwrap<TResult>(this Task<Task<TResult>> task)
+ {
+ if (task == null)
+ {
+ throw new ArgumentNullException(nameof(task));
+ }
+
+ // If the task hasn't completed or was faulted/canceled, wrap it in an unwrap promise. Otherwise,
+ // it completed successfully. Return its inner task to avoid unnecessary wrapping, or if the inner
+ // task is null, return a canceled task to match the same semantics as CreateUnwrapPromise.
+ return
+ !task.IsRanToCompletion ? Task.CreateUnwrapPromise<TResult>(task, lookForOce: false) :
+ task.Result ??
+ Task.FromCanceled<TResult>(new CancellationToken(true));
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/Tasks/TaskSchedulerException.cs b/src/mscorlib/shared/System/Threading/Tasks/TaskSchedulerException.cs
new file mode 100644
index 0000000000..148b6300ef
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/Tasks/TaskSchedulerException.cs
@@ -0,0 +1,77 @@
+// 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.
+
+// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+//
+//
+//
+// An exception for task schedulers.
+//
+// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+
+namespace System.Threading.Tasks
+{
+ /// <summary>
+ /// Represents an exception used to communicate an invalid operation by a
+ /// <see cref="T:System.Threading.Tasks.TaskScheduler"/>.
+ /// </summary>
+ [Serializable]
+ public class TaskSchedulerException : Exception
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskSchedulerException"/> class.
+ /// </summary>
+ public TaskSchedulerException() : base(SR.TaskSchedulerException_ctor_DefaultMessage) //
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskSchedulerException"/>
+ /// class with a specified error message.
+ /// </summary>
+ /// <param name="message">The error message that explains the reason for the exception.</param>
+ public TaskSchedulerException(string message) : base(message)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskSchedulerException"/>
+ /// class using the default error message and a reference to the inner exception that is the cause of
+ /// this exception.
+ /// </summary>
+ /// <param name="innerException">The exception that is the cause of the current exception.</param>
+ public TaskSchedulerException(Exception innerException)
+ : base(SR.TaskSchedulerException_ctor_DefaultMessage, innerException)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskSchedulerException"/>
+ /// class with a specified error message and a reference to the inner exception that is the cause of
+ /// this exception.
+ /// </summary>
+ /// <param name="message">The error message that explains the reason for the exception.</param>
+ /// <param name="innerException">The exception that is the cause of the current exception.</param>
+ public TaskSchedulerException(string message, Exception innerException) : base(message, innerException)
+ {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskSchedulerException"/>
+ /// class with serialized data.
+ /// </summary>
+ /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds
+ /// the serialized object data about the exception being thrown.</param>
+ /// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that
+ /// contains contextual information about the source or destination. </param>
+ protected TaskSchedulerException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/ThreadAbortException.cs b/src/mscorlib/shared/System/Threading/ThreadAbortException.cs
new file mode 100644
index 0000000000..e693e7192f
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/ThreadAbortException.cs
@@ -0,0 +1,36 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: An exception class which is thrown into a thread to cause it to
+** abort. This is a special non-catchable exception and results in
+** the thread's death. This is thrown by the VM only and can NOT be
+** thrown by any user thread, and subclassing this is useless.
+**
+**
+=============================================================================*/
+
+using System.Runtime.Serialization;
+
+namespace System.Threading
+{
+ [Serializable]
+ public sealed class ThreadAbortException : SystemException
+ {
+ private ThreadAbortException()
+ {
+ HResult = __HResults.COR_E_THREADABORTED;
+ }
+
+ internal ThreadAbortException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+
+ public object ExceptionState => null;
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/ThreadPriority.cs b/src/mscorlib/shared/System/Threading/ThreadPriority.cs
new file mode 100644
index 0000000000..3b34bd5eac
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/ThreadPriority.cs
@@ -0,0 +1,18 @@
+// 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.
+
+namespace System.Threading
+{
+ public enum ThreadPriority
+ {
+ /*=========================================================================
+ ** Constants for thread priorities.
+ =========================================================================*/
+ Lowest = 0,
+ BelowNormal = 1,
+ Normal = 2,
+ AboveNormal = 3,
+ Highest = 4
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/ThreadStart.cs b/src/mscorlib/shared/System/Threading/ThreadStart.cs
new file mode 100644
index 0000000000..5532539fc7
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/ThreadStart.cs
@@ -0,0 +1,18 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: This class is a Delegate which defines the start method
+** for starting a thread. That method must match this delegate.
+**
+**
+=============================================================================*/
+
+namespace System.Threading
+{
+ public delegate void ThreadStart();
+}
diff --git a/src/mscorlib/shared/System/Threading/ThreadStartException.cs b/src/mscorlib/shared/System/Threading/ThreadStartException.cs
new file mode 100644
index 0000000000..2ff77bc5fd
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/ThreadStartException.cs
@@ -0,0 +1,29 @@
+// 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.Runtime.Serialization;
+
+namespace System.Threading
+{
+ [Serializable]
+ public sealed class ThreadStartException : SystemException
+ {
+ internal ThreadStartException()
+ : base(SR.Arg_ThreadStartException)
+ {
+ HResult = __HResults.COR_E_THREADSTART;
+ }
+
+ internal ThreadStartException(Exception reason)
+ : base(SR.Arg_ThreadStartException, reason)
+ {
+ HResult = __HResults.COR_E_THREADSTART;
+ }
+
+ internal ThreadStartException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/ThreadState.cs b/src/mscorlib/shared/System/Threading/ThreadState.cs
new file mode 100644
index 0000000000..4bf3b5184d
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/ThreadState.cs
@@ -0,0 +1,24 @@
+// 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.
+
+namespace System.Threading
+{
+ [Flags]
+ public enum ThreadState
+ {
+ /*=========================================================================
+ ** Constants for thread states.
+ =========================================================================*/
+ Running = 0,
+ StopRequested = 1,
+ SuspendRequested = 2,
+ Background = 4,
+ Unstarted = 8,
+ Stopped = 16,
+ WaitSleepJoin = 32,
+ Suspended = 64,
+ AbortRequested = 128,
+ Aborted = 256
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/ThreadStateException.cs b/src/mscorlib/shared/System/Threading/ThreadStateException.cs
new file mode 100644
index 0000000000..33bc8baee6
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/ThreadStateException.cs
@@ -0,0 +1,45 @@
+// 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.
+
+/*=============================================================================
+**
+**
+**
+** Purpose: An exception class to indicate that the Thread class is in an
+** invalid state for the method.
+**
+**
+=============================================================================*/
+
+using System.Runtime.Serialization;
+
+namespace System.Threading
+{
+ [Serializable]
+ public class ThreadStateException : SystemException
+ {
+ public ThreadStateException()
+ : base(SR.Arg_ThreadStateException)
+ {
+ HResult = __HResults.COR_E_THREADSTATE;
+ }
+
+ public ThreadStateException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_THREADSTATE;
+ }
+
+ public ThreadStateException(String message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_THREADSTATE;
+ }
+
+ protected ThreadStateException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/Timeout.cs b/src/mscorlib/shared/System/Threading/Timeout.cs
new file mode 100644
index 0000000000..df1ea5f2bc
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/Timeout.cs
@@ -0,0 +1,20 @@
+// 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.Threading;
+using System;
+
+namespace System.Threading
+{
+ // A constant used by methods that take a timeout (Object.Wait, Thread.Sleep
+ // etc) to indicate that no timeout should occur.
+ //
+ public static class Timeout
+ {
+ public static readonly TimeSpan InfiniteTimeSpan = new TimeSpan(0, 0, 0, 0, Timeout.Infinite);
+
+ public const int Infinite = -1;
+ internal const uint UnsignedInfinite = unchecked((uint)-1);
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/TimeoutHelper.cs b/src/mscorlib/shared/System/Threading/TimeoutHelper.cs
new file mode 100644
index 0000000000..c66c9add92
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/TimeoutHelper.cs
@@ -0,0 +1,54 @@
+// 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.Diagnostics;
+
+namespace System.Threading
+{
+ /// <summary>
+ /// A helper class to capture a start time using Environment.TickCout as a time in milliseconds, also updates a given timeout bu subtracting the current time from
+ /// the start time
+ /// </summary>
+ internal static class TimeoutHelper
+ {
+ /// <summary>
+ /// Returns the Environment.TickCount as a start time in milliseconds as a uint, TickCount tools over from postive to negative every ~ 25 days
+ /// then ~25 days to back to positive again, uint is sued to ignore the sign and double the range to 50 days
+ /// </summary>
+ /// <returns></returns>
+ public static uint GetTime()
+ {
+ return (uint)Environment.TickCount;
+ }
+
+ /// <summary>
+ /// Helper function to measure and update the elapsed time
+ /// </summary>
+ /// <param name="startTime"> The first time (in milliseconds) observed when the wait started</param>
+ /// <param name="originalWaitMillisecondsTimeout">The orginal wait timeoutout in milliseconds</param>
+ /// <returns>The new wait time in milliseconds, -1 if the time expired</returns>
+ public static int UpdateTimeOut(uint startTime, int originalWaitMillisecondsTimeout)
+ {
+ // The function must be called in case the time out is not infinite
+ Debug.Assert(originalWaitMillisecondsTimeout != Timeout.Infinite);
+
+ uint elapsedMilliseconds = (GetTime() - startTime);
+
+ // Check the elapsed milliseconds is greater than max int because this property is uint
+ if (elapsedMilliseconds > int.MaxValue)
+ {
+ return 0;
+ }
+
+ // Subtract the elapsed time from the current wait time
+ int currentWaitTimeout = originalWaitMillisecondsTimeout - (int)elapsedMilliseconds; ;
+ if (currentWaitTimeout <= 0)
+ {
+ return 0;
+ }
+
+ return currentWaitTimeout;
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Threading/WaitHandleCannotBeOpenedException.cs b/src/mscorlib/shared/System/Threading/WaitHandleCannotBeOpenedException.cs
new file mode 100644
index 0000000000..e44946a669
--- /dev/null
+++ b/src/mscorlib/shared/System/Threading/WaitHandleCannotBeOpenedException.cs
@@ -0,0 +1,31 @@
+// 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.Runtime.Serialization;
+
+namespace System.Threading
+{
+ [Serializable]
+ public class WaitHandleCannotBeOpenedException : ApplicationException
+ {
+ public WaitHandleCannotBeOpenedException() : base(SR.Threading_WaitHandleCannotBeOpenedException)
+ {
+ HResult = __HResults.COR_E_WAITHANDLECANNOTBEOPENED;
+ }
+
+ public WaitHandleCannotBeOpenedException(String message) : base(message)
+ {
+ HResult = __HResults.COR_E_WAITHANDLECANNOTBEOPENED;
+ }
+
+ public WaitHandleCannotBeOpenedException(String message, Exception innerException) : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_WAITHANDLECANNOTBEOPENED;
+ }
+
+ protected WaitHandleCannotBeOpenedException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/TimeZone.cs b/src/mscorlib/shared/System/TimeZone.cs
new file mode 100644
index 0000000000..88e2e21864
--- /dev/null
+++ b/src/mscorlib/shared/System/TimeZone.cs
@@ -0,0 +1,281 @@
+// 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.
+
+/*============================================================
+**
+**
+**
+** Purpose:
+** This class is used to represent a TimeZone. It
+** has methods for converting a DateTime to UTC from local time
+** and to local time from UTC and methods for getting the
+** standard name and daylight name of the time zone.
+**
+** The only TimeZone that we support in version 1 is the
+** CurrentTimeZone as determined by the system timezone.
+**
+**
+============================================================*/
+
+using System;
+using System.Text;
+using System.Threading;
+using System.Collections;
+using System.Globalization;
+
+namespace System
+{
+ [Serializable]
+ [Obsolete("System.TimeZone has been deprecated. Please investigate the use of System.TimeZoneInfo instead.")]
+ public abstract class TimeZone
+ {
+ private static volatile TimeZone currentTimeZone = null;
+
+ // Private object for locking instead of locking on a public type for SQL reliability work.
+ private static Object s_InternalSyncObject;
+ private static Object InternalSyncObject
+ {
+ get
+ {
+ if (s_InternalSyncObject == null)
+ {
+ Object o = new Object();
+ Interlocked.CompareExchange<Object>(ref s_InternalSyncObject, o, null);
+ }
+ return s_InternalSyncObject;
+ }
+ }
+
+
+ protected TimeZone()
+ {
+ }
+
+ public static TimeZone CurrentTimeZone
+ {
+ get
+ {
+ //Grabbing the cached value is required at the top of this function so that
+ //we don't incur a race condition with the ResetTimeZone method below.
+ TimeZone tz = currentTimeZone;
+ if (tz == null)
+ {
+ lock (InternalSyncObject)
+ {
+ if (currentTimeZone == null)
+ {
+ currentTimeZone = new CurrentSystemTimeZone();
+ }
+ tz = currentTimeZone;
+ }
+ }
+ return (tz);
+ }
+ }
+
+ //This method is called by CultureInfo.ClearCachedData in response to control panel
+ //change events. It must be synchronized because otherwise there is a race condition
+ //with the CurrentTimeZone property above.
+ internal static void ResetTimeZone()
+ {
+ if (currentTimeZone != null)
+ {
+ lock (InternalSyncObject)
+ {
+ currentTimeZone = null;
+ }
+ }
+ }
+
+ public abstract String StandardName
+ {
+ get;
+ }
+
+ public abstract String DaylightName
+ {
+ get;
+ }
+
+ public abstract TimeSpan GetUtcOffset(DateTime time);
+
+ //
+ // Converts the specified datatime to the Universal time base on the current timezone
+ //
+ public virtual DateTime ToUniversalTime(DateTime time)
+ {
+ if (time.Kind == DateTimeKind.Utc)
+ {
+ return time;
+ }
+ long tickCount = time.Ticks - GetUtcOffset(time).Ticks;
+ if (tickCount > DateTime.MaxTicks)
+ {
+ return new DateTime(DateTime.MaxTicks, DateTimeKind.Utc);
+ }
+ if (tickCount < DateTime.MinTicks)
+ {
+ return new DateTime(DateTime.MinTicks, DateTimeKind.Utc);
+ }
+ return new DateTime(tickCount, DateTimeKind.Utc);
+ }
+
+ //
+ // Convert the specified datetime value from UTC to the local time based on the time zone.
+ //
+ public virtual DateTime ToLocalTime(DateTime time)
+ {
+ if (time.Kind == DateTimeKind.Local)
+ {
+ return time;
+ }
+ Boolean isAmbiguousLocalDst = false;
+ Int64 offset = ((CurrentSystemTimeZone)(TimeZone.CurrentTimeZone)).GetUtcOffsetFromUniversalTime(time, ref isAmbiguousLocalDst);
+ return new DateTime(time.Ticks + offset, DateTimeKind.Local, isAmbiguousLocalDst);
+ }
+
+ // Return an array of DaylightTime which reflects the daylight saving periods in a particular year.
+ // We currently only support having one DaylightSavingTime per year.
+ // If daylight saving time is not used in this timezone, null will be returned.
+ public abstract DaylightTime GetDaylightChanges(int year);
+
+ public virtual bool IsDaylightSavingTime(DateTime time)
+ {
+ return (IsDaylightSavingTime(time, GetDaylightChanges(time.Year)));
+ }
+
+ // Check if the specified time is in a daylight saving time. Allows the user to
+ // specify the array of Daylight Saving Times.
+ public static bool IsDaylightSavingTime(DateTime time, DaylightTime daylightTimes)
+ {
+ return CalculateUtcOffset(time, daylightTimes) != TimeSpan.Zero;
+ }
+
+ //
+ // NOTENOTE: Implementation detail
+ // In the transition from standard time to daylight saving time,
+ // if we convert local time to Universal time, we can have the
+ // following (take PST as an example):
+ // Local Universal UTC Offset
+ // ----- --------- ----------
+ // 01:00AM 09:00 -8:00
+ // 02:00 (=> 03:00) 10:00 -8:00 [This time doesn't actually exist, but it can be created from DateTime]
+ // 03:00 10:00 -7:00
+ // 04:00 11:00 -7:00
+ // 05:00 12:00 -7:00
+ //
+ // So from 02:00 - 02:59:59, we should return the standard offset, instead of the daylight saving offset.
+ //
+ // In the transition from daylight saving time to standard time,
+ // if we convert local time to Universal time, we can have the
+ // following (take PST as an example):
+ // Local Universal UTC Offset
+ // ----- --------- ----------
+ // 01:00AM 08:00 -7:00
+ // 02:00 (=> 01:00) 09:00 -8:00
+ // 02:00 10:00 -8:00
+ // 03:00 11:00 -8:00
+ // 04:00 12:00 -8:00
+ //
+ // So in this case, the 02:00 does exist after the first 2:00 rolls back to 01:00. We don't need to special case this.
+ // But note that there are two 01:00 in the local time.
+
+ //
+ // And imagine if the daylight saving offset is negative (although this does not exist in real life)
+ // In the transition from standard time to daylight saving time,
+ // if we convert local time to Universal time, we can have the
+ // following (take PST as an example, but the daylight saving offset is -01:00):
+ // Local Universal UTC Offset
+ // ----- --------- ----------
+ // 01:00AM 09:00 -8:00
+ // 02:00 (=> 01:00) 10:00 -9:00
+ // 02:00 11:00 -9:00
+ // 03:00 12:00 -9:00
+ // 04:00 13:00 -9:00
+ // 05:00 14:00 -9:00
+ //
+ // So in this case, the 02:00 does exist after the first 2:00 rolls back to 01:00. We don't need to special case this.
+ //
+ // In the transition from daylight saving time to standard time,
+ // if we convert local time to Universal time, we can have the
+ // following (take PST as an example, daylight saving offset is -01:00):
+ //
+ // Local Universal UTC Offset
+ // ----- --------- ----------
+ // 01:00AM 10:00 -9:00
+ // 02:00 (=> 03:00) 11:00 -9:00
+ // 03:00 11:00 -8:00
+ // 04:00 12:00 -8:00
+ // 05:00 13:00 -8:00
+ // 06:00 14:00 -8:00
+ //
+ // So from 02:00 - 02:59:59, we should return the daylight saving offset, instead of the standard offset.
+ //
+ internal static TimeSpan CalculateUtcOffset(DateTime time, DaylightTime daylightTimes)
+ {
+ if (daylightTimes == null)
+ {
+ return TimeSpan.Zero;
+ }
+ DateTimeKind kind = time.Kind;
+ if (kind == DateTimeKind.Utc)
+ {
+ return TimeSpan.Zero;
+ }
+
+ DateTime startTime;
+ DateTime endTime;
+
+ // startTime and endTime represent the period from either the start of DST to the end and includes the
+ // potentially overlapped times
+ startTime = daylightTimes.Start + daylightTimes.Delta;
+ endTime = daylightTimes.End;
+
+ // For normal time zones, the ambiguous hour is the last hour of daylight saving when you wind the
+ // clock back. It is theoretically possible to have a positive delta, (which would really be daylight
+ // reduction time), where you would have to wind the clock back in the begnning.
+ DateTime ambiguousStart;
+ DateTime ambiguousEnd;
+ if (daylightTimes.Delta.Ticks > 0)
+ {
+ ambiguousStart = endTime - daylightTimes.Delta;
+ ambiguousEnd = endTime;
+ }
+ else
+ {
+ ambiguousStart = startTime;
+ ambiguousEnd = startTime - daylightTimes.Delta;
+ }
+
+ Boolean isDst = false;
+ if (startTime > endTime)
+ {
+ // In southern hemisphere, the daylight saving time starts later in the year, and ends in the beginning of next year.
+ // Note, the summer in the southern hemisphere begins late in the year.
+ if (time >= startTime || time < endTime)
+ {
+ isDst = true;
+ }
+ }
+ else if (time >= startTime && time < endTime)
+ {
+ // In northern hemisphere, the daylight saving time starts in the middle of the year.
+ isDst = true;
+ }
+
+ // If this date was previously converted from a UTC date and we were able to detect that the local
+ // DateTime would be ambiguous, this data is stored in the DateTime to resolve this ambiguity.
+ if (isDst && time >= ambiguousStart && time < ambiguousEnd)
+ {
+ isDst = time.IsAmbiguousDaylightSavingTime();
+ }
+
+ if (isDst)
+ {
+ return daylightTimes.Delta;
+ }
+ return TimeSpan.Zero;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/TimeZoneNotFoundException.cs b/src/mscorlib/shared/System/TimeZoneNotFoundException.cs
index ee21c2524f..ee21c2524f 100644
--- a/src/mscorlib/src/System/TimeZoneNotFoundException.cs
+++ b/src/mscorlib/shared/System/TimeZoneNotFoundException.cs
diff --git a/src/mscorlib/src/System/TimeoutException.cs b/src/mscorlib/shared/System/TimeoutException.cs
index 32775a1c56..32775a1c56 100644
--- a/src/mscorlib/src/System/TimeoutException.cs
+++ b/src/mscorlib/shared/System/TimeoutException.cs
diff --git a/src/mscorlib/shared/System/TupleExtensions.cs b/src/mscorlib/shared/System/TupleExtensions.cs
new file mode 100644
index 0000000000..106a88a08b
--- /dev/null
+++ b/src/mscorlib/shared/System/TupleExtensions.cs
@@ -0,0 +1,930 @@
+// 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.ComponentModel;
+using System.Runtime.CompilerServices;
+
+namespace System
+{
+ /// <summary>
+ /// Provides extension methods for <see cref="Tuple"/> instances to interop with C# tuples features (deconstruction syntax, converting from and to <see cref="ValueTuple"/>).
+ /// </summary>
+ public static class TupleExtensions
+ {
+ #region Deconstruct
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 1 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1>(
+ this Tuple<T1> value,
+ out T1 item1)
+ {
+ item1 = value.Item1;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 2 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2>(
+ this Tuple<T1, T2> value,
+ out T1 item1, out T2 item2)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 3 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3>(
+ this Tuple<T1, T2, T3> value,
+ out T1 item1, out T2 item2, out T3 item3)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 4 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4>(
+ this Tuple<T1, T2, T3, T4> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 5 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5>(
+ this Tuple<T1, T2, T3, T4, T5> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 6 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6>(
+ this Tuple<T1, T2, T3, T4, T5, T6> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 7 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ item7 = value.Item7;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 8 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ item7 = value.Item7;
+ item8 = value.Rest.Item1;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 9 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9>> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ item7 = value.Item7;
+ item8 = value.Rest.Item1;
+ item9 = value.Rest.Item2;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 10 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10>> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ item7 = value.Item7;
+ item8 = value.Rest.Item1;
+ item9 = value.Rest.Item2;
+ item10 = value.Rest.Item3;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 11 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11>> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ item7 = value.Item7;
+ item8 = value.Rest.Item1;
+ item9 = value.Rest.Item2;
+ item10 = value.Rest.Item3;
+ item11 = value.Rest.Item4;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 12 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12>> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ item7 = value.Item7;
+ item8 = value.Rest.Item1;
+ item9 = value.Rest.Item2;
+ item10 = value.Rest.Item3;
+ item11 = value.Rest.Item4;
+ item12 = value.Rest.Item5;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 13 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13>> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ item7 = value.Item7;
+ item8 = value.Rest.Item1;
+ item9 = value.Rest.Item2;
+ item10 = value.Rest.Item3;
+ item11 = value.Rest.Item4;
+ item12 = value.Rest.Item5;
+ item13 = value.Rest.Item6;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 14 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14>> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ item7 = value.Item7;
+ item8 = value.Rest.Item1;
+ item9 = value.Rest.Item2;
+ item10 = value.Rest.Item3;
+ item11 = value.Rest.Item4;
+ item12 = value.Rest.Item5;
+ item13 = value.Rest.Item6;
+ item14 = value.Rest.Item7;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 15 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15>>> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ item7 = value.Item7;
+ item8 = value.Rest.Item1;
+ item9 = value.Rest.Item2;
+ item10 = value.Rest.Item3;
+ item11 = value.Rest.Item4;
+ item12 = value.Rest.Item5;
+ item13 = value.Rest.Item6;
+ item14 = value.Rest.Item7;
+ item15 = value.Rest.Rest.Item1;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 16 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16>>> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ item7 = value.Item7;
+ item8 = value.Rest.Item1;
+ item9 = value.Rest.Item2;
+ item10 = value.Rest.Item3;
+ item11 = value.Rest.Item4;
+ item12 = value.Rest.Item5;
+ item13 = value.Rest.Item6;
+ item14 = value.Rest.Item7;
+ item15 = value.Rest.Rest.Item1;
+ item16 = value.Rest.Rest.Item2;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 17 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17>>> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ item7 = value.Item7;
+ item8 = value.Rest.Item1;
+ item9 = value.Rest.Item2;
+ item10 = value.Rest.Item3;
+ item11 = value.Rest.Item4;
+ item12 = value.Rest.Item5;
+ item13 = value.Rest.Item6;
+ item14 = value.Rest.Item7;
+ item15 = value.Rest.Rest.Item1;
+ item16 = value.Rest.Rest.Item2;
+ item17 = value.Rest.Rest.Item3;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 18 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18>>> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ item7 = value.Item7;
+ item8 = value.Rest.Item1;
+ item9 = value.Rest.Item2;
+ item10 = value.Rest.Item3;
+ item11 = value.Rest.Item4;
+ item12 = value.Rest.Item5;
+ item13 = value.Rest.Item6;
+ item14 = value.Rest.Item7;
+ item15 = value.Rest.Rest.Item1;
+ item16 = value.Rest.Rest.Item2;
+ item17 = value.Rest.Rest.Item3;
+ item18 = value.Rest.Rest.Item4;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 19 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19>>> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ item7 = value.Item7;
+ item8 = value.Rest.Item1;
+ item9 = value.Rest.Item2;
+ item10 = value.Rest.Item3;
+ item11 = value.Rest.Item4;
+ item12 = value.Rest.Item5;
+ item13 = value.Rest.Item6;
+ item14 = value.Rest.Item7;
+ item15 = value.Rest.Rest.Item1;
+ item16 = value.Rest.Rest.Item2;
+ item17 = value.Rest.Rest.Item3;
+ item18 = value.Rest.Rest.Item4;
+ item19 = value.Rest.Rest.Item5;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 20 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20>>> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19, out T20 item20)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ item7 = value.Item7;
+ item8 = value.Rest.Item1;
+ item9 = value.Rest.Item2;
+ item10 = value.Rest.Item3;
+ item11 = value.Rest.Item4;
+ item12 = value.Rest.Item5;
+ item13 = value.Rest.Item6;
+ item14 = value.Rest.Item7;
+ item15 = value.Rest.Rest.Item1;
+ item16 = value.Rest.Rest.Item2;
+ item17 = value.Rest.Rest.Item3;
+ item18 = value.Rest.Rest.Item4;
+ item19 = value.Rest.Rest.Item5;
+ item20 = value.Rest.Rest.Item6;
+ }
+
+ /// <summary>
+ /// Deconstruct a properly nested <see cref="Tuple"/> with 21 elements.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20, T21>>> value,
+ out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19, out T20 item20, out T21 item21)
+ {
+ item1 = value.Item1;
+ item2 = value.Item2;
+ item3 = value.Item3;
+ item4 = value.Item4;
+ item5 = value.Item5;
+ item6 = value.Item6;
+ item7 = value.Item7;
+ item8 = value.Rest.Item1;
+ item9 = value.Rest.Item2;
+ item10 = value.Rest.Item3;
+ item11 = value.Rest.Item4;
+ item12 = value.Rest.Item5;
+ item13 = value.Rest.Item6;
+ item14 = value.Rest.Item7;
+ item15 = value.Rest.Rest.Item1;
+ item16 = value.Rest.Rest.Item2;
+ item17 = value.Rest.Rest.Item3;
+ item18 = value.Rest.Rest.Item4;
+ item19 = value.Rest.Rest.Item5;
+ item20 = value.Rest.Rest.Item6;
+ item21 = value.Rest.Rest.Item7;
+ }
+ #endregion
+
+ #region ToValueTuple
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 1 element.
+ /// </summary>
+ public static ValueTuple<T1>
+ ToValueTuple<T1>(
+ this Tuple<T1> value)
+ {
+ return ValueTuple.Create(value.Item1);
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 2 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2>
+ ToValueTuple<T1, T2>(
+ this Tuple<T1, T2> value)
+ {
+ return ValueTuple.Create(value.Item1, value.Item2);
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 3 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3>
+ ToValueTuple<T1, T2, T3>(
+ this Tuple<T1, T2, T3> value)
+ {
+ return ValueTuple.Create(value.Item1, value.Item2, value.Item3);
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 4 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4>
+ ToValueTuple<T1, T2, T3, T4>(
+ this Tuple<T1, T2, T3, T4> value)
+ {
+ return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4);
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 5 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5>
+ ToValueTuple<T1, T2, T3, T4, T5>(
+ this Tuple<T1, T2, T3, T4, T5> value)
+ {
+ return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5);
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 6 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6>
+ ToValueTuple<T1, T2, T3, T4, T5, T6>(
+ this Tuple<T1, T2, T3, T4, T5, T6> value)
+ {
+ return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6);
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 7 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7>
+ ToValueTuple<T1, T2, T3, T4, T5, T6, T7>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7> value)
+ {
+ return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7);
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 8 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8>>
+ ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>> value)
+ {
+ return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ ValueTuple.Create(value.Rest.Item1));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 9 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9>>
+ ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9>> value)
+ {
+ return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ ValueTuple.Create(value.Rest.Item1, value.Rest.Item2));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 10 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10>>
+ ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10>> value)
+ {
+ return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 11 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11>>
+ ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11>> value)
+ {
+ return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 12 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12>>
+ ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12>> value)
+ {
+ return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 13 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13>>
+ ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13>> value)
+ {
+ return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 14 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14>>
+ ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14>> value)
+ {
+ return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 15 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15>>>
+ ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15>>> value)
+ {
+ return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
+ ValueTuple.Create(value.Rest.Rest.Item1)));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 16 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16>>>
+ ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16>>> value)
+ {
+ return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
+ ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2)));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 17 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17>>>
+ ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17>>> value)
+ {
+ return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
+ ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3)));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 18 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18>>>
+ ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18>>> value)
+ {
+ return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
+ ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4)));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 19 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18, T19>>>
+ ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19>>> value)
+ {
+ return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
+ ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5)));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 20 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18, T19, T20>>>
+ ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20>>> value)
+ {
+ return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
+ ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6)));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 21 elements.
+ /// </summary>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18, T19, T20, T21>>>
+ ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(
+ this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20, T21>>> value)
+ {
+ return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
+ ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6, value.Rest.Rest.Item7)));
+ }
+ #endregion
+
+ #region ToTuple
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 1 element.
+ /// </summary>
+ public static Tuple<T1>
+ ToTuple<T1>(
+ this ValueTuple<T1> value)
+ {
+ return Tuple.Create(value.Item1);
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 2 elements.
+ /// </summary>
+ public static Tuple<T1, T2>
+ ToTuple<T1, T2>(
+ this ValueTuple<T1, T2> value)
+ {
+ return Tuple.Create(value.Item1, value.Item2);
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 3 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3>
+ ToTuple<T1, T2, T3>(
+ this ValueTuple<T1, T2, T3> value)
+ {
+ return Tuple.Create(value.Item1, value.Item2, value.Item3);
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 4 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4>
+ ToTuple<T1, T2, T3, T4>(
+ this ValueTuple<T1, T2, T3, T4> value)
+ {
+ return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4);
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 5 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5>
+ ToTuple<T1, T2, T3, T4, T5>(
+ this ValueTuple<T1, T2, T3, T4, T5> value)
+ {
+ return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5);
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 6 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6>
+ ToTuple<T1, T2, T3, T4, T5, T6>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6> value)
+ {
+ return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6);
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 7 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6, T7>
+ ToTuple<T1, T2, T3, T4, T5, T6, T7>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6, T7> value)
+ {
+ return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7);
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 8 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>>
+ ToTuple<T1, T2, T3, T4, T5, T6, T7, T8>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8>> value)
+ {
+ return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ Tuple.Create(value.Rest.Item1));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 9 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9>>
+ ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9>> value)
+ {
+ return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ Tuple.Create(value.Rest.Item1, value.Rest.Item2));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 10 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10>>
+ ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10>> value)
+ {
+ return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 11 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11>>
+ ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11>> value)
+ {
+ return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 12 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12>>
+ ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12>> value)
+ {
+ return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 13 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13>>
+ ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13>> value)
+ {
+ return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 14 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14>>
+ ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14>> value)
+ {
+ return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 15 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15>>>
+ ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15>>> value)
+ {
+ return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
+ Tuple.Create(value.Rest.Rest.Item1)));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 16 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16>>>
+ ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16>>> value)
+ {
+ return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
+ Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2)));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 17 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17>>>
+ ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17>>> value)
+ {
+ return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
+ Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3)));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 18 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18>>>
+ ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18>>> value)
+ {
+ return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
+ Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4)));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 19 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19>>>
+ ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18, T19>>> value)
+ {
+ return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
+ Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5)));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 20 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20>>>
+ ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18, T19, T20>>> value)
+ {
+ return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
+ Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6)));
+ }
+
+ /// <summary>
+ /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 21 elements.
+ /// </summary>
+ public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20, T21>>>
+ ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(
+ this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18, T19, T20, T21>>> value)
+ {
+ return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
+ CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
+ Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6, value.Rest.Rest.Item7)));
+ }
+ #endregion
+
+ private static ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> CreateLong<T1, T2, T3, T4, T5, T6, T7, TRest>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : struct, ITuple =>
+ new ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>(item1, item2, item3, item4, item5, item6, item7, rest);
+
+ private static Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> CreateLongRef<T1, T2, T3, T4, T5, T6, T7, TRest>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : ITuple =>
+ new Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>(item1, item2, item3, item4, item5, item6, item7, rest);
+ }
+}
diff --git a/src/mscorlib/shared/System/Type.Enum.cs b/src/mscorlib/shared/System/Type.Enum.cs
new file mode 100644
index 0000000000..4d82410383
--- /dev/null
+++ b/src/mscorlib/shared/System/Type.Enum.cs
@@ -0,0 +1,186 @@
+// 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.Reflection;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace System
+{
+ //
+ // This file collects a set of Enum-related apis that run when the Type is subclassed by an application.
+ // None of it runs on normal Type objects supplied by the runtime (as those types override these methods.)
+ //
+ // Since app-subclassed Types are "untrusted classes" that may or may not implement the complete surface area correctly,
+ // this code should be considered brittle and not changed lightly.
+ //
+ public abstract partial class Type
+ {
+ public virtual bool IsEnumDefined(object value)
+ {
+ if (value == null)
+ throw new ArgumentNullException(nameof(value));
+
+ if (!IsEnum)
+ throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
+
+ // Check if both of them are of the same type
+ Type valueType = value.GetType();
+
+ // If the value is an Enum then we need to extract the underlying value from it
+ if (valueType.IsEnum)
+ {
+ if (!valueType.IsEquivalentTo(this))
+ throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, valueType.ToString(), this.ToString()));
+
+ valueType = valueType.GetEnumUnderlyingType();
+ }
+
+ // If a string is passed in
+ if (valueType == typeof(string))
+ {
+ string[] names = GetEnumNames();
+ if (Array.IndexOf(names, value) >= 0)
+ return true;
+ else
+ return false;
+ }
+
+ // If an enum or integer value is passed in
+ if (Type.IsIntegerType(valueType))
+ {
+ Type underlyingType = GetEnumUnderlyingType();
+ // We cannot compare the types directly because valueType is always a runtime type but underlyingType might not be.
+ if (underlyingType.GetTypeCodeImpl() != valueType.GetTypeCodeImpl())
+ throw new ArgumentException(SR.Format(SR.Arg_EnumUnderlyingTypeAndObjectMustBeSameType, valueType.ToString(), underlyingType.ToString()));
+
+ Array values = GetEnumRawConstantValues();
+ return (BinarySearch(values, value) >= 0);
+ }
+ else
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
+ }
+ }
+
+ public virtual string GetEnumName(object value)
+ {
+ if (value == null)
+ throw new ArgumentNullException(nameof(value));
+
+ if (!IsEnum)
+ throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
+
+ Type valueType = value.GetType();
+
+ if (!(valueType.IsEnum || Type.IsIntegerType(valueType)))
+ throw new ArgumentException(SR.Arg_MustBeEnumBaseTypeOrEnum, nameof(value));
+
+ Array values = GetEnumRawConstantValues();
+ int index = BinarySearch(values, value);
+
+ if (index >= 0)
+ {
+ string[] names = GetEnumNames();
+ return names[index];
+ }
+
+ return null;
+ }
+
+ public virtual string[] GetEnumNames()
+ {
+ if (!IsEnum)
+ throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
+
+ string[] names;
+ Array values;
+ GetEnumData(out names, out values);
+ return names;
+ }
+
+
+ // Returns the enum values as an object array.
+ private Array GetEnumRawConstantValues()
+ {
+ string[] names;
+ Array values;
+ GetEnumData(out names, out values);
+ return values;
+ }
+
+ // This will return enumValues and enumNames sorted by the values.
+ private void GetEnumData(out string[] enumNames, out Array enumValues)
+ {
+ FieldInfo[] flds = GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
+
+ object[] values = new object[flds.Length];
+ string[] names = new string[flds.Length];
+
+ for (int i = 0; i < flds.Length; i++)
+ {
+ names[i] = flds[i].Name;
+ values[i] = flds[i].GetRawConstantValue();
+ }
+
+ // Insertion Sort these values in ascending order.
+ // We use this O(n^2) algorithm, but it turns out that most of the time the elements are already in sorted order and
+ // the common case performance will be faster than quick sorting this.
+ IComparer comparer = Comparer<object>.Default;
+ for (int i = 1; i < values.Length; i++)
+ {
+ int j = i;
+ string tempStr = names[i];
+ object val = values[i];
+ bool exchanged = false;
+
+ // Since the elements are sorted we only need to do one comparision, we keep the check for j inside the loop.
+ while (comparer.Compare(values[j - 1], val) > 0)
+ {
+ names[j] = names[j - 1];
+ values[j] = values[j - 1];
+ j--;
+ exchanged = true;
+ if (j == 0)
+ break;
+ }
+
+ if (exchanged)
+ {
+ names[j] = tempStr;
+ values[j] = val;
+ }
+ }
+
+ enumNames = names;
+ enumValues = values;
+ }
+
+ // Convert everything to ulong then perform a binary search.
+ private static int BinarySearch(Array array, object value)
+ {
+ ulong[] ulArray = new ulong[array.Length];
+ for (int i = 0; i < array.Length; ++i)
+ ulArray[i] = Enum.ToUInt64(array.GetValue(i));
+
+ ulong ulValue = Enum.ToUInt64(value);
+
+ return Array.BinarySearch(ulArray, ulValue);
+ }
+
+ internal static bool IsIntegerType(Type t)
+ {
+ return (t == typeof(int) ||
+ t == typeof(short) ||
+ t == typeof(ushort) ||
+ t == typeof(byte) ||
+ t == typeof(sbyte) ||
+ t == typeof(uint) ||
+ t == typeof(long) ||
+ t == typeof(ulong) ||
+ t == typeof(char) ||
+ t == typeof(bool));
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Type.Helpers.cs b/src/mscorlib/shared/System/Type.Helpers.cs
new file mode 100644
index 0000000000..db8df231e4
--- /dev/null
+++ b/src/mscorlib/shared/System/Type.Helpers.cs
@@ -0,0 +1,527 @@
+// 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.Reflection;
+
+namespace System
+{
+ // This file collects the longer methods of Type to make the main Type class more readable.
+ public abstract partial class Type : MemberInfo, IReflect
+ {
+ public virtual bool IsSerializable
+ {
+ get
+ {
+ if ((GetAttributeFlagsImpl() & TypeAttributes.Serializable) != 0)
+ return true;
+
+ Type underlyingType = UnderlyingSystemType;
+ if (underlyingType.IsRuntimeImplemented())
+ {
+ do
+ {
+ // In all sane cases we only need to compare the direct level base type with
+ // System.Enum and System.MulticastDelegate. However, a generic parameter can
+ // have a base type constraint that is Delegate or even a real delegate type.
+ // Let's maintain compatibility and return true for them.
+ if (underlyingType == typeof(Delegate) || underlyingType == typeof(Enum))
+ return true;
+
+ underlyingType = underlyingType.BaseType;
+ }
+ while (underlyingType != null);
+ }
+
+ return false;
+ }
+ }
+
+ public virtual bool ContainsGenericParameters
+ {
+ get
+ {
+ if (HasElementType)
+ return GetRootElementType().ContainsGenericParameters;
+
+ if (IsGenericParameter)
+ return true;
+
+ if (!IsGenericType)
+ return false;
+
+ Type[] genericArguments = GetGenericArguments();
+ for (int i = 0; i < genericArguments.Length; i++)
+ {
+ if (genericArguments[i].ContainsGenericParameters)
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ internal Type GetRootElementType()
+ {
+ Type rootElementType = this;
+
+ while (rootElementType.HasElementType)
+ rootElementType = rootElementType.GetElementType();
+
+ return rootElementType;
+ }
+
+ public bool IsVisible
+ {
+ get
+ {
+#if CORECLR
+ RuntimeType rt = this as RuntimeType;
+ if (rt != null)
+ return RuntimeTypeHandle.IsVisible(rt);
+#endif //CORECLR
+
+ if (IsGenericParameter)
+ return true;
+
+ if (HasElementType)
+ return GetElementType().IsVisible;
+
+ Type type = this;
+ while (type.IsNested)
+ {
+ if (!type.IsNestedPublic)
+ return false;
+
+ // this should be null for non-nested types.
+ type = type.DeclaringType;
+ }
+
+ // Now "type" should be a top level type
+ if (!type.IsPublic)
+ return false;
+
+ if (IsGenericType && !IsGenericTypeDefinition)
+ {
+ foreach (Type t in GetGenericArguments())
+ {
+ if (!t.IsVisible)
+ return false;
+ }
+ }
+
+ return true;
+ }
+ }
+
+ public virtual Type[] FindInterfaces(TypeFilter filter, object filterCriteria)
+ {
+ if (filter == null)
+ throw new ArgumentNullException(nameof(filter));
+
+ Type[] c = GetInterfaces();
+ int cnt = 0;
+ for (int i = 0; i < c.Length; i++)
+ {
+ if (!filter(c[i], filterCriteria))
+ c[i] = null;
+ else
+ cnt++;
+ }
+ if (cnt == c.Length)
+ return c;
+
+ Type[] ret = new Type[cnt];
+ cnt = 0;
+ for (int i = 0; i < c.Length; i++)
+ {
+ if (c[i] != null)
+ ret[cnt++] = c[i];
+ }
+ return ret;
+ }
+
+ public virtual MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria)
+ {
+ // Define the work arrays
+ MethodInfo[] m = null;
+ ConstructorInfo[] c = null;
+ FieldInfo[] f = null;
+ PropertyInfo[] p = null;
+ EventInfo[] e = null;
+ Type[] t = null;
+
+ int i = 0;
+ int cnt = 0; // Total Matchs
+
+ // Check the methods
+ if ((memberType & MemberTypes.Method) != 0)
+ {
+ m = GetMethods(bindingAttr);
+ if (filter != null)
+ {
+ for (i = 0; i < m.Length; i++)
+ if (!filter(m[i], filterCriteria))
+ m[i] = null;
+ else
+ cnt++;
+ }
+ else
+ {
+ cnt += m.Length;
+ }
+ }
+
+ // Check the constructors
+ if ((memberType & MemberTypes.Constructor) != 0)
+ {
+ c = GetConstructors(bindingAttr);
+ if (filter != null)
+ {
+ for (i = 0; i < c.Length; i++)
+ if (!filter(c[i], filterCriteria))
+ c[i] = null;
+ else
+ cnt++;
+ }
+ else
+ {
+ cnt += c.Length;
+ }
+ }
+
+ // Check the fields
+ if ((memberType & MemberTypes.Field) != 0)
+ {
+ f = GetFields(bindingAttr);
+ if (filter != null)
+ {
+ for (i = 0; i < f.Length; i++)
+ if (!filter(f[i], filterCriteria))
+ f[i] = null;
+ else
+ cnt++;
+ }
+ else
+ {
+ cnt += f.Length;
+ }
+ }
+
+ // Check the Properties
+ if ((memberType & MemberTypes.Property) != 0)
+ {
+ p = GetProperties(bindingAttr);
+ if (filter != null)
+ {
+ for (i = 0; i < p.Length; i++)
+ if (!filter(p[i], filterCriteria))
+ p[i] = null;
+ else
+ cnt++;
+ }
+ else
+ {
+ cnt += p.Length;
+ }
+ }
+
+ // Check the Events
+ if ((memberType & MemberTypes.Event) != 0)
+ {
+ e = GetEvents(bindingAttr);
+ if (filter != null)
+ {
+ for (i = 0; i < e.Length; i++)
+ if (!filter(e[i], filterCriteria))
+ e[i] = null;
+ else
+ cnt++;
+ }
+ else
+ {
+ cnt += e.Length;
+ }
+ }
+
+ // Check the Types
+ if ((memberType & MemberTypes.NestedType) != 0)
+ {
+ t = GetNestedTypes(bindingAttr);
+ if (filter != null)
+ {
+ for (i = 0; i < t.Length; i++)
+ if (!filter(t[i], filterCriteria))
+ t[i] = null;
+ else
+ cnt++;
+ }
+ else
+ {
+ cnt += t.Length;
+ }
+ }
+
+ // Allocate the Member Info
+ MemberInfo[] ret = new MemberInfo[cnt];
+
+ // Copy the Methods
+ cnt = 0;
+ if (m != null)
+ {
+ for (i = 0; i < m.Length; i++)
+ if (m[i] != null)
+ ret[cnt++] = m[i];
+ }
+
+ // Copy the Constructors
+ if (c != null)
+ {
+ for (i = 0; i < c.Length; i++)
+ if (c[i] != null)
+ ret[cnt++] = c[i];
+ }
+
+ // Copy the Fields
+ if (f != null)
+ {
+ for (i = 0; i < f.Length; i++)
+ if (f[i] != null)
+ ret[cnt++] = f[i];
+ }
+
+ // Copy the Properties
+ if (p != null)
+ {
+ for (i = 0; i < p.Length; i++)
+ if (p[i] != null)
+ ret[cnt++] = p[i];
+ }
+
+ // Copy the Events
+ if (e != null)
+ {
+ for (i = 0; i < e.Length; i++)
+ if (e[i] != null)
+ ret[cnt++] = e[i];
+ }
+
+ // Copy the Types
+ if (t != null)
+ {
+ for (i = 0; i < t.Length; i++)
+ if (t[i] != null)
+ ret[cnt++] = t[i];
+ }
+
+ return ret;
+ }
+
+ public virtual bool IsSubclassOf(Type c)
+ {
+ Type p = this;
+ if (p == c)
+ return false;
+ while (p != null)
+ {
+ if (p == c)
+ return true;
+ p = p.BaseType;
+ }
+ return false;
+ }
+
+ public virtual bool IsAssignableFrom(Type c)
+ {
+ if (c == null)
+ return false;
+
+ if (this == c)
+ return true;
+
+ // For backward-compatibility, we need to special case for the types
+ // whose UnderlyingSystemType are runtime implemented.
+ Type toType = this.UnderlyingSystemType;
+ if (toType.IsRuntimeImplemented())
+ return toType.IsAssignableFrom(c);
+
+ // If c is a subclass of this class, then c can be cast to this type.
+ if (c.IsSubclassOf(this))
+ return true;
+
+ if (this.IsInterface)
+ {
+ return c.ImplementInterface(this);
+ }
+ else if (IsGenericParameter)
+ {
+ Type[] constraints = GetGenericParameterConstraints();
+ for (int i = 0; i < constraints.Length; i++)
+ if (!constraints[i].IsAssignableFrom(c))
+ return false;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ internal bool ImplementInterface(Type ifaceType)
+ {
+ Type t = this;
+ while (t != null)
+ {
+ Type[] interfaces = t.GetInterfaces();
+ if (interfaces != null)
+ {
+ for (int i = 0; i < interfaces.Length; i++)
+ {
+ // Interfaces don't derive from other interfaces, they implement them.
+ // So instead of IsSubclassOf, we should use ImplementInterface instead.
+ if (interfaces[i] == ifaceType ||
+ (interfaces[i] != null && interfaces[i].ImplementInterface(ifaceType)))
+ return true;
+ }
+ }
+
+ t = t.BaseType;
+ }
+
+ return false;
+ }
+
+ // FilterAttribute
+ // This method will search for a member based upon the attribute passed in.
+ // filterCriteria -- an Int32 representing the attribute
+ private static bool FilterAttributeImpl(MemberInfo m, object filterCriteria)
+ {
+ // Check that the criteria object is an Integer object
+ if (filterCriteria == null)
+ throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritInt);
+
+ switch (m.MemberType)
+ {
+ case MemberTypes.Constructor:
+ case MemberTypes.Method:
+ {
+ MethodAttributes criteria = 0;
+ try
+ {
+ int i = (int)filterCriteria;
+ criteria = (MethodAttributes)i;
+ }
+ catch
+ {
+ throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritInt);
+ }
+
+
+ MethodAttributes attr;
+ if (m.MemberType == MemberTypes.Method)
+ attr = ((MethodInfo)m).Attributes;
+ else
+ attr = ((ConstructorInfo)m).Attributes;
+
+ if (((criteria & MethodAttributes.MemberAccessMask) != 0) && (attr & MethodAttributes.MemberAccessMask) != (criteria & MethodAttributes.MemberAccessMask))
+ return false;
+ if (((criteria & MethodAttributes.Static) != 0) && (attr & MethodAttributes.Static) == 0)
+ return false;
+ if (((criteria & MethodAttributes.Final) != 0) && (attr & MethodAttributes.Final) == 0)
+ return false;
+ if (((criteria & MethodAttributes.Virtual) != 0) && (attr & MethodAttributes.Virtual) == 0)
+ return false;
+ if (((criteria & MethodAttributes.Abstract) != 0) && (attr & MethodAttributes.Abstract) == 0)
+ return false;
+ if (((criteria & MethodAttributes.SpecialName) != 0) && (attr & MethodAttributes.SpecialName) == 0)
+ return false;
+ return true;
+ }
+ case MemberTypes.Field:
+ {
+ FieldAttributes criteria = 0;
+ try
+ {
+ int i = (int)filterCriteria;
+ criteria = (FieldAttributes)i;
+ }
+ catch
+ {
+ throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritInt);
+ }
+
+ FieldAttributes attr = ((FieldInfo)m).Attributes;
+ if (((criteria & FieldAttributes.FieldAccessMask) != 0) && (attr & FieldAttributes.FieldAccessMask) != (criteria & FieldAttributes.FieldAccessMask))
+ return false;
+ if (((criteria & FieldAttributes.Static) != 0) && (attr & FieldAttributes.Static) == 0)
+ return false;
+ if (((criteria & FieldAttributes.InitOnly) != 0) && (attr & FieldAttributes.InitOnly) == 0)
+ return false;
+ if (((criteria & FieldAttributes.Literal) != 0) && (attr & FieldAttributes.Literal) == 0)
+ return false;
+ if (((criteria & FieldAttributes.NotSerialized) != 0) && (attr & FieldAttributes.NotSerialized) == 0)
+ return false;
+ if (((criteria & FieldAttributes.PinvokeImpl) != 0) && (attr & FieldAttributes.PinvokeImpl) == 0)
+ return false;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ // FilterName
+ // This method will filter based upon the name. A partial wildcard
+ // at the end of the string is supported.
+ // filterCriteria -- This is the string name
+ private static bool FilterNameImpl(MemberInfo m, object filterCriteria)
+ {
+ // Check that the criteria object is a String object
+ if (filterCriteria == null || !(filterCriteria is string))
+ throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritString);
+
+ // At the moment this fails if its done on a single line....
+ string str = ((string)filterCriteria);
+ str = str.Trim();
+
+ string name = m.Name;
+ // Get the nested class name only, as opposed to the mangled one
+ if (m.MemberType == MemberTypes.NestedType)
+ name = name.Substring(name.LastIndexOf('+') + 1);
+ // Check to see if this is a prefix or exact match requirement
+ if (str.Length > 0 && str[str.Length - 1] == '*')
+ {
+ str = str.Substring(0, str.Length - 1);
+ return (name.StartsWith(str, StringComparison.Ordinal));
+ }
+
+ return (name.Equals(str));
+ }
+
+ // FilterIgnoreCase
+ // This delegate will do a name search but does it with the
+ // ignore case specified.
+ private static bool FilterNameIgnoreCaseImpl(MemberInfo m, object filterCriteria)
+ {
+ // Check that the criteria object is a String object
+ if (filterCriteria == null || !(filterCriteria is string))
+ throw new InvalidFilterCriteriaException(SR.InvalidFilterCriteriaException_CritString);
+
+ string str = (string)filterCriteria;
+ str = str.Trim();
+
+ string name = m.Name;
+ // Get the nested class name only, as opposed to the mangled one
+ if (m.MemberType == MemberTypes.NestedType)
+ name = name.Substring(name.LastIndexOf('+') + 1);
+ // Check to see if this is a prefix or exact match requirement
+ if (str.Length > 0 && str[str.Length - 1] == '*')
+ {
+ str = str.Substring(0, str.Length - 1);
+ return (string.Compare(name, 0, str, 0, str.Length, StringComparison.OrdinalIgnoreCase) == 0);
+ }
+
+ return (string.Compare(str, name, StringComparison.OrdinalIgnoreCase) == 0);
+ }
+ }
+}
+
diff --git a/src/mscorlib/shared/System/Type.cs b/src/mscorlib/shared/System/Type.cs
new file mode 100644
index 0000000000..7749c17414
--- /dev/null
+++ b/src/mscorlib/shared/System/Type.cs
@@ -0,0 +1,358 @@
+// 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.Threading;
+using System.Reflection;
+using System.Diagnostics;
+using System.Globalization;
+using System.Runtime.InteropServices;
+
+namespace System
+{
+ public abstract partial class Type : MemberInfo, IReflect
+ {
+ protected Type() { }
+
+ public override MemberTypes MemberType => MemberTypes.TypeInfo;
+
+ public new Type GetType() => base.GetType();
+
+ public abstract string Namespace { get; }
+ public abstract string AssemblyQualifiedName { get; }
+ public abstract string FullName { get; }
+
+ public abstract Assembly Assembly { get; }
+ public abstract new Module Module { get; }
+
+ public bool IsNested => DeclaringType != null;
+ public override Type DeclaringType => null;
+ public virtual MethodBase DeclaringMethod => null;
+
+ public override Type ReflectedType => null;
+ public abstract Type UnderlyingSystemType { get; }
+
+ public bool IsArray => IsArrayImpl();
+ protected abstract bool IsArrayImpl();
+ public bool IsByRef => IsByRefImpl();
+ protected abstract bool IsByRefImpl();
+ public bool IsPointer => IsPointerImpl();
+ protected abstract bool IsPointerImpl();
+ public virtual bool IsConstructedGenericType { get { throw NotImplemented.ByDesign; } }
+ public virtual bool IsGenericParameter => false;
+ public virtual bool IsGenericType => false;
+ public virtual bool IsGenericTypeDefinition => false;
+
+ public virtual bool IsSZArray { get { throw NotImplemented.ByDesign; } }
+ public virtual bool IsVariableBoundArray => IsArray && !IsSZArray;
+
+ public bool HasElementType => HasElementTypeImpl();
+ protected abstract bool HasElementTypeImpl();
+ public abstract Type GetElementType();
+
+ public virtual int GetArrayRank() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+
+ public virtual Type GetGenericTypeDefinition() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+ public virtual Type[] GenericTypeArguments => (IsGenericType && !IsGenericTypeDefinition) ? GetGenericArguments() : Array.Empty<Type>();
+ public virtual Type[] GetGenericArguments() { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+
+ public virtual int GenericParameterPosition { get { throw new InvalidOperationException(SR.Arg_NotGenericParameter); } }
+ public virtual GenericParameterAttributes GenericParameterAttributes { get { throw new NotSupportedException(); } }
+ public virtual Type[] GetGenericParameterConstraints()
+ {
+ if (!IsGenericParameter)
+ throw new InvalidOperationException(SR.Arg_NotGenericParameter);
+ throw new InvalidOperationException();
+ }
+
+ public TypeAttributes Attributes => GetAttributeFlagsImpl();
+ protected abstract TypeAttributes GetAttributeFlagsImpl();
+
+ public bool IsAbstract => (GetAttributeFlagsImpl() & TypeAttributes.Abstract) != 0;
+ public bool IsImport => (GetAttributeFlagsImpl() & TypeAttributes.Import) != 0;
+ public bool IsSealed => (GetAttributeFlagsImpl() & TypeAttributes.Sealed) != 0;
+ public bool IsSpecialName => (GetAttributeFlagsImpl() & TypeAttributes.SpecialName) != 0;
+
+ public bool IsClass => (GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class && !IsValueType;
+
+ public bool IsNestedAssembly => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly;
+ public bool IsNestedFamANDAssem => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem;
+ public bool IsNestedFamily => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily;
+ public bool IsNestedFamORAssem => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem;
+ public bool IsNestedPrivate => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate;
+ public bool IsNestedPublic => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic;
+ public bool IsNotPublic => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic;
+ public bool IsPublic => (GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.Public;
+
+ public bool IsAutoLayout => (GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout;
+ public bool IsExplicitLayout => (GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout;
+ public bool IsLayoutSequential => (GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout;
+
+ public bool IsAnsiClass => (GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass;
+ public bool IsAutoClass => (GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass;
+ public bool IsUnicodeClass => (GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass;
+
+ public bool IsCOMObject => IsCOMObjectImpl();
+ protected abstract bool IsCOMObjectImpl();
+ public bool IsContextful => IsContextfulImpl();
+ protected virtual bool IsContextfulImpl() => false;
+
+ public virtual bool IsEnum => IsSubclassOf(typeof(Enum));
+ public bool IsMarshalByRef => IsMarshalByRefImpl();
+ protected virtual bool IsMarshalByRefImpl() => false;
+ public bool IsPrimitive => IsPrimitiveImpl();
+ protected abstract bool IsPrimitiveImpl();
+ public bool IsValueType => IsValueTypeImpl();
+ protected virtual bool IsValueTypeImpl() => IsSubclassOf(typeof(ValueType));
+
+ public virtual bool IsSecurityCritical { get { throw NotImplemented.ByDesign; } }
+ public virtual bool IsSecuritySafeCritical { get { throw NotImplemented.ByDesign; } }
+ public virtual bool IsSecurityTransparent { get { throw NotImplemented.ByDesign; } }
+
+ public virtual StructLayoutAttribute StructLayoutAttribute { get { throw new NotSupportedException(); } }
+ public ConstructorInfo TypeInitializer => GetConstructorImpl(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, CallingConventions.Any, Type.EmptyTypes, null);
+
+ public ConstructorInfo GetConstructor(Type[] types) => GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, types, null);
+ public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) => GetConstructor(bindingAttr, binder, CallingConventions.Any, types, modifiers);
+ public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
+ {
+ if (types == null)
+ throw new ArgumentNullException(nameof(types));
+ for (int i = 0; i < types.Length; i++)
+ {
+ if (types[i] == null)
+ throw new ArgumentNullException(nameof(types));
+ }
+ return GetConstructorImpl(bindingAttr, binder, callConvention, types, modifiers);
+ }
+ protected abstract ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers);
+
+ public ConstructorInfo[] GetConstructors() => GetConstructors(BindingFlags.Public | BindingFlags.Instance);
+ public abstract ConstructorInfo[] GetConstructors(BindingFlags bindingAttr);
+
+ public EventInfo GetEvent(string name) => GetEvent(name, Type.DefaultLookup);
+ public abstract EventInfo GetEvent(string name, BindingFlags bindingAttr);
+
+ public virtual EventInfo[] GetEvents() => GetEvents(Type.DefaultLookup);
+ public abstract EventInfo[] GetEvents(BindingFlags bindingAttr);
+
+ public FieldInfo GetField(string name) => GetField(name, Type.DefaultLookup);
+ public abstract FieldInfo GetField(string name, BindingFlags bindingAttr);
+
+ public FieldInfo[] GetFields() => GetFields(Type.DefaultLookup);
+ public abstract FieldInfo[] GetFields(BindingFlags bindingAttr);
+
+ public MemberInfo[] GetMember(string name) => GetMember(name, Type.DefaultLookup);
+ public virtual MemberInfo[] GetMember(string name, BindingFlags bindingAttr) => GetMember(name, MemberTypes.All, bindingAttr);
+ public virtual MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+
+ public MemberInfo[] GetMembers() => GetMembers(Type.DefaultLookup);
+ public abstract MemberInfo[] GetMembers(BindingFlags bindingAttr);
+
+ public MethodInfo GetMethod(string name) => GetMethod(name, Type.DefaultLookup);
+ public MethodInfo GetMethod(string name, BindingFlags bindingAttr)
+ {
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+ return GetMethodImpl(name, bindingAttr, null, CallingConventions.Any, null, null);
+ }
+
+ public MethodInfo GetMethod(string name, Type[] types) => GetMethod(name, types, null);
+ public MethodInfo GetMethod(string name, Type[] types, ParameterModifier[] modifiers) => GetMethod(name, Type.DefaultLookup, null, types, modifiers);
+ public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) => GetMethod(name, bindingAttr, binder, CallingConventions.Any, types, modifiers);
+ public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
+ {
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+ if (types == null)
+ throw new ArgumentNullException(nameof(types));
+ for (int i = 0; i < types.Length; i++)
+ {
+ if (types[i] == null)
+ throw new ArgumentNullException(nameof(types));
+ }
+ return GetMethodImpl(name, bindingAttr, binder, callConvention, types, modifiers);
+ }
+
+ protected abstract MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers);
+
+ public MethodInfo[] GetMethods() => GetMethods(Type.DefaultLookup);
+ public abstract MethodInfo[] GetMethods(BindingFlags bindingAttr);
+
+ public Type GetNestedType(string name) => GetNestedType(name, Type.DefaultLookup);
+ public abstract Type GetNestedType(string name, BindingFlags bindingAttr);
+
+ public Type[] GetNestedTypes() => GetNestedTypes(Type.DefaultLookup);
+ public abstract Type[] GetNestedTypes(BindingFlags bindingAttr);
+
+ public PropertyInfo GetProperty(string name) => GetProperty(name, Type.DefaultLookup);
+ public PropertyInfo GetProperty(string name, BindingFlags bindingAttr)
+ {
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+ return GetPropertyImpl(name, bindingAttr, null, null, null, null);
+ }
+
+ public PropertyInfo GetProperty(string name, Type returnType)
+ {
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+ if (returnType == null)
+ throw new ArgumentNullException(nameof(returnType));
+ return GetPropertyImpl(name, Type.DefaultLookup, null, returnType, null, null);
+ }
+
+ public PropertyInfo GetProperty(string name, Type[] types) => GetProperty(name, null, types);
+ public PropertyInfo GetProperty(string name, Type returnType, Type[] types) => GetProperty(name, returnType, types, null);
+ public PropertyInfo GetProperty(string name, Type returnType, Type[] types, ParameterModifier[] modifiers) => GetProperty(name, Type.DefaultLookup, null, returnType, types, modifiers);
+ public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
+ {
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+ if (types == null)
+ throw new ArgumentNullException(nameof(types));
+ return GetPropertyImpl(name, bindingAttr, binder, returnType, types, modifiers);
+ }
+
+ protected abstract PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers);
+
+ public PropertyInfo[] GetProperties() => GetProperties(Type.DefaultLookup);
+ public abstract PropertyInfo[] GetProperties(BindingFlags bindingAttr);
+
+ public virtual MemberInfo[] GetDefaultMembers() { throw NotImplemented.ByDesign; }
+
+ public virtual RuntimeTypeHandle TypeHandle { get { throw new NotSupportedException(); } }
+ public static RuntimeTypeHandle GetTypeHandle(object o)
+ {
+ if (o == null)
+ throw new ArgumentNullException(null, SR.Arg_InvalidHandle);
+ Type type = o.GetType();
+ return type.TypeHandle;
+ }
+
+ public static Type[] GetTypeArray(object[] args)
+ {
+ if (args == null)
+ throw new ArgumentNullException(nameof(args));
+
+ Type[] cls = new Type[args.Length];
+ for (int i = 0; i < cls.Length; i++)
+ {
+ if (args[i] == null)
+ throw new ArgumentNullException();
+ cls[i] = args[i].GetType();
+ }
+ return cls;
+ }
+
+ public static TypeCode GetTypeCode(Type type)
+ {
+ if (type == null)
+ return TypeCode.Empty;
+ return type.GetTypeCodeImpl();
+ }
+ protected virtual TypeCode GetTypeCodeImpl()
+ {
+ if (this != UnderlyingSystemType && UnderlyingSystemType != null)
+ return Type.GetTypeCode(UnderlyingSystemType);
+
+ return TypeCode.Object;
+ }
+
+ public abstract Guid GUID { get; }
+
+ public static Type GetTypeFromCLSID(Guid clsid) => GetTypeFromCLSID(clsid, null, throwOnError: false);
+ public static Type GetTypeFromCLSID(Guid clsid, bool throwOnError) => GetTypeFromCLSID(clsid, null, throwOnError: throwOnError);
+ public static Type GetTypeFromCLSID(Guid clsid, string server) => GetTypeFromCLSID(clsid, server, throwOnError: false);
+
+ public static Type GetTypeFromProgID(string progID) => GetTypeFromProgID(progID, null, throwOnError: false);
+ public static Type GetTypeFromProgID(string progID, bool throwOnError) => GetTypeFromProgID(progID, null, throwOnError: throwOnError);
+ public static Type GetTypeFromProgID(string progID, string server) => GetTypeFromProgID(progID, server, throwOnError: false);
+
+ public abstract Type BaseType { get; }
+
+ [DebuggerHidden]
+ [DebuggerStepThrough]
+ public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args) => InvokeMember(name, invokeAttr, binder, target, args, null, null, null);
+
+ [DebuggerHidden]
+ [DebuggerStepThrough]
+ public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, CultureInfo culture) => InvokeMember(name, invokeAttr, binder, target, args, null, culture, null);
+ public abstract object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters);
+
+ public Type GetInterface(string name) => GetInterface(name, ignoreCase: false);
+ public abstract Type GetInterface(string name, bool ignoreCase);
+ public abstract Type[] GetInterfaces();
+
+ public virtual InterfaceMapping GetInterfaceMap(Type interfaceType) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+
+ public virtual bool IsInstanceOfType(object o) => o == null ? false : IsAssignableFrom(o.GetType());
+ public virtual bool IsEquivalentTo(Type other) => this == other;
+
+ public virtual Type GetEnumUnderlyingType()
+ {
+ if (!IsEnum)
+ throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
+
+ FieldInfo[] fields = GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
+ if (fields == null || fields.Length != 1)
+ throw new ArgumentException(SR.Argument_InvalidEnum, "enumType");
+
+ return fields[0].FieldType;
+ }
+ public virtual Array GetEnumValues()
+ {
+ if (!IsEnum)
+ throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
+
+ // We don't support GetEnumValues in the default implementation because we cannot create an array of
+ // a non-runtime type. If there is strong need we can consider returning an object or int64 array.
+ throw NotImplemented.ByDesign;
+ }
+
+ public virtual Type MakeArrayType() { throw new NotSupportedException(); }
+ public virtual Type MakeArrayType(int rank) { throw new NotSupportedException(); }
+ public virtual Type MakeByRefType() { throw new NotSupportedException(); }
+ public virtual Type MakeGenericType(params Type[] typeArguments) { throw new NotSupportedException(SR.NotSupported_SubclassOverride); }
+ public virtual Type MakePointerType() { throw new NotSupportedException(); }
+
+ public override string ToString() => "Type: " + Name; // Why do we add the "Type: " prefix?
+
+ public override bool Equals(object o) => o == null ? false : Equals(o as Type);
+ public override int GetHashCode()
+ {
+ Type systemType = UnderlyingSystemType;
+ if (!object.ReferenceEquals(systemType, this))
+ return systemType.GetHashCode();
+ return base.GetHashCode();
+ }
+ public virtual bool Equals(Type o) => o == null ? false : object.ReferenceEquals(this.UnderlyingSystemType, o.UnderlyingSystemType);
+
+ public static Type ReflectionOnlyGetType(string typeName, bool throwIfNotFound, bool ignoreCase) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ReflectionOnly); }
+
+ public static Binder DefaultBinder
+ {
+ get
+ {
+ if (s_defaultBinder == null)
+ {
+ DefaultBinder binder = new DefaultBinder();
+ Interlocked.CompareExchange<Binder>(ref s_defaultBinder, binder, null);
+ }
+ return s_defaultBinder;
+ }
+ }
+
+ private static volatile Binder s_defaultBinder;
+
+ public static readonly char Delimiter = '.';
+ public static readonly Type[] EmptyTypes = Array.Empty<Type>();
+ public static readonly object Missing = System.Reflection.Missing.Value;
+
+ public static readonly MemberFilter FilterAttribute = FilterAttributeImpl;
+ public static readonly MemberFilter FilterName = FilterNameImpl;
+ public static readonly MemberFilter FilterNameIgnoreCase = FilterNameIgnoreCaseImpl;
+
+ private const BindingFlags DefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
+ }
+}
diff --git a/src/mscorlib/src/System/TypeAccessException.cs b/src/mscorlib/shared/System/TypeAccessException.cs
index 32afbdfeb8..32afbdfeb8 100644
--- a/src/mscorlib/src/System/TypeAccessException.cs
+++ b/src/mscorlib/shared/System/TypeAccessException.cs
diff --git a/src/mscorlib/src/System/TypeCode.cs b/src/mscorlib/shared/System/TypeCode.cs
index 293eb1f1aa..293eb1f1aa 100644
--- a/src/mscorlib/src/System/TypeCode.cs
+++ b/src/mscorlib/shared/System/TypeCode.cs
diff --git a/src/mscorlib/src/System/TypeInitializationException.cs b/src/mscorlib/shared/System/TypeInitializationException.cs
index 9191028346..9191028346 100644
--- a/src/mscorlib/src/System/TypeInitializationException.cs
+++ b/src/mscorlib/shared/System/TypeInitializationException.cs
diff --git a/src/mscorlib/shared/System/TypeUnloadedException.cs b/src/mscorlib/shared/System/TypeUnloadedException.cs
new file mode 100644
index 0000000000..33e4687772
--- /dev/null
+++ b/src/mscorlib/shared/System/TypeUnloadedException.cs
@@ -0,0 +1,39 @@
+// 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.Runtime.Serialization;
+
+namespace System
+{
+ [Serializable]
+ public class TypeUnloadedException : SystemException
+ {
+ public TypeUnloadedException()
+ : base(SR.Arg_TypeUnloadedException)
+ {
+ HResult = __HResults.COR_E_TYPEUNLOADED;
+ }
+
+ public TypeUnloadedException(string message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_TYPEUNLOADED;
+ }
+
+ public TypeUnloadedException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_TYPEUNLOADED;
+ }
+
+ //
+ // This constructor is required for serialization;
+ //
+ protected TypeUnloadedException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
+ {
+ }
+ }
+}
+
diff --git a/src/mscorlib/src/System/UnauthorizedAccessException.cs b/src/mscorlib/shared/System/UnauthorizedAccessException.cs
index 997358826f..997358826f 100644
--- a/src/mscorlib/src/System/UnauthorizedAccessException.cs
+++ b/src/mscorlib/shared/System/UnauthorizedAccessException.cs
diff --git a/src/mscorlib/src/System/UnhandledExceptionEventArgs.cs b/src/mscorlib/shared/System/UnhandledExceptionEventArgs.cs
index d33830181c..d33830181c 100644
--- a/src/mscorlib/src/System/UnhandledExceptionEventArgs.cs
+++ b/src/mscorlib/shared/System/UnhandledExceptionEventArgs.cs
diff --git a/src/mscorlib/src/System/UnhandledExceptionEventHandler.cs b/src/mscorlib/shared/System/UnhandledExceptionEventHandler.cs
index b99414c189..b99414c189 100644
--- a/src/mscorlib/src/System/UnhandledExceptionEventHandler.cs
+++ b/src/mscorlib/shared/System/UnhandledExceptionEventHandler.cs
diff --git a/src/mscorlib/shared/System/UnitySerializationHolder.cs b/src/mscorlib/shared/System/UnitySerializationHolder.cs
new file mode 100644
index 0000000000..f1957981d3
--- /dev/null
+++ b/src/mscorlib/shared/System/UnitySerializationHolder.cs
@@ -0,0 +1,329 @@
+// 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.Runtime.Serialization;
+using System.Reflection;
+using System.Globalization;
+using System.Runtime.Versioning;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
+ [Serializable]
+ // Holds classes (Empty, Null, Missing) for which we guarantee that there is only ever one instance of.
+#if CORECLR
+ internal
+#else
+ public // On CoreRT, this must be public because of the Reflection.Core/CoreLib divide and the need to whitelist past the ReflectionBlock.
+#endif
+ class UnitySerializationHolder : ISerializable, IObjectReference
+ {
+#region Internal Constants
+ internal const int EmptyUnity = 0x0001;
+ internal const int NullUnity = 0x0002;
+ internal const int MissingUnity = 0x0003;
+ internal const int RuntimeTypeUnity = 0x0004;
+ public const int ModuleUnity = 0x0005;
+ public const int AssemblyUnity = 0x0006;
+ internal const int GenericParameterTypeUnity = 0x0007;
+ internal const int PartialInstantiationTypeUnity = 0x0008;
+
+ internal const int Pointer = 0x0001;
+ internal const int Array = 0x0002;
+ internal const int SzArray = 0x0003;
+ internal const int ByRef = 0x0004;
+#endregion
+
+#region Internal Static Members
+ internal static void GetUnitySerializationInfo(SerializationInfo info, Missing missing)
+ {
+ info.SetType(typeof(UnitySerializationHolder));
+ info.AddValue("UnityType", MissingUnity);
+ }
+
+ internal static Type AddElementTypes(SerializationInfo info, Type type)
+ {
+ List<int> elementTypes = new List<int>();
+ while (type.HasElementType)
+ {
+ if (type.IsSZArray)
+ {
+ elementTypes.Add(SzArray);
+ }
+ else if (type.IsArray)
+ {
+ elementTypes.Add(type.GetArrayRank());
+ elementTypes.Add(Array);
+ }
+ else if (type.IsPointer)
+ {
+ elementTypes.Add(Pointer);
+ }
+ else if (type.IsByRef)
+ {
+ elementTypes.Add(ByRef);
+ }
+
+ type = type.GetElementType();
+ }
+
+ info.AddValue("ElementTypes", elementTypes.ToArray(), typeof(int[]));
+
+ return type;
+ }
+
+ internal Type MakeElementTypes(Type type)
+ {
+ for (int i = _elementTypes.Length - 1; i >= 0; i--)
+ {
+ if (_elementTypes[i] == SzArray)
+ {
+ type = type.MakeArrayType();
+ }
+ else if (_elementTypes[i] == Array)
+ {
+ type = type.MakeArrayType(_elementTypes[--i]);
+ }
+ else if ((_elementTypes[i] == Pointer))
+ {
+ type = type.MakePointerType();
+ }
+ else if ((_elementTypes[i] == ByRef))
+ {
+ type = type.MakeByRefType();
+ }
+ }
+
+ return type;
+ }
+
+ public static void GetUnitySerializationInfo(SerializationInfo info, Type type)
+ {
+ Type rootElementType = type;
+ while (rootElementType.HasElementType)
+ {
+ rootElementType = rootElementType.GetElementType();
+ }
+
+ if (rootElementType.IsGenericParameter)
+ {
+ type = AddElementTypes(info, type);
+ info.SetType(typeof(UnitySerializationHolder));
+ info.AddValue("UnityType", GenericParameterTypeUnity);
+ info.AddValue("GenericParameterPosition", type.GenericParameterPosition);
+ info.AddValue("DeclaringMethod", type.DeclaringMethod, typeof(MethodBase));
+ info.AddValue("DeclaringType", type.DeclaringType, typeof(Type));
+
+ return;
+ }
+
+ int unityType = RuntimeTypeUnity;
+
+ if (!type.IsGenericTypeDefinition && type.ContainsGenericParameters)
+ {
+ // Partial instantiation
+ unityType = PartialInstantiationTypeUnity;
+ type = AddElementTypes(info, type);
+ info.AddValue("GenericArguments", type.GetGenericArguments(), typeof(Type[]));
+ type = type.GetGenericTypeDefinition();
+ }
+
+ GetUnitySerializationInfo(info, unityType, type.FullName, type.Assembly);
+ }
+
+ public static void GetUnitySerializationInfo(
+ SerializationInfo info, int unityType, string data, Assembly assembly)
+ {
+ // A helper method that returns the SerializationInfo that a class utilizing
+ // UnitySerializationHelper should return from a call to GetObjectData. It contains
+ // the unityType (defined above) and any optional data (used only for the reflection
+ // types.)
+
+ info.SetType(typeof(UnitySerializationHolder));
+ info.AddValue("Data", data, typeof(string));
+ info.AddValue("UnityType", unityType);
+
+ string assemName;
+
+ if (assembly == null)
+ {
+ assemName = string.Empty;
+ }
+ else
+ {
+ assemName = assembly.FullName;
+ }
+
+ info.AddValue("AssemblyName", assemName);
+ }
+#endregion
+
+#region Private Data Members
+ private readonly Type[] _instantiation;
+ private readonly int[] _elementTypes;
+ private readonly int _genericParameterPosition;
+ private readonly Type _declaringType;
+ private readonly MethodBase _declaringMethod;
+ private readonly string _data;
+ private readonly string _assemblyName;
+ private int _unityType;
+#endregion
+
+#region Constructor
+ public UnitySerializationHolder(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ _unityType = info.GetInt32("UnityType");
+
+ if (_unityType == MissingUnity)
+ return;
+
+ if (_unityType == GenericParameterTypeUnity)
+ {
+ _declaringMethod = info.GetValue("DeclaringMethod", typeof(MethodBase)) as MethodBase;
+ _declaringType = info.GetValue("DeclaringType", typeof(Type)) as Type;
+ _genericParameterPosition = info.GetInt32("GenericParameterPosition");
+ _elementTypes = info.GetValue("ElementTypes", typeof(int[])) as int[];
+
+ return;
+ }
+
+ if (_unityType == PartialInstantiationTypeUnity)
+ {
+ _instantiation = info.GetValue("GenericArguments", typeof(Type[])) as Type[];
+ _elementTypes = info.GetValue("ElementTypes", typeof(int[])) as int[];
+ }
+
+ _data = info.GetString("Data");
+ _assemblyName = info.GetString("AssemblyName");
+ }
+#endregion
+
+#region Private Methods
+ private void ThrowInsufficientInformation(string field)
+ {
+ throw new SerializationException(
+ SR.Format(SR.Serialization_InsufficientDeserializationState, field));
+ }
+#endregion
+
+#region ISerializable
+ public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ throw new NotSupportedException(SR.NotSupported_UnitySerHolder);
+ }
+#endregion
+
+#region IObjectReference
+ public virtual object GetRealObject(StreamingContext context)
+ {
+ // GetRealObject uses the data we have in _data and _unityType to do a lookup on the correct
+ // object to return. We have specific code here to handle the different types which we support.
+ // The reflection types (Assembly, Module, and Type) have to be looked up through their static
+ // accessors by name.
+
+ Assembly assembly;
+
+ switch (_unityType)
+ {
+ case EmptyUnity:
+ {
+ return Empty.Value;
+ }
+
+ case NullUnity:
+ {
+ return DBNull.Value;
+ }
+
+ case MissingUnity:
+ {
+ return Missing.Value;
+ }
+
+ case PartialInstantiationTypeUnity:
+ {
+ _unityType = RuntimeTypeUnity;
+ Type definition = GetRealObject(context) as Type;
+ _unityType = PartialInstantiationTypeUnity;
+
+ if (_instantiation[0] == null)
+ return null;
+
+ return MakeElementTypes(definition.MakeGenericType(_instantiation));
+ }
+
+ case GenericParameterTypeUnity:
+ {
+ if (_declaringMethod == null && _declaringType == null)
+ ThrowInsufficientInformation("DeclaringMember");
+
+ if (_declaringMethod != null)
+ return _declaringMethod.GetGenericArguments()[_genericParameterPosition];
+
+ return MakeElementTypes(_declaringType.GetGenericArguments()[_genericParameterPosition]);
+ }
+
+ case RuntimeTypeUnity:
+ {
+ if (_data == null || _data.Length == 0)
+ ThrowInsufficientInformation("Data");
+
+ if (_assemblyName == null)
+ ThrowInsufficientInformation("AssemblyName");
+
+ if (_assemblyName.Length == 0)
+ return Type.GetType(_data, true, false);
+
+ assembly = Assembly.Load(_assemblyName);
+
+ Type t = assembly.GetType(_data, true, false);
+
+ return t;
+ }
+
+ case ModuleUnity:
+ {
+ if (_data == null || _data.Length == 0)
+ ThrowInsufficientInformation("Data");
+
+ if (_assemblyName == null)
+ ThrowInsufficientInformation("AssemblyName");
+
+ assembly = Assembly.Load(_assemblyName);
+
+ Module namedModule = assembly.GetModule(_data);
+
+ if (namedModule == null)
+ throw new SerializationException(
+ SR.Format(SR.Serialization_UnableToFindModule, _data, _assemblyName));
+
+ return namedModule;
+ }
+
+ case AssemblyUnity:
+ {
+ if (_data == null || _data.Length == 0)
+ ThrowInsufficientInformation("Data");
+
+ if (_assemblyName == null)
+ ThrowInsufficientInformation("AssemblyName");
+
+ assembly = Assembly.Load(_assemblyName);
+
+ return assembly;
+ }
+
+ default:
+ throw new ArgumentException(SR.Argument_InvalidUnity);
+ }
+ }
+#endregion
+ }
+}
diff --git a/src/mscorlib/shared/System/ValueTuple.cs b/src/mscorlib/shared/System/ValueTuple.cs
new file mode 100644
index 0000000000..e0cd02e914
--- /dev/null
+++ b/src/mscorlib/shared/System/ValueTuple.cs
@@ -0,0 +1,2324 @@
+// 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.Collections;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using HashHelpers = System.Numerics.Hashing.HashHelpers;
+
+namespace System
+{
+ /// <summary>
+ /// Helper so we can call some tuple methods recursively without knowing the underlying types.
+ /// </summary>
+ internal interface IValueTupleInternal : ITuple
+ {
+ int GetHashCode(IEqualityComparer comparer);
+ string ToStringEnd();
+ }
+
+ /// <summary>
+ /// The ValueTuple types (from arity 0 to 8) comprise the runtime implementation that underlies tuples in C# and struct tuples in F#.
+ /// Aside from created via language syntax, they are most easily created via the ValueTuple.Create factory methods.
+ /// The System.ValueTuple types differ from the System.Tuple types in that:
+ /// - they are structs rather than classes,
+ /// - they are mutable rather than readonly, and
+ /// - their members (such as Item1, Item2, etc) are fields rather than properties.
+ /// </summary>
+ [Serializable]
+ public struct ValueTuple
+ : IEquatable<ValueTuple>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple>, IValueTupleInternal, ITuple
+ {
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple"/> instance is equal to a specified object.
+ /// </summary>
+ /// <param name="obj">The object to compare with this instance.</param>
+ /// <returns><see langword="true"/> if <paramref name="obj"/> is a <see cref="ValueTuple"/>.</returns>
+ public override bool Equals(object obj)
+ {
+ return obj is ValueTuple;
+ }
+
+ /// <summary>Returns a value indicating whether this instance is equal to a specified value.</summary>
+ /// <param name="other">An instance to compare to this instance.</param>
+ /// <returns>true if <paramref name="other"/> has the same value as this instance; otherwise, false.</returns>
+ public bool Equals(ValueTuple other)
+ {
+ return true;
+ }
+
+ bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
+ {
+ return other is ValueTuple;
+ }
+
+ int IComparable.CompareTo(object other)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ return 0;
+ }
+
+ /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
+ /// <param name="other">An instance to compare.</param>
+ /// <returns>
+ /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
+ /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
+ /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
+ /// than <paramref name="other"/>.
+ /// </returns>
+ public int CompareTo(ValueTuple other)
+ {
+ return 0;
+ }
+
+ int IStructuralComparable.CompareTo(object other, IComparer comparer)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ return 0;
+ }
+
+ /// <summary>Returns the hash code for this instance.</summary>
+ /// <returns>A 32-bit signed integer hash code.</returns>
+ public override int GetHashCode()
+ {
+ return 0;
+ }
+
+ int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
+ {
+ return 0;
+ }
+
+ int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
+ {
+ return 0;
+ }
+
+ /// <summary>
+ /// Returns a string that represents the value of this <see cref="ValueTuple"/> instance.
+ /// </summary>
+ /// <returns>The string representation of this <see cref="ValueTuple"/> instance.</returns>
+ /// <remarks>
+ /// The string returned by this method takes the form <c>()</c>.
+ /// </remarks>
+ public override string ToString()
+ {
+ return "()";
+ }
+
+ string IValueTupleInternal.ToStringEnd()
+ {
+ return ")";
+ }
+
+ /// <summary>
+ /// The number of positions in this data structure.
+ /// </summary>
+ int ITuple.Length => 0;
+
+ /// <summary>
+ /// Get the element at position <param name="index"/>.
+ /// </summary>
+ object ITuple.this[int index]
+ {
+ get
+ {
+ throw new IndexOutOfRangeException();
+ }
+ }
+
+ /// <summary>Creates a new struct 0-tuple.</summary>
+ /// <returns>A 0-tuple.</returns>
+ public static ValueTuple Create() =>
+ new ValueTuple();
+
+ /// <summary>Creates a new struct 1-tuple, or singleton.</summary>
+ /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
+ /// <param name="item1">The value of the first component of the tuple.</param>
+ /// <returns>A 1-tuple (singleton) whose value is (item1).</returns>
+ public static ValueTuple<T1> Create<T1>(T1 item1) =>
+ new ValueTuple<T1>(item1);
+
+ /// <summary>Creates a new struct 2-tuple, or pair.</summary>
+ /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
+ /// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
+ /// <param name="item1">The value of the first component of the tuple.</param>
+ /// <param name="item2">The value of the second component of the tuple.</param>
+ /// <returns>A 2-tuple (pair) whose value is (item1, item2).</returns>
+ public static ValueTuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2) =>
+ new ValueTuple<T1, T2>(item1, item2);
+
+ /// <summary>Creates a new struct 3-tuple, or triple.</summary>
+ /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
+ /// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
+ /// <typeparam name="T3">The type of the third component of the tuple.</typeparam>
+ /// <param name="item1">The value of the first component of the tuple.</param>
+ /// <param name="item2">The value of the second component of the tuple.</param>
+ /// <param name="item3">The value of the third component of the tuple.</param>
+ /// <returns>A 3-tuple (triple) whose value is (item1, item2, item3).</returns>
+ public static ValueTuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3) =>
+ new ValueTuple<T1, T2, T3>(item1, item2, item3);
+
+ /// <summary>Creates a new struct 4-tuple, or quadruple.</summary>
+ /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
+ /// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
+ /// <typeparam name="T3">The type of the third component of the tuple.</typeparam>
+ /// <typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
+ /// <param name="item1">The value of the first component of the tuple.</param>
+ /// <param name="item2">The value of the second component of the tuple.</param>
+ /// <param name="item3">The value of the third component of the tuple.</param>
+ /// <param name="item4">The value of the fourth component of the tuple.</param>
+ /// <returns>A 4-tuple (quadruple) whose value is (item1, item2, item3, item4).</returns>
+ public static ValueTuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 item1, T2 item2, T3 item3, T4 item4) =>
+ new ValueTuple<T1, T2, T3, T4>(item1, item2, item3, item4);
+
+ /// <summary>Creates a new struct 5-tuple, or quintuple.</summary>
+ /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
+ /// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
+ /// <typeparam name="T3">The type of the third component of the tuple.</typeparam>
+ /// <typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
+ /// <typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
+ /// <param name="item1">The value of the first component of the tuple.</param>
+ /// <param name="item2">The value of the second component of the tuple.</param>
+ /// <param name="item3">The value of the third component of the tuple.</param>
+ /// <param name="item4">The value of the fourth component of the tuple.</param>
+ /// <param name="item5">The value of the fifth component of the tuple.</param>
+ /// <returns>A 5-tuple (quintuple) whose value is (item1, item2, item3, item4, item5).</returns>
+ public static ValueTuple<T1, T2, T3, T4, T5> Create<T1, T2, T3, T4, T5>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) =>
+ new ValueTuple<T1, T2, T3, T4, T5>(item1, item2, item3, item4, item5);
+
+ /// <summary>Creates a new struct 6-tuple, or sextuple.</summary>
+ /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
+ /// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
+ /// <typeparam name="T3">The type of the third component of the tuple.</typeparam>
+ /// <typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
+ /// <typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
+ /// <typeparam name="T6">The type of the sixth component of the tuple.</typeparam>
+ /// <param name="item1">The value of the first component of the tuple.</param>
+ /// <param name="item2">The value of the second component of the tuple.</param>
+ /// <param name="item3">The value of the third component of the tuple.</param>
+ /// <param name="item4">The value of the fourth component of the tuple.</param>
+ /// <param name="item5">The value of the fifth component of the tuple.</param>
+ /// <param name="item6">The value of the sixth component of the tuple.</param>
+ /// <returns>A 6-tuple (sextuple) whose value is (item1, item2, item3, item4, item5, item6).</returns>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6> Create<T1, T2, T3, T4, T5, T6>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) =>
+ new ValueTuple<T1, T2, T3, T4, T5, T6>(item1, item2, item3, item4, item5, item6);
+
+ /// <summary>Creates a new struct 7-tuple, or septuple.</summary>
+ /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
+ /// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
+ /// <typeparam name="T3">The type of the third component of the tuple.</typeparam>
+ /// <typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
+ /// <typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
+ /// <typeparam name="T6">The type of the sixth component of the tuple.</typeparam>
+ /// <typeparam name="T7">The type of the seventh component of the tuple.</typeparam>
+ /// <param name="item1">The value of the first component of the tuple.</param>
+ /// <param name="item2">The value of the second component of the tuple.</param>
+ /// <param name="item3">The value of the third component of the tuple.</param>
+ /// <param name="item4">The value of the fourth component of the tuple.</param>
+ /// <param name="item5">The value of the fifth component of the tuple.</param>
+ /// <param name="item6">The value of the sixth component of the tuple.</param>
+ /// <param name="item7">The value of the seventh component of the tuple.</param>
+ /// <returns>A 7-tuple (septuple) whose value is (item1, item2, item3, item4, item5, item6, item7).</returns>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7> Create<T1, T2, T3, T4, T5, T6, T7>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) =>
+ new ValueTuple<T1, T2, T3, T4, T5, T6, T7>(item1, item2, item3, item4, item5, item6, item7);
+
+ /// <summary>Creates a new struct 8-tuple, or octuple.</summary>
+ /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
+ /// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
+ /// <typeparam name="T3">The type of the third component of the tuple.</typeparam>
+ /// <typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
+ /// <typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
+ /// <typeparam name="T6">The type of the sixth component of the tuple.</typeparam>
+ /// <typeparam name="T7">The type of the seventh component of the tuple.</typeparam>
+ /// <typeparam name="T8">The type of the eighth component of the tuple.</typeparam>
+ /// <param name="item1">The value of the first component of the tuple.</param>
+ /// <param name="item2">The value of the second component of the tuple.</param>
+ /// <param name="item3">The value of the third component of the tuple.</param>
+ /// <param name="item4">The value of the fourth component of the tuple.</param>
+ /// <param name="item5">The value of the fifth component of the tuple.</param>
+ /// <param name="item6">The value of the sixth component of the tuple.</param>
+ /// <param name="item7">The value of the seventh component of the tuple.</param>
+ /// <param name="item8">The value of the eighth component of the tuple.</param>
+ /// <returns>An 8-tuple (octuple) whose value is (item1, item2, item3, item4, item5, item6, item7, item8).</returns>
+ public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8>> Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) =>
+ new ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8>>(item1, item2, item3, item4, item5, item6, item7, ValueTuple.Create(item8));
+
+ internal static int CombineHashCodes(int h1, int h2)
+ {
+ return HashHelpers.Combine(HashHelpers.Combine(HashHelpers.RandomSeed, h1), h2);
+ }
+
+ internal static int CombineHashCodes(int h1, int h2, int h3)
+ {
+ return HashHelpers.Combine(CombineHashCodes(h1, h2), h3);
+ }
+
+ internal static int CombineHashCodes(int h1, int h2, int h3, int h4)
+ {
+ return HashHelpers.Combine(CombineHashCodes(h1, h2, h3), h4);
+ }
+
+ internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5)
+ {
+ return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4), h5);
+ }
+
+ internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6)
+ {
+ return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5), h6);
+ }
+
+ internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7)
+ {
+ return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6), h7);
+ }
+
+ internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8)
+ {
+ return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7), h8);
+ }
+ }
+
+ /// <summary>Represents a 1-tuple, or singleton, as a value type.</summary>
+ /// <typeparam name="T1">The type of the tuple's only component.</typeparam>
+ [Serializable]
+ public struct ValueTuple<T1>
+ : IEquatable<ValueTuple<T1>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1>>, IValueTupleInternal, ITuple
+ {
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1}"/> instance's first component.
+ /// </summary>
+ public T1 Item1;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ValueTuple{T1}"/> value type.
+ /// </summary>
+ /// <param name="item1">The value of the tuple's first component.</param>
+ public ValueTuple(T1 item1)
+ {
+ Item1 = item1;
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1}"/> instance is equal to a specified object.
+ /// </summary>
+ /// <param name="obj">The object to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
+ /// <remarks>
+ /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
+ /// <list type="bullet">
+ /// <item><description>It is a <see cref="ValueTuple{T1}"/> value type.</description></item>
+ /// <item><description>Its components are of the same types as those of the current instance.</description></item>
+ /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
+ /// </list>
+ /// </remarks>
+ public override bool Equals(object obj)
+ {
+ return obj is ValueTuple<T1> && Equals((ValueTuple<T1>)obj);
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1}"/>
+ /// instance is equal to a specified <see cref="ValueTuple{T1}"/>.
+ /// </summary>
+ /// <param name="other">The tuple to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
+ /// <remarks>
+ /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its field
+ /// is equal to that of the current instance, using the default comparer for that field's type.
+ /// </remarks>
+ public bool Equals(ValueTuple<T1> other)
+ {
+ return EqualityComparer<T1>.Default.Equals(Item1, other.Item1);
+ }
+
+ bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
+ {
+ if (other == null || !(other is ValueTuple<T1>)) return false;
+
+ var objTuple = (ValueTuple<T1>)other;
+
+ return comparer.Equals(Item1, objTuple.Item1);
+ }
+
+ int IComparable.CompareTo(object other)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ var objTuple = (ValueTuple<T1>)other;
+
+ return Comparer<T1>.Default.Compare(Item1, objTuple.Item1);
+ }
+
+ /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
+ /// <param name="other">An instance to compare.</param>
+ /// <returns>
+ /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
+ /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
+ /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
+ /// than <paramref name="other"/>.
+ /// </returns>
+ public int CompareTo(ValueTuple<T1> other)
+ {
+ return Comparer<T1>.Default.Compare(Item1, other.Item1);
+ }
+
+ int IStructuralComparable.CompareTo(object other, IComparer comparer)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ var objTuple = (ValueTuple<T1>)other;
+
+ return comparer.Compare(Item1, objTuple.Item1);
+ }
+
+ /// <summary>
+ /// Returns the hash code for the current <see cref="ValueTuple{T1}"/> instance.
+ /// </summary>
+ /// <returns>A 32-bit signed integer hash code.</returns>
+ public override int GetHashCode()
+ {
+ return Item1?.GetHashCode() ?? 0;
+ }
+
+ int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
+ {
+ return comparer.GetHashCode(Item1);
+ }
+
+ int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
+ {
+ return comparer.GetHashCode(Item1);
+ }
+
+ /// <summary>
+ /// Returns a string that represents the value of this <see cref="ValueTuple{T1}"/> instance.
+ /// </summary>
+ /// <returns>The string representation of this <see cref="ValueTuple{T1}"/> instance.</returns>
+ /// <remarks>
+ /// The string returned by this method takes the form <c>(Item1)</c>,
+ /// where <c>Item1</c> represents the value of <see cref="Item1"/>. If the field is <see langword="null"/>,
+ /// it is represented as <see cref="string.Empty"/>.
+ /// </remarks>
+ public override string ToString()
+ {
+ return "(" + Item1?.ToString() + ")";
+ }
+
+ string IValueTupleInternal.ToStringEnd()
+ {
+ return Item1?.ToString() + ")";
+ }
+
+ /// <summary>
+ /// The number of positions in this data structure.
+ /// </summary>
+ int ITuple.Length => 1;
+
+ /// <summary>
+ /// Get the element at position <param name="index"/>.
+ /// </summary>
+ object ITuple.this[int index]
+ {
+ get
+ {
+ if (index != 0)
+ {
+ throw new IndexOutOfRangeException();
+ }
+ return Item1;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Represents a 2-tuple, or pair, as a value type.
+ /// </summary>
+ /// <typeparam name="T1">The type of the tuple's first component.</typeparam>
+ /// <typeparam name="T2">The type of the tuple's second component.</typeparam>
+ [Serializable]
+ [StructLayout(LayoutKind.Auto)]
+ public struct ValueTuple<T1, T2>
+ : IEquatable<ValueTuple<T1, T2>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2>>, IValueTupleInternal, ITuple
+ {
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2}"/> instance's first component.
+ /// </summary>
+ public T1 Item1;
+
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2}"/> instance's first component.
+ /// </summary>
+ public T2 Item2;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ValueTuple{T1, T2}"/> value type.
+ /// </summary>
+ /// <param name="item1">The value of the tuple's first component.</param>
+ /// <param name="item2">The value of the tuple's second component.</param>
+ public ValueTuple(T1 item1, T2 item2)
+ {
+ Item1 = item1;
+ Item2 = item2;
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2}"/> instance is equal to a specified object.
+ /// </summary>
+ /// <param name="obj">The object to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
+ ///
+ /// <remarks>
+ /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
+ /// <list type="bullet">
+ /// <item><description>It is a <see cref="ValueTuple{T1, T2}"/> value type.</description></item>
+ /// <item><description>Its components are of the same types as those of the current instance.</description></item>
+ /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
+ /// </list>
+ /// </remarks>
+ public override bool Equals(object obj)
+ {
+ return obj is ValueTuple<T1, T2> && Equals((ValueTuple<T1, T2>)obj);
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2}"/> instance is equal to a specified <see cref="ValueTuple{T1, T2}"/>.
+ /// </summary>
+ /// <param name="other">The tuple to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
+ /// <remarks>
+ /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its fields
+ /// are equal to that of the current instance, using the default comparer for that field's type.
+ /// </remarks>
+ public bool Equals(ValueTuple<T1, T2> other)
+ {
+ return EqualityComparer<T1>.Default.Equals(Item1, other.Item1)
+ && EqualityComparer<T2>.Default.Equals(Item2, other.Item2);
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2}"/> instance is equal to a specified object based on a specified comparison method.
+ /// </summary>
+ /// <param name="other">The object to compare with this instance.</param>
+ /// <param name="comparer">An object that defines the method to use to evaluate whether the two objects are equal.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
+ ///
+ /// <remarks>
+ /// This member is an explicit interface member implementation. It can be used only when the
+ /// <see cref="ValueTuple{T1, T2}"/> instance is cast to an <see cref="IStructuralEquatable"/> interface.
+ ///
+ /// The <see cref="IEqualityComparer.Equals"/> implementation is called only if <c>other</c> is not <see langword="null"/>,
+ /// and if it can be successfully cast (in C#) or converted (in Visual Basic) to a <see cref="ValueTuple{T1, T2}"/>
+ /// whose components are of the same types as those of the current instance. The IStructuralEquatable.Equals(Object, IEqualityComparer) method
+ /// first passes the <see cref="Item1"/> values of the <see cref="ValueTuple{T1, T2}"/> objects to be compared to the
+ /// <see cref="IEqualityComparer.Equals"/> implementation. If this method call returns <see langword="true"/>, the method is
+ /// called again and passed the <see cref="Item2"/> values of the two <see cref="ValueTuple{T1, T2}"/> instances.
+ /// </remarks>
+ bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
+ {
+ if (other == null || !(other is ValueTuple<T1, T2>)) return false;
+
+ var objTuple = (ValueTuple<T1, T2>)other;
+
+ return comparer.Equals(Item1, objTuple.Item1)
+ && comparer.Equals(Item2, objTuple.Item2);
+ }
+
+ int IComparable.CompareTo(object other)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1, T2>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ return CompareTo((ValueTuple<T1, T2>)other);
+ }
+
+ /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
+ /// <param name="other">An instance to compare.</param>
+ /// <returns>
+ /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
+ /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
+ /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
+ /// than <paramref name="other"/>.
+ /// </returns>
+ public int CompareTo(ValueTuple<T1, T2> other)
+ {
+ int c = Comparer<T1>.Default.Compare(Item1, other.Item1);
+ if (c != 0) return c;
+
+ return Comparer<T2>.Default.Compare(Item2, other.Item2);
+ }
+
+ int IStructuralComparable.CompareTo(object other, IComparer comparer)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1, T2>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ var objTuple = (ValueTuple<T1, T2>)other;
+
+ int c = comparer.Compare(Item1, objTuple.Item1);
+ if (c != 0) return c;
+
+ return comparer.Compare(Item2, objTuple.Item2);
+ }
+
+ /// <summary>
+ /// Returns the hash code for the current <see cref="ValueTuple{T1, T2}"/> instance.
+ /// </summary>
+ /// <returns>A 32-bit signed integer hash code.</returns>
+ public override int GetHashCode()
+ {
+ return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
+ Item2?.GetHashCode() ?? 0);
+ }
+
+ int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
+ {
+ return GetHashCodeCore(comparer);
+ }
+
+ private int GetHashCodeCore(IEqualityComparer comparer)
+ {
+ return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
+ comparer.GetHashCode(Item2));
+ }
+
+ int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
+ {
+ return GetHashCodeCore(comparer);
+ }
+
+ /// <summary>
+ /// Returns a string that represents the value of this <see cref="ValueTuple{T1, T2}"/> instance.
+ /// </summary>
+ /// <returns>The string representation of this <see cref="ValueTuple{T1, T2}"/> instance.</returns>
+ /// <remarks>
+ /// The string returned by this method takes the form <c>(Item1, Item2)</c>,
+ /// where <c>Item1</c> and <c>Item2</c> represent the values of the <see cref="Item1"/>
+ /// and <see cref="Item2"/> fields. If either field value is <see langword="null"/>,
+ /// it is represented as <see cref="String.Empty"/>.
+ /// </remarks>
+ public override string ToString()
+ {
+ return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ")";
+ }
+
+ string IValueTupleInternal.ToStringEnd()
+ {
+ return Item1?.ToString() + ", " + Item2?.ToString() + ")";
+ }
+
+ /// <summary>
+ /// The number of positions in this data structure.
+ /// </summary>
+ int ITuple.Length => 2;
+
+ /// <summary>
+ /// Get the element at position <param name="index"/>.
+ /// </summary>
+ object ITuple.this[int index]
+ {
+ get
+ {
+ switch (index)
+ {
+ case 0:
+ return Item1;
+ case 1:
+ return Item2;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Represents a 3-tuple, or triple, as a value type.
+ /// </summary>
+ /// <typeparam name="T1">The type of the tuple's first component.</typeparam>
+ /// <typeparam name="T2">The type of the tuple's second component.</typeparam>
+ /// <typeparam name="T3">The type of the tuple's third component.</typeparam>
+ [Serializable]
+ [StructLayout(LayoutKind.Auto)]
+ public struct ValueTuple<T1, T2, T3>
+ : IEquatable<ValueTuple<T1, T2, T3>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2, T3>>, IValueTupleInternal, ITuple
+ {
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3}"/> instance's first component.
+ /// </summary>
+ public T1 Item1;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3}"/> instance's second component.
+ /// </summary>
+ public T2 Item2;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3}"/> instance's third component.
+ /// </summary>
+ public T3 Item3;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ValueTuple{T1, T2, T3}"/> value type.
+ /// </summary>
+ /// <param name="item1">The value of the tuple's first component.</param>
+ /// <param name="item2">The value of the tuple's second component.</param>
+ /// <param name="item3">The value of the tuple's third component.</param>
+ public ValueTuple(T1 item1, T2 item2, T3 item3)
+ {
+ Item1 = item1;
+ Item2 = item2;
+ Item3 = item3;
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3}"/> instance is equal to a specified object.
+ /// </summary>
+ /// <param name="obj">The object to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
+ /// <remarks>
+ /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
+ /// <list type="bullet">
+ /// <item><description>It is a <see cref="ValueTuple{T1, T2, T3}"/> value type.</description></item>
+ /// <item><description>Its components are of the same types as those of the current instance.</description></item>
+ /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
+ /// </list>
+ /// </remarks>
+ public override bool Equals(object obj)
+ {
+ return obj is ValueTuple<T1, T2, T3> && Equals((ValueTuple<T1, T2, T3>)obj);
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3}"/>
+ /// instance is equal to a specified <see cref="ValueTuple{T1, T2, T3}"/>.
+ /// </summary>
+ /// <param name="other">The tuple to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
+ /// <remarks>
+ /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its fields
+ /// are equal to that of the current instance, using the default comparer for that field's type.
+ /// </remarks>
+ public bool Equals(ValueTuple<T1, T2, T3> other)
+ {
+ return EqualityComparer<T1>.Default.Equals(Item1, other.Item1)
+ && EqualityComparer<T2>.Default.Equals(Item2, other.Item2)
+ && EqualityComparer<T3>.Default.Equals(Item3, other.Item3);
+ }
+
+ bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
+ {
+ if (other == null || !(other is ValueTuple<T1, T2, T3>)) return false;
+
+ var objTuple = (ValueTuple<T1, T2, T3>)other;
+
+ return comparer.Equals(Item1, objTuple.Item1)
+ && comparer.Equals(Item2, objTuple.Item2)
+ && comparer.Equals(Item3, objTuple.Item3);
+ }
+
+ int IComparable.CompareTo(object other)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1, T2, T3>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ return CompareTo((ValueTuple<T1, T2, T3>)other);
+ }
+
+ /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
+ /// <param name="other">An instance to compare.</param>
+ /// <returns>
+ /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
+ /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
+ /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
+ /// than <paramref name="other"/>.
+ /// </returns>
+ public int CompareTo(ValueTuple<T1, T2, T3> other)
+ {
+ int c = Comparer<T1>.Default.Compare(Item1, other.Item1);
+ if (c != 0) return c;
+
+ c = Comparer<T2>.Default.Compare(Item2, other.Item2);
+ if (c != 0) return c;
+
+ return Comparer<T3>.Default.Compare(Item3, other.Item3);
+ }
+
+ int IStructuralComparable.CompareTo(object other, IComparer comparer)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1, T2, T3>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ var objTuple = (ValueTuple<T1, T2, T3>)other;
+
+ int c = comparer.Compare(Item1, objTuple.Item1);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item2, objTuple.Item2);
+ if (c != 0) return c;
+
+ return comparer.Compare(Item3, objTuple.Item3);
+ }
+
+ /// <summary>
+ /// Returns the hash code for the current <see cref="ValueTuple{T1, T2, T3}"/> instance.
+ /// </summary>
+ /// <returns>A 32-bit signed integer hash code.</returns>
+ public override int GetHashCode()
+ {
+ return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
+ Item2?.GetHashCode() ?? 0,
+ Item3?.GetHashCode() ?? 0);
+ }
+
+ int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
+ {
+ return GetHashCodeCore(comparer);
+ }
+
+ private int GetHashCodeCore(IEqualityComparer comparer)
+ {
+ return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
+ comparer.GetHashCode(Item2),
+ comparer.GetHashCode(Item3));
+ }
+
+ int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
+ {
+ return GetHashCodeCore(comparer);
+ }
+
+ /// <summary>
+ /// Returns a string that represents the value of this <see cref="ValueTuple{T1, T2, T3}"/> instance.
+ /// </summary>
+ /// <returns>The string representation of this <see cref="ValueTuple{T1, T2, T3}"/> instance.</returns>
+ /// <remarks>
+ /// The string returned by this method takes the form <c>(Item1, Item2, Item3)</c>.
+ /// If any field value is <see langword="null"/>, it is represented as <see cref="String.Empty"/>.
+ /// </remarks>
+ public override string ToString()
+ {
+ return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")";
+ }
+
+ string IValueTupleInternal.ToStringEnd()
+ {
+ return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")";
+ }
+
+ /// <summary>
+ /// The number of positions in this data structure.
+ /// </summary>
+ int ITuple.Length => 3;
+
+ /// <summary>
+ /// Get the element at position <param name="index"/>.
+ /// </summary>
+ object ITuple.this[int index]
+ {
+ get
+ {
+ switch (index)
+ {
+ case 0:
+ return Item1;
+ case 1:
+ return Item2;
+ case 2:
+ return Item3;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Represents a 4-tuple, or quadruple, as a value type.
+ /// </summary>
+ /// <typeparam name="T1">The type of the tuple's first component.</typeparam>
+ /// <typeparam name="T2">The type of the tuple's second component.</typeparam>
+ /// <typeparam name="T3">The type of the tuple's third component.</typeparam>
+ /// <typeparam name="T4">The type of the tuple's fourth component.</typeparam>
+ [Serializable]
+ [StructLayout(LayoutKind.Auto)]
+ public struct ValueTuple<T1, T2, T3, T4>
+ : IEquatable<ValueTuple<T1, T2, T3, T4>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2, T3, T4>>, IValueTupleInternal, ITuple
+ {
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4}"/> instance's first component.
+ /// </summary>
+ public T1 Item1;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4}"/> instance's second component.
+ /// </summary>
+ public T2 Item2;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4}"/> instance's third component.
+ /// </summary>
+ public T3 Item3;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4}"/> instance's fourth component.
+ /// </summary>
+ public T4 Item4;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ValueTuple{T1, T2, T3, T4}"/> value type.
+ /// </summary>
+ /// <param name="item1">The value of the tuple's first component.</param>
+ /// <param name="item2">The value of the tuple's second component.</param>
+ /// <param name="item3">The value of the tuple's third component.</param>
+ /// <param name="item4">The value of the tuple's fourth component.</param>
+ public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4)
+ {
+ Item1 = item1;
+ Item2 = item2;
+ Item3 = item3;
+ Item4 = item4;
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4}"/> instance is equal to a specified object.
+ /// </summary>
+ /// <param name="obj">The object to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
+ /// <remarks>
+ /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
+ /// <list type="bullet">
+ /// <item><description>It is a <see cref="ValueTuple{T1, T2, T3, T4}"/> value type.</description></item>
+ /// <item><description>Its components are of the same types as those of the current instance.</description></item>
+ /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
+ /// </list>
+ /// </remarks>
+ public override bool Equals(object obj)
+ {
+ return obj is ValueTuple<T1, T2, T3, T4> && Equals((ValueTuple<T1, T2, T3, T4>)obj);
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4}"/>
+ /// instance is equal to a specified <see cref="ValueTuple{T1, T2, T3, T4}"/>.
+ /// </summary>
+ /// <param name="other">The tuple to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
+ /// <remarks>
+ /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its fields
+ /// are equal to that of the current instance, using the default comparer for that field's type.
+ /// </remarks>
+ public bool Equals(ValueTuple<T1, T2, T3, T4> other)
+ {
+ return EqualityComparer<T1>.Default.Equals(Item1, other.Item1)
+ && EqualityComparer<T2>.Default.Equals(Item2, other.Item2)
+ && EqualityComparer<T3>.Default.Equals(Item3, other.Item3)
+ && EqualityComparer<T4>.Default.Equals(Item4, other.Item4);
+ }
+
+ bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
+ {
+ if (other == null || !(other is ValueTuple<T1, T2, T3, T4>)) return false;
+
+ var objTuple = (ValueTuple<T1, T2, T3, T4>)other;
+
+ return comparer.Equals(Item1, objTuple.Item1)
+ && comparer.Equals(Item2, objTuple.Item2)
+ && comparer.Equals(Item3, objTuple.Item3)
+ && comparer.Equals(Item4, objTuple.Item4);
+ }
+
+ int IComparable.CompareTo(object other)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1, T2, T3, T4>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ return CompareTo((ValueTuple<T1, T2, T3, T4>)other);
+ }
+
+ /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
+ /// <param name="other">An instance to compare.</param>
+ /// <returns>
+ /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
+ /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
+ /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
+ /// than <paramref name="other"/>.
+ /// </returns>
+ public int CompareTo(ValueTuple<T1, T2, T3, T4> other)
+ {
+ int c = Comparer<T1>.Default.Compare(Item1, other.Item1);
+ if (c != 0) return c;
+
+ c = Comparer<T2>.Default.Compare(Item2, other.Item2);
+ if (c != 0) return c;
+
+ c = Comparer<T3>.Default.Compare(Item3, other.Item3);
+ if (c != 0) return c;
+
+ return Comparer<T4>.Default.Compare(Item4, other.Item4);
+ }
+
+ int IStructuralComparable.CompareTo(object other, IComparer comparer)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1, T2, T3, T4>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ var objTuple = (ValueTuple<T1, T2, T3, T4>)other;
+
+ int c = comparer.Compare(Item1, objTuple.Item1);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item2, objTuple.Item2);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item3, objTuple.Item3);
+ if (c != 0) return c;
+
+ return comparer.Compare(Item4, objTuple.Item4);
+ }
+
+ /// <summary>
+ /// Returns the hash code for the current <see cref="ValueTuple{T1, T2, T3, T4}"/> instance.
+ /// </summary>
+ /// <returns>A 32-bit signed integer hash code.</returns>
+ public override int GetHashCode()
+ {
+ return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
+ Item2?.GetHashCode() ?? 0,
+ Item3?.GetHashCode() ?? 0,
+ Item4?.GetHashCode() ?? 0);
+ }
+
+ int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
+ {
+ return GetHashCodeCore(comparer);
+ }
+
+ private int GetHashCodeCore(IEqualityComparer comparer)
+ {
+ return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
+ comparer.GetHashCode(Item2),
+ comparer.GetHashCode(Item3),
+ comparer.GetHashCode(Item4));
+ }
+
+ int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
+ {
+ return GetHashCodeCore(comparer);
+ }
+
+ /// <summary>
+ /// Returns a string that represents the value of this <see cref="ValueTuple{T1, T2, T3, T4}"/> instance.
+ /// </summary>
+ /// <returns>The string representation of this <see cref="ValueTuple{T1, T2, T3, T4}"/> instance.</returns>
+ /// <remarks>
+ /// The string returned by this method takes the form <c>(Item1, Item2, Item3, Item4)</c>.
+ /// If any field value is <see langword="null"/>, it is represented as <see cref="String.Empty"/>.
+ /// </remarks>
+ public override string ToString()
+ {
+ return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")";
+ }
+
+ string IValueTupleInternal.ToStringEnd()
+ {
+ return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")";
+ }
+
+ /// <summary>
+ /// The number of positions in this data structure.
+ /// </summary>
+ int ITuple.Length => 4;
+
+ /// <summary>
+ /// Get the element at position <param name="index"/>.
+ /// </summary>
+ object ITuple.this[int index]
+ {
+ get
+ {
+ switch (index)
+ {
+ case 0:
+ return Item1;
+ case 1:
+ return Item2;
+ case 2:
+ return Item3;
+ case 3:
+ return Item4;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Represents a 5-tuple, or quintuple, as a value type.
+ /// </summary>
+ /// <typeparam name="T1">The type of the tuple's first component.</typeparam>
+ /// <typeparam name="T2">The type of the tuple's second component.</typeparam>
+ /// <typeparam name="T3">The type of the tuple's third component.</typeparam>
+ /// <typeparam name="T4">The type of the tuple's fourth component.</typeparam>
+ /// <typeparam name="T5">The type of the tuple's fifth component.</typeparam>
+ [Serializable]
+ [StructLayout(LayoutKind.Auto)]
+ public struct ValueTuple<T1, T2, T3, T4, T5>
+ : IEquatable<ValueTuple<T1, T2, T3, T4, T5>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2, T3, T4, T5>>, IValueTupleInternal, ITuple
+ {
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance's first component.
+ /// </summary>
+ public T1 Item1;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance's second component.
+ /// </summary>
+ public T2 Item2;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance's third component.
+ /// </summary>
+ public T3 Item3;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance's fourth component.
+ /// </summary>
+ public T4 Item4;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance's fifth component.
+ /// </summary>
+ public T5 Item5;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> value type.
+ /// </summary>
+ /// <param name="item1">The value of the tuple's first component.</param>
+ /// <param name="item2">The value of the tuple's second component.</param>
+ /// <param name="item3">The value of the tuple's third component.</param>
+ /// <param name="item4">The value of the tuple's fourth component.</param>
+ /// <param name="item5">The value of the tuple's fifth component.</param>
+ public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
+ {
+ Item1 = item1;
+ Item2 = item2;
+ Item3 = item3;
+ Item4 = item4;
+ Item5 = item5;
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance is equal to a specified object.
+ /// </summary>
+ /// <param name="obj">The object to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
+ /// <remarks>
+ /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
+ /// <list type="bullet">
+ /// <item><description>It is a <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> value type.</description></item>
+ /// <item><description>Its components are of the same types as those of the current instance.</description></item>
+ /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
+ /// </list>
+ /// </remarks>
+ public override bool Equals(object obj)
+ {
+ return obj is ValueTuple<T1, T2, T3, T4, T5> && Equals((ValueTuple<T1, T2, T3, T4, T5>)obj);
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/>
+ /// instance is equal to a specified <see cref="ValueTuple{T1, T2, T3, T4, T5}"/>.
+ /// </summary>
+ /// <param name="other">The tuple to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
+ /// <remarks>
+ /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its fields
+ /// are equal to that of the current instance, using the default comparer for that field's type.
+ /// </remarks>
+ public bool Equals(ValueTuple<T1, T2, T3, T4, T5> other)
+ {
+ return EqualityComparer<T1>.Default.Equals(Item1, other.Item1)
+ && EqualityComparer<T2>.Default.Equals(Item2, other.Item2)
+ && EqualityComparer<T3>.Default.Equals(Item3, other.Item3)
+ && EqualityComparer<T4>.Default.Equals(Item4, other.Item4)
+ && EqualityComparer<T5>.Default.Equals(Item5, other.Item5);
+ }
+
+ bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
+ {
+ if (other == null || !(other is ValueTuple<T1, T2, T3, T4, T5>)) return false;
+
+ var objTuple = (ValueTuple<T1, T2, T3, T4, T5>)other;
+
+ return comparer.Equals(Item1, objTuple.Item1)
+ && comparer.Equals(Item2, objTuple.Item2)
+ && comparer.Equals(Item3, objTuple.Item3)
+ && comparer.Equals(Item4, objTuple.Item4)
+ && comparer.Equals(Item5, objTuple.Item5);
+ }
+
+ int IComparable.CompareTo(object other)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1, T2, T3, T4, T5>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ return CompareTo((ValueTuple<T1, T2, T3, T4, T5>)other);
+ }
+
+ /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
+ /// <param name="other">An instance to compare.</param>
+ /// <returns>
+ /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
+ /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
+ /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
+ /// than <paramref name="other"/>.
+ /// </returns>
+ public int CompareTo(ValueTuple<T1, T2, T3, T4, T5> other)
+ {
+ int c = Comparer<T1>.Default.Compare(Item1, other.Item1);
+ if (c != 0) return c;
+
+ c = Comparer<T2>.Default.Compare(Item2, other.Item2);
+ if (c != 0) return c;
+
+ c = Comparer<T3>.Default.Compare(Item3, other.Item3);
+ if (c != 0) return c;
+
+ c = Comparer<T4>.Default.Compare(Item4, other.Item4);
+ if (c != 0) return c;
+
+ return Comparer<T5>.Default.Compare(Item5, other.Item5);
+ }
+
+ int IStructuralComparable.CompareTo(object other, IComparer comparer)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1, T2, T3, T4, T5>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ var objTuple = (ValueTuple<T1, T2, T3, T4, T5>)other;
+
+ int c = comparer.Compare(Item1, objTuple.Item1);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item2, objTuple.Item2);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item3, objTuple.Item3);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item4, objTuple.Item4);
+ if (c != 0) return c;
+
+ return comparer.Compare(Item5, objTuple.Item5);
+ }
+
+ /// <summary>
+ /// Returns the hash code for the current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance.
+ /// </summary>
+ /// <returns>A 32-bit signed integer hash code.</returns>
+ public override int GetHashCode()
+ {
+ return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
+ Item2?.GetHashCode() ?? 0,
+ Item3?.GetHashCode() ?? 0,
+ Item4?.GetHashCode() ?? 0,
+ Item5?.GetHashCode() ?? 0);
+ }
+
+ int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
+ {
+ return GetHashCodeCore(comparer);
+ }
+
+ private int GetHashCodeCore(IEqualityComparer comparer)
+ {
+ return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
+ comparer.GetHashCode(Item2),
+ comparer.GetHashCode(Item3),
+ comparer.GetHashCode(Item4),
+ comparer.GetHashCode(Item5));
+ }
+
+ int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
+ {
+ return GetHashCodeCore(comparer);
+ }
+
+ /// <summary>
+ /// Returns a string that represents the value of this <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance.
+ /// </summary>
+ /// <returns>The string representation of this <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance.</returns>
+ /// <remarks>
+ /// The string returned by this method takes the form <c>(Item1, Item2, Item3, Item4, Item5)</c>.
+ /// If any field value is <see langword="null"/>, it is represented as <see cref="String.Empty"/>.
+ /// </remarks>
+ public override string ToString()
+ {
+ return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")";
+ }
+
+ string IValueTupleInternal.ToStringEnd()
+ {
+ return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")";
+ }
+
+ /// <summary>
+ /// The number of positions in this data structure.
+ /// </summary>
+ int ITuple.Length => 5;
+
+ /// <summary>
+ /// Get the element at position <param name="index"/>.
+ /// </summary>
+ object ITuple.this[int index]
+ {
+ get
+ {
+ switch (index)
+ {
+ case 0:
+ return Item1;
+ case 1:
+ return Item2;
+ case 2:
+ return Item3;
+ case 3:
+ return Item4;
+ case 4:
+ return Item5;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Represents a 6-tuple, or sixtuple, as a value type.
+ /// </summary>
+ /// <typeparam name="T1">The type of the tuple's first component.</typeparam>
+ /// <typeparam name="T2">The type of the tuple's second component.</typeparam>
+ /// <typeparam name="T3">The type of the tuple's third component.</typeparam>
+ /// <typeparam name="T4">The type of the tuple's fourth component.</typeparam>
+ /// <typeparam name="T5">The type of the tuple's fifth component.</typeparam>
+ /// <typeparam name="T6">The type of the tuple's sixth component.</typeparam>
+ [Serializable]
+ [StructLayout(LayoutKind.Auto)]
+ public struct ValueTuple<T1, T2, T3, T4, T5, T6>
+ : IEquatable<ValueTuple<T1, T2, T3, T4, T5, T6>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2, T3, T4, T5, T6>>, IValueTupleInternal, ITuple
+ {
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance's first component.
+ /// </summary>
+ public T1 Item1;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance's second component.
+ /// </summary>
+ public T2 Item2;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance's third component.
+ /// </summary>
+ public T3 Item3;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance's fourth component.
+ /// </summary>
+ public T4 Item4;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance's fifth component.
+ /// </summary>
+ public T5 Item5;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance's sixth component.
+ /// </summary>
+ public T6 Item6;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> value type.
+ /// </summary>
+ /// <param name="item1">The value of the tuple's first component.</param>
+ /// <param name="item2">The value of the tuple's second component.</param>
+ /// <param name="item3">The value of the tuple's third component.</param>
+ /// <param name="item4">The value of the tuple's fourth component.</param>
+ /// <param name="item5">The value of the tuple's fifth component.</param>
+ /// <param name="item6">The value of the tuple's sixth component.</param>
+ public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
+ {
+ Item1 = item1;
+ Item2 = item2;
+ Item3 = item3;
+ Item4 = item4;
+ Item5 = item5;
+ Item6 = item6;
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance is equal to a specified object.
+ /// </summary>
+ /// <param name="obj">The object to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
+ /// <remarks>
+ /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
+ /// <list type="bullet">
+ /// <item><description>It is a <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> value type.</description></item>
+ /// <item><description>Its components are of the same types as those of the current instance.</description></item>
+ /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
+ /// </list>
+ /// </remarks>
+ public override bool Equals(object obj)
+ {
+ return obj is ValueTuple<T1, T2, T3, T4, T5, T6> && Equals((ValueTuple<T1, T2, T3, T4, T5, T6>)obj);
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/>
+ /// instance is equal to a specified <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/>.
+ /// </summary>
+ /// <param name="other">The tuple to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
+ /// <remarks>
+ /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its fields
+ /// are equal to that of the current instance, using the default comparer for that field's type.
+ /// </remarks>
+ public bool Equals(ValueTuple<T1, T2, T3, T4, T5, T6> other)
+ {
+ return EqualityComparer<T1>.Default.Equals(Item1, other.Item1)
+ && EqualityComparer<T2>.Default.Equals(Item2, other.Item2)
+ && EqualityComparer<T3>.Default.Equals(Item3, other.Item3)
+ && EqualityComparer<T4>.Default.Equals(Item4, other.Item4)
+ && EqualityComparer<T5>.Default.Equals(Item5, other.Item5)
+ && EqualityComparer<T6>.Default.Equals(Item6, other.Item6);
+ }
+
+ bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
+ {
+ if (other == null || !(other is ValueTuple<T1, T2, T3, T4, T5, T6>)) return false;
+
+ var objTuple = (ValueTuple<T1, T2, T3, T4, T5, T6>)other;
+
+ return comparer.Equals(Item1, objTuple.Item1)
+ && comparer.Equals(Item2, objTuple.Item2)
+ && comparer.Equals(Item3, objTuple.Item3)
+ && comparer.Equals(Item4, objTuple.Item4)
+ && comparer.Equals(Item5, objTuple.Item5)
+ && comparer.Equals(Item6, objTuple.Item6);
+ }
+
+ int IComparable.CompareTo(object other)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ return CompareTo((ValueTuple<T1, T2, T3, T4, T5, T6>)other);
+ }
+
+ /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
+ /// <param name="other">An instance to compare.</param>
+ /// <returns>
+ /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
+ /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
+ /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
+ /// than <paramref name="other"/>.
+ /// </returns>
+ public int CompareTo(ValueTuple<T1, T2, T3, T4, T5, T6> other)
+ {
+ int c = Comparer<T1>.Default.Compare(Item1, other.Item1);
+ if (c != 0) return c;
+
+ c = Comparer<T2>.Default.Compare(Item2, other.Item2);
+ if (c != 0) return c;
+
+ c = Comparer<T3>.Default.Compare(Item3, other.Item3);
+ if (c != 0) return c;
+
+ c = Comparer<T4>.Default.Compare(Item4, other.Item4);
+ if (c != 0) return c;
+
+ c = Comparer<T5>.Default.Compare(Item5, other.Item5);
+ if (c != 0) return c;
+
+ return Comparer<T6>.Default.Compare(Item6, other.Item6);
+ }
+
+ int IStructuralComparable.CompareTo(object other, IComparer comparer)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ var objTuple = (ValueTuple<T1, T2, T3, T4, T5, T6>)other;
+
+ int c = comparer.Compare(Item1, objTuple.Item1);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item2, objTuple.Item2);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item3, objTuple.Item3);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item4, objTuple.Item4);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item5, objTuple.Item5);
+ if (c != 0) return c;
+
+ return comparer.Compare(Item6, objTuple.Item6);
+ }
+
+ /// <summary>
+ /// Returns the hash code for the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance.
+ /// </summary>
+ /// <returns>A 32-bit signed integer hash code.</returns>
+ public override int GetHashCode()
+ {
+ return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
+ Item2?.GetHashCode() ?? 0,
+ Item3?.GetHashCode() ?? 0,
+ Item4?.GetHashCode() ?? 0,
+ Item5?.GetHashCode() ?? 0,
+ Item6?.GetHashCode() ?? 0);
+ }
+
+ int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
+ {
+ return GetHashCodeCore(comparer);
+ }
+
+ private int GetHashCodeCore(IEqualityComparer comparer)
+ {
+ return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
+ comparer.GetHashCode(Item2),
+ comparer.GetHashCode(Item3),
+ comparer.GetHashCode(Item4),
+ comparer.GetHashCode(Item5),
+ comparer.GetHashCode(Item6));
+ }
+
+ int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
+ {
+ return GetHashCodeCore(comparer);
+ }
+
+ /// <summary>
+ /// Returns a string that represents the value of this <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance.
+ /// </summary>
+ /// <returns>The string representation of this <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance.</returns>
+ /// <remarks>
+ /// The string returned by this method takes the form <c>(Item1, Item2, Item3, Item4, Item5, Item6)</c>.
+ /// If any field value is <see langword="null"/>, it is represented as <see cref="String.Empty"/>.
+ /// </remarks>
+ public override string ToString()
+ {
+ return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")";
+ }
+
+ string IValueTupleInternal.ToStringEnd()
+ {
+ return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")";
+ }
+
+ /// <summary>
+ /// The number of positions in this data structure.
+ /// </summary>
+ int ITuple.Length => 6;
+
+ /// <summary>
+ /// Get the element at position <param name="index"/>.
+ /// </summary>
+ object ITuple.this[int index]
+ {
+ get
+ {
+ switch (index)
+ {
+ case 0:
+ return Item1;
+ case 1:
+ return Item2;
+ case 2:
+ return Item3;
+ case 3:
+ return Item4;
+ case 4:
+ return Item5;
+ case 5:
+ return Item6;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Represents a 7-tuple, or sentuple, as a value type.
+ /// </summary>
+ /// <typeparam name="T1">The type of the tuple's first component.</typeparam>
+ /// <typeparam name="T2">The type of the tuple's second component.</typeparam>
+ /// <typeparam name="T3">The type of the tuple's third component.</typeparam>
+ /// <typeparam name="T4">The type of the tuple's fourth component.</typeparam>
+ /// <typeparam name="T5">The type of the tuple's fifth component.</typeparam>
+ /// <typeparam name="T6">The type of the tuple's sixth component.</typeparam>
+ /// <typeparam name="T7">The type of the tuple's seventh component.</typeparam>
+ [Serializable]
+ [StructLayout(LayoutKind.Auto)]
+ public struct ValueTuple<T1, T2, T3, T4, T5, T6, T7>
+ : IEquatable<ValueTuple<T1, T2, T3, T4, T5, T6, T7>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2, T3, T4, T5, T6, T7>>, IValueTupleInternal, ITuple
+ {
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance's first component.
+ /// </summary>
+ public T1 Item1;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance's second component.
+ /// </summary>
+ public T2 Item2;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance's third component.
+ /// </summary>
+ public T3 Item3;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance's fourth component.
+ /// </summary>
+ public T4 Item4;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance's fifth component.
+ /// </summary>
+ public T5 Item5;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance's sixth component.
+ /// </summary>
+ public T6 Item6;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance's seventh component.
+ /// </summary>
+ public T7 Item7;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> value type.
+ /// </summary>
+ /// <param name="item1">The value of the tuple's first component.</param>
+ /// <param name="item2">The value of the tuple's second component.</param>
+ /// <param name="item3">The value of the tuple's third component.</param>
+ /// <param name="item4">The value of the tuple's fourth component.</param>
+ /// <param name="item5">The value of the tuple's fifth component.</param>
+ /// <param name="item6">The value of the tuple's sixth component.</param>
+ /// <param name="item7">The value of the tuple's seventh component.</param>
+ public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
+ {
+ Item1 = item1;
+ Item2 = item2;
+ Item3 = item3;
+ Item4 = item4;
+ Item5 = item5;
+ Item6 = item6;
+ Item7 = item7;
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance is equal to a specified object.
+ /// </summary>
+ /// <param name="obj">The object to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
+ /// <remarks>
+ /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
+ /// <list type="bullet">
+ /// <item><description>It is a <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> value type.</description></item>
+ /// <item><description>Its components are of the same types as those of the current instance.</description></item>
+ /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
+ /// </list>
+ /// </remarks>
+ public override bool Equals(object obj)
+ {
+ return obj is ValueTuple<T1, T2, T3, T4, T5, T6, T7> && Equals((ValueTuple<T1, T2, T3, T4, T5, T6, T7>)obj);
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/>
+ /// instance is equal to a specified <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/>.
+ /// </summary>
+ /// <param name="other">The tuple to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
+ /// <remarks>
+ /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its fields
+ /// are equal to that of the current instance, using the default comparer for that field's type.
+ /// </remarks>
+ public bool Equals(ValueTuple<T1, T2, T3, T4, T5, T6, T7> other)
+ {
+ return EqualityComparer<T1>.Default.Equals(Item1, other.Item1)
+ && EqualityComparer<T2>.Default.Equals(Item2, other.Item2)
+ && EqualityComparer<T3>.Default.Equals(Item3, other.Item3)
+ && EqualityComparer<T4>.Default.Equals(Item4, other.Item4)
+ && EqualityComparer<T5>.Default.Equals(Item5, other.Item5)
+ && EqualityComparer<T6>.Default.Equals(Item6, other.Item6)
+ && EqualityComparer<T7>.Default.Equals(Item7, other.Item7);
+ }
+
+ bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
+ {
+ if (other == null || !(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7>)) return false;
+
+ var objTuple = (ValueTuple<T1, T2, T3, T4, T5, T6, T7>)other;
+
+ return comparer.Equals(Item1, objTuple.Item1)
+ && comparer.Equals(Item2, objTuple.Item2)
+ && comparer.Equals(Item3, objTuple.Item3)
+ && comparer.Equals(Item4, objTuple.Item4)
+ && comparer.Equals(Item5, objTuple.Item5)
+ && comparer.Equals(Item6, objTuple.Item6)
+ && comparer.Equals(Item7, objTuple.Item7);
+ }
+
+ int IComparable.CompareTo(object other)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ return CompareTo((ValueTuple<T1, T2, T3, T4, T5, T6, T7>)other);
+ }
+
+ /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
+ /// <param name="other">An instance to compare.</param>
+ /// <returns>
+ /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
+ /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
+ /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
+ /// than <paramref name="other"/>.
+ /// </returns>
+ public int CompareTo(ValueTuple<T1, T2, T3, T4, T5, T6, T7> other)
+ {
+ int c = Comparer<T1>.Default.Compare(Item1, other.Item1);
+ if (c != 0) return c;
+
+ c = Comparer<T2>.Default.Compare(Item2, other.Item2);
+ if (c != 0) return c;
+
+ c = Comparer<T3>.Default.Compare(Item3, other.Item3);
+ if (c != 0) return c;
+
+ c = Comparer<T4>.Default.Compare(Item4, other.Item4);
+ if (c != 0) return c;
+
+ c = Comparer<T5>.Default.Compare(Item5, other.Item5);
+ if (c != 0) return c;
+
+ c = Comparer<T6>.Default.Compare(Item6, other.Item6);
+ if (c != 0) return c;
+
+ return Comparer<T7>.Default.Compare(Item7, other.Item7);
+ }
+
+ int IStructuralComparable.CompareTo(object other, IComparer comparer)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ var objTuple = (ValueTuple<T1, T2, T3, T4, T5, T6, T7>)other;
+
+ int c = comparer.Compare(Item1, objTuple.Item1);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item2, objTuple.Item2);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item3, objTuple.Item3);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item4, objTuple.Item4);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item5, objTuple.Item5);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item6, objTuple.Item6);
+ if (c != 0) return c;
+
+ return comparer.Compare(Item7, objTuple.Item7);
+ }
+
+ /// <summary>
+ /// Returns the hash code for the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance.
+ /// </summary>
+ /// <returns>A 32-bit signed integer hash code.</returns>
+ public override int GetHashCode()
+ {
+ return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
+ Item2?.GetHashCode() ?? 0,
+ Item3?.GetHashCode() ?? 0,
+ Item4?.GetHashCode() ?? 0,
+ Item5?.GetHashCode() ?? 0,
+ Item6?.GetHashCode() ?? 0,
+ Item7?.GetHashCode() ?? 0);
+ }
+
+ int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
+ {
+ return GetHashCodeCore(comparer);
+ }
+
+ private int GetHashCodeCore(IEqualityComparer comparer)
+ {
+ return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
+ comparer.GetHashCode(Item2),
+ comparer.GetHashCode(Item3),
+ comparer.GetHashCode(Item4),
+ comparer.GetHashCode(Item5),
+ comparer.GetHashCode(Item6),
+ comparer.GetHashCode(Item7));
+ }
+
+ int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
+ {
+ return GetHashCodeCore(comparer);
+ }
+
+ /// <summary>
+ /// Returns a string that represents the value of this <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance.
+ /// </summary>
+ /// <returns>The string representation of this <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance.</returns>
+ /// <remarks>
+ /// The string returned by this method takes the form <c>(Item1, Item2, Item3, Item4, Item5, Item6, Item7)</c>.
+ /// If any field value is <see langword="null"/>, it is represented as <see cref="String.Empty"/>.
+ /// </remarks>
+ public override string ToString()
+ {
+ return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")";
+ }
+
+ string IValueTupleInternal.ToStringEnd()
+ {
+ return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")";
+ }
+
+ /// <summary>
+ /// The number of positions in this data structure.
+ /// </summary>
+ int ITuple.Length => 7;
+
+ /// <summary>
+ /// Get the element at position <param name="index"/>.
+ /// </summary>
+ object ITuple.this[int index]
+ {
+ get
+ {
+ switch (index)
+ {
+ case 0:
+ return Item1;
+ case 1:
+ return Item2;
+ case 2:
+ return Item3;
+ case 3:
+ return Item4;
+ case 4:
+ return Item5;
+ case 5:
+ return Item6;
+ case 6:
+ return Item7;
+ default:
+ throw new IndexOutOfRangeException();
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Represents an 8-tuple, or octuple, as a value type.
+ /// </summary>
+ /// <typeparam name="T1">The type of the tuple's first component.</typeparam>
+ /// <typeparam name="T2">The type of the tuple's second component.</typeparam>
+ /// <typeparam name="T3">The type of the tuple's third component.</typeparam>
+ /// <typeparam name="T4">The type of the tuple's fourth component.</typeparam>
+ /// <typeparam name="T5">The type of the tuple's fifth component.</typeparam>
+ /// <typeparam name="T6">The type of the tuple's sixth component.</typeparam>
+ /// <typeparam name="T7">The type of the tuple's seventh component.</typeparam>
+ /// <typeparam name="TRest">The type of the tuple's eighth component.</typeparam>
+ [Serializable]
+ [StructLayout(LayoutKind.Auto)]
+ public struct ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>
+ : IEquatable<ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>>, IValueTupleInternal, ITuple
+ where TRest : struct
+ {
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's first component.
+ /// </summary>
+ public T1 Item1;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's second component.
+ /// </summary>
+ public T2 Item2;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's third component.
+ /// </summary>
+ public T3 Item3;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's fourth component.
+ /// </summary>
+ public T4 Item4;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's fifth component.
+ /// </summary>
+ public T5 Item5;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's sixth component.
+ /// </summary>
+ public T6 Item6;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's seventh component.
+ /// </summary>
+ public T7 Item7;
+ /// <summary>
+ /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's eighth component.
+ /// </summary>
+ public TRest Rest;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> value type.
+ /// </summary>
+ /// <param name="item1">The value of the tuple's first component.</param>
+ /// <param name="item2">The value of the tuple's second component.</param>
+ /// <param name="item3">The value of the tuple's third component.</param>
+ /// <param name="item4">The value of the tuple's fourth component.</param>
+ /// <param name="item5">The value of the tuple's fifth component.</param>
+ /// <param name="item6">The value of the tuple's sixth component.</param>
+ /// <param name="item7">The value of the tuple's seventh component.</param>
+ /// <param name="rest">The value of the tuple's eight component.</param>
+ public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest)
+ {
+ if (!(rest is IValueTupleInternal))
+ {
+ throw new ArgumentException(SR.ArgumentException_ValueTupleLastArgumentNotAValueTuple);
+ }
+
+ Item1 = item1;
+ Item2 = item2;
+ Item3 = item3;
+ Item4 = item4;
+ Item5 = item5;
+ Item6 = item6;
+ Item7 = item7;
+ Rest = rest;
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance is equal to a specified object.
+ /// </summary>
+ /// <param name="obj">The object to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
+ /// <remarks>
+ /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
+ /// <list type="bullet">
+ /// <item><description>It is a <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> value type.</description></item>
+ /// <item><description>Its components are of the same types as those of the current instance.</description></item>
+ /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
+ /// </list>
+ /// </remarks>
+ public override bool Equals(object obj)
+ {
+ return obj is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> && Equals((ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)obj);
+ }
+
+ /// <summary>
+ /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/>
+ /// instance is equal to a specified <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/>.
+ /// </summary>
+ /// <param name="other">The tuple to compare with this instance.</param>
+ /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
+ /// <remarks>
+ /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its fields
+ /// are equal to that of the current instance, using the default comparer for that field's type.
+ /// </remarks>
+ public bool Equals(ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> other)
+ {
+ return EqualityComparer<T1>.Default.Equals(Item1, other.Item1)
+ && EqualityComparer<T2>.Default.Equals(Item2, other.Item2)
+ && EqualityComparer<T3>.Default.Equals(Item3, other.Item3)
+ && EqualityComparer<T4>.Default.Equals(Item4, other.Item4)
+ && EqualityComparer<T5>.Default.Equals(Item5, other.Item5)
+ && EqualityComparer<T6>.Default.Equals(Item6, other.Item6)
+ && EqualityComparer<T7>.Default.Equals(Item7, other.Item7)
+ && EqualityComparer<TRest>.Default.Equals(Rest, other.Rest);
+ }
+
+ bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
+ {
+ if (other == null || !(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)) return false;
+
+ var objTuple = (ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)other;
+
+ return comparer.Equals(Item1, objTuple.Item1)
+ && comparer.Equals(Item2, objTuple.Item2)
+ && comparer.Equals(Item3, objTuple.Item3)
+ && comparer.Equals(Item4, objTuple.Item4)
+ && comparer.Equals(Item5, objTuple.Item5)
+ && comparer.Equals(Item6, objTuple.Item6)
+ && comparer.Equals(Item7, objTuple.Item7)
+ && comparer.Equals(Rest, objTuple.Rest);
+ }
+
+ int IComparable.CompareTo(object other)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ return CompareTo((ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)other);
+ }
+
+ /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
+ /// <param name="other">An instance to compare.</param>
+ /// <returns>
+ /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
+ /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
+ /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
+ /// than <paramref name="other"/>.
+ /// </returns>
+ public int CompareTo(ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> other)
+ {
+ int c = Comparer<T1>.Default.Compare(Item1, other.Item1);
+ if (c != 0) return c;
+
+ c = Comparer<T2>.Default.Compare(Item2, other.Item2);
+ if (c != 0) return c;
+
+ c = Comparer<T3>.Default.Compare(Item3, other.Item3);
+ if (c != 0) return c;
+
+ c = Comparer<T4>.Default.Compare(Item4, other.Item4);
+ if (c != 0) return c;
+
+ c = Comparer<T5>.Default.Compare(Item5, other.Item5);
+ if (c != 0) return c;
+
+ c = Comparer<T6>.Default.Compare(Item6, other.Item6);
+ if (c != 0) return c;
+
+ c = Comparer<T7>.Default.Compare(Item7, other.Item7);
+ if (c != 0) return c;
+
+ return Comparer<TRest>.Default.Compare(Rest, other.Rest);
+ }
+
+ int IStructuralComparable.CompareTo(object other, IComparer comparer)
+ {
+ if (other == null) return 1;
+
+ if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>))
+ {
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ }
+
+ var objTuple = (ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)other;
+
+ int c = comparer.Compare(Item1, objTuple.Item1);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item2, objTuple.Item2);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item3, objTuple.Item3);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item4, objTuple.Item4);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item5, objTuple.Item5);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item6, objTuple.Item6);
+ if (c != 0) return c;
+
+ c = comparer.Compare(Item7, objTuple.Item7);
+ if (c != 0) return c;
+
+ return comparer.Compare(Rest, objTuple.Rest);
+ }
+
+ /// <summary>
+ /// Returns the hash code for the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance.
+ /// </summary>
+ /// <returns>A 32-bit signed integer hash code.</returns>
+ public override int GetHashCode()
+ {
+ // We want to have a limited hash in this case. We'll use the last 8 elements of the tuple
+ IValueTupleInternal rest = Rest as IValueTupleInternal;
+ if (rest == null)
+ {
+ return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
+ Item2?.GetHashCode() ?? 0,
+ Item3?.GetHashCode() ?? 0,
+ Item4?.GetHashCode() ?? 0,
+ Item5?.GetHashCode() ?? 0,
+ Item6?.GetHashCode() ?? 0,
+ Item7?.GetHashCode() ?? 0);
+ }
+
+ int size = rest.Length;
+ if (size >= 8) { return rest.GetHashCode(); }
+
+ // In this case, the rest member has less than 8 elements so we need to combine some our elements with the elements in rest
+ int k = 8 - size;
+ switch (k)
+ {
+ case 1:
+ return ValueTuple.CombineHashCodes(Item7?.GetHashCode() ?? 0,
+ rest.GetHashCode());
+ case 2:
+ return ValueTuple.CombineHashCodes(Item6?.GetHashCode() ?? 0,
+ Item7?.GetHashCode() ?? 0,
+ rest.GetHashCode());
+ case 3:
+ return ValueTuple.CombineHashCodes(Item5?.GetHashCode() ?? 0,
+ Item6?.GetHashCode() ?? 0,
+ Item7?.GetHashCode() ?? 0,
+ rest.GetHashCode());
+ case 4:
+ return ValueTuple.CombineHashCodes(Item4?.GetHashCode() ?? 0,
+ Item5?.GetHashCode() ?? 0,
+ Item6?.GetHashCode() ?? 0,
+ Item7?.GetHashCode() ?? 0,
+ rest.GetHashCode());
+ case 5:
+ return ValueTuple.CombineHashCodes(Item3?.GetHashCode() ?? 0,
+ Item4?.GetHashCode() ?? 0,
+ Item5?.GetHashCode() ?? 0,
+ Item6?.GetHashCode() ?? 0,
+ Item7?.GetHashCode() ?? 0,
+ rest.GetHashCode());
+ case 6:
+ return ValueTuple.CombineHashCodes(Item2?.GetHashCode() ?? 0,
+ Item3?.GetHashCode() ?? 0,
+ Item4?.GetHashCode() ?? 0,
+ Item5?.GetHashCode() ?? 0,
+ Item6?.GetHashCode() ?? 0,
+ Item7?.GetHashCode() ?? 0,
+ rest.GetHashCode());
+ case 7:
+ case 8:
+ return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
+ Item2?.GetHashCode() ?? 0,
+ Item3?.GetHashCode() ?? 0,
+ Item4?.GetHashCode() ?? 0,
+ Item5?.GetHashCode() ?? 0,
+ Item6?.GetHashCode() ?? 0,
+ Item7?.GetHashCode() ?? 0,
+ rest.GetHashCode());
+ }
+
+ Contract.Assert(false, "Missed all cases for computing ValueTuple hash code");
+ return -1;
+ }
+
+ int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
+ {
+ return GetHashCodeCore(comparer);
+ }
+
+ private int GetHashCodeCore(IEqualityComparer comparer)
+ {
+ // We want to have a limited hash in this case. We'll use the last 8 elements of the tuple
+ IValueTupleInternal rest = Rest as IValueTupleInternal;
+ if (rest == null)
+ {
+ return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3),
+ comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6),
+ comparer.GetHashCode(Item7));
+ }
+
+ int size = rest.Length;
+ if (size >= 8) { return rest.GetHashCode(comparer); }
+
+ // In this case, the rest member has less than 8 elements so we need to combine some our elements with the elements in rest
+ int k = 8 - size;
+ switch (k)
+ {
+ case 1:
+ return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item7), rest.GetHashCode(comparer));
+ case 2:
+ return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer));
+ case 3:
+ return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7),
+ rest.GetHashCode(comparer));
+ case 4:
+ return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6),
+ comparer.GetHashCode(Item7), rest.GetHashCode(comparer));
+ case 5:
+ return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5),
+ comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer));
+ case 6:
+ return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4),
+ comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7),
+ rest.GetHashCode(comparer));
+ case 7:
+ case 8:
+ return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3),
+ comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6),
+ comparer.GetHashCode(Item7), rest.GetHashCode(comparer));
+ }
+
+ Contract.Assert(false, "Missed all cases for computing ValueTuple hash code");
+ return -1;
+ }
+
+ int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
+ {
+ return GetHashCodeCore(comparer);
+ }
+
+ /// <summary>
+ /// Returns a string that represents the value of this <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance.
+ /// </summary>
+ /// <returns>The string representation of this <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance.</returns>
+ /// <remarks>
+ /// The string returned by this method takes the form <c>(Item1, Item2, Item3, Item4, Item5, Item6, Item7, Rest)</c>.
+ /// If any field value is <see langword="null"/>, it is represented as <see cref="String.Empty"/>.
+ /// </remarks>
+ public override string ToString()
+ {
+ IValueTupleInternal rest = Rest as IValueTupleInternal;
+ if (rest == null)
+ {
+ return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")";
+ }
+ else
+ {
+ return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd();
+ }
+ }
+
+ string IValueTupleInternal.ToStringEnd()
+ {
+ IValueTupleInternal rest = Rest as IValueTupleInternal;
+ if (rest == null)
+ {
+ return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")";
+ }
+ else
+ {
+ return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd();
+ }
+ }
+
+ /// <summary>
+ /// The number of positions in this data structure.
+ /// </summary>
+ int ITuple.Length
+ {
+ get
+ {
+ IValueTupleInternal rest = Rest as IValueTupleInternal;
+ return rest == null ? 8 : 7 + rest.Length;
+ }
+ }
+
+ /// <summary>
+ /// Get the element at position <param name="index"/>.
+ /// </summary>
+ object ITuple.this[int index]
+ {
+ get
+ {
+ switch (index)
+ {
+ case 0:
+ return Item1;
+ case 1:
+ return Item2;
+ case 2:
+ return Item3;
+ case 3:
+ return Item4;
+ case 4:
+ return Item5;
+ case 5:
+ return Item6;
+ case 6:
+ return Item7;
+ }
+
+ IValueTupleInternal rest = Rest as IValueTupleInternal;
+ if (rest == null)
+ {
+ if (index == 7)
+ {
+ return Rest;
+ }
+ throw new IndexOutOfRangeException();
+ }
+ return rest[index - 7];
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/shared/System/Version.cs b/src/mscorlib/shared/System/Version.cs
new file mode 100644
index 0000000000..54b2052ddb
--- /dev/null
+++ b/src/mscorlib/shared/System/Version.cs
@@ -0,0 +1,495 @@
+// 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.Globalization;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Text;
+
+namespace System
+{
+ // A Version object contains four hierarchical numeric components: major, minor,
+ // build and revision. Build and revision may be unspecified, which is represented
+ // internally as a -1. By definition, an unspecified component matches anything
+ // (both unspecified and specified), and an unspecified component is "less than" any
+ // specified component.
+
+ [Serializable]
+ public sealed class Version : ICloneable, IComparable
+ , IComparable<Version>, IEquatable<Version>
+ {
+ // AssemblyName depends on the order staying the same
+ private readonly int _Major;
+ private readonly int _Minor;
+ private readonly int _Build = -1;
+ private readonly int _Revision = -1;
+
+ public Version(int major, int minor, int build, int revision)
+ {
+ if (major < 0)
+ throw new ArgumentOutOfRangeException(nameof(major), SR.ArgumentOutOfRange_Version);
+
+ if (minor < 0)
+ throw new ArgumentOutOfRangeException(nameof(minor), SR.ArgumentOutOfRange_Version);
+
+ if (build < 0)
+ throw new ArgumentOutOfRangeException(nameof(build), SR.ArgumentOutOfRange_Version);
+
+ if (revision < 0)
+ throw new ArgumentOutOfRangeException(nameof(revision), SR.ArgumentOutOfRange_Version);
+ Contract.EndContractBlock();
+
+ _Major = major;
+ _Minor = minor;
+ _Build = build;
+ _Revision = revision;
+ }
+
+ public Version(int major, int minor, int build)
+ {
+ if (major < 0)
+ throw new ArgumentOutOfRangeException(nameof(major), SR.ArgumentOutOfRange_Version);
+
+ if (minor < 0)
+ throw new ArgumentOutOfRangeException(nameof(minor), SR.ArgumentOutOfRange_Version);
+
+ if (build < 0)
+ throw new ArgumentOutOfRangeException(nameof(build), SR.ArgumentOutOfRange_Version);
+
+ Contract.EndContractBlock();
+
+ _Major = major;
+ _Minor = minor;
+ _Build = build;
+ }
+
+ public Version(int major, int minor)
+ {
+ if (major < 0)
+ throw new ArgumentOutOfRangeException(nameof(major), SR.ArgumentOutOfRange_Version);
+
+ if (minor < 0)
+ throw new ArgumentOutOfRangeException(nameof(minor), SR.ArgumentOutOfRange_Version);
+ Contract.EndContractBlock();
+
+ _Major = major;
+ _Minor = minor;
+ }
+
+ public Version(String version)
+ {
+ Version v = Version.Parse(version);
+ _Major = v.Major;
+ _Minor = v.Minor;
+ _Build = v.Build;
+ _Revision = v.Revision;
+ }
+
+ public Version()
+ {
+ _Major = 0;
+ _Minor = 0;
+ }
+
+ private Version(Version version)
+ {
+ Debug.Assert(version != null);
+
+ _Major = version._Major;
+ _Minor = version._Minor;
+ _Build = version._Build;
+ _Revision = version._Revision;
+ }
+
+ public object Clone()
+ {
+ return new Version(this);
+ }
+
+ // Properties for setting and getting version numbers
+ public int Major
+ {
+ get { return _Major; }
+ }
+
+ public int Minor
+ {
+ get { return _Minor; }
+ }
+
+ public int Build
+ {
+ get { return _Build; }
+ }
+
+ public int Revision
+ {
+ get { return _Revision; }
+ }
+
+ public short MajorRevision
+ {
+ get { return (short)(_Revision >> 16); }
+ }
+
+ public short MinorRevision
+ {
+ get { return (short)(_Revision & 0xFFFF); }
+ }
+
+ public int CompareTo(Object version)
+ {
+ if (version == null)
+ {
+ return 1;
+ }
+
+ Version v = version as Version;
+ if (v == null)
+ {
+ throw new ArgumentException(SR.Arg_MustBeVersion);
+ }
+
+ return CompareTo(v);
+ }
+
+ public int CompareTo(Version value)
+ {
+ return
+ object.ReferenceEquals(value, this) ? 0 :
+ object.ReferenceEquals(value, null) ? 1 :
+ _Major != value._Major ? (_Major > value._Major ? 1 : -1) :
+ _Minor != value._Minor ? (_Minor > value._Minor ? 1 : -1) :
+ _Build != value._Build ? (_Build > value._Build ? 1 : -1) :
+ _Revision != value._Revision ? (_Revision > value._Revision ? 1 : -1) :
+ 0;
+ }
+
+ public override bool Equals(Object obj)
+ {
+ return Equals(obj as Version);
+ }
+
+ public bool Equals(Version obj)
+ {
+ return object.ReferenceEquals(obj, this) ||
+ (!object.ReferenceEquals(obj, null) &&
+ _Major == obj._Major &&
+ _Minor == obj._Minor &&
+ _Build == obj._Build &&
+ _Revision == obj._Revision);
+ }
+
+ public override int GetHashCode()
+ {
+ // Let's assume that most version numbers will be pretty small and just
+ // OR some lower order bits together.
+
+ int accumulator = 0;
+
+ accumulator |= (_Major & 0x0000000F) << 28;
+ accumulator |= (_Minor & 0x000000FF) << 20;
+ accumulator |= (_Build & 0x000000FF) << 12;
+ accumulator |= (_Revision & 0x00000FFF);
+
+ return accumulator;
+ }
+
+ public override String ToString()
+ {
+ if (_Build == -1) return (ToString(2));
+ if (_Revision == -1) return (ToString(3));
+ return (ToString(4));
+ }
+
+ public String ToString(int fieldCount)
+ {
+ StringBuilder sb;
+ switch (fieldCount)
+ {
+ case 0:
+ return (String.Empty);
+ case 1:
+ return (_Major.ToString());
+ case 2:
+ sb = StringBuilderCache.Acquire();
+ AppendPositiveNumber(_Major, sb);
+ sb.Append('.');
+ AppendPositiveNumber(_Minor, sb);
+ return StringBuilderCache.GetStringAndRelease(sb);
+ default:
+ if (_Build == -1)
+ throw new ArgumentException(SR.Format(SR.ArgumentOutOfRange_Bounds_Lower_Upper, "0", "2"), nameof(fieldCount));
+
+ if (fieldCount == 3)
+ {
+ sb = StringBuilderCache.Acquire();
+ AppendPositiveNumber(_Major, sb);
+ sb.Append('.');
+ AppendPositiveNumber(_Minor, sb);
+ sb.Append('.');
+ AppendPositiveNumber(_Build, sb);
+ return StringBuilderCache.GetStringAndRelease(sb);
+ }
+
+ if (_Revision == -1)
+ throw new ArgumentException(SR.Format(SR.ArgumentOutOfRange_Bounds_Lower_Upper, "0", "3"), nameof(fieldCount));
+
+ if (fieldCount == 4)
+ {
+ sb = StringBuilderCache.Acquire();
+ AppendPositiveNumber(_Major, sb);
+ sb.Append('.');
+ AppendPositiveNumber(_Minor, sb);
+ sb.Append('.');
+ AppendPositiveNumber(_Build, sb);
+ sb.Append('.');
+ AppendPositiveNumber(_Revision, sb);
+ return StringBuilderCache.GetStringAndRelease(sb);
+ }
+
+ throw new ArgumentException(SR.Format(SR.ArgumentOutOfRange_Bounds_Lower_Upper, "0", "4"), nameof(fieldCount));
+ }
+ }
+
+ //
+ // AppendPositiveNumber is an optimization to append a number to a StringBuilder object without
+ // doing any boxing and not even creating intermediate string.
+ // Note: as we always have positive numbers then it is safe to convert the number to string
+ // regardless of the current culture as we'll not have any punctuation marks in the number
+ //
+ private const int ZERO_CHAR_VALUE = (int)'0';
+ private static void AppendPositiveNumber(int num, StringBuilder sb)
+ {
+ Debug.Assert(num >= 0, "AppendPositiveNumber expect positive numbers");
+
+ int index = sb.Length;
+ int reminder;
+
+ do
+ {
+ reminder = num % 10;
+ num = num / 10;
+ sb.Insert(index, (char)(ZERO_CHAR_VALUE + reminder));
+ } while (num > 0);
+ }
+
+ public static Version Parse(string input)
+ {
+ if (input == null)
+ {
+ throw new ArgumentNullException(nameof(input));
+ }
+ Contract.EndContractBlock();
+
+ VersionResult r = new VersionResult();
+ r.Init(nameof(input), true);
+ if (!TryParseVersion(input, ref r))
+ {
+ throw r.GetVersionParseException();
+ }
+ return r.m_parsedVersion;
+ }
+
+ public static bool TryParse(string input, out Version result)
+ {
+ VersionResult r = new VersionResult();
+ r.Init(nameof(input), false);
+ bool b = TryParseVersion(input, ref r);
+ result = r.m_parsedVersion;
+ return b;
+ }
+
+ private static bool TryParseVersion(string version, ref VersionResult result)
+ {
+ int major, minor, build, revision;
+
+ if ((Object)version == null)
+ {
+ result.SetFailure(ParseFailureKind.ArgumentNullException);
+ return false;
+ }
+
+ String[] parsedComponents = version.Split('.');
+ int parsedComponentsLength = parsedComponents.Length;
+ if ((parsedComponentsLength < 2) || (parsedComponentsLength > 4))
+ {
+ result.SetFailure(ParseFailureKind.ArgumentException);
+ return false;
+ }
+
+ if (!TryParseComponent(parsedComponents[0], nameof(version), ref result, out major))
+ {
+ return false;
+ }
+
+ if (!TryParseComponent(parsedComponents[1], nameof(version), ref result, out minor))
+ {
+ return false;
+ }
+
+ parsedComponentsLength -= 2;
+
+ if (parsedComponentsLength > 0)
+ {
+ if (!TryParseComponent(parsedComponents[2], "build", ref result, out build))
+ {
+ return false;
+ }
+
+ parsedComponentsLength--;
+
+ if (parsedComponentsLength > 0)
+ {
+ if (!TryParseComponent(parsedComponents[3], "revision", ref result, out revision))
+ {
+ return false;
+ }
+ else
+ {
+ result.m_parsedVersion = new Version(major, minor, build, revision);
+ }
+ }
+ else
+ {
+ result.m_parsedVersion = new Version(major, minor, build);
+ }
+ }
+ else
+ {
+ result.m_parsedVersion = new Version(major, minor);
+ }
+
+ return true;
+ }
+
+ private static bool TryParseComponent(string component, string componentName, ref VersionResult result, out int parsedComponent)
+ {
+ if (!Int32.TryParse(component, NumberStyles.Integer, CultureInfo.InvariantCulture, out parsedComponent))
+ {
+ result.SetFailure(ParseFailureKind.FormatException, component);
+ return false;
+ }
+
+ if (parsedComponent < 0)
+ {
+ result.SetFailure(ParseFailureKind.ArgumentOutOfRangeException, componentName);
+ return false;
+ }
+
+ return true;
+ }
+
+ public static bool operator ==(Version v1, Version v2)
+ {
+ if (Object.ReferenceEquals(v1, null))
+ {
+ return Object.ReferenceEquals(v2, null);
+ }
+
+ return v1.Equals(v2);
+ }
+
+ public static bool operator !=(Version v1, Version v2)
+ {
+ return !(v1 == v2);
+ }
+
+ public static bool operator <(Version v1, Version v2)
+ {
+ if ((Object)v1 == null)
+ throw new ArgumentNullException(nameof(v1));
+ Contract.EndContractBlock();
+ return (v1.CompareTo(v2) < 0);
+ }
+
+ public static bool operator <=(Version v1, Version v2)
+ {
+ if ((Object)v1 == null)
+ throw new ArgumentNullException(nameof(v1));
+ Contract.EndContractBlock();
+ return (v1.CompareTo(v2) <= 0);
+ }
+
+ public static bool operator >(Version v1, Version v2)
+ {
+ return (v2 < v1);
+ }
+
+ public static bool operator >=(Version v1, Version v2)
+ {
+ return (v2 <= v1);
+ }
+
+ internal enum ParseFailureKind
+ {
+ ArgumentNullException,
+ ArgumentException,
+ ArgumentOutOfRangeException,
+ FormatException
+ }
+
+ internal struct VersionResult
+ {
+ internal Version m_parsedVersion;
+ internal ParseFailureKind m_failure;
+ internal string m_exceptionArgument;
+ internal string m_argumentName;
+ internal bool m_canThrow;
+
+ internal void Init(string argumentName, bool canThrow)
+ {
+ m_canThrow = canThrow;
+ m_argumentName = argumentName;
+ }
+
+ internal void SetFailure(ParseFailureKind failure)
+ {
+ SetFailure(failure, String.Empty);
+ }
+
+ internal void SetFailure(ParseFailureKind failure, string argument)
+ {
+ m_failure = failure;
+ m_exceptionArgument = argument;
+ if (m_canThrow)
+ {
+ throw GetVersionParseException();
+ }
+ }
+
+ internal Exception GetVersionParseException()
+ {
+ switch (m_failure)
+ {
+ case ParseFailureKind.ArgumentNullException:
+ return new ArgumentNullException(m_argumentName);
+ case ParseFailureKind.ArgumentException:
+ return new ArgumentException(SR.Arg_VersionString);
+ case ParseFailureKind.ArgumentOutOfRangeException:
+ return new ArgumentOutOfRangeException(m_exceptionArgument, SR.ArgumentOutOfRange_Version);
+ case ParseFailureKind.FormatException:
+ // Regenerate the FormatException as would be thrown by Int32.Parse()
+ try
+ {
+ Int32.Parse(m_exceptionArgument, CultureInfo.InvariantCulture);
+ }
+ catch (FormatException e)
+ {
+ return e;
+ }
+ catch (OverflowException e)
+ {
+ return e;
+ }
+ Debug.Assert(false, "Int32.Parse() did not throw exception but TryParse failed: " + m_exceptionArgument);
+ return new FormatException(SR.Format_InvalidString);
+ default:
+ Debug.Assert(false, "Unmatched case in Version.GetVersionParseException() for value: " + m_failure);
+ return new ArgumentException(SR.Arg_VersionString);
+ }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Void.cs b/src/mscorlib/shared/System/Void.cs
index 5c20f634fc..5c20f634fc 100644
--- a/src/mscorlib/src/System/Void.cs
+++ b/src/mscorlib/shared/System/Void.cs
diff --git a/src/mscorlib/src/Internal/Console.cs b/src/mscorlib/src/Internal/Console.cs
new file mode 100644
index 0000000000..a2a323fa13
--- /dev/null
+++ b/src/mscorlib/src/Internal/Console.cs
@@ -0,0 +1,44 @@
+// 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.Text;
+using System.Security;
+using Microsoft.Win32;
+using Microsoft.Win32.SafeHandles;
+
+namespace Internal
+{
+ //
+ // Simple limited console class for internal printf-style debugging in System.Private.CoreLib
+ // and low-level tests that want to call System.Private.CoreLib directly
+ //
+
+ public static class Console
+ {
+ private static readonly SafeFileHandle _outputHandle =
+ new SafeFileHandle(Win32Native.GetStdHandle(Win32Native.STD_OUTPUT_HANDLE), false);
+
+ public static unsafe void Write(string s)
+ {
+ byte[] bytes = Encoding.UTF8.GetBytes(s);
+
+ fixed (byte* pBytes = bytes)
+ {
+ int bytesWritten;
+ Win32Native.WriteFile(_outputHandle, pBytes, bytes.Length, out bytesWritten, IntPtr.Zero);
+ }
+ }
+
+ public static void WriteLine(string s)
+ {
+ Write(s + Environment.NewLine);
+ }
+
+ public static void WriteLine()
+ {
+ Write(Environment.NewLine);
+ }
+ }
+}
diff --git a/src/mscorlib/src/Internal/Runtime/Augments/EnvironmentAugments.cs b/src/mscorlib/src/Internal/Runtime/Augments/EnvironmentAugments.cs
index b22310eacb..b5a56b8633 100644
--- a/src/mscorlib/src/Internal/Runtime/Augments/EnvironmentAugments.cs
+++ b/src/mscorlib/src/Internal/Runtime/Augments/EnvironmentAugments.cs
@@ -4,6 +4,8 @@
using System;
using System.Collections;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
namespace Internal.Runtime.Augments
{
@@ -16,7 +18,6 @@ namespace Internal.Runtime.Augments
public static void FailFast(string message, Exception error) => Environment.FailFast(message, error);
public static string[] GetCommandLineArgs() => Environment.GetCommandLineArgs();
public static bool HasShutdownStarted => Environment.HasShutdownStarted;
- public static string StackTrace => Environment.StackTrace;
public static int TickCount => Environment.TickCount;
public static string GetEnvironmentVariable(string variable) => Environment.GetEnvironmentVariable(variable);
public static string GetEnvironmentVariable(string variable, EnvironmentVariableTarget target) => Environment.GetEnvironmentVariable(variable, target);
@@ -24,5 +25,14 @@ namespace Internal.Runtime.Augments
public static IDictionary GetEnvironmentVariables(EnvironmentVariableTarget target) => Environment.GetEnvironmentVariables(target);
public static void SetEnvironmentVariable(string variable, string value) => Environment.SetEnvironmentVariable(variable, value);
public static void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target) => Environment.SetEnvironmentVariable(variable, value, target);
+
+ public static string StackTrace
+ {
+ [MethodImpl(MethodImplOptions.NoInlining)] // Prevent inlining from affecting where the stacktrace starts
+ get
+ {
+ return new StackTrace(1 /* skip this one frame */, true).ToString(System.Diagnostics.StackTrace.TraceFormat.Normal);
+ }
+ }
}
}
diff --git a/src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs b/src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs
index 58eff98dec..605f974da0 100644
--- a/src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs
+++ b/src/mscorlib/src/Internal/Runtime/Augments/RuntimeThread.cs
@@ -15,7 +15,7 @@ namespace Internal.Runtime.Augments
{
public class RuntimeThread : CriticalFinalizerObject
{
- internal RuntimeThread() {}
+ internal RuntimeThread() { }
public static RuntimeThread Create(ThreadStart start) => new Thread(start);
public static RuntimeThread Create(ThreadStart start, int maxStackSize) => new Thread(start, maxStackSize);
diff --git a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Collation.cs b/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Collation.cs
new file mode 100644
index 0000000000..fe14560a3a
--- /dev/null
+++ b/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Collation.cs
@@ -0,0 +1,72 @@
+// 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.Diagnostics;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Security;
+
+internal static partial class Interop
+{
+ internal static partial class GlobalizationInterop
+ {
+ [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetSortHandle")]
+ internal unsafe static extern ResultCode GetSortHandle(byte[] localeName, out SafeSortHandle sortHandle);
+
+ [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_CloseSortHandle")]
+ internal unsafe static extern void CloseSortHandle(IntPtr handle);
+
+ [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_CompareString")]
+ internal unsafe static extern int CompareString(SafeSortHandle sortHandle, char* lpStr1, int cwStr1Len, char* lpStr2, int cwStr2Len, CompareOptions options);
+
+ [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_IndexOf")]
+ internal unsafe static extern int IndexOf(SafeSortHandle sortHandle, string target, int cwTargetLength, char* pSource, int cwSourceLength, CompareOptions options, int* matchLengthPtr);
+
+ [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_LastIndexOf")]
+ internal unsafe static extern int LastIndexOf(SafeSortHandle sortHandle, string target, int cwTargetLength, char* pSource, int cwSourceLength, CompareOptions options);
+
+ [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_IndexOfOrdinalIgnoreCase")]
+ internal unsafe static extern int IndexOfOrdinalIgnoreCase(string target, int cwTargetLength, char* pSource, int cwSourceLength, bool findLast);
+
+ [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_StartsWith")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ internal unsafe static extern bool StartsWith(SafeSortHandle sortHandle, string target, int cwTargetLength, string source, int cwSourceLength, CompareOptions options);
+
+ [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_EndsWith")]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ internal unsafe static extern bool EndsWith(SafeSortHandle sortHandle, string target, int cwTargetLength, string source, int cwSourceLength, CompareOptions options);
+
+ [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetSortKey")]
+ internal unsafe static extern int GetSortKey(SafeSortHandle sortHandle, string str, int strLength, byte* sortKey, int sortKeyLength, CompareOptions options);
+
+ [DllImport(Libraries.GlobalizationInterop, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_CompareStringOrdinalIgnoreCase")]
+ internal unsafe static extern int CompareStringOrdinalIgnoreCase(char* lpStr1, int cwStr1Len, char* lpStr2, int cwStr2Len);
+
+ [DllImport(Libraries.GlobalizationInterop, EntryPoint = "GlobalizationNative_GetSortVersion")]
+ internal static extern int GetSortVersion();
+
+ internal class SafeSortHandle : SafeHandle
+ {
+ private SafeSortHandle() :
+ base(IntPtr.Zero, true)
+ {
+ }
+
+ public override bool IsInvalid
+ {
+ get { return handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ CloseSortHandle(handle);
+ SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.ICU.cs b/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.ICU.cs
new file mode 100644
index 0000000000..c690884145
--- /dev/null
+++ b/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.ICU.cs
@@ -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.InteropServices;
+using System.Runtime.CompilerServices;
+
+internal static partial class Interop
+{
+ internal static partial class GlobalizationInterop
+ {
+ [DllImport(Libraries.GlobalizationInterop, EntryPoint = "GlobalizationNative_LoadICU")]
+ internal static extern int LoadICU();
+ }
+}
diff --git a/src/mscorlib/src/Interop/Windows/Normaliz/Interop.Idna.cs b/src/mscorlib/src/Interop/Windows/Normaliz/Interop.Idna.cs
new file mode 100644
index 0000000000..cad457d915
--- /dev/null
+++ b/src/mscorlib/src/Interop/Windows/Normaliz/Interop.Idna.cs
@@ -0,0 +1,38 @@
+// 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.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Normaliz
+ {
+ //
+ // Idn APIs
+ //
+
+ [DllImport("Normaliz.dll", CharSet = CharSet.Unicode, SetLastError = true)]
+ internal static extern int IdnToAscii(
+ uint dwFlags,
+ IntPtr lpUnicodeCharStr,
+ int cchUnicodeChar,
+ [System.Runtime.InteropServices.OutAttribute()]
+ IntPtr lpASCIICharStr,
+ int cchASCIIChar);
+
+ [DllImport("Normaliz.dll", CharSet = CharSet.Unicode, SetLastError = true)]
+ internal static extern int IdnToUnicode(
+ uint dwFlags,
+ IntPtr lpASCIICharStr,
+ int cchASCIIChar,
+ [System.Runtime.InteropServices.OutAttribute()]
+ IntPtr lpUnicodeCharStr,
+ int cchUnicodeChar);
+
+ internal const int IDN_ALLOW_UNASSIGNED = 0x1;
+ internal const int IDN_USE_STD3_ASCII_RULES = 0x2;
+ internal const int ERROR_INVALID_NAME = 123;
+ }
+}
diff --git a/src/mscorlib/src/Interop/Windows/Normaliz/Interop.Normalization.cs b/src/mscorlib/src/Interop/Windows/Normaliz/Interop.Normalization.cs
new file mode 100644
index 0000000000..3e49f1f64c
--- /dev/null
+++ b/src/mscorlib/src/Interop/Windows/Normaliz/Interop.Normalization.cs
@@ -0,0 +1,24 @@
+// 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.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Normaliz
+ {
+ [DllImport("Normaliz.dll", CharSet = CharSet.Unicode, SetLastError = true)]
+ internal static extern bool IsNormalizedString(int normForm, string source, int length);
+
+ [DllImport("Normaliz.dll", CharSet = CharSet.Unicode, SetLastError = true)]
+ internal static extern int NormalizeString(
+ int normForm,
+ string source,
+ int sourceLength,
+ [System.Runtime.InteropServices.OutAttribute()]
+ char[] destination,
+ int destinationLength);
+ }
+}
diff --git a/src/mscorlib/src/Interop/Windows/kernel32/Interop.Globalization.cs b/src/mscorlib/src/Interop/Windows/kernel32/Interop.Globalization.cs
new file mode 100644
index 0000000000..2bb349d670
--- /dev/null
+++ b/src/mscorlib/src/Interop/Windows/kernel32/Interop.Globalization.cs
@@ -0,0 +1,131 @@
+// 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.InteropServices;
+
+internal static partial class Interop
+{
+ internal static unsafe partial class Kernel32
+ {
+ internal const int LOCALE_NAME_MAX_LENGTH = 85;
+ internal const uint LOCALE_ALLOW_NEUTRAL_NAMES = 0x08000000; // Flag to allow returning neutral names/lcids for name conversion
+ internal const uint LOCALE_SUPPLEMENTAL = 0x00000002;
+ internal const uint LOCALE_REPLACEMENT = 0x00000008;
+ internal const uint LOCALE_NEUTRALDATA = 0x00000010;
+ internal const uint LOCALE_SPECIFICDATA = 0x00000020;
+ internal const int COMPARE_STRING = 0x0001;
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ internal extern static unsafe int LCIDToLocaleName(int locale, char *pLocaleName, int cchName, uint dwFlags);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ internal extern static int LocaleNameToLCID(string lpName, uint dwFlags);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ internal extern static unsafe int LCMapStringEx(
+ string lpLocaleName,
+ uint dwMapFlags,
+ char* lpSrcStr,
+ int cchSrc,
+ void* lpDestStr,
+ int cchDest,
+ void* lpVersionInformation,
+ void* lpReserved,
+ IntPtr sortHandle);
+
+ [DllImport("kernel32.dll", EntryPoint = "FindNLSStringEx")]
+ internal extern static unsafe int FindNLSStringEx(
+ char* lpLocaleName,
+ uint dwFindNLSStringFlags,
+ char* lpStringSource,
+ int cchSource,
+ char* lpStringValue,
+ int cchValue,
+ int* pcchFound,
+ void* lpVersionInformation,
+ void* lpReserved,
+ IntPtr sortHandle);
+
+ [DllImport("kernel32.dll", EntryPoint = "CompareStringEx")]
+ internal extern static unsafe int CompareStringEx(
+ char* lpLocaleName,
+ uint dwCmpFlags,
+ char* lpString1,
+ int cchCount1,
+ char* lpString2,
+ int cchCount2,
+ void* lpVersionInformation,
+ void* lpReserved,
+ IntPtr lParam);
+
+ [DllImport("kernel32.dll", EntryPoint = "CompareStringOrdinal")]
+ internal extern static unsafe int CompareStringOrdinal(
+ char* lpString1,
+ int cchCount1,
+ char* lpString2,
+ int cchCount2,
+ bool bIgnoreCase);
+
+ [DllImport("kernel32.dll", EntryPoint = "FindStringOrdinal")]
+ internal extern static unsafe int FindStringOrdinal(
+ uint dwFindStringOrdinalFlags,
+ char* lpStringSource,
+ int cchSource,
+ char* lpStringValue,
+ int cchValue,
+ int bIgnoreCase);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ internal extern static unsafe bool IsNLSDefinedString(
+ int Function,
+ uint dwFlags,
+ IntPtr lpVersionInformation,
+ char* lpString,
+ int cchStr);
+
+ [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
+ internal static extern bool GetUserPreferredUILanguages(uint dwFlags, out uint pulNumLanguages, char [] pwszLanguagesBuffer, ref uint pcchLanguagesBuffer);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ internal static extern int GetLocaleInfoEx(string lpLocaleName, uint LCType, IntPtr lpLCData, int cchData);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ internal extern static bool EnumSystemLocalesEx(EnumLocalesProcEx lpLocaleEnumProcEx, uint dwFlags, IntPtr lParam, IntPtr reserved);
+
+ internal delegate BOOL EnumLocalesProcEx(IntPtr lpLocaleString, uint dwFlags, IntPtr lParam);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ internal extern static int ResolveLocaleName(string lpNameToResolve, char* lpLocaleName, int cchLocaleName);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ internal extern static bool EnumTimeFormatsEx(EnumTimeFormatsProcEx lpTimeFmtEnumProcEx, string lpLocaleName, uint dwFlags, IntPtr lParam);
+
+ internal delegate BOOL EnumTimeFormatsProcEx(IntPtr lpTimeFormatString, IntPtr lParam);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ internal extern static int GetCalendarInfoEx(string lpLocaleName, uint Calendar, IntPtr lpReserved, uint CalType, IntPtr lpCalData, int cchData, out int lpValue);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ internal extern static int GetCalendarInfoEx(string lpLocaleName, uint Calendar, IntPtr lpReserved, uint CalType, IntPtr lpCalData, int cchData, IntPtr lpValue);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ internal extern static bool EnumCalendarInfoExEx(EnumCalendarInfoProcExEx pCalInfoEnumProcExEx, string lpLocaleName, uint Calendar, string lpReserved, uint CalType, IntPtr lParam);
+
+ internal delegate BOOL EnumCalendarInfoProcExEx(IntPtr lpCalendarInfoString, uint Calendar, IntPtr lpReserved, IntPtr lParam);
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct NlsVersionInfoEx
+ {
+ internal int dwNLSVersionInfoSize;
+ internal int dwNLSVersion;
+ internal int dwDefinedVersion;
+ internal int dwEffectiveId;
+ internal Guid guidCustomVersion;
+ }
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
+ internal extern static unsafe bool GetNLSVersionEx(int function, string localeName, NlsVersionInfoEx* lpVersionInformation);
+ }
+}
diff --git a/src/mscorlib/src/Microsoft/Win32/OAVariantLib.cs b/src/mscorlib/src/Microsoft/Win32/OAVariantLib.cs
index 6c2c6e9630..93138e6e16 100644
--- a/src/mscorlib/src/Microsoft/Win32/OAVariantLib.cs
+++ b/src/mscorlib/src/Microsoft/Win32/OAVariantLib.cs
@@ -12,8 +12,9 @@
**
**
===========================================================*/
-namespace Microsoft.Win32 {
-
+
+namespace Microsoft.Win32
+{
using System;
using System.Diagnostics.Contracts;
using System.Reflection;
@@ -31,8 +32,8 @@ namespace Microsoft.Win32 {
public const int NoUserOverride = 0x04;
public const int CalendarHijri = 0x08;
public const int LocalBool = 0x10;
-
- internal static readonly Type [] ClassTypes = {
+
+ internal static readonly Type[] ClassTypes = {
typeof(Empty),
typeof(void),
typeof(Boolean),
@@ -58,12 +59,12 @@ namespace Microsoft.Win32 {
typeof(DBNull),
};
- // Keep these numbers in sync w/ the above array.
- private const int CV_OBJECT=0x12;
-
+ // Keep these numbers in sync w/ the above array.
+ private const int CV_OBJECT = 0x12;
+
#endregion
-
+
#region Internal Methods
/**
@@ -79,43 +80,45 @@ namespace Microsoft.Win32 {
throw new ArgumentNullException(nameof(targetClass));
if (culture == null)
throw new ArgumentNullException(nameof(culture));
- Variant result = new Variant ();
- ChangeTypeEx(ref result, ref source,
+ Variant result = new Variant();
+ ChangeTypeEx(ref result, ref source,
#if FEATURE_USE_LCID
- culture.LCID,
+ culture.LCID,
#else
// @CORESYSTODO: what does CoreSystem expect for this argument?
0,
#endif
targetClass.TypeHandle.Value, GetCVTypeFromClass(targetClass), options);
return result;
- }
+ }
#endregion
#region Private Helpers
- private static int GetCVTypeFromClass(Type ctype)
+ private static int GetCVTypeFromClass(Type ctype)
{
Contract.Requires(ctype != null);
#if _DEBUG
BCLDebug.Assert(ClassTypes[CV_OBJECT] == typeof(Object), "OAVariantLib::ClassTypes[CV_OBJECT] == Object.class");
#endif
-
- int cvtype=-1;
- for (int i=0; i<ClassTypes.Length; i++) {
- if (ctype.Equals(ClassTypes[i])) {
- cvtype=i;
+
+ int cvtype = -1;
+ for (int i = 0; i < ClassTypes.Length; i++)
+ {
+ if (ctype.Equals(ClassTypes[i]))
+ {
+ cvtype = i;
break;
}
}
-
+
// OleAut Binder works better if unrecognized
// types were changed to Object. So don't throw here.
if (cvtype == -1)
cvtype = CV_OBJECT;
-
+
return cvtype;
}
diff --git a/src/mscorlib/src/Microsoft/Win32/Registry.cs b/src/mscorlib/src/Microsoft/Win32/Registry.cs
index bf4f73949a..aa2dd9b396 100644
--- a/src/mscorlib/src/Microsoft/Win32/Registry.cs
+++ b/src/mscorlib/src/Microsoft/Win32/Registry.cs
@@ -2,133 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-
-namespace Microsoft.Win32 {
- using System;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
-
- /**
- * Registry encapsulation. Contains members representing all top level system
- * keys.
- *
- * @security(checkClassLinking=on)
- */
- //This class contains only static members and does not need to be serializable.
- internal static class Registry {
- static Registry()
- {
- }
-
- /**
- * Current User Key.
- *
- * This key should be used as the root for all user specific settings.
- */
- public static readonly RegistryKey CurrentUser = RegistryKey.GetBaseKey(RegistryKey.HKEY_CURRENT_USER);
-
- /**
- * Local Machine Key.
- *
- * This key should be used as the root for all machine specific settings.
- */
- public static readonly RegistryKey LocalMachine = RegistryKey.GetBaseKey(RegistryKey.HKEY_LOCAL_MACHINE);
-
- /**
- * Classes Root Key.
- *
- * This is the root key of class information.
- */
- public static readonly RegistryKey ClassesRoot = RegistryKey.GetBaseKey(RegistryKey.HKEY_CLASSES_ROOT);
-
- /**
- * Users Root Key.
- *
- * This is the root of users.
- */
- public static readonly RegistryKey Users = RegistryKey.GetBaseKey(RegistryKey.HKEY_USERS);
-
- /**
- * Performance Root Key.
- *
- * This is where dynamic performance data is stored on NT.
- */
- public static readonly RegistryKey PerformanceData = RegistryKey.GetBaseKey(RegistryKey.HKEY_PERFORMANCE_DATA);
-
- /**
- * Current Config Root Key.
- *
- * This is where current configuration information is stored.
- */
- public static readonly RegistryKey CurrentConfig = RegistryKey.GetBaseKey(RegistryKey.HKEY_CURRENT_CONFIG);
-
- //
- // Following function will parse a keyName and returns the basekey for it.
- // It will also store the subkey name in the out parameter.
- // If the keyName is not valid, we will throw ArgumentException.
- // The return value shouldn't be null.
- //
- private static RegistryKey GetBaseKeyFromKeyName(string keyName, out string subKeyName) {
- if( keyName == null) {
- throw new ArgumentNullException(nameof(keyName));
- }
-
- string basekeyName;
- int i = keyName.IndexOf('\\');
- if( i != -1) {
- basekeyName = keyName.Substring(0, i).ToUpper(System.Globalization.CultureInfo.InvariantCulture);
- }
- else {
- basekeyName = keyName.ToUpper(System.Globalization.CultureInfo.InvariantCulture);
- }
- RegistryKey basekey = null;
-
- switch(basekeyName) {
- case "HKEY_CURRENT_USER":
- basekey = Registry.CurrentUser;
- break;
- case "HKEY_LOCAL_MACHINE":
- basekey = Registry.LocalMachine;
- break;
- case "HKEY_CLASSES_ROOT":
- basekey = Registry.ClassesRoot;
- break;
- case "HKEY_USERS":
- basekey = Registry.Users;
- break;
- case "HKEY_PERFORMANCE_DATA":
- basekey = Registry.PerformanceData;
- break;
- case "HKEY_CURRENT_CONFIG":
- basekey = Registry.CurrentConfig;
- break;
- default:
- throw new ArgumentException(Environment.GetResourceString("Arg_RegInvalidKeyName", nameof(keyName)));
- }
- if( i == -1 || i == keyName.Length) {
- subKeyName = string.Empty;
- }
- else {
- subKeyName = keyName.Substring(i + 1, keyName.Length - i - 1);
- }
- return basekey;
- }
-
- public static object GetValue(string keyName, string valueName, object defaultValue ) {
- string subKeyName;
- RegistryKey basekey = GetBaseKeyFromKeyName(keyName, out subKeyName);
- BCLDebug.Assert(basekey != null, "basekey can't be null.");
- RegistryKey key = basekey.OpenSubKey(subKeyName);
- if(key == null) { // if the key doesn't exist, do nothing
- return null;
- }
- try {
- return key.GetValue(valueName, defaultValue);
- }
- finally {
- key.Close();
- }
- }
+namespace Microsoft.Win32
+{
+ internal static class Registry
+ {
+ public static readonly RegistryKey CurrentUser = RegistryKey.CurrentUser;
+ public static readonly RegistryKey LocalMachine = RegistryKey.LocalMachine;
}
}
diff --git a/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs b/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs
index f82b276059..e39b95903e 100644
--- a/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs
+++ b/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs
@@ -2,28 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-
-/*
- Note on transaction support:
- Eventually we will want to add support for NT's transactions to our
- RegistryKey API's (possibly Whidbey M3?). When we do this, here's
- the list of API's we need to make transaction-aware:
-
- RegCreateKeyEx
- RegDeleteKey
- RegDeleteValue
- RegEnumKeyEx
- RegEnumValue
- RegOpenKeyEx
- RegQueryInfoKey
- RegQueryValueEx
- RegSetValueEx
-
- We can ignore RegConnectRegistry (remote registry access doesn't yet have
- transaction support) and RegFlushKey. RegCloseKey doesn't require any
- additional work. .
- */
-
/*
Note on ACL support:
The key thing to note about ACL's is you set them on a kernel object like a
@@ -48,70 +26,41 @@
*/
+using Microsoft.Win32.SafeHandles;
+using System;
+using System.Buffers;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
namespace Microsoft.Win32
{
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Security;
- using System.Text;
- using System.Threading;
- using System.IO;
- using System.Runtime.Remoting;
- using System.Runtime.InteropServices;
- using Microsoft.Win32.SafeHandles;
- using System.Runtime.Versioning;
- using System.Globalization;
- using System.Diagnostics.Contracts;
- using System.Diagnostics.CodeAnalysis;
-
/**
* Registry encapsulation. To get an instance of a RegistryKey use the
* Registry class's static members then call OpenSubKey.
- *
- * @see Registry
- * @security(checkDllCalls=off)
- * @security(checkClassLinking=on)
*/
- internal sealed class RegistryKey : MarshalByRefObject, IDisposable
+ internal sealed class RegistryKey : MarshalByRefObject, IDisposable
{
+ // Use the public Registry.CurrentUser
+ internal static readonly RegistryKey CurrentUser =
+ GetBaseKey(new IntPtr(unchecked((int)0x80000001)), "HKEY_CURRENT_USER");
+
+ // Use the public Registry.LocalMachine
+ internal static readonly RegistryKey LocalMachine =
+ GetBaseKey(new IntPtr(unchecked((int)0x80000002)), "HKEY_LOCAL_MACHINE");
// We could use const here, if C# supported ELEMENT_TYPE_I fully.
- internal static readonly IntPtr HKEY_CLASSES_ROOT = new IntPtr(unchecked((int)0x80000000));
- internal static readonly IntPtr HKEY_CURRENT_USER = new IntPtr(unchecked((int)0x80000001));
- internal static readonly IntPtr HKEY_LOCAL_MACHINE = new IntPtr(unchecked((int)0x80000002));
- internal static readonly IntPtr HKEY_USERS = new IntPtr(unchecked((int)0x80000003));
- internal static readonly IntPtr HKEY_PERFORMANCE_DATA = new IntPtr(unchecked((int)0x80000004));
- internal static readonly IntPtr HKEY_CURRENT_CONFIG = new IntPtr(unchecked((int)0x80000005));
-
- // Dirty indicates that we have munged data that should be potentially
- // written to disk.
- //
- private const int STATE_DIRTY = 0x0001;
+ private static readonly IntPtr HKEY_CURRENT_USER = new IntPtr(unchecked((int)0x80000001));
+ private static readonly IntPtr HKEY_LOCAL_MACHINE = new IntPtr(unchecked((int)0x80000002));
// SystemKey indicates that this is a "SYSTEMKEY" and shouldn't be "opened"
// or "closed".
//
- private const int STATE_SYSTEMKEY = 0x0002;
+ private const int STATE_SYSTEMKEY = 0x0002;
// Access
//
- private const int STATE_WRITEACCESS = 0x0004;
-
- // Indicates if this key is for HKEY_PERFORMANCE_DATA
- private const int STATE_PERF_DATA = 0x0008;
-
- // Names of keys. This array must be in the same order as the HKEY values listed above.
- //
- private static readonly String[] hkeyNames = new String[] {
- "HKEY_CLASSES_ROOT",
- "HKEY_CURRENT_USER",
- "HKEY_LOCAL_MACHINE",
- "HKEY_USERS",
- "HKEY_PERFORMANCE_DATA",
- "HKEY_CURRENT_CONFIG",
- };
+ private const int STATE_WRITEACCESS = 0x0004;
// MSDN defines the following limits for registry key names & values:
// Key Name: 255 characters
@@ -122,30 +71,7 @@ namespace Microsoft.Win32
private volatile SafeRegistryHandle hkey = null;
private volatile int state = 0;
- private volatile String keyName;
- private volatile bool remoteKey = false;
- private volatile RegistryKeyPermissionCheck checkMode;
- private volatile RegistryView regView = RegistryView.Default;
-
- /**
- * RegistryInternalCheck values. Useful only for CheckPermission
- */
- private enum RegistryInternalCheck {
- CheckSubKeyWritePermission = 0,
- CheckSubKeyReadPermission = 1,
- CheckSubKeyCreatePermission = 2,
- CheckSubTreeReadPermission = 3,
- CheckSubTreeWritePermission = 4,
- CheckSubTreeReadWritePermission = 5,
- CheckValueWritePermission = 6,
- CheckValueCreatePermission = 7,
- CheckValueReadPermission = 8,
- CheckKeyReadPermission = 9,
- CheckSubTreePermission = 10,
- CheckOpenSubKeyWithWritablePermission = 11,
- CheckOpenSubKeyPermission = 12
- };
-
+ private volatile string keyName;
/**
* Creates a RegistryKey.
@@ -156,37 +82,32 @@ namespace Microsoft.Win32
* The remoteKey flag when set to true indicates that we are dealing with registry entries
* on a remote machine and requires the program making these calls to have full trust.
*/
- private RegistryKey(SafeRegistryHandle hkey, bool writable, bool systemkey, bool remoteKey, bool isPerfData, RegistryView view) {
+ private RegistryKey(SafeRegistryHandle hkey, bool writable, bool systemkey)
+ {
this.hkey = hkey;
- this.keyName = "";
- this.remoteKey = remoteKey;
- this.regView = view;
- if (systemkey) {
- this.state |= STATE_SYSTEMKEY;
+ keyName = "";
+ if (systemkey)
+ {
+ state |= STATE_SYSTEMKEY;
}
- if (writable) {
- this.state |= STATE_WRITEACCESS;
+ if (writable)
+ {
+ state |= STATE_WRITEACCESS;
}
- if (isPerfData)
- this.state |= STATE_PERF_DATA;
- ValidateKeyView(view);
- }
-
- /**
- * Closes this key, flushes it to disk if the contents have been modified.
- */
- public void Close() {
- Dispose(true);
}
- private void Dispose(bool disposing) {
- if (hkey != null) {
-
- if (!IsSystemKey()) {
- try {
+ private void Dispose(bool disposing)
+ {
+ if (hkey != null)
+ {
+ if (!IsSystemKey())
+ {
+ try
+ {
hkey.Dispose();
}
- catch (IOException){
+ catch (IOException)
+ {
// we don't really care if the handle is invalid at this point
}
finally
@@ -194,20 +115,6 @@ namespace Microsoft.Win32
hkey = null;
}
}
- else if (disposing && IsPerfDataKey()) {
- // System keys should never be closed. However, we want to call RegCloseKey
- // on HKEY_PERFORMANCE_DATA when called from PerformanceCounter.CloseSharedResources
- // (i.e. when disposing is true) so that we release the PERFLIB cache and cause it
- // to be refreshed (by re-reading the registry) when accessed subsequently.
- // This is the only way we can see the just installed perf counter.
- // NOTE: since HKEY_PERFORMANCE_DATA is process wide, there is inherent race condition in closing
- // the key asynchronously. While Vista is smart enough to rebuild the PERFLIB resources
- // in this situation the down level OSes are not. We have a small window between
- // the dispose below and usage elsewhere (other threads). This is By Design.
- // This is less of an issue when OS > NT5 (i.e Vista & higher), we can close the perfkey
- // (to release & refresh PERFLIB resources) and the OS will rebuild PERFLIB as necessary.
- SafeRegistryHandle.RegCloseKey(RegistryKey.HKEY_PERFORMANCE_DATA);
- }
}
}
@@ -216,278 +123,199 @@ namespace Microsoft.Win32
Dispose(true);
}
- public void DeleteValue(String name, bool throwOnMissingValue) {
+ public void DeleteValue(string name, bool throwOnMissingValue)
+ {
EnsureWriteable();
- CheckPermission(RegistryInternalCheck.CheckValueWritePermission, name, false, RegistryKeyPermissionCheck.Default);
int errorCode = Win32Native.RegDeleteValue(hkey, name);
-
+
//
- // From windows 2003 server, if the name is too long we will get error code ERROR_FILENAME_EXCED_RANGE
+ // From windows 2003 server, if the name is too long we will get error code ERROR_FILENAME_EXCED_RANGE
// This still means the name doesn't exist. We need to be consistent with previous OS.
//
- if (errorCode == Win32Native.ERROR_FILE_NOT_FOUND || errorCode == Win32Native.ERROR_FILENAME_EXCED_RANGE) {
- if (throwOnMissingValue) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSubKeyValueAbsent);
+ if (errorCode == Win32Native.ERROR_FILE_NOT_FOUND || errorCode == Win32Native.ERROR_FILENAME_EXCED_RANGE)
+ {
+ if (throwOnMissingValue)
+ {
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSubKeyValueAbsent);
}
+
// Otherwise, just return giving no indication to the user.
// (For compatibility)
}
+
// We really should throw an exception here if errorCode was bad,
// but we can't for compatibility reasons.
- BCLDebug.Correctness(errorCode == 0, "RegDeleteValue failed. Here's your error code: "+errorCode);
- }
-
- /**
- * Retrieves a new RegistryKey that represents the requested key. Valid
- * values are:
- *
- * HKEY_CLASSES_ROOT,
- * HKEY_CURRENT_USER,
- * HKEY_LOCAL_MACHINE,
- * HKEY_USERS,
- * HKEY_PERFORMANCE_DATA,
- * HKEY_CURRENT_CONFIG,
- * HKEY_DYN_DATA.
- *
- * @param hKey HKEY_* to open.
- *
- * @return the RegistryKey requested.
- */
- internal static RegistryKey GetBaseKey(IntPtr hKey) {
- return GetBaseKey(hKey, RegistryView.Default);
+ Debug.Assert(errorCode == 0, "RegDeleteValue failed. Here's your error code: " + errorCode);
}
- internal static RegistryKey GetBaseKey(IntPtr hKey, RegistryView view) {
-
- int index = ((int)hKey) & 0x0FFFFFFF;
- BCLDebug.Assert(index >= 0 && index < hkeyNames.Length, "index is out of range!");
- BCLDebug.Assert((((int)hKey) & 0xFFFFFFF0) == 0x80000000, "Invalid hkey value!");
-
- bool isPerf = hKey == HKEY_PERFORMANCE_DATA;
- // only mark the SafeHandle as ownsHandle if the key is HKEY_PERFORMANCE_DATA.
- SafeRegistryHandle srh = new SafeRegistryHandle(hKey, isPerf);
+ private static RegistryKey GetBaseKey(IntPtr hKey, string keyName)
+ {
+ SafeRegistryHandle srh = new SafeRegistryHandle(hKey, ownsHandle: false);
- RegistryKey key = new RegistryKey(srh, true, true,false, isPerf, view);
- key.checkMode = RegistryKeyPermissionCheck.Default;
- key.keyName = hkeyNames[index];
+ RegistryKey key = new RegistryKey(srh, true, true);
+ key.keyName = keyName;
return key;
}
- /**
- * Retrieves a subkey. If readonly is <b>true</b>, then the subkey is opened with
- * read-only access.
- *
- * @param name Name or path of subkey to open.
- * @param readonly Set to <b>true</b> if you only need readonly access.
- *
- * @return the Subkey requested, or <b>null</b> if the operation failed.
- */
- public RegistryKey OpenSubKey(string name, bool writable ) {
+ /// <summary>
+ /// Retrieves a subkey or null if the operation failed.
+ /// </summary>
+ /// <param name="writable">True to open writable, otherwise opens the key read-only.</param>
+ public RegistryKey OpenSubKey(string name, bool writable)
+ {
ValidateKeyName(name);
EnsureNotDisposed();
- name = FixupName(name); // Fixup multiple slashes to a single slash
- CheckPermission(RegistryInternalCheck.CheckOpenSubKeyWithWritablePermission, name, writable, RegistryKeyPermissionCheck.Default);
SafeRegistryHandle result = null;
int ret = Win32Native.RegOpenKeyEx(hkey,
name,
0,
- GetRegistryKeyAccess(writable) | (int)regView,
+ writable ? Win32Native.KEY_READ | Win32Native.KEY_WRITE : Win32Native.KEY_READ,
out result);
- if (ret == 0 && !result.IsInvalid) {
- RegistryKey key = new RegistryKey(result, writable, false, remoteKey, false, regView);
- key.checkMode = GetSubKeyPermissonCheck(writable);
+ if (ret == 0 && !result.IsInvalid)
+ {
+ RegistryKey key = new RegistryKey(result, writable, false);
key.keyName = keyName + "\\" + name;
return key;
}
// Return null if we didn't find the key.
- if (ret == Win32Native.ERROR_ACCESS_DENIED || ret == Win32Native.ERROR_BAD_IMPERSONATION_LEVEL) {
+ if (ret == Win32Native.ERROR_ACCESS_DENIED || ret == Win32Native.ERROR_BAD_IMPERSONATION_LEVEL)
+ {
// We need to throw SecurityException here for compatibility reasons,
// although UnauthorizedAccessException will make more sense.
ThrowHelper.ThrowSecurityException(ExceptionResource.Security_RegistryPermission);
}
-
- return null;
- }
-
- // This required no security checks. This is to get around the Deleting SubKeys which only require
- // write permission. They call OpenSubKey which required read. Now instead call this function w/o security checks
- internal RegistryKey InternalOpenSubKey(String name, bool writable) {
- ValidateKeyName(name);
- EnsureNotDisposed();
- SafeRegistryHandle result = null;
- int ret = Win32Native.RegOpenKeyEx(hkey,
- name,
- 0,
- GetRegistryKeyAccess(writable) | (int)regView,
- out result);
-
- if (ret == 0 && !result.IsInvalid) {
- RegistryKey key = new RegistryKey(result, writable, false, remoteKey, false, regView);
- key.keyName = keyName + "\\" + name;
- return key;
- }
return null;
}
- /**
- * Returns a subkey with read only permissions.
- *
- * @param name Name or path of subkey to open.
- *
- * @return the Subkey requested, or <b>null</b> if the operation failed.
- */
- public RegistryKey OpenSubKey(String name) {
- return OpenSubKey(name, false);
- }
-
- internal int InternalSubKeyCount() {
- EnsureNotDisposed();
-
- int subkeys = 0;
- int junk = 0;
- int ret = Win32Native.RegQueryInfoKey(hkey,
- null,
- null,
- IntPtr.Zero,
- ref subkeys, // subkeys
- null,
- null,
- ref junk, // values
- null,
- null,
- null,
- null);
-
- if (ret != 0)
- Win32Error(ret, null);
- return subkeys;
- }
-
- /**
- * Retrieves an array of strings containing all the subkey names.
- *
- * @return all subkey names.
- */
- public String[] GetSubKeyNames() {
- CheckPermission(RegistryInternalCheck.CheckKeyReadPermission, null, false, RegistryKeyPermissionCheck.Default);
- return InternalGetSubKeyNames();
- }
-
- internal unsafe String[] InternalGetSubKeyNames() {
+ /// <summary>
+ /// Retrieves an array of strings containing all the subkey names.
+ /// </summary>
+ public string[] GetSubKeyNames()
+ {
EnsureNotDisposed();
- int subkeys = InternalSubKeyCount();
- String[] names = new String[subkeys]; // Returns 0-length array if empty.
- if (subkeys > 0) {
- char[] name = new char[MaxKeyLength + 1];
-
- int namelen;
+ var names = new List<string>();
+ char[] name = ArrayPool<char>.Shared.Rent(MaxKeyLength + 1);
- fixed (char *namePtr = &name[0])
+ try
+ {
+ int result;
+ int nameLength = name.Length;
+
+ while ((result = Win32Native.RegEnumKeyEx(
+ hkey,
+ names.Count,
+ name,
+ ref nameLength,
+ null,
+ null,
+ null,
+ null)) != Interop.Errors.ERROR_NO_MORE_ITEMS)
{
- for (int i=0; i<subkeys; i++) {
- namelen = name.Length; // Don't remove this. The API's doesn't work if this is not properly initialised.
- int ret = Win32Native.RegEnumKeyEx(hkey,
- i,
- namePtr,
- ref namelen,
- null,
- null,
- null,
- null);
- if (ret != 0)
- Win32Error(ret, null);
- names[i] = new String(namePtr);
+ switch (result)
+ {
+ case Interop.Errors.ERROR_SUCCESS:
+ names.Add(new string(name, 0, nameLength));
+ nameLength = name.Length;
+ break;
+ default:
+ // Throw the error
+ Win32Error(result, null);
+ break;
}
}
}
+ finally
+ {
+ ArrayPool<char>.Shared.Return(name);
+ }
- return names;
+ return names.ToArray();
}
- internal int InternalValueCount() {
- EnsureNotDisposed();
- int values = 0;
- int junk = 0;
- int ret = Win32Native.RegQueryInfoKey(hkey,
- null,
- null,
- IntPtr.Zero,
- ref junk, // subkeys
- null,
- null,
- ref values, // values
- null,
- null,
- null,
- null);
- if (ret != 0)
- Win32Error(ret, null);
- return values;
- }
-
- /**
- * Retrieves an array of strings containing all the value names.
- *
- * @return all value names.
- */
- public unsafe String[] GetValueNames() {
- CheckPermission(RegistryInternalCheck.CheckKeyReadPermission, null, false, RegistryKeyPermissionCheck.Default);
+ /// <summary>
+ /// Retrieves an array of strings containing all the value names.
+ /// </summary>
+ public unsafe string[] GetValueNames()
+ {
EnsureNotDisposed();
+ var names = new List<string>();
- int values = InternalValueCount();
- String[] names = new String[values];
+ // Names in the registry aren't usually very long, although they can go to as large
+ // as 16383 characters (MaxValueLength).
+ //
+ // Every call to RegEnumValue will allocate another buffer to get the data from
+ // NtEnumerateValueKey before copying it back out to our passed in buffer. This can
+ // add up quickly- we'll try to keep the memory pressure low and grow the buffer
+ // only if needed.
- if (values > 0) {
- char[] name = new char[MaxValueLength + 1];
- int namelen;
+ char[] name = ArrayPool<char>.Shared.Rent(100);
- fixed (char *namePtr = &name[0])
+ try
+ {
+ int result;
+ int nameLength = name.Length;
+
+ while ((result = Win32Native.RegEnumValue(
+ hkey,
+ names.Count,
+ name,
+ ref nameLength,
+ IntPtr.Zero,
+ null,
+ null,
+ null)) != Interop.Errors.ERROR_NO_MORE_ITEMS)
{
- for (int i=0; i<values; i++) {
- namelen = name.Length;
-
- int ret = Win32Native.RegEnumValue(hkey,
- i,
- namePtr,
- ref namelen,
- IntPtr.Zero,
- null,
- null,
- null);
-
- if (ret != 0) {
- // ignore ERROR_MORE_DATA if we're querying HKEY_PERFORMANCE_DATA
- if (!(IsPerfDataKey() && ret == Win32Native.ERROR_MORE_DATA))
- Win32Error(ret, null);
- }
-
- names[i] = new String(namePtr);
+ switch (result)
+ {
+ // The size is only ever reported back correctly in the case
+ // of ERROR_SUCCESS. It will almost always be changed, however.
+ case Interop.Errors.ERROR_SUCCESS:
+ names.Add(new string(name, 0, nameLength));
+ break;
+ case Interop.Errors.ERROR_MORE_DATA:
+ if (IsPerfDataKey())
+ {
+ // Enumerating the values for Perf keys always returns
+ // ERROR_MORE_DATA, but has a valid name. Buffer does need
+ // to be big enough however. 8 characters is the largest
+ // known name. The size isn't returned, but the string is
+ // null terminated.
+ fixed (char* c = &name[0])
+ {
+ names.Add(new string(c));
+ }
+ }
+ else
+ {
+ char[] oldName = name;
+ int oldLength = oldName.Length;
+ name = null;
+ ArrayPool<char>.Shared.Return(oldName);
+ name = ArrayPool<char>.Shared.Rent(checked(oldLength * 2));
+ }
+ break;
+ default:
+ // Throw the error
+ Win32Error(result, null);
+ break;
}
+
+ // Always set the name length back to the buffer size
+ nameLength = name.Length;
}
}
+ finally
+ {
+ if (name != null)
+ ArrayPool<char>.Shared.Return(name);
+ }
- return names;
- }
-
- /**
- * Retrieves the specified value. <b>null</b> is returned if the value
- * doesn't exist.
- *
- * Note that <var>name</var> can be null or "", at which point the
- * unnamed or default value of this Registry key is returned, if any.
- *
- * @param name Name of value to retrieve.
- *
- * @return the data associated with the value.
- */
- public Object GetValue(String name) {
- CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default);
- return InternalGetValue(name, null, false, true);
+ return names.ToArray();
}
/**
@@ -505,426 +333,257 @@ namespace Microsoft.Win32
*
* @return the data associated with the value.
*/
- public Object GetValue(String name, Object defaultValue) {
- CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default);
- return InternalGetValue(name, defaultValue, false, true);
- }
-
- public Object GetValue(String name, Object defaultValue, RegistryValueOptions options) {
- if( options < RegistryValueOptions.None || options > RegistryValueOptions.DoNotExpandEnvironmentNames) {
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)options), nameof(options));
- }
- bool doNotExpand = (options == RegistryValueOptions.DoNotExpandEnvironmentNames);
- CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default);
- return InternalGetValue(name, defaultValue, doNotExpand, true);
- }
-
- internal Object InternalGetValue(String name, Object defaultValue, bool doNotExpand, bool checkSecurity) {
- if (checkSecurity) {
- // Name can be null! It's the most common use of RegQueryValueEx
- EnsureNotDisposed();
- }
+ public object GetValue(string name, object defaultValue = null, bool doNotExpand = false)
+ {
+ EnsureNotDisposed();
- Object data = defaultValue;
+ object data = defaultValue;
int type = 0;
int datasize = 0;
int ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, (byte[])null, ref datasize);
- if (ret != 0) {
- if (IsPerfDataKey()) {
- int size = 65000;
- int sizeInput = size;
-
- int r;
- byte[] blob = new byte[size];
- while (Win32Native.ERROR_MORE_DATA == (r = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref sizeInput))) {
- if (size == Int32.MaxValue) {
- // ERROR_MORE_DATA was returned however we cannot increase the buffer size beyond Int32.MaxValue
- Win32Error(r, name);
- }
- else if (size > (Int32.MaxValue / 2)) {
- // at this point in the loop "size * 2" would cause an overflow
- size = Int32.MaxValue;
- }
- else {
- size *= 2;
- }
- sizeInput = size;
- blob = new byte[size];
- }
- if (r != 0)
- Win32Error(r, name);
- return blob;
- }
- else {
- // For stuff like ERROR_FILE_NOT_FOUND, we want to return null (data).
- // Some OS's returned ERROR_MORE_DATA even in success cases, so we
- // want to continue on through the function.
- if (ret != Win32Native.ERROR_MORE_DATA)
- return data;
- }
+ if (ret != 0)
+ {
+ // For stuff like ERROR_FILE_NOT_FOUND, we want to return null (data).
+ // Some OS's returned ERROR_MORE_DATA even in success cases, so we
+ // want to continue on through the function.
+ if (ret != Win32Native.ERROR_MORE_DATA)
+ return data;
}
- if (datasize < 0) {
+ if (datasize < 0)
+ {
// unexpected code path
- BCLDebug.Assert(false, "[InternalGetValue] RegQueryValue returned ERROR_SUCCESS but gave a negative datasize");
+ Debug.Assert(false, "[InternalGetValue] RegQueryValue returned ERROR_SUCCESS but gave a negative datasize");
datasize = 0;
}
+ switch (type)
+ {
+ case Win32Native.REG_NONE:
+ case Win32Native.REG_DWORD_BIG_ENDIAN:
+ case Win32Native.REG_BINARY:
+ {
+ byte[] blob = new byte[datasize];
+ ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize);
+ data = blob;
+ }
+ break;
+ case Win32Native.REG_QWORD:
+ { // also REG_QWORD_LITTLE_ENDIAN
+ if (datasize > 8)
+ {
+ // prevent an AV in the edge case that datasize is larger than sizeof(long)
+ goto case Win32Native.REG_BINARY;
+ }
+ long blob = 0;
+ Debug.Assert(datasize == 8, "datasize==8");
+ // Here, datasize must be 8 when calling this
+ ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, ref blob, ref datasize);
- switch (type) {
- case Win32Native.REG_NONE:
- case Win32Native.REG_DWORD_BIG_ENDIAN:
- case Win32Native.REG_BINARY: {
- byte[] blob = new byte[datasize];
- ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize);
- data = blob;
- }
- break;
- case Win32Native.REG_QWORD:
- { // also REG_QWORD_LITTLE_ENDIAN
- if (datasize > 8) {
- // prevent an AV in the edge case that datasize is larger than sizeof(long)
- goto case Win32Native.REG_BINARY;
- }
- long blob = 0;
- BCLDebug.Assert(datasize==8, "datasize==8");
- // Here, datasize must be 8 when calling this
- ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, ref blob, ref datasize);
-
- data = blob;
- }
- break;
- case Win32Native.REG_DWORD:
- { // also REG_DWORD_LITTLE_ENDIAN
- if (datasize > 4) {
- // prevent an AV in the edge case that datasize is larger than sizeof(int)
- goto case Win32Native.REG_QWORD;
- }
- int blob = 0;
- BCLDebug.Assert(datasize==4, "datasize==4");
- // Here, datasize must be four when calling this
- ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, ref blob, ref datasize);
-
- data = blob;
- }
- break;
-
- case Win32Native.REG_SZ:
- {
- if (datasize % 2 == 1) {
- // handle the case where the registry contains an odd-byte length (corrupt data?)
- try {
- datasize = checked(datasize + 1);
- }
- catch (OverflowException e) {
- throw new IOException(Environment.GetResourceString("Arg_RegGetOverflowBug"), e);
- }
- }
- char[] blob = new char[datasize/2];
-
- ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize);
- if (blob.Length > 0 && blob[blob.Length - 1] == (char)0) {
- data = new String(blob, 0, blob.Length - 1);
- }
- else {
- // in the very unlikely case the data is missing null termination,
- // pass in the whole char[] to prevent truncating a character
- data = new String(blob);
- }
- }
- break;
-
- case Win32Native.REG_EXPAND_SZ:
- {
- if (datasize % 2 == 1) {
- // handle the case where the registry contains an odd-byte length (corrupt data?)
- try {
- datasize = checked(datasize + 1);
- }
- catch (OverflowException e) {
- throw new IOException(Environment.GetResourceString("Arg_RegGetOverflowBug"), e);
- }
- }
- char[] blob = new char[datasize/2];
-
- ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize);
-
- if (blob.Length > 0 && blob[blob.Length - 1] == (char)0) {
- data = new String(blob, 0, blob.Length - 1);
- }
- else {
- // in the very unlikely case the data is missing null termination,
- // pass in the whole char[] to prevent truncating a character
- data = new String(blob);
- }
-
- if (!doNotExpand)
- data = Environment.ExpandEnvironmentVariables((String)data);
- }
- break;
- case Win32Native.REG_MULTI_SZ:
- {
- if (datasize % 2 == 1) {
- // handle the case where the registry contains an odd-byte length (corrupt data?)
- try {
- datasize = checked(datasize + 1);
- }
- catch (OverflowException e) {
- throw new IOException(Environment.GetResourceString("Arg_RegGetOverflowBug"), e);
- }
- }
- char[] blob = new char[datasize/2];
-
- ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize);
-
- // make sure the string is null terminated before processing the data
- if (blob.Length > 0 && blob[blob.Length - 1] != (char)0) {
- try {
- char[] newBlob = new char[checked(blob.Length + 1)];
- for (int i = 0; i < blob.Length; i++) {
- newBlob[i] = blob[i];
- }
- newBlob[newBlob.Length - 1] = (char)0;
- blob = newBlob;
- }
- catch (OverflowException e) {
- throw new IOException(Environment.GetResourceString("Arg_RegGetOverflowBug"), e);
- }
- blob[blob.Length - 1] = (char)0;
- }
-
-
- IList<String> strings = new List<String>();
- int cur = 0;
- int len = blob.Length;
-
- while (ret == 0 && cur < len) {
- int nextNull = cur;
- while (nextNull < len && blob[nextNull] != (char)0) {
- nextNull++;
- }
-
- if (nextNull < len) {
- BCLDebug.Assert(blob[nextNull] == (char)0, "blob[nextNull] should be 0");
- if (nextNull-cur > 0) {
- strings.Add(new String(blob, cur, nextNull-cur));
- }
- else {
- // we found an empty string. But if we're at the end of the data,
- // it's just the extra null terminator.
- if (nextNull != len-1)
- strings.Add(String.Empty);
- }
- }
- else {
- strings.Add(new String(blob, cur, len-cur));
- }
- cur = nextNull+1;
- }
-
- data = new String[strings.Count];
- strings.CopyTo((String[])data, 0);
- }
- break;
- case Win32Native.REG_LINK:
- default:
- break;
- }
-
- return data;
- }
-
- private bool IsSystemKey() {
- return (this.state & STATE_SYSTEMKEY) != 0;
- }
-
- private bool IsWritable() {
- return (this.state & STATE_WRITEACCESS) != 0;
- }
-
- private bool IsPerfDataKey() {
- return (this.state & STATE_PERF_DATA) != 0;
- }
-
- private void SetDirty() {
- this.state |= STATE_DIRTY;
- }
-
- /**
- * Sets the specified value.
- *
- * @param name Name of value to store data in.
- * @param value Data to store.
- */
- public void SetValue(String name, Object value) {
- SetValue(name, value, RegistryValueKind.Unknown);
- }
-
- public unsafe void SetValue(String name, Object value, RegistryValueKind valueKind) {
- if (value==null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
+ data = blob;
+ }
+ break;
+ case Win32Native.REG_DWORD:
+ { // also REG_DWORD_LITTLE_ENDIAN
+ if (datasize > 4)
+ {
+ // prevent an AV in the edge case that datasize is larger than sizeof(int)
+ goto case Win32Native.REG_QWORD;
+ }
+ int blob = 0;
+ Debug.Assert(datasize == 4, "datasize==4");
+ // Here, datasize must be four when calling this
+ ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, ref blob, ref datasize);
- if (name != null && name.Length > MaxValueLength) {
- throw new ArgumentException(Environment.GetResourceString("Arg_RegValStrLenBug"));
- }
+ data = blob;
+ }
+ break;
- if (!Enum.IsDefined(typeof(RegistryValueKind), valueKind))
- throw new ArgumentException(Environment.GetResourceString("Arg_RegBadKeyKind"), nameof(valueKind));
+ case Win32Native.REG_SZ:
+ {
+ if (datasize % 2 == 1)
+ {
+ // handle the case where the registry contains an odd-byte length (corrupt data?)
+ try
+ {
+ datasize = checked(datasize + 1);
+ }
+ catch (OverflowException e)
+ {
+ throw new IOException(SR.Arg_RegGetOverflowBug, e);
+ }
+ }
+ char[] blob = new char[datasize / 2];
- EnsureWriteable();
+ ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize);
+ if (blob.Length > 0 && blob[blob.Length - 1] == (char)0)
+ {
+ data = new string(blob, 0, blob.Length - 1);
+ }
+ else
+ {
+ // in the very unlikely case the data is missing null termination,
+ // pass in the whole char[] to prevent truncating a character
+ data = new string(blob);
+ }
+ }
+ break;
- if (!remoteKey && ContainsRegistryValue(name)) { // Existing key
- CheckPermission(RegistryInternalCheck.CheckValueWritePermission, name, false, RegistryKeyPermissionCheck.Default);
- }
- else { // Creating a new value
- CheckPermission(RegistryInternalCheck.CheckValueCreatePermission, name, false, RegistryKeyPermissionCheck.Default);
- }
+ case Win32Native.REG_EXPAND_SZ:
+ {
+ if (datasize % 2 == 1)
+ {
+ // handle the case where the registry contains an odd-byte length (corrupt data?)
+ try
+ {
+ datasize = checked(datasize + 1);
+ }
+ catch (OverflowException e)
+ {
+ throw new IOException(SR.Arg_RegGetOverflowBug, e);
+ }
+ }
+ char[] blob = new char[datasize / 2];
- if (valueKind == RegistryValueKind.Unknown) {
- // this is to maintain compatibility with the old way of autodetecting the type.
- // SetValue(string, object) will come through this codepath.
- valueKind = CalculateValueKind(value);
- }
+ ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize);
- int ret = 0;
- try {
- switch (valueKind) {
- case RegistryValueKind.ExpandString:
- case RegistryValueKind.String:
+ if (blob.Length > 0 && blob[blob.Length - 1] == (char)0)
{
- String data = value.ToString();
- ret = Win32Native.RegSetValueEx(hkey,
- name,
- 0,
- valueKind,
- data,
- checked(data.Length * 2 + 2));
- break;
+ data = new string(blob, 0, blob.Length - 1);
+ }
+ else
+ {
+ // in the very unlikely case the data is missing null termination,
+ // pass in the whole char[] to prevent truncating a character
+ data = new string(blob);
}
- case RegistryValueKind.MultiString:
+ if (!doNotExpand)
+ data = Environment.ExpandEnvironmentVariables((string)data);
+ }
+ break;
+ case Win32Native.REG_MULTI_SZ:
+ {
+ if (datasize % 2 == 1)
{
- // Other thread might modify the input array after we calculate the buffer length.
- // Make a copy of the input array to be safe.
- string[] dataStrings = (string[])(((string[])value).Clone());
- int sizeInBytes = 0;
-
- // First determine the size of the array
- //
- for (int i=0; i<dataStrings.Length; i++) {
- if (dataStrings[i] == null) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetStrArrNull);
- }
- sizeInBytes = checked(sizeInBytes + (dataStrings[i].Length+1) * 2);
- }
- sizeInBytes = checked(sizeInBytes + 2);
-
- byte[] basePtr = new byte[sizeInBytes];
- fixed(byte* b = basePtr) {
- IntPtr currentPtr = new IntPtr( (void *) b);
-
- // Write out the strings...
- //
- for (int i=0; i<dataStrings.Length; i++) {
- // Assumes that the Strings are always null terminated.
- String.InternalCopy(dataStrings[i],currentPtr,(checked(dataStrings[i].Length*2)));
- currentPtr = new IntPtr((long)currentPtr + (checked(dataStrings[i].Length*2)));
- *(char*)(currentPtr.ToPointer()) = '\0';
- currentPtr = new IntPtr((long)currentPtr + 2);
- }
-
- *(char*)(currentPtr.ToPointer()) = '\0';
- currentPtr = new IntPtr((long)currentPtr + 2);
-
- ret = Win32Native.RegSetValueEx(hkey,
- name,
- 0,
- RegistryValueKind.MultiString,
- basePtr,
- sizeInBytes);
+ // handle the case where the registry contains an odd-byte length (corrupt data?)
+ try
+ {
+ datasize = checked(datasize + 1);
+ }
+ catch (OverflowException e)
+ {
+ throw new IOException(SR.Arg_RegGetOverflowBug, e);
}
- break;
}
+ char[] blob = new char[datasize / 2];
- case RegistryValueKind.None:
- case RegistryValueKind.Binary:
- byte[] dataBytes = (byte[]) value;
- ret = Win32Native.RegSetValueEx(hkey,
- name,
- 0,
- (valueKind == RegistryValueKind.None ? Win32Native.REG_NONE: RegistryValueKind.Binary),
- dataBytes,
- dataBytes.Length);
- break;
-
- case RegistryValueKind.DWord:
+ ret = Win32Native.RegQueryValueEx(hkey, name, null, ref type, blob, ref datasize);
+
+ // make sure the string is null terminated before processing the data
+ if (blob.Length > 0 && blob[blob.Length - 1] != (char)0)
{
- // We need to use Convert here because we could have a boxed type cannot be
- // unboxed and cast at the same time. I.e. ((int)(object)(short) 5) will fail.
- int data = Convert.ToInt32(value, System.Globalization.CultureInfo.InvariantCulture);
-
- ret = Win32Native.RegSetValueEx(hkey,
- name,
- 0,
- RegistryValueKind.DWord,
- ref data,
- 4);
- break;
+ try
+ {
+ char[] newBlob = new char[checked(blob.Length + 1)];
+ for (int i = 0; i < blob.Length; i++)
+ {
+ newBlob[i] = blob[i];
+ }
+ newBlob[newBlob.Length - 1] = (char)0;
+ blob = newBlob;
+ }
+ catch (OverflowException e)
+ {
+ throw new IOException(SR.Arg_RegGetOverflowBug, e);
+ }
+ blob[blob.Length - 1] = (char)0;
}
- case RegistryValueKind.QWord:
+ IList<string> strings = new List<string>();
+ int cur = 0;
+ int len = blob.Length;
+
+ while (ret == 0 && cur < len)
{
- long data = Convert.ToInt64(value, System.Globalization.CultureInfo.InvariantCulture);
-
- ret = Win32Native.RegSetValueEx(hkey,
- name,
- 0,
- RegistryValueKind.QWord,
- ref data,
- 8);
- break;
+ int nextNull = cur;
+ while (nextNull < len && blob[nextNull] != (char)0)
+ {
+ nextNull++;
+ }
+
+ if (nextNull < len)
+ {
+ Debug.Assert(blob[nextNull] == (char)0, "blob[nextNull] should be 0");
+ if (nextNull - cur > 0)
+ {
+ strings.Add(new string(blob, cur, nextNull - cur));
+ }
+ else
+ {
+ // we found an empty string. But if we're at the end of the data,
+ // it's just the extra null terminator.
+ if (nextNull != len - 1)
+ strings.Add(string.Empty);
+ }
+ }
+ else
+ {
+ strings.Add(new string(blob, cur, len - cur));
+ }
+ cur = nextNull + 1;
}
- }
- }
- catch (OverflowException) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind);
- }
- catch (InvalidOperationException) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind);
- }
- catch (FormatException) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind);
- }
- catch (InvalidCastException) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegSetMismatchedKind);
- }
- if (ret == 0) {
- SetDirty();
+ data = new string[strings.Count];
+ strings.CopyTo((string[])data, 0);
+ }
+ break;
+ case Win32Native.REG_LINK:
+ default:
+ break;
}
- else
- Win32Error(ret, null);
+ return data;
+ }
+
+ private bool IsSystemKey()
+ {
+ return (state & STATE_SYSTEMKEY) != 0;
}
- private RegistryValueKind CalculateValueKind(Object value) {
- // This logic matches what used to be in SetValue(string name, object value) in the v1.0 and v1.1 days.
- // Even though we could add detection for an int64 in here, we want to maintain compatibility with the
- // old behavior.
- if (value is Int32)
- return RegistryValueKind.DWord;
- else if (value is Array) {
- if (value is byte[])
- return RegistryValueKind.Binary;
- else if (value is String[])
- return RegistryValueKind.MultiString;
- else
- throw new ArgumentException(Environment.GetResourceString("Arg_RegSetBadArrType", value.GetType().Name));
+ private bool IsWritable()
+ {
+ return (state & STATE_WRITEACCESS) != 0;
+ }
+
+ private bool IsPerfDataKey()
+ {
+ return false;
+ }
+
+ public unsafe void SetStringValue(string name, string value)
+ {
+ if (value == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
+
+ if (name != null && name.Length > MaxValueLength)
+ {
+ throw new ArgumentException(SR.Arg_RegValStrLenBug);
}
- else
- return RegistryValueKind.String;
+
+ EnsureWriteable();
+
+ int result = Win32Native.RegSetValueEx(hkey,
+ name,
+ 0,
+ RegistryValueKind.String,
+ value,
+ checked(value.Length * 2 + 2));
+
+ if (result != 0)
+ Win32Error(result, null);
}
/**
@@ -932,7 +591,8 @@ namespace Microsoft.Win32
*
* @return a string representing the key.
*/
- public override String ToString() {
+ public override string ToString()
+ {
EnsureNotDisposed();
return keyName;
}
@@ -944,164 +604,51 @@ namespace Microsoft.Win32
* error, and depending on the error, insert a string into the message
* gotten from the ResourceManager.
*/
- internal void Win32Error(int errorCode, String str) {
- switch (errorCode) {
+ internal void Win32Error(int errorCode, string str)
+ {
+ switch (errorCode)
+ {
case Win32Native.ERROR_ACCESS_DENIED:
if (str != null)
- throw new UnauthorizedAccessException(Environment.GetResourceString("UnauthorizedAccess_RegistryKeyGeneric_Key", str));
+ throw new UnauthorizedAccessException(SR.Format(SR.UnauthorizedAccess_RegistryKeyGeneric_Key, str));
else
throw new UnauthorizedAccessException();
-
- case Win32Native.ERROR_INVALID_HANDLE:
- /**
- * For normal RegistryKey instances we dispose the SafeRegHandle and throw IOException.
- * However, for HKEY_PERFORMANCE_DATA (on a local or remote machine) we avoid disposing the
- * SafeRegHandle and only throw the IOException. This is to workaround reentrancy issues
- * in PerformanceCounter.NextValue() where the API could throw {NullReference, ObjectDisposed, ArgumentNull}Exception
- * on reentrant calls because of this error code path in RegistryKey
- *
- * Normally we'd make our caller synchronize access to a shared RegistryKey instead of doing something like this,
- * however we shipped PerformanceCounter.NextValue() un-synchronized in v2.0RTM and customers have taken a dependency on
- * this behavior (being able to simultaneously query multiple remote-machine counters on multiple threads, instead of
- * having serialized access).
- */
- if (!IsPerfDataKey()) {
- this.hkey.SetHandleAsInvalid();
- this.hkey = null;
- }
- goto default;
-
case Win32Native.ERROR_FILE_NOT_FOUND:
- throw new IOException(Environment.GetResourceString("Arg_RegKeyNotFound"), errorCode);
+ throw new IOException(SR.Arg_RegKeyNotFound, errorCode);
default:
throw new IOException(Win32Native.GetMessage(errorCode), errorCode);
}
}
- internal static String FixupName(String name)
- {
- BCLDebug.Assert(name!=null,"[FixupName]name!=null");
- if (name.IndexOf('\\') == -1)
- return name;
-
- StringBuilder sb = new StringBuilder(name);
- FixupPath(sb);
- int temp = sb.Length - 1;
- if (temp >= 0 && sb[temp] == '\\') // Remove trailing slash
- sb.Length = temp;
- return sb.ToString();
- }
-
-
- private static void FixupPath(StringBuilder path)
+ private void EnsureNotDisposed()
{
- Contract.Requires(path != null);
- int length = path.Length;
- bool fixup = false;
- char markerChar = (char)0xFFFF;
-
- int i = 1;
- while (i < length - 1)
- {
- if (path[i] == '\\')
- {
- i++;
- while (i < length)
- {
- if (path[i] == '\\')
- {
- path[i] = markerChar;
- i++;
- fixup = true;
- }
- else
- break;
- }
-
- }
- i++;
- }
-
- if (fixup)
+ if (hkey == null)
{
- i = 0;
- int j = 0;
- while (i < length)
- {
- if(path[i] == markerChar)
- {
- i++;
- continue;
- }
- path[j] = path[i];
- i++;
- j++;
- }
- path.Length += j - i;
- }
-
- }
-
- private void CheckPermission(RegistryInternalCheck check, string item, bool subKeyWritable, RegistryKeyPermissionCheck subKeyCheck)
- {
- // TODO: Cleanup
- }
-
- private bool ContainsRegistryValue(string name) {
- int type = 0;
- int datasize = 0;
- int retval = Win32Native.RegQueryValueEx(hkey, name, null, ref type, (byte[])null, ref datasize);
- return retval == 0;
- }
-
- private void EnsureNotDisposed(){
- if (hkey == null) {
ThrowHelper.ThrowObjectDisposedException(keyName, ExceptionResource.ObjectDisposed_RegKeyClosed);
}
}
- private void EnsureWriteable() {
+ private void EnsureWriteable()
+ {
EnsureNotDisposed();
- if (!IsWritable()) {
+ if (!IsWritable())
+ {
ThrowHelper.ThrowUnauthorizedAccessException(ExceptionResource.UnauthorizedAccess_RegistryNoWrite);
}
}
- static int GetRegistryKeyAccess(bool isWritable) {
- int winAccess;
- if (!isWritable) {
- winAccess = Win32Native.KEY_READ;
- }
- else {
- winAccess = Win32Native.KEY_READ | Win32Native.KEY_WRITE;
- }
-
- return winAccess;
- }
-
- private RegistryKeyPermissionCheck GetSubKeyPermissonCheck(bool subkeyWritable) {
- if( checkMode == RegistryKeyPermissionCheck.Default) {
- return checkMode;
- }
-
- if(subkeyWritable) {
- return RegistryKeyPermissionCheck.ReadWriteSubTree;
- }
- else {
- return RegistryKeyPermissionCheck.ReadSubTree;
- }
- }
-
- static private void ValidateKeyName(string name) {
- Contract.Ensures(name != null);
- if (name == null) {
+ static private void ValidateKeyName(string name)
+ {
+ if (name == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.name);
}
int nextSlash = name.IndexOf("\\", StringComparison.OrdinalIgnoreCase);
int current = 0;
- while (nextSlash != -1) {
+ while (nextSlash != -1)
+ {
if ((nextSlash - current) > MaxKeyLength)
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegKeyStrLenBug);
@@ -1111,32 +658,11 @@ namespace Microsoft.Win32
if ((name.Length - current) > MaxKeyLength)
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RegKeyStrLenBug);
-
- }
-
- static private void ValidateKeyView(RegistryView view) {
- if (view != RegistryView.Default && view != RegistryView.Registry32 && view != RegistryView.Registry64) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidRegistryViewCheck, ExceptionArgument.view);
- }
}
// Win32 constants for error handling
private const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
- private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
+ private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
private const int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000;
}
-
- [Flags]
- internal enum RegistryValueOptions {
- None = 0,
- DoNotExpandEnvironmentNames = 1
- }
-
- // the name for this API is meant to mimic FileMode, which has similar values
-
- internal enum RegistryKeyPermissionCheck {
- Default = 0,
- ReadSubTree = 1,
- ReadWriteSubTree = 2
- }
}
diff --git a/src/mscorlib/src/Microsoft/Win32/RegistryValueKind.cs b/src/mscorlib/src/Microsoft/Win32/RegistryValueKind.cs
index 5e22275332..90c880b278 100644
--- a/src/mscorlib/src/Microsoft/Win32/RegistryValueKind.cs
+++ b/src/mscorlib/src/Microsoft/Win32/RegistryValueKind.cs
@@ -2,17 +2,21 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+namespace Microsoft.Win32
+{
+ internal enum RegistryValueKind
+ {
+ String = Win32Native.REG_SZ,
+ ExpandString = Win32Native.REG_EXPAND_SZ,
+ Binary = Win32Native.REG_BINARY,
+ DWord = Win32Native.REG_DWORD,
+ MultiString = Win32Native.REG_MULTI_SZ,
+ QWord = Win32Native.REG_QWORD,
+ Unknown = 0,
-namespace Microsoft.Win32 {
- internal enum RegistryValueKind {
- String = Win32Native.REG_SZ,
- ExpandString = Win32Native.REG_EXPAND_SZ,
- Binary = Win32Native.REG_BINARY,
- DWord = Win32Native.REG_DWORD,
- MultiString = Win32Native.REG_MULTI_SZ,
- QWord = Win32Native.REG_QWORD,
- Unknown = 0, // REG_NONE is defined as zero but BCL
- None = unchecked((int)0xFFFFFFFF), // mistakingly overrode this value.
- } // Now instead of using Win32Native.REG_NONE we use "-1" and play games internally.
+ // REG_NONE is defined as zero but BCL, mistakingly overrode this value.
+ // Now instead of using Win32Native.REG_NONE we use "-1" and play games internally.
+ None = unchecked((int)0xFFFFFFFF),
+ }
}
diff --git a/src/mscorlib/src/Microsoft/Win32/RegistryView.cs b/src/mscorlib/src/Microsoft/Win32/RegistryView.cs
deleted file mode 100644
index 302a603e0c..0000000000
--- a/src/mscorlib/src/Microsoft/Win32/RegistryView.cs
+++ /dev/null
@@ -1,19 +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.
-
-//
-//
-//
-// Implements Microsoft.Win32.RegistryView
-//
-// ======================================================================================
-namespace Microsoft.Win32 {
- using System;
-
- internal enum RegistryView {
- Default = 0, // 0x0000 operate on the default registry view
- Registry64 = Win32Native.KEY_WOW64_64KEY, // 0x0100 operate on the 64-bit registry view
- Registry32 = Win32Native.KEY_WOW64_32KEY, // 0x0200 operate on the 32-bit registry view
- };
-}
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs
index 89ea22b855..d7d833d35d 100644
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs
+++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeFindHandle.cs
@@ -18,10 +18,11 @@ using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using Microsoft.Win32;
-namespace Microsoft.Win32.SafeHandles {
+namespace Microsoft.Win32.SafeHandles
+{
internal sealed class SafeFindHandle : SafeHandleZeroOrMinusOneIsInvalid
{
- internal SafeFindHandle() : base(true) {}
+ internal SafeFindHandle() : base(true) { }
override protected bool ReleaseHandle()
{
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLibraryHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLibraryHandle.cs
index 603558c51a..256f611463 100644
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLibraryHandle.cs
+++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeLibraryHandle.cs
@@ -2,11 +2,13 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace Microsoft.Win32 {
- using Microsoft.Win32.SafeHandles;
+using Microsoft.Win32.SafeHandles;
- sealed internal class SafeLibraryHandle : SafeHandleZeroOrMinusOneIsInvalid {
- internal SafeLibraryHandle() : base(true) {}
+namespace Microsoft.Win32
+{
+ sealed internal class SafeLibraryHandle : SafeHandleZeroOrMinusOneIsInvalid
+ {
+ internal SafeLibraryHandle() : base(true) { }
override protected bool ReleaseHandle()
{
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs
index a1e5bc4263..1215000ec5 100644
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs
+++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeRegistryHandle.cs
@@ -2,28 +2,23 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-//
-//
-//
-// Implements Microsoft.Win32.SafeHandles.SafeRegistryHandle
-//
-// ======================================================================================
-namespace Microsoft.Win32.SafeHandles {
- using System;
- using System.Security;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.Versioning;
+using System;
+using System.Security;
+using System.Runtime.InteropServices;
- internal sealed class SafeRegistryHandle : SafeHandleZeroOrMinusOneIsInvalid {
- internal SafeRegistryHandle() : base(true) {}
+namespace Microsoft.Win32.SafeHandles
+{
+ internal sealed class SafeRegistryHandle : SafeHandleZeroOrMinusOneIsInvalid
+ {
+ internal SafeRegistryHandle() : base(true) { }
- public SafeRegistryHandle(IntPtr preexistingHandle, bool ownsHandle) : base(ownsHandle) {
+ public SafeRegistryHandle(IntPtr preexistingHandle, bool ownsHandle) : base(ownsHandle)
+ {
SetHandle(preexistingHandle);
}
- override protected bool ReleaseHandle() {
+ override protected bool ReleaseHandle()
+ {
return (RegCloseKey(handle) == Win32Native.ERROR_SUCCESS);
}
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeWaitHandle.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeWaitHandle.cs
index 0ebcd5c09e..1141e6d027 100644
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeWaitHandle.cs
+++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/SafeWaitHandle.cs
@@ -21,8 +21,8 @@ using System.Runtime.Versioning;
using Microsoft.Win32;
using System.Threading;
-namespace Microsoft.Win32.SafeHandles {
-
+namespace Microsoft.Win32.SafeHandles
+{
public sealed class SafeWaitHandle : SafeHandleZeroOrMinusOneIsInvalid
{
// Called by P/Invoke marshaler
diff --git a/src/mscorlib/src/Microsoft/Win32/SafeHandles/Win32SafeHandles.cs b/src/mscorlib/src/Microsoft/Win32/SafeHandles/Win32SafeHandles.cs
index 62418131f3..8a7f591dfc 100644
--- a/src/mscorlib/src/Microsoft/Win32/SafeHandles/Win32SafeHandles.cs
+++ b/src/mscorlib/src/Microsoft/Win32/SafeHandles/Win32SafeHandles.cs
@@ -13,17 +13,17 @@
//
//
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+
namespace Microsoft.Win32.SafeHandles
{
- using System;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
-
// Class of safe handle which uses 0 or -1 as an invalid handle.
public abstract class SafeHandleZeroOrMinusOneIsInvalid : SafeHandle
{
- protected SafeHandleZeroOrMinusOneIsInvalid(bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ protected SafeHandleZeroOrMinusOneIsInvalid(bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
{
}
@@ -33,7 +33,8 @@ namespace Microsoft.Win32.SafeHandles
throw new NotImplementedException();
}
- public override bool IsInvalid {
+ public override bool IsInvalid
+ {
get { return handle.IsNull() || handle == new IntPtr(-1); }
}
}
@@ -41,7 +42,7 @@ namespace Microsoft.Win32.SafeHandles
// Class of safe handle which uses only -1 as an invalid handle.
public abstract class SafeHandleMinusOneIsInvalid : SafeHandle
{
- protected SafeHandleMinusOneIsInvalid(bool ownsHandle) : base(new IntPtr(-1), ownsHandle)
+ protected SafeHandleMinusOneIsInvalid(bool ownsHandle) : base(new IntPtr(-1), ownsHandle)
{
}
@@ -51,31 +52,8 @@ namespace Microsoft.Win32.SafeHandles
throw new NotImplementedException();
}
- public override bool IsInvalid {
- get { return handle == new IntPtr(-1); }
- }
- }
-
- // Class of critical handle which uses 0 or -1 as an invalid handle.
- public abstract class CriticalHandleZeroOrMinusOneIsInvalid : CriticalHandle
- {
- protected CriticalHandleZeroOrMinusOneIsInvalid() : base(IntPtr.Zero)
- {
- }
-
- public override bool IsInvalid {
- get { return handle.IsNull() || handle == new IntPtr(-1); }
- }
- }
-
- // Class of critical handle which uses only -1 as an invalid handle.
- public abstract class CriticalHandleMinusOneIsInvalid : CriticalHandle
- {
- protected CriticalHandleMinusOneIsInvalid() : base(new IntPtr(-1))
+ public override bool IsInvalid
{
- }
-
- public override bool IsInvalid {
get { return handle == new IntPtr(-1); }
}
}
diff --git a/src/mscorlib/src/Microsoft/Win32/UnsafeNativeMethods.cs b/src/mscorlib/src/Microsoft/Win32/UnsafeNativeMethods.cs
index 6e37b9c878..1b835d5dd1 100644
--- a/src/mscorlib/src/Microsoft/Win32/UnsafeNativeMethods.cs
+++ b/src/mscorlib/src/Microsoft/Win32/UnsafeNativeMethods.cs
@@ -2,7 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace Microsoft.Win32 {
+namespace Microsoft.Win32
+{
using Microsoft.Win32;
using Microsoft.Win32.SafeHandles;
using System;
@@ -16,12 +17,12 @@ namespace Microsoft.Win32 {
using System.Diagnostics.Tracing;
[SuppressUnmanagedCodeSecurityAttribute()]
- internal static class UnsafeNativeMethods {
-
- [DllImport(Win32Native.KERNEL32, EntryPoint="GetTimeZoneInformation", SetLastError = true, ExactSpelling = true)]
+ internal static class UnsafeNativeMethods
+ {
+ [DllImport(Win32Native.KERNEL32, EntryPoint = "GetTimeZoneInformation", SetLastError = true, ExactSpelling = true)]
internal static extern int GetTimeZoneInformation(out Win32Native.TimeZoneInformation lpTimeZoneInformation);
- [DllImport(Win32Native.KERNEL32, EntryPoint="GetDynamicTimeZoneInformation", SetLastError = true, ExactSpelling = true)]
+ [DllImport(Win32Native.KERNEL32, EntryPoint = "GetDynamicTimeZoneInformation", SetLastError = true, ExactSpelling = true)]
internal static extern int GetDynamicTimeZoneInformation(out Win32Native.DynamicTimeZoneInformation lpDynamicTimeZoneInformation);
//
@@ -35,7 +36,7 @@ namespace Microsoft.Win32 {
// PULONGLONG pululEnumerator
// );
//
- [DllImport(Win32Native.KERNEL32, EntryPoint="GetFileMUIPath", SetLastError = true, ExactSpelling = true)]
+ [DllImport(Win32Native.KERNEL32, EntryPoint = "GetFileMUIPath", SetLastError = true, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetFileMUIPath(
int flags,
@@ -50,13 +51,13 @@ namespace Microsoft.Win32 {
ref Int64 enumerator);
- [DllImport(Win32Native.USER32, EntryPoint="LoadStringW", SetLastError=true, CharSet=CharSet.Unicode, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
+ [DllImport(Win32Native.USER32, EntryPoint = "LoadStringW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
internal static extern int LoadString(SafeLibraryHandle handle, int id, [Out] StringBuilder buffer, int bufferLength);
- [DllImport(Win32Native.KERNEL32, CharSet=System.Runtime.InteropServices.CharSet.Unicode, SetLastError=true)]
- internal static extern SafeLibraryHandle LoadLibraryEx(string libFilename, IntPtr reserved, int flags);
-
- [DllImport(Win32Native.KERNEL32, CharSet=System.Runtime.InteropServices.CharSet.Unicode)]
+ [DllImport(Win32Native.KERNEL32, CharSet = System.Runtime.InteropServices.CharSet.Unicode, SetLastError = true)]
+ internal static extern SafeLibraryHandle LoadLibraryEx(string libFilename, IntPtr reserved, int flags);
+
+ [DllImport(Win32Native.KERNEL32, CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool FreeLibrary(IntPtr hModule);
@@ -245,14 +246,13 @@ namespace Microsoft.Win32 {
void* OutBuffer,
int OutBufferSize,
ref int ReturnLength);
-
}
#if FEATURE_COMINTEROP
[DllImport("combase.dll", PreserveSig = true)]
internal static extern int RoGetActivationFactory(
[MarshalAs(UnmanagedType.HString)] string activatableClassId,
[In] ref Guid iid,
- [Out,MarshalAs(UnmanagedType.IInspectable)] out Object factory);
+ [Out, MarshalAs(UnmanagedType.IInspectable)] out Object factory);
#endif
}
diff --git a/src/mscorlib/src/Microsoft/Win32/Win32Native.cs b/src/mscorlib/src/Microsoft/Win32/Win32Native.cs
index b081b16ca1..8543bc8a99 100644
--- a/src/mscorlib/src/Microsoft/Win32/Win32Native.cs
+++ b/src/mscorlib/src/Microsoft/Win32/Win32Native.cs
@@ -87,7 +87,8 @@
* in your DllImportAttribute.
*/
-namespace Microsoft.Win32 {
+namespace Microsoft.Win32
+{
using System;
using System.Security;
using System.Text;
@@ -103,7 +104,7 @@ namespace Microsoft.Win32 {
using BOOL = System.Int32;
using DWORD = System.UInt32;
using ULONG = System.UInt32;
-
+
/**
* Win32 encapsulation for MSCORLIB.
*/
@@ -111,49 +112,49 @@ namespace Microsoft.Win32 {
// global declaration on the class.
[SuppressUnmanagedCodeSecurityAttribute()]
- internal static class Win32Native {
-
- internal const int KEY_QUERY_VALUE = 0x0001;
- internal const int KEY_SET_VALUE = 0x0002;
- internal const int KEY_CREATE_SUB_KEY = 0x0004;
+ internal static class Win32Native
+ {
+ 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)
- &
+ 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)
- &
+
+ internal const int KEY_WRITE = ((STANDARD_RIGHTS_WRITE |
+ KEY_SET_VALUE |
+ KEY_CREATE_SUB_KEY)
+ &
(~SYNCHRONIZE));
- internal const int KEY_WOW64_64KEY = 0x0100; //
- internal const int KEY_WOW64_32KEY = 0x0200; //
- 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 KEY_WOW64_64KEY = 0x0100; //
+ internal const int KEY_WOW64_32KEY = 0x0200; //
+ 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 const int REG_NONE = 0; // No value type
- internal const int REG_SZ = 1; // Unicode nul terminated string
- internal const int REG_EXPAND_SZ = 2; // Unicode nul terminated string
+ internal const int REG_NONE = 0; // No value type
+ internal const int REG_SZ = 1; // Unicode nul terminated string
+ internal const int REG_EXPAND_SZ = 2; // Unicode nul terminated string
// (with environment variable references)
- internal const int REG_BINARY = 3; // Free form binary
- internal const int REG_DWORD = 4; // 32-bit number
- internal const int REG_DWORD_LITTLE_ENDIAN = 4; // 32-bit number (same as REG_DWORD)
- internal const int REG_DWORD_BIG_ENDIAN = 5; // 32-bit number
- internal const int REG_LINK = 6; // Symbolic Link (unicode)
- internal const int REG_MULTI_SZ = 7; // Multiple Unicode strings
- internal const int REG_RESOURCE_LIST = 8; // Resource list in the resource map
- internal const int REG_FULL_RESOURCE_DESCRIPTOR = 9; // Resource list in the hardware description
- internal const int REG_RESOURCE_REQUIREMENTS_LIST = 10;
- internal const int REG_QWORD = 11; // 64-bit number
-
- internal const int HWND_BROADCAST = 0xffff;
- internal const int WM_SETTINGCHANGE = 0x001A;
+ internal const int REG_BINARY = 3; // Free form binary
+ internal const int REG_DWORD = 4; // 32-bit number
+ internal const int REG_DWORD_LITTLE_ENDIAN = 4; // 32-bit number (same as REG_DWORD)
+ internal const int REG_DWORD_BIG_ENDIAN = 5; // 32-bit number
+ internal const int REG_LINK = 6; // Symbolic Link (unicode)
+ internal const int REG_MULTI_SZ = 7; // Multiple Unicode strings
+ internal const int REG_RESOURCE_LIST = 8; // Resource list in the resource map
+ internal const int REG_FULL_RESOURCE_DESCRIPTOR = 9; // Resource list in the hardware description
+ internal const int REG_RESOURCE_REQUIREMENTS_LIST = 10;
+ internal const int REG_QWORD = 11; // 64-bit number
+
+ internal const int HWND_BROADCAST = 0xffff;
+ internal const int WM_SETTINGCHANGE = 0x001A;
// TimeZone
internal const int TIME_ZONE_ID_INVALID = -1;
@@ -174,7 +175,8 @@ namespace Microsoft.Win32 {
internal const int LOAD_STRING_MAX_LENGTH = 500;
[StructLayout(LayoutKind.Sequential)]
- internal struct SystemTime {
+ internal struct SystemTime
+ {
[MarshalAs(UnmanagedType.U2)]
public short Year;
[MarshalAs(UnmanagedType.U2)]
@@ -194,7 +196,8 @@ namespace Microsoft.Win32 {
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- internal struct TimeZoneInformation {
+ internal struct TimeZoneInformation
+ {
[MarshalAs(UnmanagedType.I4)]
public Int32 Bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
@@ -208,7 +211,8 @@ namespace Microsoft.Win32 {
[MarshalAs(UnmanagedType.I4)]
public Int32 DaylightBias;
- public TimeZoneInformation(Win32Native.DynamicTimeZoneInformation dtzi) {
+ public TimeZoneInformation(Win32Native.DynamicTimeZoneInformation dtzi)
+ {
Bias = dtzi.Bias;
StandardName = dtzi.StandardName;
StandardDate = dtzi.StandardDate;
@@ -221,7 +225,8 @@ namespace Microsoft.Win32 {
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- internal struct DynamicTimeZoneInformation {
+ internal struct DynamicTimeZoneInformation
+ {
[MarshalAs(UnmanagedType.I4)]
public Int32 Bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
@@ -242,7 +247,8 @@ namespace Microsoft.Win32 {
[StructLayout(LayoutKind.Sequential)]
- internal struct RegistryTimeZoneInformation {
+ internal struct RegistryTimeZoneInformation
+ {
[MarshalAs(UnmanagedType.I4)]
public Int32 Bias;
[MarshalAs(UnmanagedType.I4)]
@@ -252,7 +258,8 @@ namespace Microsoft.Win32 {
public SystemTime StandardDate;
public SystemTime DaylightDate;
- public RegistryTimeZoneInformation(Win32Native.TimeZoneInformation tzi) {
+ public RegistryTimeZoneInformation(Win32Native.TimeZoneInformation tzi)
+ {
Bias = tzi.Bias;
StandardDate = tzi.StandardDate;
StandardBias = tzi.StandardBias;
@@ -260,7 +267,8 @@ namespace Microsoft.Win32 {
DaylightBias = tzi.DaylightBias;
}
- public RegistryTimeZoneInformation(Byte[] bytes) {
+ public RegistryTimeZoneInformation(Byte[] bytes)
+ {
//
// typedef struct _REG_TZI_FORMAT {
// [00-03] LONG Bias;
@@ -286,8 +294,9 @@ namespace Microsoft.Win32 {
// [42-43] WORD wMilliseconds;
// } REG_TZI_FORMAT;
//
- if (bytes == null || bytes.Length != 44) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidREG_TZI_FORMAT"), nameof(bytes));
+ if (bytes == null || bytes.Length != 44)
+ {
+ throw new ArgumentException(SR.Argument_InvalidREG_TZI_FORMAT, nameof(bytes));
}
Bias = BitConverter.ToInt32(bytes, 0);
StandardBias = BitConverter.ToInt32(bytes, 4);
@@ -317,12 +326,12 @@ namespace Microsoft.Win32 {
// Win32 ACL-related constants:
- internal const int READ_CONTROL = 0x00020000;
- internal const int SYNCHRONIZE = 0x00100000;
+ internal const int READ_CONTROL = 0x00020000;
+ internal const int SYNCHRONIZE = 0x00100000;
+
+ internal const int STANDARD_RIGHTS_READ = READ_CONTROL;
+ internal const int STANDARD_RIGHTS_WRITE = READ_CONTROL;
- internal const int STANDARD_RIGHTS_READ = READ_CONTROL;
- internal const int STANDARD_RIGHTS_WRITE = READ_CONTROL;
-
// STANDARD_RIGHTS_REQUIRED (0x000F0000L)
// SEMAPHORE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3)
@@ -332,18 +341,20 @@ namespace Microsoft.Win32 {
// Note that you may need to specify the SYNCHRONIZE bit as well
// to be able to open a synchronization primitive.
internal const int SEMAPHORE_MODIFY_STATE = 0x00000002;
- internal const int EVENT_MODIFY_STATE = 0x00000002;
- internal const int MUTEX_MODIFY_STATE = 0x00000001;
- internal const int MUTEX_ALL_ACCESS = 0x001F0001;
+ internal const int EVENT_MODIFY_STATE = 0x00000002;
+ internal const int MUTEX_MODIFY_STATE = 0x00000001;
+ internal const int MUTEX_ALL_ACCESS = 0x001F0001;
- internal const int LMEM_FIXED = 0x0000;
+ internal const int LMEM_FIXED = 0x0000;
internal const int LMEM_ZEROINIT = 0x0040;
- internal const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT);
+ internal const int LPTR = (LMEM_FIXED | LMEM_ZEROINIT);
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
- internal class OSVERSIONINFO {
- internal OSVERSIONINFO() {
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ internal class OSVERSIONINFO
+ {
+ internal OSVERSIONINFO()
+ {
OSVersionInfoSize = (int)Marshal.SizeOf(this);
}
@@ -353,14 +364,15 @@ namespace Microsoft.Win32 {
internal int MinorVersion = 0;
internal int BuildNumber = 0;
internal int PlatformId = 0;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
internal String CSDVersion = null;
}
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
- internal class OSVERSIONINFOEX {
-
- public OSVERSIONINFOEX() {
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ internal class OSVERSIONINFOEX
+ {
+ public OSVERSIONINFOEX()
+ {
OSVersionInfoSize = (int)Marshal.SizeOf(this);
}
@@ -370,26 +382,28 @@ namespace Microsoft.Win32 {
internal int MinorVersion = 0;
internal int BuildNumber = 0;
internal int PlatformId = 0;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
internal string CSDVersion = null;
internal ushort ServicePackMajor = 0;
internal ushort ServicePackMinor = 0;
internal short SuiteMask = 0;
internal byte ProductType = 0;
- internal byte Reserved = 0;
+ internal byte Reserved = 0;
}
[StructLayout(LayoutKind.Sequential)]
- internal class SECURITY_ATTRIBUTES {
+ internal class SECURITY_ATTRIBUTES
+ {
internal int nLength = 0;
// don't remove null, or this field will disappear in bcl.small
- internal unsafe byte * pSecurityDescriptor = null;
+ internal unsafe byte* pSecurityDescriptor = null;
internal int bInheritHandle = 0;
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
- internal struct WIN32_FILE_ATTRIBUTE_DATA {
+ internal struct WIN32_FILE_ATTRIBUTE_DATA
+ {
internal int fileAttributes;
internal uint ftCreationTimeLow;
internal uint ftCreationTimeHigh;
@@ -400,22 +414,24 @@ namespace Microsoft.Win32 {
internal int fileSizeHigh;
internal int fileSizeLow;
- internal void PopulateFrom(WIN32_FIND_DATA findData) {
+ internal void PopulateFrom(WIN32_FIND_DATA findData)
+ {
// Copy the information to data
- fileAttributes = findData.dwFileAttributes;
- ftCreationTimeLow = findData.ftCreationTime_dwLowDateTime;
- ftCreationTimeHigh = findData.ftCreationTime_dwHighDateTime;
- ftLastAccessTimeLow = findData.ftLastAccessTime_dwLowDateTime;
- ftLastAccessTimeHigh = findData.ftLastAccessTime_dwHighDateTime;
- ftLastWriteTimeLow = findData.ftLastWriteTime_dwLowDateTime;
- ftLastWriteTimeHigh = findData.ftLastWriteTime_dwHighDateTime;
- fileSizeHigh = findData.nFileSizeHigh;
- fileSizeLow = findData.nFileSizeLow;
+ fileAttributes = findData.dwFileAttributes;
+ ftCreationTimeLow = findData.ftCreationTime_dwLowDateTime;
+ ftCreationTimeHigh = findData.ftCreationTime_dwHighDateTime;
+ ftLastAccessTimeLow = findData.ftLastAccessTime_dwLowDateTime;
+ ftLastAccessTimeHigh = findData.ftLastAccessTime_dwHighDateTime;
+ ftLastWriteTimeLow = findData.ftLastWriteTime_dwLowDateTime;
+ ftLastWriteTimeHigh = findData.ftLastWriteTime_dwHighDateTime;
+ fileSizeHigh = findData.nFileSizeHigh;
+ fileSizeLow = findData.nFileSizeLow;
}
}
[StructLayout(LayoutKind.Sequential)]
- internal struct MEMORYSTATUSEX {
+ internal struct MEMORYSTATUSEX
+ {
// The length field must be set to the size of this data structure.
internal int length;
internal int memoryLoad;
@@ -429,7 +445,8 @@ namespace Microsoft.Win32 {
}
[StructLayout(LayoutKind.Sequential)]
- internal unsafe struct MEMORY_BASIC_INFORMATION {
+ internal unsafe struct MEMORY_BASIC_INFORMATION
+ {
internal void* BaseAddress;
internal void* AllocationBase;
internal uint AllocationProtect;
@@ -441,10 +458,10 @@ namespace Microsoft.Win32 {
#if !FEATURE_PAL
internal const String KERNEL32 = "kernel32.dll";
- internal const String USER32 = "user32.dll";
- internal const String OLE32 = "ole32.dll";
+ internal const String USER32 = "user32.dll";
+ internal const String OLE32 = "ole32.dll";
internal const String OLEAUT32 = "oleaut32.dll";
- internal const String NTDLL = "ntdll.dll";
+ internal const String NTDLL = "ntdll.dll";
#else //FEATURE_PAL
internal const String KERNEL32 = "libcoreclr";
internal const String USER32 = "libcoreclr";
@@ -453,40 +470,43 @@ namespace Microsoft.Win32 {
internal const String NTDLL = "libcoreclr";
#endif //FEATURE_PAL
internal const String ADVAPI32 = "advapi32.dll";
- internal const String SHELL32 = "shell32.dll";
- internal const String SHIM = "mscoree.dll";
- internal const String CRYPT32 = "crypt32.dll";
- internal const String SECUR32 = "secur32.dll";
+ internal const String SHELL32 = "shell32.dll";
+ internal const String SHIM = "mscoree.dll";
+ internal const String CRYPT32 = "crypt32.dll";
+ internal const String SECUR32 = "secur32.dll";
internal const String MSCORWKS = "coreclr.dll";
// From WinBase.h
internal const int SEM_FAILCRITICALERRORS = 1;
- [DllImport(KERNEL32, CharSet=CharSet.Auto, BestFitMapping=true)]
+ [DllImport(KERNEL32, CharSet = CharSet.Auto, BestFitMapping = true)]
internal static extern int FormatMessage(int dwFlags, IntPtr lpSource,
int dwMessageId, int dwLanguageId, [Out]StringBuilder lpBuffer,
int nSize, IntPtr va_list_arguments);
// Gets an error message for a Win32 error code.
- internal static String GetMessage(int errorCode) {
+ internal static String GetMessage(int errorCode)
+ {
StringBuilder sb = StringBuilderCache.Acquire(512);
int result = Win32Native.FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
IntPtr.Zero, errorCode, 0, sb, sb.Capacity, IntPtr.Zero);
- if (result != 0) {
+ if (result != 0)
+ {
// result is the # of characters copied to the StringBuilder.
return StringBuilderCache.GetStringAndRelease(sb);
}
- else {
+ else
+ {
StringBuilderCache.Release(sb);
- return Environment.GetResourceString("UnknownError_Num", errorCode);
+ return SR.Format(SR.UnknownError_Num, errorCode);
}
}
- [DllImport(KERNEL32, EntryPoint="LocalAlloc")]
+ [DllImport(KERNEL32, EntryPoint = "LocalAlloc")]
internal static extern IntPtr LocalAlloc_NoSafeHandle(int uFlags, UIntPtr sizetdwBytes);
- [DllImport(KERNEL32, SetLastError=true)]
+ [DllImport(KERNEL32, SetLastError = true)]
internal static extern IntPtr LocalFree(IntPtr handle);
// MSDN says the length is a SIZE_T.
@@ -499,25 +519,25 @@ namespace Microsoft.Win32 {
return GlobalMemoryStatusExNative(ref buffer);
}
- [DllImport(KERNEL32, SetLastError=true, EntryPoint="GlobalMemoryStatusEx")]
+ [DllImport(KERNEL32, SetLastError = true, EntryPoint = "GlobalMemoryStatusEx")]
private static extern bool GlobalMemoryStatusExNative([In, Out] ref MEMORYSTATUSEX buffer);
- [DllImport(KERNEL32, SetLastError=true)]
+ [DllImport(KERNEL32, SetLastError = true)]
unsafe internal static extern UIntPtr VirtualQuery(void* address, ref MEMORY_BASIC_INFORMATION buffer, UIntPtr sizeOfBuffer);
// VirtualAlloc should generally be avoided, but is needed in
// the MemoryFailPoint implementation (within a CER) to increase the
// size of the page file, ignoring any host memory allocators.
- [DllImport(KERNEL32, SetLastError=true)]
- unsafe internal static extern void * VirtualAlloc(void* address, UIntPtr numBytes, int commitOrReserve, int pageProtectionMode);
+ [DllImport(KERNEL32, SetLastError = true)]
+ unsafe internal static extern void* VirtualAlloc(void* address, UIntPtr numBytes, int commitOrReserve, int pageProtectionMode);
- [DllImport(KERNEL32, SetLastError=true)]
+ [DllImport(KERNEL32, SetLastError = true)]
unsafe internal static extern bool VirtualFree(void* address, UIntPtr numBytes, int pageFreeMode);
- [DllImport(KERNEL32, CharSet=CharSet.Ansi, ExactSpelling=true, EntryPoint="lstrlenA")]
+ [DllImport(KERNEL32, CharSet = CharSet.Ansi, ExactSpelling = true, EntryPoint = "lstrlenA")]
internal static extern int lstrlenA(IntPtr ptr);
- [DllImport(KERNEL32, CharSet=CharSet.Unicode, ExactSpelling=true, EntryPoint="lstrlenW")]
+ [DllImport(KERNEL32, CharSet = CharSet.Unicode, ExactSpelling = true, EntryPoint = "lstrlenW")]
internal static extern int lstrlenW(IntPtr ptr);
[DllImport(Win32Native.OLEAUT32, CharSet = CharSet.Unicode)]
@@ -538,31 +558,31 @@ namespace Microsoft.Win32 {
#endif
- [DllImport(KERNEL32, SetLastError=true)]
+ [DllImport(KERNEL32, SetLastError = true)]
internal static extern bool SetEvent(SafeWaitHandle handle);
- [DllImport(KERNEL32, SetLastError=true)]
+ [DllImport(KERNEL32, SetLastError = true)]
internal static extern bool ResetEvent(SafeWaitHandle handle);
- [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)]
+ [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern SafeWaitHandle CreateEvent(SECURITY_ATTRIBUTES lpSecurityAttributes, bool isManualReset, bool initialState, String name);
- [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)]
+ [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern SafeWaitHandle OpenEvent(/* DWORD */ int desiredAccess, bool inheritHandle, String name);
- [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)]
+ [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern SafeWaitHandle CreateMutex(SECURITY_ATTRIBUTES lpSecurityAttributes, bool initialOwner, String name);
- [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)]
+ [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern SafeWaitHandle OpenMutex(/* DWORD */ int desiredAccess, bool inheritHandle, String name);
-
- [DllImport(KERNEL32, SetLastError=true)]
+
+ [DllImport(KERNEL32, SetLastError = true)]
internal static extern bool ReleaseMutex(SafeWaitHandle handle);
- [DllImport(KERNEL32, SetLastError=true)]
+ [DllImport(KERNEL32, SetLastError = true)]
internal static extern bool CloseHandle(IntPtr handle);
- [DllImport(KERNEL32, SetLastError=true)]
+ [DllImport(KERNEL32, SetLastError = true)]
internal static unsafe extern int WriteFile(SafeFileHandle handle, byte* bytes, int numBytesToWrite, out int numBytesWritten, IntPtr mustBeZero);
[DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
@@ -576,13 +596,13 @@ namespace Microsoft.Win32 {
internal static extern SafeWaitHandle OpenSemaphore(/* DWORD */ int desiredAccess, bool inheritHandle, String name);
// Will be in winnls.h
- internal const int FIND_STARTSWITH = 0x00100000; // see if value is at the beginning of source
- internal const int FIND_ENDSWITH = 0x00200000; // see if value is at the end of source
- internal const int FIND_FROMSTART = 0x00400000; // look for value in source, starting at the beginning
- internal const int FIND_FROMEND = 0x00800000; // look for value in source, starting at the end
+ internal const int FIND_STARTSWITH = 0x00100000; // see if value is at the beginning of source
+ internal const int FIND_ENDSWITH = 0x00200000; // see if value is at the end of source
+ internal const int FIND_FROMSTART = 0x00400000; // look for value in source, starting at the beginning
+ internal const int FIND_FROMEND = 0x00800000; // look for value in source, starting at the end
[StructLayout(LayoutKind.Sequential)]
- internal struct NlsVersionInfoEx
+ internal struct NlsVersionInfoEx
{
internal int dwNLSVersionInfoSize;
internal int dwNLSVersion;
@@ -591,7 +611,7 @@ namespace Microsoft.Win32 {
internal Guid guidCustomVersion;
}
- [DllImport(KERNEL32, CharSet=CharSet.Auto, SetLastError=true, BestFitMapping=false)]
+ [DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)]
internal static extern int GetSystemDirectory([Out]StringBuilder sb, int length);
internal static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1); // WinBase.h
@@ -601,7 +621,7 @@ namespace Microsoft.Win32 {
internal const int STD_OUTPUT_HANDLE = -11;
internal const int STD_ERROR_HANDLE = -12;
- [DllImport(KERNEL32, SetLastError=true)]
+ [DllImport(KERNEL32, SetLastError = true)]
internal static extern IntPtr GetStdHandle(int nStdHandle); // param is NOT a handle, but it returns one!
// From wincon.h
@@ -621,32 +641,32 @@ namespace Microsoft.Win32 {
internal const int REPLACEFILE_IGNORE_MERGE_ERRORS = 0x2;
private const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
- private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
+ private const int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
private const int FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000;
internal const uint FILE_MAP_WRITE = 0x0002;
internal const uint FILE_MAP_READ = 0x0004;
// Constants from WinNT.h
- internal const int FILE_ATTRIBUTE_READONLY = 0x00000001;
- internal const int FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
+ internal const int FILE_ATTRIBUTE_READONLY = 0x00000001;
+ internal const int FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
internal const int FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400;
internal const int IO_REPARSE_TAG_MOUNT_POINT = unchecked((int)0xA0000003);
internal const int PAGE_READWRITE = 0x04;
- internal const int MEM_COMMIT = 0x1000;
- internal const int MEM_RESERVE = 0x2000;
- internal const int MEM_RELEASE = 0x8000;
- internal const int MEM_FREE = 0x10000;
+ internal const int MEM_COMMIT = 0x1000;
+ internal const int MEM_RESERVE = 0x2000;
+ internal const int MEM_RELEASE = 0x8000;
+ internal const int MEM_FREE = 0x10000;
// Error codes from WinError.h
internal const int ERROR_SUCCESS = 0x0;
internal const int ERROR_INVALID_FUNCTION = 0x1;
internal const int ERROR_FILE_NOT_FOUND = 0x2;
internal const int ERROR_PATH_NOT_FOUND = 0x3;
- internal const int ERROR_ACCESS_DENIED = 0x5;
+ internal const int ERROR_ACCESS_DENIED = 0x5;
internal const int ERROR_INVALID_HANDLE = 0x6;
internal const int ERROR_NOT_ENOUGH_MEMORY = 0x8;
internal const int ERROR_INVALID_DATA = 0xd;
@@ -699,10 +719,10 @@ namespace Microsoft.Win32 {
internal const uint STATUS_INSUFFICIENT_RESOURCES = 0xC000009A;
internal const uint STATUS_ACCESS_DENIED = 0xC0000022;
- internal const int INVALID_FILE_SIZE = -1;
+ internal const int INVALID_FILE_SIZE = -1;
// From WinStatus.h
- internal const int STATUS_ACCOUNT_RESTRICTION = unchecked((int) 0xC000006E);
+ internal const int STATUS_ACCOUNT_RESTRICTION = unchecked((int)0xC000006E);
// Use this to translate error codes like the above into HRESULTs like
// 0x80070006 for ERROR_INVALID_HANDLE
@@ -714,12 +734,13 @@ namespace Microsoft.Win32 {
// Win32 Structs in N/Direct style
[Serializable]
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
[BestFitMapping(false)]
- internal class WIN32_FIND_DATA {
- internal int dwFileAttributes = 0;
+ internal class WIN32_FIND_DATA
+ {
+ internal int dwFileAttributes = 0;
// ftCreationTime was a by-value FILETIME structure
- internal uint ftCreationTime_dwLowDateTime = 0 ;
+ internal uint ftCreationTime_dwLowDateTime = 0;
internal uint ftCreationTime_dwHighDateTime = 0;
// ftLastAccessTime was a by-value FILETIME structure
internal uint ftLastAccessTime_dwLowDateTime = 0;
@@ -727,24 +748,24 @@ namespace Microsoft.Win32 {
// ftLastWriteTime was a by-value FILETIME structure
internal uint ftLastWriteTime_dwLowDateTime = 0;
internal uint ftLastWriteTime_dwHighDateTime = 0;
- internal int nFileSizeHigh = 0;
- internal int nFileSizeLow = 0;
+ internal int nFileSizeHigh = 0;
+ internal int nFileSizeLow = 0;
// If the file attributes' reparse point flag is set, then
// dwReserved0 is the file tag (aka reparse tag) for the
// reparse point. Use this to figure out whether something is
// a volume mount point or a symbolic link.
- internal int dwReserved0 = 0;
- internal int dwReserved1 = 0;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
- internal String cFileName = null;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst=14)]
- internal String cAlternateFileName = null;
+ internal int dwReserved0 = 0;
+ internal int dwReserved1 = 0;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
+ internal String cFileName = null;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
+ internal String cAlternateFileName = null;
}
- [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)]
+ [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern SafeFindHandle FindFirstFile(String fileName, [In, Out] Win32Native.WIN32_FIND_DATA data);
- [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)]
+ [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern bool FindNextFile(
SafeFindHandle hndFindFile,
[In, Out, MarshalAs(UnmanagedType.LPStruct)]
@@ -756,13 +777,13 @@ namespace Microsoft.Win32 {
[DllImport(KERNEL32, SetLastError = true, ExactSpelling = true)]
internal static extern uint GetCurrentDirectoryW(uint nBufferLength, char[] lpBuffer);
- [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)]
+ [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern bool GetFileAttributesEx(String name, int fileInfoLevel, ref WIN32_FILE_ATTRIBUTE_DATA lpFileInformation);
- [DllImport(KERNEL32, SetLastError=true, CharSet=CharSet.Auto, BestFitMapping=false)]
+ [DllImport(KERNEL32, SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern bool SetCurrentDirectory(String path);
- [DllImport(KERNEL32, SetLastError=false, EntryPoint="SetErrorMode", ExactSpelling=true)]
+ [DllImport(KERNEL32, SetLastError = false, EntryPoint = "SetErrorMode", ExactSpelling = true)]
private static extern int SetErrorMode_VistaAndOlder(int newMode);
// RTM versions of Win7 and Windows Server 2008 R2
@@ -779,24 +800,21 @@ namespace Microsoft.Win32 {
[DllImport(KERNEL32)]
internal static extern unsafe int WideCharToMultiByte(uint cp, uint flags, char* pwzSource, int cchSource, byte* pbDestBuffer, int cbDestBuffer, IntPtr null1, IntPtr null2);
- [DllImport(KERNEL32, CharSet=CharSet.Auto, SetLastError=true, BestFitMapping=false)]
+ [DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)]
internal static extern bool SetEnvironmentVariable(string lpName, string lpValue);
-
- [DllImport(KERNEL32, CharSet=CharSet.Auto, SetLastError=true, BestFitMapping=false)]
+
+ [DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)]
internal static extern int GetEnvironmentVariable(string lpName, [Out]StringBuilder lpValue, int size);
- [DllImport(KERNEL32, CharSet=CharSet.Unicode)]
- internal static unsafe extern char * GetEnvironmentStrings();
+ [DllImport(KERNEL32, CharSet = CharSet.Unicode)]
+ internal static unsafe extern char* GetEnvironmentStrings();
- [DllImport(KERNEL32, CharSet=CharSet.Unicode)]
- internal static unsafe extern bool FreeEnvironmentStrings(char * pStrings);
+ [DllImport(KERNEL32, CharSet = CharSet.Unicode)]
+ internal static unsafe extern bool FreeEnvironmentStrings(char* pStrings);
- [DllImport(KERNEL32, CharSet=CharSet.Auto, SetLastError=true)]
+ [DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true)]
internal static extern uint GetCurrentProcessId();
- [DllImport(KERNEL32, CharSet=CharSet.Auto, BestFitMapping=false)]
- internal extern static int GetComputerName([Out]StringBuilder nameBuffer, ref int bufferSize);
-
[DllImport(OLE32)]
internal extern static int CoCreateGuid(out Guid guid);
@@ -810,148 +828,150 @@ namespace Microsoft.Win32 {
internal static extern IntPtr CoTaskMemRealloc(IntPtr pv, UIntPtr cb);
#if FEATURE_WIN32_REGISTRY
-
- [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)]
+
+ [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern int RegDeleteValue(SafeRegistryHandle hKey, String lpValueName);
-
- [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)]
+
+ [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
internal unsafe static extern int RegEnumKeyEx(SafeRegistryHandle hKey, int dwIndex,
- char *lpName, ref int lpcbName, int[] lpReserved,
+ char[] lpName, ref int lpcbName, int[] lpReserved,
[Out]StringBuilder lpClass, int[] lpcbClass,
long[] lpftLastWriteTime);
-
- [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)]
+
+ [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
internal unsafe static extern int RegEnumValue(SafeRegistryHandle hKey, int dwIndex,
- char *lpValueName, ref int lpcbValueName,
+ char[] lpValueName, ref int lpcbValueName,
IntPtr lpReserved_MustBeZero, int[] lpType, byte[] lpData,
int[] lpcbData);
-
- [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)]
+
+ [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern int RegOpenKeyEx(SafeRegistryHandle hKey, String lpSubKey,
int ulOptions, int samDesired, out SafeRegistryHandle hkResult);
-
- [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)]
+
+ [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern int RegQueryInfoKey(SafeRegistryHandle hKey, [Out]StringBuilder lpClass,
int[] lpcbClass, IntPtr lpReserved_MustBeZero, ref int lpcSubKeys,
int[] lpcbMaxSubKeyLen, int[] lpcbMaxClassLen,
ref int lpcValues, int[] lpcbMaxValueNameLen,
int[] lpcbMaxValueLen, int[] lpcbSecurityDescriptor,
int[] lpftLastWriteTime);
-
- [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)]
+
+ [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName,
int[] lpReserved, ref int lpType, [Out] byte[] lpData,
ref int lpcbData);
- [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)]
+ [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName,
int[] lpReserved, ref int lpType, ref int lpData,
ref int lpcbData);
-
- [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)]
+
+ [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName,
int[] lpReserved, ref int lpType, ref long lpData,
ref int lpcbData);
-
- [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)]
+
+ [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern int RegQueryValueEx(SafeRegistryHandle hKey, String lpValueName,
- int[] lpReserved, ref int lpType, [Out] char[] lpData,
+ int[] lpReserved, ref int lpType, [Out] char[] lpData,
ref int lpcbData);
-
- [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)]
+
+ [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern int RegSetValueEx(SafeRegistryHandle hKey, String lpValueName,
int Reserved, RegistryValueKind dwType, byte[] lpData, int cbData);
-
- [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)]
+
+ [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern int RegSetValueEx(SafeRegistryHandle hKey, String lpValueName,
int Reserved, RegistryValueKind dwType, ref int lpData, int cbData);
-
- [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)]
+
+ [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern int RegSetValueEx(SafeRegistryHandle hKey, String lpValueName,
int Reserved, RegistryValueKind dwType, ref long lpData, int cbData);
-
- [DllImport(ADVAPI32, CharSet=CharSet.Auto, BestFitMapping=false)]
+
+ [DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
internal static extern int RegSetValueEx(SafeRegistryHandle hKey, String lpValueName,
int Reserved, RegistryValueKind dwType, String lpData, int cbData);
#endif // FEATURE_WIN32_REGISTRY
-
- [DllImport(KERNEL32, CharSet=CharSet.Auto, SetLastError=true, BestFitMapping=false)]
+
+ [DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)]
internal static extern int ExpandEnvironmentStrings(String lpSrc, [Out]StringBuilder lpDst, int nSize);
[DllImport(KERNEL32)]
internal static extern IntPtr LocalReAlloc(IntPtr handle, IntPtr sizetcbBytes, int uFlags);
- internal const int SHGFP_TYPE_CURRENT = 0; // the current (user) folder path setting
- internal const int UOI_FLAGS = 1;
- internal const int WSF_VISIBLE = 1;
+ internal const int SHGFP_TYPE_CURRENT = 0; // the current (user) folder path setting
+ internal const int UOI_FLAGS = 1;
+ internal const int WSF_VISIBLE = 1;
// .NET Framework 4.0 and newer - all versions of windows ||| \public\sdk\inc\shlobj.h
- internal const int CSIDL_FLAG_CREATE = 0x8000; // force folder creation in SHGetFolderPath
- internal const int CSIDL_FLAG_DONT_VERIFY = 0x4000; // return an unverified folder path
- internal const int CSIDL_ADMINTOOLS = 0x0030; // <user name>\Start Menu\Programs\Administrative Tools
- internal const int CSIDL_CDBURN_AREA = 0x003b; // USERPROFILE\Local Settings\Application Data\Microsoft\CD Burning
- internal const int CSIDL_COMMON_ADMINTOOLS = 0x002f; // All Users\Start Menu\Programs\Administrative Tools
- internal const int CSIDL_COMMON_DOCUMENTS = 0x002e; // All Users\Documents
- internal const int CSIDL_COMMON_MUSIC = 0x0035; // All Users\My Music
- internal const int CSIDL_COMMON_OEM_LINKS = 0x003a; // Links to All Users OEM specific apps
- internal const int CSIDL_COMMON_PICTURES = 0x0036; // All Users\My Pictures
- internal const int CSIDL_COMMON_STARTMENU = 0x0016; // All Users\Start Menu
- internal const int CSIDL_COMMON_PROGRAMS = 0X0017; // All Users\Start Menu\Programs
- internal const int CSIDL_COMMON_STARTUP = 0x0018; // All Users\Startup
- internal const int CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019; // All Users\Desktop
- internal const int CSIDL_COMMON_TEMPLATES = 0x002d; // All Users\Templates
- internal const int CSIDL_COMMON_VIDEO = 0x0037; // All Users\My Video
- internal const int CSIDL_FONTS = 0x0014; // windows\fonts
- internal const int CSIDL_MYVIDEO = 0x000e; // "My Videos" folder
- internal const int CSIDL_NETHOOD = 0x0013; // %APPDATA%\Microsoft\Windows\Network Shortcuts
- internal const int CSIDL_PRINTHOOD = 0x001b; // %APPDATA%\Microsoft\Windows\Printer Shortcuts
- internal const int CSIDL_PROFILE = 0x0028; // %USERPROFILE% (%SystemDrive%\Users\%USERNAME%)
- internal const int CSIDL_PROGRAM_FILES_COMMONX86 = 0x002c; // x86 Program Files\Common on RISC
- internal const int CSIDL_PROGRAM_FILESX86 = 0x002a; // x86 C:\Program Files on RISC
- internal const int CSIDL_RESOURCES = 0x0038; // %windir%\Resources
- internal const int CSIDL_RESOURCES_LOCALIZED = 0x0039; // %windir%\resources\0409 (code page)
- internal const int CSIDL_SYSTEMX86 = 0x0029; // %windir%\system32
- internal const int CSIDL_WINDOWS = 0x0024; // GetWindowsDirectory()
+ internal const int CSIDL_FLAG_CREATE = 0x8000; // force folder creation in SHGetFolderPath
+ internal const int CSIDL_FLAG_DONT_VERIFY = 0x4000; // return an unverified folder path
+ internal const int CSIDL_ADMINTOOLS = 0x0030; // <user name>\Start Menu\Programs\Administrative Tools
+ internal const int CSIDL_CDBURN_AREA = 0x003b; // USERPROFILE\Local Settings\Application Data\Microsoft\CD Burning
+ internal const int CSIDL_COMMON_ADMINTOOLS = 0x002f; // All Users\Start Menu\Programs\Administrative Tools
+ internal const int CSIDL_COMMON_DOCUMENTS = 0x002e; // All Users\Documents
+ internal const int CSIDL_COMMON_MUSIC = 0x0035; // All Users\My Music
+ internal const int CSIDL_COMMON_OEM_LINKS = 0x003a; // Links to All Users OEM specific apps
+ internal const int CSIDL_COMMON_PICTURES = 0x0036; // All Users\My Pictures
+ internal const int CSIDL_COMMON_STARTMENU = 0x0016; // All Users\Start Menu
+ internal const int CSIDL_COMMON_PROGRAMS = 0X0017; // All Users\Start Menu\Programs
+ internal const int CSIDL_COMMON_STARTUP = 0x0018; // All Users\Startup
+ internal const int CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019; // All Users\Desktop
+ internal const int CSIDL_COMMON_TEMPLATES = 0x002d; // All Users\Templates
+ internal const int CSIDL_COMMON_VIDEO = 0x0037; // All Users\My Video
+ internal const int CSIDL_FONTS = 0x0014; // windows\fonts
+ internal const int CSIDL_MYVIDEO = 0x000e; // "My Videos" folder
+ internal const int CSIDL_NETHOOD = 0x0013; // %APPDATA%\Microsoft\Windows\Network Shortcuts
+ internal const int CSIDL_PRINTHOOD = 0x001b; // %APPDATA%\Microsoft\Windows\Printer Shortcuts
+ internal const int CSIDL_PROFILE = 0x0028; // %USERPROFILE% (%SystemDrive%\Users\%USERNAME%)
+ internal const int CSIDL_PROGRAM_FILES_COMMONX86 = 0x002c; // x86 Program Files\Common on RISC
+ internal const int CSIDL_PROGRAM_FILESX86 = 0x002a; // x86 C:\Program Files on RISC
+ internal const int CSIDL_RESOURCES = 0x0038; // %windir%\Resources
+ internal const int CSIDL_RESOURCES_LOCALIZED = 0x0039; // %windir%\resources\0409 (code page)
+ internal const int CSIDL_SYSTEMX86 = 0x0029; // %windir%\system32
+ internal const int CSIDL_WINDOWS = 0x0024; // GetWindowsDirectory()
// .NET Framework 3.5 and earlier - all versions of windows
- internal const int CSIDL_APPDATA = 0x001a;
- internal const int CSIDL_COMMON_APPDATA = 0x0023;
- internal const int CSIDL_LOCAL_APPDATA = 0x001c;
- internal const int CSIDL_COOKIES = 0x0021;
- internal const int CSIDL_FAVORITES = 0x0006;
- internal const int CSIDL_HISTORY = 0x0022;
- internal const int CSIDL_INTERNET_CACHE = 0x0020;
- internal const int CSIDL_PROGRAMS = 0x0002;
- internal const int CSIDL_RECENT = 0x0008;
- internal const int CSIDL_SENDTO = 0x0009;
- internal const int CSIDL_STARTMENU = 0x000b;
- internal const int CSIDL_STARTUP = 0x0007;
- internal const int CSIDL_SYSTEM = 0x0025;
- internal const int CSIDL_TEMPLATES = 0x0015;
- internal const int CSIDL_DESKTOPDIRECTORY = 0x0010;
- internal const int CSIDL_PERSONAL = 0x0005;
- internal const int CSIDL_PROGRAM_FILES = 0x0026;
- internal const int CSIDL_PROGRAM_FILES_COMMON = 0x002b;
- internal const int CSIDL_DESKTOP = 0x0000;
- internal const int CSIDL_DRIVES = 0x0011;
- internal const int CSIDL_MYMUSIC = 0x000d;
- internal const int CSIDL_MYPICTURES = 0x0027;
+ internal const int CSIDL_APPDATA = 0x001a;
+ internal const int CSIDL_COMMON_APPDATA = 0x0023;
+ internal const int CSIDL_LOCAL_APPDATA = 0x001c;
+ internal const int CSIDL_COOKIES = 0x0021;
+ internal const int CSIDL_FAVORITES = 0x0006;
+ internal const int CSIDL_HISTORY = 0x0022;
+ internal const int CSIDL_INTERNET_CACHE = 0x0020;
+ internal const int CSIDL_PROGRAMS = 0x0002;
+ internal const int CSIDL_RECENT = 0x0008;
+ internal const int CSIDL_SENDTO = 0x0009;
+ internal const int CSIDL_STARTMENU = 0x000b;
+ internal const int CSIDL_STARTUP = 0x0007;
+ internal const int CSIDL_SYSTEM = 0x0025;
+ internal const int CSIDL_TEMPLATES = 0x0015;
+ internal const int CSIDL_DESKTOPDIRECTORY = 0x0010;
+ internal const int CSIDL_PERSONAL = 0x0005;
+ internal const int CSIDL_PROGRAM_FILES = 0x0026;
+ internal const int CSIDL_PROGRAM_FILES_COMMON = 0x002b;
+ internal const int CSIDL_DESKTOP = 0x0000;
+ internal const int CSIDL_DRIVES = 0x0011;
+ internal const int CSIDL_MYMUSIC = 0x000d;
+ internal const int CSIDL_MYPICTURES = 0x0027;
internal const int NameSamCompatible = 2;
- [DllImport(USER32, SetLastError=true, BestFitMapping=false)]
+ [DllImport(USER32, SetLastError = true, BestFitMapping = false)]
internal static extern IntPtr SendMessageTimeout(IntPtr hWnd, int Msg, IntPtr wParam, String lParam, uint fuFlags, uint uTimeout, IntPtr lpdwResult);
[DllImport(KERNEL32, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal extern static bool QueryUnbiasedInterruptTime(out ulong UnbiasedTime);
-#if FEATURE_PAL
- [DllImport(KERNEL32, EntryPoint = "PAL_Random")]
- internal extern static bool Random(bool bStrong,
- [Out, MarshalAs(UnmanagedType.LPArray)] byte[] buffer, int length);
-#else
- private const int BCRYPT_USE_SYSTEM_PREFERRED_RNG = 0x00000002;
-#endif
+ internal const byte VER_GREATER_EQUAL = 0x3;
+ internal const uint VER_MAJORVERSION = 0x0000002;
+ internal const uint VER_MINORVERSION = 0x0000001;
+ internal const uint VER_SERVICEPACKMAJOR = 0x0000020;
+ internal const uint VER_SERVICEPACKMINOR = 0x0000010;
+ [DllImport("kernel32.dll")]
+ internal static extern bool VerifyVersionInfoW([In, Out] OSVERSIONINFOEX lpVersionInfo, uint dwTypeMask, ulong dwlConditionMask);
+ [DllImport("kernel32.dll")]
+ internal static extern ulong VerSetConditionMask(ulong dwlConditionMask, uint dwTypeBitMask, byte dwConditionMask);
}
}
diff --git a/src/mscorlib/src/System.Private.CoreLib.txt b/src/mscorlib/src/System.Private.CoreLib.txt
deleted file mode 100644
index b4e9e297d9..0000000000
--- a/src/mscorlib/src/System.Private.CoreLib.txt
+++ /dev/null
@@ -1,2235 +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.
-
-; These are the managed resources for mscorlib.dll.
-; See those first three bytes in the file? This is in UTF-8. Leave the
-; Unicode byte order mark (U+FEFF) written in UTF-8 at the start of this file.
-
-; For resource info, see the ResourceManager documentation and the ResGen tool,
-; which is a managed app using ResourceWriter.
-; ResGen now supports limited preprocessing of txt files, you can use
-; #if SYMBOL and #if !SYMBOL to control what sets of resources are included in
-; the resulting resources.
-
-; The naming scheme is: [Namespace.] ExceptionName _ Reason
-; We'll suppress "System." where possible.
-; Examples:
-; Argument_Null
-; Reflection.TargetInvokation_someReason
-
-; Usage Notes:
-; * Keep exceptions in alphabetical order by package
-; * A single space may exist on either side of the equal sign.
-; * Follow the naming conventions.
-; * Any lines starting with a '#' or ';' are ignored
-; * Equal signs aren't legal characters for keys, but may occur in values.
-; * Correctly punctuate all sentences. Most resources should end in a period.
-; Remember, your mother will probably read some of these messages.
-; * You may use " (quote), \n and \t. Use \\ for a single '\' character.
-; * String inserts work. i.e., BadNumber_File = Wrong number in file "{0}".
-
-; Real words, used by code like Environment.StackTrace
-#if INCLUDE_RUNTIME
-Word_At = at
-StackTrace_InFileLineNumber = in {0}:line {1}
-UnknownError_Num = Unknown error "{0}".
-AllocatedFrom = Allocated from:
-
-; Note this one is special, used as a divider between stack traces!
-Exception_EndOfInnerExceptionStack = --- End of inner exception stack trace ---
-Exception_WasThrown = Exception of type '{0}' was thrown.
-
-; The following are used in the implementation of ExceptionDispatchInfo
-Exception_EndStackTraceFromPreviousThrow = --- End of stack trace from previous location where exception was thrown ---
-
-Arg_ParamName_Name = Parameter name: {0}
-ArgumentOutOfRange_ActualValue = Actual value was {0}.
-
-NoDebugResources = [{0}]\r\nArguments: {1}\r\nDebugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See http://go.microsoft.com/fwlink/?linkid=106663&Version={2}&File={3}&Key={4}
-#endif // INCLUDE_RUNTIME
-
-#if INCLUDE_DEBUG
-
-; For code contracts
-AssumptionFailed = Assumption failed.
-AssumptionFailed_Cnd = Assumption failed: {0}
-AssertionFailed = Assertion failed.
-AssertionFailed_Cnd = Assertion failed: {0}
-PreconditionFailed = Precondition failed.
-PreconditionFailed_Cnd = Precondition failed: {0}
-PostconditionFailed = Postcondition failed.
-PostconditionFailed_Cnd = Postcondition failed: {0}
-PostconditionOnExceptionFailed = Postcondition failed after throwing an exception.
-PostconditionOnExceptionFailed_Cnd = Postcondition failed after throwing an exception: {0}
-InvariantFailed = Invariant failed.
-InvariantFailed_Cnd = Invariant failed: {0}
-MustUseCCRewrite = An assembly (probably "{1}") must be rewritten using the code contracts binary rewriter (CCRewrite) because it is calling Contract.{0} and the CONTRACTS_FULL symbol is defined. Remove any explicit definitions of the CONTRACTS_FULL symbol from your project and rebuild. CCRewrite can be downloaded from http://go.microsoft.com/fwlink/?LinkID=169180. \r\nAfter the rewriter is installed, it can be enabled in Visual Studio from the project's Properties page on the Code Contracts pane. Ensure that "Perform Runtime Contract Checking" is enabled, which will define CONTRACTS_FULL.
-
-; Identity Reference Library
-#if FEATURE_IDENTITY_REFERENCE
-IdentityReference_IdentityNotMapped = Some or all identity references could not be translated.
-IdentityReference_MustBeIdentityReference = The targetType parameter must be of IdentityReference type.
-IdentityReference_AccountNameTooLong = Account name is too long.
-IdentityReference_DomainNameTooLong = Domain name is too long.
-IdentityReference_InvalidNumberOfSubauthorities = The number of sub-authorities must not exceed {0}.
-IdentityReference_IdentifierAuthorityTooLarge = The size of the identifier authority must not exceed 6 bytes.
-IdentityReference_InvalidSidRevision = SIDs with revision other than '1' are not supported.
-IdentityReference_CannotCreateLogonIdsSid = Well-known SIDs of type LogonIdsSid cannot be created.
-IdentityReference_DomainSidRequired = The domainSid parameter must be specified for creating well-known SID of type {0}.
-IdentityReference_NotAWindowsDomain = The domainSid parameter is not a valid Windows domain SID.
-#endif // FEATURE_IDENTITY_REFERENCE
-
-; AccessException
-Acc_CreateGeneric = Cannot create a type for which Type.ContainsGenericParameters is true.
-Acc_CreateAbst = Cannot create an abstract class.
-Acc_CreateInterface = Cannot create an instance of an interface.
-Acc_NotClassInit = Type initializer was not callable.
-Acc_CreateGenericEx = Cannot create an instance of {0} because Type.ContainsGenericParameters is true.
-Acc_CreateArgIterator = Cannot dynamically create an instance of ArgIterator.
-Acc_CreateAbstEx = Cannot create an instance of {0} because it is an abstract class.
-Acc_CreateInterfaceEx = Cannot create an instance of {0} because it is an interface.
-Acc_CreateVoid = Cannot dynamically create an instance of System.Void.
-Acc_ReadOnly = Cannot set a constant field.
-Acc_RvaStatic = SkipVerification permission is needed to modify an image-based (RVA) static field.
-Access_Void = Cannot create an instance of void.
-
-; ArgumentException
-Arg_TypedReference_Null = The TypedReference must be initialized.
-Argument_AddingDuplicate__ = Item has already been added. Key in dictionary: '{0}' Key being added: '{1}'
-Argument_AddingDuplicate = An item with the same key has already been added.
-Argument_AddingDuplicateWithKey = An item with the same key has already been added. Key: {0}
-Argument_MethodDeclaringTypeGenericLcg = Method '{0}' has a generic declaring type '{1}'. Explicitly provide the declaring type to GetTokenFor.
-Argument_MethodDeclaringTypeGeneric = Cannot resolve method {0} because the declaring type of the method handle {1} is generic. Explicitly provide the declaring type to GetMethodFromHandle.
-Argument_FieldDeclaringTypeGeneric = Cannot resolve field {0} because the declaring type of the field handle {1} is generic. Explicitly provide the declaring type to GetFieldFromHandle.
-Argument_ApplicationTrustShouldHaveIdentity = An ApplicationTrust must have an application identity before it can be persisted.
-Argument_ConversionOverflow = Conversion buffer overflow.
-Argument_CodepageNotSupported = {0} is not a supported code page.
-Argument_CultureNotSupported = Culture is not supported.
-Argument_CultureInvalidIdentifier = {0} is an invalid culture identifier.
-Argument_OneOfCulturesNotSupported = Culture name {0} or {1} is not supported.
-Argument_CultureIetfNotSupported = Culture IETF Name {0} is not a recognized IETF name.
-Argument_CultureIsNeutral = Culture ID {0} (0x{0:X4}) is a neutral culture; a region cannot be created from it.
-Argument_InvalidNeutralRegionName = The region name {0} should not correspond to neutral culture; a specific culture name is required.
-Argument_InvalidGenericInstArray = Generic arguments must be provided for each generic parameter and each generic argument must be a RuntimeType.
-Argument_GenericArgsCount = The number of generic arguments provided doesn't equal the arity of the generic type definition.
-Argument_CultureInvalidFormat = Culture '{0}' is a neutral culture. It cannot be used in formatting and parsing and therefore cannot be set as the thread's current culture.
-Argument_CompareOptionOrdinal = CompareOption.Ordinal cannot be used with other options.
-Argument_CustomCultureCannotBePassedByNumber = Customized cultures cannot be passed by LCID, only by name.
-Argument_EncodingConversionOverflowChars = The output char buffer is too small to contain the decoded characters, encoding '{0}' fallback '{1}'.
-Argument_EncodingConversionOverflowBytes = The output byte buffer is too small to contain the encoded data, encoding '{0}' fallback '{1}'.
-Argument_EncoderFallbackNotEmpty = Must complete Convert() operation or call Encoder.Reset() before calling GetBytes() or GetByteCount(). Encoder '{0}' fallback '{1}'.
-Argument_EmptyFileName = Empty file name is not legal.
-Argument_EmptyPath = Empty path name is not legal.
-Argument_EmptyName = Empty name is not legal.
-Argument_ImplementIComparable = At least one object must implement IComparable.
-Argument_InvalidType = The type of arguments passed into generic comparer methods is invalid.
-Argument_InvalidTypeForCA=Cannot build type parameter for custom attribute with a type that does not support the AssemblyQualifiedName property. The type instance supplied was of type '{0}'.
-Argument_IllegalEnvVarName = Environment variable name cannot contain equal character.
-Argument_IllegalAppId = Application identity does not have same number of components as manifest paths.
-Argument_IllegalAppBase = The application base specified is not valid.
-Argument_UnableToParseManifest = Unexpected error while parsing the specified manifest.
-Argument_IllegalAppIdMismatch = Application identity does not match identities in manifests.
-Argument_InvalidAppId = Invalid identity: no deployment or application identity specified.
-Argument_InvalidGenericArg = The generic type parameter was not valid
-Argument_InvalidArrayLength = Length of the array must be {0}.
-Argument_InvalidArrayType = Target array type is not compatible with the type of items in the collection.
-Argument_InvalidAppendMode = Append access can be requested only in write-only mode.
-Argument_InvalidEnumValue = The value '{0}' is not valid for this usage of the type {1}.
-Argument_EnumIsNotIntOrShort = The underlying type of enum argument must be Int32 or Int16.
-Argument_InvalidEnum = The Enum type should contain one and only one instance field.
-Argument_InvalidKeyStore = '{0}' is not a valid KeyStore name.
-Argument_InvalidFileMode&AccessCombo = Combining FileMode: {0} with FileAccess: {1} is invalid.
-Argument_InvalidFileMode&RightsCombo = Combining FileMode: {0} with FileSystemRights: {1} is invalid.
-Argument_InvalidFileModeTruncate&RightsCombo = Combining FileMode: {0} with FileSystemRights: {1} is invalid. FileMode.Truncate is valid only when used with FileSystemRights.Write.
-Argument_InvalidFlag = Value of flags is invalid.
-Argument_InvalidAnyFlag = No flags can be set.
-Argument_InvalidHandle = The handle is invalid.
-Argument_InvalidRegistryKeyPermissionCheck = The specified RegistryKeyPermissionCheck value is invalid.
-Argument_InvalidRegistryOptionsCheck = The specified RegistryOptions value is invalid.
-Argument_InvalidRegistryViewCheck = The specified RegistryView value is invalid.
-Argument_InvalidSubPath = The directory specified, '{0}', is not a subdirectory of '{1}'.
-Argument_NoRegionInvariantCulture = There is no region associated with the Invariant Culture (Culture ID: 0x7F).
-Argument_ResultCalendarRange = The result is out of the supported range for this calendar. The result should be between {0} (Gregorian date) and {1} (Gregorian date), inclusive.
-Argument_ResultIslamicCalendarRange = The date is out of the supported range for the Islamic calendar. The date should be greater than July 18th, 622 AD (Gregorian date).
-Argument_NeverValidGenericArgument = The type '{0}' may not be used as a type argument.
-Argument_NotEnoughGenArguments = The type or method has {1} generic parameter(s), but {0} generic argument(s) were provided. A generic argument must be provided for each generic parameter.
-Argument_NullFullTrustAssembly = A null StrongName was found in the full trust assembly list.
-Argument_GenConstraintViolation = GenericArguments[{0}], '{1}', on '{2}' violates the constraint of type '{3}'.
-Argument_InvalidToken = Token {0:x} is not valid in the scope of module {1}.
-Argument_InvalidTypeToken = Token {0:x} is not a valid Type token.
-Argument_ResolveType = Token {0:x} is not a valid Type token in the scope of module {1}.
-Argument_ResolveMethod = Token {0:x} is not a valid MethodBase token in the scope of module {1}.
-Argument_ResolveField = Token {0:x} is not a valid FieldInfo token in the scope of module {1}.
-Argument_ResolveMember = Token {0:x} is not a valid MemberInfo token in the scope of module {1}.
-Argument_ResolveString = Token {0:x} is not a valid string token in the scope of module {1}.
-Argument_ResolveModuleType = Token {0} resolves to the special module type representing this module.
-Argument_ResolveMethodHandle = Type handle '{0}' and method handle with declaring type '{1}' are incompatible. Get RuntimeMethodHandle and declaring RuntimeTypeHandle off the same MethodBase.
-Argument_ResolveFieldHandle = Type handle '{0}' and field handle with declaring type '{1}' are incompatible. Get RuntimeFieldHandle and declaring RuntimeTypeHandle off the same FieldInfo.
-Argument_ResourceScopeWrongDirection = Resource type in the ResourceScope enum is going from a more restrictive resource type to a more general one. From: "{0}" To: "{1}"
-Argument_BadResourceScopeTypeBits = Unknown value for the ResourceScope: {0} Too many resource type bits may be set.
-Argument_BadResourceScopeVisibilityBits = Unknown value for the ResourceScope: {0} Too many resource visibility bits may be set.
-Argument_WaitHandleNameTooLong = The name can be no more than {0} characters in length.
-Argument_EnumTypeDoesNotMatch = The argument type, '{0}', is not the same as the enum type '{1}'.
-InvalidOperation_MethodBuilderBaked = The signature of the MethodBuilder can no longer be modified because an operation on the MethodBuilder caused the methodDef token to be created. For example, a call to SetCustomAttribute requires the methodDef token to emit the CustomAttribute token.
-InvalidOperation_GenericParametersAlreadySet = The generic parameters are already defined on this MethodBuilder.
-Arg_AccessException = Cannot access member.
-Arg_AppDomainUnloadedException = Attempted to access an unloaded AppDomain.
-Arg_ApplicationException = Error in the application.
-Arg_ArgumentOutOfRangeException = Specified argument was out of the range of valid values.
-Arg_ArithmeticException = Overflow or underflow in the arithmetic operation.
-Arg_ArrayLengthsDiffer = Array lengths must be the same.
-Arg_ArrayPlusOffTooSmall = Destination array is not long enough to copy all the items in the collection. Check array index and length.
-Arg_ArrayTypeMismatchException = Attempted to access an element as a type incompatible with the array.
-Arg_BadDecimal = Read an invalid decimal value from the buffer.
-Arg_BadImageFormatException = Format of the executable (.exe) or library (.dll) is invalid.
-Argument_BadImageFormatExceptionResolve = A BadImageFormatException has been thrown while parsing the signature. This is likely due to lack of a generic context. Ensure genericTypeArguments and genericMethodArguments are provided and contain enough context.
-Arg_BufferTooSmall = Not enough space available in the buffer.
-Arg_CATypeResolutionFailed = Failed to resolve type from string "{0}" which was embedded in custom attribute blob.
-Arg_CannotHaveNegativeValue = String cannot contain a minus sign if the base is not 10.
-Arg_CannotUnloadAppDomainException = Attempt to unload the AppDomain failed.
-Arg_CannotMixComparisonInfrastructure = The usage of IKeyComparer and IHashCodeProvider/IComparer interfaces cannot be mixed; use one or the other.
-Arg_ContextMarshalException = Attempted to marshal an object across a context boundary.
-Arg_DataMisalignedException = A datatype misalignment was detected in a load or store instruction.
-Arg_DevicesNotSupported = FileStream will not open Win32 devices such as disk partitions and tape drives. Avoid use of "\\\\.\\" in the path.
-Arg_DuplicateWaitObjectException = Duplicate objects in argument.
-Arg_EntryPointNotFoundException = Entry point was not found.
-Arg_DllNotFoundException = Dll was not found.
-Arg_ExecutionEngineException = Internal error in the runtime.
-Arg_FieldAccessException = Attempted to access a field that is not accessible by the caller.
-Arg_FileIsDirectory_Name = The target file "{0}" is a directory, not a file.
-Arg_FormatException = One of the identified items was in an invalid format.
-Arg_IndexOutOfRangeException = Index was outside the bounds of the array.
-Arg_InsufficientExecutionStackException = Insufficient stack to continue executing the program safely. This can happen from having too many functions on the call stack or function on the stack using too much stack space.
-Arg_InvalidCastException = Specified cast is not valid.
-Arg_InvalidOperationException = Operation is not valid due to the current state of the object.
-Arg_CorruptedCustomCultureFile = The file of the custom culture {0} is corrupt. Try to unregister this culture.
-Arg_InvokeMember = InvokeMember can be used only for COM objects.
-Arg_InvalidNeutralResourcesLanguage_Asm_Culture = The NeutralResourcesLanguageAttribute on the assembly "{0}" specifies an invalid culture name: "{1}".
-Arg_InvalidNeutralResourcesLanguage_FallbackLoc = The NeutralResourcesLanguageAttribute specifies an invalid or unrecognized ultimate resource fallback location: "{0}".
-Arg_InvalidSatelliteContract_Asm_Ver = Satellite contract version attribute on the assembly '{0}' specifies an invalid version: {1}.
-Arg_MethodAccessException = Attempt to access the method failed.
-Arg_MethodAccessException_WithMethodName = Attempt to access the method "{0}" on type "{1}" failed.
-Arg_MethodAccessException_WithCaller = Attempt by security transparent method '{0}' to access security critical method '{1}' failed.
-Arg_MissingFieldException = Attempted to access a non-existing field.
-Arg_MissingMemberException = Attempted to access a missing member.
-Arg_MissingMethodException = Attempted to access a missing method.
-Arg_MulticastNotSupportedException = Attempted to add multiple callbacks to a delegate that does not support multicast.
-Arg_NotFiniteNumberException = Number encountered was not a finite quantity.
-Arg_NotSupportedException = Specified method is not supported.
-Arg_UnboundGenParam = Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.
-Arg_UnboundGenField = Late bound operations cannot be performed on fields with types for which Type.ContainsGenericParameters is true.
-Arg_NotGenericParameter = Method may only be called on a Type for which Type.IsGenericParameter is true.
-Arg_GenericParameter = Method must be called on a Type for which Type.IsGenericParameter is false.
-Arg_NotGenericTypeDefinition = {0} is not a GenericTypeDefinition. MakeGenericType may only be called on a type for which Type.IsGenericTypeDefinition is true.
-Arg_NotGenericMethodDefinition = {0} is not a GenericMethodDefinition. MakeGenericMethod may only be called on a method for which MethodBase.IsGenericMethodDefinition is true.
-Arg_BadLiteralFormat = Encountered an invalid type for a default value.
-Arg_MissingActivationArguments = The AppDomainSetup must specify the activation arguments for this call.
-Argument_BadParameterTypeForCAB = Cannot emit a CustomAttribute with argument of type {0}.
-Argument_InvalidMemberForNamedArgument = The member must be either a field or a property.
-Argument_InvalidTypeName = The name of the type is invalid.
-
-; Note - don't change the NullReferenceException default message. This was
-; negotiated carefully with the VB team to avoid saying "null" or "nothing".
-Arg_NullReferenceException = Object reference not set to an instance of an object.
-
-Arg_AccessViolationException = Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
-Arg_OverflowException = Arithmetic operation resulted in an overflow.
-Arg_PathGlobalRoot = Paths that begin with \\\\?\\GlobalRoot are internal to the kernel and should not be opened by managed applications.
-Arg_PathIllegal = The path is not of a legal form.
-Arg_PathIllegalUNC = The UNC path should be of the form \\\\server\\share.
-Arg_RankException = Attempted to operate on an array with the incorrect number of dimensions.
-Arg_RankMultiDimNotSupported = Only single dimensional arrays are supported for the requested action.
-Arg_NonZeroLowerBound = The lower bound of target array must be zero.
-Arg_RegSubKeyValueAbsent = No value exists with that name.
-Arg_ResourceFileUnsupportedVersion = The ResourceReader class does not know how to read this version of .resources files. Expected version: {0} This file: {1}
-Arg_ResourceNameNotExist = The specified resource name "{0}" does not exist in the resource file.
-Arg_SecurityException = Security error.
-Arg_SerializationException = Serialization error.
-Arg_StackOverflowException = Operation caused a stack overflow.
-Arg_SurrogatesNotAllowedAsSingleChar = Unicode surrogate characters must be written out as pairs together in the same call, not individually. Consider passing in a character array instead.
-Arg_SynchronizationLockException = Object synchronization method was called from an unsynchronized block of code.
-Arg_RWLockRestoreException = ReaderWriterLock.RestoreLock was called without releasing all locks acquired since the call to ReleaseLock.
-Arg_SystemException = System error.
-Arg_TimeoutException = The operation has timed out.
-Arg_UnauthorizedAccessException = Attempted to perform an unauthorized operation.
-Arg_ArgumentException = Value does not fall within the expected range.
-Arg_DirectoryNotFoundException = Attempted to access a path that is not on the disk.
-Arg_DriveNotFoundException = Attempted to access a drive that is not available.
-Arg_EndOfStreamException = Attempted to read past the end of the stream.
-Arg_HexStyleNotSupported = The number style AllowHexSpecifier is not supported on floating point data types.
-Arg_IOException = I/O error occurred.
-Arg_InvalidHexStyle = With the AllowHexSpecifier bit set in the enum bit field, the only other valid bits that can be combined into the enum value must be a subset of those in HexNumber.
-Arg_KeyNotFound = The given key was not present in the dictionary.
-Argument_InvalidNumberStyles = An undefined NumberStyles value is being used.
-Argument_InvalidDateTimeStyles = An undefined DateTimeStyles value is being used.
-Argument_InvalidTimeSpanStyles = An undefined TimeSpanStyles value is being used.
-Argument_DateTimeOffsetInvalidDateTimeStyles = The DateTimeStyles value 'NoCurrentDateDefault' is not allowed when parsing DateTimeOffset.
-Argument_NativeResourceAlreadyDefined = Native resource has already been defined.
-Argument_BadObjRef = Invalid ObjRef provided to '{0}'.
-Argument_InvalidCultureName = Culture name '{0}' is not supported.
-Argument_NameTooLong = The name '{0}' is too long to be a Culture or Region name, which is limited to {1} characters.
-Argument_NameContainsInvalidCharacters = The name '{0}' contains characters that are not valid for a Culture or Region.
-Argument_InvalidRegionName = Region name '{0}' is not supported.
-Argument_CannotCreateTypedReference = Cannot use function evaluation to create a TypedReference object.
-Arg_ArrayZeroError = Array must not be of length zero.
-Arg_BogusIComparer = Unable to sort because the IComparer.Compare() method returns inconsistent results. Either a value does not compare equal to itself, or one value repeatedly compared to another value yields different results. IComparer: '{0}'.
-Arg_CreatInstAccess = Cannot specify both CreateInstance and another access type.
-Arg_CryptographyException = Error occurred during a cryptographic operation.
-Arg_DateTimeRange = Combination of arguments to the DateTime constructor is out of the legal range.
-Arg_DecBitCtor = Decimal byte array constructor requires an array of length four containing valid decimal bytes.
-Arg_DlgtTargMeth = Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
-Arg_DlgtTypeMis = Delegates must be of the same type.
-Arg_DlgtNullInst = Delegate to an instance method cannot have null 'this'.
-Arg_DllInitFailure = One machine may not have remote administration enabled, or both machines may not be running the remote registry service.
-Arg_EmptyArray = Array may not be empty.
-Arg_EmptyOrNullArray = Array may not be empty or null.
-Arg_EmptyCollection = Collection must not be empty.
-Arg_EmptyOrNullString = String may not be empty or null.
-Argument_ItemNotExist = The specified item does not exist in this KeyedCollection.
-Argument_EncodingNotSupported = '{0}' is not a supported encoding name. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.
-Argument_FallbackBufferNotEmpty = Cannot change fallback when buffer is not empty. Previous Convert() call left data in the fallback buffer.
-Argument_InvalidCodePageConversionIndex = Unable to translate Unicode character \\u{0:X4} at index {1} to specified code page.
-Argument_InvalidCodePageBytesIndex = Unable to translate bytes {0} at index {1} from specified code page to Unicode.
-Argument_RecursiveFallback = Recursive fallback not allowed for character \\u{0:X4}.
-Argument_RecursiveFallbackBytes = Recursive fallback not allowed for bytes {0}.
-Arg_EnumAndObjectMustBeSameType = Object must be the same type as the enum. The type passed in was '{0}'; the enum type was '{1}'.
-Arg_EnumIllegalVal = Illegal enum value: {0}.
-Arg_EnumNotSingleFlag = Must set exactly one flag.
-Arg_EnumAtLeastOneFlag = Must set at least one flag.
-Arg_EnumUnderlyingTypeAndObjectMustBeSameType = Enum underlying type and the object must be same type or object must be a String. Type passed in was '{0}'; the enum underlying type was '{1}'.
-Arg_EnumFormatUnderlyingTypeAndObjectMustBeSameType = Enum underlying type and the object must be same type or object. Type passed in was '{0}'; the enum underlying type was '{1}'.
-Arg_EnumMustHaveUnderlyingValueField = All enums must have an underlying value__ field.
-Arg_COMAccess = Must specify property Set or Get or method call for a COM Object.
-Arg_COMPropSetPut = Only one of the following binding flags can be set: BindingFlags.SetProperty, BindingFlags.PutDispProperty, BindingFlags.PutRefDispProperty.
-Arg_FldSetGet = Cannot specify both Get and Set on a field.
-Arg_PropSetGet = Cannot specify both Get and Set on a property.
-Arg_CannotBeNaN = TimeSpan does not accept floating point Not-a-Number values.
-Arg_FldGetPropSet = Cannot specify both GetField and SetProperty.
-Arg_FldSetPropGet = Cannot specify both SetField and GetProperty.
-Arg_FldSetInvoke = Cannot specify Set on a Field and Invoke on a method.
-Arg_FldGetArgErr = No arguments can be provided to Get a field value.
-Arg_FldSetArgErr = Only the field value can be specified to set a field value.
-Arg_GetMethNotFnd = Property Get method was not found.
-Arg_GuidArrayCtor = Byte array for GUID must be exactly {0} bytes long.
-Arg_HandleNotAsync = Handle does not support asynchronous operations. The parameters to the FileStream constructor may need to be changed to indicate that the handle was opened synchronously (that is, it was not opened for overlapped I/O).
-Arg_HandleNotSync = Handle does not support synchronous operations. The parameters to the FileStream constructor may need to be changed to indicate that the handle was opened asynchronously (that is, it was opened explicitly for overlapped I/O).
-Arg_HTCapacityOverflow = Hashtable's capacity overflowed and went negative. Check load factor, capacity and the current size of the table.
-Arg_IndexMustBeInt = All indexes must be of type Int32.
-Arg_InvalidConsoleColor = The ConsoleColor enum value was not defined on that enum. Please use a defined color from the enum.
-Arg_InvalidFileAttrs = Invalid File or Directory attributes value.
-Arg_InvalidHandle = Invalid handle.
-Arg_InvalidTypeInSignature = The signature Type array contains some invalid type (i.e. null, void)
-Arg_InvalidTypeInRetType = The return Type contains some invalid type (i.e. null, ByRef)
-Arg_EHClauseNotFilter = This ExceptionHandlingClause is not a filter.
-Arg_EHClauseNotClause = This ExceptionHandlingClause is not a clause.
-Arg_ReflectionOnlyCA = It is illegal to reflect on the custom attributes of a Type loaded via ReflectionOnlyGetType (see Assembly.ReflectionOnly) -- use CustomAttributeData instead.
-Arg_ReflectionOnlyInvoke = It is illegal to invoke a method on a Type loaded via ReflectionOnlyGetType.
-Arg_ReflectionOnlyField = It is illegal to get or set the value on a field on a Type loaded via ReflectionOnlyGetType.
-Arg_MemberInfoNullModule = The Module object containing the member cannot be null.
-Arg_ParameterInfoNullMember = The MemberInfo object defining the parameter cannot be null.
-Arg_ParameterInfoNullModule = The Module object containing the parameter cannot be null.
-Arg_AssemblyNullModule = The manifest module of the assembly cannot be null.
-Arg_LongerThanSrcArray = Source array was not long enough. Check the source index, length, and the array's lower bounds.
-Arg_LongerThanDestArray = Destination array was not long enough. Check the destination index, length, and the array's lower bounds.
-Arg_LowerBoundsMustMatch = The arrays' lower bounds must be identical.
-Arg_MustBeBoolean = Object must be of type Boolean.
-Arg_MustBeByte = Object must be of type Byte.
-Arg_MustBeChar = Object must be of type Char.
-Arg_MustBeDateTime = Object must be of type DateTime.
-Arg_MustBeDateTimeOffset = Object must be of type DateTimeOffset.
-Arg_MustBeDecimal = Object must be of type Decimal.
-Arg_MustBeDelegate = Type must derive from Delegate.
-Arg_MustBeDouble = Object must be of type Double.
-Arg_MustBeDriveLetterOrRootDir = Object must be a root directory ("C:\\") or a drive letter ("C").
-Arg_MustBeEnum = Type provided must be an Enum.
-Arg_MustBeEnumBaseTypeOrEnum = The value passed in must be an enum base or an underlying type for an enum, such as an Int32.
-Arg_MustBeGuid = Object must be of type GUID.
-Arg_MustBeIdentityReferenceType = Type must be an IdentityReference, such as NTAccount or SecurityIdentifier.
-Arg_MustBeInterface = Type passed must be an interface.
-Arg_MustBeInt16 = Object must be of type Int16.
-Arg_MustBeInt32 = Object must be of type Int32.
-Arg_MustBeInt64 = Object must be of type Int64.
-Arg_MustBePrimArray = Object must be an array of primitives.
-Arg_MustBePointer = Type must be a Pointer.
-Arg_MustBeStatic = Method must be a static method.
-Arg_MustBeString = Object must be of type String.
-Arg_MustBeStringPtrNotAtom = The pointer passed in as a String must not be in the bottom 64K of the process's address space.
-Arg_MustBeSByte = Object must be of type SByte.
-Arg_MustBeSingle = Object must be of type Single.
-Arg_MustBeTimeSpan = Object must be of type TimeSpan.
-Arg_MustBeType = Type must be a type provided by the runtime.
-Arg_MustBeUInt16 = Object must be of type UInt16.
-Arg_MustBeUInt32 = Object must be of type UInt32.
-Arg_MustBeUInt64 = Object must be of type UInt64.
-Arg_MustBeVersion = Object must be of type Version.
-Arg_MustBeTrue = Argument must be true.
-Arg_MustAllBeRuntimeType = At least one type argument is not a runtime type.
-Arg_NamedParamNull = Named parameter value must not be null.
-Arg_NamedParamTooBig = Named parameter array cannot be bigger than argument array.
-Arg_Need1DArray = Array was not a one-dimensional array.
-Arg_Need2DArray = Array was not a two-dimensional array.
-Arg_Need3DArray = Array was not a three-dimensional array.
-Arg_NeedAtLeast1Rank = Must provide at least one rank.
-Arg_NoDefCTor = No parameterless constructor defined for this object.
-Arg_BitArrayTypeUnsupported = Only supported array types for CopyTo on BitArrays are Boolean[], Int32[] and Byte[].
-Arg_DivideByZero = Attempted to divide by zero.
-Arg_NoAccessSpec = Must specify binding flags describing the invoke operation required (BindingFlags.InvokeMethod CreateInstance GetField SetField GetProperty SetProperty).
-Arg_NoStaticVirtual = Method cannot be both static and virtual.
-Arg_NotFoundIFace = Interface not found.
-Arg_ObjObjEx = Object of type '{0}' cannot be converted to type '{1}'.
-Arg_ObjObj = Object type cannot be converted to target type.
-Arg_FieldDeclTarget = Field '{0}' defined on type '{1}' is not a field on the target object which is of type '{2}'.
-Arg_OleAutDateInvalid = Not a legal OleAut date.
-Arg_OleAutDateScale = OleAut date did not convert to a DateTime correctly.
-Arg_PlatformNotSupported = Operation is not supported on this platform.
-Arg_PlatformSecureString = SecureString is only supported on Windows 2000 SP3 and higher platforms.
-Arg_ParmCnt = Parameter count mismatch.
-Arg_ParmArraySize = Must specify one or more parameters.
-Arg_Path2IsRooted = Second path fragment must not be a drive or UNC name.
-Arg_PathIsVolume = Path must not be a drive.
-Arg_PrimWiden = Cannot widen from source type to target type either because the source type is a not a primitive type or the conversion cannot be accomplished.
-Arg_NullIndex = Arrays indexes must be set to an object instance.
-Arg_VarMissNull = Missing parameter does not have a default value.
-Arg_PropSetInvoke = Cannot specify Set on a property and Invoke on a method.
-Arg_PropNotFound = Could not find the specified property.
-Arg_RankIndices = Indices length does not match the array rank.
-Arg_RanksAndBounds = Number of lengths and lowerBounds must match.
-Arg_RegSubKeyAbsent = Cannot delete a subkey tree because the subkey does not exist.
-Arg_RemoveArgNotFound = Cannot remove the specified item because it was not found in the specified Collection.
-Arg_RegKeyDelHive = Cannot delete a registry hive's subtree.
-Arg_RegKeyNoRemoteConnect = No remote connection to '{0}' while trying to read the registry.
-Arg_RegKeyOutOfRange = Registry HKEY was out of the legal range.
-Arg_RegKeyNotFound = The specified registry key does not exist.
-Arg_RegKeyStrLenBug = Registry key names should not be greater than 255 characters.
-Arg_RegValStrLenBug = Registry value names should not be greater than 16,383 characters.
-Arg_RegBadKeyKind = The specified RegistryValueKind is an invalid value.
-Arg_RegGetOverflowBug = RegistryKey.GetValue does not allow a String that has a length greater than Int32.MaxValue.
-Arg_RegSetMismatchedKind = The type of the value object did not match the specified RegistryValueKind or the object could not be properly converted.
-Arg_RegSetBadArrType = RegistryKey.SetValue does not support arrays of type '{0}'. Only Byte[] and String[] are supported.
-Arg_RegSetStrArrNull = RegistryKey.SetValue does not allow a String[] that contains a null String reference.
-Arg_RegInvalidKeyName = Registry key name must start with a valid base key name.
-Arg_ResMgrNotResSet = Type parameter must refer to a subclass of ResourceSet.
-Arg_SetMethNotFnd = Property set method not found.
-Arg_TypeRefPrimitve = TypedReferences cannot be redefined as primitives.
-Arg_UnknownTypeCode = Unknown TypeCode value.
-Arg_VersionString = Version string portion was too short or too long.
-Arg_NoITypeInfo = Specified TypeInfo was invalid because it did not support the ITypeInfo interface.
-Arg_NoITypeLib = Specified TypeLib was invalid because it did not support the ITypeLib interface.
-Arg_NoImporterCallback = Specified type library importer callback was invalid because it did not support the ITypeLibImporterNotifySink interface.
-Arg_ImporterLoadFailure = The type library importer encountered an error during type verification. Try importing without class members.
-Arg_InvalidBase = Invalid Base.
-Arg_EnumValueNotFound = Requested value '{0}' was not found.
-Arg_EnumLitValueNotFound = Literal value was not found.
-Arg_MustContainEnumInfo = Must specify valid information for parsing in the string.
-Arg_InvalidSearchPattern = Search pattern cannot contain ".." to move up directories and can be contained only internally in file/directory names, as in "a..b".
-Arg_NegativeArgCount = Argument count must not be negative.
-Arg_InvalidAccessEntry = Specified access entry is invalid because it is unrestricted. The global flags should be specified instead.
-Arg_InvalidFileName = Specified file name was invalid.
-Arg_InvalidFileExtension = Specified file extension was not a valid extension.
-Arg_COMException = Error HRESULT E_FAIL has been returned from a call to a COM component.
-Arg_ExternalException = External component has thrown an exception.
-Arg_InvalidComObjectException = Attempt has been made to use a COM object that does not have a backing class factory.
-Arg_InvalidOleVariantTypeException = Specified OLE variant was invalid.
-Arg_MarshalDirectiveException = Marshaling directives are invalid.
-Arg_MarshalAsAnyRestriction = AsAny cannot be used on return types, ByRef parameters, ArrayWithOffset, or parameters passed from unmanaged to managed.
-Arg_NDirectBadObject = No PInvoke conversion exists for value passed to Object-typed parameter.
-Arg_SafeArrayTypeMismatchException = Specified array was not of the expected type.
-Arg_VTableCallsNotSupportedException = Attempted to make an early bound call on a COM dispatch-only interface.
-Arg_SafeArrayRankMismatchException = Specified array was not of the expected rank.
-Arg_AmbiguousMatchException = Ambiguous match found.
-Arg_CustomAttributeFormatException = Binary format of the specified custom attribute was invalid.
-Arg_InvalidFilterCriteriaException = Specified filter criteria was invalid.
-Arg_TypeLoadNullStr = A null or zero length string does not represent a valid Type.
-Arg_TargetInvocationException = Exception has been thrown by the target of an invocation.
-Arg_TargetParameterCountException = Number of parameters specified does not match the expected number.
-Arg_TypeAccessException = Attempt to access the type failed.
-Arg_TypeLoadException = Failure has occurred while loading a type.
-Arg_TypeUnloadedException = Type had been unloaded.
-Arg_ThreadStateException = Thread was in an invalid state for the operation being executed.
-Arg_ThreadStartException = Thread failed to start.
-Arg_WrongAsyncResult = IAsyncResult object did not come from the corresponding async method on this type.
-Arg_WrongType = The value "{0}" is not of type "{1}" and cannot be used in this generic collection.
-Argument_InvalidArgumentForComparison = Type of argument is not compatible with the generic comparer.
-Argument_ALSInvalidCapacity = Specified capacity must not be less than the current capacity.
-Argument_ALSInvalidSlot = Specified slot number was invalid.
-Argument_IdnIllegalName = Decoded string is not a valid IDN name.
-Argument_IdnBadBidi = Left to right characters may not be mixed with right to left characters in IDN labels.
-Argument_IdnBadLabelSize = IDN labels must be between 1 and 63 characters long.
-Argument_IdnBadNameSize = IDN names must be between 1 and {0} characters long.
-Argument_IdnBadPunycode = Invalid IDN encoded string.
-Argument_IdnBadStd3 = Label contains character '{0}' not allowed with UseStd3AsciiRules
-Arg_InvalidANSIString = The ANSI string passed in could not be converted from the default ANSI code page to Unicode.
-Arg_InvalidUTF8String = The UTF8 string passed in could not be converted to Unicode.
-Argument_InvalidCharSequence = Invalid Unicode code point found at index {0}.
-Argument_InvalidCharSequenceNoIndex = String contains invalid Unicode code points.
-Argument_InvalidCalendar = Not a valid calendar for the given culture.
-Argument_InvalidNormalizationForm = Invalid or unsupported normalization form.
-Argument_InvalidPathChars = Illegal characters in path.
-Argument_InvalidOffLen = Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.
-Argument_InvalidSeekOrigin = Invalid seek origin.
-Argument_SeekOverflow = The specified seek offset '{0}' would result in a negative Stream position.
-Argument_InvalidUnity = Invalid Unity type.
-Argument_LongEnvVarName = Environment variable name cannot contain 1024 or more characters.
-Argument_LongEnvVarValue = Environment variable name or value is too long.
-Argument_StringFirstCharIsZero = The first char in the string is the null character.
-Argument_OnlyMscorlib = Only mscorlib's assembly is valid.
-Argument_PathEmpty = Path cannot be the empty string or all whitespace.
-Argument_PathFormatNotSupported = The given path's format is not supported.
-Argument_PathUriFormatNotSupported = URI formats are not supported.
-Argument_TypeNameTooLong = Type name was too long. The fully qualified type name must be less than 1,024 characters.
-Argument_StreamNotReadable = Stream was not readable.
-Argument_StreamNotWritable = Stream was not writable.
-Argument_InvalidNumberOfMembers = MemberData contains an invalid number of members.
-Argument_InvalidValue = Value was invalid.
-Argument_InvalidKey = Key was invalid.
-Argument_MinMaxValue = '{0}' cannot be greater than {1}.
-Argument_InvalidGroupSize = Every element in the value array should be between one and nine, except for the last element, which can be zero.
-Argument_MustHaveAttributeBaseClass = Type passed in must be derived from System.Attribute or System.Attribute itself.
-Argument_NoUninitializedStrings = Uninitialized Strings cannot be created.
-Argument_UnequalMembers = Supplied MemberInfo does not match the expected type.
-Argument_BadFormatSpecifier = Format specifier was invalid.
-Argument_InvalidHighSurrogate = Found a high surrogate char without a following low surrogate at index: {0}. The input may not be in this encoding, or may not contain valid Unicode (UTF-16) characters.
-Argument_InvalidLowSurrogate = Found a low surrogate char without a preceding high surrogate at index: {0}. The input may not be in this encoding, or may not contain valid Unicode (UTF-16) characters.
-Argument_UnmatchingSymScope = Non-matching symbol scope.
-Argument_NotInExceptionBlock = Not currently in an exception block.
-Argument_BadExceptionCodeGen = Incorrect code generation for exception block.
-Argument_NotExceptionType = Does not extend Exception.
-Argument_DuplicateResourceName = Duplicate resource name within an assembly.
-Argument_BadPersistableModuleInTransientAssembly = Cannot have a persistable module in a transient assembly.
-Argument_InvalidPermissionState = Invalid permission state.
-Argument_UnrestrictedIdentityPermission = Identity permissions cannot be unrestricted.
-Argument_WrongType = Operation on type '{0}' attempted with target of incorrect type.
-Argument_IllegalZone = Illegal security permission zone specified.
-Argument_HasToBeArrayClass = Must be an array type.
-Argument_InvalidDirectory = Invalid directory, '{0}'.
-Argument_DataLengthDifferent = Parameters 'members' and 'data' must have the same length.
-Argument_SigIsFinalized = Completed signature cannot be modified.
-Argument_ArraysInvalid = Array or pointer types are not valid.
-Argument_GenericsInvalid = Generic types are not valid.
-Argument_LargeInteger = Integer or token was too large to be encoded.
-Argument_BadSigFormat = Incorrect signature format.
-Argument_UnmatchedMethodForLocal = Local passed in does not belong to this ILGenerator.
-Argument_DuplicateName = Tried to add NamedPermissionSet with non-unique name.
-Argument_InvalidXMLElement = Invalid XML. Missing required tag <{0}> for type '{1}'.
-Argument_InvalidXMLMissingAttr = Invalid XML. Missing required attribute '{0}'.
-Argument_CannotGetTypeTokenForByRef = Cannot get TypeToken for a ByRef type.
-Argument_NotASimpleNativeType = The UnmanagedType passed to DefineUnmanagedMarshal is not a simple type. None of the following values may be used: UnmanagedType.ByValTStr, UnmanagedType.SafeArray, UnmanagedType.ByValArray, UnmanagedType.LPArray, UnmanagedType.CustomMarshaler.
-Argument_NotACustomMarshaler = Not a custom marshal.
-Argument_NoUnmanagedElementCount = Unmanaged marshal does not have ElementCount.
-Argument_NoNestedMarshal = Only LPArray or SafeArray has nested unmanaged marshal.
-Argument_InvalidXML = Invalid Xml.
-Argument_NoUnderlyingCCW = The object has no underlying COM data associated with it.
-Argument_BadFieldType = Bad field type in defining field.
-Argument_InvalidXMLBadVersion = Invalid Xml - can only parse elements of version one.
-Argument_NotAPermissionElement = 'elem' was not a permission element.
-Argument_NPMSInvalidName = Name can be neither null nor empty.
-Argument_InvalidElementTag = Invalid element tag '{0}'.
-Argument_InvalidElementText = Invalid element text '{0}'.
-Argument_InvalidElementName = Invalid element name '{0}'.
-Argument_InvalidElementValue = Invalid element value '{0}'.
-Argument_AttributeNamesMustBeUnique = Attribute names must be unique.
-Argument_InvalidHexFormat = Improperly formatted hex string.
-Argument_InvalidSite = Invalid site.
-Argument_InterfaceMap = 'this' type cannot be an interface itself.
-Argument_ArrayGetInterfaceMap = Interface maps for generic interfaces on arrays cannot be retrieved.
-Argument_InvalidName = Invalid name.
-Argument_InvalidDirectoryOnUrl = Invalid directory on URL.
-Argument_InvalidUrl = Invalid URL.
-Argument_InvalidKindOfTypeForCA = This type cannot be represented as a custom attribute.
-Argument_MustSupplyContainer = When supplying a FieldInfo for fixing up a nested type, a valid ID for that containing object must also be supplied.
-Argument_MustSupplyParent = When supplying the ID of a containing object, the FieldInfo that identifies the current field within that object must also be supplied.
-Argument_NoClass = Element does not specify a class.
-Argument_WrongElementType = '{0}' element required.
-Argument_UnableToGeneratePermissionSet = Unable to generate permission set; input XML may be malformed.
-Argument_NoEra = No Era was supplied.
-Argument_AssemblyAlreadyFullTrust = Assembly was already fully trusted.
-Argument_AssemblyNotFullTrust = Assembly was not fully trusted.
-Argument_AssemblyWinMD = Assembly must not be a Windows Runtime assembly.
-Argument_MemberAndArray = Cannot supply both a MemberInfo and an Array to indicate the parent of a value type.
-Argument_ObjNotComObject = The object's type must be __ComObject or derived from __ComObject.
-Argument_ObjIsWinRTObject = The object's type must not be a Windows Runtime type.
-Argument_TypeNotComObject = The type must be __ComObject or be derived from __ComObject.
-Argument_TypeIsWinRTType = The type must not be a Windows Runtime type.
-Argument_CantCallSecObjFunc = Cannot evaluate a security function.
-Argument_StructMustNotBeValueClass = The structure must not be a value class.
-Argument_NoSpecificCulture = Please select a specific culture, such as zh-CN, zh-HK, zh-TW, zh-MO, zh-SG.
-Argument_InvalidResourceCultureName = The given culture name '{0}' cannot be used to locate a resource file. Resource filenames must consist of only letters, numbers, hyphens or underscores.
-Argument_InvalidParamInfo = Invalid type for ParameterInfo member in Attribute class.
-Argument_EmptyDecString = Decimal separator cannot be the empty string.
-Argument_OffsetOfFieldNotFound = Field passed in is not a marshaled member of the type '{0}'.
-Argument_EmptyStrongName = StrongName cannot have an empty string for the assembly name.
-Argument_NotSerializable = Argument passed in is not serializable.
-Argument_EmptyApplicationName = ApplicationId cannot have an empty string for the name.
-Argument_NoDomainManager = The domain manager specified by the host could not be instantiated.
-Argument_NoMain = Main entry point not defined.
-Argument_InvalidDateTimeKind = Invalid DateTimeKind value.
-Argument_ConflictingDateTimeStyles = The DateTimeStyles values AssumeLocal and AssumeUniversal cannot be used together.
-Argument_ConflictingDateTimeRoundtripStyles = The DateTimeStyles value RoundtripKind cannot be used with the values AssumeLocal, AssumeUniversal or AdjustToUniversal.
-Argument_InvalidDigitSubstitution = The DigitSubstitution property must be of a valid member of the DigitShapes enumeration. Valid entries include Context, NativeNational or None.
-Argument_InvalidNativeDigitCount = The NativeDigits array must contain exactly ten members.
-Argument_InvalidNativeDigitValue = Each member of the NativeDigits array must be a single text element (one or more UTF16 code points) with a Unicode Nd (Number, Decimal Digit) property indicating it is a digit.
-ArgumentException_InvalidAceBinaryForm = The binary form of an ACE object is invalid.
-ArgumentException_InvalidAclBinaryForm = The binary form of an ACL object is invalid.
-ArgumentException_InvalidSDSddlForm = The SDDL form of a security descriptor object is invalid.
-Argument_InvalidSafeHandle = The SafeHandle is invalid.
-Argument_CannotPrepareAbstract = Abstract methods cannot be prepared.
-Argument_ArrayTooLarge = The input array length must not exceed Int32.MaxValue / {0}. Otherwise BitArray.Length would exceed Int32.MaxValue.
-Argument_RelativeUrlMembershipCondition = UrlMembershipCondition requires an absolute URL.
-Argument_EmptyWaithandleArray = Waithandle array may not be empty.
-Argument_InvalidSafeBufferOffLen = Offset and length were greater than the size of the SafeBuffer.
-Argument_NotEnoughBytesToRead = There are not enough bytes remaining in the accessor to read at this position.
-Argument_NotEnoughBytesToWrite = There are not enough bytes remaining in the accessor to write at this position.
-Argument_OffsetAndLengthOutOfBounds = Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.
-Argument_OffsetAndCapacityOutOfBounds = Offset and capacity were greater than the size of the view.
-Argument_UnmanagedMemAccessorWrapAround = The UnmanagedMemoryAccessor capacity and offset would wrap around the high end of the address space.
-Argument_UnrecognizedLoaderOptimization = Unrecognized LOADER_OPTIMIZATION property value. Supported values may include "SingleDomain", "MultiDomain", "MultiDomainHost", and "NotSpecified".
-ArgumentException_NotAllCustomSortingFuncsDefined = Implementations of all the NLS functions must be provided.
-ArgumentException_MinSortingVersion = The runtime does not support a version of "{0}" less than {1}.
-Argument_PreAllocatedAlreadyAllocated = 'preAllocated' is already in use.
-Argument_NativeOverlappedWrongBoundHandle = 'overlapped' was not allocated by this ThreadPoolBoundHandle instance.
-Argument_NativeOverlappedAlreadyFree = 'overlapped' has already been freed.
-Argument_AlreadyBoundOrSyncHandle = 'handle' has already been bound to the thread pool, or was not opened for asynchronous I/O.
-Argument_InvalidTypeWithPointersNotSupported = Cannot use type '{0}'. Only value types without pointers or references are supported.
-Argument_DestinationTooShort = Destination is too short.
-
-;
-; =====================================================
-; Reflection Emit resource strings
-Arugment_EmitMixedContext1 = Type '{0}' was loaded in the ReflectionOnly context but the AssemblyBuilder was not created as AssemblyBuilderAccess.ReflectionOnly.
-Arugment_EmitMixedContext2 = Type '{0}' was not loaded in the ReflectionOnly context but the AssemblyBuilder was created as AssemblyBuilderAccess.ReflectionOnly.
-Argument_BadSizeForData = Data size must be > 0 and < 0x3f0000
-Argument_InvalidLabel = Invalid Label.
-Argument_RedefinedLabel = Label multiply defined.
-Argument_UnclosedExceptionBlock = The IL Generator cannot be used while there are unclosed exceptions.
-Argument_MissingDefaultConstructor = was missing default constructor.
-Argument_TooManyFinallyClause = Exception blocks may have at most one finally clause.
-Argument_NotInTheSameModuleBuilder = The argument passed in was not from the same ModuleBuilder.
-Argument_BadCurrentLocalVariable = Bad current local variable for setting symbol information.
-Argument_DuplicateModuleName = Duplicate dynamic module name within an assembly.
-Argument_DuplicateTypeName = Duplicate type name within an assembly.
-Argument_InvalidAssemblyName = Assembly names may not begin with whitespace or contain the characters '/', or '\\' or ':'.
-Argument_InvalidGenericInstantiation = The given generic instantiation was invalid.
-Argument_DuplicatedFileName = Duplicate file names.
-Argument_GlobalFunctionHasToBeStatic = Global members must be static.
-Argument_BadPInvokeOnInterface = PInvoke methods cannot exist on interfaces.
-Argument_BadPInvokeMethod = PInvoke methods must be static and native and cannot be abstract.
-Argument_MethodRedefined = Method has been already defined.
-Argument_BadTypeAttrAbstractNFinal = Bad type attributes. A type cannot be both abstract and final.
-Argument_BadTypeAttrNestedVisibilityOnNonNestedType = Bad type attributes. Nested visibility flag set on a non-nested type.
-Argument_BadTypeAttrNonNestedVisibilityNestedType = Bad type attributes. Non-nested visibility flag set on a nested type.
-Argument_BadTypeAttrInvalidLayout = Bad type attributes. Invalid layout attribute specified.
-Argument_BadTypeAttrReservedBitsSet = Bad type attributes. Reserved bits set on the type.
-Argument_BadFieldSig = Field signatures do not have return types.
-Argument_ShouldOnlySetVisibilityFlags = Should only set visibility flags when creating EnumBuilder.
-Argument_BadNestedTypeFlags = Visibility of interfaces must be one of the following: NestedAssembly, NestedFamANDAssem, NestedFamily, NestedFamORAssem, NestedPrivate or NestedPublic.
-Argument_ShouldNotSpecifyExceptionType = Should not specify exception type for catch clause for filter block.
-Argument_BadLabel = Bad label in ILGenerator.
-Argument_BadLabelContent = Bad label content in ILGenerator.
-Argument_EmitWriteLineType = EmitWriteLine does not support this field or local type.
-Argument_ConstantNull = Null is not a valid constant value for this type.
-Argument_ConstantDoesntMatch = Constant does not match the defined type.
-Argument_ConstantNotSupported = {0} is not a supported constant type.
-Argument_BadConstructor = Cannot have private or static constructor.
-Argument_BadConstructorCallConv = Constructor must have standard calling convention.
-Argument_BadPropertyForConstructorBuilder = Property must be on the same type of the given ConstructorInfo.
-Argument_NotAWritableProperty = Not a writable property.
-Argument_BadFieldForConstructorBuilder = Field must be on the same type of the given ConstructorInfo.
-Argument_BadAttributeOnInterfaceMethod = Interface method must be abstract and virtual.
-ArgumentException_BadMethodImplBody = MethodOverride's body must be from this type.
-Argument_BadParameterCountsForConstructor = Parameter count does not match passed in argument value count.
-Argument_BadParameterTypeForConstructor = Passed in argument value at index {0} does not match the parameter type.
-Argument_BadTypeInCustomAttribute = An invalid type was used as a custom attribute constructor argument, field or property.
-Argument_DateTimeBadBinaryData = The binary data must result in a DateTime with ticks between DateTime.MinValue.Ticks and DateTime.MaxValue.Ticks.
-Argument_VerStringTooLong = The unmanaged Version information is too large to persist.
-Argument_UnknownUnmanagedCallConv = Unknown unmanaged calling convention for function signature.
-Argument_BadConstantValue = Bad default value.
-Argument_IllegalName = Illegal name.
-Argument_cvtres_NotFound = Cannot find cvtres.exe
-Argument_BadCAForUnmngRSC = Bad '{0}' while generating unmanaged resource information.
-Argument_MustBeInterfaceMethod = The MemberInfo must be an interface method.
-Argument_CORDBBadVarArgCallConv = Cannot evaluate a VarArgs function.
-Argument_CORDBBadMethod = Cannot find the method on the object instance.
-Argument_InvalidOpCodeOnDynamicMethod = Ldtoken, Ldftn and Ldvirtftn OpCodes cannot target DynamicMethods.
-Argument_InvalidTypeForDynamicMethod = Invalid type owner for DynamicMethod.
-Argument_NeedGenericMethodDefinition = Method must represent a generic method definition on a generic type definition.
-Argument_MethodNeedGenericDeclaringType = The specified method cannot be dynamic or global and must be declared on a generic type definition.
-Argument_ConstructorNeedGenericDeclaringType = The specified constructor must be declared on a generic type definition.
-Argument_FieldNeedGenericDeclaringType = The specified field must be declared on a generic type definition.
-Argument_InvalidMethodDeclaringType = The specified method must be declared on the generic type definition of the specified type.
-Argument_InvalidConstructorDeclaringType = The specified constructor must be declared on the generic type definition of the specified type.
-Argument_InvalidFieldDeclaringType = The specified field must be declared on the generic type definition of the specified type.
-Argument_NeedNonGenericType = The specified Type must not be a generic type definition.
-Argument_MustBeTypeBuilder = 'type' must contain a TypeBuilder as a generic argument.
-Argument_CannotSetParentToInterface = Cannot set parent to an interface.
-Argument_MismatchedArrays = Two arrays, {0} and {1}, must be of the same size.
-Argument_NeedNonGenericObject = The specified object must not be an instance of a generic type.
-Argument_NeedStructWithNoRefs = The specified Type must be a struct containing no references.
-Argument_NotMethodCallOpcode = The specified opcode cannot be passed to EmitCall.
-
-; =====================================================
-;
-Argument_ModuleAlreadyLoaded = The specified module has already been loaded.
-Argument_MustHaveLayoutOrBeBlittable = The specified structure must be blittable or have layout information.
-Argument_NotSimpleFileName = The filename must not include a path specification.
-Argument_TypeMustBeVisibleFromCom = The specified type must be visible from COM.
-Argument_TypeMustBeComCreatable = The type must be creatable from COM.
-Argument_TypeMustNotBeComImport = The type must not be imported from COM.
-Argument_PolicyFileDoesNotExist = The requested policy file does not exist.
-Argument_NonNullObjAndCtx = Either obj or ctx must be null.
-Argument_NoModuleFileExtension = Module file name '{0}' must have file extension.
-Argument_TypeDoesNotContainMethod = Type does not contain the given method.
-Argument_StringZeroLength = String cannot be of zero length.
-Argument_MustBeString = String is too long or has invalid contents.
-Argument_AbsolutePathRequired = Absolute path information is required.
-Argument_ManifestFileDoesNotExist = The specified manifest file does not exist.
-Argument_MustBeRuntimeType = Type must be a runtime Type object.
-Argument_TypeNotValid = The Type object is not valid.
-Argument_MustBeRuntimeMethodInfo = MethodInfo must be a runtime MethodInfo object.
-Argument_MustBeRuntimeFieldInfo = FieldInfo must be a runtime FieldInfo object.
-Argument_InvalidFieldInfo = The FieldInfo object is not valid.
-Argument_InvalidConstructorInfo = The ConstructorInfo object is not valid.
-Argument_MustBeRuntimeAssembly = Assembly must be a runtime Assembly object.
-Argument_MustBeRuntimeModule = Module must be a runtime Module object.
-Argument_MustBeRuntimeParameterInfo = ParameterInfo must be a runtime ParameterInfo object.
-Argument_InvalidParameterInfo = The ParameterInfo object is not valid.
-Argument_MustBeRuntimeReflectionObject = The object must be a runtime Reflection object.
-Argument_InvalidMarshalByRefObject = The MarshalByRefObject is not valid.
-Argument_TypedReferenceInvalidField = Field in TypedReferences cannot be static or init only.
-Argument_HandleLeak = Cannot pass a GCHandle across AppDomains.
-Argument_ArgumentZero = Argument cannot be zero.
-Argument_ImproperType = Improper types in collection.
-Argument_NotAMembershipCondition = The type does not implement IMembershipCondition
-Argument_NotAPermissionType = The type does not implement IPermission
-Argument_NotACodeGroupType = The type does not inherit from CodeGroup
-Argument_NotATP = Type must be a TransparentProxy
-Argument_AlreadyACCW = The object already has a CCW associated with it.
-Argument_OffsetLocalMismatch = The UTC Offset of the local dateTime parameter does not match the offset argument.
-Argument_OffsetUtcMismatch = The UTC Offset for Utc DateTime instances must be 0.
-Argument_UTCOutOfRange = The UTC time represented when the offset is applied must be between year 0 and 10,000.
-Argument_OffsetOutOfRange = Offset must be within plus or minus 14 hours.
-Argument_OffsetPrecision = Offset must be specified in whole minutes.
-Argument_FlagNotSupported = One or more flags are not supported.
-Argument_MustBeFalse = Argument must be initialized to false
-Argument_ToExclusiveLessThanFromExclusive = fromInclusive must be less than or equal to toExclusive.
-Argument_FrameworkNameTooShort=FrameworkName cannot have less than two components or more than three components.
-Argument_FrameworkNameInvalid=FrameworkName is invalid.
-Argument_FrameworkNameMissingVersion=FrameworkName version component is missing.
-#if FEATURE_COMINTEROP
-Argument_TypeNotActivatableViaWindowsRuntime = Type '{0}' does not have an activation factory because it is not activatable by Windows Runtime.
-Argument_WinRTSystemRuntimeType = Cannot marshal type '{0}' to Windows Runtime. Only 'System.RuntimeType' is supported.
-Argument_Unexpected_TypeSource = Unexpected TypeKind when marshaling Windows.Foundation.TypeName.
-#endif // FEATURE_COMINTEROP
-
-; ArgumentNullException
-ArgumentNull_Array = Array cannot be null.
-ArgumentNull_ArrayValue = Found a null value within an array.
-ArgumentNull_ArrayElement = At least one element in the specified array was null.
-ArgumentNull_Assembly = Assembly cannot be null.
-ArgumentNull_AssemblyName = AssemblyName cannot be null.
-ArgumentNull_AssemblyNameName = AssemblyName.Name cannot be null or an empty string.
-ArgumentNull_Buffer = Buffer cannot be null.
-ArgumentNull_Collection = Collection cannot be null.
-ArgumentNull_CultureInfo = CultureInfo cannot be null.
-ArgumentNull_Dictionary = Dictionary cannot be null.
-ArgumentNull_FileName = File name cannot be null.
-ArgumentNull_Key = Key cannot be null.
-ArgumentNull_Graph = Object Graph cannot be null.
-ArgumentNull_Path = Path cannot be null.
-ArgumentNull_Stream = Stream cannot be null.
-ArgumentNull_String = String reference not set to an instance of a String.
-ArgumentNull_Type = Type cannot be null.
-ArgumentNull_Obj = Object cannot be null.
-ArgumentNull_GUID = GUID cannot be null.
-ArgumentNull_NullMember = Member at position {0} was null.
-ArgumentNull_Generic = Value cannot be null.
-ArgumentNull_WithParamName = Parameter '{0}' cannot be null.
-ArgumentNull_Child = Cannot have a null child.
-ArgumentNull_SafeHandle = SafeHandle cannot be null.
-ArgumentNull_CriticalHandle = CriticalHandle cannot be null.
-ArgumentNull_TypedRefType = Type in TypedReference cannot be null.
-ArgumentNull_ApplicationTrust = The application trust cannot be null.
-ArgumentNull_TypeRequiredByResourceScope = The type parameter cannot be null when scoping the resource's visibility to Private or Assembly.
-ArgumentNull_Waithandles = The waitHandles parameter cannot be null.
-
-; ArgumentOutOfRangeException
-ArgumentOutOfRange_AddressSpace = The number of bytes cannot exceed the virtual address space on a 32 bit machine.
-ArgumentOutOfRange_ArrayLB = Number was less than the array's lower bound in the first dimension.
-ArgumentOutOfRange_ArrayLBAndLength = Higher indices will exceed Int32.MaxValue because of large lower bound and/or length.
-ArgumentOutOfRange_ArrayLength = The length of the array must be between {0} and {1}, inclusive.
-ArgumentOutOfRange_ArrayLengthMultiple = The length of the array must be a multiple of {0}.
-ArgumentOutOfRange_ArrayListInsert = Insertion index was out of range. Must be non-negative and less than or equal to size.
-ArgumentOutOfRange_ArrayTooSmall = Destination array is not long enough to copy all the required data. Check array length and offset.
-ArgumentOutOfRange_BeepFrequency = Console.Beep's frequency must be between {0} and {1}.
-ArgumentOutOfRange_BiggerThanCollection = Larger than collection size.
-ArgumentOutOfRange_Bounds_Lower_Upper = Argument must be between {0} and {1}.
-ArgumentOutOfRange_Count = Count must be positive and count must refer to a location within the string/array/collection.
-ArgumentOutOfRange_CalendarRange = Specified time is not supported in this calendar. It should be between {0} (Gregorian date) and {1} (Gregorian date), inclusive.
-ArgumentOutOfRange_ConsoleBufferBoundaries = The value must be greater than or equal to zero and less than the console's buffer size in that dimension.
-ArgumentOutOfRange_ConsoleBufferLessThanWindowSize = The console buffer size must not be less than the current size and position of the console window, nor greater than or equal to Int16.MaxValue.
-ArgumentOutOfRange_ConsoleWindowBufferSize = The new console window size would force the console buffer size to be too large.
-ArgumentOutOfRange_ConsoleTitleTooLong = The console title is too long.
-ArgumentOutOfRange_ConsoleWindowPos = The window position must be set such that the current window size fits within the console's buffer, and the numbers must not be negative.
-ArgumentOutOfRange_ConsoleWindowSize_Size = The value must be less than the console's current maximum window size of {0} in that dimension. Note that this value depends on screen resolution and the console font.
-ArgumentOutOfRange_ConsoleKey = Console key values must be between 0 and 255.
-ArgumentOutOfRange_CursorSize = The cursor size is invalid. It must be a percentage between 1 and 100.
-ArgumentOutOfRange_BadYearMonthDay = Year, Month, and Day parameters describe an un-representable DateTime.
-ArgumentOutOfRange_BadHourMinuteSecond = Hour, Minute, and Second parameters describe an un-representable DateTime.
-ArgumentOutOfRange_DateArithmetic = The added or subtracted value results in an un-representable DateTime.
-ArgumentOutOfRange_DateTimeBadMonths = Months value must be between +/-120000.
-ArgumentOutOfRange_DateTimeBadYears = Years value must be between +/-10000.
-ArgumentOutOfRange_DateTimeBadTicks = Ticks must be between DateTime.MinValue.Ticks and DateTime.MaxValue.Ticks.
-ArgumentOutOfRange_Day = Day must be between 1 and {0} for month {1}.
-ArgumentOutOfRange_DecimalRound = Decimal can only round to between 0 and 28 digits of precision.
-ArgumentOutOfRange_DecimalScale = Decimal's scale value must be between 0 and 28, inclusive.
-ArgumentOutOfRange_Era = Time value was out of era range.
-ArgumentOutOfRange_Enum = Enum value was out of legal range.
-ArgumentOutOfRange_FileLengthTooBig = Specified file length was too large for the file system.
-ArgumentOutOfRange_FileTimeInvalid = Not a valid Win32 FileTime.
-ArgumentOutOfRange_GetByteCountOverflow = Too many characters. The resulting number of bytes is larger than what can be returned as an int.
-ArgumentOutOfRange_GetCharCountOverflow = Too many bytes. The resulting number of chars is larger than what can be returned as an int.
-ArgumentOutOfRange_HashtableLoadFactor = Load factor needs to be between 0.1 and 1.0.
-ArgumentOutOfRange_HugeArrayNotSupported = Arrays larger than 2GB are not supported.
-ArgumentOutOfRange_InvalidHighSurrogate = A valid high surrogate character is between 0xd800 and 0xdbff, inclusive.
-ArgumentOutOfRange_InvalidLowSurrogate = A valid low surrogate character is between 0xdc00 and 0xdfff, inclusive.
-ArgumentOutOfRange_InvalidEraValue = Era value was not valid.
-ArgumentOutOfRange_InvalidUserDefinedAceType = User-defined ACEs must not have a well-known ACE type.
-ArgumentOutOfRange_InvalidUTF32 = A valid UTF32 value is between 0x000000 and 0x10ffff, inclusive, and should not include surrogate codepoint values (0x00d800 ~ 0x00dfff).
-ArgumentOutOfRange_Index = Index was out of range. Must be non-negative and less than the size of the collection.
-ArgumentOutOfRange_IndexString = Index was out of range. Must be non-negative and less than the length of the string.
-ArgumentOutOfRange_StreamLength = Stream length must be non-negative and less than 2^31 - 1 - origin.
-ArgumentOutOfRange_LessEqualToIntegerMaxVal = Argument must be less than or equal to 2^31 - 1 milliseconds.
-ArgumentOutOfRange_Month = Month must be between one and twelve.
-ArgumentOutOfRange_MustBeNonNegInt32 = Value must be non-negative and less than or equal to Int32.MaxValue.
-ArgumentOutOfRange_NeedNonNegNum = Non-negative number required.
-ArgumentOutOfRange_NeedNonNegOrNegative1 = Number must be either non-negative and less than or equal to Int32.MaxValue or -1.
-ArgumentOutOfRange_NeedPosNum = Positive number required.
-ArgumentOutOfRange_NegativeCapacity = Capacity must be positive.
-ArgumentOutOfRange_NegativeCount = Count cannot be less than zero.
-ArgumentOutOfRange_NegativeLength = Length cannot be less than zero.
-ArgumentOutOfRange_NegFileSize = Length must be non-negative.
-ArgumentOutOfRange_ObjectID = objectID cannot be less than or equal to zero.
-ArgumentOutOfRange_SmallCapacity = capacity was less than the current size.
-ArgumentOutOfRange_QueueGrowFactor = Queue grow factor must be between {0} and {1}.
-ArgumentOutOfRange_RoundingDigits = Rounding digits must be between 0 and 15, inclusive.
-ArgumentOutOfRange_StartIndex = StartIndex cannot be less than zero.
-ArgumentOutOfRange_MustBePositive = '{0}' must be greater than zero.
-ArgumentOutOfRange_MustBeNonNegNum = '{0}' must be non-negative.
-ArgumentOutOfRange_LengthGreaterThanCapacity = The length cannot be greater than the capacity.
-ArgumentOutOfRange_ListInsert = Index must be within the bounds of the List.
-ArgumentOutOfRange_StartIndexLessThanLength = startIndex must be less than length of string.
-ArgumentOutOfRange_StartIndexLargerThanLength = startIndex cannot be larger than length of string.
-ArgumentOutOfRange_EndIndexStartIndex = endIndex cannot be greater than startIndex.
-ArgumentOutOfRange_IndexCount = Index and count must refer to a location within the string.
-ArgumentOutOfRange_IndexCountBuffer = Index and count must refer to a location within the buffer.
-ArgumentOutOfRange_IndexLength = Index and length must refer to a location within the string.
-ArgumentOutOfRange_InvalidThreshold = The specified threshold for creating dictionary is out of range.
-ArgumentOutOfRange_Capacity = Capacity exceeds maximum capacity.
-ArgumentOutOfRange_Length = The specified length exceeds maximum capacity of SecureString.
-ArgumentOutOfRange_LengthTooLarge = The specified length exceeds the maximum value of {0}.
-ArgumentOutOfRange_SmallMaxCapacity = MaxCapacity must be one or greater.
-ArgumentOutOfRange_GenericPositive = Value must be positive.
-ArgumentOutOfRange_Range = Valid values are between {0} and {1}, inclusive.
-ArgumentOutOfRange_AddValue = Value to add was out of range.
-ArgumentOutOfRange_OffsetLength = Offset and length must refer to a position in the string.
-ArgumentOutOfRange_OffsetOut = Either offset did not refer to a position in the string, or there is an insufficient length of destination character array.
-ArgumentOutOfRange_PartialWCHAR = Pointer startIndex and length do not refer to a valid string.
-ArgumentOutOfRange_ParamSequence = The specified parameter index is not in range.
-ArgumentOutOfRange_Version = Version's parameters must be greater than or equal to zero.
-ArgumentOutOfRange_TimeoutTooLarge = Time-out interval must be less than 2^32-2.
-ArgumentOutOfRange_UIntPtrMax-1 = The length of the buffer must be less than the maximum UIntPtr value for your platform.
-ArgumentOutOfRange_UnmanagedMemStreamLength = UnmanagedMemoryStream length must be non-negative and less than 2^63 - 1 - baseAddress.
-ArgumentOutOfRange_UnmanagedMemStreamWrapAround = The UnmanagedMemoryStream capacity would wrap around the high end of the address space.
-ArgumentOutOfRange_PeriodTooLarge = Period must be less than 2^32-2.
-ArgumentOutOfRange_Year = Year must be between 1 and 9999.
-ArgumentOutOfRange_BinaryReaderFillBuffer = The number of bytes requested does not fit into BinaryReader's internal buffer.
-ArgumentOutOfRange_PositionLessThanCapacityRequired = The position may not be greater or equal to the capacity of the accessor.
-
-; ArithmeticException
-Arithmetic_NaN = Function does not accept floating point Not-a-Number values.
-
-; ArrayTypeMismatchException
-ArrayTypeMismatch_CantAssignType = Source array type cannot be assigned to destination array type.
-ArrayTypeMismatch_ConstrainedCopy = Array.ConstrainedCopy will only work on array types that are provably compatible, without any form of boxing, unboxing, widening, or casting of each array element. Change the array types (i.e., copy a Derived[] to a Base[]), or use a mitigation strategy in the CER for Array.Copy's less powerful reliability contract, such as cloning the array or throwing away the potentially corrupt destination array.
-
-; BadImageFormatException
-BadImageFormat_ResType&SerBlobMismatch = The type serialized in the .resources file was not the same type that the .resources file said it contained. Expected '{0}' but read '{1}'.
-BadImageFormat_ResourcesIndexTooLong = Corrupt .resources file. String for name index '{0}' extends past the end of the file.
-BadImageFormat_ResourcesNameTooLong = Corrupt .resources file. Resource name extends past the end of the file.
-BadImageFormat_ResourcesNameInvalidOffset = Corrupt .resources file. Invalid offset '{0}' into name section.
-BadImageFormat_ResourcesHeaderCorrupted = Corrupt .resources file. Unable to read resources from this file because of invalid header information. Try regenerating the .resources file.
-BadImageFormat_ResourceNameCorrupted = Corrupt .resources file. A resource name extends past the end of the stream.
-BadImageFormat_ResourceNameCorrupted_NameIndex = Corrupt .resources file. The resource name for name index {0} extends past the end of the stream.
-BadImageFormat_ResourceDataLengthInvalid = Corrupt .resources file. The specified data length '{0}' is not a valid position in the stream.
-BadImageFormat_TypeMismatch = Corrupt .resources file. The specified type doesn't match the available data in the stream.
-BadImageFormat_InvalidType = Corrupt .resources file. The specified type doesn't exist.
-BadImageFormat_ResourcesIndexInvalid = Corrupt .resources file. The resource index '{0}' is outside the valid range.
-BadImageFormat_StreamPositionInvalid = Corrupt .resources file. The specified position '{0}' is not a valid position in the stream.
-BadImageFormat_ResourcesDataInvalidOffset = Corrupt .resources file. Invalid offset '{0}' into data section.
-BadImageFormat_NegativeStringLength = Corrupt .resources file. String length must be non-negative.
-BadImageFormat_ParameterSignatureMismatch = The parameters and the signature of the method don't match.
-
-; Cryptography
-; These strings still appear in bcl.small but should go away eventually
-Cryptography_CSSM_Error = Error 0x{0} from the operating system security framework: '{1}'.
-Cryptography_CSSM_Error_Unknown = Error 0x{0} from the operating system security framework.
-Cryptography_InvalidDSASignatureSize = Length of the DSA signature was not 40 bytes.
-Cryptography_InvalidHandle = {0} is an invalid handle.
-Cryptography_InvalidOID = Object identifier (OID) is unknown.
-Cryptography_OAEPDecoding = Error occurred while decoding OAEP padding.
-Cryptography_PasswordDerivedBytes_InvalidIV = The Initialization vector should have the same length as the algorithm block size in bytes.
-Cryptography_SSE_InvalidDataSize = Length of the data to encrypt is invalid.
-Cryptography_X509_ExportFailed = The certificate export operation failed.
-Cryptography_X509_InvalidContentType = Invalid content type.
-Cryptography_CryptoStream_FlushFinalBlockTwice = FlushFinalBlock() method was called twice on a CryptoStream. It can only be called once.
-Cryptography_HashKeySet = Hash key cannot be changed after the first write to the stream.
-Cryptography_HashNotYetFinalized = Hash must be finalized before the hash value is retrieved.
-Cryptography_InsufficientBuffer = Input buffer contains insufficient data.
-Cryptography_InvalidBlockSize = Specified block size is not valid for this algorithm.
-Cryptography_InvalidCipherMode = Specified cipher mode is not valid for this algorithm.
-Cryptography_InvalidIVSize = Specified initialization vector (IV) does not match the block size for this algorithm.
-Cryptography_InvalidKeySize = Specified key is not a valid size for this algorithm.
-Cryptography_PasswordDerivedBytes_FewBytesSalt = Salt is not at least eight bytes.
-Cryptography_PKCS7_InvalidPadding = Padding is invalid and cannot be removed.
-Cryptography_UnknownHashAlgorithm='{0}' is not a known hash algorithm.
-
-; EventSource
-EventSource_ToString = EventSource({0}, {1})
-EventSource_EventSourceGuidInUse = An instance of EventSource with Guid {0} already exists.
-EventSource_KeywordNeedPowerOfTwo = Value {0} for keyword {1} needs to be a power of 2.
-EventSource_UndefinedKeyword = Use of undefined keyword value {0} for event {1}.
-EventSource_UnsupportedEventTypeInManifest = Unsupported type {0} in event source.
-EventSource_ListenerNotFound = Listener not found.
-EventSource_ListenerCreatedInsideCallback = Creating an EventListener inside a EventListener callback.
-EventSource_AttributeOnNonVoid = Event attribute placed on method {0} which does not return 'void'.
-EventSource_NeedPositiveId = Event IDs must be positive integers.
-EventSource_ReservedOpcode = Opcode values less than 11 are reserved for system use.
-EventSource_ReservedKeywords = Keywords values larger than 0x0000100000000000 are reserved for system use
-EventSource_PayloadTooBig=The payload for a single event is too large.
-EventSource_NoFreeBuffers=No Free Buffers available from the operating system (e.g. event rate too fast).
-EventSource_NullInput=Null passed as a event argument.
-EventSource_TooManyArgs=Too many arguments.
-EventSource_SessionIdError=Bit position in AllKeywords ({0}) must equal the command argument named "EtwSessionKeyword" ({1}).
-EventSource_EnumKindMismatch = The type of {0} is not expected in {1}.
-EventSource_MismatchIdToWriteEvent = Event {0} is givien event ID {1} but {2} was passed to WriteEvent.
-EventSource_EventIdReused = Event {0} has ID {1} which is already in use.
-EventSource_EventNameReused = Event name {0} used more than once. If you wish to overload a method, the overloaded method should have a NonEvent attribute.
-EventSource_UndefinedChannel = Use of undefined channel value {0} for event {1}.
-EventSource_UndefinedOpcode = Use of undefined opcode value {0} for event {1}.
-ArgumentOutOfRange_MaxArgExceeded = The total number of parameters must not exceed {0}.
-ArgumentOutOfRange_MaxStringsExceeded = The number of String parameters must not exceed {0}.
-ArgumentOutOfRange_NeedValidId = The ID parameter must be in the range {0} through {1}.
-EventSource_NeedGuid = The Guid of an EventSource must be non zero.
-EventSource_NeedName = The name of an EventSource must not be null.
-EventSource_EtwAlreadyRegistered = The provider has already been registered with the operating system.
-EventSource_ListenerWriteFailure = An error occurred when writing to a listener.
-EventSource_TypeMustDeriveFromEventSource = Event source types must derive from EventSource.
-EventSource_TypeMustBeSealedOrAbstract = Event source types must be sealed or abstract.
-EventSource_TaskOpcodePairReused = Event {0} (with ID {1}) has the same task/opcode pair as event {2} (with ID {3}).
-EventSource_EventMustHaveTaskIfNonDefaultOpcode = Event {0} (with ID {1}) has a non-default opcode but not a task.
-EventSource_EventNameDoesNotEqualTaskPlusOpcode = Event {0} (with ID {1}) has a name that is not the concatenation of its task name and opcode.
-EventSource_PeriodIllegalInProviderName = Period character ('.') is illegal in an ETW provider name ({0}).
-EventSource_IllegalOpcodeValue = Opcode {0} has a value of {1} which is outside the legal range (11-238).
-EventSource_OpcodeCollision = Opcodes {0} and {1} are defined with the same value ({2}).
-EventSource_IllegalTaskValue = Task {0} has a value of {1} which is outside the legal range (1-65535).
-EventSource_TaskCollision = Tasks {0} and {1} are defined with the same value ({2}).
-EventSource_IllegalKeywordsValue = Keyword {0} has a value of {1} which is outside the legal range (0-0x0000080000000000).
-EventSource_KeywordCollision = Keywords {0} and {1} are defined with the same value ({2}).
-EventSource_EventChannelOutOfRange = Channel {0} has a value of {1} which is outside the legal range (16-254).
-EventSource_ChannelTypeDoesNotMatchEventChannelValue = Channel {0} does not match event channel value {1}.
-EventSource_MaxChannelExceeded = Attempt to define more than the maximum limit of 8 channels for a provider.
-EventSource_DuplicateStringKey = Multiple definitions for string "{0}".
-EventSource_EventWithAdminChannelMustHaveMessage = Event {0} specifies an Admin channel {1}. It must specify a Message property.
-EventSource_UnsupportedMessageProperty = Event {0} specifies an illegal or unsupported formatting message ("{1}").
-EventSource_AbstractMustNotDeclareKTOC = Abstract event source must not declare {0} nested type.
-EventSource_AbstractMustNotDeclareEventMethods = Abstract event source must not declare event methods ({0} with ID {1}).
-EventSource_EventMustNotBeExplicitImplementation = Event method {0} (with ID {1}) is an explicit interface method implementation. Re-write method as implicit implementation.
-EventSource_EventParametersMismatch = Event {0} was called with {1} argument(s), but it is defined with {2} parameter(s).
-EventSource_InvalidCommand = Invalid command value.
-EventSource_InvalidEventFormat = Can't specify both etw event format flags.
-EventSource_AddScalarOutOfRange = Getting out of bounds during scalar addition.
-EventSource_PinArrayOutOfRange = Pins are out of range.
-EventSource_DataDescriptorsOutOfRange = Data descriptors are out of range.
-EventSource_NotSupportedArrayOfNil = Arrays of Nil are not supported.
-EventSource_NotSupportedArrayOfBinary = Arrays of Binary are not supported.
-EventSource_NotSupportedArrayOfNullTerminatedString = Arrays of null-terminated string are not supported.
-EventSource_TooManyFields = Too many fields in structure.
-EventSource_RecursiveTypeDefinition = Recursive type definition is not supported.
-EventSource_NotSupportedEnumType = Enum type {0} underlying type {1} is not supported for serialization.
-EventSource_NonCompliantTypeError = The API supports only anonymous types or types decorated with the EventDataAttribute. Non-compliant type: {0} dataType.
-EventSource_NotSupportedNestedArraysEnums = Nested arrays/enumerables are not supported.
-EventSource_IncorrentlyAuthoredTypeInfo = Incorrectly-authored TypeInfo - a type should be serialized as one field or as one group
-EventSource_NotSupportedCustomSerializedData = Enumerables of custom-serialized data are not supported
-EventSource_StopsFollowStarts = An event with stop suffix must follow a corresponding event with a start suffix.
-EventSource_NoRelatedActivityId = EventSource expects the first parameter of the Event method to be of type Guid and to be named "relatedActivityId" when calling WriteEventWithRelatedActivityId.
-EventSource_VarArgsParameterMismatch = The parameters to the Event method do not match the parameters to the WriteEvent method. This may cause the event to be displayed incorrectly.
-
-; ExecutionEngineException
-ExecutionEngine_InvalidAttribute = Attribute cannot have multiple definitions.
-ExecutionEngine_MissingSecurityDescriptor = Unable to retrieve security descriptor for this frame.
-
-;;ExecutionContext
-ExecutionContext_UndoFailed = Undo operation on a component context threw an exception
-ExecutionContext_ExceptionInAsyncLocalNotification = An exception was not handled in an AsyncLocal<T> notification callback.
-
-
-; FieldAccessException
-FieldAccess_InitOnly = InitOnly (aka ReadOnly) fields can only be initialized in the type/instance constructor.
-
-; FormatException
-Format_AttributeUsage = Duplicate AttributeUsageAttribute found on attribute type {0}.
-Format_Bad7BitInt32 = Too many bytes in what should have been a 7 bit encoded Int32.
-Format_BadBase = Invalid digits for the specified base.
-Format_BadBase64Char = The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
-Format_BadBase64CharArrayLength = Invalid length for a Base-64 char array or string.
-Format_BadBoolean = String was not recognized as a valid Boolean.
-Format_BadDateTime = String was not recognized as a valid DateTime.
-Format_BadDateTimeCalendar = The DateTime represented by the string is not supported in calendar {0}.
-Format_BadDayOfWeek = String was not recognized as a valid DateTime because the day of week was incorrect.
-Format_DateOutOfRange = The DateTime represented by the string is out of range.
-Format_BadDatePattern = Could not determine the order of year, month, and date from '{0}'.
-Format_BadFormatSpecifier = Format specifier was invalid.
-Format_BadTimeSpan = String was not recognized as a valid TimeSpan.
-Format_BadQuote = Cannot find a matching quote character for the character '{0}'.
-Format_EmptyInputString = Input string was either empty or contained only whitespace.
-Format_ExtraJunkAtEnd = Additional non-parsable characters are at the end of the string.
-Format_GuidBrace = Expected {0xdddddddd, etc}.
-Format_GuidComma = Could not find a comma, or the length between the previous token and the comma was zero (i.e., '0x,'etc.).
-Format_GuidBraceAfterLastNumber = Could not find a brace, or the length between the previous token and the brace was zero (i.e., '0x,'etc.).
-Format_GuidDashes = Dashes are in the wrong position for GUID parsing.
-Format_GuidEndBrace = Could not find the ending brace.
-Format_GuidHexPrefix = Expected hex 0x in '{0}'.
-Format_GuidInvLen = Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
-Format_GuidInvalidChar = Guid string should only contain hexadecimal characters.
-Format_GuidUnrecognized = Unrecognized Guid format.
-Format_InvalidEnumFormatSpecification = Format String can be only "G", "g", "X", "x", "F", "f", "D" or "d".
-Format_InvalidGuidFormatSpecification = Format String can be only "D", "d", "N", "n", "P", "p", "B", "b", "X" or "x".
-Format_InvalidString = Input string was not in a correct format.
-Format_IndexOutOfRange = Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
-Format_UnknowDateTimeWord = The string was not recognized as a valid DateTime. There is an unknown word starting at index {0}.
-Format_NeedSingleChar = String must be exactly one character long.
-Format_NoParsibleDigits = Could not find any recognizable digits.
-Format_RepeatDateTimePattern = DateTime pattern '{0}' appears more than once with different values.
-Format_StringZeroLength = String cannot have zero length.
-Format_TwoTimeZoneSpecifiers = The String being parsed cannot contain two TimeZone specifiers.
-Format_UTCOutOfRange= The UTC representation of the date falls outside the year range 1-9999.
-Format_OffsetOutOfRange=The time zone offset must be within plus or minus 14 hours.
-Format_MissingIncompleteDate=There must be at least a partial date with a year present in the input.
-
-; IndexOutOfRangeException
-IndexOutOfRange_ArrayRankIndex = Array does not have that many dimensions.
-IndexOutOfRange_IORaceCondition = Probable I/O race condition detected while copying memory. The I/O package is not thread safe by default. In multithreaded applications, a stream must be accessed in a thread-safe way, such as a thread-safe wrapper returned by TextReader's or TextWriter's Synchronized methods. This also applies to classes like StreamWriter and StreamReader.
-IndexOutOfRange_UMSPosition = Unmanaged memory stream position was beyond the capacity of the stream.
-
-; InsufficientMemoryException
-InsufficientMemory_MemFailPoint = Insufficient available memory to meet the expected demands of an operation at this time. Please try again later.
-InsufficientMemory_MemFailPoint_TooBig = Insufficient memory to meet the expected demands of an operation, and this system is likely to never satisfy this request. If this is a 32 bit system, consider booting in 3 GB mode.
-InsufficientMemory_MemFailPoint_VAFrag = Insufficient available memory to meet the expected demands of an operation at this time, possibly due to virtual address space fragmentation. Please try again later.
-
-
-; InvalidCastException
-InvalidCast_DBNull = Object cannot be cast to DBNull.
-InvalidCast_DownCastArrayElement = At least one element in the source array could not be cast down to the destination array type.
-InvalidCast_Empty = Object cannot be cast to Empty.
-InvalidCast_FromDBNull = Object cannot be cast from DBNull to other types.
-InvalidCast_FromTo = Invalid cast from '{0}' to '{1}'.
-InvalidCast_IConvertible = Object must implement IConvertible.
-InvalidCast_OATypeMismatch = OleAut reported a type mismatch.
-InvalidCast_StoreArrayElement = Object cannot be stored in an array of this type.
-InvalidCast_CannotCoerceByRefVariant = Object cannot be coerced to the original type of the ByRef VARIANT it was obtained from.
-InvalidCast_CannotCastNullToValueType = Null object cannot be converted to a value type.
-#if FEATURE_COMINTEROP
-InvalidCast_WinRTIPropertyValueElement = Object in an IPropertyValue is of type '{0}', which cannot be converted to a '{1}'.
-InvalidCast_WinRTIPropertyValueCoersion = Object in an IPropertyValue is of type '{0}' with value '{1}', which cannot be converted to a '{2}'.
-InvalidCast_WinRTIPropertyValueArrayCoersion = Object in an IPropertyValue is of type '{0}' which cannot be convereted to a '{1}' due to array element '{2}': {3}.
-#endif // FEATURE_COMINTEROP
-
-; InvalidOperationException
-InvalidOperation_ActivationArgsAppTrustMismatch = The activation arguments and application trust for the AppDomain must correspond to the same application identity.
-InvalidOperation_AddContextFrozen = Attempted to add properties to a frozen context.
-InvalidOperation_AppDomainSandboxAPINeedsExplicitAppBase = This API requires the ApplicationBase to be specified explicitly in the AppDomainSetup parameter.
-InvalidOperation_CantCancelCtrlBreak = Applications may not prevent control-break from terminating their process.
-InvalidOperation_CalledTwice = The method cannot be called twice on the same instance.
-InvalidOperation_CollectionCorrupted = A prior operation on this collection was interrupted by an exception. Collection's state is no longer trusted.
-InvalidOperation_CriticalTransparentAreMutuallyExclusive = SecurityTransparent and SecurityCritical attributes cannot be applied to the assembly scope at the same time.
-InvalidOperation_ExceptionStateCrossAppDomain = Thread.ExceptionState cannot access an ExceptionState from a different AppDomain.
-InvalidOperation_DebuggerLaunchFailed = Debugger unable to launch.
-InvalidOperation_ApartmentStateSwitchFailed = Failed to set the specified COM apartment state.
-InvalidOperation_EmptyQueue = Queue empty.
-InvalidOperation_EmptyStack = Stack empty.
-InvalidOperation_CannotRemoveFromStackOrQueue = Removal is an invalid operation for Stack or Queue.
-InvalidOperation_EnumEnded = Enumeration already finished.
-InvalidOperation_EnumFailedVersion = Collection was modified; enumeration operation may not execute.
-InvalidOperation_EnumNotStarted = Enumeration has not started. Call MoveNext.
-InvalidOperation_EnumOpCantHappen = Enumeration has either not started or has already finished.
-InvalidOperation_ModifyRONumFmtInfo = Unable to modify a read-only NumberFormatInfo object.
-InvalidOperation_MustBeSameThread = This operation must take place on the same thread on which the object was created.
-InvalidOperation_MustRevertPrivilege = Must revert the privilege prior to attempting this operation.
-InvalidOperation_ReadOnly = Instance is read-only.
-InvalidOperation_RegRemoveSubKey = Registry key has subkeys and recursive removes are not supported by this method.
-InvalidOperation_IComparerFailed = Failed to compare two elements in the array.
-InvalidOperation_InternalState = Invalid internal state.
-InvalidOperation_DuplicatePropertyName = Another property by this name already exists.
-InvalidOperation_NotCurrentDomain = You can only define a dynamic assembly on the current AppDomain.
-InvalidOperation_ContextAlreadyFrozen = Context is already frozen.
-InvalidOperation_WriteOnce = This property has already been set and cannot be modified.
-InvalidOperation_MethodBaked = Type definition of the method is complete.
-InvalidOperation_MethodHasBody = Method already has a body.
-InvalidOperation_ModificationOfNonCanonicalAcl = This access control list is not in canonical form and therefore cannot be modified.
-InvalidOperation_Method = This method is not supported by the current object.
-InvalidOperation_NativeOverlappedReused = NativeOverlapped cannot be reused for multiple operations.
-InvalidOperation_NotADebugModule = Not a debug ModuleBuilder.
-InvalidOperation_NoMultiModuleAssembly = You cannot have more than one dynamic module in each dynamic assembly in this version of the runtime.
-InvalidOperation_OpenLocalVariableScope = Local variable scope was not properly closed.
-InvalidOperation_SetVolumeLabelFailed = Volume labels can only be set for writable local volumes.
-InvalidOperation_SetData = An additional permission should not be supplied for setting loader information.
-InvalidOperation_SetData_OnlyOnce = SetData can only be used to set the value of a given name once.
-InvalidOperation_SetData_OnlyLocationURI = SetData cannot be used to set the value for '{0}'.
-InvalidOperation_TypeHasBeenCreated = Unable to change after type has been created.
-InvalidOperation_TypeNotCreated = Type has not been created.
-InvalidOperation_NoUnderlyingTypeOnEnum = Underlying type information on enumeration is not specified.
-InvalidOperation_ResMgrBadResSet_Type = '{0}': ResourceSet derived classes must provide a constructor that takes a String file name and a constructor that takes a Stream.
-InvalidOperation_AssemblyHasBeenSaved = Assembly '{0}' has been saved.
-InvalidOperation_ModuleHasBeenSaved = Module '{0}' has been saved.
-InvalidOperation_CannotAlterAssembly = Unable to alter assembly information.
-InvalidOperation_BadTransientModuleReference = Unable to make a reference to a transient module from a non-transient module.
-InvalidOperation_BadILGeneratorUsage = ILGenerator usage is invalid.
-InvalidOperation_BadInstructionOrIndexOutOfBound = MSIL instruction is invalid or index is out of bounds.
-InvalidOperation_ShouldNotHaveMethodBody = Method body should not exist.
-InvalidOperation_EntryMethodNotDefinedInAssembly = Entry method is not defined in the same assembly.
-InvalidOperation_CantSaveTransientAssembly = Cannot save a transient assembly.
-InvalidOperation_BadResourceContainer = Unable to add resource to transient module or transient assembly.
-InvalidOperation_CantInstantiateAbstractClass = Instances of abstract classes cannot be created.
-InvalidOperation_CantInstantiateFunctionPointer = Instances of function pointers cannot be created.
-InvalidOperation_BadTypeAttributesNotAbstract = Type must be declared abstract if any of its methods are abstract.
-InvalidOperation_BadInterfaceNotAbstract = Interface must be declared abstract.
-InvalidOperation_ConstructorNotAllowedOnInterface = Interface cannot have constructors.
-InvalidOperation_BadMethodBody = Method '{0}' cannot have a method body.
-InvalidOperation_MetaDataError = Metadata operation failed.
-InvalidOperation_BadEmptyMethodBody = Method '{0}' does not have a method body.
-InvalidOperation_EndInvokeCalledMultiple = EndInvoke can only be called once for each asynchronous operation.
-InvalidOperation_EndReadCalledMultiple = EndRead can only be called once for each asynchronous operation.
-InvalidOperation_EndWriteCalledMultiple = EndWrite can only be called once for each asynchronous operation.
-InvalidOperation_AsmLoadedForReflectionOnly = Assembly has been loaded as ReflectionOnly. This API requires an assembly capable of execution.
-InvalidOperation_NoAsmName = Assembly does not have an assembly name. In order to be registered for use by COM, an assembly must have a valid assembly name.
-InvalidOperation_NoAsmCodeBase = Assembly does not have a code base.
-InvalidOperation_HandleIsNotInitialized = Handle is not initialized.
-InvalidOperation_HandleIsNotPinned = Handle is not pinned.
-InvalidOperation_SlotHasBeenFreed = LocalDataStoreSlot storage has been freed.
-InvalidOperation_GlobalsHaveBeenCreated = Type definition of the global function has been completed.
-InvalidOperation_NotAVarArgCallingConvention = Calling convention must be VarArgs.
-InvalidOperation_CannotImportGlobalFromDifferentModule = Unable to import a global method or field from a different module.
-InvalidOperation_NonStaticComRegFunction = COM register function must be static.
-InvalidOperation_NonStaticComUnRegFunction = COM unregister function must be static.
-InvalidOperation_InvalidComRegFunctionSig = COM register function must have a System.Type parameter and a void return type.
-InvalidOperation_InvalidComUnRegFunctionSig = COM unregister function must have a System.Type parameter and a void return type.
-InvalidOperation_MultipleComRegFunctions = Type '{0}' has more than one COM registration function.
-InvalidOperation_MultipleComUnRegFunctions = Type '{0}' has more than one COM unregistration function.
-InvalidOperation_MustCallInitialize = You must call Initialize on this object instance before using it.
-InvalidOperation_MustLockForReadOrWrite = Object must be locked for read or write.
-InvalidOperation_MustLockForWrite = Object must be locked for read.
-InvalidOperation_NoValue = Nullable object must have a value.
-InvalidOperation_ResourceNotStream_Name = Resource '{0}' was not a Stream - call GetObject instead.
-InvalidOperation_ResourceNotString_Name = Resource '{0}' was not a String - call GetObject instead.
-InvalidOperation_ResourceNotString_Type = Resource was of type '{0}' instead of String - call GetObject instead.
-InvalidOperation_ResourceWriterSaved = The resource writer has already been closed and cannot be edited.
-InvalidOperation_UnderlyingArrayListChanged = This range in the underlying list is invalid. A possible cause is that elements were removed.
-InvalidOperation_AnonymousCannotImpersonate = An anonymous identity cannot perform an impersonation.
-InvalidOperation_DefaultConstructorILGen = Unable to access ILGenerator on a constructor created with DefineDefaultConstructor.
-InvalidOperation_DefaultConstructorDefineBody = The method body of the default constructor cannot be changed.
-InvalidOperation_ComputerName = Computer name could not be obtained.
-InvalidOperation_MismatchedAsyncResult = The IAsyncResult object provided does not match this delegate.
-InvalidOperation_PIAMustBeStrongNamed = Primary interop assemblies must be strongly named.
-InvalidOperation_HashInsertFailed = Hashtable insert failed. Load factor too high. The most common cause is multiple threads writing to the Hashtable simultaneously.
-InvalidOperation_UnknownEnumType = Unknown enum type.
-InvalidOperation_GetVersion = OSVersion's call to GetVersionEx failed.
-InvalidOperation_DateTimeParsing = Internal Error in DateTime and Calendar operations.
-InvalidOperation_UserDomainName = UserDomainName native call failed.
-InvalidOperation_WaitOnTransparentProxy = Cannot wait on a transparent proxy.
-InvalidOperation_NoPublicAddMethod = Cannot add the event handler since no public add method exists for the event.
-InvalidOperation_NoPublicRemoveMethod = Cannot remove the event handler since no public remove method exists for the event.
-InvalidOperation_NotSupportedOnWinRTEvent = Adding or removing event handlers dynamically is not supported on WinRT events.
-InvalidOperation_ConsoleKeyAvailableOnFile = Cannot see if a key has been pressed when either application does not have a console or when console input has been redirected from a file. Try Console.In.Peek.
-InvalidOperation_ConsoleReadKeyOnFile = Cannot read keys when either application does not have a console or when console input has been redirected from a file. Try Console.Read.
-InvalidOperation_ThreadWrongThreadStart = The thread was created with a ThreadStart delegate that does not accept a parameter.
-InvalidOperation_ThreadAPIsNotSupported = Use CompressedStack.(Capture/Run) or ExecutionContext.(Capture/Run) APIs instead.
-InvalidOperation_NotNewCaptureContext = Cannot apply a context that has been marshaled across AppDomains, that was not acquired through a Capture operation or that has already been the argument to a Set call.
-InvalidOperation_NullContext = Cannot call Set on a null context
-InvalidOperation_CannotCopyUsedContext = Only newly captured contexts can be copied
-InvalidOperation_CannotUseSwitcherOtherThread = Undo operation must be performed on the thread where the corresponding context was Set.
-InvalidOperation_SwitcherCtxMismatch = The Undo operation encountered a context that is different from what was applied in the corresponding Set operation. The possible cause is that a context was Set on the thread and not reverted(undone).
-InvalidOperation_CannotOverrideSetWithoutRevert = Must override both HostExecutionContextManager.SetHostExecutionContext and HostExecutionContextManager.Revert.
-InvalidOperation_CannotUseAFCOtherThread = AsyncFlowControl object must be used on the thread where it was created.
-InvalidOperation_CannotRestoreUnsupressedFlow = Cannot restore context flow when it is not suppressed.
-InvalidOperation_CannotSupressFlowMultipleTimes = Context flow is already suppressed.
-InvalidOperation_CannotUseAFCMultiple = AsyncFlowControl object can be used only once to call Undo().
-InvalidOperation_AsyncFlowCtrlCtxMismatch = AsyncFlowControl objects can be used to restore flow only on a Context that had its flow suppressed.
-InvalidOperation_TimeoutsNotSupported = Timeouts are not supported on this stream.
-InvalidOperation_Overlapped_Pack = Cannot pack a packed Overlapped again.
-InvalidOperation_OnlyValidForDS = Adding ACEs with Object Flags and Object GUIDs is only valid for directory-object ACLs.
-InvalidOperation_WrongAsyncResultOrEndReadCalledMultiple = Either the IAsyncResult object did not come from the corresponding async method on this type, or EndRead was called multiple times with the same IAsyncResult.
-InvalidOperation_WrongAsyncResultOrEndWriteCalledMultiple = Either the IAsyncResult object did not come from the corresponding async method on this type, or EndWrite was called multiple times with the same IAsyncResult.
-InvalidOperation_WrongAsyncResultOrEndCalledMultiple = Either the IAsyncResult object did not come from the corresponding async method on this type, or the End method was called multiple times with the same IAsyncResult.
-InvalidOperation_NoSecurityDescriptor = The object does not contain a security descriptor.
-InvalidOperation_NotAllowedInReflectionOnly = The requested operation is invalid in the ReflectionOnly context.
-InvalidOperation_NotAllowedInDynamicMethod = The requested operation is invalid for DynamicMethod.
-InvalidOperation_PropertyInfoNotAvailable = This API does not support PropertyInfo tokens.
-InvalidOperation_EventInfoNotAvailable = This API does not support EventInfo tokens.
-InvalidOperation_UnexpectedWin32Error = Unexpected error when calling an operating system function. The returned error code is 0x{0:x}.
-InvalidOperation_AssertTransparentCode = Cannot perform CAS Asserts in Security Transparent methods
-InvalidOperation_NullModuleHandle = The requested operation is invalid when called on a null ModuleHandle.
-InvalidOperation_NotWithConcurrentGC = This API is not available when the concurrent GC is enabled.
-InvalidOperation_WithoutARM = This API is not available when AppDomain Resource Monitoring is not turned on.
-InvalidOperation_NotGenericType = This operation is only valid on generic types.
-InvalidOperation_TypeCannotBeBoxed = The given type cannot be boxed.
-InvalidOperation_HostModifiedSecurityState = The security state of an AppDomain was modified by an AppDomainManager configured with the NoSecurityChanges flag.
-InvalidOperation_StrongNameKeyPairRequired = A strong name key pair is required to emit a strong-named dynamic assembly.
-#if FEATURE_COMINTEROP
-InvalidOperation_EventTokenTableRequiresDelegate = Type '{0}' is not a delegate type. EventTokenTable may only be used with delegate types.
-#endif // FEATURE_COMINTEROP
-InvalidOperation_NullArray = The underlying array is null.
-;system.security.claims
-InvalidOperation_ClaimCannotBeRemoved = The Claim '{0}' was not able to be removed. It is either not part of this Identity or it is a claim that is owned by the Principal that contains this Identity. For example, the Principal will own the claim when creating a GenericPrincipal with roles. The roles will be exposed through the Identity that is passed in the constructor, but not actually owned by the Identity. Similar logic exists for a RolePrincipal.
-InvalidOperationException_ActorGraphCircular = Actor cannot be set so that circular directed graph will exist chaining the subjects together.
-InvalidOperation_AsyncIOInProgress = The stream is currently in use by a previous operation on the stream.
-InvalidOperation_APIInvalidForCurrentContext = The API '{0}' cannot be used on the current platform. See http://go.microsoft.com/fwlink/?LinkId=248273 for more information.
-
-; InvalidProgramException
-InvalidProgram_Default = Common Language Runtime detected an invalid program.
-
-; Isolated Storage
-#if FEATURE_ISOSTORE
-IsolatedStorage_AssemblyMissingIdentity = Unable to determine assembly of the caller.
-IsolatedStorage_ApplicationMissingIdentity = Unable to determine application identity of the caller.
-IsolatedStorage_DomainMissingIdentity = Unable to determine domain of the caller.
-IsolatedStorage_AssemblyGrantSet = Unable to determine granted permission for assembly.
-IsolatedStorage_DomainGrantSet = Unable to determine granted permission for domain.
-IsolatedStorage_ApplicationGrantSet = Unable to determine granted permission for application.
-IsolatedStorage_Init = Initialization failed.
-IsolatedStorage_ApplicationNoEvidence = Unable to determine identity of application.
-IsolatedStorage_AssemblyNoEvidence = Unable to determine identity of assembly.
-IsolatedStorage_DomainNoEvidence = Unable to determine the identity of domain.
-IsolatedStorage_DeleteDirectories = Unable to delete; directory or files in the directory could be in use.
-IsolatedStorage_DeleteFile = Unable to delete file.
-IsolatedStorage_CreateDirectory = Unable to create directory.
-IsolatedStorage_DeleteDirectory = Unable to delete, directory not empty or does not exist.
-IsolatedStorage_Operation_ISFS = Operation not permitted on IsolatedStorageFileStream.
-IsolatedStorage_Operation = Operation not permitted.
-IsolatedStorage_Path = Path must be a valid file name.
-IsolatedStorage_FileOpenMode = Invalid mode, see System.IO.FileMode.
-IsolatedStorage_SeekOrigin = Invalid origin, see System.IO.SeekOrigin.
-IsolatedStorage_Scope_U_R_M = Invalid scope, expected User, User|Roaming or Machine.
-IsolatedStorage_Scope_Invalid = Invalid scope.
-IsolatedStorage_Exception = An error occurred while accessing IsolatedStorage.
-IsolatedStorage_QuotaIsUndefined = {0} is not defined for this store. An operation was performed that requires access to {0}. Stores obtained using enumeration APIs do not have a well-defined {0}, since partial evidence is used to open the store.
-IsolatedStorage_CurrentSizeUndefined = Current size cannot be determined for this store.
-IsolatedStorage_DomainUndefined = Domain cannot be determined on an Assembly or Application store.
-IsolatedStorage_ApplicationUndefined = Application cannot be determined on an Assembly or Domain store.
-IsolatedStorage_AssemblyUndefined = Assembly cannot be determined for an Application store.
-IsolatedStorage_StoreNotOpen = Store must be open for this operation.
-IsolatedStorage_OldQuotaLarger = The new quota must be larger than the old quota.
-IsolatedStorage_UsageWillExceedQuota = There is not enough free space to perform the operation.
-IsolatedStorage_NotValidOnDesktop = The Site scope is currently not supported.
-IsolatedStorage_OnlyIncreaseUserApplicationStore = Increasing the quota of this scope is not supported. Only the user application scope’s quota can be increased.
-#endif // FEATURE_ISOSTORE
-
-; Verification Exception
-Verification_Exception = Operation could destabilize the runtime.
-
-; IL stub marshaler exceptions
-Marshaler_StringTooLong = Marshaler restriction: Excessively long string.
-
-; Missing (General)
-MissingConstructor_Name = Constructor on type '{0}' not found.
-MissingField = Field not found.
-MissingField_Name = Field '{0}' not found.
-MissingMember = Member not found.
-MissingMember_Name = Member '{0}' not found.
-MissingMethod_Name = Method '{0}' not found.
-MissingModule = Module '{0}' not found.
-MissingType = Type '{0}' not found.
-
-; MissingManifestResourceException
-Arg_MissingManifestResourceException = Unable to find manifest resource.
-MissingManifestResource_LooselyLinked = Could not find a manifest resource entry called "{0}" in assembly "{1}". Please check spelling, capitalization, and build rules to ensure "{0}" is being linked into the assembly.
-MissingManifestResource_NoNeutralAsm = Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "{0}" was correctly embedded or linked into assembly "{1}" at compile time, or that all the satellite assemblies required are loadable and fully signed.
-MissingManifestResource_NoNeutralDisk = Could not find any resources appropriate for the specified culture (or the neutral culture) on disk.
-MissingManifestResource_MultipleBlobs = A case-insensitive lookup for resource file "{0}" in assembly "{1}" found multiple entries. Remove the duplicates or specify the exact case.
-MissingManifestResource_ResWFileNotLoaded = Unable to load resources for resource file "{0}" in package "{1}".
-MissingManifestResource_NoPRIresources = Unable to open Package Resource Index.
-
-; MissingMember
-MissingMemberTypeRef = FieldInfo does not match the target Type.
-MissingMemberNestErr = TypedReference can only be made on nested value Types.
-
-; MissingSatelliteAssemblyException
-MissingSatelliteAssembly_Default = Resource lookup fell back to the ultimate fallback resources in a satellite assembly, but that satellite either was not found or could not be loaded. Please consider reinstalling or repairing the application.
-MissingSatelliteAssembly_Culture_Name = The satellite assembly named "{1}" for fallback culture "{0}" either could not be found or could not be loaded. This is generally a setup problem. Please consider reinstalling or repairing the application.
-
-; MulticastNotSupportedException
-Multicast_Combine = Delegates that are not of type MulticastDelegate may not be combined.
-
-; NotImplementedException
-Arg_NotImplementedException = The method or operation is not implemented.
-NotImplemented_ResourcesLongerThan2^63 = Resource files longer than 2^63 bytes are not currently implemented.
-
-; NotSupportedException
-NotSupported_NYI = This feature is not currently implemented.
-NotSupported_AbstractNonCLS = This non-CLS method is not implemented.
-NotSupported_ChangeType = ChangeType operation is not supported.
-NotSupported_ByRefLike = Cannot create boxed ByRef-like values.
-NotSupported_ByRefLike[] = Cannot create arrays of ByRef-like values.
-NotSupported_OpenType = Cannot create arrays of open type.
-NotSupported_DBNullSerial = Only one DBNull instance may exist, and calls to DBNull deserialization methods are not allowed.
-NotSupported_DelegateSerHolderSerial = DelegateSerializationHolder objects are designed to represent a delegate during serialization and are not serializable themselves.
-NotSupported_DelegateCreationFromPT = Application code cannot use Activator.CreateInstance to create types that derive from System.Delegate. Delegate.CreateDelegate can be used instead.
-NotSupported_EncryptionNeedsNTFS = File encryption support only works on NTFS partitions.
-NotSupported_FileStreamOnNonFiles = FileStream was asked to open a device that was not a file. For support for devices like 'com1:' or 'lpt1:', call CreateFile, then use the FileStream constructors that take an OS handle as an IntPtr.
-NotSupported_FixedSizeCollection = Collection was of a fixed size.
-NotSupported_KeyCollectionSet = Mutating a key collection derived from a dictionary is not allowed.
-NotSupported_ValueCollectionSet = Mutating a value collection derived from a dictionary is not allowed.
-NotSupported_MemStreamNotExpandable = Memory stream is not expandable.
-NotSupported_ObsoleteResourcesFile = Found an obsolete .resources file in assembly '{0}'. Rebuild that .resources file then rebuild that assembly.
-NotSupported_OleAutBadVarType = The given Variant type is not supported by this OleAut function.
-NotSupported_PopulateData = This Surrogate does not support PopulateData().
-NotSupported_ReadOnlyCollection = Collection is read-only.
-NotSupported_RangeCollection = The specified operation is not supported on Ranges.
-NotSupported_SortedListNestedWrite = This operation is not supported on SortedList nested types because they require modifying the original SortedList.
-NotSupported_SubclassOverride = Derived classes must provide an implementation.
-NotSupported_TypeCannotDeserialized = Direct deserialization of type '{0}' is not supported.
-NotSupported_UnreadableStream = Stream does not support reading.
-NotSupported_UnseekableStream = Stream does not support seeking.
-NotSupported_UnwritableStream = Stream does not support writing.
-NotSupported_CannotWriteToBufferedStreamIfReadBufferCannotBeFlushed = Cannot write to a BufferedStream while the read buffer is not empty if the underlying stream is not seekable. Ensure that the stream underlying this BufferedStream can seek or avoid interleaving read and write operations on this BufferedStream.
-NotSupported_Method = Method is not supported.
-NotSupported_Constructor = Object cannot be created through this constructor.
-NotSupported_DynamicModule = The invoked member is not supported in a dynamic module.
-NotSupported_TypeNotYetCreated = The invoked member is not supported before the type is created.
-NotSupported_SymbolMethod = Not supported in an array method of a type definition that is not complete.
-NotSupported_NotDynamicModule = The MethodRental.SwapMethodBody method can only be called to swap the method body of a method in a dynamic module.
-NotSupported_DynamicAssembly = The invoked member is not supported in a dynamic assembly.
-NotSupported_NotAllTypesAreBaked = Type '{0}' was not completed.
-NotSupported_CannotSaveModuleIndividually = Unable to save a ModuleBuilder if it was created underneath an AssemblyBuilder. Call Save on the AssemblyBuilder instead.
-NotSupported_MaxWaitHandles = The number of WaitHandles must be less than or equal to 64.
-NotSupported_IllegalOneByteBranch = Illegal one-byte branch at position: {0}. Requested branch was: {1}.
-NotSupported_OutputStreamUsingTypeBuilder = Output streams do not support TypeBuilders.
-NotSupported_ValueClassCM = Custom marshalers for value types are not currently supported.
-NotSupported_Void[] = Arrays of System.Void are not supported.
-NotSupported_NoParentDefaultConstructor = Parent does not have a default constructor. The default constructor must be explicitly defined.
-NotSupported_NonReflectedType = Not supported in a non-reflected type.
-NotSupported_GlobalFunctionNotBaked = The type definition of the global function is not completed.
-NotSupported_SecurityPermissionUnion = Union is not implemented.
-NotSupported_UnitySerHolder = The UnitySerializationHolder object is designed to transmit information about other types and is not serializable itself.
-NotSupported_UnknownTypeCode = TypeCode '{0}' was not valid.
-NotSupported_WaitAllSTAThread = WaitAll for multiple handles on a STA thread is not supported.
-NotSupported_SignalAndWaitSTAThread = SignalAndWait on a STA thread is not supported.
-NotSupported_CreateInstanceWithTypeBuilder = CreateInstance cannot be used with an object of type TypeBuilder.
-NotSupported_NonUrlAttrOnMBR = UrlAttribute is the only attribute supported for MarshalByRefObject.
-NotSupported_ActivAttrOnNonMBR = Activation Attributes are not supported for types not deriving from MarshalByRefObject.
-NotSupported_ActivAttr = Activation Attributes are not supported.
-NotSupported_ActivForCom = Activation Attributes not supported for COM Objects.
-NotSupported_NoCodepageData = No data is available for encoding {0}. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.
-NotSupported_CodePage50229 = The ISO-2022-CN Encoding (Code page 50229) is not supported.
-NotSupported_DynamicAssemblyNoRunAccess = Cannot execute code on a dynamic assembly without run access.
-NotSupported_IDispInvokeDefaultMemberWithNamedArgs = Invoking default method with named arguments is not supported.
-NotSupported_Type = Type is not supported.
-NotSupported_GetMethod = The 'get' method is not supported on this property.
-NotSupported_SetMethod = The 'set' method is not supported on this property.
-NotSupported_DeclarativeUnion = Declarative unionizing of these permissions is not supported.
-NotSupported_StringComparison = The string comparison type passed in is currently not supported.
-NotSupported_WrongResourceReader_Type = This .resources file should not be read with this reader. The resource reader type is "{0}".
-NotSupported_MustBeModuleBuilder = Module argument must be a ModuleBuilder.
-NotSupported_CallToVarArg = Vararg calling convention not supported.
-NotSupported_TooManyArgs = Stack size too deep. Possibly too many arguments.
-NotSupported_DeclSecVarArg = Assert, Deny, and PermitOnly are not supported on methods with a Vararg calling convention.
-NotSupported_AmbiguousIdentity = The operation is ambiguous because the permission represents multiple identities.
-NotSupported_DynamicMethodFlags = Wrong MethodAttributes or CallingConventions for DynamicMethod. Only public, static, standard supported
-NotSupported_GlobalMethodSerialization = Serialization of global methods (including implicit serialization via the use of asynchronous delegates) is not supported.
-NotSupported_InComparableType = A type must implement IComparable<T> or IComparable to support comparison.
-NotSupported_ManagedActivation = Cannot create uninitialized instances of types requiring managed activation.
-NotSupported_ByRefReturn = ByRef return value not supported in reflection invocation.
-NotSupported_DelegateMarshalToWrongDomain = Delegates cannot be marshaled from native code into a domain other than their home domain.
-NotSupported_ResourceObjectSerialization = Cannot read resources that depend on serialization.
-NotSupported_One = The arithmetic type '{0}' cannot represent the number one.
-NotSupported_Zero = The arithmetic type '{0}' cannot represent the number zero.
-NotSupported_MaxValue = The arithmetic type '{0}' does not have a maximum value.
-NotSupported_MinValue = The arithmetic type '{0}' does not have a minimum value.
-NotSupported_PositiveInfinity = The arithmetic type '{0}' cannot represent positive infinity.
-NotSupported_NegativeInfinity = The arithmetic type '{0}' cannot represent negative infinity.
-NotSupported_UmsSafeBuffer = This operation is not supported for an UnmanagedMemoryStream created from a SafeBuffer.
-NotSupported_Reading = Accessor does not support reading.
-NotSupported_Writing = Accessor does not support writing.
-NotSupported_UnsafePointer = This accessor was created with a SafeBuffer; use the SafeBuffer to gain access to the pointer.
-NotSupported_CollectibleCOM = COM Interop is not supported for collectible types.
-NotSupported_CollectibleAssemblyResolve = Resolving to a collectible assembly is not supported.
-NotSupported_CollectibleBoundNonCollectible = A non-collectible assembly may not reference a collectible assembly.
-NotSupported_CollectibleDelegateMarshal = Delegate marshaling for types within collectible assemblies is not supported.
-NotSupported_NonStaticMethod = Non-static methods with NativeCallableAttribute are not supported.
-NotSupported_NativeCallableTarget = Methods with NativeCallableAttribute cannot be used as delegate target.
-NotSupported_GenericMethod = Generic methods with NativeCallableAttribute are not supported.
-NotSupported_NonBlittableTypes = Non-blittable parameter types are not supported for NativeCallable methods.
-
-NotSupported_UserDllImport = DllImport cannot be used on user-defined methods.
-NotSupported_UserCOM = COM Interop is not supported for user-defined types.
-
-#if FEATURE_APPX
-NotSupported_AppX = {0} is not supported in AppX.
-LoadOfFxAssemblyNotSupported_AppX = {0} of .NET Framework assemblies is not supported in AppX.
-#endif
-#if FEATURE_COMINTEROP
-NotSupported_WinRT_PartialTrust = Windows Runtime is not supported in partial trust.
-#endif // FEATURE_COMINTEROP
-; ReflectionTypeLoadException
-ReflectionTypeLoad_LoadFailed = Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
-#if FEATURE_COMINTEROP
-NotSupported_PIAInAppxProcess = A Primary Interop Assembly is not supported in AppX.
-#endif
-NotSupported_AssemblyLoadCodeBase = Assembly.Load with a Codebase is not supported.
-NotSupported_AssemblyLoadFromHash = Assembly.LoadFrom with hashValue is not supported.
-NotSupported_CannotCallEqualsOnSpan = Equals() on Span and ReadOnlySpan is not supported. Use operator== instead.
-NotSupported_CannotCallGetHashCodeOnSpan = GetHashCode() on Span and ReadOnlySpan is not supported.
-NotSupported_ReflectionOnlyLoad = Assembly.ReflectionOnlyLoad is not supported.
-NotSupported_ReflectionOnlyGetType = Type.ReflectionOnlyGetType is not supported.
-
-; TypeLoadException
-TypeLoad_ResolveType = Could not resolve type '{0}'.
-TypeLoad_ResolveTypeFromAssembly = Could not resolve type '{0}' in assembly '{1}'.
-TypeLoad_ResolveNestedType = Could not resolve nested type '{0}' in type "{1}'.
-FileNotFound_ResolveAssembly = Could not resolve assembly '{0}'.
-
-; NullReferenceException
-NullReference_This = The pointer for this method was null.
-
-; ObjectDisposedException
-ObjectDisposed_Generic = Cannot access a disposed object.
-ObjectDisposed_FileClosed = Cannot access a closed file.
-ObjectDisposed_ObjectName_Name = Object name: '{0}'.
-ObjectDisposed_ReaderClosed = Cannot read from a closed TextReader.
-ObjectDisposed_ResourceSet = Cannot access a closed resource set.
-ObjectDisposed_RegKeyClosed = Cannot access a closed registry key.
-ObjectDisposed_StreamClosed = Cannot access a closed Stream.
-ObjectDisposed_WriterClosed = Cannot write to a closed TextWriter.
-ObjectDisposed_ViewAccessorClosed = Cannot access a closed accessor.
-
-; OperationCanceledException
-OperationCanceled = The operation was canceled.
-
-; OutOfMemoryException
-OutOfMemory_GCHandleMDA = The GCHandle MDA has run out of available cookies.
-
-; OverflowException
-Overflow_Byte = Value was either too large or too small for an unsigned byte.
-Overflow_Char = Value was either too large or too small for a character.
-Overflow_Currency = Value was either too large or too small for a Currency.
-Overflow_Decimal = Value was either too large or too small for a Decimal.
-Overflow_Int16 = Value was either too large or too small for an Int16.
-Overflow_Int32 = Value was either too large or too small for an Int32.
-Overflow_Int64 = Value was either too large or too small for an Int64.
-Overflow_NegateTwosCompNum = Negating the minimum value of a twos complement number is invalid.
-Overflow_NegativeUnsigned = The string was being parsed as an unsigned number and could not have a negative sign.
-Overflow_SByte = Value was either too large or too small for a signed byte.
-Overflow_Single = Value was either too large or too small for a Single.
-Overflow_Double = Value was either too large or too small for a Double.
-Overflow_TimeSpanTooLong = TimeSpan overflowed because the duration is too long.
-Overflow_TimeSpanElementTooLarge = The TimeSpan could not be parsed because at least one of the numeric components is out of range or contains too many digits.
-Overflow_Duration = The duration cannot be returned for TimeSpan.MinValue because the absolute value of TimeSpan.MinValue exceeds the value of TimeSpan.MaxValue.
-Overflow_UInt16 = Value was either too large or too small for a UInt16.
-Overflow_UInt32 = Value was either too large or too small for a UInt32.
-Overflow_UInt64 = Value was either too large or too small for a UInt64.
-
-; PlatformNotsupportedException
-PlatformNotSupported_RequiresLonghorn = This operation is only supported on Windows Vista and above.
-PlatformNotSupported_RequiresNT = This operation is only supported on Windows 2000, Windows XP, and higher.
-PlatformNotSupported_RequiresW2kSP3 = This operation is only supported on Windows 2000 SP3 or later operating systems.
-#if FEATURE_COMINTEROP
-PlatformNotSupported_WinRT = Windows Runtime is not supported on this operating system.
-#endif // FEATURE_COMINTEROP
-
-; PolicyException
-; This still appears in bcl.small but should go away eventually
-Policy_Default = Error occurred while performing a policy operation.
-Policy_CannotLoadSemiTrustAssembliesDuringInit = All assemblies loaded as part of AppDomain initialization must be fully trusted.
-Policy_SaveNotFileBased = PolicyLevel object not based on a file cannot be saved.
-Policy_AppTrustMustGrantAppRequest = ApplicationTrust grant set does not contain ActivationContext's minimum request set.
-
-Error_SecurityPolicyFileParse = Error occurred while parsing the '{0}' policy level. The default policy level was used instead.
-Error_SecurityPolicyFileParseEx = Error '{1}' occurred while parsing the '{0}' policy level. The default policy level was used instead.
-
-; RankException
-Rank_MultiDimNotSupported = Only single dimension arrays are supported here.
-Rank_MustMatch = The specified arrays must have the same number of dimensions.
-
-; TypeInitializationException
-TypeInitialization_Default = Type constructor threw an exception.
-TypeInitialization_Type = The type initializer for '{0}' threw an exception.
-
-; TypeLoadException
-
-
-;
-; Reflection exceptions
-;
-RtType.InvalidCaller = Caller is not a friend.
-
-;CustomAttributeFormatException
-RFLCT.InvalidPropFail = '{0}' property specified was not found.
-RFLCT.InvalidFieldFail = '{0}' field specified was not found.
-
-;InvalidFilterCriteriaException
-RFLCT.FltCritString = A String must be provided for the filter criteria.
-RFLCT.FltCritInt = An Int32 must be provided for the filter criteria.
-
-; TargetException
-RFLCT.Targ_ITargMismatch = Object does not match target type.
-RFLCT.Targ_StatMethReqTarg = Non-static method requires a target.
-RFLCT.Targ_StatFldReqTarg = Non-static field requires a target.
-
-;AmbiguousMatchException
-RFLCT.Ambiguous = Ambiguous match found.
-RFLCT.AmbigCust = Multiple custom attributes of the same type found.
-
-;
-; Remoting exceptions
-;
-Remoting_AppDomainUnloaded_ThreadUnwound = The application domain in which the thread was running has been unloaded.
-Remoting_AppDomainUnloaded = The target application domain has been unloaded.
-Remoting_CantRemotePointerType = Pointer types cannot be passed in a remote call.
-Remoting_TypeCantBeRemoted = The given type cannot be passed in a remote call.
-Remoting_Delegate_TooManyTargets = The delegate must have only one target.
-Remoting_InvalidContext = The context is not valid.
-Remoting_InvalidValueTypeFieldAccess = An attempt was made to calculate the address of a value type field on a remote object. This was likely caused by an attempt to directly get or set the value of a field within this embedded value type. Avoid this and instead provide and use access methods for each field in the object that will be accessed remotely.
-Remoting_Message_BadRetValOrOutArg = Bad return value or out-argument inside the return message.
-Remoting_NonPublicOrStaticCantBeCalledRemotely = Permission denied: cannot call non-public or static methods remotely.
-Remoting_Proxy_ProxyTypeIsNotMBR = classToProxy argument must derive from MarshalByRef type.
-Remoting_TP_NonNull = The transparent proxy field of a real proxy must be null.
-
-; Resources exceptions
-;
-Resources_StreamNotValid = Stream is not a valid resource file.
-ResourceReaderIsClosed = ResourceReader is closed.
-
-; RuntimeWrappedException
-RuntimeWrappedException = An object that does not derive from System.Exception has been wrapped in a RuntimeWrappedException.
-
-; UnauthorizedAccessException
-UnauthorizedAccess_MemStreamBuffer = MemoryStream's internal buffer cannot be accessed.
-UnauthorizedAccess_IODenied_Path = Access to the path '{0}' is denied.
-UnauthorizedAccess_IODenied_NoPathName = Access to the path is denied.
-UnauthorizedAccess_RegistryKeyGeneric_Key = Access to the registry key '{0}' is denied.
-UnauthorizedAccess_RegistryNoWrite = Cannot write to the registry key.
-UnauthorizedAccess_SystemDomain = Cannot execute an assembly in the system domain.
-
-;
-; Security exceptions
-;
-
-;SecurityException
-; These still appear in bcl.small but should go away eventually
-Security_Generic = Request for the permission of type '{0}' failed.
-Security_GenericNoType = Request failed.
-Security_NoAPTCA = That assembly does not allow partially trusted callers.
-Security_RegistryPermission = Requested registry access is not allowed.
-Security_MustRevertOverride = Stack walk modifier must be reverted before another modification of the same type can be performed.
-
-;
-; HostProtection exceptions
-;
-
-HostProtection_HostProtection = Attempted to perform an operation that was forbidden by the CLR host.
-HostProtection_ProtectedResources = The protected resources (only available with full trust) were:
-HostProtection_DemandedResources = The demanded resources were:
-
-;
-; IO exceptions
-;
-
-; EOFException
-IO.EOF_ReadBeyondEOF = Unable to read beyond the end of the stream.
-
-; FileNotFoundException
-IO.FileNotFound = Unable to find the specified file.
-IO.FileNotFound_FileName = Could not find file '{0}'.
-IO.FileName_Name = File name: '{0}'
-IO.FileLoad = Could not load the specified file.
-
-; IOException
-IO.IO_AlreadyExists_Name = Cannot create "{0}" because a file or directory with the same name already exists.
-IO.IO_BindHandleFailed = BindHandle for ThreadPool failed on this handle.
-IO.IO_FileExists_Name = The file '{0}' already exists.
-IO.IO_FileStreamHandlePosition = The OS handle's position is not what FileStream expected. Do not use a handle simultaneously in one FileStream and in Win32 code or another FileStream. This may cause data loss.
-IO.IO_FileTooLong2GB = The file is too long. This operation is currently limited to supporting files less than 2 gigabytes in size.
-IO.IO_FileTooLongOrHandleNotSync = IO operation will not work. Most likely the file will become too long or the handle was not opened to support synchronous IO operations.
-IO.IO_FixedCapacity = Unable to expand length of this stream beyond its capacity.
-IO.IO_InvalidStringLen_Len = BinaryReader encountered an invalid string length of {0} characters.
-IO.IO_NoConsole = There is no console.
-IO.IO_NoPermissionToDirectoryName = <Path discovery permission to the specified directory was denied.>
-IO.IO_SeekBeforeBegin = An attempt was made to move the position before the beginning of the stream.
-IO.IO_SeekAppendOverwrite = Unable seek backward to overwrite data that previously existed in a file opened in Append mode.
-IO.IO_SetLengthAppendTruncate = Unable to truncate data that previously existed in a file opened in Append mode.
-IO.IO_SharingViolation_File = The process cannot access the file '{0}' because it is being used by another process.
-IO.IO_SharingViolation_NoFileName = The process cannot access the file because it is being used by another process.
-IO.IO_StreamTooLong = Stream was too long.
-IO.IO_CannotCreateDirectory = The specified directory '{0}' cannot be created.
-IO.IO_SourceDestMustBeDifferent = Source and destination path must be different.
-IO.IO_SourceDestMustHaveSameRoot = Source and destination path must have identical roots. Move will not work across volumes.
-
-; DirectoryNotFoundException
-IO.DriveNotFound_Drive = Could not find the drive '{0}'. The drive might not be ready or might not be mapped.
-IO.PathNotFound_Path = Could not find a part of the path '{0}'.
-IO.PathNotFound_NoPathName = Could not find a part of the path.
-
-; PathTooLongException
-IO.PathTooLong = The specified file name or path is too long, or a component of the specified path is too long.
-
-; SecurityException
-FileSecurityState_OperationNotPermitted = File operation not permitted. Access to path '{0}' is denied.
-
-; PrivilegeNotHeldException
-PrivilegeNotHeld_Default = The process does not possess some privilege required for this operation.
-PrivilegeNotHeld_Named = The process does not possess the '{0}' privilege which is required for this operation.
-
-; General strings used in the IO package
-IO_UnknownFileName = [Unknown]
-IO_StreamWriterBufferedDataLost = A StreamWriter was not closed and all buffered data within that StreamWriter was not flushed to the underlying stream. (This was detected when the StreamWriter was finalized with data in its buffer.) A portion of the data was lost. Consider one of calling Close(), Flush(), setting the StreamWriter's AutoFlush property to true, or allocating the StreamWriter with a "using" statement. Stream type: {0}\r\nFile name: {1}\r\nAllocated from:\r\n {2}
-IO_StreamWriterBufferedDataLostCaptureAllocatedFromCallstackNotEnabled = callstack information is not captured by default for performance reasons. Please enable captureAllocatedCallStack config switch for streamWriterBufferedDataLost MDA (refer to MSDN MDA documentation for how to do this).
-
-;
-; Serialization Exceptions
-;
-; SerializationException
-Serialization_InvalidData=An error occurred while deserializing the object. The serialized data is corrupt.
-Serialization_InvalidPtrValue = An IntPtr or UIntPtr with an eight byte value cannot be deserialized on a machine with a four byte word size.
-Serialization_MemberTypeNotRecognized = Unknown member type.
-Serialization_InsufficientState = Insufficient state to return the real object.
-Serialization_InvalidFieldState = Object fields may not be properly initialized.
-Serialization_MissField = Field {0} is missing.
-Serialization_NullSignature = The method signature cannot be null.
-Serialization_UnknownMember = Cannot get the member '{0}'.
-Serialization_InsufficientDeserializationState = Insufficient state to deserialize the object. Missing field '{0}'. More information is needed.
-Serialization_UnableToFindModule = The given module {0} cannot be found within the assembly {1}.
-Serialization_InvalidOnDeser = OnDeserialization method was called while the object was not being deserialized.
-Serialization_MissingKeys = The Keys for this Hashtable are missing.
-Serialization_MissingValues = The values for this dictionary are missing.
-Serialization_NullKey = One of the serialized keys is null.
-Serialization_KeyValueDifferentSizes = The keys and values arrays have different sizes.
-Serialization_SameNameTwice = Cannot add the same member twice to a SerializationInfo object.
-Serialization_BadParameterInfo = Non existent ParameterInfo. Position bigger than member's parameters length.
-Serialization_NoParameterInfo = Serialized member does not have a ParameterInfo.
-Serialization_NotFound = Member '{0}' was not found.
-Serialization_StringBuilderMaxCapacity = The serialized MaxCapacity property of StringBuilder must be positive and greater than or equal to the String length.
-Serialization_StringBuilderCapacity = The serialized Capacity property of StringBuilder must be positive, less than or equal to MaxCapacity and greater than or equal to the String length.
-Serialization_InvalidDelegateType = Cannot serialize delegates over unmanaged function pointers, dynamic methods or methods outside the delegate creator's assembly.
-Serialization_OptionalFieldVersionValue = Version value must be positive.
-Serialization_MissingDateTimeData = Invalid serialized DateTime data. Unable to find 'ticks' or 'dateData'.
-Serialization_DateTimeTicksOutOfRange = Invalid serialized DateTime data. Ticks must be between DateTime.MinValue.Ticks and DateTime.MaxValue.Ticks.
-; The following serialization exception messages appear in native resources too (mscorrc.rc)
-Serialization_MemberOutOfRange = The deserialized value of the member "{0}" in the class "{1}" is out of range.
-
-#if FEATURE_SERIALIZATION
-Serialization_NoID = Object has never been assigned an objectID.
-Serialization_UnknownMemberInfo = Only FieldInfo, PropertyInfo, and SerializationMemberInfo are recognized.
-Serialization_UnableToFixup = Cannot perform fixup.
-Serialization_NoType = Object does not specify a type.
-Serialization_ValueTypeFixup = ValueType fixup on Arrays is not implemented.
-Serialization_PartialValueTypeFixup = Fixing up a partially available ValueType chain is not implemented.
-Serialization_InvalidID = Object specifies an invalid ID.
-Serialization_DuplicateSelector = Selector is already on the list of checked selectors.
-Serialization_NoBaseType = Object does not specify a base type.
-Serialization_ArrayNoLength = Array does not specify a length.
-Serialization_CannotGetType = Cannot get the type '{0}'.
-Serialization_AssemblyNotFound = Unable to find assembly '{0}'.
-Serialization_ArrayInvalidLength = Array specifies an invalid length.
-Serialization_MalformedArray = The array information in the stream is invalid.
-Serialization_MultipleMembers = Cannot resolve multiple members with the same name.
-Serialization_ObjectUsedBeforeDeserCallback = An object was used before its deserialization callback ran, which may break higher-level consistency guarantees in the application.
-Serialization_RegisterTwice = An object cannot be registered twice.
-Serialization_IdTooSmall = Object IDs must be greater than zero.
-Serialization_TooManyReferences = The implementation of the IObjectReference interface returns too many nested references to other objects that implement IObjectReference.
-Serialization_NotISer = The given object does not implement the ISerializable interface.
-Serialization_MissingKeyValuePairs = The KeyValuePairs for this Dictionary are missing.
-Serialization_SurrogateCycleInArgument = Selector contained a cycle.
-Serialization_SurrogateCycle = Adding selector will introduce a cycle.
-Serialization_NeverSeen = A fixup is registered to the object with ID {0}, but the object does not appear in the graph.
-Serialization_IORIncomplete = The object with ID {0} implements the IObjectReference interface for which all dependencies cannot be resolved. The likely cause is two instances of IObjectReference that have a mutual dependency on each other.
-Serialization_NotCyclicallyReferenceableSurrogate = {0}.SetObjectData returns a value that is neither null nor equal to the first parameter. Such Surrogates cannot be part of cyclical reference.
-Serialization_ObjectNotSupplied = The object with ID {0} was referenced in a fixup but does not exist.
-Serialization_TooManyElements = The internal array cannot expand to greater than Int32.MaxValue elements.
-Serialization_InvalidType = Only system-provided types can be passed to the GetUninitializedObject method. '{0}' is not a valid instance of a type.
-Serialization_MissingObject = The object with ID {0} was referenced in a fixup but has not been registered.
-Serialization_InvalidFixupType = A member fixup was registered for an object which implements ISerializable or has a surrogate. In this situation, a delayed fixup must be used.
-Serialization_InvalidFixupDiscovered = A fixup on an object implementing ISerializable or having a surrogate was discovered for an object which does not have a SerializationInfo available.
-Serialization_InvalidFormat = The input stream is not a valid binary format. The starting contents (in bytes) are: {0} ...
-Serialization_ParentChildIdentical = The ID of the containing object cannot be the same as the object ID.
-Serialization_IncorrectNumberOfFixups = The ObjectManager found an invalid number of fixups. This usually indicates a problem in the Formatter.
-; The following serialization exception messages appear in native resources too (mscorrc.rc)
-Serialization_NonSerType = Type '{0}' in Assembly '{1}' is not marked as serializable.
-Serialization_ConstructorNotFound = The constructor to deserialize an object of type '{0}' was not found.
-
-; SerializationException used by Formatters
-Serialization_ArrayType = Invalid array type '{0}'.
-Serialization_ArrayTypeObject = Array element type is Object, 'dt' attribute is null.
-Serialization_Assembly = No assembly information is available for object on the wire, '{0}'.
-Serialization_AssemblyId = No assembly ID for object type '{0}'.
-Serialization_BinaryHeader = Binary stream '{0}' does not contain a valid BinaryHeader. Possible causes are invalid stream or object version change between serialization and deserialization.
-Serialization_CrossAppDomainError = Cross-AppDomain BinaryFormatter error; expected '{0}' but received '{1}'.
-Serialization_CorruptedStream = Invalid BinaryFormatter stream.
-Serialization_HeaderReflection = Header reflection error: number of value members: {0}.
-Serialization_ISerializableTypes = Types not available for ISerializable object '{0}'.
-Serialization_ISerializableMemberInfo = MemberInfo requested for ISerializable type.
-Serialization_MBRAsMBV = Type {0} must be marshaled by reference in this context.
-Serialization_Map = No map for object '{0}'.
-Serialization_MemberInfo = MemberInfo cannot be obtained for ISerialized Object '{0}'.
-Serialization_Method = Invalid MethodCall or MethodReturn stream format.
-Serialization_MissingMember = Member '{0}' in class '{1}' is not present in the serialized stream and is not marked with {2}.
-Serialization_NoMemberInfo = No MemberInfo for Object {0}.
-Serialization_ObjNoID = Object {0} has never been assigned an objectID.
-Serialization_ObjectTypeEnum = Invalid ObjectTypeEnum {0}.
-Serialization_ParseError = Parse error. Current element is not compatible with the next element, {0}.
-Serialization_SerMemberInfo = MemberInfo type {0} cannot be serialized.
-Serialization_Stream = Attempting to deserialize an empty stream.
-Serialization_StreamEnd = End of Stream encountered before parsing was completed.
-Serialization_TopObject = No top object.
-Serialization_TopObjectInstantiate = Top object cannot be instantiated for element '{0}'.
-Serialization_TypeCode = Invalid type code in stream '{0}'.
-Serialization_TypeExpected = Invalid expected type.
-Serialization_TypeMissing = Type is missing for member of type Object '{0}'.
-Serialization_TypeRead = Invalid read type request '{0}'.
-Serialization_TypeSecurity = Type {0} and the types derived from it (such as {1}) are not permitted to be deserialized at this security level.
-Serialization_TypeWrite = Invalid write type request '{0}'.
-Serialization_XMLElement = Invalid element '{0}'.
-Serialization_Security = Because of security restrictions, the type {0} cannot be accessed.
-Serialization_TypeLoadFailure = Unable to load type {0} required for deserialization.
-Serialization_RequireFullTrust = A type '{0}' that is defined in a partially trusted assembly cannot be type forwarded from an assembly with a different Public Key Token or without a public key token. To fix this, please either turn on unsafeTypeForwarding flag in the configuration file or remove the TypeForwardedFrom attribute.
-; The following serialization exception messages appear in native resources too (mscorrc.rc)
-Serialization_TypeResolved = Type is not resolved for member '{0}'.
-Serialization_MemberOutOfRange = The deserialized value of the member "{0}" in the class "{1}" is out of range.
-#endif // FEATURE_SERIALIZATION
-
-;
-; StringBuilder Exceptions
-;
-Arg_LongerThanSrcString = Source string was not long enough. Check sourceIndex and count.
-
-
-;
-; System.Threading
-;
-
-;
-; Thread Exceptions
-;
-ThreadState_NoAbortRequested = Unable to reset abort because no abort was requested.
-Threading.WaitHandleTooManyPosts = The WaitHandle cannot be signaled because it would exceed its maximum count.
-;
-; WaitHandleCannotBeOpenedException
-;
-Threading.WaitHandleCannotBeOpenedException = No handle of the given name exists.
-Threading.WaitHandleCannotBeOpenedException_InvalidHandle = A WaitHandle with system-wide name '{0}' cannot be created. A WaitHandle of a different type might have the same name.
-
-;
-; AbandonedMutexException
-;
-Threading.AbandonedMutexException = The wait completed due to an abandoned mutex.
-
-; AggregateException
-AggregateException_ctor_DefaultMessage=One or more errors occurred.
-AggregateException_ctor_InnerExceptionNull=An element of innerExceptions was null.
-AggregateException_DeserializationFailure=The serialization stream contains no inner exceptions.
-AggregateException_ToString={0}{1}---> (Inner Exception #{2}) {3}{4}{5}
-
-; Cancellation
-CancellationToken_CreateLinkedToken_TokensIsEmpty=No tokens were supplied.
-CancellationTokenSource_Disposed=The CancellationTokenSource has been disposed.
-CancellationToken_SourceDisposed=The CancellationTokenSource associated with this CancellationToken has been disposed.
-
-; Exceptions shared by all concurrent collection
-ConcurrentCollection_SyncRoot_NotSupported=The SyncRoot property may not be used for the synchronization of concurrent collections.
-
-; Exceptions shared by ConcurrentStack and ConcurrentQueue
-ConcurrentStackQueue_OnDeserialization_NoData=The serialization stream contains no elements.
-
-; ConcurrentStack<T>
-ConcurrentStack_PushPopRange_StartOutOfRange=The startIndex argument must be greater than or equal to zero.
-ConcurrentStack_PushPopRange_CountOutOfRange=The count argument must be greater than or equal to zero.
-ConcurrentStack_PushPopRange_InvalidCount=The sum of the startIndex and count arguments must be less than or equal to the collection's Count.
-
-; ConcurrentDictionary<TKey, TValue>
-ConcurrentDictionary_ItemKeyIsNull=TKey is a reference type and item.Key is null.
-ConcurrentDictionary_SourceContainsDuplicateKeys=The source argument contains duplicate keys.
-ConcurrentDictionary_IndexIsNegative=The index argument is less than zero.
-ConcurrentDictionary_ConcurrencyLevelMustBePositive=The concurrencyLevel argument must be positive.
-ConcurrentDictionary_CapacityMustNotBeNegative=The capacity argument must be greater than or equal to zero.
-ConcurrentDictionary_ArrayNotLargeEnough=The index is equal to or greater than the length of the array, or the number of elements in the dictionary is greater than the available space from index to the end of the destination array.
-ConcurrentDictionary_ArrayIncorrectType=The array is multidimensional, or the type parameter for the set cannot be cast automatically to the type of the destination array.
-ConcurrentDictionary_KeyAlreadyExisted=The key already existed in the dictionary.
-ConcurrentDictionary_TypeOfKeyIncorrect=The key was of an incorrect type for this dictionary.
-ConcurrentDictionary_TypeOfValueIncorrect=The value was of an incorrect type for this dictionary.
-
-; Partitioner
-Partitioner_DynamicPartitionsNotSupported=Dynamic partitions are not supported by this partitioner.
-
-; OrderablePartitioner
-OrderablePartitioner_GetPartitions_WrongNumberOfPartitions=GetPartitions returned an incorrect number of partitions.
-
-; PartitionerStatic
-PartitionerStatic_CurrentCalledBeforeMoveNext=MoveNext must be called at least once before calling Current.
-PartitionerStatic_CanNotCallGetEnumeratorAfterSourceHasBeenDisposed=Can not call GetEnumerator on partitions after the source enumerable is disposed
-
-; CDSCollectionETWBCLProvider events
-event_ConcurrentStack_FastPushFailed=Push to ConcurrentStack spun {0} time(s).
-event_ConcurrentStack_FastPopFailed=Pop from ConcurrentStack spun {0} time(s).
-event_ConcurrentDictionary_AcquiringAllLocks=ConcurrentDictionary acquiring all locks on {0} bucket(s).
-event_ConcurrentBag_TryTakeSteals=ConcurrentBag stealing in TryTake.
-event_ConcurrentBag_TryPeekSteals=ConcurrentBag stealing in TryPeek.
-
-; CountdownEvent
-CountdownEvent_Decrement_BelowZero=Invalid attempt made to decrement the event's count below zero.
-CountdownEvent_Increment_AlreadyZero=The event is already signaled and cannot be incremented.
-CountdownEvent_Increment_AlreadyMax=The increment operation would cause the CurrentCount to overflow.
-
-; Parallel
-Parallel_Invoke_ActionNull=One of the actions was null.
-Parallel_ForEach_OrderedPartitionerKeysNotNormalized=This method requires the use of an OrderedPartitioner with the KeysNormalized property set to true.
-Parallel_ForEach_PartitionerNotDynamic=The Partitioner used here must support dynamic partitioning.
-Parallel_ForEach_PartitionerReturnedNull=The Partitioner used here returned a null partitioner source.
-Parallel_ForEach_NullEnumerator=The Partitioner source returned a null enumerator.
-
-; Semaphore
-Argument_SemaphoreInitialMaximum=The initial count for the semaphore must be greater than or equal to zero and less than the maximum count.
-
-; SemaphoreFullException
-Threading_SemaphoreFullException=Adding the specified count to the semaphore would cause it to exceed its maximum count.
-
-; Lazy
-Lazy_ctor_ValueSelectorNull=The valueSelector argument is null.
-Lazy_ctor_InfoNull=The info argument is null.
-Lazy_ctor_deserialization_ValueInvalid=The Value cannot be null.
-Lazy_ctor_ModeInvalid=The mode argument specifies an invalid value.
-Lazy_CreateValue_NoParameterlessCtorForT=The lazily-initialized type does not have a public, parameterless constructor.
-Lazy_StaticInit_InvalidOperation=ValueFactory returned null.
-Lazy_Value_RecursiveCallsToValue=ValueFactory attempted to access the Value property of this instance.
-Lazy_ToString_ValueNotCreated=Value is not created.
-
-
-;ThreadLocal
-ThreadLocal_Value_RecursiveCallsToValue=ValueFactory attempted to access the Value property of this instance.
-ThreadLocal_Disposed=The ThreadLocal object has been disposed.
-ThreadLocal_ValuesNotAvailable=The ThreadLocal object is not tracking values. To use the Values property, use a ThreadLocal constructor that accepts the trackAllValues parameter and set the parameter to true.
-
-; SemaphoreSlim
-SemaphoreSlim_ctor_InitialCountWrong=The initialCount argument must be non-negative and less than or equal to the maximumCount.
-SemaphoreSlim_ctor_MaxCountWrong=The maximumCount argument must be a positive number. If a maximum is not required, use the constructor without a maxCount parameter.
-SemaphoreSlim_Wait_TimeoutWrong=The timeout must represent a value between -1 and Int32.MaxValue, inclusive.
-SemaphoreSlim_Release_CountWrong=The releaseCount argument must be greater than zero.
-SemaphoreSlim_Disposed=The semaphore has been disposed.
-
-; ManualResetEventSlim
-ManualResetEventSlim_ctor_SpinCountOutOfRange=The spinCount argument must be in the range 0 to {0}, inclusive.
-ManualResetEventSlim_ctor_TooManyWaiters=There are too many threads currently waiting on the event. A maximum of {0} waiting threads are supported.
-ManualResetEventSlim_Disposed=The event has been disposed.
-
-; SpinLock
-SpinLock_TryEnter_ArgumentOutOfRange=The timeout must be a value between -1 and Int32.MaxValue, inclusive.
-SpinLock_TryEnter_LockRecursionException=The calling thread already holds the lock.
-SpinLock_TryReliableEnter_ArgumentException=The tookLock argument must be set to false before calling this method.
-SpinLock_Exit_SynchronizationLockException=The calling thread does not hold the lock.
-SpinLock_IsHeldByCurrentThread=Thread tracking is disabled.
-
-; SpinWait
-SpinWait_SpinUntil_TimeoutWrong=The timeout must represent a value between -1 and Int32.MaxValue, inclusive.
-SpinWait_SpinUntil_ArgumentNull=The condition argument is null.
-
-; CdsSyncEtwBCLProvider events
-event_SpinLock_FastPathFailed=SpinLock beginning to spin.
-event_SpinWait_NextSpinWillYield=Next spin will yield.
-event_Barrier_PhaseFinished=Barrier finishing phase {1}.
-
-#if PLATFORM_UNIX
-; Unix threading
-PlatformNotSupported_NamedSynchronizationPrimitives=The named version of this synchronization primitive is not supported on this platform.
-PlatformNotSupported_NamedSyncObjectWaitAnyWaitAll=Wait operations on multiple wait handles including a named synchronization primitive are not supported on this platform.
-#endif
-
-;
-; System.Threading.Tasks
-;
-
-; AsyncMethodBuilder
-AsyncMethodBuilder_InstanceNotInitialized=The builder was not properly initialized.
-
-; TaskAwaiter and YieldAwaitable
-AwaitableAwaiter_InstanceNotInitialized=The awaitable or awaiter was not properly initialized.
-TaskAwaiter_TaskNotCompleted=The awaited task has not yet completed.
-
-; Task<T>
-TaskT_SetException_HasAnInitializer=A task's Exception may only be set directly if the task was created without a function.
-TaskT_TransitionToFinal_AlreadyCompleted=An attempt was made to transition a task to a final state when it had already completed.
-TaskT_ctor_SelfReplicating=It is invalid to specify TaskCreationOptions.SelfReplicating for a Task<TResult>.
-TaskT_DebuggerNoResult={Not yet computed}
-
-; Task
-Task_ctor_LRandSR=(Internal)An attempt was made to create a LongRunning SelfReplicating task.
-Task_ThrowIfDisposed=The task has been disposed.
-Task_Dispose_NotCompleted=A task may only be disposed if it is in a completion state (RanToCompletion, Faulted or Canceled).
-Task_Start_Promise=Start may not be called on a promise-style task.
-Task_Start_AlreadyStarted=Start may not be called on a task that was already started.
-Task_Start_TaskCompleted=Start may not be called on a task that has completed.
-Task_Start_ContinuationTask=Start may not be called on a continuation task.
-Task_RunSynchronously_AlreadyStarted=RunSynchronously may not be called on a task that was already started.
-Task_RunSynchronously_TaskCompleted=RunSynchronously may not be called on a task that has already completed.
-Task_RunSynchronously_Promise=RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.
-Task_RunSynchronously_Continuation=RunSynchronously may not be called on a continuation task.
-Task_ContinueWith_NotOnAnything=The specified TaskContinuationOptions excluded all continuation kinds.
-Task_ContinueWith_ESandLR=The specified TaskContinuationOptions combined LongRunning and ExecuteSynchronously. Synchronous continuations should not be long running.
-Task_MultiTaskContinuation_NullTask=The tasks argument included a null value.
-Task_MultiTaskContinuation_FireOptions=It is invalid to exclude specific continuation kinds for continuations off of multiple tasks.
-Task_MultiTaskContinuation_EmptyTaskList=The tasks argument contains no tasks.
-Task_FromAsync_TaskManagerShutDown=FromAsync was called with a TaskManager that had already shut down.
-Task_FromAsync_SelfReplicating=It is invalid to specify TaskCreationOptions.SelfReplicating in calls to FromAsync.
-Task_FromAsync_LongRunning=It is invalid to specify TaskCreationOptions.LongRunning in calls to FromAsync.
-Task_FromAsync_PreferFairness=It is invalid to specify TaskCreationOptions.PreferFairness in calls to FromAsync.
-Task_WaitMulti_NullTask=The tasks array included at least one null element.
-Task_Delay_InvalidMillisecondsDelay=The value needs to be either -1 (signifying an infinite timeout), 0 or a positive integer.
-Task_Delay_InvalidDelay=The value needs to translate in milliseconds to -1 (signifying an infinite timeout), 0 or a positive integer less than or equal to Int32.MaxValue.
-
-; TaskCanceledException
-TaskCanceledException_ctor_DefaultMessage=A task was canceled.
-
-;TaskCompletionSource<T>
-TaskCompletionSourceT_TrySetException_NullException=The exceptions collection included at least one null element.
-TaskCompletionSourceT_TrySetException_NoExceptions=The exceptions collection was empty.
-
-;TaskExceptionHolder
-TaskExceptionHolder_UnknownExceptionType=(Internal)Expected an Exception or an IEnumerable<Exception>
-TaskExceptionHolder_UnhandledException=A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread.
-
-; TaskScheduler
-TaskScheduler_ExecuteTask_TaskAlreadyExecuted=ExecuteTask may not be called for a task which was already executed.
-TaskScheduler_ExecuteTask_WrongTaskScheduler=ExecuteTask may not be called for a task which was previously queued to a different TaskScheduler.
-TaskScheduler_InconsistentStateAfterTryExecuteTaskInline=The TryExecuteTaskInline call to the underlying scheduler succeeded, but the task body was not invoked.
-TaskScheduler_FromCurrentSynchronizationContext_NoCurrent=The current SynchronizationContext may not be used as a TaskScheduler.
-
-; TaskSchedulerException
-TaskSchedulerException_ctor_DefaultMessage=An exception was thrown by a TaskScheduler.
-
-;
-; ParallelState ( used in Parallel.For(), Parallel.ForEach() )
-ParallelState_Break_InvalidOperationException_BreakAfterStop=Break was called after Stop was called.
-ParallelState_Stop_InvalidOperationException_StopAfterBreak=Stop was called after Break was called.
-ParallelState_NotSupportedException_UnsupportedMethod=This method is not supported.
-
-;
-; TPLETWProvider events
-event_ParallelLoopBegin=Beginning {3} loop {2} from Task {1}.
-event_ParallelLoopEnd=Ending loop {2} after {3} iterations.
-event_ParallelInvokeBegin=Beginning ParallelInvoke {2} from Task {1} for {4} actions.
-event_ParallelInvokeEnd=Ending ParallelInvoke {2}.
-event_ParallelFork=Task {1} entering fork/join {2}.
-event_ParallelJoin=Task {1} leaving fork/join {2}.
-event_TaskScheduled=Task {2} scheduled to TaskScheduler {0}.
-event_TaskStarted=Task {2} executing.
-event_TaskCompleted=Task {2} completed.
-event_TaskWaitBegin=Beginning wait ({3}) on Task {2}.
-event_TaskWaitEnd=Ending wait on Task {2}.
-
-
-;
-; Weak Reference Exception
-;
-WeakReference_NoLongerValid = The weak reference is no longer valid.
-
-
-;
-; Interop Exceptions
-;
-Interop.COM_TypeMismatch = Type mismatch between source and destination types.
-Interop_Marshal_Unmappable_Char = Cannot marshal: Encountered unmappable character.
-
-;
-; Loader Exceptions
-;
-Loader_InvalidPath = Relative path must be a string that contains the substring, "..", or does not contain a root directory.
-Loader_Name = Name:
-Loader_NoContextPolicies = There are no context policies.
-Loader_ContextPolicies = Context Policies:
-
-;
-; AppDomain Exceptions
-AppDomain_RequireApplicationName = ApplicationName must be set before the DynamicBase can be set.
-AppDomain_AppBaseNotSet = The ApplicationBase must be set before retrieving this property.
-AppDomain_BindingModelIsLocked = Binding model is already locked for the AppDomain and cannot be reset.
-Argument_CustomAssemblyLoadContextRequestedNameMismatch = Resolved assembly's simple name should be the same as of the requested assembly.
-
-;
-; XMLSyntaxExceptions
-XMLSyntax_UnexpectedEndOfFile = Unexpected end of file.
-XMLSyntax_ExpectedCloseBracket = Expected > character.
-XMLSyntax_ExpectedSlashOrString = Expected / character or string.
-XMLSyntax_UnexpectedCloseBracket = Unexpected > character.
-XMLSyntax_SyntaxError = Invalid syntax on line {0}.
-XMLSyntax_SyntaxErrorEx = Invalid syntax on line {0} - '{1}'.
-XMLSyntax_InvalidSyntax = Invalid syntax.
-XML_Syntax_InvalidSyntaxInFile = Invalid XML in file '{0}' near element '{1}'.
-XMLSyntax_InvalidSyntaxSatAssemTag = Invalid XML in file "{0}" near element "{1}". The <satelliteassemblies> section only supports <assembly> tags.
-XMLSyntax_InvalidSyntaxSatAssemTagBadAttr = Invalid XML in file "{0}" near "{1}" and "{2}". In the <satelliteassemblies> section, the <assembly> tag must have exactly 1 attribute called 'name', whose value is a fully-qualified assembly name.
-XMLSyntax_InvalidSyntaxSatAssemTagNoAttr = Invalid XML in file "{0}". In the <satelliteassemblies> section, the <assembly> tag must have exactly 1 attribute called 'name', whose value is a fully-qualified assembly name.
-
-; MembershipConditions
-StrongName_ToString = StrongName - {0}{1}{2}
-StrongName_Name = name = {0}
-StrongName_Version = version = {0}
-Site_ToString = Site
-Publisher_ToString = Publisher
-Hash_ToString = Hash - {0} = {1}
-ApplicationDirectory_ToString = ApplicationDirectory
-Zone_ToString = Zone - {0}
-All_ToString = All code
-Url_ToString = Url
-GAC_ToString = GAC
-
-; Interop non exception strings.
-TypeLibConverter_ImportedTypeLibProductName = Assembly imported from type library '{0}'.
-
-;
-; begin System.TimeZoneInfo ArgumentException's
-;
-Argument_AdjustmentRulesNoNulls = The AdjustmentRule array cannot contain null elements.
-Argument_AdjustmentRulesOutOfOrder = The elements of the AdjustmentRule array must be in chronological order and must not overlap.
-Argument_AdjustmentRulesAmbiguousOverlap = The elements of the AdjustmentRule array must not contain ambiguous time periods that extend beyond the DateStart or DateEnd properties of the element.
-Argument_AdjustmentRulesrDaylightSavingTimeOverlap = The elements of the AdjustmentRule array must not contain Daylight Saving Time periods that overlap adjacent elements in such a way as to cause invalid or ambiguous time periods.
-Argument_AdjustmentRulesrDaylightSavingTimeOverlapNonRuleRange = The elements of the AdjustmentRule array must not contain Daylight Saving Time periods that overlap the DateStart or DateEnd properties in such a way as to cause invalid or ambiguous time periods.
-Argument_AdjustmentRulesInvalidOverlap = The elements of the AdjustmentRule array must not contain invalid time periods that extend beyond the DateStart or DateEnd properties of the element.
-Argument_ConvertMismatch = The conversion could not be completed because the supplied DateTime did not have the Kind property set correctly. For example, when the Kind property is DateTimeKind.Local, the source time zone must be TimeZoneInfo.Local.
-Argument_DateTimeHasTimeOfDay = The supplied DateTime includes a TimeOfDay setting. This is not supported.
-Argument_DateTimeIsInvalid = The supplied DateTime represents an invalid time. For example, when the clock is adjusted forward, any time in the period that is skipped is invalid.
-Argument_DateTimeIsNotAmbiguous = The supplied DateTime is not in an ambiguous time range.
-Argument_DateTimeOffsetIsNotAmbiguous = The supplied DateTimeOffset is not in an ambiguous time range.
-Argument_DateTimeKindMustBeUnspecifiedOrUtc = The supplied DateTime must have the Kind property set to DateTimeKind.Unspecified or DateTimeKind.Utc.
-Argument_DateTimeHasTicks = The supplied DateTime must have the Year, Month, and Day properties set to 1. The time cannot be specified more precisely than whole milliseconds.
-Argument_InvalidId = The specified ID parameter '{0}' is not supported.
-Argument_InvalidSerializedString = The specified serialized string '{0}' is not supported.
-Argument_InvalidREG_TZI_FORMAT = The REG_TZI_FORMAT structure is corrupt.
-Argument_OutOfOrderDateTimes = The DateStart property must come before the DateEnd property.
-Argument_TimeSpanHasSeconds = The TimeSpan parameter cannot be specified more precisely than whole minutes.
-Argument_TimeZoneInfoBadTZif = The tzfile does not begin with the magic characters 'TZif'. Please verify that the file is not corrupt.
-Argument_TimeZoneInfoInvalidTZif = The TZif data structure is corrupt.
-Argument_TransitionTimesAreIdentical = The DaylightTransitionStart property must not equal the DaylightTransitionEnd property.
-;
-; begin System.TimeZoneInfo ArgumentOutOfRangeException's
-;
-ArgumentOutOfRange_DayParam = The Day parameter must be in the range 1 through 31.
-ArgumentOutOfRange_DayOfWeek = The DayOfWeek enumeration must be in the range 0 through 6.
-ArgumentOutOfRange_MonthParam = The Month parameter must be in the range 1 through 12.
-ArgumentOutOfRange_UtcOffset = The TimeSpan parameter must be within plus or minus 14.0 hours.
-ArgumentOutOfRange_UtcOffsetAndDaylightDelta = The sum of the BaseUtcOffset and DaylightDelta properties must within plus or minus 14.0 hours.
-ArgumentOutOfRange_Week = The Week parameter must be in the range 1 through 5.
-;
-; begin System.TimeZoneInfo InvalidTimeZoneException's
-;
-InvalidTimeZone_InvalidRegistryData = The time zone ID '{0}' was found on the local computer, but the registry information was corrupt.
-InvalidTimeZone_InvalidFileData = The time zone ID '{0}' was found on the local computer, but the file at '{1}' was corrupt.
-InvalidTimeZone_InvalidWin32APIData = The Local time zone was found on the local computer, but the data was corrupt.
-InvalidTimeZone_NoTTInfoStructures = There are no ttinfo structures in the tzfile. At least one ttinfo structure is required in order to construct a TimeZoneInfo object.
-InvalidTimeZone_UnparseablePosixMDateString = '{0}' is not a valid POSIX-TZ-environment-variable MDate rule. A valid rule has the format 'Mm.w.d'.
-InvalidTimeZone_JulianDayNotSupported = Julian dates in POSIX strings are unsupported.
-;
-; begin System.TimeZoneInfo SecurityException's
-;
-Security_CannotReadRegistryData = The time zone ID '{0}' was found on the local computer, but the application does not have permission to read the registry information.
-Security_CannotReadFileData = The time zone ID '{0}' was found on the local computer, but the application does not have permission to read the file.
-;
-; begin System.TimeZoneInfo SerializationException's
-;
-Serialization_CorruptField = The value of the field '{0}' is invalid. The serialized data is corrupt.
-Serialization_InvalidEscapeSequence = The serialized data contained an invalid escape sequence '\\{0}'.
-;
-; begin System.TimeZoneInfo TimeZoneNotFoundException's
-;
-TimeZoneNotFound_MissingData = The time zone ID '{0}' was not found on the local computer.
-;
-; end System.TimeZoneInfo
-;
-
-
-; Tuple
-ArgumentException_TupleIncorrectType=Argument must be of type {0}.
-ArgumentException_TupleNonIComparableElement=The tuple contains an element of type {0} which does not implement the IComparable interface.
-ArgumentException_TupleLastArgumentNotATuple=The last element of an eight element tuple must be a Tuple.
-ArgumentException_OtherNotArrayOfCorrectLength=Object is not a array with the same number of elements as the array to compare it to.
-
-; WinRT collection adapters
-Argument_IndexOutOfArrayBounds=The specified index is out of bounds of the specified array.
-Argument_InsufficientSpaceToCopyCollection=The specified space is not sufficient to copy the elements from this Collection.
-ArgumentOutOfRange_IndexLargerThanMaxValue=This collection cannot work with indices larger than Int32.MaxValue - 1 (0x7FFFFFFF - 1).
-ArgumentOutOfRange_IndexOutOfRange=The specified index is outside the current index range of this collection.
-InvalidOperation_CollectionBackingListTooLarge=The collection backing this List contains too many elements.
-InvalidOperation_CollectionBackingDictionaryTooLarge=The collection backing this Dictionary contains too many elements.
-InvalidOperation_CannotRemoveLastFromEmptyCollection=Cannot remove the last element from an empty collection.
-
-; Buffers
-ArgumentException_BufferNotFromPool=The buffer is not associated with this pool and may not be returned to it.
-
-;------------------
-; Encoding names:
-;
-;Total items: 147
-;
-Globalization.cp_1200 = Unicode
-Globalization.cp_1201 = Unicode (Big-Endian)
-Globalization.cp_65001 = Unicode (UTF-8)
-Globalization.cp_65000 = Unicode (UTF-7)
-Globalization.cp_12000 = Unicode (UTF-32)
-Globalization.cp_12001 = Unicode (UTF-32 Big-Endian)
-Globalization.cp_20127 = US-ASCII
-Globalization.cp_28591 = Western European (ISO)
-
-#if FEATURE_NON_UNICODE_CODE_PAGES
-Globalization.cp_37 = IBM EBCDIC (US-Canada)
-Globalization.cp_437 = OEM United States
-Globalization.cp_500 = IBM EBCDIC (International)
-Globalization.cp_708 = Arabic (ASMO 708)
-Globalization.cp_720 = Arabic (DOS)
-Globalization.cp_737 = Greek (DOS)
-Globalization.cp_775 = Baltic (DOS)
-Globalization.cp_850 = Western European (DOS)
-Globalization.cp_852 = Central European (DOS)
-Globalization.cp_855 = OEM Cyrillic
-Globalization.cp_857 = Turkish (DOS)
-Globalization.cp_858 = OEM Multilingual Latin I
-Globalization.cp_860 = Portuguese (DOS)
-Globalization.cp_861 = Icelandic (DOS)
-Globalization.cp_862 = Hebrew (DOS)
-Globalization.cp_863 = French Canadian (DOS)
-Globalization.cp_864 = Arabic (864)
-Globalization.cp_865 = Nordic (DOS)
-Globalization.cp_866 = Cyrillic (DOS)
-Globalization.cp_869 = Greek, Modern (DOS)
-Globalization.cp_870 = IBM EBCDIC (Multilingual Latin-2)
-Globalization.cp_874 = Thai (Windows)
-Globalization.cp_875 = IBM EBCDIC (Greek Modern)
-Globalization.cp_932 = Japanese (Shift-JIS)
-Globalization.cp_936 = Chinese Simplified (GB2312)
-Globalization.cp_949 = Korean
-Globalization.cp_950 = Chinese Traditional (Big5)
-Globalization.cp_1026 = IBM EBCDIC (Turkish Latin-5)
-Globalization.cp_1047 = IBM Latin-1
-Globalization.cp_1140 = IBM EBCDIC (US-Canada-Euro)
-Globalization.cp_1141 = IBM EBCDIC (Germany-Euro)
-Globalization.cp_1142 = IBM EBCDIC (Denmark-Norway-Euro)
-Globalization.cp_1143 = IBM EBCDIC (Finland-Sweden-Euro)
-Globalization.cp_1144 = IBM EBCDIC (Italy-Euro)
-Globalization.cp_1145 = IBM EBCDIC (Spain-Euro)
-Globalization.cp_1146 = IBM EBCDIC (UK-Euro)
-Globalization.cp_1147 = IBM EBCDIC (France-Euro)
-Globalization.cp_1148 = IBM EBCDIC (International-Euro)
-Globalization.cp_1149 = IBM EBCDIC (Icelandic-Euro)
-Globalization.cp_1250 = Central European (Windows)
-Globalization.cp_1251 = Cyrillic (Windows)
-Globalization.cp_1252 = Western European (Windows)
-Globalization.cp_1253 = Greek (Windows)
-Globalization.cp_1254 = Turkish (Windows)
-Globalization.cp_1255 = Hebrew (Windows)
-Globalization.cp_1256 = Arabic (Windows)
-Globalization.cp_1257 = Baltic (Windows)
-Globalization.cp_1258 = Vietnamese (Windows)
-Globalization.cp_1361 = Korean (Johab)
-Globalization.cp_10000 = Western European (Mac)
-Globalization.cp_10001 = Japanese (Mac)
-Globalization.cp_10002 = Chinese Traditional (Mac)
-Globalization.cp_10003 = Korean (Mac)
-Globalization.cp_10004 = Arabic (Mac)
-Globalization.cp_10005 = Hebrew (Mac)
-Globalization.cp_10006 = Greek (Mac)
-Globalization.cp_10007 = Cyrillic (Mac)
-Globalization.cp_10008 = Chinese Simplified (Mac)
-Globalization.cp_10010 = Romanian (Mac)
-Globalization.cp_10017 = Ukrainian (Mac)
-Globalization.cp_10021 = Thai (Mac)
-Globalization.cp_10029 = Central European (Mac)
-Globalization.cp_10079 = Icelandic (Mac)
-Globalization.cp_10081 = Turkish (Mac)
-Globalization.cp_10082 = Croatian (Mac)
-Globalization.cp_20000 = Chinese Traditional (CNS)
-Globalization.cp_20001 = TCA Taiwan
-Globalization.cp_20002 = Chinese Traditional (Eten)
-Globalization.cp_20003 = IBM5550 Taiwan
-Globalization.cp_20004 = TeleText Taiwan
-Globalization.cp_20005 = Wang Taiwan
-Globalization.cp_20105 = Western European (IA5)
-Globalization.cp_20106 = German (IA5)
-Globalization.cp_20107 = Swedish (IA5)
-Globalization.cp_20108 = Norwegian (IA5)
-Globalization.cp_20261 = T.61
-Globalization.cp_20269 = ISO-6937
-Globalization.cp_20273 = IBM EBCDIC (Germany)
-Globalization.cp_20277 = IBM EBCDIC (Denmark-Norway)
-Globalization.cp_20278 = IBM EBCDIC (Finland-Sweden)
-Globalization.cp_20280 = IBM EBCDIC (Italy)
-Globalization.cp_20284 = IBM EBCDIC (Spain)
-Globalization.cp_20285 = IBM EBCDIC (UK)
-Globalization.cp_20290 = IBM EBCDIC (Japanese katakana)
-Globalization.cp_20297 = IBM EBCDIC (France)
-Globalization.cp_20420 = IBM EBCDIC (Arabic)
-Globalization.cp_20423 = IBM EBCDIC (Greek)
-Globalization.cp_20424 = IBM EBCDIC (Hebrew)
-Globalization.cp_20833 = IBM EBCDIC (Korean Extended)
-Globalization.cp_20838 = IBM EBCDIC (Thai)
-Globalization.cp_20866 = Cyrillic (KOI8-R)
-Globalization.cp_20871 = IBM EBCDIC (Icelandic)
-Globalization.cp_20880 = IBM EBCDIC (Cyrillic Russian)
-Globalization.cp_20905 = IBM EBCDIC (Turkish)
-Globalization.cp_20924 = IBM Latin-1
-Globalization.cp_20932 = Japanese (JIS 0208-1990 and 0212-1990)
-Globalization.cp_20936 = Chinese Simplified (GB2312-80)
-Globalization.cp_20949 = Korean Wansung
-Globalization.cp_21025 = IBM EBCDIC (Cyrillic Serbian-Bulgarian)
-Globalization.cp_21027 = Ext Alpha Lowercase
-Globalization.cp_21866 = Cyrillic (KOI8-U)
-Globalization.cp_28592 = Central European (ISO)
-Globalization.cp_28593 = Latin 3 (ISO)
-Globalization.cp_28594 = Baltic (ISO)
-Globalization.cp_28595 = Cyrillic (ISO)
-Globalization.cp_28596 = Arabic (ISO)
-Globalization.cp_28597 = Greek (ISO)
-Globalization.cp_28598 = Hebrew (ISO-Visual)
-Globalization.cp_28599 = Turkish (ISO)
-Globalization.cp_28603 = Estonian (ISO)
-Globalization.cp_28605 = Latin 9 (ISO)
-Globalization.cp_29001 = Europa
-Globalization.cp_38598 = Hebrew (ISO-Logical)
-Globalization.cp_50000 = User Defined
-Globalization.cp_50220 = Japanese (JIS)
-Globalization.cp_50221 = Japanese (JIS-Allow 1 byte Kana)
-Globalization.cp_50222 = Japanese (JIS-Allow 1 byte Kana - SO/SI)
-Globalization.cp_50225 = Korean (ISO)
-Globalization.cp_50227 = Chinese Simplified (ISO-2022)
-Globalization.cp_50229 = Chinese Traditional (ISO-2022)
-Globalization.cp_50930 = IBM EBCDIC (Japanese and Japanese Katakana)
-Globalization.cp_50931 = IBM EBCDIC (Japanese and US-Canada)
-Globalization.cp_50933 = IBM EBCDIC (Korean and Korean Extended)
-Globalization.cp_50935 = IBM EBCDIC (Simplified Chinese)
-Globalization.cp_50937 = IBM EBCDIC (Traditional Chinese)
-Globalization.cp_50939 = IBM EBCDIC (Japanese and Japanese-Latin)
-Globalization.cp_51932 = Japanese (EUC)
-Globalization.cp_51936 = Chinese Simplified (EUC)
-Globalization.cp_51949 = Korean (EUC)
-Globalization.cp_52936 = Chinese Simplified (HZ)
-Globalization.cp_54936 = Chinese Simplified (GB18030)
-Globalization.cp_57002 = ISCII Devanagari
-Globalization.cp_57003 = ISCII Bengali
-Globalization.cp_57004 = ISCII Tamil
-Globalization.cp_57005 = ISCII Telugu
-Globalization.cp_57006 = ISCII Assamese
-Globalization.cp_57007 = ISCII Oriya
-Globalization.cp_57008 = ISCII Kannada
-Globalization.cp_57009 = ISCII Malayalam
-Globalization.cp_57010 = ISCII Gujarati
-Globalization.cp_57011 = ISCII Punjabi
-#endif // FEATURE_NON_UNICODE_CODE_PAGES
-#endif // INCLUDE_DEBUG
-
-;------------------
-
-; ValueTuple
-ArgumentException_ValueTupleIncorrectType=Argument must be of type {0}.
-ArgumentException_ValueTupleLastArgumentNotAValueTuple=The last element of an eight element ValueTuple must be a ValueTuple.
diff --git a/src/mscorlib/src/System/Action.cs b/src/mscorlib/src/System/Action.cs
deleted file mode 100644
index 23c7e93194..0000000000
--- a/src/mscorlib/src/System/Action.cs
+++ /dev/null
@@ -1,35 +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.
-
-namespace System
-{
- public delegate void Action<in T>(T obj);
-
- public delegate void Action();
- public delegate void Action<in T1,in T2>(T1 arg1, T2 arg2);
- public delegate void Action<in T1,in T2,in T3>(T1 arg1, T2 arg2, T3 arg3);
- public delegate void Action<in T1,in T2,in T3,in T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
-
- public delegate TResult Func<out TResult>();
- public delegate TResult Func<in T, out TResult>(T arg);
- public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
- public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);
- public delegate TResult Func<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
-
- public delegate void Action<in T1,in T2,in T3,in T4,in T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
- public delegate void Action<in T1,in T2,in T3,in T4,in T5,in T6>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
- public delegate void Action<in T1,in T2,in T3,in T4,in T5,in T6,in T7>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
- public delegate void Action<in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
-
- public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
- public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
- public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
- public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
-
- public delegate int Comparison<in T>(T x, T y);
-
- public delegate TOutput Converter<in TInput, out TOutput>(TInput input);
-
- public delegate bool Predicate<in T>(T obj);
-}
diff --git a/src/mscorlib/src/System/Activator.cs b/src/mscorlib/src/System/Activator.cs
index 323fbba9cc..34c6ea5874 100644
--- a/src/mscorlib/src/System/Activator.cs
+++ b/src/mscorlib/src/System/Activator.cs
@@ -11,8 +11,9 @@
//
//
//
-namespace System {
+namespace System
+{
using System;
using System.Reflection;
using System.Runtime.Remoting;
@@ -29,9 +30,9 @@ namespace System {
// Only statics, does not need to be marked with the serializable attribute
public sealed class Activator
{
- internal const int LookupMask = 0x000000FF;
- internal const BindingFlags ConLookup = (BindingFlags) (BindingFlags.Instance | BindingFlags.Public);
- internal const BindingFlags ConstructorDefault= BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance;
+ internal const int LookupMask = 0x000000FF;
+ internal const BindingFlags ConLookup = (BindingFlags)(BindingFlags.Instance | BindingFlags.Public);
+ internal const BindingFlags ConstructorDefault = BindingFlags.Instance | BindingFlags.Public | BindingFlags.CreateInstance;
// This class only contains statics, so hide the worthless constructor
private Activator()
@@ -47,12 +48,12 @@ namespace System {
BindingFlags bindingAttr,
Binder binder,
Object[] args,
- CultureInfo culture)
+ CultureInfo culture)
{
return CreateInstance(type, bindingAttr, binder, args, culture, null);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
static public Object CreateInstance(Type type,
BindingFlags bindingAttr,
Binder binder,
@@ -65,23 +66,24 @@ namespace System {
Contract.EndContractBlock();
if (type is System.Reflection.Emit.TypeBuilder)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_CreateInstanceWithTypeBuilder"));
+ throw new NotSupportedException(SR.NotSupported_CreateInstanceWithTypeBuilder);
// If they didn't specify a lookup, then we will provide the default lookup.
- if ((bindingAttr & (BindingFlags) LookupMask) == 0)
+ if ((bindingAttr & (BindingFlags)LookupMask) == 0)
bindingAttr |= Activator.ConstructorDefault;
- if (activationAttributes != null && activationAttributes.Length > 0){
- throw new PlatformNotSupportedException(Environment.GetResourceString("NotSupported_ActivAttr" ));
+ if (activationAttributes != null && activationAttributes.Length > 0)
+ {
+ throw new PlatformNotSupportedException(SR.NotSupported_ActivAttr);
}
RuntimeType rt = type.UnderlyingSystemType as RuntimeType;
if (rt == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(type));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(type));
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return rt.CreateInstanceImpl(bindingAttr,binder,args,culture,activationAttributes, ref stackMark);
+ return rt.CreateInstanceImpl(bindingAttr, binder, args, culture, activationAttributes, ref stackMark);
}
static public Object CreateInstance(Type type, params Object[] args)
@@ -98,14 +100,14 @@ namespace System {
Object[] args,
Object[] activationAttributes)
{
- return CreateInstance(type,
- Activator.ConstructorDefault,
- null,
- args,
- null,
- activationAttributes);
+ return CreateInstance(type,
+ Activator.ConstructorDefault,
+ null,
+ args,
+ null,
+ activationAttributes);
}
-
+
static public Object CreateInstance(Type type)
{
return Activator.CreateInstance(type, false);
@@ -116,13 +118,13 @@ namespace System {
* types to be created remotely without having to load the type locally.
*/
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
static public ObjectHandle CreateInstance(String assemblyName,
String typeName)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return CreateInstance(assemblyName,
- typeName,
+ typeName,
false,
Activator.ConstructorDefault,
null,
@@ -133,15 +135,15 @@ namespace System {
ref stackMark);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
static public ObjectHandle CreateInstance(String assemblyName,
String typeName,
Object[] activationAttributes)
-
+
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return CreateInstance(assemblyName,
- typeName,
+ typeName,
false,
Activator.ConstructorDefault,
null,
@@ -151,8 +153,8 @@ namespace System {
null,
ref stackMark);
}
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
static public Object CreateInstance(Type type, bool nonPublic)
{
if ((object)type == null)
@@ -162,13 +164,13 @@ namespace System {
RuntimeType rt = type.UnderlyingSystemType as RuntimeType;
if (rt == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(type));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(type));
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
return rt.CreateInstanceDefaultCtor(!nonPublic, false, true, ref stackMark);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
static public T CreateInstance<T>()
{
RuntimeType rt = typeof(T) as RuntimeType;
@@ -176,7 +178,7 @@ namespace System {
// This is a workaround to maintain compatibility with V2. Without this we would throw a NotSupportedException for void[].
// Array, Ref, and Pointer types don't have default constructors.
if (rt.HasElementType)
- throw new MissingMethodException(Environment.GetResourceString("Arg_NoDefCTor"));
+ throw new MissingMethodException(SR.Arg_NoDefCTor);
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -186,7 +188,7 @@ namespace System {
static public ObjectHandle CreateInstanceFrom(String assemblyFile,
String typeName)
-
+
{
return CreateInstanceFrom(assemblyFile, typeName, null);
}
@@ -194,10 +196,10 @@ namespace System {
static public ObjectHandle CreateInstanceFrom(String assemblyFile,
String typeName,
Object[] activationAttributes)
-
+
{
return CreateInstanceFrom(assemblyFile,
- typeName,
+ typeName,
false,
Activator.ConstructorDefault,
null,
@@ -206,7 +208,7 @@ namespace System {
activationAttributes);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public static ObjectHandle CreateInstance(string assemblyName,
string typeName,
bool ignoreCase,
@@ -229,10 +231,10 @@ namespace System {
ref stackMark);
}
- static internal ObjectHandle CreateInstance(String assemblyString,
- String typeName,
+ static internal ObjectHandle CreateInstance(String assemblyString,
+ String typeName,
bool ignoreCase,
- BindingFlags bindingAttr,
+ BindingFlags bindingAttr,
Binder binder,
Object[] args,
CultureInfo culture,
@@ -242,18 +244,26 @@ namespace System {
{
Type type = null;
Assembly assembly = null;
- if (assemblyString == null) {
+ if (assemblyString == null)
+ {
assembly = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
- } else {
+ }
+ else
+ {
RuntimeAssembly assemblyFromResolveEvent;
AssemblyName assemblyName = RuntimeAssembly.CreateAssemblyName(assemblyString, false /*forIntrospection*/, out assemblyFromResolveEvent);
- if (assemblyFromResolveEvent != null) {
+ if (assemblyFromResolveEvent != null)
+ {
// Assembly was resolved via AssemblyResolve event
assembly = assemblyFromResolveEvent;
- } else if (assemblyName.ContentType == AssemblyContentType.WindowsRuntime) {
+ }
+ else if (assemblyName.ContentType == AssemblyContentType.WindowsRuntime)
+ {
// WinRT type - we have to use Type.GetType
type = Type.GetType(typeName + ", " + assemblyString, true /*throwOnError*/, ignoreCase);
- } else {
+ }
+ else
+ {
// Classic managed type
assembly = RuntimeAssembly.InternalLoadAssemblyName(
assemblyName, securityInfo, null, ref stackMark,
@@ -261,14 +271,15 @@ namespace System {
}
}
- if (type == null) {
+ if (type == null)
+ {
// It's classic managed type (not WinRT type)
Log(assembly != null, "CreateInstance:: ", "Loaded " + assembly.FullName, "Failed to Load: " + assemblyString);
- if(assembly == null) return null;
+ if (assembly == null) return null;
type = assembly.GetType(typeName, true /*throwOnError*/, ignoreCase);
}
-
+
Object o = Activator.CreateInstance(type,
bindingAttr,
binder,
@@ -277,9 +288,10 @@ namespace System {
activationAttributes);
Log(o != null, "CreateInstance:: ", "Created Instance of class " + typeName, "Failed to create instance of class " + typeName);
- if(o == null)
+ if (o == null)
return null;
- else {
+ else
+ {
ObjectHandle Handle = new ObjectHandle(o);
return Handle;
}
@@ -306,9 +318,9 @@ namespace System {
}
private static ObjectHandle CreateInstanceFromInternal(String assemblyFile,
- String typeName,
+ String typeName,
bool ignoreCase,
- BindingFlags bindingAttr,
+ BindingFlags bindingAttr,
Binder binder,
Object[] args,
CultureInfo culture,
@@ -319,7 +331,7 @@ namespace System {
Assembly assembly = Assembly.LoadFrom(assemblyFile, securityInfo);
#pragma warning restore 618
Type t = assembly.GetType(typeName, true, ignoreCase);
-
+
Object o = Activator.CreateInstance(t,
bindingAttr,
binder,
@@ -328,9 +340,10 @@ namespace System {
activationAttributes);
Log(o != null, "CreateInstanceFrom:: ", "Created Instance of class " + typeName, "Failed to create instance of class " + typeName);
- if(o == null)
+ if (o == null)
return null;
- else {
+ else
+ {
ObjectHandle Handle = new ObjectHandle(o);
return Handle;
}
@@ -343,30 +356,29 @@ namespace System {
typeName,
null,
AssemblyHashAlgorithm.None);
-
}
-
+
public static ObjectHandle CreateComInstanceFrom(String assemblyName,
String typeName,
- byte[] hashValue,
+ byte[] hashValue,
AssemblyHashAlgorithm hashAlgorithm)
{
Assembly assembly = Assembly.LoadFrom(assemblyName, hashValue, hashAlgorithm);
Type t = assembly.GetType(typeName, true, false);
- Object[] Attr = t.GetCustomAttributes(typeof(ComVisibleAttribute),false);
+ Object[] Attr = t.GetCustomAttributes(typeof(ComVisibleAttribute), false);
if (Attr.Length > 0)
{
if (((ComVisibleAttribute)Attr[0]).Value == false)
- throw new TypeLoadException(Environment.GetResourceString( "Argument_TypeMustBeVisibleFromCom" ));
+ throw new TypeLoadException(SR.Argument_TypeMustBeVisibleFromCom);
}
Log(assembly != null, "CreateInstance:: ", "Loaded " + assembly.FullName, "Failed to Load: " + assemblyName);
- if(assembly == null) return null;
+ if (assembly == null) return null;
+
-
Object o = Activator.CreateInstance(t,
Activator.ConstructorDefault,
null,
@@ -375,9 +387,10 @@ namespace System {
null);
Log(o != null, "CreateInstance:: ", "Created Instance of class " + typeName, "Failed to create instance of class " + typeName);
- if(o == null)
+ if (o == null)
return null;
- else {
+ else
+ {
ObjectHandle Handle = new ObjectHandle(o);
return Handle;
}
diff --git a/src/mscorlib/src/System/AggregateException.cs b/src/mscorlib/src/System/AggregateException.cs
index c0f21229ed..22bc323215 100644
--- a/src/mscorlib/src/System/AggregateException.cs
+++ b/src/mscorlib/src/System/AggregateException.cs
@@ -23,7 +23,6 @@ using System.Threading;
namespace System
{
-
/// <summary>Represents one or more errors that occur during application execution.</summary>
/// <remarks>
/// <see cref="AggregateException"/> is used to consolidate multiple failures into a single, throwable
@@ -33,14 +32,13 @@ namespace System
[DebuggerDisplay("Count = {InnerExceptionCount}")]
public class AggregateException : Exception
{
-
private ReadOnlyCollection<Exception> m_innerExceptions; // Complete set of exceptions.
/// <summary>
/// Initializes a new instance of the <see cref="AggregateException"/> class.
/// </summary>
public AggregateException()
- : base(Environment.GetResourceString("AggregateException_ctor_DefaultMessage"))
+ : base(SR.AggregateException_ctor_DefaultMessage)
{
m_innerExceptions = new ReadOnlyCollection<Exception>(new Exception[0]);
}
@@ -85,7 +83,7 @@ namespace System
/// <exception cref="T:System.ArgumentException">An element of <paramref name="innerExceptions"/> is
/// null.</exception>
public AggregateException(IEnumerable<Exception> innerExceptions) :
- this(Environment.GetResourceString("AggregateException_ctor_DefaultMessage"), innerExceptions)
+ this(SR.AggregateException_ctor_DefaultMessage, innerExceptions)
{
}
@@ -99,7 +97,7 @@ namespace System
/// <exception cref="T:System.ArgumentException">An element of <paramref name="innerExceptions"/> is
/// null.</exception>
public AggregateException(params Exception[] innerExceptions) :
- this(Environment.GetResourceString("AggregateException_ctor_DefaultMessage"), innerExceptions)
+ this(SR.AggregateException_ctor_DefaultMessage, innerExceptions)
{
}
@@ -163,7 +161,7 @@ namespace System
if (exceptionsCopy[i] == null)
{
- throw new ArgumentException(Environment.GetResourceString("AggregateException_ctor_InnerExceptionNull"));
+ throw new ArgumentException(SR.AggregateException_ctor_InnerExceptionNull);
}
}
@@ -182,7 +180,7 @@ namespace System
/// <exception cref="T:System.ArgumentException">An element of <paramref name="innerExceptionInfos"/> is
/// null.</exception>
internal AggregateException(IEnumerable<ExceptionDispatchInfo> innerExceptionInfos) :
- this(Environment.GetResourceString("AggregateException_ctor_DefaultMessage"), innerExceptionInfos)
+ this(SR.AggregateException_ctor_DefaultMessage, innerExceptionInfos)
{
}
@@ -202,9 +200,9 @@ namespace System
internal AggregateException(string message, IEnumerable<ExceptionDispatchInfo> innerExceptionInfos)
// If it's already an IList, pass that along (a defensive copy will be made in the delegated ctor). If it's null, just pass along
// null typed correctly. Otherwise, create an IList from the enumerable and pass that along.
- : this(message, innerExceptionInfos as IList<ExceptionDispatchInfo> ??
- (innerExceptionInfos == null ?
- (List<ExceptionDispatchInfo>)null :
+ : this(message, innerExceptionInfos as IList<ExceptionDispatchInfo> ??
+ (innerExceptionInfos == null ?
+ (List<ExceptionDispatchInfo>)null :
new List<ExceptionDispatchInfo>(innerExceptionInfos)))
{
}
@@ -242,7 +240,7 @@ namespace System
if (exceptionsCopy[i] == null)
{
- throw new ArgumentException(Environment.GetResourceString("AggregateException_ctor_InnerExceptionNull"));
+ throw new ArgumentException(SR.AggregateException_ctor_InnerExceptionNull);
}
}
@@ -269,7 +267,7 @@ namespace System
Exception[] innerExceptions = info.GetValue("InnerExceptions", typeof(Exception[])) as Exception[];
if (innerExceptions == null)
{
- throw new SerializationException(Environment.GetResourceString("AggregateException_DeserializationFailure"));
+ throw new SerializationException(SR.AggregateException_DeserializationFailure);
}
m_innerExceptions = new ReadOnlyCollection<Exception>(innerExceptions);
@@ -468,7 +466,7 @@ namespace System
{
text = String.Format(
CultureInfo.InvariantCulture,
- Environment.GetResourceString("AggregateException_ToString"),
+ SR.AggregateException_ToString,
text, Environment.NewLine, i, m_innerExceptions[i].ToString(), "<---", Environment.NewLine);
}
@@ -492,5 +490,4 @@ namespace System
}
}
}
-
}
diff --git a/src/mscorlib/src/System/AppContext/AppContext.cs b/src/mscorlib/src/System/AppContext/AppContext.cs
index 5a3b732fa8..7c7e74f19b 100644
--- a/src/mscorlib/src/System/AppContext/AppContext.cs
+++ b/src/mscorlib/src/System/AppContext/AppContext.cs
@@ -35,7 +35,7 @@ namespace System
{
// The value of APP_CONTEXT_BASE_DIRECTORY key has to be a string and it is not allowed to be any other type.
// Otherwise the caller will get invalid cast exception
- return (string) AppDomain.CurrentDomain.GetData("APP_CONTEXT_BASE_DIRECTORY") ?? AppDomain.CurrentDomain.BaseDirectory;
+ return (string)AppDomain.CurrentDomain.GetData("APP_CONTEXT_BASE_DIRECTORY") ?? AppDomain.CurrentDomain.BaseDirectory;
}
}
@@ -72,16 +72,16 @@ namespace System
}
public static event System.EventHandler<System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs> FirstChanceException
- {
- add
- {
- AppDomain.CurrentDomain.FirstChanceException += value;
- }
- remove
- {
- AppDomain.CurrentDomain.FirstChanceException -= value;
- }
- }
+ {
+ add
+ {
+ AppDomain.CurrentDomain.FirstChanceException += value;
+ }
+ remove
+ {
+ AppDomain.CurrentDomain.FirstChanceException -= value;
+ }
+ }
public static event System.EventHandler ProcessExit;
internal static event System.EventHandler Unloading;
@@ -116,7 +116,7 @@ namespace System
if (switchName == null)
throw new ArgumentNullException(nameof(switchName));
if (switchName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(switchName));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(switchName));
// By default, the switch is not enabled.
isEnabled = false;
@@ -144,7 +144,7 @@ namespace System
}
// We get the value of isEnabled from the value that we stored in the dictionary
- isEnabled = (switchValue & SwitchValueState.HasTrueValue) == SwitchValueState.HasTrueValue;
+ isEnabled = (switchValue & SwitchValueState.HasTrueValue) == SwitchValueState.HasTrueValue;
// 2. The switch has a valid value AND we have checked for overrides
if ((switchValue & SwitchValueState.HasLookedForOverride) == SwitchValueState.HasLookedForOverride)
@@ -212,7 +212,7 @@ namespace System
if (switchName == null)
throw new ArgumentNullException(nameof(switchName));
if (switchName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(switchName));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(switchName));
SwitchValueState switchValue = (isEnabled ? SwitchValueState.HasTrueValue : SwitchValueState.HasFalseValue)
| SwitchValueState.HasLookedForOverride;
diff --git a/src/mscorlib/src/System/AppContext/AppContextDefaultValues.Defaults.cs b/src/mscorlib/src/System/AppContext/AppContextDefaultValues.Defaults.cs
index 52bdf9d427..ddecf18646 100644
--- a/src/mscorlib/src/System/AppContext/AppContextDefaultValues.Defaults.cs
+++ b/src/mscorlib/src/System/AppContext/AppContextDefaultValues.Defaults.cs
@@ -8,7 +8,6 @@ namespace System
{
internal static partial class AppContextDefaultValues
{
-
internal static readonly string SwitchNoAsyncCurrentCulture = "Switch.System.Globalization.NoAsyncCurrentCulture";
internal static readonly string SwitchThrowExceptionIfDisposedCancellationTokenSource = "Switch.System.Threading.ThrowExceptionIfDisposedCancellationTokenSource";
internal static readonly string SwitchPreserveEventListnerObjectIdentity = "Switch.System.Diagnostics.EventSource.PreserveEventListnerObjectIdentity";
diff --git a/src/mscorlib/src/System/AppContext/AppContextSwitches.cs b/src/mscorlib/src/System/AppContext/AppContextSwitches.cs
index 5fdd2bc1e6..03b535bda2 100644
--- a/src/mscorlib/src/System/AppContext/AppContextSwitches.cs
+++ b/src/mscorlib/src/System/AppContext/AppContextSwitches.cs
@@ -2,11 +2,11 @@
// 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;
+
namespace System
{
- using System;
- using System.Runtime.CompilerServices;
-
internal static class AppContextSwitches
{
private static int _noAsyncCurrentCulture;
diff --git a/src/mscorlib/src/System/AppDomain.cs b/src/mscorlib/src/System/AppDomain.cs
index c6987392d5..7d2f2ceaf8 100644
--- a/src/mscorlib/src/System/AppDomain.cs
+++ b/src/mscorlib/src/System/AppDomain.cs
@@ -37,59 +37,6 @@ namespace System
using System.Diagnostics.Contracts;
using System.Runtime.ExceptionServices;
- public class ResolveEventArgs : EventArgs
- {
- private String _Name;
- private Assembly _RequestingAssembly;
-
- public String Name {
- get {
- return _Name;
- }
- }
-
- public Assembly RequestingAssembly
- {
- get
- {
- return _RequestingAssembly;
- }
- }
-
- public ResolveEventArgs(String name)
- {
- _Name = name;
- }
-
- public ResolveEventArgs(String name, Assembly requestingAssembly)
- {
- _Name = name;
- _RequestingAssembly = requestingAssembly;
- }
- }
-
- public class AssemblyLoadEventArgs : EventArgs
- {
- private Assembly _LoadedAssembly;
-
- public Assembly LoadedAssembly {
- get {
- return _LoadedAssembly;
- }
- }
-
- public AssemblyLoadEventArgs(Assembly loadedAssembly)
- {
- _LoadedAssembly = loadedAssembly;
- }
- }
-
- [Serializable]
- public delegate Assembly ResolveEventHandler(Object sender, ResolveEventArgs args);
-
- [Serializable]
- public delegate void AssemblyLoadEventHandler(Object sender, AssemblyLoadEventArgs args);
-
[Serializable]
internal delegate void AppDomainInitializer(string[] args);
@@ -106,62 +53,61 @@ namespace System
internal AppDomainInitializerInfo(AppDomainInitializer init)
{
- Info=null;
- if (init==null)
+ Info = null;
+ if (init == null)
return;
List<ItemInfo> itemInfo = new List<ItemInfo>();
List<AppDomainInitializer> nestedDelegates = new List<AppDomainInitializer>();
nestedDelegates.Add(init);
- int idx=0;
-
- while (nestedDelegates.Count>idx)
+ int idx = 0;
+
+ while (nestedDelegates.Count > idx)
{
AppDomainInitializer curr = nestedDelegates[idx++];
- Delegate[] list= curr.GetInvocationList();
- for (int i=0;i<list.Length;i++)
+ Delegate[] list = curr.GetInvocationList();
+ for (int i = 0; i < list.Length; i++)
{
- if (!list[i].Method.IsStatic)
+ if (!list[i].Method.IsStatic)
{
- if(list[i].Target==null)
+ if (list[i].Target == null)
continue;
-
+
AppDomainInitializer nested = list[i].Target as AppDomainInitializer;
- if (nested!=null)
+ if (nested != null)
nestedDelegates.Add(nested);
else
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeStatic"),
- list[i].Method.ReflectedType.FullName+"::"+list[i].Method.Name);
+ throw new ArgumentException(SR.Arg_MustBeStatic,
+ list[i].Method.ReflectedType.FullName + "::" + list[i].Method.Name);
}
else
{
- ItemInfo info=new ItemInfo();
- info.TargetTypeAssembly=list[i].Method.ReflectedType.Module.Assembly.FullName;
- info.TargetTypeName=list[i].Method.ReflectedType.FullName;
- info.MethodName=list[i].Method.Name;
+ ItemInfo info = new ItemInfo();
+ info.TargetTypeAssembly = list[i].Method.ReflectedType.Module.Assembly.FullName;
+ info.TargetTypeName = list[i].Method.ReflectedType.FullName;
+ info.MethodName = list[i].Method.Name;
itemInfo.Add(info);
}
-
}
}
- Info = itemInfo.ToArray();
+ Info = itemInfo.ToArray();
}
-
+
internal AppDomainInitializer Unwrap()
{
- if (Info==null)
+ if (Info == null)
return null;
- AppDomainInitializer retVal=null;
- for (int i=0;i<Info.Length;i++)
+ AppDomainInitializer retVal = null;
+ for (int i = 0; i < Info.Length; i++)
{
- Assembly assembly=Assembly.Load(Info[i].TargetTypeAssembly);
- AppDomainInitializer newVal=(AppDomainInitializer)Delegate.CreateDelegate(typeof(AppDomainInitializer),
+ Assembly assembly = Assembly.Load(Info[i].TargetTypeAssembly);
+ AppDomainInitializer newVal = (AppDomainInitializer)Delegate.CreateDelegate(typeof(AppDomainInitializer),
assembly.GetType(Info[i].TargetTypeName),
Info[i].MethodName);
- if(retVal==null)
- retVal=newVal;
+ if (retVal == null)
+ retVal = newVal;
else
- retVal+=newVal;
+ retVal += newVal;
}
return retVal;
}
@@ -176,10 +122,10 @@ namespace System
private AppDomainManager _domainManager;
private Dictionary<String, Object> _LocalStore;
- private AppDomainSetup _FusionStore;
- private Evidence _SecurityIdentity;
+ private AppDomainSetup _FusionStore;
+ private Evidence _SecurityIdentity;
#pragma warning disable 169
- private Object[] _Policies; // Called from the VM.
+ private Object[] _Policies; // Called from the VM.
#pragma warning restore 169
public event AssemblyLoadEventHandler AssemblyLoad;
@@ -246,30 +192,27 @@ namespace System
}
}
-#if FEATURE_REFLECTION_ONLY_LOAD
- public event ResolveEventHandler ReflectionOnlyAssemblyResolve;
-#endif // FEATURE_REFLECTION_ONLY
private ApplicationTrust _applicationTrust;
- private EventHandler _processExit;
+ private EventHandler _processExit;
- private EventHandler _domainUnload;
+ private EventHandler _domainUnload;
private UnhandledExceptionEventHandler _unhandledException;
// The compat flags are set at domain creation time to indicate that the given breaking
// changes (named in the strings) should not be used in this domain. We only use the
// keys, the vhe values are ignored.
- private Dictionary<String, object> _compatFlags;
+ private Dictionary<String, object> _compatFlags;
// Delegate that will hold references to FirstChance exception notifications
private EventHandler<FirstChanceExceptionEventArgs> _firstChanceException;
- private IntPtr _pDomain; // this is an unmanaged pointer (AppDomain * m_pDomain)` used from the VM.
+ private IntPtr _pDomain; // this is an unmanaged pointer (AppDomain * m_pDomain)` used from the VM.
- private bool _HasSetPolicy;
- private bool _IsFastFullTrustDomain; // quick check to see if the AppDomain is fully trusted and homogenous
- private bool _compatFlagsInitialized;
+ private bool _HasSetPolicy;
+ private bool _IsFastFullTrustDomain; // quick check to see if the AppDomain is fully trusted and homogenous
+ private bool _compatFlagsInitialized;
internal const String TargetFrameworkNameAppCompatSetting = "TargetFrameworkName";
@@ -282,16 +225,12 @@ namespace System
[Flags]
private enum APPX_FLAGS
{
- APPX_FLAGS_INITIALIZED = 0x01,
-
- APPX_FLAGS_APPX_MODEL = 0x02,
- APPX_FLAGS_APPX_DESIGN_MODE = 0x04,
- APPX_FLAGS_APPX_NGEN = 0x08,
- APPX_FLAGS_APPX_MASK = APPX_FLAGS_APPX_MODEL |
- APPX_FLAGS_APPX_DESIGN_MODE |
- APPX_FLAGS_APPX_NGEN,
+ APPX_FLAGS_INITIALIZED = 0x01,
- APPX_FLAGS_API_CHECK = 0x10,
+ APPX_FLAGS_APPX_MODEL = 0x02,
+ APPX_FLAGS_APPX_DESIGN_MODE = 0x04,
+ APPX_FLAGS_APPX_MASK = APPX_FLAGS_APPX_MODEL |
+ APPX_FLAGS_APPX_DESIGN_MODE,
}
private static APPX_FLAGS Flags
@@ -305,22 +244,6 @@ namespace System
return s_flags;
}
}
-
- internal static bool ProfileAPICheck
- {
- get
- {
- return (Flags & APPX_FLAGS.APPX_FLAGS_API_CHECK) != 0;
- }
- }
-
- internal static bool IsAppXNGen
- {
- get
- {
- return (Flags & APPX_FLAGS.APPX_FLAGS_APPX_NGEN) != 0;
- }
- }
#endif // FEATURE_APPX
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
@@ -361,7 +284,7 @@ namespace System
// uninitialized object through remoting, etc.
if (_pDomain.IsNull())
{
- throw new InvalidOperationException(Environment.GetResourceString("Argument_InvalidHandle"));
+ throw new InvalidOperationException(SR.Argument_InvalidHandle);
}
return new AppDomainHandle(_pDomain);
@@ -417,20 +340,20 @@ namespace System
}
catch (FileNotFoundException e)
{
- throw new TypeLoadException(Environment.GetResourceString("Argument_NoDomainManager"), e);
+ throw new TypeLoadException(SR.Argument_NoDomainManager, e);
}
catch (SecurityException e)
{
- throw new TypeLoadException(Environment.GetResourceString("Argument_NoDomainManager"), e);
+ throw new TypeLoadException(SR.Argument_NoDomainManager, e);
}
catch (TypeLoadException e)
{
- throw new TypeLoadException(Environment.GetResourceString("Argument_NoDomainManager"), e);
+ throw new TypeLoadException(SR.Argument_NoDomainManager, e);
}
if (_domainManager == null)
{
- throw new TypeLoadException(Environment.GetResourceString("Argument_NoDomainManager"));
+ throw new TypeLoadException(SR.Argument_NoDomainManager);
}
// If this domain was not created by a managed call to CreateDomain, then the AppDomainSetup
@@ -463,7 +386,7 @@ namespace System
private void InitializeCompatibilityFlags()
{
AppDomainSetup adSetup = FusionStore;
-
+
// set up shim flags regardless of whether we create a DomainManager in this method.
if (adSetup.GetCompatibilityFlags() != null)
{
@@ -521,7 +444,7 @@ namespace System
{
#if FEATURE_APPX
if (IsAppXModel())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_AppX", "Assembly.LoadFrom"));
+ throw new NotSupportedException(SR.Format(SR.NotSupported_AppX, "Assembly.LoadFrom"));
#endif
}
@@ -533,7 +456,7 @@ namespace System
{
#if FEATURE_APPX
if (IsAppXModel())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_AppX", "Assembly.LoadFile"));
+ throw new NotSupportedException(SR.Format(SR.NotSupported_AppX, "Assembly.LoadFile"));
#endif
}
@@ -545,7 +468,7 @@ namespace System
{
#if FEATURE_APPX
if (IsAppXModel())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_AppX", "Assembly.ReflectionOnlyLoad"));
+ throw new NotSupportedException(SR.Format(SR.NotSupported_AppX, "Assembly.ReflectionOnlyLoad"));
#endif
}
@@ -557,7 +480,7 @@ namespace System
{
#if FEATURE_APPX
if (IsAppXModel())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_AppX", "Assembly.Load(byte[], ...)"));
+ throw new NotSupportedException(SR.Format(SR.NotSupported_AppX, "Assembly.Load(byte[], ...)"));
#endif
}
@@ -603,17 +526,20 @@ namespace System
bool runtimeSuppliedHomogenousGrant = false;
ApplicationTrust appTrust = adSetup.ApplicationTrust;
- if (appTrust != null) {
+ if (appTrust != null)
+ {
SetupDomainSecurityForHomogeneousDomain(appTrust, runtimeSuppliedHomogenousGrant);
}
- else if (_IsFastFullTrustDomain) {
+ else if (_IsFastFullTrustDomain)
+ {
SetSecurityHomogeneousFlag(GetNativeHandle(), runtimeSuppliedHomogenousGrant);
}
// Get the evidence supplied for the domain. If no evidence was supplied, it means that we want
// to use the default evidence creation strategy for this domain
Evidence newAppDomainEvidence = (providedSecurityInfo != null ? providedSecurityInfo : creatorsSecurityInfo);
- if (newAppDomainEvidence == null && generateDefaultEvidence) {
+ if (newAppDomainEvidence == null && generateDefaultEvidence)
+ {
newAppDomainEvidence = new Evidence();
}
@@ -650,63 +576,18 @@ namespace System
runtimeSuppliedHomogenousGrantSet);
}
- public AppDomainManager DomainManager {
- get {
- return _domainManager;
- }
- }
-
-#if FEATURE_REFLECTION_ONLY_LOAD
- private Assembly ResolveAssemblyForIntrospection(Object sender, ResolveEventArgs args)
- {
- Contract.Requires(args != null);
- return Assembly.ReflectionOnlyLoad(ApplyPolicy(args.Name));
- }
-
- // Helper class for method code:EnableResolveAssembliesForIntrospection
- private class NamespaceResolverForIntrospection
+ public AppDomainManager DomainManager
{
- private IEnumerable<string> _packageGraphFilePaths;
- public NamespaceResolverForIntrospection(IEnumerable<string> packageGraphFilePaths)
- {
- _packageGraphFilePaths = packageGraphFilePaths;
- }
-
- public void ResolveNamespace(
- object sender,
- System.Runtime.InteropServices.WindowsRuntime.NamespaceResolveEventArgs args)
+ get
{
- Contract.Requires(args != null);
-
- IEnumerable<string> fileNames = System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMetadata.ResolveNamespace(
- args.NamespaceName,
- null, // windowsSdkFilePath ... Use OS installed .winmd files
- _packageGraphFilePaths);
- foreach (string fileName in fileNames)
- {
- args.ResolvedAssemblies.Add(Assembly.ReflectionOnlyLoadFrom(fileName));
- }
+ return _domainManager;
}
}
-
- // Called only by native function code:ValidateWorker
- private void EnableResolveAssembliesForIntrospection(string verifiedFileDirectory)
- {
- CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(ResolveAssemblyForIntrospection);
-
- string[] packageGraphFilePaths = null;
- if (verifiedFileDirectory != null)
- packageGraphFilePaths = new string[] { verifiedFileDirectory };
- NamespaceResolverForIntrospection namespaceResolver = new NamespaceResolverForIntrospection(packageGraphFilePaths);
-
- System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMetadata.ReflectionOnlyNamespaceResolve +=
- new EventHandler<System.Runtime.InteropServices.WindowsRuntime.NamespaceResolveEventArgs>(namespaceResolver.ResolveNamespace);
- }
-#endif // FEATURE_REFLECTION_ONLY_LOAD
+
public ObjectHandle CreateInstance(String assemblyName,
String typeName)
-
+
{
// jit does not check for that, so we should do it ...
if (this == null)
@@ -722,7 +603,8 @@ namespace System
public static AppDomain CurrentDomain
{
- get {
+ get
+ {
Contract.Ensures(Contract.Result<AppDomain>() != null);
return Thread.GetDomain();
}
@@ -730,7 +612,8 @@ namespace System
public String BaseDirectory
{
- get {
+ get
+ {
return FusionStore.ApplicationBase;
}
}
@@ -740,26 +623,29 @@ namespace System
StringBuilder sb = StringBuilderCache.Acquire();
String fn = nGetFriendlyName();
- if (fn != null) {
- sb.Append(Environment.GetResourceString("Loader_Name") + fn);
+ if (fn != null)
+ {
+ sb.Append(SR.Loader_Name + fn);
sb.Append(Environment.NewLine);
}
- if(_Policies == null || _Policies.Length == 0)
- sb.Append(Environment.GetResourceString("Loader_NoContextPolicies")
+ if (_Policies == null || _Policies.Length == 0)
+ sb.Append(SR.Loader_NoContextPolicies
+ Environment.NewLine);
- else {
- sb.Append(Environment.GetResourceString("Loader_ContextPolicies")
+ else
+ {
+ sb.Append(SR.Loader_ContextPolicies
+ Environment.NewLine);
- for(int i = 0;i < _Policies.Length; i++) {
+ for (int i = 0; i < _Policies.Length; i++)
+ {
sb.Append(_Policies[i]);
sb.Append(Environment.NewLine);
}
}
-
+
return StringBuilderCache.GetStringAndRelease(sb);
}
-
+
// this is true when we've removed the handles etc so really can't do anything
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern bool IsUnloadingForcedFinalize();
@@ -772,22 +658,25 @@ namespace System
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void PublishAnonymouslyHostedDynamicMethodsAssembly(RuntimeAssembly assemblyHandle);
- public void SetData (string name, object data) {
+ public void SetData(string name, object data)
+ {
if (name == null)
throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
// SetData should only be used to set values that don't already exist.
object currentVal;
- lock (((ICollection)LocalStore).SyncRoot) {
+ lock (((ICollection)LocalStore).SyncRoot)
+ {
LocalStore.TryGetValue(name, out currentVal);
}
if (currentVal != null)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SetData_OnlyOnce"));
+ throw new InvalidOperationException(SR.InvalidOperation_SetData_OnlyOnce);
}
- lock (((ICollection)LocalStore).SyncRoot) {
+ lock (((ICollection)LocalStore).SyncRoot)
+ {
LocalStore[name] = data;
}
}
@@ -795,19 +684,20 @@ namespace System
[Pure]
public Object GetData(string name)
{
- if(name == null)
+ if (name == null)
throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
int key = AppDomainSetup.Locate(name);
- if(key == -1)
+ if (key == -1)
{
- if(name.Equals(AppDomainSetup.LoaderOptimizationKey))
+ if (name.Equals(AppDomainSetup.LoaderOptimizationKey))
return FusionStore.LoaderOptimization;
- else
+ else
{
object data;
- lock (((ICollection)LocalStore).SyncRoot) {
+ lock (((ICollection)LocalStore).SyncRoot)
+ {
LocalStore.TryGetValue(name, out data);
}
if (data == null)
@@ -815,27 +705,30 @@ namespace System
return data;
}
}
- else {
+ else
+ {
// Be sure to call these properties, not Value, so
// that the appropriate permission demand will be done
- switch(key) {
- case (int) AppDomainSetup.LoaderInformation.ApplicationBaseValue:
- return FusionStore.ApplicationBase;
- case (int) AppDomainSetup.LoaderInformation.ApplicationNameValue:
- return FusionStore.ApplicationName;
- default:
- Debug.Assert(false, "Need to handle new LoaderInformation value in AppDomain.GetData()");
- return null;
+ switch (key)
+ {
+ case (int)AppDomainSetup.LoaderInformation.ApplicationBaseValue:
+ return FusionStore.ApplicationBase;
+ case (int)AppDomainSetup.LoaderInformation.ApplicationNameValue:
+ return FusionStore.ApplicationName;
+ default:
+ Debug.Assert(false, "Need to handle new LoaderInformation value in AppDomain.GetData()");
+ return null;
}
}
}
-
+
[Obsolete("AppDomain.GetCurrentThreadId has been deprecated because it does not provide a stable Id when managed threads are running on fibers (aka lightweight threads). To get a stable identifier for a managed thread, use the ManagedThreadId property on Thread. http://go.microsoft.com/fwlink/?linkid=14202", false)]
[DllImport(Microsoft.Win32.Win32Native.KERNEL32)]
public static extern int GetCurrentThreadId();
- private AppDomain() {
- throw new NotSupportedException(Environment.GetResourceString(ResId.NotSupported_Constructor));
+ private AppDomain()
+ {
+ throw new NotSupportedException(SR.GetResourceString(ResId.NotSupported_Constructor));
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -866,13 +759,13 @@ namespace System
if (value != null)
{
RuntimeHelpers.PrepareContractedDelegate(value);
- lock(this)
+ lock (this)
_processExit += value;
}
}
remove
{
- lock(this)
+ lock (this)
_processExit -= value;
}
}
@@ -885,13 +778,13 @@ namespace System
if (value != null)
{
RuntimeHelpers.PrepareContractedDelegate(value);
- lock(this)
+ lock (this)
_domainUnload += value;
}
}
remove
{
- lock(this)
+ lock (this)
_domainUnload -= value;
}
}
@@ -904,13 +797,13 @@ namespace System
if (value != null)
{
RuntimeHelpers.PrepareContractedDelegate(value);
- lock(this)
+ lock (this)
_unhandledException += value;
}
}
remove
{
- lock(this)
+ lock (this)
_unhandledException -= value;
}
}
@@ -926,13 +819,13 @@ namespace System
if (value != null)
{
RuntimeHelpers.PrepareContractedDelegate(value);
- lock(this)
+ lock (this)
_firstChanceException += value;
}
}
remove
{
- lock(this)
+ lock (this)
_firstChanceException -= value;
}
}
@@ -940,22 +833,24 @@ namespace System
private void OnAssemblyLoadEvent(RuntimeAssembly LoadedAssembly)
{
AssemblyLoadEventHandler eventHandler = AssemblyLoad;
- if (eventHandler != null) {
+ if (eventHandler != null)
+ {
AssemblyLoadEventArgs ea = new AssemblyLoadEventArgs(LoadedAssembly);
eventHandler(this, ea);
}
}
-
+
// This method is called by the VM.
private RuntimeAssembly OnResourceResolveEvent(RuntimeAssembly assembly, String resourceName)
{
ResolveEventHandler eventHandler = _ResourceResolve;
- if ( eventHandler == null)
+ if (eventHandler == null)
return null;
Delegate[] ds = eventHandler.GetInvocationList();
int len = ds.Length;
- for (int i = 0; i < len; i++) {
+ for (int i = 0; i < len; i++)
+ {
Assembly asm = ((ResolveEventHandler)ds[i])(this, new ResolveEventArgs(resourceName, assembly));
RuntimeAssembly ret = GetRuntimeAssembly(asm);
if (ret != null)
@@ -964,7 +859,7 @@ namespace System
return null;
}
-
+
// This method is called by the VM
private RuntimeAssembly OnTypeResolveEvent(RuntimeAssembly assembly, String typeName)
{
@@ -974,7 +869,8 @@ namespace System
Delegate[] ds = eventHandler.GetInvocationList();
int len = ds.Length;
- for (int i = 0; i < len; i++) {
+ for (int i = 0; i < len; i++)
+ {
Assembly asm = ((ResolveEventHandler)ds[i])(this, new ResolveEventArgs(typeName, assembly));
RuntimeAssembly ret = GetRuntimeAssembly(asm);
if (ret != null)
@@ -996,13 +892,14 @@ namespace System
Delegate[] ds = eventHandler.GetInvocationList();
int len = ds.Length;
- for (int i = 0; i < len; i++) {
+ for (int i = 0; i < len; i++)
+ {
Assembly asm = ((ResolveEventHandler)ds[i])(this, new ResolveEventArgs(assemblyFullName, assembly));
RuntimeAssembly ret = GetRuntimeAssembly(asm);
if (ret != null)
return ret;
}
-
+
return null;
}
@@ -1016,8 +913,9 @@ namespace System
internal AppDomainSetup FusionStore
{
- get {
- Debug.Assert(_FusionStore != null,
+ get
+ {
+ Debug.Assert(_FusionStore != null,
"Fusion store has not been correctly setup in this domain");
return _FusionStore;
}
@@ -1041,10 +939,12 @@ namespace System
private Dictionary<String, Object> LocalStore
{
- get {
+ get
+ {
if (_LocalStore != null)
return _LocalStore;
- else {
+ else
+ {
_LocalStore = new Dictionary<String, Object>();
return _LocalStore;
}
@@ -1061,7 +961,7 @@ namespace System
if (info.ApplicationBase == null)
{
- info.SetupDefaults(RuntimeEnvironment.GetModuleFileName(), imageLocationAlreadyNormalized : true);
+ info.SetupDefaults(RuntimeEnvironment.GetModuleFileName(), imageLocationAlreadyNormalized: true);
}
nCreateContext();
@@ -1074,11 +974,11 @@ namespace System
private static void RunInitializer(AppDomainSetup setup)
{
- if (setup.AppDomainInitializer!=null)
+ if (setup.AppDomainInitializer != null)
{
- string[] args=null;
- if (setup.AppDomainInitializerArguments!=null)
- args=(string[])setup.AppDomainInitializerArguments.Clone();
+ string[] args = null;
+ if (setup.AppDomainInitializerArguments != null)
+ args = (string[])setup.AppDomainInitializerArguments.Clone();
setup.AppDomainInitializer(args);
}
}
@@ -1101,8 +1001,8 @@ namespace System
bool generateDefaultEvidence = false;
AppDomainInitializerInfo initializerInfo = null;
- if (setup!=null && setup.AppDomainInitializer!=null)
- initializerInfo=new AppDomainInitializerInfo(setup.AppDomainInitializer);
+ if (setup != null && setup.AppDomainInitializer != null)
+ initializerInfo = new AppDomainInitializerInfo(setup.AppDomainInitializer);
// will travel x-Ad, drop non-agile data
AppDomainSetup newSetup = new AppDomainSetup(setup, false);
@@ -1115,63 +1015,61 @@ namespace System
// System.AppDomainManager.CreateDomain() and add the flags to the AppDomainSetup
List<String> compatList = new List<String>();
- if(propertyNames!=null && propertyValues != null)
+ if (propertyNames != null && propertyValues != null)
{
- for (int i=0; i<propertyNames.Length; i++)
+ for (int i = 0; i < propertyNames.Length; i++)
{
- if(String.Compare(propertyNames[i], "AppDomainCompatSwitch", StringComparison.OrdinalIgnoreCase) == 0)
+ if (String.Compare(propertyNames[i], "AppDomainCompatSwitch", StringComparison.OrdinalIgnoreCase) == 0)
{
compatList.Add(propertyValues[i]);
propertyNames[i] = null;
propertyValues[i] = null;
}
-
}
-
+
if (compatList.Count > 0)
{
newSetup.SetCompatibilitySwitches(compatList);
}
}
- return new Object[]
+ return new Object[]
{
- friendlyName,
- newSetup,
- parentSecurityDescriptor,
+ friendlyName,
+ newSetup,
+ parentSecurityDescriptor,
generateDefaultEvidence,
serializedEvidence,
initializerInfo,
sandboxName,
propertyNames,
propertyValues
- };
+ };
} // PrepareDataForSetup
- [MethodImplAttribute(MethodImplOptions.NoInlining)]
private static Object Setup(Object arg)
{
Contract.Requires(arg != null && arg is Object[]);
Contract.Requires(((Object[])arg).Length >= 8);
- Object[] args=(Object[])arg;
- String friendlyName = (String)args[0];
- AppDomainSetup setup = (AppDomainSetup)args[1];
- IntPtr parentSecurityDescriptor = (IntPtr)args[2];
- bool generateDefaultEvidence = (bool)args[3];
- byte[] serializedEvidence = (byte[])args[4];
- AppDomainInitializerInfo initializerInfo = (AppDomainInitializerInfo)args[5];
- string sandboxName = (string)args[6];
- string[] propertyNames = (string[])args[7]; // can contain null elements
- string[] propertyValues = (string[])args[8]; // can contain null elements
+ Object[] args = (Object[])arg;
+ String friendlyName = (String)args[0];
+ AppDomainSetup setup = (AppDomainSetup)args[1];
+ IntPtr parentSecurityDescriptor = (IntPtr)args[2];
+ bool generateDefaultEvidence = (bool)args[3];
+ byte[] serializedEvidence = (byte[])args[4];
+ AppDomainInitializerInfo initializerInfo = (AppDomainInitializerInfo)args[5];
+ string sandboxName = (string)args[6];
+ string[] propertyNames = (string[])args[7]; // can contain null elements
+ string[] propertyValues = (string[])args[8]; // can contain null elements
// extract evidence
Evidence providedSecurityInfo = null;
Evidence creatorsSecurityInfo = null;
AppDomain ad = AppDomain.CurrentDomain;
- AppDomainSetup newSetup=new AppDomainSetup(setup,false);
+ AppDomainSetup newSetup = new AppDomainSetup(setup, false);
- if(propertyNames!=null && propertyValues != null)
+ if (propertyNames != null && propertyValues != null)
{
for (int i = 0; i < propertyNames.Length; i++)
{
@@ -1190,55 +1088,55 @@ namespace System
}
}
- for (int i=0; i<propertyNames.Length; i++)
+ for (int i = 0; i < propertyNames.Length; i++)
{
- if(propertyNames[i]=="APPBASE") // make sure in sync with Fusion
+ if (propertyNames[i] == "APPBASE") // make sure in sync with Fusion
{
- if(propertyValues[i]==null)
+ if (propertyValues[i] == null)
throw new ArgumentNullException("APPBASE");
if (PathInternal.IsPartiallyQualified(propertyValues[i]))
- throw new ArgumentException( Environment.GetResourceString( "Argument_AbsolutePathRequired" ) );
+ throw new ArgumentException(SR.Argument_AbsolutePathRequired);
newSetup.ApplicationBase = NormalizePath(propertyValues[i], fullCheck: true);
}
- else if(propertyNames[i]=="LOADER_OPTIMIZATION")
+ else if (propertyNames[i] == "LOADER_OPTIMIZATION")
{
- if(propertyValues[i]==null)
+ if (propertyValues[i] == null)
throw new ArgumentNullException("LOADER_OPTIMIZATION");
- switch(propertyValues[i])
+ switch (propertyValues[i])
{
- case "SingleDomain": newSetup.LoaderOptimization=LoaderOptimization.SingleDomain;break;
- case "MultiDomain": newSetup.LoaderOptimization=LoaderOptimization.MultiDomain;break;
- case "MultiDomainHost": newSetup.LoaderOptimization=LoaderOptimization.MultiDomainHost;break;
- case "NotSpecified": newSetup.LoaderOptimization=LoaderOptimization.NotSpecified;break;
- default: throw new ArgumentException(Environment.GetResourceString("Argument_UnrecognizedLoaderOptimization"), "LOADER_OPTIMIZATION");
+ case "SingleDomain": newSetup.LoaderOptimization = LoaderOptimization.SingleDomain; break;
+ case "MultiDomain": newSetup.LoaderOptimization = LoaderOptimization.MultiDomain; break;
+ case "MultiDomainHost": newSetup.LoaderOptimization = LoaderOptimization.MultiDomainHost; break;
+ case "NotSpecified": newSetup.LoaderOptimization = LoaderOptimization.NotSpecified; break;
+ default: throw new ArgumentException(SR.Argument_UnrecognizedLoaderOptimization, "LOADER_OPTIMIZATION");
}
}
- else if(propertyNames[i]=="TRUSTED_PLATFORM_ASSEMBLIES" ||
- propertyNames[i]=="PLATFORM_RESOURCE_ROOTS" ||
- propertyNames[i]=="APP_PATHS" ||
- propertyNames[i]=="APP_NI_PATHS")
+ else if (propertyNames[i] == "TRUSTED_PLATFORM_ASSEMBLIES" ||
+ propertyNames[i] == "PLATFORM_RESOURCE_ROOTS" ||
+ propertyNames[i] == "APP_PATHS" ||
+ propertyNames[i] == "APP_NI_PATHS")
{
string values = propertyValues[i];
- if(values == null)
+ if (values == null)
throw new ArgumentNullException(propertyNames[i]);
ad.SetData(propertyNames[i], NormalizeAppPaths(values));
}
- else if(propertyNames[i]!= null)
+ else if (propertyNames[i] != null)
{
- ad.SetData(propertyNames[i],propertyValues[i]); // just propagate
+ ad.SetData(propertyNames[i], propertyValues[i]); // just propagate
}
}
}
ad.SetupFusionStore(newSetup, null); // makes FusionStore a ref to newSetup
-
+
// technically, we don't need this, newSetup refers to the same object as FusionStore
// but it's confusing since it isn't immediately obvious whether we have a ref or a copy
- AppDomainSetup adSetup = ad.FusionStore;
+ AppDomainSetup adSetup = ad.FusionStore;
adSetup.InternalSetApplicationTrust(sandboxName);
@@ -1264,10 +1162,10 @@ namespace System
generateDefaultEvidence,
parentSecurityDescriptor,
true);
-
+
// can load user code now
- if(initializerInfo!=null)
- adSetup.AppDomainInitializer=initializerInfo.Unwrap();
+ if (initializerInfo != null)
+ adSetup.AppDomainInitializer = initializerInfo.Unwrap();
RunInitializer(adSetup);
return null;
@@ -1299,7 +1197,7 @@ namespace System
continue;
if (PathInternal.IsPartiallyQualified(path))
- throw new ArgumentException(Environment.GetResourceString("Argument_AbsolutePathRequired"));
+ throw new ArgumentException(SR.Argument_AbsolutePathRequired);
string appPath = NormalizePath(path, fullCheck: true);
sb.Append(appPath);
@@ -1329,7 +1227,7 @@ namespace System
// (eg. one thread doing a com call and another doing attach for IJW)
lock (this)
{
- if(_FusionStore == null)
+ if (_FusionStore == null)
{
AppDomainSetup setup = new AppDomainSetup();
@@ -1349,7 +1247,6 @@ namespace System
JitHelpers.GetObjectHandleOnStack(ref stackEvidence),
creatorsSecurityDescriptor,
publishAppDomain);
-
}
[SuppressUnmanagedCodeSecurity]
@@ -1372,8 +1269,9 @@ namespace System
public AppDomainSetup SetupInformation
{
- get {
- return new AppDomainSetup(FusionStore,true);
+ get
+ {
+ return new AppDomainSetup(FusionStore, true);
}
}
@@ -1382,7 +1280,7 @@ namespace System
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern String GetOrInternString(String str);
-
+
[SuppressUnmanagedCodeSecurity]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern void GetGrantSet(AppDomainHandle domain, ObjectHandleOnStack retGrantSet);
@@ -1407,14 +1305,14 @@ namespace System
public Int32 Id
{
- get {
+ get
+ {
return GetId();
}
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern Int32 GetId();
-
}
/// <summary>
diff --git a/src/mscorlib/src/System/AppDomainAttributes.cs b/src/mscorlib/src/System/AppDomainAttributes.cs
index 960f9c1cac..deb43eadf9 100644
--- a/src/mscorlib/src/System/AppDomainAttributes.cs
+++ b/src/mscorlib/src/System/AppDomainAttributes.cs
@@ -11,19 +11,19 @@
**
=============================================================================*/
-namespace System {
-
+namespace System
+{
[Serializable]
- internal enum LoaderOptimization
+ internal enum LoaderOptimization
{
- NotSpecified = 0,
- SingleDomain = 1,
- MultiDomain = 2,
- MultiDomainHost = 3,
+ NotSpecified = 0,
+ SingleDomain = 1,
+ MultiDomain = 2,
+ MultiDomainHost = 3,
[Obsolete("This method has been deprecated. Please use Assembly.Load() instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- DomainMask = 3,
+ DomainMask = 3,
[Obsolete("This method has been deprecated. Please use Assembly.Load() instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- DisallowBindings = 4
+ DisallowBindings = 4
}
}
diff --git a/src/mscorlib/src/System/AppDomainManager.cs b/src/mscorlib/src/System/AppDomainManager.cs
index bd2faa0110..830de29c16 100644
--- a/src/mscorlib/src/System/AppDomainManager.cs
+++ b/src/mscorlib/src/System/AppDomainManager.cs
@@ -8,18 +8,18 @@
// participate in the creation and control the settings of new AppDomains.
//
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Security;
+using System.Runtime.InteropServices;
+
namespace System
{
- using System.Reflection;
- using System.Runtime.CompilerServices;
- using System.Security;
- using System.Runtime.InteropServices;
-
internal class AppDomainManager : MarshalByRefObject
{
- public AppDomainManager () {}
+ public AppDomainManager() { }
- public virtual void InitializeNewDomain (AppDomainSetup appDomainInfo)
+ public virtual void InitializeNewDomain(AppDomainSetup appDomainInfo)
{
// By default, InitializeNewDomain does nothing. AppDomain.CreateAppDomainManager relies on this fact.
}
@@ -28,8 +28,10 @@ namespace System
private static extern void GetEntryAssembly(ObjectHandleOnStack retAssembly);
private Assembly m_entryAssembly = null;
- public virtual Assembly EntryAssembly {
- get {
+ public virtual Assembly EntryAssembly
+ {
+ get
+ {
// The default AppDomainManager sets the EntryAssembly depending on whether the
// AppDomain is a manifest application domain or not. In the first case, we parse
// the application manifest to find out the entry point assembly and return that assembly.
@@ -46,15 +48,12 @@ namespace System
}
}
- internal static AppDomainManager CurrentAppDomainManager {
- get {
+ internal static AppDomainManager CurrentAppDomainManager
+ {
+ get
+ {
return AppDomain.CurrentDomain.DomainManager;
}
}
-
- public virtual bool CheckSecuritySettings (SecurityState state)
- {
- return false;
- }
}
}
diff --git a/src/mscorlib/src/System/AppDomainSetup.cs b/src/mscorlib/src/System/AppDomainSetup.cs
index 0d19ad237f..142b8a05f7 100644
--- a/src/mscorlib/src/System/AppDomainSetup.cs
+++ b/src/mscorlib/src/System/AppDomainSetup.cs
@@ -4,15 +4,12 @@
/*=============================================================================
**
-** Class: AppDomainSetup
**
** Purpose: Defines the settings that the loader uses to find assemblies in an
** AppDomain
**
-** Date: Dec 22, 2000
**
=============================================================================*/
-
namespace System
{
using System.Text;
@@ -34,49 +31,29 @@ namespace System
// If you add a new value, add the corresponding property
// to AppDomain.GetData() and SetData()'s switch statements,
// as well as fusionsetup.h.
- ApplicationBaseValue = 0, // LOADER_APPLICATION_BASE
- ConfigurationFileValue = 1, // LOADER_CONFIGURATION_BASE
- DynamicBaseValue = 2, // LOADER_DYNAMIC_BASE
- DevPathValue = 3, // LOADER_DEVPATH
- ApplicationNameValue = 4, // LOADER_APPLICATION_NAME
- PrivateBinPathValue = 5, // LOADER_PRIVATE_PATH
- PrivateBinPathProbeValue = 6, // LOADER_PRIVATE_BIN_PATH_PROBE
- ShadowCopyDirectoriesValue = 7, // LOADER_SHADOW_COPY_DIRECTORIES
- ShadowCopyFilesValue = 8, // LOADER_SHADOW_COPY_FILES
- CachePathValue = 9, // LOADER_CACHE_PATH
- LicenseFileValue = 10, // LOADER_LICENSE_FILE
- DisallowPublisherPolicyValue = 11, // LOADER_DISALLOW_PUBLISHER_POLICY
- DisallowCodeDownloadValue = 12, // LOADER_DISALLOW_CODE_DOWNLOAD
+ ApplicationBaseValue = 0, // LOADER_APPLICATION_BASE
+ ConfigurationFileValue = 1, // LOADER_CONFIGURATION_BASE
+ DynamicBaseValue = 2, // LOADER_DYNAMIC_BASE
+ DevPathValue = 3, // LOADER_DEVPATH
+ ApplicationNameValue = 4, // LOADER_APPLICATION_NAME
+ PrivateBinPathValue = 5, // LOADER_PRIVATE_PATH
+ PrivateBinPathProbeValue = 6, // LOADER_PRIVATE_BIN_PATH_PROBE
+ ShadowCopyDirectoriesValue = 7, // LOADER_SHADOW_COPY_DIRECTORIES
+ ShadowCopyFilesValue = 8, // LOADER_SHADOW_COPY_FILES
+ CachePathValue = 9, // LOADER_CACHE_PATH
+ LicenseFileValue = 10, // LOADER_LICENSE_FILE
+ DisallowPublisherPolicyValue = 11, // LOADER_DISALLOW_PUBLISHER_POLICY
+ DisallowCodeDownloadValue = 12, // LOADER_DISALLOW_CODE_DOWNLOAD
DisallowBindingRedirectsValue = 13, // LOADER_DISALLOW_BINDING_REDIRECTS
- DisallowAppBaseProbingValue = 14, // LOADER_DISALLOW_APPBASE_PROBING
- ConfigurationBytesValue = 15, // LOADER_CONFIGURATION_BYTES
- LoaderMaximum = 18 // LOADER_MAXIMUM
+ DisallowAppBaseProbingValue = 14, // LOADER_DISALLOW_APPBASE_PROBING
+ ConfigurationBytesValue = 15, // LOADER_CONFIGURATION_BYTES
+ LoaderMaximum = 18 // LOADER_MAXIMUM
}
-
+
// Constants from fusionsetup.h.
private const string LOADER_OPTIMIZATION = "LOADER_OPTIMIZATION";
- private const string CONFIGURATION_EXTENSION = ".config";
- private const string APPENV_RELATIVEPATH = "RELPATH";
- private const string MACHINE_CONFIGURATION_FILE = "config\\machine.config";
- private const string ACTAG_HOST_CONFIG_FILE = "HOST_CONFIG";
-
- // Constants from fusionpriv.h
- private const string ACTAG_APP_CONFIG_FILE = "APP_CONFIG_FILE";
- private const string ACTAG_MACHINE_CONFIG = "MACHINE_CONFIG";
+
private const string ACTAG_APP_BASE_URL = "APPBASE";
- private const string ACTAG_APP_NAME = "APP_NAME";
- private const string ACTAG_BINPATH_PROBE_ONLY = "BINPATH_PROBE_ONLY";
- private const string ACTAG_APP_CACHE_BASE = "CACHE_BASE";
- private const string ACTAG_DEV_PATH = "DEV_PATH";
- private const string ACTAG_APP_DYNAMIC_BASE = "DYNAMIC_BASE";
- private const string ACTAG_FORCE_CACHE_INSTALL = "FORCE_CACHE_INSTALL";
- private const string ACTAG_APP_PRIVATE_BINPATH = "PRIVATE_BINPATH";
- private const string ACTAG_APP_SHADOW_COPY_DIRS = "SHADOW_COPY_DIRS";
- private const string ACTAG_DISALLOW_APPLYPUBLISHERPOLICY = "DISALLOW_APP";
- private const string ACTAG_CODE_DOWNLOAD_DISABLED = "CODE_DOWNLOAD_DISABLED";
- private const string ACTAG_DISALLOW_APP_BINDING_REDIRECTS = "DISALLOW_APP_REDIRECTS";
- private const string ACTAG_DISALLOW_APP_BASE_PROBING = "DISALLOW_APP_BASE_PROBING";
- private const string ACTAG_APP_CONFIG_BLOB = "APP_CONFIG_BLOB";
// This class has an unmanaged representation so be aware you will need to make edits in vm\object.h if you change the order
// of these fields or add new ones.
@@ -87,7 +64,7 @@ namespace System
private String _AppBase; // for compat with v1.1
#pragma warning restore 169
[OptionalField(VersionAdded = 2)]
- private AppDomainInitializer _AppDomainInitializer;
+ private AppDomainInitializer _AppDomainInitializer;
[OptionalField(VersionAdded = 2)]
private string[] _AppDomainInitializerArguments;
@@ -125,7 +102,8 @@ namespace System
internal AppDomainSetup(AppDomainSetup copy, bool copyDomainBoundData)
{
string[] mine = Value;
- if(copy != null) {
+ if (copy != null)
+ {
string[] other = copy.Value;
int mineSize = _Entries.Length;
int otherSize = other.Length;
@@ -152,7 +130,7 @@ namespace System
else
_AppDomainInitializer = null;
- _ConfigurationBytes = copy.GetConfigurationBytes();
+ _ConfigurationBytes = null;
#if FEATURE_COMINTEROP
_DisableInterfaceCache = copy._DisableInterfaceCache;
#endif // FEATURE_COMINTEROP
@@ -171,7 +149,7 @@ namespace System
#endif
}
- else
+ else
_LoaderOptimization = LoaderOptimization.NotSpecified;
}
@@ -180,39 +158,37 @@ namespace System
_LoaderOptimization = LoaderOptimization.NotSpecified;
}
- internal void SetupDefaults(string imageLocation, bool imageLocationAlreadyNormalized = false) {
- char[] sep = {'\\', '/'};
+ internal void SetupDefaults(string imageLocation, bool imageLocationAlreadyNormalized = false)
+ {
+ char[] sep = { '\\', '/' };
int i = imageLocation.LastIndexOfAny(sep);
- if (i == -1) {
+ if (i == -1)
+ {
ApplicationName = imageLocation;
}
- else {
- ApplicationName = imageLocation.Substring(i+1);
- string appBase = imageLocation.Substring(0, i+1);
+ else
+ {
+ ApplicationName = imageLocation.Substring(i + 1);
+ string appBase = imageLocation.Substring(0, i + 1);
if (imageLocationAlreadyNormalized)
- Value[(int) LoaderInformation.ApplicationBaseValue] = appBase;
- else
+ Value[(int)LoaderInformation.ApplicationBaseValue] = appBase;
+ else
ApplicationBase = appBase;
}
- ConfigurationFile = ApplicationName + AppDomainSetup.ConfigurationExtension;
}
internal string[] Value
{
- get {
- if( _Entries == null)
+ get
+ {
+ if (_Entries == null)
_Entries = new String[(int)LoaderInformation.LoaderMaximum];
return _Entries;
}
}
- internal String GetUnsecureApplicationBase()
- {
- return Value[(int) LoaderInformation.ApplicationBaseValue];
- }
-
public string AppDomainManagerAssembly
{
get { return _AppDomainManagerAssembly; }
@@ -228,233 +204,17 @@ namespace System
public String ApplicationBase
{
[Pure]
- get {
- return VerifyDir(GetUnsecureApplicationBase(), false);
- }
-
- set {
- Value[(int) LoaderInformation.ApplicationBaseValue] = NormalizePath(value, false);
- }
- }
-
- private String NormalizePath(String path, bool useAppBase)
- {
- if(path == null)
- return null;
-
- // If we add very long file name support ("\\?\") to the Path class then this is unnecesary,
- // but we do not plan on doing this for now.
-
- // Long path checks can be quirked, and as loading default quirks too early in the setup of an AppDomain is risky
- // we'll avoid checking path lengths- we'll still fail at MAX_PATH later if we're !useAppBase when we call Path's
- // NormalizePath.
- if (!useAppBase)
- path = Security.Util.URLString.PreProcessForExtendedPathRemoval(
- checkPathLength: false,
- url: path,
- isFileUrl: false);
-
-
- int len = path.Length;
- if (len == 0)
- return null;
-
-#if !PLATFORM_UNIX
- bool UNCpath = false;
-#endif // !PLATFORM_UNIX
-
- if ((len > 7) &&
- (String.Compare( path, 0, "file:", 0, 5, StringComparison.OrdinalIgnoreCase) == 0)) {
- int trim;
-
- if (path[6] == '\\') {
- if ((path[7] == '\\') || (path[7] == '/')) {
-
- // Don't allow "file:\\\\", because we can't tell the difference
- // with it for "file:\\" + "\\server" and "file:\\\" + "\localpath"
- if ( (len > 8) &&
- ((path[8] == '\\') || (path[8] == '/')) )
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPathChars"));
-
- // file:\\\ means local path
- else
-#if !PLATFORM_UNIX
- trim = 8;
-#else
- // For Unix platform, trim the first 7 charcaters only.
- // Trimming the first 8 characters will cause
- // the root path separator to be trimmed away,
- // and the absolute local path becomes a relative local path.
- trim = 7;
-#endif // !PLATFORM_UNIX
- }
-
- // file:\\ means remote server
- else {
- trim = 5;
-#if !PLATFORM_UNIX
- UNCpath = true;
-#endif // !PLATFORM_UNIX
- }
- }
-
- // local path
- else if (path[7] == '/')
-#if !PLATFORM_UNIX
- trim = 8;
-#else
- // For Unix platform, trim the first 7 characters only.
- // Trimming the first 8 characters will cause
- // the root path separator to be trimmed away,
- // and the absolute local path becomes a relative local path.
- trim = 7;
-#endif // !PLATFORM_UNIX
-
- // remote
- else {
- // file://\\remote
- if ( (len > 8) && (path[7] == '\\') && (path[8] == '\\') )
- trim = 7;
- else { // file://remote
- trim = 5;
-#if !PLATFORM_UNIX
- // Create valid UNC path by changing
- // all occurences of '/' to '\\' in path
- System.Text.StringBuilder winPathBuilder =
- new System.Text.StringBuilder(len);
- for (int i = 0; i < len; i++) {
- char c = path[i];
- if (c == '/')
- winPathBuilder.Append('\\');
- else
- winPathBuilder.Append(c);
- }
- path = winPathBuilder.ToString();
-#endif // !PLATFORM_UNIX
- }
-#if !PLATFORM_UNIX
- UNCpath = true;
-#endif // !PLATFORM_UNIX
- }
-
- path = path.Substring(trim);
- len -= trim;
- }
-
-#if !PLATFORM_UNIX
- bool localPath;
-
- // UNC
- if (UNCpath ||
- ( (len > 1) &&
- ( (path[0] == '/') || (path[0] == '\\') ) &&
- ( (path[1] == '/') || (path[1] == '\\') ) ))
- localPath = false;
-
- else {
- int colon = path.IndexOf(':') + 1;
-
- // protocol other than file:
- if ((colon != 0) &&
- (len > colon+1) &&
- ( (path[colon] == '/') || (path[colon] == '\\') ) &&
- ( (path[colon+1] == '/') || (path[colon+1] == '\\') ))
- localPath = false;
-
- else
- localPath = true;
- }
-
- if (localPath)
-#else
- if ( (len == 1) ||
- ( (path[0] != '/') && (path[0] != '\\') ) )
-#endif // !PLATFORM_UNIX
+ get
{
-
- if (useAppBase &&
- ( (len == 1) || (path[1] != ':') )) {
- String appBase = Value[(int) LoaderInformation.ApplicationBaseValue];
-
- if ((appBase == null) || (appBase.Length == 0))
- throw new MemberAccessException(Environment.GetResourceString("AppDomain_AppBaseNotSet"));
-
- StringBuilder result = StringBuilderCache.Acquire();
-
- bool slash = false;
- if ((path[0] == '/') || (path[0] == '\\')) {
- string pathRoot = AppDomain.NormalizePath(appBase, fullCheck: false);
- pathRoot = pathRoot.Substring(0, IO.PathInternal.GetRootLength(pathRoot));
-
- if (pathRoot.Length == 0) { // URL
- int index = appBase.IndexOf(":/", StringComparison.Ordinal);
- if (index == -1)
- index = appBase.IndexOf(":\\", StringComparison.Ordinal);
-
- // Get past last slashes of "url:http://"
- int urlLen = appBase.Length;
- for (index += 1;
- (index < urlLen) && ((appBase[index] == '/') || (appBase[index] == '\\'));
- index++);
-
- // Now find the next slash to get domain name
- for(; (index < urlLen) && (appBase[index] != '/') && (appBase[index] != '\\');
- index++);
-
- pathRoot = appBase.Substring(0, index);
- }
-
- result.Append(pathRoot);
- slash = true;
- }
- else
- result.Append(appBase);
-
- // Make sure there's a slash separator (and only one)
- int aLen = result.Length - 1;
- if ((result[aLen] != '/') &&
- (result[aLen] != '\\')) {
- if (!slash) {
-#if !PLATFORM_UNIX
- if (appBase.IndexOf(":/", StringComparison.Ordinal) == -1)
- result.Append('\\');
- else
-#endif // !PLATFORM_UNIX
- result.Append('/');
- }
- }
- else if (slash)
- result.Remove(aLen, 1);
-
- result.Append(path);
- path = StringBuilderCache.GetStringAndRelease(result);
- }
- else
- path = AppDomain.NormalizePath(path, fullCheck: true);
+ return Value[(int)LoaderInformation.ApplicationBaseValue];
}
- return path;
- }
-
- public String ConfigurationFile
- {
- get {
- return VerifyDir(Value[(int) LoaderInformation.ConfigurationFileValue], true);
- }
-
- set {
- Value[(int) LoaderInformation.ConfigurationFileValue] = value;
+ set
+ {
+ Value[(int)LoaderInformation.ApplicationBaseValue] = (value == null || value.Length == 0)?null:Path.GetFullPath(value);
}
}
-
- public byte[] GetConfigurationBytes()
- {
- if (_ConfigurationBytes == null)
- return null;
-
- return (byte[]) _ConfigurationBytes.Clone();
- }
-
+
// only needed by AppDomain.Setup(). Not really needed by users.
internal Dictionary<string, object> GetCompatibilityFlags()
{
@@ -469,10 +229,11 @@ namespace System
if (switches != null)
{
_CompatFlags = new Dictionary<string, object>();
- foreach (String str in switches)
+ foreach (String str in switches)
{
#if FEATURE_RANDOMIZED_STRING_HASHING
- if(StringComparer.OrdinalIgnoreCase.Equals("UseRandomizedStringHashAlgorithm", str)) {
+ if (StringComparer.OrdinalIgnoreCase.Equals("UseRandomizedStringHashAlgorithm", str))
+ {
_UseRandomizedStringHashing = true;
}
#endif
@@ -483,62 +244,55 @@ namespace System
{
_CompatFlags = null;
}
-
}
// A target Framework moniker, in a format parsible by the FrameworkName class.
- public String TargetFrameworkName {
- get {
+ public String TargetFrameworkName
+ {
+ get
+ {
return _TargetFrameworkName;
}
- set {
+ set
+ {
_TargetFrameworkName = value;
}
}
- private String VerifyDir(String dir, bool normalize)
- {
- if (dir != null) {
- if (dir.Length == 0)
- dir = null;
- else {
- if (normalize)
- dir = NormalizePath(dir, true);
- }
- }
-
- return dir;
- }
-
public String ApplicationName
{
- get {
- return Value[(int) LoaderInformation.ApplicationNameValue];
+ get
+ {
+ return Value[(int)LoaderInformation.ApplicationNameValue];
}
- set {
- Value[(int) LoaderInformation.ApplicationNameValue] = value;
+ set
+ {
+ Value[(int)LoaderInformation.ApplicationNameValue] = value;
}
}
- [XmlIgnoreMember]
public AppDomainInitializer AppDomainInitializer
{
- get {
+ get
+ {
return _AppDomainInitializer;
}
- set {
+ set
+ {
_AppDomainInitializer = value;
}
}
public string[] AppDomainInitializerArguments
{
- get {
+ get
+ {
return _AppDomainInitializerArguments;
}
- set {
+ set
+ {
_AppDomainInitializerArguments = value;
}
}
@@ -555,7 +309,6 @@ namespace System
_ApplicationTrust = permissionSetName;
}
- [XmlIgnoreMember]
internal ApplicationTrust ApplicationTrust
{
get
@@ -566,36 +319,32 @@ namespace System
public LoaderOptimization LoaderOptimization
{
- get {
+ get
+ {
return _LoaderOptimization;
}
- set {
+ set
+ {
_LoaderOptimization = value;
}
}
internal static string LoaderOptimizationKey
{
- get {
+ get
+ {
return LOADER_OPTIMIZATION;
}
}
- internal static string ConfigurationExtension
- {
- get {
- return CONFIGURATION_EXTENSION;
- }
- }
-
static internal int Locate(String s)
{
- if(String.IsNullOrEmpty(s))
+ if (String.IsNullOrEmpty(s))
return -1;
- Debug.Assert('A' == ACTAG_APP_BASE_URL[0] , "Assumption violated");
- if (s[0]=='A' && s == ACTAG_APP_BASE_URL)
+ Debug.Assert('A' == ACTAG_APP_BASE_URL[0], "Assumption violated");
+ if (s[0] == 'A' && s == ACTAG_APP_BASE_URL)
return (int)LoaderInformation.ApplicationBaseValue;
return -1;
diff --git a/src/mscorlib/src/System/AppDomainUnloadedException.cs b/src/mscorlib/src/System/AppDomainUnloadedException.cs
index 30bee7c7de..52cbb980af 100644
--- a/src/mscorlib/src/System/AppDomainUnloadedException.cs
+++ b/src/mscorlib/src/System/AppDomainUnloadedException.cs
@@ -11,21 +11,25 @@
**
=============================================================================*/
-namespace System {
- using System.Runtime.Serialization;
+using System.Runtime.Serialization;
+namespace System
+{
[Serializable]
- internal class AppDomainUnloadedException : SystemException {
- public AppDomainUnloadedException()
- : base(Environment.GetResourceString("Arg_AppDomainUnloadedException")) {
- SetErrorCode(__HResults.COR_E_APPDOMAINUNLOADED);
+ internal class AppDomainUnloadedException : SystemException
+ {
+ public AppDomainUnloadedException()
+ : base(SR.Arg_AppDomainUnloadedException)
+ {
+ HResult = __HResults.COR_E_APPDOMAINUNLOADED;
}
//
//This constructor is required for serialization.
//
- protected AppDomainUnloadedException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ protected AppDomainUnloadedException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
}
}
}
diff --git a/src/mscorlib/src/System/ArgIterator.cs b/src/mscorlib/src/System/ArgIterator.cs
index 83a60b95e1..584f85fbd3 100644
--- a/src/mscorlib/src/System/ArgIterator.cs
+++ b/src/mscorlib/src/System/ArgIterator.cs
@@ -2,8 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System {
-
+namespace System
+{
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -24,10 +24,10 @@ namespace System {
// Note, sigPtrLen is actually a DWORD, but on 64bit systems this structure becomes
// 8-byte aligned, which requires us to pad it.
-
+
private IntPtr ArgPtr; // Pointer to remaining args.
- private int RemainingArgs; // # of remaining args.
-
+ private int RemainingArgs; // # of remaining args.
+
#if VARARGS_ENABLED //The JIT doesn't support Varargs calling convention.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern ArgIterator(IntPtr arglist);
@@ -131,55 +131,55 @@ namespace System {
// Inherited from object
public override bool Equals(Object o)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NYI"));
+ throw new NotSupportedException(SR.NotSupported_NYI);
}
#else
public ArgIterator(RuntimeArgumentHandle arglist)
{
- throw new PlatformNotSupportedException(); //The JIT requires work to enable ArgIterator see: https://github.com/dotnet/coreclr/issues/9204.
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204
}
[CLSCompliant(false)]
public unsafe ArgIterator(RuntimeArgumentHandle arglist, void* ptr)
{
- throw new PlatformNotSupportedException(); //The JIT requires work to enable ArgIterator see: https://github.com/dotnet/coreclr/issues/9204.
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204
}
- public void End()
- {
- throw new PlatformNotSupportedException(); //The JIT requires work to enable ArgIterator see: https://github.com/dotnet/coreclr/issues/9204.
+ public void End()
+ {
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204
}
- public override bool Equals(Object o)
- {
- throw new PlatformNotSupportedException(); //The JIT requires work to enable ArgIterator see: https://github.com/dotnet/coreclr/issues/9204.
+ public override bool Equals(Object o)
+ {
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204
}
public override int GetHashCode()
- {
- throw new PlatformNotSupportedException(); //The JIT requires work to enable ArgIterator see: https://github.com/dotnet/coreclr/issues/9204.
+ {
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204
}
[System.CLSCompliantAttribute(false)]
public System.TypedReference GetNextArg()
{
- throw new PlatformNotSupportedException(); //The JIT requires work to enable ArgIterator see: https://github.com/dotnet/coreclr/issues/9204.
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204
}
[System.CLSCompliantAttribute(false)]
public System.TypedReference GetNextArg(System.RuntimeTypeHandle rth)
{
- throw new PlatformNotSupportedException(); //The JIT requires work to enable ArgIterator see: https://github.com/dotnet/coreclr/issues/9204.
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204
}
public unsafe System.RuntimeTypeHandle GetNextArgType()
{
- throw new PlatformNotSupportedException(); //The JIT requires work to enable ArgIterator see: https://github.com/dotnet/coreclr/issues/9204.
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204
}
public int GetRemainingCount()
- {
- throw new PlatformNotSupportedException(); //The JIT requires work to enable ArgIterator see: https://github.com/dotnet/coreclr/issues/9204.
+ {
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ArgIterator); // https://github.com/dotnet/coreclr/issues/9204
}
#endif //VARARGS_ENABLED
}
diff --git a/src/mscorlib/src/System/ArgumentException.cs b/src/mscorlib/src/System/ArgumentException.cs
deleted file mode 100644
index fe054a9aa0..0000000000
--- a/src/mscorlib/src/System/ArgumentException.cs
+++ /dev/null
@@ -1,97 +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.
-
-/*=============================================================================
-**
-**
-**
-** Purpose: Exception class for invalid arguments to a method.
-**
-**
-=============================================================================*/
-
-using System.Globalization;
-using System.Runtime.Serialization;
-
-namespace System
-{
- // The ArgumentException is thrown when an argument does not meet
- // the contract of the method. Ideally it should give a meaningful error
- // message describing what was wrong and which parameter is incorrect.
- //
- [Serializable]
- public class ArgumentException : SystemException, ISerializable
- {
- private String _paramName;
-
- // Creates a new ArgumentException with its message
- // string set to the empty string.
- public ArgumentException()
- : base(SR.Arg_ArgumentException)
- {
- HResult = __HResults.COR_E_ARGUMENT;
- }
-
- // Creates a new ArgumentException with its message
- // string set to message.
- //
- public ArgumentException(String message)
- : base(message)
- {
- HResult = __HResults.COR_E_ARGUMENT;
- }
-
- public ArgumentException(String message, Exception innerException)
- : base(message, innerException)
- {
- HResult = __HResults.COR_E_ARGUMENT;
- }
-
- public ArgumentException(String message, String paramName, Exception innerException)
- : base(message, innerException)
- {
- _paramName = paramName;
- HResult = __HResults.COR_E_ARGUMENT;
- }
-
- public ArgumentException(String message, String paramName)
- : base(message)
- {
- _paramName = paramName;
- HResult = __HResults.COR_E_ARGUMENT;
- }
-
- protected ArgumentException(SerializationInfo info, StreamingContext context)
- : base(info, context)
- {
- _paramName = info.GetString("ParamName");
- }
-
- public override void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- base.GetObjectData(info, context);
- info.AddValue("ParamName", _paramName, typeof(String));
- }
-
- public override String Message
- {
- get
- {
- String s = base.Message;
- if (!String.IsNullOrEmpty(_paramName))
- {
- String resourceString = SR.Format(SR.Arg_ParamName_Name, _paramName);
- return s + Environment.NewLine + resourceString;
- }
- else
- return s;
- }
- }
-
- public virtual String ParamName
- {
- get { return _paramName; }
- }
- }
-}
diff --git a/src/mscorlib/src/System/ArgumentOutOfRangeException.cs b/src/mscorlib/src/System/ArgumentOutOfRangeException.cs
index 59a8434089..90837810d1 100644
--- a/src/mscorlib/src/System/ArgumentOutOfRangeException.cs
+++ b/src/mscorlib/src/System/ArgumentOutOfRangeException.cs
@@ -11,92 +11,107 @@
**
=============================================================================*/
-namespace System {
- using System;
- using System.Runtime.Remoting;
- using System.Runtime.Serialization;
- using System.Globalization;
- using System.Diagnostics.Contracts;
-
+using System;
+using System.Runtime.Remoting;
+using System.Runtime.Serialization;
+using System.Globalization;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
// The ArgumentOutOfRangeException is thrown when an argument
// is outside the legal range for that argument.
[Serializable]
- public class ArgumentOutOfRangeException : ArgumentException, ISerializable {
-
+ public class ArgumentOutOfRangeException : ArgumentException, ISerializable
+ {
private static volatile String _rangeMessage;
private Object m_actualValue;
- private static String RangeMessage {
- get {
+ private static String RangeMessage
+ {
+ get
+ {
if (_rangeMessage == null)
- _rangeMessage = Environment.GetResourceString("Arg_ArgumentOutOfRangeException");
+ _rangeMessage = SR.Arg_ArgumentOutOfRangeException;
return _rangeMessage;
}
}
// Creates a new ArgumentOutOfRangeException with its message
// string set to a default message explaining an argument was out of range.
- public ArgumentOutOfRangeException()
- : base(RangeMessage) {
- SetErrorCode(__HResults.COR_E_ARGUMENTOUTOFRANGE);
+ public ArgumentOutOfRangeException()
+ : base(RangeMessage)
+ {
+ HResult = __HResults.COR_E_ARGUMENTOUTOFRANGE;
}
-
- public ArgumentOutOfRangeException(String paramName)
- : base(RangeMessage, paramName) {
- SetErrorCode(__HResults.COR_E_ARGUMENTOUTOFRANGE);
+
+ public ArgumentOutOfRangeException(String paramName)
+ : base(RangeMessage, paramName)
+ {
+ HResult = __HResults.COR_E_ARGUMENTOUTOFRANGE;
}
-
- public ArgumentOutOfRangeException(String paramName, String message)
- : base(message, paramName) {
- SetErrorCode(__HResults.COR_E_ARGUMENTOUTOFRANGE);
+
+ public ArgumentOutOfRangeException(String paramName, String message)
+ : base(message, paramName)
+ {
+ HResult = __HResults.COR_E_ARGUMENTOUTOFRANGE;
}
- public ArgumentOutOfRangeException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(__HResults.COR_E_ARGUMENTOUTOFRANGE);
+ public ArgumentOutOfRangeException(String message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_ARGUMENTOUTOFRANGE;
}
-
+
// We will not use this in the classlibs, but we'll provide it for
// anyone that's really interested so they don't have to stick a bunch
// of printf's in their code.
- public ArgumentOutOfRangeException(String paramName, Object actualValue, String message)
- : base(message, paramName) {
+ public ArgumentOutOfRangeException(String paramName, Object actualValue, String message)
+ : base(message, paramName)
+ {
m_actualValue = actualValue;
- SetErrorCode(__HResults.COR_E_ARGUMENTOUTOFRANGE);
+ HResult = __HResults.COR_E_ARGUMENTOUTOFRANGE;
}
-
- public override String Message {
- get {
+
+ public override String Message
+ {
+ get
+ {
String s = base.Message;
- if (m_actualValue != null) {
- String valueMessage = Environment.GetResourceString("ArgumentOutOfRange_ActualValue", m_actualValue.ToString());
+ if (m_actualValue != null)
+ {
+ String valueMessage = SR.Format(SR.ArgumentOutOfRange_ActualValue, m_actualValue.ToString());
if (s == null)
return valueMessage;
- return s + Environment.NewLine + valueMessage;
+ return s + Environment.NewLine + valueMessage;
}
return s;
}
}
-
+
// Gets the value of the argument that caused the exception.
// Note - we don't set this anywhere in the class libraries in
// version 1, but it might come in handy for other developers who
// want to avoid sticking printf's in their code.
- public virtual Object ActualValue {
+ public virtual Object ActualValue
+ {
get { return m_actualValue; }
}
-
- public override void GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
base.GetObjectData(info, context);
info.AddValue("ActualValue", m_actualValue, typeof(Object));
}
-
- protected ArgumentOutOfRangeException(SerializationInfo info, StreamingContext context) : base(info, context) {
+
+ protected ArgumentOutOfRangeException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
m_actualValue = info.GetValue("ActualValue", typeof(Object));
}
}
diff --git a/src/mscorlib/src/System/Array.cs b/src/mscorlib/src/System/Array.cs
index 23989f30fb..05c4804cc5 100644
--- a/src/mscorlib/src/System/Array.cs
+++ b/src/mscorlib/src/System/Array.cs
@@ -8,32 +8,35 @@
** Purpose: Base class which can be used to access any array
**
===========================================================*/
-namespace System {
-
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.Versioning;
- using System.Security;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.Versioning;
+using System.Security;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
// Note that we make a T[] (single-dimensional w/ zero as the lower bound) implement both
// IList<U> and IReadOnlyList<U>, where T : U dynamically. See the SZArrayHelper class for details.
[Serializable]
- public abstract class Array : ICloneable, IList, IStructuralComparable, IStructuralEquatable
+ public abstract class Array : ICloneable, IList, IStructuralComparable, IStructuralEquatable
{
// This ctor exists solely to prevent C# from generating a protected .ctor that violates the surface area. I really want this to be a
// "protected-and-internal" rather than "internal" but C# has no keyword for the former.
- internal Array() {}
+ internal Array() { }
- public static ReadOnlyCollection<T> AsReadOnly<T>(T[] array) {
- if (array == null) {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
+ public static ReadOnlyCollection<T> AsReadOnly<T>(T[] array)
+ {
+ if (array == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
Contract.Ensures(Contract.Result<ReadOnlyCollection<T>>() != null);
@@ -41,22 +44,25 @@ namespace System {
return new ReadOnlyCollection<T>(array);
}
- public static void Resize<T>(ref T[] array, int newSize) {
+ public static void Resize<T>(ref T[] array, int newSize)
+ {
if (newSize < 0)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.newSize, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
Contract.Ensures(Contract.ValueAtReturn(out array) != null);
Contract.Ensures(Contract.ValueAtReturn(out array).Length == newSize);
Contract.EndContractBlock();
- T[] larray = array;
- if (larray == null) {
+ T[] larray = array;
+ if (larray == null)
+ {
array = new T[newSize];
return;
}
-
- if (larray.Length != newSize) {
+
+ if (larray.Length != newSize)
+ {
T[] newArray = new T[newSize];
- Array.Copy(larray, 0, newArray, 0, larray.Length > newSize? newSize : larray.Length);
+ Array.Copy(larray, 0, newArray, 0, larray.Length > newSize ? newSize : larray.Length);
array = newArray;
}
}
@@ -76,9 +82,9 @@ namespace System {
RuntimeType t = elementType.UnderlyingSystemType as RuntimeType;
if (t == null)
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_MustBeType, ExceptionArgument.elementType);
- return InternalCreate((void*)t.TypeHandle.Value,1,&length,null);
+ return InternalCreate((void*)t.TypeHandle.Value, 1, &length, null);
}
-
+
public unsafe static Array CreateInstance(Type elementType, int length1, int length2)
{
if ((object)elementType == null)
@@ -98,9 +104,9 @@ namespace System {
int* pLengths = stackalloc int[2];
pLengths[0] = length1;
pLengths[1] = length2;
- return InternalCreate((void*)t.TypeHandle.Value,2,pLengths,null);
+ return InternalCreate((void*)t.TypeHandle.Value, 2, pLengths, null);
}
-
+
public unsafe static Array CreateInstance(Type elementType, int length1, int length2, int length3)
{
if ((object)elementType == null)
@@ -124,9 +130,9 @@ namespace System {
pLengths[0] = length1;
pLengths[1] = length2;
pLengths[2] = length3;
- return InternalCreate((void*)t.TypeHandle.Value,3,pLengths,null);
+ return InternalCreate((void*)t.TypeHandle.Value, 3, pLengths, null);
}
-
+
public unsafe static Array CreateInstance(Type elementType, params int[] lengths)
{
if ((object)elementType == null)
@@ -152,12 +158,13 @@ namespace System {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.lengths, i, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
fixed (int* pLengths = &lengths[0])
- return InternalCreate((void*)t.TypeHandle.Value,lengths.Length,pLengths,null);
+ return InternalCreate((void*)t.TypeHandle.Value, lengths.Length, pLengths, null);
}
public static Array CreateInstance(Type elementType, params long[] lengths)
{
- if( lengths == null) {
+ if (lengths == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.lengths);
}
if (lengths.Length == 0)
@@ -165,22 +172,22 @@ namespace System {
Contract.Ensures(Contract.Result<Array>() != null);
Contract.Ensures(Contract.Result<Array>().Rank == lengths.Length);
Contract.EndContractBlock();
-
+
int[] intLengths = new int[lengths.Length];
- for (int i = 0; i < lengths.Length; ++i)
+ for (int i = 0; i < lengths.Length; ++i)
{
long len = lengths[i];
if (len > Int32.MaxValue || len < Int32.MinValue)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.len, ExceptionResource.ArgumentOutOfRange_HugeArrayNotSupported);
- intLengths[i] = (int) len;
+ intLengths[i] = (int)len;
}
return Array.CreateInstance(elementType, intLengths);
}
-
- public unsafe static Array CreateInstance(Type elementType, int[] lengths,int[] lowerBounds)
+
+ public unsafe static Array CreateInstance(Type elementType, int[] lengths, int[] lowerBounds)
{
if (elementType == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.elementType);
@@ -204,17 +211,17 @@ namespace System {
// a good exception message if they are not; however we check this again inside the execution
// engine's low level allocation function after having made a copy of the array to prevent a
// malicious caller from mutating the array after this check.
- for (int i=0;i<lengths.Length;i++)
+ for (int i = 0; i < lengths.Length; i++)
if (lengths[i] < 0)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.lengths, i, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
fixed (int* pLengths = &lengths[0])
- fixed(int* pLowerBounds = &lowerBounds[0])
- return InternalCreate((void*)t.TypeHandle.Value,lengths.Length,pLengths,pLowerBounds);
+ fixed (int* pLowerBounds = &lowerBounds[0])
+ return InternalCreate((void*)t.TypeHandle.Value, lengths.Length, pLengths, pLowerBounds);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private unsafe static extern Array InternalCreate(void* elementType,int rank,int *pLengths,int *pLowerBounds);
+ private unsafe static extern Array InternalCreate(void* elementType, int rank, int* pLengths, int* pLowerBounds);
internal static Array UnsafeCreateInstance(Type elementType, int length)
{
@@ -240,11 +247,11 @@ namespace System {
Copy(sourceArray, sourceArray.GetLowerBound(0), destinationArray, destinationArray.GetLowerBound(0), length, false);
}
-
+
// Copies length elements from sourceArray, starting at sourceIndex, to
// destinationArray, starting at destinationIndex.
//
- public static void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length)
+ public static void Copy(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length)
{
Copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length, false);
}
@@ -271,7 +278,7 @@ namespace System {
if (length > Int32.MaxValue || length < Int32.MinValue)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length, ExceptionResource.ArgumentOutOfRange_HugeArrayNotSupported);
- Array.Copy(sourceArray, destinationArray, (int) length);
+ Array.Copy(sourceArray, destinationArray, (int)length);
}
public static void Copy(Array sourceArray, long sourceIndex, Array destinationArray, long destinationIndex, long length)
@@ -283,16 +290,16 @@ namespace System {
if (length > Int32.MaxValue || length < Int32.MinValue)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length, ExceptionResource.ArgumentOutOfRange_HugeArrayNotSupported);
- Array.Copy(sourceArray, (int) sourceIndex, destinationArray, (int) destinationIndex, (int) length);
+ Array.Copy(sourceArray, (int)sourceIndex, destinationArray, (int)destinationIndex, (int)length);
}
-
+
// Sets length elements in array to 0 (or null for Object arrays), starting
// at index.
//
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void Clear(Array array, int index, int length);
-
+
// The various Get values...
public unsafe Object GetValue(params int[] indices)
{
@@ -303,11 +310,11 @@ namespace System {
Contract.EndContractBlock();
TypedReference elemref = new TypedReference();
- fixed(int* pIndices = &indices[0])
+ fixed (int* pIndices = &indices[0])
InternalGetReference(&elemref, indices.Length, pIndices);
return TypedReference.InternalToObject(&elemref);
}
-
+
public unsafe Object GetValue(int index)
{
if (Rank != 1)
@@ -318,7 +325,7 @@ namespace System {
InternalGetReference(&elemref, 1, &index);
return TypedReference.InternalToObject(&elemref);
}
-
+
public unsafe Object GetValue(int index1, int index2)
{
if (Rank != 2)
@@ -333,7 +340,7 @@ namespace System {
InternalGetReference(&elemref, 2, pIndices);
return TypedReference.InternalToObject(&elemref);
}
-
+
public unsafe Object GetValue(int index1, int index2, int index3)
{
if (Rank != 3)
@@ -356,7 +363,7 @@ namespace System {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_HugeArrayNotSupported);
Contract.EndContractBlock();
- return this.GetValue((int) index);
+ return this.GetValue((int)index);
}
public Object GetValue(long index1, long index2)
@@ -367,7 +374,7 @@ namespace System {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index2, ExceptionResource.ArgumentOutOfRange_HugeArrayNotSupported);
Contract.EndContractBlock();
- return this.GetValue((int) index1, (int) index2);
+ return this.GetValue((int)index1, (int)index2);
}
public Object GetValue(long index1, long index2, long index3)
@@ -379,8 +386,8 @@ namespace System {
if (index3 > Int32.MaxValue || index3 < Int32.MinValue)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index3, ExceptionResource.ArgumentOutOfRange_HugeArrayNotSupported);
Contract.EndContractBlock();
-
- return this.GetValue((int) index1, (int) index2, (int) index3);
+
+ return this.GetValue((int)index1, (int)index2, (int)index3);
}
public Object GetValue(params long[] indices)
@@ -393,19 +400,19 @@ namespace System {
int[] intIndices = new int[indices.Length];
- for (int i = 0; i < indices.Length; ++i)
+ for (int i = 0; i < indices.Length; ++i)
{
long index = indices[i];
if (index > Int32.MaxValue || index < Int32.MinValue)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_HugeArrayNotSupported);
- intIndices[i] = (int) index;
+ intIndices[i] = (int)index;
}
return this.GetValue(intIndices);
}
-
- public unsafe void SetValue(Object value,int index)
+
+ public unsafe void SetValue(Object value, int index)
{
if (Rank != 1)
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_Need1DArray);
@@ -413,10 +420,10 @@ namespace System {
TypedReference elemref = new TypedReference();
InternalGetReference(&elemref, 1, &index);
- InternalSetValue(&elemref,value);
+ InternalSetValue(&elemref, value);
}
-
- public unsafe void SetValue(Object value,int index1, int index2)
+
+ public unsafe void SetValue(Object value, int index1, int index2)
{
if (Rank != 2)
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_Need2DArray);
@@ -428,10 +435,10 @@ namespace System {
TypedReference elemref = new TypedReference();
InternalGetReference(&elemref, 2, pIndices);
- InternalSetValue(&elemref,value);
+ InternalSetValue(&elemref, value);
}
-
- public unsafe void SetValue(Object value,int index1, int index2, int index3)
+
+ public unsafe void SetValue(Object value, int index1, int index2, int index3)
{
if (Rank != 3)
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_Need3DArray);
@@ -444,10 +451,10 @@ namespace System {
TypedReference elemref = new TypedReference();
InternalGetReference(&elemref, 3, pIndices);
- InternalSetValue(&elemref,value);
+ InternalSetValue(&elemref, value);
}
-
- public unsafe void SetValue(Object value,params int[] indices)
+
+ public unsafe void SetValue(Object value, params int[] indices)
{
if (indices == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.indices);
@@ -456,9 +463,9 @@ namespace System {
Contract.EndContractBlock();
TypedReference elemref = new TypedReference();
- fixed(int* pIndices = &indices[0])
+ fixed (int* pIndices = &indices[0])
InternalGetReference(&elemref, indices.Length, pIndices);
- InternalSetValue(&elemref,value);
+ InternalSetValue(&elemref, value);
}
public void SetValue(Object value, long index)
@@ -467,7 +474,7 @@ namespace System {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_HugeArrayNotSupported);
Contract.EndContractBlock();
- this.SetValue(value, (int) index);
+ this.SetValue(value, (int)index);
}
public void SetValue(Object value, long index1, long index2)
@@ -478,7 +485,7 @@ namespace System {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index2, ExceptionResource.ArgumentOutOfRange_HugeArrayNotSupported);
Contract.EndContractBlock();
- this.SetValue(value, (int) index1, (int) index2);
+ this.SetValue(value, (int)index1, (int)index2);
}
public void SetValue(Object value, long index1, long index2, long index3)
@@ -491,7 +498,7 @@ namespace System {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index3, ExceptionResource.ArgumentOutOfRange_HugeArrayNotSupported);
Contract.EndContractBlock();
- this.SetValue(value, (int) index1, (int) index2, (int) index3);
+ this.SetValue(value, (int)index1, (int)index2, (int)index3);
}
public void SetValue(Object value, params long[] indices)
@@ -504,12 +511,12 @@ namespace System {
int[] intIndices = new int[indices.Length];
- for (int i = 0; i < indices.Length; ++i)
+ for (int i = 0; i < indices.Length; ++i)
{
long index = indices[i];
if (index > Int32.MaxValue || index < Int32.MinValue)
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_HugeArrayNotSupported);
- intIndices[i] = (int) index;
+ intIndices[i] = (int)index;
}
this.SetValue(value, intIndices);
@@ -517,23 +524,25 @@ namespace System {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
// reference to TypedReference is banned, so have to pass result as pointer
- private unsafe extern void InternalGetReference(void * elemRef, int rank, int * pIndices);
+ private unsafe extern void InternalGetReference(void* elemRef, int rank, int* pIndices);
// Ideally, we would like to use TypedReference.SetValue instead. Unfortunately, TypedReference.SetValue
// always throws not-supported exception
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private unsafe extern static void InternalSetValue(void * target, Object value);
+ private unsafe extern static void InternalSetValue(void* target, Object value);
- public extern int Length {
+ public extern int Length
+ {
[Pure]
[MethodImpl(MethodImplOptions.InternalCall)]
get;
}
- private static int GetMedian(int low, int hi) {
+ private static int GetMedian(int low, int hi)
+ {
// Note both may be negative, if we are dealing with arrays w/ negative lower bounds.
Contract.Requires(low <= hi);
- Debug.Assert( hi - low >= 0, "Length overflow!");
+ Debug.Assert(hi - low >= 0, "Length overflow!");
return low + ((hi - low) >> 1);
}
@@ -545,7 +554,8 @@ namespace System {
internal const int MaxArrayLength = 0X7FEFFFFF;
internal const int MaxByteArrayLength = 0x7FFFFFC7;
- public extern long LongLength {
+ public extern long LongLength
+ {
[Pure]
[MethodImpl(MethodImplOptions.InternalCall)]
get;
@@ -556,12 +566,14 @@ namespace System {
public extern int GetLength(int dimension);
[Pure]
- public long GetLongLength(int dimension) {
+ public long GetLongLength(int dimension)
+ {
//This method should throw an IndexOufOfRangeException for compat if dimension < 0 or >= Rank
return GetLength(dimension);
}
- public extern int Rank {
+ public extern int Rank
+ {
[Pure]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
@@ -582,20 +594,21 @@ namespace System {
int ICollection.Count
{ get { return Length; } }
-
+
// Returns an object appropriate for synchronizing access to this
// Array.
public Object SyncRoot
{ get { return this; } }
-
+
// Is this Array read-only?
public bool IsReadOnly
{ get { return false; } }
- public bool IsFixedSize {
+ public bool IsFixedSize
+ {
get { return true; }
}
-
+
// Is this Array synchronized (i.e., thread-safe)? If you want a synchronized
// collection, you can use SyncRoot as an object to synchronize your
// collection with. You could also call GetSynchronized()
@@ -604,7 +617,8 @@ namespace System {
{ get { return false; } }
- Object IList.this[int index] {
+ Object IList.this[int index]
+ {
get { return GetValue(index); }
set { SetValue(value, index); }
}
@@ -652,8 +666,10 @@ namespace System {
return MemberwiseClone();
}
- Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer) {
- if (other == null) {
+ Int32 IStructuralComparable.CompareTo(Object other, IComparer comparer)
+ {
+ if (other == null)
+ {
return 1;
}
@@ -667,39 +683,45 @@ namespace System {
int i = 0;
int c = 0;
- while (i < o.Length && c == 0) {
+ while (i < o.Length && c == 0)
+ {
object left = GetValue(i);
object right = o.GetValue(i);
c = comparer.Compare(left, right);
i++;
}
-
+
return c;
}
- Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer) {
-
- if (other == null) {
+ Boolean IStructuralEquatable.Equals(Object other, IEqualityComparer comparer)
+ {
+ if (other == null)
+ {
return false;
}
- if (Object.ReferenceEquals(this, other)) {
+ if (Object.ReferenceEquals(this, other))
+ {
return true;
}
Array o = other as Array;
- if (o == null || o.Length != this.Length) {
+ if (o == null || o.Length != this.Length)
+ {
return false;
}
int i = 0;
- while (i < o.Length) {
+ while (i < o.Length)
+ {
object left = GetValue(i);
object right = o.GetValue(i);
- if (!comparer.Equals(left, right)) {
+ if (!comparer.Equals(left, right))
+ {
return false;
}
i++;
@@ -709,18 +731,21 @@ namespace System {
}
// From System.Web.Util.HashCodeCombiner
- internal static int CombineHashCodes(int h1, int h2) {
+ internal static int CombineHashCodes(int h1, int h2)
+ {
return (((h1 << 5) + h1) ^ h2);
}
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer) {
+ int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
+ {
if (comparer == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.comparer);
Contract.EndContractBlock();
int ret = 0;
- for (int i = (this.Length >= 8 ? this.Length - 8 : 0); i < this.Length; i++) {
+ for (int i = (this.Length >= 8 ? this.Length - 8 : 0); i < this.Length; i++)
+ {
ret = CombineHashCodes(ret, comparer.GetHashCode(GetValue(i)));
}
@@ -741,15 +766,16 @@ namespace System {
// is larger than the given search value.
//
[Pure]
- public static int BinarySearch(Array array, Object value) {
- if (array==null)
+ public static int BinarySearch(Array array, Object value)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Contract.Ensures((Contract.Result<int>() >= array.GetLowerBound(0) && Contract.Result<int>() <= array.GetUpperBound(0)) || (Contract.Result<int>() < array.GetLowerBound(0) && ~Contract.Result<int>() <= array.GetUpperBound(0) + 1));
Contract.EndContractBlock();
int lb = array.GetLowerBound(0);
return BinarySearch(array, lb, array.Length, value, null);
}
-
+
// Searches a section of an array for a given element using a binary search
// algorithm. Elements of the array are compared to the search value using
// the IComparable interface, which must be implemented by all
@@ -764,10 +790,11 @@ namespace System {
// is larger than the given search value.
//
[Pure]
- public static int BinarySearch(Array array, int index, int length, Object value) {
+ public static int BinarySearch(Array array, int index, int length, Object value)
+ {
return BinarySearch(array, index, length, value, null);
}
-
+
// Searches an array for a given element using a binary search algorithm.
// Elements of the array are compared to the search value using the given
// IComparer interface. If comparer is null, elements of the
@@ -783,14 +810,15 @@ namespace System {
// is larger than the given search value.
//
[Pure]
- public static int BinarySearch(Array array, Object value, IComparer comparer) {
- if (array==null)
+ public static int BinarySearch(Array array, Object value, IComparer comparer)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Contract.EndContractBlock();
int lb = array.GetLowerBound(0);
return BinarySearch(array, lb, array.Length, value, comparer);
}
-
+
// Searches a section of an array for a given element using a binary search
// algorithm. Elements of the array are compared to the search value using
// the given IComparer interface. If comparer is null,
@@ -807,8 +835,9 @@ namespace System {
// is larger than the given search value.
//
[Pure]
- public static int BinarySearch(Array array, int index, int length, Object value, IComparer comparer) {
- if (array==null)
+ public static int BinarySearch(Array array, int index, int length, Object value, IComparer comparer)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Contract.EndContractBlock();
int lb = array.GetLowerBound(0);
@@ -820,9 +849,10 @@ namespace System {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
if (array.Rank != 1)
ThrowHelper.ThrowRankException(ExceptionResource.Rank_MultiDimNotSupported);
-
+
if (comparer == null) comparer = Comparer.Default;
- if (comparer == Comparer.Default) {
+ if (comparer == Comparer.Default)
+ {
int retval;
bool r = TrySZBinarySearch(array, index, length, value, out retval);
if (r)
@@ -830,45 +860,57 @@ namespace System {
}
int lo = index;
- int hi = index + length - 1;
+ int hi = index + length - 1;
Object[] objArray = array as Object[];
- if(objArray != null) {
- while (lo <= hi) {
+ if (objArray != null)
+ {
+ while (lo <= hi)
+ {
// i might overflow if lo and hi are both large positive numbers.
int i = GetMedian(lo, hi);
int c = 0;
- try {
+ try
+ {
c = comparer.Compare(objArray[i], value);
}
- catch (Exception e) {
+ catch (Exception e)
+ {
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_IComparerFailed, e);
}
if (c == 0) return i;
- if (c < 0) {
+ if (c < 0)
+ {
lo = i + 1;
}
- else {
+ else
+ {
hi = i - 1;
}
}
}
- else {
- while (lo <= hi) {
- int i = GetMedian(lo, hi);
+ else
+ {
+ while (lo <= hi)
+ {
+ int i = GetMedian(lo, hi);
int c = 0;
- try {
+ try
+ {
c = comparer.Compare(array.GetValue(i), value);
}
- catch (Exception e) {
+ catch (Exception e)
+ {
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_IComparerFailed, e);
}
if (c == 0) return i;
- if (c < 0) {
+ if (c < 0)
+ {
lo = i + 1;
}
- else {
+ else
+ {
hi = i - 1;
}
}
@@ -878,31 +920,35 @@ namespace System {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool TrySZBinarySearch(Array sourceArray, int sourceIndex, int count, Object value, out int retVal);
-
+
[Pure]
- public static int BinarySearch<T>(T[] array, T value) {
- if (array==null)
+ public static int BinarySearch<T>(T[] array, T value)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Contract.EndContractBlock();
return BinarySearch<T>(array, 0, array.Length, value, null);
}
[Pure]
- public static int BinarySearch<T>(T[] array, T value, System.Collections.Generic.IComparer<T> comparer) {
- if (array==null)
+ public static int BinarySearch<T>(T[] array, T value, System.Collections.Generic.IComparer<T> comparer)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Contract.EndContractBlock();
return BinarySearch<T>(array, 0, array.Length, value, comparer);
}
[Pure]
- public static int BinarySearch<T>(T[] array, int index, int length, T value) {
+ public static int BinarySearch<T>(T[] array, int index, int length, T value)
+ {
return BinarySearch<T>(array, index, length, value, null);
}
[Pure]
- public static int BinarySearch<T>(T[] array, int index, int length, T value, System.Collections.Generic.IComparer<T> comparer) {
- if (array==null)
+ public static int BinarySearch<T>(T[] array, int index, int length, T value, System.Collections.Generic.IComparer<T> comparer)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
if (index < 0)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
@@ -916,12 +962,15 @@ namespace System {
return ArraySortHelper<T>.Default.BinarySearch(array, index, length, value, comparer);
}
- public static TOutput[] ConvertAll<TInput, TOutput>(TInput[] array, Converter<TInput,TOutput> converter) {
- if( array == null) {
+ public static TOutput[] ConvertAll<TInput, TOutput>(TInput[] array, Converter<TInput, TOutput> converter)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if( converter == null) {
+ if (converter == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.converter);
}
Contract.Ensures(Contract.Result<TOutput[]>() != null);
@@ -929,7 +978,8 @@ namespace System {
Contract.EndContractBlock();
TOutput[] newArray = new TOutput[array.Length];
- for( int i = 0; i< array.Length; i++) {
+ for (int i = 0; i < array.Length; i++)
+ {
newArray[i] = converter(array[i]);
}
return newArray;
@@ -959,7 +1009,12 @@ namespace System {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_HugeArrayNotSupported);
Contract.EndContractBlock();
- this.CopyTo(array, (int) index);
+ this.CopyTo(array, (int)index);
+ }
+
+ private static class EmptyArray<T>
+ {
+ internal static readonly T[] Value = new T[0];
}
[Pure]
@@ -972,7 +1027,8 @@ namespace System {
return EmptyArray<T>.Value;
}
- public static bool Exists<T>(T[] array, Predicate<T> match) {
+ public static bool Exists<T>(T[] array, Predicate<T> match)
+ {
return Array.FindIndex(array, match) != -1;
}
@@ -1012,45 +1068,57 @@ namespace System {
}
}
- public static T Find<T>(T[] array, Predicate<T> match) {
- if( array == null) {
+ public static T Find<T>(T[] array, Predicate<T> match)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if( match == null) {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.EndContractBlock();
- for(int i = 0 ; i < array.Length; i++) {
- if(match(array[i])) {
+ for (int i = 0; i < array.Length; i++)
+ {
+ if (match(array[i]))
+ {
return array[i];
}
}
return default(T);
}
- public static T[] FindAll<T>(T[] array, Predicate<T> match) {
- if( array == null) {
+ public static T[] FindAll<T>(T[] array, Predicate<T> match)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if( match == null) {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.EndContractBlock();
- List<T> list = new List<T>();
- for(int i = 0 ; i < array.Length; i++) {
- if(match(array[i])) {
+ List<T> list = new List<T>();
+ for (int i = 0; i < array.Length; i++)
+ {
+ if (match(array[i]))
+ {
list.Add(array[i]);
}
}
return list.ToArray();
}
- public static int FindIndex<T>(T[] array, Predicate<T> match) {
- if (array==null) {
+ public static int FindIndex<T>(T[] array, Predicate<T> match)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
Contract.Ensures(Contract.Result<int>() < array.Length);
@@ -1059,62 +1127,77 @@ namespace System {
return FindIndex(array, 0, array.Length, match);
}
- public static int FindIndex<T>(T[] array, int startIndex, Predicate<T> match) {
- if (array==null) {
+ public static int FindIndex<T>(T[] array, int startIndex, Predicate<T> match)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
Contract.Ensures(Contract.Result<int>() < array.Length);
Contract.EndContractBlock();
-
+
return FindIndex(array, startIndex, array.Length - startIndex, match);
}
- public static int FindIndex<T>(T[] array, int startIndex, int count, Predicate<T> match) {
- if (array==null) {
+ public static int FindIndex<T>(T[] array, int startIndex, int count, Predicate<T> match)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if( startIndex < 0 || startIndex > array.Length ) {
+ if (startIndex < 0 || startIndex > array.Length)
+ {
ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
- if (count < 0 || startIndex > array.Length - count) {
+ if (count < 0 || startIndex > array.Length - count)
+ {
ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
- if( match == null) {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.Ensures(Contract.Result<int>() < array.Length);
Contract.EndContractBlock();
int endIndex = startIndex + count;
- for( int i = startIndex; i < endIndex; i++) {
- if( match(array[i])) return i;
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ if (match(array[i])) return i;
}
return -1;
}
- public static T FindLast<T>(T[] array, Predicate<T> match) {
- if( array == null) {
+ public static T FindLast<T>(T[] array, Predicate<T> match)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if( match == null) {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.EndContractBlock();
-
- for(int i = array.Length - 1 ; i >= 0; i--) {
- if(match(array[i])) {
+
+ for (int i = array.Length - 1; i >= 0; i--)
+ {
+ if (match(array[i]))
+ {
return array[i];
}
}
return default(T);
}
- public static int FindLastIndex<T>(T[] array, Predicate<T> match) {
- if( array == null) {
+ public static int FindLastIndex<T>(T[] array, Predicate<T> match)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
Contract.EndContractBlock();
@@ -1122,63 +1205,79 @@ namespace System {
return FindLastIndex(array, array.Length - 1, array.Length, match);
}
- public static int FindLastIndex<T>(T[] array, int startIndex, Predicate<T> match) {
- if( array == null) {
+ public static int FindLastIndex<T>(T[] array, int startIndex, Predicate<T> match)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
Contract.EndContractBlock();
-
+
return FindLastIndex(array, startIndex, startIndex + 1, match);
}
- public static int FindLastIndex<T>(T[] array, int startIndex, int count, Predicate<T> match) {
- if( array == null) {
+ public static int FindLastIndex<T>(T[] array, int startIndex, int count, Predicate<T> match)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if( match == null) {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.EndContractBlock();
- if(array.Length == 0) {
+ if (array.Length == 0)
+ {
// Special case for 0 length List
- if( startIndex != -1) {
+ if (startIndex != -1)
+ {
ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
}
- else {
+ else
+ {
// Make sure we're not out of range
- if ( startIndex < 0 || startIndex >= array.Length) {
+ if (startIndex < 0 || startIndex >= array.Length)
+ {
ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
}
-
+
// 2nd have of this also catches when startIndex == MAXINT, so MAXINT - 0 + 1 == -1, which is < 0.
- if (count < 0 || startIndex - count + 1 < 0) {
+ if (count < 0 || startIndex - count + 1 < 0)
+ {
ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
int endIndex = startIndex - count;
- for( int i = startIndex; i > endIndex; i--) {
- if( match(array[i])) {
+ for (int i = startIndex; i > endIndex; i--)
+ {
+ if (match(array[i]))
+ {
return i;
}
}
return -1;
}
- public static void ForEach<T>(T[] array, Action<T> action) {
- if( array == null) {
+ public static void ForEach<T>(T[] array, Action<T> action)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if( action == null) {
+ if (action == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.action);
}
Contract.EndContractBlock();
- for(int i = 0 ; i < array.Length; i++) {
+ for (int i = 0; i < array.Length; i++)
+ {
action(array[i]);
}
}
@@ -1195,43 +1294,46 @@ namespace System {
else
return new ArrayEnumerator(this, lowerBound, Length);
}
-
+
// Returns the index of the first occurrence of a given value in an array.
// The array is searched forwards, and the elements of the array are
// compared to the given value using the Object.Equals method.
//
- public static int IndexOf(Array array, Object value) {
- if (array==null)
+ public static int IndexOf(Array array, Object value)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Contract.Ensures(Contract.Result<int>() < array.GetLowerBound(0) + array.Length);
Contract.EndContractBlock();
int lb = array.GetLowerBound(0);
return IndexOf(array, value, lb, array.Length);
}
-
+
// Returns the index of the first occurrence of a given value in a range of
// an array. The array is searched forwards, starting at index
// startIndex and ending at the last element of the array. The
// elements of the array are compared to the given value using the
// Object.Equals method.
//
- public static int IndexOf(Array array, Object value, int startIndex) {
- if (array==null)
+ public static int IndexOf(Array array, Object value, int startIndex)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Contract.Ensures(Contract.Result<int>() < array.GetLowerBound(0) + array.Length);
Contract.EndContractBlock();
int lb = array.GetLowerBound(0);
return IndexOf(array, value, startIndex, array.Length - startIndex + lb);
}
-
+
// Returns the index of the first occurrence of a given value in a range of
// an array. The array is searched forwards, starting at index
// startIndex and upto count elements. The
// elements of the array are compared to the given value using the
// Object.Equals method.
//
- public static int IndexOf(Array array, Object value, int startIndex, int count) {
- if (array==null)
+ public static int IndexOf(Array array, Object value, int startIndex, int count)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
if (array.Rank != 1)
ThrowHelper.ThrowRankException(ExceptionResource.Rank_MultiDimNotSupported);
@@ -1252,27 +1354,36 @@ namespace System {
Object[] objArray = array as Object[];
int endIndex = startIndex + count;
- if (objArray != null) {
- if (value == null) {
- for (int i = startIndex; i < endIndex; i++) {
+ if (objArray != null)
+ {
+ if (value == null)
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
if (objArray[i] == null) return i;
}
}
- else {
- for (int i = startIndex; i < endIndex; i++) {
+ else
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
Object obj = objArray[i];
if (obj != null && obj.Equals(value)) return i;
}
}
}
- else {
- for (int i = startIndex; i < endIndex; i++) {
+ else
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
Object obj = array.GetValue(i);
- if( obj == null) {
- if(value == null) return i;
+ if (obj == null)
+ {
+ if (value == null) return i;
}
- else {
- if( obj.Equals(value)) return i;
+ else
+ {
+ if (obj.Equals(value)) return i;
}
}
}
@@ -1280,12 +1391,14 @@ namespace System {
// for arrays with a lower bound of -1 we will not return -1 when the
// item was not found. And for SZArrays (the vast majority), -1 still
// works for them.
- return lb-1;
+ return lb - 1;
}
[Pure]
- public static int IndexOf<T>(T[] array, T value) {
- if (array==null) {
+ public static int IndexOf<T>(T[] array, T value)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
Contract.Ensures((Contract.Result<int>() < 0) ||
@@ -1295,8 +1408,10 @@ namespace System {
return IndexOf(array, value, 0, array.Length);
}
- public static int IndexOf<T>(T[] array, T value, int startIndex) {
- if (array==null) {
+ public static int IndexOf<T>(T[] array, T value, int startIndex)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
Contract.Ensures(Contract.Result<int>() < array.Length);
@@ -1305,16 +1420,20 @@ namespace System {
return IndexOf(array, value, startIndex, array.Length - startIndex);
}
- public static int IndexOf<T>(T[] array, T value, int startIndex, int count) {
- if (array==null) {
+ public static int IndexOf<T>(T[] array, T value, int startIndex, int count)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if (startIndex < 0 || startIndex > array.Length ) {
+ if (startIndex < 0 || startIndex > array.Length)
+ {
ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
- if (count < 0 || count > array.Length - startIndex) {
+ if (count < 0 || count > array.Length - startIndex)
+ {
ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
Contract.Ensures(Contract.Result<int>() < array.Length);
@@ -1325,27 +1444,29 @@ namespace System {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool TrySZIndexOf(Array sourceArray, int sourceIndex, int count, Object value, out int retVal);
-
+
// Returns the index of the last occurrence of a given value in an array.
// The array is searched backwards, and the elements of the array are
// compared to the given value using the Object.Equals method.
//
- public static int LastIndexOf(Array array, Object value) {
- if (array==null)
+ public static int LastIndexOf(Array array, Object value)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Contract.Ensures(Contract.Result<int>() < array.GetLowerBound(0) + array.Length);
Contract.EndContractBlock();
int lb = array.GetLowerBound(0);
return LastIndexOf(array, value, array.Length - 1 + lb, array.Length);
}
-
+
// Returns the index of the last occurrence of a given value in a range of
// an array. The array is searched backwards, starting at index
// startIndex and ending at index 0. The elements of the array are
// compared to the given value using the Object.Equals method.
//
- public static int LastIndexOf(Array array, Object value, int startIndex) {
+ public static int LastIndexOf(Array array, Object value, int startIndex)
+ {
if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Contract.Ensures(Contract.Result<int>() < array.GetLowerBound(0) + array.Length);
@@ -1353,21 +1474,23 @@ namespace System {
int lb = array.GetLowerBound(0);
return LastIndexOf(array, value, startIndex, startIndex + 1 - lb);
}
-
+
// Returns the index of the last occurrence of a given value in a range of
// an array. The array is searched backwards, starting at index
// startIndex and counting uptocount elements. The elements of
// the array are compared to the given value using the Object.Equals
// method.
//
- public static int LastIndexOf(Array array, Object value, int startIndex, int count) {
- if (array==null)
+ public static int LastIndexOf(Array array, Object value, int startIndex, int count)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Contract.Ensures(Contract.Result<int>() < array.GetLowerBound(0) + array.Length);
Contract.EndContractBlock();
int lb = array.GetLowerBound(0);
- if (array.Length == 0) {
- return lb-1;
+ if (array.Length == 0)
+ {
+ return lb - 1;
}
if (startIndex < lb || startIndex >= array.Length + lb)
@@ -1387,35 +1510,46 @@ namespace System {
Object[] objArray = array as Object[];
int endIndex = startIndex - count + 1;
- if (objArray!=null) {
- if (value == null) {
- for (int i = startIndex; i >= endIndex; i--) {
+ if (objArray != null)
+ {
+ if (value == null)
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (objArray[i] == null) return i;
}
}
- else {
- for (int i = startIndex; i >= endIndex; i--) {
+ else
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
Object obj = objArray[i];
if (obj != null && obj.Equals(value)) return i;
}
}
}
- else {
- for (int i = startIndex; i >= endIndex; i--) {
+ else
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
Object obj = array.GetValue(i);
- if( obj == null) {
- if(value == null) return i;
+ if (obj == null)
+ {
+ if (value == null) return i;
}
- else {
- if( obj.Equals(value)) return i;
+ else
+ {
+ if (obj.Equals(value)) return i;
}
}
}
- return lb-1; // Return lb-1 for arrays with negative lower bounds.
+ return lb - 1; // Return lb-1 for arrays with negative lower bounds.
}
-
- public static int LastIndexOf<T>(T[] array, T value) {
- if (array==null) {
+
+ public static int LastIndexOf<T>(T[] array, T value)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
Contract.Ensures(Contract.Result<int>() < array.Length);
@@ -1424,50 +1558,59 @@ namespace System {
return LastIndexOf(array, value, array.Length - 1, array.Length);
}
- public static int LastIndexOf<T>(T[] array, T value, int startIndex) {
- if (array==null) {
+ public static int LastIndexOf<T>(T[] array, T value, int startIndex)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
Contract.Ensures(Contract.Result<int>() < array.Length);
Contract.EndContractBlock();
// if array is empty and startIndex is 0, we need to pass 0 as count
- return LastIndexOf(array, value, startIndex, (array.Length == 0)? 0 : (startIndex + 1));
+ return LastIndexOf(array, value, startIndex, (array.Length == 0) ? 0 : (startIndex + 1));
}
- public static int LastIndexOf<T>(T[] array, T value, int startIndex, int count) {
- if (array==null) {
+ public static int LastIndexOf<T>(T[] array, T value, int startIndex, int count)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
Contract.Ensures(Contract.Result<int>() < array.Length);
Contract.EndContractBlock();
-
- if(array.Length == 0) {
+
+ if (array.Length == 0)
+ {
//
// Special case for 0 length List
// accept -1 and 0 as valid startIndex for compablility reason.
//
- if( startIndex != -1 && startIndex != 0) {
+ if (startIndex != -1 && startIndex != 0)
+ {
ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
// only 0 is a valid value for count if array is empty
- if( count != 0) {
+ if (count != 0)
+ {
ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
return -1;
}
// Make sure we're not out of range
- if ( startIndex < 0 || startIndex >= array.Length) {
+ if (startIndex < 0 || startIndex >= array.Length)
+ {
ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
-
+
// 2nd have of this also catches when startIndex == MAXINT, so MAXINT - 0 + 1 == -1, which is < 0.
- if (count < 0 || startIndex - count + 1 < 0) {
+ if (count < 0 || startIndex - count + 1 < 0)
+ {
ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
- return EqualityComparer<T>.Default.LastIndexOf(array, value, startIndex, count);
+ return EqualityComparer<T>.Default.LastIndexOf(array, value, startIndex, count);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -1479,21 +1622,23 @@ namespace System {
// located at index length - i - 1, where length is the
// length of the array.
//
- public static void Reverse(Array array) {
- if (array==null)
+ public static void Reverse(Array array)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Contract.EndContractBlock();
Reverse(array, array.GetLowerBound(0), array.Length);
}
-
+
// Reverses the elements in a range of an array. Following a call to this
// method, an element in the range given by index and count
// which was previously located at index i will now be located at
// index index + (index + count - i - 1).
// Reliability note: This may fail because it may have to box objects.
//
- public static void Reverse(Array array, int index, int length) {
- if (array==null)
+ public static void Reverse(Array array, int index, int length)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
int lowerBound = array.GetLowerBound(0);
if (index < lowerBound)
@@ -1514,8 +1659,10 @@ namespace System {
int i = index;
int j = index + length - 1;
Object[] objArray = array as Object[];
- if (objArray!=null) {
- while (i < j) {
+ if (objArray != null)
+ {
+ while (i < j)
+ {
Object temp = objArray[i];
objArray[i] = objArray[j];
objArray[j] = temp;
@@ -1523,8 +1670,10 @@ namespace System {
j--;
}
}
- else {
- while (i < j) {
+ else
+ {
+ while (i < j)
+ {
Object temp = array.GetValue(i);
array.SetValue(array.GetValue(j), i);
array.SetValue(temp, j);
@@ -1573,57 +1722,62 @@ namespace System {
// other using the IComparable interface, which must be implemented
// by all elements of the array.
//
- public static void Sort(Array array) {
- if (array==null)
+ public static void Sort(Array array)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Contract.EndContractBlock();
Sort(array, null, array.GetLowerBound(0), array.Length, null);
}
-
+
// Sorts the elements of two arrays based on the keys in the first array.
// Elements in the keys array specify the sort keys for
// corresponding elements in the items array. The sort compares the
// keys to each other using the IComparable interface, which must be
// implemented by all elements of the keys array.
//
- public static void Sort(Array keys, Array items) {
- if (keys==null)
+ public static void Sort(Array keys, Array items)
+ {
+ if (keys == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.keys);
Contract.EndContractBlock();
Sort(keys, items, keys.GetLowerBound(0), keys.Length, null);
}
-
+
// Sorts the elements in a section of an array. The sort compares the
// elements to each other using the IComparable interface, which
// must be implemented by all elements in the given section of the array.
//
- public static void Sort(Array array, int index, int length) {
+ public static void Sort(Array array, int index, int length)
+ {
Sort(array, null, index, length, null);
}
-
+
// Sorts the elements in a section of two arrays based on the keys in the
// first array. Elements in the keys array specify the sort keys for
// corresponding elements in the items array. The sort compares the
// keys to each other using the IComparable interface, which must be
// implemented by all elements of the keys array.
//
- public static void Sort(Array keys, Array items, int index, int length) {
+ public static void Sort(Array keys, Array items, int index, int length)
+ {
Sort(keys, items, index, length, null);
}
-
+
// Sorts the elements of an array. The sort compares the elements to each
// other using the given IComparer interface. If comparer is
// null, the elements are compared to each other using the
// IComparable interface, which in that case must be implemented by
// all elements of the array.
//
- public static void Sort(Array array, IComparer comparer) {
- if (array==null)
+ public static void Sort(Array array, IComparer comparer)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Contract.EndContractBlock();
Sort(array, null, array.GetLowerBound(0), array.Length, comparer);
}
-
+
// Sorts the elements of two arrays based on the keys in the first array.
// Elements in the keys array specify the sort keys for
// corresponding elements in the items array. The sort compares the
@@ -1632,23 +1786,25 @@ namespace System {
// the IComparable interface, which in that case must be implemented
// by all elements of the keys array.
//
- public static void Sort(Array keys, Array items, IComparer comparer) {
- if (keys==null)
+ public static void Sort(Array keys, Array items, IComparer comparer)
+ {
+ if (keys == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.keys);
Contract.EndContractBlock();
Sort(keys, items, keys.GetLowerBound(0), keys.Length, comparer);
}
-
+
// Sorts the elements in a section of an array. The sort compares the
// elements to each other using the given IComparer interface. If
// comparer is null, the elements are compared to each other using
// the IComparable interface, which in that case must be implemented
// by all elements in the given section of the array.
//
- public static void Sort(Array array, int index, int length, IComparer comparer) {
+ public static void Sort(Array array, int index, int length, IComparer comparer)
+ {
Sort(array, null, index, length, comparer);
}
-
+
// Sorts the elements in a section of two arrays based on the keys in the
// first array. Elements in the keys array specify the sort keys for
// corresponding elements in the items array. The sort compares the
@@ -1657,8 +1813,9 @@ namespace System {
// the IComparable interface, which in that case must be implemented
// by all elements of the given section of the keys array.
//
- public static void Sort(Array keys, Array items, int index, int length, IComparer comparer) {
- if (keys==null)
+ public static void Sort(Array keys, Array items, int index, int length, IComparer comparer)
+ {
+ if (keys == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.keys);
if (keys.Rank != 1 || (items != null && items.Rank != 1))
ThrowHelper.ThrowRankException(ExceptionResource.Rank_MultiDimNotSupported);
@@ -1674,9 +1831,11 @@ namespace System {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
Contract.EndContractBlock();
-
- if (length > 1) {
- if (comparer == Comparer.Default || comparer == null) {
+
+ if (length > 1)
+ {
+ if (comparer == Comparer.Default || comparer == null)
+ {
bool r = TrySZSort(keys, items, index, index + length - 1);
if (r)
return;
@@ -1686,58 +1845,67 @@ namespace System {
Object[] objItems = null;
if (objKeys != null)
objItems = items as Object[];
- if (objKeys != null && (items==null || objItems != null)) {
+ if (objKeys != null && (items == null || objItems != null))
+ {
SorterObjectArray sorter = new SorterObjectArray(objKeys, objItems, comparer);
sorter.Sort(index, length);
}
- else {
+ else
+ {
SorterGenericArray sorter = new SorterGenericArray(keys, items, comparer);
sorter.Sort(index, length);
}
}
}
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool TrySZSort(Array keys, Array items, int left, int right);
- public static void Sort<T>(T[] array) {
- if (array==null)
+ public static void Sort<T>(T[] array)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Contract.EndContractBlock();
Sort<T>(array, 0, array.Length, null);
}
- public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items) {
- if (keys==null)
+ public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items)
+ {
+ if (keys == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.keys);
Contract.EndContractBlock();
Sort<TKey, TValue>(keys, items, 0, keys.Length, null);
}
- public static void Sort<T>(T[] array, int index, int length) {
+ public static void Sort<T>(T[] array, int index, int length)
+ {
Sort<T>(array, index, length, null);
}
- public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items, int index, int length) {
+ public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items, int index, int length)
+ {
Sort<TKey, TValue>(keys, items, index, length, null);
}
- public static void Sort<T>(T[] array, System.Collections.Generic.IComparer<T> comparer) {
+ public static void Sort<T>(T[] array, System.Collections.Generic.IComparer<T> comparer)
+ {
if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
Contract.EndContractBlock();
Sort<T>(array, 0, array.Length, comparer);
}
- public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items, System.Collections.Generic.IComparer<TKey> comparer) {
- if (keys==null)
+ public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items, System.Collections.Generic.IComparer<TKey> comparer)
+ {
+ if (keys == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.keys);
Contract.EndContractBlock();
Sort<TKey, TValue>(keys, items, 0, keys.Length, comparer);
}
- public static void Sort<T>(T[] array, int index, int length, System.Collections.Generic.IComparer<T> comparer) {
- if (array==null)
+ public static void Sort<T>(T[] array, int index, int length, System.Collections.Generic.IComparer<T> comparer)
+ {
+ if (array == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
if (index < 0)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
@@ -1747,19 +1915,23 @@ namespace System {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
Contract.EndContractBlock();
- if (length > 1) {
- if ( comparer == null || comparer == Comparer<T>.Default ) {
- if(TrySZSort(array, null, index, index + length - 1)) {
+ if (length > 1)
+ {
+ if (comparer == null || comparer == Comparer<T>.Default)
+ {
+ if (TrySZSort(array, null, index, index + length - 1))
+ {
return;
}
}
- ArraySortHelper<T>.Default.Sort(array, index, length, comparer);
+ ArraySortHelper<T>.Default.Sort(array, index, length, comparer);
}
}
- public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items, int index, int length, System.Collections.Generic.IComparer<TKey> comparer) {
- if (keys==null)
+ public static void Sort<TKey, TValue>(TKey[] keys, TValue[] items, int index, int length, System.Collections.Generic.IComparer<TKey> comparer)
+ {
+ if (keys == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.keys);
if (index < 0)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
@@ -1769,13 +1941,16 @@ namespace System {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
Contract.EndContractBlock();
- if (length > 1) {
- if ( comparer == null || comparer == Comparer<TKey>.Default ) {
- if(TrySZSort(keys, items, index, index + length - 1)) {
+ if (length > 1)
+ {
+ if (comparer == null || comparer == Comparer<TKey>.Default)
+ {
+ if (TrySZSort(keys, items, index, index + length - 1))
+ {
return;
}
}
-
+
if (items == null)
{
Sort<TKey>(keys, index, length, comparer);
@@ -1786,12 +1961,15 @@ namespace System {
}
}
- public static void Sort<T>(T[] array, Comparison<T> comparison) {
- if( array == null) {
+ public static void Sort<T>(T[] array, Comparison<T> comparison)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if( comparison == null) {
+ if (comparison == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.comparison);
}
Contract.EndContractBlock();
@@ -1799,18 +1977,23 @@ namespace System {
ArraySortHelper<T>.Sort(array, 0, array.Length, comparison);
}
- public static bool TrueForAll<T>(T[] array, Predicate<T> match) {
- if( array == null) {
+ public static bool TrueForAll<T>(T[] array, Predicate<T> match)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if( match == null) {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.EndContractBlock();
- for(int i = 0 ; i < array.Length; i++) {
- if( !match(array[i])) {
+ for (int i = 0; i < array.Length; i++)
+ {
+ if (!match(array[i]))
+ {
return false;
}
}
@@ -1823,15 +2006,16 @@ namespace System {
{
private Object[] keys;
private Object[] items;
- private IComparer comparer;
-
- internal SorterObjectArray(Object[] keys, Object[] items, IComparer comparer) {
+ private IComparer comparer;
+
+ internal SorterObjectArray(Object[] keys, Object[] items, IComparer comparer)
+ {
if (comparer == null) comparer = Comparer.Default;
this.keys = keys;
this.items = items;
this.comparer = comparer;
}
-
+
internal void SwapIfGreaterWithItems(int a, int b)
{
if (a != b)
@@ -1907,9 +2091,9 @@ namespace System {
}
if (partitionSize == 3)
{
- SwapIfGreaterWithItems(lo, hi-1);
+ SwapIfGreaterWithItems(lo, hi - 1);
SwapIfGreaterWithItems(lo, hi);
- SwapIfGreaterWithItems(hi-1, hi);
+ SwapIfGreaterWithItems(hi - 1, hi);
return;
}
@@ -1948,7 +2132,7 @@ namespace System {
while (comparer.Compare(keys[++left], pivot) < 0) ;
while (comparer.Compare(pivot, keys[--right]) < 0) ;
- if(left >= right)
+ if (left >= right)
break;
Swap(left, right);
@@ -1989,7 +2173,7 @@ namespace System {
if (!(comparer.Compare(d, keys[lo + child - 1]) < 0))
break;
keys[lo + i - 1] = keys[lo + child - 1];
- if(items != null)
+ if (items != null)
items[lo + i - 1] = items[lo + child - 1];
i = child;
}
@@ -2010,17 +2194,17 @@ namespace System {
while (j >= lo && comparer.Compare(t, keys[j]) < 0)
{
keys[j + 1] = keys[j];
- if(items != null)
+ if (items != null)
items[j + 1] = items[j];
j--;
}
keys[j + 1] = t;
- if(items != null)
+ if (items != null)
items[j + 1] = ti;
}
}
}
-
+
// Private value used by the Sort methods for instances of Array.
// This is slower than the one for Object[], since we can't use the JIT helpers
// to access the elements. We must use GetValue & SetValue.
@@ -2062,8 +2246,8 @@ namespace System {
Object t1 = keys.GetValue(i);
keys.SetValue(keys.GetValue(j), i);
keys.SetValue(t1, j);
-
- if(items != null)
+
+ if (items != null)
{
Object t2 = items.GetValue(i);
items.SetValue(items.GetValue(j), i);
@@ -2113,9 +2297,9 @@ namespace System {
}
if (partitionSize == 3)
{
- SwapIfGreaterWithItems(lo, hi-1);
+ SwapIfGreaterWithItems(lo, hi - 1);
SwapIfGreaterWithItems(lo, hi);
- SwapIfGreaterWithItems(hi-1, hi);
+ SwapIfGreaterWithItems(hi - 1, hi);
return;
}
@@ -2148,7 +2332,7 @@ namespace System {
Object pivot = keys.GetValue(mid);
Swap(mid, hi - 1);
int left = lo, right = hi - 1; // We already partitioned lo and hi and put the pivot in hi - 1. And we pre-increment & decrement below.
-
+
while (left < right)
{
while (comparer.Compare(keys.GetValue(++left), pivot) < 0) ;
@@ -2183,7 +2367,7 @@ namespace System {
private void DownHeap(int i, int n, int lo)
{
Object d = keys.GetValue(lo + i - 1);
- Object dt = (items != null)? items.GetValue(lo + i - 1) : null;
+ Object dt = (items != null) ? items.GetValue(lo + i - 1) : null;
int child;
while (i <= n / 2)
{
@@ -2197,12 +2381,12 @@ namespace System {
break;
keys.SetValue(keys.GetValue(lo + child - 1), lo + i - 1);
- if(items != null)
+ if (items != null)
items.SetValue(items.GetValue(lo + child - 1), lo + i - 1);
i = child;
}
keys.SetValue(d, lo + i - 1);
- if(items != null)
+ if (items != null)
items.SetValue(dt, lo + i - 1);
}
@@ -2214,30 +2398,32 @@ namespace System {
{
j = i;
t = keys.GetValue(i + 1);
- dt = (items != null)? items.GetValue(i + 1) : null;
+ dt = (items != null) ? items.GetValue(i + 1) : null;
while (j >= lo && comparer.Compare(t, keys.GetValue(j)) < 0)
{
keys.SetValue(keys.GetValue(j), j + 1);
- if(items != null)
+ if (items != null)
items.SetValue(items.GetValue(j), j + 1);
j--;
}
keys.SetValue(t, j + 1);
- if(items != null)
+ if (items != null)
items.SetValue(dt, j + 1);
}
}
}
- [Serializable] private sealed class SZArrayEnumerator : IEnumerator, ICloneable
+ [Serializable]
+ private sealed class SZArrayEnumerator : IEnumerator, ICloneable
{
private Array _array;
private int _index;
private int _endIndex; // cache array length, since it's a little slow.
- internal SZArrayEnumerator(Array array) {
+ internal SZArrayEnumerator(Array array)
+ {
Debug.Assert(array.Rank == 1 && array.GetLowerBound(0) == 0, "SZArrayEnumerator only works on single dimension arrays w/ a lower bound of zero.");
_array = array;
_index = -1;
@@ -2249,28 +2435,34 @@ namespace System {
return MemberwiseClone();
}
- public bool MoveNext() {
- if (_index < _endIndex) {
+ public bool MoveNext()
+ {
+ if (_index < _endIndex)
+ {
_index++;
return (_index < _endIndex);
}
return false;
}
-
- public Object Current {
- get {
+
+ public Object Current
+ {
+ get
+ {
if (_index < 0) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted();
if (_index >= _endIndex) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded();
return _array.GetValue(_index);
}
}
-
- public void Reset() {
+
+ public void Reset()
+ {
_index = -1;
}
}
-
- [Serializable] private sealed class ArrayEnumerator : IEnumerator, ICloneable
+
+ [Serializable]
+ private sealed class ArrayEnumerator : IEnumerator, ICloneable
{
private Array array;
private int index;
@@ -2279,23 +2471,26 @@ namespace System {
private int[] _indices; // The current position in a multidim array
private bool _complete;
- internal ArrayEnumerator(Array array, int index, int count) {
+ internal ArrayEnumerator(Array array, int index, int count)
+ {
this.array = array;
this.index = index - 1;
startIndex = index;
endIndex = index + count;
_indices = new int[array.Rank];
int checkForZero = 1; // Check for dimensions of size 0.
- for(int i=0; i<array.Rank; i++) {
+ for (int i = 0; i < array.Rank; i++)
+ {
_indices[i] = array.GetLowerBound(i);
checkForZero *= array.GetLength(i);
}
// To make MoveNext simpler, decrement least significant index.
- _indices[_indices.Length-1]--;
+ _indices[_indices.Length - 1]--;
_complete = (checkForZero == 0);
}
- private void IncArray() {
+ private void IncArray()
+ {
// This method advances us to the next valid array index,
// handling all the multiple dimension & bounds correctly.
// Think of it like an odometer in your car - we start with
@@ -2306,16 +2501,19 @@ namespace System {
// has rolled over it's upper bound, we're done.
//
int rank = array.Rank;
- _indices[rank-1]++;
- for(int dim=rank-1; dim>=0; dim--) {
- if (_indices[dim] > array.GetUpperBound(dim)) {
- if (dim==0) {
+ _indices[rank - 1]++;
+ for (int dim = rank - 1; dim >= 0; dim--)
+ {
+ if (_indices[dim] > array.GetUpperBound(dim))
+ {
+ if (dim == 0)
+ {
_complete = true;
break;
}
- for(int j=dim; j<rank; j++)
+ for (int j = dim; j < rank; j++)
_indices[j] = array.GetLowerBound(j);
- _indices[dim-1]++;
+ _indices[dim - 1]++;
}
}
}
@@ -2325,8 +2523,10 @@ namespace System {
return MemberwiseClone();
}
- public bool MoveNext() {
- if (_complete) {
+ public bool MoveNext()
+ {
+ if (_complete)
+ {
index = endIndex;
return false;
}
@@ -2334,25 +2534,29 @@ namespace System {
IncArray();
return !_complete;
}
-
- public Object Current {
- get {
+
+ public Object Current
+ {
+ get
+ {
if (index < startIndex) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted();
if (_complete) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded();
return array.GetValue(_indices);
}
}
-
- public void Reset() {
+
+ public void Reset()
+ {
index = startIndex - 1;
int checkForZero = 1;
- for(int i=0; i<array.Rank; i++) {
+ for (int i = 0; i < array.Rank; i++)
+ {
_indices[i] = array.GetLowerBound(i);
checkForZero *= array.GetLength(i);
}
_complete = (checkForZero == 0);
// To make MoveNext simpler, decrement least significant index.
- _indices[_indices.Length-1]--;
+ _indices[_indices.Length - 1]--;
}
}
@@ -2393,16 +2597,19 @@ namespace System {
// array that is castable to "T[]" (i.e. for primitivs and valuetypes, it will be exactly
// "T[]" - for orefs, it may be a "U[]" where U derives from T.)
//----------------------------------------------------------------------------------------
- sealed class SZArrayHelper {
+ internal sealed class SZArrayHelper
+ {
// It is never legal to instantiate this class.
- private SZArrayHelper() {
+ private SZArrayHelper()
+ {
Debug.Assert(false, "Hey! How'd I get here?");
}
// -----------------------------------------------------------
// ------- Implement IEnumerable<T> interface methods --------
// -----------------------------------------------------------
- internal IEnumerator<T> GetEnumerator<T>() {
+ internal IEnumerator<T> GetEnumerator<T>()
+ {
//! Warning: "this" is an array, not an SZArrayHelper. See comments above
//! or you may introduce a security hole!
T[] _this = JitHelpers.UnsafeCast<T[]>(this);
@@ -2413,7 +2620,8 @@ namespace System {
// -----------------------------------------------------------
// ------- Implement ICollection<T> interface methods --------
// -----------------------------------------------------------
- void CopyTo<T>(T[] array, int index) {
+ private void CopyTo<T>(T[] array, int index)
+ {
//! Warning: "this" is an array, not an SZArrayHelper. See comments above
//! or you may introduce a security hole!
@@ -2421,7 +2629,8 @@ namespace System {
Array.Copy(_this, 0, array, index, _this.Length);
}
- internal int get_Count<T>() {
+ internal int get_Count<T>()
+ {
//! Warning: "this" is an array, not an SZArrayHelper. See comments above
//! or you may introduce a security hole!
T[] _this = JitHelpers.UnsafeCast<T[]>(this);
@@ -2431,70 +2640,82 @@ namespace System {
// -----------------------------------------------------------
// ---------- Implement IList<T> interface methods -----------
// -----------------------------------------------------------
- internal T get_Item<T>(int index) {
+ internal T get_Item<T>(int index)
+ {
//! Warning: "this" is an array, not an SZArrayHelper. See comments above
//! or you may introduce a security hole!
T[] _this = JitHelpers.UnsafeCast<T[]>(this);
- if ((uint)index >= (uint)_this.Length) {
+ if ((uint)index >= (uint)_this.Length)
+ {
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
}
return _this[index];
}
- internal void set_Item<T>(int index, T value) {
+ internal void set_Item<T>(int index, T value)
+ {
//! Warning: "this" is an array, not an SZArrayHelper. See comments above
//! or you may introduce a security hole!
T[] _this = JitHelpers.UnsafeCast<T[]>(this);
- if ((uint)index >= (uint)_this.Length) {
+ if ((uint)index >= (uint)_this.Length)
+ {
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
}
_this[index] = value;
}
- void Add<T>(T value) {
+ private void Add<T>(T value)
+ {
// Not meaningful for arrays.
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_FixedSizeCollection);
}
- bool Contains<T>(T value) {
+ private bool Contains<T>(T value)
+ {
//! Warning: "this" is an array, not an SZArrayHelper. See comments above
//! or you may introduce a security hole!
T[] _this = JitHelpers.UnsafeCast<T[]>(this);
return Array.IndexOf(_this, value, 0, _this.Length) >= 0;
}
-
- bool get_IsReadOnly<T>() {
- return true;
+
+ private bool get_IsReadOnly<T>()
+ {
+ return true;
}
-
- void Clear<T>() {
+
+ private void Clear<T>()
+ {
//! Warning: "this" is an array, not an SZArrayHelper. See comments above
//! or you may introduce a security hole!
- ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- int IndexOf<T>(T value) {
+ private int IndexOf<T>(T value)
+ {
//! Warning: "this" is an array, not an SZArrayHelper. See comments above
//! or you may introduce a security hole!
T[] _this = JitHelpers.UnsafeCast<T[]>(this);
return Array.IndexOf(_this, value, 0, _this.Length);
}
-
- void Insert<T>(int index, T value) {
+
+ private void Insert<T>(int index, T value)
+ {
// Not meaningful for arrays
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_FixedSizeCollection);
}
- bool Remove<T>(T value) {
+ private bool Remove<T>(T value)
+ {
// Not meaningful for arrays
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_FixedSizeCollection);
return default(bool);
}
- void RemoveAt<T>(int index) {
+ private void RemoveAt<T>(int index)
+ {
// Not meaningful for arrays
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_FixedSizeCollection);
}
@@ -2502,7 +2723,9 @@ namespace System {
// This is a normal generic Enumerator for SZ arrays. It doesn't have any of the "this" stuff
// that SZArrayHelper does.
//
- [Serializable] private sealed class SZGenericArrayEnumerator<T> : IEnumerator<T> {
+ [Serializable]
+ private sealed class SZGenericArrayEnumerator<T> : IEnumerator<T>
+ {
private T[] _array;
private int _index;
private int _endIndex; // cache array length, since it's a little slow.
@@ -2510,37 +2733,45 @@ namespace System {
// Passing -1 for endIndex so that MoveNext always returns false without mutating _index
internal static readonly SZGenericArrayEnumerator<T> Empty = new SZGenericArrayEnumerator<T>(null, -1);
- internal SZGenericArrayEnumerator(T[] array, int endIndex) {
+ internal SZGenericArrayEnumerator(T[] array, int endIndex)
+ {
// We allow passing null array in case of empty enumerator.
Debug.Assert(array != null || endIndex == -1, "endIndex should be -1 in the case of a null array (for the empty enumerator).");
_array = array;
_index = -1;
_endIndex = endIndex;
}
-
- public bool MoveNext() {
- if (_index < _endIndex) {
+
+ public bool MoveNext()
+ {
+ if (_index < _endIndex)
+ {
_index++;
return (_index < _endIndex);
}
return false;
}
-
- public T Current {
- get {
+
+ public T Current
+ {
+ get
+ {
if (_index < 0) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted();
if (_index >= _endIndex) ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded();
return _array[_index];
}
}
-
- object IEnumerator.Current {
- get {
+
+ object IEnumerator.Current
+ {
+ get
+ {
return Current;
}
}
- void IEnumerator.Reset() {
+ void IEnumerator.Reset()
+ {
_index = -1;
}
@@ -2551,8 +2782,3 @@ namespace System {
}
}
-// Useful in number of places that return an empty byte array to avoid unnecessary memory allocation.
-internal static class EmptyArray<T>
-{
- public static readonly T[] Value = new T[0];
-}
diff --git a/src/mscorlib/src/System/ArraySegment.cs b/src/mscorlib/src/System/ArraySegment.cs
index 03556e492a..a18590d5d8 100644
--- a/src/mscorlib/src/System/ArraySegment.cs
+++ b/src/mscorlib/src/System/ArraySegment.cs
@@ -15,6 +15,7 @@
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System
@@ -27,6 +28,10 @@ namespace System
[Serializable]
public struct ArraySegment<T> : IList<T>, IReadOnlyList<T>
{
+ // Do not replace the array allocation with Array.Empty. We don't want to have the overhead of
+ // instantiating another generic type in addition to ArraySegment<T> for new type parameters.
+ public static ArraySegment<T> Empty { get; } = new ArraySegment<T>(new T[0]);
+
private readonly T[] _array;
private readonly int _offset;
private readonly int _count;
@@ -45,8 +50,9 @@ namespace System
public ArraySegment(T[] array, int offset, int count)
{
// Validate arguments, check is minimal instructions with reduced branching for inlinable fast-path
+ // Negative values discovered though conversion to high values when converted to unsigned
// Failure should be rare and location determination and message is delegated to failure functions
- if (array == null || (offset | count) < 0 || (array.Length - offset < count))
+ if (array == null || (uint)offset > (uint)array.Length || (uint)count > (uint)(array.Length - offset))
ThrowHelper.ThrowArraySegmentCtorValidationFailedExceptions(array, offset, count);
Contract.EndContractBlock();
@@ -55,62 +61,37 @@ namespace System
_count = count;
}
- public T[] Array
- {
- get
- {
- Debug.Assert( (null == _array && 0 == _offset && 0 == _count)
- || (null != _array && _offset >= 0 && _count >= 0 && _offset + _count <= _array.Length),
- "ArraySegment is invalid");
+ public T[] Array => _array;
- return _array;
- }
- }
+ public int Offset => _offset;
- public int Offset
+ public int Count => _count;
+
+ public T this[int index]
{
get
{
- // Since copying value types is not atomic & callers cannot atomically
- // read all three fields, we cannot guarantee that Offset is within
- // the bounds of Array. That is our intent, but let's not specify
- // it as a postcondition - force callers to re-verify this themselves
- // after reading each field out of an ArraySegment into their stack.
- Contract.Ensures(Contract.Result<int>() >= 0);
-
- Debug.Assert( (null == _array && 0 == _offset && 0 == _count)
- || (null != _array && _offset >= 0 && _count >= 0 && _offset + _count <= _array.Length),
- "ArraySegment is invalid");
-
- return _offset;
- }
- }
+ if ((uint)index >= (uint)_count)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
+ }
- public int Count
- {
- get
+ return _array[_offset + index];
+ }
+ set
{
- // Since copying value types is not atomic & callers cannot atomically
- // read all three fields, we cannot guarantee that Count is within
- // the bounds of Array. That's our intent, but let's not specify
- // it as a postcondition - force callers to re-verify this themselves
- // after reading each field out of an ArraySegment into their stack.
- Contract.Ensures(Contract.Result<int>() >= 0);
-
- Debug.Assert( (null == _array && 0 == _offset && 0 == _count)
- || (null != _array && _offset >= 0 && _count >= 0 && _offset + _count <= _array.Length),
- "ArraySegment is invalid");
-
- return _count;
+ if ((uint)index >= (uint)_count)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
+ }
+
+ _array[_offset + index] = value;
}
}
public Enumerator GetEnumerator()
{
- if (_array == null)
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray);
- Contract.EndContractBlock();
-
+ ThrowInvalidOperationIfDefault();
return new Enumerator(this);
}
@@ -120,17 +101,38 @@ namespace System
{
return 0;
}
-
+
int hash = 5381;
hash = System.Numerics.Hashing.HashHelpers.Combine(hash, _offset);
hash = System.Numerics.Hashing.HashHelpers.Combine(hash, _count);
-
+
// The array hash is expected to be an evenly-distributed mixture of bits,
// so rather than adding the cost of another rotation we just xor it.
hash ^= _array.GetHashCode();
return hash;
}
+ public void CopyTo(T[] destination) => CopyTo(destination, 0);
+
+ public void CopyTo(T[] destination, int destinationIndex)
+ {
+ ThrowInvalidOperationIfDefault();
+ System.Array.Copy(_array, _offset, destination, destinationIndex, _count);
+ }
+
+ public void CopyTo(ArraySegment<T> destination)
+ {
+ ThrowInvalidOperationIfDefault();
+ destination.ThrowInvalidOperationIfDefault();
+
+ if (_count > destination._count)
+ {
+ ThrowHelper.ThrowArgumentException_DestinationTooShort();
+ }
+
+ System.Array.Copy(_array, _offset, destination._array, destination._offset, _count);
+ }
+
public override bool Equals(Object obj)
{
if (obj is ArraySegment<T>)
@@ -138,30 +140,69 @@ namespace System
else
return false;
}
-
+
public bool Equals(ArraySegment<T> obj)
{
return obj._array == _array && obj._offset == _offset && obj._count == _count;
}
-
+
+ public ArraySegment<T> Slice(int index)
+ {
+ ThrowInvalidOperationIfDefault();
+
+ if ((uint)index > (uint)_count)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
+ }
+
+ return new ArraySegment<T>(_array, _offset + index, _count - index);
+ }
+
+ public ArraySegment<T> Slice(int index, int count)
+ {
+ ThrowInvalidOperationIfDefault();
+
+ if ((uint)index > (uint)_count || (uint)count > (uint)(_count - index))
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index);
+ }
+
+ return new ArraySegment<T>(_array, _offset + index, count);
+ }
+
+ public T[] ToArray()
+ {
+ ThrowInvalidOperationIfDefault();
+
+ if (_count == 0)
+ {
+ return Empty._array;
+ }
+
+ var array = new T[_count];
+ System.Array.Copy(_array, _offset, array, 0, _count);
+ return array;
+ }
+
public static bool operator ==(ArraySegment<T> a, ArraySegment<T> b)
{
return a.Equals(b);
}
-
+
public static bool operator !=(ArraySegment<T> a, ArraySegment<T> b)
{
return !(a == b);
}
+ public static implicit operator ArraySegment<T>(T[] array) => new ArraySegment<T>(array);
+
#region IList<T>
T IList<T>.this[int index]
{
get
{
- if (_array == null)
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray);
- if (index < 0 || index >= _count)
+ ThrowInvalidOperationIfDefault();
+ if (index < 0 || index >= _count)
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
Contract.EndContractBlock();
@@ -170,8 +211,7 @@ namespace System
set
{
- if (_array == null)
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray);
+ ThrowInvalidOperationIfDefault();
if (index < 0 || index >= _count)
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
Contract.EndContractBlock();
@@ -182,9 +222,7 @@ namespace System
int IList<T>.IndexOf(T item)
{
- if (_array == null)
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray);
- Contract.EndContractBlock();
+ ThrowInvalidOperationIfDefault();
int index = System.Array.IndexOf<T>(_array, item, _offset, _count);
@@ -210,8 +248,7 @@ namespace System
{
get
{
- if (_array == null)
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray);
+ ThrowInvalidOperationIfDefault();
if (index < 0 || index >= _count)
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
Contract.EndContractBlock();
@@ -244,9 +281,7 @@ namespace System
bool ICollection<T>.Contains(T item)
{
- if (_array == null)
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray);
- Contract.EndContractBlock();
+ ThrowInvalidOperationIfDefault();
int index = System.Array.IndexOf<T>(_array, item, _offset, _count);
@@ -256,15 +291,6 @@ namespace System
return index >= 0;
}
- void ICollection<T>.CopyTo(T[] array, int arrayIndex)
- {
- if (_array == null)
- ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray);
- Contract.EndContractBlock();
-
- System.Array.Copy(_array, _offset, array, arrayIndex, _count);
- }
-
bool ICollection<T>.Remove(T item)
{
ThrowHelper.ThrowNotSupportedException();
@@ -282,6 +308,14 @@ namespace System
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
#endregion
+ private void ThrowInvalidOperationIfDefault()
+ {
+ if (_array == null)
+ {
+ ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NullArray);
+ }
+ }
+
[Serializable]
public struct Enumerator : IEnumerator<T>
{
diff --git a/src/mscorlib/src/System/Attribute.cs b/src/mscorlib/src/System/Attribute.cs
index b44e13f959..baa9a71638 100644
--- a/src/mscorlib/src/System/Attribute.cs
+++ b/src/mscorlib/src/System/Attribute.cs
@@ -3,19 +3,20 @@
// See the LICENSE file in the project root for more information.
-namespace System {
-
- using System;
- using System.Reflection;
- using System.Collections.Generic;
- using System.Runtime.InteropServices;
- using System.Globalization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Security;
+using System;
+using System.Reflection;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Globalization;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Security;
+
+namespace System
+{
[Serializable]
- [AttributeUsageAttribute(AttributeTargets.All, Inherited = true, AllowMultiple=false)]
+ [AttributeUsageAttribute(AttributeTargets.All, Inherited = true, AllowMultiple = false)]
public abstract class Attribute
{
#region Private Statics
@@ -42,7 +43,7 @@ namespace System {
//if this is an index we need to get the parameter types to help disambiguate
Type[] indexParamTypes = GetIndexParameterTypes(element);
-
+
PropertyInfo baseProp = GetParentDefinition(element, indexParamTypes);
while (baseProp != null)
@@ -61,12 +62,12 @@ namespace System {
// walk up the hierarchy chain
if (element.IsDefined(attributeType, inherit))
return true;
-
+
if (inherit)
{
AttributeUsageAttribute usage = InternalGetAttributeUsage(attributeType);
- if (!usage.Inherited)
+ if (!usage.Inherited)
return false;
//if this is an index we need to get the parameter types to help disambiguate
@@ -92,9 +93,9 @@ namespace System {
// for the current property get the base class of the getter and the setter, they might be different
// note that this only works for RuntimeMethodInfo
- MethodInfo propAccessor = property.GetGetMethod(true);
+ MethodInfo propAccessor = property.GetGetMethod(true);
- if (propAccessor == null)
+ if (propAccessor == null)
propAccessor = property.GetSetMethod(true);
RuntimeMethodInfo rtPropAccessor = propAccessor as RuntimeMethodInfo;
@@ -166,25 +167,25 @@ namespace System {
if (rtAdd != null)
{
rtAdd = rtAdd.GetParentDefinition();
- if (rtAdd != null)
+ if (rtAdd != null)
return rtAdd.DeclaringType.GetEvent(ev.Name);
}
return null;
}
- private static bool InternalIsDefined (EventInfo element, Type attributeType, bool inherit)
+ private static bool InternalIsDefined(EventInfo element, Type attributeType, bool inherit)
{
Contract.Requires(element != null);
// walk up the hierarchy chain
if (element.IsDefined(attributeType, inherit))
return true;
-
+
if (inherit)
{
AttributeUsageAttribute usage = InternalGetAttributeUsage(attributeType);
- if (!usage.Inherited)
+ if (!usage.Inherited)
return false;
EventInfo baseEvent = GetParentDefinition(element);
@@ -244,14 +245,14 @@ namespace System {
// class inherits from and return the respective ParameterInfo attributes
List<Type> disAllowMultiple = new List<Type>();
- Object [] objAttr;
+ Object[] objAttr;
if (type == null)
type = typeof(Attribute);
- objAttr = param.GetCustomAttributes(type, false);
-
- for (int i =0;i < objAttr.Length;i++)
+ objAttr = param.GetCustomAttributes(type, false);
+
+ for (int i = 0; i < objAttr.Length; i++)
{
Type objType = objAttr[i].GetType();
AttributeUsageAttribute attribUsage = InternalGetAttributeUsage(objType);
@@ -260,26 +261,26 @@ namespace System {
}
// Get all the attributes that have Attribute as the base class
- Attribute [] ret = null;
- if (objAttr.Length == 0)
- ret = CreateAttributeArrayHelper(type,0);
- else
+ Attribute[] ret = null;
+ if (objAttr.Length == 0)
+ ret = CreateAttributeArrayHelper(type, 0);
+ else
ret = (Attribute[])objAttr;
-
+
if (param.Member.DeclaringType == null) // This is an interface so we are done.
return ret;
-
- if (!inherit)
+
+ if (!inherit)
return ret;
ParameterInfo baseParam = GetParentDefinition(param);
while (baseParam != null)
{
- objAttr = baseParam.GetCustomAttributes(type, false);
-
+ objAttr = baseParam.GetCustomAttributes(type, false);
+
int count = 0;
- for (int i =0;i < objAttr.Length;i++)
+ for (int i = 0; i < objAttr.Length; i++)
{
Type objType = objAttr[i].GetType();
AttributeUsageAttribute attribUsage = InternalGetAttributeUsage(objType);
@@ -295,10 +296,10 @@ namespace System {
}
// Get all the attributes that have Attribute as the base class
- Attribute [] attributes = CreateAttributeArrayHelper(type,count);
-
+ Attribute[] attributes = CreateAttributeArrayHelper(type, count);
+
count = 0;
- for (int i =0;i < objAttr.Length;i++)
+ for (int i = 0; i < objAttr.Length; i++)
{
if (objAttr[i] != null)
{
@@ -306,18 +307,18 @@ namespace System {
count++;
}
}
-
- Attribute [] temp = ret;
- ret = CreateAttributeArrayHelper(type,temp.Length + count);
- Array.Copy(temp,ret,temp.Length);
-
+
+ Attribute[] temp = ret;
+ ret = CreateAttributeArrayHelper(type, temp.Length + count);
+ Array.Copy(temp, ret, temp.Length);
+
int offset = temp.Length;
- for (int i =0;i < attributes.Length;i++)
+ for (int i = 0; i < attributes.Length; i++)
ret[offset + i] = attributes[i];
baseParam = GetParentDefinition(baseParam);
- }
+ }
return ret;
}
@@ -335,7 +336,7 @@ namespace System {
if (param.IsDefined(type, false))
return true;
-
+
if (param.Member.DeclaringType == null || !inherit) // This is an interface so we are done.
return false;
@@ -343,9 +344,9 @@ namespace System {
while (baseParam != null)
{
- Object[] objAttr = baseParam.GetCustomAttributes(type, false);
-
- for (int i =0; i < objAttr.Length; i++)
+ Object[] objAttr = baseParam.GetCustomAttributes(type, false);
+
+ for (int i = 0; i < objAttr.Length; i++)
{
Type objType = objAttr[i].GetType();
AttributeUsageAttribute attribUsage = InternalGetAttributeUsage(objType);
@@ -355,7 +356,7 @@ namespace System {
}
baseParam = GetParentDefinition(baseParam);
- }
+ }
return false;
}
@@ -363,15 +364,15 @@ namespace System {
#endregion
#region Utility
- private static void CopyToArrayList(List<Attribute> attributeList,Attribute[] attributes,Dictionary<Type, AttributeUsageAttribute> types)
+ private static void CopyToArrayList(List<Attribute> attributeList, Attribute[] attributes, Dictionary<Type, AttributeUsageAttribute> types)
{
- for (int i = 0; i < attributes.Length; i++)
+ for (int i = 0; i < attributes.Length; i++)
{
attributeList.Add(attributes[i]);
Type attrType = attributes[i].GetType();
- if (!types.ContainsKey(attrType))
+ if (!types.ContainsKey(attrType))
types[attrType] = InternalGetAttributeUsage(attrType);
}
}
@@ -393,21 +394,21 @@ namespace System {
return Array.Empty<Type>();
}
- private static void AddAttributesToList(List<Attribute> attributeList, Attribute[] attributes, Dictionary<Type, AttributeUsageAttribute> types)
+ private static void AddAttributesToList(List<Attribute> attributeList, Attribute[] attributes, Dictionary<Type, AttributeUsageAttribute> types)
{
- for (int i = 0; i < attributes.Length; i++)
+ for (int i = 0; i < attributes.Length; i++)
{
Type attrType = attributes[i].GetType();
AttributeUsageAttribute usage = null;
types.TryGetValue(attrType, out usage);
- if (usage == null)
+ if (usage == null)
{
// the type has never been seen before if it's inheritable add it to the list
usage = InternalGetAttributeUsage(attrType);
types[attrType] = usage;
- if (usage.Inherited)
+ if (usage.Inherited)
attributeList.Add(attributes[i]);
}
else if (usage.Inherited && usage.AllowMultiple)
@@ -421,7 +422,7 @@ namespace System {
private static AttributeUsageAttribute InternalGetAttributeUsage(Type type)
{
// Check if the custom attributes is Inheritable
- Object [] obj = type.GetCustomAttributes(typeof(AttributeUsageAttribute), false);
+ Object[] obj = type.GetCustomAttributes(typeof(AttributeUsageAttribute), false);
if (obj.Length == 1)
return (AttributeUsageAttribute)obj[0];
@@ -430,7 +431,7 @@ namespace System {
return AttributeUsageAttribute.Default;
throw new FormatException(
- Environment.GetResourceString("Format_AttributeUsage", type));
+ SR.Format(SR.Format_AttributeUsage, type));
}
private static Attribute[] CreateAttributeArrayHelper(Type elementType, int elementCount)
@@ -448,7 +449,7 @@ namespace System {
{
return GetCustomAttributes(element, type, true);
}
-
+
public static Attribute[] GetCustomAttributes(MemberInfo element, Type type, bool inherit)
{
if (element == null)
@@ -456,17 +457,17 @@ namespace System {
if (type == null)
throw new ArgumentNullException(nameof(type));
-
+
if (!type.IsSubclassOf(typeof(Attribute)) && type != typeof(Attribute))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
+ throw new ArgumentException(SR.Argument_MustHaveAttributeBaseClass);
Contract.EndContractBlock();
switch (element.MemberType)
{
- case MemberTypes.Property:
+ case MemberTypes.Property:
return InternalGetCustomAttributes((PropertyInfo)element, type, inherit);
- case MemberTypes.Event:
+ case MemberTypes.Event:
return InternalGetCustomAttributes((EventInfo)element, type, inherit);
default:
@@ -487,17 +488,17 @@ namespace System {
switch (element.MemberType)
{
- case MemberTypes.Property:
+ case MemberTypes.Property:
return InternalGetCustomAttributes((PropertyInfo)element, typeof(Attribute), inherit);
- case MemberTypes.Event:
+ case MemberTypes.Event:
return InternalGetCustomAttributes((EventInfo)element, typeof(Attribute), inherit);
default:
return element.GetCustomAttributes(typeof(Attribute), inherit) as Attribute[];
}
}
-
+
public static bool IsDefined(MemberInfo element, Type attributeType)
{
return IsDefined(element, attributeType, true);
@@ -511,23 +512,22 @@ namespace System {
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));
-
+
if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
+ throw new ArgumentException(SR.Argument_MustHaveAttributeBaseClass);
Contract.EndContractBlock();
- switch(element.MemberType)
+ switch (element.MemberType)
{
- case MemberTypes.Property:
+ case MemberTypes.Property:
return InternalIsDefined((PropertyInfo)element, attributeType, inherit);
- case MemberTypes.Event:
+ case MemberTypes.Event:
return InternalIsDefined((EventInfo)element, attributeType, inherit);
default:
return element.IsDefined(attributeType, inherit);
}
-
}
public static Attribute GetCustomAttribute(MemberInfo element, Type attributeType)
@@ -545,7 +545,7 @@ namespace System {
if (attrib.Length == 1)
return attrib[0];
- throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.AmbigCust"));
+ throw new AmbiguousMatchException(SR.RFLCT_AmbigCust);
}
#endregion
@@ -555,7 +555,7 @@ namespace System {
{
return GetCustomAttributes(element, true);
}
-
+
public static Attribute[] GetCustomAttributes(ParameterInfo element, Type attributeType)
{
return (Attribute[])GetCustomAttributes(element, attributeType, true);
@@ -568,17 +568,17 @@ namespace System {
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));
-
+
if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
+ throw new ArgumentException(SR.Argument_MustHaveAttributeBaseClass);
if (element.Member == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidParameterInfo"), nameof(element));
+ throw new ArgumentException(SR.Argument_InvalidParameterInfo, nameof(element));
Contract.EndContractBlock();
MemberInfo member = element.Member;
- if (member.MemberType == MemberTypes.Method && inherit)
+ if (member.MemberType == MemberTypes.Method && inherit)
return InternalParamGetCustomAttributes(element, attributeType, inherit) as Attribute[];
return element.GetCustomAttributes(attributeType, inherit) as Attribute[];
@@ -590,14 +590,14 @@ namespace System {
throw new ArgumentNullException(nameof(element));
if (element.Member == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidParameterInfo"), nameof(element));
+ throw new ArgumentException(SR.Argument_InvalidParameterInfo, nameof(element));
Contract.EndContractBlock();
MemberInfo member = element.Member;
- if (member.MemberType == MemberTypes.Method && inherit)
+ if (member.MemberType == MemberTypes.Method && inherit)
return InternalParamGetCustomAttributes(element, null, inherit) as Attribute[];
-
+
return element.GetCustomAttributes(typeof(Attribute), inherit) as Attribute[];
}
@@ -614,14 +614,14 @@ namespace System {
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));
-
+
if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
+ throw new ArgumentException(SR.Argument_MustHaveAttributeBaseClass);
Contract.EndContractBlock();
MemberInfo member = element.Member;
- switch(member.MemberType)
+ switch (member.MemberType)
{
case MemberTypes.Method: // We need to climb up the member hierarchy
return InternalParamIsDefined(element, attributeType, inherit);
@@ -632,9 +632,9 @@ namespace System {
case MemberTypes.Property:
return element.IsDefined(attributeType, false);
- default:
+ default:
Debug.Assert(false, "Invalid type for ParameterInfo member in Attribute class");
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidParamInfo"));
+ throw new ArgumentException(SR.Argument_InvalidParamInfo);
}
}
@@ -658,7 +658,7 @@ namespace System {
if (attrib.Length == 1)
return attrib[0];
- throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.AmbigCust"));
+ throw new AmbiguousMatchException(SR.RFLCT_AmbigCust);
}
#endregion
@@ -666,7 +666,7 @@ namespace System {
#region Module
public static Attribute[] GetCustomAttributes(Module element, Type attributeType)
{
- return GetCustomAttributes (element, attributeType, true);
+ return GetCustomAttributes(element, attributeType, true);
}
public static Attribute[] GetCustomAttributes(Module element)
@@ -692,7 +692,7 @@ namespace System {
throw new ArgumentNullException(nameof(attributeType));
if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
+ throw new ArgumentException(SR.Argument_MustHaveAttributeBaseClass);
Contract.EndContractBlock();
return (Attribute[])element.GetCustomAttributes(attributeType, inherit);
@@ -713,10 +713,10 @@ namespace System {
throw new ArgumentNullException(nameof(attributeType));
if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
+ throw new ArgumentException(SR.Argument_MustHaveAttributeBaseClass);
Contract.EndContractBlock();
- return element.IsDefined(attributeType,false);
+ return element.IsDefined(attributeType, false);
}
public static Attribute GetCustomAttribute(Module element, Type attributeType)
@@ -728,7 +728,7 @@ namespace System {
{
// Returns an Attribute of base class/inteface attributeType on the Module or null if none exists.
// throws an AmbiguousMatchException if there are more than one defined.
- Attribute[] attrib = GetCustomAttributes(element,attributeType,inherit);
+ Attribute[] attrib = GetCustomAttributes(element, attributeType, inherit);
if (attrib == null || attrib.Length == 0)
return null;
@@ -736,7 +736,7 @@ namespace System {
if (attrib.Length == 1)
return attrib[0];
- throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.AmbigCust"));
+ throw new AmbiguousMatchException(SR.RFLCT_AmbigCust);
}
#endregion
@@ -756,7 +756,7 @@ namespace System {
throw new ArgumentNullException(nameof(attributeType));
if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
+ throw new ArgumentException(SR.Argument_MustHaveAttributeBaseClass);
Contract.EndContractBlock();
return (Attribute[])element.GetCustomAttributes(attributeType, inherit);
@@ -776,12 +776,12 @@ namespace System {
return (Attribute[])element.GetCustomAttributes(typeof(Attribute), inherit);
}
- public static bool IsDefined (Assembly element, Type attributeType)
+ public static bool IsDefined(Assembly element, Type attributeType)
{
- return IsDefined (element, attributeType, true);
+ return IsDefined(element, attributeType, true);
}
- public static bool IsDefined (Assembly element, Type attributeType, bool inherit)
+ public static bool IsDefined(Assembly element, Type attributeType, bool inherit)
{
// Returns true is a custom attribute subclass of attributeType class/interface with no inheritance walk
if (element == null)
@@ -791,7 +791,7 @@ namespace System {
throw new ArgumentNullException(nameof(attributeType));
if (!attributeType.IsSubclassOf(typeof(Attribute)) && attributeType != typeof(Attribute))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustHaveAttributeBaseClass"));
+ throw new ArgumentException(SR.Argument_MustHaveAttributeBaseClass);
Contract.EndContractBlock();
return element.IsDefined(attributeType, false);
@@ -799,14 +799,14 @@ namespace System {
public static Attribute GetCustomAttribute(Assembly element, Type attributeType)
{
- return GetCustomAttribute (element, attributeType, true);
+ return GetCustomAttribute(element, attributeType, true);
}
public static Attribute GetCustomAttribute(Assembly element, Type attributeType, bool inherit)
{
// Returns an Attribute of base class/inteface attributeType on the Assembly or null if none exists.
// throws an AmbiguousMatchException if there are more than one defined.
- Attribute[] attrib = GetCustomAttributes(element,attributeType,inherit);
+ Attribute[] attrib = GetCustomAttributes(element, attributeType, inherit);
if (attrib == null || attrib.Length == 0)
return null;
@@ -814,7 +814,7 @@ namespace System {
if (attrib.Length == 1)
return attrib[0];
- throw new AmbiguousMatchException(Environment.GetResourceString("RFLCT.AmbigCust"));
+ throw new AmbiguousMatchException(SR.RFLCT_AmbigCust);
}
#endregion
@@ -945,7 +945,7 @@ namespace System {
#region Public Virtual Members
public virtual Object TypeId { get { return GetType(); } }
-
+
public virtual bool Match(Object obj) { return Equals(obj); }
#endregion
diff --git a/src/mscorlib/src/System/AttributeUsageAttribute.cs b/src/mscorlib/src/System/AttributeUsageAttribute.cs
deleted file mode 100644
index 33f7fd805e..0000000000
--- a/src/mscorlib/src/System/AttributeUsageAttribute.cs
+++ /dev/null
@@ -1,56 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose: The class denotes how to specify the usage of an attribute
-**
-**
-===========================================================*/
-namespace System {
-
- using System.Reflection;
- /* By default, attributes are inherited and multiple attributes are not allowed */
-[Serializable]
- [AttributeUsage(AttributeTargets.Class, Inherited = true)]
- public sealed class AttributeUsageAttribute : Attribute
- {
- internal AttributeTargets m_attributeTarget = AttributeTargets.All; // Defaults to all
- internal bool m_allowMultiple = false; // Defaults to false
- internal bool m_inherited = true; // Defaults to true
-
- internal static AttributeUsageAttribute Default = new AttributeUsageAttribute(AttributeTargets.All);
-
- //Constructors
- public AttributeUsageAttribute(AttributeTargets validOn) {
- m_attributeTarget = validOn;
- }
- internal AttributeUsageAttribute(AttributeTargets validOn, bool allowMultiple, bool inherited) {
- m_attributeTarget = validOn;
- m_allowMultiple = allowMultiple;
- m_inherited = inherited;
- }
-
-
- //Properties
- public AttributeTargets ValidOn
- {
- get{ return m_attributeTarget; }
- }
-
- public bool AllowMultiple
- {
- get { return m_allowMultiple; }
- set { m_allowMultiple = value; }
- }
-
- public bool Inherited
- {
- get { return m_inherited; }
- set { m_inherited = value; }
- }
- }
-}
diff --git a/src/mscorlib/src/System/BCLDebug.cs b/src/mscorlib/src/System/BCLDebug.cs
index 7556b85789..67f7c9a0f7 100644
--- a/src/mscorlib/src/System/BCLDebug.cs
+++ b/src/mscorlib/src/System/BCLDebug.cs
@@ -11,8 +11,8 @@
**
============================================================*/
-namespace System {
-
+namespace System
+{
using System.IO;
using System.Text;
using System.Runtime.Remoting;
@@ -24,28 +24,32 @@ namespace System {
using System.Diagnostics.Contracts;
[Serializable]
- internal enum LogLevel {
- Trace = 0,
+ internal enum LogLevel
+ {
+ Trace = 0,
Status = 20,
- Warning= 40,
- Error = 50,
- Panic = 100,
+ Warning = 40,
+ Error = 50,
+ Panic = 100,
}
- internal struct SwitchStructure {
+ internal struct SwitchStructure
+ {
internal String name;
- internal int value;
-
- internal SwitchStructure (String n, int v) {
+ internal int value;
+
+ internal SwitchStructure(String n, int v)
+ {
name = n;
value = v;
}
}
-
+
// Only statics, does not need to be marked with the serializable attribute
- internal static class BCLDebug {
- internal static volatile bool m_registryChecked=false;
+ internal static class BCLDebug
+ {
+ internal static volatile bool m_registryChecked = false;
internal static volatile bool m_loggingNotEnabled = false;
internal static bool m_perfWarnings;
internal static bool m_correctnessWarnings;
@@ -54,7 +58,7 @@ namespace System {
internal static volatile bool m_domainUnloadAdded;
#endif
- static readonly SwitchStructure[] switches = {
+ private static readonly SwitchStructure[] switches = {
new SwitchStructure("NLS", 0x00000001),
new SwitchStructure("SER", 0x00000002),
new SwitchStructure("DYNIL",0x00000004),
@@ -64,14 +68,14 @@ namespace System {
new SwitchStructure("REMOTINGCHANNELS",0x00000040),
new SwitchStructure("CACHE",0x00000080),
new SwitchStructure("RESMGRFILEFORMAT", 0x00000100), // .resources files
- new SwitchStructure("PERF", 0x00000200),
- new SwitchStructure("CORRECTNESS", 0x00000400),
- new SwitchStructure("MEMORYFAILPOINT", 0x00000800),
+ new SwitchStructure("PERF", 0x00000200),
+ new SwitchStructure("CORRECTNESS", 0x00000400),
+ new SwitchStructure("MEMORYFAILPOINT", 0x00000800),
new SwitchStructure("DATETIME", 0x00001000), // System.DateTime managed tracing
new SwitchStructure("INTEROP", 0x00002000), // Interop tracing
};
- static readonly LogLevel[] levelConversions = {
+ private static readonly LogLevel[] levelConversions = {
LogLevel.Panic,
LogLevel.Error,
LogLevel.Error,
@@ -89,24 +93,28 @@ namespace System {
#if _DEBUG
internal static void WaitForFinalizers(Object sender, EventArgs e)
{
- if (!m_registryChecked) {
+ if (!m_registryChecked)
+ {
CheckRegistry();
}
- if (m_correctnessWarnings) {
+ if (m_correctnessWarnings)
+ {
GC.GetTotalMemory(true);
GC.WaitForPendingFinalizers();
}
}
#endif
[Conditional("_DEBUG")]
- static public void Assert(bool condition) {
+ static public void Assert(bool condition)
+ {
#if _DEBUG
Assert(condition, "Assert failed.");
#endif
}
[Conditional("_DEBUG")]
- static public void Assert(bool condition, String message) {
+ static public void Assert(bool condition, String message)
+ {
#if _DEBUG
// Speed up debug builds marginally by avoiding the garbage from
// concatinating "BCL Assert: " and the message.
@@ -114,13 +122,15 @@ namespace System {
System.Diagnostics.Assert.Check(condition, "BCL Assert", message);
#endif
}
-
+
[Pure]
[Conditional("_LOGGING")]
- static public void Log(String message) {
+ static public void Log(String message)
+ {
if (AppDomain.CurrentDomain.IsUnloadingForcedFinalize())
return;
- if (!m_registryChecked) {
+ if (!m_registryChecked)
+ {
CheckRegistry();
}
System.Diagnostics.Log.Trace(message);
@@ -129,23 +139,29 @@ namespace System {
[Pure]
[Conditional("_LOGGING")]
- static public void Log(String switchName, String message) {
+ static public void Log(String switchName, String message)
+ {
if (AppDomain.CurrentDomain.IsUnloadingForcedFinalize())
return;
- if (!m_registryChecked) {
+ if (!m_registryChecked)
+ {
CheckRegistry();
}
- try {
+ try
+ {
LogSwitch ls;
ls = LogSwitch.GetSwitch(switchName);
- if (ls!=null) {
- System.Diagnostics.Log.Trace(ls,message);
- System.Diagnostics.Log.Trace(ls,Environment.NewLine);
+ if (ls != null)
+ {
+ System.Diagnostics.Log.Trace(ls, message);
+ System.Diagnostics.Log.Trace(ls, Environment.NewLine);
}
- } catch {
+ }
+ catch
+ {
System.Diagnostics.Log.Trace("Exception thrown in logging." + Environment.NewLine);
- System.Diagnostics.Log.Trace("Switch was: " + ((switchName==null)?"<null>":switchName) + Environment.NewLine);
- System.Diagnostics.Log.Trace("Message was: " + ((message==null)?"<null>":message) + Environment.NewLine);
+ System.Diagnostics.Log.Trace("Switch was: " + ((switchName == null) ? "<null>" : switchName) + Environment.NewLine);
+ System.Diagnostics.Log.Trace("Message was: " + ((message == null) ? "<null>" : message) + Environment.NewLine);
}
}
@@ -156,38 +172,46 @@ namespace System {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static int GetRegistryLoggingValues(out bool loggingEnabled, out bool logToConsole, out int logLevel, out bool perfWarnings, out bool correctnessWarnings, out bool safeHandleStackTraces);
- private static void CheckRegistry() {
+ private static void CheckRegistry()
+ {
if (AppDomain.CurrentDomain.IsUnloadingForcedFinalize())
return;
- if (m_registryChecked) {
+ if (m_registryChecked)
+ {
return;
}
-
+
m_registryChecked = true;
bool loggingEnabled;
bool logToConsole;
- int logLevel;
- int facilityValue;
+ int logLevel;
+ int facilityValue;
facilityValue = GetRegistryLoggingValues(out loggingEnabled, out logToConsole, out logLevel, out m_perfWarnings, out m_correctnessWarnings, out m_safeHandleStackTraces);
// Note we can get into some recursive situations where we call
// ourseves recursively through the .cctor. That's why we have the
// check for levelConversions == null.
- if (!loggingEnabled) {
+ if (!loggingEnabled)
+ {
m_loggingNotEnabled = true;
}
- if (loggingEnabled && levelConversions!=null) {
- try {
+ if (loggingEnabled && levelConversions != null)
+ {
+ try
+ {
//The values returned for the logging levels in the registry don't map nicely onto the
//values which we support internally (which are an approximation of the ones that
//the System.Diagnostics namespace uses) so we have a quick map.
- Assert(logLevel>=0 && logLevel<=10, "logLevel>=0 && logLevel<=10");
+ Assert(logLevel >= 0 && logLevel <= 10, "logLevel>=0 && logLevel<=10");
logLevel = (int)levelConversions[logLevel];
-
- if (facilityValue>0) {
- for (int i=0; i<switches.Length; i++) {
- if ((switches[i].value & facilityValue)!=0) {
+
+ if (facilityValue > 0)
+ {
+ for (int i = 0; i < switches.Length; i++)
+ {
+ if ((switches[i].value & facilityValue) != 0)
+ {
LogSwitch L = new LogSwitch(switches[i].name, switches[i].name, System.Diagnostics.Log.GlobalSwitch);
L.MinimumLevel = (LoggingLevels)logLevel;
}
@@ -195,65 +219,80 @@ namespace System {
System.Diagnostics.Log.GlobalSwitch.MinimumLevel = (LoggingLevels)logLevel;
System.Diagnostics.Log.IsConsoleEnabled = logToConsole;
}
-
- } catch {
+ }
+ catch
+ {
//Silently eat any exceptions.
}
}
}
- internal static bool CheckEnabled(String switchName) {
+ internal static bool CheckEnabled(String switchName)
+ {
if (AppDomain.CurrentDomain.IsUnloadingForcedFinalize())
return false;
if (!m_registryChecked)
CheckRegistry();
LogSwitch logSwitch = LogSwitch.GetSwitch(switchName);
- if (logSwitch==null) {
+ if (logSwitch == null)
+ {
return false;
}
- return ((int)logSwitch.MinimumLevel<=(int)LogLevel.Trace);
+ return ((int)logSwitch.MinimumLevel <= (int)LogLevel.Trace);
}
- private static bool CheckEnabled(String switchName, LogLevel level, out LogSwitch logSwitch) {
+ private static bool CheckEnabled(String switchName, LogLevel level, out LogSwitch logSwitch)
+ {
if (AppDomain.CurrentDomain.IsUnloadingForcedFinalize())
{
logSwitch = null;
return false;
}
logSwitch = LogSwitch.GetSwitch(switchName);
- if (logSwitch==null) {
+ if (logSwitch == null)
+ {
return false;
}
- return ((int)logSwitch.MinimumLevel<=(int)level);
+ return ((int)logSwitch.MinimumLevel <= (int)level);
}
[Pure]
[Conditional("_LOGGING")]
- public static void Log(String switchName, LogLevel level, params Object[]messages) {
+ public static void Log(String switchName, LogLevel level, params Object[] messages)
+ {
if (AppDomain.CurrentDomain.IsUnloadingForcedFinalize())
return;
//Add code to check if logging is enabled in the registry.
LogSwitch logSwitch;
- if (!m_registryChecked) {
+ if (!m_registryChecked)
+ {
CheckRegistry();
}
- if (!CheckEnabled(switchName, level, out logSwitch)) {
+ if (!CheckEnabled(switchName, level, out logSwitch))
+ {
return;
}
StringBuilder sb = StringBuilderCache.Acquire();
- for (int i=0; i<messages.Length; i++) {
+ for (int i = 0; i < messages.Length; i++)
+ {
String s;
- try {
- if (messages[i]==null) {
+ try
+ {
+ if (messages[i] == null)
+ {
s = "<null>";
- } else {
+ }
+ else
+ {
s = messages[i].ToString();
}
- } catch {
+ }
+ catch
+ {
s = "<unable to convert>";
}
sb.Append(s);
@@ -263,13 +302,16 @@ namespace System {
[Pure]
[Conditional("_LOGGING")]
- public static void Trace(String switchName, String format, params Object[] messages) {
- if (m_loggingNotEnabled) {
+ public static void Trace(String switchName, String format, params Object[] messages)
+ {
+ if (m_loggingNotEnabled)
+ {
return;
}
LogSwitch logSwitch;
- if (!CheckEnabled(switchName, LogLevel.Trace, out logSwitch)) {
+ if (!CheckEnabled(switchName, LogLevel.Trace, out logSwitch))
+ {
return;
}
@@ -292,8 +334,9 @@ namespace System {
if (!m_perfWarnings)
return;
- if (!expr) {
- Log("PERF", "BCL Perf Warning: "+msg);
+ if (!expr)
+ {
+ Log("PERF", "BCL Perf Warning: " + msg);
}
System.Diagnostics.Assert.Check(expr, "BCL Perf Warning: Your perf may be less than perfect because...", msg);
}
@@ -313,13 +356,15 @@ namespace System {
if (!m_correctnessWarnings)
return;
- if (!m_domainUnloadAdded) {
+ if (!m_domainUnloadAdded)
+ {
m_domainUnloadAdded = true;
AppDomain.CurrentDomain.DomainUnload += new EventHandler(WaitForFinalizers);
}
- if (!expr) {
- Log("CORRECTNESS", "BCL Correctness Warning: "+msg);
+ if (!expr)
+ {
+ Log("CORRECTNESS", "BCL Correctness Warning: " + msg);
}
System.Diagnostics.Assert.Check(expr, "BCL Correctness Warning: Your program may not work because...", msg);
#endif
@@ -327,8 +372,10 @@ namespace System {
// Whether SafeHandles include a stack trace showing where they
// were allocated. Only useful in checked & debug builds.
- internal static bool SafeHandleStackTracesEnabled {
- get {
+ internal static bool SafeHandleStackTracesEnabled
+ {
+ get
+ {
#if _DEBUG
if (!m_registryChecked)
CheckRegistry();
diff --git a/src/mscorlib/src/System/BadImageFormatException.cs b/src/mscorlib/src/System/BadImageFormatException.cs
index 51a6c40771..42005cccce 100644
--- a/src/mscorlib/src/System/BadImageFormatException.cs
+++ b/src/mscorlib/src/System/BadImageFormatException.cs
@@ -11,8 +11,8 @@
**
===========================================================*/
-namespace System {
-
+namespace System
+{
using System;
using System.Runtime.Serialization;
using FileLoadException = System.IO.FileLoadException;
@@ -20,41 +20,46 @@ namespace System {
using System.Globalization;
[Serializable]
- public class BadImageFormatException : SystemException {
-
+ public class BadImageFormatException : SystemException
+ {
private String _fileName; // The name of the corrupt PE file.
private String _fusionLog; // fusion log (when applicable)
- public BadImageFormatException()
- : base(Environment.GetResourceString("Arg_BadImageFormatException")) {
- SetErrorCode(__HResults.COR_E_BADIMAGEFORMAT);
+ public BadImageFormatException()
+ : base(SR.Arg_BadImageFormatException)
+ {
+ HResult = __HResults.COR_E_BADIMAGEFORMAT;
}
-
- public BadImageFormatException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_BADIMAGEFORMAT);
+
+ public BadImageFormatException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_BADIMAGEFORMAT;
}
-
- public BadImageFormatException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_BADIMAGEFORMAT);
+
+ public BadImageFormatException(String message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_BADIMAGEFORMAT;
}
public BadImageFormatException(String message, String fileName) : base(message)
{
- SetErrorCode(__HResults.COR_E_BADIMAGEFORMAT);
+ HResult = __HResults.COR_E_BADIMAGEFORMAT;
_fileName = fileName;
}
- public BadImageFormatException(String message, String fileName, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_BADIMAGEFORMAT);
+ public BadImageFormatException(String message, String fileName, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_BADIMAGEFORMAT;
_fileName = fileName;
}
public override String Message
{
- get {
+ get
+ {
SetMessageField();
return _message;
}
@@ -62,17 +67,19 @@ namespace System {
private void SetMessageField()
{
- if (_message == null) {
+ if (_message == null)
+ {
if ((_fileName == null) &&
(HResult == System.__HResults.COR_E_EXCEPTION))
- _message = Environment.GetResourceString("Arg_BadImageFormatException");
+ _message = SR.Arg_BadImageFormatException;
else
_message = FileLoadException.FormatFileLoadExceptionMessage(_fileName, HResult);
}
}
- public String FileName {
+ public String FileName
+ {
get { return _fileName; }
}
@@ -81,8 +88,8 @@ namespace System {
String s = GetType().FullName + ": " + Message;
if (_fileName != null && _fileName.Length != 0)
- s += Environment.NewLine + Environment.GetResourceString("IO.FileName_Name", _fileName);
-
+ s += Environment.NewLine + SR.Format(SR.IO_FileName_Name, _fileName);
+
if (InnerException != null)
s = s + " ---> " + InnerException.ToString();
@@ -90,23 +97,23 @@ namespace System {
s += Environment.NewLine + StackTrace;
try
{
- if(FusionLog!=null)
+ if (FusionLog != null)
{
- if (s==null)
- s=" ";
- s+=Environment.NewLine;
- s+=Environment.NewLine;
- s+=FusionLog;
+ if (s == null)
+ s = " ";
+ s += Environment.NewLine;
+ s += Environment.NewLine;
+ s += FusionLog;
}
}
- catch(SecurityException)
+ catch (SecurityException)
{
-
}
return s;
}
- protected BadImageFormatException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ protected BadImageFormatException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
// Base class constructor will check info != null.
_fileName = info.GetString("BadImageFormat_FileName");
@@ -114,7 +121,7 @@ namespace System {
{
_fusionLog = info.GetString("BadImageFormat_FusionLog");
}
- catch
+ catch
{
_fusionLog = null;
}
@@ -123,19 +130,21 @@ namespace System {
private BadImageFormatException(String fileName, String fusionLog, int hResult)
: base(null)
{
- SetErrorCode(hResult);
+ HResult = hResult;
_fileName = fileName;
- _fusionLog=fusionLog;
+ _fusionLog = fusionLog;
SetMessageField();
}
- public String FusionLog {
+ public String FusionLog
+ {
#pragma warning disable CS0618 // Type or member is obsolete
#pragma warning restore CS0618 // Type or member is obsolete
get { return _fusionLog; }
}
- public override void GetObjectData(SerializationInfo info, StreamingContext context) {
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
// Serialize data for our base classes. base will verify info != null.
base.GetObjectData(info, context);
diff --git a/src/mscorlib/src/System/BitConverter.cs b/src/mscorlib/src/System/BitConverter.cs
index 07af5a8178..a17a067bec 100644
--- a/src/mscorlib/src/System/BitConverter.cs
+++ b/src/mscorlib/src/System/BitConverter.cs
@@ -2,31 +2,19 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-/*============================================================
-**
-**
-**
-** Purpose: Allows developers to view the base data types as
-** an arbitrary array of bits.
-**
-**
-===========================================================*/
-namespace System {
-
- using System;
- using System.Runtime.CompilerServices;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Security;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.CompilerServices;
+using System.Security;
+namespace System
+{
// The BitConverter class contains methods for
// converting an array of bytes to one of the base data
// types, as well as for converting a base data type to an
// array of bytes.
- //
- // Only statics, does not need to be marked with the serializable attribute
- public static class BitConverter {
-
+ public static class BitConverter
+ {
// This field indicates the "endianess" of the architecture.
// The value is set to true if the architecture is
// little endian; false if it is big endian.
@@ -36,378 +24,299 @@ namespace System {
public static readonly bool IsLittleEndian = true;
#endif
- // Converts a byte into an array of bytes with length one.
- public static byte[] GetBytes(bool value) {
+ // Converts a Boolean into an array of bytes with length one.
+ public static byte[] GetBytes(bool value)
+ {
Contract.Ensures(Contract.Result<byte[]>() != null);
Contract.Ensures(Contract.Result<byte[]>().Length == 1);
byte[] r = new byte[1];
- r[0] = (value ? (byte)Boolean.True : (byte)Boolean.False );
+ r[0] = (value ? (byte)1 : (byte)0);
return r;
}
-
+
// Converts a char into an array of bytes with length two.
public static byte[] GetBytes(char value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
- Contract.Ensures(Contract.Result<byte[]>().Length == 2);
+ Contract.Ensures(Contract.Result<byte[]>().Length == sizeof(char));
- return GetBytes((short)value);
+ byte[] bytes = new byte[sizeof(char)];
+ Unsafe.As<byte, char>(ref bytes[0]) = value;
+ return bytes;
}
-
+
// Converts a short into an array of bytes with length
// two.
- public unsafe static byte[] GetBytes(short value)
+ public static byte[] GetBytes(short value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
- Contract.Ensures(Contract.Result<byte[]>().Length == 2);
+ Contract.Ensures(Contract.Result<byte[]>().Length == sizeof(short));
- byte[] bytes = new byte[2];
- fixed(byte* b = &bytes[0])
- *((short*)b) = value;
+ byte[] bytes = new byte[sizeof(short)];
+ Unsafe.As<byte, short>(ref bytes[0]) = value;
return bytes;
}
// Converts an int into an array of bytes with length
// four.
- public unsafe static byte[] GetBytes(int value)
+ public static byte[] GetBytes(int value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
- Contract.Ensures(Contract.Result<byte[]>().Length == 4);
+ Contract.Ensures(Contract.Result<byte[]>().Length == sizeof(int));
- byte[] bytes = new byte[4];
- fixed(byte* b = &bytes[0])
- *((int*)b) = value;
+ byte[] bytes = new byte[sizeof(int)];
+ Unsafe.As<byte, int>(ref bytes[0]) = value;
return bytes;
}
-
+
// Converts a long into an array of bytes with length
// eight.
- public unsafe static byte[] GetBytes(long value)
+ public static byte[] GetBytes(long value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
- Contract.Ensures(Contract.Result<byte[]>().Length == 8);
+ Contract.Ensures(Contract.Result<byte[]>().Length == sizeof(long));
- byte[] bytes = new byte[8];
- fixed(byte* b = &bytes[0])
- *((long*)b) = value;
+ byte[] bytes = new byte[sizeof(long)];
+ Unsafe.As<byte, long>(ref bytes[0]) = value;
return bytes;
}
-
+
// Converts an ushort into an array of bytes with
// length two.
[CLSCompliant(false)]
- public static byte[] GetBytes(ushort value) {
+ public static byte[] GetBytes(ushort value)
+ {
Contract.Ensures(Contract.Result<byte[]>() != null);
- Contract.Ensures(Contract.Result<byte[]>().Length == 2);
+ Contract.Ensures(Contract.Result<byte[]>().Length == sizeof(ushort));
- return GetBytes((short)value);
+ byte[] bytes = new byte[sizeof(ushort)];
+ Unsafe.As<byte, ushort>(ref bytes[0]) = value;
+ return bytes;
}
-
+
// Converts an uint into an array of bytes with
// length four.
[CLSCompliant(false)]
- public static byte[] GetBytes(uint value) {
+ public static byte[] GetBytes(uint value)
+ {
Contract.Ensures(Contract.Result<byte[]>() != null);
- Contract.Ensures(Contract.Result<byte[]>().Length == 4);
+ Contract.Ensures(Contract.Result<byte[]>().Length == sizeof(uint));
- return GetBytes((int)value);
+ byte[] bytes = new byte[sizeof(uint)];
+ Unsafe.As<byte, uint>(ref bytes[0]) = value;
+ return bytes;
}
-
+
// Converts an unsigned long into an array of bytes with
// length eight.
[CLSCompliant(false)]
- public static byte[] GetBytes(ulong value) {
+ public static byte[] GetBytes(ulong value)
+ {
Contract.Ensures(Contract.Result<byte[]>() != null);
- Contract.Ensures(Contract.Result<byte[]>().Length == 8);
+ Contract.Ensures(Contract.Result<byte[]>().Length == sizeof(ulong));
- return GetBytes((long)value);
+ byte[] bytes = new byte[sizeof(ulong)];
+ Unsafe.As<byte, ulong>(ref bytes[0]) = value;
+ return bytes;
}
-
+
// Converts a float into an array of bytes with length
// four.
- public unsafe static byte[] GetBytes(float value)
+ public static byte[] GetBytes(float value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
- Contract.Ensures(Contract.Result<byte[]>().Length == 4);
+ Contract.Ensures(Contract.Result<byte[]>().Length == sizeof(float));
- return GetBytes(*(int*)&value);
+ byte[] bytes = new byte[sizeof(float)];
+ Unsafe.As<byte, float>(ref bytes[0]) = value;
+ return bytes;
}
-
+
// Converts a double into an array of bytes with length
// eight.
- public unsafe static byte[] GetBytes(double value)
+ public static byte[] GetBytes(double value)
{
Contract.Ensures(Contract.Result<byte[]>() != null);
- Contract.Ensures(Contract.Result<byte[]>().Length == 8);
+ Contract.Ensures(Contract.Result<byte[]>().Length == sizeof(double));
- return GetBytes(*(long*)&value);
+ byte[] bytes = new byte[sizeof(double)];
+ Unsafe.As<byte, double>(ref bytes[0]) = value;
+ return bytes;
}
// Converts an array of bytes into a char.
- public static char ToChar(byte[] value, int startIndex)
+ public static char ToChar(byte[] value, int startIndex) => unchecked((char)ReadInt16(value, startIndex));
+
+ private static short ReadInt16(byte[] value, int startIndex)
{
- if (value == null) {
+ if (value == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- if ((uint)startIndex >= value.Length) {
- ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
- }
-
- if (startIndex > value.Length - 2) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
- }
+ if (unchecked((uint)startIndex) >= unchecked((uint)value.Length))
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ if (startIndex > value.Length - sizeof(short))
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall, ExceptionArgument.value);
Contract.EndContractBlock();
- return (char)ToInt16(value, startIndex);
+ return Unsafe.ReadUnaligned<short>(ref value[startIndex]);
}
-
- // Converts an array of bytes into a short.
- public static unsafe short ToInt16(byte[] value, int startIndex) {
- if( value == null) {
+
+ private static int ReadInt32(byte[] value, int startIndex)
+ {
+ if (value == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- if ((uint) startIndex >= value.Length) {
- ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
- }
-
- if (startIndex > value.Length -2) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
- }
+ if (unchecked((uint)startIndex) >= unchecked((uint)value.Length))
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ if (startIndex > value.Length - sizeof(int))
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall, ExceptionArgument.value);
Contract.EndContractBlock();
- fixed( byte * pbyte = &value[startIndex]) {
- if( startIndex % 2 == 0) { // data is aligned
- return *((short *) pbyte);
- }
- else {
- if( IsLittleEndian) {
- return (short)((*pbyte) | (*(pbyte + 1) << 8)) ;
- }
- else {
- return (short)((*pbyte << 8) | (*(pbyte + 1)));
- }
- }
- }
-
+ return Unsafe.ReadUnaligned<int>(ref value[startIndex]);
}
-
- // Converts an array of bytes into an int.
- public static unsafe int ToInt32 (byte[] value, int startIndex) {
- if( value == null) {
+
+ private static long ReadInt64(byte[] value, int startIndex)
+ {
+ if (value == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- if ((uint) startIndex >= value.Length) {
- ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
- }
-
- if (startIndex > value.Length -4) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
- }
+ if (unchecked((uint)startIndex) >= unchecked((uint)value.Length))
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ if (startIndex > value.Length - sizeof(long))
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall, ExceptionArgument.value);
Contract.EndContractBlock();
- fixed( byte * pbyte = &value[startIndex]) {
- if( startIndex % 4 == 0) { // data is aligned
- return *((int *) pbyte);
- }
- else {
- if( IsLittleEndian) {
- return (*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24);
- }
- else {
- return (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3));
- }
- }
- }
+ return Unsafe.ReadUnaligned<long>(ref value[startIndex]);
}
-
+
+ // Converts an array of bytes into a short.
+ public static short ToInt16(byte[] value, int startIndex) => ReadInt16(value, startIndex);
+
+ // Converts an array of bytes into an int.
+ public static int ToInt32(byte[] value, int startIndex) => ReadInt32(value, startIndex);
+
// Converts an array of bytes into a long.
- public static unsafe long ToInt64 (byte[] value, int startIndex) {
- if (value == null) {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- }
-
- if ((uint) startIndex >= value.Length) {
- ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
- }
-
- if (startIndex > value.Length -8) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
- }
- Contract.EndContractBlock();
+ public static long ToInt64(byte[] value, int startIndex) => ReadInt64(value, startIndex);
- fixed( byte * pbyte = &value[startIndex]) {
- if( startIndex % 8 == 0) { // data is aligned
- return *((long *) pbyte);
- }
- else {
- if( IsLittleEndian) {
- int i1 = (*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24);
- int i2 = (*(pbyte+4)) | (*(pbyte + 5) << 8) | (*(pbyte + 6) << 16) | (*(pbyte + 7) << 24);
- return (uint)i1 | ((long)i2 << 32);
- }
- else {
- int i1 = (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3));
- int i2 = (*(pbyte+4) << 24) | (*(pbyte + 5) << 16) | (*(pbyte + 6) << 8) | (*(pbyte + 7));
- return (uint)i2 | ((long)i1 << 32);
- }
- }
- }
- }
-
-
// Converts an array of bytes into an ushort.
//
[CLSCompliant(false)]
- public static ushort ToUInt16(byte[] value, int startIndex)
- {
- if (value == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- if ((uint)startIndex >= value.Length)
- ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
- if (startIndex > value.Length - 2)
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
- Contract.EndContractBlock();
+ public static ushort ToUInt16(byte[] value, int startIndex) => unchecked((ushort)ReadInt16(value, startIndex));
- return (ushort)ToInt16(value, startIndex);
- }
-
// Converts an array of bytes into an uint.
//
[CLSCompliant(false)]
- public static uint ToUInt32(byte[] value, int startIndex)
- {
- if (value == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- if ((uint)startIndex >= value.Length)
- ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
- if (startIndex > value.Length - 4)
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
- Contract.EndContractBlock();
+ public static uint ToUInt32(byte[] value, int startIndex) => unchecked((uint)ReadInt32(value, startIndex));
- return (uint)ToInt32(value, startIndex);
- }
-
// Converts an array of bytes into an unsigned long.
//
[CLSCompliant(false)]
- public static ulong ToUInt64(byte[] value, int startIndex)
- {
- if (value == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- if ((uint)startIndex >= value.Length)
- ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
- if (startIndex > value.Length - 8)
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
- Contract.EndContractBlock();
+ public static ulong ToUInt64(byte[] value, int startIndex) => unchecked((ulong)ReadInt64(value, startIndex));
- return (ulong)ToInt64(value, startIndex);
- }
-
// Converts an array of bytes into a float.
- unsafe public static float ToSingle (byte[] value, int startIndex)
+ public static unsafe float ToSingle(byte[] value, int startIndex)
{
- if (value == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- if ((uint)startIndex >= value.Length)
- ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
- if (startIndex > value.Length - 4)
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
- Contract.EndContractBlock();
-
- int val = ToInt32(value, startIndex);
+ int val = ReadInt32(value, startIndex);
return *(float*)&val;
}
-
+
// Converts an array of bytes into a double.
- unsafe public static double ToDouble (byte[] value, int startIndex)
+ public static unsafe double ToDouble(byte[] value, int startIndex)
{
- if (value == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
- if ((uint)startIndex >= value.Length)
- ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
- if (startIndex > value.Length - 8)
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
- Contract.EndContractBlock();
-
- long val = ToInt64(value, startIndex);
+ long val = ReadInt64(value, startIndex);
return *(double*)&val;
}
-
- private static char GetHexValue(int i) {
- Debug.Assert( i >=0 && i <16, "i is out of range.");
- if (i<10) {
+
+ private static char GetHexValue(int i)
+ {
+ Debug.Assert(i >= 0 && i < 16, "i is out of range.");
+ if (i < 10)
+ {
return (char)(i + '0');
}
-
+
return (char)(i - 10 + 'A');
}
// Converts an array of bytes into a String.
- public static String ToString (byte[] value, int startIndex, int length) {
- if (value == null) {
- throw new ArgumentNullException(nameof(value));
- }
-
- if (startIndex < 0 || startIndex >= value.Length && startIndex > 0) { // Don't throw for a 0 length array.
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
- }
-
- if (length < 0) {
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
- }
-
- if (startIndex > value.Length - length) {
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall"));
- }
+ public static string ToString(byte[] value, int startIndex, int length)
+ {
+ if (value == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
+ if (startIndex < 0 || startIndex >= value.Length && startIndex > 0)
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);;
+ if (length < 0)
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_GenericPositive);
+ if (startIndex > value.Length - length)
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall, ExceptionArgument.value);
Contract.EndContractBlock();
- if (length == 0) {
+ if (length == 0)
+ {
return string.Empty;
}
- if (length > (Int32.MaxValue / 3)) {
+ if (length > (int.MaxValue / 3))
+ {
// (Int32.MaxValue / 3) == 715,827,882 Bytes == 699 MB
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_LengthTooLarge", (Int32.MaxValue / 3)));
+ throw new ArgumentOutOfRangeException(nameof(length), SR.Format(SR.ArgumentOutOfRange_LengthTooLarge, (int.MaxValue / 3)));
}
int chArrayLength = length * 3;
-
- char[] chArray = new char[chArrayLength];
- int i = 0;
- int index = startIndex;
- for (i = 0; i < chArrayLength; i += 3) {
- byte b = value[index++];
- chArray[i]= GetHexValue(b/16);
- chArray[i+1] = GetHexValue(b%16);
- chArray[i+2] = '-';
+ const int StackLimit = 512; // arbitrary limit to switch from stack to heap allocation
+ unsafe
+ {
+ if (chArrayLength < StackLimit)
+ {
+ char* chArrayPtr = stackalloc char[chArrayLength];
+ return ToString(value, startIndex, length, chArrayPtr, chArrayLength);
+ }
+ else
+ {
+ char[] chArray = new char[chArrayLength];
+ fixed (char* chArrayPtr = &chArray[0])
+ return ToString(value, startIndex, length, chArrayPtr, chArrayLength);
+ }
+ }
+ }
+
+ private static unsafe string ToString(byte[] value, int startIndex, int length, char* chArray, int chArrayLength)
+ {
+ Debug.Assert(length > 0);
+ Debug.Assert(chArrayLength == length * 3);
+
+ char* p = chArray;
+ int endIndex = startIndex + length;
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ byte b = value[i];
+ *p++ = GetHexValue(b >> 4);
+ *p++ = GetHexValue(b & 0xF);
+ *p++ = '-';
}
// We don't need the last '-' character
- return new String(chArray, 0, chArray.Length - 1);
+ return new string(chArray, 0, chArrayLength - 1);
}
-
+
// Converts an array of bytes into a String.
- public static String ToString(byte [] value) {
+ public static string ToString(byte[] value)
+ {
if (value == null)
- throw new ArgumentNullException(nameof(value));
- Contract.Ensures(Contract.Result<String>() != null);
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
+ Contract.Ensures(Contract.Result<string>() != null);
Contract.EndContractBlock();
return ToString(value, 0, value.Length);
}
-
+
// Converts an array of bytes into a String.
- public static String ToString (byte [] value, int startIndex) {
+ public static string ToString(byte[] value, int startIndex)
+ {
if (value == null)
- throw new ArgumentNullException(nameof(value));
- Contract.Ensures(Contract.Result<String>() != null);
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
+ Contract.Ensures(Contract.Result<string>() != null);
Contract.EndContractBlock();
return ToString(value, startIndex, value.Length - startIndex);
}
-
+
/*==================================ToBoolean===================================
**Action: Convert an array of bytes to a boolean value. We treat this array
** as if the first 4 bytes were an Int4 an operate on this value.
@@ -417,31 +326,36 @@ namespace System {
**Exceptions: See ToInt4.
==============================================================================*/
// Converts an array of bytes into a boolean.
- public static bool ToBoolean(byte[] value, int startIndex) {
- if (value==null)
- throw new ArgumentNullException(nameof(value));
+ public static bool ToBoolean(byte[] value, int startIndex)
+ {
+ if (value == null)
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
if (startIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);;
if (startIndex > value.Length - 1)
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);; // differs from other overloads, which throw base ArgumentException
Contract.EndContractBlock();
-
- return (value[startIndex]==0)?false:true;
+
+ return value[startIndex] != 0;
}
- public static unsafe long DoubleToInt64Bits(double value) {
- return *((long *)&value);
+ public static unsafe long DoubleToInt64Bits(double value)
+ {
+ return *((long*)&value);
}
- public static unsafe double Int64BitsToDouble(long value) {
+ public static unsafe double Int64BitsToDouble(long value)
+ {
return *((double*)&value);
}
- public static unsafe int SingleToInt32Bits(float value) {
+ public static unsafe int SingleToInt32Bits(float value)
+ {
return *((int*)&value);
}
- public static unsafe float Int32BitsToSingle(int value) {
+ public static unsafe float Int32BitsToSingle(int value)
+ {
return *((float*)&value);
}
}
diff --git a/src/mscorlib/src/System/Boolean.cs b/src/mscorlib/src/System/Boolean.cs
index c085b0a020..fe25e22920 100644
--- a/src/mscorlib/src/System/Boolean.cs
+++ b/src/mscorlib/src/System/Boolean.cs
@@ -11,105 +11,113 @@
**
**
===========================================================*/
-namespace System {
-
- using System;
- using System.Globalization;
- using System.Diagnostics.Contracts;
+
+using System;
+using System.Globalization;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
// The Boolean class provides the
// object representation of the boolean primitive type.
[Serializable]
- public struct Boolean : IComparable, IConvertible, IComparable<Boolean>, IEquatable<Boolean>
+ public struct Boolean : IComparable, IConvertible, IComparable<Boolean>, IEquatable<Boolean>
{
-
- //
- // Member Variables
- //
- private bool m_value;
-
- // The true value.
- //
- internal const int True = 1;
-
- // The false value.
- //
- internal const int False = 0;
-
-
- //
- // Internal Constants are real consts for performance.
- //
-
- // The internal string representation of true.
- //
- internal const String TrueLiteral = "True";
-
- // The internal string representation of false.
- //
- internal const String FalseLiteral = "False";
-
-
- //
- // Public Constants
- //
-
- // The public string representation of true.
- //
- public static readonly String TrueString = TrueLiteral;
-
- // The public string representation of false.
- //
- public static readonly String FalseString = FalseLiteral;
-
- //
- // Overriden Instance Methods
- //
- /*=================================GetHashCode==================================
- **Args: None
- **Returns: 1 or 0 depending on whether this instance represents true or false.
- **Exceptions: None
- **Overriden From: Value
- ==============================================================================*/
- // Provides a hash code for this instance.
- public override int GetHashCode() {
- return (m_value)?True:False;
- }
-
- /*===================================ToString===================================
- **Args: None
- **Returns: "True" or "False" depending on the state of the boolean.
- **Exceptions: None.
- ==============================================================================*/
- // Converts the boolean value of this instance to a String.
- public override String ToString() {
- if (false == m_value) {
- return FalseLiteral;
+ //
+ // Member Variables
+ //
+ private bool m_value;
+
+ // The true value.
+ //
+ internal const int True = 1;
+
+ // The false value.
+ //
+ internal const int False = 0;
+
+
+ //
+ // Internal Constants are real consts for performance.
+ //
+
+ // The internal string representation of true.
+ //
+ internal const String TrueLiteral = "True";
+
+ // The internal string representation of false.
+ //
+ internal const String FalseLiteral = "False";
+
+
+ //
+ // Public Constants
+ //
+
+ // The public string representation of true.
+ //
+ public static readonly String TrueString = TrueLiteral;
+
+ // The public string representation of false.
+ //
+ public static readonly String FalseString = FalseLiteral;
+
+ //
+ // Overriden Instance Methods
+ //
+ /*=================================GetHashCode==================================
+ **Args: None
+ **Returns: 1 or 0 depending on whether this instance represents true or false.
+ **Exceptions: None
+ **Overriden From: Value
+ ==============================================================================*/
+ // Provides a hash code for this instance.
+ public override int GetHashCode()
+ {
+ return (m_value) ? True : False;
}
- return TrueLiteral;
- }
- public String ToString(IFormatProvider provider) {
- if (false == m_value) {
- return FalseLiteral;
+ /*===================================ToString===================================
+ **Args: None
+ **Returns: "True" or "False" depending on the state of the boolean.
+ **Exceptions: None.
+ ==============================================================================*/
+ // Converts the boolean value of this instance to a String.
+ public override String ToString()
+ {
+ if (false == m_value)
+ {
+ return FalseLiteral;
+ }
+ return TrueLiteral;
}
- return TrueLiteral;
- }
-
- // Determines whether two Boolean objects are equal.
- public override bool Equals (Object obj) {
- //If it's not a boolean, we're definitely not equal
- if (!(obj is Boolean)) {
- return false;
+
+ public String ToString(IFormatProvider provider)
+ {
+ if (false == m_value)
+ {
+ return FalseLiteral;
+ }
+ return TrueLiteral;
}
-
- return (m_value==((Boolean)obj).m_value);
- }
- [System.Runtime.Versioning.NonVersionable]
- public bool Equals(Boolean obj)
- {
- return m_value == obj;
- }
+ // Determines whether two Boolean objects are equal.
+ public override bool Equals(Object obj)
+ {
+ //If it's not a boolean, we're definitely not equal
+ if (!(obj is Boolean))
+ {
+ return false;
+ }
+
+ return (m_value == ((Boolean)obj).m_value);
+ }
+
+ [System.Runtime.Versioning.NonVersionable]
+ public bool Equals(Boolean obj)
+ {
+ return m_value == obj;
+ }
// Compares this object to another object, returning an integer that
// indicates the relationship. For booleans, false sorts before true.
@@ -118,63 +126,80 @@ namespace System {
//
// Returns a value less than zero if this object
//
- public int CompareTo(Object obj) {
- if (obj==null) {
+ public int CompareTo(Object obj)
+ {
+ if (obj == null)
+ {
return 1;
}
- if (!(obj is Boolean)) {
- throw new ArgumentException (Environment.GetResourceString("Arg_MustBeBoolean"));
+ if (!(obj is Boolean))
+ {
+ throw new ArgumentException(SR.Arg_MustBeBoolean);
}
-
- if (m_value==((Boolean)obj).m_value) {
+
+ if (m_value == ((Boolean)obj).m_value)
+ {
return 0;
- } else if (m_value==false) {
+ }
+ else if (m_value == false)
+ {
return -1;
}
return 1;
}
- public int CompareTo(Boolean value) {
- if (m_value==value) {
+ public int CompareTo(Boolean value)
+ {
+ if (m_value == value)
+ {
return 0;
- } else if (m_value==false) {
+ }
+ else if (m_value == false)
+ {
return -1;
}
- return 1;
+ return 1;
}
-
+
//
// Static Methods
//
-
+
// Determines whether a String represents true or false.
//
- public static Boolean Parse (String value) {
- if (value==null) throw new ArgumentNullException(nameof(value));
+ public static Boolean Parse(String value)
+ {
+ if (value == null) throw new ArgumentNullException(nameof(value));
Contract.EndContractBlock();
Boolean result = false;
- if (!TryParse(value, out result)) {
- throw new FormatException(Environment.GetResourceString("Format_BadBoolean"));
+ if (!TryParse(value, out result))
+ {
+ throw new FormatException(SR.Format_BadBoolean);
}
- else {
+ else
+ {
return result;
}
}
// Determines whether a String represents true or false.
//
- public static Boolean TryParse (String value, out Boolean result) {
+ public static Boolean TryParse(String value, out Boolean result)
+ {
result = false;
- if (value==null) {
+ if (value == null)
+ {
return false;
}
// For perf reasons, let's first see if they're equal, then do the
// trim to get rid of white space, and check again.
- if (TrueLiteral.Equals(value, StringComparison.OrdinalIgnoreCase)) {
+ if (TrueLiteral.Equals(value, StringComparison.OrdinalIgnoreCase))
+ {
result = true;
return true;
}
- if (FalseLiteral.Equals(value,StringComparison.OrdinalIgnoreCase)) {
+ if (FalseLiteral.Equals(value, StringComparison.OrdinalIgnoreCase))
+ {
result = false;
return true;
}
@@ -182,122 +207,130 @@ namespace System {
// Special case: Trim whitespace as well as null characters.
value = TrimWhiteSpaceAndNull(value);
- if (TrueLiteral.Equals(value, StringComparison.OrdinalIgnoreCase)) {
+ if (TrueLiteral.Equals(value, StringComparison.OrdinalIgnoreCase))
+ {
result = true;
return true;
}
-
- if (FalseLiteral.Equals(value,StringComparison.OrdinalIgnoreCase)) {
+
+ if (FalseLiteral.Equals(value, StringComparison.OrdinalIgnoreCase))
+ {
result = false;
return true;
}
-
+
return false;
}
- private static String TrimWhiteSpaceAndNull(String value) {
+ private static String TrimWhiteSpaceAndNull(String value)
+ {
int start = 0;
- int end = value.Length-1;
- char nullChar = (char) 0x0000;
+ int end = value.Length - 1;
+ char nullChar = (char)0x0000;
- while (start < value.Length) {
- if (!Char.IsWhiteSpace(value[start]) && value[start] != nullChar) {
+ while (start < value.Length)
+ {
+ if (!Char.IsWhiteSpace(value[start]) && value[start] != nullChar)
+ {
break;
}
start++;
}
- while (end >= start) {
- if (!Char.IsWhiteSpace(value[end]) && value[end] != nullChar) {
+ while (end >= start)
+ {
+ if (!Char.IsWhiteSpace(value[end]) && value[end] != nullChar)
+ {
break;
}
- end--;
+ end--;
}
return value.Substring(start, end - start + 1);
- }
+ }
//
// IConvertible implementation
//
-
- public TypeCode GetTypeCode() {
+
+ public TypeCode GetTypeCode()
+ {
return TypeCode.Boolean;
}
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
return m_value;
}
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Boolean", "Char"));
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Boolean", "Char"));
}
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
return Convert.ToSByte(m_value);
}
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
return Convert.ToByte(m_value);
}
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
return Convert.ToInt16(m_value);
}
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
return Convert.ToUInt16(m_value);
}
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
return Convert.ToInt32(m_value);
}
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
return Convert.ToUInt32(m_value);
}
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
return Convert.ToInt64(m_value);
}
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
return Convert.ToUInt64(m_value);
}
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
return Convert.ToSingle(m_value);
}
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
return Convert.ToDouble(m_value);
}
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider) {
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
return Convert.ToDecimal(m_value);
}
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Boolean", "DateTime"));
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Boolean", "DateTime"));
}
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
return Convert.DefaultToType((IConvertible)this, type, provider);
}
}
diff --git a/src/mscorlib/src/System/Buffer.cs b/src/mscorlib/src/System/Buffer.cs
index 662b240b34..92b938df8c 100644
--- a/src/mscorlib/src/System/Buffer.cs
+++ b/src/mscorlib/src/System/Buffer.cs
@@ -2,10 +2,14 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System {
-
+#if AMD64 || (BIT32 && !ARM)
+#define HAS_CUSTOM_BLOCKS
+#endif
+
+namespace System
+{
//Only contains static methods. Does not require serialization
-
+
using System;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
@@ -57,7 +61,7 @@ namespace System {
if (count == 0)
return -1;
else if (*pByte == value)
- return (int) (pByte - src);
+ return (int)(pByte - src);
count--;
pByte++;
@@ -87,7 +91,7 @@ namespace System {
if (t1 != 0)
{
// We've found a match for value, figure out which position it's in.
- int foundIndex = (int) (pByte - src);
+ int foundIndex = (int)(pByte - src);
if (pByte[0] == value)
return foundIndex;
else if (pByte[1] == value)
@@ -100,14 +104,13 @@ namespace System {
count -= 4;
pByte += 4;
-
}
// Catch any bytes that might be left at the tail of the buffer
while (count > 0)
{
if (*pByte == value)
- return (int) (pByte - src);
+ return (int)(pByte - src);
count--;
pByte++;
@@ -116,7 +119,7 @@ namespace System {
// If we don't have a match return -1;
return -1;
}
-
+
// Returns a bool to indicate if the array is of primitive data types
// or not.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -139,7 +142,7 @@ namespace System {
// Is it of primitive types?
if (!IsPrimitiveTypeArray(array))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBePrimArray"), nameof(array));
+ throw new ArgumentException(SR.Arg_MustBePrimArray, nameof(array));
// Is the index in valid range of the array?
if (index < 0 || index >= _ByteLength(array))
@@ -165,7 +168,7 @@ namespace System {
// Is it of primitive types?
if (!IsPrimitiveTypeArray(array))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBePrimArray"), nameof(array));
+ throw new ArgumentException(SR.Arg_MustBePrimArray, nameof(array));
// Is the index in valid range of the array?
if (index < 0 || index >= _ByteLength(array))
@@ -175,7 +178,7 @@ namespace System {
_SetByte(array, index, value);
}
-
+
// Gets a particular byte out of the array. The array must be an
// array of primitives.
//
@@ -193,38 +196,41 @@ namespace System {
// Is it of primitive types?
if (!IsPrimitiveTypeArray(array))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBePrimArray"), nameof(array));
+ throw new ArgumentException(SR.Arg_MustBePrimArray, nameof(array));
return _ByteLength(array);
}
internal unsafe static void ZeroMemory(byte* src, long len)
{
- while(len-- > 0)
+ while (len-- > 0)
*(src + len) = 0;
}
- internal unsafe static void Memcpy(byte[] dest, int destIndex, byte* src, int srcIndex, int len) {
- Debug.Assert( (srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
+ internal unsafe static void Memcpy(byte[] dest, int destIndex, byte* src, int srcIndex, int len)
+ {
+ Debug.Assert((srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
Debug.Assert(dest.Length - destIndex >= len, "not enough bytes in dest");
// If dest has 0 elements, the fixed statement will throw an
// IndexOutOfRangeException. Special-case 0-byte copies.
- if (len==0)
+ if (len == 0)
return;
- fixed(byte* pDest = dest) {
+ fixed (byte* pDest = dest)
+ {
Memcpy(pDest + destIndex, src + srcIndex, len);
}
}
internal unsafe static void Memcpy(byte* pDest, int destIndex, byte[] src, int srcIndex, int len)
{
- Debug.Assert( (srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
+ Debug.Assert((srcIndex >= 0) && (destIndex >= 0) && (len >= 0), "Index and length must be non-negative!");
Debug.Assert(src.Length - srcIndex >= len, "not enough bytes in src");
// If dest has 0 elements, the fixed statement will throw an
// IndexOutOfRangeException. Special-case 0-byte copies.
- if (len==0)
+ if (len == 0)
return;
- fixed(byte* pSrc = src) {
+ fixed (byte* pSrc = src)
+ {
Memcpy(pDest + destIndex, pSrc + srcIndex, len);
}
}
@@ -244,7 +250,8 @@ namespace System {
internal unsafe static extern void Memcpy(byte* dest, byte* src, int len);
#else // ARM
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
- internal unsafe static void Memcpy(byte* dest, byte* src, int len) {
+ internal unsafe static void Memcpy(byte* dest, byte* src, int len)
+ {
Debug.Assert(len >= 0, "Negative length in memcopy!");
Memmove(dest, src, (uint)len);
}
@@ -253,327 +260,175 @@ namespace System {
// This method has different signature for x64 and other platforms and is done for performance reasons.
internal unsafe static void Memmove(byte* dest, byte* src, nuint len)
{
- // P/Invoke into the native version when the buffers are overlapping and the copy needs to be performed backwards
- // This check can produce false positives for lengths greater than Int32.MaxInt. It is fine because we want to use PInvoke path for the large lengths anyway.
+#if AMD64 || (BIT32 && !ARM)
+ const nuint CopyThreshold = 2048;
+#else
+ const nuint CopyThreshold = 512;
+#endif // AMD64 || (BIT32 && !ARM)
- if ((nuint)dest - (nuint)src < len) goto PInvoke;
+ // P/Invoke into the native version when the buffers are overlapping.
- // This is portable version of memcpy. It mirrors what the hand optimized assembly versions of memcpy typically do.
- //
- // Ideally, we would just use the cpblk IL instruction here. Unfortunately, cpblk IL instruction is not as efficient as
- // possible yet and so we have this implementation here for now.
+ if (((nuint)dest - (nuint)src < len) || ((nuint)src - (nuint)dest < len)) goto PInvoke;
- // Note: It's important that this switch handles lengths at least up to 22.
- // See notes below near the main loop for why.
+ byte* srcEnd = src + len;
+ byte* destEnd = dest + len;
- // The switch will be very fast since it can be implemented using a jump
- // table in assembly. See http://stackoverflow.com/a/449297/4077294 for more info.
+ if (len <= 16) goto MCPY02;
+ if (len > 64) goto MCPY05;
- switch (len)
- {
- case 0:
- return;
- case 1:
- *dest = *src;
- return;
- case 2:
- *(short*)dest = *(short*)src;
- return;
- case 3:
- *(short*)dest = *(short*)src;
- *(dest + 2) = *(src + 2);
- return;
- case 4:
- *(int*)dest = *(int*)src;
- return;
- case 5:
- *(int*)dest = *(int*)src;
- *(dest + 4) = *(src + 4);
- return;
- case 6:
- *(int*)dest = *(int*)src;
- *(short*)(dest + 4) = *(short*)(src + 4);
- return;
- case 7:
- *(int*)dest = *(int*)src;
- *(short*)(dest + 4) = *(short*)(src + 4);
- *(dest + 6) = *(src + 6);
- return;
- case 8:
-#if BIT64
- *(long*)dest = *(long*)src;
-#else
- *(int*)dest = *(int*)src;
- *(int*)(dest + 4) = *(int*)(src + 4);
-#endif
- return;
- case 9:
-#if BIT64
- *(long*)dest = *(long*)src;
-#else
- *(int*)dest = *(int*)src;
- *(int*)(dest + 4) = *(int*)(src + 4);
-#endif
- *(dest + 8) = *(src + 8);
- return;
- case 10:
-#if BIT64
- *(long*)dest = *(long*)src;
-#else
- *(int*)dest = *(int*)src;
- *(int*)(dest + 4) = *(int*)(src + 4);
-#endif
- *(short*)(dest + 8) = *(short*)(src + 8);
- return;
- case 11:
-#if BIT64
- *(long*)dest = *(long*)src;
-#else
- *(int*)dest = *(int*)src;
- *(int*)(dest + 4) = *(int*)(src + 4);
-#endif
- *(short*)(dest + 8) = *(short*)(src + 8);
- *(dest + 10) = *(src + 10);
- return;
- case 12:
-#if BIT64
- *(long*)dest = *(long*)src;
-#else
- *(int*)dest = *(int*)src;
- *(int*)(dest + 4) = *(int*)(src + 4);
-#endif
- *(int*)(dest + 8) = *(int*)(src + 8);
- return;
- case 13:
-#if BIT64
- *(long*)dest = *(long*)src;
-#else
- *(int*)dest = *(int*)src;
- *(int*)(dest + 4) = *(int*)(src + 4);
-#endif
- *(int*)(dest + 8) = *(int*)(src + 8);
- *(dest + 12) = *(src + 12);
- return;
- case 14:
-#if BIT64
- *(long*)dest = *(long*)src;
-#else
- *(int*)dest = *(int*)src;
- *(int*)(dest + 4) = *(int*)(src + 4);
-#endif
- *(int*)(dest + 8) = *(int*)(src + 8);
- *(short*)(dest + 12) = *(short*)(src + 12);
- return;
- case 15:
-#if BIT64
- *(long*)dest = *(long*)src;
-#else
- *(int*)dest = *(int*)src;
- *(int*)(dest + 4) = *(int*)(src + 4);
-#endif
- *(int*)(dest + 8) = *(int*)(src + 8);
- *(short*)(dest + 12) = *(short*)(src + 12);
- *(dest + 14) = *(src + 14);
- return;
- case 16:
-#if BIT64
- *(long*)dest = *(long*)src;
- *(long*)(dest + 8) = *(long*)(src + 8);
-#else
- *(int*)dest = *(int*)src;
- *(int*)(dest + 4) = *(int*)(src + 4);
- *(int*)(dest + 8) = *(int*)(src + 8);
- *(int*)(dest + 12) = *(int*)(src + 12);
-#endif
- return;
- case 17:
-#if BIT64
- *(long*)dest = *(long*)src;
- *(long*)(dest + 8) = *(long*)(src + 8);
-#else
- *(int*)dest = *(int*)src;
- *(int*)(dest + 4) = *(int*)(src + 4);
- *(int*)(dest + 8) = *(int*)(src + 8);
- *(int*)(dest + 12) = *(int*)(src + 12);
-#endif
- *(dest + 16) = *(src + 16);
- return;
- case 18:
-#if BIT64
- *(long*)dest = *(long*)src;
- *(long*)(dest + 8) = *(long*)(src + 8);
+ MCPY00:
+ // Copy bytes which are multiples of 16 and leave the remainder for MCPY01 to handle.
+ Debug.Assert(len > 16 && len <= 64);
+#if HAS_CUSTOM_BLOCKS
+ *(Block16*)dest = *(Block16*)src; // [0,16]
+#elif BIT64
+ *(long*)dest = *(long*)src;
+ *(long*)(dest + 8) = *(long*)(src + 8); // [0,16]
#else
- *(int*)dest = *(int*)src;
- *(int*)(dest + 4) = *(int*)(src + 4);
- *(int*)(dest + 8) = *(int*)(src + 8);
- *(int*)(dest + 12) = *(int*)(src + 12);
+ *(int*)dest = *(int*)src;
+ *(int*)(dest + 4) = *(int*)(src + 4);
+ *(int*)(dest + 8) = *(int*)(src + 8);
+ *(int*)(dest + 12) = *(int*)(src + 12); // [0,16]
#endif
- *(short*)(dest + 16) = *(short*)(src + 16);
- return;
- case 19:
-#if BIT64
- *(long*)dest = *(long*)src;
- *(long*)(dest + 8) = *(long*)(src + 8);
+ if (len <= 32) goto MCPY01;
+#if HAS_CUSTOM_BLOCKS
+ *(Block16*)(dest + 16) = *(Block16*)(src + 16); // [0,32]
+#elif BIT64
+ *(long*)(dest + 16) = *(long*)(src + 16);
+ *(long*)(dest + 24) = *(long*)(src + 24); // [0,32]
#else
- *(int*)dest = *(int*)src;
- *(int*)(dest + 4) = *(int*)(src + 4);
- *(int*)(dest + 8) = *(int*)(src + 8);
- *(int*)(dest + 12) = *(int*)(src + 12);
+ *(int*)(dest + 16) = *(int*)(src + 16);
+ *(int*)(dest + 20) = *(int*)(src + 20);
+ *(int*)(dest + 24) = *(int*)(src + 24);
+ *(int*)(dest + 28) = *(int*)(src + 28); // [0,32]
#endif
- *(short*)(dest + 16) = *(short*)(src + 16);
- *(dest + 18) = *(src + 18);
- return;
- case 20:
-#if BIT64
- *(long*)dest = *(long*)src;
- *(long*)(dest + 8) = *(long*)(src + 8);
+ if (len <= 48) goto MCPY01;
+#if HAS_CUSTOM_BLOCKS
+ *(Block16*)(dest + 32) = *(Block16*)(src + 32); // [0,48]
+#elif BIT64
+ *(long*)(dest + 32) = *(long*)(src + 32);
+ *(long*)(dest + 40) = *(long*)(src + 40); // [0,48]
#else
- *(int*)dest = *(int*)src;
- *(int*)(dest + 4) = *(int*)(src + 4);
- *(int*)(dest + 8) = *(int*)(src + 8);
- *(int*)(dest + 12) = *(int*)(src + 12);
+ *(int*)(dest + 32) = *(int*)(src + 32);
+ *(int*)(dest + 36) = *(int*)(src + 36);
+ *(int*)(dest + 40) = *(int*)(src + 40);
+ *(int*)(dest + 44) = *(int*)(src + 44); // [0,48]
#endif
- *(int*)(dest + 16) = *(int*)(src + 16);
- return;
- case 21:
-#if BIT64
- *(long*)dest = *(long*)src;
- *(long*)(dest + 8) = *(long*)(src + 8);
+
+ MCPY01:
+ // Unconditionally copy the last 16 bytes using destEnd and srcEnd and return.
+ Debug.Assert(len > 16 && len <= 64);
+#if HAS_CUSTOM_BLOCKS
+ *(Block16*)(destEnd - 16) = *(Block16*)(srcEnd - 16);
+#elif BIT64
+ *(long*)(destEnd - 16) = *(long*)(srcEnd - 16);
+ *(long*)(destEnd - 8) = *(long*)(srcEnd - 8);
#else
- *(int*)dest = *(int*)src;
- *(int*)(dest + 4) = *(int*)(src + 4);
- *(int*)(dest + 8) = *(int*)(src + 8);
- *(int*)(dest + 12) = *(int*)(src + 12);
+ *(int*)(destEnd - 16) = *(int*)(srcEnd - 16);
+ *(int*)(destEnd - 12) = *(int*)(srcEnd - 12);
+ *(int*)(destEnd - 8) = *(int*)(srcEnd - 8);
+ *(int*)(destEnd - 4) = *(int*)(srcEnd - 4);
#endif
- *(int*)(dest + 16) = *(int*)(src + 16);
- *(dest + 20) = *(src + 20);
- return;
- case 22:
+ return;
+
+ MCPY02:
+ // Copy the first 8 bytes and then unconditionally copy the last 8 bytes and return.
+ if ((len & 24) == 0) goto MCPY03;
+ Debug.Assert(len >= 8 && len <= 16);
#if BIT64
- *(long*)dest = *(long*)src;
- *(long*)(dest + 8) = *(long*)(src + 8);
+ *(long*)dest = *(long*)src;
+ *(long*)(destEnd - 8) = *(long*)(srcEnd - 8);
#else
- *(int*)dest = *(int*)src;
- *(int*)(dest + 4) = *(int*)(src + 4);
- *(int*)(dest + 8) = *(int*)(src + 8);
- *(int*)(dest + 12) = *(int*)(src + 12);
+ *(int*)dest = *(int*)src;
+ *(int*)(dest + 4) = *(int*)(src + 4);
+ *(int*)(destEnd - 8) = *(int*)(srcEnd - 8);
+ *(int*)(destEnd - 4) = *(int*)(srcEnd - 4);
#endif
- *(int*)(dest + 16) = *(int*)(src + 16);
- *(short*)(dest + 20) = *(short*)(src + 20);
- return;
- }
-
- // P/Invoke into the native version for large lengths
- if (len >= 512) goto PInvoke;
-
- nuint i = 0; // byte offset at which we're copying
+ return;
- if (((int)dest & 3) != 0)
- {
- if (((int)dest & 1) != 0)
- {
- *(dest + i) = *(src + i);
- i += 1;
- if (((int)dest & 2) != 0)
- goto IntAligned;
- }
- *(short*)(dest + i) = *(short*)(src + i);
- i += 2;
- }
+ MCPY03:
+ // Copy the first 4 bytes and then unconditionally copy the last 4 bytes and return.
+ if ((len & 4) == 0) goto MCPY04;
+ Debug.Assert(len >= 4 && len < 8);
+ *(int*)dest = *(int*)src;
+ *(int*)(destEnd - 4) = *(int*)(srcEnd - 4);
+ return;
- IntAligned:
+ MCPY04:
+ // Copy the first byte. For pending bytes, do an unconditionally copy of the last 2 bytes and return.
+ Debug.Assert(len < 4);
+ if (len == 0) return;
+ *dest = *src;
+ if ((len & 2) == 0) return;
+ *(short*)(destEnd - 2) = *(short*)(srcEnd - 2);
+ return;
-#if BIT64
- // On 64-bit IntPtr.Size == 8, so we want to advance to the next 8-aligned address. If
- // (int)dest % 8 is 0, 5, 6, or 7, we will already have advanced by 0, 3, 2, or 1
- // bytes to the next aligned address (respectively), so do nothing. On the other hand,
- // if it is 1, 2, 3, or 4 we will want to copy-and-advance another 4 bytes until
- // we're aligned.
- // The thing 1, 2, 3, and 4 have in common that the others don't is that if you
- // subtract one from them, their 3rd lsb will not be set. Hence, the below check.
-
- if ((((int)dest - 1) & 4) == 0)
+ MCPY05:
+ // PInvoke to the native version when the copy length exceeds the threshold.
+ if (len > CopyThreshold)
{
- *(int*)(dest + i) = *(int*)(src + i);
- i += 4;
+ goto PInvoke;
}
-#endif // BIT64
-
- nuint end = len - 16;
- len -= i; // lower 4 bits of len represent how many bytes are left *after* the unrolled loop
-
- // We know due to the above switch-case that this loop will always run 1 iteration; max
- // bytes we copy before checking is 23 (7 to align the pointers, 16 for 1 iteration) so
- // the switch handles lengths 0-22.
- Debug.Assert(end >= 7 && i <= end);
-
- // This is separated out into a different variable, so the i + 16 addition can be
- // performed at the start of the pipeline and the loop condition does not have
- // a dependency on the writes.
- nuint counter;
-
- do
- {
- counter = i + 16;
- // This loop looks very costly since there appear to be a bunch of temporary values
- // being created with the adds, but the jit (for x86 anyways) will convert each of
- // these to use memory addressing operands.
-
- // So the only cost is a bit of code size, which is made up for by the fact that
- // we save on writes to dest/src.
-
-#if BIT64
- *(long*)(dest + i) = *(long*)(src + i);
- *(long*)(dest + i + 8) = *(long*)(src + i + 8);
+ // Copy 64-bytes at a time until the remainder is less than 64.
+ // If remainder is greater than 16 bytes, then jump to MCPY00. Otherwise, unconditionally copy the last 16 bytes and return.
+ Debug.Assert(len > 64 && len <= CopyThreshold);
+ nuint n = len >> 6;
+
+ MCPY06:
+#if HAS_CUSTOM_BLOCKS
+ *(Block64*)dest = *(Block64*)src;
+#elif BIT64
+ *(long*)dest = *(long*)src;
+ *(long*)(dest + 8) = *(long*)(src + 8);
+ *(long*)(dest + 16) = *(long*)(src + 16);
+ *(long*)(dest + 24) = *(long*)(src + 24);
+ *(long*)(dest + 32) = *(long*)(src + 32);
+ *(long*)(dest + 40) = *(long*)(src + 40);
+ *(long*)(dest + 48) = *(long*)(src + 48);
+ *(long*)(dest + 56) = *(long*)(src + 56);
#else
- *(int*)(dest + i) = *(int*)(src + i);
- *(int*)(dest + i + 4) = *(int*)(src + i + 4);
- *(int*)(dest + i + 8) = *(int*)(src + i + 8);
- *(int*)(dest + i + 12) = *(int*)(src + i + 12);
+ *(int*)dest = *(int*)src;
+ *(int*)(dest + 4) = *(int*)(src + 4);
+ *(int*)(dest + 8) = *(int*)(src + 8);
+ *(int*)(dest + 12) = *(int*)(src + 12);
+ *(int*)(dest + 16) = *(int*)(src + 16);
+ *(int*)(dest + 20) = *(int*)(src + 20);
+ *(int*)(dest + 24) = *(int*)(src + 24);
+ *(int*)(dest + 28) = *(int*)(src + 28);
+ *(int*)(dest + 32) = *(int*)(src + 32);
+ *(int*)(dest + 36) = *(int*)(src + 36);
+ *(int*)(dest + 40) = *(int*)(src + 40);
+ *(int*)(dest + 44) = *(int*)(src + 44);
+ *(int*)(dest + 48) = *(int*)(src + 48);
+ *(int*)(dest + 52) = *(int*)(src + 52);
+ *(int*)(dest + 56) = *(int*)(src + 56);
+ *(int*)(dest + 60) = *(int*)(src + 60);
#endif
-
- i = counter;
-
- // See notes above for why this wasn't used instead
- // i += 16;
- }
- while (counter <= end);
-
- if ((len & 8) != 0)
- {
-#if BIT64
- *(long*)(dest + i) = *(long*)(src + i);
+ dest += 64;
+ src += 64;
+ n--;
+ if (n != 0) goto MCPY06;
+
+ len %= 64;
+ if (len > 16) goto MCPY00;
+#if HAS_CUSTOM_BLOCKS
+ *(Block16*)(destEnd - 16) = *(Block16*)(srcEnd - 16);
+#elif BIT64
+ *(long*)(destEnd - 16) = *(long*)(srcEnd - 16);
+ *(long*)(destEnd - 8) = *(long*)(srcEnd - 8);
#else
- *(int*)(dest + i) = *(int*)(src + i);
- *(int*)(dest + i + 4) = *(int*)(src + i + 4);
+ *(int*)(destEnd - 16) = *(int*)(srcEnd - 16);
+ *(int*)(destEnd - 12) = *(int*)(srcEnd - 12);
+ *(int*)(destEnd - 8) = *(int*)(srcEnd - 8);
+ *(int*)(destEnd - 4) = *(int*)(srcEnd - 4);
#endif
- i += 8;
- }
- if ((len & 4) != 0)
- {
- *(int*)(dest + i) = *(int*)(src + i);
- i += 4;
- }
- if ((len & 2) != 0)
- {
- *(short*)(dest + i) = *(short*)(src + i);
- i += 2;
- }
- if ((len & 1) != 0)
- {
- *(dest + i) = *(src + i);
- // We're not using i after this, so not needed
- // i += 1;
- }
-
return;
PInvoke:
_Memmove(dest, src, len);
-
}
-
+
// Non-inlinable wrapper around the QCall that avoids poluting the fast path
// with P/Invoke prolog/epilog.
[MethodImplAttribute(MethodImplOptions.NoInlining)]
@@ -616,5 +471,13 @@ namespace System {
Memmove((byte*)destination, (byte*)source, checked((uint)sourceBytesToCopy));
#endif // BIT64
}
+
+#if HAS_CUSTOM_BLOCKS
+ [StructLayout(LayoutKind.Sequential, Size = 16)]
+ private struct Block16 { }
+
+ [StructLayout(LayoutKind.Sequential, Size = 64)]
+ private struct Block64 { }
+#endif // HAS_CUSTOM_BLOCKS
}
}
diff --git a/src/mscorlib/corefx/System/Buffers/ArrayPoolEventSource.cs b/src/mscorlib/src/System/Buffers/ArrayPoolEventSource.cs
index 9482744144..9482744144 100644
--- a/src/mscorlib/corefx/System/Buffers/ArrayPoolEventSource.cs
+++ b/src/mscorlib/src/System/Buffers/ArrayPoolEventSource.cs
diff --git a/src/mscorlib/src/System/Byte.cs b/src/mscorlib/src/System/Byte.cs
index 666fdda75b..27fdcd7a64 100644
--- a/src/mscorlib/src/System/Byte.cs
+++ b/src/mscorlib/src/System/Byte.cs
@@ -12,54 +12,61 @@
**
===========================================================*/
-namespace System {
-
- using System;
- using System.Globalization;
- using System.Runtime.InteropServices;
- using System.Diagnostics.Contracts;
+using System;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
// The Byte class extends the Value class and
// provides object representation of the byte primitive type.
//
-[Serializable]
-[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
+ [Serializable]
+ [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public struct Byte : IComparable, IFormattable, IConvertible
- , IComparable<Byte>, IEquatable<Byte>
+ , IComparable<Byte>, IEquatable<Byte>
{
private byte m_value;
-
+
// The maximum value that a Byte may represent: 255.
public const byte MaxValue = (byte)0xFF;
-
+
// The minimum value that a Byte may represent: 0.
public const byte MinValue = 0;
-
-
+
+
// Compares this object to another object, returning an integer that
// indicates the relationship.
// Returns a value less than zero if this object
// null is considered to be less than any instance.
// If object is not of type byte, this method throws an ArgumentException.
//
- public int CompareTo(Object value) {
- if (value == null) {
+ public int CompareTo(Object value)
+ {
+ if (value == null)
+ {
return 1;
}
- if (!(value is Byte)) {
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeByte"));
+ if (!(value is Byte))
+ {
+ throw new ArgumentException(SR.Arg_MustBeByte);
}
-
+
return m_value - (((Byte)value).m_value);
}
- public int CompareTo(Byte value) {
+ public int CompareTo(Byte value)
+ {
return m_value - value;
}
-
+
// Determines whether two Byte objects are equal.
- public override bool Equals(Object obj) {
- if (!(obj is Byte)) {
+ public override bool Equals(Object obj)
+ {
+ if (!(obj is Byte))
+ {
return false;
}
return m_value == ((Byte)obj).m_value;
@@ -72,176 +79,194 @@ namespace System {
}
// Gets a hash code for this instance.
- public override int GetHashCode() {
+ public override int GetHashCode()
+ {
return m_value;
}
-
+
[Pure]
- public static byte Parse(String s) {
+ public static byte Parse(String s)
+ {
return Parse(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
-
+
[Pure]
- public static byte Parse(String s, NumberStyles style) {
+ public static byte Parse(String s, NumberStyles style)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Parse(s, style, NumberFormatInfo.CurrentInfo);
}
[Pure]
- public static byte Parse(String s, IFormatProvider provider) {
+ public static byte Parse(String s, IFormatProvider provider)
+ {
return Parse(s, NumberStyles.Integer, NumberFormatInfo.GetInstance(provider));
}
-
+
// Parses an unsigned byte from a String in the given style. If
// a NumberFormatInfo isn't specified, the current culture's
// NumberFormatInfo is assumed.
[Pure]
- public static byte Parse(String s, NumberStyles style, IFormatProvider provider) {
+ public static byte Parse(String s, NumberStyles style, IFormatProvider provider)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Parse(s, style, NumberFormatInfo.GetInstance(provider));
}
-
- private static byte Parse(String s, NumberStyles style, NumberFormatInfo info) {
+
+ private static byte Parse(String s, NumberStyles style, NumberFormatInfo info)
+ {
int i = 0;
- try {
+ try
+ {
i = Number.ParseInt32(s, style, info);
}
- catch(OverflowException e) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Byte"), e);
+ catch (OverflowException e)
+ {
+ throw new OverflowException(SR.Overflow_Byte, e);
}
- if (i < MinValue || i > MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Byte"));
+ if (i < MinValue || i > MaxValue) throw new OverflowException(SR.Overflow_Byte);
return (byte)i;
}
- public static bool TryParse(String s, out Byte result) {
+ public static bool TryParse(String s, out Byte result)
+ {
return TryParse(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result);
}
- public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out Byte result) {
+ public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out Byte result)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return TryParse(s, style, NumberFormatInfo.GetInstance(provider), out result);
}
-
- private static bool TryParse(String s, NumberStyles style, NumberFormatInfo info, out Byte result) {
+
+ private static bool TryParse(String s, NumberStyles style, NumberFormatInfo info, out Byte result)
+ {
result = 0;
int i;
- if (!Number.TryParseInt32(s, style, info, out i)) {
+ if (!Number.TryParseInt32(s, style, info, out i))
+ {
return false;
}
- if (i < MinValue || i > MaxValue) {
+ if (i < MinValue || i > MaxValue)
+ {
return false;
}
- result = (byte) i;
+ result = (byte)i;
return true;
}
[Pure]
- public override String ToString() {
+ public override String ToString()
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, null, NumberFormatInfo.CurrentInfo);
}
[Pure]
- public String ToString(String format) {
+ public String ToString(String format)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, format, NumberFormatInfo.CurrentInfo);
}
[Pure]
- public String ToString(IFormatProvider provider) {
+ public String ToString(IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, null, NumberFormatInfo.GetInstance(provider));
}
[Pure]
- public String ToString(String format, IFormatProvider provider) {
+ public String ToString(String format, IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, format, NumberFormatInfo.GetInstance(provider));
}
-
+
//
// IConvertible implementation
//
[Pure]
- public TypeCode GetTypeCode() {
+ public TypeCode GetTypeCode()
+ {
return TypeCode.Byte;
}
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
return Convert.ToBoolean(m_value);
}
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
return Convert.ToChar(m_value);
}
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
return Convert.ToSByte(m_value);
}
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
return m_value;
}
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
return Convert.ToInt16(m_value);
}
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
return Convert.ToUInt16(m_value);
}
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
return Convert.ToInt32(m_value);
}
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
return Convert.ToUInt32(m_value);
}
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
return Convert.ToInt64(m_value);
}
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
return Convert.ToUInt64(m_value);
}
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
return Convert.ToSingle(m_value);
}
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
return Convert.ToDouble(m_value);
}
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider) {
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
return Convert.ToDecimal(m_value);
}
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Byte", "DateTime"));
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Byte", "DateTime"));
}
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
return Convert.DefaultToType((IConvertible)this, type, provider);
}
}
diff --git a/src/mscorlib/src/System/CLRConfig.cs b/src/mscorlib/src/System/CLRConfig.cs
index 16c610b82b..d97922f9b9 100644
--- a/src/mscorlib/src/System/CLRConfig.cs
+++ b/src/mscorlib/src/System/CLRConfig.cs
@@ -7,8 +7,23 @@ using System.Runtime.Versioning;
using System.Runtime.InteropServices;
using System.Security;
-namespace System {
+namespace System
+{
+ // CLRConfig is mainly reading the config switch values. this is used when we cannot use the AppContext class
+ // one example, is using the context switch in the globalization code which require to read the switch very
+ // early even before the appdomain get initialized.
+ // In general AppContext should be used instead of CLRConfig if there is no reason prevent that.
+ internal class CLRConfig
+ {
+ internal static bool GetBoolValue(string switchName)
+ {
+ return GetConfigBoolValue(switchName);
+ }
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private extern static bool GetConfigBoolValue(string configSwitchName);
+ }
} // namespace System
// file CLRConfig
diff --git a/src/mscorlib/src/System/Char.cs b/src/mscorlib/src/System/Char.cs
deleted file mode 100644
index 7fe1c08715..0000000000
--- a/src/mscorlib/src/System/Char.cs
+++ /dev/null
@@ -1,1000 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose: This is the value class representing a Unicode character
-** Char methods until we create this functionality.
-**
-**
-===========================================================*/
-namespace System {
-
- using System;
- using System.Globalization;
- using System.Runtime;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
-[Serializable]
-[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)] public struct Char : IComparable, IConvertible
- , IComparable<Char>, IEquatable<Char>
- {
- //
- // Member Variables
- //
- internal char m_value;
-
- //
- // Public Constants
- //
- // The maximum character value.
- public const char MaxValue = (char) 0xFFFF;
- // The minimum character value.
- public const char MinValue = (char) 0x00;
-
- // Unicode category values from Unicode U+0000 ~ U+00FF. Store them in byte[] array to save space.
- private readonly static byte[] categoryForLatin1 = {
- (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0000 - 0007
- (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0008 - 000F
- (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0010 - 0017
- (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0018 - 001F
- (byte)UnicodeCategory.SpaceSeparator, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.CurrencySymbol, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.OtherPunctuation, // 0020 - 0027
- (byte)UnicodeCategory.OpenPunctuation, (byte)UnicodeCategory.ClosePunctuation, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.DashPunctuation, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.OtherPunctuation, // 0028 - 002F
- (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, // 0030 - 0037
- (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.DecimalDigitNumber, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.OtherPunctuation, // 0038 - 003F
- (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, // 0040 - 0047
- (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, // 0048 - 004F
- (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, // 0050 - 0057
- (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.OpenPunctuation, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.ClosePunctuation, (byte)UnicodeCategory.ModifierSymbol, (byte)UnicodeCategory.ConnectorPunctuation, // 0058 - 005F
- (byte)UnicodeCategory.ModifierSymbol, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, // 0060 - 0067
- (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, // 0068 - 006F
- (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, // 0070 - 0077
- (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.OpenPunctuation, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.ClosePunctuation, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.Control, // 0078 - 007F
- (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0080 - 0087
- (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0088 - 008F
- (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0090 - 0097
- (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, (byte)UnicodeCategory.Control, // 0098 - 009F
- (byte)UnicodeCategory.SpaceSeparator, (byte)UnicodeCategory.OtherPunctuation, (byte)UnicodeCategory.CurrencySymbol, (byte)UnicodeCategory.CurrencySymbol, (byte)UnicodeCategory.CurrencySymbol, (byte)UnicodeCategory.CurrencySymbol, (byte)UnicodeCategory.OtherSymbol, (byte)UnicodeCategory.OtherSymbol, // 00A0 - 00A7
- (byte)UnicodeCategory.ModifierSymbol, (byte)UnicodeCategory.OtherSymbol, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.InitialQuotePunctuation, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.DashPunctuation, (byte)UnicodeCategory.OtherSymbol, (byte)UnicodeCategory.ModifierSymbol, // 00A8 - 00AF
- (byte)UnicodeCategory.OtherSymbol, (byte)UnicodeCategory.MathSymbol, (byte)UnicodeCategory.OtherNumber, (byte)UnicodeCategory.OtherNumber, (byte)UnicodeCategory.ModifierSymbol, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.OtherSymbol, (byte)UnicodeCategory.OtherPunctuation, // 00B0 - 00B7
- (byte)UnicodeCategory.ModifierSymbol, (byte)UnicodeCategory.OtherNumber, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.FinalQuotePunctuation, (byte)UnicodeCategory.OtherNumber, (byte)UnicodeCategory.OtherNumber, (byte)UnicodeCategory.OtherNumber, (byte)UnicodeCategory.OtherPunctuation, // 00B8 - 00BF
- (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, // 00C0 - 00C7
- (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, // 00C8 - 00CF
- (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.MathSymbol, // 00D0 - 00D7
- (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.UppercaseLetter, (byte)UnicodeCategory.LowercaseLetter, // 00D8 - 00DF
- (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, // 00E0 - 00E7
- (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, // 00E8 - 00EF
- (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.MathSymbol, // 00F0 - 00F7
- (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, (byte)UnicodeCategory.LowercaseLetter, // 00F8 - 00FF
- };
-
- // Return true for all characters below or equal U+00ff, which is ASCII + Latin-1 Supplement.
- private static bool IsLatin1(char ch) {
- return (ch <= '\x00ff');
- }
-
- // Return true for all characters below or equal U+007f, which is ASCII.
- private static bool IsAscii(char ch) {
- return (ch <= '\x007f');
- }
-
- // Return the Unicode category for Unicode character <= 0x00ff.
- private static UnicodeCategory GetLatin1UnicodeCategory(char ch) {
- Debug.Assert(IsLatin1(ch), "Char.GetLatin1UnicodeCategory(): ch should be <= 007f");
- return (UnicodeCategory)(categoryForLatin1[(int)ch]);
- }
-
- //
- // Private Constants
- //
-
- //
- // Overriden Instance Methods
- //
-
- // Calculate a hashcode for a 2 byte Unicode character.
- public override int GetHashCode() {
- return (int)m_value | ((int)m_value << 16);
- }
-
- // Used for comparing two boxed Char objects.
- //
- public override bool Equals(Object obj) {
- if (!(obj is Char)) {
- return false;
- }
- return (m_value==((Char)obj).m_value);
- }
-
- [System.Runtime.Versioning.NonVersionable]
- public bool Equals(Char obj)
- {
- return m_value == obj;
- }
-
- // Compares this object to another object, returning an integer that
- // indicates the relationship.
- // Returns a value less than zero if this object
- // null is considered to be less than any instance.
- // If object is not of type Char, this method throws an ArgumentException.
- //
- [Pure]
- public int CompareTo(Object value) {
- if (value==null) {
- return 1;
- }
- if (!(value is Char)) {
- throw new ArgumentException (Environment.GetResourceString("Arg_MustBeChar"));
- }
-
- return (m_value-((Char)value).m_value);
- }
-
- [Pure]
- public int CompareTo(Char value) {
- return (m_value-value);
- }
-
- // Overrides System.Object.ToString.
- [Pure]
- public override String ToString() {
- Contract.Ensures(Contract.Result<String>() != null);
- return Char.ToString(m_value);
- }
-
- [Pure]
- public String ToString(IFormatProvider provider) {
- Contract.Ensures(Contract.Result<String>() != null);
- return Char.ToString(m_value);
- }
-
- //
- // Formatting Methods
- //
-
- /*===================================ToString===================================
- **This static methods takes a character and returns the String representation of it.
- ==============================================================================*/
- // Provides a string representation of a character.
- [Pure]
- public static string ToString(char c) => string.CreateFromChar(c);
-
- public static char Parse(String s) {
- if (s==null) {
- throw new ArgumentNullException(nameof(s));
- }
- Contract.EndContractBlock();
-
- if (s.Length!=1) {
- throw new FormatException(Environment.GetResourceString("Format_NeedSingleChar"));
- }
- return s[0];
- }
-
- public static bool TryParse(String s, out Char result) {
- result = '\0';
- if (s == null) {
- return false;
- }
- if (s.Length != 1) {
- return false;
- }
- result = s[0];
- return true;
- }
-
- //
- // Static Methods
- //
- /*=================================ISDIGIT======================================
- **A wrapper for Char. Returns a boolean indicating whether **
- **character c is considered to be a digit. **
- ==============================================================================*/
- // Determines whether a character is a digit.
- [Pure]
- public static bool IsDigit(char c) {
- if (IsLatin1(c)) {
- return (c >= '0' && c <= '9');
- }
- return (CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber);
- }
-
-
- /*=================================CheckLetter=====================================
- ** Check if the specified UnicodeCategory belongs to the letter categories.
- ==============================================================================*/
- internal static bool CheckLetter(UnicodeCategory uc) {
- switch(uc) {
- case (UnicodeCategory.UppercaseLetter):
- case (UnicodeCategory.LowercaseLetter):
- case (UnicodeCategory.TitlecaseLetter):
- case (UnicodeCategory.ModifierLetter):
- case (UnicodeCategory.OtherLetter):
- return (true);
- }
- return (false);
- }
-
- /*=================================ISLETTER=====================================
- **A wrapper for Char. Returns a boolean indicating whether **
- **character c is considered to be a letter. **
- ==============================================================================*/
- // Determines whether a character is a letter.
- [Pure]
- public static bool IsLetter(char c) {
- if (IsLatin1(c)) {
- if (IsAscii(c)) {
- c |=(char)0x20;
- return ((c >= 'a' && c <= 'z'));
- }
- return (CheckLetter(GetLatin1UnicodeCategory(c)));
- }
- return (CheckLetter(CharUnicodeInfo.GetUnicodeCategory(c)));
- }
-
- private static bool IsWhiteSpaceLatin1(char c) {
-
- // There are characters which belong to UnicodeCategory.Control but are considered as white spaces.
- // We use code point comparisons for these characters here as a temporary fix.
-
- // U+0009 = <control> HORIZONTAL TAB
- // U+000a = <control> LINE FEED
- // U+000b = <control> VERTICAL TAB
- // U+000c = <contorl> FORM FEED
- // U+000d = <control> CARRIAGE RETURN
- // U+0085 = <control> NEXT LINE
- // U+00a0 = NO-BREAK SPACE
- if ((c == ' ') || (c >= '\x0009' && c <= '\x000d') || c == '\x00a0' || c == '\x0085') {
- return (true);
- }
- return (false);
- }
-
- /*===============================ISWHITESPACE===================================
- **A wrapper for Char. Returns a boolean indicating whether **
- **character c is considered to be a whitespace character. **
- ==============================================================================*/
- // Determines whether a character is whitespace.
- [Pure]
- public static bool IsWhiteSpace(char c) {
-
- if (IsLatin1(c)) {
- return (IsWhiteSpaceLatin1(c));
- }
- return CharUnicodeInfo.IsWhiteSpace(c);
- }
-
-
- /*===================================IsUpper====================================
- **Arguments: c -- the characater to be checked.
- **Returns: True if c is an uppercase character.
- ==============================================================================*/
- // Determines whether a character is upper-case.
- [Pure]
- public static bool IsUpper(char c) {
- if (IsLatin1(c)) {
- if (IsAscii(c)) {
- return (c >= 'A' && c <= 'Z');
- }
- return (GetLatin1UnicodeCategory(c)== UnicodeCategory.UppercaseLetter);
- }
- return (CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.UppercaseLetter);
- }
-
- /*===================================IsLower====================================
- **Arguments: c -- the characater to be checked.
- **Returns: True if c is an lowercase character.
- ==============================================================================*/
- // Determines whether a character is lower-case.
- [Pure]
- public static bool IsLower(char c) {
- if (IsLatin1(c)) {
- if (IsAscii(c)) {
- return (c >= 'a' && c <= 'z');
- }
- return (GetLatin1UnicodeCategory(c)== UnicodeCategory.LowercaseLetter);
- }
- return (CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.LowercaseLetter);
- }
-
- internal static bool CheckPunctuation(UnicodeCategory uc)
- {
- switch (uc) {
- case UnicodeCategory.ConnectorPunctuation:
- case UnicodeCategory.DashPunctuation:
- case UnicodeCategory.OpenPunctuation:
- case UnicodeCategory.ClosePunctuation:
- case UnicodeCategory.InitialQuotePunctuation:
- case UnicodeCategory.FinalQuotePunctuation:
- case UnicodeCategory.OtherPunctuation:
- return (true);
- }
- return (false);
- }
-
-
- /*================================IsPunctuation=================================
- **Arguments: c -- the characater to be checked.
- **Returns: True if c is an punctuation mark
- ==============================================================================*/
- // Determines whether a character is a punctuation mark.
- [Pure]
- public static bool IsPunctuation(char c){
- if (IsLatin1(c)) {
- return (CheckPunctuation(GetLatin1UnicodeCategory(c)));
- }
- return (CheckPunctuation(CharUnicodeInfo.GetUnicodeCategory(c)));
- }
-
- /*=================================CheckLetterOrDigit=====================================
- ** Check if the specified UnicodeCategory belongs to the letter or digit categories.
- ==============================================================================*/
- internal static bool CheckLetterOrDigit(UnicodeCategory uc) {
- switch (uc) {
- case UnicodeCategory.UppercaseLetter:
- case UnicodeCategory.LowercaseLetter:
- case UnicodeCategory.TitlecaseLetter:
- case UnicodeCategory.ModifierLetter:
- case UnicodeCategory.OtherLetter:
- case UnicodeCategory.DecimalDigitNumber:
- return (true);
- }
- return (false);
- }
-
- // Determines whether a character is a letter or a digit.
- [Pure]
- public static bool IsLetterOrDigit(char c) {
- if (IsLatin1(c)) {
- return (CheckLetterOrDigit(GetLatin1UnicodeCategory(c)));
- }
- return (CheckLetterOrDigit(CharUnicodeInfo.GetUnicodeCategory(c)));
- }
-
- /*===================================ToUpper====================================
- **
- ==============================================================================*/
- // Converts a character to upper-case for the specified culture.
- // <;<;Not fully implemented>;>;
- public static char ToUpper(char c, CultureInfo culture) {
- if (culture==null)
- throw new ArgumentNullException(nameof(culture));
- Contract.EndContractBlock();
- return culture.TextInfo.ToUpper(c);
- }
-
- /*=================================TOUPPER======================================
- **A wrapper for Char.toUpperCase. Converts character c to its **
- **uppercase equivalent. If c is already an uppercase character or is not an **
- **alphabetic, nothing happens. **
- ==============================================================================*/
- // Converts a character to upper-case for the default culture.
- //
- public static char ToUpper(char c) {
- return ToUpper(c, CultureInfo.CurrentCulture);
- }
-
-
- // Converts a character to upper-case for invariant culture.
- public static char ToUpperInvariant(char c) {
- return ToUpper(c, CultureInfo.InvariantCulture);
- }
-
- /*===================================ToLower====================================
- **
- ==============================================================================*/
- // Converts a character to lower-case for the specified culture.
- // <;<;Not fully implemented>;>;
- public static char ToLower(char c, CultureInfo culture) {
- if (culture==null)
- throw new ArgumentNullException(nameof(culture));
- Contract.EndContractBlock();
- return culture.TextInfo.ToLower(c);
- }
-
- /*=================================TOLOWER======================================
- **A wrapper for Char.toLowerCase. Converts character c to its **
- **lowercase equivalent. If c is already a lowercase character or is not an **
- **alphabetic, nothing happens. **
- ==============================================================================*/
- // Converts a character to lower-case for the default culture.
- public static char ToLower(char c) {
- return ToLower(c, CultureInfo.CurrentCulture);
- }
-
-
- // Converts a character to lower-case for invariant culture.
- public static char ToLowerInvariant(char c) {
- return ToLower(c, CultureInfo.InvariantCulture);
- }
-
- //
- // IConvertible implementation
- //
- [Pure]
- public TypeCode GetTypeCode() {
- return TypeCode.Char;
- }
-
-
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Char", "Boolean"));
- }
-
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
- return m_value;
- }
-
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
- return Convert.ToSByte(m_value);
- }
-
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
- return Convert.ToByte(m_value);
- }
-
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
- return Convert.ToInt16(m_value);
- }
-
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
- return Convert.ToUInt16(m_value);
- }
-
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
- return Convert.ToInt32(m_value);
- }
-
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
- return Convert.ToUInt32(m_value);
- }
-
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
- return Convert.ToInt64(m_value);
- }
-
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
- return Convert.ToUInt64(m_value);
- }
-
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Char", "Single"));
- }
-
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Char", "Double"));
- }
-
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Char", "Decimal"));
- }
-
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Char", "DateTime"));
- }
-
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
- return Convert.DefaultToType((IConvertible)this, type, provider);
- }
-
- public static bool IsControl(char c)
- {
- if (IsLatin1(c)) {
- return (GetLatin1UnicodeCategory(c) == UnicodeCategory.Control);
- }
- return (CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.Control);
- }
-
- public static bool IsControl(String s, int index) {
- if (s==null)
- throw new ArgumentNullException(nameof(s));
- if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- char c = s[index];
- if (IsLatin1(c)) {
- return (GetLatin1UnicodeCategory(c) == UnicodeCategory.Control);
- }
- return (CharUnicodeInfo.GetUnicodeCategory(s, index) == UnicodeCategory.Control);
- }
-
-
- public static bool IsDigit(String s, int index)
- {
- if (s==null)
- throw new ArgumentNullException(nameof(s));
- if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- char c = s[index];
- if (IsLatin1(c)) {
- return (c >= '0' && c <= '9');
- }
- return (CharUnicodeInfo.GetUnicodeCategory(s, index) == UnicodeCategory.DecimalDigitNumber);
- }
-
- public static bool IsLetter(String s, int index)
- {
- if (s==null)
- throw new ArgumentNullException(nameof(s));
- if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- char c = s[index];
- if (IsLatin1(c)) {
- if (IsAscii(c)) {
- c |=(char)0x20;
- return ((c >= 'a' && c <= 'z'));
- }
- return (CheckLetter(GetLatin1UnicodeCategory(c)));
- }
- return (CheckLetter(CharUnicodeInfo.GetUnicodeCategory(s, index)));
- }
-
- public static bool IsLetterOrDigit(String s, int index)
- {
- if (s==null)
- throw new ArgumentNullException(nameof(s));
- if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- char c = s[index];
- if (IsLatin1(c)) {
- return CheckLetterOrDigit(GetLatin1UnicodeCategory(c));
- }
- return CheckLetterOrDigit(CharUnicodeInfo.GetUnicodeCategory(s, index));
- }
-
- public static bool IsLower(String s, int index)
- {
- if (s==null)
- throw new ArgumentNullException(nameof(s));
- if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- char c = s[index];
- if (IsLatin1(c)) {
- if (IsAscii(c)) {
- return (c >= 'a' && c <= 'z');
- }
- return (GetLatin1UnicodeCategory(c)== UnicodeCategory.LowercaseLetter);
- }
-
- return (CharUnicodeInfo.GetUnicodeCategory(s, index) == UnicodeCategory.LowercaseLetter);
- }
-
- /*=================================CheckNumber=====================================
- ** Check if the specified UnicodeCategory belongs to the number categories.
- ==============================================================================*/
-
- internal static bool CheckNumber(UnicodeCategory uc) {
- switch (uc) {
- case (UnicodeCategory.DecimalDigitNumber):
- case (UnicodeCategory.LetterNumber):
- case (UnicodeCategory.OtherNumber):
- return (true);
- }
- return (false);
- }
-
- public static bool IsNumber(char c)
- {
- if (IsLatin1(c)) {
- if (IsAscii(c)) {
- return (c >= '0' && c <= '9');
- }
- return (CheckNumber(GetLatin1UnicodeCategory(c)));
- }
- return (CheckNumber(CharUnicodeInfo.GetUnicodeCategory(c)));
- }
-
- public static bool IsNumber(String s, int index)
- {
- if (s==null)
- throw new ArgumentNullException(nameof(s));
- if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- char c = s[index];
- if (IsLatin1(c)) {
- if (IsAscii(c)) {
- return (c >= '0' && c <= '9');
- }
- return (CheckNumber(GetLatin1UnicodeCategory(c)));
- }
- return (CheckNumber(CharUnicodeInfo.GetUnicodeCategory(s, index)));
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // IsPunctuation
- //
- // Determines if the given character is a punctuation character.
- //
- ////////////////////////////////////////////////////////////////////////
-
- public static bool IsPunctuation (String s, int index)
- {
- if (s==null)
- throw new ArgumentNullException(nameof(s));
- if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- char c = s[index];
- if (IsLatin1(c)) {
- return (CheckPunctuation(GetLatin1UnicodeCategory(c)));
- }
- return (CheckPunctuation(CharUnicodeInfo.GetUnicodeCategory(s, index)));
- }
-
-
- /*================================= CheckSeparator ============================
- ** Check if the specified UnicodeCategory belongs to the seprator categories.
- ==============================================================================*/
-
- internal static bool CheckSeparator(UnicodeCategory uc)
- {
- switch (uc) {
- case UnicodeCategory.SpaceSeparator:
- case UnicodeCategory.LineSeparator:
- case UnicodeCategory.ParagraphSeparator:
- return (true);
- }
- return (false);
- }
-
- private static bool IsSeparatorLatin1(char c) {
- // U+00a0 = NO-BREAK SPACE
- // There is no LineSeparator or ParagraphSeparator in Latin 1 range.
- return (c == '\x0020' || c == '\x00a0');
- }
-
- public static bool IsSeparator(char c)
- {
- if (IsLatin1(c)) {
- return (IsSeparatorLatin1(c));
- }
- return (CheckSeparator(CharUnicodeInfo.GetUnicodeCategory(c)));
- }
-
- public static bool IsSeparator(String s, int index)
- {
- if (s==null)
- throw new ArgumentNullException(nameof(s));
- if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- char c = s[index];
- if (IsLatin1(c)) {
- return (IsSeparatorLatin1(c));
- }
- return (CheckSeparator(CharUnicodeInfo.GetUnicodeCategory(s, index)));
- }
-
- [Pure]
- public static bool IsSurrogate(char c)
- {
- return (c >= HIGH_SURROGATE_START && c <= LOW_SURROGATE_END);
- }
-
- [Pure]
- public static bool IsSurrogate(String s, int index)
- {
- if (s==null) {
- throw new ArgumentNullException(nameof(s));
- }
- if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- return (IsSurrogate(s[index]));
- }
-
- /*================================= CheckSymbol ============================
- ** Check if the specified UnicodeCategory belongs to the symbol categories.
- ==============================================================================*/
-
- internal static bool CheckSymbol(UnicodeCategory uc) {
- switch (uc) {
- case (UnicodeCategory.MathSymbol):
- case (UnicodeCategory.CurrencySymbol):
- case (UnicodeCategory.ModifierSymbol):
- case (UnicodeCategory.OtherSymbol):
- return (true);
- }
- return (false);
- }
-
- public static bool IsSymbol(char c)
- {
- if (IsLatin1(c)) {
- return (CheckSymbol(GetLatin1UnicodeCategory(c)));
- }
- return (CheckSymbol(CharUnicodeInfo.GetUnicodeCategory(c)));
- }
-
- public static bool IsSymbol(String s, int index)
- {
- if (s==null)
- throw new ArgumentNullException(nameof(s));
- if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- if (IsLatin1(s[index])) {
- return (CheckSymbol(GetLatin1UnicodeCategory(s[index])));
- }
- return (CheckSymbol(CharUnicodeInfo.GetUnicodeCategory(s, index)));
- }
-
-
- public static bool IsUpper(String s, int index)
- {
- if (s==null)
- throw new ArgumentNullException(nameof(s));
- if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- char c = s[index];
- if (IsLatin1(c)) {
- if (IsAscii(c)) {
- return (c >= 'A' && c <= 'Z');
- }
- return (GetLatin1UnicodeCategory(c)== UnicodeCategory.UppercaseLetter);
- }
-
- return (CharUnicodeInfo.GetUnicodeCategory(s, index) == UnicodeCategory.UppercaseLetter);
- }
-
- public static bool IsWhiteSpace(String s, int index)
- {
- if (s==null)
- throw new ArgumentNullException(nameof(s));
- if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
-
- if (IsLatin1(s[index])) {
- return IsWhiteSpaceLatin1(s[index]);
- }
-
- return CharUnicodeInfo.IsWhiteSpace(s, index);
- }
-
- public static UnicodeCategory GetUnicodeCategory(char c)
- {
- if (IsLatin1(c)) {
- return (GetLatin1UnicodeCategory(c));
- }
- return CharUnicodeInfo.InternalGetUnicodeCategory(c);
- }
-
- public static UnicodeCategory GetUnicodeCategory(String s, int index)
- {
- if (s==null)
- throw new ArgumentNullException(nameof(s));
- if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- if (IsLatin1(s[index])) {
- return (GetLatin1UnicodeCategory(s[index]));
- }
- return CharUnicodeInfo.InternalGetUnicodeCategory(s, index);
- }
-
- public static double GetNumericValue(char c)
- {
- return CharUnicodeInfo.GetNumericValue(c);
- }
-
- public static double GetNumericValue(String s, int index)
- {
- if (s==null)
- throw new ArgumentNullException(nameof(s));
- if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- return CharUnicodeInfo.GetNumericValue(s, index);
- }
-
-
- /*================================= IsHighSurrogate ============================
- ** Check if a char is a high surrogate.
- ==============================================================================*/
- [Pure]
- public static bool IsHighSurrogate(char c) {
- return ((c >= CharUnicodeInfo.HIGH_SURROGATE_START) && (c <= CharUnicodeInfo.HIGH_SURROGATE_END));
- }
-
- [Pure]
- public static bool IsHighSurrogate(String s, int index) {
- if (s == null) {
- throw new ArgumentNullException(nameof(s));
- }
- if (index < 0 || index >= s.Length) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- return (IsHighSurrogate(s[index]));
- }
-
- /*================================= IsLowSurrogate ============================
- ** Check if a char is a low surrogate.
- ==============================================================================*/
- [Pure]
- public static bool IsLowSurrogate(char c) {
- return ((c >= CharUnicodeInfo.LOW_SURROGATE_START) && (c <= CharUnicodeInfo.LOW_SURROGATE_END));
- }
-
- [Pure]
- public static bool IsLowSurrogate(String s, int index) {
- if (s == null) {
- throw new ArgumentNullException(nameof(s));
- }
- if (index < 0 || index >= s.Length) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- return (IsLowSurrogate(s[index]));
- }
-
- /*================================= IsSurrogatePair ============================
- ** Check if the string specified by the index starts with a surrogate pair.
- ==============================================================================*/
- [Pure]
- public static bool IsSurrogatePair(String s, int index) {
- if (s == null) {
- throw new ArgumentNullException(nameof(s));
- }
- if (index < 0 || index >= s.Length) {
- throw new ArgumentOutOfRangeException(nameof(index));
- }
- Contract.EndContractBlock();
- if (index + 1 < s.Length) {
- return (IsSurrogatePair(s[index], s[index+1]));
- }
- return (false);
- }
-
- [Pure]
- public static bool IsSurrogatePair(char highSurrogate, char lowSurrogate) {
- return ((highSurrogate >= CharUnicodeInfo.HIGH_SURROGATE_START && highSurrogate <= CharUnicodeInfo.HIGH_SURROGATE_END) &&
- (lowSurrogate >= CharUnicodeInfo.LOW_SURROGATE_START && lowSurrogate <= CharUnicodeInfo.LOW_SURROGATE_END));
- }
-
- internal const int UNICODE_PLANE00_END = 0x00ffff;
- // The starting codepoint for Unicode plane 1. Plane 1 contains 0x010000 ~ 0x01ffff.
- internal const int UNICODE_PLANE01_START = 0x10000;
- // The end codepoint for Unicode plane 16. This is the maximum code point value allowed for Unicode.
- // Plane 16 contains 0x100000 ~ 0x10ffff.
- internal const int UNICODE_PLANE16_END = 0x10ffff;
-
- internal const int HIGH_SURROGATE_START = 0x00d800;
- internal const int LOW_SURROGATE_END = 0x00dfff;
-
-
-
- /*================================= ConvertFromUtf32 ============================
- ** Convert an UTF32 value into a surrogate pair.
- ==============================================================================*/
-
- public static String ConvertFromUtf32(int utf32)
- {
- // For UTF32 values from U+00D800 ~ U+00DFFF, we should throw. They
- // are considered as irregular code unit sequence, but they are not illegal.
- if ((utf32 < 0 || utf32 > UNICODE_PLANE16_END) || (utf32 >= HIGH_SURROGATE_START && utf32 <= LOW_SURROGATE_END)) {
- throw new ArgumentOutOfRangeException(nameof(utf32), Environment.GetResourceString("ArgumentOutOfRange_InvalidUTF32"));
- }
- Contract.EndContractBlock();
-
- if (utf32 < UNICODE_PLANE01_START) {
- // This is a BMP character.
- return (Char.ToString((char)utf32));
- }
-
- unsafe
- {
- // This is a supplementary character. Convert it to a surrogate pair in UTF-16.
- utf32 -= UNICODE_PLANE01_START;
- uint surrogate = 0; // allocate 2 chars worth of stack space
- char* address = (char*)&surrogate;
- address[0] = (char)((utf32 / 0x400) + (int)CharUnicodeInfo.HIGH_SURROGATE_START);
- address[1] = (char)((utf32 % 0x400) + (int)CharUnicodeInfo.LOW_SURROGATE_START);
- return new string(address, 0, 2);
- }
- }
-
-
- /*=============================ConvertToUtf32===================================
- ** Convert a surrogate pair to UTF32 value
- ==============================================================================*/
-
- public static int ConvertToUtf32(char highSurrogate, char lowSurrogate) {
- if (!IsHighSurrogate(highSurrogate)) {
- throw new ArgumentOutOfRangeException(nameof(highSurrogate), Environment.GetResourceString("ArgumentOutOfRange_InvalidHighSurrogate"));
- }
- if (!IsLowSurrogate(lowSurrogate)) {
- throw new ArgumentOutOfRangeException(nameof(lowSurrogate), Environment.GetResourceString("ArgumentOutOfRange_InvalidLowSurrogate"));
- }
- Contract.EndContractBlock();
- return (((highSurrogate - CharUnicodeInfo.HIGH_SURROGATE_START) * 0x400) + (lowSurrogate - CharUnicodeInfo.LOW_SURROGATE_START) + UNICODE_PLANE01_START);
- }
-
- /*=============================ConvertToUtf32===================================
- ** Convert a character or a surrogate pair starting at index of the specified string
- ** to UTF32 value.
- ** The char pointed by index should be a surrogate pair or a BMP character.
- ** This method throws if a high-surrogate is not followed by a low surrogate.
- ** This method throws if a low surrogate is seen without preceding a high-surrogate.
- ==============================================================================*/
-
- public static int ConvertToUtf32(String s, int index) {
- if (s == null) {
- throw new ArgumentNullException(nameof(s));
- }
-
- if (index < 0 || index >= s.Length) {
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- Contract.EndContractBlock();
- // Check if the character at index is a high surrogate.
- int temp1 = (int)s[index] - CharUnicodeInfo.HIGH_SURROGATE_START;
- if (temp1 >= 0 && temp1 <= 0x7ff) {
- // Found a surrogate char.
- if (temp1 <= 0x3ff) {
- // Found a high surrogate.
- if (index < s.Length - 1) {
- int temp2 = (int)s[index+1] - CharUnicodeInfo.LOW_SURROGATE_START;
- if (temp2 >= 0 && temp2 <= 0x3ff) {
- // Found a low surrogate.
- return ((temp1 * 0x400) + temp2 + UNICODE_PLANE01_START);
- } else {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHighSurrogate", index), nameof(s));
- }
- } else {
- // Found a high surrogate at the end of the string.
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHighSurrogate", index), nameof(s));
- }
- } else {
- // Find a low surrogate at the character pointed by index.
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidLowSurrogate", index), nameof(s));
- }
- }
- // Not a high-surrogate or low-surrogate. Genereate the UTF32 value for the BMP characters.
- return ((int)s[index]);
- }
- }
-}
diff --git a/src/mscorlib/src/System/CharEnumerator.cs b/src/mscorlib/src/System/CharEnumerator.cs
deleted file mode 100644
index 689ed7e488..0000000000
--- a/src/mscorlib/src/System/CharEnumerator.cs
+++ /dev/null
@@ -1,81 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose: Enumerates the characters on a string. skips range
-** checks.
-**
-**
-============================================================*/
-
-using System.Collections;
-using System.Collections.Generic;
-
-namespace System
-{
- public sealed class CharEnumerator : IEnumerator, IEnumerator<char>, IDisposable, ICloneable
- {
- private String _str;
- private int _index;
- private char _currentElement;
-
- internal CharEnumerator(String str)
- {
- _str = str;
- _index = -1;
- }
-
- public object Clone()
- {
- return MemberwiseClone();
- }
-
- public bool MoveNext()
- {
- if (_index < (_str.Length - 1))
- {
- _index++;
- _currentElement = _str[_index];
- return true;
- }
- else
- _index = _str.Length;
- return false;
- }
-
- public void Dispose()
- {
- if (_str != null)
- _index = _str.Length;
- _str = null;
- }
-
- /// <internalonly/>
- Object IEnumerator.Current
- {
- get { return Current; }
- }
-
- public char Current
- {
- get
- {
- if (_index == -1)
- throw new InvalidOperationException(SR.InvalidOperation_EnumNotStarted);
- if (_index >= _str.Length)
- throw new InvalidOperationException(SR.InvalidOperation_EnumEnded);
- return _currentElement;
- }
- }
-
- public void Reset()
- {
- _currentElement = (char)0;
- _index = -1;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/ArrayList.cs b/src/mscorlib/src/System/Collections/ArrayList.cs
index 53746e224e..cee7be726a 100644
--- a/src/mscorlib/src/System/Collections/ArrayList.cs
+++ b/src/mscorlib/src/System/Collections/ArrayList.cs
@@ -14,16 +14,18 @@
**
**
===========================================================*/
-namespace System.Collections {
- using System;
- using System.Runtime;
- using System.Security;
- using System.Diagnostics;
- using System.Runtime.CompilerServices;
- using System.Runtime.Serialization;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
+using System;
+using System.Runtime;
+using System.Security;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+
+namespace System.Collections
+{
// Implements a variable-size List that uses an array of objects to store the
// elements. A ArrayList has a capacity, which is the allocated length
// of the internal array. As elements are added to a ArrayList, the capacity
@@ -31,7 +33,7 @@ namespace System.Collections {
// internal array.
//
[FriendAccessAllowed]
- [DebuggerTypeProxy(typeof(System.Collections.ArrayList.ArrayListDebugView))]
+ [DebuggerTypeProxy(typeof(System.Collections.ArrayList.ArrayListDebugView))]
[DebuggerDisplay("Count = {Count}")]
[Serializable]
internal class ArrayList : IList, ICloneable
@@ -42,38 +44,41 @@ namespace System.Collections {
private int _version;
[NonSerialized]
private Object _syncRoot;
-
+
private const int _defaultCapacity = 4;
- private static readonly Object[] emptyArray = EmptyArray<Object>.Value;
+ private static readonly Object[] emptyArray = Array.Empty<Object>();
// Constructs a ArrayList. The list is initially empty and has a capacity
// of zero. Upon adding the first element to the list the capacity is
// increased to _defaultCapacity, and then increased in multiples of two as required.
- public ArrayList() {
- _items = emptyArray;
+ public ArrayList()
+ {
+ _items = emptyArray;
}
-
+
// Constructs a ArrayList with a given initial capacity. The list is
// initially empty, but will have room for the given number of elements
// before any reallocations are required.
//
- public ArrayList(int capacity) {
- if (capacity < 0) throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", nameof(capacity)));
- Contract.EndContractBlock();
-
- if (capacity == 0)
- _items = emptyArray;
- else
- _items = new Object[capacity];
+ public ArrayList(int capacity)
+ {
+ if (capacity < 0) throw new ArgumentOutOfRangeException(nameof(capacity), SR.Format(SR.ArgumentOutOfRange_MustBeNonNegNum, nameof(capacity)));
+ Contract.EndContractBlock();
+
+ if (capacity == 0)
+ _items = emptyArray;
+ else
+ _items = new Object[capacity];
}
-
+
// Constructs a ArrayList, copying the contents of the given collection. The
// size and capacity of the new list will both be equal to the size of the
// given collection.
//
- public ArrayList(ICollection c) {
- if (c==null)
- throw new ArgumentNullException(nameof(c), Environment.GetResourceString("ArgumentNull_Collection"));
+ public ArrayList(ICollection c)
+ {
+ if (c == null)
+ throw new ArgumentNullException(nameof(c), SR.ArgumentNull_Collection);
Contract.EndContractBlock();
int count = c.Count;
@@ -81,124 +86,147 @@ namespace System.Collections {
{
_items = emptyArray;
}
- else {
+ else
+ {
_items = new Object[count];
AddRange(c);
}
}
-
+
// Gets and sets the capacity of this list. The capacity is the size of
// the internal array used to hold items. When set, the internal
// array of the list is reallocated to the given capacity.
//
- public virtual int Capacity {
- get {
+ public virtual int Capacity
+ {
+ get
+ {
Contract.Ensures(Contract.Result<int>() >= Count);
return _items.Length;
}
- set {
- if (value < _size) {
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
+ set
+ {
+ if (value < _size)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_SmallCapacity);
}
Contract.Ensures(Capacity >= 0);
Contract.EndContractBlock();
// We don't want to update the version number when we change the capacity.
// Some existing applications have dependency on this.
- if (value != _items.Length) {
- if (value > 0) {
+ if (value != _items.Length)
+ {
+ if (value > 0)
+ {
Object[] newItems = new Object[value];
- if (_size > 0) {
+ if (_size > 0)
+ {
Array.Copy(_items, 0, newItems, 0, _size);
}
_items = newItems;
}
- else {
+ else
+ {
_items = new Object[_defaultCapacity];
}
- }
+ }
}
}
// Read-only property describing how many elements are in the List.
- public virtual int Count {
- get {
+ public virtual int Count
+ {
+ get
+ {
Contract.Ensures(Contract.Result<int>() >= 0);
return _size;
}
}
- public virtual bool IsFixedSize {
+ public virtual bool IsFixedSize
+ {
get { return false; }
}
-
+
// Is this ArrayList read-only?
- public virtual bool IsReadOnly {
+ public virtual bool IsReadOnly
+ {
get { return false; }
}
// Is this ArrayList synchronized (thread-safe)?
- public virtual bool IsSynchronized {
+ public virtual bool IsSynchronized
+ {
get { return false; }
}
-
+
// Synchronization root for this object.
- public virtual Object SyncRoot {
- get {
- if( _syncRoot == null) {
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ public virtual Object SyncRoot
+ {
+ get
+ {
+ if (_syncRoot == null)
+ {
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
- return _syncRoot;
+ return _syncRoot;
}
}
-
+
// Sets or Gets the element at the given index.
//
- public virtual Object this[int index] {
- get {
- if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ public virtual Object this[int index]
+ {
+ get
+ {
+ if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
Contract.EndContractBlock();
return _items[index];
}
- set {
- if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ set
+ {
+ if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
Contract.EndContractBlock();
_items[index] = value;
_version++;
}
}
-
+
// Adds the given object to the end of this list. The size of the list is
// increased by one. If required, the capacity of the list is doubled
// before adding the new element.
//
- public virtual int Add(Object value) {
+ public virtual int Add(Object value)
+ {
Contract.Ensures(Contract.Result<int>() >= 0);
if (_size == _items.Length) EnsureCapacity(_size + 1);
_items[_size] = value;
_version++;
return _size++;
}
-
+
// Adds the elements of the given collection to the end of this list. If
// required, the capacity of the list is increased to twice the previous
// capacity or the new size, whichever is larger.
//
- public virtual void AddRange(ICollection c) {
+ public virtual void AddRange(ICollection c)
+ {
InsertRange(_size, c);
}
-
+
// Clears the contents of ArrayList.
- public virtual void Clear() {
+ public virtual void Clear()
+ {
if (_size > 0)
{
- Array.Clear(_items, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references.
- _size = 0;
+ Array.Clear(_items, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references.
+ _size = 0;
}
_version++;
}
-
+
// Clones this ArrayList, doing a shallow copy. (A copy is made of all
// Object references in the ArrayList, but the Objects pointed to
// are not cloned).
@@ -211,22 +239,25 @@ namespace System.Collections {
Array.Copy(_items, 0, la._items, 0, _size);
return la;
}
-
-
+
+
// Contains returns true if the specified element is in the ArrayList.
// It does a linear, O(n) search. Equality is determined by calling
// item.Equals().
//
- public virtual bool Contains(Object item) {
- if (item==null) {
- for(int i=0; i<_size; i++)
- if (_items[i]==null)
+ public virtual bool Contains(Object item)
+ {
+ if (item == null)
+ {
+ for (int i = 0; i < _size; i++)
+ if (_items[i] == null)
return true;
return false;
}
- else {
- for(int i=0; i<_size; i++)
- if ( (_items[i] != null) && (_items[i].Equals(item)) )
+ else
+ {
+ for (int i = 0; i < _size; i++)
+ if ((_items[i] != null) && (_items[i].Equals(item)))
return true;
return false;
}
@@ -235,9 +266,10 @@ namespace System.Collections {
// Copies this ArrayList into array, which must be of a
// compatible array type.
//
- public virtual void CopyTo(Array array, int arrayIndex) {
+ public virtual void CopyTo(Array array, int arrayIndex)
+ {
if ((array != null) && (array.Rank != 1))
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
+ throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
Contract.EndContractBlock();
// Delegate rest of error checking to Array.Copy.
Array.Copy(_items, 0, array, arrayIndex, _size);
@@ -247,9 +279,11 @@ namespace System.Collections {
// value. If the currect capacity of the list is less than min, the
// capacity is increased to twice the current capacity or to min,
// whichever is larger.
- private void EnsureCapacity(int min) {
- if (_items.Length < min) {
- int newCapacity = _items.Length == 0? _defaultCapacity: _items.Length * 2;
+ private void EnsureCapacity(int min)
+ {
+ if (_items.Length < min)
+ {
+ int newCapacity = _items.Length == 0 ? _defaultCapacity : _items.Length * 2;
// Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow.
// Note that this check works even when _items.Length overflowed thanks to the (uint) cast
if ((uint)newCapacity > Array.MaxArrayLength) newCapacity = Array.MaxArrayLength;
@@ -257,17 +291,18 @@ namespace System.Collections {
Capacity = newCapacity;
}
}
-
+
// Returns an enumerator for this list with the given
// permission for removal of elements. If modifications made to the list
// while an enumeration is in progress, the MoveNext and
// GetObject methods of the enumerator will throw an exception.
//
- public virtual IEnumerator GetEnumerator() {
+ public virtual IEnumerator GetEnumerator()
+ {
Contract.Ensures(Contract.Result<IEnumerator>() != null);
return new ArrayListEnumeratorSimple(this);
}
-
+
// Returns the index of the first occurrence of a given value in a range of
// this list. The list is searched forwards from beginning to end.
// The elements of the list are compared to the given value using the
@@ -276,47 +311,53 @@ namespace System.Collections {
// This method uses the Array.IndexOf method to perform the
// search.
//
- public virtual int IndexOf(Object value) {
+ public virtual int IndexOf(Object value)
+ {
Contract.Ensures(Contract.Result<int>() < Count);
return Array.IndexOf((Array)_items, value, 0, _size);
}
-
+
// Inserts an element into this list at a given index. The size of the list
// is increased by one. If required, the capacity of the list is doubled
// before inserting the new element.
//
- public virtual void Insert(int index, Object value) {
+ public virtual void Insert(int index, Object value)
+ {
// Note that insertions at the end are legal.
- if (index < 0 || index > _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_ArrayListInsert"));
+ if (index < 0 || index > _size) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_ArrayListInsert);
//Contract.Ensures(Count == Contract.OldValue(Count) + 1);
Contract.EndContractBlock();
if (_size == _items.Length) EnsureCapacity(_size + 1);
- if (index < _size) {
+ if (index < _size)
+ {
Array.Copy(_items, index, _items, index + 1, _size - index);
}
_items[index] = value;
_size++;
_version++;
}
-
+
// Inserts the elements of the given collection at a given index. If
// required, the capacity of the list is increased to twice the previous
// capacity or the new size, whichever is larger. Ranges may be added
// to the end of the list by setting index to the ArrayList's size.
//
- public virtual void InsertRange(int index, ICollection c) {
- if (c==null)
- throw new ArgumentNullException(nameof(c), Environment.GetResourceString("ArgumentNull_Collection"));
- if (index < 0 || index > _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ public virtual void InsertRange(int index, ICollection c)
+ {
+ if (c == null)
+ throw new ArgumentNullException(nameof(c), SR.ArgumentNull_Collection);
+ if (index < 0 || index > _size) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
//Contract.Ensures(Count == Contract.OldValue(Count) + c.Count);
Contract.EndContractBlock();
int count = c.Count;
- if (count > 0) {
- EnsureCapacity(_size + count);
+ if (count > 0)
+ {
+ EnsureCapacity(_size + count);
// shift existing items
- if (index < _size) {
+ if (index < _size)
+ {
Array.Copy(_items, index, _items, index + count, _size - index);
}
@@ -327,54 +368,59 @@ namespace System.Collections {
_version++;
}
}
-
+
// Returns a read-only IList wrapper for the given IList.
//
[FriendAccessAllowed]
- public static IList ReadOnly(IList list) {
- if (list==null)
+ public static IList ReadOnly(IList list)
+ {
+ if (list == null)
throw new ArgumentNullException(nameof(list));
Contract.Ensures(Contract.Result<IList>() != null);
Contract.EndContractBlock();
return new ReadOnlyList(list);
}
-
+
// Removes the element at the given index. The size of the list is
// decreased by one.
//
- public virtual void Remove(Object obj) {
+ public virtual void Remove(Object obj)
+ {
Contract.Ensures(Count >= 0);
int index = IndexOf(obj);
- BCLDebug.Correctness(index >= 0 || !(obj is Int32), "You passed an Int32 to Remove that wasn't in the ArrayList." + Environment.NewLine + "Did you mean RemoveAt? int: "+obj+" Count: "+Count);
- if (index >=0)
+ BCLDebug.Correctness(index >= 0 || !(obj is Int32), "You passed an Int32 to Remove that wasn't in the ArrayList." + Environment.NewLine + "Did you mean RemoveAt? int: " + obj + " Count: " + Count);
+ if (index >= 0)
RemoveAt(index);
}
-
+
// Removes the element at the given index. The size of the list is
// decreased by one.
//
- public virtual void RemoveAt(int index) {
- if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ public virtual void RemoveAt(int index)
+ {
+ if (index < 0 || index >= _size) throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
Contract.Ensures(Count >= 0);
//Contract.Ensures(Count == Contract.OldValue(Count) - 1);
Contract.EndContractBlock();
_size--;
- if (index < _size) {
+ if (index < _size)
+ {
Array.Copy(_items, index + 1, _items, index, _size - index);
}
_items[_size] = null;
_version++;
}
-
+
// ToArray returns a new array of a particular type containing the contents
// of the ArrayList. This requires copying the ArrayList and potentially
// downcasting all elements. This copy may fail and is an O(n) operation.
// Internally, this implementation calls Array.Copy.
//
- public virtual Array ToArray(Type type) {
- if (type==null)
+ public virtual Array ToArray(Type type)
+ {
+ if (type == null)
throw new ArgumentNullException(nameof(type));
Contract.Ensures(Contract.Result<Array>() != null);
Contract.EndContractBlock();
@@ -382,84 +428,103 @@ namespace System.Collections {
Array.Copy(_items, 0, array, 0, _size);
return array;
}
-
+
[Serializable]
private class ReadOnlyList : IList
{
private IList _list;
-
- internal ReadOnlyList(IList l) {
+
+ internal ReadOnlyList(IList l)
+ {
_list = l;
}
-
- public virtual int Count {
+
+ public virtual int Count
+ {
get { return _list.Count; }
}
-
- public virtual bool IsReadOnly {
+
+ public virtual bool IsReadOnly
+ {
get { return true; }
}
- public virtual bool IsFixedSize {
+ public virtual bool IsFixedSize
+ {
get { return true; }
}
- public virtual bool IsSynchronized {
+ public virtual bool IsSynchronized
+ {
get { return _list.IsSynchronized; }
}
-
- public virtual Object this[int index] {
- get {
+
+ public virtual Object this[int index]
+ {
+ get
+ {
return _list[index];
}
- set {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
+ set
+ {
+ throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
}
-
- public virtual Object SyncRoot {
+
+ public virtual Object SyncRoot
+ {
get { return _list.SyncRoot; }
}
-
- public virtual int Add(Object obj) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
+
+ public virtual int Add(Object obj)
+ {
+ throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
-
- public virtual void Clear() {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
+
+ public virtual void Clear()
+ {
+ throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
-
- public virtual bool Contains(Object obj) {
+
+ public virtual bool Contains(Object obj)
+ {
return _list.Contains(obj);
}
-
- public virtual void CopyTo(Array array, int index) {
+
+ public virtual void CopyTo(Array array, int index)
+ {
_list.CopyTo(array, index);
}
-
- public virtual IEnumerator GetEnumerator() {
+
+ public virtual IEnumerator GetEnumerator()
+ {
return _list.GetEnumerator();
}
-
- public virtual int IndexOf(Object value) {
+
+ public virtual int IndexOf(Object value)
+ {
return _list.IndexOf(value);
}
-
- public virtual void Insert(int index, Object obj) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
+
+ public virtual void Insert(int index, Object obj)
+ {
+ throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
- public virtual void Remove(Object value) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
+ public virtual void Remove(Object value)
+ {
+ throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
-
- public virtual void RemoveAt(int index) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
+
+ public virtual void RemoveAt(int index)
+ {
+ throw new NotSupportedException(SR.NotSupported_ReadOnlyCollection);
}
}
[Serializable]
- private sealed class ArrayListEnumeratorSimple : IEnumerator, ICloneable {
+ private sealed class ArrayListEnumeratorSimple : IEnumerator, ICloneable
+ {
private ArrayList list;
private int index;
private int version;
@@ -467,77 +532,95 @@ namespace System.Collections {
[NonSerialized]
private bool isArrayList;
// this object is used to indicate enumeration has not started or has terminated
- static Object dummyObject = new Object();
-
- internal ArrayListEnumeratorSimple(ArrayList list) {
+ private static Object dummyObject = new Object();
+
+ internal ArrayListEnumeratorSimple(ArrayList list)
+ {
this.list = list;
- this.index = -1;
+ index = -1;
version = list._version;
isArrayList = (list.GetType() == typeof(ArrayList));
- currentElement = dummyObject;
+ currentElement = dummyObject;
}
-
- public Object Clone() {
+
+ public Object Clone()
+ {
return MemberwiseClone();
}
-
- public bool MoveNext() {
- if (version != list._version) {
- throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
+
+ public bool MoveNext()
+ {
+ if (version != list._version)
+ {
+ throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
}
- if( isArrayList) { // avoid calling virtual methods if we are operating on ArrayList to improve performance
- if (index < list._size - 1) {
+ if (isArrayList)
+ { // avoid calling virtual methods if we are operating on ArrayList to improve performance
+ if (index < list._size - 1)
+ {
currentElement = list._items[++index];
return true;
}
- else {
+ else
+ {
currentElement = dummyObject;
- index =list._size;
+ index = list._size;
return false;
- }
+ }
}
- else {
- if (index < list.Count - 1) {
+ else
+ {
+ if (index < list.Count - 1)
+ {
currentElement = list[++index];
return true;
}
- else {
+ else
+ {
index = list.Count;
currentElement = dummyObject;
return false;
}
}
}
-
- public Object Current {
- get {
+
+ public Object Current
+ {
+ get
+ {
object temp = currentElement;
- if(dummyObject == temp) { // check if enumeration has not started or has terminated
- if (index == -1) {
- throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
+ if (dummyObject == temp)
+ { // check if enumeration has not started or has terminated
+ if (index == -1)
+ {
+ throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
}
- else {
- throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded));
+ else
+ {
+ throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumEnded));
}
}
return temp;
}
}
-
- public void Reset() {
- if (version != list._version) {
- throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
- }
-
+
+ public void Reset()
+ {
+ if (version != list._version)
+ {
+ throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
+ }
+
currentElement = dummyObject;
index = -1;
}
}
- internal class ArrayListDebugView {
- private ArrayList arrayList;
+ internal class ArrayListDebugView
+ {
+ private ArrayList arrayList;
}
- }
+ }
}
diff --git a/src/mscorlib/src/System/Collections/CollectionBase.cs b/src/mscorlib/src/System/Collections/CollectionBase.cs
deleted file mode 100644
index a3dd88a7b3..0000000000
--- a/src/mscorlib/src/System/Collections/CollectionBase.cs
+++ /dev/null
@@ -1,199 +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.
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-//
-
-namespace System.Collections {
- using System;
- using System.Diagnostics.Contracts;
-
- // Useful base class for typed read/write collections where items derive from object
- [Serializable]
- public abstract class CollectionBase : IList {
- private ArrayList list;
-
- protected CollectionBase() {
- list = new ArrayList();
- }
-
- internal ArrayList InnerList {
- get {
- if (list == null)
- list = new ArrayList();
- return list;
- }
- }
-
- protected IList List {
- get { return (IList)this; }
- }
-
-
- public int Count {
- get {
- return list == null ? 0 : list.Count;
- }
- }
-
- public void Clear() {
- OnClear();
- InnerList.Clear();
- OnClearComplete();
- }
-
- public void RemoveAt(int index) {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
- Object temp = InnerList[index];
- OnValidate(temp);
- OnRemove(index, temp);
- InnerList.RemoveAt(index);
- try {
- OnRemoveComplete(index, temp);
- }
- catch {
- InnerList.Insert(index, temp);
- throw;
- }
-
- }
-
- bool IList.IsReadOnly {
- get { return InnerList.IsReadOnly; }
- }
-
- bool IList.IsFixedSize {
- get { return InnerList.IsFixedSize; }
- }
-
- bool ICollection.IsSynchronized {
- get { return InnerList.IsSynchronized; }
- }
-
- Object ICollection.SyncRoot {
- get { return InnerList.SyncRoot; }
- }
-
- void ICollection.CopyTo(Array array, int index) {
- InnerList.CopyTo(array, index);
- }
-
- Object IList.this[int index] {
- get {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
- return InnerList[index];
- }
- set {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
- OnValidate(value);
- Object temp = InnerList[index];
- OnSet(index, temp, value);
- InnerList[index] = value;
- try {
- OnSetComplete(index, temp, value);
- }
- catch {
- InnerList[index] = temp;
- throw;
- }
- }
- }
-
- bool IList.Contains(Object value) {
- return InnerList.Contains(value);
- }
-
- int IList.Add(Object value) {
- OnValidate(value);
- OnInsert(InnerList.Count, value);
- int index = InnerList.Add(value);
- try {
- OnInsertComplete(index, value);
- }
- catch {
- InnerList.RemoveAt(index);
- throw;
- }
- return index;
- }
-
-
- void IList.Remove(Object value) {
- OnValidate(value);
- int index = InnerList.IndexOf(value);
- if (index < 0) throw new ArgumentException(Environment.GetResourceString("Arg_RemoveArgNotFound"));
- OnRemove(index, value);
- InnerList.RemoveAt(index);
- try{
- OnRemoveComplete(index, value);
- }
- catch {
- InnerList.Insert(index, value);
- throw;
- }
- }
-
- int IList.IndexOf(Object value) {
- return InnerList.IndexOf(value);
- }
-
- void IList.Insert(int index, Object value) {
- if (index < 0 || index > Count)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- Contract.EndContractBlock();
- OnValidate(value);
- OnInsert(index, value);
- InnerList.Insert(index, value);
- try {
- OnInsertComplete(index, value);
- }
- catch {
- InnerList.RemoveAt(index);
- throw;
- }
- }
-
- public IEnumerator GetEnumerator() {
- return InnerList.GetEnumerator();
- }
-
- protected virtual void OnSet(int index, Object oldValue, Object newValue) {
- }
-
- protected virtual void OnInsert(int index, Object value) {
- }
-
- protected virtual void OnClear() {
- }
-
- protected virtual void OnRemove(int index, Object value) {
- }
-
- protected virtual void OnValidate(Object value) {
- if (value == null) throw new ArgumentNullException(nameof(value));
- Contract.EndContractBlock();
- }
-
- protected virtual void OnSetComplete(int index, Object oldValue, Object newValue) {
- }
-
- protected virtual void OnInsertComplete(int index, Object value) {
- }
-
- protected virtual void OnClearComplete() {
- }
-
- protected virtual void OnRemoveComplete(int index, Object value) {
- }
-
- }
-
-}
diff --git a/src/mscorlib/src/System/Collections/Comparer.cs b/src/mscorlib/src/System/Collections/Comparer.cs
index 928b0f9f9a..7f4f9f0a07 100644
--- a/src/mscorlib/src/System/Collections/Comparer.cs
+++ b/src/mscorlib/src/System/Collections/Comparer.cs
@@ -12,46 +12,53 @@
**
**
===========================================================*/
-namespace System.Collections {
-
- using System;
- using System.Globalization;
- using System.Runtime.Serialization;
- using System.Diagnostics.Contracts;
+using System;
+using System.Globalization;
+using System.Runtime.Serialization;
+using System.Diagnostics.Contracts;
+
+namespace System.Collections
+{
[Serializable]
- internal sealed class Comparer : IComparer , ISerializable
+ internal sealed class Comparer : IComparer, ISerializable
{
- private CompareInfo m_compareInfo;
+ private CompareInfo m_compareInfo;
public static readonly Comparer Default = new Comparer(CultureInfo.CurrentCulture);
public static readonly Comparer DefaultInvariant = new Comparer(CultureInfo.InvariantCulture);
-
+
private const String CompareInfoName = "CompareInfo";
- private Comparer() {
+ private Comparer()
+ {
m_compareInfo = null;
}
- public Comparer(CultureInfo culture) {
- if (culture==null) {
+ public Comparer(CultureInfo culture)
+ {
+ if (culture == null)
+ {
throw new ArgumentNullException(nameof(culture));
}
Contract.EndContractBlock();
m_compareInfo = culture.CompareInfo;
}
-
- private Comparer(SerializationInfo info, StreamingContext context) {
+
+ private Comparer(SerializationInfo info, StreamingContext context)
+ {
m_compareInfo = null;
- SerializationInfoEnumerator enumerator = info.GetEnumerator();
- while( enumerator.MoveNext()) {
- switch( enumerator.Name) {
+ SerializationInfoEnumerator enumerator = info.GetEnumerator();
+ while (enumerator.MoveNext())
+ {
+ switch (enumerator.Name)
+ {
case CompareInfoName:
- m_compareInfo = (CompareInfo) info.GetValue(CompareInfoName, typeof(CompareInfo));
+ m_compareInfo = (CompareInfo)info.GetValue(CompareInfoName, typeof(CompareInfo));
break;
}
}
}
-
+
// Compares two Objects by calling CompareTo. If a ==
// b,0 is returned. If a implements
// IComparable, a.CompareTo(b) is returned. If a
@@ -59,11 +66,13 @@ namespace System.Collections {
// -(b.CompareTo(a)) is returned, otherwise an
// exception is thrown.
//
- public int Compare(Object a, Object b) {
+ public int Compare(Object a, Object b)
+ {
if (a == b) return 0;
if (a == null) return -1;
if (b == null) return 1;
- if (m_compareInfo != null) {
+ if (m_compareInfo != null)
+ {
String sa = a as String;
String sb = b as String;
if (sa != null && sb != null)
@@ -78,18 +87,21 @@ namespace System.Collections {
if (ib != null)
return -ib.CompareTo(a);
- throw new ArgumentException(Environment.GetResourceString("Argument_ImplementIComparable"));
+ throw new ArgumentException(SR.Argument_ImplementIComparable);
}
- public void GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
- if( m_compareInfo != null) {
+ if (m_compareInfo != null)
+ {
info.AddValue(CompareInfoName, m_compareInfo);
}
- }
+ }
}
}
diff --git a/src/mscorlib/src/System/Collections/CompatibleComparer.cs b/src/mscorlib/src/System/Collections/CompatibleComparer.cs
index e5d3961245..1c90707184 100644
--- a/src/mscorlib/src/System/Collections/CompatibleComparer.cs
+++ b/src/mscorlib/src/System/Collections/CompatibleComparer.cs
@@ -6,39 +6,45 @@
using System.Diagnostics.Contracts;
-namespace System.Collections {
-
+namespace System.Collections
+{
[Serializable]
- internal class CompatibleComparer: IEqualityComparer {
- IComparer _comparer;
+ internal class CompatibleComparer : IEqualityComparer
+ {
+ private IComparer _comparer;
#pragma warning disable 618
- IHashCodeProvider _hcp;
+ private IHashCodeProvider _hcp;
- internal CompatibleComparer(IComparer comparer, IHashCodeProvider hashCodeProvider) {
+ internal CompatibleComparer(IComparer comparer, IHashCodeProvider hashCodeProvider)
+ {
_comparer = comparer;
_hcp = hashCodeProvider;
}
#pragma warning restore 618
- public int Compare(Object a, Object b) {
+ public int Compare(Object a, Object b)
+ {
if (a == b) return 0;
if (a == null) return -1;
if (b == null) return 1;
if (_comparer != null)
- return _comparer.Compare(a,b);
+ return _comparer.Compare(a, b);
IComparable ia = a as IComparable;
if (ia != null)
return ia.CompareTo(b);
- throw new ArgumentException(Environment.GetResourceString("Argument_ImplementIComparable"));
+ throw new ArgumentException(SR.Argument_ImplementIComparable);
}
- public new bool Equals(Object a, Object b) {
- return Compare(a, b) == 0;
+ public new bool Equals(Object a, Object b)
+ {
+ return Compare(a, b) == 0;
}
- public int GetHashCode(Object obj) {
- if( obj == null) {
+ public int GetHashCode(Object obj)
+ {
+ if (obj == null)
+ {
throw new ArgumentNullException(nameof(obj));
}
Contract.EndContractBlock();
@@ -49,16 +55,20 @@ namespace System.Collections {
}
// These are helpers for the Hashtable to query the IKeyComparer infrastructure.
- internal IComparer Comparer {
- get {
+ internal IComparer Comparer
+ {
+ get
+ {
return _comparer;
}
}
// These are helpers for the Hashtable to query the IKeyComparer infrastructure.
#pragma warning disable 618
- internal IHashCodeProvider HashCodeProvider {
- get {
+ internal IHashCodeProvider HashCodeProvider
+ {
+ get
+ {
return _hcp;
}
}
diff --git a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs
index 8b9014a103..436808c439 100644
--- a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs
+++ b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentDictionary.cs
@@ -65,7 +65,7 @@ namespace System.Collections.Concurrent
private volatile Tables m_tables; // Internal tables of the dictionary
// NOTE: this is only used for compat reasons to serialize the comparer.
// This should not be accessed from anywhere else outside of the serialization methods.
- internal IEqualityComparer<TKey> m_comparer;
+ internal IEqualityComparer<TKey> m_comparer;
private readonly bool m_growLockArray; // Whether to dynamically increase the size of the striped lock
// How many times we resized becaused of collisions.
@@ -102,6 +102,10 @@ namespace System.Collections.Concurrent
private static bool IsValueWriteAtomic()
{
Type valueType = typeof(TValue);
+ if (valueType.IsEnum)
+ {
+ valueType = Enum.GetUnderlyingType(valueType);
+ }
//
// Section 12.6.6 of ECMA CLI explains which types can be read and written atomically without
@@ -705,7 +709,6 @@ namespace System.Collections.Concurrent
{
count += m_tables.m_countPerLock[i];
}
-
}
finally
{
@@ -1404,7 +1407,6 @@ namespace System.Collections.Concurrent
/// </summary>
private static int DefaultConcurrencyLevel
{
-
get { return DEFAULT_CONCURRENCY_MULTIPLIER * PlatformHelper.ProcessorCount; }
}
@@ -1559,7 +1561,7 @@ namespace System.Collections.Concurrent
/// </summary>
private class DictionaryEnumerator : IDictionaryEnumerator
{
- IEnumerator<KeyValuePair<TKey, TValue>> m_enumerator; // Enumerator over the dictionary.
+ private IEnumerator<KeyValuePair<TKey, TValue>> m_enumerator; // Enumerator over the dictionary.
internal DictionaryEnumerator(ConcurrentDictionary<TKey, TValue> dictionary)
{
diff --git a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs
index 90ada007dd..c6211dadd3 100644
--- a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs
+++ b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentQueue.cs
@@ -205,7 +205,7 @@ namespace System.Collections.Concurrent
/// cref="ICollection"/>. This property is not supported.
/// </summary>
/// <exception cref="NotSupportedException">The SyncRoot property is not supported.</exception>
- object ICollection.SyncRoot { get { throw new NotSupportedException(Environment.GetResourceString("ConcurrentCollection_SyncRoot_NotSupported")); } }
+ object ICollection.SyncRoot { get { throw new NotSupportedException(SR.ConcurrentCollection_SyncRoot_NotSupported); } }
/// <summary>Returns an enumerator that iterates through a collection.</summary>
/// <returns>An <see cref="IEnumerator"/> that can be used to iterate through the collection.</returns>
@@ -443,7 +443,7 @@ namespace System.Collections.Concurrent
long count = GetCount(head, headHead, tail, tailTail);
if (index > array.Length - count)
{
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall"));
+ throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall);
}
// Copy the items to the target array
@@ -1115,7 +1115,7 @@ namespace System.Collections.Concurrent
[StructLayout(LayoutKind.Explicit, Size = 192)] // padding before/between/after fields based on typical cache line size of 64
internal struct PaddedHeadAndTail
{
- [FieldOffset(64)] public int Head;
+ [FieldOffset(64)] public int Head;
[FieldOffset(128)] public int Tail;
}
}
diff --git a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs
index 10a5201f6c..82bc4f9f5c 100644
--- a/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs
+++ b/src/mscorlib/src/System/Collections/Concurrent/ConcurrentStack.cs
@@ -135,7 +135,7 @@ namespace System.Collections.Concurrent
{
get
{
- throw new NotSupportedException(Environment.GetResourceString("ConcurrentCollection_SyncRoot_NotSupported"));
+ throw new NotSupportedException(SR.ConcurrentCollection_SyncRoot_NotSupported);
}
}
@@ -306,7 +306,6 @@ namespace System.Collections.Concurrent
result = default(T);
return false;
-
}
/// <summary>
@@ -328,7 +327,7 @@ namespace System.Collections.Concurrent
Node head;
Node next;
int backoff = 1;
- Random r = new Random(Environment.TickCount & Int32.MaxValue); // avoid the case where TickCount could return Int32.MinValue
+ Random r = null;
while (true)
{
head = m_head;
@@ -359,7 +358,18 @@ namespace System.Collections.Concurrent
spin.SpinOnce();
}
- backoff = spin.NextSpinWillYield ? r.Next(1, BACKOFF_MAX_YIELDS) : backoff * 2;
+ if (spin.NextSpinWillYield)
+ {
+ if (r == null)
+ {
+ r = new Random();
+ }
+ backoff = r.Next(1, BACKOFF_MAX_YIELDS);
+ }
+ else
+ {
+ backoff *= 2;
+ }
}
}
diff --git a/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs b/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs
index 0347ece0ec..7c585d8b98 100644
--- a/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs
+++ b/src/mscorlib/src/System/Collections/Concurrent/IProducerConsumerCollection.cs
@@ -16,7 +16,6 @@ using System.Diagnostics;
namespace System.Collections.Concurrent
{
-
/// <summary>
/// Defines methods to manipulate thread-safe collections intended for producer/consumer usage.
/// </summary>
@@ -64,6 +63,5 @@ namespace System.Collections.Concurrent
internal sealed class SystemCollectionsConcurrent_ProducerConsumerCollectionDebugView<T>
{
private IProducerConsumerCollection<T> m_collection; // The collection being viewed.
-
}
}
diff --git a/src/mscorlib/src/System/Collections/DictionaryEntry.cs b/src/mscorlib/src/System/Collections/DictionaryEntry.cs
deleted file mode 100644
index 0c5d8b2387..0000000000
--- a/src/mscorlib/src/System/Collections/DictionaryEntry.cs
+++ /dev/null
@@ -1,62 +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.
-
-/*============================================================
-**
-** Interface: DictionaryEntry
-**
-**
-**
-**
-** Purpose: Return Value for IDictionaryEnumerator::GetEntry
-**
-**
-===========================================================*/
-namespace System.Collections {
-
- using System;
- using System.ComponentModel;
- // A DictionaryEntry holds a key and a value from a dictionary.
- // It is returned by IDictionaryEnumerator::GetEntry().
- [Serializable]
- public struct DictionaryEntry
- {
- private Object _key;
- private Object _value;
-
- // Constructs a new DictionaryEnumerator by setting the Key
- // and Value fields appropriately.
- public DictionaryEntry(Object key, Object value) {
- _key = key;
- _value = value;
- }
-
- public Object Key {
- get {
- return _key;
- }
-
- set {
- _key = value;
- }
- }
-
- public Object Value {
- get {
- return _value;
- }
-
- set {
- _value = value;
- }
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out object key, out object value)
- {
- key = Key;
- value = Value;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/EmptyReadOnlyDictionaryInternal.cs b/src/mscorlib/src/System/Collections/EmptyReadOnlyDictionaryInternal.cs
index a610fce016..63e0d47c75 100644
--- a/src/mscorlib/src/System/Collections/EmptyReadOnlyDictionaryInternal.cs
+++ b/src/mscorlib/src/System/Collections/EmptyReadOnlyDictionaryInternal.cs
@@ -15,178 +15,218 @@
using System.Diagnostics.Contracts;
-namespace System.Collections {
+namespace System.Collections
+{
/// This is a simple implementation of IDictionary that is empty and readonly.
[Serializable]
- internal sealed class EmptyReadOnlyDictionaryInternal: IDictionary {
-
+ internal sealed class EmptyReadOnlyDictionaryInternal : IDictionary
+ {
// Note that this class must be agile with respect to AppDomains. See its usage in
// System.Exception to understand why this is the case.
- public EmptyReadOnlyDictionaryInternal() {
+ public EmptyReadOnlyDictionaryInternal()
+ {
}
// IEnumerable members
- IEnumerator IEnumerable.GetEnumerator() {
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return new NodeEnumerator();
}
// ICollection members
- public void CopyTo(Array array, int index) {
- if (array==null)
+ public void CopyTo(Array array, int index)
+ {
+ if (array == null)
throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
+ throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
- if ( array.Length - index < this.Count )
- throw new ArgumentException( Environment.GetResourceString("ArgumentOutOfRange_Index"), nameof(index));
+ if (array.Length - index < this.Count)
+ throw new ArgumentException(SR.ArgumentOutOfRange_Index, nameof(index));
Contract.EndContractBlock();
// the actual copy is a NOP
}
- public int Count {
- get {
+ public int Count
+ {
+ get
+ {
return 0;
}
- }
+ }
- public Object SyncRoot {
- get {
+ public Object SyncRoot
+ {
+ get
+ {
return this;
}
}
- public bool IsSynchronized {
- get {
+ public bool IsSynchronized
+ {
+ get
+ {
return false;
}
}
// IDictionary members
- public Object this[Object key] {
- get {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public Object this[Object key]
+ {
+ get
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
return null;
}
- set {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ set
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
- if (!key.GetType().IsSerializable)
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(key));
+ if (!key.GetType().IsSerializable)
+ throw new ArgumentException(SR.Argument_NotSerializable, nameof(key));
- if( (value != null) && (!value.GetType().IsSerializable ) )
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(value));
+ if ((value != null) && (!value.GetType().IsSerializable))
+ throw new ArgumentException(SR.Argument_NotSerializable, nameof(value));
Contract.EndContractBlock();
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
}
- public ICollection Keys {
- get {
- return EmptyArray<Object>.Value;
+ public ICollection Keys
+ {
+ get
+ {
+ return Array.Empty<Object>();
}
}
- public ICollection Values {
- get {
- return EmptyArray<Object>.Value;
+ public ICollection Values
+ {
+ get
+ {
+ return Array.Empty<Object>();
}
}
- public bool Contains(Object key) {
+ public bool Contains(Object key)
+ {
return false;
}
- public void Add(Object key, Object value) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public void Add(Object key, Object value)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
- if (!key.GetType().IsSerializable)
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(key) );
+ if (!key.GetType().IsSerializable)
+ throw new ArgumentException(SR.Argument_NotSerializable, nameof(key));
- if( (value != null) && (!value.GetType().IsSerializable) )
- throw new ArgumentException(Environment.GetResourceString("Argument_NotSerializable"), nameof(value));
+ if ((value != null) && (!value.GetType().IsSerializable))
+ throw new ArgumentException(SR.Argument_NotSerializable, nameof(value));
Contract.EndContractBlock();
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
- public void Clear() {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
+ public void Clear()
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
- public bool IsReadOnly {
- get {
+ public bool IsReadOnly
+ {
+ get
+ {
return true;
}
}
- public bool IsFixedSize {
- get {
+ public bool IsFixedSize
+ {
+ get
+ {
return true;
}
}
- public IDictionaryEnumerator GetEnumerator() {
+ public IDictionaryEnumerator GetEnumerator()
+ {
return new NodeEnumerator();
}
- public void Remove(Object key) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
+ public void Remove(Object key)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
- private sealed class NodeEnumerator : IDictionaryEnumerator {
-
- public NodeEnumerator() {
+ private sealed class NodeEnumerator : IDictionaryEnumerator
+ {
+ public NodeEnumerator()
+ {
}
// IEnumerator members
- public bool MoveNext() {
+ public bool MoveNext()
+ {
return false;
}
- public Object Current {
- get {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public Object Current
+ {
+ get
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
}
- public void Reset() {
+ public void Reset()
+ {
}
// IDictionaryEnumerator members
- public Object Key {
- get {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public Object Key
+ {
+ get
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
}
- public Object Value {
- get {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public Object Value
+ {
+ get
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
}
- public DictionaryEntry Entry {
- get {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public DictionaryEntry Entry
+ {
+ get
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
}
}
diff --git a/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs b/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs
index 298ac3e177..e313cda0fb 100644
--- a/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs
+++ b/src/mscorlib/src/System/Collections/Generic/ArraySortHelper.cs
@@ -12,15 +12,16 @@
**
**
===========================================================*/
+
+using System;
+using System.Globalization;
+using System.Runtime.CompilerServices;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.Versioning;
+
namespace System.Collections.Generic
{
- using System;
- using System.Globalization;
- using System.Runtime.CompilerServices;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Runtime.Versioning;
-
#region ArraySortHelper for single arrays
internal interface IArraySortHelper<TKey>
@@ -36,8 +37,6 @@ namespace System.Collections.Generic
// Large value types may benefit from a smaller number.
internal const int IntrosortSizeThreshold = 16;
- internal const int QuickSortDepthThreshold = 32;
-
internal static int FloorLog2(int n)
{
int result = 0;
@@ -49,18 +48,18 @@ namespace System.Collections.Generic
return result;
}
- internal static void ThrowOrIgnoreBadComparer(Object comparer) {
- throw new ArgumentException(Environment.GetResourceString("Arg_BogusIComparer", comparer));
+ internal static void ThrowOrIgnoreBadComparer(Object comparer)
+ {
+ throw new ArgumentException(SR.Format(SR.Arg_BogusIComparer, comparer));
}
-
}
- [TypeDependencyAttribute("System.Collections.Generic.GenericArraySortHelper`1")]
- internal class ArraySortHelper<T>
+ [TypeDependencyAttribute("System.Collections.Generic.GenericArraySortHelper`1")]
+ internal class ArraySortHelper<T>
: IArraySortHelper<T>
{
- static volatile IArraySortHelper<T> defaultArraySortHelper;
-
+ private static volatile IArraySortHelper<T> defaultArraySortHelper;
+
public static IArraySortHelper<T> Default
{
get
@@ -71,8 +70,8 @@ namespace System.Collections.Generic
return sorter;
}
- }
-
+ }
+
private static IArraySortHelper<T> CreateArraySortHelper()
{
if (typeof(IComparable<T>).IsAssignableFrom(typeof(T)))
@@ -81,7 +80,7 @@ namespace System.Collections.Generic
}
else
{
- defaultArraySortHelper = new ArraySortHelper<T>();
+ defaultArraySortHelper = new ArraySortHelper<T>();
}
return defaultArraySortHelper;
}
@@ -91,7 +90,7 @@ namespace System.Collections.Generic
public void Sort(T[] keys, int index, int length, IComparer<T> comparer)
{
Debug.Assert(keys != null, "Check the arguments in the caller!");
- Debug.Assert( index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!");
+ Debug.Assert(index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!");
// Add a try block here to detect IComparers (or their
// underlying IComparables, etc) that are bogus.
@@ -110,7 +109,7 @@ namespace System.Collections.Generic
}
catch (Exception e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e);
+ throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
}
}
@@ -127,7 +126,7 @@ namespace System.Collections.Generic
}
catch (Exception e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e);
+ throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
}
}
@@ -150,7 +149,7 @@ namespace System.Collections.Generic
}
catch (Exception e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e);
+ throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
}
}
@@ -241,9 +240,9 @@ namespace System.Collections.Generic
}
if (partitionSize == 3)
{
- SwapIfGreater(keys, comparer, lo, hi-1);
+ SwapIfGreater(keys, comparer, lo, hi - 1);
SwapIfGreater(keys, comparer, lo, hi);
- SwapIfGreater(keys, comparer, hi-1, hi);
+ SwapIfGreater(keys, comparer, hi - 1, hi);
return;
}
@@ -375,7 +374,7 @@ namespace System.Collections.Generic
where T : IComparable<T>
{
// Do not add a constructor to this class because ArraySortHelper<T>.CreateSortHelper will not execute it
-
+
#region IArraySortHelper<T> Members
public void Sort(T[] keys, int index, int length, IComparer<T> comparer)
@@ -400,7 +399,7 @@ namespace System.Collections.Generic
}
catch (Exception e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e);
+ throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
}
}
@@ -422,7 +421,7 @@ namespace System.Collections.Generic
}
catch (Exception e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e);
+ throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
}
}
@@ -485,7 +484,7 @@ namespace System.Collections.Generic
private static void Swap(T[] a, int i, int j)
{
- if(i!=j)
+ if (i != j)
{
T t = a[i];
a[i] = a[j];
@@ -529,9 +528,9 @@ namespace System.Collections.Generic
}
if (partitionSize == 3)
{
- SwapIfGreaterWithItems(keys, lo, hi-1);
+ SwapIfGreaterWithItems(keys, lo, hi - 1);
SwapIfGreaterWithItems(keys, lo, hi);
- SwapIfGreaterWithItems(keys, hi-1, hi);
+ SwapIfGreaterWithItems(keys, hi - 1, hi);
return;
}
@@ -662,7 +661,7 @@ namespace System.Collections.Generic
}
}
-#endregion
+ #endregion
#region ArraySortHelper for paired key and value arrays
@@ -675,7 +674,7 @@ namespace System.Collections.Generic
internal class ArraySortHelper<TKey, TValue>
: IArraySortHelper<TKey, TValue>
{
- static volatile IArraySortHelper<TKey, TValue> defaultArraySortHelper;
+ private static volatile IArraySortHelper<TKey, TValue> defaultArraySortHelper;
public static IArraySortHelper<TKey, TValue> Default
{
@@ -724,7 +723,7 @@ namespace System.Collections.Generic
}
catch (Exception e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e);
+ throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
}
}
@@ -755,12 +754,12 @@ namespace System.Collections.Generic
private static void Swap(TKey[] keys, TValue[] values, int i, int j)
{
- if(i!=j)
+ if (i != j)
{
TKey k = keys[i];
keys[i] = keys[j];
keys[j] = k;
- if(values != null)
+ if (values != null)
{
TValue v = values[i];
values[i] = values[j];
@@ -810,9 +809,9 @@ namespace System.Collections.Generic
}
if (partitionSize == 3)
{
- SwapIfGreaterWithItems(keys, values, comparer, lo, hi-1);
+ SwapIfGreaterWithItems(keys, values, comparer, lo, hi - 1);
SwapIfGreaterWithItems(keys, values, comparer, lo, hi);
- SwapIfGreaterWithItems(keys, values, comparer, hi-1, hi);
+ SwapIfGreaterWithItems(keys, values, comparer, hi - 1, hi);
return;
}
@@ -913,12 +912,12 @@ namespace System.Collections.Generic
if (!(comparer.Compare(d, keys[lo + child - 1]) < 0))
break;
keys[lo + i - 1] = keys[lo + child - 1];
- if(values != null)
+ if (values != null)
values[lo + i - 1] = values[lo + child - 1];
i = child;
}
keys[lo + i - 1] = d;
- if(values != null)
+ if (values != null)
values[lo + i - 1] = dValue;
}
@@ -942,12 +941,12 @@ namespace System.Collections.Generic
while (j >= lo && comparer.Compare(t, keys[j]) < 0)
{
keys[j + 1] = keys[j];
- if(values != null)
+ if (values != null)
values[j + 1] = values[j];
j--;
}
keys[j + 1] = t;
- if(values != null)
+ if (values != null)
values[j + 1] = tValue;
}
}
@@ -960,8 +959,8 @@ namespace System.Collections.Generic
public void Sort(TKey[] keys, TValue[] values, int index, int length, IComparer<TKey> comparer)
{
Debug.Assert(keys != null, "Check the arguments in the caller!");
- Debug.Assert( index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!");
-
+ Debug.Assert(index >= 0 && length >= 0 && (keys.Length - index >= length), "Check the arguments in the caller!");
+
// Add a try block here to detect IComparers (or their
// underlying IComparables, etc) that are bogus.
try
@@ -974,14 +973,14 @@ namespace System.Collections.Generic
{
ArraySortHelper<TKey, TValue>.IntrospectiveSort(keys, values, index, length, comparer);
}
- }
+ }
catch (IndexOutOfRangeException)
{
IntrospectiveSortUtilities.ThrowOrIgnoreBadComparer(comparer);
}
catch (Exception e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), e);
+ throw new InvalidOperationException(SR.InvalidOperation_IComparerFailed, e);
}
}
@@ -1006,12 +1005,12 @@ namespace System.Collections.Generic
private static void Swap(TKey[] keys, TValue[] values, int i, int j)
{
- if(i != j)
+ if (i != j)
{
TKey k = keys[i];
keys[i] = keys[j];
keys[j] = k;
- if(values != null)
+ if (values != null)
{
TValue v = values[i];
values[i] = values[j];
@@ -1059,9 +1058,9 @@ namespace System.Collections.Generic
}
if (partitionSize == 3)
{
- SwapIfGreaterWithItems(keys, values, lo, hi-1);
+ SwapIfGreaterWithItems(keys, values, lo, hi - 1);
SwapIfGreaterWithItems(keys, values, lo, hi);
- SwapIfGreaterWithItems(keys, values, hi-1, hi);
+ SwapIfGreaterWithItems(keys, values, hi - 1, hi);
return;
}
@@ -1106,10 +1105,10 @@ namespace System.Collections.Generic
while (left < right)
{
- if(pivot == null)
+ if (pivot == null)
{
while (left < (hi - 1) && keys[++left] == null) ;
- while (right > lo && keys[--right] != null);
+ while (right > lo && keys[--right] != null) ;
}
else
{
@@ -1167,12 +1166,12 @@ namespace System.Collections.Generic
if (keys[lo + child - 1] == null || keys[lo + child - 1].CompareTo(d) < 0)
break;
keys[lo + i - 1] = keys[lo + child - 1];
- if(values != null)
+ if (values != null)
values[lo + i - 1] = values[lo + child - 1];
i = child;
}
keys[lo + i - 1] = d;
- if(values != null)
+ if (values != null)
values[lo + i - 1] = dValue;
}
@@ -1191,16 +1190,16 @@ namespace System.Collections.Generic
{
j = i;
t = keys[i + 1];
- tValue = (values != null)? values[i + 1] : default(TValue);
+ tValue = (values != null) ? values[i + 1] : default(TValue);
while (j >= lo && (t == null || t.CompareTo(keys[j]) < 0))
{
keys[j + 1] = keys[j];
- if(values != null)
+ if (values != null)
values[j + 1] = values[j];
j--;
}
keys[j + 1] = t;
- if(values != null)
+ if (values != null)
values[j + 1] = tValue;
}
}
diff --git a/src/mscorlib/src/System/Collections/Generic/Comparer.cs b/src/mscorlib/src/System/Collections/Generic/Comparer.cs
index 056843a606..a9b4b3f0dd 100644
--- a/src/mscorlib/src/System/Collections/Generic/Comparer.cs
+++ b/src/mscorlib/src/System/Collections/Generic/Comparer.cs
@@ -15,19 +15,14 @@ using System.Security;
using System.Runtime.Serialization;
namespace System.Collections.Generic
-{
+{
[Serializable]
- [TypeDependencyAttribute("System.Collections.Generic.ObjectComparer`1")]
+ [TypeDependencyAttribute("System.Collections.Generic.ObjectComparer`1")]
public abstract class Comparer<T> : IComparer, IComparer<T>
{
- static readonly Comparer<T> defaultComparer = CreateComparer();
-
- public static Comparer<T> Default {
- get {
- Contract.Ensures(Contract.Result<Comparer<T>>() != null);
- return defaultComparer;
- }
- }
+ // To minimize generic instantiation overhead of creating the comparer per type, we keep the generic portion of the code as small
+ // as possible and define most of the creation logic in a non-generic class.
+ public static Comparer<T> Default { get; } = (Comparer<T>)ComparerHelpers.CreateDefaultComparer(typeof(T));
public static Comparer<T> Create(Comparison<T> comparison)
{
@@ -39,69 +34,10 @@ namespace System.Collections.Generic
return new ComparisonComparer<T>(comparison);
}
- //
- // Note that logic in this method is replicated in vm\compile.cpp to ensure that NGen
- // saves the right instantiations
- //
- private static Comparer<T> CreateComparer()
- {
- object result = null;
- RuntimeType t = (RuntimeType)typeof(T);
-
- // If T implements IComparable<T> return a GenericComparer<T>
- if (typeof(IComparable<T>).IsAssignableFrom(t))
- {
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericComparer<int>), t);
- }
- else if (default(T) == null)
- {
- // If T is a Nullable<U> where U implements IComparable<U> return a NullableComparer<U>
- if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) {
- RuntimeType u = (RuntimeType)t.GetGenericArguments()[0];
- if (typeof(IComparable<>).MakeGenericType(u).IsAssignableFrom(u)) {
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableComparer<int>), u);
- }
- }
- }
- else if (t.IsEnum)
- {
- // Explicitly call Enum.GetUnderlyingType here. Although GetTypeCode
- // ends up doing this anyway, we end up avoiding an unnecessary P/Invoke
- // and virtual method call.
- TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(t));
-
- // Depending on the enum type, we need to special case the comparers so that we avoid boxing
- // Specialize differently for signed/unsigned types so we avoid problems with large numbers
- switch (underlyingTypeCode)
- {
- case TypeCode.SByte:
- case TypeCode.Int16:
- case TypeCode.Int32:
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(Int32EnumComparer<int>), t);
- break;
- case TypeCode.Byte:
- case TypeCode.UInt16:
- case TypeCode.UInt32:
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(UInt32EnumComparer<uint>), t);
- break;
- // 64-bit enums: use UnsafeEnumCastLong
- case TypeCode.Int64:
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(Int64EnumComparer<long>), t);
- break;
- case TypeCode.UInt64:
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(UInt64EnumComparer<ulong>), t);
- break;
- }
- }
-
- return result != null ?
- (Comparer<T>)result :
- new ObjectComparer<T>(); // Fallback to ObjectComparer, which uses boxing
- }
-
public abstract int Compare(T x, T y);
- int IComparer.Compare(object x, object y) {
+ int IComparer.Compare(object x, object y)
+ {
if (x == null) return y == null ? 0 : -1;
if (y == null) return 1;
if (x is T && y is T) return Compare((T)x, (T)y);
@@ -109,18 +45,20 @@ namespace System.Collections.Generic
return 0;
}
}
-
+
// Note: although there is a lot of shared code in the following
// comparers, we do not incorporate it into a base class for perf
// reasons. Adding another base class (even one with no fields)
// means another generic instantiation, which can be costly esp.
// for value types.
-
+
[Serializable]
internal sealed class GenericComparer<T> : Comparer<T> where T : IComparable<T>
- {
- public override int Compare(T x, T y) {
- if (x != null) {
+ {
+ public override int Compare(T x, T y)
+ {
+ if (x != null)
+ {
if (y != null) return x.CompareTo(y);
return 1;
}
@@ -139,8 +77,10 @@ namespace System.Collections.Generic
[Serializable]
internal sealed class NullableComparer<T> : Comparer<T?> where T : struct, IComparable<T>
{
- public override int Compare(T? x, T? y) {
- if (x.HasValue) {
+ public override int Compare(T? x, T? y)
+ {
+ if (x.HasValue)
+ {
if (y.HasValue) return x.value.CompareTo(y.value);
return 1;
}
@@ -159,7 +99,8 @@ namespace System.Collections.Generic
[Serializable]
internal sealed class ObjectComparer<T> : Comparer<T>
{
- public override int Compare(T x, T y) {
+ public override int Compare(T x, T y)
+ {
return System.Collections.Comparer.Default.Compare(x, y);
}
@@ -176,11 +117,13 @@ namespace System.Collections.Generic
{
private readonly Comparison<T> _comparison;
- public ComparisonComparer(Comparison<T> comparison) {
+ public ComparisonComparer(Comparison<T> comparison)
+ {
_comparison = comparison;
}
- public override int Compare(T x, T y) {
+ public override int Compare(T x, T y)
+ {
return _comparison(x, y);
}
}
@@ -196,12 +139,12 @@ namespace System.Collections.Generic
{
public Int32EnumComparer()
{
- Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
+ Debug.Assert(typeof(T).IsEnum);
}
-
+
// Used by the serialization engine.
private Int32EnumComparer(SerializationInfo info, StreamingContext context) { }
-
+
public override int Compare(T x, T y)
{
int ix = JitHelpers.UnsafeEnumCast(x);
@@ -231,12 +174,12 @@ namespace System.Collections.Generic
{
public UInt32EnumComparer()
{
- Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
+ Debug.Assert(typeof(T).IsEnum);
}
-
+
// Used by the serialization engine.
private UInt32EnumComparer(SerializationInfo info, StreamingContext context) { }
-
+
public override int Compare(T x, T y)
{
uint ix = (uint)JitHelpers.UnsafeEnumCast(x);
@@ -262,9 +205,9 @@ namespace System.Collections.Generic
{
public Int64EnumComparer()
{
- Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
+ Debug.Assert(typeof(T).IsEnum);
}
-
+
public override int Compare(T x, T y)
{
long lx = JitHelpers.UnsafeEnumCastLong(x);
@@ -290,12 +233,12 @@ namespace System.Collections.Generic
{
public UInt64EnumComparer()
{
- Debug.Assert(typeof(T).IsEnum, "This type is only intended to be used to compare enums!");
+ Debug.Assert(typeof(T).IsEnum);
}
-
+
// Used by the serialization engine.
private UInt64EnumComparer(SerializationInfo info, StreamingContext context) { }
-
+
public override int Compare(T x, T y)
{
ulong lx = (ulong)JitHelpers.UnsafeEnumCastLong(x);
diff --git a/src/mscorlib/src/System/Collections/Generic/ComparerHelpers.cs b/src/mscorlib/src/System/Collections/Generic/ComparerHelpers.cs
new file mode 100644
index 0000000000..3e428413d4
--- /dev/null
+++ b/src/mscorlib/src/System/Collections/Generic/ComparerHelpers.cs
@@ -0,0 +1,210 @@
+// 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.Diagnostics;
+using static System.RuntimeTypeHandle;
+
+namespace System.Collections.Generic
+{
+ /// <summary>
+ /// Helper class for creating the default <see cref="Comparer{T}"/> and <see cref="EqualityComparer{T}"/>.
+ /// </summary>
+ /// <remarks>
+ /// This class is intentionally type-unsafe and non-generic to minimize the generic instantiation overhead of creating
+ /// the default comparer/equality comparer for a new type parameter. Efficiency of the methods in here does not matter too
+ /// much since they will only be run once per type parameter, but generic code involved in creating the comparers needs to be
+ /// kept to a minimum.
+ /// </remarks>
+ internal static class ComparerHelpers
+ {
+ /// <summary>
+ /// Creates the default <see cref="Comparer{T}"/>.
+ /// </summary>
+ /// <param name="type">The type to create the default comparer for.</param>
+ /// <remarks>
+ /// The logic in this method is replicated in vm/compile.cpp to ensure that NGen saves the right instantiations.
+ /// </remarks>
+ internal static object CreateDefaultComparer(Type type)
+ {
+ Debug.Assert(type != null && type is RuntimeType);
+
+ object result = null;
+ var runtimeType = (RuntimeType)type;
+
+ // If T implements IComparable<T> return a GenericComparer<T>
+ if (typeof(IComparable<>).MakeGenericType(type).IsAssignableFrom(type))
+ {
+ result = CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericComparer<int>), runtimeType);
+ }
+ // Nullable does not implement IComparable<T?> directly because that would add an extra interface call per comparison.
+ // Instead, it relies on Comparer<T?>.Default to specialize for nullables and do the lifted comparisons if T implements IComparable.
+ else if (type.IsGenericType)
+ {
+ if (type.GetGenericTypeDefinition() == typeof(Nullable<>))
+ {
+ result = TryCreateNullableComparer(runtimeType);
+ }
+ }
+ // The comparer for enums is specialized to avoid boxing.
+ else if (type.IsEnum)
+ {
+ result = TryCreateEnumComparer(runtimeType);
+ }
+
+ return result ?? CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ObjectComparer<object>), runtimeType);
+ }
+
+ /// <summary>
+ /// Creates the default <see cref="Comparer{T}"/> for a nullable type.
+ /// </summary>
+ /// <param name="nullableType">The nullable type to create the default comparer for.</param>
+ private static object TryCreateNullableComparer(RuntimeType nullableType)
+ {
+ Debug.Assert(nullableType != null);
+ Debug.Assert(nullableType.IsGenericType && nullableType.GetGenericTypeDefinition() == typeof(Nullable<>));
+
+ var embeddedType = (RuntimeType)nullableType.GetGenericArguments()[0];
+
+ if (typeof(IComparable<>).MakeGenericType(embeddedType).IsAssignableFrom(embeddedType))
+ {
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableComparer<int>), embeddedType);
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Creates the default <see cref="Comparer{T}"/> for an enum type.
+ /// </summary>
+ /// <param name="enumType">The enum type to create the default comparer for.</param>
+ private static object TryCreateEnumComparer(RuntimeType enumType)
+ {
+ Debug.Assert(enumType != null);
+ Debug.Assert(enumType.IsEnum);
+
+ // Explicitly call Enum.GetUnderlyingType here. Although GetTypeCode
+ // ends up doing this anyway, we end up avoiding an unnecessary P/Invoke
+ // and virtual method call.
+ TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(enumType));
+
+ // Depending on the enum type, we need to special case the comparers so that we avoid boxing.
+ // Specialize differently for signed/unsigned types so we avoid problems with large numbers.
+ switch (underlyingTypeCode)
+ {
+ case TypeCode.SByte:
+ case TypeCode.Int16:
+ case TypeCode.Int32:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(Int32EnumComparer<int>), enumType);
+ case TypeCode.Byte:
+ case TypeCode.UInt16:
+ case TypeCode.UInt32:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(UInt32EnumComparer<uint>), enumType);
+ // 64-bit enums: Use `UnsafeEnumCastLong`
+ case TypeCode.Int64:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(Int64EnumComparer<long>), enumType);
+ case TypeCode.UInt64:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(UInt64EnumComparer<ulong>), enumType);
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Creates the default <see cref="EqualityComparer{T}"/>.
+ /// </summary>
+ /// <param name="type">The type to create the default equality comparer for.</param>
+ /// <remarks>
+ /// The logic in this method is replicated in vm/compile.cpp to ensure that NGen saves the right instantiations.
+ /// </remarks>
+ internal static object CreateDefaultEqualityComparer(Type type)
+ {
+ Debug.Assert(type != null && type is RuntimeType);
+
+ object result = null;
+ var runtimeType = (RuntimeType)type;
+
+ // Specialize for byte so Array.IndexOf is faster.
+ if (type == typeof(byte))
+ {
+ result = new ByteEqualityComparer();
+ }
+ // If T implements IEquatable<T> return a GenericEqualityComparer<T>
+ else if (typeof(IEquatable<>).MakeGenericType(type).IsAssignableFrom(type))
+ {
+ result = CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericEqualityComparer<int>), runtimeType);
+ }
+ // Nullable does not implement IEquatable<T?> directly because that would add an extra interface call per comparison.
+ // Instead, it relies on EqualityComparer<T?>.Default to specialize for nullables and do the lifted comparisons if T implements IEquatable.
+ else if (type.IsGenericType)
+ {
+ if (type.GetGenericTypeDefinition() == typeof(Nullable<>))
+ {
+ result = TryCreateNullableEqualityComparer(runtimeType);
+ }
+ }
+ // The equality comparer for enums is specialized to avoid boxing.
+ else if (type.IsEnum)
+ {
+ result = TryCreateEnumEqualityComparer(runtimeType);
+ }
+
+ return result ?? CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ObjectEqualityComparer<object>), runtimeType);
+ }
+
+ /// <summary>
+ /// Creates the default <see cref="EqualityComparer{T}"/> for a nullable type.
+ /// </summary>
+ /// <param name="nullableType">The nullable type to create the default equality comparer for.</param>
+ private static object TryCreateNullableEqualityComparer(RuntimeType nullableType)
+ {
+ Debug.Assert(nullableType != null);
+ Debug.Assert(nullableType.IsGenericType && nullableType.GetGenericTypeDefinition() == typeof(Nullable<>));
+
+ var embeddedType = (RuntimeType)nullableType.GetGenericArguments()[0];
+
+ if (typeof(IEquatable<>).MakeGenericType(embeddedType).IsAssignableFrom(embeddedType))
+ {
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableEqualityComparer<int>), embeddedType);
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Creates the default <see cref="EqualityComparer{T}"/> for an enum type.
+ /// </summary>
+ /// <param name="enumType">The enum type to create the default equality comparer for.</param>
+ private static object TryCreateEnumEqualityComparer(RuntimeType enumType)
+ {
+ Debug.Assert(enumType != null);
+ Debug.Assert(enumType.IsEnum);
+
+ // See the METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST and METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST_LONG cases in getILIntrinsicImplementation
+ // for how we cast the enum types to integral values in the comparer without boxing.
+
+ TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(enumType));
+
+ // Depending on the enum type, we need to special case the comparers so that we avoid boxing.
+ // Note: We have different comparers for short and sbyte, since for those types GetHashCode does not simply return the value.
+ // We need to preserve what they would return.
+ switch (underlyingTypeCode)
+ {
+ case TypeCode.Int16:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ShortEnumEqualityComparer<short>), enumType);
+ case TypeCode.SByte:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(SByteEnumEqualityComparer<sbyte>), enumType);
+ case TypeCode.Int32:
+ case TypeCode.UInt32:
+ case TypeCode.Byte:
+ case TypeCode.UInt16:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer<int>), enumType);
+ case TypeCode.Int64:
+ case TypeCode.UInt64:
+ return RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(LongEnumEqualityComparer<long>), enumType);
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Collections/Generic/DebugView.cs b/src/mscorlib/src/System/Collections/Generic/DebugView.cs
index 27c5011147..dc487c1411 100644
--- a/src/mscorlib/src/System/Collections/Generic/DebugView.cs
+++ b/src/mscorlib/src/System/Collections/Generic/DebugView.cs
@@ -13,116 +13,112 @@
**
=============================================================================*/
-namespace System.Collections.Generic {
- using System;
- using System.Collections.ObjectModel;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
+using System;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+namespace System.Collections.Generic
+{
//
// VS IDE can't differentiate between types with the same name from different
// assembly. So we need to use different names for collection debug view for
// collections in mscorlib.dll and system.dll.
//
- internal sealed class Mscorlib_CollectionDebugView<T> {
- private ICollection<T> collection;
-
- public Mscorlib_CollectionDebugView(ICollection<T> collection) {
+ internal sealed class Mscorlib_CollectionDebugView<T>
+ {
+ private ICollection<T> collection;
+
+ public Mscorlib_CollectionDebugView(ICollection<T> collection)
+ {
if (collection == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
- this.collection = collection;
+ this.collection = collection;
}
-
+
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
- public T[] Items {
- get {
+ public T[] Items
+ {
+ get
+ {
T[] items = new T[collection.Count];
collection.CopyTo(items, 0);
return items;
}
}
- }
+ }
- internal sealed class Mscorlib_DictionaryKeyCollectionDebugView<TKey, TValue> {
- private ICollection<TKey> collection;
-
- public Mscorlib_DictionaryKeyCollectionDebugView(ICollection<TKey> collection) {
+ internal sealed class Mscorlib_DictionaryKeyCollectionDebugView<TKey, TValue>
+ {
+ private ICollection<TKey> collection;
+
+ public Mscorlib_DictionaryKeyCollectionDebugView(ICollection<TKey> collection)
+ {
if (collection == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
- this.collection = collection;
+ this.collection = collection;
}
-
+
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
- public TKey[] Items {
- get {
+ public TKey[] Items
+ {
+ get
+ {
TKey[] items = new TKey[collection.Count];
collection.CopyTo(items, 0);
return items;
}
}
- }
+ }
- internal sealed class Mscorlib_DictionaryValueCollectionDebugView<TKey, TValue> {
- private ICollection<TValue> collection;
-
- public Mscorlib_DictionaryValueCollectionDebugView(ICollection<TValue> collection) {
+ internal sealed class Mscorlib_DictionaryValueCollectionDebugView<TKey, TValue>
+ {
+ private ICollection<TValue> collection;
+
+ public Mscorlib_DictionaryValueCollectionDebugView(ICollection<TValue> collection)
+ {
if (collection == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
- this.collection = collection;
+ this.collection = collection;
}
-
+
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
- public TValue[] Items {
- get {
+ public TValue[] Items
+ {
+ get
+ {
TValue[] items = new TValue[collection.Count];
collection.CopyTo(items, 0);
return items;
}
}
- }
+ }
+
+ internal sealed class Mscorlib_DictionaryDebugView<K, V>
+ {
+ private IDictionary<K, V> dict;
- internal sealed class Mscorlib_DictionaryDebugView<K, V> {
- private IDictionary<K, V> dict;
-
- public Mscorlib_DictionaryDebugView(IDictionary<K, V> dictionary) {
+ public Mscorlib_DictionaryDebugView(IDictionary<K, V> dictionary)
+ {
if (dictionary == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
- this.dict = dictionary;
+ dict = dictionary;
}
-
+
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
- public KeyValuePair<K, V>[] Items {
- get {
+ public KeyValuePair<K, V>[] Items
+ {
+ get
+ {
KeyValuePair<K, V>[] items = new KeyValuePair<K, V>[dict.Count];
dict.CopyTo(items, 0);
return items;
}
}
- }
-
- internal sealed class Mscorlib_KeyedCollectionDebugView<K, T> {
- private KeyedCollection<K, T> kc;
-
- public Mscorlib_KeyedCollectionDebugView(KeyedCollection<K, T> keyedCollection) {
- if (keyedCollection == null) {
- throw new ArgumentNullException(nameof(keyedCollection));
- }
- Contract.EndContractBlock();
+ }
- kc = keyedCollection;
- }
-
- [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
- public T[] Items {
- get {
- T[] items = new T[kc.Count];
- kc.CopyTo(items, 0);
- return items;
- }
- }
- }
}
diff --git a/src/mscorlib/src/System/Collections/Generic/Dictionary.cs b/src/mscorlib/src/System/Collections/Generic/Dictionary.cs
index 7b60e31031..409b23b541 100644
--- a/src/mscorlib/src/System/Collections/Generic/Dictionary.cs
+++ b/src/mscorlib/src/System/Collections/Generic/Dictionary.cs
@@ -41,20 +41,43 @@
** to serialization such that this code doesn't need to build in
** silverlight.
===========================================================*/
-namespace System.Collections.Generic {
+namespace System.Collections.Generic
+{
using System;
using System.Collections;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.Serialization;
+ /// <summary>
+ /// Used internally to control behavior of insertion into a <see cref="Dictionary{TKey, TValue}"/>.
+ /// </summary>
+ internal enum InsertionBehavior : byte
+ {
+ /// <summary>
+ /// The default insertion behavior.
+ /// </summary>
+ None = 0,
+
+ /// <summary>
+ /// Specifies that an existing entry with the same key should be overwritten if encountered.
+ /// </summary>
+ OverwriteExisting = 1,
+
+ /// <summary>
+ /// Specifies that if an existing entry with the same key is encountered, an exception should be thrown.
+ /// </summary>
+ ThrowOnExisting = 2
+ }
+
[DebuggerTypeProxy(typeof(Mscorlib_DictionaryDebugView<,>))]
[DebuggerDisplay("Count = {Count}")]
[Serializable]
- public class Dictionary<TKey,TValue>: IDictionary<TKey,TValue>, IDictionary, IReadOnlyDictionary<TKey, TValue>, ISerializable, IDeserializationCallback {
-
- private struct Entry {
+ public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, IReadOnlyDictionary<TKey, TValue>, ISerializable, IDeserializationCallback
+ {
+ private struct Entry
+ {
public int hashCode; // Lower 31 bits of hash code, -1 if unused
public int next; // Index of next entry, -1 if last
public TKey key; // Key of entry
@@ -71,38 +94,40 @@ namespace System.Collections.Generic {
private KeyCollection keys;
private ValueCollection values;
private Object _syncRoot;
-
+
// constants for serialization
private const String VersionName = "Version";
private const String HashSizeName = "HashSize"; // Must save buckets.Length
private const String KeyValuePairsName = "KeyValuePairs";
private const String ComparerName = "Comparer";
- public Dictionary(): this(0, null) {}
+ public Dictionary() : this(0, null) { }
- public Dictionary(int capacity): this(capacity, null) {}
+ public Dictionary(int capacity) : this(capacity, null) { }
- public Dictionary(IEqualityComparer<TKey> comparer): this(0, comparer) {}
+ public Dictionary(IEqualityComparer<TKey> comparer) : this(0, comparer) { }
- public Dictionary(int capacity, IEqualityComparer<TKey> comparer) {
+ public Dictionary(int capacity, IEqualityComparer<TKey> comparer)
+ {
if (capacity < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity);
if (capacity > 0) Initialize(capacity);
this.comparer = comparer ?? EqualityComparer<TKey>.Default;
#if FEATURE_RANDOMIZED_STRING_HASHING
- if (HashHelpers.s_UseRandomizedStringHashing && comparer == EqualityComparer<string>.Default)
+ if (HashHelpers.s_UseRandomizedStringHashing && this.comparer == EqualityComparer<string>.Default)
{
- this.comparer = (IEqualityComparer<TKey>) NonRandomizedStringEqualityComparer.Default;
+ this.comparer = (IEqualityComparer<TKey>)NonRandomizedStringEqualityComparer.Default;
}
#endif // FEATURE_RANDOMIZED_STRING_HASHING
}
- public Dictionary(IDictionary<TKey,TValue> dictionary): this(dictionary, null) {}
-
- public Dictionary(IDictionary<TKey,TValue> dictionary, IEqualityComparer<TKey> comparer):
- this(dictionary != null? dictionary.Count: 0, comparer) {
+ public Dictionary(IDictionary<TKey, TValue> dictionary) : this(dictionary, null) { }
- if( dictionary == null) {
+ public Dictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer) :
+ this(dictionary != null ? dictionary.Count : 0, comparer)
+ {
+ if (dictionary == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
}
@@ -110,138 +135,174 @@ namespace System.Collections.Generic {
// avoid the enumerator allocation and overhead by looping through the entries array directly.
// We only do this when dictionary is Dictionary<TKey,TValue> and not a subclass, to maintain
// back-compat with subclasses that may have overridden the enumerator behavior.
- if (dictionary.GetType() == typeof(Dictionary<TKey,TValue>)) {
- Dictionary<TKey,TValue> d = (Dictionary<TKey,TValue>)dictionary;
+ if (dictionary.GetType() == typeof(Dictionary<TKey, TValue>))
+ {
+ Dictionary<TKey, TValue> d = (Dictionary<TKey, TValue>)dictionary;
int count = d.count;
Entry[] entries = d.entries;
- for (int i = 0; i < count; i++) {
- if (entries[i].hashCode >= 0) {
+ for (int i = 0; i < count; i++)
+ {
+ if (entries[i].hashCode >= 0)
+ {
Add(entries[i].key, entries[i].value);
}
}
return;
}
- foreach (KeyValuePair<TKey,TValue> pair in dictionary) {
+ foreach (KeyValuePair<TKey, TValue> pair in dictionary)
+ {
Add(pair.Key, pair.Value);
}
}
- public Dictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection):
- this(collection, null) { }
+ public Dictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection) :
+ this(collection, null)
+ { }
- public Dictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer):
+ public Dictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer) :
this((collection as ICollection<KeyValuePair<TKey, TValue>>)?.Count ?? 0, comparer)
{
- if (collection == null) {
+ if (collection == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
- foreach (KeyValuePair<TKey, TValue> pair in collection) {
+ foreach (KeyValuePair<TKey, TValue> pair in collection)
+ {
Add(pair.Key, pair.Value);
}
}
- protected Dictionary(SerializationInfo info, StreamingContext context) {
+ protected Dictionary(SerializationInfo info, StreamingContext context)
+ {
//We can't do anything with the keys and values until the entire graph has been deserialized
//and we have a resonable estimate that GetHashCode is not going to fail. For the time being,
//we'll just cache this. The graph is not valid until OnDeserialization has been called.
HashHelpers.SerializationInfoTable.Add(this, info);
}
-
- public IEqualityComparer<TKey> Comparer {
- get {
- return comparer;
- }
+
+ public IEqualityComparer<TKey> Comparer
+ {
+ get
+ {
+ return comparer;
+ }
}
-
- public int Count {
+
+ public int Count
+ {
get { return count - freeCount; }
}
- public KeyCollection Keys {
- get {
+ public KeyCollection Keys
+ {
+ get
+ {
Contract.Ensures(Contract.Result<KeyCollection>() != null);
if (keys == null) keys = new KeyCollection(this);
return keys;
}
}
- ICollection<TKey> IDictionary<TKey, TValue>.Keys {
- get {
- if (keys == null) keys = new KeyCollection(this);
+ ICollection<TKey> IDictionary<TKey, TValue>.Keys
+ {
+ get
+ {
+ if (keys == null) keys = new KeyCollection(this);
return keys;
}
}
- IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys {
- get {
- if (keys == null) keys = new KeyCollection(this);
+ IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys
+ {
+ get
+ {
+ if (keys == null) keys = new KeyCollection(this);
return keys;
}
}
- public ValueCollection Values {
- get {
+ public ValueCollection Values
+ {
+ get
+ {
Contract.Ensures(Contract.Result<ValueCollection>() != null);
if (values == null) values = new ValueCollection(this);
return values;
}
}
- ICollection<TValue> IDictionary<TKey, TValue>.Values {
- get {
+ ICollection<TValue> IDictionary<TKey, TValue>.Values
+ {
+ get
+ {
if (values == null) values = new ValueCollection(this);
return values;
}
}
- IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values {
- get {
+ IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values
+ {
+ get
+ {
if (values == null) values = new ValueCollection(this);
return values;
}
}
- public TValue this[TKey key] {
- get {
+ public TValue this[TKey key]
+ {
+ get
+ {
int i = FindEntry(key);
if (i >= 0) return entries[i].value;
ThrowHelper.ThrowKeyNotFoundException();
return default(TValue);
}
- set {
- Insert(key, value, false);
+ set
+ {
+ bool modified = TryInsert(key, value, InsertionBehavior.OverwriteExisting);
+ Debug.Assert(modified);
}
}
- public void Add(TKey key, TValue value) {
- Insert(key, value, true);
+ public void Add(TKey key, TValue value)
+ {
+ bool modified = TryInsert(key, value, InsertionBehavior.ThrowOnExisting);
+ Debug.Assert(modified); // If there was an existing key and the Add failed, an exception will already have been thrown.
}
- void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> keyValuePair) {
+ void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> keyValuePair)
+ {
Add(keyValuePair.Key, keyValuePair.Value);
}
- bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> keyValuePair) {
+ bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> keyValuePair)
+ {
int i = FindEntry(keyValuePair.Key);
- if( i >= 0 && EqualityComparer<TValue>.Default.Equals(entries[i].value, keyValuePair.Value)) {
+ if (i >= 0 && EqualityComparer<TValue>.Default.Equals(entries[i].value, keyValuePair.Value))
+ {
return true;
}
return false;
}
- bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> keyValuePair) {
+ bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> keyValuePair)
+ {
int i = FindEntry(keyValuePair.Key);
- if( i >= 0 && EqualityComparer<TValue>.Default.Equals(entries[i].value, keyValuePair.Value)) {
+ if (i >= 0 && EqualityComparer<TValue>.Default.Equals(entries[i].value, keyValuePair.Value))
+ {
Remove(keyValuePair.Key);
return true;
}
return false;
}
- public void Clear() {
- if (count > 0) {
+ public void Clear()
+ {
+ if (count > 0)
+ {
for (int i = 0; i < buckets.Length; i++) buckets[i] = -1;
Array.Clear(entries, 0, count);
freeList = -1;
@@ -251,90 +312,106 @@ namespace System.Collections.Generic {
}
}
- public bool ContainsKey(TKey key) {
+ public bool ContainsKey(TKey key)
+ {
return FindEntry(key) >= 0;
}
- public bool ContainsValue(TValue value) {
- if (value == null) {
- for (int i = 0; i < count; i++) {
+ public bool ContainsValue(TValue value)
+ {
+ if (value == null)
+ {
+ for (int i = 0; i < count; i++)
+ {
if (entries[i].hashCode >= 0 && entries[i].value == null) return true;
}
}
- else {
+ else
+ {
EqualityComparer<TValue> c = EqualityComparer<TValue>.Default;
- for (int i = 0; i < count; i++) {
+ for (int i = 0; i < count; i++)
+ {
if (entries[i].hashCode >= 0 && c.Equals(entries[i].value, value)) return true;
}
}
return false;
}
- private void CopyTo(KeyValuePair<TKey,TValue>[] array, int index) {
- if (array == null) {
+ private void CopyTo(KeyValuePair<TKey, TValue>[] array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
-
- if (index < 0 || index > array.Length ) {
+
+ if (index < 0 || index > array.Length)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < Count) {
+ if (array.Length - index < Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
int count = this.count;
Entry[] entries = this.entries;
- for (int i = 0; i < count; i++) {
- if (entries[i].hashCode >= 0) {
- array[index++] = new KeyValuePair<TKey,TValue>(entries[i].key, entries[i].value);
+ for (int i = 0; i < count; i++)
+ {
+ if (entries[i].hashCode >= 0)
+ {
+ array[index++] = new KeyValuePair<TKey, TValue>(entries[i].key, entries[i].value);
}
}
}
- public Enumerator GetEnumerator() {
+ public Enumerator GetEnumerator()
+ {
return new Enumerator(this, Enumerator.KeyValuePair);
}
- IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator() {
+ IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
+ {
return new Enumerator(this, Enumerator.KeyValuePair);
- }
+ }
- public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
+ public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.info);
}
info.AddValue(VersionName, version);
-
-#if FEATURE_RANDOMIZED_STRING_HASHING
- info.AddValue(ComparerName, HashHelpers.GetEqualityComparerForSerialization(comparer), typeof(IEqualityComparer<TKey>));
-#else
info.AddValue(ComparerName, comparer, typeof(IEqualityComparer<TKey>));
-#endif
-
info.AddValue(HashSizeName, buckets == null ? 0 : buckets.Length); //This is the length of the bucket array.
- if( buckets != null) {
+ if (buckets != null)
+ {
KeyValuePair<TKey, TValue>[] array = new KeyValuePair<TKey, TValue>[Count];
CopyTo(array, 0);
info.AddValue(KeyValuePairsName, array, typeof(KeyValuePair<TKey, TValue>[]));
}
}
- private int FindEntry(TKey key) {
- if( key == null) {
+ private int FindEntry(TKey key)
+ {
+ if (key == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
- if (buckets != null) {
+ if (buckets != null)
+ {
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
- for (int i = buckets[hashCode % buckets.Length]; i >= 0; i = entries[i].next) {
+ for (int i = buckets[hashCode % buckets.Length]; i >= 0; i = entries[i].next)
+ {
if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) return i;
}
}
return -1;
}
- private void Initialize(int capacity) {
+ private void Initialize(int capacity)
+ {
int size = HashHelpers.GetPrime(capacity);
buckets = new int[size];
for (int i = 0; i < buckets.Length; i++) buckets[i] = -1;
@@ -342,9 +419,10 @@ namespace System.Collections.Generic {
freeList = -1;
}
- private void Insert(TKey key, TValue value, bool add) {
-
- if( key == null ) {
+ private bool TryInsert(TKey key, TValue value, InsertionBehavior behavior)
+ {
+ if (key == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
@@ -356,27 +434,38 @@ namespace System.Collections.Generic {
int collisionCount = 0;
#endif
- for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next) {
- if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) {
- if (add) {
+ for (int i = buckets[targetBucket]; i >= 0; i = entries[i].next)
+ {
+ if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
+ {
+ if (behavior == InsertionBehavior.OverwriteExisting)
+ {
+ entries[i].value = value;
+ version++;
+ return true;
+ }
+
+ if (behavior == InsertionBehavior.ThrowOnExisting)
+ {
ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(key);
}
- entries[i].value = value;
- version++;
- return;
- }
+
+ return false;
+ }
#if FEATURE_RANDOMIZED_STRING_HASHING
collisionCount++;
#endif
}
int index;
- if (freeCount > 0) {
+ if (freeCount > 0)
+ {
index = freeList;
freeList = entries[index].next;
freeCount--;
}
- else {
+ else
+ {
if (count == entries.Length)
{
Resize();
@@ -399,52 +488,60 @@ namespace System.Collections.Generic {
// Note, randomized string hashing is turned on by default on coreclr so EqualityComparer<string>.Default will
// be using randomized string hashing
- if (collisionCount > HashHelpers.HashCollisionThreshold && comparer == NonRandomizedStringEqualityComparer.Default)
+ if (collisionCount > HashHelpers.HashCollisionThreshold && comparer == NonRandomizedStringEqualityComparer.Default)
{
- comparer = (IEqualityComparer<TKey>) EqualityComparer<string>.Default;
+ comparer = (IEqualityComparer<TKey>)EqualityComparer<string>.Default;
Resize(entries.Length, true);
}
#endif
+ return true;
}
- public virtual void OnDeserialization(Object sender) {
+ public virtual void OnDeserialization(Object sender)
+ {
SerializationInfo siInfo;
HashHelpers.SerializationInfoTable.TryGetValue(this, out siInfo);
-
- if (siInfo==null) {
+
+ if (siInfo == null)
+ {
// It might be necessary to call OnDeserialization from a container if the container object also implements
// OnDeserialization. However, remoting will call OnDeserialization again.
// We can return immediately if this function is called twice.
// Note we set remove the serialization info from the table at the end of this method.
return;
- }
-
+ }
+
int realVersion = siInfo.GetInt32(VersionName);
int hashsize = siInfo.GetInt32(HashSizeName);
- comparer = (IEqualityComparer<TKey>)siInfo.GetValue(ComparerName, typeof(IEqualityComparer<TKey>));
-
- if( hashsize != 0) {
+ comparer = (IEqualityComparer<TKey>)siInfo.GetValue(ComparerName, typeof(IEqualityComparer<TKey>));
+
+ if (hashsize != 0)
+ {
buckets = new int[hashsize];
for (int i = 0; i < buckets.Length; i++) buckets[i] = -1;
entries = new Entry[hashsize];
freeList = -1;
- KeyValuePair<TKey, TValue>[] array = (KeyValuePair<TKey, TValue>[])
+ KeyValuePair<TKey, TValue>[] array = (KeyValuePair<TKey, TValue>[])
siInfo.GetValue(KeyValuePairsName, typeof(KeyValuePair<TKey, TValue>[]));
- if (array==null) {
+ if (array == null)
+ {
ThrowHelper.ThrowSerializationException(ExceptionResource.Serialization_MissingKeys);
}
- for (int i=0; i<array.Length; i++) {
- if ( array[i].Key == null) {
+ for (int i = 0; i < array.Length; i++)
+ {
+ if (array[i].Key == null)
+ {
ThrowHelper.ThrowSerializationException(ExceptionResource.Serialization_NullKey);
}
- Insert(array[i].Key, array[i].Value, true);
+ Add(array[i].Key, array[i].Value);
}
}
- else {
+ else
+ {
buckets = null;
}
@@ -452,25 +549,32 @@ namespace System.Collections.Generic {
HashHelpers.SerializationInfoTable.Remove(this);
}
- private void Resize() {
+ private void Resize()
+ {
Resize(HashHelpers.ExpandPrime(count), false);
}
- private void Resize(int newSize, bool forceNewHashCodes) {
+ private void Resize(int newSize, bool forceNewHashCodes)
+ {
Debug.Assert(newSize >= entries.Length);
int[] newBuckets = new int[newSize];
for (int i = 0; i < newBuckets.Length; i++) newBuckets[i] = -1;
Entry[] newEntries = new Entry[newSize];
Array.Copy(entries, 0, newEntries, 0, count);
- if(forceNewHashCodes) {
- for (int i = 0; i < count; i++) {
- if(newEntries[i].hashCode != -1) {
+ if (forceNewHashCodes)
+ {
+ for (int i = 0; i < count; i++)
+ {
+ if (newEntries[i].hashCode != -1)
+ {
newEntries[i].hashCode = (comparer.GetHashCode(newEntries[i].key) & 0x7FFFFFFF);
}
}
}
- for (int i = 0; i < count; i++) {
- if (newEntries[i].hashCode >= 0) {
+ for (int i = 0; i < count; i++)
+ {
+ if (newEntries[i].hashCode >= 0)
+ {
int bucket = newEntries[i].hashCode % newSize;
newEntries[i].next = newBuckets[bucket];
newBuckets[bucket] = i;
@@ -480,21 +584,31 @@ namespace System.Collections.Generic {
entries = newEntries;
}
- public bool Remove(TKey key) {
- if(key == null) {
+ // The overload Remove(TKey key, out TValue value) is a copy of this method with one additional
+ // statement to copy the value for entry being removed into the output parameter.
+ // Code has been intentionally duplicated for performance reasons.
+ public bool Remove(TKey key)
+ {
+ if (key == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
- if (buckets != null) {
+ if (buckets != null)
+ {
int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
int bucket = hashCode % buckets.Length;
int last = -1;
- for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next) {
- if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) {
- if (last < 0) {
+ for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next)
+ {
+ if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
+ {
+ if (last < 0)
+ {
buckets[bucket] = entries[i].next;
}
- else {
+ else
+ {
entries[last].next = entries[i].next;
}
entries[i].hashCode = -1;
@@ -511,9 +625,56 @@ namespace System.Collections.Generic {
return false;
}
- public bool TryGetValue(TKey key, out TValue value) {
+ // This overload is a copy of the overload Remove(TKey key) with one additional
+ // statement to copy the value for entry being removed into the output parameter.
+ // Code has been intentionally duplicated for performance reasons.
+ public bool Remove(TKey key, out TValue value)
+ {
+ if (key == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ }
+
+ if (buckets != null)
+ {
+ int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
+ int bucket = hashCode % buckets.Length;
+ int last = -1;
+ for (int i = buckets[bucket]; i >= 0; last = i, i = entries[i].next)
+ {
+ if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key))
+ {
+ if (last < 0)
+ {
+ buckets[bucket] = entries[i].next;
+ }
+ else
+ {
+ entries[last].next = entries[i].next;
+ }
+
+ value = entries[i].value;
+
+ entries[i].hashCode = -1;
+ entries[i].next = freeList;
+ entries[i].key = default(TKey);
+ entries[i].value = default(TValue);
+ freeList = i;
+ freeCount++;
+ version++;
+ return true;
+ }
+ }
+ }
+ value = default(TValue);
+ return false;
+ }
+
+ public bool TryGetValue(TKey key, out TValue value)
+ {
int i = FindEntry(key);
- if (i >= 0) {
+ if (i >= 0)
+ {
value = entries[i].value;
return true;
}
@@ -536,195 +697,246 @@ namespace System.Collections.Generic {
return defaultValue;
}
- bool ICollection<KeyValuePair<TKey,TValue>>.IsReadOnly {
+ public bool TryAdd(TKey key, TValue value) => TryInsert(key, value, InsertionBehavior.None);
+
+ bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
+ {
get { return false; }
}
- void ICollection<KeyValuePair<TKey,TValue>>.CopyTo(KeyValuePair<TKey,TValue>[] array, int index) {
+ void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int index)
+ {
CopyTo(array, index);
}
- void ICollection.CopyTo(Array array, int index) {
- if (array == null) {
+ void ICollection.CopyTo(Array array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
-
- if (array.Rank != 1) {
+
+ if (array.Rank != 1)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
- if( array.GetLowerBound(0) != 0 ) {
+ if (array.GetLowerBound(0) != 0)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
-
- if (index < 0 || index > array.Length) {
+
+ if (index < 0 || index > array.Length)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < Count) {
+ if (array.Length - index < Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
-
- KeyValuePair<TKey,TValue>[] pairs = array as KeyValuePair<TKey,TValue>[];
- if (pairs != null) {
+
+ KeyValuePair<TKey, TValue>[] pairs = array as KeyValuePair<TKey, TValue>[];
+ if (pairs != null)
+ {
CopyTo(pairs, index);
}
- else if( array is DictionaryEntry[]) {
+ else if (array is DictionaryEntry[])
+ {
DictionaryEntry[] dictEntryArray = array as DictionaryEntry[];
Entry[] entries = this.entries;
- for (int i = 0; i < count; i++) {
- if (entries[i].hashCode >= 0) {
+ for (int i = 0; i < count; i++)
+ {
+ if (entries[i].hashCode >= 0)
+ {
dictEntryArray[index++] = new DictionaryEntry(entries[i].key, entries[i].value);
}
- }
+ }
}
- else {
+ else
+ {
object[] objects = array as object[];
- if (objects == null) {
+ if (objects == null)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
- try {
+ try
+ {
int count = this.count;
Entry[] entries = this.entries;
- for (int i = 0; i < count; i++) {
- if (entries[i].hashCode >= 0) {
- objects[index++] = new KeyValuePair<TKey,TValue>(entries[i].key, entries[i].value);
+ for (int i = 0; i < count; i++)
+ {
+ if (entries[i].hashCode >= 0)
+ {
+ objects[index++] = new KeyValuePair<TKey, TValue>(entries[i].key, entries[i].value);
}
}
}
- catch(ArrayTypeMismatchException) {
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
- IEnumerator IEnumerable.GetEnumerator() {
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return new Enumerator(this, Enumerator.KeyValuePair);
}
-
- bool ICollection.IsSynchronized {
+
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- object ICollection.SyncRoot {
- get {
- if( _syncRoot == null) {
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ object ICollection.SyncRoot
+ {
+ get
+ {
+ if (_syncRoot == null)
+ {
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
- return _syncRoot;
+ return _syncRoot;
}
}
- bool IDictionary.IsFixedSize {
+ bool IDictionary.IsFixedSize
+ {
get { return false; }
}
- bool IDictionary.IsReadOnly {
+ bool IDictionary.IsReadOnly
+ {
get { return false; }
}
- ICollection IDictionary.Keys {
+ ICollection IDictionary.Keys
+ {
get { return (ICollection)Keys; }
}
-
- ICollection IDictionary.Values {
+
+ ICollection IDictionary.Values
+ {
get { return (ICollection)Values; }
}
-
- object IDictionary.this[object key] {
- get {
- if( IsCompatibleKey(key)) {
+
+ object IDictionary.this[object key]
+ {
+ get
+ {
+ if (IsCompatibleKey(key))
+ {
int i = FindEntry((TKey)key);
- if (i >= 0) {
- return entries[i].value;
+ if (i >= 0)
+ {
+ return entries[i].value;
}
}
return null;
}
- set {
+ set
+ {
if (key == null)
{
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<TValue>(value, ExceptionArgument.value);
- try {
+ try
+ {
TKey tempKey = (TKey)key;
- try {
- this[tempKey] = (TValue)value;
+ try
+ {
+ this[tempKey] = (TValue)value;
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(TValue));
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(TValue));
}
}
- catch (InvalidCastException) {
+ catch (InvalidCastException)
+ {
ThrowHelper.ThrowWrongKeyTypeArgumentException(key, typeof(TKey));
}
}
}
- private static bool IsCompatibleKey(object key) {
- if( key == null) {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
- }
- return (key is TKey);
+ private static bool IsCompatibleKey(object key)
+ {
+ if (key == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ }
+ return (key is TKey);
}
-
- void IDictionary.Add(object key, object value) {
+
+ void IDictionary.Add(object key, object value)
+ {
if (key == null)
{
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<TValue>(value, ExceptionArgument.value);
- try {
+ try
+ {
TKey tempKey = (TKey)key;
- try {
+ try
+ {
Add(tempKey, (TValue)value);
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(TValue));
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(TValue));
}
}
- catch (InvalidCastException) {
+ catch (InvalidCastException)
+ {
ThrowHelper.ThrowWrongKeyTypeArgumentException(key, typeof(TKey));
}
}
-
- bool IDictionary.Contains(object key) {
- if(IsCompatibleKey(key)) {
+
+ bool IDictionary.Contains(object key)
+ {
+ if (IsCompatibleKey(key))
+ {
return ContainsKey((TKey)key);
}
-
+
return false;
}
-
- IDictionaryEnumerator IDictionary.GetEnumerator() {
+
+ IDictionaryEnumerator IDictionary.GetEnumerator()
+ {
return new Enumerator(this, Enumerator.DictEntry);
}
-
- void IDictionary.Remove(object key) {
- if(IsCompatibleKey(key)) {
+
+ void IDictionary.Remove(object key)
+ {
+ if (IsCompatibleKey(key))
+ {
Remove((TKey)key);
}
}
[Serializable]
- public struct Enumerator: IEnumerator<KeyValuePair<TKey,TValue>>,
+ public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>,
IDictionaryEnumerator
{
- private Dictionary<TKey,TValue> dictionary;
+ private Dictionary<TKey, TValue> dictionary;
private int version;
private int index;
- private KeyValuePair<TKey,TValue> current;
+ private KeyValuePair<TKey, TValue> current;
private int getEnumeratorRetType; // What should Enumerator.Current return?
-
+
internal const int DictEntry = 1;
internal const int KeyValuePair = 2;
- internal Enumerator(Dictionary<TKey,TValue> dictionary, int getEnumeratorRetType) {
+ internal Enumerator(Dictionary<TKey, TValue> dictionary, int getEnumeratorRetType)
+ {
this.dictionary = dictionary;
version = dictionary.version;
index = 0;
@@ -732,15 +944,19 @@ namespace System.Collections.Generic {
current = new KeyValuePair<TKey, TValue>();
}
- public bool MoveNext() {
- if (version != dictionary.version) {
+ public bool MoveNext()
+ {
+ if (version != dictionary.version)
+ {
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
// Use unsigned comparison since we set index to dictionary.count+1 when the enumeration ends.
// dictionary.count+1 could be negative if dictionary.count is Int32.MaxValue
- while ((uint)index < (uint)dictionary.count) {
- if (dictionary.entries[index].hashCode >= 0) {
+ while ((uint)index < (uint)dictionary.count)
+ {
+ if (dictionary.entries[index].hashCode >= 0)
+ {
current = new KeyValuePair<TKey, TValue>(dictionary.entries[index].key, dictionary.entries[index].value);
index++;
return true;
@@ -753,187 +969,236 @@ namespace System.Collections.Generic {
return false;
}
- public KeyValuePair<TKey,TValue> Current {
+ public KeyValuePair<TKey, TValue> Current
+ {
get { return current; }
}
- public void Dispose() {
+ public void Dispose()
+ {
}
- object IEnumerator.Current {
- get {
- if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
- }
+ object IEnumerator.Current
+ {
+ get
+ {
+ if (index == 0 || (index == dictionary.count + 1))
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
+ }
- if (getEnumeratorRetType == DictEntry) {
+ if (getEnumeratorRetType == DictEntry)
+ {
return new System.Collections.DictionaryEntry(current.Key, current.Value);
- } else {
+ }
+ else
+ {
return new KeyValuePair<TKey, TValue>(current.Key, current.Value);
}
}
}
- void IEnumerator.Reset() {
- if (version != dictionary.version) {
+ void IEnumerator.Reset()
+ {
+ if (version != dictionary.version)
+ {
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
index = 0;
- current = new KeyValuePair<TKey, TValue>();
+ current = new KeyValuePair<TKey, TValue>();
}
- DictionaryEntry IDictionaryEnumerator.Entry {
- get {
- if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
- }
-
- return new DictionaryEntry(current.Key, current.Value);
+ DictionaryEntry IDictionaryEnumerator.Entry
+ {
+ get
+ {
+ if (index == 0 || (index == dictionary.count + 1))
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
+ }
+
+ return new DictionaryEntry(current.Key, current.Value);
}
}
- object IDictionaryEnumerator.Key {
- get {
- if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
- }
-
- return current.Key;
+ object IDictionaryEnumerator.Key
+ {
+ get
+ {
+ if (index == 0 || (index == dictionary.count + 1))
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
+ }
+
+ return current.Key;
}
}
- object IDictionaryEnumerator.Value {
- get {
- if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
- }
-
- return current.Value;
+ object IDictionaryEnumerator.Value
+ {
+ get
+ {
+ if (index == 0 || (index == dictionary.count + 1))
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
+ }
+
+ return current.Value;
}
}
}
[DebuggerTypeProxy(typeof(Mscorlib_DictionaryKeyCollectionDebugView<,>))]
- [DebuggerDisplay("Count = {Count}")]
+ [DebuggerDisplay("Count = {Count}")]
[Serializable]
- public sealed class KeyCollection: ICollection<TKey>, ICollection, IReadOnlyCollection<TKey>
+ public sealed class KeyCollection : ICollection<TKey>, ICollection, IReadOnlyCollection<TKey>
{
- private Dictionary<TKey,TValue> dictionary;
+ private Dictionary<TKey, TValue> dictionary;
- public KeyCollection(Dictionary<TKey,TValue> dictionary) {
- if (dictionary == null) {
+ public KeyCollection(Dictionary<TKey, TValue> dictionary)
+ {
+ if (dictionary == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
}
this.dictionary = dictionary;
}
- public Enumerator GetEnumerator() {
+ public Enumerator GetEnumerator()
+ {
return new Enumerator(dictionary);
}
- public void CopyTo(TKey[] array, int index) {
- if (array == null) {
+ public void CopyTo(TKey[] array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if (index < 0 || index > array.Length) {
+ if (index < 0 || index > array.Length)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < dictionary.Count) {
+ if (array.Length - index < dictionary.Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
-
+
int count = dictionary.count;
Entry[] entries = dictionary.entries;
- for (int i = 0; i < count; i++) {
+ for (int i = 0; i < count; i++)
+ {
if (entries[i].hashCode >= 0) array[index++] = entries[i].key;
}
}
- public int Count {
+ public int Count
+ {
get { return dictionary.Count; }
}
- bool ICollection<TKey>.IsReadOnly {
+ bool ICollection<TKey>.IsReadOnly
+ {
get { return true; }
}
- void ICollection<TKey>.Add(TKey item){
+ void ICollection<TKey>.Add(TKey item)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
}
-
- void ICollection<TKey>.Clear(){
+
+ void ICollection<TKey>.Clear()
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
}
- bool ICollection<TKey>.Contains(TKey item){
+ bool ICollection<TKey>.Contains(TKey item)
+ {
return dictionary.ContainsKey(item);
}
- bool ICollection<TKey>.Remove(TKey item){
+ bool ICollection<TKey>.Remove(TKey item)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
return false;
}
-
- IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator() {
+
+ IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator()
+ {
return new Enumerator(dictionary);
}
- IEnumerator IEnumerable.GetEnumerator() {
- return new Enumerator(dictionary);
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return new Enumerator(dictionary);
}
- void ICollection.CopyTo(Array array, int index) {
- if (array==null) {
+ void ICollection.CopyTo(Array array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if (array.Rank != 1) {
+ if (array.Rank != 1)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
- if( array.GetLowerBound(0) != 0 ) {
+ if (array.GetLowerBound(0) != 0)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
- if (index < 0 || index > array.Length) {
+ if (index < 0 || index > array.Length)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < dictionary.Count) {
+ if (array.Length - index < dictionary.Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
-
+
TKey[] keys = array as TKey[];
- if (keys != null) {
+ if (keys != null)
+ {
CopyTo(keys, index);
}
- else {
+ else
+ {
object[] objects = array as object[];
- if (objects == null) {
+ if (objects == null)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
-
+
int count = dictionary.count;
Entry[] entries = dictionary.entries;
- try {
- for (int i = 0; i < count; i++) {
+ try
+ {
+ for (int i = 0; i < count; i++)
+ {
if (entries[i].hashCode >= 0) objects[index++] = entries[i].key;
}
- }
- catch(ArrayTypeMismatchException) {
+ }
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
- bool ICollection.IsSynchronized {
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- Object ICollection.SyncRoot {
+ Object ICollection.SyncRoot
+ {
get { return ((ICollection)dictionary).SyncRoot; }
}
@@ -944,24 +1209,30 @@ namespace System.Collections.Generic {
private int index;
private int version;
private TKey currentKey;
-
- internal Enumerator(Dictionary<TKey, TValue> dictionary) {
+
+ internal Enumerator(Dictionary<TKey, TValue> dictionary)
+ {
this.dictionary = dictionary;
version = dictionary.version;
index = 0;
- currentKey = default(TKey);
+ currentKey = default(TKey);
}
- public void Dispose() {
+ public void Dispose()
+ {
}
- public bool MoveNext() {
- if (version != dictionary.version) {
+ public bool MoveNext()
+ {
+ if (version != dictionary.version)
+ {
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
- while ((uint)index < (uint)dictionary.count) {
- if (dictionary.entries[index].hashCode >= 0) {
+ while ((uint)index < (uint)dictionary.count)
+ {
+ if (dictionary.entries[index].hashCode >= 0)
+ {
currentKey = dictionary.entries[index].key;
index++;
return true;
@@ -973,153 +1244,189 @@ namespace System.Collections.Generic {
currentKey = default(TKey);
return false;
}
-
- public TKey Current {
- get {
+
+ public TKey Current
+ {
+ get
+ {
return currentKey;
}
}
- Object System.Collections.IEnumerator.Current {
- get {
- if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
- }
-
+ Object System.Collections.IEnumerator.Current
+ {
+ get
+ {
+ if (index == 0 || (index == dictionary.count + 1))
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
+ }
+
return currentKey;
}
}
-
- void System.Collections.IEnumerator.Reset() {
- if (version != dictionary.version) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
+
+ void System.Collections.IEnumerator.Reset()
+ {
+ if (version != dictionary.version)
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
- index = 0;
+ index = 0;
currentKey = default(TKey);
}
- }
+ }
}
[DebuggerTypeProxy(typeof(Mscorlib_DictionaryValueCollectionDebugView<,>))]
[DebuggerDisplay("Count = {Count}")]
[Serializable]
- public sealed class ValueCollection: ICollection<TValue>, ICollection, IReadOnlyCollection<TValue>
+ public sealed class ValueCollection : ICollection<TValue>, ICollection, IReadOnlyCollection<TValue>
{
- private Dictionary<TKey,TValue> dictionary;
+ private Dictionary<TKey, TValue> dictionary;
- public ValueCollection(Dictionary<TKey,TValue> dictionary) {
- if (dictionary == null) {
+ public ValueCollection(Dictionary<TKey, TValue> dictionary)
+ {
+ if (dictionary == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
}
this.dictionary = dictionary;
}
- public Enumerator GetEnumerator() {
- return new Enumerator(dictionary);
+ public Enumerator GetEnumerator()
+ {
+ return new Enumerator(dictionary);
}
- public void CopyTo(TValue[] array, int index) {
- if (array == null) {
+ public void CopyTo(TValue[] array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if (index < 0 || index > array.Length) {
+ if (index < 0 || index > array.Length)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < dictionary.Count) {
+ if (array.Length - index < dictionary.Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
-
+
int count = dictionary.count;
Entry[] entries = dictionary.entries;
- for (int i = 0; i < count; i++) {
+ for (int i = 0; i < count; i++)
+ {
if (entries[i].hashCode >= 0) array[index++] = entries[i].value;
}
}
- public int Count {
+ public int Count
+ {
get { return dictionary.Count; }
}
- bool ICollection<TValue>.IsReadOnly {
+ bool ICollection<TValue>.IsReadOnly
+ {
get { return true; }
}
- void ICollection<TValue>.Add(TValue item){
+ void ICollection<TValue>.Add(TValue item)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
}
- bool ICollection<TValue>.Remove(TValue item){
+ bool ICollection<TValue>.Remove(TValue item)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
return false;
}
- void ICollection<TValue>.Clear(){
+ void ICollection<TValue>.Clear()
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
}
- bool ICollection<TValue>.Contains(TValue item){
+ bool ICollection<TValue>.Contains(TValue item)
+ {
return dictionary.ContainsValue(item);
}
- IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator() {
+ IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator()
+ {
return new Enumerator(dictionary);
}
- IEnumerator IEnumerable.GetEnumerator() {
- return new Enumerator(dictionary);
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return new Enumerator(dictionary);
}
- void ICollection.CopyTo(Array array, int index) {
- if (array == null) {
+ void ICollection.CopyTo(Array array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if (array.Rank != 1) {
+ if (array.Rank != 1)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
- if( array.GetLowerBound(0) != 0 ) {
+ if (array.GetLowerBound(0) != 0)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
- if (index < 0 || index > array.Length) {
+ if (index < 0 || index > array.Length)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
if (array.Length - index < dictionary.Count)
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
-
+
TValue[] values = array as TValue[];
- if (values != null) {
+ if (values != null)
+ {
CopyTo(values, index);
}
- else {
+ else
+ {
object[] objects = array as object[];
- if (objects == null) {
+ if (objects == null)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
int count = dictionary.count;
Entry[] entries = dictionary.entries;
- try {
- for (int i = 0; i < count; i++) {
+ try
+ {
+ for (int i = 0; i < count; i++)
+ {
if (entries[i].hashCode >= 0) objects[index++] = entries[i].value;
}
}
- catch(ArrayTypeMismatchException) {
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
- bool ICollection.IsSynchronized {
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- Object ICollection.SyncRoot {
+ Object ICollection.SyncRoot
+ {
get { return ((ICollection)dictionary).SyncRoot; }
}
@@ -1130,24 +1437,30 @@ namespace System.Collections.Generic {
private int index;
private int version;
private TValue currentValue;
-
- internal Enumerator(Dictionary<TKey, TValue> dictionary) {
+
+ internal Enumerator(Dictionary<TKey, TValue> dictionary)
+ {
this.dictionary = dictionary;
version = dictionary.version;
index = 0;
currentValue = default(TValue);
}
- public void Dispose() {
+ public void Dispose()
+ {
}
- public bool MoveNext() {
- if (version != dictionary.version) {
+ public bool MoveNext()
+ {
+ if (version != dictionary.version)
+ {
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
-
- while ((uint)index < (uint)dictionary.count) {
- if (dictionary.entries[index].hashCode >= 0) {
+
+ while ((uint)index < (uint)dictionary.count)
+ {
+ if (dictionary.entries[index].hashCode >= 0)
+ {
currentValue = dictionary.entries[index].value;
index++;
return true;
@@ -1158,28 +1471,35 @@ namespace System.Collections.Generic {
currentValue = default(TValue);
return false;
}
-
- public TValue Current {
- get {
+
+ public TValue Current
+ {
+ get
+ {
return currentValue;
}
}
- Object System.Collections.IEnumerator.Current {
- get {
- if( index == 0 || (index == dictionary.count + 1)) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
- }
-
+ Object System.Collections.IEnumerator.Current
+ {
+ get
+ {
+ if (index == 0 || (index == dictionary.count + 1))
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
+ }
+
return currentValue;
}
}
-
- void System.Collections.IEnumerator.Reset() {
- if (version != dictionary.version) {
+
+ void System.Collections.IEnumerator.Reset()
+ {
+ if (version != dictionary.version)
+ {
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
- index = 0;
+ index = 0;
currentValue = default(TValue);
}
}
diff --git a/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs b/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs
index 0f9259d2f3..0cd1bc1c12 100644
--- a/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs
+++ b/src/mscorlib/src/System/Collections/Generic/EqualityComparer.cs
@@ -7,117 +7,56 @@ using System.Collections;
using System.Collections.Generic;
using System.Security;
+using System.Globalization;
+using System.Runtime;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.Contracts;
+
namespace System.Collections.Generic
{
- using System.Globalization;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.Diagnostics.Contracts;
-
[Serializable]
[TypeDependencyAttribute("System.Collections.Generic.ObjectEqualityComparer`1")]
public abstract class EqualityComparer<T> : IEqualityComparer, IEqualityComparer<T>
{
- static readonly EqualityComparer<T> defaultComparer = CreateComparer();
-
- public static EqualityComparer<T> Default {
- get {
- Contract.Ensures(Contract.Result<EqualityComparer<T>>() != null);
- return defaultComparer;
- }
- }
-
- //
- // Note that logic in this method is replicated in vm\compile.cpp to ensure that NGen
- // saves the right instantiations
- //
- private static EqualityComparer<T> CreateComparer()
- {
- Contract.Ensures(Contract.Result<EqualityComparer<T>>() != null);
-
- object result = null;
- RuntimeType t = (RuntimeType)typeof(T);
-
- // Specialize type byte for performance reasons
- if (t == typeof(byte)) {
- result = new ByteEqualityComparer();
- }
- // If T implements IEquatable<T> return a GenericEqualityComparer<T>
- else if (typeof(IEquatable<T>).IsAssignableFrom(t))
- {
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(GenericEqualityComparer<int>), t);
- }
- else if (default(T) == null) // Reference type/Nullable
- {
- // If T is a Nullable<U> where U implements IEquatable<U> return a NullableEqualityComparer<U>
- if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) {
- RuntimeType u = (RuntimeType)t.GetGenericArguments()[0];
- if (typeof(IEquatable<>).MakeGenericType(u).IsAssignableFrom(u)) {
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(NullableEqualityComparer<int>), u);
- }
- }
- }
- // See the METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST and METHOD__JIT_HELPERS__UNSAFE_ENUM_CAST_LONG cases in getILIntrinsicImplementation
- else if (t.IsEnum) {
- TypeCode underlyingTypeCode = Type.GetTypeCode(Enum.GetUnderlyingType(t));
-
- // Depending on the enum type, we need to special case the comparers so that we avoid boxing
- // Note: We have different comparers for Short and SByte because for those types we need to make sure we call GetHashCode on the actual underlying type as the
- // implementation of GetHashCode is more complex than for the other types.
- switch (underlyingTypeCode) {
- case TypeCode.Int16: // short
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(ShortEnumEqualityComparer<short>), t);
- break;
- case TypeCode.SByte:
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(SByteEnumEqualityComparer<sbyte>), t);
- break;
- case TypeCode.Int32:
- case TypeCode.UInt32:
- case TypeCode.Byte:
- case TypeCode.UInt16: //ushort
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(EnumEqualityComparer<int>), t);
- break;
- case TypeCode.Int64:
- case TypeCode.UInt64:
- result = RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(LongEnumEqualityComparer<long>), t);
- break;
- }
- }
-
- return result != null ?
- (EqualityComparer<T>)result :
- new ObjectEqualityComparer<T>(); // Fallback to ObjectEqualityComparer, which uses boxing
- }
+ // To minimize generic instantiation overhead of creating the comparer per type, we keep the generic portion of the code as small
+ // as possible and define most of the creation logic in a non-generic class.
+ public static EqualityComparer<T> Default { get; } = (EqualityComparer<T>)ComparerHelpers.CreateDefaultEqualityComparer(typeof(T));
[Pure]
public abstract bool Equals(T x, T y);
[Pure]
public abstract int GetHashCode(T obj);
- internal virtual int IndexOf(T[] array, T value, int startIndex, int count) {
+ internal virtual int IndexOf(T[] array, T value, int startIndex, int count)
+ {
int endIndex = startIndex + count;
- for (int i = startIndex; i < endIndex; i++) {
+ for (int i = startIndex; i < endIndex; i++)
+ {
if (Equals(array[i], value)) return i;
}
return -1;
}
- internal virtual int LastIndexOf(T[] array, T value, int startIndex, int count) {
+ internal virtual int LastIndexOf(T[] array, T value, int startIndex, int count)
+ {
int endIndex = startIndex - count + 1;
- for (int i = startIndex; i >= endIndex; i--) {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (Equals(array[i], value)) return i;
}
return -1;
}
- int IEqualityComparer.GetHashCode(object obj) {
+ int IEqualityComparer.GetHashCode(object obj)
+ {
if (obj == null) return 0;
if (obj is T) return GetHashCode((T)obj);
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArgumentForComparison);
- return 0;
- }
+ return 0;
+ }
- bool IEqualityComparer.Equals(object x, object y) {
+ bool IEqualityComparer.Equals(object x, object y)
+ {
if (x == y) return true;
if (x == null || y == null) return false;
if ((x is T) && (y is T)) return Equals((T)x, (T)y);
@@ -129,11 +68,13 @@ namespace System.Collections.Generic
// The methods in this class look identical to the inherited methods, but the calls
// to Equal bind to IEquatable<T>.Equals(T) instead of Object.Equals(Object)
[Serializable]
- internal class GenericEqualityComparer<T>: EqualityComparer<T> where T: IEquatable<T>
+ internal class GenericEqualityComparer<T> : EqualityComparer<T> where T : IEquatable<T>
{
[Pure]
- public override bool Equals(T x, T y) {
- if (x != null) {
+ public override bool Equals(T x, T y)
+ {
+ if (x != null)
+ {
if (y != null) return x.Equals(y);
return false;
}
@@ -144,30 +85,40 @@ namespace System.Collections.Generic
[Pure]
public override int GetHashCode(T obj) => obj?.GetHashCode() ?? 0;
- internal override int IndexOf(T[] array, T value, int startIndex, int count) {
+ internal override int IndexOf(T[] array, T value, int startIndex, int count)
+ {
int endIndex = startIndex + count;
- if (value == null) {
- for (int i = startIndex; i < endIndex; i++) {
+ if (value == null)
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
if (array[i] == null) return i;
}
}
- else {
- for (int i = startIndex; i < endIndex; i++) {
+ else
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
if (array[i] != null && array[i].Equals(value)) return i;
}
}
return -1;
}
- internal override int LastIndexOf(T[] array, T value, int startIndex, int count) {
+ internal override int LastIndexOf(T[] array, T value, int startIndex, int count)
+ {
int endIndex = startIndex - count + 1;
- if (value == null) {
- for (int i = startIndex; i >= endIndex; i--) {
+ if (value == null)
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (array[i] == null) return i;
}
}
- else {
- for (int i = startIndex; i >= endIndex; i--) {
+ else
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (array[i] != null && array[i].Equals(value)) return i;
}
}
@@ -188,8 +139,10 @@ namespace System.Collections.Generic
internal sealed class NullableEqualityComparer<T> : EqualityComparer<T?> where T : struct, IEquatable<T>
{
[Pure]
- public override bool Equals(T? x, T? y) {
- if (x.HasValue) {
+ public override bool Equals(T? x, T? y)
+ {
+ if (x.HasValue)
+ {
if (y.HasValue) return x.value.Equals(y.value);
return false;
}
@@ -200,30 +153,40 @@ namespace System.Collections.Generic
[Pure]
public override int GetHashCode(T? obj) => obj.GetHashCode();
- internal override int IndexOf(T?[] array, T? value, int startIndex, int count) {
+ internal override int IndexOf(T?[] array, T? value, int startIndex, int count)
+ {
int endIndex = startIndex + count;
- if (!value.HasValue) {
- for (int i = startIndex; i < endIndex; i++) {
+ if (!value.HasValue)
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
if (!array[i].HasValue) return i;
}
}
- else {
- for (int i = startIndex; i < endIndex; i++) {
+ else
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
if (array[i].HasValue && array[i].value.Equals(value.value)) return i;
}
}
return -1;
}
- internal override int LastIndexOf(T?[] array, T? value, int startIndex, int count) {
+ internal override int LastIndexOf(T?[] array, T? value, int startIndex, int count)
+ {
int endIndex = startIndex - count + 1;
- if (!value.HasValue) {
- for (int i = startIndex; i >= endIndex; i--) {
+ if (!value.HasValue)
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (!array[i].HasValue) return i;
}
}
- else {
- for (int i = startIndex; i >= endIndex; i--) {
+ else
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (array[i].HasValue && array[i].value.Equals(value.value)) return i;
}
}
@@ -239,11 +202,13 @@ namespace System.Collections.Generic
}
[Serializable]
- internal sealed class ObjectEqualityComparer<T>: EqualityComparer<T>
+ internal sealed class ObjectEqualityComparer<T> : EqualityComparer<T>
{
[Pure]
- public override bool Equals(T x, T y) {
- if (x != null) {
+ public override bool Equals(T x, T y)
+ {
+ if (x != null)
+ {
if (y != null) return x.Equals(y);
return false;
}
@@ -254,30 +219,40 @@ namespace System.Collections.Generic
[Pure]
public override int GetHashCode(T obj) => obj?.GetHashCode() ?? 0;
- internal override int IndexOf(T[] array, T value, int startIndex, int count) {
+ internal override int IndexOf(T[] array, T value, int startIndex, int count)
+ {
int endIndex = startIndex + count;
- if (value == null) {
- for (int i = startIndex; i < endIndex; i++) {
+ if (value == null)
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
if (array[i] == null) return i;
}
}
- else {
- for (int i = startIndex; i < endIndex; i++) {
+ else
+ {
+ for (int i = startIndex; i < endIndex; i++)
+ {
if (array[i] != null && array[i].Equals(value)) return i;
}
}
return -1;
}
- internal override int LastIndexOf(T[] array, T value, int startIndex, int count) {
+ internal override int LastIndexOf(T[] array, T value, int startIndex, int count)
+ {
int endIndex = startIndex - count + 1;
- if (value == null) {
- for (int i = startIndex; i >= endIndex; i--) {
+ if (value == null)
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (array[i] == null) return i;
}
}
- else {
- for (int i = startIndex; i >= endIndex; i--) {
+ else
+ {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (array[i] != null && array[i].Equals(value)) return i;
}
}
@@ -299,20 +274,25 @@ namespace System.Collections.Generic
// keep the perofrmance not affected till we hit collision threshold and then we switch to the comparer which is using
// randomized string hashing GenericEqualityComparer<string>
[Serializable]
- internal class NonRandomizedStringEqualityComparer : GenericEqualityComparer<string> {
- static IEqualityComparer<string> s_nonRandomizedComparer;
-
- internal static new IEqualityComparer<string> Default {
- get {
- if (s_nonRandomizedComparer == null) {
- s_nonRandomizedComparer = new NonRandomizedStringEqualityComparer();
- }
- return s_nonRandomizedComparer;
+ internal class NonRandomizedStringEqualityComparer : GenericEqualityComparer<string>
+ {
+ private static IEqualityComparer<string> s_nonRandomizedComparer;
+
+ internal static new IEqualityComparer<string> Default
+ {
+ get
+ {
+ if (s_nonRandomizedComparer == null)
+ {
+ s_nonRandomizedComparer = new NonRandomizedStringEqualityComparer();
+ }
+ return s_nonRandomizedComparer;
}
}
[Pure]
- public override int GetHashCode(string obj) {
+ public override int GetHashCode(string obj)
+ {
if (obj == null) return 0;
return obj.GetLegacyNonRandomizedHashCode();
}
@@ -321,37 +301,43 @@ namespace System.Collections.Generic
// Performance of IndexOf on byte array is very important for some scenarios.
// We will call the C runtime function memchr, which is optimized.
[Serializable]
- internal sealed class ByteEqualityComparer: EqualityComparer<byte>
+ internal sealed class ByteEqualityComparer : EqualityComparer<byte>
{
[Pure]
- public override bool Equals(byte x, byte y) {
+ public override bool Equals(byte x, byte y)
+ {
return x == y;
}
[Pure]
- public override int GetHashCode(byte b) {
+ public override int GetHashCode(byte b)
+ {
return b.GetHashCode();
}
- internal unsafe override int IndexOf(byte[] array, byte value, int startIndex, int count) {
- if (array==null)
+ internal unsafe override int IndexOf(byte[] array, byte value, int startIndex, int count)
+ {
+ if (array == null)
throw new ArgumentNullException(nameof(array));
if (startIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
if (count > array.Length - startIndex)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
if (count == 0) return -1;
- fixed (byte* pbytes = array) {
+ fixed (byte* pbytes = array)
+ {
return Buffer.IndexOfByte(pbytes, value, startIndex, count);
}
}
- internal override int LastIndexOf(byte[] array, byte value, int startIndex, int count) {
+ internal override int LastIndexOf(byte[] array, byte value, int startIndex, int count)
+ {
int endIndex = startIndex - count + 1;
- for (int i = startIndex; i >= endIndex; i--) {
+ for (int i = startIndex; i >= endIndex; i--)
+ {
if (array[i] == value) return i;
}
return -1;
@@ -362,21 +348,23 @@ namespace System.Collections.Generic
obj != null && GetType() == obj.GetType();
public override int GetHashCode() =>
- GetType().GetHashCode();
+ GetType().GetHashCode();
}
[Serializable]
internal class EnumEqualityComparer<T> : EqualityComparer<T> where T : struct
{
[Pure]
- public override bool Equals(T x, T y) {
+ public override bool Equals(T x, T y)
+ {
int x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(x);
int y_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(y);
return x_final == y_final;
}
[Pure]
- public override int GetHashCode(T obj) {
+ public override int GetHashCode(T obj)
+ {
int x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(obj);
return x_final.GetHashCode();
}
@@ -421,7 +409,8 @@ namespace System.Collections.Generic
public SByteEnumEqualityComparer() { }
[Pure]
- public override int GetHashCode(T obj) {
+ public override int GetHashCode(T obj)
+ {
int x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(obj);
return ((sbyte)x_final).GetHashCode();
}
@@ -433,7 +422,8 @@ namespace System.Collections.Generic
public ShortEnumEqualityComparer() { }
[Pure]
- public override int GetHashCode(T obj) {
+ public override int GetHashCode(T obj)
+ {
int x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCast(obj);
return ((short)x_final).GetHashCode();
}
@@ -443,14 +433,16 @@ namespace System.Collections.Generic
internal sealed class LongEnumEqualityComparer<T> : EqualityComparer<T> where T : struct
{
[Pure]
- public override bool Equals(T x, T y) {
+ public override bool Equals(T x, T y)
+ {
long x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCastLong(x);
long y_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCastLong(y);
return x_final == y_final;
}
[Pure]
- public override int GetHashCode(T obj) {
+ public override int GetHashCode(T obj)
+ {
long x_final = System.Runtime.CompilerServices.JitHelpers.UnsafeEnumCastLong(obj);
return x_final.GetHashCode();
}
diff --git a/src/mscorlib/src/System/Collections/Generic/ICollection.cs b/src/mscorlib/src/System/Collections/Generic/ICollection.cs
deleted file mode 100644
index 741e8cc79b..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/ICollection.cs
+++ /dev/null
@@ -1,52 +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.
-
-/*============================================================
-**
-** Interface: ICollection
-**
-**
-**
-**
-** Purpose: Base interface for all generic collections.
-**
-**
-===========================================================*/
-namespace System.Collections.Generic {
- using System;
- using System.Runtime.CompilerServices;
- using System.Diagnostics.Contracts;
-
- // Base interface for all collections, defining enumerators, size, and
- // synchronization methods.
-
- // Note that T[] : IList<T>, and we want to ensure that if you use
- // IList<YourValueType>, we ensure a YourValueType[] can be used
- // without jitting. Hence the TypeDependencyAttribute on SZArrayHelper.
- // This is a special workaround internally though - see VM\compile.cpp.
- // The same attribute is on IEnumerable<T> and ICollection<T>.
- [TypeDependencyAttribute("System.SZArrayHelper")]
- public interface ICollection<T> : IEnumerable<T>
- {
- // Number of items in the collections.
- int Count { get; }
-
- bool IsReadOnly { get; }
-
- void Add(T item);
-
- void Clear();
-
- bool Contains(T item);
-
- // CopyTo copies a collection into an Array, starting at a particular
- // index into the array.
- //
- void CopyTo(T[] array, int arrayIndex);
-
- //void CopyTo(int sourceIndex, T[] destinationArray, int destinationIndex, int count);
-
- bool Remove(T item);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IComparer.cs b/src/mscorlib/src/System/Collections/Generic/IComparer.cs
deleted file mode 100644
index 7b9e97ff0e..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IComparer.cs
+++ /dev/null
@@ -1,30 +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.
-
-/*============================================================
-**
-** Interface: IComparer
-**
-**
-**
-**
-** Purpose: Interface for comparing two generic Objects.
-**
-**
-===========================================================*/
-namespace System.Collections.Generic {
-
- using System;
- // The generic IComparer interface implements a method that compares
- // two objects. It is used in conjunction with the Sort and
- // BinarySearch methods on the Array, List, and SortedList classes.
- public interface IComparer<in T>
- {
- // Compares two objects. An implementation of this method must return a
- // value less than zero if x is less than y, zero if x is equal to y, or a
- // value greater than zero if x is greater than y.
- //
- int Compare(T x, T y);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IDictionary.cs b/src/mscorlib/src/System/Collections/Generic/IDictionary.cs
deleted file mode 100644
index 2a2da944d3..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IDictionary.cs
+++ /dev/null
@@ -1,58 +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.
-
-/*============================================================
-**
-** Interface: IDictionary
-**
-**
-**
-**
-** Purpose: Base interface for all generic dictionaries.
-**
-**
-===========================================================*/
-namespace System.Collections.Generic {
- using System;
- using System.Diagnostics.Contracts;
-
- // An IDictionary is a possibly unordered set of key-value pairs.
- // Keys can be any non-null object. Values can be any object.
- // You can look up a value in an IDictionary via the default indexed
- // property, Items.
- public interface IDictionary<TKey, TValue> : ICollection<KeyValuePair<TKey, TValue>>
- {
- // Interfaces are not serializable
- // The Item property provides methods to read and edit entries
- // in the Dictionary.
- TValue this[TKey key] {
- get;
- set;
- }
-
- // Returns a collections of the keys in this dictionary.
- ICollection<TKey> Keys {
- get;
- }
-
- // Returns a collections of the values in this dictionary.
- ICollection<TValue> Values {
- get;
- }
-
- // Returns whether this dictionary contains a particular key.
- //
- bool ContainsKey(TKey key);
-
- // Adds a key-value pair to the dictionary.
- //
- void Add(TKey key, TValue value);
-
- // Removes a particular key from the dictionary.
- //
- bool Remove(TKey key);
-
- bool TryGetValue(TKey key, out TValue value);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IEnumerable.cs b/src/mscorlib/src/System/Collections/Generic/IEnumerable.cs
deleted file mode 100644
index 67f35ce675..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IEnumerable.cs
+++ /dev/null
@@ -1,38 +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.
-
-/*============================================================
-**
-** Interface: IEnumerable
-**
-**
-**
-**
-** Purpose: Interface for providing generic IEnumerators
-**
-**
-===========================================================*/
-namespace System.Collections.Generic {
- using System;
- using System.Collections;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Diagnostics.Contracts;
-
- // Implement this interface if you need to support foreach semantics.
-
- // Note that T[] : IList<T>, and we want to ensure that if you use
- // IList<YourValueType>, we ensure a YourValueType[] can be used
- // without jitting. Hence the TypeDependencyAttribute on SZArrayHelper.
- // This is a special workaround internally though - see VM\compile.cpp.
- // The same attribute is on IList<T> and ICollection<T>.
- [TypeDependencyAttribute("System.SZArrayHelper")]
- public interface IEnumerable<out T> : IEnumerable
- {
- // Returns an IEnumerator for this enumerable Object. The enumerator provides
- // a simple way to access all the contents of a collection.
- /// <include file='doc\IEnumerable.uex' path='docs/doc[@for="IEnumerable.GetEnumerator"]/*' />
- new IEnumerator<T> GetEnumerator();
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IEnumerator.cs b/src/mscorlib/src/System/Collections/Generic/IEnumerator.cs
deleted file mode 100644
index 335616757b..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IEnumerator.cs
+++ /dev/null
@@ -1,35 +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.
-
-/*============================================================
-**
-** Interface: IEnumerator
-**
-**
-**
-**
-** Purpose: Base interface for all generic enumerators.
-**
-**
-===========================================================*/
-namespace System.Collections.Generic {
- using System;
- using System.Runtime.InteropServices;
-
- // Base interface for all generic enumerators, providing a simple approach
- // to iterating over a collection.
- public interface IEnumerator<out T> : IDisposable, IEnumerator
- {
- // Returns the current element of the enumeration. The returned value is
- // undefined before the first call to MoveNext and following a
- // call to MoveNext that returned false. Multiple calls to
- // GetCurrent with no intervening calls to MoveNext
- // will return the same object.
- //
- /// <include file='doc\IEnumerator.uex' path='docs/doc[@for="IEnumerator.Current"]/*' />
- new T Current {
- get;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IEqualityComparer.cs b/src/mscorlib/src/System/Collections/Generic/IEqualityComparer.cs
deleted file mode 100644
index b6ac3be006..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IEqualityComparer.cs
+++ /dev/null
@@ -1,19 +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.
-
-//
-
-namespace System.Collections.Generic {
- using System;
-
- // The generic IEqualityComparer interface implements methods to if check two objects are equal
- // and generate Hashcode for an object.
- // It is use in Dictionary class.
- public interface IEqualityComparer<in T>
- {
- bool Equals(T x, T y);
- int GetHashCode(T obj);
- }
-}
-
diff --git a/src/mscorlib/src/System/Collections/Generic/IList.cs b/src/mscorlib/src/System/Collections/Generic/IList.cs
deleted file mode 100644
index 75ca0a9b00..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IList.cs
+++ /dev/null
@@ -1,54 +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.
-
-/*============================================================
-**
-** Interface: IList
-**
-**
-**
-**
-** Purpose: Base interface for all generic lists.
-**
-**
-===========================================================*/
-namespace System.Collections.Generic {
-
- using System;
- using System.Collections;
- using System.Runtime.CompilerServices;
- using System.Diagnostics.Contracts;
-
- // An IList is an ordered collection of objects. The exact ordering
- // is up to the implementation of the list, ranging from a sorted
- // order to insertion order.
-
- // Note that T[] : IList<T>, and we want to ensure that if you use
- // IList<YourValueType>, we ensure a YourValueType[] can be used
- // without jitting. Hence the TypeDependencyAttribute on SZArrayHelper.
- // This is a special workaround internally though - see VM\compile.cpp.
- // The same attribute is on IEnumerable<T> and ICollection<T>.
- [TypeDependencyAttribute("System.SZArrayHelper")]
- public interface IList<T> : ICollection<T>
- {
- // The Item property provides methods to read and edit entries in the List.
- T this[int index] {
- get;
- set;
- }
-
- // Returns the index of a particular item, if it is in the list.
- // Returns -1 if the item isn't in the list.
- int IndexOf(T item);
-
- // Inserts value into the list at position index.
- // index must be non-negative and less than or equal to the
- // number of elements in the list. If index equals the number
- // of items in the list, then value is appended to the end.
- void Insert(int index, T item);
-
- // Removes the item at position index.
- void RemoveAt(int index);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IReadOnlyCollection.cs b/src/mscorlib/src/System/Collections/Generic/IReadOnlyCollection.cs
deleted file mode 100644
index 13bc718760..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IReadOnlyCollection.cs
+++ /dev/null
@@ -1,34 +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.
-
-/*============================================================
-**
-** Interface: IReadOnlyCollection<T>
-**
-**
-**
-** Purpose: Base interface for read-only generic lists.
-**
-===========================================================*/
-using System;
-using System.Diagnostics.Contracts;
-using System.Runtime.CompilerServices;
-
-namespace System.Collections.Generic
-{
-
- // Provides a read-only, covariant view of a generic list.
-
- // Note that T[] : IReadOnlyList<T>, and we want to ensure that if you use
- // IList<YourValueType>, we ensure a YourValueType[] can be used
- // without jitting. Hence the TypeDependencyAttribute on SZArrayHelper.
- // This is a special workaround internally though - see VM\compile.cpp.
- // The same attribute is on IList<T>, IEnumerable<T>, ICollection<T>, and IReadOnlyList<T>.
- [TypeDependencyAttribute("System.SZArrayHelper")]
- // If we ever implement more interfaces on IReadOnlyCollection, we should also update RuntimeTypeCache.PopulateInterfaces() in rttype.cs
- public interface IReadOnlyCollection<out T> : IEnumerable<T>
- {
- int Count { get; }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IReadOnlyDictionary.cs b/src/mscorlib/src/System/Collections/Generic/IReadOnlyDictionary.cs
deleted file mode 100644
index 3603b9a4ea..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IReadOnlyDictionary.cs
+++ /dev/null
@@ -1,29 +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.
-
-/*============================================================
-**
-** Interface: IReadOnlyDictionary<TKey, TValue>
-**
-**
-**
-** Purpose: Base interface for read-only generic dictionaries.
-**
-===========================================================*/
-using System;
-using System.Diagnostics.Contracts;
-
-namespace System.Collections.Generic
-{
- // Provides a read-only view of a generic dictionary.
- public interface IReadOnlyDictionary<TKey, TValue> : IReadOnlyCollection<KeyValuePair<TKey, TValue>>
- {
- bool ContainsKey(TKey key);
- bool TryGetValue(TKey key, out TValue value);
-
- TValue this[TKey key] { get; }
- IEnumerable<TKey> Keys { get; }
- IEnumerable<TValue> Values { get; }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/IReadOnlyList.cs b/src/mscorlib/src/System/Collections/Generic/IReadOnlyList.cs
deleted file mode 100644
index 77366f0b2f..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/IReadOnlyList.cs
+++ /dev/null
@@ -1,34 +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.
-
-/*============================================================
-**
-** Interface: IReadOnlyList<T>
-**
-**
-**
-** Purpose: Base interface for read-only generic lists.
-**
-===========================================================*/
-using System;
-using System.Diagnostics.Contracts;
-using System.Runtime.CompilerServices;
-
-namespace System.Collections.Generic
-{
-
- // Provides a read-only, covariant view of a generic list.
-
- // Note that T[] : IReadOnlyList<T>, and we want to ensure that if you use
- // IList<YourValueType>, we ensure a YourValueType[] can be used
- // without jitting. Hence the TypeDependencyAttribute on SZArrayHelper.
- // This is a special workaround internally though - see VM\compile.cpp.
- // The same attribute is on IList<T>, IEnumerable<T>, ICollection<T> and IReadOnlyCollection<T>.
- [TypeDependencyAttribute("System.SZArrayHelper")]
- // If we ever implement more interfaces on IReadOnlyList, we should also update RuntimeTypeCache.PopulateInterfaces() in rttype.cs
- public interface IReadOnlyList<out T> : IReadOnlyCollection<T>
- {
- T this[int index] { get; }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/KeyNotFoundException.cs b/src/mscorlib/src/System/Collections/Generic/KeyNotFoundException.cs
deleted file mode 100644
index 1cd18cf808..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/KeyNotFoundException.cs
+++ /dev/null
@@ -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.
-
-/*=============================================================================
-**
-**
-**
-**
-**
-** Purpose: Exception class for Hashtable and Dictionary.
-**
-**
-=============================================================================*/
-
-namespace System.Collections.Generic {
-
- using System;
- using System.Runtime.Remoting;
- using System.Runtime.Serialization;
-
- [Serializable]
- public class KeyNotFoundException : SystemException, ISerializable {
-
- public KeyNotFoundException ()
- : base(Environment.GetResourceString("Arg_KeyNotFound")) {
- SetErrorCode(System.__HResults.COR_E_KEYNOTFOUND);
- }
-
- public KeyNotFoundException(String message)
- : base(message) {
- SetErrorCode(System.__HResults.COR_E_KEYNOTFOUND);
- }
-
- public KeyNotFoundException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(System.__HResults.COR_E_KEYNOTFOUND);
- }
-
-
- protected KeyNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs b/src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs
deleted file mode 100644
index ba98adad7d..0000000000
--- a/src/mscorlib/src/System/Collections/Generic/KeyValuePair.cs
+++ /dev/null
@@ -1,74 +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.
-
-/*============================================================
-**
-** Interface: KeyValuePair
-**
-**
-**
-**
-** Purpose: Generic key-value pair for dictionary enumerators.
-**
-**
-===========================================================*/
-namespace System.Collections.Generic {
-
- using System;
- using System.ComponentModel;
- using System.Text;
-
- // Provides the Create factory method for KeyValuePair<TKey, TValue>.
- public static class KeyValuePair
- {
- // Creates a new KeyValuePair<TKey, TValue> from the given values.
- public static KeyValuePair<TKey, TValue> Create<TKey, TValue>(TKey key, TValue value)
- {
- return new KeyValuePair<TKey, TValue>(key, value);
- }
- }
-
- // A KeyValuePair holds a key and a value from a dictionary.
- // It is used by the IEnumerable<T> implementation for both IDictionary<TKey, TValue>
- // and IReadOnlyDictionary<TKey, TValue>.
- [Serializable]
- public struct KeyValuePair<TKey, TValue> {
- private TKey key;
- private TValue value;
-
- public KeyValuePair(TKey key, TValue value) {
- this.key = key;
- this.value = value;
- }
-
- public TKey Key {
- get { return key; }
- }
-
- public TValue Value {
- get { return value; }
- }
-
- public override string ToString() {
- StringBuilder s = StringBuilderCache.Acquire();
- s.Append('[');
- if( Key != null) {
- s.Append(Key.ToString());
- }
- s.Append(", ");
- if( Value != null) {
- s.Append(Value.ToString());
- }
- s.Append(']');
- return StringBuilderCache.GetStringAndRelease(s);
- }
-
- [EditorBrowsable(EditorBrowsableState.Never)]
- public void Deconstruct(out TKey key, out TValue value)
- {
- key = Key;
- value = Value;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/Generic/List.cs b/src/mscorlib/src/System/Collections/Generic/List.cs
index 362e26599d..67d1668aad 100644
--- a/src/mscorlib/src/System/Collections/Generic/List.cs
+++ b/src/mscorlib/src/System/Collections/Generic/List.cs
@@ -12,15 +12,15 @@
**
**
===========================================================*/
-namespace System.Collections.Generic {
- using System;
- using System.Runtime;
- using System.Runtime.Versioning;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Collections.ObjectModel;
+using System;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Collections.ObjectModel;
+using System.Runtime.CompilerServices;
+namespace System.Collections.Generic
+{
// Implements a variable-size List that uses an array of objects to store the
// elements. A List has a capacity, which is the allocated length
// of the internal array. As elements are added to a List, the capacity
@@ -40,22 +40,24 @@ namespace System.Collections.Generic {
private int _version;
[NonSerialized]
private Object _syncRoot;
-
- static readonly T[] _emptyArray = new T[0];
-
+
+ private static readonly T[] _emptyArray = new T[0];
+
// Constructs a List. The list is initially empty and has a capacity
// of zero. Upon adding the first element to the list the capacity is
// increased to _defaultCapacity, and then increased in multiples of two
// as required.
- public List() {
+ public List()
+ {
_items = _emptyArray;
}
-
+
// Constructs a List with a given initial capacity. The list is
// initially empty, but will have room for the given number of elements
// before any reallocations are required.
//
- public List(int capacity) {
+ public List(int capacity)
+ {
if (capacity < 0) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
@@ -64,116 +66,142 @@ namespace System.Collections.Generic {
else
_items = new T[capacity];
}
-
+
// Constructs a List, copying the contents of the given collection. The
// size and capacity of the new list will both be equal to the size of the
// given collection.
//
- public List(IEnumerable<T> collection) {
- if (collection==null)
+ public List(IEnumerable<T> collection)
+ {
+ if (collection == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
Contract.EndContractBlock();
ICollection<T> c = collection as ICollection<T>;
- if( c != null) {
+ if (c != null)
+ {
int count = c.Count;
if (count == 0)
{
_items = _emptyArray;
}
- else {
+ else
+ {
_items = new T[count];
c.CopyTo(_items, 0);
_size = count;
}
- }
- else {
+ }
+ else
+ {
_size = 0;
_items = _emptyArray;
AddEnumerable(collection);
}
}
-
+
// Gets and sets the capacity of this list. The capacity is the size of
// the internal array used to hold items. When set, the internal
// array of the list is reallocated to the given capacity.
//
- public int Capacity {
- get {
+ public int Capacity
+ {
+ get
+ {
Contract.Ensures(Contract.Result<int>() >= 0);
return _items.Length;
}
- set {
- if (value < _size) {
+ set
+ {
+ if (value < _size)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value, ExceptionResource.ArgumentOutOfRange_SmallCapacity);
}
Contract.EndContractBlock();
- if (value != _items.Length) {
- if (value > 0) {
+ if (value != _items.Length)
+ {
+ if (value > 0)
+ {
T[] newItems = new T[value];
- if (_size > 0) {
+ if (_size > 0)
+ {
Array.Copy(_items, 0, newItems, 0, _size);
}
_items = newItems;
}
- else {
+ else
+ {
_items = _emptyArray;
}
}
}
}
-
+
// Read-only property describing how many elements are in the List.
- public int Count {
- get {
+ public int Count
+ {
+ get
+ {
Contract.Ensures(Contract.Result<int>() >= 0);
- return _size;
+ return _size;
}
}
- bool System.Collections.IList.IsFixedSize {
+ bool System.Collections.IList.IsFixedSize
+ {
get { return false; }
}
-
+
// Is this List read-only?
- bool ICollection<T>.IsReadOnly {
+ bool ICollection<T>.IsReadOnly
+ {
get { return false; }
}
- bool System.Collections.IList.IsReadOnly {
+ bool System.Collections.IList.IsReadOnly
+ {
get { return false; }
}
// Is this List synchronized (thread-safe)?
- bool System.Collections.ICollection.IsSynchronized {
+ bool System.Collections.ICollection.IsSynchronized
+ {
get { return false; }
}
-
+
// Synchronization root for this object.
- Object System.Collections.ICollection.SyncRoot {
- get {
- if( _syncRoot == null) {
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ Object System.Collections.ICollection.SyncRoot
+ {
+ get
+ {
+ if (_syncRoot == null)
+ {
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
return _syncRoot;
}
}
// Sets or Gets the element at the given index.
//
- public T this[int index] {
- get {
+ public T this[int index]
+ {
+ get
+ {
// Following trick can reduce the range check by one
- if ((uint) index >= (uint)_size) {
+ if ((uint)index >= (uint)_size)
+ {
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
}
Contract.EndContractBlock();
- return _items[index];
+ return _items[index];
}
- set {
- if ((uint) index >= (uint)_size) {
+ set
+ {
+ if ((uint)index >= (uint)_size)
+ {
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
}
Contract.EndContractBlock();
@@ -182,24 +210,30 @@ namespace System.Collections.Generic {
}
}
- private static bool IsCompatibleObject(object value) {
+ private static bool IsCompatibleObject(object value)
+ {
// Non-null values are fine. Only accept nulls if T is a class or Nullable<U>.
// Note that default(T) is not equal to null for value types except when T is Nullable<U>.
return ((value is T) || (value == null && default(T) == null));
}
- Object System.Collections.IList.this[int index] {
- get {
+ Object System.Collections.IList.this[int index]
+ {
+ get
+ {
return this[index];
}
- set {
+ set
+ {
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(value, ExceptionArgument.value);
- try {
- this[index] = (T)value;
+ try
+ {
+ this[index] = (T)value;
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
}
}
}
@@ -207,22 +241,44 @@ namespace System.Collections.Generic {
// Adds the given object to the end of this list. The size of the list is
// increased by one. If required, the capacity of the list is doubled
// before adding the new element.
- //
- public void Add(T item) {
- if (_size == _items.Length) EnsureCapacity(_size + 1);
- _items[_size++] = item;
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Add(T item)
+ {
+ var array = _items;
+ var size = _size;
_version++;
+ if ((uint)size < (uint)array.Length)
+ {
+ _size = size + 1;
+ array[size] = item;
+ }
+ else
+ {
+ AddWithResize(item);
+ }
+ }
+
+ // Non-inline from List.Add to improve its code quality as uncommon path
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private void AddWithResize(T item)
+ {
+ var size = _size;
+ EnsureCapacity(size + 1);
+ _size = size + 1;
+ _items[size] = item;
}
int System.Collections.IList.Add(Object item)
{
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(item, ExceptionArgument.item);
- try {
- Add((T) item);
+ try
+ {
+ Add((T)item);
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(item, typeof(T));
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(item, typeof(T));
}
return Count - 1;
@@ -233,17 +289,19 @@ namespace System.Collections.Generic {
// required, the capacity of the list is increased to twice the previous
// capacity or the new size, whichever is larger.
//
- public void AddRange(IEnumerable<T> collection) {
+ public void AddRange(IEnumerable<T> collection)
+ {
Contract.Ensures(Count >= Contract.OldValue(Count));
InsertRange(_size, collection);
}
- public ReadOnlyCollection<T> AsReadOnly() {
+ public ReadOnlyCollection<T> AsReadOnly()
+ {
Contract.Ensures(Contract.Result<ReadOnlyCollection<T>>() != null);
return new ReadOnlyCollection<T>(this);
}
-
+
// Searches a section of the list for a given element using a binary search
// algorithm. Elements of the list are compared to the search value using
// the given IComparer interface. If comparer is null, elements of
@@ -264,7 +322,8 @@ namespace System.Collections.Generic {
// The method uses the Array.BinarySearch method to perform the
// search.
//
- public int BinarySearch(int index, int count, T item, IComparer<T> comparer) {
+ public int BinarySearch(int index, int count, T item, IComparer<T> comparer)
+ {
if (index < 0)
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
if (count < 0)
@@ -276,7 +335,7 @@ namespace System.Collections.Generic {
return Array.BinarySearch<T>(_items, index, count, item, comparer);
}
-
+
public int BinarySearch(T item)
{
Contract.Ensures(Contract.Result<int>() <= Count);
@@ -289,17 +348,27 @@ namespace System.Collections.Generic {
return BinarySearch(0, Count, item, comparer);
}
-
+
// Clears the contents of List.
- public void Clear() {
- if (_size > 0)
+ public void Clear()
+ {
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
- Array.Clear(_items, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references.
+ int size = _size;
_size = 0;
+ _version++;
+ if (size > 0)
+ {
+ Array.Clear(_items, 0, size); // Clear the elements so that the gc can reclaim the references.
+ }
+ }
+ else
+ {
+ _size = 0;
+ _version++;
}
- _version++;
}
-
+
// Contains returns true if the specified element is in the List.
// It does a linear, O(n) search. Equality is determined by calling
// EqualityComparer<T>.Default.Equals().
@@ -319,21 +388,25 @@ namespace System.Collections.Generic {
bool System.Collections.IList.Contains(Object item)
{
- if(IsCompatibleObject(item)) {
- return Contains((T) item);
+ if (IsCompatibleObject(item))
+ {
+ return Contains((T)item);
}
return false;
}
- public List<TOutput> ConvertAll<TOutput>(Converter<T,TOutput> converter) {
- if( converter == null) {
+ public List<TOutput> ConvertAll<TOutput>(Converter<T, TOutput> converter)
+ {
+ if (converter == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.converter);
}
Contract.EndContractBlock();
List<TOutput> list = new List<TOutput>(_size);
- for( int i = 0; i< _size; i++) {
+ for (int i = 0; i < _size; i++)
+ {
list._items[i] = converter(_items[i]);
}
list._size = _size;
@@ -343,43 +416,51 @@ namespace System.Collections.Generic {
// Copies this List into array, which must be of a
// compatible array type.
//
- public void CopyTo(T[] array) {
+ public void CopyTo(T[] array)
+ {
CopyTo(array, 0);
}
// Copies this List into array, which must be of a
// compatible array type.
//
- void System.Collections.ICollection.CopyTo(Array array, int arrayIndex) {
- if ((array != null) && (array.Rank != 1)) {
+ void System.Collections.ICollection.CopyTo(Array array, int arrayIndex)
+ {
+ if ((array != null) && (array.Rank != 1))
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
Contract.EndContractBlock();
- try {
+ try
+ {
// Array.Copy will check for NULL.
Array.Copy(_items, 0, array, arrayIndex, _size);
}
- catch(ArrayTypeMismatchException){
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
-
+
// Copies a section of this list to the given array at the given index.
//
// The method uses the Array.Copy method to copy the elements.
//
- public void CopyTo(int index, T[] array, int arrayIndex, int count) {
- if (_size - index < count) {
+ public void CopyTo(int index, T[] array, int arrayIndex, int count)
+ {
+ if (_size - index < count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
}
Contract.EndContractBlock();
-
+
// Delegate rest of error checking to Array.Copy.
Array.Copy(_items, index, array, arrayIndex, count);
}
- public void CopyTo(T[] array, int arrayIndex) {
+ public void CopyTo(T[] array, int arrayIndex)
+ {
// Delegate rest of error checking to Array.Copy.
Array.Copy(_items, 0, array, arrayIndex, _size);
}
@@ -388,9 +469,11 @@ namespace System.Collections.Generic {
// value. If the current capacity of the list is less than min, the
// capacity is increased to twice the current capacity or to min,
// whichever is larger.
- private void EnsureCapacity(int min) {
- if (_items.Length < min) {
- int newCapacity = _items.Length == 0? _defaultCapacity : _items.Length * 2;
+ private void EnsureCapacity(int min)
+ {
+ if (_items.Length < min)
+ {
+ int newCapacity = _items.Length == 0 ? _defaultCapacity : _items.Length * 2;
// Allow the list to grow to maximum possible capacity (~2G elements) before encountering overflow.
// Note that this check works even when _items.Length overflowed thanks to the (uint) cast
if ((uint)newCapacity > Array.MaxArrayLength) newCapacity = Array.MaxArrayLength;
@@ -398,62 +481,77 @@ namespace System.Collections.Generic {
Capacity = newCapacity;
}
}
-
- public bool Exists(Predicate<T> match) {
+
+ public bool Exists(Predicate<T> match)
+ {
return FindIndex(match) != -1;
}
- public T Find(Predicate<T> match) {
- if( match == null) {
+ public T Find(Predicate<T> match)
+ {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.EndContractBlock();
- for(int i = 0 ; i < _size; i++) {
- if(match(_items[i])) {
+ for (int i = 0; i < _size; i++)
+ {
+ if (match(_items[i]))
+ {
return _items[i];
}
}
return default(T);
}
-
- public List<T> FindAll(Predicate<T> match) {
- if( match == null) {
+
+ public List<T> FindAll(Predicate<T> match)
+ {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.EndContractBlock();
- List<T> list = new List<T>();
- for(int i = 0 ; i < _size; i++) {
- if(match(_items[i])) {
+ List<T> list = new List<T>();
+ for (int i = 0; i < _size; i++)
+ {
+ if (match(_items[i]))
+ {
list.Add(_items[i]);
}
}
return list;
}
-
- public int FindIndex(Predicate<T> match) {
+
+ public int FindIndex(Predicate<T> match)
+ {
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() < Count);
return FindIndex(0, _size, match);
}
-
- public int FindIndex(int startIndex, Predicate<T> match) {
+
+ public int FindIndex(int startIndex, Predicate<T> match)
+ {
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() < startIndex + Count);
return FindIndex(startIndex, _size - startIndex, match);
}
-
- public int FindIndex(int startIndex, int count, Predicate<T> match) {
- if( (uint)startIndex > (uint)_size ) {
- ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
+
+ public int FindIndex(int startIndex, int count, Predicate<T> match)
+ {
+ if ((uint)startIndex > (uint)_size)
+ {
+ ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
- if (count < 0 || startIndex > _size - count) {
+ if (count < 0 || startIndex > _size - count)
+ {
ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
- if( match == null) {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.Ensures(Contract.Result<int>() >= -1);
@@ -461,83 +559,103 @@ namespace System.Collections.Generic {
Contract.EndContractBlock();
int endIndex = startIndex + count;
- for( int i = startIndex; i < endIndex; i++) {
- if( match(_items[i])) return i;
+ for (int i = startIndex; i < endIndex; i++)
+ {
+ if (match(_items[i])) return i;
}
return -1;
}
-
- public T FindLast(Predicate<T> match) {
- if( match == null) {
+
+ public T FindLast(Predicate<T> match)
+ {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.EndContractBlock();
- for(int i = _size - 1 ; i >= 0; i--) {
- if(match(_items[i])) {
+ for (int i = _size - 1; i >= 0; i--)
+ {
+ if (match(_items[i]))
+ {
return _items[i];
}
}
return default(T);
}
- public int FindLastIndex(Predicate<T> match) {
+ public int FindLastIndex(Predicate<T> match)
+ {
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() < Count);
return FindLastIndex(_size - 1, _size, match);
}
-
- public int FindLastIndex(int startIndex, Predicate<T> match) {
+
+ public int FindLastIndex(int startIndex, Predicate<T> match)
+ {
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() <= startIndex);
return FindLastIndex(startIndex, startIndex + 1, match);
}
- public int FindLastIndex(int startIndex, int count, Predicate<T> match) {
- if( match == null) {
+ public int FindLastIndex(int startIndex, int count, Predicate<T> match)
+ {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() <= startIndex);
Contract.EndContractBlock();
- if(_size == 0) {
+ if (_size == 0)
+ {
// Special case for 0 length List
- if( startIndex != -1) {
+ if (startIndex != -1)
+ {
ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
}
- else {
+ else
+ {
// Make sure we're not out of range
- if ( (uint)startIndex >= (uint)_size) {
+ if ((uint)startIndex >= (uint)_size)
+ {
ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index();
}
}
-
+
// 2nd have of this also catches when startIndex == MAXINT, so MAXINT - 0 + 1 == -1, which is < 0.
- if (count < 0 || startIndex - count + 1 < 0) {
+ if (count < 0 || startIndex - count + 1 < 0)
+ {
ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
}
-
+
int endIndex = startIndex - count;
- for( int i = startIndex; i > endIndex; i--) {
- if( match(_items[i])) {
+ for (int i = startIndex; i > endIndex; i--)
+ {
+ if (match(_items[i]))
+ {
return i;
}
}
return -1;
}
- public void ForEach(Action<T> action) {
- if( action == null) {
+ public void ForEach(Action<T> action)
+ {
+ if (action == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.action);
}
Contract.EndContractBlock();
int version = _version;
- for(int i = 0 ; i < _size; i++) {
- if (version != _version) {
+ for (int i = 0; i < _size; i++)
+ {
+ if (version != _version)
+ {
break;
}
action(_items[i]);
@@ -552,36 +670,42 @@ namespace System.Collections.Generic {
// while an enumeration is in progress, the MoveNext and
// GetObject methods of the enumerator will throw an exception.
//
- public Enumerator GetEnumerator() {
+ public Enumerator GetEnumerator()
+ {
return new Enumerator(this);
}
- /// <internalonly/>
- IEnumerator<T> IEnumerable<T>.GetEnumerator() {
+ IEnumerator<T> IEnumerable<T>.GetEnumerator()
+ {
return new Enumerator(this);
}
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
return new Enumerator(this);
}
- public List<T> GetRange(int index, int count) {
- if (index < 0) {
+ public List<T> GetRange(int index, int count)
+ {
+ if (index < 0)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (count < 0) {
+ if (count < 0)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
- if (_size - index < count) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
+ if (_size - index < count)
+ {
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
}
Contract.Ensures(Contract.Result<List<T>>() != null);
Contract.EndContractBlock();
List<T> list = new List<T>(count);
- Array.Copy(_items, index, list._items, 0, count);
+ Array.Copy(_items, index, list._items, 0, count);
list._size = count;
return list;
}
@@ -595,7 +719,8 @@ namespace System.Collections.Generic {
// This method uses the Array.IndexOf method to perform the
// search.
//
- public int IndexOf(T item) {
+ public int IndexOf(T item)
+ {
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() < Count);
return Array.IndexOf(_items, item, 0, _size);
@@ -603,7 +728,8 @@ namespace System.Collections.Generic {
int System.Collections.IList.IndexOf(Object item)
{
- if(IsCompatibleObject(item)) {
+ if (IsCompatibleObject(item))
+ {
return IndexOf((T)item);
}
return -1;
@@ -618,7 +744,8 @@ namespace System.Collections.Generic {
// This method uses the Array.IndexOf method to perform the
// search.
//
- public int IndexOf(T item, int index) {
+ public int IndexOf(T item, int index)
+ {
if (index > _size)
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
Contract.Ensures(Contract.Result<int>() >= -1);
@@ -636,46 +763,52 @@ namespace System.Collections.Generic {
// This method uses the Array.IndexOf method to perform the
// search.
//
- public int IndexOf(T item, int index, int count) {
+ public int IndexOf(T item, int index, int count)
+ {
if (index > _size)
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
- if (count <0 || index > _size - count) ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
+ if (count < 0 || index > _size - count) ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count();
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() < Count);
Contract.EndContractBlock();
return Array.IndexOf(_items, item, index, count);
}
-
+
// Inserts an element into this list at a given index. The size of the list
// is increased by one. If required, the capacity of the list is doubled
// before inserting the new element.
//
- public void Insert(int index, T item) {
+ public void Insert(int index, T item)
+ {
// Note that insertions at the end are legal.
- if ((uint) index > (uint)_size) {
+ if ((uint)index > (uint)_size)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_ListInsert);
}
Contract.EndContractBlock();
if (_size == _items.Length) EnsureCapacity(_size + 1);
- if (index < _size) {
+ if (index < _size)
+ {
Array.Copy(_items, index, _items, index + 1, _size - index);
}
_items[index] = item;
- _size++;
+ _size++;
_version++;
}
-
+
void System.Collections.IList.Insert(int index, Object item)
{
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(item, ExceptionArgument.item);
- try {
- Insert(index, (T) item);
+ try
+ {
+ Insert(index, (T)item);
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(item, typeof(T));
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(item, typeof(T));
}
}
@@ -684,44 +817,55 @@ namespace System.Collections.Generic {
// capacity or the new size, whichever is larger. Ranges may be added
// to the end of the list by setting index to the List's size.
//
- public void InsertRange(int index, IEnumerable<T> collection) {
- if (collection==null) {
+ public void InsertRange(int index, IEnumerable<T> collection)
+ {
+ if (collection == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
-
- if ((uint)index > (uint)_size) {
+
+ if ((uint)index > (uint)_size)
+ {
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
}
Contract.EndContractBlock();
ICollection<T> c = collection as ICollection<T>;
- if( c != null ) { // if collection is ICollection<T>
+ if (c != null)
+ { // if collection is ICollection<T>
int count = c.Count;
- if (count > 0) {
+ if (count > 0)
+ {
EnsureCapacity(_size + count);
- if (index < _size) {
+ if (index < _size)
+ {
Array.Copy(_items, index, _items, index + count, _size - index);
}
-
+
// If we're inserting a List into itself, we want to be able to deal with that.
- if (this == c) {
+ if (this == c)
+ {
// Copy first part of _items to insert location
Array.Copy(_items, 0, _items, index, index);
// Copy last part of _items back to inserted location
- Array.Copy(_items, index+count, _items, index*2, _size-index);
+ Array.Copy(_items, index + count, _items, index * 2, _size - index);
}
- else {
+ else
+ {
c.CopyTo(_items, index);
}
_size += count;
- }
+ }
}
- else if (index < _size) {
+ else if (index < _size)
+ {
// We're inserting a lazy enumerable. Call Insert on each of the constituent items.
- using(IEnumerator<T> en = collection.GetEnumerator()) {
- while(en.MoveNext()) {
- Insert(index++, en.Current);
- }
+ using (IEnumerator<T> en = collection.GetEnumerator())
+ {
+ while (en.MoveNext())
+ {
+ Insert(index++, en.Current);
+ }
}
}
else
@@ -729,9 +873,9 @@ namespace System.Collections.Generic {
// We're adding a lazy enumerable because the index is at the end of this list.
AddEnumerable(collection);
}
- _version++;
+ _version++;
}
-
+
// Returns the index of the last occurrence of a given value in a range of
// this list. The list is searched backwards, starting at the end
// and ending at the first element in the list. The elements of the list
@@ -744,10 +888,12 @@ namespace System.Collections.Generic {
{
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(Contract.Result<int>() < Count);
- if (_size == 0) { // Special case for empty list
+ if (_size == 0)
+ { // Special case for empty list
return -1;
}
- else {
+ else
+ {
return LastIndexOf(item, _size - 1, _size);
}
}
@@ -780,39 +926,47 @@ namespace System.Collections.Generic {
// This method uses the Array.LastIndexOf method to perform the
// search.
//
- public int LastIndexOf(T item, int index, int count) {
- if ((Count != 0) && (index < 0)) {
+ public int LastIndexOf(T item, int index, int count)
+ {
+ if ((Count != 0) && (index < 0))
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if ((Count !=0) && (count < 0)) {
+ if ((Count != 0) && (count < 0))
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.Ensures(Contract.Result<int>() >= -1);
Contract.Ensures(((Count == 0) && (Contract.Result<int>() == -1)) || ((Count > 0) && (Contract.Result<int>() <= index)));
Contract.EndContractBlock();
- if (_size == 0) { // Special case for empty list
+ if (_size == 0)
+ { // Special case for empty list
return -1;
}
- if (index >= _size) {
+ if (index >= _size)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_BiggerThanCollection);
}
- if (count > index + 1) {
+ if (count > index + 1)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_BiggerThanCollection);
- }
+ }
return Array.LastIndexOf(_items, item, index, count);
}
-
+
// Removes the element at the given index. The size of the list is
// decreased by one.
//
- public bool Remove(T item) {
+ public bool Remove(T item)
+ {
int index = IndexOf(item);
- if (index >= 0) {
+ if (index >= 0)
+ {
RemoveAt(index);
return true;
}
@@ -822,39 +976,48 @@ namespace System.Collections.Generic {
void System.Collections.IList.Remove(Object item)
{
- if(IsCompatibleObject(item)) {
- Remove((T) item);
+ if (IsCompatibleObject(item))
+ {
+ Remove((T)item);
}
}
// This method removes all items which matches the predicate.
// The complexity is O(n).
- public int RemoveAll(Predicate<T> match) {
- if( match == null) {
+ public int RemoveAll(Predicate<T> match)
+ {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.Ensures(Contract.Result<int>() >= 0);
Contract.Ensures(Contract.Result<int>() <= Contract.OldValue(Count));
Contract.EndContractBlock();
-
+
int freeIndex = 0; // the first free slot in items array
// Find the first item which needs to be removed.
- while( freeIndex < _size && !match(_items[freeIndex])) freeIndex++;
- if( freeIndex >= _size) return 0;
-
+ while (freeIndex < _size && !match(_items[freeIndex])) freeIndex++;
+ if (freeIndex >= _size) return 0;
+
int current = freeIndex + 1;
- while( current < _size) {
+ while (current < _size)
+ {
// Find the first item which needs to be kept.
- while( current < _size && match(_items[current])) current++;
+ while (current < _size && match(_items[current])) current++;
- if( current < _size) {
+ if (current < _size)
+ {
// copy item to the free slot.
_items[freeIndex++] = _items[current++];
}
- }
-
- Array.Clear(_items, freeIndex, _size - freeIndex);
+ }
+
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
+ {
+ Array.Clear(_items, freeIndex, _size - freeIndex); // Clear the elements so that the gc can reclaim the references.
+ }
+
int result = _size - freeIndex;
_size = freeIndex;
_version++;
@@ -864,61 +1027,80 @@ namespace System.Collections.Generic {
// Removes the element at the given index. The size of the list is
// decreased by one.
//
- public void RemoveAt(int index) {
- if ((uint)index >= (uint)_size) {
+ public void RemoveAt(int index)
+ {
+ if ((uint)index >= (uint)_size)
+ {
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
}
Contract.EndContractBlock();
_size--;
- if (index < _size) {
+ if (index < _size)
+ {
Array.Copy(_items, index + 1, _items, index, _size - index);
}
- _items[_size] = default(T);
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
+ {
+ _items[_size] = default(T);
+ }
_version++;
}
-
+
// Removes a range of elements from this list.
//
- public void RemoveRange(int index, int count) {
- if (index < 0) {
+ public void RemoveRange(int index, int count)
+ {
+ if (index < 0)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (count < 0) {
+ if (count < 0)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
-
+
if (_size - index < count)
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
Contract.EndContractBlock();
-
- if (count > 0) {
+
+ if (count > 0)
+ {
int i = _size;
_size -= count;
- if (index < _size) {
+ if (index < _size)
+ {
Array.Copy(_items, index + count, _items, index, _size - index);
}
- Array.Clear(_items, _size, count);
+
_version++;
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
+ {
+ Array.Clear(_items, _size, count);
+ }
}
}
-
+
// Reverses the elements in this list.
- public void Reverse() {
+ public void Reverse()
+ {
Reverse(0, Count);
}
-
+
// Reverses the elements in a range of this list. Following a call to this
// method, an element in the range given by index and count
// which was previously located at index i will now be located at
// index index + (index + count - i - 1).
//
- public void Reverse(int index, int count) {
- if (index < 0) {
+ public void Reverse(int index, int count)
+ {
+ if (index < 0)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
-
- if (count < 0) {
+
+ if (count < 0)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
@@ -926,12 +1108,13 @@ namespace System.Collections.Generic {
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
Contract.EndContractBlock();
- if (count > 1) {
+ if (count > 1)
+ {
Array.Reverse(_items, index, count);
}
_version++;
}
-
+
// Sorts the elements in this list. Uses the default comparer and
// Array.Sort.
public void Sort()
@@ -954,32 +1137,39 @@ namespace System.Collections.Generic {
//
// This method uses the Array.Sort method to sort the elements.
//
- public void Sort(int index, int count, IComparer<T> comparer) {
- if (index < 0) {
+ public void Sort(int index, int count, IComparer<T> comparer)
+ {
+ if (index < 0)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
-
- if (count < 0) {
+
+ if (count < 0)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
-
+
if (_size - index < count)
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
Contract.EndContractBlock();
- if (count > 1) {
+ if (count > 1)
+ {
Array.Sort<T>(_items, index, count, comparer);
}
_version++;
}
- public void Sort(Comparison<T> comparison) {
- if( comparison == null) {
+ public void Sort(Comparison<T> comparison)
+ {
+ if (comparison == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.comparison);
}
Contract.EndContractBlock();
- if (_size > 1) {
+ if (_size > 1)
+ {
ArraySortHelper<T>.Sort(_items, 0, _size, comparison);
}
_version++;
@@ -987,7 +1177,8 @@ namespace System.Collections.Generic {
// ToArray returns an array containing the contents of the List.
// This requires copying the List, which is an O(n) operation.
- public T[] ToArray() {
+ public T[] ToArray()
+ {
Contract.Ensures(Contract.Result<T[]>() != null);
Contract.Ensures(Contract.Result<T[]>().Length == Count);
@@ -1000,7 +1191,7 @@ namespace System.Collections.Generic {
Array.Copy(_items, 0, array, 0, _size);
return array;
}
-
+
// Sets the capacity of this list to the size of the list. This method can
// be used to minimize a list's memory overhead once it is known that no
// new elements will be added to the list. To completely clear a list and
@@ -1010,21 +1201,27 @@ namespace System.Collections.Generic {
// list.Clear();
// list.TrimExcess();
//
- public void TrimExcess() {
- int threshold = (int)(((double)_items.Length) * 0.9);
- if( _size < threshold ) {
- Capacity = _size;
+ public void TrimExcess()
+ {
+ int threshold = (int)(((double)_items.Length) * 0.9);
+ if (_size < threshold)
+ {
+ Capacity = _size;
}
- }
+ }
- public bool TrueForAll(Predicate<T> match) {
- if( match == null) {
+ public bool TrueForAll(Predicate<T> match)
+ {
+ if (match == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
Contract.EndContractBlock();
- for(int i = 0 ; i < _size; i++) {
- if( !match(_items[i])) {
+ for (int i = 0; i < _size; i++)
+ {
+ if (!match(_items[i]))
+ {
return false;
}
}
@@ -1064,23 +1261,25 @@ namespace System.Collections.Generic {
private int version;
private T current;
- internal Enumerator(List<T> list) {
+ internal Enumerator(List<T> list)
+ {
this.list = list;
index = 0;
version = list._version;
current = default(T);
}
- public void Dispose() {
+ public void Dispose()
+ {
}
- public bool MoveNext() {
-
+ public bool MoveNext()
+ {
List<T> localList = list;
- if (version == localList._version && ((uint)index < (uint)localList._size))
- {
- current = localList._items[index];
+ if (version == localList._version && ((uint)index < (uint)localList._size))
+ {
+ current = localList._items[index];
index++;
return true;
}
@@ -1088,40 +1287,47 @@ namespace System.Collections.Generic {
}
private bool MoveNextRare()
- {
- if (version != list._version) {
+ {
+ if (version != list._version)
+ {
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
index = list._size + 1;
current = default(T);
- return false;
+ return false;
}
- public T Current {
- get {
+ public T Current
+ {
+ get
+ {
return current;
}
}
- Object System.Collections.IEnumerator.Current {
- get {
- if( index == 0 || index == list._size + 1) {
- ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
+ Object System.Collections.IEnumerator.Current
+ {
+ get
+ {
+ if (index == 0 || index == list._size + 1)
+ {
+ ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
}
return Current;
}
}
-
- void System.Collections.IEnumerator.Reset() {
- if (version != list._version) {
+
+ void System.Collections.IEnumerator.Reset()
+ {
+ if (version != list._version)
+ {
ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
}
-
+
index = 0;
current = default(T);
}
-
}
}
}
diff --git a/src/mscorlib/src/System/Collections/Hashtable.cs b/src/mscorlib/src/System/Collections/Hashtable.cs
index d1831dd97d..e2fd57ea4d 100644
--- a/src/mscorlib/src/System/Collections/Hashtable.cs
+++ b/src/mscorlib/src/System/Collections/Hashtable.cs
@@ -13,12 +13,13 @@
**
===========================================================*/
-namespace System.Collections {
+namespace System.Collections
+{
using System;
using System.Runtime;
using System.Runtime.Serialization;
using System.Diagnostics;
- using System.Threading;
+ using System.Threading;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Diagnostics.Contracts;
@@ -66,7 +67,8 @@ namespace System.Collections {
[DebuggerTypeProxy(typeof(System.Collections.Hashtable.HashtableDebugView))]
[DebuggerDisplay("Count = {Count}")]
[Serializable]
- internal class Hashtable : IDictionary, ISerializable, IDeserializationCallback, ICloneable {
+ internal class Hashtable : IDictionary, ISerializable, IDeserializationCallback, ICloneable
+ {
/*
Implementation Notes:
The generic Dictionary was copied from Hashtable's source - any bug
@@ -121,7 +123,7 @@ namespace System.Collections {
--
*/
-
+
internal const Int32 HashPrime = 101;
private const Int32 InitialSize = 3;
private const String LoadFactorName = "LoadFactor";
@@ -132,31 +134,32 @@ namespace System.Collections {
private const String KeysName = "Keys";
private const String ValuesName = "Values";
private const String KeyComparerName = "KeyComparer";
-
+
// Deleted entries have their key set to buckets
-
+
// The hash table data.
// This cannot be serialised
- private struct bucket {
+ private struct bucket
+ {
public Object key;
public Object val;
public int hash_coll; // Store hash code; sign bit means there was a collision.
}
-
+
private bucket[] buckets;
-
+
// The total number of entries in the hash table.
- private int count;
-
+ private int count;
+
// The total number of collision bits set in the hashtable
private int occupancy;
-
- private int loadsize;
- private float loadFactor;
-
+
+ private int loadsize;
+ private float loadFactor;
+
private volatile int version;
- private volatile bool isWriterInProgress;
-
+ private volatile bool isWriterInProgress;
+
private ICollection keys;
private ICollection values;
@@ -165,15 +168,16 @@ namespace System.Collections {
// Note: this constructor is a bogus constructor that does nothing
// and is for use only with SyncHashtable.
- internal Hashtable( bool trash )
+ internal Hashtable(bool trash)
{
}
// Constructs a new hashtable. The hashtable is created with an initial
// capacity of zero and a load factor of 1.0.
- public Hashtable() : this(0, 1.0f) {
+ public Hashtable() : this(0, 1.0f)
+ {
}
-
+
// Constructs a new hashtable with the given initial capacity and a load
// factor of 1.0. The capacity argument serves as an indication of
// the number of entries the hashtable will contain. When this number (or
@@ -181,9 +185,10 @@ namespace System.Collections {
// eliminate a number of resizing operations that would otherwise be
// performed when elements are added to the hashtable.
//
- public Hashtable(int capacity) : this(capacity, 1.0f) {
+ public Hashtable(int capacity) : this(capacity, 1.0f)
+ {
}
-
+
// Constructs a new hashtable with the given initial capacity and load
// factor. The capacity argument serves as an indication of the
// number of entries the hashtable will contain. When this number (or an
@@ -195,19 +200,20 @@ namespace System.Collections {
// increased memory consumption. A load factor of 1.0 generally provides
// the best balance between speed and size.
//
- public Hashtable(int capacity, float loadFactor) {
+ public Hashtable(int capacity, float loadFactor)
+ {
if (capacity < 0)
- throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_NeedNonNegNum);
if (!(loadFactor >= 0.1f && loadFactor <= 1.0f))
- throw new ArgumentOutOfRangeException(nameof(loadFactor), Environment.GetResourceString("ArgumentOutOfRange_HashtableLoadFactor", .1, 1.0));
+ throw new ArgumentOutOfRangeException(nameof(loadFactor), SR.Format(SR.ArgumentOutOfRange_HashtableLoadFactor, .1, 1.0));
Contract.EndContractBlock();
-
+
// Based on perf work, .72 is the optimal load factor for this table.
this.loadFactor = 0.72f * loadFactor;
double rawsize = capacity / this.loadFactor;
if (rawsize > Int32.MaxValue)
- throw new ArgumentException(Environment.GetResourceString("Arg_HTCapacityOverflow"));
+ throw new ArgumentException(SR.Arg_HTCapacityOverflow);
// Avoid awfully small sizes
int hashsize = (rawsize > InitialSize) ? HashHelpers.GetPrime((int)rawsize) : InitialSize;
@@ -216,18 +222,21 @@ namespace System.Collections {
loadsize = (int)(this.loadFactor * hashsize);
isWriterInProgress = false;
// Based on the current algorithm, loadsize must be less than hashsize.
- Debug.Assert( loadsize < hashsize, "Invalid hashtable loadsize!");
+ Debug.Assert(loadsize < hashsize, "Invalid hashtable loadsize!");
}
-
- public Hashtable(int capacity, float loadFactor, IEqualityComparer equalityComparer) : this(capacity, loadFactor) {
- this._keycomparer = equalityComparer;
+
+ public Hashtable(int capacity, float loadFactor, IEqualityComparer equalityComparer) : this(capacity, loadFactor)
+ {
+ _keycomparer = equalityComparer;
}
- public Hashtable(IEqualityComparer equalityComparer) : this(0, 1.0f, equalityComparer) {
+ public Hashtable(IEqualityComparer equalityComparer) : this(0, 1.0f, equalityComparer)
+ {
}
-
- public Hashtable(int capacity, IEqualityComparer equalityComparer)
- : this(capacity, 1.0f, equalityComparer) {
+
+ public Hashtable(int capacity, IEqualityComparer equalityComparer)
+ : this(capacity, 1.0f, equalityComparer)
+ {
}
// InitHash is basically an implementation of classic DoubleHashing (see http://en.wikipedia.org/wiki/Double_hashing)
@@ -250,11 +259,12 @@ namespace System.Collections {
// The out parameter seed is h1(key), while the out parameter
// incr is h2(key, hashSize). Callers of this function should
// add incr each time through a loop.
- private uint InitHash(Object key, int hashsize, out uint seed, out uint incr) {
+ private uint InitHash(Object key, int hashsize, out uint seed, out uint incr)
+ {
// Hashcode must be positive. Also, we must not use the sign bit, since
// that is used for the collision bit.
- uint hashcode = (uint) GetHash(key) & 0x7FFFFFFF;
- seed = (uint) hashcode;
+ uint hashcode = (uint)GetHash(key) & 0x7FFFFFFF;
+ seed = (uint)hashcode;
// Restriction: incr MUST be between 1 and hashsize - 1, inclusive for
// the modular arithmetic to work correctly. This guarantees you'll
// visit every bucket in the table exactly once within hashsize
@@ -268,64 +278,72 @@ namespace System.Collections {
// ArgumentException is thrown if the key is null or if the key is already
// present in the hashtable.
//
- public virtual void Add(Object key, Object value) {
+ public virtual void Add(Object key, Object value)
+ {
Insert(key, value, true);
}
// Removes all entries from this hashtable.
- public virtual void Clear() {
+ public virtual void Clear()
+ {
Debug.Assert(!isWriterInProgress, "Race condition detected in usages of Hashtable - multiple threads appear to be writing to a Hashtable instance simultaneously! Don't do that - use Hashtable.Synchronized.");
if (count == 0 && occupancy == 0)
return;
isWriterInProgress = true;
- for (int i = 0; i < buckets.Length; i++){
+ for (int i = 0; i < buckets.Length; i++)
+ {
buckets[i].hash_coll = 0;
buckets[i].key = null;
buckets[i].val = null;
}
-
+
count = 0;
occupancy = 0;
- UpdateVersion();
- isWriterInProgress = false;
+ UpdateVersion();
+ isWriterInProgress = false;
}
-
+
// Clone returns a virtually identical copy of this hash table. This does
// a shallow copy - the Objects in the table aren't cloned, only the references
// to those Objects.
public virtual Object Clone()
- {
+ {
bucket[] lbuckets = buckets;
- Hashtable ht = new Hashtable(count,_keycomparer);
+ Hashtable ht = new Hashtable(count, _keycomparer);
ht.version = version;
ht.loadFactor = loadFactor;
ht.count = 0;
int bucket = lbuckets.Length;
- while (bucket > 0) {
+ while (bucket > 0)
+ {
bucket--;
Object keyv = lbuckets[bucket].key;
- if ((keyv!= null) && (keyv != lbuckets)) {
+ if ((keyv != null) && (keyv != lbuckets))
+ {
ht[keyv] = lbuckets[bucket].val;
}
}
return ht;
}
-
+
// Checks if this hashtable contains the given key.
- public virtual bool Contains(Object key) {
+ public virtual bool Contains(Object key)
+ {
return ContainsKey(key);
}
-
+
// Checks if this hashtable contains an entry with the given key. This is
// an O(1) operation.
//
- public virtual bool ContainsKey(Object key) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public virtual bool ContainsKey(Object key)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
@@ -334,68 +352,76 @@ namespace System.Collections {
// Take a snapshot of buckets, in case another thread resizes table
bucket[] lbuckets = buckets;
uint hashcode = InitHash(key, lbuckets.Length, out seed, out incr);
- int ntry = 0;
-
+ int ntry = 0;
+
bucket b;
- int bucketNumber = (int) (seed % (uint)lbuckets.Length);
- do {
+ int bucketNumber = (int)(seed % (uint)lbuckets.Length);
+ do
+ {
b = lbuckets[bucketNumber];
- if (b.key == null) {
+ if (b.key == null)
+ {
return false;
}
- if (((b.hash_coll & 0x7FFFFFFF) == hashcode) &&
- KeyEquals (b.key, key))
+ if (((b.hash_coll & 0x7FFFFFFF) == hashcode) &&
+ KeyEquals(b.key, key))
return true;
- bucketNumber = (int) (((long)bucketNumber + incr)% (uint)lbuckets.Length);
+ bucketNumber = (int)(((long)bucketNumber + incr) % (uint)lbuckets.Length);
} while (b.hash_coll < 0 && ++ntry < lbuckets.Length);
return false;
}
-
+
// Copies the keys of this hashtable to a given array starting at a given
// index. This method is used by the implementation of the CopyTo method in
// the KeyCollection class.
- private void CopyKeys(Array array, int arrayIndex) {
+ private void CopyKeys(Array array, int arrayIndex)
+ {
Contract.Requires(array != null);
Contract.Requires(array.Rank == 1);
bucket[] lbuckets = buckets;
- for (int i = lbuckets.Length; --i >= 0;) {
+ for (int i = lbuckets.Length; --i >= 0;)
+ {
Object keyv = lbuckets[i].key;
- if ((keyv != null) && (keyv != buckets)){
+ if ((keyv != null) && (keyv != buckets))
+ {
array.SetValue(keyv, arrayIndex++);
}
- }
+ }
}
// Copies the keys of this hashtable to a given array starting at a given
// index. This method is used by the implementation of the CopyTo method in
// the KeyCollection class.
- private void CopyEntries(Array array, int arrayIndex) {
+ private void CopyEntries(Array array, int arrayIndex)
+ {
Contract.Requires(array != null);
Contract.Requires(array.Rank == 1);
bucket[] lbuckets = buckets;
- for (int i = lbuckets.Length; --i >= 0;) {
+ for (int i = lbuckets.Length; --i >= 0;)
+ {
Object keyv = lbuckets[i].key;
- if ((keyv != null) && (keyv != buckets)){
- DictionaryEntry entry = new DictionaryEntry(keyv,lbuckets[i].val);
+ if ((keyv != null) && (keyv != buckets))
+ {
+ DictionaryEntry entry = new DictionaryEntry(keyv, lbuckets[i].val);
array.SetValue(entry, arrayIndex++);
}
}
}
-
+
// Copies the values in this hash table to an array at
// a given index. Note that this only copies values, and not keys.
public virtual void CopyTo(Array array, int arrayIndex)
{
if (array == null)
- throw new ArgumentNullException(nameof(array), Environment.GetResourceString("ArgumentNull_Array"));
+ throw new ArgumentNullException(nameof(array), SR.ArgumentNull_Array);
if (array.Rank != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
- if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
+ if (arrayIndex < 0)
+ throw new ArgumentOutOfRangeException(nameof(arrayIndex), SR.ArgumentOutOfRange_NeedNonNegNum);
if (array.Length - arrayIndex < Count)
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall"));
+ throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall);
Contract.EndContractBlock();
CopyEntries(array, arrayIndex);
}
@@ -404,40 +430,46 @@ namespace System.Collections {
// Copies the values of this hashtable to a given array starting at a given
// index. This method is used by the implementation of the CopyTo method in
// the ValueCollection class.
- private void CopyValues(Array array, int arrayIndex) {
+ private void CopyValues(Array array, int arrayIndex)
+ {
Contract.Requires(array != null);
Contract.Requires(array.Rank == 1);
bucket[] lbuckets = buckets;
- for (int i = lbuckets.Length; --i >= 0;) {
+ for (int i = lbuckets.Length; --i >= 0;)
+ {
Object keyv = lbuckets[i].key;
- if ((keyv != null) && (keyv != buckets)){
+ if ((keyv != null) && (keyv != buckets))
+ {
array.SetValue(lbuckets[i].val, arrayIndex++);
}
}
}
-
+
// Returns the value associated with the given key. If an entry with the
// given key is not found, the returned value is null.
//
- public virtual Object this[Object key] {
- get {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public virtual Object this[Object key]
+ {
+ get
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
uint seed;
uint incr;
-
+
// Take a snapshot of buckets, in case another thread does a resize
bucket[] lbuckets = buckets;
uint hashcode = InitHash(key, lbuckets.Length, out seed, out incr);
- int ntry = 0;
-
+ int ntry = 0;
+
bucket b;
- int bucketNumber = (int) (seed % (uint)lbuckets.Length);
+ int bucketNumber = (int)(seed % (uint)lbuckets.Length);
do
{
int currentversion;
@@ -459,35 +491,39 @@ namespace System.Collections {
// we will see the 'isWriterProgress' flag to be true or 'version' is changed in the reader.
//
int spinCount = 0;
- do {
+ do
+ {
// this is violate read, following memory accesses can not be moved ahead of it.
currentversion = version;
- b = lbuckets[bucketNumber];
+ b = lbuckets[bucketNumber];
// The contention between reader and writer shouldn't happen frequently.
// But just in case this will burn CPU, yield the control of CPU if we spinned a few times.
// 8 is just a random number I pick.
- if( (++spinCount) % 8 == 0 ) {
+ if ((++spinCount) % 8 == 0)
+ {
Thread.Sleep(1); // 1 means we are yeilding control to all threads, including low-priority ones.
}
- } while ( isWriterInProgress || (currentversion != version) );
+ } while (isWriterInProgress || (currentversion != version));
- if (b.key == null) {
+ if (b.key == null)
+ {
return null;
}
- if (((b.hash_coll & 0x7FFFFFFF) == hashcode) &&
- KeyEquals (b.key, key))
+ if (((b.hash_coll & 0x7FFFFFFF) == hashcode) &&
+ KeyEquals(b.key, key))
return b.val;
- bucketNumber = (int) (((long)bucketNumber + incr)% (uint)lbuckets.Length);
+ bucketNumber = (int)(((long)bucketNumber + incr) % (uint)lbuckets.Length);
} while (b.hash_coll < 0 && ++ntry < lbuckets.Length);
return null;
}
- set {
+ set
+ {
Insert(key, value, false);
}
}
-
+
// Increases the bucket count of this hashtable. This method is called from
// the Insert method when the actual load factor of the hashtable reaches
// the upper limit specified when the hashtable was constructed. The number
@@ -495,27 +531,30 @@ namespace System.Collections {
// that is larger than twice the current number of buckets, and the entries
// in the hashtable are redistributed into the new buckets using the cached
// hashcodes.
- private void expand() {
+ private void expand()
+ {
int rawsize = HashHelpers.ExpandPrime(buckets.Length);
rehash(rawsize, false);
}
// We occationally need to rehash the table to clean up the collision bits.
- private void rehash() {
- rehash( buckets.Length, false );
+ private void rehash()
+ {
+ rehash(buckets.Length, false);
}
- private void UpdateVersion() {
+ private void UpdateVersion()
+ {
// Version might become negative when version is Int32.MaxValue, but the oddity will be still be correct.
// So we don't need to special case this.
version++;
}
- private void rehash( int newsize, bool forceNewHashCode ) {
-
+ private void rehash(int newsize, bool forceNewHashCode)
+ {
// reset occupancy
- occupancy=0;
-
+ occupancy = 0;
+
// Don't replace any internal state until we've finished adding to the
// new bucket[]. This serves two purposes:
// 1) Allow concurrent readers to see valid hashtable contents
@@ -523,12 +562,14 @@ namespace System.Collections {
// 2) Protect against an OutOfMemoryException while allocating this
// new bucket[].
bucket[] newBuckets = new bucket[newsize];
-
+
// rehash table into new buckets
int nb;
- for (nb = 0; nb < buckets.Length; nb++){
+ for (nb = 0; nb < buckets.Length; nb++)
+ {
bucket oldb = buckets[nb];
- if ((oldb.key != null) && (oldb.key != buckets)) {
+ if ((oldb.key != null) && (oldb.key != buckets))
+ {
int hashcode = ((forceNewHashCode ? GetHash(oldb.key) : oldb.hash_coll) & 0x7FFFFFFF);
putEntry(newBuckets, oldb.key, oldb.val, hashcode);
}
@@ -551,7 +592,8 @@ namespace System.Collections {
// in progress, the MoveNext and Current methods of the
// enumerator will throw an exception.
//
- IEnumerator IEnumerable.GetEnumerator() {
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return new HashtableEnumerator(this, HashtableEnumerator.DictEntry);
}
@@ -560,10 +602,11 @@ namespace System.Collections {
// in progress, the MoveNext and Current methods of the
// enumerator will throw an exception.
//
- public virtual IDictionaryEnumerator GetEnumerator() {
+ public virtual IDictionaryEnumerator GetEnumerator()
+ {
return new HashtableEnumerator(this, HashtableEnumerator.DictEntry);
}
-
+
// Internal method to get the hash code for an Object. This will call
// GetHashCode() on each object if you haven't provided an IHashCodeProvider
// instance. Otherwise, it calls hcp.GetHashCode(obj).
@@ -575,16 +618,19 @@ namespace System.Collections {
}
// Is this Hashtable read-only?
- public virtual bool IsReadOnly {
+ public virtual bool IsReadOnly
+ {
get { return false; }
}
- public virtual bool IsFixedSize {
+ public virtual bool IsFixedSize
+ {
get { return false; }
}
// Is this Hashtable synchronized? See SyncRoot property
- public virtual bool IsSynchronized {
+ public virtual bool IsSynchronized
+ {
get { return false; }
}
@@ -595,11 +641,12 @@ namespace System.Collections {
protected virtual bool KeyEquals(Object item, Object key)
{
Debug.Assert(key != null, "key can't be null here!");
- if( Object.ReferenceEquals(buckets, item)) {
+ if (Object.ReferenceEquals(buckets, item))
+ {
return false;
}
- if (Object.ReferenceEquals(item,key))
+ if (Object.ReferenceEquals(item, key))
return true;
if (_keycomparer != null)
@@ -616,13 +663,15 @@ namespace System.Collections {
// to the hash table are reflected in this collection. It is not
// a static copy of all the keys in the hash table.
//
- public virtual ICollection Keys {
- get {
+ public virtual ICollection Keys
+ {
+ get
+ {
if (keys == null) keys = new KeyCollection(this);
- return keys;
+ return keys;
}
}
-
+
// Returns a collection representing the values of this hashtable. The
// order in which the returned collection represents the values is
// unspecified, but it is guaranteed to be the same order in which a
@@ -633,39 +682,45 @@ namespace System.Collections {
// to the hash table are reflected in this collection. It is not
// a static copy of all the keys in the hash table.
//
- public virtual ICollection Values {
- get {
+ public virtual ICollection Values
+ {
+ get
+ {
if (values == null) values = new ValueCollection(this);
- return values;
+ return values;
}
}
-
+
// Inserts an entry into this hashtable. This method is called from the Set
// and Add methods. If the add parameter is true and the given key already
// exists in the hashtable, an exception is thrown.
- private void Insert (Object key, Object nvalue, bool add) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ private void Insert(Object key, Object nvalue, bool add)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
- if (count >= loadsize) {
+ if (count >= loadsize)
+ {
expand();
}
- else if(occupancy > loadsize && count > 100) {
+ else if (occupancy > loadsize && count > 100)
+ {
rehash();
}
-
+
uint seed;
uint incr;
// Assume we only have one thread writing concurrently. Modify
// buckets to contain new data, as long as we insert in the right order.
uint hashcode = InitHash(key, buckets.Length, out seed, out incr);
- int ntry = 0;
+ int ntry = 0;
int emptySlotNumber = -1; // We use the empty slot number to cache the first empty slot. We chose to reuse slots
// create by remove that have the collision bit set over using up new slots.
- int bucketNumber = (int) (seed % (uint)buckets.Length);
- do {
-
+ int bucketNumber = (int)(seed % (uint)buckets.Length);
+ do
+ {
// Set emptySlot number to current bucket if it is the first available bucket that we have seen
// that once contained an entry and also has had a collision.
// We need to search this entire collision chain because we have to ensure that there are no
@@ -676,9 +731,9 @@ namespace System.Collections {
// Insert the key/value pair into this bucket if this bucket is empty and has never contained an entry
// OR
// This bucket once contained an entry but there has never been a collision
- if ((buckets[bucketNumber].key == null) ||
- (buckets[bucketNumber].key == buckets && ((buckets[bucketNumber].hash_coll & unchecked(0x80000000))==0))) {
-
+ if ((buckets[bucketNumber].key == null) ||
+ (buckets[bucketNumber].key == buckets && ((buckets[bucketNumber].hash_coll & unchecked(0x80000000)) == 0)))
+ {
// If we have found an available bucket that has never had a collision, but we've seen an available
// bucket in the past that has the collision bit set, use the previous bucket instead
if (emptySlotNumber != -1) // Reuse slot
@@ -688,11 +743,11 @@ namespace System.Collections {
// code until the value & key are set appropriately.
isWriterInProgress = true;
buckets[bucketNumber].val = nvalue;
- buckets[bucketNumber].key = key;
- buckets[bucketNumber].hash_coll |= (int) hashcode;
+ buckets[bucketNumber].key = key;
+ buckets[bucketNumber].hash_coll |= (int)hashcode;
count++;
UpdateVersion();
- isWriterInProgress = false;
+ isWriterInProgress = false;
return;
}
@@ -700,29 +755,33 @@ namespace System.Collections {
// The current bucket is in use
// OR
// it is available, but has had the collision bit set and we have already found an available bucket
- if (((buckets[bucketNumber].hash_coll & 0x7FFFFFFF) == hashcode) &&
- KeyEquals (buckets[bucketNumber].key, key)) {
- if (add) {
- throw new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicate__", buckets[bucketNumber].key, key));
+ if (((buckets[bucketNumber].hash_coll & 0x7FFFFFFF) == hashcode) &&
+ KeyEquals(buckets[bucketNumber].key, key))
+ {
+ if (add)
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_AddingDuplicate__, buckets[bucketNumber].key, key));
}
isWriterInProgress = true;
buckets[bucketNumber].val = nvalue;
UpdateVersion();
- isWriterInProgress = false;
+ isWriterInProgress = false;
return;
}
// The current bucket is full, and we have therefore collided. We need to set the collision bit
// UNLESS
// we have remembered an available slot previously.
- if (emptySlotNumber == -1) {// We don't need to set the collision bit here since we already have an empty slot
- if( buckets[bucketNumber].hash_coll >= 0 ) {
+ if (emptySlotNumber == -1)
+ {// We don't need to set the collision bit here since we already have an empty slot
+ if (buckets[bucketNumber].hash_coll >= 0)
+ {
buckets[bucketNumber].hash_coll |= unchecked((int)0x80000000);
occupancy++;
}
}
- bucketNumber = (int) (((long)bucketNumber + incr)% (uint)buckets.Length);
+ bucketNumber = (int)(((long)bucketNumber + incr) % (uint)buckets.Length);
} while (++ntry < buckets.Length);
// This code is here if and only if there were no buckets without a collision bit set in the entire table
@@ -732,11 +791,11 @@ namespace System.Collections {
// code until the value & key are set appropriately.
isWriterInProgress = true;
buckets[emptySlotNumber].val = nvalue;
- buckets[emptySlotNumber].key = key;
- buckets[emptySlotNumber].hash_coll |= (int) hashcode;
+ buckets[emptySlotNumber].key = key;
+ buckets[emptySlotNumber].hash_coll |= (int)hashcode;
count++;
- UpdateVersion();
- isWriterInProgress = false;
+ UpdateVersion();
+ isWriterInProgress = false;
return;
}
@@ -745,40 +804,44 @@ namespace System.Collections {
// Then verify that our double hash function (h2, described at top of file)
// meets the requirements described above. You should never see this assert.
Debug.Assert(false, "hash table insert failed! Load factor too high, or our double hashing function is incorrect.");
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HashInsertFailed"));
+ throw new InvalidOperationException(SR.InvalidOperation_HashInsertFailed);
}
-
- private void putEntry (bucket[] newBuckets, Object key, Object nvalue, int hashcode)
+
+ private void putEntry(bucket[] newBuckets, Object key, Object nvalue, int hashcode)
{
Debug.Assert(hashcode >= 0, "hashcode >= 0"); // make sure collision bit (sign bit) wasn't set.
- uint seed = (uint) hashcode;
+ uint seed = (uint)hashcode;
uint incr = (uint)(1 + ((seed * HashPrime) % ((uint)newBuckets.Length - 1)));
- int bucketNumber = (int) (seed % (uint)newBuckets.Length);
- do {
-
- if ((newBuckets[bucketNumber].key == null) || (newBuckets[bucketNumber].key == buckets)) {
+ int bucketNumber = (int)(seed % (uint)newBuckets.Length);
+ do
+ {
+ if ((newBuckets[bucketNumber].key == null) || (newBuckets[bucketNumber].key == buckets))
+ {
newBuckets[bucketNumber].val = nvalue;
newBuckets[bucketNumber].key = key;
newBuckets[bucketNumber].hash_coll |= hashcode;
return;
}
-
- if( newBuckets[bucketNumber].hash_coll >= 0 ) {
- newBuckets[bucketNumber].hash_coll |= unchecked((int)0x80000000);
+
+ if (newBuckets[bucketNumber].hash_coll >= 0)
+ {
+ newBuckets[bucketNumber].hash_coll |= unchecked((int)0x80000000);
occupancy++;
}
- bucketNumber = (int) (((long)bucketNumber + incr)% (uint)newBuckets.Length);
+ bucketNumber = (int)(((long)bucketNumber + incr) % (uint)newBuckets.Length);
} while (true);
}
-
+
// Removes an entry from this hashtable. If an entry with the specified
// key exists in the hashtable, it is removed. An ArgumentException is
// thrown if the key is null.
//
- public virtual void Remove(Object key) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public virtual void Remove(Object key)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
Debug.Assert(!isWriterInProgress, "Race condition detected in usages of Hashtable - multiple threads appear to be writing to a Hashtable instance simultaneously! Don't do that - use Hashtable.Synchronized.");
@@ -788,124 +851,135 @@ namespace System.Collections {
// Assuming only one concurrent writer, write directly into buckets.
uint hashcode = InitHash(key, buckets.Length, out seed, out incr);
int ntry = 0;
-
+
bucket b;
- int bn = (int) (seed % (uint)buckets.Length); // bucketNumber
- do {
+ int bn = (int)(seed % (uint)buckets.Length); // bucketNumber
+ do
+ {
b = buckets[bn];
- if (((b.hash_coll & 0x7FFFFFFF) == hashcode) &&
- KeyEquals (b.key, key)) {
+ if (((b.hash_coll & 0x7FFFFFFF) == hashcode) &&
+ KeyEquals(b.key, key))
+ {
isWriterInProgress = true;
// Clear hash_coll field, then key, then value
buckets[bn].hash_coll &= unchecked((int)0x80000000);
- if (buckets[bn].hash_coll != 0) {
+ if (buckets[bn].hash_coll != 0)
+ {
buckets[bn].key = buckets;
- }
- else {
+ }
+ else
+ {
buckets[bn].key = null;
}
buckets[bn].val = null; // Free object references sooner & simplify ContainsValue.
count--;
UpdateVersion();
- isWriterInProgress = false;
+ isWriterInProgress = false;
return;
}
- bn = (int) (((long)bn + incr)% (uint)buckets.Length);
+ bn = (int)(((long)bn + incr) % (uint)buckets.Length);
} while (b.hash_coll < 0 && ++ntry < buckets.Length);
- //throw new ArgumentException(Environment.GetResourceString("Arg_RemoveArgNotFound"));
+ //throw new ArgumentException(SR.Arg_RemoveArgNotFound);
}
-
+
// Returns the object to synchronize on for this hash table.
- public virtual Object SyncRoot {
- get {
- if( _syncRoot == null) {
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ public virtual Object SyncRoot
+ {
+ get
+ {
+ if (_syncRoot == null)
+ {
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
- return _syncRoot;
+ return _syncRoot;
}
}
-
+
// Returns the number of associations in this hashtable.
//
- public virtual int Count {
+ public virtual int Count
+ {
get { return count; }
}
-
+
// Returns a thread-safe wrapper for a Hashtable.
//
- public static Hashtable Synchronized(Hashtable table) {
- if (table==null)
+ public static Hashtable Synchronized(Hashtable table)
+ {
+ if (table == null)
throw new ArgumentNullException(nameof(table));
Contract.EndContractBlock();
return new SyncHashtable(table);
}
-
+
//
// The ISerializable Implementation
//
- public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
+ public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
// This is imperfect - it only works well if all other writes are
// also using our synchronized wrapper. But it's still a good idea.
- lock (SyncRoot) {
+ lock (SyncRoot)
+ {
// This method hasn't been fully tweaked to be safe for a concurrent writer.
int oldVersion = version;
- info.AddValue(LoadFactorName, loadFactor);
- info.AddValue(VersionName, version);
-
- //
- // We need to maintain serialization compatibility with Everett and RTM.
- // If the comparer is null or a compatible comparer, serialize Hashtable
- // in a format that can be deserialized on Everett and RTM.
- //
- // Also, if the Hashtable is using randomized hashing, serialize the old
- // view of the _keycomparer so perevious frameworks don't see the new types
+ info.AddValue(LoadFactorName, loadFactor);
+ info.AddValue(VersionName, version);
+
+ //
+ // We need to maintain serialization compatibility with Everett and RTM.
+ // If the comparer is null or a compatible comparer, serialize Hashtable
+ // in a format that can be deserialized on Everett and RTM.
+ //
#pragma warning disable 618
-#if FEATURE_RANDOMIZED_STRING_HASHING
- IEqualityComparer keyComparerForSerilization = (IEqualityComparer) HashHelpers.GetEqualityComparerForSerialization(_keycomparer);
-#else
- IEqualityComparer keyComparerForSerilization = _keycomparer;
-#endif
+ IEqualityComparer keyComparerForSerilization = _keycomparer;
- if( keyComparerForSerilization == null) {
- info.AddValue(ComparerName, null,typeof(IComparer));
- info.AddValue(HashCodeProviderName, null, typeof(IHashCodeProvider));
- }
- else if(keyComparerForSerilization is CompatibleComparer) {
- CompatibleComparer c = keyComparerForSerilization as CompatibleComparer;
- info.AddValue(ComparerName, c.Comparer, typeof(IComparer));
- info.AddValue(HashCodeProviderName, c.HashCodeProvider, typeof(IHashCodeProvider));
- }
- else {
- info.AddValue(KeyComparerName, keyComparerForSerilization, typeof(IEqualityComparer));
- }
+ if (keyComparerForSerilization == null)
+ {
+ info.AddValue(ComparerName, null, typeof(IComparer));
+ info.AddValue(HashCodeProviderName, null, typeof(IHashCodeProvider));
+ }
+ else if (keyComparerForSerilization is CompatibleComparer)
+ {
+ CompatibleComparer c = keyComparerForSerilization as CompatibleComparer;
+ info.AddValue(ComparerName, c.Comparer, typeof(IComparer));
+ info.AddValue(HashCodeProviderName, c.HashCodeProvider, typeof(IHashCodeProvider));
+ }
+ else
+ {
+ info.AddValue(KeyComparerName, keyComparerForSerilization, typeof(IEqualityComparer));
+ }
#pragma warning restore 618
- info.AddValue(HashSizeName, buckets.Length); //This is the length of the bucket array.
- Object [] serKeys = new Object[count];
- Object [] serValues = new Object[count];
- CopyKeys(serKeys, 0);
- CopyValues(serValues,0);
- info.AddValue(KeysName, serKeys, typeof(Object[]));
- info.AddValue(ValuesName, serValues, typeof(Object[]));
+ info.AddValue(HashSizeName, buckets.Length); //This is the length of the bucket array.
+ Object[] serKeys = new Object[count];
+ Object[] serValues = new Object[count];
+ CopyKeys(serKeys, 0);
+ CopyValues(serValues, 0);
+ info.AddValue(KeysName, serKeys, typeof(Object[]));
+ info.AddValue(ValuesName, serValues, typeof(Object[]));
// Explicitly check to see if anyone changed the Hashtable while we
// were serializing it. That's a race condition in their code.
if (version != oldVersion)
- throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
- }
+ throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
+ }
}
-
+
//
// DeserializationEvent Listener
//
- public virtual void OnDeserialization(Object sender) {
- if (buckets!=null) {
+ public virtual void OnDeserialization(Object sender)
+ {
+ if (buckets != null)
+ {
// Somebody had a dependency on this hashtable and fixed us up before the ObjectManager got to it.
return;
}
@@ -913,8 +987,9 @@ namespace System.Collections {
SerializationInfo siInfo;
HashHelpers.SerializationInfoTable.TryGetValue(this, out siInfo);
- if (siInfo==null) {
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidOnDeser"));
+ if (siInfo == null)
+ {
+ throw new SerializationException(SR.Serialization_InvalidOnDeser);
}
int hashsize = 0;
@@ -924,14 +999,14 @@ namespace System.Collections {
IHashCodeProvider hcp = null;
#pragma warning restore 618
- Object [] serKeys = null;
- Object [] serValues = null;
+ Object[] serKeys = null;
+ Object[] serValues = null;
SerializationInfoEnumerator enumerator = siInfo.GetEnumerator();
- while( enumerator.MoveNext())
+ while (enumerator.MoveNext())
{
- switch( enumerator.Name)
+ switch (enumerator.Name)
{
case LoadFactorName:
loadFactor = siInfo.GetSingle(LoadFactorName);
@@ -939,7 +1014,7 @@ namespace System.Collections {
case HashSizeName:
hashsize = siInfo.GetInt32(HashSizeName);
break;
- case KeyComparerName:
+ case KeyComparerName:
_keycomparer = (IEqualityComparer)siInfo.GetValue(KeyComparerName, typeof(IEqualityComparer));
break;
case ComparerName:
@@ -959,129 +1034,148 @@ namespace System.Collections {
}
}
- loadsize = (int)(loadFactor*hashsize);
+ loadsize = (int)(loadFactor * hashsize);
// V1 object doesn't has _keycomparer field.
- if ( (_keycomparer == null) && ( (c != null) || (hcp != null) ) ){
- _keycomparer = new CompatibleComparer(c,hcp);
+ if ((_keycomparer == null) && ((c != null) || (hcp != null)))
+ {
+ _keycomparer = new CompatibleComparer(c, hcp);
}
buckets = new bucket[hashsize];
-
- if (serKeys==null) {
- throw new SerializationException(Environment.GetResourceString("Serialization_MissingKeys"));
+
+ if (serKeys == null)
+ {
+ throw new SerializationException(SR.Serialization_MissingKeys);
}
- if (serValues==null) {
- throw new SerializationException(Environment.GetResourceString("Serialization_MissingValues"));
+ if (serValues == null)
+ {
+ throw new SerializationException(SR.Serialization_MissingValues);
}
- if (serKeys.Length!=serValues.Length) {
- throw new SerializationException(Environment.GetResourceString("Serialization_KeyValueDifferentSizes"));
+ if (serKeys.Length != serValues.Length)
+ {
+ throw new SerializationException(SR.Serialization_KeyValueDifferentSizes);
}
- for (int i=0; i<serKeys.Length; i++) {
- if (serKeys[i]==null) {
- throw new SerializationException(Environment.GetResourceString("Serialization_NullKey"));
+ for (int i = 0; i < serKeys.Length; i++)
+ {
+ if (serKeys[i] == null)
+ {
+ throw new SerializationException(SR.Serialization_NullKey);
}
Insert(serKeys[i], serValues[i], true);
}
-
+
version = siInfo.GetInt32(VersionName);
-
+
HashHelpers.SerializationInfoTable.Remove(this);
}
-
-
+
+
// Implements a Collection for the keys of a hashtable. An instance of this
// class is created by the GetKeys method of a hashtable.
[Serializable]
private class KeyCollection : ICollection
{
private Hashtable _hashtable;
-
- internal KeyCollection(Hashtable hashtable) {
+
+ internal KeyCollection(Hashtable hashtable)
+ {
_hashtable = hashtable;
}
-
- public virtual void CopyTo(Array array, int arrayIndex) {
- if (array==null)
+
+ public virtual void CopyTo(Array array, int arrayIndex)
+ {
+ if (array == null)
throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
- if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
+ if (arrayIndex < 0)
+ throw new ArgumentOutOfRangeException(nameof(arrayIndex), SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
if (array.Length - arrayIndex < _hashtable.count)
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall"));
+ throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall);
_hashtable.CopyKeys(array, arrayIndex);
}
-
- public virtual IEnumerator GetEnumerator() {
+
+ public virtual IEnumerator GetEnumerator()
+ {
return new HashtableEnumerator(_hashtable, HashtableEnumerator.Keys);
}
-
- public virtual bool IsSynchronized {
+
+ public virtual bool IsSynchronized
+ {
get { return _hashtable.IsSynchronized; }
}
- public virtual Object SyncRoot {
+ public virtual Object SyncRoot
+ {
get { return _hashtable.SyncRoot; }
}
- public virtual int Count {
+ public virtual int Count
+ {
get { return _hashtable.count; }
}
}
-
+
// Implements a Collection for the values of a hashtable. An instance of
// this class is created by the GetValues method of a hashtable.
[Serializable]
private class ValueCollection : ICollection
{
private Hashtable _hashtable;
-
- internal ValueCollection(Hashtable hashtable) {
+
+ internal ValueCollection(Hashtable hashtable)
+ {
_hashtable = hashtable;
}
-
- public virtual void CopyTo(Array array, int arrayIndex) {
- if (array==null)
+
+ public virtual void CopyTo(Array array, int arrayIndex)
+ {
+ if (array == null)
throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
- if (arrayIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(arrayIndex), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
+ if (arrayIndex < 0)
+ throw new ArgumentOutOfRangeException(nameof(arrayIndex), SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
if (array.Length - arrayIndex < _hashtable.count)
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayPlusOffTooSmall"));
+ throw new ArgumentException(SR.Arg_ArrayPlusOffTooSmall);
_hashtable.CopyValues(array, arrayIndex);
}
-
- public virtual IEnumerator GetEnumerator() {
+
+ public virtual IEnumerator GetEnumerator()
+ {
return new HashtableEnumerator(_hashtable, HashtableEnumerator.Values);
}
-
- public virtual bool IsSynchronized {
+
+ public virtual bool IsSynchronized
+ {
get { return _hashtable.IsSynchronized; }
}
- public virtual Object SyncRoot {
+ public virtual Object SyncRoot
+ {
get { return _hashtable.SyncRoot; }
}
- public virtual int Count {
+ public virtual int Count
+ {
get { return _hashtable.count; }
}
}
-
+
// Synchronized wrapper for hashtable
[Serializable]
private class SyncHashtable : Hashtable, IEnumerable
{
protected Hashtable _table;
-
- internal SyncHashtable(Hashtable table) : base(false) {
+
+ internal SyncHashtable(Hashtable table) : base(false)
+ {
_table = table;
}
-
+
/*================================GetObjectData=================================
**Action: Return a serialization info containing a reference to _table. We need
@@ -1093,115 +1187,148 @@ namespace System.Collections {
** context -- the StreamingContext for the current serialization (ignored)
**Exceptions: ArgumentNullException if info is null.
==============================================================================*/
- public override void GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
// Our serialization code hasn't been fully tweaked to be safe
// for a concurrent writer.
- lock (_table.SyncRoot) {
- info.AddValue("ParentTable", _table, typeof(Hashtable));
- }
+ lock (_table.SyncRoot)
+ {
+ info.AddValue("ParentTable", _table, typeof(Hashtable));
+ }
}
- public override int Count {
+ public override int Count
+ {
get { return _table.Count; }
}
-
- public override bool IsReadOnly {
+
+ public override bool IsReadOnly
+ {
get { return _table.IsReadOnly; }
}
- public override bool IsFixedSize {
+ public override bool IsFixedSize
+ {
get { return _table.IsFixedSize; }
}
-
- public override bool IsSynchronized {
+
+ public override bool IsSynchronized
+ {
get { return true; }
}
- public override Object this[Object key] {
- get {
- return _table[key];
+ public override Object this[Object key]
+ {
+ get
+ {
+ return _table[key];
}
- set {
- lock(_table.SyncRoot) {
+ set
+ {
+ lock (_table.SyncRoot)
+ {
_table[key] = value;
}
}
}
-
- public override Object SyncRoot {
+
+ public override Object SyncRoot
+ {
get { return _table.SyncRoot; }
}
-
- public override void Add(Object key, Object value) {
- lock(_table.SyncRoot) {
+
+ public override void Add(Object key, Object value)
+ {
+ lock (_table.SyncRoot)
+ {
_table.Add(key, value);
}
}
-
- public override void Clear() {
- lock(_table.SyncRoot) {
+
+ public override void Clear()
+ {
+ lock (_table.SyncRoot)
+ {
_table.Clear();
}
}
-
- public override bool Contains(Object key) {
+
+ public override bool Contains(Object key)
+ {
return _table.Contains(key);
}
-
- public override bool ContainsKey(Object key) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+
+ public override bool ContainsKey(Object key)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
return _table.ContainsKey(key);
}
-
- public override void CopyTo(Array array, int arrayIndex) {
- lock (_table.SyncRoot) {
+
+ public override void CopyTo(Array array, int arrayIndex)
+ {
+ lock (_table.SyncRoot)
+ {
_table.CopyTo(array, arrayIndex);
}
}
- public override Object Clone() {
- lock (_table.SyncRoot) {
+ public override Object Clone()
+ {
+ lock (_table.SyncRoot)
+ {
return Hashtable.Synchronized((Hashtable)_table.Clone());
}
}
-
- IEnumerator IEnumerable.GetEnumerator() {
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return _table.GetEnumerator();
}
-
- public override IDictionaryEnumerator GetEnumerator() {
+
+ public override IDictionaryEnumerator GetEnumerator()
+ {
return _table.GetEnumerator();
}
-
- public override ICollection Keys {
- get {
- lock(_table.SyncRoot) {
+
+ public override ICollection Keys
+ {
+ get
+ {
+ lock (_table.SyncRoot)
+ {
return _table.Keys;
}
}
}
-
- public override ICollection Values {
- get {
- lock(_table.SyncRoot) {
+
+ public override ICollection Values
+ {
+ get
+ {
+ lock (_table.SyncRoot)
+ {
return _table.Values;
}
}
}
-
- public override void Remove(Object key) {
- lock(_table.SyncRoot) {
+
+ public override void Remove(Object key)
+ {
+ lock (_table.SyncRoot)
+ {
_table.Remove(key);
}
}
-
+
/*==============================OnDeserialization===============================
**Action: Does nothing. We have to implement this because our parent HT implements it,
** but it doesn't do anything meaningful. The real work will be done when we
@@ -1210,13 +1337,13 @@ namespace System.Collections {
**Arguments: None
**Exceptions: None
==============================================================================*/
- public override void OnDeserialization(Object sender) {
+ public override void OnDeserialization(Object sender)
+ {
return;
}
-
}
-
-
+
+
// Implements an enumerator for a hashtable. The enumerator uses the
// internal version number of the hashtabke to ensure that no modifications
// are made to the hashtable while an enumeration is in progress.
@@ -1230,12 +1357,13 @@ namespace System.Collections {
private int getObjectRetType; // What should GetObject return?
private Object currentKey;
private Object currentValue;
-
+
internal const int Keys = 1;
internal const int Values = 2;
internal const int DictEntry = 3;
-
- internal HashtableEnumerator(Hashtable hashtable, int getObjRetType) {
+
+ internal HashtableEnumerator(Hashtable hashtable, int getObjRetType)
+ {
this.hashtable = hashtable;
bucket = hashtable.buckets.Length;
version = hashtable.version;
@@ -1243,23 +1371,29 @@ namespace System.Collections {
getObjectRetType = getObjRetType;
}
- public Object Clone() {
+ public Object Clone()
+ {
return MemberwiseClone();
}
-
- public virtual Object Key {
- get {
- if (current == false) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
+
+ public virtual Object Key
+ {
+ get
+ {
+ if (current == false) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
return currentKey;
}
}
-
- public virtual bool MoveNext() {
- if (version != hashtable.version) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
- while (bucket > 0) {
+
+ public virtual bool MoveNext()
+ {
+ if (version != hashtable.version) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
+ while (bucket > 0)
+ {
bucket--;
Object keyv = hashtable.buckets[bucket].key;
- if ((keyv!= null) && (keyv != hashtable.buckets)) {
+ if ((keyv != null) && (keyv != hashtable.buckets))
+ {
currentKey = keyv;
currentValue = hashtable.buckets[bucket].val;
current = true;
@@ -1269,54 +1403,61 @@ namespace System.Collections {
current = false;
return false;
}
-
- public virtual DictionaryEntry Entry {
- get {
- if (current == false) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumOpCantHappen));
+
+ public virtual DictionaryEntry Entry
+ {
+ get
+ {
+ if (current == false) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumOpCantHappen));
return new DictionaryEntry(currentKey, currentValue);
}
}
-
-
- public virtual Object Current {
- get {
- if (current == false) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumOpCantHappen));
-
- if (getObjectRetType==Keys)
+
+
+ public virtual Object Current
+ {
+ get
+ {
+ if (current == false) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumOpCantHappen));
+
+ if (getObjectRetType == Keys)
return currentKey;
- else if (getObjectRetType==Values)
+ else if (getObjectRetType == Values)
return currentValue;
- else
+ else
return new DictionaryEntry(currentKey, currentValue);
}
}
-
- public virtual Object Value {
- get {
- if (current == false) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumOpCantHappen));
+
+ public virtual Object Value
+ {
+ get
+ {
+ if (current == false) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumOpCantHappen));
return currentValue;
}
}
-
- public virtual void Reset() {
- if (version != hashtable.version) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
+
+ public virtual void Reset()
+ {
+ if (version != hashtable.version) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumFailedVersion));
current = false;
bucket = hashtable.buckets.Length;
currentKey = null;
currentValue = null;
}
}
-
+
// internal debug view class for hashtable
- internal class HashtableDebugView {
- private Hashtable hashtable;
- }
+ internal class HashtableDebugView
+ {
+ private Hashtable hashtable;
+ }
}
[FriendAccessAllowed]
internal static class HashHelpers
{
-
#if FEATURE_RANDOMIZED_STRING_HASHING
public const int HashCollisionThreshold = 100;
public static bool s_UseRandomizedStringHashing = String.UseRandomizedHashing();
@@ -1344,11 +1485,11 @@ namespace System.Collections {
// object until OnDeserialization is called.
private static ConditionalWeakTable<object, SerializationInfo> s_SerializationInfoTable;
- internal static ConditionalWeakTable<object, SerializationInfo> SerializationInfoTable
- {
- get
- {
- if(s_SerializationInfoTable == null)
+ internal static ConditionalWeakTable<object, SerializationInfo> SerializationInfoTable
+ {
+ get
+ {
+ if (s_SerializationInfoTable == null)
{
ConditionalWeakTable<object, SerializationInfo> newTable = new ConditionalWeakTable<object, SerializationInfo>();
Interlocked.CompareExchange(ref s_SerializationInfoTable, newTable, null);
@@ -1356,15 +1497,14 @@ namespace System.Collections {
return s_SerializationInfoTable;
}
-
}
- public static bool IsPrime(int candidate)
+ public static bool IsPrime(int candidate)
{
- if ((candidate & 1) != 0)
+ if ((candidate & 1) != 0)
{
- int limit = (int)Math.Sqrt (candidate);
- for (int divisor = 3; divisor <= limit; divisor+=2)
+ int limit = (int)Math.Sqrt(candidate);
+ for (int divisor = 3; divisor <= limit; divisor += 2)
{
if ((candidate % divisor) == 0)
return false;
@@ -1374,13 +1514,13 @@ namespace System.Collections {
return (candidate == 2);
}
- public static int GetPrime(int min)
+ public static int GetPrime(int min)
{
if (min < 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_HTCapacityOverflow"));
+ throw new ArgumentException(SR.Arg_HTCapacityOverflow);
Contract.EndContractBlock();
- for (int i = 0; i < primes.Length; i++)
+ for (int i = 0; i < primes.Length; i++)
{
int prime = primes[i];
if (prime >= min) return prime;
@@ -1388,7 +1528,7 @@ namespace System.Collections {
//outside of our predefined table.
//compute the hard way.
- for (int i = (min | 1); i < Int32.MaxValue;i+=2)
+ for (int i = (min | 1); i < Int32.MaxValue; i += 2)
{
if (IsPrime(i) && ((i - 1) % Hashtable.HashPrime != 0))
return i;
@@ -1405,7 +1545,7 @@ namespace System.Collections {
// Note that this check works even when _items.Length overflowed thanks to the (uint) cast
if ((uint)newSize > MaxPrimeArrayLength && MaxPrimeArrayLength > oldSize)
{
- Debug.Assert( MaxPrimeArrayLength == GetPrime(MaxPrimeArrayLength), "Invalid MaxPrimeArrayLength");
+ Debug.Assert(MaxPrimeArrayLength == GetPrime(MaxPrimeArrayLength), "Invalid MaxPrimeArrayLength");
return MaxPrimeArrayLength;
}
@@ -1415,29 +1555,5 @@ namespace System.Collections {
// This is the maximum prime smaller than Array.MaxArrayLength
public const int MaxPrimeArrayLength = 0x7FEFFFFD;
-
-#if FEATURE_RANDOMIZED_STRING_HASHING
-
- public static object GetEqualityComparerForSerialization(object comparer)
- {
- if(comparer == null)
- {
- return null;
- }
-
- IWellKnownStringEqualityComparer cmp = comparer as IWellKnownStringEqualityComparer;
-
- if(cmp != null)
- {
- return cmp.GetEqualityComparerForSerialization();
- }
-
- return comparer;
- }
-
- private const int bufferSize = 1024;
- private static int currentIndex = bufferSize;
- private static readonly object lockObj = new Object();
-#endif // FEATURE_RANDOMIZED_STRING_HASHING
}
}
diff --git a/src/mscorlib/src/System/Collections/ICollection.cs b/src/mscorlib/src/System/Collections/ICollection.cs
deleted file mode 100644
index 088928a0ef..0000000000
--- a/src/mscorlib/src/System/Collections/ICollection.cs
+++ /dev/null
@@ -1,80 +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.
-
-/*============================================================
-**
-** Interface: ICollection
-**
-**
-**
-**
-** Purpose: Base interface for all collections.
-**
-**
-===========================================================*/
-namespace System.Collections {
- using System;
- using System.Diagnostics.Contracts;
-
- // Base interface for all collections, defining enumerators, size, and
- // synchronization methods.
- public interface ICollection : IEnumerable
- {
- // Interfaces are not serialable
- // CopyTo copies a collection into an Array, starting at a particular
- // index into the array.
- //
- void CopyTo(Array array, int index);
-
- // Number of items in the collections.
- int Count
- { get; }
-
-
- // SyncRoot will return an Object to use for synchronization
- // (thread safety). You can use this object in your code to take a
- // lock on the collection, even if this collection is a wrapper around
- // another collection. The intent is to tunnel through to a real
- // implementation of a collection, and use one of the internal objects
- // found in that code.
- //
- // In the absense of a static Synchronized method on a collection,
- // the expected usage for SyncRoot would look like this:
- //
- // ICollection col = ...
- // lock (col.SyncRoot) {
- // // Some operation on the collection, which is now thread safe.
- // // This may include multiple operations.
- // }
- //
- //
- // The system-provided collections have a static method called
- // Synchronized which will create a thread-safe wrapper around the
- // collection. All access to the collection that you want to be
- // thread-safe should go through that wrapper collection. However, if
- // you need to do multiple calls on that collection (such as retrieving
- // two items, or checking the count then doing something), you should
- // NOT use our thread-safe wrapper since it only takes a lock for the
- // duration of a single method call. Instead, use Monitor.Enter/Exit
- // or your language's equivalent to the C# lock keyword as mentioned
- // above.
- //
- // For collections with no publically available underlying store, the
- // expected implementation is to simply return the this pointer. Note
- // that the this pointer may not be sufficient for collections that
- // wrap other collections; those should return the underlying
- // collection's SyncRoot property.
- Object SyncRoot
- { get; }
-
- // Is this collection synchronized (i.e., thread-safe)? If you want a
- // thread-safe collection, you can use SyncRoot as an object to
- // synchronize your collection with. If you're using one of the
- // collections in System.Collections, you could call the static
- // Synchronized method to get a thread-safe wrapper around the
- // underlying collection.
- bool IsSynchronized
- { get; }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IComparer.cs b/src/mscorlib/src/System/Collections/IComparer.cs
deleted file mode 100644
index 574af1a768..0000000000
--- a/src/mscorlib/src/System/Collections/IComparer.cs
+++ /dev/null
@@ -1,31 +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.
-
-/*============================================================
-**
-** Interface: IComparer
-**
-**
-**
-**
-** Purpose: Interface for comparing two Objects.
-**
-**
-===========================================================*/
-namespace System.Collections {
-
- using System;
- // The IComparer interface implements a method that compares two objects. It is
- // used in conjunction with the Sort and BinarySearch methods on
- // the Array and List classes.
- //
- // Interfaces are not serializable
- public interface IComparer {
- // Compares two objects. An implementation of this method must return a
- // value less than zero if x is less than y, zero if x is equal to y, or a
- // value greater than zero if x is greater than y.
- //
- int Compare(Object x, Object y);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IDictionary.cs b/src/mscorlib/src/System/Collections/IDictionary.cs
deleted file mode 100644
index 519d53ed55..0000000000
--- a/src/mscorlib/src/System/Collections/IDictionary.cs
+++ /dev/null
@@ -1,68 +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.
-
-/*============================================================
-**
-** Interface: IDictionary
-**
-**
-**
-**
-** Purpose: Base interface for all dictionaries.
-**
-**
-===========================================================*/
-namespace System.Collections {
- using System;
- using System.Diagnostics.Contracts;
-
- // An IDictionary is a possibly unordered set of key-value pairs.
- // Keys can be any non-null object. Values can be any object.
- // You can look up a value in an IDictionary via the default indexed
- // property, Items.
- public interface IDictionary : ICollection
- {
- // Interfaces are not serializable
- // The Item property provides methods to read and edit entries
- // in the Dictionary.
- Object this[Object key] {
- get;
- set;
- }
-
- // Returns a collections of the keys in this dictionary.
- ICollection Keys {
- get;
- }
-
- // Returns a collections of the values in this dictionary.
- ICollection Values {
- get;
- }
-
- // Returns whether this dictionary contains a particular key.
- //
- bool Contains(Object key);
-
- // Adds a key-value pair to the dictionary.
- //
- void Add(Object key, Object value);
-
- // Removes all pairs from the dictionary.
- void Clear();
-
- bool IsReadOnly
- { get; }
-
- bool IsFixedSize
- { get; }
-
- // Returns an IDictionaryEnumerator for this dictionary.
- new IDictionaryEnumerator GetEnumerator();
-
- // Removes a particular key from the dictionary.
- //
- void Remove(Object key);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IDictionaryEnumerator.cs b/src/mscorlib/src/System/Collections/IDictionaryEnumerator.cs
deleted file mode 100644
index 2f1add682c..0000000000
--- a/src/mscorlib/src/System/Collections/IDictionaryEnumerator.cs
+++ /dev/null
@@ -1,78 +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.
-
-/*============================================================
-**
-** Interface: IDictionaryEnumerator
-**
-**
-**
-**
-** Purpose: Base interface for dictionary enumerators.
-**
-**
-===========================================================*/
-namespace System.Collections {
- // Interfaces are not serializable
-
- using System;
- // This interface represents an enumerator that allows sequential access to the
- // elements of a dictionary. Upon creation, an enumerator is conceptually
- // positioned before the first element of the enumeration. The first call to the
- // MoveNext method brings the first element of the enumeration into view,
- // and each successive call to MoveNext brings the next element into
- // view until MoveNext returns false, indicating that there are no more
- // elements to enumerate. Following each call to MoveNext, the
- // Key and Value methods are used to obtain the key and
- // value of the element currently in view. The values returned by calls to
- // Key and Value are undefined before the first call to
- // MoveNext and following a call to MoveNext that returned false.
- // Enumerators are typically used in while loops of the form
- //
- // IDictionaryEnumerator e = ...;
- // while (e.MoveNext()) {
- // Object key = e.Key;
- // Object value = e.Value;
- // ...
- // }
- //
- // The IDictionaryEnumerator interface extends the IEnumerator
- // inerface and can thus be used as a regular enumerator. The Current
- // method of an IDictionaryEnumerator returns a DictionaryEntry containing
- // the current key and value pair. However, the GetEntry method will
- // return the same DictionaryEntry and avoids boxing the DictionaryEntry (boxing
- // is somewhat expensive).
- //
- public interface IDictionaryEnumerator : IEnumerator
- {
- // Returns the key of the current element of the enumeration. The returned
- // value is undefined before the first call to GetNext and following
- // a call to GetNext that returned false. Multiple calls to
- // GetKey with no intervening calls to GetNext will return
- // the same object.
- //
- Object Key {
- get;
- }
-
- // Returns the value of the current element of the enumeration. The
- // returned value is undefined before the first call to GetNext and
- // following a call to GetNext that returned false. Multiple calls
- // to GetValue with no intervening calls to GetNext will
- // return the same object.
- //
- Object Value {
- get;
- }
-
- // GetBlock will copy dictionary values into the given Array. It will either
- // fill up the array, or if there aren't enough elements, it will
- // copy as much as possible into the Array. The number of elements
- // copied is returned.
- //
- DictionaryEntry Entry {
- get;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IEnumerable.cs b/src/mscorlib/src/System/Collections/IEnumerable.cs
deleted file mode 100644
index 1d8e71cf07..0000000000
--- a/src/mscorlib/src/System/Collections/IEnumerable.cs
+++ /dev/null
@@ -1,33 +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.
-
-/*============================================================
-**
-** Interface: IEnumerable
-**
-**
-**
-**
-** Purpose: Interface for classes providing IEnumerators
-**
-**
-===========================================================*/
-namespace System.Collections {
- using System;
- using System.Diagnostics.Contracts;
- using System.Runtime.InteropServices;
-
- // Implement this interface if you need to support VB's foreach semantics.
- // Also, COM classes that support an enumerator will also implement this interface.
- [Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
- public interface IEnumerable
- {
- // Interfaces are not serializable
- // Returns an IEnumerator for this enumerable Object. The enumerator provides
- // a simple way to access all the contents of a collection.
- [Pure]
- [DispId(-4)]
- IEnumerator GetEnumerator();
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IEnumerator.cs b/src/mscorlib/src/System/Collections/IEnumerator.cs
deleted file mode 100644
index 4c4fc085e8..0000000000
--- a/src/mscorlib/src/System/Collections/IEnumerator.cs
+++ /dev/null
@@ -1,52 +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.
-
-/*============================================================
-**
-** Interface: IEnumerator
-**
-**
-**
-**
-** Purpose: Base interface for all enumerators.
-**
-**
-===========================================================*/
-namespace System.Collections {
- using System;
- using System.Runtime.InteropServices;
-
- // Base interface for all enumerators, providing a simple approach
- // to iterating over a collection.
- [Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
- public interface IEnumerator
- {
- // Interfaces are not serializable
- // Advances the enumerator to the next element of the enumeration and
- // returns a boolean indicating whether an element is available. Upon
- // creation, an enumerator is conceptually positioned before the first
- // element of the enumeration, and the first call to MoveNext
- // brings the first element of the enumeration into view.
- //
- bool MoveNext();
-
- // Returns the current element of the enumeration. The returned value is
- // undefined before the first call to MoveNext and following a
- // call to MoveNext that returned false. Multiple calls to
- // GetCurrent with no intervening calls to MoveNext
- // will return the same object.
- //
- Object Current {
- get;
- }
-
- // Resets the enumerator to the beginning of the enumeration, starting over.
- // The preferred behavior for Reset is to return the exact same enumeration.
- // This means if you modify the underlying collection then call Reset, your
- // IEnumerator will be invalid, just as it would have been if you had called
- // MoveNext or Current.
- //
- void Reset();
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IEqualityComparer.cs b/src/mscorlib/src/System/Collections/IEqualityComparer.cs
deleted file mode 100644
index f591b11152..0000000000
--- a/src/mscorlib/src/System/Collections/IEqualityComparer.cs
+++ /dev/null
@@ -1,26 +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.
-
-/*============================================================
-**
-** Interface: IEqualityComparer
-**
-**
-**
-**
-** Purpose: A mechanism to expose a simplified infrastructure for
-** Comparing objects in collections.
-**
-**
-===========================================================*/
-namespace System.Collections {
-
- using System;
- // An IEqualityComparer is a mechanism to consume custom performant comparison infrastructure
- // that can be consumed by some of the common collections.
- public interface IEqualityComparer {
- bool Equals(Object x, Object y);
- int GetHashCode(Object obj);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IHashCodeProvider.cs b/src/mscorlib/src/System/Collections/IHashCodeProvider.cs
index 0ae1e3295b..fa4738ab64 100644
--- a/src/mscorlib/src/System/Collections/IHashCodeProvider.cs
+++ b/src/mscorlib/src/System/Collections/IHashCodeProvider.cs
@@ -13,17 +13,19 @@
**
**
===========================================================*/
-namespace System.Collections {
-
- using System;
+
+using System;
+
+namespace System.Collections
+{
// Provides a mechanism for a hash table user to override the default
// GetHashCode() function on Objects, providing their own hash function.
[Obsolete("Please use IEqualityComparer instead.")]
- internal interface IHashCodeProvider
+ internal interface IHashCodeProvider
{
// Interfaces are not serializable
// Returns a hash code for the given object.
//
- int GetHashCode (Object obj);
+ int GetHashCode(Object obj);
}
}
diff --git a/src/mscorlib/src/System/Collections/IList.cs b/src/mscorlib/src/System/Collections/IList.cs
deleted file mode 100644
index 8b63400852..0000000000
--- a/src/mscorlib/src/System/Collections/IList.cs
+++ /dev/null
@@ -1,70 +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.
-
-/*============================================================
-**
-** Interface: IList
-**
-**
-**
-**
-** Purpose: Base interface for all Lists.
-**
-**
-===========================================================*/
-namespace System.Collections {
-
- using System;
- using System.Diagnostics.Contracts;
-
- // An IList is an ordered collection of objects. The exact ordering
- // is up to the implementation of the list, ranging from a sorted
- // order to insertion order.
- public interface IList : ICollection
- {
- // The Item property provides methods to read and edit entries in the List.
- Object this[int index] {
- get;
- set;
- }
-
- // Adds an item to the list. The exact position in the list is
- // implementation-dependent, so while ArrayList may always insert
- // in the last available location, a SortedList most likely would not.
- // The return value is the position the new element was inserted in.
- int Add(Object value);
-
- // Returns whether the list contains a particular item.
- bool Contains(Object value);
-
- // Removes all items from the list.
- void Clear();
-
- bool IsReadOnly
- { get; }
-
-
- bool IsFixedSize
- {
- get;
- }
-
-
- // Returns the index of a particular item, if it is in the list.
- // Returns -1 if the item isn't in the list.
- int IndexOf(Object value);
-
- // Inserts value into the list at position index.
- // index must be non-negative and less than or equal to the
- // number of elements in the list. If index equals the number
- // of items in the list, then value is appended to the end.
- void Insert(int index, Object value);
-
- // Removes an item from the list.
- void Remove(Object value);
-
- // Removes the item at position index.
- void RemoveAt(int index);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IStructuralComparable.cs b/src/mscorlib/src/System/Collections/IStructuralComparable.cs
deleted file mode 100644
index 1b6f3aff7a..0000000000
--- a/src/mscorlib/src/System/Collections/IStructuralComparable.cs
+++ /dev/null
@@ -1,11 +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;
-
-namespace System.Collections {
-
- public interface IStructuralComparable {
- Int32 CompareTo(Object other, IComparer comparer);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/IStructuralEquatable.cs b/src/mscorlib/src/System/Collections/IStructuralEquatable.cs
deleted file mode 100644
index 5a5295fc38..0000000000
--- a/src/mscorlib/src/System/Collections/IStructuralEquatable.cs
+++ /dev/null
@@ -1,10 +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.
-namespace System.Collections {
-
- public interface IStructuralEquatable {
- Boolean Equals(Object other, IEqualityComparer comparer);
- int GetHashCode(IEqualityComparer comparer);
- }
-}
diff --git a/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs b/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs
index 617c33707a..3f92038d4f 100644
--- a/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs
+++ b/src/mscorlib/src/System/Collections/ListDictionaryInternal.cs
@@ -11,55 +11,70 @@
**
**
===========================================================*/
+
using System.Diagnostics.Contracts;
-namespace System.Collections {
+
+namespace System.Collections
+{
/// This is a simple implementation of IDictionary using a singly linked list. This
/// will be smaller and faster than a Hashtable if the number of elements is 10 or less.
/// This should not be used if performance is important for large numbers of elements.
[Serializable]
- internal class ListDictionaryInternal: IDictionary {
- DictionaryNode head;
- int version;
- int count;
+ internal class ListDictionaryInternal : IDictionary
+ {
+ private DictionaryNode head;
+ private int version;
+ private int count;
[NonSerialized]
private Object _syncRoot;
- public ListDictionaryInternal() {
+ public ListDictionaryInternal()
+ {
}
- public Object this[Object key] {
- get {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public Object this[Object key]
+ {
+ get
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
DictionaryNode node = head;
- while (node != null) {
- if ( node.key.Equals(key) ) {
+ while (node != null)
+ {
+ if (node.key.Equals(key))
+ {
return node.value;
}
node = node.next;
}
return null;
}
- set {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ set
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
-
+
version++;
DictionaryNode last = null;
DictionaryNode node;
- for (node = head; node != null; node = node.next) {
- if( node.key.Equals(key) ) {
+ for (node = head; node != null; node = node.next)
+ {
+ if (node.key.Equals(key))
+ {
break;
- }
+ }
last = node;
}
- if (node != null) {
+ if (node != null)
+ {
// Found it
node.value = value;
return;
@@ -68,78 +83,100 @@ namespace System.Collections {
DictionaryNode newNode = new DictionaryNode();
newNode.key = key;
newNode.value = value;
- if (last != null) {
+ if (last != null)
+ {
last.next = newNode;
}
- else {
+ else
+ {
head = newNode;
}
count++;
}
}
- public int Count {
- get {
+ public int Count
+ {
+ get
+ {
return count;
}
- }
+ }
- public ICollection Keys {
- get {
+ public ICollection Keys
+ {
+ get
+ {
return new NodeKeyValueCollection(this, true);
}
}
- public bool IsReadOnly {
- get {
+ public bool IsReadOnly
+ {
+ get
+ {
return false;
}
}
- public bool IsFixedSize {
- get {
+ public bool IsFixedSize
+ {
+ get
+ {
return false;
}
}
- public bool IsSynchronized {
- get {
+ public bool IsSynchronized
+ {
+ get
+ {
return false;
}
}
- public Object SyncRoot {
- get {
- if( _syncRoot == null) {
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ public Object SyncRoot
+ {
+ get
+ {
+ if (_syncRoot == null)
+ {
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
- return _syncRoot;
+ return _syncRoot;
}
}
- public ICollection Values {
- get {
+ public ICollection Values
+ {
+ get
+ {
return new NodeKeyValueCollection(this, false);
}
}
- public void Add(Object key, Object value) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public void Add(Object key, Object value)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
-
+
version++;
DictionaryNode last = null;
DictionaryNode node;
- for (node = head; node != null; node = node.next) {
- if (node.key.Equals(key)) {
- throw new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicate__", node.key, key));
- }
+ for (node = head; node != null; node = node.next)
+ {
+ if (node.key.Equals(key))
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_AddingDuplicate__, node.key, key));
+ }
last = node;
}
- if (node != null) {
+ if (node != null)
+ {
// Found it
node.value = value;
return;
@@ -148,265 +185,328 @@ namespace System.Collections {
DictionaryNode newNode = new DictionaryNode();
newNode.key = key;
newNode.value = value;
- if (last != null) {
+ if (last != null)
+ {
last.next = newNode;
}
- else {
+ else
+ {
head = newNode;
}
count++;
}
- public void Clear() {
+ public void Clear()
+ {
count = 0;
head = null;
version++;
}
- public bool Contains(Object key) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public bool Contains(Object key)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
- for (DictionaryNode node = head; node != null; node = node.next) {
- if (node.key.Equals(key)) {
+ for (DictionaryNode node = head; node != null; node = node.next)
+ {
+ if (node.key.Equals(key))
+ {
return true;
}
}
return false;
}
- public void CopyTo(Array array, int index) {
- if (array==null)
+ public void CopyTo(Array array, int index)
+ {
+ if (array == null)
throw new ArgumentNullException(nameof(array));
-
+
if (array.Rank != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
+ throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
- if ( array.Length - index < this.Count )
- throw new ArgumentException( Environment.GetResourceString("ArgumentOutOfRange_Index"), nameof(index));
+ if (array.Length - index < this.Count)
+ throw new ArgumentException(SR.ArgumentOutOfRange_Index, nameof(index));
Contract.EndContractBlock();
- for (DictionaryNode node = head; node != null; node = node.next) {
+ for (DictionaryNode node = head; node != null; node = node.next)
+ {
array.SetValue(new DictionaryEntry(node.key, node.value), index);
index++;
}
}
- public IDictionaryEnumerator GetEnumerator() {
+ public IDictionaryEnumerator GetEnumerator()
+ {
return new NodeEnumerator(this);
}
- IEnumerator IEnumerable.GetEnumerator() {
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return new NodeEnumerator(this);
}
- public void Remove(Object key) {
- if (key == null) {
- throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
+ public void Remove(Object key)
+ {
+ if (key == null)
+ {
+ throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
}
Contract.EndContractBlock();
version++;
DictionaryNode last = null;
DictionaryNode node;
- for (node = head; node != null; node = node.next) {
- if (node.key.Equals(key)) {
+ for (node = head; node != null; node = node.next)
+ {
+ if (node.key.Equals(key))
+ {
break;
- }
+ }
last = node;
}
- if (node == null) {
+ if (node == null)
+ {
return;
- }
- if (node == head) {
+ }
+ if (node == head)
+ {
head = node.next;
- } else {
+ }
+ else
+ {
last.next = node.next;
}
count--;
}
- private class NodeEnumerator : IDictionaryEnumerator {
- ListDictionaryInternal list;
- DictionaryNode current;
- int version;
- bool start;
+ private class NodeEnumerator : IDictionaryEnumerator
+ {
+ private ListDictionaryInternal list;
+ private DictionaryNode current;
+ private int version;
+ private bool start;
- public NodeEnumerator(ListDictionaryInternal list) {
+ public NodeEnumerator(ListDictionaryInternal list)
+ {
this.list = list;
version = list.version;
start = true;
current = null;
}
- public Object Current {
- get {
+ public Object Current
+ {
+ get
+ {
return Entry;
}
}
- public DictionaryEntry Entry {
- get {
- if (current == null) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public DictionaryEntry Entry
+ {
+ get
+ {
+ if (current == null)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
return new DictionaryEntry(current.key, current.value);
}
}
- public Object Key {
- get {
- if (current == null) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public Object Key
+ {
+ get
+ {
+ if (current == null)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
return current.key;
}
}
- public Object Value {
- get {
- if (current == null) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public Object Value
+ {
+ get
+ {
+ if (current == null)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
return current.value;
}
}
- public bool MoveNext() {
- if (version != list.version) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumFailedVersion"));
+ public bool MoveNext()
+ {
+ if (version != list.version)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
}
- if (start) {
+ if (start)
+ {
current = list.head;
start = false;
}
- else {
- if( current != null ) {
+ else
+ {
+ if (current != null)
+ {
current = current.next;
}
}
return (current != null);
}
- public void Reset() {
- if (version != list.version) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumFailedVersion"));
+ public void Reset()
+ {
+ if (version != list.version)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
}
start = true;
current = null;
}
-
}
- private class NodeKeyValueCollection : ICollection {
- ListDictionaryInternal list;
- bool isKeys;
+ private class NodeKeyValueCollection : ICollection
+ {
+ private ListDictionaryInternal list;
+ private bool isKeys;
- public NodeKeyValueCollection(ListDictionaryInternal list, bool isKeys) {
+ public NodeKeyValueCollection(ListDictionaryInternal list, bool isKeys)
+ {
this.list = list;
this.isKeys = isKeys;
}
- void ICollection.CopyTo(Array array, int index) {
- if (array==null)
+ void ICollection.CopyTo(Array array, int index)
+ {
+ if (array == null)
throw new ArgumentNullException(nameof(array));
if (array.Rank != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
+ throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
- if (array.Length - index < list.Count)
- throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_Index"), nameof(index));
- for (DictionaryNode node = list.head; node != null; node = node.next) {
+ if (array.Length - index < list.Count)
+ throw new ArgumentException(SR.ArgumentOutOfRange_Index, nameof(index));
+ for (DictionaryNode node = list.head; node != null; node = node.next)
+ {
array.SetValue(isKeys ? node.key : node.value, index);
index++;
}
}
- int ICollection.Count {
- get {
+ int ICollection.Count
+ {
+ get
+ {
int count = 0;
- for (DictionaryNode node = list.head; node != null; node = node.next) {
+ for (DictionaryNode node = list.head; node != null; node = node.next)
+ {
count++;
}
return count;
}
- }
+ }
- bool ICollection.IsSynchronized {
- get {
+ bool ICollection.IsSynchronized
+ {
+ get
+ {
return false;
}
}
- Object ICollection.SyncRoot {
- get {
+ Object ICollection.SyncRoot
+ {
+ get
+ {
return list.SyncRoot;
}
}
- IEnumerator IEnumerable.GetEnumerator() {
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return new NodeKeyValueEnumerator(list, isKeys);
}
- private class NodeKeyValueEnumerator: IEnumerator {
- ListDictionaryInternal list;
- DictionaryNode current;
- int version;
- bool isKeys;
- bool start;
+ private class NodeKeyValueEnumerator : IEnumerator
+ {
+ private ListDictionaryInternal list;
+ private DictionaryNode current;
+ private int version;
+ private bool isKeys;
+ private bool start;
- public NodeKeyValueEnumerator(ListDictionaryInternal list, bool isKeys) {
+ public NodeKeyValueEnumerator(ListDictionaryInternal list, bool isKeys)
+ {
this.list = list;
this.isKeys = isKeys;
- this.version = list.version;
- this.start = true;
- this.current = null;
+ version = list.version;
+ start = true;
+ current = null;
}
- public Object Current {
- get {
- if (current == null) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
+ public Object Current
+ {
+ get
+ {
+ if (current == null)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
return isKeys ? current.key : current.value;
}
}
- public bool MoveNext() {
- if (version != list.version) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumFailedVersion"));
+ public bool MoveNext()
+ {
+ if (version != list.version)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
}
- if (start) {
+ if (start)
+ {
current = list.head;
start = false;
}
- else {
- if( current != null) {
+ else
+ {
+ if (current != null)
+ {
current = current.next;
}
}
return (current != null);
}
- public void Reset() {
- if (version != list.version) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumFailedVersion"));
+ public void Reset()
+ {
+ if (version != list.version)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
}
start = true;
current = null;
}
- }
+ }
}
[Serializable]
- private class DictionaryNode {
+ private class DictionaryNode
+ {
public Object key;
public Object value;
public DictionaryNode next;
diff --git a/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs b/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs
index b3b19fb616..d9801dfaaf 100644
--- a/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs
+++ b/src/mscorlib/src/System/Collections/ObjectModel/Collection.cs
@@ -4,50 +4,59 @@
//
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime;
+
namespace System.Collections.ObjectModel
{
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Runtime;
-
[Serializable]
[DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]
- [DebuggerDisplay("Count = {Count}")]
- public class Collection<T>: IList<T>, IList, IReadOnlyList<T>
+ [DebuggerDisplay("Count = {Count}")]
+ public class Collection<T> : IList<T>, IList, IReadOnlyList<T>
{
- IList<T> items;
+ private IList<T> items;
[NonSerialized]
private Object _syncRoot;
- public Collection() {
+ public Collection()
+ {
items = new List<T>();
}
- public Collection(IList<T> list) {
- if (list == null) {
+ public Collection(IList<T> list)
+ {
+ if (list == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.list);
}
items = list;
}
- public int Count {
+ public int Count
+ {
get { return items.Count; }
}
- protected IList<T> Items {
+ protected IList<T> Items
+ {
get { return items; }
}
- public T this[int index] {
+ public T this[int index]
+ {
get { return items[index]; }
- set {
- if( items.IsReadOnly) {
+ set
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
-
- if (index < 0 || index >= items.Count) {
+
+ if (index < 0 || index >= items.Count)
+ {
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
}
@@ -55,154 +64,192 @@ namespace System.Collections.ObjectModel
}
}
- public void Add(T item) {
- if( items.IsReadOnly) {
+ public void Add(T item)
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
-
+
int index = items.Count;
InsertItem(index, item);
}
- public void Clear() {
- if( items.IsReadOnly) {
+ public void Clear()
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
-
+
ClearItems();
}
- public void CopyTo(T[] array, int index) {
+ public void CopyTo(T[] array, int index)
+ {
items.CopyTo(array, index);
}
- public bool Contains(T item) {
+ public bool Contains(T item)
+ {
return items.Contains(item);
}
- public IEnumerator<T> GetEnumerator() {
+ public IEnumerator<T> GetEnumerator()
+ {
return items.GetEnumerator();
}
- public int IndexOf(T item) {
+ public int IndexOf(T item)
+ {
return items.IndexOf(item);
}
- public void Insert(int index, T item) {
- if (items.IsReadOnly) {
+ public void Insert(int index, T item)
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- if (index < 0 || index > items.Count) {
+ if (index < 0 || index > items.Count)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_ListInsert);
}
InsertItem(index, item);
}
- public bool Remove(T item) {
- if( items.IsReadOnly) {
+ public bool Remove(T item)
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
-
+
int index = items.IndexOf(item);
if (index < 0) return false;
RemoveItem(index);
return true;
}
- public void RemoveAt(int index) {
- if( items.IsReadOnly) {
+ public void RemoveAt(int index)
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- if (index < 0 || index >= items.Count) {
+ if (index < 0 || index >= items.Count)
+ {
ThrowHelper.ThrowArgumentOutOfRange_IndexException();
}
RemoveItem(index);
}
- protected virtual void ClearItems() {
+ protected virtual void ClearItems()
+ {
items.Clear();
}
- protected virtual void InsertItem(int index, T item) {
+ protected virtual void InsertItem(int index, T item)
+ {
items.Insert(index, item);
}
-
- protected virtual void RemoveItem(int index) {
+
+ protected virtual void RemoveItem(int index)
+ {
items.RemoveAt(index);
}
- protected virtual void SetItem(int index, T item) {
+ protected virtual void SetItem(int index, T item)
+ {
items[index] = item;
}
-
- bool ICollection<T>.IsReadOnly {
- get {
- return items.IsReadOnly;
+
+ bool ICollection<T>.IsReadOnly
+ {
+ get
+ {
+ return items.IsReadOnly;
}
}
-
- IEnumerator IEnumerable.GetEnumerator() {
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return ((IEnumerable)items).GetEnumerator();
}
- bool ICollection.IsSynchronized {
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- object ICollection.SyncRoot {
- get {
- if( _syncRoot == null) {
+ object ICollection.SyncRoot
+ {
+ get
+ {
+ if (_syncRoot == null)
+ {
ICollection c = items as ICollection;
- if( c != null) {
+ if (c != null)
+ {
_syncRoot = c.SyncRoot;
}
- else {
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ else
+ {
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
}
- return _syncRoot;
+ return _syncRoot;
}
}
- void ICollection.CopyTo(Array array, int index) {
- if (array == null) {
+ void ICollection.CopyTo(Array array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
-
- if (array.Rank != 1) {
+
+ if (array.Rank != 1)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
- if( array.GetLowerBound(0) != 0 ) {
+ if (array.GetLowerBound(0) != 0)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
-
- if (index < 0 ) {
+
+ if (index < 0)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < Count) {
+ if (array.Length - index < Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
T[] tArray = array as T[];
- if (tArray != null) {
- items.CopyTo(tArray , index);
+ if (tArray != null)
+ {
+ items.CopyTo(tArray, index);
}
- else {
+ else
+ {
//
// Catch the obvious case assignment will fail.
// We can found all possible problems by doing the check though.
// For example, if the element type of the Array is derived from T,
// we can't figure out if we can successfully copy the element beforehand.
//
- Type targetType = array.GetType().GetElementType();
+ Type targetType = array.GetType().GetElementType();
Type sourceType = typeof(T);
- if(!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType))) {
+ if (!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType)))
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
@@ -211,51 +258,62 @@ namespace System.Collections.ObjectModel
// widening of primitive types here.
//
object[] objects = array as object[];
- if( objects == null) {
+ if (objects == null)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
int count = items.Count;
- try {
- for (int i = 0; i < count; i++) {
+ try
+ {
+ for (int i = 0; i < count; i++)
+ {
objects[index++] = items[i];
}
}
- catch(ArrayTypeMismatchException) {
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
- }
+ }
}
- object IList.this[int index] {
+ object IList.this[int index]
+ {
get { return items[index]; }
- set {
+ set
+ {
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(value, ExceptionArgument.value);
- try {
- this[index] = (T)value;
+ try
+ {
+ this[index] = (T)value;
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
}
-
}
}
- bool IList.IsReadOnly {
- get {
+ bool IList.IsReadOnly
+ {
+ get
+ {
return items.IsReadOnly;
}
}
- bool IList.IsFixedSize {
- get {
+ bool IList.IsFixedSize
+ {
+ get
+ {
// There is no IList<T>.IsFixedSize, so we must assume that only
// readonly collections are fixed size, if our internal item
// collection does not implement IList. Note that Array implements
// IList, and therefore T[] and U[] will be fixed-size.
IList list = items as IList;
- if(list != null)
+ if (list != null)
{
return list.IsFixedSize;
}
@@ -263,62 +321,77 @@ namespace System.Collections.ObjectModel
}
}
- int IList.Add(object value) {
- if( items.IsReadOnly) {
+ int IList.Add(object value)
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(value, ExceptionArgument.value);
-
- try {
+
+ try
+ {
Add((T)value);
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
- }
-
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
+ }
+
return this.Count - 1;
}
- bool IList.Contains(object value) {
- if(IsCompatibleObject(value)) {
- return Contains((T) value);
+ bool IList.Contains(object value)
+ {
+ if (IsCompatibleObject(value))
+ {
+ return Contains((T)value);
}
return false;
}
- int IList.IndexOf(object value) {
- if(IsCompatibleObject(value)) {
+ int IList.IndexOf(object value)
+ {
+ if (IsCompatibleObject(value))
+ {
return IndexOf((T)value);
- }
+ }
return -1;
}
- void IList.Insert(int index, object value) {
- if( items.IsReadOnly) {
+ void IList.Insert(int index, object value)
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(value, ExceptionArgument.value);
-
- try {
+
+ try
+ {
Insert(index, (T)value);
}
- catch (InvalidCastException) {
- ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
- }
-
+ catch (InvalidCastException)
+ {
+ ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(T));
+ }
}
- void IList.Remove(object value) {
- if( items.IsReadOnly) {
+ void IList.Remove(object value)
+ {
+ if (items.IsReadOnly)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- if(IsCompatibleObject(value)) {
- Remove((T) value);
- }
+ if (IsCompatibleObject(value))
+ {
+ Remove((T)value);
+ }
}
- private static bool IsCompatibleObject(object value) {
+ private static bool IsCompatibleObject(object value)
+ {
// Non-null values are fine. Only accept nulls if T is a class or Nullable<U>.
// Note that default(T) is not equal to null for value types except when T is Nullable<U>.
return ((value is T) || (value == null && default(T) == null));
diff --git a/src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs b/src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs
deleted file mode 100644
index 3fe7716203..0000000000
--- a/src/mscorlib/src/System/Collections/ObjectModel/KeyedCollection.cs
+++ /dev/null
@@ -1,244 +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.
-
-//
-
-namespace System.Collections.ObjectModel
-{
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- [Serializable]
- [DebuggerTypeProxy(typeof(Mscorlib_KeyedCollectionDebugView<,>))]
- [DebuggerDisplay("Count = {Count}")]
- public abstract class KeyedCollection<TKey,TItem>: Collection<TItem>
- {
- const int defaultThreshold = 0;
-
- IEqualityComparer<TKey> comparer;
- Dictionary<TKey,TItem> dict;
- int keyCount;
- int threshold;
-
- protected KeyedCollection(): this(null, defaultThreshold) {}
-
- protected KeyedCollection(IEqualityComparer<TKey> comparer): this(comparer, defaultThreshold) {}
-
-
- protected KeyedCollection(IEqualityComparer<TKey> comparer, int dictionaryCreationThreshold)
- : base(new List<TItem>()) { // Be explicit about the use of List<T> so we can foreach over
- // Items internally without enumerator allocations.
- if (comparer == null) {
- comparer = EqualityComparer<TKey>.Default;
- }
-
- if (dictionaryCreationThreshold == -1) {
- dictionaryCreationThreshold = int.MaxValue;
- }
-
- if( dictionaryCreationThreshold < -1) {
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.dictionaryCreationThreshold, ExceptionResource.ArgumentOutOfRange_InvalidThreshold);
- }
-
- this.comparer = comparer;
- this.threshold = dictionaryCreationThreshold;
- }
-
- /// <summary>
- /// Enables the use of foreach internally without allocations using <see cref="List{T}"/>'s struct enumerator.
- /// </summary>
- new private List<TItem> Items {
- get {
- Debug.Assert(base.Items is List<TItem>);
-
- return (List<TItem>)base.Items;
- }
- }
-
- public IEqualityComparer<TKey> Comparer {
- get {
- return comparer;
- }
- }
-
- public TItem this[TKey key] {
- get {
- if( key == null) {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
- }
-
- if (dict != null) {
- return dict[key];
- }
-
- foreach (TItem item in Items) {
- if (comparer.Equals(GetKeyForItem(item), key)) return item;
- }
-
- ThrowHelper.ThrowKeyNotFoundException();
- return default(TItem);
- }
- }
-
- public bool Contains(TKey key) {
- if( key == null) {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
- }
-
- if (dict != null) {
- return dict.ContainsKey(key);
- }
-
- foreach (TItem item in Items) {
- if (comparer.Equals(GetKeyForItem(item), key)) return true;
- }
- return false;
- }
-
- private bool ContainsItem(TItem item) {
- TKey key;
- if( (dict == null) || ((key = GetKeyForItem(item)) == null)) {
- return Items.Contains(item);
- }
-
- TItem itemInDict;
- bool exist = dict.TryGetValue(key, out itemInDict);
- if( exist) {
- return EqualityComparer<TItem>.Default.Equals(itemInDict, item);
- }
- return false;
- }
-
- public bool Remove(TKey key) {
- if( key == null) {
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
- }
-
- if (dict != null) {
- if (dict.ContainsKey(key)) {
- return Remove(dict[key]);
- }
-
- return false;
- }
-
- for (int i = 0; i < Items.Count; i++) {
- if (comparer.Equals(GetKeyForItem(Items[i]), key)) {
- RemoveItem(i);
- return true;
- }
- }
- return false;
- }
-
- protected IDictionary<TKey,TItem> Dictionary {
- get { return dict; }
- }
-
- protected void ChangeItemKey(TItem item, TKey newKey) {
- // check if the item exists in the collection
- if( !ContainsItem(item)) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_ItemNotExist);
- }
-
- TKey oldKey = GetKeyForItem(item);
- if (!comparer.Equals(oldKey, newKey)) {
- if (newKey != null) {
- AddKey(newKey, item);
- }
-
- if (oldKey != null) {
- RemoveKey(oldKey);
- }
- }
- }
-
- protected override void ClearItems() {
- base.ClearItems();
- if (dict != null) {
- dict.Clear();
- }
-
- keyCount = 0;
- }
-
- protected abstract TKey GetKeyForItem(TItem item);
-
- protected override void InsertItem(int index, TItem item) {
- TKey key = GetKeyForItem(item);
- if (key != null) {
- AddKey(key, item);
- }
- base.InsertItem(index, item);
- }
-
- protected override void RemoveItem(int index) {
- TKey key = GetKeyForItem(Items[index]);
- if (key != null) {
- RemoveKey(key);
- }
- base.RemoveItem(index);
- }
-
- protected override void SetItem(int index, TItem item) {
- TKey newKey = GetKeyForItem(item);
- TKey oldKey = GetKeyForItem(Items[index]);
-
- if (comparer.Equals(oldKey, newKey)) {
- if (newKey != null && dict != null) {
- dict[newKey] = item;
- }
- }
- else {
- if (newKey != null) {
- AddKey(newKey, item);
- }
-
- if (oldKey != null) {
- RemoveKey(oldKey);
- }
- }
- base.SetItem(index, item);
- }
-
- private void AddKey(TKey key, TItem item) {
- if (dict != null) {
- dict.Add(key, item);
- }
- else if (keyCount == threshold) {
- CreateDictionary();
- dict.Add(key, item);
- }
- else {
- if (Contains(key)) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
- }
-
- keyCount++;
- }
- }
-
- private void CreateDictionary() {
- dict = new Dictionary<TKey,TItem>(comparer);
- foreach (TItem item in Items) {
- TKey key = GetKeyForItem(item);
- if (key != null) {
- dict.Add(key, item);
- }
- }
- }
-
- private void RemoveKey(TKey key) {
- Debug.Assert(key != null, "key shouldn't be null!");
- if (dict != null) {
- dict.Remove(key);
- }
- else {
- keyCount--;
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs
index 10c48cf76d..b484879c27 100644
--- a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs
+++ b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyCollection.cs
@@ -4,150 +4,184 @@
//
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime;
+
namespace System.Collections.ObjectModel
{
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Runtime;
-
[Serializable]
[DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]
- [DebuggerDisplay("Count = {Count}")]
- public class ReadOnlyCollection<T>: IList<T>, IList, IReadOnlyList<T>
+ [DebuggerDisplay("Count = {Count}")]
+ public class ReadOnlyCollection<T> : IList<T>, IList, IReadOnlyList<T>
{
- IList<T> list;
+ private IList<T> list;
[NonSerialized]
private Object _syncRoot;
- public ReadOnlyCollection(IList<T> list) {
- if (list == null) {
+ public ReadOnlyCollection(IList<T> list)
+ {
+ if (list == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.list);
}
this.list = list;
}
- public int Count {
+ public int Count
+ {
get { return list.Count; }
}
- public T this[int index] {
+ public T this[int index]
+ {
get { return list[index]; }
}
- public bool Contains(T value) {
+ public bool Contains(T value)
+ {
return list.Contains(value);
}
- public void CopyTo(T[] array, int index) {
+ public void CopyTo(T[] array, int index)
+ {
list.CopyTo(array, index);
}
- public IEnumerator<T> GetEnumerator() {
+ public IEnumerator<T> GetEnumerator()
+ {
return list.GetEnumerator();
}
- public int IndexOf(T value) {
+ public int IndexOf(T value)
+ {
return list.IndexOf(value);
}
- protected IList<T> Items {
- get {
+ protected IList<T> Items
+ {
+ get
+ {
return list;
}
}
- bool ICollection<T>.IsReadOnly {
+ bool ICollection<T>.IsReadOnly
+ {
get { return true; }
}
-
- T IList<T>.this[int index] {
+
+ T IList<T>.this[int index]
+ {
get { return list[index]; }
- set {
+ set
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
}
- void ICollection<T>.Add(T value) {
+ void ICollection<T>.Add(T value)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
-
- void ICollection<T>.Clear() {
+
+ void ICollection<T>.Clear()
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- void IList<T>.Insert(int index, T value) {
+ void IList<T>.Insert(int index, T value)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- bool ICollection<T>.Remove(T value) {
+ bool ICollection<T>.Remove(T value)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
return false;
}
- void IList<T>.RemoveAt(int index) {
+ void IList<T>.RemoveAt(int index)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- IEnumerator IEnumerable.GetEnumerator() {
+ IEnumerator IEnumerable.GetEnumerator()
+ {
return ((IEnumerable)list).GetEnumerator();
}
- bool ICollection.IsSynchronized {
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- object ICollection.SyncRoot {
- get {
- if( _syncRoot == null) {
+ object ICollection.SyncRoot
+ {
+ get
+ {
+ if (_syncRoot == null)
+ {
ICollection c = list as ICollection;
- if( c != null) {
+ if (c != null)
+ {
_syncRoot = c.SyncRoot;
}
- else {
- System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
+ else
+ {
+ System.Threading.Interlocked.CompareExchange<Object>(ref _syncRoot, new Object(), null);
}
}
- return _syncRoot;
+ return _syncRoot;
}
}
- void ICollection.CopyTo(Array array, int index) {
- if (array==null) {
+ void ICollection.CopyTo(Array array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if (array.Rank != 1) {
- ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
+ if (array.Rank != 1)
+ {
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
- if( array.GetLowerBound(0) != 0 ) {
+ if (array.GetLowerBound(0) != 0)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
-
- if (index < 0) {
+
+ if (index < 0)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < Count) {
+ if (array.Length - index < Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
T[] items = array as T[];
- if (items != null) {
+ if (items != null)
+ {
list.CopyTo(items, index);
}
- else {
+ else
+ {
//
// Catch the obvious case assignment will fail.
// We can found all possible problems by doing the check though.
// For example, if the element type of the Array is derived from T,
// we can't figure out if we can successfully copy the element beforehand.
//
- Type targetType = array.GetType().GetElementType();
+ Type targetType = array.GetType().GetElementType();
Type sourceType = typeof(T);
- if(!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType))) {
+ if (!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType)))
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
@@ -156,76 +190,94 @@ namespace System.Collections.ObjectModel
// widening of primitive types here.
//
object[] objects = array as object[];
- if( objects == null) {
+ if (objects == null)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
int count = list.Count;
- try {
- for (int i = 0; i < count; i++) {
+ try
+ {
+ for (int i = 0; i < count; i++)
+ {
objects[index++] = list[i];
}
}
- catch(ArrayTypeMismatchException) {
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
- bool IList.IsFixedSize {
+ bool IList.IsFixedSize
+ {
get { return true; }
}
- bool IList.IsReadOnly {
+ bool IList.IsReadOnly
+ {
get { return true; }
}
- object IList.this[int index] {
+ object IList.this[int index]
+ {
get { return list[index]; }
- set {
+ set
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
}
- int IList.Add(object value) {
+ int IList.Add(object value)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
return -1;
}
- void IList.Clear() {
- ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ void IList.Clear()
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- private static bool IsCompatibleObject(object value) {
+ private static bool IsCompatibleObject(object value)
+ {
// Non-null values are fine. Only accept nulls if T is a class or Nullable<U>.
// Note that default(T) is not equal to null for value types except when T is Nullable<U>.
return ((value is T) || (value == null && default(T) == null));
}
- bool IList.Contains(object value) {
- if(IsCompatibleObject(value)) {
- return Contains((T) value);
+ bool IList.Contains(object value)
+ {
+ if (IsCompatibleObject(value))
+ {
+ return Contains((T)value);
}
return false;
}
- int IList.IndexOf(object value) {
- if(IsCompatibleObject(value)) {
+ int IList.IndexOf(object value)
+ {
+ if (IsCompatibleObject(value))
+ {
return IndexOf((T)value);
}
return -1;
}
- void IList.Insert(int index, object value) {
+ void IList.Insert(int index, object value)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- void IList.Remove(object value) {
- ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ void IList.Remove(object value)
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- void IList.RemoveAt(int index) {
+ void IList.RemoveAt(int index)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
- }
+ }
}
}
diff --git a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs
index 5c9e8c44c6..ebf86cdc58 100644
--- a/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs
+++ b/src/mscorlib/src/System/Collections/ObjectModel/ReadOnlyDictionary.cs
@@ -11,18 +11,18 @@
**
===========================================================*/
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
namespace System.Collections.ObjectModel
{
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
[Serializable]
[DebuggerTypeProxy(typeof(Mscorlib_DictionaryDebugView<,>))]
[DebuggerDisplay("Count = {Count}")]
- public class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, IReadOnlyDictionary<TKey, TValue>
+ internal class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, IReadOnlyDictionary<TKey, TValue>
{
private readonly IDictionary<TKey, TValue> m_dictionary;
[NonSerialized]
@@ -32,32 +32,41 @@ namespace System.Collections.ObjectModel
[NonSerialized]
private ValueCollection m_values;
- public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary) {
- if (dictionary == null) {
+ public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
+ {
+ if (dictionary == null)
+ {
throw new ArgumentNullException(nameof(dictionary));
}
Contract.EndContractBlock();
m_dictionary = dictionary;
}
- protected IDictionary<TKey, TValue> Dictionary {
+ protected IDictionary<TKey, TValue> Dictionary
+ {
get { return m_dictionary; }
}
- public KeyCollection Keys {
- get {
+ public KeyCollection Keys
+ {
+ get
+ {
Contract.Ensures(Contract.Result<KeyCollection>() != null);
- if (m_keys == null) {
+ if (m_keys == null)
+ {
m_keys = new KeyCollection(m_dictionary.Keys);
}
return m_keys;
}
}
- public ValueCollection Values {
- get {
+ public ValueCollection Values
+ {
+ get
+ {
Contract.Ensures(Contract.Result<ValueCollection>() != null);
- if (m_values == null) {
+ if (m_values == null)
+ {
m_values = new ValueCollection(m_dictionary.Values);
}
return m_values;
@@ -66,46 +75,59 @@ namespace System.Collections.ObjectModel
#region IDictionary<TKey, TValue> Members
- public bool ContainsKey(TKey key) {
+ public bool ContainsKey(TKey key)
+ {
return m_dictionary.ContainsKey(key);
}
- ICollection<TKey> IDictionary<TKey, TValue>.Keys {
- get {
+ ICollection<TKey> IDictionary<TKey, TValue>.Keys
+ {
+ get
+ {
return Keys;
}
}
- public bool TryGetValue(TKey key, out TValue value) {
+ public bool TryGetValue(TKey key, out TValue value)
+ {
return m_dictionary.TryGetValue(key, out value);
}
- ICollection<TValue> IDictionary<TKey, TValue>.Values {
- get {
+ ICollection<TValue> IDictionary<TKey, TValue>.Values
+ {
+ get
+ {
return Values;
}
}
- public TValue this[TKey key] {
- get {
+ public TValue this[TKey key]
+ {
+ get
+ {
return m_dictionary[key];
}
}
- void IDictionary<TKey, TValue>.Add(TKey key, TValue value) {
+ void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- bool IDictionary<TKey, TValue>.Remove(TKey key) {
+ bool IDictionary<TKey, TValue>.Remove(TKey key)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
return false;
}
- TValue IDictionary<TKey, TValue>.this[TKey key] {
- get {
+ TValue IDictionary<TKey, TValue>.this[TKey key]
+ {
+ get
+ {
return m_dictionary[key];
}
- set {
+ set
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
}
@@ -114,31 +136,38 @@ namespace System.Collections.ObjectModel
#region ICollection<KeyValuePair<TKey, TValue>> Members
- public int Count {
+ public int Count
+ {
get { return m_dictionary.Count; }
}
- bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item) {
+ bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
+ {
return m_dictionary.Contains(item);
}
- void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) {
+ void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
+ {
m_dictionary.CopyTo(array, arrayIndex);
}
- bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly {
+ bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
+ {
get { return true; }
}
- void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item) {
+ void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- void ICollection<KeyValuePair<TKey, TValue>>.Clear() {
+ void ICollection<KeyValuePair<TKey, TValue>>.Clear()
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item) {
+ bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
return false;
}
@@ -147,7 +176,8 @@ namespace System.Collections.ObjectModel
#region IEnumerable<KeyValuePair<TKey, TValue>> Members
- public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
+ public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
+ {
return m_dictionary.GetEnumerator();
}
@@ -155,7 +185,8 @@ namespace System.Collections.ObjectModel
#region IEnumerable Members
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
return ((IEnumerable)m_dictionary).GetEnumerator();
}
@@ -163,131 +194,170 @@ namespace System.Collections.ObjectModel
#region IDictionary Members
- private static bool IsCompatibleKey(object key) {
- if (key == null) {
+ private static bool IsCompatibleKey(object key)
+ {
+ if (key == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
return key is TKey;
}
- void IDictionary.Add(object key, object value) {
+ void IDictionary.Add(object key, object value)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- void IDictionary.Clear() {
+ void IDictionary.Clear()
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- bool IDictionary.Contains(object key) {
+ bool IDictionary.Contains(object key)
+ {
return IsCompatibleKey(key) && ContainsKey((TKey)key);
}
- IDictionaryEnumerator IDictionary.GetEnumerator() {
+ IDictionaryEnumerator IDictionary.GetEnumerator()
+ {
IDictionary d = m_dictionary as IDictionary;
- if (d != null) {
+ if (d != null)
+ {
return d.GetEnumerator();
}
return new DictionaryEnumerator(m_dictionary);
}
- bool IDictionary.IsFixedSize {
+ bool IDictionary.IsFixedSize
+ {
get { return true; }
}
- bool IDictionary.IsReadOnly {
+ bool IDictionary.IsReadOnly
+ {
get { return true; }
}
- ICollection IDictionary.Keys {
- get {
+ ICollection IDictionary.Keys
+ {
+ get
+ {
return Keys;
}
}
- void IDictionary.Remove(object key) {
+ void IDictionary.Remove(object key)
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
- ICollection IDictionary.Values {
- get {
+ ICollection IDictionary.Values
+ {
+ get
+ {
return Values;
}
}
- object IDictionary.this[object key] {
- get {
- if (IsCompatibleKey(key)) {
+ object IDictionary.this[object key]
+ {
+ get
+ {
+ if (IsCompatibleKey(key))
+ {
return this[(TKey)key];
}
return null;
}
- set {
+ set
+ {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
}
- void ICollection.CopyTo(Array array, int index) {
- if (array == null) {
+ void ICollection.CopyTo(Array array, int index)
+ {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if (array.Rank != 1) {
+ if (array.Rank != 1)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
- if (array.GetLowerBound(0) != 0) {
+ if (array.GetLowerBound(0) != 0)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
- if (index < 0 || index > array.Length) {
+ if (index < 0 || index > array.Length)
+ {
ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException();
}
- if (array.Length - index < Count) {
+ if (array.Length - index < Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
KeyValuePair<TKey, TValue>[] pairs = array as KeyValuePair<TKey, TValue>[];
- if (pairs != null) {
+ if (pairs != null)
+ {
m_dictionary.CopyTo(pairs, index);
}
- else {
+ else
+ {
DictionaryEntry[] dictEntryArray = array as DictionaryEntry[];
- if (dictEntryArray != null) {
- foreach (var item in m_dictionary) {
+ if (dictEntryArray != null)
+ {
+ foreach (var item in m_dictionary)
+ {
dictEntryArray[index++] = new DictionaryEntry(item.Key, item.Value);
}
}
- else {
+ else
+ {
object[] objects = array as object[];
- if (objects == null) {
+ if (objects == null)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
- try {
- foreach (var item in m_dictionary) {
+ try
+ {
+ foreach (var item in m_dictionary)
+ {
objects[index++] = new KeyValuePair<TKey, TValue>(item.Key, item.Value);
}
}
- catch (ArrayTypeMismatchException) {
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
}
}
- bool ICollection.IsSynchronized {
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- object ICollection.SyncRoot {
- get {
- if (m_syncRoot == null) {
+ object ICollection.SyncRoot
+ {
+ get
+ {
+ if (m_syncRoot == null)
+ {
ICollection c = m_dictionary as ICollection;
- if (c != null) {
+ if (c != null)
+ {
m_syncRoot = c.SyncRoot;
}
- else {
+ else
+ {
System.Threading.Interlocked.CompareExchange<Object>(ref m_syncRoot, new Object(), null);
}
}
@@ -296,36 +366,44 @@ namespace System.Collections.ObjectModel
}
[Serializable]
- private struct DictionaryEnumerator : IDictionaryEnumerator {
+ private struct DictionaryEnumerator : IDictionaryEnumerator
+ {
private readonly IDictionary<TKey, TValue> m_dictionary;
private IEnumerator<KeyValuePair<TKey, TValue>> m_enumerator;
- public DictionaryEnumerator(IDictionary<TKey, TValue> dictionary) {
+ public DictionaryEnumerator(IDictionary<TKey, TValue> dictionary)
+ {
m_dictionary = dictionary;
m_enumerator = m_dictionary.GetEnumerator();
}
- public DictionaryEntry Entry {
+ public DictionaryEntry Entry
+ {
get { return new DictionaryEntry(m_enumerator.Current.Key, m_enumerator.Current.Value); }
}
- public object Key {
+ public object Key
+ {
get { return m_enumerator.Current.Key; }
}
- public object Value {
+ public object Value
+ {
get { return m_enumerator.Current.Value; }
}
- public object Current {
+ public object Current
+ {
get { return Entry; }
}
- public bool MoveNext() {
+ public bool MoveNext()
+ {
return m_enumerator.MoveNext();
}
- public void Reset() {
+ public void Reset()
+ {
m_enumerator.Reset();
}
}
@@ -334,14 +412,18 @@ namespace System.Collections.ObjectModel
#region IReadOnlyDictionary members
- IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys {
- get {
+ IEnumerable<TKey> IReadOnlyDictionary<TKey, TValue>.Keys
+ {
+ get
+ {
return Keys;
}
}
- IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values {
- get {
+ IEnumerable<TValue> IReadOnlyDictionary<TKey, TValue>.Values
+ {
+ get
+ {
return Values;
}
}
@@ -351,14 +433,16 @@ namespace System.Collections.ObjectModel
[DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]
[DebuggerDisplay("Count = {Count}")]
[Serializable]
- public sealed class KeyCollection : ICollection<TKey>, ICollection, IReadOnlyCollection<TKey> {
+ public sealed class KeyCollection : ICollection<TKey>, ICollection, IReadOnlyCollection<TKey>
+ {
private readonly ICollection<TKey> m_collection;
[NonSerialized]
private Object m_syncRoot;
internal KeyCollection(ICollection<TKey> collection)
{
- if (collection == null) {
+ if (collection == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
m_collection = collection;
@@ -386,11 +470,13 @@ namespace System.Collections.ObjectModel
m_collection.CopyTo(array, arrayIndex);
}
- public int Count {
+ public int Count
+ {
get { return m_collection.Count; }
}
- bool ICollection<TKey>.IsReadOnly {
+ bool ICollection<TKey>.IsReadOnly
+ {
get { return true; }
}
@@ -413,7 +499,8 @@ namespace System.Collections.ObjectModel
#region IEnumerable Members
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
return ((IEnumerable)m_collection).GetEnumerator();
}
@@ -421,22 +508,29 @@ namespace System.Collections.ObjectModel
#region ICollection Members
- void ICollection.CopyTo(Array array, int index) {
+ void ICollection.CopyTo(Array array, int index)
+ {
ReadOnlyDictionaryHelpers.CopyToNonGenericICollectionHelper<TKey>(m_collection, array, index);
}
- bool ICollection.IsSynchronized {
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- object ICollection.SyncRoot {
- get {
- if (m_syncRoot == null) {
+ object ICollection.SyncRoot
+ {
+ get
+ {
+ if (m_syncRoot == null)
+ {
ICollection c = m_collection as ICollection;
- if (c != null) {
+ if (c != null)
+ {
m_syncRoot = c.SyncRoot;
}
- else {
+ else
+ {
System.Threading.Interlocked.CompareExchange<Object>(ref m_syncRoot, new Object(), null);
}
}
@@ -450,14 +544,16 @@ namespace System.Collections.ObjectModel
[DebuggerTypeProxy(typeof(Mscorlib_CollectionDebugView<>))]
[DebuggerDisplay("Count = {Count}")]
[Serializable]
- public sealed class ValueCollection : ICollection<TValue>, ICollection, IReadOnlyCollection<TValue> {
+ public sealed class ValueCollection : ICollection<TValue>, ICollection, IReadOnlyCollection<TValue>
+ {
private readonly ICollection<TValue> m_collection;
[NonSerialized]
private Object m_syncRoot;
internal ValueCollection(ICollection<TValue> collection)
{
- if (collection == null) {
+ if (collection == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
m_collection = collection;
@@ -485,11 +581,13 @@ namespace System.Collections.ObjectModel
m_collection.CopyTo(array, arrayIndex);
}
- public int Count {
+ public int Count
+ {
get { return m_collection.Count; }
}
- bool ICollection<TValue>.IsReadOnly {
+ bool ICollection<TValue>.IsReadOnly
+ {
get { return true; }
}
@@ -512,7 +610,8 @@ namespace System.Collections.ObjectModel
#region IEnumerable Members
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
return ((IEnumerable)m_collection).GetEnumerator();
}
@@ -520,22 +619,29 @@ namespace System.Collections.ObjectModel
#region ICollection Members
- void ICollection.CopyTo(Array array, int index) {
+ void ICollection.CopyTo(Array array, int index)
+ {
ReadOnlyDictionaryHelpers.CopyToNonGenericICollectionHelper<TValue>(m_collection, array, index);
}
- bool ICollection.IsSynchronized {
+ bool ICollection.IsSynchronized
+ {
get { return false; }
}
- object ICollection.SyncRoot {
- get {
- if (m_syncRoot == null) {
+ object ICollection.SyncRoot
+ {
+ get
+ {
+ if (m_syncRoot == null)
+ {
ICollection c = m_collection as ICollection;
- if (c != null) {
+ if (c != null)
+ {
m_syncRoot = c.SyncRoot;
}
- else {
+ else
+ {
System.Threading.Interlocked.CompareExchange<Object>(ref m_syncRoot, new Object(), null);
}
}
@@ -555,38 +661,46 @@ namespace System.Collections.ObjectModel
// Abstracted away to avoid redundant implementations.
internal static void CopyToNonGenericICollectionHelper<T>(ICollection<T> collection, Array array, int index)
{
- if (array == null) {
+ if (array == null)
+ {
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
- if (array.Rank != 1) {
+ if (array.Rank != 1)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
- if (array.GetLowerBound(0) != 0) {
+ if (array.GetLowerBound(0) != 0)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
- if (index < 0) {
+ if (index < 0)
+ {
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
- if (array.Length - index < collection.Count) {
+ if (array.Length - index < collection.Count)
+ {
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
// Easy out if the ICollection<T> implements the non-generic ICollection
ICollection nonGenericCollection = collection as ICollection;
- if (nonGenericCollection != null) {
+ if (nonGenericCollection != null)
+ {
nonGenericCollection.CopyTo(array, index);
return;
}
T[] items = array as T[];
- if (items != null) {
+ if (items != null)
+ {
collection.CopyTo(items, index);
}
- else {
+ else
+ {
//
// Catch the obvious case assignment will fail.
// We can found all possible problems by doing the check though.
@@ -595,7 +709,8 @@ namespace System.Collections.ObjectModel
//
Type targetType = array.GetType().GetElementType();
Type sourceType = typeof(T);
- if (!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType))) {
+ if (!(targetType.IsAssignableFrom(sourceType) || sourceType.IsAssignableFrom(targetType)))
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
@@ -604,16 +719,20 @@ namespace System.Collections.ObjectModel
// widening of primitive types here.
//
object[] objects = array as object[];
- if (objects == null) {
+ if (objects == null)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
- try {
- foreach (var item in collection) {
+ try
+ {
+ foreach (var item in collection)
+ {
objects[index++] = item;
}
}
- catch (ArrayTypeMismatchException) {
+ catch (ArrayTypeMismatchException)
+ {
ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType();
}
}
diff --git a/src/mscorlib/src/System/Collections/StructuralComparisons.cs b/src/mscorlib/src/System/Collections/StructuralComparisons.cs
deleted file mode 100644
index 685af59c4b..0000000000
--- a/src/mscorlib/src/System/Collections/StructuralComparisons.cs
+++ /dev/null
@@ -1,89 +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;
-
-namespace System.Collections {
- public static class StructuralComparisons {
-
- private static volatile IComparer s_StructuralComparer;
- private static volatile IEqualityComparer s_StructuralEqualityComparer;
-
- public static IComparer StructuralComparer {
- get {
- IComparer comparer = s_StructuralComparer;
- if (comparer == null) {
- comparer = new StructuralComparer();
- s_StructuralComparer = comparer;
- }
- return comparer;
- }
- }
-
- public static IEqualityComparer StructuralEqualityComparer {
- get {
- IEqualityComparer comparer = s_StructuralEqualityComparer;
- if (comparer == null) {
- comparer = new StructuralEqualityComparer();
- s_StructuralEqualityComparer = comparer;
- }
- return comparer;
- }
- }
- }
-
- [Serializable]
- internal class StructuralEqualityComparer : IEqualityComparer {
- public new bool Equals(Object x, Object y) {
- if (x != null) {
-
- IStructuralEquatable seObj = x as IStructuralEquatable;
-
- if (seObj != null){
- return seObj.Equals(y, this);
- }
-
- if (y != null) {
- return x.Equals(y);
- } else {
- return false;
- }
- }
- if (y != null) return false;
- return true;
- }
-
- public int GetHashCode(Object obj) {
- if (obj == null) return 0;
-
- IStructuralEquatable seObj = obj as IStructuralEquatable;
-
- if (seObj != null) {
- return seObj.GetHashCode(this);
- }
-
- return obj.GetHashCode();
- }
- }
-
- [Serializable]
- internal class StructuralComparer : IComparer {
- public int Compare(Object x, Object y) {
-
- if (x == null) return y == null ? 0 : -1;
- if (y == null) return 1;
-
- IStructuralComparable scX = x as IStructuralComparable;
-
- if (scX != null) {
- return scX.CompareTo(y, this);
- }
-
- return Comparer.Default.Compare(x, y);
- }
- }
-
-}
diff --git a/src/mscorlib/src/System/ComponentModel/EditorBrowsableAttribute.cs b/src/mscorlib/src/System/ComponentModel/EditorBrowsableAttribute.cs
deleted file mode 100644
index a7946f8203..0000000000
--- a/src/mscorlib/src/System/ComponentModel/EditorBrowsableAttribute.cs
+++ /dev/null
@@ -1,48 +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.
-
-namespace System.ComponentModel
-{
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Delegate | AttributeTargets.Interface)]
- public sealed class EditorBrowsableAttribute : Attribute
- {
- private EditorBrowsableState browsableState;
-
- public EditorBrowsableAttribute(EditorBrowsableState state)
- {
- browsableState = state;
- }
-
- public EditorBrowsableAttribute () : this(EditorBrowsableState.Always) { }
-
- public EditorBrowsableState State
- {
- get { return browsableState; }
- }
-
- public override bool Equals(object obj)
- {
- if (obj == this)
- {
- return true;
- }
-
- EditorBrowsableAttribute other = obj as EditorBrowsableAttribute;
-
- return (other != null) && other.browsableState == browsableState;
- }
-
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
- }
-
- public enum EditorBrowsableState
- {
- Always,
- Never,
- Advanced
- }
-}
diff --git a/src/mscorlib/src/System/Configuration/Assemblies/AssemblyHashAlgorithm.cs b/src/mscorlib/src/System/Configuration/Assemblies/AssemblyHashAlgorithm.cs
deleted file mode 100644
index a19d0344b1..0000000000
--- a/src/mscorlib/src/System/Configuration/Assemblies/AssemblyHashAlgorithm.cs
+++ /dev/null
@@ -1,28 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose:
-**
-**
-===========================================================*/
-using System.Runtime.InteropServices;
-
-namespace System.Configuration.Assemblies {
-
- using System;
- [Serializable]
- public enum AssemblyHashAlgorithm
- {
- None = 0,
- MD5 = 0x8003,
- SHA1 = 0x8004,
- SHA256 = 0x800c,
- SHA384 = 0x800d,
- SHA512 = 0x800e,
- }
-}
diff --git a/src/mscorlib/src/System/Configuration/Assemblies/AssemblyVersionCompatibility.cs b/src/mscorlib/src/System/Configuration/Assemblies/AssemblyVersionCompatibility.cs
deleted file mode 100644
index b7e9c30c62..0000000000
--- a/src/mscorlib/src/System/Configuration/Assemblies/AssemblyVersionCompatibility.cs
+++ /dev/null
@@ -1,23 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose: defining the different flavor's assembly version compatibility
-**
-**
-===========================================================*/
-namespace System.Configuration.Assemblies {
-
- using System;
- [Serializable]
- public enum AssemblyVersionCompatibility
- {
- SameMachine = 1,
- SameProcess = 2,
- SameDomain = 3,
- }
-}
diff --git a/src/mscorlib/src/System/Convert.cs b/src/mscorlib/src/System/Convert.cs
deleted file mode 100644
index 0cd3c5d715..0000000000
--- a/src/mscorlib/src/System/Convert.cs
+++ /dev/null
@@ -1,2703 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose: Home for static conversion methods.
-**
-**
-===========================================================*/
-
-using System;
-using System.Globalization;
-using System.Threading;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Versioning;
-using System.Security;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-
-
-namespace System {
-
- [Flags]
- public enum Base64FormattingOptions {
- None = 0,
- InsertLineBreaks = 1
- }
-
- // Returns the type code of this object. An implementation of this method
- // must not return TypeCode.Empty (which represents a null reference) or
- // TypeCode.Object (which represents an object that doesn't implement the
- // IConvertible interface). An implementation of this method should return
- // TypeCode.DBNull if the value of this object is a database null. For
- // example, a nullable integer type should return TypeCode.DBNull if the
- // value of the object is the database null. Otherwise, an implementation
- // of this method should return the TypeCode that best describes the
- // internal representation of the object.
- // The Value class provides conversion and querying methods for values. The
- // Value class contains static members only, and it is not possible to create
- // instances of the class.
- //
- // The statically typed conversion methods provided by the Value class are all
- // of the form:
- //
- // public static XXX ToXXX(YYY value)
- //
- // where XXX is the target type and YYY is the source type. The matrix below
- // shows the set of supported conversions. The set of conversions is symmetric
- // such that for every ToXXX(YYY) there is also a ToYYY(XXX).
- //
- // From: To: Bol Chr SBy Byt I16 U16 I32 U32 I64 U64 Sgl Dbl Dec Dat Str
- // ----------------------------------------------------------------------
- // Boolean x x x x x x x x x x x x x
- // Char x x x x x x x x x x
- // SByte x x x x x x x x x x x x x x
- // Byte x x x x x x x x x x x x x x
- // Int16 x x x x x x x x x x x x x x
- // UInt16 x x x x x x x x x x x x x x
- // Int32 x x x x x x x x x x x x x x
- // UInt32 x x x x x x x x x x x x x x
- // Int64 x x x x x x x x x x x x x x
- // UInt64 x x x x x x x x x x x x x x
- // Single x x x x x x x x x x x x x
- // Double x x x x x x x x x x x x x
- // Decimal x x x x x x x x x x x x x
- // DateTime x x
- // String x x x x x x x x x x x x x x x
- // ----------------------------------------------------------------------
- //
- // For dynamic conversions, the Value class provides a set of methods of the
- // form:
- //
- // public static XXX ToXXX(object value)
- //
- // where XXX is the target type (Boolean, Char, SByte, Byte, Int16, UInt16,
- // Int32, UInt32, Int64, UInt64, Single, Double, Decimal, DateTime,
- // or String). The implementations of these methods all take the form:
- //
- // public static XXX toXXX(object value) {
- // return value == null? XXX.Default: ((IConvertible)value).ToXXX();
- // }
- //
- // The code first checks if the given value is a null reference (which is the
- // same as Value.Empty), in which case it returns the default value for type
- // XXX. Otherwise, a cast to IConvertible is performed, and the appropriate ToXXX()
- // method is invoked on the object. An InvalidCastException is thrown if the
- // cast to IConvertible fails, and that exception is simply allowed to propagate out
- // of the conversion method.
-
- // Constant representing the database null value. This value is used in
- // database applications to indicate the absense of a known value. Note
- // that Value.DBNull is NOT the same as a null object reference, which is
- // represented by Value.Empty.
- //
- // The Equals() method of DBNull always returns false, even when the
- // argument is itself DBNull.
- //
- // When passed Value.DBNull, the Value.GetTypeCode() method returns
- // TypeCode.DBNull.
- //
- // When passed Value.DBNull, the Value.ToXXX() methods all throw an
- // InvalidCastException.
-
- public static class Convert {
-
- //A typeof operation is fairly expensive (does a system call), so we'll cache these here
- //statically. These are exactly lined up with the TypeCode, eg. ConvertType[TypeCode.Int16]
- //will give you the type of an Int16.
- internal static readonly RuntimeType[] ConvertTypes = {
- (RuntimeType)typeof(System.Empty),
- (RuntimeType)typeof(Object),
- (RuntimeType)typeof(System.DBNull),
- (RuntimeType)typeof(Boolean),
- (RuntimeType)typeof(Char),
- (RuntimeType)typeof(SByte),
- (RuntimeType)typeof(Byte),
- (RuntimeType)typeof(Int16),
- (RuntimeType)typeof(UInt16),
- (RuntimeType)typeof(Int32),
- (RuntimeType)typeof(UInt32),
- (RuntimeType)typeof(Int64),
- (RuntimeType)typeof(UInt64),
- (RuntimeType)typeof(Single),
- (RuntimeType)typeof(Double),
- (RuntimeType)typeof(Decimal),
- (RuntimeType)typeof(DateTime),
- (RuntimeType)typeof(Object), //TypeCode is discontinuous so we need a placeholder.
- (RuntimeType)typeof(String)
- };
-
- // Need to special case Enum because typecode will be underlying type, e.g. Int32
- private static readonly RuntimeType EnumType = (RuntimeType)typeof(Enum);
-
- internal static readonly char[] base64Table = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
- 'P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d',
- 'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s',
- 't','u','v','w','x','y','z','0','1','2','3','4','5','6','7',
- '8','9','+','/','=' };
-
- private const Int32 base64LineBreakPosition = 76;
-
-#if _DEBUG
- private static bool TriggerAsserts = DoAsserts();
- private static bool DoAsserts() {
- Debug.Assert(ConvertTypes!=null, "[Convert.cctor]ConvertTypes!=null");
- Debug.Assert(ConvertTypes.Length == ((int)TypeCode.String + 1), "[Convert.cctor]ConvertTypes.Length == ((int)TypeCode.String + 1)");
- Debug.Assert(ConvertTypes[(int)TypeCode.Empty]==typeof(System.Empty),
- "[Convert.cctor]ConvertTypes[(int)TypeCode.Empty]==typeof(System.Empty)");
- Debug.Assert(ConvertTypes[(int)TypeCode.String]==typeof(String),
- "[Convert.cctor]ConvertTypes[(int)TypeCode.String]==typeof(System.String)");
- Debug.Assert(ConvertTypes[(int)TypeCode.Int32]==typeof(int),
- "[Convert.cctor]ConvertTypes[(int)TypeCode.Int32]==typeof(int)");
- return true;
- }
-#endif
-
- public static readonly Object DBNull = System.DBNull.Value;
-
- // Returns the type code for the given object. If the argument is null,
- // the result is TypeCode.Empty. If the argument is not a value (i.e. if
- // the object does not implement IConvertible), the result is TypeCode.Object.
- // Otherwise, the result is the type code of the object, as determined by
- // the object's implementation of IConvertible.
- [Pure]
- public static TypeCode GetTypeCode(object value) {
- if (value == null) return TypeCode.Empty;
- IConvertible temp = value as IConvertible;
- if (temp != null)
- {
- return temp.GetTypeCode();
- }
- return TypeCode.Object;
- }
-
- // Returns true if the given object is a database null. This operation
- // corresponds to "value.GetTypeCode() == TypeCode.DBNull".
- [Pure]
- public static bool IsDBNull(object value) {
- if (value == System.DBNull.Value) return true;
- IConvertible convertible = value as IConvertible;
- return convertible != null? convertible.GetTypeCode() == TypeCode.DBNull: false;
- }
-
- // Converts the given object to the given type. In general, this method is
- // equivalent to calling the Value.ToXXX(value) method for the given
- // typeCode and boxing the result.
- //
- // The method first checks if the given object implements IConvertible. If not,
- // the only permitted conversion is from a null to TypeCode.Empty, the
- // result of which is null.
- //
- // If the object does implement IConvertible, a check is made to see if the
- // object already has the given type code, in which case the object is
- // simply returned. Otherwise, the appropriate ToXXX() is invoked on the
- // object's implementation of IConvertible.
- public static Object ChangeType(Object value, TypeCode typeCode) {
- return ChangeType(value, typeCode, Thread.CurrentThread.CurrentCulture);
- }
-
- public static Object ChangeType(Object value, TypeCode typeCode, IFormatProvider provider) {
- if (value == null && (typeCode == TypeCode.Empty || typeCode == TypeCode.String || typeCode == TypeCode.Object)) {
- return null;
- }
-
- IConvertible v = value as IConvertible;
- if (v == null) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_IConvertible"));
- }
-
- // This line is invalid for things like Enums that return a TypeCode
- // of Int32, but the object can't actually be cast to an Int32.
- // if (v.GetTypeCode() == typeCode) return value;
- switch (typeCode) {
- case TypeCode.Boolean:
- return v.ToBoolean(provider);
- case TypeCode.Char:
- return v.ToChar(provider);
- case TypeCode.SByte:
- return v.ToSByte(provider);
- case TypeCode.Byte:
- return v.ToByte(provider);
- case TypeCode.Int16:
- return v.ToInt16(provider);
- case TypeCode.UInt16:
- return v.ToUInt16(provider);
- case TypeCode.Int32:
- return v.ToInt32(provider);
- case TypeCode.UInt32:
- return v.ToUInt32(provider);
- case TypeCode.Int64:
- return v.ToInt64(provider);
- case TypeCode.UInt64:
- return v.ToUInt64(provider);
- case TypeCode.Single:
- return v.ToSingle(provider);
- case TypeCode.Double:
- return v.ToDouble(provider);
- case TypeCode.Decimal:
- return v.ToDecimal(provider);
- case TypeCode.DateTime:
- return v.ToDateTime(provider);
- case TypeCode.String:
- return v.ToString(provider);
- case TypeCode.Object:
- return value;
- case TypeCode.DBNull:
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_DBNull"));
- case TypeCode.Empty:
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_Empty"));
- default:
- throw new ArgumentException(Environment.GetResourceString("Arg_UnknownTypeCode"));
- }
- }
-
- internal static Object DefaultToType(IConvertible value, Type targetType, IFormatProvider provider) {
- Contract.Requires(value != null, "[Convert.DefaultToType]value!=null");
- if (targetType==null) {
- throw new ArgumentNullException(nameof(targetType));
- }
- Contract.EndContractBlock();
-
- RuntimeType rtTargetType = targetType as RuntimeType;
-
- if (rtTargetType != null)
- {
- if (value.GetType() == targetType)
- {
- return value;
- }
-
- if (rtTargetType == ConvertTypes[(int)TypeCode.Boolean])
- return value.ToBoolean(provider);
- if (rtTargetType == ConvertTypes[(int)TypeCode.Char])
- return value.ToChar(provider);
- if (rtTargetType == ConvertTypes[(int)TypeCode.SByte])
- return value.ToSByte(provider);
- if (rtTargetType == ConvertTypes[(int)TypeCode.Byte])
- return value.ToByte(provider);
- if (rtTargetType == ConvertTypes[(int)TypeCode.Int16])
- return value.ToInt16(provider);
- if (rtTargetType == ConvertTypes[(int)TypeCode.UInt16])
- return value.ToUInt16(provider);
- if (rtTargetType == ConvertTypes[(int)TypeCode.Int32])
- return value.ToInt32(provider);
- if (rtTargetType == ConvertTypes[(int)TypeCode.UInt32])
- return value.ToUInt32(provider);
- if (rtTargetType == ConvertTypes[(int)TypeCode.Int64])
- return value.ToInt64(provider);
- if (rtTargetType == ConvertTypes[(int)TypeCode.UInt64])
- return value.ToUInt64(provider);
- if (rtTargetType == ConvertTypes[(int)TypeCode.Single])
- return value.ToSingle(provider);
- if (rtTargetType == ConvertTypes[(int)TypeCode.Double])
- return value.ToDouble(provider);
- if (rtTargetType == ConvertTypes[(int)TypeCode.Decimal])
- return value.ToDecimal(provider);
- if (rtTargetType == ConvertTypes[(int)TypeCode.DateTime])
- return value.ToDateTime(provider);
- if (rtTargetType == ConvertTypes[(int)TypeCode.String])
- return value.ToString(provider);
- if (rtTargetType == ConvertTypes[(int)TypeCode.Object])
- return (Object)value;
- // Need to special case Enum because typecode will be underlying type, e.g. Int32
- if (rtTargetType == EnumType)
- return (Enum)value;
- if (rtTargetType == ConvertTypes[(int)TypeCode.DBNull])
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_DBNull"));
- if (rtTargetType == ConvertTypes[(int)TypeCode.Empty])
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_Empty"));
- }
-
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", value.GetType().FullName, targetType.FullName));
- }
-
- public static Object ChangeType(Object value, Type conversionType) {
- return ChangeType(value, conversionType, Thread.CurrentThread.CurrentCulture);
- }
-
- public static Object ChangeType(Object value, Type conversionType, IFormatProvider provider) {
- if( conversionType == null) {
- throw new ArgumentNullException(nameof(conversionType));
- }
- Contract.EndContractBlock();
-
- if( value == null ) {
- if(conversionType.IsValueType) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_CannotCastNullToValueType"));
- }
- return null;
- }
-
- IConvertible ic = value as IConvertible;
- if (ic == null) {
- if ( value.GetType() == conversionType) {
- return value;
- }
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_IConvertible"));
- }
-
- RuntimeType rtConversionType = conversionType as RuntimeType;
-
- if (rtConversionType==ConvertTypes[(int)TypeCode.Boolean])
- return ic.ToBoolean(provider);
- if (rtConversionType==ConvertTypes[(int)TypeCode.Char])
- return ic.ToChar(provider);
- if (rtConversionType==ConvertTypes[(int)TypeCode.SByte])
- return ic.ToSByte(provider);
- if (rtConversionType==ConvertTypes[(int)TypeCode.Byte])
- return ic.ToByte(provider);
- if (rtConversionType==ConvertTypes[(int)TypeCode.Int16])
- return ic.ToInt16(provider);
- if (rtConversionType==ConvertTypes[(int)TypeCode.UInt16])
- return ic.ToUInt16(provider);
- if (rtConversionType==ConvertTypes[(int)TypeCode.Int32])
- return ic.ToInt32(provider);
- if (rtConversionType==ConvertTypes[(int)TypeCode.UInt32])
- return ic.ToUInt32(provider);
- if (rtConversionType==ConvertTypes[(int)TypeCode.Int64])
- return ic.ToInt64(provider);
- if (rtConversionType==ConvertTypes[(int)TypeCode.UInt64])
- return ic.ToUInt64(provider);
- if (rtConversionType==ConvertTypes[(int)TypeCode.Single])
- return ic.ToSingle(provider);
- if (rtConversionType==ConvertTypes[(int)TypeCode.Double])
- return ic.ToDouble(provider);
- if (rtConversionType==ConvertTypes[(int)TypeCode.Decimal])
- return ic.ToDecimal(provider);
- if (rtConversionType==ConvertTypes[(int)TypeCode.DateTime])
- return ic.ToDateTime(provider);
- if (rtConversionType==ConvertTypes[(int)TypeCode.String])
- return ic.ToString(provider);
- if (rtConversionType==ConvertTypes[(int)TypeCode.Object])
- return (Object)value;
-
- return ic.ToType(conversionType, provider);
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static void ThrowCharOverflowException() { throw new OverflowException(Environment.GetResourceString("Overflow_Char")); }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static void ThrowByteOverflowException() { throw new OverflowException(Environment.GetResourceString("Overflow_Byte")); }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static void ThrowSByteOverflowException() { throw new OverflowException(Environment.GetResourceString("Overflow_SByte")); }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static void ThrowInt16OverflowException() { throw new OverflowException(Environment.GetResourceString("Overflow_Int16")); }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static void ThrowUInt16OverflowException() { throw new OverflowException(Environment.GetResourceString("Overflow_UInt16")); }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static void ThrowInt32OverflowException() { throw new OverflowException(Environment.GetResourceString("Overflow_Int32")); }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static void ThrowUInt32OverflowException() { throw new OverflowException(Environment.GetResourceString("Overflow_UInt32")); }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static void ThrowInt64OverflowException() { throw new OverflowException(Environment.GetResourceString("Overflow_Int64")); }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static void ThrowUInt64OverflowException() { throw new OverflowException(Environment.GetResourceString("Overflow_UInt64")); }
-
- // Conversions to Boolean
- public static bool ToBoolean(Object value) {
- return value == null? false: ((IConvertible)value).ToBoolean(null);
- }
-
- public static bool ToBoolean(Object value, IFormatProvider provider) {
- return value == null? false: ((IConvertible)value).ToBoolean(provider);
- }
-
-
- public static bool ToBoolean(bool value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static bool ToBoolean(sbyte value) {
- return value != 0;
- }
-
- // To be consistent with IConvertible in the base data types else we get different semantics
- // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
- public static bool ToBoolean(char value) {
- return ((IConvertible)value).ToBoolean(null);
- }
-
- public static bool ToBoolean(byte value) {
- return value != 0;
- }
-
-
- public static bool ToBoolean(short value) {
- return value != 0;
- }
-
- [CLSCompliant(false)]
- public static bool ToBoolean(ushort value) {
- return value != 0;
- }
-
- public static bool ToBoolean(int value) {
- return value != 0;
- }
-
- [CLSCompliant(false)]
- public static bool ToBoolean(uint value) {
- return value != 0;
- }
-
- public static bool ToBoolean(long value) {
- return value != 0;
- }
-
- [CLSCompliant(false)]
- public static bool ToBoolean(ulong value) {
- return value != 0;
- }
-
- public static bool ToBoolean(String value) {
- if (value == null)
- return false;
- return Boolean.Parse(value);
- }
-
- public static bool ToBoolean(String value, IFormatProvider provider) {
- if (value == null)
- return false;
- return Boolean.Parse(value);
- }
-
- public static bool ToBoolean(float value)
- {
- return value != 0;
- }
-
- public static bool ToBoolean(double value)
- {
- return value != 0;
- }
-
- public static bool ToBoolean(decimal value)
- {
- return value != 0;
- }
-
- public static bool ToBoolean(DateTime value)
- {
- return ((IConvertible)value).ToBoolean(null);
- }
-
- // Disallowed conversions to Boolean
- // public static bool ToBoolean(TimeSpan value)
-
- // Conversions to Char
-
-
- public static char ToChar(object value) {
- return value == null? (char)0: ((IConvertible)value).ToChar(null);
- }
-
- public static char ToChar(object value, IFormatProvider provider) {
- return value == null? (char)0: ((IConvertible)value).ToChar(provider);
- }
-
- public static char ToChar(bool value) {
- return ((IConvertible)value).ToChar(null);
- }
-
- public static char ToChar(char value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static char ToChar(sbyte value) {
- if (value < 0) ThrowCharOverflowException();
- Contract.EndContractBlock();
- return (char)value;
- }
-
- public static char ToChar(byte value) {
- return (char)value;
- }
-
- public static char ToChar(short value) {
- if (value < 0) ThrowCharOverflowException();
- Contract.EndContractBlock();
- return (char)value;
- }
-
- [CLSCompliant(false)]
- public static char ToChar(ushort value) {
- return (char)value;
- }
-
- public static char ToChar(int value) {
- if (value < 0 || value > Char.MaxValue) ThrowCharOverflowException();
- Contract.EndContractBlock();
- return (char)value;
- }
-
- [CLSCompliant(false)]
- public static char ToChar(uint value) {
- if (value > Char.MaxValue) ThrowCharOverflowException();
- Contract.EndContractBlock();
- return (char)value;
- }
-
- public static char ToChar(long value) {
- if (value < 0 || value > Char.MaxValue) ThrowCharOverflowException();
- Contract.EndContractBlock();
- return (char)value;
- }
-
- [CLSCompliant(false)]
- public static char ToChar(ulong value) {
- if (value > Char.MaxValue) ThrowCharOverflowException();
- Contract.EndContractBlock();
- return (char)value;
- }
-
- //
- // @VariantSwitch
- // Remove FormatExceptions;
- //
- public static char ToChar(String value) {
- return ToChar(value, null);
- }
-
- public static char ToChar(String value, IFormatProvider provider) {
- if (value == null)
- throw new ArgumentNullException(nameof(value));
- Contract.EndContractBlock();
-
- if (value.Length != 1)
- throw new FormatException(Environment.GetResourceString(ResId.Format_NeedSingleChar));
-
- return value[0];
- }
-
- // To be consistent with IConvertible in the base data types else we get different semantics
- // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
- public static char ToChar(float value)
- {
- return ((IConvertible)value).ToChar(null);
- }
-
- // To be consistent with IConvertible in the base data types else we get different semantics
- // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
- public static char ToChar(double value)
- {
- return ((IConvertible)value).ToChar(null);
- }
-
- // To be consistent with IConvertible in the base data types else we get different semantics
- // with widening operations. Without this operator this widen succeeds,with this API the widening throws.
- public static char ToChar(decimal value)
- {
- return ((IConvertible)value).ToChar(null);
- }
-
- public static char ToChar(DateTime value)
- {
- return ((IConvertible)value).ToChar(null);
- }
-
-
- // Disallowed conversions to Char
- // public static char ToChar(TimeSpan value)
-
- // Conversions to SByte
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(object value) {
- return value == null? (sbyte)0: ((IConvertible)value).ToSByte(null);
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(object value, IFormatProvider provider) {
- return value == null? (sbyte)0: ((IConvertible)value).ToSByte(provider);
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(bool value) {
- return value? (sbyte)Boolean.True: (sbyte)Boolean.False;
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(sbyte value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(char value) {
- if (value > SByte.MaxValue) ThrowSByteOverflowException();
- Contract.EndContractBlock();
- return (sbyte)value;
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(byte value) {
- if (value > SByte.MaxValue) ThrowSByteOverflowException();
- Contract.EndContractBlock();
- return (sbyte)value;
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(short value) {
- if (value < SByte.MinValue || value > SByte.MaxValue) ThrowSByteOverflowException();
- Contract.EndContractBlock();
- return (sbyte)value;
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(ushort value) {
- if (value > SByte.MaxValue) ThrowSByteOverflowException();
- Contract.EndContractBlock();
- return (sbyte)value;
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(int value) {
- if (value < SByte.MinValue || value > SByte.MaxValue) ThrowSByteOverflowException();
- Contract.EndContractBlock();
- return (sbyte)value;
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(uint value) {
- if (value > SByte.MaxValue) ThrowSByteOverflowException();
- Contract.EndContractBlock();
- return (sbyte)value;
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(long value) {
- if (value < SByte.MinValue || value > SByte.MaxValue) ThrowSByteOverflowException();
- Contract.EndContractBlock();
- return (sbyte)value;
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(ulong value) {
- if (value > (ulong)SByte.MaxValue) ThrowSByteOverflowException();
- Contract.EndContractBlock();
- return (sbyte)value;
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(float value) {
- return ToSByte((double)value);
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(double value) {
- return ToSByte(ToInt32(value));
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(decimal value) {
- return Decimal.ToSByte(Decimal.Round(value, 0));
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(String value) {
- if (value == null)
- return 0;
- return SByte.Parse(value, CultureInfo.CurrentCulture);
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(String value, IFormatProvider provider) {
- return SByte.Parse(value, NumberStyles.Integer, provider);
- }
-
- [CLSCompliant(false)]
- public static sbyte ToSByte(DateTime value)
- {
- return ((IConvertible)value).ToSByte(null);
- }
-
- // Disallowed conversions to SByte
- // public static sbyte ToSByte(TimeSpan value)
-
- // Conversions to Byte
-
- public static byte ToByte(object value) {
- return value == null? (byte)0: ((IConvertible)value).ToByte(null);
- }
-
- public static byte ToByte(object value, IFormatProvider provider) {
- return value == null? (byte)0: ((IConvertible)value).ToByte(provider);
- }
-
- public static byte ToByte(bool value) {
- return value? (byte)Boolean.True: (byte)Boolean.False;
- }
-
- public static byte ToByte(byte value) {
- return value;
- }
-
- public static byte ToByte(char value) {
- if (value > Byte.MaxValue) ThrowByteOverflowException();
- Contract.EndContractBlock();
- return (byte)value;
- }
-
- [CLSCompliant(false)]
- public static byte ToByte(sbyte value) {
- if (value < Byte.MinValue) ThrowByteOverflowException();
- Contract.EndContractBlock();
- return (byte)value;
- }
-
- public static byte ToByte(short value) {
- if (value < Byte.MinValue || value > Byte.MaxValue) ThrowByteOverflowException();
- Contract.EndContractBlock();
- return (byte)value;
- }
-
- [CLSCompliant(false)]
- public static byte ToByte(ushort value) {
- if (value > Byte.MaxValue) ThrowByteOverflowException();
- Contract.EndContractBlock();
- return (byte)value;
- }
-
- public static byte ToByte(int value) {
- if (value < Byte.MinValue || value > Byte.MaxValue) ThrowByteOverflowException();
- Contract.EndContractBlock();
- return (byte)value;
- }
-
- [CLSCompliant(false)]
- public static byte ToByte(uint value) {
- if (value > Byte.MaxValue) ThrowByteOverflowException();
- Contract.EndContractBlock();
- return (byte)value;
- }
-
- public static byte ToByte(long value) {
- if (value < Byte.MinValue || value > Byte.MaxValue) ThrowByteOverflowException();
- Contract.EndContractBlock();
- return (byte)value;
- }
-
- [CLSCompliant(false)]
- public static byte ToByte(ulong value) {
- if (value > Byte.MaxValue) ThrowByteOverflowException();
- Contract.EndContractBlock();
- return (byte)value;
- }
-
- public static byte ToByte(float value) {
- return ToByte((double)value);
- }
-
- public static byte ToByte(double value) {
- return ToByte(ToInt32(value));
- }
-
- public static byte ToByte(decimal value) {
- return Decimal.ToByte(Decimal.Round(value, 0));
- }
-
- public static byte ToByte(String value) {
- if (value == null)
- return 0;
- return Byte.Parse(value, CultureInfo.CurrentCulture);
- }
-
- public static byte ToByte(String value, IFormatProvider provider) {
- if (value == null)
- return 0;
- return Byte.Parse(value, NumberStyles.Integer, provider);
- }
-
- public static byte ToByte(DateTime value)
- {
- return ((IConvertible)value).ToByte(null);
- }
-
-
- // Disallowed conversions to Byte
- // public static byte ToByte(TimeSpan value)
-
- // Conversions to Int16
-
- public static short ToInt16(object value) {
- return value == null? (short)0: ((IConvertible)value).ToInt16(null);
- }
-
- public static short ToInt16(object value, IFormatProvider provider) {
- return value == null? (short)0: ((IConvertible)value).ToInt16(provider);
- }
-
- public static short ToInt16(bool value) {
- return value? (short)Boolean.True: (short)Boolean.False;
- }
-
- public static short ToInt16(char value) {
- if (value > Int16.MaxValue) ThrowInt16OverflowException();
- Contract.EndContractBlock();
- return (short)value;
- }
-
- [CLSCompliant(false)]
- public static short ToInt16(sbyte value) {
- return value;
- }
-
- public static short ToInt16(byte value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static short ToInt16(ushort value) {
- if (value > Int16.MaxValue) ThrowInt16OverflowException();
- Contract.EndContractBlock();
- return (short)value;
- }
-
- public static short ToInt16(int value) {
- if (value < Int16.MinValue || value > Int16.MaxValue) ThrowInt16OverflowException();
- Contract.EndContractBlock();
- return (short)value;
- }
-
- [CLSCompliant(false)]
- public static short ToInt16(uint value) {
- if (value > Int16.MaxValue) ThrowInt16OverflowException();
- Contract.EndContractBlock();
- return (short)value;
- }
-
- public static short ToInt16(short value) {
- return value;
- }
-
- public static short ToInt16(long value) {
- if (value < Int16.MinValue || value > Int16.MaxValue) ThrowInt16OverflowException();
- Contract.EndContractBlock();
- return (short)value;
- }
-
- [CLSCompliant(false)]
- public static short ToInt16(ulong value) {
- if (value > (ulong)Int16.MaxValue) ThrowInt16OverflowException();
- Contract.EndContractBlock();
- return (short)value;
- }
-
- public static short ToInt16(float value) {
- return ToInt16((double)value);
- }
-
- public static short ToInt16(double value) {
- return ToInt16(ToInt32(value));
- }
-
- public static short ToInt16(decimal value) {
- return Decimal.ToInt16(Decimal.Round(value, 0));
- }
-
- public static short ToInt16(String value) {
- if (value == null)
- return 0;
- return Int16.Parse(value, CultureInfo.CurrentCulture);
- }
-
- public static short ToInt16(String value, IFormatProvider provider) {
- if (value == null)
- return 0;
- return Int16.Parse(value, NumberStyles.Integer, provider);
- }
-
- public static short ToInt16(DateTime value)
- {
- return ((IConvertible)value).ToInt16(null);
- }
-
-
- // Disallowed conversions to Int16
- // public static short ToInt16(TimeSpan value)
-
- // Conversions to UInt16
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(object value) {
- return value == null? (ushort)0: ((IConvertible)value).ToUInt16(null);
- }
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(object value, IFormatProvider provider) {
- return value == null? (ushort)0: ((IConvertible)value).ToUInt16(provider);
- }
-
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(bool value) {
- return value? (ushort)Boolean.True: (ushort)Boolean.False;
- }
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(char value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(sbyte value) {
- if (value < 0) ThrowUInt16OverflowException();
- Contract.EndContractBlock();
- return (ushort)value;
- }
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(byte value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(short value) {
- if (value < 0) ThrowUInt16OverflowException();
- Contract.EndContractBlock();
- return (ushort)value;
- }
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(int value) {
- if (value < 0 || value > UInt16.MaxValue) ThrowUInt16OverflowException();
- Contract.EndContractBlock();
- return (ushort)value;
- }
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(ushort value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(uint value) {
- if (value > UInt16.MaxValue) ThrowUInt16OverflowException();
- Contract.EndContractBlock();
- return (ushort)value;
- }
-
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(long value) {
- if (value < 0 || value > UInt16.MaxValue) ThrowUInt16OverflowException();
- Contract.EndContractBlock();
- return (ushort)value;
- }
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(ulong value) {
- if (value > UInt16.MaxValue) ThrowUInt16OverflowException();
- Contract.EndContractBlock();
- return (ushort)value;
- }
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(float value) {
- return ToUInt16((double)value);
- }
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(double value) {
- return ToUInt16(ToInt32(value));
- }
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(decimal value) {
- return Decimal.ToUInt16(Decimal.Round(value, 0));
- }
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(String value) {
- if (value == null)
- return 0;
- return UInt16.Parse(value, CultureInfo.CurrentCulture);
- }
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(String value, IFormatProvider provider) {
- if (value == null)
- return 0;
- return UInt16.Parse(value, NumberStyles.Integer, provider);
- }
-
- [CLSCompliant(false)]
- public static ushort ToUInt16(DateTime value)
- {
- return ((IConvertible)value).ToUInt16(null);
- }
-
- // Disallowed conversions to UInt16
- // public static ushort ToUInt16(TimeSpan value)
-
- // Conversions to Int32
-
- public static int ToInt32(object value) {
- return value == null? 0: ((IConvertible)value).ToInt32(null);
- }
-
- public static int ToInt32(object value, IFormatProvider provider) {
- return value == null? 0: ((IConvertible)value).ToInt32(provider);
- }
-
-
- public static int ToInt32(bool value) {
- return value? Boolean.True: Boolean.False;
- }
-
- public static int ToInt32(char value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static int ToInt32(sbyte value) {
- return value;
- }
-
- public static int ToInt32(byte value) {
- return value;
- }
-
- public static int ToInt32(short value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static int ToInt32(ushort value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static int ToInt32(uint value) {
- if (value > Int32.MaxValue) ThrowInt32OverflowException();
- Contract.EndContractBlock();
- return (int)value;
- }
-
- public static int ToInt32(int value) {
- return value;
- }
-
- public static int ToInt32(long value) {
- if (value < Int32.MinValue || value > Int32.MaxValue) ThrowInt32OverflowException();
- Contract.EndContractBlock();
- return (int)value;
- }
-
- [CLSCompliant(false)]
- public static int ToInt32(ulong value) {
- if (value > Int32.MaxValue) ThrowInt32OverflowException();
- Contract.EndContractBlock();
- return (int)value;
- }
-
- public static int ToInt32(float value) {
- return ToInt32((double)value);
- }
-
- public static int ToInt32(double value) {
- if (value >= 0) {
- if (value < 2147483647.5) {
- int result = (int)value;
- double dif = value - result;
- if (dif > 0.5 || dif == 0.5 && (result & 1) != 0) result++;
- return result;
- }
- }
- else {
- if (value >= -2147483648.5) {
- int result = (int)value;
- double dif = value - result;
- if (dif < -0.5 || dif == -0.5 && (result & 1) != 0) result--;
- return result;
- }
- }
- throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
- }
-
- public static int ToInt32(decimal value) {
- return Decimal.FCallToInt32(value);
- }
-
- public static int ToInt32(String value) {
- if (value == null)
- return 0;
- return Int32.Parse(value, CultureInfo.CurrentCulture);
- }
-
- public static int ToInt32(String value, IFormatProvider provider) {
- if (value == null)
- return 0;
- return Int32.Parse(value, NumberStyles.Integer, provider);
- }
-
- public static int ToInt32(DateTime value)
- {
- return ((IConvertible)value).ToInt32(null);
- }
-
-
- // Disallowed conversions to Int32
- // public static int ToInt32(TimeSpan value)
-
- // Conversions to UInt32
-
- [CLSCompliant(false)]
- public static uint ToUInt32(object value) {
- return value == null? 0: ((IConvertible)value).ToUInt32(null);
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(object value, IFormatProvider provider) {
- return value == null? 0: ((IConvertible)value).ToUInt32(provider);
- }
-
-
- [CLSCompliant(false)]
- public static uint ToUInt32(bool value) {
- return value? (uint)Boolean.True: (uint)Boolean.False;
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(char value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(sbyte value) {
- if (value < 0) ThrowUInt32OverflowException();
- Contract.EndContractBlock();
- return (uint)value;
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(byte value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(short value) {
- if (value < 0) ThrowUInt32OverflowException();
- Contract.EndContractBlock();
- return (uint)value;
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(ushort value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(int value) {
- if (value < 0) ThrowUInt32OverflowException();
- Contract.EndContractBlock();
- return (uint)value;
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(uint value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(long value) {
- if (value < 0 || value > UInt32.MaxValue) ThrowUInt32OverflowException();
- Contract.EndContractBlock();
- return (uint)value;
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(ulong value) {
- if (value > UInt32.MaxValue) ThrowUInt32OverflowException();
- Contract.EndContractBlock();
- return (uint)value;
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(float value) {
- return ToUInt32((double)value);
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(double value) {
- if (value >= -0.5 && value < 4294967295.5) {
- uint result = (uint)value;
- double dif = value - result;
- if (dif > 0.5 || dif == 0.5 && (result & 1) != 0) result++;
- return result;
- }
- throw new OverflowException(Environment.GetResourceString("Overflow_UInt32"));
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(decimal value) {
- return Decimal.ToUInt32(Decimal.Round(value, 0));
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(String value) {
- if (value == null)
- return 0;
- return UInt32.Parse(value, CultureInfo.CurrentCulture);
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(String value, IFormatProvider provider) {
- if (value == null)
- return 0;
- return UInt32.Parse(value, NumberStyles.Integer, provider);
- }
-
- [CLSCompliant(false)]
- public static uint ToUInt32(DateTime value)
- {
- return ((IConvertible)value).ToUInt32(null);
- }
-
- // Disallowed conversions to UInt32
- // public static uint ToUInt32(TimeSpan value)
-
- // Conversions to Int64
-
- public static long ToInt64(object value) {
- return value == null? 0: ((IConvertible)value).ToInt64(null);
- }
-
- public static long ToInt64(object value, IFormatProvider provider) {
- return value == null? 0: ((IConvertible)value).ToInt64(provider);
- }
-
-
- public static long ToInt64(bool value) {
- return value? Boolean.True: Boolean.False;
- }
-
- public static long ToInt64(char value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static long ToInt64(sbyte value) {
- return value;
- }
-
- public static long ToInt64(byte value) {
- return value;
- }
-
- public static long ToInt64(short value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static long ToInt64(ushort value) {
- return value;
- }
-
- public static long ToInt64(int value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static long ToInt64(uint value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static long ToInt64(ulong value) {
- if (value > Int64.MaxValue) ThrowInt64OverflowException();
- Contract.EndContractBlock();
- return (long)value;
- }
-
- public static long ToInt64(long value) {
- return value;
- }
-
-
- public static long ToInt64(float value) {
- return ToInt64((double)value);
- }
-
- public static long ToInt64(double value) {
- return checked((long)Math.Round(value));
- }
-
- public static long ToInt64(decimal value) {
- return Decimal.ToInt64(Decimal.Round(value, 0));
- }
-
- public static long ToInt64(string value) {
- if (value == null)
- return 0;
- return Int64.Parse(value, CultureInfo.CurrentCulture);
- }
-
- public static long ToInt64(String value, IFormatProvider provider) {
- if (value == null)
- return 0;
- return Int64.Parse(value, NumberStyles.Integer, provider);
- }
-
- public static long ToInt64(DateTime value)
- {
- return ((IConvertible)value).ToInt64(null);
- }
-
- // Disallowed conversions to Int64
- // public static long ToInt64(TimeSpan value)
-
- // Conversions to UInt64
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(object value) {
- return value == null? 0: ((IConvertible)value).ToUInt64(null);
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(object value, IFormatProvider provider) {
- return value == null? 0: ((IConvertible)value).ToUInt64(provider);
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(bool value) {
- return value? (ulong)Boolean.True: (ulong)Boolean.False;
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(char value) {
- return value;
- }
-
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(sbyte value) {
- if (value < 0) ThrowUInt64OverflowException();
- Contract.EndContractBlock();
- return (ulong)value;
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(byte value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(short value) {
- if (value < 0) ThrowUInt64OverflowException();
- Contract.EndContractBlock();
- return (ulong)value;
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(ushort value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(int value) {
- if (value < 0) ThrowUInt64OverflowException();
- Contract.EndContractBlock();
- return (ulong)value;
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(uint value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(long value) {
- if (value < 0) ThrowUInt64OverflowException();
- Contract.EndContractBlock();
- return (ulong)value;
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(UInt64 value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(float value) {
- return ToUInt64((double)value);
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(double value) {
- return checked((ulong)Math.Round(value));
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(decimal value) {
- return Decimal.ToUInt64(Decimal.Round(value, 0));
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(String value) {
- if (value == null)
- return 0;
- return UInt64.Parse(value, CultureInfo.CurrentCulture);
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(String value, IFormatProvider provider) {
- if (value == null)
- return 0;
- return UInt64.Parse(value, NumberStyles.Integer, provider);
- }
-
- [CLSCompliant(false)]
- public static ulong ToUInt64(DateTime value)
- {
- return ((IConvertible)value).ToUInt64(null);
- }
-
- // Disallowed conversions to UInt64
- // public static ulong ToUInt64(TimeSpan value)
-
- // Conversions to Single
-
- public static float ToSingle(object value) {
- return value == null? 0: ((IConvertible)value).ToSingle(null);
- }
-
- public static float ToSingle(object value, IFormatProvider provider) {
- return value == null? 0: ((IConvertible)value).ToSingle(provider);
- }
-
- [CLSCompliant(false)]
- public static float ToSingle(sbyte value) {
- return value;
- }
-
- public static float ToSingle(byte value) {
- return value;
- }
-
- public static float ToSingle(char value) {
- return ((IConvertible)value).ToSingle(null);
- }
-
- public static float ToSingle(short value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static float ToSingle(ushort value) {
- return value;
- }
-
- public static float ToSingle(int value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static float ToSingle(uint value) {
- return value;
- }
-
- public static float ToSingle(long value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static float ToSingle(ulong value) {
- return value;
- }
-
- public static float ToSingle(float value) {
- return value;
- }
-
- public static float ToSingle(double value) {
- return (float)value;
- }
-
- public static float ToSingle(decimal value) {
- return (float)value;
- }
-
- public static float ToSingle(String value) {
- if (value == null)
- return 0;
- return Single.Parse(value, CultureInfo.CurrentCulture);
- }
-
- public static float ToSingle(String value, IFormatProvider provider) {
- if (value == null)
- return 0;
- return Single.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);
- }
-
-
- public static float ToSingle(bool value)
- {
- return value? Boolean.True: Boolean.False;
- }
-
- public static float ToSingle(DateTime value)
- {
- return ((IConvertible)value).ToSingle(null);
- }
-
- // Disallowed conversions to Single
- // public static float ToSingle(TimeSpan value)
-
- // Conversions to Double
-
- public static double ToDouble(object value) {
- return value == null? 0: ((IConvertible)value).ToDouble(null);
- }
-
- public static double ToDouble(object value, IFormatProvider provider) {
- return value == null? 0: ((IConvertible)value).ToDouble(provider);
- }
-
-
- [CLSCompliant(false)]
- public static double ToDouble(sbyte value) {
- return value;
- }
-
- public static double ToDouble(byte value) {
- return value;
- }
-
- public static double ToDouble(short value) {
- return value;
- }
-
- public static double ToDouble(char value) {
- return ((IConvertible)value).ToDouble(null);
- }
-
- [CLSCompliant(false)]
- public static double ToDouble(ushort value) {
- return value;
- }
-
- public static double ToDouble(int value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static double ToDouble(uint value) {
- return value;
- }
-
- public static double ToDouble(long value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static double ToDouble(ulong value) {
- return value;
- }
-
- public static double ToDouble(float value) {
- return value;
- }
-
- public static double ToDouble(double value) {
- return value;
- }
-
- public static double ToDouble(decimal value) {
- return (double)value;
- }
-
- public static double ToDouble(String value) {
- if (value == null)
- return 0;
- return Double.Parse(value, CultureInfo.CurrentCulture);
- }
-
- public static double ToDouble(String value, IFormatProvider provider) {
- if (value == null)
- return 0;
- return Double.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);
- }
-
- public static double ToDouble(bool value) {
- return value? Boolean.True: Boolean.False;
- }
-
- public static double ToDouble(DateTime value)
- {
- return ((IConvertible)value).ToDouble(null);
- }
-
- // Disallowed conversions to Double
- // public static double ToDouble(TimeSpan value)
-
- // Conversions to Decimal
-
- public static decimal ToDecimal(object value) {
- return value == null? 0: ((IConvertible)value).ToDecimal(null);
- }
-
- public static decimal ToDecimal(object value, IFormatProvider provider) {
- return value == null? 0: ((IConvertible)value).ToDecimal(provider);
- }
-
- [CLSCompliant(false)]
- public static decimal ToDecimal(sbyte value) {
- return value;
- }
-
- public static decimal ToDecimal(byte value) {
- return value;
- }
-
- public static decimal ToDecimal(char value) {
- return ((IConvertible)value).ToDecimal(null);
- }
-
- public static decimal ToDecimal(short value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static decimal ToDecimal(ushort value) {
- return value;
- }
-
- public static decimal ToDecimal(int value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static decimal ToDecimal(uint value) {
- return value;
- }
-
- public static decimal ToDecimal(long value) {
- return value;
- }
-
- [CLSCompliant(false)]
- public static decimal ToDecimal(ulong value) {
- return value;
- }
-
- public static decimal ToDecimal(float value) {
- return (decimal)value;
- }
-
- public static decimal ToDecimal(double value) {
- return (decimal)value;
- }
-
- public static decimal ToDecimal(String value) {
- if (value == null)
- return 0m;
- return Decimal.Parse(value, CultureInfo.CurrentCulture);
- }
-
- public static Decimal ToDecimal(String value, IFormatProvider provider) {
- if (value == null)
- return 0m;
- return Decimal.Parse(value, NumberStyles.Number, provider);
- }
-
- public static decimal ToDecimal(decimal value) {
- return value;
- }
-
- public static decimal ToDecimal(bool value) {
- return value? Boolean.True: Boolean.False;
- }
-
- public static decimal ToDecimal(DateTime value)
- {
- return ((IConvertible)value).ToDecimal(null);
- }
-
- // Disallowed conversions to Decimal
- // public static decimal ToDecimal(TimeSpan value)
-
- // Conversions to DateTime
-
- public static DateTime ToDateTime(DateTime value) {
- return value;
- }
-
- public static DateTime ToDateTime(object value) {
- return value == null? DateTime.MinValue: ((IConvertible)value).ToDateTime(null);
- }
-
- public static DateTime ToDateTime(object value, IFormatProvider provider) {
- return value == null? DateTime.MinValue: ((IConvertible)value).ToDateTime(provider);
- }
-
- public static DateTime ToDateTime(String value) {
- if (value == null)
- return new DateTime(0);
- return DateTime.Parse(value, CultureInfo.CurrentCulture);
- }
-
- public static DateTime ToDateTime(String value, IFormatProvider provider) {
- if (value == null)
- return new DateTime(0);
- return DateTime.Parse(value, provider);
- }
-
- [CLSCompliant(false)]
- public static DateTime ToDateTime(sbyte value) {
- return ((IConvertible)value).ToDateTime(null);
- }
-
- public static DateTime ToDateTime(byte value) {
- return ((IConvertible)value).ToDateTime(null);
- }
-
- public static DateTime ToDateTime(short value) {
- return ((IConvertible)value).ToDateTime(null);
- }
-
- [CLSCompliant(false)]
- public static DateTime ToDateTime(ushort value) {
- return ((IConvertible)value).ToDateTime(null);
- }
-
- public static DateTime ToDateTime(int value) {
- return ((IConvertible)value).ToDateTime(null);
- }
-
- [CLSCompliant(false)]
- public static DateTime ToDateTime(uint value) {
- return ((IConvertible)value).ToDateTime(null);
- }
-
- public static DateTime ToDateTime(long value) {
- return ((IConvertible)value).ToDateTime(null);
- }
-
- [CLSCompliant(false)]
- public static DateTime ToDateTime(ulong value) {
- return ((IConvertible)value).ToDateTime(null);
- }
-
- public static DateTime ToDateTime(bool value) {
- return ((IConvertible)value).ToDateTime(null);
- }
-
- public static DateTime ToDateTime(char value) {
- return ((IConvertible)value).ToDateTime(null);
- }
-
- public static DateTime ToDateTime(float value) {
- return ((IConvertible)value).ToDateTime(null);
- }
-
- public static DateTime ToDateTime(double value) {
- return ((IConvertible)value).ToDateTime(null);
- }
-
- public static DateTime ToDateTime(decimal value) {
- return ((IConvertible)value).ToDateTime(null);
- }
-
- // Disallowed conversions to DateTime
- // public static DateTime ToDateTime(TimeSpan value)
-
- // Conversions to String
-
- public static string ToString(Object value) {
- return ToString(value,null);
- }
-
- public static string ToString(Object value, IFormatProvider provider) {
- IConvertible ic = value as IConvertible;
- if (ic != null)
- return ic.ToString(provider);
- IFormattable formattable = value as IFormattable;
- if (formattable != null)
- return formattable.ToString(null, provider);
- return value == null? String.Empty: value.ToString();
- }
-
- public static string ToString(bool value) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString();
- }
-
- public static string ToString(bool value, IFormatProvider provider) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(provider);
- }
-
- public static string ToString(char value) {
- Contract.Ensures(Contract.Result<string>() != null);
- return Char.ToString(value);
- }
-
- public static string ToString(char value, IFormatProvider provider) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(provider);
- }
-
- [CLSCompliant(false)]
- public static string ToString(sbyte value) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(CultureInfo.CurrentCulture);
- }
-
- [CLSCompliant(false)]
- public static string ToString(sbyte value, IFormatProvider provider) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(provider);
- }
-
- public static string ToString(byte value) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(CultureInfo.CurrentCulture);
- }
-
- public static string ToString(byte value, IFormatProvider provider) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(provider);
- }
-
- public static string ToString(short value) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(CultureInfo.CurrentCulture);
- }
-
- public static string ToString(short value, IFormatProvider provider) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(provider);
- }
-
- [CLSCompliant(false)]
- public static string ToString(ushort value) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(CultureInfo.CurrentCulture);
- }
-
- [CLSCompliant(false)]
- public static string ToString(ushort value, IFormatProvider provider) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(provider);
- }
-
- public static string ToString(int value) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(CultureInfo.CurrentCulture);
- }
-
- public static string ToString(int value, IFormatProvider provider) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(provider);
- }
-
- [CLSCompliant(false)]
- public static string ToString(uint value) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(CultureInfo.CurrentCulture);
- }
-
- [CLSCompliant(false)]
- public static string ToString(uint value, IFormatProvider provider) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(provider);
- }
-
- public static string ToString(long value) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(CultureInfo.CurrentCulture);
- }
-
- public static string ToString(long value, IFormatProvider provider) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(provider);
- }
-
- [CLSCompliant(false)]
- public static string ToString(ulong value) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(CultureInfo.CurrentCulture);
- }
-
- [CLSCompliant(false)]
- public static string ToString(ulong value, IFormatProvider provider) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(provider);
- }
-
- public static string ToString(float value) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(CultureInfo.CurrentCulture);
- }
-
- public static string ToString(float value, IFormatProvider provider) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(provider);
- }
-
- public static string ToString(double value) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(CultureInfo.CurrentCulture);
- }
-
- public static string ToString(double value, IFormatProvider provider) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(provider);
- }
-
- public static string ToString(decimal value) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(CultureInfo.CurrentCulture);
- }
-
- public static string ToString(Decimal value, IFormatProvider provider) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(provider);
- }
-
- public static string ToString(DateTime value) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString();
- }
-
- public static string ToString(DateTime value, IFormatProvider provider) {
- Contract.Ensures(Contract.Result<string>() != null);
- return value.ToString(provider);
- }
-
- public static String ToString(String value) {
- Contract.Ensures(Contract.Result<string>() == value); // We were always skipping the null check here.
- return value;
- }
-
- public static String ToString(String value,IFormatProvider provider) {
- Contract.Ensures(Contract.Result<string>() == value); // We were always skipping the null check here.
- return value; // avoid the null check
- }
-
-
- //
- // Conversions which understand Base XXX numbers.
- //
- // Parses value in base base. base can only
- // be 2, 8, 10, or 16. If base is 16, the number may be preceded
- // by 0x; any other leading or trailing characters cause an error.
- //
- public static byte ToByte (String value, int fromBase) {
- if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
- }
- Contract.EndContractBlock();
- int r = ParseNumbers.StringToInt(value,fromBase,ParseNumbers.IsTight | ParseNumbers.TreatAsUnsigned);
- if (r < Byte.MinValue || r > Byte.MaxValue)
- ThrowByteOverflowException();
- return (byte) r;
- }
-
- // Parses value in base fromBase. fromBase can only
- // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
- // by 0x; any other leading or trailing characters cause an error.
- //
- [CLSCompliant(false)]
- public static sbyte ToSByte (String value, int fromBase) {
- if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
- }
- Contract.EndContractBlock();
- int r = ParseNumbers.StringToInt(value,fromBase,ParseNumbers.IsTight | ParseNumbers.TreatAsI1);
- if (fromBase != 10 && r <= Byte.MaxValue)
- return (sbyte)r;
-
- if (r < SByte.MinValue || r > SByte.MaxValue)
- ThrowSByteOverflowException();
- return (sbyte) r;
- }
-
- // Parses value in base fromBase. fromBase can only
- // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
- // by 0x; any other leading or trailing characters cause an error.
- //
- public static short ToInt16 (String value, int fromBase) {
- if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
- }
- Contract.EndContractBlock();
- int r = ParseNumbers.StringToInt(value,fromBase,ParseNumbers.IsTight | ParseNumbers.TreatAsI2);
- if (fromBase != 10 && r <= UInt16.MaxValue)
- return (short)r;
-
- if (r < Int16.MinValue || r > Int16.MaxValue)
- ThrowInt16OverflowException();
- return (short) r;
- }
-
- // Parses value in base fromBase. fromBase can only
- // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
- // by 0x; any other leading or trailing characters cause an error.
- //
- [CLSCompliant(false)]
- public static ushort ToUInt16 (String value, int fromBase) {
- if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
- }
- Contract.EndContractBlock();
- int r = ParseNumbers.StringToInt(value,fromBase,ParseNumbers.IsTight | ParseNumbers.TreatAsUnsigned);
- if (r < UInt16.MinValue || r > UInt16.MaxValue)
- ThrowUInt16OverflowException();
- return (ushort) r;
- }
-
- // Parses value in base fromBase. fromBase can only
- // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
- // by 0x; any other leading or trailing characters cause an error.
- //
- public static int ToInt32 (String value, int fromBase) {
- if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
- }
- Contract.EndContractBlock();
- return ParseNumbers.StringToInt(value,fromBase,ParseNumbers.IsTight);
- }
-
- // Parses value in base fromBase. fromBase can only
- // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
- // by 0x; any other leading or trailing characters cause an error.
- //
- [CLSCompliant(false)]
- public static uint ToUInt32 (String value, int fromBase) {
- if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
- }
- Contract.EndContractBlock();
- return (uint) ParseNumbers.StringToInt(value,fromBase, ParseNumbers.TreatAsUnsigned | ParseNumbers.IsTight);
- }
-
- // Parses value in base fromBase. fromBase can only
- // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
- // by 0x; any other leading or trailing characters cause an error.
- //
- public static long ToInt64 (String value, int fromBase) {
- if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
- }
- Contract.EndContractBlock();
- return ParseNumbers.StringToLong(value,fromBase,ParseNumbers.IsTight);
- }
-
- // Parses value in base fromBase. fromBase can only
- // be 2, 8, 10, or 16. If fromBase is 16, the number may be preceded
- // by 0x; any other leading or trailing characters cause an error.
- //
- [CLSCompliant(false)]
- public static ulong ToUInt64 (String value, int fromBase) {
- if (fromBase!=2 && fromBase!=8 && fromBase!=10 && fromBase!=16) {
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
- }
- Contract.EndContractBlock();
- return (ulong) ParseNumbers.StringToLong(value,fromBase, ParseNumbers.TreatAsUnsigned | ParseNumbers.IsTight);
- }
-
- // Convert the byte value to a string in base fromBase
- public static String ToString (byte value, int toBase) {
- if (toBase!=2 && toBase!=8 && toBase!=10 && toBase!=16) {
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
- }
- Contract.EndContractBlock();
- return ParseNumbers.IntToString((int)value, toBase, -1, ' ', ParseNumbers.PrintAsI1);
- }
-
- // Convert the Int16 value to a string in base fromBase
- public static String ToString (short value, int toBase) {
- if (toBase!=2 && toBase!=8 && toBase!=10 && toBase!=16) {
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
- }
- Contract.EndContractBlock();
- return ParseNumbers.IntToString((int)value, toBase, -1, ' ', ParseNumbers.PrintAsI2);
- }
-
- // Convert the Int32 value to a string in base toBase
- public static String ToString (int value, int toBase) {
- if (toBase!=2 && toBase!=8 && toBase!=10 && toBase!=16) {
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
- }
- Contract.EndContractBlock();
- return ParseNumbers.IntToString(value, toBase, -1, ' ', 0);
- }
-
- // Convert the Int64 value to a string in base toBase
- public static String ToString (long value, int toBase) {
- if (toBase!=2 && toBase!=8 && toBase!=10 && toBase!=16) {
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidBase"));
- }
- Contract.EndContractBlock();
- return ParseNumbers.LongToString(value, toBase, -1, ' ', 0);
- }
-
- public static String ToBase64String(byte[] inArray) {
- if (inArray==null) {
- throw new ArgumentNullException(nameof(inArray));
- }
- Contract.Ensures(Contract.Result<string>() != null);
- Contract.EndContractBlock();
- return ToBase64String(inArray, 0, inArray.Length, Base64FormattingOptions.None);
- }
-
- public static String ToBase64String(byte[] inArray, Base64FormattingOptions options) {
- if (inArray==null) {
- throw new ArgumentNullException(nameof(inArray));
- }
- Contract.Ensures(Contract.Result<string>() != null);
- Contract.EndContractBlock();
- return ToBase64String(inArray, 0, inArray.Length, options);
- }
-
- public static String ToBase64String(byte[] inArray, int offset, int length) {
- return ToBase64String(inArray, offset, length, Base64FormattingOptions.None);
- }
-
- public static unsafe String ToBase64String(byte[] inArray, int offset, int length, Base64FormattingOptions options) {
- //Do data verfication
- if (inArray==null)
- throw new ArgumentNullException(nameof(inArray));
- if (length<0)
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- if (offset<0)
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
- if (options < Base64FormattingOptions.None || options > Base64FormattingOptions.InsertLineBreaks)
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)options));
- Contract.Ensures(Contract.Result<string>() != null);
- Contract.EndContractBlock();
-
- int inArrayLength;
- int stringLength;
-
- inArrayLength = inArray.Length;
- if (offset > (inArrayLength - length))
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
-
- if (inArrayLength == 0)
- return String.Empty;
-
- bool insertLineBreaks = (options == Base64FormattingOptions.InsertLineBreaks);
- //Create the new string. This is the maximally required length.
- stringLength = ToBase64_CalculateAndValidateOutputLength(length, insertLineBreaks);
-
- string returnString = string.FastAllocateString(stringLength);
- fixed (char* outChars = returnString){
- fixed (byte* inData = &inArray[0]) {
- int j = ConvertToBase64Array(outChars,inData,offset,length, insertLineBreaks);
- BCLDebug.Assert(returnString.Length == j, "returnString.Length == j");
- return returnString;
- }
- }
- }
-
- public static int ToBase64CharArray(byte[] inArray, int offsetIn, int length, char[] outArray, int offsetOut) {
- Contract.Ensures(Contract.Result<int>() >= 0);
- Contract.Ensures(Contract.Result<int>() <= outArray.Length);
- Contract.EndContractBlock();
-
- return ToBase64CharArray(inArray, offsetIn, length, outArray, offsetOut, Base64FormattingOptions.None);
- }
-
- public static unsafe int ToBase64CharArray(byte[] inArray, int offsetIn, int length, char[] outArray, int offsetOut, Base64FormattingOptions options) {
- //Do data verfication
- if (inArray==null)
- throw new ArgumentNullException(nameof(inArray));
- if (outArray==null)
- throw new ArgumentNullException(nameof(outArray));
- if (length<0)
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- if (offsetIn<0)
- throw new ArgumentOutOfRangeException(nameof(offsetIn), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
- if (offsetOut<0)
- throw new ArgumentOutOfRangeException(nameof(offsetOut), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
-
- if( options < Base64FormattingOptions.None || options > Base64FormattingOptions.InsertLineBreaks) {
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)options));
- }
- Contract.Ensures(Contract.Result<int>() >= 0);
- Contract.Ensures(Contract.Result<int>() <= outArray.Length);
- Contract.EndContractBlock();
-
-
- int retVal;
-
- int inArrayLength;
- int outArrayLength;
- int numElementsToCopy;
-
- inArrayLength = inArray.Length;
-
- if (offsetIn > (int)(inArrayLength - length))
- throw new ArgumentOutOfRangeException(nameof(offsetIn), Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
-
- if (inArrayLength == 0)
- return 0;
-
- bool insertLineBreaks = (options == Base64FormattingOptions.InsertLineBreaks);
- //This is the maximally required length that must be available in the char array
- outArrayLength = outArray.Length;
-
- // Length of the char buffer required
- numElementsToCopy = ToBase64_CalculateAndValidateOutputLength(length, insertLineBreaks);
-
- if (offsetOut > (int)(outArrayLength - numElementsToCopy))
- throw new ArgumentOutOfRangeException(nameof(offsetOut), Environment.GetResourceString("ArgumentOutOfRange_OffsetOut"));
-
- fixed (char* outChars = &outArray[offsetOut]) {
- fixed (byte* inData = &inArray[0]) {
- retVal = ConvertToBase64Array(outChars,inData,offsetIn,length, insertLineBreaks);
- }
- }
-
- return retVal;
- }
-
- private static unsafe int ConvertToBase64Array(char* outChars, byte* inData, int offset, int length, bool insertLineBreaks) {
- int lengthmod3 = length%3;
- int calcLength = offset + (length - lengthmod3);
- int j=0;
- int charcount = 0;
- //Convert three bytes at a time to base64 notation. This will consume 4 chars.
- int i;
-
- // get a pointer to the base64Table to avoid unnecessary range checking
- fixed(char* base64 = &base64Table[0]) {
- for (i=offset; i<calcLength; i+=3)
- {
- if (insertLineBreaks) {
- if (charcount == base64LineBreakPosition) {
- outChars[j++] = '\r';
- outChars[j++] = '\n';
- charcount = 0;
- }
- charcount += 4;
- }
- outChars[j] = base64[(inData[i]&0xfc)>>2];
- outChars[j+1] = base64[((inData[i]&0x03)<<4) | ((inData[i+1]&0xf0)>>4)];
- outChars[j+2] = base64[((inData[i+1]&0x0f)<<2) | ((inData[i+2]&0xc0)>>6)];
- outChars[j+3] = base64[(inData[i+2]&0x3f)];
- j += 4;
- }
-
- //Where we left off before
- i = calcLength;
-
- if (insertLineBreaks && (lengthmod3 !=0) && (charcount == base64LineBreakPosition)) {
- outChars[j++] = '\r';
- outChars[j++] = '\n';
- }
-
- switch(lengthmod3)
- {
- case 2: //One character padding needed
- outChars[j] = base64[(inData[i]&0xfc)>>2];
- outChars[j+1] = base64[((inData[i]&0x03)<<4)|((inData[i+1]&0xf0)>>4)];
- outChars[j+2] = base64[(inData[i+1]&0x0f)<<2];
- outChars[j+3] = base64[64]; //Pad
- j+=4;
- break;
- case 1: // Two character padding needed
- outChars[j] = base64[(inData[i]&0xfc)>>2];
- outChars[j+1] = base64[(inData[i]&0x03)<<4];
- outChars[j+2] = base64[64]; //Pad
- outChars[j+3] = base64[64]; //Pad
- j+=4;
- break;
- }
- }
-
- return j;
- }
-
- private static int ToBase64_CalculateAndValidateOutputLength(int inputLength, bool insertLineBreaks) {
- long outlen = ((long)inputLength) / 3 * 4; // the base length - we want integer division here.
- outlen += ((inputLength % 3) != 0) ? 4 : 0; // at most 4 more chars for the remainder
-
- if (outlen == 0)
- return 0;
-
- if (insertLineBreaks) {
- long newLines = outlen / base64LineBreakPosition;
- if ((outlen % base64LineBreakPosition) == 0) {
- --newLines;
- }
- outlen += newLines * 2; // the number of line break chars we'll add, "\r\n"
- }
-
- // If we overflow an int then we cannot allocate enough
- // memory to output the value so throw
- if (outlen > int.MaxValue)
- throw new OutOfMemoryException();
-
- return (int)outlen;
- }
-
-
- /// <summary>
- /// Converts the specified string, which encodes binary data as Base64 digits, to the equivalent byte array.
- /// </summary>
- /// <param name="s">The string to convert</param>
- /// <returns>The array of bytes represented by the specifed Base64 string.</returns>
- public static Byte[] FromBase64String(String s) {
-
- // "s" is an unfortunate parameter name, but we need to keep it for backward compat.
-
- if (s == null)
- throw new ArgumentNullException(nameof(s));
-
- Contract.EndContractBlock();
-
- unsafe {
- fixed (Char* sPtr = s) {
-
- return FromBase64CharPtr(sPtr, s.Length);
- }
- }
- }
-
-
- /// <summary>
- /// Converts the specified range of a Char array, which encodes binary data as Base64 digits, to the equivalent byte array.
- /// </summary>
- /// <param name="inArray">Chars representing Base64 encoding characters</param>
- /// <param name="offset">A position within the input array.</param>
- /// <param name="length">Number of element to convert.</param>
- /// <returns>The array of bytes represented by the specified Base64 encoding characters.</returns>
- public static Byte[] FromBase64CharArray(Char[] inArray, Int32 offset, Int32 length) {
-
- if (inArray == null)
- throw new ArgumentNullException(nameof(inArray));
-
- if (length < 0)
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_Index"));
-
- if (offset < 0)
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
-
- if (offset > inArray.Length - length)
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
-
- Contract.EndContractBlock();
-
- unsafe {
- fixed (Char* inArrayPtr = inArray) {
-
- return FromBase64CharPtr(inArrayPtr + offset, length);
- }
- }
- }
-
-
-
- /// <summary>
- /// Convert Base64 encoding characters to bytes:
- /// - Compute result length exactly by actually walking the input;
- /// - Allocate new result array based on computation;
- /// - Decode input into the new array;
- /// </summary>
- /// <param name="inputPtr">Pointer to the first input char</param>
- /// <param name="inputLength">Number of input chars</param>
- /// <returns></returns>
- private static unsafe Byte[] FromBase64CharPtr(Char* inputPtr, Int32 inputLength) {
-
- // The validity of parameters much be checked by callers, thus we are Critical here.
-
- Debug.Assert(0 <= inputLength);
-
- // We need to get rid of any trailing white spaces.
- // Otherwise we would be rejecting input such as "abc= ":
- while (inputLength > 0)
- {
- Int32 lastChar = inputPtr[inputLength - 1];
- if (lastChar != (Int32) ' ' && lastChar != (Int32) '\n' && lastChar != (Int32) '\r' && lastChar != (Int32) '\t')
- break;
- inputLength--;
- }
-
- // Compute the output length:
- Int32 resultLength = FromBase64_ComputeResultLength(inputPtr, inputLength);
-
- Debug.Assert(0 <= resultLength);
-
- // resultLength can be zero. We will still enter FromBase64_Decode and process the input.
- // It may either simply write no bytes (e.g. input = " ") or throw (e.g. input = "ab").
-
- // Create result byte blob:
- Byte[] decodedBytes = new Byte[resultLength];
-
- // Convert Base64 chars into bytes:
- Int32 actualResultLength;
- fixed (Byte* decodedBytesPtr = decodedBytes)
- actualResultLength = FromBase64_Decode(inputPtr, inputLength, decodedBytesPtr, resultLength);
-
- // Note that actualResultLength can differ from resultLength if the caller is modifying the array
- // as it is being converted. Silently ignore the failure.
- // Consider throwing exception in an non in-place release.
-
- // We are done:
- return decodedBytes;
- }
-
-
- /// <summary>
- /// Decode characters representing a Base64 encoding into bytes:
- /// Walk the input. Every time 4 chars are read, convert them to the 3 corresponding output bytes.
- /// This method is a bit lengthy on purpose. We are trying to avoid jumps to helpers in the loop
- /// to aid performance.
- /// </summary>
- /// <param name="inputPtr">Pointer to first input char</param>
- /// <param name="inputLength">Number of input chars</param>
- /// <param name="destPtr">Pointer to location for the first result byte</param>
- /// <param name="destLength">Max length of the preallocated result buffer</param>
- /// <returns>If the result buffer was not large enough to write all result bytes, return -1;
- /// Otherwise return the number of result bytes actually produced.</returns>
- private static unsafe Int32 FromBase64_Decode(Char* startInputPtr, Int32 inputLength, Byte* startDestPtr, Int32 destLength) {
-
- // You may find this method weird to look at. It’s written for performance, not aesthetics.
- // You will find unrolled loops label jumps and bit manipulations.
-
- const UInt32 intA = (UInt32) 'A';
- const UInt32 inta = (UInt32) 'a';
- const UInt32 int0 = (UInt32) '0';
- const UInt32 intEq = (UInt32) '=';
- const UInt32 intPlus = (UInt32) '+';
- const UInt32 intSlash = (UInt32) '/';
- const UInt32 intSpace = (UInt32) ' ';
- const UInt32 intTab = (UInt32) '\t';
- const UInt32 intNLn = (UInt32) '\n';
- const UInt32 intCRt = (UInt32) '\r';
- const UInt32 intAtoZ = (UInt32) ('Z' - 'A'); // = ('z' - 'a')
- const UInt32 int0to9 = (UInt32) ('9' - '0');
-
- Char* inputPtr = startInputPtr;
- Byte* destPtr = startDestPtr;
-
- // Pointers to the end of input and output:
- Char* endInputPtr = inputPtr + inputLength;
- Byte* endDestPtr = destPtr + destLength;
-
- // Current char code/value:
- UInt32 currCode;
-
- // This 4-byte integer will contain the 4 codes of the current 4-char group.
- // Eeach char codes for 6 bits = 24 bits.
- // The remaining byte will be FF, we use it as a marker when 4 chars have been processed.
- UInt32 currBlockCodes = 0x000000FFu;
-
- unchecked { while (true) {
-
- // break when done:
- if (inputPtr >= endInputPtr)
- goto _AllInputConsumed;
-
- // Get current char:
- currCode = (UInt32) (*inputPtr);
- inputPtr++;
-
- // Determine current char code:
-
- if (currCode - intA <= intAtoZ)
- currCode -= intA;
-
- else if (currCode - inta <= intAtoZ)
- currCode -= (inta - 26u);
-
- else if (currCode - int0 <= int0to9)
- currCode -= (int0 - 52u);
-
- else {
- // Use the slower switch for less common cases:
- switch(currCode) {
-
- // Significant chars:
- case intPlus: currCode = 62u;
- break;
-
- case intSlash: currCode = 63u;
- break;
-
- // Legal no-value chars (we ignore these):
- case intCRt: case intNLn: case intSpace: case intTab:
- continue;
-
- // The equality char is only legal at the end of the input.
- // Jump after the loop to make it easier for the JIT register predictor to do a good job for the loop itself:
- case intEq:
- goto _EqualityCharEncountered;
-
- // Other chars are illegal:
- default:
- throw new FormatException(Environment.GetResourceString("Format_BadBase64Char"));
- }
- }
-
- // Ok, we got the code. Save it:
- currBlockCodes = (currBlockCodes << 6) | currCode;
-
- // Last bit in currBlockCodes will be on after in shifted right 4 times:
- if ((currBlockCodes & 0x80000000u) != 0u) {
-
- if ((Int32) (endDestPtr - destPtr) < 3)
- return -1;
-
- *(destPtr) = (Byte) (currBlockCodes >> 16);
- *(destPtr + 1) = (Byte) (currBlockCodes >> 8);
- *(destPtr + 2) = (Byte) (currBlockCodes);
- destPtr += 3;
-
- currBlockCodes = 0x000000FFu;
- }
-
- }} // unchecked while
-
- // 'd be nice to have an assert that we never get here, but CS0162: Unreachable code detected.
- // Debug.Assert(false, "We only leave the above loop by jumping; should never get here.");
-
- // We jump here out of the loop if we hit an '=':
- _EqualityCharEncountered:
-
- Debug.Assert(currCode == intEq);
-
- // Recall that inputPtr is now one position past where '=' was read.
- // '=' can only be at the last input pos:
- if (inputPtr == endInputPtr) {
-
- // Code is zero for trailing '=':
- currBlockCodes <<= 6;
-
- // The '=' did not complete a 4-group. The input must be bad:
- if ((currBlockCodes & 0x80000000u) == 0u)
- throw new FormatException(Environment.GetResourceString("Format_BadBase64CharArrayLength"));
-
- if ((int)(endDestPtr - destPtr) < 2) // Autch! We underestimated the output length!
- return -1;
-
- // We are good, store bytes form this past group. We had a single "=", so we take two bytes:
- *(destPtr++) = (Byte) (currBlockCodes >> 16);
- *(destPtr++) = (Byte) (currBlockCodes >> 8);
-
- currBlockCodes = 0x000000FFu;
-
- } else { // '=' can also be at the pre-last position iff the last is also a '=' excluding the white spaces:
-
- // We need to get rid of any intermediate white spaces.
- // Otherwise we would be rejecting input such as "abc= =":
- while (inputPtr < (endInputPtr - 1))
- {
- Int32 lastChar = *(inputPtr);
- if (lastChar != (Int32) ' ' && lastChar != (Int32) '\n' && lastChar != (Int32) '\r' && lastChar != (Int32) '\t')
- break;
- inputPtr++;
- }
-
- if (inputPtr == (endInputPtr - 1) && *(inputPtr) == '=') {
-
- // Code is zero for each of the two '=':
- currBlockCodes <<= 12;
-
- // The '=' did not complete a 4-group. The input must be bad:
- if ((currBlockCodes & 0x80000000u) == 0u)
- throw new FormatException(Environment.GetResourceString("Format_BadBase64CharArrayLength"));
-
- if ((Int32) (endDestPtr - destPtr) < 1) // Autch! We underestimated the output length!
- return -1;
-
- // We are good, store bytes form this past group. We had a "==", so we take only one byte:
- *(destPtr++) = (Byte) (currBlockCodes >> 16);
-
- currBlockCodes = 0x000000FFu;
-
- } else // '=' is not ok at places other than the end:
- throw new FormatException(Environment.GetResourceString("Format_BadBase64Char"));
-
- }
-
- // We get here either from above or by jumping out of the loop:
- _AllInputConsumed:
-
- // The last block of chars has less than 4 items
- if (currBlockCodes != 0x000000FFu)
- throw new FormatException(Environment.GetResourceString("Format_BadBase64CharArrayLength"));
-
- // Return how many bytes were actually recovered:
- return (Int32) (destPtr - startDestPtr);
-
- } // Int32 FromBase64_Decode(...)
-
-
- /// <summary>
- /// Compute the number of bytes encoded in the specified Base 64 char array:
- /// Walk the entire input counting white spaces and padding chars, then compute result length
- /// based on 3 bytes per 4 chars.
- /// </summary>
- private static unsafe Int32 FromBase64_ComputeResultLength(Char* inputPtr, Int32 inputLength) {
-
- const UInt32 intEq = (UInt32) '=';
- const UInt32 intSpace = (UInt32) ' ';
-
- Debug.Assert(0 <= inputLength);
-
- Char* inputEndPtr = inputPtr + inputLength;
- Int32 usefulInputLength = inputLength;
- Int32 padding = 0;
-
- while (inputPtr < inputEndPtr) {
-
- UInt32 c = (UInt32) (*inputPtr);
- inputPtr++;
-
- // We want to be as fast as possible and filter out spaces with as few comparisons as possible.
- // We end up accepting a number of illegal chars as legal white-space chars.
- // This is ok: as soon as we hit them during actual decode we will recognise them as illegal and throw.
- if (c <= intSpace)
- usefulInputLength--;
-
- else if (c == intEq) {
- usefulInputLength--;
- padding++;
- }
- }
-
- Debug.Assert(0 <= usefulInputLength);
-
- // For legal input, we can assume that 0 <= padding < 3. But it may be more for illegal input.
- // We will notice it at decode when we see a '=' at the wrong place.
- Debug.Assert(0 <= padding);
-
- // Perf: reuse the variable that stored the number of '=' to store the number of bytes encoded by the
- // last group that contains the '=':
- if (padding != 0) {
-
- if (padding == 1)
- padding = 2;
- else if (padding == 2)
- padding = 1;
- else
- throw new FormatException(Environment.GetResourceString("Format_BadBase64Char"));
- }
-
- // Done:
- return (usefulInputLength / 4) * 3 + padding;
- }
-
- } // class Convert
-} // namespace
-
diff --git a/src/mscorlib/src/System/Currency.cs b/src/mscorlib/src/System/Currency.cs
index 05a09802cd..13ec1b0c4e 100644
--- a/src/mscorlib/src/System/Currency.cs
+++ b/src/mscorlib/src/System/Currency.cs
@@ -2,37 +2,41 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System {
-
- using System;
- using System.Globalization;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
+using System;
+using System.Globalization;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+
+namespace System
+{
[Serializable]
internal struct Currency
{
internal long m_value;
-
+
// Constructs a Currency from a Decimal value.
//
- public Currency(Decimal value) {
+ public Currency(Decimal value)
+ {
m_value = Decimal.ToCurrency(value).m_value;
}
-
+
// Constructs a Currency from a long value without scaling. The
// ignored parameter exists only to distinguish this constructor
// from the constructor that takes a long. Used only in the System
// package, especially in Variant.
- internal Currency(long value, int ignored) {
+ internal Currency(long value, int ignored)
+ {
m_value = value;
}
-
+
// Creates a Currency from an OLE Automation Currency. This method
// applies no scaling to the Currency value, essentially doing a bitwise
// copy.
//
- public static Currency FromOACurrency(long cy){
+ public static Currency FromOACurrency(long cy)
+ {
return new Currency(cy, 0);
}
@@ -40,20 +44,21 @@ namespace System {
// method applies no scaling to the Currency value, essentially doing
// a bitwise copy.
//
- public long ToOACurrency() {
+ public long ToOACurrency()
+ {
return m_value;
}
-
+
// Converts a Currency to a Decimal.
//
public static Decimal ToDecimal(Currency c)
{
- Decimal result = new Decimal ();
- FCallToDecimal (ref result, c);
+ Decimal result = new Decimal();
+ FCallToDecimal(ref result, c);
return result;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void FCallToDecimal(ref Decimal result,Currency c);
+ private static extern void FCallToDecimal(ref Decimal result, Currency c);
}
}
diff --git a/src/mscorlib/src/System/CurrentSystemTimeZone.Cache.cs b/src/mscorlib/src/System/CurrentSystemTimeZone.Cache.cs
new file mode 100644
index 0000000000..744c697124
--- /dev/null
+++ b/src/mscorlib/src/System/CurrentSystemTimeZone.Cache.cs
@@ -0,0 +1,35 @@
+// 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.Collections;
+using System.Globalization;
+
+namespace System
+{
+ internal partial class CurrentSystemTimeZone
+ {
+ private DaylightTime GetCachedDaylightChanges(int year)
+ {
+ Object objYear = (Object)year;
+
+ if (!m_CachedDaylightChanges.Contains(objYear))
+ {
+ DaylightTime currentDaylightChanges = CreateDaylightChanges(year);
+ lock (m_CachedDaylightChanges)
+ {
+ if (!m_CachedDaylightChanges.Contains(objYear))
+ {
+ m_CachedDaylightChanges.Add(objYear, currentDaylightChanges);
+ }
+ }
+ }
+
+ return (DaylightTime)m_CachedDaylightChanges[objYear];
+ }
+
+ // The per-year information is cached in in this instance value. As a result it can
+ // be cleaned up by CultureInfo.ClearCachedData, which will clear the instance of this object
+ private readonly Hashtable m_CachedDaylightChanges = new Hashtable();
+ }
+}
diff --git a/src/mscorlib/src/System/CurrentTimeZone.cs b/src/mscorlib/src/System/CurrentTimeZone.cs
deleted file mode 100644
index 804bbcccc4..0000000000
--- a/src/mscorlib/src/System/CurrentTimeZone.cs
+++ /dev/null
@@ -1,214 +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.
-
-/*============================================================
-**
-** Class: CurrentTimeZone
-**
-**
-** Purpose:
-** This class represents the current system timezone. It is
-** the only meaningful implementation of the TimeZone class
-** available in this version.
-**
-** The only TimeZone that we support in version 1 is the
-** CurrentTimeZone as determined by the system timezone.
-**
-**
-============================================================*/
-namespace System {
- using System;
- using System.Diagnostics.Contracts;
- using System.Text;
- using System.Collections;
- using System.Globalization;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
-
- [Obsolete("System.CurrentSystemTimeZone has been deprecated. Please investigate the use of System.TimeZoneInfo.Local instead.")]
- [Serializable]
- internal class CurrentSystemTimeZone : TimeZone
- {
- // The per-year information is cached in in this instance value. As a result it can
- // be cleaned up by CultureInfo.ClearCachedData, which will clear the instance of this object
- private readonly Hashtable m_CachedDaylightChanges = new Hashtable();
-
- // Standard offset in ticks to the Universal time if
- // no daylight saving is in used.
- // E.g. the offset for PST (Pacific Standard time) should be -8 * 60 * 60 * 1000 * 10000.
- // (1 millisecond = 10000 ticks)
- private long m_ticksOffset;
- private String m_standardName;
- private String m_daylightName;
-
- internal CurrentSystemTimeZone()
- {
- TimeZoneInfo local = TimeZoneInfo.Local;
-
- m_ticksOffset = local.BaseUtcOffset.Ticks;
- m_standardName = local.StandardName;
- m_daylightName = local.DaylightName;
- }
-
- public override String StandardName
- {
- get
- {
- return m_standardName;
- }
- }
-
- public override String DaylightName
- {
- get
- {
- return m_daylightName;
- }
- }
-
- internal long GetUtcOffsetFromUniversalTime(DateTime time, ref Boolean isAmbiguousLocalDst)
- {
- // Get the daylight changes for the year of the specified time.
- TimeSpan offset = new TimeSpan(m_ticksOffset);
- DaylightTime daylightTime = GetDaylightChanges(time.Year);
- isAmbiguousLocalDst= false;
-
- if (daylightTime == null || daylightTime.Delta.Ticks == 0)
- {
- return offset.Ticks;
- }
-
- // The start and end times represent the range of universal times that are in DST for that year.
- // Within that there is an ambiguous hour, usually right at the end, but at the beginning in
- // the unusual case of a negative daylight savings delta.
- DateTime startTime = daylightTime.Start - offset;
- DateTime endTime = daylightTime.End - offset - daylightTime.Delta;
- DateTime ambiguousStart;
- DateTime ambiguousEnd;
-
- if (daylightTime.Delta.Ticks > 0)
- {
- ambiguousStart = endTime - daylightTime.Delta;
- ambiguousEnd = endTime;
- }
- else
- {
- ambiguousStart = startTime;
- ambiguousEnd = startTime - daylightTime.Delta;
- }
-
- Boolean isDst = false;
- if (startTime > endTime)
- {
- // In southern hemisphere, the daylight saving time starts later in the year, and ends in the beginning of next year.
- // Note, the summer in the southern hemisphere begins late in the year.
- isDst = (time < endTime || time >= startTime);
- }
- else
- {
- // In northern hemisphere, the daylight saving time starts in the middle of the year.
- isDst = (time >= startTime && time < endTime);
- }
-
- if (isDst)
- {
- offset += daylightTime.Delta;
-
- // See if the resulting local time becomes ambiguous. This must be captured here or the
- // DateTime will not be able to round-trip back to UTC accurately.
- if (time >= ambiguousStart && time < ambiguousEnd )
- {
- isAmbiguousLocalDst = true;
- }
- }
- return offset.Ticks;
- }
-
- public override DateTime ToLocalTime(DateTime time)
- {
- if (time.Kind == DateTimeKind.Local)
- {
- return time;
- }
- Boolean isAmbiguousLocalDst = false;
- Int64 offset = GetUtcOffsetFromUniversalTime(time, ref isAmbiguousLocalDst);
- long tick = time.Ticks + offset;
- if (tick > DateTime.MaxTicks)
- {
- return new DateTime(DateTime.MaxTicks, DateTimeKind.Local);
- }
- if (tick < DateTime.MinTicks)
- {
- return new DateTime(DateTime.MinTicks, DateTimeKind.Local);
- }
- return new DateTime(tick, DateTimeKind.Local, isAmbiguousLocalDst);
- }
-
- public override DaylightTime GetDaylightChanges(int year)
- {
- if (year < 1 || year > 9999)
- {
- throw new ArgumentOutOfRangeException(nameof(year), Environment.GetResourceString("ArgumentOutOfRange_Range", 1, 9999));
- }
- Contract.EndContractBlock();
-
- Object objYear = (Object) year;
-
- if (!m_CachedDaylightChanges.Contains(objYear))
- {
- DaylightTime currentDaylightChanges = null;
-
- if (TimeZoneInfo.Local.SupportsDaylightSavingTime)
- {
- DateTime start;
- DateTime end;
- TimeSpan delta;
-
- foreach (var rule in TimeZoneInfo.Local.GetAdjustmentRules())
- {
- if (rule.DateStart.Year <= year && rule.DateEnd.Year >= year && rule.DaylightDelta != TimeSpan.Zero)
- {
- start = TimeZoneInfo.TransitionTimeToDateTime(year, rule.DaylightTransitionStart);
- end = TimeZoneInfo.TransitionTimeToDateTime(year, rule.DaylightTransitionEnd);
- delta = rule.DaylightDelta;
-
- currentDaylightChanges = new DaylightTime(start, end, delta);
- break;
- }
- }
- }
-
- if (currentDaylightChanges == null)
- {
- currentDaylightChanges = new DaylightTime(DateTime.MinValue, DateTime.MinValue, TimeSpan.Zero);
- }
-
- lock (m_CachedDaylightChanges)
- {
- if (!m_CachedDaylightChanges.Contains(objYear))
- {
- m_CachedDaylightChanges.Add(objYear, currentDaylightChanges);
- }
- }
- }
-
- DaylightTime result = (DaylightTime)m_CachedDaylightChanges[objYear];
-
- return result;
- }
-
- public override TimeSpan GetUtcOffset(DateTime time)
- {
- if (time.Kind == DateTimeKind.Utc)
- {
- return TimeSpan.Zero;
- }
- else
- {
- return new TimeSpan(TimeZone.CalculateUtcOffset(time, GetDaylightChanges(time.Year)).Ticks + m_ticksOffset);
- }
- }
-
- } // class CurrentSystemTimeZone
-}
diff --git a/src/mscorlib/src/System/DBNull.cs b/src/mscorlib/src/System/DBNull.cs
deleted file mode 100644
index 65c85ba968..0000000000
--- a/src/mscorlib/src/System/DBNull.cs
+++ /dev/null
@@ -1,119 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-// Void
-// This class represents a Missing Variant
-////////////////////////////////////////////////////////////////////////////////
-namespace System {
-
- using System;
- using System.Runtime.Remoting;
- using System.Runtime.Serialization;
- [Serializable]
- public sealed class DBNull : ISerializable, IConvertible {
-
- //Package private constructor
- private DBNull(){
- }
-
- private DBNull(SerializationInfo info, StreamingContext context) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DBNullSerial"));
- }
-
- public static readonly DBNull Value = new DBNull();
-
- public void GetObjectData(SerializationInfo info, StreamingContext context) {
- UnitySerializationHolder.GetUnitySerializationInfo(info, UnitySerializationHolder.NullUnity, null, null);
- }
-
- public override String ToString() {
- return String.Empty;
- }
-
- public String ToString(IFormatProvider provider) {
- return String.Empty;
- }
-
- public TypeCode GetTypeCode() {
- return TypeCode.DBNull;
- }
-
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromDBNull"));
- }
-
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromDBNull"));
- }
-
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromDBNull"));
- }
-
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromDBNull"));
- }
-
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromDBNull"));
- }
-
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromDBNull"));
- }
-
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromDBNull"));
- }
-
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromDBNull"));
- }
-
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromDBNull"));
- }
-
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromDBNull"));
- }
-
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromDBNull"));
- }
-
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromDBNull"));
- }
-
- /// <internalonly/>
- decimal IConvertible.ToDecimal(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromDBNull"));
- }
-
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromDBNull"));
- }
-
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
- return Convert.DefaultToType((IConvertible)this, type, provider);
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/DataMisalignedException.cs b/src/mscorlib/src/System/DataMisalignedException.cs
deleted file mode 100644
index a3653e7219..0000000000
--- a/src/mscorlib/src/System/DataMisalignedException.cs
+++ /dev/null
@@ -1,39 +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.
-
-/*=============================================================================
-**
-**
-** Purpose: The exception class for a misaligned access exception
-**
-=============================================================================*/
-
-using System.Runtime.Serialization;
-
-namespace System
-{
- [Serializable]
- public sealed class DataMisalignedException : SystemException
- {
- public DataMisalignedException()
- : base(SR.Arg_DataMisalignedException)
- {
- HResult = __HResults.COR_E_DATAMISALIGNED;
- }
-
- public DataMisalignedException(String message)
- : base(message)
- {
- HResult = __HResults.COR_E_DATAMISALIGNED;
- }
-
- public DataMisalignedException(String message, Exception innerException)
- : base(message, innerException)
- {
- HResult = __HResults.COR_E_DATAMISALIGNED;
- }
-
- internal DataMisalignedException(SerializationInfo info, StreamingContext context) : base(info, context) { }
- }
-}
diff --git a/src/mscorlib/src/System/DateTime.CoreCLR.cs b/src/mscorlib/src/System/DateTime.CoreCLR.cs
new file mode 100644
index 0000000000..69c595663b
--- /dev/null
+++ b/src/mscorlib/src/System/DateTime.CoreCLR.cs
@@ -0,0 +1,29 @@
+// 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.Diagnostics.Contracts;
+using System.Runtime.CompilerServices;
+
+namespace System
+{
+ public partial struct DateTime
+ {
+ public static DateTime UtcNow
+ {
+ get
+ {
+ Contract.Ensures(Contract.Result<DateTime>().Kind == DateTimeKind.Utc);
+ // following code is tuned for speed. Don't change it without running benchmark.
+ long ticks = 0;
+ ticks = GetSystemTimeAsFileTime();
+
+ return new DateTime(((UInt64)(ticks + FileTimeOffset)) | KindUtc);
+ }
+ }
+
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern long GetSystemTimeAsFileTime();
+ }
+}
diff --git a/src/mscorlib/src/System/DateTime.cs b/src/mscorlib/src/System/DateTime.cs
deleted file mode 100644
index 3de50336a9..0000000000
--- a/src/mscorlib/src/System/DateTime.cs
+++ /dev/null
@@ -1,1360 +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.
-
-namespace System {
-
- using System;
- using System.Threading;
- using System.Globalization;
- using System.Runtime;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Runtime.Serialization;
- using System.Runtime.Versioning;
- using System.Security;
- using System.Diagnostics.Contracts;
- using CultureInfo = System.Globalization.CultureInfo;
- using Calendar = System.Globalization.Calendar;
-
- // This value type represents a date and time. Every DateTime
- // object has a private field (Ticks) of type Int64 that stores the
- // date and time as the number of 100 nanosecond intervals since
- // 12:00 AM January 1, year 1 A.D. in the proleptic Gregorian Calendar.
- //
- // Starting from V2.0, DateTime also stored some context about its time
- // zone in the form of a 3-state value representing Unspecified, Utc or
- // Local. This is stored in the two top bits of the 64-bit numeric value
- // with the remainder of the bits storing the tick count. This information
- // is only used during time zone conversions and is not part of the
- // identity of the DateTime. Thus, operations like Compare and Equals
- // ignore this state. This is to stay compatible with earlier behavior
- // and performance characteristics and to avoid forcing people into dealing
- // with the effects of daylight savings. Note, that this has little effect
- // on how the DateTime works except in a context where its specific time
- // zone is needed, such as during conversions and some parsing and formatting
- // cases.
- //
- // There is also 4th state stored that is a special type of Local value that
- // is used to avoid data loss when round-tripping between local and UTC time.
- // See below for more information on this 4th state, although it is
- // effectively hidden from most users, who just see the 3-state DateTimeKind
- // enumeration.
- //
- // For compatibility, DateTime does not serialize the Kind data when used in
- // binary serialization.
- //
- // For a description of various calendar issues, look at
- //
- // Calendar Studies web site, at
- // http://serendipity.nofadz.com/hermetic/cal_stud.htm.
- //
- //
- [StructLayout(LayoutKind.Auto)]
- [Serializable]
- public struct DateTime : IComparable, IFormattable, IConvertible, IComparable<DateTime>, IEquatable<DateTime>, ISerializable
- {
-
- // Number of 100ns ticks per time unit
- private const long TicksPerMillisecond = 10000;
- private const long TicksPerSecond = TicksPerMillisecond * 1000;
- private const long TicksPerMinute = TicksPerSecond * 60;
- private const long TicksPerHour = TicksPerMinute * 60;
- private const long TicksPerDay = TicksPerHour * 24;
-
- // Number of milliseconds per time unit
- private const int MillisPerSecond = 1000;
- private const int MillisPerMinute = MillisPerSecond * 60;
- private const int MillisPerHour = MillisPerMinute * 60;
- private const int MillisPerDay = MillisPerHour * 24;
-
- // Number of days in a non-leap year
- private const int DaysPerYear = 365;
- // Number of days in 4 years
- private const int DaysPer4Years = DaysPerYear * 4 + 1; // 1461
- // Number of days in 100 years
- private const int DaysPer100Years = DaysPer4Years * 25 - 1; // 36524
- // Number of days in 400 years
- private const int DaysPer400Years = DaysPer100Years * 4 + 1; // 146097
-
- // Number of days from 1/1/0001 to 12/31/1600
- private const int DaysTo1601 = DaysPer400Years * 4; // 584388
- // Number of days from 1/1/0001 to 12/30/1899
- private const int DaysTo1899 = DaysPer400Years * 4 + DaysPer100Years * 3 - 367;
- // Number of days from 1/1/0001 to 12/31/1969
- internal const int DaysTo1970 = DaysPer400Years * 4 + DaysPer100Years * 3 + DaysPer4Years * 17 + DaysPerYear; // 719,162
- // Number of days from 1/1/0001 to 12/31/9999
- private const int DaysTo10000 = DaysPer400Years * 25 - 366; // 3652059
-
- internal const long MinTicks = 0;
- internal const long MaxTicks = DaysTo10000 * TicksPerDay - 1;
- private const long MaxMillis = (long)DaysTo10000 * MillisPerDay;
-
- private const long FileTimeOffset = DaysTo1601 * TicksPerDay;
- private const long DoubleDateOffset = DaysTo1899 * TicksPerDay;
- // The minimum OA date is 0100/01/01 (Note it's year 100).
- // The maximum OA date is 9999/12/31
- private const long OADateMinAsTicks = (DaysPer100Years - DaysPerYear) * TicksPerDay;
- // All OA dates must be greater than (not >=) OADateMinAsDouble
- private const double OADateMinAsDouble = -657435.0;
- // All OA dates must be less than (not <=) OADateMaxAsDouble
- private const double OADateMaxAsDouble = 2958466.0;
-
- private const int DatePartYear = 0;
- private const int DatePartDayOfYear = 1;
- private const int DatePartMonth = 2;
- private const int DatePartDay = 3;
-
- private static readonly int[] DaysToMonth365 = {
- 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
- private static readonly int[] DaysToMonth366 = {
- 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366};
-
- public static readonly DateTime MinValue = new DateTime(MinTicks, DateTimeKind.Unspecified);
- public static readonly DateTime MaxValue = new DateTime(MaxTicks, DateTimeKind.Unspecified);
-
- private const UInt64 TicksMask = 0x3FFFFFFFFFFFFFFF;
- private const UInt64 FlagsMask = 0xC000000000000000;
- private const UInt64 LocalMask = 0x8000000000000000;
- private const Int64 TicksCeiling = 0x4000000000000000;
- private const UInt64 KindUnspecified = 0x0000000000000000;
- private const UInt64 KindUtc = 0x4000000000000000;
- private const UInt64 KindLocal = 0x8000000000000000;
- private const UInt64 KindLocalAmbiguousDst = 0xC000000000000000;
- private const Int32 KindShift = 62;
-
- private const String TicksField = "ticks";
- private const String DateDataField = "dateData";
-
- // The data is stored as an unsigned 64-bit integeter
- // Bits 01-62: The value of 100-nanosecond ticks where 0 represents 1/1/0001 12:00am, up until the value
- // 12/31/9999 23:59:59.9999999
- // Bits 63-64: A four-state value that describes the DateTimeKind value of the date time, with a 2nd
- // value for the rare case where the date time is local, but is in an overlapped daylight
- // savings time hour and it is in daylight savings time. This allows distinction of these
- // otherwise ambiguous local times and prevents data loss when round tripping from Local to
- // UTC time.
- private UInt64 dateData;
-
- // Constructs a DateTime from a tick count. The ticks
- // argument specifies the date as the number of 100-nanosecond intervals
- // that have elapsed since 1/1/0001 12:00am.
- //
- public DateTime(long ticks) {
- if (ticks < MinTicks || ticks > MaxTicks)
- throw new ArgumentOutOfRangeException(nameof(ticks), Environment.GetResourceString("ArgumentOutOfRange_DateTimeBadTicks"));
- Contract.EndContractBlock();
- dateData = (UInt64)ticks;
- }
-
- private DateTime(UInt64 dateData) {
- this.dateData = dateData;
- }
-
- public DateTime(long ticks, DateTimeKind kind) {
- if (ticks < MinTicks || ticks > MaxTicks) {
- throw new ArgumentOutOfRangeException(nameof(ticks), Environment.GetResourceString("ArgumentOutOfRange_DateTimeBadTicks"));
- }
- if (kind < DateTimeKind.Unspecified || kind > DateTimeKind.Local) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDateTimeKind"), nameof(kind));
- }
- Contract.EndContractBlock();
- this.dateData = ((UInt64)ticks | ((UInt64)kind << KindShift));
- }
-
- internal DateTime(long ticks, DateTimeKind kind, Boolean isAmbiguousDst) {
- if (ticks < MinTicks || ticks > MaxTicks) {
- throw new ArgumentOutOfRangeException(nameof(ticks), Environment.GetResourceString("ArgumentOutOfRange_DateTimeBadTicks"));
- }
- Contract.Requires(kind == DateTimeKind.Local, "Internal Constructor is for local times only");
- Contract.EndContractBlock();
- dateData = ((UInt64)ticks | (isAmbiguousDst ? KindLocalAmbiguousDst : KindLocal));
- }
-
- // Constructs a DateTime from a given year, month, and day. The
- // time-of-day of the resulting DateTime is always midnight.
- //
- public DateTime(int year, int month, int day) {
- this.dateData = (UInt64) DateToTicks(year, month, day);
- }
-
- // Constructs a DateTime from a given year, month, and day for
- // the specified calendar. The
- // time-of-day of the resulting DateTime is always midnight.
- //
- public DateTime(int year, int month, int day, Calendar calendar)
- : this(year, month, day, 0, 0, 0, calendar) {
- }
-
- // Constructs a DateTime from a given year, month, day, hour,
- // minute, and second.
- //
- public DateTime(int year, int month, int day, int hour, int minute, int second) {
- this.dateData = (UInt64)(DateToTicks(year, month, day) + TimeToTicks(hour, minute, second));
- }
-
- public DateTime(int year, int month, int day, int hour, int minute, int second, DateTimeKind kind) {
- if (kind < DateTimeKind.Unspecified || kind > DateTimeKind.Local) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDateTimeKind"), nameof(kind));
- }
- Contract.EndContractBlock();
- Int64 ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
- this.dateData = ((UInt64)ticks | ((UInt64)kind << KindShift));
- }
-
- // Constructs a DateTime from a given year, month, day, hour,
- // minute, and second for the specified calendar.
- //
- public DateTime(int year, int month, int day, int hour, int minute, int second, Calendar calendar) {
- if (calendar == null)
- throw new ArgumentNullException(nameof(calendar));
- Contract.EndContractBlock();
- this.dateData = (UInt64)calendar.ToDateTime(year, month, day, hour, minute, second, 0).Ticks;
- }
-
- // Constructs a DateTime from a given year, month, day, hour,
- // minute, and second.
- //
- public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond) {
- if (millisecond < 0 || millisecond >= MillisPerSecond) {
- throw new ArgumentOutOfRangeException(nameof(millisecond), Environment.GetResourceString("ArgumentOutOfRange_Range", 0, MillisPerSecond - 1));
- }
- Contract.EndContractBlock();
- Int64 ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
- ticks += millisecond * TicksPerMillisecond;
- if (ticks < MinTicks || ticks > MaxTicks)
- throw new ArgumentException(Environment.GetResourceString("Arg_DateTimeRange"));
- this.dateData = (UInt64)ticks;
- }
-
- public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, DateTimeKind kind) {
- if (millisecond < 0 || millisecond >= MillisPerSecond) {
- throw new ArgumentOutOfRangeException(nameof(millisecond), Environment.GetResourceString("ArgumentOutOfRange_Range", 0, MillisPerSecond - 1));
- }
- if (kind < DateTimeKind.Unspecified || kind > DateTimeKind.Local) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDateTimeKind"), nameof(kind));
- }
- Contract.EndContractBlock();
- Int64 ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
- ticks += millisecond * TicksPerMillisecond;
- if (ticks < MinTicks || ticks > MaxTicks)
- throw new ArgumentException(Environment.GetResourceString("Arg_DateTimeRange"));
- this.dateData = ((UInt64)ticks | ((UInt64)kind << KindShift));
- }
-
- // Constructs a DateTime from a given year, month, day, hour,
- // minute, and second for the specified calendar.
- //
- public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar) {
- if (calendar == null)
- throw new ArgumentNullException(nameof(calendar));
- if (millisecond < 0 || millisecond >= MillisPerSecond) {
- throw new ArgumentOutOfRangeException(nameof(millisecond), Environment.GetResourceString("ArgumentOutOfRange_Range", 0, MillisPerSecond - 1));
- }
- Contract.EndContractBlock();
- Int64 ticks = calendar.ToDateTime(year, month, day, hour, minute, second, 0).Ticks;
- ticks += millisecond * TicksPerMillisecond;
- if (ticks < MinTicks || ticks > MaxTicks)
- throw new ArgumentException(Environment.GetResourceString("Arg_DateTimeRange"));
- this.dateData = (UInt64)ticks;
- }
-
- public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar, DateTimeKind kind) {
- if (calendar == null)
- throw new ArgumentNullException(nameof(calendar));
- if (millisecond < 0 || millisecond >= MillisPerSecond) {
- throw new ArgumentOutOfRangeException(nameof(millisecond), Environment.GetResourceString("ArgumentOutOfRange_Range", 0, MillisPerSecond - 1));
- }
- if (kind < DateTimeKind.Unspecified || kind > DateTimeKind.Local) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDateTimeKind"), nameof(kind));
- }
- Contract.EndContractBlock();
- Int64 ticks = calendar.ToDateTime(year, month, day, hour, minute, second, 0).Ticks;
- ticks += millisecond * TicksPerMillisecond;
- if (ticks < MinTicks || ticks > MaxTicks)
- throw new ArgumentException(Environment.GetResourceString("Arg_DateTimeRange"));
- this.dateData = ((UInt64)ticks | ((UInt64)kind << KindShift));
- }
-
- private DateTime(SerializationInfo info, StreamingContext context) {
- if (info==null)
- throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- Boolean foundTicks = false;
- Boolean foundDateData = false;
- Int64 serializedTicks = 0;
- UInt64 serializedDateData = 0;
-
-
- // Get the data
- SerializationInfoEnumerator enumerator = info.GetEnumerator();
- while( enumerator.MoveNext()) {
- switch( enumerator.Name) {
- case TicksField:
- serializedTicks = Convert.ToInt64(enumerator.Value, CultureInfo.InvariantCulture);
- foundTicks = true;
- break;
- case DateDataField:
- serializedDateData = Convert.ToUInt64(enumerator.Value, CultureInfo.InvariantCulture);
- foundDateData = true;
- break;
- default:
- // Ignore other fields for forward compatibility.
- break;
- }
- }
- if (foundDateData) {
- this.dateData = serializedDateData;
- }
- else if (foundTicks) {
- this.dateData = (UInt64)serializedTicks;
- }
- else {
- throw new SerializationException(Environment.GetResourceString("Serialization_MissingDateTimeData"));
- }
- Int64 ticks = InternalTicks;
- if (ticks < MinTicks || ticks > MaxTicks) {
- throw new SerializationException(Environment.GetResourceString("Serialization_DateTimeTicksOutOfRange"));
- }
- }
-
-
-
- internal Int64 InternalTicks {
- get {
- return (Int64)(dateData & TicksMask);
- }
- }
-
- private UInt64 InternalKind {
- get {
- return (dateData & FlagsMask);
- }
- }
-
- // Returns the DateTime resulting from adding the given
- // TimeSpan to this DateTime.
- //
- public DateTime Add(TimeSpan value) {
- return AddTicks(value._ticks);
- }
-
- // Returns the DateTime resulting from adding a fractional number of
- // time units to this DateTime.
- private DateTime Add(double value, int scale) {
- long millis = (long)(value * scale + (value >= 0? 0.5: -0.5));
- if (millis <= -MaxMillis || millis >= MaxMillis)
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_AddValue"));
- return AddTicks(millis * TicksPerMillisecond);
- }
-
- // Returns the DateTime resulting from adding a fractional number of
- // days to this DateTime. The result is computed by rounding the
- // fractional number of days given by value to the nearest
- // millisecond, and adding that interval to this DateTime. The
- // value argument is permitted to be negative.
- //
- public DateTime AddDays(double value) {
- return Add(value, MillisPerDay);
- }
-
- // Returns the DateTime resulting from adding a fractional number of
- // hours to this DateTime. The result is computed by rounding the
- // fractional number of hours given by value to the nearest
- // millisecond, and adding that interval to this DateTime. The
- // value argument is permitted to be negative.
- //
- public DateTime AddHours(double value) {
- return Add(value, MillisPerHour);
- }
-
- // Returns the DateTime resulting from the given number of
- // milliseconds to this DateTime. The result is computed by rounding
- // the number of milliseconds given by value to the nearest integer,
- // and adding that interval to this DateTime. The value
- // argument is permitted to be negative.
- //
- public DateTime AddMilliseconds(double value) {
- return Add(value, 1);
- }
-
- // Returns the DateTime resulting from adding a fractional number of
- // minutes to this DateTime. The result is computed by rounding the
- // fractional number of minutes given by value to the nearest
- // millisecond, and adding that interval to this DateTime. The
- // value argument is permitted to be negative.
- //
- public DateTime AddMinutes(double value) {
- return Add(value, MillisPerMinute);
- }
-
- // Returns the DateTime resulting from adding the given number of
- // months to this DateTime. The result is computed by incrementing
- // (or decrementing) the year and month parts of this DateTime by
- // months months, and, if required, adjusting the day part of the
- // resulting date downwards to the last day of the resulting month in the
- // resulting year. The time-of-day part of the result is the same as the
- // time-of-day part of this DateTime.
- //
- // In more precise terms, considering this DateTime to be of the
- // form y / m / d + t, where y is the
- // year, m is the month, d is the day, and t is the
- // time-of-day, the result is y1 / m1 / d1 + t,
- // where y1 and m1 are computed by adding months months
- // to y and m, and d1 is the largest value less than
- // or equal to d that denotes a valid day in month m1 of year
- // y1.
- //
- public DateTime AddMonths(int months) {
- if (months < -120000 || months > 120000) throw new ArgumentOutOfRangeException(nameof(months), Environment.GetResourceString("ArgumentOutOfRange_DateTimeBadMonths"));
- Contract.EndContractBlock();
- int y = GetDatePart(DatePartYear);
- int m = GetDatePart(DatePartMonth);
- int d = GetDatePart(DatePartDay);
- int i = m - 1 + months;
- if (i >= 0) {
- m = i % 12 + 1;
- y = y + i / 12;
- }
- else {
- m = 12 + (i + 1) % 12;
- y = y + (i - 11) / 12;
- }
- if (y < 1 || y > 9999) {
- throw new ArgumentOutOfRangeException(nameof(months), Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
- }
- int days = DaysInMonth(y, m);
- if (d > days) d = days;
- return new DateTime((UInt64)(DateToTicks(y, m, d) + InternalTicks % TicksPerDay) | InternalKind);
- }
-
- // Returns the DateTime resulting from adding a fractional number of
- // seconds to this DateTime. The result is computed by rounding the
- // fractional number of seconds given by value to the nearest
- // millisecond, and adding that interval to this DateTime. The
- // value argument is permitted to be negative.
- //
- public DateTime AddSeconds(double value) {
- return Add(value, MillisPerSecond);
- }
-
- // Returns the DateTime resulting from adding the given number of
- // 100-nanosecond ticks to this DateTime. The value argument
- // is permitted to be negative.
- //
- public DateTime AddTicks(long value) {
- long ticks = InternalTicks;
- if (value > MaxTicks - ticks || value < MinTicks - ticks) {
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
- }
- return new DateTime((UInt64)(ticks + value) | InternalKind);
- }
-
- // Returns the DateTime resulting from adding the given number of
- // years to this DateTime. The result is computed by incrementing
- // (or decrementing) the year part of this DateTime by value
- // years. If the month and day of this DateTime is 2/29, and if the
- // resulting year is not a leap year, the month and day of the resulting
- // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
- // parts of the result are the same as those of this DateTime.
- //
- public DateTime AddYears(int value) {
- if (value < -10000 || value > 10000)
- {
- // DateTimeOffset.AddYears(int years) is implemented on top of DateTime.AddYears(int value). Use the more appropriate
- // parameter name out of the two for the exception.
- throw new ArgumentOutOfRangeException("years", Environment.GetResourceString("ArgumentOutOfRange_DateTimeBadYears"));
- }
- Contract.EndContractBlock();
- return AddMonths(value * 12);
- }
-
- // Compares two DateTime values, returning an integer that indicates
- // their relationship.
- //
- public static int Compare(DateTime t1, DateTime t2) {
- Int64 ticks1 = t1.InternalTicks;
- Int64 ticks2 = t2.InternalTicks;
- if (ticks1 > ticks2) return 1;
- if (ticks1 < ticks2) return -1;
- return 0;
- }
-
- // Compares this DateTime to a given object. This method provides an
- // implementation of the IComparable interface. The object
- // argument must be another DateTime, or otherwise an exception
- // occurs. Null is considered less than any instance.
- //
- // Returns a value less than zero if this object
- public int CompareTo(Object value) {
- if (value == null) return 1;
- if (!(value is DateTime)) {
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDateTime"));
- }
-
- return Compare(this, (DateTime)value);
- }
-
- public int CompareTo(DateTime value) {
- return Compare(this, value);
- }
-
- // Returns the tick count corresponding to the given year, month, and day.
- // Will check the if the parameters are valid.
- private static long DateToTicks(int year, int month, int day) {
- if (year >= 1 && year <= 9999 && month >= 1 && month <= 12) {
- int[] days = IsLeapYear(year)? DaysToMonth366: DaysToMonth365;
- if (day >= 1 && day <= days[month] - days[month - 1]) {
- int y = year - 1;
- int n = y * 365 + y / 4 - y / 100 + y / 400 + days[month - 1] + day - 1;
- return n * TicksPerDay;
- }
- }
- throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
- }
-
- // Return the tick count corresponding to the given hour, minute, second.
- // Will check the if the parameters are valid.
- private static long TimeToTicks(int hour, int minute, int second)
- {
- //TimeSpan.TimeToTicks is a family access function which does no error checking, so
- //we need to put some error checking out here.
- if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >=0 && second < 60)
- {
- return (TimeSpan.TimeToTicks(hour, minute, second));
- }
- throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadHourMinuteSecond"));
- }
-
- // Returns the number of days in the month given by the year and
- // month arguments.
- //
- public static int DaysInMonth(int year, int month) {
- if (month < 1 || month > 12) throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
- Contract.EndContractBlock();
- // IsLeapYear checks the year argument
- int[] days = IsLeapYear(year)? DaysToMonth366: DaysToMonth365;
- return days[month] - days[month - 1];
- }
-
- // Converts an OLE Date to a tick count.
- // This function is duplicated in COMDateTime.cpp
- internal static long DoubleDateToTicks(double value) {
- // The check done this way will take care of NaN
- if (!(value < OADateMaxAsDouble) || !(value > OADateMinAsDouble))
- throw new ArgumentException(Environment.GetResourceString("Arg_OleAutDateInvalid"));
-
- // Conversion to long will not cause an overflow here, as at this point the "value" is in between OADateMinAsDouble and OADateMaxAsDouble
- long millis = (long)(value * MillisPerDay + (value >= 0? 0.5: -0.5));
- // The interesting thing here is when you have a value like 12.5 it all positive 12 days and 12 hours from 01/01/1899
- // However if you a value of -12.25 it is minus 12 days but still positive 6 hours, almost as though you meant -11.75 all negative
- // This line below fixes up the millis in the negative case
- if (millis < 0) {
- millis -= (millis % MillisPerDay) * 2;
- }
-
- millis += DoubleDateOffset / TicksPerMillisecond;
-
- if (millis < 0 || millis >= MaxMillis) throw new ArgumentException(Environment.GetResourceString("Arg_OleAutDateScale"));
- return millis * TicksPerMillisecond;
- }
-
- // Checks if this DateTime is equal to a given object. Returns
- // true if the given object is a boxed DateTime and its value
- // is equal to the value of this DateTime. Returns false
- // otherwise.
- //
- public override bool Equals(Object value) {
- if (value is DateTime) {
- return InternalTicks == ((DateTime)value).InternalTicks;
- }
- return false;
- }
-
- public bool Equals(DateTime value) {
- return InternalTicks == value.InternalTicks;
- }
-
- // Compares two DateTime values for equality. Returns true if
- // the two DateTime values are equal, or false if they are
- // not equal.
- //
- public static bool Equals(DateTime t1, DateTime t2) {
- return t1.InternalTicks == t2.InternalTicks;
- }
-
- public static DateTime FromBinary(Int64 dateData) {
- if ((dateData & (unchecked( (Int64) LocalMask))) != 0) {
- // Local times need to be adjusted as you move from one time zone to another,
- // just as they are when serializing in text. As such the format for local times
- // changes to store the ticks of the UTC time, but with flags that look like a
- // local date.
- Int64 ticks = dateData & (unchecked((Int64)TicksMask));
- // Negative ticks are stored in the top part of the range and should be converted back into a negative number
- if (ticks > TicksCeiling - TicksPerDay) {
- ticks = ticks - TicksCeiling;
- }
- // Convert the ticks back to local. If the UTC ticks are out of range, we need to default to
- // the UTC offset from MinValue and MaxValue to be consistent with Parse.
- Boolean isAmbiguousLocalDst = false;
- Int64 offsetTicks;
- if (ticks < MinTicks) {
- offsetTicks = TimeZoneInfo.GetLocalUtcOffset(DateTime.MinValue, TimeZoneInfoOptions.NoThrowOnInvalidTime).Ticks;
- }
- else if (ticks > MaxTicks) {
- offsetTicks = TimeZoneInfo.GetLocalUtcOffset(DateTime.MaxValue, TimeZoneInfoOptions.NoThrowOnInvalidTime).Ticks;
- }
- else {
- // Because the ticks conversion between UTC and local is lossy, we need to capture whether the
- // time is in a repeated hour so that it can be passed to the DateTime constructor.
- DateTime utcDt = new DateTime(ticks, DateTimeKind.Utc);
- Boolean isDaylightSavings = false;
- offsetTicks = TimeZoneInfo.GetUtcOffsetFromUtc(utcDt, TimeZoneInfo.Local, out isDaylightSavings, out isAmbiguousLocalDst).Ticks;
- }
- ticks += offsetTicks;
- // Another behaviour of parsing is to cause small times to wrap around, so that they can be used
- // to compare times of day
- if (ticks < 0) {
- ticks += TicksPerDay;
- }
- if (ticks < MinTicks || ticks > MaxTicks) {
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeBadBinaryData"), nameof(dateData));
- }
- return new DateTime(ticks, DateTimeKind.Local, isAmbiguousLocalDst);
- }
- else {
- return DateTime.FromBinaryRaw(dateData);
- }
- }
-
- // A version of ToBinary that uses the real representation and does not adjust local times. This is needed for
- // scenarios where the serialized data must maintain compatibility
- internal static DateTime FromBinaryRaw(Int64 dateData) {
- Int64 ticks = dateData & (Int64)TicksMask;
- if (ticks < MinTicks || ticks > MaxTicks)
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeBadBinaryData"), nameof(dateData));
- return new DateTime((UInt64)dateData);
- }
-
- // Creates a DateTime from a Windows filetime. A Windows filetime is
- // a long representing the date and time as the number of
- // 100-nanosecond intervals that have elapsed since 1/1/1601 12:00am.
- //
- public static DateTime FromFileTime(long fileTime) {
- return FromFileTimeUtc(fileTime).ToLocalTime();
- }
-
- public static DateTime FromFileTimeUtc(long fileTime) {
- if (fileTime < 0 || fileTime > MaxTicks - FileTimeOffset) {
- throw new ArgumentOutOfRangeException(nameof(fileTime), Environment.GetResourceString("ArgumentOutOfRange_FileTimeInvalid"));
- }
- Contract.EndContractBlock();
-
- // This is the ticks in Universal time for this fileTime.
- long universalTicks = fileTime + FileTimeOffset;
- return new DateTime(universalTicks, DateTimeKind.Utc);
- }
-
- // Creates a DateTime from an OLE Automation Date.
- //
- public static DateTime FromOADate(double d) {
- return new DateTime(DoubleDateToTicks(d), DateTimeKind.Unspecified);
- }
-
- void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
- throw new ArgumentNullException(nameof(info));
- }
- Contract.EndContractBlock();
-
- // Serialize both the old and the new format
- info.AddValue(TicksField, InternalTicks);
- info.AddValue(DateDataField, dateData);
- }
-
- public Boolean IsDaylightSavingTime() {
- if (Kind == DateTimeKind.Utc) {
- return false;
- }
- return TimeZoneInfo.Local.IsDaylightSavingTime(this, TimeZoneInfoOptions.NoThrowOnInvalidTime);
- }
-
- public static DateTime SpecifyKind(DateTime value, DateTimeKind kind) {
- return new DateTime(value.InternalTicks, kind);
- }
-
- public Int64 ToBinary() {
- if (Kind == DateTimeKind.Local) {
- // Local times need to be adjusted as you move from one time zone to another,
- // just as they are when serializing in text. As such the format for local times
- // changes to store the ticks of the UTC time, but with flags that look like a
- // local date.
-
- // To match serialization in text we need to be able to handle cases where
- // the UTC value would be out of range. Unused parts of the ticks range are
- // used for this, so that values just past max value are stored just past the
- // end of the maximum range, and values just below minimum value are stored
- // at the end of the ticks area, just below 2^62.
- TimeSpan offset = TimeZoneInfo.GetLocalUtcOffset(this, TimeZoneInfoOptions.NoThrowOnInvalidTime);
- Int64 ticks = Ticks;
- Int64 storedTicks = ticks - offset.Ticks;
- if (storedTicks < 0) {
- storedTicks = TicksCeiling + storedTicks;
- }
- return storedTicks | (unchecked((Int64) LocalMask));
- }
- else {
- return (Int64)dateData;
- }
- }
-
- // Returns the date part of this DateTime. The resulting value
- // corresponds to this DateTime with the time-of-day part set to
- // zero (midnight).
- //
- public DateTime Date {
- get {
- Int64 ticks = InternalTicks;
- return new DateTime((UInt64)(ticks - ticks % TicksPerDay) | InternalKind);
- }
- }
-
- // Returns a given date part of this DateTime. This method is used
- // to compute the year, day-of-year, month, or day part.
- private int GetDatePart(int part) {
- Int64 ticks = InternalTicks;
- // n = number of days since 1/1/0001
- int n = (int)(ticks / TicksPerDay);
- // y400 = number of whole 400-year periods since 1/1/0001
- int y400 = n / DaysPer400Years;
- // n = day number within 400-year period
- n -= y400 * DaysPer400Years;
- // y100 = number of whole 100-year periods within 400-year period
- int y100 = n / DaysPer100Years;
- // Last 100-year period has an extra day, so decrement result if 4
- if (y100 == 4) y100 = 3;
- // n = day number within 100-year period
- n -= y100 * DaysPer100Years;
- // y4 = number of whole 4-year periods within 100-year period
- int y4 = n / DaysPer4Years;
- // n = day number within 4-year period
- n -= y4 * DaysPer4Years;
- // y1 = number of whole years within 4-year period
- int y1 = n / DaysPerYear;
- // Last year has an extra day, so decrement result if 4
- if (y1 == 4) y1 = 3;
- // If year was requested, compute and return it
- if (part == DatePartYear) {
- return y400 * 400 + y100 * 100 + y4 * 4 + y1 + 1;
- }
- // n = day number within year
- n -= y1 * DaysPerYear;
- // If day-of-year was requested, return it
- if (part == DatePartDayOfYear) return n + 1;
- // Leap year calculation looks different from IsLeapYear since y1, y4,
- // and y100 are relative to year 1, not year 0
- bool leapYear = y1 == 3 && (y4 != 24 || y100 == 3);
- int[] days = leapYear? DaysToMonth366: DaysToMonth365;
- // All months have less than 32 days, so n >> 5 is a good conservative
- // estimate for the month
- int m = (n >> 5) + 1;
- // m = 1-based month number
- while (n >= days[m]) m++;
- // If month was requested, return it
- if (part == DatePartMonth) return m;
- // Return 1-based day-of-month
- return n - days[m - 1] + 1;
- }
-
- // Returns the day-of-month part of this DateTime. The returned
- // value is an integer between 1 and 31.
- //
- public int Day {
- get {
- Contract.Ensures(Contract.Result<int>() >= 1);
- Contract.Ensures(Contract.Result<int>() <= 31);
- return GetDatePart(DatePartDay);
- }
- }
-
- // Returns the day-of-week part of this DateTime. The returned value
- // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
- // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
- // Thursday, 5 indicates Friday, and 6 indicates Saturday.
- //
- public DayOfWeek DayOfWeek {
- get {
- Contract.Ensures(Contract.Result<DayOfWeek>() >= DayOfWeek.Sunday);
- Contract.Ensures(Contract.Result<DayOfWeek>() <= DayOfWeek.Saturday);
- return (DayOfWeek)((InternalTicks / TicksPerDay + 1) % 7);
- }
- }
-
- // Returns the day-of-year part of this DateTime. The returned value
- // is an integer between 1 and 366.
- //
- public int DayOfYear {
- get {
- Contract.Ensures(Contract.Result<int>() >= 1);
- Contract.Ensures(Contract.Result<int>() <= 366); // leap year
- return GetDatePart(DatePartDayOfYear);
- }
- }
-
- // Returns the hash code for this DateTime.
- //
- public override int GetHashCode() {
- Int64 ticks = InternalTicks;
- return unchecked((int)ticks) ^ (int)(ticks >> 32);
- }
-
- // Returns the hour part of this DateTime. The returned value is an
- // integer between 0 and 23.
- //
- public int Hour {
- get {
- Contract.Ensures(Contract.Result<int>() >= 0);
- Contract.Ensures(Contract.Result<int>() < 24);
- return (int)((InternalTicks / TicksPerHour) % 24);
- }
- }
-
- internal Boolean IsAmbiguousDaylightSavingTime() {
- return (InternalKind == KindLocalAmbiguousDst);
- }
-
- [Pure]
- public DateTimeKind Kind {
- get {
- switch (InternalKind) {
- case KindUnspecified:
- return DateTimeKind.Unspecified;
- case KindUtc:
- return DateTimeKind.Utc;
- default:
- return DateTimeKind.Local;
- }
- }
- }
-
- // Returns the millisecond part of this DateTime. The returned value
- // is an integer between 0 and 999.
- //
- public int Millisecond {
- get {
- Contract.Ensures(Contract.Result<int>() >= 0);
- Contract.Ensures(Contract.Result<int>() < 1000);
- return (int)((InternalTicks/ TicksPerMillisecond) % 1000);
- }
- }
-
- // Returns the minute part of this DateTime. The returned value is
- // an integer between 0 and 59.
- //
- public int Minute {
- get {
- Contract.Ensures(Contract.Result<int>() >= 0);
- Contract.Ensures(Contract.Result<int>() < 60);
- return (int)((InternalTicks / TicksPerMinute) % 60);
- }
- }
-
- // Returns the month part of this DateTime. The returned value is an
- // integer between 1 and 12.
- //
- public int Month {
- get {
- Contract.Ensures(Contract.Result<int>() >= 1);
- return GetDatePart(DatePartMonth);
- }
- }
-
- // Returns a DateTime representing the current date and time. The
- // resolution of the returned value depends on the system timer. For
- // Windows NT 3.5 and later the timer resolution is approximately 10ms,
- // for Windows NT 3.1 it is approximately 16ms, and for Windows 95 and 98
- // it is approximately 55ms.
- //
- public static DateTime Now {
- get {
- Contract.Ensures(Contract.Result<DateTime>().Kind == DateTimeKind.Local);
-
- DateTime utc = UtcNow;
- Boolean isAmbiguousLocalDst = false;
- Int64 offset = TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(utc, out isAmbiguousLocalDst).Ticks;
- long tick = utc.Ticks + offset;
- if (tick>DateTime.MaxTicks) {
- return new DateTime(DateTime.MaxTicks, DateTimeKind.Local);
- }
- if (tick<DateTime.MinTicks) {
- return new DateTime(DateTime.MinTicks, DateTimeKind.Local);
- }
- return new DateTime(tick, DateTimeKind.Local, isAmbiguousLocalDst);
- }
- }
-
- public static DateTime UtcNow {
- get {
- Contract.Ensures(Contract.Result<DateTime>().Kind == DateTimeKind.Utc);
- // following code is tuned for speed. Don't change it without running benchmark.
- long ticks = 0;
- ticks = GetSystemTimeAsFileTime();
-
- return new DateTime( ((UInt64)(ticks + FileTimeOffset)) | KindUtc);
- }
- }
-
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern long GetSystemTimeAsFileTime();
-
-
-
- // Returns the second part of this DateTime. The returned value is
- // an integer between 0 and 59.
- //
- public int Second {
- get {
- Contract.Ensures(Contract.Result<int>() >= 0);
- Contract.Ensures(Contract.Result<int>() < 60);
- return (int)((InternalTicks / TicksPerSecond) % 60);
- }
- }
-
- // Returns the tick count for this DateTime. The returned value is
- // the number of 100-nanosecond intervals that have elapsed since 1/1/0001
- // 12:00am.
- //
- public long Ticks {
- get {
- return InternalTicks;
- }
- }
-
- // Returns the time-of-day part of this DateTime. The returned value
- // is a TimeSpan that indicates the time elapsed since midnight.
- //
- public TimeSpan TimeOfDay {
- get {
- return new TimeSpan(InternalTicks % TicksPerDay);
- }
- }
-
- // Returns a DateTime representing the current date. The date part
- // of the returned value is the current date, and the time-of-day part of
- // the returned value is zero (midnight).
- //
- public static DateTime Today {
- get {
- return DateTime.Now.Date;
- }
- }
-
- // Returns the year part of this DateTime. The returned value is an
- // integer between 1 and 9999.
- //
- public int Year {
- get {
- Contract.Ensures(Contract.Result<int>() >= 1 && Contract.Result<int>() <= 9999);
- return GetDatePart(DatePartYear);
- }
- }
-
- // Checks whether a given year is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
- public static bool IsLeapYear(int year) {
- if (year < 1 || year > 9999) {
- throw new ArgumentOutOfRangeException(nameof(year), Environment.GetResourceString("ArgumentOutOfRange_Year"));
- }
- Contract.EndContractBlock();
- return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
- }
-
- // Constructs a DateTime from a string. The string must specify a
- // date and optionally a time in a culture-specific or universal format.
- // Leading and trailing whitespace characters are allowed.
- //
- public static DateTime Parse(String s) {
- return (DateTimeParse.Parse(s, DateTimeFormatInfo.CurrentInfo, DateTimeStyles.None));
- }
-
- // Constructs a DateTime from a string. The string must specify a
- // date and optionally a time in a culture-specific or universal format.
- // Leading and trailing whitespace characters are allowed.
- //
- public static DateTime Parse(String s, IFormatProvider provider) {
- return (DateTimeParse.Parse(s, DateTimeFormatInfo.GetInstance(provider), DateTimeStyles.None));
- }
-
- public static DateTime Parse(String s, IFormatProvider provider, DateTimeStyles styles) {
- DateTimeFormatInfo.ValidateStyles(styles, nameof(styles));
- return (DateTimeParse.Parse(s, DateTimeFormatInfo.GetInstance(provider), styles));
- }
-
- // Constructs a DateTime from a string. The string must specify a
- // date and optionally a time in a culture-specific or universal format.
- // Leading and trailing whitespace characters are allowed.
- //
- public static DateTime ParseExact(String s, String format, IFormatProvider provider) {
- return (DateTimeParse.ParseExact(s, format, DateTimeFormatInfo.GetInstance(provider), DateTimeStyles.None));
- }
-
- // Constructs a DateTime from a string. The string must specify a
- // date and optionally a time in a culture-specific or universal format.
- // Leading and trailing whitespace characters are allowed.
- //
- public static DateTime ParseExact(String s, String format, IFormatProvider provider, DateTimeStyles style) {
- DateTimeFormatInfo.ValidateStyles(style, nameof(style));
- return (DateTimeParse.ParseExact(s, format, DateTimeFormatInfo.GetInstance(provider), style));
- }
-
- public static DateTime ParseExact(String s, String[] formats, IFormatProvider provider, DateTimeStyles style) {
- DateTimeFormatInfo.ValidateStyles(style, nameof(style));
- return DateTimeParse.ParseExactMultiple(s, formats, DateTimeFormatInfo.GetInstance(provider), style);
- }
-
- public TimeSpan Subtract(DateTime value) {
- return new TimeSpan(InternalTicks - value.InternalTicks);
- }
-
- public DateTime Subtract(TimeSpan value) {
- long ticks = InternalTicks;
- long valueTicks = value._ticks;
- if (ticks - MinTicks < valueTicks || ticks - MaxTicks > valueTicks) {
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
- }
- return new DateTime((UInt64)(ticks - valueTicks) | InternalKind);
- }
-
- // This function is duplicated in COMDateTime.cpp
- private static double TicksToOADate(long value) {
- if (value == 0)
- return 0.0; // Returns OleAut's zero'ed date value.
- if (value < TicksPerDay) // This is a fix for VB. They want the default day to be 1/1/0001 rathar then 12/30/1899.
- value += DoubleDateOffset; // We could have moved this fix down but we would like to keep the bounds check.
- if (value < OADateMinAsTicks)
- throw new OverflowException(Environment.GetResourceString("Arg_OleAutDateInvalid"));
- // Currently, our max date == OA's max date (12/31/9999), so we don't
- // need an overflow check in that direction.
- long millis = (value - DoubleDateOffset) / TicksPerMillisecond;
- if (millis < 0) {
- long frac = millis % MillisPerDay;
- if (frac != 0) millis -= (MillisPerDay + frac) * 2;
- }
- return (double)millis / MillisPerDay;
- }
-
- // Converts the DateTime instance into an OLE Automation compatible
- // double date.
- public double ToOADate() {
- return TicksToOADate(InternalTicks);
- }
-
- public long ToFileTime() {
- // Treats the input as local if it is not specified
- return ToUniversalTime().ToFileTimeUtc();
- }
-
- public long ToFileTimeUtc() {
- // Treats the input as universal if it is not specified
- long ticks = ((InternalKind & LocalMask) != 0) ? ToUniversalTime().InternalTicks : this.InternalTicks;
- ticks -= FileTimeOffset;
- if (ticks < 0) {
- throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_FileTimeInvalid"));
- }
- return ticks;
- }
-
- public DateTime ToLocalTime()
- {
- return ToLocalTime(false);
- }
-
- internal DateTime ToLocalTime(bool throwOnOverflow)
- {
- if (Kind == DateTimeKind.Local) {
- return this;
- }
- Boolean isDaylightSavings = false;
- Boolean isAmbiguousLocalDst = false;
- Int64 offset = TimeZoneInfo.GetUtcOffsetFromUtc(this, TimeZoneInfo.Local, out isDaylightSavings, out isAmbiguousLocalDst).Ticks;
- long tick = Ticks + offset;
- if (tick > DateTime.MaxTicks)
- {
- if (throwOnOverflow)
- throw new ArgumentException(Environment.GetResourceString("Arg_ArgumentOutOfRangeException"));
- else
- return new DateTime(DateTime.MaxTicks, DateTimeKind.Local);
- }
- if (tick < DateTime.MinTicks)
- {
- if (throwOnOverflow)
- throw new ArgumentException(Environment.GetResourceString("Arg_ArgumentOutOfRangeException"));
- else
- return new DateTime(DateTime.MinTicks, DateTimeKind.Local);
- }
- return new DateTime(tick, DateTimeKind.Local, isAmbiguousLocalDst);
- }
-
- public String ToLongDateString() {
- Contract.Ensures(Contract.Result<String>() != null);
- return DateTimeFormat.Format(this, "D", DateTimeFormatInfo.CurrentInfo);
- }
-
- public String ToLongTimeString() {
- Contract.Ensures(Contract.Result<String>() != null);
- return DateTimeFormat.Format(this, "T", DateTimeFormatInfo.CurrentInfo);
- }
-
- public String ToShortDateString() {
- Contract.Ensures(Contract.Result<String>() != null);
- return DateTimeFormat.Format(this, "d", DateTimeFormatInfo.CurrentInfo);
- }
-
- public String ToShortTimeString() {
- Contract.Ensures(Contract.Result<String>() != null);
- return DateTimeFormat.Format(this, "t", DateTimeFormatInfo.CurrentInfo);
- }
-
- public override String ToString() {
- Contract.Ensures(Contract.Result<String>() != null);
- return DateTimeFormat.Format(this, null, DateTimeFormatInfo.CurrentInfo);
- }
-
- public String ToString(String format) {
- Contract.Ensures(Contract.Result<String>() != null);
- return DateTimeFormat.Format(this, format, DateTimeFormatInfo.CurrentInfo);
- }
-
- public String ToString(IFormatProvider provider) {
- Contract.Ensures(Contract.Result<String>() != null);
- return DateTimeFormat.Format(this, null, DateTimeFormatInfo.GetInstance(provider));
- }
-
- public String ToString(String format, IFormatProvider provider) {
- Contract.Ensures(Contract.Result<String>() != null);
- return DateTimeFormat.Format(this, format, DateTimeFormatInfo.GetInstance(provider));
- }
-
- public DateTime ToUniversalTime() {
- return TimeZoneInfo.ConvertTimeToUtc(this, TimeZoneInfoOptions.NoThrowOnInvalidTime);
- }
-
- public static Boolean TryParse(String s, out DateTime result) {
- return DateTimeParse.TryParse(s, DateTimeFormatInfo.CurrentInfo, DateTimeStyles.None, out result);
- }
-
- public static Boolean TryParse(String s, IFormatProvider provider, DateTimeStyles styles, out DateTime result) {
- DateTimeFormatInfo.ValidateStyles(styles, nameof(styles));
- return DateTimeParse.TryParse(s, DateTimeFormatInfo.GetInstance(provider), styles, out result);
- }
-
- public static Boolean TryParseExact(String s, String format, IFormatProvider provider, DateTimeStyles style, out DateTime result) {
- DateTimeFormatInfo.ValidateStyles(style, nameof(style));
- return DateTimeParse.TryParseExact(s, format, DateTimeFormatInfo.GetInstance(provider), style, out result);
- }
-
- public static Boolean TryParseExact(String s, String[] formats, IFormatProvider provider, DateTimeStyles style, out DateTime result) {
- DateTimeFormatInfo.ValidateStyles(style, nameof(style));
- return DateTimeParse.TryParseExactMultiple(s, formats, DateTimeFormatInfo.GetInstance(provider), style, out result);
- }
-
- public static DateTime operator +(DateTime d, TimeSpan t) {
- long ticks = d.InternalTicks;
- long valueTicks = t._ticks;
- if (valueTicks > MaxTicks - ticks || valueTicks < MinTicks - ticks) {
- throw new ArgumentOutOfRangeException(nameof(t), Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
- }
- return new DateTime((UInt64)(ticks + valueTicks) | d.InternalKind);
- }
-
- public static DateTime operator -(DateTime d, TimeSpan t) {
- long ticks = d.InternalTicks;
- long valueTicks = t._ticks;
- if (ticks - MinTicks < valueTicks || ticks - MaxTicks > valueTicks) {
- throw new ArgumentOutOfRangeException(nameof(t), Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
- }
- return new DateTime((UInt64)(ticks - valueTicks) | d.InternalKind);
- }
-
- public static TimeSpan operator -(DateTime d1, DateTime d2) {
- return new TimeSpan(d1.InternalTicks - d2.InternalTicks);
- }
-
- public static bool operator ==(DateTime d1, DateTime d2) {
- return d1.InternalTicks == d2.InternalTicks;
- }
-
- public static bool operator !=(DateTime d1, DateTime d2) {
- return d1.InternalTicks != d2.InternalTicks;
- }
-
- public static bool operator <(DateTime t1, DateTime t2) {
- return t1.InternalTicks < t2.InternalTicks;
- }
-
- public static bool operator <=(DateTime t1, DateTime t2) {
- return t1.InternalTicks <= t2.InternalTicks;
- }
-
- public static bool operator >(DateTime t1, DateTime t2) {
- return t1.InternalTicks > t2.InternalTicks;
- }
-
- public static bool operator >=(DateTime t1, DateTime t2) {
- return t1.InternalTicks >= t2.InternalTicks;
- }
-
-
- // Returns a string array containing all of the known date and time options for the
- // current culture. The strings returned are properly formatted date and
- // time strings for the current instance of DateTime.
- public String[] GetDateTimeFormats()
- {
- Contract.Ensures(Contract.Result<String[]>() != null);
- return (GetDateTimeFormats(CultureInfo.CurrentCulture));
- }
-
- // Returns a string array containing all of the known date and time options for the
- // using the information provided by IFormatProvider. The strings returned are properly formatted date and
- // time strings for the current instance of DateTime.
- public String[] GetDateTimeFormats(IFormatProvider provider)
- {
- Contract.Ensures(Contract.Result<String[]>() != null);
- return (DateTimeFormat.GetAllDateTimes(this, DateTimeFormatInfo.GetInstance(provider)));
- }
-
-
- // Returns a string array containing all of the date and time options for the
- // given format format and current culture. The strings returned are properly formatted date and
- // time strings for the current instance of DateTime.
- public String[] GetDateTimeFormats(char format)
- {
- Contract.Ensures(Contract.Result<String[]>() != null);
- return (GetDateTimeFormats(format, CultureInfo.CurrentCulture));
- }
-
- // Returns a string array containing all of the date and time options for the
- // given format format and given culture. The strings returned are properly formatted date and
- // time strings for the current instance of DateTime.
- public String[] GetDateTimeFormats(char format, IFormatProvider provider)
- {
- Contract.Ensures(Contract.Result<String[]>() != null);
- return (DateTimeFormat.GetAllDateTimes(this, format, DateTimeFormatInfo.GetInstance(provider)));
- }
-
- //
- // IConvertible implementation
- //
-
- public TypeCode GetTypeCode() {
- return TypeCode.DateTime;
- }
-
-
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "DateTime", "Boolean"));
- }
-
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "DateTime", "Char"));
- }
-
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "DateTime", "SByte"));
- }
-
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "DateTime", "Byte"));
- }
-
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "DateTime", "Int16"));
- }
-
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "DateTime", "UInt16"));
- }
-
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "DateTime", "Int32"));
- }
-
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "DateTime", "UInt32"));
- }
-
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "DateTime", "Int64"));
- }
-
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "DateTime", "UInt64"));
- }
-
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "DateTime", "Single"));
- }
-
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "DateTime", "Double"));
- }
-
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "DateTime", "Decimal"));
- }
-
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
- return this;
- }
-
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
- return Convert.DefaultToType((IConvertible)this, type, provider);
- }
-
- // Tries to construct a DateTime from a given year, month, day, hour,
- // minute, second and millisecond.
- //
- internal static Boolean TryCreate(int year, int month, int day, int hour, int minute, int second, int millisecond, out DateTime result) {
- result = DateTime.MinValue;
- if (year < 1 || year > 9999 || month < 1 || month > 12) {
- return false;
- }
- int[] days = IsLeapYear(year) ? DaysToMonth366 : DaysToMonth365;
- if (day < 1 || day > days[month] - days[month - 1]) {
- return false;
- }
- if (hour < 0 || hour >= 24 || minute < 0 || minute >= 60 || second < 0 || second >= 60) {
- return false;
- }
- if (millisecond < 0 || millisecond >= MillisPerSecond) {
- return false;
- }
- long ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
-
- ticks += millisecond * TicksPerMillisecond;
- if (ticks < MinTicks || ticks > MaxTicks) {
- return false;
- }
- result = new DateTime(ticks, DateTimeKind.Unspecified);
- return true;
- }
- }
-}
diff --git a/src/mscorlib/src/System/DateTimeOffset.cs b/src/mscorlib/src/System/DateTimeOffset.cs
deleted file mode 100644
index d64ba1582e..0000000000
--- a/src/mscorlib/src/System/DateTimeOffset.cs
+++ /dev/null
@@ -1,830 +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.
-
-namespace System {
-
- using System;
- using System.Threading;
- using System.Globalization;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Runtime.Serialization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- // DateTimeOffset is a value type that consists of a DateTime and a time zone offset,
- // ie. how far away the time is from GMT. The DateTime is stored whole, and the offset
- // is stored as an Int16 internally to save space, but presented as a TimeSpan.
- //
- // The range is constrained so that both the represented clock time and the represented
- // UTC time fit within the boundaries of MaxValue. This gives it the same range as DateTime
- // for actual UTC times, and a slightly constrained range on one end when an offset is
- // present.
- //
- // This class should be substitutable for date time in most cases; so most operations
- // effectively work on the clock time. However, the underlying UTC time is what counts
- // for the purposes of identity, sorting and subtracting two instances.
- //
- //
- // There are theoretically two date times stored, the UTC and the relative local representation
- // or the 'clock' time. It actually does not matter which is stored in m_dateTime, so it is desirable
- // for most methods to go through the helpers UtcDateTime and ClockDateTime both to abstract this
- // out and for internal readability.
-
- [StructLayout(LayoutKind.Auto)]
- [Serializable]
- public struct DateTimeOffset : IComparable, IFormattable,
- IComparable<DateTimeOffset>, IEquatable<DateTimeOffset>, ISerializable, IDeserializationCallback
- {
- // Constants
- internal const Int64 MaxOffset = TimeSpan.TicksPerHour * 14;
- internal const Int64 MinOffset = -MaxOffset;
-
- private const long UnixEpochTicks = TimeSpan.TicksPerDay * DateTime.DaysTo1970; // 621,355,968,000,000,000
- private const long UnixEpochSeconds = UnixEpochTicks / TimeSpan.TicksPerSecond; // 62,135,596,800
- private const long UnixEpochMilliseconds = UnixEpochTicks / TimeSpan.TicksPerMillisecond; // 62,135,596,800,000
-
- internal const long UnixMinSeconds = DateTime.MinTicks / TimeSpan.TicksPerSecond - UnixEpochSeconds;
- internal const long UnixMaxSeconds = DateTime.MaxTicks / TimeSpan.TicksPerSecond - UnixEpochSeconds;
-
- // Static Fields
- public static readonly DateTimeOffset MinValue = new DateTimeOffset(DateTime.MinTicks, TimeSpan.Zero);
- public static readonly DateTimeOffset MaxValue = new DateTimeOffset(DateTime.MaxTicks, TimeSpan.Zero);
-
- // Instance Fields
- private DateTime m_dateTime;
- private Int16 m_offsetMinutes;
-
- // Constructors
-
- // Constructs a DateTimeOffset from a tick count and offset
- public DateTimeOffset(long ticks, TimeSpan offset) {
- m_offsetMinutes = ValidateOffset(offset);
- // Let the DateTime constructor do the range checks
- DateTime dateTime = new DateTime(ticks);
- m_dateTime = ValidateDate(dateTime, offset);
- }
-
- // Constructs a DateTimeOffset from a DateTime. For Local and Unspecified kinds,
- // extracts the local offset. For UTC, creates a UTC instance with a zero offset.
- public DateTimeOffset(DateTime dateTime) {
- TimeSpan offset;
- if (dateTime.Kind != DateTimeKind.Utc) {
- // Local and Unspecified are both treated as Local
- offset = TimeZoneInfo.GetLocalUtcOffset(dateTime, TimeZoneInfoOptions.NoThrowOnInvalidTime);
- }
- else {
- offset = new TimeSpan(0);
- }
- m_offsetMinutes = ValidateOffset(offset);
- m_dateTime = ValidateDate(dateTime, offset);
- }
-
- // Constructs a DateTimeOffset from a DateTime. And an offset. Always makes the clock time
- // consistent with the DateTime. For Utc ensures the offset is zero. For local, ensures that
- // the offset corresponds to the local.
- public DateTimeOffset(DateTime dateTime, TimeSpan offset) {
- if (dateTime.Kind == DateTimeKind.Local) {
- if (offset != TimeZoneInfo.GetLocalUtcOffset(dateTime, TimeZoneInfoOptions.NoThrowOnInvalidTime)) {
- throw new ArgumentException(Environment.GetResourceString("Argument_OffsetLocalMismatch"), nameof(offset));
- }
- }
- else if (dateTime.Kind == DateTimeKind.Utc) {
- if (offset != TimeSpan.Zero) {
- throw new ArgumentException(Environment.GetResourceString("Argument_OffsetUtcMismatch"), nameof(offset));
- }
- }
- m_offsetMinutes = ValidateOffset(offset);
- m_dateTime = ValidateDate(dateTime, offset);
- }
-
- // Constructs a DateTimeOffset from a given year, month, day, hour,
- // minute, second and offset.
- public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, TimeSpan offset) {
- m_offsetMinutes = ValidateOffset(offset);
- m_dateTime = ValidateDate(new DateTime(year, month, day, hour, minute, second), offset);
- }
-
- // Constructs a DateTimeOffset from a given year, month, day, hour,
- // minute, second, millsecond and offset
- public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, int millisecond, TimeSpan offset) {
- m_offsetMinutes = ValidateOffset(offset);
- m_dateTime = ValidateDate(new DateTime(year, month, day, hour, minute, second, millisecond), offset);
- }
-
-
- // Constructs a DateTimeOffset from a given year, month, day, hour,
- // minute, second, millsecond, Calendar and offset.
- public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar, TimeSpan offset) {
- m_offsetMinutes = ValidateOffset(offset);
- m_dateTime = ValidateDate(new DateTime(year, month, day, hour, minute, second, millisecond, calendar), offset);
- }
-
- // Returns a DateTimeOffset representing the current date and time. The
- // resolution of the returned value depends on the system timer. For
- // Windows NT 3.5 and later the timer resolution is approximately 10ms,
- // for Windows NT 3.1 it is approximately 16ms, and for Windows 95 and 98
- // it is approximately 55ms.
- //
- public static DateTimeOffset Now {
- get {
- return new DateTimeOffset(DateTime.Now);
- }
- }
-
- public static DateTimeOffset UtcNow {
- get {
- return new DateTimeOffset(DateTime.UtcNow);
- }
- }
-
- public DateTime DateTime {
- get {
- return ClockDateTime;
- }
- }
-
- public DateTime UtcDateTime {
- [Pure]
- get {
- Contract.Ensures(Contract.Result<DateTime>().Kind == DateTimeKind.Utc);
- return DateTime.SpecifyKind(m_dateTime, DateTimeKind.Utc);
- }
- }
-
- public DateTime LocalDateTime {
- [Pure]
- get {
- Contract.Ensures(Contract.Result<DateTime>().Kind == DateTimeKind.Local);
- return UtcDateTime.ToLocalTime();
- }
- }
-
- // Adjust to a given offset with the same UTC time. Can throw ArgumentException
- //
- public DateTimeOffset ToOffset(TimeSpan offset) {
- return new DateTimeOffset((m_dateTime + offset).Ticks, offset);
- }
-
-
- // Instance Properties
-
- // The clock or visible time represented. This is just a wrapper around the internal date because this is
- // the chosen storage mechanism. Going through this helper is good for readability and maintainability.
- // This should be used for display but not identity.
- private DateTime ClockDateTime {
- get {
- return new DateTime((m_dateTime + Offset).Ticks, DateTimeKind.Unspecified);
- }
- }
-
- // Returns the date part of this DateTimeOffset. The resulting value
- // corresponds to this DateTimeOffset with the time-of-day part set to
- // zero (midnight).
- //
- public DateTime Date {
- get {
- return ClockDateTime.Date;
- }
- }
-
- // Returns the day-of-month part of this DateTimeOffset. The returned
- // value is an integer between 1 and 31.
- //
- public int Day {
- get {
- Contract.Ensures(Contract.Result<int>() >= 1);
- Contract.Ensures(Contract.Result<int>() <= 31);
- return ClockDateTime.Day;
- }
- }
-
- // Returns the day-of-week part of this DateTimeOffset. The returned value
- // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
- // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
- // Thursday, 5 indicates Friday, and 6 indicates Saturday.
- //
- public DayOfWeek DayOfWeek {
- get {
- Contract.Ensures(Contract.Result<DayOfWeek>() >= DayOfWeek.Sunday);
- Contract.Ensures(Contract.Result<DayOfWeek>() <= DayOfWeek.Saturday);
- return ClockDateTime.DayOfWeek;
- }
- }
-
- // Returns the day-of-year part of this DateTimeOffset. The returned value
- // is an integer between 1 and 366.
- //
- public int DayOfYear {
- get {
- Contract.Ensures(Contract.Result<int>() >= 1);
- Contract.Ensures(Contract.Result<int>() <= 366); // leap year
- return ClockDateTime.DayOfYear;
- }
- }
-
- // Returns the hour part of this DateTimeOffset. The returned value is an
- // integer between 0 and 23.
- //
- public int Hour {
- get {
- Contract.Ensures(Contract.Result<int>() >= 0);
- Contract.Ensures(Contract.Result<int>() < 24);
- return ClockDateTime.Hour;
- }
- }
-
-
- // Returns the millisecond part of this DateTimeOffset. The returned value
- // is an integer between 0 and 999.
- //
- public int Millisecond {
- get {
- Contract.Ensures(Contract.Result<int>() >= 0);
- Contract.Ensures(Contract.Result<int>() < 1000);
- return ClockDateTime.Millisecond;
- }
- }
-
- // Returns the minute part of this DateTimeOffset. The returned value is
- // an integer between 0 and 59.
- //
- public int Minute {
- get {
- Contract.Ensures(Contract.Result<int>() >= 0);
- Contract.Ensures(Contract.Result<int>() < 60);
- return ClockDateTime.Minute;
- }
- }
-
- // Returns the month part of this DateTimeOffset. The returned value is an
- // integer between 1 and 12.
- //
- public int Month {
- get {
- Contract.Ensures(Contract.Result<int>() >= 1);
- return ClockDateTime.Month;
- }
- }
-
- public TimeSpan Offset {
- get {
- return new TimeSpan(0, m_offsetMinutes, 0);
- }
- }
-
- // Returns the second part of this DateTimeOffset. The returned value is
- // an integer between 0 and 59.
- //
- public int Second {
- get {
- Contract.Ensures(Contract.Result<int>() >= 0);
- Contract.Ensures(Contract.Result<int>() < 60);
- return ClockDateTime.Second;
- }
- }
-
- // Returns the tick count for this DateTimeOffset. The returned value is
- // the number of 100-nanosecond intervals that have elapsed since 1/1/0001
- // 12:00am.
- //
- public long Ticks {
- get {
- return ClockDateTime.Ticks;
- }
- }
-
- public long UtcTicks {
- get {
- return UtcDateTime.Ticks;
- }
- }
-
- // Returns the time-of-day part of this DateTimeOffset. The returned value
- // is a TimeSpan that indicates the time elapsed since midnight.
- //
- public TimeSpan TimeOfDay {
- get {
- return ClockDateTime.TimeOfDay;
- }
- }
-
- // Returns the year part of this DateTimeOffset. The returned value is an
- // integer between 1 and 9999.
- //
- public int Year {
- get {
- Contract.Ensures(Contract.Result<int>() >= 1 && Contract.Result<int>() <= 9999);
- return ClockDateTime.Year;
- }
- }
-
- // Returns the DateTimeOffset resulting from adding the given
- // TimeSpan to this DateTimeOffset.
- //
- public DateTimeOffset Add(TimeSpan timeSpan) {
- return new DateTimeOffset(ClockDateTime.Add(timeSpan), Offset);
- }
-
- // Returns the DateTimeOffset resulting from adding a fractional number of
- // days to this DateTimeOffset. The result is computed by rounding the
- // fractional number of days given by value to the nearest
- // millisecond, and adding that interval to this DateTimeOffset. The
- // value argument is permitted to be negative.
- //
- public DateTimeOffset AddDays(double days) {
- return new DateTimeOffset(ClockDateTime.AddDays(days), Offset);
- }
-
- // Returns the DateTimeOffset resulting from adding a fractional number of
- // hours to this DateTimeOffset. The result is computed by rounding the
- // fractional number of hours given by value to the nearest
- // millisecond, and adding that interval to this DateTimeOffset. The
- // value argument is permitted to be negative.
- //
- public DateTimeOffset AddHours(double hours) {
- return new DateTimeOffset(ClockDateTime.AddHours(hours), Offset);
- }
-
- // Returns the DateTimeOffset resulting from the given number of
- // milliseconds to this DateTimeOffset. The result is computed by rounding
- // the number of milliseconds given by value to the nearest integer,
- // and adding that interval to this DateTimeOffset. The value
- // argument is permitted to be negative.
- //
- public DateTimeOffset AddMilliseconds(double milliseconds) {
- return new DateTimeOffset(ClockDateTime.AddMilliseconds(milliseconds), Offset);
- }
-
- // Returns the DateTimeOffset resulting from adding a fractional number of
- // minutes to this DateTimeOffset. The result is computed by rounding the
- // fractional number of minutes given by value to the nearest
- // millisecond, and adding that interval to this DateTimeOffset. The
- // value argument is permitted to be negative.
- //
- public DateTimeOffset AddMinutes(double minutes) {
- return new DateTimeOffset(ClockDateTime.AddMinutes(minutes), Offset);
- }
-
- public DateTimeOffset AddMonths(int months) {
- return new DateTimeOffset(ClockDateTime.AddMonths(months), Offset);
- }
-
- // Returns the DateTimeOffset resulting from adding a fractional number of
- // seconds to this DateTimeOffset. The result is computed by rounding the
- // fractional number of seconds given by value to the nearest
- // millisecond, and adding that interval to this DateTimeOffset. The
- // value argument is permitted to be negative.
- //
- public DateTimeOffset AddSeconds(double seconds) {
- return new DateTimeOffset(ClockDateTime.AddSeconds(seconds), Offset);
- }
-
- // Returns the DateTimeOffset resulting from adding the given number of
- // 100-nanosecond ticks to this DateTimeOffset. The value argument
- // is permitted to be negative.
- //
- public DateTimeOffset AddTicks(long ticks) {
- return new DateTimeOffset(ClockDateTime.AddTicks(ticks), Offset);
- }
-
- // Returns the DateTimeOffset resulting from adding the given number of
- // years to this DateTimeOffset. The result is computed by incrementing
- // (or decrementing) the year part of this DateTimeOffset by value
- // years. If the month and day of this DateTimeOffset is 2/29, and if the
- // resulting year is not a leap year, the month and day of the resulting
- // DateTimeOffset becomes 2/28. Otherwise, the month, day, and time-of-day
- // parts of the result are the same as those of this DateTimeOffset.
- //
- public DateTimeOffset AddYears(int years) {
- return new DateTimeOffset(ClockDateTime.AddYears(years), Offset);
- }
-
- // Compares two DateTimeOffset values, returning an integer that indicates
- // their relationship.
- //
- public static int Compare(DateTimeOffset first, DateTimeOffset second) {
- return DateTime.Compare(first.UtcDateTime, second.UtcDateTime);
- }
-
- // Compares this DateTimeOffset to a given object. This method provides an
- // implementation of the IComparable interface. The object
- // argument must be another DateTimeOffset, or otherwise an exception
- // occurs. Null is considered less than any instance.
- //
- int IComparable.CompareTo(Object obj) {
- if (obj == null) return 1;
- if (!(obj is DateTimeOffset)) {
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDateTimeOffset"));
- }
-
- DateTime objUtc = ((DateTimeOffset)obj).UtcDateTime;
- DateTime utc = UtcDateTime;
- if (utc > objUtc) return 1;
- if (utc < objUtc) return -1;
- return 0;
- }
-
- public int CompareTo(DateTimeOffset other) {
- DateTime otherUtc = other.UtcDateTime;
- DateTime utc = UtcDateTime;
- if (utc > otherUtc) return 1;
- if (utc < otherUtc) return -1;
- return 0;
- }
-
-
- // Checks if this DateTimeOffset is equal to a given object. Returns
- // true if the given object is a boxed DateTimeOffset and its value
- // is equal to the value of this DateTimeOffset. Returns false
- // otherwise.
- //
- public override bool Equals(Object obj) {
- if (obj is DateTimeOffset) {
- return UtcDateTime.Equals(((DateTimeOffset)obj).UtcDateTime);
- }
- return false;
- }
-
- public bool Equals(DateTimeOffset other) {
- return UtcDateTime.Equals(other.UtcDateTime);
- }
-
- public bool EqualsExact(DateTimeOffset other) {
- //
- // returns true when the ClockDateTime, Kind, and Offset match
- //
- // currently the Kind should always be Unspecified, but there is always the possibility that a future version
- // of DateTimeOffset overloads the Kind field
- //
- return (ClockDateTime == other.ClockDateTime && Offset == other.Offset && ClockDateTime.Kind == other.ClockDateTime.Kind);
- }
-
- // Compares two DateTimeOffset values for equality. Returns true if
- // the two DateTimeOffset values are equal, or false if they are
- // not equal.
- //
- public static bool Equals(DateTimeOffset first, DateTimeOffset second) {
- return DateTime.Equals(first.UtcDateTime, second.UtcDateTime);
- }
-
- // Creates a DateTimeOffset from a Windows filetime. A Windows filetime is
- // a long representing the date and time as the number of
- // 100-nanosecond intervals that have elapsed since 1/1/1601 12:00am.
- //
- public static DateTimeOffset FromFileTime(long fileTime) {
- return new DateTimeOffset(DateTime.FromFileTime(fileTime));
- }
-
- public static DateTimeOffset FromUnixTimeSeconds(long seconds) {
- if (seconds < UnixMinSeconds || seconds > UnixMaxSeconds) {
- throw new ArgumentOutOfRangeException(nameof(seconds),
- string.Format(Environment.GetResourceString("ArgumentOutOfRange_Range"), UnixMinSeconds, UnixMaxSeconds));
- }
-
- long ticks = seconds * TimeSpan.TicksPerSecond + UnixEpochTicks;
- return new DateTimeOffset(ticks, TimeSpan.Zero);
- }
-
- public static DateTimeOffset FromUnixTimeMilliseconds(long milliseconds) {
- const long MinMilliseconds = DateTime.MinTicks / TimeSpan.TicksPerMillisecond - UnixEpochMilliseconds;
- const long MaxMilliseconds = DateTime.MaxTicks / TimeSpan.TicksPerMillisecond - UnixEpochMilliseconds;
-
- if (milliseconds < MinMilliseconds || milliseconds > MaxMilliseconds) {
- throw new ArgumentOutOfRangeException(nameof(milliseconds),
- string.Format(Environment.GetResourceString("ArgumentOutOfRange_Range"), MinMilliseconds, MaxMilliseconds));
- }
-
- long ticks = milliseconds * TimeSpan.TicksPerMillisecond + UnixEpochTicks;
- return new DateTimeOffset(ticks, TimeSpan.Zero);
- }
-
- // ----- SECTION: private serialization instance methods ----------------*
-
- void IDeserializationCallback.OnDeserialization(Object sender) {
- try {
- m_offsetMinutes = ValidateOffset(Offset);
- m_dateTime = ValidateDate(ClockDateTime, Offset);
- }
- catch (ArgumentException e) {
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"), e);
- }
- }
-
-
- void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info == null) {
- throw new ArgumentNullException(nameof(info));
- }
-
- Contract.EndContractBlock();
-
- info.AddValue("DateTime", m_dateTime);
- info.AddValue("OffsetMinutes", m_offsetMinutes);
- }
-
-
- DateTimeOffset(SerializationInfo info, StreamingContext context) {
- if (info == null) {
- throw new ArgumentNullException(nameof(info));
- }
-
- m_dateTime = (DateTime)info.GetValue("DateTime", typeof(DateTime));
- m_offsetMinutes = (Int16)info.GetValue("OffsetMinutes", typeof(Int16));
- }
-
- // Returns the hash code for this DateTimeOffset.
- //
- public override int GetHashCode() {
- return UtcDateTime.GetHashCode();
- }
-
- // Constructs a DateTimeOffset from a string. The string must specify a
- // date and optionally a time in a culture-specific or universal format.
- // Leading and trailing whitespace characters are allowed.
- //
- public static DateTimeOffset Parse(String input) {
- TimeSpan offset;
- DateTime dateResult = DateTimeParse.Parse(input,
- DateTimeFormatInfo.CurrentInfo,
- DateTimeStyles.None,
- out offset);
- return new DateTimeOffset(dateResult.Ticks, offset);
- }
-
- // Constructs a DateTimeOffset from a string. The string must specify a
- // date and optionally a time in a culture-specific or universal format.
- // Leading and trailing whitespace characters are allowed.
- //
- public static DateTimeOffset Parse(String input, IFormatProvider formatProvider) {
- return Parse(input, formatProvider, DateTimeStyles.None);
- }
-
- public static DateTimeOffset Parse(String input, IFormatProvider formatProvider, DateTimeStyles styles) {
- styles = ValidateStyles(styles, nameof(styles));
- TimeSpan offset;
- DateTime dateResult = DateTimeParse.Parse(input,
- DateTimeFormatInfo.GetInstance(formatProvider),
- styles,
- out offset);
- return new DateTimeOffset(dateResult.Ticks, offset);
- }
-
- // Constructs a DateTimeOffset from a string. The string must specify a
- // date and optionally a time in a culture-specific or universal format.
- // Leading and trailing whitespace characters are allowed.
- //
- public static DateTimeOffset ParseExact(String input, String format, IFormatProvider formatProvider) {
- return ParseExact(input, format, formatProvider, DateTimeStyles.None);
- }
-
- // Constructs a DateTimeOffset from a string. The string must specify a
- // date and optionally a time in a culture-specific or universal format.
- // Leading and trailing whitespace characters are allowed.
- //
- public static DateTimeOffset ParseExact(String input, String format, IFormatProvider formatProvider, DateTimeStyles styles) {
- styles = ValidateStyles(styles, nameof(styles));
- TimeSpan offset;
- DateTime dateResult = DateTimeParse.ParseExact(input,
- format,
- DateTimeFormatInfo.GetInstance(formatProvider),
- styles,
- out offset);
- return new DateTimeOffset(dateResult.Ticks, offset);
- }
-
- public static DateTimeOffset ParseExact(String input, String[] formats, IFormatProvider formatProvider, DateTimeStyles styles) {
- styles = ValidateStyles(styles, nameof(styles));
- TimeSpan offset;
- DateTime dateResult = DateTimeParse.ParseExactMultiple(input,
- formats,
- DateTimeFormatInfo.GetInstance(formatProvider),
- styles,
- out offset);
- return new DateTimeOffset(dateResult.Ticks, offset);
- }
-
- public TimeSpan Subtract(DateTimeOffset value) {
- return UtcDateTime.Subtract(value.UtcDateTime);
- }
-
- public DateTimeOffset Subtract(TimeSpan value) {
- return new DateTimeOffset(ClockDateTime.Subtract(value), Offset);
- }
-
-
- public long ToFileTime() {
- return UtcDateTime.ToFileTime();
- }
-
- public long ToUnixTimeSeconds() {
- // Truncate sub-second precision before offsetting by the Unix Epoch to avoid
- // the last digit being off by one for dates that result in negative Unix times.
- //
- // For example, consider the DateTimeOffset 12/31/1969 12:59:59.001 +0
- // ticks = 621355967990010000
- // ticksFromEpoch = ticks - UnixEpochTicks = -9990000
- // secondsFromEpoch = ticksFromEpoch / TimeSpan.TicksPerSecond = 0
- //
- // Notice that secondsFromEpoch is rounded *up* by the truncation induced by integer division,
- // whereas we actually always want to round *down* when converting to Unix time. This happens
- // automatically for positive Unix time values. Now the example becomes:
- // seconds = ticks / TimeSpan.TicksPerSecond = 62135596799
- // secondsFromEpoch = seconds - UnixEpochSeconds = -1
- //
- // In other words, we want to consistently round toward the time 1/1/0001 00:00:00,
- // rather than toward the Unix Epoch (1/1/1970 00:00:00).
- long seconds = UtcDateTime.Ticks / TimeSpan.TicksPerSecond;
- return seconds - UnixEpochSeconds;
- }
-
- public long ToUnixTimeMilliseconds() {
- // Truncate sub-millisecond precision before offsetting by the Unix Epoch to avoid
- // the last digit being off by one for dates that result in negative Unix times
- long milliseconds = UtcDateTime.Ticks / TimeSpan.TicksPerMillisecond;
- return milliseconds - UnixEpochMilliseconds;
- }
-
- public DateTimeOffset ToLocalTime() {
- return ToLocalTime(false);
- }
-
- internal DateTimeOffset ToLocalTime(bool throwOnOverflow)
- {
- return new DateTimeOffset(UtcDateTime.ToLocalTime(throwOnOverflow));
- }
-
- public override String ToString() {
- Contract.Ensures(Contract.Result<String>() != null);
- return DateTimeFormat.Format(ClockDateTime, null, DateTimeFormatInfo.CurrentInfo, Offset);
- }
-
- public String ToString(String format) {
- Contract.Ensures(Contract.Result<String>() != null);
- return DateTimeFormat.Format(ClockDateTime, format, DateTimeFormatInfo.CurrentInfo, Offset);
- }
-
- public String ToString(IFormatProvider formatProvider) {
- Contract.Ensures(Contract.Result<String>() != null);
- return DateTimeFormat.Format(ClockDateTime, null, DateTimeFormatInfo.GetInstance(formatProvider), Offset);
- }
-
- public String ToString(String format, IFormatProvider formatProvider) {
- Contract.Ensures(Contract.Result<String>() != null);
- return DateTimeFormat.Format(ClockDateTime, format, DateTimeFormatInfo.GetInstance(formatProvider), Offset);
- }
-
- public DateTimeOffset ToUniversalTime() {
- return new DateTimeOffset(UtcDateTime);
- }
-
- public static Boolean TryParse(String input, out DateTimeOffset result) {
- TimeSpan offset;
- DateTime dateResult;
- Boolean parsed = DateTimeParse.TryParse(input,
- DateTimeFormatInfo.CurrentInfo,
- DateTimeStyles.None,
- out dateResult,
- out offset);
- result = new DateTimeOffset(dateResult.Ticks, offset);
- return parsed;
- }
-
- public static Boolean TryParse(String input, IFormatProvider formatProvider, DateTimeStyles styles, out DateTimeOffset result) {
- styles = ValidateStyles(styles, nameof(styles));
- TimeSpan offset;
- DateTime dateResult;
- Boolean parsed = DateTimeParse.TryParse(input,
- DateTimeFormatInfo.GetInstance(formatProvider),
- styles,
- out dateResult,
- out offset);
- result = new DateTimeOffset(dateResult.Ticks, offset);
- return parsed;
- }
-
- public static Boolean TryParseExact(String input, String format, IFormatProvider formatProvider, DateTimeStyles styles,
- out DateTimeOffset result) {
- styles = ValidateStyles(styles, nameof(styles));
- TimeSpan offset;
- DateTime dateResult;
- Boolean parsed = DateTimeParse.TryParseExact(input,
- format,
- DateTimeFormatInfo.GetInstance(formatProvider),
- styles,
- out dateResult,
- out offset);
- result = new DateTimeOffset(dateResult.Ticks, offset);
- return parsed;
- }
-
- public static Boolean TryParseExact(String input, String[] formats, IFormatProvider formatProvider, DateTimeStyles styles,
- out DateTimeOffset result) {
- styles = ValidateStyles(styles, nameof(styles));
- TimeSpan offset;
- DateTime dateResult;
- Boolean parsed = DateTimeParse.TryParseExactMultiple(input,
- formats,
- DateTimeFormatInfo.GetInstance(formatProvider),
- styles,
- out dateResult,
- out offset);
- result = new DateTimeOffset(dateResult.Ticks, offset);
- return parsed;
- }
-
- // Ensures the TimeSpan is valid to go in a DateTimeOffset.
- private static Int16 ValidateOffset(TimeSpan offset) {
- Int64 ticks = offset.Ticks;
- if (ticks % TimeSpan.TicksPerMinute != 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_OffsetPrecision"), nameof(offset));
- }
- if (ticks < MinOffset || ticks > MaxOffset) {
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("Argument_OffsetOutOfRange"));
- }
- return (Int16)(offset.Ticks / TimeSpan.TicksPerMinute);
- }
-
- // Ensures that the time and offset are in range.
- private static DateTime ValidateDate(DateTime dateTime, TimeSpan offset) {
- // The key validation is that both the UTC and clock times fit. The clock time is validated
- // by the DateTime constructor.
- Debug.Assert(offset.Ticks >= MinOffset && offset.Ticks <= MaxOffset, "Offset not validated.");
- // This operation cannot overflow because offset should have already been validated to be within
- // 14 hours and the DateTime instance is more than that distance from the boundaries of Int64.
- Int64 utcTicks = dateTime.Ticks - offset.Ticks;
- if (utcTicks < DateTime.MinTicks || utcTicks > DateTime.MaxTicks) {
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("Argument_UTCOutOfRange"));
- }
- // make sure the Kind is set to Unspecified
- //
- return new DateTime(utcTicks, DateTimeKind.Unspecified);
- }
-
- private static DateTimeStyles ValidateStyles(DateTimeStyles style, String parameterName) {
- if ((style & DateTimeFormatInfo.InvalidDateTimeStyles) != 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDateTimeStyles"), parameterName);
- }
- if (((style & (DateTimeStyles.AssumeLocal)) != 0) && ((style & (DateTimeStyles.AssumeUniversal)) != 0)) {
- throw new ArgumentException(Environment.GetResourceString("Argument_ConflictingDateTimeStyles"), parameterName);
- }
- if ((style & DateTimeStyles.NoCurrentDateDefault) != 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeOffsetInvalidDateTimeStyles"), parameterName);
- }
-
- Contract.EndContractBlock();
- // RoundtripKind does not make sense for DateTimeOffset; ignore this flag for backward compatibility with DateTime
- style &= ~DateTimeStyles.RoundtripKind;
-
- // AssumeLocal is also ignored as that is what we do by default with DateTimeOffset.Parse
- style &= ~DateTimeStyles.AssumeLocal;
-
- return style;
- }
-
- // Operators
-
- public static implicit operator DateTimeOffset (DateTime dateTime) {
- return new DateTimeOffset(dateTime);
- }
-
- public static DateTimeOffset operator +(DateTimeOffset dateTimeOffset, TimeSpan timeSpan) {
- return new DateTimeOffset(dateTimeOffset.ClockDateTime + timeSpan, dateTimeOffset.Offset);
- }
-
-
- public static DateTimeOffset operator -(DateTimeOffset dateTimeOffset, TimeSpan timeSpan) {
- return new DateTimeOffset(dateTimeOffset.ClockDateTime - timeSpan, dateTimeOffset.Offset);
- }
-
- public static TimeSpan operator -(DateTimeOffset left, DateTimeOffset right) {
- return left.UtcDateTime - right.UtcDateTime;
- }
-
- public static bool operator ==(DateTimeOffset left, DateTimeOffset right) {
- return left.UtcDateTime == right.UtcDateTime;
- }
-
- public static bool operator !=(DateTimeOffset left, DateTimeOffset right) {
- return left.UtcDateTime != right.UtcDateTime;
- }
-
- public static bool operator <(DateTimeOffset left, DateTimeOffset right) {
- return left.UtcDateTime < right.UtcDateTime;
- }
-
- public static bool operator <=(DateTimeOffset left, DateTimeOffset right) {
- return left.UtcDateTime <= right.UtcDateTime;
- }
-
- public static bool operator >(DateTimeOffset left, DateTimeOffset right) {
- return left.UtcDateTime > right.UtcDateTime;
- }
-
- public static bool operator >=(DateTimeOffset left, DateTimeOffset right) {
- return left.UtcDateTime >= right.UtcDateTime;
- }
-
- }
-}
diff --git a/src/mscorlib/src/System/Decimal.cs b/src/mscorlib/src/System/Decimal.cs
index a01ed19753..ce59a99334 100644
--- a/src/mscorlib/src/System/Decimal.cs
+++ b/src/mscorlib/src/System/Decimal.cs
@@ -2,17 +2,18 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System {
-
- using System;
- using System.Globalization;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.Versioning;
- using System.Runtime.Serialization;
- using System.Diagnostics.Contracts;
+using System;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.Versioning;
+using System.Runtime.Serialization;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
// Implements the Decimal data type. The Decimal data type can
// represent values ranging from -79,228,162,514,264,337,593,543,950,335 to
// 79,228,162,514,264,337,593,543,950,335 with 28 significant digits. The
@@ -60,31 +61,30 @@ namespace System {
[System.Runtime.Versioning.NonVersionable] // This only applies to field layout
public struct Decimal : IFormattable, IComparable, IConvertible, IComparable<Decimal>, IEquatable<Decimal>, IDeserializationCallback
{
-
// Sign mask for the flags field. A value of zero in this bit indicates a
// positive Decimal value, and a value of one in this bit indicates a
// negative Decimal value.
//
// Look at OleAut's DECIMAL_NEG constant to check for negative values
// in native code.
- private const int SignMask = unchecked((int)0x80000000);
+ private const int SignMask = unchecked((int)0x80000000);
private const byte DECIMAL_NEG = 0x80;
private const byte DECIMAL_ADD = 0x00;
-
+
// Scale mask for the flags field. This byte in the flags field contains
// the power of 10 to divide the Decimal value by. The scale byte must
// contain a value between 0 and 28 inclusive.
private const int ScaleMask = 0x00FF0000;
-
+
// Number of bits scale is shifted by.
private const int ScaleShift = 16;
-
+
// The maximum power of 10 that a 32 bit integer can store
private const Int32 MaxInt32Scale = 9;
// Fast access for 10^n where n is 0-9
private static UInt32[] Powers10 = new UInt32[] {
- 1,
+ 1,
10,
100,
1000,
@@ -94,21 +94,21 @@ namespace System {
10000000,
100000000,
1000000000
- };
-
+ };
+
// Constant representing the Decimal value 0.
public const Decimal Zero = 0m;
-
+
// Constant representing the Decimal value 1.
public const Decimal One = 1m;
-
+
// Constant representing the Decimal value -1.
public const Decimal MinusOne = -1m;
-
+
// Constant representing the largest possible Decimal value. The value of
// this constant is 79,228,162,514,264,337,593,543,950,335.
public const Decimal MaxValue = 79228162514264337593543950335m;
-
+
// Constant representing the smallest possible Decimal value. The value of
// this constant is -79,228,162,514,264,337,593,543,950,335.
public const Decimal MinValue = -79228162514264337593543950335m;
@@ -120,8 +120,8 @@ namespace System {
// Constant representing the positive number that is the closest possible
// Decimal value to +0m.
- private const Decimal NearPositiveZero = +0.000000000000000000000000001m;
-
+ private const Decimal NearPositiveZero = +0.000000000000000000000000001m;
+
// The lo, mid, hi, and flags fields contain the representation of the
// Decimal value. The lo, mid, and hi fields contain the 96-bit integer
// part of the Decimal. Bits 0-15 (the lower word) of the flags field are
@@ -137,8 +137,8 @@ namespace System {
private int hi;
private int lo;
private int mid;
-
-
+
+
// Constructs a zero Decimal.
//public Decimal() {
// lo = 0;
@@ -146,17 +146,20 @@ namespace System {
// hi = 0;
// flags = 0;
//}
-
+
// Constructs a Decimal from an integer value.
//
- public Decimal(int value) {
+ public Decimal(int value)
+ {
// JIT today can't inline methods that contains "starg" opcode.
// For more details, see DevDiv Bugs 81184: x86 JIT CQ: Removing the inline striction of "starg".
- int value_copy = value;
- if (value_copy >= 0) {
+ int value_copy = value;
+ if (value_copy >= 0)
+ {
flags = 0;
}
- else {
+ else
+ {
flags = SignMask;
value_copy = -value_copy;
}
@@ -164,27 +167,31 @@ namespace System {
mid = 0;
hi = 0;
}
-
+
// Constructs a Decimal from an unsigned integer value.
//
[CLSCompliant(false)]
- public Decimal(uint value) {
+ public Decimal(uint value)
+ {
flags = 0;
- lo = (int) value;
+ lo = (int)value;
mid = 0;
hi = 0;
}
-
+
// Constructs a Decimal from a long value.
//
- public Decimal(long value) {
+ public Decimal(long value)
+ {
// JIT today can't inline methods that contains "starg" opcode.
// For more details, see DevDiv Bugs 81184: x86 JIT CQ: Removing the inline striction of "starg".
long value_copy = value;
- if (value_copy >= 0) {
+ if (value_copy >= 0)
+ {
flags = 0;
}
- else {
+ else
+ {
flags = SignMask;
value_copy = -value_copy;
}
@@ -192,30 +199,32 @@ namespace System {
mid = (int)(value_copy >> 32);
hi = 0;
}
-
+
// Constructs a Decimal from an unsigned long value.
//
- [CLSCompliant(false)]
- public Decimal(ulong value) {
+ [CLSCompliant(false)]
+ public Decimal(ulong value)
+ {
flags = 0;
lo = (int)value;
mid = (int)(value >> 32);
hi = 0;
}
-
+
// Constructs a Decimal from a float value.
//
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Decimal(float value);
-
+
// Constructs a Decimal from a double value.
//
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Decimal(double value);
-
+
// Constructs a Decimal from a Currency value.
//
- internal Decimal(Currency value) {
+ internal Decimal(Currency value)
+ {
this = Currency.ToDecimal(value);
}
@@ -225,13 +234,13 @@ namespace System {
{
return new Currency(value).ToOACurrency();
}
-
+
public static Decimal FromOACurrency(long cy)
{
return Currency.ToDecimal(Currency.FromOACurrency(cy));
}
-
+
// Constructs a Decimal from an integer array containing a binary
// representation. The bits argument must be a non-null integer
// array with four elements. bits[0], bits[1], and
@@ -251,21 +260,25 @@ namespace System {
// The possible binary representations of a particular value are all
// equally valid, and all are numerically equivalent.
//
- public Decimal(int[] bits) {
- this.lo = 0;
- this.mid = 0;
- this.hi = 0;
- this.flags = 0;
+ public Decimal(int[] bits)
+ {
+ lo = 0;
+ mid = 0;
+ hi = 0;
+ flags = 0;
SetBits(bits);
}
- private void SetBits(int[] bits) {
- if (bits==null)
+ private void SetBits(int[] bits)
+ {
+ if (bits == null)
throw new ArgumentNullException(nameof(bits));
Contract.EndContractBlock();
- if (bits.Length == 4) {
+ if (bits.Length == 4)
+ {
int f = bits[3];
- if ((f & ~(SignMask | ScaleMask)) == 0 && (f & ScaleMask) <= (28 << 16)) {
+ if ((f & ~(SignMask | ScaleMask)) == 0 && (f & ScaleMask) <= (28 << 16))
+ {
lo = bits[0];
mid = bits[1];
hi = bits[2];
@@ -273,94 +286,108 @@ namespace System {
return;
}
}
- throw new ArgumentException(Environment.GetResourceString("Arg_DecBitCtor"));
+ throw new ArgumentException(SR.Arg_DecBitCtor);
}
-
+
// Constructs a Decimal from its constituent parts.
//
- public Decimal(int lo, int mid, int hi, bool isNegative, byte scale) {
+ public Decimal(int lo, int mid, int hi, bool isNegative, byte scale)
+ {
if (scale > 28)
- throw new ArgumentOutOfRangeException(nameof(scale), Environment.GetResourceString("ArgumentOutOfRange_DecimalScale"));
+ throw new ArgumentOutOfRangeException(nameof(scale), SR.ArgumentOutOfRange_DecimalScale);
Contract.EndContractBlock();
this.lo = lo;
this.mid = mid;
this.hi = hi;
- this.flags = ((int)scale) << 16;
+ flags = ((int)scale) << 16;
if (isNegative)
- this.flags |= SignMask;
+ flags |= SignMask;
}
[OnSerializing]
- void OnSerializing(StreamingContext ctx) {
+ private void OnSerializing(StreamingContext ctx)
+ {
// OnSerializing is called before serialization of an object
- try {
- SetBits( GetBits(this) );
- } catch (ArgumentException e) {
- throw new SerializationException(Environment.GetResourceString("Overflow_Decimal"), e);
- }
+ try
+ {
+ SetBits(GetBits(this));
+ }
+ catch (ArgumentException e)
+ {
+ throw new SerializationException(SR.Overflow_Decimal, e);
+ }
}
- void IDeserializationCallback.OnDeserialization(Object sender) {
+ void IDeserializationCallback.OnDeserialization(Object sender)
+ {
// OnDeserialization is called after each instance of this class is deserialized.
// This callback method performs decimal validation after being deserialized.
- try {
- SetBits( GetBits(this) );
- } catch (ArgumentException e) {
- throw new SerializationException(Environment.GetResourceString("Overflow_Decimal"), e);
- }
+ try
+ {
+ SetBits(GetBits(this));
+ }
+ catch (ArgumentException e)
+ {
+ throw new SerializationException(SR.Overflow_Decimal, e);
+ }
}
-
+
// Constructs a Decimal from its constituent parts.
- private Decimal(int lo, int mid, int hi, int flags) {
- if ((flags & ~(SignMask | ScaleMask)) == 0 && (flags & ScaleMask) <= (28 << 16)) {
+ private Decimal(int lo, int mid, int hi, int flags)
+ {
+ if ((flags & ~(SignMask | ScaleMask)) == 0 && (flags & ScaleMask) <= (28 << 16))
+ {
this.lo = lo;
this.mid = mid;
this.hi = hi;
this.flags = flags;
return;
}
- throw new ArgumentException(Environment.GetResourceString("Arg_DecBitCtor"));
+ throw new ArgumentException(SR.Arg_DecBitCtor);
}
-
+
// Returns the absolute value of the given Decimal. If d is
// positive, the result is d. If d is negative, the result
// is -d.
//
- internal static Decimal Abs(Decimal d) {
+ internal static Decimal Abs(Decimal d)
+ {
return new Decimal(d.lo, d.mid, d.hi, d.flags & ~SignMask);
}
-
+
// Adds two Decimal values.
//
public static Decimal Add(Decimal d1, Decimal d2)
{
- FCallAddSub (ref d1, ref d2, DECIMAL_ADD);
+ FCallAddSub(ref d1, ref d2, DECIMAL_ADD);
return d1;
}
-
+
// FCallAddSub adds or subtracts two decimal values. On return, d1 contains the result
// of the operation. Passing in DECIMAL_ADD or DECIMAL_NEG for bSign indicates
// addition or subtraction, respectively.
//
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallAddSub(ref Decimal d1, ref Decimal d2, byte bSign);
-
+
// Rounds a Decimal to an integer value. The Decimal argument is rounded
// towards positive infinity.
- public static Decimal Ceiling(Decimal d) {
+ public static Decimal Ceiling(Decimal d)
+ {
return (-(Decimal.Floor(-d)));
- }
-
+ }
+
// Compares two Decimal values, returning an integer that indicates their
// relationship.
//
- public static int Compare(Decimal d1, Decimal d2) {
+ public static int Compare(Decimal d1, Decimal d2)
+ {
return FCallCompare(ref d1, ref d2);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int FCallCompare(ref Decimal d1, ref Decimal d2);
-
+
// Compares this object to another object, returning an integer that
// indicates the relationship.
// Returns a value less than zero if this object
@@ -372,9 +399,9 @@ namespace System {
if (value == null)
return 1;
if (!(value is Decimal))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDecimal"));
-
- Decimal other = (Decimal)value;
+ throw new ArgumentException(SR.Arg_MustBeDecimal);
+
+ Decimal other = (Decimal)value;
return FCallCompare(ref this, ref other);
}
@@ -382,12 +409,12 @@ namespace System {
{
return FCallCompare(ref this, ref value);
}
-
+
// Divides two Decimal values.
//
public static Decimal Divide(Decimal d1, Decimal d2)
{
- FCallDivide (ref d1, ref d2);
+ FCallDivide(ref d1, ref d2);
return d1;
}
@@ -397,13 +424,15 @@ namespace System {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallDivide(ref Decimal d1, ref Decimal d2);
-
+
// Checks if this Decimal is equal to a given object. Returns true
// if the given object is a boxed Decimal and its value is equal to the
// value of this Decimal. Returns false otherwise.
//
- public override bool Equals(Object value) {
- if (value is Decimal) {
+ public override bool Equals(Object value)
+ {
+ if (value is Decimal)
+ {
Decimal other = (Decimal)value;
return FCallCompare(ref this, ref other) == 0;
}
@@ -419,52 +448,57 @@ namespace System {
//
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern override int GetHashCode();
-
+
// Compares two Decimal values for equality. Returns true if the two
// Decimal values are equal, or false if they are not equal.
//
- public static bool Equals(Decimal d1, Decimal d2) {
+ public static bool Equals(Decimal d1, Decimal d2)
+ {
return FCallCompare(ref d1, ref d2) == 0;
}
-
+
// Rounds a Decimal to an integer value. The Decimal argument is rounded
// towards negative infinity.
//
public static Decimal Floor(Decimal d)
{
- FCallFloor (ref d);
+ FCallFloor(ref d);
return d;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void FCallFloor(ref Decimal d);
+ private static extern void FCallFloor(ref Decimal d);
// Converts this Decimal to a string. The resulting string consists of an
// optional minus sign ("-") followed to a sequence of digits ("0" - "9"),
// optionally followed by a decimal point (".") and another sequence of
// digits.
//
- public override String ToString() {
+ public override String ToString()
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDecimal(this, null, NumberFormatInfo.CurrentInfo);
}
- public String ToString(String format) {
+ public String ToString(String format)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDecimal(this, format, NumberFormatInfo.CurrentInfo);
}
- public String ToString(IFormatProvider provider) {
+ public String ToString(IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDecimal(this, null, NumberFormatInfo.GetInstance(provider));
- }
+ }
- public String ToString(String format, IFormatProvider provider) {
+ public String ToString(String format, IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDecimal(this, format, NumberFormatInfo.GetInstance(provider));
}
-
+
// Converts a string to a Decimal. The string must consist of an optional
// minus sign ("-") followed by a sequence of digits ("0" - "9"). The
// sequence of digits may optionally contain a single decimal point (".")
@@ -472,29 +506,35 @@ namespace System {
// Parse also allows a currency symbol, a trailing negative sign, and
// parentheses in the number.
//
- public static Decimal Parse(String s) {
+ public static Decimal Parse(String s)
+ {
return Number.ParseDecimal(s, NumberStyles.Number, NumberFormatInfo.CurrentInfo);
}
-
- public static Decimal Parse(String s, NumberStyles style) {
+
+ public static Decimal Parse(String s, NumberStyles style)
+ {
NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
return Number.ParseDecimal(s, style, NumberFormatInfo.CurrentInfo);
}
- public static Decimal Parse(String s, IFormatProvider provider) {
+ public static Decimal Parse(String s, IFormatProvider provider)
+ {
return Number.ParseDecimal(s, NumberStyles.Number, NumberFormatInfo.GetInstance(provider));
}
-
- public static Decimal Parse(String s, NumberStyles style, IFormatProvider provider) {
+
+ public static Decimal Parse(String s, NumberStyles style, IFormatProvider provider)
+ {
NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
return Number.ParseDecimal(s, style, NumberFormatInfo.GetInstance(provider));
}
-
- public static Boolean TryParse(String s, out Decimal result) {
+
+ public static Boolean TryParse(String s, out Decimal result)
+ {
return Number.TryParseDecimal(s, NumberStyles.Number, NumberFormatInfo.CurrentInfo, out result);
}
- public static Boolean TryParse(String s, NumberStyles style, IFormatProvider provider, out Decimal result) {
+ public static Boolean TryParse(String s, NumberStyles style, IFormatProvider provider, out Decimal result)
+ {
NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
return Number.TryParseDecimal(s, style, NumberFormatInfo.GetInstance(provider), out result);
}
@@ -509,160 +549,181 @@ namespace System {
// indicates the sign of the Decimal value, 0 meaning positive and 1
// meaning negative.
//
- public static int[] GetBits(Decimal d) {
- return new int[] {d.lo, d.mid, d.hi, d.flags};
+ public static int[] GetBits(Decimal d)
+ {
+ return new int[] { d.lo, d.mid, d.hi, d.flags };
}
- internal static void GetBytes(Decimal d, byte [] buffer) {
+ internal static void GetBytes(Decimal d, byte[] buffer)
+ {
Contract.Requires((buffer != null && buffer.Length >= 16), "[GetBytes]buffer != null && buffer.Length >= 16");
- buffer[0] = (byte) d.lo;
- buffer[1] = (byte) (d.lo >> 8);
- buffer[2] = (byte) (d.lo >> 16);
- buffer[3] = (byte) (d.lo >> 24);
-
- buffer[4] = (byte) d.mid;
- buffer[5] = (byte) (d.mid >> 8);
- buffer[6] = (byte) (d.mid >> 16);
- buffer[7] = (byte) (d.mid >> 24);
-
- buffer[8] = (byte) d.hi;
- buffer[9] = (byte) (d.hi >> 8);
- buffer[10] = (byte) (d.hi >> 16);
- buffer[11] = (byte) (d.hi >> 24);
-
- buffer[12] = (byte) d.flags;
- buffer[13] = (byte) (d.flags >> 8);
- buffer[14] = (byte) (d.flags >> 16);
- buffer[15] = (byte) (d.flags >> 24);
- }
-
- internal static decimal ToDecimal(byte [] buffer) {
+ buffer[0] = (byte)d.lo;
+ buffer[1] = (byte)(d.lo >> 8);
+ buffer[2] = (byte)(d.lo >> 16);
+ buffer[3] = (byte)(d.lo >> 24);
+
+ buffer[4] = (byte)d.mid;
+ buffer[5] = (byte)(d.mid >> 8);
+ buffer[6] = (byte)(d.mid >> 16);
+ buffer[7] = (byte)(d.mid >> 24);
+
+ buffer[8] = (byte)d.hi;
+ buffer[9] = (byte)(d.hi >> 8);
+ buffer[10] = (byte)(d.hi >> 16);
+ buffer[11] = (byte)(d.hi >> 24);
+
+ buffer[12] = (byte)d.flags;
+ buffer[13] = (byte)(d.flags >> 8);
+ buffer[14] = (byte)(d.flags >> 16);
+ buffer[15] = (byte)(d.flags >> 24);
+ }
+
+ internal static decimal ToDecimal(byte[] buffer)
+ {
Contract.Requires((buffer != null && buffer.Length >= 16), "[ToDecimal]buffer != null && buffer.Length >= 16");
int lo = ((int)buffer[0]) | ((int)buffer[1] << 8) | ((int)buffer[2] << 16) | ((int)buffer[3] << 24);
int mid = ((int)buffer[4]) | ((int)buffer[5] << 8) | ((int)buffer[6] << 16) | ((int)buffer[7] << 24);
int hi = ((int)buffer[8]) | ((int)buffer[9] << 8) | ((int)buffer[10] << 16) | ((int)buffer[11] << 24);
int flags = ((int)buffer[12]) | ((int)buffer[13] << 8) | ((int)buffer[14] << 16) | ((int)buffer[15] << 24);
- return new Decimal(lo,mid,hi,flags);
+ return new Decimal(lo, mid, hi, flags);
}
-
+
// This method does a 'raw' and 'unchecked' addition of a UInt32 to a Decimal in place.
// 'raw' means that it operates on the internal 96-bit unsigned integer value and
// ingores the sign and scale. This means that it is not equivalent to just adding
// that number, as the sign and scale are effectively applied to the UInt32 value also.
// 'unchecked' means that it does not fail if you overflow the 96 bit value.
- private static void InternalAddUInt32RawUnchecked(ref Decimal value, UInt32 i) {
- UInt32 v;
+ private static void InternalAddUInt32RawUnchecked(ref Decimal value, UInt32 i)
+ {
+ UInt32 v;
UInt32 sum;
v = (UInt32)value.lo;
sum = v + i;
value.lo = (Int32)sum;
- if (sum < v || sum < i) {
+ if (sum < v || sum < i)
+ {
v = (UInt32)value.mid;
sum = v + 1;
value.mid = (Int32)sum;
- if (sum < v || sum < 1) {
- value.hi = (Int32) ((UInt32)value.hi + 1);
- }
+ if (sum < v || sum < 1)
+ {
+ value.hi = (Int32)((UInt32)value.hi + 1);
+ }
}
- }
+ }
// This method does an in-place division of a decimal by a UInt32, returning the remainder.
// Although it does not operate on the sign or scale, this does not result in any
// caveat for the result. It is equivalent to dividing by that number.
- private static UInt32 InternalDivRemUInt32(ref Decimal value, UInt32 divisor) {
+ private static UInt32 InternalDivRemUInt32(ref Decimal value, UInt32 divisor)
+ {
UInt32 remainder = 0;
UInt64 n;
- if (value.hi != 0) {
- n = ((UInt32) value.hi);
+ if (value.hi != 0)
+ {
+ n = ((UInt32)value.hi);
value.hi = (Int32)((UInt32)(n / divisor));
remainder = (UInt32)(n % divisor);
}
- if (value.mid != 0 || remainder != 0) {
- n = ((UInt64)remainder << 32) | (UInt32) value.mid;
+ if (value.mid != 0 || remainder != 0)
+ {
+ n = ((UInt64)remainder << 32) | (UInt32)value.mid;
value.mid = (Int32)((UInt32)(n / divisor));
- remainder = (UInt32)(n % divisor);
+ remainder = (UInt32)(n % divisor);
}
- if (value.lo != 0 || remainder != 0) {
- n = ((UInt64)remainder << 32) | (UInt32) value.lo;
+ if (value.lo != 0 || remainder != 0)
+ {
+ n = ((UInt64)remainder << 32) | (UInt32)value.lo;
value.lo = (Int32)((UInt32)(n / divisor));
- remainder = (UInt32)(n % divisor);
+ remainder = (UInt32)(n % divisor);
}
return remainder;
}
-
+
// Does an in-place round the specified number of digits, rounding mid-point values
// away from zero
- private static void InternalRoundFromZero(ref Decimal d, int decimalCount) {
+ private static void InternalRoundFromZero(ref Decimal d, int decimalCount)
+ {
Int32 scale = (d.flags & ScaleMask) >> ScaleShift;
Int32 scaleDifference = scale - decimalCount;
- if (scaleDifference <= 0) {
+ if (scaleDifference <= 0)
+ {
return;
}
// Divide the value by 10^scaleDifference
UInt32 lastRemainder;
UInt32 lastDivisor;
- do {
+ do
+ {
Int32 diffChunk = (scaleDifference > MaxInt32Scale) ? MaxInt32Scale : scaleDifference;
lastDivisor = Powers10[diffChunk];
lastRemainder = InternalDivRemUInt32(ref d, lastDivisor);
scaleDifference -= diffChunk;
} while (scaleDifference > 0);
-
+
// Round away from zero at the mid point
- if (lastRemainder >= (lastDivisor >> 1)) {
+ if (lastRemainder >= (lastDivisor >> 1))
+ {
InternalAddUInt32RawUnchecked(ref d, 1);
}
-
+
// the scale becomes the desired decimal count
d.flags = ((decimalCount << ScaleShift) & ScaleMask) | (d.flags & SignMask);
}
-
+
// Returns the larger of two Decimal values.
//
- internal static Decimal Max(Decimal d1, Decimal d2) {
- return FCallCompare(ref d1, ref d2) >= 0? d1: d2;
+ internal static Decimal Max(Decimal d1, Decimal d2)
+ {
+ return FCallCompare(ref d1, ref d2) >= 0 ? d1 : d2;
}
-
+
// Returns the smaller of two Decimal values.
//
- internal static Decimal Min(Decimal d1, Decimal d2) {
- return FCallCompare(ref d1, ref d2) < 0? d1: d2;
+ internal static Decimal Min(Decimal d1, Decimal d2)
+ {
+ return FCallCompare(ref d1, ref d2) < 0 ? d1 : d2;
}
-
- public static Decimal Remainder(Decimal d1, Decimal d2) {
+
+ public static Decimal Remainder(Decimal d1, Decimal d2)
+ {
// OleAut doesn't provide a VarDecMod.
-
+
// In the operation x % y the sign of y does not matter. Result will have the sign of x.
- d2.flags = (d2.flags & ~SignMask) | (d1.flags & SignMask);
+ d2.flags = (d2.flags & ~SignMask) | (d1.flags & SignMask);
// This piece of code is to work around the fact that Dividing a decimal with 28 digits number by decimal which causes
// causes the result to be 28 digits, can cause to be incorrectly rounded up.
// eg. Decimal.MaxValue / 2 * Decimal.MaxValue will overflow since the division by 2 was rounded instead of being truncked.
- if (Abs(d1) < Abs(d2)) {
+ if (Abs(d1) < Abs(d2))
+ {
return d1;
}
d1 -= d2;
- if (d1 == 0) {
+ if (d1 == 0)
+ {
// The sign of D1 will be wrong here. Fall through so that we still get a DivideByZeroException
d1.flags = (d1.flags & ~SignMask) | (d2.flags & SignMask);
}
-
+
// Formula: d1 - (RoundTowardsZero(d1 / d2) * d2)
- Decimal dividedResult = Truncate(d1/d2);
+ Decimal dividedResult = Truncate(d1 / d2);
Decimal multipliedResult = dividedResult * d2;
Decimal result = d1 - multipliedResult;
// See if the result has crossed 0
- if ((d1.flags & SignMask) != (result.flags & SignMask)) {
-
- if (NearNegativeZero <= result && result <= NearPositiveZero) {
+ if ((d1.flags & SignMask) != (result.flags & SignMask))
+ {
+ if (NearNegativeZero <= result && result <= NearPositiveZero)
+ {
// Certain Remainder operations on decimals with 28 significant digits round
// to [+-]0.000000000000000000000000001m instead of [+-]0m during the intermediate calculations.
// 'zero' results just need their sign corrected.
result.flags = (result.flags & ~SignMask) | (d1.flags & SignMask);
}
- else {
+ else
+ {
// If the division rounds up because it runs out of digits, the multiplied result can end up with a larger
// absolute value and the result of the formula crosses 0. To correct it can add the divisor back.
result += d2;
@@ -671,12 +732,12 @@ namespace System {
return result;
}
-
+
// Multiplies two Decimal values.
//
public static Decimal Multiply(Decimal d1, Decimal d2)
{
- FCallMultiply (ref d1, ref d2);
+ FCallMultiply(ref d1, ref d2);
return d1;
}
@@ -685,11 +746,12 @@ namespace System {
//
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallMultiply(ref Decimal d1, ref Decimal d2);
-
+
// Returns the negated value of the given Decimal. If d is non-zero,
// the result is -d. If d is zero, the result is zero.
//
- public static Decimal Negate(Decimal d) {
+ public static Decimal Negate(Decimal d)
+ {
return new Decimal(d.lo, d.mid, d.hi, d.flags ^ SignMask);
}
@@ -700,33 +762,39 @@ namespace System {
//
// By default a mid-point value is rounded to the nearest even number. If the mode is
// passed in, it can also round away from zero.
-
- public static Decimal Round(Decimal d) {
+
+ public static Decimal Round(Decimal d)
+ {
return Round(d, 0);
}
-
+
public static Decimal Round(Decimal d, int decimals)
{
- FCallRound (ref d, decimals);
+ FCallRound(ref d, decimals);
return d;
}
- public static Decimal Round(Decimal d, MidpointRounding mode) {
+ public static Decimal Round(Decimal d, MidpointRounding mode)
+ {
return Round(d, 0, mode);
}
- public static Decimal Round(Decimal d, int decimals, MidpointRounding mode) {
+ public static Decimal Round(Decimal d, int decimals, MidpointRounding mode)
+ {
if ((decimals < 0) || (decimals > 28))
- throw new ArgumentOutOfRangeException(nameof(decimals), Environment.GetResourceString("ArgumentOutOfRange_DecimalRound"));
- if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnumValue", mode, nameof(MidpointRounding)), nameof(mode));
+ throw new ArgumentOutOfRangeException(nameof(decimals), SR.ArgumentOutOfRange_DecimalRound);
+ if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero)
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidEnumValue, mode, nameof(MidpointRounding)), nameof(mode));
}
Contract.EndContractBlock();
- if (mode == MidpointRounding.ToEven) {
- FCallRound (ref d, decimals);
+ if (mode == MidpointRounding.ToEven)
+ {
+ FCallRound(ref d, decimals);
}
- else {
+ else
+ {
InternalRoundFromZero(ref d, decimals);
}
return d;
@@ -734,7 +802,7 @@ namespace System {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallRound(ref Decimal d, int decimals);
-
+
// Subtracts two Decimal values.
//
public static Decimal Subtract(Decimal d1, Decimal d2)
@@ -747,67 +815,75 @@ namespace System {
// towards zero to the nearest integer value, and the result of this
// operation is returned as a byte.
//
- public static byte ToByte(Decimal value) {
+ public static byte ToByte(Decimal value)
+ {
uint temp;
- try {
- temp = ToUInt32(value);
+ try
+ {
+ temp = ToUInt32(value);
}
- catch (OverflowException e) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Byte"), e);
+ catch (OverflowException e)
+ {
+ throw new OverflowException(SR.Overflow_Byte, e);
}
- if (temp < Byte.MinValue || temp > Byte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Byte"));
+ if (temp < Byte.MinValue || temp > Byte.MaxValue) throw new OverflowException(SR.Overflow_Byte);
return (byte)temp;
-
}
-
+
// Converts a Decimal to a signed byte. The Decimal value is rounded
// towards zero to the nearest integer value, and the result of this
// operation is returned as a byte.
//
- [CLSCompliant(false)]
- public static sbyte ToSByte(Decimal value) {
+ [CLSCompliant(false)]
+ public static sbyte ToSByte(Decimal value)
+ {
int temp;
- try {
- temp = ToInt32(value);
+ try
+ {
+ temp = ToInt32(value);
}
- catch (OverflowException e) {
- throw new OverflowException(Environment.GetResourceString("Overflow_SByte"), e);
+ catch (OverflowException e)
+ {
+ throw new OverflowException(SR.Overflow_SByte, e);
}
- if (temp < SByte.MinValue || temp > SByte.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_SByte"));
+ if (temp < SByte.MinValue || temp > SByte.MaxValue) throw new OverflowException(SR.Overflow_SByte);
return (sbyte)temp;
}
-
+
// Converts a Decimal to a short. The Decimal value is
// rounded towards zero to the nearest integer value, and the result of
// this operation is returned as a short.
//
- public static short ToInt16(Decimal value) {
+ public static short ToInt16(Decimal value)
+ {
int temp;
- try {
- temp = ToInt32(value);
+ try
+ {
+ temp = ToInt32(value);
}
- catch (OverflowException e) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Int16"), e);
+ catch (OverflowException e)
+ {
+ throw new OverflowException(SR.Overflow_Int16, e);
}
- if (temp < Int16.MinValue || temp > Int16.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Int16"));
+ if (temp < Int16.MinValue || temp > Int16.MaxValue) throw new OverflowException(SR.Overflow_Int16);
return (short)temp;
}
-
-
+
+
// Converts a Decimal to a Currency. Since a Currency
// has fewer significant digits than a Decimal, this operation may
// produce round-off errors.
//
internal static Currency ToCurrency(Decimal d)
{
- Currency result = new Currency ();
- FCallToCurrency (ref result, d);
+ Currency result = new Currency();
+ FCallToCurrency(ref result, d);
return result;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallToCurrency(ref Currency result, Decimal d);
-
+
// Converts a Decimal to a double. Since a double has fewer significant
// digits than a Decimal, this operation may produce round-off errors.
//
@@ -816,92 +892,107 @@ namespace System {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int FCallToInt32(Decimal d);
-
+
// Converts a Decimal to an integer. The Decimal value is rounded towards
// zero to the nearest integer value, and the result of this operation is
// returned as an integer.
//
- public static int ToInt32(Decimal d) {
- if ((d.flags & ScaleMask) != 0) FCallTruncate (ref d);
- if (d.hi == 0 && d.mid == 0) {
+ public static int ToInt32(Decimal d)
+ {
+ if ((d.flags & ScaleMask) != 0) FCallTruncate(ref d);
+ if (d.hi == 0 && d.mid == 0)
+ {
int i = d.lo;
- if (d.flags >= 0) {
+ if (d.flags >= 0)
+ {
if (i >= 0) return i;
}
- else {
+ else
+ {
i = -i;
if (i <= 0) return i;
}
}
- throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
+ throw new OverflowException(SR.Overflow_Int32);
}
-
+
// Converts a Decimal to a long. The Decimal value is rounded towards zero
// to the nearest integer value, and the result of this operation is
// returned as a long.
//
- public static long ToInt64(Decimal d) {
- if ((d.flags & ScaleMask) != 0) FCallTruncate (ref d);
- if (d.hi == 0) {
+ public static long ToInt64(Decimal d)
+ {
+ if ((d.flags & ScaleMask) != 0) FCallTruncate(ref d);
+ if (d.hi == 0)
+ {
long l = d.lo & 0xFFFFFFFFL | (long)d.mid << 32;
- if (d.flags >= 0) {
+ if (d.flags >= 0)
+ {
if (l >= 0) return l;
}
- else {
+ else
+ {
l = -l;
if (l <= 0) return l;
}
}
- throw new OverflowException(Environment.GetResourceString("Overflow_Int64"));
+ throw new OverflowException(SR.Overflow_Int64);
}
-
+
// Converts a Decimal to an ushort. The Decimal
// value is rounded towards zero to the nearest integer value, and the
// result of this operation is returned as an ushort.
//
- [CLSCompliant(false)]
- public static ushort ToUInt16(Decimal value) {
+ [CLSCompliant(false)]
+ public static ushort ToUInt16(Decimal value)
+ {
uint temp;
- try {
- temp = ToUInt32(value);
+ try
+ {
+ temp = ToUInt32(value);
}
- catch (OverflowException e) {
- throw new OverflowException(Environment.GetResourceString("Overflow_UInt16"), e);
+ catch (OverflowException e)
+ {
+ throw new OverflowException(SR.Overflow_UInt16, e);
}
- if (temp < UInt16.MinValue || temp > UInt16.MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_UInt16"));
+ if (temp < UInt16.MinValue || temp > UInt16.MaxValue) throw new OverflowException(SR.Overflow_UInt16);
return (ushort)temp;
}
-
+
// Converts a Decimal to an unsigned integer. The Decimal
// value is rounded towards zero to the nearest integer value, and the
// result of this operation is returned as an unsigned integer.
//
- [CLSCompliant(false)]
- public static uint ToUInt32(Decimal d) {
- if ((d.flags & ScaleMask) != 0) FCallTruncate (ref d);
- if (d.hi == 0 && d.mid == 0) {
- uint i = (uint) d.lo;
- if (d.flags >= 0 || i == 0)
+ [CLSCompliant(false)]
+ public static uint ToUInt32(Decimal d)
+ {
+ if ((d.flags & ScaleMask) != 0) FCallTruncate(ref d);
+ if (d.hi == 0 && d.mid == 0)
+ {
+ uint i = (uint)d.lo;
+ if (d.flags >= 0 || i == 0)
return i;
}
- throw new OverflowException(Environment.GetResourceString("Overflow_UInt32"));
+ throw new OverflowException(SR.Overflow_UInt32);
}
-
+
// Converts a Decimal to an unsigned long. The Decimal
// value is rounded towards zero to the nearest integer value, and the
// result of this operation is returned as a long.
//
- [CLSCompliant(false)]
- public static ulong ToUInt64(Decimal d) {
- if ((d.flags & ScaleMask) != 0) FCallTruncate (ref d);
- if (d.hi == 0) {
+ [CLSCompliant(false)]
+ public static ulong ToUInt64(Decimal d)
+ {
+ if ((d.flags & ScaleMask) != 0) FCallTruncate(ref d);
+ if (d.hi == 0)
+ {
ulong l = ((ulong)(uint)d.lo) | ((ulong)(uint)d.mid << 32);
if (d.flags >= 0 || l == 0)
return l;
}
- throw new OverflowException(Environment.GetResourceString("Overflow_UInt64"));
+ throw new OverflowException(SR.Overflow_UInt64);
}
-
+
// Converts a Decimal to a float. Since a float has fewer significant
// digits than a Decimal, this operation may produce round-off errors.
//
@@ -914,180 +1005,219 @@ namespace System {
//
public static Decimal Truncate(Decimal d)
{
- FCallTruncate (ref d);
+ FCallTruncate(ref d);
return d;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void FCallTruncate(ref Decimal d);
-
-
- public static implicit operator Decimal(byte value) {
+
+
+ public static implicit operator Decimal(byte value)
+ {
return new Decimal(value);
}
-
+
[CLSCompliant(false)]
- public static implicit operator Decimal(sbyte value) {
+ public static implicit operator Decimal(sbyte value)
+ {
return new Decimal(value);
}
-
- public static implicit operator Decimal(short value) {
+
+ public static implicit operator Decimal(short value)
+ {
return new Decimal(value);
}
-
+
[CLSCompliant(false)]
- public static implicit operator Decimal(ushort value) {
+ public static implicit operator Decimal(ushort value)
+ {
return new Decimal(value);
}
- public static implicit operator Decimal(char value) {
+ public static implicit operator Decimal(char value)
+ {
return new Decimal(value);
}
-
- public static implicit operator Decimal(int value) {
+
+ public static implicit operator Decimal(int value)
+ {
return new Decimal(value);
}
-
+
[CLSCompliant(false)]
- public static implicit operator Decimal(uint value) {
+ public static implicit operator Decimal(uint value)
+ {
return new Decimal(value);
}
-
- public static implicit operator Decimal(long value) {
+
+ public static implicit operator Decimal(long value)
+ {
return new Decimal(value);
}
-
+
[CLSCompliant(false)]
- public static implicit operator Decimal(ulong value) {
+ public static implicit operator Decimal(ulong value)
+ {
return new Decimal(value);
}
-
-
- public static explicit operator Decimal(float value) {
+
+
+ public static explicit operator Decimal(float value)
+ {
return new Decimal(value);
}
-
- public static explicit operator Decimal(double value) {
+
+ public static explicit operator Decimal(double value)
+ {
return new Decimal(value);
}
-
- public static explicit operator byte(Decimal value) {
+
+ public static explicit operator byte(Decimal value)
+ {
return ToByte(value);
}
-
+
[CLSCompliant(false)]
- public static explicit operator sbyte(Decimal value) {
+ public static explicit operator sbyte(Decimal value)
+ {
return ToSByte(value);
}
-
- public static explicit operator char(Decimal value) {
+
+ public static explicit operator char(Decimal value)
+ {
UInt16 temp;
- try {
+ try
+ {
temp = ToUInt16(value);
- }
- catch (OverflowException e) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Char"), e);
+ }
+ catch (OverflowException e)
+ {
+ throw new OverflowException(SR.Overflow_Char, e);
}
return (char)temp;
}
- public static explicit operator short(Decimal value) {
+ public static explicit operator short(Decimal value)
+ {
return ToInt16(value);
}
-
+
[CLSCompliant(false)]
- public static explicit operator ushort(Decimal value) {
+ public static explicit operator ushort(Decimal value)
+ {
return ToUInt16(value);
}
-
- public static explicit operator int(Decimal value) {
+
+ public static explicit operator int(Decimal value)
+ {
return ToInt32(value);
}
-
+
[CLSCompliant(false)]
- public static explicit operator uint(Decimal value) {
+ public static explicit operator uint(Decimal value)
+ {
return ToUInt32(value);
}
-
- public static explicit operator long(Decimal value) {
+
+ public static explicit operator long(Decimal value)
+ {
return ToInt64(value);
}
-
+
[CLSCompliant(false)]
- public static explicit operator ulong(Decimal value) {
+ public static explicit operator ulong(Decimal value)
+ {
return ToUInt64(value);
}
-
- public static explicit operator float(Decimal value) {
+
+ public static explicit operator float(Decimal value)
+ {
return ToSingle(value);
}
-
- public static explicit operator double(Decimal value) {
+
+ public static explicit operator double(Decimal value)
+ {
return ToDouble(value);
}
-
- public static Decimal operator +(Decimal d) {
+
+ public static Decimal operator +(Decimal d)
+ {
return d;
}
-
- public static Decimal operator -(Decimal d) {
+
+ public static Decimal operator -(Decimal d)
+ {
return Negate(d);
}
-
- public static Decimal operator ++(Decimal d) {
+
+ public static Decimal operator ++(Decimal d)
+ {
return Add(d, One);
}
-
- public static Decimal operator --(Decimal d) {
+
+ public static Decimal operator --(Decimal d)
+ {
return Subtract(d, One);
}
-
- public static Decimal operator +(Decimal d1, Decimal d2) {
+
+ public static Decimal operator +(Decimal d1, Decimal d2)
+ {
FCallAddSub(ref d1, ref d2, DECIMAL_ADD);
return d1;
}
-
- public static Decimal operator -(Decimal d1, Decimal d2) {
+
+ public static Decimal operator -(Decimal d1, Decimal d2)
+ {
FCallAddSub(ref d1, ref d2, DECIMAL_NEG);
return d1;
}
-
- public static Decimal operator *(Decimal d1, Decimal d2) {
- FCallMultiply (ref d1, ref d2);
+
+ public static Decimal operator *(Decimal d1, Decimal d2)
+ {
+ FCallMultiply(ref d1, ref d2);
return d1;
}
-
- public static Decimal operator /(Decimal d1, Decimal d2) {
- FCallDivide (ref d1, ref d2);
+
+ public static Decimal operator /(Decimal d1, Decimal d2)
+ {
+ FCallDivide(ref d1, ref d2);
return d1;
}
-
- public static Decimal operator %(Decimal d1, Decimal d2) {
+
+ public static Decimal operator %(Decimal d1, Decimal d2)
+ {
return Remainder(d1, d2);
}
-
- public static bool operator ==(Decimal d1, Decimal d2) {
+
+ public static bool operator ==(Decimal d1, Decimal d2)
+ {
return FCallCompare(ref d1, ref d2) == 0;
}
- public static bool operator !=(Decimal d1, Decimal d2) {
+ public static bool operator !=(Decimal d1, Decimal d2)
+ {
return FCallCompare(ref d1, ref d2) != 0;
}
- public static bool operator <(Decimal d1, Decimal d2) {
+ public static bool operator <(Decimal d1, Decimal d2)
+ {
return FCallCompare(ref d1, ref d2) < 0;
}
- public static bool operator <=(Decimal d1, Decimal d2) {
+ public static bool operator <=(Decimal d1, Decimal d2)
+ {
return FCallCompare(ref d1, ref d2) <= 0;
}
- public static bool operator >(Decimal d1, Decimal d2) {
+ public static bool operator >(Decimal d1, Decimal d2)
+ {
return FCallCompare(ref d1, ref d2) > 0;
}
- public static bool operator >=(Decimal d1, Decimal d2) {
+ public static bool operator >=(Decimal d1, Decimal d2)
+ {
return FCallCompare(ref d1, ref d2) >= 0;
}
@@ -1095,83 +1225,84 @@ namespace System {
// IConvertible implementation
//
- public TypeCode GetTypeCode() {
+ public TypeCode GetTypeCode()
+ {
return TypeCode.Decimal;
}
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
- return Convert.ToBoolean(this);
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
+ return Convert.ToBoolean(this);
}
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Decimal", "Char"));
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Decimal", "Char"));
}
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
return Convert.ToSByte(this);
}
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
return Convert.ToByte(this);
}
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
return Convert.ToInt16(this);
}
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
return Convert.ToUInt16(this);
}
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
return Convert.ToInt32(this);
}
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
return Convert.ToUInt32(this);
}
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
return Convert.ToInt64(this);
}
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
return Convert.ToUInt64(this);
}
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
return Convert.ToSingle(this);
}
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
return Convert.ToDouble(this);
}
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider) {
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
return this;
}
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Decimal", "DateTime"));
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Decimal", "DateTime"));
}
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
return Convert.DefaultToType((IConvertible)this, type, provider);
}
}
diff --git a/src/mscorlib/src/System/DefaultBinder.CanConvert.cs b/src/mscorlib/src/System/DefaultBinder.CanConvert.cs
new file mode 100644
index 0000000000..09c7298a3d
--- /dev/null
+++ b/src/mscorlib/src/System/DefaultBinder.CanConvert.cs
@@ -0,0 +1,30 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+
+namespace System
+{
+ internal partial class DefaultBinder : Binder
+ {
+ // CanChangePrimitive
+ // This will determine if the source can be converted to the target type
+ private static bool CanChangePrimitive(Type source, Type target) => CanConvertPrimitive((RuntimeType)source, (RuntimeType)target);
+
+ // CanChangePrimitiveObjectToType
+ private static bool CanChangePrimitiveObjectToType(object source, Type type) => CanConvertPrimitiveObjectToType(source, (RuntimeType)type);
+
+ // CanConvertPrimitive
+ // This will determine if the source can be converted to the target type
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern bool CanConvertPrimitive(RuntimeType source, RuntimeType target);
+
+ // CanConvertPrimitiveObjectToType
+ // This method will determine if the primitive object can be converted
+ // to a type.
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern bool CanConvertPrimitiveObjectToType(object source, RuntimeType type);
+ }
+}
diff --git a/src/mscorlib/src/System/DefaultBinder.cs b/src/mscorlib/src/System/DefaultBinder.cs
deleted file mode 100644
index b4681c406d..0000000000
--- a/src/mscorlib/src/System/DefaultBinder.cs
+++ /dev/null
@@ -1,1162 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// This class represents the Default COM+ binder.
-//
-//
-namespace System {
-
- using System;
- using System.Reflection;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using CultureInfo = System.Globalization.CultureInfo;
- //Marked serializable even though it has no state.
- [Serializable]
- internal class DefaultBinder : Binder
- {
- // This method is passed a set of methods and must choose the best
- // fit. The methods all have the same number of arguments and the object
- // array args. On exit, this method will choice the best fit method
- // and coerce the args to match that method. By match, we mean all primitive
- // arguments are exact matchs and all object arguments are exact or subclasses
- // of the target. If the target OR is an interface, the object must implement
- // that interface. There are a couple of exceptions
- // thrown when a method cannot be returned. If no method matchs the args and
- // ArgumentException is thrown. If multiple methods match the args then
- // an AmbiguousMatchException is thrown.
- //
- // The most specific match will be selected.
- //
- public override MethodBase BindToMethod(
- BindingFlags bindingAttr, MethodBase[] match, ref Object[] args,
- ParameterModifier[] modifiers, CultureInfo cultureInfo, String[] names, out Object state)
- {
- if (match == null || match.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), nameof(match));
- Contract.EndContractBlock();
-
- MethodBase[] candidates = (MethodBase[]) match.Clone();
-
- int i;
- int j;
-
- state = null;
-
- #region Map named parameters to candidate parameter postions
- // We are creating an paramOrder array to act as a mapping
- // between the order of the args and the actual order of the
- // parameters in the method. This order may differ because
- // named parameters (names) may change the order. If names
- // is not provided, then we assume the default mapping (0,1,...)
- int[][] paramOrder = new int[candidates.Length][];
-
- for (i = 0; i < candidates.Length; i++)
- {
- ParameterInfo[] par = candidates[i].GetParametersNoCopy();
-
- // args.Length + 1 takes into account the possibility of a last paramArray that can be omitted
- paramOrder[i] = new int[(par.Length > args.Length) ? par.Length : args.Length];
-
- if (names == null)
- {
- // Default mapping
- for (j = 0; j < args.Length; j++)
- paramOrder[i][j] = j;
- }
- else
- {
- // Named parameters, reorder the mapping. If CreateParamOrder fails, it means that the method
- // doesn't have a name that matchs one of the named parameters so we don't consider it any further.
- if (!CreateParamOrder(paramOrder[i], par, names))
- candidates[i] = null;
- }
- }
- #endregion
-
- Type[] paramArrayTypes = new Type[candidates.Length];
-
- Type[] argTypes = new Type[args.Length];
-
- #region Cache the type of the provided arguments
- // object that contain a null are treated as if they were typeless (but match either object
- // references or value classes). We mark this condition by placing a null in the argTypes array.
- for (i = 0; i < args.Length; i++)
- {
- if (args[i] != null)
- {
- argTypes[i] = args[i].GetType();
- }
- }
- #endregion
-
-
- // Find the method that matches...
- int CurIdx = 0;
- bool defaultValueBinding = ((bindingAttr & BindingFlags.OptionalParamBinding) != 0);
-
- Type paramArrayType = null;
-
- #region Filter methods by parameter count and type
- for (i = 0; i < candidates.Length; i++)
- {
- paramArrayType = null;
-
- // If we have named parameters then we may have a hole in the candidates array.
- if (candidates[i] == null)
- continue;
-
- // Validate the parameters.
- ParameterInfo[] par = candidates[i].GetParametersNoCopy();
-
- #region Match method by parameter count
- if (par.Length == 0)
- {
- #region No formal parameters
- if (args.Length != 0)
- {
- if ((candidates[i].CallingConvention & CallingConventions.VarArgs) == 0)
- continue;
- }
-
- // This is a valid routine so we move it up the candidates list.
- paramOrder[CurIdx] = paramOrder[i];
- candidates[CurIdx++] = candidates[i];
-
- continue;
- #endregion
- }
- else if (par.Length > args.Length)
- {
- #region Shortage of provided parameters
- // If the number of parameters is greater than the number of args then
- // we are in the situation were we may be using default values.
- for (j = args.Length; j < par.Length - 1; j++)
- {
- if (par[j].DefaultValue == System.DBNull.Value)
- break;
- }
-
- if (j != par.Length - 1)
- continue;
-
- if (par[j].DefaultValue == System.DBNull.Value)
- {
- if (!par[j].ParameterType.IsArray)
- continue;
-
- if (!par[j].IsDefined(typeof(ParamArrayAttribute), true))
- continue;
-
- paramArrayType = par[j].ParameterType.GetElementType();
- }
- #endregion
- }
- else if (par.Length < args.Length)
- {
- #region Excess provided parameters
- // test for the ParamArray case
- int lastArgPos = par.Length - 1;
-
- if (!par[lastArgPos].ParameterType.IsArray)
- continue;
-
- if (!par[lastArgPos].IsDefined(typeof(ParamArrayAttribute), true))
- continue;
-
- if (paramOrder[i][lastArgPos] != lastArgPos)
- continue;
-
- paramArrayType = par[lastArgPos].ParameterType.GetElementType();
- #endregion
- }
- else
- {
- #region Test for paramArray, save paramArray type
- int lastArgPos = par.Length - 1;
-
- if (par[lastArgPos].ParameterType.IsArray
- && par[lastArgPos].IsDefined(typeof(ParamArrayAttribute), true)
- && paramOrder[i][lastArgPos] == lastArgPos)
- {
- if (!par[lastArgPos].ParameterType.IsAssignableFrom(argTypes[lastArgPos]))
- paramArrayType = par[lastArgPos].ParameterType.GetElementType();
- }
- #endregion
- }
- #endregion
-
- Type pCls = null;
- int argsToCheck = (paramArrayType != null) ? par.Length - 1 : args.Length;
-
- #region Match method by parameter type
- for (j = 0; j < argsToCheck; j++)
- {
- #region Classic argument coersion checks
- // get the formal type
- pCls = par[j].ParameterType;
-
- if (pCls.IsByRef)
- pCls = pCls.GetElementType();
-
- // the type is the same
- if (pCls == argTypes[paramOrder[i][j]])
- continue;
-
- // a default value is available
- if (defaultValueBinding && args[paramOrder[i][j]] == Type.Missing)
- continue;
-
- // the argument was null, so it matches with everything
- if (args[paramOrder[i][j]] == null)
- continue;
-
- // the type is Object, so it will match everything
- if (pCls == typeof(Object))
- continue;
-
- // now do a "classic" type check
- if (pCls.IsPrimitive)
- {
- if (argTypes[paramOrder[i][j]] == null || !CanConvertPrimitiveObjectToType(args[paramOrder[i][j]],(RuntimeType)pCls))
- {
- break;
- }
- }
- else
- {
- if (argTypes[paramOrder[i][j]] == null)
- continue;
-
- if (!pCls.IsAssignableFrom(argTypes[paramOrder[i][j]]))
- {
- if (argTypes[paramOrder[i][j]].IsCOMObject)
- {
- if (pCls.IsInstanceOfType(args[paramOrder[i][j]]))
- continue;
- }
- break;
- }
- }
- #endregion
- }
-
- if (paramArrayType != null && j == par.Length - 1)
- {
- #region Check that excess arguments can be placed in the param array
- for (; j < args.Length; j++)
- {
- if (paramArrayType.IsPrimitive)
- {
- if (argTypes[j] == null || !CanConvertPrimitiveObjectToType(args[j], (RuntimeType)paramArrayType))
- break;
- }
- else
- {
- if (argTypes[j] == null)
- continue;
-
- if (!paramArrayType.IsAssignableFrom(argTypes[j]))
- {
- if (argTypes[j].IsCOMObject)
- {
- if (paramArrayType.IsInstanceOfType(args[j]))
- continue;
- }
-
- break;
- }
- }
- }
- #endregion
- }
- #endregion
-
- if (j == args.Length)
- {
- #region This is a valid routine so we move it up the candidates list
- paramOrder[CurIdx] = paramOrder[i];
- paramArrayTypes[CurIdx] = paramArrayType;
- candidates[CurIdx++] = candidates[i];
- #endregion
- }
- }
- #endregion
-
- // If we didn't find a method
- if (CurIdx == 0)
- throw new MissingMethodException(Environment.GetResourceString("MissingMember"));
-
- if (CurIdx == 1)
- {
- #region Found only one method
- if (names != null)
- {
- state = new BinderState((int[])paramOrder[0].Clone(), args.Length, paramArrayTypes[0] != null);
- ReorderParams(paramOrder[0],args);
- }
-
- // If the parameters and the args are not the same length or there is a paramArray
- // then we need to create a argument array.
- ParameterInfo[] parms = candidates[0].GetParametersNoCopy();
-
- if (parms.Length == args.Length)
- {
- if (paramArrayTypes[0] != null)
- {
- Object[] objs = new Object[parms.Length];
- int lastPos = parms.Length - 1;
- Array.Copy(args, 0, objs, 0, lastPos);
- objs[lastPos] = Array.UnsafeCreateInstance(paramArrayTypes[0], 1);
- ((Array)objs[lastPos]).SetValue(args[lastPos], 0);
- args = objs;
- }
- }
- else if (parms.Length > args.Length)
- {
- Object[] objs = new Object[parms.Length];
-
- for (i=0;i<args.Length;i++)
- objs[i] = args[i];
-
- for (;i<parms.Length - 1;i++)
- objs[i] = parms[i].DefaultValue;
-
- if (paramArrayTypes[0] != null)
- objs[i] = Array.UnsafeCreateInstance(paramArrayTypes[0], 0); // create an empty array for the
-
- else
- objs[i] = parms[i].DefaultValue;
-
- args = objs;
- }
- else
- {
- if ((candidates[0].CallingConvention & CallingConventions.VarArgs) == 0)
- {
- Object[] objs = new Object[parms.Length];
- int paramArrayPos = parms.Length - 1;
- Array.Copy(args, 0, objs, 0, paramArrayPos);
- objs[paramArrayPos] = Array.UnsafeCreateInstance(paramArrayTypes[0], args.Length - paramArrayPos);
- Array.Copy(args, paramArrayPos, (System.Array)objs[paramArrayPos], 0, args.Length - paramArrayPos);
- args = objs;
- }
- }
- #endregion
-
- return candidates[0];
- }
-
- int currentMin = 0;
- bool ambig = false;
- for (i = 1; i < CurIdx; i++)
- {
- #region Walk all of the methods looking the most specific method to invoke
- int newMin = FindMostSpecificMethod(candidates[currentMin], paramOrder[currentMin], paramArrayTypes[currentMin],
- candidates[i], paramOrder[i], paramArrayTypes[i], argTypes, args);
-
- if (newMin == 0)
- {
- ambig = true;
- }
- else if (newMin == 2)
- {
- currentMin = i;
- ambig = false;
- }
- #endregion
- }
-
- if (ambig)
- throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
-
- // Reorder (if needed)
- if (names != null) {
- state = new BinderState((int[])paramOrder[currentMin].Clone(), args.Length, paramArrayTypes[currentMin] != null);
- ReorderParams(paramOrder[currentMin], args);
- }
-
- // If the parameters and the args are not the same length or there is a paramArray
- // then we need to create a argument array.
- ParameterInfo[] parameters = candidates[currentMin].GetParametersNoCopy();
- if (parameters.Length == args.Length)
- {
- if (paramArrayTypes[currentMin] != null)
- {
- Object[] objs = new Object[parameters.Length];
- int lastPos = parameters.Length - 1;
- Array.Copy(args, 0, objs, 0, lastPos);
- objs[lastPos] = Array.UnsafeCreateInstance(paramArrayTypes[currentMin], 1);
- ((Array)objs[lastPos]).SetValue(args[lastPos], 0);
- args = objs;
- }
- }
- else if (parameters.Length > args.Length)
- {
- Object[] objs = new Object[parameters.Length];
-
- for (i=0;i<args.Length;i++)
- objs[i] = args[i];
-
- for (;i<parameters.Length - 1;i++)
- objs[i] = parameters[i].DefaultValue;
-
- if (paramArrayTypes[currentMin] != null)
- {
- objs[i] = Array.UnsafeCreateInstance(paramArrayTypes[currentMin], 0);
- }
- else
- {
- objs[i] = parameters[i].DefaultValue;
- }
-
- args = objs;
- }
- else
- {
- if ((candidates[currentMin].CallingConvention & CallingConventions.VarArgs) == 0)
- {
- Object[] objs = new Object[parameters.Length];
- int paramArrayPos = parameters.Length - 1;
- Array.Copy(args, 0, objs, 0, paramArrayPos);
- objs[paramArrayPos] = Array.UnsafeCreateInstance(paramArrayTypes[currentMin], args.Length - paramArrayPos);
- Array.Copy(args, paramArrayPos, (System.Array)objs[paramArrayPos], 0, args.Length - paramArrayPos);
- args = objs;
- }
- }
-
- return candidates[currentMin];
- }
-
-
- // Given a set of fields that match the base criteria, select a field.
- // if value is null then we have no way to select a field
- public override FieldInfo BindToField(BindingFlags bindingAttr,FieldInfo[] match, Object value,CultureInfo cultureInfo)
- {
- if (match == null) {
- throw new ArgumentNullException(nameof(match));
- }
-
- int i;
- // Find the method that match...
- int CurIdx = 0;
-
- Type valueType = null;
-
- FieldInfo[] candidates = (FieldInfo[]) match.Clone();
-
- // If we are a FieldSet, then use the value's type to disambiguate
- if ((bindingAttr & BindingFlags.SetField) != 0) {
- valueType = value.GetType();
-
- for (i=0;i<candidates.Length;i++) {
- Type pCls = candidates[i].FieldType;
- if (pCls == valueType) {
- candidates[CurIdx++] = candidates[i];
- continue;
- }
- if (value == Empty.Value) {
- // the object passed in was null which would match any non primitive non value type
- if (pCls.IsClass) {
- candidates[CurIdx++] = candidates[i];
- continue;
- }
- }
- if (pCls == typeof(Object)) {
- candidates[CurIdx++] = candidates[i];
- continue;
- }
- if (pCls.IsPrimitive) {
- if (CanConvertPrimitiveObjectToType(value,(RuntimeType)pCls)) {
- candidates[CurIdx++] = candidates[i];
- continue;
- }
- }
- else {
- if (pCls.IsAssignableFrom(valueType)) {
- candidates[CurIdx++] = candidates[i];
- continue;
- }
- }
- }
- if (CurIdx == 0)
- throw new MissingFieldException(Environment.GetResourceString("MissingField"));
- if (CurIdx == 1)
- return candidates[0];
- }
-
- // Walk all of the methods looking the most specific method to invoke
- int currentMin = 0;
- bool ambig = false;
- for (i=1;i<CurIdx;i++) {
- int newMin = FindMostSpecificField(candidates[currentMin], candidates[i]);
- if (newMin == 0)
- ambig = true;
- else {
- if (newMin == 2) {
- currentMin = i;
- ambig = false;
- }
- }
- }
- if (ambig)
- throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
- return candidates[currentMin];
- }
-
- // Given a set of methods that match the base criteria, select a method based
- // upon an array of types. This method should return null if no method matchs
- // the criteria.
- public override MethodBase SelectMethod(BindingFlags bindingAttr,MethodBase[] match,Type[] types,ParameterModifier[] modifiers)
- {
- int i;
- int j;
-
- Type[] realTypes = new Type[types.Length];
- for (i=0;i<types.Length;i++) {
- realTypes[i] = types[i].UnderlyingSystemType;
- if (!(realTypes[i] is RuntimeType))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(types));
- }
- types = realTypes;
-
- // We don't automatically jump out on exact match.
- if (match == null || match.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), nameof(match));
-
- MethodBase[] candidates = (MethodBase[]) match.Clone();
-
- // Find all the methods that can be described by the types parameter.
- // Remove all of them that cannot.
- int CurIdx = 0;
- for (i=0;i<candidates.Length;i++) {
- ParameterInfo[] par = candidates[i].GetParametersNoCopy();
- if (par.Length != types.Length)
- continue;
- for (j=0;j<types.Length;j++) {
- Type pCls = par[j].ParameterType;
- if (pCls == types[j])
- continue;
- if (pCls == typeof(Object))
- continue;
- if (pCls.IsPrimitive) {
- if (!(types[j].UnderlyingSystemType is RuntimeType) ||
- !CanConvertPrimitive((RuntimeType)types[j].UnderlyingSystemType,(RuntimeType)pCls.UnderlyingSystemType))
- break;
- }
- else {
- if (!pCls.IsAssignableFrom(types[j]))
- break;
- }
- }
- if (j == types.Length)
- candidates[CurIdx++] = candidates[i];
- }
- if (CurIdx == 0)
- return null;
- if (CurIdx == 1)
- return candidates[0];
-
- // Walk all of the methods looking the most specific method to invoke
- int currentMin = 0;
- bool ambig = false;
- int[] paramOrder = new int[types.Length];
- for (i=0;i<types.Length;i++)
- paramOrder[i] = i;
- for (i=1;i<CurIdx;i++) {
- int newMin = FindMostSpecificMethod(candidates[currentMin], paramOrder, null, candidates[i], paramOrder, null, types, null);
- if (newMin == 0)
- ambig = true;
- else {
- if (newMin == 2) {
- currentMin = i;
- ambig = false;
- currentMin = i;
- }
- }
- }
- if (ambig)
- throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
- return candidates[currentMin];
- }
-
- // Given a set of properties that match the base criteria, select one.
- public override PropertyInfo SelectProperty(BindingFlags bindingAttr,PropertyInfo[] match,Type returnType,
- Type[] indexes,ParameterModifier[] modifiers)
- {
- // Allow a null indexes array. But if it is not null, every element must be non-null as well.
- if (indexes != null && !Contract.ForAll(indexes, delegate(Type t) { return t != null; }))
- {
- throw new ArgumentNullException(nameof(indexes));
- }
- if (match == null || match.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), nameof(match));
- Contract.EndContractBlock();
-
- PropertyInfo[] candidates = (PropertyInfo[]) match.Clone();
-
- int i,j = 0;
-
- // Find all the properties that can be described by type indexes parameter
- int CurIdx = 0;
- int indexesLength = (indexes != null) ? indexes.Length : 0;
- for (i=0;i<candidates.Length;i++) {
-
- if (indexes != null)
- {
- ParameterInfo[] par = candidates[i].GetIndexParameters();
- if (par.Length != indexesLength)
- continue;
-
- for (j=0;j<indexesLength;j++) {
- Type pCls = par[j]. ParameterType;
-
- // If the classes exactly match continue
- if (pCls == indexes[j])
- continue;
- if (pCls == typeof(Object))
- continue;
-
- if (pCls.IsPrimitive) {
- if (!(indexes[j].UnderlyingSystemType is RuntimeType) ||
- !CanConvertPrimitive((RuntimeType)indexes[j].UnderlyingSystemType,(RuntimeType)pCls.UnderlyingSystemType))
- break;
- }
- else {
- if (!pCls.IsAssignableFrom(indexes[j]))
- break;
- }
- }
- }
-
- if (j == indexesLength) {
- if (returnType != null) {
- if (candidates[i].PropertyType.IsPrimitive) {
- if (!(returnType.UnderlyingSystemType is RuntimeType) ||
- !CanConvertPrimitive((RuntimeType)returnType.UnderlyingSystemType,(RuntimeType)candidates[i].PropertyType.UnderlyingSystemType))
- continue;
- }
- else {
- if (!candidates[i].PropertyType.IsAssignableFrom(returnType))
- continue;
- }
- }
- candidates[CurIdx++] = candidates[i];
- }
- }
- if (CurIdx == 0)
- return null;
- if (CurIdx == 1)
- return candidates[0];
-
- // Walk all of the properties looking the most specific method to invoke
- int currentMin = 0;
- bool ambig = false;
- int[] paramOrder = new int[indexesLength];
- for (i=0;i<indexesLength;i++)
- paramOrder[i] = i;
- for (i=1;i<CurIdx;i++) {
- int newMin = FindMostSpecificType(candidates[currentMin].PropertyType, candidates[i].PropertyType,returnType);
- if (newMin == 0 && indexes != null)
- newMin = FindMostSpecific(candidates[currentMin].GetIndexParameters(),
- paramOrder,
- null,
- candidates[i].GetIndexParameters(),
- paramOrder,
- null,
- indexes,
- null);
- if (newMin == 0)
- {
- newMin = FindMostSpecificProperty(candidates[currentMin], candidates[i]);
- if (newMin == 0)
- ambig = true;
- }
- if (newMin == 2) {
- ambig = false;
- currentMin = i;
- }
- }
-
- if (ambig)
- throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
- return candidates[currentMin];
- }
-
- // ChangeType
- // The default binder doesn't support any change type functionality.
- // This is because the default is built into the low level invoke code.
- public override Object ChangeType(Object value,Type type,CultureInfo cultureInfo)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ChangeType"));
- }
-
- public override void ReorderArgumentArray(ref Object[] args, Object state)
- {
- BinderState binderState = (BinderState)state;
- ReorderParams(binderState.m_argsMap, args);
- if (binderState.m_isParamArray) {
- int paramArrayPos = args.Length - 1;
- if (args.Length == binderState.m_originalSize)
- args[paramArrayPos] = ((Object[])args[paramArrayPos])[0];
- else {
- // must be args.Length < state.originalSize
- Object[] newArgs = new Object[args.Length];
- Array.Copy(args, 0, newArgs, 0, paramArrayPos);
- for (int i = paramArrayPos, j = 0; i < newArgs.Length; i++, j++) {
- newArgs[i] = ((Object[])args[paramArrayPos])[j];
- }
- args = newArgs;
- }
- }
- else {
- if (args.Length > binderState.m_originalSize) {
- Object[] newArgs = new Object[binderState.m_originalSize];
- Array.Copy(args, 0, newArgs, 0, binderState.m_originalSize);
- args = newArgs;
- }
- }
- }
-
- // Return any exact bindings that may exist. (This method is not defined on the
- // Binder and is used by RuntimeType.)
- public static MethodBase ExactBinding(MethodBase[] match,Type[] types,ParameterModifier[] modifiers)
- {
- if (match==null)
- throw new ArgumentNullException(nameof(match));
- Contract.EndContractBlock();
- MethodBase[] aExactMatches = new MethodBase[match.Length];
- int cExactMatches = 0;
-
- for (int i=0;i<match.Length;i++) {
- ParameterInfo[] par = match[i].GetParametersNoCopy();
- if (par.Length == 0) {
- continue;
- }
- int j;
- for (j=0;j<types.Length;j++) {
- Type pCls = par[j]. ParameterType;
-
- // If the classes exactly match continue
- if (!pCls.Equals(types[j]))
- break;
- }
- if (j < types.Length)
- continue;
-
- // Add the exact match to the array of exact matches.
- aExactMatches[cExactMatches] = match[i];
- cExactMatches++;
- }
-
- if (cExactMatches == 0)
- return null;
-
- if (cExactMatches == 1)
- return aExactMatches[0];
-
- return FindMostDerivedNewSlotMeth(aExactMatches, cExactMatches);
- }
-
- // Return any exact bindings that may exist. (This method is not defined on the
- // Binder and is used by RuntimeType.)
- public static PropertyInfo ExactPropertyBinding(PropertyInfo[] match,Type returnType,Type[] types,ParameterModifier[] modifiers)
- {
- if (match==null)
- throw new ArgumentNullException(nameof(match));
- Contract.EndContractBlock();
-
- PropertyInfo bestMatch = null;
- int typesLength = (types != null) ? types.Length : 0;
- for (int i=0;i<match.Length;i++) {
- ParameterInfo[] par = match[i].GetIndexParameters();
- int j;
- for (j=0;j<typesLength;j++) {
- Type pCls = par[j].ParameterType;
-
- // If the classes exactly match continue
- if (pCls != types[j])
- break;
- }
- if (j < typesLength)
- continue;
- if (returnType != null && returnType != match[i].PropertyType)
- continue;
-
- if (bestMatch != null)
- throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
-
- bestMatch = match[i];
- }
- return bestMatch;
- }
-
- private static int FindMostSpecific(ParameterInfo[] p1, int[] paramOrder1, Type paramArrayType1,
- ParameterInfo[] p2, int[] paramOrder2, Type paramArrayType2,
- Type[] types, Object[] args)
- {
- // A method using params is always less specific than one not using params
- if (paramArrayType1 != null && paramArrayType2 == null) return 2;
- if (paramArrayType2 != null && paramArrayType1 == null) return 1;
-
- // now either p1 and p2 both use params or neither does.
-
- bool p1Less = false;
- bool p2Less = false;
-
- for (int i = 0; i < types.Length; i++)
- {
- if (args != null && args[i] == Type.Missing)
- continue;
-
- Type c1, c2;
-
- // If a param array is present, then either
- // the user re-ordered the parameters in which case
- // the argument to the param array is either an array
- // in which case the params is conceptually ignored and so paramArrayType1 == null
- // or the argument to the param array is a single element
- // in which case paramOrder[i] == p1.Length - 1 for that element
- // or the user did not re-order the parameters in which case
- // the paramOrder array could contain indexes larger than p.Length - 1 (see VSW 577286)
- // so any index >= p.Length - 1 is being put in the param array
-
- if (paramArrayType1 != null && paramOrder1[i] >= p1.Length - 1)
- c1 = paramArrayType1;
- else
- c1 = p1[paramOrder1[i]].ParameterType;
-
- if (paramArrayType2 != null && paramOrder2[i] >= p2.Length - 1)
- c2 = paramArrayType2;
- else
- c2 = p2[paramOrder2[i]].ParameterType;
-
- if (c1 == c2) continue;
-
- switch (FindMostSpecificType(c1, c2, types[i])) {
- case 0: return 0;
- case 1: p1Less = true; break;
- case 2: p2Less = true; break;
- }
- }
-
- // Two way p1Less and p2Less can be equal. All the arguments are the
- // same they both equal false, otherwise there were things that both
- // were the most specific type on....
- if (p1Less == p2Less)
- {
- // if we cannot tell which is a better match based on parameter types (p1Less == p2Less),
- // let's see which one has the most matches without using the params array (the longer one wins).
- if (!p1Less && args != null)
- {
- if (p1.Length > p2.Length)
- {
- return 1;
- }
- else if (p2.Length > p1.Length)
- {
- return 2;
- }
- }
-
- return 0;
- }
- else
- {
- return (p1Less == true) ? 1 : 2;
- }
- }
-
- private static int FindMostSpecificType(Type c1, Type c2, Type t)
- {
- // If the two types are exact move on...
- if (c1 == c2)
- return 0;
-
- if (c1 == t)
- return 1;
-
- if (c2 == t)
- return 2;
-
- bool c1FromC2;
- bool c2FromC1;
-
- if (c1.IsByRef || c2.IsByRef)
- {
- if (c1.IsByRef && c2.IsByRef)
- {
- c1 = c1.GetElementType();
- c2 = c2.GetElementType();
- }
- else if (c1.IsByRef)
- {
- if (c1.GetElementType() == c2)
- return 2;
-
- c1 = c1.GetElementType();
- }
- else
- {
- if (c2.GetElementType() == c1)
- return 1;
-
- c2 = c2.GetElementType();
- }
- }
-
-
- if (c1.IsPrimitive && c2.IsPrimitive)
- {
- c1FromC2 = CanConvertPrimitive((RuntimeType)c2, (RuntimeType)c1);
- c2FromC1 = CanConvertPrimitive((RuntimeType)c1, (RuntimeType)c2);
- }
- else
- {
- c1FromC2 = c1.IsAssignableFrom(c2);
- c2FromC1 = c2.IsAssignableFrom(c1);
- }
-
- if (c1FromC2 == c2FromC1)
- return 0;
-
- if (c1FromC2)
- {
- return 2;
- }
- else
- {
- return 1;
- }
- }
-
- private static int FindMostSpecificMethod(MethodBase m1, int[] paramOrder1, Type paramArrayType1,
- MethodBase m2, int[] paramOrder2, Type paramArrayType2,
- Type[] types, Object[] args)
- {
- // Find the most specific method based on the parameters.
- int res = FindMostSpecific(m1.GetParametersNoCopy(), paramOrder1, paramArrayType1,
- m2.GetParametersNoCopy(), paramOrder2, paramArrayType2, types, args);
-
- // If the match was not ambigous then return the result.
- if (res != 0)
- return res;
-
- // Check to see if the methods have the exact same name and signature.
- if (CompareMethodSigAndName(m1, m2))
- {
- // Determine the depth of the declaring types for both methods.
- int hierarchyDepth1 = GetHierarchyDepth(m1.DeclaringType);
- int hierarchyDepth2 = GetHierarchyDepth(m2.DeclaringType);
-
- // The most derived method is the most specific one.
- if (hierarchyDepth1 == hierarchyDepth2)
- {
- return 0;
- }
- else if (hierarchyDepth1 < hierarchyDepth2)
- {
- return 2;
- }
- else
- {
- return 1;
- }
- }
-
- // The match is ambigous.
- return 0;
- }
-
- private static int FindMostSpecificField(FieldInfo cur1,FieldInfo cur2)
- {
- // Check to see if the fields have the same name.
- if (cur1.Name == cur2.Name)
- {
- int hierarchyDepth1 = GetHierarchyDepth(cur1.DeclaringType);
- int hierarchyDepth2 = GetHierarchyDepth(cur2.DeclaringType);
-
- if (hierarchyDepth1 == hierarchyDepth2) {
- Debug.Assert(cur1.IsStatic != cur2.IsStatic, "hierarchyDepth1 == hierarchyDepth2");
- return 0;
- }
- else if (hierarchyDepth1 < hierarchyDepth2)
- return 2;
- else
- return 1;
- }
-
- // The match is ambigous.
- return 0;
- }
-
- private static int FindMostSpecificProperty(PropertyInfo cur1,PropertyInfo cur2)
- {
- // Check to see if the fields have the same name.
- if (cur1.Name == cur2.Name)
- {
- int hierarchyDepth1 = GetHierarchyDepth(cur1.DeclaringType);
- int hierarchyDepth2 = GetHierarchyDepth(cur2.DeclaringType);
-
- if (hierarchyDepth1 == hierarchyDepth2) {
- return 0;
- }
- else if (hierarchyDepth1 < hierarchyDepth2)
- return 2;
- else
- return 1;
- }
-
- // The match is ambigous.
- return 0;
- }
-
- internal static bool CompareMethodSigAndName(MethodBase m1, MethodBase m2)
- {
- ParameterInfo[] params1 = m1.GetParametersNoCopy();
- ParameterInfo[] params2 = m2.GetParametersNoCopy();
-
- if (params1.Length != params2.Length)
- return false;
-
- int numParams = params1.Length;
- for (int i = 0; i < numParams; i++)
- {
- if (params1[i].ParameterType != params2[i].ParameterType)
- return false;
- }
-
- return true;
- }
-
- internal static int GetHierarchyDepth(Type t)
- {
- int depth = 0;
-
- Type currentType = t;
- do
- {
- depth++;
- currentType = currentType.BaseType;
- } while (currentType != null);
-
- return depth;
- }
-
- internal static MethodBase FindMostDerivedNewSlotMeth(MethodBase[] match, int cMatches)
- {
- int deepestHierarchy = 0;
- MethodBase methWithDeepestHierarchy = null;
-
- for (int i = 0; i < cMatches; i++)
- {
- // Calculate the depth of the hierarchy of the declaring type of the
- // current method.
- int currentHierarchyDepth = GetHierarchyDepth(match[i].DeclaringType);
-
- // The two methods have the same name, signature, and hierarchy depth.
- // This can only happen if at least one is vararg or generic.
- if (currentHierarchyDepth == deepestHierarchy)
- {
- throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
- }
-
- // Check to see if this method is on the most derived class.
- if (currentHierarchyDepth > deepestHierarchy)
- {
- deepestHierarchy = currentHierarchyDepth;
- methWithDeepestHierarchy = match[i];
- }
- }
-
- return methWithDeepestHierarchy;
- }
-
- // CanConvertPrimitive
- // This will determine if the source can be converted to the target type
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern bool CanConvertPrimitive(RuntimeType source,RuntimeType target);
-
- // CanConvertPrimitiveObjectToType
- // This method will determine if the primitive object can be converted
- // to a type.
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static internal extern bool CanConvertPrimitiveObjectToType(Object source,RuntimeType type);
-
- // This method will sort the vars array into the mapping order stored
- // in the paramOrder array.
- private static void ReorderParams(int[] paramOrder,Object[] vars)
- {
- object[] varsCopy = new object[vars.Length];
- for (int i = 0; i < vars.Length; i ++)
- varsCopy[i] = vars[i];
-
- for (int i = 0; i < vars.Length; i ++)
- vars[i] = varsCopy[paramOrder[i]];
- }
-
- // This method will create the mapping between the Parameters and the underlying
- // data based upon the names array. The names array is stored in the same order
- // as the values and maps to the parameters of the method. We store the mapping
- // from the parameters to the names in the paramOrder array. All parameters that
- // don't have matching names are then stored in the array in order.
- private static bool CreateParamOrder(int[] paramOrder,ParameterInfo[] pars,String[] names)
- {
- bool[] used = new bool[pars.Length];
-
- // Mark which parameters have not been found in the names list
- for (int i=0;i<pars.Length;i++)
- paramOrder[i] = -1;
- // Find the parameters with names.
- for (int i=0;i<names.Length;i++) {
- int j;
- for (j=0;j<pars.Length;j++) {
- if (names[i].Equals(pars[j].Name)) {
- paramOrder[j] = i;
- used[i] = true;
- break;
- }
- }
- // This is an error condition. The name was not found. This
- // method must not match what we sent.
- if (j == pars.Length)
- return false;
- }
-
- // Now we fill in the holes with the parameters that are unused.
- int pos = 0;
- for (int i=0;i<pars.Length;i++) {
- if (paramOrder[i] == -1) {
- for (;pos<pars.Length;pos++) {
- if (!used[pos]) {
- paramOrder[i] = pos;
- pos++;
- break;
- }
- }
- }
- }
- return true;
- }
-
- internal class BinderState {
- internal int[] m_argsMap;
- internal int m_originalSize;
- internal bool m_isParamArray;
-
- internal BinderState(int[] argsMap, int originalSize, bool isParamArray) {
- m_argsMap = argsMap;
- m_originalSize = originalSize;
- m_isParamArray = isParamArray;
- }
-
- }
-
- }
-}
diff --git a/src/mscorlib/src/System/Delegate.cs b/src/mscorlib/src/System/Delegate.cs
index fb9dc4b110..de0ff6532c 100644
--- a/src/mscorlib/src/System/Delegate.cs
+++ b/src/mscorlib/src/System/Delegate.cs
@@ -2,8 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System {
-
+namespace System
+{
using System;
using System.Reflection;
using System.Runtime;
@@ -18,7 +18,7 @@ namespace System {
[Serializable]
[ClassInterface(ClassInterfaceType.AutoDual)]
[System.Runtime.InteropServices.ComVisible(true)]
- public abstract class Delegate : ICloneable, ISerializable
+ public abstract class Delegate : ICloneable, ISerializable
{
// _target is the object we will invoke on
internal Object _target;
@@ -30,7 +30,7 @@ namespace System {
// _methodPtr is a pointer to the method we will invoke
// It could be a small thunk if this is a static or UM call
internal IntPtr _methodPtr;
-
+
// In the case of a static method passed to a delegate, this field stores
// whatever _methodPtr would have stored: and _methodPtr points to a
// small thunk which removes the "this" pointer before going on
@@ -39,15 +39,15 @@ namespace System {
// This constructor is called from the class generated by the
// compiler generated code
- protected Delegate(Object target,String method)
+ protected Delegate(Object target, String method)
{
if (target == null)
throw new ArgumentNullException(nameof(target));
-
+
if (method == null)
throw new ArgumentNullException(nameof(method));
Contract.EndContractBlock();
-
+
// This API existed in v1/v1.1 and only expected to create closed
// instance delegates. Constrain the call to BindToMethodName to
// such and don't allow relaxed signature matching (which could make
@@ -57,19 +57,19 @@ namespace System {
if (!BindToMethodName(target, (RuntimeType)target.GetType(), method,
DelegateBindingFlags.InstanceMethodOnly |
DelegateBindingFlags.ClosedDelegateOnly))
- throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTargMeth"));
+ throw new ArgumentException(SR.Arg_DlgtTargMeth);
}
-
+
// This constructor is called from a class to generate a
// delegate based upon a static method name and the Type object
// for the class defining the method.
- protected unsafe Delegate(Type target,String method)
+ protected unsafe Delegate(Type target, String method)
{
if (target == null)
throw new ArgumentNullException(nameof(target));
if (target.IsGenericType && target.ContainsGenericParameters)
- throw new ArgumentException(Environment.GetResourceString("Arg_UnboundGenParam"), nameof(target));
+ throw new ArgumentException(SR.Arg_UnboundGenParam, nameof(target));
if (method == null)
throw new ArgumentNullException(nameof(method));
@@ -77,7 +77,7 @@ namespace System {
RuntimeType rtTarget = target as RuntimeType;
if (rtTarget == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(target));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(target));
// This API existed in v1/v1.1 and only expected to create open
// static delegates. Constrain the call to BindToMethodName to such
@@ -91,7 +91,7 @@ namespace System {
DelegateBindingFlags.OpenDelegateOnly |
DelegateBindingFlags.CaselessMatching);
}
-
+
// Protect the default constructor so you can't build a delegate
private Delegate()
{
@@ -108,7 +108,7 @@ namespace System {
return DynamicInvokeImpl(args);
}
- protected virtual object DynamicInvokeImpl(object[] args)
+ protected virtual object DynamicInvokeImpl(object[] args)
{
RuntimeMethodHandleInternal method = new RuntimeMethodHandleInternal(GetInvokeMethod());
RuntimeMethodInfo invoke = (RuntimeMethodInfo)RuntimeType.GetMethodBase((RuntimeType)this.GetType(), method);
@@ -116,16 +116,16 @@ namespace System {
return invoke.UnsafeInvoke(this, BindingFlags.Default, null, args, null);
}
-
+
public override bool Equals(Object obj)
- {
+ {
if (obj == null || !InternalEqualTypes(this, obj))
- return false;
+ return false;
- Delegate d = (Delegate) obj;
+ Delegate d = (Delegate)obj;
// do an optimistic check first. This is hopefully cheap enough to be worth
- if (_target == d._target && _methodPtr == d._methodPtr && _methodPtrAux == d._methodPtrAux)
+ if (_target == d._target && _methodPtr == d._methodPtr && _methodPtrAux == d._methodPtrAux)
return true;
// even though the fields were not all equals the delegates may still match
@@ -154,7 +154,7 @@ namespace System {
return false;
*/
- if (_methodPtrAux == d._methodPtrAux)
+ if (_methodPtrAux == d._methodPtrAux)
return true;
// fall through method handle check
}
@@ -163,9 +163,8 @@ namespace System {
//
if (_methodBase == null || d._methodBase == null || !(_methodBase is MethodInfo) || !(d._methodBase is MethodInfo))
return Delegate.InternalEqualMethodHandles(this, d);
- else
+ else
return _methodBase.Equals(d._methodBase);
-
}
public override int GetHashCode()
@@ -188,37 +187,37 @@ namespace System {
if ((Object)a == null) // cast to object for a more efficient test
return b;
- return a.CombineImpl(b);
+ return a.CombineImpl(b);
}
-
+
public static Delegate Combine(params Delegate[] delegates)
{
if (delegates == null || delegates.Length == 0)
return null;
-
+
Delegate d = delegates[0];
for (int i = 1; i < delegates.Length; i++)
- d = Combine(d,delegates[i]);
-
+ d = Combine(d, delegates[i]);
+
return d;
}
-
+
public virtual Delegate[] GetInvocationList()
{
Delegate[] d = new Delegate[1];
d[0] = this;
return d;
}
-
+
// This routine will return the method
public MethodInfo Method
- {
- get
- {
+ {
+ get
+ {
return GetMethodImpl();
}
}
-
+
protected virtual MethodInfo GetMethodImpl()
{
if ((_methodBase == null) || !(_methodBase is MethodInfo))
@@ -226,12 +225,12 @@ namespace System {
IRuntimeMethodInfo method = FindMethodHandle();
RuntimeType declaringType = RuntimeMethodHandle.GetDeclaringType(method);
// need a proper declaring type instance method on a generic type
- if (RuntimeTypeHandle.IsGenericTypeDefinition(declaringType) || RuntimeTypeHandle.HasInstantiation(declaringType))
+ if (RuntimeTypeHandle.IsGenericTypeDefinition(declaringType) || RuntimeTypeHandle.HasInstantiation(declaringType))
{
bool isStatic = (RuntimeMethodHandle.GetAttributes(method) & MethodAttributes.Static) != (MethodAttributes)0;
- if (!isStatic)
+ if (!isStatic)
{
- if (_methodPtrAux == (IntPtr)0)
+ if (_methodPtrAux == (IntPtr)0)
{
// The target may be of a derived type that doesn't have visibility onto the
// target method. We don't want to call RuntimeType.GetMethodBase below with that
@@ -271,9 +270,9 @@ namespace System {
}
_methodBase = (MethodInfo)RuntimeType.GetMethodBase(declaringType, method);
}
- return (MethodInfo)_methodBase;
+ return (MethodInfo)_methodBase;
}
-
+
public Object Target
{
get
@@ -281,19 +280,19 @@ namespace System {
return GetTarget();
}
}
-
-
+
+
public static Delegate Remove(Delegate source, Delegate value)
{
if (source == null)
return null;
-
+
if (value == null)
return source;
-
+
if (!InternalEqualTypes(source, value))
- throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTypeMis"));
-
+ throw new ArgumentException(SR.Arg_DlgtTypeMis);
+
return source.RemoveImpl(value);
}
@@ -302,7 +301,7 @@ namespace System {
Delegate newDelegate = null;
do
- {
+ {
newDelegate = source;
source = Remove(source, value);
}
@@ -310,29 +309,29 @@ namespace System {
return newDelegate;
}
-
- protected virtual Delegate CombineImpl(Delegate d)
+
+ protected virtual Delegate CombineImpl(Delegate d)
{
- throw new MulticastNotSupportedException(Environment.GetResourceString("Multicast_Combine"));
+ throw new MulticastNotSupportedException(SR.Multicast_Combine);
}
-
+
protected virtual Delegate RemoveImpl(Delegate d)
{
return (d.Equals(this)) ? null : this;
}
-
-
+
+
public virtual Object Clone()
{
return MemberwiseClone();
}
-
+
// V1 API.
public static Delegate CreateDelegate(Type type, Object target, String method)
{
return CreateDelegate(type, target, method, false, true);
}
-
+
// V1 API.
public static Delegate CreateDelegate(Type type, Object target, String method, bool ignoreCase)
{
@@ -352,9 +351,9 @@ namespace System {
RuntimeType rtType = type as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(type));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type));
if (!rtType.IsDelegate())
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"),nameof(type));
+ throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(type));
Delegate d = InternalAlloc(rtType);
// This API existed in v1/v1.1 and only expected to create closed
@@ -371,19 +370,19 @@ namespace System {
(ignoreCase ? DelegateBindingFlags.CaselessMatching : 0)))
{
if (throwOnBindFailure)
- throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTargMeth"));
+ throw new ArgumentException(SR.Arg_DlgtTargMeth);
d = null;
}
-
+
return d;
}
-
+
// V1 API.
public static Delegate CreateDelegate(Type type, Type target, String method)
{
return CreateDelegate(type, target, method, false, true);
}
-
+
// V1 API.
public static Delegate CreateDelegate(Type type, Type target, String method, bool ignoreCase)
{
@@ -394,11 +393,11 @@ namespace System {
public static Delegate CreateDelegate(Type type, Type target, String method, bool ignoreCase, bool throwOnBindFailure)
{
if (type == null)
- throw new ArgumentNullException(nameof(type));
+ throw new ArgumentNullException(nameof(type));
if (target == null)
throw new ArgumentNullException(nameof(target));
if (target.IsGenericType && target.ContainsGenericParameters)
- throw new ArgumentException(Environment.GetResourceString("Arg_UnboundGenParam"), nameof(target));
+ throw new ArgumentException(SR.Arg_UnboundGenParam, nameof(target));
if (method == null)
throw new ArgumentNullException(nameof(method));
Contract.EndContractBlock();
@@ -406,11 +405,11 @@ namespace System {
RuntimeType rtType = type as RuntimeType;
RuntimeType rtTarget = target as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(type));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type));
if (rtTarget == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(target));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(target));
if (!rtType.IsDelegate())
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"),nameof(type));
+ throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(type));
Delegate d = InternalAlloc(rtType);
// This API existed in v1/v1.1 and only expected to create open
@@ -423,15 +422,15 @@ namespace System {
(ignoreCase ? DelegateBindingFlags.CaselessMatching : 0)))
{
if (throwOnBindFailure)
- throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTargMeth"));
+ throw new ArgumentException(SR.Arg_DlgtTargMeth);
d = null;
}
-
+
return d;
}
-
+
// V1 API.
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public static Delegate CreateDelegate(Type type, MethodInfo method, bool throwOnBindFailure)
{
// Validate the parameters.
@@ -443,14 +442,14 @@ namespace System {
RuntimeType rtType = type as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(type));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type));
RuntimeMethodInfo rmi = method as RuntimeMethodInfo;
if (rmi == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), nameof(method));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, nameof(method));
if (!rtType.IsDelegate())
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), nameof(type));
+ throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(type));
// This API existed in v1/v1.1 and only expected to create closed
// instance delegates. Constrain the call to BindToMethodInfo to
@@ -469,11 +468,11 @@ namespace System {
ref stackMark);
if (d == null && throwOnBindFailure)
- throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTargMeth"));
+ throw new ArgumentException(SR.Arg_DlgtTargMeth);
return d;
}
-
+
// V2 API.
public static Delegate CreateDelegate(Type type, Object firstArgument, MethodInfo method)
{
@@ -481,7 +480,7 @@ namespace System {
}
// V2 API.
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public static Delegate CreateDelegate(Type type, Object firstArgument, MethodInfo method, bool throwOnBindFailure)
{
// Validate the parameters.
@@ -493,14 +492,14 @@ namespace System {
RuntimeType rtType = type as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(type));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type));
RuntimeMethodInfo rmi = method as RuntimeMethodInfo;
if (rmi == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), nameof(method));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, nameof(method));
if (!rtType.IsDelegate())
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), nameof(type));
+ throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(type));
// This API is new in Whidbey and allows the full range of delegate
// flexability (open or closed delegates binding to static or
@@ -516,7 +515,7 @@ namespace System {
ref stackMark);
if (d == null && throwOnBindFailure)
- throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTargMeth"));
+ throw new ArgumentException(SR.Arg_DlgtTargMeth);
return d;
}
@@ -525,18 +524,18 @@ namespace System {
{
if ((Object)d1 == null)
return (Object)d2 == null;
-
+
return d1.Equals(d2);
}
-
- public static bool operator != (Delegate d1, Delegate d2)
+
+ public static bool operator !=(Delegate d1, Delegate d2)
{
if ((Object)d1 == null)
return (Object)d2 != null;
-
+
return !d1.Equals(d2);
}
-
+
//
// Implementation of ISerializable
//
@@ -563,11 +562,11 @@ namespace System {
RuntimeType rtType = type as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(type));
-
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(type));
+
if (!rtType.IsDelegate())
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), nameof(type));
-
+ throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(type));
+
// Initialize the method...
Delegate d = InternalAlloc(rtType);
// This is a new internal API added in Whidbey. Currently it's only
@@ -579,7 +578,7 @@ namespace System {
method.GetMethodInfo(),
RuntimeMethodHandle.GetDeclaringType(method.GetMethodInfo()),
DelegateBindingFlags.RelaxedSignature | DelegateBindingFlags.SkipSecurityChecks))
- throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTargMeth"));
+ throw new ArgumentException(SR.Arg_DlgtTargMeth);
return d;
}
@@ -596,11 +595,11 @@ namespace System {
RuntimeMethodInfo rtMethod = method as RuntimeMethodInfo;
if (rtMethod == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), nameof(method));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, nameof(method));
if (!type.IsDelegate())
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), nameof(type));
-
+ throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(type));
+
// This API is used by the formatters when deserializing a delegate.
// They pass us the specific target method (that was already the
// target in a valid delegate) so we should bind with the most
@@ -614,7 +613,7 @@ namespace System {
DelegateBindingFlags.RelaxedSignature);
if (d == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTargMeth"));
+ throw new ArgumentException(SR.Arg_DlgtTargMeth);
return d;
}
@@ -629,19 +628,6 @@ namespace System {
{
Debug.Assert((flags & DelegateBindingFlags.SkipSecurityChecks) == 0);
-#if FEATURE_APPX
- bool nonW8PMethod = (rtMethod.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0;
- bool nonW8PType = (rtType.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0;
- if (nonW8PMethod || nonW8PType)
- {
- RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
- if (caller != null && !caller.IsSafeForReflection())
- throw new InvalidOperationException(
- Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext",
- nonW8PMethod ? rtMethod.FullName : rtType.FullName));
- }
-#endif
-
return UnsafeCreateDelegate(rtType, rtMethod, firstArgument, flags);
}
@@ -661,13 +647,13 @@ namespace System {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool BindToMethodName(Object target, RuntimeType methodType, String method, DelegateBindingFlags flags);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool BindToMethodInfo(Object target, IRuntimeMethodInfo method, RuntimeType methodType, DelegateBindingFlags flags);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static MulticastDelegate InternalAlloc(RuntimeType type);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static MulticastDelegate InternalAllocLike(Delegate d);
@@ -703,20 +689,20 @@ namespace System {
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern static bool CompareUnmanagedFunctionPtrs (Delegate d1, Delegate d2);
+ internal extern static bool CompareUnmanagedFunctionPtrs(Delegate d1, Delegate d2);
}
// These flags effect the way BindToMethodInfo and BindToMethodName are allowed to bind a delegate to a target method. Their
// values must be kept in sync with the definition in vm\comdelegate.h.
internal enum DelegateBindingFlags
{
- StaticMethodOnly = 0x00000001, // Can only bind to static target methods
- InstanceMethodOnly = 0x00000002, // Can only bind to instance (including virtual) methods
- OpenDelegateOnly = 0x00000004, // Only allow the creation of delegates open over the 1st argument
- ClosedDelegateOnly = 0x00000008, // Only allow the creation of delegates closed over the 1st argument
- NeverCloseOverNull = 0x00000010, // A null target will never been considered as a possible null 1st argument
- CaselessMatching = 0x00000020, // Use case insensitive lookup for methods matched by name
- SkipSecurityChecks = 0x00000040, // Skip security checks (visibility, link demand etc.)
- RelaxedSignature = 0x00000080, // Allow relaxed signature matching (co/contra variance)
+ StaticMethodOnly = 0x00000001, // Can only bind to static target methods
+ InstanceMethodOnly = 0x00000002, // Can only bind to instance (including virtual) methods
+ OpenDelegateOnly = 0x00000004, // Only allow the creation of delegates open over the 1st argument
+ ClosedDelegateOnly = 0x00000008, // Only allow the creation of delegates closed over the 1st argument
+ NeverCloseOverNull = 0x00000010, // A null target will never been considered as a possible null 1st argument
+ CaselessMatching = 0x00000020, // Use case insensitive lookup for methods matched by name
+ SkipSecurityChecks = 0x00000040, // Skip security checks (visibility, link demand etc.)
+ RelaxedSignature = 0x00000080, // Allow relaxed signature matching (co/contra variance)
}
}
diff --git a/src/mscorlib/src/System/DelegateSerializationHolder.cs b/src/mscorlib/src/System/DelegateSerializationHolder.cs
index 061f92d42e..d7ad827673 100644
--- a/src/mscorlib/src/System/DelegateSerializationHolder.cs
+++ b/src/mscorlib/src/System/DelegateSerializationHolder.cs
@@ -2,7 +2,7 @@
// 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 System.Runtime.Remoting;
@@ -21,17 +21,17 @@ namespace System
{
// Used for MulticastDelegate
- if (method == null)
+ if (method == null)
throw new ArgumentNullException(nameof(method));
Contract.EndContractBlock();
-
+
Type c = delegateType.BaseType;
if (c == null || (c != typeof(Delegate) && c != typeof(MulticastDelegate)))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"),"type");
+ throw new ArgumentException(SR.Arg_MustBeDelegate, "type");
if (method.DeclaringType == null)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_GlobalMethodSerialization"));
+ throw new NotSupportedException(SR.NotSupported_GlobalMethodSerialization);
DelegateEntry de = new DelegateEntry(delegateType.FullName, delegateType.Module.Assembly.FullName, target,
method.ReflectedType.Module.Assembly.FullName, method.ReflectedType.FullName, method.Name);
@@ -39,7 +39,7 @@ namespace System
if (info.MemberCount == 0)
{
info.SetType(typeof(DelegateSerializationHolder));
- info.AddValue("Delegate",de,typeof(DelegateEntry));
+ info.AddValue("Delegate", de, typeof(DelegateEntry));
}
// target can be an object so it needs to be added to the info, or else a fixup is needed
@@ -108,15 +108,15 @@ namespace System
#region Private Data Members
private DelegateEntry m_delegateEntry;
private MethodInfo[] m_methods;
- #endregion
-
+ #endregion
+
#region Constructor
private DelegateSerializationHolder(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
-
+
bool bNewWire = true;
try
@@ -170,7 +170,7 @@ namespace System
private void ThrowInsufficientState(string field)
{
throw new SerializationException(
- Environment.GetResourceString("Serialization_InsufficientDeserializationState", field));
+ SR.Format(SR.Serialization_InsufficientDeserializationState, field));
}
private DelegateEntry OldDelegateWireFormat(SerializationInfo info, StreamingContext context)
@@ -206,26 +206,34 @@ namespace System
// We cannot use Type.GetType directly, because of AppCompat - assembly names starting with '[' would fail to load.
RuntimeType type = (RuntimeType)Assembly.GetType_Compat(de.assembly, de.type);
- RuntimeType targetType = (RuntimeType)Assembly.GetType_Compat(de.targetTypeAssembly, de.targetTypeName);
+
+ // {de.targetTypeAssembly, de.targetTypeName} do not actually refer to the type of the target, but the reflected
+ // type of the method. Those types may be the same when the method is on the target's type or on a type in its
+ // inheritance chain, but those types may not be the same when the method is an extension method for the
+ // target's type or a type in its inheritance chain.
// If we received the new style delegate encoding we already have the target MethodInfo in hand.
if (m_methods != null)
{
- if(de.target != null && !targetType.IsInstanceOfType(de.target))
- throw new InvalidCastException();
- Object target=de.target;
- d = Delegate.CreateDelegateNoSecurityCheck(type, target, m_methods[index]);
+ // The method info is serialized, so the target type info is redundant. The desktop framework does no
+ // additional verification on the target type info.
+ d = Delegate.CreateDelegateNoSecurityCheck(type, de.target, m_methods[index]);
}
else
{
if (de.target != null)
{
- if(!targetType.IsInstanceOfType(de.target))
- throw new InvalidCastException();
- d = Delegate.CreateDelegate(type, de.target, de.methodName);
+ // For consistency with the desktop framework, when the method info is not serialized for a closed
+ // delegate, the method is assumed to be on the target's type or in its inheritance chain. An extension
+ // method would not work on this path for the above reason and also because the delegate binds to
+ // instance methods only. The desktop framework does no additional verification on the target type info.
+ d = Delegate.CreateDelegate(type, de.target, de.methodName);
}
else
+ {
+ RuntimeType targetType = (RuntimeType)Assembly.GetType_Compat(de.targetTypeAssembly, de.targetTypeName);
d = Delegate.CreateDelegate(type, targetType, de.methodName);
+ }
}
}
catch (Exception e)
@@ -256,7 +264,7 @@ namespace System
else
{
object[] invocationList = new object[count];
-
+
for (DelegateEntry de = m_delegateEntry; de != null; de = de.Entry)
{
// Be careful to match the index we pass to GetDelegate (used to look up extra information for each delegate) to
@@ -272,7 +280,7 @@ namespace System
#region ISerializable
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DelegateSerHolderSerial"));
+ throw new NotSupportedException(SR.NotSupported_DelegateSerHolderSerial);
}
#endregion
}
diff --git a/src/mscorlib/src/System/Diagnostics/Assert.cs b/src/mscorlib/src/System/Diagnostics/Assert.cs
index 9f4b86b7e4..67e6914aa4 100644
--- a/src/mscorlib/src/System/Diagnostics/Assert.cs
+++ b/src/mscorlib/src/System/Diagnostics/Assert.cs
@@ -2,36 +2,37 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Diagnostics {
- using System;
- using System.IO;
- using System.Reflection;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Diagnostics.Contracts;
- using System.Diagnostics.CodeAnalysis;
+using System;
+using System.IO;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+using System.Diagnostics.Contracts;
+using System.Diagnostics.CodeAnalysis;
+namespace System.Diagnostics
+{
// Class which handles code asserts. Asserts are used to explicitly protect
// assumptions made in the code. In general if an assert fails, it indicates
// a program bug so is immediately called to the attention of the user.
// Only static data members, does not need to be marked with the serializable attribute
internal static class Assert
{
- internal const int COR_E_FAILFAST = unchecked((int) 0x80131623);
+ internal const int COR_E_FAILFAST = unchecked((int)0x80131623);
private static AssertFilter Filter;
static Assert()
{
Filter = new DefaultFilter();
}
-
+
// Called when an assertion is being made.
//
internal static void Check(bool condition, String conditionString, String message)
{
if (!condition)
{
- Fail (conditionString, message, null, COR_E_FAILFAST);
+ Fail(conditionString, message, null, COR_E_FAILFAST);
}
}
@@ -54,9 +55,9 @@ namespace System.Diagnostics {
{
// get the stacktrace
StackTrace st = new StackTrace(numStackFramesToSkip, true);
-
- AssertFilters iResult = Filter.AssertFailure (conditionString, message, st, stackTraceFormat, windowTitle);
-
+
+ AssertFilters iResult = Filter.AssertFailure(conditionString, message, st, stackTraceFormat, windowTitle);
+
if (iResult == AssertFilters.FailDebug)
{
if (Debugger.IsAttached == true)
@@ -66,9 +67,9 @@ namespace System.Diagnostics {
if (Debugger.Launch() == false)
{
throw new InvalidOperationException(
- Environment.GetResourceString("InvalidOperation_DebuggerLaunchFailed"));
- }
- }
+ SR.InvalidOperation_DebuggerLaunchFailed);
+ }
+ }
}
else if (iResult == AssertFilters.FailTerminate)
{
@@ -78,10 +79,10 @@ namespace System.Diagnostics {
Environment._Exit(exitCode);
}
}
-
- // Called when an assert happens.
- // windowTitle can be null.
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern static int ShowDefaultAssertDialog(String conditionString, String message, String stackTrace, String windowTitle);
+
+ // Called when an assert happens.
+ // windowTitle can be null.
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal extern static int ShowDefaultAssertDialog(String conditionString, String message, String stackTrace, String windowTitle);
}
}
diff --git a/src/mscorlib/src/System/Diagnostics/AssertFilter.cs b/src/mscorlib/src/System/Diagnostics/AssertFilter.cs
index ab60ee4cff..7c861de58e 100644
--- a/src/mscorlib/src/System/Diagnostics/AssertFilter.cs
+++ b/src/mscorlib/src/System/Diagnostics/AssertFilter.cs
@@ -2,29 +2,29 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Diagnostics {
-
-
- using System;
- using System.Runtime.Versioning;
- // A Filter is used to decide whether an assert failure
- // should terminate the program (or invoke the debugger).
- // Typically this is done by popping up a dialog & asking the user.
- //
- // The default filter brings up a simple Win32 dialog with 3 buttons.
-
+
+
+using System;
+using System.Runtime.Versioning;
+
+namespace System.Diagnostics
+{
+ // A Filter is used to decide whether an assert failure
+ // should terminate the program (or invoke the debugger).
+ // Typically this is done by popping up a dialog & asking the user.
+ //
+ // The default filter brings up a simple Win32 dialog with 3 buttons.
+
[Serializable]
abstract internal class AssertFilter
{
-
// Called when an assert fails. This should be overridden with logic which
// determines whether the program should terminate or not. Typically this
// is done by asking the user.
//
// The windowTitle can be null.
- abstract public AssertFilters AssertFailure(String condition, String message,
+ abstract public AssertFilters AssertFailure(String condition, String message,
StackTrace location, StackTrace.TraceFormat stackTraceFormat, String windowTitle);
-
}
// No data, does not need to be marked with the serializable attribute
internal class DefaultFilter : AssertFilter
@@ -32,14 +32,13 @@ namespace System.Diagnostics {
internal DefaultFilter()
{
}
-
- public override AssertFilters AssertFailure(String condition, String message,
+
+ public override AssertFilters AssertFailure(String condition, String message,
StackTrace location, StackTrace.TraceFormat stackTraceFormat,
String windowTitle)
-
+
{
- return (AssertFilters) Assert.ShowDefaultAssertDialog (condition, message, location.ToString(stackTraceFormat), windowTitle);
+ return (AssertFilters)Assert.ShowDefaultAssertDialog(condition, message, location.ToString(stackTraceFormat), windowTitle);
}
}
-
}
diff --git a/src/mscorlib/src/System/Diagnostics/AssertFilters.cs b/src/mscorlib/src/System/Diagnostics/AssertFilters.cs
index 13131d4819..0f34b41dba 100644
--- a/src/mscorlib/src/System/Diagnostics/AssertFilters.cs
+++ b/src/mscorlib/src/System/Diagnostics/AssertFilters.cs
@@ -2,23 +2,26 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Diagnostics {
-
- /*
- * FailDebug indicates the debugger should be invoked
- * FailIgnore indicates the failure should be ignored & the
- * program continued
- * FailTerminate indicates that the program should be terminated
- * FailContinue indicates that no decision is made -
- * the previous Filter should be invoked
- */
- using System;
+
+/*
+ * FailDebug indicates the debugger should be invoked
+ * FailIgnore indicates the failure should be ignored & the
+ * program continued
+ * FailTerminate indicates that the program should be terminated
+ * FailContinue indicates that no decision is made -
+ * the previous Filter should be invoked
+ */
+
+using System;
+
+namespace System.Diagnostics
+{
[Serializable]
internal enum AssertFilters
{
- FailDebug = 0,
- FailIgnore = 1,
- FailTerminate = 2,
- FailContinueFilter = 3,
+ FailDebug = 0,
+ FailIgnore = 1,
+ FailTerminate = 2,
+ FailContinueFilter = 3,
}
}
diff --git a/src/mscorlib/src/System/Diagnostics/CodeAnalysis/SuppressMessageAttribute.cs b/src/mscorlib/src/System/Diagnostics/CodeAnalysis/SuppressMessageAttribute.cs
deleted file mode 100644
index fb26fcc4ab..0000000000
--- a/src/mscorlib/src/System/Diagnostics/CodeAnalysis/SuppressMessageAttribute.cs
+++ /dev/null
@@ -1,76 +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.
-
-/*============================================================
-**
-**
-**
-** An attribute to suppress violation messages/warnings
-** by static code analysis tools.
-**
-**
-===========================================================*/
-
-using System;
-
-namespace System.Diagnostics.CodeAnalysis
-{
-
- [AttributeUsage(
- AttributeTargets.All,
- Inherited = false,
- AllowMultiple = true
- )
- ]
- [Conditional("CODE_ANALYSIS")]
- public sealed class SuppressMessageAttribute : Attribute
- {
- private string category;
- private string justification;
- private string checkId;
- private string scope;
- private string target;
- private string messageId;
-
- public SuppressMessageAttribute(string category, string checkId)
- {
- this.category = category;
- this.checkId = checkId;
- }
-
- public string Category
- {
- get { return category; }
- }
-
- public string CheckId
- {
- get { return checkId; }
- }
-
- public string Scope
- {
- get { return scope; }
- set { scope = value; }
- }
-
- public string Target
- {
- get { return target; }
- set { target = value; }
- }
-
- public string MessageId
- {
- get { return messageId; }
- set { messageId = value; }
- }
-
- public string Justification
- {
- get { return justification; }
- set { justification = value; }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Diagnostics/ConditionalAttribute.cs b/src/mscorlib/src/System/Diagnostics/ConditionalAttribute.cs
deleted file mode 100644
index c57fb59319..0000000000
--- a/src/mscorlib/src/System/Diagnostics/ConditionalAttribute.cs
+++ /dev/null
@@ -1,25 +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;
-
-namespace System.Diagnostics {
- [Serializable]
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple=true)]
- public sealed class ConditionalAttribute : Attribute
- {
- public ConditionalAttribute(String conditionString)
- {
- m_conditionString = conditionString;
- }
-
- public String ConditionString {
- get {
- return m_conditionString;
- }
- }
-
- private String m_conditionString;
- }
-}
diff --git a/src/mscorlib/src/System/Diagnostics/Contracts/Contracts.cs b/src/mscorlib/src/System/Diagnostics/Contracts/Contracts.cs
index 93d6c48701..76b15197f2 100644
--- a/src/mscorlib/src/System/Diagnostics/Contracts/Contracts.cs
+++ b/src/mscorlib/src/System/Diagnostics/Contracts/Contracts.cs
@@ -27,7 +27,6 @@
#else // CLR
#define FEATURE_UNTRUSTED_CALLERS
#define FEATURE_RELIABILITY_CONTRACTS
-#define FEATURE_SERIALIZATION
#endif
using System;
@@ -43,8 +42,8 @@ using System.Runtime.ConstrainedExecution;
using System.Security;
#endif
-namespace System.Diagnostics.Contracts {
-
+namespace System.Diagnostics.Contracts
+{
#region Attributes
/// <summary>
@@ -71,7 +70,8 @@ namespace System.Diagnostics.Contracts {
_typeWithContracts = typeContainingContracts;
}
- public Type TypeContainingContracts {
+ public Type TypeContainingContracts
+ {
get { return _typeWithContracts; }
}
}
@@ -90,7 +90,8 @@ namespace System.Diagnostics.Contracts {
_typeIAmAContractFor = typeContractsAreFor;
}
- public Type TypeContractsAreFor {
+ public Type TypeContractsAreFor
+ {
get { return _typeIAmAContractFor; }
}
}
@@ -176,7 +177,8 @@ namespace System.Diagnostics.Contracts {
public ContractVerificationAttribute(bool value) { _value = value; }
- public bool Value {
+ public bool Value
+ {
get { return _value; }
}
}
@@ -197,7 +199,8 @@ namespace System.Diagnostics.Contracts {
_publicName = name;
}
- public String Name {
+ public String Name
+ {
get { return _publicName; }
}
}
@@ -247,19 +250,23 @@ namespace System.Diagnostics.Contracts {
_value = value;
}
- public String Category {
+ public String Category
+ {
get { return _category; }
}
- public String Setting {
+ public String Setting
+ {
get { return _setting; }
}
- public bool Enabled {
+ public bool Enabled
+ {
get { return _enabled; }
}
- public String Value {
+ public String Value
+ {
get { return _value; }
}
}
@@ -296,7 +303,8 @@ namespace System.Diagnostics.Contracts {
#endif
public static void Assume(bool condition)
{
- if (!condition) {
+ if (!condition)
+ {
ReportFailure(ContractFailureKind.Assume, null, null, null);
}
}
@@ -316,7 +324,8 @@ namespace System.Diagnostics.Contracts {
#endif
public static void Assume(bool condition, String userMessage)
{
- if (!condition) {
+ if (!condition)
+ {
ReportFailure(ContractFailureKind.Assume, userMessage, null, null);
}
}
@@ -630,8 +639,8 @@ namespace System.Diagnostics.Contracts {
public static bool ForAll(int fromInclusive, int toExclusive, Predicate<int> predicate)
{
if (fromInclusive > toExclusive)
-#if INSIDE_CLR
- throw new ArgumentException(Environment.GetResourceString("Argument_ToExclusiveLessThanFromExclusive"));
+#if CORECLR
+ throw new ArgumentException(SR.Argument_ToExclusiveLessThanFromExclusive);
#else
throw new ArgumentException("fromInclusive must be less than or equal to toExclusive.");
#endif
@@ -690,8 +699,8 @@ namespace System.Diagnostics.Contracts {
public static bool Exists(int fromInclusive, int toExclusive, Predicate<int> predicate)
{
if (fromInclusive > toExclusive)
-#if INSIDE_CLR
- throw new ArgumentException(Environment.GetResourceString("Argument_ToExclusiveLessThanFromExclusive"));
+#if CORECLR
+ throw new ArgumentException(SR.Argument_ToExclusiveLessThanFromExclusive);
#else
throw new ArgumentException("fromInclusive must be less than or equal to toExclusive.");
#endif
@@ -769,7 +778,8 @@ namespace System.Diagnostics.Contracts {
#endregion
}
- public enum ContractFailureKind {
+ public enum ContractFailureKind
+ {
Precondition,
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Postcondition")]
Postcondition,
@@ -779,8 +789,6 @@ namespace System.Diagnostics.Contracts {
Assert,
Assume,
}
-
-
}
// Note: In .NET FX 4.5, we duplicated the ContractHelper class in the System.Runtime.CompilerServices
diff --git a/src/mscorlib/src/System/Diagnostics/Contracts/ContractsBCL.cs b/src/mscorlib/src/System/Diagnostics/Contracts/ContractsBCL.cs
index 5f4de4f666..09d1e6baca 100644
--- a/src/mscorlib/src/System/Diagnostics/Contracts/ContractsBCL.cs
+++ b/src/mscorlib/src/System/Diagnostics/Contracts/ContractsBCL.cs
@@ -20,7 +20,6 @@
#else // CLR
#define FEATURE_UNTRUSTED_CALLERS
#define FEATURE_RELIABILITY_CONTRACTS
-#define FEATURE_SERIALIZATION
#endif
using System;
@@ -37,8 +36,8 @@ using System.Runtime.ConstrainedExecution;
using System.Security;
#endif
-namespace System.Diagnostics.Contracts {
-
+namespace System.Diagnostics.Contracts
+{
public static partial class Contract
{
#region Private Methods
@@ -74,7 +73,7 @@ namespace System.Diagnostics.Contracts {
if (probablyNotRewritten == null)
probablyNotRewritten = thisAssembly;
String simpleName = probablyNotRewritten.GetName().Name;
- System.Runtime.CompilerServices.ContractHelper.TriggerFailure(kind, Environment.GetResourceString("MustUseCCRewrite", contractKind, simpleName), null, null, null);
+ System.Runtime.CompilerServices.ContractHelper.TriggerFailure(kind, SR.Format(SR.MustUseCCRewrite, contractKind, simpleName), null, null, null);
_assertingMustUseRewriter = false;
}
@@ -96,7 +95,7 @@ namespace System.Diagnostics.Contracts {
static partial void ReportFailure(ContractFailureKind failureKind, String userMessage, String conditionText, Exception innerException)
{
if (failureKind < ContractFailureKind.Precondition || failureKind > ContractFailureKind.Assume)
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", failureKind), nameof(failureKind));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, failureKind), nameof(failureKind));
Contract.EndContractBlock();
// displayMessage == null means: yes we handled it. Otherwise it is the localized failure message
@@ -116,15 +115,18 @@ namespace System.Diagnostics.Contracts {
/// full trust, because it will inform you of bugs in the appdomain and because the event handler
/// could allow you to continue execution.
/// </summary>
- public static event EventHandler<ContractFailedEventArgs> ContractFailed {
+ public static event EventHandler<ContractFailedEventArgs> ContractFailed
+ {
#if FEATURE_UNTRUSTED_CALLERS
#endif
- add {
+ add
+ {
System.Runtime.CompilerServices.ContractHelper.InternalContractFailed += value;
}
#if FEATURE_UNTRUSTED_CALLERS
#endif
- remove {
+ remove
+ {
System.Runtime.CompilerServices.ContractHelper.InternalContractFailed -= value;
}
}
@@ -159,7 +161,8 @@ namespace System.Diagnostics.Contracts {
public Exception OriginalException { get { return _originalException; } }
// Whether the event handler "handles" this contract failure, or to fail via escalation policy.
- public bool Handled {
+ public bool Handled
+ {
get { return _handled; }
}
@@ -170,7 +173,8 @@ namespace System.Diagnostics.Contracts {
_handled = true;
}
- public bool Unwind {
+ public bool Unwind
+ {
get { return _unwind; }
}
@@ -186,9 +190,9 @@ namespace System.Diagnostics.Contracts {
[SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")]
internal sealed class ContractException : Exception
{
- readonly ContractFailureKind _Kind;
- readonly string _UserMessage;
- readonly string _Condition;
+ private readonly ContractFailureKind _Kind;
+ private readonly string _UserMessage;
+ private readonly string _Condition;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public ContractFailureKind Kind { get { return _Kind; } }
@@ -209,9 +213,9 @@ namespace System.Diagnostics.Contracts {
: base(failure, innerException)
{
HResult = System.Runtime.CompilerServices.ContractHelper.COR_E_CODECONTRACTFAILED;
- this._Kind = kind;
- this._UserMessage = userMessage;
- this._Condition = condition;
+ _Kind = kind;
+ _UserMessage = userMessage;
+ _Condition = condition;
}
private ContractException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
@@ -259,7 +263,8 @@ namespace System.Runtime.CompilerServices
{
#if FEATURE_UNTRUSTED_CALLERS
#endif
- add {
+ add
+ {
// Eagerly prepare each event handler _marked with a reliability contract_, to
// attempt to reduce out of memory exceptions while reporting contract violations.
// This only works if the new handler obeys the constraints placed on
@@ -275,7 +280,8 @@ namespace System.Runtime.CompilerServices
}
#if FEATURE_UNTRUSTED_CALLERS
#endif
- remove {
+ remove
+ {
lock (lockObject)
{
contractFailedEvent -= value;
@@ -302,7 +308,7 @@ namespace System.Runtime.CompilerServices
static partial void RaiseContractFailedEventImplementation(ContractFailureKind failureKind, String userMessage, String conditionText, Exception innerException, ref string resultFailureMessage)
{
if (failureKind < ContractFailureKind.Precondition || failureKind > ContractFailureKind.Assume)
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", failureKind), nameof(failureKind));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, failureKind), nameof(failureKind));
Contract.EndContractBlock();
string returnValue;
@@ -369,13 +375,14 @@ namespace System.Runtime.CompilerServices
// "Assert On Failure" but used in a process that can't pop up asserts, like an
// NT Service).
- if (!Environment.UserInteractive) {
+ if (!Environment.UserInteractive)
+ {
throw new ContractException(kind, displayMessage, userMessage, conditionText, innerException);
}
// May need to rethink Assert.Fail w/ TaskDialogIndirect as a model. Window title. Main instruction. Content. Expanded info.
// Optional info like string for collapsed text vs. expanded text.
- String windowTitle = Environment.GetResourceString(GetResourceNameForFailure(kind));
+ String windowTitle = SR.GetResourceString(GetResourceNameForFailure(kind));
const int numStackFramesToSkip = 2; // To make stack traces easier to read
System.Diagnostics.Assert.Fail(conditionText, displayMessage, windowTitle, COR_E_CODECONTRACTFAILED, StackTrace.TraceFormat.Normal, numStackFramesToSkip);
// If we got here, the user selected Ignore. Continue.
@@ -430,12 +437,14 @@ namespace System.Runtime.CompilerServices
// on Silverlight we may not be able to look up a friendly string for the
// error message. Let's leverage Silverlight's default error message there.
String failureMessage;
- if (!String.IsNullOrEmpty(conditionText)) {
+ if (!String.IsNullOrEmpty(conditionText))
+ {
resourceName += "_Cnd";
- failureMessage = Environment.GetResourceString(resourceName, conditionText);
+ failureMessage = SR.Format(SR.GetResourceString(resourceName), conditionText);
}
- else {
- failureMessage = Environment.GetResourceString(resourceName);
+ else
+ {
+ failureMessage = SR.GetResourceString(resourceName);
}
// Now add in the user message, if present.
diff --git a/src/mscorlib/src/System/Diagnostics/Debug.Unix.cs b/src/mscorlib/src/System/Diagnostics/Debug.Unix.cs
new file mode 100644
index 0000000000..495f2f713c
--- /dev/null
+++ b/src/mscorlib/src/System/Diagnostics/Debug.Unix.cs
@@ -0,0 +1,95 @@
+// 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 Microsoft.Win32.SafeHandles;
+
+namespace System.Diagnostics
+{
+ public static partial class Debug
+ {
+ private static readonly bool s_shouldWriteToStdErr = Environment.GetEnvironmentVariable("COMPlus_DebugWriteToStdErr") == "1";
+
+ private static void ShowAssertDialog(string stackTrace, string message, string detailMessage)
+ {
+ if (Debugger.IsAttached)
+ {
+ Debugger.Break();
+ }
+ else
+ {
+ // In Core, we do not show a dialog.
+ // Fail in order to avoid anyone catching an exception and masking
+ // an assert failure.
+ var ex = new DebugAssertException(message, detailMessage, stackTrace);
+ Environment.FailFast(ex.Message, ex);
+ }
+ }
+
+ private static void WriteCore(string message)
+ {
+ WriteToDebugger(message);
+
+ if (s_shouldWriteToStdErr)
+ {
+ WriteToStderr(message);
+ }
+ }
+
+ private static void WriteToDebugger(string message)
+ {
+ if (Debugger.IsLogging())
+ {
+ Debugger.Log(0, null, message);
+ }
+ else
+ {
+ Interop.Sys.SysLog(Interop.Sys.SysLogPriority.LOG_USER | Interop.Sys.SysLogPriority.LOG_DEBUG, "%s", message);
+ }
+ }
+
+ private static void WriteToStderr(string message)
+ {
+ // We don't want to write UTF-16 to a file like standard error. Ideally we would transcode this
+ // to UTF8, but the downside of that is it pulls in a bunch of stuff into what is ideally
+ // a path with minimal dependencies (as to prevent re-entrency), so we'll take the strategy
+ // of just throwing away any non ASCII characters from the message and writing the rest
+
+ const int BufferLength = 256;
+
+ unsafe
+ {
+ byte* buf = stackalloc byte[BufferLength];
+ int bufCount;
+ int i = 0;
+
+ while (i < message.Length)
+ {
+ for (bufCount = 0; bufCount < BufferLength && i < message.Length; i++)
+ {
+ if (message[i] <= 0x7F)
+ {
+ buf[bufCount] = (byte)message[i];
+ bufCount++;
+ }
+ }
+
+ int totalBytesWritten = 0;
+ while (bufCount > 0)
+ {
+ int bytesWritten = Interop.Sys.Write(2 /* stderr */, buf + totalBytesWritten, bufCount);
+ if (bytesWritten < 0)
+ {
+ // On error, simply stop writing the debug output. This could commonly happen if stderr
+ // was piped to a program that ended before this program did, resulting in EPIPE errors.
+ return;
+ }
+
+ bufCount -= bytesWritten;
+ totalBytesWritten += bytesWritten;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Diagnostics/Debug.Windows.cs b/src/mscorlib/src/System/Diagnostics/Debug.Windows.cs
new file mode 100644
index 0000000000..095e9b6985
--- /dev/null
+++ b/src/mscorlib/src/System/Diagnostics/Debug.Windows.cs
@@ -0,0 +1,63 @@
+// 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.
+
+namespace System.Diagnostics
+{
+ public static partial class Debug
+ {
+ private static void ShowAssertDialog(string stackTrace, string message, string detailMessage)
+ {
+ if (Debugger.IsAttached)
+ {
+ Debugger.Break();
+ }
+ else
+ {
+ // In Core, we do not show a dialog.
+ // Fail in order to avoid anyone catching an exception and masking
+ // an assert failure.
+ var ex = new DebugAssertException(message, detailMessage, stackTrace);
+ Environment.FailFast(ex.Message, ex);
+ }
+ }
+
+ private static void WriteCore(string message)
+ {
+ // really huge messages mess up both VS and dbmon, so we chop it up into
+ // reasonable chunks if it's too big. This is the number of characters
+ // that OutputDebugstring chunks at.
+ const int WriteChunkLength = 4091;
+
+ // We don't want output from multiple threads to be interleaved.
+ lock (s_ForLock)
+ {
+ if (message == null || message.Length <= WriteChunkLength)
+ {
+ WriteToDebugger(message);
+ }
+ else
+ {
+ int offset;
+ for (offset = 0; offset < message.Length - WriteChunkLength; offset += WriteChunkLength)
+ {
+ WriteToDebugger(message.Substring(offset, WriteChunkLength));
+ }
+ WriteToDebugger(message.Substring(offset));
+ }
+ }
+ }
+
+ private static void WriteToDebugger(string message)
+ {
+ if (Debugger.IsLogging())
+ {
+ Debugger.Log(0, null, message);
+ }
+ else
+ {
+ Interop.Kernel32.OutputDebugString(message ?? string.Empty);
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Diagnostics/Debugger.cs b/src/mscorlib/src/System/Diagnostics/Debugger.cs
index 21c57dbfaf..92df7e7f5f 100644
--- a/src/mscorlib/src/System/Diagnostics/Debugger.cs
+++ b/src/mscorlib/src/System/Diagnostics/Debugger.cs
@@ -5,16 +5,16 @@
// The Debugger class is a part of the System.Diagnostics package
// and is used for communicating with a debugger.
+using System;
+using System.IO;
+using System.Collections;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Security;
+using System.Runtime.Versioning;
+
namespace System.Diagnostics
{
- using System;
- using System.IO;
- using System.Collections;
- using System.Reflection;
- using System.Runtime.CompilerServices;
- using System.Security;
- using System.Runtime.Versioning;
-
// No data, does not need to be marked with the serializable attribute
public sealed class Debugger
{
@@ -30,13 +30,14 @@ namespace System.Diagnostics
// Break causes a breakpoint to be signalled to an attached debugger. If no debugger
// is attached, the user is asked if he wants to attach a debugger. If yes, then the
// debugger is launched.
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Break()
{
// Causing a break is now allowed.
BreakInternal();
}
- static void BreakCanThrow()
+ private static void BreakCanThrow()
{
BreakInternal();
}
@@ -128,7 +129,5 @@ namespace System.Diagnostics
// report the notification depending on its settings.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void CustomNotification(ICustomDebuggerNotification data);
-
}
-
}
diff --git a/src/mscorlib/src/System/Diagnostics/DebuggerAttributes.cs b/src/mscorlib/src/System/Diagnostics/DebuggerAttributes.cs
index ce9987b9e2..5e1dfd82a5 100644
--- a/src/mscorlib/src/System/Diagnostics/DebuggerAttributes.cs
+++ b/src/mscorlib/src/System/Diagnostics/DebuggerAttributes.cs
@@ -10,32 +10,33 @@
**
**
===========================================================*/
-
-
-namespace System.Diagnostics {
- using System;
- using System.Runtime.InteropServices;
- using System.Diagnostics.Contracts;
-
-[Serializable]
-[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)]
+
+
+using System;
+using System.Runtime.InteropServices;
+using System.Diagnostics.Contracts;
+
+namespace System.Diagnostics
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)]
public sealed class DebuggerStepThroughAttribute : Attribute
{
- public DebuggerStepThroughAttribute () {}
- }
+ public DebuggerStepThroughAttribute() { }
+ }
-[Serializable]
-[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor, Inherited = false)]
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor, Inherited = false)]
public sealed class DebuggerHiddenAttribute : Attribute
{
- public DebuggerHiddenAttribute () {}
+ public DebuggerHiddenAttribute() { }
}
-[Serializable]
-[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor |AttributeTargets.Struct, Inherited = false)]
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor | AttributeTargets.Struct, Inherited = false)]
public sealed class DebuggerNonUserCodeAttribute : Attribute
{
- public DebuggerNonUserCodeAttribute () {}
+ public DebuggerNonUserCodeAttribute() { }
}
// Attribute class used by the compiler to mark modules.
@@ -46,11 +47,11 @@ namespace System.Diagnostics {
// or may not have included debugging information, and the Runtime
// won't preserve the debugging info, which will make debugging after
// a JIT attach difficult.
- [AttributeUsage(AttributeTargets.Assembly|AttributeTargets.Module, AllowMultiple = false)]
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module, AllowMultiple = false)]
public sealed class DebuggableAttribute : Attribute
{
[Flags]
- public enum DebuggingModes
+ public enum DebuggingModes
{
None = 0x0,
Default = 0x1,
@@ -58,7 +59,7 @@ namespace System.Diagnostics {
IgnoreSymbolStoreSequencePoints = 0x2,
EnableEditAndContinue = 0x4
}
-
+
private DebuggingModes m_debuggingModes;
public DebuggableAttribute(bool isJITTrackingEnabled,
@@ -66,12 +67,12 @@ namespace System.Diagnostics {
{
m_debuggingModes = 0;
- if (isJITTrackingEnabled)
+ if (isJITTrackingEnabled)
{
m_debuggingModes |= DebuggingModes.Default;
}
- if (isJITOptimizerDisabled)
+ if (isJITOptimizerDisabled)
{
m_debuggingModes |= DebuggingModes.DisableOptimizations;
}
@@ -91,7 +92,7 @@ namespace System.Diagnostics {
{
get { return ((m_debuggingModes & DebuggingModes.DisableOptimizations) != 0); }
}
-
+
public DebuggingModes DebuggingFlags
{
get { return m_debuggingModes; }
@@ -108,25 +109,25 @@ namespace System.Diagnostics {
// Please also change the code which validates DebuggerBrowsableState variable (in this file)
// if you change this enum.
- public enum DebuggerBrowsableState
- {
- Never = 0,
+ public enum DebuggerBrowsableState
+ {
+ Never = 0,
//Expanded is not supported in this release
//Expanded = 1,
- Collapsed = 2,
+ Collapsed = 2,
RootHidden = 3
}
-
-
+
+
// the one currently supported with the csee.dat
// (mcee.dat, autoexp.dat) file.
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
- public sealed class DebuggerBrowsableAttribute: Attribute
+ public sealed class DebuggerBrowsableAttribute : Attribute
{
private DebuggerBrowsableState state;
public DebuggerBrowsableAttribute(DebuggerBrowsableState state)
{
- if( state < DebuggerBrowsableState.Never || state > DebuggerBrowsableState.RootHidden)
+ if (state < DebuggerBrowsableState.Never || state > DebuggerBrowsableState.RootHidden)
throw new ArgumentOutOfRangeException(nameof(state));
Contract.EndContractBlock();
@@ -141,7 +142,7 @@ namespace System.Diagnostics {
// DebuggerTypeProxyAttribute
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = true)]
- public sealed class DebuggerTypeProxyAttribute: Attribute
+ public sealed class DebuggerTypeProxyAttribute : Attribute
{
private string typeName;
private string targetName;
@@ -149,14 +150,15 @@ namespace System.Diagnostics {
public DebuggerTypeProxyAttribute(Type type)
{
- if (type == null) {
+ if (type == null)
+ {
throw new ArgumentNullException(nameof(type));
}
Contract.EndContractBlock();
- this.typeName = type.AssemblyQualifiedName;
+ typeName = type.AssemblyQualifiedName;
}
-
+
public DebuggerTypeProxyAttribute(string typeName)
{
this.typeName = typeName;
@@ -168,16 +170,18 @@ namespace System.Diagnostics {
public Type Target
{
- set {
- if( value == null) {
+ set
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
-
- targetName = value.AssemblyQualifiedName;
- target = value;
+
+ targetName = value.AssemblyQualifiedName;
+ target = value;
}
-
+
get { return target; }
}
@@ -185,10 +189,9 @@ namespace System.Diagnostics {
{
get { return targetName; }
set { targetName = value; }
-
}
}
-
+
// This attribute is used to control what is displayed for the given class or field
// in the data windows in the debugger. The single argument to this attribute is
// the string that will be displayed in the value column for instances of the type.
@@ -209,19 +212,21 @@ namespace System.Diagnostics {
public DebuggerDisplayAttribute(string value)
{
- if( value == null ) {
+ if (value == null)
+ {
this.value = "";
}
- else {
+ else
+ {
this.value = value;
}
name = "";
type = "";
- }
+ }
public string Value
{
- get { return this.value; }
+ get { return value; }
}
public string Name
@@ -238,13 +243,15 @@ namespace System.Diagnostics {
public Type Target
{
- set {
- if( value == null) {
+ set
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
-
- targetName = value.AssemblyQualifiedName;
+
+ targetName = value.AssemblyQualifiedName;
target = value;
}
get { return target; }
@@ -254,7 +261,6 @@ namespace System.Diagnostics {
{
get { return targetName; }
set { targetName = value; }
-
}
}
}
diff --git a/src/mscorlib/src/System/Diagnostics/EditAndContinueHelper.cs b/src/mscorlib/src/System/Diagnostics/EditAndContinueHelper.cs
index 32d7a98a50..8ad4fec082 100644
--- a/src/mscorlib/src/System/Diagnostics/EditAndContinueHelper.cs
+++ b/src/mscorlib/src/System/Diagnostics/EditAndContinueHelper.cs
@@ -11,12 +11,13 @@
**
=============================================================================*/
-namespace System.Diagnostics {
-
- using System;
-
+
+using System;
+
+namespace System.Diagnostics
+{
[Serializable]
- internal sealed class EditAndContinueHelper
+ internal sealed class EditAndContinueHelper
{
#pragma warning disable 169
#pragma warning disable 414 // Field is not used from managed.
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/ActivityTracker.cs b/src/mscorlib/src/System/Diagnostics/Eventing/ActivityTracker.cs
deleted file mode 100644
index 1a1f5fa2c0..0000000000
--- a/src/mscorlib/src/System/Diagnostics/Eventing/ActivityTracker.cs
+++ /dev/null
@@ -1,665 +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.Diagnostics;
-using System.Threading;
-#if !ES_BUILD_AGAINST_DOTNET_V35
-using Contract = System.Diagnostics.Contracts.Contract;
-#else
-using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract;
-#endif
-
-#if ES_BUILD_STANDALONE
-namespace Microsoft.Diagnostics.Tracing
-#else
-using System.Threading.Tasks;
-namespace System.Diagnostics.Tracing
-#endif
-{
- /// <summary>
- /// Tracks activities. This is meant to be a singleton (accessed by the ActivityTracer.Instance static property)
- ///
- /// Logically this is simply holds the m_current variable that holds the async local that holds the current ActivityInfo
- /// An ActivityInfo is represents a activity (which knows its creator and thus knows its path).
- ///
- /// Most of the magic is in the async local (it gets copied to new tasks)
- ///
- /// On every start event call OnStart
- ///
- /// Guid activityID;
- /// Guid relatedActivityID;
- /// if (OnStart(activityName, out activityID, out relatedActivityID, ForceStop, options))
- /// // Log Start event with activityID and relatedActivityID
- ///
- /// On every stop event call OnStop
- ///
- /// Guid activityID;
- /// if (OnStop(activityName, ref activityID ForceStop))
- /// // Stop event with activityID
- ///
- /// On any normal event log the event with activityTracker.CurrentActivityId
- /// </summary>
- internal class ActivityTracker
- {
-
- /// <summary>
- /// Called on work item begins. The activity name = providerName + activityName without 'Start' suffix.
- /// It updates CurrentActivityId to track.
- ///
- /// It returns true if the Start should be logged, otherwise (if it is illegal recursion) it return false.
- ///
- /// The start event should use as its activity ID the CurrentActivityId AFTER calling this routine and its
- /// RelatedActivityID the CurrentActivityId BEFORE calling this routine (the creator).
- ///
- /// If activity tracing is not on, then activityId and relatedActivityId are not set
- /// </summary>
- public void OnStart(string providerName, string activityName, int task, ref Guid activityId, ref Guid relatedActivityId, EventActivityOptions options)
- {
- if (m_current == null) // We are not enabled
- {
- // We used to rely on the TPL provider turning us on, but that has the disadvantage that you don't get Start-Stop tracking
- // until you use Tasks for the first time (which you may never do). Thus we change it to pull rather tan push for whether
- // we are enabled.
- if (m_checkedForEnable)
- return;
- m_checkedForEnable = true;
- if (TplEtwProvider.Log.IsEnabled(EventLevel.Informational, TplEtwProvider.Keywords.TasksFlowActivityIds))
- Enable();
- if (m_current == null)
- return;
- }
-
-
- Debug.Assert((options & EventActivityOptions.Disable) == 0);
-
- var currentActivity = m_current.Value;
- var fullActivityName = NormalizeActivityName(providerName, activityName, task);
-
- var etwLog = TplEtwProvider.Log;
- if (etwLog.Debug)
- {
- etwLog.DebugFacilityMessage("OnStartEnter", fullActivityName);
- etwLog.DebugFacilityMessage("OnStartEnterActivityState", ActivityInfo.LiveActivities(currentActivity));
- }
-
- if (currentActivity != null)
- {
- // Stop activity tracking if we reached the maximum allowed depth
- if (currentActivity.m_level >= MAX_ACTIVITY_DEPTH)
- {
- activityId = Guid.Empty;
- relatedActivityId = Guid.Empty;
- if (etwLog.Debug)
- etwLog.DebugFacilityMessage("OnStartRET", "Fail");
- return;
- }
- // Check for recursion, and force-stop any activities if the activity already started.
- if ((options & EventActivityOptions.Recursive) == 0)
- {
- ActivityInfo existingActivity = FindActiveActivity(fullActivityName, currentActivity);
- if (existingActivity != null)
- {
- OnStop(providerName, activityName, task, ref activityId);
- currentActivity = m_current.Value;
- }
- }
- }
-
- // Get a unique ID for this activity.
- long id;
- if (currentActivity == null)
- id = Interlocked.Increment(ref m_nextId);
- else
- id = Interlocked.Increment(ref currentActivity.m_lastChildID);
-
- // The previous ID is my 'causer' and becomes my related activity ID
- relatedActivityId = EventSource.CurrentThreadActivityId;
-
- // Add to the list of started but not stopped activities.
- ActivityInfo newActivity = new ActivityInfo(fullActivityName, id, currentActivity, relatedActivityId, options);
- m_current.Value = newActivity;
-
- // Remember the current ID so we can log it
- activityId = newActivity.ActivityId;
-
- if (etwLog.Debug)
- {
- etwLog.DebugFacilityMessage("OnStartRetActivityState", ActivityInfo.LiveActivities(newActivity));
- etwLog.DebugFacilityMessage1("OnStartRet", activityId.ToString(), relatedActivityId.ToString());
- }
- }
-
- /// <summary>
- /// Called when a work item stops. The activity name = providerName + activityName without 'Stop' suffix.
- /// It updates m_current variable to track this fact. The Stop event associated with stop should log the ActivityID associated with the event.
- ///
- /// If activity tracing is not on, then activityId and relatedActivityId are not set
- /// </summary>
- public void OnStop(string providerName, string activityName, int task, ref Guid activityId)
- {
- if (m_current == null) // We are not enabled
- return;
-
- var fullActivityName = NormalizeActivityName(providerName, activityName, task);
-
- var etwLog = TplEtwProvider.Log;
- if (etwLog.Debug)
- {
- etwLog.DebugFacilityMessage("OnStopEnter", fullActivityName);
- etwLog.DebugFacilityMessage("OnStopEnterActivityState", ActivityInfo.LiveActivities(m_current.Value));
- }
-
- for (; ; ) // This is a retry loop.
- {
- ActivityInfo currentActivity = m_current.Value;
- ActivityInfo newCurrentActivity = null; // if we have seen any live activities (orphans), at he first one we have seen.
-
- // Search to find the activity to stop in one pass. This insures that we don't let one mistake
- // (stopping something that was not started) cause all active starts to be stopped
- // By first finding the target start to stop we are more robust.
- ActivityInfo activityToStop = FindActiveActivity(fullActivityName, currentActivity);
-
- // ignore stops where we can't find a start because we may have popped them previously.
- if (activityToStop == null)
- {
- activityId = Guid.Empty;
- // TODO add some logging about this. Basically could not find matching start.
- if (etwLog.Debug)
- etwLog.DebugFacilityMessage("OnStopRET", "Fail");
- return;
- }
-
- activityId = activityToStop.ActivityId;
-
- // See if there are any orphans that need to be stopped.
- ActivityInfo orphan = currentActivity;
- while (orphan != activityToStop && orphan != null)
- {
- if (orphan.m_stopped != 0) // Skip dead activities.
- {
- orphan = orphan.m_creator;
- continue;
- }
- if (orphan.CanBeOrphan())
- {
- // We can't pop anything after we see a valid orphan, remember this for later when we update m_current.
- if (newCurrentActivity == null)
- newCurrentActivity = orphan;
- }
- else
- {
- orphan.m_stopped = 1;
- Debug.Assert(orphan.m_stopped != 0);
- }
- orphan = orphan.m_creator;
- }
-
- // try to Stop the activity atomically. Other threads may be trying to do this as well.
- if (Interlocked.CompareExchange(ref activityToStop.m_stopped, 1, 0) == 0)
- {
- // I succeeded stopping this activity. Now we update our m_current pointer
-
- // If I haven't yet determined the new current activity, it is my creator.
- if (newCurrentActivity == null)
- newCurrentActivity = activityToStop.m_creator;
-
- m_current.Value = newCurrentActivity;
-
- if (etwLog.Debug)
- {
- etwLog.DebugFacilityMessage("OnStopRetActivityState", ActivityInfo.LiveActivities(newCurrentActivity));
- etwLog.DebugFacilityMessage("OnStopRet", activityId.ToString());
- }
- return;
- }
- // We failed to stop it. We must have hit a race to stop it. Just start over and try again.
- }
- }
-
- /// <summary>
- /// Turns on activity tracking. It is sticky, once on it stays on (race issues otherwise)
- /// </summary>
- public void Enable()
- {
- if (m_current == null)
- {
- // Catch the not Implemented
- try
- {
- m_current = new AsyncLocal<ActivityInfo>(ActivityChanging);
- }
- catch (NotImplementedException) {
-#if (!ES_BUILD_PCL && ! PROJECTN)
- // send message to debugger without delay
- System.Diagnostics.Debugger.Log(0, null, "Activity Enabled() called but AsyncLocals Not Supported (pre V4.6). Ignoring Enable");
-#endif
- }
- }
- }
-
- /// <summary>
- /// An activity tracker is a singleton, this is how you get the one and only instance.
- /// </summary>
- public static ActivityTracker Instance { get { return s_activityTrackerInstance; } }
-
-
- #region private
-
- /// <summary>
- /// The current activity ID. Use this to log normal events.
- /// </summary>
- private Guid CurrentActivityId { get { return m_current.Value.ActivityId; } }
-
- /// <summary>
- /// Searched for a active (nonstopped) activity with the given name. Returns null if not found.
- /// </summary>
- private ActivityInfo FindActiveActivity(string name, ActivityInfo startLocation)
- {
- var activity = startLocation;
- while (activity != null)
- {
- if (name == activity.m_name && activity.m_stopped == 0)
- return activity;
- activity = activity.m_creator;
- }
- return null;
- }
-
- /// <summary>
- /// Strip out "Start" or "End" suffix from activity name and add providerName prefix.
- /// If 'task' it does not end in Start or Stop and Task is non-zero use that as the name of the activity
- /// </summary>
- private string NormalizeActivityName(string providerName, string activityName, int task)
- {
- if (activityName.EndsWith(EventSource.s_ActivityStartSuffix, StringComparison.Ordinal))
- activityName = activityName.Substring(0, activityName.Length - EventSource.s_ActivityStartSuffix.Length);
- else if (activityName.EndsWith(EventSource.s_ActivityStopSuffix, StringComparison.Ordinal))
- activityName = activityName.Substring(0, activityName.Length - EventSource.s_ActivityStopSuffix.Length);
- else if (task != 0)
- activityName = "task" + task.ToString();
-
- // We use provider name to distinguish between activities from different providers.
- return providerName + activityName;
- }
-
- // *******************************************************************************
- /// <summary>
- /// An ActivityInfo represents a particular activity. It is almost read-only. The only
- /// fields that change after creation are
- /// m_lastChildID - used to generate unique IDs for the children activities and for the most part can be ignored.
- /// m_stopped - indicates that this activity is dead
- /// This read-only-ness is important because an activity's m_creator chain forms the
- /// 'Path of creation' for the activity (which is also its unique ID) but is also used as
- /// the 'list of live parents' which indicate of those ancestors, which are alive (if they
- /// are not marked dead they are alive).
- /// </summary>
- private class ActivityInfo
- {
- public ActivityInfo(string name, long uniqueId, ActivityInfo creator, Guid activityIDToRestore, EventActivityOptions options)
- {
- m_name = name;
- m_eventOptions = options;
- m_creator = creator;
- m_uniqueId = uniqueId;
- m_level = creator != null ? creator.m_level + 1 : 0;
- m_activityIdToRestore = activityIDToRestore;
-
- // Create a nice GUID that encodes the chain of activities that started this one.
- CreateActivityPathGuid(out m_guid, out m_activityPathGuidOffset);
- }
-
- public Guid ActivityId
- {
- get
- {
- return m_guid;
- }
- }
-
- public static string Path(ActivityInfo activityInfo)
- {
- if (activityInfo == null)
- return ("");
- return Path(activityInfo.m_creator) + "/" + activityInfo.m_uniqueId.ToString();
- }
-
- public override string ToString()
- {
- return m_name + "(" + Path(this) + (m_stopped != 0 ? ",DEAD)" : ")");
- }
-
- public static string LiveActivities(ActivityInfo list)
- {
- if (list == null)
- return "";
- return list.ToString() + ";" + LiveActivities(list.m_creator);
- }
-
- public bool CanBeOrphan()
- {
- if ((m_eventOptions & EventActivityOptions.Detachable) != 0)
- return true;
- return false;
- }
-
- #region private
-
- #region CreateActivityPathGuid
- /// <summary>
- /// Logically every activity Path (see Path()) that describes the activities that caused this
- /// (rooted in an activity that predates activity tracking.
- ///
- /// We wish to encode this path in the Guid to the extent that we can. Many of the paths have
- /// many small numbers in them and we take advantage of this in the encoding to output as long
- /// a path in the GUID as possible.
- ///
- /// Because of the possibility of GUID collision, we only use 96 of the 128 bits of the GUID
- /// for encoding the path. The last 32 bits are a simple checksum (and random number) that
- /// identifies this as using the convention defined here.
- ///
- /// It returns both the GUID which has the path as well as the offset that points just beyond
- /// the end of the activity (so it can be appended to). Note that if the end is in a nibble
- /// (it uses nibbles instead of bytes as the unit of encoding, then it will point at the unfinished
- /// byte (since the top nibble can't be zero you can determine if this is true by seeing if
- /// this byte is nonZero. This offset is needed to efficiently create the ID for child activities.
- /// </summary>
- private unsafe void CreateActivityPathGuid(out Guid idRet, out int activityPathGuidOffset)
- {
- fixed (Guid* outPtr = &idRet)
- {
- int activityPathGuidOffsetStart = 0;
- if (m_creator != null)
- {
- activityPathGuidOffsetStart = m_creator.m_activityPathGuidOffset;
- idRet = m_creator.m_guid;
- }
- else
- {
- // TODO FIXME - differentiate between AD inside PCL
- int appDomainID = 0;
-#if (!ES_BUILD_STANDALONE && !PROJECTN)
- appDomainID = System.Threading.Thread.GetDomainID();
-#endif
- // We start with the appdomain number to make this unique among appdomains.
- activityPathGuidOffsetStart = AddIdToGuid(outPtr, activityPathGuidOffsetStart, (uint)appDomainID);
- }
-
- activityPathGuidOffset = AddIdToGuid(outPtr, activityPathGuidOffsetStart, (uint)m_uniqueId);
-
-
- // If the path does not fit, Make a GUID by incrementing rather than as a path, keeping as much of the path as possible
- if (12 < activityPathGuidOffset)
- CreateOverflowGuid(outPtr);
- }
- }
-
- /// <summary>
- /// If we can't fit the activity Path into the GUID we come here. What we do is simply
- /// generate a 4 byte number (s_nextOverflowId). Then look for an ancestor that has
- /// sufficient space for this ID. By doing this, we preserve the fact that this activity
- /// is a child (of unknown depth) from that ancestor.
- /// </summary>
- private unsafe void CreateOverflowGuid(Guid* outPtr)
- {
- // Search backwards for an ancestor that has sufficient space to put the ID.
- for (ActivityInfo ancestor = m_creator; ancestor != null; ancestor = ancestor.m_creator)
- {
- if (ancestor.m_activityPathGuidOffset <= 10) // we need at least 2 bytes.
- {
- uint id = unchecked((uint)Interlocked.Increment(ref ancestor.m_lastChildID)); // Get a unique ID
- // Try to put the ID into the GUID
- *outPtr = ancestor.m_guid;
- int endId = AddIdToGuid(outPtr, ancestor.m_activityPathGuidOffset, id, true);
-
- // Does it fit?
- if (endId <= 12)
- break;
- }
- }
- }
-
- /// <summary>
- /// The encoding for a list of numbers used to make Activity GUIDs. Basically
- /// we operate on nibbles (which are nice because they show up as hex digits). The
- /// list is ended with a end nibble (0) and depending on the nibble value (Below)
- /// the value is either encoded into nibble itself or it can spill over into the
- /// bytes that follow.
- /// </summary>
- enum NumberListCodes : byte
- {
- End = 0x0, // ends the list. No valid value has this prefix.
- LastImmediateValue = 0xA,
-
- PrefixCode = 0xB, // all the 'long' encodings go here. If the next nibble is MultiByte1-4
- // than this is a 'overflow' id. Unlike the hierarchical IDs these are
- // allocated densely but don't tell you anything about nesting. we use
- // these when we run out of space in the GUID to store the path.
-
- MultiByte1 = 0xC, // 1 byte follows. If this Nibble is in the high bits, it the high bits of the number are stored in the low nibble.
- // commented out because the code does not explicitly reference the names (but they are logically defined).
- // MultiByte2 = 0xD, // 2 bytes follow (we don't bother with the nibble optimization)
- // MultiByte3 = 0xE, // 3 bytes follow (we don't bother with the nibble optimization)
- // MultiByte4 = 0xF, // 4 bytes follow (we don't bother with the nibble optimization)
- }
-
- /// Add the activity id 'id' to the output Guid 'outPtr' starting at the offset 'whereToAddId'
- /// Thus if this number is 6 that is where 'id' will be added. This will return 13 (12
- /// is the maximum number of bytes that fit in a GUID) if the path did not fit.
- /// If 'overflow' is true, then the number is encoded as an 'overflow number (which has a
- /// special (longer prefix) that indicates that this ID is allocated differently
- private static unsafe int AddIdToGuid(Guid* outPtr, int whereToAddId, uint id, bool overflow = false)
- {
- byte* ptr = (byte*)outPtr;
- byte* endPtr = ptr + 12;
- ptr += whereToAddId;
- if (endPtr <= ptr)
- return 13; // 12 means we might exactly fit, 13 means we definately did not fit
-
- if (0 < id && id <= (uint)NumberListCodes.LastImmediateValue && !overflow)
- WriteNibble(ref ptr, endPtr, id);
- else
- {
- uint len = 4;
- if (id <= 0xFF)
- len = 1;
- else if (id <= 0xFFFF)
- len = 2;
- else if (id <= 0xFFFFFF)
- len = 3;
-
- if (overflow)
- {
- if (endPtr <= ptr + 2) // I need at least 2 bytes
- return 13;
-
- // Write out the prefix code nibble and the length nibble
- WriteNibble(ref ptr, endPtr, (uint)NumberListCodes.PrefixCode);
- }
- // The rest is the same for overflow and non-overflow case
- WriteNibble(ref ptr, endPtr, (uint)NumberListCodes.MultiByte1 + (len - 1));
-
- // Do we have an odd nibble? If so flush it or use it for the 12 byte case.
- if (ptr < endPtr && *ptr != 0)
- {
- // If the value < 4096 we can use the nibble we are otherwise just outputting as padding.
- if (id < 4096)
- {
- // Indicate this is a 1 byte multicode with 4 high order bits in the lower nibble.
- *ptr = (byte)(((uint)NumberListCodes.MultiByte1 << 4) + (id >> 8));
- id &= 0xFF; // Now we only want the low order bits.
- }
- ptr++;
- }
-
- // Write out the bytes.
- while (0 < len)
- {
- if (endPtr <= ptr)
- {
- ptr++; // Indicate that we have overflowed
- break;
- }
- *ptr++ = (byte)id;
- id = (id >> 8);
- --len;
- }
- }
-
- // Compute the checksum
- uint* sumPtr = (uint*)outPtr;
- // We set the last DWORD the sum of the first 3 DWORDS in the GUID. This
- sumPtr[3] = sumPtr[0] + sumPtr[1] + sumPtr[2] + 0x599D99AD; // This last number is a random number (it identifies us as us)
-
- return (int)(ptr - ((byte*)outPtr));
- }
-
- /// <summary>
- /// Write a single Nible 'value' (must be 0-15) to the byte buffer represented by *ptr.
- /// Will not go past 'endPtr'. Also it assumes that we never write 0 so we can detect
- /// whether a nibble has already been written to ptr because it will be nonzero.
- /// Thus if it is non-zero it adds to the current byte, otherwise it advances and writes
- /// the new byte (in the high bits) of the next byte.
- /// </summary>
- private static unsafe void WriteNibble(ref byte* ptr, byte* endPtr, uint value)
- {
- Debug.Assert(0 <= value && value < 16);
- Debug.Assert(ptr < endPtr);
-
- if (*ptr != 0)
- *ptr++ |= (byte)value;
- else
- *ptr = (byte)(value << 4);
- }
-
- #endregion // CreateGuidForActivityPath
-
- readonly internal string m_name; // The name used in the 'start' and 'stop' APIs to help match up
- readonly long m_uniqueId; // a small number that makes this activity unique among its siblings
- internal readonly Guid m_guid; // Activity Guid, it is basically an encoding of the Path() (see CreateActivityPathGuid)
- internal readonly int m_activityPathGuidOffset; // Keeps track of where in m_guid the causality path stops (used to generated child GUIDs)
- internal readonly int m_level; // current depth of the Path() of the activity (used to keep recursion under control)
- readonly internal EventActivityOptions m_eventOptions; // Options passed to start.
- internal long m_lastChildID; // used to create a unique ID for my children activities
- internal int m_stopped; // This work item has stopped
- readonly internal ActivityInfo m_creator; // My parent (creator). Forms the Path() for the activity.
- readonly internal Guid m_activityIdToRestore; // The Guid to restore after a stop.
- #endregion
- }
-
- // This callback is used to initialize the m_current AsyncLocal Variable.
- // Its job is to keep the ETW Activity ID (part of thread local storage) in sync
- // with m_current.ActivityID
- void ActivityChanging(AsyncLocalValueChangedArgs<ActivityInfo> args)
- {
- ActivityInfo cur = args.CurrentValue;
- ActivityInfo prev = args.PreviousValue;
-
- // Are we popping off a value? (we have a prev, and it creator is cur)
- // Then check if we should use the GUID at the time of the start event
- if (prev != null && prev.m_creator == cur)
- {
- // If the saved activity ID is not the same as the creator activity
- // that takes precedence (it means someone explicitly did a SetActivityID)
- // Set it to that and get out
- if (cur == null || prev.m_activityIdToRestore != cur.ActivityId)
- {
- EventSource.SetCurrentThreadActivityId(prev.m_activityIdToRestore);
- return;
- }
- }
-
- // OK we did not have an explicit SetActivityID set. Then we should be
- // setting the activity to current ActivityInfo. However that activity
- // might be dead, in which case we should skip it, so we never set
- // the ID to dead things.
- while (cur != null)
- {
- // We found a live activity (typically the first time), set it to that.
- if (cur.m_stopped == 0)
- {
- EventSource.SetCurrentThreadActivityId(cur.ActivityId);
- return;
- }
- cur = cur.m_creator;
- }
- // we can get here if there is no information on our activity stack (everything is dead)
- // currently we do nothing, as that seems better than setting to Guid.Emtpy.
- }
-
- /// <summary>
- /// Async local variables have the property that the are automatically copied whenever a task is created and used
- /// while that task is running. Thus m_current 'flows' to any task that is caused by the current thread that
- /// last set it.
- ///
- /// This variable points a a linked list that represents all Activities that have started but have not stopped.
- /// </summary>
- AsyncLocal<ActivityInfo> m_current;
- bool m_checkedForEnable;
-
- // Singleton
- private static ActivityTracker s_activityTrackerInstance = new ActivityTracker();
-
- // Used to create unique IDs at the top level. Not used for nested Ids (each activity has its own id generator)
- static long m_nextId = 0;
- private const ushort MAX_ACTIVITY_DEPTH = 100; // Limit maximum depth of activities to be tracked at 100.
- // This will avoid leaking memory in case of activities that are never stopped.
-
- #endregion
- }
-
-#if ES_BUILD_STANDALONE || PROJECTN
- /******************************** SUPPORT *****************************/
- /// <summary>
- /// This is supplied by the framework. It is has the semantics that the value is copied to any new Tasks that is created
- /// by the current task. Thus all causally related code gets this value. Note that reads and writes to this VARIABLE
- /// (not what it points it) to this does not need to be protected by locks because it is inherently thread local (you always
- /// only get your thread local copy which means that you never have races.
- /// </summary>
- ///
-#if ES_BUILD_STANDALONE
- [EventSource(Name = "Microsoft.Tasks.Nuget")]
-#else
- [EventSource(Name = "System.Diagnostics.Tracing.TplEtwProvider")]
-#endif
- internal class TplEtwProvider : EventSource
- {
- public class Keywords
- {
- public const EventKeywords TasksFlowActivityIds = (EventKeywords)0x80;
- public const EventKeywords Debug = (EventKeywords)0x20000;
- }
-
- public static TplEtwProvider Log = new TplEtwProvider();
- public bool Debug { get { return IsEnabled(EventLevel.Verbose, Keywords.Debug); } }
-
- public void DebugFacilityMessage(string Facility, string Message) { WriteEvent(1, Facility, Message); }
- public void DebugFacilityMessage1(string Facility, string Message, string Arg) { WriteEvent(2, Facility, Message, Arg); }
- public void SetActivityId(Guid Id) { WriteEvent(3, Id); }
- }
-#endif
-
-#if ES_BUILD_AGAINST_DOTNET_V35 || ES_BUILD_PCL || NO_ASYNC_LOCAL
- // In these cases we don't have any Async local support. Do nothing.
- internal sealed class AsyncLocalValueChangedArgs<T>
- {
- public T PreviousValue { get { return default(T); } }
- public T CurrentValue { get { return default(T); } }
-
- }
-
- internal sealed class AsyncLocal<T>
- {
- public AsyncLocal(Action<AsyncLocalValueChangedArgs<T>> valueChangedHandler) {
- throw new NotImplementedException("AsyncLocal only available on V4.6 and above");
- }
- public T Value
- {
- get { return default(T); }
- set { }
- }
- }
-#endif
-
-}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventDescriptor.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventDescriptor.cs
deleted file mode 100644
index 116b50f86c..0000000000
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventDescriptor.cs
+++ /dev/null
@@ -1,195 +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.InteropServices;
-
-#if ES_BUILD_STANDALONE
-using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment;
-#endif
-
-#if !ES_BUILD_AGAINST_DOTNET_V35
-using Contract = System.Diagnostics.Contracts.Contract;
-#else
-using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract;
-#endif
-
-#if ES_BUILD_STANDALONE
-namespace Microsoft.Diagnostics.Tracing
-#else
-namespace System.Diagnostics.Tracing
-#endif
-{
- [StructLayout(LayoutKind.Explicit, Size = 16)]
-#if !CORECLR
- [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
-#endif // CORECLR
- internal struct EventDescriptor
- {
- # region private
- [FieldOffset(0)]
- private int m_traceloggingId;
- [FieldOffset(0)]
- private ushort m_id;
- [FieldOffset(2)]
- private byte m_version;
- [FieldOffset(3)]
- private byte m_channel;
- [FieldOffset(4)]
- private byte m_level;
- [FieldOffset(5)]
- private byte m_opcode;
- [FieldOffset(6)]
- private ushort m_task;
- [FieldOffset(8)]
- private long m_keywords;
- #endregion
-
- public EventDescriptor(
- int traceloggingId,
- byte level,
- byte opcode,
- long keywords
- )
- {
- this.m_id = 0;
- this.m_version = 0;
- this.m_channel = 0;
- this.m_traceloggingId = traceloggingId;
- this.m_level = level;
- this.m_opcode = opcode;
- this.m_task = 0;
- this.m_keywords = keywords;
- }
-
- public EventDescriptor(
- int id,
- byte version,
- byte channel,
- byte level,
- byte opcode,
- int task,
- long keywords
- )
- {
- if (id < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(id), Resources.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
-
- if (id > ushort.MaxValue)
- {
- throw new ArgumentOutOfRangeException(nameof(id), Resources.GetResourceString("ArgumentOutOfRange_NeedValidId", 1, ushort.MaxValue));
- }
-
- m_traceloggingId = 0;
- m_id = (ushort)id;
- m_version = version;
- m_channel = channel;
- m_level = level;
- m_opcode = opcode;
- m_keywords = keywords;
-
- if (task < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(task), Resources.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
-
- if (task > ushort.MaxValue)
- {
- throw new ArgumentOutOfRangeException(nameof(task), Resources.GetResourceString("ArgumentOutOfRange_NeedValidId", 1, ushort.MaxValue));
- }
-
- m_task = (ushort)task;
- }
-
- public int EventId
- {
- get
- {
- return m_id;
- }
- }
- public byte Version
- {
- get
- {
- return m_version;
- }
- }
- public byte Channel
- {
- get
- {
- return m_channel;
- }
- }
- public byte Level
- {
- get
- {
- return m_level;
- }
- }
- public byte Opcode
- {
- get
- {
- return m_opcode;
- }
- }
- public int Task
- {
- get
- {
- return m_task;
- }
- }
- public long Keywords
- {
- get
- {
- return m_keywords;
- }
- }
-
- public override bool Equals(object obj)
- {
- if (!(obj is EventDescriptor))
- return false;
-
- return Equals((EventDescriptor) obj);
- }
-
- public override int GetHashCode()
- {
- return m_id ^ m_version ^ m_channel ^ m_level ^ m_opcode ^ m_task ^ (int)m_keywords;
- }
-
- public bool Equals(EventDescriptor other)
- {
- if ((m_id != other.m_id) ||
- (m_version != other.m_version) ||
- (m_channel != other.m_channel) ||
- (m_level != other.m_level) ||
- (m_opcode != other.m_opcode) ||
- (m_task != other.m_task) ||
- (m_keywords != other.m_keywords))
- {
- return false;
- }
- return true;
- }
-
- public static bool operator ==(EventDescriptor event1, EventDescriptor event2)
- {
- return event1.Equals(event2);
- }
-
- public static bool operator !=(EventDescriptor event1, EventDescriptor event2)
- {
- return !event1.Equals(event2);
- }
- }
-}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs
deleted file mode 100644
index 1da6a46707..0000000000
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventProvider.cs
+++ /dev/null
@@ -1,1207 +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 Microsoft.Win32;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
-using System.Runtime.InteropServices;
-using System.Security;
-#if !CORECLR
-using System.Security.Permissions;
-#endif // !CORECLR
-using System.Threading;
-using System;
-
-#if !ES_BUILD_AGAINST_DOTNET_V35
-using Contract = System.Diagnostics.Contracts.Contract;
-#else
-using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract;
-#endif
-
-#if ES_BUILD_AGAINST_DOTNET_V35
-using Microsoft.Internal; // for Tuple (can't define alias for open generic types so we "use" the whole namespace)
-#endif
-
-#if ES_BUILD_STANDALONE
-namespace Microsoft.Diagnostics.Tracing
-#else
-namespace System.Diagnostics.Tracing
-#endif
-{
- // New in CLR4.0
- internal enum ControllerCommand
- {
- // Strictly Positive numbers are for provider-specific commands, negative number are for 'shared' commands. 256
- // The first 256 negative numbers are reserved for the framework.
- Update = 0, // Not used by EventPrividerBase.
- SendManifest = -1,
- Enable = -2,
- Disable = -3,
- };
-
- /// <summary>
- /// Only here because System.Diagnostics.EventProvider needs one more extensibility hook (when it gets a
- /// controller callback)
- /// </summary>
-#if !CORECLR
- [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)]
-#endif // CORECLR
- internal partial class EventProvider : IDisposable
- {
- // This is the windows EVENT_DATA_DESCRIPTOR structure. We expose it because this is what
- // subclasses of EventProvider use when creating efficient (but unsafe) version of
- // EventWrite. We do make it a nested type because we really don't expect anyone to use
- // it except subclasses (and then only rarely).
- public struct EventData
- {
- internal unsafe ulong Ptr;
- internal uint Size;
- internal uint Reserved;
- }
-
- /// <summary>
- /// A struct characterizing ETW sessions (identified by the etwSessionId) as
- /// activity-tracing-aware or legacy. A session that's activity-tracing-aware
- /// has specified one non-zero bit in the reserved range 44-47 in the
- /// 'allKeywords' value it passed in for a specific EventProvider.
- /// </summary>
- public struct SessionInfo
- {
- internal int sessionIdBit; // the index of the bit used for tracing in the "reserved" field of AllKeywords
- internal int etwSessionId; // the machine-wide ETW session ID
-
- internal SessionInfo(int sessionIdBit_, int etwSessionId_)
- { sessionIdBit = sessionIdBit_; etwSessionId = etwSessionId_; }
- }
-
- private static bool m_setInformationMissing;
-
- UnsafeNativeMethods.ManifestEtw.EtwEnableCallback m_etwCallback; // Trace Callback function
- private long m_regHandle; // Trace Registration Handle
- private byte m_level; // Tracing Level
- private long m_anyKeywordMask; // Trace Enable Flags
- private long m_allKeywordMask; // Match all keyword
- private List<SessionInfo> m_liveSessions; // current live sessions (Tuple<sessionIdBit, etwSessionId>)
- private bool m_enabled; // Enabled flag from Trace callback
- private Guid m_providerId; // Control Guid
- internal bool m_disposed; // when true provider has unregistered
-
- [ThreadStatic]
- private static WriteEventErrorCode s_returnCode; // The last return code
-
- private const int s_basicTypeAllocationBufferSize = 16;
- private const int s_etwMaxNumberArguments = 128;
- private const int s_etwAPIMaxRefObjCount = 8;
- private const int s_maxEventDataDescriptors = 128;
- private const int s_traceEventMaximumSize = 65482;
- private const int s_traceEventMaximumStringSize = 32724;
-
- [SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
- public enum WriteEventErrorCode : int
- {
- //check mapping to runtime codes
- NoError = 0,
- NoFreeBuffers = 1,
- EventTooBig = 2,
- NullInput = 3,
- TooManyArgs = 4,
- Other = 5,
- };
-
- // Because callbacks happen on registration, and we need the callbacks for those setup
- // we can't call Register in the constructor.
- //
- // Note that EventProvider should ONLY be used by EventSource. In particular because
- // it registers a callback from native code you MUST dispose it BEFORE shutdown, otherwise
- // you may get native callbacks during shutdown when we have destroyed the delegate.
- // EventSource has special logic to do this, no one else should be calling EventProvider.
- internal EventProvider()
- {
- }
-
- /// <summary>
- /// This method registers the controlGuid of this class with ETW. We need to be running on
- /// Vista or above. If not a PlatformNotSupported exception will be thrown. If for some
- /// reason the ETW Register call failed a NotSupported exception will be thrown.
- /// </summary>
- // <SecurityKernel Critical="True" Ring="0">
- // <CallsSuppressUnmanagedCode Name="UnsafeNativeMethods.ManifestEtw.EventRegister(System.Guid&,Microsoft.Win32.UnsafeNativeMethods.ManifestEtw+EtwEnableCallback,System.Void*,System.Int64&):System.UInt32" />
- // <SatisfiesLinkDemand Name="Win32Exception..ctor(System.Int32)" />
- // <ReferencesCritical Name="Method: EtwEnableCallBack(Guid&, Int32, Byte, Int64, Int64, Void*, Void*):Void" Ring="1" />
- // </SecurityKernel>
- internal unsafe void Register(Guid providerGuid)
- {
- m_providerId = providerGuid;
- uint status;
- m_etwCallback = new UnsafeNativeMethods.ManifestEtw.EtwEnableCallback(EtwEnableCallBack);
-
- status = EventRegister(ref m_providerId, m_etwCallback);
- if (status != 0)
- {
- throw new ArgumentException(Win32Native.GetMessage(unchecked((int)status)));
- }
- }
-
- //
- // implement Dispose Pattern to early deregister from ETW insted of waiting for
- // the finalizer to call deregistration.
- // Once the user is done with the provider it needs to call Close() or Dispose()
- // If neither are called the finalizer will unregister the provider anyway
- //
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- // <SecurityKernel Critical="True" TreatAsSafe="Does not expose critical resource" Ring="1">
- // <ReferencesCritical Name="Method: Deregister():Void" Ring="1" />
- // </SecurityKernel>
- protected virtual void Dispose(bool disposing)
- {
- //
- // explicit cleanup is done by calling Dispose with true from
- // Dispose() or Close(). The disposing arguement is ignored because there
- // are no unmanaged resources.
- // The finalizer calls Dispose with false.
- //
-
- //
- // check if the object has been allready disposed
- //
- if (m_disposed) return;
-
- // Disable the provider.
- m_enabled = false;
-
- // Do most of the work under a lock to avoid shutdown race.
-
- long registrationHandle = 0;
- lock (EventListener.EventListenersLock)
- {
- // Double check
- if (m_disposed)
- return;
-
- registrationHandle = m_regHandle;
- m_regHandle = 0;
- m_disposed = true;
- }
-
- // We do the Unregistration outside the EventListenerLock because there is a lock
- // inside the ETW routines. This lock is taken before ETW issues commands
- // Thus the ETW lock gets taken first and then our EventListenersLock gets taken
- // in SendCommand(), and also here. If we called EventUnregister after taking
- // the EventListenersLock then the take-lock order is reversed and we can have
- // deadlocks in race conditions (dispose racing with an ETW command).
- //
- // We solve by Unregistering after releasing the EventListenerLock.
- if (registrationHandle != 0)
- EventUnregister(registrationHandle);
-
- }
-
- /// <summary>
- /// This method deregisters the controlGuid of this class with ETW.
- ///
- /// </summary>
- public virtual void Close()
- {
- Dispose();
- }
-
- ~EventProvider()
- {
- Dispose(false);
- }
-
- // <SecurityKernel Critical="True" Ring="0">
- // <UsesUnsafeCode Name="Parameter filterData of type: Void*" />
- // <UsesUnsafeCode Name="Parameter callbackContext of type: Void*" />
- // </SecurityKernel>
- unsafe void EtwEnableCallBack(
- [In] ref System.Guid sourceId,
- [In] int controlCode,
- [In] byte setLevel,
- [In] long anyKeyword,
- [In] long allKeyword,
- [In] UnsafeNativeMethods.ManifestEtw.EVENT_FILTER_DESCRIPTOR* filterData,
- [In] void* callbackContext
- )
- {
- // This is an optional callback API. We will therefore ignore any failures that happen as a
- // result of turning on this provider as to not crash the app.
- // EventSource has code to validate whether initialization it expected to occur actually occurred
- try
- {
- ControllerCommand command = ControllerCommand.Update;
- IDictionary<string, string> args = null;
- bool skipFinalOnControllerCommand = false;
- if (controlCode == UnsafeNativeMethods.ManifestEtw.EVENT_CONTROL_CODE_ENABLE_PROVIDER)
- {
- m_enabled = true;
- m_level = setLevel;
- m_anyKeywordMask = anyKeyword;
- m_allKeywordMask = allKeyword;
-
- // ES_SESSION_INFO is a marker for additional places we #ifdeffed out to remove
- // references to EnumerateTraceGuidsEx. This symbol is actually not used because
- // today we use FEATURE_ACTIVITYSAMPLING to determine if this code is there or not.
- // However we put it in the #if so that we don't lose the fact that this feature
- // switch is at least partially independent of FEATURE_ACTIVITYSAMPLING
-
- List<Tuple<SessionInfo, bool>> sessionsChanged = GetSessions();
- foreach (var session in sessionsChanged)
- {
- int sessionChanged = session.Item1.sessionIdBit;
- int etwSessionId = session.Item1.etwSessionId;
- bool bEnabling = session.Item2;
-
- skipFinalOnControllerCommand = true;
- args = null; // reinitialize args for every session...
-
- // if we get more than one session changed we have no way
- // of knowing which one "filterData" belongs to
- if (sessionsChanged.Count > 1)
- filterData = null;
-
- // read filter data only when a session is being *added*
- byte[] data;
- int keyIndex;
- if (bEnabling &&
- GetDataFromController(etwSessionId, filterData, out command, out data, out keyIndex))
- {
- args = new Dictionary<string, string>(4);
- while (keyIndex < data.Length)
- {
- int keyEnd = FindNull(data, keyIndex);
- int valueIdx = keyEnd + 1;
- int valueEnd = FindNull(data, valueIdx);
- if (valueEnd < data.Length)
- {
- string key = System.Text.Encoding.UTF8.GetString(data, keyIndex, keyEnd - keyIndex);
- string value = System.Text.Encoding.UTF8.GetString(data, valueIdx, valueEnd - valueIdx);
- args[key] = value;
- }
- keyIndex = valueEnd + 1;
- }
- }
-
- // execute OnControllerCommand once for every session that has changed.
- OnControllerCommand(command, args, (bEnabling ? sessionChanged : -sessionChanged), etwSessionId);
- }
- }
- else if (controlCode == UnsafeNativeMethods.ManifestEtw.EVENT_CONTROL_CODE_DISABLE_PROVIDER)
- {
- m_enabled = false;
- m_level = 0;
- m_anyKeywordMask = 0;
- m_allKeywordMask = 0;
- m_liveSessions = null;
- }
- else if (controlCode == UnsafeNativeMethods.ManifestEtw.EVENT_CONTROL_CODE_CAPTURE_STATE)
- {
- command = ControllerCommand.SendManifest;
- }
- else
- return; // per spec you ignore commands you don't recognize.
-
- if (!skipFinalOnControllerCommand)
- OnControllerCommand(command, args, 0, 0);
- }
- catch (Exception)
- {
- // We want to ignore any failures that happen as a result of turning on this provider as to
- // not crash the app.
- }
- }
-
- // New in CLR4.0
- protected virtual void OnControllerCommand(ControllerCommand command, IDictionary<string, string> arguments, int sessionId, int etwSessionId) { }
- protected EventLevel Level { get { return (EventLevel)m_level; } set { m_level = (byte)value; } }
- protected EventKeywords MatchAnyKeyword { get { return (EventKeywords)m_anyKeywordMask; } set { m_anyKeywordMask = unchecked((long)value); } }
- protected EventKeywords MatchAllKeyword { get { return (EventKeywords)m_allKeywordMask; } set { m_allKeywordMask = unchecked((long)value); } }
-
- static private int FindNull(byte[] buffer, int idx)
- {
- while (idx < buffer.Length && buffer[idx] != 0)
- idx++;
- return idx;
- }
-
- /// <summary>
- /// Determines the ETW sessions that have been added and/or removed to the set of
- /// sessions interested in the current provider. It does so by (1) enumerating over all
- /// ETW sessions that enabled 'this.m_Guid' for the current process ID, and (2)
- /// comparing the current list with a list it cached on the previous invocation.
- ///
- /// The return value is a list of tuples, where the SessionInfo specifies the
- /// ETW session that was added or remove, and the bool specifies whether the
- /// session was added or whether it was removed from the set.
- /// </summary>
- private List<Tuple<SessionInfo, bool>> GetSessions()
- {
- List<SessionInfo> liveSessionList = null;
-
- GetSessionInfo(
- (int etwSessionId, long matchAllKeywords, ref List<SessionInfo> sessionList) =>
- GetSessionInfoCallback(etwSessionId, matchAllKeywords, ref sessionList),
- ref liveSessionList);
-
- List<Tuple<SessionInfo, bool>> changedSessionList = new List<Tuple<SessionInfo, bool>>();
-
- // first look for sessions that have gone away (or have changed)
- // (present in the m_liveSessions but not in the new liveSessionList)
- if (m_liveSessions != null)
- {
- foreach (SessionInfo s in m_liveSessions)
- {
- int idx;
- if ((idx = IndexOfSessionInList(liveSessionList, s.etwSessionId)) < 0 ||
- (liveSessionList[idx].sessionIdBit != s.sessionIdBit))
- changedSessionList.Add(Tuple.Create(s, false));
-
- }
- }
- // next look for sessions that were created since the last callback (or have changed)
- // (present in the new liveSessionList but not in m_liveSessions)
- if (liveSessionList != null)
- {
- foreach (SessionInfo s in liveSessionList)
- {
- int idx;
- if ((idx = IndexOfSessionInList(m_liveSessions, s.etwSessionId)) < 0 ||
- (m_liveSessions[idx].sessionIdBit != s.sessionIdBit))
- changedSessionList.Add(Tuple.Create(s, true));
- }
- }
-
- m_liveSessions = liveSessionList;
- return changedSessionList;
- }
-
-
- /// <summary>
- /// This method is the callback used by GetSessions() when it calls into GetSessionInfo().
- /// It updates a List{SessionInfo} based on the etwSessionId and matchAllKeywords that
- /// GetSessionInfo() passes in.
- /// </summary>
- private static void GetSessionInfoCallback(int etwSessionId, long matchAllKeywords,
- ref List<SessionInfo> sessionList)
- {
- uint sessionIdBitMask = (uint)SessionMask.FromEventKeywords(unchecked((ulong)matchAllKeywords));
- // an ETW controller that specifies more than the mandated bit for our EventSource
- // will be ignored...
- if (bitcount(sessionIdBitMask) > 1)
- return;
-
- if (sessionList == null)
- sessionList = new List<SessionInfo>(8);
-
- if (bitcount(sessionIdBitMask) == 1)
- {
- // activity-tracing-aware etw session
- sessionList.Add(new SessionInfo(bitindex(sessionIdBitMask) + 1, etwSessionId));
- }
- else
- {
- // legacy etw session
- sessionList.Add(new SessionInfo(bitcount((uint)SessionMask.All) + 1, etwSessionId));
- }
- }
-
- private delegate void SessionInfoCallback(int etwSessionId, long matchAllKeywords, ref List<SessionInfo> sessionList);
-
- /// <summary>
- /// This method enumerates over all active ETW sessions that have enabled 'this.m_Guid'
- /// for the current process ID, calling 'action' for each session, and passing it the
- /// ETW session and the 'AllKeywords' the session enabled for the current provider.
- /// </summary>
- private unsafe void GetSessionInfo(SessionInfoCallback action, ref List<SessionInfo> sessionList)
- {
- // We wish the EventSource package to be legal for Windows Store applications.
- // Currently EnumerateTraceGuidsEx is not an allowed API, so we avoid its use here
- // and use the information in the registry instead. This means that ETW controllers
- // that do not publish their intent to the registry (basically all controllers EXCEPT
- // TraceEventSesion) will not work properly
-
- // However the framework version of EventSource DOES have ES_SESSION_INFO defined and thus
- // does not have this issue.
-#if ES_SESSION_INFO || !ES_BUILD_STANDALONE
- int buffSize = 256; // An initial guess that probably works most of the time.
- byte* buffer;
- for (; ; )
- {
- var space = stackalloc byte[buffSize];
- buffer = space;
- var hr = 0;
-
- fixed (Guid* provider = &m_providerId)
- {
- hr = UnsafeNativeMethods.ManifestEtw.EnumerateTraceGuidsEx(UnsafeNativeMethods.ManifestEtw.TRACE_QUERY_INFO_CLASS.TraceGuidQueryInfo,
- provider, sizeof(Guid), buffer, buffSize, ref buffSize);
- }
- if (hr == 0)
- break;
- if (hr != 122 /* ERROR_INSUFFICIENT_BUFFER */)
- return;
- }
-
- var providerInfos = (UnsafeNativeMethods.ManifestEtw.TRACE_GUID_INFO*)buffer;
- var providerInstance = (UnsafeNativeMethods.ManifestEtw.TRACE_PROVIDER_INSTANCE_INFO*)&providerInfos[1];
- int processId = unchecked((int)Win32Native.GetCurrentProcessId());
- // iterate over the instances of the EventProvider in all processes
- for (int i = 0; i < providerInfos->InstanceCount; i++)
- {
- if (providerInstance->Pid == processId)
- {
- var enabledInfos = (UnsafeNativeMethods.ManifestEtw.TRACE_ENABLE_INFO*)&providerInstance[1];
- // iterate over the list of active ETW sessions "listening" to the current provider
- for (int j = 0; j < providerInstance->EnableCount; j++)
- action(enabledInfos[j].LoggerId, enabledInfos[j].MatchAllKeyword, ref sessionList);
- }
- if (providerInstance->NextOffset == 0)
- break;
- Debug.Assert(0 <= providerInstance->NextOffset && providerInstance->NextOffset < buffSize);
- var structBase = (byte*)providerInstance;
- providerInstance = (UnsafeNativeMethods.ManifestEtw.TRACE_PROVIDER_INSTANCE_INFO*)&structBase[providerInstance->NextOffset];
- }
-#else
-#if !ES_BUILD_PCL && !FEATURE_PAL // TODO command arguments don't work on PCL builds...
- // This code is only used in the Nuget Package Version of EventSource. because
- // the code above is using APIs baned from UWP apps.
- //
- // TODO: In addition to only working when TraceEventSession enables the provider, this code
- // also has a problem because TraceEvent does not clean up if the registry is stale
- // It is unclear if it is worth keeping, but for now we leave it as it does work
- // at least some of the time.
-
- // Determine our session from what is in the registry.
- string regKey = @"\Microsoft\Windows\CurrentVersion\Winevt\Publishers\{" + m_providerId + "}";
- if (System.Runtime.InteropServices.Marshal.SizeOf(typeof(IntPtr)) == 8)
- regKey = @"Software" + @"\Wow6432Node" + regKey;
- else
- regKey = @"Software" + regKey;
-
- var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(regKey);
- if (key != null)
- {
- foreach (string valueName in key.GetValueNames())
- {
- if (valueName.StartsWith("ControllerData_Session_", StringComparison.Ordinal))
- {
- string strId = valueName.Substring(23); // strip of the ControllerData_Session_
- int etwSessionId;
- if (int.TryParse(strId, out etwSessionId))
- {
- // we need to assert this permission for partial trust scenarios
- (new RegistryPermission(RegistryPermissionAccess.Read, regKey)).Assert();
- var data = key.GetValue(valueName) as byte[];
- if (data != null)
- {
- var dataAsString = System.Text.Encoding.UTF8.GetString(data);
- int keywordIdx = dataAsString.IndexOf("EtwSessionKeyword", StringComparison.Ordinal);
- if (0 <= keywordIdx)
- {
- int startIdx = keywordIdx + 18;
- int endIdx = dataAsString.IndexOf('\0', startIdx);
- string keywordBitString = dataAsString.Substring(startIdx, endIdx-startIdx);
- int keywordBit;
- if (0 < endIdx && int.TryParse(keywordBitString, out keywordBit))
- action(etwSessionId, 1L << keywordBit, ref sessionList);
- }
- }
- }
- }
- }
- }
-#endif
-#endif
- }
-
- /// <summary>
- /// Returns the index of the SesisonInfo from 'sessions' that has the specified 'etwSessionId'
- /// or -1 if the value is not present.
- /// </summary>
- private static int IndexOfSessionInList(List<SessionInfo> sessions, int etwSessionId)
- {
- if (sessions == null)
- return -1;
- // for non-coreclr code we could use List<T>.FindIndex(Predicate<T>), but we need this to compile
- // on coreclr as well
- for (int i = 0; i < sessions.Count; ++i)
- if (sessions[i].etwSessionId == etwSessionId)
- return i;
-
- return -1;
- }
-
- /// <summary>
- /// Gets any data to be passed from the controller to the provider. It starts with what is passed
- /// into the callback, but unfortunately this data is only present for when the provider is active
- /// at the time the controller issues the command. To allow for providers to activate after the
- /// controller issued a command, we also check the registry and use that to get the data. The function
- /// returns an array of bytes representing the data, the index into that byte array where the data
- /// starts, and the command being issued associated with that data.
- /// </summary>
- private unsafe bool GetDataFromController(int etwSessionId,
- UnsafeNativeMethods.ManifestEtw.EVENT_FILTER_DESCRIPTOR* filterData, out ControllerCommand command, out byte[] data, out int dataStart)
- {
- data = null;
- dataStart = 0;
- if (filterData == null)
- {
-#if (!ES_BUILD_PCL && !PROJECTN && !FEATURE_PAL)
- string regKey = @"\Microsoft\Windows\CurrentVersion\Winevt\Publishers\{" + m_providerId + "}";
- if (System.Runtime.InteropServices.Marshal.SizeOf(typeof(IntPtr)) == 8)
- regKey = @"HKEY_LOCAL_MACHINE\Software" + @"\Wow6432Node" + regKey;
- else
- regKey = @"HKEY_LOCAL_MACHINE\Software" + regKey;
-
- string valueName = "ControllerData_Session_" + etwSessionId.ToString(CultureInfo.InvariantCulture);
-
- // we need to assert this permission for partial trust scenarios
-#if !CORECLR
- (new RegistryPermission(RegistryPermissionAccess.Read, regKey)).Assert();
-#endif
- data = Microsoft.Win32.Registry.GetValue(regKey, valueName, null) as byte[];
- if (data != null)
- {
- // We only used the persisted data from the registry for updates.
- command = ControllerCommand.Update;
- return true;
- }
-#endif
- }
- else
- {
- if (filterData->Ptr != 0 && 0 < filterData->Size && filterData->Size <= 1024)
- {
- data = new byte[filterData->Size];
- Marshal.Copy((IntPtr)filterData->Ptr, data, 0, data.Length);
- }
- command = (ControllerCommand)filterData->Type;
- return true;
- }
-
- command = ControllerCommand.Update;
- return false;
- }
-
- /// <summary>
- /// IsEnabled, method used to test if provider is enabled
- /// </summary>
- public bool IsEnabled()
- {
- return m_enabled;
- }
-
- /// <summary>
- /// IsEnabled, method used to test if event is enabled
- /// </summary>
- /// <param name="level">
- /// Level to test
- /// </param>
- /// <param name="keywords">
- /// Keyword to test
- /// </param>
- public bool IsEnabled(byte level, long keywords)
- {
- //
- // If not enabled at all, return false.
- //
- if (!m_enabled)
- {
- return false;
- }
-
- // This also covers the case of Level == 0.
- if ((level <= m_level) ||
- (m_level == 0))
- {
-
- //
- // Check if Keyword is enabled
- //
-
- if ((keywords == 0) ||
- (((keywords & m_anyKeywordMask) != 0) &&
- ((keywords & m_allKeywordMask) == m_allKeywordMask)))
- {
- return true;
- }
- }
-
- return false;
- }
-
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
- public static WriteEventErrorCode GetLastWriteEventError()
- {
- return s_returnCode;
- }
-
- //
- // Helper function to set the last error on the thread
- //
- private static void SetLastError(int error)
- {
- switch (error)
- {
- case UnsafeNativeMethods.ManifestEtw.ERROR_ARITHMETIC_OVERFLOW:
- case UnsafeNativeMethods.ManifestEtw.ERROR_MORE_DATA:
- s_returnCode = WriteEventErrorCode.EventTooBig;
- break;
- case UnsafeNativeMethods.ManifestEtw.ERROR_NOT_ENOUGH_MEMORY:
- s_returnCode = WriteEventErrorCode.NoFreeBuffers;
- break;
- }
- }
-
- // <SecurityKernel Critical="True" Ring="0">
- // <UsesUnsafeCode Name="Local intptrPtr of type: IntPtr*" />
- // <UsesUnsafeCode Name="Local intptrPtr of type: Int32*" />
- // <UsesUnsafeCode Name="Local longptr of type: Int64*" />
- // <UsesUnsafeCode Name="Local uintptr of type: UInt32*" />
- // <UsesUnsafeCode Name="Local ulongptr of type: UInt64*" />
- // <UsesUnsafeCode Name="Local charptr of type: Char*" />
- // <UsesUnsafeCode Name="Local byteptr of type: Byte*" />
- // <UsesUnsafeCode Name="Local shortptr of type: Int16*" />
- // <UsesUnsafeCode Name="Local sbyteptr of type: SByte*" />
- // <UsesUnsafeCode Name="Local ushortptr of type: UInt16*" />
- // <UsesUnsafeCode Name="Local floatptr of type: Single*" />
- // <UsesUnsafeCode Name="Local doubleptr of type: Double*" />
- // <UsesUnsafeCode Name="Local boolptr of type: Boolean*" />
- // <UsesUnsafeCode Name="Local guidptr of type: Guid*" />
- // <UsesUnsafeCode Name="Local decimalptr of type: Decimal*" />
- // <UsesUnsafeCode Name="Local booleanptr of type: Boolean*" />
- // <UsesUnsafeCode Name="Parameter dataDescriptor of type: EventData*" />
- // <UsesUnsafeCode Name="Parameter dataBuffer of type: Byte*" />
- // </SecurityKernel>
- private static unsafe object EncodeObject(ref object data, ref EventData* dataDescriptor, ref byte* dataBuffer, ref uint totalEventSize)
- /*++
-
- Routine Description:
-
- This routine is used by WriteEvent to unbox the object type and
- to fill the passed in ETW data descriptor.
-
- Arguments:
-
- data - argument to be decoded
-
- dataDescriptor - pointer to the descriptor to be filled (updated to point to the next empty entry)
-
- dataBuffer - storage buffer for storing user data, needed because cant get the address of the object
- (updated to point to the next empty entry)
-
- Return Value:
-
- null if the object is a basic type other than string or byte[]. String otherwise
-
- --*/
- {
- Again:
- dataDescriptor->Reserved = 0;
-
- string sRet = data as string;
- byte[] blobRet = null;
-
- if (sRet != null)
- {
- dataDescriptor->Size = ((uint)sRet.Length + 1) * 2;
- }
- else if ((blobRet = data as byte[]) != null)
- {
- // first store array length
- *(int*)dataBuffer = blobRet.Length;
- dataDescriptor->Ptr = (ulong)dataBuffer;
- dataDescriptor->Size = 4;
- totalEventSize += dataDescriptor->Size;
-
- // then the array parameters
- dataDescriptor++;
- dataBuffer += s_basicTypeAllocationBufferSize;
- dataDescriptor->Size = (uint)blobRet.Length;
- }
- else if (data is IntPtr)
- {
- dataDescriptor->Size = (uint)sizeof(IntPtr);
- IntPtr* intptrPtr = (IntPtr*)dataBuffer;
- *intptrPtr = (IntPtr)data;
- dataDescriptor->Ptr = (ulong)intptrPtr;
- }
- else if (data is int)
- {
- dataDescriptor->Size = (uint)sizeof(int);
- int* intptr = (int*)dataBuffer;
- *intptr = (int)data;
- dataDescriptor->Ptr = (ulong)intptr;
- }
- else if (data is long)
- {
- dataDescriptor->Size = (uint)sizeof(long);
- long* longptr = (long*)dataBuffer;
- *longptr = (long)data;
- dataDescriptor->Ptr = (ulong)longptr;
- }
- else if (data is uint)
- {
- dataDescriptor->Size = (uint)sizeof(uint);
- uint* uintptr = (uint*)dataBuffer;
- *uintptr = (uint)data;
- dataDescriptor->Ptr = (ulong)uintptr;
- }
- else if (data is UInt64)
- {
- dataDescriptor->Size = (uint)sizeof(ulong);
- UInt64* ulongptr = (ulong*)dataBuffer;
- *ulongptr = (ulong)data;
- dataDescriptor->Ptr = (ulong)ulongptr;
- }
- else if (data is char)
- {
- dataDescriptor->Size = (uint)sizeof(char);
- char* charptr = (char*)dataBuffer;
- *charptr = (char)data;
- dataDescriptor->Ptr = (ulong)charptr;
- }
- else if (data is byte)
- {
- dataDescriptor->Size = (uint)sizeof(byte);
- byte* byteptr = (byte*)dataBuffer;
- *byteptr = (byte)data;
- dataDescriptor->Ptr = (ulong)byteptr;
- }
- else if (data is short)
- {
- dataDescriptor->Size = (uint)sizeof(short);
- short* shortptr = (short*)dataBuffer;
- *shortptr = (short)data;
- dataDescriptor->Ptr = (ulong)shortptr;
- }
- else if (data is sbyte)
- {
- dataDescriptor->Size = (uint)sizeof(sbyte);
- sbyte* sbyteptr = (sbyte*)dataBuffer;
- *sbyteptr = (sbyte)data;
- dataDescriptor->Ptr = (ulong)sbyteptr;
- }
- else if (data is ushort)
- {
- dataDescriptor->Size = (uint)sizeof(ushort);
- ushort* ushortptr = (ushort*)dataBuffer;
- *ushortptr = (ushort)data;
- dataDescriptor->Ptr = (ulong)ushortptr;
- }
- else if (data is float)
- {
- dataDescriptor->Size = (uint)sizeof(float);
- float* floatptr = (float*)dataBuffer;
- *floatptr = (float)data;
- dataDescriptor->Ptr = (ulong)floatptr;
- }
- else if (data is double)
- {
- dataDescriptor->Size = (uint)sizeof(double);
- double* doubleptr = (double*)dataBuffer;
- *doubleptr = (double)data;
- dataDescriptor->Ptr = (ulong)doubleptr;
- }
- else if (data is bool)
- {
- // WIN32 Bool is 4 bytes
- dataDescriptor->Size = 4;
- int* intptr = (int*)dataBuffer;
- if (((bool)data))
- {
- *intptr = 1;
- }
- else
- {
- *intptr = 0;
- }
- dataDescriptor->Ptr = (ulong)intptr;
- }
- else if (data is Guid)
- {
- dataDescriptor->Size = (uint)sizeof(Guid);
- Guid* guidptr = (Guid*)dataBuffer;
- *guidptr = (Guid)data;
- dataDescriptor->Ptr = (ulong)guidptr;
- }
- else if (data is decimal)
- {
- dataDescriptor->Size = (uint)sizeof(decimal);
- decimal* decimalptr = (decimal*)dataBuffer;
- *decimalptr = (decimal)data;
- dataDescriptor->Ptr = (ulong)decimalptr;
- }
- else if (data is DateTime)
- {
- const long UTCMinTicks = 504911232000000000;
- long dateTimeTicks = 0;
- // We cannot translate dates sooner than 1/1/1601 in UTC.
- // To avoid getting an ArgumentOutOfRangeException we compare with 1/1/1601 DateTime ticks
- if (((DateTime)data).Ticks > UTCMinTicks)
- dateTimeTicks = ((DateTime)data).ToFileTimeUtc();
- dataDescriptor->Size = (uint)sizeof(long);
- long* longptr = (long*)dataBuffer;
- *longptr = dateTimeTicks;
- dataDescriptor->Ptr = (ulong)longptr;
- }
- else
- {
- if (data is System.Enum)
- {
- Type underlyingType = Enum.GetUnderlyingType(data.GetType());
- if (underlyingType == typeof(int))
- {
-#if !ES_BUILD_PCL
- data = ((IConvertible)data).ToInt32(null);
-#else
- data = (int)data;
-#endif
- goto Again;
- }
- else if (underlyingType == typeof(long))
- {
-#if !ES_BUILD_PCL
- data = ((IConvertible)data).ToInt64(null);
-#else
- data = (long)data;
-#endif
- goto Again;
- }
- }
-
- // To our eyes, everything else is a just a string
- if (data == null)
- sRet = "";
- else
- sRet = data.ToString();
- dataDescriptor->Size = ((uint)sRet.Length + 1) * 2;
- }
-
- totalEventSize += dataDescriptor->Size;
-
- // advance buffers
- dataDescriptor++;
- dataBuffer += s_basicTypeAllocationBufferSize;
-
- return (object)sRet ?? (object)blobRet;
- }
-
- /// <summary>
- /// WriteEvent, method to write a parameters with event schema properties
- /// </summary>
- /// <param name="eventDescriptor">
- /// Event Descriptor for this event.
- /// </param>
- /// <param name="activityID">
- /// A pointer to the activity ID GUID to log
- /// </param>
- /// <param name="childActivityID">
- /// childActivityID is marked as 'related' to the current activity ID.
- /// </param>
- /// <param name="eventPayload">
- /// Payload for the ETW event.
- /// </param>
- // <SecurityKernel Critical="True" Ring="0">
- // <CallsSuppressUnmanagedCode Name="UnsafeNativeMethods.ManifestEtw.EventWrite(System.Int64,EventDescriptor&,System.UInt32,System.Void*):System.UInt32" />
- // <UsesUnsafeCode Name="Local dataBuffer of type: Byte*" />
- // <UsesUnsafeCode Name="Local pdata of type: Char*" />
- // <UsesUnsafeCode Name="Local userData of type: EventData*" />
- // <UsesUnsafeCode Name="Local userDataPtr of type: EventData*" />
- // <UsesUnsafeCode Name="Local currentBuffer of type: Byte*" />
- // <UsesUnsafeCode Name="Local v0 of type: Char*" />
- // <UsesUnsafeCode Name="Local v1 of type: Char*" />
- // <UsesUnsafeCode Name="Local v2 of type: Char*" />
- // <UsesUnsafeCode Name="Local v3 of type: Char*" />
- // <UsesUnsafeCode Name="Local v4 of type: Char*" />
- // <UsesUnsafeCode Name="Local v5 of type: Char*" />
- // <UsesUnsafeCode Name="Local v6 of type: Char*" />
- // <UsesUnsafeCode Name="Local v7 of type: Char*" />
- // <ReferencesCritical Name="Method: EncodeObject(Object&, EventData*, Byte*):String" Ring="1" />
- // </SecurityKernel>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Performance-critical code")]
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
- internal unsafe bool WriteEvent(ref EventDescriptor eventDescriptor, Guid* activityID, Guid* childActivityID, params object[] eventPayload)
- {
- int status = 0;
-
- if (IsEnabled(eventDescriptor.Level, eventDescriptor.Keywords))
- {
- int argCount = 0;
- unsafe
- {
- argCount = eventPayload.Length;
-
- if (argCount > s_etwMaxNumberArguments)
- {
- s_returnCode = WriteEventErrorCode.TooManyArgs;
- return false;
- }
-
- uint totalEventSize = 0;
- int index;
- int refObjIndex = 0;
- List<int> refObjPosition = new List<int>(s_etwAPIMaxRefObjCount);
- List<object> dataRefObj = new List<object>(s_etwAPIMaxRefObjCount);
- EventData* userData = stackalloc EventData[2 * argCount];
- EventData* userDataPtr = (EventData*)userData;
- byte* dataBuffer = stackalloc byte[s_basicTypeAllocationBufferSize * 2 * argCount]; // Assume 16 chars for non-string argument
- byte* currentBuffer = dataBuffer;
-
- //
- // The loop below goes through all the arguments and fills in the data
- // descriptors. For strings save the location in the dataString array.
- // Calculates the total size of the event by adding the data descriptor
- // size value set in EncodeObject method.
- //
- bool hasNonStringRefArgs = false;
- for (index = 0; index < eventPayload.Length; index++)
- {
- if (eventPayload[index] != null)
- {
- object supportedRefObj;
- supportedRefObj = EncodeObject(ref eventPayload[index], ref userDataPtr, ref currentBuffer, ref totalEventSize);
-
- if (supportedRefObj != null)
- {
- // EncodeObject advanced userDataPtr to the next empty slot
- int idx = (int)(userDataPtr - userData - 1);
- if (!(supportedRefObj is string))
- {
- if (eventPayload.Length + idx + 1 - index > s_etwMaxNumberArguments)
- {
- s_returnCode = WriteEventErrorCode.TooManyArgs;
- return false;
- }
- hasNonStringRefArgs = true;
- }
- dataRefObj.Add(supportedRefObj);
- refObjPosition.Add(idx);
- refObjIndex++;
- }
- }
- else
- {
- s_returnCode = WriteEventErrorCode.NullInput;
- return false;
- }
- }
-
- // update argCount based on actual number of arguments written to 'userData'
- argCount = (int)(userDataPtr - userData);
-
- if (totalEventSize > s_traceEventMaximumSize)
- {
- s_returnCode = WriteEventErrorCode.EventTooBig;
- return false;
- }
-
- // the optimized path (using "fixed" instead of allocating pinned GCHandles
- if (!hasNonStringRefArgs && (refObjIndex < s_etwAPIMaxRefObjCount))
- {
- // Fast path: at most 8 string arguments
-
- // ensure we have at least s_etwAPIMaxStringCount in dataString, so that
- // the "fixed" statement below works
- while (refObjIndex < s_etwAPIMaxRefObjCount)
- {
- dataRefObj.Add(null);
- ++refObjIndex;
- }
-
- //
- // now fix any string arguments and set the pointer on the data descriptor
- //
- fixed (char* v0 = (string)dataRefObj[0], v1 = (string)dataRefObj[1], v2 = (string)dataRefObj[2], v3 = (string)dataRefObj[3],
- v4 = (string)dataRefObj[4], v5 = (string)dataRefObj[5], v6 = (string)dataRefObj[6], v7 = (string)dataRefObj[7])
- {
- userDataPtr = (EventData*)userData;
- if (dataRefObj[0] != null)
- {
- userDataPtr[refObjPosition[0]].Ptr = (ulong)v0;
- }
- if (dataRefObj[1] != null)
- {
- userDataPtr[refObjPosition[1]].Ptr = (ulong)v1;
- }
- if (dataRefObj[2] != null)
- {
- userDataPtr[refObjPosition[2]].Ptr = (ulong)v2;
- }
- if (dataRefObj[3] != null)
- {
- userDataPtr[refObjPosition[3]].Ptr = (ulong)v3;
- }
- if (dataRefObj[4] != null)
- {
- userDataPtr[refObjPosition[4]].Ptr = (ulong)v4;
- }
- if (dataRefObj[5] != null)
- {
- userDataPtr[refObjPosition[5]].Ptr = (ulong)v5;
- }
- if (dataRefObj[6] != null)
- {
- userDataPtr[refObjPosition[6]].Ptr = (ulong)v6;
- }
- if (dataRefObj[7] != null)
- {
- userDataPtr[refObjPosition[7]].Ptr = (ulong)v7;
- }
-
- status = UnsafeNativeMethods.ManifestEtw.EventWriteTransferWrapper(m_regHandle, ref eventDescriptor, activityID, childActivityID, argCount, userData);
- }
- }
- else
- {
- // Slow path: use pinned handles
- userDataPtr = (EventData*)userData;
-
- GCHandle[] rgGCHandle = new GCHandle[refObjIndex];
- for (int i = 0; i < refObjIndex; ++i)
- {
- // below we still use "fixed" to avoid taking dependency on the offset of the first field
- // in the object (the way we would need to if we used GCHandle.AddrOfPinnedObject)
- rgGCHandle[i] = GCHandle.Alloc(dataRefObj[i], GCHandleType.Pinned);
- if (dataRefObj[i] is string)
- {
- fixed (char* p = (string)dataRefObj[i])
- userDataPtr[refObjPosition[i]].Ptr = (ulong)p;
- }
- else
- {
- fixed (byte* p = (byte[])dataRefObj[i])
- userDataPtr[refObjPosition[i]].Ptr = (ulong)p;
- }
- }
-
- status = UnsafeNativeMethods.ManifestEtw.EventWriteTransferWrapper(m_regHandle, ref eventDescriptor, activityID, childActivityID, argCount, userData);
-
- for (int i = 0; i < refObjIndex; ++i)
- {
- rgGCHandle[i].Free();
- }
- }
- }
- }
-
- if (status != 0)
- {
- SetLastError((int)status);
- return false;
- }
-
- return true;
- }
-
- /// <summary>
- /// WriteEvent, method to be used by generated code on a derived class
- /// </summary>
- /// <param name="eventDescriptor">
- /// Event Descriptor for this event.
- /// </param>
- /// <param name="activityID">
- /// A pointer to the activity ID to log
- /// </param>
- /// <param name="childActivityID">
- /// If this event is generating a child activity (WriteEventTransfer related activity) this is child activity
- /// This can be null for events that do not generate a child activity.
- /// </param>
- /// <param name="dataCount">
- /// number of event descriptors
- /// </param>
- /// <param name="data">
- /// pointer do the event data
- /// </param>
- // <SecurityKernel Critical="True" Ring="0">
- // <CallsSuppressUnmanagedCode Name="UnsafeNativeMethods.ManifestEtw.EventWrite(System.Int64,EventDescriptor&,System.UInt32,System.Void*):System.UInt32" />
- // </SecurityKernel>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
- internal unsafe protected bool WriteEvent(ref EventDescriptor eventDescriptor, Guid* activityID, Guid* childActivityID, int dataCount, IntPtr data)
- {
- if (childActivityID != null)
- {
- // activity transfers are supported only for events that specify the Send or Receive opcode
- Debug.Assert((EventOpcode)eventDescriptor.Opcode == EventOpcode.Send ||
- (EventOpcode)eventDescriptor.Opcode == EventOpcode.Receive ||
- (EventOpcode)eventDescriptor.Opcode == EventOpcode.Start ||
- (EventOpcode)eventDescriptor.Opcode == EventOpcode.Stop);
- }
-
- int status = UnsafeNativeMethods.ManifestEtw.EventWriteTransferWrapper(m_regHandle, ref eventDescriptor, activityID, childActivityID, dataCount, (EventData*)data);
-
- if (status != 0)
- {
- SetLastError(status);
- return false;
- }
- return true;
- }
-
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")]
- internal unsafe bool WriteEventRaw(
- ref EventDescriptor eventDescriptor,
- Guid* activityID,
- Guid* relatedActivityID,
- int dataCount,
- IntPtr data)
- {
- int status;
-
- status = UnsafeNativeMethods.ManifestEtw.EventWriteTransferWrapper(
- m_regHandle,
- ref eventDescriptor,
- activityID,
- relatedActivityID,
- dataCount,
- (EventData*)data);
-
- if (status != 0)
- {
- SetLastError(status);
- return false;
- }
- return true;
- }
-
-
- // These are look-alikes to the Manifest based ETW OS APIs that have been shimmed to work
- // either with Manifest ETW or Classic ETW (if Manifest based ETW is not available).
- private unsafe uint EventRegister(ref Guid providerId, UnsafeNativeMethods.ManifestEtw.EtwEnableCallback enableCallback)
- {
- m_providerId = providerId;
- m_etwCallback = enableCallback;
- return UnsafeNativeMethods.ManifestEtw.EventRegister(ref providerId, enableCallback, null, ref m_regHandle);
- }
-
- private uint EventUnregister(long registrationHandle)
- {
- return UnsafeNativeMethods.ManifestEtw.EventUnregister(registrationHandle);
- }
-
- static int[] nibblebits = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
- private static int bitcount(uint n)
- {
- int count = 0;
- for (; n != 0; n = n >> 4)
- count += nibblebits[n & 0x0f];
- return count;
- }
- private static int bitindex(uint n)
- {
- Debug.Assert(bitcount(n) == 1);
- int idx = 0;
- while ((n & (1 << idx)) == 0)
- idx++;
- return idx;
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs
deleted file mode 100644
index a558a1647e..0000000000
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs
+++ /dev/null
@@ -1,6912 +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.
-
-// This program uses code hyperlinks available as part of the HyperAddin Visual Studio plug-in.
-// It is available from http://www.codeplex.com/hyperAddin
-#if !PLATFORM_UNIX
-
-#define FEATURE_MANAGED_ETW
-
-#if !ES_BUILD_STANDALONE && !CORECLR && !PROJECTN
-#define FEATURE_ACTIVITYSAMPLING
-#endif // !ES_BUILD_STANDALONE
-
-#endif // !PLATFORM_UNIX
-
-#if ES_BUILD_STANDALONE
-#define FEATURE_MANAGED_ETW_CHANNELS
-// #define FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
-#endif
-
-/* DESIGN NOTES DESIGN NOTES DESIGN NOTES DESIGN NOTES */
-// DESIGN NOTES
-// Over the years EventSource has become more complex and so it is important to understand
-// the basic structure of the code to insure that it does not grow more complex.
-//
-// Basic Model
-//
-// PRINCIPLE: EventSource - ETW decoupling
-//
-// Conceptually and EventSouce is something takes event logging data from the source methods
-// To the EventListener that can subscribe them. Note that CONCEPTUALLY EVENTSOURCES DON'T
-// KNOW ABOUT ETW!. The MODEL of the system is that there is a special EventListern Which
-// we will call the EtwEventListener, that forwards commands from ETW to EventSources and
-// listeners to the EventSources and forwards on those events to ETW. THus the model should
-// be that you DON'T NEED ETW.
-//
-// Now in actual practice, EventSouce have rather intimate knowledge of ETW and send events
-// to it directly, but this can be VIEWED AS AN OPTIMIATION.
-//
-// Basic Event Data Flow:
-//
-// There are two ways for event Data to enter the system
-// 1) WriteEvent* and friends. This is called the 'contract' based approach because
-// you write a method per event which forms a contract that is know at compile time.
-// In this scheme each event is given an EVENTID (small integer). which is its identity
-// 2) Write<T> methods. This is called the 'dynamic' approach because new events
-// can be created on the fly. Event identity is determined by the event NAME, and these
-// are not quite as efficient at runtime since you have at least a hash table lookup
-// on every event write.
-//
-// EventSource-EventListener transfer fully support both ways of writing events (either contract
-// based (WriteEvent*) or dynamic (Write<T>). Both way fully support the same set of data
-// types. It is suggested, however, that you use the contract based approach when the event scheme
-// is known at compile time (that is whenever possible). It is more efficient, but more importantly
-// it makes the contract very explicit, and centralizes all policy about logging. These are good
-// things. The Write<T> API is really meant for more ad-hoc
-//
-// Allowed Data.
-//
-// Note that EventSource-EventListeners have a conceptual serialization-deserialization that happens
-// during the transfer. In particular object identity is not preserved, some objects are morphed,
-// and not all data types are supported. In particular you can pass
-//
-// A Valid type to log to an EventSource include
-// * Primitive data types
-// * IEnumerable<T> of valid types T (this include arrays) (* New for V4.6)
-// * Explicitly Opted in class or struct with public property Getters over Valid types. (* New for V4.6)
-//
-// This set of types is roughly a generalization of JSON support (Basically primitives, bags, and arrays).
-//
-// Explicitly allowed structs include (* New for V4.6)
-// * Marked with the EventData attribute
-// * implicitly defined (e.g the C# new {x = 3, y = 5} syntax)
-// * KeyValuePair<K,V> (thus dictionaries can be passed since they are an IEnumerable of KeyValuePair)
-//
-// When classes are returned in an EventListener, what is returned is something that implements
-// IDictionary<string, T>. Thus when objects are passed to an EventSource they are transformed
-// into a key-value bag (the IDictionary<string, T>) for consumption in the listener. These
-// are obvious NOT the original objects.
-//
-// ETWserialization formats:
-//
-// As mentioned conceptually EventSource's send data to EventListeners and there is a conceptual
-// copy/morph of that data as described above. In addition the .NET framework supports a conceptual
-// ETWListener that will send the data to then ETW stream. If you use this feature, the data needs
-// to be serialized in a way that ETW supports. ETW supports the following serialization formats
-//
-// 1) Manifest Based serialization.
-// 2) SelfDescribing serialization (TraceLogging style in the TraceLogging directory)
-//
-// A key factor is that the Write<T> method, which support on the fly definition of events, can't
-// support the manifest based serialization because the manifest needs the schema of all events
-// to be known before any events are emitted. This implies the following
-//
-// If you use Write<T> and the output goes to ETW it will use the SelfDescribing format.
-// If you use the EventSource(string) constructor for an eventSource (in which you don't
-// create a subclass), the default is also to use Self-Describing serialization. In addition
-// you can use the EventSoruce(EventSourceSettings) constructor to also explicitly specify
-// Self-Describing serialization format. These effect the WriteEvent* APIs going to ETW.
-//
-// Note that none of this ETW serialization logic affects EventListeners. Only the ETW listener.
-//
-// *************************************************************************************
-// *** INTERNALS: Event Propagation
-//
-// Data enters the system either though
-//
-// 1) A user defined method in the user defined subclass of EventSource which calls
-// A) A typesafe type specific overload of WriteEvent(ID, ...) e.g. WriteEvent(ID, string, string)
-// * which calls into the unsafe WriteEventCore(ID COUNT EventData*) WriteEventWithRelatedActivityIdCore()
-// B) The typesafe overload WriteEvent(ID, object[]) which calls the private helper WriteEventVarargs(ID, Guid* object[])
-// C) Directly into the unsafe WriteEventCore(ID, COUNT EventData*) or WriteEventWithRelatedActivityIdCore()
-//
-// All event data eventually flows to one of
-// * WriteEventWithRelatedActivityIdCore(ID, Guid*, COUNT, EventData*)
-// * WriteEventVarargs(ID, Guid*, object[])
-//
-// 2) A call to one of the overloads of Write<T>. All these overloads end up in
-// * WriteImpl<T>(EventName, Options, Data, Guid*, Guid*)
-//
-// On output there are the following routines
-// Writing to all listeners that are NOT ETW, we have the following routines
-// * WriteToAllListeners(ID, Guid*, COUNT, EventData*)
-// * WriteToAllListeners(ID, Guid*, object[])
-// * WriteToAllListeners(NAME, Guid*, EventPayload)
-//
-// EventPayload is the internal type that implements the IDictionary<string, object> interface
-// The EventListeners will pass back for serialized classes for nested object, but
-// WriteToAllListeners(NAME, Guid*, EventPayload) unpacks this uses the fields as if they
-// were parameters to a method.
-//
-// The first two are used for the WriteEvent* case, and the later is used for the Write<T> case.
-//
-// Writing to ETW, Manifest Based
-// EventProvider.WriteEvent(EventDescriptor, Guid*, COUNT, EventData*)
-// EventProvider.WriteEvent(EventDescriptor, Guid*, object[])
-// Writing to ETW, Self-Describing format
-// WriteMultiMerge(NAME, Options, Types, EventData*)
-// WriteMultiMerge(NAME, Options, Types, object[])
-// WriteImpl<T> has logic that knows how to serialize (like WriteMultiMerge) but also knows
-// will write it to
-//
-// All ETW writes eventually call
-// EventWriteTransfer (native PINVOKE wrapper)
-// EventWriteTransferWrapper (fixes compat problem if you pass null as the related activityID)
-// EventProvider.WriteEventRaw - sets last error
-// EventSource.WriteEventRaw - Does EventSource exception handling logic
-// WriteMultiMerge
-// WriteImpl<T>
-// EventProvider.WriteEvent(EventDescriptor, Guid*, COUNT, EventData*)
-// EventProvider.WriteEvent(EventDescriptor, Guid*, object[])
-//
-// Serialization: We have a bit of a hodge-podge of serializers right now. Only the one for ETW knows
-// how to deal with nested classes or arrays. I will call this serializer the 'TypeInfo' serializer
-// since it is the TraceLoggingTypeInfo structure that knows how to do this. Effectively for a type you
-// can call one of these
-// WriteMetadata - transforms the type T into serialization meta data blob for that type
-// WriteObjectData - transforms an object of T into serialization meta data blob for that type
-// GetData - transforms an object of T into its deserialized form suitable for passing to EventListener.
-// The first two are used to serialize something for ETW. The second one is used to transform the object
-// for use by the EventListener. We also have a 'DecodeObject' method that will take a EventData* and
-// deserialize to pass to an EventListener, but it only works on primitive types (types supported in version V4.5).
-//
-// It is an important observation that while EventSource does support users directly calling with EventData*
-// blobs, we ONLY support that for the primitive types (V4.5 level support). Thus while there is a EventData*
-// path through the system it is only for some types. The object[] path is the more general (but less efficient) path.
-//
-// TODO There is cleanup needed There should be no divergence until WriteEventRaw.
-//
-// TODO: We should have a single choke point (right now we always have this parallel EventData* and object[] path. This
-// was historical (at one point we tried to pass object directly from EventSoruce to EventListener. That was always
-// fragile and a compatibility headache, but we have finally been forced into the idea that there is always a transformation.
-// This allows us to use the EventData* form to be the canonical data format in the low level APIs. This also gives us the
-// opportunity to expose this format to EventListeners in the future.
-//
-using System;
-using System.Runtime.CompilerServices;
-#if FEATURE_ACTIVITYSAMPLING
-using System.Collections.Concurrent;
-#endif
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
-using System.Reflection;
-using System.Resources;
-using System.Security;
-#if !CORECLR
-using System.Security.Permissions;
-#endif // !CORECLR
-
-using System.Text;
-using System.Threading;
-using Microsoft.Win32;
-
-#if ES_BUILD_STANDALONE
-using EventDescriptor = Microsoft.Diagnostics.Tracing.EventDescriptor;
-#else
-using System.Threading.Tasks;
-#endif
-
-using Microsoft.Reflection;
-
-#if !ES_BUILD_AGAINST_DOTNET_V35
-using Contract = System.Diagnostics.Contracts.Contract;
-#else
-using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract;
-#endif
-
-#if ES_BUILD_STANDALONE
-namespace Microsoft.Diagnostics.Tracing
-#else
-namespace System.Diagnostics.Tracing
-#endif
-{
- /// <summary>
- /// This class is meant to be inherited by a user-defined event source in order to define a managed
- /// ETW provider. Please See DESIGN NOTES above for the internal architecture.
- /// The minimal definition of an EventSource simply specifies a number of ETW event methods that
- /// call one of the EventSource.WriteEvent overloads, <see cref="EventSource.WriteEventCore"/>,
- /// or <see cref="EventSource.WriteEventWithRelatedActivityIdCore"/> to log them. This functionality
- /// is sufficient for many users.
- /// <para>
- /// To achieve more control over the ETW provider manifest exposed by the event source type, the
- /// [<see cref="EventAttribute"/>] attributes can be specified for the ETW event methods.
- /// </para><para>
- /// For very advanced EventSources, it is possible to intercept the commands being given to the
- /// eventSource and change what filtering is done (see EventListener.EnableEvents and
- /// <see cref="EventListener.DisableEvents"/>) or cause actions to be performed by the eventSource,
- /// e.g. dumping a data structure (see EventSource.SendCommand and
- /// <see cref="EventSource.OnEventCommand"/>).
- /// </para><para>
- /// The eventSources can be turned on with Windows ETW controllers (e.g. logman), immediately.
- /// It is also possible to control and intercept the data dispatcher programmatically. See
- /// <see cref="EventListener"/> for more.
- /// </para>
- /// </summary>
- /// <remarks>
- /// This is a minimal definition for a custom event source:
- /// <code>
- /// [EventSource(Name="Samples-Demos-Minimal")]
- /// sealed class MinimalEventSource : EventSource
- /// {
- /// public static MinimalEventSource Log = new MinimalEventSource();
- /// public void Load(long ImageBase, string Name) { WriteEvent(1, ImageBase, Name); }
- /// public void Unload(long ImageBase) { WriteEvent(2, ImageBase); }
- /// private MinimalEventSource() {}
- /// }
- /// </code>
- /// </remarks>
- public partial class EventSource : IDisposable
- {
-
-#if FEATURE_EVENTSOURCE_XPLAT
- private static readonly EventListener persistent_Xplat_Listener = XplatEventLogger.InitializePersistentListener();
-#endif //FEATURE_EVENTSOURCE_XPLAT
-
- /// <summary>
- /// The human-friendly name of the eventSource. It defaults to the simple name of the class
- /// </summary>
- public string Name { get { return m_name; } }
- /// <summary>
- /// Every eventSource is assigned a GUID to uniquely identify it to the system.
- /// </summary>
- public Guid Guid { get { return m_guid; } }
-
- /// <summary>
- /// Returns true if the eventSource has been enabled at all. This is the prefered test
- /// to be performed before a relatively expensive EventSource operation.
- /// </summary>
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- public bool IsEnabled()
- {
- return m_eventSourceEnabled;
- }
-
- /// <summary>
- /// Returns true if events with greater than or equal 'level' and have one of 'keywords' set are enabled.
- ///
- /// Note that the result of this function is only an approximation on whether a particular
- /// event is active or not. It is only meant to be used as way of avoiding expensive
- /// computation for logging when logging is not on, therefore it sometimes returns false
- /// positives (but is always accurate when returning false). EventSources are free to
- /// have additional filtering.
- /// </summary>
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- public bool IsEnabled(EventLevel level, EventKeywords keywords)
- {
- return IsEnabled(level, keywords, EventChannel.None);
- }
-
- /// <summary>
- /// Returns true if events with greater than or equal 'level' and have one of 'keywords' set are enabled, or
- /// if 'keywords' specifies a channel bit for a channel that is enabled.
- ///
- /// Note that the result of this function only an approximation on whether a particular
- /// event is active or not. It is only meant to be used as way of avoiding expensive
- /// computation for logging when logging is not on, therefore it sometimes returns false
- /// positives (but is always accurate when returning false). EventSources are free to
- /// have additional filtering.
- /// </summary>
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- public bool IsEnabled(EventLevel level, EventKeywords keywords, EventChannel channel)
- {
- if (!m_eventSourceEnabled)
- return false;
-
- if (!IsEnabledCommon(m_eventSourceEnabled, m_level, m_matchAnyKeyword, level, keywords, channel))
- return false;
-
-#if !FEATURE_ACTIVITYSAMPLING
-
- return true;
-
-#else // FEATURE_ACTIVITYSAMPLING
-
- return true;
-
-#if OPTIMIZE_IS_ENABLED
- //================================================================================
- // 2013/03/06 - The code below is a possible optimization for IsEnabled(level, kwd)
- // in case activity tracing/sampling is enabled. The added complexity of this
- // code however weighs against having it "on" until we know it's really needed.
- // For now we'll have this #ifdef-ed out in case we see evidence this is needed.
- //================================================================================
-
- // At this point we believe the event is enabled, however we now need to check
- // if we filter because of activity
-
- // Optimization, all activity filters also register a delegate here, so if there
- // is no delegate, we know there are no activity filters, which means that there
- // is no additional filtering, which means that we can return true immediately.
- if (s_activityDying == null)
- return true;
-
- // if there's at least one legacy ETW listener we can't filter this
- if (m_legacySessions != null && m_legacySessions.Count > 0)
- return true;
-
- // if any event ID that triggers a new activity, or "transfers" activities
- // is covered by 'keywords' we can't filter this
- if (unchecked(((long)keywords & m_keywordTriggers)) != 0)
- return true;
-
- // See if all listeners have activity filters that would block the event.
- for (int perEventSourceSessionId = 0; perEventSourceSessionId < SessionMask.MAX; ++perEventSourceSessionId)
- {
- EtwSession etwSession = m_etwSessionIdMap[perEventSourceSessionId];
- if (etwSession == null)
- continue;
-
- ActivityFilter activityFilter = etwSession.m_activityFilter;
- if (activityFilter == null ||
- ActivityFilter.GetFilter(activityFilter, this) == null)
- {
- // No activity filter for ETW, if event is active for ETW, we can't filter.
- for (int i = 0; i < m_eventData.Length; i++)
- if (m_eventData[i].EnabledForETW)
- return true;
- }
- else if (ActivityFilter.IsCurrentActivityActive(activityFilter))
- return true;
- }
-
- // for regular event listeners
- var curDispatcher = m_Dispatchers;
- while (curDispatcher != null)
- {
- ActivityFilter activityFilter = curDispatcher.m_Listener.m_activityFilter;
- if (activityFilter == null)
- {
- // See if any event is enabled.
- for (int i = 0; i < curDispatcher.m_EventEnabled.Length; i++)
- if (curDispatcher.m_EventEnabled[i])
- return true;
- }
- else if (ActivityFilter.IsCurrentActivityActive(activityFilter))
- return true;
- curDispatcher = curDispatcher.m_Next;
- }
-
- // Every listener has an activity filter that is blocking writing the event,
- // thus the event is not enabled.
- return false;
-#endif // OPTIMIZE_IS_ENABLED
-
-#endif // FEATURE_ACTIVITYSAMPLING
- }
-
- /// <summary>
- /// Returns the settings for the event source instance
- /// </summary>
- public EventSourceSettings Settings
- {
- get { return m_config; }
- }
-
- // Manifest support
- /// <summary>
- /// Returns the GUID that uniquely identifies the eventSource defined by 'eventSourceType'.
- /// This API allows you to compute this without actually creating an instance of the EventSource.
- /// It only needs to reflect over the type.
- /// </summary>
- public static Guid GetGuid(Type eventSourceType)
- {
- if (eventSourceType == null)
- throw new ArgumentNullException(nameof(eventSourceType));
- Contract.EndContractBlock();
-
- EventSourceAttribute attrib = (EventSourceAttribute)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute));
- string name = eventSourceType.Name;
- if (attrib != null)
- {
- if (attrib.Guid != null)
- {
- Guid g = Guid.Empty;
-#if !ES_BUILD_AGAINST_DOTNET_V35
- if (Guid.TryParse(attrib.Guid, out g))
- return g;
-#else
- try { return new Guid(attrib.Guid); }
- catch (Exception) { }
-#endif
- }
-
- if (attrib.Name != null)
- name = attrib.Name;
- }
-
- if (name == null)
- {
- throw new ArgumentException(Resources.GetResourceString("Argument_InvalidTypeName"), nameof(eventSourceType));
- }
- return GenerateGuidFromName(name.ToUpperInvariant()); // Make it case insensitive.
- }
- /// <summary>
- /// Returns the official ETW Provider name for the eventSource defined by 'eventSourceType'.
- /// This API allows you to compute this without actually creating an instance of the EventSource.
- /// It only needs to reflect over the type.
- /// </summary>
- public static string GetName(Type eventSourceType)
- {
- return GetName(eventSourceType, EventManifestOptions.None);
- }
-
- /// <summary>
- /// Returns a string of the XML manifest associated with the eventSourceType. The scheme for this XML is
- /// documented at in EventManifest Schema http://msdn.microsoft.com/en-us/library/aa384043(VS.85).aspx.
- /// This is the preferred way of generating a manifest to be embedded in the ETW stream as it is fast and
- /// the fact that it only includes localized entries for the current UI culture is an acceptable tradeoff.
- /// </summary>
- /// <param name="eventSourceType">The type of the event source class for which the manifest is generated</param>
- /// <param name="assemblyPathToIncludeInManifest">The manifest XML fragment contains the string name of the DLL name in
- /// which it is embedded. This parameter specifies what name will be used</param>
- /// <returns>The XML data string</returns>
- public static string GenerateManifest(Type eventSourceType, string assemblyPathToIncludeInManifest)
- {
- return GenerateManifest(eventSourceType, assemblyPathToIncludeInManifest, EventManifestOptions.None);
- }
- /// <summary>
- /// Returns a string of the XML manifest associated with the eventSourceType. The scheme for this XML is
- /// documented at in EventManifest Schema http://msdn.microsoft.com/en-us/library/aa384043(VS.85).aspx.
- /// Pass EventManifestOptions.AllCultures when generating a manifest to be registered on the machine. This
- /// ensures that the entries in the event log will be "optimally" localized.
- /// </summary>
- /// <param name="eventSourceType">The type of the event source class for which the manifest is generated</param>
- /// <param name="assemblyPathToIncludeInManifest">The manifest XML fragment contains the string name of the DLL name in
- /// which it is embedded. This parameter specifies what name will be used</param>
- /// <param name="flags">The flags to customize manifest generation. If flags has bit OnlyIfNeededForRegistration specified
- /// this returns null when the eventSourceType does not require explicit registration</param>
- /// <returns>The XML data string or null</returns>
- public static string GenerateManifest(Type eventSourceType, string assemblyPathToIncludeInManifest, EventManifestOptions flags)
- {
- if (eventSourceType == null)
- throw new ArgumentNullException(nameof(eventSourceType));
- Contract.EndContractBlock();
-
- byte[] manifestBytes = EventSource.CreateManifestAndDescriptors(eventSourceType, assemblyPathToIncludeInManifest, null, flags);
- return (manifestBytes == null) ? null : Encoding.UTF8.GetString(manifestBytes, 0, manifestBytes.Length);
- }
-
- // EventListener support
- /// <summary>
- /// returns a list (IEnumerable) of all sources in the appdomain). EventListeners typically need this.
- /// </summary>
- /// <returns></returns>
- public static IEnumerable<EventSource> GetSources()
- {
- var ret = new List<EventSource>();
- lock (EventListener.EventListenersLock)
- {
- foreach (WeakReference eventSourceRef in EventListener.s_EventSources)
- {
- EventSource eventSource = eventSourceRef.Target as EventSource;
- if (eventSource != null && !eventSource.IsDisposed)
- ret.Add(eventSource);
- }
- }
- return ret;
- }
-
- /// <summary>
- /// Send a command to a particular EventSource identified by 'eventSource'.
- /// Calling this routine simply forwards the command to the EventSource.OnEventCommand
- /// callback. What the EventSource does with the command and its arguments are from
- /// that point EventSource-specific.
- /// </summary>
- /// <param name="eventSource">The instance of EventSource to send the command to</param>
- /// <param name="command">A positive user-defined EventCommand, or EventCommand.SendManifest</param>
- /// <param name="commandArguments">A set of (name-argument, value-argument) pairs associated with the command</param>
- public static void SendCommand(EventSource eventSource, EventCommand command, IDictionary<string, string> commandArguments)
- {
- if (eventSource == null)
- throw new ArgumentNullException(nameof(eventSource));
-
- // User-defined EventCommands should not conflict with the reserved commands.
- if ((int)command <= (int)EventCommand.Update && (int)command != (int)EventCommand.SendManifest)
- {
- throw new ArgumentException(Resources.GetResourceString("EventSource_InvalidCommand"), nameof(command));
- }
-
- eventSource.SendCommand(null, 0, 0, command, true, EventLevel.LogAlways, EventKeywords.None, commandArguments);
- }
-
-#if !ES_BUILD_STANDALONE
- /// <summary>
- /// This property allows EventSource code to appropriately handle as "different"
- /// activities started on different threads that have not had an activity created on them.
- /// </summary>
- internal static Guid InternalCurrentThreadActivityId
- {
- get
- {
- Guid retval = CurrentThreadActivityId;
- if (retval == Guid.Empty)
- {
- retval = FallbackActivityId;
- }
- return retval;
- }
- }
-
- internal static Guid FallbackActivityId
- {
- get
- {
-#pragma warning disable 612, 618
- int threadID = AppDomain.GetCurrentThreadId();
-
- // Managed thread IDs are more aggressively re-used than native thread IDs,
- // so we'll use the latter...
- return new Guid(unchecked((uint)threadID),
- unchecked((ushort)s_currentPid), unchecked((ushort)(s_currentPid >> 16)),
- 0x94, 0x1b, 0x87, 0xd5, 0xa6, 0x5c, 0x36, 0x64);
-#pragma warning restore 612, 618
- }
- }
-#endif // !ES_BUILD_STANDALONE
-
- // Error APIs. (We don't throw by default, but you can probe for status)
- /// <summary>
- /// Because
- ///
- /// 1) Logging is often optional and thus should not generate fatal errors (exceptions)
- /// 2) EventSources are often initialized in class constructors (which propagate exceptions poorly)
- ///
- /// The event source constructor does not throw exceptions. Instead we remember any exception that
- /// was generated (it is also logged to Trace.WriteLine).
- /// </summary>
- public Exception ConstructionException { get { return m_constructionException; } }
-
- /// <summary>
- /// EventSources can have arbitrary string key-value pairs associated with them called Traits.
- /// These traits are not interpreted by the EventSource but may be interpreted by EventListeners
- /// (e.g. like the built in ETW listener). These traits are specififed at EventSource
- /// construction time and can be retrieved by using this GetTrait API.
- /// </summary>
- /// <param name="key">The key to look up in the set of key-value pairs passed to the EventSource constructor</param>
- /// <returns>The value string associated iwth key. Will return null if there is no such key.</returns>
- public string GetTrait(string key)
- {
- if (m_traits != null)
- {
- for (int i = 0; i < m_traits.Length - 1; i += 2)
- {
- if (m_traits[i] == key)
- return m_traits[i + 1];
- }
- }
- return null;
- }
-
- /// <summary>
- /// Displays the name and GUID for the eventSource for debugging purposes.
- /// </summary>
- public override string ToString()
- {
- return Resources.GetResourceString("EventSource_ToString", Name, Guid);
- }
-
- /// <summary>
- /// Fires when a Command (e.g. Enable) comes from a an EventListener.
- /// </summary>
- public event EventHandler<EventCommandEventArgs> EventCommandExecuted
- {
- add
- {
- m_eventCommandExecuted += value;
-
- // If we have an EventHandler<EventCommandEventArgs> attached to the EventSource before the first command arrives
- // It should get a chance to handle the deferred commands.
- EventCommandEventArgs deferredCommands = m_deferredCommands;
- while (deferredCommands != null)
- {
- value(this, deferredCommands);
- deferredCommands = deferredCommands.nextCommand;
- }
- }
- remove
- {
- m_eventCommandExecuted -= value;
- }
- }
-
- #region protected
- /// <summary>
- /// This is the constructor that most users will use to create their eventSource. It takes
- /// no parameters. The ETW provider name and GUID of the EventSource are determined by the EventSource
- /// custom attribute (so you can determine these things declaratively). If the GUID for the eventSource
- /// is not specified in the EventSourceAttribute (recommended), it is Generated by hashing the name.
- /// If the ETW provider name of the EventSource is not given, the name of the EventSource class is used as
- /// the ETW provider name.
- /// </summary>
- protected EventSource()
- : this(EventSourceSettings.EtwManifestEventFormat)
- {
- }
-
- /// <summary>
- /// By default calling the 'WriteEvent' methods do NOT throw on errors (they silently discard the event).
- /// This is because in most cases users assume logging is not 'precious' and do NOT wish to have logging failures
- /// crash the program. However for those applications where logging is 'precious' and if it fails the caller
- /// wishes to react, setting 'throwOnEventWriteErrors' will cause an exception to be thrown if WriteEvent
- /// fails. Note the fact that EventWrite succeeds does not necessarily mean that the event reached its destination
- /// only that operation of writing it did not fail. These EventSources will not generate self-describing ETW events.
- ///
- /// For compatibility only use the EventSourceSettings.ThrowOnEventWriteErrors flag instead.
- /// </summary>
- // [Obsolete("Use the EventSource(EventSourceSettings) overload")]
- protected EventSource(bool throwOnEventWriteErrors)
- : this(EventSourceSettings.EtwManifestEventFormat | (throwOnEventWriteErrors ? EventSourceSettings.ThrowOnEventWriteErrors : 0))
- { }
-
- /// <summary>
- /// Construct an EventSource with additional non-default settings (see EventSourceSettings for more)
- /// </summary>
- protected EventSource(EventSourceSettings settings) : this(settings, null) { }
-
- /// <summary>
- /// Construct an EventSource with additional non-default settings.
- ///
- /// Also specify a list of key-value pairs called traits (you must pass an even number of strings).
- /// The first string is the key and the second is the value. These are not interpreted by EventSource
- /// itself but may be interprated the listeners. Can be fetched with GetTrait(string).
- /// </summary>
- /// <param name="settings">See EventSourceSettings for more.</param>
- /// <param name="traits">A collection of key-value strings (must be an even number).</param>
- protected EventSource(EventSourceSettings settings, params string[] traits)
- {
- m_config = ValidateSettings(settings);
-
- Guid eventSourceGuid;
- string eventSourceName;
-
- EventMetadata[] eventDescriptors;
- byte[] manifest;
- GetMetadata(out eventSourceGuid, out eventSourceName, out eventDescriptors, out manifest);
-
- if (eventSourceGuid.Equals(Guid.Empty) || eventSourceName == null)
- {
- var myType = this.GetType();
- eventSourceGuid = GetGuid(myType);
- eventSourceName = GetName(myType);
- }
-
- Initialize(eventSourceGuid, eventSourceName, traits);
- }
-
- internal virtual void GetMetadata(out Guid eventSourceGuid, out string eventSourceName, out EventMetadata[] eventData, out byte[] manifestBytes)
- {
- //
- // In ProjectN subclasses need to override this method, and return the data from their EventSourceAttribute and EventAttribute annotations.
- // On other architectures it is a no-op.
- //
- // eventDescriptors needs to contain one EventDescriptor for each event; the event's ID should be the same as its index in this array.
- // manifestBytes is a UTF-8 encoding of the ETW manifest for the type.
- //
- // This will be implemented by an IL rewriter, so we can't make this method abstract or the initial build of the subclass would fail.
- //
- eventSourceGuid = Guid.Empty;
- eventSourceName = null;
- eventData = null;
- manifestBytes = null;
-
- return;
- }
-
- /// <summary>
- /// This method is called when the eventSource is updated by the controller.
- /// </summary>
- protected virtual void OnEventCommand(EventCommandEventArgs command) { }
-
-#pragma warning disable 1591
- // optimized for common signatures (no args)
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId)
- {
- WriteEventCore(eventId, 0, null);
- }
-
- // optimized for common signatures (ints)
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, int arg1)
- {
- if (m_eventSourceEnabled)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[1];
- descrs[0].DataPointer = (IntPtr)(&arg1);
- descrs[0].Size = 4;
- WriteEventCore(eventId, 1, descrs);
- }
- }
-
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, int arg1, int arg2)
- {
- if (m_eventSourceEnabled)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
- descrs[0].DataPointer = (IntPtr)(&arg1);
- descrs[0].Size = 4;
- descrs[1].DataPointer = (IntPtr)(&arg2);
- descrs[1].Size = 4;
- WriteEventCore(eventId, 2, descrs);
- }
- }
-
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, int arg1, int arg2, int arg3)
- {
- if (m_eventSourceEnabled)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[3];
- descrs[0].DataPointer = (IntPtr)(&arg1);
- descrs[0].Size = 4;
- descrs[1].DataPointer = (IntPtr)(&arg2);
- descrs[1].Size = 4;
- descrs[2].DataPointer = (IntPtr)(&arg3);
- descrs[2].Size = 4;
- WriteEventCore(eventId, 3, descrs);
- }
- }
-
- // optimized for common signatures (longs)
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, long arg1)
- {
- if (m_eventSourceEnabled)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[1];
- descrs[0].DataPointer = (IntPtr)(&arg1);
- descrs[0].Size = 8;
- WriteEventCore(eventId, 1, descrs);
- }
- }
-
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, long arg1, long arg2)
- {
- if (m_eventSourceEnabled)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
- descrs[0].DataPointer = (IntPtr)(&arg1);
- descrs[0].Size = 8;
- descrs[1].DataPointer = (IntPtr)(&arg2);
- descrs[1].Size = 8;
- WriteEventCore(eventId, 2, descrs);
- }
- }
-
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, long arg1, long arg2, long arg3)
- {
- if (m_eventSourceEnabled)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[3];
- descrs[0].DataPointer = (IntPtr)(&arg1);
- descrs[0].Size = 8;
- descrs[1].DataPointer = (IntPtr)(&arg2);
- descrs[1].Size = 8;
- descrs[2].DataPointer = (IntPtr)(&arg3);
- descrs[2].Size = 8;
- WriteEventCore(eventId, 3, descrs);
- }
- }
-
- // optimized for common signatures (strings)
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, string arg1)
- {
- if (m_eventSourceEnabled)
- {
- if (arg1 == null) arg1 = "";
- fixed (char* string1Bytes = arg1)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[1];
- descrs[0].DataPointer = (IntPtr)string1Bytes;
- descrs[0].Size = ((arg1.Length + 1) * 2);
- WriteEventCore(eventId, 1, descrs);
- }
- }
- }
-
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, string arg1, string arg2)
- {
- if (m_eventSourceEnabled)
- {
- if (arg1 == null) arg1 = "";
- if (arg2 == null) arg2 = "";
- fixed (char* string1Bytes = arg1)
- fixed (char* string2Bytes = arg2)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
- descrs[0].DataPointer = (IntPtr)string1Bytes;
- descrs[0].Size = ((arg1.Length + 1) * 2);
- descrs[1].DataPointer = (IntPtr)string2Bytes;
- descrs[1].Size = ((arg2.Length + 1) * 2);
- WriteEventCore(eventId, 2, descrs);
- }
- }
- }
-
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, string arg1, string arg2, string arg3)
- {
- if (m_eventSourceEnabled)
- {
- if (arg1 == null) arg1 = "";
- if (arg2 == null) arg2 = "";
- if (arg3 == null) arg3 = "";
- fixed (char* string1Bytes = arg1)
- fixed (char* string2Bytes = arg2)
- fixed (char* string3Bytes = arg3)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[3];
- descrs[0].DataPointer = (IntPtr)string1Bytes;
- descrs[0].Size = ((arg1.Length + 1) * 2);
- descrs[1].DataPointer = (IntPtr)string2Bytes;
- descrs[1].Size = ((arg2.Length + 1) * 2);
- descrs[2].DataPointer = (IntPtr)string3Bytes;
- descrs[2].Size = ((arg3.Length + 1) * 2);
- WriteEventCore(eventId, 3, descrs);
- }
- }
- }
-
- // optimized for common signatures (string and ints)
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, string arg1, int arg2)
- {
- if (m_eventSourceEnabled)
- {
- if (arg1 == null) arg1 = "";
- fixed (char* string1Bytes = arg1)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
- descrs[0].DataPointer = (IntPtr)string1Bytes;
- descrs[0].Size = ((arg1.Length + 1) * 2);
- descrs[1].DataPointer = (IntPtr)(&arg2);
- descrs[1].Size = 4;
- WriteEventCore(eventId, 2, descrs);
- }
- }
- }
-
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, string arg1, int arg2, int arg3)
- {
- if (m_eventSourceEnabled)
- {
- if (arg1 == null) arg1 = "";
- fixed (char* string1Bytes = arg1)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[3];
- descrs[0].DataPointer = (IntPtr)string1Bytes;
- descrs[0].Size = ((arg1.Length + 1) * 2);
- descrs[1].DataPointer = (IntPtr)(&arg2);
- descrs[1].Size = 4;
- descrs[2].DataPointer = (IntPtr)(&arg3);
- descrs[2].Size = 4;
- WriteEventCore(eventId, 3, descrs);
- }
- }
- }
-
- // optimized for common signatures (string and longs)
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, string arg1, long arg2)
- {
- if (m_eventSourceEnabled)
- {
- if (arg1 == null) arg1 = "";
- fixed (char* string1Bytes = arg1)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
- descrs[0].DataPointer = (IntPtr)string1Bytes;
- descrs[0].Size = ((arg1.Length + 1) * 2);
- descrs[1].DataPointer = (IntPtr)(&arg2);
- descrs[1].Size = 8;
- WriteEventCore(eventId, 2, descrs);
- }
- }
- }
-
- // optimized for common signatures (long and string)
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, long arg1, string arg2)
- {
- if (m_eventSourceEnabled)
- {
- if (arg2 == null) arg2 = "";
- fixed (char* string2Bytes = arg2)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
- descrs[0].DataPointer = (IntPtr)(&arg1);
- descrs[0].Size = 8;
- descrs[1].DataPointer = (IntPtr)string2Bytes;
- descrs[1].Size = ((arg2.Length + 1) * 2);
- WriteEventCore(eventId, 2, descrs);
- }
- }
- }
-
- // optimized for common signatures (int and string)
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, int arg1, string arg2)
- {
- if (m_eventSourceEnabled)
- {
- if (arg2 == null) arg2 = "";
- fixed (char* string2Bytes = arg2)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
- descrs[0].DataPointer = (IntPtr)(&arg1);
- descrs[0].Size = 4;
- descrs[1].DataPointer = (IntPtr)string2Bytes;
- descrs[1].Size = ((arg2.Length + 1) * 2);
- WriteEventCore(eventId, 2, descrs);
- }
- }
- }
-
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, byte[] arg1)
- {
- if (m_eventSourceEnabled)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
- if (arg1 == null || arg1.Length == 0)
- {
- int blobSize = 0;
- descrs[0].DataPointer = (IntPtr)(&blobSize);
- descrs[0].Size = 4;
- descrs[1].DataPointer = (IntPtr)(&blobSize); // valid address instead of empty content
- descrs[1].Size = 0;
- WriteEventCore(eventId, 2, descrs);
- }
- else
- {
- int blobSize = arg1.Length;
- fixed (byte* blob = &arg1[0])
- {
- descrs[0].DataPointer = (IntPtr)(&blobSize);
- descrs[0].Size = 4;
- descrs[1].DataPointer = (IntPtr)blob;
- descrs[1].Size = blobSize;
- WriteEventCore(eventId, 2, descrs);
- }
- }
- }
- }
-
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, long arg1, byte[] arg2)
- {
- if (m_eventSourceEnabled)
- {
- EventSource.EventData* descrs = stackalloc EventSource.EventData[3];
- descrs[0].DataPointer = (IntPtr)(&arg1);
- descrs[0].Size = 8;
- if (arg2 == null || arg2.Length == 0)
- {
- int blobSize = 0;
- descrs[1].DataPointer = (IntPtr)(&blobSize);
- descrs[1].Size = 4;
- descrs[2].DataPointer = (IntPtr)(&blobSize); // valid address instead of empty contents
- descrs[2].Size = 0;
- WriteEventCore(eventId, 3, descrs);
- }
- else
- {
- int blobSize = arg2.Length;
- fixed (byte* blob = &arg2[0])
- {
- descrs[1].DataPointer = (IntPtr)(&blobSize);
- descrs[1].Size = 4;
- descrs[2].DataPointer = (IntPtr)blob;
- descrs[2].Size = blobSize;
- WriteEventCore(eventId, 3, descrs);
- }
- }
- }
- }
-
-#pragma warning restore 1591
-
- /// <summary>
- /// Used to construct the data structure to be passed to the native ETW APIs - EventWrite and EventWriteTransfer.
- /// </summary>
- protected internal struct EventData
- {
- /// <summary>
- /// Address where the one argument lives (if this points to managed memory you must ensure the
- /// managed object is pinned.
- /// </summary>
- public IntPtr DataPointer { get { return (IntPtr)m_Ptr; } set { m_Ptr = unchecked((long)value); } }
- /// <summary>
- /// Size of the argument referenced by DataPointer
- /// </summary>
- public int Size { get { return m_Size; } set { m_Size = value; } }
-
- #region private
- /// <summary>
- /// Initializes the members of this EventData object to point at a previously-pinned
- /// tracelogging-compatible metadata blob.
- /// </summary>
- /// <param name="pointer">Pinned tracelogging-compatible metadata blob.</param>
- /// <param name="size">The size of the metadata blob.</param>
- /// <param name="reserved">Value for reserved: 2 for per-provider metadata, 1 for per-event metadata</param>
- internal unsafe void SetMetadata(byte* pointer, int size, int reserved)
- {
- this.m_Ptr = (long)(ulong)(UIntPtr)pointer;
- this.m_Size = size;
- this.m_Reserved = reserved; // Mark this descriptor as containing tracelogging-compatible metadata.
- }
-
- //Important, we pass this structure directly to the Win32 EventWrite API, so this structure must be layed out exactly
- // the way EventWrite wants it.
- internal long m_Ptr;
- internal int m_Size;
-#pragma warning disable 0649
- internal int m_Reserved; // Used to pad the size to match the Win32 API
-#pragma warning restore 0649
- #endregion
- }
-
- /// <summary>
- /// This routine allows you to create efficient WriteEvent helpers, however the code that you use to
- /// do this, while straightforward, is unsafe.
- /// </summary>
- /// <remarks>
- /// <code>
- /// protected unsafe void WriteEvent(int eventId, string arg1, long arg2)
- /// {
- /// if (IsEnabled())
- /// {
- /// if (arg2 == null) arg2 = "";
- /// fixed (char* string2Bytes = arg2)
- /// {
- /// EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
- /// descrs[0].DataPointer = (IntPtr)(&amp;arg1);
- /// descrs[0].Size = 8;
- /// descrs[1].DataPointer = (IntPtr)string2Bytes;
- /// descrs[1].Size = ((arg2.Length + 1) * 2);
- /// WriteEventCore(eventId, 2, descrs);
- /// }
- /// }
- /// }
- /// </code>
- /// </remarks>
- [CLSCompliant(false)]
- protected unsafe void WriteEventCore(int eventId, int eventDataCount, EventSource.EventData* data)
- {
- WriteEventWithRelatedActivityIdCore(eventId, null, eventDataCount, data);
- }
-
- /// <summary>
- /// This routine allows you to create efficient WriteEventWithRelatedActivityId helpers, however the code
- /// that you use to do this, while straightforward, is unsafe. The only difference from
- /// <see cref="WriteEventCore"/> is that you pass the relatedActivityId from caller through to this API
- /// </summary>
- /// <remarks>
- /// <code>
- /// protected unsafe void WriteEventWithRelatedActivityId(int eventId, Guid relatedActivityId, string arg1, long arg2)
- /// {
- /// if (IsEnabled())
- /// {
- /// if (arg2 == null) arg2 = "";
- /// fixed (char* string2Bytes = arg2)
- /// {
- /// EventSource.EventData* descrs = stackalloc EventSource.EventData[2];
- /// descrs[0].DataPointer = (IntPtr)(&amp;arg1);
- /// descrs[0].Size = 8;
- /// descrs[1].DataPointer = (IntPtr)string2Bytes;
- /// descrs[1].Size = ((arg2.Length + 1) * 2);
- /// WriteEventWithRelatedActivityIdCore(eventId, relatedActivityId, 2, descrs);
- /// }
- /// }
- /// }
- /// </code>
- /// </remarks>
- [CLSCompliant(false)]
- protected unsafe void WriteEventWithRelatedActivityIdCore(int eventId, Guid* relatedActivityId, int eventDataCount, EventSource.EventData* data)
- {
- if (m_eventSourceEnabled)
- {
- try
- {
- Debug.Assert(m_eventData != null); // You must have initialized this if you enabled the source.
- if (relatedActivityId != null)
- ValidateEventOpcodeForTransfer(ref m_eventData[eventId], m_eventData[eventId].Name);
-
- EventOpcode opcode = (EventOpcode)m_eventData[eventId].Descriptor.Opcode;
- EventActivityOptions activityOptions = m_eventData[eventId].ActivityOptions;
- Guid* pActivityId = null;
- Guid activityId = Guid.Empty;
- Guid relActivityId = Guid.Empty;
-
- if (opcode != EventOpcode.Info && relatedActivityId == null &&
- ((activityOptions & EventActivityOptions.Disable) == 0))
- {
- if (opcode == EventOpcode.Start)
- {
- m_activityTracker.OnStart(m_name, m_eventData[eventId].Name, m_eventData[eventId].Descriptor.Task, ref activityId, ref relActivityId, m_eventData[eventId].ActivityOptions);
- }
- else if (opcode == EventOpcode.Stop)
- {
- m_activityTracker.OnStop(m_name, m_eventData[eventId].Name, m_eventData[eventId].Descriptor.Task, ref activityId);
- }
-
- if (activityId != Guid.Empty)
- pActivityId = &activityId;
- if (relActivityId != Guid.Empty)
- relatedActivityId = &relActivityId;
- }
-
-#if FEATURE_MANAGED_ETW
- if (m_eventData[eventId].EnabledForETW)
- {
-
-#if FEATURE_ACTIVITYSAMPLING
- // this code should be kept in sync with WriteEventVarargs().
- SessionMask etwSessions = SessionMask.All;
- // only compute etwSessions if there are *any* ETW filters enabled...
- if ((ulong)m_curLiveSessions != 0)
- etwSessions = GetEtwSessionMask(eventId, relatedActivityId);
- // OutputDebugString(string.Format("{0}.WriteEvent(id {1}) -> to sessions {2:x}",
- // m_name, m_eventData[eventId].Name, (ulong) etwSessions));
-
- if ((ulong)etwSessions != 0 || m_legacySessions != null && m_legacySessions.Count > 0)
- {
- if (!SelfDescribingEvents)
- {
- if (etwSessions.IsEqualOrSupersetOf(m_curLiveSessions))
- {
- // OutputDebugString(string.Format(" (1) id {0}, kwd {1:x}",
- // m_eventData[eventId].Name, m_eventData[eventId].Descriptor.Keywords));
- // by default the Descriptor.Keyword will have the perEventSourceSessionId bit
- // mask set to 0x0f so, when all ETW sessions want the event we don't need to
- // synthesize a new one
- if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, pActivityId, relatedActivityId, eventDataCount, (IntPtr)data))
- ThrowEventSourceException(m_eventData[eventId].Name);
- }
- else
- {
- long origKwd = unchecked((long)((ulong)m_eventData[eventId].Descriptor.Keywords & ~(SessionMask.All.ToEventKeywords())));
- // OutputDebugString(string.Format(" (2) id {0}, kwd {1:x}",
- // m_eventData[eventId].Name, etwSessions.ToEventKeywords() | (ulong) origKwd));
- // only some of the ETW sessions will receive this event. Synthesize a new
- // Descriptor whose Keywords field will have the appropriate bits set.
- // etwSessions might be 0, if there are legacy ETW listeners that want this event
- var desc = new EventDescriptor(
- m_eventData[eventId].Descriptor.EventId,
- m_eventData[eventId].Descriptor.Version,
- m_eventData[eventId].Descriptor.Channel,
- m_eventData[eventId].Descriptor.Level,
- m_eventData[eventId].Descriptor.Opcode,
- m_eventData[eventId].Descriptor.Task,
- unchecked((long)etwSessions.ToEventKeywords() | origKwd));
-
- if (!m_provider.WriteEvent(ref desc, pActivityId, relatedActivityId, eventDataCount, (IntPtr)data))
- ThrowEventSourceException(m_eventData[eventId].Name);
- }
- }
- else
- {
- TraceLoggingEventTypes tlet = m_eventData[eventId].TraceLoggingEventTypes;
- if (tlet == null)
- {
- tlet = new TraceLoggingEventTypes(m_eventData[eventId].Name,
- EventTags.None,
- m_eventData[eventId].Parameters);
- Interlocked.CompareExchange(ref m_eventData[eventId].TraceLoggingEventTypes, tlet, null);
-
- }
- long origKwd = unchecked((long)((ulong)m_eventData[eventId].Descriptor.Keywords & ~(SessionMask.All.ToEventKeywords())));
- // TODO: activity ID support
- EventSourceOptions opt = new EventSourceOptions
- {
- Keywords = (EventKeywords)unchecked((long)etwSessions.ToEventKeywords() | origKwd),
- Level = (EventLevel)m_eventData[eventId].Descriptor.Level,
- Opcode = (EventOpcode)m_eventData[eventId].Descriptor.Opcode
- };
-
- WriteMultiMerge(m_eventData[eventId].Name, ref opt, tlet, pActivityId, relatedActivityId, data);
- }
- }
-#else
- if (!SelfDescribingEvents)
- {
- if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, pActivityId, relatedActivityId, eventDataCount, (IntPtr)data))
- ThrowEventSourceException(m_eventData[eventId].Name);
- }
- else
- {
- TraceLoggingEventTypes tlet = m_eventData[eventId].TraceLoggingEventTypes;
- if (tlet == null)
- {
- tlet = new TraceLoggingEventTypes(m_eventData[eventId].Name,
- m_eventData[eventId].Tags,
- m_eventData[eventId].Parameters);
- Interlocked.CompareExchange(ref m_eventData[eventId].TraceLoggingEventTypes, tlet, null);
-
- }
- EventSourceOptions opt = new EventSourceOptions
- {
- Keywords = (EventKeywords)m_eventData[eventId].Descriptor.Keywords,
- Level = (EventLevel)m_eventData[eventId].Descriptor.Level,
- Opcode = (EventOpcode)m_eventData[eventId].Descriptor.Opcode
- };
-
- WriteMultiMerge(m_eventData[eventId].Name, ref opt, tlet, pActivityId, relatedActivityId, data);
- }
-#endif // FEATURE_ACTIVITYSAMPLING
- }
-#endif // FEATURE_MANAGED_ETW
-
- if (m_Dispatchers != null && m_eventData[eventId].EnabledForAnyListener)
- WriteToAllListeners(eventId, relatedActivityId, eventDataCount, data);
- }
- catch (Exception ex)
- {
- if (ex is EventSourceException)
- throw;
- else
- ThrowEventSourceException(m_eventData[eventId].Name, ex);
- }
- }
- }
-
- // fallback varags helpers.
- /// <summary>
- /// This is the varargs helper for writing an event. It does create an array and box all the arguments so it is
- /// relatively inefficient and should only be used for relatively rare events (e.g. less than 100 / sec). If your
- /// rates are faster than that you should use <see cref="WriteEventCore"/> to create fast helpers for your particular
- /// method signature. Even if you use this for rare events, this call should be guarded by an <see cref="IsEnabled()"/>
- /// check so that the varargs call is not made when the EventSource is not active.
- /// </summary>
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- protected unsafe void WriteEvent(int eventId, params object[] args)
- {
- WriteEventVarargs(eventId, null, args);
- }
-
- /// <summary>
- /// This is the varargs helper for writing an event which also specifies a related activity. It is completely analogous
- /// to corresponding WriteEvent (they share implementation). It does create an array and box all the arguments so it is
- /// relatively inefficient and should only be used for relatively rare events (e.g. less than 100 / sec). If your
- /// rates are faster than that you should use <see cref="WriteEventWithRelatedActivityIdCore"/> to create fast helpers for your
- /// particular method signature. Even if you use this for rare events, this call should be guarded by an <see cref="IsEnabled()"/>
- /// check so that the varargs call is not made when the EventSource is not active.
- /// </summary>
- protected unsafe void WriteEventWithRelatedActivityId(int eventId, Guid relatedActivityId, params object[] args)
- {
- WriteEventVarargs(eventId, &relatedActivityId, args);
- }
-
- #endregion
-
- #region IDisposable Members
- /// <summary>
- /// Disposes of an EventSource.
- /// </summary>
- public void Dispose()
- {
- this.Dispose(true);
- GC.SuppressFinalize(this);
- }
- /// <summary>
- /// Disposes of an EventSource.
- /// </summary>
- /// <remarks>
- /// Called from Dispose() with disposing=true, and from the finalizer (~EventSource) with disposing=false.
- /// Guidelines:
- /// 1. We may be called more than once: do nothing after the first call.
- /// 2. Avoid throwing exceptions if disposing is false, i.e. if we're being finalized.
- /// </remarks>
- /// <param name="disposing">True if called from Dispose(), false if called from the finalizer.</param>
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
-#if FEATURE_MANAGED_ETW
- // Send the manifest one more time to ensure circular buffers have a chance to get to this information
- // even in scenarios with a high volume of ETW events.
- if (m_eventSourceEnabled)
- {
- try
- {
- SendManifest(m_rawManifest);
- }
- catch (Exception)
- { } // If it fails, simply give up.
- m_eventSourceEnabled = false;
- }
- if (m_provider != null)
- {
- m_provider.Dispose();
- m_provider = null;
- }
-#endif
- }
- m_eventSourceEnabled = false;
- m_eventSourceDisposed = true;
- }
- /// <summary>
- /// Finalizer for EventSource
- /// </summary>
- ~EventSource()
- {
- this.Dispose(false);
- }
- #endregion
-
- #region private
-#if FEATURE_ACTIVITYSAMPLING
- internal void WriteStringToListener(EventListener listener, string msg, SessionMask m)
- {
- Debug.Assert(listener == null || (uint)m == (uint)SessionMask.FromId(0));
-
- if (m_eventSourceEnabled)
- {
- if (listener == null)
- {
- WriteEventString(0, unchecked((long)m.ToEventKeywords()), msg);
- }
- else
- {
- EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this);
- eventCallbackArgs.EventId = 0;
- eventCallbackArgs.Message = msg;
- eventCallbackArgs.Payload = new ReadOnlyCollection<object>(new List<object>() { msg });
- eventCallbackArgs.PayloadNames = new ReadOnlyCollection<string>(new List<string> { "message" });
- eventCallbackArgs.EventName = "EventSourceMessage";
- listener.OnEventWritten(eventCallbackArgs);
- }
- }
- }
-#endif
-
- private unsafe void WriteEventRaw(
- string eventName,
- ref EventDescriptor eventDescriptor,
- Guid* activityID,
- Guid* relatedActivityID,
- int dataCount,
- IntPtr data)
- {
-#if FEATURE_MANAGED_ETW
- if (m_provider == null)
- {
- ThrowEventSourceException(eventName);
- }
- else
- {
- if (!m_provider.WriteEventRaw(ref eventDescriptor, activityID, relatedActivityID, dataCount, data))
- ThrowEventSourceException(eventName);
- }
-#endif // FEATURE_MANAGED_ETW
- }
-
- // FrameworkEventSource is on the startup path for the framework, so we have this internal overload that it can use
- // to prevent the working set hit from looking at the custom attributes on the type to get the Guid.
- internal EventSource(Guid eventSourceGuid, string eventSourceName)
- : this(eventSourceGuid, eventSourceName, EventSourceSettings.EtwManifestEventFormat)
- { }
-
- // Used by the internal FrameworkEventSource constructor and the TraceLogging-style event source constructor
- internal EventSource(Guid eventSourceGuid, string eventSourceName, EventSourceSettings settings, string[] traits = null)
- {
- m_config = ValidateSettings(settings);
- Initialize(eventSourceGuid, eventSourceName, traits);
- }
-
- /// <summary>
- /// This method is responsible for the common initialization path from our constructors. It must
- /// not leak any exceptions (otherwise, since most EventSource classes define a static member,
- /// "Log", such an exception would become a cached exception for the initialization of the static
- /// member, and any future access to the "Log" would throw the cached exception).
- /// </summary>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "guid")]
- private unsafe void Initialize(Guid eventSourceGuid, string eventSourceName, string[] traits)
- {
- try
- {
- m_traits = traits;
- if (m_traits != null && m_traits.Length % 2 != 0)
- {
- throw new ArgumentException(Resources.GetResourceString("TraitEven"), nameof(traits));
- }
-
- if (eventSourceGuid == Guid.Empty)
- {
- throw new ArgumentException(Resources.GetResourceString("EventSource_NeedGuid"));
- }
-
- if (eventSourceName == null)
- {
- throw new ArgumentException(Resources.GetResourceString("EventSource_NeedName"));
- }
-
- m_name = eventSourceName;
- m_guid = eventSourceGuid;
-#if FEATURE_ACTIVITYSAMPLING
- m_curLiveSessions = new SessionMask(0);
- m_etwSessionIdMap = new EtwSession[SessionMask.MAX];
-#endif // FEATURE_ACTIVITYSAMPLING
-
- //Enable Implicit Activity tracker
- m_activityTracker = ActivityTracker.Instance;
-
-#if FEATURE_MANAGED_ETW
- // Create and register our provider traits. We do this early because it is needed to log errors
- // In the self-describing event case.
- this.InitializeProviderMetadata();
-
- // Register the provider with ETW
- var provider = new OverideEventProvider(this);
- provider.Register(eventSourceGuid);
-#endif
- // Add the eventSource to the global (weak) list.
- // This also sets m_id, which is the index in the list.
- EventListener.AddEventSource(this);
-
-#if FEATURE_MANAGED_ETW
- // OK if we get this far without an exception, then we can at least write out error messages.
- // Set m_provider, which allows this.
- m_provider = provider;
-
-#if (!ES_BUILD_STANDALONE && !PROJECTN)
- // API available on OS >= Win 8 and patched Win 7.
- // Disable only for FrameworkEventSource to avoid recursion inside exception handling.
- var osVer = Environment.OSVersion.Version.Major * 10 + Environment.OSVersion.Version.Minor;
- if (this.Name != "System.Diagnostics.Eventing.FrameworkEventSource" || osVer >= 62)
-#endif
- {
- int setInformationResult;
- System.Runtime.InteropServices.GCHandle metadataHandle =
- System.Runtime.InteropServices.GCHandle.Alloc(this.providerMetadata, System.Runtime.InteropServices.GCHandleType.Pinned);
- IntPtr providerMetadata = metadataHandle.AddrOfPinnedObject();
-
- setInformationResult = m_provider.SetInformation(
- UnsafeNativeMethods.ManifestEtw.EVENT_INFO_CLASS.SetTraits,
- providerMetadata,
- (uint)this.providerMetadata.Length);
-
- metadataHandle.Free();
- }
-#endif // FEATURE_MANAGED_ETW
-
- Debug.Assert(!m_eventSourceEnabled); // We can't be enabled until we are completely initted.
- // We are logically completely initialized at this point.
- m_completelyInited = true;
- }
- catch (Exception e)
- {
- if (m_constructionException == null)
- m_constructionException = e;
- ReportOutOfBandMessage("ERROR: Exception during construction of EventSource " + Name + ": " + e.Message, true);
- }
-
- // Once m_completelyInited is set, you can have concurrency, so all work is under the lock.
- lock (EventListener.EventListenersLock)
- {
- // If there are any deferred commands, we can do them now.
- // This is the most likely place for exceptions to happen.
- // Note that we are NOT resetting m_deferredCommands to NULL here,
- // We are giving for EventHandler<EventCommandEventArgs> that will be attached later
- EventCommandEventArgs deferredCommands = m_deferredCommands;
- while (deferredCommands != null)
- {
- DoCommand(deferredCommands); // This can never throw, it catches them and reports the errors.
- deferredCommands = deferredCommands.nextCommand;
- }
- }
- }
-
- private static string GetName(Type eventSourceType, EventManifestOptions flags)
- {
- if (eventSourceType == null)
- throw new ArgumentNullException(nameof(eventSourceType));
- Contract.EndContractBlock();
-
- EventSourceAttribute attrib = (EventSourceAttribute)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute), flags);
- if (attrib != null && attrib.Name != null)
- return attrib.Name;
-
- return eventSourceType.Name;
- }
-
- /// <summary>
- /// Implements the SHA1 hashing algorithm. Note that this
- /// implementation is for hashing public information. Do not
- /// use this code to hash private data, as this implementation does
- /// not take any steps to avoid information disclosure.
- /// </summary>
- private struct Sha1ForNonSecretPurposes
- {
- private long length; // Total message length in bits
- private uint[] w; // Workspace
- private int pos; // Length of current chunk in bytes
-
- /// <summary>
- /// Call Start() to initialize the hash object.
- /// </summary>
- public void Start()
- {
- if (this.w == null)
- {
- this.w = new uint[85];
- }
-
- this.length = 0;
- this.pos = 0;
- this.w[80] = 0x67452301;
- this.w[81] = 0xEFCDAB89;
- this.w[82] = 0x98BADCFE;
- this.w[83] = 0x10325476;
- this.w[84] = 0xC3D2E1F0;
- }
-
- /// <summary>
- /// Adds an input byte to the hash.
- /// </summary>
- /// <param name="input">Data to include in the hash.</param>
- public void Append(byte input)
- {
- this.w[this.pos / 4] = (this.w[this.pos / 4] << 8) | input;
- if (64 == ++this.pos)
- {
- this.Drain();
- }
- }
-
- /// <summary>
- /// Adds input bytes to the hash.
- /// </summary>
- /// <param name="input">
- /// Data to include in the hash. Must not be null.
- /// </param>
- public void Append(byte[] input)
- {
- foreach (var b in input)
- {
- this.Append(b);
- }
- }
-
- /// <summary>
- /// Retrieves the hash value.
- /// Note that after calling this function, the hash object should
- /// be considered uninitialized. Subsequent calls to Append or
- /// Finish will produce useless results. Call Start() to
- /// reinitialize.
- /// </summary>
- /// <param name="output">
- /// Buffer to receive the hash value. Must not be null.
- /// Up to 20 bytes of hash will be written to the output buffer.
- /// If the buffer is smaller than 20 bytes, the remaining hash
- /// bytes will be lost. If the buffer is larger than 20 bytes, the
- /// rest of the buffer is left unmodified.
- /// </param>
- public void Finish(byte[] output)
- {
- long l = this.length + 8 * this.pos;
- this.Append(0x80);
- while (this.pos != 56)
- {
- this.Append(0x00);
- }
-
- unchecked
- {
- this.Append((byte)(l >> 56));
- this.Append((byte)(l >> 48));
- this.Append((byte)(l >> 40));
- this.Append((byte)(l >> 32));
- this.Append((byte)(l >> 24));
- this.Append((byte)(l >> 16));
- this.Append((byte)(l >> 8));
- this.Append((byte)l);
-
- int end = output.Length < 20 ? output.Length : 20;
- for (int i = 0; i != end; i++)
- {
- uint temp = this.w[80 + i / 4];
- output[i] = (byte)(temp >> 24);
- this.w[80 + i / 4] = temp << 8;
- }
- }
- }
-
- /// <summary>
- /// Called when this.pos reaches 64.
- /// </summary>
- private void Drain()
- {
- for (int i = 16; i != 80; i++)
- {
- this.w[i] = Rol1((this.w[i - 3] ^ this.w[i - 8] ^ this.w[i - 14] ^ this.w[i - 16]));
- }
-
- unchecked
- {
- uint a = this.w[80];
- uint b = this.w[81];
- uint c = this.w[82];
- uint d = this.w[83];
- uint e = this.w[84];
-
- for (int i = 0; i != 20; i++)
- {
- const uint k = 0x5A827999;
- uint f = (b & c) | ((~b) & d);
- uint temp = Rol5(a) + f + e + k + this.w[i]; e = d; d = c; c = Rol30(b); b = a; a = temp;
- }
-
- for (int i = 20; i != 40; i++)
- {
- uint f = b ^ c ^ d;
- const uint k = 0x6ED9EBA1;
- uint temp = Rol5(a) + f + e + k + this.w[i]; e = d; d = c; c = Rol30(b); b = a; a = temp;
- }
-
- for (int i = 40; i != 60; i++)
- {
- uint f = (b & c) | (b & d) | (c & d);
- const uint k = 0x8F1BBCDC;
- uint temp = Rol5(a) + f + e + k + this.w[i]; e = d; d = c; c = Rol30(b); b = a; a = temp;
- }
-
- for (int i = 60; i != 80; i++)
- {
- uint f = b ^ c ^ d;
- const uint k = 0xCA62C1D6;
- uint temp = Rol5(a) + f + e + k + this.w[i]; e = d; d = c; c = Rol30(b); b = a; a = temp;
- }
-
- this.w[80] += a;
- this.w[81] += b;
- this.w[82] += c;
- this.w[83] += d;
- this.w[84] += e;
- }
-
- this.length += 512; // 64 bytes == 512 bits
- this.pos = 0;
- }
-
- private static uint Rol1(uint input)
- {
- return (input << 1) | (input >> 31);
- }
-
- private static uint Rol5(uint input)
- {
- return (input << 5) | (input >> 27);
- }
-
- private static uint Rol30(uint input)
- {
- return (input << 30) | (input >> 2);
- }
- }
-
- private static Guid GenerateGuidFromName(string name)
- {
- byte[] bytes = Encoding.BigEndianUnicode.GetBytes(name);
- var hash = new Sha1ForNonSecretPurposes();
- hash.Start();
- hash.Append(namespaceBytes);
- hash.Append(bytes);
- Array.Resize(ref bytes, 16);
- hash.Finish(bytes);
-
- bytes[7] = unchecked((byte)((bytes[7] & 0x0F) | 0x50)); // Set high 4 bits of octet 7 to 5, as per RFC 4122
- return new Guid(bytes);
- }
-
- private unsafe object DecodeObject(int eventId, int parameterId, ref EventSource.EventData* data)
- {
- // TODO FIX : We use reflection which in turn uses EventSource, right now we carefully avoid
- // the recursion, but can we do this in a robust way?
-
- IntPtr dataPointer = data->DataPointer;
- // advance to next EventData in array
- ++data;
-
- Type dataType = GetDataType(m_eventData[eventId], parameterId);
-
- Again:
- if (dataType == typeof(IntPtr))
- {
- return *((IntPtr*)dataPointer);
- }
- else if (dataType == typeof(int))
- {
- return *((int*)dataPointer);
- }
- else if (dataType == typeof(uint))
- {
- return *((uint*)dataPointer);
- }
- else if (dataType == typeof(long))
- {
- return *((long*)dataPointer);
- }
- else if (dataType == typeof(ulong))
- {
- return *((ulong*)dataPointer);
- }
- else if (dataType == typeof(byte))
- {
- return *((byte*)dataPointer);
- }
- else if (dataType == typeof(sbyte))
- {
- return *((sbyte*)dataPointer);
- }
- else if (dataType == typeof(short))
- {
- return *((short*)dataPointer);
- }
- else if (dataType == typeof(ushort))
- {
- return *((ushort*)dataPointer);
- }
- else if (dataType == typeof(float))
- {
- return *((float*)dataPointer);
- }
- else if (dataType == typeof(double))
- {
- return *((double*)dataPointer);
- }
- else if (dataType == typeof(decimal))
- {
- return *((decimal*)dataPointer);
- }
- else if (dataType == typeof(bool))
- {
- // The manifest defines a bool as a 32bit type (WIN32 BOOL), not 1 bit as CLR Does.
- if (*((int*)dataPointer) == 1)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- else if (dataType == typeof(Guid))
- {
- return *((Guid*)dataPointer);
- }
- else if (dataType == typeof(char))
- {
- return *((char*)dataPointer);
- }
- else if (dataType == typeof(DateTime))
- {
- long dateTimeTicks = *((long*)dataPointer);
- return DateTime.FromFileTimeUtc(dateTimeTicks);
- }
- else if (dataType == typeof(byte[]))
- {
- // byte[] are written to EventData* as an int followed by a blob
- int cbSize = *((int*)dataPointer);
- byte[] blob = new byte[cbSize];
- dataPointer = data->DataPointer;
- data++;
- for (int i = 0; i < cbSize; ++i)
- blob[i] = *((byte*)(dataPointer + i));
- return blob;
- }
- else if (dataType == typeof(byte*))
- {
- // TODO: how do we want to handle this? For now we ignore it...
- return null;
- }
- else
- {
- if (m_EventSourcePreventRecursion && m_EventSourceInDecodeObject)
- {
- return null;
- }
-
- try
- {
- m_EventSourceInDecodeObject = true;
-
- if (dataType.IsEnum())
- {
- dataType = Enum.GetUnderlyingType(dataType);
- goto Again;
- }
-
-
- // Everything else is marshaled as a string.
- // ETW strings are NULL-terminated, so marshal everything up to the first
- // null in the string.
- return System.Runtime.InteropServices.Marshal.PtrToStringUni(dataPointer);
-
- }
- finally
- {
- m_EventSourceInDecodeObject = false;
- }
- }
- }
-
- // Finds the Dispatcher (which holds the filtering state), for a given dispatcher for the current
- // eventSource).
- private EventDispatcher GetDispatcher(EventListener listener)
- {
- EventDispatcher dispatcher = m_Dispatchers;
- while (dispatcher != null)
- {
- if (dispatcher.m_Listener == listener)
- return dispatcher;
- dispatcher = dispatcher.m_Next;
- }
- return dispatcher;
- }
-
- private unsafe void WriteEventVarargs(int eventId, Guid* childActivityID, object[] args)
- {
- if (m_eventSourceEnabled)
- {
- try
- {
- Debug.Assert(m_eventData != null); // You must have initialized this if you enabled the source.
- if (childActivityID != null)
- {
- ValidateEventOpcodeForTransfer(ref m_eventData[eventId], m_eventData[eventId].Name);
-
- // If you use WriteEventWithRelatedActivityID you MUST declare the first argument to be a GUID
- // with the name 'relatedActivityID, and NOT pass this argument to the WriteEvent method.
- // During manifest creation we modify the ParameterInfo[] that we store to strip out any
- // first parameter that is of type Guid and named "relatedActivityId." Thus, if you call
- // WriteEventWithRelatedActivityID from a method that doesn't name its first parameter correctly
- // we can end up in a state where the ParameterInfo[] doesn't have its first parameter stripped,
- // and this leads to a mismatch between the number of arguments and the number of ParameterInfos,
- // which would cause a cryptic IndexOutOfRangeException later if we don't catch it here.
- if (!m_eventData[eventId].HasRelatedActivityID)
- {
- throw new ArgumentException(Resources.GetResourceString("EventSource_NoRelatedActivityId"));
- }
- }
-
- LogEventArgsMismatches(m_eventData[eventId].Parameters, args);
-
- Guid* pActivityId = null;
- Guid activityId = Guid.Empty;
- Guid relatedActivityId = Guid.Empty;
- EventOpcode opcode = (EventOpcode)m_eventData[eventId].Descriptor.Opcode;
- EventActivityOptions activityOptions = m_eventData[eventId].ActivityOptions;
-
- if (childActivityID == null &&
- ((activityOptions & EventActivityOptions.Disable) == 0))
- {
- if (opcode == EventOpcode.Start)
- {
- m_activityTracker.OnStart(m_name, m_eventData[eventId].Name, m_eventData[eventId].Descriptor.Task, ref activityId, ref relatedActivityId, m_eventData[eventId].ActivityOptions);
- }
- else if (opcode == EventOpcode.Stop)
- {
- m_activityTracker.OnStop(m_name, m_eventData[eventId].Name, m_eventData[eventId].Descriptor.Task, ref activityId);
- }
-
- if (activityId != Guid.Empty)
- pActivityId = &activityId;
- if (relatedActivityId != Guid.Empty)
- childActivityID = &relatedActivityId;
- }
-
-#if FEATURE_MANAGED_ETW
- if (m_eventData[eventId].EnabledForETW)
- {
-#if FEATURE_ACTIVITYSAMPLING
- // this code should be kept in sync with WriteEventWithRelatedActivityIdCore().
- SessionMask etwSessions = SessionMask.All;
- // only compute etwSessions if there are *any* ETW filters enabled...
- if ((ulong)m_curLiveSessions != 0)
- etwSessions = GetEtwSessionMask(eventId, childActivityID);
-
- if ((ulong)etwSessions != 0 || m_legacySessions != null && m_legacySessions.Count > 0)
- {
- if (!SelfDescribingEvents)
- {
- if (etwSessions.IsEqualOrSupersetOf(m_curLiveSessions))
- {
- // by default the Descriptor.Keyword will have the perEventSourceSessionId bit
- // mask set to 0x0f so, when all ETW sessions want the event we don't need to
- // synthesize a new one
- if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, pActivityId, childActivityID, args))
- ThrowEventSourceException(m_eventData[eventId].Name);
- }
- else
- {
- long origKwd = unchecked((long)((ulong)m_eventData[eventId].Descriptor.Keywords & ~(SessionMask.All.ToEventKeywords())));
- // only some of the ETW sessions will receive this event. Synthesize a new
- // Descriptor whose Keywords field will have the appropriate bits set.
- var desc = new EventDescriptor(
- m_eventData[eventId].Descriptor.EventId,
- m_eventData[eventId].Descriptor.Version,
- m_eventData[eventId].Descriptor.Channel,
- m_eventData[eventId].Descriptor.Level,
- m_eventData[eventId].Descriptor.Opcode,
- m_eventData[eventId].Descriptor.Task,
- unchecked((long)etwSessions.ToEventKeywords() | origKwd));
-
- if (!m_provider.WriteEvent(ref desc, pActivityId, childActivityID, args))
- ThrowEventSourceException(m_eventData[eventId].Name);
- }
- }
- else
- {
- TraceLoggingEventTypes tlet = m_eventData[eventId].TraceLoggingEventTypes;
- if (tlet == null)
- {
- tlet = new TraceLoggingEventTypes(m_eventData[eventId].Name,
- EventTags.None,
- m_eventData[eventId].Parameters);
- Interlocked.CompareExchange(ref m_eventData[eventId].TraceLoggingEventTypes, tlet, null);
-
- }
- long origKwd = unchecked((long)((ulong)m_eventData[eventId].Descriptor.Keywords & ~(SessionMask.All.ToEventKeywords())));
- // TODO: activity ID support
- EventSourceOptions opt = new EventSourceOptions
- {
- Keywords = (EventKeywords)unchecked((long)etwSessions.ToEventKeywords() | origKwd),
- Level = (EventLevel)m_eventData[eventId].Descriptor.Level,
- Opcode = (EventOpcode)m_eventData[eventId].Descriptor.Opcode
- };
-
- WriteMultiMerge(m_eventData[eventId].Name, ref opt, tlet, pActivityId, childActivityID, args);
- }
- }
-#else
- if (!SelfDescribingEvents)
- {
- if (!m_provider.WriteEvent(ref m_eventData[eventId].Descriptor, pActivityId, childActivityID, args))
- ThrowEventSourceException(m_eventData[eventId].Name);
- }
- else
- {
- TraceLoggingEventTypes tlet = m_eventData[eventId].TraceLoggingEventTypes;
- if (tlet == null)
- {
- tlet = new TraceLoggingEventTypes(m_eventData[eventId].Name,
- EventTags.None,
- m_eventData[eventId].Parameters);
- Interlocked.CompareExchange(ref m_eventData[eventId].TraceLoggingEventTypes, tlet, null);
-
- }
- // TODO: activity ID support
- EventSourceOptions opt = new EventSourceOptions
- {
- Keywords = (EventKeywords)m_eventData[eventId].Descriptor.Keywords,
- Level = (EventLevel)m_eventData[eventId].Descriptor.Level,
- Opcode = (EventOpcode)m_eventData[eventId].Descriptor.Opcode
- };
-
- WriteMultiMerge(m_eventData[eventId].Name, ref opt, tlet, pActivityId, childActivityID, args);
- }
-#endif // FEATURE_ACTIVITYSAMPLING
- }
-#endif // FEATURE_MANAGED_ETW
- if (m_Dispatchers != null && m_eventData[eventId].EnabledForAnyListener)
- {
-#if (!ES_BUILD_STANDALONE && !PROJECTN)
- // Maintain old behavior - object identity is preserved
- if (AppContextSwitches.PreserveEventListnerObjectIdentity)
- {
- WriteToAllListeners(eventId, childActivityID, args);
- }
- else
-#endif // !ES_BUILD_STANDALONE
- {
- object[] serializedArgs = SerializeEventArgs(eventId, args);
- WriteToAllListeners(eventId, childActivityID, serializedArgs);
- }
- }
- }
- catch (Exception ex)
- {
- if (ex is EventSourceException)
- throw;
- else
- ThrowEventSourceException(m_eventData[eventId].Name, ex);
- }
- }
- }
-
- unsafe private object[] SerializeEventArgs(int eventId, object[] args)
- {
- TraceLoggingEventTypes eventTypes = m_eventData[eventId].TraceLoggingEventTypes;
- if (eventTypes == null)
- {
- eventTypes = new TraceLoggingEventTypes(m_eventData[eventId].Name,
- EventTags.None,
- m_eventData[eventId].Parameters);
- Interlocked.CompareExchange(ref m_eventData[eventId].TraceLoggingEventTypes, eventTypes, null);
- }
- var eventData = new object[eventTypes.typeInfos.Length];
- for (int i = 0; i < eventTypes.typeInfos.Length; i++)
- {
- eventData[i] = eventTypes.typeInfos[i].GetData(args[i]);
- }
- return eventData;
- }
-
- /// <summary>
- /// We expect that the arguments to the Event method and the arguments to WriteEvent match. This function
- /// checks that they in fact match and logs a warning to the debugger if they don't.
- /// </summary>
- /// <param name="infos"></param>
- /// <param name="args"></param>
- private void LogEventArgsMismatches(ParameterInfo[] infos, object[] args)
- {
-#if (!ES_BUILD_PCL && !PROJECTN)
- // It would be nice to have this on PCL builds, but it would be pointless since there isn't support for
- // writing to the debugger log on PCL.
- bool typesMatch = args.Length == infos.Length;
-
- int i = 0;
- while (typesMatch && i < args.Length)
- {
- Type pType = infos[i].ParameterType;
-
- // Checking to see if the Parameter types (from the Event method) match the supplied argument types.
- // Fail if one of two things hold : either the argument type is not equal to the parameter type, or the
- // argument is null and the parameter type is non-nullable.
- if ((args[i] != null && (args[i].GetType() != pType))
- || (args[i] == null && (!(pType.IsGenericType && pType.GetGenericTypeDefinition() == typeof(Nullable<>))))
- )
- {
- typesMatch = false;
- break;
- }
-
- ++i;
- }
-
- if (!typesMatch)
- {
- System.Diagnostics.Debugger.Log(0, null, Resources.GetResourceString("EventSource_VarArgsParameterMismatch") + "\r\n");
- }
-#endif //!ES_BUILD_PCL
- }
-
- private int GetParamLenghtIncludingByteArray(ParameterInfo[] parameters)
- {
- int sum = 0;
- foreach (ParameterInfo info in parameters)
- {
- if (info.ParameterType == typeof(byte[]))
- {
- sum += 2;
- }
- else
- {
- sum++;
- }
- }
-
- return sum;
- }
-
- unsafe private void WriteToAllListeners(int eventId, Guid* childActivityID, int eventDataCount, EventSource.EventData* data)
- {
- // We represent a byte[] as a integer denoting the length and then a blob of bytes in the data pointer. This causes a spurious
- // warning because eventDataCount is off by one for the byte[] case since a byte[] has 2 items associated it. So we want to check
- // that the number of parameters is correct against the byte[] case, but also we the args array would be one too long if
- // we just used the modifiedParamCount here -- so we need both.
- int paramCount = m_eventData[eventId].Parameters.Length;
- int modifiedParamCount = GetParamLenghtIncludingByteArray(m_eventData[eventId].Parameters);
- if (eventDataCount != modifiedParamCount)
- {
- ReportOutOfBandMessage(Resources.GetResourceString("EventSource_EventParametersMismatch", eventId, eventDataCount, paramCount), true);
- paramCount = Math.Min(paramCount, eventDataCount);
- }
-
- object[] args = new object[paramCount];
-
- EventSource.EventData* dataPtr = data;
- for (int i = 0; i < paramCount; i++)
- args[i] = DecodeObject(eventId, i, ref dataPtr);
- WriteToAllListeners(eventId, childActivityID, args);
- }
-
- // helper for writing to all EventListeners attached the current eventSource.
- unsafe private void WriteToAllListeners(int eventId, Guid* childActivityID, params object[] args)
- {
- EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this);
- eventCallbackArgs.EventId = eventId;
- if (childActivityID != null)
- eventCallbackArgs.RelatedActivityId = *childActivityID;
- eventCallbackArgs.EventName = m_eventData[eventId].Name;
- eventCallbackArgs.Message = m_eventData[eventId].Message;
- eventCallbackArgs.Payload = new ReadOnlyCollection<object>(args);
-
- DispatchToAllListeners(eventId, childActivityID, eventCallbackArgs);
- }
-
- private unsafe void DispatchToAllListeners(int eventId, Guid* childActivityID, EventWrittenEventArgs eventCallbackArgs)
- {
- Exception lastThrownException = null;
- for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next)
- {
- Debug.Assert(dispatcher.m_EventEnabled != null);
- if (eventId == -1 || dispatcher.m_EventEnabled[eventId])
- {
-#if FEATURE_ACTIVITYSAMPLING
- var activityFilter = dispatcher.m_Listener.m_activityFilter;
- // order below is important as PassesActivityFilter will "flow" active activities
- // even when the current EventSource doesn't have filtering enabled. This allows
- // interesting activities to be updated so that sources that do sample can get
- // accurate data
- if (activityFilter == null ||
- ActivityFilter.PassesActivityFilter(activityFilter, childActivityID,
- m_eventData[eventId].TriggersActivityTracking > 0,
- this, eventId) ||
- !dispatcher.m_activityFilteringEnabled)
-#endif // FEATURE_ACTIVITYSAMPLING
- {
- try
- {
- dispatcher.m_Listener.OnEventWritten(eventCallbackArgs);
- }
- catch (Exception e)
- {
- ReportOutOfBandMessage("ERROR: Exception during EventSource.OnEventWritten: "
- + e.Message, false);
- lastThrownException = e;
- }
- }
- }
- }
-
- if (lastThrownException != null)
- {
- throw new EventSourceException(lastThrownException);
- }
- }
-
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- private unsafe void WriteEventString(EventLevel level, long keywords, string msgString)
- {
-#if FEATURE_MANAGED_ETW
- if (m_provider != null)
- {
- string eventName = "EventSourceMessage";
- if (SelfDescribingEvents)
- {
- EventSourceOptions opt = new EventSourceOptions
- {
- Keywords = (EventKeywords)unchecked(keywords),
- Level = level
- };
- var msg = new { message = msgString };
- var tlet = new TraceLoggingEventTypes(eventName, EventTags.None, new Type[] { msg.GetType() });
- WriteMultiMergeInner(eventName, ref opt, tlet, null, null, msg);
- }
- else
- {
- // We want the name of the provider to show up so if we don't have a manifest we create
- // on that at least has the provider name (I don't define any events).
- if (m_rawManifest == null && m_outOfBandMessageCount == 1)
- {
- ManifestBuilder manifestBuilder = new ManifestBuilder(Name, Guid, Name, null, EventManifestOptions.None);
- manifestBuilder.StartEvent(eventName, new EventAttribute(0) { Level = EventLevel.LogAlways, Task = (EventTask)0xFFFE });
- manifestBuilder.AddEventParameter(typeof(string), "message");
- manifestBuilder.EndEvent();
- SendManifest(manifestBuilder.CreateManifest());
- }
-
- // We use this low level routine to to bypass the enabled checking, since the eventSource itself is only partially inited.
- fixed (char* msgStringPtr = msgString)
- {
- EventDescriptor descr = new EventDescriptor(0, 0, 0, (byte)level, 0, 0, keywords);
- EventProvider.EventData data = new EventProvider.EventData();
- data.Ptr = (ulong)msgStringPtr;
- data.Size = (uint)(2 * (msgString.Length + 1));
- data.Reserved = 0;
- m_provider.WriteEvent(ref descr, null, null, 1, (IntPtr)((void*)&data));
- }
- }
- }
-#endif // FEATURE_MANAGED_ETW
- }
-
- /// <summary>
- /// Since this is a means of reporting errors (see ReportoutOfBandMessage) any failure encountered
- /// while writing the message to any one of the listeners will be silently ignored.
- /// </summary>
- private void WriteStringToAllListeners(string eventName, string msg)
- {
- EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this);
- eventCallbackArgs.EventId = 0;
- eventCallbackArgs.Message = msg;
- eventCallbackArgs.Payload = new ReadOnlyCollection<object>(new List<object>() { msg });
- eventCallbackArgs.PayloadNames = new ReadOnlyCollection<string>(new List<string> { "message" });
- eventCallbackArgs.EventName = eventName;
-
- for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next)
- {
- bool dispatcherEnabled = false;
- if (dispatcher.m_EventEnabled == null)
- {
- // if the listeners that weren't correctly initialized, we will send to it
- // since this is an error message and we want to see it go out.
- dispatcherEnabled = true;
- }
- else
- {
- // if there's *any* enabled event on the dispatcher we'll write out the string
- // otherwise we'll treat the listener as disabled and skip it
- for (int evtId = 0; evtId < dispatcher.m_EventEnabled.Length; ++evtId)
- {
- if (dispatcher.m_EventEnabled[evtId])
- {
- dispatcherEnabled = true;
- break;
- }
- }
- }
- try
- {
- if (dispatcherEnabled)
- dispatcher.m_Listener.OnEventWritten(eventCallbackArgs);
- }
- catch
- {
- // ignore any exceptions thrown by listeners' OnEventWritten
- }
- }
- }
-
-#if FEATURE_ACTIVITYSAMPLING
- unsafe private SessionMask GetEtwSessionMask(int eventId, Guid* childActivityID)
- {
- SessionMask etwSessions = new SessionMask();
-
- for (int i = 0; i < SessionMask.MAX; ++i)
- {
- EtwSession etwSession = m_etwSessionIdMap[i];
- if (etwSession != null)
- {
- ActivityFilter activityFilter = etwSession.m_activityFilter;
- // PassesActivityFilter() will flow "interesting" activities, so make sure
- // to perform this test first, before ORing with ~m_activityFilteringForETWEnabled
- // (note: the first test for !m_activityFilteringForETWEnabled[i] ensures we
- // do not fire events indiscriminately, when no filters are specified, but only
- // if, in addition, the session did not also enable ActivitySampling)
- if (activityFilter == null && !m_activityFilteringForETWEnabled[i] ||
- activityFilter != null &&
- ActivityFilter.PassesActivityFilter(activityFilter, childActivityID,
- m_eventData[eventId].TriggersActivityTracking > 0, this, eventId) ||
- !m_activityFilteringForETWEnabled[i])
- {
- etwSessions[i] = true;
- }
- }
- }
- // flow "interesting" activities for all legacy sessions in which there's some
- // level of activity tracing enabled (even other EventSources)
- if (m_legacySessions != null && m_legacySessions.Count > 0 &&
- (EventOpcode)m_eventData[eventId].Descriptor.Opcode == EventOpcode.Send)
- {
- // only calculate InternalCurrentThreadActivityId once
- Guid* pCurrentActivityId = null;
- Guid currentActivityId;
- foreach (var legacyEtwSession in m_legacySessions)
- {
- if (legacyEtwSession == null)
- continue;
-
- ActivityFilter activityFilter = legacyEtwSession.m_activityFilter;
- if (activityFilter != null)
- {
- if (pCurrentActivityId == null)
- {
- currentActivityId = InternalCurrentThreadActivityId;
- pCurrentActivityId = &currentActivityId;
- }
- ActivityFilter.FlowActivityIfNeeded(activityFilter, pCurrentActivityId, childActivityID);
- }
- }
- }
-
- return etwSessions;
- }
-#endif // FEATURE_ACTIVITYSAMPLING
-
- /// <summary>
- /// Returns true if 'eventNum' is enabled if you only consider the level and matchAnyKeyword filters.
- /// It is possible that eventSources turn off the event based on additional filtering criteria.
- /// </summary>
- private bool IsEnabledByDefault(int eventNum, bool enable, EventLevel currentLevel, EventKeywords currentMatchAnyKeyword)
- {
- if (!enable)
- return false;
-
- EventLevel eventLevel = (EventLevel)m_eventData[eventNum].Descriptor.Level;
- EventKeywords eventKeywords = unchecked((EventKeywords)((ulong)m_eventData[eventNum].Descriptor.Keywords & (~(SessionMask.All.ToEventKeywords()))));
-
-#if FEATURE_MANAGED_ETW_CHANNELS
- EventChannel channel = unchecked((EventChannel)m_eventData[eventNum].Descriptor.Channel);
-#else
- EventChannel channel = EventChannel.None;
-#endif
-
- return IsEnabledCommon(enable, currentLevel, currentMatchAnyKeyword, eventLevel, eventKeywords, channel);
- }
-
- private bool IsEnabledCommon(bool enabled, EventLevel currentLevel, EventKeywords currentMatchAnyKeyword,
- EventLevel eventLevel, EventKeywords eventKeywords, EventChannel eventChannel)
- {
- if (!enabled)
- return false;
-
- // does is pass the level test?
- if ((currentLevel != 0) && (currentLevel < eventLevel))
- return false;
-
- // if yes, does it pass the keywords test?
- if (currentMatchAnyKeyword != 0 && eventKeywords != 0)
- {
-#if FEATURE_MANAGED_ETW_CHANNELS
- // is there a channel with keywords that match currentMatchAnyKeyword?
- if (eventChannel != EventChannel.None && this.m_channelData != null && this.m_channelData.Length > (int)eventChannel)
- {
- EventKeywords channel_keywords = unchecked((EventKeywords)(m_channelData[(int)eventChannel] | (ulong)eventKeywords));
- if (channel_keywords != 0 && (channel_keywords & currentMatchAnyKeyword) == 0)
- return false;
- }
- else
-#endif
- {
- if ((unchecked((ulong)eventKeywords & (ulong)currentMatchAnyKeyword)) == 0)
- return false;
- }
- }
- return true;
-
- }
- [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
- private void ThrowEventSourceException(string eventName, Exception innerEx = null)
- {
- // If we fail during out of band logging we may end up trying
- // to throw another EventSourceException, thus hitting a StackOverflowException.
- // Avoid StackOverflow by making sure we do not recursively call this method.
- if (m_EventSourceExceptionRecurenceCount > 0)
- return;
- try
- {
- m_EventSourceExceptionRecurenceCount++;
-
- string errorPrefix = "EventSourceException";
- if (eventName != null)
- {
- errorPrefix += " while processing event \"" + eventName + "\"";
- }
-
- // TODO Create variations of EventSourceException that indicate more information using the error code.
- switch (EventProvider.GetLastWriteEventError())
- {
- case EventProvider.WriteEventErrorCode.EventTooBig:
- ReportOutOfBandMessage(errorPrefix + ": " + Resources.GetResourceString("EventSource_EventTooBig"), true);
- if (ThrowOnEventWriteErrors) throw new EventSourceException(Resources.GetResourceString("EventSource_EventTooBig"), innerEx);
- break;
- case EventProvider.WriteEventErrorCode.NoFreeBuffers:
- ReportOutOfBandMessage(errorPrefix + ": " + Resources.GetResourceString("EventSource_NoFreeBuffers"), true);
- if (ThrowOnEventWriteErrors) throw new EventSourceException(Resources.GetResourceString("EventSource_NoFreeBuffers"), innerEx);
- break;
- case EventProvider.WriteEventErrorCode.NullInput:
- ReportOutOfBandMessage(errorPrefix + ": " + Resources.GetResourceString("EventSource_NullInput"), true);
- if (ThrowOnEventWriteErrors) throw new EventSourceException(Resources.GetResourceString("EventSource_NullInput"), innerEx);
- break;
- case EventProvider.WriteEventErrorCode.TooManyArgs:
- ReportOutOfBandMessage(errorPrefix + ": " + Resources.GetResourceString("EventSource_TooManyArgs"), true);
- if (ThrowOnEventWriteErrors) throw new EventSourceException(Resources.GetResourceString("EventSource_TooManyArgs"), innerEx);
- break;
- default:
- if (innerEx != null)
- ReportOutOfBandMessage(errorPrefix + ": " + innerEx.GetType() + ":" + innerEx.Message, true);
- else
- ReportOutOfBandMessage(errorPrefix, true);
- if (ThrowOnEventWriteErrors) throw new EventSourceException(innerEx);
- break;
- }
- }
- finally
- {
- m_EventSourceExceptionRecurenceCount--;
- }
- }
-
- private void ValidateEventOpcodeForTransfer(ref EventMetadata eventData, string eventName)
- {
- if ((EventOpcode)eventData.Descriptor.Opcode != EventOpcode.Send &&
- (EventOpcode)eventData.Descriptor.Opcode != EventOpcode.Receive &&
- (EventOpcode)eventData.Descriptor.Opcode != EventOpcode.Start)
- {
- ThrowEventSourceException(eventName);
- }
- }
-
- internal static EventOpcode GetOpcodeWithDefault(EventOpcode opcode, string eventName)
- {
- if (opcode == EventOpcode.Info && eventName != null)
- {
- if (eventName.EndsWith(s_ActivityStartSuffix, StringComparison.Ordinal))
- {
- return EventOpcode.Start;
- }
- else if (eventName.EndsWith(s_ActivityStopSuffix, StringComparison.Ordinal))
- {
- return EventOpcode.Stop;
- }
- }
-
- return opcode;
- }
-
-#if FEATURE_MANAGED_ETW
- /// <summary>
- /// This class lets us hook the 'OnEventCommand' from the eventSource.
- /// </summary>
- private class OverideEventProvider : EventProvider
- {
- public OverideEventProvider(EventSource eventSource)
- {
- this.m_eventSource = eventSource;
- }
- protected override void OnControllerCommand(ControllerCommand command, IDictionary<string, string> arguments,
- int perEventSourceSessionId, int etwSessionId)
- {
- // We use null to represent the ETW EventListener.
- EventListener listener = null;
- m_eventSource.SendCommand(listener, perEventSourceSessionId, etwSessionId,
- (EventCommand)command, IsEnabled(), Level, MatchAnyKeyword, arguments);
- }
- private EventSource m_eventSource;
- }
-#endif
-
- /// <summary>
- /// Used to hold all the static information about an event. This includes everything in the event
- /// descriptor as well as some stuff we added specifically for EventSource. see the
- /// code:m_eventData for where we use this.
- /// </summary>
- internal partial struct EventMetadata
- {
- public EventDescriptor Descriptor;
- public EventTags Tags;
- public bool EnabledForAnyListener; // true if any dispatcher has this event turned on
- public bool EnabledForETW; // is this event on for the OS ETW data dispatcher?
-
- public bool HasRelatedActivityID; // Set if the event method's first parameter is a Guid named 'relatedActivityId'
-#if !FEATURE_ACTIVITYSAMPLING
-#pragma warning disable 0649
-#endif
- public byte TriggersActivityTracking; // count of listeners that marked this event as trigger for start of activity logging.
-#if !FEATURE_ACTIVITYSAMPLING
-#pragma warning restore 0649
-#endif
- public string Name; // the name of the event
- public string Message; // If the event has a message associated with it, this is it.
- public ParameterInfo[] Parameters; // TODO can we remove?
-
- public TraceLoggingEventTypes TraceLoggingEventTypes;
- public EventActivityOptions ActivityOptions;
-
-#if PROJECTN
- public EventParameterType[] ParameterTypes;
-#endif
- };
-
- // This is the internal entry point that code:EventListeners call when wanting to send a command to a
- // eventSource. The logic is as follows
- //
- // * if Command == Update
- // * perEventSourceSessionId specifies the per-provider ETW session ID that the command applies
- // to (if listener != null)
- // perEventSourceSessionId = 0 - reserved for EventListeners
- // perEventSourceSessionId = 1..SessionMask.MAX - reserved for activity tracing aware ETW sessions
- // perEventSourceSessionId-1 represents the bit in the reserved field (bits 44..47) in
- // Keywords that identifies the session
- // perEventSourceSessionId = SessionMask.MAX+1 - reserved for legacy ETW sessions; these are
- // discriminated by etwSessionId
- // * etwSessionId specifies a machine-wide ETW session ID; this allows correlation of
- // activity tracing across different providers (which might have different sessionIds
- // for the same ETW session)
- // * enable, level, matchAnyKeywords are used to set a default for all events for the
- // eventSource. In particular, if 'enabled' is false, 'level' and
- // 'matchAnyKeywords' are not used.
- // * OnEventCommand is invoked, which may cause calls to
- // code:EventSource.EnableEventForDispatcher which may cause changes in the filtering
- // depending on the logic in that routine.
- // * else (command != Update)
- // * Simply call OnEventCommand. The expectation is that filtering is NOT changed.
- // * The 'enabled' 'level', matchAnyKeyword' arguments are ignored (must be true, 0, 0).
- //
- // dispatcher == null has special meaning. It is the 'ETW' dispatcher.
- internal void SendCommand(EventListener listener, int perEventSourceSessionId, int etwSessionId,
- EventCommand command, bool enable,
- EventLevel level, EventKeywords matchAnyKeyword,
- IDictionary<string, string> commandArguments)
- {
- var commandArgs = new EventCommandEventArgs(command, commandArguments, this, listener, perEventSourceSessionId, etwSessionId, enable, level, matchAnyKeyword);
- lock (EventListener.EventListenersLock)
- {
- if (m_completelyInited)
- {
- // After the first command arrive after construction, we are ready to get rid of the deferred commands
- this.m_deferredCommands = null;
- // We are fully initialized, do the command
- DoCommand(commandArgs);
- }
- else
- {
- // We can't do the command, simply remember it and we do it when we are fully constructed.
- commandArgs.nextCommand = m_deferredCommands;
- m_deferredCommands = commandArgs;
- }
- }
- }
-
- /// <summary>
- /// We want the eventSource to be fully initialized when we do commands because that way we can send
- /// error messages and other logging directly to the event stream. Unfortunately we can get callbacks
- /// when we are not fully initialized. In that case we store them in 'commandArgs' and do them later.
- /// This helper actually does all actual command logic.
- /// </summary>
- internal void DoCommand(EventCommandEventArgs commandArgs)
- {
- // PRECONDITION: We should be holding the EventListener.EventListenersLock
- // We defer commands until we are completely inited. This allows error messages to be sent.
- Debug.Assert(m_completelyInited);
-
-#if FEATURE_MANAGED_ETW
- if (m_provider == null) // If we failed to construct
- return;
-#endif // FEATURE_MANAGED_ETW
-
- m_outOfBandMessageCount = 0;
- bool shouldReport = (commandArgs.perEventSourceSessionId > 0) && (commandArgs.perEventSourceSessionId <= SessionMask.MAX);
- try
- {
- EnsureDescriptorsInitialized();
- Debug.Assert(m_eventData != null);
-
- // Find the per-EventSource dispatcher corresponding to registered dispatcher
- commandArgs.dispatcher = GetDispatcher(commandArgs.listener);
- if (commandArgs.dispatcher == null && commandArgs.listener != null) // dispatcher == null means ETW dispatcher
- {
- throw new ArgumentException(Resources.GetResourceString("EventSource_ListenerNotFound"));
- }
-
- if (commandArgs.Arguments == null)
- commandArgs.Arguments = new Dictionary<string, string>();
-
- if (commandArgs.Command == EventCommand.Update)
- {
- // Set it up using the 'standard' filtering bitfields (use the "global" enable, not session specific one)
- for (int i = 0; i < m_eventData.Length; i++)
- EnableEventForDispatcher(commandArgs.dispatcher, i, IsEnabledByDefault(i, commandArgs.enable, commandArgs.level, commandArgs.matchAnyKeyword));
-
- if (commandArgs.enable)
- {
- if (!m_eventSourceEnabled)
- {
- // EventSource turned on for the first time, simply copy the bits.
- m_level = commandArgs.level;
- m_matchAnyKeyword = commandArgs.matchAnyKeyword;
- }
- else
- {
- // Already enabled, make it the most verbose of the existing and new filter
- if (commandArgs.level > m_level)
- m_level = commandArgs.level;
- if (commandArgs.matchAnyKeyword == 0)
- m_matchAnyKeyword = 0;
- else if (m_matchAnyKeyword != 0)
- m_matchAnyKeyword = unchecked(m_matchAnyKeyword | commandArgs.matchAnyKeyword);
- }
- }
-
- // interpret perEventSourceSessionId's sign, and adjust perEventSourceSessionId to
- // represent 0-based positive values
- bool bSessionEnable = (commandArgs.perEventSourceSessionId >= 0);
- if (commandArgs.perEventSourceSessionId == 0 && commandArgs.enable == false)
- bSessionEnable = false;
-
- if (commandArgs.listener == null)
- {
- if (!bSessionEnable)
- commandArgs.perEventSourceSessionId = -commandArgs.perEventSourceSessionId;
- // for "global" enable/disable (passed in with listener == null and
- // perEventSourceSessionId == 0) perEventSourceSessionId becomes -1
- --commandArgs.perEventSourceSessionId;
- }
-
- commandArgs.Command = bSessionEnable ? EventCommand.Enable : EventCommand.Disable;
-
- // perEventSourceSessionId = -1 when ETW sent a notification, but the set of active sessions
- // hasn't changed.
- // sesisonId = SessionMask.MAX when one of the legacy ETW sessions changed
- // 0 <= perEventSourceSessionId < SessionMask.MAX for activity-tracing aware sessions
- Debug.Assert(commandArgs.perEventSourceSessionId >= -1 && commandArgs.perEventSourceSessionId <= SessionMask.MAX);
-
- // Send the manifest if we are enabling an ETW session
- if (bSessionEnable && commandArgs.dispatcher == null)
- {
- // eventSourceDispatcher == null means this is the ETW manifest
-
- // Note that we unconditionally send the manifest whenever we are enabled, even if
- // we were already enabled. This is because there may be multiple sessions active
- // and we can't know that all the sessions have seen the manifest.
- if (!SelfDescribingEvents)
- SendManifest(m_rawManifest);
- }
-
-#if FEATURE_ACTIVITYSAMPLING
- if (bSessionEnable && commandArgs.perEventSourceSessionId != -1)
- {
- bool participateInSampling = false;
- string activityFilters;
- int sessionIdBit;
-
- ParseCommandArgs(commandArgs.Arguments, out participateInSampling,
- out activityFilters, out sessionIdBit);
-
- if (commandArgs.listener == null && commandArgs.Arguments.Count > 0 && commandArgs.perEventSourceSessionId != sessionIdBit)
- {
- throw new ArgumentException(Resources.GetResourceString("EventSource_SessionIdError",
- commandArgs.perEventSourceSessionId + SessionMask.SHIFT_SESSION_TO_KEYWORD,
- sessionIdBit + SessionMask.SHIFT_SESSION_TO_KEYWORD));
- }
-
- if (commandArgs.listener == null)
- {
- UpdateEtwSession(commandArgs.perEventSourceSessionId, commandArgs.etwSessionId, true, activityFilters, participateInSampling);
- }
- else
- {
- ActivityFilter.UpdateFilter(ref commandArgs.listener.m_activityFilter, this, 0, activityFilters);
- commandArgs.dispatcher.m_activityFilteringEnabled = participateInSampling;
- }
- }
- else if (!bSessionEnable && commandArgs.listener == null)
- {
- // if we disable an ETW session, indicate that in a synthesized command argument
- if (commandArgs.perEventSourceSessionId >= 0 && commandArgs.perEventSourceSessionId < SessionMask.MAX)
- {
- commandArgs.Arguments["EtwSessionKeyword"] = (commandArgs.perEventSourceSessionId + SessionMask.SHIFT_SESSION_TO_KEYWORD).ToString(CultureInfo.InvariantCulture);
- }
- }
-#endif // FEATURE_ACTIVITYSAMPLING
-
- // Turn on the enable bit before making the OnEventCommand callback This allows you to do useful
- // things like log messages, or test if keywords are enabled in the callback.
- if (commandArgs.enable)
- {
- Debug.Assert(m_eventData != null);
- m_eventSourceEnabled = true;
- }
-
- this.OnEventCommand(commandArgs);
- var eventCommandCallback = this.m_eventCommandExecuted;
- if (eventCommandCallback != null)
- eventCommandCallback(this, commandArgs);
-
-#if FEATURE_ACTIVITYSAMPLING
- if (commandArgs.listener == null && !bSessionEnable && commandArgs.perEventSourceSessionId != -1)
- {
- // if we disable an ETW session, complete disabling it
- UpdateEtwSession(commandArgs.perEventSourceSessionId, commandArgs.etwSessionId, false, null, false);
- }
-#endif // FEATURE_ACTIVITYSAMPLING
-
- if (!commandArgs.enable)
- {
- // If we are disabling, maybe we can turn on 'quick checks' to filter
- // quickly. These are all just optimizations (since later checks will still filter)
-
-#if FEATURE_ACTIVITYSAMPLING
- // Turn off (and forget) any information about Activity Tracing.
- if (commandArgs.listener == null)
- {
- // reset all filtering information for activity-tracing-aware sessions
- for (int i = 0; i < SessionMask.MAX; ++i)
- {
- EtwSession etwSession = m_etwSessionIdMap[i];
- if (etwSession != null)
- ActivityFilter.DisableFilter(ref etwSession.m_activityFilter, this);
- }
- m_activityFilteringForETWEnabled = new SessionMask(0);
- m_curLiveSessions = new SessionMask(0);
- // reset activity-tracing-aware sessions
- if (m_etwSessionIdMap != null)
- for (int i = 0; i < SessionMask.MAX; ++i)
- m_etwSessionIdMap[i] = null;
- // reset legacy sessions
- if (m_legacySessions != null)
- m_legacySessions.Clear();
- }
- else
- {
- ActivityFilter.DisableFilter(ref commandArgs.listener.m_activityFilter, this);
- commandArgs.dispatcher.m_activityFilteringEnabled = false;
- }
-#endif // FEATURE_ACTIVITYSAMPLING
-
- // There is a good chance EnabledForAnyListener are not as accurate as
- // they could be, go ahead and get a better estimate.
- for (int i = 0; i < m_eventData.Length; i++)
- {
- bool isEnabledForAnyListener = false;
- for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next)
- {
- if (dispatcher.m_EventEnabled[i])
- {
- isEnabledForAnyListener = true;
- break;
- }
- }
- m_eventData[i].EnabledForAnyListener = isEnabledForAnyListener;
- }
-
- // If no events are enabled, disable the global enabled bit.
- if (!AnyEventEnabled())
- {
- m_level = 0;
- m_matchAnyKeyword = 0;
- m_eventSourceEnabled = false;
- }
- }
-#if FEATURE_ACTIVITYSAMPLING
- UpdateKwdTriggers(commandArgs.enable);
-#endif // FEATURE_ACTIVITYSAMPLING
- }
- else
- {
- if (commandArgs.Command == EventCommand.SendManifest)
- {
- // TODO: should we generate the manifest here if we hadn't already?
- if (m_rawManifest != null)
- SendManifest(m_rawManifest);
- }
-
- // These are not used for non-update commands and thus should always be 'default' values
- // Debug.Assert(enable == true);
- // Debug.Assert(level == EventLevel.LogAlways);
- // Debug.Assert(matchAnyKeyword == EventKeywords.None);
-
- this.OnEventCommand(commandArgs);
- var eventCommandCallback = m_eventCommandExecuted;
- if (eventCommandCallback != null)
- eventCommandCallback(this, commandArgs);
- }
-
-#if FEATURE_ACTIVITYSAMPLING
- if (m_completelyInited && (commandArgs.listener != null || shouldReport))
- {
- SessionMask m = SessionMask.FromId(commandArgs.perEventSourceSessionId);
- ReportActivitySamplingInfo(commandArgs.listener, m);
- }
-#endif // FEATURE_ACTIVITYSAMPLING
- }
- catch (Exception e)
- {
- // When the ETW session is created after the EventSource has registered with the ETW system
- // we can send any error messages here.
- ReportOutOfBandMessage("ERROR: Exception in Command Processing for EventSource " + Name + ": " + e.Message, true);
- // We never throw when doing a command.
- }
- }
-
-#if FEATURE_ACTIVITYSAMPLING
-
- internal void UpdateEtwSession(
- int sessionIdBit,
- int etwSessionId,
- bool bEnable,
- string activityFilters,
- bool participateInSampling)
- {
- if (sessionIdBit < SessionMask.MAX)
- {
- // activity-tracing-aware etw session
- if (bEnable)
- {
- var etwSession = EtwSession.GetEtwSession(etwSessionId, true);
- ActivityFilter.UpdateFilter(ref etwSession.m_activityFilter, this, sessionIdBit, activityFilters);
- m_etwSessionIdMap[sessionIdBit] = etwSession;
- m_activityFilteringForETWEnabled[sessionIdBit] = participateInSampling;
- }
- else
- {
- var etwSession = EtwSession.GetEtwSession(etwSessionId);
- m_etwSessionIdMap[sessionIdBit] = null;
- m_activityFilteringForETWEnabled[sessionIdBit] = false;
- if (etwSession != null)
- {
- ActivityFilter.DisableFilter(ref etwSession.m_activityFilter, this);
- // the ETW session is going away; remove it from the global list
- EtwSession.RemoveEtwSession(etwSession);
- }
- }
- m_curLiveSessions[sessionIdBit] = bEnable;
- }
- else
- {
- // legacy etw session
- if (bEnable)
- {
- if (m_legacySessions == null)
- m_legacySessions = new List<EtwSession>(8);
- var etwSession = EtwSession.GetEtwSession(etwSessionId, true);
- if (!m_legacySessions.Contains(etwSession))
- m_legacySessions.Add(etwSession);
- }
- else
- {
- var etwSession = EtwSession.GetEtwSession(etwSessionId);
- if (etwSession != null)
- {
- if (m_legacySessions != null)
- m_legacySessions.Remove(etwSession);
- // the ETW session is going away; remove it from the global list
- EtwSession.RemoveEtwSession(etwSession);
- }
- }
- }
- }
-
- internal static bool ParseCommandArgs(
- IDictionary<string, string> commandArguments,
- out bool participateInSampling,
- out string activityFilters,
- out int sessionIdBit)
- {
- bool res = true;
- participateInSampling = false;
- string activityFilterString;
- if (commandArguments.TryGetValue("ActivitySamplingStartEvent", out activityFilters))
- {
- // if a start event is specified default the event source to participate in sampling
- participateInSampling = true;
- }
-
- if (commandArguments.TryGetValue("ActivitySampling", out activityFilterString))
- {
- if (string.Compare(activityFilterString, "false", StringComparison.OrdinalIgnoreCase) == 0 ||
- activityFilterString == "0")
- participateInSampling = false;
- else
- participateInSampling = true;
- }
-
- string sSessionKwd;
- int sessionKwd = -1;
- if (!commandArguments.TryGetValue("EtwSessionKeyword", out sSessionKwd) ||
- !int.TryParse(sSessionKwd, out sessionKwd) ||
- sessionKwd < SessionMask.SHIFT_SESSION_TO_KEYWORD ||
- sessionKwd >= SessionMask.SHIFT_SESSION_TO_KEYWORD + SessionMask.MAX)
- {
- sessionIdBit = -1;
- res = false;
- }
- else
- {
- sessionIdBit = sessionKwd - SessionMask.SHIFT_SESSION_TO_KEYWORD;
- }
- return res;
- }
-
- internal void UpdateKwdTriggers(bool enable)
- {
- if (enable)
- {
- // recompute m_keywordTriggers
- ulong gKeywords = unchecked((ulong)m_matchAnyKeyword);
- if (gKeywords == 0)
- gKeywords = 0xFFFFffffFFFFffff;
-
- m_keywordTriggers = 0;
- for (int sessId = 0; sessId < SessionMask.MAX; ++sessId)
- {
- EtwSession etwSession = m_etwSessionIdMap[sessId];
- if (etwSession == null)
- continue;
-
- ActivityFilter activityFilter = etwSession.m_activityFilter;
- ActivityFilter.UpdateKwdTriggers(activityFilter, m_guid, this, unchecked((EventKeywords)gKeywords));
- }
- }
- else
- {
- m_keywordTriggers = 0;
- }
- }
-
-#endif // FEATURE_ACTIVITYSAMPLING
-
- /// <summary>
- /// If 'value is 'true' then set the eventSource so that 'dispatcher' will receive event with the eventId
- /// of 'eventId. If value is 'false' disable the event for that dispatcher. If 'eventId' is out of
- /// range return false, otherwise true.
- /// </summary>
- internal bool EnableEventForDispatcher(EventDispatcher dispatcher, int eventId, bool value)
- {
- if (dispatcher == null)
- {
- if (eventId >= m_eventData.Length)
- return false;
-#if FEATURE_MANAGED_ETW
- if (m_provider != null)
- m_eventData[eventId].EnabledForETW = value;
-#endif
- }
- else
- {
- if (eventId >= dispatcher.m_EventEnabled.Length)
- return false;
- dispatcher.m_EventEnabled[eventId] = value;
- if (value)
- m_eventData[eventId].EnabledForAnyListener = true;
- }
- return true;
- }
-
- /// <summary>
- /// Returns true if any event at all is on.
- /// </summary>
- private bool AnyEventEnabled()
- {
- for (int i = 0; i < m_eventData.Length; i++)
- if (m_eventData[i].EnabledForETW || m_eventData[i].EnabledForAnyListener)
- return true;
- return false;
- }
-
- private bool IsDisposed
- {
- get { return m_eventSourceDisposed; }
- }
-
- private void EnsureDescriptorsInitialized()
- {
-#if !ES_BUILD_STANDALONE
- Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
-#endif
- if (m_eventData == null)
- {
- Guid eventSourceGuid = Guid.Empty;
- string eventSourceName = null;
- EventMetadata[] eventData = null;
- byte[] manifest = null;
-
- // Try the GetMetadata provided by the ILTransform in ProjectN. The default sets all to null, and in that case we fall back
- // to the reflection approach.
- GetMetadata(out eventSourceGuid, out eventSourceName, out eventData, out manifest);
-
- if (eventSourceGuid.Equals(Guid.Empty) || eventSourceName == null || eventData == null || manifest == null)
- {
- // GetMetadata failed, so we have to set it via reflection.
- Debug.Assert(m_rawManifest == null);
- m_rawManifest = CreateManifestAndDescriptors(this.GetType(), Name, this);
- Debug.Assert(m_eventData != null);
-
- }
- else
- {
- // GetMetadata worked, so set the fields as appropriate.
- m_name = eventSourceName;
- m_guid = eventSourceGuid;
- m_eventData = eventData;
- m_rawManifest = manifest;
- }
- // TODO Enforce singleton pattern
- foreach (WeakReference eventSourceRef in EventListener.s_EventSources)
- {
- EventSource eventSource = eventSourceRef.Target as EventSource;
- if (eventSource != null && eventSource.Guid == m_guid && !eventSource.IsDisposed)
- {
- if (eventSource != this)
- {
- throw new ArgumentException(Resources.GetResourceString("EventSource_EventSourceGuidInUse", m_guid));
- }
- }
- }
-
- // Make certain all dispatchers also have their arrays initialized
- EventDispatcher dispatcher = m_Dispatchers;
- while (dispatcher != null)
- {
- if (dispatcher.m_EventEnabled == null)
- dispatcher.m_EventEnabled = new bool[m_eventData.Length];
- dispatcher = dispatcher.m_Next;
- }
- }
- if (s_currentPid == 0)
- {
-#if ES_BUILD_STANDALONE && !ES_BUILD_PCL && !CORECLR
- // for non-BCL EventSource we must assert SecurityPermission
- new SecurityPermission(PermissionState.Unrestricted).Assert();
-#endif
- s_currentPid = Win32Native.GetCurrentProcessId();
- }
- }
-
- // Send out the ETW manifest XML out to ETW
- // Today, we only send the manifest to ETW, custom listeners don't get it.
- private unsafe bool SendManifest(byte[] rawManifest)
- {
- bool success = true;
-
- if (rawManifest == null)
- return false;
-
- Debug.Assert(!SelfDescribingEvents);
-
-#if FEATURE_MANAGED_ETW
- fixed (byte* dataPtr = rawManifest)
- {
- // we don't want the manifest to show up in the event log channels so we specify as keywords
- // everything but the first 8 bits (reserved for the 8 channels)
- var manifestDescr = new EventDescriptor(0xFFFE, 1, 0, 0, 0xFE, 0xFFFE, 0x00ffFFFFffffFFFF);
- ManifestEnvelope envelope = new ManifestEnvelope();
-
- envelope.Format = ManifestEnvelope.ManifestFormats.SimpleXmlFormat;
- envelope.MajorVersion = 1;
- envelope.MinorVersion = 0;
- envelope.Magic = 0x5B; // An unusual number that can be checked for consistency.
- int dataLeft = rawManifest.Length;
- envelope.ChunkNumber = 0;
-
- EventProvider.EventData* dataDescrs = stackalloc EventProvider.EventData[2];
-
- dataDescrs[0].Ptr = (ulong)&envelope;
- dataDescrs[0].Size = (uint)sizeof(ManifestEnvelope);
- dataDescrs[0].Reserved = 0;
-
- dataDescrs[1].Ptr = (ulong)dataPtr;
- dataDescrs[1].Reserved = 0;
-
- int chunkSize = ManifestEnvelope.MaxChunkSize;
- TRY_AGAIN_WITH_SMALLER_CHUNK_SIZE:
- envelope.TotalChunks = (ushort)((dataLeft + (chunkSize - 1)) / chunkSize);
- while (dataLeft > 0)
- {
- dataDescrs[1].Size = (uint)Math.Min(dataLeft, chunkSize);
- if (m_provider != null)
- {
- if (!m_provider.WriteEvent(ref manifestDescr, null, null, 2, (IntPtr)dataDescrs))
- {
- // Turns out that if users set the BufferSize to something less than 64K then WriteEvent
- // can fail. If we get this failure on the first chunk try again with something smaller
- // The smallest BufferSize is 1K so if we get to 256 (to account for envelope overhead), we can give up making it smaller.
- if (EventProvider.GetLastWriteEventError() == EventProvider.WriteEventErrorCode.EventTooBig)
- {
- if (envelope.ChunkNumber == 0 && chunkSize > 256)
- {
- chunkSize = chunkSize / 2;
- goto TRY_AGAIN_WITH_SMALLER_CHUNK_SIZE;
- }
- }
- success = false;
- if (ThrowOnEventWriteErrors)
- ThrowEventSourceException("SendManifest");
- break;
- }
- }
- dataLeft -= chunkSize;
- dataDescrs[1].Ptr += (uint)chunkSize;
- envelope.ChunkNumber++;
-
- // For large manifests we want to not overflow any receiver's buffer. Most manifests will fit within
- // 5 chunks, so only the largest manifests will hit the pause.
- if ((envelope.ChunkNumber % 5) == 0)
- Thread.Sleep(15);
- }
- }
-#endif // FEATURE_MANAGED_ETW
- return success;
- }
-
-#if (ES_BUILD_PCL || PROJECTN)
- internal static Attribute GetCustomAttributeHelper(Type type, Type attributeType, EventManifestOptions flags = EventManifestOptions.None)
- {
- return GetCustomAttributeHelper(type.GetTypeInfo(), attributeType, flags);
- }
-#endif
-
- // Helper to deal with the fact that the type we are reflecting over might be loaded in the ReflectionOnly context.
- // When that is the case, we have the build the custom assemblies on a member by hand.
- internal static Attribute GetCustomAttributeHelper(MemberInfo member, Type attributeType, EventManifestOptions flags = EventManifestOptions.None)
- {
- if (!member.Module.Assembly.ReflectionOnly() && (flags & EventManifestOptions.AllowEventSourceOverride) == 0)
- {
- // Let the runtime to the work for us, since we can execute code in this context.
- Attribute firstAttribute = null;
- foreach (var attribute in member.GetCustomAttributes(attributeType, false))
- {
- firstAttribute = (Attribute)attribute;
- break;
- }
- return firstAttribute;
- }
-
-#if (!ES_BUILD_PCL && !PROJECTN)
- // In the reflection only context, we have to do things by hand.
- string fullTypeNameToFind = attributeType.FullName;
-
-#if EVENT_SOURCE_LEGACY_NAMESPACE_SUPPORT
- fullTypeNameToFind = fullTypeNameToFind.Replace("System.Diagnostics.Eventing", "System.Diagnostics.Tracing");
-#endif
-
- foreach (CustomAttributeData data in CustomAttributeData.GetCustomAttributes(member))
- {
- if (AttributeTypeNamesMatch(attributeType, data.Constructor.ReflectedType))
- {
- Attribute attr = null;
-
- Debug.Assert(data.ConstructorArguments.Count <= 1);
-
- if (data.ConstructorArguments.Count == 1)
- {
- attr = (Attribute)Activator.CreateInstance(attributeType, new object[] { data.ConstructorArguments[0].Value });
- }
- else if (data.ConstructorArguments.Count == 0)
- {
- attr = (Attribute)Activator.CreateInstance(attributeType);
- }
-
- if (attr != null)
- {
- Type t = attr.GetType();
-
- foreach (CustomAttributeNamedArgument namedArgument in data.NamedArguments)
- {
- PropertyInfo p = t.GetProperty(namedArgument.MemberInfo.Name, BindingFlags.Public | BindingFlags.Instance);
- object value = namedArgument.TypedValue.Value;
-
- if (p.PropertyType.IsEnum)
- {
- value = Enum.Parse(p.PropertyType, value.ToString());
- }
-
- p.SetValue(attr, value, null);
- }
-
- return attr;
- }
- }
- }
-
- return null;
-#else // ES_BUILD_PCL && PROJECTN
- throw new ArgumentException(Resources.GetResourceString("EventSource", nameof(EventSource_PCLPlatformNotSupportedReflection)));
-#endif
- }
-
- /// <summary>
- /// Evaluates if two related "EventSource"-domain types should be considered the same
- /// </summary>
- /// <param name="attributeType">The attribute type in the load context - it's associated with the running
- /// EventSource type. This type may be different fromt he base type of the user-defined EventSource.</param>
- /// <param name="reflectedAttributeType">The attribute type in the reflection context - it's associated with
- /// the user-defined EventSource, and is in the same assembly as the eventSourceType passed to
- /// </param>
- /// <returns>True - if the types should be considered equivalent, False - otherwise</returns>
- private static bool AttributeTypeNamesMatch(Type attributeType, Type reflectedAttributeType)
- {
- return
- // are these the same type?
- attributeType == reflectedAttributeType ||
- // are the full typenames equal?
- string.Equals(attributeType.FullName, reflectedAttributeType.FullName, StringComparison.Ordinal) ||
- // are the typenames equal and the namespaces under "Diagnostics.Tracing" (typically
- // either Microsoft.Diagnostics.Tracing or System.Diagnostics.Tracing)?
- string.Equals(attributeType.Name, reflectedAttributeType.Name, StringComparison.Ordinal) &&
- attributeType.Namespace.EndsWith("Diagnostics.Tracing", StringComparison.Ordinal) &&
- (reflectedAttributeType.Namespace.EndsWith("Diagnostics.Tracing", StringComparison.Ordinal)
-#if EVENT_SOURCE_LEGACY_NAMESPACE_SUPPORT
- || reflectedAttributeType.Namespace.EndsWith("Diagnostics.Eventing", StringComparison.Ordinal)
-#endif
-);
- }
-
- private static Type GetEventSourceBaseType(Type eventSourceType, bool allowEventSourceOverride, bool reflectionOnly)
- {
- // return false for "object" and interfaces
- if (eventSourceType.BaseType() == null)
- return null;
-
- // now go up the inheritance chain until hitting a concrete type ("object" at worse)
- do
- {
- eventSourceType = eventSourceType.BaseType();
- }
- while (eventSourceType != null && eventSourceType.IsAbstract());
-
- if (eventSourceType != null)
- {
- if (!allowEventSourceOverride)
- {
- if (reflectionOnly && eventSourceType.FullName != typeof(EventSource).FullName ||
- !reflectionOnly && eventSourceType != typeof(EventSource))
- return null;
- }
- else
- {
- if (eventSourceType.Name != "EventSource")
- return null;
- }
- }
- return eventSourceType;
- }
-
- // Use reflection to look at the attributes of a class, and generate a manifest for it (as UTF8) and
- // return the UTF8 bytes. It also sets up the code:EventData structures needed to dispatch events
- // at run time. 'source' is the event source to place the descriptors. If it is null,
- // then the descriptors are not creaed, and just the manifest is generated.
- private static byte[] CreateManifestAndDescriptors(Type eventSourceType, string eventSourceDllName, EventSource source,
- EventManifestOptions flags = EventManifestOptions.None)
- {
- ManifestBuilder manifest = null;
- bool bNeedsManifest = source != null ? !source.SelfDescribingEvents : true;
- Exception exception = null; // exception that might get raised during validation b/c we couldn't/didn't recover from a previous error
- byte[] res = null;
-
- if (eventSourceType.IsAbstract() && (flags & EventManifestOptions.Strict) == 0)
- return null;
-
-#if DEBUG && ES_BUILD_STANDALONE
- TestSupport.TestHooks.MaybeThrow(eventSourceType,
- TestSupport.Category.ManifestError,
- "EventSource_CreateManifestAndDescriptors",
- new ArgumentException("EventSource_CreateManifestAndDescriptors"));
-#endif
-
- try
- {
- MethodInfo[] methods = eventSourceType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
- EventAttribute defaultEventAttribute;
- int eventId = 1; // The number given to an event that does not have a explicitly given ID.
- EventMetadata[] eventData = null;
- Dictionary<string, string> eventsByName = null;
- if (source != null || (flags & EventManifestOptions.Strict) != 0)
- {
- eventData = new EventMetadata[methods.Length + 1];
- eventData[0].Name = ""; // Event 0 is the 'write messages string' event, and has an empty name.
- }
-
- // See if we have localization information.
- ResourceManager resources = null;
- EventSourceAttribute eventSourceAttrib = (EventSourceAttribute)GetCustomAttributeHelper(eventSourceType, typeof(EventSourceAttribute), flags);
- if (eventSourceAttrib != null && eventSourceAttrib.LocalizationResources != null)
- resources = new ResourceManager(eventSourceAttrib.LocalizationResources, eventSourceType.Assembly());
-
- manifest = new ManifestBuilder(GetName(eventSourceType, flags), GetGuid(eventSourceType), eventSourceDllName,
- resources, flags);
-
- // Add an entry unconditionally for event ID 0 which will be for a string message.
- manifest.StartEvent("EventSourceMessage", new EventAttribute(0) { Level = EventLevel.LogAlways, Task = (EventTask)0xFFFE });
- manifest.AddEventParameter(typeof(string), "message");
- manifest.EndEvent();
-
- // eventSourceType must be sealed and must derive from this EventSource
- if ((flags & EventManifestOptions.Strict) != 0)
- {
- bool typeMatch = GetEventSourceBaseType(eventSourceType, (flags & EventManifestOptions.AllowEventSourceOverride) != 0, eventSourceType.Assembly().ReflectionOnly()) != null;
-
- if (!typeMatch)
- {
- manifest.ManifestError(Resources.GetResourceString("EventSource_TypeMustDeriveFromEventSource"));
- }
- if (!eventSourceType.IsAbstract() && !eventSourceType.IsSealed())
- {
- manifest.ManifestError(Resources.GetResourceString("EventSource_TypeMustBeSealedOrAbstract"));
- }
- }
-
- // Collect task, opcode, keyword and channel information
-#if FEATURE_MANAGED_ETW_CHANNELS && FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
- foreach (var providerEnumKind in new string[] { "Keywords", "Tasks", "Opcodes", "Channels" })
-#else
- foreach (var providerEnumKind in new string[] { "Keywords", "Tasks", "Opcodes" })
-#endif
- {
- Type nestedType = eventSourceType.GetNestedType(providerEnumKind);
- if (nestedType != null)
- {
- if (eventSourceType.IsAbstract())
- {
- manifest.ManifestError(Resources.GetResourceString("EventSource_AbstractMustNotDeclareKTOC", nestedType.Name));
- }
- else
- {
- foreach (FieldInfo staticField in nestedType.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static))
- {
- AddProviderEnumKind(manifest, staticField, providerEnumKind);
- }
- }
- }
- }
- // ensure we have keywords for the session-filtering reserved bits
- {
- manifest.AddKeyword("Session3", (long)0x1000 << 32);
- manifest.AddKeyword("Session2", (long)0x2000 << 32);
- manifest.AddKeyword("Session1", (long)0x4000 << 32);
- manifest.AddKeyword("Session0", (long)0x8000 << 32);
- }
-
- if (eventSourceType != typeof(EventSource))
- {
- for (int i = 0; i < methods.Length; i++)
- {
- MethodInfo method = methods[i];
- ParameterInfo[] args = method.GetParameters();
-
- // Get the EventDescriptor (from the Custom attributes)
- EventAttribute eventAttribute = (EventAttribute)GetCustomAttributeHelper(method, typeof(EventAttribute), flags);
-
- // Compat: until v4.5.1 we ignored any non-void returning methods as well as virtual methods for
- // the only reason of limiting the number of methods considered to be events. This broke a common
- // design of having event sources implement specific interfaces. To fix this in a compatible way
- // we will now allow both non-void returning and virtual methods to be Event methods, as long
- // as they are marked with the [Event] attribute
- if (/* method.IsVirtual || */ method.IsStatic)
- {
- continue;
- }
-
- if (eventSourceType.IsAbstract())
- {
- if (eventAttribute != null)
- {
- manifest.ManifestError(Resources.GetResourceString("EventSource_AbstractMustNotDeclareEventMethods", method.Name, eventAttribute.EventId));
- }
- continue;
- }
- else if (eventAttribute == null)
- {
- // Methods that don't return void can't be events, if they're NOT marked with [Event].
- // (see Compat comment above)
- if (method.ReturnType != typeof(void))
- {
- continue;
- }
-
- // Continue to ignore virtual methods if they do NOT have the [Event] attribute
- // (see Compat comment above)
- if (method.IsVirtual)
- {
- continue;
- }
-
- // If we explicitly mark the method as not being an event, then honor that.
- if (GetCustomAttributeHelper(method, typeof(NonEventAttribute), flags) != null)
- continue;
-
- defaultEventAttribute = new EventAttribute(eventId);
- eventAttribute = defaultEventAttribute;
- }
- else if (eventAttribute.EventId <= 0)
- {
- manifest.ManifestError(Resources.GetResourceString("EventSource_NeedPositiveId", method.Name), true);
- continue; // don't validate anything else for this event
- }
- if (method.Name.LastIndexOf('.') >= 0)
- {
- manifest.ManifestError(Resources.GetResourceString("EventSource_EventMustNotBeExplicitImplementation", method.Name, eventAttribute.EventId));
- }
-
- eventId++;
- string eventName = method.Name;
-
- if (eventAttribute.Opcode == EventOpcode.Info) // We are still using the default opcode.
- {
- // By default pick a task ID derived from the EventID, starting with the highest task number and working back
- bool noTask = (eventAttribute.Task == EventTask.None);
- if (noTask)
- eventAttribute.Task = (EventTask)(0xFFFE - eventAttribute.EventId);
-
- // Unless we explicitly set the opcode to Info (to override the auto-generate of Start or Stop opcodes,
- // pick a default opcode based on the event name (either Info or start or stop if the name ends with that suffix).
- if (!eventAttribute.IsOpcodeSet)
- eventAttribute.Opcode = GetOpcodeWithDefault(EventOpcode.Info, eventName);
-
- // Make the stop opcode have the same task as the start opcode.
- if (noTask)
- {
- if (eventAttribute.Opcode == EventOpcode.Start)
- {
- string taskName = eventName.Substring(0, eventName.Length - s_ActivityStartSuffix.Length); // Remove the Stop suffix to get the task name
- if (string.Compare(eventName, 0, taskName, 0, taskName.Length) == 0 &&
- string.Compare(eventName, taskName.Length, s_ActivityStartSuffix, 0, Math.Max(eventName.Length - taskName.Length, s_ActivityStartSuffix.Length)) == 0)
- {
- // Add a task that is just the task name for the start event. This suppress the auto-task generation
- // That would otherwise happen (and create 'TaskName'Start as task name rather than just 'TaskName'
- manifest.AddTask(taskName, (int)eventAttribute.Task);
- }
- }
- else if (eventAttribute.Opcode == EventOpcode.Stop)
- {
- // Find the start associated with this stop event. We require start to be immediately before the stop
- int startEventId = eventAttribute.EventId - 1;
- if (eventData != null && startEventId < eventData.Length)
- {
- Debug.Assert(0 <= startEventId); // Since we reserve id 0, we know that id-1 is <= 0
- EventMetadata startEventMetadata = eventData[startEventId];
-
- // If you remove the Stop and add a Start does that name match the Start Event's Name?
- // Ideally we would throw an error
- string taskName = eventName.Substring(0, eventName.Length - s_ActivityStopSuffix.Length); // Remove the Stop suffix to get the task name
- if (startEventMetadata.Descriptor.Opcode == (byte)EventOpcode.Start &&
- string.Compare(startEventMetadata.Name, 0, taskName, 0, taskName.Length) == 0 &&
- string.Compare(startEventMetadata.Name, taskName.Length, s_ActivityStartSuffix, 0, Math.Max(startEventMetadata.Name.Length - taskName.Length, s_ActivityStartSuffix.Length)) == 0)
- {
-
- // Make the stop event match the start event
- eventAttribute.Task = (EventTask)startEventMetadata.Descriptor.Task;
- noTask = false;
- }
- }
- if (noTask && (flags & EventManifestOptions.Strict) != 0) // Throw an error if we can compatibly.
- {
- throw new ArgumentException(Resources.GetResourceString("EventSource_StopsFollowStarts"));
- }
- }
- }
- }
-
- bool hasRelatedActivityID = RemoveFirstArgIfRelatedActivityId(ref args);
- if (!(source != null && source.SelfDescribingEvents))
- {
- manifest.StartEvent(eventName, eventAttribute);
- for (int fieldIdx = 0; fieldIdx < args.Length; fieldIdx++)
- {
- manifest.AddEventParameter(args[fieldIdx].ParameterType, args[fieldIdx].Name);
- }
- manifest.EndEvent();
- }
-
- if (source != null || (flags & EventManifestOptions.Strict) != 0)
- {
- // Do checking for user errors (optional, but not a big deal so we do it).
- DebugCheckEvent(ref eventsByName, eventData, method, eventAttribute, manifest, flags);
-
-#if FEATURE_MANAGED_ETW_CHANNELS
- // add the channel keyword for Event Viewer channel based filters. This is added for creating the EventDescriptors only
- // and is not required for the manifest
- if (eventAttribute.Channel != EventChannel.None)
- {
- unchecked
- {
- eventAttribute.Keywords |= (EventKeywords)manifest.GetChannelKeyword(eventAttribute.Channel, (ulong)eventAttribute.Keywords);
- }
- }
-#endif
- string eventKey = "event_" + eventName;
- string msg = manifest.GetLocalizedMessage(eventKey, CultureInfo.CurrentUICulture, etwFormat: false);
- // overwrite inline message with the localized message
- if (msg != null) eventAttribute.Message = msg;
-
- AddEventDescriptor(ref eventData, eventName, eventAttribute, args, hasRelatedActivityID);
- }
- }
- }
-
- // Tell the TraceLogging stuff where to start allocating its own IDs.
- NameInfo.ReserveEventIDsBelow(eventId);
-
- if (source != null)
- {
- TrimEventDescriptors(ref eventData);
- source.m_eventData = eventData; // officially initialize it. We do this at most once (it is racy otherwise).
-#if FEATURE_MANAGED_ETW_CHANNELS
- source.m_channelData = manifest.GetChannelData();
-#endif
- }
-
- // if this is an abstract event source we've already performed all the validation we can
- if (!eventSourceType.IsAbstract() && (source == null || !source.SelfDescribingEvents))
- {
- bNeedsManifest = (flags & EventManifestOptions.OnlyIfNeededForRegistration) == 0
-#if FEATURE_MANAGED_ETW_CHANNELS
- || manifest.GetChannelData().Length > 0
-#endif
-;
-
- // if the manifest is not needed and we're not requested to validate the event source return early
- if (!bNeedsManifest && (flags & EventManifestOptions.Strict) == 0)
- return null;
-
- res = manifest.CreateManifest();
- }
- }
- catch (Exception e)
- {
- // if this is a runtime manifest generation let the exception propagate
- if ((flags & EventManifestOptions.Strict) == 0)
- throw;
- // else store it to include it in the Argument exception we raise below
- exception = e;
- }
-
- if ((flags & EventManifestOptions.Strict) != 0 && (manifest.Errors.Count > 0 || exception != null))
- {
- string msg = String.Empty;
- if (manifest.Errors.Count > 0)
- {
- bool firstError = true;
- foreach (string error in manifest.Errors)
- {
- if (!firstError)
- msg += Environment.NewLine;
- firstError = false;
- msg += error;
- }
- }
- else
- msg = "Unexpected error: " + exception.Message;
-
- throw new ArgumentException(msg, exception);
- }
-
- return bNeedsManifest ? res : null;
- }
-
- private static bool RemoveFirstArgIfRelatedActivityId(ref ParameterInfo[] args)
- {
- // If the first parameter is (case insensitive) 'relatedActivityId' then skip it.
- if (args.Length > 0 && args[0].ParameterType == typeof(Guid) &&
- string.Compare(args[0].Name, "relatedActivityId", StringComparison.OrdinalIgnoreCase) == 0)
- {
- var newargs = new ParameterInfo[args.Length - 1];
- Array.Copy(args, 1, newargs, 0, args.Length - 1);
- args = newargs;
-
- return true;
- }
-
- return false;
- }
-
- // adds a enumeration (keyword, opcode, task or channel) represented by 'staticField'
- // to the manifest.
- private static void AddProviderEnumKind(ManifestBuilder manifest, FieldInfo staticField, string providerEnumKind)
- {
- bool reflectionOnly = staticField.Module.Assembly.ReflectionOnly();
- Type staticFieldType = staticField.FieldType;
- if (!reflectionOnly && (staticFieldType == typeof(EventOpcode)) || AttributeTypeNamesMatch(staticFieldType, typeof(EventOpcode)))
- {
- if (providerEnumKind != "Opcodes") goto Error;
- int value = (int)staticField.GetRawConstantValue();
- manifest.AddOpcode(staticField.Name, value);
- }
- else if (!reflectionOnly && (staticFieldType == typeof(EventTask)) || AttributeTypeNamesMatch(staticFieldType, typeof(EventTask)))
- {
- if (providerEnumKind != "Tasks") goto Error;
- int value = (int)staticField.GetRawConstantValue();
- manifest.AddTask(staticField.Name, value);
- }
- else if (!reflectionOnly && (staticFieldType == typeof(EventKeywords)) || AttributeTypeNamesMatch(staticFieldType, typeof(EventKeywords)))
- {
- if (providerEnumKind != "Keywords") goto Error;
- ulong value = unchecked((ulong)(long)staticField.GetRawConstantValue());
- manifest.AddKeyword(staticField.Name, value);
- }
-#if FEATURE_MANAGED_ETW_CHANNELS && FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
- else if (!reflectionOnly && (staticFieldType == typeof(EventChannel)) || AttributeTypeNamesMatch(staticFieldType, typeof(EventChannel)))
- {
- if (providerEnumKind != "Channels") goto Error;
- var channelAttribute = (EventChannelAttribute)GetCustomAttributeHelper(staticField, typeof(EventChannelAttribute));
- manifest.AddChannel(staticField.Name, (byte)staticField.GetRawConstantValue(), channelAttribute);
- }
-#endif
- return;
- Error:
- manifest.ManifestError(Resources.GetResourceString("EventSource_EnumKindMismatch", staticField.Name, staticField.FieldType.Name, providerEnumKind));
- }
-
- // Helper used by code:CreateManifestAndDescriptors to add a code:EventData descriptor for a method
- // with the code:EventAttribute 'eventAttribute'. resourceManger may be null in which case we populate it
- // it is populated if we need to look up message resources
- private static void AddEventDescriptor(ref EventMetadata[] eventData, string eventName,
- EventAttribute eventAttribute, ParameterInfo[] eventParameters,
- bool hasRelatedActivityID)
- {
- if (eventData == null || eventData.Length <= eventAttribute.EventId)
- {
- EventMetadata[] newValues = new EventMetadata[Math.Max(eventData.Length + 16, eventAttribute.EventId + 1)];
- Array.Copy(eventData, 0, newValues, 0, eventData.Length);
- eventData = newValues;
- }
-
- eventData[eventAttribute.EventId].Descriptor = new EventDescriptor(
- eventAttribute.EventId,
- eventAttribute.Version,
-#if FEATURE_MANAGED_ETW_CHANNELS
- (byte)eventAttribute.Channel,
-#else
- (byte)0,
-#endif
- (byte)eventAttribute.Level,
- (byte)eventAttribute.Opcode,
- (int)eventAttribute.Task,
- unchecked((long)((ulong)eventAttribute.Keywords | SessionMask.All.ToEventKeywords())));
-
- eventData[eventAttribute.EventId].Tags = eventAttribute.Tags;
- eventData[eventAttribute.EventId].Name = eventName;
- eventData[eventAttribute.EventId].Parameters = eventParameters;
- eventData[eventAttribute.EventId].Message = eventAttribute.Message;
- eventData[eventAttribute.EventId].ActivityOptions = eventAttribute.ActivityOptions;
- eventData[eventAttribute.EventId].HasRelatedActivityID = hasRelatedActivityID;
- }
-
- // Helper used by code:CreateManifestAndDescriptors that trims the m_eventData array to the correct
- // size after all event descriptors have been added.
- private static void TrimEventDescriptors(ref EventMetadata[] eventData)
- {
- int idx = eventData.Length;
- while (0 < idx)
- {
- --idx;
- if (eventData[idx].Descriptor.EventId != 0)
- break;
- }
- if (eventData.Length - idx > 2) // allow one wasted slot.
- {
- EventMetadata[] newValues = new EventMetadata[idx + 1];
- Array.Copy(eventData, 0, newValues, 0, newValues.Length);
- eventData = newValues;
- }
- }
-
- // Helper used by code:EventListener.AddEventSource and code:EventListener.EventListener
- // when a listener gets attached to a eventSource
- internal void AddListener(EventListener listener)
- {
- lock (EventListener.EventListenersLock)
- {
- bool[] enabledArray = null;
- if (m_eventData != null)
- enabledArray = new bool[m_eventData.Length];
- m_Dispatchers = new EventDispatcher(m_Dispatchers, enabledArray, listener);
- listener.OnEventSourceCreated(this);
- }
- }
-
- // Helper used by code:CreateManifestAndDescriptors to find user mistakes like reusing an event
- // index for two distinct events etc. Throws exceptions when it finds something wrong.
- private static void DebugCheckEvent(ref Dictionary<string, string> eventsByName,
- EventMetadata[] eventData, MethodInfo method, EventAttribute eventAttribute,
- ManifestBuilder manifest, EventManifestOptions options)
- {
- int evtId = eventAttribute.EventId;
- string evtName = method.Name;
- int eventArg = GetHelperCallFirstArg(method);
- if (eventArg >= 0 && evtId != eventArg)
- {
- manifest.ManifestError(Resources.GetResourceString("EventSource_MismatchIdToWriteEvent", evtName, evtId, eventArg), true);
- }
-
- if (evtId < eventData.Length && eventData[evtId].Descriptor.EventId != 0)
- {
- manifest.ManifestError(Resources.GetResourceString("EventSource_EventIdReused", evtName, evtId, eventData[evtId].Name), true);
- }
-
- // We give a task to things if they don't have one.
- // TODO this is moderately expensive (N*N). We probably should not even bother....
- Debug.Assert(eventAttribute.Task != EventTask.None || eventAttribute.Opcode != EventOpcode.Info);
- for (int idx = 0; idx < eventData.Length; ++idx)
- {
- // skip unused Event IDs.
- if (eventData[idx].Name == null)
- continue;
-
- if (eventData[idx].Descriptor.Task == (int)eventAttribute.Task && eventData[idx].Descriptor.Opcode == (int)eventAttribute.Opcode)
- {
- manifest.ManifestError(Resources.GetResourceString("EventSource_TaskOpcodePairReused",
- evtName, evtId, eventData[idx].Name, idx));
- // If we are not strict stop on first error. We have had problems with really large providers taking forever. because of many errors.
- if ((options & EventManifestOptions.Strict) == 0)
- break;
- }
- }
-
- // for non-default event opcodes the user must define a task!
- if (eventAttribute.Opcode != EventOpcode.Info)
- {
- bool failure = false;
- if (eventAttribute.Task == EventTask.None)
- failure = true;
- else
- {
- // If you have the auto-assigned Task, then you did not explicitly set one.
- // This is OK for Start events because we have special logic to assign the task to a prefix derived from the event name
- // But all other cases we want to catch the omission.
- var autoAssignedTask = (EventTask)(0xFFFE - evtId);
- if ((eventAttribute.Opcode != EventOpcode.Start && eventAttribute.Opcode != EventOpcode.Stop) && eventAttribute.Task == autoAssignedTask)
- failure = true;
- }
- if (failure)
- {
- manifest.ManifestError(Resources.GetResourceString("EventSource_EventMustHaveTaskIfNonDefaultOpcode", evtName, evtId));
- }
- }
-
- // If we ever want to enforce the rule: MethodName = TaskName + OpcodeName here's how:
- // (the reason we don't is backwards compat and the need for handling this as a non-fatal error
- // by eventRegister.exe)
- // taskName & opcodeName could be passed in by the caller which has opTab & taskTab handy
- // if (!(((int)eventAttribute.Opcode == 0 && evtName == taskName) || (evtName == taskName+opcodeName)))
- // {
- // throw new WarningException(Resources.GetResourceString("EventSource_EventNameDoesNotEqualTaskPlusOpcode"));
- // }
-
- if (eventsByName == null)
- eventsByName = new Dictionary<string, string>();
-
- if (eventsByName.ContainsKey(evtName))
- {
- manifest.ManifestError(Resources.GetResourceString("EventSource_EventNameReused", evtName), true);
- }
-
- eventsByName[evtName] = evtName;
- }
-
- /// <summary>
- /// This method looks at the IL and tries to pattern match against the standard
- /// 'boilerplate' event body
- /// <code>
- /// { if (Enabled()) WriteEvent(#, ...) }
- /// </code>
- /// If the pattern matches, it returns the literal number passed as the first parameter to
- /// the WriteEvent. This is used to find common user errors (mismatching this
- /// number with the EventAttribute ID). It is only used for validation.
- /// </summary>
- /// <param name="method">The method to probe.</param>
- /// <returns>The literal value or -1 if the value could not be determined. </returns>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Switch statement is clearer than alternatives")]
- static private int GetHelperCallFirstArg(MethodInfo method)
- {
-#if (!ES_BUILD_PCL && !PROJECTN)
- // Currently searches for the following pattern
- //
- // ... // CAN ONLY BE THE INSTRUCTIONS BELOW
- // LDARG0
- // LDC.I4 XXX
- // ... // CAN ONLY BE THE INSTRUCTIONS BELOW CAN'T BE A BRANCH OR A CALL
- // CALL
- // NOP // 0 or more times
- // RET
- //
- // If we find this pattern we return the XXX. Otherwise we return -1.
-#if !CORECLR
- (new ReflectionPermission(ReflectionPermissionFlag.MemberAccess)).Assert();
-#endif
- byte[] instrs = method.GetMethodBody().GetILAsByteArray();
- int retVal = -1;
- for (int idx = 0; idx < instrs.Length;)
- {
- switch (instrs[idx])
- {
- case 0: // NOP
- case 1: // BREAK
- case 2: // LDARG_0
- case 3: // LDARG_1
- case 4: // LDARG_2
- case 5: // LDARG_3
- case 6: // LDLOC_0
- case 7: // LDLOC_1
- case 8: // LDLOC_2
- case 9: // LDLOC_3
- case 10: // STLOC_0
- case 11: // STLOC_1
- case 12: // STLOC_2
- case 13: // STLOC_3
- break;
- case 14: // LDARG_S
- case 16: // STARG_S
- idx++;
- break;
- case 20: // LDNULL
- break;
- case 21: // LDC_I4_M1
- case 22: // LDC_I4_0
- case 23: // LDC_I4_1
- case 24: // LDC_I4_2
- case 25: // LDC_I4_3
- case 26: // LDC_I4_4
- case 27: // LDC_I4_5
- case 28: // LDC_I4_6
- case 29: // LDC_I4_7
- case 30: // LDC_I4_8
- if (idx > 0 && instrs[idx - 1] == 2) // preceeded by LDARG0
- retVal = instrs[idx] - 22;
- break;
- case 31: // LDC_I4_S
- if (idx > 0 && instrs[idx - 1] == 2) // preceeded by LDARG0
- retVal = instrs[idx + 1];
- idx++;
- break;
- case 32: // LDC_I4
- idx += 4;
- break;
- case 37: // DUP
- break;
- case 40: // CALL
- idx += 4;
-
- if (retVal >= 0)
- {
- // Is this call just before return?
- for (int search = idx + 1; search < instrs.Length; search++)
- {
- if (instrs[search] == 42) // RET
- return retVal;
- if (instrs[search] != 0) // NOP
- break;
- }
- }
- retVal = -1;
- break;
- case 44: // BRFALSE_S
- case 45: // BRTRUE_S
- retVal = -1;
- idx++;
- break;
- case 57: // BRFALSE
- case 58: // BRTRUE
- retVal = -1;
- idx += 4;
- break;
- case 103: // CONV_I1
- case 104: // CONV_I2
- case 105: // CONV_I4
- case 106: // CONV_I8
- case 109: // CONV_U4
- case 110: // CONV_U8
- break;
- case 140: // BOX
- case 141: // NEWARR
- idx += 4;
- break;
- case 162: // STELEM_REF
- break;
- case 254: // PREFIX
- idx++;
- // Covers the CEQ instructions used in debug code for some reason.
- if (idx >= instrs.Length || instrs[idx] >= 6)
- goto default;
- break;
- default:
- /* Debug.Assert(false, "Warning: User validation code sub-optimial: Unsuported opcode " + instrs[idx] +
- " at " + idx + " in method " + method.Name); */
- return -1;
- }
- idx++;
- }
-#endif
- return -1;
- }
-
-#if false // This routine is not needed at all, it was used for unit test debugging.
- [Conditional("DEBUG")]
- private static void OutputDebugString(string msg)
- {
-#if !ES_BUILD_PCL
- msg = msg.TrimEnd('\r', '\n') +
- string.Format(CultureInfo.InvariantCulture, ", Thrd({0})" + Environment.NewLine, Thread.CurrentThread.ManagedThreadId);
- System.Diagnostics.Debugger.Log(0, null, msg);
-#endif
- }
-#endif
-
- /// <summary>
- /// Sends an error message to the debugger (outputDebugString), as well as the EventListeners
- /// It will do this even if the EventSource is not enabled.
- /// TODO remove flush parameter it is not used.
- /// </summary>
- [SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
- internal void ReportOutOfBandMessage(string msg, bool flush)
- {
- try
- {
-#if (!ES_BUILD_PCL && !PROJECTN)
- // send message to debugger without delay
- System.Diagnostics.Debugger.Log(0, null, String.Format("EventSource Error: {0}{1}", msg, Environment.NewLine));
-#endif
-
- // Send it to all listeners.
- if (m_outOfBandMessageCount < 16 - 1) // Note this is only if size byte
- m_outOfBandMessageCount++;
- else
- {
- if (m_outOfBandMessageCount == 16)
- return;
- m_outOfBandMessageCount = 16; // Mark that we hit the limit. Notify them that this is the case.
- msg = "Reached message limit. End of EventSource error messages.";
- }
-
- WriteEventString(EventLevel.LogAlways, -1, msg);
- WriteStringToAllListeners("EventSourceMessage", msg);
- }
- catch (Exception) { } // If we fail during last chance logging, well, we have to give up....
- }
-
- private EventSourceSettings ValidateSettings(EventSourceSettings settings)
- {
- var evtFormatMask = EventSourceSettings.EtwManifestEventFormat |
- EventSourceSettings.EtwSelfDescribingEventFormat;
- if ((settings & evtFormatMask) == evtFormatMask)
- {
- throw new ArgumentException(Resources.GetResourceString("EventSource_InvalidEventFormat"), nameof(settings));
- }
-
- // If you did not explicitly ask for manifest, you get self-describing.
- if ((settings & evtFormatMask) == 0)
- settings |= EventSourceSettings.EtwSelfDescribingEventFormat;
- return settings;
- }
-
- private bool ThrowOnEventWriteErrors
- {
- get { return (m_config & EventSourceSettings.ThrowOnEventWriteErrors) != 0; }
- set
- {
- if (value) m_config |= EventSourceSettings.ThrowOnEventWriteErrors;
- else m_config &= ~EventSourceSettings.ThrowOnEventWriteErrors;
- }
- }
-
- private bool SelfDescribingEvents
- {
- get
- {
- Debug.Assert(((m_config & EventSourceSettings.EtwManifestEventFormat) != 0) !=
- ((m_config & EventSourceSettings.EtwSelfDescribingEventFormat) != 0));
- return (m_config & EventSourceSettings.EtwSelfDescribingEventFormat) != 0;
- }
- set
- {
- if (!value)
- {
- m_config |= EventSourceSettings.EtwManifestEventFormat;
- m_config &= ~EventSourceSettings.EtwSelfDescribingEventFormat;
- }
- else
- {
- m_config |= EventSourceSettings.EtwSelfDescribingEventFormat;
- m_config &= ~EventSourceSettings.EtwManifestEventFormat;
- }
- }
- }
-
-#if FEATURE_ACTIVITYSAMPLING
- private void ReportActivitySamplingInfo(EventListener listener, SessionMask sessions)
- {
- Debug.Assert(listener == null || (uint)sessions == (uint)SessionMask.FromId(0));
-
- for (int perEventSourceSessionId = 0; perEventSourceSessionId < SessionMask.MAX; ++perEventSourceSessionId)
- {
- if (!sessions[perEventSourceSessionId])
- continue;
-
- ActivityFilter af;
- if (listener == null)
- {
- EtwSession etwSession = m_etwSessionIdMap[perEventSourceSessionId];
- Debug.Assert(etwSession != null);
- af = etwSession.m_activityFilter;
- }
- else
- {
- af = listener.m_activityFilter;
- }
-
- if (af == null)
- continue;
-
- SessionMask m = new SessionMask();
- m[perEventSourceSessionId] = true;
-
- foreach (var t in af.GetFilterAsTuple(m_guid))
- {
- WriteStringToListener(listener, string.Format(CultureInfo.InvariantCulture, "Session {0}: {1} = {2}", perEventSourceSessionId, t.Item1, t.Item2), m);
- }
-
- bool participateInSampling = (listener == null) ?
- m_activityFilteringForETWEnabled[perEventSourceSessionId] :
- GetDispatcher(listener).m_activityFilteringEnabled;
- WriteStringToListener(listener, string.Format(CultureInfo.InvariantCulture, "Session {0}: Activity Sampling support: {1}",
- perEventSourceSessionId, participateInSampling ? "enabled" : "disabled"), m);
- }
- }
-#endif // FEATURE_ACTIVITYSAMPLING
-
- // private instance state
- private string m_name; // My friendly name (privided in ctor)
- internal int m_id; // A small integer that is unique to this instance.
- private Guid m_guid; // GUID representing the ETW eventSource to the OS.
- internal volatile EventMetadata[] m_eventData; // None per-event data
- private volatile byte[] m_rawManifest; // Bytes to send out representing the event schema
-
- private EventHandler<EventCommandEventArgs> m_eventCommandExecuted;
-
- private EventSourceSettings m_config; // configuration information
-
- private bool m_eventSourceDisposed; // has Dispose been called.
-
- // Enabling bits
- private bool m_eventSourceEnabled; // am I enabled (any of my events are enabled for any dispatcher)
- internal EventLevel m_level; // highest level enabled by any output dispatcher
- internal EventKeywords m_matchAnyKeyword; // the logical OR of all levels enabled by any output dispatcher (zero is a special case) meaning 'all keywords'
-
- // Dispatching state
- internal volatile EventDispatcher m_Dispatchers; // Linked list of code:EventDispatchers we write the data to (we also do ETW specially)
-#if FEATURE_MANAGED_ETW
- private volatile OverideEventProvider m_provider; // This hooks up ETW commands to our 'OnEventCommand' callback
-#endif
- private bool m_completelyInited; // The EventSource constructor has returned without exception.
- private Exception m_constructionException; // If there was an exception construction, this is it
- private byte m_outOfBandMessageCount; // The number of out of band messages sent (we throttle them
- private EventCommandEventArgs m_deferredCommands;// If we get commands before we are fully we store them here and run the when we are fully inited.
-
- private string[] m_traits; // Used to implement GetTraits
-
- internal static uint s_currentPid; // current process id, used in synthesizing quasi-GUIDs
- [ThreadStatic]
- private static byte m_EventSourceExceptionRecurenceCount = 0; // current recursion count inside ThrowEventSourceException
-
- [ThreadStatic]
- private static bool m_EventSourceInDecodeObject = false;
-
-#if FEATURE_MANAGED_ETW_CHANNELS
- internal volatile ulong[] m_channelData;
-#endif
-
-#if FEATURE_ACTIVITYSAMPLING
- private SessionMask m_curLiveSessions; // the activity-tracing aware sessions' bits
- private EtwSession[] m_etwSessionIdMap; // the activity-tracing aware sessions
- private List<EtwSession> m_legacySessions; // the legacy ETW sessions listening to this source
- internal long m_keywordTriggers; // a bit is set if it corresponds to a keyword that's part of an enabled triggering event
- internal SessionMask m_activityFilteringForETWEnabled; // does THIS EventSource have activity filtering turned on for each ETW session
- static internal Action<Guid> s_activityDying; // Fires when something calls SetCurrentThreadToActivity()
- // Also used to mark that activity tracing is on for some case
-#endif // FEATURE_ACTIVITYSAMPLING
-
- // We use a single instance of ActivityTracker for all EventSources instances to allow correlation between multiple event providers.
- // We have m_activityTracker field simply because instance field is more efficient than static field fetch.
- ActivityTracker m_activityTracker;
- internal const string s_ActivityStartSuffix = "Start";
- internal const string s_ActivityStopSuffix = "Stop";
-
- // used for generating GUID from eventsource name
- private static readonly byte[] namespaceBytes = new byte[] {
- 0x48, 0x2C, 0x2D, 0xB2, 0xC3, 0x90, 0x47, 0xC8,
- 0x87, 0xF8, 0x1A, 0x15, 0xBF, 0xC1, 0x30, 0xFB,
- };
-
- #endregion
- }
-
- /// <summary>
- /// Enables specifying event source configuration options to be used in the EventSource constructor.
- /// </summary>
- [Flags]
- public enum EventSourceSettings
- {
- /// <summary>
- /// This specifies none of the special configuration options should be enabled.
- /// </summary>
- Default = 0,
- /// <summary>
- /// Normally an EventSource NEVER throws; setting this option will tell it to throw when it encounters errors.
- /// </summary>
- ThrowOnEventWriteErrors = 1,
- /// <summary>
- /// Setting this option is a directive to the ETW listener should use manifest-based format when
- /// firing events. This is the default option when defining a type derived from EventSource
- /// (using the protected EventSource constructors).
- /// Only one of EtwManifestEventFormat or EtwSelfDescribingEventFormat should be specified
- /// </summary>
- EtwManifestEventFormat = 4,
- /// <summary>
- /// Setting this option is a directive to the ETW listener should use self-describing event format
- /// when firing events. This is the default option when creating a new instance of the EventSource
- /// type (using the public EventSource constructors).
- /// Only one of EtwManifestEventFormat or EtwSelfDescribingEventFormat should be specified
- /// </summary>
- EtwSelfDescribingEventFormat = 8,
- }
-
- /// <summary>
- /// An EventListener represents a target for the events generated by EventSources (that is subclasses
- /// of <see cref="EventSource"/>), in the current appdomain. When a new EventListener is created
- /// it is logically attached to all eventSources in that appdomain. When the EventListener is Disposed, then
- /// it is disconnected from the event eventSources. Note that there is a internal list of STRONG references
- /// to EventListeners, which means that relying on the lack of references to EventListeners to clean up
- /// EventListeners will NOT work. You must call EventListener.Dispose explicitly when a dispatcher is no
- /// longer needed.
- /// <para>
- /// Once created, EventListeners can enable or disable on a per-eventSource basis using verbosity levels
- /// (<see cref="EventLevel"/>) and bitfields (<see cref="EventKeywords"/>) to further restrict the set of
- /// events to be sent to the dispatcher. The dispatcher can also send arbitrary commands to a particular
- /// eventSource using the 'SendCommand' method. The meaning of the commands are eventSource specific.
- /// </para><para>
- /// The Null Guid (that is (new Guid()) has special meaning as a wildcard for 'all current eventSources in
- /// the appdomain'. Thus it is relatively easy to turn on all events in the appdomain if desired.
- /// </para><para>
- /// It is possible for there to be many EventListener's defined in a single appdomain. Each dispatcher is
- /// logically independent of the other listeners. Thus when one dispatcher enables or disables events, it
- /// affects only that dispatcher (other listeners get the events they asked for). It is possible that
- /// commands sent with 'SendCommand' would do a semantic operation that would affect the other listeners
- /// (like doing a GC, or flushing data ...), but this is the exception rather than the rule.
- /// </para><para>
- /// Thus the model is that each EventSource keeps a list of EventListeners that it is sending events
- /// to. Associated with each EventSource-dispatcher pair is a set of filtering criteria that determine for
- /// that eventSource what events that dispatcher will receive.
- /// </para><para>
- /// Listeners receive the events on their 'OnEventWritten' method. Thus subclasses of EventListener must
- /// override this method to do something useful with the data.
- /// </para><para>
- /// In addition, when new eventSources are created, the 'OnEventSourceCreate' method is called. The
- /// invariant associated with this callback is that every eventSource gets exactly one
- /// 'OnEventSourceCreate' call for ever eventSource that can potentially send it log messages. In
- /// particular when a EventListener is created, typically a series of OnEventSourceCreate' calls are
- /// made to notify the new dispatcher of all the eventSources that existed before the EventListener was
- /// created.
- /// </para>
- /// </summary>
- public class EventListener : IDisposable
- {
- private event EventHandler<EventSourceCreatedEventArgs> _EventSourceCreated;
-
- /// <summary>
- /// This event is raised whenever a new eventSource is 'attached' to the dispatcher.
- /// This can happen for all existing EventSources when the EventListener is created
- /// as well as for any EventSources that come into existence after the EventListener
- /// has been created.
- ///
- /// These 'catch up' events are called during the construction of the EventListener.
- /// Subclasses need to be prepared for that.
- ///
- /// In a multi-threaded environment, it is possible that 'EventSourceEventWrittenCallback'
- /// events for a particular eventSource to occur BEFORE the EventSourceCreatedCallback is issued.
- /// </summary>
- public event EventHandler<EventSourceCreatedEventArgs> EventSourceCreated
- {
- add
- {
- CallBackForExistingEventSources(false, value);
-
- this._EventSourceCreated = (EventHandler<EventSourceCreatedEventArgs>)Delegate.Combine(_EventSourceCreated, value);
- }
- remove
- {
- this._EventSourceCreated = (EventHandler<EventSourceCreatedEventArgs>)Delegate.Remove(_EventSourceCreated, value);
- }
- }
-
- /// <summary>
- /// This event is raised whenever an event has been written by a EventSource for which
- /// the EventListener has enabled events.
- /// </summary>
- public event EventHandler<EventWrittenEventArgs> EventWritten;
-
- /// <summary>
- /// Create a new EventListener in which all events start off turned off (use EnableEvents to turn
- /// them on).
- /// </summary>
- public EventListener()
- {
- // This will cause the OnEventSourceCreated callback to fire.
- CallBackForExistingEventSources(true, (obj, args) => args.EventSource.AddListener((EventListener)obj));
- }
-
- /// <summary>
- /// Dispose should be called when the EventListener no longer desires 'OnEvent*' callbacks. Because
- /// there is an internal list of strong references to all EventListeners, calling 'Dispose' directly
- /// is the only way to actually make the listen die. Thus it is important that users of EventListener
- /// call Dispose when they are done with their logging.
- /// </summary>
-#if ES_BUILD_STANDALONE
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly")]
-#endif
- public virtual void Dispose()
- {
- lock (EventListenersLock)
- {
- if (s_Listeners != null)
- {
- if (this == s_Listeners)
- {
- EventListener cur = s_Listeners;
- s_Listeners = this.m_Next;
- RemoveReferencesToListenerInEventSources(cur);
- }
- else
- {
- // Find 'this' from the s_Listeners linked list.
- EventListener prev = s_Listeners;
- for (;;)
- {
- EventListener cur = prev.m_Next;
- if (cur == null)
- break;
- if (cur == this)
- {
- // Found our Listener, remove references to to it in the eventSources
- prev.m_Next = cur.m_Next; // Remove entry.
- RemoveReferencesToListenerInEventSources(cur);
- break;
- }
- prev = cur;
- }
- }
- }
- Validate();
- }
- }
- // We don't expose a Dispose(bool), because the contract is that you don't have any non-syncronous
- // 'cleanup' associated with this object
-
- /// <summary>
- /// Enable all events from the eventSource identified by 'eventSource' to the current
- /// dispatcher that have a verbosity level of 'level' or lower.
- ///
- /// This call can have the effect of REDUCING the number of events sent to the
- /// dispatcher if 'level' indicates a less verbose level than was previously enabled.
- ///
- /// This call never has an effect on other EventListeners.
- ///
- /// </summary>
- public void EnableEvents(EventSource eventSource, EventLevel level)
- {
- EnableEvents(eventSource, level, EventKeywords.None);
- }
- /// <summary>
- /// Enable all events from the eventSource identified by 'eventSource' to the current
- /// dispatcher that have a verbosity level of 'level' or lower and have a event keyword
- /// matching any of the bits in 'matchAnyKeyword'.
- ///
- /// This call can have the effect of REDUCING the number of events sent to the
- /// dispatcher if 'level' indicates a less verbose level than was previously enabled or
- /// if 'matchAnyKeyword' has fewer keywords set than where previously set.
- ///
- /// This call never has an effect on other EventListeners.
- /// </summary>
- public void EnableEvents(EventSource eventSource, EventLevel level, EventKeywords matchAnyKeyword)
- {
- EnableEvents(eventSource, level, matchAnyKeyword, null);
- }
- /// <summary>
- /// Enable all events from the eventSource identified by 'eventSource' to the current
- /// dispatcher that have a verbosity level of 'level' or lower and have a event keyword
- /// matching any of the bits in 'matchAnyKeyword' as well as any (eventSource specific)
- /// effect passing additional 'key-value' arguments 'arguments' might have.
- ///
- /// This call can have the effect of REDUCING the number of events sent to the
- /// dispatcher if 'level' indicates a less verbose level than was previously enabled or
- /// if 'matchAnyKeyword' has fewer keywords set than where previously set.
- ///
- /// This call never has an effect on other EventListeners.
- /// </summary>
- public void EnableEvents(EventSource eventSource, EventLevel level, EventKeywords matchAnyKeyword, IDictionary<string, string> arguments)
- {
- if (eventSource == null)
- {
- throw new ArgumentNullException(nameof(eventSource));
- }
- Contract.EndContractBlock();
-
- eventSource.SendCommand(this, 0, 0, EventCommand.Update, true, level, matchAnyKeyword, arguments);
- }
- /// <summary>
- /// Disables all events coming from eventSource identified by 'eventSource'.
- ///
- /// This call never has an effect on other EventListeners.
- /// </summary>
- public void DisableEvents(EventSource eventSource)
- {
- if (eventSource == null)
- {
- throw new ArgumentNullException(nameof(eventSource));
- }
- Contract.EndContractBlock();
-
- eventSource.SendCommand(this, 0, 0, EventCommand.Update, false, EventLevel.LogAlways, EventKeywords.None, null);
- }
-
- /// <summary>
- /// EventSourceIndex is small non-negative integer (suitable for indexing in an array)
- /// identifying EventSource. It is unique per-appdomain. Some EventListeners might find
- /// it useful to store additional information about each eventSource connected to it,
- /// and EventSourceIndex allows this extra information to be efficiently stored in a
- /// (growable) array (eg List(T)).
- /// </summary>
- public static int EventSourceIndex(EventSource eventSource) { return eventSource.m_id; }
-
- /// <summary>
- /// This method is called whenever a new eventSource is 'attached' to the dispatcher.
- /// This can happen for all existing EventSources when the EventListener is created
- /// as well as for any EventSources that come into existence after the EventListener
- /// has been created.
- ///
- /// These 'catch up' events are called during the construction of the EventListener.
- /// Subclasses need to be prepared for that.
- ///
- /// In a multi-threaded environment, it is possible that 'OnEventWritten' callbacks
- /// for a particular eventSource to occur BEFORE the OnEventSourceCreated is issued.
- /// </summary>
- /// <param name="eventSource"></param>
- internal protected virtual void OnEventSourceCreated(EventSource eventSource)
- {
- EventHandler<EventSourceCreatedEventArgs> callBack = this._EventSourceCreated;
- if (callBack != null)
- {
- EventSourceCreatedEventArgs args = new EventSourceCreatedEventArgs();
- args.EventSource = eventSource;
- callBack(this, args);
- }
- }
-
- /// <summary>
- /// This method is called whenever an event has been written by a EventSource for which
- /// the EventListener has enabled events.
- /// </summary>
- /// <param name="eventData"></param>
- internal protected virtual void OnEventWritten(EventWrittenEventArgs eventData)
- {
- EventHandler<EventWrittenEventArgs> callBack = this.EventWritten;
- if (callBack != null)
- {
- callBack(this, eventData);
- }
- }
-
-
- #region private
- /// <summary>
- /// This routine adds newEventSource to the global list of eventSources, it also assigns the
- /// ID to the eventSource (which is simply the ordinal in the global list).
- ///
- /// EventSources currently do not pro-actively remove themselves from this list. Instead
- /// when eventSources's are GCed, the weak handle in this list naturally gets nulled, and
- /// we will reuse the slot. Today this list never shrinks (but we do reuse entries
- /// that are in the list). This seems OK since the expectation is that EventSources
- /// tend to live for the lifetime of the appdomain anyway (they tend to be used in
- /// global variables).
- /// </summary>
- /// <param name="newEventSource"></param>
- internal static void AddEventSource(EventSource newEventSource)
- {
- lock (EventListenersLock)
- {
- if (s_EventSources == null)
- s_EventSources = new List<WeakReference>(2);
-
- if (!s_EventSourceShutdownRegistered)
- {
- s_EventSourceShutdownRegistered = true;
- }
-
-
- // Periodically search the list for existing entries to reuse, this avoids
- // unbounded memory use if we keep recycling eventSources (an unlikely thing).
- int newIndex = -1;
- if (s_EventSources.Count % 64 == 63) // on every block of 64, fill up the block before continuing
- {
- int i = s_EventSources.Count; // Work from the top down.
- while (0 < i)
- {
- --i;
- WeakReference weakRef = s_EventSources[i];
- if (!weakRef.IsAlive)
- {
- newIndex = i;
- weakRef.Target = newEventSource;
- break;
- }
- }
- }
- if (newIndex < 0)
- {
- newIndex = s_EventSources.Count;
- s_EventSources.Add(new WeakReference(newEventSource));
- }
- newEventSource.m_id = newIndex;
-
- // Add every existing dispatcher to the new EventSource
- for (EventListener listener = s_Listeners; listener != null; listener = listener.m_Next)
- newEventSource.AddListener(listener);
-
- Validate();
- }
- }
-
- // Whenver we have async callbacks from native code, there is an ugly issue where
- // during .NET shutdown native code could be calling the callback, but the CLR
- // has already prohibited callbacks to managed code in the appdomain, causing the CLR
- // to throw a COMPLUS_BOOT_EXCEPTION. The guideline we give is that you must unregister
- // such callbacks on process shutdown or appdomain so that unmanaged code will never
- // do this. This is what this callback is for.
- // See bug 724140 for more
- private static void DisposeOnShutdown(object sender, EventArgs e)
- {
- lock (EventListenersLock)
- {
- foreach (var esRef in s_EventSources)
- {
- EventSource es = esRef.Target as EventSource;
- if (es != null)
- es.Dispose();
- }
- }
- }
-
- /// <summary>
- /// Helper used in code:Dispose that removes any references to 'listenerToRemove' in any of the
- /// eventSources in the appdomain.
- ///
- /// The EventListenersLock must be held before calling this routine.
- /// </summary>
- private static void RemoveReferencesToListenerInEventSources(EventListener listenerToRemove)
- {
-#if !ES_BUILD_STANDALONE
- Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
-#endif
- // Foreach existing EventSource in the appdomain
- foreach (WeakReference eventSourceRef in s_EventSources)
- {
- EventSource eventSource = eventSourceRef.Target as EventSource;
- if (eventSource != null)
- {
- // Is the first output dispatcher the dispatcher we are removing?
- if (eventSource.m_Dispatchers.m_Listener == listenerToRemove)
- eventSource.m_Dispatchers = eventSource.m_Dispatchers.m_Next;
- else
- {
- // Remove 'listenerToRemove' from the eventSource.m_Dispatchers linked list.
- EventDispatcher prev = eventSource.m_Dispatchers;
- for (;;)
- {
- EventDispatcher cur = prev.m_Next;
- if (cur == null)
- {
- Debug.Assert(false, "EventSource did not have a registered EventListener!");
- break;
- }
- if (cur.m_Listener == listenerToRemove)
- {
- prev.m_Next = cur.m_Next; // Remove entry.
- break;
- }
- prev = cur;
- }
- }
- }
- }
- }
-
- /// <summary>
- /// Checks internal consistency of EventSources/Listeners.
- /// </summary>
- [Conditional("DEBUG")]
- internal static void Validate()
- {
- lock (EventListenersLock)
- {
- // Get all listeners
- Dictionary<EventListener, bool> allListeners = new Dictionary<EventListener, bool>();
- EventListener cur = s_Listeners;
- while (cur != null)
- {
- allListeners.Add(cur, true);
- cur = cur.m_Next;
- }
-
- // For all eventSources
- int id = -1;
- foreach (WeakReference eventSourceRef in s_EventSources)
- {
- id++;
- EventSource eventSource = eventSourceRef.Target as EventSource;
- if (eventSource == null)
- continue;
- Debug.Assert(eventSource.m_id == id, "Unexpected event source ID.");
-
- // None listeners on eventSources exist in the dispatcher list.
- EventDispatcher dispatcher = eventSource.m_Dispatchers;
- while (dispatcher != null)
- {
- Debug.Assert(allListeners.ContainsKey(dispatcher.m_Listener), "EventSource has a listener not on the global list.");
- dispatcher = dispatcher.m_Next;
- }
-
- // Every dispatcher is on Dispatcher List of every eventSource.
- foreach (EventListener listener in allListeners.Keys)
- {
- dispatcher = eventSource.m_Dispatchers;
- for (;;)
- {
- Debug.Assert(dispatcher != null, "Listener is not on all eventSources.");
- if (dispatcher.m_Listener == listener)
- break;
- dispatcher = dispatcher.m_Next;
- }
- }
- }
- }
- }
-
- /// <summary>
- /// Gets a global lock that is intended to protect the code:s_Listeners linked list and the
- /// code:s_EventSources WeakReference list. (We happen to use the s_EventSources list as
- /// the lock object)
- /// </summary>
- internal static object EventListenersLock
- {
- get
- {
- if (s_EventSources == null)
- Interlocked.CompareExchange(ref s_EventSources, new List<WeakReference>(2), null);
- return s_EventSources;
- }
- }
-
- private void CallBackForExistingEventSources(bool addToListenersList, EventHandler<EventSourceCreatedEventArgs> callback)
- {
- lock (EventListenersLock)
- {
- // Disallow creating EventListener reentrancy.
- if (s_CreatingListener)
- {
- throw new InvalidOperationException(Resources.GetResourceString("EventSource_ListenerCreatedInsideCallback"));
- }
-
- try
- {
- s_CreatingListener = true;
-
- if (addToListenersList)
- {
- // Add to list of listeners in the system, do this BEFORE firing the 'OnEventSourceCreated' so that
- // Those added sources see this listener.
- this.m_Next = s_Listeners;
- s_Listeners = this;
- }
-
- // Find all existing eventSources call OnEventSourceCreated to 'catchup'
- // Note that we DO have reentrancy here because 'AddListener' calls out to user code (via OnEventSourceCreated callback)
- // We tolerate this by iterating over a copy of the list here. New event sources will take care of adding listeners themselves
- // EventSources are not guaranteed to be added at the end of the s_EventSource list -- We re-use slots when a new source
- // is created.
- WeakReference[] eventSourcesSnapshot = s_EventSources.ToArray();
-
- for (int i = 0; i < eventSourcesSnapshot.Length; i++)
- {
- WeakReference eventSourceRef = eventSourcesSnapshot[i];
- EventSource eventSource = eventSourceRef.Target as EventSource;
- if (eventSource != null)
- {
- EventSourceCreatedEventArgs args = new EventSourceCreatedEventArgs();
- args.EventSource = eventSource;
- callback(this, args);
- }
- }
-
- Validate();
- }
- finally
- {
- s_CreatingListener = false;
- }
- }
-
- }
-
- // Instance fields
- internal volatile EventListener m_Next; // These form a linked list in s_Listeners
-#if FEATURE_ACTIVITYSAMPLING
- internal ActivityFilter m_activityFilter; // If we are filtering by activity on this Listener, this keeps track of it.
-#endif // FEATURE_ACTIVITYSAMPLING
-
- // static fields
-
- /// <summary>
- /// The list of all listeners in the appdomain. Listeners must be explicitly disposed to remove themselves
- /// from this list. Note that EventSources point to their listener but NOT the reverse.
- /// </summary>
- internal static EventListener s_Listeners;
- /// <summary>
- /// The list of all active eventSources in the appdomain. Note that eventSources do NOT
- /// remove themselves from this list this is a weak list and the GC that removes them may
- /// not have happened yet. Thus it can contain event sources that are dead (thus you have
- /// to filter those out.
- /// </summary>
- internal static List<WeakReference> s_EventSources;
-
- /// <summary>
- /// Used to disallow reentrancy.
- /// </summary>
- private static bool s_CreatingListener = false;
-
- /// <summary>
- /// Used to register AD/Process shutdown callbacks.
- /// </summary>
- private static bool s_EventSourceShutdownRegistered = false;
- #endregion
- }
-
- /// <summary>
- /// Passed to the code:EventSource.OnEventCommand callback
- /// </summary>
- public class EventCommandEventArgs : EventArgs
- {
- /// <summary>
- /// Gets the command for the callback.
- /// </summary>
- public EventCommand Command { get; internal set; }
-
- /// <summary>
- /// Gets the arguments for the callback.
- /// </summary>
- public IDictionary<String, String> Arguments { get; internal set; }
-
- /// <summary>
- /// Enables the event that has the specified identifier.
- /// </summary>
- /// <param name="eventId">Event ID of event to be enabled</param>
- /// <returns>true if eventId is in range</returns>
- public bool EnableEvent(int eventId)
- {
- if (Command != EventCommand.Enable && Command != EventCommand.Disable)
- throw new InvalidOperationException();
- return eventSource.EnableEventForDispatcher(dispatcher, eventId, true);
- }
-
- /// <summary>
- /// Disables the event that have the specified identifier.
- /// </summary>
- /// <param name="eventId">Event ID of event to be disabled</param>
- /// <returns>true if eventId is in range</returns>
- public bool DisableEvent(int eventId)
- {
- if (Command != EventCommand.Enable && Command != EventCommand.Disable)
- throw new InvalidOperationException();
- return eventSource.EnableEventForDispatcher(dispatcher, eventId, false);
- }
-
- #region private
-
- internal EventCommandEventArgs(EventCommand command, IDictionary<string, string> arguments, EventSource eventSource,
- EventListener listener, int perEventSourceSessionId, int etwSessionId, bool enable, EventLevel level, EventKeywords matchAnyKeyword)
- {
- this.Command = command;
- this.Arguments = arguments;
- this.eventSource = eventSource;
- this.listener = listener;
- this.perEventSourceSessionId = perEventSourceSessionId;
- this.etwSessionId = etwSessionId;
- this.enable = enable;
- this.level = level;
- this.matchAnyKeyword = matchAnyKeyword;
- }
-
- internal EventSource eventSource;
- internal EventDispatcher dispatcher;
-
- // These are the arguments of sendCommand and are only used for deferring commands until after we are fully initialized.
- internal EventListener listener;
- internal int perEventSourceSessionId;
- internal int etwSessionId;
- internal bool enable;
- internal EventLevel level;
- internal EventKeywords matchAnyKeyword;
- internal EventCommandEventArgs nextCommand; // We form a linked list of these deferred commands.
-
- #endregion
- }
-
- /// <summary>
- /// EventSourceCreatedEventArgs is passed to <see cref="EventListener.EventSourceCreated"/>
- /// </summary>
- public class EventSourceCreatedEventArgs : EventArgs
- {
- /// <summary>
- /// The EventSource that is attaching to the listener.
- /// </summary>
- public EventSource EventSource
- {
- get;
- internal set;
- }
- }
-
- /// <summary>
- /// EventWrittenEventArgs is passed to the user-provided override for
- /// <see cref="EventListener.OnEventWritten"/> when an event is fired.
- /// </summary>
- public class EventWrittenEventArgs : EventArgs
- {
- /// <summary>
- /// The name of the event.
- /// </summary>
- public string EventName
- {
- get
- {
- if (m_eventName != null || EventId < 0) // TraceLogging convention EventID == -1
- {
- return m_eventName;
- }
- else
- return m_eventSource.m_eventData[EventId].Name;
- }
- internal set
- {
- m_eventName = value;
- }
- }
-
- /// <summary>
- /// Gets the event ID for the event that was written.
- /// </summary>
- public int EventId { get; internal set; }
-
- /// <summary>
- /// Gets the activity ID for the thread on which the event was written.
- /// </summary>
- public Guid ActivityId
- {
- get { return EventSource.CurrentThreadActivityId; }
- }
-
- /// <summary>
- /// Gets the related activity ID if one was specified when the event was written.
- /// </summary>
- public Guid RelatedActivityId
- {
- get;
- internal set;
- }
-
- /// <summary>
- /// Gets the payload for the event.
- /// </summary>
- public ReadOnlyCollection<Object> Payload { get; internal set; }
-
- /// <summary>
- /// Gets the payload argument names.
- /// </summary>
- public ReadOnlyCollection<string> PayloadNames
- {
- get
- {
- // For contract based events we create the list lazily.
- if (m_payloadNames == null)
- {
- // Self described events are identified by id -1.
- Debug.Assert(EventId != -1);
-
- var names = new List<string>();
- foreach (var parameter in m_eventSource.m_eventData[EventId].Parameters)
- {
- names.Add(parameter.Name);
- }
- m_payloadNames = new ReadOnlyCollection<string>(names);
- }
-
- return m_payloadNames;
- }
-
- internal set
- {
- m_payloadNames = value;
- }
- }
-
- /// <summary>
- /// Gets the event source object.
- /// </summary>
- public EventSource EventSource { get { return m_eventSource; } }
-
- /// <summary>
- /// Gets the keywords for the event.
- /// </summary>
- public EventKeywords Keywords
- {
- get
- {
- if (EventId < 0) // TraceLogging convention EventID == -1
- return m_keywords;
-
- return (EventKeywords)m_eventSource.m_eventData[EventId].Descriptor.Keywords;
- }
- }
-
- /// <summary>
- /// Gets the operation code for the event.
- /// </summary>
- public EventOpcode Opcode
- {
- get
- {
- if (EventId <= 0) // TraceLogging convention EventID == -1
- return m_opcode;
- return (EventOpcode)m_eventSource.m_eventData[EventId].Descriptor.Opcode;
- }
- }
-
- /// <summary>
- /// Gets the task for the event.
- /// </summary>
- public EventTask Task
- {
- get
- {
- if (EventId <= 0) // TraceLogging convention EventID == -1
- return EventTask.None;
-
- return (EventTask)m_eventSource.m_eventData[EventId].Descriptor.Task;
- }
- }
-
- /// <summary>
- /// Any provider/user defined options associated with the event.
- /// </summary>
- public EventTags Tags
- {
- get
- {
- if (EventId <= 0) // TraceLogging convention EventID == -1
- return m_tags;
- return m_eventSource.m_eventData[EventId].Tags;
- }
- }
-
- /// <summary>
- /// Gets the message for the event. If the message has {N} parameters they are NOT substituted.
- /// </summary>
- public string Message
- {
- get
- {
- if (EventId <= 0) // TraceLogging convention EventID == -1
- return m_message;
- else
- return m_eventSource.m_eventData[EventId].Message;
- }
- internal set
- {
- m_message = value;
- }
- }
-
-
-#if FEATURE_MANAGED_ETW_CHANNELS
- /// <summary>
- /// Gets the channel for the event.
- /// </summary>
- public EventChannel Channel
- {
- get
- {
- if (EventId <= 0) // TraceLogging convention EventID == -1
- return EventChannel.None;
- return (EventChannel)m_eventSource.m_eventData[EventId].Descriptor.Channel;
- }
- }
-#endif
-
- /// <summary>
- /// Gets the version of the event.
- /// </summary>
- public byte Version
- {
- get
- {
- if (EventId <= 0) // TraceLogging convention EventID == -1
- return 0;
- return m_eventSource.m_eventData[EventId].Descriptor.Version;
- }
- }
-
- /// <summary>
- /// Gets the level for the event.
- /// </summary>
- public EventLevel Level
- {
- get
- {
- if (EventId <= 0) // TraceLogging convention EventID == -1
- return m_level;
- return (EventLevel)m_eventSource.m_eventData[EventId].Descriptor.Level;
- }
- }
-
- #region private
- internal EventWrittenEventArgs(EventSource eventSource)
- {
- m_eventSource = eventSource;
- }
- private string m_message;
- private string m_eventName;
- private EventSource m_eventSource;
- private ReadOnlyCollection<string> m_payloadNames;
- internal EventTags m_tags;
- internal EventOpcode m_opcode;
- internal EventLevel m_level;
- internal EventKeywords m_keywords;
- #endregion
- }
-
- /// <summary>
- /// Allows customizing defaults and specifying localization support for the event source class to which it is applied.
- /// </summary>
- [AttributeUsage(AttributeTargets.Class)]
- public sealed class EventSourceAttribute : Attribute
- {
- /// <summary>
- /// Overrides the ETW name of the event source (which defaults to the class name)
- /// </summary>
- public string Name { get; set; }
-
- /// <summary>
- /// Overrides the default (calculated) Guid of an EventSource type. Explicitly defining a GUID is discouraged,
- /// except when upgrading existing ETW providers to using event sources.
- /// </summary>
- public string Guid { get; set; }
-
- /// <summary>
- /// <para>
- /// EventSources support localization of events. The names used for events, opcodes, tasks, keywords and maps
- /// can be localized to several languages if desired. This works by creating a ResX style string table
- /// (by simply adding a 'Resource File' to your project). This resource file is given a name e.g.
- /// 'DefaultNameSpace.ResourceFileName' which can be passed to the ResourceManager constructor to read the
- /// resources. This name is the value of the LocalizationResources property.
- /// </para><para>
- /// If LocalizationResources property is non-null, then EventSource will look up the localized strings for events by
- /// using the following resource naming scheme
- /// </para>
- /// <para>* event_EVENTNAME</para>
- /// <para>* task_TASKNAME</para>
- /// <para>* keyword_KEYWORDNAME</para>
- /// <para>* map_MAPNAME</para>
- /// <para>
- /// where the capitalized name is the name of the event, task, keyword, or map value that should be localized.
- /// Note that the localized string for an event corresponds to the Message string, and can have {0} values
- /// which represent the payload values.
- /// </para>
- /// </summary>
- public string LocalizationResources { get; set; }
- }
-
- /// <summary>
- /// Any instance methods in a class that subclasses <see cref="EventSource"/> and that return void are
- /// assumed by default to be methods that generate an ETW event. Enough information can be deduced from the
- /// name of the method and its signature to generate basic schema information for the event. The
- /// <see cref="EventAttribute"/> class allows you to specify additional event schema information for an event if
- /// desired.
- /// </summary>
- [AttributeUsage(AttributeTargets.Method)]
- public sealed class EventAttribute : Attribute
- {
- /// <summary>Construct an EventAttribute with specified eventId</summary>
- /// <param name="eventId">ID of the ETW event (an integer between 1 and 65535)</param>
- public EventAttribute(int eventId) { this.EventId = eventId; Level = EventLevel.Informational; this.m_opcodeSet = false; }
- /// <summary>Event's ID</summary>
- public int EventId { get; private set; }
- /// <summary>Event's severity level: indicates the severity or verbosity of the event</summary>
- public EventLevel Level { get; set; }
- /// <summary>Event's keywords: allows classification of events by "categories"</summary>
- public EventKeywords Keywords { get; set; }
- /// <summary>Event's operation code: allows defining operations, generally used with Tasks</summary>
- public EventOpcode Opcode
- {
- get
- {
- return m_opcode;
- }
- set
- {
- this.m_opcode = value;
- this.m_opcodeSet = true;
- }
- }
-
- internal bool IsOpcodeSet
- {
- get
- {
- return m_opcodeSet;
- }
- }
-
- /// <summary>Event's task: allows logical grouping of events</summary>
- public EventTask Task { get; set; }
-#if FEATURE_MANAGED_ETW_CHANNELS
- /// <summary>Event's channel: defines an event log as an additional destination for the event</summary>
- public EventChannel Channel { get; set; }
-#endif
- /// <summary>Event's version</summary>
- public byte Version { get; set; }
-
- /// <summary>
- /// This can be specified to enable formatting and localization of the event's payload. You can
- /// use standard .NET substitution operators (eg {1}) in the string and they will be replaced
- /// with the 'ToString()' of the corresponding part of the event payload.
- /// </summary>
- public string Message { get; set; }
-
- /// <summary>
- /// User defined options associated with the event. These do not have meaning to the EventSource but
- /// are passed through to listeners which given them semantics.
- /// </summary>
- public EventTags Tags { get; set; }
-
- /// <summary>
- /// Allows fine control over the Activity IDs generated by start and stop events
- /// </summary>
- public EventActivityOptions ActivityOptions { get; set; }
-
- #region private
- EventOpcode m_opcode;
- private bool m_opcodeSet;
- #endregion
- }
-
- /// <summary>
- /// By default all instance methods in a class that subclasses code:EventSource that and return
- /// void are assumed to be methods that generate an event. This default can be overridden by specifying
- /// the code:NonEventAttribute
- /// </summary>
- [AttributeUsage(AttributeTargets.Method)]
- public sealed class NonEventAttribute : Attribute
- {
- /// <summary>
- /// Constructs a default NonEventAttribute
- /// </summary>
- public NonEventAttribute() { }
- }
-
- // FUTURE we may want to expose this at some point once we have a partner that can help us validate the design.
-#if FEATURE_MANAGED_ETW_CHANNELS
- /// <summary>
- /// EventChannelAttribute allows customizing channels supported by an EventSource. This attribute must be
- /// applied to an member of type EventChannel defined in a Channels class nested in the EventSource class:
- /// <code>
- /// public static class Channels
- /// {
- /// [Channel(Enabled = true, EventChannelType = EventChannelType.Admin)]
- /// public const EventChannel Admin = (EventChannel)16;
- ///
- /// [Channel(Enabled = false, EventChannelType = EventChannelType.Operational)]
- /// public const EventChannel Operational = (EventChannel)17;
- /// }
- /// </code>
- /// </summary>
- [AttributeUsage(AttributeTargets.Field)]
-#if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
- public
-#endif
- class EventChannelAttribute : Attribute
- {
- /// <summary>
- /// Specified whether the channel is enabled by default
- /// </summary>
- public bool Enabled { get; set; }
-
- /// <summary>
- /// Legal values are in EventChannelType
- /// </summary>
- public EventChannelType EventChannelType { get; set; }
-
-#if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
- /// <summary>
- /// Specifies the isolation for the channel
- /// </summary>
- public EventChannelIsolation Isolation { get; set; }
-
- /// <summary>
- /// Specifies an SDDL access descriptor that controls access to the log file that backs the channel.
- /// See MSDN ((http://msdn.microsoft.com/en-us/library/windows/desktop/aa382741.aspx) for details.
- /// </summary>
- public string Access { get; set; }
-
- /// <summary>
- /// Allows importing channels defined in external manifests
- /// </summary>
- public string ImportChannel { get; set; }
-#endif
-
- // TODO: there is a convention that the name is the Provider/Type Should we provide an override?
- // public string Name { get; set; }
- }
-
- /// <summary>
- /// Allowed channel types
- /// </summary>
-#if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
- public
-#endif
- enum EventChannelType
- {
- /// <summary>The admin channel</summary>
- Admin = 1,
- /// <summary>The operational channel</summary>
- Operational,
- /// <summary>The Analytic channel</summary>
- Analytic,
- /// <summary>The debug channel</summary>
- Debug,
- }
-
-#if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
- /// <summary>
- /// Allowed isolation levels. See MSDN (http://msdn.microsoft.com/en-us/library/windows/desktop/aa382741.aspx)
- /// for the default permissions associated with each level. EventChannelIsolation and Access allows control over the
- /// access permissions for the channel and backing file.
- /// </summary>
- public
- enum EventChannelIsolation
- {
- /// <summary>
- /// This is the default isolation level. All channels that specify Application isolation use the same ETW session
- /// </summary>
- Application = 1,
- /// <summary>
- /// All channels that specify System isolation use the same ETW session
- /// </summary>
- System,
- /// <summary>
- /// Use sparingly! When specifying Custom isolation, a separate ETW session is created for the channel.
- /// Using Custom isolation lets you control the access permissions for the channel and backing file.
- /// Because there are only 64 ETW sessions available, you should limit your use of Custom isolation.
- /// </summary>
- Custom,
- }
-#endif
-#endif
-
- /// <summary>
- /// Describes the pre-defined command (EventCommandEventArgs.Command property) that is passed to the OnEventCommand callback.
- /// </summary>
- public enum EventCommand
- {
- /// <summary>
- /// Update EventSource state
- /// </summary>
- Update = 0,
- /// <summary>
- /// Request EventSource to generate and send its manifest
- /// </summary>
- SendManifest = -1,
- /// <summary>
- /// Enable event
- /// </summary>
- Enable = -2,
- /// <summary>
- /// Disable event
- /// </summary>
- Disable = -3
- };
-
-
- #region private classes
-
-#if FEATURE_ACTIVITYSAMPLING
-
- /// <summary>
- /// ActivityFilter is a helper structure that is used to keep track of run-time state
- /// associated with activity filtering. It is 1-1 with EventListeners (logically
- /// every listener has one of these, however we actually allocate them lazily), as well
- /// as 1-to-1 with tracing-aware EtwSessions.
- ///
- /// This structure also keeps track of the sampling counts associated with 'trigger'
- /// events. Because these trigger events are rare, and you typically only have one of
- /// them, we store them here as a linked list.
- /// </summary>
- internal sealed class ActivityFilter : IDisposable
- {
- /// <summary>
- /// Disable all activity filtering for the listener associated with 'filterList',
- /// (in the session associated with it) that is triggered by any event in 'source'.
- /// </summary>
- public static void DisableFilter(ref ActivityFilter filterList, EventSource source)
- {
-#if !ES_BUILD_STANDALONE
- Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
-#endif
-
- if (filterList == null)
- return;
-
- ActivityFilter cur;
- // Remove it from anywhere in the list (except the first element, which has to
- // be treated specially)
- ActivityFilter prev = filterList;
- cur = prev.m_next;
- while (cur != null)
- {
- if (cur.m_providerGuid == source.Guid)
- {
- // update TriggersActivityTracking bit
- if (cur.m_eventId >= 0 && cur.m_eventId < source.m_eventData.Length)
- --source.m_eventData[cur.m_eventId].TriggersActivityTracking;
-
- // Remove it from the linked list.
- prev.m_next = cur.m_next;
- // dispose of the removed node
- cur.Dispose();
- // update cursor
- cur = prev.m_next;
- }
- else
- {
- // update cursors
- prev = cur;
- cur = prev.m_next;
- }
- }
-
- // Sadly we have to treat the first element specially in linked list removal in C#
- if (filterList.m_providerGuid == source.Guid)
- {
- // update TriggersActivityTracking bit
- if (filterList.m_eventId >= 0 && filterList.m_eventId < source.m_eventData.Length)
- --source.m_eventData[filterList.m_eventId].TriggersActivityTracking;
-
- // We are the first element in the list.
- var first = filterList;
- filterList = first.m_next;
- // dispose of the removed node
- first.Dispose();
- }
- // the above might have removed the one ActivityFilter in the session that contains the
- // cleanup delegate; re-create the delegate if needed
- if (filterList != null)
- {
- EnsureActivityCleanupDelegate(filterList);
- }
- }
-
- /// <summary>
- /// Currently this has "override" semantics. We first disable all filters
- /// associated with 'source', and next we add new filters for each entry in the
- /// string 'startEvents'. participateInSampling specifies whether non-startEvents
- /// always trigger or only trigger when current activity is 'active'.
- /// </summary>
- public static void UpdateFilter(
- ref ActivityFilter filterList,
- EventSource source,
- int perEventSourceSessionId,
- string startEvents)
- {
-#if !ES_BUILD_STANDALONE
- Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
-#endif
-
- // first remove all filters associated with 'source'
- DisableFilter(ref filterList, source);
-
- if (!string.IsNullOrEmpty(startEvents))
- {
- // ActivitySamplingStartEvents is a space-separated list of Event:Frequency pairs.
- // The Event may be specified by name or by ID. Errors in parsing such a pair
- // result in the error being reported to the listeners, and the pair being ignored.
- // E.g. "CustomActivityStart:1000 12:10" specifies that for event CustomActivityStart
- // we should initiate activity tracing once every 1000 events, *and* for event ID 12
- // we should initiate activity tracing once every 10 events.
- string[] activityFilterStrings = startEvents.Split(' ');
-
- for (int i = 0; i < activityFilterStrings.Length; ++i)
- {
- string activityFilterString = activityFilterStrings[i];
- int sampleFreq = 1;
- int eventId = -1;
- int colonIdx = activityFilterString.IndexOf(':');
- if (colonIdx < 0)
- {
- source.ReportOutOfBandMessage("ERROR: Invalid ActivitySamplingStartEvent specification: " +
- activityFilterString, false);
- // ignore failure...
- continue;
- }
- string sFreq = activityFilterString.Substring(colonIdx + 1);
- if (!int.TryParse(sFreq, out sampleFreq))
- {
- source.ReportOutOfBandMessage("ERROR: Invalid sampling frequency specification: " + sFreq, false);
- continue;
- }
- activityFilterString = activityFilterString.Substring(0, colonIdx);
- if (!int.TryParse(activityFilterString, out eventId))
- {
- // reset eventId
- eventId = -1;
- // see if it's an event name
- for (int j = 0; j < source.m_eventData.Length; j++)
- {
- EventSource.EventMetadata[] ed = source.m_eventData;
- if (ed[j].Name != null && ed[j].Name.Length == activityFilterString.Length &&
- string.Compare(ed[j].Name, activityFilterString, StringComparison.OrdinalIgnoreCase) == 0)
- {
- eventId = ed[j].Descriptor.EventId;
- break;
- }
- }
- }
- if (eventId < 0 || eventId >= source.m_eventData.Length)
- {
- source.ReportOutOfBandMessage("ERROR: Invalid eventId specification: " + activityFilterString, false);
- continue;
- }
- EnableFilter(ref filterList, source, perEventSourceSessionId, eventId, sampleFreq);
- }
- }
- }
-
- /// <summary>
- /// Returns the first ActivityFilter from 'filterList' corresponding to 'source'.
- /// </summary>
- public static ActivityFilter GetFilter(ActivityFilter filterList, EventSource source)
- {
- for (var af = filterList; af != null; af = af.m_next)
- {
- if (af.m_providerGuid == source.Guid && af.m_samplingFreq != -1)
- return af;
- }
- return null;
- }
-
- /// <summary>
- /// Returns a session mask representing all sessions in which the activity
- /// associated with the current thread is allowed through the activity filter.
- /// If 'triggeringEvent' is true the event MAY be a triggering event. Ideally
- /// most of the time this is false as you can guarentee this event is NOT a
- /// triggering event. If 'triggeringEvent' is true, then it checks the
- /// 'EventSource' and 'eventID' of the event being logged to see if it is actually
- /// a trigger. If so it activates the current activity.
- ///
- /// If 'childActivityID' is present, it will be added to the active set if the
- /// current activity is active.
- /// </summary>
- unsafe public static bool PassesActivityFilter(
- ActivityFilter filterList,
- Guid* childActivityID,
- bool triggeringEvent,
- EventSource source,
- int eventId)
- {
- Debug.Assert(filterList != null && filterList.m_activeActivities != null);
- bool shouldBeLogged = false;
- if (triggeringEvent)
- {
- for (ActivityFilter af = filterList; af != null; af = af.m_next)
- {
- if (eventId == af.m_eventId && source.Guid == af.m_providerGuid)
- {
- // Update the sampling count with wrap-around
- int curSampleCount, newSampleCount;
- do
- {
- curSampleCount = af.m_curSampleCount;
- if (curSampleCount <= 1)
- newSampleCount = af.m_samplingFreq; // Wrap around, counting down to 1
- else
- newSampleCount = curSampleCount - 1;
- }
- while (Interlocked.CompareExchange(ref af.m_curSampleCount, newSampleCount, curSampleCount) != curSampleCount);
- // If we hit zero, then start tracking the activity.
- if (curSampleCount <= 1)
- {
- Guid currentActivityId = EventSource.InternalCurrentThreadActivityId;
- Tuple<Guid, int> startId;
- // only add current activity if it's not already a root activity
- if (!af.m_rootActiveActivities.TryGetValue(currentActivityId, out startId))
- {
- // EventSource.OutputDebugString(string.Format(" PassesAF - Triggering(session {0}, evt {1})", af.m_perEventSourceSessionId, eventId));
- shouldBeLogged = true;
- af.m_activeActivities[currentActivityId] = Environment.TickCount;
- af.m_rootActiveActivities[currentActivityId] = Tuple.Create(source.Guid, eventId);
- }
- }
- else
- {
- // a start event following a triggering start event
- Guid currentActivityId = EventSource.InternalCurrentThreadActivityId;
- Tuple<Guid, int> startId;
- // only remove current activity if we added it
- if (af.m_rootActiveActivities.TryGetValue(currentActivityId, out startId) &&
- startId.Item1 == source.Guid && startId.Item2 == eventId)
- {
- // EventSource.OutputDebugString(string.Format("Activity dying: {0} -> StartEvent({1})", currentActivityId, eventId));
- // remove activity only from current logging scope (af)
- int dummy;
- af.m_activeActivities.TryRemove(currentActivityId, out dummy);
- }
- }
- break;
- }
- }
- }
-
- var activeActivities = GetActiveActivities(filterList);
- if (activeActivities != null)
- {
- // if we hadn't already determined this should be logged, test further
- if (!shouldBeLogged)
- {
- shouldBeLogged = !activeActivities.IsEmpty &&
- activeActivities.ContainsKey(EventSource.InternalCurrentThreadActivityId);
- }
- if (shouldBeLogged && childActivityID != null &&
- ((EventOpcode)source.m_eventData[eventId].Descriptor.Opcode == EventOpcode.Send))
- {
- FlowActivityIfNeeded(filterList, null, childActivityID);
- // EventSource.OutputDebugString(string.Format(" PassesAF - activity {0}", *childActivityID));
- }
- }
- // EventSource.OutputDebugString(string.Format(" PassesAF - shouldBeLogged(evt {0}) = {1:x}", eventId, shouldBeLogged));
- return shouldBeLogged;
- }
-
- public static bool IsCurrentActivityActive(ActivityFilter filterList)
- {
- var activeActivities = GetActiveActivities(filterList);
- if (activeActivities != null &&
- activeActivities.ContainsKey(EventSource.InternalCurrentThreadActivityId))
- return true;
-
- return false;
- }
-
- /// <summary>
- /// For the EventListener/EtwSession associated with 'filterList', add 'childActivityid'
- /// to list of active activities IF 'currentActivityId' is also active. Passing in a null
- /// value for 'currentActivityid' is an indication tha caller has already verified
- /// that the current activity is active.
- /// </summary>
- unsafe public static void FlowActivityIfNeeded(ActivityFilter filterList, Guid* currentActivityId, Guid* childActivityID)
- {
- Debug.Assert(childActivityID != null);
-
- var activeActivities = GetActiveActivities(filterList);
- Debug.Assert(activeActivities != null);
-
- // take currentActivityId == null to mean we *know* the current activity is "active"
- if (currentActivityId != null && !activeActivities.ContainsKey(*currentActivityId))
- return;
-
- if (activeActivities.Count > MaxActivityTrackCount)
- {
- TrimActiveActivityStore(activeActivities);
- // make sure current activity is still in the set:
- activeActivities[EventSource.InternalCurrentThreadActivityId] = Environment.TickCount;
- }
- // add child activity to list of actives
- activeActivities[*childActivityID] = Environment.TickCount;
-
- }
-
- /// <summary>
- /// </summary>
- public static void UpdateKwdTriggers(ActivityFilter activityFilter, Guid sourceGuid, EventSource source, EventKeywords sessKeywords)
- {
- for (var af = activityFilter; af != null; af = af.m_next)
- {
- if ((sourceGuid == af.m_providerGuid) &&
- (source.m_eventData[af.m_eventId].TriggersActivityTracking > 0 ||
- ((EventOpcode)source.m_eventData[af.m_eventId].Descriptor.Opcode == EventOpcode.Send)))
- {
- // we could be more precise here, if we tracked 'anykeywords' per session
- unchecked
- {
- source.m_keywordTriggers |= (source.m_eventData[af.m_eventId].Descriptor.Keywords & (long)sessKeywords);
- }
- }
- }
- }
-
- /// <summary>
- /// For the EventSource specified by 'sourceGuid' and the EventListener/EtwSession
- /// associated with 'this' ActivityFilter list, return configured sequence of
- /// [eventId, sampleFreq] pairs that defines the sampling policy.
- /// </summary>
- public IEnumerable<Tuple<int, int>> GetFilterAsTuple(Guid sourceGuid)
- {
- for (ActivityFilter af = this; af != null; af = af.m_next)
- {
- if (af.m_providerGuid == sourceGuid)
- yield return Tuple.Create(af.m_eventId, af.m_samplingFreq);
- }
- }
-
- /// <summary>
- /// The cleanup being performed consists of removing the m_myActivityDelegate from
- /// the static s_activityDying, therefore allowing the ActivityFilter to be reclaimed.
- /// </summary>
- public void Dispose()
- {
-#if !ES_BUILD_STANDALONE
- Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
-#endif
- // m_myActivityDelegate is still alive (held by the static EventSource.s_activityDying).
- // Therefore we are ok to take a dependency on m_myActivityDelegate being valid even
- // during the finalization of the ActivityFilter
- if (m_myActivityDelegate != null)
- {
- EventSource.s_activityDying = (Action<Guid>)Delegate.Remove(EventSource.s_activityDying, m_myActivityDelegate);
- m_myActivityDelegate = null;
- }
- }
-
- #region private
-
- /// <summary>
- /// Creates a new ActivityFilter that is triggered by 'eventId' from 'source' ever
- /// 'samplingFreq' times the event fires. You can have several of these forming a
- /// linked list.
- /// </summary>
- private ActivityFilter(EventSource source, int perEventSourceSessionId, int eventId, int samplingFreq, ActivityFilter existingFilter = null)
- {
- m_providerGuid = source.Guid;
- m_perEventSourceSessionId = perEventSourceSessionId;
- m_eventId = eventId;
- m_samplingFreq = samplingFreq;
- m_next = existingFilter;
-
- Debug.Assert(existingFilter == null ||
- (existingFilter.m_activeActivities == null) == (existingFilter.m_rootActiveActivities == null));
-
- // if this is the first filter we add for this session, we need to create a new
- // table of activities. m_activeActivities is common across EventSources in the same
- // session
- ConcurrentDictionary<Guid, int> activeActivities = null;
- if (existingFilter == null ||
- (activeActivities = GetActiveActivities(existingFilter)) == null)
- {
- m_activeActivities = new ConcurrentDictionary<Guid, int>();
- m_rootActiveActivities = new ConcurrentDictionary<Guid, Tuple<Guid, int>>();
-
- // Add a delegate to the 'SetCurrentThreadToActivity callback so that I remove 'dead' activities
- m_myActivityDelegate = GetActivityDyingDelegate(this);
- EventSource.s_activityDying = (Action<Guid>)Delegate.Combine(EventSource.s_activityDying, m_myActivityDelegate);
- }
- else
- {
- m_activeActivities = activeActivities;
- m_rootActiveActivities = existingFilter.m_rootActiveActivities;
- }
-
- }
-
- /// <summary>
- /// Ensure there's at least one ActivityFilter in the 'filterList' that contains an
- /// activity-removing delegate for the listener/session associated with 'filterList'.
- /// </summary>
- private static void EnsureActivityCleanupDelegate(ActivityFilter filterList)
- {
- if (filterList == null)
- return;
-
- for (ActivityFilter af = filterList; af != null; af = af.m_next)
- {
- if (af.m_myActivityDelegate != null)
- return;
- }
-
- // we didn't find a delegate
- filterList.m_myActivityDelegate = GetActivityDyingDelegate(filterList);
- EventSource.s_activityDying = (Action<Guid>)Delegate.Combine(EventSource.s_activityDying, filterList.m_myActivityDelegate);
- }
-
- /// <summary>
- /// Builds the delegate to be called when an activity is dying. This is responsible
- /// for performing whatever cleanup is needed for the ActivityFilter list passed in.
- /// This gets "added" to EventSource.s_activityDying and ends up being called from
- /// EventSource.SetCurrentThreadActivityId and ActivityFilter.PassesActivityFilter.
- /// </summary>
- /// <returns>The delegate to be called when an activity is dying</returns>
- private static Action<Guid> GetActivityDyingDelegate(ActivityFilter filterList)
- {
- return (Guid oldActivity) =>
- {
- int dummy;
- filterList.m_activeActivities.TryRemove(oldActivity, out dummy);
- Tuple<Guid, int> dummyTuple;
- filterList.m_rootActiveActivities.TryRemove(oldActivity, out dummyTuple);
- };
- }
-
- /// <summary>
- /// Enables activity filtering for the listener associated with 'filterList', triggering on
- /// the event 'eventID' from 'source' with a sampling frequency of 'samplingFreq'
- ///
- /// if 'eventID' is out of range (e.g. negative), it means we are not triggering (but we are
- /// activitySampling if something else triggered).
- /// </summary>
- /// <returns>true if activity sampling is enabled the samplingFreq is non-zero </returns>
- private static bool EnableFilter(ref ActivityFilter filterList, EventSource source, int perEventSourceSessionId, int eventId, int samplingFreq)
- {
-#if !ES_BUILD_STANDALONE
- Debug.Assert(Monitor.IsEntered(EventListener.EventListenersLock));
-#endif
- Debug.Assert(samplingFreq > 0);
- Debug.Assert(eventId >= 0);
-
- filterList = new ActivityFilter(source, perEventSourceSessionId, eventId, samplingFreq, filterList);
-
- // Mark the 'quick Check' that indicates this is a trigger event.
- // If eventId is out of range then this mark is not done which has the effect of ignoring
- // the trigger.
- if (0 <= eventId && eventId < source.m_eventData.Length)
- ++source.m_eventData[eventId].TriggersActivityTracking;
-
- return true;
- }
-
- /// <summary>
- /// Normally this code never runs, it is here just to prevent run-away resource usage.
- /// </summary>
- private static void TrimActiveActivityStore(ConcurrentDictionary<Guid, int> activities)
- {
- if (activities.Count > MaxActivityTrackCount)
- {
- // Remove half of the oldest activity ids.
- var keyValues = activities.ToArray();
- var tickNow = Environment.TickCount;
-
- // Sort by age, taking into account wrap-around. As long as x and y are within
- // 23 days of now then (0x7FFFFFFF & (tickNow - x.Value)) is the delta (even if
- // TickCount wraps). I then sort by DESCENDING age. (that is oldest value first)
- Array.Sort(keyValues, (x, y) => (0x7FFFFFFF & (tickNow - y.Value)) - (0x7FFFFFFF & (tickNow - x.Value)));
- for (int i = 0; i < keyValues.Length / 2; i++)
- {
- int dummy;
- activities.TryRemove(keyValues[i].Key, out dummy);
- }
- }
- }
-
- private static ConcurrentDictionary<Guid, int> GetActiveActivities(
- ActivityFilter filterList)
- {
- for (ActivityFilter af = filterList; af != null; af = af.m_next)
- {
- if (af.m_activeActivities != null)
- return af.m_activeActivities;
- }
- return null;
- }
-
- // m_activeActivities always points to the sample dictionary for EVERY ActivityFilter
- // in the m_next list. The 'int' value in the m_activities set is a timestamp
- // (Environment.TickCount) of when the entry was put in the system and is used to
- // remove 'old' entries that if the set gets too big.
- ConcurrentDictionary<Guid, int> m_activeActivities;
-
- // m_rootActiveActivities holds the "root" active activities, i.e. the activities
- // that were marked as active because a Start event fired on them. We need to keep
- // track of these to enable sampling in the scenario of an app's main thread that
- // never explicitly sets distinct activity IDs as it executes. To handle these
- // situations we manufacture a Guid from the thread's ID, and:
- // (a) we consider the firing of a start event when the sampling counter reaches
- // zero to mark the beginning of an interesting activity, and
- // (b) we consider the very next firing of the same start event to mark the
- // ending of that activity.
- // We use a ConcurrentDictionary to avoid taking explicit locks.
- // The key (a guid) represents the activity ID of the root active activity
- // The value is made up of the Guid of the event provider and the eventId of
- // the start event.
- ConcurrentDictionary<Guid, Tuple<Guid, int>> m_rootActiveActivities;
- Guid m_providerGuid; // We use the GUID rather than object identity because we don't want to keep the eventSource alive
- int m_eventId; // triggering event
- int m_samplingFreq; // Counter reset to this when it hits 0
- int m_curSampleCount; // We count down to 0 and then activate the activity.
- int m_perEventSourceSessionId; // session ID bit for ETW, 0 for EventListeners
-
- const int MaxActivityTrackCount = 100000; // maximum number of tracked activities
-
- ActivityFilter m_next; // We create a linked list of these
- Action<Guid> m_myActivityDelegate;
- #endregion
- };
-
-
- /// <summary>
- /// An EtwSession instance represents an activity-tracing-aware ETW session. Since these
- /// are limited to 8 concurrent sessions per machine (currently) we're going to store
- /// the active ones in a singly linked list.
- /// </summary>
- internal class EtwSession
- {
- public static EtwSession GetEtwSession(int etwSessionId, bool bCreateIfNeeded = false)
- {
- if (etwSessionId < 0)
- return null;
-
- EtwSession etwSession;
- foreach (var wrEtwSession in s_etwSessions)
- {
-#if ES_BUILD_STANDALONE
- if ((etwSession = (EtwSession) wrEtwSession.Target) != null && etwSession.m_etwSessionId == etwSessionId)
- return etwSession;
-#else
- if (wrEtwSession.TryGetTarget(out etwSession) && etwSession.m_etwSessionId == etwSessionId)
- return etwSession;
-#endif
- }
-
- if (!bCreateIfNeeded)
- return null;
-
-#if ES_BUILD_STANDALONE
- if (s_etwSessions == null)
- s_etwSessions = new List<WeakReference>();
-
- etwSession = new EtwSession(etwSessionId);
- s_etwSessions.Add(new WeakReference(etwSession));
-#else
- if (s_etwSessions == null)
- s_etwSessions = new List<WeakReference<EtwSession>>();
-
- etwSession = new EtwSession(etwSessionId);
- s_etwSessions.Add(new WeakReference<EtwSession>(etwSession));
-#endif
-
- if (s_etwSessions.Count > s_thrSessionCount)
- TrimGlobalList();
-
- return etwSession;
-
- }
-
- public static void RemoveEtwSession(EtwSession etwSession)
- {
- Debug.Assert(etwSession != null);
- if (s_etwSessions == null || etwSession == null)
- return;
-
- s_etwSessions.RemoveAll((wrEtwSession) =>
- {
- EtwSession session;
-#if ES_BUILD_STANDALONE
- return (session = (EtwSession) wrEtwSession.Target) != null &&
- (session.m_etwSessionId == etwSession.m_etwSessionId);
-#else
- return wrEtwSession.TryGetTarget(out session) &&
- (session.m_etwSessionId == etwSession.m_etwSessionId);
-#endif
- });
-
- if (s_etwSessions.Count > s_thrSessionCount)
- TrimGlobalList();
- }
-
- private static void TrimGlobalList()
- {
- if (s_etwSessions == null)
- return;
-
- s_etwSessions.RemoveAll((wrEtwSession) =>
- {
-#if ES_BUILD_STANDALONE
- return wrEtwSession.Target == null;
-#else
- EtwSession session;
- return !wrEtwSession.TryGetTarget(out session);
-#endif
- });
- }
-
- private EtwSession(int etwSessionId)
- {
- m_etwSessionId = etwSessionId;
- }
-
- public readonly int m_etwSessionId; // ETW session ID (as retrieved by EventProvider)
- public ActivityFilter m_activityFilter; // all filters enabled for this session
-
-#if ES_BUILD_STANDALONE
- private static List<WeakReference> s_etwSessions = new List<WeakReference>();
-#else
- private static List<WeakReference<EtwSession>> s_etwSessions = new List<WeakReference<EtwSession>>();
-#endif
- private const int s_thrSessionCount = 16;
- }
-
-#endif // FEATURE_ACTIVITYSAMPLING
-
- // holds a bitfield representing a session mask
- /// <summary>
- /// A SessionMask represents a set of (at most MAX) sessions as a bit mask. The perEventSourceSessionId
- /// is the index in the SessionMask of the bit that will be set. These can translate to
- /// EventSource's reserved keywords bits using the provided ToEventKeywords() and
- /// FromEventKeywords() methods.
- /// </summary>
- internal struct SessionMask
- {
- public SessionMask(SessionMask m)
- { m_mask = m.m_mask; }
-
- public SessionMask(uint mask = 0)
- { m_mask = mask & MASK; }
-
- public bool IsEqualOrSupersetOf(SessionMask m)
- {
- return (this.m_mask | m.m_mask) == this.m_mask;
- }
-
- public static SessionMask All
- {
- get { return new SessionMask(MASK); }
- }
-
- public static SessionMask FromId(int perEventSourceSessionId)
- {
- Debug.Assert(perEventSourceSessionId < MAX);
- return new SessionMask((uint)1 << perEventSourceSessionId);
- }
-
- public ulong ToEventKeywords()
- {
- return (ulong)m_mask << SHIFT_SESSION_TO_KEYWORD;
- }
-
- public static SessionMask FromEventKeywords(ulong m)
- {
- return new SessionMask((uint)(m >> SHIFT_SESSION_TO_KEYWORD));
- }
-
- public bool this[int perEventSourceSessionId]
- {
- get
- {
- Debug.Assert(perEventSourceSessionId < MAX);
- return (m_mask & (1 << perEventSourceSessionId)) != 0;
- }
- set
- {
- Debug.Assert(perEventSourceSessionId < MAX);
- if (value) m_mask |= ((uint)1 << perEventSourceSessionId);
- else m_mask &= ~((uint)1 << perEventSourceSessionId);
- }
- }
-
- public static SessionMask operator |(SessionMask m1, SessionMask m2)
- {
- return new SessionMask(m1.m_mask | m2.m_mask);
- }
-
- public static SessionMask operator &(SessionMask m1, SessionMask m2)
- {
- return new SessionMask(m1.m_mask & m2.m_mask);
- }
-
- public static SessionMask operator ^(SessionMask m1, SessionMask m2)
- {
- return new SessionMask(m1.m_mask ^ m2.m_mask);
- }
-
- public static SessionMask operator ~(SessionMask m)
- {
- return new SessionMask(MASK & ~(m.m_mask));
- }
-
- public static explicit operator ulong(SessionMask m)
- { return m.m_mask; }
-
- public static explicit operator uint(SessionMask m)
- { return m.m_mask; }
-
- private uint m_mask;
-
- internal const int SHIFT_SESSION_TO_KEYWORD = 44; // bits 44-47 inclusive are reserved
- internal const uint MASK = 0x0fU; // the mask of 4 reserved bits
- internal const uint MAX = 4; // maximum number of simultaneous ETW sessions supported
- }
-
- /// <summary>
- /// code:EventDispatchers are a simple 'helper' structure that holds the filtering state
- /// (m_EventEnabled) for a particular EventSource X EventListener tuple
- ///
- /// Thus a single EventListener may have many EventDispatchers (one for every EventSource
- /// that that EventListener has activate) and a Single EventSource may also have many
- /// event Dispatchers (one for every EventListener that has activated it).
- ///
- /// Logically a particular EventDispatcher belongs to exactly one EventSource and exactly
- /// one EventListener (alhtough EventDispatcher does not 'remember' the EventSource it is
- /// associated with.
- /// </summary>
- internal class EventDispatcher
- {
- internal EventDispatcher(EventDispatcher next, bool[] eventEnabled, EventListener listener)
- {
- m_Next = next;
- m_EventEnabled = eventEnabled;
- m_Listener = listener;
- }
-
- // Instance fields
- readonly internal EventListener m_Listener; // The dispatcher this entry is for
- internal bool[] m_EventEnabled; // For every event in a the eventSource, is it enabled?
-#if FEATURE_ACTIVITYSAMPLING
- internal bool m_activityFilteringEnabled; // does THIS EventSource have activity filtering turned on for this listener?
-#endif // FEATURE_ACTIVITYSAMPLING
-
- // Only guaranteed to exist after a InsureInit()
- internal EventDispatcher m_Next; // These form a linked list in code:EventSource.m_Dispatchers
- // Of all listeners for that eventSource.
- }
-
- /// <summary>
- /// Flags that can be used with EventSource.GenerateManifest to control how the ETW manifest for the EventSource is
- /// generated.
- /// </summary>
- [Flags]
- public enum EventManifestOptions
- {
- /// <summary>
- /// Only the resources associated with current UI culture are included in the manifest
- /// </summary>
- None = 0x0,
- /// <summary>
- /// Throw exceptions for any inconsistency encountered
- /// </summary>
- Strict = 0x1,
- /// <summary>
- /// Generate a "resources" node under "localization" for every satellite assembly provided
- /// </summary>
- AllCultures = 0x2,
- /// <summary>
- /// Generate the manifest only if the event source needs to be registered on the machine,
- /// otherwise return null (but still perform validation if Strict is specified)
- /// </summary>
- OnlyIfNeededForRegistration = 0x4,
- /// <summary>
- /// When generating the manifest do *not* enforce the rule that the current EventSource class
- /// must be the base class for the user-defined type passed in. This allows validation of .net
- /// event sources using the new validation code
- /// </summary>
- AllowEventSourceOverride = 0x8,
- }
-
- /// <summary>
- /// ManifestBuilder is designed to isolate the details of the message of the event from the
- /// rest of EventSource. This one happens to create XML.
- /// </summary>
- internal partial class ManifestBuilder
- {
- /// <summary>
- /// Build a manifest for 'providerName' with the given GUID, which will be packaged into 'dllName'.
- /// 'resources, is a resource manager. If specified all messages are localized using that manager.
- /// </summary>
- public ManifestBuilder(string providerName, Guid providerGuid, string dllName, ResourceManager resources,
- EventManifestOptions flags)
- {
-#if FEATURE_MANAGED_ETW_CHANNELS
- this.providerName = providerName;
-#endif
- this.flags = flags;
-
- this.resources = resources;
- sb = new StringBuilder();
- events = new StringBuilder();
- templates = new StringBuilder();
- opcodeTab = new Dictionary<int, string>();
- stringTab = new Dictionary<string, string>();
- errors = new List<string>();
- perEventByteArrayArgIndices = new Dictionary<string, List<int>>();
-
- sb.AppendLine("<instrumentationManifest xmlns=\"http://schemas.microsoft.com/win/2004/08/events\">");
- sb.AppendLine(" <instrumentation xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:win=\"http://manifests.microsoft.com/win/2004/08/windows/events\">");
- sb.AppendLine(" <events xmlns=\"http://schemas.microsoft.com/win/2004/08/events\">");
- sb.Append("<provider name=\"").Append(providerName).
- Append("\" guid=\"{").Append(providerGuid.ToString()).Append("}");
- if (dllName != null)
- sb.Append("\" resourceFileName=\"").Append(dllName).Append("\" messageFileName=\"").Append(dllName);
-
- var symbolsName = providerName.Replace("-", "").Replace(".", "_"); // Period and - are illegal replace them.
- sb.Append("\" symbol=\"").Append(symbolsName);
- sb.Append("\">").AppendLine();
- }
-
- public void AddOpcode(string name, int value)
- {
- if ((flags & EventManifestOptions.Strict) != 0)
- {
- if (value <= 10 || value >= 239)
- {
- ManifestError(Resources.GetResourceString("EventSource_IllegalOpcodeValue", name, value));
- }
- string prevName;
- if (opcodeTab.TryGetValue(value, out prevName) && !name.Equals(prevName, StringComparison.Ordinal))
- {
- ManifestError(Resources.GetResourceString("EventSource_OpcodeCollision", name, prevName, value));
- }
- }
- opcodeTab[value] = name;
- }
- public void AddTask(string name, int value)
- {
- if ((flags & EventManifestOptions.Strict) != 0)
- {
- if (value <= 0 || value >= 65535)
- {
- ManifestError(Resources.GetResourceString("EventSource_IllegalTaskValue", name, value));
- }
- string prevName;
- if (taskTab != null && taskTab.TryGetValue(value, out prevName) && !name.Equals(prevName, StringComparison.Ordinal))
- {
- ManifestError(Resources.GetResourceString("EventSource_TaskCollision", name, prevName, value));
- }
- }
- if (taskTab == null)
- taskTab = new Dictionary<int, string>();
- taskTab[value] = name;
- }
- public void AddKeyword(string name, ulong value)
- {
- if ((value & (value - 1)) != 0) // Is it a power of 2?
- {
- ManifestError(Resources.GetResourceString("EventSource_KeywordNeedPowerOfTwo", "0x" + value.ToString("x", CultureInfo.CurrentCulture), name), true);
- }
- if ((flags & EventManifestOptions.Strict) != 0)
- {
- if (value >= 0x0000100000000000UL && !name.StartsWith("Session", StringComparison.Ordinal))
- {
- ManifestError(Resources.GetResourceString("EventSource_IllegalKeywordsValue", name, "0x" + value.ToString("x", CultureInfo.CurrentCulture)));
- }
- string prevName;
- if (keywordTab != null && keywordTab.TryGetValue(value, out prevName) && !name.Equals(prevName, StringComparison.Ordinal))
- {
- ManifestError(Resources.GetResourceString("EventSource_KeywordCollision", name, prevName, "0x" + value.ToString("x", CultureInfo.CurrentCulture)));
- }
- }
- if (keywordTab == null)
- keywordTab = new Dictionary<ulong, string>();
- keywordTab[value] = name;
- }
-
-#if FEATURE_MANAGED_ETW_CHANNELS
- /// <summary>
- /// Add a channel. channelAttribute can be null
- /// </summary>
- public void AddChannel(string name, int value, EventChannelAttribute channelAttribute)
- {
- EventChannel chValue = (EventChannel)value;
- if (value < (int)EventChannel.Admin || value > 255)
- ManifestError(Resources.GetResourceString("EventSource_EventChannelOutOfRange", name, value));
- else if (chValue >= EventChannel.Admin && chValue <= EventChannel.Debug &&
- channelAttribute != null && EventChannelToChannelType(chValue) != channelAttribute.EventChannelType)
- {
- // we want to ensure developers do not define EventChannels that conflict with the builtin ones,
- // but we want to allow them to override the default ones...
- ManifestError(Resources.GetResourceString("EventSource_ChannelTypeDoesNotMatchEventChannelValue",
- name, ((EventChannel)value).ToString()));
- }
-
- // TODO: validate there are no conflicting manifest exposed names (generally following the format "provider/type")
-
- ulong kwd = GetChannelKeyword(chValue);
-
- if (channelTab == null)
- channelTab = new Dictionary<int, ChannelInfo>(4);
- channelTab[value] = new ChannelInfo { Name = name, Keywords = kwd, Attribs = channelAttribute };
- }
-
- private EventChannelType EventChannelToChannelType(EventChannel channel)
- {
-#if !ES_BUILD_STANDALONE
- Debug.Assert(channel >= EventChannel.Admin && channel <= EventChannel.Debug);
-#endif
- return (EventChannelType)((int)channel - (int)EventChannel.Admin + (int)EventChannelType.Admin);
- }
- private EventChannelAttribute GetDefaultChannelAttribute(EventChannel channel)
- {
- EventChannelAttribute attrib = new EventChannelAttribute();
- attrib.EventChannelType = EventChannelToChannelType(channel);
- if (attrib.EventChannelType <= EventChannelType.Operational)
- attrib.Enabled = true;
- return attrib;
- }
-
- public ulong[] GetChannelData()
- {
- if (this.channelTab == null)
- {
- return new ulong[0];
- }
-
- // We create an array indexed by the channel id for fast look up.
- // E.g. channelMask[Admin] will give you the bit mask for Admin channel.
- int maxkey = -1;
- foreach (var item in this.channelTab.Keys)
- {
- if (item > maxkey)
- {
- maxkey = item;
- }
- }
-
- ulong[] channelMask = new ulong[maxkey + 1];
- foreach (var item in this.channelTab)
- {
- channelMask[item.Key] = item.Value.Keywords;
- }
-
- return channelMask;
- }
-
-#endif
- public void StartEvent(string eventName, EventAttribute eventAttribute)
- {
- Debug.Assert(numParams == 0);
- Debug.Assert(this.eventName == null);
- this.eventName = eventName;
- numParams = 0;
- byteArrArgIndices = null;
-
- events.Append(" <event").
- Append(" value=\"").Append(eventAttribute.EventId).Append("\"").
- Append(" version=\"").Append(eventAttribute.Version).Append("\"").
- Append(" level=\"").Append(GetLevelName(eventAttribute.Level)).Append("\"").
- Append(" symbol=\"").Append(eventName).Append("\"");
-
- // at this point we add to the manifest's stringTab a message that is as-of-yet
- // "untranslated to manifest convention", b/c we don't have the number or position
- // of any byte[] args (which require string format index updates)
- WriteMessageAttrib(events, "event", eventName, eventAttribute.Message);
-
- if (eventAttribute.Keywords != 0)
- events.Append(" keywords=\"").Append(GetKeywords((ulong)eventAttribute.Keywords, eventName)).Append("\"");
- if (eventAttribute.Opcode != 0)
- events.Append(" opcode=\"").Append(GetOpcodeName(eventAttribute.Opcode, eventName)).Append("\"");
- if (eventAttribute.Task != 0)
- events.Append(" task=\"").Append(GetTaskName(eventAttribute.Task, eventName)).Append("\"");
-#if FEATURE_MANAGED_ETW_CHANNELS
- if (eventAttribute.Channel != 0)
- {
- events.Append(" channel=\"").Append(GetChannelName(eventAttribute.Channel, eventName, eventAttribute.Message)).Append("\"");
- }
-#endif
- }
-
- public void AddEventParameter(Type type, string name)
- {
- if (numParams == 0)
- templates.Append(" <template tid=\"").Append(eventName).Append("Args\">").AppendLine();
- if (type == typeof(byte[]))
- {
- // mark this index as "extraneous" (it has no parallel in the managed signature)
- // we use these values in TranslateToManifestConvention()
- if (byteArrArgIndices == null)
- byteArrArgIndices = new List<int>(4);
- byteArrArgIndices.Add(numParams);
-
- // add an extra field to the template representing the length of the binary blob
- numParams++;
- templates.Append(" <data name=\"").Append(name).Append("Size\" inType=\"win:UInt32\"/>").AppendLine();
- }
- numParams++;
- templates.Append(" <data name=\"").Append(name).Append("\" inType=\"").Append(GetTypeName(type)).Append("\"");
- // TODO: for 'byte*' types it assumes the user provided length is named using the same naming convention
- // as for 'byte[]' args (blob_arg_name + "Size")
- if ((type.IsArray || type.IsPointer) && type.GetElementType() == typeof(byte))
- {
- // add "length" attribute to the "blob" field in the template (referencing the field added above)
- templates.Append(" length=\"").Append(name).Append("Size\"");
- }
- // ETW does not support 64-bit value maps, so we don't specify these as ETW maps
- if (type.IsEnum() && Enum.GetUnderlyingType(type) != typeof(UInt64) && Enum.GetUnderlyingType(type) != typeof(Int64))
- {
- templates.Append(" map=\"").Append(type.Name).Append("\"");
- if (mapsTab == null)
- mapsTab = new Dictionary<string, Type>();
- if (!mapsTab.ContainsKey(type.Name))
- mapsTab.Add(type.Name, type); // Remember that we need to dump the type enumeration
- }
-
- templates.Append("/>").AppendLine();
- }
- public void EndEvent()
- {
- if (numParams > 0)
- {
- templates.Append(" </template>").AppendLine();
- events.Append(" template=\"").Append(eventName).Append("Args\"");
- }
- events.Append("/>").AppendLine();
-
- if (byteArrArgIndices != null)
- perEventByteArrayArgIndices[eventName] = byteArrArgIndices;
-
- // at this point we have all the information we need to translate the C# Message
- // to the manifest string we'll put in the stringTab
- string msg;
- if (stringTab.TryGetValue("event_" + eventName, out msg))
- {
- msg = TranslateToManifestConvention(msg, eventName);
- stringTab["event_" + eventName] = msg;
- }
-
- eventName = null;
- numParams = 0;
- byteArrArgIndices = null;
- }
-
-#if FEATURE_MANAGED_ETW_CHANNELS
- // Channel keywords are generated one per channel to allow channel based filtering in event viewer. These keywords are autogenerated
- // by mc.exe for compiling a manifest and are based on the order of the channels (fields) in the Channels inner class (when advanced
- // channel support is enabled), or based on the order the predefined channels appear in the EventAttribute properties (for simple
- // support). The manifest generated *MUST* have the channels specified in the same order (that's how our computed keywords are mapped
- // to channels by the OS infrastructure).
- // If channelKeyworkds is present, and has keywords bits in the ValidPredefinedChannelKeywords then it is
- // assumed that that the keyword for that channel should be that bit.
- // otherwise we allocate a channel bit for the channel.
- // explicit channel bits are only used by WCF to mimic an existing manifest,
- // so we don't dont do error checking.
- public ulong GetChannelKeyword(EventChannel channel, ulong channelKeyword = 0)
- {
- // strip off any non-channel keywords, since we are only interested in channels here.
- channelKeyword &= ValidPredefinedChannelKeywords;
- if (channelTab == null)
- {
- channelTab = new Dictionary<int, ChannelInfo>(4);
- }
-
- if (channelTab.Count == MaxCountChannels)
- ManifestError(Resources.GetResourceString("EventSource_MaxChannelExceeded"));
-
- ChannelInfo info;
- if (!channelTab.TryGetValue((int)channel, out info))
- {
- // If we were not given an explicit channel, allocate one.
- if (channelKeyword != 0)
- {
- channelKeyword = nextChannelKeywordBit;
- nextChannelKeywordBit >>= 1;
- }
- }
- else
- {
- channelKeyword = info.Keywords;
- }
-
- return channelKeyword;
- }
-#endif
-
- public byte[] CreateManifest()
- {
- string str = CreateManifestString();
- return Encoding.UTF8.GetBytes(str);
- }
-
- public IList<string> Errors { get { return errors; } }
-
- /// <summary>
- /// When validating an event source it adds the error to the error collection.
- /// When not validating it throws an exception if runtimeCritical is "true".
- /// Otherwise the error is ignored.
- /// </summary>
- /// <param name="msg"></param>
- /// <param name="runtimeCritical"></param>
- public void ManifestError(string msg, bool runtimeCritical = false)
- {
- if ((flags & EventManifestOptions.Strict) != 0)
- errors.Add(msg);
- else if (runtimeCritical)
- throw new ArgumentException(msg);
- }
-
- private string CreateManifestString()
- {
-
-#if FEATURE_MANAGED_ETW_CHANNELS
- // Write out the channels
- if (channelTab != null)
- {
- sb.Append(" <channels>").AppendLine();
- var sortedChannels = new List<KeyValuePair<int, ChannelInfo>>();
- foreach (KeyValuePair<int, ChannelInfo> p in channelTab) { sortedChannels.Add(p); }
- sortedChannels.Sort((p1, p2) => -Comparer<ulong>.Default.Compare(p1.Value.Keywords, p2.Value.Keywords));
- foreach (var kvpair in sortedChannels)
- {
- int channel = kvpair.Key;
- ChannelInfo channelInfo = kvpair.Value;
-
- string channelType = null;
- string elementName = "channel";
- bool enabled = false;
- string fullName = null;
-#if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
- string isolation = null;
- string access = null;
-#endif
- if (channelInfo.Attribs != null)
- {
- var attribs = channelInfo.Attribs;
- if (Enum.IsDefined(typeof(EventChannelType), attribs.EventChannelType))
- channelType = attribs.EventChannelType.ToString();
- enabled = attribs.Enabled;
-#if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
- if (attribs.ImportChannel != null)
- {
- fullName = attribs.ImportChannel;
- elementName = "importChannel";
- }
- if (Enum.IsDefined(typeof(EventChannelIsolation), attribs.Isolation))
- isolation = attribs.Isolation.ToString();
- access = attribs.Access;
-#endif
- }
- if (fullName == null)
- fullName = providerName + "/" + channelInfo.Name;
-
- sb.Append(" <").Append(elementName);
- sb.Append(" chid=\"").Append(channelInfo.Name).Append("\"");
- sb.Append(" name=\"").Append(fullName).Append("\"");
- if (elementName == "channel") // not applicable to importChannels.
- {
- WriteMessageAttrib(sb, "channel", channelInfo.Name, null);
- sb.Append(" value=\"").Append(channel).Append("\"");
- if (channelType != null)
- sb.Append(" type=\"").Append(channelType).Append("\"");
- sb.Append(" enabled=\"").Append(enabled.ToString().ToLower()).Append("\"");
-#if FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
- if (access != null)
- sb.Append(" access=\"").Append(access).Append("\"");
- if (isolation != null)
- sb.Append(" isolation=\"").Append(isolation).Append("\"");
-#endif
- }
- sb.Append("/>").AppendLine();
- }
- sb.Append(" </channels>").AppendLine();
- }
-#endif
-
- // Write out the tasks
- if (taskTab != null)
- {
-
- sb.Append(" <tasks>").AppendLine();
- var sortedTasks = new List<int>(taskTab.Keys);
- sortedTasks.Sort();
- foreach (int task in sortedTasks)
- {
- sb.Append(" <task");
- WriteNameAndMessageAttribs(sb, "task", taskTab[task]);
- sb.Append(" value=\"").Append(task).Append("\"/>").AppendLine();
- }
- sb.Append(" </tasks>").AppendLine();
- }
-
- // Write out the maps
- if (mapsTab != null)
- {
- sb.Append(" <maps>").AppendLine();
- foreach (Type enumType in mapsTab.Values)
- {
- bool isbitmap = EventSource.GetCustomAttributeHelper(enumType, typeof(FlagsAttribute), flags) != null;
- string mapKind = isbitmap ? "bitMap" : "valueMap";
- sb.Append(" <").Append(mapKind).Append(" name=\"").Append(enumType.Name).Append("\">").AppendLine();
-
- // write out each enum value
- FieldInfo[] staticFields = enumType.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static);
- foreach (FieldInfo staticField in staticFields)
- {
- object constantValObj = staticField.GetRawConstantValue();
- if (constantValObj != null)
- {
- long hexValue;
- if (constantValObj is int)
- hexValue = ((int)constantValObj);
- else if (constantValObj is long)
- hexValue = ((long)constantValObj);
- else
- continue;
-
- // ETW requires all bitmap values to be powers of 2. Skip the ones that are not.
- // TODO: Warn people about the dropping of values.
- if (isbitmap && ((hexValue & (hexValue - 1)) != 0 || hexValue == 0))
- continue;
-
- sb.Append(" <map value=\"0x").Append(hexValue.ToString("x", CultureInfo.InvariantCulture)).Append("\"");
- WriteMessageAttrib(sb, "map", enumType.Name + "." + staticField.Name, staticField.Name);
- sb.Append("/>").AppendLine();
- }
- }
- sb.Append(" </").Append(mapKind).Append(">").AppendLine();
- }
- sb.Append(" </maps>").AppendLine();
- }
-
- // Write out the opcodes
- sb.Append(" <opcodes>").AppendLine();
- var sortedOpcodes = new List<int>(opcodeTab.Keys);
- sortedOpcodes.Sort();
- foreach (int opcode in sortedOpcodes)
- {
- sb.Append(" <opcode");
- WriteNameAndMessageAttribs(sb, "opcode", opcodeTab[opcode]);
- sb.Append(" value=\"").Append(opcode).Append("\"/>").AppendLine();
- }
- sb.Append(" </opcodes>").AppendLine();
-
- // Write out the keywords
- if (keywordTab != null)
- {
- sb.Append(" <keywords>").AppendLine();
- var sortedKeywords = new List<ulong>(keywordTab.Keys);
- sortedKeywords.Sort();
- foreach (ulong keyword in sortedKeywords)
- {
- sb.Append(" <keyword");
- WriteNameAndMessageAttribs(sb, "keyword", keywordTab[keyword]);
- sb.Append(" mask=\"0x").Append(keyword.ToString("x", CultureInfo.InvariantCulture)).Append("\"/>").AppendLine();
- }
- sb.Append(" </keywords>").AppendLine();
- }
-
- sb.Append(" <events>").AppendLine();
- sb.Append(events);
- sb.Append(" </events>").AppendLine();
-
- sb.Append(" <templates>").AppendLine();
- if (templates.Length > 0)
- {
- sb.Append(templates);
- }
- else
- {
- // Work around a cornercase ETW issue where a manifest with no templates causes
- // ETW events to not get sent to their associated channel.
- sb.Append(" <template tid=\"_empty\"></template>").AppendLine();
- }
- sb.Append(" </templates>").AppendLine();
-
- sb.Append("</provider>").AppendLine();
- sb.Append("</events>").AppendLine();
- sb.Append("</instrumentation>").AppendLine();
-
- // Output the localization information.
- sb.Append("<localization>").AppendLine();
-
- List<CultureInfo> cultures = null;
- if (resources != null && (flags & EventManifestOptions.AllCultures) != 0)
- {
- cultures = GetSupportedCultures(resources);
- }
- else
- {
- cultures = new List<CultureInfo>();
- cultures.Add(CultureInfo.CurrentUICulture);
- }
-#if ES_BUILD_STANDALONE || PROJECTN
- var sortedStrings = new List<string>(stringTab.Keys);
- sortedStrings.Sort();
-#else
- // DD 947936
- var sortedStrings = new string[stringTab.Keys.Count];
- stringTab.Keys.CopyTo(sortedStrings, 0);
- // Avoid using public Array.Sort as that attempts to access BinaryCompatibility. Unfortunately FrameworkEventSource gets called
- // very early in the app domain creation, when _FusionStore is not set up yet, resulting in a failure to run the static constructory
- // for BinaryCompatibility. This failure is then cached and a TypeInitializationException is thrown every time some code attampts to
- // access BinaryCompatibility.
- ArraySortHelper<string>.IntrospectiveSort(sortedStrings, 0, sortedStrings.Length, string.Compare);
-#endif
- foreach (var ci in cultures)
- {
- sb.Append(" <resources culture=\"").Append(ci.Name).Append("\">").AppendLine();
- sb.Append(" <stringTable>").AppendLine();
-
- foreach (var stringKey in sortedStrings)
- {
- string val = GetLocalizedMessage(stringKey, ci, etwFormat: true);
- sb.Append(" <string id=\"").Append(stringKey).Append("\" value=\"").Append(val).Append("\"/>").AppendLine();
- }
- sb.Append(" </stringTable>").AppendLine();
- sb.Append(" </resources>").AppendLine();
- }
- sb.Append("</localization>").AppendLine();
- sb.AppendLine("</instrumentationManifest>");
- return sb.ToString();
- }
-
- #region private
- private void WriteNameAndMessageAttribs(StringBuilder stringBuilder, string elementName, string name)
- {
- stringBuilder.Append(" name=\"").Append(name).Append("\"");
- WriteMessageAttrib(sb, elementName, name, name);
- }
- private void WriteMessageAttrib(StringBuilder stringBuilder, string elementName, string name, string value)
- {
- string key = elementName + "_" + name;
- // See if the user wants things localized.
- if (resources != null)
- {
- // resource fallback: strings in the neutral culture will take precedence over inline strings
- string localizedString = resources.GetString(key, CultureInfo.InvariantCulture);
- if (localizedString != null)
- value = localizedString;
- }
- if (value == null)
- return;
-
- stringBuilder.Append(" message=\"$(string.").Append(key).Append(")\"");
- string prevValue;
- if (stringTab.TryGetValue(key, out prevValue) && !prevValue.Equals(value))
- {
- ManifestError(Resources.GetResourceString("EventSource_DuplicateStringKey", key), true);
- return;
- }
-
- stringTab[key] = value;
- }
- internal string GetLocalizedMessage(string key, CultureInfo ci, bool etwFormat)
- {
- string value = null;
- if (resources != null)
- {
- string localizedString = resources.GetString(key, ci);
- if (localizedString != null)
- {
- value = localizedString;
- if (etwFormat && key.StartsWith("event_", StringComparison.Ordinal))
- {
- var evtName = key.Substring("event_".Length);
- value = TranslateToManifestConvention(value, evtName);
- }
- }
- }
- if (etwFormat && value == null)
- stringTab.TryGetValue(key, out value);
-
- return value;
- }
-
- /// <summary>
- /// There's no API to enumerate all languages an assembly is localized into, so instead
- /// we enumerate through all the "known" cultures and attempt to load a corresponding satellite
- /// assembly
- /// </summary>
- /// <param name="resources"></param>
- /// <returns></returns>
- private static List<CultureInfo> GetSupportedCultures(ResourceManager resources)
- {
- var cultures = new List<CultureInfo>();
-
- if (!cultures.Contains(CultureInfo.CurrentUICulture))
- cultures.Insert(0, CultureInfo.CurrentUICulture);
- return cultures;
- }
-
- private static string GetLevelName(EventLevel level)
- {
- return (((int)level >= 16) ? "" : "win:") + level.ToString();
- }
-
-#if FEATURE_MANAGED_ETW_CHANNELS
- private string GetChannelName(EventChannel channel, string eventName, string eventMessage)
- {
- ChannelInfo info = null;
- if (channelTab == null || !channelTab.TryGetValue((int)channel, out info))
- {
- if (channel < EventChannel.Admin) // || channel > EventChannel.Debug)
- ManifestError(Resources.GetResourceString("EventSource_UndefinedChannel", channel, eventName));
-
- // allow channels to be auto-defined. The well known ones get their well known names, and the
- // rest get names Channel<N>. This allows users to modify the Manifest if they want more advanced features.
- if (channelTab == null)
- channelTab = new Dictionary<int, ChannelInfo>(4);
-
- string channelName = channel.ToString(); // For well know channels this is a nice name, otherwise a number
- if (EventChannel.Debug < channel)
- channelName = "Channel" + channelName; // Add a 'Channel' prefix for numbers.
-
- AddChannel(channelName, (int)channel, GetDefaultChannelAttribute(channel));
- if (!channelTab.TryGetValue((int)channel, out info))
- ManifestError(Resources.GetResourceString("EventSource_UndefinedChannel", channel, eventName));
- }
- // events that specify admin channels *must* have non-null "Message" attributes
- if (resources != null && eventMessage == null)
- eventMessage = resources.GetString("event_" + eventName, CultureInfo.InvariantCulture);
- if (info.Attribs.EventChannelType == EventChannelType.Admin && eventMessage == null)
- ManifestError(Resources.GetResourceString("EventSource_EventWithAdminChannelMustHaveMessage", eventName, info.Name));
- return info.Name;
- }
-#endif
- private string GetTaskName(EventTask task, string eventName)
- {
- if (task == EventTask.None)
- return "";
-
- string ret;
- if (taskTab == null)
- taskTab = new Dictionary<int, string>();
- if (!taskTab.TryGetValue((int)task, out ret))
- ret = taskTab[(int)task] = eventName;
- return ret;
- }
-
- private string GetOpcodeName(EventOpcode opcode, string eventName)
- {
- switch (opcode)
- {
- case EventOpcode.Info:
- return "win:Info";
- case EventOpcode.Start:
- return "win:Start";
- case EventOpcode.Stop:
- return "win:Stop";
- case EventOpcode.DataCollectionStart:
- return "win:DC_Start";
- case EventOpcode.DataCollectionStop:
- return "win:DC_Stop";
- case EventOpcode.Extension:
- return "win:Extension";
- case EventOpcode.Reply:
- return "win:Reply";
- case EventOpcode.Resume:
- return "win:Resume";
- case EventOpcode.Suspend:
- return "win:Suspend";
- case EventOpcode.Send:
- return "win:Send";
- case EventOpcode.Receive:
- return "win:Receive";
- }
-
- string ret;
- if (opcodeTab == null || !opcodeTab.TryGetValue((int)opcode, out ret))
- {
- ManifestError(Resources.GetResourceString("EventSource_UndefinedOpcode", opcode, eventName), true);
- ret = null;
- }
- return ret;
- }
-
- private string GetKeywords(ulong keywords, string eventName)
- {
- // ignore keywords associate with channels
- // See ValidPredefinedChannelKeywords def for more.
- keywords &= ~ValidPredefinedChannelKeywords;
-
- string ret = "";
- for (ulong bit = 1; bit != 0; bit <<= 1)
- {
- if ((keywords & bit) != 0)
- {
- string keyword = null;
- if ((keywordTab == null || !keywordTab.TryGetValue(bit, out keyword)) &&
- (bit >= (ulong)0x1000000000000))
- {
- // do not report Windows reserved keywords in the manifest (this allows the code
- // to be resilient to potential renaming of these keywords)
- keyword = string.Empty;
- }
- if (keyword == null)
- {
- ManifestError(Resources.GetResourceString("EventSource_UndefinedKeyword", "0x" + bit.ToString("x", CultureInfo.CurrentCulture), eventName), true);
- keyword = string.Empty;
- }
- if (ret.Length != 0 && keyword.Length != 0)
- ret = ret + " ";
- ret = ret + keyword;
- }
- }
- return ret;
- }
-
- private string GetTypeName(Type type)
- {
- if (type.IsEnum())
- {
- FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
- var typeName = GetTypeName(fields[0].FieldType);
- return typeName.Replace("win:Int", "win:UInt"); // ETW requires enums to be unsigned.
- }
-
- return GetTypeNameHelper(type);
- }
-
- private static void UpdateStringBuilder(ref StringBuilder stringBuilder, string eventMessage, int startIndex, int count)
- {
- if (stringBuilder == null)
- stringBuilder = new StringBuilder();
- stringBuilder.Append(eventMessage, startIndex, count);
- }
-
- private static readonly string[] s_escapes = { "&amp;", "&lt;", "&gt;", "&apos;", "&quot;", "%r", "%n", "%t" };
- // Manifest messages use %N conventions for their message substitutions. Translate from
- // .NET conventions. We can't use RegEx for this (we are in mscorlib), so we do it 'by hand'
- private string TranslateToManifestConvention(string eventMessage, string evtName)
- {
- StringBuilder stringBuilder = null; // We lazily create this
- int writtenSoFar = 0;
- int chIdx = -1;
- for (int i = 0; ;)
- {
- if (i >= eventMessage.Length)
- {
- if (stringBuilder == null)
- return eventMessage;
- UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
- return stringBuilder.ToString();
- }
-
- if (eventMessage[i] == '%')
- {
- // handle format message escaping character '%' by escaping it
- UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
- stringBuilder.Append("%%");
- i++;
- writtenSoFar = i;
- }
- else if (i < eventMessage.Length - 1 &&
- (eventMessage[i] == '{' && eventMessage[i + 1] == '{' || eventMessage[i] == '}' && eventMessage[i + 1] == '}'))
- {
- // handle C# escaped '{" and '}'
- UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
- stringBuilder.Append(eventMessage[i]);
- i++; i++;
- writtenSoFar = i;
- }
- else if (eventMessage[i] == '{')
- {
- int leftBracket = i;
- i++;
- int argNum = 0;
- while (i < eventMessage.Length && Char.IsDigit(eventMessage[i]))
- {
- argNum = argNum * 10 + eventMessage[i] - '0';
- i++;
- }
- if (i < eventMessage.Length && eventMessage[i] == '}')
- {
- i++;
- UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, leftBracket - writtenSoFar);
- int manIndex = TranslateIndexToManifestConvention(argNum, evtName);
- stringBuilder.Append('%').Append(manIndex);
- // An '!' after the insert specifier {n} will be interpreted as a literal.
- // We'll escape it so that mc.exe does not attempt to consider it the
- // beginning of a format string.
- if (i < eventMessage.Length && eventMessage[i] == '!')
- {
- i++;
- stringBuilder.Append("%!");
- }
- writtenSoFar = i;
- }
- else
- {
- ManifestError(Resources.GetResourceString("EventSource_UnsupportedMessageProperty", evtName, eventMessage));
- }
- }
- else if ((chIdx = "&<>'\"\r\n\t".IndexOf(eventMessage[i])) >= 0)
- {
- UpdateStringBuilder(ref stringBuilder, eventMessage, writtenSoFar, i - writtenSoFar);
- i++;
- stringBuilder.Append(s_escapes[chIdx]);
- writtenSoFar = i;
- }
- else
- i++;
- }
- }
-
- private int TranslateIndexToManifestConvention(int idx, string evtName)
- {
- List<int> byteArrArgIndices;
- if (perEventByteArrayArgIndices.TryGetValue(evtName, out byteArrArgIndices))
- {
- foreach (var byArrIdx in byteArrArgIndices)
- {
- if (idx >= byArrIdx)
- ++idx;
- else
- break;
- }
- }
- return idx + 1;
- }
-
-#if FEATURE_MANAGED_ETW_CHANNELS
- class ChannelInfo
- {
- public string Name;
- public ulong Keywords;
- public EventChannelAttribute Attribs;
- }
-#endif
-
- Dictionary<int, string> opcodeTab;
- Dictionary<int, string> taskTab;
-#if FEATURE_MANAGED_ETW_CHANNELS
- Dictionary<int, ChannelInfo> channelTab;
-#endif
- Dictionary<ulong, string> keywordTab;
- Dictionary<string, Type> mapsTab;
-
- Dictionary<string, string> stringTab; // Maps unlocalized strings to localized ones
-
-#if FEATURE_MANAGED_ETW_CHANNELS
- // WCF used EventSource to mimic a existing ETW manifest. To support this
- // in just their case, we allowed them to specify the keywords associated
- // with their channels explicitly. ValidPredefinedChannelKeywords is
- // this set of channel keywords that we allow to be explicitly set. You
- // can ignore these bits otherwise.
- internal const ulong ValidPredefinedChannelKeywords = 0xF000000000000000;
- ulong nextChannelKeywordBit = 0x8000000000000000; // available Keyword bit to be used for next channel definition, grows down
- const int MaxCountChannels = 8; // a manifest can defined at most 8 ETW channels
-#endif
-
- StringBuilder sb; // Holds the provider information.
- StringBuilder events; // Holds the events.
- StringBuilder templates;
-
-#if FEATURE_MANAGED_ETW_CHANNELS
- string providerName;
-#endif
- ResourceManager resources; // Look up localized strings here.
- EventManifestOptions flags;
- IList<string> errors; // list of currently encountered errors
- Dictionary<string, List<int>> perEventByteArrayArgIndices; // "event_name" -> List_of_Indices_of_Byte[]_Arg
-
- // State we track between StartEvent and EndEvent.
- string eventName; // Name of the event currently being processed.
- int numParams; // keeps track of the number of args the event has.
- List<int> byteArrArgIndices; // keeps track of the index of each byte[] argument
- #endregion
- }
-
- /// <summary>
- /// Used to send the m_rawManifest into the event dispatcher as a series of events.
- /// </summary>
- internal struct ManifestEnvelope
- {
- public const int MaxChunkSize = 0xFF00;
- public enum ManifestFormats : byte
- {
- SimpleXmlFormat = 1, // simply dump the XML manifest as UTF8
- }
-
- public ManifestFormats Format;
- public byte MajorVersion;
- public byte MinorVersion;
- public byte Magic;
- public ushort TotalChunks;
- public ushort ChunkNumber;
- };
-
- #endregion
-}
-
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventSourceException.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventSourceException.cs
deleted file mode 100644
index 3fc9d545b8..0000000000
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventSourceException.cs
+++ /dev/null
@@ -1,53 +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.Serialization;
-
-#if ES_BUILD_STANDALONE
-using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment;
-#endif
-
-#if ES_BUILD_STANDALONE
-namespace Microsoft.Diagnostics.Tracing
-#else
-namespace System.Diagnostics.Tracing
-#endif
-{
- /// <summary>
- /// Exception that is thrown when an error occurs during EventSource operation.
- /// </summary>
-#if (!ES_BUILD_PCL && !PROJECTN)
- [Serializable]
-#endif
- public class EventSourceException : Exception
- {
- /// <summary>
- /// Initializes a new instance of the EventSourceException class.
- /// </summary>
- public EventSourceException() :
- base(Resources.GetResourceString("EventSource_ListenerWriteFailure")) { }
-
- /// <summary>
- /// Initializes a new instance of the EventSourceException class with a specified error message.
- /// </summary>
- public EventSourceException(string message) : base(message) { }
-
- /// <summary>
- /// Initializes a new instance of the EventSourceException class with a specified error message
- /// and a reference to the inner exception that is the cause of this exception.
- /// </summary>
- public EventSourceException(string message, Exception innerException) : base(message, innerException) { }
-
-#if (!ES_BUILD_PCL && !PROJECTN)
- /// <summary>
- /// Initializes a new instance of the EventSourceException class with serialized data.
- /// </summary>
- protected EventSourceException(SerializationInfo info, StreamingContext context) : base(info, context) { }
-#endif
-
- internal EventSourceException(Exception innerException) :
- base(Resources.GetResourceString("EventSource_ListenerWriteFailure"), innerException) { }
- }
-}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs
index 0a689efe92..b691dd38b9 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/EventSource_CoreCLR.cs
@@ -128,12 +128,12 @@ namespace System.Diagnostics.Tracing
private static string GetResourceString(string key, params object[] args)
{
- return Environment.GetResourceString(key, args);
+ return SR.Format(SR.GetResourceString(key), args);
}
-
+
private static readonly bool m_EventSourcePreventRecursion = false;
}
-
+
internal partial class ManifestBuilder
{
private string GetTypeNameHelper(Type type)
@@ -174,13 +174,13 @@ namespace System.Diagnostics.Tracing
return "win:Pointer";
else if ((type.IsArray || type.IsPointer) && type.GetElementType() == typeof(byte))
return "win:Binary";
-
+
ManifestError(Resources.GetResourceString("EventSource_UnsupportedEventTypeInManifest", type.Name), true);
return string.Empty;
}
}
}
-
+
internal partial class EventProvider
{
internal unsafe int SetInformation(
@@ -197,7 +197,7 @@ namespace System.Diagnostics.Tracing
status = UnsafeNativeMethods.ManifestEtw.EventSetInformation(
m_regHandle,
eventInfoClass,
- (void *)data,
+ (void*)data,
(int)dataSize);
}
catch (TypeLoadException)
@@ -209,12 +209,12 @@ namespace System.Diagnostics.Tracing
return status;
}
}
-
+
internal static class Resources
{
internal static string GetResourceString(string key, params object[] args)
{
- return Environment.GetResourceString(key, args);
+ return SR.Format(SR.GetResourceString(key), args);
}
}
}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/FrameworkEventSource.cs b/src/mscorlib/src/System/Diagnostics/Eventing/FrameworkEventSource.cs
index 80c524b350..d746f58f24 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/FrameworkEventSource.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/FrameworkEventSource.cs
@@ -8,6 +8,7 @@
//
// Managed event source for things that can version with MSCORLIB.
//
+
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -15,8 +16,8 @@ using System.Reflection;
using System.Text;
using System.Runtime.CompilerServices;
-namespace System.Diagnostics.Tracing {
-
+namespace System.Diagnostics.Tracing
+{
// To use the framework provider
//
// \\clrmain\tools\Perfmonitor /nokernel /noclr /provider:8E9F5090-2D75-4d03-8A81-E5AFBF85DAF1 start
@@ -28,7 +29,8 @@ namespace System.Diagnostics.Tracing {
//
[FriendAccessAllowed]
[EventSource(Guid = "8E9F5090-2D75-4d03-8A81-E5AFBF85DAF1", Name = "System.Diagnostics.Eventing.FrameworkEventSource")]
- sealed internal class FrameworkEventSource : EventSource {
+ sealed internal class FrameworkEventSource : EventSource
+ {
// Defines the singleton instance for the Resources ETW provider
public static readonly FrameworkEventSource Log = new FrameworkEventSource();
@@ -36,16 +38,17 @@ namespace System.Diagnostics.Tracing {
// Often each task has a keyword, but where tasks are determined by subsystem, keywords are determined by
// usefulness to end users to filter. Generally users don't mind extra events if they are not high volume
// so grouping low volume events together in a single keywords is OK (users can post-filter by task if desired)
- public static class Keywords {
- public const EventKeywords Loader = (EventKeywords)0x0001; // This is bit 0
- public const EventKeywords ThreadPool = (EventKeywords)0x0002;
- public const EventKeywords NetClient = (EventKeywords)0x0004;
+ public static class Keywords
+ {
+ public const EventKeywords Loader = (EventKeywords)0x0001; // This is bit 0
+ public const EventKeywords ThreadPool = (EventKeywords)0x0002;
+ public const EventKeywords NetClient = (EventKeywords)0x0004;
//
// This is a private event we do not want to expose to customers. It is to be used for profiling
// uses of dynamic type loading by ProjectN applications running on the desktop CLR
//
public const EventKeywords DynamicTypeUsage = (EventKeywords)0x0008;
- public const EventKeywords ThreadTransfer = (EventKeywords)0x0010;
+ public const EventKeywords ThreadTransfer = (EventKeywords)0x0010;
}
/// <summary>ETW tasks that have start/stop events.</summary>
@@ -53,7 +56,7 @@ namespace System.Diagnostics.Tracing {
public static class Tasks // this name is important for EventSource
{
/// <summary>Begin / End - GetResponse.</summary>
- public const EventTask GetResponse = (EventTask)1;
+ public const EventTask GetResponse = (EventTask)1;
/// <summary>Begin / End - GetRequestStream</summary>
public const EventTask GetRequestStream = (EventTask)2;
/// <summary>Send / Receive - begin transfer/end transfer</summary>
@@ -211,18 +214,21 @@ namespace System.Diagnostics.Tracing {
// ResourceManager Event Definitions
[Event(1, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
- public void ResourceManagerLookupStarted(String baseName, String mainAssemblyName, String cultureName) {
+ public void ResourceManagerLookupStarted(String baseName, String mainAssemblyName, String cultureName)
+ {
WriteEvent(1, baseName, mainAssemblyName, cultureName);
}
[Event(2, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
- public void ResourceManagerLookingForResourceSet(String baseName, String mainAssemblyName, String cultureName) {
+ public void ResourceManagerLookingForResourceSet(String baseName, String mainAssemblyName, String cultureName)
+ {
if (IsEnabled())
WriteEvent(2, baseName, mainAssemblyName, cultureName);
}
[Event(3, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
- public void ResourceManagerFoundResourceSetInCache(String baseName, String mainAssemblyName, String cultureName) {
+ public void ResourceManagerFoundResourceSetInCache(String baseName, String mainAssemblyName, String cultureName)
+ {
if (IsEnabled())
WriteEvent(3, baseName, mainAssemblyName, cultureName);
}
@@ -231,119 +237,138 @@ namespace System.Diagnostics.Tracing {
// the cache. This can happen if you have an assembly load callback that called into this
// instance of the ResourceManager.
[Event(4, Level = EventLevel.Warning, Keywords = Keywords.Loader)]
- public void ResourceManagerFoundResourceSetInCacheUnexpected(String baseName, String mainAssemblyName, String cultureName) {
+ public void ResourceManagerFoundResourceSetInCacheUnexpected(String baseName, String mainAssemblyName, String cultureName)
+ {
if (IsEnabled())
WriteEvent(4, baseName, mainAssemblyName, cultureName);
}
// manifest resource stream lookup succeeded
[Event(5, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
- public void ResourceManagerStreamFound(String baseName, String mainAssemblyName, String cultureName, String loadedAssemblyName, String resourceFileName) {
+ public void ResourceManagerStreamFound(String baseName, String mainAssemblyName, String cultureName, String loadedAssemblyName, String resourceFileName)
+ {
if (IsEnabled())
WriteEvent(5, baseName, mainAssemblyName, cultureName, loadedAssemblyName, resourceFileName);
}
// manifest resource stream lookup failed
[Event(6, Level = EventLevel.Warning, Keywords = Keywords.Loader)]
- public void ResourceManagerStreamNotFound(String baseName, String mainAssemblyName, String cultureName, String loadedAssemblyName, String resourceFileName) {
+ public void ResourceManagerStreamNotFound(String baseName, String mainAssemblyName, String cultureName, String loadedAssemblyName, String resourceFileName)
+ {
if (IsEnabled())
WriteEvent(6, baseName, mainAssemblyName, cultureName, loadedAssemblyName, resourceFileName);
}
[Event(7, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
- public void ResourceManagerGetSatelliteAssemblySucceeded(String baseName, String mainAssemblyName, String cultureName, String assemblyName) {
+ public void ResourceManagerGetSatelliteAssemblySucceeded(String baseName, String mainAssemblyName, String cultureName, String assemblyName)
+ {
if (IsEnabled())
WriteEvent(7, baseName, mainAssemblyName, cultureName, assemblyName);
}
[Event(8, Level = EventLevel.Warning, Keywords = Keywords.Loader)]
- public void ResourceManagerGetSatelliteAssemblyFailed(String baseName, String mainAssemblyName, String cultureName, String assemblyName) {
+ public void ResourceManagerGetSatelliteAssemblyFailed(String baseName, String mainAssemblyName, String cultureName, String assemblyName)
+ {
if (IsEnabled())
WriteEvent(8, baseName, mainAssemblyName, cultureName, assemblyName);
}
[Event(9, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
- public void ResourceManagerCaseInsensitiveResourceStreamLookupSucceeded(String baseName, String mainAssemblyName, String assemblyName, String resourceFileName) {
+ public void ResourceManagerCaseInsensitiveResourceStreamLookupSucceeded(String baseName, String mainAssemblyName, String assemblyName, String resourceFileName)
+ {
if (IsEnabled())
WriteEvent(9, baseName, mainAssemblyName, assemblyName, resourceFileName);
}
[Event(10, Level = EventLevel.Warning, Keywords = Keywords.Loader)]
- public void ResourceManagerCaseInsensitiveResourceStreamLookupFailed(String baseName, String mainAssemblyName, String assemblyName, String resourceFileName) {
+ public void ResourceManagerCaseInsensitiveResourceStreamLookupFailed(String baseName, String mainAssemblyName, String assemblyName, String resourceFileName)
+ {
if (IsEnabled())
WriteEvent(10, baseName, mainAssemblyName, assemblyName, resourceFileName);
}
// Could not access the manifest resource the assembly
[Event(11, Level = EventLevel.Error, Keywords = Keywords.Loader)]
- public void ResourceManagerManifestResourceAccessDenied(String baseName, String mainAssemblyName, String assemblyName, String canonicalName) {
+ public void ResourceManagerManifestResourceAccessDenied(String baseName, String mainAssemblyName, String assemblyName, String canonicalName)
+ {
if (IsEnabled())
WriteEvent(11, baseName, mainAssemblyName, assemblyName, canonicalName);
}
// Neutral resources are sufficient for this culture. Skipping satellites
[Event(12, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
- public void ResourceManagerNeutralResourcesSufficient(String baseName, String mainAssemblyName, String cultureName) {
+ public void ResourceManagerNeutralResourcesSufficient(String baseName, String mainAssemblyName, String cultureName)
+ {
if (IsEnabled())
WriteEvent(12, baseName, mainAssemblyName, cultureName);
}
[Event(13, Level = EventLevel.Warning, Keywords = Keywords.Loader)]
- public void ResourceManagerNeutralResourceAttributeMissing(String mainAssemblyName) {
+ public void ResourceManagerNeutralResourceAttributeMissing(String mainAssemblyName)
+ {
if (IsEnabled())
WriteEvent(13, mainAssemblyName);
}
[Event(14, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
- public void ResourceManagerCreatingResourceSet(String baseName, String mainAssemblyName, String cultureName, String fileName) {
+ public void ResourceManagerCreatingResourceSet(String baseName, String mainAssemblyName, String cultureName, String fileName)
+ {
if (IsEnabled())
WriteEvent(14, baseName, mainAssemblyName, cultureName, fileName);
}
[Event(15, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
- public void ResourceManagerNotCreatingResourceSet(String baseName, String mainAssemblyName, String cultureName) {
+ public void ResourceManagerNotCreatingResourceSet(String baseName, String mainAssemblyName, String cultureName)
+ {
if (IsEnabled())
WriteEvent(15, baseName, mainAssemblyName, cultureName);
}
[Event(16, Level = EventLevel.Warning, Keywords = Keywords.Loader)]
- public void ResourceManagerLookupFailed(String baseName, String mainAssemblyName, String cultureName) {
+ public void ResourceManagerLookupFailed(String baseName, String mainAssemblyName, String cultureName)
+ {
if (IsEnabled())
WriteEvent(16, baseName, mainAssemblyName, cultureName);
}
[Event(17, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
- public void ResourceManagerReleasingResources(String baseName, String mainAssemblyName) {
+ public void ResourceManagerReleasingResources(String baseName, String mainAssemblyName)
+ {
if (IsEnabled())
WriteEvent(17, baseName, mainAssemblyName);
}
[Event(18, Level = EventLevel.Warning, Keywords = Keywords.Loader)]
- public void ResourceManagerNeutralResourcesNotFound(String baseName, String mainAssemblyName, String resName) {
+ public void ResourceManagerNeutralResourcesNotFound(String baseName, String mainAssemblyName, String resName)
+ {
if (IsEnabled())
WriteEvent(18, baseName, mainAssemblyName, resName);
}
[Event(19, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
- public void ResourceManagerNeutralResourcesFound(String baseName, String mainAssemblyName, String resName) {
+ public void ResourceManagerNeutralResourcesFound(String baseName, String mainAssemblyName, String resName)
+ {
if (IsEnabled())
WriteEvent(19, baseName, mainAssemblyName, resName);
}
[Event(20, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
- public void ResourceManagerAddingCultureFromConfigFile(String baseName, String mainAssemblyName, String cultureName) {
+ public void ResourceManagerAddingCultureFromConfigFile(String baseName, String mainAssemblyName, String cultureName)
+ {
if (IsEnabled())
WriteEvent(20, baseName, mainAssemblyName, cultureName);
}
[Event(21, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
- public void ResourceManagerCultureNotFoundInConfigFile(String baseName, String mainAssemblyName, String cultureName) {
+ public void ResourceManagerCultureNotFoundInConfigFile(String baseName, String mainAssemblyName, String cultureName)
+ {
if (IsEnabled())
WriteEvent(21, baseName, mainAssemblyName, cultureName);
}
[Event(22, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
- public void ResourceManagerCultureFoundInConfigFile(String baseName, String mainAssemblyName, String cultureName) {
+ public void ResourceManagerCultureFoundInConfigFile(String baseName, String mainAssemblyName, String cultureName)
+ {
if (IsEnabled())
WriteEvent(22, baseName, mainAssemblyName, cultureName);
}
@@ -352,159 +377,185 @@ namespace System.Diagnostics.Tracing {
// ResourceManager Event Wrappers
[NonEvent]
- public void ResourceManagerLookupStarted(String baseName, Assembly mainAssembly, String cultureName) {
+ public void ResourceManagerLookupStarted(String baseName, Assembly mainAssembly, String cultureName)
+ {
if (IsEnabled())
ResourceManagerLookupStarted(baseName, GetName(mainAssembly), cultureName);
}
[NonEvent]
- public void ResourceManagerLookingForResourceSet(String baseName, Assembly mainAssembly, String cultureName) {
+ public void ResourceManagerLookingForResourceSet(String baseName, Assembly mainAssembly, String cultureName)
+ {
if (IsEnabled())
ResourceManagerLookingForResourceSet(baseName, GetName(mainAssembly), cultureName);
}
[NonEvent]
- public void ResourceManagerFoundResourceSetInCache(String baseName, Assembly mainAssembly, String cultureName) {
+ public void ResourceManagerFoundResourceSetInCache(String baseName, Assembly mainAssembly, String cultureName)
+ {
if (IsEnabled())
ResourceManagerFoundResourceSetInCache(baseName, GetName(mainAssembly), cultureName);
}
[NonEvent]
- public void ResourceManagerFoundResourceSetInCacheUnexpected(String baseName, Assembly mainAssembly, String cultureName) {
+ public void ResourceManagerFoundResourceSetInCacheUnexpected(String baseName, Assembly mainAssembly, String cultureName)
+ {
if (IsEnabled())
ResourceManagerFoundResourceSetInCacheUnexpected(baseName, GetName(mainAssembly), cultureName);
}
[NonEvent]
- public void ResourceManagerStreamFound(String baseName, Assembly mainAssembly, String cultureName, Assembly loadedAssembly, String resourceFileName) {
+ public void ResourceManagerStreamFound(String baseName, Assembly mainAssembly, String cultureName, Assembly loadedAssembly, String resourceFileName)
+ {
if (IsEnabled())
ResourceManagerStreamFound(baseName, GetName(mainAssembly), cultureName, GetName(loadedAssembly), resourceFileName);
}
[NonEvent]
- public void ResourceManagerStreamNotFound(String baseName, Assembly mainAssembly, String cultureName, Assembly loadedAssembly, String resourceFileName) {
+ public void ResourceManagerStreamNotFound(String baseName, Assembly mainAssembly, String cultureName, Assembly loadedAssembly, String resourceFileName)
+ {
if (IsEnabled())
ResourceManagerStreamNotFound(baseName, GetName(mainAssembly), cultureName, GetName(loadedAssembly), resourceFileName);
}
[NonEvent]
- public void ResourceManagerGetSatelliteAssemblySucceeded(String baseName, Assembly mainAssembly, String cultureName, String assemblyName) {
+ public void ResourceManagerGetSatelliteAssemblySucceeded(String baseName, Assembly mainAssembly, String cultureName, String assemblyName)
+ {
if (IsEnabled())
ResourceManagerGetSatelliteAssemblySucceeded(baseName, GetName(mainAssembly), cultureName, assemblyName);
}
[NonEvent]
- public void ResourceManagerGetSatelliteAssemblyFailed(String baseName, Assembly mainAssembly, String cultureName, String assemblyName) {
+ public void ResourceManagerGetSatelliteAssemblyFailed(String baseName, Assembly mainAssembly, String cultureName, String assemblyName)
+ {
if (IsEnabled())
ResourceManagerGetSatelliteAssemblyFailed(baseName, GetName(mainAssembly), cultureName, assemblyName);
}
[NonEvent]
- public void ResourceManagerCaseInsensitiveResourceStreamLookupSucceeded(String baseName, Assembly mainAssembly, String assemblyName, String resourceFileName) {
+ public void ResourceManagerCaseInsensitiveResourceStreamLookupSucceeded(String baseName, Assembly mainAssembly, String assemblyName, String resourceFileName)
+ {
if (IsEnabled())
ResourceManagerCaseInsensitiveResourceStreamLookupSucceeded(baseName, GetName(mainAssembly), assemblyName, resourceFileName);
}
[NonEvent]
- public void ResourceManagerCaseInsensitiveResourceStreamLookupFailed(String baseName, Assembly mainAssembly, String assemblyName, String resourceFileName) {
+ public void ResourceManagerCaseInsensitiveResourceStreamLookupFailed(String baseName, Assembly mainAssembly, String assemblyName, String resourceFileName)
+ {
if (IsEnabled())
ResourceManagerCaseInsensitiveResourceStreamLookupFailed(baseName, GetName(mainAssembly), assemblyName, resourceFileName);
}
[NonEvent]
- public void ResourceManagerManifestResourceAccessDenied(String baseName, Assembly mainAssembly, String assemblyName, String canonicalName) {
+ public void ResourceManagerManifestResourceAccessDenied(String baseName, Assembly mainAssembly, String assemblyName, String canonicalName)
+ {
if (IsEnabled())
ResourceManagerManifestResourceAccessDenied(baseName, GetName(mainAssembly), assemblyName, canonicalName);
}
[NonEvent]
- public void ResourceManagerNeutralResourcesSufficient(String baseName, Assembly mainAssembly, String cultureName) {
- if (IsEnabled())
+ public void ResourceManagerNeutralResourcesSufficient(String baseName, Assembly mainAssembly, String cultureName)
+ {
+ if (IsEnabled())
ResourceManagerNeutralResourcesSufficient(baseName, GetName(mainAssembly), cultureName);
}
[NonEvent]
- public void ResourceManagerNeutralResourceAttributeMissing(Assembly mainAssembly) {
+ public void ResourceManagerNeutralResourceAttributeMissing(Assembly mainAssembly)
+ {
if (IsEnabled())
ResourceManagerNeutralResourceAttributeMissing(GetName(mainAssembly));
}
[NonEvent]
- public void ResourceManagerCreatingResourceSet(String baseName, Assembly mainAssembly, String cultureName, String fileName) {
+ public void ResourceManagerCreatingResourceSet(String baseName, Assembly mainAssembly, String cultureName, String fileName)
+ {
if (IsEnabled())
ResourceManagerCreatingResourceSet(baseName, GetName(mainAssembly), cultureName, fileName);
}
[NonEvent]
- public void ResourceManagerNotCreatingResourceSet(String baseName, Assembly mainAssembly, String cultureName) {
+ public void ResourceManagerNotCreatingResourceSet(String baseName, Assembly mainAssembly, String cultureName)
+ {
if (IsEnabled())
ResourceManagerNotCreatingResourceSet(baseName, GetName(mainAssembly), cultureName);
}
[NonEvent]
- public void ResourceManagerLookupFailed(String baseName, Assembly mainAssembly, String cultureName) {
+ public void ResourceManagerLookupFailed(String baseName, Assembly mainAssembly, String cultureName)
+ {
if (IsEnabled())
ResourceManagerLookupFailed(baseName, GetName(mainAssembly), cultureName);
}
[NonEvent]
- public void ResourceManagerReleasingResources(String baseName, Assembly mainAssembly) {
+ public void ResourceManagerReleasingResources(String baseName, Assembly mainAssembly)
+ {
if (IsEnabled())
ResourceManagerReleasingResources(baseName, GetName(mainAssembly));
}
[NonEvent]
- public void ResourceManagerNeutralResourcesNotFound(String baseName, Assembly mainAssembly, String resName) {
+ public void ResourceManagerNeutralResourcesNotFound(String baseName, Assembly mainAssembly, String resName)
+ {
if (IsEnabled())
ResourceManagerNeutralResourcesNotFound(baseName, GetName(mainAssembly), resName);
}
[NonEvent]
- public void ResourceManagerNeutralResourcesFound(String baseName, Assembly mainAssembly, String resName) {
+ public void ResourceManagerNeutralResourcesFound(String baseName, Assembly mainAssembly, String resName)
+ {
if (IsEnabled())
ResourceManagerNeutralResourcesFound(baseName, GetName(mainAssembly), resName);
}
[NonEvent]
- public void ResourceManagerAddingCultureFromConfigFile(String baseName, Assembly mainAssembly, String cultureName) {
+ public void ResourceManagerAddingCultureFromConfigFile(String baseName, Assembly mainAssembly, String cultureName)
+ {
if (IsEnabled())
ResourceManagerAddingCultureFromConfigFile(baseName, GetName(mainAssembly), cultureName);
}
[NonEvent]
- public void ResourceManagerCultureNotFoundInConfigFile(String baseName, Assembly mainAssembly, String cultureName) {
+ public void ResourceManagerCultureNotFoundInConfigFile(String baseName, Assembly mainAssembly, String cultureName)
+ {
if (IsEnabled())
ResourceManagerCultureNotFoundInConfigFile(baseName, GetName(mainAssembly), cultureName);
}
[NonEvent]
- public void ResourceManagerCultureFoundInConfigFile(String baseName, Assembly mainAssembly, String cultureName) {
+ public void ResourceManagerCultureFoundInConfigFile(String baseName, Assembly mainAssembly, String cultureName)
+ {
if (IsEnabled())
ResourceManagerCultureFoundInConfigFile(baseName, GetName(mainAssembly), cultureName);
}
- private static string GetName(Assembly assembly) {
+ private static string GetName(Assembly assembly)
+ {
if (assembly == null)
return "<<NULL>>";
else
return assembly.FullName;
}
- [Event(30, Level = EventLevel.Verbose, Keywords = Keywords.ThreadPool|Keywords.ThreadTransfer)]
- public void ThreadPoolEnqueueWork(long workID) {
+ [Event(30, Level = EventLevel.Verbose, Keywords = Keywords.ThreadPool | Keywords.ThreadTransfer)]
+ public void ThreadPoolEnqueueWork(long workID)
+ {
WriteEvent(30, workID);
}
[NonEvent]
#if !CORECLR
[System.Security.SecuritySafeCritical]
#endif // !CORECLR
- public unsafe void ThreadPoolEnqueueWorkObject(object workID) {
+ public unsafe void ThreadPoolEnqueueWorkObject(object workID)
+ {
// convert the Object Id to a long
- ThreadPoolEnqueueWork((long) *((void**) JitHelpers.UnsafeCastToStackPointer(ref workID)));
+ ThreadPoolEnqueueWork((long)*((void**)JitHelpers.UnsafeCastToStackPointer(ref workID)));
}
- [Event(31, Level = EventLevel.Verbose, Keywords = Keywords.ThreadPool|Keywords.ThreadTransfer)]
- public void ThreadPoolDequeueWork(long workID) {
+ [Event(31, Level = EventLevel.Verbose, Keywords = Keywords.ThreadPool | Keywords.ThreadTransfer)]
+ public void ThreadPoolDequeueWork(long workID)
+ {
WriteEvent(31, workID);
}
@@ -512,36 +563,41 @@ namespace System.Diagnostics.Tracing {
#if !CORECLR
[System.Security.SecuritySafeCritical]
#endif // !CORECLR
- public unsafe void ThreadPoolDequeueWorkObject(object workID) {
+ public unsafe void ThreadPoolDequeueWorkObject(object workID)
+ {
// convert the Object Id to a long
- ThreadPoolDequeueWork((long) *((void**) JitHelpers.UnsafeCastToStackPointer(ref workID)));
+ ThreadPoolDequeueWork((long)*((void**)JitHelpers.UnsafeCastToStackPointer(ref workID)));
}
// In the desktop runtime they don't use Tasks for the point at which the response happens, which means that the
// Activity ID created by start using implicit activity IDs does not match. Thus disable implicit activities (until we fix that)
- [Event(140, Level = EventLevel.Informational, Keywords = Keywords.NetClient, ActivityOptions=EventActivityOptions.Disable,
+ [Event(140, Level = EventLevel.Informational, Keywords = Keywords.NetClient, ActivityOptions = EventActivityOptions.Disable,
Task = Tasks.GetResponse, Opcode = EventOpcode.Start, Version = 1)]
- private void GetResponseStart(long id, string uri, bool success, bool synchronous) {
+ private void GetResponseStart(long id, string uri, bool success, bool synchronous)
+ {
WriteEvent(140, id, uri, success, synchronous);
}
- [Event(141, Level = EventLevel.Informational, Keywords = Keywords.NetClient, ActivityOptions=EventActivityOptions.Disable,
+ [Event(141, Level = EventLevel.Informational, Keywords = Keywords.NetClient, ActivityOptions = EventActivityOptions.Disable,
Task = Tasks.GetResponse, Opcode = EventOpcode.Stop, Version = 1)]
- private void GetResponseStop(long id, bool success, bool synchronous, int statusCode) {
+ private void GetResponseStop(long id, bool success, bool synchronous, int statusCode)
+ {
WriteEvent(141, id, success, synchronous, statusCode);
}
// In the desktop runtime they don't use Tasks for the point at which the response happens, which means that the
// Activity ID created by start using implicit activity IDs does not match. Thus disable implicit activities (until we fix that)
- [Event(142, Level = EventLevel.Informational, Keywords = Keywords.NetClient, ActivityOptions=EventActivityOptions.Disable,
+ [Event(142, Level = EventLevel.Informational, Keywords = Keywords.NetClient, ActivityOptions = EventActivityOptions.Disable,
Task = Tasks.GetRequestStream, Opcode = EventOpcode.Start, Version = 1)]
- private void GetRequestStreamStart(long id, string uri, bool success, bool synchronous) {
+ private void GetRequestStreamStart(long id, string uri, bool success, bool synchronous)
+ {
WriteEvent(142, id, uri, success, synchronous);
}
- [Event(143, Level = EventLevel.Informational, Keywords = Keywords.NetClient, ActivityOptions=EventActivityOptions.Disable,
+ [Event(143, Level = EventLevel.Informational, Keywords = Keywords.NetClient, ActivityOptions = EventActivityOptions.Disable,
Task = Tasks.GetRequestStream, Opcode = EventOpcode.Stop, Version = 1)]
- private void GetRequestStreamStop(long id, bool success, bool synchronous) {
+ private void GetRequestStreamStop(long id, bool success, bool synchronous)
+ {
WriteEvent(143, id, success, synchronous);
}
@@ -549,16 +605,18 @@ namespace System.Diagnostics.Tracing {
#if !CORECLR
[System.Security.SecuritySafeCritical]
#endif // !CORECLR
- public unsafe void BeginGetResponse(object id, string uri, bool success, bool synchronous) {
+ public unsafe void BeginGetResponse(object id, string uri, bool success, bool synchronous)
+ {
if (IsEnabled())
GetResponseStart(IdForObject(id), uri, success, synchronous);
}
-
+
[NonEvent]
#if !CORECLR
[System.Security.SecuritySafeCritical]
#endif // !CORECLR
- public unsafe void EndGetResponse(object id, bool success, bool synchronous, int statusCode) {
+ public unsafe void EndGetResponse(object id, bool success, bool synchronous, int statusCode)
+ {
if (IsEnabled())
GetResponseStop(IdForObject(id), success, synchronous, statusCode);
}
@@ -567,7 +625,8 @@ namespace System.Diagnostics.Tracing {
#if !CORECLR
[System.Security.SecuritySafeCritical]
#endif // !CORECLR
- public unsafe void BeginGetRequestStream(object id, string uri, bool success, bool synchronous) {
+ public unsafe void BeginGetRequestStream(object id, string uri, bool success, bool synchronous)
+ {
if (IsEnabled())
GetRequestStreamStart(IdForObject(id), uri, success, synchronous);
}
@@ -576,7 +635,8 @@ namespace System.Diagnostics.Tracing {
#if !CORECLR
[System.Security.SecuritySafeCritical]
#endif // !CORECLR
- public unsafe void EndGetRequestStream(object id, bool success, bool synchronous) {
+ public unsafe void EndGetRequestStream(object id, bool success, bool synchronous)
+ {
if (IsEnabled())
GetRequestStreamStop(IdForObject(id), success, synchronous);
}
@@ -589,7 +649,8 @@ namespace System.Diagnostics.Tracing {
// 3 - WinRT dispatch operations
// info - any additional information user code might consider interesting
[Event(150, Level = EventLevel.Informational, Keywords = Keywords.ThreadTransfer, Task = Tasks.ThreadTransfer, Opcode = EventOpcode.Send)]
- public void ThreadTransferSend(long id, int kind, string info, bool multiDequeues) {
+ public void ThreadTransferSend(long id, int kind, string info, bool multiDequeues)
+ {
if (IsEnabled())
WriteEvent(150, id, kind, info, multiDequeues);
}
@@ -600,8 +661,9 @@ namespace System.Diagnostics.Tracing {
#if !CORECLR
[System.Security.SecuritySafeCritical]
#endif // !CORECLR
- public unsafe void ThreadTransferSendObj(object id, int kind, string info, bool multiDequeues) {
- ThreadTransferSend((long) *((void**) JitHelpers.UnsafeCastToStackPointer(ref id)), kind, info, multiDequeues);
+ public unsafe void ThreadTransferSendObj(object id, int kind, string info, bool multiDequeues)
+ {
+ ThreadTransferSend((long)*((void**)JitHelpers.UnsafeCastToStackPointer(ref id)), kind, info, multiDequeues);
}
// id - represents a correlation ID that allows correlation of two activities, one stamped by
@@ -612,7 +674,8 @@ namespace System.Diagnostics.Tracing {
// 3 - WinRT dispatch operations
// info - any additional information user code might consider interesting
[Event(151, Level = EventLevel.Informational, Keywords = Keywords.ThreadTransfer, Task = Tasks.ThreadTransfer, Opcode = EventOpcode.Receive)]
- public void ThreadTransferReceive(long id, int kind, string info) {
+ public void ThreadTransferReceive(long id, int kind, string info)
+ {
if (IsEnabled())
WriteEvent(151, id, kind, info);
}
@@ -623,8 +686,9 @@ namespace System.Diagnostics.Tracing {
#if !CORECLR
[System.Security.SecuritySafeCritical]
#endif // !CORECLR
- public unsafe void ThreadTransferReceiveObj(object id, int kind, string info) {
- ThreadTransferReceive((long) *((void**) JitHelpers.UnsafeCastToStackPointer(ref id)), kind, info);
+ public unsafe void ThreadTransferReceiveObj(object id, int kind, string info)
+ {
+ ThreadTransferReceive((long)*((void**)JitHelpers.UnsafeCastToStackPointer(ref id)), kind, info);
}
// id - represents a correlation ID that allows correlation of two activities, one stamped by
@@ -635,7 +699,8 @@ namespace System.Diagnostics.Tracing {
// 3 - WinRT dispatch operations
// info - any additional information user code might consider interesting
[Event(152, Level = EventLevel.Informational, Keywords = Keywords.ThreadTransfer, Task = Tasks.ThreadTransfer, Opcode = Opcodes.ReceiveHandled)]
- public void ThreadTransferReceiveHandled(long id, int kind, string info) {
+ public void ThreadTransferReceiveHandled(long id, int kind, string info)
+ {
if (IsEnabled())
WriteEvent(152, id, kind, info);
}
@@ -646,15 +711,17 @@ namespace System.Diagnostics.Tracing {
#if !CORECLR
[System.Security.SecuritySafeCritical]
#endif // !CORECLR
- public unsafe void ThreadTransferReceiveHandledObj(object id, int kind, string info) {
- ThreadTransferReceive((long) *((void**) JitHelpers.UnsafeCastToStackPointer(ref id)), kind, info);
+ public unsafe void ThreadTransferReceiveHandledObj(object id, int kind, string info)
+ {
+ ThreadTransferReceive((long)*((void**)JitHelpers.UnsafeCastToStackPointer(ref id)), kind, info);
}
// return a stable ID for a an object. We use the hash code which is not truely unique but is
// close enough for now at least. we add to it 0x7FFFFFFF00000000 to make it distinguishable
// from the style of ID that simply casts the object reference to a long (since old versions of the
// runtime will emit IDs of that form).
- private static long IdForObject(object obj) {
+ private static long IdForObject(object obj)
+ {
return obj.GetHashCode() + 0x7FFFFFFF00000000;
}
}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/StubEnvironment.cs b/src/mscorlib/src/System/Diagnostics/Eventing/StubEnvironment.cs
deleted file mode 100644
index e090c4f106..0000000000
--- a/src/mscorlib/src/System/Diagnostics/Eventing/StubEnvironment.cs
+++ /dev/null
@@ -1,373 +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.Collections.Generic;
-
-#if ES_BUILD_STANDALONE
-namespace Microsoft.Diagnostics.Tracing.Internal
-#else
-namespace System.Diagnostics.Tracing.Internal
-#endif
-{
-#if ES_BUILD_AGAINST_DOTNET_V35
- using Microsoft.Internal;
-#endif
- using Microsoft.Reflection;
- using System.Reflection;
-
- internal static class Environment
- {
- public static readonly string NewLine = System.Environment.NewLine;
-
- public static int TickCount
- { get { return System.Environment.TickCount; } }
-
- public static string GetResourceString(string key, params object[] args)
- {
- string fmt = rm.GetString(key);
- if (fmt != null)
- return string.Format(fmt, args);
-
- string sargs = String.Empty;
- foreach(var arg in args)
- {
- if (sargs != String.Empty)
- sargs += ", ";
- sargs += arg.ToString();
- }
-
- return key + " (" + sargs + ")";
- }
-
- public static string GetRuntimeResourceString(string key, params object[] args)
- {
- return GetResourceString(key, args);
- }
-
- private static System.Resources.ResourceManager rm = new System.Resources.ResourceManager("Microsoft.Diagnostics.Tracing.Messages", typeof(Environment).Assembly());
- }
-}
-
-#if ES_BUILD_AGAINST_DOTNET_V35
-
-namespace Microsoft.Diagnostics.Contracts.Internal
-{
- internal class Contract
- {
- public static void Assert(bool invariant)
- {
- Assert(invariant, string.Empty);
- }
- public static void Assert(bool invariant, string message)
- {
- if (!invariant)
- {
- if (System.Diagnostics.Debugger.IsAttached)
- System.Diagnostics.Debugger.Break();
- throw new Exception("Assertion failed: " + message);
- }
- }
- public static void EndContractBlock()
- { }
- }
-}
-
-
-namespace Microsoft.Internal
-{
- using System.Text;
-
- internal static class Tuple
- {
- public static Tuple<T1> Create<T1>(T1 item1)
- {
- return new Tuple<T1>(item1);
- }
-
- public static Tuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2)
- {
- return new Tuple<T1, T2>(item1, item2);
- }
- }
-
- [Serializable]
- internal class Tuple<T1>
- {
- private readonly T1 m_Item1;
-
- public T1 Item1 { get { return m_Item1; } }
-
- public Tuple(T1 item1)
- {
- m_Item1 = item1;
- }
-
- public override string ToString()
- {
- StringBuilder sb = new StringBuilder();
- sb.Append("(");
- sb.Append(m_Item1);
- sb.Append(")");
- return sb.ToString();
- }
-
- int Size
- {
- get
- {
- return 1;
- }
- }
- }
-
- [Serializable]
- public class Tuple<T1, T2>
- {
- private readonly T1 m_Item1;
- private readonly T2 m_Item2;
-
- public T1 Item1 { get { return m_Item1; } }
- public T2 Item2 { get { return m_Item2; } }
-
- public Tuple(T1 item1, T2 item2)
- {
- m_Item1 = item1;
- m_Item2 = item2;
- }
-
- public override string ToString()
- {
- StringBuilder sb = new StringBuilder();
- sb.Append("(");
- sb.Append(m_Item1);
- sb.Append(", ");
- sb.Append(m_Item2);
- sb.Append(")");
- return sb.ToString();
- }
-
- int Size
- {
- get
- {
- return 2;
- }
- }
- }
-}
-
-#endif
-
-namespace Microsoft.Reflection
-{
- using System.Reflection;
-
-#if (ES_BUILD_PCL || PROJECTN)
- [Flags]
- public enum BindingFlags
- {
- DeclaredOnly = 0x02, // Only look at the members declared on the Type
- Instance = 0x04, // Include Instance members in search
- Static = 0x08, // Include Static members in search
- Public = 0x10, // Include Public members in search
- NonPublic = 0x20, // Include Non-Public members in search
- }
-
- public enum TypeCode {
- Empty = 0, // Null reference
- Object = 1, // Instance that isn't a value
- DBNull = 2, // Database null value
- Boolean = 3, // Boolean
- Char = 4, // Unicode character
- SByte = 5, // Signed 8-bit integer
- Byte = 6, // Unsigned 8-bit integer
- Int16 = 7, // Signed 16-bit integer
- UInt16 = 8, // Unsigned 16-bit integer
- Int32 = 9, // Signed 32-bit integer
- UInt32 = 10, // Unsigned 32-bit integer
- Int64 = 11, // Signed 64-bit integer
- UInt64 = 12, // Unsigned 64-bit integer
- Single = 13, // IEEE 32-bit float
- Double = 14, // IEEE 64-bit double
- Decimal = 15, // Decimal
- DateTime = 16, // DateTime
- String = 18, // Unicode character string
- }
-#endif
- static class ReflectionExtensions
- {
-#if (!ES_BUILD_PCL && !PROJECTN)
-
- //
- // Type extension methods
- //
- public static bool IsEnum(this Type type) { return type.IsEnum; }
- public static bool IsAbstract(this Type type) { return type.IsAbstract; }
- public static bool IsSealed(this Type type) { return type.IsSealed; }
- public static bool IsValueType(this Type type) { return type.IsValueType; }
- public static bool IsGenericType(this Type type) { return type.IsGenericType; }
- public static Type BaseType(this Type type) { return type.BaseType; }
- public static Assembly Assembly(this Type type) { return type.Assembly; }
- public static TypeCode GetTypeCode(this Type type) { return Type.GetTypeCode(type); }
-
- public static bool ReflectionOnly(this Assembly assm) { return assm.ReflectionOnly; }
-
-#else // ES_BUILD_PCL
-
- //
- // Type extension methods
- //
- public static bool IsEnum(this Type type) { return type.GetTypeInfo().IsEnum; }
- public static bool IsAbstract(this Type type) { return type.GetTypeInfo().IsAbstract; }
- public static bool IsSealed(this Type type) { return type.GetTypeInfo().IsSealed; }
- public static bool IsValueType(this Type type) { return type.GetTypeInfo().IsValueType; }
- public static bool IsGenericType(this Type type) { return type.IsConstructedGenericType; }
- public static Type BaseType(this Type type) { return type.GetTypeInfo().BaseType; }
- public static Assembly Assembly(this Type type) { return type.GetTypeInfo().Assembly; }
- public static IEnumerable<PropertyInfo> GetProperties(this Type type) { return type.GetRuntimeProperties(); }
- public static MethodInfo GetGetMethod(this PropertyInfo propInfo) { return propInfo.GetMethod; }
- public static Type[] GetGenericArguments(this Type type) { return type.GenericTypeArguments; }
-
- public static MethodInfo[] GetMethods(this Type type, BindingFlags flags)
- {
- // Minimal implementation to cover only the cases we need
- System.Diagnostics.Debug.Assert((flags & BindingFlags.DeclaredOnly) != 0);
- System.Diagnostics.Debug.Assert((flags & ~(BindingFlags.DeclaredOnly|BindingFlags.Instance|BindingFlags.Static|BindingFlags.Public|BindingFlags.NonPublic)) == 0);
- Func<MethodInfo, bool> visFilter;
- Func<MethodInfo, bool> instFilter;
- switch (flags & (BindingFlags.Public | BindingFlags.NonPublic))
- {
- case 0: visFilter = mi => false; break;
- case BindingFlags.Public: visFilter = mi => mi.IsPublic; break;
- case BindingFlags.NonPublic: visFilter = mi => !mi.IsPublic; break;
- default: visFilter = mi => true; break;
- }
- switch (flags & (BindingFlags.Instance | BindingFlags.Static))
- {
- case 0: instFilter = mi => false; break;
- case BindingFlags.Instance: instFilter = mi => !mi.IsStatic; break;
- case BindingFlags.Static: instFilter = mi => mi.IsStatic; break;
- default: instFilter = mi => true; break;
- }
- List<MethodInfo> methodInfos = new List<MethodInfo>();
- foreach (var declaredMethod in type.GetTypeInfo().DeclaredMethods)
- {
- if (visFilter(declaredMethod) && instFilter(declaredMethod))
- methodInfos.Add(declaredMethod);
- }
- return methodInfos.ToArray();
- }
- public static FieldInfo[] GetFields(this Type type, BindingFlags flags)
- {
- // Minimal implementation to cover only the cases we need
- System.Diagnostics.Debug.Assert((flags & BindingFlags.DeclaredOnly) != 0);
- System.Diagnostics.Debug.Assert((flags & ~(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) == 0);
- Func<FieldInfo, bool> visFilter;
- Func<FieldInfo, bool> instFilter;
- switch (flags & (BindingFlags.Public | BindingFlags.NonPublic))
- {
- case 0: visFilter = fi => false; break;
- case BindingFlags.Public: visFilter = fi => fi.IsPublic; break;
- case BindingFlags.NonPublic: visFilter = fi => !fi.IsPublic; break;
- default: visFilter = fi => true; break;
- }
- switch (flags & (BindingFlags.Instance | BindingFlags.Static))
- {
- case 0: instFilter = fi => false; break;
- case BindingFlags.Instance: instFilter = fi => !fi.IsStatic; break;
- case BindingFlags.Static: instFilter = fi => fi.IsStatic; break;
- default: instFilter = fi => true; break;
- }
- List<FieldInfo> fieldInfos = new List<FieldInfo>();
- foreach (var declaredField in type.GetTypeInfo().DeclaredFields)
- {
- if (visFilter(declaredField) && instFilter(declaredField))
- fieldInfos.Add(declaredField);
- }
- return fieldInfos.ToArray();
- }
- public static Type GetNestedType(this Type type, string nestedTypeName)
- {
- TypeInfo ti = null;
- foreach(var nt in type.GetTypeInfo().DeclaredNestedTypes)
- {
- if (nt.Name == nestedTypeName)
- {
- ti = nt;
- break;
- }
- }
- return ti == null ? null : ti.AsType();
- }
- public static TypeCode GetTypeCode(this Type type)
- {
- if (type == typeof(bool)) return TypeCode.Boolean;
- else if (type == typeof(byte)) return TypeCode.Byte;
- else if (type == typeof(char)) return TypeCode.Char;
- else if (type == typeof(ushort)) return TypeCode.UInt16;
- else if (type == typeof(uint)) return TypeCode.UInt32;
- else if (type == typeof(ulong)) return TypeCode.UInt64;
- else if (type == typeof(sbyte)) return TypeCode.SByte;
- else if (type == typeof(short)) return TypeCode.Int16;
- else if (type == typeof(int)) return TypeCode.Int32;
- else if (type == typeof(long)) return TypeCode.Int64;
- else if (type == typeof(string)) return TypeCode.String;
- else if (type == typeof(float)) return TypeCode.Single;
- else if (type == typeof(double)) return TypeCode.Double;
- else if (type == typeof(DateTime)) return TypeCode.DateTime;
- else if (type == (typeof(Decimal))) return TypeCode.Decimal;
- else return TypeCode.Object;
- }
-
- //
- // FieldInfo extension methods
- //
- public static object GetRawConstantValue(this FieldInfo fi)
- { return fi.GetValue(null); }
-
- //
- // Assembly extension methods
- //
- public static bool ReflectionOnly(this Assembly assm)
- {
- // In PCL we can't load in reflection-only context
- return false;
- }
-
-#endif
- }
-}
-
-// Defining some no-ops in PCL builds
-#if ES_BUILD_PCL || PROJECTN
-namespace System.Security
-{
- class SuppressUnmanagedCodeSecurityAttribute : Attribute { }
-
- enum SecurityAction { Demand }
-}
-namespace System.Security.Permissions
-{
- class HostProtectionAttribute : Attribute { public bool MayLeakOnAbort { get; set; } }
- class PermissionSetAttribute : Attribute
- {
- public PermissionSetAttribute(System.Security.SecurityAction action) { }
- public bool Unrestricted { get; set; }
- }
-}
-#endif
-
-#if PROJECTN
-namespace System
-{
- public static class AppDomain
- {
- public static int GetCurrentThreadId()
- {
- return (int)Interop.mincore.GetCurrentThreadId();
- }
- }
-}
-#endif
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/DataCollector.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/DataCollector.cs
deleted file mode 100644
index 079d7f480b..0000000000
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/DataCollector.cs
+++ /dev/null
@@ -1,318 +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.InteropServices;
-using System.Security;
-
-#if ES_BUILD_STANDALONE
-using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment;
-namespace Microsoft.Diagnostics.Tracing
-#else
-namespace System.Diagnostics.Tracing
-#endif
-{
- /// <summary>
- /// TraceLogging: This is the implementation of the DataCollector
- /// functionality. To enable safe access to the DataCollector from
- /// untrusted code, there is one thread-local instance of this structure
- /// per thread. The instance must be Enabled before any data is written to
- /// it. The instance must be Finished before the data is passed to
- /// EventWrite. The instance must be Disabled before the arrays referenced
- /// by the pointers are freed or unpinned.
- /// </summary>
- internal unsafe struct DataCollector
- {
- [ThreadStatic]
- internal static DataCollector ThreadInstance;
-
- private byte* scratchEnd;
- private EventSource.EventData* datasEnd;
- private GCHandle* pinsEnd;
- private EventSource.EventData* datasStart;
- private byte* scratch;
- private EventSource.EventData* datas;
- private GCHandle* pins;
- private byte[] buffer;
- private int bufferPos;
- private int bufferNesting; // We may merge many fields int a single blob. If we are doing this we increment this.
- private bool writingScalars;
-
- internal void Enable(
- byte* scratch,
- int scratchSize,
- EventSource.EventData* datas,
- int dataCount,
- GCHandle* pins,
- int pinCount)
- {
- this.datasStart = datas;
- this.scratchEnd = scratch + scratchSize;
- this.datasEnd = datas + dataCount;
- this.pinsEnd = pins + pinCount;
- this.scratch = scratch;
- this.datas = datas;
- this.pins = pins;
- this.writingScalars = false;
- }
-
- internal void Disable()
- {
- this = new DataCollector();
- }
-
- /// <summary>
- /// Completes the list of scalars. Finish must be called before the data
- /// descriptor array is passed to EventWrite.
- /// </summary>
- /// <returns>
- /// A pointer to the next unused data descriptor, or datasEnd if they were
- /// all used. (Descriptors may be unused if a string or array was null.)
- /// </returns>
- internal EventSource.EventData* Finish()
- {
- this.ScalarsEnd();
- return this.datas;
- }
-
- internal void AddScalar(void* value, int size)
- {
- var pb = (byte*)value;
- if (this.bufferNesting == 0)
- {
- var scratchOld = this.scratch;
- var scratchNew = scratchOld + size;
- if (this.scratchEnd < scratchNew)
- {
- throw new IndexOutOfRangeException(Resources.GetResourceString("EventSource_AddScalarOutOfRange"));
- }
-
- this.ScalarsBegin();
- this.scratch = scratchNew;
-
- for (int i = 0; i != size; i++)
- {
- scratchOld[i] = pb[i];
- }
- }
- else
- {
- var oldPos = this.bufferPos;
- this.bufferPos = checked(this.bufferPos + size);
- this.EnsureBuffer();
- for (int i = 0; i != size; i++, oldPos++)
- {
- this.buffer[oldPos] = pb[i];
- }
- }
- }
-
- internal void AddBinary(string value, int size)
- {
- if (size > ushort.MaxValue)
- {
- size = ushort.MaxValue - 1;
- }
-
- if (this.bufferNesting != 0)
- {
- this.EnsureBuffer(size + 2);
- }
-
- this.AddScalar(&size, 2);
-
- if (size != 0)
- {
- if (this.bufferNesting == 0)
- {
- this.ScalarsEnd();
- this.PinArray(value, size);
- }
- else
- {
- var oldPos = this.bufferPos;
- this.bufferPos = checked(this.bufferPos + size);
- this.EnsureBuffer();
- fixed (void* p = value)
- {
- Marshal.Copy((IntPtr)p, this.buffer, oldPos, size);
- }
- }
- }
- }
-
- internal void AddBinary(Array value, int size)
- {
- this.AddArray(value, size, 1);
- }
-
- internal void AddArray(Array value, int length, int itemSize)
- {
- if (length > ushort.MaxValue)
- {
- length = ushort.MaxValue;
- }
-
- var size = length * itemSize;
- if (this.bufferNesting != 0)
- {
- this.EnsureBuffer(size + 2);
- }
-
- this.AddScalar(&length, 2);
-
- if (length != 0)
- {
- if (this.bufferNesting == 0)
- {
- this.ScalarsEnd();
- this.PinArray(value, size);
- }
- else
- {
- var oldPos = this.bufferPos;
- this.bufferPos = checked(this.bufferPos + size);
- this.EnsureBuffer();
- Buffer.BlockCopy(value, 0, this.buffer, oldPos, size);
- }
- }
- }
-
- /// <summary>
- /// Marks the start of a non-blittable array or enumerable.
- /// </summary>
- /// <returns>Bookmark to be passed to EndBufferedArray.</returns>
- internal int BeginBufferedArray()
- {
- this.BeginBuffered();
- this.bufferPos += 2; // Reserve space for the array length (filled in by EndEnumerable)
- return this.bufferPos;
- }
-
- /// <summary>
- /// Marks the end of a non-blittable array or enumerable.
- /// </summary>
- /// <param name="bookmark">The value returned by BeginBufferedArray.</param>
- /// <param name="count">The number of items in the array.</param>
- internal void EndBufferedArray(int bookmark, int count)
- {
- this.EnsureBuffer();
- this.buffer[bookmark - 2] = unchecked((byte)count);
- this.buffer[bookmark - 1] = unchecked((byte)(count >> 8));
- this.EndBuffered();
- }
-
- /// <summary>
- /// Marks the start of dynamically-buffered data.
- /// </summary>
- internal void BeginBuffered()
- {
- this.ScalarsEnd();
- this.bufferNesting += 1;
- }
-
- /// <summary>
- /// Marks the end of dynamically-buffered data.
- /// </summary>
- internal void EndBuffered()
- {
- this.bufferNesting -= 1;
-
- if (this.bufferNesting == 0)
- {
- /*
- TODO (perf): consider coalescing adjacent buffered regions into a
- single buffer, similar to what we're already doing for adjacent
- scalars. In addition, if a type contains a buffered region adjacent
- to a blittable array, and the blittable array is small, it would be
- more efficient to buffer the array instead of pinning it.
- */
-
- this.EnsureBuffer();
- this.PinArray(this.buffer, this.bufferPos);
- this.buffer = null;
- this.bufferPos = 0;
- }
- }
-
- private void EnsureBuffer()
- {
- var required = this.bufferPos;
- if (this.buffer == null || this.buffer.Length < required)
- {
- this.GrowBuffer(required);
- }
- }
-
- private void EnsureBuffer(int additionalSize)
- {
- var required = this.bufferPos + additionalSize;
- if (this.buffer == null || this.buffer.Length < required)
- {
- this.GrowBuffer(required);
- }
- }
-
- private void GrowBuffer(int required)
- {
- var newSize = this.buffer == null ? 64 : this.buffer.Length;
-
- do
- {
- newSize *= 2;
- }
- while (newSize < required);
-
- Array.Resize(ref this.buffer, newSize);
- }
-
- private void PinArray(object value, int size)
- {
- var pinsTemp = this.pins;
- if (this.pinsEnd <= pinsTemp)
- {
- throw new IndexOutOfRangeException(Resources.GetResourceString("EventSource_PinArrayOutOfRange"));
- }
-
- var datasTemp = this.datas;
- if (this.datasEnd <= datasTemp)
- {
- throw new IndexOutOfRangeException(Resources.GetResourceString("EventSource_DataDescriptorsOutOfRange"));
- }
-
- this.pins = pinsTemp + 1;
- this.datas = datasTemp + 1;
-
- *pinsTemp = GCHandle.Alloc(value, GCHandleType.Pinned);
- datasTemp->m_Ptr = (long)(ulong)(UIntPtr)(void*)pinsTemp->AddrOfPinnedObject();
- datasTemp->m_Size = size;
- }
-
- private void ScalarsBegin()
- {
- if (!this.writingScalars)
- {
- var datasTemp = this.datas;
- if (this.datasEnd <= datasTemp)
- {
- throw new IndexOutOfRangeException(Resources.GetResourceString("EventSource_DataDescriptorsOutOfRange"));
- }
-
- datasTemp->m_Ptr = (long)(ulong)(UIntPtr)this.scratch;
- this.writingScalars = true;
- }
- }
-
- private void ScalarsEnd()
- {
- if (this.writingScalars)
- {
- var datasTemp = this.datas;
- datasTemp->m_Size = checked((int)(this.scratch - (byte*)datasTemp->m_Ptr));
- this.datas = datasTemp + 1;
- this.writingScalars = false;
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/Statics.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/Statics.cs
deleted file mode 100644
index 516c8ba19a..0000000000
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/Statics.cs
+++ /dev/null
@@ -1,727 +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.Collections.Generic;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using Encoding = System.Text.Encoding;
-
-using Microsoft.Reflection;
-
-#if ES_BUILD_STANDALONE
-using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment;
-namespace Microsoft.Diagnostics.Tracing
-#else
-namespace System.Diagnostics.Tracing
-#endif
-{
- /// <summary>
- /// TraceLogging: Constants and utility functions.
- /// </summary>
- internal static class Statics
- {
- #region Constants
-
- public const byte DefaultLevel = 5;
- public const byte TraceLoggingChannel = 0xb;
- public const byte InTypeMask = 31;
- public const byte InTypeFixedCountFlag = 32;
- public const byte InTypeVariableCountFlag = 64;
- public const byte InTypeCustomCountFlag = 96;
- public const byte InTypeCountMask = 96;
- public const byte InTypeChainFlag = 128;
- public const byte OutTypeMask = 127;
- public const byte OutTypeChainFlag = 128;
- public const EventTags EventTagsMask = (EventTags)0xfffffff;
-
- public static readonly TraceLoggingDataType IntPtrType = IntPtr.Size == 8
- ? TraceLoggingDataType.Int64
- : TraceLoggingDataType.Int32;
- public static readonly TraceLoggingDataType UIntPtrType = IntPtr.Size == 8
- ? TraceLoggingDataType.UInt64
- : TraceLoggingDataType.UInt32;
- public static readonly TraceLoggingDataType HexIntPtrType = IntPtr.Size == 8
- ? TraceLoggingDataType.HexInt64
- : TraceLoggingDataType.HexInt32;
-
- #endregion
-
- #region Metadata helpers
-
- /// <summary>
- /// A complete metadata chunk can be expressed as:
- /// length16 + prefix + null-terminated-utf8-name + suffix + additionalData.
- /// We assume that excludedData will be provided by some other means,
- /// but that its size is known. This function returns a blob containing
- /// length16 + prefix + name + suffix, with prefix and suffix initialized
- /// to 0's. The length16 value is initialized to the length of the returned
- /// blob plus additionalSize, so that the concatenation of the returned blob
- /// plus a blob of size additionalSize constitutes a valid metadata blob.
- /// </summary>
- /// <param name="name">
- /// The name to include in the blob.
- /// </param>
- /// <param name="prefixSize">
- /// Amount of space to reserve before name. For provider or field blobs, this
- /// should be 0. For event blobs, this is used for the tags field and will vary
- /// from 1 to 4, depending on how large the tags field needs to be.
- /// </param>
- /// <param name="suffixSize">
- /// Amount of space to reserve after name. For example, a provider blob with no
- /// traits would reserve 0 extra bytes, but a provider blob with a single GroupId
- /// field would reserve 19 extra bytes.
- /// </param>
- /// <param name="additionalSize">
- /// Amount of additional data in another blob. This value will be counted in the
- /// blob's length field, but will not be included in the returned byte[] object.
- /// The complete blob would then be the concatenation of the returned byte[] object
- /// with another byte[] object of length additionalSize.
- /// </param>
- /// <returns>
- /// A byte[] object with the length and name fields set, with room reserved for
- /// prefix and suffix. If additionalSize was 0, the byte[] object is a complete
- /// blob. Otherwise, another byte[] of size additionalSize must be concatenated
- /// with this one to form a complete blob.
- /// </returns>
- public static byte[] MetadataForString(
- string name,
- int prefixSize,
- int suffixSize,
- int additionalSize)
- {
- Statics.CheckName(name);
- int metadataSize = Encoding.UTF8.GetByteCount(name) + 3 + prefixSize + suffixSize;
- var metadata = new byte[metadataSize];
- ushort totalSize = checked((ushort)(metadataSize + additionalSize));
- metadata[0] = unchecked((byte)totalSize);
- metadata[1] = unchecked((byte)(totalSize >> 8));
- Encoding.UTF8.GetBytes(name, 0, name.Length, metadata, 2 + prefixSize);
- return metadata;
- }
-
- /// <summary>
- /// Serialize the low 28 bits of the tags value into the metadata stream,
- /// starting at the index given by pos. Updates pos. Writes 1 to 4 bytes,
- /// depending on the value of the tags variable. Usable for event tags and
- /// field tags.
- ///
- /// Note that 'metadata' can be null, in which case it only updates 'pos'.
- /// This is useful for a two pass approach where you figure out how big to
- /// make the array, and then you fill it in.
- /// </summary>
- public static void EncodeTags(int tags, ref int pos, byte[] metadata)
- {
- // We transmit the low 28 bits of tags, high bits first, 7 bits at a time.
- var tagsLeft = tags & 0xfffffff;
- bool more;
- do
- {
- byte current = (byte)((tagsLeft >> 21) & 0x7f);
- more = (tagsLeft & 0x1fffff) != 0;
- current |= (byte)(more ? 0x80 : 0x00);
- tagsLeft = tagsLeft << 7;
-
- if (metadata != null)
- {
- metadata[pos] = current;
- }
- pos += 1;
- }
- while (more);
- }
-
- public static byte Combine(
- int settingValue,
- byte defaultValue)
- {
- unchecked
- {
- return (byte)settingValue == settingValue
- ? (byte)settingValue
- : defaultValue;
- }
- }
-
- public static byte Combine(
- int settingValue1,
- int settingValue2,
- byte defaultValue)
- {
- unchecked
- {
- return (byte)settingValue1 == settingValue1
- ? (byte)settingValue1
- : (byte)settingValue2 == settingValue2
- ? (byte)settingValue2
- : defaultValue;
- }
- }
-
- public static int Combine(
- int settingValue1,
- int settingValue2)
- {
- unchecked
- {
- return (byte)settingValue1 == settingValue1
- ? settingValue1
- : settingValue2;
- }
- }
-
- public static void CheckName(string name)
- {
- if (name != null && 0 <= name.IndexOf('\0'))
- {
- throw new ArgumentOutOfRangeException(nameof(name));
- }
- }
-
- public static bool ShouldOverrideFieldName(string fieldName)
- {
- return (fieldName.Length <= 2 && fieldName[0] == '_');
- }
-
- public static TraceLoggingDataType MakeDataType(
- TraceLoggingDataType baseType,
- EventFieldFormat format)
- {
- return (TraceLoggingDataType)(((int)baseType & 0x1f) | ((int)format << 8));
- }
-
- /// <summary>
- /// Adjusts the native type based on format.
- /// - If format is default, return native.
- /// - If format is recognized, return the canonical type for that format.
- /// - Otherwise remove existing format from native and apply the requested format.
- /// </summary>
- public static TraceLoggingDataType Format8(
- EventFieldFormat format,
- TraceLoggingDataType native)
- {
- switch (format)
- {
- case EventFieldFormat.Default:
- return native;
- case EventFieldFormat.String:
- return TraceLoggingDataType.Char8;
- case EventFieldFormat.Boolean:
- return TraceLoggingDataType.Boolean8;
- case EventFieldFormat.Hexadecimal:
- return TraceLoggingDataType.HexInt8;
-#if false
- case EventSourceFieldFormat.Signed:
- return TraceLoggingDataType.Int8;
- case EventSourceFieldFormat.Unsigned:
- return TraceLoggingDataType.UInt8;
-#endif
- default:
- return MakeDataType(native, format);
- }
- }
-
- /// <summary>
- /// Adjusts the native type based on format.
- /// - If format is default, return native.
- /// - If format is recognized, return the canonical type for that format.
- /// - Otherwise remove existing format from native and apply the requested format.
- /// </summary>
- public static TraceLoggingDataType Format16(
- EventFieldFormat format,
- TraceLoggingDataType native)
- {
- switch (format)
- {
- case EventFieldFormat.Default:
- return native;
- case EventFieldFormat.String:
- return TraceLoggingDataType.Char16;
- case EventFieldFormat.Hexadecimal:
- return TraceLoggingDataType.HexInt16;
-#if false
- case EventSourceFieldFormat.Port:
- return TraceLoggingDataType.Port;
- case EventSourceFieldFormat.Signed:
- return TraceLoggingDataType.Int16;
- case EventSourceFieldFormat.Unsigned:
- return TraceLoggingDataType.UInt16;
-#endif
- default:
- return MakeDataType(native, format);
- }
- }
-
- /// <summary>
- /// Adjusts the native type based on format.
- /// - If format is default, return native.
- /// - If format is recognized, return the canonical type for that format.
- /// - Otherwise remove existing format from native and apply the requested format.
- /// </summary>
- public static TraceLoggingDataType Format32(
- EventFieldFormat format,
- TraceLoggingDataType native)
- {
- switch (format)
- {
- case EventFieldFormat.Default:
- return native;
- case EventFieldFormat.Boolean:
- return TraceLoggingDataType.Boolean32;
- case EventFieldFormat.Hexadecimal:
- return TraceLoggingDataType.HexInt32;
-#if false
- case EventSourceFieldFormat.Ipv4Address:
- return TraceLoggingDataType.Ipv4Address;
- case EventSourceFieldFormat.ProcessId:
- return TraceLoggingDataType.ProcessId;
- case EventSourceFieldFormat.ThreadId:
- return TraceLoggingDataType.ThreadId;
- case EventSourceFieldFormat.Win32Error:
- return TraceLoggingDataType.Win32Error;
- case EventSourceFieldFormat.NTStatus:
- return TraceLoggingDataType.NTStatus;
-#endif
- case EventFieldFormat.HResult:
- return TraceLoggingDataType.HResult;
-#if false
- case EventSourceFieldFormat.Signed:
- return TraceLoggingDataType.Int32;
- case EventSourceFieldFormat.Unsigned:
- return TraceLoggingDataType.UInt32;
-#endif
- default:
- return MakeDataType(native, format);
- }
- }
-
- /// <summary>
- /// Adjusts the native type based on format.
- /// - If format is default, return native.
- /// - If format is recognized, return the canonical type for that format.
- /// - Otherwise remove existing format from native and apply the requested format.
- /// </summary>
- public static TraceLoggingDataType Format64(
- EventFieldFormat format,
- TraceLoggingDataType native)
- {
- switch (format)
- {
- case EventFieldFormat.Default:
- return native;
- case EventFieldFormat.Hexadecimal:
- return TraceLoggingDataType.HexInt64;
-#if false
- case EventSourceFieldFormat.FileTime:
- return TraceLoggingDataType.FileTime;
- case EventSourceFieldFormat.Signed:
- return TraceLoggingDataType.Int64;
- case EventSourceFieldFormat.Unsigned:
- return TraceLoggingDataType.UInt64;
-#endif
- default:
- return MakeDataType(native, format);
- }
- }
-
- /// <summary>
- /// Adjusts the native type based on format.
- /// - If format is default, return native.
- /// - If format is recognized, return the canonical type for that format.
- /// - Otherwise remove existing format from native and apply the requested format.
- /// </summary>
- public static TraceLoggingDataType FormatPtr(
- EventFieldFormat format,
- TraceLoggingDataType native)
- {
- switch (format)
- {
- case EventFieldFormat.Default:
- return native;
- case EventFieldFormat.Hexadecimal:
- return HexIntPtrType;
-#if false
- case EventSourceFieldFormat.Signed:
- return IntPtrType;
- case EventSourceFieldFormat.Unsigned:
- return UIntPtrType;
-#endif
- default:
- return MakeDataType(native, format);
- }
- }
-
- #endregion
-
- #region Reflection helpers
-
- /*
- All TraceLogging use of reflection APIs should go through wrappers here.
- This helps with portability, and it also makes it easier to audit what
- kinds of reflection operations are being done.
- */
-
- public static object CreateInstance(Type type, params object[] parameters)
- {
- return Activator.CreateInstance(type, parameters);
- }
-
- public static bool IsValueType(Type type)
- {
- bool result = type.IsValueType();
- return result;
- }
-
- public static bool IsEnum(Type type)
- {
- bool result = type.IsEnum();
- return result;
- }
-
- public static IEnumerable<PropertyInfo> GetProperties(Type type)
- {
- IEnumerable<PropertyInfo> result = type.GetProperties();
- return result;
- }
-
- public static MethodInfo GetGetMethod(PropertyInfo propInfo)
- {
- MethodInfo result = propInfo.GetGetMethod();
- return result;
- }
-
- public static MethodInfo GetDeclaredStaticMethod(Type declaringType, string name)
- {
- MethodInfo result;
-#if (ES_BUILD_PCL || PROJECTN)
- result = declaringType.GetTypeInfo().GetDeclaredMethod(name);
-#else
- result = declaringType.GetMethod(
- name,
- BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.NonPublic);
-#endif
- return result;
- }
-
- public static bool HasCustomAttribute(
- PropertyInfo propInfo,
- Type attributeType)
- {
- bool result;
-#if (ES_BUILD_PCL || PROJECTN)
- result = propInfo.IsDefined(attributeType);
-#else
- var attributes = propInfo.GetCustomAttributes(
- attributeType,
- false);
- result = attributes.Length != 0;
-#endif
- return result;
- }
-
- public static AttributeType GetCustomAttribute<AttributeType>(PropertyInfo propInfo)
- where AttributeType : Attribute
- {
- AttributeType result = null;
-#if (ES_BUILD_PCL || PROJECTN)
- foreach (var attrib in propInfo.GetCustomAttributes<AttributeType>(false))
- {
- result = attrib;
- break;
- }
-#else
- var attributes = propInfo.GetCustomAttributes(typeof(AttributeType), false);
- if (attributes.Length != 0)
- {
- result = (AttributeType)attributes[0];
- }
-#endif
- return result;
- }
-
- public static AttributeType GetCustomAttribute<AttributeType>(Type type)
- where AttributeType : Attribute
- {
- AttributeType result = null;
-#if (ES_BUILD_PCL || PROJECTN)
- foreach (var attrib in type.GetTypeInfo().GetCustomAttributes<AttributeType>(false))
- {
- result = attrib;
- break;
- }
-#else
- var attributes = type.GetCustomAttributes(typeof(AttributeType), false);
- if (attributes.Length != 0)
- {
- result = (AttributeType)attributes[0];
- }
-#endif
- return result;
- }
-
- public static Type[] GetGenericArguments(Type type)
- {
- return type.GetGenericArguments();
- }
-
- public static Type FindEnumerableElementType(Type type)
- {
- Type elementType = null;
-
- if (IsGenericMatch(type, typeof(IEnumerable<>)))
- {
- elementType = GetGenericArguments(type)[0];
- }
- else
- {
-#if (ES_BUILD_PCL || PROJECTN)
- var ifaceTypes = type.GetTypeInfo().ImplementedInterfaces;
-#else
- var ifaceTypes = type.FindInterfaces(IsGenericMatch, typeof(IEnumerable<>));
-#endif
-
- foreach (var ifaceType in ifaceTypes)
- {
-#if (ES_BUILD_PCL || PROJECTN)
- if (!IsGenericMatch(ifaceType, typeof(IEnumerable<>)))
- {
- continue;
- }
-#endif
-
- if (elementType != null)
- {
- // ambiguous match. report no match at all.
- elementType = null;
- break;
- }
-
- elementType = GetGenericArguments(ifaceType)[0];
- }
- }
-
- return elementType;
- }
-
- public static bool IsGenericMatch(Type type, object openType)
- {
- return type.IsGenericType() && type.GetGenericTypeDefinition() == (Type)openType;
- }
-
- public static Delegate CreateDelegate(Type delegateType, MethodInfo methodInfo)
- {
- Delegate result;
-#if (ES_BUILD_PCL || PROJECTN)
- result = methodInfo.CreateDelegate(
- delegateType);
-#else
- result = Delegate.CreateDelegate(
- delegateType,
- methodInfo);
-#endif
- return result;
- }
-
- public static TraceLoggingTypeInfo CreateDefaultTypeInfo(
- Type dataType,
- List<Type> recursionCheck)
- {
- TraceLoggingTypeInfo result;
-
- if (recursionCheck.Contains(dataType))
- {
- throw new NotSupportedException(Resources.GetResourceString("EventSource_RecursiveTypeDefinition"));
- }
-
- recursionCheck.Add(dataType);
-
- var eventAttrib = Statics.GetCustomAttribute<EventDataAttribute>(dataType);
- if (eventAttrib != null ||
- Statics.GetCustomAttribute<CompilerGeneratedAttribute>(dataType) != null ||
- IsGenericMatch(dataType, typeof(KeyValuePair<,>)))
- {
- var analysis = new TypeAnalysis(dataType, eventAttrib, recursionCheck);
- result = new InvokeTypeInfo(dataType, analysis);
- }
- else if (dataType.IsArray)
- {
- var elementType = dataType.GetElementType();
- if (elementType == typeof(Boolean))
- {
- result = ScalarArrayTypeInfo.Boolean();
- }
- else if (elementType == typeof(Byte))
- {
- result = ScalarArrayTypeInfo.Byte();
- }
- else if (elementType == typeof(SByte))
- {
- result = ScalarArrayTypeInfo.SByte();
- }
- else if (elementType == typeof(Int16))
- {
- result = ScalarArrayTypeInfo.Int16();
- }
- else if (elementType == typeof(UInt16))
- {
- result = ScalarArrayTypeInfo.UInt16();
- }
- else if (elementType == typeof(Int32))
- {
- result = ScalarArrayTypeInfo.Int32();
- }
- else if (elementType == typeof(UInt32))
- {
- result = ScalarArrayTypeInfo.UInt32();
- }
- else if (elementType == typeof(Int64))
- {
- result = ScalarArrayTypeInfo.Int64();
- }
- else if (elementType == typeof(UInt64))
- {
- result = ScalarArrayTypeInfo.UInt64();
- }
- else if (elementType == typeof(Char))
- {
- result = ScalarArrayTypeInfo.Char();
- }
- else if (elementType == typeof(Double))
- {
- result = ScalarArrayTypeInfo.Double();
- }
- else if (elementType == typeof(Single))
- {
- result = ScalarArrayTypeInfo.Single();
- }
- else if (elementType == typeof(IntPtr))
- {
- result = ScalarArrayTypeInfo.IntPtr();
- }
- else if (elementType == typeof(UIntPtr))
- {
- result = ScalarArrayTypeInfo.UIntPtr();
- }
- else if (elementType == typeof(Guid))
- {
- result = ScalarArrayTypeInfo.Guid();
- }
- else
- {
- result = new ArrayTypeInfo(dataType, TraceLoggingTypeInfo.GetInstance(elementType, recursionCheck));
- }
- }
- else
- {
- if (Statics.IsEnum(dataType))
- dataType = Enum.GetUnderlyingType(dataType);
-
- if (dataType == typeof(String))
- {
- result = new StringTypeInfo();
- }
- else if (dataType == typeof(Boolean))
- {
- result = ScalarTypeInfo.Boolean();
- }
- else if (dataType == typeof(Byte))
- {
- result = ScalarTypeInfo.Byte();
- }
- else if (dataType == typeof(SByte))
- {
- result = ScalarTypeInfo.SByte();
- }
- else if (dataType == typeof(Int16))
- {
- result = ScalarTypeInfo.Int16();
- }
- else if (dataType == typeof(UInt16))
- {
- result = ScalarTypeInfo.UInt16();
- }
- else if (dataType == typeof(Int32))
- {
- result = ScalarTypeInfo.Int32();
- }
- else if (dataType == typeof(UInt32))
- {
- result = ScalarTypeInfo.UInt32();
- }
- else if (dataType == typeof(Int64))
- {
- result = ScalarTypeInfo.Int64();
- }
- else if (dataType == typeof(UInt64))
- {
- result = ScalarTypeInfo.UInt64();
- }
- else if (dataType == typeof(Char))
- {
- result = ScalarTypeInfo.Char();
- }
- else if (dataType == typeof(Double))
- {
- result = ScalarTypeInfo.Double();
- }
- else if (dataType == typeof(Single))
- {
- result = ScalarTypeInfo.Single();
- }
- else if (dataType == typeof(DateTime))
- {
- result = new DateTimeTypeInfo();
- }
- else if (dataType == typeof(Decimal))
- {
- result = new DecimalTypeInfo();
- }
- else if (dataType == typeof(IntPtr))
- {
- result = ScalarTypeInfo.IntPtr();
- }
- else if (dataType == typeof(UIntPtr))
- {
- result = ScalarTypeInfo.UIntPtr();
- }
- else if (dataType == typeof(Guid))
- {
- result = ScalarTypeInfo.Guid();
- }
- else if (dataType == typeof(TimeSpan))
- {
- result = new TimeSpanTypeInfo();
- }
- else if (dataType == typeof(DateTimeOffset))
- {
- result = new DateTimeOffsetTypeInfo();
- }
- else if (dataType == typeof(EmptyStruct))
- {
- result = new NullTypeInfo();
- }
- else if (IsGenericMatch(dataType, typeof(Nullable<>)))
- {
- result = new NullableTypeInfo(dataType, recursionCheck);
- }
- else
- {
- var elementType = FindEnumerableElementType(dataType);
- if (elementType != null)
- {
- result = new EnumerableTypeInfo(dataType, TraceLoggingTypeInfo.GetInstance(elementType, recursionCheck));
- }
- else
- {
- throw new ArgumentException(Resources.GetResourceString("EventSource_NonCompliantTypeError", dataType.Name));
- }
- }
- }
-
- return result;
- }
-
- #endregion
- }
-}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventSource.cs b/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventSource.cs
deleted file mode 100644
index 07a56751ea..0000000000
--- a/src/mscorlib/src/System/Diagnostics/Eventing/TraceLogging/TraceLoggingEventSource.cs
+++ /dev/null
@@ -1,890 +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.
-
-// This program uses code hyperlinks available as part of the HyperAddin Visual Studio plug-in.
-// It is available from http://www.codeplex.com/hyperAddin
-
-#if !PLATFORM_UNIX
-#define FEATURE_MANAGED_ETW
-
-#if !ES_BUILD_STANDALONE
-#define FEATURE_ACTIVITYSAMPLING
-#endif
-#endif // PLATFORM_UNIX
-
-#if ES_BUILD_STANDALONE
-#define FEATURE_MANAGED_ETW_CHANNELS
-// #define FEATURE_ADVANCED_MANAGED_ETW_CHANNELS
-#endif
-
-#if ES_BUILD_STANDALONE
-using Environment = Microsoft.Diagnostics.Tracing.Internal.Environment;
-using EventDescriptor = Microsoft.Diagnostics.Tracing.EventDescriptor;
-#endif
-
-using System;
-using System.Runtime.InteropServices;
-using System.Security;
-using System.Collections.ObjectModel;
-
-#if !ES_BUILD_AGAINST_DOTNET_V35
-using Contract = System.Diagnostics.Contracts.Contract;
-using System.Collections.Generic;
-using System.Text;
-#else
-using Contract = Microsoft.Diagnostics.Contracts.Internal.Contract;
-using System.Collections.Generic;
-using System.Text;
-#endif
-
-#if ES_BUILD_STANDALONE
-namespace Microsoft.Diagnostics.Tracing
-#else
-namespace System.Diagnostics.Tracing
-#endif
-{
- public partial class EventSource
- {
-#if FEATURE_MANAGED_ETW
- private byte[] providerMetadata;
-#endif
-
- /// <summary>
- /// Construct an EventSource with a given name for non-contract based events (e.g. those using the Write() API).
- /// </summary>
- /// <param name="eventSourceName">
- /// The name of the event source. Must not be null.
- /// </param>
- public EventSource(
- string eventSourceName)
- : this(eventSourceName, EventSourceSettings.EtwSelfDescribingEventFormat)
- { }
-
- /// <summary>
- /// Construct an EventSource with a given name for non-contract based events (e.g. those using the Write() API).
- /// </summary>
- /// <param name="eventSourceName">
- /// The name of the event source. Must not be null.
- /// </param>
- /// <param name="config">
- /// Configuration options for the EventSource as a whole.
- /// </param>
- public EventSource(
- string eventSourceName,
- EventSourceSettings config)
- : this(eventSourceName, config, null) { }
-
- /// <summary>
- /// Construct an EventSource with a given name for non-contract based events (e.g. those using the Write() API).
- ///
- /// Also specify a list of key-value pairs called traits (you must pass an even number of strings).
- /// The first string is the key and the second is the value. These are not interpreted by EventSource
- /// itself but may be interprated the listeners. Can be fetched with GetTrait(string).
- /// </summary>
- /// <param name="eventSourceName">
- /// The name of the event source. Must not be null.
- /// </param>
- /// <param name="config">
- /// Configuration options for the EventSource as a whole.
- /// </param>
- /// <param name="traits">A collection of key-value strings (must be an even number).</param>
- public EventSource(
- string eventSourceName,
- EventSourceSettings config,
- params string[] traits)
- : this(
- eventSourceName == null ? new Guid() : GenerateGuidFromName(eventSourceName.ToUpperInvariant()),
- eventSourceName,
- config, traits)
- {
- if (eventSourceName == null)
- {
- throw new ArgumentNullException(nameof(eventSourceName));
- }
- Contract.EndContractBlock();
- }
-
- /// <summary>
- /// Writes an event with no fields and default options.
- /// (Native API: EventWriteTransfer)
- /// </summary>
- /// <param name="eventName">The name of the event. Must not be null.</param>
- public unsafe void Write(string eventName)
- {
- if (eventName == null)
- {
- throw new ArgumentNullException(nameof(eventName));
- }
-
- Contract.EndContractBlock();
-
- if (!this.IsEnabled())
- {
- return;
- }
-
- var options = new EventSourceOptions();
- this.WriteImpl(eventName, ref options, null, null, null, SimpleEventTypes<EmptyStruct>.Instance);
- }
-
- /// <summary>
- /// Writes an event with no fields.
- /// (Native API: EventWriteTransfer)
- /// </summary>
- /// <param name="eventName">The name of the event. Must not be null.</param>
- /// <param name="options">
- /// Options for the event, such as the level, keywords, and opcode. Unset
- /// options will be set to default values.
- /// </param>
- public unsafe void Write(string eventName, EventSourceOptions options)
- {
- if (eventName == null)
- {
- throw new ArgumentNullException(nameof(eventName));
- }
-
- Contract.EndContractBlock();
-
- if (!this.IsEnabled())
- {
- return;
- }
-
- this.WriteImpl(eventName, ref options, null, null, null, SimpleEventTypes<EmptyStruct>.Instance);
- }
-
- /// <summary>
- /// Writes an event.
- /// (Native API: EventWriteTransfer)
- /// </summary>
- /// <typeparam name="T">
- /// The type that defines the event and its payload. This must be an
- /// anonymous type or a type with an [EventData] attribute.
- /// </typeparam>
- /// <param name="eventName">
- /// The name for the event. If null, the event name is automatically
- /// determined based on T, either from the Name property of T's EventData
- /// attribute or from typeof(T).Name.
- /// </param>
- /// <param name="data">
- /// The object containing the event payload data. The type T must be
- /// an anonymous type or a type with an [EventData] attribute. The
- /// public instance properties of data will be written recursively to
- /// create the fields of the event.
- /// </param>
- public unsafe void Write<T>(
- string eventName,
- T data)
- {
- if (!this.IsEnabled())
- {
- return;
- }
-
- var options = new EventSourceOptions();
- this.WriteImpl(eventName, ref options, data, null, null, SimpleEventTypes<T>.Instance);
- }
-
- /// <summary>
- /// Writes an event.
- /// (Native API: EventWriteTransfer)
- /// </summary>
- /// <typeparam name="T">
- /// The type that defines the event and its payload. This must be an
- /// anonymous type or a type with an [EventData] attribute.
- /// </typeparam>
- /// <param name="eventName">
- /// The name for the event. If null, the event name is automatically
- /// determined based on T, either from the Name property of T's EventData
- /// attribute or from typeof(T).Name.
- /// </param>
- /// <param name="options">
- /// Options for the event, such as the level, keywords, and opcode. Unset
- /// options will be set to default values.
- /// </param>
- /// <param name="data">
- /// The object containing the event payload data. The type T must be
- /// an anonymous type or a type with an [EventData] attribute. The
- /// public instance properties of data will be written recursively to
- /// create the fields of the event.
- /// </param>
- public unsafe void Write<T>(
- string eventName,
- EventSourceOptions options,
- T data)
- {
- if (!this.IsEnabled())
- {
- return;
- }
-
- this.WriteImpl(eventName, ref options, data, null, null, SimpleEventTypes<T>.Instance);
- }
-
- /// <summary>
- /// Writes an event.
- /// This overload is for use with extension methods that wish to efficiently
- /// forward the options or data parameter without performing an extra copy.
- /// (Native API: EventWriteTransfer)
- /// </summary>
- /// <typeparam name="T">
- /// The type that defines the event and its payload. This must be an
- /// anonymous type or a type with an [EventData] attribute.
- /// </typeparam>
- /// <param name="eventName">
- /// The name for the event. If null, the event name is automatically
- /// determined based on T, either from the Name property of T's EventData
- /// attribute or from typeof(T).Name.
- /// </param>
- /// <param name="options">
- /// Options for the event, such as the level, keywords, and opcode. Unset
- /// options will be set to default values.
- /// </param>
- /// <param name="data">
- /// The object containing the event payload data. The type T must be
- /// an anonymous type or a type with an [EventData] attribute. The
- /// public instance properties of data will be written recursively to
- /// create the fields of the event.
- /// </param>
- public unsafe void Write<T>(
- string eventName,
- ref EventSourceOptions options,
- ref T data)
- {
- if (!this.IsEnabled())
- {
- return;
- }
-
- this.WriteImpl(eventName, ref options, data, null, null, SimpleEventTypes<T>.Instance);
- }
-
- /// <summary>
- /// Writes an event.
- /// This overload is meant for clients that need to manipuate the activityId
- /// and related ActivityId for the event.
- /// </summary>
- /// <typeparam name="T">
- /// The type that defines the event and its payload. This must be an
- /// anonymous type or a type with an [EventData] attribute.
- /// </typeparam>
- /// <param name="eventName">
- /// The name for the event. If null, the event name is automatically
- /// determined based on T, either from the Name property of T's EventData
- /// attribute or from typeof(T).Name.
- /// </param>
- /// <param name="options">
- /// Options for the event, such as the level, keywords, and opcode. Unset
- /// options will be set to default values.
- /// </param>
- /// <param name="activityId">
- /// The GUID of the activity associated with this event.
- /// </param>
- /// <param name="relatedActivityId">
- /// The GUID of another activity that is related to this activity, or Guid.Empty
- /// if there is no related activity. Most commonly, the Start operation of a
- /// new activity specifies a parent activity as its related activity.
- /// </param>
- /// <param name="data">
- /// The object containing the event payload data. The type T must be
- /// an anonymous type or a type with an [EventData] attribute. The
- /// public instance properties of data will be written recursively to
- /// create the fields of the event.
- /// </param>
- public unsafe void Write<T>(
- string eventName,
- ref EventSourceOptions options,
- ref Guid activityId,
- ref Guid relatedActivityId,
- ref T data)
- {
- if (!this.IsEnabled())
- {
- return;
- }
-
- fixed (Guid* pActivity = &activityId, pRelated = &relatedActivityId)
- {
- this.WriteImpl(
- eventName,
- ref options,
- data,
- pActivity,
- relatedActivityId == Guid.Empty ? null : pRelated,
- SimpleEventTypes<T>.Instance);
- }
- }
-
- /// <summary>
- /// Writes an extended event, where the values of the event are the
- /// combined properties of any number of values. This method is
- /// intended for use in advanced logging scenarios that support a
- /// dynamic set of event context providers.
- /// This method does a quick check on whether this event is enabled.
- /// </summary>
- /// <param name="eventName">
- /// The name for the event. If null, the name from eventTypes is used.
- /// (Note that providing the event name via the name parameter is slightly
- /// less efficient than using the name from eventTypes.)
- /// </param>
- /// <param name="options">
- /// Optional overrides for the event, such as the level, keyword, opcode,
- /// activityId, and relatedActivityId. Any settings not specified by options
- /// are obtained from eventTypes.
- /// </param>
- /// <param name="eventTypes">
- /// Information about the event and the types of the values in the event.
- /// Must not be null. Note that the eventTypes object should be created once and
- /// saved. It should not be recreated for each event.
- /// </param>
- /// <param name="activityID">
- /// A pointer to the activity ID GUID to log
- /// </param>
- /// <param name="childActivityID">
- /// A pointer to the child activity ID to log (can be null) </param>
- /// <param name="values">
- /// The values to include in the event. Must not be null. The number and types of
- /// the values must match the number and types of the fields described by the
- /// eventTypes parameter.
- /// </param>
- private unsafe void WriteMultiMerge(
- string eventName,
- ref EventSourceOptions options,
- TraceLoggingEventTypes eventTypes,
- Guid* activityID,
- Guid* childActivityID,
- params object[] values)
- {
- if (!this.IsEnabled())
- {
- return;
- }
- byte level = (options.valuesSet & EventSourceOptions.levelSet) != 0
- ? options.level
- : eventTypes.level;
- EventKeywords keywords = (options.valuesSet & EventSourceOptions.keywordsSet) != 0
- ? options.keywords
- : eventTypes.keywords;
-
- if (this.IsEnabled((EventLevel)level, keywords))
- {
- WriteMultiMergeInner(eventName, ref options, eventTypes, activityID, childActivityID, values);
- }
- }
-
- /// <summary>
- /// Writes an extended event, where the values of the event are the
- /// combined properties of any number of values. This method is
- /// intended for use in advanced logging scenarios that support a
- /// dynamic set of event context providers.
- /// Attention: This API does not check whether the event is enabled or not.
- /// Please use WriteMultiMerge to avoid spending CPU cycles for events that are
- /// not enabled.
- /// </summary>
- /// <param name="eventName">
- /// The name for the event. If null, the name from eventTypes is used.
- /// (Note that providing the event name via the name parameter is slightly
- /// less efficient than using the name from eventTypes.)
- /// </param>
- /// <param name="options">
- /// Optional overrides for the event, such as the level, keyword, opcode,
- /// activityId, and relatedActivityId. Any settings not specified by options
- /// are obtained from eventTypes.
- /// </param>
- /// <param name="eventTypes">
- /// Information about the event and the types of the values in the event.
- /// Must not be null. Note that the eventTypes object should be created once and
- /// saved. It should not be recreated for each event.
- /// </param>
- /// <param name="activityID">
- /// A pointer to the activity ID GUID to log
- /// </param>
- /// <param name="childActivityID">
- /// A pointer to the child activity ID to log (can be null)
- /// </param>
- /// <param name="values">
- /// The values to include in the event. Must not be null. The number and types of
- /// the values must match the number and types of the fields described by the
- /// eventTypes parameter.
- /// </param>
- private unsafe void WriteMultiMergeInner(
- string eventName,
- ref EventSourceOptions options,
- TraceLoggingEventTypes eventTypes,
- Guid* activityID,
- Guid* childActivityID,
- params object[] values)
- {
-#if FEATURE_MANAGED_ETW
- int identity = 0;
- byte level = (options.valuesSet & EventSourceOptions.levelSet) != 0
- ? options.level
- : eventTypes.level;
- byte opcode = (options.valuesSet & EventSourceOptions.opcodeSet) != 0
- ? options.opcode
- : eventTypes.opcode;
- EventTags tags = (options.valuesSet & EventSourceOptions.tagsSet) != 0
- ? options.tags
- : eventTypes.Tags;
- EventKeywords keywords = (options.valuesSet & EventSourceOptions.keywordsSet) != 0
- ? options.keywords
- : eventTypes.keywords;
-
- var nameInfo = eventTypes.GetNameInfo(eventName ?? eventTypes.Name, tags);
- if (nameInfo == null)
- {
- return;
- }
- identity = nameInfo.identity;
- EventDescriptor descriptor = new EventDescriptor(identity, level, opcode, (long)keywords);
-
- var pinCount = eventTypes.pinCount;
- var scratch = stackalloc byte[eventTypes.scratchSize];
- var descriptors = stackalloc EventData[eventTypes.dataCount + 3];
- var pins = stackalloc GCHandle[pinCount];
-
- fixed (byte*
- pMetadata0 = this.providerMetadata,
- pMetadata1 = nameInfo.nameMetadata,
- pMetadata2 = eventTypes.typeMetadata)
- {
- descriptors[0].SetMetadata(pMetadata0, this.providerMetadata.Length, 2);
- descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1);
- descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1);
-
-#if (!ES_BUILD_PCL && !PROJECTN)
- System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions();
-#endif
- try
- {
- DataCollector.ThreadInstance.Enable(
- scratch,
- eventTypes.scratchSize,
- descriptors + 3,
- eventTypes.dataCount,
- pins,
- pinCount);
-
- for (int i = 0; i < eventTypes.typeInfos.Length; i++)
- {
- var info = eventTypes.typeInfos[i];
- info.WriteData(TraceLoggingDataCollector.Instance, info.PropertyValueFactory(values[i]));
- }
-
- this.WriteEventRaw(
- eventName,
- ref descriptor,
- activityID,
- childActivityID,
- (int)(DataCollector.ThreadInstance.Finish() - descriptors),
- (IntPtr)descriptors);
- }
- finally
- {
- this.WriteCleanup(pins, pinCount);
- }
- }
-#endif // FEATURE_MANAGED_ETW
- }
-
- /// <summary>
- /// Writes an extended event, where the values of the event have already
- /// been serialized in "data".
- /// </summary>
- /// <param name="eventName">
- /// The name for the event. If null, the name from eventTypes is used.
- /// (Note that providing the event name via the name parameter is slightly
- /// less efficient than using the name from eventTypes.)
- /// </param>
- /// <param name="options">
- /// Optional overrides for the event, such as the level, keyword, opcode,
- /// activityId, and relatedActivityId. Any settings not specified by options
- /// are obtained from eventTypes.
- /// </param>
- /// <param name="eventTypes">
- /// Information about the event and the types of the values in the event.
- /// Must not be null. Note that the eventTypes object should be created once and
- /// saved. It should not be recreated for each event.
- /// </param>
- /// <param name="activityID">
- /// A pointer to the activity ID GUID to log
- /// </param>
- /// <param name="childActivityID">
- /// A pointer to the child activity ID to log (can be null)
- /// </param>
- /// <param name="data">
- /// The previously serialized values to include in the event. Must not be null.
- /// The number and types of the values must match the number and types of the
- /// fields described by the eventTypes parameter.
- /// </param>
- internal unsafe void WriteMultiMerge(
- string eventName,
- ref EventSourceOptions options,
- TraceLoggingEventTypes eventTypes,
- Guid* activityID,
- Guid* childActivityID,
- EventData* data)
- {
-#if FEATURE_MANAGED_ETW
- if (!this.IsEnabled())
- {
- return;
- }
-
- fixed (EventSourceOptions* pOptions = &options)
- {
- EventDescriptor descriptor;
- var nameInfo = this.UpdateDescriptor(eventName, eventTypes, ref options, out descriptor);
- if (nameInfo == null)
- {
- return;
- }
-
- // We make a descriptor for each EventData, and because we morph strings to counted strings
- // we may have 2 for each arg, so we allocate enough for this.
- var descriptors = stackalloc EventData[eventTypes.dataCount + eventTypes.typeInfos.Length * 2 + 3];
-
- fixed (byte*
- pMetadata0 = this.providerMetadata,
- pMetadata1 = nameInfo.nameMetadata,
- pMetadata2 = eventTypes.typeMetadata)
- {
- descriptors[0].SetMetadata(pMetadata0, this.providerMetadata.Length, 2);
- descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1);
- descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1);
- int numDescrs = 3;
-
- for (int i = 0; i < eventTypes.typeInfos.Length; i++)
- {
- // Until M3, we need to morph strings to a counted representation
- // When TDH supports null terminated strings, we can remove this.
- if (eventTypes.typeInfos[i].DataType == typeof(string))
- {
- // Write out the size of the string
- descriptors[numDescrs].m_Ptr = (long)&descriptors[numDescrs + 1].m_Size;
- descriptors[numDescrs].m_Size = 2;
- numDescrs++;
-
- descriptors[numDescrs].m_Ptr = data[i].m_Ptr;
- descriptors[numDescrs].m_Size = data[i].m_Size - 2; // Remove the null terminator
- numDescrs++;
- }
- else
- {
- descriptors[numDescrs].m_Ptr = data[i].m_Ptr;
- descriptors[numDescrs].m_Size = data[i].m_Size;
-
- // old conventions for bool is 4 bytes, but meta-data assumes 1.
- if (data[i].m_Size == 4 && eventTypes.typeInfos[i].DataType == typeof(bool))
- descriptors[numDescrs].m_Size = 1;
-
- numDescrs++;
- }
- }
-
- this.WriteEventRaw(
- eventName,
- ref descriptor,
- activityID,
- childActivityID,
- numDescrs,
- (IntPtr)descriptors);
- }
- }
-#endif // FEATURE_MANAGED_ETW
- }
-
- private unsafe void WriteImpl(
- string eventName,
- ref EventSourceOptions options,
- object data,
- Guid* pActivityId,
- Guid* pRelatedActivityId,
- TraceLoggingEventTypes eventTypes)
- {
- try
- {
- fixed (EventSourceOptions* pOptions = &options)
- {
- EventDescriptor descriptor;
- options.Opcode = options.IsOpcodeSet ? options.Opcode : GetOpcodeWithDefault(options.Opcode, eventName);
- var nameInfo = this.UpdateDescriptor(eventName, eventTypes, ref options, out descriptor);
- if (nameInfo == null)
- {
- return;
- }
-
-#if FEATURE_MANAGED_ETW
- var pinCount = eventTypes.pinCount;
- var scratch = stackalloc byte[eventTypes.scratchSize];
- var descriptors = stackalloc EventData[eventTypes.dataCount + 3];
- var pins = stackalloc GCHandle[pinCount];
-
- fixed (byte*
- pMetadata0 = this.providerMetadata,
- pMetadata1 = nameInfo.nameMetadata,
- pMetadata2 = eventTypes.typeMetadata)
- {
- descriptors[0].SetMetadata(pMetadata0, this.providerMetadata.Length, 2);
- descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1);
- descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1);
-#endif // FEATURE_MANAGED_ETW
-
-#if (!ES_BUILD_PCL && !PROJECTN)
- System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions();
-#endif
- EventOpcode opcode = (EventOpcode)descriptor.Opcode;
-
- Guid activityId = Guid.Empty;
- Guid relatedActivityId = Guid.Empty;
- if (pActivityId == null && pRelatedActivityId == null &&
- ((options.ActivityOptions & EventActivityOptions.Disable) == 0))
- {
- if (opcode == EventOpcode.Start)
- {
- m_activityTracker.OnStart(m_name, eventName, 0, ref activityId, ref relatedActivityId, options.ActivityOptions);
- }
- else if (opcode == EventOpcode.Stop)
- {
- m_activityTracker.OnStop(m_name, eventName, 0, ref activityId);
- }
- if (activityId != Guid.Empty)
- pActivityId = &activityId;
- if (relatedActivityId != Guid.Empty)
- pRelatedActivityId = &relatedActivityId;
- }
-
- try
- {
-#if FEATURE_MANAGED_ETW
- DataCollector.ThreadInstance.Enable(
- scratch,
- eventTypes.scratchSize,
- descriptors + 3,
- eventTypes.dataCount,
- pins,
- pinCount);
-
- var info = eventTypes.typeInfos[0];
- info.WriteData(TraceLoggingDataCollector.Instance, info.PropertyValueFactory(data));
-
- this.WriteEventRaw(
- eventName,
- ref descriptor,
- pActivityId,
- pRelatedActivityId,
- (int)(DataCollector.ThreadInstance.Finish() - descriptors),
- (IntPtr)descriptors);
-#endif // FEATURE_MANAGED_ETW
-
- // TODO enable filtering for listeners.
- if (m_Dispatchers != null)
- {
- var eventData = (EventPayload)(eventTypes.typeInfos[0].GetData(data));
- WriteToAllListeners(eventName, ref descriptor, nameInfo.tags, pActivityId, eventData);
- }
-
- }
- catch (Exception ex)
- {
- if (ex is EventSourceException)
- throw;
- else
- ThrowEventSourceException(eventName, ex);
- }
-#if FEATURE_MANAGED_ETW
- finally
- {
- this.WriteCleanup(pins, pinCount);
- }
- }
-#endif // FEATURE_MANAGED_ETW
- }
- }
- catch (Exception ex)
- {
- if (ex is EventSourceException)
- throw;
- else
- ThrowEventSourceException(eventName, ex);
- }
- }
-
- private unsafe void WriteToAllListeners(string eventName, ref EventDescriptor eventDescriptor, EventTags tags, Guid* pActivityId, EventPayload payload)
- {
- EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this);
- eventCallbackArgs.EventName = eventName;
- eventCallbackArgs.m_level = (EventLevel) eventDescriptor.Level;
- eventCallbackArgs.m_keywords = (EventKeywords) eventDescriptor.Keywords;
- eventCallbackArgs.m_opcode = (EventOpcode) eventDescriptor.Opcode;
- eventCallbackArgs.m_tags = tags;
-
- // Self described events do not have an id attached. We mark it internally with -1.
- eventCallbackArgs.EventId = -1;
- if (pActivityId != null)
- eventCallbackArgs.RelatedActivityId = *pActivityId;
-
- if (payload != null)
- {
- eventCallbackArgs.Payload = new ReadOnlyCollection<object>((IList<object>)payload.Values);
- eventCallbackArgs.PayloadNames = new ReadOnlyCollection<string>((IList<string>)payload.Keys);
- }
-
- DispatchToAllListeners(-1, pActivityId, eventCallbackArgs);
- }
-
-#if (!ES_BUILD_PCL && !PROJECTN)
- [System.Runtime.ConstrainedExecution.ReliabilityContract(
- System.Runtime.ConstrainedExecution.Consistency.WillNotCorruptState,
- System.Runtime.ConstrainedExecution.Cer.Success)]
-#endif
- [NonEvent]
- private unsafe void WriteCleanup(GCHandle* pPins, int cPins)
- {
- DataCollector.ThreadInstance.Disable();
-
- for (int i = 0; i != cPins; i++)
- {
- if (IntPtr.Zero != (IntPtr)pPins[i])
- {
- pPins[i].Free();
- }
- }
- }
-
- private void InitializeProviderMetadata()
- {
-#if FEATURE_MANAGED_ETW
- if (m_traits != null)
- {
- List<byte> traitMetaData = new List<byte>(100);
- for (int i = 0; i < m_traits.Length - 1; i += 2)
- {
- if (m_traits[i].StartsWith("ETW_", StringComparison.Ordinal))
- {
- string etwTrait = m_traits[i].Substring(4);
- byte traitNum;
- if (!byte.TryParse(etwTrait, out traitNum))
- {
- if (etwTrait == "GROUP")
- {
- traitNum = 1;
- }
- else
- {
- throw new ArgumentException(Resources.GetResourceString("UnknownEtwTrait", etwTrait), "traits");
- }
- }
- string value = m_traits[i + 1];
- int lenPos = traitMetaData.Count;
- traitMetaData.Add(0); // Emit size (to be filled in later)
- traitMetaData.Add(0);
- traitMetaData.Add(traitNum); // Emit Trait number
- var valueLen = AddValueToMetaData(traitMetaData, value) + 3; // Emit the value bytes +3 accounts for 3 bytes we emited above.
- traitMetaData[lenPos] = unchecked((byte)valueLen); // Fill in size
- traitMetaData[lenPos + 1] = unchecked((byte)(valueLen >> 8));
- }
- }
- providerMetadata = Statics.MetadataForString(this.Name, 0, traitMetaData.Count, 0);
- int startPos = providerMetadata.Length - traitMetaData.Count;
- foreach (var b in traitMetaData)
- providerMetadata[startPos++] = b;
- }
- else
- providerMetadata = Statics.MetadataForString(this.Name, 0, 0, 0);
-#endif //FEATURE_MANAGED_ETW
- }
-
- private static int AddValueToMetaData(List<byte> metaData, string value)
- {
- if (value.Length == 0)
- return 0;
-
- int startPos = metaData.Count;
- char firstChar = value[0];
-
- if (firstChar == '@')
- metaData.AddRange(Encoding.UTF8.GetBytes(value.Substring(1)));
- else if (firstChar == '{')
- metaData.AddRange(new Guid(value).ToByteArray());
- else if (firstChar == '#')
- {
- for (int i = 1; i < value.Length; i++)
- {
- if (value[i] != ' ') // Skip spaces between bytes.
- {
- if (!(i + 1 < value.Length))
- {
- throw new ArgumentException(Resources.GetResourceString("EvenHexDigits"), "traits");
- }
- metaData.Add((byte)(HexDigit(value[i]) * 16 + HexDigit(value[i + 1])));
- i++;
- }
- }
- }
- else if ('A' <= firstChar || ' ' == firstChar) // Is it alphabetic or space (excludes digits and most punctuation).
- {
- metaData.AddRange(Encoding.UTF8.GetBytes(value));
- }
- else
- {
- throw new ArgumentException(Resources.GetResourceString("IllegalValue", value), "traits");
- }
-
- return metaData.Count - startPos;
- }
-
- /// <summary>
- /// Returns a value 0-15 if 'c' is a hexadecimal digit. If it throws an argument exception.
- /// </summary>
- private static int HexDigit(char c)
- {
- if ('0' <= c && c <= '9')
- {
- return (c - '0');
- }
- if ('a' <= c)
- {
- c = unchecked((char)(c - ('a' - 'A'))); // Convert to lower case
- }
- if ('A' <= c && c <= 'F')
- {
- return (c - 'A' + 10);
- }
-
- throw new ArgumentException(Resources.GetResourceString("BadHexDigit", c), "traits");
- }
-
- private NameInfo UpdateDescriptor(
- string name,
- TraceLoggingEventTypes eventInfo,
- ref EventSourceOptions options,
- out EventDescriptor descriptor)
- {
- NameInfo nameInfo = null;
- int identity = 0;
- byte level = (options.valuesSet & EventSourceOptions.levelSet) != 0
- ? options.level
- : eventInfo.level;
- byte opcode = (options.valuesSet & EventSourceOptions.opcodeSet) != 0
- ? options.opcode
- : eventInfo.opcode;
- EventTags tags = (options.valuesSet & EventSourceOptions.tagsSet) != 0
- ? options.tags
- : eventInfo.Tags;
- EventKeywords keywords = (options.valuesSet & EventSourceOptions.keywordsSet) != 0
- ? options.keywords
- : eventInfo.keywords;
-
- if (this.IsEnabled((EventLevel)level, keywords))
- {
- nameInfo = eventInfo.GetNameInfo(name ?? eventInfo.Name, tags);
- identity = nameInfo.identity;
- }
-
- descriptor = new EventDescriptor(identity, level, opcode, (long)keywords);
- return nameInfo;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/Winmeta.cs b/src/mscorlib/src/System/Diagnostics/Eventing/Winmeta.cs
deleted file mode 100644
index c93e745173..0000000000
--- a/src/mscorlib/src/System/Diagnostics/Eventing/Winmeta.cs
+++ /dev/null
@@ -1,196 +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.
-
-/*============================================================
-**
-**
-** Purpose:
-** Contains eventing constants defined by the Windows
-** environment.
-**
-============================================================*/
-#if ES_BUILD_STANDALONE
-#define FEATURE_MANAGED_ETW_CHANNELS
-#endif
-
-#if ES_BUILD_STANDALONE
-namespace Microsoft.Diagnostics.Tracing
-#else
-namespace System.Diagnostics.Tracing
-#endif
-{
- using System;
-
- /// <summary>
- /// WindowsEventLevel. Custom values must be in the range from 16 through 255
- /// </summary>
- public enum EventLevel
- {
- /// <summary>
- /// Log always
- /// </summary>
- LogAlways = 0,
- /// <summary>
- /// Only critical errors
- /// </summary>
- Critical,
- /// <summary>
- /// All errors, including previous levels
- /// </summary>
- Error,
- /// <summary>
- /// All warnings, including previous levels
- /// </summary>
- Warning,
- /// <summary>
- /// All informational events, including previous levels
- /// </summary>
- Informational,
- /// <summary>
- /// All events, including previous levels
- /// </summary>
- Verbose
- }
- /// <summary>
- /// WindowsEventTask. Custom values must be in the range from 1 through 65534
- /// </summary>
-#if (!ES_BUILD_STANDALONE && !PROJECTN)
- [System.Runtime.CompilerServices.FriendAccessAllowed]
-#endif
- public enum EventTask
- {
- /// <summary>
- /// Undefined task
- /// </summary>
- None = 0
- }
- /// <summary>
- /// EventOpcode. Custom values must be in the range from 11 through 239
- /// </summary>
-#if (!ES_BUILD_STANDALONE && !PROJECTN)
- [System.Runtime.CompilerServices.FriendAccessAllowed]
-#endif
- public enum EventOpcode
- {
- /// <summary>
- /// An informational event
- /// </summary>
- Info = 0,
- /// <summary>
- /// An activity start event
- /// </summary>
- Start,
- /// <summary>
- /// An activity end event
- /// </summary>
- Stop,
- /// <summary>
- /// A trace collection start event
- /// </summary>
- DataCollectionStart,
- /// <summary>
- /// A trace collection end event
- /// </summary>
- DataCollectionStop,
- /// <summary>
- /// An extensional event
- /// </summary>
- Extension,
- /// <summary>
- /// A reply event
- /// </summary>
- Reply,
- /// <summary>
- /// An event representing the activity resuming from the suspension
- /// </summary>
- Resume,
- /// <summary>
- /// An event representing the activity is suspended, pending another activity's completion
- /// </summary>
- Suspend,
- /// <summary>
- /// An event representing the activity is transferred to another component, and can continue to work
- /// </summary>
- Send,
- /// <summary>
- /// An event representing receiving an activity transfer from another component
- /// </summary>
- Receive = 240
- }
-
- // Added for CLR V4
- /// <summary>
- /// EventChannel. Custom values must be in the range from 16 through 255. Currently only predefined values allowed.
- /// </summary>
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1028:EnumStorageShouldBeInt32", Justification = "Backwards compatibility")]
-#if (!ES_BUILD_STANDALONE && !PROJECTN)
- [System.Runtime.CompilerServices.FriendAccessAllowed]
-#endif
- public enum EventChannel : byte
- {
- /// <summary>
- /// No channel
- /// </summary>
- None = 0,
- // Channels 1 - 15 are reserved...
- /// <summary>The admin channel</summary>
- Admin = 16,
- /// <summary>The operational channel</summary>
- Operational = 17,
- /// <summary>The analytic channel</summary>
- Analytic = 18,
- /// <summary>The debug channel</summary>
- Debug = 19,
-
- };
-
- /// <summary>
- /// EventOpcode
- /// </summary>
- [Flags]
- public enum EventKeywords : long
- {
- /// <summary>
- /// No events.
- /// </summary>
- None = 0x0,
- /// <summary>
- /// All Events
- /// </summary>
- All = ~0,
- /// <summary>
- /// Telemetry events
- /// </summary>
- MicrosoftTelemetry = 0x02000000000000,
- /// <summary>
- /// WDI context events
- /// </summary>
- WdiContext = 0x02000000000000,
- /// <summary>
- /// WDI diagnostic events
- /// </summary>
- WdiDiagnostic = 0x04000000000000,
- /// <summary>
- /// SQM events
- /// </summary>
- Sqm = 0x08000000000000,
- /// <summary>
- /// Failed security audits
- /// </summary>
- AuditFailure = 0x10000000000000,
- /// <summary>
- /// Successful security audits
- /// </summary>
- AuditSuccess = 0x20000000000000,
- /// <summary>
- /// Transfer events where the related Activity ID is a computed value and not a GUID
- /// N.B. The correct value for this field is 0x40000000000000.
- /// </summary>
- CorrelationHint = 0x10000000000000,
- /// <summary>
- /// Events raised using classic eventlog API
- /// </summary>
- EventLogClassic = 0x80000000000000
- }
-}
diff --git a/src/mscorlib/src/System/Diagnostics/ICustomDebuggerNotification.cs b/src/mscorlib/src/System/Diagnostics/ICustomDebuggerNotification.cs
index 29323cea2d..e7f41051f2 100644
--- a/src/mscorlib/src/System/Diagnostics/ICustomDebuggerNotification.cs
+++ b/src/mscorlib/src/System/Diagnostics/ICustomDebuggerNotification.cs
@@ -8,9 +8,11 @@
** This interface is implemented by classes that support custom debugger notifications.
**
===========================================================*/
-namespace System.Diagnostics {
-
- using System;
+
+using System;
+
+namespace System.Diagnostics
+{
// Defines an interface indicating that a custom debugger notification is requested under specific
// conditions. Users should implement this interface to be used as an argument to
// System.Diagnostics.Debugger.CustomNotification.
diff --git a/src/mscorlib/src/System/Diagnostics/LogSwitch.cs b/src/mscorlib/src/System/Diagnostics/LogSwitch.cs
index 14f0f26d98..29d6a1d4e6 100644
--- a/src/mscorlib/src/System/Diagnostics/LogSwitch.cs
+++ b/src/mscorlib/src/System/Diagnostics/LogSwitch.cs
@@ -2,14 +2,15 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Diagnostics {
- using System;
- using System.IO;
- using System.Collections;
- using System.Runtime.Versioning;
- using System.Diagnostics.Contracts;
- using System.Diagnostics.CodeAnalysis;
-
+using System;
+using System.IO;
+using System.Collections;
+using System.Runtime.Versioning;
+using System.Diagnostics.Contracts;
+using System.Diagnostics.CodeAnalysis;
+
+namespace System.Diagnostics
+{
[Serializable]
internal class LogSwitch
{
@@ -18,17 +19,17 @@ namespace System.Diagnostics {
// same in the EE code (debugdebugger.cpp/debugdebugger.h)
internal String strName;
internal String strDescription;
- private LogSwitch ParentSwitch;
+ private LogSwitch ParentSwitch;
internal volatile LoggingLevels iLevel;
internal volatile LoggingLevels iOldLevel;
-
+
// ! END WARNING !
-
-
- private LogSwitch ()
+
+
+ private LogSwitch()
{
}
-
+
// Constructs a LogSwitch. A LogSwitch is used to categorize log messages.
//
// All switches (except for the global LogSwitch) have a parent LogSwitch.
@@ -36,27 +37,27 @@ namespace System.Diagnostics {
public LogSwitch(String name, String description, LogSwitch parent)
{
if (name != null && name.Length == 0)
- throw new ArgumentOutOfRangeException(nameof(Name), Environment.GetResourceString("Argument_StringZeroLength"));
+ throw new ArgumentOutOfRangeException(nameof(Name), SR.Argument_StringZeroLength);
Contract.EndContractBlock();
if ((name != null) && (parent != null))
- {
+ {
strName = name;
strDescription = description;
iLevel = LoggingLevels.ErrorLevel;
iOldLevel = iLevel;
ParentSwitch = parent;
-
- Log.m_Hashtable.Add (strName, this);
-
+
+ Log.m_Hashtable.Add(strName, this);
+
// Call into the EE to let it know about the creation of
// this switch
- Log.AddLogSwitch (this);
+ Log.AddLogSwitch(this);
}
else
- throw new ArgumentNullException ((name==null ? nameof(name) : nameof(parent)));
+ throw new ArgumentNullException((name == null ? nameof(name) : nameof(parent)));
}
-
+
internal LogSwitch(String name, String description)
{
strName = name;
@@ -65,39 +66,39 @@ namespace System.Diagnostics {
iOldLevel = iLevel;
ParentSwitch = null;
- Log.m_Hashtable.Add (strName, this);
-
+ Log.m_Hashtable.Add(strName, this);
+
// Call into the EE to let it know about the creation of
// this switch
- Log.AddLogSwitch (this);
+ Log.AddLogSwitch(this);
}
-
-
+
+
// Get property returns the name of the switch
public virtual String Name
{
- get { return strName;}
+ get { return strName; }
}
-
-
+
+
// Property to Get/Set the level of log messages which are "on" for the switch.
//
- public virtual LoggingLevels MinimumLevel
+ public virtual LoggingLevels MinimumLevel
{
get { return iLevel; }
- set
- {
- iLevel = value;
+ set
+ {
+ iLevel = value;
iOldLevel = value;
- String strParentName = ParentSwitch!=null ? ParentSwitch.Name : "";
+ String strParentName = ParentSwitch != null ? ParentSwitch.Name : "";
if (Debugger.IsAttached)
- Log.ModifyLogSwitch ((int)iLevel, strName, strParentName);
-
- Log.InvokeLogSwitchLevelHandlers (this, iLevel);
+ Log.ModifyLogSwitch((int)iLevel, strName, strParentName);
+
+ Log.InvokeLogSwitchLevelHandlers(this, iLevel);
}
}
-
-
+
+
// Checks if the given level is "on" for this switch or one of its parents.
//
public virtual bool CheckLevel(LoggingLevels level)
@@ -105,22 +106,21 @@ namespace System.Diagnostics {
if (iLevel > level)
{
// recurse through the list till parent is hit.
- if (this.ParentSwitch == null)
+ if (ParentSwitch == null)
return false;
else
- return this.ParentSwitch.CheckLevel (level);
+ return ParentSwitch.CheckLevel(level);
}
else
return true;
}
-
-
+
+
// Returns a switch with the particular name, if any. Returns null if no
// such switch exists.
public static LogSwitch GetSwitch(String name)
{
return (LogSwitch)Log.m_Hashtable[name];
}
-
}
}
diff --git a/src/mscorlib/src/System/Diagnostics/LoggingLevels.cs b/src/mscorlib/src/System/Diagnostics/LoggingLevels.cs
index 0eea0507ec..6b5ea85ee1 100644
--- a/src/mscorlib/src/System/Diagnostics/LoggingLevels.cs
+++ b/src/mscorlib/src/System/Diagnostics/LoggingLevels.cs
@@ -2,17 +2,19 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Diagnostics {
-
- using System;
- // Constants representing the importance level of messages to be logged.
- // This level can be used to organize messages, and also to filter which
- // messages are displayed.
- //
- // An attached debugger can enable or disable which messages will
- // actually be reported to the user through the COM+ debugger
- // services API. This info is communicated to the runtime so only
- // desired events are actually reported to the debugger.
+
+using System;
+
+namespace System.Diagnostics
+{
+ // Constants representing the importance level of messages to be logged.
+ // This level can be used to organize messages, and also to filter which
+ // messages are displayed.
+ //
+ // An attached debugger can enable or disable which messages will
+ // actually be reported to the user through the COM+ debugger
+ // services API. This info is communicated to the runtime so only
+ // desired events are actually reported to the debugger.
// NOTE: The following constants mirror the constants
// declared in the EE code (DebugDebugger.h). Any changes here will also
// need to be made there.
@@ -22,24 +24,23 @@ namespace System.Diagnostics {
[Serializable]
internal enum LoggingLevels
{
- TraceLevel0 = 0,
- TraceLevel1 = 1,
- TraceLevel2 = 2,
- TraceLevel3 = 3,
- TraceLevel4 = 4,
-
- StatusLevel0 = 20,
- StatusLevel1 = 21,
- StatusLevel2 = 22,
- StatusLevel3 = 23,
- StatusLevel4 = 24,
-
-
- WarningLevel = 40,
-
- ErrorLevel = 50,
-
- PanicLevel = 100,
- }
+ TraceLevel0 = 0,
+ TraceLevel1 = 1,
+ TraceLevel2 = 2,
+ TraceLevel3 = 3,
+ TraceLevel4 = 4,
+ StatusLevel0 = 20,
+ StatusLevel1 = 21,
+ StatusLevel2 = 22,
+ StatusLevel3 = 23,
+ StatusLevel4 = 24,
+
+
+ WarningLevel = 40,
+
+ ErrorLevel = 50,
+
+ PanicLevel = 100,
+ }
}
diff --git a/src/mscorlib/src/System/Diagnostics/Stackframe.cs b/src/mscorlib/src/System/Diagnostics/Stackframe.cs
index 13d8f5cdcc..b555a609e7 100644
--- a/src/mscorlib/src/System/Diagnostics/Stackframe.cs
+++ b/src/mscorlib/src/System/Diagnostics/Stackframe.cs
@@ -2,27 +2,28 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Diagnostics {
- using System.Text;
- using System;
- using System.IO;
- using System.Reflection;
- using System.Diagnostics.Contracts;
+using System.Text;
+using System;
+using System.IO;
+using System.Reflection;
+using System.Diagnostics.Contracts;
+namespace System.Diagnostics
+{
// There is no good reason for the methods of this class to be virtual.
[Serializable]
public class StackFrame
{
- private MethodBase method;
- private int offset;
- private int ILOffset;
- private String strFileName;
- private int iLineNumber;
- private int iColumnNumber;
-
+ private MethodBase method;
+ private int offset;
+ private int ILOffset;
+ private String strFileName;
+ private int iLineNumber;
+ private int iColumnNumber;
+
[System.Runtime.Serialization.OptionalField]
- private bool fIsLastFrameFromForeignExceptionStackTrace;
+ private bool fIsLastFrameFromForeignExceptionStackTrace;
internal void InitMembers()
{
@@ -33,21 +34,20 @@ namespace System.Diagnostics {
iLineNumber = 0;
iColumnNumber = 0;
fIsLastFrameFromForeignExceptionStackTrace = false;
-
}
// Constructs a StackFrame corresponding to the active stack frame.
public StackFrame()
{
InitMembers();
- BuildStackFrame (0 + StackTrace.METHODS_TO_SKIP, false);// iSkipFrames=0
+ BuildStackFrame(0 + StackTrace.METHODS_TO_SKIP, false);// iSkipFrames=0
}
-
+
// Constructs a StackFrame corresponding to the active stack frame.
public StackFrame(bool fNeedFileInfo)
{
InitMembers();
- BuildStackFrame (0 + StackTrace.METHODS_TO_SKIP, fNeedFileInfo);// iSkipFrames=0
+ BuildStackFrame(0 + StackTrace.METHODS_TO_SKIP, fNeedFileInfo);// iSkipFrames=0
}
// Constructs a StackFrame corresponding to a calling stack frame.
@@ -55,25 +55,25 @@ namespace System.Diagnostics {
public StackFrame(int skipFrames)
{
InitMembers();
- BuildStackFrame (skipFrames + StackTrace.METHODS_TO_SKIP, false);
+ BuildStackFrame(skipFrames + StackTrace.METHODS_TO_SKIP, false);
}
-
+
// Constructs a StackFrame corresponding to a calling stack frame.
//
public StackFrame(int skipFrames, bool fNeedFileInfo)
{
InitMembers();
- BuildStackFrame (skipFrames + StackTrace.METHODS_TO_SKIP, fNeedFileInfo);
+ BuildStackFrame(skipFrames + StackTrace.METHODS_TO_SKIP, fNeedFileInfo);
}
-
+
// Called from the class "StackTrace"
//
internal StackFrame(bool DummyFlag1, bool DummyFlag2)
{
InitMembers();
}
-
+
// Constructs a "fake" stack frame, just containing the given file
// name and line number. Use when you don't want to use the
// debugger's line mapping logic.
@@ -81,12 +81,12 @@ namespace System.Diagnostics {
public StackFrame(String fileName, int lineNumber)
{
InitMembers();
- BuildStackFrame (StackTrace.METHODS_TO_SKIP, false);
+ BuildStackFrame(StackTrace.METHODS_TO_SKIP, false);
strFileName = fileName;
- iLineNumber = lineNumber;
+ iLineNumber = lineNumber;
iColumnNumber = 0;
}
-
+
// Constructs a "fake" stack frame, just containing the given file
// name, line number and column number. Use when you don't want to
@@ -95,48 +95,48 @@ namespace System.Diagnostics {
public StackFrame(String fileName, int lineNumber, int colNumber)
{
InitMembers();
- BuildStackFrame (StackTrace.METHODS_TO_SKIP, false);
+ BuildStackFrame(StackTrace.METHODS_TO_SKIP, false);
strFileName = fileName;
- iLineNumber = lineNumber;
+ iLineNumber = lineNumber;
iColumnNumber = colNumber;
}
// Constant returned when the native or IL offset is unknown
- public const int OFFSET_UNKNOWN = -1;
-
-
- internal virtual void SetMethodBase (MethodBase mb)
+ public const int OFFSET_UNKNOWN = -1;
+
+
+ internal virtual void SetMethodBase(MethodBase mb)
{
method = mb;
}
-
- internal virtual void SetOffset (int iOffset)
+
+ internal virtual void SetOffset(int iOffset)
{
offset = iOffset;
}
-
- internal virtual void SetILOffset (int iOffset)
+
+ internal virtual void SetILOffset(int iOffset)
{
ILOffset = iOffset;
}
- internal virtual void SetFileName (String strFName)
+ internal virtual void SetFileName(String strFName)
{
strFileName = strFName;
}
- internal virtual void SetLineNumber (int iLine)
+ internal virtual void SetLineNumber(int iLine)
{
iLineNumber = iLine;
}
- internal virtual void SetColumnNumber (int iCol)
+ internal virtual void SetColumnNumber(int iCol)
{
iColumnNumber = iCol;
}
- internal virtual void SetIsLastFrameFromForeignExceptionStackTrace (bool fIsLastFrame)
+ internal virtual void SetIsLastFrameFromForeignExceptionStackTrace(bool fIsLastFrame)
{
fIsLastFrameFromForeignExceptionStackTrace = fIsLastFrame;
}
@@ -148,22 +148,22 @@ namespace System.Diagnostics {
// Returns the method the frame is executing
//
- public virtual MethodBase GetMethod ()
+ public virtual MethodBase GetMethod()
{
Contract.Ensures(Contract.Result<MethodBase>() != null);
return method;
}
-
+
// Returns the offset from the start of the native (jitted) code for the
// method being executed
//
- public virtual int GetNativeOffset ()
+ public virtual int GetNativeOffset()
{
return offset;
}
-
-
+
+
// Returns the offset from the start of the IL code for the
// method being executed. This offset may be approximate depending
// on whether the jitter is generating debuggable code or not.
@@ -171,8 +171,8 @@ namespace System.Diagnostics {
public virtual int GetILOffset()
{
return ILOffset;
- }
-
+ }
+
// Returns the file name containing the code being executed. This
// information is normally extracted from the debugging symbols
// for the executable.
@@ -181,7 +181,7 @@ namespace System.Diagnostics {
{
return strFileName;
}
-
+
// Returns the line number in the file containing the code being executed.
// This information is normally extracted from the debugging symbols
// for the executable.
@@ -200,7 +200,7 @@ namespace System.Diagnostics {
return iColumnNumber;
}
-
+
// Builds a readable representation of the stack frame
//
public override String ToString()
@@ -258,10 +258,10 @@ namespace System.Diagnostics {
}
sb.Append(Environment.NewLine);
- return sb.ToString();
+ return sb.ToString();
}
-
-
+
+
private void BuildStackFrame(int skipFrames, bool fNeedFileInfo)
{
using (StackFrameHelper StackF = new StackFrameHelper(null))
diff --git a/src/mscorlib/src/System/Diagnostics/Stacktrace.cs b/src/mscorlib/src/System/Diagnostics/Stacktrace.cs
index cd88f5108f..cdedb66ed8 100644
--- a/src/mscorlib/src/System/Diagnostics/Stacktrace.cs
+++ b/src/mscorlib/src/System/Diagnostics/Stacktrace.cs
@@ -2,21 +2,22 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Diagnostics {
- using System;
- using System.Collections;
- using System.Text;
- using System.Threading;
- using System.Security;
- using System.IO;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Globalization;
- using System.Runtime.Serialization;
- using System.Runtime.Versioning;
- using System.Diagnostics.Contracts;
-
+using System;
+using System.Collections;
+using System.Text;
+using System.Threading;
+using System.Security;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Globalization;
+using System.Runtime.Serialization;
+using System.Runtime.Versioning;
+using System.Diagnostics.Contracts;
+
+namespace System.Diagnostics
+{
// READ ME:
// Modifying the order or fields of this object may require other changes
// to the unmanaged definition of the StackFrameHelper class, in
@@ -55,7 +56,7 @@ namespace System.Diagnostics {
#pragma warning restore 414
private delegate void GetSourceLineInfoDelegate(string assemblyPath, IntPtr loadedPeAddress, int loadedPeSize,
- IntPtr inMemoryPdbAddress, int inMemoryPdbSize, int methodToken, int ilOffset,
+ IntPtr inMemoryPdbAddress, int inMemoryPdbSize, int methodToken, int ilOffset,
out string sourceFile, out int sourceLine, out int sourceColumn);
private static Type s_symbolsType = null;
@@ -170,16 +171,16 @@ namespace System.Diagnostics {
}
}
- public virtual MethodBase GetMethodBase(int i)
- {
+ public virtual MethodBase GetMethodBase(int i)
+ {
// There may be a better way to do this.
// we got RuntimeMethodHandles here and we need to go to MethodBase
// but we don't know whether the reflection info has been initialized
// or not. So we call GetMethods and GetConstructors on the type
// and then we fetch the proper MethodBase!!
IntPtr mh = rgMethodHandle[i];
-
- if (mh.IsNull())
+
+ if (mh.IsNull())
return null;
IRuntimeMethodInfo mhReal = RuntimeMethodHandle.GetTypicalMethodDefinition(new RuntimeMethodInfoStub(mh, this));
@@ -187,32 +188,32 @@ namespace System.Diagnostics {
return RuntimeType.GetMethodBase(mhReal);
}
- public virtual int GetOffset(int i) { return rgiOffset[i];}
- public virtual int GetILOffset(int i) { return rgiILOffset[i];}
- public virtual String GetFilename(int i) { return rgFilename == null ? null : rgFilename[i];}
- public virtual int GetLineNumber(int i) { return rgiLineNumber == null ? 0 : rgiLineNumber[i];}
- public virtual int GetColumnNumber(int i) { return rgiColumnNumber == null ? 0 : rgiColumnNumber[i];}
+ public virtual int GetOffset(int i) { return rgiOffset[i]; }
+ public virtual int GetILOffset(int i) { return rgiILOffset[i]; }
+ public virtual String GetFilename(int i) { return rgFilename == null ? null : rgFilename[i]; }
+ public virtual int GetLineNumber(int i) { return rgiLineNumber == null ? 0 : rgiLineNumber[i]; }
+ public virtual int GetColumnNumber(int i) { return rgiColumnNumber == null ? 0 : rgiColumnNumber[i]; }
- public virtual bool IsLastFrameFromForeignExceptionStackTrace(int i)
- {
- return (rgiLastFrameFromForeignExceptionStackTrace == null)?false:rgiLastFrameFromForeignExceptionStackTrace[i];
- }
+ public virtual bool IsLastFrameFromForeignExceptionStackTrace(int i)
+ {
+ return (rgiLastFrameFromForeignExceptionStackTrace == null) ? false : rgiLastFrameFromForeignExceptionStackTrace[i];
+ }
+
+ public virtual int GetNumberOfFrames() { return iFrameCount; }
- public virtual int GetNumberOfFrames() { return iFrameCount;}
-
//
// serialization implementation
//
[OnSerializing]
- void OnSerializing(StreamingContext context)
+ private void OnSerializing(StreamingContext context)
{
// this is called in the process of serializing this object.
// For compatibility with Everett we need to assign the rgMethodBase field as that is the field
// that will be serialized
rgMethodBase = (rgMethodHandle == null) ? null : new MethodBase[rgMethodHandle.Length];
- if (rgMethodHandle != null)
+ if (rgMethodHandle != null)
{
- for (int i = 0; i < rgMethodHandle.Length; i++)
+ for (int i = 0; i < rgMethodHandle.Length; i++)
{
if (!rgMethodHandle[i].IsNull())
rgMethodBase[i] = RuntimeType.GetMethodBase(new RuntimeMethodInfoStub(rgMethodHandle[i], this));
@@ -221,20 +222,20 @@ namespace System.Diagnostics {
}
[OnSerialized]
- void OnSerialized(StreamingContext context)
+ private void OnSerialized(StreamingContext context)
{
// after we are done serializing null the rgMethodBase field
rgMethodBase = null;
}
[OnDeserialized]
- void OnDeserialized(StreamingContext context)
+ private void OnDeserialized(StreamingContext context)
{
// after we are done deserializing we need to transform the rgMethodBase in rgMethodHandle
rgMethodHandle = (rgMethodBase == null) ? null : new IntPtr[rgMethodBase.Length];
- if (rgMethodBase != null)
+ if (rgMethodBase != null)
{
- for (int i = 0; i < rgMethodBase.Length; i++)
+ for (int i = 0; i < rgMethodBase.Length; i++)
{
if (rgMethodBase[i] != null)
rgMethodHandle[i] = rgMethodBase[i].MethodHandle.Value;
@@ -243,8 +244,8 @@ namespace System.Diagnostics {
rgMethodBase = null;
}
}
-
-
+
+
// Class which represents a description of a stack trace
// There is no good reason for the methods of this class to be virtual.
// In order to ensure trusted code can trust the data it gets from a
@@ -274,42 +275,40 @@ namespace System.Diagnostics {
m_iMethodsToSkip = 0;
CaptureStackTrace(METHODS_TO_SKIP, fNeedFileInfo, null, null);
}
-
+
// Constructs a stack trace from the current location, in a caller's
// frame
//
public StackTrace(int skipFrames)
{
-
if (skipFrames < 0)
- throw new ArgumentOutOfRangeException(nameof(skipFrames),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(skipFrames),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
-
+
m_iNumOfFrames = 0;
m_iMethodsToSkip = 0;
-
- CaptureStackTrace(skipFrames+METHODS_TO_SKIP, false, null, null);
+
+ CaptureStackTrace(skipFrames + METHODS_TO_SKIP, false, null, null);
}
-
+
// Constructs a stack trace from the current location, in a caller's
// frame
//
public StackTrace(int skipFrames, bool fNeedFileInfo)
{
-
if (skipFrames < 0)
- throw new ArgumentOutOfRangeException(nameof(skipFrames),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(skipFrames),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
-
+
m_iNumOfFrames = 0;
m_iMethodsToSkip = 0;
-
- CaptureStackTrace(skipFrames+METHODS_TO_SKIP, fNeedFileInfo, null, null);
+
+ CaptureStackTrace(skipFrames + METHODS_TO_SKIP, fNeedFileInfo, null, null);
}
-
-
+
+
// Constructs a stack trace from the current location.
public StackTrace(Exception e)
{
@@ -334,7 +333,7 @@ namespace System.Diagnostics {
m_iMethodsToSkip = 0;
CaptureStackTrace(METHODS_TO_SKIP, fNeedFileInfo, null, e);
}
-
+
// Constructs a stack trace from the current location, in a caller's
// frame
//
@@ -344,16 +343,16 @@ namespace System.Diagnostics {
throw new ArgumentNullException(nameof(e));
if (skipFrames < 0)
- throw new ArgumentOutOfRangeException(nameof(skipFrames),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(skipFrames),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
-
+
m_iNumOfFrames = 0;
m_iMethodsToSkip = 0;
-
- CaptureStackTrace(skipFrames+METHODS_TO_SKIP, false, null, e);
+
+ CaptureStackTrace(skipFrames + METHODS_TO_SKIP, false, null, e);
}
-
+
// Constructs a stack trace from the current location, in a caller's
// frame
//
@@ -363,17 +362,17 @@ namespace System.Diagnostics {
throw new ArgumentNullException(nameof(e));
if (skipFrames < 0)
- throw new ArgumentOutOfRangeException(nameof(skipFrames),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(skipFrames),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
-
+
m_iNumOfFrames = 0;
m_iMethodsToSkip = 0;
-
- CaptureStackTrace(skipFrames+METHODS_TO_SKIP, fNeedFileInfo, null, e);
+
+ CaptureStackTrace(skipFrames + METHODS_TO_SKIP, fNeedFileInfo, null, e);
}
-
-
+
+
// Constructs a "fake" stack trace, just containing a single frame.
// Does not have the overhead of a full stack trace.
//
@@ -386,26 +385,14 @@ namespace System.Diagnostics {
}
- // Constructs a stack trace for the given thread
- //
- [Obsolete("This constructor has been deprecated. Please use a constructor that does not require a Thread parameter. http://go.microsoft.com/fwlink/?linkid=14202")]
- public StackTrace(Thread targetThread, bool needFileInfo)
- {
- m_iNumOfFrames = 0;
- m_iMethodsToSkip = 0;
-
- CaptureStackTrace(METHODS_TO_SKIP, needFileInfo, targetThread, null);
-
- }
-
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void GetStackFramesInternal(StackFrameHelper sfh, int iSkip, bool fNeedFileInfo, Exception e);
-
+
internal static int CalculateFramesToSkip(StackFrameHelper StackF, int iNumFrames)
{
int iRetVal = 0;
String PackageName = "System.Diagnostics";
-
+
// Check if this method is part of the System.Diagnostics
// package. If so, increment counter keeping track of
// System.Diagnostics functions
@@ -413,22 +400,22 @@ namespace System.Diagnostics {
{
MethodBase mb = StackF.GetMethodBase(i);
if (mb != null)
- {
+ {
Type t = mb.DeclaringType;
- if (t == null)
+ if (t == null)
break;
String ns = t.Namespace;
- if (ns == null)
+ if (ns == null)
break;
if (String.Compare(ns, PackageName, StringComparison.Ordinal) != 0)
break;
}
iRetVal++;
}
-
+
return iRetVal;
}
-
+
// Retrieves an object with stack trace information encoded.
// It leaves out the first "iSkip" lines of the stacktrace.
//
@@ -459,7 +446,7 @@ namespace System.Diagnostics {
sfTemp.SetOffset(StackF.GetOffset(i));
sfTemp.SetILOffset(StackF.GetILOffset(i));
- sfTemp.SetIsLastFrameFromForeignExceptionStackTrace(StackF.IsLastFrameFromForeignExceptionStackTrace(i));
+ sfTemp.SetIsLastFrameFromForeignExceptionStackTrace(StackF.IsLastFrameFromForeignExceptionStackTrace(i));
if (fNeedFileInfo)
{
@@ -488,23 +475,23 @@ namespace System.Diagnostics {
frames = null;
}
}
-
+
// Property to get the number of frames in the stack trace
//
public virtual int FrameCount
{
- get { return m_iNumOfFrames;}
+ get { return m_iNumOfFrames; }
}
-
-
+
+
// Returns a given stack frame. Stack frames are numbered starting at
// zero, which is the last stack frame pushed.
//
public virtual StackFrame GetFrame(int index)
{
if ((frames != null) && (index < m_iNumOfFrames) && (index >= 0))
- return frames[index+m_iMethodsToSkip];
-
+ return frames[index + m_iMethodsToSkip];
+
return null;
}
@@ -513,18 +500,18 @@ namespace System.Diagnostics {
// The nth element of this array is the same as GetFrame(n).
// The length of the array is the same as FrameCount.
//
- public virtual StackFrame [] GetFrames()
+ public virtual StackFrame[] GetFrames()
{
if (frames == null || m_iNumOfFrames <= 0)
return null;
-
+
// We have to return a subset of the array. Unfortunately this
// means we have to allocate a new array and copy over.
- StackFrame [] array = new StackFrame[m_iNumOfFrames];
+ StackFrame[] array = new StackFrame[m_iNumOfFrames];
Array.Copy(frames, m_iMethodsToSkip, array, 0, m_iNumOfFrames);
return array;
}
-
+
// Builds a readable representation of the stack trace
//
public override String ToString()
@@ -535,13 +522,13 @@ namespace System.Diagnostics {
// TraceFormat is Used to specify options for how the
// string-representation of a StackTrace should be generated.
- internal enum TraceFormat
+ internal enum TraceFormat
{
Normal,
TrailingNewLine, // include a trailing new line character
NoResourceLookup // to prevent infinite resource recusion
}
-
+
// Builds a readable representation of the stack trace, specifying
// the format for backwards compatibility.
internal String ToString(TraceFormat traceFormat)
@@ -550,12 +537,12 @@ namespace System.Diagnostics {
String word_At = "at";
String inFileLineNum = "in {0}:line {1}";
- if(traceFormat != TraceFormat.NoResourceLookup)
+ if (traceFormat != TraceFormat.NoResourceLookup)
{
- word_At = Environment.GetResourceString("Word_At");
- inFileLineNum = Environment.GetResourceString("StackTrace_InFileLineNumber");
+ word_At = SR.Word_At;
+ inFileLineNum = SR.StackTrace_InFileLineNumber;
}
-
+
bool fFirstFrame = true;
StringBuilder sb = new StringBuilder(255);
for (int iFrameIndex = 0; iFrameIndex < m_iNumOfFrames; iFrameIndex++)
@@ -569,11 +556,11 @@ namespace System.Diagnostics {
fFirstFrame = false;
else
sb.Append(Environment.NewLine);
-
+
sb.AppendFormat(CultureInfo.InvariantCulture, " {0} ", word_At);
Type t = mb.DeclaringType;
- // if there is a type (non global method) print it
+ // if there is a type (non global method) print it
if (t != null)
{
// Append t.FullName, replacing '+' with '.'
@@ -592,7 +579,7 @@ namespace System.Diagnostics {
{
Type[] typars = ((MethodInfo)mb).GetGenericArguments();
sb.Append('[');
- int k=0;
+ int k = 0;
bool fFirstTyParam = true;
while (k < typars.Length)
{
@@ -603,8 +590,8 @@ namespace System.Diagnostics {
sb.Append(typars[k].Name);
k++;
- }
- sb.Append(']');
+ }
+ sb.Append(']');
}
ParameterInfo[] pi = null;
@@ -635,7 +622,7 @@ namespace System.Diagnostics {
sb.Append(typeName);
sb.Append(' ');
sb.Append(pi[j].Name);
- }
+ }
sb.Append(')');
}
@@ -645,7 +632,7 @@ namespace System.Diagnostics {
// If we don't have a PDB or PDB-reading is disabled for the module,
// then the file name will be null.
String fileName = null;
-
+
// Getting the filename from a StackFrame is a privileged operation - we won't want
// to disclose full path names to arbitrarily untrusted code. Rather than just omit
// this we could probably trim to just the filename so it's still mostly usefull.
@@ -660,7 +647,7 @@ namespace System.Diagnostics {
displayFilenames = false;
}
- if (fileName != null)
+ if (fileName != null)
{
// tack on " in c:\tmp\MyFile.cs:line 5"
sb.Append(' ');
@@ -671,15 +658,15 @@ namespace System.Diagnostics {
if (sf.GetIsLastFrameFromForeignExceptionStackTrace())
{
sb.Append(Environment.NewLine);
- sb.Append(Environment.GetResourceString("Exception_EndStackTraceFromPreviousThrow"));
+ sb.Append(SR.Exception_EndStackTraceFromPreviousThrow);
}
}
}
- if(traceFormat == TraceFormat.TrailingNewLine)
+ if (traceFormat == TraceFormat.TrailingNewLine)
sb.Append(Environment.NewLine);
-
- return sb.ToString();
+
+ return sb.ToString();
}
// This helper is called from within the EE to construct a string representation
@@ -693,5 +680,4 @@ namespace System.Diagnostics {
return st.ToString();
}
}
-
}
diff --git a/src/mscorlib/src/System/Diagnostics/SymbolStore/ISymDocumentWriter.cs b/src/mscorlib/src/System/Diagnostics/SymbolStore/ISymDocumentWriter.cs
index a1a2366c0a..09a7a3b0b0 100644
--- a/src/mscorlib/src/System/Diagnostics/SymbolStore/ISymDocumentWriter.cs
+++ b/src/mscorlib/src/System/Diagnostics/SymbolStore/ISymDocumentWriter.cs
@@ -12,10 +12,11 @@
**
**
===========================================================*/
-namespace System.Diagnostics.SymbolStore {
-
- using System;
-
+
+using System;
+
+namespace System.Diagnostics.SymbolStore
+{
// Interface does not need to be marked with the serializable attribute
public interface ISymbolDocumentWriter
{
@@ -23,7 +24,7 @@ namespace System.Diagnostics.SymbolStore {
// symbol store. An array of unsigned bytes is used instead of
// character data to accommodate a wider variety of "source".
void SetSource(byte[] source);
-
+
// Check sum support.
void SetCheckSum(Guid algorithmId, byte[] checkSum);
}
diff --git a/src/mscorlib/src/System/Diagnostics/SymbolStore/ISymWriter.cs b/src/mscorlib/src/System/Diagnostics/SymbolStore/ISymWriter.cs
index bfe9133aee..fa2a59797a 100644
--- a/src/mscorlib/src/System/Diagnostics/SymbolStore/ISymWriter.cs
+++ b/src/mscorlib/src/System/Diagnostics/SymbolStore/ISymWriter.cs
@@ -11,18 +11,18 @@
**
**
===========================================================*/
-namespace System.Diagnostics.SymbolStore {
-
- using System;
- using System.Text;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
+using System;
+using System.Text;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+
+namespace System.Diagnostics.SymbolStore
+{
// Interface does not need to be marked with the serializable attribute
internal interface ISymbolWriter
{
-
// Define a source document. Guid's will be provided for the
// languages, vendors, and document types that we currently know
// about.
@@ -30,7 +30,7 @@ namespace System.Diagnostics.SymbolStore {
Guid language,
Guid languageVendor,
Guid documentType);
-
+
// Open a method to emit symbol information into. The given method
// becomes the current method for calls do define sequence points,
// parameters and lexical scopes. There is an implicit lexical
@@ -40,11 +40,11 @@ namespace System.Diagnostics.SymbolStore {
//
// There can be only one open method at a time.
void OpenMethod(SymbolToken method);
-
+
// Close the current method. Once a method is closed, no more
// symbols can be defined within it.
void CloseMethod();
-
+
// Define a group of sequence points within the current method.
// Each line/column defines the start of a statement within a
// method. The arrays should be sorted by offset. The offset is
@@ -55,7 +55,7 @@ namespace System.Diagnostics.SymbolStore {
int[] columns,
int[] endLines,
int[] endColumns);
-
+
// Open a new lexical scope in the current method. The scope
// becomes the new current scope and is effectivley pushed onto a
// stack of scopes. startOffset is the offset, in bytes from the
@@ -72,12 +72,12 @@ namespace System.Diagnostics.SymbolStore {
//
int OpenScope(int startOffset);
-
+
// Close the current lexical scope. Once a scope is closed no more
// variables can be defined within it. endOffset points past the
// last instruction in the scope.
void CloseScope(int endOffset);
-
+
// Define a single variable in the current lexical
// scope. startOffset and endOffset are optional. If 0, then they
// are ignored and the variable is defined over the entire
@@ -95,12 +95,12 @@ namespace System.Diagnostics.SymbolStore {
int addr3,
int startOffset,
int endOffset);
-
+
// Defines a custom attribute based upon its name. Not to be
// confused with Metadata custom attributes, these attributes are
// held in the symbol store.
void SetSymAttribute(SymbolToken parent, String name, byte[] data);
-
+
// Specifies that the given, fully qualified namespace name is
// being used within the currently open lexical scope. Closing the
// current scope will also stop using the namespace, and the
@@ -108,5 +108,4 @@ namespace System.Diagnostics.SymbolStore {
// currently open scope.
void UsingNamespace(String fullName);
}
-
}
diff --git a/src/mscorlib/src/System/Diagnostics/SymbolStore/SymAddressKind.cs b/src/mscorlib/src/System/Diagnostics/SymbolStore/SymAddressKind.cs
index bb50d9841b..c4c1ede525 100644
--- a/src/mscorlib/src/System/Diagnostics/SymbolStore/SymAddressKind.cs
+++ b/src/mscorlib/src/System/Diagnostics/SymbolStore/SymAddressKind.cs
@@ -11,37 +11,39 @@
**
**
===========================================================*/
-namespace System.Diagnostics.SymbolStore {
- // Only statics, does not need to be marked with the serializable attribute
- using System;
+// Only statics, does not need to be marked with the serializable attribute
+using System;
+
+namespace System.Diagnostics.SymbolStore
+{
[Serializable]
internal enum SymAddressKind
{
// ILOffset: addr1 = IL local var or param index.
ILOffset = 1,
-
+
// NativeRVA: addr1 = RVA into module.
NativeRVA = 2,
-
+
// NativeRegister: addr1 = register the var is stored in.
NativeRegister = 3,
-
+
// NativeRegisterRelative: addr1 = register, addr2 = offset.
NativeRegisterRelative = 4,
-
+
// NativeOffset: addr1 = offset from start of parent.
NativeOffset = 5,
-
+
// NativeRegisterRegister: addr1 = reg low, addr2 = reg high.
NativeRegisterRegister = 6,
-
+
// NativeRegisterStack: addr1 = reg low, addr2 = reg stk, addr3 = offset.
NativeRegisterStack = 7,
-
+
// NativeStackRegister: addr1 = reg stk, addr2 = offset, addr3 = reg high.
NativeStackRegister = 8,
-
+
// BitField: addr1 = field start, addr = field length.
BitField = 9,
diff --git a/src/mscorlib/src/System/Diagnostics/SymbolStore/Token.cs b/src/mscorlib/src/System/Diagnostics/SymbolStore/Token.cs
index cc1e4a865f..a6e6fdc0ef 100644
--- a/src/mscorlib/src/System/Diagnostics/SymbolStore/Token.cs
+++ b/src/mscorlib/src/System/Diagnostics/SymbolStore/Token.cs
@@ -9,21 +9,22 @@
** around metadata tokens.
**
===========================================================*/
-namespace System.Diagnostics.SymbolStore {
-
- using System;
- using System.Runtime.InteropServices;
+using System;
+using System.Runtime.InteropServices;
+
+namespace System.Diagnostics.SymbolStore
+{
internal struct SymbolToken
{
internal int m_token;
-
- public SymbolToken(int val) {m_token=val;}
-
- public int GetToken() {return m_token;}
-
- public override int GetHashCode() {return m_token;}
-
+
+ public SymbolToken(int val) { m_token = val; }
+
+ public int GetToken() { return m_token; }
+
+ public override int GetHashCode() { return m_token; }
+
public override bool Equals(Object obj)
{
if (obj is SymbolToken)
@@ -31,7 +32,7 @@ namespace System.Diagnostics.SymbolStore {
else
return false;
}
-
+
public bool Equals(SymbolToken obj)
{
return obj.m_token == m_token;
diff --git a/src/mscorlib/src/System/Diagnostics/log.cs b/src/mscorlib/src/System/Diagnostics/log.cs
index d297b8fa08..b62ea493e7 100644
--- a/src/mscorlib/src/System/Diagnostics/log.cs
+++ b/src/mscorlib/src/System/Diagnostics/log.cs
@@ -2,7 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Diagnostics {
+namespace System.Diagnostics
+{
using System.Runtime.Remoting;
using System;
using System.IO;
@@ -12,19 +13,19 @@ namespace System.Diagnostics {
using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
using System.Diagnostics.CodeAnalysis;
-
-
- // LogSwitchLevelHandlers are triggered when the level of a LogSwitch is modified
- // NOTE: These are NOT triggered when the log switch setting is changed from the
- // attached debugger.
- //
+
+ using Console = Internal.Console;
+
+ // LogSwitchLevelHandlers are triggered when the level of a LogSwitch is modified
+ // NOTE: These are NOT triggered when the log switch setting is changed from the
+ // attached debugger.
+ //
[Serializable]
internal delegate void LogSwitchLevelHandler(LogSwitch ls, LoggingLevels newLevel);
-
-
+
+
internal static class Log
{
-
// Switches allow relatively fine level control of which messages are
// actually shown. Normally most debugging messages are not shown - the
// user will typically enable those which are relevant to what is being
@@ -36,13 +37,13 @@ namespace System.Diagnostics {
// desired events are actually reported to the debugger.
internal static Hashtable m_Hashtable;
private static volatile bool m_fConsoleDeviceEnabled;
- private static volatile LogSwitchLevelHandler _LogSwitchLevelHandler;
+ private static volatile LogSwitchLevelHandler _LogSwitchLevelHandler;
private static Object locker;
-
+
// Constant representing the global switch
public static readonly LogSwitch GlobalSwitch;
-
-
+
+
static Log()
{
m_Hashtable = new Hashtable();
@@ -51,21 +52,21 @@ namespace System.Diagnostics {
//iNumOfMsgHandlers = 0;
//iMsgHandlerArraySize = 0;
locker = new Object();
-
+
// allocate the GlobalSwitch object
- GlobalSwitch = new LogSwitch ("Global", "Global Switch for this log");
-
+ GlobalSwitch = new LogSwitch("Global", "Global Switch for this log");
+
GlobalSwitch.MinimumLevel = LoggingLevels.ErrorLevel;
}
-
- internal static void InvokeLogSwitchLevelHandlers (LogSwitch ls, LoggingLevels newLevel)
+
+ internal static void InvokeLogSwitchLevelHandlers(LogSwitch ls, LoggingLevels newLevel)
{
LogSwitchLevelHandler handler = _LogSwitchLevelHandler;
if (handler != null)
handler(ls, newLevel);
}
-
-
+
+
// Property to Enable/Disable ConsoleDevice. Enabling the console device
// adds the console device as a log output, causing any
// log messages which make it through filters to be written to the
@@ -76,7 +77,7 @@ namespace System.Diagnostics {
get { return m_fConsoleDeviceEnabled; }
set { m_fConsoleDeviceEnabled = value; }
}
-
+
// Generates a log message. If its switch (or a parent switch) allows the
// level for the message, it is "broadcast" to all of the log
// devices.
@@ -84,28 +85,28 @@ namespace System.Diagnostics {
public static void LogMessage(LoggingLevels level, LogSwitch logswitch, String message)
{
if (logswitch == null)
- throw new ArgumentNullException ("LogSwitch");
-
+ throw new ArgumentNullException("LogSwitch");
+
if (level < 0)
- throw new ArgumentOutOfRangeException(nameof(level), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(level), SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
-
+
// Is logging for this level for this switch enabled?
- if (logswitch.CheckLevel (level) == true)
+ if (logswitch.CheckLevel(level) == true)
{
// Send message for logging
-
+
// first send it to the debugger
- Debugger.Log ((int) level, logswitch.strName, message);
-
+ Debugger.Log((int)level, logswitch.strName, message);
+
// Send to the console device
if (m_fConsoleDeviceEnabled)
{
- Console.Write(message);
- }
+ Console.Write(message);
+ }
}
}
-
+
/*
* Following are convenience entry points; all go through Log()
* Note that the (Switch switch, String message) variations
@@ -113,20 +114,19 @@ namespace System.Diagnostics {
*/
public static void Trace(LogSwitch logswitch, String message)
{
- LogMessage (LoggingLevels.TraceLevel0, logswitch, message);
+ LogMessage(LoggingLevels.TraceLevel0, logswitch, message);
}
-
+
public static void Trace(String message)
{
- LogMessage (LoggingLevels.TraceLevel0, GlobalSwitch, message);
+ LogMessage(LoggingLevels.TraceLevel0, GlobalSwitch, message);
}
-
-
+
+
// Native method to inform the EE about the creation of a new LogSwitch
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void AddLogSwitch(LogSwitch logSwitch);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern void ModifyLogSwitch (int iNewLevel, String strSwitchName, String strParentName);
+ internal static extern void ModifyLogSwitch(int iNewLevel, String strSwitchName, String strParentName);
}
-
}
diff --git a/src/mscorlib/src/System/DllNotFoundException.cs b/src/mscorlib/src/System/DllNotFoundException.cs
index 43bb57fec2..a3b46c76b3 100644
--- a/src/mscorlib/src/System/DllNotFoundException.cs
+++ b/src/mscorlib/src/System/DllNotFoundException.cs
@@ -11,29 +11,35 @@
**
=============================================================================*/
-namespace System {
-
- using System;
- using System.Runtime.Serialization;
+using System;
+using System.Runtime.Serialization;
+
+namespace System
+{
[Serializable]
- public class DllNotFoundException : TypeLoadException {
- public DllNotFoundException()
- : base(Environment.GetResourceString("Arg_DllNotFoundException")) {
- SetErrorCode(__HResults.COR_E_DLLNOTFOUND);
+ public class DllNotFoundException : TypeLoadException
+ {
+ public DllNotFoundException()
+ : base(SR.Arg_DllNotFoundException)
+ {
+ HResult = __HResults.COR_E_DLLNOTFOUND;
}
-
- public DllNotFoundException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_DLLNOTFOUND);
+
+ public DllNotFoundException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_DLLNOTFOUND;
}
-
- public DllNotFoundException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_DLLNOTFOUND);
+
+ public DllNotFoundException(String message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_DLLNOTFOUND;
}
- protected DllNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) {
- }
+ protected DllNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ }
}
}
diff --git a/src/mscorlib/src/System/Double.cs b/src/mscorlib/src/System/Double.cs
index 1e4e477366..f2c5cec219 100644
--- a/src/mscorlib/src/System/Double.cs
+++ b/src/mscorlib/src/System/Double.cs
@@ -11,19 +11,20 @@
**
**
===========================================================*/
-namespace System {
- using System;
- using System.Globalization;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Diagnostics.Contracts;
-
-[Serializable]
-[StructLayout(LayoutKind.Sequential)]
+using System;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
+ [Serializable]
+ [StructLayout(LayoutKind.Sequential)]
public struct Double : IComparable, IFormattable, IConvertible
- , IComparable<Double>, IEquatable<Double>
+ , IComparable<Double>, IEquatable<Double>
{
internal double m_value;
@@ -35,22 +36,24 @@ namespace System {
// Note Epsilon should be a double whose hex representation is 0x1
// on little endian machines.
- public const double Epsilon = 4.9406564584124654E-324;
+ public const double Epsilon = 4.9406564584124654E-324;
public const double NegativeInfinity = (double)-1.0 / (double)(0.0);
public const double PositiveInfinity = (double)1.0 / (double)(0.0);
public const double NaN = (double)0.0 / (double)0.0;
-
+
internal static double NegativeZero = BitConverter.Int64BitsToDouble(unchecked((long)0x8000000000000000));
[Pure]
[System.Runtime.Versioning.NonVersionable]
- public unsafe static bool IsInfinity(double d) {
+ public unsafe static bool IsInfinity(double d)
+ {
return (*(long*)(&d) & 0x7FFFFFFFFFFFFFFF) == 0x7FF0000000000000;
}
[Pure]
[System.Runtime.Versioning.NonVersionable]
- public static bool IsPositiveInfinity(double d) {
+ public static bool IsPositiveInfinity(double d)
+ {
//Jit will generate inlineable code with this
if (d == double.PositiveInfinity)
{
@@ -64,7 +67,8 @@ namespace System {
[Pure]
[System.Runtime.Versioning.NonVersionable]
- public static bool IsNegativeInfinity(double d) {
+ public static bool IsNegativeInfinity(double d)
+ {
//Jit will generate inlineable code with this
if (d == double.NegativeInfinity)
{
@@ -77,7 +81,8 @@ namespace System {
}
[Pure]
- internal unsafe static bool IsNegative(double d) {
+ internal unsafe static bool IsNegative(double d)
+ {
return (*(UInt64*)(&d) & 0x8000000000000000) == 0x8000000000000000;
}
@@ -96,11 +101,14 @@ namespace System {
//
// Returns a value less than zero if this object
//
- public int CompareTo(Object value) {
- if (value == null) {
+ public int CompareTo(Object value)
+ {
+ if (value == null)
+ {
return 1;
}
- if (value is Double) {
+ if (value is Double)
+ {
double d = (double)value;
if (m_value < d) return -1;
if (m_value > d) return 1;
@@ -112,10 +120,11 @@ namespace System {
else
return 1;
}
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDouble"));
+ throw new ArgumentException(SR.Arg_MustBeDouble);
}
- public int CompareTo(Double value) {
+ public int CompareTo(Double value)
+ {
if (m_value < value) return -1;
if (m_value > value) return 1;
if (m_value == value) return 0;
@@ -129,51 +138,61 @@ namespace System {
// True if obj is another Double with the same value as the current instance. This is
// a method of object equality, that only returns true if obj is also a double.
- public override bool Equals(Object obj) {
- if (!(obj is Double)) {
+ public override bool Equals(Object obj)
+ {
+ if (!(obj is Double))
+ {
return false;
}
double temp = ((Double)obj).m_value;
// This code below is written this way for performance reasons i.e the != and == check is intentional.
- if (temp == m_value) {
+ if (temp == m_value)
+ {
return true;
}
return IsNaN(temp) && IsNaN(m_value);
}
[System.Runtime.Versioning.NonVersionable]
- public static bool operator ==(Double left, Double right) {
+ public static bool operator ==(Double left, Double right)
+ {
return left == right;
}
[System.Runtime.Versioning.NonVersionable]
- public static bool operator !=(Double left, Double right) {
+ public static bool operator !=(Double left, Double right)
+ {
return left != right;
}
[System.Runtime.Versioning.NonVersionable]
- public static bool operator <(Double left, Double right) {
+ public static bool operator <(Double left, Double right)
+ {
return left < right;
}
[System.Runtime.Versioning.NonVersionable]
- public static bool operator >(Double left, Double right) {
+ public static bool operator >(Double left, Double right)
+ {
return left > right;
}
[System.Runtime.Versioning.NonVersionable]
- public static bool operator <=(Double left, Double right) {
+ public static bool operator <=(Double left, Double right)
+ {
return left <= right;
}
[System.Runtime.Versioning.NonVersionable]
- public static bool operator >=(Double left, Double right) {
+ public static bool operator >=(Double left, Double right)
+ {
return left >= right;
}
public bool Equals(Double obj)
{
- if (obj == m_value) {
+ if (obj == m_value)
+ {
return true;
}
return IsNaN(obj) && IsNaN(m_value);
@@ -182,9 +201,11 @@ namespace System {
//The hashcode for a double is the absolute value of the integer representation
//of that double.
//
- public unsafe override int GetHashCode() {
+ public unsafe override int GetHashCode()
+ {
double d = m_value;
- if (d == 0) {
+ if (d == 0)
+ {
// Ensure that 0 and -0 have the same hash code
return 0;
}
@@ -192,44 +213,52 @@ namespace System {
return unchecked((int)value) ^ ((int)(value >> 32));
}
- public override String ToString() {
+ public override String ToString()
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDouble(m_value, null, NumberFormatInfo.CurrentInfo);
}
- public String ToString(String format) {
+ public String ToString(String format)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDouble(m_value, format, NumberFormatInfo.CurrentInfo);
}
-
- public String ToString(IFormatProvider provider) {
+
+ public String ToString(IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDouble(m_value, null, NumberFormatInfo.GetInstance(provider));
}
-
- public String ToString(String format, IFormatProvider provider) {
+
+ public String ToString(String format, IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatDouble(m_value, format, NumberFormatInfo.GetInstance(provider));
}
- public static double Parse(String s) {
- return Parse(s, NumberStyles.Float| NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo);
+ public static double Parse(String s)
+ {
+ return Parse(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo);
}
- public static double Parse(String s, NumberStyles style) {
+ public static double Parse(String s, NumberStyles style)
+ {
NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
return Parse(s, style, NumberFormatInfo.CurrentInfo);
}
- public static double Parse(String s, IFormatProvider provider) {
- return Parse(s, NumberStyles.Float| NumberStyles.AllowThousands, NumberFormatInfo.GetInstance(provider));
+ public static double Parse(String s, IFormatProvider provider)
+ {
+ return Parse(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.GetInstance(provider));
}
- public static double Parse(String s, NumberStyles style, IFormatProvider provider) {
+ public static double Parse(String s, NumberStyles style, IFormatProvider provider)
+ {
NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
return Parse(s, style, NumberFormatInfo.GetInstance(provider));
}
-
+
// Parses a double from a String in the given style. If
// a NumberFormatInfo isn't specified, the current culture's
// NumberFormatInfo is assumed.
@@ -238,34 +267,46 @@ namespace System {
// PositiveInfinity or NegativeInfinity for a number that is too
// large or too small.
//
- private static double Parse(String s, NumberStyles style, NumberFormatInfo info) {
+ private static double Parse(String s, NumberStyles style, NumberFormatInfo info)
+ {
return Number.ParseDouble(s, style, info);
}
- public static bool TryParse(String s, out double result) {
- return TryParse(s, NumberStyles.Float| NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo, out result);
+ public static bool TryParse(String s, out double result)
+ {
+ return TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo, out result);
}
- public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out double result) {
+ public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out double result)
+ {
NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
return TryParse(s, style, NumberFormatInfo.GetInstance(provider), out result);
}
-
- private static bool TryParse(String s, NumberStyles style, NumberFormatInfo info, out double result) {
- if (s == null) {
+
+ private static bool TryParse(String s, NumberStyles style, NumberFormatInfo info, out double result)
+ {
+ if (s == null)
+ {
result = 0;
return false;
}
bool success = Number.TryParseDouble(s, style, info, out result);
- if (!success) {
+ if (!success)
+ {
String sTrim = s.Trim();
- if (sTrim.Equals(info.PositiveInfinitySymbol)) {
+ if (sTrim.Equals(info.PositiveInfinitySymbol))
+ {
result = PositiveInfinity;
- } else if (sTrim.Equals(info.NegativeInfinitySymbol)) {
+ }
+ else if (sTrim.Equals(info.NegativeInfinitySymbol))
+ {
result = NegativeInfinity;
- } else if (sTrim.Equals(info.NaNSymbol)) {
+ }
+ else if (sTrim.Equals(info.NaNSymbol))
+ {
result = NaN;
- } else
+ }
+ else
return false; // We really failed
}
return true;
@@ -275,82 +316,83 @@ namespace System {
// IConvertible implementation
//
- public TypeCode GetTypeCode() {
+ public TypeCode GetTypeCode()
+ {
return TypeCode.Double;
}
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
return Convert.ToBoolean(m_value);
}
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Double", "Char"));
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Double", "Char"));
}
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
return Convert.ToSByte(m_value);
}
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
return Convert.ToByte(m_value);
}
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
return Convert.ToInt16(m_value);
}
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
return Convert.ToUInt16(m_value);
}
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
return Convert.ToInt32(m_value);
}
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
return Convert.ToUInt32(m_value);
}
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
return Convert.ToInt64(m_value);
}
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
return Convert.ToUInt64(m_value);
}
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
return Convert.ToSingle(m_value);
}
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
return m_value;
}
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider) {
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
return Convert.ToDecimal(m_value);
}
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Double", "DateTime"));
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Double", "DateTime"));
}
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
return Convert.DefaultToType((IConvertible)this, type, provider);
}
}
diff --git a/src/mscorlib/src/System/Empty.cs b/src/mscorlib/src/System/Empty.cs
index 4790d9a383..502e8dfea7 100644
--- a/src/mscorlib/src/System/Empty.cs
+++ b/src/mscorlib/src/System/Empty.cs
@@ -5,28 +5,33 @@
// Empty
// This class represents an empty variant
////////////////////////////////////////////////////////////////////////////////
+
using System.Diagnostics.Contracts;
-namespace System {
-
- using System;
- using System.Runtime.Remoting;
- using System.Runtime.Serialization;
+using System;
+using System.Runtime.Remoting;
+using System.Runtime.Serialization;
+
+namespace System
+{
[Serializable]
internal sealed class Empty : ISerializable
{
- private Empty() {
+ private Empty()
+ {
}
-
+
public static readonly Empty Value = new Empty();
-
+
public override String ToString()
{
return String.Empty;
}
-
- public void GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
+
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/Enum.cs b/src/mscorlib/src/System/Enum.cs
index 97cfdf1b23..489f36739c 100644
--- a/src/mscorlib/src/System/Enum.cs
+++ b/src/mscorlib/src/System/Enum.cs
@@ -12,7 +12,7 @@ using System.Runtime.Versioning;
using System.Diagnostics;
using System.Diagnostics.Contracts;
-namespace System
+namespace System
{
[Serializable]
public abstract class Enum : ValueType, IComparable, IFormattable, IConvertible
@@ -69,7 +69,7 @@ namespace System
case CorElementType.U8:
return (*(ulong*)pValue).ToString("X16", null);
default:
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
+ throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
}
}
}
@@ -103,7 +103,7 @@ namespace System
return ((UInt64)(Int64)value).ToString("X16", null);
// All unsigned types will be directly cast
default:
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
+ throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
}
}
@@ -139,7 +139,7 @@ namespace System
}
}
- private static String InternalFlagsFormat(RuntimeType eT,ulong result)
+ private static String InternalFlagsFormat(RuntimeType eT, ulong result)
{
// These values are sorted by value. Don't change this
TypeValuesAndNames entry = GetCachedValuesAndNames(eT, true);
@@ -250,7 +250,7 @@ namespace System
break;
// All unsigned types will be directly cast
default:
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
+ throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
}
return result;
@@ -273,11 +273,11 @@ namespace System
#region Public Static Methods
private enum ParseFailureKind
{
- None = 0,
- Argument = 1,
- ArgumentNull = 2,
+ None = 0,
+ Argument = 1,
+ ArgumentNull = 2,
ArgumentWithParameter = 3,
- UnhandledException = 4
+ UnhandledException = 4
}
// This will store the result of the parsing.
@@ -316,20 +316,20 @@ namespace System
switch (m_failure)
{
case ParseFailureKind.Argument:
- return new ArgumentException(Environment.GetResourceString(m_failureMessageID));
+ return new ArgumentException(SR.GetResourceString(m_failureMessageID));
case ParseFailureKind.ArgumentNull:
return new ArgumentNullException(m_failureParameter);
case ParseFailureKind.ArgumentWithParameter:
- return new ArgumentException(Environment.GetResourceString(m_failureMessageID, m_failureMessageFormatArgument));
+ return new ArgumentException(SR.Format(SR.GetResourceString(m_failureMessageID), m_failureMessageFormatArgument));
case ParseFailureKind.UnhandledException:
return m_innerException;
default:
Debug.Assert(false, "Unknown EnumParseFailure: " + m_failure);
- return new ArgumentException(Environment.GetResourceString("Arg_EnumValueNotFound"));
+ return new ArgumentException(SR.Arg_EnumValueNotFound);
}
}
}
@@ -362,7 +362,7 @@ namespace System
bool retValue;
if (retValue = TryParseEnum(typeof(TEnum), value, ignoreCase, ref parseResult))
- result = (TEnum)parseResult.parsedEnum;
+ result = (TEnum)parseResult.parsedEnum;
return retValue;
}
@@ -402,12 +402,13 @@ namespace System
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeEnum, nameof(enumType));
- if (value == null) {
+ if (value == null)
+ {
parseResult.SetFailure(ParseFailureKind.ArgumentNull, nameof(value));
return false;
}
@@ -421,7 +422,8 @@ namespace System
break;
}
}
- if (firstNonWhitespaceIndex == -1) {
+ if (firstNonWhitespaceIndex == -1)
+ {
parseResult.SetFailure(ParseFailureKind.Argument, "Arg_MustContainEnumInfo", null);
return false;
}
@@ -466,8 +468,8 @@ namespace System
String[] enumNames = entry.Names;
ulong[] enumValues = entry.Values;
- StringComparison comparison = ignoreCase ?
- StringComparison.OrdinalIgnoreCase :
+ StringComparison comparison = ignoreCase ?
+ StringComparison.OrdinalIgnoreCase :
StringComparison.Ordinal;
int valueIndex = firstNonWhitespaceIndex;
@@ -490,7 +492,7 @@ namespace System
bool success = false;
for (int i = 0; i < enumNames.Length; i++)
{
- if (enumNames[i].Length == valueSubstringLength &&
+ if (enumNames[i].Length == valueSubstringLength &&
string.Compare(enumNames[i], 0, value, valueIndex, valueSubstringLength, comparison) == 0)
{
result |= enumValues[i];
@@ -553,7 +555,7 @@ namespace System
// Get all of the values
return GetCachedValuesAndNames(enumType, false).Values;
}
-
+
public static String GetName(Type enumType, Object value)
{
if (enumType == null)
@@ -590,28 +592,28 @@ namespace System
switch (typeCode)
{
- case TypeCode.Int32 :
+ case TypeCode.Int32:
return ToObject(enumType, (int)value);
- case TypeCode.SByte :
+ case TypeCode.SByte:
return ToObject(enumType, (sbyte)value);
- case TypeCode.Int16 :
+ case TypeCode.Int16:
return ToObject(enumType, (short)value);
- case TypeCode.Int64 :
+ case TypeCode.Int64:
return ToObject(enumType, (long)value);
- case TypeCode.UInt32 :
+ case TypeCode.UInt32:
return ToObject(enumType, (uint)value);
- case TypeCode.Byte :
+ case TypeCode.Byte:
return ToObject(enumType, (byte)value);
- case TypeCode.UInt16 :
+ case TypeCode.UInt16:
return ToObject(enumType, (ushort)value);
- case TypeCode.UInt64 :
+ case TypeCode.UInt64:
return ToObject(enumType, (ulong)value);
case TypeCode.Char:
@@ -622,7 +624,7 @@ namespace System
default:
// All unsigned types will be directly cast
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), nameof(value));
+ throw new ArgumentException(SR.Arg_MustBeEnumBaseTypeOrEnum, nameof(value));
}
}
@@ -635,14 +637,14 @@ namespace System
return enumType.IsEnumDefined(value);
}
-
+
public static String Format(Type enumType, Object value, String format)
{
if (enumType == null)
throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeEnum, nameof(enumType));
if (value == null)
throw new ArgumentNullException(nameof(value));
@@ -653,7 +655,7 @@ namespace System
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(enumType));
// Check if both of them are of the same type
Type valueType = value.GetType();
@@ -661,31 +663,32 @@ namespace System
Type underlyingType = GetUnderlyingType(enumType);
// If the value is an Enum then we need to extract the underlying value from it
- if (valueType.IsEnum) {
-
+ if (valueType.IsEnum)
+ {
if (!valueType.IsEquivalentTo(enumType))
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumAndObjectMustBeSameType", valueType.ToString(), enumType.ToString()));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, valueType.ToString(), enumType.ToString()));
if (format.Length != 1)
{
// all acceptable format string are of length 1
- throw new FormatException(Environment.GetResourceString("Format_InvalidEnumFormatSpecification"));
+ throw new FormatException(SR.Format_InvalidEnumFormatSpecification);
}
return ((Enum)value).ToString(format);
}
// The value must be of the same type as the Underlying type of the Enum
- else if (valueType != underlyingType) {
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumFormatUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), underlyingType.ToString()));
+ else if (valueType != underlyingType)
+ {
+ throw new ArgumentException(SR.Format(SR.Arg_EnumFormatUnderlyingTypeAndObjectMustBeSameType, valueType.ToString(), underlyingType.ToString()));
}
if (format.Length != 1)
{
// all acceptable format string are of length 1
- throw new FormatException(Environment.GetResourceString("Format_InvalidEnumFormatSpecification"));
+ throw new FormatException(SR.Format_InvalidEnumFormatSpecification);
}
char formatCh = format[0];
if (formatCh == 'G' || formatCh == 'g')
- return GetEnumName(rtType, ToUInt64(value));
+ return GetEnumName(rtType, ToUInt64(value)) ?? value.ToString();
if (formatCh == 'D' || formatCh == 'd')
return value.ToString();
@@ -696,7 +699,7 @@ namespace System
if (formatCh == 'F' || formatCh == 'f')
return Enum.InternalFlagsFormat(rtType, ToUInt64(value)) ?? value.ToString();
- throw new FormatException(Environment.GetResourceString("Format_InvalidEnumFormatSpecification"));
+ throw new FormatException(SR.Format_InvalidEnumFormatSpecification);
}
#endregion
@@ -884,7 +887,7 @@ namespace System
#endregion
#region IFormattable
- [Obsolete("The provider argument is not used. Please use ToString(String).")]
+ [Obsolete("The provider argument is not used. Please use ToString(String).")]
public String ToString(String format, IFormatProvider provider)
{
return ToString(format);
@@ -900,10 +903,10 @@ namespace System
if (this == null)
throw new NullReferenceException();
Contract.EndContractBlock();
-
+
int ret = InternalCompareTo(this, target);
- if (ret < retIncompatibleMethodTables)
+ if (ret < retIncompatibleMethodTables)
{
// -1, 0 and 1 are the normal return codes
return ret;
@@ -913,26 +916,26 @@ namespace System
Type thisType = this.GetType();
Type targetType = target.GetType();
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumAndObjectMustBeSameType",
- targetType.ToString(), thisType.ToString()));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, targetType.ToString(), thisType.ToString()));
}
else
{
// assert valid return code (3)
Debug.Assert(ret == retInvalidEnumType, "Enum.InternalCompareTo return code was invalid");
-
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
+
+ throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
}
}
#endregion
#region Public Methods
- public String ToString(String format) {
+ public String ToString(String format)
+ {
char formatCh;
if (format == null || format.Length == 0)
formatCh = 'G';
else if (format.Length != 1)
- throw new FormatException(Environment.GetResourceString("Format_InvalidEnumFormatSpecification"));
+ throw new FormatException(SR.Format_InvalidEnumFormatSpecification);
else
formatCh = format[0];
@@ -948,7 +951,7 @@ namespace System
if (formatCh == 'F' || formatCh == 'f')
return InternalFlagsFormat((RuntimeType)GetType(), ToUInt64()) ?? GetValue().ToString();
- throw new FormatException(Environment.GetResourceString("Format_InvalidEnumFormatSpecification"));
+ throw new FormatException(SR.Format_InvalidEnumFormatSpecification);
}
[Obsolete("The provider argument is not used. Please use ToString().")]
@@ -957,13 +960,15 @@ namespace System
return ToString();
}
- public Boolean HasFlag(Enum flag) {
+ public Boolean HasFlag(Enum flag)
+ {
if (flag == null)
throw new ArgumentNullException(nameof(flag));
Contract.EndContractBlock();
-
- if (!this.GetType().IsEquivalentTo(flag.GetType())) {
- throw new ArgumentException(Environment.GetResourceString("Argument_EnumTypeDoesNotMatch", flag.GetType(), this.GetType()));
+
+ if (!this.GetType().IsEquivalentTo(flag.GetType()))
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_EnumTypeDoesNotMatch, flag.GetType(), this.GetType()));
}
return InternalHasFlag(flag);
@@ -997,101 +1002,86 @@ namespace System
case CorElementType.U8:
return TypeCode.UInt64;
default:
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
+ throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
}
}
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider)
+ bool IConvertible.ToBoolean(IFormatProvider provider)
{
return Convert.ToBoolean(GetValue(), CultureInfo.CurrentCulture);
}
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider)
+ char IConvertible.ToChar(IFormatProvider provider)
{
return Convert.ToChar(GetValue(), CultureInfo.CurrentCulture);
}
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider)
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
{
return Convert.ToSByte(GetValue(), CultureInfo.CurrentCulture);
}
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider)
+ byte IConvertible.ToByte(IFormatProvider provider)
{
return Convert.ToByte(GetValue(), CultureInfo.CurrentCulture);
}
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider)
+ short IConvertible.ToInt16(IFormatProvider provider)
{
return Convert.ToInt16(GetValue(), CultureInfo.CurrentCulture);
}
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider)
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
{
return Convert.ToUInt16(GetValue(), CultureInfo.CurrentCulture);
}
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider)
+ int IConvertible.ToInt32(IFormatProvider provider)
{
return Convert.ToInt32(GetValue(), CultureInfo.CurrentCulture);
}
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider)
+ uint IConvertible.ToUInt32(IFormatProvider provider)
{
return Convert.ToUInt32(GetValue(), CultureInfo.CurrentCulture);
}
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider)
+ long IConvertible.ToInt64(IFormatProvider provider)
{
return Convert.ToInt64(GetValue(), CultureInfo.CurrentCulture);
}
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider)
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
{
return Convert.ToUInt64(GetValue(), CultureInfo.CurrentCulture);
}
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider)
+ float IConvertible.ToSingle(IFormatProvider provider)
{
return Convert.ToSingle(GetValue(), CultureInfo.CurrentCulture);
}
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider)
+ double IConvertible.ToDouble(IFormatProvider provider)
{
return Convert.ToDouble(GetValue(), CultureInfo.CurrentCulture);
}
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
{
return Convert.ToDecimal(GetValue(), CultureInfo.CurrentCulture);
}
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
{
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Enum", "DateTime"));
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Enum", "DateTime"));
}
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider)
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
{
return Convert.DefaultToType((IConvertible)this, type, provider);
}
#endregion
-
+
#region ToObject
[CLSCompliant(false)]
public static Object ToObject(Type enumType, sbyte value)
@@ -1099,11 +1089,11 @@ namespace System
if (enumType == null)
throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeEnum, nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(enumType));
return InternalBoxEnum(rtType, value);
}
@@ -1112,11 +1102,11 @@ namespace System
if (enumType == null)
throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeEnum, nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(enumType));
return InternalBoxEnum(rtType, value);
}
@@ -1125,11 +1115,11 @@ namespace System
if (enumType == null)
throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeEnum, nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(enumType));
return InternalBoxEnum(rtType, value);
}
@@ -1138,11 +1128,11 @@ namespace System
if (enumType == null)
throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeEnum, nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(enumType));
return InternalBoxEnum(rtType, value);
}
@@ -1152,11 +1142,11 @@ namespace System
if (enumType == null)
throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeEnum, nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(enumType));
return InternalBoxEnum(rtType, value);
}
@@ -1166,11 +1156,11 @@ namespace System
if (enumType == null)
throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeEnum, nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(enumType));
return InternalBoxEnum(rtType, value);
}
@@ -1179,11 +1169,11 @@ namespace System
if (enumType == null)
throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeEnum, nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(enumType));
return InternalBoxEnum(rtType, value);
}
@@ -1193,11 +1183,11 @@ namespace System
if (enumType == null)
throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeEnum, nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(enumType));
return InternalBoxEnum(rtType, unchecked((long)value));
}
@@ -1206,11 +1196,11 @@ namespace System
if (enumType == null)
throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeEnum, nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(enumType));
return InternalBoxEnum(rtType, value);
}
@@ -1219,11 +1209,11 @@ namespace System
if (enumType == null)
throw new ArgumentNullException(nameof(enumType));
if (!enumType.IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeEnum, nameof(enumType));
Contract.EndContractBlock();
RuntimeType rtType = enumType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(enumType));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(enumType));
return InternalBoxEnum(rtType, value ? 1 : 0);
}
#endregion
diff --git a/src/mscorlib/src/System/Environment.cs b/src/mscorlib/src/System/Environment.cs
index 8fa4ce4ff5..b9070ae713 100644
--- a/src/mscorlib/src/System/Environment.cs
+++ b/src/mscorlib/src/System/Environment.cs
@@ -11,7 +11,9 @@
**
**
============================================================*/
-namespace System {
+
+namespace System
+{
using System.IO;
using System.Security;
using System.Resources;
@@ -37,145 +39,37 @@ namespace System {
Machine = 2,
}
- public static partial class Environment
+ internal static partial class Environment
{
// Assume the following constants include the terminating '\0' - use <, not <=
- const int MaxEnvVariableValueLength = 32767; // maximum length for environment variable name and value
+ private const int MaxEnvVariableValueLength = 32767; // maximum length for environment variable name and value
// System environment variables are stored in the registry, and have
// a size restriction that is separate from both normal environment
// variables and registry value name lengths, according to MSDN.
// MSDN doesn't detail whether the name is limited to 1024, or whether
// that includes the contents of the environment variable.
- const int MaxSystemEnvVariableLength = 1024;
- const int MaxUserEnvVariableLength = 255;
+ private const int MaxSystemEnvVariableLength = 1024;
+ private const int MaxUserEnvVariableLength = 255;
+ private const int MaxMachineNameLength = 256;
- internal sealed class ResourceHelper
+ // Looks up the resource string value for key.
+ //
+ // if you change this method's signature then you must change the code that calls it
+ // in excep.cpp and probably you will have to visit mscorlib.h to add the new signature
+ // as well as metasig.h to create the new signature type
+ internal static String GetResourceStringLocal(String key)
{
- internal ResourceHelper(String name) {
- m_name = name;
- }
-
- private String m_name;
- private ResourceManager SystemResMgr;
-
- // To avoid infinite loops when calling GetResourceString. See comments
- // in GetResourceString for this field.
- private List<string> currentlyLoading;
-
- // process-wide state (since this is only used in one domain),
- // used to avoid the TypeInitialization infinite recusion
- // in GetResourceStringCode
- internal bool resourceManagerInited = false;
-
- // Is this thread currently doing infinite resource lookups?
- private int infinitelyRecursingCount;
-
- internal String GetResourceString(String key) {
- if (key == null || key.Length == 0) {
- Debug.Assert(false, "Environment::GetResourceString with null or empty key. Bug in caller, or weird recursive loading problem?");
- return "[Resource lookup failed - null or empty resource name]";
- }
-
- // We have a somewhat common potential for infinite
- // loops with mscorlib's ResourceManager. If "potentially dangerous"
- // code throws an exception, we will get into an infinite loop
- // inside the ResourceManager and this "potentially dangerous" code.
- // Potentially dangerous code includes the IO package, CultureInfo,
- // parts of the loader, some parts of Reflection, Security (including
- // custom user-written permissions that may parse an XML file at
- // class load time), assembly load event handlers, etc. Essentially,
- // this is not a bounded set of code, and we need to fix the problem.
- // Fortunately, this is limited to mscorlib's error lookups and is NOT
- // a general problem for all user code using the ResourceManager.
-
- // The solution is to make sure only one thread at a time can call
- // GetResourceString. Also, since resource lookups can be
- // reentrant, if the same thread comes into GetResourceString
- // twice looking for the exact same resource name before
- // returning, we're going into an infinite loop and we should
- // return a bogus string.
-
- bool lockTaken = false;
- try
- {
- Monitor.Enter(this, ref lockTaken);
-
- // Are we recursively looking up the same resource? Note - our backout code will set
- // the ResourceHelper's currentlyLoading stack to null if an exception occurs.
- if (currentlyLoading != null && currentlyLoading.Count > 0 && currentlyLoading.LastIndexOf(key) != -1)
- {
- // We can start infinitely recursing for one resource lookup,
- // then during our failure reporting, start infinitely recursing again.
- // avoid that.
- if (infinitelyRecursingCount > 0)
- {
- return "[Resource lookup failed - infinite recursion or critical failure detected.]";
- }
- infinitelyRecursingCount++;
-
- // Note: our infrastructure for reporting this exception will again cause resource lookup.
- // This is the most direct way of dealing with that problem.
- string message = $"Infinite recursion during resource lookup within {System.CoreLib.Name}. This may be a bug in {System.CoreLib.Name}, or potentially in certain extensibility points such as assembly resolve events or CultureInfo names. Resource name: {key}";
- Assert.Fail("[Recursive resource lookup bug]", message, Assert.COR_E_FAILFAST, System.Diagnostics.StackTrace.TraceFormat.NoResourceLookup);
- Environment.FailFast(message);
- }
- if (currentlyLoading == null)
- currentlyLoading = new List<string>();
-
- // Call class constructors preemptively, so that we cannot get into an infinite
- // loop constructing a TypeInitializationException. If this were omitted,
- // we could get the Infinite recursion assert above by failing type initialization
- // between the Push and Pop calls below.
- if (!resourceManagerInited)
- {
- RuntimeHelpers.RunClassConstructor(typeof(ResourceManager).TypeHandle);
- RuntimeHelpers.RunClassConstructor(typeof(ResourceReader).TypeHandle);
- RuntimeHelpers.RunClassConstructor(typeof(RuntimeResourceSet).TypeHandle);
- RuntimeHelpers.RunClassConstructor(typeof(BinaryReader).TypeHandle);
- resourceManagerInited = true;
- }
-
- currentlyLoading.Add(key); // Push
-
- if (SystemResMgr == null)
- {
- SystemResMgr = new ResourceManager(m_name, typeof(Object).Assembly);
- }
- string s = SystemResMgr.GetString(key, null);
- currentlyLoading.RemoveAt(currentlyLoading.Count - 1); // Pop
-
- Debug.Assert(s != null, "Managed resource string lookup failed. Was your resource name misspelled? Did you rebuild mscorlib after adding a resource to resources.txt? Debug this w/ cordbg and bug whoever owns the code that called Environment.GetResourceString. Resource name was: \"" + key + "\"");
- return s;
- }
- catch
- {
- if (lockTaken)
- {
- // Backout code - throw away potentially corrupt state
- SystemResMgr = null;
- currentlyLoading = null;
- }
- throw;
- }
- finally
- {
- if (lockTaken)
- {
- Monitor.Exit(this);
- }
- }
- }
+ return SR.GetResourceString(key);
}
- private static volatile ResourceHelper m_resHelper; // Doesn't need to be initialized as they're zero-init.
-
- private const int MaxMachineNameLength = 256;
-
// Private object for locking instead of locking on a public type for SQL reliability work.
private static Object s_InternalSyncObject;
- private static Object InternalSyncObject {
- get {
- if (s_InternalSyncObject == null) {
+ private static Object InternalSyncObject
+ {
+ get
+ {
+ if (s_InternalSyncObject == null)
+ {
Object o = new Object();
Interlocked.CompareExchange<Object>(ref s_InternalSyncObject, o, null);
}
@@ -192,25 +86,28 @@ namespace System {
**Arguments: None
**Exceptions: None
==============================================================================*/
- public static extern int TickCount {
+ public static extern int TickCount
+ {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
}
-
+
// Terminates this process with the given exit code.
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern void _Exit(int exitCode);
- public static void Exit(int exitCode) {
+ public static void Exit(int exitCode)
+ {
_Exit(exitCode);
}
- public static extern int ExitCode {
+ public static extern int ExitCode
+ {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
set;
}
@@ -246,22 +143,26 @@ namespace System {
==============================================================================*/
internal static String CurrentDirectory
{
- get{
+ get
+ {
return Directory.GetCurrentDirectory();
}
- set {
+ set
+ {
Directory.SetCurrentDirectory(value);
}
}
// Returns the system directory (ie, C:\WinNT\System32).
- internal static String SystemDirectory {
- get {
+ internal static String SystemDirectory
+ {
+ get
+ {
StringBuilder sb = new StringBuilder(Path.MaxPath);
int r = Win32Native.GetSystemDirectory(sb, Path.MaxPath);
Debug.Assert(r < Path.MaxPath, "r < Path.MaxPath");
- if (r==0) __Error.WinIOError();
+ if (r == 0) __Error.WinIOError();
String path = sb.ToString();
return path;
@@ -274,16 +175,11 @@ namespace System {
throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
- if (name.Length == 0) {
+ if (name.Length == 0)
+ {
return name;
}
- if (AppDomain.IsAppXModel() && !AppDomain.IsAppXDesignMode()) {
- // Environment variable accessors are not approved modern API.
- // Behave as if no variables are defined in this case.
- return name;
- }
-
int currentSize = 100;
StringBuilder blob = new StringBuilder(currentSize); // A somewhat reasonable default size
@@ -314,8 +210,9 @@ namespace System {
size = Win32Native.ExpandEnvironmentStrings(name, blob, currentSize);
if (size == 0)
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
-
- while (size > currentSize) {
+
+ while (size > currentSize)
+ {
currentSize = size;
blob.Capacity = currentSize;
blob.Length = 0;
@@ -329,32 +226,14 @@ namespace System {
return blob.ToString();
}
- public static String MachineName {
- get {
-
- // UWP Debug scenarios
- if (AppDomain.IsAppXModel() && !AppDomain.IsAppXDesignMode())
- {
- // Getting Computer Name is not a supported scenario on Store apps.
- throw new PlatformNotSupportedException();
- }
-
- // In future release of operating systems, you might be able to rename a machine without
- // rebooting. Therefore, don't cache this machine name.
- StringBuilder buf = new StringBuilder(MaxMachineNameLength);
- int len = MaxMachineNameLength;
- if (Win32Native.GetComputerName(buf, ref len) == 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ComputerName"));
- return buf.ToString();
- }
- }
-
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern Int32 GetProcessorCount();
- public static int ProcessorCount {
- get {
+ public static int ProcessorCount
+ {
+ get
+ {
return GetProcessorCount();
}
}
@@ -381,7 +260,7 @@ namespace System {
* So our best bet is to simply use the commandLine that was used to invoke the process.
* in case it is present.
*/
- if(s_CommandLineArgs != null)
+ if (s_CommandLineArgs != null)
return (string[])s_CommandLineArgs.Clone();
return GetCommandLineArgsNative();
@@ -450,91 +329,70 @@ namespace System {
**Arguments: None.
**Exceptions: None.
==============================================================================*/
- public static String NewLine {
- get {
+ public static String NewLine
+ {
+ get
+ {
Contract.Ensures(Contract.Result<String>() != null);
-#if !PLATFORM_UNIX
+#if PLATFORM_WINDOWS
return "\r\n";
#else
return "\n";
-#endif // !PLATFORM_UNIX
+#endif // PLATFORM_WINDOWS
}
}
-
+
/*===================================Version====================================
**Action: Returns the COM+ version struct, describing the build number.
**Returns:
**Arguments:
**Exceptions:
==============================================================================*/
- public static Version Version {
- get {
-
+ public static Version Version
+ {
+ get
+ {
// Previously this represented the File version of mscorlib.dll. Many other libraries in the framework and outside took dependencies on the first three parts of this version
// remaining constant throughout 4.x. From 4.0 to 4.5.2 this was fine since the file version only incremented the last part.Starting with 4.6 we switched to a file versioning
// scheme that matched the product version. In order to preserve compatibility with existing libraries, this needs to be hard-coded.
-
- return new Version(4,0,30319,42000);
- }
- }
-
- /*==================================OSVersion===================================
- **Action:
- **Returns:
- **Arguments:
- **Exceptions:
- ==============================================================================*/
- internal static OperatingSystem OSVersion {
- get {
- Contract.Ensures(Contract.Result<OperatingSystem>() != null);
-
- if (m_os==null) { // We avoid the lock since we don't care if two threads will set this at the same time.
-
- Microsoft.Win32.Win32Native.OSVERSIONINFO osvi = new Microsoft.Win32.Win32Native.OSVERSIONINFO();
- if (!GetVersion(osvi)) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GetVersion"));
- }
-
- Microsoft.Win32.Win32Native.OSVERSIONINFOEX osviEx = new Microsoft.Win32.Win32Native.OSVERSIONINFOEX();
- if (!GetVersionEx(osviEx))
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GetVersion"));
-#if PLATFORM_UNIX
- PlatformID id = PlatformID.Unix;
-#else
- PlatformID id = PlatformID.Win32NT;
-#endif // PLATFORM_UNIX
-
- Version v = new Version(osvi.MajorVersion, osvi.MinorVersion, osvi.BuildNumber, (osviEx.ServicePackMajor << 16) |osviEx.ServicePackMinor);
- m_os = new OperatingSystem(id, v, osvi.CSDVersion);
- }
- Debug.Assert(m_os != null, "m_os != null");
- return m_os;
+ return new Version(4, 0, 30319, 42000);
}
}
+#if !FEATURE_PAL
+ private static Lazy<bool> s_IsWindows8OrAbove = new Lazy<bool>(() =>
+ {
+ ulong conditionMask = Win32Native.VerSetConditionMask(0, Win32Native.VER_MAJORVERSION, Win32Native.VER_GREATER_EQUAL);
+ conditionMask = Win32Native.VerSetConditionMask(conditionMask, Win32Native.VER_MINORVERSION, Win32Native.VER_GREATER_EQUAL);
+ conditionMask = Win32Native.VerSetConditionMask(conditionMask, Win32Native.VER_SERVICEPACKMAJOR, Win32Native.VER_GREATER_EQUAL);
+ conditionMask = Win32Native.VerSetConditionMask(conditionMask, Win32Native.VER_SERVICEPACKMINOR, Win32Native.VER_GREATER_EQUAL);
- internal static bool IsWindows8OrAbove {
- get {
- return true;
- }
- }
-
+ // Windows 8 version is 6.2
+ var version = new Win32Native.OSVERSIONINFOEX { MajorVersion = 6, MinorVersion = 2, ServicePackMajor = 0, ServicePackMinor = 0 };
+
+ return Win32Native.VerifyVersionInfoW(version,
+ Win32Native.VER_MAJORVERSION | Win32Native.VER_MINORVERSION | Win32Native.VER_SERVICEPACKMAJOR | Win32Native.VER_SERVICEPACKMINOR,
+ conditionMask);
+ });
+ internal static bool IsWindows8OrAbove => s_IsWindows8OrAbove.Value;
+#endif
+
#if FEATURE_COMINTEROP
- internal static bool IsWinRTSupported {
- get {
- return true;
- }
- }
-#endif // FEATURE_COMINTEROP
-
+ // Does the current version of Windows have Windows Runtime suppport?
+ private static Lazy<bool> s_IsWinRTSupported = new Lazy<bool>(() =>
+ {
+ return WinRTSupported();
+ });
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern bool GetVersion(Microsoft.Win32.Win32Native.OSVERSIONINFO osVer);
+ internal static bool IsWinRTSupported => s_IsWinRTSupported.Value;
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern bool GetVersionEx(Microsoft.Win32.Win32Native.OSVERSIONINFOEX osVer);
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ private static extern bool WinRTSupported();
+#endif // FEATURE_COMINTEROP
/*==================================StackTrace==================================
@@ -543,11 +401,13 @@ namespace System {
**Arguments:
**Exceptions:
==============================================================================*/
- public static String StackTrace {
- get {
+ public static String StackTrace
+ {
+ [MethodImpl(MethodImplOptions.NoInlining)] // Prevent inlining from affecting where the stacktrace starts
+ get
+ {
Contract.Ensures(Contract.Result<String>() != null);
-
- return GetStackTrace(null, true);
+ return Internal.Runtime.Augments.EnvironmentAugments.StackTrace;
}
}
@@ -564,104 +424,19 @@ namespace System {
st = new StackTrace(e, needFileInfo);
// Do no include a trailing newline for backwards compatibility
- return st.ToString( System.Diagnostics.StackTrace.TraceFormat.Normal );
- }
-
- private static void InitResourceHelper() {
- // Only the default AppDomain should have a ResourceHelper. All calls to
- // GetResourceString from any AppDomain delegate to GetResourceStringLocal
- // in the default AppDomain via the fcall GetResourceFromDefault.
-
- bool tookLock = false;
- RuntimeHelpers.PrepareConstrainedRegions();
- try {
-
- Monitor.Enter(Environment.InternalSyncObject, ref tookLock);
-
- if (m_resHelper == null) {
- ResourceHelper rh = new ResourceHelper(System.CoreLib.Name);
-
- System.Threading.Thread.MemoryBarrier();
- m_resHelper =rh;
- }
- }
- finally {
- if (tookLock)
- Monitor.Exit(Environment.InternalSyncObject);
- }
- }
-
- // Looks up the resource string value for key.
- //
- // if you change this method's signature then you must change the code that calls it
- // in excep.cpp and probably you will have to visit mscorlib.h to add the new signature
- // as well as metasig.h to create the new signature type
- // NoInlining causes the caller and callee to not be inlined in mscorlib as it is an assumption of StackCrawlMark use
- [MethodImpl(MethodImplOptions.NoInlining)]
- internal static String GetResourceStringLocal(String key) {
- if (m_resHelper == null)
- InitResourceHelper();
-
- return m_resHelper.GetResourceString(key);
- }
-
- internal static String GetResourceString(String key) {
- return GetResourceStringLocal(key);
- }
-
- // The reason the following overloads exist are to reduce code bloat.
- // Since GetResourceString is basically only called when exceptions are
- // thrown, we want the code size to be as small as possible.
- // Using the params object[] overload works against this since the
- // initialization of the array is done inline in the caller at the IL
- // level. So we have overloads that simply wrap the params one, and
- // the methods they call through to are tagged as NoInlining.
- // In mscorlib NoInlining causes the caller and callee to not be inlined
- // as it is an assumption of StackCrawlMark use so it is not added
- // directly to these methods, but to the ones they call.
- // That way they do not bloat either the IL or the generated asm.
-
- internal static string GetResourceString(string key, object val0)
- {
- return GetResourceStringFormatted(key, new object[] { val0 });
- }
-
- internal static string GetResourceString(string key, object val0, object val1)
- {
- return GetResourceStringFormatted(key, new object[] { val0, val1 });
- }
-
- internal static string GetResourceString(string key, object val0, object val1, object val2)
- {
- return GetResourceStringFormatted(key, new object[] { val0, val1, val2 });
- }
-
- internal static string GetResourceString(string key, object val0, object val1, object val2, object val3)
- {
- return GetResourceStringFormatted(key, new object[] { val0, val1, val2, val3 });
- }
-
- internal static String GetResourceString(string key, params object[] values)
- {
- return GetResourceStringFormatted(key, values);
+ return st.ToString(System.Diagnostics.StackTrace.TraceFormat.Normal);
}
- // NoInlining causes the caller and callee to not be inlined in mscorlib as it is an assumption of StackCrawlMark use
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static String GetResourceStringFormatted(string key, params object[] values)
+ public static extern bool HasShutdownStarted
{
- string rs = GetResourceString(key);
- return String.Format(CultureInfo.CurrentCulture, rs, values);
- }
-
- public static extern bool HasShutdownStarted {
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
}
internal static bool UserInteractive
{
- get {
+ get
+ {
return true;
}
}
@@ -684,11 +459,11 @@ namespace System {
// TODO: Consider flushing the executionIdCache on Wait operations or similar
// actions that are likely to result in changing the executing core
[ThreadStatic]
- static int t_executionIdCache;
+ private static int t_executionIdCache;
- const int ExecutionIdCacheShift = 16;
- const int ExecutionIdCacheCountDownMask = (1 << ExecutionIdCacheShift) - 1;
- const int ExecutionIdRefreshRate = 5000;
+ private const int ExecutionIdCacheShift = 16;
+ private const int ExecutionIdCacheCountDownMask = (1 << ExecutionIdCacheShift) - 1;
+ private const int ExecutionIdRefreshRate = 5000;
private static int RefreshExecutionId()
{
@@ -784,19 +559,19 @@ namespace System {
}
if (variable.Length == 0)
{
- throw new ArgumentException(GetResourceString("Argument_StringZeroLength"), nameof(variable));
+ throw new ArgumentException(SR.Argument_StringZeroLength, nameof(variable));
}
if (variable[0] == '\0')
{
- throw new ArgumentException(GetResourceString("Argument_StringFirstCharIsZero"), nameof(variable));
+ throw new ArgumentException(SR.Argument_StringFirstCharIsZero, nameof(variable));
}
if (variable.Length >= MaxEnvVariableValueLength)
{
- throw new ArgumentException(GetResourceString("Argument_LongEnvVarValue"), nameof(variable));
+ throw new ArgumentException(SR.Argument_LongEnvVarValue, nameof(variable));
}
if (variable.IndexOf('=') != -1)
{
- throw new ArgumentException(GetResourceString("Argument_IllegalEnvVarName"), nameof(variable));
+ throw new ArgumentException(SR.Argument_IllegalEnvVarName, nameof(variable));
}
if (string.IsNullOrEmpty(value) || value[0] == '\0')
@@ -806,7 +581,7 @@ namespace System {
}
else if (value.Length >= MaxEnvVariableValueLength)
{
- throw new ArgumentException(GetResourceString("Argument_LongEnvVarValue"), nameof(value));
+ throw new ArgumentException(SR.Argument_LongEnvVarValue, nameof(value));
}
}
@@ -816,7 +591,7 @@ namespace System {
target != EnvironmentVariableTarget.Machine &&
target != EnvironmentVariableTarget.User)
{
- throw new ArgumentOutOfRangeException(nameof(target), target, SR.Format(GetResourceString("Arg_EnumIllegalVal"), target));
+ throw new ArgumentOutOfRangeException(nameof(target), target, SR.Format(SR.Arg_EnumIllegalVal, target));
}
}
@@ -867,13 +642,6 @@ namespace System {
private static string GetEnvironmentVariableCore(string variable)
{
- if (AppDomain.IsAppXModel() && !AppDomain.IsAppXDesignMode())
- {
- // Environment variable accessors are not approved modern API.
- // Behave as if the variable was not found in this case.
- return null;
- }
-
StringBuilder sb = StringBuilderCache.Acquire(128); // A somewhat reasonable default size
int requiredSize = Win32Native.GetEnvironmentVariable(variable, sb, sb.Capacity);
@@ -917,7 +685,7 @@ namespace System {
}
else
{
- throw new ArgumentException(GetResourceString("Arg_EnumIllegalVal", (int)target));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, (int)target));
}
using (RegistryKey environmentKey = baseKey.OpenSubKey(keyName, writable: false))
@@ -929,13 +697,6 @@ namespace System {
private static IDictionary GetEnvironmentVariablesCore()
{
- if (AppDomain.IsAppXModel() && !AppDomain.IsAppXDesignMode())
- {
- // Environment variable accessors are not approved modern API.
- // Behave as if no environment variables are defined in this case.
- return new Dictionary<string, string>(0);
- }
-
return GetRawEnvironmentVariables();
}
@@ -963,7 +724,7 @@ namespace System {
}
else
{
- throw new ArgumentException(GetResourceString("Arg_EnumIllegalVal", (int)target));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, (int)target));
}
using (RegistryKey environmentKey = baseKey.OpenSubKey(keyName, writable: false))
@@ -987,13 +748,6 @@ namespace System {
if (string.IsNullOrEmpty(value) || value[0] == '\0')
value = null;
- if (AppDomain.IsAppXModel() && !AppDomain.IsAppXDesignMode())
- {
- // Environment variable accessors are not approved modern API.
- // so we throw PlatformNotSupportedException.
- throw new PlatformNotSupportedException();
- }
-
if (!Win32Native.SetEnvironmentVariable(variable, value))
{
int errorCode = Marshal.GetLastWin32Error();
@@ -1006,7 +760,7 @@ namespace System {
case Win32Native.ERROR_FILENAME_EXCED_RANGE:
// The error message from Win32 is "The filename or extension is too long",
// which is not accurate.
- throw new ArgumentException(GetResourceString("Argument_LongEnvVarValue"));
+ throw new ArgumentException(SR.Format(SR.Argument_LongEnvVarValue));
default:
throw new ArgumentException(Win32Native.GetMessage(errorCode));
}
@@ -1045,7 +799,7 @@ namespace System {
const int MaxUserEnvVariableLength = 255;
if (variable.Length >= MaxUserEnvVariableLength)
{
- throw new ArgumentException(GetResourceString("Argument_LongEnvVarValue"), nameof(variable));
+ throw new ArgumentException(SR.Argument_LongEnvVarValue, nameof(variable));
}
baseKey = Registry.CurrentUser;
@@ -1053,7 +807,7 @@ namespace System {
}
else
{
- throw new ArgumentException(GetResourceString("Arg_EnumIllegalVal", (int)target));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, (int)target));
}
using (RegistryKey environmentKey = baseKey.OpenSubKey(keyName, writable: true))
@@ -1066,7 +820,7 @@ namespace System {
}
else
{
- environmentKey.SetValue(variable, value);
+ environmentKey.SetStringValue(variable, value);
}
}
}
diff --git a/src/mscorlib/src/System/Exception.cs b/src/mscorlib/src/System/Exception.cs
index a166c1ab0a..263b6b3c65 100644
--- a/src/mscorlib/src/System/Exception.cs
+++ b/src/mscorlib/src/System/Exception.cs
@@ -11,7 +11,8 @@
**
=============================================================================*/
-namespace System {
+namespace System
+{
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -36,55 +37,57 @@ namespace System {
_dynamicMethods = null;
HResult = __HResults.COR_E_EXCEPTION;
_xcode = _COMPlusExceptionCode;
- _xptrs = (IntPtr) 0;
+ _xptrs = (IntPtr)0;
// Initialize the WatsonBuckets to be null
_watsonBuckets = null;
// Initialize the watson bucketing IP
_ipForWatsonBuckets = UIntPtr.Zero;
-
}
- public Exception() {
+ public Exception()
+ {
Init();
}
-
- public Exception(String message) {
+
+ public Exception(String message)
+ {
Init();
_message = message;
}
-
+
// Creates a new Exception. All derived classes should
// provide this constructor.
// Note: the stack trace is not started until the exception
// is thrown
//
- public Exception (String message, Exception innerException) {
+ public Exception(String message, Exception innerException)
+ {
Init();
_message = message;
_innerException = innerException;
}
- protected Exception(SerializationInfo info, StreamingContext context)
+ protected Exception(SerializationInfo info, StreamingContext context)
{
- if (info==null)
+ if (info == null)
throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
-
+
_className = info.GetString("ClassName");
_message = info.GetString("Message");
- _data = (IDictionary)(info.GetValueNoThrow("Data",typeof(IDictionary)));
- _innerException = (Exception)(info.GetValue("InnerException",typeof(Exception)));
+ _data = (IDictionary)(info.GetValueNoThrow("Data", typeof(IDictionary)));
+ _innerException = (Exception)(info.GetValue("InnerException", typeof(Exception)));
_helpURL = info.GetString("HelpURL");
_stackTraceString = info.GetString("StackTraceString");
_remoteStackTraceString = info.GetString("RemoteStackTraceString");
_remoteStackIndex = info.GetInt32("RemoteStackIndex");
- _exceptionMethodString = (String)(info.GetValue("ExceptionMethod",typeof(String)));
+ _exceptionMethodString = (String)(info.GetValue("ExceptionMethod", typeof(String)));
HResult = info.GetInt32("HResult");
_source = info.GetString("Source");
-
+
// Get the WatsonBuckets that were serialized - this is particularly
// done to support exceptions going across AD transitions.
//
@@ -94,9 +97,9 @@ namespace System {
_watsonBuckets = (Object)info.GetValueNoThrow("WatsonBuckets", typeof(byte[]));
- if (_className == null || HResult==0)
- throw new SerializationException(Environment.GetResourceString("Serialization_InsufficientState"));
-
+ if (_className == null || HResult == 0)
+ throw new SerializationException(SR.Serialization_InsufficientState);
+
// If we are constructing a new exception after a cross-appdomain call...
if (context.State == StreamingContextStates.CrossAppDomain)
{
@@ -115,30 +118,37 @@ namespace System {
_stackTraceString = null;
}
}
-
-
- public virtual String Message {
- get {
- if (_message == null) {
- if (_className==null) {
+
+
+ public virtual String Message
+ {
+ get
+ {
+ if (_message == null)
+ {
+ if (_className == null)
+ {
_className = GetClassName();
}
- return Environment.GetResourceString("Exception_WasThrown", _className);
-
- } else {
+ return SR.Format(SR.Exception_WasThrown, _className);
+ }
+ else
+ {
return _message;
}
}
}
- public virtual IDictionary Data {
- get {
+ public virtual IDictionary Data
+ {
+ get
+ {
if (_data == null)
if (IsImmutableAgileException(this))
_data = new EmptyReadOnlyDictionaryInternal();
else
_data = new ListDictionaryInternal();
-
+
return _data;
}
}
@@ -163,22 +173,22 @@ namespace System {
internal __RestrictedErrorObject(object errorObject)
{
- _realErrorObject = errorObject;
+ _realErrorObject = errorObject;
}
public object RealErrorObject
{
- get
- {
- return _realErrorObject;
- }
+ get
+ {
+ return _realErrorObject;
+ }
}
}
[FriendAccessAllowed]
internal void AddExceptionDataForRestrictedErrorInfo(
- string restrictedError,
- string restrictedErrorReference,
+ string restrictedError,
+ string restrictedErrorReference,
string restrictedCapabilitySid,
object restrictedErrorObject,
bool hasrestrictedLanguageErrorObject = false)
@@ -223,26 +233,28 @@ namespace System {
return _className;
}
-
+
// Retrieves the lowest exception (inner most) for the given Exception.
// This will traverse exceptions using the innerException property.
//
- public virtual Exception GetBaseException()
+ public virtual Exception GetBaseException()
{
Exception inner = InnerException;
Exception back = this;
-
- while (inner != null) {
+
+ while (inner != null)
+ {
back = inner;
inner = inner.InnerException;
}
-
+
return back;
}
-
+
// Returns the inner exception contained in this exception
//
- public Exception InnerException {
+ public Exception InnerException
+ {
get { return _innerException; }
}
@@ -260,36 +272,44 @@ namespace System {
return RuntimeType.GetMethodBase(method);
}
-
- public MethodBase TargetSite {
- get {
+
+ public MethodBase TargetSite
+ {
+ get
+ {
return GetTargetSiteInternal();
}
}
-
+
// this function is provided as a private helper to avoid the security demand
- private MethodBase GetTargetSiteInternal() {
- if (_exceptionMethod!=null) {
+ private MethodBase GetTargetSiteInternal()
+ {
+ if (_exceptionMethod != null)
+ {
return _exceptionMethod;
}
- if (_stackTrace==null) {
+ if (_stackTrace == null)
+ {
return null;
}
- if (_exceptionMethodString!=null) {
+ if (_exceptionMethodString != null)
+ {
_exceptionMethod = GetExceptionMethodFromString();
- } else {
+ }
+ else
+ {
_exceptionMethod = GetExceptionMethodFromStackTrace();
}
return _exceptionMethod;
}
-
+
// Returns the stack trace as a string. If no stack trace is
// available, null is returned.
public virtual String StackTrace
{
- get
+ get
{
// By default attempt to include file and line number info
return GetStackTrace(true);
@@ -322,14 +342,14 @@ namespace System {
// don't store the stack trace string in the _stackTraceString member variable.
String tempStackTraceString = Environment.GetStackTrace(this, needFileInfo);
return remoteStackTraceString + tempStackTraceString;
- }
-
+ }
+
[FriendAccessAllowed]
internal void SetErrorCode(int hr)
{
HResult = hr;
}
-
+
// Sets the help link for this exception.
// This should be in a URL/URN form, such as:
// "file:///C:/Applications/Bazzal/help.html#ErrorNum42"
@@ -345,13 +365,15 @@ namespace System {
_helpURL = value;
}
}
-
- public virtual String Source {
- get {
+
+ public virtual String Source
+ {
+ get
+ {
if (_source == null)
{
- StackTrace st = new StackTrace(this,true);
- if (st.FrameCount>0)
+ StackTrace st = new StackTrace(this, true);
+ if (st.FrameCount > 0)
{
StackFrame sf = st.GetFrame(0);
MethodBase method = sf.GetMethod();
@@ -366,7 +388,7 @@ namespace System {
if (moduleBuilder != null)
rtModule = moduleBuilder.InternalModule;
else
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeReflectionObject"));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeReflectionObject);
}
_source = rtModule.GetRuntimeAssembly().GetSimpleName();
@@ -383,21 +405,24 @@ namespace System {
return ToString(true, true);
}
- private String ToString(bool needFileLineInfo, bool needMessage) {
+ private String ToString(bool needFileLineInfo, bool needMessage)
+ {
String message = (needMessage ? Message : null);
String s;
- if (message == null || message.Length <= 0) {
+ if (message == null || message.Length <= 0)
+ {
s = GetClassName();
}
- else {
+ else
+ {
s = GetClassName() + ": " + message;
}
- if (_innerException!=null) {
- s = s + " ---> " + _innerException.ToString(needFileLineInfo, needMessage) + Environment.NewLine +
- " " + Environment.GetResourceString("Exception_EndOfInnerExceptionStack");
-
+ if (_innerException != null)
+ {
+ s = s + " ---> " + _innerException.ToString(needFileLineInfo, needMessage) + Environment.NewLine +
+ " " + SR.Exception_EndOfInnerExceptionStack;
}
string stackTrace = GetStackTrace(needFileLineInfo);
@@ -408,10 +433,12 @@ namespace System {
return s;
}
-
- private String GetExceptionMethodString() {
+
+ private String GetExceptionMethodString()
+ {
MethodBase methBase = GetTargetSiteInternal();
- if (methBase==null) {
+ if (methBase == null)
+ {
return null;
}
if (methBase is System.Reflection.Emit.DynamicMethod.RTDynamicMethod)
@@ -425,13 +452,14 @@ namespace System {
// only for serialization of the Exception Method.
char separator = '\n';
StringBuilder result = new StringBuilder();
- if (methBase is ConstructorInfo) {
+ if (methBase is ConstructorInfo)
+ {
RuntimeConstructorInfo rci = (RuntimeConstructorInfo)methBase;
Type t = rci.ReflectedType;
result.Append((int)MemberTypes.Constructor);
result.Append(separator);
result.Append(rci.Name);
- if (t!=null)
+ if (t != null)
{
result.Append(separator);
result.Append(t.Assembly.FullName);
@@ -440,7 +468,9 @@ namespace System {
}
result.Append(separator);
result.Append(rci.ToString());
- } else {
+ }
+ else
+ {
Debug.Assert(methBase is MethodInfo, "[Exception.GetExceptionMethodString]methBase is MethodInfo");
RuntimeMethodInfo rmi = (RuntimeMethodInfo)methBase;
Type t = rmi.DeclaringType;
@@ -457,14 +487,16 @@ namespace System {
}
result.Append(rmi.ToString());
}
-
+
return result.ToString();
}
- private MethodBase GetExceptionMethodFromString() {
+ private MethodBase GetExceptionMethodFromString()
+ {
Debug.Assert(_exceptionMethodString != null, "Method string cannot be NULL!");
- String[] args = _exceptionMethodString.Split(new char[]{'\0', '\n'});
- if (args.Length!=5) {
+ String[] args = _exceptionMethodString.Split(new char[] { '\0', '\n' });
+ if (args.Length != 5)
+ {
throw new SerializationException();
}
SerializationInfo si = new SerializationInfo(typeof(MemberInfoSerializationHolder), new FormatterConverter());
@@ -475,9 +507,12 @@ namespace System {
si.AddValue("Signature", args[4]);
MethodBase result;
StreamingContext sc = new StreamingContext(StreamingContextStates.All);
- try {
+ try
+ {
result = (MethodBase)new MemberInfoSerializationHolder(si, sc).GetRealObject(sc);
- } catch (SerializationException) {
+ }
+ catch (SerializationException)
+ {
result = null;
}
return result;
@@ -485,11 +520,11 @@ namespace System {
protected event EventHandler<SafeSerializationEventArgs> SerializeObjectState
{
- add { throw new PlatformNotSupportedException();}
- remove { throw new PlatformNotSupportedException();}
+ add { throw new PlatformNotSupportedException(SR.PlatformNotSupported_SecureBinarySerialization); }
+ remove { throw new PlatformNotSupportedException(SR.PlatformNotSupported_SecureBinarySerialization); }
}
- public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
+ public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
@@ -497,25 +532,25 @@ namespace System {
}
Contract.EndContractBlock();
- String tempStackTraceString = _stackTraceString;
-
- if (_stackTrace!=null)
+ String tempStackTraceString = _stackTraceString;
+
+ if (_stackTrace != null)
{
- if (tempStackTraceString==null)
+ if (tempStackTraceString == null)
{
tempStackTraceString = Environment.GetStackTrace(this, true);
}
- if (_exceptionMethod==null)
+ if (_exceptionMethod == null)
{
_exceptionMethod = GetExceptionMethodFromStackTrace();
}
}
- if (_source == null)
+ if (_source == null)
{
_source = Source; // Set the Source information correctly before serialization
}
-
+
info.AddValue("ClassName", GetClassName(), typeof(String));
info.AddValue("Message", _message, typeof(String));
info.AddValue("Data", _data, typeof(IDictionary));
@@ -527,10 +562,9 @@ namespace System {
info.AddValue("ExceptionMethod", GetExceptionMethodString(), typeof(String));
info.AddValue("HResult", HResult);
info.AddValue("Source", _source, typeof(String));
-
+
// Serialize the Watson bucket details as well
info.AddValue("WatsonBuckets", _watsonBuckets, typeof(byte[]));
-
}
// This method will clear the _stackTrace of the exception object upon deserialization
@@ -547,7 +581,6 @@ namespace System {
//
// Hence, we set it to zero when deserialization takes place.
_ipForWatsonBuckets = UIntPtr.Zero;
-
}
// This is used by the runtime when re-throwing a managed exception. It will
@@ -583,11 +616,11 @@ namespace System {
{
_remoteStackTraceString = tmpStackTraceString + Environment.NewLine;
}
-
+
_stackTrace = null;
_stackTraceString = null;
}
-
+
// This is the object against which a lock will be taken
// when attempt to restore the EDI. Since its static, its possible
@@ -600,14 +633,15 @@ namespace System {
internal UIntPtr IPForWatsonBuckets
{
- get {
+ get
+ {
return _ipForWatsonBuckets;
- }
+ }
}
-
+
internal object WatsonBuckets
{
- get
+ get
{
return _watsonBuckets;
}
@@ -659,7 +693,7 @@ namespace System {
return null;
}
}
-
+
internal void GetStackTracesDeepCopy(out object currentStackTrace, out object dynamicMethodArray)
{
GetStackTracesDeepCopy(this, out currentStackTrace, out dynamicMethodArray);
@@ -680,7 +714,7 @@ namespace System {
// We do this inside a finally clause to ensure ThreadAbort cannot
// be injected while we have taken the lock. This is to prevent
// unrelated exception restorations from getting blocked due to TAE.
- try{}
+ try { }
finally
{
// When restoring back the fields, we again create a copy and set reference to them
@@ -689,14 +723,14 @@ namespace System {
//
// Since deep copying can throw on OOM, try to get the copies
// outside the lock.
- object _stackTraceCopy = (exceptionDispatchInfo.BinaryStackTraceArray == null)?null:DeepCopyStackTrace(exceptionDispatchInfo.BinaryStackTraceArray);
- object _dynamicMethodsCopy = (exceptionDispatchInfo.DynamicMethodArray == null)?null:DeepCopyDynamicMethods(exceptionDispatchInfo.DynamicMethodArray);
-
+ object _stackTraceCopy = (exceptionDispatchInfo.BinaryStackTraceArray == null) ? null : DeepCopyStackTrace(exceptionDispatchInfo.BinaryStackTraceArray);
+ object _dynamicMethodsCopy = (exceptionDispatchInfo.DynamicMethodArray == null) ? null : DeepCopyDynamicMethods(exceptionDispatchInfo.DynamicMethodArray);
+
// Finally, restore the information.
//
// Since EDI can be created at various points during exception dispatch (e.g. at various frames on the stack) for the same exception instance,
// they can have different data to be restored. Thus, to ensure atomicity of restoration from each EDI, perform the restore under a lock.
- lock(Exception.s_EDILock)
+ lock (Exception.s_EDILock)
{
_watsonBuckets = exceptionDispatchInfo.WatsonBuckets;
_ipForWatsonBuckets = exceptionDispatchInfo.IPForWatsonBuckets;
@@ -730,7 +764,7 @@ namespace System {
// DynamicMethodDescs alive for the lifetime of the exception. We do this because
// the _stackTrace field holds MethodDescs, and a DynamicMethodDesc can be destroyed
// unless a System.Resolver object roots it.
- private Object _dynamicMethods;
+ private Object _dynamicMethods;
#pragma warning restore 414
// @MANAGED: HResult is used from within the EE! Rename with care - check VM directory
@@ -747,7 +781,7 @@ namespace System {
_HResult = value;
}
}
-
+
private String _source; // Mainly used by VB.
// WARNING: Don't delete/rename _xptrs and _xcode - used by functions
// on Marshal class. Native functions are in COMUtilNative.cpp & AppDomain
@@ -769,7 +803,7 @@ namespace System {
// Get the current stack trace string.
return ToString(true, true);
}
-
+
// this method is required so Object.GetType is not made virtual by the compiler
// _Exception.GetType()
public new Type GetType()
@@ -779,7 +813,8 @@ namespace System {
internal bool IsTransient
{
- get {
+ get
+ {
return nIsTransient(_HResult);
}
}
@@ -824,12 +859,12 @@ namespace System {
// The Message field is set to the ToString() output of the original exception.
//--------------------------------------------------------------------------
- internal sealed class CrossAppDomainMarshaledException : SystemException
+ internal sealed class CrossAppDomainMarshaledException : SystemException
{
- public CrossAppDomainMarshaledException(String message, int errorCode)
- : base(message)
+ public CrossAppDomainMarshaledException(String message, int errorCode)
+ : base(message)
{
- SetErrorCode(errorCode);
+ HResult = errorCode;
}
// Normally, only Telesto's UEF will see these exceptions.
diff --git a/src/mscorlib/src/System/GC.cs b/src/mscorlib/src/System/GC.cs
index fd09ef7984..aeb0ca5196 100644
--- a/src/mscorlib/src/System/GC.cs
+++ b/src/mscorlib/src/System/GC.cs
@@ -12,21 +12,22 @@
**
**
===========================================================*/
-namespace System {
- //This class only static members and doesn't require the serializable keyword.
-
- using System;
- using System.Reflection;
- using System.Security;
- using System.Threading;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Globalization;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
- using System.Diagnostics.Contracts;
-
+//This class only static members and doesn't require the serializable keyword.
+
+using System;
+using System.Reflection;
+using System.Security;
+using System.Threading;
+using System.Runtime;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
[Serializable]
public enum GCCollectionMode
{
@@ -60,7 +61,7 @@ namespace System {
NotApplicable = 4
}
- public static class GC
+ public static class GC
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int GetGCLatencyMode();
@@ -95,9 +96,9 @@ namespace System {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int GetMaxGeneration();
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern int _CollectionCount (int generation, int getSpecialGCCount);
+ private static extern int _CollectionCount(int generation, int getSpecialGCCount);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern bool IsServerGC();
@@ -107,35 +108,41 @@ namespace System {
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern void _RemoveMemoryPressure(UInt64 bytesAllocated);
-
- public static void AddMemoryPressure (long bytesAllocated) {
- if( bytesAllocated <= 0) {
- throw new ArgumentOutOfRangeException(nameof(bytesAllocated),
- Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+
+ public static void AddMemoryPressure(long bytesAllocated)
+ {
+ if (bytesAllocated <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(bytesAllocated),
+ SR.ArgumentOutOfRange_NeedPosNum);
}
- if( (4 == IntPtr.Size) && (bytesAllocated > Int32.MaxValue) ) {
- throw new ArgumentOutOfRangeException("pressure",
- Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegInt32"));
+ if ((4 == IntPtr.Size) && (bytesAllocated > Int32.MaxValue))
+ {
+ throw new ArgumentOutOfRangeException("pressure",
+ SR.ArgumentOutOfRange_MustBeNonNegInt32);
}
Contract.EndContractBlock();
_AddMemoryPressure((ulong)bytesAllocated);
}
- public static void RemoveMemoryPressure (long bytesAllocated) {
- if( bytesAllocated <= 0) {
- throw new ArgumentOutOfRangeException(nameof(bytesAllocated),
- Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ public static void RemoveMemoryPressure(long bytesAllocated)
+ {
+ if (bytesAllocated <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(bytesAllocated),
+ SR.ArgumentOutOfRange_NeedPosNum);
}
- if( (4 == IntPtr.Size) && (bytesAllocated > Int32.MaxValue) ) {
- throw new ArgumentOutOfRangeException(nameof(bytesAllocated),
- Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegInt32"));
+ if ((4 == IntPtr.Size) && (bytesAllocated > Int32.MaxValue))
+ {
+ throw new ArgumentOutOfRangeException(nameof(bytesAllocated),
+ SR.ArgumentOutOfRange_MustBeNonNegInt32);
}
Contract.EndContractBlock();
- _RemoveMemoryPressure((ulong) bytesAllocated);
+ _RemoveMemoryPressure((ulong)bytesAllocated);
}
@@ -144,40 +151,42 @@ namespace System {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern int GetGeneration(Object obj);
-
+
// Forces a collection of all generations from 0 through Generation.
//
- public static void Collect(int generation) {
+ public static void Collect(int generation)
+ {
Collect(generation, GCCollectionMode.Default);
}
-
+
// Garbage Collect all generations.
//
- public static void Collect() {
+ public static void Collect()
+ {
//-1 says to GC all generations.
_Collect(-1, (int)InternalGCCollectionMode.Blocking);
}
- public static void Collect(int generation, GCCollectionMode mode)
+ public static void Collect(int generation, GCCollectionMode mode)
{
Collect(generation, mode, true);
}
- public static void Collect(int generation, GCCollectionMode mode, bool blocking)
+ public static void Collect(int generation, GCCollectionMode mode, bool blocking)
{
Collect(generation, mode, blocking, false);
}
public static void Collect(int generation, GCCollectionMode mode, bool blocking, bool compacting)
{
- if (generation<0)
+ if (generation < 0)
{
- throw new ArgumentOutOfRangeException(nameof(generation), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ throw new ArgumentOutOfRangeException(nameof(generation), SR.ArgumentOutOfRange_GenericPositive);
}
if ((mode < GCCollectionMode.Default) || (mode > GCCollectionMode.Optimized))
{
- throw new ArgumentOutOfRangeException(nameof(mode), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(mode), SR.ArgumentOutOfRange_Enum);
}
Contract.EndContractBlock();
@@ -204,16 +213,16 @@ namespace System {
_Collect(generation, iInternalModes);
}
- public static int CollectionCount (int generation)
+ public static int CollectionCount(int generation)
{
- if (generation<0)
+ if (generation < 0)
{
- throw new ArgumentOutOfRangeException(nameof(generation), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
+ throw new ArgumentOutOfRangeException(nameof(generation), SR.ArgumentOutOfRange_GenericPositive);
}
Contract.EndContractBlock();
return _CollectionCount(generation, 0);
}
-
+
// This method DOES NOT DO ANYTHING in and of itself. It's used to
// prevent a finalizable object from losing any outstanding references
// a touch too early. The JIT is very aggressive about keeping an
@@ -256,15 +265,17 @@ namespace System {
// Returns the generation in which wo currently resides.
//
- public static int GetGeneration(WeakReference wo) {
+ public static int GetGeneration(WeakReference wo)
+ {
int result = GetGenerationWR(wo.m_handle);
KeepAlive(wo);
return result;
}
-
+
// Returns the maximum GC generation. Currently assumes only 1 heap.
//
- public static int MaxGeneration {
+ public static int MaxGeneration
+ {
get { return GetMaxGeneration(); }
}
@@ -272,17 +283,19 @@ namespace System {
[SuppressUnmanagedCodeSecurity]
private static extern void _WaitForPendingFinalizers();
- public static void WaitForPendingFinalizers() {
+ public static void WaitForPendingFinalizers()
+ {
// QCalls can not be exposed from mscorlib directly, need to wrap it.
_WaitForPendingFinalizers();
}
-
+
// Indicates that the system should not call the Finalize() method on
// an object that would normally require this call.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _SuppressFinalize(Object o);
- public static void SuppressFinalize(Object obj) {
+ public static void SuppressFinalize(Object obj)
+ {
if (obj == null)
throw new ArgumentNullException(nameof(obj));
Contract.EndContractBlock();
@@ -295,8 +308,9 @@ namespace System {
// needs to resurrect itself or an object that it references.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _ReRegisterForFinalize(Object o);
-
- public static void ReRegisterForFinalize(Object obj) {
+
+ public static void ReRegisterForFinalize(Object obj)
+ {
if (obj == null)
throw new ArgumentNullException(nameof(obj));
Contract.EndContractBlock();
@@ -307,7 +321,8 @@ namespace System {
// the GC heap. This does not return the total size of the GC heap, but
// only the live objects in the GC heap.
//
- public static long GetTotalMemory(bool forceFullCollection) {
+ public static long GetTotalMemory(bool forceFullCollection)
+ {
long size = GetTotalMemory();
if (!forceFullCollection)
return size;
@@ -319,7 +334,8 @@ namespace System {
int reps = 20; // Number of iterations
long newSize = size;
float diff;
- do {
+ do
+ {
GC.WaitForPendingFinalizers();
GC.Collect();
size = newSize;
@@ -332,7 +348,8 @@ namespace System {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern long _GetAllocatedBytesForCurrentThread();
- public static long GetAllocatedBytesForCurrentThread() {
+ public static long GetAllocatedBytesForCurrentThread()
+ {
return _GetAllocatedBytesForCurrentThread();
}
@@ -352,27 +369,27 @@ namespace System {
{
if ((maxGenerationThreshold <= 0) || (maxGenerationThreshold >= 100))
{
- throw new ArgumentOutOfRangeException(nameof(maxGenerationThreshold),
+ throw new ArgumentOutOfRangeException(nameof(maxGenerationThreshold),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper"),
- 1,
+ SR.ArgumentOutOfRange_Bounds_Lower_Upper,
+ 1,
99));
}
-
+
if ((largeObjectHeapThreshold <= 0) || (largeObjectHeapThreshold >= 100))
{
- throw new ArgumentOutOfRangeException(nameof(largeObjectHeapThreshold),
+ throw new ArgumentOutOfRangeException(nameof(largeObjectHeapThreshold),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper"),
- 1,
+ SR.ArgumentOutOfRange_Bounds_Lower_Upper,
+ 1,
99));
-}
+ }
if (!_RegisterForFullGCNotification(maxGenerationThreshold, largeObjectHeapThreshold))
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotWithConcurrentGC"));
+ throw new InvalidOperationException(SR.InvalidOperation_NotWithConcurrentGC);
}
}
@@ -380,7 +397,7 @@ namespace System {
{
if (!_CancelFullGCNotification())
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotWithConcurrentGC"));
+ throw new InvalidOperationException(SR.InvalidOperation_NotWithConcurrentGC);
}
}
@@ -392,7 +409,7 @@ namespace System {
public static GCNotificationStatus WaitForFullGCApproach(int millisecondsTimeout)
{
if (millisecondsTimeout < -1)
- throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
return (GCNotificationStatus)_WaitForFullGCApproach(millisecondsTimeout);
}
@@ -405,11 +422,11 @@ namespace System {
public static GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout)
{
if (millisecondsTimeout < -1)
- throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
return (GCNotificationStatus)_WaitForFullGCComplete(millisecondsTimeout);
}
- enum StartNoGCRegionStatus
+ private enum StartNoGCRegionStatus
{
Succeeded = 0,
NotEnoughMemory = 1,
@@ -417,7 +434,7 @@ namespace System {
AlreadyInProgress = 3
}
- enum EndNoGCRegionStatus
+ private enum EndNoGCRegionStatus
{
Succeeded = 0,
NotInProgress = 1,
@@ -425,11 +442,11 @@ namespace System {
AllocationExceeded = 3
}
- static bool StartNoGCRegionWorker(long totalSize, bool hasLohSize, long lohSize, bool disallowFullBlockingGC)
+ private static bool StartNoGCRegionWorker(long totalSize, bool hasLohSize, long lohSize, bool disallowFullBlockingGC)
{
StartNoGCRegionStatus status = (StartNoGCRegionStatus)_StartNoGCRegion(totalSize, hasLohSize, lohSize, disallowFullBlockingGC);
if (status == StartNoGCRegionStatus.AmountTooLarge)
- throw new ArgumentOutOfRangeException(nameof(totalSize),
+ throw new ArgumentOutOfRangeException(nameof(totalSize),
"totalSize is too large. For more information about setting the maximum size, see \"Latency Modes\" in http://go.microsoft.com/fwlink/?LinkId=522706");
else if (status == StartNoGCRegionStatus.AlreadyInProgress)
throw new InvalidOperationException("The NoGCRegion mode was already in progress");
@@ -458,7 +475,7 @@ namespace System {
return StartNoGCRegionWorker(totalSize, true, lohSize, disallowFullBlockingGC);
}
- static EndNoGCRegionStatus EndNoGCRegionWorker()
+ private static EndNoGCRegionStatus EndNoGCRegionWorker()
{
EndNoGCRegionStatus status = (EndNoGCRegionStatus)_EndNoGCRegion();
if (status == EndNoGCRegionStatus.NotInProgress)
diff --git a/src/mscorlib/src/System/Globalization/BidiCategory.cs b/src/mscorlib/src/System/Globalization/BidiCategory.cs
index 1041776424..f37c44b385 100644
--- a/src/mscorlib/src/System/Globalization/BidiCategory.cs
+++ b/src/mscorlib/src/System/Globalization/BidiCategory.cs
@@ -9,9 +9,12 @@
**
**
============================================================*/
-namespace System.Globalization {
+
+namespace System.Globalization
+{
[Serializable]
- internal enum BidiCategory {
+ internal enum BidiCategory
+ {
LeftToRight = 0,
LeftToRightEmbedding = 1,
LeftToRightOverride = 2,
@@ -32,7 +35,7 @@ namespace System.Globalization {
Whitespace = 17,
OtherNeutrals = 18,
LeftToRightIsolate = 19,
- RightToLeftIsolate = 20,
+ RightToLeftIsolate = 20,
FirstStrongIsolate = 21,
PopDirectionIsolate = 22,
}
diff --git a/src/mscorlib/src/System/Globalization/Calendar.cs b/src/mscorlib/src/System/Globalization/Calendar.cs
index 1ff795ddc5..c23e1088c1 100644
--- a/src/mscorlib/src/System/Globalization/Calendar.cs
+++ b/src/mscorlib/src/System/Globalization/Calendar.cs
@@ -2,14 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Globalization {
- using System;
- using System.Runtime.CompilerServices;
- using System.Globalization;
- using System.Runtime.Versioning;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+namespace System.Globalization
+{
// This abstract class represents a calendar. A calendar reckons time in
// divisions such as weeks, months and years. The number, length and start of
// the divisions vary in each calendar.
@@ -31,69 +29,49 @@ namespace System.Globalization {
// since most of the calendars (or all?) have the same way of calcuating hour/minute/second.
[Serializable]
- public abstract class Calendar : ICloneable
+ public abstract partial class Calendar : ICloneable
{
-
// Number of 100ns (10E-7 second) ticks per time unit
- internal const long TicksPerMillisecond = 10000;
- internal const long TicksPerSecond = TicksPerMillisecond * 1000;
- internal const long TicksPerMinute = TicksPerSecond * 60;
- internal const long TicksPerHour = TicksPerMinute * 60;
- internal const long TicksPerDay = TicksPerHour * 24;
+ internal const long TicksPerMillisecond = 10000;
+ internal const long TicksPerSecond = TicksPerMillisecond * 1000;
+ internal const long TicksPerMinute = TicksPerSecond * 60;
+ internal const long TicksPerHour = TicksPerMinute * 60;
+ internal const long TicksPerDay = TicksPerHour * 24;
// Number of milliseconds per time unit
- internal const int MillisPerSecond = 1000;
- internal const int MillisPerMinute = MillisPerSecond * 60;
- internal const int MillisPerHour = MillisPerMinute * 60;
- internal const int MillisPerDay = MillisPerHour * 24;
+ internal const int MillisPerSecond = 1000;
+ internal const int MillisPerMinute = MillisPerSecond * 60;
+ internal const int MillisPerHour = MillisPerMinute * 60;
+ internal const int MillisPerDay = MillisPerHour * 24;
// Number of days in a non-leap year
- internal const int DaysPerYear = 365;
+ internal const int DaysPerYear = 365;
// Number of days in 4 years
- internal const int DaysPer4Years = DaysPerYear * 4 + 1;
+ internal const int DaysPer4Years = DaysPerYear * 4 + 1;
// Number of days in 100 years
- internal const int DaysPer100Years = DaysPer4Years * 25 - 1;
+ internal const int DaysPer100Years = DaysPer4Years * 25 - 1;
// Number of days in 400 years
- internal const int DaysPer400Years = DaysPer100Years * 4 + 1;
+ internal const int DaysPer400Years = DaysPer100Years * 4 + 1;
// Number of days from 1/1/0001 to 1/1/10000
- internal const int DaysTo10000 = DaysPer400Years * 25 - 366;
-
- internal const long MaxMillis = (long)DaysTo10000 * MillisPerDay;
-
- //
- // Calendar ID Values. This is used to get data from calendar.nlp.
- // The order of calendar ID means the order of data items in the table.
- //
-
- internal const int CAL_GREGORIAN = 1 ; // Gregorian (localized) calendar
- internal const int CAL_GREGORIAN_US = 2 ; // Gregorian (U.S.) calendar
- internal const int CAL_JAPAN = 3 ; // Japanese Emperor Era calendar
- internal const int CAL_TAIWAN = 4 ; // Taiwan Era calendar
- internal const int CAL_KOREA = 5 ; // Korean Tangun Era calendar
- internal const int CAL_HIJRI = 6 ; // Hijri (Arabic Lunar) calendar
- internal const int CAL_THAI = 7 ; // Thai calendar
- internal const int CAL_HEBREW = 8 ; // Hebrew (Lunar) calendar
- internal const int CAL_GREGORIAN_ME_FRENCH = 9 ; // Gregorian Middle East French calendar
- internal const int CAL_GREGORIAN_ARABIC = 10; // Gregorian Arabic calendar
- internal const int CAL_GREGORIAN_XLIT_ENGLISH = 11; // Gregorian Transliterated English calendar
- internal const int CAL_GREGORIAN_XLIT_FRENCH = 12;
- internal const int CAL_JULIAN = 13;
- internal const int CAL_JAPANESELUNISOLAR = 14;
- internal const int CAL_CHINESELUNISOLAR = 15;
- internal const int CAL_SAKA = 16; // reserved to match Office but not implemented in our code
- internal const int CAL_LUNAR_ETO_CHN = 17; // reserved to match Office but not implemented in our code
- internal const int CAL_LUNAR_ETO_KOR = 18; // reserved to match Office but not implemented in our code
- internal const int CAL_LUNAR_ETO_ROKUYOU = 19; // reserved to match Office but not implemented in our code
- internal const int CAL_KOREANLUNISOLAR = 20;
- internal const int CAL_TAIWANLUNISOLAR = 21;
- internal const int CAL_PERSIAN = 22;
- internal const int CAL_UMALQURA = 23;
-
- internal int m_currentEraValue = -1;
-
- [System.Runtime.Serialization.OptionalField(VersionAdded = 2)]
- private bool m_isReadOnly = false;
+ internal const int DaysTo10000 = DaysPer400Years * 25 - 366;
+
+ internal const long MaxMillis = (long)DaysTo10000 * MillisPerDay;
+
+ private int _currentEraValue = -1;
+
+ [OptionalField(VersionAdded = 2)]
+ private bool _isReadOnly = false;
+
+#if CORECLR
+ internal const CalendarId CAL_HEBREW = CalendarId.HEBREW;
+ internal const CalendarId CAL_HIJRI = CalendarId.HIJRI;
+ internal const CalendarId CAL_JAPAN = CalendarId.JAPAN;
+ internal const CalendarId CAL_JULIAN = CalendarId.JULIAN;
+ internal const CalendarId CAL_TAIWAN = CalendarId.TAIWAN;
+ internal const CalendarId CAL_UMALQURA = CalendarId.UMALQURA;
+ internal const CalendarId CAL_PERSIAN = CalendarId.PERSIAN;
+#endif
// The minimum supported DateTime range for the calendar.
@@ -115,19 +93,27 @@ namespace System.Globalization {
}
}
+ public virtual CalendarAlgorithmType AlgorithmType
+ {
+ get
+ {
+ return CalendarAlgorithmType.Unknown;
+ }
+ }
-
-
- protected Calendar() {
+ protected Calendar()
+ {
//Do-nothing constructor.
}
///
// This can not be abstract, otherwise no one can create a subclass of Calendar.
//
- internal virtual int ID {
- get {
- return (-1);
+ internal virtual CalendarId ID
+ {
+ get
+ {
+ return CalendarId.UNINITIALIZED_VALUE;
}
}
@@ -135,21 +121,11 @@ namespace System.Globalization {
// Return the Base calendar ID for calendars that didn't have defined data in calendarData
//
- internal virtual int BaseCalendarID
+ internal virtual CalendarId BaseCalendarID
{
get { return ID; }
}
- // Returns the type of the calendar.
- //
- public virtual CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.Unknown;
- }
- }
-
////////////////////////////////////////////////////////////////////////
//
// IsReadOnly
@@ -159,7 +135,7 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
public bool IsReadOnly
{
- get { return (m_isReadOnly); }
+ get { return (_isReadOnly); }
}
////////////////////////////////////////////////////////////////////////
@@ -169,13 +145,13 @@ namespace System.Globalization {
// Is the implementation of ICloneable.
//
////////////////////////////////////////////////////////////////////////
- public virtual Object Clone()
+ public virtual object Clone()
{
object o = MemberwiseClone();
- ((Calendar) o).SetReadOnlyState(false);
+ ((Calendar)o).SetReadOnlyState(false);
return (o);
}
-
+
////////////////////////////////////////////////////////////////////////
//
// ReadOnly
@@ -184,29 +160,29 @@ namespace System.Globalization {
// readonly.
//
////////////////////////////////////////////////////////////////////////
- public static Calendar ReadOnly(Calendar calendar)
+ public static Calendar ReadOnly(Calendar calendar)
{
- if (calendar == null) { throw new ArgumentNullException(nameof(calendar)); }
+ if (calendar == null) { throw new ArgumentNullException(nameof(calendar)); }
Contract.EndContractBlock();
- if (calendar.IsReadOnly) { return (calendar); }
-
+ if (calendar.IsReadOnly) { return (calendar); }
+
Calendar clonedCalendar = (Calendar)(calendar.MemberwiseClone());
clonedCalendar.SetReadOnlyState(true);
-
+
return (clonedCalendar);
}
internal void VerifyWritable()
{
- if (m_isReadOnly)
+ if (_isReadOnly)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
}
internal void SetReadOnlyState(bool readOnly)
{
- m_isReadOnly = readOnly;
+ _isReadOnly = readOnly;
}
@@ -219,14 +195,17 @@ namespace System.Globalization {
** The value is from calendar.nlp.
============================================================================*/
- internal virtual int CurrentEraValue {
- get {
+ internal virtual int CurrentEraValue
+ {
+ get
+ {
// The following code assumes that the current era value can not be -1.
- if (m_currentEraValue == -1) {
- Debug.Assert(BaseCalendarID > 0, "[Calendar.CurrentEraValue] Expected ID > 0");
- m_currentEraValue = CalendarData.GetCalendarData(BaseCalendarID).iCurrentEra;
+ if (_currentEraValue == -1)
+ {
+ Debug.Assert(BaseCalendarID != CalendarId.UNINITIALIZED_VALUE, "[Calendar.CurrentEraValue] Expected a real calendar ID");
+ _currentEraValue = CalendarData.GetCalendarData(BaseCalendarID).iCurrentEra;
}
- return (m_currentEraValue);
+ return (_currentEraValue);
}
}
@@ -236,16 +215,19 @@ namespace System.Globalization {
internal int twoDigitYearMax = -1;
- internal static void CheckAddResult(long ticks, DateTime minValue, DateTime maxValue) {
- if (ticks < minValue.Ticks || ticks > maxValue.Ticks) {
+ internal static void CheckAddResult(long ticks, DateTime minValue, DateTime maxValue)
+ {
+ if (ticks < minValue.Ticks || ticks > maxValue.Ticks)
+ {
throw new ArgumentException(
- String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("Argument_ResultCalendarRange"),
- minValue, maxValue));
+ String.Format(CultureInfo.InvariantCulture, SR.Format(SR.Argument_ResultCalendarRange,
+ minValue, maxValue)));
}
Contract.EndContractBlock();
}
- internal DateTime Add(DateTime time, double value, int scale) {
+ internal DateTime Add(DateTime time, double value, int scale)
+ {
// From ECMA CLI spec, Partition III, section 3.27:
//
// If overflow occurs converting a floating-point type to an integer, or if the floating-point value
@@ -256,7 +238,7 @@ namespace System.Globalization {
double tempMillis = (value * scale + (value >= 0 ? 0.5 : -0.5));
if (!((tempMillis > -(double)MaxMillis) && (tempMillis < (double)MaxMillis)))
{
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_AddValue"));
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_AddValue);
}
long millis = (long)tempMillis;
@@ -272,7 +254,8 @@ namespace System.Globalization {
// argument is permitted to be negative.
//
- public virtual DateTime AddMilliseconds(DateTime time, double milliseconds) {
+ public virtual DateTime AddMilliseconds(DateTime time, double milliseconds)
+ {
return (Add(time, milliseconds, 1));
}
@@ -284,7 +267,8 @@ namespace System.Globalization {
// value argument is permitted to be negative.
//
- public virtual DateTime AddDays(DateTime time, int days) {
+ public virtual DateTime AddDays(DateTime time, int days)
+ {
return (Add(time, days, MillisPerDay));
}
@@ -295,7 +279,8 @@ namespace System.Globalization {
// value argument is permitted to be negative.
//
- public virtual DateTime AddHours(DateTime time, int hours) {
+ public virtual DateTime AddHours(DateTime time, int hours)
+ {
return (Add(time, hours, MillisPerHour));
}
@@ -307,7 +292,8 @@ namespace System.Globalization {
// value argument is permitted to be negative.
//
- public virtual DateTime AddMinutes(DateTime time, int minutes) {
+ public virtual DateTime AddMinutes(DateTime time, int minutes)
+ {
return (Add(time, minutes, MillisPerMinute));
}
@@ -339,7 +325,8 @@ namespace System.Globalization {
// value argument is permitted to be negative.
//
- public virtual DateTime AddSeconds(DateTime time, int seconds) {
+ public virtual DateTime AddSeconds(DateTime time, int seconds)
+ {
return Add(time, seconds, MillisPerSecond);
}
@@ -348,7 +335,8 @@ namespace System.Globalization {
// value argument is permitted to be negative.
//
- public virtual DateTime AddWeeks(DateTime time, int weeks) {
+ public virtual DateTime AddWeeks(DateTime time, int weeks)
+ {
return (AddDays(time, weeks * 7));
}
@@ -425,7 +413,8 @@ namespace System.Globalization {
============================================================================*/
- public abstract int[] Eras {
+ public abstract int[] Eras
+ {
get;
}
@@ -434,7 +423,8 @@ namespace System.Globalization {
// integer between 0 and 23.
//
- public virtual int GetHour(DateTime time) {
+ public virtual int GetHour(DateTime time)
+ {
return ((int)((time.Ticks / TicksPerHour) % 24));
}
@@ -442,7 +432,8 @@ namespace System.Globalization {
// is an integer between 0 and 999.
//
- public virtual double GetMilliseconds(DateTime time) {
+ public virtual double GetMilliseconds(DateTime time)
+ {
return (double)((time.Ticks / TicksPerMillisecond) % 1000);
}
@@ -450,7 +441,8 @@ namespace System.Globalization {
// an integer between 0 and 59.
//
- public virtual int GetMinute(DateTime time) {
+ public virtual int GetMinute(DateTime time)
+ {
return ((int)((time.Ticks / TicksPerMinute) % 60));
}
@@ -475,7 +467,8 @@ namespace System.Globalization {
// an integer between 0 and 59.
//
- public virtual int GetSecond(DateTime time) {
+ public virtual int GetSecond(DateTime time)
+ {
return ((int)((time.Ticks / TicksPerSecond) % 60));
}
@@ -516,7 +509,8 @@ namespace System.Globalization {
** So Week of year = (GetDayOfYear(time) + offset - 1) / 7 + 1
============================================================================*/
- internal int GetFirstDayWeekOfYear(DateTime time, int firstDayOfWeek) {
+ internal int GetFirstDayWeekOfYear(DateTime time, int firstDayOfWeek)
+ {
int dayOfYear = GetDayOfYear(time) - 1; // Make the day of year to be 0-based, so that 1/1 is day 0.
// Calculate the day of week for the first day of the year.
// dayOfWeek - (dayOfYear % 7) is the day of week for the first day of this year. Note that
@@ -527,7 +521,8 @@ namespace System.Globalization {
return ((dayOfYear + offset) / 7 + 1);
}
- private int GetWeekOfYearFullDays(DateTime time, int firstDayOfWeek, int fullDays) {
+ private int GetWeekOfYearFullDays(DateTime time, int firstDayOfWeek, int fullDays)
+ {
int dayForJan1;
int offset;
int day;
@@ -576,11 +571,12 @@ namespace System.Globalization {
// Calculate the day of year for specified time by taking offset into account.
//
day = dayOfYear - offset;
- if (day >= 0) {
+ if (day >= 0)
+ {
//
// If the day of year value is greater than zero, get the week of year.
//
- return (day/7 + 1);
+ return (day / 7 + 1);
}
//
// Otherwise, the specified time falls on the week of previous year.
@@ -643,13 +639,15 @@ namespace System.Globalization {
public virtual int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
{
- if ((int)firstDayOfWeek < 0 || (int)firstDayOfWeek > 6) {
+ if ((int)firstDayOfWeek < 0 || (int)firstDayOfWeek > 6)
+ {
throw new ArgumentOutOfRangeException(
- nameof(firstDayOfWeek), Environment.GetResourceString("ArgumentOutOfRange_Range",
+ nameof(firstDayOfWeek), SR.Format(SR.ArgumentOutOfRange_Range,
DayOfWeek.Sunday, DayOfWeek.Saturday));
}
Contract.EndContractBlock();
- switch (rule) {
+ switch (rule)
+ {
case CalendarWeekRule.FirstDay:
return (GetFirstDayWeekOfYear(time, (int)firstDayOfWeek));
case CalendarWeekRule.FirstFullWeek:
@@ -658,9 +656,8 @@ namespace System.Globalization {
return (GetWeekOfYearFullDays(time, (int)firstDayOfWeek, 4));
}
throw new ArgumentOutOfRangeException(
- nameof(rule), Environment.GetResourceString("ArgumentOutOfRange_Range",
+ nameof(rule), SR.Format(SR.ArgumentOutOfRange_Range,
CalendarWeekRule.FirstDay, CalendarWeekRule.FirstFourDayWeek));
-
}
// Returns the year part of the specified DateTime. The returned value is an
@@ -688,7 +685,8 @@ namespace System.Globalization {
// month is a leap month, or false if not.
//
- public virtual bool IsLeapMonth(int year, int month) {
+ public virtual bool IsLeapMonth(int year, int month)
+ {
return (IsLeapMonth(year, month, CurrentEra));
}
@@ -717,7 +715,7 @@ namespace System.Globalization {
return 0;
int monthsCount = GetMonthsInYear(year, era);
- for (int month=1; month<=monthsCount; month++)
+ for (int month = 1; month <= monthsCount; month++)
{
if (IsLeapMonth(year, month, era))
return month;
@@ -744,7 +742,7 @@ namespace System.Globalization {
// Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
//
- public virtual DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond)
+ public virtual DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond)
{
return (ToDateTime(year, month, day, hour, minute, second, millisecond, CurrentEra));
}
@@ -754,30 +752,35 @@ namespace System.Globalization {
public abstract DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era);
- internal virtual Boolean TryToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era, out DateTime result) {
+ internal virtual Boolean TryToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era, out DateTime result)
+ {
result = DateTime.MinValue;
- try {
+ try
+ {
result = ToDateTime(year, month, day, hour, minute, second, millisecond, era);
return true;
}
- catch (ArgumentException) {
+ catch (ArgumentException)
+ {
return false;
}
}
-
- internal virtual bool IsValidYear(int year, int era) {
+
+ internal virtual bool IsValidYear(int year, int era)
+ {
return (year >= GetYear(MinSupportedDateTime) && year <= GetYear(MaxSupportedDateTime));
}
-
- internal virtual bool IsValidMonth(int year, int month, int era) {
+
+ internal virtual bool IsValidMonth(int year, int month, int era)
+ {
return (IsValidYear(year, era) && month >= 1 && month <= GetMonthsInYear(year, era));
}
-
+
internal virtual bool IsValidDay(int year, int month, int day, int era)
{
return (IsValidMonth(year, month, era) && day >= 1 && day <= GetDaysInMonth(year, month, era));
}
-
+
// Returns and assigns the maximum value to represent a two digit year. This
// value is the upper boundary of a 100 year range that allows a two digit year
@@ -805,14 +808,17 @@ namespace System.Globalization {
// then a two digit value of 30 will get converted to 1930 while a two digit
// value of 29 will get converted to 2029.
- public virtual int ToFourDigitYear(int year) {
- if (year < 0) {
+ public virtual int ToFourDigitYear(int year)
+ {
+ if (year < 0)
+ {
throw new ArgumentOutOfRangeException(nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
- if (year < 100) {
- return ((TwoDigitYearMax/100 - ( year > TwoDigitYearMax % 100 ? 1 : 0))*100 + year);
+ if (year < 100)
+ {
+ return ((TwoDigitYearMax / 100 - (year > TwoDigitYearMax % 100 ? 1 : 0)) * 100 + year);
}
// If the year value is above 100, just return the year value. Don't have to do
// the TwoDigitYearMax comparison.
@@ -823,30 +829,29 @@ namespace System.Globalization {
// Will check the if the parameters are valid.
internal static long TimeToTicks(int hour, int minute, int second, int millisecond)
{
- if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >=0 && second < 60)
+ if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >= 0 && second < 60)
{
- if (millisecond < 0 || millisecond >= MillisPerSecond) {
+ if (millisecond < 0 || millisecond >= MillisPerSecond)
+ {
throw new ArgumentOutOfRangeException(
nameof(millisecond),
String.Format(
CultureInfo.InvariantCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"), 0, MillisPerSecond - 1));
+ SR.Format(SR.ArgumentOutOfRange_Range, 0, MillisPerSecond - 1)));
}
- return TimeSpan.TimeToTicks(hour, minute, second) + millisecond * TicksPerMillisecond;
+ return InternalGlobalizationHelper.TimeToTicks(hour, minute, second) + millisecond * TicksPerMillisecond;
}
- throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadHourMinuteSecond"));
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
}
- internal static int GetSystemTwoDigitYearSetting(int CalID, int defaultYearValue)
+ internal static int GetSystemTwoDigitYearSetting(CalendarId CalID, int defaultYearValue)
{
- // Call nativeGetTwoDigitYearMax
- int twoDigitYearMax = CalendarData.nativeGetTwoDigitYearMax(CalID);
+ int twoDigitYearMax = CalendarData.GetTwoDigitYearMax(CalID);
if (twoDigitYearMax < 0)
{
twoDigitYearMax = defaultYearValue;
}
return (twoDigitYearMax);
}
-
}
}
diff --git a/src/mscorlib/src/System/Globalization/CalendarAlgorithmType.cs b/src/mscorlib/src/System/Globalization/CalendarAlgorithmType.cs
deleted file mode 100644
index 33b5035a8d..0000000000
--- a/src/mscorlib/src/System/Globalization/CalendarAlgorithmType.cs
+++ /dev/null
@@ -1,19 +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.
-
-namespace System.Globalization {
- using System;
-
- public enum CalendarAlgorithmType {
- Unknown = 0, // This is the default value to return in the Calendar base class.
- SolarCalendar = 1, // Solar-base calendar, such as GregorianCalendar, jaoaneseCalendar, JulianCalendar, etc.
- // Solar calendars are based on the solar year and seasons.
- LunarCalendar = 2, // Lunar-based calendar, such as Hijri and UmAlQuraCalendar.
- // Lunar calendars are based on the path of the moon. The seasons are not accurately represented.
- LunisolarCalendar = 3 // Lunisolar-based calendar which use leap month rule, such as HebrewCalendar and Asian Lunisolar calendars.
- // Lunisolar calendars are based on the cycle of the moon, but consider the seasons as a secondary consideration,
- // so they align with the seasons as well as lunar events.
-
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/CalendarData.Unix.cs b/src/mscorlib/src/System/Globalization/CalendarData.Unix.cs
new file mode 100644
index 0000000000..319f66ae8c
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/CalendarData.Unix.cs
@@ -0,0 +1,339 @@
+// 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.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Text;
+
+namespace System.Globalization
+{
+ // needs to be kept in sync with CalendarDataType in System.Globalization.Native
+ internal enum CalendarDataType
+ {
+ Uninitialized = 0,
+ NativeName = 1,
+ MonthDay = 2,
+ ShortDates = 3,
+ LongDates = 4,
+ YearMonths = 5,
+ DayNames = 6,
+ AbbrevDayNames = 7,
+ MonthNames = 8,
+ AbbrevMonthNames = 9,
+ SuperShortDayNames = 10,
+ MonthGenitiveNames = 11,
+ AbbrevMonthGenitiveNames = 12,
+ EraNames = 13,
+ AbbrevEraNames = 14,
+ }
+
+ internal partial class CalendarData
+ {
+ private bool LoadCalendarDataFromSystem(String localeName, CalendarId calendarId)
+ {
+ bool result = true;
+ result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.NativeName, out this.sNativeName);
+ result &= GetCalendarInfo(localeName, calendarId, CalendarDataType.MonthDay, out this.sMonthDay);
+ this.sMonthDay = NormalizeDatePattern(this.sMonthDay);
+
+ result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.ShortDates, out this.saShortDates);
+ result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.LongDates, out this.saLongDates);
+ result &= EnumDatePatterns(localeName, calendarId, CalendarDataType.YearMonths, out this.saYearMonths);
+ result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.DayNames, out this.saDayNames);
+ result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.AbbrevDayNames, out this.saAbbrevDayNames);
+ result &= EnumCalendarInfo(localeName, calendarId, CalendarDataType.SuperShortDayNames, out this.saSuperShortDayNames);
+ result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthNames, out this.saMonthNames);
+ result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthNames, out this.saAbbrevMonthNames);
+ result &= EnumMonthNames(localeName, calendarId, CalendarDataType.MonthGenitiveNames, out this.saMonthGenitiveNames);
+ result &= EnumMonthNames(localeName, calendarId, CalendarDataType.AbbrevMonthGenitiveNames, out this.saAbbrevMonthGenitiveNames);
+ result &= EnumEraNames(localeName, calendarId, CalendarDataType.EraNames, out this.saEraNames);
+ result &= EnumEraNames(localeName, calendarId, CalendarDataType.AbbrevEraNames, out this.saAbbrevEraNames);
+
+ return result;
+ }
+
+ internal static int GetTwoDigitYearMax(CalendarId calendarId)
+ {
+ // There is no user override for this value on Linux or in ICU.
+ // So just return -1 to use the hard-coded defaults.
+ return -1;
+ }
+
+ // Call native side to figure out which calendars are allowed
+ internal static int GetCalendars(string localeName, bool useUserOverride, CalendarId[] calendars)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ // NOTE: there are no 'user overrides' on Linux
+ int count = Interop.GlobalizationInterop.GetCalendars(localeName, calendars, calendars.Length);
+
+ // ensure there is at least 1 calendar returned
+ if (count == 0 && calendars.Length > 0)
+ {
+ calendars[0] = CalendarId.GREGORIAN;
+ count = 1;
+ }
+
+ return count;
+ }
+
+ private static bool SystemSupportsTaiwaneseCalendar()
+ {
+ return true;
+ }
+
+ // PAL Layer ends here
+
+ private static bool GetCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string calendarString)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ return Interop.CallStringMethod(
+ (locale, calId, type, stringBuilder) =>
+ Interop.GlobalizationInterop.GetCalendarInfo(
+ locale,
+ calId,
+ type,
+ stringBuilder,
+ stringBuilder.Capacity),
+ localeName,
+ calendarId,
+ dataType,
+ out calendarString);
+ }
+
+ private static bool EnumDatePatterns(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] datePatterns)
+ {
+ datePatterns = null;
+
+ CallbackContext callbackContext = new CallbackContext();
+ callbackContext.DisallowDuplicates = true;
+ bool result = EnumCalendarInfo(localeName, calendarId, dataType, callbackContext);
+ if (result)
+ {
+ List<string> datePatternsList = callbackContext.Results;
+
+ datePatterns = new string[datePatternsList.Count];
+ for (int i = 0; i < datePatternsList.Count; i++)
+ {
+ datePatterns[i] = NormalizeDatePattern(datePatternsList[i]);
+ }
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// The ICU date format characters are not exactly the same as the .NET date format characters.
+ /// NormalizeDatePattern will take in an ICU date pattern and return the equivalent .NET date pattern.
+ /// </summary>
+ /// <remarks>
+ /// see Date Field Symbol Table in http://userguide.icu-project.org/formatparse/datetime
+ /// and https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx
+ /// </remarks>
+ private static string NormalizeDatePattern(string input)
+ {
+ StringBuilder destination = StringBuilderCache.Acquire(input.Length);
+
+ int index = 0;
+ while (index < input.Length)
+ {
+ switch (input[index])
+ {
+ case '\'':
+ // single quotes escape characters, like 'de' in es-SP
+ // so read verbatim until the next single quote
+ destination.Append(input[index++]);
+ while (index < input.Length)
+ {
+ char current = input[index++];
+ destination.Append(current);
+ if (current == '\'')
+ {
+ break;
+ }
+ }
+ break;
+ case 'E':
+ case 'e':
+ case 'c':
+ // 'E' in ICU is the day of the week, which maps to 3 or 4 'd's in .NET
+ // 'e' in ICU is the local day of the week, which has no representation in .NET, but
+ // maps closest to 3 or 4 'd's in .NET
+ // 'c' in ICU is the stand-alone day of the week, which has no representation in .NET, but
+ // maps closest to 3 or 4 'd's in .NET
+ NormalizeDayOfWeek(input, destination, ref index);
+ break;
+ case 'L':
+ case 'M':
+ // 'L' in ICU is the stand-alone name of the month,
+ // which maps closest to 'M' in .NET since it doesn't support stand-alone month names in patterns
+ // 'M' in both ICU and .NET is the month,
+ // but ICU supports 5 'M's, which is the super short month name
+ int occurrences = CountOccurrences(input, input[index], ref index);
+ if (occurrences > 4)
+ {
+ // 5 'L's or 'M's in ICU is the super short name, which maps closest to MMM in .NET
+ occurrences = 3;
+ }
+ destination.Append('M', occurrences);
+ break;
+ case 'G':
+ // 'G' in ICU is the era, which maps to 'g' in .NET
+ occurrences = CountOccurrences(input, 'G', ref index);
+
+ // it doesn't matter how many 'G's, since .NET only supports 'g' or 'gg', and they
+ // have the same meaning
+ destination.Append('g');
+ break;
+ case 'y':
+ // a single 'y' in ICU is the year with no padding or trimming.
+ // a single 'y' in .NET is the year with 1 or 2 digits
+ // so convert any single 'y' to 'yyyy'
+ occurrences = CountOccurrences(input, 'y', ref index);
+ if (occurrences == 1)
+ {
+ occurrences = 4;
+ }
+ destination.Append('y', occurrences);
+ break;
+ default:
+ const string unsupportedDateFieldSymbols = "YuUrQqwWDFg";
+ Debug.Assert(unsupportedDateFieldSymbols.IndexOf(input[index]) == -1,
+ string.Format(CultureInfo.InvariantCulture,
+ "Encountered an unexpected date field symbol '{0}' from ICU which has no known corresponding .NET equivalent.",
+ input[index]));
+
+ destination.Append(input[index++]);
+ break;
+ }
+ }
+
+ return StringBuilderCache.GetStringAndRelease(destination);
+ }
+
+ private static void NormalizeDayOfWeek(string input, StringBuilder destination, ref int index)
+ {
+ char dayChar = input[index];
+ int occurrences = CountOccurrences(input, dayChar, ref index);
+ occurrences = Math.Max(occurrences, 3);
+ if (occurrences > 4)
+ {
+ // 5 and 6 E/e/c characters in ICU is the super short names, which maps closest to ddd in .NET
+ occurrences = 3;
+ }
+
+ destination.Append('d', occurrences);
+ }
+
+ private static int CountOccurrences(string input, char value, ref int index)
+ {
+ int startIndex = index;
+ while (index < input.Length && input[index] == value)
+ {
+ index++;
+ }
+
+ return index - startIndex;
+ }
+
+ private static bool EnumMonthNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] monthNames)
+ {
+ monthNames = null;
+
+ CallbackContext callbackContext = new CallbackContext();
+ bool result = EnumCalendarInfo(localeName, calendarId, dataType, callbackContext);
+ if (result)
+ {
+ // the month-name arrays are expected to have 13 elements. If ICU only returns 12, add an
+ // extra empty string to fill the array.
+ if (callbackContext.Results.Count == 12)
+ {
+ callbackContext.Results.Add(string.Empty);
+ }
+
+ monthNames = callbackContext.Results.ToArray();
+ }
+
+ return result;
+ }
+
+ private static bool EnumEraNames(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] eraNames)
+ {
+ bool result = EnumCalendarInfo(localeName, calendarId, dataType, out eraNames);
+
+ // .NET expects that only the Japanese calendars have more than 1 era.
+ // So for other calendars, only return the latest era.
+ if (calendarId != CalendarId.JAPAN && calendarId != CalendarId.JAPANESELUNISOLAR && eraNames.Length > 0)
+ {
+ string[] latestEraName = new string[] { eraNames[eraNames.Length - 1] };
+ eraNames = latestEraName;
+ }
+
+ return result;
+ }
+
+ internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, out string[] calendarData)
+ {
+ calendarData = null;
+
+ CallbackContext callbackContext = new CallbackContext();
+ bool result = EnumCalendarInfo(localeName, calendarId, dataType, callbackContext);
+ if (result)
+ {
+ calendarData = callbackContext.Results.ToArray();
+ }
+
+ return result;
+ }
+
+ private static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, CallbackContext callbackContext)
+ {
+ GCHandle context = GCHandle.Alloc(callbackContext);
+ try
+ {
+ return Interop.GlobalizationInterop.EnumCalendarInfo(EnumCalendarInfoCallback, localeName, calendarId, dataType, (IntPtr)context);
+ }
+ finally
+ {
+ context.Free();
+ }
+ }
+
+ private static void EnumCalendarInfoCallback(string calendarString, IntPtr context)
+ {
+ CallbackContext callbackContext = (CallbackContext)((GCHandle)context).Target;
+
+ if (callbackContext.DisallowDuplicates)
+ {
+ foreach (string existingResult in callbackContext.Results)
+ {
+ if (string.Equals(calendarString, existingResult, StringComparison.Ordinal))
+ {
+ // the value is already in the results, so don't add it again
+ return;
+ }
+ }
+ }
+
+ callbackContext.Results.Add(calendarString);
+ }
+
+ private class CallbackContext
+ {
+ private List<string> _results = new List<string>();
+
+ public CallbackContext()
+ {
+ }
+
+ public List<string> Results { get { return _results; } }
+
+ public bool DisallowDuplicates { get; set; }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/CalendarData.Windows.cs b/src/mscorlib/src/System/Globalization/CalendarData.Windows.cs
new file mode 100644
index 0000000000..51a2727c7d
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/CalendarData.Windows.cs
@@ -0,0 +1,502 @@
+// 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.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.Contracts;
+using System.Collections.Generic;
+
+namespace System.Globalization
+{
+#if CORECLR
+ using IntList = List<int>;
+ using StringList = List<string>;
+#else
+ using IntList = LowLevelList<int>;
+ using StringList = LowLevelList<string>;
+#endif
+
+ internal partial class CalendarData
+ {
+ private bool LoadCalendarDataFromSystem(String localeName, CalendarId calendarId)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ bool ret = true;
+
+ uint useOverrides = this.bUseUserOverrides ? 0 : CAL_NOUSEROVERRIDE;
+
+ //
+ // Windows doesn't support some calendars right now, so remap those.
+ //
+ switch (calendarId)
+ {
+ case CalendarId.JAPANESELUNISOLAR: // Data looks like Japanese
+ calendarId = CalendarId.JAPAN;
+ break;
+ case CalendarId.JULIAN: // Data looks like gregorian US
+ case CalendarId.CHINESELUNISOLAR: // Algorithmic, so actual data is irrelevent
+ case CalendarId.SAKA: // reserved to match Office but not implemented in our code, so data is irrelevent
+ case CalendarId.LUNAR_ETO_CHN: // reserved to match Office but not implemented in our code, so data is irrelevent
+ case CalendarId.LUNAR_ETO_KOR: // reserved to match Office but not implemented in our code, so data is irrelevent
+ case CalendarId.LUNAR_ETO_ROKUYOU: // reserved to match Office but not implemented in our code, so data is irrelevent
+ case CalendarId.KOREANLUNISOLAR: // Algorithmic, so actual data is irrelevent
+ case CalendarId.TAIWANLUNISOLAR: // Algorithmic, so actual data is irrelevent
+ calendarId = CalendarId.GREGORIAN_US;
+ break;
+ }
+
+ //
+ // Special handling for some special calendar due to OS limitation.
+ // This includes calendar like Taiwan calendar, UmAlQura calendar, etc.
+ //
+ CheckSpecialCalendar(ref calendarId, ref localeName);
+
+ // Numbers
+ ret &= CallGetCalendarInfoEx(localeName, calendarId, CAL_ITWODIGITYEARMAX | useOverrides, out this.iTwoDigitYearMax);
+
+ // Strings
+ ret &= CallGetCalendarInfoEx(localeName, calendarId, CAL_SCALNAME, out this.sNativeName);
+ ret &= CallGetCalendarInfoEx(localeName, calendarId, CAL_SMONTHDAY | useOverrides, out this.sMonthDay);
+
+ // String Arrays
+ // Formats
+ ret &= CallEnumCalendarInfo(localeName, calendarId, CAL_SSHORTDATE, LOCALE_SSHORTDATE | useOverrides, out this.saShortDates);
+ ret &= CallEnumCalendarInfo(localeName, calendarId, CAL_SLONGDATE, LOCALE_SLONGDATE | useOverrides, out this.saLongDates);
+
+ // Get the YearMonth pattern.
+ ret &= CallEnumCalendarInfo(localeName, calendarId, CAL_SYEARMONTH, LOCALE_SYEARMONTH, out this.saYearMonths);
+
+ // Day & Month Names
+ // These are all single calType entries, 1 per day, so we have to make 7 or 13 calls to collect all the names
+
+ // Day
+ // Note that we're off-by-one since managed starts on sunday and windows starts on monday
+ ret &= GetCalendarDayInfo(localeName, calendarId, CAL_SDAYNAME7, out this.saDayNames);
+ ret &= GetCalendarDayInfo(localeName, calendarId, CAL_SABBREVDAYNAME7, out this.saAbbrevDayNames);
+
+ // Month names
+ ret &= GetCalendarMonthInfo(localeName, calendarId, CAL_SMONTHNAME1, out this.saMonthNames);
+ ret &= GetCalendarMonthInfo(localeName, calendarId, CAL_SABBREVMONTHNAME1, out this.saAbbrevMonthNames);
+
+ //
+ // The following LCTYPE are not supported in some platforms. If the call fails,
+ // don't return a failure.
+ //
+ GetCalendarDayInfo(localeName, calendarId, CAL_SSHORTESTDAYNAME7, out this.saSuperShortDayNames);
+
+ // Gregorian may have genitive month names
+ if (calendarId == CalendarId.GREGORIAN)
+ {
+ GetCalendarMonthInfo(localeName, calendarId, CAL_SMONTHNAME1 | CAL_RETURN_GENITIVE_NAMES, out this.saMonthGenitiveNames);
+ GetCalendarMonthInfo(localeName, calendarId, CAL_SABBREVMONTHNAME1 | CAL_RETURN_GENITIVE_NAMES, out this.saAbbrevMonthGenitiveNames);
+ }
+
+ // Calendar Parts Names
+ // This doesn't get always get localized names for gregorian (not available in windows < 7)
+ // so: eg: coreclr on win < 7 won't get these
+ CallEnumCalendarInfo(localeName, calendarId, CAL_SERASTRING, 0, out this.saEraNames);
+ CallEnumCalendarInfo(localeName, calendarId, CAL_SABBREVERASTRING, 0, out this.saAbbrevEraNames);
+
+ //
+ // Calendar Era Info
+ // Note that calendar era data (offsets, etc) is hard coded for each calendar since this
+ // data is implementation specific and not dynamic (except perhaps Japanese)
+ //
+
+ // Clean up the escaping of the formats
+ this.saShortDates = CultureData.ReescapeWin32Strings(this.saShortDates);
+ this.saLongDates = CultureData.ReescapeWin32Strings(this.saLongDates);
+ this.saYearMonths = CultureData.ReescapeWin32Strings(this.saYearMonths);
+ this.sMonthDay = CultureData.ReescapeWin32String(this.sMonthDay);
+
+ return ret;
+ }
+
+ // Get native two digit year max
+ internal static int GetTwoDigitYearMax(CalendarId calendarId)
+ {
+ if (GlobalizationMode.Invariant)
+ {
+ return Invariant.iTwoDigitYearMax;
+ }
+
+ int twoDigitYearMax = -1;
+
+ if (!CallGetCalendarInfoEx(null, calendarId, (uint)CAL_ITWODIGITYEARMAX, out twoDigitYearMax))
+ {
+ twoDigitYearMax = -1;
+ }
+
+ return twoDigitYearMax;
+ }
+
+ // Call native side to figure out which calendars are allowed
+ internal static int GetCalendars(String localeName, bool useUserOverride, CalendarId[] calendars)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ EnumCalendarsData data = new EnumCalendarsData();
+ data.userOverride = 0;
+ data.calendars = new IntList();
+
+ // First call GetLocaleInfo if necessary
+ if (useUserOverride)
+ {
+ // They want user overrides, see if the user calendar matches the input calendar
+ int userCalendar = CultureData.GetLocaleInfoExInt(localeName, LOCALE_ICALENDARTYPE);
+
+ // If we got a default, then use it as the first calendar
+ if (userCalendar != 0)
+ {
+ data.userOverride = userCalendar;
+ data.calendars.Add(userCalendar);
+ }
+ }
+
+ GCHandle contextHandle = GCHandle.Alloc(data);
+ try
+ {
+ // Now call the enumeration API. Work is done by our callback function
+#if CORECLR
+ Interop.Kernel32.EnumCalendarInfoExEx(EnumCalendarsCallback, localeName, ENUM_ALL_CALENDARS, null, CAL_ICALINTVALUE, (IntPtr)contextHandle);
+#else
+ IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, uint, IntPtr, IntPtr, Interop.BOOL>>(EnumCalendarsCallback);
+ Interop.Kernel32.EnumCalendarInfoExEx(callback, localeName, ENUM_ALL_CALENDARS, null, CAL_ICALINTVALUE, (IntPtr)contextHandle);
+#endif
+ }
+ finally
+ {
+ contextHandle.Free();
+ }
+
+ // Copy to the output array
+ for (int i = 0; i < Math.Min(calendars.Length, data.calendars.Count); i++)
+ calendars[i] = (CalendarId)data.calendars[i];
+
+ // Now we have a list of data, return the count
+ return data.calendars.Count;
+ }
+
+ private static bool SystemSupportsTaiwaneseCalendar()
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ string data;
+ // Taiwanese calendar get listed as one of the optional zh-TW calendars only when having zh-TW UI
+ return CallGetCalendarInfoEx("zh-TW", CalendarId.TAIWAN, CAL_SCALNAME, out data);
+ }
+
+ // PAL Layer ends here
+
+ private const uint CAL_RETURN_NUMBER = 0x20000000;
+ private const uint CAL_RETURN_GENITIVE_NAMES = 0x10000000;
+ private const uint CAL_NOUSEROVERRIDE = 0x80000000;
+ private const uint CAL_SCALNAME = 0x00000002;
+ private const uint CAL_SMONTHDAY = 0x00000038;
+ private const uint CAL_SSHORTDATE = 0x00000005;
+ private const uint CAL_SLONGDATE = 0x00000006;
+ private const uint CAL_SYEARMONTH = 0x0000002f;
+ private const uint CAL_SDAYNAME7 = 0x0000000d;
+ private const uint CAL_SABBREVDAYNAME7 = 0x00000014;
+ private const uint CAL_SMONTHNAME1 = 0x00000015;
+ private const uint CAL_SABBREVMONTHNAME1 = 0x00000022;
+ private const uint CAL_SSHORTESTDAYNAME7 = 0x00000037;
+ private const uint CAL_SERASTRING = 0x00000004;
+ private const uint CAL_SABBREVERASTRING = 0x00000039;
+ private const uint CAL_ICALINTVALUE = 0x00000001;
+ private const uint CAL_ITWODIGITYEARMAX = 0x00000030;
+
+ private const uint ENUM_ALL_CALENDARS = 0xffffffff;
+
+ private const uint LOCALE_SSHORTDATE = 0x0000001F;
+ private const uint LOCALE_SLONGDATE = 0x00000020;
+ private const uint LOCALE_SYEARMONTH = 0x00001006;
+ private const uint LOCALE_ICALENDARTYPE = 0x00001009;
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // For calendars like Gregorain US/Taiwan/UmAlQura, they are not available
+ // in all OS or all localized versions of OS.
+ // If OS does not support these calendars, we will fallback by using the
+ // appropriate fallback calendar and locale combination to retrieve data from OS.
+ //
+ // Parameters:
+ // __deref_inout pCalendarInt:
+ // Pointer to the calendar ID. This will be updated to new fallback calendar ID if needed.
+ // __in_out pLocaleNameStackBuffer
+ // Pointer to the StackSString object which holds the locale name to be checked.
+ // This will be updated to new fallback locale name if needed.
+ //
+ ////////////////////////////////////////////////////////////////////////
+ private static void CheckSpecialCalendar(ref CalendarId calendar, ref string localeName)
+ {
+ string data;
+
+ // Gregorian-US isn't always available in the OS, however it is the same for all locales
+ switch (calendar)
+ {
+ case CalendarId.GREGORIAN_US:
+ // See if this works
+ if (!CallGetCalendarInfoEx(localeName, calendar, CAL_SCALNAME, out data))
+ {
+ // Failed, set it to a locale (fa-IR) that's alway has Gregorian US available in the OS
+ localeName = "fa-IR";
+ }
+ // See if that works
+ if (!CallGetCalendarInfoEx(localeName, calendar, CAL_SCALNAME, out data))
+ {
+ // Failed again, just use en-US with the gregorian calendar
+ localeName = "en-US";
+ calendar = CalendarId.GREGORIAN;
+ }
+ break;
+ case CalendarId.TAIWAN:
+ // Taiwan calendar data is not always in all language version of OS due to Geopolical reasons.
+ // It is only available in zh-TW localized versions of Windows.
+ // Let's check if OS supports it. If not, fallback to Greogrian localized for Taiwan calendar.
+ if (!SystemSupportsTaiwaneseCalendar())
+ {
+ calendar = CalendarId.GREGORIAN;
+ }
+ break;
+ }
+ }
+
+ private static bool CallGetCalendarInfoEx(string localeName, CalendarId calendar, uint calType, out int data)
+ {
+ return (Interop.Kernel32.GetCalendarInfoEx(localeName, (uint)calendar, IntPtr.Zero, calType | CAL_RETURN_NUMBER, IntPtr.Zero, 0, out data) != 0);
+ }
+
+ private static unsafe bool CallGetCalendarInfoEx(string localeName, CalendarId calendar, uint calType, out string data)
+ {
+ const int BUFFER_LENGTH = 80;
+
+ // The maximum size for values returned from GetCalendarInfoEx is 80 characters.
+ char* buffer = stackalloc char[BUFFER_LENGTH];
+
+ int ret = Interop.Kernel32.GetCalendarInfoEx(localeName, (uint)calendar, IntPtr.Zero, calType, (IntPtr)buffer, BUFFER_LENGTH, IntPtr.Zero);
+ if (ret > 0)
+ {
+ if (buffer[ret - 1] == '\0')
+ {
+ ret--; // don't include the null termination in the string
+ }
+ data = new string(buffer, 0, ret);
+ return true;
+ }
+ data = "";
+ return false;
+ }
+
+ // Context for EnumCalendarInfoExEx callback.
+ private class EnumData
+ {
+ public string userOverride;
+ public StringList strings;
+ }
+
+ // EnumCalendarInfoExEx callback itself.
+#if !CORECLR
+ [NativeCallable(CallingConvention = CallingConvention.StdCall)]
+#endif
+ private static unsafe Interop.BOOL EnumCalendarInfoCallback(IntPtr lpCalendarInfoString, uint calendar, IntPtr pReserved, IntPtr lParam)
+ {
+ EnumData context = (EnumData)((GCHandle)lParam).Target;
+ try
+ {
+ string calendarInfo = new string((char*)lpCalendarInfoString);
+
+ // If we had a user override, check to make sure this differs
+ if (context.userOverride != calendarInfo)
+ context.strings.Add(calendarInfo);
+
+ return Interop.BOOL.TRUE;
+ }
+ catch (Exception)
+ {
+ return Interop.BOOL.FALSE;
+ }
+ }
+
+ private static unsafe bool CallEnumCalendarInfo(string localeName, CalendarId calendar, uint calType, uint lcType, out string[] data)
+ {
+ EnumData context = new EnumData();
+ context.userOverride = null;
+ context.strings = new StringList();
+ // First call GetLocaleInfo if necessary
+ if (((lcType != 0) && ((lcType & CAL_NOUSEROVERRIDE) == 0)) &&
+ // Get user locale, see if it matches localeName.
+ // Note that they should match exactly, including letter case
+ GetUserDefaultLocaleName() == localeName)
+ {
+ // They want user overrides, see if the user calendar matches the input calendar
+ CalendarId userCalendar = (CalendarId)CultureData.GetLocaleInfoExInt(localeName, LOCALE_ICALENDARTYPE);
+
+ // If the calendars were the same, see if the locales were the same
+ if (userCalendar == calendar)
+ {
+ // They matched, get the user override since locale & calendar match
+ string res = CultureData.GetLocaleInfoEx(localeName, lcType);
+
+ // if it succeeded remember the override for the later callers
+ if (res != "")
+ {
+ // Remember this was the override (so we can look for duplicates later in the enum function)
+ context.userOverride = res;
+
+ // Add to the result strings.
+ context.strings.Add(res);
+ }
+ }
+ }
+
+ GCHandle contextHandle = GCHandle.Alloc(context);
+ try
+ {
+#if CORECLR
+ Interop.Kernel32.EnumCalendarInfoExEx(EnumCalendarInfoCallback, localeName, (uint)calendar, null, calType, (IntPtr)contextHandle);
+#else
+ // Now call the enumeration API. Work is done by our callback function
+ IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, uint, IntPtr, IntPtr, Interop.BOOL>>(EnumCalendarInfoCallback);
+ Interop.Kernel32.EnumCalendarInfoExEx(callback, localeName, (uint)calendar, null, calType, (IntPtr)contextHandle);
+#endif // CORECLR
+ }
+ finally
+ {
+ contextHandle.Free();
+ }
+
+ // Now we have a list of data, fail if we didn't find anything.
+ if (context.strings.Count == 0)
+ {
+ data = null;
+ return false;
+ }
+
+ string[] output = context.strings.ToArray();
+
+ if (calType == CAL_SABBREVERASTRING || calType == CAL_SERASTRING)
+ {
+ // Eras are enumerated backwards. (oldest era name first, but
+ // Japanese calendar has newest era first in array, and is only
+ // calendar with multiple eras)
+ Array.Reverse(output, 0, output.Length);
+ }
+
+ data = output;
+
+ return true;
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Get the native day names
+ //
+ // NOTE: There's a disparity between .Net & windows day orders, the input day should
+ // start with Sunday
+ //
+ // Parameters:
+ // OUT pOutputStrings The output string[] value.
+ //
+ ////////////////////////////////////////////////////////////////////////
+ private static bool GetCalendarDayInfo(string localeName, CalendarId calendar, uint calType, out string[] outputStrings)
+ {
+ bool result = true;
+
+ //
+ // We'll need a new array of 7 items
+ //
+ string[] results = new string[7];
+
+ // Get each one of them
+ for (int i = 0; i < 7; i++, calType++)
+ {
+ result &= CallGetCalendarInfoEx(localeName, calendar, calType, out results[i]);
+
+ // On the first iteration we need to go from CAL_SDAYNAME7 to CAL_SDAYNAME1, so subtract 7 before the ++ happens
+ // This is because the framework starts on sunday and windows starts on monday when counting days
+ if (i == 0)
+ calType -= 7;
+ }
+
+ outputStrings = results;
+
+ return result;
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Get the native month names
+ //
+ // Parameters:
+ // OUT pOutputStrings The output string[] value.
+ //
+ ////////////////////////////////////////////////////////////////////////
+ private static bool GetCalendarMonthInfo(string localeName, CalendarId calendar, uint calType, out string[] outputStrings)
+ {
+ //
+ // We'll need a new array of 13 items
+ //
+ string[] results = new string[13];
+
+ // Get each one of them
+ for (int i = 0; i < 13; i++, calType++)
+ {
+ if (!CallGetCalendarInfoEx(localeName, calendar, calType, out results[i]))
+ results[i] = "";
+ }
+
+ outputStrings = results;
+
+ return true;
+ }
+
+ //
+ // struct to help our calendar data enumaration callback
+ //
+ private class EnumCalendarsData
+ {
+ public int userOverride; // user override value (if found)
+ public IntList calendars; // list of calendars found so far
+ }
+
+#if !CORECLR
+ [NativeCallable(CallingConvention = CallingConvention.StdCall)]
+#endif
+ private static Interop.BOOL EnumCalendarsCallback(IntPtr lpCalendarInfoString, uint calendar, IntPtr reserved, IntPtr lParam)
+ {
+ EnumCalendarsData context = (EnumCalendarsData)((GCHandle)lParam).Target;
+ try
+ {
+ // If we had a user override, check to make sure this differs
+ if (context.userOverride != calendar)
+ context.calendars.Add((int)calendar);
+
+ return Interop.BOOL.TRUE;
+ }
+ catch (Exception)
+ {
+ return Interop.BOOL.FALSE;
+ }
+ }
+
+ private static unsafe String GetUserDefaultLocaleName()
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ const int LOCALE_NAME_MAX_LENGTH = 85;
+ const uint LOCALE_SNAME = 0x0000005c;
+ const string LOCALE_NAME_USER_DEFAULT = null;
+
+ int result;
+ char* localeName = stackalloc char[LOCALE_NAME_MAX_LENGTH];
+ result = CultureData.GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME, localeName, LOCALE_NAME_MAX_LENGTH);
+
+ return result <= 0 ? "" : new String(localeName, 0, result - 1); // exclude the null termination
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/CalendarData.cs b/src/mscorlib/src/System/Globalization/CalendarData.cs
index d66331b31d..0991149e07 100644
--- a/src/mscorlib/src/System/Globalization/CalendarData.cs
+++ b/src/mscorlib/src/System/Globalization/CalendarData.cs
@@ -2,159 +2,136 @@
// 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.Diagnostics;
+
namespace System.Globalization
{
-
- using System;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- //
// List of calendar data
// Note the we cache overrides.
// Note that localized names (resource names) aren't available from here.
//
// NOTE: Calendars depend on the locale name that creates it. Only a few
- // properties are available without locales using CalendarData.GetCalendar(int)
+ // properties are available without locales using CalendarData.GetCalendar(CalendarData)
- // StructLayout is needed here otherwise compiler can re-arrange the fields.
- // We have to keep this in-sync with the definition in calendardata.h
- //
- // WARNING WARNING WARNING
- //
- // WARNING: Anything changed here also needs to be updated on the native side (object.h see type CalendarDataBaseObject)
- // WARNING: The type loader will rearrange class member offsets so the mscorwks!CalendarDataBaseObject
- // WARNING: must be manually structured to match the true loaded class layout
- //
- internal class CalendarData
+ internal partial class CalendarData
{
// Max calendars
internal const int MAX_CALENDARS = 23;
// Identity
- internal String sNativeName ; // Calendar Name for the locale
+ internal String sNativeName; // Calendar Name for the locale
// Formats
- internal String[] saShortDates ; // Short Data format, default first
- internal String[] saYearMonths ; // Year/Month Data format, default first
- internal String[] saLongDates ; // Long Data format, default first
- internal String sMonthDay ; // Month/Day format
+ internal String[] saShortDates; // Short Data format, default first
+ internal String[] saYearMonths; // Year/Month Data format, default first
+ internal String[] saLongDates; // Long Data format, default first
+ internal String sMonthDay; // Month/Day format
// Calendar Parts Names
- internal String[] saEraNames ; // Names of Eras
- internal String[] saAbbrevEraNames ; // Abbreviated Era Names
- internal String[] saAbbrevEnglishEraNames ; // Abbreviated Era Names in English
- internal String[] saDayNames ; // Day Names, null to use locale data, starts on Sunday
- internal String[] saAbbrevDayNames ; // Abbrev Day Names, null to use locale data, starts on Sunday
- internal String[] saSuperShortDayNames ; // Super short Day of week names
- internal String[] saMonthNames ; // Month Names (13)
- internal String[] saAbbrevMonthNames ; // Abbrev Month Names (13)
- internal String[] saMonthGenitiveNames ; // Genitive Month Names (13)
- internal String[] saAbbrevMonthGenitiveNames; // Genitive Abbrev Month Names (13)
- internal String[] saLeapYearMonthNames ; // Multiple strings for the month names in a leap year.
+ internal String[] saEraNames; // Names of Eras
+ internal String[] saAbbrevEraNames; // Abbreviated Era Names
+ internal String[] saAbbrevEnglishEraNames; // Abbreviated Era Names in English
+ internal String[] saDayNames; // Day Names, null to use locale data, starts on Sunday
+ internal String[] saAbbrevDayNames; // Abbrev Day Names, null to use locale data, starts on Sunday
+ internal String[] saSuperShortDayNames; // Super short Day of week names
+ internal String[] saMonthNames; // Month Names (13)
+ internal String[] saAbbrevMonthNames; // Abbrev Month Names (13)
+ internal String[] saMonthGenitiveNames; // Genitive Month Names (13)
+ internal String[] saAbbrevMonthGenitiveNames; // Genitive Abbrev Month Names (13)
+ internal String[] saLeapYearMonthNames; // Multiple strings for the month names in a leap year.
// Integers at end to make marshaller happier
- internal int iTwoDigitYearMax=2029 ; // Max 2 digit year (for Y2K bug data entry)
- internal int iCurrentEra=0 ; // current era # (usually 1)
+ internal int iTwoDigitYearMax = 2029; // Max 2 digit year (for Y2K bug data entry)
+ internal int iCurrentEra = 0; // current era # (usually 1)
// Use overrides?
- internal bool bUseUserOverrides ; // True if we want user overrides.
+ internal bool bUseUserOverrides; // True if we want user overrides.
// Static invariant for the invariant locale
- internal static CalendarData Invariant;
+ internal static readonly CalendarData Invariant = CreateInvariant();
// Private constructor
- private CalendarData() {}
+ private CalendarData() { }
- // Invariant constructor
- static CalendarData()
+ // Invariant factory
+ private static CalendarData CreateInvariant()
{
-
// Set our default/gregorian US calendar data
// Calendar IDs are 1-based, arrays are 0 based.
CalendarData invariant = new CalendarData();
// Set default data for calendar
// Note that we don't load resources since this IS NOT supposed to change (by definition)
- invariant.sNativeName = "Gregorian Calendar"; // Calendar Name
+ invariant.sNativeName = "Gregorian Calendar"; // Calendar Name
// Year
- invariant.iTwoDigitYearMax = 2029; // Max 2 digit year (for Y2K bug data entry)
- invariant.iCurrentEra = 1; // Current era #
+ invariant.iTwoDigitYearMax = 2029; // Max 2 digit year (for Y2K bug data entry)
+ invariant.iCurrentEra = 1; // Current era #
// Formats
- invariant.saShortDates = new String[] { "MM/dd/yyyy", "yyyy-MM-dd" }; // short date format
- invariant.saLongDates = new String[] { "dddd, dd MMMM yyyy"}; // long date format
- invariant.saYearMonths = new String[] { "yyyy MMMM" }; // year month format
- invariant.sMonthDay = "MMMM dd"; // Month day pattern
+ invariant.saShortDates = new String[] { "MM/dd/yyyy", "yyyy-MM-dd" }; // short date format
+ invariant.saLongDates = new String[] { "dddd, dd MMMM yyyy" }; // long date format
+ invariant.saYearMonths = new String[] { "yyyy MMMM" }; // year month format
+ invariant.sMonthDay = "MMMM dd"; // Month day pattern
// Calendar Parts Names
- invariant.saEraNames = new String[] { "A.D." }; // Era names
- invariant.saAbbrevEraNames = new String[] { "AD" }; // Abbreviated Era names
- invariant.saAbbrevEnglishEraNames=new String[] { "AD" }; // Abbreviated era names in English
- invariant.saDayNames = new String[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };// day names
- invariant.saAbbrevDayNames = new String[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; // abbreviated day names
- invariant.saSuperShortDayNames = new String[] { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" }; // The super short day names
- invariant.saMonthNames = new String[] { "January", "February", "March", "April", "May", "June",
+ invariant.saEraNames = new String[] { "A.D." }; // Era names
+ invariant.saAbbrevEraNames = new String[] { "AD" }; // Abbreviated Era names
+ invariant.saAbbrevEnglishEraNames = new String[] { "AD" }; // Abbreviated era names in English
+ invariant.saDayNames = new String[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };// day names
+ invariant.saAbbrevDayNames = new String[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; // abbreviated day names
+ invariant.saSuperShortDayNames = new String[] { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" }; // The super short day names
+ invariant.saMonthNames = new String[] { "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December", String.Empty}; // month names
- invariant.saAbbrevMonthNames = new String[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ invariant.saAbbrevMonthNames = new String[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", String.Empty}; // abbreviated month names
- invariant.saMonthGenitiveNames = invariant.saMonthNames; // Genitive month names (same as month names for invariant)
- invariant.saAbbrevMonthGenitiveNames=invariant.saAbbrevMonthNames; // Abbreviated genitive month names (same as abbrev month names for invariant)
- invariant.saLeapYearMonthNames = invariant.saMonthNames; // leap year month names are unused in Gregorian English (invariant)
+ invariant.saMonthGenitiveNames = invariant.saMonthNames; // Genitive month names (same as month names for invariant)
+ invariant.saAbbrevMonthGenitiveNames = invariant.saAbbrevMonthNames; // Abbreviated genitive month names (same as abbrev month names for invariant)
+ invariant.saLeapYearMonthNames = invariant.saMonthNames; // leap year month names are unused in Gregorian English (invariant)
- invariant.bUseUserOverrides = false;
+ invariant.bUseUserOverrides = false;
- // Calendar was built, go ahead and assign it...
- Invariant = invariant;
+ return invariant;
}
-
-
//
// Get a bunch of data for a calendar
//
- internal CalendarData(String localeName, int calendarId, bool bUseUserOverrides)
+ internal CalendarData(String localeName, CalendarId calendarId, bool bUseUserOverrides)
{
- // Call nativeGetCalendarData to populate the data
this.bUseUserOverrides = bUseUserOverrides;
- if (!nativeGetCalendarData(this, localeName, calendarId))
+
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ if (!LoadCalendarDataFromSystem(localeName, calendarId))
{
- Debug.Assert(false, "[CalendarData] nativeGetCalendarData call isn't expected to fail for calendar " + calendarId + " locale " +localeName);
-
+ Debug.Assert(false, "[CalendarData] LoadCalendarDataFromSystem call isn't expected to fail for calendar " + calendarId + " locale " + localeName);
+
// Something failed, try invariant for missing parts
// This is really not good, but we don't want the callers to crash.
- if (this.sNativeName == null) this.sNativeName = String.Empty; // Calendar Name for the locale.
-
+ if (this.sNativeName == null) this.sNativeName = String.Empty; // Calendar Name for the locale.
+
// Formats
- if (this.saShortDates == null) this.saShortDates = Invariant.saShortDates; // Short Data format, default first
- if (this.saYearMonths == null) this.saYearMonths = Invariant.saYearMonths; // Year/Month Data format, default first
- if (this.saLongDates == null) this.saLongDates = Invariant.saLongDates; // Long Data format, default first
- if (this.sMonthDay == null) this.sMonthDay = Invariant.sMonthDay; // Month/Day format
-
+ if (this.saShortDates == null) this.saShortDates = Invariant.saShortDates; // Short Data format, default first
+ if (this.saYearMonths == null) this.saYearMonths = Invariant.saYearMonths; // Year/Month Data format, default first
+ if (this.saLongDates == null) this.saLongDates = Invariant.saLongDates; // Long Data format, default first
+ if (this.sMonthDay == null) this.sMonthDay = Invariant.sMonthDay; // Month/Day format
+
// Calendar Parts Names
- if (this.saEraNames == null) this.saEraNames = Invariant.saEraNames; // Names of Eras
- if (this.saAbbrevEraNames == null) this.saAbbrevEraNames = Invariant.saAbbrevEraNames; // Abbreviated Era Names
+ if (this.saEraNames == null) this.saEraNames = Invariant.saEraNames; // Names of Eras
+ if (this.saAbbrevEraNames == null) this.saAbbrevEraNames = Invariant.saAbbrevEraNames; // Abbreviated Era Names
if (this.saAbbrevEnglishEraNames == null) this.saAbbrevEnglishEraNames = Invariant.saAbbrevEnglishEraNames; // Abbreviated Era Names in English
- if (this.saDayNames == null) this.saDayNames = Invariant.saDayNames; // Day Names, null to use locale data, starts on Sunday
- if (this.saAbbrevDayNames == null) this.saAbbrevDayNames = Invariant.saAbbrevDayNames; // Abbrev Day Names, null to use locale data, starts on Sunday
- if (this.saSuperShortDayNames == null) this.saSuperShortDayNames = Invariant.saSuperShortDayNames; // Super short Day of week names
- if (this.saMonthNames == null) this.saMonthNames = Invariant.saMonthNames; // Month Names (13)
- if (this.saAbbrevMonthNames == null) this.saAbbrevMonthNames = Invariant.saAbbrevMonthNames; // Abbrev Month Names (13)
+ if (this.saDayNames == null) this.saDayNames = Invariant.saDayNames; // Day Names, null to use locale data, starts on Sunday
+ if (this.saAbbrevDayNames == null) this.saAbbrevDayNames = Invariant.saAbbrevDayNames; // Abbrev Day Names, null to use locale data, starts on Sunday
+ if (this.saSuperShortDayNames == null) this.saSuperShortDayNames = Invariant.saSuperShortDayNames; // Super short Day of week names
+ if (this.saMonthNames == null) this.saMonthNames = Invariant.saMonthNames; // Month Names (13)
+ if (this.saAbbrevMonthNames == null) this.saAbbrevMonthNames = Invariant.saAbbrevMonthNames; // Abbrev Month Names (13)
// Genitive and Leap names can follow the fallback below
}
- // Clean up the escaping of the formats
- this.saShortDates = CultureData.ReescapeWin32Strings(this.saShortDates);
- this.saLongDates = CultureData.ReescapeWin32Strings(this.saLongDates);
- this.saYearMonths = CultureData.ReescapeWin32Strings(this.saYearMonths);
- this.sMonthDay = CultureData.ReescapeWin32String(this.sMonthDay);
-
- if ((CalendarId)calendarId == CalendarId.TAIWAN)
+ if (calendarId == CalendarId.TAIWAN)
{
- if (CultureInfo.IsTaiwanSku)
+ if (SystemSupportsTaiwaneseCalendar())
{
// We got the month/day names from the OS (same as gregorian), but the native name is wrong
this.sNativeName = "\x4e2d\x83ef\x6c11\x570b\x66c6";
@@ -166,11 +143,11 @@ namespace System.Globalization
}
// Check for null genitive names (in case unmanaged side skips it for non-gregorian calendars, etc)
- if (this.saMonthGenitiveNames == null || String.IsNullOrEmpty(this.saMonthGenitiveNames[0]))
+ if (this.saMonthGenitiveNames == null || this.saMonthGenitiveNames.Length == 0 || String.IsNullOrEmpty(this.saMonthGenitiveNames[0]))
this.saMonthGenitiveNames = this.saMonthNames; // Genitive month names (same as month names for invariant)
- if (this.saAbbrevMonthGenitiveNames == null || String.IsNullOrEmpty(this.saAbbrevMonthGenitiveNames[0]))
+ if (this.saAbbrevMonthGenitiveNames == null || this.saAbbrevMonthGenitiveNames.Length == 0 || String.IsNullOrEmpty(this.saAbbrevMonthGenitiveNames[0]))
this.saAbbrevMonthGenitiveNames = this.saAbbrevMonthNames; // Abbreviated genitive month names (same as abbrev month names for invariant)
- if (this.saLeapYearMonthNames == null || String.IsNullOrEmpty(this.saLeapYearMonthNames[0]))
+ if (this.saLeapYearMonthNames == null || this.saLeapYearMonthNames.Length == 0 || String.IsNullOrEmpty(this.saLeapYearMonthNames[0]))
this.saLeapYearMonthNames = this.saMonthNames;
InitializeEraNames(localeName, calendarId);
@@ -178,7 +155,7 @@ namespace System.Globalization
InitializeAbbreviatedEraNames(localeName, calendarId);
// Abbreviated English Era Names are only used for the Japanese calendar.
- if (calendarId == (int)CalendarId.JAPAN)
+ if (calendarId == CalendarId.JAPAN)
{
this.saAbbrevEnglishEraNames = JapaneseCalendar.EnglishEraNames();
}
@@ -193,12 +170,12 @@ namespace System.Globalization
this.iCurrentEra = this.saEraNames.Length;
}
- private void InitializeEraNames(string localeName, int calendarId)
+ private void InitializeEraNames(string localeName, CalendarId calendarId)
{
// Note that the saEraNames only include "A.D." We don't have localized names for other calendars available from windows
- switch ((CalendarId)calendarId)
+ switch (calendarId)
{
- // For Localized Gregorian we really expect the data from the OS.
+ // For Localized Gregorian we really expect the data from the OS.
case CalendarId.GREGORIAN:
// Fallback for CoreCLR < Win7 or culture.dll missing
if (this.saEraNames == null || this.saEraNames.Length == 0 || String.IsNullOrEmpty(this.saEraNames[0]))
@@ -207,7 +184,7 @@ namespace System.Globalization
}
break;
- // The rest of the calendars have constant data, so we'll just use that
+ // The rest of the calendars have constant data, so we'll just use that
case CalendarId.GREGORIAN_US:
case CalendarId.JULIAN:
this.saEraNames = new String[] { "A.D." };
@@ -237,9 +214,9 @@ namespace System.Globalization
case CalendarId.GREGORIAN_ME_FRENCH:
this.saEraNames = new String[] { "ap. J.-C." };
break;
-
+
case CalendarId.TAIWAN:
- if (CultureInfo.IsTaiwanSku)
+ if (SystemSupportsTaiwaneseCalendar())
{
this.saEraNames = new String[] { "\x4e2d\x83ef\x6c11\x570b" };
}
@@ -252,11 +229,11 @@ namespace System.Globalization
case CalendarId.KOREA:
this.saEraNames = new String[] { "\xb2e8\xae30" };
break;
-
+
case CalendarId.THAI:
this.saEraNames = new String[] { "\x0e1e\x002e\x0e28\x002e" };
break;
-
+
case CalendarId.JAPAN:
case CalendarId.JAPANESELUNISOLAR:
this.saEraNames = JapaneseCalendar.EraNames();
@@ -276,25 +253,25 @@ namespace System.Globalization
}
}
- private void InitializeAbbreviatedEraNames(string localeName, int calendarId)
+ private void InitializeAbbreviatedEraNames(string localeName, CalendarId calendarId)
{
// Note that the saAbbrevEraNames only include "AD" We don't have localized names for other calendars available from windows
- switch ((CalendarId)calendarId)
+ switch (calendarId)
{
- // For Localized Gregorian we really expect the data from the OS.
+ // For Localized Gregorian we really expect the data from the OS.
case CalendarId.GREGORIAN:
- // Fallback for culture.dll missing
+ // Fallback for CoreCLR < Win7 or culture.dll missing
if (this.saAbbrevEraNames == null || this.saAbbrevEraNames.Length == 0 || String.IsNullOrEmpty(this.saAbbrevEraNames[0]))
{
this.saAbbrevEraNames = new String[] { "AD" };
}
break;
- // The rest of the calendars have constant data, so we'll just use that
+ // The rest of the calendars have constant data, so we'll just use that
case CalendarId.GREGORIAN_US:
- case CalendarId.JULIAN:
+ case CalendarId.JULIAN:
this.saAbbrevEraNames = new String[] { "AD" };
- break;
+ break;
case CalendarId.JAPAN:
case CalendarId.JAPANESELUNISOLAR:
this.saAbbrevEraNames = JapaneseCalendar.AbbrevEraNames();
@@ -316,12 +293,12 @@ namespace System.Globalization
this.saAbbrevEraNames = new String[1];
if (this.saEraNames[0].Length == 4)
{
- this.saAbbrevEraNames[0] = this.saEraNames[0].Substring(2,2);
+ this.saAbbrevEraNames[0] = this.saEraNames[0].Substring(2, 2);
}
else
{
this.saAbbrevEraNames[0] = this.saEraNames[0];
- }
+ }
break;
case CalendarId.PERSIAN:
@@ -338,7 +315,7 @@ namespace System.Globalization
}
}
- internal static CalendarData GetCalendarData(int calendarId)
+ internal static CalendarData GetCalendarData(CalendarId calendarId)
{
//
// Get a calendar.
@@ -348,50 +325,47 @@ namespace System.Globalization
//
// Get a culture name
+ // TODO: Note that this doesn't handle the new calendars (lunisolar, etc)
String culture = CalendarIdToCultureName(calendarId);
-
+
// Return our calendar
- return CultureInfo.GetCultureInfo(culture).m_cultureData.GetCalendar(calendarId);
+ return CultureInfo.GetCultureInfo(culture)._cultureData.GetCalendar(calendarId);
}
- //
- // Helper methods
- //
- private static String CalendarIdToCultureName(int calendarId)
+ private static String CalendarIdToCultureName(CalendarId calendarId)
{
- // note that this doesn't handle the new calendars (lunisolar, etc)
switch (calendarId)
{
- case Calendar.CAL_GREGORIAN_US:
+ case CalendarId.GREGORIAN_US:
return "fa-IR"; // "fa-IR" Iran
-
- case Calendar.CAL_JAPAN:
+
+ case CalendarId.JAPAN:
return "ja-JP"; // "ja-JP" Japan
- case Calendar.CAL_TAIWAN: // zh-TW Taiwan
- return "zh-TW";
-
- case Calendar.CAL_KOREA:
+ case CalendarId.TAIWAN:
+ return "zh-TW"; // zh-TW Taiwan
+
+ case CalendarId.KOREA:
return "ko-KR"; // "ko-KR" Korea
-
- case Calendar.CAL_HIJRI:
- case Calendar.CAL_GREGORIAN_ARABIC:
- case Calendar.CAL_UMALQURA:
+
+ case CalendarId.HIJRI:
+ case CalendarId.GREGORIAN_ARABIC:
+ case CalendarId.UMALQURA:
return "ar-SA"; // "ar-SA" Saudi Arabia
- case Calendar.CAL_THAI:
+ case CalendarId.THAI:
return "th-TH"; // "th-TH" Thailand
-
- case Calendar.CAL_HEBREW:
+
+ case CalendarId.HEBREW:
return "he-IL"; // "he-IL" Israel
-
- case Calendar.CAL_GREGORIAN_ME_FRENCH:
+
+ case CalendarId.GREGORIAN_ME_FRENCH:
return "ar-DZ"; // "ar-DZ" Algeria
-
- case Calendar.CAL_GREGORIAN_XLIT_ENGLISH:
- case Calendar.CAL_GREGORIAN_XLIT_FRENCH:
+
+ case CalendarId.GREGORIAN_XLIT_ENGLISH:
+ case CalendarId.GREGORIAN_XLIT_FRENCH:
return "ar-IQ"; // "ar-IQ"; Iraq
-
+
default:
// Default to gregorian en-US
break;
@@ -399,20 +373,6 @@ namespace System.Globalization
return "en-US";
}
-
-
- // Get native two digit year max
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern int nativeGetTwoDigitYearMax(int calID);
-
- // Call native side to load our calendar data
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern bool nativeGetCalendarData(CalendarData data, String localeName, int calendar);
-
- // Call native side to figure out which calendars are allowed
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern int nativeGetCalendars(String localeName, bool useUserOverride, [In, Out] int[] calendars);
-
}
- }
+}
diff --git a/src/mscorlib/src/System/Globalization/CalendarWeekRule.cs b/src/mscorlib/src/System/Globalization/CalendarWeekRule.cs
deleted file mode 100644
index fa2a6429f1..0000000000
--- a/src/mscorlib/src/System/Globalization/CalendarWeekRule.cs
+++ /dev/null
@@ -1,19 +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.
-
-namespace System.Globalization {
- using System;
-
-
- [Serializable]
- public enum CalendarWeekRule
- {
-
- FirstDay = 0, // Week 1 begins on the first day of the year
-
- FirstFullWeek = 1, // Week 1 begins on first FirstDayOfWeek not before the first day of the year
-
- FirstFourDayWeek = 2 // Week 1 begins on first FirstDayOfWeek such that FirstDayOfWeek+3 is not before the first day of the year
- };
-}
diff --git a/src/mscorlib/src/System/Globalization/CalendricalCalculationsHelper.cs b/src/mscorlib/src/System/Globalization/CalendricalCalculationsHelper.cs
deleted file mode 100644
index 1113cd58ba..0000000000
--- a/src/mscorlib/src/System/Globalization/CalendricalCalculationsHelper.cs
+++ /dev/null
@@ -1,414 +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.
-
-namespace System.Globalization
-{
- using System;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- internal class CalendricalCalculationsHelper
- {
- const double FullCircleOfArc = 360.0; // 360.0;
- const int HalfCircleOfArc = 180;
- const double TwelveHours = 0.5; // half a day
- const double Noon2000Jan01 = 730120.5;
- internal const double MeanTropicalYearInDays = 365.242189;
- const double MeanSpeedOfSun = MeanTropicalYearInDays / FullCircleOfArc;
- const double LongitudeSpring = 0.0;
- const double TwoDegreesAfterSpring = 2.0;
- const int SecondsPerDay = 24 * 60 * 60; // 24 hours * 60 minutes * 60 seconds
-
- const int DaysInUniformLengthCentury = 36525;
- const int SecondsPerMinute = 60;
- const int MinutesPerDegree = 60;
-
- static long StartOf1810 = GetNumberOfDays(new DateTime(1810, 1, 1));
- static long StartOf1900Century = GetNumberOfDays(new DateTime(1900, 1, 1));
-
- static double[] Coefficients1900to1987 = new double[] { -0.00002, 0.000297, 0.025184, -0.181133, 0.553040, -0.861938, 0.677066, -0.212591 };
- static double[] Coefficients1800to1899 = new double[] { -0.000009, 0.003844, 0.083563, 0.865736, 4.867575, 15.845535, 31.332267, 38.291999, 28.316289, 11.636204, 2.043794 };
- static double[] Coefficients1700to1799 = new double[] { 8.118780842, -0.005092142, 0.003336121, -0.0000266484 };
- static double[] Coefficients1620to1699 = new double[] { 196.58333, -4.0675, 0.0219167 };
- static double[] LambdaCoefficients = new double[] { 280.46645, 36000.76983, 0.0003032 };
- static double[] AnomalyCoefficients = new double[] { 357.52910, 35999.05030, -0.0001559, -0.00000048 };
- static double[] EccentricityCoefficients = new double[] { 0.016708617, -0.000042037, -0.0000001236 };
- static double[] Coefficients = new double[] { Angle(23, 26, 21.448), Angle(0, 0, -46.8150), Angle(0, 0, -0.00059), Angle(0, 0, 0.001813) };
- static double[] CoefficientsA = new double[] { 124.90, -1934.134, 0.002063 };
- static double[] CoefficientsB = new double[] { 201.11, 72001.5377, 0.00057 };
-
- static double RadiansFromDegrees(double degree)
- {
- return degree * Math.PI / 180;
- }
-
- static double SinOfDegree(double degree)
- {
- return Math.Sin(RadiansFromDegrees(degree));
- }
-
- static double CosOfDegree(double degree)
- {
- return Math.Cos(RadiansFromDegrees(degree));
- }
- static double TanOfDegree(double degree)
- {
- return Math.Tan(RadiansFromDegrees(degree));
- }
-
- public static double Angle(int degrees, int minutes, double seconds)
- {
- return ((seconds / SecondsPerMinute + minutes) / MinutesPerDegree) + degrees;
- }
-
- static double Obliquity(double julianCenturies)
- {
- return PolynomialSum(Coefficients, julianCenturies);
- }
-
- internal static long GetNumberOfDays(DateTime date)
- {
- return date.Ticks / GregorianCalendar.TicksPerDay;
- }
-
- static int GetGregorianYear(double numberOfDays)
- {
- return new DateTime(Math.Min((long)(Math.Floor(numberOfDays) * GregorianCalendar.TicksPerDay), DateTime.MaxValue.Ticks)).Year;
- }
-
- enum CorrectionAlgorithm
- {
- Default,
- Year1988to2019,
- Year1900to1987,
- Year1800to1899,
- Year1700to1799,
- Year1620to1699
- }
-
- struct EphemerisCorrectionAlgorithmMap
- {
- public EphemerisCorrectionAlgorithmMap(int year, CorrectionAlgorithm algorithm)
- {
- _lowestYear = year;
- _algorithm = algorithm;
- }
-
- internal int _lowestYear;
- internal CorrectionAlgorithm _algorithm;
- };
-
- static EphemerisCorrectionAlgorithmMap[] EphemerisCorrectionTable = new EphemerisCorrectionAlgorithmMap[]
- {
- // lowest year that starts algorithm, algorithm to use
- new EphemerisCorrectionAlgorithmMap(2020, CorrectionAlgorithm.Default),
- new EphemerisCorrectionAlgorithmMap(1988, CorrectionAlgorithm.Year1988to2019),
- new EphemerisCorrectionAlgorithmMap(1900, CorrectionAlgorithm.Year1900to1987),
- new EphemerisCorrectionAlgorithmMap(1800, CorrectionAlgorithm.Year1800to1899),
- new EphemerisCorrectionAlgorithmMap(1700, CorrectionAlgorithm.Year1700to1799),
- new EphemerisCorrectionAlgorithmMap(1620, CorrectionAlgorithm.Year1620to1699),
- new EphemerisCorrectionAlgorithmMap(int.MinValue, CorrectionAlgorithm.Default) // default must be last
- };
-
- static double Reminder(double divisor, double dividend)
- {
- double whole = Math.Floor(divisor / dividend);
- return divisor - (dividend * whole);
- }
-
- static double NormalizeLongitude(double longitude)
- {
- longitude = Reminder(longitude, FullCircleOfArc);
- if (longitude < 0)
- {
- longitude += FullCircleOfArc;
- }
- return longitude;
- }
-
- static public double AsDayFraction(double longitude)
- {
- return longitude / FullCircleOfArc;
- }
-
- static double PolynomialSum(double[] coefficients, double indeterminate)
- {
- double sum = coefficients[0];
- double indeterminateRaised = 1;
- for (int i=1; i<coefficients.Length; i++)
- {
- indeterminateRaised *= indeterminate;
- sum += (coefficients[i] * indeterminateRaised);
- }
-
- return sum;
- }
-
- static double CenturiesFrom1900(int gregorianYear)
- {
- long july1stOfYear = GetNumberOfDays(new DateTime(gregorianYear, 7, 1));
- return (double) (july1stOfYear - StartOf1900Century) / DaysInUniformLengthCentury;
- }
-
- // the following formulas defines a polynomial function which gives us the amount that the earth is slowing down for specific year ranges
- static double DefaultEphemerisCorrection(int gregorianYear)
- {
- Debug.Assert(gregorianYear < 1620 || 2020 <= gregorianYear);
- long january1stOfYear = GetNumberOfDays(new DateTime(gregorianYear, 1, 1));
- double daysSinceStartOf1810 = january1stOfYear - StartOf1810;
- double x = TwelveHours + daysSinceStartOf1810;
- return ((Math.Pow(x, 2) / 41048480) - 15) / SecondsPerDay;
- }
-
- static double EphemerisCorrection1988to2019(int gregorianYear)
- {
- Debug.Assert(1988 <= gregorianYear && gregorianYear <= 2019);
- return (double)(gregorianYear - 1933) / SecondsPerDay;
- }
-
- static double EphemerisCorrection1900to1987(int gregorianYear)
- {
- Debug.Assert(1900 <= gregorianYear && gregorianYear <= 1987);
- double centuriesFrom1900 = CenturiesFrom1900(gregorianYear);
- return PolynomialSum(Coefficients1900to1987, centuriesFrom1900);
- }
-
- static double EphemerisCorrection1800to1899(int gregorianYear)
- {
- Debug.Assert(1800 <= gregorianYear && gregorianYear <= 1899);
- double centuriesFrom1900 = CenturiesFrom1900(gregorianYear);
- return PolynomialSum(Coefficients1800to1899, centuriesFrom1900);
- }
-
- static double EphemerisCorrection1700to1799(int gregorianYear)
- {
- Debug.Assert(1700 <= gregorianYear && gregorianYear <= 1799);
- double yearsSince1700 = gregorianYear - 1700;
- return PolynomialSum(Coefficients1700to1799, yearsSince1700) / SecondsPerDay;
- }
-
- static double EphemerisCorrection1620to1699(int gregorianYear)
- {
- Debug.Assert(1620 <= gregorianYear && gregorianYear <= 1699);
- double yearsSince1600 = gregorianYear - 1600;
- return PolynomialSum(Coefficients1620to1699, yearsSince1600) / SecondsPerDay;
- }
-
- // ephemeris-correction: correction to account for the slowing down of the rotation of the earth
- static double EphemerisCorrection(double time)
- {
- int year = GetGregorianYear(time);
- foreach (EphemerisCorrectionAlgorithmMap map in EphemerisCorrectionTable)
- {
- if (map._lowestYear <= year)
- {
- switch (map._algorithm)
- {
- case CorrectionAlgorithm.Default: return DefaultEphemerisCorrection(year);
- case CorrectionAlgorithm.Year1988to2019: return EphemerisCorrection1988to2019(year);
- case CorrectionAlgorithm.Year1900to1987: return EphemerisCorrection1900to1987(year);
- case CorrectionAlgorithm.Year1800to1899: return EphemerisCorrection1800to1899(year);
- case CorrectionAlgorithm.Year1700to1799: return EphemerisCorrection1700to1799(year);
- case CorrectionAlgorithm.Year1620to1699: return EphemerisCorrection1620to1699(year);
- }
-
- break; // break the loop and assert eventually
- }
- }
-
- Debug.Assert(false, "Not expected to come here");
- return DefaultEphemerisCorrection(year);
- }
-
- static public double JulianCenturies(double moment)
- {
- double dynamicalMoment = moment + EphemerisCorrection(moment);
- return (dynamicalMoment - Noon2000Jan01) / DaysInUniformLengthCentury;
- }
-
- static bool IsNegative(double value)
- {
- return Math.Sign(value) == -1;
- }
-
- static double CopySign(double value, double sign)
- {
- return (IsNegative(value) == IsNegative(sign)) ? value : -value;
- }
-
- // equation-of-time; approximate the difference between apparent solar time and mean solar time
- // formal definition is EOT = GHA - GMHA
- // GHA is the Greenwich Hour Angle of the apparent (actual) Sun
- // GMHA is the Greenwich Mean Hour Angle of the mean (fictitious) Sun
- // http://www.esrl.noaa.gov/gmd/grad/solcalc/
- // http://en.wikipedia.org/wiki/Equation_of_time
- static double EquationOfTime(double time)
- {
- double julianCenturies = JulianCenturies(time);
- double lambda = PolynomialSum(LambdaCoefficients, julianCenturies);
- double anomaly = PolynomialSum(AnomalyCoefficients, julianCenturies);
- double eccentricity = PolynomialSum(EccentricityCoefficients, julianCenturies);
-
- double epsilon = Obliquity(julianCenturies);
- double tanHalfEpsilon = TanOfDegree(epsilon / 2);
- double y = tanHalfEpsilon * tanHalfEpsilon;
-
- double dividend = ((y * SinOfDegree(2 * lambda))
- - (2 * eccentricity * SinOfDegree(anomaly))
- + (4 * eccentricity * y * SinOfDegree(anomaly) * CosOfDegree(2 * lambda))
- - (0.5 * Math.Pow(y, 2) * SinOfDegree(4 * lambda))
- - (1.25 * Math.Pow(eccentricity, 2) * SinOfDegree(2 * anomaly)));
- double divisor = 2 * Math.PI;
- double equation = dividend / divisor;
-
- // approximation of equation of time is not valid for dates that are many millennia in the past or future
- // thus limited to a half day
- return CopySign(Math.Min(Math.Abs(equation), TwelveHours), equation);
- }
-
- static double AsLocalTime(double apparentMidday, double longitude)
- {
- // slightly inaccurate since equation of time takes mean time not apparent time as its argument, but the difference is negligible
- double universalTime = apparentMidday - AsDayFraction(longitude);
- return apparentMidday - EquationOfTime(universalTime);
- }
-
- // midday
- static public double Midday(double date, double longitude)
- {
- return AsLocalTime(date+TwelveHours, longitude) - AsDayFraction(longitude);
- }
-
- static double InitLongitude(double longitude)
- {
- return NormalizeLongitude(longitude + HalfCircleOfArc) - HalfCircleOfArc;
- }
-
- // midday-in-tehran
- static public double MiddayAtPersianObservationSite(double date)
- {
- return Midday(date, InitLongitude(52.5)); // 52.5 degrees east - longitude of UTC+3:30 which defines Iranian Standard Time
- }
-
- static double PeriodicTerm(double julianCenturies, int x, double y, double z)
- {
- return x * SinOfDegree(y + z * julianCenturies);
- }
-
- static double SumLongSequenceOfPeriodicTerms(double julianCenturies)
- {
- double sum = 0.0;
- sum += PeriodicTerm(julianCenturies, 403406, 270.54861, 0.9287892);
- sum += PeriodicTerm(julianCenturies, 195207, 340.19128, 35999.1376958);
- sum += PeriodicTerm(julianCenturies, 119433, 63.91854, 35999.4089666);
- sum += PeriodicTerm(julianCenturies, 112392, 331.2622, 35998.7287385);
- sum += PeriodicTerm(julianCenturies, 3891, 317.843, 71998.20261);
- sum += PeriodicTerm(julianCenturies, 2819, 86.631, 71998.4403);
- sum += PeriodicTerm(julianCenturies, 1721, 240.052, 36000.35726);
- sum += PeriodicTerm(julianCenturies, 660, 310.26, 71997.4812);
- sum += PeriodicTerm(julianCenturies, 350, 247.23, 32964.4678);
- sum += PeriodicTerm(julianCenturies, 334, 260.87, -19.441);
- sum += PeriodicTerm(julianCenturies, 314, 297.82, 445267.1117);
- sum += PeriodicTerm(julianCenturies, 268, 343.14, 45036.884);
- sum += PeriodicTerm(julianCenturies, 242, 166.79, 3.1008);
- sum += PeriodicTerm(julianCenturies, 234, 81.53, 22518.4434);
- sum += PeriodicTerm(julianCenturies, 158, 3.5, -19.9739);
- sum += PeriodicTerm(julianCenturies, 132, 132.75, 65928.9345);
- sum += PeriodicTerm(julianCenturies, 129, 182.95, 9038.0293);
- sum += PeriodicTerm(julianCenturies, 114, 162.03, 3034.7684);
- sum += PeriodicTerm(julianCenturies, 99, 29.8, 33718.148);
- sum += PeriodicTerm(julianCenturies, 93, 266.4, 3034.448);
- sum += PeriodicTerm(julianCenturies, 86, 249.2, -2280.773);
- sum += PeriodicTerm(julianCenturies, 78, 157.6, 29929.992);
- sum += PeriodicTerm(julianCenturies, 72, 257.8, 31556.493);
- sum += PeriodicTerm(julianCenturies, 68, 185.1, 149.588);
- sum += PeriodicTerm(julianCenturies, 64, 69.9, 9037.75);
- sum += PeriodicTerm(julianCenturies, 46, 8.0, 107997.405);
- sum += PeriodicTerm(julianCenturies, 38, 197.1, -4444.176);
- sum += PeriodicTerm(julianCenturies, 37, 250.4, 151.771);
- sum += PeriodicTerm(julianCenturies, 32, 65.3, 67555.316);
- sum += PeriodicTerm(julianCenturies, 29, 162.7, 31556.08);
- sum += PeriodicTerm(julianCenturies, 28, 341.5, -4561.54);
- sum += PeriodicTerm(julianCenturies, 27, 291.6, 107996.706);
- sum += PeriodicTerm(julianCenturies, 27, 98.5, 1221.655);
- sum += PeriodicTerm(julianCenturies, 25, 146.7, 62894.167);
- sum += PeriodicTerm(julianCenturies, 24, 110.0, 31437.369);
- sum += PeriodicTerm(julianCenturies, 21, 5.2, 14578.298);
- sum += PeriodicTerm(julianCenturies, 21, 342.6, -31931.757);
- sum += PeriodicTerm(julianCenturies, 20, 230.9, 34777.243);
- sum += PeriodicTerm(julianCenturies, 18, 256.1, 1221.999);
- sum += PeriodicTerm(julianCenturies, 17, 45.3, 62894.511);
- sum += PeriodicTerm(julianCenturies, 14, 242.9, -4442.039);
- sum += PeriodicTerm(julianCenturies, 13, 115.2, 107997.909);
- sum += PeriodicTerm(julianCenturies, 13, 151.8, 119.066);
- sum += PeriodicTerm(julianCenturies, 13, 285.3, 16859.071);
- sum += PeriodicTerm(julianCenturies, 12, 53.3, -4.578);
- sum += PeriodicTerm(julianCenturies, 10, 126.6, 26895.292);
- sum += PeriodicTerm(julianCenturies, 10, 205.7, -39.127);
- sum += PeriodicTerm(julianCenturies, 10, 85.9, 12297.536);
- sum += PeriodicTerm(julianCenturies, 10, 146.1, 90073.778);
- return sum;
- }
-
- static double Aberration(double julianCenturies)
- {
- return (0.0000974 * CosOfDegree(177.63 + (35999.01848 * julianCenturies))) - 0.005575;
- }
-
- static double Nutation(double julianCenturies)
- {
- double a = PolynomialSum(CoefficientsA, julianCenturies);
- double b = PolynomialSum(CoefficientsB, julianCenturies);
- return (-0.004778 * SinOfDegree(a)) - (0.0003667 * SinOfDegree(b));
- }
-
- static public double Compute(double time)
- {
- double julianCenturies = JulianCenturies(time);
- double lambda = 282.7771834
- + (36000.76953744 * julianCenturies)
- + (0.000005729577951308232 * SumLongSequenceOfPeriodicTerms(julianCenturies));
-
- double longitude = lambda + Aberration(julianCenturies) + Nutation(julianCenturies);
- return InitLongitude(longitude);
- }
-
- static public double AsSeason(double longitude)
- {
- return (longitude < 0) ? (longitude + FullCircleOfArc) : longitude;
- }
-
- static double EstimatePrior(double longitude, double time)
- {
- double timeSunLastAtLongitude = time - (MeanSpeedOfSun * AsSeason(InitLongitude(Compute(time) - longitude)));
- double longitudeErrorDelta = InitLongitude(Compute(timeSunLastAtLongitude) - longitude);
- return Math.Min(time, timeSunLastAtLongitude - (MeanSpeedOfSun * longitudeErrorDelta));
- }
-
- // persian-new-year-on-or-before
- // number of days is the absolute date. The absolute date is the number of days from January 1st, 1 A.D.
- // 1/1/0001 is absolute date 1.
- internal static long PersianNewYearOnOrBefore(long numberOfDays)
- {
- double date = (double) numberOfDays;
-
- double approx = EstimatePrior(LongitudeSpring, MiddayAtPersianObservationSite(date));
- long lowerBoundNewYearDay = (long) Math.Floor(approx) - 1;
- long upperBoundNewYearDay = lowerBoundNewYearDay + 3; // estimate is generally within a day of the actual occurrance (at the limits, the error expands, since the calculations rely on the mean tropical year which changes...)
- long day = lowerBoundNewYearDay;
- for (; day != upperBoundNewYearDay; ++day)
- {
- double midday = MiddayAtPersianObservationSite((double) day);
- double l = Compute(midday);
- if ((LongitudeSpring <= l) && (l <= TwoDegreesAfterSpring))
- {
- break;
- }
- }
- Debug.Assert(day != upperBoundNewYearDay);
-
- return day - 1;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/CharUnicodeInfo.cs b/src/mscorlib/src/System/Globalization/CharUnicodeInfo.cs
index 2822b418ef..8e3bb47424 100644
--- a/src/mscorlib/src/System/Globalization/CharUnicodeInfo.cs
+++ b/src/mscorlib/src/System/Globalization/CharUnicodeInfo.cs
@@ -12,22 +12,12 @@
//
////////////////////////////////////////////////////////////////////////////
-namespace System.Globalization {
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
- //This class has only static members and therefore doesn't need to be serialized.
-
- using System;
- using System.Threading;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Reflection;
- using System.Security;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
-
- public static class CharUnicodeInfo
+namespace System.Globalization
+{
+ public static partial class CharUnicodeInfo
{
//--------------------------------------------------------------------//
// Internal Information //
@@ -36,95 +26,18 @@ namespace System.Globalization {
//
// Native methods to access the Unicode category data tables in charinfo.nlp.
//
- internal const char HIGH_SURROGATE_START = '\ud800';
- internal const char HIGH_SURROGATE_END = '\udbff';
- internal const char LOW_SURROGATE_START = '\udc00';
- internal const char LOW_SURROGATE_END = '\udfff';
+ internal const char HIGH_SURROGATE_START = '\ud800';
+ internal const char HIGH_SURROGATE_END = '\udbff';
+ internal const char LOW_SURROGATE_START = '\udc00';
+ internal const char LOW_SURROGATE_END = '\udfff';
internal const int UNICODE_CATEGORY_OFFSET = 0;
internal const int BIDI_CATEGORY_OFFSET = 1;
- static bool s_initialized = InitTable();
-
- // The native pointer to the 12:4:4 index table of the Unicode cateogry data.
- unsafe static ushort* s_pCategoryLevel1Index;
- unsafe static byte* s_pCategoriesValue;
-
- // The native pointer to the 12:4:4 index table of the Unicode numeric data.
- // The value of this index table is an index into the real value table stored in s_pNumericValues.
- unsafe static ushort* s_pNumericLevel1Index;
-
- // The numeric value table, which is indexed by s_pNumericLevel1Index.
- // Every item contains the value for numeric value.
- // unsafe static double* s_pNumericValues;
- // To get around the IA64 alignment issue. Our double data is aligned in 8-byte boundary, but loader loads the embeded table starting
- // at 4-byte boundary. This cause a alignment issue since double is 8-byte.
- unsafe static byte* s_pNumericValues;
-
- // The digit value table, which is indexed by s_pNumericLevel1Index. It shares the same indice as s_pNumericValues.
- // Every item contains the value for decimal digit/digit value.
- unsafe static DigitValues* s_pDigitValues;
-
- internal const String UNICODE_INFO_FILE_NAME = "charinfo.nlp";
// The starting codepoint for Unicode plane 1. Plane 1 contains 0x010000 ~ 0x01ffff.
internal const int UNICODE_PLANE01_START = 0x10000;
- //
- // This is the header for the native data table that we load from UNICODE_INFO_FILE_NAME.
- //
- // Excplicit layout is used here since a syntax like char[16] can not be used in sequential layout.
- [StructLayout(LayoutKind.Explicit)]
- internal unsafe struct UnicodeDataHeader {
- [FieldOffset(0)]
- internal char TableName; // WCHAR[16]
- [FieldOffset(0x20)]
- internal ushort version; // WORD[4]
- [FieldOffset(0x28)]
- internal uint OffsetToCategoriesIndex; // DWORD
- [FieldOffset(0x2c)]
- internal uint OffsetToCategoriesValue; // DWORD
- [FieldOffset(0x30)]
- internal uint OffsetToNumbericIndex; // DWORD
- [FieldOffset(0x34)]
- internal uint OffsetToDigitValue; // DWORD
- [FieldOffset(0x38)]
- internal uint OffsetToNumbericValue; // DWORD
-
- }
-
- // NOTE: It's important to specify pack size here, since the size of the structure is 2 bytes. Otherwise,
- // the default pack size will be 4.
-
- [StructLayout(LayoutKind.Sequential, Pack=2)]
- internal struct DigitValues {
- internal sbyte decimalDigit;
- internal sbyte digit;
- }
-
-
- //We need to allocate the underlying table that provides us with the information that we
- //use. We allocate this once in the class initializer and then we don't need to worry
- //about it again.
- //
- unsafe static bool InitTable() {
-
- // Go to native side and get pointer to the native table
- byte * pDataTable = GlobalizationAssembly.GetGlobalizationResourceBytePtr(typeof(CharUnicodeInfo).Assembly, UNICODE_INFO_FILE_NAME);
-
- UnicodeDataHeader* mainHeader = (UnicodeDataHeader*)pDataTable;
-
- // Set up the native pointer to different part of the tables.
- s_pCategoryLevel1Index = (ushort*) (pDataTable + mainHeader->OffsetToCategoriesIndex);
- s_pCategoriesValue = (byte*) (pDataTable + mainHeader->OffsetToCategoriesValue);
- s_pNumericLevel1Index = (ushort*) (pDataTable + mainHeader->OffsetToNumbericIndex);
- s_pNumericValues = (byte*) (pDataTable + mainHeader->OffsetToNumbericValue);
- s_pDigitValues = (DigitValues*) (pDataTable + mainHeader->OffsetToDigitValue);
-
- return true;
- }
-
-
////////////////////////////////////////////////////////////////////////
//
// Actions:
@@ -137,14 +50,18 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
- internal static int InternalConvertToUtf32(String s, int index) {
+ internal static int InternalConvertToUtf32(String s, int index)
+ {
Debug.Assert(s != null, "s != null");
Debug.Assert(index >= 0 && index < s.Length, "index < s.Length");
- if (index < s.Length - 1) {
+ if (index < s.Length - 1)
+ {
int temp1 = (int)s[index] - HIGH_SURROGATE_START;
- if (temp1 >= 0 && temp1 <= 0x3ff) {
- int temp2 = (int)s[index+1] - LOW_SURROGATE_START;
- if (temp2 >= 0 && temp2 <= 0x3ff) {
+ if (temp1 >= 0 && temp1 <= 0x3ff)
+ {
+ int temp2 = (int)s[index + 1] - LOW_SURROGATE_START;
+ if (temp2 >= 0 && temp2 <= 0x3ff)
+ {
// Convert the surrogate to UTF32 and get the result.
return ((temp1 * 0x400) + temp2 + UNICODE_PLANE01_START);
}
@@ -152,7 +69,6 @@ namespace System.Globalization {
}
return ((int)s[index]);
}
-
////////////////////////////////////////////////////////////////////////
//
// Convert a character or a surrogate pair starting at index of string s
@@ -175,16 +91,20 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
- internal static int InternalConvertToUtf32(String s, int index, out int charLength) {
+ internal static int InternalConvertToUtf32(String s, int index, out int charLength)
+ {
Debug.Assert(s != null, "s != null");
Debug.Assert(s.Length > 0, "s.Length > 0");
Debug.Assert(index >= 0 && index < s.Length, "index >= 0 && index < s.Length");
charLength = 1;
- if (index < s.Length - 1) {
+ if (index < s.Length - 1)
+ {
int temp1 = (int)s[index] - HIGH_SURROGATE_START;
- if (temp1 >= 0 && temp1 <= 0x3ff) {
- int temp2 = (int)s[index+1] - LOW_SURROGATE_START;
- if (temp2 >= 0 && temp2 <= 0x3ff) {
+ if (temp1 >= 0 && temp1 <= 0x3ff)
+ {
+ int temp2 = (int)s[index + 1] - LOW_SURROGATE_START;
+ if (temp2 >= 0 && temp2 <= 0x3ff)
+ {
// Convert the surrogate to UTF32 and get the result.
charLength++;
return ((temp1 * 0x400) + temp2 + UNICODE_PLANE01_START);
@@ -210,7 +130,8 @@ namespace System.Globalization {
UnicodeCategory uc = GetUnicodeCategory(s, index);
// In Unicode 3.0, U+2028 is the only character which is under the category "LineSeparator".
// And U+2029 is th eonly character which is under the category "ParagraphSeparator".
- switch (uc) {
+ switch (uc)
+ {
case (UnicodeCategory.SpaceSeparator):
case (UnicodeCategory.LineSeparator):
case (UnicodeCategory.ParagraphSeparator):
@@ -225,7 +146,8 @@ namespace System.Globalization {
UnicodeCategory uc = GetUnicodeCategory(c);
// In Unicode 3.0, U+2028 is the only character which is under the category "LineSeparator".
// And U+2029 is th eonly character which is under the category "ParagraphSeparator".
- switch (uc) {
+ switch (uc)
+ {
case (UnicodeCategory.SpaceSeparator):
case (UnicodeCategory.LineSeparator):
case (UnicodeCategory.ParagraphSeparator):
@@ -235,12 +157,14 @@ namespace System.Globalization {
return (false);
}
+
//
// This is called by the public char and string, index versions
//
// Note that for ch in the range D800-DFFF we just treat it as any other non-numeric character
//
- internal unsafe static double InternalGetNumericValue(int ch) {
+ internal static unsafe double InternalGetNumericValue(int ch)
+ {
Debug.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range.");
// Get the level 2 item from the highest 12 bit (8 - 19) of ch.
ushort index = s_pNumericLevel1Index[ch >> 8];
@@ -248,52 +172,34 @@ namespace System.Globalization {
// The offset is referred to an float item in m_pNumericFloatData.
// Note that & has the lower precedence than addition, so don't forget the parathesis.
index = s_pNumericLevel1Index[index + ((ch >> 4) & 0x000f)];
- byte* pBytePtr = (byte*)&(s_pNumericLevel1Index[index]);
- // Get the result from the 0 -3 bit of ch.
-#if BIT64
- // To get around the IA64 alignment issue. Our double data is aligned in 8-byte boundary, but loader loads the embeded table starting
- // at 4-byte boundary. This cause a alignment issue since double is 8-byte.
- byte* pSourcePtr = &(s_pNumericValues[pBytePtr[(ch & 0x000f)] * sizeof(double)]);
- if (((long)pSourcePtr % 8) != 0) {
- // We are not aligned in 8-byte boundary. Do a copy.
- double ret;
- byte* retPtr = (byte*)&ret;
- Buffer.Memcpy(retPtr, pSourcePtr, sizeof(double));
- return (ret);
+
+ fixed (ushort* pUshortPtr = &(s_pNumericLevel1Index[index]))
+ {
+ byte* pBytePtr = (byte*)pUshortPtr;
+ fixed (byte* pByteNum = s_pNumericValues)
+ {
+ double* pDouble = (double*)pByteNum;
+ return pDouble[pBytePtr[(ch & 0x000f)]];
+ }
}
- return (((double*)s_pNumericValues)[pBytePtr[(ch & 0x000f)]]);
-#else
- return (((double*)s_pNumericValues)[pBytePtr[(ch & 0x000f)]]);
-#endif
}
- //
- // This is called by the public char and string, index versions
- //
- // Note that for ch in the range D800-DFFF we just treat it as any other non-numeric character
- //
- internal unsafe static DigitValues* InternalGetDigitValues(int ch) {
+ internal static unsafe ushort InternalGetDigitValues(int ch)
+ {
Debug.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range.");
// Get the level 2 item from the highest 12 bit (8 - 19) of ch.
ushort index = s_pNumericLevel1Index[ch >> 8];
// Get the level 2 WORD offset from the 4 - 7 bit of ch. This provides the base offset of the level 3 table.
- // The offset is referred to an float item in m_pNumericFloatData.
// Note that & has the lower precedence than addition, so don't forget the parathesis.
index = s_pNumericLevel1Index[index + ((ch >> 4) & 0x000f)];
- byte* pBytePtr = (byte*)&(s_pNumericLevel1Index[index]);
- // Get the result from the 0 -3 bit of ch.
- return &(s_pDigitValues[pBytePtr[(ch & 0x000f)]]);
- }
- internal unsafe static sbyte InternalGetDecimalDigitValue(int ch) {
- return (InternalGetDigitValues(ch)->decimalDigit);
- }
-
- internal unsafe static sbyte InternalGetDigitValue(int ch) {
- return (InternalGetDigitValues(ch)->digit);
+ fixed (ushort* pUshortPtr = &(s_pNumericLevel1Index[index]))
+ {
+ byte* pBytePtr = (byte*)pUshortPtr;
+ return s_pDigitValues[pBytePtr[(ch & 0x000f)]];
+ }
}
-
////////////////////////////////////////////////////////////////////////
//
//Returns the numeric value associated with the character c. If the character is a fraction,
@@ -310,114 +216,91 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
- public static double GetNumericValue(char ch) {
+ public static double GetNumericValue(char ch)
+ {
return (InternalGetNumericValue(ch));
}
- public static double GetNumericValue(String s, int index) {
- if (s == null) {
+ public static double GetNumericValue(String s, int index)
+ {
+ if (s == null)
+ {
throw new ArgumentNullException(nameof(s));
}
- if (index < 0 || index >= s.Length) {
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ if (index < 0 || index >= s.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
}
Contract.EndContractBlock();
return (InternalGetNumericValue(InternalConvertToUtf32(s, index)));
-
}
- ////////////////////////////////////////////////////////////////////////
- //
- //Returns the decimal digit value associated with the character c.
- //
- // The value should be from 0 ~ 9.
- // If the character does not have a numeric value, the return value is -1.
- // From Unicode.org: Decimal Digits. Digits that can be used to form decimal-radix numbers.
- //Returns:
- // the decimal digit value for the specified Unicode character. If the character does not have a decimal digit value, the return value is -1.
- //Arguments:
- // ch a Unicode character
- //Exceptions:
- // ArgumentNullException
- // ArgumentOutOfRangeException
- //
- ////////////////////////////////////////////////////////////////////////
-
-
- public static int GetDecimalDigitValue(char ch) {
- return (InternalGetDecimalDigitValue(ch));
+ public static int GetDecimalDigitValue(char ch)
+ {
+ return (sbyte)(InternalGetDigitValues(ch) >> 8);
}
-
- public static int GetDecimalDigitValue(String s, int index) {
- if (s == null) {
+ public static int GetDecimalDigitValue(String s, int index)
+ {
+ if (s == null)
+ {
throw new ArgumentNullException(nameof(s));
}
- if (index < 0 || index >= s.Length) {
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+
+ if (index < 0 || index >= s.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
}
Contract.EndContractBlock();
- return (InternalGetDecimalDigitValue(InternalConvertToUtf32(s, index)));
+ return (sbyte)(InternalGetDigitValues(InternalConvertToUtf32(s, index)) >> 8);
}
- ////////////////////////////////////////////////////////////////////////
- //
- //Action: Returns the digit value associated with the character c.
- // If the character does not have a numeric value, the return value is -1.
- // From Unicode.org: If the character represents a digit, not necessarily a decimal digit,
- // the value is here. This covers digits which do not form decimal radix forms, such as the compatibility superscript digits.
- //
- // An example is: U+2460 IRCLED DIGIT ONE. This character has digit value 1, but does not have associcated decimal digit value.
- //
- //Returns:
- // the digit value for the specified Unicode character. If the character does not have a digit value, the return value is -1.
- //Arguments:
- // ch a Unicode character
- //Exceptions:
- // ArgumentNullException
- // ArgumentOutOfRangeException
- //
- ////////////////////////////////////////////////////////////////////////
-
-
- public static int GetDigitValue(char ch) {
- return (InternalGetDigitValue(ch));
+ public static int GetDigitValue(char ch)
+ {
+ return (sbyte)(InternalGetDigitValues(ch) & 0x00FF);
}
-
- public static int GetDigitValue(String s, int index) {
- if (s == null) {
+ public static int GetDigitValue(String s, int index)
+ {
+ if (s == null)
+ {
throw new ArgumentNullException(nameof(s));
}
- if (index < 0 || index >= s.Length) {
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+
+ if (index < 0 || index >= s.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
}
+
Contract.EndContractBlock();
- return (InternalGetDigitValue(InternalConvertToUtf32(s, index)));
+ return (sbyte)(InternalGetDigitValues(InternalConvertToUtf32(s, index)) & 0x00FF);
}
public static UnicodeCategory GetUnicodeCategory(char ch)
{
- return (InternalGetUnicodeCategory(ch)) ;
+ return (InternalGetUnicodeCategory(ch));
}
public static UnicodeCategory GetUnicodeCategory(String s, int index)
{
- if (s==null)
+ if (s == null)
throw new ArgumentNullException(nameof(s));
- if (((uint)index)>=((uint)s.Length)) {
+ if (((uint)index) >= ((uint)s.Length))
+ {
throw new ArgumentOutOfRangeException(nameof(index));
}
Contract.EndContractBlock();
return InternalGetUnicodeCategory(s, index);
}
- internal unsafe static UnicodeCategory InternalGetUnicodeCategory(int ch) {
+ internal static unsafe UnicodeCategory InternalGetUnicodeCategory(int ch)
+ {
return ((UnicodeCategory)InternalGetCategoryValue(ch, UNICODE_CATEGORY_OFFSET));
}
+
////////////////////////////////////////////////////////////////////////
//
//Action: Returns the Unicode Category property for the character c.
@@ -432,37 +315,28 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
- internal unsafe static byte InternalGetCategoryValue(int ch, int offset) {
+ internal static unsafe byte InternalGetCategoryValue(int ch, int offset)
+ {
Debug.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range.");
// Get the level 2 item from the highest 12 bit (8 - 19) of ch.
ushort index = s_pCategoryLevel1Index[ch >> 8];
// Get the level 2 WORD offset from the 4 - 7 bit of ch. This provides the base offset of the level 3 table.
// Note that & has the lower precedence than addition, so don't forget the parathesis.
index = s_pCategoryLevel1Index[index + ((ch >> 4) & 0x000f)];
- byte* pBytePtr = (byte*)&(s_pCategoryLevel1Index[index]);
- // Get the result from the 0 -3 bit of ch.
- byte valueIndex = pBytePtr[(ch & 0x000f)];
- byte uc = s_pCategoriesValue[valueIndex * 2 + offset];
- //
- // Make sure that OtherNotAssigned is the last category in UnicodeCategory.
- // If that changes, change the following assertion as well.
- //
- //Debug.Assert(uc >= 0 && uc <= UnicodeCategory.OtherNotAssigned, "Table returns incorrect Unicode category");
- return (uc);
- }
-// internal static BidiCategory GetBidiCategory(char ch) {
-// return ((BidiCategory)InternalGetCategoryValue(c, BIDI_CATEGORY_OFFSET));
-// }
-
- internal static BidiCategory GetBidiCategory(String s, int index) {
- if (s==null)
- throw new ArgumentNullException(nameof(s));
- if (((uint)index)>=((uint)s.Length)) {
- throw new ArgumentOutOfRangeException(nameof(index));
+ fixed (ushort* pUshortPtr = &(s_pCategoryLevel1Index[index]))
+ {
+ byte* pBytePtr = (byte*)pUshortPtr;
+ // Get the result from the 0 -3 bit of ch.
+ byte valueIndex = pBytePtr[(ch & 0x000f)];
+ byte uc = s_pCategoriesValue[valueIndex * 2 + offset];
+ //
+ // Make sure that OtherNotAssigned is the last category in UnicodeCategory.
+ // If that changes, change the following assertion as well.
+ //
+ //Debug.Assert(uc >= 0 && uc <= UnicodeCategory.OtherNotAssigned, "Table returns incorrect Unicode category");
+ return (uc);
}
- Contract.EndContractBlock();
- return ((BidiCategory)InternalGetCategoryValue(InternalConvertToUtf32(s, index), BIDI_CATEGORY_OFFSET));
}
////////////////////////////////////////////////////////////////////////
@@ -478,13 +352,27 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
- internal static UnicodeCategory InternalGetUnicodeCategory(String value, int index) {
+ internal static UnicodeCategory InternalGetUnicodeCategory(String value, int index)
+ {
Debug.Assert(value != null, "value can not be null");
Debug.Assert(index < value.Length, "index < value.Length");
return (InternalGetUnicodeCategory(InternalConvertToUtf32(value, index)));
}
+ internal static BidiCategory GetBidiCategory(String s, int index)
+ {
+ if (s == null)
+ throw new ArgumentNullException(nameof(s));
+
+ if (((uint)index) >= ((uint)s.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(index));
+ }
+
+ return ((BidiCategory) InternalGetCategoryValue(InternalConvertToUtf32(s, index), BIDI_CATEGORY_OFFSET));
+ }
+
////////////////////////////////////////////////////////////////////////
//
// Get the Unicode category of the character starting at index. If the character is in BMP, charLength will return 1.
@@ -492,15 +380,17 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
- internal static UnicodeCategory InternalGetUnicodeCategory(String str, int index, out int charLength) {
+ internal static UnicodeCategory InternalGetUnicodeCategory(String str, int index, out int charLength)
+ {
Debug.Assert(str != null, "str can not be null");
- Debug.Assert(str.Length > 0, "str.Length > 0");;
+ Debug.Assert(str.Length > 0, "str.Length > 0"); ;
Debug.Assert(index >= 0 && index < str.Length, "index >= 0 && index < str.Length");
return (InternalGetUnicodeCategory(InternalConvertToUtf32(str, index, out charLength)));
}
- internal static bool IsCombiningCategory(UnicodeCategory uc) {
+ internal static bool IsCombiningCategory(UnicodeCategory uc)
+ {
Debug.Assert(uc >= 0, "uc >= 0");
return (
uc == UnicodeCategory.NonSpacingMark ||
diff --git a/src/mscorlib/corefx/System/Globalization/CharUnicodeInfoData.cs b/src/mscorlib/src/System/Globalization/CharUnicodeInfoData.cs
index b1bef8146e..b1bef8146e 100644
--- a/src/mscorlib/corefx/System/Globalization/CharUnicodeInfoData.cs
+++ b/src/mscorlib/src/System/Globalization/CharUnicodeInfoData.cs
diff --git a/src/mscorlib/src/System/Globalization/ChineseLunisolarCalendar.cs b/src/mscorlib/src/System/Globalization/ChineseLunisolarCalendar.cs
deleted file mode 100644
index 374ed0dcfa..0000000000
--- a/src/mscorlib/src/System/Globalization/ChineseLunisolarCalendar.cs
+++ /dev/null
@@ -1,397 +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.
-
-namespace System.Globalization {
- using System;
- using System.Diagnostics.Contracts;
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about ChineseLunisolarCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
- /*
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 1901/02/19 2101/01/28
- ** ChineseLunisolar 1901/01/01 2100/12/29
- */
-
- [Serializable]
- public class ChineseLunisolarCalendar : EastAsianLunisolarCalendar {
-
-
- //
- // The era value for the current era.
- //
-
- public const int ChineseEra = 1;
- //internal static Calendar m_defaultInstance;
-
- internal const int MIN_LUNISOLAR_YEAR = 1901;
- internal const int MAX_LUNISOLAR_YEAR = 2100;
-
- internal const int MIN_GREGORIAN_YEAR = 1901;
- internal const int MIN_GREGORIAN_MONTH = 2;
- internal const int MIN_GREGORIAN_DAY = 19;
-
- internal const int MAX_GREGORIAN_YEAR = 2101;
- internal const int MAX_GREGORIAN_MONTH = 1;
- internal const int MAX_GREGORIAN_DAY = 28;
-
- internal static DateTime minDate = new DateTime(MIN_GREGORIAN_YEAR, MIN_GREGORIAN_MONTH, MIN_GREGORIAN_DAY);
- internal static DateTime maxDate = new DateTime((new DateTime(MAX_GREGORIAN_YEAR, MAX_GREGORIAN_MONTH, MAX_GREGORIAN_DAY, 23, 59, 59, 999)).Ticks + 9999);
-
- public override DateTime MinSupportedDateTime {
- get
- {
- return (minDate);
- }
- }
-
-
- public override DateTime MaxSupportedDateTime {
- get
- {
- return (maxDate);
- }
- }
-
- protected override int DaysInYearBeforeMinSupportedYear
- {
- get
- {
- // 1900: 1-29 2-30 3-29 4-29 5-30 6-29 7-30 8-30 Leap8-29 9-30 10-30 11-29 12-30 from Calendrical Tabulations
- return 384;
- }
- }
-
-
- static readonly int [,] yinfo =
- {
- /*Y LM Lmon Lday DaysPerMonth D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 #Days
-1901 */{ 0 , 2 , 19 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1902 */{ 0 , 2 , 8 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1903 */{ 5 , 1 , 29 , 21096 },/* 29 30 29 30 29 29 30 29 29 30 30 29 30 383
-1904 */{ 0 , 2 , 16 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1905 */{ 0 , 2 , 4 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1906 */{ 4 , 1 , 25 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
-1907 */{ 0 , 2 , 13 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1908 */{ 0 , 2 , 2 , 39632 },/* 30 29 29 30 30 29 30 29 30 30 29 30 0 355
-1909 */{ 2 , 1 , 22 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1910 */{ 0 , 2 , 10 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1911 */{ 6 , 1 , 30 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1912 */{ 0 , 2 , 18 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1913 */{ 0 , 2 , 6 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1914 */{ 5 , 1 , 26 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
-1915 */{ 0 , 2 , 14 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1916 */{ 0 , 2 , 3 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 0 355
-1917 */{ 2 , 1 , 23 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1918 */{ 0 , 2 , 11 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1919 */{ 7 , 2 , 1 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1920 */{ 0 , 2 , 20 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1921 */{ 0 , 2 , 8 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1922 */{ 5 , 1 , 28 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1923 */{ 0 , 2 , 16 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1924 */{ 0 , 2 , 5 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1925 */{ 4 , 1 , 24 , 44456 },/* 30 29 30 29 30 30 29 30 30 29 30 29 30 385
-1926 */{ 0 , 2 , 13 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1927 */{ 0 , 2 , 2 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 0 355
-1928 */{ 2 , 1 , 23 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
-1929 */{ 0 , 2 , 10 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1930 */{ 6 , 1 , 30 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
-1931 */{ 0 , 2 , 17 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1932 */{ 0 , 2 , 6 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-1933 */{ 5 , 1 , 26 , 27976 },/* 29 30 30 29 30 30 29 30 29 30 29 29 30 384
-1934 */{ 0 , 2 , 14 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
-1935 */{ 0 , 2 , 4 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1936 */{ 3 , 1 , 24 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
-1937 */{ 0 , 2 , 11 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1938 */{ 7 , 1 , 31 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-1939 */{ 0 , 2 , 19 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
-1940 */{ 0 , 2 , 8 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1941 */{ 6 , 1 , 27 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1942 */{ 0 , 2 , 15 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1943 */{ 0 , 2 , 5 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1944 */{ 4 , 1 , 25 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
-1945 */{ 0 , 2 , 13 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1946 */{ 0 , 2 , 2 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-1947 */{ 2 , 1 , 22 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-1948 */{ 0 , 2 , 10 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1949 */{ 7 , 1 , 29 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-1950 */{ 0 , 2 , 17 , 27808 },/* 29 30 30 29 30 30 29 29 30 29 30 29 0 354
-1951 */{ 0 , 2 , 6 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1952 */{ 5 , 1 , 27 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-1953 */{ 0 , 2 , 14 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
-1954 */{ 0 , 2 , 3 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-1955 */{ 3 , 1 , 24 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1956 */{ 0 , 2 , 12 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1957 */{ 8 , 1 , 31 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 29 383
-1958 */{ 0 , 2 , 18 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
-1959 */{ 0 , 2 , 8 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1960 */{ 6 , 1 , 28 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1961 */{ 0 , 2 , 15 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1962 */{ 0 , 2 , 5 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1963 */{ 4 , 1 , 25 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1964 */{ 0 , 2 , 13 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1965 */{ 0 , 2 , 2 , 21088 },/* 29 30 29 30 29 29 30 29 29 30 30 29 0 353
-1966 */{ 3 , 1 , 21 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-1967 */{ 0 , 2 , 9 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1968 */{ 7 , 1 , 30 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1969 */{ 0 , 2 , 17 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1970 */{ 0 , 2 , 6 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-1971 */{ 5 , 1 , 27 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1972 */{ 0 , 2 , 15 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
-1973 */{ 0 , 2 , 3 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1974 */{ 4 , 1 , 23 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1975 */{ 0 , 2 , 11 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1976 */{ 8 , 1 , 31 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
-1977 */{ 0 , 2 , 18 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1978 */{ 0 , 2 , 7 , 46752 },/* 30 29 30 30 29 30 30 29 30 29 30 29 0 355
-1979 */{ 6 , 1 , 28 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1980 */{ 0 , 2 , 16 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1981 */{ 0 , 2 , 5 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1982 */{ 4 , 1 , 25 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-1983 */{ 0 , 2 , 13 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1984 */{ 10 , 2 , 2 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1985 */{ 0 , 2 , 20 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1986 */{ 0 , 2 , 9 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1987 */{ 6 , 1 , 29 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 29 384
-1988 */{ 0 , 2 , 17 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1989 */{ 0 , 2 , 6 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 0 355
-1990 */{ 5 , 1 , 27 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
-1991 */{ 0 , 2 , 15 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1992 */{ 0 , 2 , 4 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1993 */{ 3 , 1 , 23 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1994 */{ 0 , 2 , 10 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-1995 */{ 8 , 1 , 31 , 27432 },/* 29 30 30 29 30 29 30 30 29 29 30 29 30 384
-1996 */{ 0 , 2 , 19 , 23232 },/* 29 30 29 30 30 29 30 29 30 30 29 29 0 354
-1997 */{ 0 , 2 , 7 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1998 */{ 5 , 1 , 28 , 37736 },/* 30 29 29 30 29 29 30 30 29 30 30 29 30 384
-1999 */{ 0 , 2 , 16 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-2000 */{ 0 , 2 , 5 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-2001 */{ 4 , 1 , 24 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-2002 */{ 0 , 2 , 12 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-2003 */{ 0 , 2 , 1 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-2004 */{ 2 , 1 , 22 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-2005 */{ 0 , 2 , 9 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-2006 */{ 7 , 1 , 29 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
-2007 */{ 0 , 2 , 18 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-2008 */{ 0 , 2 , 7 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-2009 */{ 5 , 1 , 26 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-2010 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-2011 */{ 0 , 2 , 3 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-2012 */{ 4 , 1 , 23 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-2013 */{ 0 , 2 , 10 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2014 */{ 9 , 1 , 31 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-2015 */{ 0 , 2 , 19 , 19360 },/* 29 30 29 29 30 29 30 30 30 29 30 29 0 354
-2016 */{ 0 , 2 , 8 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-2017 */{ 6 , 1 , 28 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-2018 */{ 0 , 2 , 16 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-2019 */{ 0 , 2 , 5 , 43312 },/* 30 29 30 29 30 29 29 30 29 29 30 30 0 354
-2020 */{ 4 , 1 , 25 , 29864 },/* 29 30 30 30 29 30 29 29 30 29 30 29 30 384
-2021 */{ 0 , 2 , 12 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-2022 */{ 0 , 2 , 1 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2023 */{ 2 , 1 , 22 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
-2024 */{ 0 , 2 , 10 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-2025 */{ 6 , 1 , 29 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-2026 */{ 0 , 2 , 17 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
-2027 */{ 0 , 2 , 6 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-2028 */{ 5 , 1 , 26 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-2029 */{ 0 , 2 , 13 , 54576 },/* 30 30 29 30 29 30 29 30 29 29 30 30 0 355
-2030 */{ 0 , 2 , 3 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-2031 */{ 3 , 1 , 23 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
-2032 */{ 0 , 2 , 11 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-2033 */{ 11 , 1 , 31 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-2034 */{ 0 , 2 , 19 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
-2035 */{ 0 , 2 , 8 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-2036 */{ 6 , 1 , 28 , 53848 },/* 30 30 29 30 29 29 30 29 29 30 29 30 30 384
-2037 */{ 0 , 2 , 15 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-2038 */{ 0 , 2 , 4 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
-2039 */{ 5 , 1 , 24 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 29 384
-2040 */{ 0 , 2 , 12 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
-2041 */{ 0 , 2 , 1 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-2042 */{ 2 , 1 , 22 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
-2043 */{ 0 , 2 , 10 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-2044 */{ 7 , 1 , 30 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-2045 */{ 0 , 2 , 17 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-2046 */{ 0 , 2 , 6 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-2047 */{ 5 , 1 , 26 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-2048 */{ 0 , 2 , 14 , 27936 },/* 29 30 30 29 30 30 29 30 29 29 30 29 0 354
-2049 */{ 0 , 2 , 2 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
-2050 */{ 3 , 1 , 23 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-2051 */{ 0 , 2 , 11 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-2052 */{ 8 , 2 , 1 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
-2053 */{ 0 , 2 , 19 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-2054 */{ 0 , 2 , 8 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-2055 */{ 6 , 1 , 28 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-2056 */{ 0 , 2 , 15 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-2057 */{ 0 , 2 , 4 , 27424 },/* 29 30 30 29 30 29 30 30 29 29 30 29 0 354
-2058 */{ 4 , 1 , 24 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 29 384
-2059 */{ 0 , 2 , 12 , 43744 },/* 30 29 30 29 30 29 30 29 30 30 30 29 0 355
-2060 */{ 0 , 2 , 2 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-2061 */{ 3 , 1 , 21 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 29 384
-2062 */{ 0 , 2 , 9 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-2063 */{ 7 , 1 , 29 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-2064 */{ 0 , 2 , 17 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-2065 */{ 0 , 2 , 5 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-2066 */{ 5 , 1 , 26 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-2067 */{ 0 , 2 , 14 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-2068 */{ 0 , 2 , 3 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
-2069 */{ 4 , 1 , 23 , 21224 },/* 29 30 29 30 29 29 30 29 30 30 30 29 30 384
-2070 */{ 0 , 2 , 11 , 21200 },/* 29 30 29 30 29 29 30 29 30 30 29 30 0 354
-2071 */{ 8 , 1 , 31 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-2072 */{ 0 , 2 , 19 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-2073 */{ 0 , 2 , 7 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-2074 */{ 6 , 1 , 27 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-2075 */{ 0 , 2 , 15 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2076 */{ 0 , 2 , 5 , 21920 },/* 29 30 29 30 29 30 29 30 30 29 30 29 0 354
-2077 */{ 4 , 1 , 24 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 29 384
-2078 */{ 0 , 2 , 12 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-2079 */{ 0 , 2 , 2 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-2080 */{ 3 , 1 , 22 , 43320 },/* 30 29 30 29 30 29 29 30 29 29 30 30 30 384
-2081 */{ 0 , 2 , 9 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 0 354
-2082 */{ 7 , 1 , 29 , 29336 },/* 29 30 30 30 29 29 30 29 30 29 29 30 30 384
-2083 */{ 0 , 2 , 17 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-2084 */{ 0 , 2 , 6 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2085 */{ 5 , 1 , 26 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
-2086 */{ 0 , 2 , 14 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-2087 */{ 0 , 2 , 3 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-2088 */{ 4 , 1 , 24 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 29 383
-2089 */{ 0 , 2 , 10 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-2090 */{ 8 , 1 , 30 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-2091 */{ 0 , 2 , 18 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
-2092 */{ 0 , 2 , 7 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
-2093 */{ 6 , 1 , 27 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
-2094 */{ 0 , 2 , 15 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-2095 */{ 0 , 2 , 5 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-2096 */{ 4 , 1 , 25 , 42216 },/* 30 29 30 29 29 30 29 29 30 30 30 29 30 384
-2097 */{ 0 , 2 , 12 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-2098 */{ 0 , 2 , 1 , 53584 },/* 30 30 29 30 29 29 29 30 29 30 29 30 0 354
-2099 */{ 2 , 1 , 21 , 55592 },/* 30 30 29 30 30 29 29 30 29 29 30 29 30 384
-2100 */{ 0 , 2 , 9 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
- */};
-
-
- internal override int MinCalendarYear {
- get
- {
- return (MIN_LUNISOLAR_YEAR);
- }
- }
-
- internal override int MaxCalendarYear {
- get
- {
- return (MAX_LUNISOLAR_YEAR);
- }
- }
-
- internal override DateTime MinDate {
- get
- {
- return (minDate);
- }
- }
-
- internal override DateTime MaxDate {
- get
- {
- return (maxDate);
- }
- }
-
- internal override EraInfo[] CalEraInfo {
- get
- {
- return (null);
- }
- }
-
- internal override int GetYearInfo(int LunarYear, int Index) {
- if ((LunarYear < MIN_LUNISOLAR_YEAR) || (LunarYear > MAX_LUNISOLAR_YEAR)) {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"), MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR ));
- }
- Contract.EndContractBlock();
-
- return yinfo[LunarYear - MIN_LUNISOLAR_YEAR, Index];
- }
-
- internal override int GetYear(int year, DateTime time) {
- return year;
- }
-
- internal override int GetGregorianYear(int year, int era) {
- if (era != CurrentEra && era != ChineseEra) {
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
- }
-
- if (year < MIN_LUNISOLAR_YEAR || year > MAX_LUNISOLAR_YEAR) {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"), MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR));
- }
- Contract.EndContractBlock();
-
- return year;
- }
-
-
- /*=================================GetDefaultInstance==========================
- **Action: Internal method to provide a default intance of ChineseLunisolarCalendar. Used by NLS+ implementation
- ** and other calendars.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
-
- /*
- internal static Calendar GetDefaultInstance()
- {
- if (m_defaultInstance == null) {
- m_defaultInstance = new ChineseLunisolarCalendar();
- }
- return (m_defaultInstance);
- }
- */
-
- // Construct an instance of ChineseLunisolar calendar.
-
- public ChineseLunisolarCalendar() {
- }
-
-
- public override int GetEra(DateTime time) {
- CheckTicksRange(time.Ticks);
- return (ChineseEra);
- }
-
- internal override int ID {
- get {
- return (CAL_CHINESELUNISOLAR);
- }
- }
-
- internal override int BaseCalendarID {
- get {
- //Use CAL_GREGORIAN just to get CurrentEraValue as 1 since we do not have data under the ID CAL_ChineseLunisolar yet
- return (CAL_GREGORIAN);
- }
- }
-
-
- public override int[] Eras {
- get {
- return (new int[] {ChineseEra});
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/CompareInfo.Invariant.cs b/src/mscorlib/src/System/Globalization/CompareInfo.Invariant.cs
new file mode 100644
index 0000000000..2a20de76bb
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/CompareInfo.Invariant.cs
@@ -0,0 +1,238 @@
+// 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.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System.Globalization
+{
+ public partial class CompareInfo
+ {
+ internal static unsafe int InvariantIndexOf(string source, string value, int startIndex, int count, bool ignoreCase)
+ {
+ Debug.Assert(source != null);
+ Debug.Assert(value != null);
+ Debug.Assert(startIndex >= 0 && startIndex < source.Length);
+
+ fixed (char* pSource = source) fixed (char* pValue = value)
+ {
+ char* pSrc = &pSource[startIndex];
+ int index = InvariantFindString(pSrc, count, pValue, value.Length, ignoreCase, start : true);
+ if (index >= 0)
+ {
+ return index + startIndex;
+ }
+ return -1;
+ }
+ }
+
+ internal static unsafe int InvariantLastIndexOf(string source, string value, int startIndex, int count, bool ignoreCase)
+ {
+ Debug.Assert(source != null);
+ Debug.Assert(value != null);
+ Debug.Assert(startIndex >= 0 && startIndex < source.Length);
+
+ fixed (char* pSource = source) fixed (char* pValue = value)
+ {
+ char* pSrc = &pSource[startIndex - count + 1];
+ int index = InvariantFindString(pSrc, count, pValue, value.Length, ignoreCase, start : false);
+ if (index >= 0)
+ {
+ return index + startIndex - count + 1;
+ }
+ return -1;
+ }
+ }
+
+ private static unsafe int InvariantFindString(char* source, int sourceCount, char* value, int valueCount, bool ignoreCase, bool start)
+ {
+ int ctrSource = 0; // index value into source
+ int ctrValue = 0; // index value into value
+ char sourceChar; // Character for case lookup in source
+ char valueChar; // Character for case lookup in value
+ int lastSourceStart;
+
+ Debug.Assert(source != null);
+ Debug.Assert(value != null);
+ Debug.Assert(sourceCount >= 0);
+ Debug.Assert(valueCount >= 0);
+
+ if (valueCount == 0)
+ {
+ return start ? 0 : sourceCount - 1;
+ }
+
+ if (sourceCount < valueCount)
+ {
+ return -1;
+ }
+
+ if (start)
+ {
+ lastSourceStart = sourceCount - valueCount;
+ if (ignoreCase)
+ {
+ char firstValueChar = InvariantToUpper(value[0]);
+ for (ctrSource = 0; ctrSource <= lastSourceStart; ctrSource++)
+ {
+ sourceChar = InvariantToUpper(source[ctrSource]);
+ if (sourceChar != firstValueChar)
+ {
+ continue;
+ }
+
+ for (ctrValue = 1; ctrValue < valueCount; ctrValue++)
+ {
+ sourceChar = InvariantToUpper(source[ctrSource + ctrValue]);
+ valueChar = InvariantToUpper(value[ctrValue]);
+
+ if (sourceChar != valueChar)
+ {
+ break;
+ }
+ }
+
+ if (ctrValue == valueCount)
+ {
+ return ctrSource;
+ }
+ }
+ }
+ else
+ {
+ char firstValueChar = value[0];
+ for (ctrSource = 0; ctrSource <= lastSourceStart; ctrSource++)
+ {
+ sourceChar = source[ctrSource];
+ if (sourceChar != firstValueChar)
+ {
+ continue;
+ }
+
+ for (ctrValue = 1; ctrValue < valueCount; ctrValue++)
+ {
+ sourceChar = source[ctrSource + ctrValue];
+ valueChar = value[ctrValue];
+
+ if (sourceChar != valueChar)
+ {
+ break;
+ }
+ }
+
+ if (ctrValue == valueCount)
+ {
+ return ctrSource;
+ }
+ }
+ }
+ }
+ else
+ {
+ lastSourceStart = sourceCount - valueCount;
+ if (ignoreCase)
+ {
+ char firstValueChar = InvariantToUpper(value[0]);
+ for (ctrSource = lastSourceStart; ctrSource >= 0; ctrSource--)
+ {
+ sourceChar = InvariantToUpper(source[ctrSource]);
+ if (sourceChar != firstValueChar)
+ {
+ continue;
+ }
+ for (ctrValue = 1; ctrValue < valueCount; ctrValue++)
+ {
+ sourceChar = InvariantToUpper(source[ctrSource + ctrValue]);
+ valueChar = InvariantToUpper(value[ctrValue]);
+
+ if (sourceChar != valueChar)
+ {
+ break;
+ }
+ }
+
+ if (ctrValue == valueCount)
+ {
+ return ctrSource;
+ }
+ }
+ }
+ else
+ {
+ char firstValueChar = value[0];
+ for (ctrSource = lastSourceStart; ctrSource >= 0; ctrSource--)
+ {
+ sourceChar = source[ctrSource];
+ if (sourceChar != firstValueChar)
+ {
+ continue;
+ }
+
+ for (ctrValue = 1; ctrValue < valueCount; ctrValue++)
+ {
+ sourceChar = source[ctrSource + ctrValue];
+ valueChar = value[ctrValue];
+
+ if (sourceChar != valueChar)
+ {
+ break;
+ }
+ }
+
+ if (ctrValue == valueCount)
+ {
+ return ctrSource;
+ }
+ }
+ }
+ }
+
+ return -1;
+ }
+
+ private static char InvariantToUpper(char c)
+ {
+ return (uint)(c - 'a') <= (uint)('z' - 'a') ? (char)(c - 0x20) : c;
+ }
+
+ private unsafe SortKey InvariantCreateSortKey(string source, CompareOptions options)
+ {
+ if (source == null) { throw new ArgumentNullException(nameof(source)); }
+ Contract.EndContractBlock();
+
+ if ((options & ValidSortkeyCtorMaskOffFlags) != 0)
+ {
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
+ }
+
+ byte [] keyData;
+ if (source.Length == 0)
+ {
+ keyData = Array.Empty<byte>();
+ }
+ else
+ {
+ // In the invariant mode, all string comparisons are done as ordinal so when generating the sort keys we generate it according to this fact
+ keyData = new byte[source.Length * sizeof(char)];
+
+ fixed (char* pChar = source) fixed (byte* pByte = keyData)
+ {
+ if ((options & (CompareOptions.IgnoreCase | CompareOptions.OrdinalIgnoreCase)) != 0)
+ {
+ short *pShort = (short *) pByte;
+ for (int i=0; i<source.Length; i++)
+ {
+ pShort[i] = (short) InvariantToUpper(source[i]);
+ }
+ }
+ else
+ {
+ Buffer.MemoryCopy(pChar, pByte, keyData.Length, keyData.Length);
+ }
+ }
+ }
+ return new SortKey(Name, source, options, keyData);
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/CompareInfo.Unix.cs b/src/mscorlib/src/System/Globalization/CompareInfo.Unix.cs
new file mode 100644
index 0000000000..edc9a7f575
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/CompareInfo.Unix.cs
@@ -0,0 +1,439 @@
+// 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.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Security;
+
+namespace System.Globalization
+{
+ public partial class CompareInfo
+ {
+ [NonSerialized]
+ private Interop.GlobalizationInterop.SafeSortHandle _sortHandle;
+
+ [NonSerialized]
+ private bool _isAsciiEqualityOrdinal;
+
+ private void InitSort(CultureInfo culture)
+ {
+ _sortName = culture.SortName;
+
+ if (_invariantMode)
+ {
+ _isAsciiEqualityOrdinal = true;
+ }
+ else
+ {
+ Interop.GlobalizationInterop.ResultCode resultCode = Interop.GlobalizationInterop.GetSortHandle(GetNullTerminatedUtf8String(_sortName), out _sortHandle);
+ if (resultCode != Interop.GlobalizationInterop.ResultCode.Success)
+ {
+ _sortHandle.Dispose();
+
+ if (resultCode == Interop.GlobalizationInterop.ResultCode.OutOfMemory)
+ throw new OutOfMemoryException();
+
+ throw new ExternalException(SR.Arg_ExternalException);
+ }
+ _isAsciiEqualityOrdinal = (_sortName == "en-US" || _sortName == "");
+ }
+ }
+
+ internal static unsafe int IndexOfOrdinalCore(string source, string value, int startIndex, int count, bool ignoreCase)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ Debug.Assert(source != null);
+ Debug.Assert(value != null);
+
+ if (value.Length == 0)
+ {
+ return startIndex;
+ }
+
+ if (count < value.Length)
+ {
+ return -1;
+ }
+
+ if (ignoreCase)
+ {
+ fixed (char* pSource = source)
+ {
+ int index = Interop.GlobalizationInterop.IndexOfOrdinalIgnoreCase(value, value.Length, pSource + startIndex, count, findLast: false);
+ return index != -1 ?
+ startIndex + index :
+ -1;
+ }
+ }
+
+ int endIndex = startIndex + (count - value.Length);
+ for (int i = startIndex; i <= endIndex; i++)
+ {
+ int valueIndex, sourceIndex;
+
+ for (valueIndex = 0, sourceIndex = i;
+ valueIndex < value.Length && source[sourceIndex] == value[valueIndex];
+ valueIndex++, sourceIndex++) ;
+
+ if (valueIndex == value.Length)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ internal static unsafe int LastIndexOfOrdinalCore(string source, string value, int startIndex, int count, bool ignoreCase)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ Debug.Assert(source != null);
+ Debug.Assert(value != null);
+
+ if (value.Length == 0)
+ {
+ return startIndex;
+ }
+
+ if (count < value.Length)
+ {
+ return -1;
+ }
+
+ // startIndex is the index into source where we start search backwards from.
+ // leftStartIndex is the index into source of the start of the string that is
+ // count characters away from startIndex.
+ int leftStartIndex = startIndex - count + 1;
+
+ if (ignoreCase)
+ {
+ fixed (char* pSource = source)
+ {
+ int lastIndex = Interop.GlobalizationInterop.IndexOfOrdinalIgnoreCase(value, value.Length, pSource + leftStartIndex, count, findLast: true);
+ return lastIndex != -1 ?
+ leftStartIndex + lastIndex :
+ -1;
+ }
+ }
+
+ for (int i = startIndex - value.Length + 1; i >= leftStartIndex; i--)
+ {
+ int valueIndex, sourceIndex;
+
+ for (valueIndex = 0, sourceIndex = i;
+ valueIndex < value.Length && source[sourceIndex] == value[valueIndex];
+ valueIndex++, sourceIndex++) ;
+
+ if (valueIndex == value.Length) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ private int GetHashCodeOfStringCore(string source, CompareOptions options)
+ {
+ Debug.Assert(source != null);
+ Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+
+ return GetHashCodeOfStringCore(source, options, forceRandomizedHashing: false, additionalEntropy: 0);
+ }
+
+ private static unsafe int CompareStringOrdinalIgnoreCase(char* string1, int count1, char* string2, int count2)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ return Interop.GlobalizationInterop.CompareStringOrdinalIgnoreCase(string1, count1, string2, count2);
+ }
+
+ private unsafe int CompareString(string string1, int offset1, int length1, string string2, int offset2, int length2, CompareOptions options)
+ {
+ Debug.Assert(!_invariantMode);
+
+ Debug.Assert(string1 != null);
+ Debug.Assert(string2 != null);
+ Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+
+ fixed (char* pString1 = string1)
+ {
+ fixed (char* pString2 = string2)
+ {
+ return Interop.GlobalizationInterop.CompareString(_sortHandle, pString1 + offset1, length1, pString2 + offset2, length2, options);
+ }
+ }
+ }
+
+ internal unsafe int IndexOfCore(string source, string target, int startIndex, int count, CompareOptions options, int* matchLengthPtr)
+ {
+ Debug.Assert(!_invariantMode);
+
+ Debug.Assert(!string.IsNullOrEmpty(source));
+ Debug.Assert(target != null);
+ Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
+
+ int index;
+
+ if (target.Length == 0)
+ {
+ if(matchLengthPtr != null)
+ *matchLengthPtr = 0;
+ return startIndex;
+ }
+
+ if (options == CompareOptions.Ordinal)
+ {
+ index = IndexOfOrdinal(source, target, startIndex, count, ignoreCase: false);
+ if(index != -1)
+ {
+ if(matchLengthPtr != null)
+ *matchLengthPtr = target.Length;
+ }
+ return index;
+ }
+
+ if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsFastSort() && target.IsFastSort())
+ {
+ index = IndexOf(source, target, startIndex, count, GetOrdinalCompareOptions(options));
+ if(index != -1)
+ {
+ if(matchLengthPtr != null)
+ *matchLengthPtr = target.Length;
+ }
+ return index;
+ }
+
+ fixed (char* pSource = source)
+ {
+ index = Interop.GlobalizationInterop.IndexOf(_sortHandle, target, target.Length, pSource + startIndex, count, options, matchLengthPtr);
+
+ return index != -1 ? index + startIndex : -1;
+ }
+ }
+
+ private unsafe int LastIndexOfCore(string source, string target, int startIndex, int count, CompareOptions options)
+ {
+ Debug.Assert(!_invariantMode);
+
+ Debug.Assert(!string.IsNullOrEmpty(source));
+ Debug.Assert(target != null);
+ Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
+
+ if (target.Length == 0)
+ {
+ return startIndex;
+ }
+
+ if (options == CompareOptions.Ordinal)
+ {
+ return LastIndexOfOrdinalCore(source, target, startIndex, count, ignoreCase: false);
+ }
+
+ if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsFastSort() && target.IsFastSort())
+ {
+ return LastIndexOf(source, target, startIndex, count, GetOrdinalCompareOptions(options));
+ }
+
+ // startIndex is the index into source where we start search backwards from. leftStartIndex is the index into source
+ // of the start of the string that is count characters away from startIndex.
+ int leftStartIndex = (startIndex - count + 1);
+
+ fixed (char* pSource = source)
+ {
+ int lastIndex = Interop.GlobalizationInterop.LastIndexOf(_sortHandle, target, target.Length, pSource + (startIndex - count + 1), count, options);
+
+ return lastIndex != -1 ? lastIndex + leftStartIndex : -1;
+ }
+ }
+
+ private bool StartsWith(string source, string prefix, CompareOptions options)
+ {
+ Debug.Assert(!_invariantMode);
+
+ Debug.Assert(!string.IsNullOrEmpty(source));
+ Debug.Assert(!string.IsNullOrEmpty(prefix));
+ Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+
+ if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsFastSort() && prefix.IsFastSort())
+ {
+ return IsPrefix(source, prefix, GetOrdinalCompareOptions(options));
+ }
+
+ return Interop.GlobalizationInterop.StartsWith(_sortHandle, prefix, prefix.Length, source, source.Length, options);
+ }
+
+ private bool EndsWith(string source, string suffix, CompareOptions options)
+ {
+ Debug.Assert(!_invariantMode);
+
+ Debug.Assert(!string.IsNullOrEmpty(source));
+ Debug.Assert(!string.IsNullOrEmpty(suffix));
+ Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+
+ if (_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsFastSort() && suffix.IsFastSort())
+ {
+ return IsSuffix(source, suffix, GetOrdinalCompareOptions(options));
+ }
+
+ return Interop.GlobalizationInterop.EndsWith(_sortHandle, suffix, suffix.Length, source, source.Length, options);
+ }
+
+ private unsafe SortKey CreateSortKey(String source, CompareOptions options)
+ {
+ Debug.Assert(!_invariantMode);
+
+ if (source==null) { throw new ArgumentNullException(nameof(source)); }
+ Contract.EndContractBlock();
+
+ if ((options & ValidSortkeyCtorMaskOffFlags) != 0)
+ {
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
+ }
+
+ byte [] keyData;
+ if (source.Length == 0)
+ {
+ keyData = Array.Empty<Byte>();
+ }
+ else
+ {
+ int sortKeyLength = Interop.GlobalizationInterop.GetSortKey(_sortHandle, source, source.Length, null, 0, options);
+ keyData = new byte[sortKeyLength];
+
+ fixed (byte* pSortKey = keyData)
+ {
+ Interop.GlobalizationInterop.GetSortKey(_sortHandle, source, source.Length, pSortKey, sortKeyLength, options);
+ }
+ }
+
+ return new SortKey(Name, source, options, keyData);
+ }
+
+ private unsafe static bool IsSortable(char *text, int length)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ int index = 0;
+ UnicodeCategory uc;
+
+ while (index < length)
+ {
+ if (Char.IsHighSurrogate(text[index]))
+ {
+ if (index == length - 1 || !Char.IsLowSurrogate(text[index+1]))
+ return false; // unpaired surrogate
+
+ uc = CharUnicodeInfo.InternalGetUnicodeCategory(Char.ConvertToUtf32(text[index], text[index+1]));
+ if (uc == UnicodeCategory.PrivateUse || uc == UnicodeCategory.OtherNotAssigned)
+ return false;
+
+ index += 2;
+ continue;
+ }
+
+ if (Char.IsLowSurrogate(text[index]))
+ {
+ return false; // unpaired surrogate
+ }
+
+ uc = CharUnicodeInfo.GetUnicodeCategory(text[index]);
+ if (uc == UnicodeCategory.PrivateUse || uc == UnicodeCategory.OtherNotAssigned)
+ {
+ return false;
+ }
+
+ index++;
+ }
+
+ return true;
+ }
+
+ // -----------------------------
+ // ---- PAL layer ends here ----
+ // -----------------------------
+
+ internal unsafe int GetHashCodeOfStringCore(string source, CompareOptions options, bool forceRandomizedHashing, long additionalEntropy)
+ {
+ Debug.Assert(!_invariantMode);
+
+ Debug.Assert(source != null);
+ Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+
+ if (source.Length == 0)
+ {
+ return 0;
+ }
+
+ int sortKeyLength = Interop.GlobalizationInterop.GetSortKey(_sortHandle, source, source.Length, null, 0, options);
+
+ // As an optimization, for small sort keys we allocate the buffer on the stack.
+ if (sortKeyLength <= 256)
+ {
+ byte* pSortKey = stackalloc byte[sortKeyLength];
+ Interop.GlobalizationInterop.GetSortKey(_sortHandle, source, source.Length, pSortKey, sortKeyLength, options);
+ return InternalHashSortKey(pSortKey, sortKeyLength, false, additionalEntropy);
+ }
+
+ byte[] sortKey = new byte[sortKeyLength];
+
+ fixed (byte* pSortKey = sortKey)
+ {
+ Interop.GlobalizationInterop.GetSortKey(_sortHandle, source, source.Length, pSortKey, sortKeyLength, options);
+ return InternalHashSortKey(pSortKey, sortKeyLength, false, additionalEntropy);
+ }
+ }
+
+ [DllImport(JitHelpers.QCall)]
+ [SuppressUnmanagedCodeSecurity]
+ private static unsafe extern int InternalHashSortKey(byte* sortKey, int sortKeyLength, [MarshalAs(UnmanagedType.Bool)] bool forceRandomizedHashing, long additionalEntropy);
+
+ private static CompareOptions GetOrdinalCompareOptions(CompareOptions options)
+ {
+ if ((options & CompareOptions.IgnoreCase) == CompareOptions.IgnoreCase)
+ {
+ return CompareOptions.OrdinalIgnoreCase;
+ }
+ else
+ {
+ return CompareOptions.Ordinal;
+ }
+ }
+
+ private static bool CanUseAsciiOrdinalForOptions(CompareOptions options)
+ {
+ // Unlike the other Ignore options, IgnoreSymbols impacts ASCII characters (e.g. ').
+ return (options & CompareOptions.IgnoreSymbols) == 0;
+ }
+
+ private static byte[] GetNullTerminatedUtf8String(string s)
+ {
+ int byteLen = System.Text.Encoding.UTF8.GetByteCount(s);
+
+ // Allocate an extra byte (which defaults to 0) as the null terminator.
+ byte[] buffer = new byte[byteLen + 1];
+
+ int bytesWritten = System.Text.Encoding.UTF8.GetBytes(s, 0, s.Length, buffer, 0);
+
+ Debug.Assert(bytesWritten == byteLen);
+
+ return buffer;
+ }
+
+ private SortVersion GetSortVersion()
+ {
+ Debug.Assert(!_invariantMode);
+
+ int sortVersion = Interop.GlobalizationInterop.GetSortVersion();
+ return new SortVersion(sortVersion, LCID, new Guid(sortVersion, 0, 0, 0, 0, 0, 0,
+ (byte) (LCID >> 24),
+ (byte) ((LCID & 0x00FF0000) >> 16),
+ (byte) ((LCID & 0x0000FF00) >> 8),
+ (byte) (LCID & 0xFF)));
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/CompareInfo.Windows.cs b/src/mscorlib/src/System/Globalization/CompareInfo.Windows.cs
new file mode 100644
index 0000000000..d20bb9f9f3
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/CompareInfo.Windows.cs
@@ -0,0 +1,486 @@
+// 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.Security;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+
+namespace System.Globalization
+{
+ public partial class CompareInfo
+ {
+ private unsafe void InitSort(CultureInfo culture)
+ {
+ _sortName = culture.SortName;
+
+ _name = culture._name;
+ _sortName = culture.SortName;
+
+ if (_invariantMode)
+ {
+ _sortHandle = IntPtr.Zero;
+ }
+ else
+ {
+ const uint LCMAP_SORTHANDLE = 0x20000000;
+ IntPtr handle;
+ int ret = Interop.Kernel32.LCMapStringEx(_sortName, LCMAP_SORTHANDLE, null, 0, &handle, IntPtr.Size, null, null, IntPtr.Zero);
+ _sortHandle = ret > 0 ? handle : IntPtr.Zero;
+ }
+ }
+
+ private static unsafe int FindStringOrdinal(
+ uint dwFindStringOrdinalFlags,
+ string stringSource,
+ int offset,
+ int cchSource,
+ string value,
+ int cchValue,
+ bool bIgnoreCase)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ fixed (char* pSource = stringSource)
+ fixed (char* pValue = value)
+ {
+ int ret = Interop.Kernel32.FindStringOrdinal(
+ dwFindStringOrdinalFlags,
+ pSource + offset,
+ cchSource,
+ pValue,
+ cchValue,
+ bIgnoreCase ? 1 : 0);
+ return ret < 0 ? ret : ret + offset;
+ }
+ }
+
+ internal static int IndexOfOrdinalCore(string source, string value, int startIndex, int count, bool ignoreCase)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ Debug.Assert(source != null);
+ Debug.Assert(value != null);
+
+ return FindStringOrdinal(FIND_FROMSTART, source, startIndex, count, value, value.Length, ignoreCase);
+ }
+
+ internal static int LastIndexOfOrdinalCore(string source, string value, int startIndex, int count, bool ignoreCase)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ Debug.Assert(source != null);
+ Debug.Assert(value != null);
+
+ return FindStringOrdinal(FIND_FROMEND, source, startIndex - count + 1, count, value, value.Length, ignoreCase);
+ }
+
+ private unsafe int GetHashCodeOfStringCore(string source, CompareOptions options)
+ {
+ Debug.Assert(!_invariantMode);
+
+ Debug.Assert(source != null);
+ Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+
+ if (source.Length == 0)
+ {
+ return 0;
+ }
+
+ int flags = GetNativeCompareFlags(options);
+ int tmpHash = 0;
+#if CORECLR
+ tmpHash = InternalGetGlobalizedHashCode(_sortHandle, _sortName, source, source.Length, flags, 0);
+#else
+ fixed (char* pSource = source)
+ {
+ if (Interop.Kernel32.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _sortName,
+ LCMAP_HASH | (uint)flags,
+ pSource, source.Length,
+ &tmpHash, sizeof(int),
+ null, null, _sortHandle) == 0)
+ {
+ Environment.FailFast("LCMapStringEx failed!");
+ }
+ }
+#endif
+ return tmpHash;
+ }
+
+ private static unsafe int CompareStringOrdinalIgnoreCase(char* string1, int count1, char* string2, int count2)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ // Use the OS to compare and then convert the result to expected value by subtracting 2
+ return Interop.Kernel32.CompareStringOrdinal(string1, count1, string2, count2, true) - 2;
+ }
+
+ private unsafe int CompareString(string string1, int offset1, int length1, string string2, int offset2, int length2, CompareOptions options)
+ {
+ Debug.Assert(!_invariantMode);
+
+ Debug.Assert(string1 != null);
+ Debug.Assert(string2 != null);
+ Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+
+ string localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
+
+ fixed (char* pLocaleName = localeName)
+ fixed (char* pString1 = string1)
+ fixed (char* pString2 = string2)
+ {
+ int result = Interop.Kernel32.CompareStringEx(
+ pLocaleName,
+ (uint)GetNativeCompareFlags(options),
+ pString1 + offset1,
+ length1,
+ pString2 + offset2,
+ length2,
+ null,
+ null,
+ _sortHandle);
+
+ if (result == 0)
+ {
+ Environment.FailFast("CompareStringEx failed");
+ }
+
+ // Map CompareStringEx return value to -1, 0, 1.
+ return result - 2;
+ }
+ }
+
+ private unsafe int FindString(
+ uint dwFindNLSStringFlags,
+ string lpStringSource,
+ int startSource,
+ int cchSource,
+ string lpStringValue,
+ int startValue,
+ int cchValue,
+ int *pcchFound)
+ {
+ Debug.Assert(!_invariantMode);
+
+ string localeName = _sortHandle != IntPtr.Zero ? null : _sortName;
+
+ fixed (char* pLocaleName = localeName)
+ fixed (char* pSource = lpStringSource)
+ fixed (char* pValue = lpStringValue)
+ {
+ char* pS = pSource + startSource;
+ char* pV = pValue + startValue;
+
+ return Interop.Kernel32.FindNLSStringEx(
+ pLocaleName,
+ dwFindNLSStringFlags,
+ pS,
+ cchSource,
+ pV,
+ cchValue,
+ pcchFound,
+ null,
+ null,
+ _sortHandle);
+ }
+ }
+
+ internal unsafe int IndexOfCore(String source, String target, int startIndex, int count, CompareOptions options, int* matchLengthPtr)
+ {
+ Debug.Assert(!_invariantMode);
+
+ Debug.Assert(source != null);
+ Debug.Assert(target != null);
+ Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
+
+ if (target.Length == 0)
+ {
+ if (matchLengthPtr != null)
+ *matchLengthPtr = 0;
+ return 0;
+ }
+
+ if (source.Length == 0)
+ {
+ return -1;
+ }
+
+ if ((options & CompareOptions.Ordinal) != 0)
+ {
+ int retValue = FastIndexOfString(source, target, startIndex, count, target.Length, findLastIndex: false);
+ if (retValue >= 0)
+ {
+ if (matchLengthPtr != null)
+ *matchLengthPtr = target.Length;
+ }
+ return retValue;
+ }
+ else
+ {
+ int retValue = FindString(FIND_FROMSTART | (uint)GetNativeCompareFlags(options), source, startIndex, count,
+ target, 0, target.Length, matchLengthPtr);
+ if (retValue >= 0)
+ {
+ return retValue + startIndex;
+ }
+ }
+
+ return -1;
+ }
+
+ private unsafe int LastIndexOfCore(string source, string target, int startIndex, int count, CompareOptions options)
+ {
+ Debug.Assert(!_invariantMode);
+
+ Debug.Assert(!string.IsNullOrEmpty(source));
+ Debug.Assert(target != null);
+ Debug.Assert((options & CompareOptions.OrdinalIgnoreCase) == 0);
+
+ // TODO: Consider moving this up to the relevent APIs we need to ensure this behavior for
+ // and add a precondition that target is not empty.
+ if (target.Length == 0)
+ return startIndex; // keep Whidbey compatibility
+
+ if ((options & CompareOptions.Ordinal) != 0)
+ {
+ return FastIndexOfString(source, target, startIndex, count, target.Length, findLastIndex: true);
+ }
+ else
+ {
+ int retValue = FindString(FIND_FROMEND | (uint) GetNativeCompareFlags(options), source, startIndex - count + 1,
+ count, target, 0, target.Length, null);
+
+ if (retValue >= 0)
+ {
+ return retValue + startIndex - (count - 1);
+ }
+ }
+
+ return -1;
+ }
+
+ private unsafe bool StartsWith(string source, string prefix, CompareOptions options)
+ {
+ Debug.Assert(!_invariantMode);
+
+ Debug.Assert(!string.IsNullOrEmpty(source));
+ Debug.Assert(!string.IsNullOrEmpty(prefix));
+ Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+
+ return FindString(FIND_STARTSWITH | (uint)GetNativeCompareFlags(options), source, 0, source.Length,
+ prefix, 0, prefix.Length, null) >= 0;
+ }
+
+ private unsafe bool EndsWith(string source, string suffix, CompareOptions options)
+ {
+ Debug.Assert(!_invariantMode);
+
+ Debug.Assert(!string.IsNullOrEmpty(source));
+ Debug.Assert(!string.IsNullOrEmpty(suffix));
+ Debug.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0);
+
+ return FindString(FIND_ENDSWITH | (uint)GetNativeCompareFlags(options), source, 0, source.Length,
+ suffix, 0, suffix.Length, null) >= 0;
+ }
+
+ // PAL ends here
+ [NonSerialized]
+ private IntPtr _sortHandle;
+
+ private const uint LCMAP_SORTKEY = 0x00000400;
+ private const uint LCMAP_HASH = 0x00040000;
+
+ private const int FIND_STARTSWITH = 0x00100000;
+ private const int FIND_ENDSWITH = 0x00200000;
+ private const int FIND_FROMSTART = 0x00400000;
+ private const int FIND_FROMEND = 0x00800000;
+
+ // TODO: Instead of this method could we just have upstack code call IndexOfOrdinal with ignoreCase = false?
+ private static unsafe int FastIndexOfString(string source, string target, int startIndex, int sourceCount, int targetCount, bool findLastIndex)
+ {
+ int retValue = -1;
+
+ int sourceStartIndex = findLastIndex ? startIndex - sourceCount + 1 : startIndex;
+
+ fixed (char* pSource = source, spTarget = target)
+ {
+ char* spSubSource = pSource + sourceStartIndex;
+
+ if (findLastIndex)
+ {
+ int startPattern = (sourceCount - 1) - targetCount + 1;
+ if (startPattern < 0)
+ return -1;
+
+ char patternChar0 = spTarget[0];
+ for (int ctrSrc = startPattern; ctrSrc >= 0; ctrSrc--)
+ {
+ if (spSubSource[ctrSrc] != patternChar0)
+ continue;
+
+ int ctrPat;
+ for (ctrPat = 1; ctrPat < targetCount; ctrPat++)
+ {
+ if (spSubSource[ctrSrc + ctrPat] != spTarget[ctrPat])
+ break;
+ }
+ if (ctrPat == targetCount)
+ {
+ retValue = ctrSrc;
+ break;
+ }
+ }
+
+ if (retValue >= 0)
+ {
+ retValue += startIndex - sourceCount + 1;
+ }
+ }
+ else
+ {
+ int endPattern = (sourceCount - 1) - targetCount + 1;
+ if (endPattern < 0)
+ return -1;
+
+ char patternChar0 = spTarget[0];
+ for (int ctrSrc = 0; ctrSrc <= endPattern; ctrSrc++)
+ {
+ if (spSubSource[ctrSrc] != patternChar0)
+ continue;
+ int ctrPat;
+ for (ctrPat = 1; ctrPat < targetCount; ctrPat++)
+ {
+ if (spSubSource[ctrSrc + ctrPat] != spTarget[ctrPat])
+ break;
+ }
+ if (ctrPat == targetCount)
+ {
+ retValue = ctrSrc;
+ break;
+ }
+ }
+
+ if (retValue >= 0)
+ {
+ retValue += startIndex;
+ }
+ }
+ }
+
+ return retValue;
+ }
+
+ private unsafe SortKey CreateSortKey(String source, CompareOptions options)
+ {
+ Debug.Assert(!_invariantMode);
+
+ if (source == null) { throw new ArgumentNullException(nameof(source)); }
+ Contract.EndContractBlock();
+
+ if ((options & ValidSortkeyCtorMaskOffFlags) != 0)
+ {
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
+ }
+
+ byte [] keyData = null;
+ if (source.Length == 0)
+ {
+ keyData = Array.Empty<byte>();
+ }
+ else
+ {
+ fixed (char *pSource = source)
+ {
+ int result = Interop.Kernel32.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _sortName,
+ LCMAP_SORTKEY | (uint) GetNativeCompareFlags(options),
+ pSource, source.Length,
+ null, 0,
+ null, null, _sortHandle);
+ if (result == 0)
+ {
+ throw new ArgumentException(SR.Argument_InvalidFlag, "source");
+ }
+
+ keyData = new byte[result];
+
+ fixed (byte* pBytes = keyData)
+ {
+ result = Interop.Kernel32.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _sortName,
+ LCMAP_SORTKEY | (uint) GetNativeCompareFlags(options),
+ pSource, source.Length,
+ pBytes, keyData.Length,
+ null, null, _sortHandle);
+ }
+ }
+ }
+
+ return new SortKey(Name, source, options, keyData);
+ }
+
+ private static unsafe bool IsSortable(char* text, int length)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ return Interop.Kernel32.IsNLSDefinedString(Interop.Kernel32.COMPARE_STRING, 0, IntPtr.Zero, text, length);
+ }
+
+ private const int COMPARE_OPTIONS_ORDINAL = 0x40000000; // Ordinal
+ private const int NORM_IGNORECASE = 0x00000001; // Ignores case. (use LINGUISTIC_IGNORECASE instead)
+ private const int NORM_IGNOREKANATYPE = 0x00010000; // Does not differentiate between Hiragana and Katakana characters. Corresponding Hiragana and Katakana will compare as equal.
+ private const int NORM_IGNORENONSPACE = 0x00000002; // Ignores nonspacing. This flag also removes Japanese accent characters. (use LINGUISTIC_IGNOREDIACRITIC instead)
+ private const int NORM_IGNORESYMBOLS = 0x00000004; // Ignores symbols.
+ private const int NORM_IGNOREWIDTH = 0x00020000; // Does not differentiate between a single-byte character and the same character as a double-byte character.
+ private const int NORM_LINGUISTIC_CASING = 0x08000000; // use linguistic rules for casing
+ private const int SORT_STRINGSORT = 0x00001000; // Treats punctuation the same as symbols.
+
+ private static int GetNativeCompareFlags(CompareOptions options)
+ {
+ // Use "linguistic casing" by default (load the culture's casing exception tables)
+ int nativeCompareFlags = NORM_LINGUISTIC_CASING;
+
+ if ((options & CompareOptions.IgnoreCase) != 0) { nativeCompareFlags |= NORM_IGNORECASE; }
+ if ((options & CompareOptions.IgnoreKanaType) != 0) { nativeCompareFlags |= NORM_IGNOREKANATYPE; }
+ if ((options & CompareOptions.IgnoreNonSpace) != 0) { nativeCompareFlags |= NORM_IGNORENONSPACE; }
+ if ((options & CompareOptions.IgnoreSymbols) != 0) { nativeCompareFlags |= NORM_IGNORESYMBOLS; }
+ if ((options & CompareOptions.IgnoreWidth) != 0) { nativeCompareFlags |= NORM_IGNOREWIDTH; }
+ if ((options & CompareOptions.StringSort) != 0) { nativeCompareFlags |= SORT_STRINGSORT; }
+
+ // TODO: Can we try for GetNativeCompareFlags to never
+ // take Ordinal or OrdinalIgnoreCase. This value is not part of Win32, we just handle it special
+ // in some places.
+ // Suffix & Prefix shouldn't use this, make sure to turn off the NORM_LINGUISTIC_CASING flag
+ if (options == CompareOptions.Ordinal) { nativeCompareFlags = COMPARE_OPTIONS_ORDINAL; }
+
+ Debug.Assert(((options & ~(CompareOptions.IgnoreCase |
+ CompareOptions.IgnoreKanaType |
+ CompareOptions.IgnoreNonSpace |
+ CompareOptions.IgnoreSymbols |
+ CompareOptions.IgnoreWidth |
+ CompareOptions.StringSort)) == 0) ||
+ (options == CompareOptions.Ordinal), "[CompareInfo.GetNativeCompareFlags]Expected all flags to be handled");
+
+ return nativeCompareFlags;
+ }
+
+ private unsafe SortVersion GetSortVersion()
+ {
+ Debug.Assert(!_invariantMode);
+
+ Interop.Kernel32.NlsVersionInfoEx nlsVersion = new Interop.Kernel32.NlsVersionInfoEx();
+ Interop.Kernel32.GetNLSVersionEx(Interop.Kernel32.COMPARE_STRING, _sortName, &nlsVersion);
+ return new SortVersion(
+ nlsVersion.dwNLSVersion,
+ nlsVersion.dwEffectiveId == 0 ? LCID : nlsVersion.dwEffectiveId,
+ nlsVersion.guidCustomVersion);
+ }
+
+#if CORECLR
+ // Get a locale sensitive sort hash code from native code -- COMNlsInfo::InternalGetGlobalizedHashCode
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern int InternalGetGlobalizedHashCode(IntPtr handle, string localeName, string source, int length, int dwFlags, long additionalEntropy);
+#endif
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/CompareInfo.cs b/src/mscorlib/src/System/Globalization/CompareInfo.cs
index 6c2230b66b..285a81d906 100644
--- a/src/mscorlib/src/System/Globalization/CompareInfo.cs
+++ b/src/mscorlib/src/System/Globalization/CompareInfo.cs
@@ -12,57 +12,28 @@
//
////////////////////////////////////////////////////////////////////////////
-namespace System.Globalization {
-
- //
- // We pass all of the sorting calls to the native side, preferrably to the OS to do
- // the actual work.
- //
-
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Reflection;
- using System.Runtime.Serialization;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
- using System.Threading;
- using Microsoft.Win32;
- using System.Security;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- //
- // Options can be used during string comparison.
- //
- // Native implementation (COMNlsInfo.cpp & SortingTable.cpp) relies on the values of these,
- // If you change the values below, be sure to change the values in native part as well.
- //
-
-
-[Serializable]
+using System.Reflection;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+
+namespace System.Globalization
+{
[Flags]
+ [Serializable]
public enum CompareOptions
{
- None = 0x00000000,
- IgnoreCase = 0x00000001,
- IgnoreNonSpace = 0x00000002,
- IgnoreSymbols = 0x00000004,
- IgnoreKanaType = 0x00000008, // ignore kanatype
- IgnoreWidth = 0x00000010, // ignore width
- OrdinalIgnoreCase = 0x10000000, // This flag can not be used with other flags.
- StringSort = 0x20000000, // use string sort method
- Ordinal = 0x40000000, // This flag can not be used with other flags.
-
- // StopOnNull = 0x10000000,
-
- // StopOnNull is defined in SortingTable.h, but we didn't enable this option here.
- // Do not use this value for other flags accidentally.
+ None = 0x00000000,
+ IgnoreCase = 0x00000001,
+ IgnoreNonSpace = 0x00000002,
+ IgnoreSymbols = 0x00000004,
+ IgnoreKanaType = 0x00000008, // ignore kanatype
+ IgnoreWidth = 0x00000010, // ignore width
+ OrdinalIgnoreCase = 0x10000000, // This flag can not be used with other flags.
+ StringSort = 0x20000000, // use string sort method
+ Ordinal = 0x40000000, // This flag can not be used with other flags.
}
-
[Serializable]
public partial class CompareInfo : IDeserializationCallback
{
@@ -81,6 +52,11 @@ namespace System.Globalization {
~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace |
CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType);
+ // Mask used to check if we have the right flags.
+ private const CompareOptions ValidSortkeyCtorMaskOffFlags =
+ ~(CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace |
+ CompareOptions.IgnoreWidth | CompareOptions.IgnoreKanaType | CompareOptions.StringSort);
+
//
// CompareInfos have an interesting identity. They are attached to the locale that created them,
// ie: en-US would have an en-US sort. For haw-US (custom), then we serialize it as haw-US.
@@ -88,33 +64,21 @@ namespace System.Globalization {
// locale, which is what SCOMPAREINFO does.
[OptionalField(VersionAdded = 2)]
- private String m_name; // The name used to construct this CompareInfo
-
+ private string _name; // The name used to construct this CompareInfo
[NonSerialized]
- private String m_sortName; // The name that defines our behavior
+ private string _sortName; // The name that defines our behavior
- [NonSerialized]
- private IntPtr m_dataHandle;
+ [OptionalField(VersionAdded = 3)]
+ private SortVersion _sortVersion;
- [NonSerialized]
- private IntPtr m_handleOrigin;
+ // _invariantMode is defined for the perf reason as accessing the instance field is faster than access the static property GlobalizationMode.Invariant
+ [NonSerialized]
+ private readonly bool _invariantMode = GlobalizationMode.Invariant;
- ////////////////////////////////////////////////////////////////////////
- //
- // CompareInfo Constructor
- //
- //
- ////////////////////////////////////////////////////////////////////////
- // Constructs an instance that most closely corresponds to the NLS locale
- // identifier.
internal CompareInfo(CultureInfo culture)
{
- this.m_name = culture.m_name;
- this.m_sortName = culture.SortName;
-
- IntPtr handleOrigin;
- this.m_dataHandle = InternalInitSortHandle(m_sortName, out handleOrigin);
- this.m_handleOrigin = handleOrigin;
+ _name = culture._name;
+ InitSort(culture);
}
/*=================================GetCompareInfo==========================
@@ -122,49 +86,52 @@ namespace System.Globalization {
** Warning: The assembly versioning mechanism is dead!
**Returns: The CompareInfo for the specified culture.
**Arguments:
- ** culture the ID of the culture
+ ** culture the ID of the culture
** assembly the assembly which contains the sorting table.
**Exceptions:
** ArugmentNullException when the assembly is null
** ArgumentException if culture is invalid.
============================================================================*/
-#if FEATURE_USE_LCID
// Assembly constructor should be deprecated, we don't act on the assembly information any more
- public static CompareInfo GetCompareInfo(int culture, Assembly assembly){
+ public static CompareInfo GetCompareInfo(int culture, Assembly assembly)
+ {
// Parameter checking.
- if (assembly == null) {
+ if (assembly == null)
+ {
throw new ArgumentNullException(nameof(assembly));
}
- if (assembly!=typeof(Object).Module.Assembly) {
- throw new ArgumentException(Environment.GetResourceString("Argument_OnlyMscorlib"));
+ if (assembly != typeof(Object).Module.Assembly)
+ {
+ throw new ArgumentException(SR.Argument_OnlyMscorlib);
}
Contract.EndContractBlock();
return GetCompareInfo(culture);
}
-#endif
-
/*=================================GetCompareInfo==========================
**Action: Get the CompareInfo constructed from the data table in the specified assembly for the specified culture.
** The purpose of this method is to provide version for CompareInfo tables.
**Returns: The CompareInfo for the specified culture.
**Arguments:
- ** name the name of the culture
- ** assembly the assembly which contains the sorting table.
+ ** name the name of the culture
+ ** assembly the assembly which contains the sorting table.
**Exceptions:
** ArugmentNullException when the assembly is null
** ArgumentException if name is invalid.
============================================================================*/
// Assembly constructor should be deprecated, we don't act on the assembly information any more
- public static CompareInfo GetCompareInfo(String name, Assembly assembly){
- if (name == null || assembly == null) {
+ public static CompareInfo GetCompareInfo(string name, Assembly assembly)
+ {
+ if (name == null || assembly == null)
+ {
throw new ArgumentNullException(name == null ? nameof(name) : nameof(assembly));
}
Contract.EndContractBlock();
- if (assembly!=typeof(Object).Module.Assembly) {
- throw new ArgumentException(Environment.GetResourceString("Argument_OnlyMscorlib"));
+ if (assembly != typeof(Object).Module.Assembly)
+ {
+ throw new ArgumentException(SR.Argument_OnlyMscorlib);
}
return GetCompareInfo(name);
@@ -179,20 +146,17 @@ namespace System.Globalization {
**Exceptions:
** ArgumentException if culture is invalid.
============================================================================*/
-
-#if FEATURE_USE_LCID
// People really shouldn't be calling LCID versions, no custom support
public static CompareInfo GetCompareInfo(int culture)
{
if (CultureData.IsCustomCultureId(culture))
{
// Customized culture cannot be created by the LCID.
- throw new ArgumentException(Environment.GetResourceString("Argument_CustomCultureCannotBePassedByNumber", nameof(culture)));
+ throw new ArgumentException(SR.Argument_CustomCultureCannotBePassedByNumber, nameof(culture));
}
return CultureInfo.GetCultureInfo(culture).CompareInfo;
}
-#endif
/*=================================GetCompareInfo==========================
**Action: Get the CompareInfo for the specified culture.
@@ -203,7 +167,7 @@ namespace System.Globalization {
** ArgumentException if name is invalid.
============================================================================*/
- public static CompareInfo GetCompareInfo(String name)
+ public static CompareInfo GetCompareInfo(string name)
{
if (name == null)
{
@@ -214,64 +178,51 @@ namespace System.Globalization {
return CultureInfo.GetCultureInfo(name).CompareInfo;
}
- public static bool IsSortable(char ch) {
- return(IsSortable(ch.ToString()));
+ public static unsafe bool IsSortable(char ch)
+ {
+ if (GlobalizationMode.Invariant)
+ {
+ return true;
+ }
+ char *pChar = &ch;
+ return IsSortable(pChar, 1);
}
- public static bool IsSortable(String text) {
- if (text == null) {
+ public static unsafe bool IsSortable(string text)
+ {
+ if (text == null)
+ {
// A null param is invalid here.
throw new ArgumentNullException(nameof(text));
}
- if (0 == text.Length) {
+ if (text.Length == 0)
+ {
// A zero length string is not invalid, but it is also not sortable.
- return(false);
+ return (false);
}
- CompareInfo c = CultureInfo.InvariantCulture.CompareInfo;
-
- return (InternalIsSortable(c.m_dataHandle, c.m_handleOrigin, c.m_sortName, text, text.Length));
+ if (GlobalizationMode.Invariant)
+ {
+ return true;
+ }
+
+ fixed (char *pChar = text)
+ {
+ return IsSortable(pChar, text.Length);
+ }
}
-#region Serialization
- // the following fields are defined to keep the compatibility with Whidbey.
- // don't change/remove the names/types of these fields.
-#if FEATURE_USE_LCID
- [OptionalField(VersionAdded = 1)]
- private int win32LCID; // mapped sort culture id of this instance
- private int culture; // the culture ID used to create this instance.
-#endif
[OnDeserializing]
private void OnDeserializing(StreamingContext ctx)
{
- this.m_name = null;
+ _name = null;
}
- private void OnDeserialized()
+ void IDeserializationCallback.OnDeserialization(Object sender)
{
- CultureInfo ci;
- // If we didn't have a name, use the LCID
- if (this.m_name == null)
- {
-#if FEATURE_USE_LCID
- // From whidbey, didn't have a name
- ci = CultureInfo.GetCultureInfo(this.culture);
- this.m_name = ci.m_name;
- this.m_sortName = ci.SortName;
-#endif
- }
- else
- {
- ci = CultureInfo.GetCultureInfo(m_name);
- this.m_sortName = ci.SortName;
- }
-
- IntPtr handleOrigin;
- this.m_dataHandle = InternalInitSortHandle(m_sortName, out handleOrigin);
- this.m_handleOrigin = handleOrigin;
-
+ OnDeserialized();
}
[OnDeserialized]
@@ -280,23 +231,16 @@ namespace System.Globalization {
OnDeserialized();
}
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx)
- {
-#if FEATURE_USE_LCID
- // This is merely for serialization compatibility with Whidbey/Orcas, it can go away when we don't want that compat any more.
- culture = CultureInfo.GetCultureInfo(this.Name).LCID; // This is the lcid of the constructing culture (still have to dereference to get target sort)
- Debug.Assert(m_name != null, "CompareInfo.OnSerializing - expected m_name to be set already");
-#endif
- }
-
- void IDeserializationCallback.OnDeserialization(Object sender)
+ private void OnDeserialized()
{
- OnDeserialized();
+ if (_name != null)
+ {
+ InitSort(CultureInfo.GetCultureInfo(_name));
+ }
}
-#endregion Serialization
-
+ [OnSerializing]
+ private void OnSerializing(StreamingContext ctx) { }
///////////////////////////----- Name -----/////////////////////////////////
//
@@ -311,65 +255,20 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
- public virtual String Name
+ public virtual string Name
{
get
{
- Debug.Assert(m_name != null, "CompareInfo.Name Expected m_name to be set");
- return (m_sortName);
- }
- }
+ Debug.Assert(_name != null, "CompareInfo.Name Expected _name to be set");
+ if (_name == "zh-CHT" || _name == "zh-CHS")
+ {
+ return _name;
+ }
- // These flags are used in the native Win32. so we need to map the managed options to those flags
- private const int LINGUISTIC_IGNORECASE = 0x00000010; // linguistically appropriate 'ignore case'
- private const int NORM_IGNORECASE = 0x00000001; // Ignores case. (use LINGUISTIC_IGNORECASE instead)
- private const int NORM_IGNOREKANATYPE = 0x00010000; // Does not differentiate between Hiragana and Katakana characters. Corresponding Hiragana and Katakana will compare as equal.
- private const int LINGUISTIC_IGNOREDIACRITIC = 0x00000020; // linguistically appropriate 'ignore nonspace'
- private const int NORM_IGNORENONSPACE = 0x00000002; // Ignores nonspacing. This flag also removes Japanese accent characters. (use LINGUISTIC_IGNOREDIACRITIC instead)
- private const int NORM_IGNORESYMBOLS = 0x00000004; // Ignores symbols.
- private const int NORM_IGNOREWIDTH = 0x00020000; // Does not differentiate between a single-byte character and the same character as a double-byte character.
- private const int SORT_STRINGSORT = 0x00001000; // Treats punctuation the same as symbols.
- private const int COMPARE_OPTIONS_ORDINAL = 0x40000000; // Ordinal (handled by Comnlsinfo)
- internal const int NORM_LINGUISTIC_CASING = 0x08000000; // use linguistic rules for casing
-
-
- private const int RESERVED_FIND_ASCII_STRING = 0x20000000; // This flag used only to tell the sorting DLL can assume the string characters are in ASCII.
-
- [Pure]
- internal static int GetNativeCompareFlags(CompareOptions options)
- {
- // some NLS VM functions can handle COMPARE_OPTIONS_ORDINAL
- // in which case options should be simply cast to int instead of using this function
- // Does not look like the best approach to me but for now I am going to leave it as it is
- Debug.Assert(options != CompareOptions.OrdinalIgnoreCase, "[CompareInfo.GetNativeCompareFlags]CompareOptions.OrdinalIgnoreCase should be handled separately");
-
- // Use "linguistic casing" by default (load the culture's casing exception tables)
- int nativeCompareFlags = NORM_LINGUISTIC_CASING;
-
- if ((options & CompareOptions.IgnoreCase) != 0) { nativeCompareFlags |= NORM_IGNORECASE; }
- if ((options & CompareOptions.IgnoreKanaType) != 0) { nativeCompareFlags |= NORM_IGNOREKANATYPE; }
- if ((options & CompareOptions.IgnoreNonSpace) != 0) { nativeCompareFlags |= NORM_IGNORENONSPACE; }
- if ((options & CompareOptions.IgnoreSymbols) != 0) { nativeCompareFlags |= NORM_IGNORESYMBOLS; }
- if ((options & CompareOptions.IgnoreWidth) != 0) { nativeCompareFlags |= NORM_IGNOREWIDTH; }
- if ((options & CompareOptions.StringSort) != 0) { nativeCompareFlags |= SORT_STRINGSORT; }
-
- // Suffix & Prefix shouldn't use this, make sure to turn off the NORM_LINGUISTIC_CASING flag
- if (options == CompareOptions.Ordinal) { nativeCompareFlags = COMPARE_OPTIONS_ORDINAL; }
-
- Debug.Assert(((options & ~(CompareOptions.IgnoreCase |
- CompareOptions.IgnoreKanaType |
- CompareOptions.IgnoreNonSpace |
- CompareOptions.IgnoreSymbols |
- CompareOptions.IgnoreWidth |
- CompareOptions.StringSort)) == 0) ||
- (options == CompareOptions.Ordinal), "[CompareInfo.GetNativeCompareFlags]Expected all flags to be handled");
-
- Debug.Assert((nativeCompareFlags & RESERVED_FIND_ASCII_STRING) == 0, "[CompareInfo.GetNativeCompareFlags] RESERVED_FIND_ASCII_STRING shouldn't be set here");
-
- return nativeCompareFlags;
+ return _sortName;
+ }
}
-
////////////////////////////////////////////////////////////////////////
//
// Compare
@@ -381,14 +280,13 @@ namespace System.Globalization {
//
////////////////////////////////////////////////////////////////////////
-
- public virtual int Compare(String string1, String string2)
+ public virtual int Compare(string string1, string string2)
{
return (Compare(string1, string2, CompareOptions.None));
}
- public unsafe virtual int Compare(String string1, String string2, CompareOptions options){
-
+ public unsafe virtual int Compare(string string1, string string2, CompareOptions options)
+ {
if (options == CompareOptions.OrdinalIgnoreCase)
{
return String.Compare(string1, string2, StringComparison.OrdinalIgnoreCase);
@@ -399,29 +297,41 @@ namespace System.Globalization {
{
if (options != CompareOptions.Ordinal)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_CompareOptionOrdinal"), nameof(options));
- }
+ throw new ArgumentException(SR.Argument_CompareOptionOrdinal, nameof(options));
+ }
+
return String.CompareOrdinal(string1, string2);
- }
+ }
if ((options & ValidCompareMaskOffFlags) != 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
}
//Our paradigm is that null sorts less than any other string and
//that two nulls sort as equal.
- if (string1 == null) {
- if (string2 == null) {
+ if (string1 == null)
+ {
+ if (string2 == null)
+ {
return (0); // Equal
}
return (-1); // null < non-null
}
- if (string2 == null) {
+ if (string2 == null)
+ {
return (1); // non-null > null
}
- return InternalCompareString(m_dataHandle, m_handleOrigin, m_sortName, string1, 0, string1.Length, string2, 0, string2.Length, GetNativeCompareFlags(options));
+ if (_invariantMode)
+ {
+ if ((options & CompareOptions.IgnoreCase) != 0)
+ return CompareOrdinalIgnoreCase(string1, 0, string1.Length, string2, 0, string2.Length);
+
+ return String.CompareOrdinal(string1, string2);
+ }
+
+ return CompareString(string1, 0, string1.Length, string2, 0, string2.Length, options);
}
@@ -438,63 +348,63 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
- public unsafe virtual int Compare(String string1, int offset1, int length1, String string2, int offset2, int length2)
+ public unsafe virtual int Compare(string string1, int offset1, int length1, string string2, int offset2, int length2)
{
return Compare(string1, offset1, length1, string2, offset2, length2, 0);
}
- public unsafe virtual int Compare(String string1, int offset1, String string2, int offset2, CompareOptions options)
+ public virtual int Compare(string string1, int offset1, string string2, int offset2, CompareOptions options)
{
- return Compare(string1, offset1, string1 == null ? 0 : string1.Length-offset1,
- string2, offset2, string2 == null ? 0 : string2.Length-offset2, options);
+ return Compare(string1, offset1, string1 == null ? 0 : string1.Length - offset1,
+ string2, offset2, string2 == null ? 0 : string2.Length - offset2, options);
}
- public unsafe virtual int Compare(String string1, int offset1, String string2, int offset2)
+ public virtual int Compare(string string1, int offset1, string string2, int offset2)
{
return Compare(string1, offset1, string2, offset2, 0);
}
- public unsafe virtual int Compare(String string1, int offset1, int length1, String string2, int offset2, int length2, CompareOptions options)
+ public virtual int Compare(string string1, int offset1, int length1, string string2, int offset2, int length2, CompareOptions options)
{
if (options == CompareOptions.OrdinalIgnoreCase)
{
- int result = String.Compare(string1, offset1, string2, offset2, length1<length2 ? length1 : length2, StringComparison.OrdinalIgnoreCase);
+ int result = String.Compare(string1, offset1, string2, offset2, length1 < length2 ? length1 : length2, StringComparison.OrdinalIgnoreCase);
if ((length1 != length2) && result == 0)
- return (length1 > length2? 1: -1);
+ return (length1 > length2 ? 1 : -1);
return (result);
}
// Verify inputs
if (length1 < 0 || length2 < 0)
{
- throw new ArgumentOutOfRangeException((length1 < 0) ? nameof(length1) : nameof(length2), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ throw new ArgumentOutOfRangeException((length1 < 0) ? nameof(length1) : nameof(length2), SR.ArgumentOutOfRange_NeedPosNum);
}
if (offset1 < 0 || offset2 < 0)
{
- throw new ArgumentOutOfRangeException((offset1 < 0) ? nameof(offset1) : nameof(offset2), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ throw new ArgumentOutOfRangeException((offset1 < 0) ? nameof(offset1) : nameof(offset2), SR.ArgumentOutOfRange_NeedPosNum);
}
if (offset1 > (string1 == null ? 0 : string1.Length) - length1)
{
- throw new ArgumentOutOfRangeException(nameof(string1), Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
+ throw new ArgumentOutOfRangeException(nameof(string1), SR.ArgumentOutOfRange_OffsetLength);
}
if (offset2 > (string2 == null ? 0 : string2.Length) - length2)
{
- throw new ArgumentOutOfRangeException(nameof(string2), Environment.GetResourceString("ArgumentOutOfRange_OffsetLength"));
+ throw new ArgumentOutOfRangeException(nameof(string2), SR.ArgumentOutOfRange_OffsetLength);
}
if ((options & CompareOptions.Ordinal) != 0)
{
if (options != CompareOptions.Ordinal)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_CompareOptionOrdinal"),
+ throw new ArgumentException(SR.Argument_CompareOptionOrdinal,
nameof(options));
}
}
else if ((options & ValidCompareMaskOffFlags) != 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
}
//
@@ -515,12 +425,89 @@ namespace System.Globalization {
if (options == CompareOptions.Ordinal)
{
- return string.CompareOrdinalHelper(string1, offset1, length1, string2, offset2, length2);
+ return CompareOrdinal(string1, offset1, length1,
+ string2, offset2, length2);
+ }
+
+ if (_invariantMode)
+ {
+ if ((options & CompareOptions.IgnoreCase) != 0)
+ return CompareOrdinalIgnoreCase(string1, offset1, length1, string2, offset2, length2);
+
+ return CompareOrdinal(string1, offset1, length1, string2, offset2, length2);
+ }
+
+ return CompareString(string1, offset1, length1,
+ string2, offset2, length2,
+ options);
+ }
+
+ private static int CompareOrdinal(string string1, int offset1, int length1, string string2, int offset2, int length2)
+ {
+ int result = String.CompareOrdinal(string1, offset1, string2, offset2,
+ (length1 < length2 ? length1 : length2));
+ if ((length1 != length2) && result == 0)
+ {
+ return (length1 > length2 ? 1 : -1);
+ }
+ return (result);
+ }
+
+ //
+ // CompareOrdinalIgnoreCase compare two string ordinally with ignoring the case.
+ // it assumes the strings are Ascii string till we hit non Ascii character in strA or strB and then we continue the comparison by
+ // calling the OS.
+ //
+ internal static unsafe int CompareOrdinalIgnoreCase(string strA, int indexA, int lengthA, string strB, int indexB, int lengthB)
+ {
+ Debug.Assert(indexA + lengthA <= strA.Length);
+ Debug.Assert(indexB + lengthB <= strB.Length);
+
+ int length = Math.Min(lengthA, lengthB);
+ int range = length;
+
+ fixed (char* ap = strA) fixed (char* bp = strB)
+ {
+ char* a = ap + indexA;
+ char* b = bp + indexB;
+
+ // in InvariantMode we support all range and not only the ascii characters.
+ char maxChar = (char) (GlobalizationMode.Invariant ? 0xFFFF : 0x80);
+
+ while (length != 0 && (*a <= maxChar) && (*b <= maxChar))
+ {
+ int charA = *a;
+ int charB = *b;
+
+ if (charA == charB)
+ {
+ a++; b++;
+ length--;
+ continue;
+ }
+
+ // uppercase both chars - notice that we need just one compare per char
+ if ((uint)(charA - 'a') <= (uint)('z' - 'a')) charA -= 0x20;
+ if ((uint)(charB - 'a') <= (uint)('z' - 'a')) charB -= 0x20;
+
+ // Return the (case-insensitive) difference between them.
+ if (charA != charB)
+ return charA - charB;
+
+ // Next char
+ a++; b++;
+ length--;
+ }
+
+ if (length == 0)
+ return lengthA - lengthB;
+
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ range -= length;
+
+ return CompareStringOrdinalIgnoreCase(a, lengthA - range, b, lengthB - range);
}
- return InternalCompareString(this.m_dataHandle, this.m_handleOrigin, this.m_sortName,
- string1, offset1, length1,
- string2, offset2, length2,
- GetNativeCompareFlags(options));
}
////////////////////////////////////////////////////////////////////////
@@ -531,22 +518,25 @@ namespace System.Globalization {
// String.Empty, true is returned.
//
////////////////////////////////////////////////////////////////////////
-
-
- public unsafe virtual bool IsPrefix(String source, String prefix, CompareOptions options)
+ public virtual bool IsPrefix(string source, string prefix, CompareOptions options)
{
- if (source == null || prefix == null) {
+ if (source == null || prefix == null)
+ {
throw new ArgumentNullException((source == null ? nameof(source) : nameof(prefix)),
- Environment.GetResourceString("ArgumentNull_String"));
+ SR.ArgumentNull_String);
}
Contract.EndContractBlock();
- int prefixLen = prefix.Length;
- if (prefixLen == 0)
+ if (prefix.Length == 0)
{
return (true);
}
+ if (source.Length == 0)
+ {
+ return false;
+ }
+
if (options == CompareOptions.OrdinalIgnoreCase)
{
return source.StartsWith(prefix, StringComparison.OrdinalIgnoreCase);
@@ -557,26 +547,24 @@ namespace System.Globalization {
return source.StartsWith(prefix, StringComparison.Ordinal);
}
- if ((options & ValidIndexMaskOffFlags) != 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
+ if ((options & ValidIndexMaskOffFlags) != 0)
+ {
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
}
+ if (_invariantMode)
+ {
+ return source.StartsWith(prefix, (options & CompareOptions.IgnoreCase) != 0 ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
+ }
- // to let the sorting DLL do the call optimization in case of Ascii strings, we check if the strings are in Ascii and then send the flag RESERVED_FIND_ASCII_STRING to
- // the sorting DLL API SortFindString so sorting DLL don't have to check if the string is Ascii with every call to SortFindString.
-
- return (InternalFindNLSStringEx(
- m_dataHandle, m_handleOrigin, m_sortName,
- GetNativeCompareFlags(options) | Win32Native.FIND_STARTSWITH | ((source.IsAscii() && prefix.IsAscii()) ? RESERVED_FIND_ASCII_STRING : 0),
- source, source.Length, 0, prefix, prefix.Length) > -1);
+ return StartsWith(source, prefix, options);
}
- public virtual bool IsPrefix(String source, String prefix)
+ public virtual bool IsPrefix(string source, string prefix)
{
return (IsPrefix(source, prefix, 0));
}
-
////////////////////////////////////////////////////////////////////////
//
// IsSuffix
@@ -585,44 +573,50 @@ namespace System.Globalization {
// String.Empty, true is returned.
//
////////////////////////////////////////////////////////////////////////
-
-
- public unsafe virtual bool IsSuffix(String source, String suffix, CompareOptions options)
+ public virtual bool IsSuffix(string source, string suffix, CompareOptions options)
{
- if (source == null || suffix == null) {
+ if (source == null || suffix == null)
+ {
throw new ArgumentNullException((source == null ? nameof(source) : nameof(suffix)),
- Environment.GetResourceString("ArgumentNull_String"));
+ SR.ArgumentNull_String);
}
Contract.EndContractBlock();
- int suffixLen = suffix.Length;
- if (suffixLen == 0)
+ if (suffix.Length == 0)
{
return (true);
}
- if (options == CompareOptions.OrdinalIgnoreCase) {
+ if (source.Length == 0)
+ {
+ return false;
+ }
+
+ if (options == CompareOptions.OrdinalIgnoreCase)
+ {
return source.EndsWith(suffix, StringComparison.OrdinalIgnoreCase);
}
- if (options == CompareOptions.Ordinal) {
+ if (options == CompareOptions.Ordinal)
+ {
return source.EndsWith(suffix, StringComparison.Ordinal);
}
- if ((options & ValidIndexMaskOffFlags) != 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
+ if ((options & ValidIndexMaskOffFlags) != 0)
+ {
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
+ }
+
+ if (_invariantMode)
+ {
+ return source.EndsWith(suffix, (options & CompareOptions.IgnoreCase) != 0 ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal);
}
- // to let the sorting DLL do the call optimization in case of Ascii strings, we check if the strings are in Ascii and then send the flag RESERVED_FIND_ASCII_STRING to
- // the sorting DLL API SortFindString so sorting DLL don't have to check if the string is Ascii with every call to SortFindString.
- return InternalFindNLSStringEx(
- m_dataHandle, m_handleOrigin, m_sortName,
- GetNativeCompareFlags(options) | Win32Native.FIND_ENDSWITH | ((source.IsAscii() && suffix.IsAscii()) ? RESERVED_FIND_ASCII_STRING : 0),
- source, source.Length, source.Length - 1, suffix, suffix.Length) >= 0;
+ return EndsWith(source, suffix, options);
}
- public virtual bool IsSuffix(String source, String suffix)
+ public virtual bool IsSuffix(string source, string suffix)
{
return (IsSuffix(source, suffix, 0));
}
@@ -641,9 +635,9 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
- public unsafe virtual int IndexOf(String source, char value)
+ public virtual int IndexOf(string source, char value)
{
- if (source==null)
+ if (source == null)
throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
@@ -651,9 +645,9 @@ namespace System.Globalization {
}
- public unsafe virtual int IndexOf(String source, String value)
+ public virtual int IndexOf(string source, string value)
{
- if (source==null)
+ if (source == null)
throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
@@ -661,9 +655,9 @@ namespace System.Globalization {
}
- public unsafe virtual int IndexOf(String source, char value, CompareOptions options)
+ public virtual int IndexOf(string source, char value, CompareOptions options)
{
- if (source==null)
+ if (source == null)
throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
@@ -671,17 +665,16 @@ namespace System.Globalization {
}
- public unsafe virtual int IndexOf(String source, String value, CompareOptions options)
+ public virtual int IndexOf(string source, string value, CompareOptions options)
{
- if (source==null)
+ if (source == null)
throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
return IndexOf(source, value, 0, source.Length, options);
}
-
- public unsafe virtual int IndexOf(String source, char value, int startIndex)
+ public virtual int IndexOf(string source, char value, int startIndex)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
@@ -690,8 +683,7 @@ namespace System.Globalization {
return IndexOf(source, value, startIndex, source.Length - startIndex, CompareOptions.None);
}
-
- public unsafe virtual int IndexOf(String source, String value, int startIndex)
+ public virtual int IndexOf(string source, string value, int startIndex)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
@@ -700,8 +692,7 @@ namespace System.Globalization {
return IndexOf(source, value, startIndex, source.Length - startIndex, CompareOptions.None);
}
-
- public unsafe virtual int IndexOf(String source, char value, int startIndex, CompareOptions options)
+ public virtual int IndexOf(string source, char value, int startIndex, CompareOptions options)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
@@ -711,7 +702,7 @@ namespace System.Globalization {
}
- public unsafe virtual int IndexOf(String source, String value, int startIndex, CompareOptions options)
+ public virtual int IndexOf(string source, string value, int startIndex, CompareOptions options)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
@@ -721,28 +712,28 @@ namespace System.Globalization {
}
- public unsafe virtual int IndexOf(String source, char value, int startIndex, int count)
+ public virtual int IndexOf(string source, char value, int startIndex, int count)
{
return IndexOf(source, value, startIndex, count, CompareOptions.None);
}
- public unsafe virtual int IndexOf(String source, String value, int startIndex, int count)
+ public virtual int IndexOf(string source, string value, int startIndex, int count)
{
return IndexOf(source, value, startIndex, count, CompareOptions.None);
}
- public unsafe virtual int IndexOf(String source, char value, int startIndex, int count, CompareOptions options)
+ public unsafe virtual int IndexOf(string source, char value, int startIndex, int count, CompareOptions options)
{
// Validate inputs
if (source == null)
throw new ArgumentNullException(nameof(source));
if (startIndex < 0 || startIndex > source.Length)
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
if (count < 0 || startIndex > source.Length - count)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
Contract.EndContractBlock();
if (options == CompareOptions.OrdinalIgnoreCase)
@@ -753,18 +744,16 @@ namespace System.Globalization {
// Validate CompareOptions
// Ordinal can't be selected with other flags
if ((options & ValidIndexMaskOffFlags) != 0 && (options != CompareOptions.Ordinal))
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
-
- // to let the sorting DLL do the call optimization in case of Ascii strings, we check if the strings are in Ascii and then send the flag RESERVED_FIND_ASCII_STRING to
- // the sorting DLL API SortFindString so sorting DLL don't have to check if the string is Ascii with every call to SortFindString.
- return InternalFindNLSStringEx(
- m_dataHandle, m_handleOrigin, m_sortName,
- GetNativeCompareFlags(options) | Win32Native.FIND_FROMSTART | ((source.IsAscii() && (value <= '\x007f')) ? RESERVED_FIND_ASCII_STRING : 0),
- source, count, startIndex, new String(value, 1), 1);
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
+
+ if (_invariantMode)
+ return IndexOfOrdinal(source, new string(value, 1), startIndex, count, ignoreCase: (options & (CompareOptions.IgnoreCase | CompareOptions.OrdinalIgnoreCase)) != 0);
+
+ return IndexOfCore(source, new string(value, 1), startIndex, count, options, null);
}
- public unsafe virtual int IndexOf(String source, String value, int startIndex, int count, CompareOptions options)
+ public unsafe virtual int IndexOf(string source, string value, int startIndex, int count, CompareOptions options)
{
// Validate inputs
if (source == null)
@@ -774,7 +763,7 @@ namespace System.Globalization {
if (startIndex > source.Length)
{
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
}
Contract.EndContractBlock();
@@ -791,28 +780,36 @@ namespace System.Globalization {
if (startIndex < 0)
{
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
}
if (count < 0 || startIndex > source.Length - count)
- throw new ArgumentOutOfRangeException(nameof(count),Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
if (options == CompareOptions.OrdinalIgnoreCase)
{
- return source.IndexOf(value, startIndex, count, StringComparison.OrdinalIgnoreCase);
+ return IndexOfOrdinal(source, value, startIndex, count, ignoreCase: true);
}
// Validate CompareOptions
// Ordinal can't be selected with other flags
if ((options & ValidIndexMaskOffFlags) != 0 && (options != CompareOptions.Ordinal))
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
-
- // to let the sorting DLL do the call optimization in case of Ascii strings, we check if the strings are in Ascii and then send the flag RESERVED_FIND_ASCII_STRING to
- // the sorting DLL API SortFindString so sorting DLL don't have to check if the string is Ascii with every call to SortFindString.
- return InternalFindNLSStringEx(
- m_dataHandle, m_handleOrigin, m_sortName,
- GetNativeCompareFlags(options) | Win32Native.FIND_FROMSTART | ((source.IsAscii() && value.IsAscii()) ? RESERVED_FIND_ASCII_STRING : 0),
- source, count, startIndex, value, value.Length);
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
+
+ if (_invariantMode)
+ return IndexOfOrdinal(source, value, startIndex, count, ignoreCase: (options & (CompareOptions.IgnoreCase | CompareOptions.OrdinalIgnoreCase)) != 0);
+
+ return IndexOfCore(source, value, startIndex, count, options, null);
+ }
+
+ internal int IndexOfOrdinal(string source, string value, int startIndex, int count, bool ignoreCase)
+ {
+ if (_invariantMode)
+ {
+ return InvariantIndexOf(source, value, startIndex, count, ignoreCase);
+ }
+
+ return IndexOfOrdinalCore(source, value, startIndex, count, ignoreCase);
}
////////////////////////////////////////////////////////////////////////
@@ -829,21 +826,20 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
- public unsafe virtual int LastIndexOf(String source, char value)
+ public virtual int LastIndexOf(String source, char value)
{
- if (source==null)
+ if (source == null)
throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
// Can't start at negative index, so make sure we check for the length == 0 case.
- return LastIndexOf(source, value, source.Length - 1,
- source.Length, CompareOptions.None);
+ return LastIndexOf(source, value, source.Length - 1, source.Length, CompareOptions.None);
}
- public virtual int LastIndexOf(String source, String value)
+ public virtual int LastIndexOf(string source, string value)
{
- if (source==null)
+ if (source == null)
throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
@@ -853,9 +849,9 @@ namespace System.Globalization {
}
- public virtual int LastIndexOf(String source, char value, CompareOptions options)
+ public virtual int LastIndexOf(string source, char value, CompareOptions options)
{
- if (source==null)
+ if (source == null)
throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
@@ -864,58 +860,55 @@ namespace System.Globalization {
source.Length, options);
}
- public unsafe virtual int LastIndexOf(String source, String value, CompareOptions options)
+ public virtual int LastIndexOf(string source, string value, CompareOptions options)
{
- if (source==null)
+ if (source == null)
throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
// Can't start at negative index, so make sure we check for the length == 0 case.
- return LastIndexOf(source, value, source.Length - 1,
- source.Length, options);
+ return LastIndexOf(source, value, source.Length - 1, source.Length, options);
}
-
- public unsafe virtual int LastIndexOf(String source, char value, int startIndex)
+ public virtual int LastIndexOf(string source, char value, int startIndex)
{
return LastIndexOf(source, value, startIndex, startIndex + 1, CompareOptions.None);
}
- public unsafe virtual int LastIndexOf(String source, String value, int startIndex)
+ public virtual int LastIndexOf(string source, string value, int startIndex)
{
return LastIndexOf(source, value, startIndex, startIndex + 1, CompareOptions.None);
}
-
- public unsafe virtual int LastIndexOf(String source, char value, int startIndex, CompareOptions options)
+ public virtual int LastIndexOf(string source, char value, int startIndex, CompareOptions options)
{
return LastIndexOf(source, value, startIndex, startIndex + 1, options);
}
- public unsafe virtual int LastIndexOf(String source, String value, int startIndex, CompareOptions options)
+ public virtual int LastIndexOf(string source, string value, int startIndex, CompareOptions options)
{
return LastIndexOf(source, value, startIndex, startIndex + 1, options);
}
- public unsafe virtual int LastIndexOf(String source, char value, int startIndex, int count)
+ public virtual int LastIndexOf(string source, char value, int startIndex, int count)
{
return LastIndexOf(source, value, startIndex, count, CompareOptions.None);
}
- public unsafe virtual int LastIndexOf(String source, String value, int startIndex, int count)
+ public virtual int LastIndexOf(string source, string value, int startIndex, int count)
{
return LastIndexOf(source, value, startIndex, count, CompareOptions.None);
}
- public unsafe virtual int LastIndexOf(String source, char value, int startIndex, int count, CompareOptions options)
+ public virtual int LastIndexOf(string source, char value, int startIndex, int count, CompareOptions options)
{
// Verify Arguments
- if (source==null)
+ if (source == null)
throw new ArgumentNullException(nameof(source));
Contract.EndContractBlock();
@@ -924,7 +917,7 @@ namespace System.Globalization {
if ((options & ValidIndexMaskOffFlags) != 0 &&
(options != CompareOptions.Ordinal) &&
(options != CompareOptions.OrdinalIgnoreCase))
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
// Special case for 0 length input strings
if (source.Length == 0 && (startIndex == -1 || startIndex == 0))
@@ -932,7 +925,7 @@ namespace System.Globalization {
// Make sure we're not out of range
if (startIndex < 0 || startIndex > source.Length)
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
// Make sure that we allow startIndex == source.Length
if (startIndex == source.Length)
@@ -944,23 +937,21 @@ namespace System.Globalization {
// 2nd have of this also catches when startIndex == MAXINT, so MAXINT - 0 + 1 == -1, which is < 0.
if (count < 0 || startIndex - count + 1 < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
if (options == CompareOptions.OrdinalIgnoreCase)
{
return source.LastIndexOf(value.ToString(), startIndex, count, StringComparison.OrdinalIgnoreCase);
}
- // to let the sorting DLL do the call optimization in case of Ascii strings, we check if the strings are in Ascii and then send the flag RESERVED_FIND_ASCII_STRING to
- // the sorting DLL API SortFindString so sorting DLL don't have to check if the string is Ascii with every call to SortFindString.
- return InternalFindNLSStringEx(
- m_dataHandle, m_handleOrigin, m_sortName,
- GetNativeCompareFlags(options) | Win32Native.FIND_FROMEND | ((source.IsAscii() && (value <= '\x007f')) ? RESERVED_FIND_ASCII_STRING : 0),
- source, count, startIndex, new String(value, 1), 1);
+ if (_invariantMode)
+ return InvariantLastIndexOf(source, new string(value, 1), startIndex, count, (options & (CompareOptions.IgnoreCase | CompareOptions.OrdinalIgnoreCase)) != 0);
+
+ return LastIndexOfCore(source, value.ToString(), startIndex, count, options);
}
- public unsafe virtual int LastIndexOf(String source, String value, int startIndex, int count, CompareOptions options)
+ public virtual int LastIndexOf(string source, string value, int startIndex, int count, CompareOptions options)
{
// Verify Arguments
if (source == null)
@@ -974,7 +965,7 @@ namespace System.Globalization {
if ((options & ValidIndexMaskOffFlags) != 0 &&
(options != CompareOptions.Ordinal) &&
(options != CompareOptions.OrdinalIgnoreCase))
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
// Special case for 0 length input strings
if (source.Length == 0 && (startIndex == -1 || startIndex == 0))
@@ -982,7 +973,7 @@ namespace System.Globalization {
// Make sure we're not out of range
if (startIndex < 0 || startIndex > source.Length)
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
// Make sure that we allow startIndex == source.Length
if (startIndex == source.Length)
@@ -998,21 +989,28 @@ namespace System.Globalization {
// 2nd half of this also catches when startIndex == MAXINT, so MAXINT - 0 + 1 == -1, which is < 0.
if (count < 0 || startIndex - count + 1 < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
if (options == CompareOptions.OrdinalIgnoreCase)
{
- return source.LastIndexOf(value, startIndex, count, StringComparison.OrdinalIgnoreCase);
+ return LastIndexOfOrdinal(source, value, startIndex, count, ignoreCase: true);
}
- // to let the sorting DLL do the call optimization in case of Ascii strings, we check if the strings are in Ascii and then send the flag RESERVED_FIND_ASCII_STRING to
- // the sorting DLL API SortFindString so sorting DLL don't have to check if the string is Ascii with every call to SortFindString.
- return InternalFindNLSStringEx(
- m_dataHandle, m_handleOrigin, m_sortName,
- GetNativeCompareFlags(options) | Win32Native.FIND_FROMEND | ((source.IsAscii() && value.IsAscii()) ? RESERVED_FIND_ASCII_STRING : 0),
- source, count, startIndex, value, value.Length);
+ if (_invariantMode)
+ return InvariantLastIndexOf(source, value, startIndex, count, (options & (CompareOptions.IgnoreCase | CompareOptions.OrdinalIgnoreCase)) != 0);
+
+ return LastIndexOfCore(source, value, startIndex, count, options);
}
+ internal int LastIndexOfOrdinal(string source, string value, int startIndex, int count, bool ignoreCase)
+ {
+ if (_invariantMode)
+ {
+ return InvariantLastIndexOf(source, value, startIndex, count, ignoreCase);
+ }
+
+ return LastIndexOfOrdinalCore(source, value, startIndex, count, ignoreCase);
+ }
////////////////////////////////////////////////////////////////////////
//
@@ -1021,74 +1019,23 @@ namespace System.Globalization {
// Gets the SortKey for the given string with the given options.
//
////////////////////////////////////////////////////////////////////////
- public unsafe virtual SortKey GetSortKey(String source, CompareOptions options)
+ public virtual SortKey GetSortKey(string source, CompareOptions options)
{
+ if (_invariantMode)
+ return InvariantCreateSortKey(source, options);
+
return CreateSortKey(source, options);
}
- public unsafe virtual SortKey GetSortKey(String source)
+ public virtual SortKey GetSortKey(string source)
{
- return CreateSortKey(source, CompareOptions.None);
- }
+ if (_invariantMode)
+ return InvariantCreateSortKey(source, CompareOptions.None);
- private SortKey CreateSortKey(String source, CompareOptions options)
- {
- if (source==null) { throw new ArgumentNullException(nameof(source)); }
- Contract.EndContractBlock();
-
- // Mask used to check if we have the right flags.
- const CompareOptions ValidSortkeyCtorMaskOffFlags = ~(CompareOptions.IgnoreCase |
- CompareOptions.IgnoreSymbols |
- CompareOptions.IgnoreNonSpace |
- CompareOptions.IgnoreWidth |
- CompareOptions.IgnoreKanaType |
- CompareOptions.StringSort);
-
- if ((options & ValidSortkeyCtorMaskOffFlags) != 0)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
- }
- byte[] keyData = null;
- // The OS doesn't have quite the same behavior so we have to test for empty inputs
- if (String.IsNullOrEmpty(source))
- {
- // Empty strings get an empty sort key
- keyData = EmptyArray<Byte>.Value;
- // Fake value to test though so we can verify our flags
- source = "\x0000";
- }
-
- int flags = GetNativeCompareFlags(options);
-
- // Go ahead and call the OS
- // First get the count
- int length = InternalGetSortKey(m_dataHandle, m_handleOrigin, m_sortName, flags, source, source.Length, null, 0);
-
- // If there was an error, return an error
- if (length == 0)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(source));
- }
-
- // If input was empty, return the empty byte[] we made earlier and skip this
- if (keyData == null)
- {
- // Make an appropriate byte array
- keyData = new byte[length];
-
- // Fill up the array
- length = InternalGetSortKey(m_dataHandle, m_handleOrigin, m_sortName, flags, source, source.Length, keyData, keyData.Length);
- }
- else
- {
- source = String.Empty; // back to original
- }
-
- return new SortKey(Name, source, options, keyData);
+ return CreateSortKey(source, CompareOptions.None);
}
-
////////////////////////////////////////////////////////////////////////
//
// Equals
@@ -1129,34 +1076,6 @@ namespace System.Globalization {
return (this.Name.GetHashCode());
}
- //
- // return hash value for the string according to the input CompareOptions
- //
-
- public virtual int GetHashCode(string source, CompareOptions options)
- {
- if (source == null)
- {
- throw new ArgumentNullException(nameof(source));
- }
-
- if (options == CompareOptions.Ordinal)
- {
- return source.GetHashCode();
- }
-
- if (options == CompareOptions.OrdinalIgnoreCase)
- {
- return TextInfo.GetHashCodeOrdinalIgnoreCase(source);
- }
-
- //
- // GetHashCodeOfString does more parameters validation. basically will throw when
- // having Ordinal, OrdinalIgnoreCase and StringSort
- //
-
- return GetHashCodeOfString(source, options, false, 0);
- }
////////////////////////////////////////////////////////////////////////
//
@@ -1184,33 +1103,46 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
internal int GetHashCodeOfString(string source, CompareOptions options)
{
- return GetHashCodeOfString(source, options, false, 0);
- }
-
- internal int GetHashCodeOfString(string source, CompareOptions options, bool forceRandomizedHashing, long additionalEntropy)
- {
//
// Parameter validation
//
- if(null == source)
+ if (null == source)
{
throw new ArgumentNullException(nameof(source));
}
if ((options & ValidHashCodeOfStringMaskOffFlags) != 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag"), nameof(options));
+ throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
}
Contract.EndContractBlock();
- if(0 == source.Length)
+ return GetHashCodeOfStringCore(source, options);
+ }
+
+ public virtual int GetHashCode(string source, CompareOptions options)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+
+ if (options == CompareOptions.Ordinal)
{
- return(0);
+ return source.GetHashCode();
}
+ if (options == CompareOptions.OrdinalIgnoreCase)
+ {
+ return TextInfo.GetHashCodeOrdinalIgnoreCase(source);
+ }
+
+ //
+ // GetHashCodeOfString does more parameters validation. basically will throw when
+ // having Ordinal, OrdinalIgnoreCase and StringSort
//
- ////////////////////////////////////////////////////////////////////////
- return (InternalGetGlobalizedHashCode(m_dataHandle, m_handleOrigin, this.m_sortName, source, source.Length, GetNativeCompareFlags(options), forceRandomizedHashing, additionalEntropy));
+
+ return GetHashCodeOfString(source, options);
}
////////////////////////////////////////////////////////////////////////
@@ -1221,82 +1153,41 @@ namespace System.Globalization {
// CompareInfo.
//
////////////////////////////////////////////////////////////////////////
-
-
- public override String ToString()
+ public override string ToString()
{
return ("CompareInfo - " + this.Name);
}
-#if FEATURE_USE_LCID
- public int LCID
+ public SortVersion Version
{
get
{
- return CultureInfo.GetCultureInfo(this.Name).LCID;
- }
- }
-#endif
+ if (_sortVersion == null)
+ {
+ if (_invariantMode)
+ {
+ _sortVersion = new SortVersion(0, CultureInfo.LOCALE_INVARIANT, new Guid(0, 0, 0, 0, 0, 0, 0,
+ (byte) (CultureInfo.LOCALE_INVARIANT >> 24),
+ (byte) ((CultureInfo.LOCALE_INVARIANT & 0x00FF0000) >> 16),
+ (byte) ((CultureInfo.LOCALE_INVARIANT & 0x0000FF00) >> 8),
+ (byte) (CultureInfo.LOCALE_INVARIANT & 0xFF)));
+ }
+ else
+ {
+ _sortVersion = GetSortVersion();
+ }
+ }
- internal static IntPtr InternalInitSortHandle(String localeName, out IntPtr handleOrigin)
- {
- return NativeInternalInitSortHandle(localeName, out handleOrigin);
+ return _sortVersion;
+ }
}
- [OptionalField(VersionAdded = 3)]
- private SortVersion m_SortVersion;
-
- public SortVersion Version
+ public int LCID
{
get
{
- if(m_SortVersion == null)
- {
- Win32Native.NlsVersionInfoEx v = new Win32Native.NlsVersionInfoEx();
- v.dwNLSVersionInfoSize = Marshal.SizeOf(typeof(Win32Native.NlsVersionInfoEx));
- InternalGetNlsVersionEx(m_dataHandle, m_handleOrigin, m_sortName, ref v);
- m_SortVersion = new SortVersion(v.dwNLSVersion, (v.dwEffectiveId != 0) ? v.dwEffectiveId : LCID, v.guidCustomVersion);
- }
-
- return m_SortVersion;
+ return CultureInfo.GetCultureInfo(Name).LCID;
}
}
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool InternalGetNlsVersionEx(IntPtr handle, IntPtr handleOrigin, String localeName, ref Win32Native.NlsVersionInfoEx lpNlsVersionInformation);
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern IntPtr NativeInternalInitSortHandle(String localeName, out IntPtr handleOrigin);
-
- // Get a locale sensitive sort hash code from native code -- COMNlsInfo::InternalGetGlobalizedHashCode
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern int InternalGetGlobalizedHashCode(IntPtr handle, IntPtr handleOrigin, string localeName, string source, int length, int dwFlags, bool forceRandomizedHashing, long additionalEntropy);
-
- // Use native API calls to see if this string is entirely defined -- COMNlsInfo::InternalIsSortable
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool InternalIsSortable(IntPtr handle, IntPtr handleOrigin, String localeName, String source, int length);
-
- // Compare a string using the native API calls -- COMNlsInfo::InternalCompareString
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern int InternalCompareString(IntPtr handle, IntPtr handleOrigin, String localeName, String string1, int offset1, int length1,
- String string2, int offset2, int length2, int flags);
-
- // InternalFindNLSStringEx parameters is not exactly matching kernel32::FindNLSStringEx parameters.
- // Call through to NewApis::FindNLSStringEx so we can get the right behavior
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern int InternalFindNLSStringEx(IntPtr handle, IntPtr handleOrigin, String localeName, int flags, String source, int sourceCount, int startIndex, string target, int targetCount);
-
- // Call through to NewAPis::LCMapStringEx so we can get appropriate behavior for all platforms
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern int InternalGetSortKey(IntPtr handle, IntPtr handleOrigin, String localeName, int flags, String source, int sourceCount, byte[] target, int targetCount);
}
}
diff --git a/src/mscorlib/src/System/Globalization/CultureData.Unix.cs b/src/mscorlib/src/System/Globalization/CultureData.Unix.cs
new file mode 100644
index 0000000000..4f685de580
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/CultureData.Unix.cs
@@ -0,0 +1,431 @@
+// 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.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Text;
+
+namespace System.Globalization
+{
+ internal partial class CultureData
+ {
+ // ICU constants
+ const int ICU_ULOC_KEYWORD_AND_VALUES_CAPACITY = 100; // max size of keyword or value
+ const int ICU_ULOC_FULLNAME_CAPACITY = 157; // max size of locale name
+ const string ICU_COLLATION_KEYWORD = "@collation=";
+
+
+ /// <summary>
+ /// This method uses the sRealName field (which is initialized by the constructor before this is called) to
+ /// initialize the rest of the state of CultureData based on the underlying OS globalization library.
+ /// </summary>
+ private unsafe bool InitCultureData()
+ {
+ Debug.Assert(_sRealName != null);
+
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ string alternateSortName = string.Empty;
+ string realNameBuffer = _sRealName;
+
+ // Basic validation
+ if (realNameBuffer.Contains("@"))
+ {
+ return false; // don't allow ICU variants to come in directly
+ }
+
+ // Replace _ (alternate sort) with @collation= for ICU
+ int index = realNameBuffer.IndexOf('_');
+ if (index > 0)
+ {
+ if (index >= (realNameBuffer.Length - 1) // must have characters after _
+ || realNameBuffer.Substring(index + 1).Contains("_")) // only one _ allowed
+ {
+ return false; // fail
+ }
+ alternateSortName = realNameBuffer.Substring(index + 1);
+ realNameBuffer = realNameBuffer.Substring(0, index) + ICU_COLLATION_KEYWORD + alternateSortName;
+ }
+
+ // Get the locale name from ICU
+ if (!GetLocaleName(realNameBuffer, out _sWindowsName))
+ {
+ return false; // fail
+ }
+
+ // Replace the ICU collation keyword with an _
+ index = _sWindowsName.IndexOf(ICU_COLLATION_KEYWORD, StringComparison.Ordinal);
+ if (index >= 0)
+ {
+ _sName = _sWindowsName.Substring(0, index) + "_" + alternateSortName;
+ }
+ else
+ {
+ _sName = _sWindowsName;
+ }
+ _sRealName = _sName;
+
+ _iLanguage = this.ILANGUAGE;
+ if (_iLanguage == 0)
+ {
+ _iLanguage = CultureInfo.LOCALE_CUSTOM_UNSPECIFIED;
+ }
+
+ _bNeutral = (this.SISO3166CTRYNAME.Length == 0);
+
+ _sSpecificCulture = _bNeutral ? LocaleData.GetSpecificCultureName(_sRealName) : _sRealName;
+
+ // Remove the sort from sName unless custom culture
+ if (index>0 && !_bNeutral && !IsCustomCultureId(_iLanguage))
+ {
+ _sName = _sWindowsName.Substring(0, index);
+ }
+ return true;
+ }
+
+ internal static bool GetLocaleName(string localeName, out string windowsName)
+ {
+ // Get the locale name from ICU
+ StringBuilder sb = StringBuilderCache.Acquire(ICU_ULOC_FULLNAME_CAPACITY);
+ if (!Interop.GlobalizationInterop.GetLocaleName(localeName, sb, sb.Capacity))
+ {
+ StringBuilderCache.Release(sb);
+ windowsName = null;
+ return false; // fail
+ }
+
+ // Success - use the locale name returned which may be different than realNameBuffer (casing)
+ windowsName = StringBuilderCache.GetStringAndRelease(sb); // the name passed to subsequent ICU calls
+ return true;
+ }
+
+ internal static bool GetDefaultLocaleName(out string windowsName)
+ {
+ // Get the default (system) locale name from ICU
+ StringBuilder sb = StringBuilderCache.Acquire(ICU_ULOC_FULLNAME_CAPACITY);
+ if (!Interop.GlobalizationInterop.GetDefaultLocaleName(sb, sb.Capacity))
+ {
+ StringBuilderCache.Release(sb);
+ windowsName = null;
+ return false; // fail
+ }
+
+ // Success - use the locale name returned which may be different than realNameBuffer (casing)
+ windowsName = StringBuilderCache.GetStringAndRelease(sb); // the name passed to subsequent ICU calls
+ return true;
+ }
+
+ private string GetLocaleInfo(LocaleStringData type)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ Debug.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo] Expected _sWindowsName to be populated already");
+ return GetLocaleInfo(_sWindowsName, type);
+ }
+
+ // For LOCALE_SPARENT we need the option of using the "real" name (forcing neutral names) instead of the
+ // "windows" name, which can be specific for downlevel (< windows 7) os's.
+ private string GetLocaleInfo(string localeName, LocaleStringData type)
+ {
+ Debug.Assert(localeName != null, "[CultureData.GetLocaleInfo] Expected localeName to be not be null");
+
+ switch (type)
+ {
+ case LocaleStringData.NegativeInfinitySymbol:
+ // not an equivalent in ICU; prefix the PositiveInfinitySymbol with NegativeSign
+ return GetLocaleInfo(localeName, LocaleStringData.NegativeSign) +
+ GetLocaleInfo(localeName, LocaleStringData.PositiveInfinitySymbol);
+ }
+
+ StringBuilder sb = StringBuilderCache.Acquire(ICU_ULOC_KEYWORD_AND_VALUES_CAPACITY);
+
+ bool result = Interop.GlobalizationInterop.GetLocaleInfoString(localeName, (uint)type, sb, sb.Capacity);
+ if (!result)
+ {
+ // Failed, just use empty string
+ StringBuilderCache.Release(sb);
+ Debug.Assert(false, "[CultureData.GetLocaleInfo(LocaleStringData)] Failed");
+ return String.Empty;
+ }
+ return StringBuilderCache.GetStringAndRelease(sb);
+ }
+
+ private int GetLocaleInfo(LocaleNumberData type)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ Debug.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo(LocaleNumberData)] Expected _sWindowsName to be populated already");
+
+ switch (type)
+ {
+ case LocaleNumberData.CalendarType:
+ // returning 0 will cause the first supported calendar to be returned, which is the preferred calendar
+ return 0;
+ }
+
+
+ int value = 0;
+ bool result = Interop.GlobalizationInterop.GetLocaleInfoInt(_sWindowsName, (uint)type, ref value);
+ if (!result)
+ {
+ // Failed, just use 0
+ Debug.Assert(false, "[CultureData.GetLocaleInfo(LocaleNumberData)] failed");
+ }
+
+ return value;
+ }
+
+ private int[] GetLocaleInfo(LocaleGroupingData type)
+ {
+ Debug.Assert(_sWindowsName != null, "[CultureData.GetLocaleInfo(LocaleGroupingData)] Expected _sWindowsName to be populated already");
+
+ int primaryGroupingSize = 0;
+ int secondaryGroupingSize = 0;
+ bool result = Interop.GlobalizationInterop.GetLocaleInfoGroupingSizes(_sWindowsName, (uint)type, ref primaryGroupingSize, ref secondaryGroupingSize);
+ if (!result)
+ {
+ Debug.Assert(false, "[CultureData.GetLocaleInfo(LocaleGroupingData type)] failed");
+ }
+
+ if (secondaryGroupingSize == 0)
+ {
+ return new int[] { primaryGroupingSize };
+ }
+
+ return new int[] { primaryGroupingSize, secondaryGroupingSize };
+ }
+
+ private string GetTimeFormatString()
+ {
+ return GetTimeFormatString(false);
+ }
+
+ private string GetTimeFormatString(bool shortFormat)
+ {
+ Debug.Assert(_sWindowsName != null, "[CultureData.GetTimeFormatString(bool shortFormat)] Expected _sWindowsName to be populated already");
+
+ StringBuilder sb = StringBuilderCache.Acquire(ICU_ULOC_KEYWORD_AND_VALUES_CAPACITY);
+
+ bool result = Interop.GlobalizationInterop.GetLocaleTimeFormat(_sWindowsName, shortFormat, sb, sb.Capacity);
+ if (!result)
+ {
+ // Failed, just use empty string
+ StringBuilderCache.Release(sb);
+ Debug.Assert(false, "[CultureData.GetTimeFormatString(bool shortFormat)] Failed");
+ return String.Empty;
+ }
+
+ return ConvertIcuTimeFormatString(StringBuilderCache.GetStringAndRelease(sb));
+ }
+
+ private int GetFirstDayOfWeek()
+ {
+ return this.GetLocaleInfo(LocaleNumberData.FirstDayOfWeek);
+ }
+
+ private String[] GetTimeFormats()
+ {
+ string format = GetTimeFormatString(false);
+ return new string[] { format };
+ }
+
+ private String[] GetShortTimeFormats()
+ {
+ string format = GetTimeFormatString(true);
+ return new string[] { format };
+ }
+
+ private static CultureData GetCultureDataFromRegionName(String regionName)
+ {
+ // no support to lookup by region name, other than the hard-coded list in CultureData
+ return null;
+ }
+
+ private static string GetLanguageDisplayName(string cultureName)
+ {
+ return new CultureInfo(cultureName)._cultureData.GetLocaleInfo(cultureName, LocaleStringData.LocalizedDisplayName);
+ }
+
+ private static string GetRegionDisplayName(string isoCountryCode)
+ {
+ // use the fallback which is to return NativeName
+ return null;
+ }
+
+ private static CultureInfo GetUserDefaultCulture()
+ {
+ return CultureInfo.GetUserDefaultCulture();
+ }
+
+ private static string ConvertIcuTimeFormatString(string icuFormatString)
+ {
+ StringBuilder sb = StringBuilderCache.Acquire(ICU_ULOC_FULLNAME_CAPACITY);
+ bool amPmAdded = false;
+
+ for (int i = 0; i < icuFormatString.Length; i++)
+ {
+ switch(icuFormatString[i])
+ {
+ case ':':
+ case '.':
+ case 'H':
+ case 'h':
+ case 'm':
+ case 's':
+ sb.Append(icuFormatString[i]);
+ break;
+
+ case ' ':
+ case '\u00A0':
+ // Convert nonbreaking spaces into regular spaces
+ sb.Append(' ');
+ break;
+
+ case 'a': // AM/PM
+ if (!amPmAdded)
+ {
+ amPmAdded = true;
+ sb.Append("tt");
+ }
+ break;
+
+ }
+ }
+
+ return StringBuilderCache.GetStringAndRelease(sb);
+ }
+
+ private static string LCIDToLocaleName(int culture)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ return LocaleData.LCIDToLocaleName(culture);
+ }
+
+ private static int LocaleNameToLCID(string cultureName)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ int lcid = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.Lcid);
+ return lcid == -1 ? CultureInfo.LOCALE_CUSTOM_UNSPECIFIED : lcid;
+ }
+
+ private static int GetAnsiCodePage(string cultureName)
+ {
+ int ansiCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.AnsiCodePage);
+ return ansiCodePage == -1 ? CultureData.Invariant.IDEFAULTANSICODEPAGE : ansiCodePage;
+ }
+
+ private static int GetOemCodePage(string cultureName)
+ {
+ int oemCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.OemCodePage);
+ return oemCodePage == -1 ? CultureData.Invariant.IDEFAULTOEMCODEPAGE : oemCodePage;
+ }
+
+ private static int GetMacCodePage(string cultureName)
+ {
+ int macCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.MacCodePage);
+ return macCodePage == -1 ? CultureData.Invariant.IDEFAULTMACCODEPAGE : macCodePage;
+ }
+
+ private static int GetEbcdicCodePage(string cultureName)
+ {
+ int ebcdicCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.EbcdicCodePage);
+ return ebcdicCodePage == -1 ? CultureData.Invariant.IDEFAULTEBCDICCODEPAGE : ebcdicCodePage;
+ }
+
+ private static int GetGeoId(string cultureName)
+ {
+ int geoId = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.GeoId);
+ return geoId == -1 ? CultureData.Invariant.IGEOID : geoId;
+ }
+
+ private static int GetDigitSubstitution(string cultureName)
+ {
+ int digitSubstitution = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.DigitSubstitution);
+ return digitSubstitution == -1 ? (int) DigitShapes.None : digitSubstitution;
+ }
+
+ private static string GetThreeLetterWindowsLanguageName(string cultureName)
+ {
+ string langName = LocaleData.GetThreeLetterWindowsLangageName(cultureName);
+ return langName == null ? "ZZZ" /* default lang name */ : langName;
+ }
+
+ private static CultureInfo[] EnumCultures(CultureTypes types)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ if ((types & (CultureTypes.NeutralCultures | CultureTypes.SpecificCultures)) == 0)
+ {
+ return Array.Empty<CultureInfo>();
+ }
+
+ int bufferLength = Interop.GlobalizationInterop.GetLocales(null, 0);
+ if (bufferLength <= 0)
+ {
+ return Array.Empty<CultureInfo>();
+ }
+
+ Char [] chars = new Char[bufferLength];
+
+ bufferLength = Interop.GlobalizationInterop.GetLocales(chars, bufferLength);
+ if (bufferLength <= 0)
+ {
+ return Array.Empty<CultureInfo>();
+ }
+
+ bool enumNeutrals = (types & CultureTypes.NeutralCultures) != 0;
+ bool enumSpecificss = (types & CultureTypes.SpecificCultures) != 0;
+
+ List<CultureInfo> list = new List<CultureInfo>();
+ if (enumNeutrals)
+ {
+ list.Add(CultureInfo.InvariantCulture);
+ }
+
+ int index = 0;
+ while (index < bufferLength)
+ {
+ int length = (int) chars[index++];
+ if (index + length <= bufferLength)
+ {
+ CultureInfo ci = CultureInfo.GetCultureInfo(new String(chars, index, length));
+ if ((enumNeutrals && ci.IsNeutralCulture) || (enumSpecificss && !ci.IsNeutralCulture))
+ {
+ list.Add(ci);
+ }
+ }
+
+ index += length;
+ }
+
+ return list.ToArray();
+ }
+
+ private static string GetConsoleFallbackName(string cultureName)
+ {
+ return LocaleData.GetConsoleUICulture(cultureName);
+ }
+
+ internal bool IsFramework // not applicable on Linux based systems
+ {
+ get { return false; }
+ }
+
+ internal bool IsWin32Installed // not applicable on Linux based systems
+ {
+ get { return false; }
+ }
+
+ internal bool IsReplacementCulture // not applicable on Linux based systems
+ {
+ get { return false; }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/CultureData.Windows.cs b/src/mscorlib/src/System/Globalization/CultureData.Windows.cs
new file mode 100644
index 0000000000..6d2678b550
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/CultureData.Windows.cs
@@ -0,0 +1,830 @@
+// 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.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Text;
+
+#if ENABLE_WINRT
+using Internal.Runtime.Augments;
+#endif
+
+namespace System.Globalization
+{
+#if CORECLR
+ using StringList = List<string>;
+#else
+ using StringList = LowLevelList<string>;
+#endif
+
+ internal partial class CultureData
+ {
+ private const uint LOCALE_NOUSEROVERRIDE = 0x80000000;
+ private const uint LOCALE_RETURN_NUMBER = 0x20000000;
+ private const uint LOCALE_SISO3166CTRYNAME = 0x0000005A;
+
+ private const uint TIME_NOSECONDS = 0x00000002;
+
+ /// <summary>
+ /// Check with the OS to see if this is a valid culture.
+ /// If so we populate a limited number of fields. If its not valid we return false.
+ ///
+ /// The fields we populate:
+ ///
+ /// sWindowsName -- The name that windows thinks this culture is, ie:
+ /// en-US if you pass in en-US
+ /// de-DE_phoneb if you pass in de-DE_phoneb
+ /// fj-FJ if you pass in fj (neutral, on a pre-Windows 7 machine)
+ /// fj if you pass in fj (neutral, post-Windows 7 machine)
+ ///
+ /// sRealName -- The name you used to construct the culture, in pretty form
+ /// en-US if you pass in EN-us
+ /// en if you pass in en
+ /// de-DE_phoneb if you pass in de-DE_phoneb
+ ///
+ /// sSpecificCulture -- The specific culture for this culture
+ /// en-US for en-US
+ /// en-US for en
+ /// de-DE_phoneb for alt sort
+ /// fj-FJ for fj (neutral)
+ ///
+ /// sName -- The IETF name of this culture (ie: no sort info, could be neutral)
+ /// en-US if you pass in en-US
+ /// en if you pass in en
+ /// de-DE if you pass in de-DE_phoneb
+ ///
+ /// bNeutral -- TRUE if it is a neutral locale
+ ///
+ /// For a neutral we just populate the neutral name, but we leave the windows name pointing to the
+ /// windows locale that's going to provide data for us.
+ /// </summary>
+ private unsafe bool InitCultureData()
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ const uint LOCALE_ILANGUAGE = 0x00000001;
+ const uint LOCALE_INEUTRAL = 0x00000071;
+ const uint LOCALE_SNAME = 0x0000005c;
+
+ int result;
+ string realNameBuffer = _sRealName;
+ char* pBuffer = stackalloc char[LOCALE_NAME_MAX_LENGTH];
+
+ result = GetLocaleInfoEx(realNameBuffer, LOCALE_SNAME, pBuffer, LOCALE_NAME_MAX_LENGTH);
+
+ // Did it fail?
+ if (result == 0)
+ {
+ return false;
+ }
+
+ // It worked, note that the name is the locale name, so use that (even for neutrals)
+ // We need to clean up our "real" name, which should look like the windows name right now
+ // so overwrite the input with the cleaned up name
+ _sRealName = new String(pBuffer, 0, result - 1);
+ realNameBuffer = _sRealName;
+
+ // Check for neutrality, don't expect to fail
+ // (buffer has our name in it, so we don't have to do the gc. stuff)
+
+ result = GetLocaleInfoEx(realNameBuffer, LOCALE_INEUTRAL | LOCALE_RETURN_NUMBER, pBuffer, sizeof(int) / sizeof(char));
+ if (result == 0)
+ {
+ return false;
+ }
+
+ // Remember our neutrality
+ _bNeutral = *((uint*)pBuffer) != 0;
+
+ // Note: Parents will be set dynamically
+
+ // Start by assuming the windows name will be the same as the specific name since windows knows
+ // about specifics on all versions. Only for downlevel Neutral locales does this have to change.
+ _sWindowsName = realNameBuffer;
+
+ // Neutrals and non-neutrals are slightly different
+ if (_bNeutral)
+ {
+ // Neutral Locale
+
+ // IETF name looks like neutral name
+ _sName = realNameBuffer;
+
+ // Specific locale name is whatever ResolveLocaleName (win7+) returns.
+ // (Buffer has our name in it, and we can recycle that because windows resolves it before writing to the buffer)
+ result = Interop.Kernel32.ResolveLocaleName(realNameBuffer, pBuffer, LOCALE_NAME_MAX_LENGTH);
+
+ // 0 is failure, 1 is invariant (""), which we expect
+ if (result < 1)
+ {
+ return false;
+ }
+ // We found a locale name, so use it.
+ // In vista this should look like a sort name (de-DE_phoneb) or a specific culture (en-US) and be in the "pretty" form
+ _sSpecificCulture = new String(pBuffer, 0, result - 1);
+ }
+ else
+ {
+ // Specific Locale
+
+ // Specific culture's the same as the locale name since we know its not neutral
+ // On mac we'll use this as well, even for neutrals. There's no obvious specific
+ // culture to use and this isn't exposed, but behaviorally this is correct on mac.
+ // Note that specifics include the sort name (de-DE_phoneb)
+ _sSpecificCulture = realNameBuffer;
+
+ _sName = realNameBuffer;
+
+ // We need the IETF name (sname)
+ // If we aren't an alt sort locale then this is the same as the windows name.
+ // If we are an alt sort locale then this is the same as the part before the _ in the windows name
+ // This is for like de-DE_phoneb and es-ES_tradnl that hsouldn't have the _ part
+
+ result = GetLocaleInfoEx(realNameBuffer, LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER, pBuffer, sizeof(int) / sizeof(char));
+ if (result == 0)
+ {
+ return false;
+ }
+
+ _iLanguage = *((int*)pBuffer);
+
+ if (!IsCustomCultureId(_iLanguage))
+ {
+ // not custom locale
+ int index = realNameBuffer.IndexOf('_');
+ if (index > 0 && index < realNameBuffer.Length)
+ {
+ _sName = realNameBuffer.Substring(0, index);
+ }
+ }
+ }
+
+ // It succeeded.
+ return true;
+ }
+
+ // Wrappers around the GetLocaleInfoEx APIs which handle marshalling the returned
+ // data as either and Int or String.
+ internal static unsafe String GetLocaleInfoEx(String localeName, uint field)
+ {
+ // REVIEW: Determine the maximum size for the buffer
+ const int BUFFER_SIZE = 530;
+
+ char* pBuffer = stackalloc char[BUFFER_SIZE];
+ int resultCode = GetLocaleInfoEx(localeName, field, pBuffer, BUFFER_SIZE);
+ if (resultCode > 0)
+ {
+ return new String(pBuffer);
+ }
+
+ return "";
+ }
+
+ internal static unsafe int GetLocaleInfoExInt(String localeName, uint field)
+ {
+ const uint LOCALE_RETURN_NUMBER = 0x20000000;
+ field |= LOCALE_RETURN_NUMBER;
+ int value = 0;
+ GetLocaleInfoEx(localeName, field, (char*) &value, sizeof(int));
+ return value;
+ }
+
+ internal static unsafe int GetLocaleInfoEx(string lpLocaleName, uint lcType, char* lpLCData, int cchData)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ return Interop.Kernel32.GetLocaleInfoEx(lpLocaleName, lcType, (IntPtr)lpLCData, cchData);
+ }
+
+ private string GetLocaleInfo(LocaleStringData type)
+ {
+ Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfo] Expected _sWindowsName to be populated by already");
+ return GetLocaleInfo(_sWindowsName, type);
+ }
+
+ // For LOCALE_SPARENT we need the option of using the "real" name (forcing neutral names) instead of the
+ // "windows" name, which can be specific for downlevel (< windows 7) os's.
+ private string GetLocaleInfo(string localeName, LocaleStringData type)
+ {
+ uint lctype = (uint)type;
+
+ return GetLocaleInfoFromLCType(localeName, lctype, UseUserOverride);
+ }
+
+ private int GetLocaleInfo(LocaleNumberData type)
+ {
+ uint lctype = (uint)type;
+
+ // Fix lctype if we don't want overrides
+ if (!UseUserOverride)
+ {
+ lctype |= LOCALE_NOUSEROVERRIDE;
+ }
+
+ // Ask OS for data, note that we presume it returns success, so we have to know that
+ // sWindowsName is valid before calling.
+ Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already");
+ return GetLocaleInfoExInt(_sWindowsName, lctype);
+ }
+
+ private int[] GetLocaleInfo(LocaleGroupingData type)
+ {
+ return ConvertWin32GroupString(GetLocaleInfoFromLCType(_sWindowsName, (uint)type, UseUserOverride));
+ }
+
+ private string GetTimeFormatString()
+ {
+ const uint LOCALE_STIMEFORMAT = 0x00001003;
+
+ return ReescapeWin32String(GetLocaleInfoFromLCType(_sWindowsName, LOCALE_STIMEFORMAT, UseUserOverride));
+ }
+
+ private int GetFirstDayOfWeek()
+ {
+ Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already");
+
+ const uint LOCALE_IFIRSTDAYOFWEEK = 0x0000100C;
+
+ int result = GetLocaleInfoExInt(_sWindowsName, LOCALE_IFIRSTDAYOFWEEK | (!UseUserOverride ? LOCALE_NOUSEROVERRIDE : 0));
+
+ // Win32 and .NET disagree on the numbering for days of the week, so we have to convert.
+ return ConvertFirstDayOfWeekMonToSun(result);
+ }
+
+ private String[] GetTimeFormats()
+ {
+ // Note that this gets overrides for us all the time
+ Debug.Assert(_sWindowsName != null, "[CultureData.DoEnumTimeFormats] Expected _sWindowsName to be populated by already");
+ String[] result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, 0, UseUserOverride));
+
+ return result;
+ }
+
+ private String[] GetShortTimeFormats()
+ {
+ // Note that this gets overrides for us all the time
+ Debug.Assert(_sWindowsName != null, "[CultureData.DoEnumShortTimeFormats] Expected _sWindowsName to be populated by already");
+ String[] result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, TIME_NOSECONDS, UseUserOverride));
+
+ return result;
+ }
+
+ // Enumerate all system cultures and then try to find out which culture has
+ // region name match the requested region name
+ private static CultureData GetCultureDataFromRegionName(String regionName)
+ {
+ Debug.Assert(regionName != null);
+
+ const uint LOCALE_SUPPLEMENTAL = 0x00000002;
+ const uint LOCALE_SPECIFICDATA = 0x00000020;
+
+ EnumLocaleData context = new EnumLocaleData();
+ context.cultureName = null;
+ context.regionName = regionName;
+
+ GCHandle contextHandle = GCHandle.Alloc(context);
+ try
+ {
+#if CORECLR
+ Interop.Kernel32.EnumSystemLocalesEx(EnumSystemLocalesProc, LOCALE_SPECIFICDATA | LOCALE_SUPPLEMENTAL, (IntPtr)contextHandle, IntPtr.Zero);
+#else
+ IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, uint, IntPtr, Interop.BOOL>>(EnumSystemLocalesProc);
+ Interop.Kernel32.EnumSystemLocalesEx(callback, LOCALE_SPECIFICDATA | LOCALE_SUPPLEMENTAL, (IntPtr)contextHandle, IntPtr.Zero);
+#endif
+ }
+ finally
+ {
+ contextHandle.Free();
+ }
+
+ if (context.cultureName != null)
+ {
+ // we got a matched culture
+ return GetCultureData(context.cultureName, true);
+ }
+
+ return null;
+ }
+
+ private string GetLanguageDisplayName(string cultureName)
+ {
+#if ENABLE_WINRT
+ return WinRTInterop.Callbacks.GetLanguageDisplayName(cultureName);
+#else
+ // Usually the UI culture shouldn't be different than what we got from WinRT except
+ // if DefaultThreadCurrentUICulture was set
+ CultureInfo ci;
+
+ if (CultureInfo.DefaultThreadCurrentUICulture != null &&
+ ((ci = GetUserDefaultCulture()) != null) &&
+ !CultureInfo.DefaultThreadCurrentUICulture.Name.Equals(ci.Name))
+ {
+ return SNATIVEDISPLAYNAME;
+ }
+ else
+ {
+ return GetLocaleInfo(cultureName, LocaleStringData.LocalizedDisplayName);
+ }
+#endif // ENABLE_WINRT
+ }
+
+ private string GetRegionDisplayName(string isoCountryCode)
+ {
+#if ENABLE_WINRT
+ return WinRTInterop.Callbacks.GetRegionDisplayName(isoCountryCode);
+#else
+ // Usually the UI culture shouldn't be different than what we got from WinRT except
+ // if DefaultThreadCurrentUICulture was set
+ CultureInfo ci;
+
+ if (CultureInfo.DefaultThreadCurrentUICulture != null &&
+ ((ci = GetUserDefaultCulture()) != null) &&
+ !CultureInfo.DefaultThreadCurrentUICulture.Name.Equals(ci.Name))
+ {
+ return SNATIVECOUNTRY;
+ }
+ else
+ {
+ return GetLocaleInfo(LocaleStringData.LocalizedCountryName);
+ }
+#endif // ENABLE_WINRT
+ }
+
+ private static CultureInfo GetUserDefaultCulture()
+ {
+#if ENABLE_WINRT
+ return (CultureInfo)WinRTInterop.Callbacks.GetUserDefaultCulture();
+#else
+ return CultureInfo.GetUserDefaultCulture();
+#endif // ENABLE_WINRT
+ }
+
+ // PAL methods end here.
+
+ private static string GetLocaleInfoFromLCType(string localeName, uint lctype, bool useUserOveride)
+ {
+ Debug.Assert(localeName != null, "[CultureData.GetLocaleInfoFromLCType] Expected localeName to be not be null");
+
+ // Fix lctype if we don't want overrides
+ if (!useUserOveride)
+ {
+ lctype |= LOCALE_NOUSEROVERRIDE;
+ }
+
+ // Ask OS for data
+ string result = GetLocaleInfoEx(localeName, lctype);
+ if (result == null)
+ {
+ // Failed, just use empty string
+ result = String.Empty;
+ }
+
+ return result;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Reescape a Win32 style quote string as a NLS+ style quoted string
+ //
+ // This is also the escaping style used by custom culture data files
+ //
+ // NLS+ uses \ to escape the next character, whether in a quoted string or
+ // not, so we always have to change \ to \\.
+ //
+ // NLS+ uses \' to escape a quote inside a quoted string so we have to change
+ // '' to \' (if inside a quoted string)
+ //
+ // We don't build the stringbuilder unless we find something to change
+ ////////////////////////////////////////////////////////////////////////////
+ internal static String ReescapeWin32String(String str)
+ {
+ // If we don't have data, then don't try anything
+ if (str == null)
+ return null;
+
+ StringBuilder result = null;
+
+ bool inQuote = false;
+ for (int i = 0; i < str.Length; i++)
+ {
+ // Look for quote
+ if (str[i] == '\'')
+ {
+ // Already in quote?
+ if (inQuote)
+ {
+ // See another single quote. Is this '' of 'fred''s' or '''', or is it an ending quote?
+ if (i + 1 < str.Length && str[i + 1] == '\'')
+ {
+ // Found another ', so we have ''. Need to add \' instead.
+ // 1st make sure we have our stringbuilder
+ if (result == null)
+ result = new StringBuilder(str, 0, i, str.Length * 2);
+
+ // Append a \' and keep going (so we don't turn off quote mode)
+ result.Append("\\'");
+ i++;
+ continue;
+ }
+
+ // Turning off quote mode, fall through to add it
+ inQuote = false;
+ }
+ else
+ {
+ // Found beginning quote, fall through to add it
+ inQuote = true;
+ }
+ }
+ // Is there a single \ character?
+ else if (str[i] == '\\')
+ {
+ // Found a \, need to change it to \\
+ // 1st make sure we have our stringbuilder
+ if (result == null)
+ result = new StringBuilder(str, 0, i, str.Length * 2);
+
+ // Append our \\ to the string & continue
+ result.Append("\\\\");
+ continue;
+ }
+
+ // If we have a builder we need to add our character
+ if (result != null)
+ result.Append(str[i]);
+ }
+
+ // Unchanged string? , just return input string
+ if (result == null)
+ return str;
+
+ // String changed, need to use the builder
+ return result.ToString();
+ }
+
+ internal static String[] ReescapeWin32Strings(String[] array)
+ {
+ if (array != null)
+ {
+ for (int i = 0; i < array.Length; i++)
+ {
+ array[i] = ReescapeWin32String(array[i]);
+ }
+ }
+
+ return array;
+ }
+
+ // If we get a group from windows, then its in 3;0 format with the 0 backwards
+ // of how NLS+ uses it (ie: if the string has a 0, then the int[] shouldn't and vice versa)
+ // EXCEPT in the case where the list only contains 0 in which NLS and NLS+ have the same meaning.
+ private static int[] ConvertWin32GroupString(String win32Str)
+ {
+ // None of these cases make any sense
+ if (win32Str == null || win32Str.Length == 0)
+ {
+ return (new int[] { 3 });
+ }
+
+ if (win32Str[0] == '0')
+ {
+ return (new int[] { 0 });
+ }
+
+ // Since its in n;n;n;n;n format, we can always get the length quickly
+ int[] values;
+ if (win32Str[win32Str.Length - 1] == '0')
+ {
+ // Trailing 0 gets dropped. 1;0 -> 1
+ values = new int[(win32Str.Length / 2)];
+ }
+ else
+ {
+ // Need extra space for trailing zero 1 -> 1;0
+ values = new int[(win32Str.Length / 2) + 2];
+ values[values.Length - 1] = 0;
+ }
+
+ int i;
+ int j;
+ for (i = 0, j = 0; i < win32Str.Length && j < values.Length; i += 2, j++)
+ {
+ // Note that this # shouldn't ever be zero, 'cause 0 is only at end
+ // But we'll test because its registry that could be anything
+ if (win32Str[i] < '1' || win32Str[i] > '9')
+ return new int[] { 3 };
+
+ values[j] = (int)(win32Str[i] - '0');
+ }
+
+ return (values);
+ }
+
+ private static int ConvertFirstDayOfWeekMonToSun(int iTemp)
+ {
+ // Convert Mon-Sun to Sun-Sat format
+ iTemp++;
+ if (iTemp > 6)
+ {
+ // Wrap Sunday and convert invalid data to Sunday
+ iTemp = 0;
+ }
+ return iTemp;
+ }
+
+
+ // Context for EnumCalendarInfoExEx callback.
+ private class EnumLocaleData
+ {
+ public string regionName;
+ public string cultureName;
+ }
+
+ // EnumSystemLocaleEx callback.
+#if !CORECLR
+ [NativeCallable(CallingConvention = CallingConvention.StdCall)]
+#endif
+ private static unsafe Interop.BOOL EnumSystemLocalesProc(IntPtr lpLocaleString, uint flags, IntPtr contextHandle)
+ {
+ EnumLocaleData context = (EnumLocaleData)((GCHandle)contextHandle).Target;
+ try
+ {
+ string cultureName = new string((char*)lpLocaleString);
+ string regionName = GetLocaleInfoEx(cultureName, LOCALE_SISO3166CTRYNAME);
+ if (regionName != null && regionName.Equals(context.regionName, StringComparison.OrdinalIgnoreCase))
+ {
+ context.cultureName = cultureName;
+ return Interop.BOOL.FALSE; // we found a match, then stop the enumeration
+ }
+
+ return Interop.BOOL.TRUE;
+ }
+ catch (Exception)
+ {
+ return Interop.BOOL.FALSE;
+ }
+ }
+
+ // EnumSystemLocaleEx callback.
+#if !CORECLR
+ [NativeCallable(CallingConvention = CallingConvention.StdCall)]
+#endif
+ private static unsafe Interop.BOOL EnumAllSystemLocalesProc(IntPtr lpLocaleString, uint flags, IntPtr contextHandle)
+ {
+ EnumData context = (EnumData)((GCHandle)contextHandle).Target;
+ try
+ {
+ context.strings.Add(new string((char*)lpLocaleString));
+ return Interop.BOOL.TRUE;
+ }
+ catch (Exception)
+ {
+ return Interop.BOOL.FALSE;
+ }
+ }
+
+ // Context for EnumTimeFormatsEx callback.
+ private class EnumData
+ {
+ public StringList strings;
+ }
+
+ // EnumTimeFormatsEx callback itself.
+#if !CORECLR
+ [NativeCallable(CallingConvention = CallingConvention.StdCall)]
+#endif
+ private static unsafe Interop.BOOL EnumTimeCallback(IntPtr lpTimeFormatString, IntPtr lParam)
+ {
+ EnumData context = (EnumData)((GCHandle)lParam).Target;
+
+ try
+ {
+ context.strings.Add(new string((char*)lpTimeFormatString));
+ return Interop.BOOL.TRUE;
+ }
+ catch (Exception)
+ {
+ return Interop.BOOL.FALSE;
+ }
+ }
+
+ private static unsafe String[] nativeEnumTimeFormats(String localeName, uint dwFlags, bool useUserOverride)
+ {
+ const uint LOCALE_SSHORTTIME = 0x00000079;
+ const uint LOCALE_STIMEFORMAT = 0x00001003;
+
+ EnumData data = new EnumData();
+ data.strings = new StringList();
+ GCHandle dataHandle = GCHandle.Alloc(data);
+ try
+ {
+#if CORECLR
+ Interop.Kernel32.EnumTimeFormatsEx(EnumTimeCallback, localeName, (uint)dwFlags, (IntPtr)dataHandle);
+#else
+ // Now call the enumeration API. Work is done by our callback function
+ IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, IntPtr, Interop.BOOL>>(EnumTimeCallback);
+ Interop.Kernel32.EnumTimeFormatsEx(callback, localeName, (uint)dwFlags, (IntPtr)dataHandle);
+#endif
+ }
+ finally
+ {
+ dataHandle.Free();
+ }
+
+ if (data.strings.Count > 0)
+ {
+ // Now we need to allocate our stringarray and populate it
+ string[] results = data.strings.ToArray();
+
+ if (!useUserOverride && data.strings.Count > 1)
+ {
+ // Since there is no "NoUserOverride" aware EnumTimeFormatsEx, we always get an override
+ // The override is the first entry if it is overriden.
+ // We can check if we have overrides by checking the GetLocaleInfo with no override
+ // If we do have an override, we don't know if it is a user defined override or if the
+ // user has just selected one of the predefined formats so we can't just remove it
+ // but we can move it down.
+ uint lcType = (dwFlags == TIME_NOSECONDS) ? LOCALE_SSHORTTIME : LOCALE_STIMEFORMAT;
+ string timeFormatNoUserOverride = GetLocaleInfoFromLCType(localeName, lcType, useUserOverride);
+ if (timeFormatNoUserOverride != "")
+ {
+ string firstTimeFormat = results[0];
+ if (timeFormatNoUserOverride != firstTimeFormat)
+ {
+ results[0] = results[1];
+ results[1] = firstTimeFormat;
+ }
+ }
+ }
+
+ return results;
+ }
+
+ return null;
+ }
+
+ private static int LocaleNameToLCID(string cultureName)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ return Interop.Kernel32.LocaleNameToLCID(cultureName, Interop.Kernel32.LOCALE_ALLOW_NEUTRAL_NAMES);
+ }
+
+ private static unsafe string LCIDToLocaleName(int culture)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ char *pBuffer = stackalloc char[Interop.Kernel32.LOCALE_NAME_MAX_LENGTH + 1]; // +1 for the null termination
+ int length = Interop.Kernel32.LCIDToLocaleName(culture, pBuffer, Interop.Kernel32.LOCALE_NAME_MAX_LENGTH + 1, Interop.Kernel32.LOCALE_ALLOW_NEUTRAL_NAMES);
+
+ if (length > 0)
+ {
+ return new String(pBuffer);
+ }
+
+ return null;
+ }
+
+ private int GetAnsiCodePage(string cultureName)
+ {
+ return GetLocaleInfo(LocaleNumberData.AnsiCodePage);
+ }
+
+ private int GetOemCodePage(string cultureName)
+ {
+ return GetLocaleInfo(LocaleNumberData.OemCodePage);
+ }
+
+ private int GetMacCodePage(string cultureName)
+ {
+ return GetLocaleInfo(LocaleNumberData.MacCodePage);
+ }
+
+ private int GetEbcdicCodePage(string cultureName)
+ {
+ return GetLocaleInfo(LocaleNumberData.EbcdicCodePage);
+ }
+
+ private int GetGeoId(string cultureName)
+ {
+ return GetLocaleInfo(LocaleNumberData.GeoId);
+ }
+
+ private int GetDigitSubstitution(string cultureName)
+ {
+ return GetLocaleInfo(LocaleNumberData.DigitSubstitution);
+ }
+
+ private string GetThreeLetterWindowsLanguageName(string cultureName)
+ {
+ return GetLocaleInfo(cultureName, LocaleStringData.AbbreviatedWindowsLanguageName);
+ }
+
+ private static CultureInfo[] EnumCultures(CultureTypes types)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ uint flags = 0;
+
+#pragma warning disable 618
+ if ((types & (CultureTypes.FrameworkCultures | CultureTypes.InstalledWin32Cultures | CultureTypes.ReplacementCultures)) != 0)
+ {
+ flags |= Interop.Kernel32.LOCALE_NEUTRALDATA | Interop.Kernel32.LOCALE_SPECIFICDATA;
+ }
+#pragma warning restore 618
+
+ if ((types & CultureTypes.NeutralCultures) != 0)
+ {
+ flags |= Interop.Kernel32.LOCALE_NEUTRALDATA;
+ }
+
+ if ((types & CultureTypes.SpecificCultures) != 0)
+ {
+ flags |= Interop.Kernel32.LOCALE_SPECIFICDATA;
+ }
+
+ if ((types & CultureTypes.UserCustomCulture) != 0)
+ {
+ flags |= Interop.Kernel32.LOCALE_SUPPLEMENTAL;
+ }
+
+ if ((types & CultureTypes.ReplacementCultures) != 0)
+ {
+ flags |= Interop.Kernel32.LOCALE_SUPPLEMENTAL;
+ }
+
+ EnumData context = new EnumData();
+ context.strings = new StringList();
+ GCHandle contextHandle = GCHandle.Alloc(context);
+ try
+ {
+#if CORECLR
+ Interop.Kernel32.EnumSystemLocalesEx(EnumAllSystemLocalesProc, flags, (IntPtr)contextHandle, IntPtr.Zero);
+#else
+ IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, uint, IntPtr, Interop.BOOL>>(EnumAllSystemLocalesProc);
+ Interop.Kernel32.EnumSystemLocalesEx(callback, flags, (IntPtr)contextHandle, IntPtr.Zero);
+#endif
+ }
+ finally
+ {
+ contextHandle.Free();
+ }
+
+ CultureInfo [] cultures = new CultureInfo[context.strings.Count];
+ for (int i = 0; i < cultures.Length; i++)
+ {
+ cultures[i] = new CultureInfo(context.strings[i]);
+ }
+
+ return cultures;
+ }
+
+ private string GetConsoleFallbackName(string cultureName)
+ {
+ return GetLocaleInfo(cultureName, LocaleStringData.ConsoleFallbackName);
+ }
+
+ internal bool IsFramework
+ {
+ get { return false; }
+ }
+
+ internal bool IsWin32Installed
+ {
+ get { return true; }
+ }
+
+ internal bool IsReplacementCulture
+ {
+ get
+ {
+ EnumData context = new EnumData();
+ context.strings = new StringList();
+ GCHandle contextHandle = GCHandle.Alloc(context);
+ try
+ {
+#if CORECLR
+ Interop.Kernel32.EnumSystemLocalesEx(EnumAllSystemLocalesProc, Interop.Kernel32.LOCALE_REPLACEMENT, (IntPtr)contextHandle, IntPtr.Zero);
+#else
+ IntPtr callback = AddrofIntrinsics.AddrOf<Func<IntPtr, uint, IntPtr, Interop.BOOL>>(EnumAllSystemLocalesProc);
+ Interop.Kernel32.EnumSystemLocalesEx(callback, Interop.Kernel32.LOCALE_REPLACEMENT, (IntPtr)contextHandle, IntPtr.Zero);
+#endif
+ }
+ finally
+ {
+ contextHandle.Free();
+ }
+
+ for (int i=0; i<context.strings.Count; i++)
+ {
+ if (String.Compare(context.strings[i], _sWindowsName, StringComparison.OrdinalIgnoreCase) == 0)
+ return true;
+ }
+
+ return false;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/CultureData.cs b/src/mscorlib/src/System/Globalization/CultureData.cs
index a93b7d43bb..0dcebf484b 100644
--- a/src/mscorlib/src/System/Globalization/CultureData.cs
+++ b/src/mscorlib/src/System/Globalization/CultureData.cs
@@ -2,20 +2,23 @@
// 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.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+using System.Threading;
+
namespace System.Globalization
{
-
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Text;
- using System.Threading;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Security;
+#if CORECLR
+ using StringStringDictionary = Dictionary<string, string>;
+ using StringCultureDataDictionary = Dictionary<string, CultureData>;
+ using LcidToCultureNameDictionary = Dictionary<int, string>;
+ using Lock = Object;
+#else
+ using StringStringDictionary = LowLevelDictionary<string, string>;
+ using StringCultureDataDictionary = LowLevelDictionary<string, CultureData>;
+ using LcidToCultureNameDictionary = LowLevelDictionary<int, string>;
+#endif
//
// List of culture data
@@ -48,504 +51,263 @@ namespace System.Globalization
// en if you pass in en
// de-DE if you pass in de-DE_phoneb
//
-
- // StructLayout is needed here otherwise compiler can re-arrange the fields.
- // We have to keep this in-sync with the definition in comnlsinfo.h
- //
- // WARNING WARNING WARNING
- //
- // WARNING: Anything changed here also needs to be updated on the native side (object.h see type CultureDataBaseObject)
- // WARNING: The type loader will rearrange class member offsets so the mscorwks!CultureDataBaseObject
- // WARNING: must be manually structured to match the true loaded class layout
- //
- [FriendAccessAllowed]
- internal class CultureData
+ internal partial class CultureData
{
- const int undef = -1;
+ private const int LOCALE_NAME_MAX_LENGTH = 85;
+ private const int undef = -1;
// Override flag
- private String sRealName; // Name you passed in (ie: en-US, en, or de-DE_phoneb)
- private String sWindowsName; // Name OS thinks the object is (ie: de-DE_phoneb, or en-US (even if en was passed in))
+ private String _sRealName; // Name you passed in (ie: en-US, en, or de-DE_phoneb)
+ private String _sWindowsName; // Name OS thinks the object is (ie: de-DE_phoneb, or en-US (even if en was passed in))
// Identity
- private String sName; // locale name (ie: en-us, NO sort info, but could be neutral)
- private String sParent; // Parent name (which may be a custom locale/culture)
- private String sLocalizedDisplayName; // Localized pretty name for this locale
- private String sEnglishDisplayName; // English pretty name for this locale
- private String sNativeDisplayName; // Native pretty name for this locale
- private String sSpecificCulture; // The culture name to be used in CultureInfo.CreateSpecificCulture(), en-US form if neutral, sort name if sort
+ private String _sName; // locale name (ie: en-us, NO sort info, but could be neutral)
+ private String _sParent; // Parent name (which may be a custom locale/culture)
+ private String _sLocalizedDisplayName; // Localized pretty name for this locale
+ private String _sEnglishDisplayName; // English pretty name for this locale
+ private String _sNativeDisplayName; // Native pretty name for this locale
+ private String _sSpecificCulture; // The culture name to be used in CultureInfo.CreateSpecificCulture(), en-US form if neutral, sort name if sort
// Language
- private String sISO639Language; // ISO 639 Language Name
- private String sLocalizedLanguage; // Localized name for this language
- private String sEnglishLanguage; // English name for this language
- private String sNativeLanguage; // Native name of this language
+ private String _sISO639Language; // ISO 639 Language Name
+ private String _sISO639Language2; // ISO 639 Language Name
+ private String _sLocalizedLanguage; // Localized name for this language
+ private String _sEnglishLanguage; // English name for this language
+ private String _sNativeLanguage; // Native name of this language
+ private String _sAbbrevLang; // abbreviated language name (Windows Language Name) ex: ENU
+ private string _sConsoleFallbackName; // The culture name for the console fallback UI culture
+ private int _iInputLanguageHandle=undef;// input language handle
// Region
- private String sRegionName; // (RegionInfo)
- private int iGeoId = undef; // GeoId
- private String sLocalizedCountry; // localized country name
- private String sEnglishCountry; // english country name (RegionInfo)
- private String sNativeCountry; // native country name
- private String sISO3166CountryName; // ISO 3166 (RegionInfo), ie: US
+ private String _sRegionName; // (RegionInfo)
+ private String _sLocalizedCountry; // localized country name
+ private String _sEnglishCountry; // english country name (RegionInfo)
+ private String _sNativeCountry; // native country name
+ private String _sISO3166CountryName; // ISO 3166 (RegionInfo), ie: US
+ private String _sISO3166CountryName2; // 3 char ISO 3166 country name 2 2(RegionInfo) ex: USA (ISO)
+ private int _iGeoId = undef; // GeoId
// Numbers
- private String sPositiveSign; // (user can override) positive sign
- private String sNegativeSign; // (user can override) negative sign
- private String[] saNativeDigits; // (user can override) native characters for digits 0-9
+ private String _sPositiveSign; // (user can override) positive sign
+ private String _sNegativeSign; // (user can override) negative sign
// (nfi populates these 5, don't have to be = undef)
- private int iDigitSubstitution; // (user can override) Digit substitution 0=context, 1=none/arabic, 2=Native/national (2 seems to be unused)
- private int iLeadingZeros; // (user can override) leading zeros 0 = no leading zeros, 1 = leading zeros
- private int iDigits; // (user can override) number of fractional digits
- private int iNegativeNumber; // (user can override) negative number format
- private int[] waGrouping; // (user can override) grouping of digits
- private String sDecimalSeparator; // (user can override) decimal separator
- private String sThousandSeparator; // (user can override) thousands separator
- private String sNaN; // Not a Number
- private String sPositiveInfinity; // + Infinity
- private String sNegativeInfinity; // - Infinity
+ private int _iDigits; // (user can override) number of fractional digits
+ private int _iNegativeNumber; // (user can override) negative number format
+ private int[] _waGrouping; // (user can override) grouping of digits
+ private String _sDecimalSeparator; // (user can override) decimal separator
+ private String _sThousandSeparator; // (user can override) thousands separator
+ private String _sNaN; // Not a Number
+ private String _sPositiveInfinity; // + Infinity
+ private String _sNegativeInfinity; // - Infinity
// Percent
- private int iNegativePercent = undef; // Negative Percent (0-3)
- private int iPositivePercent = undef; // Positive Percent (0-11)
- private String sPercent; // Percent (%) symbol
- private String sPerMille; // PerMille (‰) symbol
+ private int _iNegativePercent = undef; // Negative Percent (0-3)
+ private int _iPositivePercent = undef; // Positive Percent (0-11)
+ private String _sPercent; // Percent (%) symbol
+ private String _sPerMille; // PerMille symbol
// Currency
- private String sCurrency; // (user can override) local monetary symbol
- private String sIntlMonetarySymbol; // international monetary symbol (RegionInfo)
- private String sEnglishCurrency; // English name for this currency
- private String sNativeCurrency; // Native name for this currency
+ private String _sCurrency; // (user can override) local monetary symbol
+ private String _sIntlMonetarySymbol; // international monetary symbol (RegionInfo)
+ private String _sEnglishCurrency; // English name for this currency
+ private String _sNativeCurrency; // Native name for this currency
// (nfi populates these 4, don't have to be = undef)
- private int iCurrencyDigits; // (user can override) # local monetary fractional digits
- private int iCurrency; // (user can override) positive currency format
- private int iNegativeCurrency; // (user can override) negative currency format
- private int[] waMonetaryGrouping; // (user can override) monetary grouping of digits
- private String sMonetaryDecimal; // (user can override) monetary decimal separator
- private String sMonetaryThousand; // (user can override) monetary thousands separator
+ private int _iCurrencyDigits; // (user can override) # local monetary fractional digits
+ private int _iCurrency; // (user can override) positive currency format
+ private int _iNegativeCurrency; // (user can override) negative currency format
+ private int[] _waMonetaryGrouping; // (user can override) monetary grouping of digits
+ private String _sMonetaryDecimal; // (user can override) monetary decimal separator
+ private String _sMonetaryThousand; // (user can override) monetary thousands separator
// Misc
- private int iMeasure = undef; // (user can override) system of measurement 0=metric, 1=US (RegionInfo)
- private String sListSeparator; // (user can override) list separator
- // private int iPaperSize ; // default paper size (RegionInfo)
+ private int _iMeasure = undef; // (user can override) system of measurement 0=metric, 1=US (RegionInfo)
+ private String _sListSeparator; // (user can override) list separator
// Time
- private String sAM1159; // (user can override) AM designator
- private String sPM2359; // (user can override) PM designator
- private String sTimeSeparator;
- private volatile String[] saLongTimes; // (user can override) time format
- private volatile String[] saShortTimes; // short time format
- private volatile String[] saDurationFormats; // time duration format
+ private String _sAM1159; // (user can override) AM designator
+ private String _sPM2359; // (user can override) PM designator
+ private String _sTimeSeparator;
+ private volatile String[] _saLongTimes; // (user can override) time format
+ private volatile String[] _saShortTimes; // short time format
+ private volatile String[] _saDurationFormats; // time duration format
// Calendar specific data
- private int iFirstDayOfWeek = undef; // (user can override) first day of week (gregorian really)
- private int iFirstWeekOfYear = undef; // (user can override) first week of year (gregorian really)
- private volatile int[] waCalendars; // all available calendar type(s). The first one is the default calendar
+ private int _iFirstDayOfWeek = undef; // (user can override) first day of week (gregorian really)
+ private int _iFirstWeekOfYear = undef; // (user can override) first week of year (gregorian really)
+ private volatile CalendarId[] _waCalendars; // all available calendar type(s). The first one is the default calendar
// Store for specific data about each calendar
- private CalendarData[] calendars; // Store for specific calendar data
+ private CalendarData[] _calendars; // Store for specific calendar data
// Text information
- private int iReadingLayout = undef; // Reading layout data
+ private int _iReadingLayout = undef; // Reading layout data
// 0 - Left to right (eg en-US)
// 1 - Right to left (eg arabic locales)
// 2 - Vertical top to bottom with columns to the left and also left to right (ja-JP locales)
// 3 - Vertical top to bottom with columns proceeding to the right
- private String sTextInfo; // Text info name to use for custom
- private String sCompareInfo; // Compare info name (including sorting key) to use if custom
- private String sScripts; // Typical Scripts for this locale (latn;cyrl; etc)
-
- private int iDefaultAnsiCodePage = undef; // default ansi code page ID (ACP)
- private int iDefaultOemCodePage = undef; // default oem code page ID (OCP or OEM)
- private int iDefaultMacCodePage = undef; // default macintosh code page
- private int iDefaultEbcdicCodePage = undef; // default EBCDIC code page
-
- // These are desktop only, not coreclr
- private int iLanguage; // locale ID (0409) - NO sort information
- private String sAbbrevLang; // abbreviated language name (Windows Language Name) ex: ENU
- private String sAbbrevCountry; // abbreviated country name (RegionInfo) (Windows Region Name) ex: USA
- private String sISO639Language2; // 3 char ISO 639 lang name 2 ex: eng
- private String sISO3166CountryName2; // 3 char ISO 3166 country name 2 2(RegionInfo) ex: USA (ISO)
- private int iInputLanguageHandle=undef;// input language handle
- private String sConsoleFallbackName; // The culture name for the console fallback UI culture
- private String sKeyboardsToInstall; // Keyboard installation string.
- private String fontSignature; // Font signature (16 WORDS)
-
- // The bools all need to be in one spot
- private bool bUseOverrides; // use user overrides?
- private bool bNeutral; // Flags for the culture (ie: neutral or not right now)
- private bool bWin32Installed; // Flags indicate if the culture is Win32 installed
- private bool bFramework; // Flags for indicate if the culture is one of Whidbey cultures
+ // CoreCLR depends on this even though its not exposed publicly.
+
+ private int _iDefaultAnsiCodePage = undef; // default ansi code page ID (ACP)
+ private int _iDefaultOemCodePage = undef; // default oem code page ID (OCP or OEM)
+ private int _iDefaultMacCodePage = undef; // default macintosh code page
+ private int _iDefaultEbcdicCodePage = undef; // default EBCDIC code page
+
+ private int _iLanguage; // locale ID (0409) - NO sort information
+ private bool _bUseOverrides; // use user overrides?
+ private bool _bNeutral; // Flags for the culture (ie: neutral or not right now)
// Region Name to Culture Name mapping table
// (In future would be nice to be in registry or something)
- //Using a property so we avoid creating the dictionary untill we need it
- private static Dictionary<string, string> RegionNames
+ //Using a property so we avoid creating the dictionary until we need it
+ private static StringStringDictionary RegionNames
{
- get
+ get
{
if (s_RegionNames == null)
{
- var regionNames = new Dictionary<string, string> {
- { "029", "en-029" },
- { "AE", "ar-AE" },
- { "AF", "prs-AF" },
- { "AL", "sq-AL" },
- { "AM", "hy-AM" },
- { "AR", "es-AR" },
- { "AT", "de-AT" },
- { "AU", "en-AU" },
- { "AZ", "az-Cyrl-AZ" },
- { "BA", "bs-Latn-BA" },
- { "BD", "bn-BD" },
- { "BE", "nl-BE" },
- { "BG", "bg-BG" },
- { "BH", "ar-BH" },
- { "BN", "ms-BN" },
- { "BO", "es-BO" },
- { "BR", "pt-BR" },
- { "BY", "be-BY" },
- { "BZ", "en-BZ" },
- { "CA", "en-CA" },
- { "CH", "it-CH" },
- { "CL", "es-CL" },
- { "CN", "zh-CN" },
- { "CO", "es-CO" },
- { "CR", "es-CR" },
- { "CS", "sr-Cyrl-CS" },
- { "CZ", "cs-CZ" },
- { "DE", "de-DE" },
- { "DK", "da-DK" },
- { "DO", "es-DO" },
- { "DZ", "ar-DZ" },
- { "EC", "es-EC" },
- { "EE", "et-EE" },
- { "EG", "ar-EG" },
- { "ES", "es-ES" },
- { "ET", "am-ET" },
- { "FI", "fi-FI" },
- { "FO", "fo-FO" },
- { "FR", "fr-FR" },
- { "GB", "en-GB" },
- { "GE", "ka-GE" },
- { "GL", "kl-GL" },
- { "GR", "el-GR" },
- { "GT", "es-GT" },
- { "HK", "zh-HK" },
- { "HN", "es-HN" },
- { "HR", "hr-HR" },
- { "HU", "hu-HU" },
- { "ID", "id-ID" },
- { "IE", "en-IE" },
- { "IL", "he-IL" },
- { "IN", "hi-IN" },
- { "IQ", "ar-IQ" },
- { "IR", "fa-IR" },
- { "IS", "is-IS" },
- { "IT", "it-IT" },
- { "IV", "" },
- { "JM", "en-JM" },
- { "JO", "ar-JO" },
- { "JP", "ja-JP" },
- { "KE", "sw-KE" },
- { "KG", "ky-KG" },
- { "KH", "km-KH" },
- { "KR", "ko-KR" },
- { "KW", "ar-KW" },
- { "KZ", "kk-KZ" },
- { "LA", "lo-LA" },
- { "LB", "ar-LB" },
- { "LI", "de-LI" },
- { "LK", "si-LK" },
- { "LT", "lt-LT" },
- { "LU", "lb-LU" },
- { "LV", "lv-LV" },
- { "LY", "ar-LY" },
- { "MA", "ar-MA" },
- { "MC", "fr-MC" },
- { "ME", "sr-Latn-ME" },
- { "MK", "mk-MK" },
- { "MN", "mn-MN" },
- { "MO", "zh-MO" },
- { "MT", "mt-MT" },
- { "MV", "dv-MV" },
- { "MX", "es-MX" },
- { "MY", "ms-MY" },
- { "NG", "ig-NG" },
- { "NI", "es-NI" },
- { "NL", "nl-NL" },
- { "NO", "nn-NO" },
- { "NP", "ne-NP" },
- { "NZ", "en-NZ" },
- { "OM", "ar-OM" },
- { "PA", "es-PA" },
- { "PE", "es-PE" },
- { "PH", "en-PH" },
- { "PK", "ur-PK" },
- { "PL", "pl-PL" },
- { "PR", "es-PR" },
- { "PT", "pt-PT" },
- { "PY", "es-PY" },
- { "QA", "ar-QA" },
- { "RO", "ro-RO" },
- { "RS", "sr-Latn-RS" },
- { "RU", "ru-RU" },
- { "RW", "rw-RW" },
- { "SA", "ar-SA" },
- { "SE", "sv-SE" },
- { "SG", "zh-SG" },
- { "SI", "sl-SI" },
- { "SK", "sk-SK" },
- { "SN", "wo-SN" },
- { "SV", "es-SV" },
- { "SY", "ar-SY" },
- { "TH", "th-TH" },
- { "TJ", "tg-Cyrl-TJ" },
- { "TM", "tk-TM" },
- { "TN", "ar-TN" },
- { "TR", "tr-TR" },
- { "TT", "en-TT" },
- { "TW", "zh-TW" },
- { "UA", "uk-UA" },
- { "US", "en-US" },
- { "UY", "es-UY" },
- { "UZ", "uz-Cyrl-UZ" },
- { "VE", "es-VE" },
- { "VN", "vi-VN" },
- { "YE", "ar-YE" },
- { "ZA", "af-ZA" },
- { "ZW", "en-ZW" }
- };
- s_RegionNames = regionNames;
- }
- return s_RegionNames;
- }
- }
- private volatile static Dictionary<string, string> s_RegionNames;
-
- /////////////////////////////////////////////////////////////////////////
- // Build our invariant information
- //
- // We need an invariant instance, which we build hard-coded
- /////////////////////////////////////////////////////////////////////////
- internal static CultureData Invariant
- {
- get
- {
- if (s_Invariant == null)
- {
- // Make a new culturedata
- CultureData invariant = new CultureData();
-
- // Call the native code to get the value of bWin32Installed.
- // For versions <= Vista, we set this to false for compatibility with v2.
- // For Windows 7, the flag is true.
- invariant.bUseOverrides = false;
- invariant.sRealName = "";
-
- // Ask the native code to fill it out for us, we only need the field IsWin32Installed
- nativeInitCultureData(invariant);
-
- // Basics
- // Note that we override the resources since this IS NOT supposed to change (by definition)
- invariant.bUseOverrides = false;
- invariant.sRealName = ""; // Name you passed in (ie: en-US, en, or de-DE_phoneb)
- invariant.sWindowsName = ""; // Name OS thinks the object is (ie: de-DE_phoneb, or en-US (even if en was passed in))
-
- // Identity
- invariant.sName = ""; // locale name (ie: en-us)
- invariant.sParent = ""; // Parent name (which may be a custom locale/culture)
- invariant.bNeutral = false; // Flags for the culture (ie: neutral or not right now)
- // Don't set invariant.bWin32Installed, we used nativeInitCultureData for that.
- invariant.bFramework = true;
-
- invariant.sEnglishDisplayName = "Invariant Language (Invariant Country)"; // English pretty name for this locale
- invariant.sNativeDisplayName = "Invariant Language (Invariant Country)"; // Native pretty name for this locale
- invariant.sSpecificCulture = ""; // The culture name to be used in CultureInfo.CreateSpecificCulture()
-
- // Language
- invariant.sISO639Language = "iv"; // ISO 639 Language Name
- invariant.sLocalizedLanguage = "Invariant Language"; // Display name for this Language
- invariant.sEnglishLanguage = "Invariant Language"; // English name for this language
- invariant.sNativeLanguage = "Invariant Language"; // Native name of this language
-
- // Region
- invariant.sRegionName = "IV"; // (RegionInfo)
- // Unused for now:
- // invariant.iCountry =1; // country code (RegionInfo)
- invariant.iGeoId = 244; // GeoId (Windows Only)
- invariant.sEnglishCountry = "Invariant Country"; // english country name (RegionInfo)
- invariant.sNativeCountry = "Invariant Country"; // native country name (Windows Only)
- invariant.sISO3166CountryName = "IV"; // (RegionInfo), ie: US
-
- // Numbers
- invariant.sPositiveSign = "+"; // positive sign
- invariant.sNegativeSign = "-"; // negative sign
- invariant.saNativeDigits = new String[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; // native characters for digits 0-9
- invariant.iDigitSubstitution = 1; // Digit substitution 0=context, 1=none/arabic, 2=Native/national (2 seems to be unused) (Windows Only)
- invariant.iLeadingZeros = 1; // leading zeros 0=no leading zeros, 1=leading zeros
- invariant.iDigits = 2; // number of fractional digits
- invariant.iNegativeNumber = 1; // negative number format
- invariant.waGrouping = new int[] { 3 }; // grouping of digits
- invariant.sDecimalSeparator = "."; // decimal separator
- invariant.sThousandSeparator = ","; // thousands separator
- invariant.sNaN = "NaN"; // Not a Number
- invariant.sPositiveInfinity = "Infinity"; // + Infinity
- invariant.sNegativeInfinity = "-Infinity"; // - Infinity
-
- // Percent
- invariant.iNegativePercent = 0; // Negative Percent (0-3)
- invariant.iPositivePercent = 0; // Positive Percent (0-11)
- invariant.sPercent = "%"; // Percent (%) symbol
- invariant.sPerMille = "\x2030"; // PerMille(‰) symbol
-
- // Currency
- invariant.sCurrency = "\x00a4"; // local monetary symbol "¤: for international monetary symbol
- invariant.sIntlMonetarySymbol = "XDR"; // international monetary symbol (RegionInfo)
- invariant.sEnglishCurrency = "International Monetary Fund"; // English name for this currency (Windows Only)
- invariant.sNativeCurrency = "International Monetary Fund"; // Native name for this currency (Windows Only)
- invariant.iCurrencyDigits = 2; // # local monetary fractional digits
- invariant.iCurrency = 0; // positive currency format
- invariant.iNegativeCurrency = 0; // negative currency format
- invariant.waMonetaryGrouping = new int[] { 3 }; // monetary grouping of digits
- invariant.sMonetaryDecimal = "."; // monetary decimal separator
- invariant.sMonetaryThousand = ","; // monetary thousands separator
-
- // Misc
- invariant.iMeasure = 0; // system of measurement 0=metric, 1=US (RegionInfo)
- invariant.sListSeparator = ","; // list separator
- // Unused for now:
- // invariant.iPaperSize =9; // default paper size (RegionInfo)
- // invariant.waFontSignature ="\x0002\x0000\x0000\x0000\x0000\x0000\x0000\x8000\x0001\x0000\x0000\x8000\x0001\x0000\x0000\x8000"; // Font signature (16 WORDS) (Windows Only)
-
- // Time
- invariant.sAM1159 = "AM"; // AM designator
- invariant.sPM2359 = "PM"; // PM designator
- invariant.saLongTimes = new String[] { "HH:mm:ss" }; // time format
- invariant.saShortTimes = new String[] { "HH:mm", "hh:mm tt", "H:mm", "h:mm tt" }; // short time format
- invariant.saDurationFormats = new String[] { "HH:mm:ss" }; // time duration format
-
- // Calendar specific data
- invariant.iFirstDayOfWeek = 0; // first day of week
- invariant.iFirstWeekOfYear = 0; // first week of year
- invariant.waCalendars = new int[] { (int)CalendarId.GREGORIAN }; // all available calendar type(s). The first one is the default calendar
-
- // Store for specific data about each calendar
- invariant.calendars = new CalendarData[CalendarData.MAX_CALENDARS];
- invariant.calendars[0] = CalendarData.Invariant;
-
- // Text information
- invariant.iReadingLayout = 0; // Reading Layout = RTL
-
- invariant.sTextInfo = ""; // Text info name to use for custom
- invariant.sCompareInfo = ""; // Compare info name (including sorting key) to use if custom
- invariant.sScripts = "Latn;"; // Typical Scripts for this locale (latn,cyrl, etc)
-
- invariant.iLanguage = 0x007f; // locale ID (0409) - NO sort information
- invariant.iDefaultAnsiCodePage = 1252; // default ansi code page ID (ACP)
- invariant.iDefaultOemCodePage = 437; // default oem code page ID (OCP or OEM)
- invariant.iDefaultMacCodePage = 10000; // default macintosh code page
- invariant.iDefaultEbcdicCodePage = 037; // default EBCDIC code page
- invariant.sAbbrevLang = "IVL"; // abbreviated language name (Windows Language Name)
- invariant.sAbbrevCountry = "IVC"; // abbreviated country name (RegionInfo) (Windows Region Name)
- invariant.sISO639Language2 = "ivl"; // 3 char ISO 639 lang name 2
- invariant.sISO3166CountryName2 = "ivc"; // 3 char ISO 3166 country name 2 2(RegionInfo)
- invariant.iInputLanguageHandle = 0x007f; // input language handle
- invariant.sConsoleFallbackName = ""; // The culture name for the console fallback UI culture
- invariant.sKeyboardsToInstall = "0409:00000409"; // Keyboard installation string.
- // Remember it
- s_Invariant = invariant;
+ StringStringDictionary regionNames = new StringStringDictionary(211 /* prime */);
+
+ regionNames.Add("029", "en-029");
+ regionNames.Add("AE", "ar-AE");
+ regionNames.Add("AF", "prs-AF");
+ regionNames.Add("AL", "sq-AL");
+ regionNames.Add("AM", "hy-AM");
+ regionNames.Add("AR", "es-AR");
+ regionNames.Add("AT", "de-AT");
+ regionNames.Add("AU", "en-AU");
+ regionNames.Add("AZ", "az-Cyrl-AZ");
+ regionNames.Add("BA", "bs-Latn-BA");
+ regionNames.Add("BD", "bn-BD");
+ regionNames.Add("BE", "nl-BE");
+ regionNames.Add("BG", "bg-BG");
+ regionNames.Add("BH", "ar-BH");
+ regionNames.Add("BN", "ms-BN");
+ regionNames.Add("BO", "es-BO");
+ regionNames.Add("BR", "pt-BR");
+ regionNames.Add("BY", "be-BY");
+ regionNames.Add("BZ", "en-BZ");
+ regionNames.Add("CA", "en-CA");
+ regionNames.Add("CH", "it-CH");
+ regionNames.Add("CL", "es-CL");
+ regionNames.Add("CN", "zh-CN");
+ regionNames.Add("CO", "es-CO");
+ regionNames.Add("CR", "es-CR");
+ regionNames.Add("CS", "sr-Cyrl-CS");
+ regionNames.Add("CZ", "cs-CZ");
+ regionNames.Add("DE", "de-DE");
+ regionNames.Add("DK", "da-DK");
+ regionNames.Add("DO", "es-DO");
+ regionNames.Add("DZ", "ar-DZ");
+ regionNames.Add("EC", "es-EC");
+ regionNames.Add("EE", "et-EE");
+ regionNames.Add("EG", "ar-EG");
+ regionNames.Add("ES", "es-ES");
+ regionNames.Add("ET", "am-ET");
+ regionNames.Add("FI", "fi-FI");
+ regionNames.Add("FO", "fo-FO");
+ regionNames.Add("FR", "fr-FR");
+ regionNames.Add("GB", "en-GB");
+ regionNames.Add("GE", "ka-GE");
+ regionNames.Add("GL", "kl-GL");
+ regionNames.Add("GR", "el-GR");
+ regionNames.Add("GT", "es-GT");
+ regionNames.Add("HK", "zh-HK");
+ regionNames.Add("HN", "es-HN");
+ regionNames.Add("HR", "hr-HR");
+ regionNames.Add("HU", "hu-HU");
+ regionNames.Add("ID", "id-ID");
+ regionNames.Add("IE", "en-IE");
+ regionNames.Add("IL", "he-IL");
+ regionNames.Add("IN", "hi-IN");
+ regionNames.Add("IQ", "ar-IQ");
+ regionNames.Add("IR", "fa-IR");
+ regionNames.Add("IS", "is-IS");
+ regionNames.Add("IT", "it-IT");
+ regionNames.Add("IV", "");
+ regionNames.Add("JM", "en-JM");
+ regionNames.Add("JO", "ar-JO");
+ regionNames.Add("JP", "ja-JP");
+ regionNames.Add("KE", "sw-KE");
+ regionNames.Add("KG", "ky-KG");
+ regionNames.Add("KH", "km-KH");
+ regionNames.Add("KR", "ko-KR");
+ regionNames.Add("KW", "ar-KW");
+ regionNames.Add("KZ", "kk-KZ");
+ regionNames.Add("LA", "lo-LA");
+ regionNames.Add("LB", "ar-LB");
+ regionNames.Add("LI", "de-LI");
+ regionNames.Add("LK", "si-LK");
+ regionNames.Add("LT", "lt-LT");
+ regionNames.Add("LU", "lb-LU");
+ regionNames.Add("LV", "lv-LV");
+ regionNames.Add("LY", "ar-LY");
+ regionNames.Add("MA", "ar-MA");
+ regionNames.Add("MC", "fr-MC");
+ regionNames.Add("ME", "sr-Latn-ME");
+ regionNames.Add("MK", "mk-MK");
+ regionNames.Add("MN", "mn-MN");
+ regionNames.Add("MO", "zh-MO");
+ regionNames.Add("MT", "mt-MT");
+ regionNames.Add("MV", "dv-MV");
+ regionNames.Add("MX", "es-MX");
+ regionNames.Add("MY", "ms-MY");
+ regionNames.Add("NG", "ig-NG");
+ regionNames.Add("NI", "es-NI");
+ regionNames.Add("NL", "nl-NL");
+ regionNames.Add("NO", "nn-NO");
+ regionNames.Add("NP", "ne-NP");
+ regionNames.Add("NZ", "en-NZ");
+ regionNames.Add("OM", "ar-OM");
+ regionNames.Add("PA", "es-PA");
+ regionNames.Add("PE", "es-PE");
+ regionNames.Add("PH", "en-PH");
+ regionNames.Add("PK", "ur-PK");
+ regionNames.Add("PL", "pl-PL");
+ regionNames.Add("PR", "es-PR");
+ regionNames.Add("PT", "pt-PT");
+ regionNames.Add("PY", "es-PY");
+ regionNames.Add("QA", "ar-QA");
+ regionNames.Add("RO", "ro-RO");
+ regionNames.Add("RS", "sr-Latn-RS");
+ regionNames.Add("RU", "ru-RU");
+ regionNames.Add("RW", "rw-RW");
+ regionNames.Add("SA", "ar-SA");
+ regionNames.Add("SE", "sv-SE");
+ regionNames.Add("SG", "zh-SG");
+ regionNames.Add("SI", "sl-SI");
+ regionNames.Add("SK", "sk-SK");
+ regionNames.Add("SN", "wo-SN");
+ regionNames.Add("SV", "es-SV");
+ regionNames.Add("SY", "ar-SY");
+ regionNames.Add("TH", "th-TH");
+ regionNames.Add("TJ", "tg-Cyrl-TJ");
+ regionNames.Add("TM", "tk-TM");
+ regionNames.Add("TN", "ar-TN");
+ regionNames.Add("TR", "tr-TR");
+ regionNames.Add("TT", "en-TT");
+ regionNames.Add("TW", "zh-TW");
+ regionNames.Add("UA", "uk-UA");
+ regionNames.Add("US", "en-US");
+ regionNames.Add("UY", "es-UY");
+ regionNames.Add("UZ", "uz-Cyrl-UZ");
+ regionNames.Add("VE", "es-VE");
+ regionNames.Add("VN", "vi-VN");
+ regionNames.Add("YE", "ar-YE");
+ regionNames.Add("ZA", "af-ZA");
+ regionNames.Add("ZW", "en-ZW");
+
+ s_RegionNames = regionNames;
}
- return s_Invariant;
- }
- }
- private volatile static CultureData s_Invariant;
- ///////////////
- // Constructors //
- ///////////////
- // Cache of cultures we've already looked up
- private static volatile Dictionary<String, CultureData> s_cachedCultures;
-
- [FriendAccessAllowed]
- internal static CultureData GetCultureData(String cultureName, bool useUserOverride)
- {
- // First do a shortcut for Invariant
- if (String.IsNullOrEmpty(cultureName))
- {
- return CultureData.Invariant;
- }
-
- // Try the hash table first
- String hashName = AnsiToLower(useUserOverride ? cultureName : cultureName + '*');
- Dictionary<String, CultureData> tempHashTable = s_cachedCultures;
- if (tempHashTable == null)
- {
- // No table yet, make a new one
- tempHashTable = new Dictionary<String, CultureData>();
- }
- else
- {
- // Check the hash table
- CultureData retVal;
- lock (((ICollection)tempHashTable).SyncRoot)
- {
- tempHashTable.TryGetValue(hashName, out retVal);
- }
- if (retVal != null)
- {
- return retVal;
- }
- }
-
- // Not found in the hash table, need to see if we can build one that works for us
- CultureData culture = CreateCultureData(cultureName, useUserOverride);
- if (culture == null)
- {
- return null;
- }
-
- // Found one, add it to the cache
- lock (((ICollection)tempHashTable).SyncRoot)
- {
- tempHashTable[hashName] = culture;
- }
-
- // Copy the hashtable to the corresponding member variables. This will potentially overwrite
- // new tables simultaneously created by a new thread, but maximizes thread safety.
- s_cachedCultures = tempHashTable;
-
- return culture;
- }
-
- private static CultureData CreateCultureData(string cultureName, bool useUserOverride)
- {
- CultureData culture = new CultureData();
- culture.bUseOverrides = useUserOverride;
- culture.sRealName = cultureName;
-
- // Ask native code if that one's real
- if (culture.InitCultureData() == false)
- {
- return null;
- }
-
- return culture;
- }
-
- private bool InitCultureData()
- {
- if (nativeInitCultureData(this) == false)
- {
- return false;
+ return s_RegionNames;
}
- return true;
}
// Cache of regions we've already looked up
- private static volatile Dictionary<String, CultureData> s_cachedRegions;
+ private static volatile StringCultureDataDictionary s_cachedRegions;
+ private static volatile StringStringDictionary s_RegionNames;
internal static CultureData GetCultureDataForRegion(String cultureName, bool useUserOverride)
{
@@ -571,16 +333,16 @@ namespace System.Globalization
// Try the hash table next
String hashName = AnsiToLower(useUserOverride ? cultureName : cultureName + '*');
- Dictionary<String, CultureData> tempHashTable = s_cachedRegions;
+ StringCultureDataDictionary tempHashTable = s_cachedRegions;
if (tempHashTable == null)
{
// No table yet, make a new one
- tempHashTable = new Dictionary<String, CultureData>();
+ tempHashTable = new StringCultureDataDictionary();
}
else
{
// Check the hash table
- lock (((ICollection)tempHashTable).SyncRoot)
+ lock (s_lock)
{
tempHashTable.TryGetValue(hashName, out retVal);
}
@@ -598,36 +360,25 @@ namespace System.Globalization
if (retVal == null || (retVal.IsNeutralCulture == true))
{
// Not a valid mapping, try the hard coded table
- if (RegionNames.ContainsKey(cultureName))
+ string name;
+ if (RegionNames.TryGetValue(cultureName, out name))
{
// Make sure we can get culture data for it
- retVal = GetCultureData(RegionNames[cultureName], useUserOverride);
+ retVal = GetCultureData(name, useUserOverride);
}
}
// If not found in the hard coded table we'll have to find a culture that works for us
if (retVal == null || (retVal.IsNeutralCulture == true))
{
- // Not found in the hard coded table, need to see if we can find a culture that works for us
- // Not a real culture name, see if it matches a region name
- // (we just return the first culture we match)
- CultureInfo[] specifics = SpecificCultures;
- for (int i = 0; i < specifics.Length; i++)
- {
- if (String.Compare(specifics[i].m_cultureData.SREGIONNAME, cultureName, StringComparison.OrdinalIgnoreCase) == 0)
- {
- // Matched, use this culture
- retVal = specifics[i].m_cultureData;
- break;
- }
- }
+ retVal = GetCultureDataFromRegionName(cultureName);
}
- // If we found one we can use, then cash it for next time
+ // If we found one we can use, then cache it for next time
if (retVal != null && (retVal.IsNeutralCulture == false))
{
// first add it to the cache
- lock (((ICollection)tempHashTable).SyncRoot)
+ lock (s_lock)
{
tempHashTable[hashName] = retVal;
}
@@ -647,54 +398,11 @@ namespace System.Globalization
return retVal;
}
-#if FEATURE_USE_LCID
- // Obtain locale name from LCID
- // NOTE: This will get neutral names, unlike the OS API
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern String LCIDToLocaleName(int lcid);
-
- // We'd rather people use the named version since this doesn't allow custom locales
- internal static CultureData GetCultureData(int culture, bool bUseUserOverride)
- {
- String localeName = null;
- CultureData retVal = null;
-
- if (localeName == null)
- {
- // Convert the lcid to a name, then use that
- // Note that this'll return neutral names (unlike Vista native API)
- localeName = LCIDToLocaleName(culture);
- }
-
- // If its not valid, then throw
- if (String.IsNullOrEmpty(localeName))
- {
- // Could be valid for Invariant
- if (culture == 0x007f)
- return Invariant;
- }
- else
- {
- // Valid name, use it
- retVal = GetCultureData(localeName, bUseUserOverride);
- }
-
- // If not successful, throw
- if (retVal == null)
- throw new CultureNotFoundException(
- nameof(culture), culture, Environment.GetResourceString("Argument_CultureNotSupported"));
-
- // Return the one we found
- return retVal;
- }
-#endif
-
// Clear our internal caches
internal static void ClearCachedData()
{
s_cachedCultures = null;
s_cachedRegions = null;
- s_replacementCultureNames = null;
}
internal static CultureInfo[] GetCultures(CultureTypes types)
@@ -703,23 +411,16 @@ namespace System.Globalization
#pragma warning disable 618
// Validate flags
if ((int)types <= 0 || ((int)types & (int)~(CultureTypes.NeutralCultures | CultureTypes.SpecificCultures |
- CultureTypes.InstalledWin32Cultures | CultureTypes.UserCustomCulture |
- CultureTypes.ReplacementCultures | CultureTypes.WindowsOnlyCultures |
- CultureTypes.FrameworkCultures)) != 0)
+ CultureTypes.InstalledWin32Cultures | CultureTypes.UserCustomCulture |
+ CultureTypes.ReplacementCultures | CultureTypes.WindowsOnlyCultures |
+ CultureTypes.FrameworkCultures)) != 0)
{
- throw new ArgumentOutOfRangeException(
- nameof(types),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"), CultureTypes.NeutralCultures, CultureTypes.FrameworkCultures));
+ throw new ArgumentOutOfRangeException(nameof(types),
+ SR.Format(SR.ArgumentOutOfRange_Range, CultureTypes.NeutralCultures, CultureTypes.FrameworkCultures));
}
- //
- // CHANGE FROM Whidbey
- //
// We have deprecated CultureTypes.FrameworkCultures.
// When this enum is used, we will enumerate Whidbey framework cultures (for compatibility).
- //
// We have deprecated CultureTypes.WindowsOnlyCultures.
// When this enum is used, we will return an empty array for this enum.
@@ -728,85 +429,349 @@ namespace System.Globalization
// Remove the enum as it is an no-op.
types &= (~CultureTypes.WindowsOnlyCultures);
}
+
+ if (GlobalizationMode.Invariant)
+ {
+ // in invariant mode we always return invariant culture only from the enumeration
+ return new CultureInfo[1] { new CultureInfo("") };
+ }
- String[] cultureNames = null;
+#pragma warning restore 618
+ return EnumCultures(types);
+ }
+
+ private static CultureData CreateCultureWithInvariantData()
+ {
+ // Make a new culturedata
+ CultureData invariant = new CultureData();
+
+ // Basics
+ // Note that we override the resources since this IS NOT supposed to change (by definition)
+ invariant._bUseOverrides = false;
+ invariant._sRealName = ""; // Name you passed in (ie: en-US, en, or de-DE_phoneb)
+ invariant._sWindowsName = ""; // Name OS thinks the object is (ie: de-DE_phoneb, or en-US (even if en was passed in))
+
+ // Identity
+ invariant._sName = ""; // locale name (ie: en-us)
+ invariant._sParent = ""; // Parent name (which may be a custom locale/culture)
+ invariant._bNeutral = false; // Flags for the culture (ie: neutral or not right now)
+ invariant._sEnglishDisplayName = "Invariant Language (Invariant Country)"; // English pretty name for this locale
+ invariant._sNativeDisplayName = "Invariant Language (Invariant Country)"; // Native pretty name for this locale
+ invariant._sSpecificCulture = ""; // The culture name to be used in CultureInfo.CreateSpecificCulture()
+
+ // Language
+ invariant._sISO639Language = "iv"; // ISO 639 Language Name
+ invariant._sISO639Language2 = "ivl"; // 3 char ISO 639 lang name 2
+ invariant._sLocalizedLanguage = "Invariant Language"; // Display name for this Language
+ invariant._sEnglishLanguage = "Invariant Language"; // English name for this language
+ invariant._sNativeLanguage = "Invariant Language"; // Native name of this language
+ invariant._sAbbrevLang = "IVL"; // abbreviated language name (Windows Language Name)
+ invariant._sConsoleFallbackName = ""; // The culture name for the console fallback UI culture
+ invariant._iInputLanguageHandle = 0x07F; // input language handle
+
+ // Region
+ invariant._sRegionName = "IV"; // (RegionInfo)
+ invariant._sEnglishCountry = "Invariant Country"; // english country name (RegionInfo)
+ invariant._sNativeCountry = "Invariant Country"; // native country name (Windows Only)
+ invariant._sISO3166CountryName = "IV"; // (RegionInfo), ie: US
+ invariant._sISO3166CountryName2 = "ivc"; // 3 char ISO 3166 country name 2 2(RegionInfo)
+ invariant._iGeoId = 244; // GeoId (Windows Only)
+
+ // Numbers
+ invariant._sPositiveSign = "+"; // positive sign
+ invariant._sNegativeSign = "-"; // negative sign
+ invariant._iDigits = 2; // number of fractional digits
+ invariant._iNegativeNumber = 1; // negative number format
+ invariant._waGrouping = new int[] { 3 }; // grouping of digits
+ invariant._sDecimalSeparator = "."; // decimal separator
+ invariant._sThousandSeparator = ","; // thousands separator
+ invariant._sNaN = "NaN"; // Not a Number
+ invariant._sPositiveInfinity = "Infinity"; // + Infinity
+ invariant._sNegativeInfinity = "-Infinity"; // - Infinity
+
+ // Percent
+ invariant._iNegativePercent = 0; // Negative Percent (0-3)
+ invariant._iPositivePercent = 0; // Positive Percent (0-11)
+ invariant._sPercent = "%"; // Percent (%) symbol
+ invariant._sPerMille = "\x2030"; // PerMille symbol
+
+ // Currency
+ invariant._sCurrency = "\x00a4"; // local monetary symbol: for international monetary symbol
+ invariant._sIntlMonetarySymbol = "XDR"; // international monetary symbol (RegionInfo)
+ invariant._sEnglishCurrency = "International Monetary Fund"; // English name for this currency (Windows Only)
+ invariant._sNativeCurrency = "International Monetary Fund"; // Native name for this currency (Windows Only)
+ invariant._iCurrencyDigits = 2; // # local monetary fractional digits
+ invariant._iCurrency = 0; // positive currency format
+ invariant._iNegativeCurrency = 0; // negative currency format
+ invariant._waMonetaryGrouping = new int[] { 3 }; // monetary grouping of digits
+ invariant._sMonetaryDecimal = "."; // monetary decimal separator
+ invariant._sMonetaryThousand = ","; // monetary thousands separator
+
+ // Misc
+ invariant._iMeasure = 0; // system of measurement 0=metric, 1=US (RegionInfo)
+ invariant._sListSeparator = ","; // list separator
+
+ // Time
+ invariant._sTimeSeparator = ":";
+ invariant._sAM1159 = "AM"; // AM designator
+ invariant._sPM2359 = "PM"; // PM designator
+ invariant._saLongTimes = new String[] { "HH:mm:ss" }; // time format
+ invariant._saShortTimes = new String[] { "HH:mm", "hh:mm tt", "H:mm", "h:mm tt" }; // short time format
+ invariant._saDurationFormats = new String[] { "HH:mm:ss" }; // time duration format
+
+
+ // Calendar specific data
+ invariant._iFirstDayOfWeek = 0; // first day of week
+ invariant._iFirstWeekOfYear = 0; // first week of year
+ invariant._waCalendars = new CalendarId[] { CalendarId.GREGORIAN }; // all available calendar type(s). The first one is the default calendar
+
+ // Store for specific data about each calendar
+ invariant._calendars = new CalendarData[CalendarData.MAX_CALENDARS];
+ invariant._calendars[0] = CalendarData.Invariant;
+
+ // Text information
+ invariant._iReadingLayout = 0;
+
+ // These are desktop only, not coreclr
+
+ invariant._iLanguage = CultureInfo.LOCALE_INVARIANT; // locale ID (0409) - NO sort information
+ invariant._iDefaultAnsiCodePage = 1252; // default ansi code page ID (ACP)
+ invariant._iDefaultOemCodePage = 437; // default oem code page ID (OCP or OEM)
+ invariant._iDefaultMacCodePage = 10000; // default macintosh code page
+ invariant._iDefaultEbcdicCodePage = 037; // default EBCDIC code page
+
+ if (GlobalizationMode.Invariant)
+ {
+ invariant._sLocalizedDisplayName = invariant._sNativeDisplayName;
+ invariant._sLocalizedCountry = invariant._sNativeCountry;
+ }
+
+ return invariant;
+ }
- //
- // Call nativeEnumCultureNames() to get a string array of culture names based on the specified
- // enumeration type.
- //
- // nativeEnumCultureNames is a QCall. We need to use a reference to return the string array
- // allocated from the QCall. That ref has to be wrapped as object handle.
- // See vm\qcall.h for details in QCall.
- //
+ /////////////////////////////////////////////////////////////////////////
+ // Build our invariant information
+ //
+ // We need an invariant instance, which we build hard-coded
+ /////////////////////////////////////////////////////////////////////////
+ internal static CultureData Invariant
+ {
+ get
+ {
+ if (s_Invariant == null)
+ {
+ // Remember it
+ s_Invariant = CreateCultureWithInvariantData();
+ }
+ return s_Invariant;
+ }
+ }
+ private volatile static CultureData s_Invariant;
- if (nativeEnumCultureNames((int)types, JitHelpers.GetObjectHandleOnStack(ref cultureNames)) == 0)
+ ///////////////
+ // Constructors //
+ ///////////////
+ // Cache of cultures we've already looked up
+ private static volatile StringCultureDataDictionary s_cachedCultures;
+ private static readonly Lock s_lock = new Lock();
+
+ internal static CultureData GetCultureData(String cultureName, bool useUserOverride)
+ {
+ // First do a shortcut for Invariant
+ if (String.IsNullOrEmpty(cultureName))
{
- return new CultureInfo[0];
+ return CultureData.Invariant;
}
- int arrayLength = cultureNames.Length;
+ // Try the hash table first
+ String hashName = AnsiToLower(useUserOverride ? cultureName : cultureName + '*');
+ StringCultureDataDictionary tempHashTable = s_cachedCultures;
+ if (tempHashTable == null)
+ {
+ // No table yet, make a new one
+ tempHashTable = new StringCultureDataDictionary();
+ }
+ else
+ {
+ // Check the hash table
+ bool ret;
+ CultureData retVal;
+ lock (s_lock)
+ {
+ ret = tempHashTable.TryGetValue(hashName, out retVal);
+ }
+ if (ret && retVal != null)
+ {
+ return retVal;
+ }
+ }
- CultureInfo[] cultures = new CultureInfo[arrayLength];
+ // Not found in the hash table, need to see if we can build one that works for us
+ CultureData culture = CreateCultureData(cultureName, useUserOverride);
+ if (culture == null)
+ {
+ return null;
+ }
- for (int i = 0; i < cultureNames.Length; i++)
+ // Found one, add it to the cache
+ lock (s_lock)
{
- cultures[i] = new CultureInfo(cultureNames[i]);
+ tempHashTable[hashName] = culture;
}
-#pragma warning restore 618
- return cultures;
- }
+ // Copy the hashtable to the corresponding member variables. This will potentially overwrite
+ // new tables simultaneously created by a new thread, but maximizes thread safety.
+ s_cachedCultures = tempHashTable;
- internal static volatile CultureInfo[] specificCultures;
+ return culture;
+ }
- private static CultureInfo[] SpecificCultures
+ private static unsafe string NormalizeCultureName(string name, out bool isNeutralName)
{
- get
+ isNeutralName = true;
+ int i = 0;
+
+ Debug.Assert(name.Length <= LOCALE_NAME_MAX_LENGTH);
+
+ char *pName = stackalloc char[LOCALE_NAME_MAX_LENGTH];
+ bool changed = false;
+
+ while (i < name.Length && name[i] != '-' && name[i] != '_')
{
- if (specificCultures == null)
- specificCultures = GetCultures(CultureTypes.SpecificCultures);
+ if (name[i] >= 'A' && name[i] <= 'Z')
+ {
+ // lowercase characters before '-'
+ pName[i] = (char) (((int)name[i]) + 0x20);
+ changed = true;
+ }
+ else
+ {
+ pName[i] = name[i];
+ }
+ i++;
+ }
- return specificCultures;
+ if (i < name.Length)
+ {
+ // this is not perfect to detect the non neutral cultures but it is good enough when we are running in invariant mode
+ isNeutralName = false;
}
+
+ while (i < name.Length)
+ {
+ if (name[i] >= 'a' && name[i] <= 'z')
+ {
+ pName[i] = (char) (((int)name[i]) - 0x20);
+ changed = true;
+ }
+ else
+ {
+ pName[i] = name[i];
+ }
+ i++;
+ }
+
+ if (changed)
+ return new string(pName, 0, name.Length);
+
+ return name;
}
- internal bool IsReplacementCulture
+ private static CultureData CreateCultureData(string cultureName, bool useUserOverride)
{
- get
+ if (GlobalizationMode.Invariant)
{
- return IsReplacementCultureName(this.SNAME);
+ CultureInfo.VerifyCultureName(cultureName, true);
+ CultureData cd = CreateCultureWithInvariantData();
+ cd._bUseOverrides = useUserOverride;
+ cd._sName = NormalizeCultureName(cultureName, out cd._bNeutral);
+ cd._sRealName = cd._sName;
+ cd._sWindowsName = cd._sName;
+ cd._iLanguage = CultureInfo.LOCALE_CUSTOM_UNSPECIFIED;
+
+ return cd;
}
- }
- internal static volatile String[] s_replacementCultureNames;
+ CultureData culture = new CultureData();
+ culture._bUseOverrides = useUserOverride;
+ culture._sRealName = cultureName;
- ////////////////////////////////////////////////////////////////////////
- //
- // Cache for the known replacement cultures.
- // This is used by CultureInfo.CultureType to check if a culture is a
- // replacement culture.
- //
- ////////////////////////////////////////////////////////////////////////
+ // Ask native code if that one's real
+ if (culture.InitCultureData() == false)
+ {
+ if (culture.InitCompatibilityCultureData() == false)
+ {
+ return null;
+ }
+ }
+ return culture;
+ }
- private static bool IsReplacementCultureName(String name)
+ private bool InitCompatibilityCultureData()
{
- Debug.Assert(name != null, "IsReplacementCultureName(): name should not be null");
- String[] replacementCultureNames = s_replacementCultureNames;
- if (replacementCultureNames == null)
+ // for compatibility handle the deprecated ids: zh-chs, zh-cht
+ string cultureName = _sRealName;
+
+ string fallbackCultureName;
+ string realCultureName;
+ switch (AnsiToLower(cultureName))
{
- if (nativeEnumCultureNames((int)CultureTypes.ReplacementCultures, JitHelpers.GetObjectHandleOnStack(ref replacementCultureNames)) == 0)
- {
+ case "zh-chs":
+ fallbackCultureName = "zh-Hans";
+ realCultureName = "zh-CHS";
+ break;
+ case "zh-cht":
+ fallbackCultureName = "zh-Hant";
+ realCultureName = "zh-CHT";
+ break;
+ default:
return false;
- }
+ }
+
+ _sRealName = fallbackCultureName;
+ if (InitCultureData() == false)
+ {
+ return false;
+ }
+ // fixup our data
+ _sName = realCultureName; // the name that goes back to the user
+ _sParent = fallbackCultureName;
+
+ return true;
+ }
+
+ // We'd rather people use the named version since this doesn't allow custom locales
+ internal static CultureData GetCultureData(int culture, bool bUseUserOverride)
+ {
+ string localeName = null;
+ CultureData retVal = null;
+
+ if (culture == CultureInfo.LOCALE_INVARIANT)
+ return Invariant;
+
+ if (GlobalizationMode.Invariant)
+ {
+ // LCID is not supported in the InvariantMode
+ throw new CultureNotFoundException(nameof(culture), culture, SR.Argument_CultureNotSupported);
+ }
+
+ // Convert the lcid to a name, then use that
+ // Note that this will return neutral names (unlike Vista native API)
+ localeName = LCIDToLocaleName(culture);
- // Even if we don't have any replacement cultures, the returned replacementCultureNames will still an empty string array, not null.
- Debug.Assert(name != null, "IsReplacementCultureName(): replacementCultureNames should not be null");
- Array.Sort(replacementCultureNames);
- s_replacementCultureNames = replacementCultureNames;
+ if (!String.IsNullOrEmpty(localeName))
+ {
+ // Valid name, use it
+ retVal = GetCultureData(localeName, bUseUserOverride);
}
- return Array.BinarySearch(replacementCultureNames, name) >= 0;
+
+ // If not successful, throw
+ if (retVal == null)
+ throw new CultureNotFoundException(nameof(culture), culture, SR.Argument_CultureNotSupported);
+
+ // Return the one we found
+ return retVal;
}
////////////////////////////////////////////////////////////////////////
@@ -826,17 +791,17 @@ namespace System.Globalization
{
get
{
- Debug.Assert(this.sRealName != null, "[CultureData.CultureName] Expected this.sRealName to be populated by COMNlsInfo::nativeInitCultureData already");
+ Debug.Assert(_sRealName != null, "[CultureData.CultureName] Expected _sRealName to be populated by already");
// since windows doesn't know about zh-CHS and zh-CHT,
// we leave sRealName == zh-Hanx but we still need to
// pretend that it was zh-CHX.
- switch (this.sName)
+ switch (_sName)
{
case "zh-CHS":
case "zh-CHT":
- return this.sName;
+ return _sName;
}
- return this.sRealName;
+ return _sRealName;
}
}
@@ -845,7 +810,7 @@ namespace System.Globalization
{
get
{
- return this.bUseOverrides;
+ return _bUseOverrides;
}
}
@@ -854,13 +819,11 @@ namespace System.Globalization
{
get
{
- // Debug.Assert(this.sName != null,
- // "[CultureData.SNAME] Expected this.sName to be populated by COMNlsInfo::nativeInitCultureData already");
- if (this.sName == null)
+ if (_sName == null)
{
- this.sName = String.Empty;
+ _sName = String.Empty;
}
- return this.sName;
+ return _sName;
}
}
@@ -869,12 +832,12 @@ namespace System.Globalization
{
get
{
- if (this.sParent == null)
+ if (_sParent == null)
{
// Ask using the real name, so that we get parents of neutrals
- this.sParent = DoGetLocaleInfo(this.sRealName, LOCALE_SPARENT);
+ _sParent = GetLocaleInfo(_sRealName, LocaleStringData.ParentName);
}
- return this.sParent;
+ return _sParent;
}
}
@@ -883,31 +846,73 @@ namespace System.Globalization
{
get
{
- if (this.sLocalizedDisplayName == null)
+ if (_sLocalizedDisplayName == null)
{
+ if (this.IsSupplementalCustomCulture)
+ {
+ if (this.IsNeutralCulture)
+ {
+ _sLocalizedDisplayName = this.SNATIVELANGUAGE;
+ }
+ else
+ {
+ _sLocalizedDisplayName = this.SNATIVEDISPLAYNAME;
+ }
+ }
+ else
+ {
+ try
+ {
+ const string ZH_CHT = "zh-CHT";
+ const string ZH_CHS = "zh-CHS";
+
+ if (SNAME.Equals(ZH_CHT, StringComparison.OrdinalIgnoreCase))
+ {
+ _sLocalizedDisplayName = GetLanguageDisplayName("zh-Hant");
+ }
+ else if (SNAME.Equals(ZH_CHS, StringComparison.OrdinalIgnoreCase))
+ {
+ _sLocalizedDisplayName = GetLanguageDisplayName("zh-Hans");
+ }
+ else
+ {
+ _sLocalizedDisplayName = GetLanguageDisplayName(SNAME);
+ }
+ }
+ catch (Exception)
+ {
+ // do nothing
+ }
+ }
// If it hasn't been found (Windows 8 and up), fallback to the system
- if (String.IsNullOrEmpty(this.sLocalizedDisplayName))
+ if (String.IsNullOrEmpty(_sLocalizedDisplayName))
{
// If its neutral use the language name
if (this.IsNeutralCulture)
{
- this.sLocalizedDisplayName = this.SLOCALIZEDLANGUAGE;
+ _sLocalizedDisplayName = this.SLOCALIZEDLANGUAGE;
}
else
{
- // We have to make the neutral distinction in case the OS returns a specific name
- if (CultureInfo.UserDefaultUICulture.Name.Equals(Thread.CurrentThread.CurrentUICulture.Name))
+ // Usually the UI culture shouldn't be different than what we got from WinRT except
+ // if DefaultThreadCurrentUICulture was set
+ CultureInfo ci;
+
+ if (CultureInfo.DefaultThreadCurrentUICulture != null &&
+ ((ci = GetUserDefaultCulture()) != null) &&
+ !CultureInfo.DefaultThreadCurrentUICulture.Name.Equals(ci.Name))
{
- this.sLocalizedDisplayName = DoGetLocaleInfo(LOCALE_SLOCALIZEDDISPLAYNAME);
+ _sLocalizedDisplayName = this.SNATIVEDISPLAYNAME;
}
- if (String.IsNullOrEmpty(this.sLocalizedDisplayName))
+ else
{
- this.sLocalizedDisplayName = this.SNATIVEDISPLAYNAME;
+ _sLocalizedDisplayName = GetLocaleInfo(LocaleStringData.LocalizedDisplayName);
}
}
}
}
- return this.sLocalizedDisplayName;
+
+ return _sLocalizedDisplayName;
}
}
@@ -916,39 +921,47 @@ namespace System.Globalization
{
get
{
- if (this.sEnglishDisplayName == null)
+ if (_sEnglishDisplayName == null)
{
// If its neutral use the language name
if (this.IsNeutralCulture)
{
- this.sEnglishDisplayName = this.SENGLISHLANGUAGE;
+ _sEnglishDisplayName = this.SENGLISHLANGUAGE;
+ // differentiate the legacy display names
+ switch (_sName)
+ {
+ case "zh-CHS":
+ case "zh-CHT":
+ _sEnglishDisplayName += " Legacy";
+ break;
+ }
}
else
{
- this.sEnglishDisplayName = DoGetLocaleInfo(LOCALE_SENGLISHDISPLAYNAME);
+ _sEnglishDisplayName = GetLocaleInfo(LocaleStringData.EnglishDisplayName);
// if it isn't found build one:
- if (String.IsNullOrEmpty(this.sEnglishDisplayName))
+ if (String.IsNullOrEmpty(_sEnglishDisplayName))
{
// Our existing names mostly look like:
// "English" + "United States" -> "English (United States)"
// "Azeri (Latin)" + "Azerbaijan" -> "Azeri (Latin, Azerbaijan)"
- if (this.SENGLISHLANGUAGE.EndsWith(')'))
+ if (this.SENGLISHLANGUAGE[this.SENGLISHLANGUAGE.Length - 1] == ')')
{
// "Azeri (Latin)" + "Azerbaijan" -> "Azeri (Latin, Azerbaijan)"
- this.sEnglishDisplayName =
- this.SENGLISHLANGUAGE.Substring(0, this.sEnglishLanguage.Length - 1) +
+ _sEnglishDisplayName =
+ this.SENGLISHLANGUAGE.Substring(0, _sEnglishLanguage.Length - 1) +
", " + this.SENGCOUNTRY + ")";
}
else
{
// "English" + "United States" -> "English (United States)"
- this.sEnglishDisplayName = this.SENGLISHLANGUAGE + " (" + this.SENGCOUNTRY + ")";
+ _sEnglishDisplayName = this.SENGLISHLANGUAGE + " (" + this.SENGCOUNTRY + ")";
}
}
}
}
- return this.sEnglishDisplayName;
+ return _sEnglishDisplayName;
}
}
@@ -957,37 +970,47 @@ namespace System.Globalization
{
get
{
- if (this.sNativeDisplayName == null)
+ if (_sNativeDisplayName == null)
{
// If its neutral use the language name
if (this.IsNeutralCulture)
{
- this.sNativeDisplayName = this.SNATIVELANGUAGE;
+ _sNativeDisplayName = this.SNATIVELANGUAGE;
+ // differentiate the legacy display names
+ switch (_sName)
+ {
+ case "zh-CHS":
+ _sNativeDisplayName += " \u65E7\u7248";
+ break;
+ case "zh-CHT":
+ _sNativeDisplayName += " \u820A\u7248";
+ break;
+ }
}
else
{
- this.sNativeDisplayName = DoGetLocaleInfo(LOCALE_SNATIVEDISPLAYNAME);
+ _sNativeDisplayName = GetLocaleInfo(LocaleStringData.NativeDisplayName);
// if it isn't found build one:
- if (String.IsNullOrEmpty(this.sNativeDisplayName))
+ if (String.IsNullOrEmpty(_sNativeDisplayName))
{
// These should primarily be "Deutsch (Deutschland)" type names
- this.sNativeDisplayName = this.SNATIVELANGUAGE + " (" + this.SNATIVECOUNTRY + ")";
+ _sNativeDisplayName = this.SNATIVELANGUAGE + " (" + this.SNATIVECOUNTRY + ")";
}
}
}
- return this.sNativeDisplayName;
+ return _sNativeDisplayName;
}
}
// The culture name to be used in CultureInfo.CreateSpecificCulture()
- internal String SSPECIFICCULTURE
+ internal string SSPECIFICCULTURE
{
get
{
- // This got populated when ComNlsInfo::nativeInitCultureData told us we had a culture
- Debug.Assert(this.sSpecificCulture != null, "[CultureData.SSPECIFICCULTURE] Expected this.sSpecificCulture to be populated by COMNlsInfo::nativeInitCultureData already");
- return this.sSpecificCulture;
+ // This got populated during the culture initialization
+ Debug.Assert(_sSpecificCulture != null, "[CultureData.SSPECIFICCULTURE] Expected this.sSpecificCulture to be populated by culture data initialization already");
+ return _sSpecificCulture;
}
}
@@ -1000,37 +1023,37 @@ namespace System.Globalization
{
get
{
- if (this.sISO639Language == null)
+ if (_sISO639Language == null)
{
- this.sISO639Language = DoGetLocaleInfo(LOCALE_SISO639LANGNAME);
+ _sISO639Language = GetLocaleInfo(LocaleStringData.Iso639LanguageTwoLetterName);
}
- return this.sISO639Language;
+ return _sISO639Language;
}
}
// iso 639 language name, ie: eng
- internal String SISO639LANGNAME2
+ internal string SISO639LANGNAME2
{
get
{
- if (this.sISO639Language2 == null)
+ if (_sISO639Language2 == null)
{
- this.sISO639Language2 = DoGetLocaleInfo(LOCALE_SISO639LANGNAME2);
+ _sISO639Language2 = GetLocaleInfo(LocaleStringData.Iso639LanguageThreeLetterName);
}
- return this.sISO639Language2;
+ return _sISO639Language2;
}
}
// abbreviated windows language name (ie: enu) (non-standard, avoid this)
- internal String SABBREVLANGNAME
+ internal string SABBREVLANGNAME
{
get
{
- if (this.sAbbrevLang == null)
+ if (_sAbbrevLang == null)
{
- this.sAbbrevLang = DoGetLocaleInfo(LOCALE_SABBREVLANGNAME);
+ _sAbbrevLang = GetThreeLetterWindowsLanguageName(_sRealName);
}
- return this.sAbbrevLang;
+ return _sAbbrevLang;
}
}
@@ -1040,20 +1063,25 @@ namespace System.Globalization
{
get
{
- if (this.sLocalizedLanguage == null)
+ if (_sLocalizedLanguage == null)
{
- if (CultureInfo.UserDefaultUICulture.Name.Equals(Thread.CurrentThread.CurrentUICulture.Name))
+ // Usually the UI culture shouldn't be different than what we got from WinRT except
+ // if DefaultThreadCurrentUICulture was set
+ CultureInfo ci;
+
+ if (CultureInfo.DefaultThreadCurrentUICulture != null &&
+ ((ci = GetUserDefaultCulture()) != null) &&
+ !CultureInfo.DefaultThreadCurrentUICulture.Name.Equals(ci.Name))
{
- this.sLocalizedLanguage = DoGetLocaleInfo(LOCALE_SLOCALIZEDLANGUAGENAME);
+ _sLocalizedLanguage = SNATIVELANGUAGE;
}
- // Some OS's might not have this resource or LCTYPE
- if (String.IsNullOrEmpty(this.sLocalizedLanguage))
+ else
{
- this.sLocalizedLanguage = SNATIVELANGUAGE;
+ _sLocalizedLanguage = GetLocaleInfo(LocaleStringData.LocalizedLanguageName);
}
}
- return this.sLocalizedLanguage;
+ return _sLocalizedLanguage;
}
}
@@ -1062,11 +1090,11 @@ namespace System.Globalization
{
get
{
- if (this.sEnglishLanguage == null)
+ if (_sEnglishLanguage == null)
{
- this.sEnglishLanguage = DoGetLocaleInfo(LOCALE_SENGLISHLANGUAGENAME);
+ _sEnglishLanguage = GetLocaleInfo(LocaleStringData.EnglishLanguageName);
}
- return this.sEnglishLanguage;
+ return _sEnglishLanguage;
}
}
@@ -1075,13 +1103,11 @@ namespace System.Globalization
{
get
{
- if (this.sNativeLanguage == null)
+ if (_sNativeLanguage == null)
{
- {
- this.sNativeLanguage = DoGetLocaleInfo(LOCALE_SNATIVELANGUAGENAME);
- }
+ _sNativeLanguage = GetLocaleInfo(LocaleStringData.NativeLanguageName);
}
- return this.sNativeLanguage;
+ return _sNativeLanguage;
}
}
@@ -1094,24 +1120,23 @@ namespace System.Globalization
{
get
{
- if (this.sRegionName == null)
+ if (_sRegionName == null)
{
- this.sRegionName = DoGetLocaleInfo(LOCALE_SISO3166CTRYNAME);
+ _sRegionName = GetLocaleInfo(LocaleStringData.Iso3166CountryName);
}
- return this.sRegionName;
+ return _sRegionName;
}
}
- // GeoId
internal int IGEOID
{
get
{
- if (this.iGeoId == undef)
+ if (_iGeoId == undef)
{
- this.iGeoId = DoGetLocaleInfoInt(LOCALE_IGEOID);
+ _iGeoId = GetGeoId(_sRealName);
}
- return this.iGeoId;
+ return _iGeoId;
}
}
@@ -1120,23 +1145,23 @@ namespace System.Globalization
{
get
{
- if (this.sLocalizedCountry == null)
+ if (_sLocalizedCountry == null)
{
- // If it hasn't been found (Windows 8 and up), fallback to the system
- if (String.IsNullOrEmpty(this.sLocalizedCountry))
+ try
{
- // We have to make the neutral distinction in case the OS returns a specific name
- if (CultureInfo.UserDefaultUICulture.Name.Equals(Thread.CurrentThread.CurrentUICulture.Name))
- {
- this.sLocalizedCountry = DoGetLocaleInfo(LOCALE_SLOCALIZEDCOUNTRYNAME);
- }
- if (String.IsNullOrEmpty(this.sLocalizedDisplayName))
- {
- this.sLocalizedCountry = SNATIVECOUNTRY;
- }
+ _sLocalizedCountry = GetRegionDisplayName(SISO3166CTRYNAME);
+ }
+ catch (Exception)
+ {
+ // do nothing. we'll fallback
+ }
+
+ if (_sLocalizedCountry == null)
+ {
+ _sLocalizedCountry = SNATIVECOUNTRY;
}
}
- return this.sLocalizedCountry;
+ return _sLocalizedCountry;
}
}
@@ -1145,11 +1170,11 @@ namespace System.Globalization
{
get
{
- if (this.sEnglishCountry == null)
+ if (_sEnglishCountry == null)
{
- this.sEnglishCountry = DoGetLocaleInfo(LOCALE_SENGLISHCOUNTRYNAME);
+ _sEnglishCountry = GetLocaleInfo(LocaleStringData.EnglishCountryName);
}
- return this.sEnglishCountry;
+ return _sEnglishCountry;
}
}
@@ -1158,11 +1183,11 @@ namespace System.Globalization
{
get
{
- if (this.sNativeCountry == null)
+ if (_sNativeCountry == null)
{
- this.sNativeCountry = DoGetLocaleInfo(LOCALE_SNATIVECOUNTRYNAME);
+ _sNativeCountry = GetLocaleInfo(LocaleStringData.NativeCountryName);
}
- return this.sNativeCountry;
+ return _sNativeCountry;
}
}
@@ -1171,90 +1196,70 @@ namespace System.Globalization
{
get
{
- if (this.sISO3166CountryName == null)
+ if (_sISO3166CountryName == null)
{
- this.sISO3166CountryName = DoGetLocaleInfo(LOCALE_SISO3166CTRYNAME);
+ _sISO3166CountryName = GetLocaleInfo(LocaleStringData.Iso3166CountryName);
}
- return this.sISO3166CountryName;
+ return _sISO3166CountryName;
}
}
- // ISO 3166 Country Name
+ // 3 letter ISO 3166 country code
internal String SISO3166CTRYNAME2
{
get
{
- if (this.sISO3166CountryName2 == null)
+ if (_sISO3166CountryName2 == null)
{
- this.sISO3166CountryName2 = DoGetLocaleInfo(LOCALE_SISO3166CTRYNAME2);
+ _sISO3166CountryName2 = GetLocaleInfo(LocaleStringData.Iso3166CountryName2);
}
- return this.sISO3166CountryName2;
+ return _sISO3166CountryName2;
}
}
- // abbreviated Country Name (windows version, non-standard, avoid)
- internal String SABBREVCTRYNAME
- {
- get
- {
- if (this.sAbbrevCountry == null)
- {
- this.sAbbrevCountry = DoGetLocaleInfo(LOCALE_SABBREVCTRYNAME);
- }
- return this.sAbbrevCountry;
- }
- }
-
- // Console fallback name (ie: locale to use for console apps for unicode-only locales)
internal int IINPUTLANGUAGEHANDLE
{
get
{
- if (this.iInputLanguageHandle == undef)
+ if (_iInputLanguageHandle == undef)
{
if (IsSupplementalCustomCulture)
{
- this.iInputLanguageHandle = 0x0409;
+ _iInputLanguageHandle = 0x0409;
}
else
{
// Input Language is same as LCID for built-in cultures
- this.iInputLanguageHandle = this.ILANGUAGE;
+ _iInputLanguageHandle = this.ILANGUAGE;
}
}
- return this.iInputLanguageHandle;
+ return _iInputLanguageHandle;
}
}
// Console fallback name (ie: locale to use for console apps for unicode-only locales)
- internal String SCONSOLEFALLBACKNAME
+ internal string SCONSOLEFALLBACKNAME
{
get
{
- if (this.sConsoleFallbackName == null)
+ if (_sConsoleFallbackName == null)
{
- string consoleFallbackName = DoGetLocaleInfo(LOCALE_SCONSOLEFALLBACKNAME);
- if (consoleFallbackName == "es-ES_tradnl")
- {
- consoleFallbackName = "es-ES";
- }
- this.sConsoleFallbackName = consoleFallbackName;
+ _sConsoleFallbackName = GetConsoleFallbackName(_sRealName);
}
- return this.sConsoleFallbackName;
+ return _sConsoleFallbackName;
}
}
-
// (user can override) grouping of digits
internal int[] WAGROUPING
{
get
{
- if (this.waGrouping == null || UseUserOverride)
+ if (_waGrouping == null)
{
- this.waGrouping = ConvertWin32GroupString(DoGetLocaleInfo(LOCALE_SGROUPING));
+ _waGrouping = GetLocaleInfo(LocaleGroupingData.Digit);
}
- return this.waGrouping;
+ return _waGrouping;
}
}
@@ -1267,11 +1272,11 @@ namespace System.Globalization
{
get
{
- if (this.sNaN == null)
+ if (_sNaN == null)
{
- this.sNaN = DoGetLocaleInfo(LOCALE_SNAN);
+ _sNaN = GetLocaleInfo(LocaleStringData.NaNSymbol);
}
- return this.sNaN;
+ return _sNaN;
}
}
@@ -1280,11 +1285,11 @@ namespace System.Globalization
{
get
{
- if (this.sPositiveInfinity == null)
+ if (_sPositiveInfinity == null)
{
- this.sPositiveInfinity = DoGetLocaleInfo(LOCALE_SPOSINFINITY);
+ _sPositiveInfinity = GetLocaleInfo(LocaleStringData.PositiveInfinitySymbol);
}
- return this.sPositiveInfinity;
+ return _sPositiveInfinity;
}
}
@@ -1293,11 +1298,11 @@ namespace System.Globalization
{
get
{
- if (this.sNegativeInfinity == null)
+ if (_sNegativeInfinity == null)
{
- this.sNegativeInfinity = DoGetLocaleInfo(LOCALE_SNEGINFINITY);
+ _sNegativeInfinity = GetLocaleInfo(LocaleStringData.NegativeInfinitySymbol);
}
- return this.sNegativeInfinity;
+ return _sNegativeInfinity;
}
}
@@ -1311,12 +1316,12 @@ namespace System.Globalization
{
get
{
- if (this.iNegativePercent == undef)
+ if (_iNegativePercent == undef)
{
// Note that <= Windows Vista this is synthesized by native code
- this.iNegativePercent = DoGetLocaleInfoInt(LOCALE_INEGATIVEPERCENT);
+ _iNegativePercent = GetLocaleInfo(LocaleNumberData.NegativePercentFormat);
}
- return this.iNegativePercent;
+ return _iNegativePercent;
}
}
@@ -1325,12 +1330,12 @@ namespace System.Globalization
{
get
{
- if (this.iPositivePercent == undef)
+ if (_iPositivePercent == undef)
{
// Note that <= Windows Vista this is synthesized by native code
- this.iPositivePercent = DoGetLocaleInfoInt(LOCALE_IPOSITIVEPERCENT);
+ _iPositivePercent = GetLocaleInfo(LocaleNumberData.PositivePercentFormat);
}
- return this.iPositivePercent;
+ return _iPositivePercent;
}
}
@@ -1339,26 +1344,24 @@ namespace System.Globalization
{
get
{
- if (this.sPercent == null)
+ if (_sPercent == null)
{
- // Note that <= Windows Vista this is synthesized by native code
- this.sPercent = DoGetLocaleInfo(LOCALE_SPERCENT);
+ _sPercent = GetLocaleInfo(LocaleStringData.PercentSymbol);
}
- return this.sPercent;
+ return _sPercent;
}
}
- // PerMille (‰) symbol
+ // PerMille symbol
internal String SPERMILLE
{
get
{
- if (this.sPerMille == null)
+ if (_sPerMille == null)
{
- // Note that <= Windows Vista this is synthesized by native code
- this.sPerMille = DoGetLocaleInfo(LOCALE_SPERMILLE);
+ _sPerMille = GetLocaleInfo(LocaleStringData.PerMilleSymbol);
}
- return this.sPerMille;
+ return _sPerMille;
}
}
@@ -1371,11 +1374,11 @@ namespace System.Globalization
{
get
{
- if (this.sCurrency == null || UseUserOverride)
+ if (_sCurrency == null)
{
- this.sCurrency = DoGetLocaleInfo(LOCALE_SCURRENCY);
+ _sCurrency = GetLocaleInfo(LocaleStringData.MonetarySymbol);
}
- return this.sCurrency;
+ return _sCurrency;
}
}
@@ -1384,11 +1387,11 @@ namespace System.Globalization
{
get
{
- if (this.sIntlMonetarySymbol == null)
+ if (_sIntlMonetarySymbol == null)
{
- this.sIntlMonetarySymbol = DoGetLocaleInfo(LOCALE_SINTLSYMBOL);
+ _sIntlMonetarySymbol = GetLocaleInfo(LocaleStringData.Iso4217MonetarySymbol);
}
- return this.sIntlMonetarySymbol;
+ return _sIntlMonetarySymbol;
}
}
@@ -1397,11 +1400,11 @@ namespace System.Globalization
{
get
{
- if (this.sEnglishCurrency == null)
+ if (_sEnglishCurrency == null)
{
- this.sEnglishCurrency = DoGetLocaleInfo(LOCALE_SENGCURRNAME);
+ _sEnglishCurrency = GetLocaleInfo(LocaleStringData.CurrencyEnglishName);
}
- return this.sEnglishCurrency;
+ return _sEnglishCurrency;
}
}
@@ -1410,11 +1413,11 @@ namespace System.Globalization
{
get
{
- if (this.sNativeCurrency == null)
+ if (_sNativeCurrency == null)
{
- this.sNativeCurrency = DoGetLocaleInfo(LOCALE_SNATIVECURRNAME);
+ _sNativeCurrency = GetLocaleInfo(LocaleStringData.CurrencyNativeName);
}
- return this.sNativeCurrency;
+ return _sNativeCurrency;
}
}
@@ -1427,31 +1430,24 @@ namespace System.Globalization
{
get
{
- if (this.waMonetaryGrouping == null || UseUserOverride)
+ if (_waMonetaryGrouping == null)
{
- this.waMonetaryGrouping = ConvertWin32GroupString(DoGetLocaleInfo(LOCALE_SMONGROUPING));
+ _waMonetaryGrouping = GetLocaleInfo(LocaleGroupingData.Monetary);
}
- return this.waMonetaryGrouping;
+ return _waMonetaryGrouping;
}
}
- // internal String sMonetaryDecimal ; // (user can override) monetary decimal separator
- // internal String sMonetaryThousand ; // (user can override) monetary thousands separator
-
- /////////
- // Misc //
- /////////
-
// (user can override) system of measurement 0=metric, 1=US (RegionInfo)
internal int IMEASURE
{
get
{
- if (this.iMeasure == undef || UseUserOverride)
+ if (_iMeasure == undef)
{
- this.iMeasure = DoGetLocaleInfoInt(LOCALE_IMEASURE);
+ _iMeasure = GetLocaleInfo(LocaleNumberData.MeasurementSystem);
}
- return this.iMeasure;
+ return _iMeasure;
}
}
@@ -1460,14 +1456,15 @@ namespace System.Globalization
{
get
{
- if (this.sListSeparator == null || UseUserOverride)
+ if (_sListSeparator == null)
{
- this.sListSeparator = DoGetLocaleInfo(LOCALE_SLIST);
+ _sListSeparator = GetLocaleInfo(LocaleStringData.ListSeparator);
}
- return this.sListSeparator;
+ return _sListSeparator;
}
}
+
////////////////////////////
// Calendar/Time (Gregorian) //
////////////////////////////
@@ -1477,11 +1474,11 @@ namespace System.Globalization
{
get
{
- if (this.sAM1159 == null || UseUserOverride)
+ if (_sAM1159 == null)
{
- this.sAM1159 = DoGetLocaleInfo(LOCALE_S1159);
+ _sAM1159 = GetLocaleInfo(LocaleStringData.AMDesignator);
}
- return this.sAM1159;
+ return _sAM1159;
}
}
@@ -1490,11 +1487,11 @@ namespace System.Globalization
{
get
{
- if (this.sPM2359 == null || UseUserOverride)
+ if (_sPM2359 == null)
{
- this.sPM2359 = DoGetLocaleInfo(LOCALE_S2359);
+ _sPM2359 = GetLocaleInfo(LocaleStringData.PMDesignator);
}
- return this.sPM2359;
+ return _sPM2359;
}
}
@@ -1503,32 +1500,38 @@ namespace System.Globalization
{
get
{
- if (this.saLongTimes == null || UseUserOverride)
+ if (_saLongTimes == null)
{
- String[] longTimes = DoEnumTimeFormats();
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ String[] longTimes = GetTimeFormats();
if (longTimes == null || longTimes.Length == 0)
{
- this.saLongTimes = Invariant.saLongTimes;
+ _saLongTimes = Invariant._saLongTimes;
}
else
{
- this.saLongTimes = longTimes;
+ _saLongTimes = longTimes;
}
}
- return this.saLongTimes;
+ return _saLongTimes;
}
}
// short time format
// Short times (derived from long times format)
+ // TODO: NLS Arrowhead - On Windows 7 we should have short times so this isn't necessary
internal String[] ShortTimes
{
get
{
- if (this.saShortTimes == null || UseUserOverride)
+ if (_saShortTimes == null)
{
+ Debug.Assert(!GlobalizationMode.Invariant);
+
// Try to get the short times from the OS/culture.dll
- String[] shortTimes = DoEnumShortTimeFormats();
+ String[] shortTimes = null;
+ shortTimes = GetShortTimeFormats();
if (shortTimes == null || shortTimes.Length == 0)
{
@@ -1539,13 +1542,24 @@ namespace System.Globalization
shortTimes = DeriveShortTimesFromLong();
}
+ /* The above logic doesn't make sense on Mac, since the OS can provide us a "short time pattern".
+ * currently this is the 4th element in the array returned by LongTimes. We'll add this to our array
+ * if it doesn't exist.
+ */
+ shortTimes = AdjustShortTimesForMac(shortTimes);
+
// Found short times, use them
- this.saShortTimes = shortTimes;
+ _saShortTimes = shortTimes;
}
- return this.saShortTimes;
+ return _saShortTimes;
}
}
+ private string[] AdjustShortTimesForMac(string[] shortTimes)
+ {
+ return shortTimes;
+ }
+
private string[] DeriveShortTimesFromLong()
{
// Our logic is to look for h,H,m,s,t. If we find an s, then we check the string
@@ -1611,13 +1625,19 @@ namespace System.Globalization
bool containsSpace;
int endIndex = GetIndexOfNextTokenAfterSeconds(time, j, out containsSpace);
- StringBuilder sb = new StringBuilder(time.Substring(0, j));
+
+ string sep;
+
if (containsSpace)
{
- sb.Append(' ');
+ sep = " ";
}
- sb.Append(time.Substring(endIndex));
- time = sb.ToString();
+ else
+ {
+ sep = "";
+ }
+
+ time = time.Substring(0, j) + sep + time.Substring(endIndex);
break;
case 'm':
case 'H':
@@ -1670,12 +1690,11 @@ namespace System.Globalization
{
get
{
- if (this.iFirstDayOfWeek == undef || UseUserOverride)
+ if (_iFirstDayOfWeek == undef)
{
- // Have to convert it from windows to .Net formats
- this.iFirstDayOfWeek = ConvertFirstDayOfWeekMonToSun(DoGetLocaleInfoInt(LOCALE_IFIRSTDAYOFWEEK));
+ _iFirstDayOfWeek = GetFirstDayOfWeek();
}
- return this.iFirstDayOfWeek;
+ return _iFirstDayOfWeek;
}
}
@@ -1684,71 +1703,71 @@ namespace System.Globalization
{
get
{
- if (this.iFirstWeekOfYear == undef || UseUserOverride)
+ if (_iFirstWeekOfYear == undef)
{
- this.iFirstWeekOfYear = DoGetLocaleInfoInt(LOCALE_IFIRSTWEEKOFYEAR);
+ _iFirstWeekOfYear = GetLocaleInfo(LocaleNumberData.FirstWeekOfYear);
}
- return this.iFirstWeekOfYear;
+ return _iFirstWeekOfYear;
}
}
// (user can override default only) short date format
- internal String[] ShortDates(int calendarId)
+ internal String[] ShortDates(CalendarId calendarId)
{
return GetCalendar(calendarId).saShortDates;
}
// (user can override default only) long date format
- internal String[] LongDates(int calendarId)
+ internal String[] LongDates(CalendarId calendarId)
{
return GetCalendar(calendarId).saLongDates;
}
// (user can override) date year/month format.
- internal String[] YearMonths(int calendarId)
+ internal String[] YearMonths(CalendarId calendarId)
{
return GetCalendar(calendarId).saYearMonths;
}
// day names
- internal string[] DayNames(int calendarId)
+ internal string[] DayNames(CalendarId calendarId)
{
return GetCalendar(calendarId).saDayNames;
}
// abbreviated day names
- internal string[] AbbreviatedDayNames(int calendarId)
+ internal string[] AbbreviatedDayNames(CalendarId calendarId)
{
// Get abbreviated day names for this calendar from the OS if necessary
return GetCalendar(calendarId).saAbbrevDayNames;
}
// The super short day names
- internal string[] SuperShortDayNames(int calendarId)
+ internal string[] SuperShortDayNames(CalendarId calendarId)
{
return GetCalendar(calendarId).saSuperShortDayNames;
}
// month names
- internal string[] MonthNames(int calendarId)
+ internal string[] MonthNames(CalendarId calendarId)
{
return GetCalendar(calendarId).saMonthNames;
}
// Genitive month names
- internal string[] GenitiveMonthNames(int calendarId)
+ internal string[] GenitiveMonthNames(CalendarId calendarId)
{
return GetCalendar(calendarId).saMonthGenitiveNames;
}
// month names
- internal string[] AbbreviatedMonthNames(int calendarId)
+ internal string[] AbbreviatedMonthNames(CalendarId calendarId)
{
return GetCalendar(calendarId).saAbbrevMonthNames;
}
// Genitive month names
- internal string[] AbbreviatedGenitiveMonthNames(int calendarId)
+ internal string[] AbbreviatedGenitiveMonthNames(CalendarId calendarId)
{
return GetCalendar(calendarId).saAbbrevMonthGenitiveNames;
}
@@ -1756,13 +1775,13 @@ namespace System.Globalization
// Leap year month names
// Note: This only applies to Hebrew, and it basically adds a "1" to the 6th month name
// the non-leap names skip the 7th name in the normal month name array
- internal string[] LeapYearMonthNames(int calendarId)
+ internal string[] LeapYearMonthNames(CalendarId calendarId)
{
return GetCalendar(calendarId).saLeapYearMonthNames;
}
// month/day format (single string, no override)
- internal String MonthDay(int calendarId)
+ internal String MonthDay(CalendarId calendarId)
{
return GetCalendar(calendarId).sMonthDay;
}
@@ -1774,29 +1793,30 @@ namespace System.Globalization
/////////////
// all available calendar type(s), The first one is the default calendar.
- internal int[] CalendarIds
+ internal CalendarId[] CalendarIds
{
get
{
- if (this.waCalendars == null)
+ if (_waCalendars == null)
{
// We pass in an array of ints, and native side fills it up with count calendars.
// We then have to copy that list to a new array of the right size.
// Default calendar should be first
- int[] calendarInts = new int[23];
- Debug.Assert(this.sWindowsName != null, "[CultureData.CalendarIds] Expected this.sWindowsName to be populated by COMNlsInfo::nativeInitCultureData already");
- int count = CalendarData.nativeGetCalendars(this.sWindowsName, this.bUseOverrides, calendarInts);
+ CalendarId[] calendars = new CalendarId[23];
+ Debug.Assert(_sWindowsName != null, "[CultureData.CalendarIds] Expected _sWindowsName to be populated by already");
+ int count = CalendarData.GetCalendars(_sWindowsName, _bUseOverrides, calendars);
// See if we had a calendar to add.
if (count == 0)
{
// Failed for some reason, just grab Gregorian from Invariant
- this.waCalendars = Invariant.waCalendars;
+ _waCalendars = Invariant._waCalendars;
}
else
{
// The OS may not return calendar 4 for zh-TW, but we've always allowed it.
- if (this.sWindowsName == "zh-TW")
+ // TODO: Is this hack necessary long-term?
+ if (_sWindowsName == "zh-TW")
{
bool found = false;
@@ -1804,7 +1824,7 @@ namespace System.Globalization
for (int i = 0; i < count; i++)
{
// Stop if we found calendar four
- if (calendarInts[i] == Calendar.CAL_TAIWAN)
+ if (calendars[i] == CalendarId.TAIWAN)
{
found = true;
break;
@@ -1817,21 +1837,20 @@ namespace System.Globalization
// Insert it as the 2nd calendar
count++;
// Copy them from the 2nd position to the end, -1 for skipping 1st, -1 for one being added.
- Array.Copy(calendarInts, 1, calendarInts, 2, 23 - 1 - 1);
- calendarInts[1] = Calendar.CAL_TAIWAN;
+ Array.Copy(calendars, 1, calendars, 2, 23 - 1 - 1);
+ calendars[1] = CalendarId.TAIWAN;
}
}
// It worked, remember the list
- int[] temp = new int[count];
- Array.Copy(calendarInts, temp, count);
+ CalendarId[] temp = new CalendarId[count];
+ Array.Copy(calendars, temp, count);
// Want 1st calendar to be default
// Prior to Vista the enumeration didn't have default calendar first
- // Only a coreclr concern, culture.dll does the right thing.
if (temp.Length > 1)
{
- int i = DoGetLocaleInfoInt(LOCALE_ICALENDARTYPE);
+ CalendarId i = (CalendarId)GetLocaleInfo(LocaleNumberData.CalendarType);
if (temp[1] == i)
{
temp[1] = temp[0];
@@ -1839,45 +1858,45 @@ namespace System.Globalization
}
}
- this.waCalendars = temp;
+ _waCalendars = temp;
}
}
- return this.waCalendars;
+ return _waCalendars;
}
}
// Native calendar names. index of optional calendar - 1, empty if no optional calendar at that number
- internal String CalendarName(int calendarId)
+ internal string CalendarName(CalendarId calendarId)
{
// Get the calendar
return GetCalendar(calendarId).sNativeName;
}
- internal CalendarData GetCalendar(int calendarId)
+ internal CalendarData GetCalendar(CalendarId calendarId)
{
- Debug.Assert(calendarId > 0 && calendarId <= CalendarData.MAX_CALENDARS,
+ Debug.Assert(calendarId > 0 && calendarId <= CalendarId.LAST_CALENDAR,
"[CultureData.GetCalendar] Expect calendarId to be in a valid range");
// arrays are 0 based, calendarIds are 1 based
- int calendarIndex = calendarId - 1;
+ int calendarIndex = (int)calendarId - 1;
// Have to have calendars
- if (calendars == null)
+ if (_calendars == null)
{
- calendars = new CalendarData[CalendarData.MAX_CALENDARS];
+ _calendars = new CalendarData[CalendarData.MAX_CALENDARS];
}
// we need the following local variable to avoid returning null
// when another thread creates a new array of CalendarData (above)
// right after we insert the newly created CalendarData (below)
- CalendarData calendarData = calendars[calendarIndex];
+ CalendarData calendarData = _calendars[calendarIndex];
// Make sure that calendar has data
- if (calendarData == null || UseUserOverride)
+ if (calendarData == null)
{
- Debug.Assert(this.sWindowsName != null, "[CultureData.GetCalendar] Expected this.sWindowsName to be populated by COMNlsInfo::nativeInitCultureData already");
- calendarData = new CalendarData(this.sWindowsName, calendarId, this.UseUserOverride);
- calendars[calendarIndex] = calendarData;
+ Debug.Assert(_sWindowsName != null, "[CultureData.GetCalendar] Expected _sWindowsName to be populated by already");
+ calendarData = new CalendarData(_sWindowsName, calendarId, this.UseUserOverride);
+ _calendars[calendarIndex] = calendarData;
}
return calendarData;
@@ -1913,13 +1932,13 @@ namespace System.Globalization
{
get
{
- if (this.iReadingLayout == undef)
+ if (_iReadingLayout == undef)
{
- Debug.Assert(this.sRealName != null, "[CultureData.IsRightToLeft] Expected this.sRealName to be populated by COMNlsInfo::nativeInitCultureData already");
- this.iReadingLayout = DoGetLocaleInfoInt(LOCALE_IREADINGLAYOUT);
+ Debug.Assert(_sRealName != null, "[CultureData.IsRightToLeft] Expected _sRealName to be populated by already");
+ _iReadingLayout = GetLocaleInfo(LocaleNumberData.ReadingLayout);
}
- return (this.iReadingLayout);
+ return (_iReadingLayout);
}
}
@@ -1934,23 +1953,10 @@ namespace System.Globalization
{
get
{
- if (this.sTextInfo == null)
- {
- // LOCALE_SSORTLOCALE is broken in Win7 for Alt sorts.
- // It is also not supported downlevel without culture.dll.
- if (IsNeutralCulture || IsSupplementalCustomCulture)
- {
- string sortLocale = DoGetLocaleInfo(LOCALE_SSORTLOCALE);
- this.sTextInfo = GetCultureData(sortLocale, bUseOverrides).SNAME;
- }
-
- if (this.sTextInfo == null)
- {
- this.sTextInfo = this.SNAME; // removes alternate sort
- }
- }
-
- return this.sTextInfo;
+ // Note: Custom cultures might point at another culture's textinfo, however windows knows how
+ // to redirect it to the desired textinfo culture, so this is OK.
+ Debug.Assert(_sRealName != null, "[CultureData.STEXTINFO] Expected _sRealName to be populated by already");
+ return (_sRealName);
}
}
@@ -1959,24 +1965,8 @@ namespace System.Globalization
{
get
{
- if (this.sCompareInfo == null)
- {
- // LOCALE_SSORTLOCALE is broken in Win7 for Alt sorts.
- // It is also not supported downlevel without culture.dll.
- // We really only need it for the custom locale case though
- // since for all other cases, it is the same as sWindowsName
- if (IsSupplementalCustomCulture)
- {
- this.sCompareInfo = DoGetLocaleInfo(LOCALE_SSORTLOCALE);
- }
-
- if (this.sCompareInfo == null)
- {
- this.sCompareInfo = this.sWindowsName;
- }
- }
-
- return this.sCompareInfo;
+ Debug.Assert(_sRealName != null, "[CultureData.SCOMPAREINFO] Expected _sRealName to be populated by already");
+ return (_sRealName);
}
}
@@ -1988,16 +1978,15 @@ namespace System.Globalization
}
}
-
internal int IDEFAULTANSICODEPAGE // default ansi code page ID (ACP)
{
get
{
- if (this.iDefaultAnsiCodePage == undef)
+ if (_iDefaultAnsiCodePage == undef)
{
- this.iDefaultAnsiCodePage = DoGetLocaleInfoInt(LOCALE_IDEFAULTANSICODEPAGE);
+ _iDefaultAnsiCodePage = GetAnsiCodePage(_sRealName);
}
- return this.iDefaultAnsiCodePage;
+ return _iDefaultAnsiCodePage;
}
}
@@ -2005,11 +1994,11 @@ namespace System.Globalization
{
get
{
- if (this.iDefaultOemCodePage == undef)
+ if (_iDefaultOemCodePage == undef)
{
- this.iDefaultOemCodePage = DoGetLocaleInfoInt(LOCALE_IDEFAULTCODEPAGE);
+ _iDefaultOemCodePage = GetOemCodePage(_sRealName);
}
- return this.iDefaultOemCodePage;
+ return _iDefaultOemCodePage;
}
}
@@ -2017,11 +2006,11 @@ namespace System.Globalization
{
get
{
- if (this.iDefaultMacCodePage == undef)
+ if (_iDefaultMacCodePage == undef)
{
- this.iDefaultMacCodePage = DoGetLocaleInfoInt(LOCALE_IDEFAULTMACCODEPAGE);
+ _iDefaultMacCodePage = GetMacCodePage(_sRealName);
}
- return this.iDefaultMacCodePage;
+ return _iDefaultMacCodePage;
}
}
@@ -2029,54 +2018,33 @@ namespace System.Globalization
{
get
{
- if (this.iDefaultEbcdicCodePage == undef)
+ if (_iDefaultEbcdicCodePage == undef)
{
- this.iDefaultEbcdicCodePage = DoGetLocaleInfoInt(LOCALE_IDEFAULTEBCDICCODEPAGE);
+ _iDefaultEbcdicCodePage = GetEbcdicCodePage(_sRealName);
}
- return this.iDefaultEbcdicCodePage;
+ return _iDefaultEbcdicCodePage;
}
}
- // Obtain locale name from LCID
- // NOTE: This will get neutral names, unlike the OS API
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern int LocaleNameToLCID(String localeName);
-
- // These are desktop only, not coreclr
- // locale ID (0409), including sort information
internal int ILANGUAGE
{
get
{
- if (this.iLanguage == 0)
+ if (_iLanguage == 0)
{
- Debug.Assert(this.sRealName != null, "[CultureData.ILANGUAGE] Expected this.sRealName to be populated by COMNlsInfo::nativeInitCultureData already");
- this.iLanguage = LocaleNameToLCID(this.sRealName);
+ Debug.Assert(_sRealName != null, "[CultureData.ILANGUAGE] Expected this.sRealName to be populated already");
+ _iLanguage = LocaleNameToLCID(_sRealName);
}
- return this.iLanguage;
+ return _iLanguage;
}
}
- internal bool IsWin32Installed
- {
- get { return this.bWin32Installed; }
- }
-
- internal bool IsFramework
- {
- get { return this.bFramework; }
- }
-
- ////////////////////
- // Derived properties //
- ////////////////////
-
internal bool IsNeutralCulture
{
get
{
- // NlsInfo::nativeInitCultureData told us if we're neutral or not
- return this.bNeutral;
+ // InitCultureData told us if we're neutral or not
+ return _bNeutral;
}
}
@@ -2093,7 +2061,13 @@ namespace System.Globalization
{
get
{
- int defaultCalId = DoGetLocaleInfoInt(LOCALE_ICALENDARTYPE);
+ if (GlobalizationMode.Invariant)
+ {
+ return CultureInfo.GetCalendarInstance(CalendarIds[0]);
+ }
+
+ CalendarId defaultCalId = (CalendarId)GetLocaleInfo(LocaleNumberData.CalendarType);
+
if (defaultCalId == 0)
{
defaultCalId = this.CalendarIds[0];
@@ -2104,29 +2078,29 @@ namespace System.Globalization
}
// All of our era names
- internal String[] EraNames(int calendarId)
+ internal String[] EraNames(CalendarId calendarId)
{
Debug.Assert(calendarId > 0, "[CultureData.saEraNames] Expected Calendar.ID > 0");
return this.GetCalendar(calendarId).saEraNames;
}
- internal String[] AbbrevEraNames(int calendarId)
+ internal String[] AbbrevEraNames(CalendarId calendarId)
{
Debug.Assert(calendarId > 0, "[CultureData.saAbbrevEraNames] Expected Calendar.ID > 0");
return this.GetCalendar(calendarId).saAbbrevEraNames;
}
- internal String[] AbbreviatedEnglishEraNames(int calendarId)
+ internal String[] AbbreviatedEnglishEraNames(CalendarId calendarId)
{
Debug.Assert(calendarId > 0, "[CultureData.saAbbrevEraNames] Expected Calendar.ID > 0");
return this.GetCalendar(calendarId).saAbbrevEnglishEraNames;
}
- // String array DEFAULTS
- // Note: GetDTFIOverrideValues does the user overrides for these, so we don't have to.
+ //// String array DEFAULTS
+ //// Note: GetDTFIOverrideValues does the user overrides for these, so we don't have to.
// Time separator (derived from time format)
@@ -2134,23 +2108,23 @@ namespace System.Globalization
{
get
{
- if (sTimeSeparator == null || UseUserOverride)
+ if (_sTimeSeparator == null)
{
- string longTimeFormat = ReescapeWin32String(DoGetLocaleInfo(LOCALE_STIMEFORMAT));
+ string longTimeFormat = GetTimeFormatString();
if (String.IsNullOrEmpty(longTimeFormat))
{
longTimeFormat = LongTimes[0];
}
// Compute STIME from time format
- sTimeSeparator = GetTimeSeparator(longTimeFormat);
+ _sTimeSeparator = GetTimeSeparator(longTimeFormat);
}
- return sTimeSeparator;
+ return _sTimeSeparator;
}
}
// Date separator (derived from short date format)
- internal String DateSeparator(int calendarId)
+ internal String DateSeparator(CalendarId calendarId)
{
return GetDateSeparator(ShortDates(calendarId)[0]);
}
@@ -2178,11 +2152,11 @@ namespace System.Globalization
// always build a stringbuilder because we need to remove the ' or \.
//
////////////////////////////////////////////////////////////////////////////
- static private String UnescapeNlsString(String str, int start, int end)
+ private static String UnescapeNlsString(String str, int start, int end)
{
- Contract.Requires(str != null);
- Contract.Requires(start >= 0);
- Contract.Requires(end >= 0);
+ Debug.Assert(str != null);
+ Debug.Assert(start >= 0);
+ Debug.Assert(end >= 0);
StringBuilder result = null;
for (int i = start; i < str.Length && i <= end; i++)
@@ -2221,102 +2195,7 @@ namespace System.Globalization
return (result.ToString());
}
- ////////////////////////////////////////////////////////////////////////////
- //
- // Reescape a Win32 style quote string as a NLS+ style quoted string
- //
- // This is also the escaping style used by custom culture data files
- //
- // NLS+ uses \ to escape the next character, whether in a quoted string or
- // not, so we always have to change \ to \\.
- //
- // NLS+ uses \' to escape a quote inside a quoted string so we have to change
- // '' to \' (if inside a quoted string)
- //
- // We don't build the stringbuilder unless we find something to change
- ////////////////////////////////////////////////////////////////////////////
- static internal String ReescapeWin32String(String str)
- {
- // If we don't have data, then don't try anything
- if (str == null)
- return null;
-
- StringBuilder result = null;
-
- bool inQuote = false;
- for (int i = 0; i < str.Length; i++)
- {
- // Look for quote
- if (str[i] == '\'')
- {
- // Already in quote?
- if (inQuote)
- {
- // See another single quote. Is this '' of 'fred''s' or '''', or is it an ending quote?
- if (i + 1 < str.Length && str[i + 1] == '\'')
- {
- // Found another ', so we have ''. Need to add \' instead.
- // 1st make sure we have our stringbuilder
- if (result == null)
- result = new StringBuilder(str, 0, i, str.Length * 2);
-
- // Append a \' and keep going (so we don't turn off quote mode)
- result.Append("\\'");
- i++;
- continue;
- }
-
- // Turning off quote mode, fall through to add it
- inQuote = false;
- }
- else
- {
- // Found beginning quote, fall through to add it
- inQuote = true;
- }
- }
- // Is there a single \ character?
- else if (str[i] == '\\')
- {
- // Found a \, need to change it to \\
- // 1st make sure we have our stringbuilder
- if (result == null)
- result = new StringBuilder(str, 0, i, str.Length * 2);
-
- // Append our \\ to the string & continue
- result.Append("\\\\");
- continue;
- }
-
- // If we have a builder we need to add our character
- if (result != null)
- result.Append(str[i]);
- }
-
- // Unchanged string? , just return input string
- if (result == null)
- return str;
-
- // String changed, need to use the builder
- return result.ToString();
- }
-
- static internal String[] ReescapeWin32Strings(String[] array)
- {
- if (array != null)
- {
- for (int i = 0; i < array.Length; i++)
- {
- array[i] = ReescapeWin32String(array[i]);
- }
- }
-
- return array;
- }
-
- // NOTE: this method is used through reflection by System.Globalization.CultureXmlParser.ReadDateElement()
- // and breaking changes here will not show up at build time, only at run time.
- static private String GetTimeSeparator(String format)
+ private static String GetTimeSeparator(String format)
{
// Time format separator (ie: : in 12:39:00)
//
@@ -2329,9 +2208,7 @@ namespace System.Globalization
return GetSeparator(format, "Hhms");
}
- // NOTE: this method is used through reflection by System.Globalization.CultureXmlParser.ReadDateElement()
- // and breaking changes here will not show up at build time, only at run time.
- static private String GetDateSeparator(String format)
+ private static String GetDateSeparator(String format)
{
// Date format separator (ie: / in 9/1/03)
//
@@ -2413,128 +2290,61 @@ namespace System.Globalization
return -1;
}
- string DoGetLocaleInfo(uint lctype)
- {
- Debug.Assert(this.sWindowsName != null, "[CultureData.DoGetLocaleInfo] Expected this.sWindowsName to be populated by COMNlsInfo::nativeInitCultureData already");
- return DoGetLocaleInfo(this.sWindowsName, lctype);
- }
-
- // For LOCALE_SPARENT we need the option of using the "real" name (forcing neutral names) instead of the
- // "windows" name, which can be specific for downlevel (< windows 7) os's.
- string DoGetLocaleInfo(string localeName, uint lctype)
- {
- // Fix lctype if we don't want overrides
- if (!UseUserOverride)
- {
- lctype |= LOCALE_NOUSEROVERRIDE;
- }
-
- // Ask OS for data
- Debug.Assert(localeName != null, "[CultureData.DoGetLocaleInfo] Expected localeName to be not be null");
- string result = CultureInfo.nativeGetLocaleInfoEx(localeName, lctype);
- if (result == null)
- {
- // Failed, just use empty string
- result = String.Empty;
- }
-
- return result;
- }
-
- int DoGetLocaleInfoInt(uint lctype)
- {
- // Fix lctype if we don't want overrides
- if (!UseUserOverride)
- {
- lctype |= LOCALE_NOUSEROVERRIDE;
- }
-
- // Ask OS for data, note that we presume it returns success, so we have to know that
- // sWindowsName is valid before calling.
- Debug.Assert(this.sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected this.sWindowsName to be populated by COMNlsInfo::nativeInitCultureData already");
- int result = CultureInfo.nativeGetLocaleInfoExInt(this.sWindowsName, lctype);
-
- return result;
- }
-
- String[] DoEnumTimeFormats()
- {
- // Note that this gets overrides for us all the time
- Debug.Assert(this.sWindowsName != null, "[CultureData.DoEnumTimeFormats] Expected this.sWindowsName to be populated by COMNlsInfo::nativeInitCultureData already");
- String[] result = ReescapeWin32Strings(nativeEnumTimeFormats(this.sWindowsName, 0, UseUserOverride));
-
- return result;
- }
-
- String[] DoEnumShortTimeFormats()
- {
- // Note that this gets overrides for us all the time
- Debug.Assert(this.sWindowsName != null, "[CultureData.DoEnumShortTimeFormats] Expected this.sWindowsName to be populated by COMNlsInfo::nativeInitCultureData already");
- String[] result = ReescapeWin32Strings(nativeEnumTimeFormats(this.sWindowsName, TIME_NOSECONDS, UseUserOverride));
-
- return result;
- }
-
- /////////////////
- // Static Helpers //
- ////////////////
internal static bool IsCustomCultureId(int cultureId)
{
- if (cultureId == CultureInfo.LOCALE_CUSTOM_DEFAULT || cultureId == CultureInfo.LOCALE_CUSTOM_UNSPECIFIED)
- return true;
-
- return false;
+ return (cultureId == CultureInfo.LOCALE_CUSTOM_DEFAULT || cultureId == CultureInfo.LOCALE_CUSTOM_UNSPECIFIED);
}
- ////////////////////////////////////////////////////////////////////////////
- //
- // Parameters:
- // calendarValueOnly Retrieve the values which are affected by the calendar change of DTFI.
- // This will cause values like longTimePattern not be retrieved since it is
- // not affected by the Calendar property in DTFI.
- //
- ////////////////////////////////////////////////////////////////////////////
internal void GetNFIValues(NumberFormatInfo nfi)
{
- if (this.IsInvariantCulture)
+ if (GlobalizationMode.Invariant || this.IsInvariantCulture)
{
- nfi.positiveSign = this.sPositiveSign;
- nfi.negativeSign = this.sNegativeSign;
-
- nfi.nativeDigits = this.saNativeDigits;
- nfi.digitSubstitution = this.iDigitSubstitution;
+ // FUTURE: NumberFormatInfo already has default values for many of these fields. Can we not do this?
+ nfi.positiveSign = _sPositiveSign;
+ nfi.negativeSign = _sNegativeSign;
- nfi.numberGroupSeparator = this.sThousandSeparator;
- nfi.numberDecimalSeparator = this.sDecimalSeparator;
- nfi.numberDecimalDigits = this.iDigits;
- nfi.numberNegativePattern = this.iNegativeNumber;
+ nfi.numberGroupSeparator = _sThousandSeparator;
+ nfi.numberDecimalSeparator = _sDecimalSeparator;
+ nfi.numberDecimalDigits = _iDigits;
+ nfi.numberNegativePattern = _iNegativeNumber;
- nfi.currencySymbol = this.sCurrency;
- nfi.currencyGroupSeparator = this.sMonetaryThousand;
- nfi.currencyDecimalSeparator = this.sMonetaryDecimal;
- nfi.currencyDecimalDigits = this.iCurrencyDigits;
- nfi.currencyNegativePattern = this.iNegativeCurrency;
- nfi.currencyPositivePattern = this.iCurrency;
+ nfi.currencySymbol = _sCurrency;
+ nfi.currencyGroupSeparator = _sMonetaryThousand;
+ nfi.currencyDecimalSeparator = _sMonetaryDecimal;
+ nfi.currencyDecimalDigits = _iCurrencyDigits;
+ nfi.currencyNegativePattern = _iNegativeCurrency;
+ nfi.currencyPositivePattern = _iCurrency;
}
else
{
- //
- // We don't have information for the following four. All cultures use
- // the same value of the number formatting values.
- //
- // PercentDecimalDigits
- // PercentDecimalSeparator
- // PercentGroupSize
- // PercentGroupSeparator
- //
+ Debug.Assert(_sWindowsName != null, "[CultureData.GetNFIValues] Expected _sWindowsName to be populated by already");
+ // String values
+ nfi.positiveSign = GetLocaleInfo(LocaleStringData.PositiveSign);
+ nfi.negativeSign = GetLocaleInfo(LocaleStringData.NegativeSign);
- //
- // Ask native side for our data.
- //
- Debug.Assert(this.sWindowsName != null, "[CultureData.GetNFIValues] Expected this.sWindowsName to be populated by COMNlsInfo::nativeInitCultureData already");
- CultureData.nativeGetNumberFormatInfoValues(this.sWindowsName, nfi, UseUserOverride);
- }
+ nfi.numberDecimalSeparator = GetLocaleInfo(LocaleStringData.DecimalSeparator);
+ nfi.numberGroupSeparator = GetLocaleInfo(LocaleStringData.ThousandSeparator);
+ nfi.currencyGroupSeparator = GetLocaleInfo(LocaleStringData.MonetaryThousandSeparator);
+ nfi.currencyDecimalSeparator = GetLocaleInfo(LocaleStringData.MonetaryDecimalSeparator);
+ nfi.currencySymbol = GetLocaleInfo(LocaleStringData.MonetarySymbol);
+
+ // Numeric values
+ nfi.numberDecimalDigits = GetLocaleInfo(LocaleNumberData.FractionalDigitsCount);
+ nfi.currencyDecimalDigits = GetLocaleInfo(LocaleNumberData.MonetaryFractionalDigitsCount);
+ nfi.currencyPositivePattern = GetLocaleInfo(LocaleNumberData.PositiveMonetaryNumberFormat);
+ nfi.currencyNegativePattern = GetLocaleInfo(LocaleNumberData.NegativeMonetaryNumberFormat);
+ nfi.numberNegativePattern = GetLocaleInfo(LocaleNumberData.NegativeNumberFormat);
+ // LOCALE_SNATIVEDIGITS (array of 10 single character strings).
+ string digits = GetLocaleInfo(LocaleStringData.Digits);
+ nfi.nativeDigits = new string[10];
+ for (int i = 0; i < nfi.nativeDigits.Length; i++)
+ {
+ nfi.nativeDigits[i] = new string(digits[i], 1);
+ }
+
+ nfi.digitSubstitution = GetDigitSubstitution(_sRealName);
+ }
//
// Gather additional data
@@ -2569,289 +2379,188 @@ namespace System.Globalization
//Special case for Italian. The currency decimal separator in the control panel is the empty string. When the user
//specifies C4 as the currency format, this results in the number apparently getting multiplied by 10000 because the
- //decimal point doesn't show up. We'll just workaround this here because our default currency format will never use nfi.
+ //decimal point doesn't show up. We'll just hack this here because our default currency format will never use nfi.
if (nfi.currencyDecimalSeparator == null || nfi.currencyDecimalSeparator.Length == 0)
{
nfi.currencyDecimalSeparator = nfi.numberDecimalSeparator;
}
}
- static private int ConvertFirstDayOfWeekMonToSun(int iTemp)
- {
- // Convert Mon-Sun to Sun-Sat format
- iTemp++;
- if (iTemp > 6)
- {
- // Wrap Sunday and convert invalid data to Sunday
- iTemp = 0;
- }
- return iTemp;
- }
-
// Helper
// This is ONLY used for caching names and shouldn't be used for anything else
internal static string AnsiToLower(string testString)
{
- StringBuilder sb = new StringBuilder(testString.Length);
-
- for (int ich = 0; ich < testString.Length; ich++)
+ int index = 0;
+
+ while (index<testString.Length && (testString[index]<'A' || testString[index]>'Z' ))
{
- char ch = testString[ich];
- sb.Append(ch <= 'Z' && ch >= 'A' ? (char)(ch - 'A' + 'a') : ch);
+ index++;
}
-
- return (sb.ToString());
- }
-
- // If we get a group from windows, then its in 3;0 format with the 0 backwards
- // of how NLS+ uses it (ie: if the string has a 0, then the int[] shouldn't and vice versa)
- // EXCEPT in the case where the list only contains 0 in which NLS and NLS+ have the same meaning.
- static private int[] ConvertWin32GroupString(String win32Str)
- {
- // None of these cases make any sense
- if (win32Str == null || win32Str.Length == 0)
+ if (index >= testString.Length)
{
- return (new int[] { 3 });
+ return testString; // we didn't really change the string
}
-
- if (win32Str[0] == '0')
+
+ StringBuilder sb = new StringBuilder(testString.Length);
+ for (int i=0; i<index; i++)
{
- return (new int[] { 0 });
+ sb.Append(testString[i]);
}
- // Since its in n;n;n;n;n format, we can always get the length quickly
- int[] values;
- if (win32Str[win32Str.Length - 1] == '0')
- {
- // Trailing 0 gets dropped. 1;0 -> 1
- values = new int[(win32Str.Length / 2)];
- }
- else
- {
- // Need extra space for trailing zero 1 -> 1;0
- values = new int[(win32Str.Length / 2) + 2];
- values[values.Length - 1] = 0;
- }
+ sb.Append((char) (testString[index] -'A' + 'a'));
- int i;
- int j;
- for (i = 0, j = 0; i < win32Str.Length && j < values.Length; i += 2, j++)
+ for (int ich = index+1; ich < testString.Length; ich++)
{
- // Note that this # shouldn't ever be zero, 'cause 0 is only at end
- // But we'll test because its registry that could be anything
- if (win32Str[i] < '1' || win32Str[i] > '9')
- return new int[] { 3 };
-
- values[j] = (int)(win32Str[i] - '0');
+ char ch = testString[ich];
+ sb.Append(ch <= 'Z' && ch >= 'A' ? (char)(ch - 'A' + 'a') : ch);
}
- return (values);
+ return (sb.ToString());
}
- // LCTYPES for GetLocaleInfo
- private const uint LOCALE_NOUSEROVERRIDE = 0x80000000; // do not use user overrides
- private const uint LOCALE_RETURN_NUMBER = 0x20000000; // return number instead of string
-
- // Modifier for genitive names
- private const uint LOCALE_RETURN_GENITIVE_NAMES = 0x10000000; //Flag to return the Genitive forms of month names
-
- //
- // The following LCTypes are mutually exclusive in that they may NOT
- // be used in combination with each other.
- //
-
- //
- // These are the various forms of the name of the locale:
- //
- private const uint LOCALE_SLOCALIZEDDISPLAYNAME = 0x00000002; // localized name of locale, eg "German (Germany)" in UI language
- private const uint LOCALE_SENGLISHDISPLAYNAME = 0x00000072; // Display name (language + country usually) in English, eg "German (Germany)"
- private const uint LOCALE_SNATIVEDISPLAYNAME = 0x00000073; // Display name in native locale language, eg "Deutsch (Deutschland)
-
- private const uint LOCALE_SLOCALIZEDLANGUAGENAME = 0x0000006f; // Language Display Name for a language, eg "German" in UI language
- private const uint LOCALE_SENGLISHLANGUAGENAME = 0x00001001; // English name of language, eg "German"
- private const uint LOCALE_SNATIVELANGUAGENAME = 0x00000004; // native name of language, eg "Deutsch"
-
- private const uint LOCALE_SLOCALIZEDCOUNTRYNAME = 0x00000006; // localized name of country, eg "Germany" in UI language
- private const uint LOCALE_SENGLISHCOUNTRYNAME = 0x00001002; // English name of country, eg "Germany"
- private const uint LOCALE_SNATIVECOUNTRYNAME = 0x00000008; // native name of country, eg "Deutschland"
-
-
- // private const uint LOCALE_ILANGUAGE =0x00000001; // language id // Don't use, use NewApis::LocaleNameToLCID instead (GetLocaleInfo doesn't return neutrals)
-
- // private const uint LOCALE_SLANGUAGE =LOCALE_SLOCALIZEDDISPLAYNAME; // localized name of language (use LOCALE_SLOCALIZEDDISPLAYNAME instead)
- // private const uint LOCALE_SENGLANGUAGE =LOCALE_SENGLISHLANGUAGENAME; // English name of language (use LOCALE_SENGLISHLANGUAGENAME instead)
- private const uint LOCALE_SABBREVLANGNAME = 0x00000003; // abbreviated language name
- // private const uint LOCALE_SNATIVELANGNAME =LOCALE_SNATIVELANGUAGENAME; // native name of language (use LOCALE_SNATIVELANGUAGENAME instead)
-
- private const uint LOCALE_ICOUNTRY = 0x00000005; // country code
- // private const uint LOCALE_SCOUNTRY =LOCALE_SLOCALIZEDCOUNTRYNAME; // localized name of country (use LOCALE_SLOCALIZEDCOUNTRYNAME instead)
- // private const uint LOCALE_SENGCOUNTRY =LOCALE_SENGLISHCOUNTRYNAME; // English name of country (use LOCALE_SENGLISHCOUNTRYNAME instead)
- private const uint LOCALE_SABBREVCTRYNAME = 0x00000007; // abbreviated country name
- // private const uint LOCALE_SNATIVECTRYNAME =LOCALE_SNATIVECOUNTRYNAME; // native name of country ( use LOCALE_SNATIVECOUNTRYNAME instead)
- private const uint LOCALE_IGEOID = 0x0000005B; // geographical location id
-
- private const uint LOCALE_IDEFAULTLANGUAGE = 0x00000009; // default language id
- private const uint LOCALE_IDEFAULTCOUNTRY = 0x0000000A; // default country code
- private const uint LOCALE_IDEFAULTCODEPAGE = 0x0000000B; // default oem code page
- private const uint LOCALE_IDEFAULTANSICODEPAGE = 0x00001004; // default ansi code page
- private const uint LOCALE_IDEFAULTMACCODEPAGE = 0x00001011; // default mac code page
-
- private const uint LOCALE_SLIST = 0x0000000C; // list item separator
- private const uint LOCALE_IMEASURE = 0x0000000D; // 0 = metric, 1 = US
-
- private const uint LOCALE_SDECIMAL = 0x0000000E; // decimal separator
- private const uint LOCALE_STHOUSAND = 0x0000000F; // thousand separator
- private const uint LOCALE_SGROUPING = 0x00000010; // digit grouping
- private const uint LOCALE_IDIGITS = 0x00000011; // number of fractional digits
- private const uint LOCALE_ILZERO = 0x00000012; // leading zeros for decimal
- private const uint LOCALE_INEGNUMBER = 0x00001010; // negative number mode
- private const uint LOCALE_SNATIVEDIGITS = 0x00000013; // native digits for 0-9
-
- private const uint LOCALE_SCURRENCY = 0x00000014; // local monetary symbol
- private const uint LOCALE_SINTLSYMBOL = 0x00000015; // uintl monetary symbol
- private const uint LOCALE_SMONDECIMALSEP = 0x00000016; // monetary decimal separator
- private const uint LOCALE_SMONTHOUSANDSEP = 0x00000017; // monetary thousand separator
- private const uint LOCALE_SMONGROUPING = 0x00000018; // monetary grouping
- private const uint LOCALE_ICURRDIGITS = 0x00000019; // # local monetary digits
- private const uint LOCALE_IINTLCURRDIGITS = 0x0000001A; // # uintl monetary digits
- private const uint LOCALE_ICURRENCY = 0x0000001B; // positive currency mode
- private const uint LOCALE_INEGCURR = 0x0000001C; // negative currency mode
-
- private const uint LOCALE_SDATE = 0x0000001D; // date separator (derived from LOCALE_SSHORTDATE, use that instead)
- private const uint LOCALE_STIME = 0x0000001E; // time separator (derived from LOCALE_STIMEFORMAT, use that instead)
- private const uint LOCALE_SSHORTDATE = 0x0000001F; // short date format string
- private const uint LOCALE_SLONGDATE = 0x00000020; // long date format string
- private const uint LOCALE_STIMEFORMAT = 0x00001003; // time format string
- private const uint LOCALE_IDATE = 0x00000021; // short date format ordering (derived from LOCALE_SSHORTDATE, use that instead)
- private const uint LOCALE_ILDATE = 0x00000022; // long date format ordering (derived from LOCALE_SLONGDATE, use that instead)
- private const uint LOCALE_ITIME = 0x00000023; // time format specifier (derived from LOCALE_STIMEFORMAT, use that instead)
- private const uint LOCALE_ITIMEMARKPOSN = 0x00001005; // time marker position (derived from LOCALE_STIMEFORMAT, use that instead)
- private const uint LOCALE_ICENTURY = 0x00000024; // century format specifier (short date, LOCALE_SSHORTDATE is preferred)
- private const uint LOCALE_ITLZERO = 0x00000025; // leading zeros in time field (derived from LOCALE_STIMEFORMAT, use that instead)
- private const uint LOCALE_IDAYLZERO = 0x00000026; // leading zeros in day field (short date, LOCALE_SSHORTDATE is preferred)
- private const uint LOCALE_IMONLZERO = 0x00000027; // leading zeros in month field (short date, LOCALE_SSHORTDATE is preferred)
- private const uint LOCALE_S1159 = 0x00000028; // AM designator
- private const uint LOCALE_S2359 = 0x00000029; // PM designator
-
- private const uint LOCALE_ICALENDARTYPE = 0x00001009; // type of calendar specifier
- private const uint LOCALE_IOPTIONALCALENDAR = 0x0000100B; // additional calendar types specifier
- private const uint LOCALE_IFIRSTDAYOFWEEK = 0x0000100C; // first day of week specifier
- private const uint LOCALE_IFIRSTWEEKOFYEAR = 0x0000100D; // first week of year specifier
-
- private const uint LOCALE_SDAYNAME1 = 0x0000002A; // long name for Monday
- private const uint LOCALE_SDAYNAME2 = 0x0000002B; // long name for Tuesday
- private const uint LOCALE_SDAYNAME3 = 0x0000002C; // long name for Wednesday
- private const uint LOCALE_SDAYNAME4 = 0x0000002D; // long name for Thursday
- private const uint LOCALE_SDAYNAME5 = 0x0000002E; // long name for Friday
- private const uint LOCALE_SDAYNAME6 = 0x0000002F; // long name for Saturday
- private const uint LOCALE_SDAYNAME7 = 0x00000030; // long name for Sunday
- private const uint LOCALE_SABBREVDAYNAME1 = 0x00000031; // abbreviated name for Monday
- private const uint LOCALE_SABBREVDAYNAME2 = 0x00000032; // abbreviated name for Tuesday
- private const uint LOCALE_SABBREVDAYNAME3 = 0x00000033; // abbreviated name for Wednesday
- private const uint LOCALE_SABBREVDAYNAME4 = 0x00000034; // abbreviated name for Thursday
- private const uint LOCALE_SABBREVDAYNAME5 = 0x00000035; // abbreviated name for Friday
- private const uint LOCALE_SABBREVDAYNAME6 = 0x00000036; // abbreviated name for Saturday
- private const uint LOCALE_SABBREVDAYNAME7 = 0x00000037; // abbreviated name for Sunday
- private const uint LOCALE_SMONTHNAME1 = 0x00000038; // long name for January
- private const uint LOCALE_SMONTHNAME2 = 0x00000039; // long name for February
- private const uint LOCALE_SMONTHNAME3 = 0x0000003A; // long name for March
- private const uint LOCALE_SMONTHNAME4 = 0x0000003B; // long name for April
- private const uint LOCALE_SMONTHNAME5 = 0x0000003C; // long name for May
- private const uint LOCALE_SMONTHNAME6 = 0x0000003D; // long name for June
- private const uint LOCALE_SMONTHNAME7 = 0x0000003E; // long name for July
- private const uint LOCALE_SMONTHNAME8 = 0x0000003F; // long name for August
- private const uint LOCALE_SMONTHNAME9 = 0x00000040; // long name for September
- private const uint LOCALE_SMONTHNAME10 = 0x00000041; // long name for October
- private const uint LOCALE_SMONTHNAME11 = 0x00000042; // long name for November
- private const uint LOCALE_SMONTHNAME12 = 0x00000043; // long name for December
- private const uint LOCALE_SMONTHNAME13 = 0x0000100E; // long name for 13th month (if exists)
- private const uint LOCALE_SABBREVMONTHNAME1 = 0x00000044; // abbreviated name for January
- private const uint LOCALE_SABBREVMONTHNAME2 = 0x00000045; // abbreviated name for February
- private const uint LOCALE_SABBREVMONTHNAME3 = 0x00000046; // abbreviated name for March
- private const uint LOCALE_SABBREVMONTHNAME4 = 0x00000047; // abbreviated name for April
- private const uint LOCALE_SABBREVMONTHNAME5 = 0x00000048; // abbreviated name for May
- private const uint LOCALE_SABBREVMONTHNAME6 = 0x00000049; // abbreviated name for June
- private const uint LOCALE_SABBREVMONTHNAME7 = 0x0000004A; // abbreviated name for July
- private const uint LOCALE_SABBREVMONTHNAME8 = 0x0000004B; // abbreviated name for August
- private const uint LOCALE_SABBREVMONTHNAME9 = 0x0000004C; // abbreviated name for September
- private const uint LOCALE_SABBREVMONTHNAME10 = 0x0000004D; // abbreviated name for October
- private const uint LOCALE_SABBREVMONTHNAME11 = 0x0000004E; // abbreviated name for November
- private const uint LOCALE_SABBREVMONTHNAME12 = 0x0000004F; // abbreviated name for December
- private const uint LOCALE_SABBREVMONTHNAME13 = 0x0000100F; // abbreviated name for 13th month (if exists)
-
- private const uint LOCALE_SPOSITIVESIGN = 0x00000050; // positive sign
- private const uint LOCALE_SNEGATIVESIGN = 0x00000051; // negative sign
- private const uint LOCALE_IPOSSIGNPOSN = 0x00000052; // positive sign position (derived from INEGCURR)
- private const uint LOCALE_INEGSIGNPOSN = 0x00000053; // negative sign position (derived from INEGCURR)
- private const uint LOCALE_IPOSSYMPRECEDES = 0x00000054; // mon sym precedes pos amt (derived from ICURRENCY)
- private const uint LOCALE_IPOSSEPBYSPACE = 0x00000055; // mon sym sep by space from pos amt (derived from ICURRENCY)
- private const uint LOCALE_INEGSYMPRECEDES = 0x00000056; // mon sym precedes neg amt (derived from INEGCURR)
- private const uint LOCALE_INEGSEPBYSPACE = 0x00000057; // mon sym sep by space from neg amt (derived from INEGCURR)
-
- private const uint LOCALE_FONTSIGNATURE = 0x00000058; // font signature
- private const uint LOCALE_SISO639LANGNAME = 0x00000059; // ISO abbreviated language name
- private const uint LOCALE_SISO3166CTRYNAME = 0x0000005A; // ISO abbreviated country name
-
- private const uint LOCALE_IDEFAULTEBCDICCODEPAGE = 0x00001012; // default ebcdic code page
- private const uint LOCALE_IPAPERSIZE = 0x0000100A; // 1 = letter, 5 = legal, 8 = a3, 9 = a4
- private const uint LOCALE_SENGCURRNAME = 0x00001007; // english name of currency
- private const uint LOCALE_SNATIVECURRNAME = 0x00001008; // native name of currency
- private const uint LOCALE_SYEARMONTH = 0x00001006; // year month format string
- private const uint LOCALE_SSORTNAME = 0x00001013; // sort name
- private const uint LOCALE_IDIGITSUBSTITUTION = 0x00001014; // 0 = context, 1 = none, 2 = national
-
- private const uint LOCALE_SNAME = 0x0000005c; // locale name (with sort info) (ie: de-DE_phoneb)
- private const uint LOCALE_SDURATION = 0x0000005d; // time duration format
- private const uint LOCALE_SKEYBOARDSTOINSTALL = 0x0000005e; // (windows only) keyboards to install
- private const uint LOCALE_SSHORTESTDAYNAME1 = 0x00000060; // Shortest day name for Monday
- private const uint LOCALE_SSHORTESTDAYNAME2 = 0x00000061; // Shortest day name for Tuesday
- private const uint LOCALE_SSHORTESTDAYNAME3 = 0x00000062; // Shortest day name for Wednesday
- private const uint LOCALE_SSHORTESTDAYNAME4 = 0x00000063; // Shortest day name for Thursday
- private const uint LOCALE_SSHORTESTDAYNAME5 = 0x00000064; // Shortest day name for Friday
- private const uint LOCALE_SSHORTESTDAYNAME6 = 0x00000065; // Shortest day name for Saturday
- private const uint LOCALE_SSHORTESTDAYNAME7 = 0x00000066; // Shortest day name for Sunday
- private const uint LOCALE_SISO639LANGNAME2 = 0x00000067; // 3 character ISO abbreviated language name
- private const uint LOCALE_SISO3166CTRYNAME2 = 0x00000068; // 3 character ISO country name
- private const uint LOCALE_SNAN = 0x00000069; // Not a Number
- private const uint LOCALE_SPOSINFINITY = 0x0000006a; // + Infinity
- private const uint LOCALE_SNEGINFINITY = 0x0000006b; // - Infinity
- private const uint LOCALE_SSCRIPTS = 0x0000006c; // Typical scripts in the locale
- private const uint LOCALE_SPARENT = 0x0000006d; // Fallback name for resources
- private const uint LOCALE_SCONSOLEFALLBACKNAME = 0x0000006e; // Fallback name for within the console
- // private const uint LOCALE_SLANGDISPLAYNAME =LOCALE_SLOCALIZEDLANGUAGENAME; // Language Display Name for a language (use LOCALE_SLOCALIZEDLANGUAGENAME instead)
-
- // Windows 7 LCTYPES
- private const uint LOCALE_IREADINGLAYOUT = 0x00000070; // Returns one of the following 4 reading layout values:
- // 0 - Left to right (eg en-US)
- // 1 - Right to left (eg arabic locales)
- // 2 - Vertical top to bottom with columns to the left and also left to right (ja-JP locales)
- // 3 - Vertical top to bottom with columns proceeding to the right
- private const uint LOCALE_INEUTRAL = 0x00000071; // Returns 0 for specific cultures, 1 for neutral cultures.
- private const uint LOCALE_INEGATIVEPERCENT = 0x00000074; // Returns 0-11 for the negative percent format
- private const uint LOCALE_IPOSITIVEPERCENT = 0x00000075; // Returns 0-3 for the positive percent formatIPOSITIVEPERCENT
- private const uint LOCALE_SPERCENT = 0x00000076; // Returns the percent symbol
- private const uint LOCALE_SPERMILLE = 0x00000077; // Returns the permille (U+2030) symbol
- private const uint LOCALE_SMONTHDAY = 0x00000078; // Returns the preferred month/day format
- private const uint LOCALE_SSHORTTIME = 0x00000079; // Returns the preferred short time format (ie: no seconds, just h:mm)
- private const uint LOCALE_SOPENTYPELANGUAGETAG = 0x0000007a; // Open type language tag, eg: "latn" or "dflt"
- private const uint LOCALE_SSORTLOCALE = 0x0000007b; // Name of locale to use for sorting/collation/casing behavior.
-
- // Time formats enumerations
- internal const uint TIME_NOSECONDS = 0x00000002; // Don't use seconds (get short time format for enumtimeformats on win7+)
-
- // Get our initial minimal culture data (name, parent, etc.)
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern bool nativeInitCultureData(CultureData cultureData);
-
- // Grab the NumberFormatInfo data
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern bool nativeGetNumberFormatInfoValues(String localeName, NumberFormatInfo nfi, bool useUserOverride);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern String[] nativeEnumTimeFormats(String localeName, uint dwFlags, bool useUserOverride);
-
- [SuppressUnmanagedCodeSecurityAttribute()]
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- internal static extern int nativeEnumCultureNames(int cultureTypes, ObjectHandleOnStack retStringArray);
+ /// <remarks>
+ /// The numeric values of the enum members match their Win32 counterparts. The CultureData Win32 PAL implementation
+ /// takes a dependency on this fact, in order to prevent having to construct a mapping from internal values to LCTypes.
+ /// </remarks>
+ private enum LocaleStringData : uint
+ {
+ /// <summary>localized name of locale, eg "German (Germany)" in UI language (coresponds to LOCALE_SLOCALIZEDDISPLAYNAME)</summary>
+ LocalizedDisplayName = 0x00000002,
+ /// <summary>Display name (language + country usually) in English, eg "German (Germany)" (coresponds to LOCALE_SENGLISHDISPLAYNAME)</summary>
+ EnglishDisplayName = 0x00000072,
+ /// <summary>Display name in native locale language, eg "Deutsch (Deutschland) (coresponds to LOCALE_SNATIVEDISPLAYNAME)</summary>
+ NativeDisplayName = 0x00000073,
+ /// <summary>Language Display Name for a language, eg "German" in UI language (coresponds to LOCALE_SLOCALIZEDLANGUAGENAME)</summary>
+ LocalizedLanguageName = 0x0000006f,
+ /// <summary>English name of language, eg "German" (coresponds to LOCALE_SENGLISHLANGUAGENAME)</summary>
+ EnglishLanguageName = 0x00001001,
+ /// <summary>native name of language, eg "Deutsch" (coresponds to LOCALE_SNATIVELANGUAGENAME)</summary>
+ NativeLanguageName = 0x00000004,
+ /// <summary>localized name of country, eg "Germany" in UI language (coresponds to LOCALE_SLOCALIZEDCOUNTRYNAME)</summary>
+ LocalizedCountryName = 0x00000006,
+ /// <summary>English name of country, eg "Germany" (coresponds to LOCALE_SENGLISHCOUNTRYNAME)</summary>
+ EnglishCountryName = 0x00001002,
+ /// <summary>native name of country, eg "Deutschland" (coresponds to LOCALE_SNATIVECOUNTRYNAME)</summary>
+ NativeCountryName = 0x00000008,
+ /// <summary>abbreviated language name (coresponds to LOCALE_SABBREVLANGNAME)</summary>
+ AbbreviatedWindowsLanguageName = 0x00000003,
+ /// <summary>list item separator (coresponds to LOCALE_SLIST)</summary>
+ ListSeparator = 0x0000000C,
+ /// <summary>decimal separator (coresponds to LOCALE_SDECIMAL)</summary>
+ DecimalSeparator = 0x0000000E,
+ /// <summary>thousand separator (coresponds to LOCALE_STHOUSAND)</summary>
+ ThousandSeparator = 0x0000000F,
+ /// <summary>digit grouping (coresponds to LOCALE_SGROUPING)</summary>
+ Digits = 0x00000013,
+ /// <summary>local monetary symbol (coresponds to LOCALE_SCURRENCY)</summary>
+ MonetarySymbol = 0x00000014,
+ /// <summary>English currency name (coresponds to LOCALE_SENGCURRNAME)</summary>
+ CurrencyEnglishName = 0x00001007,
+ /// <summary>Native currency name (coresponds to LOCALE_SNATIVECURRNAME)</summary>
+ CurrencyNativeName = 0x00001008,
+ /// <summary>uintl monetary symbol (coresponds to LOCALE_SINTLSYMBOL)</summary>
+ Iso4217MonetarySymbol = 0x00000015,
+ /// <summary>monetary decimal separator (coresponds to LOCALE_SMONDECIMALSEP)</summary>
+ MonetaryDecimalSeparator = 0x00000016,
+ /// <summary>monetary thousand separator (coresponds to LOCALE_SMONTHOUSANDSEP)</summary>
+ MonetaryThousandSeparator = 0x00000017,
+ /// <summary>AM designator (coresponds to LOCALE_S1159)</summary>
+ AMDesignator = 0x00000028,
+ /// <summary>PM designator (coresponds to LOCALE_S2359)</summary>
+ PMDesignator = 0x00000029,
+ /// <summary>positive sign (coresponds to LOCALE_SPOSITIVESIGN)</summary>
+ PositiveSign = 0x00000050,
+ /// <summary>negative sign (coresponds to LOCALE_SNEGATIVESIGN)</summary>
+ NegativeSign = 0x00000051,
+ /// <summary>ISO abbreviated language name (coresponds to LOCALE_SISO639LANGNAME)</summary>
+ Iso639LanguageTwoLetterName = 0x00000059,
+ /// <summary>ISO abbreviated country name (coresponds to LOCALE_SISO639LANGNAME2)</summary>
+ Iso639LanguageThreeLetterName = 0x00000067,
+ /// <summary>ISO abbreviated language name (coresponds to LOCALE_SISO639LANGNAME)</summary>
+ Iso639LanguageName = 0x00000059,
+ /// <summary>ISO abbreviated country name (coresponds to LOCALE_SISO3166CTRYNAME)</summary>
+ Iso3166CountryName = 0x0000005A,
+ /// <summary>3 letter ISO country code (coresponds to LOCALE_SISO3166CTRYNAME2)</summary>
+ Iso3166CountryName2 = 0x00000068, // 3 character ISO country name
+ /// <summary>Not a Number (coresponds to LOCALE_SNAN)</summary>
+ NaNSymbol = 0x00000069,
+ /// <summary>+ Infinity (coresponds to LOCALE_SPOSINFINITY)</summary>
+ PositiveInfinitySymbol = 0x0000006a,
+ /// <summary>- Infinity (coresponds to LOCALE_SNEGINFINITY)</summary>
+ NegativeInfinitySymbol = 0x0000006b,
+ /// <summary>Fallback name for resources (coresponds to LOCALE_SPARENT)</summary>
+ ParentName = 0x0000006d,
+ /// <summary>Fallback name for within the console (coresponds to LOCALE_SCONSOLEFALLBACKNAME)</summary>
+ ConsoleFallbackName = 0x0000006e,
+ /// <summary>Returns the percent symbol (coresponds to LOCALE_SPERCENT)</summary>
+ PercentSymbol = 0x00000076,
+ /// <summary>Returns the permille (U+2030) symbol (coresponds to LOCALE_SPERMILLE)</summary>
+ PerMilleSymbol = 0x00000077
+ }
+
+ /// <remarks>
+ /// The numeric values of the enum members match their Win32 counterparts. The CultureData Win32 PAL implementation
+ /// takes a dependency on this fact, in order to prevent having to construct a mapping from internal values to LCTypes.
+ /// </remarks>
+ private enum LocaleGroupingData : uint
+ {
+ /// <summary>digit grouping (coresponds to LOCALE_SGROUPING)</summary>
+ Digit = 0x00000010,
+ /// <summary>monetary grouping (coresponds to LOCALE_SMONGROUPING)</summary>
+ Monetary = 0x00000018,
+ }
+
+ /// <remarks>
+ /// The numeric values of the enum members match their Win32 counterparts. The CultureData Win32 PAL implementation
+ /// takes a dependency on this fact, in order to prevent having to construct a mapping from internal values to LCTypes.
+ /// </remarks>
+ private enum LocaleNumberData : uint
+ {
+ /// <summary>language id (coresponds to LOCALE_ILANGUAGE)</summary>
+ LanguageId = 0x00000001,
+ /// <summary>geographical location id, (coresponds to LOCALE_IGEOID)</summary>
+ GeoId = 0x0000005B,
+ /// <summary>0 = context, 1 = none, 2 = national (coresponds to LOCALE_IDIGITSUBSTITUTION)</summary>
+ DigitSubstitution = 0x00001014,
+ /// <summary>0 = metric, 1 = US (coresponds to LOCALE_IMEASURE)</summary>
+ MeasurementSystem = 0x0000000D,
+ /// <summary>number of fractional digits (coresponds to LOCALE_IDIGITS)</summary>
+ FractionalDigitsCount = 0x00000011,
+ /// <summary>negative number mode (coresponds to LOCALE_INEGNUMBER)</summary>
+ NegativeNumberFormat = 0x00001010,
+ /// <summary># local monetary digits (coresponds to LOCALE_ICURRDIGITS)</summary>
+ MonetaryFractionalDigitsCount = 0x00000019,
+ /// <summary>positive currency mode (coresponds to LOCALE_ICURRENCY)</summary>
+ PositiveMonetaryNumberFormat = 0x0000001B,
+ /// <summary>negative currency mode (coresponds to LOCALE_INEGCURR)</summary>
+ NegativeMonetaryNumberFormat = 0x0000001C,
+ /// <summary>type of calendar specifier (coresponds to LOCALE_ICALENDARTYPE)</summary>
+ CalendarType = 0x00001009,
+ /// <summary>first day of week specifier (coresponds to LOCALE_IFIRSTDAYOFWEEK)</summary>
+ FirstDayOfWeek = 0x0000100C,
+ /// <summary>first week of year specifier (coresponds to LOCALE_IFIRSTWEEKOFYEAR)</summary>
+ FirstWeekOfYear = 0x0000100D,
+ /// <summary>
+ /// Returns one of the following 4 reading layout values:
+ /// 0 - Left to right (eg en-US)
+ /// 1 - Right to left (eg arabic locales)
+ /// 2 - Vertical top to bottom with columns to the left and also left to right (ja-JP locales)
+ /// 3 - Vertical top to bottom with columns proceeding to the right
+ /// (coresponds to LOCALE_IREADINGLAYOUT)
+ /// </summary>
+ ReadingLayout = 0x00000070,
+ /// <summary>Returns 0-11 for the negative percent format (coresponds to LOCALE_INEGATIVEPERCENT)</summary>
+ NegativePercentFormat = 0x00000074,
+ /// <summary>Returns 0-3 for the positive percent format (coresponds to LOCALE_IPOSITIVEPERCENT)</summary>
+ PositivePercentFormat = 0x00000075,
+ /// <summary>default ansi code page (coresponds to LOCALE_IDEFAULTCODEPAGE)</summary>
+ OemCodePage = 0x0000000B,
+ /// <summary>default ansi code page (coresponds to LOCALE_IDEFAULTANSICODEPAGE)</summary>
+ AnsiCodePage = 0x00001004,
+ /// <summary>default mac code page (coresponds to LOCALE_IDEFAULTMACCODEPAGE)</summary>
+ MacCodePage = 0x00001011,
+ /// <summary>default ebcdic code page (coresponds to LOCALE_IDEFAULTEBCDICCODEPAGE)</summary>
+ EbcdicCodePage = 0x00001012,
+ }
}
}
diff --git a/src/mscorlib/src/System/Globalization/CultureInfo.Unix.cs b/src/mscorlib/src/System/Globalization/CultureInfo.Unix.cs
new file mode 100644
index 0000000000..7a8a9fd08d
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/CultureInfo.Unix.cs
@@ -0,0 +1,128 @@
+// 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.Diagnostics;
+using System.Threading;
+
+namespace System.Globalization
+{
+ public partial class CultureInfo : IFormatProvider
+ {
+ private static CultureInfo GetUserDefaultCultureCacheOverride()
+ {
+ return null; // ICU doesn't provide a user override
+ }
+
+ internal static CultureInfo GetUserDefaultCulture()
+ {
+ if (GlobalizationMode.Invariant)
+ return CultureInfo.InvariantCulture;
+
+ CultureInfo cultureInfo = null;
+ string localeName;
+ if (CultureData.GetDefaultLocaleName(out localeName))
+ {
+ cultureInfo = GetCultureByName(localeName, true);
+ cultureInfo._isReadOnly = true;
+ }
+ else
+ {
+ cultureInfo = CultureInfo.InvariantCulture;
+ }
+
+ return cultureInfo;
+ }
+
+ private static CultureInfo GetUserDefaultUILanguage()
+ {
+ return GetUserDefaultCulture();
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // CurrentCulture
+ //
+ // This instance provides methods based on the current user settings.
+ // These settings are volatile and may change over the lifetime of the
+ // thread.
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ //
+ // We use the following order to return CurrentCulture and CurrentUICulture
+ // o use current thread culture if the user already set one using CurrentCulture/CurrentUICulture
+ // o use thread culture if the user already set one using DefaultThreadCurrentCulture
+ // or DefaultThreadCurrentUICulture
+ // o Use NLS default user culture
+ // o Use NLS default system culture
+ // o Use Invariant culture
+ //
+ public static CultureInfo CurrentCulture
+ {
+ get
+ {
+ if (Thread.m_CurrentCulture != null)
+ {
+ return Thread.m_CurrentCulture;
+ }
+
+ CultureInfo ci = s_DefaultThreadCurrentCulture;
+ if (ci != null)
+ {
+ return ci;
+ }
+
+ // if s_userDefaultCulture == null means CultureInfo statics didn't get initialized yet. this can happen if there early static
+ // method get executed which eventually hit the cultureInfo code while CultureInfo statics didn’t get chance to initialize
+ if (s_userDefaultCulture == null)
+ {
+ Init();
+ }
+
+ Debug.Assert(s_userDefaultCulture != null);
+ return s_userDefaultCulture;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
+
+ if (s_asyncLocalCurrentCulture == null)
+ {
+ Interlocked.CompareExchange(ref s_asyncLocalCurrentCulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentCulture), null);
+ }
+ s_asyncLocalCurrentCulture.Value = value;
+ }
+ }
+
+ public static CultureInfo CurrentUICulture
+ {
+ get
+ {
+ return GetCurrentUICultureNoAppX();
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
+
+ CultureInfo.VerifyCultureName(value, true);
+ if (s_asyncLocalCurrentUICulture == null)
+ {
+ Interlocked.CompareExchange(ref s_asyncLocalCurrentUICulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentUICulture), null);
+ }
+
+ // this one will set s_currentThreadUICulture too
+ s_asyncLocalCurrentUICulture.Value = value;
+ }
+ }
+
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/CultureInfo.Windows.cs b/src/mscorlib/src/System/Globalization/CultureInfo.Windows.cs
new file mode 100644
index 0000000000..e33874e760
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/CultureInfo.Windows.cs
@@ -0,0 +1,278 @@
+// 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.Diagnostics;
+
+#if ENABLE_WINRT
+using Internal.Runtime.Augments;
+#endif
+
+using System.Threading;
+#if FEATURE_APPX
+using System.Resources;
+#endif
+
+namespace System.Globalization
+{
+ public partial class CultureInfo : IFormatProvider
+ {
+#if FEATURE_APPX
+ // When running under AppX, we use this to get some information about the language list
+ private static volatile WindowsRuntimeResourceManagerBase s_WindowsRuntimeResourceManager;
+
+ [ThreadStatic]
+ private static bool ts_IsDoingAppXCultureInfoLookup;
+#endif
+
+ /// <summary>
+ /// Gets the default user culture from WinRT, if available.
+ /// </summary>
+ /// <remarks>
+ /// This method may return null, if there is no default user culture or if WinRT isn't available.
+ /// </remarks>
+ private static CultureInfo GetUserDefaultCultureCacheOverride()
+ {
+#if ENABLE_WINRT
+ WinRTInteropCallbacks callbacks = WinRTInterop.UnsafeCallbacks;
+ if (callbacks != null && callbacks.IsAppxModel())
+ {
+ return (CultureInfo)callbacks.GetUserDefaultCulture();
+ }
+#endif
+
+ return null;
+ }
+
+ internal static CultureInfo GetUserDefaultCulture()
+ {
+ if (GlobalizationMode.Invariant)
+ return CultureInfo.InvariantCulture;
+
+ const uint LOCALE_SNAME = 0x0000005c;
+ const string LOCALE_NAME_USER_DEFAULT = null;
+ const string LOCALE_NAME_SYSTEM_DEFAULT = "!x-sys-default-locale";
+
+ string strDefault = CultureData.GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME);
+ if (strDefault == null)
+ {
+ strDefault = CultureData.GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_SNAME);
+
+ if (strDefault == null)
+ {
+ // If system default doesn't work, use invariant
+ return CultureInfo.InvariantCulture;
+ }
+ }
+
+ CultureInfo temp = GetCultureByName(strDefault, true);
+
+ temp._isReadOnly = true;
+
+ return temp;
+ }
+
+ private static CultureInfo GetUserDefaultUILanguage()
+ {
+ if (GlobalizationMode.Invariant)
+ return CultureInfo.InvariantCulture;
+
+ const uint MUI_LANGUAGE_NAME = 0x8; // Use ISO language (culture) name convention
+ uint langCount = 0;
+ uint bufLen = 0;
+
+ if (Interop.Kernel32.GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, out langCount, null, ref bufLen))
+ {
+ char [] languages = new char[bufLen];
+ if (Interop.Kernel32.GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, out langCount, languages, ref bufLen))
+ {
+ int index = 0;
+ while (languages[index] != (char) 0 && index<languages.Length)
+ {
+ index++;
+ }
+
+ CultureInfo temp = GetCultureByName(new String(languages, 0, index), true);
+ temp._isReadOnly = true;
+ return temp;
+ }
+ }
+
+ return GetUserDefaultCulture();
+ }
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // CurrentCulture
+ //
+ // This instance provides methods based on the current user settings.
+ // These settings are volatile and may change over the lifetime of the
+ // thread.
+ //
+ ////////////////////////////////////////////////////////////////////////
+
+ //
+ // We use the following order to return CurrentCulture and CurrentUICulture
+ // o Use WinRT to return the current user profile language
+ // o use current thread culture if the user already set one using CurrentCulture/CurrentUICulture
+ // o use thread culture if the user already set one using DefaultThreadCurrentCulture
+ // or DefaultThreadCurrentUICulture
+ // o Use NLS default user culture
+ // o Use NLS default system culture
+ // o Use Invariant culture
+ //
+ public static CultureInfo CurrentCulture
+ {
+ get
+ {
+#if FEATURE_APPX
+ if (AppDomain.IsAppXModel())
+ {
+ CultureInfo culture = GetCultureInfoForUserPreferredLanguageInAppX();
+ if (culture != null)
+ return culture;
+ }
+#endif
+ CultureInfo ci = GetUserDefaultCultureCacheOverride();
+ if (ci != null)
+ {
+ return ci;
+ }
+
+ if (Thread.m_CurrentCulture != null)
+ {
+ return Thread.m_CurrentCulture;
+ }
+
+ ci = s_DefaultThreadCurrentCulture;
+ if (ci != null)
+ {
+ return ci;
+ }
+
+ // if s_userDefaultCulture == null means CultureInfo statics didn't get initialized yet. this can happen if there early static
+ // method get executed which eventually hit the cultureInfo code while CultureInfo statics didn’t get chance to initialize
+ if (s_userDefaultCulture == null)
+ {
+ Init();
+ }
+
+ Debug.Assert(s_userDefaultCulture != null);
+ return s_userDefaultCulture;
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
+
+#if FEATURE_APPX
+ if (AppDomain.IsAppXModel())
+ {
+ if (SetCultureInfoForUserPreferredLanguageInAppX(value))
+ {
+ // successfully set the culture, otherwise fallback to legacy path
+ return;
+ }
+ }
+#endif
+ if (s_asyncLocalCurrentCulture == null)
+ {
+ Interlocked.CompareExchange(ref s_asyncLocalCurrentCulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentCulture), null);
+ }
+ s_asyncLocalCurrentCulture.Value = value;
+ }
+ }
+
+ public static CultureInfo CurrentUICulture
+ {
+ get
+ {
+#if FEATURE_APPX
+ if (AppDomain.IsAppXModel())
+ {
+ CultureInfo culture = GetCultureInfoForUserPreferredLanguageInAppX();
+ if (culture != null)
+ return culture;
+ }
+#endif
+ return GetCurrentUICultureNoAppX();
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
+
+ CultureInfo.VerifyCultureName(value, true);
+#if FEATURE_APPX
+ if (AppDomain.IsAppXModel())
+ {
+ if (SetCultureInfoForUserPreferredLanguageInAppX(value))
+ {
+ // successfully set the culture, otherwise fallback to legacy path
+ return;
+ }
+ }
+#endif
+ if (s_asyncLocalCurrentUICulture == null)
+ {
+ Interlocked.CompareExchange(ref s_asyncLocalCurrentUICulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentUICulture), null);
+ }
+
+ // this one will set s_currentThreadUICulture too
+ s_asyncLocalCurrentUICulture.Value = value;
+ }
+ }
+
+#if FEATURE_APPX
+ internal static CultureInfo GetCultureInfoForUserPreferredLanguageInAppX()
+ {
+ // If a call to GetCultureInfoForUserPreferredLanguageInAppX() generated a recursive
+ // call to itself, return null, since we don't want to stack overflow. For example,
+ // this can happen if some code in this method ends up calling CultureInfo.CurrentCulture
+ // (which is common on check'd build because of BCLDebug logging which calls Int32.ToString()).
+ // In this case, returning null will mean CultureInfo.CurrentCulture gets the default Win32
+ // value, which should be fine.
+ if (ts_IsDoingAppXCultureInfoLookup)
+ {
+ return null;
+ }
+
+ CultureInfo toReturn = null;
+
+ try
+ {
+ ts_IsDoingAppXCultureInfoLookup = true;
+
+ if (s_WindowsRuntimeResourceManager == null)
+ {
+ s_WindowsRuntimeResourceManager = ResourceManager.GetWinRTResourceManager();
+ }
+
+ toReturn = s_WindowsRuntimeResourceManager.GlobalResourceContextBestFitCultureInfo;
+ }
+ finally
+ {
+ ts_IsDoingAppXCultureInfoLookup = false;
+ }
+
+ return toReturn;
+ }
+
+ internal static bool SetCultureInfoForUserPreferredLanguageInAppX(CultureInfo ci)
+ {
+ if (s_WindowsRuntimeResourceManager == null)
+ {
+ s_WindowsRuntimeResourceManager = ResourceManager.GetWinRTResourceManager();
+ }
+
+ return s_WindowsRuntimeResourceManager.SetGlobalResourceContextDefaultCulture(ci);
+ }
+#endif
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/CultureInfo.cs b/src/mscorlib/src/System/Globalization/CultureInfo.cs
index ba61c146f6..60938defac 100644
--- a/src/mscorlib/src/System/Globalization/CultureInfo.cs
+++ b/src/mscorlib/src/System/Globalization/CultureInfo.cs
@@ -26,24 +26,27 @@
//
////////////////////////////////////////////////////////////////////////////
-namespace System.Globalization {
- using System;
- using System.Security;
- using System.Threading;
- using System.Collections;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Runtime.Serialization;
- using System.Runtime.Versioning;
- using System.Reflection;
- using Microsoft.Win32;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Resources;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+using System.Threading;
+
+namespace System.Globalization
+{
+#if CORECLR
+ using StringCultureInfoDictionary = Dictionary<string, CultureInfo>;
+ using StringLcidDictionary = Dictionary<int, CultureInfo>;
+
+ using Lock = Object;
+#else
+ using StringCultureInfoDictionary = LowLevelDictionary<string, CultureInfo>;
+ using StringLcidDictionary = LowLevelDictionary<int, CultureInfo>;
+#endif
[Serializable]
- public partial class CultureInfo : ICloneable, IFormatProvider {
+ public partial class CultureInfo : IFormatProvider, ICloneable
+ {
//--------------------------------------------------------------------//
// Internal Information //
//--------------------------------------------------------------------//
@@ -53,38 +56,32 @@ namespace System.Globalization {
//--------------------------------------------------------------------//
// We use an RFC4646 type string to construct CultureInfo.
- // This string is stored in m_name and is authoritative.
- // We use the m_cultureData to get the data for our object
-
- // WARNING
- // WARNING: All member fields declared here must also be in ndp/clr/src/vm/object.h
- // WARNING: They aren't really private because object.h can access them, but other C# stuff cannot
- // WARNING: The type loader will rearrange class member offsets so the mscorwks!CultureInfoBaseObject
- // WARNING: must be manually structured to match the true loaded class layout
- // WARNING
- internal bool m_isReadOnly;
- internal CompareInfo compareInfo;
- internal TextInfo textInfo;
+ // This string is stored in _name and is authoritative.
+ // We use the _cultureData to get the data for our object
+
+ private bool _isReadOnly;
+ private CompareInfo compareInfo;
+ private TextInfo textInfo;
internal NumberFormatInfo numInfo;
internal DateTimeFormatInfo dateTimeInfo;
- internal Calendar calendar;
- [OptionalField(VersionAdded = 1)]
- internal int m_dataItem; // NEVER USED, DO NOT USE THIS! (Serialized in Whidbey/Everett)
- [OptionalField(VersionAdded = 1)]
- internal int cultureID = 0x007f; // NEVER USED, DO NOT USE THIS! (Serialized in Whidbey/Everett)
+ private Calendar calendar;
//
// The CultureData instance that we are going to read data from.
// For supported culture, this will be the CultureData instance that read data from mscorlib assembly.
// For customized culture, this will be the CultureData instance that read data from user customized culture binary file.
//
- [NonSerialized]internal CultureData m_cultureData;
-
- [NonSerialized]internal bool m_isInherited;
- [NonSerialized]private CultureInfo m_consoleFallbackCulture;
+ [NonSerialized]
+ internal CultureData _cultureData;
+
+ [NonSerialized]
+ internal bool _isInherited;
+
+ [NonSerialized]
+ private CultureInfo _consoleFallbackCulture;
// Names are confusing. Here are 3 names we have:
//
- // new CultureInfo() m_name m_nonSortName m_sortName
+ // new CultureInfo() _name _nonSortName _sortName
// en-US en-US en-US en-US
// de-de_phoneb de-DE_phoneb de-DE de-DE_phoneb
// fj-fj (custom) fj-FJ fj-FJ en-US (if specified sort is en-US)
@@ -96,17 +93,18 @@ namespace System.Globalization {
// Note that the name used to be serialized for Everett; it is now serialized
// because alernate sorts can have alternate names.
// This has a de-DE, de-DE_phoneb or fj-FJ style name
- internal string m_name;
+ internal string _name;
// This will hold the non sorting name to be returned from CultureInfo.Name property.
// This has a de-DE style name even for de-DE_phoneb type cultures
- [NonSerialized]private string m_nonSortName;
+ [NonSerialized]
+ private string _nonSortName;
// This will hold the sorting name to be returned from CultureInfo.SortName property.
// This might be completely unrelated to the culture name if a custom culture. Ie en-US for fj-FJ.
// Otherwise its the sort name, ie: de-DE or de-DE_phoneb
- [NonSerialized]private string m_sortName;
-
+ [NonSerialized]
+ private string _sortName;
//--------------------------------------------------------------------//
//
@@ -117,184 +115,74 @@ namespace System.Globalization {
//Get the current user default culture. This one is almost always used, so we create it by default.
private static volatile CultureInfo s_userDefaultCulture;
+ //The culture used in the user interface. This is mostly used to load correct localized resources.
+ private static volatile CultureInfo s_userDefaultUICulture;
//
// All of the following will be created on demand.
//
+ // WARNING: We allow diagnostic tools to directly inspect these three members (s_InvariantCultureInfo, s_DefaultThreadCurrentUICulture and s_DefaultThreadCurrentCulture)
+ // See https://github.com/dotnet/corert/blob/master/Documentation/design-docs/diagnostics/diagnostics-tools-contract.md for more details.
+ // Please do not change the type, the name, or the semantic usage of this member without understanding the implication for tools.
+ // Get in touch with the diagnostics team if you have questions.
+
//The Invariant culture;
private static volatile CultureInfo s_InvariantCultureInfo;
- //The culture used in the user interface. This is mostly used to load correct localized resources.
- private static volatile CultureInfo s_userDefaultUICulture;
-
- //This is the UI culture used to install the OS.
- private static volatile CultureInfo s_InstalledUICultureInfo;
-
//These are defaults that we use if a thread has not opted into having an explicit culture
private static volatile CultureInfo s_DefaultThreadCurrentUICulture;
private static volatile CultureInfo s_DefaultThreadCurrentCulture;
- //This is a cache of all previously created cultures. Valid keys are LCIDs or the name. We use two hashtables to track them,
- // depending on how they are called.
- private static volatile Hashtable s_LcidCachedCultures;
- private static volatile Hashtable s_NameCachedCultures;
+ internal static AsyncLocal<CultureInfo> s_asyncLocalCurrentCulture;
+ internal static AsyncLocal<CultureInfo> s_asyncLocalCurrentUICulture;
-#if FEATURE_APPX
- // When running under AppX, we use this to get some information about the language list
- private static volatile WindowsRuntimeResourceManagerBase s_WindowsRuntimeResourceManager;
+ internal static void AsyncLocalSetCurrentCulture(AsyncLocalValueChangedArgs<CultureInfo> args)
+ {
+ Thread.m_CurrentCulture = args.CurrentValue;
+ }
- [ThreadStatic]
- private static bool ts_IsDoingAppXCultureInfoLookup;
-#endif
+ internal static void AsyncLocalSetCurrentUICulture(AsyncLocalValueChangedArgs<CultureInfo> args)
+ {
+ Thread.m_CurrentUICulture = args.CurrentValue;
+ }
+
+ private static readonly Lock _lock = new Lock();
+ private static volatile StringCultureInfoDictionary s_NameCachedCultures;
+ private static volatile StringLcidDictionary s_LcidCachedCultures;
//The parent culture.
- [NonSerialized]private CultureInfo m_parent;
+ [NonSerialized]
+ private CultureInfo _parent;
// LOCALE constants of interest to us internally and privately for LCID functions
// (ie: avoid using these and use names if possible)
- internal const int LOCALE_NEUTRAL = 0x0000;
- private const int LOCALE_USER_DEFAULT = 0x0400;
- private const int LOCALE_SYSTEM_DEFAULT = 0x0800;
- internal const int LOCALE_CUSTOM_DEFAULT = 0x0c00;
- internal const int LOCALE_CUSTOM_UNSPECIFIED = 0x1000;
- internal const int LOCALE_INVARIANT = 0x007F;
- private const int LOCALE_TRADITIONAL_SPANISH = 0x040a;
+ internal const int LOCALE_NEUTRAL = 0x0000;
+ private const int LOCALE_USER_DEFAULT = 0x0400;
+ private const int LOCALE_SYSTEM_DEFAULT = 0x0800;
+ internal const int LOCALE_CUSTOM_UNSPECIFIED = 0x1000;
+ internal const int LOCALE_CUSTOM_DEFAULT = 0x0c00;
+ internal const int LOCALE_INVARIANT = 0x007F;
//
// The CultureData instance that reads the data provided by our CultureData class.
//
- //Using a field initializer rather than a static constructor so that the whole class can be lazy
- //init.
+ // Using a field initializer rather than a static constructor so that the whole class can be lazy
+ // init.
private static readonly bool init = Init();
private static bool Init()
{
-
- if (s_InvariantCultureInfo == null)
+ if (s_InvariantCultureInfo == null)
{
CultureInfo temp = new CultureInfo("", false);
- temp.m_isReadOnly = true;
+ temp._isReadOnly = true;
s_InvariantCultureInfo = temp;
}
- // First we set it to Invariant in case someone needs it before we're done finding it.
- // For example, if we throw an exception in InitUserDefaultCulture, we will still need an valid
- // s_userDefaultCulture to be used in Thread.CurrentCulture.
- s_userDefaultCulture = s_userDefaultUICulture = s_InvariantCultureInfo;
- s_userDefaultCulture = InitUserDefaultCulture();
- s_userDefaultUICulture = InitUserDefaultUICulture();
+ s_userDefaultCulture = GetUserDefaultCulture();
+ s_userDefaultUICulture = GetUserDefaultUILanguage();
return true;
}
- static CultureInfo InitUserDefaultCulture()
- {
- String strDefault = GetDefaultLocaleName(LOCALE_USER_DEFAULT);
- if (strDefault == null)
- {
- strDefault = GetDefaultLocaleName(LOCALE_SYSTEM_DEFAULT);
-
- if (strDefault == null)
- {
- // If system default doesn't work, keep using the invariant
- return (CultureInfo.InvariantCulture);
- }
- }
- CultureInfo temp = GetCultureByName(strDefault, true);
-
- temp.m_isReadOnly = true;
-
- return (temp);
- }
-
- static CultureInfo InitUserDefaultUICulture()
- {
- String strDefault = GetUserDefaultUILanguage();
-
- // In most of cases, UserDefaultCulture == UserDefaultUICulture, so we should use the same instance if possible.
- if (strDefault == UserDefaultCulture.Name)
- {
- return (UserDefaultCulture);
- }
-
- CultureInfo temp = GetCultureByName( strDefault, true);
-
- if (temp == null)
- {
- return (CultureInfo.InvariantCulture);
- }
-
- temp.m_isReadOnly = true;
-
- return (temp);
- }
-
-#if FEATURE_APPX
- internal static CultureInfo GetCultureInfoForUserPreferredLanguageInAppX()
- {
- // If a call to GetCultureInfoForUserPreferredLanguageInAppX() generated a recursive
- // call to itself, return null, since we don't want to stack overflow. For example,
- // this can happen if some code in this method ends up calling CultureInfo.CurrentCulture
- // (which is common on check'd build because of BCLDebug logging which calls Int32.ToString()).
- // In this case, returning null will mean CultureInfo.CurrentCulture gets the default Win32
- // value, which should be fine.
- if(ts_IsDoingAppXCultureInfoLookup)
- {
- return null;
- }
-
- // If running within a compilation process (mscorsvw.exe, for example), it is illegal to
- // load any non-mscorlib assembly for execution. Since WindowsRuntimeResourceManager lives
- // in System.Runtime.WindowsRuntime, caller will need to fall back to default Win32 value,
- // which should be fine because we should only ever need to access FX resources during NGEN.
- // FX resources are always loaded from satellite assemblies - even in AppX processes (see the
- // comments in code:System.Resources.ResourceManager.SetAppXConfiguration for more details).
- if (AppDomain.IsAppXNGen)
- {
- return null;
- }
-
- CultureInfo toReturn = null;
-
- try
- {
- ts_IsDoingAppXCultureInfoLookup = true;
-
- if(s_WindowsRuntimeResourceManager == null)
- {
- s_WindowsRuntimeResourceManager = ResourceManager.GetWinRTResourceManager();
- }
-
- toReturn = s_WindowsRuntimeResourceManager.GlobalResourceContextBestFitCultureInfo;
- }
- finally
- {
- ts_IsDoingAppXCultureInfoLookup = false;
- }
-
- return toReturn;
- }
-
- internal static bool SetCultureInfoForUserPreferredLanguageInAppX(CultureInfo ci)
- {
- // If running within a compilation process (mscorsvw.exe, for example), it is illegal to
- // load any non-mscorlib assembly for execution. Since WindowsRuntimeResourceManager lives
- // in System.Runtime.WindowsRuntime, caller will need to fall back to default Win32 value,
- // which should be fine because we should only ever need to access FX resources during NGEN.
- // FX resources are always loaded from satellite assemblies - even in AppX processes (see the
- // comments in code:System.Resources.ResourceManager.SetAppXConfiguration for more details).
- if (AppDomain.IsAppXNGen)
- {
- return false;
- }
-
- if (s_WindowsRuntimeResourceManager == null)
- {
- s_WindowsRuntimeResourceManager = ResourceManager.GetWinRTResourceManager();
- }
-
- return s_WindowsRuntimeResourceManager.SetGlobalResourceContextDefaultCulture(ci);
- }
-#endif
-
////////////////////////////////////////////////////////////////////////
//
// CultureInfo Constructors
@@ -302,38 +190,33 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
- public CultureInfo(String name) : this(name, true) {
+ public CultureInfo(String name)
+ : this(name, true)
+ {
}
- public CultureInfo(String name, bool useUserOverride) {
- if (name==null) {
+ public CultureInfo(String name, bool useUserOverride)
+ {
+ if (name == null)
+ {
throw new ArgumentNullException(nameof(name),
- Environment.GetResourceString("ArgumentNull_String"));
+ SR.ArgumentNull_String);
}
- Contract.EndContractBlock();
-
- // Get our data providing record
- this.m_cultureData = CultureData.GetCultureData(name, useUserOverride);
- if (this.m_cultureData == null) {
- throw new CultureNotFoundException(nameof(name), name, Environment.GetResourceString("Argument_CultureNotSupported"));
- }
-
- this.m_name = this.m_cultureData.CultureName;
- this.m_isInherited = (this.GetType() != typeof(System.Globalization.CultureInfo));
+ InitializeFromName(name, useUserOverride);
}
-
-#if FEATURE_USE_LCID
- public CultureInfo(int culture) : this(culture, true) {
+ public CultureInfo(int culture) : this(culture, true)
+ {
}
- public CultureInfo(int culture, bool useUserOverride) {
+ public CultureInfo(int culture, bool useUserOverride)
+ {
// We don't check for other invalid LCIDS here...
- if (culture < 0) {
- throw new ArgumentOutOfRangeException(nameof(culture),
- Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ if (culture < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(culture), SR.ArgumentOutOfRange_NeedPosNum);
}
Contract.EndContractBlock();
@@ -351,88 +234,31 @@ namespace System.Globalization {
case LOCALE_CUSTOM_UNSPECIFIED:
// Can't support unknown custom cultures and we do not support neutral or
// non-custom user locales.
- throw new CultureNotFoundException(
- nameof(culture), culture, Environment.GetResourceString("Argument_CultureNotSupported"));
+ throw new CultureNotFoundException(nameof(culture), culture, SR.Argument_CultureNotSupported);
default:
- // Now see if this LCID is supported in the system default CultureData table.
- this.m_cultureData = CultureData.GetCultureData(culture, useUserOverride);
+ // Now see if this LCID is supported in the system default CultureData table.
+ _cultureData = CultureData.GetCultureData(culture, useUserOverride);
break;
}
- this.m_isInherited = (this.GetType() != typeof(System.Globalization.CultureInfo));
- this.m_name = this.m_cultureData.CultureName;
+ _isInherited = (this.GetType() != typeof(System.Globalization.CultureInfo));
+ _name = _cultureData.CultureName;
}
-#endif // FEATURE_USE_LCID
-
-#region Serialization
- // We need to store the override from the culture data record.
- private bool m_useUserOverride;
- [OnDeserialized]
- private void OnDeserialized(StreamingContext ctx)
+ private void InitializeFromName(string name, bool useUserOverride)
{
-#if FEATURE_USE_LCID
- // Whidbey+ should remember our name
- // but v1 and v1.1 did not store name -- only lcid
- // Whidbey did not store actual alternate sort name in m_name
- // like we do in v4 so we can't use name for alternate sort
- // e.g. for es-ES_tradnl: v2 puts es-ES in m_name; v4 puts es-ES_tradnl
- if (m_name == null || IsAlternateSortLcid(cultureID))
- {
- Debug.Assert(cultureID >=0, "[CultureInfo.OnDeserialized] cultureID >= 0");
- InitializeFromCultureId(cultureID, m_useUserOverride);
- }
- else
- {
-#endif
- Debug.Assert(m_name != null, "[CultureInfo.OnDeserialized] m_name != null");
-
- this.m_cultureData = CultureData.GetCultureData(m_name, m_useUserOverride);
- if (this.m_cultureData == null)
- throw new CultureNotFoundException(
- nameof(m_name), m_name, Environment.GetResourceString("Argument_CultureNotSupported"));
-
-#if FEATURE_USE_LCID
- }
-#endif
- m_isInherited = (this.GetType() != typeof(System.Globalization.CultureInfo));
- }
-
-#if FEATURE_USE_LCID
- // A locale ID is a 32 bit value which is the combination of a
- // language ID, a sort ID, and a reserved area. The bits are
- // allocated as follows:
- //
- // +------------------------+-------+--------------------------------+
- // | Reserved |Sort ID| Language ID |
- // +------------------------+-------+--------------------------------+
- // 31 20 19 16 15 0 bit
- private const int LOCALE_SORTID_MASK = 0x000f0000;
+ // Get our data providing record
+ _cultureData = CultureData.GetCultureData(name, useUserOverride);
- static private bool IsAlternateSortLcid(int lcid)
- {
- if(lcid == LOCALE_TRADITIONAL_SPANISH)
+ if (_cultureData == null)
{
- return true;
+ throw new CultureNotFoundException(nameof(name), name, SR.Argument_CultureNotSupported);
}
- return (lcid & LOCALE_SORTID_MASK) != 0;
- }
-#endif
-
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx)
- {
- this.m_name = this.m_cultureData.CultureName;
- this.m_useUserOverride = this.m_cultureData.UseUserOverride;
-#if FEATURE_USE_LCID
- // for compatibility with v2 serialize cultureID
- this.cultureID = this.m_cultureData.ILANGUAGE;
-#endif
+ _name = _cultureData.CultureName;
+ _isInherited = (this.GetType() != typeof(System.Globalization.CultureInfo));
}
-#endregion Serialization
-
// Constructor called by SQL Server's special munged culture - creates a culture with
// a TextInfo and CompareInfo that come from a supplied alternate source. This object
// is ALWAYS read-only.
@@ -441,38 +267,46 @@ namespace System.Globalization {
// the GetCultureInfo override *only*.
internal CultureInfo(String cultureName, String textAndCompareCultureName)
{
- if (cultureName==null) {
- throw new ArgumentNullException(nameof(cultureName),
- Environment.GetResourceString("ArgumentNull_String"));
+ if (cultureName == null)
+ {
+ throw new ArgumentNullException(nameof(cultureName),SR.ArgumentNull_String);
}
Contract.EndContractBlock();
- this.m_cultureData = CultureData.GetCultureData(cultureName, false);
- if (this.m_cultureData == null)
- throw new CultureNotFoundException(
- nameof(cultureName), cultureName, Environment.GetResourceString("Argument_CultureNotSupported"));
+ _cultureData = CultureData.GetCultureData(cultureName, false);
+ if (_cultureData == null)
+ throw new CultureNotFoundException(nameof(cultureName), cultureName, SR.Argument_CultureNotSupported);
- this.m_name = this.m_cultureData.CultureName;
+ _name = _cultureData.CultureName;
CultureInfo altCulture = GetCultureInfo(textAndCompareCultureName);
- this.compareInfo = altCulture.CompareInfo;
- this.textInfo = altCulture.TextInfo;
+ compareInfo = altCulture.CompareInfo;
+ textInfo = altCulture.TextInfo;
}
// We do this to try to return the system UI language and the default user languages
- // The callers should have a fallback if this fails (like Invariant)
+ // This method will fallback if this fails (like Invariant)
+ //
+ // TODO: It would appear that this is only ever called with userOveride = true
+ // and this method only has one caller. Can we fold it into the caller?
private static CultureInfo GetCultureByName(String name, bool userOverride)
- {
+ {
+ CultureInfo ci = null;
// Try to get our culture
try
{
- return userOverride ? new CultureInfo(name) : CultureInfo.GetCultureInfo(name);
+ ci = userOverride ? new CultureInfo(name) : CultureInfo.GetCultureInfo(name);
}
catch (ArgumentException)
{
}
- return null;
+ if (ci == null)
+ {
+ ci = InvariantCulture;
+ }
+
+ return ci;
}
//
@@ -483,14 +317,18 @@ namespace System.Globalization {
// if we can't find a bigger name. That doesn't help with things like "zh" though, so
// the approach is of questionable value
//
- public static CultureInfo CreateSpecificCulture(String name) {
+ public static CultureInfo CreateSpecificCulture(String name)
+ {
Contract.Ensures(Contract.Result<CultureInfo>() != null);
CultureInfo culture;
- try {
+ try
+ {
culture = new CultureInfo(name);
- } catch(ArgumentException) {
+ }
+ catch (ArgumentException)
+ {
// When CultureInfo throws this exception, it may be because someone passed the form
// like "az-az" because it came out of an http accept lang. We should try a little
// parsing to perhaps fall back to "az" here and use *it* to create the neutral.
@@ -498,269 +336,160 @@ namespace System.Globalization {
int idx;
culture = null;
- for(idx = 0; idx < name.Length; idx++) {
- if('-' == name[idx]) {
- try {
+ for (idx = 0; idx < name.Length; idx++)
+ {
+ if ('-' == name[idx])
+ {
+ try
+ {
culture = new CultureInfo(name.Substring(0, idx));
break;
- } catch(ArgumentException) {
+ }
+ catch (ArgumentException)
+ {
// throw the original exception so the name in the string will be right
throw;
}
}
}
- if(null == culture) {
+ if (culture == null)
+ {
// nothing to save here; throw the original exception
throw;
}
}
- //In the most common case, they've given us a specific culture, so we'll just return that.
- if (!(culture.IsNeutralCulture)) {
+ // In the most common case, they've given us a specific culture, so we'll just return that.
+ if (!(culture.IsNeutralCulture))
+ {
return culture;
}
- return (new CultureInfo(culture.m_cultureData.SSPECIFICCULTURE));
+ return (new CultureInfo(culture._cultureData.SSPECIFICCULTURE));
}
- internal static bool VerifyCultureName(String cultureName, bool throwException)
+ internal static bool VerifyCultureName(String cultureName, bool throwException)
{
- // This function is used by ResourceManager.GetResourceFileName().
+ // This function is used by ResourceManager.GetResourceFileName().
// ResourceManager searches for resource using CultureInfo.Name,
// so we should check against CultureInfo.Name.
- for (int i=0; i<cultureName.Length; i++) {
+ for (int i = 0; i < cultureName.Length; i++)
+ {
char c = cultureName[i];
-
- if (Char.IsLetterOrDigit(c) || c=='-' || c=='_') {
+ // TODO: Names can only be RFC4646 names (ie: a-zA-Z0-9) while this allows any unicode letter/digit
+ if (Char.IsLetterOrDigit(c) || c == '-' || c == '_')
+ {
continue;
}
- if (throwException) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidResourceCultureName", cultureName));
+ if (throwException)
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidResourceCultureName, cultureName));
}
return false;
}
return true;
-
}
- internal static bool VerifyCultureName(CultureInfo culture, bool throwException) {
- Debug.Assert(culture!=null, "[CultureInfo.VerifyCultureName]culture!=null");
-
+ internal static bool VerifyCultureName(CultureInfo culture, bool throwException)
+ {
//If we have an instance of one of our CultureInfos, the user can't have changed the
//name and we know that all names are valid in files.
- if (!culture.m_isInherited) {
+ if (!culture._isInherited)
+ {
return true;
}
return VerifyCultureName(culture.Name, throwException);
-
}
- ////////////////////////////////////////////////////////////////////////
- //
- // CurrentCulture
- //
- // This instance provides methods based on the current user settings.
- // These settings are volatile and may change over the lifetime of the
- // thread.
- //
- ////////////////////////////////////////////////////////////////////////
-
+ // We need to store the override from the culture data record.
+ private bool _useUserOverride;
- public static CultureInfo CurrentCulture
+ [OnSerializing]
+ private void OnSerializing(StreamingContext ctx)
{
- get {
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
-
- // In the case of CoreCLR, Thread.m_CurrentCulture and
- // Thread.m_CurrentUICulture are thread static so as not to let
- // CultureInfo objects leak across AppDomain boundaries. The
- // fact that these fields are thread static introduces overhead
- // in accessing them (through Thread.CurrentCulture). There is
- // also overhead in accessing Thread.CurrentThread. In this
- // case, we can avoid the overhead of Thread.CurrentThread
- // because these fields are thread static, and so do not
- // require a Thread instance to be accessed.
-#if FEATURE_APPX
- if(AppDomain.IsAppXModel()) {
- CultureInfo culture = GetCultureInfoForUserPreferredLanguageInAppX();
- if (culture != null)
- return culture;
- }
-#endif
- return Thread.m_CurrentCulture ??
- s_DefaultThreadCurrentCulture ??
- s_userDefaultCulture ??
- UserDefaultCulture;
- }
-
- set {
-#if FEATURE_APPX
- if (value == null) {
- throw new ArgumentNullException(nameof(value));
- }
-
- if (AppDomain.IsAppXModel()) {
- if (SetCultureInfoForUserPreferredLanguageInAppX(value)) {
- // successfully set the culture, otherwise fallback to legacy path
- return;
- }
- }
-#endif
- Thread.CurrentThread.CurrentCulture = value;
- }
+ _name = _cultureData.CultureName;
+ _useUserOverride = _cultureData.UseUserOverride;
}
- //
- // This is the equivalence of the Win32 GetUserDefaultLCID()
- //
- internal static CultureInfo UserDefaultCulture {
- get
+ [OnDeserialized]
+ private void OnDeserialized(StreamingContext ctx)
+ {
+ Debug.Assert(_name != null, "[CultureInfo.OnDeserialized] _name != null");
+ InitializeFromName(_name, _useUserOverride);
+ }
+
+ internal static CultureInfo GetCurrentUICultureNoAppX()
+ {
+ CultureInfo ci = GetUserDefaultCultureCacheOverride();
+ if (ci != null)
{
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
-
- CultureInfo temp = s_userDefaultCulture;
- if (temp == null)
- {
- //
- // setting the s_userDefaultCulture with invariant culture before intializing it is a protection
- // against recursion problem just in case if somebody called CurrentCulture from the CultureInfo
- // creation path. the recursion can happen if the current user culture is a replaced custom culture.
- //
-
- s_userDefaultCulture = CultureInfo.InvariantCulture;
- temp = InitUserDefaultCulture();
- s_userDefaultCulture = temp;
- }
- return (temp);
+ return ci;
}
- }
- //
- // This is the equivalence of the Win32 GetUserDefaultUILanguage()
- //
- internal static CultureInfo UserDefaultUICulture {
- get {
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
-
- CultureInfo temp = s_userDefaultUICulture;
- if (temp == null)
- {
- //
- // setting the s_userDefaultCulture with invariant culture before intializing it is a protection
- // against recursion problem just in case if somebody called CurrentUICulture from the CultureInfo
- // creation path. the recursion can happen if the current user culture is a replaced custom culture.
- //
-
- s_userDefaultUICulture = CultureInfo.InvariantCulture;
-
- temp = InitUserDefaultUICulture();
- s_userDefaultUICulture = temp;
- }
- return (temp);
+ if (Thread.m_CurrentUICulture != null)
+ {
+ return Thread.m_CurrentUICulture;
}
- }
+ ci = s_DefaultThreadCurrentUICulture;
+ if (ci != null)
+ {
+ return ci;
+ }
- public static CultureInfo CurrentUICulture {
- get {
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
-
- // In the case of CoreCLR, Thread.m_CurrentCulture and
- // Thread.m_CurrentUICulture are thread static so as not to let
- // CultureInfo objects leak across AppDomain boundaries. The
- // fact that these fields are thread static introduces overhead
- // in accessing them (through Thread.CurrentCulture). There is
- // also overhead in accessing Thread.CurrentThread. In this
- // case, we can avoid the overhead of Thread.CurrentThread
- // because these fields are thread static, and so do not
- // require a Thread instance to be accessed.
-#if FEATURE_APPX
- if(AppDomain.IsAppXModel()) {
- CultureInfo culture = GetCultureInfoForUserPreferredLanguageInAppX();
- if (culture != null)
- return culture;
- }
-#endif
- return Thread.m_CurrentUICulture ??
- s_DefaultThreadCurrentUICulture ??
- s_userDefaultUICulture ??
- UserDefaultUICulture;
- }
-
- set {
-#if FEATURE_APPX
- if (value == null) {
- throw new ArgumentNullException(nameof(value));
- }
-
- if (AppDomain.IsAppXModel()) {
- if (SetCultureInfoForUserPreferredLanguageInAppX(value)) {
- // successfully set the culture, otherwise fallback to legacy path
- return;
- }
- }
-#endif
- Thread.CurrentThread.CurrentUICulture = value;
+ // if s_userDefaultUICulture == null means CultureInfo statics didn't get initialized yet. this can happen if there early static
+ // method get executed which eventually hit the cultureInfo code while CultureInfo statics didn’t get chance to initialize
+ if (s_userDefaultUICulture == null)
+ {
+ Init();
}
- }
+ Debug.Assert(s_userDefaultUICulture != null);
+ return s_userDefaultUICulture;
+ }
- //
- // This is the equivalence of the Win32 GetSystemDefaultUILanguage()
- //
- public static CultureInfo InstalledUICulture {
- get {
+ public static CultureInfo InstalledUICulture
+ {
+ get
+ {
Contract.Ensures(Contract.Result<CultureInfo>() != null);
-
- CultureInfo temp = s_InstalledUICultureInfo;
- if (temp == null) {
- String strDefault = GetSystemDefaultUILanguage();
- temp = GetCultureByName(strDefault, true);
-
- if (temp == null)
- {
- temp = InvariantCulture;
- }
-
- temp.m_isReadOnly = true;
- s_InstalledUICultureInfo = temp;
+ if (s_userDefaultCulture == null)
+ {
+ Init();
}
- return (temp);
+ Debug.Assert(s_userDefaultCulture != null, "[CultureInfo.InstalledUICulture] s_userDefaultCulture != null");
+ return s_userDefaultCulture;
}
}
- public static CultureInfo DefaultThreadCurrentCulture {
- get {
- return s_DefaultThreadCurrentCulture;
- }
-
- set {
-
- // If you add pre-conditions to this method, check to see if you also need to
+ public static CultureInfo DefaultThreadCurrentCulture
+ {
+ get { return s_DefaultThreadCurrentCulture; }
+ set
+ {
+ // If you add pre-conditions to this method, check to see if you also need to
// add them to Thread.CurrentCulture.set.
s_DefaultThreadCurrentCulture = value;
}
}
- public static CultureInfo DefaultThreadCurrentUICulture {
- get {
- return s_DefaultThreadCurrentUICulture;
- }
-
- set {
-
+ public static CultureInfo DefaultThreadCurrentUICulture
+ {
+ get { return s_DefaultThreadCurrentUICulture; }
+ set
+ {
//If they're trying to use a Culture with a name that we can't use in resource lookup,
//don't even let them set it on the thread.
- // If you add more pre-conditions to this method, check to see if you also need to
+ // If you add more pre-conditions to this method, check to see if you also need to
// add them to Thread.CurrentUICulture.set.
- if (value != null)
- {
+ if (value != null)
+ {
CultureInfo.VerifyCultureName(value, true);
}
@@ -782,10 +511,10 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
- public static CultureInfo InvariantCulture {
- [Pure]
- get {
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
+ public static CultureInfo InvariantCulture
+ {
+ get
+ {
return (s_InvariantCultureInfo);
}
}
@@ -803,21 +532,19 @@ namespace System.Globalization {
{
get
{
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
- CultureInfo culture = null;
-
- if (null == m_parent)
+ if (null == _parent)
{
try
{
- string parentName = this.m_cultureData.SPARENT;
+ string parentName = _cultureData.SPARENT;
+
if (String.IsNullOrEmpty(parentName))
{
- culture = InvariantCulture;
+ _parent = InvariantCulture;
}
else
{
- culture = new CultureInfo(parentName, this.m_cultureData.UseUserOverride);
+ _parent = new CultureInfo(parentName, _cultureData.UseUserOverride);
}
}
catch (ArgumentException)
@@ -825,58 +552,35 @@ namespace System.Globalization {
// For whatever reason our IPARENT or SPARENT wasn't correct, so use invariant
// We can't allow ourselves to fail. In case of custom cultures the parent of the
// current custom culture isn't installed.
- culture = InvariantCulture;
+ _parent = InvariantCulture;
}
-
- Interlocked.CompareExchange<CultureInfo>(ref m_parent, culture, null);
}
- return m_parent;
+ return _parent;
}
}
- ////////////////////////////////////////////////////////////////////////
- //
- // LCID
- //
- // Returns a properly formed culture identifier for the current
- // culture info.
- //
- ////////////////////////////////////////////////////////////////////////
-
-#if FEATURE_USE_LCID
- public virtual int LCID {
- get {
- return (this.m_cultureData.ILANGUAGE);
+ public virtual int LCID
+ {
+ get
+ {
+ return (this._cultureData.ILANGUAGE);
}
}
-#endif
- ////////////////////////////////////////////////////////////////////////
- //
- // BaseInputLanguage
- //
- // Essentially an LCID, though one that may be different than LCID in the case
- // of a customized culture (LCID == LOCALE_CUSTOM_UNSPECIFIED).
- //
- ////////////////////////////////////////////////////////////////////////
-#if FEATURE_USE_LCID
public virtual int KeyboardLayoutId
{
get
{
- int keyId = this.m_cultureData.IINPUTLANGUAGEHANDLE;
-
- // Not a customized culture, return the default Keyboard layout ID, which is the same as the language ID.
- return (keyId);
+ return _cultureData.IINPUTLANGUAGEHANDLE;
}
}
-#endif
- public static CultureInfo[] GetCultures(CultureTypes types) {
+ public static CultureInfo[] GetCultures(CultureTypes types)
+ {
Contract.Ensures(Contract.Result<CultureInfo[]>() != null);
// internally we treat UserCustomCultures as Supplementals but v2
// treats as Supplementals and Replacements
- if((types & CultureTypes.UserCustomCulture) == CultureTypes.UserCustomCulture)
+ if ((types & CultureTypes.UserCustomCulture) == CultureTypes.UserCustomCulture)
{
types |= CultureTypes.ReplacementCultures;
}
@@ -891,18 +595,20 @@ namespace System.Globalization {
// "en-US" This version does NOT include sort information in the name.
//
////////////////////////////////////////////////////////////////////////
- public virtual String Name {
- get {
- Contract.Ensures(Contract.Result<String>() != null);
-
+ public virtual String Name
+ {
+ get
+ {
// We return non sorting name here.
- if (this.m_nonSortName == null) {
- this.m_nonSortName = this.m_cultureData.SNAME;
- if (this.m_nonSortName == null) {
- this.m_nonSortName = String.Empty;
+ if (_nonSortName == null)
+ {
+ _nonSortName = _cultureData.SNAME;
+ if (_nonSortName == null)
+ {
+ _nonSortName = String.Empty;
}
}
- return this.m_nonSortName;
+ return _nonSortName;
}
}
@@ -911,20 +617,20 @@ namespace System.Globalization {
{
get
{
- if (this.m_sortName == null)
+ if (_sortName == null)
{
- this.m_sortName = this.m_cultureData.SCOMPAREINFO;
+ _sortName = _cultureData.SCOMPAREINFO;
}
- return this.m_sortName;
+ return _sortName;
}
}
- public String IetfLanguageTag
+ public string IetfLanguageTag
{
get
{
- Contract.Ensures(Contract.Result<String>() != null);
+ Contract.Ensures(Contract.Result<string>() != null);
// special case the compatibility cultures
switch (this.Name)
@@ -953,9 +659,9 @@ namespace System.Globalization {
get
{
Contract.Ensures(Contract.Result<String>() != null);
- Debug.Assert(m_name != null, "[CultureInfo.DisplayName]Always expect m_name to be set");
+ Debug.Assert(_name != null, "[CultureInfo.DisplayName] Always expect _name to be set");
- return m_cultureData.SLOCALIZEDDISPLAYNAME;
+ return _cultureData.SLOCALIZEDDISPLAYNAME;
}
}
@@ -968,10 +674,12 @@ namespace System.Globalization {
// (United States)" will be returned.
//
////////////////////////////////////////////////////////////////////////
- public virtual String NativeName {
- get {
+ public virtual String NativeName
+ {
+ get
+ {
Contract.Ensures(Contract.Result<String>() != null);
- return (this.m_cultureData.SNATIVEDISPLAYNAME);
+ return (_cultureData.SNATIVEDISPLAYNAME);
}
}
@@ -984,26 +692,32 @@ namespace System.Globalization {
// (United States)" will be returned.
//
////////////////////////////////////////////////////////////////////////
- public virtual String EnglishName {
- get {
+ public virtual String EnglishName
+ {
+ get
+ {
Contract.Ensures(Contract.Result<String>() != null);
- return (this.m_cultureData.SENGDISPLAYNAME);
+ return (_cultureData.SENGDISPLAYNAME);
}
}
-
+
// ie: en
- public virtual String TwoLetterISOLanguageName {
- get {
+ public virtual String TwoLetterISOLanguageName
+ {
+ get
+ {
Contract.Ensures(Contract.Result<String>() != null);
- return (this.m_cultureData.SISO639LANGNAME);
+ return (_cultureData.SISO639LANGNAME);
}
}
// ie: eng
- public virtual String ThreeLetterISOLanguageName {
- get {
+ public virtual String ThreeLetterISOLanguageName
+ {
+ get
+ {
Contract.Ensures(Contract.Result<String>() != null);
- return (this.m_cultureData.SISO639LANGNAME2);
+ return _cultureData.SISO639LANGNAME2;
}
}
@@ -1015,10 +729,12 @@ namespace System.Globalization {
// The ISO names are much preferred
//
////////////////////////////////////////////////////////////////////////
- public virtual String ThreeLetterWindowsLanguageName {
- get {
+ public virtual String ThreeLetterWindowsLanguageName
+ {
+ get
+ {
Contract.Ensures(Contract.Result<String>() != null);
- return (this.m_cultureData.SABBREVLANGNAME);
+ return _cultureData.SABBREVLANGNAME;
}
}
@@ -1033,16 +749,14 @@ namespace System.Globalization {
{
get
{
- Contract.Ensures(Contract.Result<CompareInfo>() != null);
-
if (this.compareInfo == null)
{
// Since CompareInfo's don't have any overrideable properties, get the CompareInfo from
// the Non-Overridden CultureInfo so that we only create one CompareInfo per culture
- CompareInfo temp = UseUserOverride
- ? GetCultureInfo(this.m_name).CompareInfo
+ CompareInfo temp = UseUserOverride
+ ? GetCultureInfo(this._name).CompareInfo
: new CompareInfo(this);
- if (CompatibilitySwitches.IsCompatibilityBehaviorDefined)
+ if (OkayToCacheClassWithCompatibilityBehavior)
{
this.compareInfo = temp;
}
@@ -1055,6 +769,14 @@ namespace System.Globalization {
}
}
+ private static bool OkayToCacheClassWithCompatibilityBehavior
+ {
+ get
+ {
+ return true;
+ }
+ }
+
////////////////////////////////////////////////////////////////////////
//
// TextInfo
@@ -1062,19 +784,17 @@ namespace System.Globalization {
// Gets the TextInfo for this culture.
//
////////////////////////////////////////////////////////////////////////
-
-
- public virtual TextInfo TextInfo {
- get {
- Contract.Ensures(Contract.Result<TextInfo>() != null);
-
- if (textInfo==null)
+ public virtual TextInfo TextInfo
+ {
+ get
+ {
+ if (textInfo == null)
{
// Make a new textInfo
- TextInfo tempTextInfo = new TextInfo(this.m_cultureData);
- tempTextInfo.SetReadOnlyState(m_isReadOnly);
+ TextInfo tempTextInfo = new TextInfo(_cultureData);
+ tempTextInfo.SetReadOnlyState(_isReadOnly);
- if (CompatibilitySwitches.IsCompatibilityBehaviorDefined)
+ if (OkayToCacheClassWithCompatibilityBehavior)
{
textInfo = tempTextInfo;
}
@@ -1144,26 +864,24 @@ namespace System.Globalization {
public override String ToString()
{
- Contract.Ensures(Contract.Result<String>() != null);
-
- Debug.Assert(m_name != null, "[CultureInfo.ToString]Always expect m_name to be set");
- return m_name;
+ return _name;
}
- public virtual Object GetFormat(Type formatType) {
- if (formatType == typeof(NumberFormatInfo)) {
+ public virtual Object GetFormat(Type formatType)
+ {
+ if (formatType == typeof(NumberFormatInfo))
return (NumberFormat);
- }
- if (formatType == typeof(DateTimeFormatInfo)) {
+ if (formatType == typeof(DateTimeFormatInfo))
return (DateTimeFormat);
- }
return (null);
}
- public virtual bool IsNeutralCulture {
- get {
- return this.m_cultureData.IsNeutralCulture;
+ public virtual bool IsNeutralCulture
+ {
+ get
+ {
+ return _cultureData.IsNeutralCulture;
}
}
@@ -1173,43 +891,43 @@ namespace System.Globalization {
{
CultureTypes types = 0;
- if (m_cultureData.IsNeutralCulture)
+ if (_cultureData.IsNeutralCulture)
types |= CultureTypes.NeutralCultures;
- else
+ else
types |= CultureTypes.SpecificCultures;
- types |= m_cultureData.IsWin32Installed ? CultureTypes.InstalledWin32Cultures : 0;
+ types |= _cultureData.IsWin32Installed ? CultureTypes.InstalledWin32Cultures : 0;
-// Disable warning 618: System.Globalization.CultureTypes.FrameworkCultures' is obsolete
+ // Disable warning 618: System.Globalization.CultureTypes.FrameworkCultures' is obsolete
#pragma warning disable 618
- types |= m_cultureData.IsFramework ? CultureTypes.FrameworkCultures : 0;
-#pragma warning restore 618
+ types |= _cultureData.IsFramework ? CultureTypes.FrameworkCultures : 0;
- types |= m_cultureData.IsSupplementalCustomCulture ? CultureTypes.UserCustomCulture : 0;
- types |= m_cultureData.IsReplacementCulture ? CultureTypes.ReplacementCultures | CultureTypes.UserCustomCulture : 0;
+#pragma warning restore 618
+ types |= _cultureData.IsSupplementalCustomCulture ? CultureTypes.UserCustomCulture : 0;
+ types |= _cultureData.IsReplacementCulture ? CultureTypes.ReplacementCultures | CultureTypes.UserCustomCulture : 0;
return types;
}
}
- public virtual NumberFormatInfo NumberFormat {
- get
+ public virtual NumberFormatInfo NumberFormat
+ {
+ get
{
- Contract.Ensures(Contract.Result<NumberFormatInfo>() != null);
-
- if (numInfo == null) {
- NumberFormatInfo temp = new NumberFormatInfo(this.m_cultureData);
- temp.isReadOnly = m_isReadOnly;
+ if (numInfo == null)
+ {
+ NumberFormatInfo temp = new NumberFormatInfo(_cultureData);
+ temp.isReadOnly = _isReadOnly;
Interlocked.CompareExchange(ref numInfo, temp, null);
}
return (numInfo);
}
- set {
- if (value == null) {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_Obj"));
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value), SR.ArgumentNull_Obj);
}
- Contract.EndContractBlock();
VerifyWritable();
numInfo = value;
}
@@ -1223,44 +941,40 @@ namespace System.Globalization {
// the CultureID.
//
////////////////////////////////////////////////////////////////////////
-
-
- public virtual DateTimeFormatInfo DateTimeFormat {
- get {
- Contract.Ensures(Contract.Result<DateTimeFormatInfo>() != null);
-
- if (dateTimeInfo == null) {
+ public virtual DateTimeFormatInfo DateTimeFormat
+ {
+ get
+ {
+ if (dateTimeInfo == null)
+ {
// Change the calendar of DTFI to the specified calendar of this CultureInfo.
- DateTimeFormatInfo temp = new DateTimeFormatInfo(
- this.m_cultureData, this.Calendar);
- temp.m_isReadOnly = m_isReadOnly;
+ DateTimeFormatInfo temp = new DateTimeFormatInfo(_cultureData, this.Calendar);
+ temp._isReadOnly = _isReadOnly;
Interlocked.CompareExchange(ref dateTimeInfo, temp, null);
}
return (dateTimeInfo);
}
- set {
- if (value == null) {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_Obj"));
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException(nameof(value), SR.ArgumentNull_Obj);
}
- Contract.EndContractBlock();
VerifyWritable();
dateTimeInfo = value;
}
}
- public void ClearCachedData() {
- s_userDefaultUICulture = null;
+ public void ClearCachedData()
+ {
s_userDefaultCulture = null;
RegionInfo.s_currentRegionInfo = null;
-#pragma warning disable CS0618
+ #pragma warning disable 0618 // disable the obsolete warning
TimeZone.ResetTimeZone();
-#pragma warning restore CS0618
+ #pragma warning restore 0618
TimeZoneInfo.ClearCachedData();
-
- // Delete the cached cultures.
s_LcidCachedCultures = null;
s_NameCachedCultures = null;
@@ -1275,8 +989,10 @@ namespace System.Globalization {
** Shouldn't throw exception since the calType value is from our data table or from Win32 registry.
** If we are in trouble (like getting a weird value from Win32 registry), just return the GregorianCalendar.
============================================================================*/
- internal static Calendar GetCalendarInstance(int calType) {
- if (calType==Calendar.CAL_GREGORIAN) {
+ internal static Calendar GetCalendarInstance(CalendarId calType)
+ {
+ if (calType == CalendarId.GREGORIAN)
+ {
return (new GregorianCalendar());
}
return GetCalendarInstanceRare(calType);
@@ -1284,45 +1000,38 @@ namespace System.Globalization {
//This function exists as a shortcut to prevent us from loading all of the non-gregorian
//calendars unless they're required.
- internal static Calendar GetCalendarInstanceRare(int calType) {
- Debug.Assert(calType!=Calendar.CAL_GREGORIAN, "calType!=Calendar.CAL_GREGORIAN");
-
- switch (calType) {
- case Calendar.CAL_GREGORIAN_US: // Gregorian (U.S.) calendar
- case Calendar.CAL_GREGORIAN_ME_FRENCH: // Gregorian Middle East French calendar
- case Calendar.CAL_GREGORIAN_ARABIC: // Gregorian Arabic calendar
- case Calendar.CAL_GREGORIAN_XLIT_ENGLISH: // Gregorian Transliterated English calendar
- case Calendar.CAL_GREGORIAN_XLIT_FRENCH: // Gregorian Transliterated French calendar
+ internal static Calendar GetCalendarInstanceRare(CalendarId calType)
+ {
+ Debug.Assert(calType != CalendarId.GREGORIAN, "calType!=CalendarId.GREGORIAN");
+
+ switch (calType)
+ {
+ case CalendarId.GREGORIAN_US: // Gregorian (U.S.) calendar
+ case CalendarId.GREGORIAN_ME_FRENCH: // Gregorian Middle East French calendar
+ case CalendarId.GREGORIAN_ARABIC: // Gregorian Arabic calendar
+ case CalendarId.GREGORIAN_XLIT_ENGLISH: // Gregorian Transliterated English calendar
+ case CalendarId.GREGORIAN_XLIT_FRENCH: // Gregorian Transliterated French calendar
return (new GregorianCalendar((GregorianCalendarTypes)calType));
- case Calendar.CAL_TAIWAN: // Taiwan Era calendar
+ case CalendarId.TAIWAN: // Taiwan Era calendar
return (new TaiwanCalendar());
- case Calendar.CAL_JAPAN: // Japanese Emperor Era calendar
+ case CalendarId.JAPAN: // Japanese Emperor Era calendar
return (new JapaneseCalendar());
- case Calendar.CAL_KOREA: // Korean Tangun Era calendar
+ case CalendarId.KOREA: // Korean Tangun Era calendar
return (new KoreanCalendar());
- case Calendar.CAL_THAI: // Thai calendar
+ case CalendarId.THAI: // Thai calendar
return (new ThaiBuddhistCalendar());
- case Calendar.CAL_HIJRI: // Hijri (Arabic Lunar) calendar
+ case CalendarId.HIJRI: // Hijri (Arabic Lunar) calendar
return (new HijriCalendar());
- case Calendar.CAL_HEBREW: // Hebrew (Lunar) calendar
+ case CalendarId.HEBREW: // Hebrew (Lunar) calendar
return (new HebrewCalendar());
- case Calendar.CAL_UMALQURA:
+ case CalendarId.UMALQURA:
return (new UmAlQuraCalendar());
- case Calendar.CAL_PERSIAN:
+ case CalendarId.PERSIAN:
return (new PersianCalendar());
- case Calendar.CAL_CHINESELUNISOLAR:
- return (new ChineseLunisolarCalendar());
- case Calendar.CAL_JAPANESELUNISOLAR:
- return (new JapaneseLunisolarCalendar());
- case Calendar.CAL_KOREANLUNISOLAR:
- return (new KoreanLunisolarCalendar());
- case Calendar.CAL_TAIWANLUNISOLAR:
- return (new TaiwanLunisolarCalendar());
}
return (new GregorianCalendar());
}
-
/*=================================Calendar==========================
**Action: Return/set the default calendar used by this culture.
** This value can be overridden by regional option if this is a current culture.
@@ -1331,19 +1040,19 @@ namespace System.Globalization {
**Exceptions:
** ArgumentNull_Obj if the set value is null.
============================================================================*/
-
-
- public virtual Calendar Calendar {
- get {
- Contract.Ensures(Contract.Result<Calendar>() != null);
- if (calendar == null) {
- Debug.Assert(this.m_cultureData.CalendarIds.Length > 0, "this.m_cultureData.CalendarIds.Length > 0");
+ public virtual Calendar Calendar
+ {
+ get
+ {
+ if (calendar == null)
+ {
+ Debug.Assert(_cultureData.CalendarIds.Length > 0, "_cultureData.CalendarIds.Length > 0");
// Get the default calendar for this culture. Note that the value can be
// from registry if this is a user default culture.
- Calendar newObj = this.m_cultureData.DefaultCalendar;
+ Calendar newObj = _cultureData.DefaultCalendar;
- System.Threading.Thread.MemoryBarrier();
- newObj.SetReadOnlyState(m_isReadOnly);
+ System.Threading.Interlocked.MemoryBarrier();
+ newObj.SetReadOnlyState(_isReadOnly);
calendar = newObj;
}
return (calendar);
@@ -1358,26 +1067,30 @@ namespace System.Globalization {
============================================================================*/
- public virtual Calendar[] OptionalCalendars {
- get {
+ public virtual Calendar[] OptionalCalendars
+ {
+ get
+ {
Contract.Ensures(Contract.Result<Calendar[]>() != null);
//
// This property always returns a new copy of the calendar array.
//
- int[] calID = this.m_cultureData.CalendarIds;
- Calendar [] cals = new Calendar[calID.Length];
- for (int i = 0; i < cals.Length; i++) {
+ CalendarId[] calID = _cultureData.CalendarIds;
+ Calendar[] cals = new Calendar[calID.Length];
+ for (int i = 0; i < cals.Length; i++)
+ {
cals[i] = GetCalendarInstance(calID[i]);
}
return (cals);
}
}
-
- public bool UseUserOverride {
- get {
- return (this.m_cultureData.UseUserOverride);
+ public bool UseUserOverride
+ {
+ get
+ {
+ return _cultureData.UseUserOverride;
}
}
@@ -1385,26 +1098,24 @@ namespace System.Globalization {
{
Contract.Ensures(Contract.Result<CultureInfo>() != null);
- CultureInfo temp = m_consoleFallbackCulture;
+ CultureInfo temp = _consoleFallbackCulture;
if (temp == null)
{
- temp = CreateSpecificCulture(this.m_cultureData.SCONSOLEFALLBACKNAME);
- temp.m_isReadOnly = true;
- m_consoleFallbackCulture = temp;
+ temp = CreateSpecificCulture(_cultureData.SCONSOLEFALLBACKNAME);
+ _isReadOnly = true;
+ _consoleFallbackCulture = temp;
}
return (temp);
}
public virtual Object Clone()
{
- Contract.Ensures(Contract.Result<Object>() != null);
-
CultureInfo ci = (CultureInfo)MemberwiseClone();
- ci.m_isReadOnly = false;
+ ci._isReadOnly = false;
//If this is exactly our type, we can make certain optimizations so that we don't allocate NumberFormatInfo or DTFI unless
//they've already been allocated. If this is a derived type, we'll take a more generic codepath.
- if (!m_isInherited)
+ if (!_isInherited)
{
if (this.dateTimeInfo != null)
{
@@ -1414,36 +1125,37 @@ namespace System.Globalization {
{
ci.numInfo = (NumberFormatInfo)this.numInfo.Clone();
}
-
}
else
{
ci.DateTimeFormat = (DateTimeFormatInfo)this.DateTimeFormat.Clone();
- ci.NumberFormat = (NumberFormatInfo)this.NumberFormat.Clone();
+ ci.NumberFormat = (NumberFormatInfo)this.NumberFormat.Clone();
}
if (textInfo != null)
{
- ci.textInfo = (TextInfo) textInfo.Clone();
+ ci.textInfo = (TextInfo)textInfo.Clone();
}
if (calendar != null)
{
- ci.calendar = (Calendar) calendar.Clone();
+ ci.calendar = (Calendar)calendar.Clone();
}
return (ci);
}
-
- public static CultureInfo ReadOnly(CultureInfo ci) {
- if (ci == null) {
+ public static CultureInfo ReadOnly(CultureInfo ci)
+ {
+ if (ci == null)
+ {
throw new ArgumentNullException(nameof(ci));
}
Contract.Ensures(Contract.Result<CultureInfo>() != null);
Contract.EndContractBlock();
- if (ci.IsReadOnly) {
+ if (ci.IsReadOnly)
+ {
return (ci);
}
CultureInfo newInfo = (CultureInfo)(ci.MemberwiseClone());
@@ -1452,20 +1164,24 @@ namespace System.Globalization {
{
//If this is exactly our type, we can make certain optimizations so that we don't allocate NumberFormatInfo or DTFI unless
//they've already been allocated. If this is a derived type, we'll take a more generic codepath.
- if (!ci.m_isInherited) {
- if (ci.dateTimeInfo != null) {
+ if (!ci._isInherited)
+ {
+ if (ci.dateTimeInfo != null)
+ {
newInfo.dateTimeInfo = DateTimeFormatInfo.ReadOnly(ci.dateTimeInfo);
}
- if (ci.numInfo != null) {
+ if (ci.numInfo != null)
+ {
newInfo.numInfo = NumberFormatInfo.ReadOnly(ci.numInfo);
}
-
- } else {
+ }
+ else
+ {
newInfo.DateTimeFormat = DateTimeFormatInfo.ReadOnly(ci.DateTimeFormat);
newInfo.NumberFormat = NumberFormatInfo.ReadOnly(ci.NumberFormat);
}
}
-
+
if (ci.textInfo != null)
{
newInfo.textInfo = TextInfo.ReadOnly(ci.textInfo);
@@ -1478,23 +1194,26 @@ namespace System.Globalization {
// Don't set the read-only flag too early.
// We should set the read-only flag here. Otherwise, info.DateTimeFormat will not be able to set.
- newInfo.m_isReadOnly = true;
+ newInfo._isReadOnly = true;
return (newInfo);
}
- public bool IsReadOnly {
- get {
- return (m_isReadOnly);
+ public bool IsReadOnly
+ {
+ get
+ {
+ return (_isReadOnly);
}
}
- private void VerifyWritable() {
- if (m_isReadOnly) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
+ private void VerifyWritable()
+ {
+ if (_isReadOnly)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
- Contract.EndContractBlock();
}
// For resource lookup, we consider a culture the invariant culture by name equality.
@@ -1509,24 +1228,17 @@ namespace System.Globalization {
// If lcid is -1, use the altName and create one of those special SQL cultures.
internal static CultureInfo GetCultureInfoHelper(int lcid, string name, string altName)
{
- // There is a race condition in this code with the side effect that the second thread's value
- // clobbers the first in the dictionary. This is an acceptable race condition since the CultureInfo objects
- // are content equal (but not reference equal). Since we make no guarantees there, this race condition is
- // acceptable.
- // See code:Dictionary#DictionaryVersusHashtableThreadSafety for details on Dictionary versus
- // Hashtable thread safety.
-
// retval is our return value.
CultureInfo retval;
// Temporary hashtable for the names.
- Hashtable tempNameHT = s_NameCachedCultures;
+ StringCultureInfoDictionary tempNameHT = s_NameCachedCultures;
if (name != null)
{
name = CultureData.AnsiToLower(name);
}
-
+
if (altName != null)
{
altName = CultureData.AnsiToLower(altName);
@@ -1535,55 +1247,56 @@ namespace System.Globalization {
// We expect the same result for both hashtables, but will test individually for added safety.
if (tempNameHT == null)
{
- tempNameHT = Hashtable.Synchronized(new Hashtable());
+ tempNameHT = new StringCultureInfoDictionary();
}
else
{
// If we are called by name, check if the object exists in the hashtable. If so, return it.
- if (lcid == -1)
+ if (lcid == -1 || lcid == 0)
{
- retval = (CultureInfo)tempNameHT[name + '\xfffd' + altName];
- if (retval != null)
+ bool ret;
+ lock (_lock)
{
- return retval;
+ ret = tempNameHT.TryGetValue(lcid == 0 ? name : name + '\xfffd' + altName, out retval);
}
- }
- else if (lcid == 0)
- {
- retval = (CultureInfo)tempNameHT[name];
- if (retval != null)
+
+ if (ret && retval != null)
{
return retval;
}
}
}
-#if FEATURE_USE_LCID
+
// Next, the Lcid table.
- Hashtable tempLcidHT = s_LcidCachedCultures;
+ StringLcidDictionary tempLcidHT = s_LcidCachedCultures;
if (tempLcidHT == null)
{
// Case insensitive is not an issue here, save the constructor call.
- tempLcidHT = Hashtable.Synchronized(new Hashtable());
+ tempLcidHT = new StringLcidDictionary();
}
else
{
// If we were called by Lcid, check if the object exists in the table. If so, return it.
if (lcid > 0)
{
- retval = (CultureInfo) tempLcidHT[lcid];
- if (retval != null)
+ bool ret;
+ lock (_lock)
+ {
+ ret = tempLcidHT.TryGetValue(lcid, out retval);
+ }
+ if (ret && retval != null)
{
return retval;
}
}
}
-#endif
+
// We now have two temporary hashtables and the desired object was not found.
// We'll construct it. We catch any exceptions from the constructor call and return null.
try
{
- switch(lcid)
+ switch (lcid)
{
case -1:
// call the private constructor
@@ -1595,65 +1308,55 @@ namespace System.Globalization {
break;
default:
-#if FEATURE_USE_LCID
retval = new CultureInfo(lcid, false);
break;
-#else
- return null;
-#endif
}
}
- catch(ArgumentException)
+ catch (ArgumentException)
{
return null;
}
// Set it to read-only
- retval.m_isReadOnly = true;
+ retval._isReadOnly = true;
if (lcid == -1)
{
- // This new culture will be added only to the name hash table.
- tempNameHT[name + '\xfffd' + altName] = retval;
-
+ lock (_lock)
+ {
+ // This new culture will be added only to the name hash table.
+ tempNameHT[name + '\xfffd' + altName] = retval;
+ }
// when lcid == -1 then TextInfo object is already get created and we need to set it as read only.
retval.TextInfo.SetReadOnlyState(true);
}
- else
+ else if (lcid == 0)
{
// Remember our name (as constructed). Do NOT use alternate sort name versions because
// we have internal state representing the sort. (So someone would get the wrong cached version)
- string newName = CultureData.AnsiToLower(retval.m_name);
-
- // We add this new culture info object to both tables.
- tempNameHT[newName] = retval;
-#if FEATURE_USE_LCID
- const int LCID_ZH_CHS_HANS = 0x0004;
- const int LCID_ZH_CHT_HANT = 0x7c04;
+ string newName = CultureData.AnsiToLower(retval._name);
- if ((retval.LCID == LCID_ZH_CHS_HANS && newName == "zh-hans")
- || (retval.LCID == LCID_ZH_CHT_HANT && newName == "zh-hant"))
+ // We add this new culture info object to both tables.
+ lock (_lock)
{
- // do nothing because we only want zh-CHS and zh-CHT to cache
- // by lcid
+ tempNameHT[newName] = retval;
}
- else
+ }
+ else
+ {
+ lock (_lock)
{
- tempLcidHT[retval.LCID] = retval;
+ tempLcidHT[lcid] = retval;
}
-
-#endif
}
-#if FEATURE_USE_LCID
// Copy the two hashtables to the corresponding member variables. This will potentially overwrite
// new tables simultaneously created by a new thread, but maximizes thread safety.
- if(-1 != lcid)
+ if (-1 != lcid)
{
// Only when we modify the lcid hash table, is there a need to overwrite.
s_LcidCachedCultures = tempLcidHT;
}
-#endif
s_NameCachedCultures = tempNameHT;
@@ -1661,7 +1364,6 @@ namespace System.Globalization {
return retval;
}
-#if FEATURE_USE_LCID
// Gets a cached copy of the specified culture from an internal hashtable (or creates it
// if not found). (LCID version)... use named version
public static CultureInfo GetCultureInfo(int culture)
@@ -1669,21 +1371,19 @@ namespace System.Globalization {
// Must check for -1 now since the helper function uses the value to signal
// the altCulture code path for SQL Server.
// Also check for zero as this would fail trying to add as a key to the hash.
- if (culture <= 0) {
- throw new ArgumentOutOfRangeException(nameof(culture),
- Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ if (culture <= 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(culture), SR.ArgumentOutOfRange_NeedPosNum);
}
Contract.Ensures(Contract.Result<CultureInfo>() != null);
Contract.EndContractBlock();
CultureInfo retval = GetCultureInfoHelper(culture, null, null);
if (null == retval)
{
- throw new CultureNotFoundException(
- nameof(culture), culture, Environment.GetResourceString("Argument_CultureNotSupported"));
+ throw new CultureNotFoundException(nameof(culture), culture, SR.Argument_CultureNotSupported);
}
return retval;
}
-#endif
// Gets a cached copy of the specified culture from an internal hashtable (or creates it
// if not found). (Named version)
@@ -1694,15 +1394,12 @@ namespace System.Globalization {
{
throw new ArgumentNullException(nameof(name));
}
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
- Contract.EndContractBlock();
CultureInfo retval = GetCultureInfoHelper(0, name, null);
if (retval == null)
{
throw new CultureNotFoundException(
- nameof(name), name, Environment.GetResourceString("Argument_CultureNotSupported"));
-
+ nameof(name), name, SR.Argument_CultureNotSupported);
}
return retval;
}
@@ -1712,32 +1409,28 @@ namespace System.Globalization {
public static CultureInfo GetCultureInfo(string name, string altName)
{
// Make sure we have a valid, non-zero length string as name
- if (null == name)
+ if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
- if (null == altName)
+ if (altName == null)
{
throw new ArgumentNullException(nameof(altName));
}
+
Contract.Ensures(Contract.Result<CultureInfo>() != null);
Contract.EndContractBlock();
CultureInfo retval = GetCultureInfoHelper(-1, name, altName);
if (retval == null)
{
- throw new CultureNotFoundException(nameof(name) + " or " + nameof(altName),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("Argument_OneOfCulturesNotSupported"),
- name,
- altName));
+ throw new CultureNotFoundException("name or altName",
+ SR.Format(SR.Argument_OneOfCulturesNotSupported, name, altName));
}
return retval;
}
-
// This function is deprecated, we don't like it
public static CultureInfo GetCultureInfoByIetfLanguageTag(string name)
{
@@ -1746,105 +1439,19 @@ namespace System.Globalization {
// Disallow old zh-CHT/zh-CHS names
if (name == "zh-CHT" || name == "zh-CHS")
{
- throw new CultureNotFoundException(
- nameof(name),
- String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_CultureIetfNotSupported"), name)
- );
+ throw new CultureNotFoundException(nameof(name), SR.Format(SR.Argument_CultureIetfNotSupported, name));
}
-
+
CultureInfo ci = GetCultureInfo(name);
// Disallow alt sorts and es-es_TS
if (ci.LCID > 0xffff || ci.LCID == 0x040a)
{
- throw new CultureNotFoundException(
- nameof(name),
- String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_CultureIetfNotSupported"), name)
- );
+ throw new CultureNotFoundException(nameof(name), SR.Format(SR.Argument_CultureIetfNotSupported, name));
}
-
- return ci;
- }
-
- private static volatile bool s_isTaiwanSku;
- private static volatile bool s_haveIsTaiwanSku;
- internal static bool IsTaiwanSku
- {
- get
- {
- if (!s_haveIsTaiwanSku)
- {
- s_isTaiwanSku = (GetSystemDefaultUILanguage() == "zh-TW");
- s_haveIsTaiwanSku = true;
- }
- return (bool)s_isTaiwanSku;
- }
- }
-
- //
- // Helper Methods.
- //
-
- // Get Locale Info Ex calls. So we don't have to muck with the different int/string return types we declared two of these:
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern String nativeGetLocaleInfoEx(String localeName, uint field);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern int nativeGetLocaleInfoExInt(String localeName, uint field);
-
- private static String GetDefaultLocaleName(int localeType)
- {
- Debug.Assert(localeType == LOCALE_USER_DEFAULT || localeType == LOCALE_SYSTEM_DEFAULT, "[CultureInfo.GetDefaultLocaleName] localeType must be LOCALE_USER_DEFAULT or LOCALE_SYSTEM_DEFAULT");
-
- string localeName = null;
- if(InternalGetDefaultLocaleName(localeType, JitHelpers.GetStringHandleOnStack(ref localeName)))
- {
- return localeName;
- }
- return string.Empty;
- }
-
- // Get the default locale name
- [SuppressUnmanagedCodeSecurity]
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool InternalGetDefaultLocaleName(int localetype, StringHandleOnStack localeString);
-
- private static String GetUserDefaultUILanguage()
- {
- string userDefaultUiLanguage = null;
- if(InternalGetUserDefaultUILanguage(JitHelpers.GetStringHandleOnStack(ref userDefaultUiLanguage)))
- {
- return userDefaultUiLanguage;
- }
- return String.Empty;
- }
-
- // Get the user's default UI language, return locale name
- [SuppressUnmanagedCodeSecurity]
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool InternalGetUserDefaultUILanguage(StringHandleOnStack userDefaultUiLanguage);
-
- private static String GetSystemDefaultUILanguage()
- {
- string systemDefaultUiLanguage = null;
- if(InternalGetSystemDefaultUILanguage(JitHelpers.GetStringHandleOnStack(ref systemDefaultUiLanguage)))
- {
- return systemDefaultUiLanguage;
- }
- return String.Empty;
+ return ci;
}
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- [SuppressUnmanagedCodeSecurity]
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool InternalGetSystemDefaultUILanguage(StringHandleOnStack systemDefaultUiLanguage);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern String[] nativeGetResourceFallbackArray();
}
}
diff --git a/src/mscorlib/src/System/Globalization/CultureNotFoundException.cs b/src/mscorlib/src/System/Globalization/CultureNotFoundException.cs
deleted file mode 100644
index d4ab700a16..0000000000
--- a/src/mscorlib/src/System/Globalization/CultureNotFoundException.cs
+++ /dev/null
@@ -1,129 +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.
-
-
-namespace System.Globalization {
-
- using System;
- using System.Runtime.Serialization;
- using System.Threading;
- using System.Diagnostics.Contracts;
-
- [Serializable]
- public partial class CultureNotFoundException : ArgumentException, ISerializable
- {
- private string m_invalidCultureName; // unrecognized culture name
- private Nullable<int> m_invalidCultureId; // unrecognized culture Lcid
-
- public CultureNotFoundException()
- : base(DefaultMessage)
- {
- }
-
- public CultureNotFoundException(String message)
- : base(message)
- {
- }
-
- public CultureNotFoundException(String paramName, String message)
- : base(message, paramName)
- {
- }
-
- public CultureNotFoundException(String message, Exception innerException)
- : base(message, innerException)
- {
- }
-
- public CultureNotFoundException(String paramName, int invalidCultureId, String message)
- : base(message, paramName)
- {
- m_invalidCultureId = invalidCultureId;
- }
-
- public CultureNotFoundException(String message, int invalidCultureId, Exception innerException)
- : base(message, innerException)
- {
- m_invalidCultureId = invalidCultureId;
- }
-
- public CultureNotFoundException(String paramName, string invalidCultureName, String message)
- : base(message, paramName)
- {
- m_invalidCultureName = invalidCultureName;
- }
-
- public CultureNotFoundException(String message, string invalidCultureName, Exception innerException)
- : base(message, innerException)
- {
- m_invalidCultureName = invalidCultureName;
- }
-
- protected CultureNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) {
- m_invalidCultureId = (Nullable<int>) info.GetValue("InvalidCultureId", typeof(Nullable<int>));
- m_invalidCultureName = (string) info.GetValue("InvalidCultureName", typeof(string));
- }
-
- public override void GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
- throw new ArgumentNullException(nameof(info));
- }
- Contract.EndContractBlock();
- base.GetObjectData(info, context);
- Nullable<int> invalidCultureId = null;
- invalidCultureId = m_invalidCultureId;
- info.AddValue("InvalidCultureId", invalidCultureId, typeof(Nullable<int>));
- info.AddValue("InvalidCultureName", m_invalidCultureName, typeof(string));
- }
- public virtual Nullable<int> InvalidCultureId
- {
- get { return m_invalidCultureId; }
- }
-
- public virtual string InvalidCultureName
- {
- get { return m_invalidCultureName; }
- }
-
- private static String DefaultMessage
- {
- get
- {
- return Environment.GetResourceString("Argument_CultureNotSupported");
- }
- }
-
- private String FormatedInvalidCultureId
- {
- get
- {
- if (InvalidCultureId != null)
- {
- return String.Format(CultureInfo.InvariantCulture,
- "{0} (0x{0:x4})", (int)InvalidCultureId);
- }
- return InvalidCultureName;
- }
- }
-
- public override String Message
- {
- get
- {
- String s = base.Message;
- if (
- m_invalidCultureId != null ||
- m_invalidCultureName != null)
- {
- String valueMessage = Environment.GetResourceString("Argument_CultureInvalidIdentifier", FormatedInvalidCultureId);
- if (s == null)
- return valueMessage;
- return s + Environment.NewLine + valueMessage;
- }
- return s;
- }
- }
-
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/CultureTypes.cs b/src/mscorlib/src/System/Globalization/CultureTypes.cs
deleted file mode 100644
index b19ab86bb1..0000000000
--- a/src/mscorlib/src/System/Globalization/CultureTypes.cs
+++ /dev/null
@@ -1,30 +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.
-
-//
-// The enumeration constants used in CultureInfo.GetCultures().
-//
-// Note that this isn't exposed in Silverlight
-namespace System.Globalization {
-
-
-[Serializable]
- [Flags]
- public enum CultureTypes
- {
- NeutralCultures = 0x0001, // Neutral cultures are cultures like "en", "de", "zh", etc, for enumeration this includes ALL neutrals regardless of other flags
- SpecificCultures = 0x0002, // Non-netural cultuers. Examples are "en-us", "zh-tw", etc., for enumeration this includes ALL specifics regardless of other flags
- InstalledWin32Cultures = 0x0004, // Win32 installed cultures in the system and exists in the framework too., this is effectively all cultures
-
- AllCultures = NeutralCultures | SpecificCultures | InstalledWin32Cultures,
-
- UserCustomCulture = 0x0008, // User defined custom culture
- ReplacementCultures = 0x0010, // User defined replacement custom culture.
- [Obsolete("This value has been deprecated. Please use other values in CultureTypes.")]
- WindowsOnlyCultures = 0x0020, // this will always return empty list.
- [Obsolete("This value has been deprecated. Please use other values in CultureTypes.")]
- FrameworkCultures = 0x0040, // will return only the v2 cultures marked as Framework culture.
- }
-
-}
diff --git a/src/mscorlib/src/System/Globalization/DateTimeFormat.cs b/src/mscorlib/src/System/Globalization/DateTimeFormat.cs
deleted file mode 100644
index 1ace207952..0000000000
--- a/src/mscorlib/src/System/Globalization/DateTimeFormat.cs
+++ /dev/null
@@ -1,1130 +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.
-
-namespace System {
- using System.Text;
- using System.Threading;
- using System.Globalization;
- using System.Collections.Generic;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
- using System.Security;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- /*
- Customized format patterns:
- P.S. Format in the table below is the internal number format used to display the pattern.
-
- Patterns Format Description Example
- ========= ========== ===================================== ========
- "h" "0" hour (12-hour clock)w/o leading zero 3
- "hh" "00" hour (12-hour clock)with leading zero 03
- "hh*" "00" hour (12-hour clock)with leading zero 03
-
- "H" "0" hour (24-hour clock)w/o leading zero 8
- "HH" "00" hour (24-hour clock)with leading zero 08
- "HH*" "00" hour (24-hour clock) 08
-
- "m" "0" minute w/o leading zero
- "mm" "00" minute with leading zero
- "mm*" "00" minute with leading zero
-
- "s" "0" second w/o leading zero
- "ss" "00" second with leading zero
- "ss*" "00" second with leading zero
-
- "f" "0" second fraction (1 digit)
- "ff" "00" second fraction (2 digit)
- "fff" "000" second fraction (3 digit)
- "ffff" "0000" second fraction (4 digit)
- "fffff" "00000" second fraction (5 digit)
- "ffffff" "000000" second fraction (6 digit)
- "fffffff" "0000000" second fraction (7 digit)
-
- "F" "0" second fraction (up to 1 digit)
- "FF" "00" second fraction (up to 2 digit)
- "FFF" "000" second fraction (up to 3 digit)
- "FFFF" "0000" second fraction (up to 4 digit)
- "FFFFF" "00000" second fraction (up to 5 digit)
- "FFFFFF" "000000" second fraction (up to 6 digit)
- "FFFFFFF" "0000000" second fraction (up to 7 digit)
-
- "t" first character of AM/PM designator A
- "tt" AM/PM designator AM
- "tt*" AM/PM designator PM
-
- "d" "0" day w/o leading zero 1
- "dd" "00" day with leading zero 01
- "ddd" short weekday name (abbreviation) Mon
- "dddd" full weekday name Monday
- "dddd*" full weekday name Monday
-
-
- "M" "0" month w/o leading zero 2
- "MM" "00" month with leading zero 02
- "MMM" short month name (abbreviation) Feb
- "MMMM" full month name Febuary
- "MMMM*" full month name Febuary
-
- "y" "0" two digit year (year % 100) w/o leading zero 0
- "yy" "00" two digit year (year % 100) with leading zero 00
- "yyy" "D3" year 2000
- "yyyy" "D4" year 2000
- "yyyyy" "D5" year 2000
- ...
-
- "z" "+0;-0" timezone offset w/o leading zero -8
- "zz" "+00;-00" timezone offset with leading zero -08
- "zzz" "+00;-00" for hour offset, "00" for minute offset full timezone offset -07:30
- "zzz*" "+00;-00" for hour offset, "00" for minute offset full timezone offset -08:00
-
- "K" -Local "zzz", e.g. -08:00
- -Utc "'Z'", representing UTC
- -Unspecified ""
- -DateTimeOffset "zzzzz" e.g -07:30:15
-
- "g*" the current era name A.D.
-
- ":" time separator : -- DEPRECATED - Insert separator directly into pattern (eg: "H.mm.ss")
- "/" date separator /-- DEPRECATED - Insert separator directly into pattern (eg: "M-dd-yyyy")
- "'" quoted string 'ABC' will insert ABC into the formatted string.
- '"' quoted string "ABC" will insert ABC into the formatted string.
- "%" used to quote a single pattern characters E.g.The format character "%y" is to print two digit year.
- "\" escaped character E.g. '\d' insert the character 'd' into the format string.
- other characters insert the character into the format string.
-
- Pre-defined format characters:
- (U) to indicate Universal time is used.
- (G) to indicate Gregorian calendar is used.
-
- Format Description Real format Example
- ========= ================================= ====================== =======================
- "d" short date culture-specific 10/31/1999
- "D" long data culture-specific Sunday, October 31, 1999
- "f" full date (long date + short time) culture-specific Sunday, October 31, 1999 2:00 AM
- "F" full date (long date + long time) culture-specific Sunday, October 31, 1999 2:00:00 AM
- "g" general date (short date + short time) culture-specific 10/31/1999 2:00 AM
- "G" general date (short date + long time) culture-specific 10/31/1999 2:00:00 AM
- "m"/"M" Month/Day date culture-specific October 31
-(G) "o"/"O" Round Trip XML "yyyy-MM-ddTHH:mm:ss.fffffffK" 1999-10-31 02:00:00.0000000Z
-(G) "r"/"R" RFC 1123 date, "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'" Sun, 31 Oct 1999 10:00:00 GMT
-(G) "s" Sortable format, based on ISO 8601. "yyyy-MM-dd'T'HH:mm:ss" 1999-10-31T02:00:00
- ('T' for local time)
- "t" short time culture-specific 2:00 AM
- "T" long time culture-specific 2:00:00 AM
-(G) "u" Universal time with sortable format, "yyyy'-'MM'-'dd HH':'mm':'ss'Z'" 1999-10-31 10:00:00Z
- based on ISO 8601.
-(U) "U" Universal time with full culture-specific Sunday, October 31, 1999 10:00:00 AM
- (long date + long time) format
- "y"/"Y" Year/Month day culture-specific October, 1999
-
- */
-
- //This class contains only static members and does not require the serializable attribute.
- internal static
- class DateTimeFormat {
-
- internal const int MaxSecondsFractionDigits = 7;
- internal static readonly TimeSpan NullOffset = TimeSpan.MinValue;
-
- internal static char[] allStandardFormats =
- {
- 'd', 'D', 'f', 'F', 'g', 'G',
- 'm', 'M', 'o', 'O', 'r', 'R',
- 's', 't', 'T', 'u', 'U', 'y', 'Y',
- };
-
- internal const String RoundtripFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK";
- internal const String RoundtripDateTimeUnfixed = "yyyy'-'MM'-'ddTHH':'mm':'ss zzz";
-
- private const int DEFAULT_ALL_DATETIMES_SIZE = 132;
-
- internal static readonly DateTimeFormatInfo InvariantFormatInfo = CultureInfo.InvariantCulture.DateTimeFormat;
- internal static readonly string[] InvariantAbbreviatedMonthNames = InvariantFormatInfo.AbbreviatedMonthNames;
- internal static readonly string[] InvariantAbbreviatedDayNames = InvariantFormatInfo.AbbreviatedDayNames;
- internal const string Gmt = "GMT";
-
- internal static String[] fixedNumberFormats = new String[] {
- "0",
- "00",
- "000",
- "0000",
- "00000",
- "000000",
- "0000000",
- };
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Format the positive integer value to a string and perfix with assigned
- // length of leading zero.
- //
- // Parameters:
- // value: The value to format
- // len: The maximum length for leading zero.
- // If the digits of the value is greater than len, no leading zero is added.
- //
- // Notes:
- // The function can format to Int32.MaxValue.
- //
- ////////////////////////////////////////////////////////////////////////////
- internal static void FormatDigits(StringBuilder outputBuffer, int value, int len) {
- Debug.Assert(value >= 0, "DateTimeFormat.FormatDigits(): value >= 0");
- FormatDigits(outputBuffer, value, len, false);
- }
-
- internal unsafe static void FormatDigits(StringBuilder outputBuffer, int value, int len, bool overrideLengthLimit) {
- Debug.Assert(value >= 0, "DateTimeFormat.FormatDigits(): value >= 0");
-
- // Limit the use of this function to be two-digits, so that we have the same behavior
- // as RTM bits.
- if (!overrideLengthLimit && len > 2)
- {
- len = 2;
- }
-
- char* buffer = stackalloc char[16];
- char* p = buffer + 16;
- int n = value;
- do {
- *--p = (char)(n % 10 + '0');
- n /= 10;
- } while ((n != 0)&&(p > buffer));
-
- int digits = (int) (buffer + 16 - p);
-
- //If the repeat count is greater than 0, we're trying
- //to emulate the "00" format, so we have to prepend
- //a zero if the string only has one character.
- while ((digits < len) && (p > buffer)) {
- *--p='0';
- digits++;
- }
- outputBuffer.Append(p, digits);
- }
-
- private static void HebrewFormatDigits(StringBuilder outputBuffer, int digits) {
- outputBuffer.Append(HebrewNumber.ToString(digits));
- }
-
- internal static int ParseRepeatPattern(String format, int pos, char patternChar)
- {
- int len = format.Length;
- int index = pos + 1;
- while ((index < len) && (format[index] == patternChar))
- {
- index++;
- }
- return (index - pos);
- }
-
- private static String FormatDayOfWeek(int dayOfWeek, int repeat, DateTimeFormatInfo dtfi)
- {
- Debug.Assert(dayOfWeek >= 0 && dayOfWeek <= 6, "dayOfWeek >= 0 && dayOfWeek <= 6");
- if (repeat == 3)
- {
- return (dtfi.GetAbbreviatedDayName((DayOfWeek)dayOfWeek));
- }
- // Call dtfi.GetDayName() here, instead of accessing DayNames property, because we don't
- // want a clone of DayNames, which will hurt perf.
- return (dtfi.GetDayName((DayOfWeek)dayOfWeek));
- }
-
- private static String FormatMonth(int month, int repeatCount, DateTimeFormatInfo dtfi)
- {
- Debug.Assert(month >=1 && month <= 12, "month >=1 && month <= 12");
- if (repeatCount == 3)
- {
- return (dtfi.GetAbbreviatedMonthName(month));
- }
- // Call GetMonthName() here, instead of accessing MonthNames property, because we don't
- // want a clone of MonthNames, which will hurt perf.
- return (dtfi.GetMonthName(month));
- }
-
- //
- // FormatHebrewMonthName
- //
- // Action: Return the Hebrew month name for the specified DateTime.
- // Returns: The month name string for the specified DateTime.
- // Arguments:
- // time the time to format
- // month The month is the value of HebrewCalendar.GetMonth(time).
- // repeat Return abbreviated month name if repeat=3, or full month name if repeat=4
- // dtfi The DateTimeFormatInfo which uses the Hebrew calendars as its calendar.
- // Exceptions: None.
- //
-
- /* Note:
- If DTFI is using Hebrew calendar, GetMonthName()/GetAbbreviatedMonthName() will return month names like this:
- 1 Hebrew 1st Month
- 2 Hebrew 2nd Month
- .. ...
- 6 Hebrew 6th Month
- 7 Hebrew 6th Month II (used only in a leap year)
- 8 Hebrew 7th Month
- 9 Hebrew 8th Month
- 10 Hebrew 9th Month
- 11 Hebrew 10th Month
- 12 Hebrew 11th Month
- 13 Hebrew 12th Month
-
- Therefore, if we are in a regular year, we have to increment the month name if moth is greater or eqaul to 7.
- */
- private static String FormatHebrewMonthName(DateTime time, int month, int repeatCount, DateTimeFormatInfo dtfi)
- {
- Debug.Assert(repeatCount != 3 || repeatCount != 4, "repeateCount should be 3 or 4");
- if (dtfi.Calendar.IsLeapYear(dtfi.Calendar.GetYear(time))) {
- // This month is in a leap year
- return (dtfi.internalGetMonthName(month, MonthNameStyles.LeapYear, (repeatCount == 3)));
- }
- // This is in a regular year.
- if (month >= 7) {
- month++;
- }
- if (repeatCount == 3) {
- return (dtfi.GetAbbreviatedMonthName(month));
- }
- return (dtfi.GetMonthName(month));
- }
-
- //
- // The pos should point to a quote character. This method will
- // append to the result StringBuilder the string encloed by the quote character.
- //
- internal static int ParseQuoteString(String format, int pos, StringBuilder result)
- {
- //
- // NOTE : pos will be the index of the quote character in the 'format' string.
- //
- int formatLen = format.Length;
- int beginPos = pos;
- char quoteChar = format[pos++]; // Get the character used to quote the following string.
-
- bool foundQuote = false;
- while (pos < formatLen)
- {
- char ch = format[pos++];
- if (ch == quoteChar)
- {
- foundQuote = true;
- break;
- }
- else if (ch == '\\') {
- // The following are used to support escaped character.
- // Escaped character is also supported in the quoted string.
- // Therefore, someone can use a format like "'minute:' mm\"" to display:
- // minute: 45"
- // because the second double quote is escaped.
- if (pos < formatLen) {
- result.Append(format[pos++]);
- } else {
- //
- // This means that '\' is at the end of the formatting string.
- //
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
- }
- } else {
- result.Append(ch);
- }
- }
-
- if (!foundQuote)
- {
- // Here we can't find the matching quote.
- throw new FormatException(
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("Format_BadQuote"), quoteChar));
- }
-
- //
- // Return the character count including the begin/end quote characters and enclosed string.
- //
- return (pos - beginPos);
- }
-
- //
- // Get the next character at the index of 'pos' in the 'format' string.
- // Return value of -1 means 'pos' is already at the end of the 'format' string.
- // Otherwise, return value is the int value of the next character.
- //
- internal static int ParseNextChar(String format, int pos)
- {
- if (pos >= format.Length - 1)
- {
- return (-1);
- }
- return ((int)format[pos+1]);
- }
-
- //
- // IsUseGenitiveForm
- //
- // Actions: Check the format to see if we should use genitive month in the formatting.
- // Starting at the position (index) in the (format) string, look back and look ahead to
- // see if there is "d" or "dd". In the case like "d MMMM" or "MMMM dd", we can use
- // genitive form. Genitive form is not used if there is more than two "d".
- // Arguments:
- // format The format string to be scanned.
- // index Where we should start the scanning. This is generally where "M" starts.
- // tokenLen The len of the current pattern character. This indicates how many "M" that we have.
- // patternToMatch The pattern that we want to search. This generally uses "d"
- //
- private static bool IsUseGenitiveForm(String format, int index, int tokenLen, char patternToMatch) {
- int i;
- int repeat = 0;
- //
- // Look back to see if we can find "d" or "ddd"
- //
-
- // Find first "d".
- for (i = index - 1; i >= 0 && format[i] != patternToMatch; i--) { /*Do nothing here */ };
-
- if (i >= 0) {
- // Find a "d", so look back to see how many "d" that we can find.
- while (--i >= 0 && format[i] == patternToMatch) {
- repeat++;
- }
- //
- // repeat == 0 means that we have one (patternToMatch)
- // repeat == 1 means that we have two (patternToMatch)
- //
- if (repeat <= 1) {
- return (true);
- }
- // Note that we can't just stop here. We may find "ddd" while looking back, and we have to look
- // ahead to see if there is "d" or "dd".
- }
-
- //
- // If we can't find "d" or "dd" by looking back, try look ahead.
- //
-
- // Find first "d"
- for (i = index + tokenLen; i < format.Length && format[i] != patternToMatch; i++) { /* Do nothing here */ };
-
- if (i < format.Length) {
- repeat = 0;
- // Find a "d", so contine the walk to see how may "d" that we can find.
- while (++i < format.Length && format[i] == patternToMatch) {
- repeat++;
- }
- //
- // repeat == 0 means that we have one (patternToMatch)
- // repeat == 1 means that we have two (patternToMatch)
- //
- if (repeat <= 1) {
- return (true);
- }
- }
- return (false);
- }
-
-
- //
- // FormatCustomized
- //
- // Actions: Format the DateTime instance using the specified format.
- //
- private static String FormatCustomized(DateTime dateTime, String format, DateTimeFormatInfo dtfi, TimeSpan offset) {
-
-
- Calendar cal = dtfi.Calendar;
- StringBuilder result = StringBuilderCache.Acquire();
- // This is a flag to indicate if we are format the dates using Hebrew calendar.
-
- bool isHebrewCalendar = (cal.ID == Calendar.CAL_HEBREW);
- // This is a flag to indicate if we are formating hour/minute/second only.
- bool bTimeOnly = true;
-
- int i = 0;
- int tokenLen, hour12;
-
- while (i < format.Length) {
- char ch = format[i];
- int nextChar;
- switch (ch) {
- case 'g':
- tokenLen = ParseRepeatPattern(format, i, ch);
- result.Append(dtfi.GetEraName(cal.GetEra(dateTime)));
- break;
- case 'h':
- tokenLen = ParseRepeatPattern(format, i, ch);
- hour12 = dateTime.Hour % 12;
- if (hour12 == 0)
- {
- hour12 = 12;
- }
- FormatDigits(result, hour12, tokenLen);
- break;
- case 'H':
- tokenLen = ParseRepeatPattern(format, i, ch);
- FormatDigits(result, dateTime.Hour, tokenLen);
- break;
- case 'm':
- tokenLen = ParseRepeatPattern(format, i, ch);
- FormatDigits(result, dateTime.Minute, tokenLen);
- break;
- case 's':
- tokenLen = ParseRepeatPattern(format, i, ch);
- FormatDigits(result, dateTime.Second, tokenLen);
- break;
- case 'f':
- case 'F':
- tokenLen = ParseRepeatPattern(format, i, ch);
- if (tokenLen <= MaxSecondsFractionDigits) {
- long fraction = (dateTime.Ticks % Calendar.TicksPerSecond);
- fraction = fraction / (long)Math.Pow(10, 7 - tokenLen);
- if (ch == 'f') {
- result.Append(((int)fraction).ToString(fixedNumberFormats[tokenLen - 1], CultureInfo.InvariantCulture));
- }
- else {
- int effectiveDigits = tokenLen;
- while (effectiveDigits > 0) {
- if (fraction % 10 == 0) {
- fraction = fraction / 10;
- effectiveDigits--;
- }
- else {
- break;
- }
- }
- if (effectiveDigits > 0) {
- result.Append(((int)fraction).ToString(fixedNumberFormats[effectiveDigits - 1], CultureInfo.InvariantCulture));
- }
- else {
- // No fraction to emit, so see if we should remove decimal also.
- if (result.Length > 0 && result[result.Length - 1] == '.') {
- result.Remove(result.Length - 1, 1);
- }
- }
- }
- } else {
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
- }
- break;
- case 't':
- tokenLen = ParseRepeatPattern(format, i, ch);
- if (tokenLen == 1)
- {
- if (dateTime.Hour < 12)
- {
- if (dtfi.AMDesignator.Length >= 1)
- {
- result.Append(dtfi.AMDesignator[0]);
- }
- }
- else
- {
- if (dtfi.PMDesignator.Length >= 1)
- {
- result.Append(dtfi.PMDesignator[0]);
- }
- }
-
- }
- else
- {
- result.Append((dateTime.Hour < 12 ? dtfi.AMDesignator : dtfi.PMDesignator));
- }
- break;
- case 'd':
- //
- // tokenLen == 1 : Day of month as digits with no leading zero.
- // tokenLen == 2 : Day of month as digits with leading zero for single-digit months.
- // tokenLen == 3 : Day of week as a three-leter abbreviation.
- // tokenLen >= 4 : Day of week as its full name.
- //
- tokenLen = ParseRepeatPattern(format, i, ch);
- if (tokenLen <= 2)
- {
- int day = cal.GetDayOfMonth(dateTime);
- if (isHebrewCalendar) {
- // For Hebrew calendar, we need to convert numbers to Hebrew text for yyyy, MM, and dd values.
- HebrewFormatDigits(result, day);
- } else {
- FormatDigits(result, day, tokenLen);
- }
- }
- else
- {
- int dayOfWeek = (int)cal.GetDayOfWeek(dateTime);
- result.Append(FormatDayOfWeek(dayOfWeek, tokenLen, dtfi));
- }
- bTimeOnly = false;
- break;
- case 'M':
- //
- // tokenLen == 1 : Month as digits with no leading zero.
- // tokenLen == 2 : Month as digits with leading zero for single-digit months.
- // tokenLen == 3 : Month as a three-letter abbreviation.
- // tokenLen >= 4 : Month as its full name.
- //
- tokenLen = ParseRepeatPattern(format, i, ch);
- int month = cal.GetMonth(dateTime);
- if (tokenLen <= 2)
- {
- if (isHebrewCalendar) {
- // For Hebrew calendar, we need to convert numbers to Hebrew text for yyyy, MM, and dd values.
- HebrewFormatDigits(result, month);
- } else {
- FormatDigits(result, month, tokenLen);
- }
- }
- else {
- if (isHebrewCalendar) {
- result.Append(FormatHebrewMonthName(dateTime, month, tokenLen, dtfi));
- } else {
- if ((dtfi.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != 0 && tokenLen >= 4) {
- result.Append(
- dtfi.internalGetMonthName(
- month,
- IsUseGenitiveForm(format, i, tokenLen, 'd')? MonthNameStyles.Genitive : MonthNameStyles.Regular,
- false));
- } else {
- result.Append(FormatMonth(month, tokenLen, dtfi));
- }
- }
- }
- bTimeOnly = false;
- break;
- case 'y':
- // Notes about OS behavior:
- // y: Always print (year % 100). No leading zero.
- // yy: Always print (year % 100) with leading zero.
- // yyy/yyyy/yyyyy/... : Print year value. No leading zero.
-
- int year = cal.GetYear(dateTime);
- tokenLen = ParseRepeatPattern(format, i, ch);
- if (dtfi.HasForceTwoDigitYears) {
- FormatDigits(result, year, tokenLen <= 2 ? tokenLen : 2);
- }
- else if (cal.ID == Calendar.CAL_HEBREW) {
- HebrewFormatDigits(result, year);
- }
- else {
- if (tokenLen <= 2) {
- FormatDigits(result, year % 100, tokenLen);
- }
- else {
- String fmtPattern = "D" + tokenLen.ToString();
- result.Append(year.ToString(fmtPattern, CultureInfo.InvariantCulture));
- }
- }
- bTimeOnly = false;
- break;
- case 'z':
- tokenLen = ParseRepeatPattern(format, i, ch);
- FormatCustomizedTimeZone(dateTime, offset, format, tokenLen, bTimeOnly, result);
- break;
- case 'K':
- tokenLen = 1;
- FormatCustomizedRoundripTimeZone(dateTime, offset, result);
- break;
- case ':':
- result.Append(dtfi.TimeSeparator);
- tokenLen = 1;
- break;
- case '/':
- result.Append(dtfi.DateSeparator);
- tokenLen = 1;
- break;
- case '\'':
- case '\"':
- tokenLen = ParseQuoteString(format, i, result);
- break;
- case '%':
- // Optional format character.
- // For example, format string "%d" will print day of month
- // without leading zero. Most of the cases, "%" can be ignored.
- nextChar = ParseNextChar(format, i);
- // nextChar will be -1 if we already reach the end of the format string.
- // Besides, we will not allow "%%" appear in the pattern.
- if (nextChar >= 0 && nextChar != (int)'%') {
- result.Append(FormatCustomized(dateTime, ((char)nextChar).ToString(), dtfi, offset));
- tokenLen = 2;
- }
- else
- {
- //
- // This means that '%' is at the end of the format string or
- // "%%" appears in the format string.
- //
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
- }
- break;
- case '\\':
- // Escaped character. Can be used to insert character into the format string.
- // For exmple, "\d" will insert the character 'd' into the string.
- //
- // NOTENOTE : we can remove this format character if we enforce the enforced quote
- // character rule.
- // That is, we ask everyone to use single quote or double quote to insert characters,
- // then we can remove this character.
- //
- nextChar = ParseNextChar(format, i);
- if (nextChar >= 0)
- {
- result.Append(((char)nextChar));
- tokenLen = 2;
- }
- else
- {
- //
- // This means that '\' is at the end of the formatting string.
- //
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
- }
- break;
- default:
- // NOTENOTE : we can remove this rule if we enforce the enforced quote
- // character rule.
- // That is, if we ask everyone to use single quote or double quote to insert characters,
- // then we can remove this default block.
- result.Append(ch);
- tokenLen = 1;
- break;
- }
- i += tokenLen;
- }
- return StringBuilderCache.GetStringAndRelease(result);
-
- }
-
-
- // output the 'z' famliy of formats, which output a the offset from UTC, e.g. "-07:30"
- private static void FormatCustomizedTimeZone(DateTime dateTime, TimeSpan offset, String format, Int32 tokenLen, Boolean timeOnly, StringBuilder result) {
- // See if the instance already has an offset
- Boolean dateTimeFormat = (offset == NullOffset);
- if (dateTimeFormat) {
- // No offset. The instance is a DateTime and the output should be the local time zone
-
- if (timeOnly && dateTime.Ticks < Calendar.TicksPerDay) {
- // For time only format and a time only input, the time offset on 0001/01/01 is less
- // accurate than the system's current offset because of daylight saving time.
- offset = TimeZoneInfo.GetLocalUtcOffset(DateTime.Now, TimeZoneInfoOptions.NoThrowOnInvalidTime);
- } else if (dateTime.Kind == DateTimeKind.Utc) {
- offset = TimeSpan.Zero;
- } else {
- offset = TimeZoneInfo.GetLocalUtcOffset(dateTime, TimeZoneInfoOptions.NoThrowOnInvalidTime);
- }
- }
- if (offset >= TimeSpan.Zero) {
- result.Append('+');
- }
- else {
- result.Append('-');
- // get a positive offset, so that you don't need a separate code path for the negative numbers.
- offset = offset.Negate();
- }
-
- if (tokenLen <= 1) {
- // 'z' format e.g "-7"
- result.AppendFormat(CultureInfo.InvariantCulture, "{0:0}", offset.Hours);
- }
- else {
- // 'zz' or longer format e.g "-07"
- result.AppendFormat(CultureInfo.InvariantCulture, "{0:00}", offset.Hours);
- if (tokenLen >= 3) {
- // 'zzz*' or longer format e.g "-07:30"
- result.AppendFormat(CultureInfo.InvariantCulture, ":{0:00}", offset.Minutes);
- }
- }
- }
-
- // output the 'K' format, which is for round-tripping the data
- private static void FormatCustomizedRoundripTimeZone(DateTime dateTime, TimeSpan offset, StringBuilder result) {
-
- // The objective of this format is to round trip the data in the type
- // For DateTime it should round-trip the Kind value and preserve the time zone.
- // DateTimeOffset instance, it should do so by using the internal time zone.
-
- if (offset == NullOffset) {
- // source is a date time, so behavior depends on the kind.
- switch (dateTime.Kind) {
- case DateTimeKind.Local:
- // This should output the local offset, e.g. "-07:30"
- offset = TimeZoneInfo.GetLocalUtcOffset(dateTime, TimeZoneInfoOptions.NoThrowOnInvalidTime);
- // fall through to shared time zone output code
- break;
- case DateTimeKind.Utc:
- // The 'Z' constant is a marker for a UTC date
- result.Append("Z");
- return;
- default:
- // If the kind is unspecified, we output nothing here
- return;
- }
- }
- if (offset >= TimeSpan.Zero) {
- result.Append('+');
- }
- else {
- result.Append('-');
- // get a positive offset, so that you don't need a separate code path for the negative numbers.
- offset = offset.Negate();
- }
-
- AppendNumber(result, offset.Hours, 2);
- result.Append(':');
- AppendNumber(result, offset.Minutes, 2);
- }
-
-
- internal static String GetRealFormat(String format, DateTimeFormatInfo dtfi)
- {
- String realFormat = null;
-
- switch (format[0])
- {
- case 'd': // Short Date
- realFormat = dtfi.ShortDatePattern;
- break;
- case 'D': // Long Date
- realFormat = dtfi.LongDatePattern;
- break;
- case 'f': // Full (long date + short time)
- realFormat = dtfi.LongDatePattern + " " + dtfi.ShortTimePattern;
- break;
- case 'F': // Full (long date + long time)
- realFormat = dtfi.FullDateTimePattern;
- break;
- case 'g': // General (short date + short time)
- realFormat = dtfi.GeneralShortTimePattern;
- break;
- case 'G': // General (short date + long time)
- realFormat = dtfi.GeneralLongTimePattern;
- break;
- case 'm':
- case 'M': // Month/Day Date
- realFormat = dtfi.MonthDayPattern;
- break;
- case 'o':
- case 'O':
- realFormat = RoundtripFormat;
- break;
- case 'r':
- case 'R': // RFC 1123 Standard
- realFormat = dtfi.RFC1123Pattern;
- break;
- case 's': // Sortable without Time Zone Info
- realFormat = dtfi.SortableDateTimePattern;
- break;
- case 't': // Short Time
- realFormat = dtfi.ShortTimePattern;
- break;
- case 'T': // Long Time
- realFormat = dtfi.LongTimePattern;
- break;
- case 'u': // Universal with Sortable format
- realFormat = dtfi.UniversalSortableDateTimePattern;
- break;
- case 'U': // Universal with Full (long date + long time) format
- realFormat = dtfi.FullDateTimePattern;
- break;
- case 'y':
- case 'Y': // Year/Month Date
- realFormat = dtfi.YearMonthPattern;
- break;
- default:
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
- }
- return (realFormat);
- }
-
-
- // Expand a pre-defined format string (like "D" for long date) to the real format that
- // we are going to use in the date time parsing.
- // This method also convert the dateTime if necessary (e.g. when the format is in Universal time),
- // and change dtfi if necessary (e.g. when the format should use invariant culture).
- //
- private static String ExpandPredefinedFormat(String format, ref DateTime dateTime, ref DateTimeFormatInfo dtfi, ref TimeSpan offset) {
- switch (format[0]) {
- case 'o':
- case 'O': // Round trip format
- dtfi = DateTimeFormatInfo.InvariantInfo;
- break;
- case 'r':
- case 'R': // RFC 1123 Standard
- if (offset != NullOffset) {
- // Convert to UTC invariants mean this will be in range
- dateTime = dateTime - offset;
- }
- else if (dateTime.Kind == DateTimeKind.Local) {
- InvalidFormatForLocal(format, dateTime);
- }
- dtfi = DateTimeFormatInfo.InvariantInfo;
- break;
- case 's': // Sortable without Time Zone Info
- dtfi = DateTimeFormatInfo.InvariantInfo;
- break;
- case 'u': // Universal time in sortable format.
- if (offset != NullOffset) {
- // Convert to UTC invariants mean this will be in range
- dateTime = dateTime - offset;
- }
- else if (dateTime.Kind == DateTimeKind.Local) {
-
- InvalidFormatForLocal(format, dateTime);
- }
- dtfi = DateTimeFormatInfo.InvariantInfo;
- break;
- case 'U': // Universal time in culture dependent format.
- if (offset != NullOffset) {
- // This format is not supported by DateTimeOffset
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
- }
- // Universal time is always in Greogrian calendar.
- //
- // Change the Calendar to be Gregorian Calendar.
- //
- dtfi = (DateTimeFormatInfo)dtfi.Clone();
- if (dtfi.Calendar.GetType() != typeof(GregorianCalendar)) {
- dtfi.Calendar = GregorianCalendar.GetDefaultInstance();
- }
- dateTime = dateTime.ToUniversalTime();
- break;
- }
- format = GetRealFormat(format, dtfi);
- return (format);
- }
-
- internal static String Format(DateTime dateTime, String format, DateTimeFormatInfo dtfi) {
- return Format(dateTime, format, dtfi, NullOffset);
- }
-
-
- internal static String Format(DateTime dateTime, String format, DateTimeFormatInfo dtfi, TimeSpan offset)
- {
- Contract.Requires(dtfi != null);
- if (format==null || format.Length==0) {
- Boolean timeOnlySpecialCase = false;
- if (dateTime.Ticks < Calendar.TicksPerDay) {
- // If the time is less than 1 day, consider it as time of day.
- // Just print out the short time format.
- //
- // This is a workaround for VB, since they use ticks less then one day to be
- // time of day. In cultures which use calendar other than Gregorian calendar, these
- // alternative calendar may not support ticks less than a day.
- // For example, Japanese calendar only supports date after 1868/9/8.
- // This will pose a problem when people in VB get the time of day, and use it
- // to call ToString(), which will use the general format (short date + long time).
- // Since Japanese calendar does not support Gregorian year 0001, an exception will be
- // thrown when we try to get the Japanese year for Gregorian year 0001.
- // Therefore, the workaround allows them to call ToString() for time of day from a DateTime by
- // formatting as ISO 8601 format.
- switch (dtfi.Calendar.ID) {
- case Calendar.CAL_JAPAN:
- case Calendar.CAL_TAIWAN:
- case Calendar.CAL_HIJRI:
- case Calendar.CAL_HEBREW:
- case Calendar.CAL_JULIAN:
- case Calendar.CAL_UMALQURA:
- case Calendar.CAL_PERSIAN:
- timeOnlySpecialCase = true;
- dtfi = DateTimeFormatInfo.InvariantInfo;
- break;
- }
- }
- if (offset == NullOffset) {
- // Default DateTime.ToString case.
- if (timeOnlySpecialCase) {
- format = "s";
- }
- else {
- format = "G";
- }
- }
- else {
- // Default DateTimeOffset.ToString case.
- if (timeOnlySpecialCase) {
- format = RoundtripDateTimeUnfixed;
- }
- else {
- format = dtfi.DateTimeOffsetPattern;
- }
-
- }
-
- }
-
- if (format.Length == 1) {
- switch (format[0])
- {
- case 'O':
- case 'o':
- return FastFormatRoundtrip(dateTime, offset);
- case 'R':
- case 'r':
- return FastFormatRfc1123(dateTime, offset, dtfi);
- }
-
- format = ExpandPredefinedFormat(format, ref dateTime, ref dtfi, ref offset);
- }
-
- return (FormatCustomized(dateTime, format, dtfi, offset));
- }
-
- internal static string FastFormatRfc1123(DateTime dateTime, TimeSpan offset, DateTimeFormatInfo dtfi)
- {
- // ddd, dd MMM yyyy HH:mm:ss GMT
- const int Rfc1123FormatLength = 29;
- StringBuilder result = StringBuilderCache.Acquire(Rfc1123FormatLength);
-
- if (offset != NullOffset)
- {
- // Convert to UTC invariants
- dateTime = dateTime - offset;
- }
-
- result.Append(InvariantAbbreviatedDayNames[(int)dateTime.DayOfWeek]);
- result.Append(',');
- result.Append(' ');
- AppendNumber(result, dateTime.Day, 2);
- result.Append(' ');
- result.Append(InvariantAbbreviatedMonthNames[dateTime.Month - 1]);
- result.Append(' ');
- AppendNumber(result, dateTime.Year, 4);
- result.Append(' ');
- AppendHHmmssTimeOfDay(result, dateTime);
- result.Append(' ');
- result.Append(Gmt);
-
- return StringBuilderCache.GetStringAndRelease(result);
- }
-
- internal static string FastFormatRoundtrip(DateTime dateTime, TimeSpan offset)
- {
- // yyyy-MM-ddTHH:mm:ss.fffffffK
- const int roundTripFormatLength = 28;
- StringBuilder result = StringBuilderCache.Acquire(roundTripFormatLength);
-
- AppendNumber(result, dateTime.Year, 4);
- result.Append('-');
- AppendNumber(result, dateTime.Month, 2);
- result.Append('-');
- AppendNumber(result, dateTime.Day, 2);
- result.Append('T');
- AppendHHmmssTimeOfDay(result, dateTime);
- result.Append('.');
-
- long fraction = dateTime.Ticks % TimeSpan.TicksPerSecond;
- AppendNumber(result, fraction, 7);
-
- FormatCustomizedRoundripTimeZone(dateTime, offset, result);
-
- return StringBuilderCache.GetStringAndRelease(result);
- }
-
- private static void AppendHHmmssTimeOfDay(StringBuilder result, DateTime dateTime)
- {
- // HH:mm:ss
- AppendNumber(result, dateTime.Hour, 2);
- result.Append(':');
- AppendNumber(result, dateTime.Minute, 2);
- result.Append(':');
- AppendNumber(result, dateTime.Second, 2);
- }
-
- internal static void AppendNumber(StringBuilder builder, long val, int digits)
- {
- for (int i = 0; i < digits; i++)
- {
- builder.Append('0');
- }
-
- int index = 1;
- while (val > 0 && index <= digits)
- {
- builder[builder.Length - index] = (char)('0' + (val % 10));
- val = val / 10;
- index++;
- }
-
- Debug.Assert(val == 0, "DateTimeFormat.AppendNumber(): digits less than size of val");
- }
-
- internal static String[] GetAllDateTimes(DateTime dateTime, char format, DateTimeFormatInfo dtfi)
- {
- Contract.Requires(dtfi != null);
- String [] allFormats = null;
- String [] results = null;
-
- switch (format)
- {
- case 'd':
- case 'D':
- case 'f':
- case 'F':
- case 'g':
- case 'G':
- case 'm':
- case 'M':
- case 't':
- case 'T':
- case 'y':
- case 'Y':
- allFormats = dtfi.GetAllDateTimePatterns(format);
- results = new String[allFormats.Length];
- for (int i = 0; i < allFormats.Length; i++)
- {
- results[i] = Format(dateTime, allFormats[i], dtfi);
- }
- break;
- case 'U':
- DateTime universalTime = dateTime.ToUniversalTime();
- allFormats = dtfi.GetAllDateTimePatterns(format);
- results = new String[allFormats.Length];
- for (int i = 0; i < allFormats.Length; i++)
- {
- results[i] = Format(universalTime, allFormats[i], dtfi);
- }
- break;
- //
- // The following ones are special cases because these patterns are read-only in
- // DateTimeFormatInfo.
- //
- case 'r':
- case 'R':
- case 'o':
- case 'O':
- case 's':
- case 'u':
- results = new String[] {Format(dateTime, new String(format, 1), dtfi)};
- break;
- default:
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
-
- }
- return (results);
- }
-
- internal static String[] GetAllDateTimes(DateTime dateTime, DateTimeFormatInfo dtfi)
- {
- List<String> results = new List<String>(DEFAULT_ALL_DATETIMES_SIZE);
-
- for (int i = 0; i < allStandardFormats.Length; i++)
- {
- String[] strings = GetAllDateTimes(dateTime, allStandardFormats[i], dtfi);
- for (int j = 0; j < strings.Length; j++)
- {
- results.Add(strings[j]);
- }
- }
- String[] value = new String[results.Count];
- results.CopyTo(0, value, 0, results.Count);
- return (value);
- }
-
- // This is a placeholder for an MDA to detect when the user is using a
- // local DateTime with a format that will be interpreted as UTC.
- internal static void InvalidFormatForLocal(String format, DateTime dateTime) {
- }
-
-
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/DateTimeFormatInfo.cs b/src/mscorlib/src/System/Globalization/DateTimeFormatInfo.cs
deleted file mode 100644
index b2374ef0b2..0000000000
--- a/src/mscorlib/src/System/Globalization/DateTimeFormatInfo.cs
+++ /dev/null
@@ -1,2858 +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.
-
-
-namespace System.Globalization {
- using System;
- using System.Security;
- using System.Threading;
- using System.Collections;
- using System.Collections.Generic;
- using System.Runtime.Serialization;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
- using System.Text;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- //
- // Flags used to indicate different styles of month names.
- // This is an internal flag used by internalGetMonthName().
- // Use flag here in case that we need to provide a combination of these styles
- // (such as month name of a leap year in genitive form. Not likely for now,
- // but would like to keep the option open).
- //
-
- [Flags]
- internal enum MonthNameStyles {
- Regular = 0x00000000,
- Genitive = 0x00000001,
- LeapYear = 0x00000002,
- }
-
- //
- // Flags used to indicate special rule used in parsing/formatting
- // for a specific DateTimeFormatInfo instance.
- // This is an internal flag.
- //
- // This flag is different from MonthNameStyles because this flag
- // can be expanded to accomodate parsing behaviors like CJK month names
- // or alternative month names, etc.
-
- [Flags]
- internal enum DateTimeFormatFlags {
- None = 0x00000000,
- UseGenitiveMonth = 0x00000001,
- UseLeapYearMonth = 0x00000002,
- UseSpacesInMonthNames = 0x00000004, // Has spaces or non-breaking space in the month names.
- UseHebrewRule = 0x00000008, // Format/Parse using the Hebrew calendar rule.
- UseSpacesInDayNames = 0x00000010, // Has spaces or non-breaking space in the day names.
- UseDigitPrefixInTokens = 0x00000020, // Has token starting with numbers.
-
- NotInitialized = -1,
- }
-
-
- [Serializable]
- public sealed class DateTimeFormatInfo : ICloneable, IFormatProvider
- {
- //
- // Note, some fields are derived so don't really need to be serialized, but we can't mark as
- // optional because Whidbey was expecting them. Post-Arrowhead we could fix that
- // once Whidbey serialization is no longer necessary.
- //
-
- // cache for the invariant culture.
- // invariantInfo is constant irrespective of your current culture.
- private static volatile DateTimeFormatInfo invariantInfo;
-
- // an index which points to a record in Culture Data Table.
- [NonSerialized]private CultureData m_cultureData;
-
- // The culture name used to create this DTFI.
- [OptionalField(VersionAdded = 2)]
- internal String m_name = null;
-
- // The language name of the culture used to create this DTFI.
- [NonSerialized]private String m_langName = null;
-
- // CompareInfo usually used by the parser.
- [NonSerialized]private CompareInfo m_compareInfo = null;
-
- // Culture matches current DTFI. mainly used for string comparisons during parsing.
- [NonSerialized]private CultureInfo m_cultureInfo = null;
-
- //
- // Caches for various properties.
- //
-
- internal String amDesignator = null;
- internal String pmDesignator = null;
- [OptionalField(VersionAdded = 1)]
- internal String dateSeparator = null; // derived from short date (whidbey expects, arrowhead doesn't)
- [OptionalField(VersionAdded = 1)]
- internal String generalShortTimePattern = null; // short date + short time (whidbey expects, arrowhead doesn't)
- [OptionalField(VersionAdded = 1)]
- internal String generalLongTimePattern = null; // short date + long time (whidbey expects, arrowhead doesn't)
- [OptionalField(VersionAdded = 1)]
- internal String timeSeparator = null; // derived from long time (whidbey expects, arrowhead doesn't)
- internal String monthDayPattern = null;
- [OptionalField(VersionAdded = 2)] // added in .NET Framework Release {2.0SP1/3.0SP1/3.5RTM}
- internal String dateTimeOffsetPattern = null;
-
- //
- // The following are constant values.
- //
- internal const String rfc1123Pattern = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'";
-
- // The sortable pattern is based on ISO 8601.
- internal const String sortableDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss";
- internal const String universalSortableDateTimePattern = "yyyy'-'MM'-'dd HH':'mm':'ss'Z'";
-
- //
- // The following are affected by calendar settings.
- //
- internal Calendar calendar = null;
-
- internal int firstDayOfWeek = -1;
- internal int calendarWeekRule = -1;
-
- [OptionalField(VersionAdded = 1)]
- internal String fullDateTimePattern = null; // long date + long time (whidbey expects, arrowhead doesn't)
-
- internal String[] abbreviatedDayNames = null;
-
- [OptionalField(VersionAdded = 2)]
- internal String[] m_superShortDayNames = null;
-
- internal String[] dayNames = null;
- internal String[] abbreviatedMonthNames = null;
- internal String[] monthNames = null;
- // Cache the genitive month names that we retrieve from the data table.
- [OptionalField(VersionAdded = 2)]
- internal String[] genitiveMonthNames = null;
-
- // Cache the abbreviated genitive month names that we retrieve from the data table.
- [OptionalField(VersionAdded = 2)]
- internal String[] m_genitiveAbbreviatedMonthNames = null;
-
- // Cache the month names of a leap year that we retrieve from the data table.
- [OptionalField(VersionAdded = 2)]
- internal String[] leapYearMonthNames = null;
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
-
- // The "default" Date/time patterns
- internal String longDatePattern = null;
- internal String shortDatePattern = null;
- internal String yearMonthPattern = null;
- internal String longTimePattern = null;
- internal String shortTimePattern = null;
-
- // These are Whidbey-serialization compatable arrays (eg: default not included)
- // "all" is a bit of a misnomer since the "default" pattern stored above isn't
- // necessarily a member of the list
- [OptionalField(VersionAdded = 3)]
- private String[] allYearMonthPatterns = null; // This was wasn't serialized in Whidbey
- internal String[] allShortDatePatterns = null;
- internal String[] allLongDatePatterns = null;
- internal String[] allShortTimePatterns = null;
- internal String[] allLongTimePatterns = null;
-
- // Cache the era names for this DateTimeFormatInfo instance.
- internal String[] m_eraNames = null;
- internal String[] m_abbrevEraNames = null;
- internal String[] m_abbrevEnglishEraNames = null;
-
- internal int[] optionalCalendars = null;
-
- private const int DEFAULT_ALL_DATETIMES_SIZE = 132;
-
- // CultureInfo updates this
- internal bool m_isReadOnly=false;
-
- // This flag gives hints about if formatting/parsing should perform special code path for things like
- // genitive form or leap year month names.
- [OptionalField(VersionAdded = 2)]
- internal DateTimeFormatFlags formatFlags = DateTimeFormatFlags.NotInitialized;
-
- private String CultureName
- {
- get
- {
- if (m_name == null)
- {
- m_name = this.m_cultureData.CultureName;
- }
- return (m_name);
- }
- }
-
- private CultureInfo Culture
- {
- get
- {
- if (m_cultureInfo == null)
- {
- m_cultureInfo = CultureInfo.GetCultureInfo(this.CultureName);
- }
- return m_cultureInfo;
- }
- }
-
- private String LanguageName
- {
- get
- {
- if (m_langName == null)
- {
- m_langName = this.m_cultureData.SISO639LANGNAME;
- }
- return (m_langName);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Create an array of string which contains the abbreviated day names.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- private String[] internalGetAbbreviatedDayOfWeekNames()
- {
- if (this.abbreviatedDayNames == null)
- {
- // Get the abbreviated day names for our current calendar
- this.abbreviatedDayNames = this.m_cultureData.AbbreviatedDayNames(Calendar.ID);
- Debug.Assert(this.abbreviatedDayNames.Length == 7, "[DateTimeFormatInfo.GetAbbreviatedDayOfWeekNames] Expected 7 day names in a week");
- }
- return (this.abbreviatedDayNames);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Action: Returns the string array of the one-letter day of week names.
- // Returns:
- // an array of one-letter day of week names
- // Arguments:
- // None
- // Exceptions:
- // None
- //
- ////////////////////////////////////////////////////////////////////////
-
- private String[] internalGetSuperShortDayNames()
- {
- if (this.m_superShortDayNames == null)
- {
- // Get the super short day names for our current calendar
- this.m_superShortDayNames = this.m_cultureData.SuperShortDayNames(Calendar.ID);
- Debug.Assert(this.m_superShortDayNames.Length == 7, "[DateTimeFormatInfo.internalGetSuperShortDayNames] Expected 7 day names in a week");
- }
- return (this.m_superShortDayNames);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Create an array of string which contains the day names.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- private String[] internalGetDayOfWeekNames()
- {
- if (this.dayNames == null)
- {
- // Get the day names for our current calendar
- this.dayNames = this.m_cultureData.DayNames(Calendar.ID);
- Debug.Assert(this.dayNames.Length == 7, "[DateTimeFormatInfo.GetDayOfWeekNames] Expected 7 day names in a week");
- }
- return (this.dayNames);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Create an array of string which contains the abbreviated month names.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- private String[] internalGetAbbreviatedMonthNames()
- {
- if (this.abbreviatedMonthNames == null)
- {
- // Get the month names for our current calendar
- this.abbreviatedMonthNames = this.m_cultureData.AbbreviatedMonthNames(Calendar.ID);
- Debug.Assert(this.abbreviatedMonthNames.Length == 12 || this.abbreviatedMonthNames.Length == 13,
- "[DateTimeFormatInfo.GetAbbreviatedMonthNames] Expected 12 or 13 month names in a year");
- }
- return (this.abbreviatedMonthNames);
- }
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Create an array of string which contains the month names.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- private String[] internalGetMonthNames()
- {
- if (this.monthNames == null)
- {
- // Get the month names for our current calendar
- this.monthNames = this.m_cultureData.MonthNames(Calendar.ID);
- Debug.Assert(this.monthNames.Length == 12 || this.monthNames.Length == 13,
- "[DateTimeFormatInfo.GetMonthNames] Expected 12 or 13 month names in a year");
- }
-
- return (this.monthNames);
- }
-
-
- //
- // Invariant DateTimeFormatInfo doesn't have user-overriden values
- // Default calendar is gregorian
- public DateTimeFormatInfo()
- : this(CultureInfo.InvariantCulture.m_cultureData,
- GregorianCalendar.GetDefaultInstance())
- {
- }
-
- internal DateTimeFormatInfo(CultureData cultureData, Calendar cal)
- {
- Contract.Requires(cultureData != null);
- Contract.Requires(cal != null);
-
- // Remember our culture
- this.m_cultureData = cultureData;
-
- // m_isDefaultCalendar is set in the setter of Calendar below.
- this.Calendar = cal;
- }
- private void InitializeOverridableProperties(CultureData cultureData, int calendarID)
- {
- // Silverlight 2.0 never took a snapshot of the user's overridable properties
- // This has a substantial performance impact so skip when CoreCLR
- Contract.Requires(cultureData != null);
- Debug.Assert(calendarID > 0, "[DateTimeFormatInfo.Populate] Expected Calendar.ID > 0");
-
- if (this.firstDayOfWeek == -1) { this.firstDayOfWeek = cultureData.IFIRSTDAYOFWEEK; }
- if (this.calendarWeekRule == -1) { this.calendarWeekRule = cultureData.IFIRSTWEEKOFYEAR; }
-
- if (this.amDesignator == null) { this.amDesignator = cultureData.SAM1159; }
- if (this.pmDesignator == null) { this.pmDesignator = cultureData.SPM2359; }
- if (this.timeSeparator == null) { this.timeSeparator = cultureData.TimeSeparator; }
- if (this.dateSeparator == null) { this.dateSeparator = cultureData.DateSeparator(calendarID); }
-
- this.allLongTimePatterns = this.m_cultureData.LongTimes;
- Debug.Assert(this.allLongTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long time patterns");
-
- this.allShortTimePatterns = this.m_cultureData.ShortTimes;
- Debug.Assert(this.allShortTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short time patterns");
-
- this.allLongDatePatterns = cultureData.LongDates(calendarID);
- Debug.Assert(this.allLongDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long date patterns");
-
- this.allShortDatePatterns = cultureData.ShortDates(calendarID);
- Debug.Assert(this.allShortDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short date patterns");
-
- this.allYearMonthPatterns = cultureData.YearMonths(calendarID);
- Debug.Assert(this.allYearMonthPatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some year month patterns");
- }
-
-#region Serialization
- // The following fields are defined to keep the serialization compatibility with .NET V1.0/V1.1.
- [OptionalField(VersionAdded = 1)]
- private int CultureID;
- [OptionalField(VersionAdded = 1)]
- private bool m_useUserOverride;
- [OptionalField(VersionAdded = 1)]
- private bool bUseCalendarInfo;
- [OptionalField(VersionAdded = 1)]
- private int nDataItem;
- [OptionalField(VersionAdded = 2)]
- internal bool m_isDefaultCalendar; // NEVER USED, DO NOT USE THIS! (Serialized in Whidbey)
-
- // This was synthesized by Whidbey so we knew what words might appear in the middle of a date string
- // Now we always synthesize so its not helpful
- [OptionalField(VersionAdded = 1)]
- internal String[] m_dateWords = null; // calculated, no need to serialze (whidbey expects, arrowhead doesn't)
-
- [OnDeserialized]
- private void OnDeserialized(StreamingContext ctx)
- {
- if (this.m_name != null)
- {
- m_cultureData = CultureData.GetCultureData(m_name, m_useUserOverride);
-
- if (this.m_cultureData == null)
- throw new CultureNotFoundException(
- nameof(m_name), m_name, Environment.GetResourceString("Argument_CultureNotSupported"));
- }
- // Note: This is for Everett compatibility
-
-#if FEATURE_USE_LCID
- else
- m_cultureData = CultureData.GetCultureData(CultureID, m_useUserOverride);
-#endif
- if (calendar == null)
- {
- calendar = (Calendar) GregorianCalendar.GetDefaultInstance().Clone();
- calendar.SetReadOnlyState(m_isReadOnly);
- }
- InitializeOverridableProperties(m_cultureData, calendar.ID);
-
- //
- // turn off read only state till we finish initializing all fields and then store read only state after we are done.
- //
- bool isReadOnly = m_isReadOnly;
- m_isReadOnly = false;
-
- // If we deserialized defaults ala Whidbey, make sure they're still defaults
- // Whidbey's arrays could get a bit mixed up.
- if (longDatePattern != null) this.LongDatePattern = longDatePattern;
- if (shortDatePattern != null) this.ShortDatePattern = shortDatePattern;
- if (yearMonthPattern != null) this.YearMonthPattern = yearMonthPattern;
- if (longTimePattern != null) this.LongTimePattern = longTimePattern;
- if (shortTimePattern != null) this.ShortTimePattern = shortTimePattern;
-
- m_isReadOnly = isReadOnly;
- }
-
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx)
- {
-#if FEATURE_USE_LCID
- CultureID = this.m_cultureData.ILANGUAGE; // Used for serialization compatibility with Whidbey which didn't always serialize the name
-#endif
- m_useUserOverride = this.m_cultureData.UseUserOverride;
-
- // make sure the m_name is initialized.
- m_name = this.CultureName;
-
- // Important to initialize these fields otherwise we may run into exception when deserializing on Whidbey
- // because Whidbey try to initialize some of these fields using calendar data which could be null values
- // and then we get exceptions. So we call the accessors to force the caches to get loaded.
- Object o;
- o = this.LongTimePattern;
- o = this.LongDatePattern;
- o = this.ShortTimePattern;
- o = this.ShortDatePattern;
- o = this.YearMonthPattern;
- o = this.AllLongTimePatterns;
- o = this.AllLongDatePatterns;
- o = this.AllShortTimePatterns;
- o = this.AllShortDatePatterns;
- o = this.AllYearMonthPatterns;
- }
-#endregion Serialization
-
- // Returns a default DateTimeFormatInfo that will be universally
- // supported and constant irrespective of the current culture.
- // Used by FromString methods.
- //
-
- public static DateTimeFormatInfo InvariantInfo {
- get {
- Contract.Ensures(Contract.Result<DateTimeFormatInfo>() != null);
- if (invariantInfo == null)
- {
- DateTimeFormatInfo info = new DateTimeFormatInfo();
- info.Calendar.SetReadOnlyState(true);
- info.m_isReadOnly = true;
- invariantInfo = info;
- }
- return (invariantInfo);
- }
- }
-
- // Returns the current culture's DateTimeFormatInfo. Used by Parse methods.
- //
-
- public static DateTimeFormatInfo CurrentInfo {
- get {
- Contract.Ensures(Contract.Result<DateTimeFormatInfo>() != null);
- System.Globalization.CultureInfo culture = System.Threading.Thread.CurrentThread.CurrentCulture;
- if (!culture.m_isInherited) {
- DateTimeFormatInfo info = culture.dateTimeInfo;
- if (info != null) {
- return info;
- }
- }
- return (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo));
- }
- }
-
-
- public static DateTimeFormatInfo GetInstance(IFormatProvider provider) {
- // Fast case for a regular CultureInfo
- DateTimeFormatInfo info;
- CultureInfo cultureProvider = provider as CultureInfo;
- if (cultureProvider != null && !cultureProvider.m_isInherited)
- {
- return cultureProvider.DateTimeFormat;
- }
- // Fast case for a DTFI;
- info = provider as DateTimeFormatInfo;
- if (info != null) {
- return info;
- }
- // Wasn't cultureInfo or DTFI, do it the slower way
- if (provider != null) {
- info = provider.GetFormat(typeof(DateTimeFormatInfo)) as DateTimeFormatInfo;
- if (info != null) {
- return info;
- }
- }
- // Couldn't get anything, just use currentInfo as fallback
- return CurrentInfo;
- }
-
-
- public Object GetFormat(Type formatType)
- {
- return (formatType == typeof(DateTimeFormatInfo)? this: null);
- }
-
-
- public Object Clone()
- {
- DateTimeFormatInfo n = (DateTimeFormatInfo)MemberwiseClone();
- // We can use the data member calendar in the setter, instead of the property Calendar,
- // since the cloned copy should have the same state as the original copy.
- n.calendar = (Calendar) this.Calendar.Clone();
- n.m_isReadOnly = false;
- return n;
- }
-
-
- public String AMDesignator
- {
- get
- {
- if (this.amDesignator == null)
- {
- this.amDesignator = this.m_cultureData.SAM1159;
- }
-
- Debug.Assert(this.amDesignator != null, "DateTimeFormatInfo.AMDesignator, amDesignator != null");
- return (this.amDesignator);
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_String"));
- }
- Contract.EndContractBlock();
- ClearTokenHashTable();
- amDesignator = value;
- }
- }
-
-
- public Calendar Calendar {
- get {
- Contract.Ensures(Contract.Result<Calendar>() != null);
-
- Debug.Assert(this.calendar != null, "DateTimeFormatInfo.Calendar: calendar != null");
- return (this.calendar);
- }
-
- set {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null) {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_Obj"));
- }
- Contract.EndContractBlock();
- if (value == calendar) {
- return;
- }
-
- for (int i = 0; i < this.OptionalCalendars.Length; i++)
- {
- if (this.OptionalCalendars[i] == value.ID)
- {
- // We can use this one, so do so.
-
- // Clean related properties if we already had a calendar set
- if (calendar != null)
- {
- // clean related properties which are affected by the calendar setting,
- // so that they will be refreshed when they are accessed next time.
- //
-
- // These properites are in the order as appearing in calendar.xml.
- m_eraNames = null;
- m_abbrevEraNames = null;
- m_abbrevEnglishEraNames = null;
-
- monthDayPattern = null;
-
- dayNames = null;
- abbreviatedDayNames = null;
- m_superShortDayNames = null;
- monthNames = null;
- abbreviatedMonthNames = null;
- genitiveMonthNames = null;
- m_genitiveAbbreviatedMonthNames = null;
- leapYearMonthNames = null;
- formatFlags = DateTimeFormatFlags.NotInitialized;
-
- allShortDatePatterns = null;
- allLongDatePatterns = null;
- allYearMonthPatterns = null;
- dateTimeOffsetPattern = null;
-
- // The defaults need reset as well:
- longDatePattern = null;
- shortDatePattern = null;
- yearMonthPattern = null;
-
- // These properies are not in the OS data, but they are dependent on the values like shortDatePattern.
- fullDateTimePattern = null; // Long date + long time
- generalShortTimePattern = null; // short date + short time
- generalLongTimePattern = null; // short date + long time
-
- // Derived item that changes
- dateSeparator = null;
-
- // We don't need to do these because they are not changed by changing calendar
- // amDesignator
- // pmDesignator
- // timeSeparator
- // longTimePattern
- // firstDayOfWeek
- // calendarWeekRule
-
- // We don't need to clear these because they're only used for whidbey compat serialization
- // the only values we use are the all...Patterns[0]
- // longDatePattern
- // shortDatePattern
- // yearMonthPattern
-
- // remember to reload tokens
- ClearTokenHashTable();
- }
-
- // Remember the new calendar
- calendar = value;
- InitializeOverridableProperties(m_cultureData, calendar.ID);
-
- // We succeeded, return
- return;
- }
- }
-
- // The assigned calendar is not a valid calendar for this culture, throw
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("Argument_InvalidCalendar"));
- }
- }
-
- private int[] OptionalCalendars {
- get {
- if (this.optionalCalendars == null) {
- this.optionalCalendars = this.m_cultureData.CalendarIds;
- }
- return (this.optionalCalendars);
- }
- }
-
- /*=================================GetEra==========================
- **Action: Get the era value by parsing the name of the era.
- **Returns: The era value for the specified era name.
- ** -1 if the name of the era is not valid or not supported.
- **Arguments: eraName the name of the era.
- **Exceptions: None.
- ============================================================================*/
-
-
- public int GetEra(String eraName) {
- if (eraName == null) {
- throw new ArgumentNullException(nameof(eraName),
- Environment.GetResourceString("ArgumentNull_String"));
- }
- Contract.EndContractBlock();
-
- // For Geo-Political reasons, the Era Name and Abbreviated Era Name
- // for Taiwan Calendar on non-Taiwan SKU returns empty string (which
- // would be matched below) but we don't want the empty string to give
- // us an Era number
- // confer 85900 DTFI.GetEra("") should fail on all cultures
- if (eraName.Length == 0) {
- return (-1);
- }
-
- // The following is based on the assumption that the era value is starting from 1, and has a
- // serial values.
- // If that ever changes, the code has to be changed.
-
- // The calls to String.Compare should use the current culture for the string comparisons, but the
- // invariant culture when comparing against the english names.
- for (int i = 0; i < EraNames.Length; i++) {
- // Compare the era name in a case-insensitive way for the appropriate culture.
- if (m_eraNames[i].Length > 0) {
- if (String.Compare(eraName, m_eraNames[i], this.Culture, CompareOptions.IgnoreCase)==0) {
- return (i+1);
- }
- }
- }
- for (int i = 0; i < AbbreviatedEraNames.Length; i++) {
- // Compare the abbreviated era name in a case-insensitive way for the appropriate culture.
- if (String.Compare(eraName, m_abbrevEraNames[i], this.Culture, CompareOptions.IgnoreCase)==0) {
- return (i+1);
- }
- }
- for (int i = 0; i < AbbreviatedEnglishEraNames.Length; i++) {
- // this comparison should use the InvariantCulture. The English name could have linguistically
- // interesting characters.
- if (String.Compare(eraName, m_abbrevEnglishEraNames[i], StringComparison.InvariantCultureIgnoreCase)==0) {
- return (i+1);
- }
- }
- return (-1);
- }
-
- internal String[] EraNames
- {
- get
- {
- if (this.m_eraNames == null)
- {
- this.m_eraNames = this.m_cultureData.EraNames(Calendar.ID);;
- }
- return (this.m_eraNames);
- }
- }
-
- /*=================================GetEraName==========================
- **Action: Get the name of the era for the specified era value.
- **Returns: The name of the specified era.
- **Arguments:
- ** era the era value.
- **Exceptions:
- ** ArguementException if the era valie is invalid.
- ============================================================================*/
-
- // Era names are 1 indexed
- public String GetEraName(int era) {
- if (era == Calendar.CurrentEra) {
- era = Calendar.CurrentEraValue;
- }
-
- // The following is based on the assumption that the era value is starting from 1, and has a
- // serial values.
- // If that ever changes, the code has to be changed.
- if ((--era) < EraNames.Length && (era >= 0)) {
- return (m_eraNames[era]);
- }
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
- }
-
- internal String[] AbbreviatedEraNames
- {
- get
- {
- if (this.m_abbrevEraNames == null)
- {
- this.m_abbrevEraNames = this.m_cultureData.AbbrevEraNames(Calendar.ID);
- }
- return (this.m_abbrevEraNames);
- }
- }
-
- // Era names are 1 indexed
- public String GetAbbreviatedEraName(int era) {
- if (AbbreviatedEraNames.Length == 0) {
- // If abbreviation era name is not used in this culture,
- // return the full era name.
- return (GetEraName(era));
- }
- if (era == Calendar.CurrentEra) {
- era = Calendar.CurrentEraValue;
- }
- if ((--era) < m_abbrevEraNames.Length && (era >= 0)) {
- return (m_abbrevEraNames[era]);
- }
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
- }
-
- internal String[] AbbreviatedEnglishEraNames
- {
- get
- {
- if (this.m_abbrevEnglishEraNames == null)
- {
- Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.AbbreviatedEnglishEraNames] Expected Calendar.ID > 0");
- this.m_abbrevEnglishEraNames = this.m_cultureData.AbbreviatedEnglishEraNames(Calendar.ID);
- }
- return (this.m_abbrevEnglishEraNames);
- }
- }
-
-
- // Note that cultureData derives this from the short date format (unless someone's set this previously)
- // Note that this property is quite undesirable.
- public String DateSeparator
- {
- get
- {
- if (this.dateSeparator == null)
- {
- this.dateSeparator = this.m_cultureData.DateSeparator(Calendar.ID);
- }
-
- Debug.Assert(this.dateSeparator != null, "DateTimeFormatInfo.DateSeparator, dateSeparator != null");
- return (this.dateSeparator);
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_String"));
- }
- Contract.EndContractBlock();
- ClearTokenHashTable();
- this.dateSeparator = value;
- }
- }
-
-
- public DayOfWeek FirstDayOfWeek
- {
- get
- {
- if (this.firstDayOfWeek == -1)
- {
- this.firstDayOfWeek = this.m_cultureData.IFIRSTDAYOFWEEK;
- }
-
- Debug.Assert(this.firstDayOfWeek != -1, "DateTimeFormatInfo.FirstDayOfWeek, firstDayOfWeek != -1");
- return ((DayOfWeek)this.firstDayOfWeek);
- }
-
- set {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value >= DayOfWeek.Sunday && value <= DayOfWeek.Saturday) {
- firstDayOfWeek = (int)value;
- } else {
- throw new ArgumentOutOfRangeException(
- nameof(value), Environment.GetResourceString("ArgumentOutOfRange_Range",
- DayOfWeek.Sunday, DayOfWeek.Saturday));
- }
- }
- }
-
-
- public CalendarWeekRule CalendarWeekRule
- {
- get
- {
- if (this.calendarWeekRule == -1)
- {
- this.calendarWeekRule = this.m_cultureData.IFIRSTWEEKOFYEAR;
- }
-
- Debug.Assert(this.calendarWeekRule != -1, "DateTimeFormatInfo.CalendarWeekRule, calendarWeekRule != -1");
- return ((CalendarWeekRule)this.calendarWeekRule);
- }
-
- set {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value >= CalendarWeekRule.FirstDay && value <= CalendarWeekRule.FirstFourDayWeek) {
- calendarWeekRule = (int)value;
- } else {
- throw new ArgumentOutOfRangeException(
- nameof(value), Environment.GetResourceString("ArgumentOutOfRange_Range",
- CalendarWeekRule.FirstDay, CalendarWeekRule.FirstFourDayWeek));
- }
- }
- }
-
-
-
- public String FullDateTimePattern
- {
- get
- {
- if (fullDateTimePattern == null)
- {
- fullDateTimePattern = LongDatePattern + " " + LongTimePattern;
- }
- return (fullDateTimePattern);
- }
-
- set {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null) {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_String"));
- }
- Contract.EndContractBlock();
- fullDateTimePattern = value;
- }
- }
-
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
- public String LongDatePattern
- {
- get
- {
- // Initialize our long date pattern from the 1st array value if not set
- if (this.longDatePattern == null)
- {
- // Initialize our data
- this.longDatePattern = this.UnclonedLongDatePatterns[0];
- }
-
- return this.longDatePattern;
- }
-
- set {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null) {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_String"));
- }
- Contract.EndContractBlock();
-
- // Remember the new string
- this.longDatePattern = value;
-
- // Clear the token hash table
- ClearTokenHashTable();
-
- // Clean up cached values that will be affected by this property.
- this.fullDateTimePattern = null;
- }
- }
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
- public String LongTimePattern
- {
- get
- {
- // Initialize our long time pattern from the 1st array value if not set
- if (this.longTimePattern == null)
- {
- // Initialize our data
- this.longTimePattern = this.UnclonedLongTimePatterns[0];
- }
-
- return this.longTimePattern;
- }
-
- set {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null) {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_String"));
- }
- Contract.EndContractBlock();
-
- // Remember the new string
- this.longTimePattern = value;
-
- // Clear the token hash table
- ClearTokenHashTable();
-
- // Clean up cached values that will be affected by this property.
- this.fullDateTimePattern = null; // Full date = long date + long Time
- this.generalLongTimePattern = null; // General long date = short date + long Time
- this.dateTimeOffsetPattern = null;
- }
- }
-
-
- // Note: just to be confusing there's only 1 month day pattern, not a whole list
- public String MonthDayPattern
- {
- get
- {
- if (this.monthDayPattern == null)
- {
- Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.MonthDayPattern] Expected calID > 0");
- this.monthDayPattern = this.m_cultureData.MonthDay(Calendar.ID);
- }
- Debug.Assert(this.monthDayPattern != null, "DateTimeFormatInfo.MonthDayPattern, monthDayPattern != null");
- return (this.monthDayPattern);
- }
-
- set {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null) {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_String"));
- }
- Contract.EndContractBlock();
-
- this.monthDayPattern = value;
- }
- }
-
-
- public String PMDesignator
- {
- get
- {
- if (this.pmDesignator == null)
- {
- this.pmDesignator = this.m_cultureData.SPM2359;
- }
-
- Debug.Assert(this.pmDesignator != null, "DateTimeFormatInfo.PMDesignator, pmDesignator != null");
- return (this.pmDesignator);
- }
-
- set {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null) {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_String"));
- }
- Contract.EndContractBlock();
- ClearTokenHashTable();
-
- pmDesignator = value;
- }
-
- }
-
-
- public String RFC1123Pattern
- {
- get
- {
- return (rfc1123Pattern);
- }
- }
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
- public String ShortDatePattern
- {
- get
- {
- // Initialize our short date pattern from the 1st array value if not set
- if (this.shortDatePattern == null)
- {
- // Initialize our data
- this.shortDatePattern = this.UnclonedShortDatePatterns[0];
- }
-
- return this.shortDatePattern;
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null)
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_String"));
- Contract.EndContractBlock();
-
- // Remember the new string
- this.shortDatePattern = value;
-
- // Clear the token hash table, note that even short dates could require this
- ClearTokenHashTable();
-
- // Clean up cached values that will be affected by this property.
- generalLongTimePattern = null; // General long time = short date + long time
- generalShortTimePattern = null; // General short time = short date + short Time
- dateTimeOffsetPattern = null;
- }
- }
-
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
- public String ShortTimePattern
- {
- get
- {
- // Initialize our short time pattern from the 1st array value if not set
- if (this.shortTimePattern == null)
- {
- // Initialize our data
- this.shortTimePattern = this.UnclonedShortTimePatterns[0];
- }
- return this.shortTimePattern;
- }
-
- set {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null) {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_String"));
- }
- Contract.EndContractBlock();
-
- // Remember the new string
- this.shortTimePattern= value;
-
- // Clear the token hash table, note that even short times could require this
- ClearTokenHashTable();
-
- // Clean up cached values that will be affected by this property.
- generalShortTimePattern = null; // General short date = short date + short time.
- }
- }
-
-
- public String SortableDateTimePattern {
- get {
- return (sortableDateTimePattern);
- }
- }
-
- /*=================================GeneralShortTimePattern=====================
- **Property: Return the pattern for 'g' general format: shortDate + short time
- **Note: This is used by DateTimeFormat.cs to get the pattern for 'g'
- ** We put this internal property here so that we can avoid doing the
- ** concatation every time somebody asks for the general format.
- ==============================================================================*/
-
- internal String GeneralShortTimePattern {
- get {
- if (generalShortTimePattern == null) {
- generalShortTimePattern = ShortDatePattern + " " + ShortTimePattern;
- }
- return (generalShortTimePattern);
- }
- }
-
- /*=================================GeneralLongTimePattern=====================
- **Property: Return the pattern for 'g' general format: shortDate + Long time
- **Note: This is used by DateTimeFormat.cs to get the pattern for 'g'
- ** We put this internal property here so that we can avoid doing the
- ** concatation every time somebody asks for the general format.
- ==============================================================================*/
-
- internal String GeneralLongTimePattern {
- get {
- if (generalLongTimePattern == null) {
- generalLongTimePattern = ShortDatePattern + " " + LongTimePattern;
- }
- return (generalLongTimePattern);
- }
- }
-
- /*=================================DateTimeOffsetPattern==========================
- **Property: Return the default pattern DateTimeOffset : shortDate + long time + time zone offset
- **Note: This is used by DateTimeFormat.cs to get the pattern for short Date + long time + time zone offset
- ** We put this internal property here so that we can avoid doing the
- ** concatation every time somebody uses this form
- ==============================================================================*/
-
- /*=================================DateTimeOffsetPattern==========================
- **Property: Return the default pattern DateTimeOffset : shortDate + long time + time zone offset
- **Note: This is used by DateTimeFormat.cs to get the pattern for short Date + long time + time zone offset
- ** We put this internal property here so that we can avoid doing the
- ** concatation every time somebody uses this form
- ==============================================================================*/
-
- internal String DateTimeOffsetPattern {
- get {
- if (dateTimeOffsetPattern == null) {
-
- string dateTimePattern = ShortDatePattern + " " + LongTimePattern;
-
- /* LongTimePattern might contain a "z" as part of the format string in which case we don't want to append a time zone offset */
-
- bool foundZ = false;
- bool inQuote = false;
- char quote = '\'';
- for (int i = 0; !foundZ && i < LongTimePattern.Length; i++) {
- switch (LongTimePattern[i]) {
- case 'z':
- /* if we aren't in a quote, we've found a z */
- foundZ = !inQuote;
- /* we'll fall out of the loop now because the test includes !foundZ */
- break;
- case '\'':
- case '\"':
- if (inQuote && (quote == LongTimePattern[i])) {
- /* we were in a quote and found a matching exit quote, so we are outside a quote now */
- inQuote = false;
- } else if (!inQuote) {
- quote = LongTimePattern[i];
- inQuote = true;
- } else {
- /* we were in a quote and saw the other type of quote character, so we are still in a quote */
- }
- break;
- case '%':
- case '\\':
- i++; /* skip next character that is escaped by this backslash */
- break;
- default:
- break;
- }
- }
-
- if (!foundZ) {
- dateTimePattern = dateTimePattern + " zzz";
- }
-
- dateTimeOffsetPattern = dateTimePattern;
- }
- return (dateTimeOffsetPattern);
- }
- }
-
- // Note that cultureData derives this from the long time format (unless someone's set this previously)
- // Note that this property is quite undesirable.
- public String TimeSeparator
- {
- get
- {
- if (timeSeparator == null)
- {
- timeSeparator = this.m_cultureData.TimeSeparator;
- }
-
- Debug.Assert(this.timeSeparator != null, "DateTimeFormatInfo.TimeSeparator, timeSeparator != null");
- return (timeSeparator);
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_String"));
- }
- Contract.EndContractBlock();
- ClearTokenHashTable();
-
- timeSeparator = value;
- }
- }
-
-
- public String UniversalSortableDateTimePattern
- {
- get
- {
- return (universalSortableDateTimePattern);
- }
- }
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
- public String YearMonthPattern
- {
- get
- {
- // Initialize our year/month pattern from the 1st array value if not set
- if (this.yearMonthPattern == null)
- {
- // Initialize our data
- this.yearMonthPattern = this.UnclonedYearMonthPatterns[0];
- }
- return this.yearMonthPattern;
- }
-
- set {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null) {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_String"));
- }
- Contract.EndContractBlock();
-
- // Remember the new string
- this.yearMonthPattern = value;
-
- // Clear the token hash table, note that even short times could require this
- ClearTokenHashTable();
- }
- }
-
- //
- // Check if a string array contains a null value, and throw ArgumentNullException with parameter name "value"
- //
- static private void CheckNullValue(String[] values, int length) {
- Contract.Requires(values != null, "value != null");
- Contract.Requires(values.Length >= length);
- for (int i = 0; i < length; i++) {
- if (values[i] == null) {
- throw new ArgumentNullException("value",
- Environment.GetResourceString("ArgumentNull_ArrayValue"));
- }
- }
- }
-
-
- public String[] AbbreviatedDayNames
- {
- get
- {
- return ((String[])internalGetAbbreviatedDayOfWeekNames().Clone());
- }
-
- set {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null) {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (value.Length != 7) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 7), nameof(value));
- }
- Contract.EndContractBlock();
- CheckNullValue(value, value.Length);
- ClearTokenHashTable();
-
- abbreviatedDayNames = value;
- }
- }
-
-
- // Returns the string array of the one-letter day of week names.
- public String[] ShortestDayNames
- {
- get
- {
- return ((String[])internalGetSuperShortDayNames().Clone());
- }
-
- set {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null) {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (value.Length != 7)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 7), nameof(value));
- }
- Contract.EndContractBlock();
- CheckNullValue(value, value.Length);
- this.m_superShortDayNames = value;
- }
- }
-
-
- public String[] DayNames
- {
- get
- {
- return ((String[])internalGetDayOfWeekNames().Clone());
- }
-
- set {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null) {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (value.Length != 7)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 7), nameof(value));
- }
- Contract.EndContractBlock();
- CheckNullValue(value, value.Length);
- ClearTokenHashTable();
-
- dayNames = value;
- }
- }
-
-
- public String[] AbbreviatedMonthNames {
- get {
- return ((String[])internalGetAbbreviatedMonthNames().Clone());
- }
-
- set {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null) {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (value.Length != 13)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 13), nameof(value));
- }
- Contract.EndContractBlock();
- CheckNullValue(value, value.Length - 1);
- ClearTokenHashTable();
- abbreviatedMonthNames = value;
- }
- }
-
-
- public String[] MonthNames
- {
- get
- {
- return ((String[])internalGetMonthNames().Clone());
- }
-
- set {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null) {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (value.Length != 13)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 13), nameof(value));
- }
- Contract.EndContractBlock();
- CheckNullValue(value, value.Length - 1);
- monthNames = value;
- ClearTokenHashTable();
- }
- }
-
- // Whitespaces that we allow in the month names.
- // U+00a0 is non-breaking space.
- static char[] MonthSpaces = {' ', '\u00a0'};
-
- internal bool HasSpacesInMonthNames {
- get {
- return (FormatFlags & DateTimeFormatFlags.UseSpacesInMonthNames) != 0;
- }
- }
-
- internal bool HasSpacesInDayNames {
- get {
- return (FormatFlags & DateTimeFormatFlags.UseSpacesInDayNames) != 0;
- }
- }
-
-
- //
- // internalGetMonthName
- //
- // Actions: Return the month name using the specified MonthNameStyles in either abbreviated form
- // or full form.
- // Arguments:
- // month
- // style To indicate a form like regular/genitive/month name in a leap year.
- // abbreviated When true, return abbreviated form. Otherwise, return a full form.
- // Exceptions:
- // ArgumentOutOfRangeException When month name is invalid.
- //
- internal String internalGetMonthName(int month, MonthNameStyles style, bool abbreviated) {
- //
- // Right now, style is mutual exclusive, but I make the style to be flag so that
- // maybe we can combine flag if there is such a need.
- //
- String[] monthNamesArray = null;
- switch (style) {
- case MonthNameStyles.Genitive:
- monthNamesArray = internalGetGenitiveMonthNames(abbreviated);
- break;
- case MonthNameStyles.LeapYear:
- monthNamesArray = internalGetLeapYearMonthNames(/*abbreviated*/);
- break;
- default:
- monthNamesArray = (abbreviated ? internalGetAbbreviatedMonthNames(): internalGetMonthNames());
- break;
- }
- // The month range is from 1 ~ this.m_monthNames.Length
- // (actually is 13 right now for all cases)
- if ((month < 1) || (month > monthNamesArray.Length)) {
- throw new ArgumentOutOfRangeException(
- nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Range",
- 1, monthNamesArray.Length));
- }
- return (monthNamesArray[month-1]);
- }
-
- //
- // internalGetGenitiveMonthNames
- //
- // Action: Retrieve the array which contains the month names in genitive form.
- // If this culture does not use the gentive form, the normal month name is returned.
- // Arguments:
- // abbreviated When true, return abbreviated form. Otherwise, return a full form.
- //
- private String[] internalGetGenitiveMonthNames(bool abbreviated) {
- if (abbreviated) {
- if (this.m_genitiveAbbreviatedMonthNames == null)
- {
- this.m_genitiveAbbreviatedMonthNames = this.m_cultureData.AbbreviatedGenitiveMonthNames(this.Calendar.ID);
- Debug.Assert(this.m_genitiveAbbreviatedMonthNames.Length == 13,
- "[DateTimeFormatInfo.GetGenitiveMonthNames] Expected 13 abbreviated genitive month names in a year");
- }
- return (this.m_genitiveAbbreviatedMonthNames);
- }
-
- if (this.genitiveMonthNames == null)
- {
- this.genitiveMonthNames = this.m_cultureData.GenitiveMonthNames(this.Calendar.ID);
- Debug.Assert(this.genitiveMonthNames.Length == 13,
- "[DateTimeFormatInfo.GetGenitiveMonthNames] Expected 13 genitive month names in a year");
- }
- return (this.genitiveMonthNames);
- }
-
- //
- // internalGetLeapYearMonthNames
- //
- // Actions: Retrieve the month names used in a leap year.
- // If this culture does not have different month names in a leap year, the normal month name is returned.
- // Agruments: None. (can use abbreviated later if needed)
- //
- internal String[] internalGetLeapYearMonthNames(/*bool abbreviated*/) {
- if (this.leapYearMonthNames == null)
- {
- Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.internalGetLeapYearMonthNames] Expected Calendar.ID > 0");
- this.leapYearMonthNames = this.m_cultureData.LeapYearMonthNames(Calendar.ID);
- Debug.Assert(this.leapYearMonthNames.Length == 13,
- "[DateTimeFormatInfo.internalGetLeapYearMonthNames] Expepcted 13 leap year month names");
- }
- return (leapYearMonthNames);
- }
-
-
- public String GetAbbreviatedDayName(DayOfWeek dayofweek)
- {
-
- if ((int)dayofweek < 0 || (int)dayofweek > 6) {
- throw new ArgumentOutOfRangeException(
- nameof(dayofweek), Environment.GetResourceString("ArgumentOutOfRange_Range",
- DayOfWeek.Sunday, DayOfWeek.Saturday));
- }
- Contract.EndContractBlock();
- //
- // Don't call the public property AbbreviatedDayNames here since a clone is needed in that
- // property, so it will be slower. Instead, use GetAbbreviatedDayOfWeekNames() directly.
- //
- return (internalGetAbbreviatedDayOfWeekNames()[(int)dayofweek]);
- }
-
-
- // Returns the super short day of week names for the specified day of week.
- public String GetShortestDayName(DayOfWeek dayOfWeek)
- {
-
- if ((int)dayOfWeek < 0 || (int)dayOfWeek > 6) {
- throw new ArgumentOutOfRangeException(
- nameof(dayOfWeek), Environment.GetResourceString("ArgumentOutOfRange_Range",
- DayOfWeek.Sunday, DayOfWeek.Saturday));
- }
- Contract.EndContractBlock();
- //
- // Don't call the public property SuperShortDayNames here since a clone is needed in that
- // property, so it will be slower. Instead, use internalGetSuperShortDayNames() directly.
- //
- return (internalGetSuperShortDayNames()[(int)dayOfWeek]);
- }
-
- // Get all possible combination of inputs
- static private String[] GetCombinedPatterns(String[] patterns1, String[] patterns2, String connectString)
- {
- Contract.Requires(patterns1 != null);
- Contract.Requires(patterns2 != null);
-
- // Get array size
- String[] result = new String[patterns1.Length * patterns2.Length];
-
- // Counter of actual results
- int k = 0;
- for (int i = 0; i < patterns1.Length; i++)
- {
- for (int j = 0; j < patterns2.Length; j++)
- {
- // Can't combine if null or empty
- result[k++] = patterns1[i] + connectString + patterns2[j];
- }
- }
-
- // Return the combinations
- return (result);
- }
-
-
- public String[] GetAllDateTimePatterns()
- {
- List<String> results = new List<String>(DEFAULT_ALL_DATETIMES_SIZE);
-
- for (int i = 0; i < DateTimeFormat.allStandardFormats.Length; i++)
- {
- String[] strings = GetAllDateTimePatterns(DateTimeFormat.allStandardFormats[i]);
- for (int j = 0; j < strings.Length; j++)
- {
- results.Add(strings[j]);
- }
- }
- return results.ToArray();
- }
-
-
- public String[] GetAllDateTimePatterns(char format)
- {
- Contract.Ensures(Contract.Result<String[]>() != null);
- String [] result = null;
-
- switch (format)
- {
- case 'd':
- result = this.AllShortDatePatterns;
- break;
- case 'D':
- result = this.AllLongDatePatterns;
- break;
- case 'f':
- result = GetCombinedPatterns(AllLongDatePatterns, AllShortTimePatterns, " ");
- break;
- case 'F':
- case 'U':
- result = GetCombinedPatterns(AllLongDatePatterns, AllLongTimePatterns, " ");
- break;
- case 'g':
- result = GetCombinedPatterns(AllShortDatePatterns, AllShortTimePatterns, " ");
- break;
- case 'G':
- result = GetCombinedPatterns(AllShortDatePatterns, AllLongTimePatterns, " ");
- break;
- case 'm':
- case 'M':
- result = new String[] {MonthDayPattern};
- break;
- case 'o':
- case 'O':
- result = new String[] {DateTimeFormat.RoundtripFormat};
- break;
- case 'r':
- case 'R':
- result = new String[] {rfc1123Pattern};
- break;
- case 's':
- result = new String[] {sortableDateTimePattern};
- break;
- case 't':
- result = this.AllShortTimePatterns;
- break;
- case 'T':
- result = this.AllLongTimePatterns;
- break;
- case 'u':
- result = new String[] {UniversalSortableDateTimePattern};
- break;
- case 'y':
- case 'Y':
- result = this.AllYearMonthPatterns;
- break;
- default:
- throw new ArgumentException(Environment.GetResourceString("Format_BadFormatSpecifier"), nameof(format));
- }
- return (result);
- }
-
-
- public String GetDayName(DayOfWeek dayofweek)
- {
- if ((int)dayofweek < 0 || (int)dayofweek > 6) {
- throw new ArgumentOutOfRangeException(
- nameof(dayofweek), Environment.GetResourceString("ArgumentOutOfRange_Range",
- DayOfWeek.Sunday, DayOfWeek.Saturday));
- }
- Contract.EndContractBlock();
-
- // Use the internal one so that we don't clone the array unnecessarily
- return (internalGetDayOfWeekNames()[(int)dayofweek]);
- }
-
-
-
- public String GetAbbreviatedMonthName(int month)
- {
- if (month < 1 || month > 13) {
- throw new ArgumentOutOfRangeException(
- nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Range",
- 1, 13));
- }
- Contract.EndContractBlock();
- // Use the internal one so we don't clone the array unnecessarily
- return (internalGetAbbreviatedMonthNames()[month-1]);
- }
-
-
- public String GetMonthName(int month)
- {
- if (month < 1 || month > 13) {
- throw new ArgumentOutOfRangeException(
- nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Range",
- 1, 13));
- }
- Contract.EndContractBlock();
- // Use the internal one so we don't clone the array unnecessarily
- return (internalGetMonthNames()[month-1]);
- }
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
- //
- // The resulting [] can get returned to the calling app, so clone it.
- private static string[] GetMergedPatterns(string [] patterns, string defaultPattern)
- {
- Debug.Assert(patterns != null && patterns.Length > 0,
- "[DateTimeFormatInfo.GetMergedPatterns]Expected array of at least one pattern");
- Debug.Assert(defaultPattern != null,
- "[DateTimeFormatInfo.GetMergedPatterns]Expected non null default string");
-
- // If the default happens to be the first in the list just return (a cloned) copy
- if (defaultPattern == patterns[0])
- {
- return (string[])patterns.Clone();
- }
-
- // We either need a bigger list, or the pattern from the list.
- int i;
- for (i = 0; i < patterns.Length; i++)
- {
- // Stop if we found it
- if (defaultPattern == patterns[i])
- break;
- }
-
- // Either way we're going to need a new array
- string[] newPatterns;
-
- // Did we find it
- if (i < patterns.Length)
- {
- // Found it, output will be same size
- newPatterns = (string[])patterns.Clone();
-
- // Have to move [0] item to [i] so we can re-write default at [0]
- // (remember defaultPattern == [i] so this is OK)
- newPatterns[i] = newPatterns[0];
- }
- else
- {
- // Not found, make room for it
- newPatterns = new String[patterns.Length + 1];
-
- // Copy existing array
- Array.Copy(patterns, 0, newPatterns, 1, patterns.Length);
- }
-
- // Remember the default
- newPatterns[0] = defaultPattern;
-
- // Return the reconstructed list
- return newPatterns;
- }
-
- // Default string isn't necessarily in our string array, so get the
- // merged patterns of both
- private String[] AllYearMonthPatterns
- {
- get
- {
- return GetMergedPatterns(this.UnclonedYearMonthPatterns, this.YearMonthPattern);
- }
- }
-
- private String[] AllShortDatePatterns
- {
- get
- {
- return GetMergedPatterns(this.UnclonedShortDatePatterns, this.ShortDatePattern);
- }
- }
-
- private String[] AllShortTimePatterns
- {
- get
- {
- return GetMergedPatterns(this.UnclonedShortTimePatterns, this.ShortTimePattern);
- }
- }
-
- private String[] AllLongDatePatterns
- {
- get
- {
- return GetMergedPatterns(this.UnclonedLongDatePatterns, this.LongDatePattern);
- }
- }
-
- private String[] AllLongTimePatterns
- {
- get
- {
- return GetMergedPatterns(this.UnclonedLongTimePatterns, this.LongTimePattern);
- }
- }
-
- // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
- // This won't include default, call AllYearMonthPatterns
- private String[] UnclonedYearMonthPatterns
- {
- get
- {
- if (this.allYearMonthPatterns == null)
- {
- Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedYearMonthPatterns] Expected Calendar.ID > 0");
- this.allYearMonthPatterns = this.m_cultureData.YearMonths(this.Calendar.ID);
- Debug.Assert(this.allYearMonthPatterns.Length > 0,
- "[DateTimeFormatInfo.UnclonedYearMonthPatterns] Expected some year month patterns");
- }
-
- return this.allYearMonthPatterns;
- }
- }
-
-
- // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
- // This won't include default, call AllShortDatePatterns
- private String [] UnclonedShortDatePatterns
- {
- get
- {
- if (allShortDatePatterns == null)
- {
- Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedShortDatePatterns] Expected Calendar.ID > 0");
- this.allShortDatePatterns = this.m_cultureData.ShortDates(this.Calendar.ID);
- Debug.Assert(this.allShortDatePatterns.Length > 0,
- "[DateTimeFormatInfo.UnclonedShortDatePatterns] Expected some short date patterns");
- }
-
- return this.allShortDatePatterns;
- }
- }
-
- // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
- // This won't include default, call AllLongDatePatterns
- private String[] UnclonedLongDatePatterns
- {
- get
- {
- if (allLongDatePatterns == null)
- {
- Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedLongDatePatterns] Expected Calendar.ID > 0");
- this.allLongDatePatterns = this.m_cultureData.LongDates(this.Calendar.ID);
- Debug.Assert(this.allLongDatePatterns.Length > 0,
- "[DateTimeFormatInfo.UnclonedLongDatePatterns] Expected some long date patterns");
- }
-
- return this.allLongDatePatterns;
- }
- }
-
- // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
- // This won't include default, call AllShortTimePatterns
- private String[] UnclonedShortTimePatterns
- {
- get
- {
- if (this.allShortTimePatterns == null)
- {
- this.allShortTimePatterns = this.m_cultureData.ShortTimes;
- Debug.Assert(this.allShortTimePatterns.Length > 0,
- "[DateTimeFormatInfo.UnclonedShortTimePatterns] Expected some short time patterns");
- }
-
- return this.allShortTimePatterns;
- }
- }
-
- // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
- // This won't include default, call AllLongTimePatterns
- private String[] UnclonedLongTimePatterns
- {
- get
- {
- if (this.allLongTimePatterns == null)
- {
- this.allLongTimePatterns = this.m_cultureData.LongTimes;
- Debug.Assert(this.allLongTimePatterns.Length > 0,
- "[DateTimeFormatInfo.UnclonedLongTimePatterns] Expected some long time patterns");
- }
-
- return this.allLongTimePatterns;
- }
- }
-
- public static DateTimeFormatInfo ReadOnly(DateTimeFormatInfo dtfi) {
- if (dtfi == null) {
- throw new ArgumentNullException(nameof(dtfi),
- Environment.GetResourceString("ArgumentNull_Obj"));
- }
- Contract.EndContractBlock();
- if (dtfi.IsReadOnly) {
- return (dtfi);
- }
- DateTimeFormatInfo newInfo = (DateTimeFormatInfo)(dtfi.MemberwiseClone());
- // We can use the data member calendar in the setter, instead of the property Calendar,
- // since the cloned copy should have the same state as the original copy.
- newInfo.calendar = Calendar.ReadOnly(dtfi.Calendar);
- newInfo.m_isReadOnly = true;
- return (newInfo);
- }
-
-
- public bool IsReadOnly {
- get {
- return (m_isReadOnly);
- }
- }
-
- // Return the native name for the calendar in DTFI.Calendar. The native name is referred to
- // the culture used to create the DTFI. E.g. in the following example, the native language is Japanese.
- // DateTimeFormatInfo dtfi = new CultureInfo("ja-JP", false).DateTimeFormat.Calendar = new JapaneseCalendar();
- // String nativeName = dtfi.NativeCalendarName; // Get the Japanese name for the Japanese calendar.
- // DateTimeFormatInfo dtfi = new CultureInfo("ja-JP", false).DateTimeFormat.Calendar = new GregorianCalendar(GregorianCalendarTypes.Localized);
- // String nativeName = dtfi.NativeCalendarName; // Get the Japanese name for the Gregorian calendar.
- public String NativeCalendarName
- {
- get
- {
- return m_cultureData.CalendarName(Calendar.ID);
- }
- }
-
- //
- // Used by custom cultures and others to set the list of available formats. Note that none of them are
- // explicitly used unless someone calls GetAllDateTimePatterns and subsequently uses one of the items
- // from the list.
- //
- // Most of the format characters that can be used in GetAllDateTimePatterns are
- // not really needed since they are one of the following:
- //
- // r/R/s/u locale-independent constants -- cannot be changed!
- // m/M/y/Y fields with a single string in them -- that can be set through props directly
- // f/F/g/G/U derived fields based on combinations of various of the below formats
- //
- // NOTE: No special validation is done here beyond what is done when the actual respective fields
- // are used (what would be the point of disallowing here what we allow in the appropriate property?)
- //
- // WARNING: If more validation is ever done in one place, it should be done in the other.
- //
-
- public void SetAllDateTimePatterns(String[] patterns, char format)
- {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (patterns == null) {
- throw new ArgumentNullException(nameof(patterns),
- Environment.GetResourceString("ArgumentNull_Array"));
- }
-
- if (patterns.Length == 0)
- {
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayZeroError"), nameof(patterns));
- }
- Contract.EndContractBlock();
-
- for (int i=0; i<patterns.Length; i++)
- {
- if (patterns[i] == null)
- {
- throw new ArgumentNullException("patterns[" + i + "]", Environment.GetResourceString("ArgumentNull_ArrayValue"));
- }
- }
-
- // Remember the patterns, and use the 1st as default
- switch (format)
- {
- case 'd':
- this.allShortDatePatterns = patterns;
- this.shortDatePattern = this.allShortDatePatterns[0];
- break;
-
- case 'D':
- this.allLongDatePatterns = patterns;
- this.longDatePattern = this.allLongDatePatterns[0];
- break;
-
- case 't':
- this.allShortTimePatterns = patterns;
- this.shortTimePattern = this.allShortTimePatterns[0];
- break;
-
- case 'T':
- this.allLongTimePatterns = patterns;
- this.longTimePattern = this.allLongTimePatterns[0];
- break;
-
- case 'y':
- case 'Y':
- this.allYearMonthPatterns = patterns;
- this.yearMonthPattern = this.allYearMonthPatterns[0];
- break;
-
- default:
- throw new ArgumentException(Environment.GetResourceString("Format_BadFormatSpecifier"), nameof(format));
- }
-
- // Clear the token hash table, note that even short dates could require this
- ClearTokenHashTable();
-
- return;
- }
-
- public String[] AbbreviatedMonthGenitiveNames
- {
- get
- {
- return ((String[])internalGetGenitiveMonthNames(true).Clone());
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (value.Length != 13)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 13), nameof(value));
- }
- Contract.EndContractBlock();
- CheckNullValue(value, value.Length - 1);
- ClearTokenHashTable();
- this.m_genitiveAbbreviatedMonthNames= value;
- }
- }
-
- public String[] MonthGenitiveNames
- {
- get
- {
- return ((String[])internalGetGenitiveMonthNames(false).Clone());
- }
-
- set
- {
- if (IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value),
- Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (value.Length != 13)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidArrayLength", 13), nameof(value));
- }
- Contract.EndContractBlock();
- CheckNullValue(value, value.Length - 1);
- genitiveMonthNames= value;
- ClearTokenHashTable();
- }
- }
-
- //
- // Positive TimeSpan Pattern
- //
- [NonSerialized]
- private string m_fullTimeSpanPositivePattern;
- internal String FullTimeSpanPositivePattern
- {
- get
- {
- if (m_fullTimeSpanPositivePattern == null)
- {
- CultureData cultureDataWithoutUserOverrides;
- if (m_cultureData.UseUserOverride)
- cultureDataWithoutUserOverrides = CultureData.GetCultureData(m_cultureData.CultureName, false);
- else
- cultureDataWithoutUserOverrides = m_cultureData;
- String decimalSeparator = new NumberFormatInfo(cultureDataWithoutUserOverrides).NumberDecimalSeparator;
-
- m_fullTimeSpanPositivePattern = "d':'h':'mm':'ss'" + decimalSeparator + "'FFFFFFF";
- }
- return m_fullTimeSpanPositivePattern;
- }
- }
-
- //
- // Negative TimeSpan Pattern
- //
- [NonSerialized]
- private string m_fullTimeSpanNegativePattern;
- internal String FullTimeSpanNegativePattern
- {
- get
- {
- if (m_fullTimeSpanNegativePattern == null)
- m_fullTimeSpanNegativePattern = "'-'" + FullTimeSpanPositivePattern;
- return m_fullTimeSpanNegativePattern;
- }
- }
-
- //
- // Get suitable CompareInfo from current DTFI object.
- //
- internal CompareInfo CompareInfo
- {
- get
- {
- if (m_compareInfo == null)
- {
- // We use the regular GetCompareInfo here to make sure the created CompareInfo object is stored in the
- // CompareInfo cache. otherwise we would just create CompareInfo using m_cultureData.
- m_compareInfo = CompareInfo.GetCompareInfo(m_cultureData.SCOMPAREINFO);
- }
-
- return m_compareInfo;
- }
- }
-
-
- internal const DateTimeStyles InvalidDateTimeStyles = ~(DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite
- | DateTimeStyles.AllowInnerWhite | DateTimeStyles.NoCurrentDateDefault
- | DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeLocal
- | DateTimeStyles.AssumeUniversal | DateTimeStyles.RoundtripKind);
-
- internal static void ValidateStyles(DateTimeStyles style, String parameterName) {
- if ((style & InvalidDateTimeStyles) != 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDateTimeStyles"), parameterName);
- }
- if (((style & (DateTimeStyles.AssumeLocal)) != 0) && ((style & (DateTimeStyles.AssumeUniversal)) != 0)) {
- throw new ArgumentException(Environment.GetResourceString("Argument_ConflictingDateTimeStyles"), parameterName);
- }
- Contract.EndContractBlock();
- if (((style & DateTimeStyles.RoundtripKind) != 0)
- && ((style & (DateTimeStyles.AssumeLocal | DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal)) != 0)) {
- throw new ArgumentException(Environment.GetResourceString("Argument_ConflictingDateTimeRoundtripStyles"), parameterName);
- }
- }
-
- //
- // Actions: Return the internal flag used in formatting and parsing.
- // The flag can be used to indicate things like if genitive forms is used in this DTFi, or if leap year gets different month names.
- //
- internal DateTimeFormatFlags FormatFlags
- {
- get
- {
- if (formatFlags == DateTimeFormatFlags.NotInitialized)
- {
- // Build the format flags from the data in this DTFI
- formatFlags = DateTimeFormatFlags.None;
- formatFlags |= (DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagGenitiveMonth(
- MonthNames, internalGetGenitiveMonthNames(false), AbbreviatedMonthNames, internalGetGenitiveMonthNames(true));
- formatFlags |= (DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagUseSpaceInMonthNames(
- MonthNames, internalGetGenitiveMonthNames(false), AbbreviatedMonthNames, internalGetGenitiveMonthNames(true));
- formatFlags |= (DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagUseSpaceInDayNames(DayNames, AbbreviatedDayNames);
- formatFlags |= (DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagUseHebrewCalendar((int)Calendar.ID);
- }
- return (formatFlags);
- }
- }
-
- internal Boolean HasForceTwoDigitYears {
- get {
- switch (calendar.ID)
- {
- // If is y/yy, do not get (year % 100). "y" will print
- // year without leading zero. "yy" will print year with two-digit in leading zero.
- // If pattern is yyy/yyyy/..., print year value with two-digit in leading zero.
- // So year 5 is "05", and year 125 is "125".
- // The reason for not doing (year % 100) is for Taiwan calendar.
- // If year 125, then output 125 and not 25.
- // Note: OS uses "yyyy" for Taiwan calendar by default.
- case (Calendar.CAL_JAPAN):
- case (Calendar.CAL_TAIWAN):
- return true;
- }
- return false;
- }
- }
-
- // Returns whether the YearMonthAdjustment function has any fix-up work to do for this culture/calendar.
- internal Boolean HasYearMonthAdjustment {
- get {
- return ((FormatFlags & DateTimeFormatFlags.UseHebrewRule) != 0);
- }
- }
-
- // This is a callback that the parser can make back into the DTFI to let it fiddle with special
- // cases associated with that culture or calendar. Currently this only has special cases for
- // the Hebrew calendar, but this could be extended to other cultures.
- //
- // The return value is whether the year and month are actually valid for this calendar.
- internal Boolean YearMonthAdjustment(ref int year, ref int month, Boolean parsedMonthName) {
- if ((FormatFlags & DateTimeFormatFlags.UseHebrewRule) != 0) {
-
- // Special rules to fix up the Hebrew year/month
-
- // When formatting, we only format up to the hundred digit of the Hebrew year, although Hebrew year is now over 5000.
- // E.g. if the year is 5763, we only format as 763.
- if (year < 1000) {
- year += 5000;
- }
-
- // Because we need to calculate leap year, we should fall out now for an invalid year.
- if (year < Calendar.GetYear(Calendar.MinSupportedDateTime) || year > Calendar.GetYear(Calendar.MaxSupportedDateTime)) {
- return false;
- }
-
- // To handle leap months, the set of month names in the symbol table does not always correspond to the numbers.
- // For non-leap years, month 7 (Adar Bet) is not present, so we need to make using this month invalid and
- // shuffle the other months down.
- if (parsedMonthName) {
- if (!Calendar.IsLeapYear(year)) {
- if (month >= 8) {
- month--;
- }
- else if (month == 7) {
- return false;
- }
- }
- }
- }
- return true;
- }
-
- //
- // DateTimeFormatInfo tokenizer. This is used by DateTime.Parse() to break input string into tokens.
- //
- [NonSerialized]
- TokenHashValue[] m_dtfiTokenHash;
-
- private const int TOKEN_HASH_SIZE = 199;
- private const int SECOND_PRIME = 197;
- private const String dateSeparatorOrTimeZoneOffset = "-";
- private const String invariantDateSeparator = "/";
- private const String invariantTimeSeparator = ":";
-
- //
- // Common Ignorable Symbols
- //
- internal const String IgnorablePeriod = ".";
- internal const String IgnorableComma = ",";
-
- //
- // Year/Month/Day suffixes
- //
- internal const String CJKYearSuff = "\u5e74";
- internal const String CJKMonthSuff = "\u6708";
- internal const String CJKDaySuff = "\u65e5";
-
- internal const String KoreanYearSuff = "\ub144";
- internal const String KoreanMonthSuff = "\uc6d4";
- internal const String KoreanDaySuff = "\uc77c";
-
- internal const String KoreanHourSuff = "\uc2dc";
- internal const String KoreanMinuteSuff = "\ubd84";
- internal const String KoreanSecondSuff = "\ucd08";
-
- internal const String CJKHourSuff = "\u6642";
- internal const String ChineseHourSuff = "\u65f6";
-
- internal const String CJKMinuteSuff = "\u5206";
- internal const String CJKSecondSuff = "\u79d2";
-
- internal const String LocalTimeMark = "T";
-
- internal const String KoreanLangName = "ko";
- internal const String JapaneseLangName = "ja";
- internal const String EnglishLangName = "en";
-
- private static volatile DateTimeFormatInfo s_jajpDTFI;
- private static volatile DateTimeFormatInfo s_zhtwDTFI;
-
- //
- // Create a Japanese DTFI which uses JapaneseCalendar. This is used to parse
- // date string with Japanese era name correctly even when the supplied DTFI
- // does not use Japanese calendar.
- // The created instance is stored in global s_jajpDTFI.
- //
- internal static DateTimeFormatInfo GetJapaneseCalendarDTFI() {
- DateTimeFormatInfo temp = s_jajpDTFI;
- if (temp == null) {
- temp = new CultureInfo("ja-JP", false).DateTimeFormat;
- temp.Calendar = JapaneseCalendar.GetDefaultInstance();
- s_jajpDTFI = temp;
- }
- return (temp);
- }
- internal static DateTimeFormatInfo GetTaiwanCalendarDTFI() {
- DateTimeFormatInfo temp = s_zhtwDTFI;
- if (temp == null) {
- temp = new CultureInfo("zh-TW", false).DateTimeFormat;
- temp.Calendar = TaiwanCalendar.GetDefaultInstance();
- s_zhtwDTFI = temp;
- }
- return (temp);
- }
-
-
- // DTFI properties should call this when the setter are called.
- private void ClearTokenHashTable()
- {
- m_dtfiTokenHash = null;
- formatFlags = DateTimeFormatFlags.NotInitialized;
- }
-
- internal TokenHashValue[] CreateTokenHashTable() {
- TokenHashValue[] temp = m_dtfiTokenHash;
- if (temp == null) {
- temp = new TokenHashValue[TOKEN_HASH_SIZE];
-
- bool koreanLanguage = LanguageName.Equals(KoreanLangName);
-
- string sep = this.TimeSeparator.Trim();
- if (IgnorableComma != sep) InsertHash(temp, IgnorableComma, TokenType.IgnorableSymbol, 0);
- if (IgnorablePeriod != sep) InsertHash(temp, IgnorablePeriod, TokenType.IgnorableSymbol, 0);
-
- if (KoreanHourSuff != sep && CJKHourSuff != sep && ChineseHourSuff != sep) {
- //
- // On the Macintosh, the default TimeSeparator is identical to the KoreanHourSuff, CJKHourSuff, or ChineseHourSuff for some cultures like
- // ja-JP and ko-KR. In these cases having the same symbol inserted into the hash table with multiple TokenTypes causes undesirable
- // DateTime.Parse behavior. For instance, the DateTimeFormatInfo.Tokenize() method might return SEP_DateOrOffset for KoreanHourSuff
- // instead of SEP_HourSuff.
- //
- InsertHash(temp, this.TimeSeparator, TokenType.SEP_Time, 0);
- }
-
- InsertHash(temp, this.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
- InsertHash(temp, this.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
-
- if (LanguageName.Equals("sq")) {
- // Albanian allows time formats like "12:00.PD"
- InsertHash(temp, IgnorablePeriod + this.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
- InsertHash(temp, IgnorablePeriod + this.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
- }
-
- // CJK suffix
- InsertHash(temp, CJKYearSuff, TokenType.SEP_YearSuff, 0);
- InsertHash(temp, KoreanYearSuff, TokenType.SEP_YearSuff, 0);
- InsertHash(temp, CJKMonthSuff, TokenType.SEP_MonthSuff, 0);
- InsertHash(temp, KoreanMonthSuff, TokenType.SEP_MonthSuff, 0);
- InsertHash(temp, CJKDaySuff, TokenType.SEP_DaySuff, 0);
- InsertHash(temp, KoreanDaySuff, TokenType.SEP_DaySuff, 0);
-
- InsertHash(temp, CJKHourSuff, TokenType.SEP_HourSuff, 0);
- InsertHash(temp, ChineseHourSuff, TokenType.SEP_HourSuff, 0);
- InsertHash(temp, CJKMinuteSuff, TokenType.SEP_MinuteSuff, 0);
- InsertHash(temp, CJKSecondSuff, TokenType.SEP_SecondSuff, 0);
-
- if (koreanLanguage) {
- // Korean suffix
- InsertHash(temp, KoreanHourSuff, TokenType.SEP_HourSuff, 0);
- InsertHash(temp, KoreanMinuteSuff, TokenType.SEP_MinuteSuff, 0);
- InsertHash(temp, KoreanSecondSuff, TokenType.SEP_SecondSuff, 0);
- }
-
- if ( LanguageName.Equals("ky")) {
- // For some cultures, the date separator works more like a comma, being allowed before or after any date part
- InsertHash(temp, dateSeparatorOrTimeZoneOffset, TokenType.IgnorableSymbol, 0);
- }
- else {
- InsertHash(temp, dateSeparatorOrTimeZoneOffset, TokenType.SEP_DateOrOffset, 0);
- }
-
- String[] dateWords = null;
- DateTimeFormatInfoScanner scanner = null;
-
- // We need to rescan the date words since we're always synthetic
- scanner = new DateTimeFormatInfoScanner();
- // Enumarate all LongDatePatterns, and get the DateWords and scan for month postfix.
- // The only reason they're being assigned to m_dateWords is for Whidbey Deserialization
- m_dateWords = dateWords = scanner.GetDateWordsOfDTFI(this);
- // Ensure the formatflags is initialized.
- DateTimeFormatFlags flag = FormatFlags;
-
- // For some cultures, the date separator works more like a comma, being allowed before or after any date part.
- // In these cultures, we do not use normal date separator since we disallow date separator after a date terminal state.
- // This is determined in DateTimeFormatInfoScanner. Use this flag to determine if we should treat date separator as ignorable symbol.
- bool useDateSepAsIgnorableSymbol = false;
-
- String monthPostfix = null;
- if (dateWords != null)
- {
- // There are DateWords. It could be a real date word (such as "de"), or a monthPostfix.
- // The monthPostfix starts with '\xfffe' (MonthPostfixChar), followed by the real monthPostfix.
- for (int i = 0; i < dateWords.Length; i++)
- {
- switch (dateWords[i][0])
- {
- // This is a month postfix
- case DateTimeFormatInfoScanner.MonthPostfixChar:
- // Get the real month postfix.
- monthPostfix = dateWords[i].Substring(1);
- // Add the month name + postfix into the token.
- AddMonthNames(temp, monthPostfix);
- break;
- case DateTimeFormatInfoScanner.IgnorableSymbolChar:
- String symbol = dateWords[i].Substring(1);
- InsertHash(temp, symbol, TokenType.IgnorableSymbol, 0);
- if (this.DateSeparator.Trim().Equals(symbol))
- {
- // The date separator is the same as the ingorable symbol.
- useDateSepAsIgnorableSymbol = true;
- }
- break;
- default:
- InsertHash(temp, dateWords[i], TokenType.DateWordToken, 0);
- if (LanguageName.Equals("eu")) {
- // Basque has date words with leading dots
- InsertHash(temp, IgnorablePeriod + dateWords[i], TokenType.DateWordToken, 0);
- }
- break;
- }
- }
- }
-
- if (!useDateSepAsIgnorableSymbol)
- {
- // Use the normal date separator.
- InsertHash(temp, this.DateSeparator, TokenType.SEP_Date, 0);
- }
- // Add the regular month names.
- AddMonthNames(temp, null);
-
- // Add the abbreviated month names.
- for (int i = 1; i <= 13; i++) {
- InsertHash(temp, GetAbbreviatedMonthName(i), TokenType.MonthToken, i);
- }
-
-
- if ((FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != 0) {
- for (int i = 1; i <= 13; i++) {
- String str;
- str = internalGetMonthName(i, MonthNameStyles.Genitive, false);
- InsertHash(temp, str, TokenType.MonthToken, i);
- }
- }
-
- if ((FormatFlags & DateTimeFormatFlags.UseLeapYearMonth) != 0) {
- for (int i = 1; i <= 13; i++) {
- String str;
- str = internalGetMonthName(i, MonthNameStyles.LeapYear, false);
- InsertHash(temp, str, TokenType.MonthToken, i);
- }
- }
-
- for (int i = 0; i < 7; i++) {
- //String str = GetDayOfWeekNames()[i];
- // We have to call public methods here to work with inherited DTFI.
- String str = GetDayName((DayOfWeek)i);
- InsertHash(temp, str, TokenType.DayOfWeekToken, i);
-
- str = GetAbbreviatedDayName((DayOfWeek)i);
- InsertHash(temp, str, TokenType.DayOfWeekToken, i);
-
- }
-
- int[] eras = calendar.Eras;
- for (int i = 1; i <= eras.Length; i++) {
- InsertHash(temp, GetEraName(i), TokenType.EraToken, i);
- InsertHash(temp, GetAbbreviatedEraName(i), TokenType.EraToken, i);
- }
-
- if (LanguageName.Equals(JapaneseLangName)) {
- // Japanese allows day of week forms like: "(Tue)"
- for (int i = 0; i < 7; i++) {
- String specialDayOfWeek = "(" + GetAbbreviatedDayName((DayOfWeek)i) + ")";
- InsertHash(temp, specialDayOfWeek, TokenType.DayOfWeekToken, i);
- }
- if (this.Calendar.GetType() != typeof(JapaneseCalendar)) {
- // Special case for Japanese. If this is a Japanese DTFI, and the calendar is not Japanese calendar,
- // we will check Japanese Era name as well when the calendar is Gregorian.
- DateTimeFormatInfo jaDtfi = GetJapaneseCalendarDTFI();
- for (int i = 1; i <= jaDtfi.Calendar.Eras.Length; i++) {
- InsertHash(temp, jaDtfi.GetEraName(i), TokenType.JapaneseEraToken, i);
- InsertHash(temp, jaDtfi.GetAbbreviatedEraName(i), TokenType.JapaneseEraToken, i);
- // m_abbrevEnglishEraNames[0] contains the name for era 1, so the token value is i+1.
- InsertHash(temp, jaDtfi.AbbreviatedEnglishEraNames[i-1], TokenType.JapaneseEraToken, i);
- }
- }
- }
- else if (CultureName.Equals("zh-TW")) {
- DateTimeFormatInfo twDtfi = GetTaiwanCalendarDTFI();
- for (int i = 1; i <= twDtfi.Calendar.Eras.Length; i++) {
- if (twDtfi.GetEraName(i).Length > 0) {
- InsertHash(temp, twDtfi.GetEraName(i), TokenType.TEraToken, i);
- }
- }
- }
-
- InsertHash(temp, InvariantInfo.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
- InsertHash(temp, InvariantInfo.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
-
- // Add invariant month names and day names.
- for (int i = 1; i <= 12; i++) {
- String str;
- // We have to call public methods here to work with inherited DTFI.
- // Insert the month name first, so that they are at the front of abbrevaited
- // month names.
- str = InvariantInfo.GetMonthName(i);
- InsertHash(temp, str, TokenType.MonthToken, i);
- str = InvariantInfo.GetAbbreviatedMonthName(i);
- InsertHash(temp, str, TokenType.MonthToken, i);
- }
-
- for (int i = 0; i < 7; i++) {
- // We have to call public methods here to work with inherited DTFI.
- String str = InvariantInfo.GetDayName((DayOfWeek)i);
- InsertHash(temp, str, TokenType.DayOfWeekToken, i);
-
- str = InvariantInfo.GetAbbreviatedDayName((DayOfWeek)i);
- InsertHash(temp, str, TokenType.DayOfWeekToken, i);
-
- }
-
- for (int i = 0; i < AbbreviatedEnglishEraNames.Length; i++) {
- // m_abbrevEnglishEraNames[0] contains the name for era 1, so the token value is i+1.
- InsertHash(temp, AbbreviatedEnglishEraNames[i], TokenType.EraToken, i + 1);
- }
-
- InsertHash(temp, LocalTimeMark, TokenType.SEP_LocalTimeMark, 0);
- InsertHash(temp, DateTimeParse.GMTName, TokenType.TimeZoneToken, 0);
- InsertHash(temp, DateTimeParse.ZuluName, TokenType.TimeZoneToken, 0);
-
- InsertHash(temp, invariantDateSeparator, TokenType.SEP_Date, 0);
- InsertHash(temp, invariantTimeSeparator, TokenType.SEP_Time, 0);
-
- m_dtfiTokenHash = temp;
- }
- return (temp);
- }
-
- private void AddMonthNames(TokenHashValue[] temp, String monthPostfix)
- {
- for (int i = 1; i <= 13; i++) {
- String str;
- //str = internalGetMonthName(i, MonthNameStyles.Regular, false);
- // We have to call public methods here to work with inherited DTFI.
- // Insert the month name first, so that they are at the front of abbrevaited
- // month names.
- str = GetMonthName(i);
- if (str.Length > 0) {
- if (monthPostfix != null) {
- // Insert the month name with the postfix first, so it can be matched first.
- InsertHash(temp, str + monthPostfix, TokenType.MonthToken, i);
- } else
- {
- InsertHash(temp, str, TokenType.MonthToken, i);
- }
- }
- str = GetAbbreviatedMonthName(i);
- InsertHash(temp, str, TokenType.MonthToken, i);
- }
-
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Actions:
- // Try to parse the current word to see if it is a Hebrew number.
- // Tokens will be updated accordingly.
- // This is called by the Lexer of DateTime.Parse().
- //
- // Unlike most of the functions in this class, the return value indicates
- // whether or not it started to parse. The badFormat parameter indicates
- // if parsing began, but the format was bad.
- //
- ////////////////////////////////////////////////////////////////////////
-
- private static bool TryParseHebrewNumber(
- ref __DTString str,
- out Boolean badFormat,
- out int number) {
-
- number = -1;
- badFormat = false;
-
- int i = str.Index;
- if (!HebrewNumber.IsDigit(str.Value[i])) {
- // If the current character is not a Hebrew digit, just return false.
- // There is no chance that we can parse a valid Hebrew number from here.
- return (false);
- }
- // The current character is a Hebrew digit. Try to parse this word as a Hebrew number.
- HebrewNumberParsingContext context = new HebrewNumberParsingContext(0);
- HebrewNumberParsingState state;
-
- do {
- state = HebrewNumber.ParseByChar(str.Value[i++], ref context);
- switch (state) {
- case HebrewNumberParsingState.InvalidHebrewNumber: // Not a valid Hebrew number.
- case HebrewNumberParsingState.NotHebrewDigit: // The current character is not a Hebrew digit character.
- // Break out so that we don't continue to try parse this as a Hebrew number.
- return (false);
- }
- } while (i < str.Value.Length && (state != HebrewNumberParsingState.FoundEndOfHebrewNumber));
-
- // When we are here, we are either at the end of the string, or we find a valid Hebrew number.
- Debug.Assert(state == HebrewNumberParsingState.ContinueParsing || state == HebrewNumberParsingState.FoundEndOfHebrewNumber,
- "Invalid returned state from HebrewNumber.ParseByChar()");
-
- if (state != HebrewNumberParsingState.FoundEndOfHebrewNumber) {
- // We reach end of the string but we can't find a terminal state in parsing Hebrew number.
- return (false);
- }
-
- // We have found a valid Hebrew number. Update the index.
- str.Advance(i - str.Index);
-
- // Get the final Hebrew number value from the HebrewNumberParsingContext.
- number = context.result;
-
- return (true);
- }
-
- private static bool IsHebrewChar(char ch) {
- return (ch >= '\x0590' && ch <= '\x05ff');
- }
-
- internal bool Tokenize(TokenType TokenMask, out TokenType tokenType, out int tokenValue, ref __DTString str) {
- tokenType = TokenType.UnknownToken;
- tokenValue = 0;
-
- TokenHashValue value;
- Debug.Assert(str.Index < str.Value.Length, "DateTimeFormatInfo.Tokenize(): start < value.Length");
-
- char ch = str.m_current;
- bool isLetter = Char.IsLetter(ch);
- if (isLetter) {
- ch = Char.ToLower(ch, this.Culture);
- if (IsHebrewChar(ch) && TokenMask == TokenType.RegularTokenMask) {
- bool badFormat;
- if (TryParseHebrewNumber(ref str, out badFormat, out tokenValue)) {
- if (badFormat) {
- tokenType = TokenType.UnknownToken;
- return (false);
- }
- // This is a Hebrew number.
- // Do nothing here. TryParseHebrewNumber() will update token accordingly.
- tokenType = TokenType.HebrewNumber;
- return (true);
- }
- }
- }
-
-
- int hashcode = ch % TOKEN_HASH_SIZE;
- int hashProbe = 1 + ch % SECOND_PRIME;
- int remaining = str.len - str.Index;
- int i = 0;
-
- TokenHashValue[] hashTable = m_dtfiTokenHash;
- if (hashTable == null) {
- hashTable = CreateTokenHashTable();
- }
- do {
- value = hashTable[hashcode];
- if (value == null) {
- // Not found.
- break;
- }
- // Check this value has the right category (regular token or separator token) that we are looking for.
- if (((int)value.tokenType & (int)TokenMask) > 0 && value.tokenString.Length <= remaining) {
- if (String.Compare(str.Value, str.Index, value.tokenString, 0, value.tokenString.Length, this.Culture, CompareOptions.IgnoreCase)==0) {
- if (isLetter) {
- // If this token starts with a letter, make sure that we won't allow partial match. So you can't tokenize "MarchWed" separately.
- int nextCharIndex;
- if ((nextCharIndex = str.Index + value.tokenString.Length) < str.len) {
- // Check word boundary. The next character should NOT be a letter.
- char nextCh = str.Value[nextCharIndex];
- if (Char.IsLetter(nextCh)) {
- return (false);
- }
- }
- }
- tokenType = value.tokenType & TokenMask;
- tokenValue = value.tokenValue;
- str.Advance(value.tokenString.Length);
- return (true);
- } else if (value.tokenType == TokenType.MonthToken && HasSpacesInMonthNames) {
- // For month token, we will match the month names which have spaces.
- int matchStrLen = 0;
- if (str.MatchSpecifiedWords(value.tokenString, true, ref matchStrLen)) {
- tokenType = value.tokenType & TokenMask;
- tokenValue = value.tokenValue;
- str.Advance(matchStrLen);
- return (true);
- }
- } else if (value.tokenType == TokenType.DayOfWeekToken && HasSpacesInDayNames) {
- // For month token, we will match the month names which have spaces.
- int matchStrLen = 0;
- if (str.MatchSpecifiedWords(value.tokenString, true, ref matchStrLen)) {
- tokenType = value.tokenType & TokenMask;
- tokenValue = value.tokenValue;
- str.Advance(matchStrLen);
- return (true);
- }
- }
- }
- i++;
- hashcode += hashProbe;
- if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
- }while (i < TOKEN_HASH_SIZE);
-
- return (false);
- }
-
- void InsertAtCurrentHashNode(TokenHashValue[] hashTable, String str, char ch, TokenType tokenType, int tokenValue, int pos, int hashcode, int hashProbe) {
- // Remember the current slot.
- TokenHashValue previousNode = hashTable[hashcode];
-
- //// Console.WriteLine(" Insert Key: {0} in {1}", str, slotToInsert);
- // Insert the new node into the current slot.
- hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue);;
-
- while (++pos < TOKEN_HASH_SIZE) {
- hashcode += hashProbe;
- if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
- // Remember this slot
- TokenHashValue temp = hashTable[hashcode];
-
- if (temp != null && Char.ToLower(temp.tokenString[0], this.Culture) != ch) {
- continue;
- }
- // Put the previous slot into this slot.
- hashTable[hashcode] = previousNode;
- //// Console.WriteLine(" Move {0} to slot {1}", previousNode.tokenString, hashcode);
- if (temp == null) {
- // Done
- return;
- }
- previousNode = temp;
- } ;
- Debug.Assert(false, "The hashtable is full. This should not happen.");
- }
-
- void InsertHash(TokenHashValue[] hashTable, String str, TokenType tokenType, int tokenValue) {
- // The month of the 13th month is allowed to be null, so make sure that we ignore null value here.
- if (str == null || str.Length == 0) {
- return;
- }
- TokenHashValue value;
- int i = 0;
- // If there is whitespace characters in the beginning and end of the string, trim them since whitespaces are skipped by
- // DateTime.Parse().
- if (Char.IsWhiteSpace(str[0]) || Char.IsWhiteSpace(str[str.Length - 1])) {
- str = str.Trim(); // Trim white space characters.
- // Could have space for separators
- if (str.Length == 0)
- return;
- }
- char ch = Char.ToLower(str[0], this.Culture);
- int hashcode = ch % TOKEN_HASH_SIZE;
- int hashProbe = 1 + ch % SECOND_PRIME;
- do {
- value = hashTable[hashcode];
- if (value == null) {
- //// Console.WriteLine(" Put Key: {0} in {1}", str, hashcode);
- hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue);
- return;
- } else {
- // Collision happens. Find another slot.
- if (str.Length >= value.tokenString.Length) {
- // If there are two tokens with the same prefix, we have to make sure that the longer token should be at the front of
- // the shorter ones.
- if (String.Compare(str, 0, value.tokenString, 0, value.tokenString.Length, this.Culture, CompareOptions.IgnoreCase) == 0) {
- if (str.Length > value.tokenString.Length) {
- // The str to be inserted has the same prefix as the current token, and str is longer.
- // Insert str into this node, and shift every node behind it.
- InsertAtCurrentHashNode(hashTable, str, ch, tokenType, tokenValue, i, hashcode, hashProbe);
- return;
- } else {
- // Same token. If they have different types (regular token vs separator token). Add them.
- // If we have the same regular token or separator token in the hash already, do NOT update the hash.
- // Therefore, the order of inserting token is significant here regarding what tokenType will be kept in the hash.
-
-
- //
- // Check the current value of RegularToken (stored in the lower 8-bit of tokenType) , and insert the tokenType into the hash ONLY when we don't have a RegularToken yet.
- // Also check the current value of SeparatorToken (stored in the upper 8-bit of token), and insert the tokenType into the hash ONLY when we don't have the SeparatorToken yet.
- //
-
- int nTokenType = (int)tokenType;
- int nCurrentTokenTypeInHash = (int)value.tokenType;
-
- if (((nCurrentTokenTypeInHash & (int)TokenType.RegularTokenMask) == 0) && ((nTokenType & (int)TokenType.RegularTokenMask) != 0) ||
- ((nCurrentTokenTypeInHash & (int)TokenType.SeparatorTokenMask) == 0) && ((nTokenType & (int)TokenType.SeparatorTokenMask) != 0))
- {
- value.tokenType |= tokenType;
- if (tokenValue != 0)
- {
- value.tokenValue = tokenValue;
- }
- }
- // The token to be inserted is already in the table. Skip it.
- }
- }
- }
- }
- //// Console.WriteLine(" COLLISION. Old Key: {0}, New Key: {1}", hashTable[hashcode].tokenString, str);
- i++;
- hashcode += hashProbe;
- if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
- } while (i < TOKEN_HASH_SIZE);
- Debug.Assert(false, "The hashtable is full. This should not happen.");
- }
- } // class DateTimeFormatInfo
-
- internal class TokenHashValue {
- internal String tokenString;
- internal TokenType tokenType;
- internal int tokenValue;
-
- internal TokenHashValue(String tokenString, TokenType tokenType, int tokenValue) {
- this.tokenString = tokenString;
- this.tokenType = tokenType;
- this.tokenValue = tokenValue;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/DateTimeFormatInfoScanner.cs b/src/mscorlib/src/System/Globalization/DateTimeFormatInfoScanner.cs
deleted file mode 100644
index 4555bb2463..0000000000
--- a/src/mscorlib/src/System/Globalization/DateTimeFormatInfoScanner.cs
+++ /dev/null
@@ -1,747 +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.
-////////////////////////////////////////////////////////////////////////////
-//
-// DateTimeFormatInfoScanner
-//
-// Scan a specified DateTimeFormatInfo to search for data used in DateTime.Parse()
-//
-// The data includes:
-//
-// DateWords: such as "de" used in es-ES (Spanish) LongDatePattern.
-// Postfix: such as "ta" used in fi-FI after the month name.
-//
-// This class is shared among mscorlib.dll and sysglobl.dll.
-// Use conditional CULTURE_AND_REGIONINFO_BUILDER_ONLY to differentiate between
-// methods for mscorlib.dll and sysglobl.dll.
-//
-////////////////////////////////////////////////////////////////////////////
-
-namespace System.Globalization
-{
- using System;
- using System.Globalization;
- using System.Collections;
- using System.Collections.Generic;
- using System.Text;
-
- //
- // from LocaleEx.txt header
- //
- //; IFORMATFLAGS
- //; Parsing/formatting flags.
- internal enum FORMATFLAGS {
- None = 0x00000000,
- UseGenitiveMonth = 0x00000001,
- UseLeapYearMonth = 0x00000002,
- UseSpacesInMonthNames = 0x00000004,
- UseHebrewParsing = 0x00000008,
- UseSpacesInDayNames = 0x00000010, // Has spaces or non-breaking space in the day names.
- UseDigitPrefixInTokens = 0x00000020, // Has token starting with numbers.
- }
-
- //
- // To change in CalendarId you have to do the same change in Calendar.cs
- // To do: make the definintion shared between these two files.
- //
-
- internal enum CalendarId : ushort
- {
- GREGORIAN = 1 , // Gregorian (localized) calendar
- GREGORIAN_US = 2 , // Gregorian (U.S.) calendar
- JAPAN = 3 , // Japanese Emperor Era calendar
-/* SSS_WARNINGS_OFF */ TAIWAN = 4 , // Taiwan Era calendar /* SSS_WARNINGS_ON */
- KOREA = 5 , // Korean Tangun Era calendar
- HIJRI = 6 , // Hijri (Arabic Lunar) calendar
- THAI = 7 , // Thai calendar
- HEBREW = 8 , // Hebrew (Lunar) calendar
- GREGORIAN_ME_FRENCH = 9 , // Gregorian Middle East French calendar
- GREGORIAN_ARABIC = 10, // Gregorian Arabic calendar
- GREGORIAN_XLIT_ENGLISH = 11, // Gregorian Transliterated English calendar
- GREGORIAN_XLIT_FRENCH = 12,
-// Note that all calendars after this point are MANAGED ONLY for now.
- JULIAN = 13,
- JAPANESELUNISOLAR = 14,
- CHINESELUNISOLAR = 15,
- SAKA = 16, // reserved to match Office but not implemented in our code
- LUNAR_ETO_CHN = 17, // reserved to match Office but not implemented in our code
- LUNAR_ETO_KOR = 18, // reserved to match Office but not implemented in our code
- LUNAR_ETO_ROKUYOU = 19, // reserved to match Office but not implemented in our code
- KOREANLUNISOLAR = 20,
- TAIWANLUNISOLAR = 21,
- PERSIAN = 22,
- UMALQURA = 23,
- LAST_CALENDAR = 23 // Last calendar ID
- }
-
- internal class DateTimeFormatInfoScanner
- {
- // Special prefix-like flag char in DateWord array.
-
- // Use char in PUA area since we won't be using them in real data.
- // The char used to tell a read date word or a month postfix. A month postfix
- // is "ta" in the long date pattern like "d. MMMM'ta 'yyyy" for fi-FI.
- // In this case, it will be stored as "\xfffeta" in the date word array.
- internal const char MonthPostfixChar = '\xe000';
-
- // Add ignorable symbol in a DateWord array.
-
- // hu-HU has:
- // shrot date pattern: yyyy. MM. dd.;yyyy-MM-dd;yy-MM-dd
- // long date pattern: yyyy. MMMM d.
- // Here, "." is the date separator (derived from short date pattern). However,
- // "." also appear at the end of long date pattern. In this case, we just
- // "." as ignorable symbol so that the DateTime.Parse() state machine will not
- // treat the additional date separator at the end of y,m,d pattern as an error
- // condition.
- internal const char IgnorableSymbolChar = '\xe001';
-
- // Known CJK suffix
- internal const String CJKYearSuff = "\u5e74";
- internal const String CJKMonthSuff = "\u6708";
- internal const String CJKDaySuff = "\u65e5";
-
- internal const String KoreanYearSuff = "\ub144";
- internal const String KoreanMonthSuff = "\uc6d4";
- internal const String KoreanDaySuff = "\uc77c";
-
- internal const String KoreanHourSuff = "\uc2dc";
- internal const String KoreanMinuteSuff = "\ubd84";
- internal const String KoreanSecondSuff = "\ucd08";
-
- internal const String CJKHourSuff = "\u6642";
- internal const String ChineseHourSuff = "\u65f6";
-
- internal const String CJKMinuteSuff = "\u5206";
- internal const String CJKSecondSuff = "\u79d2";
-
- // The collection fo date words & postfix.
- internal List<String> m_dateWords = new List<String>();
- // Hashtable for the known words.
- private static volatile Dictionary<String, String> s_knownWords;
-
- static Dictionary<String, String> KnownWords
- {
- get
- {
- if (s_knownWords == null)
- {
- Dictionary<String, String> temp = new Dictionary<String, String>();
- // Add known words into the hash table.
-
- // Skip these special symbols.
- temp.Add("/", String.Empty);
- temp.Add("-", String.Empty);
- temp.Add(".", String.Empty);
- // Skip known CJK suffixes.
- temp.Add(CJKYearSuff, String.Empty);
- temp.Add(CJKMonthSuff, String.Empty);
- temp.Add(CJKDaySuff, String.Empty);
- temp.Add(KoreanYearSuff, String.Empty);
- temp.Add(KoreanMonthSuff, String.Empty);
- temp.Add(KoreanDaySuff, String.Empty);
- temp.Add(KoreanHourSuff, String.Empty);
- temp.Add(KoreanMinuteSuff, String.Empty);
- temp.Add(KoreanSecondSuff, String.Empty);
- temp.Add(CJKHourSuff, String.Empty);
- temp.Add(ChineseHourSuff, String.Empty);
- temp.Add(CJKMinuteSuff, String.Empty);
- temp.Add(CJKSecondSuff, String.Empty);
-
- s_knownWords = temp;
- }
- return (s_knownWords);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Parameters:
- // pattern: The pattern to be scanned.
- // currentIndex: the current index to start the scan.
- //
- // Returns:
- // Return the index with the first character that is a letter, which will
- // be the start of a date word.
- // Note that the index can be pattern.Length if we reach the end of the string.
- //
- ////////////////////////////////////////////////////////////////////////////
- internal static int SkipWhiteSpacesAndNonLetter(String pattern, int currentIndex)
- {
- while (currentIndex < pattern.Length)
- {
- char ch = pattern[currentIndex];
- if (ch == '\\')
- {
- // Escaped character. Look ahead one character.
- currentIndex++;
- if (currentIndex < pattern.Length)
- {
- ch = pattern[currentIndex];
- if (ch == '\'')
- {
- // Skip the leading single quote. We will
- // stop at the first letter.
- continue;
- }
- // Fall thru to check if this is a letter.
- } else
- {
- // End of string
- break;
- }
- }
- if (Char.IsLetter(ch) || ch == '\'' || ch == '.')
- {
- break;
- }
- // Skip the current char since it is not a letter.
- currentIndex++;
- }
- return (currentIndex);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // A helper to add the found date word or month postfix into ArrayList for date words.
- //
- // Parameters:
- // formatPostfix: What kind of postfix this is.
- // Possible values:
- // null: This is a regular date word
- // "MMMM": month postfix
- // word: The date word or postfix to be added.
- //
- ////////////////////////////////////////////////////////////////////////////
- internal void AddDateWordOrPostfix(String formatPostfix, String str)
- {
- if (str.Length > 0)
- {
- // Some cultures use . like an abbreviation
- if (str.Equals("."))
- {
- AddIgnorableSymbols(".");
- return;
- }
- String words;
- if (KnownWords.TryGetValue(str, out words) == false)
- {
- if (m_dateWords == null)
- {
- m_dateWords = new List<String>();
- }
- if (formatPostfix == "MMMM")
- {
- // Add the word into the ArrayList as "\xfffe" + real month postfix.
- String temp = MonthPostfixChar + str;
- if (!m_dateWords.Contains(temp))
- {
- m_dateWords.Add(temp);
- }
- } else
- {
- if (!m_dateWords.Contains(str))
- {
- m_dateWords.Add(str);
- }
- if (str[str.Length - 1] == '.')
- {
- // Old version ignore the trialing dot in the date words. Support this as well.
- String strWithoutDot = str.Substring(0, str.Length - 1);
- if (!m_dateWords.Contains(strWithoutDot))
- {
- m_dateWords.Add(strWithoutDot);
- }
-
- }
- }
- }
- }
-
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Scan the pattern from the specified index and add the date word/postfix
- // when appropriate.
- //
- // Parameters:
- // pattern: The pattern to be scanned.
- // index: The starting index to be scanned.
- // formatPostfix: The kind of postfix to be scanned.
- // Possible values:
- // null: This is a regular date word
- // "MMMM": month postfix
- //
- //
- ////////////////////////////////////////////////////////////////////////////
- internal int AddDateWords(String pattern, int index, String formatPostfix)
- {
- // Skip any whitespaces so we will start from a letter.
- int newIndex = SkipWhiteSpacesAndNonLetter(pattern, index);
- if (newIndex != index && formatPostfix != null)
- {
- // There are whitespaces. This will not be a postfix.
- formatPostfix = null;
- }
- index = newIndex;
-
- // This is the first char added into dateWord.
- // Skip all non-letter character. We will add the first letter into DateWord.
- StringBuilder dateWord = new StringBuilder();
- // We assume that date words should start with a letter.
- // Skip anything until we see a letter.
-
- while (index < pattern.Length)
- {
- char ch = pattern[index];
- if (ch == '\'')
- {
- // We have seen the end of quote. Add the word if we do not see it before,
- // and break the while loop.
- AddDateWordOrPostfix(formatPostfix, dateWord.ToString());
- index++;
- break;
- } else if (ch == '\\')
- {
- //
- // Escaped character. Look ahead one character
- //
-
- // Skip escaped backslash.
- index++;
- if (index < pattern.Length)
- {
- dateWord.Append(pattern[index]);
- index++;
- }
- } else if (Char.IsWhiteSpace(ch))
- {
- // Found a whitespace. We have to add the current date word/postfix.
- AddDateWordOrPostfix(formatPostfix, dateWord.ToString());
- if (formatPostfix != null)
- {
- // Done with postfix. The rest will be regular date word.
- formatPostfix = null;
- }
- // Reset the dateWord.
- dateWord.Length = 0;
- index++;
- } else
- {
- dateWord.Append(ch);
- index++;
- }
- }
- return (index);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // A simple helper to find the repeat count for a specified char.
- //
- ////////////////////////////////////////////////////////////////////////////
- internal static int ScanRepeatChar(String pattern, char ch, int index, out int count)
- {
- count = 1;
- while (++index < pattern.Length && pattern[index] == ch) {
- count++;
- }
- // Return the updated position.
- return (index);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Add the text that is a date separator but is treated like ignroable symbol.
- // E.g.
- // hu-HU has:
- // shrot date pattern: yyyy. MM. dd.;yyyy-MM-dd;yy-MM-dd
- // long date pattern: yyyy. MMMM d.
- // Here, "." is the date separator (derived from short date pattern). However,
- // "." also appear at the end of long date pattern. In this case, we just
- // "." as ignorable symbol so that the DateTime.Parse() state machine will not
- // treat the additional date separator at the end of y,m,d pattern as an error
- // condition.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal void AddIgnorableSymbols(String text)
- {
- if (m_dateWords == null)
- {
- // Create the date word array.
- m_dateWords = new List<String>();
- }
- // Add the ingorable symbol into the ArrayList.
- String temp = IgnorableSymbolChar + text;
- if (!m_dateWords.Contains(temp))
- {
- m_dateWords.Add(temp);
- }
- }
-
-
- //
- // Flag used to trace the date patterns (yy/yyyyy/M/MM/MMM/MMM/d/dd) that we have seen.
- //
- enum FoundDatePattern
- {
- None = 0x0000,
- FoundYearPatternFlag = 0x0001,
- FoundMonthPatternFlag = 0x0002,
- FoundDayPatternFlag = 0x0004,
- FoundYMDPatternFlag = 0x0007, // FoundYearPatternFlag | FoundMonthPatternFlag | FoundDayPatternFlag;
- }
-
- // Check if we have found all of the year/month/day pattern.
- FoundDatePattern m_ymdFlags = FoundDatePattern.None;
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Given a date format pattern, scan for date word or postfix.
- //
- // A date word should be always put in a single quoted string. And it will
- // start from a letter, so whitespace and symbols will be ignored before
- // the first letter.
- //
- // Examples of date word:
- // 'de' in es-SP: dddd, dd' de 'MMMM' de 'yyyy
- // "\x0443." in bg-BG: dd.M.yyyy '\x0433.'
- //
- // Example of postfix:
- // month postfix:
- // "ta" in fi-FI: d. MMMM'ta 'yyyy
- // Currently, only month postfix is supported.
- //
- // Usage:
- // Always call this with Framework-style pattern, instead of Windows style pattern.
- // Windows style pattern uses '' for single quote, while .NET uses \'
- //
- ////////////////////////////////////////////////////////////////////////////
- internal void ScanDateWord(String pattern)
- {
-
- // Check if we have found all of the year/month/day pattern.
- m_ymdFlags = FoundDatePattern.None;
-
- int i = 0;
- while (i < pattern.Length)
- {
- char ch = pattern[i];
- int chCount;
-
- switch (ch)
- {
- case '\'':
- // Find a beginning quote. Search until the end quote.
- i = AddDateWords(pattern, i+1, null);
- break;
- case 'M':
- i = ScanRepeatChar(pattern, 'M', i, out chCount);
- if (chCount >= 4)
- {
- if (i < pattern.Length && pattern[i] == '\'')
- {
- i = AddDateWords(pattern, i+1, "MMMM");
- }
- }
- m_ymdFlags |= FoundDatePattern.FoundMonthPatternFlag;
- break;
- case 'y':
- i = ScanRepeatChar(pattern, 'y', i, out chCount);
- m_ymdFlags |= FoundDatePattern.FoundYearPatternFlag;
- break;
- case 'd':
- i = ScanRepeatChar(pattern, 'd', i, out chCount);
- if (chCount <= 2)
- {
- // Only count "d" & "dd".
- // ddd, dddd are day names. Do not count them.
- m_ymdFlags |= FoundDatePattern.FoundDayPatternFlag;
- }
- break;
- case '\\':
- // Found a escaped char not in a quoted string. Skip the current backslash
- // and its next character.
- i += 2;
- break;
- case '.':
- if (m_ymdFlags == FoundDatePattern.FoundYMDPatternFlag)
- {
- // If we find a dot immediately after the we have seen all of the y, m, d pattern.
- // treat it as a ignroable symbol. Check for comments in AddIgnorableSymbols for
- // more details.
- AddIgnorableSymbols(".");
- m_ymdFlags = FoundDatePattern.None;
- }
- i++;
- break;
- default:
- if (m_ymdFlags == FoundDatePattern.FoundYMDPatternFlag && !Char.IsWhiteSpace(ch))
- {
- // We are not seeing "." after YMD. Clear the flag.
- m_ymdFlags = FoundDatePattern.None;
- }
- // We are not in quote. Skip the current character.
- i++;
- break;
- }
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Given a DTFI, get all of the date words from date patterns and time patterns.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal String[] GetDateWordsOfDTFI(DateTimeFormatInfo dtfi) {
- // Enumarate all LongDatePatterns, and get the DateWords and scan for month postfix.
- String[] datePatterns = dtfi.GetAllDateTimePatterns('D');
- int i;
-
- // Scan the long date patterns
- for (i = 0; i < datePatterns.Length; i++)
- {
- ScanDateWord(datePatterns[i]);
- }
-
- // Scan the short date patterns
- datePatterns = dtfi.GetAllDateTimePatterns('d');
- for (i = 0; i < datePatterns.Length; i++)
- {
- ScanDateWord(datePatterns[i]);
- }
- // Scan the YearMonth patterns.
- datePatterns = dtfi.GetAllDateTimePatterns('y');
- for (i = 0; i < datePatterns.Length; i++)
- {
- ScanDateWord(datePatterns[i]);
- }
-
- // Scan the month/day pattern
- ScanDateWord(dtfi.MonthDayPattern);
-
- // Scan the long time patterns.
- datePatterns = dtfi.GetAllDateTimePatterns('T');
- for (i = 0; i < datePatterns.Length; i++)
- {
- ScanDateWord(datePatterns[i]);
- }
-
- // Scan the short time patterns.
- datePatterns = dtfi.GetAllDateTimePatterns('t');
- for (i = 0; i < datePatterns.Length; i++)
- {
- ScanDateWord(datePatterns[i]);
- }
-
- String[] result = null;
- if (m_dateWords != null && m_dateWords.Count > 0)
- {
- result = new String[m_dateWords.Count];
- for (i = 0; i < m_dateWords.Count; i++)
- {
- result[i] = m_dateWords[i];
- }
- }
- return (result);
- }
-
-#if ADDITIONAL_DTFI_SCANNER_METHODS
- ////////////////////////////////////////////////////////////////////////////
- //
- // Reset the date word ArrayList
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal void Reset()
- {
- m_dateWords.RemoveRange(0, m_dateWords.Count);
- }
-#endif
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Scan the month names to see if genitive month names are used, and return
- // the format flag.
- //
- ////////////////////////////////////////////////////////////////////////////
- internal static FORMATFLAGS GetFormatFlagGenitiveMonth(String[] monthNames, String[] genitveMonthNames, String[] abbrevMonthNames, String[] genetiveAbbrevMonthNames)
- {
- // If we have different names in regular and genitive month names, use genitive month flag.
- return ((!EqualStringArrays(monthNames, genitveMonthNames) || !EqualStringArrays(abbrevMonthNames, genetiveAbbrevMonthNames))
- ? FORMATFLAGS.UseGenitiveMonth: 0);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Scan the month names to see if spaces are used or start with a digit, and return the format flag
- //
- ////////////////////////////////////////////////////////////////////////////
- internal static FORMATFLAGS GetFormatFlagUseSpaceInMonthNames(String[] monthNames, String[] genitveMonthNames, String[] abbrevMonthNames, String[] genetiveAbbrevMonthNames)
- {
- FORMATFLAGS formatFlags = 0;
- formatFlags |= (ArrayElementsBeginWithDigit(monthNames) ||
- ArrayElementsBeginWithDigit(genitveMonthNames) ||
- ArrayElementsBeginWithDigit(abbrevMonthNames) ||
- ArrayElementsBeginWithDigit(genetiveAbbrevMonthNames)
- ? FORMATFLAGS.UseDigitPrefixInTokens : 0);
-
- formatFlags |= (ArrayElementsHaveSpace(monthNames) ||
- ArrayElementsHaveSpace(genitveMonthNames) ||
- ArrayElementsHaveSpace(abbrevMonthNames) ||
- ArrayElementsHaveSpace(genetiveAbbrevMonthNames)
- ? FORMATFLAGS.UseSpacesInMonthNames : 0);
- return (formatFlags);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Scan the day names and set the correct format flag.
- //
- ////////////////////////////////////////////////////////////////////////////
- internal static FORMATFLAGS GetFormatFlagUseSpaceInDayNames(String[] dayNames, String[] abbrevDayNames)
- {
- return ((ArrayElementsHaveSpace(dayNames) ||
- ArrayElementsHaveSpace(abbrevDayNames))
- ? FORMATFLAGS.UseSpacesInDayNames : 0);
-
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Check the calendar to see if it is HebrewCalendar and set the Hebrew format flag if necessary.
- //
- ////////////////////////////////////////////////////////////////////////////
- internal static FORMATFLAGS GetFormatFlagUseHebrewCalendar(int calID)
- {
- return (calID == (int)CalendarId.HEBREW ?
- FORMATFLAGS.UseHebrewParsing | FORMATFLAGS.UseLeapYearMonth : 0);
- }
-
-
- //-----------------------------------------------------------------------------
- // EqualStringArrays
- // compares two string arrays and return true if all elements of the first
- // array equals to all elmentsof the second array.
- // otherwise it returns false.
- //-----------------------------------------------------------------------------
-
- private static bool EqualStringArrays(string [] array1, string [] array2)
- {
- // Shortcut if they're the same array
- if (array1 == array2)
- {
- return true;
- }
-
- // This is effectively impossible
- if (array1.Length != array2.Length)
- {
- return false;
- }
-
- // Check each string
- for (int i=0; i<array1.Length; i++)
- {
- if (!array1[i].Equals(array2[i]))
- {
- return false;
- }
- }
-
- return true;
- }
-
- //-----------------------------------------------------------------------------
- // ArrayElementsHaveSpace
- // It checks all input array elements if any of them has space character
- // returns true if found space character in one of the array elements.
- // otherwise returns false.
- //-----------------------------------------------------------------------------
-
- private static bool ArrayElementsHaveSpace(string [] array)
- {
-
- for (int i=0; i<array.Length; i++)
- {
- // it is faster to check for space character manually instead of calling IndexOf
- // so we don't have to go to native code side.
- for (int j=0; j<array[i].Length; j++)
- {
- if ( Char.IsWhiteSpace(array[i][j]) )
- {
- return true;
- }
- }
- }
-
- return false;
- }
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Check if any element of the array start with a digit.
- //
- ////////////////////////////////////////////////////////////////////////////
- private static bool ArrayElementsBeginWithDigit(string [] array)
- {
-
- for (int i=0; i<array.Length; i++)
- {
- // it is faster to check for space character manually instead of calling IndexOf
- // so we don't have to go to native code side.
- if (array[i].Length > 0 &&
- array[i][0] >= '0' && array[i][0] <= '9')
- {
- int index = 1;
- while (index < array[i].Length && array[i][index] >= '0' && array[i][index] <= '9')
- {
- // Skip other digits.
- index++;
- }
- if (index == array[i].Length)
- {
- return (false);
- }
-
- if (index == array[i].Length - 1)
- {
- // Skip known CJK month suffix.
- // CJK uses month name like "1\x6708", since \x6708 is a known month suffix,
- // we don't need the UseDigitPrefixInTokens since it is slower.
- switch (array[i][index])
- {
- case '\x6708': // CJKMonthSuff
- case '\xc6d4': // KoreanMonthSuff
- return (false);
- }
- }
-
- if (index == array[i].Length - 4)
- {
- // Skip known CJK month suffix.
- // Starting with Windows 8, the CJK months for some cultures looks like: "1' \x6708'"
- // instead of just "1\x6708"
- if(array[i][index] == '\'' && array[i][index + 1] == ' ' &&
- array[i][index + 2] == '\x6708' && array[i][index + 3] == '\'')
- {
- return (false);
- }
-
- }
- return (true);
- }
- }
-
- return false;
- }
-
- }
-}
-
diff --git a/src/mscorlib/src/System/Globalization/DateTimeParse.cs b/src/mscorlib/src/System/Globalization/DateTimeParse.cs
deleted file mode 100644
index 363747cfc3..0000000000
--- a/src/mscorlib/src/System/Globalization/DateTimeParse.cs
+++ /dev/null
@@ -1,5035 +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.
-
-////////////////////////////////////////////////////////////////////////////
-//
-//
-// Purpose: This class is called by DateTime to parse a date/time string.
-//
-////////////////////////////////////////////////////////////////////////////
-
-namespace System {
- using System;
- using System.Text;
- using System.Globalization;
- using System.Threading;
- using System.Collections;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
- using System.Security;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- ////////////////////////////////////////////////////////////////////////
-
- //This class contains only static members
-
- internal static
- class DateTimeParse {
-
- internal const Int32 MaxDateTimeNumberDigits = 8;
-
- internal delegate bool MatchNumberDelegate(ref __DTString str, int digitLen, out int result);
-
- internal static MatchNumberDelegate m_hebrewNumberParser = new MatchNumberDelegate(DateTimeParse.MatchHebrewDigits);
-
- internal static DateTime ParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style) {
- DateTimeResult result = new DateTimeResult(); // The buffer to store the parsing result.
- result.Init();
- if (TryParseExact(s, format, dtfi, style, ref result)) {
- return result.parsedDate;
- }
- else {
- throw GetDateTimeParseException(ref result);
- }
- }
-
- internal static DateTime ParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style, out TimeSpan offset) {
- DateTimeResult result = new DateTimeResult(); // The buffer to store the parsing result.
- offset = TimeSpan.Zero;
- result.Init();
- result.flags |= ParseFlags.CaptureOffset;
- if (TryParseExact(s, format, dtfi, style, ref result)) {
- offset = result.timeZoneOffset;
- return result.parsedDate;
- }
- else {
- throw GetDateTimeParseException(ref result);
- }
- }
-
- internal static bool TryParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style, out DateTime result) {
- result = DateTime.MinValue;
- DateTimeResult resultData = new DateTimeResult(); // The buffer to store the parsing result.
- resultData.Init();
- if (TryParseExact(s, format, dtfi, style, ref resultData)) {
- result = resultData.parsedDate;
- return true;
- }
- return false;
- }
-
- internal static bool TryParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style, out DateTime result, out TimeSpan offset) {
- result = DateTime.MinValue;
- offset = TimeSpan.Zero;
- DateTimeResult resultData = new DateTimeResult(); // The buffer to store the parsing result.
- resultData.Init();
- resultData.flags |= ParseFlags.CaptureOffset;
- if (TryParseExact(s, format, dtfi, style, ref resultData)) {
- result = resultData.parsedDate;
- offset = resultData.timeZoneOffset;
- return true;
- }
- return false;
- }
-
- internal static bool TryParseExact(String s, String format, DateTimeFormatInfo dtfi, DateTimeStyles style, ref DateTimeResult result) {
- if (s == null) {
- result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(s));
- return false;
- }
- if (format == null) {
- result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(format));
- return false;
- }
- if (s.Length == 0) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- if (format.Length == 0) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null);
- return false;
- }
-
- Debug.Assert(dtfi != null, "dtfi == null");
-
- return DoStrictParse(s, format, style, dtfi, ref result);
- }
-
- internal static DateTime ParseExactMultiple(String s, String[] formats,
- DateTimeFormatInfo dtfi, DateTimeStyles style) {
- DateTimeResult result = new DateTimeResult(); // The buffer to store the parsing result.
- result.Init();
- if (TryParseExactMultiple(s, formats, dtfi, style, ref result)) {
- return result.parsedDate;
- }
- else {
- throw GetDateTimeParseException(ref result);
- }
- }
-
-
- internal static DateTime ParseExactMultiple(String s, String[] formats,
- DateTimeFormatInfo dtfi, DateTimeStyles style, out TimeSpan offset) {
- DateTimeResult result = new DateTimeResult(); // The buffer to store the parsing result.
- offset = TimeSpan.Zero;
- result.Init();
- result.flags |= ParseFlags.CaptureOffset;
- if (TryParseExactMultiple(s, formats, dtfi, style, ref result)) {
- offset = result.timeZoneOffset;
- return result.parsedDate;
- }
- else {
- throw GetDateTimeParseException(ref result);
- }
- }
-
- internal static bool TryParseExactMultiple(String s, String[] formats,
- DateTimeFormatInfo dtfi, DateTimeStyles style, out DateTime result, out TimeSpan offset) {
- result = DateTime.MinValue;
- offset = TimeSpan.Zero;
- DateTimeResult resultData = new DateTimeResult(); // The buffer to store the parsing result.
- resultData.Init();
- resultData.flags |= ParseFlags.CaptureOffset;
- if (TryParseExactMultiple(s, formats, dtfi, style, ref resultData)) {
- result = resultData.parsedDate;
- offset = resultData.timeZoneOffset;
- return true;
- }
- return false;
- }
-
-
- internal static bool TryParseExactMultiple(String s, String[] formats,
- DateTimeFormatInfo dtfi, DateTimeStyles style, out DateTime result) {
- result = DateTime.MinValue;
- DateTimeResult resultData = new DateTimeResult(); // The buffer to store the parsing result.
- resultData.Init();
- if (TryParseExactMultiple(s, formats, dtfi, style, ref resultData)) {
- result = resultData.parsedDate;
- return true;
- }
- return false;
- }
-
- internal static bool TryParseExactMultiple(String s, String[] formats,
- DateTimeFormatInfo dtfi, DateTimeStyles style, ref DateTimeResult result) {
- if (s == null) {
- result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(s));
- return false;
- }
- if (formats == null) {
- result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(formats));
- return false;
- }
-
- if (s.Length == 0) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- if (formats.Length == 0) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null);
- return false;
- }
-
- Debug.Assert(dtfi != null, "dtfi == null");
-
- //
- // Do a loop through the provided formats and see if we can parse succesfully in
- // one of the formats.
- //
- for (int i = 0; i < formats.Length; i++) {
- if (formats[i] == null || formats[i].Length == 0) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null);
- return false;
- }
- // Create a new result each time to ensure the runs are independent. Carry through
- // flags from the caller and return the result.
- DateTimeResult innerResult = new DateTimeResult(); // The buffer to store the parsing result.
- innerResult.Init();
- innerResult.flags = result.flags;
- if (TryParseExact(s, formats[i], dtfi, style, ref innerResult)) {
- result.parsedDate = innerResult.parsedDate;
- result.timeZoneOffset = innerResult.timeZoneOffset;
- return (true);
- }
- }
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
-
- ////////////////////////////////////////////////////////////////////////////
- // Date Token Types
- //
- // Following is the set of tokens that can be generated from a date
- // string. Notice that the legal set of trailing separators have been
- // folded in with the date number, and month name tokens. This set
- // of tokens is chosen to reduce the number of date parse states.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal enum DTT: int {
-
- End = 0, // '\0'
- NumEnd = 1, // Num[ ]*[\0]
- NumAmpm = 2, // Num[ ]+AmPm
- NumSpace = 3, // Num[ ]+^[Dsep|Tsep|'0\']
- NumDatesep = 4, // Num[ ]*Dsep
- NumTimesep = 5, // Num[ ]*Tsep
- MonthEnd = 6, // Month[ ]*'\0'
- MonthSpace = 7, // Month[ ]+^[Dsep|Tsep|'\0']
- MonthDatesep = 8, // Month[ ]*Dsep
- NumDatesuff = 9, // Month[ ]*DSuff
- NumTimesuff = 10, // Month[ ]*TSuff
- DayOfWeek = 11, // Day of week name
- YearSpace = 12, // Year+^[Dsep|Tsep|'0\']
- YearDateSep = 13, // Year+Dsep
- YearEnd = 14, // Year+['\0']
- TimeZone = 15, // timezone name
- Era = 16, // era name
- NumUTCTimeMark = 17, // Num + 'Z'
- // When you add a new token which will be in the
- // state table, add it after NumLocalTimeMark.
- Unk = 18, // unknown
- NumLocalTimeMark = 19, // Num + 'T'
- Max = 20, // marker
- }
-
- internal enum TM {
- NotSet = -1,
- AM = 0,
- PM = 1,
- }
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // DateTime parsing state enumeration (DS.*)
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal enum DS {
- BEGIN = 0,
- N = 1, // have one number
- NN = 2, // have two numbers
-
- // The following are known to be part of a date
-
- D_Nd = 3, // date string: have number followed by date separator
- D_NN = 4, // date string: have two numbers
- D_NNd = 5, // date string: have two numbers followed by date separator
-
- D_M = 6, // date string: have a month
- D_MN = 7, // date string: have a month and a number
- D_NM = 8, // date string: have a number and a month
- D_MNd = 9, // date string: have a month and number followed by date separator
- D_NDS = 10, // date string: have one number followed a date suffix.
-
- D_Y = 11, // date string: have a year.
- D_YN = 12, // date string: have a year and a number
- D_YNd = 13, // date string: have a year and a number and a date separator
- D_YM = 14, // date string: have a year and a month
- D_YMd = 15, // date string: have a year and a month and a date separator
- D_S = 16, // have numbers followed by a date suffix.
- T_S = 17, // have numbers followed by a time suffix.
-
- // The following are known to be part of a time
-
- T_Nt = 18, // have num followed by time separator
- T_NNt = 19, // have two numbers followed by time separator
-
-
- ERROR = 20,
-
- // The following are terminal states. These all have an action
- // associated with them; and transition back to BEGIN.
-
- DX_NN = 21, // day from two numbers
- DX_NNN = 22, // day from three numbers
- DX_MN = 23, // day from month and one number
- DX_NM = 24, // day from month and one number
- DX_MNN = 25, // day from month and two numbers
- DX_DS = 26, // a set of date suffixed numbers.
- DX_DSN = 27, // day from date suffixes and one number.
- DX_NDS = 28, // day from one number and date suffixes .
- DX_NNDS = 29, // day from one number and date suffixes .
-
- DX_YNN = 30, // date string: have a year and two number
- DX_YMN = 31, // date string: have a year, a month, and a number.
- DX_YN = 32, // date string: have a year and one number
- DX_YM = 33, // date string: have a year, a month.
- TX_N = 34, // time from one number (must have ampm)
- TX_NN = 35, // time from two numbers
- TX_NNN = 36, // time from three numbers
- TX_TS = 37, // a set of time suffixed numbers.
- DX_NNY = 38,
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // NOTE: The following state machine table is dependent on the order of the
- // DS and DTT enumerations.
- //
- // For each non terminal state, the following table defines the next state
- // for each given date token type.
- //
- ////////////////////////////////////////////////////////////////////////////
-
-// End NumEnd NumAmPm NumSpace NumDaySep NumTimesep MonthEnd MonthSpace MonthDSep NumDateSuff NumTimeSuff DayOfWeek YearSpace YearDateSep YearEnd TimeZone Era UTCTimeMark
-private static DS[][] dateParsingStates = {
-// DS.BEGIN // DS.BEGIN
-new DS[] { DS.BEGIN, DS.ERROR, DS.TX_N, DS.N, DS.D_Nd, DS.T_Nt, DS.ERROR, DS.D_M, DS.D_M, DS.D_S, DS.T_S, DS.BEGIN, DS.D_Y, DS.D_Y, DS.ERROR, DS.BEGIN, DS.BEGIN, DS.ERROR},
-
-// DS.N // DS.N
-new DS[] { DS.ERROR, DS.DX_NN, DS.ERROR, DS.NN, DS.D_NNd, DS.ERROR, DS.DX_NM, DS.D_NM, DS.D_MNd, DS.D_NDS, DS.ERROR, DS.N, DS.D_YN, DS.D_YNd, DS.DX_YN, DS.N, DS.N, DS.ERROR},
-
-// DS.NN // DS.NN
-new DS[] { DS.DX_NN, DS.DX_NNN, DS.TX_N, DS.DX_NNN, DS.ERROR, DS.T_Nt, DS.DX_MNN, DS.DX_MNN, DS.ERROR, DS.ERROR, DS.T_S, DS.NN, DS.DX_NNY, DS.ERROR, DS.DX_NNY, DS.NN, DS.NN, DS.ERROR},
-
-// DS.D_Nd // DS.D_Nd
-new DS[] { DS.ERROR, DS.DX_NN, DS.ERROR, DS.D_NN, DS.D_NNd, DS.ERROR, DS.DX_NM, DS.D_MN, DS.D_MNd, DS.ERROR, DS.ERROR, DS.D_Nd, DS.D_YN, DS.D_YNd, DS.DX_YN, DS.ERROR, DS.D_Nd, DS.ERROR},
-
-// DS.D_NN // DS.D_NN
-new DS[] { DS.DX_NN, DS.DX_NNN, DS.TX_N, DS.DX_NNN, DS.ERROR, DS.T_Nt, DS.DX_MNN, DS.DX_MNN, DS.ERROR, DS.DX_DS, DS.T_S, DS.D_NN, DS.DX_NNY, DS.ERROR, DS.DX_NNY, DS.ERROR, DS.D_NN, DS.ERROR},
-
-// DS.D_NNd // DS.D_NNd
-new DS[] { DS.ERROR, DS.DX_NNN, DS.DX_NNN, DS.DX_NNN, DS.ERROR, DS.ERROR, DS.DX_MNN, DS.DX_MNN, DS.ERROR, DS.DX_DS, DS.ERROR, DS.D_NNd, DS.DX_NNY, DS.ERROR, DS.DX_NNY, DS.ERROR, DS.D_NNd, DS.ERROR},
-
-// DS.D_M // DS.D_M
-new DS[] { DS.ERROR, DS.DX_MN, DS.ERROR, DS.D_MN, DS.D_MNd, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_M, DS.D_YM, DS.D_YMd, DS.DX_YM, DS.ERROR, DS.D_M, DS.ERROR},
-
-// DS.D_MN // DS.D_MN
-new DS[] { DS.DX_MN, DS.DX_MNN, DS.DX_MNN, DS.DX_MNN, DS.ERROR, DS.T_Nt, DS.ERROR, DS.ERROR, DS.ERROR, DS.DX_DS, DS.T_S, DS.D_MN, DS.DX_YMN, DS.ERROR, DS.DX_YMN, DS.ERROR, DS.D_MN, DS.ERROR},
-
-// DS.D_NM // DS.D_NM
-new DS[] { DS.DX_NM, DS.DX_MNN, DS.DX_MNN, DS.DX_MNN, DS.ERROR, DS.T_Nt, DS.ERROR, DS.ERROR, DS.ERROR, DS.DX_DS, DS.T_S, DS.D_NM, DS.DX_YMN, DS.ERROR, DS.DX_YMN, DS.ERROR, DS.D_NM, DS.ERROR},
-
-// DS.D_MNd // DS.D_MNd
-new DS[] { DS.ERROR, DS.DX_MNN, DS.ERROR, DS.DX_MNN, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_MNd, DS.DX_YMN, DS.ERROR, DS.DX_YMN, DS.ERROR, DS.D_MNd, DS.ERROR},
-
-// DS.D_NDS, // DS.D_NDS,
-new DS[] { DS.DX_NDS,DS.DX_NNDS, DS.DX_NNDS, DS.DX_NNDS, DS.ERROR, DS.T_Nt, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_NDS, DS.T_S, DS.D_NDS, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_NDS, DS.ERROR},
-
-// DS.D_Y // DS.D_Y
-new DS[] { DS.ERROR, DS.DX_YN, DS.ERROR, DS.D_YN, DS.D_YNd, DS.ERROR, DS.DX_YM, DS.D_YM, DS.D_YMd, DS.D_YM, DS.ERROR, DS.D_Y, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_Y, DS.ERROR},
-
-// DS.D_YN // DS.D_YN
-new DS[] { DS.DX_YN, DS.DX_YNN, DS.DX_YNN, DS.DX_YNN, DS.ERROR, DS.ERROR, DS.DX_YMN, DS.DX_YMN, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YN, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YN, DS.ERROR},
-
-// DS.D_YNd // DS.D_YNd
-new DS[] { DS.ERROR, DS.DX_YNN, DS.DX_YNN, DS.DX_YNN, DS.ERROR, DS.ERROR, DS.DX_YMN, DS.DX_YMN, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YN, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YN, DS.ERROR},
-
-// DS.D_YM // DS.D_YM
-new DS[] { DS.DX_YM, DS.DX_YMN, DS.DX_YMN, DS.DX_YMN, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YM, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YM, DS.ERROR},
-
-// DS.D_YMd // DS.D_YMd
-new DS[] { DS.ERROR, DS.DX_YMN, DS.DX_YMN, DS.DX_YMN, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YM, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_YM, DS.ERROR},
-
-// DS.D_S // DS.D_S
-new DS[] { DS.DX_DS, DS.DX_DSN, DS.TX_N, DS.T_Nt, DS.ERROR, DS.T_Nt, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_S, DS.T_S, DS.D_S, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_S, DS.ERROR},
-
-// DS.T_S // DS.T_S
-new DS[] { DS.TX_TS, DS.TX_TS, DS.TX_TS, DS.T_Nt, DS.D_Nd, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.D_S, DS.T_S, DS.T_S, DS.ERROR, DS.ERROR, DS.ERROR, DS.T_S, DS.T_S, DS.ERROR},
-
-// DS.T_Nt // DS.T_Nt
-new DS[] { DS.ERROR, DS.TX_NN, DS.TX_NN, DS.TX_NN, DS.ERROR, DS.T_NNt, DS.DX_NM, DS.D_NM, DS.ERROR, DS.ERROR, DS.T_S, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.T_Nt, DS.T_Nt, DS.TX_NN},
-
-// DS.T_NNt // DS.T_NNt
-new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.ERROR, DS.T_S, DS.T_NNt, DS.ERROR, DS.ERROR, DS.ERROR, DS.T_NNt, DS.T_NNt, DS.TX_NNN},
-
-};
-// End NumEnd NumAmPm NumSpace NumDaySep NumTimesep MonthEnd MonthSpace MonthDSep NumDateSuff NumTimeSuff DayOfWeek YearSpace YearDateSep YearEnd TimeZone Era UTCMark
-
- internal const String GMTName = "GMT";
- internal const String ZuluName = "Z";
-
- //
- // Search from the index of str at str.Index to see if the target string exists in the str.
- //
- private static bool MatchWord(ref __DTString str, String target)
- {
- int length = target.Length;
- if (length > (str.Value.Length - str.Index)) {
- return false;
- }
-
- if (str.CompareInfo.Compare(str.Value, str.Index, length,
- target, 0, length, CompareOptions.IgnoreCase)!=0) {
- return (false);
- }
-
- int nextCharIndex = str.Index + target.Length;
-
- if (nextCharIndex < str.Value.Length) {
- char nextCh = str.Value[nextCharIndex];
- if (Char.IsLetter(nextCh)) {
- return (false);
- }
- }
- str.Index = nextCharIndex;
- if (str.Index < str.len) {
- str.m_current = str.Value[str.Index];
- }
-
- return (true);
- }
-
-
- //
- // Check the word at the current index to see if it matches GMT name or Zulu name.
- //
- private static bool GetTimeZoneName(ref __DTString str)
- {
- if (MatchWord(ref str, GMTName)) {
- return (true);
- }
-
- if (MatchWord(ref str, ZuluName)) {
- return (true);
- }
-
- return (false);
- }
-
- internal static bool IsDigit(char ch) {
- return (ch >= '0' && ch <= '9');
- }
-
-
- /*=================================ParseFraction==========================
- **Action: Starting at the str.Index, which should be a decimal symbol.
- ** if the current character is a digit, parse the remaining
- ** numbers as fraction. For example, if the sub-string starting at str.Index is "123", then
- ** the method will return 0.123
- **Returns: The fraction number.
- **Arguments:
- ** str the parsing string
- **Exceptions:
- ============================================================================*/
-
- private static bool ParseFraction(ref __DTString str, out double result) {
- result = 0;
- double decimalBase = 0.1;
- int digits = 0;
- char ch;
- while (str.GetNext()
- && IsDigit(ch = str.m_current)) {
- result += (ch - '0') * decimalBase;
- decimalBase *= 0.1;
- digits++;
- }
- return (digits > 0);
- }
-
- /*=================================ParseTimeZone==========================
- **Action: Parse the timezone offset in the following format:
- ** "+8", "+08", "+0800", "+0800"
- ** This method is used by DateTime.Parse().
- **Returns: The TimeZone offset.
- **Arguments:
- ** str the parsing string
- **Exceptions:
- ** FormatException if invalid timezone format is found.
- ============================================================================*/
-
- private static bool ParseTimeZone(ref __DTString str, ref TimeSpan result) {
- // The hour/minute offset for timezone.
- int hourOffset = 0;
- int minuteOffset = 0;
- DTSubString sub;
-
- // Consume the +/- character that has already been read
- sub = str.GetSubString();
- if (sub.length != 1) {
- return false;
- }
- char offsetChar = sub[0];
- if (offsetChar != '+' && offsetChar != '-') {
- return false;
- }
- str.ConsumeSubString(sub);
-
- sub = str.GetSubString();
- if (sub.type != DTSubStringType.Number) {
- return false;
- }
- int value = sub.value;
- int length = sub.length;
- if (length == 1 || length == 2) {
- // Parsing "+8" or "+08"
- hourOffset = value;
- str.ConsumeSubString(sub);
- // See if we have minutes
- sub = str.GetSubString();
- if (sub.length == 1 && sub[0] == ':') {
- // Parsing "+8:00" or "+08:00"
- str.ConsumeSubString(sub);
- sub = str.GetSubString();
- if (sub.type != DTSubStringType.Number || sub.length < 1 || sub.length > 2) {
- return false;
- }
- minuteOffset = sub.value;
- str.ConsumeSubString(sub);
- }
- }
- else if (length == 3 || length == 4) {
- // Parsing "+800" or "+0800"
- hourOffset = value / 100;
- minuteOffset = value % 100;
- str.ConsumeSubString(sub);
- }
- else {
- // Wrong number of digits
- return false;
- }
- Debug.Assert(hourOffset >= 0 && hourOffset <= 99, "hourOffset >= 0 && hourOffset <= 99");
- Debug.Assert(minuteOffset >= 0 && minuteOffset <= 99, "minuteOffset >= 0 && minuteOffset <= 99");
- if (minuteOffset < 0 || minuteOffset >= 60) {
- return false;
- }
-
- result = new TimeSpan(hourOffset, minuteOffset, 0);
- if (offsetChar == '-') {
- result = result.Negate();
- }
- return true;
- }
-
- // This is the helper function to handle timezone in string in the format like +/-0800
- private static bool HandleTimeZone(ref __DTString str, ref DateTimeResult result)
- {
- if ((str.Index < str.len - 1)) {
- char nextCh = str.Value[str.Index];
- // Skip whitespace, but don't update the index unless we find a time zone marker
- int whitespaceCount = 0;
- while (Char.IsWhiteSpace(nextCh) && str.Index + whitespaceCount < str.len - 1) {
- whitespaceCount++;
- nextCh = str.Value[str.Index + whitespaceCount];
- }
- if (nextCh == '+' || nextCh == '-') {
- str.Index += whitespaceCount;
- if ((result.flags & ParseFlags.TimeZoneUsed) != 0) {
- // Should not have two timezone offsets.
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- result.flags |= ParseFlags.TimeZoneUsed;
- if (!ParseTimeZone(ref str, ref result.timeZoneOffset)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- }
- }
- return true;
- }
-
- //
- // This is the lexer. Check the character at the current index, and put the found token in dtok and
- // some raw date/time information in raw.
- //
- private static Boolean Lex(DS dps, ref __DTString str, ref DateTimeToken dtok, ref DateTimeRawInfo raw, ref DateTimeResult result, ref DateTimeFormatInfo dtfi, DateTimeStyles styles)
- {
-
- TokenType tokenType;
- int tokenValue;
- int indexBeforeSeparator;
- char charBeforeSeparator;
-
- TokenType sep;
- dtok.dtt = DTT.Unk; // Assume the token is unkown.
-
- str.GetRegularToken(out tokenType, out tokenValue, dtfi);
-
-#if _LOGGING
- // Builds with _LOGGING defined (x86dbg, amd64chk, etc) support tracing
- // Set the following internal-only/unsupported environment variables to enable DateTime tracing to the console:
- //
- // COMPlus_LogEnable=1
- // COMPlus_LogToConsole=1
- // COMPlus_LogLevel=9
- // COMPlus_ManagedLogFacility=0x00001000
- if (_tracingEnabled) {
- BCLDebug.Trace("DATETIME", "[DATETIME] Lex({0})\tpos:{1}({2}), {3}, DS.{4}", Hex(str.Value),
- str.Index, Hex(str.m_current), tokenType, dps);
- }
-#endif // _LOGGING
-
- // Look at the regular token.
- switch (tokenType) {
- case TokenType.NumberToken:
- case TokenType.YearNumberToken:
- if (raw.numCount == 3 || tokenValue == -1) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0010", dps);
- return false;
- }
- //
- // This is a digit.
- //
- // If the previous parsing state is DS.T_NNt (like 12:01), and we got another number,
- // so we will have a terminal state DS.TX_NNN (like 12:01:02).
- // If the previous parsing state is DS.T_Nt (like 12:), and we got another number,
- // so we will have a terminal state DS.TX_NN (like 12:01).
- //
- // Look ahead to see if the following character is a decimal point or timezone offset.
- // This enables us to parse time in the forms of:
- // "11:22:33.1234" or "11:22:33-08".
- if (dps == DS.T_NNt) {
- if ((str.Index < str.len - 1)) {
- char nextCh = str.Value[str.Index];
- if (nextCh == '.') {
- // While ParseFraction can fail, it just means that there were no digits after
- // the dot. In this case ParseFraction just removes the dot. This is actually
- // valid for cultures like Albanian, that join the time marker to the time with
- // with a dot: e.g. "9:03.MD"
- ParseFraction(ref str, out raw.fraction);
- }
- }
- }
- if (dps == DS.T_NNt || dps == DS.T_Nt) {
- if ((str.Index < str.len - 1)) {
- if (false == HandleTimeZone(ref str, ref result))
- {
- LexTraceExit("0020 (value like \"12:01\" or \"12:\" followed by a non-TZ number", dps);
- return false;
- }
- }
- }
-
- dtok.num = tokenValue;
- if (tokenType == TokenType.YearNumberToken)
- {
- if (raw.year == -1)
- {
- raw.year = tokenValue;
- //
- // If we have number which has 3 or more digits (like "001" or "0001"),
- // we assume this number is a year. Save the currnet raw.numCount in
- // raw.year.
- //
- switch (sep = str.GetSeparatorToken(dtfi, out indexBeforeSeparator, out charBeforeSeparator)) {
- case TokenType.SEP_End:
- dtok.dtt = DTT.YearEnd;
- break;
- case TokenType.SEP_Am:
- case TokenType.SEP_Pm:
- if (raw.timeMark == TM.NotSet) {
- raw.timeMark = (sep == TokenType.SEP_Am ? TM.AM : TM.PM);
- dtok.dtt = DTT.YearSpace;
- } else {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0030 (TM.AM/TM.PM Happened more than 1x)", dps);
- }
- break;
- case TokenType.SEP_Space:
- dtok.dtt = DTT.YearSpace;
- break;
- case TokenType.SEP_Date:
- dtok.dtt = DTT.YearDateSep;
- break;
- case TokenType.SEP_Time:
- if (!raw.hasSameDateAndTimeSeparators)
- {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0040 (Invalid separator after number)", dps);
- return false;
- }
-
- // we have the date and time separators are same and getting a year number, then change the token to YearDateSep as
- // we are sure we are not parsing time.
- dtok.dtt = DTT.YearDateSep;
- break;
- case TokenType.SEP_DateOrOffset:
- // The separator is either a date separator or the start of a time zone offset. If the token will complete the date then
- // process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset.
- if ((dateParsingStates[(int)dps][(int) DTT.YearDateSep] == DS.ERROR)
- && (dateParsingStates[(int)dps][(int) DTT.YearSpace] > DS.ERROR)) {
- str.Index = indexBeforeSeparator;
- str.m_current = charBeforeSeparator;
- dtok.dtt = DTT.YearSpace;
- }
- else {
- dtok.dtt = DTT.YearDateSep;
- }
- break;
- case TokenType.SEP_YearSuff:
- case TokenType.SEP_MonthSuff:
- case TokenType.SEP_DaySuff:
- dtok.dtt = DTT.NumDatesuff;
- dtok.suffix = sep;
- break;
- case TokenType.SEP_HourSuff:
- case TokenType.SEP_MinuteSuff:
- case TokenType.SEP_SecondSuff:
- dtok.dtt = DTT.NumTimesuff;
- dtok.suffix = sep;
- break;
- default:
- // Invalid separator after number number.
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0040 (Invalid separator after number)", dps);
- return false;
- }
- //
- // Found the token already. Return now.
- //
- LexTraceExit("0050 (success)", dps);
- return true;
- }
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0060", dps);
- return false;
- }
- switch (sep = str.GetSeparatorToken(dtfi, out indexBeforeSeparator, out charBeforeSeparator))
- {
- //
- // Note here we check if the numCount is less than three.
- // When we have more than three numbers, it will be caught as error in the state machine.
- //
- case TokenType.SEP_End:
- dtok.dtt = DTT.NumEnd;
- raw.AddNumber(dtok.num);
- break;
- case TokenType.SEP_Am:
- case TokenType.SEP_Pm:
- if (raw.timeMark == TM.NotSet) {
- raw.timeMark = (sep == TokenType.SEP_Am ? TM.AM : TM.PM);
- dtok.dtt = DTT.NumAmpm;
- // Fix AM/PM parsing case, e.g. "1/10 5 AM"
- if (dps == DS.D_NN)
- {
- if (!ProcessTerminaltState(DS.DX_NN, ref result, ref styles, ref raw, dtfi))
- {
- return false;
- }
- }
-
- raw.AddNumber(dtok.num);
- } else {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- break;
- }
- if (dps == DS.T_NNt || dps == DS.T_Nt) {
- if (false == HandleTimeZone(ref str, ref result))
- {
- LexTraceExit("0070 (HandleTimeZone returned false)", dps);
- return false;
- }
- }
- break;
- case TokenType.SEP_Space:
- dtok.dtt = DTT.NumSpace;
- raw.AddNumber(dtok.num);
- break;
- case TokenType.SEP_Date:
- dtok.dtt = DTT.NumDatesep;
- raw.AddNumber(dtok.num);
- break;
- case TokenType.SEP_DateOrOffset:
- // The separator is either a date separator or the start of a time zone offset. If the token will complete the date then
- // process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset.
- if ((dateParsingStates[(int)dps][(int) DTT.NumDatesep] == DS.ERROR)
- && (dateParsingStates[(int)dps][(int) DTT.NumSpace] > DS.ERROR)) {
- str.Index = indexBeforeSeparator;
- str.m_current = charBeforeSeparator;
- dtok.dtt = DTT.NumSpace;
- }
- else {
- dtok.dtt = DTT.NumDatesep;
- }
- raw.AddNumber(dtok.num);
- break;
- case TokenType.SEP_Time:
- if (raw.hasSameDateAndTimeSeparators &&
- (dps == DS.D_Y || dps == DS.D_YN || dps == DS.D_YNd || dps == DS.D_YM || dps == DS.D_YMd))
- {
- // we are parsing a date and we have the time separator same as date separator, so we mark the token as date separator
- dtok.dtt = DTT.NumDatesep;
- raw.AddNumber(dtok.num);
- break;
- }
- dtok.dtt = DTT.NumTimesep;
- raw.AddNumber(dtok.num);
- break;
- case TokenType.SEP_YearSuff:
- try {
- dtok.num = dtfi.Calendar.ToFourDigitYear(tokenValue);
- }
- catch (ArgumentOutOfRangeException e) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", e);
- LexTraceExit("0075 (Calendar.ToFourDigitYear failed)", dps);
- return false;
- }
- dtok.dtt = DTT.NumDatesuff;
- dtok.suffix = sep;
- break;
- case TokenType.SEP_MonthSuff:
- case TokenType.SEP_DaySuff:
- dtok.dtt = DTT.NumDatesuff;
- dtok.suffix = sep;
- break;
- case TokenType.SEP_HourSuff:
- case TokenType.SEP_MinuteSuff:
- case TokenType.SEP_SecondSuff:
- dtok.dtt = DTT.NumTimesuff;
- dtok.suffix = sep;
- break;
- case TokenType.SEP_LocalTimeMark:
- dtok.dtt = DTT.NumLocalTimeMark;
- raw.AddNumber(dtok.num);
- break;
- default:
- // Invalid separator after number number.
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0080", dps);
- return false;
- }
- break;
- case TokenType.HebrewNumber:
- if (tokenValue >= 100) {
- // This is a year number
- if (raw.year == -1) {
- raw.year = tokenValue;
- //
- // If we have number which has 3 or more digits (like "001" or "0001"),
- // we assume this number is a year. Save the currnet raw.numCount in
- // raw.year.
- //
- switch (sep = str.GetSeparatorToken(dtfi, out indexBeforeSeparator, out charBeforeSeparator)) {
- case TokenType.SEP_End:
- dtok.dtt = DTT.YearEnd;
- break;
- case TokenType.SEP_Space:
- dtok.dtt = DTT.YearSpace;
- break;
- case TokenType.SEP_DateOrOffset:
- // The separator is either a date separator or the start of a time zone offset. If the token will complete the date then
- // process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset.
- if (dateParsingStates[(int)dps][(int) DTT.YearSpace] > DS.ERROR) {
- str.Index = indexBeforeSeparator;
- str.m_current = charBeforeSeparator;
- dtok.dtt = DTT.YearSpace;
- break;
- }
- goto default;
- default:
- // Invalid separator after number number.
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0090", dps);
- return false;
- }
- } else {
- // Invalid separator after number number.
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0100", dps);
- return false;
- }
- } else {
- // This is a day number
- dtok.num = tokenValue;
- raw.AddNumber(dtok.num);
-
- switch (sep = str.GetSeparatorToken(dtfi, out indexBeforeSeparator, out charBeforeSeparator)) {
- //
- // Note here we check if the numCount is less than three.
- // When we have more than three numbers, it will be caught as error in the state machine.
- //
- case TokenType.SEP_End:
- dtok.dtt = DTT.NumEnd;
- break;
- case TokenType.SEP_Space:
- case TokenType.SEP_Date:
- dtok.dtt = DTT.NumDatesep;
- break;
- case TokenType.SEP_DateOrOffset:
- // The separator is either a date separator or the start of a time zone offset. If the token will complete the date then
- // process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset.
- if ((dateParsingStates[(int)dps][(int) DTT.NumDatesep] == DS.ERROR)
- && (dateParsingStates[(int)dps][(int) DTT.NumSpace] > DS.ERROR)) {
- str.Index = indexBeforeSeparator;
- str.m_current = charBeforeSeparator;
- dtok.dtt = DTT.NumSpace;
- }
- else {
- dtok.dtt = DTT.NumDatesep;
- }
- break;
- default:
- // Invalid separator after number number.
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0110", dps);
- return false;
- }
- }
- break;
- case TokenType.DayOfWeekToken:
- if (raw.dayOfWeek == -1)
- {
- //
- // This is a day of week name.
- //
- raw.dayOfWeek = tokenValue;
- dtok.dtt = DTT.DayOfWeek;
- } else {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0120 (DayOfWeek seen more than 1x)", dps);
- return false;
- }
- break;
- case TokenType.MonthToken:
- if (raw.month == -1)
- {
- //
- // This is a month name
- //
- switch(sep=str.GetSeparatorToken(dtfi, out indexBeforeSeparator, out charBeforeSeparator))
- {
- case TokenType.SEP_End:
- dtok.dtt = DTT.MonthEnd;
- break;
- case TokenType.SEP_Space:
- dtok.dtt = DTT.MonthSpace;
- break;
- case TokenType.SEP_Date:
- dtok.dtt = DTT.MonthDatesep;
- break;
- case TokenType.SEP_Time:
- if (!raw.hasSameDateAndTimeSeparators)
- {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0130 (Invalid separator after month name)", dps);
- return false;
- }
-
- // we have the date and time separators are same and getting a Month name, then change the token to MonthDatesep as
- // we are sure we are not parsing time.
- dtok.dtt = DTT.MonthDatesep;
- break;
- case TokenType.SEP_DateOrOffset:
- // The separator is either a date separator or the start of a time zone offset. If the token will complete the date then
- // process just the number and roll back the index so that the outer loop can attempt to parse the time zone offset.
- if ((dateParsingStates[(int)dps][(int) DTT.MonthDatesep] == DS.ERROR)
- && (dateParsingStates[(int)dps][(int) DTT.MonthSpace] > DS.ERROR)) {
- str.Index = indexBeforeSeparator;
- str.m_current = charBeforeSeparator;
- dtok.dtt = DTT.MonthSpace;
- }
- else {
- dtok.dtt = DTT.MonthDatesep;
- }
- break;
- default:
- //Invalid separator after month name
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0130 (Invalid separator after month name)", dps);
- return false;
- }
- raw.month = tokenValue;
- } else {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0140 (MonthToken seen more than 1x)", dps);
- return false;
- }
- break;
- case TokenType.EraToken:
- if (result.era != -1) {
- result.era = tokenValue;
- dtok.dtt = DTT.Era;
- } else {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0150 (EraToken seen when result.era already set)", dps);
- return false;
- }
- break;
- case TokenType.JapaneseEraToken:
- // Special case for Japanese. We allow Japanese era name to be used even if the calendar is not Japanese Calendar.
- result.calendar = JapaneseCalendar.GetDefaultInstance();
- dtfi = DateTimeFormatInfo.GetJapaneseCalendarDTFI();
- if (result.era != -1) {
- result.era = tokenValue;
- dtok.dtt = DTT.Era;
- } else {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0160 (JapaneseEraToken seen when result.era already set)", dps);
- return false;
- }
- break;
- case TokenType.TEraToken:
- result.calendar = TaiwanCalendar.GetDefaultInstance();
- dtfi = DateTimeFormatInfo.GetTaiwanCalendarDTFI();
- if (result.era != -1) {
- result.era = tokenValue;
- dtok.dtt = DTT.Era;
- } else {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0170 (TEraToken seen when result.era already set)", dps);
- return false;
- }
- break;
- case TokenType.TimeZoneToken:
- //
- // This is a timezone designator
- //
- // NOTENOTE : for now, we only support "GMT" and "Z" (for Zulu time).
- //
- if ((result.flags & ParseFlags.TimeZoneUsed) != 0) {
- // Should not have two timezone offsets.
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0180 (seen GMT or Z more than 1x)", dps);
- return false;
- }
- dtok.dtt = DTT.TimeZone;
- result.flags |= ParseFlags.TimeZoneUsed;
- result.timeZoneOffset = new TimeSpan(0);
- result.flags |= ParseFlags.TimeZoneUtc;
- break;
- case TokenType.EndOfString:
- dtok.dtt = DTT.End;
- break;
- case TokenType.DateWordToken:
- case TokenType.IgnorableSymbol:
- // Date words and ignorable symbols can just be skipped over
- break;
- case TokenType.Am:
- case TokenType.Pm:
- if (raw.timeMark == TM.NotSet) {
- raw.timeMark = (TM)tokenValue;
- } else {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0190 (AM/PM timeMark already set)", dps);
- return false;
- }
- break;
- case TokenType.UnknownToken:
- if (Char.IsLetter(str.m_current)) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_UnknowDateTimeWord", str.Index);
- LexTraceExit("0200", dps);
- return (false);
- }
-
- if ((str.m_current == '-' || str.m_current == '+') && ((result.flags & ParseFlags.TimeZoneUsed) == 0)) {
- Int32 originalIndex = str.Index;
- if (ParseTimeZone(ref str, ref result.timeZoneOffset)) {
- result.flags |= ParseFlags.TimeZoneUsed;
- LexTraceExit("0220 (success)", dps);
- return true;
- }
- else {
- // Time zone parse attempt failed. Fall through to punctuation handling.
- str.Index = originalIndex;
- }
- }
-
- // Visual Basic implements string to date conversions on top of DateTime.Parse:
- // CDate("#10/10/95#")
- //
- if (VerifyValidPunctuation(ref str)) {
- LexTraceExit("0230 (success)", dps);
- return true;
- }
-
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- LexTraceExit("0240", dps);
- return false;
- }
-
- LexTraceExit("0250 (success)", dps);
- return true;
- }
-
- private static Boolean VerifyValidPunctuation(ref __DTString str) {
- // Compatability Behavior. Allow trailing nulls and surrounding hashes
- Char ch = str.Value[str.Index];
- if (ch == '#') {
- bool foundStart = false;
- bool foundEnd = false;
- for (int i = 0; i < str.len; i++) {
- ch = str.Value[i];
- if (ch == '#') {
- if (foundStart) {
- if (foundEnd) {
- // Having more than two hashes is invalid
- return false;
- }
- else {
- foundEnd = true;
- }
- }
- else {
- foundStart = true;
- }
- }
- else if (ch == '\0') {
- // Allow nulls only at the end
- if (!foundEnd) {
- return false;
- }
- }
- else if ((!Char.IsWhiteSpace(ch))) {
- // Anthyhing other than whitespace outside hashes is invalid
- if (!foundStart || foundEnd) {
- return false;
- }
- }
- }
- if (!foundEnd) {
- // The has was un-paired
- return false;
- }
- // Valid Hash usage: eat the hash and continue.
- str.GetNext();
- return true;
- }
- else if (ch == '\0') {
- for (int i = str.Index; i < str.len; i++) {
- if (str.Value[i] != '\0') {
- // Nulls are only valid if they are the only trailing character
- return false;
- }
- }
- // Move to the end of the string
- str.Index = str.len;
- return true;
- }
- return false;
- }
-
- private const int ORDER_YMD = 0; // The order of date is Year/Month/Day.
- private const int ORDER_MDY = 1; // The order of date is Month/Day/Year.
- private const int ORDER_DMY = 2; // The order of date is Day/Month/Year.
- private const int ORDER_YDM = 3; // The order of date is Year/Day/Month
- private const int ORDER_YM = 4; // Year/Month order.
- private const int ORDER_MY = 5; // Month/Year order.
- private const int ORDER_MD = 6; // Month/Day order.
- private const int ORDER_DM = 7; // Day/Month order.
-
- //
- // Decide the year/month/day order from the datePattern.
- //
- // Return 0 for YMD, 1 for MDY, 2 for DMY, otherwise -1.
- //
- private static Boolean GetYearMonthDayOrder(String datePattern, DateTimeFormatInfo dtfi, out int order)
- {
- int yearOrder = -1;
- int monthOrder = -1;
- int dayOrder = -1;
- int orderCount = 0;
-
- bool inQuote = false;
-
- for (int i = 0; i < datePattern.Length && orderCount < 3; i++)
- {
- char ch = datePattern[i];
- if (ch == '\\' || ch == '%')
- {
- i++;
- continue; // Skip next character that is escaped by this backslash
- }
-
- if (ch == '\'' || ch == '"')
- {
- inQuote = !inQuote;
- }
-
- if (!inQuote)
- {
- if (ch == 'y')
- {
- yearOrder = orderCount++;
-
- //
- // Skip all year pattern charaters.
- //
- for(; i+1 < datePattern.Length && datePattern[i+1] == 'y'; i++)
- {
- // Do nothing here.
- }
- }
- else if (ch == 'M')
- {
- monthOrder = orderCount++;
- //
- // Skip all month pattern characters.
- //
- for(; i+1 < datePattern.Length && datePattern[i+1] == 'M'; i++)
- {
- // Do nothing here.
- }
- }
- else if (ch == 'd')
- {
-
- int patternCount = 1;
- //
- // Skip all day pattern characters.
- //
- for(; i+1 < datePattern.Length && datePattern[i+1] == 'd'; i++)
- {
- patternCount++;
- }
- //
- // Make sure this is not "ddd" or "dddd", which means day of week.
- //
- if (patternCount <= 2)
- {
- dayOrder = orderCount++;
- }
- }
- }
- }
-
- if (yearOrder == 0 && monthOrder == 1 && dayOrder == 2)
- {
- order = ORDER_YMD;
- return true;
- }
- if (monthOrder == 0 && dayOrder == 1 && yearOrder == 2)
- {
- order = ORDER_MDY;
- return true;
- }
- if (dayOrder == 0 && monthOrder == 1 && yearOrder == 2)
- {
- order = ORDER_DMY;
- return true;
- }
- if (yearOrder == 0 && dayOrder == 1 && monthOrder == 2)
- {
- order = ORDER_YDM;
- return true;
- }
- order = -1;
- return false;
- }
-
- //
- // Decide the year/month order from the pattern.
- //
- // Return 0 for YM, 1 for MY, otherwise -1.
- //
- private static Boolean GetYearMonthOrder(String pattern, DateTimeFormatInfo dtfi, out int order)
- {
- int yearOrder = -1;
- int monthOrder = -1;
- int orderCount = 0;
-
- bool inQuote = false;
- for (int i = 0; i < pattern.Length && orderCount < 2; i++)
- {
- char ch = pattern[i];
- if (ch == '\\' || ch == '%')
- {
- i++;
- continue; // Skip next character that is escaped by this backslash
- }
-
- if (ch == '\'' || ch == '"')
- {
- inQuote = !inQuote;
- }
-
- if (!inQuote)
- {
- if (ch == 'y')
- {
- yearOrder = orderCount++;
-
- //
- // Skip all year pattern charaters.
- //
- for(; i+1 < pattern.Length && pattern[i+1] == 'y'; i++)
- {
- }
- }
- else if (ch == 'M')
- {
- monthOrder = orderCount++;
- //
- // Skip all month pattern characters.
- //
- for(; i+1 < pattern.Length && pattern[i+1] == 'M'; i++)
- {
- }
- }
- }
- }
-
- if (yearOrder == 0 && monthOrder == 1)
- {
- order = ORDER_YM;
- return true;
- }
- if (monthOrder == 0 && yearOrder == 1)
- {
- order = ORDER_MY;
- return true;
- }
- order = -1;
- return false;
- }
-
- //
- // Decide the month/day order from the pattern.
- //
- // Return 0 for MD, 1 for DM, otherwise -1.
- //
- private static Boolean GetMonthDayOrder(String pattern, DateTimeFormatInfo dtfi, out int order)
- {
- int monthOrder = -1;
- int dayOrder = -1;
- int orderCount = 0;
-
- bool inQuote = false;
- for (int i = 0; i < pattern.Length && orderCount < 2; i++)
- {
- char ch = pattern[i];
- if (ch == '\\' || ch == '%')
- {
- i++;
- continue; // Skip next character that is escaped by this backslash
- }
-
- if (ch == '\'' || ch == '"')
- {
- inQuote = !inQuote;
- }
-
- if (!inQuote)
- {
- if (ch == 'd')
- {
- int patternCount = 1;
- //
- // Skip all day pattern charaters.
- //
- for(; i+1 < pattern.Length && pattern[i+1] == 'd'; i++)
- {
- patternCount++;
- }
-
- //
- // Make sure this is not "ddd" or "dddd", which means day of week.
- //
- if (patternCount <= 2)
- {
- dayOrder = orderCount++;
- }
-
- }
- else if (ch == 'M')
- {
- monthOrder = orderCount++;
- //
- // Skip all month pattern characters.
- //
- for(; i+1 < pattern.Length && pattern[i+1] == 'M'; i++)
- {
- }
- }
- }
- }
-
- if (monthOrder == 0 && dayOrder == 1)
- {
- order = ORDER_MD;
- return true;
- }
- if (dayOrder == 0 && monthOrder == 1)
- {
- order = ORDER_DM;
- return true;
- }
- order = -1;
- return false;
- }
-
- //
- // Adjust the two-digit year if necessary.
- //
- private static bool TryAdjustYear(ref DateTimeResult result, int year, out int adjustedYear)
- {
- if (year < 100)
- {
- try {
- // the Calendar classes need some real work. Many of the calendars that throw
- // don't implement a fast/non-allocating (and non-throwing) IsValid{Year|Day|Month} method.
- // we are making a targeted try/catch fix in the in-place release but will revisit this code
- // in the next side-by-side release.
- year = result.calendar.ToFourDigitYear(year);
- }
- catch (ArgumentOutOfRangeException) {
- adjustedYear = -1;
- return false;
- }
- }
- adjustedYear = year;
- return true;
- }
-
- private static bool SetDateYMD(ref DateTimeResult result, int year, int month, int day)
- {
- // Note, longer term these checks should be done at the end of the parse. This current
- // way of checking creates order dependence with parsing the era name.
- if (result.calendar.IsValidDay(year, month, day, result.era))
- {
- result.SetDate(year, month, day); // YMD
- return (true);
- }
- return (false);
- }
-
- private static bool SetDateMDY(ref DateTimeResult result, int month, int day, int year)
- {
- return (SetDateYMD(ref result, year, month, day));
- }
-
- private static bool SetDateDMY(ref DateTimeResult result, int day, int month, int year)
- {
- return (SetDateYMD(ref result, year, month, day));
- }
-
- private static bool SetDateYDM(ref DateTimeResult result, int year, int day, int month)
- {
- return (SetDateYMD(ref result, year, month, day));
- }
-
- private static void GetDefaultYear(ref DateTimeResult result, ref DateTimeStyles styles) {
- result.Year = result.calendar.GetYear(GetDateTimeNow(ref result, ref styles));
- result.flags |= ParseFlags.YearDefault;
- }
-
- // Processing teriminal case: DS.DX_NN
- private static Boolean GetDayOfNN(ref DateTimeResult result, ref DateTimeStyles styles, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi) {
-
- if ((result.flags & ParseFlags.HaveDate) != 0) {
- // Multiple dates in the input string
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- int n1 = raw.GetNumber(0);
- int n2 = raw.GetNumber(1);
-
- GetDefaultYear(ref result, ref styles);
-
- int order;
- if (!GetMonthDayOrder(dtfi.MonthDayPattern, dtfi, out order)) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.MonthDayPattern);
- return false;
- }
-
- if (order == ORDER_MD)
- {
- if (SetDateYMD(ref result, result.Year, n1, n2)) // MD
- {
- result.flags |= ParseFlags.HaveDate;
- return true;
- }
- } else {
- // ORDER_DM
- if (SetDateYMD(ref result, result.Year, n2, n1)) // DM
- {
- result.flags |= ParseFlags.HaveDate;
- return true;
- }
- }
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- // Processing teriminal case: DS.DX_NNN
- private static Boolean GetDayOfNNN(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
- {
- if ((result.flags & ParseFlags.HaveDate) != 0) {
- // Multiple dates in the input string
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- int n1 = raw.GetNumber(0);
- int n2 = raw.GetNumber(1);;
- int n3 = raw.GetNumber(2);
-
- int order;
- if (!GetYearMonthDayOrder(dtfi.ShortDatePattern, dtfi, out order)) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.ShortDatePattern);
- return false;
- }
- int year;
-
- if (order == ORDER_YMD) {
- if (TryAdjustYear(ref result, n1, out year) && SetDateYMD(ref result, year, n2, n3)) // YMD
- {
- result.flags |= ParseFlags.HaveDate;
- return true;
- }
- } else if (order == ORDER_MDY) {
- if (TryAdjustYear(ref result, n3, out year) && SetDateMDY(ref result, n1, n2, year)) // MDY
- {
- result.flags |= ParseFlags.HaveDate;
- return true;
- }
- } else if (order == ORDER_DMY) {
- if (TryAdjustYear(ref result, n3, out year) && SetDateDMY(ref result, n1, n2, year)) // DMY
- {
- result.flags |= ParseFlags.HaveDate;
- return true;
- }
- } else if (order == ORDER_YDM) {
- if (TryAdjustYear(ref result, n1, out year) && SetDateYDM(ref result, year, n2, n3)) // YDM
- {
- result.flags |= ParseFlags.HaveDate;
- return true;
- }
- }
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- private static Boolean GetDayOfMN(ref DateTimeResult result, ref DateTimeStyles styles, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi) {
-
- if ((result.flags & ParseFlags.HaveDate) != 0) {
- // Multiple dates in the input string
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- // The interpretation is based on the MonthDayPattern and YearMonthPattern
- //
- // MonthDayPattern YearMonthPattern Interpretation
- // --------------- ---------------- ---------------
- // MMMM dd MMMM yyyy Day
- // MMMM dd yyyy MMMM Day
- // dd MMMM MMMM yyyy Year
- // dd MMMM yyyy MMMM Day
- //
- // In the first and last cases, it could be either or neither, but a day is a better default interpretation
- // than a 2 digit year.
-
- int monthDayOrder;
- if (!GetMonthDayOrder(dtfi.MonthDayPattern, dtfi, out monthDayOrder)) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.MonthDayPattern);
- return false;
- }
- if (monthDayOrder == ORDER_DM) {
- int yearMonthOrder;
- if (!GetYearMonthOrder(dtfi.YearMonthPattern, dtfi, out yearMonthOrder)) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.YearMonthPattern);
- return false;
- }
- if (yearMonthOrder == ORDER_MY) {
- int year;
- if (!TryAdjustYear(ref result, raw.GetNumber(0), out year) || !SetDateYMD(ref result, year, raw.month, 1)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- return true;
- }
- }
-
- GetDefaultYear(ref result, ref styles);
- if (!SetDateYMD(ref result, result.Year, raw.month, raw.GetNumber(0))) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- return true;
-
- }
-
- ////////////////////////////////////////////////////////////////////////
- // Actions:
- // Deal with the terminal state for Hebrew Month/Day pattern
- //
- ////////////////////////////////////////////////////////////////////////
-
- private static Boolean GetHebrewDayOfNM(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
- {
- int monthDayOrder;
- if (!GetMonthDayOrder(dtfi.MonthDayPattern, dtfi, out monthDayOrder)) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.MonthDayPattern);
- return false;
- }
- result.Month = raw.month;
- if (monthDayOrder == ORDER_DM || monthDayOrder == ORDER_MD)
- {
- if (result.calendar.IsValidDay(result.Year, result.Month, raw.GetNumber(0), result.era))
- {
- result.Day = raw.GetNumber(0);
- return true;
- }
- }
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- private static Boolean GetDayOfNM(ref DateTimeResult result, ref DateTimeStyles styles, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
- {
- if ((result.flags & ParseFlags.HaveDate) != 0) {
- // Multiple dates in the input string
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- // The interpretation is based on the MonthDayPattern and YearMonthPattern
- //
- // MonthDayPattern YearMonthPattern Interpretation
- // --------------- ---------------- ---------------
- // MMMM dd MMMM yyyy Day
- // MMMM dd yyyy MMMM Year
- // dd MMMM MMMM yyyy Day
- // dd MMMM yyyy MMMM Day
- //
- // In the first and last cases, it could be either or neither, but a day is a better default interpretation
- // than a 2 digit year.
-
- int monthDayOrder;
- if (!GetMonthDayOrder(dtfi.MonthDayPattern, dtfi, out monthDayOrder)) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.MonthDayPattern);
- return false;
- }
- if (monthDayOrder == ORDER_MD) {
- int yearMonthOrder;
- if (!GetYearMonthOrder(dtfi.YearMonthPattern, dtfi, out yearMonthOrder)) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.YearMonthPattern);
- return false;
- }
- if (yearMonthOrder == ORDER_YM) {
- int year;
- if (!TryAdjustYear(ref result, raw.GetNumber(0), out year) || !SetDateYMD(ref result, year, raw.month, 1)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- return true;
- }
- }
-
- GetDefaultYear(ref result, ref styles);
- if (!SetDateYMD(ref result, result.Year, raw.month, raw.GetNumber(0))) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- return true;
- }
-
- private static Boolean GetDayOfMNN(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
- {
- if ((result.flags & ParseFlags.HaveDate) != 0) {
- // Multiple dates in the input string
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- int n1 = raw.GetNumber(0);
- int n2 = raw.GetNumber(1);
-
- int order;
- if (!GetYearMonthDayOrder(dtfi.ShortDatePattern, dtfi, out order)) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.ShortDatePattern);
- return false;
- }
- int year;
-
- if (order == ORDER_MDY)
- {
- if (TryAdjustYear(ref result, n2, out year) && result.calendar.IsValidDay(year, raw.month, n1, result.era))
- {
- result.SetDate(year, raw.month, n1); // MDY
- result.flags |= ParseFlags.HaveDate;
- return true;
- }
- else if (TryAdjustYear(ref result, n1, out year) && result.calendar.IsValidDay(year, raw.month, n2, result.era))
- {
- result.SetDate(year, raw.month, n2); // YMD
- result.flags |= ParseFlags.HaveDate;
- return true;
- }
- }
- else if (order == ORDER_YMD)
- {
- if (TryAdjustYear(ref result, n1, out year) && result.calendar.IsValidDay(year, raw.month, n2, result.era))
- {
- result.SetDate(year, raw.month, n2); // YMD
- result.flags |= ParseFlags.HaveDate;
- return true;
- }
- else if (TryAdjustYear(ref result, n2, out year) && result.calendar.IsValidDay(year, raw.month, n1, result.era))
- {
- result.SetDate(year, raw.month, n1); // DMY
- result.flags |= ParseFlags.HaveDate;
- return true;
- }
- }
- else if (order == ORDER_DMY)
- {
- if (TryAdjustYear(ref result, n2, out year) && result.calendar.IsValidDay(year, raw.month, n1, result.era))
- {
- result.SetDate(year, raw.month, n1); // DMY
- result.flags |= ParseFlags.HaveDate;
- return true;
- }
- else if (TryAdjustYear(ref result, n1, out year) && result.calendar.IsValidDay(year, raw.month, n2, result.era))
- {
- result.SetDate(year, raw.month, n2); // YMD
- result.flags |= ParseFlags.HaveDate;
- return true;
- }
- }
-
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- private static Boolean GetDayOfYNN(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi) {
-
- if ((result.flags & ParseFlags.HaveDate) != 0) {
- // Multiple dates in the input string
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- int n1 = raw.GetNumber(0);
- int n2 = raw.GetNumber(1);
- String pattern = dtfi.ShortDatePattern;
-
- // For compatibility, don't throw if we can't determine the order, but default to YMD instead
- int order;
- if (GetYearMonthDayOrder(pattern, dtfi, out order) && order == ORDER_YDM) {
- if (SetDateYMD(ref result, raw.year, n2, n1)) {
- result.flags |= ParseFlags.HaveDate;
- return true; // Year + DM
- }
- }
- else {
- if (SetDateYMD(ref result, raw.year, n1, n2)) {
- result.flags |= ParseFlags.HaveDate;
- return true; // Year + MD
- }
- }
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- private static Boolean GetDayOfNNY(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi) {
-
- if ((result.flags & ParseFlags.HaveDate) != 0) {
- // Multiple dates in the input string
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- int n1 = raw.GetNumber(0);
- int n2 = raw.GetNumber(1);
-
- int order;
- if (!GetYearMonthDayOrder(dtfi.ShortDatePattern, dtfi, out order)) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.ShortDatePattern);
- return false;
- }
-
- if (order == ORDER_MDY || order == ORDER_YMD) {
- if (SetDateYMD(ref result, raw.year, n1, n2)) {
- result.flags |= ParseFlags.HaveDate;
- return true; // MD + Year
- }
- } else {
- if (SetDateYMD(ref result, raw.year, n2, n1)) {
- result.flags |= ParseFlags.HaveDate;
- return true; // DM + Year
- }
- }
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
-
- private static Boolean GetDayOfYMN(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi) {
-
- if ((result.flags & ParseFlags.HaveDate) != 0) {
- // Multiple dates in the input string
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- if (SetDateYMD(ref result, raw.year, raw.month, raw.GetNumber(0))) {
- result.flags |= ParseFlags.HaveDate;
- return true;
- }
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- private static Boolean GetDayOfYN(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
- {
- if ((result.flags & ParseFlags.HaveDate) != 0) {
- // Multiple dates in the input string
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- if (SetDateYMD(ref result, raw.year, raw.GetNumber(0), 1))
- {
- result.flags |= ParseFlags.HaveDate;
- return true;
- }
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- private static Boolean GetDayOfYM(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
- {
- if ((result.flags & ParseFlags.HaveDate) != 0) {
- // Multiple dates in the input string
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- if (SetDateYMD(ref result, raw.year, raw.month, 1))
- {
- result.flags |= ParseFlags.HaveDate;
- return true;
- }
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- private static void AdjustTimeMark(DateTimeFormatInfo dtfi, ref DateTimeRawInfo raw) {
- // Specail case for culture which uses AM as empty string.
- // E.g. af-ZA (0x0436)
- // S1159 \x0000
- // S2359 nm
- // In this case, if we are parsing a string like "2005/09/14 12:23", we will assume this is in AM.
-
- if (raw.timeMark == TM.NotSet) {
- if (dtfi.AMDesignator != null && dtfi.PMDesignator != null) {
- if (dtfi.AMDesignator.Length == 0 && dtfi.PMDesignator.Length != 0) {
- raw.timeMark = TM.AM;
- }
- if (dtfi.PMDesignator.Length == 0 && dtfi.AMDesignator.Length != 0) {
- raw.timeMark = TM.PM;
- }
- }
- }
- }
-
- //
- // Adjust hour according to the time mark.
- //
- private static Boolean AdjustHour(ref int hour, TM timeMark) {
- if (timeMark != TM.NotSet) {
-
- if (timeMark == TM.AM) {
- if (hour < 0 || hour > 12) {
- return false;
- }
- hour = (hour == 12) ? 0 : hour;
- }
- else {
- if (hour < 0 || hour > 23) {
- return false;
- }
- if (hour < 12) {
- hour += 12;
- }
- }
- }
- return true;
- }
-
- private static Boolean GetTimeOfN(DateTimeFormatInfo dtfi, ref DateTimeResult result, ref DateTimeRawInfo raw)
- {
- if ((result.flags & ParseFlags.HaveTime) != 0) {
- // Multiple times in the input string
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- //
- // In this case, we need a time mark. Check if so.
- //
- if (raw.timeMark == TM.NotSet)
- {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- result.Hour = raw.GetNumber(0);
- result.flags |= ParseFlags.HaveTime;
- return true;
- }
-
- private static Boolean GetTimeOfNN(DateTimeFormatInfo dtfi, ref DateTimeResult result, ref DateTimeRawInfo raw)
- {
- Debug.Assert(raw.numCount >= 2, "raw.numCount >= 2");
- if ((result.flags & ParseFlags.HaveTime) != 0) {
- // Multiple times in the input string
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- result.Hour = raw.GetNumber(0);
- result.Minute = raw.GetNumber(1);
- result.flags |= ParseFlags.HaveTime;
- return true;
- }
-
- private static Boolean GetTimeOfNNN(DateTimeFormatInfo dtfi, ref DateTimeResult result, ref DateTimeRawInfo raw)
- {
- if ((result.flags & ParseFlags.HaveTime) != 0) {
- // Multiple times in the input string
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- Debug.Assert(raw.numCount >= 3, "raw.numCount >= 3");
- result.Hour = raw.GetNumber(0);
- result.Minute = raw.GetNumber(1);
- result.Second = raw.GetNumber(2);
- result.flags |= ParseFlags.HaveTime;
- return true;
- }
-
- //
- // Processing terminal state: A Date suffix followed by one number.
- //
- private static Boolean GetDateOfDSN(ref DateTimeResult result, ref DateTimeRawInfo raw)
- {
- if (raw.numCount != 1 || result.Day != -1)
- {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- result.Day = raw.GetNumber(0);
- return true;
- }
-
- private static Boolean GetDateOfNDS(ref DateTimeResult result, ref DateTimeRawInfo raw)
- {
- if (result.Month == -1)
- {
- //Should have a month suffix
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- if (result.Year != -1)
- {
- // Aleady has a year suffix
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- if (!TryAdjustYear(ref result, raw.GetNumber(0), out result.Year))
- {
- // the year value is out of range
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- result.Day = 1;
- return true;
- }
-
- private static Boolean GetDateOfNNDS(ref DateTimeResult result, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
- {
-
- // For partial CJK Dates, the only valid formats are with a specified year, followed by two numbers, which
- // will be the Month and Day, and with a specified Month, when the numbers are either the year and day or
- // day and year, depending on the short date pattern.
-
- if ((result.flags & ParseFlags.HaveYear) != 0) {
- if (((result.flags & ParseFlags.HaveMonth) == 0) && ((result.flags & ParseFlags.HaveDay) == 0)) {
- if (TryAdjustYear(ref result, raw.year, out result.Year) && SetDateYMD(ref result, result.Year, raw.GetNumber(0), raw.GetNumber(1))) {
- return true;
- }
- }
- }
- else if ((result.flags & ParseFlags.HaveMonth) != 0) {
- if (((result.flags & ParseFlags.HaveYear) == 0) && ((result.flags & ParseFlags.HaveDay) == 0)) {
- int order;
- if (!GetYearMonthDayOrder(dtfi.ShortDatePattern, dtfi, out order)) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadDatePattern", dtfi.ShortDatePattern);
- return false;
- }
- int year;
- if (order == ORDER_YMD) {
- if (TryAdjustYear(ref result, raw.GetNumber(0), out year) && SetDateYMD(ref result, year, result.Month, raw.GetNumber(1))) {
- return true;
- }
- }
- else {
- if (TryAdjustYear(ref result, raw.GetNumber(1), out year) && SetDateYMD(ref result, year, result.Month, raw.GetNumber(0))){
- return true;
- }
- }
- }
- }
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- //
- // A date suffix is found, use this method to put the number into the result.
- //
- private static bool ProcessDateTimeSuffix(ref DateTimeResult result, ref DateTimeRawInfo raw, ref DateTimeToken dtok)
- {
- switch (dtok.suffix)
- {
- case TokenType.SEP_YearSuff:
- if ((result.flags & ParseFlags.HaveYear) != 0) {
- return false;
- }
- result.flags |= ParseFlags.HaveYear;
- result.Year = raw.year = dtok.num;
- break;
- case TokenType.SEP_MonthSuff:
- if ((result.flags & ParseFlags.HaveMonth) != 0) {
- return false;
- }
- result.flags |= ParseFlags.HaveMonth;
- result.Month= raw.month = dtok.num;
- break;
- case TokenType.SEP_DaySuff:
- if ((result.flags & ParseFlags.HaveDay) != 0) {
- return false;
- }
- result.flags |= ParseFlags.HaveDay;
- result.Day = dtok.num;
- break;
- case TokenType.SEP_HourSuff:
- if ((result.flags & ParseFlags.HaveHour) != 0) {
- return false;
- }
- result.flags |= ParseFlags.HaveHour;
- result.Hour = dtok.num;
- break;
- case TokenType.SEP_MinuteSuff:
- if ((result.flags & ParseFlags.HaveMinute) != 0) {
- return false;
- }
- result.flags |= ParseFlags.HaveMinute;
- result.Minute = dtok.num;
- break;
- case TokenType.SEP_SecondSuff:
- if ((result.flags & ParseFlags.HaveSecond) != 0) {
- return false;
- }
- result.flags |= ParseFlags.HaveSecond;
- result.Second = dtok.num;
- break;
- }
- return true;
-
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Actions:
- // This is used by DateTime.Parse().
- // Process the terminal state for the Hebrew calendar parsing.
- //
- ////////////////////////////////////////////////////////////////////////
-
- internal static Boolean ProcessHebrewTerminalState(DS dps, ref DateTimeResult result, ref DateTimeStyles styles, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi) {
- // The following are accepted terminal state for Hebrew date.
- switch (dps) {
- case DS.DX_MNN:
- // Deal with the default long/short date format when the year number is ambigous (i.e. year < 100).
- raw.year = raw.GetNumber(1);
- if (!dtfi.YearMonthAdjustment(ref raw.year, ref raw.month, true)) {
- result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
- return false;
- }
- if (!GetDayOfMNN(ref result, ref raw, dtfi)) {
- return false;
- }
- break;
- case DS.DX_YMN:
- // Deal with the default long/short date format when the year number is NOT ambigous (i.e. year >= 100).
- if (!dtfi.YearMonthAdjustment(ref raw.year, ref raw.month, true)) {
- result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
- return false;
- }
- if (!GetDayOfYMN(ref result, ref raw, dtfi)) {
- return false;
- }
- break;
- case DS.DX_NM:
- case DS.DX_MN:
- // Deal with Month/Day pattern.
- GetDefaultYear(ref result, ref styles);
- if (!dtfi.YearMonthAdjustment(ref result.Year, ref raw.month, true)) {
- result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
- return false;
- }
- if (!GetHebrewDayOfNM(ref result, ref raw, dtfi)) {
- return false;
- }
- break;
- case DS.DX_YM:
- // Deal with Year/Month pattern.
- if (!dtfi.YearMonthAdjustment(ref raw.year, ref raw.month, true)) {
- result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
- return false;
- }
- if (!GetDayOfYM(ref result, ref raw, dtfi)) {
- return false;
- }
- break;
- case DS.TX_N:
- // Deal hour + AM/PM
- if (!GetTimeOfN(dtfi, ref result, ref raw)) {
- return false;
- }
- break;
- case DS.TX_NN:
- if (!GetTimeOfNN(dtfi, ref result, ref raw)) {
- return false;
- }
- break;
- case DS.TX_NNN:
- if (!GetTimeOfNNN(dtfi, ref result, ref raw)) {
- return false;
- }
- break;
- default:
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
-
- }
- if (dps > DS.ERROR)
- {
- //
- // We have reached a terminal state. Reset the raw num count.
- //
- raw.numCount = 0;
- }
- return true;
- }
-
- //
- // A terminal state has been reached, call the appropriate function to fill in the parsing result.
- // Return true if the state is a terminal state.
- //
- internal static Boolean ProcessTerminaltState(DS dps, ref DateTimeResult result, ref DateTimeStyles styles, ref DateTimeRawInfo raw, DateTimeFormatInfo dtfi)
- {
-
- bool passed = true;
- switch (dps)
- {
- case DS.DX_NN:
- passed = GetDayOfNN(ref result, ref styles, ref raw, dtfi);
- break;
- case DS.DX_NNN:
- passed = GetDayOfNNN(ref result, ref raw, dtfi);
- break;
- case DS.DX_MN:
- passed = GetDayOfMN(ref result, ref styles, ref raw, dtfi);
- break;
- case DS.DX_NM:
- passed = GetDayOfNM(ref result, ref styles, ref raw, dtfi);
- break;
- case DS.DX_MNN:
- passed = GetDayOfMNN(ref result, ref raw, dtfi);
- break;
- case DS.DX_DS:
- // The result has got the correct value. No need to process.
- passed = true;
- break;
- case DS.DX_YNN:
- passed = GetDayOfYNN(ref result, ref raw, dtfi);
- break;
- case DS.DX_NNY:
- passed = GetDayOfNNY(ref result, ref raw, dtfi);
- break;
- case DS.DX_YMN:
- passed = GetDayOfYMN(ref result, ref raw, dtfi);
- break;
- case DS.DX_YN:
- passed = GetDayOfYN(ref result, ref raw, dtfi);
- break;
- case DS.DX_YM:
- passed = GetDayOfYM(ref result, ref raw, dtfi);
- break;
- case DS.TX_N:
- passed = GetTimeOfN(dtfi, ref result, ref raw);
- break;
- case DS.TX_NN:
- passed = GetTimeOfNN(dtfi, ref result, ref raw);
- break;
- case DS.TX_NNN:
- passed = GetTimeOfNNN(dtfi, ref result, ref raw);
- break;
- case DS.TX_TS:
- // The result has got the correct value. Nothing to do.
- passed = true;
- break;
- case DS.DX_DSN:
- passed = GetDateOfDSN(ref result, ref raw);
- break;
- case DS.DX_NDS:
- passed = GetDateOfNDS(ref result, ref raw);
- break;
- case DS.DX_NNDS:
- passed = GetDateOfNNDS(ref result, ref raw, dtfi);
- break;
- }
-
- PTSTraceExit(dps, passed);
- if (!passed) {
- return false;
- }
-
- if (dps > DS.ERROR)
- {
- //
- // We have reached a terminal state. Reset the raw num count.
- //
- raw.numCount = 0;
- }
- return true;
- }
-
- internal static DateTime Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles) {
- DateTimeResult result = new DateTimeResult(); // The buffer to store the parsing result.
- result.Init();
- if (TryParse(s, dtfi, styles, ref result)) {
- return result.parsedDate;
- }
- else {
- throw GetDateTimeParseException(ref result);
- }
- }
-
- internal static DateTime Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles, out TimeSpan offset) {
- DateTimeResult result = new DateTimeResult(); // The buffer to store the parsing result.
- result.Init();
- result.flags |= ParseFlags.CaptureOffset;
- if (TryParse(s, dtfi, styles, ref result)) {
- offset = result.timeZoneOffset;
- return result.parsedDate;
- }
- else {
- throw GetDateTimeParseException(ref result);
- }
- }
-
-
- internal static bool TryParse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles, out DateTime result) {
- result = DateTime.MinValue;
- DateTimeResult resultData = new DateTimeResult(); // The buffer to store the parsing result.
- resultData.Init();
- if (TryParse(s, dtfi, styles, ref resultData)) {
- result = resultData.parsedDate;
- return true;
- }
- return false;
- }
-
- internal static bool TryParse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles, out DateTime result, out TimeSpan offset) {
- result = DateTime.MinValue;
- offset = TimeSpan.Zero;
- DateTimeResult parseResult = new DateTimeResult(); // The buffer to store the parsing result.
- parseResult.Init();
- parseResult.flags |= ParseFlags.CaptureOffset;
- if (TryParse(s, dtfi, styles, ref parseResult)) {
- result = parseResult.parsedDate;
- offset = parseResult.timeZoneOffset;
- return true;
- }
- return false;
- }
-
-
- //
- // This is the real method to do the parsing work.
- //
- internal static bool TryParse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles, ref DateTimeResult result) {
- if (s == null) {
- result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(s));
- return false;
- }
- if (s.Length == 0) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- Debug.Assert(dtfi != null, "dtfi == null");
-
-#if _LOGGING
- DTFITrace(dtfi);
-#endif
-
- DateTime time;
- //
- // First try the predefined format.
- //
-
- DS dps = DS.BEGIN; // Date Parsing State.
- bool reachTerminalState = false;
-
- DateTimeToken dtok = new DateTimeToken(); // The buffer to store the parsing token.
- dtok.suffix = TokenType.SEP_Unk;
- DateTimeRawInfo raw = new DateTimeRawInfo(); // The buffer to store temporary parsing information.
- unsafe {
- Int32 * numberPointer = stackalloc Int32[3];
- raw.Init(numberPointer);
- }
- raw.hasSameDateAndTimeSeparators = dtfi.DateSeparator.Equals(dtfi.TimeSeparator, StringComparison.Ordinal);
-
- result.calendar = dtfi.Calendar;
- result.era = Calendar.CurrentEra;
-
- //
- // The string to be parsed. Use a __DTString wrapper so that we can trace the index which
- // indicates the begining of next token.
- //
- __DTString str = new __DTString(s, dtfi);
-
- str.GetNext();
-
- //
- // The following loop will break out when we reach the end of the str.
- //
- do {
- //
- // Call the lexer to get the next token.
- //
- // If we find a era in Lex(), the era value will be in raw.era.
- if (!Lex(dps, ref str, ref dtok, ref raw, ref result, ref dtfi, styles))
- {
- TPTraceExit("0000", dps);
- return false;
- }
-
- //
- // If the token is not unknown, process it.
- // Otherwise, just discard it.
- //
- if (dtok.dtt != DTT.Unk)
- {
- //
- // Check if we got any CJK Date/Time suffix.
- // Since the Date/Time suffix tells us the number belongs to year/month/day/hour/minute/second,
- // store the number in the appropriate field in the result.
- //
- if (dtok.suffix != TokenType.SEP_Unk)
- {
- if (!ProcessDateTimeSuffix(ref result, ref raw, ref dtok)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- TPTraceExit("0010", dps);
- return false;
- }
-
- dtok.suffix = TokenType.SEP_Unk; // Reset suffix to SEP_Unk;
- }
-
- if (dtok.dtt == DTT.NumLocalTimeMark) {
- if (dps == DS.D_YNd || dps == DS.D_YN) {
- // Consider this as ISO 8601 format:
- // "yyyy-MM-dd'T'HH:mm:ss" 1999-10-31T02:00:00
- TPTraceExit("0020", dps);
- return (ParseISO8601(ref raw, ref str, styles, ref result));
- }
- else {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- TPTraceExit("0030", dps);
- return false;
- }
- }
-
- if (raw.hasSameDateAndTimeSeparators)
- {
- if (dtok.dtt == DTT.YearEnd || dtok.dtt == DTT.YearSpace || dtok.dtt == DTT.YearDateSep)
- {
- // When time and date separators are same and we are hitting a year number while the first parsed part of the string was recognized
- // as part of time (and not a date) DS.T_Nt, DS.T_NNt then change the state to be a date so we try to parse it as a date instead
- if (dps == DS.T_Nt)
- {
- dps = DS.D_Nd;
- }
- if (dps == DS.T_NNt)
- {
- dps = DS.D_NNd;
- }
- }
-
- bool atEnd = str.AtEnd();
- if (dateParsingStates[(int)dps][(int)dtok.dtt] == DS.ERROR || atEnd)
- {
- switch (dtok.dtt)
- {
- // we have the case of Serbia have dates in forms 'd.M.yyyy.' so we can expect '.' after the date parts.
- // changing the token to end with space instead of Date Separator will avoid failing the parsing.
-
- case DTT.YearDateSep: dtok.dtt = atEnd ? DTT.YearEnd : DTT.YearSpace; break;
- case DTT.NumDatesep: dtok.dtt = atEnd ? DTT.NumEnd : DTT.NumSpace; break;
- case DTT.NumTimesep: dtok.dtt = atEnd ? DTT.NumEnd : DTT.NumSpace; break;
- case DTT.MonthDatesep: dtok.dtt = atEnd ? DTT.MonthEnd : DTT.MonthSpace; break;
- }
- }
- }
-
- //
- // Advance to the next state, and continue
- //
- dps = dateParsingStates[(int)dps][(int)dtok.dtt];
-
- if (dps == DS.ERROR)
- {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- TPTraceExit("0040 (invalid state transition)", dps);
- return false;
- }
- else if (dps > DS.ERROR)
- {
- if ((dtfi.FormatFlags & DateTimeFormatFlags.UseHebrewRule) != 0) {
- if (!ProcessHebrewTerminalState(dps, ref result, ref styles, ref raw, dtfi)) {
- TPTraceExit("0050 (ProcessHebrewTerminalState)", dps);
- return false;
- }
- } else {
- if (!ProcessTerminaltState(dps, ref result, ref styles, ref raw, dtfi)) {
- TPTraceExit("0060 (ProcessTerminaltState)", dps);
- return false;
- }
- }
- reachTerminalState = true;
-
- //
- // If we have reached a terminal state, start over from DS.BEGIN again.
- // For example, when we parsed "1999-12-23 13:30", we will reach a terminal state at "1999-12-23",
- // and we start over so we can continue to parse "12:30".
- //
- dps = DS.BEGIN;
- }
- }
- } while (dtok.dtt != DTT.End && dtok.dtt != DTT.NumEnd && dtok.dtt != DTT.MonthEnd);
-
- if (!reachTerminalState) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- TPTraceExit("0070 (did not reach terminal state)", dps);
- return false;
- }
-
- AdjustTimeMark(dtfi, ref raw);
- if (!AdjustHour(ref result.Hour, raw.timeMark)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- TPTraceExit("0080 (AdjustHour)", dps);
- return false;
- }
-
- // Check if the parased string only contains hour/minute/second values.
- bool bTimeOnly = (result.Year == -1 && result.Month == -1 && result.Day == -1);
-
- //
- // Check if any year/month/day is missing in the parsing string.
- // If yes, get the default value from today's date.
- //
- if (!CheckDefaultDateTime(ref result, ref result.calendar, styles)) {
- TPTraceExit("0090 (failed to fill in missing year/month/day defaults)", dps);
- return false;
- }
-
- if (!result.calendar.TryToDateTime(result.Year, result.Month, result.Day,
- result.Hour, result.Minute, result.Second, 0, result.era, out time)) {
- result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
- TPTraceExit("0100 (result.calendar.TryToDateTime)", dps);
- return false;
- }
- if (raw.fraction > 0) {
- time = time.AddTicks((long)Math.Round(raw.fraction * Calendar.TicksPerSecond));
- }
-
- //
- // We have to check day of week before we adjust to the time zone.
- // Otherwise, the value of day of week may change after adjustting to the time zone.
- //
- if (raw.dayOfWeek != -1) {
- //
- // Check if day of week is correct.
- //
- if (raw.dayOfWeek != (int)result.calendar.GetDayOfWeek(time)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDayOfWeek", null);
- TPTraceExit("0110 (dayOfWeek check)", dps);
- return false;
- }
- }
-
- result.parsedDate = time;
-
- if (!DetermineTimeZoneAdjustments(ref result, styles, bTimeOnly)) {
- TPTraceExit("0120 (DetermineTimeZoneAdjustments)", dps);
- return false;
- }
- TPTraceExit("0130 (success)", dps);
- return true;
- }
-
-
- // Handles time zone adjustments and sets DateTimeKind values as required by the styles
- private static Boolean DetermineTimeZoneAdjustments(ref DateTimeResult result, DateTimeStyles styles, Boolean bTimeOnly) {
-
- if ((result.flags & ParseFlags.CaptureOffset) != 0) {
- // This is a DateTimeOffset parse, so the offset will actually be captured directly, and
- // no adjustment is required in most cases
- return DateTimeOffsetTimeZonePostProcessing(ref result, styles);
- }
- else {
- Int64 offsetTicks = result.timeZoneOffset.Ticks;
-
- // the DateTime offset must be within +- 14:00 hours.
- if (offsetTicks < DateTimeOffset.MinOffset || offsetTicks > DateTimeOffset.MaxOffset) {
- result.SetFailure(ParseFailureKind.Format, "Format_OffsetOutOfRange", null);
- return false;
- }
- }
-
- // The flags AssumeUniveral and AssumeLocal only apply when the input does not have a time zone
- if ((result.flags & ParseFlags.TimeZoneUsed) == 0) {
-
- // If AssumeLocal or AssumeLocal is used, there will always be a kind specified. As in the
- // case when a time zone is present, it will default to being local unless AdjustToUniversal
- // is present. These comparisons determine whether setting the kind is sufficient, or if a
- // time zone adjustment is required. For consistentcy with the rest of parsing, it is desirable
- // to fall through to the Adjust methods below, so that there is consist handling of boundary
- // cases like wrapping around on time-only dates and temporarily allowing an adjusted date
- // to exceed DateTime.MaxValue
- if ((styles & DateTimeStyles.AssumeLocal) != 0) {
- if ((styles & DateTimeStyles.AdjustToUniversal) != 0) {
- result.flags |= ParseFlags.TimeZoneUsed;
- result.timeZoneOffset = TimeZoneInfo.GetLocalUtcOffset(result.parsedDate, TimeZoneInfoOptions.NoThrowOnInvalidTime);
- }
- else {
- result.parsedDate = DateTime.SpecifyKind(result.parsedDate, DateTimeKind.Local);
- return true;
- }
- }
- else if ((styles & DateTimeStyles.AssumeUniversal) != 0) {
- if ((styles & DateTimeStyles.AdjustToUniversal) != 0) {
- result.parsedDate = DateTime.SpecifyKind(result.parsedDate, DateTimeKind.Utc);
- return true;
- }
- else {
- result.flags |= ParseFlags.TimeZoneUsed;
- result.timeZoneOffset = TimeSpan.Zero;
- }
- }
- else {
- // No time zone and no Assume flags, so DateTimeKind.Unspecified is fine
- Debug.Assert(result.parsedDate.Kind == DateTimeKind.Unspecified, "result.parsedDate.Kind == DateTimeKind.Unspecified");
- return true;
- }
- }
-
- if (((styles & DateTimeStyles.RoundtripKind) != 0) && ((result.flags & ParseFlags.TimeZoneUtc) != 0)) {
- result.parsedDate = DateTime.SpecifyKind(result.parsedDate, DateTimeKind.Utc);
- return true;
- }
-
- if ((styles & DateTimeStyles.AdjustToUniversal) != 0) {
- return (AdjustTimeZoneToUniversal(ref result));
- }
- return (AdjustTimeZoneToLocal(ref result, bTimeOnly));
- }
-
- // Apply validation and adjustments specific to DateTimeOffset
- private static Boolean DateTimeOffsetTimeZonePostProcessing(ref DateTimeResult result, DateTimeStyles styles) {
-
- // For DateTimeOffset, default to the Utc or Local offset when an offset was not specified by
- // the input string.
- if ((result.flags & ParseFlags.TimeZoneUsed) == 0) {
- if ((styles & DateTimeStyles.AssumeUniversal) != 0) {
- // AssumeUniversal causes the offset to default to zero (0)
- result.timeZoneOffset = TimeSpan.Zero;
- }
- else {
- // AssumeLocal causes the offset to default to Local. This flag is on by default for DateTimeOffset.
- result.timeZoneOffset = TimeZoneInfo.GetLocalUtcOffset(result.parsedDate, TimeZoneInfoOptions.NoThrowOnInvalidTime);
- }
- }
-
- Int64 offsetTicks = result.timeZoneOffset.Ticks;
-
- // there should be no overflow, because the offset can be no more than -+100 hours and the date already
- // fits within a DateTime.
- Int64 utcTicks = result.parsedDate.Ticks - offsetTicks;
-
- // For DateTimeOffset, both the parsed time and the corresponding UTC value must be within the boundaries
- // of a DateTime instance.
- if (utcTicks < DateTime.MinTicks || utcTicks > DateTime.MaxTicks) {
- result.SetFailure(ParseFailureKind.Format, "Format_UTCOutOfRange", null);
- return false;
- }
-
- // the offset must be within +- 14:00 hours.
- if (offsetTicks < DateTimeOffset.MinOffset || offsetTicks > DateTimeOffset.MaxOffset) {
- result.SetFailure(ParseFailureKind.Format, "Format_OffsetOutOfRange", null);
- return false;
- }
-
- // DateTimeOffset should still honor the AdjustToUniversal flag for consistency with DateTime. It means you
- // want to return an adjusted UTC value, so store the utcTicks in the DateTime and set the offset to zero
- if ((styles & DateTimeStyles.AdjustToUniversal) != 0) {
- if (((result.flags & ParseFlags.TimeZoneUsed) == 0) && ((styles & DateTimeStyles.AssumeUniversal) == 0)) {
- // Handle the special case where the timeZoneOffset was defaulted to Local
- Boolean toUtcResult = AdjustTimeZoneToUniversal(ref result);
- result.timeZoneOffset = TimeSpan.Zero;
- return toUtcResult;
- }
-
- // The constructor should always succeed because of the range check earlier in the function
- // Althought it is UTC, internally DateTimeOffset does not use this flag
- result.parsedDate = new DateTime(utcTicks, DateTimeKind.Utc);
- result.timeZoneOffset = TimeSpan.Zero;
- }
-
- return true;
- }
-
-
- //
- // Adjust the specified time to universal time based on the supplied timezone.
- // E.g. when parsing "2001/06/08 14:00-07:00",
- // the time is 2001/06/08 14:00, and timeZoneOffset = -07:00.
- // The result will be "2001/06/08 21:00"
- //
- private static Boolean AdjustTimeZoneToUniversal(ref DateTimeResult result) {
- long resultTicks = result.parsedDate.Ticks;
- resultTicks -= result.timeZoneOffset.Ticks;
- if (resultTicks < 0) {
- resultTicks += Calendar.TicksPerDay;
- }
-
- if (resultTicks < DateTime.MinTicks || resultTicks > DateTime.MaxTicks) {
- result.SetFailure(ParseFailureKind.Format, "Format_DateOutOfRange", null);
- return false;
- }
- result.parsedDate = new DateTime(resultTicks, DateTimeKind.Utc);
- return true;
- }
-
- //
- // Adjust the specified time to universal time based on the supplied timezone,
- // and then convert to local time.
- // E.g. when parsing "2001/06/08 14:00-04:00", and local timezone is GMT-7.
- // the time is 2001/06/08 14:00, and timeZoneOffset = -05:00.
- // The result will be "2001/06/08 11:00"
- //
- private static Boolean AdjustTimeZoneToLocal(ref DateTimeResult result, bool bTimeOnly) {
- long resultTicks = result.parsedDate.Ticks;
- // Convert to local ticks
- TimeZoneInfo tz = TimeZoneInfo.Local;
- Boolean isAmbiguousLocalDst = false;
- if (resultTicks < Calendar.TicksPerDay) {
- //
- // This is time of day.
- //
-
- // Adjust timezone.
- resultTicks -= result.timeZoneOffset.Ticks;
- // If the time is time of day, use the current timezone offset.
- resultTicks += tz.GetUtcOffset(bTimeOnly ? DateTime.Now: result.parsedDate, TimeZoneInfoOptions.NoThrowOnInvalidTime).Ticks;
-
- if (resultTicks < 0) {
- resultTicks += Calendar.TicksPerDay;
- }
- } else {
- // Adjust timezone to GMT.
- resultTicks -= result.timeZoneOffset.Ticks;
- if (resultTicks < DateTime.MinTicks || resultTicks > DateTime.MaxTicks) {
- // If the result ticks is greater than DateTime.MaxValue, we can not create a DateTime from this ticks.
- // In this case, keep using the old code.
- resultTicks += tz.GetUtcOffset(result.parsedDate, TimeZoneInfoOptions.NoThrowOnInvalidTime).Ticks;
- } else {
- // Convert the GMT time to local time.
- DateTime utcDt = new DateTime(resultTicks, DateTimeKind.Utc);
- Boolean isDaylightSavings = false;
- resultTicks += TimeZoneInfo.GetUtcOffsetFromUtc(utcDt, TimeZoneInfo.Local, out isDaylightSavings, out isAmbiguousLocalDst).Ticks;
- }
- }
- if (resultTicks < DateTime.MinTicks || resultTicks > DateTime.MaxTicks) {
- result.parsedDate = DateTime.MinValue;
- result.SetFailure(ParseFailureKind.Format, "Format_DateOutOfRange", null);
- return false;
- }
- result.parsedDate = new DateTime(resultTicks, DateTimeKind.Local, isAmbiguousLocalDst);
- return true;
- }
-
- //
- // Parse the ISO8601 format string found during Parse();
- //
- //
- private static bool ParseISO8601(ref DateTimeRawInfo raw, ref __DTString str, DateTimeStyles styles, ref DateTimeResult result) {
- if (raw.year < 0 || raw.GetNumber(0) < 0 || raw.GetNumber(1) < 0) {
- }
- str.Index--;
- int hour, minute;
- int second = 0;
- double partSecond = 0;
-
- str.SkipWhiteSpaces();
- if (!ParseDigits(ref str, 2, out hour)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- str.SkipWhiteSpaces();
- if (!str.Match(':')) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- str.SkipWhiteSpaces();
- if (!ParseDigits(ref str, 2, out minute)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- str.SkipWhiteSpaces();
- if (str.Match(':')) {
- str.SkipWhiteSpaces();
- if (!ParseDigits(ref str, 2, out second)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- if (str.Match('.')) {
- if (!ParseFraction(ref str, out partSecond)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- str.Index--;
- }
- str.SkipWhiteSpaces();
- }
- if (str.GetNext()) {
- char ch = str.GetChar();
- if (ch == '+' || ch == '-') {
- result.flags |= ParseFlags.TimeZoneUsed;
- if (!ParseTimeZone(ref str, ref result.timeZoneOffset)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- } else if (ch == 'Z' || ch == 'z') {
- result.flags |= ParseFlags.TimeZoneUsed;
- result.timeZoneOffset = TimeSpan.Zero;
- result.flags |= ParseFlags.TimeZoneUtc;
- } else {
- str.Index--;
- }
- str.SkipWhiteSpaces();
- if (str.Match('#')) {
- if (!VerifyValidPunctuation(ref str)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- str.SkipWhiteSpaces();
- }
- if (str.Match('\0')) {
- if (!VerifyValidPunctuation(ref str)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- }
- if (str.GetNext()) {
- // If this is true, there were non-white space characters remaining in the DateTime
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- }
-
- DateTime time;
- Calendar calendar = GregorianCalendar.GetDefaultInstance();
- if (!calendar.TryToDateTime(raw.year, raw.GetNumber(0), raw.GetNumber(1),
- hour, minute, second, 0, result.era, out time)) {
- result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
- return false;
- }
-
- time = time.AddTicks((long)Math.Round(partSecond * Calendar.TicksPerSecond));
- result.parsedDate = time;
- if (!DetermineTimeZoneAdjustments(ref result, styles, false)) {
- return false;
- }
- return true;
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Actions:
- // Parse the current word as a Hebrew number.
- // This is used by DateTime.ParseExact().
- //
- ////////////////////////////////////////////////////////////////////////
-
- internal static bool MatchHebrewDigits(ref __DTString str, int digitLen, out int number) {
- number = 0;
-
- // Create a context object so that we can parse the Hebrew number text character by character.
- HebrewNumberParsingContext context = new HebrewNumberParsingContext(0);
-
- // Set this to ContinueParsing so that we will run the following while loop in the first time.
- HebrewNumberParsingState state = HebrewNumberParsingState.ContinueParsing;
-
- while (state == HebrewNumberParsingState.ContinueParsing && str.GetNext()) {
- state = HebrewNumber.ParseByChar(str.GetChar(), ref context);
- }
-
- if (state == HebrewNumberParsingState.FoundEndOfHebrewNumber) {
- // If we have reached a terminal state, update the result and returns.
- number = context.result;
- return (true);
- }
-
- // If we run out of the character before reaching FoundEndOfHebrewNumber, or
- // the state is InvalidHebrewNumber or ContinueParsing, we fail to match a Hebrew number.
- // Return an error.
- return false;
- }
-
- /*=================================ParseDigits==================================
- **Action: Parse the number string in __DTString that are formatted using
- ** the following patterns:
- ** "0", "00", and "000..0"
- **Returns: the integer value
- **Arguments: str: a __DTString. The parsing will start from the
- ** next character after str.Index.
- **Exceptions: FormatException if error in parsing number.
- ==============================================================================*/
-
- internal static bool ParseDigits(ref __DTString str, int digitLen, out int result) {
- if (digitLen == 1) {
- // 1 really means 1 or 2 for this call
- return ParseDigits(ref str, 1, 2, out result);
- }
- else {
- return ParseDigits(ref str, digitLen, digitLen, out result);
- }
- }
-
- internal static bool ParseDigits(ref __DTString str, int minDigitLen, int maxDigitLen, out int result) {
- Debug.Assert(minDigitLen > 0, "minDigitLen > 0");
- Debug.Assert(maxDigitLen < 9, "maxDigitLen < 9");
- Debug.Assert(minDigitLen <= maxDigitLen, "minDigitLen <= maxDigitLen");
- result = 0;
- int startingIndex = str.Index;
- int tokenLength = 0;
- while (tokenLength < maxDigitLen) {
- if (!str.GetNextDigit()) {
- str.Index--;
- break;
- }
- result = result * 10 + str.GetDigit();
- tokenLength++;
- }
- if (tokenLength < minDigitLen) {
- str.Index = startingIndex;
- return false;
- }
- return true;
- }
-
- /*=================================ParseFractionExact==================================
- **Action: Parse the number string in __DTString that are formatted using
- ** the following patterns:
- ** "0", "00", and "000..0"
- **Returns: the fraction value
- **Arguments: str: a __DTString. The parsing will start from the
- ** next character after str.Index.
- **Exceptions: FormatException if error in parsing number.
- ==============================================================================*/
-
- private static bool ParseFractionExact(ref __DTString str, int maxDigitLen, ref double result) {
- if (!str.GetNextDigit()) {
- str.Index--;
- return false;
- }
- result = str.GetDigit();
-
- int digitLen = 1;
- for (; digitLen < maxDigitLen; digitLen++) {
- if (!str.GetNextDigit()) {
- str.Index--;
- break;
- }
- result = result * 10 + str.GetDigit();
- }
-
- result = ((double)result / Math.Pow(10, digitLen));
- return (digitLen == maxDigitLen);
- }
-
- /*=================================ParseSign==================================
- **Action: Parse a positive or a negative sign.
- **Returns: true if postive sign. flase if negative sign.
- **Arguments: str: a __DTString. The parsing will start from the
- ** next character after str.Index.
- **Exceptions: FormatException if end of string is encountered or a sign
- ** symbol is not found.
- ==============================================================================*/
-
- private static bool ParseSign(ref __DTString str, ref bool result) {
- if (!str.GetNext()) {
- // A sign symbol ('+' or '-') is expected. However, end of string is encountered.
- return false;
- }
- char ch = str.GetChar();
- if (ch == '+') {
- result = true;
- return (true);
- } else if (ch == '-') {
- result = false;
- return (true);
- }
- // A sign symbol ('+' or '-') is expected.
- return false;
- }
-
- /*=================================ParseTimeZoneOffset==================================
- **Action: Parse the string formatted using "z", "zz", "zzz" in DateTime.Format().
- **Returns: the TimeSpan for the parsed timezone offset.
- **Arguments: str: a __DTString. The parsing will start from the
- ** next character after str.Index.
- ** len: the repeated number of the "z"
- **Exceptions: FormatException if errors in parsing.
- ==============================================================================*/
-
- private static bool ParseTimeZoneOffset(ref __DTString str, int len, ref TimeSpan result) {
- bool isPositive = true;
- int hourOffset;
- int minuteOffset = 0;
-
- switch (len) {
- case 1:
- case 2:
- if (!ParseSign(ref str, ref isPositive)) {
- return (false);
- }
- if (!ParseDigits(ref str, len, out hourOffset)) {
- return (false);
- }
- break;
- default:
- if (!ParseSign(ref str, ref isPositive)) {
- return (false);
- }
-
- // Parsing 1 digit will actually parse 1 or 2.
- if (!ParseDigits(ref str, 1, out hourOffset)) {
- return (false);
- }
- // ':' is optional.
- if (str.Match(":")) {
- // Found ':'
- if (!ParseDigits(ref str, 2, out minuteOffset)) {
- return (false);
- }
- } else {
- // Since we can not match ':', put the char back.
- str.Index--;
- if (!ParseDigits(ref str, 2, out minuteOffset)) {
- return (false);
- }
- }
- break;
- }
- if (minuteOffset < 0 || minuteOffset >= 60) {
- return false;
- }
-
- result = (new TimeSpan(hourOffset, minuteOffset, 0));
- if (!isPositive) {
- result = result.Negate();
- }
- return (true);
- }
-
- /*=================================MatchAbbreviatedMonthName==================================
- **Action: Parse the abbreviated month name from string starting at str.Index.
- **Returns: A value from 1 to 12 for the first month to the twelveth month.
- **Arguments: str: a __DTString. The parsing will start from the
- ** next character after str.Index.
- **Exceptions: FormatException if an abbreviated month name can not be found.
- ==============================================================================*/
-
- private static bool MatchAbbreviatedMonthName(ref __DTString str, DateTimeFormatInfo dtfi, ref int result) {
- int maxMatchStrLen = 0;
- result = -1;
- if (str.GetNext()) {
- //
- // Scan the month names (note that some calendars has 13 months) and find
- // the matching month name which has the max string length.
- // We need to do this because some cultures (e.g. "cs-CZ") which have
- // abbreviated month names with the same prefix.
- //
- int monthsInYear = (dtfi.GetMonthName(13).Length == 0 ? 12: 13);
- for (int i = 1; i <= monthsInYear; i++) {
- String searchStr = dtfi.GetAbbreviatedMonthName(i);
- int matchStrLen = searchStr.Length;
- if ( dtfi.HasSpacesInMonthNames
- ? str.MatchSpecifiedWords(searchStr, false, ref matchStrLen)
- : str.MatchSpecifiedWord(searchStr)) {
- if (matchStrLen > maxMatchStrLen) {
- maxMatchStrLen = matchStrLen;
- result = i;
- }
- }
- }
-
- // Search leap year form.
- if ((dtfi.FormatFlags & DateTimeFormatFlags.UseLeapYearMonth) != 0) {
- int tempResult = str.MatchLongestWords(dtfi.internalGetLeapYearMonthNames(), ref maxMatchStrLen);
- // We found a longer match in the leap year month name. Use this as the result.
- // The result from MatchLongestWords is 0 ~ length of word array.
- // So we increment the result by one to become the month value.
- if (tempResult >= 0) {
- result = tempResult + 1;
- }
- }
-
-
- }
- if (result > 0) {
- str.Index += (maxMatchStrLen - 1);
- return (true);
- }
- return false;
- }
-
- /*=================================MatchMonthName==================================
- **Action: Parse the month name from string starting at str.Index.
- **Returns: A value from 1 to 12 indicating the first month to the twelveth month.
- **Arguments: str: a __DTString. The parsing will start from the
- ** next character after str.Index.
- **Exceptions: FormatException if a month name can not be found.
- ==============================================================================*/
-
- private static bool MatchMonthName(ref __DTString str, DateTimeFormatInfo dtfi, ref int result) {
- int maxMatchStrLen = 0;
- result = -1;
- if (str.GetNext()) {
- //
- // Scan the month names (note that some calendars has 13 months) and find
- // the matching month name which has the max string length.
- // We need to do this because some cultures (e.g. "vi-VN") which have
- // month names with the same prefix.
- //
- int monthsInYear = (dtfi.GetMonthName(13).Length == 0 ? 12: 13);
- for (int i = 1; i <= monthsInYear; i++) {
- String searchStr = dtfi.GetMonthName(i);
- int matchStrLen = searchStr.Length;
- if ( dtfi.HasSpacesInMonthNames
- ? str.MatchSpecifiedWords(searchStr, false, ref matchStrLen)
- : str.MatchSpecifiedWord(searchStr)) {
- if (matchStrLen > maxMatchStrLen) {
- maxMatchStrLen = matchStrLen;
- result = i;
- }
- }
- }
-
- // Search genitive form.
- if ((dtfi.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != 0) {
- int tempResult = str.MatchLongestWords(dtfi.MonthGenitiveNames, ref maxMatchStrLen);
- // We found a longer match in the genitive month name. Use this as the result.
- // The result from MatchLongestWords is 0 ~ length of word array.
- // So we increment the result by one to become the month value.
- if (tempResult >= 0) {
- result = tempResult + 1;
- }
- }
-
- // Search leap year form.
- if ((dtfi.FormatFlags & DateTimeFormatFlags.UseLeapYearMonth) != 0) {
- int tempResult = str.MatchLongestWords(dtfi.internalGetLeapYearMonthNames(), ref maxMatchStrLen);
- // We found a longer match in the leap year month name. Use this as the result.
- // The result from MatchLongestWords is 0 ~ length of word array.
- // So we increment the result by one to become the month value.
- if (tempResult >= 0) {
- result = tempResult + 1;
- }
- }
-
-
- }
-
- if (result > 0) {
- str.Index += (maxMatchStrLen - 1);
- return (true);
- }
- return false;
- }
-
- /*=================================MatchAbbreviatedDayName==================================
- **Action: Parse the abbreviated day of week name from string starting at str.Index.
- **Returns: A value from 0 to 6 indicating Sunday to Saturday.
- **Arguments: str: a __DTString. The parsing will start from the
- ** next character after str.Index.
- **Exceptions: FormatException if a abbreviated day of week name can not be found.
- ==============================================================================*/
-
- private static bool MatchAbbreviatedDayName(ref __DTString str, DateTimeFormatInfo dtfi, ref int result) {
- int maxMatchStrLen = 0;
- result = -1;
- if (str.GetNext()) {
- for (DayOfWeek i = DayOfWeek.Sunday; i <= DayOfWeek.Saturday; i++) {
- String searchStr = dtfi.GetAbbreviatedDayName(i);
- int matchStrLen = searchStr.Length;
- if ( dtfi.HasSpacesInDayNames
- ? str.MatchSpecifiedWords(searchStr, false, ref matchStrLen)
- : str.MatchSpecifiedWord(searchStr)) {
- if (matchStrLen > maxMatchStrLen) {
- maxMatchStrLen = matchStrLen;
- result = (int)i;
- }
- }
- }
- }
- if (result >= 0) {
- str.Index += maxMatchStrLen - 1;
- return (true);
- }
- return false;
- }
-
- /*=================================MatchDayName==================================
- **Action: Parse the day of week name from string starting at str.Index.
- **Returns: A value from 0 to 6 indicating Sunday to Saturday.
- **Arguments: str: a __DTString. The parsing will start from the
- ** next character after str.Index.
- **Exceptions: FormatException if a day of week name can not be found.
- ==============================================================================*/
-
- private static bool MatchDayName(ref __DTString str, DateTimeFormatInfo dtfi, ref int result) {
- // Turkish (tr-TR) got day names with the same prefix.
- int maxMatchStrLen = 0;
- result = -1;
- if (str.GetNext()) {
- for (DayOfWeek i = DayOfWeek.Sunday; i <= DayOfWeek.Saturday; i++) {
- String searchStr = dtfi.GetDayName(i);
- int matchStrLen = searchStr.Length;
- if ( dtfi.HasSpacesInDayNames
- ? str.MatchSpecifiedWords(searchStr, false, ref matchStrLen)
- : str.MatchSpecifiedWord(searchStr)) {
- if (matchStrLen > maxMatchStrLen) {
- maxMatchStrLen = matchStrLen;
- result = (int)i;
- }
- }
- }
- }
- if (result >= 0) {
- str.Index += maxMatchStrLen - 1;
- return (true);
- }
- return false;
- }
-
- /*=================================MatchEraName==================================
- **Action: Parse era name from string starting at str.Index.
- **Returns: An era value.
- **Arguments: str: a __DTString. The parsing will start from the
- ** next character after str.Index.
- **Exceptions: FormatException if an era name can not be found.
- ==============================================================================*/
-
- private static bool MatchEraName(ref __DTString str, DateTimeFormatInfo dtfi, ref int result) {
- if (str.GetNext()) {
- int[] eras = dtfi.Calendar.Eras;
-
- if (eras != null) {
- for (int i = 0; i < eras.Length; i++) {
- String searchStr = dtfi.GetEraName(eras[i]);
- if (str.MatchSpecifiedWord(searchStr)) {
- str.Index += (searchStr.Length - 1);
- result = eras[i];
- return (true);
- }
- searchStr = dtfi.GetAbbreviatedEraName(eras[i]);
- if (str.MatchSpecifiedWord(searchStr)) {
- str.Index += (searchStr.Length - 1);
- result = eras[i];
- return (true);
- }
- }
- }
- }
- return false;
- }
-
- /*=================================MatchTimeMark==================================
- **Action: Parse the time mark (AM/PM) from string starting at str.Index.
- **Returns: TM_AM or TM_PM.
- **Arguments: str: a __DTString. The parsing will start from the
- ** next character after str.Index.
- **Exceptions: FormatException if a time mark can not be found.
- ==============================================================================*/
-
- private static bool MatchTimeMark(ref __DTString str, DateTimeFormatInfo dtfi, ref TM result) {
- result = TM.NotSet;
- // In some cultures have empty strings in AM/PM mark. E.g. af-ZA (0x0436), the AM mark is "", and PM mark is "nm".
- if (dtfi.AMDesignator.Length == 0) {
- result = TM.AM;
- }
- if (dtfi.PMDesignator.Length == 0) {
- result = TM.PM;
- }
-
- if (str.GetNext()) {
- String searchStr = dtfi.AMDesignator;
- if (searchStr.Length > 0) {
- if (str.MatchSpecifiedWord(searchStr)) {
- // Found an AM timemark with length > 0.
- str.Index += (searchStr.Length - 1);
- result = TM.AM;
- return (true);
- }
- }
- searchStr = dtfi.PMDesignator;
- if (searchStr.Length > 0) {
- if (str.MatchSpecifiedWord(searchStr)) {
- // Found a PM timemark with length > 0.
- str.Index += (searchStr.Length - 1);
- result = TM.PM;
- return (true);
- }
- }
- str.Index--; // Undo the GetNext call.
- }
- if (result != TM.NotSet) {
- // If one of the AM/PM marks is empty string, return the result.
- return (true);
- }
- return false;
- }
-
- /*=================================MatchAbbreviatedTimeMark==================================
- **Action: Parse the abbreviated time mark (AM/PM) from string starting at str.Index.
- **Returns: TM_AM or TM_PM.
- **Arguments: str: a __DTString. The parsing will start from the
- ** next character after str.Index.
- **Exceptions: FormatException if a abbreviated time mark can not be found.
- ==============================================================================*/
-
- private static bool MatchAbbreviatedTimeMark(ref __DTString str, DateTimeFormatInfo dtfi, ref TM result) {
- // NOTENOTE : the assumption here is that abbreviated time mark is the first
- // character of the AM/PM designator. If this invariant changes, we have to
- // change the code below.
- if (str.GetNext())
- {
- if (str.GetChar() == dtfi.AMDesignator[0]) {
- result = TM.AM;
- return (true);
- }
- if (str.GetChar() == dtfi.PMDesignator[0]) {
- result = TM.PM;
- return (true);
- }
- }
- return false;
- }
-
- /*=================================CheckNewValue==================================
- **Action: Check if currentValue is initialized. If not, return the newValue.
- ** If yes, check if the current value is equal to newValue. Return false
- ** if they are not equal. This is used to check the case like "d" and "dd" are both
- ** used to format a string.
- **Returns: the correct value for currentValue.
- **Arguments:
- **Exceptions:
- ==============================================================================*/
-
- private static bool CheckNewValue(ref int currentValue, int newValue, char patternChar, ref DateTimeResult result) {
- if (currentValue == -1) {
- currentValue = newValue;
- return (true);
- } else {
- if (newValue != currentValue) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", patternChar);
- return (false);
- }
- }
- return (true);
- }
-
- private static DateTime GetDateTimeNow(ref DateTimeResult result, ref DateTimeStyles styles) {
- if ((result.flags & ParseFlags.CaptureOffset) != 0) {
- if ((result.flags & ParseFlags.TimeZoneUsed) != 0) {
- // use the supplied offset to calculate 'Now'
- return new DateTime(DateTime.UtcNow.Ticks + result.timeZoneOffset.Ticks, DateTimeKind.Unspecified);
- }
- else if ((styles & DateTimeStyles.AssumeUniversal) != 0) {
- // assume the offset is Utc
- return DateTime.UtcNow;
- }
- }
-
- // assume the offset is Local
- return DateTime.Now;
- }
-
- private static bool CheckDefaultDateTime(ref DateTimeResult result, ref Calendar cal, DateTimeStyles styles) {
-
- if ((result.flags & ParseFlags.CaptureOffset) != 0) {
- // DateTimeOffset.Parse should allow dates without a year, but only if there is also no time zone marker;
- // e.g. "May 1 5pm" is OK, but "May 1 5pm -08:30" is not. This is somewhat pragmatic, since we would
- // have to rearchitect parsing completely to allow this one case to correctly handle things like leap
- // years and leap months. Is is an extremely corner case, and DateTime is basically incorrect in that
- // case today.
- //
- // values like "11:00Z" or "11:00 -3:00" are also acceptable
- //
- // if ((month or day is set) and (year is not set and time zone is set))
- //
- if ( ((result.Month != -1) || (result.Day != -1))
- && ((result.Year == -1 || ((result.flags & ParseFlags.YearDefault) != 0)) && (result.flags & ParseFlags.TimeZoneUsed) != 0) ) {
- result.SetFailure(ParseFailureKind.Format, "Format_MissingIncompleteDate", null);
- return false;
- }
- }
-
-
- if ((result.Year == -1) || (result.Month == -1) || (result.Day == -1)) {
- /*
- The following table describes the behaviors of getting the default value
- when a certain year/month/day values are missing.
-
- An "X" means that the value exists. And "--" means that value is missing.
-
- Year Month Day => ResultYear ResultMonth ResultDay Note
-
- X X X Parsed year Parsed month Parsed day
- X X -- Parsed Year Parsed month First day If we have year and month, assume the first day of that month.
- X -- X Parsed year First month Parsed day If the month is missing, assume first month of that year.
- X -- -- Parsed year First month First day If we have only the year, assume the first day of that year.
-
- -- X X CurrentYear Parsed month Parsed day If the year is missing, assume the current year.
- -- X -- CurrentYear Parsed month First day If we have only a month value, assume the current year and current day.
- -- -- X CurrentYear First month Parsed day If we have only a day value, assume current year and first month.
- -- -- -- CurrentYear Current month Current day So this means that if the date string only contains time, you will get current date.
-
- */
-
- DateTime now = GetDateTimeNow(ref result, ref styles);
- if (result.Month == -1 && result.Day == -1) {
- if (result.Year == -1) {
- if ((styles & DateTimeStyles.NoCurrentDateDefault) != 0) {
- // If there is no year/month/day values, and NoCurrentDateDefault flag is used,
- // set the year/month/day value to the beginning year/month/day of DateTime().
- // Note we should be using Gregorian for the year/month/day.
- cal = GregorianCalendar.GetDefaultInstance();
- result.Year = result.Month = result.Day = 1;
- } else {
- // Year/Month/Day are all missing.
- result.Year = cal.GetYear(now);
- result.Month = cal.GetMonth(now);
- result.Day = cal.GetDayOfMonth(now);
- }
- } else {
- // Month/Day are both missing.
- result.Month = 1;
- result.Day = 1;
- }
- } else {
- if (result.Year == -1) {
- result.Year = cal.GetYear(now);
- }
- if (result.Month == -1) {
- result.Month = 1;
- }
- if (result.Day == -1) {
- result.Day = 1;
- }
- }
- }
- // Set Hour/Minute/Second to zero if these value are not in str.
- if (result.Hour == -1) result.Hour = 0;
- if (result.Minute == -1) result.Minute = 0;
- if (result.Second == -1) result.Second = 0;
- if (result.era == -1) result.era = Calendar.CurrentEra;
- return true;
- }
-
- // Expand a pre-defined format string (like "D" for long date) to the real format that
- // we are going to use in the date time parsing.
- // This method also set the dtfi according/parseInfo to some special pre-defined
- // formats.
- //
- private static String ExpandPredefinedFormat(String format, ref DateTimeFormatInfo dtfi, ref ParsingInfo parseInfo, ref DateTimeResult result) {
- //
- // Check the format to see if we need to override the dtfi to be InvariantInfo,
- // and see if we need to set up the userUniversalTime flag.
- //
- switch (format[0]) {
- case 'o':
- case 'O': // Round Trip Format
- parseInfo.calendar = GregorianCalendar.GetDefaultInstance();
- dtfi = DateTimeFormatInfo.InvariantInfo;
- break;
- case 'r':
- case 'R': // RFC 1123 Standard. (in Universal time)
- parseInfo.calendar = GregorianCalendar.GetDefaultInstance();
- dtfi = DateTimeFormatInfo.InvariantInfo;
-
- if ((result.flags & ParseFlags.CaptureOffset) != 0) {
- result.flags |= ParseFlags.Rfc1123Pattern;
- }
- break;
- case 's': // Sortable format (in local time)
- dtfi = DateTimeFormatInfo.InvariantInfo;
- parseInfo.calendar = GregorianCalendar.GetDefaultInstance();
- break;
- case 'u': // Universal time format in sortable format.
- parseInfo.calendar = GregorianCalendar.GetDefaultInstance();
- dtfi = DateTimeFormatInfo.InvariantInfo;
-
- if ((result.flags & ParseFlags.CaptureOffset) != 0) {
- result.flags |= ParseFlags.UtcSortPattern;
- }
- break;
- case 'U': // Universal time format with culture-dependent format.
- parseInfo.calendar = GregorianCalendar.GetDefaultInstance();
- result.flags |= ParseFlags.TimeZoneUsed;
- result.timeZoneOffset = new TimeSpan(0);
- result.flags |= ParseFlags.TimeZoneUtc;
- if (dtfi.Calendar.GetType() != typeof(GregorianCalendar)) {
- dtfi = (DateTimeFormatInfo)dtfi.Clone();
- dtfi.Calendar = GregorianCalendar.GetDefaultInstance();
- }
- break;
- }
-
- //
- // Expand the pre-defined format character to the real format from DateTimeFormatInfo.
- //
- return (DateTimeFormat.GetRealFormat(format, dtfi));
- }
-
-
-
-
-
- // Given a specified format character, parse and update the parsing result.
- //
- private static bool ParseByFormat(
- ref __DTString str,
- ref __DTString format,
- ref ParsingInfo parseInfo,
- DateTimeFormatInfo dtfi,
- ref DateTimeResult result) {
-
- int tokenLen = 0;
- int tempYear = 0, tempMonth = 0, tempDay = 0, tempDayOfWeek = 0, tempHour = 0, tempMinute = 0, tempSecond = 0;
- double tempFraction = 0;
- TM tempTimeMark = 0;
-
- char ch = format.GetChar();
-
- switch (ch) {
- case 'y':
- tokenLen = format.GetRepeatCount();
- bool parseResult;
- if (dtfi.HasForceTwoDigitYears) {
- parseResult = ParseDigits(ref str, 1, 4, out tempYear);
- }
- else {
- if (tokenLen <= 2) {
- parseInfo.fUseTwoDigitYear = true;
- }
- parseResult = ParseDigits(ref str, tokenLen, out tempYear);
- }
- if (!parseResult && parseInfo.fCustomNumberParser) {
- parseResult = parseInfo.parseNumberDelegate(ref str, tokenLen, out tempYear);
- }
- if (!parseResult) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- if (!CheckNewValue(ref result.Year, tempYear, ch, ref result)) {
- return (false);
- }
- break;
- case 'M':
- tokenLen = format.GetRepeatCount();
- if (tokenLen <= 2) {
- if (!ParseDigits(ref str, tokenLen, out tempMonth)) {
- if (!parseInfo.fCustomNumberParser ||
- !parseInfo.parseNumberDelegate(ref str, tokenLen, out tempMonth)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- }
- } else {
- if (tokenLen == 3) {
- if (!MatchAbbreviatedMonthName(ref str, dtfi, ref tempMonth)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- } else {
- if (!MatchMonthName(ref str, dtfi, ref tempMonth)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- }
- result.flags |= ParseFlags.ParsedMonthName;
- }
- if (!CheckNewValue(ref result.Month, tempMonth, ch, ref result)) {
- return (false);
- }
- break;
- case 'd':
- // Day & Day of week
- tokenLen = format.GetRepeatCount();
- if (tokenLen <= 2) {
- // "d" & "dd"
-
- if (!ParseDigits(ref str, tokenLen, out tempDay)) {
- if (!parseInfo.fCustomNumberParser ||
- !parseInfo.parseNumberDelegate(ref str, tokenLen, out tempDay)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- }
- if (!CheckNewValue(ref result.Day, tempDay, ch, ref result)) {
- return (false);
- }
- } else {
- if (tokenLen == 3) {
- // "ddd"
- if (!MatchAbbreviatedDayName(ref str, dtfi, ref tempDayOfWeek)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- } else {
- // "dddd*"
- if (!MatchDayName(ref str, dtfi, ref tempDayOfWeek)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- }
- if (!CheckNewValue(ref parseInfo.dayOfWeek, tempDayOfWeek, ch, ref result)) {
- return (false);
- }
- }
- break;
- case 'g':
- tokenLen = format.GetRepeatCount();
- // Put the era value in result.era.
- if (!MatchEraName(ref str, dtfi, ref result.era)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- break;
- case 'h':
- parseInfo.fUseHour12 = true;
- tokenLen = format.GetRepeatCount();
- if (!ParseDigits(ref str, (tokenLen < 2? 1 : 2), out tempHour)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- if (!CheckNewValue(ref result.Hour, tempHour, ch, ref result)) {
- return (false);
- }
- break;
- case 'H':
- tokenLen = format.GetRepeatCount();
- if (!ParseDigits(ref str, (tokenLen < 2? 1 : 2), out tempHour)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- if (!CheckNewValue(ref result.Hour, tempHour, ch, ref result)) {
- return (false);
- }
- break;
- case 'm':
- tokenLen = format.GetRepeatCount();
- if (!ParseDigits(ref str, (tokenLen < 2? 1 : 2), out tempMinute)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- if (!CheckNewValue(ref result.Minute, tempMinute, ch, ref result)) {
- return (false);
- }
- break;
- case 's':
- tokenLen = format.GetRepeatCount();
- if (!ParseDigits(ref str, (tokenLen < 2? 1 : 2), out tempSecond)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- if (!CheckNewValue(ref result.Second, tempSecond, ch, ref result)) {
- return (false);
- }
- break;
- case 'f':
- case 'F':
- tokenLen = format.GetRepeatCount();
- if (tokenLen <= DateTimeFormat.MaxSecondsFractionDigits) {
- if (!ParseFractionExact(ref str, tokenLen, ref tempFraction)) {
- if (ch == 'f') {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- }
- if (result.fraction < 0) {
- result.fraction = tempFraction;
- } else {
- if (tempFraction != result.fraction) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", ch);
- return (false);
- }
- }
- } else {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- break;
- case 't':
- // AM/PM designator
- tokenLen = format.GetRepeatCount();
- if (tokenLen == 1) {
- if (!MatchAbbreviatedTimeMark(ref str, dtfi, ref tempTimeMark)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- } else {
- if (!MatchTimeMark(ref str, dtfi, ref tempTimeMark)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- }
-
- if (parseInfo.timeMark == TM.NotSet) {
- parseInfo.timeMark = tempTimeMark;
- }
- else {
- if (parseInfo.timeMark != tempTimeMark) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", ch);
- return (false);
- }
- }
- break;
- case 'z':
- // timezone offset
- tokenLen = format.GetRepeatCount();
- {
- TimeSpan tempTimeZoneOffset = new TimeSpan(0);
- if (!ParseTimeZoneOffset(ref str, tokenLen, ref tempTimeZoneOffset)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- if ((result.flags & ParseFlags.TimeZoneUsed) != 0 && tempTimeZoneOffset != result.timeZoneOffset) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'z');
- return (false);
- }
- result.timeZoneOffset = tempTimeZoneOffset;
- result.flags |= ParseFlags.TimeZoneUsed;
- }
- break;
- case 'Z':
- if ((result.flags & ParseFlags.TimeZoneUsed) != 0 && result.timeZoneOffset != TimeSpan.Zero) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'Z');
- return (false);
- }
-
- result.flags |= ParseFlags.TimeZoneUsed;
- result.timeZoneOffset = new TimeSpan(0);
- result.flags |= ParseFlags.TimeZoneUtc;
-
- // The updating of the indexes is to reflect that ParseExact MatchXXX methods assume that
- // they need to increment the index and Parse GetXXX do not. Since we are calling a Parse
- // method from inside ParseExact we need to adjust this. Long term, we should try to
- // eliminate this discrepancy.
- str.Index++;
- if (!GetTimeZoneName(ref str)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- str.Index--;
- break;
- case 'K':
- // This should parse either as a blank, the 'Z' character or a local offset like "-07:00"
- if (str.Match('Z')) {
- if ((result.flags & ParseFlags.TimeZoneUsed) != 0 && result.timeZoneOffset != TimeSpan.Zero) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'K');
- return (false);
- }
-
- result.flags |= ParseFlags.TimeZoneUsed;
- result.timeZoneOffset = new TimeSpan(0);
- result.flags |= ParseFlags.TimeZoneUtc;
- }
- else if (str.Match('+') || str.Match('-')) {
- str.Index--; // Put the character back for the parser
- TimeSpan tempTimeZoneOffset = new TimeSpan(0);
- if (!ParseTimeZoneOffset(ref str, 3, ref tempTimeZoneOffset)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return (false);
- }
- if ((result.flags & ParseFlags.TimeZoneUsed) != 0 && tempTimeZoneOffset != result.timeZoneOffset) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_RepeatDateTimePattern", 'K');
- return (false);
- }
- result.timeZoneOffset = tempTimeZoneOffset;
- result.flags |= ParseFlags.TimeZoneUsed;
- }
- // Otherwise it is unspecified and we consume no characters
- break;
- case ':':
- // We match the separator in time pattern with the character in the time string if both equal to ':' or the date separator is matching the characters in the date string
- // We have to exclude the case when the time separator is more than one character and starts with ':' something like "::" for instance.
- if (((dtfi.TimeSeparator.Length > 1 && dtfi.TimeSeparator[0] == ':') || !str.Match(':')) &&
- !str.Match(dtfi.TimeSeparator)) {
- // A time separator is expected.
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- break;
- case '/':
- // We match the separator in date pattern with the character in the date string if both equal to '/' or the date separator is matching the characters in the date string
- // We have to exclude the case when the date separator is more than one character and starts with '/' something like "//" for instance.
- if (((dtfi.DateSeparator.Length > 1 && dtfi.DateSeparator[0] == '/') || !str.Match('/')) &&
- !str.Match(dtfi.DateSeparator))
- {
- // A date separator is expected.
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- break;
- case '\"':
- case '\'':
- StringBuilder enquotedString = new StringBuilder();
- // Use ParseQuoteString so that we can handle escape characters within the quoted string.
- if (!TryParseQuoteString(format.Value, format.Index, enquotedString, out tokenLen)) {
- result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadQuote", ch);
- return (false);
- }
- format.Index += tokenLen - 1;
-
- // Some cultures uses space in the quoted string. E.g. Spanish has long date format as:
- // "dddd, dd' de 'MMMM' de 'yyyy". When inner spaces flag is set, we should skip whitespaces if there is space
- // in the quoted string.
- String quotedStr = enquotedString.ToString();
-
- for (int i = 0; i < quotedStr.Length; i++) {
- if (quotedStr[i] == ' ' && parseInfo.fAllowInnerWhite) {
- str.SkipWhiteSpaces();
- } else if (!str.Match(quotedStr[i])) {
- // Can not find the matching quoted string.
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- }
-
- // The "r" and "u" formats incorrectly quoted 'GMT' and 'Z', respectively. We cannot
- // correct this mistake for DateTime.ParseExact for compatibility reasons, but we can
- // fix it for DateTimeOffset.ParseExact as DateTimeOffset has not been publically released
- // with this issue.
- if ((result.flags & ParseFlags.CaptureOffset) != 0) {
- if ((result.flags & ParseFlags.Rfc1123Pattern) != 0 && quotedStr == GMTName) {
- result.flags |= ParseFlags.TimeZoneUsed;
- result.timeZoneOffset = TimeSpan.Zero;
- }
- else if ((result.flags & ParseFlags.UtcSortPattern) != 0 && quotedStr == ZuluName) {
- result.flags |= ParseFlags.TimeZoneUsed;
- result.timeZoneOffset = TimeSpan.Zero;
- }
- }
-
- break;
- case '%':
- // Skip this so we can get to the next pattern character.
- // Used in case like "%d", "%y"
-
- // Make sure the next character is not a '%' again.
- if (format.Index >= format.Value.Length - 1 || format.Value[format.Index + 1] == '%') {
- result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null);
- return false;
- }
- break;
- case '\\':
- // Escape character. For example, "\d".
- // Get the next character in format, and see if we can
- // find a match in str.
- if (format.GetNext()) {
- if (!str.Match(format.GetChar())) {
- // Can not find a match for the escaped character.
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- } else {
- result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null);
- return false;
- }
- break;
- case '.':
- if (!str.Match(ch)) {
- if (format.GetNext()) {
- // If we encounter the pattern ".F", and the dot is not present, it is an optional
- // second fraction and we can skip this format.
- if (format.Match('F')) {
- format.GetRepeatCount();
- break;
- }
- }
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- break;
- default:
- if (ch == ' ') {
- if (parseInfo.fAllowInnerWhite) {
- // Skip whitespaces if AllowInnerWhite.
- // Do nothing here.
- } else {
- if (!str.Match(ch)) {
- // If the space does not match, and trailing space is allowed, we do
- // one more step to see if the next format character can lead to
- // successful parsing.
- // This is used to deal with special case that a empty string can match
- // a specific pattern.
- // The example here is af-ZA, which has a time format like "hh:mm:ss tt". However,
- // its AM symbol is "" (empty string). If fAllowTrailingWhite is used, and time is in
- // the AM, we will trim the whitespaces at the end, which will lead to a failure
- // when we are trying to match the space before "tt".
- if (parseInfo.fAllowTrailingWhite) {
- if (format.GetNext()) {
- if (ParseByFormat(ref str, ref format, ref parseInfo, dtfi, ref result)) {
- return (true);
- }
- }
- }
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- // Found a macth.
- }
- } else {
- if (format.MatchSpecifiedWord(GMTName)) {
- format.Index += (GMTName.Length - 1);
- // Found GMT string in format. This means the DateTime string
- // is in GMT timezone.
- result.flags |= ParseFlags.TimeZoneUsed;
- result.timeZoneOffset = TimeSpan.Zero;
- if (!str.Match(GMTName)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- } else if (!str.Match(ch)) {
- // ch is expected.
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- }
- break;
- } // switch
- return (true);
- }
-
- //
- // The pos should point to a quote character. This method will
- // get the string enclosed by the quote character.
- //
- internal static bool TryParseQuoteString(String format, int pos, StringBuilder result, out int returnValue) {
- //
- // NOTE : pos will be the index of the quote character in the 'format' string.
- //
- returnValue = 0;
- int formatLen = format.Length;
- int beginPos = pos;
- char quoteChar = format[pos++]; // Get the character used to quote the following string.
-
- bool foundQuote = false;
- while (pos < formatLen) {
- char ch = format[pos++];
- if (ch == quoteChar) {
- foundQuote = true;
- break;
- }
- else if (ch == '\\') {
- // The following are used to support escaped character.
- // Escaped character is also supported in the quoted string.
- // Therefore, someone can use a format like "'minute:' mm\"" to display:
- // minute: 45"
- // because the second double quote is escaped.
- if (pos < formatLen) {
- result.Append(format[pos++]);
- } else {
- //
- // This means that '\' is at the end of the formatting string.
- //
- return false;
- }
- } else {
- result.Append(ch);
- }
- }
-
- if (!foundQuote) {
- // Here we can't find the matching quote.
- return false;
- }
-
- //
- // Return the character count including the begin/end quote characters and enclosed string.
- //
- returnValue = (pos - beginPos);
- return true;
- }
-
-
-
-
- /*=================================DoStrictParse==================================
- **Action: Do DateTime parsing using the format in formatParam.
- **Returns: The parsed DateTime.
- **Arguments:
- **Exceptions:
- **
- **Notes:
- ** When the following general formats are used, InvariantInfo is used in dtfi:
- ** 'r', 'R', 's'.
- ** When the following general formats are used, the time is assumed to be in Universal time.
- **
- **Limitations:
- ** Only GregarianCalendar is supported for now.
- ** Only support GMT timezone.
- ==============================================================================*/
-
- private static bool DoStrictParse(
- String s,
- String formatParam,
- DateTimeStyles styles,
- DateTimeFormatInfo dtfi,
- ref DateTimeResult result) {
-
-
-
- ParsingInfo parseInfo = new ParsingInfo();
- parseInfo.Init();
-
- parseInfo.calendar = dtfi.Calendar;
- parseInfo.fAllowInnerWhite = ((styles & DateTimeStyles.AllowInnerWhite) != 0);
- parseInfo.fAllowTrailingWhite = ((styles & DateTimeStyles.AllowTrailingWhite) != 0);
-
- // We need the original values of the following two below.
- String originalFormat = formatParam;
-
- if (formatParam.Length == 1) {
- if (((result.flags & ParseFlags.CaptureOffset) != 0) && formatParam[0] == 'U') {
- // The 'U' format is not allowed for DateTimeOffset
- result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier", null);
- return false;
- }
- formatParam = ExpandPredefinedFormat(formatParam, ref dtfi, ref parseInfo, ref result);
- }
-
- bool bTimeOnly = false;
- result.calendar = parseInfo.calendar;
-
- if (parseInfo.calendar.ID == Calendar.CAL_HEBREW) {
- parseInfo.parseNumberDelegate = m_hebrewNumberParser;
- parseInfo.fCustomNumberParser = true;
- }
-
- // Reset these values to negative one so that we could throw exception
- // if we have parsed every item twice.
- result.Hour = result.Minute = result.Second = -1;
-
- __DTString format = new __DTString(formatParam, dtfi, false);
- __DTString str = new __DTString(s, dtfi, false);
-
- if (parseInfo.fAllowTrailingWhite) {
- // Trim trailing spaces if AllowTrailingWhite.
- format.TrimTail();
- format.RemoveTrailingInQuoteSpaces();
- str.TrimTail();
- }
-
- if ((styles & DateTimeStyles.AllowLeadingWhite) != 0) {
- format.SkipWhiteSpaces();
- format.RemoveLeadingInQuoteSpaces();
- str.SkipWhiteSpaces();
- }
-
- //
- // Scan every character in format and match the pattern in str.
- //
- while (format.GetNext()) {
- // We trim inner spaces here, so that we will not eat trailing spaces when
- // AllowTrailingWhite is not used.
- if (parseInfo.fAllowInnerWhite) {
- str.SkipWhiteSpaces();
- }
- if (!ParseByFormat(ref str, ref format, ref parseInfo, dtfi, ref result)) {
- return (false);
- }
- }
-
- if (str.Index < str.Value.Length - 1) {
- // There are still remaining character in str.
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
-
- if (parseInfo.fUseTwoDigitYear && ((dtfi.FormatFlags & DateTimeFormatFlags.UseHebrewRule) == 0)) {
- // A two digit year value is expected. Check if the parsed year value is valid.
- if (result.Year >= 100) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- try {
- result.Year = parseInfo.calendar.ToFourDigitYear(result.Year);
- }
- catch (ArgumentOutOfRangeException e) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", e);
- return false;
- }
- }
-
- if (parseInfo.fUseHour12) {
- if (parseInfo.timeMark == TM.NotSet) {
- // hh is used, but no AM/PM designator is specified.
- // Assume the time is AM.
- // Don't throw exceptions in here becasue it is very confusing for the caller.
- // I always got confused myself when I use "hh:mm:ss" to parse a time string,
- // and ParseExact() throws on me (because I didn't use the 24-hour clock 'HH').
- parseInfo.timeMark = TM.AM;
- }
- if (result.Hour > 12) {
- // AM/PM is used, but the value for HH is too big.
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- if (parseInfo.timeMark == TM.AM) {
- if (result.Hour == 12) {
- result.Hour = 0;
- }
- } else {
- result.Hour = (result.Hour == 12) ? 12 : result.Hour + 12;
- }
- }
- else
- {
- // Military (24-hour time) mode
- //
- // AM cannot be set with a 24-hour time like 17:15.
- // PM cannot be set with a 24-hour time like 03:15.
- if ( (parseInfo.timeMark == TM.AM && result.Hour >= 12)
- ||(parseInfo.timeMark == TM.PM && result.Hour < 12)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDateTime", null);
- return false;
- }
- }
-
-
- // Check if the parased string only contains hour/minute/second values.
- bTimeOnly = (result.Year == -1 && result.Month == -1 && result.Day == -1);
- if (!CheckDefaultDateTime(ref result, ref parseInfo.calendar, styles)) {
- return false;
- }
-
- if (!bTimeOnly && dtfi.HasYearMonthAdjustment) {
- if (!dtfi.YearMonthAdjustment(ref result.Year, ref result.Month, ((result.flags & ParseFlags.ParsedMonthName) != 0))) {
- result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
- return false;
- }
- }
- if (!parseInfo.calendar.TryToDateTime(result.Year, result.Month, result.Day,
- result.Hour, result.Minute, result.Second, 0, result.era, out result.parsedDate)) {
- result.SetFailure(ParseFailureKind.FormatBadDateTimeCalendar, "Format_BadDateTimeCalendar", null);
- return false;
- }
- if (result.fraction > 0) {
- result.parsedDate = result.parsedDate.AddTicks((long)Math.Round(result.fraction * Calendar.TicksPerSecond));
- }
-
- //
- // We have to check day of week before we adjust to the time zone.
- // It is because the value of day of week may change after adjusting
- // to the time zone.
- //
- if (parseInfo.dayOfWeek != -1) {
- //
- // Check if day of week is correct.
- //
- if (parseInfo.dayOfWeek != (int)parseInfo.calendar.GetDayOfWeek(result.parsedDate)) {
- result.SetFailure(ParseFailureKind.Format, "Format_BadDayOfWeek", null);
- return false;
- }
- }
-
-
- if (!DetermineTimeZoneAdjustments(ref result, styles, bTimeOnly)) {
- return false;
- }
- return true;
- }
-
- private static Exception GetDateTimeParseException(ref DateTimeResult result) {
- switch (result.failure) {
- case ParseFailureKind.ArgumentNull:
- return new ArgumentNullException(result.failureArgumentName, Environment.GetResourceString(result.failureMessageID));
- case ParseFailureKind.Format:
- return new FormatException(Environment.GetResourceString(result.failureMessageID));
- case ParseFailureKind.FormatWithParameter:
- return new FormatException(Environment.GetResourceString(result.failureMessageID, result.failureMessageFormatArgument));
- case ParseFailureKind.FormatBadDateTimeCalendar:
- return new FormatException(Environment.GetResourceString(result.failureMessageID, result.calendar));
- default:
- Debug.Assert(false, "Unkown DateTimeParseFailure: " + result);
- return null;
-
- }
- }
-
- // Builds with _LOGGING defined (x86dbg, amd64chk, etc) support tracing
- // Set the following internal-only/unsupported environment variables to enable DateTime tracing to the console:
- //
- // COMPlus_LogEnable=1
- // COMPlus_LogToConsole=1
- // COMPlus_LogLevel=9
- // COMPlus_ManagedLogFacility=0x00001000
- [Pure]
- [Conditional("_LOGGING")]
- internal static void LexTraceExit(string message, DS dps) {
-#if _LOGGING
- if (!_tracingEnabled)
- return;
- BCLDebug.Trace("DATETIME", "[DATETIME] Lex return {0}, DS.{1}", message, dps);
-#endif // _LOGGING
- }
- [Pure]
- [Conditional("_LOGGING")]
- internal static void PTSTraceExit(DS dps, bool passed) {
-#if _LOGGING
- if (!_tracingEnabled)
- return;
- BCLDebug.Trace("DATETIME", "[DATETIME] ProcessTerminalState {0} @ DS.{1}", passed ? "passed" : "failed", dps);
-#endif // _LOGGING
- }
- [Pure]
- [Conditional("_LOGGING")]
- internal static void TPTraceExit(string message, DS dps) {
-#if _LOGGING
- if (!_tracingEnabled)
- return;
- BCLDebug.Trace("DATETIME", "[DATETIME] TryParse return {0}, DS.{1}", message, dps);
-#endif // _LOGGING
- }
- [Pure]
- [Conditional("_LOGGING")]
- internal static void DTFITrace(DateTimeFormatInfo dtfi) {
-#if _LOGGING
- if (!_tracingEnabled)
- return;
-
- BCLDebug.Trace("DATETIME", "[DATETIME] DateTimeFormatInfo Properties");
-#if !FEATURE_COREFX_GLOBALIZATION
- BCLDebug.Trace("DATETIME", " NativeCalendarName {0}", Hex(dtfi.NativeCalendarName));
-#endif
- BCLDebug.Trace("DATETIME", " AMDesignator {0}", Hex(dtfi.AMDesignator));
- BCLDebug.Trace("DATETIME", " PMDesignator {0}", Hex(dtfi.PMDesignator));
- BCLDebug.Trace("DATETIME", " TimeSeparator {0}", Hex(dtfi.TimeSeparator));
- BCLDebug.Trace("DATETIME", " AbbrvDayNames {0}", Hex(dtfi.AbbreviatedDayNames));
- BCLDebug.Trace("DATETIME", " ShortestDayNames {0}", Hex(dtfi.ShortestDayNames));
- BCLDebug.Trace("DATETIME", " DayNames {0}", Hex(dtfi.DayNames));
- BCLDebug.Trace("DATETIME", " AbbrvMonthNames {0}", Hex(dtfi.AbbreviatedMonthNames));
- BCLDebug.Trace("DATETIME", " MonthNames {0}", Hex(dtfi.MonthNames));
- BCLDebug.Trace("DATETIME", " AbbrvMonthGenNames {0}", Hex(dtfi.AbbreviatedMonthGenitiveNames));
- BCLDebug.Trace("DATETIME", " MonthGenNames {0}", Hex(dtfi.MonthGenitiveNames));
-#endif // _LOGGING
- }
-#if _LOGGING
- [Pure]
- // return a string in the form: "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
- internal static string Hex(string[] strs) {
- if (strs == null || strs.Length == 0)
- return String.Empty;
- if (strs.Length == 1)
- return Hex(strs[0]);
-
- int curLineLength = 0;
- int maxLineLength = 55;
- int newLinePadding = 20;
-
-
- //invariant: strs.Length >= 2
- StringBuilder buffer = new StringBuilder();
- buffer.Append(Hex(strs[0]));
- curLineLength = buffer.Length;
- String s;
-
- for (int i = 1; i < strs.Length-1; i++) {
- s = Hex(strs[i]);
-
- if (s.Length > maxLineLength || (curLineLength + s.Length + 2) > maxLineLength) {
- buffer.Append(',');
- buffer.Append(Environment.NewLine);
- buffer.Append(' ', newLinePadding);
- curLineLength = 0;
- }
- else {
- buffer.Append(", ");
- curLineLength += 2;
- }
- buffer.Append(s);
- curLineLength += s.Length;
- }
-
- buffer.Append(',');
- s = Hex(strs[strs.Length-1]);
- if (s.Length > maxLineLength || (curLineLength + s.Length + 6) > maxLineLength) {
- buffer.Append(Environment.NewLine);
- buffer.Append(' ', newLinePadding);
- }
- else {
- buffer.Append(' ');
- }
- buffer.Append(s);
- return buffer.ToString();
- }
- [Pure]
- // return a string in the form: "Sun"
- internal static string Hex(string str) {
- StringBuilder buffer = new StringBuilder();
- buffer.Append("\"");
- for (int i = 0; i < str.Length; i++) {
- if (str[i] <= '\x007f')
- buffer.Append(str[i]);
- else
- buffer.Append("\\u" + ((int)str[i]).ToString("x4", CultureInfo.InvariantCulture));
- }
- buffer.Append("\"");
- return buffer.ToString();
- }
- [Pure]
- // return an unicode escaped string form of char c
- internal static String Hex(char c) {
- if (c <= '\x007f')
- return c.ToString(CultureInfo.InvariantCulture);
- else
- return "\\u" + ((int)c).ToString("x4", CultureInfo.InvariantCulture);
- }
-
- internal static bool _tracingEnabled = BCLDebug.CheckEnabled("DATETIME");
-#endif // _LOGGING
- }
-
-
- //
- // This is a string parsing helper which wraps a String object.
- // It has a Index property which tracks
- // the current parsing pointer of the string.
- //
- internal
- struct __DTString
- {
-
- //
- // Value propery: stores the real string to be parsed.
- //
- internal String Value;
-
- //
- // Index property: points to the character that we are currently parsing.
- //
- internal int Index;
-
- // The length of Value string.
- internal int len;
-
- // The current chracter to be looked at.
- internal char m_current;
-
- private CompareInfo m_info;
- // Flag to indicate if we encouter an digit, we should check for token or not.
- // In some cultures, such as mn-MN, it uses "\x0031\x00a0\x0434\x04af\x0433\x044d\x044d\x0440\x00a0\x0441\x0430\x0440" in month names.
- private bool m_checkDigitToken;
-
- internal __DTString(String str, DateTimeFormatInfo dtfi, bool checkDigitToken) : this (str, dtfi)
- {
- m_checkDigitToken = checkDigitToken;
- }
-
- internal __DTString(String str, DateTimeFormatInfo dtfi)
- {
- Index = -1;
- Value = str;
- len = Value.Length;
-
- m_current = '\0';
- if (dtfi != null)
- {
- m_info = dtfi.CompareInfo;
- m_checkDigitToken = ((dtfi.FormatFlags & DateTimeFormatFlags.UseDigitPrefixInTokens) != 0);
- } else
- {
- m_info = Thread.CurrentThread.CurrentCulture.CompareInfo;
- m_checkDigitToken = false;
- }
- }
-
- internal CompareInfo CompareInfo
- {
- get { return m_info; }
- }
-
- //
- // Advance the Index.
- // Return true if Index is NOT at the end of the string.
- //
- // Typical usage:
- // while (str.GetNext())
- // {
- // char ch = str.GetChar()
- // }
- internal bool GetNext() {
- Index++;
- if (Index < len) {
- m_current = Value[Index];
- return (true);
- }
- return (false);
- }
-
- internal bool AtEnd()
- {
- return Index < len ? false : true;
- }
-
- internal bool Advance(int count) {
- Debug.Assert(Index + count <= len, "__DTString::Advance: Index + count <= len");
- Index += count;
- if (Index < len) {
- m_current = Value[Index];
- return (true);
- }
- return (false);
- }
-
-
- // Used by DateTime.Parse() to get the next token.
- internal void GetRegularToken(out TokenType tokenType, out int tokenValue, DateTimeFormatInfo dtfi) {
- tokenValue = 0;
- if (Index >= len) {
- tokenType = TokenType.EndOfString;
- return;
- }
-
- tokenType = TokenType.UnknownToken;
-
-Start:
- if (DateTimeParse.IsDigit(m_current)) {
- // This is a digit.
- tokenValue = m_current - '0';
- int value;
- int start = Index;
-
- //
- // Collect other digits.
- //
- while (++Index < len)
- {
- m_current = Value[Index];
- value = m_current - '0';
- if (value >= 0 && value <= 9) {
- tokenValue = tokenValue * 10 + value;
- } else {
- break;
- }
- }
- if (Index - start > DateTimeParse.MaxDateTimeNumberDigits) {
- tokenType = TokenType.NumberToken;
- tokenValue = -1;
- } else if (Index - start < 3) {
- tokenType = TokenType.NumberToken;
- } else {
- // If there are more than 3 digits, assume that it's a year value.
- tokenType = TokenType.YearNumberToken;
- }
- if (m_checkDigitToken)
- {
- int save = Index;
- char saveCh = m_current;
- // Re-scan using the staring Index to see if this is a token.
- Index = start; // To include the first digit.
- m_current = Value[Index];
- TokenType tempType;
- int tempValue;
- // This DTFI has tokens starting with digits.
- // E.g. mn-MN has month name like "\x0031\x00a0\x0434\x04af\x0433\x044d\x044d\x0440\x00a0\x0441\x0430\x0440"
- if (dtfi.Tokenize(TokenType.RegularTokenMask, out tempType, out tempValue, ref this))
- {
- tokenType = tempType;
- tokenValue = tempValue;
- // This is a token, so the Index has been advanced propertly in DTFI.Tokenizer().
- } else
- {
- // Use the number token value.
- // Restore the index.
- Index = save;
- m_current = saveCh;
- }
-
- }
-
- } else if (Char.IsWhiteSpace( m_current)) {
- // Just skip to the next character.
- while (++Index < len) {
- m_current = Value[Index];
- if (!(Char.IsWhiteSpace(m_current))) {
- goto Start;
- }
- }
- // We have reached the end of string.
- tokenType = TokenType.EndOfString;
- } else {
- dtfi.Tokenize(TokenType.RegularTokenMask, out tokenType, out tokenValue, ref this);
- }
- }
-
- internal TokenType GetSeparatorToken(DateTimeFormatInfo dtfi, out int indexBeforeSeparator, out char charBeforeSeparator) {
- indexBeforeSeparator = Index;
- charBeforeSeparator = m_current;
- TokenType tokenType;
- if (!SkipWhiteSpaceCurrent()) {
- // Reach the end of the string.
- return (TokenType.SEP_End);
- }
- if (!DateTimeParse.IsDigit(m_current)) {
- // Not a digit. Tokenize it.
- int tokenValue;
- bool found = dtfi.Tokenize(TokenType.SeparatorTokenMask, out tokenType, out tokenValue, ref this);
- if (!found) {
- tokenType = TokenType.SEP_Space;
- }
- } else {
- // Do nothing here. If we see a number, it will not be a separator. There is no need wasting time trying to find the
- // separator token.
- tokenType = TokenType.SEP_Space;
- }
- return (tokenType);
- }
-
- internal bool MatchSpecifiedWord(String target) {
- return MatchSpecifiedWord(target, target.Length + Index);
- }
-
- internal bool MatchSpecifiedWord(String target, int endIndex) {
- int count = endIndex - Index;
-
- if (count != target.Length) {
- return false;
- }
-
- if (Index + count > len) {
- return false;
- }
-
- return (m_info.Compare(Value, Index, count, target, 0, count, CompareOptions.IgnoreCase)==0);
- }
-
- private static Char[] WhiteSpaceChecks = new Char[] { ' ', '\u00A0' };
-
- internal bool MatchSpecifiedWords(String target, bool checkWordBoundary, ref int matchLength) {
- int valueRemaining = Value.Length - Index;
- matchLength = target.Length;
-
- if (matchLength > valueRemaining || m_info.Compare(Value, Index, matchLength, target, 0, matchLength, CompareOptions.IgnoreCase) !=0) {
- // Check word by word
- int targetPosition = 0; // Where we are in the target string
- int thisPosition = Index; // Where we are in this string
- int wsIndex = target.IndexOfAny(WhiteSpaceChecks, targetPosition);
- if (wsIndex == -1) {
- return false;
- }
- do {
- int segmentLength = wsIndex - targetPosition;
- if (thisPosition >= Value.Length - segmentLength) { // Subtraction to prevent overflow.
- return false;
- }
- if (segmentLength == 0) {
- // If segmentLength == 0, it means that we have leading space in the target string.
- // In that case, skip the leading spaces in the target and this string.
- matchLength--;
- } else {
- // Make sure we also have whitespace in the input string
- if (!Char.IsWhiteSpace(Value[thisPosition + segmentLength])) {
- return false;
- }
- if (m_info.Compare(Value, thisPosition, segmentLength, target, targetPosition, segmentLength, CompareOptions.IgnoreCase) !=0) {
- return false;
- }
- // Advance the input string
- thisPosition = thisPosition + segmentLength + 1;
- }
- // Advance our target string
- targetPosition = wsIndex + 1;
-
-
- // Skip past multiple whitespace
- while (thisPosition < Value.Length && Char.IsWhiteSpace(Value[thisPosition])) {
- thisPosition++;
- matchLength++;
- }
- } while ((wsIndex = target.IndexOfAny(WhiteSpaceChecks, targetPosition)) >= 0);
- // now check the last segment;
- if (targetPosition < target.Length) {
- int segmentLength = target.Length - targetPosition;
- if (thisPosition > Value.Length - segmentLength) {
- return false;
- }
- if (m_info.Compare(Value, thisPosition, segmentLength, target, targetPosition, segmentLength, CompareOptions.IgnoreCase) !=0) {
- return false;
- }
- }
- }
-
- if (checkWordBoundary) {
- int nextCharIndex = Index + matchLength;
- if (nextCharIndex < Value.Length) {
- if (Char.IsLetter(Value[nextCharIndex])) {
- return (false);
- }
- }
- }
- return (true);
- }
-
- //
- // Check to see if the string starting from Index is a prefix of
- // str.
- // If a match is found, true value is returned and Index is updated to the next character to be parsed.
- // Otherwise, Index is unchanged.
- //
- internal bool Match(String str) {
- if (++Index >= len) {
- return (false);
- }
-
- if (str.Length > (Value.Length - Index)) {
- return false;
- }
-
- if (m_info.Compare(Value, Index, str.Length, str, 0, str.Length, CompareOptions.Ordinal)==0) {
- // Update the Index to the end of the matching string.
- // So the following GetNext()/Match() opeartion will get
- // the next character to be parsed.
- Index += (str.Length - 1);
- return (true);
- }
- return (false);
- }
-
- internal bool Match(char ch) {
- if (++Index >= len) {
- return (false);
- }
- if (Value[Index] == ch) {
- m_current = ch;
- return (true);
- }
- Index--;
- return (false);
- }
-
- //
- // Actions: From the current position, try matching the longest word in the specified string array.
- // E.g. words[] = {"AB", "ABC", "ABCD"}, if the current position points to a substring like "ABC DEF",
- // MatchLongestWords(words, ref MaxMatchStrLen) will return 1 (the index), and maxMatchLen will be 3.
- // Returns:
- // The index that contains the longest word to match
- // Arguments:
- // words The string array that contains words to search.
- // maxMatchStrLen [in/out] the initailized maximum length. This parameter can be used to
- // find the longest match in two string arrays.
- //
- internal int MatchLongestWords(String[] words, ref int maxMatchStrLen) {
- int result = -1;
- for (int i = 0; i < words.Length; i++) {
- String word = words[i];
- int matchLength = word.Length;
- if (MatchSpecifiedWords(word, false, ref matchLength)) {
- if (matchLength > maxMatchStrLen) {
- maxMatchStrLen = matchLength;
- result = i;
- }
- }
- }
-
- return (result);
- }
-
- //
- // Get the number of repeat character after the current character.
- // For a string "hh:mm:ss" at Index of 3. GetRepeatCount() = 2, and Index
- // will point to the second ':'.
- //
- internal int GetRepeatCount() {
- char repeatChar = Value[Index];
- int pos = Index + 1;
- while ((pos < len) && (Value[pos] == repeatChar)) {
- pos++;
- }
- int repeatCount = (pos - Index);
- // Update the Index to the end of the repeated characters.
- // So the following GetNext() opeartion will get
- // the next character to be parsed.
- Index = pos - 1;
- return (repeatCount);
- }
-
- // Return false when end of string is encountered or a non-digit character is found.
- internal bool GetNextDigit() {
- if (++Index >= len) {
- return (false);
- }
- return (DateTimeParse.IsDigit(Value[Index]));
- }
-
- //
- // Get the current character.
- //
- internal char GetChar() {
- Debug.Assert(Index >= 0 && Index < len, "Index >= 0 && Index < len");
- return (Value[Index]);
- }
-
- //
- // Convert the current character to a digit, and return it.
- //
- internal int GetDigit() {
- Debug.Assert(Index >= 0 && Index < len, "Index >= 0 && Index < len");
- Debug.Assert(DateTimeParse.IsDigit(Value[Index]), "IsDigit(Value[Index])");
- return (Value[Index] - '0');
- }
-
- //
- // Eat White Space ahead of the current position
- //
- // Return false if end of string is encountered.
- //
- internal void SkipWhiteSpaces()
- {
- // Look ahead to see if the next character
- // is a whitespace.
- while (Index+1 < len)
- {
- char ch = Value[Index+1];
- if (!Char.IsWhiteSpace(ch)) {
- return;
- }
- Index++;
- }
- return;
- }
-
- //
- // Skip white spaces from the current position
- //
- // Return false if end of string is encountered.
- //
- internal bool SkipWhiteSpaceCurrent()
- {
- if (Index >= len) {
- return (false);
- }
-
- if (!Char.IsWhiteSpace(m_current))
- {
- return (true);
- }
-
- while (++Index < len)
- {
- m_current = Value[Index];
- if (!Char.IsWhiteSpace(m_current))
- {
- return (true);
- }
- // Nothing here.
- }
- return (false);
- }
-
- internal void TrimTail() {
- int i = len - 1;
- while (i >= 0 && Char.IsWhiteSpace(Value[i])) {
- i--;
- }
- Value = Value.Substring(0, i + 1);
- len = Value.Length;
- }
-
- // Trim the trailing spaces within a quoted string.
- // Call this after TrimTail() is done.
- internal void RemoveTrailingInQuoteSpaces() {
- int i = len - 1;
- if (i <= 1) {
- return;
- }
- char ch = Value[i];
- // Check if the last character is a quote.
- if (ch == '\'' || ch == '\"') {
- if (Char.IsWhiteSpace(Value[i-1])) {
- i--;
- while (i >= 1 && Char.IsWhiteSpace(Value[i-1])) {
- i--;
- }
- Value = Value.Remove(i, Value.Length - 1 - i);
- len = Value.Length;
- }
- }
- }
-
- // Trim the leading spaces within a quoted string.
- // Call this after the leading spaces before quoted string are trimmed.
- internal void RemoveLeadingInQuoteSpaces() {
- if (len <= 2) {
- return;
- }
- int i = 0;
- char ch = Value[i];
- // Check if the last character is a quote.
- if (ch == '\'' || ch == '\"') {
- while ((i + 1) < len && Char.IsWhiteSpace(Value[i+1])) {
- i++;
- }
- if (i != 0) {
- Value = Value.Remove(1, i);
- len = Value.Length;
- }
- }
- }
-
- internal DTSubString GetSubString() {
- DTSubString sub = new DTSubString();
- sub.index = Index;
- sub.s = Value;
- while (Index + sub.length < len) {
- DTSubStringType currentType;
- Char ch = Value[Index + sub.length];
- if (ch >= '0' && ch <= '9') {
- currentType = DTSubStringType.Number;
- }
- else {
- currentType = DTSubStringType.Other;
- }
-
- if (sub.length == 0) {
- sub.type = currentType;
- }
- else {
- if (sub.type != currentType) {
- break;
- }
- }
- sub.length++;
- if (currentType == DTSubStringType.Number) {
- // Incorporate the number into the value
- // Limit the digits to prevent overflow
- if (sub.length > DateTimeParse.MaxDateTimeNumberDigits) {
- sub.type = DTSubStringType.Invalid;
- return sub;
- }
- int number = ch - '0';
- Debug.Assert(number >= 0 && number <= 9, "number >= 0 && number <= 9");
- sub.value = sub.value * 10 + number;
- }
- else {
- // For non numbers, just return this length 1 token. This should be expanded
- // to more types of thing if this parsing approach is used for things other
- // than numbers and single characters
- break;
- }
- }
- if (sub.length == 0) {
- sub.type = DTSubStringType.End;
- return sub;
- }
-
- return sub;
- }
-
- internal void ConsumeSubString(DTSubString sub) {
- Debug.Assert(sub.index == Index, "sub.index == Index");
- Debug.Assert(sub.index + sub.length <= len, "sub.index + sub.length <= len");
- Index = sub.index + sub.length;
- if (Index < len) {
- m_current = Value[Index];
- }
- }
- }
-
- internal enum DTSubStringType {
- Unknown = 0,
- Invalid = 1,
- Number = 2,
- End = 3,
- Other = 4,
- }
-
- internal struct DTSubString {
- internal String s;
- internal Int32 index;
- internal Int32 length;
- internal DTSubStringType type;
- internal Int32 value;
-
- internal Char this[Int32 relativeIndex] {
- get {
- return s[index + relativeIndex];
- }
- }
- }
-
- //
- // The buffer to store the parsing token.
- //
- internal
- struct DateTimeToken {
- internal DateTimeParse.DTT dtt; // Store the token
- internal TokenType suffix; // Store the CJK Year/Month/Day suffix (if any)
- internal int num; // Store the number that we are parsing (if any)
- }
-
- //
- // The buffer to store temporary parsing information.
- //
- internal
- unsafe struct DateTimeRawInfo {
- private int* num;
- internal int numCount;
- internal int month;
- internal int year;
- internal int dayOfWeek;
- internal int era;
- internal DateTimeParse.TM timeMark;
- internal double fraction;
- internal bool hasSameDateAndTimeSeparators;
- //
-
- internal bool timeZone;
-
- internal void Init(int * numberBuffer) {
- month = -1;
- year = -1;
- dayOfWeek = -1;
- era = -1;
- timeMark = DateTimeParse.TM.NotSet;
- fraction = -1;
- num = numberBuffer;
- }
- internal unsafe void AddNumber(int value) {
- num[numCount++] = value;
- }
- internal unsafe int GetNumber(int index) {
- return num[index];
- }
- }
-
- internal enum ParseFailureKind {
- None = 0,
- ArgumentNull = 1,
- Format = 2,
- FormatWithParameter = 3,
- FormatBadDateTimeCalendar = 4, // FormatException when ArgumentOutOfRange is thrown by a Calendar.TryToDateTime().
- };
-
- [Flags]
- internal enum ParseFlags {
- HaveYear = 0x00000001,
- HaveMonth = 0x00000002,
- HaveDay = 0x00000004,
- HaveHour = 0x00000008,
- HaveMinute = 0x00000010,
- HaveSecond = 0x00000020,
- HaveTime = 0x00000040,
- HaveDate = 0x00000080,
- TimeZoneUsed = 0x00000100,
- TimeZoneUtc = 0x00000200,
- ParsedMonthName = 0x00000400,
- CaptureOffset = 0x00000800,
- YearDefault = 0x00001000,
- Rfc1123Pattern = 0x00002000,
- UtcSortPattern = 0x00004000,
- }
-
- //
- // This will store the result of the parsing. And it will be eventually
- // used to construct a DateTime instance.
- //
- internal
- struct DateTimeResult
- {
- internal int Year;
- internal int Month;
- internal int Day;
- //
- // Set time defualt to 00:00:00.
- //
- internal int Hour;
- internal int Minute;
- internal int Second;
- internal double fraction;
-
- internal int era;
-
- internal ParseFlags flags;
-
- internal TimeSpan timeZoneOffset;
-
- internal Calendar calendar;
-
- internal DateTime parsedDate;
-
- internal ParseFailureKind failure;
- internal string failureMessageID;
- internal object failureMessageFormatArgument;
- internal string failureArgumentName;
-
- internal void Init() {
- Year = -1;
- Month = -1;
- Day = -1;
- fraction = -1;
- era = -1;
- }
-
- internal void SetDate(int year, int month, int day)
- {
- Year = year;
- Month = month;
- Day = day;
- }
- internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument) {
- this.failure = failure;
- this.failureMessageID = failureMessageID;
- this.failureMessageFormatArgument = failureMessageFormatArgument;
- }
-
- internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument, string failureArgumentName) {
- this.failure = failure;
- this.failureMessageID = failureMessageID;
- this.failureMessageFormatArgument = failureMessageFormatArgument;
- this.failureArgumentName = failureArgumentName;
- }
-
-
-
-
- }
-
- // This is the helper data structure used in ParseExact().
- internal struct ParsingInfo {
-
- internal Calendar calendar;
- internal int dayOfWeek;
- internal DateTimeParse.TM timeMark;
-
- internal bool fUseHour12;
- internal bool fUseTwoDigitYear;
- internal bool fAllowInnerWhite;
- internal bool fAllowTrailingWhite;
- internal bool fCustomNumberParser;
- internal DateTimeParse.MatchNumberDelegate parseNumberDelegate;
-
- internal void Init() {
- dayOfWeek = -1;
- timeMark = DateTimeParse.TM.NotSet;
- }
-
- }
-
- //
- // The type of token that will be returned by DateTimeFormatInfo.Tokenize().
- //
- internal enum TokenType {
- // The valid token should start from 1.
-
- // Regular tokens. The range is from 0x00 ~ 0xff.
- NumberToken = 1, // The number. E.g. "12"
- YearNumberToken = 2, // The number which is considered as year number, which has 3 or more digits. E.g. "2003"
- Am = 3, // AM timemark. E.g. "AM"
- Pm = 4, // PM timemark. E.g. "PM"
- MonthToken = 5, // A word (or words) that represents a month name. E.g. "March"
- EndOfString = 6, // End of string
- DayOfWeekToken = 7, // A word (or words) that represents a day of week name. E.g. "Monday" or "Mon"
- TimeZoneToken = 8, // A word that represents a timezone name. E.g. "GMT"
- EraToken = 9, // A word that represents a era name. E.g. "A.D."
- DateWordToken = 10, // A word that can appear in a DateTime string, but serves no parsing semantics. E.g. "de" in Spanish culture.
- UnknownToken = 11, // An unknown word, which signals an error in parsing.
- HebrewNumber = 12, // A number that is composed of Hebrew text. Hebrew calendar uses Hebrew digits for year values, month values, and day values.
- JapaneseEraToken= 13, // Era name for JapaneseCalendar
- TEraToken = 14, // Era name for TaiwanCalendar
- IgnorableSymbol = 15, // A separator like "," that is equivalent to whitespace
-
-
- // Separator tokens.
- SEP_Unk = 0x100, // Unknown separator.
- SEP_End = 0x200, // The end of the parsing string.
- SEP_Space = 0x300, // Whitespace (including comma).
- SEP_Am = 0x400, // AM timemark. E.g. "AM"
- SEP_Pm = 0x500, // PM timemark. E.g. "PM"
- SEP_Date = 0x600, // date separator. E.g. "/"
- SEP_Time = 0x700, // time separator. E.g. ":"
- SEP_YearSuff = 0x800, // Chinese/Japanese/Korean year suffix.
- SEP_MonthSuff = 0x900, // Chinese/Japanese/Korean month suffix.
- SEP_DaySuff = 0xa00, // Chinese/Japanese/Korean day suffix.
- SEP_HourSuff = 0xb00, // Chinese/Japanese/Korean hour suffix.
- SEP_MinuteSuff = 0xc00, // Chinese/Japanese/Korean minute suffix.
- SEP_SecondSuff = 0xd00, // Chinese/Japanese/Korean second suffix.
- SEP_LocalTimeMark = 0xe00, // 'T', used in ISO 8601 format.
- SEP_DateOrOffset = 0xf00, // '-' which could be a date separator or start of a time zone offset
-
- RegularTokenMask = 0x00ff,
- SeparatorTokenMask = 0xff00,
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/DateTimeStyles.cs b/src/mscorlib/src/System/Globalization/DateTimeStyles.cs
deleted file mode 100644
index eadeda8e72..0000000000
--- a/src/mscorlib/src/System/Globalization/DateTimeStyles.cs
+++ /dev/null
@@ -1,49 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose: Contains valid formats for DateTime recognized by
-** the DateTime class' parsing code.
-**
-**
-===========================================================*/
-namespace System.Globalization {
-
-
-[Serializable]
- [Flags]
- public enum DateTimeStyles {
- // Bit flag indicating that leading whitespace is allowed. Character values
- // 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, and 0x0020 are considered to be
- // whitespace.
-
-
- None = 0x00000000,
-
- AllowLeadingWhite = 0x00000001,
-
- AllowTrailingWhite = 0x00000002, //Bitflag indicating trailing whitespace is allowed.
-
- AllowInnerWhite = 0x00000004,
-
- AllowWhiteSpaces = AllowLeadingWhite | AllowInnerWhite | AllowTrailingWhite,
- // When parsing a date/time string, if all year/month/day are missing, set the default date
- // to 0001/1/1, instead of the current year/month/day.
-
- NoCurrentDateDefault = 0x00000008,
- // When parsing a date/time string, if a timezone specifier ("GMT","Z","+xxxx", "-xxxx" exists), we will
- // ajdust the parsed time based to GMT.
-
- AdjustToUniversal = 0x00000010,
-
- AssumeLocal = 0x00000020,
-
- AssumeUniversal = 0x00000040,
- // Attempt to preserve whether the input is unspecified, local or UTC
- RoundtripKind = 0x00000080,
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/DaylightTime.cs b/src/mscorlib/src/System/Globalization/DaylightTime.cs
deleted file mode 100644
index a21e092955..0000000000
--- a/src/mscorlib/src/System/Globalization/DaylightTime.cs
+++ /dev/null
@@ -1,63 +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.Runtime.InteropServices;
-
-namespace System.Globalization
-{
- // This class represents a starting/ending time for a period of daylight saving time.
- [Serializable]
- public class DaylightTime
- {
- internal DateTime m_start;
- internal DateTime m_end;
- internal TimeSpan m_delta;
-
- private DaylightTime() {
- }
-
- public DaylightTime(DateTime start, DateTime end, TimeSpan delta) {
- m_start = start;
- m_end = end;
- m_delta = delta;
- }
-
- // The start date of a daylight saving period.
- public DateTime Start {
- get {
- return m_start;
- }
- }
-
- // The end date of a daylight saving period.
- public DateTime End {
- get {
- return m_end;
- }
- }
-
- // Delta to stardard offset in ticks.
- public TimeSpan Delta {
- get {
- return m_delta;
- }
- }
-
- }
-
- // Value type version of DaylightTime
- internal struct DaylightTimeStruct
- {
- public DaylightTimeStruct(DateTime start, DateTime end, TimeSpan delta)
- {
- Start = start;
- End = end;
- Delta = delta;
- }
-
- public DateTime Start { get; }
- public DateTime End { get; }
- public TimeSpan Delta { get; }
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/DigitShapes.cs b/src/mscorlib/src/System/Globalization/DigitShapes.cs
deleted file mode 100644
index 1513d56f5c..0000000000
--- a/src/mscorlib/src/System/Globalization/DigitShapes.cs
+++ /dev/null
@@ -1,21 +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.
-
-//
-// The enumeration constants used in NumberFormatInfo.DigitSubstitution.
-//
-namespace System.Globalization {
-
-
- [Serializable]
- public enum DigitShapes : int {
-
- Context = 0x0000, // The shape depends on the previous text in the same output.
-
- None = 0x0001, // Gives full Unicode compatibility.
-
- NativeNational = 0x0002, // National shapes determined by LOCALE_SNATIVEDIGITS
- }
-}
-
diff --git a/src/mscorlib/src/System/Globalization/EastAsianLunisolarCalendar.cs b/src/mscorlib/src/System/Globalization/EastAsianLunisolarCalendar.cs
deleted file mode 100644
index 3f6df52a96..0000000000
--- a/src/mscorlib/src/System/Globalization/EastAsianLunisolarCalendar.cs
+++ /dev/null
@@ -1,643 +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.
-
-namespace System.Globalization {
- using System;
- using System.Diagnostics.Contracts;
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about EastAsianLunisolarCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
-
-
- [Serializable]
- public abstract class EastAsianLunisolarCalendar : Calendar {
- internal const int LeapMonth = 0;
- internal const int Jan1Month = 1;
- internal const int Jan1Date = 2;
- internal const int nDaysPerMonth = 3;
-
- // # of days so far in the solar year
- internal static readonly int[] DaysToMonth365 =
- {
- 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
- };
-
- internal static readonly int[] DaysToMonth366 =
- {
- 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335
- };
-
- internal const int DatePartYear = 0;
- internal const int DatePartDayOfYear = 1;
- internal const int DatePartMonth = 2;
- internal const int DatePartDay = 3;
-
- // Return the type of the East Asian Lunisolar calendars.
- //
-
- public override CalendarAlgorithmType AlgorithmType {
- get {
- return CalendarAlgorithmType.LunisolarCalendar;
- }
- }
-
- // Return the year number in the 60-year cycle.
- //
-
- public virtual int GetSexagenaryYear (DateTime time) {
- CheckTicksRange(time.Ticks);
-
- int year = 0, month = 0, day = 0;
- TimeToLunar(time, ref year, ref month, ref day);
-
- return ((year - 4) % 60) + 1;
- }
-
- // Return the celestial year from the 60-year cycle.
- // The returned value is from 1 ~ 10.
- //
-
- public int GetCelestialStem(int sexagenaryYear) {
- if ((sexagenaryYear < 1) || (sexagenaryYear > 60)) {
- throw new ArgumentOutOfRangeException(
- nameof(sexagenaryYear),
- Environment.GetResourceString("ArgumentOutOfRange_Range", 1, 60));
- }
- Contract.EndContractBlock();
-
- return ((sexagenaryYear - 1) % 10) + 1;
- }
-
- // Return the Terrestial Branch from the the 60-year cycle.
- // The returned value is from 1 ~ 12.
- //
-
- public int GetTerrestrialBranch(int sexagenaryYear) {
- if ((sexagenaryYear < 1) || (sexagenaryYear > 60)) {
- throw new ArgumentOutOfRangeException(
- nameof(sexagenaryYear),
- Environment.GetResourceString("ArgumentOutOfRange_Range", 1, 60));
- }
- Contract.EndContractBlock();
-
- return ((sexagenaryYear - 1) % 12) + 1;
- }
-
- internal abstract int GetYearInfo(int LunarYear, int Index);
- internal abstract int GetYear(int year, DateTime time);
- internal abstract int GetGregorianYear(int year, int era);
-
- internal abstract int MinCalendarYear {get;}
- internal abstract int MaxCalendarYear {get;}
- internal abstract EraInfo[] CalEraInfo{get;}
- internal abstract DateTime MinDate {get;}
- internal abstract DateTime MaxDate {get;}
-
- internal const int MaxCalendarMonth = 13;
- internal const int MaxCalendarDay = 30;
-
- internal int MinEraCalendarYear (int era) {
- EraInfo[] mEraInfo = CalEraInfo;
- //ChineseLunisolarCalendar does not has m_EraInfo it is going to retuen null
- if (mEraInfo == null) {
- return MinCalendarYear;
- }
-
- if (era == Calendar.CurrentEra) {
- era = CurrentEraValue;
- }
- //era has to be in the supported range otherwise we will throw exception in CheckEraRange()
- if (era == GetEra(MinDate)) {
- return (GetYear(MinCalendarYear, MinDate));
- }
-
- for (int i = 0; i < mEraInfo.Length; i++) {
- if (era == mEraInfo[i].era) {
- return (mEraInfo[i].minEraYear);
- }
- }
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
- }
-
- internal int MaxEraCalendarYear (int era) {
- EraInfo[] mEraInfo = CalEraInfo;
- //ChineseLunisolarCalendar does not has m_EraInfo it is going to retuen null
- if (mEraInfo == null) {
- return MaxCalendarYear;
- }
-
- if (era == Calendar.CurrentEra) {
- era = CurrentEraValue;
- }
- //era has to be in the supported range otherwise we will throw exception in CheckEraRange()
- if (era == GetEra(MaxDate)) {
- return (GetYear(MaxCalendarYear, MaxDate));
- }
-
- for (int i = 0; i < mEraInfo.Length; i++) {
- if (era == mEraInfo[i].era) {
- return (mEraInfo[i].maxEraYear);
- }
- }
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
- }
-
- // Construct an instance of EastAsianLunisolar calendar.
-
- internal EastAsianLunisolarCalendar() {
- }
-
- internal void CheckTicksRange(long ticks) {
- if (ticks < MinSupportedDateTime.Ticks || ticks > MaxSupportedDateTime.Ticks) {
- throw new ArgumentOutOfRangeException(
- "time",
- String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("ArgumentOutOfRange_CalendarRange"),
- MinSupportedDateTime, MaxSupportedDateTime));
- }
- Contract.EndContractBlock();
- }
-
- internal void CheckEraRange (int era) {
- if (era == Calendar.CurrentEra) {
- era = CurrentEraValue;
- }
-
- if ((era <GetEra(MinDate)) || (era > GetEra(MaxDate))) {
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
- }
- }
-
- internal int CheckYearRange(int year, int era) {
- CheckEraRange(era);
- year = GetGregorianYear(year, era);
-
- if ((year < MinCalendarYear) || (year > MaxCalendarYear)) {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_Range", MinEraCalendarYear(era), MaxEraCalendarYear(era)));
- }
- return year;
- }
-
- internal int CheckYearMonthRange(int year, int month, int era) {
- year = CheckYearRange(year, era);
-
- if (month == 13)
- {
- //Reject if there is no leap month this year
- if (GetYearInfo(year , LeapMonth) == 0)
- throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
- }
-
- if (month < 1 || month > 13) {
- throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
- }
- return year;
- }
-
- internal int InternalGetDaysInMonth(int year, int month) {
- int nDays;
- int mask; // mask for extracting bits
-
- mask = 0x8000;
- // convert the lunar day into a lunar month/date
- mask >>= (month-1);
- if ((GetYearInfo(year, nDaysPerMonth) & mask)== 0)
- nDays = 29;
- else
- nDays = 30;
- return nDays;
- }
-
- // Returns the number of days in the month given by the year and
- // month arguments.
- //
-
- public override int GetDaysInMonth(int year, int month, int era) {
- year = CheckYearMonthRange(year, month, era);
- return InternalGetDaysInMonth(year, month);
- }
-
- static int GregorianIsLeapYear(int y) {
- return ((((y)%4)!=0)?0:((((y)%100)!=0)?1:((((y)%400)!=0)?0:1)));
- }
-
- // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
- //
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) {
- year = CheckYearMonthRange(year, month, era);
- int daysInMonth = InternalGetDaysInMonth(year, month);
- if (day < 1 || day > daysInMonth) {
- BCLDebug.Log("year = " + year + ", month = " + month + ", day = " + day);
- throw new ArgumentOutOfRangeException(
- nameof(day),
- Environment.GetResourceString("ArgumentOutOfRange_Day", daysInMonth, month));
- }
-
- int gy=0; int gm=0; int gd=0;
-
- if (LunarToGregorian(year, month, day, ref gy, ref gm, ref gd)) {
- return new DateTime(gy, gm, gd, hour, minute, second, millisecond);
- } else {
- throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
- }
- }
-
-
- //
- // GregorianToLunar calculates lunar calendar info for the given gregorian year, month, date.
- // The input date should be validated before calling this method.
- //
- internal void GregorianToLunar(int nSYear, int nSMonth, int nSDate, ref int nLYear, ref int nLMonth, ref int nLDate) {
- // unsigned int nLYear, nLMonth, nLDate; // lunar ymd
- int nSolarDay; // day # in solar year
- int nLunarDay; // day # in lunar year
- int fLeap; // is it a solar leap year?
- int LDpM; // lunar days/month bitfield
- int mask; // mask for extracting bits
- int nDays; // # days this lunar month
- int nJan1Month, nJan1Date;
-
- // calc the solar day of year
- fLeap = GregorianIsLeapYear(nSYear);
- nSolarDay = (fLeap==1) ? DaysToMonth366[nSMonth-1]: DaysToMonth365[nSMonth-1] ;
- nSolarDay += nSDate;
-
- // init lunar year info
- nLunarDay = nSolarDay;
- nLYear = nSYear;
- if (nLYear == (MaxCalendarYear + 1)) {
- nLYear--;
- nLunarDay += ((GregorianIsLeapYear(nLYear) == 1) ? 366 : 365);
- nJan1Month = GetYearInfo(nLYear, Jan1Month);
- nJan1Date = GetYearInfo(nLYear,Jan1Date);
- } else {
-
- nJan1Month = GetYearInfo(nLYear, Jan1Month);
- nJan1Date = GetYearInfo(nLYear,Jan1Date);
-
- // check if this solar date is actually part of the previous
- // lunar year
- if ((nSMonth < nJan1Month) ||
- (nSMonth == nJan1Month && nSDate < nJan1Date)) {
- // the corresponding lunar day is actually part of the previous
- // lunar year
- nLYear--;
-
- // add a solar year to the lunar day #
- nLunarDay += ((GregorianIsLeapYear(nLYear) == 1) ? 366 : 365);
-
- // update the new start of year
- nJan1Month = GetYearInfo(nLYear, Jan1Month);
- nJan1Date = GetYearInfo(nLYear, Jan1Date);
- }
- }
-
- // convert solar day into lunar day.
- // subtract off the beginning part of the solar year which is not
- // part of the lunar year. since this part is always in Jan or Feb,
- // we don't need to handle Leap Year (LY only affects March
- // and later).
- nLunarDay -= DaysToMonth365[nJan1Month-1];
- nLunarDay -= (nJan1Date - 1);
-
- // convert the lunar day into a lunar month/date
- mask = 0x8000;
- LDpM = GetYearInfo(nLYear, nDaysPerMonth);
- nDays = ((LDpM & mask) != 0) ? 30 : 29;
- nLMonth = 1;
- while (nLunarDay > nDays) {
- nLunarDay -= nDays;
- nLMonth++;
- mask >>= 1;
- nDays = ((LDpM & mask) != 0) ? 30 : 29;
- }
- nLDate = nLunarDay;
- }
-
- /*
- //Convert from Lunar to Gregorian
- //Highly inefficient, but it works based on the forward conversion
- */
- internal bool LunarToGregorian(int nLYear, int nLMonth, int nLDate, ref int nSolarYear, ref int nSolarMonth, ref int nSolarDay) {
- int numLunarDays;
-
- if (nLDate < 1 || nLDate > 30)
- return false;
-
- numLunarDays = nLDate-1;
-
- //Add previous months days to form the total num of days from the first of the month.
- for (int i = 1; i < nLMonth; i++) {
- numLunarDays += InternalGetDaysInMonth(nLYear, i);
- }
-
- //Get Gregorian First of year
- int nJan1Month = GetYearInfo(nLYear, Jan1Month);
- int nJan1Date = GetYearInfo(nLYear, Jan1Date);
-
- // calc the solar day of year of 1 Lunar day
- int fLeap = GregorianIsLeapYear(nLYear);
- int[] days = (fLeap==1)? DaysToMonth366: DaysToMonth365;
-
- nSolarDay = nJan1Date;
-
- if (nJan1Month > 1)
- nSolarDay += days [nJan1Month-1];
-
- // Add the actual lunar day to get the solar day we want
- nSolarDay = nSolarDay + numLunarDays;// - 1;
-
- if ( nSolarDay > (fLeap + 365)) {
- nSolarYear = nLYear + 1;
- nSolarDay -= (fLeap + 365);
- } else {
- nSolarYear = nLYear;
- }
-
- for (nSolarMonth = 1; nSolarMonth < 12; nSolarMonth++) {
- if (days[nSolarMonth] >= nSolarDay)
- break;
- }
-
- nSolarDay -= days[nSolarMonth-1];
- return true;
- }
-
- internal DateTime LunarToTime(DateTime time, int year, int month, int day) {
- int gy=0; int gm=0; int gd=0;
- LunarToGregorian(year, month, day, ref gy, ref gm, ref gd);
- return (GregorianCalendar.GetDefaultInstance().ToDateTime(gy,gm,gd,time.Hour,time.Minute,time.Second,time.Millisecond));
- }
-
- internal void TimeToLunar(DateTime time, ref int year, ref int month, ref int day) {
- int gy=0; int gm=0; int gd=0;
-
- Calendar Greg = GregorianCalendar.GetDefaultInstance();
- gy = Greg.GetYear(time);
- gm = Greg.GetMonth(time);
- gd = Greg.GetDayOfMonth(time);
-
- GregorianToLunar(gy, gm, gd, ref year, ref month, ref day);
- }
-
- // Returns the DateTime resulting from adding the given number of
- // months to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year and month parts of the specified DateTime by
- // value months, and, if required, adjusting the day part of the
- // resulting date downwards to the last day of the resulting month in the
- // resulting year. The time-of-day part of the result is the same as the
- // time-of-day part of the specified DateTime.
- //
-
- public override DateTime AddMonths(DateTime time, int months) {
- if (months < -120000 || months > 120000) {
- throw new ArgumentOutOfRangeException(
- nameof(months),
- Environment.GetResourceString("ArgumentOutOfRange_Range", -120000, 120000));
- }
- Contract.EndContractBlock();
-
- CheckTicksRange(time.Ticks);
-
- int y=0; int m=0; int d=0;
- TimeToLunar(time, ref y, ref m, ref d);
-
- int i = m + months;
- if (i > 0) {
- int monthsInYear = InternalIsLeapYear(y)?13:12;
-
- while (i-monthsInYear > 0) {
- i -= monthsInYear;
- y++;
- monthsInYear = InternalIsLeapYear(y)?13:12;
- }
- m = i;
- } else {
- int monthsInYear;
- while (i <= 0) {
- monthsInYear = InternalIsLeapYear(y-1)?13:12;
- i += monthsInYear;
- y--;
- }
- m = i;
- }
-
- int days = InternalGetDaysInMonth(y, m);
- if (d > days) {
- d = days;
- }
- DateTime dt = LunarToTime(time, y, m, d);
-
- CheckAddResult(dt.Ticks, MinSupportedDateTime, MaxSupportedDateTime);
- return (dt);
- }
-
-
- public override DateTime AddYears(DateTime time, int years) {
- CheckTicksRange(time.Ticks);
-
- int y=0; int m=0; int d=0;
- TimeToLunar(time, ref y, ref m, ref d);
-
- y += years;
-
- if (m==13 && !InternalIsLeapYear(y)) {
- m = 12;
- d = InternalGetDaysInMonth(y, m);
- }
- int DaysInMonths = InternalGetDaysInMonth(y, m);
- if (d > DaysInMonths) {
- d = DaysInMonths;
- }
-
- DateTime dt = LunarToTime(time, y, m, d);
- CheckAddResult(dt.Ticks, MinSupportedDateTime, MaxSupportedDateTime);
- return (dt);
- }
-
- // Returns the day-of-year part of the specified DateTime. The returned value
- // is an integer between 1 and [354|355 |383|384].
- //
-
- public override int GetDayOfYear(DateTime time) {
- CheckTicksRange(time.Ticks);
-
- int y=0; int m=0; int d=0;
- TimeToLunar(time, ref y, ref m, ref d);
-
- for (int i=1; i<m ;i++)
- {
- d = d + InternalGetDaysInMonth(y, i);
- }
- return d;
- }
-
- // Returns the day-of-month part of the specified DateTime. The returned
- // value is an integer between 1 and 29 or 30.
- //
-
- public override int GetDayOfMonth(DateTime time) {
- CheckTicksRange(time.Ticks);
-
- int y=0; int m=0; int d=0;
- TimeToLunar(time, ref y, ref m, ref d);
-
- return d;
- }
-
- // Returns the number of days in the year given by the year argument for the current era.
- //
-
- public override int GetDaysInYear(int year, int era) {
- year = CheckYearRange(year, era);
-
- int Days = 0;
- int monthsInYear = InternalIsLeapYear(year) ? 13 : 12;
-
- while (monthsInYear != 0)
- Days += InternalGetDaysInMonth(year, monthsInYear--);
-
- return Days;
- }
-
- // Returns the month part of the specified DateTime. The returned value is an
- // integer between 1 and 13.
- //
-
- public override int GetMonth(DateTime time) {
- CheckTicksRange(time.Ticks);
-
- int y=0; int m=0; int d=0;
- TimeToLunar(time, ref y, ref m, ref d);
-
- return m;
- }
-
- // Returns the year part of the specified DateTime. The returned value is an
- // integer between 1 and MaxCalendarYear.
- //
-
- public override int GetYear(DateTime time) {
- CheckTicksRange(time.Ticks);
-
- int y=0; int m=0; int d=0;
- TimeToLunar(time, ref y, ref m, ref d);
-
- return GetYear(y, time);
- }
-
- // Returns the day-of-week part of the specified DateTime. The returned value
- // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
- // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
- // Thursday, 5 indicates Friday, and 6 indicates Saturday.
- //
-
- public override DayOfWeek GetDayOfWeek(DateTime time) {
- CheckTicksRange(time.Ticks);
- return ((DayOfWeek)((int)(time.Ticks / Calendar.TicksPerDay + 1) % 7));
- }
-
- // Returns the number of months in the specified year and era.
-
- public override int GetMonthsInYear(int year, int era) {
- year = CheckYearRange(year, era);
- return (InternalIsLeapYear(year)?13:12);
- }
-
- // Checks whether a given day in the specified era is a leap day. This method returns true if
- // the date is a leap day, or false if not.
- //
-
- public override bool IsLeapDay(int year, int month, int day, int era) {
- year = CheckYearMonthRange(year, month, era);
- int daysInMonth = InternalGetDaysInMonth(year, month);
-
- if (day < 1 || day > daysInMonth) {
- throw new ArgumentOutOfRangeException(
- nameof(day),
- Environment.GetResourceString("ArgumentOutOfRange_Day", daysInMonth, month));
- }
- int m = GetYearInfo(year, LeapMonth);
- return ((m!=0) && (month == (m+1)));
- }
-
- // Checks whether a given month in the specified era is a leap month. This method returns true if
- // month is a leap month, or false if not.
- //
-
- public override bool IsLeapMonth(int year, int month, int era) {
- year = CheckYearMonthRange(year, month, era);
- int m = GetYearInfo(year, LeapMonth);
- return ((m!=0) && (month == (m+1)));
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this this year is not a leap year.
- //
-
- public override int GetLeapMonth(int year, int era) {
- year = CheckYearRange(year, era);
- int month = GetYearInfo(year, LeapMonth);
- if (month>0)
- {
- return (month+1);
- }
- return 0;
- }
-
- internal bool InternalIsLeapYear(int year) {
- return (GetYearInfo(year, LeapMonth)!=0);
- }
- // Checks whether a given year in the specified era is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
-
- public override bool IsLeapYear(int year, int era) {
- year = CheckYearRange(year, era);
- return InternalIsLeapYear(year);
- }
-
- private const int DEFAULT_GREGORIAN_TWO_DIGIT_YEAR_MAX = 2029;
-
-
- public override int TwoDigitYearMax {
- get {
- if (twoDigitYearMax == -1) {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(BaseCalendarID, GetYear(new DateTime(DEFAULT_GREGORIAN_TWO_DIGIT_YEAR_MAX, 1, 1)));
- }
- return (twoDigitYearMax);
- }
-
- set {
- VerifyWritable();
- if (value < 99 || value > MaxCalendarYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(value),
- Environment.GetResourceString("ArgumentOutOfRange_Range", 99, MaxCalendarYear));
- }
- twoDigitYearMax = value;
- }
- }
-
-
- public override int ToFourDigitYear(int year) {
- if (year < 0) {
- throw new ArgumentOutOfRangeException(nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- Contract.EndContractBlock();
-
- year = base.ToFourDigitYear(year);
- CheckYearRange(year, CurrentEra);
- return (year);
- }
-
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/EncodingDataItem.Unix.cs b/src/mscorlib/src/System/Globalization/EncodingDataItem.Unix.cs
index 408f6e681e..ffb2d46a9e 100644
--- a/src/mscorlib/src/System/Globalization/EncodingDataItem.Unix.cs
+++ b/src/mscorlib/src/System/Globalization/EncodingDataItem.Unix.cs
@@ -59,7 +59,7 @@ namespace System.Globalization
{
if (_displayNameResourceKey == null)
{
- _displayNameResourceKey = "Globalization.cp_" + CodePage;
+ _displayNameResourceKey = "Globalization_cp_" + CodePage;
}
return _displayNameResourceKey;
diff --git a/src/mscorlib/src/System/Globalization/EncodingDataItem.cs b/src/mscorlib/src/System/Globalization/EncodingDataItem.cs
index 89ac780587..b049eaf45d 100644
--- a/src/mscorlib/src/System/Globalization/EncodingDataItem.cs
+++ b/src/mscorlib/src/System/Globalization/EncodingDataItem.cs
@@ -2,12 +2,13 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Globalization {
- using System.Text;
- using System.Runtime.Remoting;
- using System;
- using System.Security;
+using System.Text;
+using System.Runtime.Remoting;
+using System;
+using System.Security;
+namespace System.Globalization
+{
//
// Data item for EncodingTable. Along with EncodingTable, they are used by
// System.Text.Encoding.
@@ -16,18 +17,19 @@ namespace System.Globalization {
// where our required information is found. We load the code page, flags and uiFamilyCodePage
// immediately because they don't require creating an object. Creating any of the string
// names is delayed until somebody actually asks for them and the names are then cached.
-
+
[Serializable]
internal class CodePageDataItem
{
- internal int m_dataIndex;
- internal int m_uiFamilyCodePage;
+ internal int m_dataIndex;
+ internal int m_uiFamilyCodePage;
internal String m_webName;
internal String m_headerName;
internal String m_bodyName;
- internal uint m_flags;
-
- unsafe internal CodePageDataItem(int dataIndex) {
+ internal uint m_flags;
+
+ unsafe internal CodePageDataItem(int dataIndex)
+ {
m_dataIndex = dataIndex;
m_uiFamilyCodePage = EncodingTable.codePageDataPtr[dataIndex].uiFamilyCodePage;
m_flags = EncodingTable.codePageDataPtr[dataIndex].flags;
@@ -38,8 +40,8 @@ namespace System.Globalization {
if (pStrings[0] == '|') // |str1|str2|str3
{
int start = 1;
-
- for (int i = 1; true; i ++)
+
+ for (int i = 1; true; i++)
{
sbyte ch = pStrings[i];
@@ -50,7 +52,7 @@ namespace System.Globalization {
return new String(pStrings, start, i - start);
}
- index --;
+ index--;
start = i + 1;
if (ch == 0)
@@ -68,41 +70,54 @@ namespace System.Globalization {
}
}
- unsafe public String WebName {
- get {
- if (m_webName==null) {
+ unsafe public String WebName
+ {
+ get
+ {
+ if (m_webName == null)
+ {
m_webName = CreateString(EncodingTable.codePageDataPtr[m_dataIndex].Names, 0);
}
return m_webName;
}
}
-
- public virtual int UIFamilyCodePage {
- get {
+
+ public virtual int UIFamilyCodePage
+ {
+ get
+ {
return m_uiFamilyCodePage;
}
}
-
- unsafe public String HeaderName {
- get {
- if (m_headerName==null) {
+
+ unsafe public String HeaderName
+ {
+ get
+ {
+ if (m_headerName == null)
+ {
m_headerName = CreateString(EncodingTable.codePageDataPtr[m_dataIndex].Names, 1);
}
return m_headerName;
}
}
-
- unsafe public String BodyName {
- get {
- if (m_bodyName==null) {
+
+ unsafe public String BodyName
+ {
+ get
+ {
+ if (m_bodyName == null)
+ {
m_bodyName = CreateString(EncodingTable.codePageDataPtr[m_dataIndex].Names, 2);
}
return m_bodyName;
}
- }
+ }
- unsafe public uint Flags {
- get {
+ unsafe public uint Flags
+ {
+ get
+ {
return (m_flags);
}
}
diff --git a/src/mscorlib/src/System/Globalization/EncodingTable.Unix.cs b/src/mscorlib/src/System/Globalization/EncodingTable.Unix.cs
index 0fce2e58fc..dc61c9f0d9 100644
--- a/src/mscorlib/src/System/Globalization/EncodingTable.Unix.cs
+++ b/src/mscorlib/src/System/Globalization/EncodingTable.Unix.cs
@@ -21,7 +21,7 @@ namespace System.Globalization
CodePageDataItem dataItem = s_encodingDataTableItems[i];
arrayEncodingInfo[i] = new EncodingInfo(dataItem.CodePage, dataItem.WebName,
- Environment.GetResourceString(dataItem.DisplayNameResourceKey));
+ SR.GetResourceString(dataItem.DisplayNameResourceKey));
}
return arrayEncodingInfo;
@@ -45,7 +45,7 @@ namespace System.Globalization
throw new ArgumentException(
string.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("Argument_EncodingNotSupported"), name), nameof(name));
+ SR.Argument_EncodingNotSupported, name), nameof(name));
}
internal static CodePageDataItem GetCodePageDataItem(int codepage)
diff --git a/src/mscorlib/src/System/Globalization/EncodingTable.cs b/src/mscorlib/src/System/Globalization/EncodingTable.cs
index b7c268a956..6d9cc3127f 100644
--- a/src/mscorlib/src/System/Globalization/EncodingTable.cs
+++ b/src/mscorlib/src/System/Globalization/EncodingTable.cs
@@ -2,44 +2,44 @@
// 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.Text;
+using System.Collections;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+using System.Security;
+using System.Threading;
+using System.Diagnostics.Contracts;
+
namespace System.Globalization
{
- using System;
- using System.Text;
- using System.Collections;
- using System.Collections.Generic;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
- using System.Security;
- using System.Threading;
- using System.Diagnostics.Contracts;
//
// Data table for encoding classes. Used by System.Text.Encoding.
// This class contains two hashtables to allow System.Text.Encoding
// to retrieve the data item either by codepage value or by webName.
//
-
+
// Only statics, does not need to be marked with the serializable attribute
internal static class EncodingTable
{
-
//This number is the size of the table in native. The value is retrieved by
//calling the native GetNumEncodingItems().
private static int lastEncodingItem = GetNumEncodingItems() - 1;
//This number is the size of the code page table. Its generated when we walk the table the first time.
private static volatile int lastCodePageItem;
-
+
//
// This points to a native data table which maps an encoding name to the correct code page.
//
- unsafe internal static InternalEncodingDataItem *encodingDataPtr = GetEncodingData();
+ unsafe internal static InternalEncodingDataItem* encodingDataPtr = GetEncodingData();
//
// This points to a native data table which stores the properties for the code page, and
// the table is indexed by code page.
//
- unsafe internal static InternalCodePageDataItem *codePageDataPtr = GetCodePageData();
+ unsafe internal static InternalCodePageDataItem* codePageDataPtr = GetCodePageData();
//
// This caches the mapping of an encoding name to a code page.
//
@@ -49,40 +49,45 @@ namespace System.Globalization
//
private static Hashtable hashByCodePage = Hashtable.Synchronized(new Hashtable());
- static EncodingTable()
- {
- }
-
// Find the data item by binary searching the table that we have in native.
// nativeCompareOrdinalWC is an internal-only function.
- unsafe private static int internalGetCodePageFromName(String name) {
- int left = 0;
+ unsafe private static int internalGetCodePageFromName(String name)
+ {
+ int left = 0;
int right = lastEncodingItem;
int index;
int result;
-
+
//Binary search the array until we have only a couple of elements left and then
//just walk those elements.
- while ((right - left)>3) {
- index = ((right - left)/2) + left;
-
+ while ((right - left) > 3)
+ {
+ index = ((right - left) / 2) + left;
+
result = String.nativeCompareOrdinalIgnoreCaseWC(name, encodingDataPtr[index].webName);
-
- if (result == 0) {
+
+ if (result == 0)
+ {
//We found the item, return the associated codepage.
return (encodingDataPtr[index].codePage);
- } else if (result<0) {
+ }
+ else if (result < 0)
+ {
//The name that we're looking for is less than our current index.
right = index;
- } else {
+ }
+ else
+ {
//The name that we're looking for is greater than our current index
left = index;
}
}
-
+
//Walk the remaining elements (it'll be 3 or fewer).
- for (; left<=right; left++) {
- if (String.nativeCompareOrdinalIgnoreCaseWC(name, encodingDataPtr[left].webName) == 0) {
+ for (; left <= right; left++)
+ {
+ if (String.nativeCompareOrdinalIgnoreCaseWC(name, encodingDataPtr[left].webName) == 0)
+ {
return (encodingDataPtr[left].codePage);
}
}
@@ -90,7 +95,7 @@ namespace System.Globalization
throw new ArgumentException(
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("Argument_EncodingNotSupported"), name), nameof(name));
+ SR.Argument_EncodingNotSupported, name), nameof(name));
}
// Return a list of all EncodingInfo objects describing all of our encodings
@@ -112,12 +117,12 @@ namespace System.Globalization
for (i = 0; i < lastCodePageItem; i++)
{
arrayEncodingInfo[i] = new EncodingInfo(codePageDataPtr[i].codePage, CodePageDataItem.CreateString(codePageDataPtr[i].Names, 0),
- Environment.GetResourceString("Globalization.cp_" + codePageDataPtr[i].codePage));
+ SR.GetResourceString("Globalization_cp_" + codePageDataPtr[i].codePage));
}
-
+
return arrayEncodingInfo;
- }
-
+ }
+
/*=================================GetCodePageFromName==========================
**Action: Given a encoding name, return the correct code page number for this encoding.
**Returns: The code page for the encoding.
@@ -127,10 +132,11 @@ namespace System.Globalization
** ArgumentNullException if name is null.
** internalGetCodePageFromName will throw ArgumentException if name is not a valid encoding name.
============================================================================*/
-
+
internal static int GetCodePageFromName(String name)
- {
- if (name==null) {
+ {
+ if (name == null)
+ {
throw new ArgumentNullException(nameof(name));
}
Contract.EndContractBlock();
@@ -143,7 +149,8 @@ namespace System.Globalization
//
codePageObj = hashByName[name];
- if (codePageObj!=null) {
+ if (codePageObj != null)
+ {
return ((int)codePageObj);
}
@@ -155,8 +162,9 @@ namespace System.Globalization
return codePage;
}
-
- unsafe internal static CodePageDataItem GetCodePageDataItem(int codepage) {
+
+ unsafe internal static CodePageDataItem GetCodePageDataItem(int codepage)
+ {
CodePageDataItem dataItem;
// We synchronize around dictionary gets/sets. There's still a possibility that two threads
@@ -166,9 +174,10 @@ namespace System.Globalization
//Look up the item in the hashtable.
dataItem = (CodePageDataItem)hashByCodePage[codepage];
-
+
//If we found it, return it.
- if (dataItem!=null) {
+ if (dataItem != null)
+ {
return dataItem;
}
@@ -179,22 +188,24 @@ namespace System.Globalization
//
int i = 0;
int data;
- while ((data = codePageDataPtr[i].codePage) != 0) {
- if (data == codepage) {
+ while ((data = codePageDataPtr[i].codePage) != 0)
+ {
+ if (data == codepage)
+ {
dataItem = new CodePageDataItem(i);
hashByCodePage[codepage] = dataItem;
return (dataItem);
}
i++;
}
-
+
//Nope, we didn't find it.
return null;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private unsafe static extern InternalEncodingDataItem *GetEncodingData();
-
+ private unsafe static extern InternalEncodingDataItem* GetEncodingData();
+
//
// Return the number of encoding data items.
//
@@ -204,18 +215,19 @@ namespace System.Globalization
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private unsafe static extern InternalCodePageDataItem* GetCodePageData();
}
-
+
/*=================================InternalEncodingDataItem==========================
**Action: This is used to map a encoding name to a correct code page number. By doing this,
** we can get the properties of this encoding via the InternalCodePageDataItem.
**
** We use this structure to access native data exposed by the native side.
============================================================================*/
-
+
[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
- internal unsafe struct InternalEncodingDataItem {
- internal sbyte * webName;
- internal UInt16 codePage;
+ internal unsafe struct InternalEncodingDataItem
+ {
+ internal sbyte* webName;
+ internal UInt16 codePage;
}
/*=================================InternalCodePageDataItem==========================
@@ -224,11 +236,11 @@ namespace System.Globalization
============================================================================*/
[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
- internal unsafe struct InternalCodePageDataItem {
- internal UInt16 codePage;
- internal UInt16 uiFamilyCodePage;
- internal uint flags;
- internal sbyte * Names;
+ internal unsafe struct InternalCodePageDataItem
+ {
+ internal UInt16 codePage;
+ internal UInt16 uiFamilyCodePage;
+ internal uint flags;
+ internal sbyte* Names;
}
-
}
diff --git a/src/mscorlib/src/System/Globalization/GlobalizationAssembly.cs b/src/mscorlib/src/System/Globalization/GlobalizationAssembly.cs
index e203223eb0..956543524a 100644
--- a/src/mscorlib/src/System/Globalization/GlobalizationAssembly.cs
+++ b/src/mscorlib/src/System/Globalization/GlobalizationAssembly.cs
@@ -3,21 +3,21 @@
// See the LICENSE file in the project root for more information.
-namespace System.Globalization {
- using System;
- using System.Reflection;
- using System.Collections;
- using System.Collections.Generic;
- using System.Threading;
- using System.Security;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.Versioning;
- using System.IO;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
+using System;
+using System.Reflection;
+using System.Collections;
+using System.Collections.Generic;
+using System.Threading;
+using System.Security;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.Versioning;
+using System.IO;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
-
+namespace System.Globalization
+{
/*=================================GlobalizationAssembly==========================
**
** This class provides the table loading wrapper that calls GetManifestResourceStream
@@ -32,31 +32,33 @@ namespace System.Globalization {
// Instance data members and instance methods.
//
// ----------------------------------------------------------------------------------------------------
- internal unsafe static byte* GetGlobalizationResourceBytePtr(Assembly assembly, String tableName) {
- Debug.Assert(assembly != null, "assembly can not be null. This should be generally the "+System.CoreLib.Name+" assembly.");
+ internal unsafe static byte* GetGlobalizationResourceBytePtr(Assembly assembly, String tableName)
+ {
+ Debug.Assert(assembly != null, "assembly can not be null. This should be generally the " + System.CoreLib.Name + " assembly.");
Debug.Assert(tableName != null, "table name can not be null");
-
+
Stream stream = assembly.GetManifestResourceStream(tableName);
UnmanagedMemoryStream bytesStream = stream as UnmanagedMemoryStream;
- if (bytesStream != null) {
+ if (bytesStream != null)
+ {
byte* bytes = bytesStream.PositionPointer;
- if (bytes != null) {
+ if (bytes != null)
+ {
return (bytes);
}
}
-
+
Debug.Assert(
- false,
+ false,
String.Format(
CultureInfo.CurrentCulture,
- "Didn't get the resource table {0} for System.Globalization from {1}",
- tableName,
+ "Didn't get the resource table {0} for System.Globalization from {1}",
+ tableName,
assembly));
-
+
// We can not continue if we can't get the resource.
throw new InvalidOperationException();
}
-
}
}
diff --git a/src/mscorlib/src/System/Globalization/GlobalizationMode.Unix.cs b/src/mscorlib/src/System/Globalization/GlobalizationMode.Unix.cs
new file mode 100644
index 0000000000..6896029047
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/GlobalizationMode.Unix.cs
@@ -0,0 +1,24 @@
+// 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.
+
+namespace System.Globalization
+{
+ internal sealed partial class GlobalizationMode
+ {
+ private static bool GetGlobalizationInvariantMode()
+ {
+ bool invariantEnabled = CLRConfig.GetBoolValue(c_InvariantModeConfigSwitch);
+ if (!invariantEnabled)
+ {
+ if (Interop.GlobalizationInterop.LoadICU() == 0)
+ {
+ string message = "Couldn't find a valid ICU package installed on the system. " +
+ "Set the configuration flag System.Globalization.Invariant to true if you want to run with no globalization support.";
+ Environment.FailFast(message);
+ }
+ }
+ return invariantEnabled;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/GlobalizationMode.Windows.cs b/src/mscorlib/src/System/Globalization/GlobalizationMode.Windows.cs
new file mode 100644
index 0000000000..1be79f3507
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/GlobalizationMode.Windows.cs
@@ -0,0 +1,14 @@
+// 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.
+
+namespace System.Globalization
+{
+ internal sealed partial class GlobalizationMode
+ {
+ private static bool GetGlobalizationInvariantMode()
+ {
+ return CLRConfig.GetBoolValue(c_InvariantModeConfigSwitch);
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/GlobalizationMode.cs b/src/mscorlib/src/System/Globalization/GlobalizationMode.cs
new file mode 100644
index 0000000000..8f8309886d
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/GlobalizationMode.cs
@@ -0,0 +1,12 @@
+// 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.
+
+namespace System.Globalization
+{
+ internal sealed partial class GlobalizationMode
+ {
+ private const string c_InvariantModeConfigSwitch = "System.Globalization.Invariant";
+ internal static bool Invariant { get; } = GetGlobalizationInvariantMode();
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/GregorianCalendar.cs b/src/mscorlib/src/System/Globalization/GregorianCalendar.cs
index 9083e6de27..6dbf5b2786 100644
--- a/src/mscorlib/src/System/Globalization/GregorianCalendar.cs
+++ b/src/mscorlib/src/System/Globalization/GregorianCalendar.cs
@@ -2,27 +2,20 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Globalization {
- //
- // N.B.:
- // A lot of this code is directly from DateTime.cs. If you update that class,
- // update this one as well.
- // However, we still need these duplicated code because we will add era support
- // in this class.
- //
- //
-
- using System.Threading;
- using System;
- using System.Globalization;
- using System.Runtime.Serialization;
- using System.Diagnostics.Contracts;
-
+using System;
+using System.Globalization;
+using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+using System.Threading;
+
+namespace System.Globalization
+{
// This calendar recognizes two era values:
// 0 CurrentEra (AD)
// 1 BeforeCurrentEra (BC)
[Serializable]
+
public class GregorianCalendar : Calendar
{
/*
@@ -57,24 +50,16 @@ namespace System.Globalization {
private static volatile Calendar s_defaultInstance;
-
-#region Serialization
[OnDeserialized]
private void OnDeserialized(StreamingContext ctx)
{
- if (m_type < GregorianCalendarTypes.Localized ||
- m_type > GregorianCalendarTypes.TransliteratedFrench)
+ if (m_type < GregorianCalendarTypes.Localized ||
+ m_type > GregorianCalendarTypes.TransliteratedFrench)
{
throw new SerializationException(
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString(
- "Serialization_MemberOutOfRange"),
- "type",
- "GregorianCalendar"));
+ String.Format(CultureInfo.CurrentCulture, SR.Serialization_MemberOutOfRange, "type", "GregorianCalendar"));
}
}
-#endregion Serialization
public override DateTime MinSupportedDateTime
{
@@ -92,9 +77,6 @@ namespace System.Globalization {
}
}
- // Return the type of the Gregorian calendar.
- //
-
public override CalendarAlgorithmType AlgorithmType
{
get
@@ -111,8 +93,10 @@ namespace System.Globalization {
**Exceptions:
============================================================================*/
- internal static Calendar GetDefaultInstance() {
- if (s_defaultInstance == null) {
+ internal static Calendar GetDefaultInstance()
+ {
+ if (s_defaultInstance == null)
+ {
s_defaultInstance = new GregorianCalendar();
}
return (s_defaultInstance);
@@ -121,30 +105,37 @@ namespace System.Globalization {
// Construct an instance of gregorian calendar.
public GregorianCalendar() :
- this(GregorianCalendarTypes.Localized) {
+ this(GregorianCalendarTypes.Localized)
+ {
}
- public GregorianCalendar(GregorianCalendarTypes type) {
- if ((int)type < (int)GregorianCalendarTypes.Localized || (int)type > (int)GregorianCalendarTypes.TransliteratedFrench) {
+ public GregorianCalendar(GregorianCalendarTypes type)
+ {
+ if ((int)type < (int)GregorianCalendarTypes.Localized || (int)type > (int)GregorianCalendarTypes.TransliteratedFrench)
+ {
throw new ArgumentOutOfRangeException(
nameof(type),
- Environment.GetResourceString("ArgumentOutOfRange_Range",
+ SR.Format(SR.ArgumentOutOfRange_Range,
GregorianCalendarTypes.Localized, GregorianCalendarTypes.TransliteratedFrench));
}
Contract.EndContractBlock();
this.m_type = type;
}
- public virtual GregorianCalendarTypes CalendarType {
- get {
+ public virtual GregorianCalendarTypes CalendarType
+ {
+ get
+ {
return (m_type);
}
- set {
+ set
+ {
VerifyWritable();
- switch (value) {
+ switch (value)
+ {
case GregorianCalendarTypes.Localized:
case GregorianCalendarTypes.USEnglish:
case GregorianCalendarTypes.MiddleEastFrench:
@@ -155,18 +146,20 @@ namespace System.Globalization {
break;
default:
- throw new ArgumentOutOfRangeException(nameof(m_type), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException("m_type", SR.ArgumentOutOfRange_Enum);
}
}
}
- internal override int ID {
- get {
+ internal override CalendarId ID
+ {
+ get
+ {
// By returning different ID for different variations of GregorianCalendar,
// we can support the Transliterated Gregorian calendar.
// DateTimeFormatInfo will use this ID to get formatting information about
// the calendar.
- return ((int)m_type);
+ return ((CalendarId)m_type);
}
}
@@ -210,7 +203,7 @@ namespace System.Globalization {
// Leap year calculation looks different from IsLeapYear since y1, y4,
// and y100 are relative to year 1, not year 0
bool leapYear = (y1 == 3 && (y4 != 24 || y100 == 3));
- int[] days = leapYear? DaysToMonth366: DaysToMonth365;
+ int[] days = leapYear ? DaysToMonth366 : DaysToMonth365;
// All months have less than 32 days, so n >> 5 is a good conservative
// estimate for the month
int m = (n >> 5) + 1;
@@ -240,23 +233,26 @@ namespace System.Globalization {
**
============================================================================*/
- internal static long GetAbsoluteDate(int year, int month, int day) {
+ internal static long GetAbsoluteDate(int year, int month, int day)
+ {
if (year >= 1 && year <= MaxYear && month >= 1 && month <= 12)
{
- int[] days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))) ? DaysToMonth366: DaysToMonth365;
- if (day >= 1 && (day <= days[month] - days[month - 1])) {
+ int[] days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))) ? DaysToMonth366 : DaysToMonth365;
+ if (day >= 1 && (day <= days[month] - days[month - 1]))
+ {
int y = year - 1;
int absoluteDate = y * 365 + y / 4 - y / 100 + y / 400 + days[month - 1] + day - 1;
return (absoluteDate);
}
}
- throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
}
// Returns the tick count corresponding to the given year, month, and day.
// Will check the if the parameters are valid.
- internal virtual long DateToTicks(int year, int month, int day) {
- return (GetAbsoluteDate(year, month, day)* TicksPerDay);
+ internal virtual long DateToTicks(int year, int month, int day)
+ {
+ return (GetAbsoluteDate(year, month, day) * TicksPerDay);
}
// Returns the DateTime resulting from adding the given number of
@@ -279,12 +275,13 @@ namespace System.Globalization {
public override DateTime AddMonths(DateTime time, int months)
{
- if (months < -120000 || months > 120000) {
+ if (months < -120000 || months > 120000)
+ {
throw new ArgumentOutOfRangeException(
nameof(months),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
+ SR.ArgumentOutOfRange_Range,
-120000,
120000));
}
@@ -303,7 +300,7 @@ namespace System.Globalization {
m = 12 + (i + 1) % 12;
y = y + (i - 11) / 12;
}
- int[] daysArray = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? DaysToMonth366: DaysToMonth365;
+ int[] daysArray = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? DaysToMonth366 : DaysToMonth365;
int days = (daysArray[m] - daysArray[m - 1]);
if (d > days)
@@ -364,19 +361,23 @@ namespace System.Globalization {
// month arguments.
//
- public override int GetDaysInMonth(int year, int month, int era) {
- if (era == CurrentEra || era == ADEra) {
- if (year < 1 || year > MaxYear) {
- throw new ArgumentOutOfRangeException(nameof(year), Environment.GetResourceString("ArgumentOutOfRange_Range",
+ public override int GetDaysInMonth(int year, int month, int era)
+ {
+ if (era == CurrentEra || era == ADEra)
+ {
+ if (year < 1 || year > MaxYear)
+ {
+ throw new ArgumentOutOfRangeException(nameof(year), SR.Format(SR.ArgumentOutOfRange_Range,
1, MaxYear));
}
- if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
+ if (month < 1 || month > 12)
+ {
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
}
- int[] days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? DaysToMonth366: DaysToMonth365);
+ int[] days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? DaysToMonth366 : DaysToMonth365);
return (days[month] - days[month - 1]);
}
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
// Returns the number of days in the year given by the year argument for the current era.
@@ -384,19 +385,21 @@ namespace System.Globalization {
public override int GetDaysInYear(int year, int era)
{
- if (era == CurrentEra || era == ADEra) {
- if (year >= 1 && year <= MaxYear) {
- return ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? 366:365);
+ if (era == CurrentEra || era == ADEra)
+ {
+ if (year >= 1 && year <= MaxYear)
+ {
+ return ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? 366 : 365);
}
throw new ArgumentOutOfRangeException(
nameof(year),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
+ SR.ArgumentOutOfRange_Range,
1,
MaxYear));
}
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
// Returns the era for the specified DateTime value.
@@ -407,9 +410,11 @@ namespace System.Globalization {
}
- public override int[] Eras {
- get {
- return (new int[] {ADEra} );
+ public override int[] Eras
+ {
+ get
+ {
+ return (new int[] { ADEra });
}
}
@@ -427,7 +432,8 @@ namespace System.Globalization {
public override int GetMonthsInYear(int year, int era)
{
- if (era == CurrentEra || era == ADEra) {
+ if (era == CurrentEra || era == ADEra)
+ {
if (year >= 1 && year <= MaxYear)
{
return (12);
@@ -436,11 +442,11 @@ namespace System.Globalization {
nameof(year),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
+ SR.ArgumentOutOfRange_Range,
1,
MaxYear));
}
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
// Returns the year part of the specified DateTime. The returned value is an
@@ -458,30 +464,35 @@ namespace System.Globalization {
public override bool IsLeapDay(int year, int month, int day, int era)
{
- if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Range",
+ if (month < 1 || month > 12)
+ {
+ throw new ArgumentOutOfRangeException(nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
1, 12));
}
Contract.EndContractBlock();
if (era != CurrentEra && era != ADEra)
{
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
- if (year < 1 || year > MaxYear) {
+ if (year < 1 || year > MaxYear)
+ {
throw new ArgumentOutOfRangeException(
nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_Range", 1, MaxYear));
+ SR.Format(SR.ArgumentOutOfRange_Range, 1, MaxYear));
}
- if (day < 1 || day > GetDaysInMonth(year, month)) {
- throw new ArgumentOutOfRangeException(nameof(day), Environment.GetResourceString("ArgumentOutOfRange_Range",
+ if (day < 1 || day > GetDaysInMonth(year, month))
+ {
+ throw new ArgumentOutOfRangeException(nameof(day), SR.Format(SR.ArgumentOutOfRange_Range,
1, GetDaysInMonth(year, month)));
}
- if (!IsLeapYear(year)) {
+ if (!IsLeapYear(year))
+ {
return (false);
}
- if (month == 2 && day == 29) {
+ if (month == 2 && day == 29)
+ {
return (true);
}
return (false);
@@ -495,14 +506,15 @@ namespace System.Globalization {
{
if (era != CurrentEra && era != ADEra)
{
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
- if (year < 1 || year > MaxYear) {
+ if (year < 1 || year > MaxYear)
+ {
throw new ArgumentOutOfRangeException(
nameof(year),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"), 1, MaxYear));
+ SR.ArgumentOutOfRange_Range, 1, MaxYear));
}
Contract.EndContractBlock();
return (0);
@@ -514,34 +526,39 @@ namespace System.Globalization {
public override bool IsLeapMonth(int year, int month, int era)
{
- if (era != CurrentEra && era != ADEra) {
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ if (era != CurrentEra && era != ADEra)
+ {
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
- if (year < 1 || year > MaxYear) {
+ if (year < 1 || year > MaxYear)
+ {
throw new ArgumentOutOfRangeException(
nameof(year),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"), 1, MaxYear));
+ SR.ArgumentOutOfRange_Range, 1, MaxYear));
}
- if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Range",
+ if (month < 1 || month > 12)
+ {
+ throw new ArgumentOutOfRangeException(nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
1, 12));
}
Contract.EndContractBlock();
return (false);
-
}
// Checks whether a given year in the specified era is a leap year. This method returns true if
// year is a leap year, or false if not.
//
- public override bool IsLeapYear(int year, int era) {
- if (era == CurrentEra || era == ADEra) {
- if (year >= 1 && year <= MaxYear) {
+ public override bool IsLeapYear(int year, int era)
+ {
+ if (era == CurrentEra || era == ADEra)
+ {
+ if (year >= 1 && year <= MaxYear)
+ {
return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
}
@@ -549,9 +566,9 @@ namespace System.Globalization {
nameof(year),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"), 1, MaxYear));
+ SR.ArgumentOutOfRange_Range, 1, MaxYear));
}
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
// Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
@@ -559,15 +576,32 @@ namespace System.Globalization {
public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
{
- if (era == CurrentEra || era == ADEra) {
+ if (era == CurrentEra || era == ADEra)
+ {
return new DateTime(year, month, day, hour, minute, second, millisecond);
}
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
- internal override Boolean TryToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era, out DateTime result) {
- if (era == CurrentEra || era == ADEra) {
- return DateTime.TryCreate(year, month, day, hour, minute, second, millisecond, out result);
+ internal override Boolean TryToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era, out DateTime result)
+ {
+ if (era == CurrentEra || era == ADEra)
+ {
+ try
+ {
+ result = new DateTime(year, month, day, hour, minute, second, millisecond);
+ return true;
+ }
+ catch (ArgumentOutOfRangeException)
+ {
+ result = DateTime.Now;
+ return false;
+ }
+ catch (ArgumentException)
+ {
+ result = DateTime.Now;
+ return false;
+ }
}
result = DateTime.MinValue;
return false;
@@ -578,43 +612,49 @@ namespace System.Globalization {
public override int TwoDigitYearMax
{
- get {
- if (twoDigitYearMax == -1) {
+ get
+ {
+ if (twoDigitYearMax == -1)
+ {
twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
}
return (twoDigitYearMax);
}
- set {
+ set
+ {
VerifyWritable();
- if (value < 99 || value > MaxYear) {
+ if (value < 99 || value > MaxYear)
+ {
throw new ArgumentOutOfRangeException(
"year",
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
+ SR.ArgumentOutOfRange_Range,
99,
MaxYear));
-
}
twoDigitYearMax = value;
}
}
- public override int ToFourDigitYear(int year) {
- if (year < 0) {
+ public override int ToFourDigitYear(int year)
+ {
+ if (year < 0)
+ {
throw new ArgumentOutOfRangeException(nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
- if (year > MaxYear) {
+ if (year > MaxYear)
+ {
throw new ArgumentOutOfRangeException(
nameof(year),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"), 1, MaxYear));
+ SR.ArgumentOutOfRange_Range, 1, MaxYear));
}
return (base.ToFourDigitYear(year));
}
diff --git a/src/mscorlib/src/System/Globalization/GregorianCalendarHelper.cs b/src/mscorlib/src/System/Globalization/GregorianCalendarHelper.cs
index 062ae4818a..bdc35f0734 100644
--- a/src/mscorlib/src/System/Globalization/GregorianCalendarHelper.cs
+++ b/src/mscorlib/src/System/Globalization/GregorianCalendarHelper.cs
@@ -2,27 +2,25 @@
// 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.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+using System.Threading;
-namespace System.Globalization {
- using System;
- using System.Runtime.Serialization;
- using System.Threading;
- using System.Diagnostics.Contracts;
-
+namespace System.Globalization
+{
// Gregorian Calendars use Era Info
- // Note: We shouldn't have to serialize this since the info doesn't change, but we have been.
- // (We really only need the calendar #, and maybe culture)
[Serializable]
internal class EraInfo
{
- internal int era; // The value of the era.
+ internal int era; // The value of the era.
internal long ticks; // The time in ticks when the era starts
- internal int yearOffset; // The offset to Gregorian year when the era starts.
- // Gregorian Year = Era Year + yearOffset
- // Era Year = Gregorian Year - yearOffset
- internal int minEraYear; // Min year value in this era. Generally, this value is 1, but this may
- // be affected by the DateTime.MinValue;
- internal int maxEraYear; // Max year value in this era. (== the year length of the era + 1)
+ internal int yearOffset; // The offset to Gregorian year when the era starts.
+ // Gregorian Year = Era Year + yearOffset
+ // Era Year = Gregorian Year - yearOffset
+ internal int minEraYear; // Min year value in this era. Generally, this value is 1, but this may
+ // be affected by the DateTime.MinValue;
+ internal int maxEraYear; // Max year value in this era. (== the year length of the era + 1)
[OptionalField(VersionAdded = 4)]
internal String eraName; // The era name
@@ -57,90 +55,85 @@ namespace System.Globalization {
// This calendar recognizes two era values:
// 0 CurrentEra (AD)
// 1 BeforeCurrentEra (BC)
- [Serializable] internal class GregorianCalendarHelper {
-
+ [Serializable]
+ internal class GregorianCalendarHelper
+ {
// 1 tick = 100ns = 10E-7 second
// Number of ticks per time unit
- internal const long TicksPerMillisecond = 10000;
- internal const long TicksPerSecond = TicksPerMillisecond * 1000;
- internal const long TicksPerMinute = TicksPerSecond * 60;
- internal const long TicksPerHour = TicksPerMinute * 60;
- internal const long TicksPerDay = TicksPerHour * 24;
-
+ internal const long TicksPerMillisecond = 10000;
+ internal const long TicksPerSecond = TicksPerMillisecond * 1000;
+ internal const long TicksPerMinute = TicksPerSecond * 60;
+ internal const long TicksPerHour = TicksPerMinute * 60;
+ internal const long TicksPerDay = TicksPerHour * 24;
+
// Number of milliseconds per time unit
- internal const int MillisPerSecond = 1000;
- internal const int MillisPerMinute = MillisPerSecond * 60;
- internal const int MillisPerHour = MillisPerMinute * 60;
- internal const int MillisPerDay = MillisPerHour * 24;
+ internal const int MillisPerSecond = 1000;
+ internal const int MillisPerMinute = MillisPerSecond * 60;
+ internal const int MillisPerHour = MillisPerMinute * 60;
+ internal const int MillisPerDay = MillisPerHour * 24;
// Number of days in a non-leap year
- internal const int DaysPerYear = 365;
+ internal const int DaysPerYear = 365;
// Number of days in 4 years
- internal const int DaysPer4Years = DaysPerYear * 4 + 1;
+ internal const int DaysPer4Years = DaysPerYear * 4 + 1;
// Number of days in 100 years
- internal const int DaysPer100Years = DaysPer4Years * 25 - 1;
+ internal const int DaysPer100Years = DaysPer4Years * 25 - 1;
// Number of days in 400 years
- internal const int DaysPer400Years = DaysPer100Years * 4 + 1;
-
+ internal const int DaysPer400Years = DaysPer100Years * 4 + 1;
+
// Number of days from 1/1/0001 to 1/1/10000
- internal const int DaysTo10000 = DaysPer400Years * 25 - 366;
+ internal const int DaysTo10000 = DaysPer400Years * 25 - 366;
- internal const long MaxMillis = (long)DaysTo10000 * MillisPerDay;
+ internal const long MaxMillis = (long)DaysTo10000 * MillisPerDay;
internal const int DatePartYear = 0;
internal const int DatePartDayOfYear = 1;
internal const int DatePartMonth = 2;
- internal const int DatePartDay = 3;
+ internal const int DatePartDay = 3;
//
// This is the max Gregorian year can be represented by DateTime class. The limitation
// is derived from DateTime class.
//
- internal int MaxYear {
- get {
+ internal int MaxYear
+ {
+ get
+ {
return (m_maxYear);
}
}
- internal static readonly int[] DaysToMonth365 =
+ internal static readonly int[] DaysToMonth365 =
{
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
};
-
- internal static readonly int[] DaysToMonth366 =
+
+ internal static readonly int[] DaysToMonth366 =
{
0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366
};
- // Strictly these don't need serialized since they can be recreated from the calendar id
[OptionalField(VersionAdded = 1)]
internal int m_maxYear = 9999;
[OptionalField(VersionAdded = 1)]
internal int m_minYear;
internal Calendar m_Cal;
- // Era information doesn't need serialized, its constant for the same calendars (ie: we can recreate it from the calendar id)
[OptionalField(VersionAdded = 1)]
- internal EraInfo[] m_EraInfo;
+ internal EraInfo[] m_EraInfo;
[OptionalField(VersionAdded = 1)]
internal int[] m_eras = null;
- // m_minDate is existing here just to keep the serialization compatibility.
- // it has nothing to do with the code anymore.
- [OptionalField(VersionAdded = 1)]
- internal DateTime m_minDate;
-
+
// Construct an instance of gregorian calendar.
- internal GregorianCalendarHelper(Calendar cal, EraInfo[] eraInfo) {
+ internal GregorianCalendarHelper(Calendar cal, EraInfo[] eraInfo)
+ {
m_Cal = cal;
- m_EraInfo = eraInfo;
- // m_minDate is existing here just to keep the serialization compatibility.
- // it has nothing to do with the code anymore.
- m_minDate = m_Cal.MinSupportedDateTime;
+ m_EraInfo = eraInfo;
m_maxYear = m_EraInfo[0].maxEraYear;
- m_minYear = m_EraInfo[0].minEraYear;;
+ m_minYear = m_EraInfo[0].minEraYear; ;
}
-
+
/*=================================GetGregorianYear==========================
**Action: Get the Gregorian year value for the specified year in an era.
**Returns: The Gregorian year value.
@@ -151,58 +144,70 @@ namespace System.Globalization {
** ArgumentOutOfRangeException if year value is invalid or era value is invalid.
============================================================================*/
- internal int GetGregorianYear(int year, int era) {
- if (year < 0) {
+ internal int GetGregorianYear(int year, int era)
+ {
+ if (year < 0)
+ {
throw new ArgumentOutOfRangeException(nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
+ SR.ArgumentOutOfRange_NeedNonNegNum);
+ }
Contract.EndContractBlock();
- if (era == Calendar.CurrentEra) {
+ if (era == Calendar.CurrentEra)
+ {
era = m_Cal.CurrentEraValue;
}
-
- for (int i = 0; i < m_EraInfo.Length; i++) {
- if (era == m_EraInfo[i].era) {
- if (year < m_EraInfo[i].minEraYear || year > m_EraInfo[i].maxEraYear) {
+
+ for (int i = 0; i < m_EraInfo.Length; i++)
+ {
+ if (era == m_EraInfo[i].era)
+ {
+ if (year < m_EraInfo[i].minEraYear || year > m_EraInfo[i].maxEraYear)
+ {
throw new ArgumentOutOfRangeException(
- nameof(year),
+ nameof(year),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- m_EraInfo[i].minEraYear,
+ SR.ArgumentOutOfRange_Range,
+ m_EraInfo[i].minEraYear,
m_EraInfo[i].maxEraYear));
}
return (m_EraInfo[i].yearOffset + year);
}
}
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
+ throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
}
-
- internal bool IsValidYear(int year, int era) {
- if (year < 0) {
+
+ internal bool IsValidYear(int year, int era)
+ {
+ if (year < 0)
+ {
return false;
- }
+ }
- if (era == Calendar.CurrentEra) {
+ if (era == Calendar.CurrentEra)
+ {
era = m_Cal.CurrentEraValue;
}
-
- for (int i = 0; i < m_EraInfo.Length; i++) {
- if (era == m_EraInfo[i].era) {
- if (year < m_EraInfo[i].minEraYear || year > m_EraInfo[i].maxEraYear) {
+
+ for (int i = 0; i < m_EraInfo.Length; i++)
+ {
+ if (era == m_EraInfo[i].era)
+ {
+ if (year < m_EraInfo[i].minEraYear || year > m_EraInfo[i].maxEraYear)
+ {
return false;
}
return true;
}
}
return false;
- }
-
+ }
+
// Returns a given date part of this DateTime. This method is used
// to compute the year, day-of-year, month, or day part.
- internal virtual int GetDatePart(long ticks, int part)
+ internal virtual int GetDatePart(long ticks, int part)
{
CheckTicksRange(ticks);
// n = number of days since 1/1/0001
@@ -214,7 +219,7 @@ namespace System.Globalization {
// y100 = number of whole 100-year periods within 400-year period
int y100 = n / DaysPer100Years;
// Last 100-year period has an extra day, so decrement result if 4
- if (y100 == 4) y100 = 3;
+ if (y100 == 4) y100 = 3;
// n = day number within 100-year period
n -= y100 * DaysPer100Years;
// y4 = number of whole 4-year periods within 100-year period
@@ -224,23 +229,23 @@ namespace System.Globalization {
// y1 = number of whole years within 4-year period
int y1 = n / DaysPerYear;
// Last year has an extra day, so decrement result if 4
- if (y1 == 4) y1 = 3;
+ if (y1 == 4) y1 = 3;
// If year was requested, compute and return it
- if (part == DatePartYear)
+ if (part == DatePartYear)
{
return (y400 * 400 + y100 * 100 + y4 * 4 + y1 + 1);
}
// n = day number within year
n -= y1 * DaysPerYear;
// If day-of-year was requested, return it
- if (part == DatePartDayOfYear)
+ if (part == DatePartDayOfYear)
{
return (n + 1);
}
// Leap year calculation looks different from IsLeapYear since y1, y4,
// and y100 are relative to year 1, not year 0
bool leapYear = (y1 == 3 && (y4 != 24 || y100 == 3));
- int[] days = leapYear? DaysToMonth366: DaysToMonth365;
+ int[] days = leapYear ? DaysToMonth366 : DaysToMonth365;
// All months have less than 32 days, so n >> 5 is a good conservative
// estimate for the month
int m = (n >> 5) + 1;
@@ -270,23 +275,26 @@ namespace System.Globalization {
**
============================================================================*/
- internal static long GetAbsoluteDate(int year, int month, int day) {
- if (year >= 1 && year <= 9999 && month >= 1 && month <= 12)
+ internal static long GetAbsoluteDate(int year, int month, int day)
+ {
+ if (year >= 1 && year <= 9999 && month >= 1 && month <= 12)
{
- int[] days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))) ? DaysToMonth366: DaysToMonth365;
- if (day >= 1 && (day <= days[month] - days[month - 1])) {
+ int[] days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))) ? DaysToMonth366 : DaysToMonth365;
+ if (day >= 1 && (day <= days[month] - days[month - 1]))
+ {
int y = year - 1;
int absoluteDate = y * 365 + y / 4 - y / 100 + y / 400 + days[month - 1] + day - 1;
return (absoluteDate);
}
}
- throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
- }
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadYearMonthDay);
+ }
// Returns the tick count corresponding to the given year, month, and day.
// Will check the if the parameters are valid.
- internal static long DateToTicks(int year, int month, int day) {
- return (GetAbsoluteDate(year, month, day)* TicksPerDay);
+ internal static long DateToTicks(int year, int month, int day)
+ {
+ return (GetAbsoluteDate(year, month, day) * TicksPerDay);
}
// Return the tick count corresponding to the given hour, minute, second.
@@ -295,30 +303,33 @@ namespace System.Globalization {
{
//TimeSpan.TimeToTicks is a family access function which does no error checking, so
//we need to put some error checking out here.
- if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >=0 && second < 60)
+ if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >= 0 && second < 60)
{
- if (millisecond < 0 || millisecond >= MillisPerSecond) {
+ if (millisecond < 0 || millisecond >= MillisPerSecond)
+ {
throw new ArgumentOutOfRangeException(
- nameof(millisecond),
+ nameof(millisecond),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 0,
+ SR.ArgumentOutOfRange_Range,
+ 0,
MillisPerSecond - 1));
- }
- return (TimeSpan.TimeToTicks(hour, minute, second) + millisecond * TicksPerMillisecond);;
+ }
+ return (InternalGlobalizationHelper.TimeToTicks(hour, minute, second) + millisecond * TicksPerMillisecond); ;
}
- throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadHourMinuteSecond"));
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
}
-
- internal void CheckTicksRange(long ticks) {
- if (ticks < m_Cal.MinSupportedDateTime.Ticks || ticks > m_Cal.MaxSupportedDateTime.Ticks) {
+
+ internal void CheckTicksRange(long ticks)
+ {
+ if (ticks < m_Cal.MinSupportedDateTime.Ticks || ticks > m_Cal.MaxSupportedDateTime.Ticks)
+ {
throw new ArgumentOutOfRangeException(
- "time",
+ "time",
String.Format(
- CultureInfo.InvariantCulture,
- Environment.GetResourceString("ArgumentOutOfRange_CalendarRange"),
+ CultureInfo.InvariantCulture,
+ SR.ArgumentOutOfRange_CalendarRange,
m_Cal.MinSupportedDateTime,
m_Cal.MaxSupportedDateTime));
}
@@ -342,15 +353,16 @@ namespace System.Globalization {
// or equal to d that denotes a valid day in month m1 of year
// y1.
//
- public DateTime AddMonths(DateTime time, int months)
+ public DateTime AddMonths(DateTime time, int months)
{
- if (months < -120000 || months > 120000) {
+ if (months < -120000 || months > 120000)
+ {
throw new ArgumentOutOfRangeException(
- nameof(months),
+ nameof(months),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- -120000,
+ SR.ArgumentOutOfRange_Range,
+ -120000,
120000));
}
Contract.EndContractBlock();
@@ -360,20 +372,20 @@ namespace System.Globalization {
int m = GetDatePart(time.Ticks, DatePartMonth);
int d = GetDatePart(time.Ticks, DatePartDay);
int i = m - 1 + months;
- if (i >= 0)
+ if (i >= 0)
{
m = i % 12 + 1;
y = y + i / 12;
}
- else
+ else
{
m = 12 + (i + 1) % 12;
y = y + (i - 11) / 12;
}
- int[] daysArray = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? DaysToMonth366: DaysToMonth365;
- int days = (daysArray[m] - daysArray[m - 1]);
-
- if (d > days)
+ int[] daysArray = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? DaysToMonth366 : DaysToMonth365;
+ int days = (daysArray[m] - daysArray[m - 1]);
+
+ if (d > days)
{
d = days;
}
@@ -381,7 +393,7 @@ namespace System.Globalization {
Calendar.CheckAddResult(ticks, m_Cal.MinSupportedDateTime, m_Cal.MaxSupportedDateTime);
return (new DateTime(ticks));
}
-
+
// Returns the DateTime resulting from adding the given number of
// years to the specified DateTime. The result is computed by incrementing
// (or decrementing) the year part of the specified DateTime by value
@@ -390,11 +402,11 @@ namespace System.Globalization {
// DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
// parts of the result are the same as those of the specified DateTime.
//
- public DateTime AddYears(DateTime time, int years)
+ public DateTime AddYears(DateTime time, int years)
{
return (AddMonths(time, years * 12));
}
-
+
// Returns the day-of-month part of the specified DateTime. The returned
// value is an integer between 1 and 31.
//
@@ -402,18 +414,18 @@ namespace System.Globalization {
{
return (GetDatePart(time.Ticks, DatePartDay));
}
-
+
// Returns the day-of-week part of the specified DateTime. The returned value
// is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
// Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
// Thursday, 5 indicates Friday, and 6 indicates Saturday.
//
- public DayOfWeek GetDayOfWeek(DateTime time)
+ public DayOfWeek GetDayOfWeek(DateTime time)
{
CheckTicksRange(time.Ticks);
return ((DayOfWeek)((time.Ticks / TicksPerDay + 1) % 7));
}
-
+
// Returns the day-of-year part of the specified DateTime. The returned value
// is an integer between 1 and 366.
//
@@ -426,18 +438,20 @@ namespace System.Globalization {
// month arguments.
//
[Pure]
- public int GetDaysInMonth(int year, int month, int era) {
+ public int GetDaysInMonth(int year, int month, int era)
+ {
//
// Convert year/era value to Gregorain year value.
//
year = GetGregorianYear(year, era);
- if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
+ if (month < 1 || month > 12)
+ {
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_Month);
}
- int[] days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? DaysToMonth366: DaysToMonth365);
- return (days[month] - days[month - 1]);
+ int[] days = ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? DaysToMonth366 : DaysToMonth365);
+ return (days[month] - days[month - 1]);
}
-
+
// Returns the number of days in the year given by the year argument for the current era.
//
@@ -447,83 +461,93 @@ namespace System.Globalization {
// Convert year/era value to Gregorain year value.
//
year = GetGregorianYear(year, era);
- return ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? 366:365);
+ return ((year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? 366 : 365);
}
-
+
// Returns the era for the specified DateTime value.
public int GetEra(DateTime time)
{
long ticks = time.Ticks;
// The assumption here is that m_EraInfo is listed in reverse order.
- for (int i = 0; i < m_EraInfo.Length; i++) {
- if (ticks >= m_EraInfo[i].ticks) {
+ for (int i = 0; i < m_EraInfo.Length; i++)
+ {
+ if (ticks >= m_EraInfo[i].ticks)
+ {
return (m_EraInfo[i].era);
}
}
- throw new ArgumentOutOfRangeException(nameof(time), Environment.GetResourceString("ArgumentOutOfRange_Era"));
+ throw new ArgumentOutOfRangeException(nameof(time), SR.ArgumentOutOfRange_Era);
}
- public int[] Eras {
- get {
- if (m_eras == null) {
+ public int[] Eras
+ {
+ get
+ {
+ if (m_eras == null)
+ {
m_eras = new int[m_EraInfo.Length];
- for (int i = 0; i < m_EraInfo.Length; i++) {
+ for (int i = 0; i < m_EraInfo.Length; i++)
+ {
m_eras[i] = m_EraInfo[i].era;
}
}
return ((int[])m_eras.Clone());
}
}
-
+
// Returns the month part of the specified DateTime. The returned value is an
// integer between 1 and 12.
//
- public int GetMonth(DateTime time)
+ public int GetMonth(DateTime time)
{
return (GetDatePart(time.Ticks, DatePartMonth));
}
-
+
// Returns the number of months in the specified year and era.
public int GetMonthsInYear(int year, int era)
{
year = GetGregorianYear(year, era);
return (12);
}
-
+
// Returns the year part of the specified DateTime. The returned value is an
// integer between 1 and 9999.
//
- public int GetYear(DateTime time)
+ public int GetYear(DateTime time)
{
long ticks = time.Ticks;
int year = GetDatePart(ticks, DatePartYear);
- for (int i = 0; i < m_EraInfo.Length; i++) {
- if (ticks >= m_EraInfo[i].ticks) {
+ for (int i = 0; i < m_EraInfo.Length; i++)
+ {
+ if (ticks >= m_EraInfo[i].ticks)
+ {
return (year - m_EraInfo[i].yearOffset);
}
}
- throw new ArgumentException(Environment.GetResourceString("Argument_NoEra"));
- }
-
+ throw new ArgumentException(SR.Argument_NoEra);
+ }
+
// Returns the year that match the specified Gregorian year. The returned value is an
// integer between 1 and 9999.
//
- public int GetYear(int year, DateTime time)
+ public int GetYear(int year, DateTime time)
{
long ticks = time.Ticks;
- for (int i = 0; i < m_EraInfo.Length; i++) {
- // while calculating dates with JapaneseLuniSolarCalendar, we can run into cases right after the start of the era
- // and still belong to the month which is started in previous era. Calculating equivalent calendar date will cause
- // using the new era info which will have the year offset equal to the year we are calculating year = m_EraInfo[i].yearOffset
+ for (int i = 0; i < m_EraInfo.Length; i++)
+ {
+ // while calculating dates with JapaneseLuniSolarCalendar, we can run into cases right after the start of the era
+ // and still belong to the month which is started in previous era. Calculating equivalent calendar date will cause
+ // using the new era info which will have the year offset equal to the year we are calculating year = m_EraInfo[i].yearOffset
// which will end up with zero as calendar year.
// We should use the previous era info instead to get the right year number. Example of such date is Feb 2nd 1989
- if (ticks >= m_EraInfo[i].ticks && year > m_EraInfo[i].yearOffset) {
+ if (ticks >= m_EraInfo[i].ticks && year > m_EraInfo[i].yearOffset)
+ {
return (year - m_EraInfo[i].yearOffset);
}
}
- throw new ArgumentException(Environment.GetResourceString("Argument_NoEra"));
- }
+ throw new ArgumentException(SR.Argument_NoEra);
+ }
// Checks whether a given day in the specified era is a leap day. This method returns true if
// the date is a leap day, or false if not.
@@ -531,35 +555,38 @@ namespace System.Globalization {
public bool IsLeapDay(int year, int month, int day, int era)
{
// year/month/era checking is done in GetDaysInMonth()
- if (day < 1 || day > GetDaysInMonth(year, month, era)) {
+ if (day < 1 || day > GetDaysInMonth(year, month, era))
+ {
throw new ArgumentOutOfRangeException(
- nameof(day),
+ nameof(day),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 1,
- GetDaysInMonth(year, month, era)));
+ SR.ArgumentOutOfRange_Range,
+ 1,
+ GetDaysInMonth(year, month, era)));
}
Contract.EndContractBlock();
-
- if (!IsLeapYear(year, era)) {
+
+ if (!IsLeapYear(year, era))
+ {
return (false);
}
-
- if (month == 2 && day == 29) {
+
+ if (month == 2 && day == 29)
+ {
return (true);
}
-
- return (false);
+
+ return (false);
}
-
+
// Returns the leap month in a calendar year of the specified era. This method returns 0
// if this calendar does not have leap month, or this year is not a leap year.
//
public int GetLeapMonth(int year, int era)
{
year = GetGregorianYear(year, era);
- return (0);
+ return (0);
}
// Checks whether a given month in the specified era is a leap month. This method returns true if
@@ -568,36 +595,40 @@ namespace System.Globalization {
public bool IsLeapMonth(int year, int month, int era)
{
year = GetGregorianYear(year, era);
- if (month < 1 || month > 12) {
+ if (month < 1 || month > 12)
+ {
throw new ArgumentOutOfRangeException(
- nameof(month),
+ nameof(month),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 1,
- 12));
- }
- return (false);
+ SR.ArgumentOutOfRange_Range,
+ 1,
+ 12));
+ }
+ return (false);
}
-
+
// Checks whether a given year in the specified era is a leap year. This method returns true if
// year is a leap year, or false if not.
//
- public bool IsLeapYear(int year, int era) {
+ public bool IsLeapYear(int year, int era)
+ {
year = GetGregorianYear(year, era);
return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
}
-
+
// Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
//
- public DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) {
+ public DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
+ {
year = GetGregorianYear(year, era);
long ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second, millisecond);
CheckTicksRange(ticks);
return (new DateTime(ticks));
}
- public virtual int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek) {
+ public virtual int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
+ {
CheckTicksRange(time.Ticks);
// Use GregorianCalendar to get around the problem that the implmentation in Calendar.GetWeekOfYear()
// can call GetYear() that exceeds the supported range of the Gregorian-based calendars.
@@ -605,29 +636,33 @@ namespace System.Globalization {
}
- public int ToFourDigitYear(int year, int twoDigitYearMax) {
- if (year < 0) {
+ public int ToFourDigitYear(int year, int twoDigitYearMax)
+ {
+ if (year < 0)
+ {
throw new ArgumentOutOfRangeException(nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ SR.ArgumentOutOfRange_NeedPosNum);
}
Contract.EndContractBlock();
-
- if (year < 100) {
+
+ if (year < 100)
+ {
int y = year % 100;
- return ((twoDigitYearMax/100 - ( y > twoDigitYearMax % 100 ? 1 : 0))*100 + y);
+ return ((twoDigitYearMax / 100 - (y > twoDigitYearMax % 100 ? 1 : 0)) * 100 + y);
}
-
- if (year < m_minYear || year > m_maxYear) {
+
+ if (year < m_minYear || year > m_maxYear)
+ {
throw new ArgumentOutOfRangeException(
nameof(year),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"), m_minYear, m_maxYear));
+ SR.ArgumentOutOfRange_Range, m_minYear, m_maxYear));
}
// If the year value is above 100, just return the year value. Don't have to do
// the TwoDigitYearMax comparison.
return (year);
}
- }
+ }
}
diff --git a/src/mscorlib/src/System/Globalization/GregorianCalendarTypes.cs b/src/mscorlib/src/System/Globalization/GregorianCalendarTypes.cs
deleted file mode 100644
index 1af5e9221c..0000000000
--- a/src/mscorlib/src/System/Globalization/GregorianCalendarTypes.cs
+++ /dev/null
@@ -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.
-
-namespace System.Globalization {
- using System;
-
- [Serializable]
- public enum GregorianCalendarTypes {
- Localized = Calendar.CAL_GREGORIAN,
- USEnglish = Calendar.CAL_GREGORIAN_US,
- MiddleEastFrench = Calendar.CAL_GREGORIAN_ME_FRENCH,
- Arabic = Calendar.CAL_GREGORIAN_ARABIC,
- TransliteratedEnglish = Calendar.CAL_GREGORIAN_XLIT_ENGLISH,
- TransliteratedFrench = Calendar.CAL_GREGORIAN_XLIT_FRENCH,
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/HebrewCalendar.cs b/src/mscorlib/src/System/Globalization/HebrewCalendar.cs
deleted file mode 100644
index 190c3f17d2..0000000000
--- a/src/mscorlib/src/System/Globalization/HebrewCalendar.cs
+++ /dev/null
@@ -1,1084 +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.
-
-namespace System.Globalization {
- using System;
- using System.Text;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Rules for the Hebrew calendar:
- // - The Hebrew calendar is both a Lunar (months) and Solar (years)
- // calendar, but allows for a week of seven days.
- // - Days begin at sunset.
- // - Leap Years occur in the 3, 6, 8, 11, 14, 17, & 19th years of a
- // 19-year cycle. Year = leap iff ((7y+1) mod 19 < 7).
- // - There are 12 months in a common year and 13 months in a leap year.
- // - In a common year, the 6th month, Adar, has 29 days. In a leap
- // year, the 6th month, Adar I, has 30 days and the leap month,
- // Adar II, has 29 days.
- // - Common years have 353-355 days. Leap years have 383-385 days.
- // - The Hebrew new year (Rosh HaShanah) begins on the 1st of Tishri,
- // the 7th month in the list below.
- // - The new year may not begin on Sunday, Wednesday, or Friday.
- // - If the new year would fall on a Tuesday and the conjunction of
- // the following year were at midday or later, the new year is
- // delayed until Thursday.
- // - If the new year would fall on a Monday after a leap year, the
- // new year is delayed until Tuesday.
- // - The length of the 8th and 9th months vary from year to year,
- // depending on the overall length of the year.
- // - The length of a year is determined by the dates of the new
- // years (Tishri 1) preceding and following the year in question.
- // - The 2th month is long (30 days) if the year has 355 or 385 days.
- // - The 3th month is short (29 days) if the year has 353 or 383 days.
- // - The Hebrew months are:
- // 1. Tishri (30 days)
- // 2. Heshvan (29 or 30 days)
- // 3. Kislev (29 or 30 days)
- // 4. Teveth (29 days)
- // 5. Shevat (30 days)
- // 6. Adar I (30 days)
- // 7. Adar {II} (29 days, this only exists if that year is a leap year)
- // 8. Nisan (30 days)
- // 9. Iyyar (29 days)
- // 10. Sivan (30 days)
- // 11. Tammuz (29 days)
- // 12. Av (30 days)
- // 13. Elul (29 days)
- //
- ////////////////////////////////////////////////////////////////////////////
- /*
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 1583/01/01 2239/09/29
- ** Hebrew 5343/04/07 5999/13/29
- */
-
-// Includes CHebrew implemetation;i.e All the code necessary for converting
-// Gregorian to Hebrew Lunar from 1583 to 2239.
-
-
- [Serializable]
- public class HebrewCalendar : Calendar {
-
-
- public static readonly int HebrewEra = 1;
-
- internal const int DatePartYear = 0;
- internal const int DatePartDayOfYear = 1;
- internal const int DatePartMonth = 2;
- internal const int DatePartDay = 3;
- internal const int DatePartDayOfWeek = 4;
-
- //
- // Hebrew Translation Table.
- //
- // This table is used to get the following Hebrew calendar information for a
- // given Gregorian year:
- // 1. The day of the Hebrew month corresponding to Gregorian January 1st
- // for a given Gregorian year.
- // 2. The month of the Hebrew month corresponding to Gregorian January 1st
- // for a given Gregorian year.
- // The information is not directly in the table. Instead, the info is decoded
- // by special values (numbers above 29 and below 1).
- // 3. The type of the Hebrew year for a given Gregorian year.
- //
-
- /*
- More notes:
-
- This table includes 2 numbers for each year.
- The offset into the table determines the year. (offset 0 is Gregorian year 1500)
- 1st number determines the day of the Hebrew month coresponeds to January 1st.
- 2nd number determines the type of the Hebrew year. (the type determines how
- many days are there in the year.)
-
- normal years : 1 = 353 days 2 = 354 days 3 = 355 days.
- Leap years : 4 = 383 5 384 6 = 385 days.
-
- A 99 means the year is not supported for translation.
- for convenience the table was defined for 750 year,
- but only 640 years are supported. (from 1583 to 2239)
- the years before 1582 (starting of Georgian calander)
- and after 2239, are filled with 99.
-
- Greogrian January 1st falls usually in Tevet (4th month). Tevet has always 29 days.
- That's why, there no nead to specify the lunar month in the table.
- There are exceptions, these are coded by giving numbers above 29 and below 1.
- Actual decoding is takenig place whenever fetching information from the table.
- The function for decoding is in GetLunarMonthDay().
-
- Example:
- The data for 2000 - 2005 A.D. is:
-
- 23,6,6,1,17,2,27,6,7,3, // 2000 - 2004
-
- For year 2000, we know it has a Hebrew year type 6, which means it has 385 days.
- And 1/1/2000 A.D. is Hebrew year 5760, 23rd day of 4th month.
- */
-
- //
- // Jewish Era in use today is dated from the supposed year of the
- // Creation with its beginning in 3761 B.C.
- //
-
- // The Hebrew year of Gregorian 1st year AD.
- // 0001/01/01 AD is Hebrew 3760/01/01
- private const int HebrewYearOf1AD = 3760;
-
- // The first Gregorian year in HebrewTable.
- private const int FirstGregorianTableYear = 1583; // == Hebrew Year 5343
- // The last Gregorian year in HebrewTable.
- private const int LastGregorianTableYear = 2239; // == Hebrew Year 5999
- private const int TABLESIZE = (LastGregorianTableYear-FirstGregorianTableYear);
-
- private const int MinHebrewYear = HebrewYearOf1AD + FirstGregorianTableYear; // == 5343
- private const int MaxHebrewYear = HebrewYearOf1AD + LastGregorianTableYear; // == 5999
-
- private static readonly int[] HebrewTable = {
- 7,3,17,3, // 1583-1584 (Hebrew year: 5343 - 5344)
- 0,4,11,2,21,6,1,3,13,2, // 1585-1589
- 25,4,5,3,16,2,27,6,9,1, // 1590-1594
- 20,2,0,6,11,3,23,4,4,2, // 1595-1599
- 14,3,27,4,8,2,18,3,28,6, // 1600
- 11,1,22,5,2,3,12,3,25,4, // 1605
- 6,2,16,3,26,6,8,2,20,1, // 1610
- 0,6,11,2,24,4,4,3,15,2, // 1615
- 25,6,8,1,19,2,29,6,9,3, // 1620
- 22,4,3,2,13,3,25,4,6,3, // 1625
- 17,2,27,6,7,3,19,2,31,4, // 1630
- 11,3,23,4,5,2,15,3,25,6, // 1635
- 6,2,19,1,29,6,10,2,22,4, // 1640
- 3,3,14,2,24,6,6,1,17,3, // 1645
- 28,5,8,3,20,1,32,5,12,3, // 1650
- 22,6,4,1,16,2,26,6,6,3, // 1655
- 17,2,0,4,10,3,22,4,3,2, // 1660
- 14,3,24,6,5,2,17,1,28,6, // 1665
- 9,2,19,3,31,4,13,2,23,6, // 1670
- 3,3,15,1,27,5,7,3,17,3, // 1675
- 29,4,11,2,21,6,3,1,14,2, // 1680
- 25,6,5,3,16,2,28,4,9,3, // 1685
- 20,2,0,6,12,1,23,6,4,2, // 1690
- 14,3,26,4,8,2,18,3,0,4, // 1695
- 10,3,21,5,1,3,13,1,24,5, // 1700
- 5,3,15,3,27,4,8,2,19,3, // 1705
- 29,6,10,2,22,4,3,3,14,2, // 1710
- 26,4,6,3,18,2,28,6,10,1, // 1715
- 20,6,2,2,12,3,24,4,5,2, // 1720
- 16,3,28,4,8,3,19,2,0,6, // 1725
- 12,1,23,5,3,3,14,3,26,4, // 1730
- 7,2,17,3,28,6,9,2,21,4, // 1735
- 1,3,13,2,25,4,5,3,16,2, // 1740
- 27,6,9,1,19,3,0,5,11,3, // 1745
- 23,4,4,2,14,3,25,6,7,1, // 1750
- 18,2,28,6,9,3,21,4,2,2, // 1755
- 12,3,25,4,6,2,16,3,26,6, // 1760
- 8,2,20,1,0,6,11,2,22,6, // 1765
- 4,1,15,2,25,6,6,3,18,1, // 1770
- 29,5,9,3,22,4,2,3,13,2, // 1775
- 23,6,4,3,15,2,27,4,7,3, // 1780
- 19,2,31,4,11,3,21,6,3,2, // 1785
- 15,1,25,6,6,2,17,3,29,4, // 1790
- 10,2,20,6,3,1,13,3,24,5, // 1795
- 4,3,16,1,27,5,7,3,17,3, // 1800
- 0,4,11,2,21,6,1,3,13,2, // 1805
- 25,4,5,3,16,2,29,4,9,3, // 1810
- 19,6,30,2,13,1,23,6,4,2, // 1815
- 14,3,27,4,8,2,18,3,0,4, // 1820
- 11,3,22,5,2,3,14,1,26,5, // 1825
- 6,3,16,3,28,4,10,2,20,6, // 1830
- 30,3,11,2,24,4,4,3,15,2, // 1835
- 25,6,8,1,19,2,29,6,9,3, // 1840
- 22,4,3,2,13,3,25,4,7,2, // 1845
- 17,3,27,6,9,1,21,5,1,3, // 1850
- 11,3,23,4,5,2,15,3,25,6, // 1855
- 6,2,19,1,29,6,10,2,22,4, // 1860
- 3,3,14,2,24,6,6,1,18,2, // 1865
- 28,6,8,3,20,4,2,2,12,3, // 1870
- 24,4,4,3,16,2,26,6,6,3, // 1875
- 17,2,0,4,10,3,22,4,3,2, // 1880
- 14,3,24,6,5,2,17,1,28,6, // 1885
- 9,2,21,4,1,3,13,2,23,6, // 1890
- 5,1,15,3,27,5,7,3,19,1, // 1895
- 0,5,10,3,22,4,2,3,13,2, // 1900
- 24,6,4,3,15,2,27,4,8,3, // 1905
- 20,4,1,2,11,3,22,6,3,2, // 1910
- 15,1,25,6,7,2,17,3,29,4, // 1915
- 10,2,21,6,1,3,13,1,24,5, // 1920
- 5,3,15,3,27,4,8,2,19,6, // 1925
- 1,1,12,2,22,6,3,3,14,2, // 1930
- 26,4,6,3,18,2,28,6,10,1, // 1935
- 20,6,2,2,12,3,24,4,5,2, // 1940
- 16,3,28,4,9,2,19,6,30,3, // 1945
- 12,1,23,5,3,3,14,3,26,4, // 1950
- 7,2,17,3,28,6,9,2,21,4, // 1955
- 1,3,13,2,25,4,5,3,16,2, // 1960
- 27,6,9,1,19,6,30,2,11,3, // 1965
- 23,4,4,2,14,3,27,4,7,3, // 1970
- 18,2,28,6,11,1,22,5,2,3, // 1975
- 12,3,25,4,6,2,16,3,26,6, // 1980
- 8,2,20,4,30,3,11,2,24,4, // 1985
- 4,3,15,2,25,6,8,1,18,3, // 1990
- 29,5,9,3,22,4,3,2,13,3, // 1995
- 23,6,6,1,17,2,27,6,7,3, // 2000 - 2004
- 20,4,1,2,11,3,23,4,5,2, // 2005 - 2009
- 15,3,25,6,6,2,19,1,29,6, // 2010
- 10,2,20,6,3,1,14,2,24,6, // 2015
- 4,3,17,1,28,5,8,3,20,4, // 2020
- 1,3,12,2,22,6,2,3,14,2, // 2025
- 26,4,6,3,17,2,0,4,10,3, // 2030
- 20,6,1,2,14,1,24,6,5,2, // 2035
- 15,3,28,4,9,2,19,6,1,1, // 2040
- 12,3,23,5,3,3,15,1,27,5, // 2045
- 7,3,17,3,29,4,11,2,21,6, // 2050
- 1,3,12,2,25,4,5,3,16,2, // 2055
- 28,4,9,3,19,6,30,2,12,1, // 2060
- 23,6,4,2,14,3,26,4,8,2, // 2065
- 18,3,0,4,10,3,22,5,2,3, // 2070
- 14,1,25,5,6,3,16,3,28,4, // 2075
- 9,2,20,6,30,3,11,2,23,4, // 2080
- 4,3,15,2,27,4,7,3,19,2, // 2085
- 29,6,11,1,21,6,3,2,13,3, // 2090
- 25,4,6,2,17,3,27,6,9,1, // 2095
- 20,5,30,3,10,3,22,4,3,2, // 2100
- 14,3,24,6,5,2,17,1,28,6, // 2105
- 9,2,21,4,1,3,13,2,23,6, // 2110
- 5,1,16,2,27,6,7,3,19,4, // 2115
- 30,2,11,3,23,4,3,3,14,2, // 2120
- 25,6,5,3,16,2,28,4,9,3, // 2125
- 21,4,2,2,12,3,23,6,4,2, // 2130
- 16,1,26,6,8,2,20,4,30,3, // 2135
- 11,2,22,6,4,1,14,3,25,5, // 2140
- 6,3,18,1,29,5,9,3,22,4, // 2145
- 2,3,13,2,23,6,4,3,15,2, // 2150
- 27,4,7,3,20,4,1,2,11,3, // 2155
- 21,6,3,2,15,1,25,6,6,2, // 2160
- 17,3,29,4,10,2,20,6,3,1, // 2165
- 13,3,24,5,4,3,17,1,28,5, // 2170
- 8,3,18,6,1,1,12,2,22,6, // 2175
- 2,3,14,2,26,4,6,3,17,2, // 2180
- 28,6,10,1,20,6,1,2,12,3, // 2185
- 24,4,5,2,15,3,28,4,9,2, // 2190
- 19,6,33,3,12,1,23,5,3,3, // 2195
- 13,3,25,4,6,2,16,3,26,6, // 2200
- 8,2,20,4,30,3,11,2,24,4, // 2205
- 4,3,15,2,25,6,8,1,18,6, // 2210
- 33,2,9,3,22,4,3,2,13,3, // 2215
- 25,4,6,3,17,2,27,6,9,1, // 2220
- 21,5,1,3,11,3,23,4,5,2, // 2225
- 15,3,25,6,6,2,19,4,33,3, // 2230
- 10,2,22,4,3,3,14,2,24,6, // 2235
- 6,1 // 2240 (Hebrew year: 6000)
- };
-
- //
- // The lunar calendar has 6 different variations of month lengths
- // within a year.
- //
- private static readonly int[,] LunarMonthLen = {
- {0,00,00,00,00,00,00,00,00,00,00,00,00,0},
- {0,30,29,29,29,30,29,30,29,30,29,30,29,0}, // 3 common year variations
- {0,30,29,30,29,30,29,30,29,30,29,30,29,0},
- {0,30,30,30,29,30,29,30,29,30,29,30,29,0},
- {0,30,29,29,29,30,30,29,30,29,30,29,30,29}, // 3 leap year variations
- {0,30,29,30,29,30,30,29,30,29,30,29,30,29},
- {0,30,30,30,29,30,30,29,30,29,30,29,30,29}
- };
-
- //internal static Calendar m_defaultInstance;
-
- internal static readonly DateTime calendarMinValue = new DateTime(1583, 1, 1);
- // Gregorian 2239/9/29 = Hebrew 5999/13/29 (last day in Hebrew year 5999).
- // We can only format/parse Hebrew numbers up to 999, so we limit the max range to Hebrew year 5999.
- internal static readonly DateTime calendarMaxValue = new DateTime((new DateTime(2239, 9, 29, 23, 59, 59, 999)).Ticks + 9999);
-
-
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (calendarMinValue);
- }
- }
-
-
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (calendarMaxValue);
- }
- }
-
-
- // Return the type of the Hebrew calendar.
- //
-
-
- public override CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.LunisolarCalendar;
- }
- }
-
- /*=================================GetDefaultInstance==========================
- **Action: Internal method to provide a default intance of HebrewCalendar. Used by NLS+ implementation
- ** and other calendars.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
-
- /*
- internal static Calendar GetDefaultInstance() {
- if (m_defaultInstance == null) {
- m_defaultInstance = new HebrewCalendar();
- }
- return (m_defaultInstance);
- }
- */
-
-
- // Construct an instance of gregorian calendar.
-
- public HebrewCalendar() {
- }
-
- internal override int ID {
- get {
- return (CAL_HEBREW);
- }
- }
-
-
- /*=================================CheckHebrewYearValue==========================
- **Action: Check if the Hebrew year value is supported in this class.
- **Returns: None.
- **Arguments: y Hebrew year value
- ** ear Hebrew era value
- **Exceptions: ArgumentOutOfRange_Range if the year value is not supported.
- **Note:
- ** We use a table for the Hebrew calendar calculation, so the year supported is limited.
- ============================================================================*/
-
- static private void CheckHebrewYearValue(int y, int era, String varName) {
- CheckEraRange(era);
- if (y > MaxHebrewYear || y < MinHebrewYear) {
- throw new ArgumentOutOfRangeException(
- varName,
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- MinHebrewYear,
- MaxHebrewYear));
- }
- }
-
- /*=================================CheckHebrewMonthValue==========================
- **Action: Check if the Hebrew month value is valid.
- **Returns: None.
- **Arguments: year Hebrew year value
- ** month Hebrew month value
- **Exceptions: ArgumentOutOfRange_Range if the month value is not valid.
- **Note:
- ** Call CheckHebrewYearValue() before calling this to verify the year value is supported.
- ============================================================================*/
-
- private void CheckHebrewMonthValue(int year, int month, int era) {
- int monthsInYear = GetMonthsInYear(year, era);
- if (month < 1 || month > monthsInYear) {
- throw new ArgumentOutOfRangeException(
- nameof(month),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 1,
- monthsInYear));
- }
- }
-
- /*=================================CheckHebrewDayValue==========================
- **Action: Check if the Hebrew day value is valid.
- **Returns: None.
- **Arguments: year Hebrew year value
- ** month Hebrew month value
- ** day Hebrew day value.
- **Exceptions: ArgumentOutOfRange_Range if the day value is not valid.
- **Note:
- ** Call CheckHebrewYearValue()/CheckHebrewMonthValue() before calling this to verify the year/month values are valid.
- ============================================================================*/
-
- private void CheckHebrewDayValue(int year, int month, int day, int era) {
- int daysInMonth = GetDaysInMonth(year, month, era);
- if (day < 1 || day > daysInMonth) {
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 1,
- daysInMonth));
- }
- }
-
- static internal void CheckEraRange(int era) {
- if (era != CurrentEra && era != HebrewEra) {
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
- }
- }
-
- static private void CheckTicksRange(long ticks) {
- if (ticks < calendarMinValue.Ticks || ticks > calendarMaxValue.Ticks) {
- throw new ArgumentOutOfRangeException(
- "time",
- // Print out the date in Gregorian using InvariantCulture since the DateTime is based on GreograinCalendar.
- String.Format(
- CultureInfo.InvariantCulture,
- Environment.GetResourceString("ArgumentOutOfRange_CalendarRange"),
- calendarMinValue,
- calendarMaxValue));
- }
- }
-
- static internal int GetResult(__DateBuffer result, int part) {
- switch (part) {
- case DatePartYear:
- return (result.year);
- case DatePartMonth:
- return (result.month);
- case DatePartDay:
- return (result.day);
- }
-
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_DateTimeParsing"));
- }
-
- /*=================================GetLunarMonthDay==========================
- **Action: Using the Hebrew table (HebrewTable) to get the Hebrew month/day value for Gregorian January 1st
- ** in a given Gregorian year.
- ** Greogrian January 1st falls usually in Tevet (4th month). Tevet has always 29 days.
- ** That's why, there no nead to specify the lunar month in the table. There are exceptions, and these
- ** are coded by giving numbers above 29 and below 1.
- ** Actual decoding is takenig place in the switch statement below.
- **Returns:
- ** The Hebrew year type. The value is from 1 to 6.
- ** normal years : 1 = 353 days 2 = 354 days 3 = 355 days.
- ** Leap years : 4 = 383 5 384 6 = 385 days.
- **Arguments:
- ** gregorianYear The year value in Gregorian calendar. The value should be between 1500 and 2239.
- ** lunarDate Object to take the result of the Hebrew year/month/day.
- **Exceptions:
- ============================================================================*/
-
- static internal int GetLunarMonthDay(int gregorianYear, __DateBuffer lunarDate) {
- //
- // Get the offset into the LunarMonthLen array and the lunar day
- // for January 1st.
- //
- int index = gregorianYear - FirstGregorianTableYear;
- if (index < 0 || index > TABLESIZE) {
- throw new ArgumentOutOfRangeException(nameof(gregorianYear));
- }
-
- index *= 2;
- lunarDate.day = HebrewTable[index];
-
- // Get the type of the year. The value is from 1 to 6
- int LunarYearType = HebrewTable[index + 1];
-
- //
- // Get the Lunar Month.
- //
- switch (lunarDate.day) {
- case ( 0 ) : // 1/1 is on Shvat 1
- lunarDate.month = 5;
- lunarDate.day = 1;
- break;
- case ( 30 ) : // 1/1 is on Kislev 30
- lunarDate.month = 3;
- break;
- case ( 31 ) : // 1/1 is on Shvat 2
- lunarDate.month = 5;
- lunarDate.day = 2;
- break;
- case ( 32 ) : // 1/1 is on Shvat 3
- lunarDate.month = 5;
- lunarDate.day = 3;
- break;
- case ( 33 ) : // 1/1 is on Kislev 29
- lunarDate.month = 3;
- lunarDate.day = 29;
- break;
- default : // 1/1 is on Tevet (This is the general case)
- lunarDate.month = 4;
- break;
- }
- return (LunarYearType);
- }
-
- // Returns a given date part of this DateTime. This method is used
- // to compute the year, day-of-year, month, or day part.
-
- internal virtual int GetDatePart(long ticks, int part) {
- // The Gregorian year, month, day value for ticks.
- int gregorianYear, gregorianMonth, gregorianDay;
- int hebrewYearType; // lunar year type
- long AbsoluteDate; // absolute date - absolute date 1/1/1600
-
- //
- // Make sure we have a valid Gregorian date that will fit into our
- // Hebrew conversion limits.
- //
- CheckTicksRange(ticks);
-
- DateTime time = new DateTime(ticks);
-
- //
- // Save the Gregorian date values.
- //
- gregorianYear = time.Year;
- gregorianMonth = time.Month;
- gregorianDay = time.Day;
-
- __DateBuffer lunarDate = new __DateBuffer(); // lunar month and day for Jan 1
-
- // From the table looking-up value of HebrewTable[index] (stored in lunarDate.day), we get the the
- // lunar month and lunar day where the Gregorian date 1/1 falls.
- lunarDate.year = gregorianYear + HebrewYearOf1AD;
- hebrewYearType = GetLunarMonthDay(gregorianYear, lunarDate);
-
- // This is the buffer used to store the result Hebrew date.
- __DateBuffer result = new __DateBuffer();
-
- //
- // Store the values for the start of the new year - 1/1.
- //
- result.year = lunarDate.year;
- result.month = lunarDate.month;
- result.day = lunarDate.day;
-
- //
- // Get the absolute date from 1/1/1600.
- //
- AbsoluteDate = GregorianCalendar.GetAbsoluteDate(gregorianYear, gregorianMonth, gregorianDay);
-
- //
- // If the requested date was 1/1, then we're done.
- //
- if ((gregorianMonth == 1) && (gregorianDay == 1)) {
- return (GetResult(result, part));
- }
-
- //
- // Calculate the number of days between 1/1 and the requested date.
- //
- long NumDays; // number of days since 1/1
- NumDays = AbsoluteDate - GregorianCalendar.GetAbsoluteDate(gregorianYear, 1, 1);
-
- //
- // If the requested date is within the current lunar month, then
- // we're done.
- //
- if ((NumDays + (long)lunarDate.day) <= (long)(LunarMonthLen[hebrewYearType, lunarDate.month])) {
- result.day += (int)NumDays;
- return (GetResult(result, part));
- }
-
- //
- // Adjust for the current partial month.
- //
- result.month++;
- result.day = 1;
-
- //
- // Adjust the Lunar Month and Year (if necessary) based on the number
- // of days between 1/1 and the requested date.
- //
- // Assumes Jan 1 can never translate to the last Lunar month, which
- // is true.
- //
- NumDays -= (long)(LunarMonthLen[hebrewYearType, lunarDate.month] - lunarDate.day);
- Debug.Assert(NumDays >= 1, "NumDays >= 1");
-
- // If NumDays is 1, then we are done. Otherwise, find the correct Hebrew month
- // and day.
- if (NumDays > 1) {
- //
- // See if we're on the correct Lunar month.
- //
- while (NumDays > (long)(LunarMonthLen[hebrewYearType, result.month])) {
- //
- // Adjust the number of days and move to the next month.
- //
- NumDays -= (long)(LunarMonthLen[hebrewYearType, result.month++]);
-
- //
- // See if we need to adjust the Year.
- // Must handle both 12 and 13 month years.
- //
- if ((result.month > 13) || (LunarMonthLen[hebrewYearType, result.month] == 0)) {
- //
- // Adjust the Year.
- //
- result.year++;
- hebrewYearType = HebrewTable[(gregorianYear + 1 - FirstGregorianTableYear) * 2 + 1];
-
- //
- // Adjust the Month.
- //
- result.month = 1;
- }
- }
- //
- // Found the right Lunar month.
- //
- result.day += (int)(NumDays - 1);
- }
- return (GetResult(result, part));
- }
-
- // Returns the DateTime resulting from adding the given number of
- // months to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year and month parts of the specified DateTime by
- // value months, and, if required, adjusting the day part of the
- // resulting date downwards to the last day of the resulting month in the
- // resulting year. The time-of-day part of the result is the same as the
- // time-of-day part of the specified DateTime.
- //
- // In more precise terms, considering the specified DateTime to be of the
- // form y / m / d + t, where y is the
- // year, m is the month, d is the day, and t is the
- // time-of-day, the result is y1 / m1 / d1 + t,
- // where y1 and m1 are computed by adding value months
- // to y and m, and d1 is the largest value less than
- // or equal to d that denotes a valid day in month m1 of year
- // y1.
- //
-
- public override DateTime AddMonths(DateTime time, int months) {
- try {
- int y = GetDatePart(time.Ticks, DatePartYear);
- int m = GetDatePart(time.Ticks, DatePartMonth);
- int d = GetDatePart(time.Ticks, DatePartDay);
-
-
- int monthsInYear;
- int i;
- if (months >= 0) {
- i = m + months;
- while (i > (monthsInYear = GetMonthsInYear(y, CurrentEra))) {
- y++;
- i -= monthsInYear;
- }
- } else {
- if ((i = m + months) <= 0) {
- months = -months;
- months -= m;
- y--;
-
- while (months > (monthsInYear = GetMonthsInYear(y, CurrentEra))) {
- y--;
- months -= monthsInYear;
- }
- monthsInYear = GetMonthsInYear(y, CurrentEra);
- i = monthsInYear - months;
- }
- }
-
- int days = GetDaysInMonth(y, i);
- if (d > days) {
- d = days;
- }
- return (new DateTime(ToDateTime(y, i, d, 0, 0, 0, 0).Ticks + (time.Ticks % TicksPerDay)));
- }
- // We expect ArgumentException and ArgumentOutOfRangeException (which is subclass of ArgumentException)
- // If exception is thrown in the calls above, we are out of the supported range of this calendar.
- catch (ArgumentException)
- {
- throw new ArgumentOutOfRangeException(
- nameof(months),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_AddValue")));
- }
- }
-
- // Returns the DateTime resulting from adding the given number of
- // years to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year part of the specified DateTime by value
- // years. If the month and day of the specified DateTime is 2/29, and if the
- // resulting year is not a leap year, the month and day of the resulting
- // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
- // parts of the result are the same as those of the specified DateTime.
- //
-
- public override DateTime AddYears(DateTime time, int years) {
- int y = GetDatePart(time.Ticks, DatePartYear);
- int m = GetDatePart(time.Ticks, DatePartMonth);
- int d = GetDatePart(time.Ticks, DatePartDay);
-
- y += years;
- CheckHebrewYearValue(y, Calendar.CurrentEra, nameof(years));
-
- int months = GetMonthsInYear(y, CurrentEra);
- if (m > months) {
- m = months;
- }
-
- int days = GetDaysInMonth(y, m);
- if (d > days) {
- d = days;
- }
-
- long ticks = ToDateTime(y, m, d, 0, 0, 0, 0).Ticks + (time.Ticks % TicksPerDay);
- Calendar.CheckAddResult(ticks, MinSupportedDateTime, MaxSupportedDateTime);
- return (new DateTime(ticks));
- }
-
- // Returns the day-of-month part of the specified DateTime. The returned
- // value is an integer between 1 and 31.
- //
-
- public override int GetDayOfMonth(DateTime time) {
- return (GetDatePart(time.Ticks, DatePartDay));
- }
-
- // Returns the day-of-week part of the specified DateTime. The returned value
- // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
- // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
- // Thursday, 5 indicates Friday, and 6 indicates Saturday.
- //
-
- public override DayOfWeek GetDayOfWeek(DateTime time) {
- // If we calculate back, the Hebrew day of week for Gregorian 0001/1/1 is Monday (1).
- // Therfore, the fomula is:
- return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
- }
-
- static internal int GetHebrewYearType(int year, int era) {
- CheckHebrewYearValue(year, era, nameof(year));
- // The HebrewTable is indexed by Gregorian year and starts from FirstGregorianYear.
- // So we need to convert year (Hebrew year value) to Gregorian Year below.
- return (HebrewTable[(year - HebrewYearOf1AD - FirstGregorianTableYear) * 2 + 1]);
- }
-
- // Returns the day-of-year part of the specified DateTime. The returned value
- // is an integer between 1 and 366.
- //
-
- public override int GetDayOfYear(DateTime time) {
- // Get Hebrew year value of the specified time.
- int year = GetYear(time);
- DateTime beginOfYearDate;
- if (year == 5343)
- {
- // Gregorian 1583/01/01 corresponds to Hebrew 5343/04/07 (MinSupportedDateTime)
- // To figure out the Gregorian date associated with Hebrew 5343/01/01, we need to
- // count the days from 5343/01/01 to 5343/04/07 and subtract that from Gregorian
- // 1583/01/01.
- // 1. Tishri (30 days)
- // 2. Heshvan (30 days since 5343 has 355 days)
- // 3. Kislev (30 days since 5343 has 355 days)
- // 96 days to get from 5343/01/01 to 5343/04/07
- // Gregorian 1583/01/01 - 96 days = 1582/9/27
-
- // the beginning of Hebrew year 5343 corresponds to Gregorian September 27, 1582.
- beginOfYearDate = new DateTime(1582, 9, 27);
- }
- else
- {
- // following line will fail when year is 5343 (first supported year)
- beginOfYearDate = ToDateTime(year, 1, 1, 0, 0, 0, 0, CurrentEra);
- }
- return ((int)((time.Ticks - beginOfYearDate.Ticks) / TicksPerDay) + 1);
- }
-
- // Returns the number of days in the month given by the year and
- // month arguments.
- //
-
- public override int GetDaysInMonth(int year, int month, int era) {
- CheckEraRange(era);
- int hebrewYearType = GetHebrewYearType(year, era);
- CheckHebrewMonthValue(year, month, era);
-
- Debug.Assert(hebrewYearType>= 1 && hebrewYearType <= 6,
- "hebrewYearType should be from 1 to 6, but now hebrewYearType = " + hebrewYearType + " for hebrew year " + year);
- int monthDays = LunarMonthLen[hebrewYearType, month];
- if (monthDays == 0) {
- throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
- }
- return (monthDays);
- }
-
- // Returns the number of days in the year given by the year argument for the current era.
- //
-
- public override int GetDaysInYear(int year, int era) {
- CheckEraRange(era);
- // normal years : 1 = 353 days 2 = 354 days 3 = 355 days.
- // Leap years : 4 = 383 5 384 6 = 385 days.
-
- // LunarYearType is from 1 to 6
- int LunarYearType = GetHebrewYearType(year, era);
- if (LunarYearType < 4) {
- // common year: LunarYearType = 1, 2, 3
- return (352 + LunarYearType);
- }
- return (382 + (LunarYearType - 3));
- }
-
- // Returns the era for the specified DateTime value.
-
- public override int GetEra(DateTime time) {
-
- return (HebrewEra);
- }
-
-
- public override int[] Eras {
- get {
- return (new int[] {HebrewEra});
- }
- }
-
- // Returns the month part of the specified DateTime. The returned value is an
- // integer between 1 and 12.
- //
-
- public override int GetMonth(DateTime time) {
- return (GetDatePart(time.Ticks, DatePartMonth));
- }
-
- // Returns the number of months in the specified year and era.
-
- public override int GetMonthsInYear(int year, int era) {
- return (IsLeapYear(year, era) ? 13 : 12);
- }
-
- // Returns the year part of the specified DateTime. The returned value is an
- // integer between 1 and 9999.
- //
-
- public override int GetYear(DateTime time) {
- return (GetDatePart(time.Ticks, DatePartYear));
- }
-
- // Checks whether a given day in the specified era is a leap day. This method returns true if
- // the date is a leap day, or false if not.
- //
-
- public override bool IsLeapDay(int year, int month, int day, int era) {
- if (IsLeapMonth(year, month, era)) {
- // Every day in a leap month is a leap day.
- CheckHebrewDayValue(year, month, day, era);
- return (true);
- } else if (IsLeapYear(year, Calendar.CurrentEra)) {
- // There is an additional day in the 6th month in the leap year (the extra day is the 30th day in the 6th month),
- // so we should return true for 6/30 if that's in a leap year.
- if (month == 6 && day == 30) {
- return (true);
- }
- }
- CheckHebrewDayValue(year, month, day, era);
- return (false);
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
-
- public override int GetLeapMonth(int year, int era)
- {
- // Year/era values are checked in IsLeapYear().
- if (IsLeapYear(year, era))
- {
- // The 7th month in a leap year is a leap month.
- return (7);
- }
- return (0);
- }
-
- // Checks whether a given month in the specified era is a leap month. This method returns true if
- // month is a leap month, or false if not.
- //
-
- public override bool IsLeapMonth(int year, int month, int era) {
- // Year/era values are checked in IsLeapYear().
- bool isLeapYear = IsLeapYear(year, era);
- CheckHebrewMonthValue(year, month, era);
- // The 7th month in a leap year is a leap month.
- if (isLeapYear) {
- if (month == 7) {
- return (true);
- }
- }
- return (false);
- }
-
- // Checks whether a given year in the specified era is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
-
- public override bool IsLeapYear(int year, int era) {
- CheckHebrewYearValue(year, era, nameof(year));
- return (((7 * (long)year + 1) % 19) < 7);
- }
-
- // (month1, day1) - (month2, day2)
- static int GetDayDifference(int lunarYearType, int month1, int day1, int month2, int day2) {
- if (month1 == month2) {
- return (day1 - day2);
- }
-
- // Make sure that (month1, day1) < (month2, day2)
- bool swap = (month1 > month2);
- if (swap) {
- // (month1, day1) < (month2, day2). Swap the values.
- // The result will be a negative number.
- int tempMonth, tempDay;
- tempMonth = month1; tempDay = day1;
- month1 = month2; day1 = day2;
- month2 = tempMonth; day2 = tempDay;
- }
-
- // Get the number of days from (month1,day1) to (month1, end of month1)
- int days = LunarMonthLen[lunarYearType, month1] - day1;
-
- // Move to next month.
- month1++;
-
- // Add up the days.
- while (month1 < month2) {
- days += LunarMonthLen[lunarYearType, month1++];
- }
- days += day2;
-
- return (swap ? days : -days);
- }
-
- /*=================================HebrewToGregorian==========================
- **Action: Convert Hebrew date to Gregorian date.
- **Returns:
- **Arguments:
- **Exceptions:
- ** The algorithm is like this:
- ** The hebrew year has an offset to the Gregorian year, so we can guess the Gregorian year for
- ** the specified Hebrew year. That is, GreogrianYear = HebrewYear - FirstHebrewYearOf1AD.
- **
- ** From the Gregorian year and HebrewTable, we can get the Hebrew month/day value
- ** of the Gregorian date January 1st. Let's call this month/day value [hebrewDateForJan1]
- **
- ** If the requested Hebrew month/day is less than [hebrewDateForJan1], we know the result
- ** Gregorian date falls in previous year. So we decrease the Gregorian year value, and
- ** retrieve the Hebrew month/day value of the Gregorian date january 1st again.
- **
- ** Now, we get the answer of the Gregorian year.
- **
- ** The next step is to get the number of days between the requested Hebrew month/day
- ** and [hebrewDateForJan1]. When we get that, we can create the DateTime by adding/subtracting
- ** the ticks value of the number of days.
- **
- ============================================================================*/
-
-
- static DateTime HebrewToGregorian(int hebrewYear, int hebrewMonth, int hebrewDay, int hour, int minute, int second, int millisecond) {
- // Get the rough Gregorian year for the specified hebrewYear.
- //
- int gregorianYear = hebrewYear - HebrewYearOf1AD;
-
- __DateBuffer hebrewDateOfJan1 = new __DateBuffer(); // year value is unused.
- int lunarYearType = GetLunarMonthDay(gregorianYear, hebrewDateOfJan1);
-
- if ((hebrewMonth == hebrewDateOfJan1.month) && (hebrewDay == hebrewDateOfJan1.day)) {
- return (new DateTime(gregorianYear, 1, 1, hour, minute, second, millisecond));
- }
-
- int days = GetDayDifference(lunarYearType, hebrewMonth, hebrewDay, hebrewDateOfJan1.month, hebrewDateOfJan1.day);
-
- DateTime gregorianNewYear = new DateTime(gregorianYear, 1, 1);
- return (new DateTime(gregorianNewYear.Ticks + days * TicksPerDay
- + TimeToTicks(hour, minute, second, millisecond)));
- }
-
- // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
- //
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) {
- CheckHebrewYearValue(year, era, nameof(year));
- CheckHebrewMonthValue(year, month, era);
- CheckHebrewDayValue(year, month, day, era);
- DateTime dt = HebrewToGregorian(year, month, day, hour, minute, second, millisecond);
- CheckTicksRange(dt.Ticks);
- return (dt);
- }
-
- private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 5790;
-
-
- public override int TwoDigitYearMax {
- get {
- if (twoDigitYearMax == -1) {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
- }
- return (twoDigitYearMax);
- }
-
- set {
- VerifyWritable();
- if (value == 99)
- {
- // Do nothing here. Year 99 is allowed so that TwoDitYearMax is disabled.
- }
- else
- {
- CheckHebrewYearValue(value, HebrewEra, nameof(value));
- }
- twoDigitYearMax = value;
- }
- }
-
-
- public override int ToFourDigitYear(int year) {
- if (year < 0) {
- throw new ArgumentOutOfRangeException(nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- Contract.EndContractBlock();
-
- if (year < 100) {
- return (base.ToFourDigitYear(year));
- }
-
- if (year > MaxHebrewYear || year < MinHebrewYear) {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- MinHebrewYear,
- MaxHebrewYear));
- }
- return (year);
- }
-
- internal class __DateBuffer {
- internal int year;
- internal int month;
- internal int day;
- }
-
- }
-
-}
-
diff --git a/src/mscorlib/src/System/Globalization/HebrewNumber.cs b/src/mscorlib/src/System/Globalization/HebrewNumber.cs
deleted file mode 100644
index 5517cb14ea..0000000000
--- a/src/mscorlib/src/System/Globalization/HebrewNumber.cs
+++ /dev/null
@@ -1,403 +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.
-
-
-namespace System.Globalization {
- using System;
- using System.Text;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Used in HebrewNumber.ParseByChar to maintain the context information (
- // the state in the state machine and current Hebrew number values, etc.)
- // when parsing Hebrew number character by character.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal struct HebrewNumberParsingContext {
- // The current state of the state machine for parsing Hebrew numbers.
- internal HebrewNumber.HS state;
- // The current value of the Hebrew number.
- // The final value is determined when state is FoundEndOfHebrewNumber.
- internal int result;
-
- public HebrewNumberParsingContext(int result) {
- // Set the start state of the state machine for parsing Hebrew numbers.
- state = HebrewNumber.HS.Start;
- this.result = result;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Please see ParseByChar() for comments about different states defined here.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal enum HebrewNumberParsingState {
- InvalidHebrewNumber,
- NotHebrewDigit,
- FoundEndOfHebrewNumber,
- ContinueParsing,
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // class HebrewNumber
- //
- // Provides static methods for formatting integer values into
- // Hebrew text and parsing Hebrew number text.
- //
- // Limitations:
- // Parse can only handles value 1 ~ 999.
- // ToString() can only handles 1 ~ 999. If value is greater than 5000,
- // 5000 will be subtracted from the value.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal class HebrewNumber {
-
- // This class contains only static methods. Add a private ctor so that
- // compiler won't generate a default one for us.
- private HebrewNumber() {
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // ToString
- //
- // Converts the given number to Hebrew letters according to the numeric
- // value of each Hebrew letter. Basically, this converts the lunar year
- // and the lunar month to letters.
- //
- // The character of a year is described by three letters of the Hebrew
- // alphabet, the first and third giving, respectively, the days of the
- // weeks on which the New Year occurs and Passover begins, while the
- // second is the initial of the Hebrew word for defective, normal, or
- // complete.
- //
- // Defective Year : Both Heshvan and Kislev are defective (353 or 383 days)
- // Normal Year : Heshvan is defective, Kislev is full (354 or 384 days)
- // Complete Year : Both Heshvan and Kislev are full (355 or 385 days)
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal static String ToString(int Number) {
- char cTens = '\x0';
- char cUnits; // tens and units chars
- int Hundreds, Tens; // hundreds and tens values
- StringBuilder szHebrew = new StringBuilder();
-
-
- //
- // Adjust the number if greater than 5000.
- //
- if (Number > 5000) {
- Number -= 5000;
- }
-
- Debug.Assert(Number > 0 && Number <= 999, "Number is out of range.");;
-
- //
- // Get the Hundreds.
- //
- Hundreds = Number / 100;
-
- if (Hundreds > 0) {
- Number -= Hundreds * 100;
- // \x05e7 = 100
- // \x05e8 = 200
- // \x05e9 = 300
- // \x05ea = 400
- // If the number is greater than 400, use the multiples of 400.
- for (int i = 0; i < (Hundreds / 4) ; i++) {
- szHebrew.Append('\x05ea');
- }
-
- int remains = Hundreds % 4;
- if (remains > 0) {
- szHebrew.Append((char)((int)'\x05e6' + remains));
- }
- }
-
- //
- // Get the Tens.
- //
- Tens = Number / 10;
- Number %= 10;
-
- switch (Tens) {
- case ( 0 ) :
- cTens = '\x0';
- break;
- case ( 1 ) :
- cTens = '\x05d9'; // Hebrew Letter Yod
- break;
- case ( 2 ) :
- cTens = '\x05db'; // Hebrew Letter Kaf
- break;
- case ( 3 ) :
- cTens = '\x05dc'; // Hebrew Letter Lamed
- break;
- case ( 4 ) :
- cTens = '\x05de'; // Hebrew Letter Mem
- break;
- case ( 5 ) :
- cTens = '\x05e0'; // Hebrew Letter Nun
- break;
- case ( 6 ) :
- cTens = '\x05e1'; // Hebrew Letter Samekh
- break;
- case ( 7 ) :
- cTens = '\x05e2'; // Hebrew Letter Ayin
- break;
- case ( 8 ) :
- cTens = '\x05e4'; // Hebrew Letter Pe
- break;
- case ( 9 ) :
- cTens = '\x05e6'; // Hebrew Letter Tsadi
- break;
- }
-
- //
- // Get the Units.
- //
- cUnits = (char)(Number > 0 ? ((int)'\x05d0' + Number - 1) : 0);
-
- if ((cUnits == '\x05d4') && // Hebrew Letter He (5)
- (cTens == '\x05d9')) { // Hebrew Letter Yod (10)
- cUnits = '\x05d5'; // Hebrew Letter Vav (6)
- cTens = '\x05d8'; // Hebrew Letter Tet (9)
- }
-
- if ((cUnits == '\x05d5') && // Hebrew Letter Vav (6)
- (cTens == '\x05d9')) { // Hebrew Letter Yod (10)
- cUnits = '\x05d6'; // Hebrew Letter Zayin (7)
- cTens = '\x05d8'; // Hebrew Letter Tet (9)
- }
-
- //
- // Copy the appropriate info to the given buffer.
- //
-
- if (cTens != '\x0') {
- szHebrew.Append(cTens);
- }
-
- if (cUnits != '\x0') {
- szHebrew.Append(cUnits);
- }
-
- if (szHebrew.Length > 1) {
- szHebrew.Insert(szHebrew.Length - 1, '"');
- } else {
- szHebrew.Append('\'');
- }
-
- //
- // Return success.
- //
- return (szHebrew.ToString());
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Token used to tokenize a Hebrew word into tokens so that we can use in the
- // state machine.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- enum HebrewToken {
- Invalid = -1,
- Digit400 = 0,
- Digit200_300 = 1,
- Digit100 = 2,
- Digit10 = 3, // 10 ~ 90
- Digit1 = 4, // 1, 2, 3, 4, 5, 8,
- Digit6_7 = 5,
- Digit7 = 6,
- Digit9 = 7,
- SingleQuote = 8,
- DoubleQuote = 9,
- };
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // This class is used to map a token into its Hebrew digit value.
- //
- ////////////////////////////////////////////////////////////////////////////
-
- class HebrewValue {
- internal HebrewToken token;
- internal int value;
- internal HebrewValue(HebrewToken token, int value) {
- this.token = token;
- this.value = value;
- }
- }
-
- //
- // Map a Hebrew character from U+05D0 ~ U+05EA to its digit value.
- // The value is -1 if the Hebrew character does not have a associated value.
- //
- static HebrewValue[] HebrewValues = {
- new HebrewValue(HebrewToken.Digit1, 1) , // '\x05d0
- new HebrewValue(HebrewToken.Digit1, 2) , // '\x05d1
- new HebrewValue(HebrewToken.Digit1, 3) , // '\x05d2
- new HebrewValue(HebrewToken.Digit1, 4) , // '\x05d3
- new HebrewValue(HebrewToken.Digit1, 5) , // '\x05d4
- new HebrewValue(HebrewToken.Digit6_7,6) , // '\x05d5
- new HebrewValue(HebrewToken.Digit6_7,7) , // '\x05d6
- new HebrewValue(HebrewToken.Digit1, 8) , // '\x05d7
- new HebrewValue(HebrewToken.Digit9, 9) , // '\x05d8
- new HebrewValue(HebrewToken.Digit10, 10) , // '\x05d9; // Hebrew Letter Yod
- new HebrewValue(HebrewToken.Invalid, -1) , // '\x05da;
- new HebrewValue(HebrewToken.Digit10, 20) , // '\x05db; // Hebrew Letter Kaf
- new HebrewValue(HebrewToken.Digit10, 30) , // '\x05dc; // Hebrew Letter Lamed
- new HebrewValue(HebrewToken.Invalid, -1) , // '\x05dd;
- new HebrewValue(HebrewToken.Digit10, 40) , // '\x05de; // Hebrew Letter Mem
- new HebrewValue(HebrewToken.Invalid, -1) , // '\x05df;
- new HebrewValue(HebrewToken.Digit10, 50) , // '\x05e0; // Hebrew Letter Nun
- new HebrewValue(HebrewToken.Digit10, 60) , // '\x05e1; // Hebrew Letter Samekh
- new HebrewValue(HebrewToken.Digit10, 70) , // '\x05e2; // Hebrew Letter Ayin
- new HebrewValue(HebrewToken.Invalid, -1) , // '\x05e3;
- new HebrewValue(HebrewToken.Digit10, 80) , // '\x05e4; // Hebrew Letter Pe
- new HebrewValue(HebrewToken.Invalid, -1) , // '\x05e5;
- new HebrewValue(HebrewToken.Digit10, 90) , // '\x05e6; // Hebrew Letter Tsadi
- new HebrewValue(HebrewToken.Digit100, 100) , // '\x05e7;
- new HebrewValue(HebrewToken.Digit200_300, 200) , // '\x05e8;
- new HebrewValue(HebrewToken.Digit200_300, 300) , // '\x05e9;
- new HebrewValue(HebrewToken.Digit400, 400) , // '\x05ea;
- };
-
- const int minHebrewNumberCh = 0x05d0;
- static char maxHebrewNumberCh = (char)(minHebrewNumberCh + HebrewValues.Length - 1);
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Hebrew number parsing State
- // The current state and the next token will lead to the next state in the state machine.
- // DQ = Double Quote
- //
- ////////////////////////////////////////////////////////////////////////////
-
- internal enum HS {
- _err = -1, // an error state
- Start = 0,
- S400 = 1, // a Hebrew digit 400
- S400_400 = 2, // Two Hebrew digit 400
- S400_X00 = 3, // Two Hebrew digit 400 and followed by 100
- S400_X0 = 4, // Hebrew digit 400 and followed by 10 ~ 90
- X00_DQ = 5, // A hundred number and followed by a double quote.
- S400_X00_X0 = 6,
- X0_DQ = 7, // A two-digit number and followed by a double quote.
- X = 8, // A single digit Hebrew number.
- X0 = 9, // A two-digit Hebrew number
- X00 = 10, // A three-digit Hebrew number
- S400_DQ = 11, // A Hebrew digit 400 and followed by a double quote.
- S400_400_DQ = 12,
- S400_400_100 = 13,
- S9 = 14, // Hebrew digit 9
- X00_S9 = 15, // A hundered number and followed by a digit 9
- S9_DQ = 16, // Hebrew digit 9 and followed by a double quote
- END = 100, // A terminial state is reached.
- }
-
- //
- // The state machine for Hebrew number pasing.
- //
- readonly static HS[][] NumberPasingState = {
- // 400 300/200 100 90~10 8~1 6, 7, 9, ' "
- /* 0 */ new HS[] {HS.S400, HS.X00, HS.X00, HS.X0, HS.X, HS.X, HS.X, HS.S9, HS._err, HS._err},
- /* 1: S400 */ new HS[] {HS.S400_400, HS.S400_X00, HS.S400_X00, HS.S400_X0, HS._err, HS._err, HS._err, HS.X00_S9 ,HS.END, HS.S400_DQ},
- /* 2: S400_400 */ new HS[] {HS._err, HS._err, HS.S400_400_100,HS.S400_X0, HS._err, HS._err, HS._err, HS.X00_S9 ,HS._err, HS.S400_400_DQ},
- /* 3: S400_X00 */ new HS[] {HS._err, HS._err, HS._err, HS.S400_X00_X0, HS._err, HS._err, HS._err, HS.X00_S9 ,HS._err, HS.X00_DQ},
- /* 4: S400_X0 */ new HS[] {HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.X0_DQ},
- /* 5: X00_DQ */ new HS[] {HS._err, HS._err, HS._err, HS.END, HS.END, HS.END, HS.END, HS.END, HS._err, HS._err},
- /* 6: S400_X00_X0 */new HS[] {HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.X0_DQ},
- /* 7: X0_DQ */ new HS[] {HS._err, HS._err, HS._err, HS._err, HS.END, HS.END, HS.END, HS.END, HS._err, HS._err},
- /* 8: X */ new HS[] {HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.END, HS._err},
- /* 9: X0 */ new HS[] {HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.END, HS.X0_DQ},
- /* 10: X00 */ new HS[] {HS._err, HS._err, HS._err, HS.S400_X0, HS._err, HS._err, HS._err, HS.X00_S9, HS.END, HS.X00_DQ},
- /* 11: S400_DQ */ new HS[] {HS.END, HS.END, HS.END, HS.END, HS.END, HS.END, HS.END, HS.END, HS._err, HS._err},
- /* 12: S400_400_DQ*/new HS[] {HS._err, HS._err, HS.END, HS.END, HS.END, HS.END, HS.END, HS.END, HS._err, HS._err},
- /* 13: S400_400_100*/new HS[]{HS._err, HS._err, HS._err, HS.S400_X00_X0, HS._err, HS._err, HS._err, HS.X00_S9, HS._err, HS.X00_DQ},
- /* 14: S9 */ new HS[] {HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err,HS.END, HS.S9_DQ},
- /* 15: X00_S9 */ new HS[] {HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS._err, HS.S9_DQ},
- /* 16: S9_DQ */ new HS[] {HS._err, HS._err, HS._err, HS._err, HS._err, HS.END, HS.END, HS._err, HS._err, HS._err},
- };
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Actions:
- // Parse the Hebrew number by passing one character at a time.
- // The state between characters are maintained at HebrewNumberPasingContext.
- // Returns:
- // Return a enum of HebrewNumberParsingState.
- // NotHebrewDigit: The specified ch is not a valid Hebrew digit.
- // InvalidHebrewNumber: After parsing the specified ch, it will lead into
- // an invalid Hebrew number text.
- // FoundEndOfHebrewNumber: A terminal state is reached. This means that
- // we find a valid Hebrew number text after the specified ch is parsed.
- // ContinueParsing: The specified ch is a valid Hebrew digit, and
- // it will lead into a valid state in the state machine, we should
- // continue to parse incoming characters.
- //
- ////////////////////////////////////////////////////////////////////////
-
- internal static HebrewNumberParsingState ParseByChar(char ch, ref HebrewNumberParsingContext context) {
- HebrewToken token;
- if (ch == '\'') {
- token = HebrewToken.SingleQuote;
- } else if (ch == '\"') {
- token = HebrewToken.DoubleQuote;
- } else {
- int index = (int)ch - minHebrewNumberCh;
- if (index >= 0 && index < HebrewValues.Length ) {
- token = HebrewValues[index].token;
- if (token == HebrewToken.Invalid) {
- return (HebrewNumberParsingState.NotHebrewDigit);
- }
- context.result += HebrewValues[index].value;
- } else {
- // Not in valid Hebrew digit range.
- return (HebrewNumberParsingState.NotHebrewDigit);
- }
- }
- context.state = NumberPasingState[(int)context.state][(int)token];
- if (context.state == HS._err) {
- // Invalid Hebrew state. This indicates an incorrect Hebrew number.
- return (HebrewNumberParsingState.InvalidHebrewNumber);
- }
- if (context.state == HS.END) {
- // Reach a terminal state.
- return (HebrewNumberParsingState.FoundEndOfHebrewNumber);
- }
- // We should continue to parse.
- return (HebrewNumberParsingState.ContinueParsing);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Actions:
- // Check if the ch is a valid Hebrew number digit.
- // This function will return true if the specified char is a legal Hebrew
- // digit character, single quote, or double quote.
- // Returns:
- // true if the specified character is a valid Hebrew number character.
- //
- ////////////////////////////////////////////////////////////////////////
-
- internal static bool IsDigit(char ch) {
- if (ch >= minHebrewNumberCh && ch <= maxHebrewNumberCh) {
- return (HebrewValues[ch - minHebrewNumberCh].value >= 0);
- }
- return (ch == '\'' || ch == '\"');
- }
-
- }
-}
diff --git a/src/mscorlib/corefx/System/Globalization/HijriCalendar.Unix.cs b/src/mscorlib/src/System/Globalization/HijriCalendar.Unix.cs
index a6e8f73d3e..a6e8f73d3e 100644
--- a/src/mscorlib/corefx/System/Globalization/HijriCalendar.Unix.cs
+++ b/src/mscorlib/src/System/Globalization/HijriCalendar.Unix.cs
diff --git a/src/mscorlib/src/System/Globalization/HijriCalendar.Win32.cs b/src/mscorlib/src/System/Globalization/HijriCalendar.Win32.cs
new file mode 100644
index 0000000000..4ba95c8fa8
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/HijriCalendar.Win32.cs
@@ -0,0 +1,83 @@
+// 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 Microsoft.Win32;
+
+namespace System.Globalization
+{
+ public partial class HijriCalendar : Calendar
+ {
+ private int GetHijriDateAdjustment()
+ {
+ if (_hijriAdvance == Int32.MinValue)
+ {
+ // Never been set before. Use the system value from registry.
+ _hijriAdvance = GetAdvanceHijriDate();
+ }
+ return (_hijriAdvance);
+ }
+
+ private const String InternationalRegKey = "Control Panel\\International";
+ private const String HijriAdvanceRegKeyEntry = "AddHijriDate";
+
+ /*=================================GetAdvanceHijriDate==========================
+ **Action: Gets the AddHijriDate value from the registry.
+ **Returns:
+ **Arguments: None.
+ **Exceptions:
+ **Note:
+ ** The HijriCalendar has a user-overidable calculation. That is, use can set a value from the control
+ ** panel, so that the calculation of the Hijri Calendar can move ahead or backwards from -2 to +2 days.
+ **
+ ** The valid string values in the registry are:
+ ** "AddHijriDate-2" => Add -2 days to the current calculated Hijri date.
+ ** "AddHijriDate" => Add -1 day to the current calculated Hijri date.
+ ** "" => Add 0 day to the current calculated Hijri date.
+ ** "AddHijriDate+1" => Add +1 days to the current calculated Hijri date.
+ ** "AddHijriDate+2" => Add +2 days to the current calculated Hijri date.
+ ============================================================================*/
+ private static int GetAdvanceHijriDate()
+ {
+ int hijriAdvance = 0;
+ Microsoft.Win32.RegistryKey key = null;
+
+ using (key = Registry.CurrentUser.OpenSubKey(InternationalRegKey, writable: false))
+ {
+ if (key == null)
+ return 0;
+
+ Object value = key.GetValue(HijriAdvanceRegKeyEntry);
+ if (value == null)
+ {
+ return (0);
+ }
+ String str = value.ToString();
+ if (String.Compare(str, 0, HijriAdvanceRegKeyEntry, 0, HijriAdvanceRegKeyEntry.Length, StringComparison.OrdinalIgnoreCase) == 0)
+ {
+ if (str.Length == HijriAdvanceRegKeyEntry.Length)
+ hijriAdvance = -1;
+ else
+ {
+ str = str.Substring(HijriAdvanceRegKeyEntry.Length);
+ try
+ {
+ int advance = Int32.Parse(str.ToString(), CultureInfo.InvariantCulture);
+ if ((advance >= MinAdvancedHijri) && (advance <= MaxAdvancedHijri))
+ {
+ hijriAdvance = advance;
+ }
+ }
+ // If we got garbage from registry just ignore it.
+ // hijriAdvance = 0 because of declaraction assignment up above.
+ catch (ArgumentException) { }
+ catch (FormatException) { }
+ catch (OverflowException) { }
+ }
+ }
+ }
+
+ return (hijriAdvance);
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Globalization/HijriCalendar.WinRT.cs b/src/mscorlib/src/System/Globalization/HijriCalendar.WinRT.cs
index fb91c27ef6..fb91c27ef6 100644
--- a/src/mscorlib/corefx/System/Globalization/HijriCalendar.WinRT.cs
+++ b/src/mscorlib/src/System/Globalization/HijriCalendar.WinRT.cs
diff --git a/src/mscorlib/src/System/Globalization/HijriCalendar.cs b/src/mscorlib/src/System/Globalization/HijriCalendar.cs
deleted file mode 100644
index 061d380285..0000000000
--- a/src/mscorlib/src/System/Globalization/HijriCalendar.cs
+++ /dev/null
@@ -1,716 +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.
-
-namespace System.Globalization {
-
- using System;
- using System.Runtime.Versioning;
- using System.Diagnostics.Contracts;
-#if !FEATURE_WIN32_REGISTRY
- using System.Text;
- using Microsoft.Win32;
-#endif // FEATURE_WIN32_REGISTRY
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Rules for the Hijri calendar:
- // - The Hijri calendar is a strictly Lunar calendar.
- // - Days begin at sunset.
- // - Islamic Year 1 (Muharram 1, 1 A.H.) is equivalent to absolute date
- // 227015 (Friday, July 16, 622 C.E. - Julian).
- // - Leap Years occur in the 2, 5, 7, 10, 13, 16, 18, 21, 24, 26, & 29th
- // years of a 30-year cycle. Year = leap iff ((11y+14) mod 30 < 11).
- // - There are 12 months which contain alternately 30 and 29 days.
- // - The 12th month, Dhu al-Hijjah, contains 30 days instead of 29 days
- // in a leap year.
- // - Common years have 354 days. Leap years have 355 days.
- // - There are 10,631 days in a 30-year cycle.
- // - The Islamic months are:
- // 1. Muharram (30 days) 7. Rajab (30 days)
- // 2. Safar (29 days) 8. Sha'ban (29 days)
- // 3. Rabi I (30 days) 9. Ramadan (30 days)
- // 4. Rabi II (29 days) 10. Shawwal (29 days)
- // 5. Jumada I (30 days) 11. Dhu al-Qada (30 days)
- // 6. Jumada II (29 days) 12. Dhu al-Hijjah (29 days) {30}
- //
- // NOTENOTE
- // The calculation of the HijriCalendar is based on the absolute date. And the
- // absolute date means the number of days from January 1st, 1 A.D.
- // Therefore, we do not support the days before the January 1st, 1 A.D.
- //
- ////////////////////////////////////////////////////////////////////////////
- /*
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 0622/07/18 9999/12/31
- ** Hijri 0001/01/01 9666/04/03
- */
-
- [Serializable]
- public class HijriCalendar : Calendar {
-
-
- public static readonly int HijriEra = 1;
-
- internal const int DatePartYear = 0;
- internal const int DatePartDayOfYear = 1;
- internal const int DatePartMonth = 2;
- internal const int DatePartDay = 3;
-
- internal const int MinAdvancedHijri = -2;
- internal const int MaxAdvancedHijri = 2;
-
- internal static readonly int[] HijriMonthDays = {0,30,59,89,118,148,177,207,236,266,295,325,355};
-
- //internal static Calendar m_defaultInstance;
-
-#if FEATURE_WIN32_REGISTRY
- private const String InternationalRegKey = "Control Panel\\International";
- private const String HijriAdvanceRegKeyEntry = "AddHijriDate";
-#endif
-
- private int m_HijriAdvance = Int32.MinValue;
-
- // DateTime.MaxValue = Hijri calendar (year:9666, month: 4, day: 3).
- internal const int MaxCalendarYear = 9666;
- internal const int MaxCalendarMonth = 4;
- internal const int MaxCalendarDay = 3;
- // Hijri calendar (year: 1, month: 1, day:1 ) = Gregorian (year: 622, month: 7, day: 18)
- // This is the minimal Gregorian date that we support in the HijriCalendar.
- internal static readonly DateTime calendarMinValue = new DateTime(622, 7, 18);
- internal static readonly DateTime calendarMaxValue = DateTime.MaxValue;
-
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (calendarMinValue);
- }
- }
-
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (calendarMaxValue);
- }
- }
-
- // Return the type of the Hijri calendar.
- //
-
- public override CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.LunarCalendar;
- }
- }
-
- /*=================================GetDefaultInstance==========================
- **Action: Internal method to provide a default intance of HijriCalendar. Used by NLS+ implementation
- ** and other calendars.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
- /*
- internal static Calendar GetDefaultInstance() {
- if (m_defaultInstance == null) {
- m_defaultInstance = new HijriCalendar();
- }
- return (m_defaultInstance);
- }
- */
-
- // Construct an instance of Hijri calendar.
-
- public HijriCalendar() {
- }
-
- internal override int ID {
- get {
- return (CAL_HIJRI);
- }
- }
-
- protected override int DaysInYearBeforeMinSupportedYear
- {
- get
- {
- // the year before the 1st year of the cycle would have been the 30th year
- // of the previous cycle which is not a leap year. Common years have 354 days.
- return 354;
- }
- }
-
-
-
- /*=================================GetAbsoluteDateHijri==========================
- **Action: Gets the Absolute date for the given Hijri date. The absolute date means
- ** the number of days from January 1st, 1 A.D.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
-
- long GetAbsoluteDateHijri(int y, int m, int d) {
- return (long)(DaysUpToHijriYear(y) + HijriMonthDays[m-1] + d - 1 - HijriAdjustment);
- }
-
- /*=================================DaysUpToHijriYear==========================
- **Action: Gets the total number of days (absolute date) up to the given Hijri Year.
- ** The absolute date means the number of days from January 1st, 1 A.D.
- **Returns: Gets the total number of days (absolute date) up to the given Hijri Year.
- **Arguments: HijriYear year value in Hijri calendar.
- **Exceptions: None
- **Notes:
- ============================================================================*/
-
- long DaysUpToHijriYear(int HijriYear) {
- long NumDays; // number of absolute days
- int NumYear30; // number of years up to current 30 year cycle
- int NumYearsLeft; // number of years into 30 year cycle
-
- //
- // Compute the number of years up to the current 30 year cycle.
- //
- NumYear30 = ((HijriYear - 1) / 30) * 30;
-
- //
- // Compute the number of years left. This is the number of years
- // into the 30 year cycle for the given year.
- //
- NumYearsLeft = HijriYear - NumYear30 - 1;
-
- //
- // Compute the number of absolute days up to the given year.
- //
- NumDays = ((NumYear30 * 10631L) / 30L) + 227013L;
- while (NumYearsLeft > 0) {
- // Common year is 354 days, and leap year is 355 days.
- NumDays += 354 + (IsLeapYear(NumYearsLeft, CurrentEra) ? 1: 0);
- NumYearsLeft--;
- }
-
- //
- // Return the number of absolute days.
- //
- return (NumDays);
- }
-
-
- public int HijriAdjustment {
- get {
- if (m_HijriAdvance == Int32.MinValue) {
- // Never been set before. Use the system value from registry.
- m_HijriAdvance = GetAdvanceHijriDate();
- }
- return (m_HijriAdvance);
- }
-
- set {
- // NOTE: Check the value of Min/MaxAdavncedHijri with Arabic speakers to see if the assumption is good.
- if (value < MinAdvancedHijri || value > MaxAdvancedHijri) {
- throw new ArgumentOutOfRangeException(
- nameof(HijriAdjustment),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper"),
- MinAdvancedHijri,
- MaxAdvancedHijri));
- }
- Contract.EndContractBlock();
- VerifyWritable();
-
- m_HijriAdvance = value;
- }
- }
-
- /*=================================GetAdvanceHijriDate==========================
- **Action: Gets the AddHijriDate value from the registry.
- **Returns:
- **Arguments: None.
- **Exceptions:
- **Note:
- ** The HijriCalendar has a user-overidable calculation. That is, use can set a value from the control
- ** panel, so that the calculation of the Hijri Calendar can move ahead or backwards from -2 to +2 days.
- **
- ** The valid string values in the registry are:
- ** "AddHijriDate-2" => Add -2 days to the current calculated Hijri date.
- ** "AddHijriDate" => Add -1 day to the current calculated Hijri date.
- ** "" => Add 0 day to the current calculated Hijri date.
- ** "AddHijriDate+1" => Add +1 days to the current calculated Hijri date.
- ** "AddHijriDate+2" => Add +2 days to the current calculated Hijri date.
- ============================================================================*/
- static int GetAdvanceHijriDate() {
-#if FEATURE_WIN32_REGISTRY
-
- int hijriAdvance = 0;
- Microsoft.Win32.RegistryKey key = null;
-
- try {
- // Open in read-only mode.
- // Use InternalOpenSubKey so that we avoid the security check.
- key = Microsoft.Win32.Registry.CurrentUser.InternalOpenSubKey(InternationalRegKey, false);
- }
- //If this fails for any reason, we'll just return 0.
- catch (ObjectDisposedException) { return 0; }
- catch (ArgumentException) { return 0; }
-
- if (key != null) {
- try {
- Object value = key.InternalGetValue(HijriAdvanceRegKeyEntry, null, false, false);
- if (value == null) {
- return (0);
- }
- String str = value.ToString();
- if (String.Compare(str, 0, HijriAdvanceRegKeyEntry, 0, HijriAdvanceRegKeyEntry.Length, StringComparison.OrdinalIgnoreCase) == 0) {
- if (str.Length == HijriAdvanceRegKeyEntry.Length)
- hijriAdvance = -1;
- else {
- str = str.Substring(HijriAdvanceRegKeyEntry.Length);
- try {
- int advance = Int32.Parse(str.ToString(), CultureInfo.InvariantCulture);
- if ((advance >= MinAdvancedHijri) && (advance <= MaxAdvancedHijri)) {
- hijriAdvance = advance;
- }
- }
- // If we got garbage from registry just ignore it.
- // hijriAdvance = 0 because of declaraction assignment up above.
- catch (ArgumentException) { }
- catch (FormatException) { }
- catch (OverflowException) { }
- }
- }
- }
- finally {
- key.Close();
- }
-
- }
- return (hijriAdvance);
-
-#else //FEATURE_WIN32_REGISTRY
- return 0;
-#endif // FEATURE_WIN32_REGISTRY
- }
-
- static internal void CheckTicksRange(long ticks) {
- if (ticks < calendarMinValue.Ticks || ticks > calendarMaxValue.Ticks) {
- throw new ArgumentOutOfRangeException(
- "time",
- String.Format(
- CultureInfo.InvariantCulture,
- Environment.GetResourceString("ArgumentOutOfRange_CalendarRange"),
- calendarMinValue,
- calendarMaxValue));
- }
- }
-
- static internal void CheckEraRange(int era) {
- if (era != CurrentEra && era != HijriEra) {
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
- }
- }
-
- static internal void CheckYearRange(int year, int era) {
- CheckEraRange(era);
- if (year < 1 || year > MaxCalendarYear) {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 1,
- MaxCalendarYear));
- }
- }
-
- static internal void CheckYearMonthRange(int year, int month, int era) {
- CheckYearRange(year, era);
- if (year == MaxCalendarYear) {
- if (month > MaxCalendarMonth) {
- throw new ArgumentOutOfRangeException(
- nameof(month),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 1,
- MaxCalendarMonth));
- }
- }
-
- if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
- }
- }
-
- /*=================================GetDatePart==========================
- **Action: Returns a given date part of this <i>DateTime</i>. This method is used
- ** to compute the year, day-of-year, month, or day part.
- **Returns:
- **Arguments:
- **Exceptions: ArgumentException if part is incorrect.
- **Notes:
- ** First, we get the absolute date (the number of days from January 1st, 1 A.C) for the given ticks.
- ** Use the formula (((AbsoluteDate - 227013) * 30) / 10631) + 1, we can a rough value for the Hijri year.
- ** In order to get the exact Hijri year, we compare the exact absolute date for HijriYear and (HijriYear + 1).
- ** From here, we can get the correct Hijri year.
- ============================================================================*/
-
- internal virtual int GetDatePart(long ticks, int part) {
- int HijriYear; // Hijri year
- int HijriMonth; // Hijri month
- int HijriDay; // Hijri day
- long NumDays; // The calculation buffer in number of days.
-
- CheckTicksRange(ticks);
-
- //
- // Get the absolute date. The absolute date is the number of days from January 1st, 1 A.D.
- // 1/1/0001 is absolute date 1.
- //
- NumDays = ticks / GregorianCalendar.TicksPerDay + 1;
-
- //
- // See how much we need to backup or advance
- //
- NumDays += HijriAdjustment;
-
- //
- // Calculate the appromixate Hijri Year from this magic formula.
- //
- HijriYear = (int)(((NumDays - 227013) * 30) / 10631) + 1;
-
- long daysToHijriYear = DaysUpToHijriYear(HijriYear); // The absoulte date for HijriYear
- long daysOfHijriYear = GetDaysInYear(HijriYear, CurrentEra); // The number of days for (HijriYear+1) year.
-
- if (NumDays < daysToHijriYear) {
- daysToHijriYear -= daysOfHijriYear;
- HijriYear--;
- } else if (NumDays == daysToHijriYear) {
- HijriYear--;
- daysToHijriYear -= GetDaysInYear(HijriYear, CurrentEra);
- } else {
- if (NumDays > daysToHijriYear + daysOfHijriYear) {
- daysToHijriYear += daysOfHijriYear;
- HijriYear++;
- }
- }
- if (part == DatePartYear) {
- return (HijriYear);
- }
-
- //
- // Calculate the Hijri Month.
- //
-
- HijriMonth = 1;
- NumDays -= daysToHijriYear;
-
- if (part == DatePartDayOfYear) {
- return ((int)NumDays);
- }
-
- while ((HijriMonth <= 12) && (NumDays > HijriMonthDays[HijriMonth - 1])) {
- HijriMonth++;
- }
- HijriMonth--;
-
- if (part == DatePartMonth) {
- return (HijriMonth);
- }
-
- //
- // Calculate the Hijri Day.
- //
- HijriDay = (int)(NumDays - HijriMonthDays[HijriMonth - 1]);
-
- if (part == DatePartDay) {
- return (HijriDay);
- }
- // Incorrect part value.
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_DateTimeParsing"));
- }
-
- // Returns the DateTime resulting from adding the given number of
- // months to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year and month parts of the specified DateTime by
- // value months, and, if required, adjusting the day part of the
- // resulting date downwards to the last day of the resulting month in the
- // resulting year. The time-of-day part of the result is the same as the
- // time-of-day part of the specified DateTime.
- //
- // In more precise terms, considering the specified DateTime to be of the
- // form y / m / d + t, where y is the
- // year, m is the month, d is the day, and t is the
- // time-of-day, the result is y1 / m1 / d1 + t,
- // where y1 and m1 are computed by adding value months
- // to y and m, and d1 is the largest value less than
- // or equal to d that denotes a valid day in month m1 of year
- // y1.
- //
-
- public override DateTime AddMonths(DateTime time, int months) {
- if (months < -120000 || months > 120000) {
- throw new ArgumentOutOfRangeException(
- nameof(months),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- -120000,
- 120000));
- }
- Contract.EndContractBlock();
- // Get the date in Hijri calendar.
- int y = GetDatePart(time.Ticks, DatePartYear);
- int m = GetDatePart(time.Ticks, DatePartMonth);
- int d = GetDatePart(time.Ticks, DatePartDay);
- int i = m - 1 + months;
- if (i >= 0) {
- m = i % 12 + 1;
- y = y + i / 12;
- } else {
- m = 12 + (i + 1) % 12;
- y = y + (i - 11) / 12;
- }
- int days = GetDaysInMonth(y, m);
- if (d > days) {
- d = days;
- }
- long ticks = GetAbsoluteDateHijri(y, m, d)* TicksPerDay + (time.Ticks % TicksPerDay);
- Calendar.CheckAddResult(ticks, MinSupportedDateTime, MaxSupportedDateTime);
- return (new DateTime(ticks));
- }
-
- // Returns the DateTime resulting from adding the given number of
- // years to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year part of the specified DateTime by value
- // years. If the month and day of the specified DateTime is 2/29, and if the
- // resulting year is not a leap year, the month and day of the resulting
- // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
- // parts of the result are the same as those of the specified DateTime.
- //
-
- public override DateTime AddYears(DateTime time, int years) {
- return (AddMonths(time, years * 12));
- }
-
- // Returns the day-of-month part of the specified DateTime. The returned
- // value is an integer between 1 and 31.
- //
-
- public override int GetDayOfMonth(DateTime time) {
- return (GetDatePart(time.Ticks, DatePartDay));
- }
-
- // Returns the day-of-week part of the specified DateTime. The returned value
- // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
- // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
- // Thursday, 5 indicates Friday, and 6 indicates Saturday.
- //
-
- public override DayOfWeek GetDayOfWeek(DateTime time) {
- return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
- }
-
- // Returns the day-of-year part of the specified DateTime. The returned value
- // is an integer between 1 and 366.
- //
-
- public override int GetDayOfYear(DateTime time) {
- return (GetDatePart(time.Ticks, DatePartDayOfYear));
- }
-
- // Returns the number of days in the month given by the year and
- // month arguments.
- //
- [Pure]
- public override int GetDaysInMonth(int year, int month, int era) {
- CheckYearMonthRange(year, month, era);
- if (month == 12) {
- // For the 12th month, leap year has 30 days, and common year has 29 days.
- return (IsLeapYear(year, CurrentEra) ? 30 : 29);
- }
- // Other months contain 30 and 29 days alternatively. The 1st month has 30 days.
- return (((month % 2) == 1) ? 30 : 29);
- }
-
- // Returns the number of days in the year given by the year argument for the current era.
- //
-
- public override int GetDaysInYear(int year, int era) {
- CheckYearRange(year, era);
- // Common years have 354 days. Leap years have 355 days.
- return (IsLeapYear(year, CurrentEra) ? 355: 354);
- }
-
- // Returns the era for the specified DateTime value.
-
- public override int GetEra(DateTime time) {
- CheckTicksRange(time.Ticks);
- return (HijriEra);
- }
-
-
- public override int[] Eras {
- get {
- return (new int[] {HijriEra});
- }
- }
-
- // Returns the month part of the specified DateTime. The returned value is an
- // integer between 1 and 12.
- //
-
- public override int GetMonth(DateTime time) {
- return (GetDatePart(time.Ticks, DatePartMonth));
- }
-
- // Returns the number of months in the specified year and era.
-
- public override int GetMonthsInYear(int year, int era) {
- CheckYearRange(year, era);
- return (12);
- }
-
- // Returns the year part of the specified DateTime. The returned value is an
- // integer between 1 and MaxCalendarYear.
- //
-
- public override int GetYear(DateTime time) {
- return (GetDatePart(time.Ticks, DatePartYear));
- }
-
- // Checks whether a given day in the specified era is a leap day. This method returns true if
- // the date is a leap day, or false if not.
- //
-
- public override bool IsLeapDay(int year, int month, int day, int era) {
- // The year/month/era value checking is done in GetDaysInMonth().
- int daysInMonth = GetDaysInMonth(year, month, era);
- if (day < 1 || day > daysInMonth) {
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Day"),
- daysInMonth,
- month));
- }
- return (IsLeapYear(year, era) && month == 12 && day == 30);
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
- public override int GetLeapMonth(int year, int era)
- {
- CheckYearRange(year, era);
- return (0);
- }
-
- // Checks whether a given month in the specified era is a leap month. This method returns true if
- // month is a leap month, or false if not.
- //
-
- public override bool IsLeapMonth(int year, int month, int era) {
- CheckYearMonthRange(year, month, era);
- return (false);
- }
-
- // Checks whether a given year in the specified era is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
-
- public override bool IsLeapYear(int year, int era) {
- CheckYearRange(year, era);
- return ((((year * 11) + 14) % 30) < 11);
- }
-
- // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
- //
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) {
- // The year/month/era checking is done in GetDaysInMonth().
- int daysInMonth = GetDaysInMonth(year, month, era);
- if (day < 1 || day > daysInMonth) {
- BCLDebug.Log("year = " + year + ", month = " + month + ", day = " + day);
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Day"),
- daysInMonth,
- month));
- }
-
- long lDate = GetAbsoluteDateHijri(year, month, day);
-
- if (lDate >= 0) {
- return (new DateTime(lDate * GregorianCalendar.TicksPerDay + TimeToTicks(hour, minute, second, millisecond)));
- } else {
- throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
- }
- }
-
- private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 1451;
-
-
- public override int TwoDigitYearMax {
- get {
- if (twoDigitYearMax == -1) {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
- }
- return (twoDigitYearMax);
- }
-
- set {
- VerifyWritable();
- if (value < 99 || value > MaxCalendarYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(value),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 99,
- MaxCalendarYear));
-
- }
- twoDigitYearMax = value;
- }
- }
-
-
- public override int ToFourDigitYear(int year) {
- if (year < 0) {
- throw new ArgumentOutOfRangeException(nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- Contract.EndContractBlock();
-
- if (year < 100) {
- return (base.ToFourDigitYear(year));
- }
-
- if (year > MaxCalendarYear) {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 1,
- MaxCalendarYear));
- }
- return (year);
- }
-
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/IdnMapping.Unix.cs b/src/mscorlib/src/System/Globalization/IdnMapping.Unix.cs
new file mode 100644
index 0000000000..f1ad6f1d0a
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/IdnMapping.Unix.cs
@@ -0,0 +1,142 @@
+// 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.Diagnostics;
+
+namespace System.Globalization
+{
+ sealed partial class IdnMapping
+ {
+ private unsafe string GetAsciiCore(char* unicode, int count)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ uint flags = Flags;
+ CheckInvalidIdnCharacters(unicode, count, flags, nameof(unicode));
+
+ const int StackallocThreshold = 512;
+ // Each unicode character is represented by up to 3 ASCII chars
+ // and the whole string is prefixed by "xn--" (length 4)
+ int estimatedLength = (int)Math.Min(count * 3L + 4, StackallocThreshold);
+ int actualLength;
+ if (estimatedLength < StackallocThreshold)
+ {
+ char* outputStack = stackalloc char[estimatedLength];
+ actualLength = Interop.GlobalizationInterop.ToAscii(flags, unicode, count, outputStack, estimatedLength);
+ if (actualLength > 0 && actualLength <= estimatedLength)
+ {
+ return new string(outputStack, 0, actualLength);
+ }
+ }
+ else
+ {
+ actualLength = Interop.GlobalizationInterop.ToAscii(flags, unicode, count, null, 0);
+ }
+ if (actualLength == 0)
+ {
+ throw new ArgumentException(SR.Argument_IdnIllegalName, nameof(unicode));
+ }
+
+ char[] outputHeap = new char[actualLength];
+ fixed (char* pOutputHeap = outputHeap)
+ {
+ actualLength = Interop.GlobalizationInterop.ToAscii(flags, unicode, count, pOutputHeap, actualLength);
+ if (actualLength == 0 || actualLength > outputHeap.Length)
+ {
+ throw new ArgumentException(SR.Argument_IdnIllegalName, nameof(unicode));
+ }
+ return new string(pOutputHeap, 0, actualLength);
+ }
+ }
+
+ private unsafe string GetUnicodeCore(char* ascii, int count)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ uint flags = Flags;
+ CheckInvalidIdnCharacters(ascii, count, flags, nameof(ascii));
+
+ const int StackAllocThreshold = 512;
+ if (count < StackAllocThreshold)
+ {
+ char* output = stackalloc char[count];
+ return GetUnicodeCore(ascii, count, flags, output, count, reattempt: true);
+ }
+ else
+ {
+ char[] output = new char[count];
+ fixed (char* pOutput = output)
+ {
+ return GetUnicodeCore(ascii, count, flags, pOutput, count, reattempt: true);
+ }
+ }
+ }
+
+ private unsafe string GetUnicodeCore(char* ascii, int count, uint flags, char* output, int outputLength, bool reattempt)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ int realLen = Interop.GlobalizationInterop.ToUnicode(flags, ascii, count, output, outputLength);
+
+ if (realLen == 0)
+ {
+ throw new ArgumentException(SR.Argument_IdnIllegalName, nameof(ascii));
+ }
+ else if (realLen <= outputLength)
+ {
+ return new string(output, 0, realLen);
+ }
+ else if (reattempt)
+ {
+ char[] newOutput = new char[realLen];
+ fixed (char* pNewOutput = newOutput)
+ {
+ return GetUnicodeCore(ascii, count, flags, pNewOutput, realLen, reattempt: false);
+ }
+ }
+
+ throw new ArgumentException(SR.Argument_IdnIllegalName, nameof(ascii));
+ }
+
+ // -----------------------------
+ // ---- PAL layer ends here ----
+ // -----------------------------
+
+ private uint Flags
+ {
+ get
+ {
+ int flags =
+ (AllowUnassigned ? Interop.GlobalizationInterop.AllowUnassigned : 0) |
+ (UseStd3AsciiRules ? Interop.GlobalizationInterop.UseStd3AsciiRules : 0);
+ return (uint)flags;
+ }
+ }
+
+ /// <summary>
+ /// ICU doesn't check for invalid characters unless the STD3 rules option
+ /// is enabled.
+ ///
+ /// To match Windows behavior, we walk the string ourselves looking for these
+ /// bad characters so we can continue to throw ArgumentException in these cases.
+ /// </summary>
+ private static unsafe void CheckInvalidIdnCharacters(char* s, int count, uint flags, string paramName)
+ {
+ if ((flags & Interop.GlobalizationInterop.UseStd3AsciiRules) == 0)
+ {
+ for (int i = 0; i < count; i++)
+ {
+ char c = s[i];
+
+ // These characters are prohibited regardless of the UseStd3AsciiRules property.
+ // See https://msdn.microsoft.com/en-us/library/system.globalization.idnmapping.usestd3asciirules(v=vs.110).aspx
+ if (c <= 0x1F || c == 0x7F)
+ {
+ throw new ArgumentException(SR.Argument_IdnIllegalName, paramName);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/IdnMapping.Windows.cs b/src/mscorlib/src/System/Globalization/IdnMapping.Windows.cs
new file mode 100644
index 0000000000..d3f05bb164
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/IdnMapping.Windows.cs
@@ -0,0 +1,121 @@
+// 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.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace System.Globalization
+{
+ public sealed partial class IdnMapping
+ {
+ private unsafe string GetAsciiCore(char* unicode, int count)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ uint flags = Flags;
+
+ // Determine the required length
+ int length = Interop.Normaliz.IdnToAscii(flags, new IntPtr(unicode), count, IntPtr.Zero, 0);
+ if (length == 0)
+ {
+ ThrowForZeroLength(nameof(unicode), SR.Argument_IdnIllegalName, SR.Argument_InvalidCharSequenceNoIndex);
+ }
+
+ // Do the conversion
+ const int StackAllocThreshold = 512; // arbitrary limit to switch from stack to heap allocation
+ if (length < StackAllocThreshold)
+ {
+ char* output = stackalloc char[length];
+ return GetAsciiCore(unicode, count, flags, output, length);
+ }
+ else
+ {
+ char[] output = new char[length];
+ fixed (char* pOutput = output)
+ {
+ return GetAsciiCore(unicode, count, flags, pOutput, length);
+ }
+ }
+ }
+
+ private unsafe string GetAsciiCore(char* unicode, int count, uint flags, char* output, int outputLength)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ int length = Interop.Normaliz.IdnToAscii(flags, new IntPtr(unicode), count, new IntPtr(output), outputLength);
+ if (length == 0)
+ {
+ ThrowForZeroLength(nameof(unicode), SR.Argument_IdnIllegalName, SR.Argument_InvalidCharSequenceNoIndex);
+ }
+ Debug.Assert(length == outputLength);
+ return new string(output, 0, length);
+ }
+
+ private unsafe string GetUnicodeCore(char* ascii, int count)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ uint flags = Flags;
+
+ // Determine the required length
+ int length = Interop.Normaliz.IdnToUnicode(flags, new IntPtr(ascii), count, IntPtr.Zero, 0);
+ if (length == 0)
+ {
+ ThrowForZeroLength(nameof(ascii), SR.Argument_IdnIllegalName, SR.Argument_IdnBadPunycode);
+ }
+
+ // Do the conversion
+ const int StackAllocThreshold = 512; // arbitrary limit to switch from stack to heap allocation
+ if (length < StackAllocThreshold)
+ {
+ char* output = stackalloc char[length];
+ return GetUnicodeCore(ascii, count, flags, output, length);
+ }
+ else
+ {
+ char[] output = new char[length];
+ fixed (char* pOutput = output)
+ {
+ return GetUnicodeCore(ascii, count, flags, pOutput, length);
+ }
+ }
+ }
+
+ private unsafe string GetUnicodeCore(char* ascii, int count, uint flags, char* output, int outputLength)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ int length = Interop.Normaliz.IdnToUnicode(flags, new IntPtr(ascii), count, new IntPtr(output), outputLength);
+ if (length == 0)
+ {
+ ThrowForZeroLength(nameof(ascii), SR.Argument_IdnIllegalName, SR.Argument_IdnBadPunycode);
+ }
+ Debug.Assert(length == outputLength);
+ return new string(output, 0, length);
+ }
+
+ // -----------------------------
+ // ---- PAL layer ends here ----
+ // -----------------------------
+
+ private uint Flags
+ {
+ get
+ {
+ int flags =
+ (AllowUnassigned ? Interop.Normaliz.IDN_ALLOW_UNASSIGNED : 0) |
+ (UseStd3AsciiRules ? Interop.Normaliz.IDN_USE_STD3_ASCII_RULES : 0);
+ return (uint)flags;
+ }
+ }
+
+ private static void ThrowForZeroLength(string paramName, string invalidNameString, string otherString)
+ {
+ throw new ArgumentException(
+ Marshal.GetLastWin32Error() == Interop.Normaliz.ERROR_INVALID_NAME ? invalidNameString : otherString,
+ paramName);
+ }
+ }
+}
+
diff --git a/src/mscorlib/src/System/Globalization/IdnMapping.cs b/src/mscorlib/src/System/Globalization/IdnMapping.cs
index bf75f5be3c..4320e3abf5 100644
--- a/src/mscorlib/src/System/Globalization/IdnMapping.cs
+++ b/src/mscorlib/src/System/Globalization/IdnMapping.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-//
// This file contains the IDN functions and implementation.
//
// This allows encoding of non-ASCII domain names in a "punycode" form,
@@ -24,69 +23,18 @@
// RFC 3490 - Internationalizing Domain Names in Applications (IDNA)
// RFC 3491 - Nameprep: A Stringprep Profile for Internationalized Domain Names (IDN)
// RFC 3492 - Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)
-//
-/*
-
-The punycode implementation is based on the sample code in RFC 3492
-
-Copyright (C) The Internet Society (2003). All Rights Reserved.
-
-This document and translations of it may be copied and furnished to
-others, and derivative works that comment on or otherwise explain it
-or assist in its implementation may be prepared, copied, published
-and distributed, in whole or in part, without restriction of any
-kind, provided that the above copyright notice and this paragraph are
-included on all such copies and derivative works. However, this
-document itself may not be modified in any way, such as by removing
-the copyright notice or references to the Internet Society or other
-Internet organizations, except as needed for the purpose of
-developing Internet standards in which case the procedures for
-copyrights defined in the Internet Standards process must be
-followed, or as required to translate it into languages other than
-English.
-
-The limited permissions granted above are perpetual and will not be
-revoked by the Internet Society or its successors or assigns.
-
-This document and the information contained herein is provided on an
-"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
-TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
-HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
-MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-*/
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Text;
namespace System.Globalization
{
- using System;
- using System.Security;
- using System.Globalization;
- using System.Text;
- using System.Runtime.Versioning;
- using System.Runtime.InteropServices;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
// IdnMapping class used to map names to Punycode
-
- public sealed class IdnMapping
+ public sealed partial class IdnMapping
{
- // Legal name lengths for domain names
- const int M_labelLimit = 63; // Not including dots
- const int M_defaultNameLimit = 255; // Including dots
-
- // IDNA prefix
- const String M_strAcePrefix = "xn--";
-
- // Legal "dot" seperators (i.e: . in www.microsoft.com)
- static char[] M_Dots =
- {
- '.', '\u3002', '\uFF0E', '\uFF61'
- };
-
- bool m_bAllowUnassigned;
- bool m_bUseStd3AsciiRules;
+ private bool _allowUnassigned;
+ private bool _useStd3AsciiRules;
public IdnMapping()
{
@@ -94,282 +42,192 @@ namespace System.Globalization
public bool AllowUnassigned
{
- get
- {
- return this.m_bAllowUnassigned;
- }
-
- set
- {
- this.m_bAllowUnassigned = value;
- }
+ get { return _allowUnassigned; }
+ set { _allowUnassigned = value; }
}
public bool UseStd3AsciiRules
{
- get
- {
- return this.m_bUseStd3AsciiRules;
- }
-
- set
- {
- this.m_bUseStd3AsciiRules = value;
- }
+ get { return _useStd3AsciiRules; }
+ set { _useStd3AsciiRules = value; }
}
// Gets ASCII (Punycode) version of the string
- public String GetAscii(String unicode)
+ public string GetAscii(string unicode)
{
return GetAscii(unicode, 0);
}
- public String GetAscii(String unicode, int index)
+ public string GetAscii(string unicode, int index)
{
- if (unicode==null) throw new ArgumentNullException(nameof(unicode));
+ if (unicode == null)
+ throw new ArgumentNullException(nameof(unicode));
Contract.EndContractBlock();
return GetAscii(unicode, index, unicode.Length - index);
}
- public string GetAscii(String unicode, int index, int count)
+ public string GetAscii(string unicode, int index, int count)
{
- if (unicode == null) throw new ArgumentNullException(nameof(unicode));
+ if (unicode == null)
+ throw new ArgumentNullException(nameof(unicode));
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0) ? nameof(index) : nameof(count),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0) ? nameof(index) : nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (index > unicode.Length)
- throw new ArgumentOutOfRangeException(nameof(index),
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
if (index > unicode.Length - count)
- throw new ArgumentOutOfRangeException(nameof(unicode),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ throw new ArgumentOutOfRangeException(nameof(unicode), SR.ArgumentOutOfRange_IndexCountBuffer);
Contract.EndContractBlock();
- // We're only using part of the string
- unicode = unicode.Substring(index, count);
-
- if (Environment.IsWindows8OrAbove)
- {
- return GetAsciiUsingOS(unicode);
- }
-
- // Check for ASCII only string, which will be unchanged
- if (ValidateStd3AndAscii(unicode, UseStd3AsciiRules, true))
- {
- return unicode;
- }
-
- // Cannot be null terminated (normalization won't help us with this one, and
- // may have returned false before checking the whole string above)
- Debug.Assert(unicode.Length >= 1, "[IdnMapping.GetAscii]Expected 0 length strings to fail before now.");
- if (unicode[unicode.Length - 1] <= 0x1f)
- {
- throw new ArgumentException(
- Environment.GetResourceString("Argument_InvalidCharSequence", unicode.Length-1 ),
- nameof(unicode));
- }
-
- // Have to correctly IDNA normalize the string and Unassigned flags
- bool bHasLastDot = (unicode.Length > 0) && IsDot(unicode[unicode.Length - 1]);
- unicode = unicode.Normalize((NormalizationForm)(m_bAllowUnassigned ?
- ExtendedNormalizationForms.FormIdna : ExtendedNormalizationForms.FormIdnaDisallowUnassigned));
-
- // Make sure we didn't normalize away something after a last dot
- if ((!bHasLastDot) && unicode.Length > 0 && IsDot(unicode[unicode.Length - 1]))
- {
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), nameof(unicode));
- }
-
- // May need to check Std3 rules again for non-ascii
- if (UseStd3AsciiRules)
+ if (count == 0)
{
- ValidateStd3AndAscii(unicode, true, false);
+ throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(unicode));
}
-
- // Go ahead and encode it
- return punycode_encode(unicode);
- }
-
-
- private String GetAsciiUsingOS(String unicode)
- {
- if (unicode.Length == 0)
- {
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), nameof(unicode));
- }
-
- if (unicode[unicode.Length - 1] == 0)
+ if (unicode[index + count - 1] == 0)
{
- throw new ArgumentException(
- Environment.GetResourceString("Argument_InvalidCharSequence", unicode.Length - 1),
- nameof(unicode));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidCharSequence, index + count - 1), nameof(unicode));
}
-
- uint flags = (uint) ((AllowUnassigned ? IDN_ALLOW_UNASSIGNED : 0) | (UseStd3AsciiRules ? IDN_USE_STD3_ASCII_RULES : 0));
- int length = IdnToAscii(flags, unicode, unicode.Length, null, 0);
- int lastError;
-
- if (length == 0)
+ if (GlobalizationMode.Invariant)
{
- lastError = Marshal.GetLastWin32Error();
- if (lastError == ERROR_INVALID_NAME)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_IdnIllegalName"), nameof(unicode));
- }
-
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"), nameof(unicode));
+ return GetAsciiInvariant(unicode, index, count);
}
- char [] output = new char[length];
-
- length = IdnToAscii(flags, unicode, unicode.Length, output, length);
- if (length == 0)
+ unsafe
{
- lastError = Marshal.GetLastWin32Error();
- if (lastError == ERROR_INVALID_NAME)
+ fixed (char* pUnicode = unicode)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_IdnIllegalName"), nameof(unicode));
+ return GetAsciiCore(pUnicode + index, count);
}
-
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"), nameof(unicode));
}
-
- return new String(output, 0, length);
}
// Gets Unicode version of the string. Normalized and limited to IDNA characters.
- public String GetUnicode(String ascii)
+ public string GetUnicode(string ascii)
{
return GetUnicode(ascii, 0);
}
- public String GetUnicode(String ascii, int index)
+ public string GetUnicode(string ascii, int index)
{
- if (ascii==null) throw new ArgumentNullException(nameof(ascii));
+ if (ascii == null)
+ throw new ArgumentNullException(nameof(ascii));
Contract.EndContractBlock();
return GetUnicode(ascii, index, ascii.Length - index);
}
- public String GetUnicode(String ascii, int index, int count)
+ public string GetUnicode(string ascii, int index, int count)
{
- if (ascii==null) throw new ArgumentNullException(nameof(ascii));
+ if (ascii == null)
+ throw new ArgumentNullException(nameof(ascii));
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0) ? nameof(index) : nameof(count),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0) ? nameof(index) : nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (index > ascii.Length)
- throw new ArgumentOutOfRangeException("byteIndex",
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
if (index > ascii.Length - count)
- throw new ArgumentOutOfRangeException(nameof(ascii),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ throw new ArgumentOutOfRangeException(nameof(ascii), SR.ArgumentOutOfRange_IndexCountBuffer);
// This is a case (i.e. explicitly null-terminated input) where behavior in .NET and Win32 intentionally differ.
// The .NET APIs should (and did in v4.0 and earlier) throw an ArgumentException on input that includes a terminating null.
// The Win32 APIs fail on an embedded null, but not on a terminating null.
if (count > 0 && ascii[index + count - 1] == (char)0)
- throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"),
- nameof(ascii));
+ throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
Contract.EndContractBlock();
- // We're only using part of the string
- ascii = ascii.Substring(index, count);
-
- if (Environment.IsWindows8OrAbove)
+ if (GlobalizationMode.Invariant)
{
- return GetUnicodeUsingOS(ascii);
+ return GetUnicodeInvariant(ascii, index, count);
}
- // Convert Punycode to Unicode
- String strUnicode = punycode_decode(ascii);
+ unsafe
+ {
+ fixed (char* pAscii = ascii)
+ {
+ return GetUnicodeCore(pAscii + index, count);
+ }
+ }
+ }
- // Output name MUST obey IDNA rules & round trip (casing differences are allowed)
- if (!ascii.Equals(GetAscii(strUnicode), StringComparison.OrdinalIgnoreCase))
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnIllegalName"), nameof(ascii));
+ public override bool Equals(object obj)
+ {
+ IdnMapping that = obj as IdnMapping;
+ return
+ that != null &&
+ _allowUnassigned == that._allowUnassigned &&
+ _useStd3AsciiRules == that._useStd3AsciiRules;
+ }
- return strUnicode;
+ public override int GetHashCode()
+ {
+ return (_allowUnassigned ? 100 : 200) + (_useStd3AsciiRules ? 1000 : 2000);
}
-
- private string GetUnicodeUsingOS(string ascii)
+ //
+ // Invariant implementation
+ //
+
+ private const char c_delimiter = '-';
+ private const string c_strAcePrefix = "xn--";
+ private const int c_labelLimit = 63; // Not including dots
+ private const int c_defaultNameLimit = 255; // Including dots
+ private const int c_initialN = 0x80;
+ private const int c_maxint = 0x7ffffff;
+ private const int c_initialBias = 72;
+ private const int c_punycodeBase = 36;
+ private const int c_tmin = 1;
+ private const int c_tmax = 26;
+ private const int c_skew = 38;
+ private const int c_damp = 700;
+
+
+ // Legal "dot" separators (i.e: . in www.microsoft.com)
+ private static char[] c_Dots = { '.', '\u3002', '\uFF0E', '\uFF61' };
+
+ private string GetAsciiInvariant(string unicode, int index, int count)
{
- uint flags = (uint)((AllowUnassigned ? IDN_ALLOW_UNASSIGNED : 0) | (UseStd3AsciiRules ? IDN_USE_STD3_ASCII_RULES : 0));
- int length = IdnToUnicode(flags, ascii, ascii.Length, null, 0);
- int lastError;
-
- if (length == 0)
+ if (index > 0 || count < unicode.Length)
{
- lastError = Marshal.GetLastWin32Error();
- if (lastError == ERROR_INVALID_NAME)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_IdnIllegalName"), nameof(ascii));
- }
-
- throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), nameof(ascii));
+ unicode = unicode.Substring(index, count);
}
- char [] output = new char[length];
-
- length = IdnToUnicode(flags, ascii, ascii.Length, output, length);
- if (length == 0)
+ // Check for ASCII only string, which will be unchanged
+ if (ValidateStd3AndAscii(unicode, UseStd3AsciiRules, true))
{
- lastError = Marshal.GetLastWin32Error();
- if (lastError == ERROR_INVALID_NAME)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_IdnIllegalName"), nameof(ascii));
- }
-
- throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), nameof(ascii));
+ return unicode;
}
-
- return new String(output, 0, length);
- }
- public override bool Equals(Object obj)
- {
- IdnMapping that = obj as IdnMapping;
-
- if (that != null)
+ // Cannot be null terminated (normalization won't help us with this one, and
+ // may have returned false before checking the whole string above)
+ Debug.Assert(count >= 1, "[IdnMapping.GetAscii] Expected 0 length strings to fail before now.");
+ if (unicode[unicode.Length - 1] <= 0x1f)
{
- return this.m_bAllowUnassigned == that.m_bAllowUnassigned &&
- this.m_bUseStd3AsciiRules == that.m_bUseStd3AsciiRules;
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidCharSequence, unicode.Length - 1), nameof(unicode));
}
- return (false);
- }
+ // Have to correctly IDNA normalize the string and Unassigned flags
+ bool bHasLastDot = (unicode.Length > 0) && IsDot(unicode[unicode.Length - 1]);
- public override int GetHashCode()
- {
- return (this.m_bAllowUnassigned ? 100 : 200) + (this.m_bUseStd3AsciiRules ? 1000 : 2000);
- }
+ // Make sure we didn't normalize away something after a last dot
+ if ((!bHasLastDot) && unicode.Length > 0 && IsDot(unicode[unicode.Length - 1]))
+ {
+ throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(unicode));
+ }
- // Helpers
- static bool IsSupplementary(int cTest)
- {
- return cTest >= 0x10000;
- }
+ // May need to check Std3 rules again for non-ascii
+ if (UseStd3AsciiRules)
+ {
+ ValidateStd3AndAscii(unicode, true, false);
+ }
- // Is it a dot?
- // are we U+002E (., full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), or
- // U+FF61 (halfwidth ideographic full stop).
- // Note: IDNA Normalization gets rid of dots now, but testing for last dot is before normalization
- static bool IsDot(char c)
- {
- return c == '.' || c == '\u3002' || c == '\uFF0E' || c == '\uFF61';
+ // Go ahead and encode it
+ return PunycodeEncode(unicode);
}
-
// See if we're only ASCII
static bool ValidateStd3AndAscii(string unicode, bool bUseStd3, bool bCheckAscii)
{
// If its empty, then its too small
if (unicode.Length == 0)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), nameof(unicode));
- Contract.EndContractBlock();
+ throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(unicode));
int iLastDot = -1;
@@ -379,9 +237,7 @@ namespace System.Globalization
// Aren't allowing control chars (or 7f, but idn tables catch that, they don't catch \0 at end though)
if (unicode[i] <= 0x1f)
{
- throw new ArgumentException(
- Environment.GetResourceString("Argument_InvalidCharSequence", i ),
- nameof(unicode));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidCharSequence, i ), nameof(unicode));
}
// If its Unicode or a control character, return false (non-ascii)
@@ -393,17 +249,15 @@ namespace System.Globalization
{
// Can't have 2 dots in a row
if (i == iLastDot + 1)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), nameof(unicode));
+ throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(unicode));
// If its too far between dots then fail
- if (i - iLastDot > M_labelLimit + 1)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), nameof(unicode));
+ if (i - iLastDot > c_labelLimit + 1)
+ throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(unicode));
// If validating Std3, then char before dot can't be - char
if (bUseStd3 && i > 0)
- ValidateStd3(unicode[i-1], true);
+ ValidateStd3(unicode[i - 1], true);
// Remember where the last dot is
iLastDot = i;
@@ -418,148 +272,22 @@ namespace System.Globalization
}
// If we never had a dot, then we need to be shorter than the label limit
- if (iLastDot == -1 && unicode.Length > M_labelLimit)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), nameof(unicode));
+ if (iLastDot == -1 && unicode.Length > c_labelLimit)
+ throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(unicode));
// Need to validate entire string length, 1 shorter if last char wasn't a dot
- if (unicode.Length > M_defaultNameLimit - (IsDot(unicode[unicode.Length-1])? 0 : 1))
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadNameSize",
- M_defaultNameLimit - (IsDot(unicode[unicode.Length-1]) ? 0 : 1)),
- nameof(unicode));
+ if (unicode.Length > c_defaultNameLimit - (IsDot(unicode[unicode.Length - 1]) ? 0 : 1))
+ throw new ArgumentException(SR.Format(SR.Argument_IdnBadNameSize,
+ c_defaultNameLimit - (IsDot(unicode[unicode.Length - 1]) ? 0 : 1)), nameof(unicode));
// If last char wasn't a dot we need to check for trailing -
- if (bUseStd3 && !IsDot(unicode[unicode.Length-1]))
- ValidateStd3(unicode[unicode.Length-1], true);
+ if (bUseStd3 && !IsDot(unicode[unicode.Length - 1]))
+ ValidateStd3(unicode[unicode.Length - 1], true);
return true;
}
- // Validate Std3 rules for a character
- static void ValidateStd3(char c, bool bNextToDot)
- {
- // Check for illegal characters
- if ((c <= ',' || c == '/' || (c >= ':' && c <= '@') || // Lots of characters not allowed
- (c >= '[' && c <= '`') || (c >= '{' && c <= (char)0x7F)) ||
- (c == '-' && bNextToDot))
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadStd3", c), "Unicode");
- }
-
- //
- // The following punycode implementation is ported from the sample punycode.c in RFC 3492
- // Original sample code was written by Adam M. Costello.
- //
-
- // Return whether a punycode code point is flagged as being upper case.
-
- static bool HasUpperCaseFlag(char punychar)
- {
- return (punychar >= 'A' && punychar <= 'Z');
- }
-
-
- /**********************************************************/
- /* Implementation (would normally go in its own .c file): */
-
- /*** Bootstring parameters for Punycode ***/
- const int punycodeBase = 36;
- const int tmin = 1;
- const int tmax = 26;
- const int skew = 38;
- const int damp = 700;
- const int initial_bias = 72;
- const int initial_n = 0x80;
- const char delimiter = '-';
-
- /* basic(cp) tests whether cp is a basic code point: */
- static bool basic(uint cp)
- {
- // Is it in ASCII range?
- return cp < 0x80;
- }
-
- // decode_digit(cp) returns the numeric value of a basic code */
- // point (for use in representing integers) in the range 0 to */
- // punycodeBase-1, or <0 if cp is does not represent a value. */
-
- static int decode_digit(char cp)
- {
- if (cp >= '0' && cp <= '9')
- return cp - '0' + 26;
-
- // Two flavors for case differences
- if (cp >= 'a' && cp <= 'z')
- return cp - 'a';
-
- if (cp >= 'A' && cp <= 'Z')
- return cp - 'A';
-
- // Expected 0-9, A-Z or a-z, everything else is illegal
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), "ascii");
- }
-
- /* encode_digit(d,flag) returns the basic code point whose value */
- /* (when used for representing integers) is d, which needs to be in */
- /* the range 0 to punycodeBase-1. The lowercase form is used unless flag is */
- /* true, in which case the uppercase form is used. */
-
- static char encode_digit(int d)
- {
- Debug.Assert(d >= 0 && d < punycodeBase, "[IdnMapping.encode_digit]Expected 0 <= d < punycodeBase");
- // 26-35 map to ASCII 0-9
- if (d > 25) return (char)(d - 26 + '0');
-
- // 0-25 map to a-z or A-Z
- return (char)(d + 'a');
- }
-
-
-
- /* encode_basic(bcp,flag) forces a basic code point to lowercase */
- /* if flag is false, uppercase if flag is true, and returns */
- /* the resulting code point. The code point is unchanged if it */
- /* is caseless. The behavior is undefined if bcp is not a basic */
- /* code point. */
-
- static char encode_basic(char bcp)
- {
- if (HasUpperCaseFlag(bcp))
- bcp += (char)('a' - 'A');
-
- return bcp;
- }
-
- /*** Platform-specific constants ***/
-
- /* maxint is the maximum value of a uint variable: */
- const int maxint = 0x7ffffff;
-
- /*** Bias adaptation function ***/
-
- static int adapt(
- int delta, int numpoints, bool firsttime )
- {
- uint k;
-
- delta = firsttime ? delta / damp : delta / 2;
- Debug.Assert(numpoints != 0, "[IdnMapping.adapt]Expected non-zero numpoints.");
- delta += delta / numpoints;
-
- for (k = 0; delta > ((punycodeBase - tmin) * tmax) / 2; k += punycodeBase)
- {
- delta /= punycodeBase - tmin;
- }
-
- Debug.Assert(delta + skew != 0, "[IdnMapping.adapt]Expected non-zero delta+skew.");
- return (int)(k + (punycodeBase - tmin + 1) * delta / (delta + skew));
- }
-
- /*** Main encode function ***/
-
- /* punycode_encode() converts Unicode to Punycode. The input */
+ /* PunycodeEncode() converts Unicode to Punycode. The input */
/* is represented as an array of Unicode code points (not code */
/* units; surrogate pairs are not allowed), and the output */
/* will be represented as an array of ASCII code points. The */
@@ -584,14 +312,11 @@ namespace System.Globalization
/* value can be any of the punycode_status values defined above */
/* except punycode_bad_input; if not punycode_success, then */
/* output_size and output might contain garbage. */
-
- static String punycode_encode(String unicode)
+ static string PunycodeEncode(string unicode)
{
// 0 length strings aren't allowed
if (unicode.Length == 0)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), nameof(unicode));
- Contract.EndContractBlock();
+ throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(unicode));
StringBuilder output = new StringBuilder(unicode.Length);
int iNextDot = 0;
@@ -602,8 +327,8 @@ namespace System.Globalization
while (iNextDot < unicode.Length)
{
// Find end of this segment
- iNextDot = unicode.IndexOfAny(M_Dots, iAfterLastDot);
- Debug.Assert(iNextDot <= unicode.Length, "[IdnMapping.punycode_encode]IndexOfAny is broken");
+ iNextDot = unicode.IndexOfAny(c_Dots, iAfterLastDot);
+ Contract.Assert(iNextDot <= unicode.Length, "[IdnMapping.punycode_encode]IndexOfAny is broken");
if (iNextDot < 0)
iNextDot = unicode.Length;
@@ -612,14 +337,13 @@ namespace System.Globalization
{
// Only allowed to have empty sections as trailing .
if (iNextDot != unicode.Length)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), nameof(unicode));
+ throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(unicode));
// Last dot, stop
break;
}
// We'll need an Ace prefix
- output.Append(M_strAcePrefix);
+ output.Append(c_strAcePrefix);
// Everything resets every segment.
bool bRightToLeft = false;
@@ -642,8 +366,7 @@ namespace System.Globalization
if (eBidi != BidiCategory.RightToLeft && eBidi != BidiCategory.RightToLeftArabic)
{
// Oops, last wasn't RTL, last should be RTL if first is RTL
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadBidi"), nameof(unicode));
+ throw new ArgumentException(SR.Argument_IdnBadBidi, nameof(unicode));
}
}
@@ -653,8 +376,7 @@ namespace System.Globalization
for (basicCount = iAfterLastDot; basicCount < iNextDot; basicCount++)
{
// Can't be lonely surrogate because it would've thrown in normalization
- Debug.Assert(Char.IsLowSurrogate(unicode, basicCount) == false,
- "[IdnMapping.punycode_encode]Unexpected low surrogate");
+ Debug.Assert(Char.IsLowSurrogate(unicode, basicCount) == false, "[IdnMapping.punycode_encode]Unexpected low surrogate");
// Double check our bidi rules
BidiCategory testBidi = CharUnicodeInfo.GetBidiCategory(unicode, basicCount);
@@ -663,23 +385,20 @@ namespace System.Globalization
if (bRightToLeft && testBidi == BidiCategory.LeftToRight)
{
// Oops, throw error
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadBidi"), nameof(unicode));
+ throw new ArgumentException(SR.Argument_IdnBadBidi, nameof(unicode));
}
// If we're not RTL we can't have RTL chars
- if (!bRightToLeft && (testBidi == BidiCategory.RightToLeft ||
- testBidi == BidiCategory.RightToLeftArabic))
+ if (!bRightToLeft && (testBidi == BidiCategory.RightToLeft || testBidi == BidiCategory.RightToLeftArabic))
{
// Oops, throw error
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadBidi"), nameof(unicode));
+ throw new ArgumentException(SR.Argument_IdnBadBidi, nameof(unicode));
}
// If its basic then add it
- if (basic(unicode[basicCount]))
+ if (Basic(unicode[basicCount]))
{
- output.Append(encode_basic(unicode[basicCount]));
+ output.Append(EncodeBasic(unicode[basicCount]));
numProcessed++;
}
// If its a surrogate, skip the next since our bidi category tester doesn't handle it.
@@ -693,16 +412,15 @@ namespace System.Globalization
if (numBasicCodePoints == iNextDot - iAfterLastDot)
{
// Get rid of xn-- and this segments done
- output.Remove(iOutputAfterLastDot, M_strAcePrefix.Length);
+ output.Remove(iOutputAfterLastDot, c_strAcePrefix.Length);
}
else
{
// If it has some non-basic code points the input cannot start with xn--
- if (unicode.Length - iAfterLastDot >= M_strAcePrefix.Length &&
- unicode.Substring(iAfterLastDot, M_strAcePrefix.Length).Equals(
- M_strAcePrefix, StringComparison.OrdinalIgnoreCase))
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), nameof(unicode));
+ if (unicode.Length - iAfterLastDot >= c_strAcePrefix.Length &&
+ unicode.Substring(iAfterLastDot, c_strAcePrefix.Length).Equals(
+ c_strAcePrefix, StringComparison.OrdinalIgnoreCase))
+ throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(unicode));
// Need to do ACE encoding
int numSurrogatePairs = 0; // number of surrogate pairs so far
@@ -710,13 +428,13 @@ namespace System.Globalization
// Add a delimiter (-) if we had any basic code points (between basic and encoded pieces)
if (numBasicCodePoints > 0)
{
- output.Append(delimiter);
+ output.Append(c_delimiter);
}
// Initialize the state
- int n = initial_n;
+ int n = c_initialN;
int delta = 0;
- int bias = initial_bias;
+ int bias = c_initialBias;
// Main loop
while (numProcessed < (iNextDot - iAfterLastDot))
@@ -726,7 +444,7 @@ namespace System.Globalization
int j;
int m;
int test = 0;
- for (m = maxint, j = iAfterLastDot;
+ for (m = c_maxint, j = iAfterLastDot;
j < iNextDot;
j += IsSupplementary(test) ? 2 : 1)
{
@@ -751,27 +469,24 @@ namespace System.Globalization
if (test < n)
{
delta++;
- Debug.Assert(delta > 0, "[IdnMapping.cs]2 punycode_encode - delta overflowed int");
+ Contract.Assert(delta > 0, "[IdnMapping.cs]2 punycode_encode - delta overflowed int");
}
if (test == n)
{
// Represent delta as a generalized variable-length integer:
int q, k;
- for (q = delta, k = punycodeBase; ; k += punycodeBase)
+ for (q = delta, k = c_punycodeBase; ; k += c_punycodeBase)
{
- int t = k <= bias ? tmin :
- k >= bias + tmax ? tmax : k - bias;
+ int t = k <= bias ? c_tmin : k >= bias + c_tmax ? c_tmax : k - bias;
if (q < t) break;
- Debug.Assert(punycodeBase != t, "[IdnMapping.punycode_encode]Expected punycodeBase (36) to be != t");
-
- int mod;
- q = Math.DivRem(q - t, punycodeBase - t, out mod);
- output.Append(encode_digit(t + mod));
+ Debug.Assert(c_punycodeBase != t, "[IdnMapping.punycode_encode]Expected c_punycodeBase (36) to be != t");
+ output.Append(EncodeDigit(t + (q - t) % (c_punycodeBase - t)));
+ q = (q - t) / (c_punycodeBase - t);
}
- output.Append(encode_digit(q));
- bias = adapt(delta, (numProcessed - numSurrogatePairs) + 1, numProcessed == numBasicCodePoints);
+ output.Append(EncodeDigit(q));
+ bias = Adapt(delta, (numProcessed - numSurrogatePairs) + 1, numProcessed == numBasicCodePoints);
delta = 0;
numProcessed++;
@@ -789,9 +504,8 @@ namespace System.Globalization
}
// Make sure its not too big
- if (output.Length - iOutputAfterLastDot > M_labelLimit)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), nameof(unicode));
+ if (output.Length - iOutputAfterLastDot > c_labelLimit)
+ throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(unicode));
// Done with this segment, add dot if necessary
if (iNextDot != unicode.Length)
@@ -802,19 +516,61 @@ namespace System.Globalization
}
// Throw if we're too long
- if (output.Length > M_defaultNameLimit - (IsDot(unicode[unicode.Length-1]) ? 0 : 1))
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadNameSize",
- M_defaultNameLimit - (IsDot(unicode[unicode.Length-1]) ? 0 : 1)),
- nameof(unicode));
-
+ if (output.Length > c_defaultNameLimit - (IsDot(unicode[unicode.Length-1]) ? 0 : 1))
+ throw new ArgumentException(SR.Format(SR.Argument_IdnBadNameSize,
+ c_defaultNameLimit - (IsDot(unicode[unicode.Length-1]) ? 0 : 1)), nameof(unicode));
// Return our output string
return output.ToString();
}
- /*** Main decode function ***/
+ // Is it a dot?
+ // are we U+002E (., full stop), U+3002 (ideographic full stop), U+FF0E (fullwidth full stop), or
+ // U+FF61 (halfwidth ideographic full stop).
+ // Note: IDNA Normalization gets rid of dots now, but testing for last dot is before normalization
+ private static bool IsDot(char c)
+ {
+ return c == '.' || c == '\u3002' || c == '\uFF0E' || c == '\uFF61';
+ }
+
+ private static bool IsSupplementary(int cTest)
+ {
+ return cTest >= 0x10000;
+ }
- /* punycode_decode() converts Punycode to Unicode. The input is */
+ private static bool Basic(uint cp)
+ {
+ // Is it in ASCII range?
+ return cp < 0x80;
+ }
+
+ // Validate Std3 rules for a character
+ private static void ValidateStd3(char c, bool bNextToDot)
+ {
+ // Check for illegal characters
+ if ((c <= ',' || c == '/' || (c >= ':' && c <= '@') || // Lots of characters not allowed
+ (c >= '[' && c <= '`') || (c >= '{' && c <= (char)0x7F)) ||
+ (c == '-' && bNextToDot))
+ throw new ArgumentException(SR.Format(SR.Argument_IdnBadStd3, c), nameof(c));
+ }
+
+ private string GetUnicodeInvariant(string ascii, int index, int count)
+ {
+ if (index > 0 || count < ascii.Length)
+ {
+ // We're only using part of the string
+ ascii = ascii.Substring(index, count);
+ }
+ // Convert Punycode to Unicode
+ string strUnicode = PunycodeDecode(ascii);
+
+ // Output name MUST obey IDNA rules & round trip (casing differences are allowed)
+ if (!ascii.Equals(GetAscii(strUnicode), StringComparison.OrdinalIgnoreCase))
+ throw new ArgumentException(SR.Argument_IdnIllegalName, nameof(ascii));
+
+ return strUnicode;
+ }
+
+ /* PunycodeDecode() converts Punycode to Unicode. The input is */
/* represented as an array of ASCII code points, and the output */
/* will be represented as an array of Unicode code points. The */
/* input_length is the number of code points in the input. The */
@@ -835,19 +591,16 @@ namespace System.Globalization
/* decoder will never need to write an output_length greater than */
/* input_length, because of how the encoding is defined. */
- static String punycode_decode( String ascii )
+ private static string PunycodeDecode(string ascii)
{
// 0 length strings aren't allowed
if (ascii.Length == 0)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), nameof(ascii));
- Contract.EndContractBlock();
+ throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(ascii));
// Throw if we're too long
- if (ascii.Length > M_defaultNameLimit - (IsDot(ascii[ascii.Length-1]) ? 0 : 1))
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadNameSize",
- M_defaultNameLimit - (IsDot(ascii[ascii.Length-1]) ? 0 : 1)), nameof(ascii));
+ if (ascii.Length > c_defaultNameLimit - (IsDot(ascii[ascii.Length-1]) ? 0 : 1))
+ throw new ArgumentException(SR.Format(SR.Argument_IdnBadNameSize,
+ c_defaultNameLimit - (IsDot(ascii[ascii.Length-1]) ? 0 : 1)), nameof(ascii));
// output stringbuilder
StringBuilder output = new StringBuilder(ascii.Length);
@@ -869,51 +622,35 @@ namespace System.Globalization
{
// Only allowed to have empty sections as trailing .
if (iNextDot != ascii.Length)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), nameof(ascii));
+ throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(ascii));
// Last dot, stop
break;
}
// In either case it can't be bigger than segment size
- if (iNextDot - iAfterLastDot > M_labelLimit)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), nameof(ascii));
+ if (iNextDot - iAfterLastDot > c_labelLimit)
+ throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(ascii));
// See if this section's ASCII or ACE
- if (ascii.Length < M_strAcePrefix.Length + iAfterLastDot ||
- !ascii.Substring(iAfterLastDot, M_strAcePrefix.Length).Equals(
- M_strAcePrefix, StringComparison.OrdinalIgnoreCase))
+ if (ascii.Length < c_strAcePrefix.Length + iAfterLastDot ||
+ !ascii.Substring(iAfterLastDot,c_strAcePrefix.Length).Equals(c_strAcePrefix, StringComparison.OrdinalIgnoreCase))
{
- // Its supposed to be just ASCII
- // Actually, for non xn-- stuff do we want to allow Unicode?
- // for (int i = iAfterLastDot; i < iNextDot; i++)
- // {
- // // Only ASCII is allowed
- // if (ascii[i] >= 0x80)
- // throw new ArgumentException(Environment.GetResourceString(
- // "Argument_IdnBadPunycode"), nameof(ascii));
-// }
-
// Its ASCII, copy it
output.Append(ascii.Substring(iAfterLastDot, iNextDot - iAfterLastDot));
-
- // ASCII doesn't have BIDI issues
}
else
{
// Not ASCII, bump up iAfterLastDot to be after ACE Prefix
- iAfterLastDot += M_strAcePrefix.Length;
+ iAfterLastDot += c_strAcePrefix.Length;
// Get number of basic code points (where delimiter is)
// numBasicCodePoints < 0 if there're no basic code points
- int iTemp = ascii.LastIndexOf(delimiter, iNextDot - 1);
+ int iTemp = ascii.LastIndexOf(c_delimiter, iNextDot - 1);
// Trailing - not allowed
if (iTemp == iNextDot - 1)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), nameof(ascii));
+ throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
int numBasicCodePoints;
if (iTemp <= iAfterLastDot)
@@ -924,31 +661,25 @@ namespace System.Globalization
// Copy all the basic code points, making sure they're all in the allowed range,
// and losing the casing for all of them.
- for (int copyAscii = iAfterLastDot;
- copyAscii < iAfterLastDot + numBasicCodePoints;
- copyAscii++)
+ for (int copyAscii = iAfterLastDot; copyAscii < iAfterLastDot + numBasicCodePoints; copyAscii++)
{
// Make sure we don't allow unicode in the ascii part
if (ascii[copyAscii] > 0x7f)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), nameof(ascii));
+ throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
// When appending make sure they get lower cased
- output.Append((char)(ascii[copyAscii] >= 'A' && ascii[copyAscii] <='Z' ?
- ascii[copyAscii] - 'A' + 'a' :
- ascii[copyAscii]));
+ output.Append((char)(ascii[copyAscii] >= 'A' && ascii[copyAscii] <='Z' ? ascii[copyAscii] - 'A' + 'a' : ascii[copyAscii]));
}
}
// Get ready for main loop. Start at beginning if we didn't have any
// basic code points, otherwise start after the -.
// asciiIndex will be next character to read from ascii
- int asciiIndex = iAfterLastDot +
- ( numBasicCodePoints > 0 ? numBasicCodePoints + 1 : 0);
+ int asciiIndex = iAfterLastDot + (numBasicCodePoints > 0 ? numBasicCodePoints + 1 : 0);
// initialize our state
- int n = initial_n;
- int bias = initial_bias;
+ int n = c_initialN;
+ int bias = c_initialBias;
int i = 0;
int w, k;
@@ -965,58 +696,43 @@ namespace System.Globalization
/* value at the end to obtain delta. */
int oldi = i;
- for (w = 1, k = punycodeBase; ; k += punycodeBase)
+ for (w = 1, k = c_punycodeBase; ; k += c_punycodeBase)
{
// Check to make sure we aren't overrunning our ascii string
if (asciiIndex >= iNextDot)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), nameof(ascii));
+ throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
// decode the digit from the next char
- int digit = decode_digit(ascii[asciiIndex++]);
+ int digit = DecodeDigit(ascii[asciiIndex++]);
Debug.Assert(w > 0, "[IdnMapping.punycode_decode]Expected w > 0");
- if (digit > (maxint - i) / w)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), nameof(ascii));
+ if (digit > (c_maxint - i) / w)
+ throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
i += (int)(digit * w);
- int t = k <= bias ? tmin :
- k >= bias + tmax ? tmax : k - bias;
- if (digit < t) break;
- Debug.Assert(punycodeBase != t, "[IdnMapping.punycode_decode]Expected t != punycodeBase (36)");
- if (w > maxint / (punycodeBase - t))
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), nameof(ascii));
- w *= (punycodeBase - t);
+ int t = k <= bias ? c_tmin : k >= bias + c_tmax ? c_tmax : k - bias;
+ if (digit < t)
+ break;
+ Debug.Assert(c_punycodeBase != t, "[IdnMapping.punycode_decode]Expected t != c_punycodeBase (36)");
+ if (w > c_maxint / (c_punycodeBase - t))
+ throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
+ w *= (c_punycodeBase - t);
}
- bias = adapt(i - oldi,
- (output.Length - iOutputAfterLastDot - numSurrogatePairs) + 1, oldi == 0);
+ bias = Adapt(i - oldi, (output.Length - iOutputAfterLastDot - numSurrogatePairs) + 1, oldi == 0);
/* i was supposed to wrap around from output.Length to 0, */
/* incrementing n each time, so we'll fix that now: */
Debug.Assert((output.Length - iOutputAfterLastDot - numSurrogatePairs) + 1 > 0,
"[IdnMapping.punycode_decode]Expected to have added > 0 characters this segment");
- if (i / ((output.Length - iOutputAfterLastDot - numSurrogatePairs) + 1) > maxint - n)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), nameof(ascii));
+ if (i / ((output.Length - iOutputAfterLastDot - numSurrogatePairs) + 1) > c_maxint - n)
+ throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
n += (int)(i / (output.Length - iOutputAfterLastDot - numSurrogatePairs + 1));
i %= (output.Length - iOutputAfterLastDot - numSurrogatePairs + 1);
- // If it was flagged it needs to be capitalized
- // if (HasUpperCaseFlag(ascii[asciiIndex - 1]))
- // {
- // /* Case of last character determines uppercase flag: */
- // // Any casing stuff need to happen last.
- // If we wanted to reverse the IDNA casing data
- // n = MakeNUpperCase(n)
- // }
-
// Make sure n is legal
if ((n < 0 || n > 0x10ffff) || (n >= 0xD800 && n <= 0xDFFF))
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), nameof(ascii));
+ throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
// insert n at position i of the output: Really tricky if we have surrogates
int iUseInsertLocation;
@@ -1027,14 +743,11 @@ namespace System.Globalization
{
// Hard way, we have supplimentary characters
int iCount;
- for (iCount = i, iUseInsertLocation = iOutputAfterLastDot;
- iCount > 0;
- iCount--, iUseInsertLocation++)
+ for (iCount = i, iUseInsertLocation = iOutputAfterLastDot; iCount > 0; iCount--, iUseInsertLocation++)
{
// If its a surrogate, we have to go one more
if (iUseInsertLocation >= output.Length)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadPunycode"), nameof(ascii));
+ throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
if (Char.IsSurrogate(output[iUseInsertLocation]))
iUseInsertLocation++;
}
@@ -1071,34 +784,27 @@ namespace System.Globalization
for (int iTest = iOutputAfterLastDot; iTest < output.Length; iTest++)
{
// This might happen if we run into a pair
- if (Char.IsLowSurrogate(output.ToString(), iTest)) continue;
+ if (Char.IsLowSurrogate(output.ToString(), iTest))
+ continue;
// Check to see if its LTR
eBidi = CharUnicodeInfo.GetBidiCategory(output.ToString(), iTest);
if ((bRightToLeft && eBidi == BidiCategory.LeftToRight) ||
- (!bRightToLeft && (eBidi == BidiCategory.RightToLeft ||
- eBidi == BidiCategory.RightToLeftArabic)))
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadBidi"), nameof(ascii));
-
- // Make it lower case if we must (so we can test IsNormalized later)
- // if (output[iTest] >= 'A' && output[iTest] <= 'Z')
- // output[iTest] = (char)(output[iTest] + (char)('a' - 'A'));
+ (!bRightToLeft && (eBidi == BidiCategory.RightToLeft || eBidi == BidiCategory.RightToLeftArabic)))
+ throw new ArgumentException(SR.Argument_IdnBadBidi, nameof(ascii));
}
// Its also a requirement that the last one be RTL if 1st is RTL
if (bRightToLeft && eBidi != BidiCategory.RightToLeft && eBidi != BidiCategory.RightToLeftArabic)
{
// Oops, last wasn't RTL, last should be RTL if first is RTL
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadBidi"), nameof(ascii));
+ throw new ArgumentException(SR.Argument_IdnBadBidi, nameof(ascii));
}
}
// See if this label was too long
- if (iNextDot - iAfterLastDot > M_labelLimit)
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadLabelSize"), nameof(ascii));
+ if (iNextDot - iAfterLastDot > c_labelLimit)
+ throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(ascii));
// Done with this segment, add dot if necessary
if (iNextDot != ascii.Length)
@@ -1109,79 +815,84 @@ namespace System.Globalization
}
// Throw if we're too long
- if (output.Length > M_defaultNameLimit - (IsDot(output[output.Length-1]) ? 0 : 1))
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_IdnBadNameSize",
- M_defaultNameLimit -(IsDot(output[output.Length-1]) ? 0 : 1)), nameof(ascii));
+ if (output.Length > c_defaultNameLimit - (IsDot(output[output.Length-1]) ? 0 : 1))
+ throw new ArgumentException(SR.Format(SR.Argument_IdnBadNameSize, c_defaultNameLimit - (IsDot(output[output.Length-1]) ? 0 : 1)), nameof(ascii));
// Return our output string
return output.ToString();
}
- /*
- The previous punycode implimentation is based on the sample code in RFC 3492
-
- Full Copyright Statement
-
- Copyright (C) The Internet Society (2003). All Rights Reserved.
-
- This document and translations of it may be copied and furnished to
- others, and derivative works that comment on or otherwise explain it
- or assist in its implementation may be prepared, copied, published
- and distributed, in whole or in part, without restriction of any
- kind, provided that the above copyright notice and this paragraph are
- included on all such copies and derivative works. However, this
- document itself may not be modified in any way, such as by removing
- the copyright notice or references to the Internet Society or other
- Internet organizations, except as needed for the purpose of
- developing Internet standards in which case the procedures for
- copyrights defined in the Internet Standards process must be
- followed, or as required to translate it into languages other than
- English.
-
- The limited permissions granted above are perpetual and will not be
- revoked by the Internet Society or its successors or assigns.
-
- This document and the information contained herein is provided on an
- "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
- TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
- BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
- HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-
- private const int IDN_ALLOW_UNASSIGNED = 0x1;
- private const int IDN_USE_STD3_ASCII_RULES = 0x2;
+ // DecodeDigit(cp) returns the numeric value of a basic code */
+ // point (for use in representing integers) in the range 0 to */
+ // c_punycodeBase-1, or <0 if cp is does not represent a value. */
+
+ private static int DecodeDigit(char cp)
+ {
+ if (cp >= '0' && cp <= '9')
+ return cp - '0' + 26;
+
+ // Two flavors for case differences
+ if (cp >= 'a' && cp <= 'z')
+ return cp - 'a';
+
+ if (cp >= 'A' && cp <= 'Z')
+ return cp - 'A';
+
+ // Expected 0-9, A-Z or a-z, everything else is illegal
+ throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(cp));
+ }
+
+ private static int Adapt(int delta, int numpoints, bool firsttime)
+ {
+ uint k;
+
+ delta = firsttime ? delta / c_damp : delta / 2;
+ Debug.Assert(numpoints != 0, "[IdnMapping.adapt]Expected non-zero numpoints.");
+ delta += delta / numpoints;
+
+ for (k = 0; delta > ((c_punycodeBase - c_tmin) * c_tmax) / 2; k += c_punycodeBase)
+ {
+ delta /= c_punycodeBase - c_tmin;
+ }
+
+ Debug.Assert(delta + c_skew != 0, "[IdnMapping.adapt]Expected non-zero delta+skew.");
+ return (int)(k + (c_punycodeBase - c_tmin + 1) * delta / (delta + c_skew));
+ }
+
+ /* EncodeBasic(bcp,flag) forces a basic code point to lowercase */
+ /* if flag is false, uppercase if flag is true, and returns */
+ /* the resulting code point. The code point is unchanged if it */
+ /* is caseless. The behavior is undefined if bcp is not a basic */
+ /* code point. */
+
+ static char EncodeBasic(char bcp)
+ {
+ if (HasUpperCaseFlag(bcp))
+ bcp += (char)('a' - 'A');
+
+ return bcp;
+ }
+
+ // Return whether a punycode code point is flagged as being upper case.
+ private static bool HasUpperCaseFlag(char punychar)
+ {
+ return (punychar >= 'A' && punychar <= 'Z');
+ }
+
+ /* EncodeDigit(d,flag) returns the basic code point whose value */
+ /* (when used for representing integers) is d, which needs to be in */
+ /* the range 0 to punycodeBase-1. The lowercase form is used unless flag is */
+ /* true, in which case the uppercase form is used. */
+
+ private static char EncodeDigit(int d)
+ {
+ Debug.Assert(d >= 0 && d < c_punycodeBase, "[IdnMapping.encode_digit]Expected 0 <= d < punycodeBase");
+ // 26-35 map to ASCII 0-9
+ if (d > 25) return (char)(d - 26 + '0');
+
+ // 0-25 map to a-z or A-Z
+ return (char)(d + 'a');
+ }
- private const int ERROR_INVALID_NAME = 123;
-
-
- [SuppressUnmanagedCodeSecurityAttribute()]
- [DllImport("normaliz.dll", CharSet=CharSet.Unicode, SetLastError=true)]
- private static extern int IdnToAscii(
- uint dwFlags,
- [InAttribute()]
- [MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
- String lpUnicodeCharStr,
- int cchUnicodeChar,
- [System.Runtime.InteropServices.OutAttribute()]
-
- char [] lpASCIICharStr,
- int cchASCIIChar);
-
- [SuppressUnmanagedCodeSecurityAttribute()]
- [DllImport("normaliz.dll", CharSet=CharSet.Unicode, SetLastError=true)]
- private static extern int IdnToUnicode(
- uint dwFlags,
- [InAttribute()]
- [MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
- string lpASCIICharStr,
- int cchASCIIChar,
- [System.Runtime.InteropServices.OutAttribute()]
-
- char [] lpUnicodeCharStr,
- int cchUnicodeChar);
}
}
-
diff --git a/src/mscorlib/src/System/Globalization/JapaneseCalendar.Unix.cs b/src/mscorlib/src/System/Globalization/JapaneseCalendar.Unix.cs
new file mode 100644
index 0000000000..51ff8095a3
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/JapaneseCalendar.Unix.cs
@@ -0,0 +1,96 @@
+// 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.Collections.Generic;
+using System.Diagnostics;
+
+namespace System.Globalization
+{
+ public partial class JapaneseCalendar : Calendar
+ {
+ private static EraInfo[] GetJapaneseEras()
+ {
+ if (GlobalizationMode.Invariant)
+ {
+ return null;
+ }
+
+ string[] eraNames;
+ if (!CalendarData.EnumCalendarInfo("ja-JP", CalendarId.JAPAN, CalendarDataType.EraNames, out eraNames))
+ {
+ return null;
+ }
+
+ string[] abbrevEnglishEraNames;
+ if (!CalendarData.EnumCalendarInfo("en", CalendarId.JAPAN, CalendarDataType.AbbrevEraNames, out abbrevEnglishEraNames))
+ {
+ return null;
+ }
+
+ List<EraInfo> eras = new List<EraInfo>();
+ int lastMaxYear = GregorianCalendar.MaxYear;
+
+ int latestEra = Interop.GlobalizationInterop.GetLatestJapaneseEra();
+ for (int i = latestEra; i >= 0; i--)
+ {
+ DateTime dt;
+ if (!GetJapaneseEraStartDate(i, out dt))
+ {
+ return null;
+ }
+
+ if (dt < JapaneseCalendar.calendarMinValue)
+ {
+ // only populate the Eras that are valid JapaneseCalendar date times
+ break;
+ }
+
+ eras.Add(new EraInfo(i, dt.Year, dt.Month, dt.Day, dt.Year - 1, 1, lastMaxYear - dt.Year + 1,
+ eraNames[i], GetAbbreviatedEraName(eraNames, i), abbrevEnglishEraNames[i]));
+
+ lastMaxYear = dt.Year;
+ }
+
+ // remap the Era numbers, now that we know how many there will be
+ for (int i = 0; i < eras.Count; i++)
+ {
+ eras[i].era = eras.Count - i;
+ }
+
+ return eras.ToArray();
+ }
+
+ // PAL Layer ends here
+
+ private static string GetAbbreviatedEraName(string[] eraNames, int eraIndex)
+ {
+ // This matches the behavior on Win32 - only returning the first character of the era name.
+ // See Calendar.EraAsString(Int32) - https://msdn.microsoft.com/en-us/library/windows/apps/br206751.aspx
+ return eraNames[eraIndex].Substring(0, 1);
+ }
+
+ private static bool GetJapaneseEraStartDate(int era, out DateTime dateTime)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+
+ dateTime = default(DateTime);
+
+ int startYear;
+ int startMonth;
+ int startDay;
+ bool result = Interop.GlobalizationInterop.GetJapaneseEraStartDate(
+ era,
+ out startYear,
+ out startMonth,
+ out startDay);
+
+ if (result)
+ {
+ dateTime = new DateTime(startYear, startMonth, startDay);
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/JapaneseCalendar.Win32.cs b/src/mscorlib/src/System/Globalization/JapaneseCalendar.Win32.cs
new file mode 100644
index 0000000000..fe8b1b5896
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/JapaneseCalendar.Win32.cs
@@ -0,0 +1,209 @@
+// 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.Diagnostics;
+
+using Microsoft.Win32;
+
+namespace System.Globalization
+{
+ public partial class JapaneseCalendar : Calendar
+ {
+ private const string c_japaneseErasHive = @"System\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras";
+ private const string c_japaneseErasHivePermissionList = @"HKEY_LOCAL_MACHINE\" + c_japaneseErasHive;
+
+ // We know about 4 built-in eras, however users may add additional era(s) from the
+ // registry, by adding values to HKLM\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras
+ //
+ // Registry values look like:
+ // yyyy.mm.dd=era_abbrev_english_englishabbrev
+ //
+ // Where yyyy.mm.dd is the registry value name, and also the date of the era start.
+ // yyyy, mm, and dd are the year, month & day the era begins (4, 2 & 2 digits long)
+ // era is the Japanese Era name
+ // abbrev is the Abbreviated Japanese Era Name
+ // english is the English name for the Era (unused)
+ // englishabbrev is the Abbreviated English name for the era.
+ // . is a delimiter, but the value of . doesn't matter.
+ // '_' marks the space between the japanese era name, japanese abbreviated era name
+ // english name, and abbreviated english names.
+ private static EraInfo[] GetJapaneseEras()
+ {
+ // Look in the registry key and see if we can find any ranges
+ int iFoundEras = 0;
+ EraInfo[] registryEraRanges = null;
+
+ try
+ {
+ using (RegistryKey key = Registry.LocalMachine.OpenSubKey(c_japaneseErasHive, writable: false))
+ {
+ // Abort if we didn't find anything
+ if (key == null) return null;
+
+ // Look up the values in our reg key
+ String[] valueNames = key.GetValueNames();
+ if (valueNames != null && valueNames.Length > 0)
+ {
+ registryEraRanges = new EraInfo[valueNames.Length];
+
+ // Loop through the registry and read in all the values
+ for (int i = 0; i < valueNames.Length; i++)
+ {
+ // See if the era is a valid date
+ EraInfo era = GetEraFromValue(valueNames[i], key.GetValue(valueNames[i]).ToString());
+
+ // continue if not valid
+ if (era == null) continue;
+
+ // Remember we found one.
+ registryEraRanges[iFoundEras] = era;
+ iFoundEras++;
+ }
+ }
+ }
+ }
+ catch (System.Security.SecurityException)
+ {
+ // If we weren't allowed to read, then just ignore the error
+ return null;
+ }
+ catch (System.IO.IOException)
+ {
+ // If key is being deleted just ignore the error
+ return null;
+ }
+ catch (System.UnauthorizedAccessException)
+ {
+ // Registry access rights permissions, just ignore the error
+ return null;
+ }
+
+ //
+ // If we didn't have valid eras, then fail
+ // should have at least 4 eras
+ //
+ if (iFoundEras < 4) return null;
+
+ //
+ // Now we have eras, clean them up.
+ //
+ // Clean up array length
+ Array.Resize(ref registryEraRanges, iFoundEras);
+
+ // Sort them
+ Array.Sort(registryEraRanges, CompareEraRanges);
+
+ // Clean up era information
+ for (int i = 0; i < registryEraRanges.Length; i++)
+ {
+ // eras count backwards from length to 1 (and are 1 based indexes into string arrays)
+ registryEraRanges[i].era = registryEraRanges.Length - i;
+
+ // update max era year
+ if (i == 0)
+ {
+ // First range is 'til the end of the calendar
+ registryEraRanges[0].maxEraYear = GregorianCalendar.MaxYear - registryEraRanges[0].yearOffset;
+ }
+ else
+ {
+ // Rest are until the next era (remember most recent era is first in array)
+ registryEraRanges[i].maxEraYear = registryEraRanges[i - 1].yearOffset + 1 - registryEraRanges[i].yearOffset;
+ }
+ }
+
+ // Return our ranges
+ return registryEraRanges;
+ }
+
+ //
+ // Compare two era ranges, eg just the ticks
+ // Remember the era array is supposed to be in reverse chronological order
+ //
+ private static int CompareEraRanges(EraInfo a, EraInfo b)
+ {
+ return b.ticks.CompareTo(a.ticks);
+ }
+
+ //
+ // GetEraFromValue
+ //
+ // Parse the registry value name/data pair into an era
+ //
+ // Registry values look like:
+ // yyyy.mm.dd=era_abbrev_english_englishabbrev
+ //
+ // Where yyyy.mm.dd is the registry value name, and also the date of the era start.
+ // yyyy, mm, and dd are the year, month & day the era begins (4, 2 & 2 digits long)
+ // era is the Japanese Era name
+ // abbrev is the Abbreviated Japanese Era Name
+ // english is the English name for the Era (unused)
+ // englishabbrev is the Abbreviated English name for the era.
+ // . is a delimiter, but the value of . doesn't matter.
+ // '_' marks the space between the japanese era name, japanese abbreviated era name
+ // english name, and abbreviated english names.
+ private static EraInfo GetEraFromValue(String value, String data)
+ {
+ // Need inputs
+ if (value == null || data == null) return null;
+
+ //
+ // Get Date
+ //
+ // Need exactly 10 characters in name for date
+ // yyyy.mm.dd although the . can be any character
+ if (value.Length != 10) return null;
+
+ int year;
+ int month;
+ int day;
+
+ if (!Int32.TryParse(value.Substring(0, 4), NumberStyles.None, NumberFormatInfo.InvariantInfo, out year) ||
+ !Int32.TryParse(value.Substring(5, 2), NumberStyles.None, NumberFormatInfo.InvariantInfo, out month) ||
+ !Int32.TryParse(value.Substring(8, 2), NumberStyles.None, NumberFormatInfo.InvariantInfo, out day))
+ {
+ // Couldn't convert integer, fail
+ return null;
+ }
+
+ //
+ // Get Strings
+ //
+ // Needs to be a certain length e_a_E_A at least (7 chars, exactly 4 groups)
+ String[] names = data.Split('_');
+
+ // Should have exactly 4 parts
+ // 0 - Era Name
+ // 1 - Abbreviated Era Name
+ // 2 - English Era Name
+ // 3 - Abbreviated English Era Name
+ if (names.Length != 4) return null;
+
+ // Each part should have data in it
+ if (names[0].Length == 0 ||
+ names[1].Length == 0 ||
+ names[2].Length == 0 ||
+ names[3].Length == 0)
+ return null;
+
+ //
+ // Now we have an era we can build
+ // Note that the era # and max era year need cleaned up after sorting
+ // Don't use the full English Era Name (names[2])
+ //
+ return new EraInfo(0, year, month, day, year - 1, 1, 0,
+ names[0], names[1], names[3]);
+ }
+
+ // PAL Layer ends here
+
+ private static string[] s_japaneseErasEnglishNames = new String[] { "M", "T", "S", "H" };
+
+ private static string GetJapaneseEnglishEraName(int era)
+ {
+ Debug.Assert(era > 0);
+ return era <= s_japaneseErasEnglishNames.Length ? s_japaneseErasEnglishNames[era - 1] : " ";
+ }
+ }
+}
diff --git a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.WinRT.cs b/src/mscorlib/src/System/Globalization/JapaneseCalendar.WinRT.cs
index 6a9df97200..6a9df97200 100644
--- a/src/mscorlib/corefx/System/Globalization/JapaneseCalendar.WinRT.cs
+++ b/src/mscorlib/src/System/Globalization/JapaneseCalendar.WinRT.cs
diff --git a/src/mscorlib/src/System/Globalization/JapaneseCalendar.cs b/src/mscorlib/src/System/Globalization/JapaneseCalendar.cs
deleted file mode 100644
index 72331f8346..0000000000
--- a/src/mscorlib/src/System/Globalization/JapaneseCalendar.cs
+++ /dev/null
@@ -1,581 +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.
-
-namespace System.Globalization {
-
- using System;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
- using Microsoft.Win32;
-
- /*=================================JapaneseCalendar==========================
- **
- ** JapaneseCalendar is based on Gregorian calendar. The month and day values are the same as
- ** Gregorian calendar. However, the year value is an offset to the Gregorian
- ** year based on the era.
- **
- ** This system is adopted by Emperor Meiji in 1868. The year value is counted based on the reign of an emperor,
- ** and the era begins on the day an emperor ascends the throne and continues until his death.
- ** The era changes at 12:00AM.
- **
- ** For example, the current era is Heisei. It started on 1989/1/8 A.D. Therefore, Gregorian year 1989 is also Heisei 1st.
- ** 1989/1/8 A.D. is also Heisei 1st 1/8.
- **
- ** Any date in the year during which era is changed can be reckoned in either era. For example,
- ** 1989/1/1 can be 1/1 Heisei 1st year or 1/1 Showa 64th year.
- **
- ** Note:
- ** The DateTime can be represented by the JapaneseCalendar are limited to two factors:
- ** 1. The min value and max value of DateTime class.
- ** 2. The available era information.
- **
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 1868/09/08 9999/12/31
- ** Japanese Meiji 01/01 Heisei 8011/12/31
- ============================================================================*/
-
-
- [Serializable]
- public class JapaneseCalendar : Calendar
- {
- internal static readonly DateTime calendarMinValue = new DateTime(1868, 9, 8);
-
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (calendarMinValue);
- }
- }
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (DateTime.MaxValue);
- }
- }
-
- // Return the type of the Japanese calendar.
- //
-
- public override CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.SolarCalendar;
- }
- }
-
- //
- // Using a field initializer rather than a static constructor so that the whole class can be lazy
- // init.
- static internal volatile EraInfo[] japaneseEraInfo;
-
- //
- // Read our era info
- //
- // m_EraInfo must be listed in reverse chronological order. The most recent era
- // should be the first element.
- // That is, m_EraInfo[0] contains the most recent era.
- //
- // We know about 4 built-in eras, however users may add additional era(s) from the
- // registry, by adding values to HKLM\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras
- //
- // Registry values look like:
- // yyyy.mm.dd=era_abbrev_english_englishabbrev
- //
- // Where yyyy.mm.dd is the registry value name, and also the date of the era start.
- // yyyy, mm, and dd are the year, month & day the era begins (4, 2 & 2 digits long)
- // era is the Japanese Era name
- // abbrev is the Abbreviated Japanese Era Name
- // english is the English name for the Era (unused)
- // englishabbrev is the Abbreviated English name for the era.
- // . is a delimiter, but the value of . doesn't matter.
- // '_' marks the space between the japanese era name, japanese abbreviated era name
- // english name, and abbreviated english names.
- //
- internal static EraInfo[] GetEraInfo()
- {
- // See if we need to build it
- if (japaneseEraInfo == null)
- {
- // See if we have any eras from the registry
- japaneseEraInfo = GetErasFromRegistry();
-
- // See if we have to use the built-in eras
- if (japaneseEraInfo == null)
- {
- // We know about some built-in ranges
- EraInfo[] defaultEraRanges = new EraInfo[4];
- defaultEraRanges[0] = new EraInfo( 4, 1989, 1, 8, 1988, 1, GregorianCalendar.MaxYear - 1988,
- "\x5e73\x6210", "\x5e73", "H"); // era #4 start year/month/day, yearOffset, minEraYear
- defaultEraRanges[1] = new EraInfo( 3, 1926, 12, 25, 1925, 1, 1989-1925,
- "\x662d\x548c", "\x662d", "S"); // era #3,start year/month/day, yearOffset, minEraYear
- defaultEraRanges[2] = new EraInfo( 2, 1912, 7, 30, 1911, 1, 1926-1911,
- "\x5927\x6b63", "\x5927", "T"); // era #2,start year/month/day, yearOffset, minEraYear
- defaultEraRanges[3] = new EraInfo( 1, 1868, 1, 1, 1867, 1, 1912-1867,
- "\x660e\x6cbb", "\x660e", "M"); // era #1,start year/month/day, yearOffset, minEraYear
-
- // Remember the ranges we built
- japaneseEraInfo = defaultEraRanges;
- }
- }
-
- // return the era we found/made
- return japaneseEraInfo;
- }
-
-
-#if FEATURE_WIN32_REGISTRY
- private const string c_japaneseErasHive = @"System\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras";
- private const string c_japaneseErasHivePermissionList = @"HKEY_LOCAL_MACHINE\" + c_japaneseErasHive;
-
- //
- // GetErasFromRegistry()
- //
- // We know about 4 built-in eras, however users may add additional era(s) from the
- // registry, by adding values to HKLM\SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras
- //
- // Registry values look like:
- // yyyy.mm.dd=era_abbrev_english_englishabbrev
- //
- // Where yyyy.mm.dd is the registry value name, and also the date of the era start.
- // yyyy, mm, and dd are the year, month & day the era begins (4, 2 & 2 digits long)
- // era is the Japanese Era name
- // abbrev is the Abbreviated Japanese Era Name
- // english is the English name for the Era (unused)
- // englishabbrev is the Abbreviated English name for the era.
- // . is a delimiter, but the value of . doesn't matter.
- // '_' marks the space between the japanese era name, japanese abbreviated era name
- // english name, and abbreviated english names.
- private static EraInfo[] GetErasFromRegistry()
- {
- // Look in the registry key and see if we can find any ranges
- int iFoundEras = 0;
- EraInfo[] registryEraRanges = null;
-
- try
- {
- RegistryKey key = Registry.LocalMachine.OpenSubKey(c_japaneseErasHive, writable: false);
-
- // Abort if we didn't find anything
- if (key == null) return null;
-
- // Look up the values in our reg key
- String[] valueNames = key.GetValueNames();
- if (valueNames != null && valueNames.Length > 0)
- {
- registryEraRanges = new EraInfo[valueNames.Length];
-
- // Loop through the registry and read in all the values
- for (int i = 0; i < valueNames.Length; i++)
- {
- // See if the era is a valid date
- EraInfo era = GetEraFromValue(valueNames[i], key.GetValue(valueNames[i]).ToString());
-
- // continue if not valid
- if (era == null) continue;
-
- // Remember we found one.
- registryEraRanges[iFoundEras] = era;
- iFoundEras++;
- }
- }
- }
- catch (System.Security.SecurityException)
- {
- // If we weren't allowed to read, then just ignore the error
- return null;
- }
- catch (System.IO.IOException)
- {
- // If key is being deleted just ignore the error
- return null;
- }
- catch (System.UnauthorizedAccessException)
- {
- // Registry access rights permissions, just ignore the error
- return null;
- }
-
- //
- // If we didn't have valid eras, then fail
- // should have at least 4 eras
- //
- if (iFoundEras < 4) return null;
-
- //
- // Now we have eras, clean them up.
- //
- // Clean up array length
- Array.Resize(ref registryEraRanges, iFoundEras);
-
- // Sort them
- Array.Sort(registryEraRanges, CompareEraRanges);
-
- // Clean up era information
- for (int i = 0; i < registryEraRanges.Length; i++)
- {
- // eras count backwards from length to 1 (and are 1 based indexes into string arrays)
- registryEraRanges[i].era = registryEraRanges.Length - i;
-
- // update max era year
- if (i == 0)
- {
- // First range is 'til the end of the calendar
- registryEraRanges[0].maxEraYear = GregorianCalendar.MaxYear - registryEraRanges[0].yearOffset;
- }
- else
- {
- // Rest are until the next era (remember most recent era is first in array)
- registryEraRanges[i].maxEraYear = registryEraRanges[i-1].yearOffset + 1 - registryEraRanges[i].yearOffset;
- }
- }
-
- // Return our ranges
- return registryEraRanges;
- }
-#else
- private static EraInfo[] GetErasFromRegistry()
- {
- return null;
- }
-#endif
-
- //
- // Compare two era ranges, eg just the ticks
- // Remember the era array is supposed to be in reverse chronological order
- //
- private static int CompareEraRanges(EraInfo a, EraInfo b)
- {
- return b.ticks.CompareTo(a.ticks);
- }
-
- //
- // GetEraFromValue
- //
- // Parse the registry value name/data pair into an era
- //
- // Registry values look like:
- // yyyy.mm.dd=era_abbrev_english_englishabbrev
- //
- // Where yyyy.mm.dd is the registry value name, and also the date of the era start.
- // yyyy, mm, and dd are the year, month & day the era begins (4, 2 & 2 digits long)
- // era is the Japanese Era name
- // abbrev is the Abbreviated Japanese Era Name
- // english is the English name for the Era (unused)
- // englishabbrev is the Abbreviated English name for the era.
- // . is a delimiter, but the value of . doesn't matter.
- // '_' marks the space between the japanese era name, japanese abbreviated era name
- // english name, and abbreviated english names.
- private static EraInfo GetEraFromValue(String value, String data)
- {
- // Need inputs
- if (value == null || data == null) return null;
-
- //
- // Get Date
- //
- // Need exactly 10 characters in name for date
- // yyyy.mm.dd although the . can be any character
- if (value.Length != 10) return null;
-
- int year;
- int month;
- int day;
-
- if (!Number.TryParseInt32(value.Substring(0,4), NumberStyles.None, NumberFormatInfo.InvariantInfo, out year) ||
- !Number.TryParseInt32(value.Substring(5,2), NumberStyles.None, NumberFormatInfo.InvariantInfo, out month) ||
- !Number.TryParseInt32(value.Substring(8,2), NumberStyles.None, NumberFormatInfo.InvariantInfo, out day))
- {
- // Couldn't convert integer, fail
- return null;
- }
-
- //
- // Get Strings
- //
- // Needs to be a certain length e_a_E_A at least (7 chars, exactly 4 groups)
- String[] names = data.Split('_');
-
- // Should have exactly 4 parts
- // 0 - Era Name
- // 1 - Abbreviated Era Name
- // 2 - English Era Name
- // 3 - Abbreviated English Era Name
- if (names.Length != 4) return null;
-
- // Each part should have data in it
- if (names[0].Length == 0 ||
- names[1].Length == 0 ||
- names[2].Length == 0 ||
- names[3].Length == 0)
- return null;
-
- //
- // Now we have an era we can build
- // Note that the era # and max era year need cleaned up after sorting
- // Don't use the full English Era Name (names[2])
- //
- return new EraInfo( 0, year, month, day, year - 1, 1, 0,
- names[0], names[1], names[3]);
- }
-
- internal static volatile Calendar s_defaultInstance;
- internal GregorianCalendarHelper helper;
-
- /*=================================GetDefaultInstance==========================
- **Action: Internal method to provide a default intance of JapaneseCalendar. Used by NLS+ implementation
- ** and other calendars.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
-
- internal static Calendar GetDefaultInstance() {
- if (s_defaultInstance == null) {
- s_defaultInstance = new JapaneseCalendar();
- }
- return (s_defaultInstance);
- }
-
-
- public JapaneseCalendar() {
- try {
- new CultureInfo("ja-JP");
- } catch (ArgumentException e) {
- throw new TypeInitializationException(this.GetType().FullName, e);
- }
- helper = new GregorianCalendarHelper(this, GetEraInfo());
- }
-
- internal override int ID {
- get {
- return (CAL_JAPAN);
- }
- }
-
-
- public override DateTime AddMonths(DateTime time, int months) {
- return (helper.AddMonths(time, months));
- }
-
-
- public override DateTime AddYears(DateTime time, int years) {
- return (helper.AddYears(time, years));
- }
-
- /*=================================GetDaysInMonth==========================
- **Action: Returns the number of days in the month given by the year and month arguments.
- **Returns: The number of days in the given month.
- **Arguments:
- ** year The year in Japanese calendar.
- ** month The month
- ** era The Japanese era value.
- **Exceptions
- ** ArgumentException If month is less than 1 or greater * than 12.
- ============================================================================*/
-
-
- public override int GetDaysInMonth(int year, int month, int era) {
- return (helper.GetDaysInMonth(year, month, era));
- }
-
-
- public override int GetDaysInYear(int year, int era) {
- return (helper.GetDaysInYear(year, era));
- }
-
-
- public override int GetDayOfMonth(DateTime time) {
- return (helper.GetDayOfMonth(time));
- }
-
-
- public override DayOfWeek GetDayOfWeek(DateTime time) {
- return (helper.GetDayOfWeek(time));
- }
-
-
- public override int GetDayOfYear(DateTime time)
- {
- return (helper.GetDayOfYear(time));
- }
-
-
- public override int GetMonthsInYear(int year, int era)
- {
- return (helper.GetMonthsInYear(year, era));
- }
-
-
- [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
- public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
- {
- return (helper.GetWeekOfYear(time, rule, firstDayOfWeek));
- }
-
- /*=================================GetEra==========================
- **Action: Get the era value of the specified time.
- **Returns: The era value for the specified time.
- **Arguments:
- ** time the specified date time.
- **Exceptions: ArgumentOutOfRangeException if time is out of the valid era ranges.
- ============================================================================*/
-
-
- public override int GetEra(DateTime time) {
- return (helper.GetEra(time));
- }
-
-
- public override int GetMonth(DateTime time) {
- return (helper.GetMonth(time));
- }
-
-
- public override int GetYear(DateTime time) {
- return (helper.GetYear(time));
- }
-
-
- public override bool IsLeapDay(int year, int month, int day, int era)
- {
- return (helper.IsLeapDay(year, month, day, era));
- }
-
-
- public override bool IsLeapYear(int year, int era) {
- return (helper.IsLeapYear(year, era));
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
- public override int GetLeapMonth(int year, int era)
- {
- return (helper.GetLeapMonth(year, era));
- }
-
-
- public override bool IsLeapMonth(int year, int month, int era) {
- return (helper.IsLeapMonth(year, month, era));
- }
-
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) {
- return (helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era));
- }
-
- // For Japanese calendar, four digit year is not used. Few emperors will live for more than one hundred years.
- // Therefore, for any two digit number, we just return the original number.
-
- public override int ToFourDigitYear(int year) {
- if (year <= 0) {
- throw new ArgumentOutOfRangeException(nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
- }
- Contract.EndContractBlock();
-
- if (year > helper.MaxYear) {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 1,
- helper.MaxYear));
- }
- return (year);
- }
-
-
- public override int[] Eras {
- get {
- return (helper.Eras);
- }
- }
-
- //
- // Return the various era strings
- // Note: The arrays are backwards of the eras
- //
- internal static String[] EraNames()
- {
- EraInfo[] eras = GetEraInfo();
- String[] eraNames = new String[eras.Length];
-
- for (int i = 0; i < eras.Length; i++)
- {
- // Strings are in chronological order, eras are backwards order.
- eraNames[i] = eras[eras.Length - i - 1].eraName;
- }
-
- return eraNames;
- }
-
- internal static String[] AbbrevEraNames()
- {
- EraInfo[] eras = GetEraInfo();
- String[] erasAbbrev = new String[eras.Length];
-
- for (int i = 0; i < eras.Length; i++)
- {
- // Strings are in chronological order, eras are backwards order.
- erasAbbrev[i] = eras[eras.Length - i - 1].abbrevEraName;
- }
-
- return erasAbbrev;
- }
-
- internal static String[] EnglishEraNames()
- {
- EraInfo[] eras = GetEraInfo();
- String[] erasEnglish = new String[eras.Length];
-
- for (int i = 0; i < eras.Length; i++)
- {
- // Strings are in chronological order, eras are backwards order.
- erasEnglish[i] = eras[eras.Length - i - 1].englishEraName;
- }
-
- return erasEnglish;
- }
-
- private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 99;
-
- internal override bool IsValidYear(int year, int era) {
- return helper.IsValidYear(year, era);
- }
-
- public override int TwoDigitYearMax {
- get {
- if (twoDigitYearMax == -1) {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
- }
- return (twoDigitYearMax);
- }
-
- set {
- VerifyWritable();
- if (value < 99 || value > helper.MaxYear)
- {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 99,
- helper.MaxYear));
- }
- twoDigitYearMax = value;
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/JapaneseLunisolarCalendar.cs b/src/mscorlib/src/System/Globalization/JapaneseLunisolarCalendar.cs
deleted file mode 100644
index 67cfb23833..0000000000
--- a/src/mscorlib/src/System/Globalization/JapaneseLunisolarCalendar.cs
+++ /dev/null
@@ -1,293 +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.
-
-namespace System.Globalization {
- using System;
- using System.Diagnostics.Contracts;
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about JapaneseLunisolarCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
- /*
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 1960/01/28 2050/01/22
- ** JapaneseLunisolar 1960/01/01 2049/12/29
- */
-
- [Serializable]
- public class JapaneseLunisolarCalendar : EastAsianLunisolarCalendar {
-
- //
- // The era value for the current era.
- //
-
- public const int JapaneseEra = 1;
-
- internal GregorianCalendarHelper helper;
-
- internal const int MIN_LUNISOLAR_YEAR = 1960;
- internal const int MAX_LUNISOLAR_YEAR = 2049;
-
- internal const int MIN_GREGORIAN_YEAR = 1960;
- internal const int MIN_GREGORIAN_MONTH = 1;
- internal const int MIN_GREGORIAN_DAY = 28;
-
- internal const int MAX_GREGORIAN_YEAR = 2050;
- internal const int MAX_GREGORIAN_MONTH = 1;
- internal const int MAX_GREGORIAN_DAY = 22;
-
- internal static DateTime minDate = new DateTime(MIN_GREGORIAN_YEAR, MIN_GREGORIAN_MONTH, MIN_GREGORIAN_DAY);
- internal static DateTime maxDate = new DateTime((new DateTime(MAX_GREGORIAN_YEAR, MAX_GREGORIAN_MONTH, MAX_GREGORIAN_DAY, 23, 59, 59, 999)).Ticks + 9999);
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (minDate);
- }
- }
-
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (maxDate);
- }
- }
- protected override int DaysInYearBeforeMinSupportedYear
- {
- get
- {
- // 1959 from ChineseLunisolarCalendar
- return 354;
- }
- }
-
- static readonly int [,] yinfo =
- {
-/*Y LM Lmon Lday DaysPerMonth D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 #Days
-1960 */{ 6 , 1 , 28 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1961 */{ 0 , 2 , 15 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1962 */{ 0 , 2 , 5 , 19808 },/* 29 30 29 29 30 30 29 30 29 30 30 29 0 354
-1963 */{ 4 , 1 , 25 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1964 */{ 0 , 2 , 13 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1965 */{ 0 , 2 , 2 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
-1966 */{ 3 , 1 , 22 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 29 383
-1967 */{ 0 , 2 , 9 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1968 */{ 7 , 1 , 30 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
-1969 */{ 0 , 2 , 17 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1970 */{ 0 , 2 , 6 , 39632 },/* 30 29 29 30 30 29 30 29 30 30 29 30 0 355
-1971 */{ 5 , 1 , 27 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1972 */{ 0 , 2 , 15 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1973 */{ 0 , 2 , 3 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
-1974 */{ 4 , 1 , 23 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1975 */{ 0 , 2 , 11 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1976 */{ 8 , 1 , 31 , 54600 },/* 30 30 29 30 29 30 29 30 29 30 29 29 30 384
-1977 */{ 0 , 2 , 18 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1978 */{ 0 , 2 , 7 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 0 355
-1979 */{ 6 , 1 , 28 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1980 */{ 0 , 2 , 16 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1981 */{ 0 , 2 , 5 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1982 */{ 4 , 1 , 25 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1983 */{ 0 , 2 , 13 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1984 */{ 10 , 2 , 2 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1985 */{ 0 , 2 , 20 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1986 */{ 0 , 2 , 9 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1987 */{ 6 , 1 , 29 , 46504 },/* 30 29 30 30 29 30 29 30 30 29 30 29 30 385
-1988 */{ 0 , 2 , 18 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1989 */{ 0 , 2 , 6 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1990 */{ 5 , 1 , 27 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1991 */{ 0 , 2 , 15 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1992 */{ 0 , 2 , 4 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1993 */{ 3 , 1 , 23 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1994 */{ 0 , 2 , 10 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-1995 */{ 8 , 1 , 31 , 27976 },/* 29 30 30 29 30 30 29 30 29 30 29 29 30 384
-1996 */{ 0 , 2 , 19 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
-1997 */{ 0 , 2 , 8 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1998 */{ 5 , 1 , 28 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
-1999 */{ 0 , 2 , 16 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-2000 */{ 0 , 2 , 5 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-2001 */{ 4 , 1 , 24 , 58536 },/* 30 30 30 29 29 30 29 29 30 29 30 29 30 384
-2002 */{ 0 , 2 , 12 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-2003 */{ 0 , 2 , 1 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-2004 */{ 2 , 1 , 22 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-2005 */{ 0 , 2 , 9 , 22208 },/* 29 30 29 30 29 30 30 29 30 30 29 29 0 354
-2006 */{ 7 , 1 , 29 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
-2007 */{ 0 , 2 , 18 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-2008 */{ 0 , 2 , 7 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-2009 */{ 5 , 1 , 26 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-2010 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-2011 */{ 0 , 2 , 3 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-2012 */{ 3 , 1 , 23 , 47696 },/* 30 29 30 30 30 29 30 29 29 30 29 30 29 384
-2013 */{ 0 , 2 , 10 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-2014 */{ 9 , 1 , 31 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-2015 */{ 0 , 2 , 19 , 19360 },/* 29 30 29 29 30 29 30 30 30 29 30 29 0 354
-2016 */{ 0 , 2 , 8 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-2017 */{ 5 , 1 , 28 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-2018 */{ 0 , 2 , 16 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-2019 */{ 0 , 2 , 5 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-2020 */{ 4 , 1 , 25 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-2021 */{ 0 , 2 , 12 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-2022 */{ 0 , 2 , 1 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2023 */{ 2 , 1 , 22 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-2024 */{ 0 , 2 , 10 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-2025 */{ 6 , 1 , 29 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-2026 */{ 0 , 2 , 17 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-2027 */{ 0 , 2 , 7 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
-2028 */{ 5 , 1 , 27 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 29 383
-2029 */{ 0 , 2 , 13 , 55600 },/* 30 30 29 30 30 29 29 30 29 29 30 30 0 355
-2030 */{ 0 , 2 , 3 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-2031 */{ 3 , 1 , 23 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
-2032 */{ 0 , 2 , 11 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-2033 */{ 11 , 1 , 31 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-2034 */{ 0 , 2 , 19 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-2035 */{ 0 , 2 , 8 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-2036 */{ 6 , 1 , 28 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-2037 */{ 0 , 2 , 15 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-2038 */{ 0 , 2 , 4 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
-2039 */{ 5 , 1 , 24 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 29 384
-2040 */{ 0 , 2 , 12 , 46752 },/* 30 29 30 30 29 30 30 29 30 29 30 29 0 355
-2041 */{ 0 , 2 , 1 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-2042 */{ 2 , 1 , 22 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
-2043 */{ 0 , 2 , 10 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-2044 */{ 7 , 1 , 30 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-2045 */{ 0 , 2 , 17 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-2046 */{ 0 , 2 , 6 , 45648 },/* 30 29 30 30 29 29 30 29 29 30 29 30 0 354
-2047 */{ 5 , 1 , 26 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-2048 */{ 0 , 2 , 14 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-2049 */{ 0 , 2 , 2 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
- */ };
-
- internal override int MinCalendarYear {
- get
- {
- return (MIN_LUNISOLAR_YEAR);
- }
- }
-
- internal override int MaxCalendarYear {
- get
- {
- return (MAX_LUNISOLAR_YEAR);
- }
- }
-
- internal override DateTime MinDate {
- get
- {
- return (minDate);
- }
- }
-
- internal override DateTime MaxDate {
- get
- {
- return (maxDate);
- }
- }
-
- internal override EraInfo[] CalEraInfo {
- get
- {
- return (JapaneseCalendar.GetEraInfo());
- }
- }
-
- internal override int GetYearInfo(int LunarYear, int Index) {
- if ((LunarYear < MIN_LUNISOLAR_YEAR) || (LunarYear > MAX_LUNISOLAR_YEAR)) {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- MIN_LUNISOLAR_YEAR,
- MAX_LUNISOLAR_YEAR ));
- }
- Contract.EndContractBlock();
-
- return yinfo[LunarYear - MIN_LUNISOLAR_YEAR, Index];
- }
-
- internal override int GetYear(int year, DateTime time) {
- return helper.GetYear(year, time);
- }
-
- internal override int GetGregorianYear(int year, int era) {
- return helper.GetGregorianYear(year, era);
- }
-
- // Trim off the eras that are before our date range
- private static EraInfo[] TrimEras(EraInfo[] baseEras)
- {
- EraInfo[] newEras = new EraInfo[baseEras.Length];
- int newIndex = 0;
-
- // Eras have most recent first, so start with that
- for (int i = 0; i < baseEras.Length; i++)
- {
- // If this one's minimum year is bigger than our maximum year
- // then we can't use it.
- if (baseEras[i].yearOffset + baseEras[i].minEraYear >= MAX_LUNISOLAR_YEAR)
- {
- // skip this one.
- continue;
- }
-
- // If this one's maximum era is less than our minimum era
- // then we've gotten too low in the era #s, so we're done
- if (baseEras[i].yearOffset + baseEras[i].maxEraYear < MIN_LUNISOLAR_YEAR)
- {
- break;
- }
-
- // Wasn't too large or too small, can use this one
- newEras[newIndex] = baseEras[i];
- newIndex++;
- }
-
- // If we didn't copy any then something was wrong, just return base
- if (newIndex == 0) return baseEras;
-
- // Resize the output array
- Array.Resize(ref newEras, newIndex);
- return newEras;
- }
-
-
- // Construct an instance of JapaneseLunisolar calendar.
- public JapaneseLunisolarCalendar()
- {
- helper = new GregorianCalendarHelper(this, TrimEras(JapaneseCalendar.GetEraInfo()));
- }
-
-
- public override int GetEra(DateTime time) {
- return (helper.GetEra(time));
- }
-
- internal override int BaseCalendarID {
- get {
- return (CAL_JAPAN);
- }
- }
-
- internal override int ID {
- get {
- return (CAL_JAPANESELUNISOLAR);
- }
- }
-
-
- public override int[] Eras {
- get {
- return (helper.Eras);
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/JulianCalendar.cs b/src/mscorlib/src/System/Globalization/JulianCalendar.cs
deleted file mode 100644
index ff8801433c..0000000000
--- a/src/mscorlib/src/System/Globalization/JulianCalendar.cs
+++ /dev/null
@@ -1,436 +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.
-
-namespace System.Globalization {
-
- using System;
- using System.Diagnostics.Contracts;
- //
- // This class implements the Julian calendar. In 48 B.C. Julius Caesar ordered a calendar reform, and this calendar
- // is called Julian calendar. It consisted of a solar year of twelve months and of 365 days with an extra day
- // every fourth year.
- //*
- //* Calendar support range:
- //* Calendar Minimum Maximum
- //* ========== ========== ==========
- //* Gregorian 0001/01/01 9999/12/31
- //* Julia 0001/01/03 9999/10/19
-
- [Serializable]
- public class JulianCalendar : Calendar {
-
-
- public static readonly int JulianEra = 1;
-
- private const int DatePartYear = 0;
- private const int DatePartDayOfYear = 1;
- private const int DatePartMonth = 2;
- private const int DatePartDay = 3;
-
- // Number of days in a non-leap year
- private const int JulianDaysPerYear = 365;
- // Number of days in 4 years
- private const int JulianDaysPer4Years = JulianDaysPerYear * 4 + 1;
-
- //internal static Calendar m_defaultInstance;
-
- private static readonly int[] DaysToMonth365 =
- {
- 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
- };
-
- private static readonly int[] DaysToMonth366 =
- {
- 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366
- };
-
- // Gregorian Calendar 9999/12/31 = Julian Calendar 9999/10/19
- // keep it as variable field for serialization compat.
- internal int MaxYear = 9999;
-
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (DateTime.MinValue);
- }
- }
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (DateTime.MaxValue);
- }
- }
-
- // Return the type of the Julian calendar.
- //
-
- public override CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.SolarCalendar;
- }
- }
-
- /*=================================GetDefaultInstance==========================
- **Action: Internal method to provide a default intance of JulianCalendar. Used by NLS+ implementation
- ** and other calendars.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
- /*
- internal static Calendar GetDefaultInstance() {
- if (m_defaultInstance == null) {
- m_defaultInstance = new JulianCalendar();
- }
- return (m_defaultInstance);
- }
- */
-
- // Construct an instance of gregorian calendar.
-
- public JulianCalendar() {
- // There is no system setting of TwoDigitYear max, so set the value here.
- twoDigitYearMax = 2029;
- }
-
- internal override int ID {
- get {
- return (CAL_JULIAN);
- }
- }
-
- static internal void CheckEraRange(int era) {
- if (era != CurrentEra && era != JulianEra) {
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
- }
- }
-
- internal void CheckYearEraRange(int year, int era) {
- CheckEraRange(era);
- if (year <= 0 || year > MaxYear) {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 1,
- MaxYear));
- }
- }
-
- static internal void CheckMonthRange(int month) {
- if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
- }
- }
-
- /*=================================GetDefaultInstance==========================
- **Action: Check for if the day value is valid.
- **Returns:
- **Arguments:
- **Exceptions:
- **Notes:
- ** Before calling this method, call CheckYearEraRange()/CheckMonthRange() to make
- ** sure year/month values are correct.
- ============================================================================*/
-
- static internal void CheckDayRange(int year, int month, int day) {
- if (year == 1 && month == 1)
- {
- // The mimimum supported Julia date is Julian 0001/01/03.
- if (day < 3) {
- throw new ArgumentOutOfRangeException(null,
- Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
- }
- }
- bool isLeapYear = (year % 4) == 0;
- int[] days = isLeapYear ? DaysToMonth366 : DaysToMonth365;
- int monthDays = days[month] - days[month - 1];
- if (day < 1 || day > monthDays) {
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 1,
- monthDays));
- }
- }
-
-
- // Returns a given date part of this DateTime. This method is used
- // to compute the year, day-of-year, month, or day part.
- static internal int GetDatePart(long ticks, int part)
- {
- // Gregorian 1/1/0001 is Julian 1/3/0001. Remember DateTime(0) is refered to Gregorian 1/1/0001.
- // The following line convert Gregorian ticks to Julian ticks.
- long julianTicks = ticks + TicksPerDay * 2;
- // n = number of days since 1/1/0001
- int n = (int)(julianTicks / TicksPerDay);
- // y4 = number of whole 4-year periods within 100-year period
- int y4 = n / JulianDaysPer4Years;
- // n = day number within 4-year period
- n -= y4 * JulianDaysPer4Years;
- // y1 = number of whole years within 4-year period
- int y1 = n / JulianDaysPerYear;
- // Last year has an extra day, so decrement result if 4
- if (y1 == 4) y1 = 3;
- // If year was requested, compute and return it
- if (part == DatePartYear)
- {
- return (y4 * 4 + y1 + 1);
- }
- // n = day number within year
- n -= y1 * JulianDaysPerYear;
- // If day-of-year was requested, return it
- if (part == DatePartDayOfYear)
- {
- return (n + 1);
- }
- // Leap year calculation looks different from IsLeapYear since y1, y4,
- // and y100 are relative to year 1, not year 0
- bool leapYear = (y1 == 3);
- int[] days = leapYear? DaysToMonth366: DaysToMonth365;
- // All months have less than 32 days, so n >> 5 is a good conservative
- // estimate for the month
- int m = (n >> 5) + 1;
- // m = 1-based month number
- while (n >= days[m]) m++;
- // If month was requested, return it
- if (part == DatePartMonth) return (m);
- // Return 1-based day-of-month
- return (n - days[m - 1] + 1);
- }
-
- // Returns the tick count corresponding to the given year, month, and day.
- static internal long DateToTicks(int year, int month, int day)
- {
- int[] days = (year % 4 == 0)? DaysToMonth366: DaysToMonth365;
- int y = year - 1;
- int n = y * 365 + y / 4 + days[month - 1] + day - 1;
- // Gregorian 1/1/0001 is Julian 1/3/0001. n * TicksPerDay is the ticks in JulianCalendar.
- // Therefore, we subtract two days in the following to convert the ticks in JulianCalendar
- // to ticks in Gregorian calendar.
- return ((n - 2) * TicksPerDay);
- }
-
-
- public override DateTime AddMonths(DateTime time, int months)
- {
- if (months < -120000 || months > 120000) {
- throw new ArgumentOutOfRangeException(
- nameof(months),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- -120000,
- 120000));
- }
- Contract.EndContractBlock();
- int y = GetDatePart(time.Ticks, DatePartYear);
- int m = GetDatePart(time.Ticks, DatePartMonth);
- int d = GetDatePart(time.Ticks, DatePartDay);
- int i = m - 1 + months;
- if (i >= 0) {
- m = i % 12 + 1;
- y = y + i / 12;
- }
- else {
- m = 12 + (i + 1) % 12;
- y = y + (i - 11) / 12;
- }
- int[] daysArray = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? DaysToMonth366: DaysToMonth365;
- int days = (daysArray[m] - daysArray[m - 1]);
-
- if (d > days) {
- d = days;
- }
- long ticks = DateToTicks(y, m, d) + time.Ticks % TicksPerDay;
- Calendar.CheckAddResult(ticks, MinSupportedDateTime, MaxSupportedDateTime);
- return (new DateTime(ticks));
- }
-
-
- public override DateTime AddYears(DateTime time, int years) {
- return (AddMonths(time, years * 12));
- }
-
-
- public override int GetDayOfMonth(DateTime time) {
- return (GetDatePart(time.Ticks, DatePartDay));
- }
-
-
- public override DayOfWeek GetDayOfWeek(DateTime time) {
- return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
- }
-
-
- public override int GetDayOfYear(DateTime time) {
- return (GetDatePart(time.Ticks, DatePartDayOfYear));
- }
-
-
- public override int GetDaysInMonth(int year, int month, int era) {
- CheckYearEraRange(year, era);
- CheckMonthRange(month);
- int[] days = (year % 4 == 0) ? DaysToMonth366: DaysToMonth365;
- return (days[month] - days[month - 1]);
- }
-
-
- public override int GetDaysInYear(int year, int era) {
- // Year/Era range is done in IsLeapYear().
- return (IsLeapYear(year, era) ? 366:365);
- }
-
-
- public override int GetEra(DateTime time)
- {
- return (JulianEra);
- }
-
-
- public override int GetMonth(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartMonth));
- }
-
-
- public override int[] Eras {
- get {
- return (new int[] {JulianEra});
- }
- }
-
-
- public override int GetMonthsInYear(int year, int era)
- {
- CheckYearEraRange(year, era);
- return (12);
- }
-
-
- public override int GetYear(DateTime time)
- {
- return (GetDatePart(time.Ticks, DatePartYear));
- }
-
-
- public override bool IsLeapDay(int year, int month, int day, int era)
- {
- CheckMonthRange(month);
- // Year/Era range check is done in IsLeapYear().
- if (IsLeapYear(year, era)) {
- CheckDayRange(year, month, day);
- return (month == 2 && day == 29);
- }
- CheckDayRange(year, month, day);
- return (false);
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
- public override int GetLeapMonth(int year, int era)
- {
- CheckYearEraRange(year, era);
- return (0);
- }
-
-
- public override bool IsLeapMonth(int year, int month, int era)
- {
- CheckYearEraRange(year, era);
- CheckMonthRange(month);
- return (false);
- }
-
- // Checks whether a given year in the specified era is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
-
- public override bool IsLeapYear(int year, int era)
- {
- CheckYearEraRange(year, era);
- return (year % 4 == 0);
- }
-
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era)
- {
- CheckYearEraRange(year, era);
- CheckMonthRange(month);
- CheckDayRange(year, month, day);
- if (millisecond < 0 || millisecond >= MillisPerSecond) {
- throw new ArgumentOutOfRangeException(
- nameof(millisecond),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 0,
- MillisPerSecond - 1));
- }
-
- if (hour >= 0 && hour < 24 && minute >= 0 && minute < 60 && second >=0 && second < 60)
- {
- return new DateTime(DateToTicks(year, month, day) + (new TimeSpan(0, hour, minute, second, millisecond)).Ticks);
- } else
- {
- throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadHourMinuteSecond"));
- }
- }
-
-
- public override int TwoDigitYearMax {
- get {
- return (twoDigitYearMax);
- }
-
- set {
- VerifyWritable();
- if (value < 99 || value > MaxYear)
- {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 99,
- MaxYear));
-
- }
- twoDigitYearMax = value;
- }
- }
-
-
- public override int ToFourDigitYear(int year) {
- if (year < 0) {
- throw new ArgumentOutOfRangeException(nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- Contract.EndContractBlock();
-
- if (year > MaxYear) {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper"),
- 1,
- MaxYear));
- }
- return (base.ToFourDigitYear(year));
- }
- }
-
-}
diff --git a/src/mscorlib/src/System/Globalization/KoreanCalendar.cs b/src/mscorlib/src/System/Globalization/KoreanCalendar.cs
deleted file mode 100644
index 6c5a03b7e8..0000000000
--- a/src/mscorlib/src/System/Globalization/KoreanCalendar.cs
+++ /dev/null
@@ -1,259 +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.
-
-namespace System.Globalization {
-
- using System;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
-
- /*=================================KoreanCalendar==========================
- **
- ** Korean calendar is based on the Gregorian calendar. And the year is an offset to Gregorian calendar.
- ** That is,
- ** Korean year = Gregorian year + 2333. So 2000/01/01 A.D. is Korean 4333/01/01
- **
- ** 0001/1/1 A.D. is Korean year 2334.
- **
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 0001/01/01 9999/12/31
- ** Korean 2334/01/01 12332/12/31
- ============================================================================*/
-
-
- [Serializable] public class KoreanCalendar: Calendar {
- //
- // The era value for the current era.
- //
-
- public const int KoreanEra = 1;
-
- // Since
- // Gregorian Year = Era Year + yearOffset
- // Gregorian Year 1 is Korean year 2334, so that
- // 1 = 2334 + yearOffset
- // So yearOffset = -2333
- // Gregorian year 2001 is Korean year 4334.
-
- //m_EraInfo[0] = new EraInfo(1, new DateTime(1, 1, 1).Ticks, -2333, 2334, GregorianCalendar.MaxYear + 2333);
-
- // Initialize our era info.
- static internal EraInfo[] koreanEraInfo = new EraInfo[] {
- new EraInfo( 1, 1, 1, 1, -2333, 2334, GregorianCalendar.MaxYear + 2333) // era #, start year/month/day, yearOffset, minEraYear
- };
-
- internal GregorianCalendarHelper helper;
-
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (DateTime.MinValue);
- }
- }
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (DateTime.MaxValue);
- }
- }
-
- // Return the type of the Korean calendar.
- //
-
- public override CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.SolarCalendar;
- }
- }
-
- /*=================================GetDefaultInstance==========================
- **Action: Internal method to provide a default intance of KoreanCalendar. Used by NLS+ implementation
- ** and other calendars.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
- /*
- internal static Calendar GetDefaultInstance() {
- if (m_defaultInstance == null) {
- m_defaultInstance = new KoreanCalendar();
- }
- return (m_defaultInstance);
- }
- */
-
-
- public KoreanCalendar() {
- try {
- new CultureInfo("ko-KR");
- } catch (ArgumentException e) {
- throw new TypeInitializationException(this.GetType().FullName, e);
- }
- helper = new GregorianCalendarHelper(this, koreanEraInfo);
- }
-
- internal override int ID {
- get {
- return (CAL_KOREA);
- }
- }
-
-
- public override DateTime AddMonths(DateTime time, int months) {
- return (helper.AddMonths(time, months));
- }
-
-
- public override DateTime AddYears(DateTime time, int years) {
- return (helper.AddYears(time, years));
- }
-
- /*=================================GetDaysInMonth==========================
- **Action: Returns the number of days in the month given by the year and month arguments.
- **Returns: The number of days in the given month.
- **Arguments:
- ** year The year in Korean calendar.
- ** month The month
- ** era The Japanese era value.
- **Exceptions
- ** ArgumentException If month is less than 1 or greater * than 12.
- ============================================================================*/
-
-
- public override int GetDaysInMonth(int year, int month, int era) {
- return (helper.GetDaysInMonth(year, month, era));
- }
-
-
- public override int GetDaysInYear(int year, int era) {
- return (helper.GetDaysInYear(year, era));
- }
-
-
- public override int GetDayOfMonth(DateTime time) {
- return (helper.GetDayOfMonth(time));
- }
-
-
- public override DayOfWeek GetDayOfWeek(DateTime time) {
- return (helper.GetDayOfWeek(time));
- }
-
-
- public override int GetDayOfYear(DateTime time)
- {
- return (helper.GetDayOfYear(time));
- }
-
-
- public override int GetMonthsInYear(int year, int era) {
- return (helper.GetMonthsInYear(year, era));
- }
-
-
- [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
- public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
- {
- return (helper.GetWeekOfYear(time, rule, firstDayOfWeek));
- }
-
-
- public override int GetEra(DateTime time) {
- return (helper.GetEra(time));
- }
-
- public override int GetMonth(DateTime time) {
- return (helper.GetMonth(time));
- }
-
-
- public override int GetYear(DateTime time) {
- return (helper.GetYear(time));
- }
-
-
- public override bool IsLeapDay(int year, int month, int day, int era)
- {
- return (helper.IsLeapDay(year, month, day, era));
- }
-
-
- public override bool IsLeapYear(int year, int era) {
- return (helper.IsLeapYear(year, era));
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
- public override int GetLeapMonth(int year, int era)
- {
- return (helper.GetLeapMonth(year, era));
- }
-
-
- public override bool IsLeapMonth(int year, int month, int era) {
- return (helper.IsLeapMonth(year, month, era));
- }
-
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) {
- return (helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era));
- }
-
-
- public override int[] Eras {
- get {
- return (helper.Eras);
- }
- }
-
- private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 4362;
-
-
- public override int TwoDigitYearMax {
- get {
- if (twoDigitYearMax == -1) {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
- }
- return (twoDigitYearMax);
- }
-
- set {
- VerifyWritable();
- if (value < 99 || value > helper.MaxYear)
- {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 99,
- helper.MaxYear));
-
- }
- twoDigitYearMax = value;
- }
- }
-
-
- public override int ToFourDigitYear(int year) {
- if (year < 0) {
- throw new ArgumentOutOfRangeException(nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- Contract.EndContractBlock();
-
- return (helper.ToFourDigitYear(year, this.TwoDigitYearMax));
- }
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/KoreanLunisolarCalendar.cs b/src/mscorlib/src/System/Globalization/KoreanLunisolarCalendar.cs
deleted file mode 100644
index 9e36b435e7..0000000000
--- a/src/mscorlib/src/System/Globalization/KoreanLunisolarCalendar.cs
+++ /dev/null
@@ -1,1334 +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.
-
-namespace System.Globalization {
- using System;
- using System.Diagnostics.Contracts;
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about KoreanLunisolarCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
- /*
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 918/02/14 2051/02/10
- ** KoreanLunisolar 918/01/01 2050/13/29
- */
-
- [Serializable]
- public class KoreanLunisolarCalendar : EastAsianLunisolarCalendar {
-
-
- //
- // The era value for the current era.
- //
-
- public const int GregorianEra = 1;
-
- //internal static Calendar m_defaultInstance;
-
- internal const int MIN_LUNISOLAR_YEAR = 918;
- internal const int MAX_LUNISOLAR_YEAR = 2050;
-
- internal const int MIN_GREGORIAN_YEAR = 918;
- internal const int MIN_GREGORIAN_MONTH = 2;
- internal const int MIN_GREGORIAN_DAY = 14;
-
- internal const int MAX_GREGORIAN_YEAR = 2051;
- internal const int MAX_GREGORIAN_MONTH = 2;
- internal const int MAX_GREGORIAN_DAY = 10;
-
- internal static DateTime minDate = new DateTime(MIN_GREGORIAN_YEAR, MIN_GREGORIAN_MONTH, MIN_GREGORIAN_DAY);
- internal static DateTime maxDate = new DateTime((new DateTime(MAX_GREGORIAN_YEAR, MAX_GREGORIAN_MONTH, MAX_GREGORIAN_DAY, 23, 59, 59, 999)).Ticks + 9999);
-
- public override DateTime MinSupportedDateTime {
- get
- {
- return (minDate);
- }
- }
-
-
-
- public override DateTime MaxSupportedDateTime {
- get
- {
- return (maxDate);
- }
- }
-
- protected override int DaysInYearBeforeMinSupportedYear
- {
- get
- {
- // 917 -- From http://emr.cs.iit.edu/home/reingold/calendar-book/Calendrica.html
- // using ChineseLunisolar
- return 384;
- }
- }
-
- static readonly int [,] yinfo =
- {
-/*Y LM Lmon Lday DaysPerMonth D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 #Days
-918 */{ 0 , 2 , 14 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-919 */{ 0 , 2 , 4 , 17872 },/* 29 30 29 29 29 30 29 30 30 30 29 30 0 354
-920 */{ 6 , 1 , 24 , 41688 },/* 30 29 30 29 29 29 30 29 30 30 29 30 30 384
-921 */{ 0 , 2 , 11 , 41648 },/* 30 29 30 29 29 29 30 29 30 29 30 30 0 354
-922 */{ 0 , 1 , 31 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-923 */{ 4 , 1 , 20 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-924 */{ 0 , 2 , 8 , 27936 },/* 29 30 30 29 30 30 29 30 29 29 30 29 0 354
-925 */{ 12 , 1 , 27 , 44384 },/* 30 29 30 29 30 30 29 30 29 30 30 29 29 384
-926 */{ 0 , 2 , 15 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-927 */{ 0 , 2 , 5 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-928 */{ 8 , 1 , 26 , 17848 },/* 29 30 29 29 29 30 29 30 30 29 30 30 30 384
-929 */{ 0 , 2 , 13 , 17776 },/* 29 30 29 29 29 30 29 30 29 30 30 30 0 354
-930 */{ 0 , 2 , 2 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-931 */{ 5 , 1 , 22 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 29 383
-932 */{ 0 , 2 , 9 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
-933 */{ 0 , 1 , 29 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-934 */{ 1 , 1 , 18 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-935 */{ 0 , 2 , 6 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-936 */{ 11 , 1 , 27 , 21344 },/* 29 30 29 30 29 29 30 30 29 30 30 29 29 383
-937 */{ 0 , 2 , 13 , 51904 },/* 30 30 29 29 30 29 30 29 30 30 29 29 0 354
-938 */{ 0 , 2 , 2 , 58720 },/* 30 30 30 29 29 30 29 30 29 30 30 29 0 355
-939 */{ 7 , 1 , 23 , 53928 },/* 30 30 29 30 29 29 30 29 30 29 30 29 30 384
-940 */{ 0 , 2 , 11 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
-941 */{ 0 , 1 , 30 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-942 */{ 3 , 1 , 20 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-943 */{ 0 , 2 , 8 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-944 */{ 12 , 1 , 28 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 29 384
-945 */{ 0 , 2 , 15 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-946 */{ 0 , 2 , 5 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
-947 */{ 7 , 1 , 25 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-948 */{ 0 , 2 , 13 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-949 */{ 0 , 2 , 1 , 45664 },/* 30 29 30 30 29 29 30 29 29 30 30 29 0 354
-950 */{ 5 , 1 , 21 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-951 */{ 0 , 2 , 9 , 45936 },/* 30 29 30 30 29 30 29 30 29 30 29 0 0 325
-952 */{ 0 , 12 , 31 , 43728 },/* 30 29 30 29 30 29 30 29 30 30 29 30 29 384
-953 */{ 1 , 1 , 18 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 29 384
-954 */{ 0 , 2 , 6 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-955 */{ 9 , 1 , 27 , 19128 },/* 29 30 29 29 30 29 30 29 30 29 30 30 30 384
-956 */{ 0 , 2 , 15 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-957 */{ 0 , 2 , 3 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-958 */{ 7 , 1 , 23 , 43672 },/* 30 29 30 29 30 29 30 29 30 29 29 30 30 384
-959 */{ 0 , 2 , 11 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-960 */{ 0 , 1 , 31 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-961 */{ 3 , 1 , 20 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
-962 */{ 0 , 2 , 8 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-963 */{ 12 , 1 , 28 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 29 384
-964 */{ 0 , 2 , 16 , 41840 },/* 30 29 30 29 29 29 30 30 29 30 30 30 0 355
-965 */{ 0 , 2 , 5 , 20848 },/* 29 30 29 30 29 29 29 30 29 30 30 30 0 354
-966 */{ 8 , 1 , 25 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
-967 */{ 0 , 2 , 12 , 54448 },/* 30 30 29 30 29 30 29 29 30 29 30 30 0 355
-968 */{ 0 , 2 , 2 , 23184 },/* 29 30 29 30 30 29 30 29 30 29 29 30 0 354
-969 */{ 5 , 1 , 21 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
-970 */{ 0 , 2 , 9 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-971 */{ 0 , 1 , 30 , 10976 },/* 29 29 30 29 30 29 30 29 30 30 30 29 0 354
-972 */{ 2 , 1 , 19 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
-973 */{ 0 , 2 , 6 , 41696 },/* 30 29 30 29 29 29 30 29 30 30 30 29 0 354
-974 */{ 10 , 1 , 26 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-975 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-976 */{ 0 , 2 , 3 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-977 */{ 7 , 1 , 22 , 55952 },/* 30 30 29 30 30 29 30 29 30 29 29 30 29 384
-978 */{ 0 , 2 , 10 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
-979 */{ 0 , 1 , 31 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-980 */{ 3 , 1 , 21 , 10968 },/* 29 29 30 29 30 29 30 29 30 30 29 30 30 384
-981 */{ 0 , 2 , 8 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-982 */{ 12 , 1 , 28 , 37592 },/* 30 29 29 30 29 29 30 29 30 30 29 30 30 384
-983 */{ 0 , 2 , 16 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
-984 */{ 0 , 2 , 5 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-985 */{ 9 , 1 , 24 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-986 */{ 0 , 2 , 12 , 44192 },/* 30 29 30 29 30 30 29 29 30 29 30 29 0 354
-987 */{ 0 , 2 , 1 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-988 */{ 5 , 1 , 22 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-989 */{ 0 , 2 , 9 , 19376 },/* 29 30 29 29 30 29 30 30 30 29 30 30 0 355
-990 */{ 0 , 1 , 30 , 9648 },/* 29 29 30 29 29 30 29 30 30 29 30 30 0 354
-991 */{ 2 , 1 , 19 , 37560 },/* 30 29 29 30 29 29 30 29 30 29 30 30 30 384
-992 */{ 0 , 2 , 7 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-993 */{ 10 , 1 , 26 , 26968 },/* 29 30 30 29 30 29 29 30 29 30 29 30 30 384
-994 */{ 0 , 2 , 14 , 22864 },/* 29 30 29 30 30 29 29 30 29 30 29 30 0 354
-995 */{ 0 , 2 , 3 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-996 */{ 7 , 1 , 23 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
-997 */{ 0 , 2 , 10 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-998 */{ 0 , 1 , 31 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-999 */{ 3 , 1 , 20 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1000 */{ 0 , 2 , 8 , 9584 },/* 29 29 30 29 29 30 29 30 29 30 30 30 0 354
-1001 */{ 12 , 1 , 28 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 29 383
-1002 */{ 0 , 2 , 15 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
-1003 */{ 0 , 2 , 4 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1004 */{ 9 , 1 , 25 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1005 */{ 0 , 2 , 12 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1006 */{ 0 , 2 , 1 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-1007 */{ 5 , 1 , 22 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1008 */{ 0 , 2 , 10 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
-1009 */{ 0 , 1 , 29 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1010 */{ 2 , 1 , 18 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1011 */{ 0 , 2 , 6 , 45664 },/* 30 29 30 30 29 29 30 29 29 30 30 29 0 354
-1012 */{ 10 , 1 , 26 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1013 */{ 0 , 2 , 13 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1014 */{ 0 , 2 , 3 , 13728 },/* 29 29 30 30 29 30 29 30 30 29 30 29 0 354
-1015 */{ 6 , 1 , 23 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 29 384
-1016 */{ 0 , 2 , 11 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1017 */{ 0 , 1 , 31 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1018 */{ 4 , 1 , 20 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1019 */{ 0 , 2 , 8 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1020 */{ 12 , 1 , 28 , 43608 },/* 30 29 30 29 30 29 30 29 29 30 29 30 30 384
-1021 */{ 0 , 2 , 15 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1022 */{ 0 , 2 , 4 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1023 */{ 9 , 1 , 25 , 11688 },/* 29 29 30 29 30 30 29 30 30 29 30 29 30 384
-1024 */{ 0 , 2 , 13 , 11088 },/* 29 29 30 29 30 29 30 30 29 30 29 30 0 354
-1025 */{ 0 , 2 , 1 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 0 355
-1026 */{ 5 , 1 , 22 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 29 383
-1027 */{ 0 , 2 , 9 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 0 355
-1028 */{ 0 , 1 , 30 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1029 */{ 2 , 1 , 18 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1030 */{ 0 , 2 , 5 , 55952 },/* 30 30 29 30 30 29 30 29 30 29 29 30 0 355
-1031 */{ 10 , 1 , 26 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
-1032 */{ 0 , 2 , 14 , 26320 },/* 29 30 30 29 29 30 30 29 30 30 29 30 0 355
-1033 */{ 0 , 2 , 3 , 9952 },/* 29 29 30 29 29 30 30 29 30 30 30 29 0 354
-1034 */{ 6 , 1 , 23 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
-1035 */{ 0 , 2 , 11 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1036 */{ 0 , 1 , 31 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1037 */{ 4 , 1 , 19 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1038 */{ 0 , 2 , 7 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1039 */{ 12 , 1 , 27 , 54928 },/* 30 30 29 30 29 30 30 29 30 29 29 30 29 384
-1040 */{ 0 , 2 , 15 , 46464 },/* 30 29 30 30 29 30 29 30 30 29 29 29 0 354
-1041 */{ 0 , 2 , 3 , 54960 },/* 30 30 29 30 29 30 30 29 30 29 30 30 0 356
-1042 */{ 9 , 1 , 25 , 9944 },/* 29 29 30 29 29 30 30 29 30 30 29 30 30 384
-1043 */{ 0 , 2 , 13 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1044 */{ 0 , 2 , 2 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
-1045 */{ 5 , 1 , 21 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1046 */{ 0 , 2 , 9 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1047 */{ 0 , 1 , 29 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1048 */{ 1 , 1 , 18 , 46424 },/* 30 29 30 30 29 30 29 30 29 30 29 30 30 385
-1049 */{ 0 , 2 , 6 , 11600 },/* 29 29 30 29 30 30 29 30 29 30 29 30 0 354
-1050 */{ 11 , 1 , 26 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-1051 */{ 0 , 2 , 14 , 19376 },/* 29 30 29 29 30 29 30 30 30 29 30 30 0 355
-1052 */{ 0 , 2 , 4 , 9648 },/* 29 29 30 29 29 30 29 30 30 29 30 30 0 354
-1053 */{ 7 , 1 , 23 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1054 */{ 0 , 2 , 11 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1055 */{ 0 , 1 , 31 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1056 */{ 3 , 1 , 20 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
-1057 */{ 0 , 2 , 7 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1058 */{ 12 , 1 , 27 , 43864 },/* 30 29 30 29 30 29 30 30 29 30 29 30 30 385
-1059 */{ 0 , 2 , 16 , 10064 },/* 29 29 30 29 29 30 30 30 29 30 29 30 0 354
-1060 */{ 0 , 2 , 5 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1061 */{ 8 , 1 , 24 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1062 */{ 0 , 2 , 12 , 42336 },/* 30 29 30 29 29 30 29 30 29 30 30 29 0 354
-1063 */{ 0 , 2 , 1 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1064 */{ 5 , 1 , 21 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-1065 */{ 0 , 2 , 8 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1066 */{ 0 , 1 , 29 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1067 */{ 1 , 1 , 18 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
-1068 */{ 0 , 2 , 6 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-1069 */{ 11 , 1 , 26 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1070 */{ 0 , 2 , 14 , 18896 },/* 29 30 29 29 30 29 29 30 30 30 29 30 0 354
-1071 */{ 0 , 2 , 3 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1072 */{ 7 , 1 , 23 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1073 */{ 0 , 2 , 10 , 43616 },/* 30 29 30 29 30 29 30 29 29 30 30 29 0 354
-1074 */{ 0 , 1 , 30 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1075 */{ 4 , 1 , 20 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1076 */{ 0 , 2 , 8 , 13728 },/* 29 29 30 30 29 30 29 30 30 29 30 29 0 354
-1077 */{ 0 , 1 , 27 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1078 */{ 1 , 1 , 17 , 19352 },/* 29 30 29 29 30 29 30 30 30 29 29 30 30 384
-1079 */{ 0 , 2 , 5 , 17840 },/* 29 30 29 29 29 30 29 30 30 29 30 30 0 354
-1080 */{ 9 , 1 , 25 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-1081 */{ 0 , 2 , 12 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1082 */{ 0 , 2 , 1 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1083 */{ 6 , 1 , 21 , 46408 },/* 30 29 30 30 29 30 29 30 29 30 29 29 30 384
-1084 */{ 0 , 2 , 9 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 0 355
-1085 */{ 0 , 1 , 29 , 11680 },/* 29 29 30 29 30 30 29 30 30 29 30 29 0 354
-1086 */{ 2 , 1 , 18 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 29 384
-1087 */{ 0 , 2 , 6 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1088 */{ 12 , 1 , 27 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 29 383
-1089 */{ 0 , 2 , 13 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 0 355
-1090 */{ 0 , 2 , 3 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1091 */{ 8 , 1 , 23 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1092 */{ 0 , 2 , 10 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-1093 */{ 0 , 1 , 30 , 23360 },/* 29 30 29 30 30 29 30 30 29 30 29 29 0 354
-1094 */{ 4 , 1 , 19 , 43880 },/* 30 29 30 29 30 29 30 30 29 30 30 29 30 385
-1095 */{ 0 , 2 , 8 , 10976 },/* 29 29 30 29 30 29 30 29 30 30 30 29 0 354
-1096 */{ 0 , 1 , 28 , 58896 },/* 30 30 30 29 29 30 30 29 29 29 29 30 0 354
-1097 */{ 2 , 1 , 16 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 29 384
-1098 */{ 0 , 2 , 4 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1099 */{ 9 , 1 , 24 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1100 */{ 0 , 2 , 12 , 21664 },/* 29 30 29 30 29 30 29 29 30 29 30 29 0 353
-1101 */{ 0 , 1 , 31 , 54864 },/* 30 30 29 30 29 30 30 29 29 30 29 30 0 355
-1102 */{ 6 , 1 , 21 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1103 */{ 0 , 2 , 9 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
-1104 */{ 0 , 1 , 30 , 9936 },/* 29 29 30 29 29 30 30 29 30 30 29 30 0 354
-1105 */{ 2 , 1 , 18 , 37608 },/* 30 29 29 30 29 29 30 29 30 30 30 29 30 384
-1106 */{ 0 , 2 , 6 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
-1107 */{ 10 , 1 , 26 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1108 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1109 */{ 0 , 2 , 2 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1110 */{ 8 , 1 , 22 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1111 */{ 0 , 2 , 10 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1112 */{ 0 , 1 , 31 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-1113 */{ 4 , 1 , 20 , 9656 },/* 29 29 30 29 29 30 29 30 30 29 30 30 30 384
-1114 */{ 0 , 2 , 8 , 17776 },/* 29 30 29 29 29 30 29 30 29 30 30 30 0 354
-1115 */{ 0 , 1 , 28 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1116 */{ 1 , 1 , 17 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1117 */{ 0 , 2 , 4 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1118 */{ 9 , 1 , 24 , 29352 },/* 29 30 30 30 29 29 30 29 30 29 30 29 30 384
-1119 */{ 0 , 2 , 12 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1120 */{ 0 , 2 , 1 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1121 */{ 5 , 1 , 21 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
-1122 */{ 0 , 2 , 9 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1123 */{ 0 , 1 , 29 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1124 */{ 3 , 1 , 19 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 29 383
-1125 */{ 0 , 2 , 5 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1126 */{ 11 , 1 , 25 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-1127 */{ 0 , 2 , 13 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1128 */{ 0 , 2 , 3 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1129 */{ 8 , 1 , 22 , 39824 },/* 30 29 29 30 30 29 30 30 30 29 29 30 29 384
-1130 */{ 0 , 2 , 10 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-1131 */{ 0 , 1 , 31 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1132 */{ 4 , 1 , 20 , 42216 },/* 30 29 30 29 29 30 29 29 30 30 30 29 30 384
-1133 */{ 0 , 2 , 7 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1134 */{ 0 , 1 , 27 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1135 */{ 2 , 1 , 16 , 55592 },/* 30 30 29 30 30 29 29 30 29 29 30 29 30 384
-1136 */{ 0 , 2 , 4 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1137 */{ 10 , 1 , 23 , 54952 },/* 30 30 29 30 29 30 30 29 30 29 30 29 30 385
-1138 */{ 0 , 2 , 12 , 11680 },/* 29 29 30 29 30 30 29 30 30 29 30 29 0 354
-1139 */{ 0 , 2 , 1 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1140 */{ 6 , 1 , 22 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
-1141 */{ 0 , 2 , 9 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1142 */{ 0 , 1 , 29 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1143 */{ 4 , 1 , 18 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1144 */{ 0 , 2 , 6 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1145 */{ 11 , 1 , 25 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-1146 */{ 0 , 2 , 13 , 27456 },/* 29 30 30 29 30 29 30 30 29 30 29 29 0 354
-1147 */{ 0 , 2 , 2 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1148 */{ 8 , 1 , 23 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 29 384
-1149 */{ 0 , 2 , 10 , 39280 },/* 30 29 29 30 30 29 29 30 29 30 30 30 0 355
-1150 */{ 0 , 1 , 31 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1151 */{ 4 , 1 , 20 , 25784 },/* 29 30 30 29 29 30 29 29 30 29 30 30 30 384
-1152 */{ 0 , 2 , 8 , 21680 },/* 29 30 29 30 29 30 29 29 30 29 30 30 0 354
-1153 */{ 12 , 1 , 27 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1154 */{ 0 , 2 , 14 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-1155 */{ 0 , 2 , 4 , 23232 },/* 29 30 29 30 30 29 30 29 30 30 29 29 0 354
-1156 */{ 10 , 1 , 24 , 43880 },/* 30 29 30 29 30 29 30 30 29 30 30 29 30 385
-1157 */{ 0 , 2 , 12 , 9952 },/* 29 29 30 29 29 30 30 29 30 30 30 29 0 354
-1158 */{ 0 , 2 , 1 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1159 */{ 6 , 1 , 21 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 29 384
-1160 */{ 0 , 2 , 9 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1161 */{ 0 , 1 , 28 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1162 */{ 2 , 1 , 17 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1163 */{ 0 , 2 , 5 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1164 */{ 11 , 1 , 26 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1165 */{ 0 , 2 , 13 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-1166 */{ 0 , 2 , 3 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1167 */{ 7 , 1 , 23 , 37608 },/* 30 29 29 30 29 29 30 29 30 30 30 29 30 384
-1168 */{ 0 , 2 , 11 , 37488 },/* 30 29 29 30 29 29 30 29 29 30 30 30 0 354
-1169 */{ 0 , 1 , 30 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1170 */{ 5 , 1 , 19 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1171 */{ 0 , 2 , 7 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1172 */{ 0 , 1 , 27 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1173 */{ 1 , 1 , 16 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1174 */{ 0 , 2 , 4 , 19888 },/* 29 30 29 29 30 30 29 30 30 29 30 30 0 355
-1175 */{ 9 , 1 , 25 , 9648 },/* 29 29 30 29 29 30 29 30 30 29 30 30 29 383
-1176 */{ 0 , 2 , 12 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1177 */{ 0 , 2 , 1 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1178 */{ 6 , 1 , 21 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1179 */{ 0 , 2 , 9 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1180 */{ 0 , 1 , 29 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1181 */{ 3 , 1 , 17 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1182 */{ 0 , 2 , 5 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1183 */{ 11 , 1 , 26 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
-1184 */{ 0 , 2 , 14 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1185 */{ 0 , 2 , 2 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1186 */{ 7 , 1 , 23 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 29 383
-1187 */{ 0 , 2 , 10 , 53392 },/* 30 30 29 30 29 29 30 29 29 30 30 0 0 325
-1188 */{ 0 , 1 , 1 , 29848 },/* 29 30 30 30 29 30 29 29 30 29 29 30 30 384
-1189 */{ 5 , 1 , 19 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
-1190 */{ 0 , 2 , 7 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1191 */{ 0 , 1 , 27 , 39760 },/* 30 29 29 30 30 29 30 30 29 30 29 30 0 355
-1192 */{ 2 , 1 , 17 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
-1193 */{ 0 , 2 , 4 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1194 */{ 10 , 1 , 24 , 42216 },/* 30 29 30 29 29 30 29 29 30 30 30 29 30 384
-1195 */{ 0 , 2 , 12 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1196 */{ 0 , 2 , 1 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1197 */{ 6 , 1 , 20 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
-1198 */{ 0 , 2 , 8 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1199 */{ 0 , 1 , 28 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 0 355
-1200 */{ 2 , 1 , 18 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
-1201 */{ 0 , 2 , 5 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1202 */{ 12 , 1 , 26 , 18904 },/* 29 30 29 29 30 29 29 30 30 30 29 30 30 384
-1203 */{ 0 , 2 , 14 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1204 */{ 0 , 2 , 3 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1205 */{ 8 , 1 , 22 , 43608 },/* 30 29 30 29 30 29 30 29 29 30 29 30 30 384
-1206 */{ 0 , 2 , 10 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1207 */{ 0 , 1 , 30 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1208 */{ 4 , 1 , 19 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 29 384
-1209 */{ 0 , 2 , 6 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1210 */{ 0 , 1 , 27 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1211 */{ 2 , 1 , 17 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1212 */{ 0 , 2 , 5 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1213 */{ 9 , 1 , 24 , 25784 },/* 29 30 30 29 29 30 29 29 30 29 30 30 30 384
-1214 */{ 0 , 2 , 12 , 21680 },/* 29 30 29 30 29 30 29 29 30 29 30 30 0 354
-1215 */{ 0 , 2 , 1 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1216 */{ 7 , 1 , 21 , 27944 },/* 29 30 30 29 30 30 29 30 29 29 30 29 30 384
-1217 */{ 0 , 2 , 8 , 23232 },/* 29 30 29 30 30 29 30 29 30 30 29 29 0 354
-1218 */{ 0 , 1 , 28 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1219 */{ 3 , 1 , 18 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
-1220 */{ 0 , 2 , 6 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1221 */{ 12 , 1 , 25 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 29 384
-1222 */{ 0 , 2 , 13 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1223 */{ 0 , 2 , 2 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1224 */{ 8 , 1 , 22 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1225 */{ 0 , 2 , 9 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1226 */{ 0 , 1 , 30 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1227 */{ 5 , 1 , 19 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
-1228 */{ 0 , 2 , 8 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1229 */{ 0 , 1 , 27 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1230 */{ 2 , 1 , 16 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-1231 */{ 0 , 2 , 4 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1232 */{ 9 , 1 , 24 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1233 */{ 0 , 2 , 11 , 45728 },/* 30 29 30 30 29 29 30 29 30 29 30 29 0 354
-1234 */{ 0 , 1 , 31 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1235 */{ 7 , 1 , 21 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1236 */{ 0 , 2 , 9 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
-1237 */{ 0 , 1 , 28 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-1238 */{ 4 , 1 , 18 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1239 */{ 0 , 2 , 6 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1240 */{ 12 , 1 , 26 , 43320 },/* 30 29 30 29 30 29 29 30 29 29 30 30 30 384
-1241 */{ 0 , 2 , 13 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 0 354
-1242 */{ 0 , 2 , 2 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1243 */{ 8 , 1 , 22 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1244 */{ 0 , 2 , 10 , 44624 },/* 30 29 30 29 30 30 30 29 29 30 29 30 0 355
-1245 */{ 0 , 1 , 30 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1246 */{ 4 , 1 , 19 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1247 */{ 0 , 2 , 7 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1248 */{ 0 , 1 , 28 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
-1249 */{ 2 , 1 , 16 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 29 383
-1250 */{ 0 , 2 , 3 , 58672 },/* 30 30 30 29 29 30 29 30 29 29 30 30 0 355
-1251 */{ 10 , 1 , 24 , 27800 },/* 29 30 30 29 30 30 29 29 30 29 29 30 30 384
-1252 */{ 0 , 2 , 12 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1253 */{ 0 , 1 , 31 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
-1254 */{ 6 , 1 , 21 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
-1255 */{ 0 , 2 , 9 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1256 */{ 0 , 1 , 29 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
-1257 */{ 4 , 1 , 17 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1258 */{ 0 , 2 , 5 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1259 */{ 11 , 1 , 25 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
-1260 */{ 0 , 2 , 13 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1261 */{ 0 , 2 , 1 , 46752 },/* 30 29 30 30 29 30 30 29 30 29 30 29 0 355
-1262 */{ 9 , 1 , 22 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
-1263 */{ 0 , 2 , 10 , 21872 },/* 29 30 29 30 29 30 29 30 29 30 30 30 0 355
-1264 */{ 0 , 1 , 31 , 18896 },/* 29 30 29 29 30 29 29 30 30 30 29 30 0 354
-1265 */{ 5 , 1 , 19 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1266 */{ 0 , 2 , 7 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1267 */{ 0 , 1 , 27 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1268 */{ 1 , 1 , 16 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-1269 */{ 0 , 2 , 3 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1270 */{ 11 , 1 , 23 , 46528 },/* 30 29 30 30 29 30 29 30 30 30 29 29 29 384
-1271 */{ 0 , 2 , 11 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1272 */{ 0 , 2 , 1 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1273 */{ 6 , 1 , 21 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1274 */{ 0 , 2 , 9 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1275 */{ 0 , 1 , 29 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1276 */{ 3 , 1 , 18 , 27224 },/* 29 30 30 29 30 29 30 29 29 30 29 30 30 384
-1277 */{ 0 , 2 , 5 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1278 */{ 11 , 1 , 25 , 27432 },/* 29 30 30 29 30 29 30 30 29 29 30 29 30 384
-1279 */{ 0 , 2 , 13 , 23232 },/* 29 30 29 30 30 29 30 29 30 30 29 29 0 354
-1280 */{ 0 , 2 , 2 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1281 */{ 8 , 1 , 22 , 10984 },/* 29 29 30 29 30 29 30 29 30 30 30 29 30 384
-1282 */{ 0 , 2 , 10 , 18912 },/* 29 30 29 29 30 29 29 30 30 30 30 29 0 354
-1283 */{ 0 , 1 , 30 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1284 */{ 5 , 1 , 19 , 53848 },/* 30 30 29 30 29 29 30 29 29 30 29 30 30 384
-1285 */{ 0 , 2 , 6 , 45648 },/* 30 29 30 30 29 29 30 29 29 30 29 30 0 354
-1286 */{ 0 , 1 , 26 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1287 */{ 2 , 1 , 15 , 62096 },/* 30 30 30 30 29 29 30 29 30 29 29 30 29 384
-1288 */{ 0 , 2 , 3 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
-1289 */{ 10 , 1 , 23 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 29 384
-1290 */{ 0 , 2 , 11 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1291 */{ 0 , 2 , 1 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1292 */{ 6 , 1 , 21 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-1293 */{ 0 , 2 , 8 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1294 */{ 0 , 1 , 28 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1295 */{ 4 , 1 , 17 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-1296 */{ 0 , 2 , 5 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1297 */{ 12 , 1 , 24 , 44384 },/* 30 29 30 29 30 30 29 30 29 30 30 29 29 384
-1298 */{ 0 , 2 , 12 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1299 */{ 0 , 2 , 2 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1300 */{ 8 , 1 , 23 , 2424 },/* 29 29 29 29 30 29 29 30 29 30 30 30 30 383
-1301 */{ 0 , 2 , 10 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1302 */{ 0 , 1 , 30 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1303 */{ 5 , 1 , 19 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1304 */{ 0 , 2 , 6 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-1305 */{ 0 , 1 , 26 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1306 */{ 1 , 1 , 15 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 29 384
-1307 */{ 0 , 2 , 3 , 42720 },/* 30 29 30 29 29 30 30 29 30 30 30 29 0 355
-1308 */{ 11 , 1 , 24 , 37608 },/* 30 29 29 30 29 29 30 29 30 30 30 29 30 384
-1309 */{ 0 , 2 , 11 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1310 */{ 0 , 1 , 31 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1311 */{ 7 , 1 , 20 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1312 */{ 0 , 2 , 8 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1313 */{ 0 , 1 , 27 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1314 */{ 3 , 1 , 17 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1315 */{ 0 , 2 , 5 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1316 */{ 0 , 1 , 25 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
-1317 */{ 1 , 1 , 14 , 37608 },/* 30 29 29 30 29 29 30 29 30 30 30 29 30 384
-1318 */{ 0 , 2 , 2 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
-1319 */{ 8 , 1 , 22 , 42328 },/* 30 29 30 29 29 30 29 30 29 30 29 30 30 384
-1320 */{ 0 , 2 , 10 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1321 */{ 0 , 1 , 29 , 45728 },/* 30 29 30 30 29 29 30 29 30 29 30 29 0 354
-1322 */{ 5 , 1 , 18 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1323 */{ 0 , 2 , 6 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1324 */{ 0 , 1 , 27 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
-1325 */{ 1 , 1 , 15 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 29 384
-1326 */{ 0 , 2 , 3 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1327 */{ 9 , 1 , 24 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1328 */{ 0 , 2 , 12 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
-1329 */{ 0 , 1 , 31 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 0 354
-1330 */{ 7 , 1 , 20 , 27288 },/* 29 30 30 29 30 29 30 29 30 29 29 30 30 384
-1331 */{ 0 , 2 , 8 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1332 */{ 0 , 1 , 28 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1333 */{ 3 , 1 , 17 , 19368 },/* 29 30 29 29 30 29 30 30 30 29 30 29 30 384
-1334 */{ 0 , 2 , 5 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1335 */{ 12 , 1 , 25 , 42608 },/* 30 29 30 29 29 30 30 29 29 30 30 30 29 384
-1336 */{ 0 , 2 , 13 , 41696 },/* 30 29 30 29 29 29 30 29 30 30 30 29 0 354
-1337 */{ 0 , 2 , 1 , 53600 },/* 30 30 29 30 29 29 29 30 29 30 30 29 0 354
-1338 */{ 8 , 1 , 21 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-1339 */{ 0 , 2 , 9 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1340 */{ 0 , 1 , 29 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
-1341 */{ 5 , 1 , 18 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 29 384
-1342 */{ 0 , 2 , 6 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1343 */{ 0 , 1 , 27 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1344 */{ 2 , 1 , 16 , 41704 },/* 30 29 30 29 29 29 30 29 30 30 30 29 30 384
-1345 */{ 0 , 2 , 3 , 41680 },/* 30 29 30 29 29 29 30 29 30 30 29 30 0 354
-1346 */{ 10 , 1 , 23 , 53592 },/* 30 30 29 30 29 29 29 30 29 30 29 30 30 384
-1347 */{ 0 , 2 , 11 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1348 */{ 0 , 1 , 31 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1349 */{ 7 , 1 , 19 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 29 384
-1350 */{ 0 , 2 , 7 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
-1351 */{ 0 , 1 , 28 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
-1352 */{ 3 , 1 , 18 , 18904 },/* 29 30 29 29 30 29 29 30 30 30 29 30 30 384
-1353 */{ 0 , 2 , 5 , 17840 },/* 29 30 29 29 29 30 29 30 30 29 30 30 0 354
-1354 */{ 0 , 1 , 25 , 41648 },/* 30 29 30 29 29 29 30 29 30 29 30 30 0 354
-1355 */{ 1 , 1 , 14 , 53592 },/* 30 30 29 30 29 29 29 30 29 30 29 30 30 384
-1356 */{ 0 , 2 , 2 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1357 */{ 9 , 1 , 21 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-1358 */{ 0 , 2 , 9 , 27424 },/* 29 30 30 29 30 29 30 30 29 29 30 29 0 354
-1359 */{ 0 , 1 , 29 , 44384 },/* 30 29 30 29 30 30 29 30 29 30 30 29 0 355
-1360 */{ 5 , 1 , 19 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-1361 */{ 0 , 2 , 6 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1362 */{ 0 , 1 , 27 , 17776 },/* 29 30 29 29 29 30 29 30 29 30 30 30 0 354
-1363 */{ 3 , 1 , 16 , 41656 },/* 30 29 30 29 29 29 30 29 30 29 30 30 30 384
-1364 */{ 0 , 2 , 4 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1365 */{ 10 , 1 , 23 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 29 383
-1366 */{ 0 , 2 , 10 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1367 */{ 0 , 1 , 31 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1368 */{ 7 , 1 , 20 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 29 384
-1369 */{ 0 , 2 , 7 , 42720 },/* 30 29 30 29 29 30 30 29 30 30 30 29 0 355
-1370 */{ 0 , 1 , 28 , 21216 },/* 29 30 29 30 29 29 30 29 30 30 30 29 0 354
-1371 */{ 3 , 1 , 17 , 50544 },/* 30 30 29 29 29 30 29 30 29 30 30 30 29 384
-1372 */{ 0 , 2 , 5 , 42336 },/* 30 29 30 29 29 30 29 30 29 30 30 29 0 354
-1373 */{ 11 , 1 , 24 , 53928 },/* 30 30 29 30 29 29 30 29 30 29 30 29 30 384
-1374 */{ 0 , 2 , 12 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
-1375 */{ 0 , 2 , 1 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1376 */{ 9 , 1 , 22 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1377 */{ 0 , 2 , 9 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1378 */{ 0 , 1 , 29 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
-1379 */{ 5 , 1 , 19 , 21224 },/* 29 30 29 30 29 29 30 29 30 30 30 29 30 384
-1380 */{ 0 , 2 , 7 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1381 */{ 0 , 1 , 26 , 43216 },/* 30 29 30 29 30 29 29 29 30 30 29 30 0 354
-1382 */{ 2 , 1 , 15 , 53928 },/* 30 30 29 30 29 29 30 29 30 29 30 29 30 384
-1383 */{ 0 , 2 , 3 , 45728 },/* 30 29 30 30 29 29 30 29 30 29 30 29 0 354
-1384 */{ 10 , 1 , 23 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1385 */{ 0 , 2 , 10 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1386 */{ 0 , 1 , 31 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
-1387 */{ 6 , 1 , 20 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 29 384
-1388 */{ 0 , 2 , 8 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1389 */{ 0 , 1 , 28 , 20912 },/* 29 30 29 30 29 29 29 30 30 29 30 30 0 354
-1390 */{ 4 , 1 , 17 , 43192 },/* 30 29 30 29 30 29 29 29 30 29 30 30 30 384
-1391 */{ 0 , 2 , 5 , 25904 },/* 29 30 30 29 29 30 29 30 29 29 30 30 0 354
-1392 */{ 12 , 1 , 25 , 27288 },/* 29 30 30 29 30 29 30 29 30 29 29 30 30 384
-1393 */{ 0 , 2 , 12 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1394 */{ 0 , 2 , 1 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1395 */{ 9 , 1 , 22 , 11176 },/* 29 29 30 29 30 29 30 30 30 29 30 29 30 384
-1396 */{ 0 , 2 , 10 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1397 */{ 0 , 1 , 29 , 50032 },/* 30 30 29 29 29 29 30 30 29 30 30 30 0 355
-1398 */{ 5 , 1 , 19 , 20848 },/* 29 30 29 30 29 29 29 30 29 30 30 30 29 383
-1399 */{ 0 , 2 , 6 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1400 */{ 0 , 1 , 26 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1401 */{ 3 , 1 , 15 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 29 383
-1402 */{ 0 , 2 , 2 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
-1403 */{ 11 , 1 , 23 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 29 384
-1404 */{ 0 , 2 , 11 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1405 */{ 0 , 1 , 31 , 10976 },/* 29 29 30 29 30 29 30 29 30 30 30 29 0 354
-1406 */{ 7 , 1 , 20 , 41704 },/* 30 29 30 29 29 29 30 29 30 30 30 29 30 384
-1407 */{ 0 , 2 , 8 , 41680 },/* 30 29 30 29 29 29 30 29 30 30 29 30 0 354
-1408 */{ 0 , 1 , 28 , 53584 },/* 30 30 29 30 29 29 29 30 29 30 29 30 0 354
-1409 */{ 4 , 1 , 16 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1410 */{ 0 , 2 , 4 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1411 */{ 12 , 1 , 24 , 46736 },/* 30 29 30 30 29 30 30 29 30 29 29 30 29 384
-1412 */{ 0 , 2 , 12 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
-1413 */{ 0 , 2 , 1 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
-1414 */{ 9 , 1 , 22 , 9688 },/* 29 29 30 29 29 30 29 30 30 30 29 30 30 384
-1415 */{ 0 , 2 , 10 , 17840 },/* 29 30 29 29 29 30 29 30 30 29 30 30 0 354
-1416 */{ 0 , 1 , 30 , 41648 },/* 30 29 30 29 29 29 30 29 30 29 30 30 0 354
-1417 */{ 5 , 1 , 18 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1418 */{ 0 , 2 , 6 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1419 */{ 0 , 1 , 26 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1420 */{ 1 , 1 , 15 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1421 */{ 0 , 2 , 2 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1422 */{ 12 , 1 , 23 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-1423 */{ 0 , 2 , 11 , 19312 },/* 29 30 29 29 30 29 30 30 29 30 30 30 0 355
-1424 */{ 0 , 2 , 1 , 17776 },/* 29 30 29 29 29 30 29 30 29 30 30 30 0 354
-1425 */{ 7 , 1 , 20 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1426 */{ 0 , 2 , 8 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1427 */{ 0 , 1 , 28 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1428 */{ 4 , 1 , 17 , 27816 },/* 29 30 30 29 30 30 29 29 30 29 30 29 30 384
-1429 */{ 0 , 2 , 4 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1430 */{ 12 , 1 , 24 , 39760 },/* 30 29 29 30 30 29 30 30 29 30 29 30 29 384
-1431 */{ 0 , 2 , 12 , 42720 },/* 30 29 30 29 29 30 30 29 30 30 30 29 0 355
-1432 */{ 0 , 2 , 2 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1433 */{ 8 , 1 , 21 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1434 */{ 0 , 2 , 9 , 42336 },/* 30 29 30 29 29 30 29 30 29 30 30 29 0 354
-1435 */{ 0 , 1 , 29 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
-1436 */{ 6 , 1 , 18 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 29 384
-1437 */{ 0 , 2 , 5 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1438 */{ 0 , 1 , 26 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1439 */{ 2 , 1 , 15 , 43728 },/* 30 29 30 29 30 29 30 29 30 30 29 30 29 384
-1440 */{ 0 , 2 , 3 , 38368 },/* 30 29 29 30 29 30 29 30 30 30 30 29 0 355
-1441 */{ 11 , 1 , 23 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1442 */{ 0 , 2 , 11 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1443 */{ 0 , 1 , 31 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1444 */{ 7 , 1 , 20 , 53872 },/* 30 30 29 30 29 29 30 29 29 30 30 30 29 384
-1445 */{ 0 , 2 , 7 , 45728 },/* 30 29 30 30 29 29 30 29 30 29 30 29 0 354
-1446 */{ 0 , 1 , 27 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1447 */{ 4 , 1 , 17 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1448 */{ 0 , 2 , 5 , 11680 },/* 29 29 30 29 30 30 29 30 30 29 30 29 0 354
-1449 */{ 0 , 1 , 24 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1450 */{ 1 , 1 , 14 , 19128 },/* 29 30 29 29 30 29 30 29 30 29 30 30 30 384
-1451 */{ 0 , 2 , 2 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1452 */{ 9 , 1 , 22 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-1453 */{ 0 , 2 , 9 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1454 */{ 0 , 1 , 29 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 0 354
-1455 */{ 6 , 1 , 18 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1456 */{ 0 , 2 , 6 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 0 355
-1457 */{ 0 , 1 , 26 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1458 */{ 2 , 1 , 15 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 29 384
-1459 */{ 0 , 2 , 3 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1460 */{ 11 , 1 , 24 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 29 383
-1461 */{ 0 , 2 , 10 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1462 */{ 0 , 1 , 30 , 58544 },/* 30 30 30 29 29 30 29 29 30 29 30 30 0 355
-1463 */{ 7 , 1 , 20 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 29 383
-1464 */{ 0 , 2 , 7 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
-1465 */{ 0 , 1 , 27 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
-1466 */{ 3 , 1 , 17 , 11112 },/* 29 29 30 29 30 29 30 30 29 30 30 29 30 384
-1467 */{ 0 , 2 , 5 , 9952 },/* 29 29 30 29 29 30 30 29 30 30 30 29 0 354
-1468 */{ 0 , 1 , 25 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1469 */{ 2 , 1 , 13 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-1470 */{ 0 , 2 , 1 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
-1471 */{ 9 , 1 , 21 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1472 */{ 0 , 2 , 9 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1473 */{ 0 , 1 , 28 , 46736 },/* 30 29 30 30 29 30 30 29 30 29 29 30 0 355
-1474 */{ 6 , 1 , 18 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
-1475 */{ 0 , 2 , 6 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-1476 */{ 0 , 1 , 27 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1477 */{ 2 , 1 , 15 , 37592 },/* 30 29 29 30 29 29 30 29 30 30 29 30 30 384
-1478 */{ 0 , 2 , 3 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
-1479 */{ 10 , 1 , 23 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1480 */{ 0 , 2 , 11 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1481 */{ 0 , 1 , 30 , 29856 },/* 29 30 30 30 29 30 29 29 30 29 30 29 0 354
-1482 */{ 8 , 1 , 19 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1483 */{ 0 , 2 , 7 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1484 */{ 0 , 1 , 28 , 21424 },/* 29 30 29 30 29 29 30 30 30 29 30 30 0 355
-1485 */{ 4 , 1 , 17 , 9656 },/* 29 29 30 29 29 30 29 30 30 29 30 30 30 384
-1486 */{ 0 , 2 , 5 , 9584 },/* 29 29 30 29 29 30 29 30 29 30 30 30 0 354
-1487 */{ 0 , 1 , 25 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1488 */{ 1 , 1 , 14 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1489 */{ 0 , 2 , 1 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1490 */{ 9 , 1 , 21 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
-1491 */{ 0 , 2 , 9 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1492 */{ 0 , 1 , 29 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1493 */{ 5 , 1 , 18 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
-1494 */{ 0 , 2 , 6 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1495 */{ 0 , 1 , 26 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1496 */{ 3 , 1 , 16 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 29 383
-1497 */{ 0 , 2 , 2 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
-1498 */{ 11 , 1 , 22 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 29 384
-1499 */{ 0 , 2 , 10 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1500 */{ 0 , 1 , 31 , 5792 },/* 29 29 29 30 29 30 30 29 30 29 30 29 0 353
-1501 */{ 7 , 1 , 19 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1502 */{ 0 , 2 , 7 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1503 */{ 0 , 1 , 28 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1504 */{ 4 , 1 , 17 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1505 */{ 0 , 2 , 4 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1506 */{ 0 , 1 , 24 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1507 */{ 1 , 1 , 13 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 29 384
-1508 */{ 0 , 2 , 1 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1509 */{ 9 , 1 , 21 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1510 */{ 0 , 2 , 9 , 11680 },/* 29 29 30 29 30 30 29 30 30 29 30 29 0 354
-1511 */{ 0 , 1 , 29 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1512 */{ 5 , 1 , 19 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1513 */{ 0 , 2 , 6 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1514 */{ 0 , 1 , 26 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1515 */{ 4 , 1 , 15 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1516 */{ 0 , 2 , 3 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 0 354
-1517 */{ 12 , 1 , 22 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1518 */{ 0 , 2 , 10 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 0 355
-1519 */{ 0 , 1 , 31 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1520 */{ 8 , 1 , 20 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 29 384
-1521 */{ 0 , 2 , 7 , 37616 },/* 30 29 29 30 29 29 30 29 30 30 30 30 0 355
-1522 */{ 0 , 1 , 28 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1523 */{ 4 , 1 , 17 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
-1524 */{ 0 , 2 , 4 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1525 */{ 12 , 1 , 23 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 29 384
-1526 */{ 0 , 2 , 11 , 54928 },/* 30 30 29 30 29 30 30 29 30 29 29 30 0 355
-1527 */{ 0 , 2 , 1 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1528 */{ 10 , 1 , 22 , 11112 },/* 29 29 30 29 30 29 30 30 29 30 30 29 30 384
-1529 */{ 0 , 2 , 9 , 9952 },/* 29 29 30 29 29 30 30 29 30 30 30 29 0 354
-1530 */{ 0 , 1 , 29 , 21216 },/* 29 30 29 30 29 29 30 29 30 30 30 29 0 354
-1531 */{ 6 , 1 , 18 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-1532 */{ 0 , 2 , 6 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
-1533 */{ 0 , 1 , 25 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1534 */{ 2 , 1 , 14 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1535 */{ 0 , 2 , 2 , 46480 },/* 30 29 30 30 29 30 29 30 30 29 29 30 0 355
-1536 */{ 12 , 1 , 23 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
-1537 */{ 0 , 2 , 10 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-1538 */{ 0 , 1 , 31 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1539 */{ 7 , 1 , 20 , 37592 },/* 30 29 29 30 29 29 30 29 30 30 29 30 30 384
-1540 */{ 0 , 2 , 8 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
-1541 */{ 0 , 1 , 27 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1542 */{ 5 , 1 , 16 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-1543 */{ 0 , 2 , 4 , 27808 },/* 29 30 30 29 30 30 29 29 30 29 30 29 0 354
-1544 */{ 0 , 1 , 24 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1545 */{ 1 , 1 , 13 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-1546 */{ 0 , 2 , 1 , 19376 },/* 29 30 29 29 30 29 30 30 30 29 30 30 0 355
-1547 */{ 9 , 1 , 22 , 9656 },/* 29 29 30 29 29 30 29 30 30 29 30 30 30 384
-1548 */{ 0 , 2 , 10 , 9584 },/* 29 29 30 29 29 30 29 30 29 30 30 30 0 354
-1549 */{ 0 , 1 , 29 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1550 */{ 6 , 1 , 18 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 29 383
-1551 */{ 0 , 2 , 5 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
-1552 */{ 0 , 1 , 26 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1553 */{ 3 , 1 , 14 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1554 */{ 0 , 2 , 2 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1555 */{ 11 , 1 , 23 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
-1556 */{ 0 , 2 , 11 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1557 */{ 0 , 1 , 30 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1558 */{ 7 , 1 , 20 , 21096 },/* 29 30 29 30 29 29 30 29 29 30 30 29 30 383
-1559 */{ 0 , 2 , 7 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1560 */{ 0 , 1 , 27 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1561 */{ 5 , 1 , 16 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1562 */{ 0 , 2 , 4 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1563 */{ 0 , 1 , 24 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-1564 */{ 2 , 1 , 14 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1565 */{ 0 , 2 , 1 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1566 */{ 10 , 1 , 21 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1567 */{ 0 , 2 , 9 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1568 */{ 0 , 1 , 29 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1569 */{ 6 , 1 , 17 , 54600 },/* 30 30 29 30 29 30 29 30 29 30 29 29 30 384
-1570 */{ 0 , 2 , 5 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1571 */{ 0 , 1 , 26 , 13728 },/* 29 29 30 30 29 30 29 30 30 29 30 29 0 354
-1572 */{ 2 , 1 , 15 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 29 384
-1573 */{ 0 , 2 , 2 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1574 */{ 12 , 1 , 23 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1575 */{ 0 , 2 , 11 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1576 */{ 0 , 1 , 31 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1577 */{ 8 , 1 , 19 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1578 */{ 0 , 2 , 7 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1579 */{ 0 , 1 , 27 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1580 */{ 4 , 1 , 16 , 44456 },/* 30 29 30 29 30 30 29 30 30 29 30 29 30 385
-1581 */{ 0 , 2 , 4 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1582 */{ 0 , 1 , 24 , 39024 },/* 30 29 29 30 29 29 30 30 39 30 30 30 0 365
-1583 */{ 2 , 1 , 24 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
-1584 */{ 0 , 2 , 12 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1585 */{ 9 , 1 , 31 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
-1586 */{ 0 , 2 , 18 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1587 */{ 0 , 3 , 9 , 53968 },/* 30 30 29 30 29 30 29 29 30 29 30 0 0 325
-1588 */{ 6 , 1 , 28 , 27464 },/* 29 30 30 29 30 29 30 30 29 30 29 29 30 384
-1589 */{ 0 , 2 , 15 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1590 */{ 0 , 2 , 5 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1591 */{ 3 , 1 , 25 , 37616 },/* 30 29 29 30 29 29 30 29 30 30 30 30 29 384
-1592 */{ 0 , 2 , 13 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1593 */{ 11 , 2 , 1 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-1594 */{ 0 , 2 , 20 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1595 */{ 0 , 2 , 9 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1596 */{ 8 , 1 , 29 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1597 */{ 0 , 2 , 16 , 46288 },/* 30 29 30 30 29 30 29 29 30 30 29 30 0 355
-1598 */{ 0 , 2 , 6 , 22192 },/* 29 30 29 30 29 30 30 29 30 29 30 30 0 355
-1599 */{ 4 , 1 , 27 , 9944 },/* 29 29 30 29 29 30 30 29 30 30 29 30 30 384
-1600 */{ 0 , 2 , 15 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1601 */{ 0 , 2 , 3 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-1602 */{ 2 , 1 , 23 , 51608 },/* 30 30 29 29 30 29 29 30 30 29 29 30 30 384
-1603 */{ 0 , 2 , 11 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1604 */{ 9 , 1 , 31 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-1605 */{ 0 , 2 , 18 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1606 */{ 0 , 2 , 7 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1607 */{ 6 , 1 , 28 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-1608 */{ 0 , 2 , 16 , 19376 },/* 29 30 29 29 30 29 30 30 30 29 30 30 0 355
-1609 */{ 0 , 2 , 5 , 9648 },/* 29 29 30 29 29 30 29 30 30 29 30 30 0 354
-1610 */{ 3 , 1 , 25 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1611 */{ 0 , 2 , 13 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1612 */{ 11 , 2 , 2 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 29 383
-1613 */{ 0 , 2 , 19 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
-1614 */{ 0 , 2 , 9 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1615 */{ 8 , 1 , 29 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1616 */{ 0 , 2 , 17 , 39760 },/* 30 29 29 30 30 29 30 30 29 30 29 30 0 355
-1617 */{ 0 , 2 , 6 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1618 */{ 4 , 1 , 26 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1619 */{ 0 , 2 , 14 , 42224 },/* 30 29 30 29 29 30 29 29 30 30 30 30 0 355
-1620 */{ 0 , 2 , 4 , 21088 },/* 29 30 29 30 29 29 30 29 29 30 30 29 0 353
-1621 */{ 2 , 1 , 22 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-1622 */{ 0 , 2 , 10 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1623 */{ 10 , 1 , 31 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1624 */{ 0 , 2 , 19 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1625 */{ 0 , 2 , 7 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-1626 */{ 6 , 1 , 28 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1627 */{ 0 , 2 , 16 , 18912 },/* 29 30 29 29 30 29 29 30 30 30 30 29 0 354
-1628 */{ 0 , 2 , 5 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1629 */{ 4 , 1 , 24 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1630 */{ 0 , 2 , 12 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1631 */{ 11 , 2 , 1 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
-1632 */{ 0 , 2 , 20 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1633 */{ 0 , 2 , 8 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
-1634 */{ 8 , 1 , 29 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 29 384
-1635 */{ 0 , 2 , 17 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1636 */{ 0 , 2 , 7 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1637 */{ 4 , 1 , 26 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-1638 */{ 0 , 2 , 14 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1639 */{ 0 , 2 , 3 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1640 */{ 1 , 1 , 23 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-1641 */{ 0 , 2 , 10 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1642 */{ 11 , 1 , 30 , 44456 },/* 30 29 30 29 30 30 29 30 30 29 30 29 30 385
-1643 */{ 0 , 2 , 19 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1644 */{ 0 , 2 , 8 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1645 */{ 6 , 1 , 28 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
-1646 */{ 0 , 2 , 16 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1647 */{ 0 , 2 , 5 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1648 */{ 3 , 1 , 24 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1649 */{ 0 , 2 , 11 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-1650 */{ 11 , 2 , 1 , 27464 },/* 29 30 30 29 30 29 30 30 29 30 29 29 30 384
-1651 */{ 0 , 2 , 20 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1652 */{ 0 , 2 , 10 , 11168 },/* 29 29 30 29 30 29 30 30 30 29 30 29 0 354
-1653 */{ 7 , 1 , 29 , 37616 },/* 30 29 29 30 29 29 30 29 30 30 30 30 29 384
-1654 */{ 0 , 2 , 17 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1655 */{ 0 , 2 , 6 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1656 */{ 5 , 1 , 26 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1657 */{ 0 , 2 , 13 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1658 */{ 0 , 2 , 2 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-1659 */{ 3 , 1 , 23 , 39592 },/* 30 29 29 30 30 29 30 29 30 29 30 29 30 384
-1660 */{ 0 , 2 , 11 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1661 */{ 7 , 1 , 30 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 29 384
-1662 */{ 0 , 2 , 18 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 0 355
-1663 */{ 0 , 2 , 8 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-1664 */{ 6 , 1 , 28 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1665 */{ 0 , 2 , 15 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1666 */{ 0 , 2 , 4 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1667 */{ 4 , 1 , 24 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1668 */{ 0 , 2 , 12 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1669 */{ 0 , 2 , 1 , 21920 },/* 29 30 29 30 29 30 29 30 30 29 30 29 0 354
-1670 */{ 2 , 1 , 21 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 29 384
-1671 */{ 0 , 2 , 9 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-1672 */{ 7 , 1 , 30 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1673 */{ 0 , 2 , 17 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1674 */{ 0 , 2 , 6 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 0 354
-1675 */{ 5 , 1 , 26 , 29864 },/* 29 30 30 30 29 30 29 29 30 29 30 29 30 384
-1676 */{ 0 , 2 , 14 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1677 */{ 0 , 2 , 2 , 44432 },/* 30 29 30 29 30 30 29 30 30 29 29 30 0 355
-1678 */{ 3 , 1 , 23 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
-1679 */{ 0 , 2 , 11 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1680 */{ 8 , 1 , 31 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1681 */{ 0 , 2 , 18 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
-1682 */{ 0 , 2 , 7 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1683 */{ 6 , 1 , 27 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-1684 */{ 0 , 2 , 15 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
-1685 */{ 0 , 2 , 3 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
-1686 */{ 4 , 1 , 24 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
-1687 */{ 0 , 2 , 12 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1688 */{ 0 , 2 , 2 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1689 */{ 3 , 1 , 21 , 42216 },/* 30 29 30 29 29 30 29 29 30 30 30 29 30 384
-1690 */{ 0 , 2 , 9 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1691 */{ 7 , 1 , 29 , 53848 },/* 30 30 29 30 29 29 30 29 29 30 29 30 30 384
-1692 */{ 0 , 2 , 17 , 45136 },/* 30 29 29 32 29 29 29 29 29 30 29 30 0 354
-1693 */{ 0 , 2 , 5 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
-1694 */{ 5 , 1 , 25 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 29 384
-1695 */{ 0 , 2 , 13 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
-1696 */{ 0 , 2 , 3 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
-1697 */{ 3 , 1 , 23 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
-1698 */{ 0 , 2 , 11 , 18896 },/* 29 30 29 29 30 29 29 30 30 30 29 30 0 354
-1699 */{ 7 , 1 , 31 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-1700 */{ 0 , 2 , 19 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1701 */{ 0 , 2 , 8 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1702 */{ 6 , 1 , 28 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-1703 */{ 0 , 2 , 16 , 27936 },/* 29 30 30 29 30 30 29 30 29 29 30 29 0 354
-1704 */{ 0 , 2 , 5 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
-1705 */{ 4 , 1 , 25 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-1706 */{ 0 , 2 , 13 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1707 */{ 0 , 2 , 3 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1708 */{ 3 , 1 , 23 , 25784 },/* 29 30 30 29 29 30 29 29 30 29 30 30 30 384
-1709 */{ 0 , 2 , 10 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1710 */{ 7 , 1 , 30 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1711 */{ 0 , 2 , 17 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-1712 */{ 0 , 2 , 7 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1713 */{ 5 , 1 , 26 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 29 384
-1714 */{ 0 , 2 , 14 , 43744 },/* 30 29 30 29 30 29 30 29 30 30 30 29 0 355
-1715 */{ 0 , 2 , 4 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1716 */{ 3 , 1 , 24 , 51568 },/* 30 30 29 29 30 29 29 30 29 30 30 30 29 384
-1717 */{ 0 , 2 , 11 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-1718 */{ 8 , 1 , 31 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1719 */{ 0 , 2 , 19 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1720 */{ 0 , 2 , 8 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1721 */{ 6 , 1 , 28 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1722 */{ 0 , 2 , 16 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1723 */{ 0 , 2 , 5 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
-1724 */{ 4 , 1 , 26 , 21224 },/* 29 30 29 30 29 29 30 29 30 30 30 29 30 384
-1725 */{ 0 , 2 , 13 , 21200 },/* 29 30 29 30 29 29 30 29 30 30 29 30 0 354
-1726 */{ 0 , 2 , 2 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1727 */{ 3 , 1 , 22 , 58536 },/* 30 30 30 29 29 30 29 29 30 29 30 29 30 384
-1728 */{ 0 , 2 , 10 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1729 */{ 7 , 1 , 29 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1730 */{ 0 , 2 , 17 , 40272 },/* 30 29 29 30 30 30 29 30 29 30 29 30 0 355
-1731 */{ 0 , 2 , 7 , 21920 },/* 29 30 29 30 29 30 29 30 30 29 30 29 0 354
-1732 */{ 5 , 1 , 27 , 42448 },/* 30 29 30 29 29 30 29 30 30 30 29 30 29 384
-1733 */{ 0 , 2 , 14 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-1734 */{ 0 , 2 , 4 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1735 */{ 4 , 1 , 24 , 43192 },/* 30 29 30 29 30 29 29 29 30 29 30 30 30 384
-1736 */{ 0 , 2 , 12 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 0 354
-1737 */{ 9 , 1 , 31 , 27288 },/* 29 30 30 29 30 29 30 29 30 29 29 30 30 384
-1738 */{ 0 , 2 , 19 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1739 */{ 0 , 2 , 8 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1740 */{ 6 , 1 , 29 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
-1741 */{ 0 , 2 , 16 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1742 */{ 0 , 2 , 5 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1743 */{ 4 , 1 , 26 , 20848 },/* 29 30 29 30 29 29 29 30 29 30 30 30 29 383
-1744 */{ 0 , 2 , 13 , 53600 },/* 30 30 29 30 29 29 29 30 29 30 30 29 0 354
-1745 */{ 0 , 2 , 1 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 0 355
-1746 */{ 3 , 1 , 22 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 29 383
-1747 */{ 0 , 2 , 9 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 0 355
-1748 */{ 7 , 1 , 30 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 29 384
-1749 */{ 0 , 2 , 17 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1750 */{ 0 , 2 , 7 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1751 */{ 5 , 1 , 27 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1752 */{ 0 , 2 , 15 , 41680 },/* 30 29 30 29 29 29 30 29 30 30 29 30 0 354
-1753 */{ 0 , 2 , 3 , 53592 },/* 30 30 29 30 29 29 29 30 29 30 29 30 30 384
-1754 */{ 4 , 2 , 22 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-1755 */{ 0 , 2 , 11 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1756 */{ 9 , 1 , 31 , 54928 },/* 30 30 29 30 29 30 30 29 30 29 29 30 29 384
-1757 */{ 0 , 2 , 18 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
-1758 */{ 0 , 2 , 8 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
-1759 */{ 6 , 1 , 29 , 10968 },/* 29 29 30 29 30 29 30 29 30 30 29 30 30 384
-1760 */{ 0 , 2 , 17 , 17840 },/* 29 30 29 29 29 30 29 30 30 29 30 30 0 354
-1761 */{ 0 , 2 , 5 , 41648 },/* 30 29 30 29 29 29 30 29 30 29 30 30 0 354
-1762 */{ 5 , 1 , 25 , 45400 },/* 30 29 30 30 29 29 29 30 29 30 29 30 30 384
-1763 */{ 0 , 2 , 13 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1764 */{ 0 , 2 , 2 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1765 */{ 2 , 1 , 21 , 46480 },/* 30 29 30 30 29 30 29 30 30 29 29 30 29 384
-1766 */{ 0 , 2 , 9 , 44384 },/* 30 29 30 29 30 30 29 30 29 30 30 29 0 355
-1767 */{ 7 , 1 , 30 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
-1768 */{ 0 , 2 , 18 , 21360 },/* 29 30 29 30 29 29 30 30 29 30 30 30 0 355
-1769 */{ 0 , 2 , 7 , 17776 },/* 29 30 29 29 29 30 29 30 29 30 30 30 0 354
-1770 */{ 5 , 1 , 27 , 25272 },/* 29 30 30 29 29 29 30 29 30 29 30 30 30 384
-1771 */{ 0 , 2 , 15 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1772 */{ 0 , 2 , 4 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1773 */{ 3 , 1 , 23 , 27816 },/* 29 30 30 29 30 30 29 29 30 29 30 29 30 384
-1774 */{ 0 , 2 , 11 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1775 */{ 10 , 1 , 31 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
-1776 */{ 0 , 2 , 19 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
-1777 */{ 0 , 2 , 8 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1778 */{ 6 , 1 , 28 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 29 384
-1779 */{ 0 , 2 , 16 , 42336 },/* 30 29 30 29 29 30 29 30 29 30 30 29 0 354
-1780 */{ 0 , 2 , 5 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
-1781 */{ 5 , 1 , 24 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 29 384
-1782 */{ 0 , 2 , 12 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1783 */{ 0 , 2 , 2 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1784 */{ 3 , 1 , 22 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
-1785 */{ 0 , 2 , 9 , 42704 },/* 30 29 30 29 29 30 30 29 30 30 29 30 0 355
-1786 */{ 7 , 1 , 30 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1787 */{ 0 , 2 , 18 , 19120 },/* 29 30 29 29 30 29 30 29 30 29 30 30 0 354
-1788 */{ 0 , 2 , 7 , 43216 },/* 30 29 30 29 30 29 29 29 30 30 29 30 0 354
-1789 */{ 5 , 1 , 26 , 53928 },/* 30 30 29 30 29 29 30 29 30 29 30 29 30 384
-1790 */{ 0 , 2 , 14 , 45728 },/* 30 29 30 30 29 29 30 29 30 29 30 29 0 354
-1791 */{ 0 , 2 , 3 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1792 */{ 4 , 1 , 24 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1793 */{ 0 , 2 , 11 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
-1794 */{ 0 , 1 , 31 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1795 */{ 2 , 1 , 21 , 19128 },/* 29 30 29 29 30 29 30 29 30 29 30 30 30 384
-1796 */{ 0 , 2 , 9 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1797 */{ 6 , 1 , 28 , 43192 },/* 30 29 30 29 30 29 29 29 30 29 30 30 30 384
-1798 */{ 0 , 2 , 16 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1799 */{ 0 , 2 , 5 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 0 354
-1800 */{ 4 , 1 , 25 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1801 */{ 0 , 2 , 13 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 0 355
-1802 */{ 0 , 2 , 3 , 11168 },/* 29 29 30 29 30 29 30 30 30 29 30 29 0 354
-1803 */{ 2 , 1 , 23 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 29 384
-1804 */{ 0 , 2 , 11 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1805 */{ 6 , 1 , 31 , 20848 },/* 29 30 29 30 29 29 29 30 29 30 30 30 29 383
-1806 */{ 0 , 2 , 18 , 53600 },/* 30 30 29 30 29 29 29 30 29 30 30 29 0 354
-1807 */{ 0 , 2 , 7 , 58544 },/* 30 30 30 29 29 30 29 29 30 29 30 30 0 355
-1808 */{ 5 , 1 , 28 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 29 383
-1809 */{ 0 , 2 , 14 , 55952 },/* 30 30 29 30 30 29 30 29 30 29 29 30 0 355
-1810 */{ 0 , 2 , 4 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 0 355
-1811 */{ 3 , 1 , 25 , 11112 },/* 29 29 30 29 30 29 30 30 29 30 30 29 30 384
-1812 */{ 0 , 2 , 13 , 10976 },/* 29 29 30 29 30 29 30 29 30 30 30 29 0 354
-1813 */{ 0 , 2 , 1 , 41696 },/* 30 29 30 29 29 29 30 29 30 30 30 29 0 354
-1814 */{ 2 , 1 , 21 , 53608 },/* 30 30 29 30 29 29 29 30 29 30 30 29 30 384
-1815 */{ 0 , 2 , 9 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
-1816 */{ 6 , 1 , 29 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1817 */{ 0 , 2 , 16 , 46368 },/* 30 29 30 30 29 30 29 30 29 29 30 29 0 354
-1818 */{ 0 , 2 , 5 , 46736 },/* 30 29 30 30 29 30 30 29 30 29 29 30 0 355
-1819 */{ 4 , 1 , 26 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
-1820 */{ 0 , 2 , 14 , 21968 },/* 29 30 29 30 29 30 29 30 30 30 29 30 0 355
-1821 */{ 0 , 2 , 3 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1822 */{ 3 , 1 , 23 , 41688 },/* 30 29 30 29 29 29 30 29 30 30 29 30 30 384
-1823 */{ 0 , 2 , 11 , 41648 },/* 30 29 30 29 29 29 30 29 30 29 30 30 0 354
-1824 */{ 7 , 1 , 31 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1825 */{ 0 , 2 , 18 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1826 */{ 0 , 2 , 7 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1827 */{ 5 , 1 , 27 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-1828 */{ 0 , 2 , 15 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-1829 */{ 0 , 2 , 4 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-1830 */{ 4 , 1 , 25 , 9656 },/* 29 29 30 29 29 30 29 30 30 29 30 30 30 384
-1831 */{ 0 , 2 , 13 , 9584 },/* 29 29 30 29 29 30 29 30 29 30 30 30 0 354
-1832 */{ 9 , 2 , 2 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1833 */{ 0 , 2 , 20 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1834 */{ 0 , 2 , 9 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1835 */{ 6 , 1 , 29 , 27816 },/* 29 30 30 29 30 30 29 29 30 29 30 29 30 384
-1836 */{ 0 , 2 , 17 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1837 */{ 0 , 2 , 5 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1838 */{ 4 , 1 , 26 , 21352 },/* 29 30 29 30 29 29 30 30 29 30 30 29 30 384
-1839 */{ 0 , 2 , 14 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1840 */{ 0 , 2 , 3 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1841 */{ 3 , 1 , 23 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 29 383
-1842 */{ 0 , 2 , 10 , 53920 },/* 30 30 29 30 29 29 30 29 30 29 30 29 0 354
-1843 */{ 7 , 1 , 30 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 29 384
-1844 */{ 0 , 2 , 18 , 54608 },/* 30 30 29 30 29 30 29 30 29 30 29 30 0 355
-1845 */{ 0 , 2 , 7 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-1846 */{ 5 , 1 , 27 , 43728 },/* 30 29 30 29 30 29 30 29 30 30 29 30 29 384
-1847 */{ 0 , 2 , 15 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1848 */{ 0 , 2 , 5 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1849 */{ 4 , 1 , 24 , 42328 },/* 30 29 30 29 29 30 29 30 29 30 29 30 30 384
-1850 */{ 0 , 2 , 12 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1851 */{ 8 , 2 , 1 , 53848 },/* 30 30 29 30 29 29 30 29 29 30 29 30 30 384
-1852 */{ 0 , 2 , 20 , 45712 },/* 30 29 30 30 29 29 30 29 30 29 29 30 0 354
-1853 */{ 0 , 2 , 8 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1854 */{ 7 , 1 , 29 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1855 */{ 0 , 2 , 17 , 11680 },/* 29 29 30 29 30 30 29 30 30 29 30 29 0 354
-1856 */{ 0 , 2 , 6 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1857 */{ 5 , 1 , 26 , 19128 },/* 29 30 29 29 30 29 30 29 30 29 30 30 30 384
-1858 */{ 0 , 2 , 14 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1859 */{ 0 , 2 , 3 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1860 */{ 3 , 1 , 23 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1861 */{ 0 , 2 , 10 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 0 354
-1862 */{ 8 , 1 , 30 , 44360 },/* 30 29 30 29 30 30 29 30 29 30 29 29 30 384
-1863 */{ 0 , 2 , 18 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 0 355
-1864 */{ 0 , 2 , 8 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1865 */{ 5 , 1 , 27 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 29 384
-1866 */{ 0 , 2 , 15 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 0 355
-1867 */{ 0 , 2 , 5 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1868 */{ 4 , 1 , 25 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
-1869 */{ 0 , 2 , 11 , 58528 },/* 30 30 30 29 29 30 29 29 30 29 30 29 0 354
-1870 */{ 10 , 1 , 31 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 29 384
-1871 */{ 0 , 2 , 19 , 55952 },/* 30 30 29 30 30 29 30 29 30 29 29 30 0 355
-1872 */{ 0 , 2 , 9 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
-1873 */{ 6 , 1 , 29 , 11112 },/* 29 29 30 29 30 29 30 30 29 30 30 29 30 384
-1874 */{ 0 , 2 , 17 , 10976 },/* 29 29 30 29 30 29 30 29 30 30 30 29 0 354
-1875 */{ 0 , 2 , 6 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1876 */{ 5 , 1 , 26 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-1877 */{ 0 , 2 , 13 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
-1878 */{ 0 , 2 , 2 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1879 */{ 3 , 1 , 22 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1880 */{ 0 , 2 , 10 , 46736 },/* 30 29 30 30 29 30 30 29 30 29 29 30 0 355
-1881 */{ 7 , 1 , 30 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 29 384
-1882 */{ 0 , 2 , 18 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-1883 */{ 0 , 2 , 8 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1884 */{ 5 , 1 , 28 , 37592 },/* 30 29 29 30 29 29 30 29 30 30 29 30 30 384
-1885 */{ 0 , 2 , 15 , 37552 },/* 30 29 29 30 29 29 30 29 30 29 30 30 0 354
-1886 */{ 0 , 2 , 4 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1887 */{ 4 , 1 , 24 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1888 */{ 0 , 2 , 12 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1889 */{ 0 , 1 , 31 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1890 */{ 2 , 1 , 21 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1891 */{ 0 , 2 , 9 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 0 355
-1892 */{ 6 , 1 , 30 , 9656 },/* 29 29 30 29 29 30 29 30 30 29 30 30 30 384
-1893 */{ 0 , 2 , 17 , 9584 },/* 29 29 30 29 29 30 29 30 29 30 30 30 0 354
-1894 */{ 0 , 2 , 6 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1895 */{ 5 , 1 , 26 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 29 383
-1896 */{ 0 , 2 , 13 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
-1897 */{ 0 , 2 , 2 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1898 */{ 3 , 1 , 22 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1899 */{ 0 , 2 , 10 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1900 */{ 8 , 1 , 31 , 19304 },/* 29 30 29 29 30 29 30 30 29 30 30 29 30 384
-1901 */{ 0 , 2 , 19 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1902 */{ 0 , 2 , 8 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1903 */{ 5 , 1 , 29 , 21096 },/* 29 30 29 30 29 29 30 29 29 30 30 29 30 383
-1904 */{ 0 , 2 , 16 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-1905 */{ 0 , 2 , 4 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1906 */{ 4 , 1 , 25 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
-1907 */{ 0 , 2 , 13 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1908 */{ 0 , 2 , 2 , 39632 },/* 30 29 29 30 30 29 30 29 30 30 29 30 0 355
-1909 */{ 2 , 1 , 22 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1910 */{ 0 , 2 , 10 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1911 */{ 6 , 1 , 30 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1912 */{ 0 , 2 , 18 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1913 */{ 0 , 2 , 6 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1914 */{ 5 , 1 , 26 , 55624 },/* 30 30 29 30 30 29 29 30 29 30 29 29 30 384
-1915 */{ 0 , 2 , 14 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1916 */{ 0 , 2 , 4 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1917 */{ 2 , 1 , 23 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1918 */{ 0 , 2 , 11 , 38352 },/* 30 29 29 30 29 30 29 30 30 30 29 30 0 355
-1919 */{ 7 , 2 , 1 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
-1920 */{ 0 , 2 , 20 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1921 */{ 0 , 2 , 8 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1922 */{ 5 , 1 , 28 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1923 */{ 0 , 2 , 16 , 27280 },/* 29 30 30 29 30 29 30 29 30 29 29 30 0 354
-1924 */{ 0 , 2 , 5 , 44352 },/* 30 29 30 29 30 30 29 30 29 30 29 29 0 354
-1925 */{ 4 , 1 , 24 , 46504 },/* 30 29 30 30 29 30 29 30 30 29 30 29 30 385
-1926 */{ 0 , 2 , 13 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1927 */{ 0 , 2 , 2 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1928 */{ 2 , 1 , 23 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1929 */{ 0 , 2 , 10 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1930 */{ 6 , 1 , 30 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
-1931 */{ 0 , 2 , 17 , 58528 },/* 30 30 30 29 29 30 29 29 30 29 30 29 0 354
-1932 */{ 0 , 2 , 6 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-1933 */{ 5 , 1 , 26 , 27976 },/* 29 30 30 29 30 30 29 30 29 30 29 29 30 384
-1934 */{ 0 , 2 , 14 , 23376 },/* 29 30 29 30 30 29 30 30 29 30 29 30 0 355
-1935 */{ 0 , 2 , 4 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1936 */{ 3 , 1 , 24 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 29 384
-1937 */{ 0 , 2 , 11 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1938 */{ 7 , 1 , 31 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-1939 */{ 0 , 2 , 19 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
-1940 */{ 0 , 2 , 8 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1941 */{ 6 , 1 , 27 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1942 */{ 0 , 2 , 15 , 46736 },/* 30 29 30 30 29 30 30 29 30 29 29 30 0 355
-1943 */{ 0 , 2 , 5 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-1944 */{ 4 , 1 , 26 , 10968 },/* 29 29 30 29 30 29 30 29 30 30 29 30 30 384
-1945 */{ 0 , 2 , 13 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1946 */{ 0 , 2 , 2 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-1947 */{ 2 , 1 , 22 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-1948 */{ 0 , 2 , 10 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1949 */{ 7 , 1 , 29 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-1950 */{ 0 , 2 , 17 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-1951 */{ 0 , 2 , 6 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1952 */{ 5 , 1 , 27 , 22184 },/* 29 30 29 30 29 30 30 29 30 29 30 29 30 384
-1953 */{ 0 , 2 , 14 , 19888 },/* 29 30 29 29 30 30 29 30 30 29 30 30 0 355
-1954 */{ 0 , 2 , 4 , 9648 },/* 29 29 30 29 29 30 29 30 30 29 30 30 0 354
-1955 */{ 3 , 1 , 24 , 37560 },/* 30 29 29 30 29 29 30 29 30 29 30 30 30 384
-1956 */{ 0 , 2 , 12 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1957 */{ 8 , 1 , 31 , 43352 },/* 30 29 30 29 30 29 29 30 29 30 29 30 30 384
-1958 */{ 0 , 2 , 19 , 26960 },/* 29 30 30 29 30 29 29 30 29 30 29 30 0 354
-1959 */{ 0 , 2 , 8 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1960 */{ 6 , 1 , 28 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1961 */{ 0 , 2 , 15 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1962 */{ 0 , 2 , 5 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1963 */{ 4 , 1 , 25 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1964 */{ 0 , 2 , 13 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1965 */{ 0 , 2 , 2 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
-1966 */{ 3 , 1 , 22 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 29 383
-1967 */{ 0 , 2 , 9 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1968 */{ 7 , 1 , 30 , 27304 },/* 29 30 30 29 30 29 30 29 30 29 30 29 30 384
-1969 */{ 0 , 2 , 17 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1970 */{ 0 , 2 , 6 , 39632 },/* 30 29 29 30 30 29 30 29 30 30 29 30 0 355
-1971 */{ 5 , 1 , 27 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1972 */{ 0 , 2 , 15 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-1973 */{ 0 , 2 , 3 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
-1974 */{ 4 , 1 , 23 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1975 */{ 0 , 2 , 11 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1976 */{ 8 , 1 , 31 , 54600 },/* 30 30 29 30 29 30 29 30 29 30 29 29 30 384
-1977 */{ 0 , 2 , 18 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1978 */{ 0 , 2 , 7 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 0 355
-1979 */{ 6 , 1 , 28 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1980 */{ 0 , 2 , 16 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1981 */{ 0 , 2 , 5 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1982 */{ 4 , 1 , 25 , 42200 },/* 30 29 30 29 29 30 29 29 30 30 29 30 30 384
-1983 */{ 0 , 2 , 13 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1984 */{ 10 , 2 , 2 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1985 */{ 0 , 2 , 20 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1986 */{ 0 , 2 , 9 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1987 */{ 6 , 1 , 29 , 46504 },/* 30 29 30 30 29 30 29 30 30 29 30 29 30 385
-1988 */{ 0 , 2 , 18 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1989 */{ 0 , 2 , 6 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1990 */{ 5 , 1 , 27 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1991 */{ 0 , 2 , 15 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1992 */{ 0 , 2 , 4 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1993 */{ 3 , 1 , 23 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1994 */{ 0 , 2 , 10 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-1995 */{ 8 , 1 , 31 , 27976 },/* 29 30 30 29 30 30 29 30 29 30 29 29 30 384
-1996 */{ 0 , 2 , 19 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
-1997 */{ 0 , 2 , 8 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1998 */{ 5 , 1 , 28 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
-1999 */{ 0 , 2 , 16 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-2000 */{ 0 , 2 , 5 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-2001 */{ 4 , 1 , 24 , 58536 },/* 30 30 30 29 29 30 29 29 30 29 30 29 30 384
-2002 */{ 0 , 2 , 12 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-2003 */{ 0 , 2 , 1 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-2004 */{ 2 , 1 , 22 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-2005 */{ 0 , 2 , 9 , 22208 },/* 29 30 29 30 29 30 30 29 30 30 29 29 0 354
-2006 */{ 7 , 1 , 29 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
-2007 */{ 0 , 2 , 18 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-2008 */{ 0 , 2 , 7 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-2009 */{ 5 , 1 , 26 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-2010 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-2011 */{ 0 , 2 , 3 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-2012 */{ 3 , 1 , 23 , 47696 },/* 30 29 30 30 30 29 30 29 29 30 29 30 29 384
-2013 */{ 0 , 2 , 10 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-2014 */{ 9 , 1 , 31 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-2015 */{ 0 , 2 , 19 , 19360 },/* 29 30 29 29 30 29 30 30 30 29 30 29 0 354
-2016 */{ 0 , 2 , 8 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-2017 */{ 5 , 1 , 28 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-2018 */{ 0 , 2 , 16 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-2019 */{ 0 , 2 , 5 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-2020 */{ 4 , 1 , 25 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-2021 */{ 0 , 2 , 12 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-2022 */{ 0 , 2 , 1 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2023 */{ 2 , 1 , 22 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-2024 */{ 0 , 2 , 10 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-2025 */{ 6 , 1 , 29 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-2026 */{ 0 , 2 , 17 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-2027 */{ 0 , 2 , 7 , 21104 },/* 29 30 29 30 29 29 30 29 29 30 30 30 0 354
-2028 */{ 5 , 1 , 27 , 26928 },/* 29 30 30 29 30 29 29 30 29 29 30 30 29 383
-2029 */{ 0 , 2 , 13 , 55600 },/* 30 30 29 30 30 29 29 30 29 29 30 30 0 355
-2030 */{ 0 , 2 , 3 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-2031 */{ 3 , 1 , 23 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 29 384
-2032 */{ 0 , 2 , 11 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-2033 */{ 11 , 1 , 31 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-2034 */{ 0 , 2 , 19 , 19168 },/* 29 30 29 29 30 29 30 29 30 30 30 29 0 354
-2035 */{ 0 , 2 , 8 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-2036 */{ 6 , 1 , 28 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-2037 */{ 0 , 2 , 15 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-2038 */{ 0 , 2 , 4 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
-2039 */{ 5 , 1 , 24 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 29 384
-2040 */{ 0 , 2 , 12 , 46752 },/* 30 29 30 30 29 30 30 29 30 29 30 29 0 355
-2041 */{ 0 , 2 , 1 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-2042 */{ 2 , 1 , 22 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
-2043 */{ 0 , 2 , 10 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-2044 */{ 7 , 1 , 30 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-2045 */{ 0 , 2 , 17 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-2046 */{ 0 , 2 , 6 , 45648 },/* 30 29 30 30 29 29 30 29 29 30 29 30 0 354
-2047 */{ 5 , 1 , 26 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-2048 */{ 0 , 2 , 14 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-2049 */{ 0 , 2 , 2 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
-2050 */{ 3 , 1 , 23 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 29 384
- */};
-
-
- internal override int MinCalendarYear {
- get
- {
- return (MIN_LUNISOLAR_YEAR);
- }
- }
-
- internal override int MaxCalendarYear {
- get
- {
- return (MAX_LUNISOLAR_YEAR);
- }
- }
-
- internal override DateTime MinDate {
- get
- {
- return (minDate);
- }
- }
-
- internal override DateTime MaxDate {
- get
- {
- return (maxDate);
- }
- }
-
- internal override EraInfo[] CalEraInfo {
- get
- {
- return null;
- }
- }
-
- internal override int GetYearInfo(int LunarYear, int Index) {
- if ((LunarYear < MIN_LUNISOLAR_YEAR) || (LunarYear > MAX_LUNISOLAR_YEAR)) {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- MIN_LUNISOLAR_YEAR,
- MAX_LUNISOLAR_YEAR ));
- }
- Contract.EndContractBlock();
- return yinfo[LunarYear - MIN_LUNISOLAR_YEAR, Index];
- }
-
- internal override int GetYear(int year, DateTime time)
- {
- return year;
- }
-
- internal override int GetGregorianYear(int year, int era)
- {
- if (era != CurrentEra && era != GregorianEra)
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
-
- if (year < MIN_LUNISOLAR_YEAR || year > MAX_LUNISOLAR_YEAR)
- {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"), MIN_LUNISOLAR_YEAR, MAX_LUNISOLAR_YEAR));
- }
- Contract.EndContractBlock();
-
- return year;
- }
-
- /*=================================GetDefaultInstance==========================
- **Action: Internal method to provide a default intance of KoreanLunisolarCalendar. Used by NLS+ implementation
- ** and other calendars.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
- /*
- internal static Calendar GetDefaultInstance()
- {
- if (m_defaultInstance == null) {
- m_defaultInstance = new KoreanLunisolarCalendar();
- }
- return (m_defaultInstance);
- }
- */
-
- // Construct an instance of KoreanLunisolar calendar.
-
- public KoreanLunisolarCalendar() {
- }
-
-
-
- public override int GetEra(DateTime time) {
- CheckTicksRange(time.Ticks);
- return (GregorianEra);
- }
-
- internal override int BaseCalendarID {
- get {
- return (CAL_KOREA);
- }
- }
-
- internal override int ID {
- get {
- return (CAL_KOREANLUNISOLAR);
- }
- }
-
-
-
- public override int[] Eras {
- get {
- return (new int[] {GregorianEra});
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/NumberFormatInfo.cs b/src/mscorlib/src/System/Globalization/NumberFormatInfo.cs
index d95aac3d3d..c44c085a69 100644
--- a/src/mscorlib/src/System/Globalization/NumberFormatInfo.cs
+++ b/src/mscorlib/src/System/Globalization/NumberFormatInfo.cs
@@ -2,11 +2,13 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Globalization {
- using System.Runtime.Serialization;
- using System.Text;
- using System;
- using System.Diagnostics.Contracts;
+using System;
+using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace System.Globalization
+{
//
// Property Default Description
// PositiveSign '+' Character used to indicate positive values.
@@ -40,19 +42,19 @@ namespace System.Globalization {
//
[Serializable]
- sealed public partial class NumberFormatInfo : ICloneable, IFormatProvider
+ sealed public class NumberFormatInfo : IFormatProvider, ICloneable
{
// invariantInfo is constant irrespective of your current culture.
- private static volatile NumberFormatInfo invariantInfo;
+ private static volatile NumberFormatInfo s_invariantInfo;
// READTHIS READTHIS READTHIS
// This class has an exact mapping onto a native structure defined in COMNumber.cpp
// DO NOT UPDATE THIS WITHOUT UPDATING THAT STRUCTURE. IF YOU ADD BOOL, ADD THEM AT THE END.
// ALSO MAKE SURE TO UPDATE mscorlib.h in the VM directory to check field offsets.
// READTHIS READTHIS READTHIS
- internal int[] numberGroupSizes = new int[] {3};
- internal int[] currencyGroupSizes = new int[] {3};
- internal int[] percentGroupSizes = new int[] {3};
+ internal int[] numberGroupSizes = new int[] { 3 };
+ internal int[] currencyGroupSizes = new int[] { 3 };
+ internal int[] percentGroupSizes = new int[] { 3 };
internal String positiveSign = "+";
internal String negativeSign = "-";
internal String numberDecimalSeparator = ".";
@@ -60,10 +62,6 @@ namespace System.Globalization {
internal String currencyGroupSeparator = ",";
internal String currencyDecimalSeparator = ".";
internal String currencySymbol = "\x00a4"; // U+00a4 is the symbol for International Monetary Fund.
- // The alternative currency symbol used in Win9x ANSI codepage, that can not roundtrip between ANSI and Unicode.
- // Currently, only ja-JP and ko-KR has non-null values (which is U+005c, backslash)
- // NOTE: The only legal values for this string are null and "\x005c"
- internal String ansiCurrencySymbol = null;
internal String nanSymbol = "NaN";
internal String positiveInfinitySymbol = "Infinity";
internal String negativeInfinitySymbol = "-Infinity";
@@ -72,14 +70,9 @@ namespace System.Globalization {
internal String percentSymbol = "%";
internal String perMilleSymbol = "\u2030";
- [OptionalField(VersionAdded = 2)]
- internal String[] nativeDigits = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
- // an index which points to a record in Culture Data Table.
- // We shouldn't be persisting dataItem (since its useless & we weren't using it),
- // but since COMNumber.cpp uses it and since serialization isn't implimented, its stuck for now.
- [OptionalField(VersionAdded = 1)]
- internal int m_dataItem = 0; // NEVER USED, DO NOT USE THIS! (Serialized in Everett)
+ [OptionalField(VersionAdded = 2)]
+ internal String[] nativeDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
internal int numberDecimalDigits = 2;
internal int currencyDecimalDigits = 2;
@@ -91,109 +84,100 @@ namespace System.Globalization {
internal int percentDecimalDigits = 2;
[OptionalField(VersionAdded = 2)]
- internal int digitSubstitution = 1; // DigitShapes.None
+ internal int digitSubstitution = (int) DigitShapes.None;
- internal bool isReadOnly=false;
- // We shouldn't be persisting m_useUserOverride (since its useless & we weren't using it),
- // but since COMNumber.cpp uses it and since serialization isn't implimented, its stuck for now.
- [OptionalField(VersionAdded = 1)]
- internal bool m_useUserOverride=false; // NEVER USED, DO NOT USE THIS! (Serialized in Everett)
+ internal bool isReadOnly = false;
// Is this NumberFormatInfo for invariant culture?
+
[OptionalField(VersionAdded = 2)]
- internal bool m_isInvariant=false;
+ internal bool m_isInvariant = false;
- public NumberFormatInfo() : this(null) {
+ public NumberFormatInfo() : this(null)
+ {
}
-#region Serialization
- // Check if NumberFormatInfo was not set up ambiguously for parsing as number and currency
- // eg. if the NumberDecimalSeparator and the NumberGroupSeparator were the same. This check
- // is solely for backwards compatibility / version tolerant serialization
- [OptionalField(VersionAdded = 1)]
- internal bool validForParseAsNumber = true; // NEVER USED, DO NOT USE THIS! (Serialized in Whidbey/Everett)
- [OptionalField(VersionAdded = 1)]
- internal bool validForParseAsCurrency = true; // NEVER USED, DO NOT USE THIS! (Serialized in Whidbey/Everett)
-
[OnSerializing]
- private void OnSerializing(StreamingContext ctx)
- {
- }
+ private void OnSerializing(StreamingContext ctx) { }
[OnDeserializing]
- private void OnDeserializing(StreamingContext ctx)
- {
- }
+ private void OnDeserializing(StreamingContext ctx) { }
[OnDeserialized]
- private void OnDeserialized(StreamingContext ctx)
- {
- }
-#endregion Serialization
+ private void OnDeserialized(StreamingContext ctx) { }
- static private void VerifyDecimalSeparator(String decSep, String propertyName) {
- if (decSep==null) {
+ private static void VerifyDecimalSeparator(String decSep, String propertyName)
+ {
+ if (decSep == null)
+ {
throw new ArgumentNullException(propertyName,
- Environment.GetResourceString("ArgumentNull_String"));
+ SR.ArgumentNull_String);
}
- if (decSep.Length==0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyDecString"));
+ if (decSep.Length == 0)
+ {
+ throw new ArgumentException(SR.Argument_EmptyDecString);
}
Contract.EndContractBlock();
-
}
- static private void VerifyGroupSeparator(String groupSep, String propertyName) {
- if (groupSep==null) {
+ private static void VerifyGroupSeparator(String groupSep, String propertyName)
+ {
+ if (groupSep == null)
+ {
throw new ArgumentNullException(propertyName,
- Environment.GetResourceString("ArgumentNull_String"));
+ SR.ArgumentNull_String);
}
Contract.EndContractBlock();
}
- static private void VerifyNativeDigits(String [] nativeDig, String propertyName) {
- if (nativeDig==null) {
- throw new ArgumentNullException(propertyName,
- Environment.GetResourceString("ArgumentNull_Array"));
+ private static void VerifyNativeDigits(string [] nativeDig, string propertyName)
+ {
+ if (nativeDig == null)
+ {
+ throw new ArgumentNullException(propertyName, SR.ArgumentNull_Array);
}
if (nativeDig.Length != 10)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNativeDigitCount"), propertyName);
+ throw new ArgumentException(SR.Argument_InvalidNativeDigitCount, propertyName);
}
Contract.EndContractBlock();
- for(int i = 0; i < nativeDig.Length; i++)
+ for (int i = 0; i < nativeDig.Length; i++)
{
if (nativeDig[i] == null)
{
- throw new ArgumentNullException(propertyName,
- Environment.GetResourceString("ArgumentNull_ArrayValue"));
+ throw new ArgumentNullException(propertyName, SR.ArgumentNull_ArrayValue);
}
-
- if (nativeDig[i].Length != 1) {
- if(nativeDig[i].Length != 2) {
+ if (nativeDig[i].Length != 1)
+ {
+ if (nativeDig[i].Length != 2)
+ {
// Not 1 or 2 UTF-16 code points
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNativeDigitValue"), propertyName);
- } else if(!char.IsSurrogatePair(nativeDig[i][0], nativeDig[i][1])) {
+ throw new ArgumentException(SR.Argument_InvalidNativeDigitValue, propertyName);
+ }
+ else if (!char.IsSurrogatePair(nativeDig[i][0], nativeDig[i][1]))
+ {
// 2 UTF-6 code points, but not a surrogate pair
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNativeDigitValue"), propertyName);
+ throw new ArgumentException(SR.Argument_InvalidNativeDigitValue, propertyName);
}
}
if (CharUnicodeInfo.GetDecimalDigitValue(nativeDig[i], 0) != i &&
- CharUnicodeInfo.GetUnicodeCategory(nativeDig[i], 0) != UnicodeCategory.PrivateUse) {
+ CharUnicodeInfo.GetUnicodeCategory(nativeDig[i], 0) != UnicodeCategory.PrivateUse)
+ {
// Not the appropriate digit according to the Unicode data properties
// (Digit 0 must be a 0, etc.).
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNativeDigitValue"), propertyName);
+ throw new ArgumentException(SR.Argument_InvalidNativeDigitValue, propertyName);
}
}
}
- static private void VerifyDigitSubstitution(DigitShapes digitSub, String propertyName) {
- switch(digitSub)
+ private static void VerifyDigitSubstitution(DigitShapes digitSub, string propertyName)
+ {
+ switch (digitSub)
{
case DigitShapes.Context:
case DigitShapes.None:
@@ -202,12 +186,10 @@ namespace System.Globalization {
break;
default:
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDigitSubstitution"), propertyName);
+ throw new ArgumentException(SR.Argument_InvalidDigitSubstitution, propertyName);
}
}
- // We aren't persisting dataItem any more (since its useless & we weren't using it),
- // Ditto with m_useUserOverride. Don't use them, we use a local copy of everything.
internal NumberFormatInfo(CultureData cultureData)
{
if (cultureData != null)
@@ -225,9 +207,11 @@ namespace System.Globalization {
}
[Pure]
- private void VerifyWritable() {
- if (isReadOnly) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
+ private void VerifyWritable()
+ {
+ if (isReadOnly)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
Contract.EndContractBlock();
}
@@ -237,41 +221,50 @@ namespace System.Globalization {
// Used by FromString methods.
//
- public static NumberFormatInfo InvariantInfo {
- get {
- if (invariantInfo == null) {
+ public static NumberFormatInfo InvariantInfo
+ {
+ get
+ {
+ if (s_invariantInfo == null)
+ {
// Lazy create the invariant info. This cannot be done in a .cctor because exceptions can
// be thrown out of a .cctor stack that will need this.
NumberFormatInfo nfi = new NumberFormatInfo();
nfi.m_isInvariant = true;
- invariantInfo = ReadOnly(nfi);
+ s_invariantInfo = ReadOnly(nfi);
}
- return invariantInfo;
+ return s_invariantInfo;
}
}
-
- public static NumberFormatInfo GetInstance(IFormatProvider formatProvider) {
+ public static NumberFormatInfo GetInstance(IFormatProvider formatProvider)
+ {
// Fast case for a regular CultureInfo
NumberFormatInfo info;
CultureInfo cultureProvider = formatProvider as CultureInfo;
- if (cultureProvider != null && !cultureProvider.m_isInherited) {
+ if (cultureProvider != null && !cultureProvider._isInherited)
+ {
info = cultureProvider.numInfo;
- if (info != null) {
+ if (info != null)
+ {
return info;
}
- else {
+ else
+ {
return cultureProvider.NumberFormat;
}
}
// Fast case for an NFI;
info = formatProvider as NumberFormatInfo;
- if (info != null) {
+ if (info != null)
+ {
return info;
}
- if (formatProvider != null) {
+ if (formatProvider != null)
+ {
info = formatProvider.GetFormat(typeof(NumberFormatInfo)) as NumberFormatInfo;
- if (info != null) {
+ if (info != null)
+ {
return info;
}
}
@@ -280,22 +273,26 @@ namespace System.Globalization {
- public Object Clone() {
+ public Object Clone()
+ {
NumberFormatInfo n = (NumberFormatInfo)MemberwiseClone();
n.isReadOnly = false;
return n;
}
- public int CurrencyDecimalDigits {
+ public int CurrencyDecimalDigits
+ {
get { return currencyDecimalDigits; }
- set {
- if (value < 0 || value > 99) {
+ set
+ {
+ if (value < 0 || value > 99)
+ {
throw new ArgumentOutOfRangeException(
nameof(CurrencyDecimalDigits),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
+ SR.ArgumentOutOfRange_Range,
0,
99));
}
@@ -306,18 +303,22 @@ namespace System.Globalization {
}
- public String CurrencyDecimalSeparator {
+ public String CurrencyDecimalSeparator
+ {
get { return currencyDecimalSeparator; }
- set {
+ set
+ {
VerifyWritable();
- VerifyDecimalSeparator(value, nameof(CurrencyDecimalSeparator));
+ VerifyDecimalSeparator(value, "CurrencyDecimalSeparator");
currencyDecimalSeparator = value;
}
}
- public bool IsReadOnly {
- get {
+ public bool IsReadOnly
+ {
+ get
+ {
return isReadOnly;
}
}
@@ -328,7 +329,7 @@ namespace System.Globalization {
// Every element in the groupSize array should be between 1 and 9
// excpet the last element could be zero.
//
- static internal void CheckGroupSize(String propName, int[] groupSize)
+ internal static void CheckGroupSize(String propName, int[] groupSize)
{
for (int i = 0; i < groupSize.Length; i++)
{
@@ -336,49 +337,56 @@ namespace System.Globalization {
{
if (i == groupSize.Length - 1 && groupSize[i] == 0)
return;
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidGroupSize"), propName);
+ throw new ArgumentException(SR.Argument_InvalidGroupSize, propName);
}
else if (groupSize[i] > 9)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidGroupSize"), propName);
+ throw new ArgumentException(SR.Argument_InvalidGroupSize, propName);
}
}
}
- public int[] CurrencyGroupSizes {
- get {
+ public int[] CurrencyGroupSizes
+ {
+ get
+ {
return ((int[])currencyGroupSizes.Clone());
}
- set {
- if (value == null) {
+ set
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(CurrencyGroupSizes),
- Environment.GetResourceString("ArgumentNull_Obj"));
+ SR.ArgumentNull_Obj);
}
Contract.EndContractBlock();
- VerifyWritable();
-
+ VerifyWritable();
+
Int32[] inputSizes = (Int32[])value.Clone();
CheckGroupSize(nameof(CurrencyGroupSizes), inputSizes);
currencyGroupSizes = inputSizes;
}
-
}
- public int[] NumberGroupSizes {
- get {
+ public int[] NumberGroupSizes
+ {
+ get
+ {
return ((int[])numberGroupSizes.Clone());
}
- set {
- if (value == null) {
+ set
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(NumberGroupSizes),
- Environment.GetResourceString("ArgumentNull_Obj"));
+ SR.ArgumentNull_Obj);
}
Contract.EndContractBlock();
VerifyWritable();
-
+
Int32[] inputSizes = (Int32[])value.Clone();
CheckGroupSize(nameof(NumberGroupSizes), inputSizes);
numberGroupSizes = inputSizes;
@@ -386,28 +394,33 @@ namespace System.Globalization {
}
- public int[] PercentGroupSizes {
- get {
+ public int[] PercentGroupSizes
+ {
+ get
+ {
return ((int[])percentGroupSizes.Clone());
}
- set {
- if (value == null) {
- throw new ArgumentNullException(nameof(PercentGroupSizes),
- Environment.GetResourceString("ArgumentNull_Obj"));
+ set
+ {
+ if (value == null)
+ {
+ throw new ArgumentNullException("PercentGroupSizes",
+ SR.ArgumentNull_Obj);
}
Contract.EndContractBlock();
VerifyWritable();
Int32[] inputSizes = (Int32[])value.Clone();
- CheckGroupSize(nameof(PercentGroupSizes), inputSizes);
+ CheckGroupSize("PercentGroupSizes", inputSizes);
percentGroupSizes = inputSizes;
}
-
}
- public String CurrencyGroupSeparator {
+ public String CurrencyGroupSeparator
+ {
get { return currencyGroupSeparator; }
- set {
+ set
+ {
VerifyWritable();
VerifyGroupSeparator(value, nameof(CurrencyGroupSeparator));
currencyGroupSeparator = value;
@@ -415,12 +428,15 @@ namespace System.Globalization {
}
- public String CurrencySymbol {
+ public String CurrencySymbol
+ {
get { return currencySymbol; }
- set {
- if (value == null) {
+ set
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(CurrencySymbol),
- Environment.GetResourceString("ArgumentNull_String"));
+ SR.ArgumentNull_String);
}
Contract.EndContractBlock();
VerifyWritable();
@@ -431,12 +447,16 @@ namespace System.Globalization {
// Returns the current culture's NumberFormatInfo. Used by Parse methods.
//
- public static NumberFormatInfo CurrentInfo {
- get {
- System.Globalization.CultureInfo culture = System.Threading.Thread.CurrentThread.CurrentCulture;
- if (!culture.m_isInherited) {
+ public static NumberFormatInfo CurrentInfo
+ {
+ get
+ {
+ System.Globalization.CultureInfo culture = CultureInfo.CurrentCulture;
+ if (!culture._isInherited)
+ {
NumberFormatInfo info = culture.numInfo;
- if (info != null) {
+ if (info != null)
+ {
return info;
}
}
@@ -445,14 +465,18 @@ namespace System.Globalization {
}
- public String NaNSymbol {
- get {
+ public String NaNSymbol
+ {
+ get
+ {
return nanSymbol;
}
- set {
- if (value == null) {
+ set
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(NaNSymbol),
- Environment.GetResourceString("ArgumentNull_String"));
+ SR.ArgumentNull_String);
}
Contract.EndContractBlock();
VerifyWritable();
@@ -462,15 +486,18 @@ namespace System.Globalization {
- public int CurrencyNegativePattern {
+ public int CurrencyNegativePattern
+ {
get { return currencyNegativePattern; }
- set {
- if (value < 0 || value > 15) {
+ set
+ {
+ if (value < 0 || value > 15)
+ {
throw new ArgumentOutOfRangeException(
nameof(CurrencyNegativePattern),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
+ SR.ArgumentOutOfRange_Range,
0,
15));
}
@@ -481,18 +508,21 @@ namespace System.Globalization {
}
- public int NumberNegativePattern {
+ public int NumberNegativePattern
+ {
get { return numberNegativePattern; }
- set {
+ set
+ {
//
// NOTENOTE: the range of value should correspond to negNumberFormats[] in vm\COMNumber.cpp.
//
- if (value < 0 || value > 4) {
+ if (value < 0 || value > 4)
+ {
throw new ArgumentOutOfRangeException(
nameof(NumberNegativePattern),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
+ SR.ArgumentOutOfRange_Range,
0,
4));
}
@@ -503,18 +533,21 @@ namespace System.Globalization {
}
- public int PercentPositivePattern {
+ public int PercentPositivePattern
+ {
get { return percentPositivePattern; }
- set {
+ set
+ {
//
// NOTENOTE: the range of value should correspond to posPercentFormats[] in vm\COMNumber.cpp.
//
- if (value < 0 || value > 3) {
+ if (value < 0 || value > 3)
+ {
throw new ArgumentOutOfRangeException(
nameof(PercentPositivePattern),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
+ SR.ArgumentOutOfRange_Range,
0,
3));
}
@@ -525,18 +558,21 @@ namespace System.Globalization {
}
- public int PercentNegativePattern {
+ public int PercentNegativePattern
+ {
get { return percentNegativePattern; }
- set {
+ set
+ {
//
// NOTENOTE: the range of value should correspond to posPercentFormats[] in vm\COMNumber.cpp.
//
- if (value < 0 || value > 11) {
+ if (value < 0 || value > 11)
+ {
throw new ArgumentOutOfRangeException(
nameof(PercentNegativePattern),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
+ SR.ArgumentOutOfRange_Range,
0,
11));
}
@@ -547,14 +583,18 @@ namespace System.Globalization {
}
- public String NegativeInfinitySymbol {
- get {
+ public String NegativeInfinitySymbol
+ {
+ get
+ {
return negativeInfinitySymbol;
}
- set {
- if (value == null) {
+ set
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(NegativeInfinitySymbol),
- Environment.GetResourceString("ArgumentNull_String"));
+ SR.ArgumentNull_String);
}
Contract.EndContractBlock();
VerifyWritable();
@@ -563,12 +603,15 @@ namespace System.Globalization {
}
- public String NegativeSign {
+ public String NegativeSign
+ {
get { return negativeSign; }
- set {
- if (value == null) {
+ set
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(NegativeSign),
- Environment.GetResourceString("ArgumentNull_String"));
+ SR.ArgumentNull_String);
}
Contract.EndContractBlock();
VerifyWritable();
@@ -577,15 +620,18 @@ namespace System.Globalization {
}
- public int NumberDecimalDigits {
+ public int NumberDecimalDigits
+ {
get { return numberDecimalDigits; }
- set {
- if (value < 0 || value > 99) {
+ set
+ {
+ if (value < 0 || value > 99)
+ {
throw new ArgumentOutOfRangeException(
nameof(NumberDecimalDigits),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
+ SR.ArgumentOutOfRange_Range,
0,
99));
}
@@ -596,9 +642,11 @@ namespace System.Globalization {
}
- public String NumberDecimalSeparator {
+ public String NumberDecimalSeparator
+ {
get { return numberDecimalSeparator; }
- set {
+ set
+ {
VerifyWritable();
VerifyDecimalSeparator(value, nameof(NumberDecimalSeparator));
numberDecimalSeparator = value;
@@ -606,9 +654,11 @@ namespace System.Globalization {
}
- public String NumberGroupSeparator {
+ public String NumberGroupSeparator
+ {
get { return numberGroupSeparator; }
- set {
+ set
+ {
VerifyWritable();
VerifyGroupSeparator(value, nameof(NumberGroupSeparator));
numberGroupSeparator = value;
@@ -616,15 +666,18 @@ namespace System.Globalization {
}
- public int CurrencyPositivePattern {
+ public int CurrencyPositivePattern
+ {
get { return currencyPositivePattern; }
- set {
- if (value < 0 || value > 3) {
+ set
+ {
+ if (value < 0 || value > 3)
+ {
throw new ArgumentOutOfRangeException(
nameof(CurrencyPositivePattern),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
+ SR.ArgumentOutOfRange_Range,
0,
3));
}
@@ -635,14 +688,18 @@ namespace System.Globalization {
}
- public String PositiveInfinitySymbol {
- get {
+ public String PositiveInfinitySymbol
+ {
+ get
+ {
return positiveInfinitySymbol;
}
- set {
- if (value == null) {
+ set
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(PositiveInfinitySymbol),
- Environment.GetResourceString("ArgumentNull_String"));
+ SR.ArgumentNull_String);
}
Contract.EndContractBlock();
VerifyWritable();
@@ -651,12 +708,15 @@ namespace System.Globalization {
}
- public String PositiveSign {
+ public String PositiveSign
+ {
get { return positiveSign; }
- set {
- if (value == null) {
+ set
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(PositiveSign),
- Environment.GetResourceString("ArgumentNull_String"));
+ SR.ArgumentNull_String);
}
Contract.EndContractBlock();
VerifyWritable();
@@ -665,15 +725,18 @@ namespace System.Globalization {
}
- public int PercentDecimalDigits {
+ public int PercentDecimalDigits
+ {
get { return percentDecimalDigits; }
- set {
- if (value < 0 || value > 99) {
+ set
+ {
+ if (value < 0 || value > 99)
+ {
throw new ArgumentOutOfRangeException(
nameof(PercentDecimalDigits),
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
+ SR.ArgumentOutOfRange_Range,
0,
99));
}
@@ -684,9 +747,11 @@ namespace System.Globalization {
}
- public String PercentDecimalSeparator {
+ public String PercentDecimalSeparator
+ {
get { return percentDecimalSeparator; }
- set {
+ set
+ {
VerifyWritable();
VerifyDecimalSeparator(value, nameof(PercentDecimalSeparator));
percentDecimalSeparator = value;
@@ -694,9 +759,11 @@ namespace System.Globalization {
}
- public String PercentGroupSeparator {
+ public String PercentGroupSeparator
+ {
get { return percentGroupSeparator; }
- set {
+ set
+ {
VerifyWritable();
VerifyGroupSeparator(value, nameof(PercentGroupSeparator));
percentGroupSeparator = value;
@@ -704,14 +771,18 @@ namespace System.Globalization {
}
- public String PercentSymbol {
- get {
+ public String PercentSymbol
+ {
+ get
+ {
return percentSymbol;
}
- set {
- if (value == null) {
+ set
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(PercentSymbol),
- Environment.GetResourceString("ArgumentNull_String"));
+ SR.ArgumentNull_String);
}
Contract.EndContractBlock();
VerifyWritable();
@@ -720,12 +791,15 @@ namespace System.Globalization {
}
- public String PerMilleSymbol {
+ public String PerMilleSymbol
+ {
get { return perMilleSymbol; }
- set {
- if (value == null) {
+ set
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(PerMilleSymbol),
- Environment.GetResourceString("ArgumentNull_String"));
+ SR.ArgumentNull_String);
}
Contract.EndContractBlock();
VerifyWritable();
@@ -733,10 +807,9 @@ namespace System.Globalization {
}
}
-
- public String[] NativeDigits
+ public string [] NativeDigits
{
- get { return (String[])nativeDigits.Clone(); }
+ get { return (String[]) nativeDigits.Clone(); }
set
{
VerifyWritable();
@@ -747,25 +820,29 @@ namespace System.Globalization {
public DigitShapes DigitSubstitution
{
- get { return (DigitShapes)digitSubstitution; }
+ get { return (DigitShapes) digitSubstitution; }
set
{
VerifyWritable();
VerifyDigitSubstitution(value, nameof(DigitSubstitution));
- digitSubstitution = (int)value;
+ digitSubstitution = (int) value;
}
}
- public Object GetFormat(Type formatType) {
- return formatType == typeof(NumberFormatInfo)? this: null;
+ public Object GetFormat(Type formatType)
+ {
+ return formatType == typeof(NumberFormatInfo) ? this : null;
}
- public static NumberFormatInfo ReadOnly(NumberFormatInfo nfi) {
- if (nfi == null) {
+ public static NumberFormatInfo ReadOnly(NumberFormatInfo nfi)
+ {
+ if (nfi == null)
+ {
throw new ArgumentNullException(nameof(nfi));
}
Contract.EndContractBlock();
- if (nfi.IsReadOnly) {
+ if (nfi.IsReadOnly)
+ {
return (nfi);
}
NumberFormatInfo info = (NumberFormatInfo)(nfi.MemberwiseClone());
@@ -780,27 +857,34 @@ namespace System.Globalization {
| NumberStyles.AllowThousands | NumberStyles.AllowExponent
| NumberStyles.AllowCurrencySymbol | NumberStyles.AllowHexSpecifier);
- internal static void ValidateParseStyleInteger(NumberStyles style) {
+ internal static void ValidateParseStyleInteger(NumberStyles style)
+ {
// Check for undefined flags
- if ((style & InvalidNumberStyles) != 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNumberStyles"), nameof(style));
+ if ((style & InvalidNumberStyles) != 0)
+ {
+ throw new ArgumentException(SR.Argument_InvalidNumberStyles, nameof(style));
}
Contract.EndContractBlock();
- if ((style & NumberStyles.AllowHexSpecifier) != 0) { // Check for hex number
- if ((style & ~NumberStyles.HexNumber) != 0) {
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidHexStyle"));
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ { // Check for hex number
+ if ((style & ~NumberStyles.HexNumber) != 0)
+ {
+ throw new ArgumentException(SR.Arg_InvalidHexStyle);
}
}
}
- internal static void ValidateParseStyleFloatingPoint(NumberStyles style) {
+ internal static void ValidateParseStyleFloatingPoint(NumberStyles style)
+ {
// Check for undefined flags
- if ((style & InvalidNumberStyles) != 0) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNumberStyles"), nameof(style));
+ if ((style & InvalidNumberStyles) != 0)
+ {
+ throw new ArgumentException(SR.Argument_InvalidNumberStyles, nameof(style));
}
Contract.EndContractBlock();
- if ((style & NumberStyles.AllowHexSpecifier) != 0) { // Check for hex number
- throw new ArgumentException(Environment.GetResourceString("Arg_HexStyleNotSupported"));
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ { // Check for hex number
+ throw new ArgumentException(SR.Arg_HexStyleNotSupported);
}
}
} // NumberFormatInfo
diff --git a/src/mscorlib/src/System/Globalization/NumberStyles.cs b/src/mscorlib/src/System/Globalization/NumberStyles.cs
deleted file mode 100644
index 969c07fc2a..0000000000
--- a/src/mscorlib/src/System/Globalization/NumberStyles.cs
+++ /dev/null
@@ -1,66 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose: Contains valid formats for Numbers recognized by
-** the Number class' parsing code.
-**
-**
-===========================================================*/
-namespace System.Globalization {
-
- using System;
- [Serializable]
- [Flags]
- public enum NumberStyles {
- // Bit flag indicating that leading whitespace is allowed. Character values
- // 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, and 0x0020 are considered to be
- // whitespace.
-
- None = 0x00000000,
-
- AllowLeadingWhite = 0x00000001,
-
- AllowTrailingWhite = 0x00000002, //Bitflag indicating trailing whitespace is allowed.
-
- AllowLeadingSign = 0x00000004, //Can the number start with a sign char.
- //Specified by NumberFormatInfo.PositiveSign and NumberFormatInfo.NegativeSign
-
- AllowTrailingSign = 0x00000008, //Allow the number to end with a sign char
-
- AllowParentheses = 0x00000010, //Allow the number to be enclosed in parens
-
- AllowDecimalPoint = 0x00000020, //Allow a decimal point
-
- AllowThousands = 0x00000040, //Allow thousands separators (more properly, allow group separators)
-
- AllowExponent = 0x00000080, //Allow an exponent
-
- AllowCurrencySymbol = 0x00000100, //Allow a currency symbol.
-
- AllowHexSpecifier = 0x00000200, //Allow specifiying hexadecimal.
- //Common uses. These represent some of the most common combinations of these flags.
-
-
- Integer = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign,
-
- HexNumber = AllowLeadingWhite | AllowTrailingWhite | AllowHexSpecifier,
-
- Number = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | AllowTrailingSign |
- AllowDecimalPoint | AllowThousands,
-
- Float = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign |
- AllowDecimalPoint | AllowExponent,
-
- Currency = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | AllowTrailingSign |
- AllowParentheses | AllowDecimalPoint | AllowThousands | AllowCurrencySymbol,
-
- Any = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | AllowTrailingSign |
- AllowParentheses | AllowDecimalPoint | AllowThousands | AllowCurrencySymbol | AllowExponent,
-
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/PersianCalendar.cs b/src/mscorlib/src/System/Globalization/PersianCalendar.cs
deleted file mode 100644
index e61a007a02..0000000000
--- a/src/mscorlib/src/System/Globalization/PersianCalendar.cs
+++ /dev/null
@@ -1,578 +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.
-
-namespace System.Globalization {
- using System;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about PersianCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
- // Modern Persian calendar is a solar observation based calendar. Each new year begins on the day when the vernal equinox occurs before noon.
- // The epoch is the date of the vernal equinox prior to the epoch of the Islamic calendar (March 19, 622 Julian or March 22, 622 Gregorian)
-
- // There is no Persian year 0. Ordinary years have 365 days. Leap years have 366 days with the last month (Esfand) gaining the extra day.
- /*
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 0622/03/22 9999/12/31
- ** Persian 0001/01/01 9378/10/13
- */
-
- [Serializable]
- public class PersianCalendar : Calendar {
-
-
- public static readonly int PersianEra = 1;
-
- internal static long PersianEpoch = new DateTime(622, 3, 22).Ticks / GregorianCalendar.TicksPerDay;
- const int ApproximateHalfYear = 180;
-
- internal const int DatePartYear = 0;
- internal const int DatePartDayOfYear = 1;
- internal const int DatePartMonth = 2;
- internal const int DatePartDay = 3;
- internal const int MonthsPerYear = 12;
-
- internal static int[] DaysToMonth = { 0, 31, 62, 93, 124, 155, 186, 216, 246, 276, 306, 336, 366 };
-
- internal const int MaxCalendarYear = 9378;
- internal const int MaxCalendarMonth = 10;
- internal const int MaxCalendarDay = 13;
-
- // Persian calendar (year: 1, month: 1, day:1 ) = Gregorian (year: 622, month: 3, day: 22)
- // This is the minimal Gregorian date that we support in the PersianCalendar.
- internal static DateTime minDate = new DateTime(622, 3, 22);
- internal static DateTime maxDate = DateTime.MaxValue;
-
- /*=================================GetDefaultInstance==========================
- **Action: Internal method to provide a default intance of PersianCalendar. Used by NLS+ implementation
- ** and other calendars.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
- /*
- internal static Calendar GetDefaultInstance() {
- if (m_defaultInstance == null) {
- m_defaultInstance = new PersianCalendar();
- }
- return (m_defaultInstance);
- }
- */
-
-
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (minDate);
- }
- }
-
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (maxDate);
- }
- }
-
- // Return the type of the Persian calendar.
- //
-
-
- public override CalendarAlgorithmType AlgorithmType {
- get {
- return CalendarAlgorithmType.SolarCalendar;
- }
- }
-
- // Construct an instance of Persian calendar.
-
- public PersianCalendar() {
- }
-
-
- internal override int BaseCalendarID {
- get {
- return (CAL_GREGORIAN);
- }
- }
-
- internal override int ID {
- get {
- return (CAL_PERSIAN);
- }
- }
-
-
- /*=================================GetAbsoluteDatePersian==========================
- **Action: Gets the Absolute date for the given Persian date. The absolute date means
- ** the number of days from January 1st, 1 A.D.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
-
- long GetAbsoluteDatePersian(int year, int month, int day) {
- if (year >= 1 && year <= MaxCalendarYear && month >= 1 && month <= 12)
- {
- int ordinalDay = DaysInPreviousMonths(month) + day - 1; // day is one based, make 0 based since this will be the number of days we add to beginning of year below
- int approximateDaysFromEpochForYearStart = (int)(CalendricalCalculationsHelper.MeanTropicalYearInDays * (year - 1));
- long yearStart = CalendricalCalculationsHelper.PersianNewYearOnOrBefore(PersianEpoch + approximateDaysFromEpochForYearStart + ApproximateHalfYear);
- yearStart += ordinalDay;
- return yearStart;
- }
- throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
- }
-
- static internal void CheckTicksRange(long ticks) {
- if (ticks < minDate.Ticks || ticks > maxDate.Ticks) {
- throw new ArgumentOutOfRangeException(
- "time",
- String.Format(
- CultureInfo.InvariantCulture,
- Environment.GetResourceString("ArgumentOutOfRange_CalendarRange"),
- minDate,
- maxDate));
- }
- }
-
- static internal void CheckEraRange(int era) {
- if (era != CurrentEra && era != PersianEra) {
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
- }
- }
-
- static internal void CheckYearRange(int year, int era) {
- CheckEraRange(era);
- if (year < 1 || year > MaxCalendarYear) {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 1,
- MaxCalendarYear));
- }
- }
-
- static internal void CheckYearMonthRange(int year, int month, int era) {
- CheckYearRange(year, era);
- if (year == MaxCalendarYear) {
- if (month > MaxCalendarMonth) {
- throw new ArgumentOutOfRangeException(
- nameof(month),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 1,
- MaxCalendarMonth));
- }
- }
-
- if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
- }
- }
-
- static int MonthFromOrdinalDay(int ordinalDay)
- {
- Debug.Assert(ordinalDay <= 366);
- int index = 0;
- while (ordinalDay > DaysToMonth[index])
- index++;
-
- return index;
- }
-
- static int DaysInPreviousMonths(int month)
- {
- Debug.Assert(1 <= month && month <= 12);
- --month; // months are one based but for calculations use 0 based
- return DaysToMonth[month];
- }
-
- /*=================================GetDatePart==========================
- **Action: Returns a given date part of this <i>DateTime</i>. This method is used
- ** to compute the year, day-of-year, month, or day part.
- **Returns:
- **Arguments:
- **Exceptions: ArgumentException if part is incorrect.
- ============================================================================*/
-
- internal int GetDatePart(long ticks, int part) {
- long NumDays; // The calculation buffer in number of days.
-
- CheckTicksRange(ticks);
-
- //
- // Get the absolute date. The absolute date is the number of days from January 1st, 1 A.D.
- // 1/1/0001 is absolute date 1.
- //
- NumDays = ticks / GregorianCalendar.TicksPerDay + 1;
-
- //
- // Calculate the appromixate Persian Year.
- //
-
- long yearStart = CalendricalCalculationsHelper.PersianNewYearOnOrBefore(NumDays);
- int y = (int)(Math.Floor(((yearStart - PersianEpoch) / CalendricalCalculationsHelper.MeanTropicalYearInDays) + 0.5)) + 1;
- Debug.Assert(y >= 1);
-
- if (part == DatePartYear)
- {
- return y;
- }
-
- //
- // Calculate the Persian Month.
- //
-
- int ordinalDay = (int)(NumDays - CalendricalCalculationsHelper.GetNumberOfDays(this.ToDateTime(y, 1, 1, 0, 0, 0, 0, 1)));
-
- if (part == DatePartDayOfYear)
- {
- return ordinalDay;
- }
-
- int m = MonthFromOrdinalDay(ordinalDay);
- Debug.Assert(ordinalDay >= 1);
- Debug.Assert(m >= 1 && m <= 12);
- if (part == DatePartMonth)
- {
- return m;
- }
-
- int d = ordinalDay - DaysInPreviousMonths(m);
- Debug.Assert(1 <= d);
- Debug.Assert(d <= 31);
-
- //
- // Calculate the Persian Day.
- //
-
- if (part == DatePartDay)
- {
- return (d);
- }
-
- // Incorrect part value.
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_DateTimeParsing"));
- }
-
- // Returns the DateTime resulting from adding the given number of
- // months to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year and month parts of the specified DateTime by
- // value months, and, if required, adjusting the day part of the
- // resulting date downwards to the last day of the resulting month in the
- // resulting year. The time-of-day part of the result is the same as the
- // time-of-day part of the specified DateTime.
- //
- // In more precise terms, considering the specified DateTime to be of the
- // form y / m / d + t, where y is the
- // year, m is the month, d is the day, and t is the
- // time-of-day, the result is y1 / m1 / d1 + t,
- // where y1 and m1 are computed by adding value months
- // to y and m, and d1 is the largest value less than
- // or equal to d that denotes a valid day in month m1 of year
- // y1.
- //
-
-
- public override DateTime AddMonths(DateTime time, int months) {
- if (months < -120000 || months > 120000) {
- throw new ArgumentOutOfRangeException(
- nameof(months),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- -120000,
- 120000));
- }
- Contract.EndContractBlock();
- // Get the date in Persian calendar.
- int y = GetDatePart(time.Ticks, DatePartYear);
- int m = GetDatePart(time.Ticks, DatePartMonth);
- int d = GetDatePart(time.Ticks, DatePartDay);
- int i = m - 1 + months;
- if (i >= 0) {
- m = i % 12 + 1;
- y = y + i / 12;
- } else {
- m = 12 + (i + 1) % 12;
- y = y + (i - 11) / 12;
- }
- int days = GetDaysInMonth(y, m);
- if (d > days) {
- d = days;
- }
- long ticks = GetAbsoluteDatePersian(y, m, d) * TicksPerDay + time.Ticks % TicksPerDay;
- Calendar.CheckAddResult(ticks, MinSupportedDateTime, MaxSupportedDateTime);
- return (new DateTime(ticks));
- }
-
- // Returns the DateTime resulting from adding the given number of
- // years to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year part of the specified DateTime by value
- // years. If the month and day of the specified DateTime is 2/29, and if the
- // resulting year is not a leap year, the month and day of the resulting
- // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
- // parts of the result are the same as those of the specified DateTime.
- //
-
-
- public override DateTime AddYears(DateTime time, int years) {
- return (AddMonths(time, years * 12));
- }
-
- // Returns the day-of-month part of the specified DateTime. The returned
- // value is an integer between 1 and 31.
- //
-
-
- public override int GetDayOfMonth(DateTime time) {
- return (GetDatePart(time.Ticks, DatePartDay));
- }
-
- // Returns the day-of-week part of the specified DateTime. The returned value
- // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
- // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
- // Thursday, 5 indicates Friday, and 6 indicates Saturday.
- //
-
-
- public override DayOfWeek GetDayOfWeek(DateTime time) {
- return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
- }
-
- // Returns the day-of-year part of the specified DateTime. The returned value
- // is an integer between 1 and 366.
- //
-
-
- public override int GetDayOfYear(DateTime time) {
- return (GetDatePart(time.Ticks, DatePartDayOfYear));
- }
-
- // Returns the number of days in the month given by the year and
- // month arguments.
- //
-
-
- public override int GetDaysInMonth(int year, int month, int era) {
- CheckYearMonthRange(year, month, era);
-
- if ((month==MaxCalendarMonth) && (year==MaxCalendarYear)) {
- return MaxCalendarDay;
- }
-
- int daysInMonth = DaysToMonth[month] - DaysToMonth[month - 1];
- if ((month == MonthsPerYear) && !IsLeapYear(year))
- {
- Debug.Assert(daysInMonth == 30);
- --daysInMonth;
- }
- return daysInMonth;
- }
-
- // Returns the number of days in the year given by the year argument for the current era.
- //
-
- public override int GetDaysInYear(int year, int era) {
- CheckYearRange(year, era);
- if (year==MaxCalendarYear) {
- return DaysToMonth[MaxCalendarMonth-1] + MaxCalendarDay;
- }
- // Common years have 365 days. Leap years have 366 days.
- return (IsLeapYear(year, CurrentEra) ? 366: 365);
- }
-
- // Returns the era for the specified DateTime value.
-
-
- public override int GetEra(DateTime time) {
- CheckTicksRange(time.Ticks);
- return (PersianEra);
- }
-
-
-
- public override int[] Eras {
- get {
- return (new int[] {PersianEra});
- }
- }
-
- // Returns the month part of the specified DateTime. The returned value is an
- // integer between 1 and 12.
- //
-
-
- public override int GetMonth(DateTime time) {
- return (GetDatePart(time.Ticks, DatePartMonth));
- }
-
- // Returns the number of months in the specified year and era.
-
-
- public override int GetMonthsInYear(int year, int era) {
- CheckYearRange(year, era);
- if (year==MaxCalendarYear) {
- return MaxCalendarMonth;
- }
- return (12);
- }
-
- // Returns the year part of the specified DateTime. The returned value is an
- // integer between 1 and MaxCalendarYear.
- //
-
-
- public override int GetYear(DateTime time) {
- return (GetDatePart(time.Ticks, DatePartYear));
- }
-
- // Checks whether a given day in the specified era is a leap day. This method returns true if
- // the date is a leap day, or false if not.
- //
-
-
- public override bool IsLeapDay(int year, int month, int day, int era) {
- // The year/month/era value checking is done in GetDaysInMonth().
- int daysInMonth = GetDaysInMonth(year, month, era);
- if (day < 1 || day > daysInMonth) {
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Day"),
- daysInMonth,
- month));
- }
- return (IsLeapYear(year, era) && month == 12 && day == 30);
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
-
- public override int GetLeapMonth(int year, int era)
- {
- CheckYearRange(year, era);
- return (0);
- }
-
- // Checks whether a given month in the specified era is a leap month. This method returns true if
- // month is a leap month, or false if not.
- //
-
-
- public override bool IsLeapMonth(int year, int month, int era) {
- CheckYearMonthRange(year, month, era);
- return (false);
- }
-
- // Checks whether a given year in the specified era is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
-
- public override bool IsLeapYear(int year, int era) {
- CheckYearRange(year, era);
-
- if (year == MaxCalendarYear)
- {
- return false;
- }
-
- return (GetAbsoluteDatePersian(year + 1, 1, 1) - GetAbsoluteDatePersian(year, 1, 1)) == 366;
- }
-
- // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
- //
-
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) {
- // The year/month/era checking is done in GetDaysInMonth().
- int daysInMonth = GetDaysInMonth(year, month, era);
- if (day < 1 || day > daysInMonth) {
- BCLDebug.Log("year = " + year + ", month = " + month + ", day = " + day);
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Day"),
- daysInMonth,
- month));
- }
-
- long lDate = GetAbsoluteDatePersian(year, month, day);
-
- if (lDate >= 0) {
- return (new DateTime(lDate * GregorianCalendar.TicksPerDay + TimeToTicks(hour, minute, second, millisecond)));
- } else {
- throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
- }
- }
-
- private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 1410;
-
- public override int TwoDigitYearMax {
- get {
- if (twoDigitYearMax == -1) {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
- }
- return (twoDigitYearMax);
- }
-
- set {
- VerifyWritable();
- if (value < 99 || value > MaxCalendarYear)
- {
- throw new ArgumentOutOfRangeException(
- nameof(value),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 99,
- MaxCalendarYear));
- }
- twoDigitYearMax = value;
- }
- }
-
-
-
- public override int ToFourDigitYear(int year) {
- if (year < 0) {
- throw new ArgumentOutOfRangeException(nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- Contract.EndContractBlock();
-
- if (year < 100) {
- return (base.ToFourDigitYear(year));
- }
-
- if (year > MaxCalendarYear) {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 1,
- MaxCalendarYear));
- }
- return (year);
- }
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/RegionInfo.cs b/src/mscorlib/src/System/Globalization/RegionInfo.cs
index b719af7128..c3d5e659ca 100644
--- a/src/mscorlib/src/System/Globalization/RegionInfo.cs
+++ b/src/mscorlib/src/System/Globalization/RegionInfo.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-
////////////////////////////////////////////////////////////////////////////
//
//
@@ -15,15 +14,14 @@
//
////////////////////////////////////////////////////////////////////////////
-namespace System.Globalization {
-
- using System;
- using System.Runtime.Serialization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
- [Serializable]
- public partial class RegionInfo
+namespace System.Globalization
+{
+ [Serializable]
+ public class RegionInfo
{
//--------------------------------------------------------------------//
// Internal Information //
@@ -36,12 +34,12 @@ namespace System.Globalization {
//
// Name of this region (ie: es-US): serialized, the field used for deserialization
//
- internal String m_name;
+ internal String _name;
//
// The CultureData instance that we are going to read data from.
//
- [NonSerialized]internal CultureData m_cultureData;
+ internal CultureData _cultureData;
//
// The RegionInfo for our current region
@@ -59,125 +57,94 @@ namespace System.Globalization {
// In Silverlight we enforce that RegionInfos must be created with a full culture name
//
////////////////////////////////////////////////////////////////////////
- public RegionInfo(String name) {
- if (name==null)
+ public RegionInfo(String name)
+ {
+ if (name == null)
throw new ArgumentNullException(nameof(name));
if (name.Length == 0) //The InvariantCulture has no matching region
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_NoRegionInvariantCulture"), nameof(name));
+ {
+ throw new ArgumentException(SR.Argument_NoRegionInvariantCulture, nameof(name));
}
-
+
Contract.EndContractBlock();
//
- // First try it as an entire culture. We must have user override as true here so
- // that we can pick up custom cultures *before* built-in ones (if they want to
- // prefer built-in cultures they will pass "us" instead of "en-US").
+ // For CoreCLR we only want the region names that are full culture names
//
- this.m_cultureData = CultureData.GetCultureDataForRegion(name,true);
- // this.m_name = name.ToUpper(CultureInfo.InvariantCulture);
-
- if (this.m_cultureData == null)
+ _cultureData = CultureData.GetCultureDataForRegion(name, true);
+ if (_cultureData == null)
throw new ArgumentException(
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("Argument_InvalidCultureName"), name), nameof(name));
+ SR.Argument_InvalidCultureName, name), nameof(name));
// Not supposed to be neutral
- if (this.m_cultureData.IsNeutralCulture)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNeutralRegionName", name), nameof(name));
+ if (_cultureData.IsNeutralCulture)
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidNeutralRegionName, name), nameof(name));
SetName(name);
}
-#if FEATURE_USE_LCID
- // We'd rather people use the named version since this doesn't allow custom locales
public RegionInfo(int culture)
{
if (culture == CultureInfo.LOCALE_INVARIANT) //The InvariantCulture has no matching region
{
- throw new ArgumentException(Environment.GetResourceString("Argument_NoRegionInvariantCulture"));
+ throw new ArgumentException(SR.Argument_NoRegionInvariantCulture);
}
-
+
if (culture == CultureInfo.LOCALE_NEUTRAL)
{
// Not supposed to be neutral
- throw new ArgumentException(Environment.GetResourceString("Argument_CultureIsNeutral", culture), nameof(culture));
+ throw new ArgumentException(SR.Format(SR.Argument_CultureIsNeutral, culture), nameof(culture));
}
if (culture == CultureInfo.LOCALE_CUSTOM_DEFAULT)
{
// Not supposed to be neutral
- throw new ArgumentException(Environment.GetResourceString("Argument_CustomCultureCannotBePassedByNumber", culture), nameof(culture));
+ throw new ArgumentException(SR.Format(SR.Argument_CustomCultureCannotBePassedByNumber, culture), nameof(culture));
}
- this.m_cultureData = CultureData.GetCultureData(culture,true);
- this.m_name = this.m_cultureData.SREGIONNAME;
+ _cultureData = CultureData.GetCultureData(culture, true);
+ _name = _cultureData.SREGIONNAME;
- if (this.m_cultureData.IsNeutralCulture)
+ if (_cultureData.IsNeutralCulture)
{
// Not supposed to be neutral
- throw new ArgumentException(Environment.GetResourceString("Argument_CultureIsNeutral", culture), nameof(culture));
+ throw new ArgumentException(SR.Format(SR.Argument_CultureIsNeutral, culture), nameof(culture));
}
- m_cultureId = culture;
}
-#endif
-
+
internal RegionInfo(CultureData cultureData)
{
- this.m_cultureData = cultureData;
- this.m_name = this.m_cultureData.SREGIONNAME;
+ _cultureData = cultureData;
+ _name = _cultureData.SREGIONNAME;
}
private void SetName(string name)
{
// Use the name of the region we found
- this.m_name = this.m_cultureData.SREGIONNAME;
+ _name = _cultureData.SREGIONNAME;
}
-#region Serialization
- //
- // m_cultureId is needed for serialization only to detect the case if the region info is created using the name or using the LCID.
- // in case m_cultureId is zero means that the RigionInfo is created using name. otherwise it is created using LCID.
- //
-
- [OptionalField(VersionAdded = 2)]
- int m_cultureId;
- // the following field is defined to keep the compatibility with Everett.
- // don't change/remove the names/types of these field.
- [OptionalField(VersionAdded = 2)]
- internal int m_dataItem = 0;
+ [OnSerializing]
+ private void OnSerializing(StreamingContext ctx) { }
[OnDeserialized]
private void OnDeserialized(StreamingContext ctx)
{
- // This won't happen anyway since CoreCLR doesn't support serialization
- this.m_cultureData = CultureData.GetCultureData(m_name, true);
-
- if (this.m_cultureData == null)
- throw new ArgumentException(
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("Argument_InvalidCultureName"), m_name), nameof(m_name));
+ _cultureData = CultureData.GetCultureData(_name, true);
- if (m_cultureId == 0)
+ if (_cultureData == null)
{
- SetName(this.m_name);
- }
- else
- {
- this.m_name = this.m_cultureData.SREGIONNAME;
+ throw new ArgumentException(
+ String.Format(CultureInfo.CurrentCulture, SR.Argument_InvalidCultureName, _name),
+ "_name");
}
- }
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx)
- {
- // Used to fill in everett data item, unnecessary now
- }
-#endregion Serialization
+ _name = _cultureData.SREGIONNAME;
+ }
////////////////////////////////////////////////////////////////////////
//
@@ -188,15 +155,17 @@ namespace System.Globalization {
// thread.
//
////////////////////////////////////////////////////////////////////////
- public static RegionInfo CurrentRegion {
- get {
+ public static RegionInfo CurrentRegion
+ {
+ get
+ {
RegionInfo temp = s_currentRegionInfo;
if (temp == null)
{
- temp = new RegionInfo(CultureInfo.CurrentCulture.m_cultureData);
+ temp = new RegionInfo(CultureInfo.CurrentCulture._cultureData);
// Need full name for custom cultures
- temp.m_name=temp.m_cultureData.SREGIONNAME;
+ temp._name = temp._cultureData.SREGIONNAME;
s_currentRegionInfo = temp;
}
return temp;
@@ -210,10 +179,12 @@ namespace System.Globalization {
// Returns the name of the region (ie: en-US)
//
////////////////////////////////////////////////////////////////////////
- public virtual String Name {
- get {
- Debug.Assert(m_name != null, "Expected RegionInfo.m_name to be populated already");
- return (m_name);
+ public virtual String Name
+ {
+ get
+ {
+ Debug.Assert(_name != null, "Expected RegionInfo._name to be populated already");
+ return (_name);
}
}
@@ -228,7 +199,7 @@ namespace System.Globalization {
{
get
{
- return (this.m_cultureData.SENGCOUNTRY);
+ return (_cultureData.SENGCOUNTRY);
}
}
@@ -241,11 +212,11 @@ namespace System.Globalization {
// if the current UI language is en-US)
//
////////////////////////////////////////////////////////////////////////
- public virtual String DisplayName
+ public virtual String DisplayName
{
- get
+ get
{
- return (this.m_cultureData.SLOCALIZEDCOUNTRY);
+ return (_cultureData.SLOCALIZEDCOUNTRY);
}
}
@@ -262,7 +233,7 @@ namespace System.Globalization {
{
get
{
- return (this.m_cultureData.SNATIVECOUNTRY);
+ return (_cultureData.SNATIVECOUNTRY);
}
}
@@ -277,11 +248,10 @@ namespace System.Globalization {
{
get
{
- return (this.m_cultureData.SISO3166CTRYNAME);
+ return (_cultureData.SISO3166CTRYNAME);
}
}
-
////////////////////////////////////////////////////////////////////////
//
// ThreeLetterISORegionName
@@ -293,7 +263,7 @@ namespace System.Globalization {
{
get
{
- return (this.m_cultureData.SISO3166CTRYNAME2);
+ return (_cultureData.SISO3166CTRYNAME2);
}
}
@@ -308,10 +278,12 @@ namespace System.Globalization {
{
get
{
- return (this.m_cultureData.SABBREVCTRYNAME);
+ // ThreeLetterWindowsRegionName is really same as ThreeLetterISORegionName
+ return ThreeLetterISORegionName;
}
}
+
////////////////////////////////////////////////////////////////////////
//
// IsMetric
@@ -319,19 +291,20 @@ namespace System.Globalization {
// Returns true if this region uses the metric measurement system
//
////////////////////////////////////////////////////////////////////////
- public virtual bool IsMetric {
- get {
- int value = this.m_cultureData.IMEASURE;
- return (value==0);
+ public virtual bool IsMetric
+ {
+ get
+ {
+ int value = _cultureData.IMEASURE;
+ return (value == 0);
}
}
-
public virtual int GeoId
{
- get
+ get
{
- return (this.m_cultureData.IGEOID);
+ return (_cultureData.IGEOID);
}
}
@@ -342,27 +315,27 @@ namespace System.Globalization {
// English name for this region's currency, ie: Swiss Franc
//
////////////////////////////////////////////////////////////////////////
- public virtual String CurrencyEnglishName
+ public virtual string CurrencyEnglishName
{
get
{
- return (this.m_cultureData.SENGLISHCURRENCY);
+ return (_cultureData.SENGLISHCURRENCY);
}
}
////////////////////////////////////////////////////////////////////////
//
- // CurrencyEnglishName
+ // CurrencyNativeName
//
- // English name for this region's currency, ie: Schweizer Franken
+ // Native name for this region's currency, ie: Schweizer Franken
// WARNING: You need a full locale name for this to make sense.
//
////////////////////////////////////////////////////////////////////////
- public virtual String CurrencyNativeName
+ public virtual string CurrencyNativeName
{
get
{
- return (this.m_cultureData.SNATIVECURRENCY);
+ return (_cultureData.SNATIVECURRENCY);
}
}
@@ -373,9 +346,11 @@ namespace System.Globalization {
// Currency Symbol for this locale, ie: Fr. or $
//
////////////////////////////////////////////////////////////////////////
- public virtual String CurrencySymbol {
- get {
- return (this.m_cultureData.SCURRENCY);
+ public virtual String CurrencySymbol
+ {
+ get
+ {
+ return (_cultureData.SCURRENCY);
}
}
@@ -386,9 +361,11 @@ namespace System.Globalization {
// ISO Currency Symbol for this locale, ie: CHF
//
////////////////////////////////////////////////////////////////////////
- public virtual String ISOCurrencySymbol {
- get {
- return (this.m_cultureData.SINTLSYMBOL);
+ public virtual String ISOCurrencySymbol
+ {
+ get
+ {
+ return (_cultureData.SINTLSYMBOL);
}
}
@@ -439,6 +416,6 @@ namespace System.Globalization {
public override String ToString()
{
return (Name);
- }
+ }
}
}
diff --git a/src/mscorlib/src/System/Globalization/SortKey.cs b/src/mscorlib/src/System/Globalization/SortKey.cs
index 7c7408b009..0930965e5d 100644
--- a/src/mscorlib/src/System/Globalization/SortKey.cs
+++ b/src/mscorlib/src/System/Globalization/SortKey.cs
@@ -11,8 +11,8 @@
//
////////////////////////////////////////////////////////////////////////////
-namespace System.Globalization {
-
+namespace System.Globalization
+{
using System;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
@@ -25,21 +25,17 @@ namespace System.Globalization {
//--------------------------------------------------------------------//
// Internal Information //
//--------------------------------------------------------------------//
-
- //
- // Variables.
- //
[OptionalField(VersionAdded = 3)]
- internal String localeName; // locale identifier
+ internal string _localeName; // locale identifier
[OptionalField(VersionAdded = 1)] // LCID field so serialization is Whidbey compatible though we don't officially support it
- internal int win32LCID;
+ internal int _win32LCID;
// Whidbey serialization
- internal CompareOptions options; // options
- internal String m_String; // original string
- internal byte[] m_KeyData; // sortkey data
+ internal CompareOptions _options; // options
+ internal string _string; // original string
+ internal byte[] _keyData; // sortkey data
//
// The following constructor is designed to be called from CompareInfo to get the
@@ -47,20 +43,19 @@ namespace System.Globalization {
//
internal SortKey(String localeName, String str, CompareOptions options, byte[] keyData)
{
- this.m_KeyData = keyData;
- this.localeName = localeName;
- this.options = options;
- this.m_String = str;
+ _keyData = keyData;
+ _localeName = localeName;
+ _options = options;
+ _string = str;
}
-#if FEATURE_USE_LCID
[OnSerializing]
private void OnSerializing(StreamingContext context)
{
//set LCID to proper value for Whidbey serialization (no other use)
- if (win32LCID == 0)
+ if (_win32LCID == 0)
{
- win32LCID = CultureInfo.GetCultureInfo(localeName).LCID;
+ _win32LCID = CultureInfo.GetCultureInfo(_localeName).LCID;
}
}
@@ -68,13 +63,12 @@ namespace System.Globalization {
private void OnDeserialized(StreamingContext context)
{
//set locale name to proper value after Whidbey deserialization
- if (String.IsNullOrEmpty(localeName) && win32LCID != 0)
+ if (String.IsNullOrEmpty(_localeName) && _win32LCID != 0)
{
- localeName = CultureInfo.GetCultureInfo(win32LCID).Name;
+ _localeName = CultureInfo.GetCultureInfo(_win32LCID).Name;
}
}
-#endif //FEATURE_USE_LCID
-
+
////////////////////////////////////////////////////////////////////////
//
// GetOriginalString
@@ -85,12 +79,12 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
public virtual String OriginalString
{
- get {
- return (m_String);
+ get
+ {
+ return (_string);
}
}
-
////////////////////////////////////////////////////////////////////////
//
// GetKeyData
@@ -101,12 +95,12 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
public virtual byte[] KeyData
{
- get {
- return (byte[])(m_KeyData.Clone());
+ get
+ {
+ return (byte[])(_keyData.Clone());
}
}
-
////////////////////////////////////////////////////////////////////////
//
// Compare
@@ -116,45 +110,49 @@ namespace System.Globalization {
// and a number greater than 0 if sortkey1 is greater than sortkey2.
//
////////////////////////////////////////////////////////////////////////
- public static int Compare(SortKey sortkey1, SortKey sortkey2) {
-
- if (sortkey1==null || sortkey2==null) {
- throw new ArgumentNullException((sortkey1==null ? nameof(sortkey1): nameof(sortkey2)));
+ public static int Compare(SortKey sortkey1, SortKey sortkey2)
+ {
+ if (sortkey1==null || sortkey2==null)
+ {
+ throw new ArgumentNullException((sortkey1 == null ? nameof(sortkey1) : nameof(sortkey2)));
}
Contract.EndContractBlock();
+ byte[] key1Data = sortkey1._keyData;
+ byte[] key2Data = sortkey2._keyData;
- byte[] key1Data = sortkey1.m_KeyData;
- byte[] key2Data = sortkey2.m_KeyData;
-
- Debug.Assert(key1Data!=null, "key1Data!=null");
- Debug.Assert(key2Data!=null, "key2Data!=null");
+ Debug.Assert(key1Data != null, "key1Data != null");
+ Debug.Assert(key2Data != null, "key2Data != null");
- if (key1Data.Length == 0) {
- if (key2Data.Length == 0) {
+ if (key1Data.Length == 0)
+ {
+ if (key2Data.Length == 0)
+ {
return (0);
}
return (-1);
}
- if (key2Data.Length == 0) {
+ if (key2Data.Length == 0)
+ {
return (1);
}
-
- int compLen = (key1Data.Length<key2Data.Length)?key1Data.Length:key2Data.Length;
- for (int i=0; i<compLen; i++) {
- if (key1Data[i]>key2Data[i]) {
+ int compLen = (key1Data.Length < key2Data.Length) ? key1Data.Length : key2Data.Length;
+
+ for (int i=0; i<compLen; i++)
+ {
+ if (key1Data[i]>key2Data[i])
+ {
return (1);
}
- if (key1Data[i]<key2Data[i]) {
+ if (key1Data[i]<key2Data[i])
+ {
return (-1);
}
}
-
+
return 0;
-
}
-
-
+
////////////////////////////////////////////////////////////////////////
//
// Equals
@@ -166,7 +164,7 @@ namespace System.Globalization {
public override bool Equals(Object value)
{
SortKey that = value as SortKey;
-
+
if (that != null)
{
return Compare(this, that) == 0;
@@ -174,8 +172,7 @@ namespace System.Globalization {
return (false);
}
-
-
+
////////////////////////////////////////////////////////////////////////
//
// GetHashCode
@@ -187,11 +184,9 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
public override int GetHashCode()
{
- return (CompareInfo.GetCompareInfo(
- this.localeName).GetHashCodeOfString(this.m_String, this.options));
+ return (CompareInfo.GetCompareInfo(_localeName).GetHashCodeOfString(_string, _options));
}
-
-
+
////////////////////////////////////////////////////////////////////////
//
// ToString
@@ -202,7 +197,7 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
public override String ToString()
{
- return ("SortKey - " + localeName + ", " + options + ", " + m_String);
+ return ("SortKey - " + _localeName + ", " + _options + ", " + _string);
}
}
}
diff --git a/src/mscorlib/src/System/Globalization/SortVersion.cs b/src/mscorlib/src/System/Globalization/SortVersion.cs
deleted file mode 100644
index 24fe8546fc..0000000000
--- a/src/mscorlib/src/System/Globalization/SortVersion.cs
+++ /dev/null
@@ -1,102 +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.
-
-namespace System.Globalization
-{
- using System;
- using System.Diagnostics.Contracts;
-
- [Serializable]
- public sealed class SortVersion : IEquatable<SortVersion>
- {
- private int m_NlsVersion;
- private Guid m_SortId;
-
- public int FullVersion
- {
- get
- {
- return m_NlsVersion;
- }
- }
-
- public Guid SortId
- {
- get
- {
- return m_SortId;
- }
- }
-
- public SortVersion(int fullVersion, Guid sortId)
- {
- m_SortId = sortId;
- m_NlsVersion = fullVersion;
- }
-
- internal SortVersion(int nlsVersion, int effectiveId, Guid customVersion)
- {
- m_NlsVersion = nlsVersion;
-
- if (customVersion == Guid.Empty)
- {
- byte[] b = BitConverter.GetBytes(effectiveId);
- byte b1 = (byte) ((uint) effectiveId >> 24);
- byte b2 = (byte) ((effectiveId & 0x00FF0000) >> 16);
- byte b3 = (byte) ((effectiveId & 0x0000FF00) >> 8);
- byte b4 = (byte) (effectiveId & 0xFF);
- customVersion = new Guid(0,0,0,0,0,0,0,b1,b2,b3,b4);
- }
-
- m_SortId = customVersion;
- }
-
- public override bool Equals(object obj)
- {
- SortVersion n = obj as SortVersion;
- if(n != null)
- {
- return this.Equals(n);
- }
-
- return false;
- }
-
- public bool Equals(SortVersion other)
- {
- if (other == null)
- {
- return false;
- }
-
- return m_NlsVersion == other.m_NlsVersion && m_SortId == other.m_SortId;
- }
-
- public override int GetHashCode()
- {
- return m_NlsVersion * 7 | m_SortId.GetHashCode();
- }
-
- public static bool operator ==(SortVersion left, SortVersion right)
- {
- if (((object) left) != null)
- {
- return left.Equals(right);
- }
-
- if (((object) right) != null)
- {
- return right.Equals(left);
- }
-
- // Both null.
- return true;
- }
-
- public static bool operator !=(SortVersion left, SortVersion right)
- {
- return !(left == right);
- }
- }
-} \ No newline at end of file
diff --git a/src/mscorlib/src/System/Globalization/StringInfo.cs b/src/mscorlib/src/System/Globalization/StringInfo.cs
index dc32fe9493..f1dd30561b 100644
--- a/src/mscorlib/src/System/Globalization/StringInfo.cs
+++ b/src/mscorlib/src/System/Globalization/StringInfo.cs
@@ -12,158 +12,166 @@
//
////////////////////////////////////////////////////////////////////////////
-namespace System.Globalization {
-
- using System;
- using System.Runtime.Serialization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
+using System;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+namespace System.Globalization
+{
[Serializable]
- public class StringInfo
+ public class StringInfo
{
-
[OptionalField(VersionAdded = 2)]
- private String m_str;
-
- // We allow this class to be serialized but there is no conceivable reason
- // for them to do so. Thus, we do not serialize the instance variables.
- [NonSerialized] private int[] m_indexes;
+ private string _str;
+
+ [NonSerialized]
+ private int[] _indexes;
// Legacy constructor
- public StringInfo() : this(""){}
+ public StringInfo() : this("") { }
// Primary, useful constructor
- public StringInfo(String value) {
+ public StringInfo(string value)
+ {
this.String = value;
}
-
-#region Serialization
- [OnDeserializing]
- private void OnDeserializing(StreamingContext ctx)
- {
- m_str = String.Empty;
- }
+
+ [OnDeserializing]
+ private void OnDeserializing(StreamingContext ctx)
+ {
+ _str = String.Empty;
+ }
[OnDeserialized]
private void OnDeserialized(StreamingContext ctx)
{
- if (m_str.Length == 0)
+ if (_str.Length == 0)
{
- m_indexes = null;
+ _indexes = null;
}
- }
-#endregion Serialization
+ }
public override bool Equals(Object value)
{
StringInfo that = value as StringInfo;
if (that != null)
{
- return (this.m_str.Equals(that.m_str));
+ return (_str.Equals(that._str));
}
return (false);
}
public override int GetHashCode()
{
- return this.m_str.GetHashCode();
+ return _str.GetHashCode();
}
// Our zero-based array of index values into the string. Initialize if
// our private array is not yet, in fact, initialized.
- private int[] Indexes {
- get {
- if((null == this.m_indexes) && (0 < this.String.Length)) {
- this.m_indexes = StringInfo.ParseCombiningCharacters(this.String);
+ private int[] Indexes
+ {
+ get
+ {
+ if ((null == _indexes) && (0 < this.String.Length))
+ {
+ _indexes = StringInfo.ParseCombiningCharacters(this.String);
}
- return(this.m_indexes);
+ return (_indexes);
}
}
- public String String {
- get {
- return(this.m_str);
+ public string String
+ {
+ get
+ {
+ return (_str);
}
- set {
- if (null == value) {
- throw new ArgumentNullException(nameof(String),
- Environment.GetResourceString("ArgumentNull_String"));
+ set
+ {
+ if (null == value)
+ {
+ throw new ArgumentNullException("String",
+ SR.ArgumentNull_String);
}
Contract.EndContractBlock();
- this.m_str = value;
- this.m_indexes = null;
+ _str = value;
+ _indexes = null;
}
}
- public int LengthInTextElements {
- get {
- if(null == this.Indexes) {
+ public int LengthInTextElements
+ {
+ get
+ {
+ if (null == this.Indexes)
+ {
// Indexes not initialized, so assume length zero
- return(0);
+ return (0);
}
- return(this.Indexes.Length);
+ return (this.Indexes.Length);
}
}
- public String SubstringByTextElements(int startingTextElement) {
+ public string SubstringByTextElements(int startingTextElement)
+ {
// If the string is empty, no sense going further.
- if(null == this.Indexes) {
+ if (null == this.Indexes)
+ {
// Just decide which error to give depending on the param they gave us....
- if(startingTextElement < 0) {
- throw new ArgumentOutOfRangeException(nameof(startingTextElement),
- Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ if (startingTextElement < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startingTextElement), SR.ArgumentOutOfRange_NeedPosNum);
}
- else {
- throw new ArgumentOutOfRangeException(nameof(startingTextElement),
- Environment.GetResourceString("Arg_ArgumentOutOfRangeException"));
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(startingTextElement), SR.Arg_ArgumentOutOfRangeException);
}
}
- return (this.SubstringByTextElements(startingTextElement, this.Indexes.Length - startingTextElement));
+ return (SubstringByTextElements(startingTextElement, Indexes.Length - startingTextElement));
}
- public String SubstringByTextElements(int startingTextElement, int lengthInTextElements) {
-
- //
- // Parameter checking
- //
- if(startingTextElement < 0) {
- throw new ArgumentOutOfRangeException(nameof(startingTextElement),
- Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ public string SubstringByTextElements(int startingTextElement, int lengthInTextElements)
+ {
+ if (startingTextElement < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startingTextElement), SR.ArgumentOutOfRange_NeedPosNum);
}
- if(this.String.Length == 0 || startingTextElement >= this.Indexes.Length) {
- throw new ArgumentOutOfRangeException(nameof(startingTextElement),
- Environment.GetResourceString("Arg_ArgumentOutOfRangeException"));
+ if (this.String.Length == 0 || startingTextElement >= Indexes.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startingTextElement), SR.Arg_ArgumentOutOfRangeException);
}
- if(lengthInTextElements < 0) {
- throw new ArgumentOutOfRangeException(nameof(lengthInTextElements),
- Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ if (lengthInTextElements < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(lengthInTextElements), SR.ArgumentOutOfRange_NeedPosNum);
}
- if(startingTextElement > this.Indexes.Length - lengthInTextElements) {
- throw new ArgumentOutOfRangeException(nameof(lengthInTextElements),
- Environment.GetResourceString("Arg_ArgumentOutOfRangeException"));
+ if (startingTextElement > Indexes.Length - lengthInTextElements)
+ {
+ throw new ArgumentOutOfRangeException(nameof(lengthInTextElements), SR.Arg_ArgumentOutOfRangeException);
}
- int start = this.Indexes[startingTextElement];
+ int start = Indexes[startingTextElement];
- if(startingTextElement + lengthInTextElements == this.Indexes.Length) {
+ if (startingTextElement + lengthInTextElements == Indexes.Length)
+ {
// We are at the last text element in the string and because of that
// must handle the call differently.
- return(this.String.Substring(start));
+ return (this.String.Substring(start));
}
- else {
- return(this.String.Substring(start, (this.Indexes[lengthInTextElements + startingTextElement] - start)));
+ else
+ {
+ return (this.String.Substring(start, (Indexes[lengthInTextElements + startingTextElement] - start)));
}
}
-
- public static String GetNextTextElement(String str)
+
+ public static string GetNextTextElement(string str)
{
return (GetNextTextElement(str, 0));
}
@@ -200,8 +208,8 @@ namespace System.Globalization {
// currentCharCount The char count of an abstract char pointed by Index. It will be updated to the char count of next abstract character if this is not the last text element.
//
////////////////////////////////////////////////////////////////////////
-
- internal static int GetCurrentTextElementLen(String str, int index, int len, ref UnicodeCategory ucCurrent, ref int currentCharCount)
+
+ internal static int GetCurrentTextElementLen(string str, int index, int len, ref UnicodeCategory ucCurrent, ref int currentCharCount)
{
Debug.Assert(index >= 0 && len >= 0, "StringInfo.GetCurrentTextElementLen() : index = " + index + ", len = " + len);
Debug.Assert(index < len, "StringInfo.GetCurrentTextElementLen() : index = " + index + ", len = " + len);
@@ -214,30 +222,34 @@ namespace System.Globalization {
// Call an internal GetUnicodeCategory, which will tell us both the unicode category, and also tell us if it is a surrogate pair or not.
int nextCharCount;
UnicodeCategory ucNext = CharUnicodeInfo.InternalGetUnicodeCategory(str, index + currentCharCount, out nextCharCount);
- if (CharUnicodeInfo.IsCombiningCategory(ucNext)) {
+ if (CharUnicodeInfo.IsCombiningCategory(ucNext))
+ {
// The next element is a combining class.
// Check if the current text element to see if it is a valid base category (i.e. it should not be a combining category,
// not a format character, and not a control character).
- if (CharUnicodeInfo.IsCombiningCategory(ucCurrent)
- || (ucCurrent == UnicodeCategory.Format)
- || (ucCurrent == UnicodeCategory.Control)
+ if (CharUnicodeInfo.IsCombiningCategory(ucCurrent)
+ || (ucCurrent == UnicodeCategory.Format)
+ || (ucCurrent == UnicodeCategory.Control)
|| (ucCurrent == UnicodeCategory.OtherNotAssigned)
|| (ucCurrent == UnicodeCategory.Surrogate)) // An unpair high surrogate or low surrogate
- {
- // Will fall thru and return the currentCharCount
- } else {
+ {
+ // Will fall thru and return the currentCharCount
+ }
+ else
+ {
int startIndex = index; // Remember the current index.
// We have a valid base characters, and we have a character (or surrogate) that is combining.
// Check if there are more combining characters to follow.
// Check if the next character is a nonspacing character.
index += currentCharCount + nextCharCount;
-
+
while (index < len)
{
ucNext = CharUnicodeInfo.InternalGetUnicodeCategory(str, index, out nextCharCount);
- if (!CharUnicodeInfo.IsCombiningCategory(ucNext)) {
+ if (!CharUnicodeInfo.IsCombiningCategory(ucNext))
+ {
ucCurrent = ucNext;
currentCharCount = nextCharCount;
break;
@@ -254,27 +266,31 @@ namespace System.Globalization {
currentCharCount = nextCharCount;
return (ret);
}
-
+
// Returns the str containing the next text element in str starting at
// index index. If index is not supplied, then it will start at the beginning
// of str. It recognizes a base character plus one or more combining
// characters or a properly formed surrogate pair as a text element. See also
// the ParseCombiningCharacters() and the ParseSurrogates() methods.
- public static String GetNextTextElement(String str, int index) {
+ public static string GetNextTextElement(string str, int index)
+ {
//
// Validate parameters.
//
- if (str==null) {
+ if (str == null)
+ {
throw new ArgumentNullException(nameof(str));
}
Contract.EndContractBlock();
-
+
int len = str.Length;
- if (index < 0 || index >= len) {
- if (index == len) {
+ if (index < 0 || index >= len)
+ {
+ if (index == len)
+ {
return (String.Empty);
- }
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ }
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
}
int charLen;
@@ -282,26 +298,26 @@ namespace System.Globalization {
return (str.Substring(index, GetCurrentTextElementLen(str, index, len, ref uc, ref charLen)));
}
- public static TextElementEnumerator GetTextElementEnumerator(String str)
+ public static TextElementEnumerator GetTextElementEnumerator(string str)
{
return (GetTextElementEnumerator(str, 0));
}
-
- public static TextElementEnumerator GetTextElementEnumerator(String str, int index)
+
+ public static TextElementEnumerator GetTextElementEnumerator(string str, int index)
{
//
// Validate parameters.
//
- if (str==null)
+ if (str == null)
{
throw new ArgumentNullException(nameof(str));
}
Contract.EndContractBlock();
-
+
int len = str.Length;
if (index < 0 || (index > len))
{
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
}
return (new TextElementEnumerator(str, index, len));
@@ -319,14 +335,14 @@ namespace System.Globalization {
* return the indices: 0, 2, 4.
*/
- public static int[] ParseCombiningCharacters(String str)
+ public static int[] ParseCombiningCharacters(string str)
{
if (str == null)
{
throw new ArgumentNullException(nameof(str));
}
Contract.EndContractBlock();
-
+
int len = str.Length;
int[] result = new int[len];
if (len == 0)
@@ -338,11 +354,12 @@ namespace System.Globalization {
int i = 0;
int currentCharLen;
- UnicodeCategory currentCategory = CharUnicodeInfo.InternalGetUnicodeCategory(str, 0, out currentCharLen);
-
- while (i < len) {
+ UnicodeCategory currentCategory = CharUnicodeInfo.InternalGetUnicodeCategory(str, 0, out currentCharLen);
+
+ while (i < len)
+ {
result[resultCount++] = i;
- i += GetCurrentTextElementLen(str, i, len, ref currentCategory, ref currentCharLen);
+ i += GetCurrentTextElementLen(str, i, len, ref currentCategory, ref currentCharLen);
}
if (resultCount < len)
@@ -352,7 +369,6 @@ namespace System.Globalization {
return (returnArray);
}
return (result);
-
}
}
}
diff --git a/src/mscorlib/src/System/Globalization/Tables/charinfo.nlp b/src/mscorlib/src/System/Globalization/Tables/charinfo.nlp
deleted file mode 100644
index 2d5444f524..0000000000
--- a/src/mscorlib/src/System/Globalization/Tables/charinfo.nlp
+++ /dev/null
Binary files differ
diff --git a/src/mscorlib/src/System/Globalization/TaiwanCalendar.cs b/src/mscorlib/src/System/Globalization/TaiwanCalendar.cs
deleted file mode 100644
index ec84a06b76..0000000000
--- a/src/mscorlib/src/System/Globalization/TaiwanCalendar.cs
+++ /dev/null
@@ -1,256 +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.
-
-namespace System.Globalization {
-
- using System;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
- /* SSS_DROP_BEGIN */ /* SSS_WARNINGS_OFF */
- /*=================================TaiwanCalendar==========================
- **
- ** Taiwan calendar is based on the Gregorian calendar. And the year is an offset to Gregorian calendar.
- ** That is,
- ** Taiwan year = Gregorian year - 1911. So 1912/01/01 A.D. is Taiwan 1/01/01
- **
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 1912/01/01 9999/12/31
- ** Taiwan 01/01/01 8088/12/31
- ============================================================================*/
- /* SSS_WARNINGS_ON */ /* SSS_DROP_END */
-
- [Serializable] public class TaiwanCalendar: Calendar {
- //
- // The era value for the current era.
- //
-
- // Since
- // Gregorian Year = Era Year + yearOffset
- // When Gregorian Year 1912 is year 1, so that
- // 1912 = 1 + yearOffset
- // So yearOffset = 1911
- //m_EraInfo[0] = new EraInfo(1, new DateTime(1912, 1, 1).Ticks, 1911, 1, GregorianCalendar.MaxYear - 1911);
-
- // Initialize our era info.
- static internal EraInfo[] taiwanEraInfo = new EraInfo[] {
- new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911) // era #, start year/month/day, yearOffset, minEraYear
- };
-
- internal static volatile Calendar s_defaultInstance;
-
- internal GregorianCalendarHelper helper;
-
- /*=================================GetDefaultInstance==========================
- **Action: Internal method to provide a default intance of TaiwanCalendar. Used by NLS+ implementation
- ** and other calendars.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
-
- internal static Calendar GetDefaultInstance() {
- if (s_defaultInstance == null) {
- s_defaultInstance = new TaiwanCalendar();
- }
- return (s_defaultInstance);
- }
-
- internal static readonly DateTime calendarMinValue = new DateTime(1912, 1, 1);
-
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (calendarMinValue);
- }
- }
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (DateTime.MaxValue);
- }
- }
-
- // Return the type of the Taiwan calendar.
- //
-
- public override CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.SolarCalendar;
- }
- }
-
-
- public TaiwanCalendar() {
- try {
- new CultureInfo("zh-TW");
- } catch (ArgumentException e) {
- throw new TypeInitializationException(this.GetType().FullName, e);
- }
- helper = new GregorianCalendarHelper(this, taiwanEraInfo);
- }
-
- internal override int ID {
- get {
- return (CAL_TAIWAN);
- }
- }
-
-
- public override DateTime AddMonths(DateTime time, int months) {
- return (helper.AddMonths(time, months));
- }
-
-
- public override DateTime AddYears(DateTime time, int years) {
- return (helper.AddYears(time, years));
- }
-
-
- public override int GetDaysInMonth(int year, int month, int era) {
- return (helper.GetDaysInMonth(year, month, era));
- }
-
-
- public override int GetDaysInYear(int year, int era) {
- return (helper.GetDaysInYear(year, era));
- }
-
-
- public override int GetDayOfMonth(DateTime time) {
- return (helper.GetDayOfMonth(time));
- }
-
-
- public override DayOfWeek GetDayOfWeek(DateTime time) {
- return (helper.GetDayOfWeek(time));
- }
-
-
- public override int GetDayOfYear(DateTime time)
- {
- return (helper.GetDayOfYear(time));
- }
-
-
- public override int GetMonthsInYear(int year, int era) {
- return (helper.GetMonthsInYear(year, era));
- }
-
-
- [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
- public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
- {
- return (helper.GetWeekOfYear(time, rule, firstDayOfWeek));
- }
-
-
- public override int GetEra(DateTime time) {
- return (helper.GetEra(time));
- }
-
- public override int GetMonth(DateTime time) {
- return (helper.GetMonth(time));
- }
-
-
- public override int GetYear(DateTime time) {
- return (helper.GetYear(time));
- }
-
-
- public override bool IsLeapDay(int year, int month, int day, int era)
- {
- return (helper.IsLeapDay(year, month, day, era));
- }
-
-
- public override bool IsLeapYear(int year, int era) {
- return (helper.IsLeapYear(year, era));
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
- public override int GetLeapMonth(int year, int era)
- {
- return (helper.GetLeapMonth(year, era));
- }
-
-
- public override bool IsLeapMonth(int year, int month, int era) {
- return (helper.IsLeapMonth(year, month, era));
- }
-
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) {
- return (helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era));
- }
-
-
- public override int[] Eras {
- get {
- return (helper.Eras);
- }
- }
-
- private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 99;
-
- public override int TwoDigitYearMax {
- get {
- if (twoDigitYearMax == -1) {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
- }
- return (twoDigitYearMax);
- }
-
- set {
- VerifyWritable();
- if (value < 99 || value > helper.MaxYear)
- {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 99,
- helper.MaxYear));
-
- }
- twoDigitYearMax = value;
- }
- }
-
- // For Taiwan calendar, four digit year is not used.
- // Therefore, for any two digit number, we just return the original number.
-
- public override int ToFourDigitYear(int year) {
- if (year <= 0) {
- throw new ArgumentOutOfRangeException(nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
- }
- Contract.EndContractBlock();
-
- if (year > helper.MaxYear) {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 1,
- helper.MaxYear));
- }
- return (year);
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/Globalization/TaiwanLunisolarCalendar.cs b/src/mscorlib/src/System/Globalization/TaiwanLunisolarCalendar.cs
deleted file mode 100644
index d96c450f49..0000000000
--- a/src/mscorlib/src/System/Globalization/TaiwanLunisolarCalendar.cs
+++ /dev/null
@@ -1,330 +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.
-
-namespace System.Globalization {
- using System;
- using System.Diagnostics.Contracts;
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about TaiwanLunisolarCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
- /*
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 1912/02/18 2051/02/10
- ** TaiwanLunisolar 1912/01/01 2050/13/29
- */
-
- [Serializable]
- public class TaiwanLunisolarCalendar : EastAsianLunisolarCalendar {
-
- // Since
- // Gregorian Year = Era Year + yearOffset
- // When Gregorian Year 1912 is year 1, so that
- // 1912 = 1 + yearOffset
- // So yearOffset = 1911
- //m_EraInfo[0] = new EraInfo(1, new DateTime(1912, 1, 1).Ticks, 1911, 1, GregorianCalendar.MaxYear - 1911);
-
- // Initialize our era info.
- static internal EraInfo[] taiwanLunisolarEraInfo = new EraInfo[] {
- new EraInfo( 1, 1912, 1, 1, 1911, 1, GregorianCalendar.MaxYear - 1911) // era #, start year/month/day, yearOffset, minEraYear
- };
-
- internal GregorianCalendarHelper helper;
-
- internal const int MIN_LUNISOLAR_YEAR = 1912;
- internal const int MAX_LUNISOLAR_YEAR = 2050;
-
- internal const int MIN_GREGORIAN_YEAR = 1912;
- internal const int MIN_GREGORIAN_MONTH = 2;
- internal const int MIN_GREGORIAN_DAY = 18;
-
- internal const int MAX_GREGORIAN_YEAR = 2051;
- internal const int MAX_GREGORIAN_MONTH = 2;
- internal const int MAX_GREGORIAN_DAY = 10;
-
- internal static DateTime minDate = new DateTime(MIN_GREGORIAN_YEAR, MIN_GREGORIAN_MONTH, MIN_GREGORIAN_DAY);
- internal static DateTime maxDate = new DateTime((new DateTime(MAX_GREGORIAN_YEAR, MAX_GREGORIAN_MONTH, MAX_GREGORIAN_DAY, 23, 59, 59, 999)).Ticks + 9999);
-
- public override DateTime MinSupportedDateTime {
- get
- {
- return (minDate);
- }
- }
-
-
-
- public override DateTime MaxSupportedDateTime {
- get
- {
- return (maxDate);
- }
- }
-
- protected override int DaysInYearBeforeMinSupportedYear
- {
- get
- {
- // 1911 from ChineseLunisolarCalendar
- return 384;
- }
- }
-
- static readonly int [,] yinfo =
- {
-/*Y LM Lmon Lday DaysPerMonth D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 #Days
-1912 */{ 0 , 2 , 18 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1913 */{ 0 , 2 , 6 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1914 */{ 5 , 1 , 26 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
-1915 */{ 0 , 2 , 14 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1916 */{ 0 , 2 , 3 , 54944 },/* 30 30 29 30 29 30 30 29 30 29 30 29 0 355
-1917 */{ 2 , 1 , 23 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1918 */{ 0 , 2 , 11 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1919 */{ 7 , 2 , 1 , 18872 },/* 29 30 29 29 30 29 29 30 30 29 30 30 30 384
-1920 */{ 0 , 2 , 20 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1921 */{ 0 , 2 , 8 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1922 */{ 5 , 1 , 28 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1923 */{ 0 , 2 , 16 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1924 */{ 0 , 2 , 5 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1925 */{ 4 , 1 , 24 , 44456 },/* 30 29 30 29 30 30 29 30 30 29 30 29 30 385
-1926 */{ 0 , 2 , 13 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1927 */{ 0 , 2 , 2 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 0 355
-1928 */{ 2 , 1 , 23 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
-1929 */{ 0 , 2 , 10 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1930 */{ 6 , 1 , 30 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 29 383
-1931 */{ 0 , 2 , 17 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1932 */{ 0 , 2 , 6 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-1933 */{ 5 , 1 , 26 , 27976 },/* 29 30 30 29 30 30 29 30 29 30 29 29 30 384
-1934 */{ 0 , 2 , 14 , 23248 },/* 29 30 29 30 30 29 30 29 30 30 29 30 0 355
-1935 */{ 0 , 2 , 4 , 11104 },/* 29 29 30 29 30 29 30 30 29 30 30 29 0 354
-1936 */{ 3 , 1 , 24 , 37744 },/* 30 29 29 30 29 29 30 30 29 30 30 30 29 384
-1937 */{ 0 , 2 , 11 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-1938 */{ 7 , 1 , 31 , 51560 },/* 30 30 29 29 30 29 29 30 29 30 30 29 30 384
-1939 */{ 0 , 2 , 19 , 51536 },/* 30 30 29 29 30 29 29 30 29 30 29 30 0 354
-1940 */{ 0 , 2 , 8 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-1941 */{ 6 , 1 , 27 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 29 384
-1942 */{ 0 , 2 , 15 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1943 */{ 0 , 2 , 5 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1944 */{ 4 , 1 , 25 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
-1945 */{ 0 , 2 , 13 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-1946 */{ 0 , 2 , 2 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-1947 */{ 2 , 1 , 22 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-1948 */{ 0 , 2 , 10 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-1949 */{ 7 , 1 , 29 , 46248 },/* 30 29 30 30 29 30 29 29 30 29 30 29 30 384
-1950 */{ 0 , 2 , 17 , 27808 },/* 29 30 30 29 30 30 29 29 30 29 30 29 0 354
-1951 */{ 0 , 2 , 6 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 0 355
-1952 */{ 5 , 1 , 27 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-1953 */{ 0 , 2 , 14 , 19872 },/* 29 30 29 29 30 30 29 30 30 29 30 29 0 354
-1954 */{ 0 , 2 , 3 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-1955 */{ 3 , 1 , 24 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-1956 */{ 0 , 2 , 12 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-1957 */{ 8 , 1 , 31 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 29 383
-1958 */{ 0 , 2 , 18 , 59728 },/* 30 30 30 29 30 29 29 30 29 30 29 30 0 355
-1959 */{ 0 , 2 , 8 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-1960 */{ 6 , 1 , 28 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 29 384
-1961 */{ 0 , 2 , 15 , 43856 },/* 30 29 30 29 30 29 30 30 29 30 29 30 0 355
-1962 */{ 0 , 2 , 5 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-1963 */{ 4 , 1 , 25 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-1964 */{ 0 , 2 , 13 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 0 355
-1965 */{ 0 , 2 , 2 , 21088 },/* 29 30 29 30 29 29 30 29 29 30 30 29 0 353
-1966 */{ 3 , 1 , 21 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-1967 */{ 0 , 2 , 9 , 55632 },/* 30 30 29 30 30 29 29 30 29 30 29 30 0 355
-1968 */{ 7 , 1 , 30 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-1969 */{ 0 , 2 , 17 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-1970 */{ 0 , 2 , 6 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-1971 */{ 5 , 1 , 27 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-1972 */{ 0 , 2 , 15 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
-1973 */{ 0 , 2 , 3 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-1974 */{ 4 , 1 , 23 , 53864 },/* 30 30 29 30 29 29 30 29 29 30 30 29 30 384
-1975 */{ 0 , 2 , 11 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-1976 */{ 8 , 1 , 31 , 54568 },/* 30 30 29 30 29 30 29 30 29 29 30 29 30 384
-1977 */{ 0 , 2 , 18 , 46400 },/* 30 29 30 30 29 30 29 30 29 30 29 29 0 354
-1978 */{ 0 , 2 , 7 , 46752 },/* 30 29 30 30 29 30 30 29 30 29 30 29 0 355
-1979 */{ 6 , 1 , 28 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 29 384
-1980 */{ 0 , 2 , 16 , 38320 },/* 30 29 29 30 29 30 29 30 30 29 30 30 0 355
-1981 */{ 0 , 2 , 5 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-1982 */{ 4 , 1 , 25 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-1983 */{ 0 , 2 , 13 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-1984 */{ 10 , 2 , 2 , 45656 },/* 30 29 30 30 29 29 30 29 29 30 29 30 30 384
-1985 */{ 0 , 2 , 20 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 0 354
-1986 */{ 0 , 2 , 9 , 27968 },/* 29 30 30 29 30 30 29 30 29 30 29 29 0 354
-1987 */{ 6 , 1 , 29 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 29 384
-1988 */{ 0 , 2 , 17 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1989 */{ 0 , 2 , 6 , 38256 },/* 30 29 29 30 29 30 29 30 29 30 30 30 0 355
-1990 */{ 5 , 1 , 27 , 18808 },/* 29 30 29 29 30 29 29 30 29 30 30 30 30 384
-1991 */{ 0 , 2 , 15 , 18800 },/* 29 30 29 29 30 29 29 30 29 30 30 30 0 354
-1992 */{ 0 , 2 , 4 , 25776 },/* 29 30 30 29 29 30 29 29 30 29 30 30 0 354
-1993 */{ 3 , 1 , 23 , 27216 },/* 29 30 30 29 30 29 30 29 29 30 29 30 29 383
-1994 */{ 0 , 2 , 10 , 59984 },/* 30 30 30 29 30 29 30 29 29 30 29 30 0 355
-1995 */{ 8 , 1 , 31 , 27432 },/* 29 30 30 29 30 29 30 30 29 29 30 29 30 384
-1996 */{ 0 , 2 , 19 , 23232 },/* 29 30 29 30 30 29 30 29 30 30 29 29 0 354
-1997 */{ 0 , 2 , 7 , 43872 },/* 30 29 30 29 30 29 30 30 29 30 30 29 0 355
-1998 */{ 5 , 1 , 28 , 37736 },/* 30 29 29 30 29 29 30 30 29 30 30 29 30 384
-1999 */{ 0 , 2 , 16 , 37600 },/* 30 29 29 30 29 29 30 29 30 30 30 29 0 354
-2000 */{ 0 , 2 , 5 , 51552 },/* 30 30 29 29 30 29 29 30 29 30 30 29 0 354
-2001 */{ 4 , 1 , 24 , 54440 },/* 30 30 29 30 29 30 29 29 30 29 30 29 30 384
-2002 */{ 0 , 2 , 12 , 54432 },/* 30 30 29 30 29 30 29 29 30 29 30 29 0 354
-2003 */{ 0 , 2 , 1 , 55888 },/* 30 30 29 30 30 29 30 29 29 30 29 30 0 355
-2004 */{ 2 , 1 , 22 , 23208 },/* 29 30 29 30 30 29 30 29 30 29 30 29 30 384
-2005 */{ 0 , 2 , 9 , 22176 },/* 29 30 29 30 29 30 30 29 30 29 30 29 0 354
-2006 */{ 7 , 1 , 29 , 43736 },/* 30 29 30 29 30 29 30 29 30 30 29 30 30 385
-2007 */{ 0 , 2 , 18 , 9680 },/* 29 29 30 29 29 30 29 30 30 30 29 30 0 354
-2008 */{ 0 , 2 , 7 , 37584 },/* 30 29 29 30 29 29 30 29 30 30 29 30 0 354
-2009 */{ 5 , 1 , 26 , 51544 },/* 30 30 29 29 30 29 29 30 29 30 29 30 30 384
-2010 */{ 0 , 2 , 14 , 43344 },/* 30 29 30 29 30 29 29 30 29 30 29 30 0 354
-2011 */{ 0 , 2 , 3 , 46240 },/* 30 29 30 30 29 30 29 29 30 29 30 29 0 354
-2012 */{ 4 , 1 , 23 , 46416 },/* 30 29 30 30 29 30 29 30 29 30 29 30 29 384
-2013 */{ 0 , 2 , 10 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2014 */{ 9 , 1 , 31 , 21928 },/* 29 30 29 30 29 30 29 30 30 29 30 29 30 384
-2015 */{ 0 , 2 , 19 , 19360 },/* 29 30 29 29 30 29 30 30 30 29 30 29 0 354
-2016 */{ 0 , 2 , 8 , 42416 },/* 30 29 30 29 29 30 29 30 30 29 30 30 0 355
-2017 */{ 6 , 1 , 28 , 21176 },/* 29 30 29 30 29 29 30 29 30 29 30 30 30 384
-2018 */{ 0 , 2 , 16 , 21168 },/* 29 30 29 30 29 29 30 29 30 29 30 30 0 354
-2019 */{ 0 , 2 , 5 , 43312 },/* 30 29 30 29 30 29 29 30 29 29 30 30 0 354
-2020 */{ 4 , 1 , 25 , 29864 },/* 29 30 30 30 29 30 29 29 30 29 30 29 30 384
-2021 */{ 0 , 2 , 12 , 27296 },/* 29 30 30 29 30 29 30 29 30 29 30 29 0 354
-2022 */{ 0 , 2 , 1 , 44368 },/* 30 29 30 29 30 30 29 30 29 30 29 30 0 355
-2023 */{ 2 , 1 , 22 , 19880 },/* 29 30 29 29 30 30 29 30 30 29 30 29 30 384
-2024 */{ 0 , 2 , 10 , 19296 },/* 29 30 29 29 30 29 30 30 29 30 30 29 0 354
-2025 */{ 6 , 1 , 29 , 42352 },/* 30 29 30 29 29 30 29 30 29 30 30 30 29 384
-2026 */{ 0 , 2 , 17 , 42208 },/* 30 29 30 29 29 30 29 29 30 30 30 29 0 354
-2027 */{ 0 , 2 , 6 , 53856 },/* 30 30 29 30 29 29 30 29 29 30 30 29 0 354
-2028 */{ 5 , 1 , 26 , 59696 },/* 30 30 30 29 30 29 29 30 29 29 30 30 29 384
-2029 */{ 0 , 2 , 13 , 54576 },/* 30 30 29 30 29 30 29 30 29 29 30 30 0 355
-2030 */{ 0 , 2 , 3 , 23200 },/* 29 30 29 30 30 29 30 29 30 29 30 29 0 354
-2031 */{ 3 , 1 , 23 , 27472 },/* 29 30 30 29 30 29 30 30 29 30 29 30 29 384
-2032 */{ 0 , 2 , 11 , 38608 },/* 30 29 29 30 29 30 30 29 30 30 29 30 0 355
-2033 */{ 11 , 1 , 31 , 19176 },/* 29 30 29 29 30 29 30 29 30 30 30 29 30 384
-2034 */{ 0 , 2 , 19 , 19152 },/* 29 30 29 29 30 29 30 29 30 30 29 30 0 354
-2035 */{ 0 , 2 , 8 , 42192 },/* 30 29 30 29 29 30 29 29 30 30 29 30 0 354
-2036 */{ 6 , 1 , 28 , 53848 },/* 30 30 29 30 29 29 30 29 29 30 29 30 30 384
-2037 */{ 0 , 2 , 15 , 53840 },/* 30 30 29 30 29 29 30 29 29 30 29 30 0 354
-2038 */{ 0 , 2 , 4 , 54560 },/* 30 30 29 30 29 30 29 30 29 29 30 29 0 354
-2039 */{ 5 , 1 , 24 , 55968 },/* 30 30 29 30 30 29 30 29 30 29 30 29 29 384
-2040 */{ 0 , 2 , 12 , 46496 },/* 30 29 30 30 29 30 29 30 30 29 30 29 0 355
-2041 */{ 0 , 2 , 1 , 22224 },/* 29 30 29 30 29 30 30 29 30 30 29 30 0 355
-2042 */{ 2 , 1 , 22 , 19160 },/* 29 30 29 29 30 29 30 29 30 30 29 30 30 384
-2043 */{ 0 , 2 , 10 , 18864 },/* 29 30 29 29 30 29 29 30 30 29 30 30 0 354
-2044 */{ 7 , 1 , 30 , 42168 },/* 30 29 30 29 29 30 29 29 30 29 30 30 30 384
-2045 */{ 0 , 2 , 17 , 42160 },/* 30 29 30 29 29 30 29 29 30 29 30 30 0 354
-2046 */{ 0 , 2 , 6 , 43600 },/* 30 29 30 29 30 29 30 29 29 30 29 30 0 354
-2047 */{ 5 , 1 , 26 , 46376 },/* 30 29 30 30 29 30 29 30 29 29 30 29 30 384
-2048 */{ 0 , 2 , 14 , 27936 },/* 29 30 30 29 30 30 29 30 29 29 30 29 0 354
-2049 */{ 0 , 2 , 2 , 44448 },/* 30 29 30 29 30 30 29 30 30 29 30 29 0 355
-2050 */{ 3 , 1 , 23 , 21936 },/* 29 30 29 30 29 30 29 30 30 29 30 30 29 384
- */};
-
-
- internal override int MinCalendarYear {
- get
- {
- return (MIN_LUNISOLAR_YEAR);
- }
- }
-
- internal override int MaxCalendarYear {
- get
- {
- return (MAX_LUNISOLAR_YEAR);
- }
- }
-
- internal override DateTime MinDate {
- get
- {
- return (minDate);
- }
- }
-
- internal override DateTime MaxDate {
- get
- {
- return (maxDate);
- }
- }
-
- internal override EraInfo[] CalEraInfo {
- get
- {
- return (taiwanLunisolarEraInfo);
- }
- }
-
- internal override int GetYearInfo(int LunarYear, int Index) {
- if ((LunarYear < MIN_LUNISOLAR_YEAR) || (LunarYear > MAX_LUNISOLAR_YEAR)) {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- MIN_LUNISOLAR_YEAR,
- MAX_LUNISOLAR_YEAR ));
- }
- Contract.EndContractBlock();
-
- return yinfo[LunarYear - MIN_LUNISOLAR_YEAR, Index];
- }
-
- internal override int GetYear(int year, DateTime time) {
- return helper.GetYear(year, time);
- }
-
- internal override int GetGregorianYear(int year, int era) {
- return helper.GetGregorianYear(year, era);
- }
-
- /*=================================GetDefaultInstance==========================
- **Action: Internal method to provide a default intance of TaiwanLunisolarCalendar. Used by NLS+ implementation
- ** and other calendars.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
- /*
- internal static Calendar GetDefaultInstance()
- {
- if (m_defaultInstance == null) {
- m_defaultInstance = new TaiwanLunisolarCalendar();
- }
- return (m_defaultInstance);
- }
- */
-
- // Construct an instance of TaiwanLunisolar calendar.
-
- public TaiwanLunisolarCalendar() {
- helper = new GregorianCalendarHelper(this, taiwanLunisolarEraInfo);
- }
-
-
-
- public override int GetEra(DateTime time) {
- return (helper.GetEra(time));
- }
-
- internal override int BaseCalendarID {
- get {
- return (CAL_TAIWAN);
- }
- }
-
- internal override int ID {
- get {
- return (CAL_TAIWANLUNISOLAR);
- }
- }
-
-
-
- public override int[] Eras {
- get {
- return (helper.Eras);
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/TextElementEnumerator.cs b/src/mscorlib/src/System/Globalization/TextElementEnumerator.cs
index 0fee7a0745..464897b03f 100644
--- a/src/mscorlib/src/System/Globalization/TextElementEnumerator.cs
+++ b/src/mscorlib/src/System/Globalization/TextElementEnumerator.cs
@@ -10,93 +10,86 @@
//
////////////////////////////////////////////////////////////////////////////
+using System.Collections;
+using System.Diagnostics;
using System.Runtime.Serialization;
-
-namespace System.Globalization {
- using System.Collections;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
+namespace System.Globalization
+{
//
// This is public because GetTextElement() is public.
//
[Serializable]
- public class TextElementEnumerator: IEnumerator
+ public class TextElementEnumerator : IEnumerator
{
- private String str;
- private int index;
- private int startIndex;
-
+ private String _str;
+ private int _index;
+ private int _startIndex;
+
[NonSerialized]
- private int strLen; // This is the length of the total string, counting from the beginning of string.
-
- [NonSerialized]
- private int currTextElementLen; // The current text element lenght after MoveNext() is called.
-
+ private int _strLen; // This is the length of the total string, counting from the beginning of string.
+
+ [NonSerialized]
+ private int _currTextElementLen; // The current text element lenght after MoveNext() is called.
+
[OptionalField(VersionAdded = 2)]
- private UnicodeCategory uc;
-
+ private UnicodeCategory _uc;
+
[OptionalField(VersionAdded = 2)]
- private int charLen; // The next abstract char to look at after MoveNext() is called. It could be 1 or 2, depending on if it is a surrogate or not.
+ private int _charLen; // The next abstract char to look at after MoveNext() is called. It could be 1 or 2, depending on if it is a surrogate or not.
internal TextElementEnumerator(String str, int startIndex, int strLen)
{
Debug.Assert(str != null, "TextElementEnumerator(): str != null");
Debug.Assert(startIndex >= 0 && strLen >= 0, "TextElementEnumerator(): startIndex >= 0 && strLen >= 0");
Debug.Assert(strLen >= startIndex, "TextElementEnumerator(): strLen >= startIndex");
- this.str = str;
- this.startIndex = startIndex;
- this.strLen = strLen;
+ _str = str;
+ _startIndex = startIndex;
+ _strLen = strLen;
Reset();
}
-#region Serialization
// the following fields is defined to keep the compatibility with Everett.
// don't change/remove the names/types of these fields.
- private int endIndex;
- private int nextTextElementLen;
-
- [OnDeserializing]
- private void OnDeserializing(StreamingContext ctx)
- {
- charLen = -1;
- }
-
+ private int _endIndex;
+ private int _nextTextElementLen;
+
+ [OnDeserializing]
+ private void OnDeserializing(StreamingContext ctx)
+ {
+ _charLen = -1;
+ }
+
[OnDeserialized]
private void OnDeserialized(StreamingContext ctx)
{
- strLen = endIndex + 1;
- currTextElementLen = nextTextElementLen;
+ _strLen = _endIndex + 1;
+ _currTextElementLen = _nextTextElementLen;
- if (charLen == -1)
+ if (_charLen == -1)
{
- uc = CharUnicodeInfo.InternalGetUnicodeCategory(str, index, out charLen);
+ _uc = CharUnicodeInfo.InternalGetUnicodeCategory(_str, _index, out _charLen);
}
- }
-
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx)
- {
- endIndex = strLen - 1;
- nextTextElementLen = currTextElementLen;
- }
-
-#endregion Serialization
-
+ }
+ [OnSerializing]
+ private void OnSerializing(StreamingContext ctx)
+ {
+ _endIndex = _strLen - 1;
+ _nextTextElementLen = _currTextElementLen;
+ }
public bool MoveNext()
{
- if (index >= strLen)
+ if (_index >= _strLen)
{
- // Make the index to be greater than strLen so that we can throw exception if GetTextElement() is called.
- index = strLen + 1;
+ // Make the _index to be greater than _strLen so that we can throw exception if GetTextElement() is called.
+ _index = _strLen + 1;
return (false);
}
- currTextElementLen = StringInfo.GetCurrentTextElementLen(str, index, strLen, ref uc, ref charLen);
- index += currTextElementLen;
+ _currTextElementLen = StringInfo.GetCurrentTextElementLen(_str, _index, _strLen, ref _uc, ref _charLen);
+ _index += _currTextElementLen;
return (true);
}
@@ -104,8 +97,10 @@ namespace System.Globalization {
// Get the current text element.
//
- public Object Current {
- get {
+ public Object Current
+ {
+ get
+ {
return (GetTextElement());
}
}
@@ -116,16 +111,18 @@ namespace System.Globalization {
public String GetTextElement()
{
- if (index == startIndex) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumNotStarted"));
+ if (_index == _startIndex)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumNotStarted);
}
- if (index > strLen) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumEnded"));
- }
-
- return (str.Substring(index - currTextElementLen, currTextElementLen));
+ if (_index > _strLen)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_EnumEnded);
+ }
+
+ return (_str.Substring(_index - _currTextElementLen, _currTextElementLen));
}
-
+
//
// Get the starting index of the current text element.
//
@@ -134,22 +131,23 @@ namespace System.Globalization {
{
get
{
- if (index == startIndex)
+ if (_index == _startIndex)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumNotStarted"));
+ throw new InvalidOperationException(SR.InvalidOperation_EnumNotStarted);
}
- return (index - currTextElementLen);
+ return (_index - _currTextElementLen);
}
}
public void Reset()
{
- index = startIndex;
- if (index < strLen) {
+ _index = _startIndex;
+ if (_index < _strLen)
+ {
// If we have more than 1 character, get the category of the current char.
- uc = CharUnicodeInfo.InternalGetUnicodeCategory(str, index, out charLen);
- }
+ _uc = CharUnicodeInfo.InternalGetUnicodeCategory(_str, _index, out _charLen);
+ }
}
}
}
diff --git a/src/mscorlib/src/System/Globalization/TextInfo.Unix.cs b/src/mscorlib/src/System/Globalization/TextInfo.Unix.cs
new file mode 100644
index 0000000000..f7f64c684a
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/TextInfo.Unix.cs
@@ -0,0 +1,117 @@
+// 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.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Security;
+using System.Text;
+
+namespace System.Globalization
+{
+ public partial class TextInfo
+ {
+ [NonSerialized]
+ private Tristate _needsTurkishCasing = Tristate.NotInitialized;
+
+ private void FinishInitialization(string textInfoName)
+ {
+ }
+
+ private unsafe string ChangeCase(string s, bool toUpper)
+ {
+ Debug.Assert(!_invariantMode);
+
+ Debug.Assert(s != null);
+
+ if (s.Length == 0)
+ {
+ return string.Empty;
+ }
+
+ string result = string.FastAllocateString(s.Length);
+
+ fixed (char* pSource = s)
+ {
+ fixed (char* pResult = result)
+ {
+ if (IsAsciiCasingSameAsInvariant && s.IsAscii())
+ {
+ int length = s.Length;
+ char* a = pSource, b = pResult;
+ if (toUpper)
+ {
+ while (length-- != 0)
+ {
+ *b++ = ToUpperAsciiInvariant(*a++);
+ }
+ }
+ else
+ {
+ while (length-- != 0)
+ {
+ *b++ = ToLowerAsciiInvariant(*a++);
+ }
+ }
+ }
+ else
+ {
+ ChangeCase(pSource, s.Length, pResult, result.Length, toUpper);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private unsafe char ChangeCase(char c, bool toUpper)
+ {
+ Debug.Assert(!_invariantMode);
+
+ char dst = default(char);
+
+ ChangeCase(&c, 1, &dst, 1, toUpper);
+
+ return dst;
+ }
+
+ // -----------------------------
+ // ---- PAL layer ends here ----
+ // -----------------------------
+
+ private bool NeedsTurkishCasing(string localeName)
+ {
+ Debug.Assert(localeName != null);
+
+ return CultureInfo.GetCultureInfo(localeName).CompareInfo.Compare("\u0131", "I", CompareOptions.IgnoreCase) == 0;
+ }
+
+ private bool IsInvariant { get { return _cultureName.Length == 0; } }
+
+ internal unsafe void ChangeCase(char* src, int srcLen, char* dstBuffer, int dstBufferCapacity, bool bToUpper)
+ {
+ Debug.Assert(!_invariantMode);
+
+ if (IsInvariant)
+ {
+ Interop.GlobalizationInterop.ChangeCaseInvariant(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper);
+ }
+ else
+ {
+ if (_needsTurkishCasing == Tristate.NotInitialized)
+ {
+ _needsTurkishCasing = NeedsTurkishCasing(_textInfoName) ? Tristate.True : Tristate.False;
+ }
+ if (_needsTurkishCasing == Tristate.True)
+ {
+ Interop.GlobalizationInterop.ChangeCaseTurkish(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper);
+ }
+ else
+ {
+ Interop.GlobalizationInterop.ChangeCase(src, srcLen, dstBuffer, dstBufferCapacity, bToUpper);
+ }
+ }
+ }
+
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/TextInfo.Windows.cs b/src/mscorlib/src/System/Globalization/TextInfo.Windows.cs
new file mode 100644
index 0000000000..cc7c4df1da
--- /dev/null
+++ b/src/mscorlib/src/System/Globalization/TextInfo.Windows.cs
@@ -0,0 +1,113 @@
+// 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.Diagnostics;
+
+namespace System.Globalization
+{
+ public partial class TextInfo
+ {
+ private unsafe void FinishInitialization(string textInfoName)
+ {
+ if (_invariantMode)
+ {
+ _sortHandle = IntPtr.Zero;
+ return;
+ }
+
+ const uint LCMAP_SORTHANDLE = 0x20000000;
+
+ long handle;
+ int ret = Interop.Kernel32.LCMapStringEx(_textInfoName, LCMAP_SORTHANDLE, null, 0, &handle, IntPtr.Size, null, null, IntPtr.Zero);
+ _sortHandle = ret > 0 ? (IntPtr)handle : IntPtr.Zero;
+ }
+
+ private unsafe string ChangeCase(string s, bool toUpper)
+ {
+ Debug.Assert(!_invariantMode);
+
+ Debug.Assert(s != null);
+
+ //
+ // Get the length of the string.
+ //
+ int nLengthInput = s.Length;
+
+ //
+ // Check if we have the empty string.
+ //
+ if (nLengthInput == 0)
+ {
+ return s;
+ }
+
+ int ret;
+
+ // Check for Invariant to avoid A/V in LCMapStringEx
+ uint linguisticCasing = IsInvariantLocale(_textInfoName) ? 0 : LCMAP_LINGUISTIC_CASING;
+
+ //
+ // Create the result string.
+ //
+ string result = string.FastAllocateString(nLengthInput);
+
+ fixed (char* pSource = s)
+ fixed (char* pResult = result)
+ {
+ ret = Interop.Kernel32.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _textInfoName,
+ linguisticCasing | (toUpper ? LCMAP_UPPERCASE : LCMAP_LOWERCASE),
+ pSource,
+ nLengthInput,
+ pResult,
+ nLengthInput,
+ null,
+ null,
+ _sortHandle);
+ }
+
+ if (ret == 0)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
+
+ Debug.Assert(ret == nLengthInput, "Expected getting the same length of the original string");
+ return result;
+ }
+
+ private unsafe char ChangeCase(char c, bool toUpper)
+ {
+ Debug.Assert(!_invariantMode);
+
+ char retVal = '\0';
+
+ // Check for Invariant to avoid A/V in LCMapStringEx
+ uint linguisticCasing = IsInvariantLocale(_textInfoName) ? 0 : LCMAP_LINGUISTIC_CASING;
+
+ Interop.Kernel32.LCMapStringEx(_sortHandle != IntPtr.Zero ? null : _textInfoName,
+ toUpper ? LCMAP_UPPERCASE | linguisticCasing : LCMAP_LOWERCASE | linguisticCasing,
+ &c,
+ 1,
+ &retVal,
+ 1,
+ null,
+ null,
+ _sortHandle);
+
+ return retVal;
+ }
+
+ // PAL Ends here
+
+ private IntPtr _sortHandle;
+
+ private const uint LCMAP_LINGUISTIC_CASING = 0x01000000;
+ private const uint LCMAP_LOWERCASE = 0x00000100;
+ private const uint LCMAP_UPPERCASE = 0x00000200;
+
+ private static bool IsInvariantLocale(string localeName)
+ {
+ return localeName == "";
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/TextInfo.cs b/src/mscorlib/src/System/Globalization/TextInfo.cs
index 9ece275dd3..fecd2b2970 100644
--- a/src/mscorlib/src/System/Globalization/TextInfo.cs
+++ b/src/mscorlib/src/System/Globalization/TextInfo.cs
@@ -12,27 +12,19 @@
//
////////////////////////////////////////////////////////////////////////////
-using System.Security;
-
-namespace System.Globalization {
- using System;
- using System.Text;
- using System.Threading;
- using System.Runtime;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Runtime.Serialization;
- using System.Runtime.Versioning;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+using System.Text;
+namespace System.Globalization
+{
[Serializable]
public partial class TextInfo : ICloneable, IDeserializationCallback
{
- //--------------------------------------------------------------------//
- // Internal Information //
- //--------------------------------------------------------------------//
+ ////--------------------------------------------------------------------//
+ //// Internal Information //
+ ////--------------------------------------------------------------------//
private enum Tristate : byte
{
@@ -41,49 +33,42 @@ namespace System.Globalization {
False,
}
- //
- // Variables.
- //
+ ////
+ //// Variables.
+ ////
[OptionalField(VersionAdded = 2)]
- private String m_listSeparator;
-
+ private String _listSeparator;
[OptionalField(VersionAdded = 2)]
- private bool m_isReadOnly = false;
-
- //
- // In Whidbey we had several names:
- // m_win32LangID is the name of the culture, but only used for (de)serialization.
- // customCultureName is the name of the creating custom culture (if custom) In combination with m_win32LangID
- // this is authoratative, ie when deserializing.
- // m_cultureTableRecord was the data record of the creating culture. (could have different name if custom)
- // m_textInfoID is the LCID of the textinfo itself (no longer used)
- // m_name is the culture name (from cultureinfo.name)
- //
- // In Silverlight/Arrowhead this is slightly different:
- // m_cultureName is the name of the creating culture. Note that we consider this authoratative,
- // if the culture's textinfo changes when deserializing, then behavior may change.
- // (ala Whidbey behavior). This is the only string Arrowhead needs to serialize.
- // m_cultureData is the data that backs this class.
- // m_textInfoName is the actual name of the textInfo (from cultureData.STEXTINFO)
- // m_textInfoName can be the same as m_cultureName on Silverlight since the OS knows
- // how to do the sorting. However in the desktop, when we call the sorting dll, it doesn't
- // know how to resolve custom locle names to sort ids so we have to have alredy resolved this.
- //
+ private bool _isReadOnly = false;
+
+ //// _cultureName is the name of the creating culture. Note that we consider this authoratative,
+ //// if the culture's textinfo changes when deserializing, then behavior may change.
+ //// (ala Whidbey behavior). This is the only string Arrowhead needs to serialize.
+ //// _cultureData is the data that backs this class.
+ //// _textInfoName is the actual name of the textInfo (from cultureData.STEXTINFO)
+ //// this can be the same as _cultureName on Silverlight since the OS knows
+ //// how to do the sorting. However in the desktop, when we call the sorting dll, it doesn't
+ //// know how to resolve custom locle names to sort ids so we have to have alredy resolved this.
+ ////
[OptionalField(VersionAdded = 3)]
- private String m_cultureName; // Name of the culture that created this text info
- [NonSerialized]private CultureData m_cultureData; // Data record for the culture that made us, not for this textinfo
- [NonSerialized]private String m_textInfoName; // Name of the text info we're using (ie: m_cultureData.STEXTINFO)
- [NonSerialized]private IntPtr m_dataHandle; // Sort handle
- [NonSerialized]private IntPtr m_handleOrigin;
- [NonSerialized]private Tristate m_IsAsciiCasingSameAsInvariant = Tristate.NotInitialized;
-
+ private String _cultureName; // Name of the culture that created this text info
+ [NonSerialized]
+ private CultureData _cultureData; // Data record for the culture that made us, not for this textinfo
+ [NonSerialized]
+ private String _textInfoName; // Name of the text info we're using (ie: _cultureData.STEXTINFO)
+ [NonSerialized]
+ private Tristate _isAsciiCasingSameAsInvariant = Tristate.NotInitialized;
+
+ // _invariantMode is defined for the perf reason as accessing the instance field is faster than access the static property GlobalizationMode.Invariant
+ [NonSerialized]
+ private readonly bool _invariantMode = GlobalizationMode.Invariant;
// Invariant text info
- internal static TextInfo Invariant
+ internal static TextInfo Invariant
{
- get
+ get
{
if (s_Invariant == null)
s_Invariant = new TextInfo(CultureData.Invariant);
@@ -92,88 +77,31 @@ namespace System.Globalization {
}
internal volatile static TextInfo s_Invariant;
- ////////////////////////////////////////////////////////////////////////
- //
- // TextInfo Constructors
- //
- // Implements CultureInfo.TextInfo.
- //
- ////////////////////////////////////////////////////////////////////////
- internal TextInfo(CultureData cultureData)
+ //////////////////////////////////////////////////////////////////////////
+ ////
+ //// TextInfo Constructors
+ ////
+ //// Implements CultureInfo.TextInfo.
+ ////
+ //////////////////////////////////////////////////////////////////////////
+ internal unsafe TextInfo(CultureData cultureData)
{
// This is our primary data source, we don't need most of the rest of this
- this.m_cultureData = cultureData;
- this.m_cultureName = this.m_cultureData.CultureName;
- this.m_textInfoName = this.m_cultureData.STEXTINFO;
+ _cultureData = cultureData;
+ _cultureName = _cultureData.CultureName;
+ _textInfoName = _cultureData.STEXTINFO;
+ FinishInitialization(_textInfoName);
}
- ////////////////////////////////////////////////////////////////////////
- //
- // Serialization / Deserialization
- //
- // Note that we have to respect the Whidbey behavior for serialization compatibility
- //
- ////////////////////////////////////////////////////////////////////////
-
-#region Serialization
- // the following fields are defined to keep the compatibility with Whidbey.
- // don't change/remove the names/types of these fields.
- [OptionalField(VersionAdded = 2)]
- private string customCultureName;
-
- // the following fields are defined to keep compatibility with Everett.
- // don't change/remove the names/types of these fields.
- [OptionalField(VersionAdded = 1)]
- internal int m_nDataItem;
- [OptionalField(VersionAdded = 1)]
- internal bool m_useUserOverride;
- [OptionalField(VersionAdded = 1)]
- internal int m_win32LangID;
-
-
- [OnDeserializing]
- private void OnDeserializing(StreamingContext ctx)
- {
- // Clear these so we can check if we've fixed them yet
- this.m_cultureData = null;
- this.m_cultureName = null;
- }
+ [OnSerializing]
+ private void OnSerializing(StreamingContext ctx) { }
- private void OnDeserialized()
+ [OnDeserializing]
+ private void OnDeserializing(StreamingContext ctx)
{
- // this method will be called twice because of the support of IDeserializationCallback
- if (this.m_cultureData == null)
- {
- if (this.m_cultureName == null)
- {
- // This is whidbey data, get it from customCultureName/win32langid
- if (this.customCultureName != null)
- {
- // They gave a custom cultuer name, so use that
- this.m_cultureName = this.customCultureName;
- }
-#if FEATURE_USE_LCID
- else
- {
- if (m_win32LangID == 0)
- {
- // m_cultureName and m_win32LangID are nulls which means we got uninitialized textinfo serialization stream.
- // To be compatible with v2/3/3.5 we need to return ar-SA TextInfo in this case.
- m_cultureName = "ar-SA";
- }
- else
- {
- // No custom culture, use the name from the LCID
- m_cultureName = CultureInfo.GetCultureInfo(m_win32LangID).m_cultureData.CultureName;
- }
- }
-#endif
- }
-
- // Get the text info name belonging to that culture
- this.m_cultureData = CultureInfo.GetCultureInfo(m_cultureName).m_cultureData;
- this.m_textInfoName = this.m_cultureData.STEXTINFO;
- }
+ // Clear these so we can check if we've fixed them yet
+ _cultureData = null;
+ _cultureName = null;
}
[OnDeserialized]
@@ -182,142 +110,56 @@ namespace System.Globalization {
OnDeserialized();
}
- [OnSerializing]
- private void OnSerializing(StreamingContext ctx)
+ void IDeserializationCallback.OnDeserialization(Object sender)
{
- // Relabel our name since Whidbey expects it to be called customCultureName
- this.customCultureName = this.m_cultureName;
+ OnDeserialized();
+ }
-#if FEATURE_USE_LCID
- // Ignore the m_win32LangId because whidbey'll just get it by name if we make it the LOCALE_CUSTOM_UNSPECIFIED.
- this.m_win32LangID = (CultureInfo.GetCultureInfo(m_cultureName)).LCID;
-#endif
- }
-
-#endregion Serialization
+ private void OnDeserialized()
+ {
+ // this method will be called twice because of the support of IDeserializationCallback
+ if (_cultureData == null)
+ {
+ // Get the text info name belonging to that culture
+ _cultureData = CultureInfo.GetCultureInfo(_cultureName)._cultureData;
+ _textInfoName = _cultureData.STEXTINFO;
+ FinishInitialization(_textInfoName);
+ }
+ }
//
// Internal ordinal comparison functions
//
- internal static int GetHashCodeOrdinalIgnoreCase(String s)
- {
- return GetHashCodeOrdinalIgnoreCase(s, false, 0);
- }
- internal static int GetHashCodeOrdinalIgnoreCase(String s, bool forceRandomizedHashing, long additionalEntropy)
+ internal static int GetHashCodeOrdinalIgnoreCase(String s)
{
// This is the same as an case insensitive hash for Invariant
// (not necessarily true for sorting, but OK for casing & then we apply normal hash code rules)
- return (Invariant.GetCaseInsensitiveHashCode(s, forceRandomizedHashing, additionalEntropy));
- }
-
- internal static unsafe bool TryFastFindStringOrdinalIgnoreCase(int searchFlags, String source, int startIndex, String value, int count, ref int foundIndex)
- {
- return InternalTryFindStringOrdinalIgnoreCase(searchFlags, source, count, startIndex, value, value.Length, ref foundIndex);
- }
-
- // This function doesn't check arguments. Please do check in the caller.
- // The underlying unmanaged code will assert the sanity of arguments.
- internal static unsafe int CompareOrdinalIgnoreCase(String str1, String str2)
- {
- // Compare the whole string and ignore case.
- return InternalCompareStringOrdinalIgnoreCase(str1, 0, str2, 0, str1.Length, str2.Length);
- }
-
- // This function doesn't check arguments. Please do check in the caller.
- // The underlying unmanaged code will assert the sanity of arguments.
- internal static unsafe int CompareOrdinalIgnoreCaseEx(String strA, int indexA, String strB, int indexB, int lengthA, int lengthB )
- {
- Debug.Assert(strA.Length >= indexA + lengthA, "[TextInfo.CompareOrdinalIgnoreCaseEx] Caller should've validated strA.Length >= indexA + lengthA");
- Debug.Assert(strB.Length >= indexB + lengthB, "[TextInfo.CompareOrdinalIgnoreCaseEx] Caller should've validated strB.Length >= indexB + lengthB");
- return InternalCompareStringOrdinalIgnoreCase(strA, indexA, strB, indexB, lengthA, lengthB);
+ return (Invariant.GetCaseInsensitiveHashCode(s));
}
+ // Currently we don't have native functions to do this, so we do it the hard way
internal static int IndexOfStringOrdinalIgnoreCase(String source, String value, int startIndex, int count)
{
- Debug.Assert(source != null, "[TextInfo.IndexOfStringOrdinalIgnoreCase] Caller should've validated source != null");
- Debug.Assert(value != null, "[TextInfo.IndexOfStringOrdinalIgnoreCase] Caller should've validated value != null");
- Debug.Assert(startIndex + count <= source.Length, "[TextInfo.IndexOfStringOrdinalIgnoreCase] Caller should've validated startIndex + count <= source.Length");
-
- // We return 0 if both inputs are empty strings
- if (source.Length == 0 && value.Length == 0)
+ if (count > source.Length || count < 0 || startIndex < 0 || startIndex >= source.Length || startIndex + count > source.Length)
{
- return 0;
+ return -1;
}
- // fast path
- int ret = -1;
- if (TryFastFindStringOrdinalIgnoreCase(Microsoft.Win32.Win32Native.FIND_FROMSTART, source, startIndex, value, count, ref ret))
- return ret;
-
- // the search space within [source] starts at offset [startIndex] inclusive and includes
- // [count] characters (thus the last included character is at index [startIndex + count -1]
- // [end] is the index of the next character after the search space
- // (it points past the end of the search space)
- int end = startIndex + count;
-
- // maxStartIndex is the index beyond which we never *start* searching, inclusive; in other words;
- // a search could include characters beyond maxStartIndex, but we'd never begin a search at an
- // index strictly greater than maxStartIndex.
- int maxStartIndex = end - value.Length;
-
- for (; startIndex <= maxStartIndex; startIndex++)
- {
- // We should always have the same or more characters left to search than our actual pattern
- Debug.Assert(end - startIndex >= value.Length);
- // since this is an ordinal comparison, we can assume that the lengths must match
- if (CompareOrdinalIgnoreCaseEx(source, startIndex, value, 0, value.Length, value.Length) == 0)
- {
- return startIndex;
- }
- }
-
- // Not found
- return -1;
+ return CultureInfo.InvariantCulture.CompareInfo.IndexOfOrdinal(source, value, startIndex, count, ignoreCase: true);
}
+ // Currently we don't have native functions to do this, so we do it the hard way
internal static int LastIndexOfStringOrdinalIgnoreCase(String source, String value, int startIndex, int count)
{
- Debug.Assert(source != null, "[TextInfo.LastIndexOfStringOrdinalIgnoreCase] Caller should've validated source != null");
- Debug.Assert(value != null, "[TextInfo.LastIndexOfStringOrdinalIgnoreCase] Caller should've validated value != null");
- Debug.Assert(startIndex - count+1 >= 0, "[TextInfo.LastIndexOfStringOrdinalIgnoreCase] Caller should've validated startIndex - count+1 >= 0");
- Debug.Assert(startIndex <= source.Length, "[TextInfo.LastIndexOfStringOrdinalIgnoreCase] Caller should've validated startIndex <= source.Length");
-
- // If value is Empty, the return value is startIndex
- if (value.Length == 0)
- {
- return startIndex;
- }
-
- // fast path
- int ret = -1;
- if (TryFastFindStringOrdinalIgnoreCase(Microsoft.Win32.Win32Native.FIND_FROMEND, source, startIndex, value, count, ref ret))
- return ret;
-
- // the search space within [source] ends at offset [startIndex] inclusive
- // and includes [count] characters
- // minIndex is the first included character and is at index [startIndex - count + 1]
- int minIndex = startIndex - count + 1;
-
- // First place we can find it is start index - (value.length -1)
- if (value.Length > 0)
+ if (count > source.Length || count < 0 || startIndex < 0 || startIndex > source.Length - 1 || (startIndex - count + 1 < 0))
{
- startIndex -= (value.Length - 1);
+ return -1;
}
- for (; startIndex >= minIndex; startIndex--)
- {
- if (CompareOrdinalIgnoreCaseEx(source, startIndex, value, 0, value.Length, value.Length) == 0)
- {
- return startIndex;
- }
- }
-
- // Not found
- return -1;
+ return CultureInfo.InvariantCulture.CompareInfo.LastIndexOfOrdinal(source, value, startIndex, count, ignoreCase: true);
}
-
////////////////////////////////////////////////////////////////////////
//
// CodePage
@@ -331,72 +173,62 @@ namespace System.Globalization {
////////////////////////////////////////////////////////////////////////
- public virtual int ANSICodePage
+ public virtual int ANSICodePage
{
- get
+ get
{
- return (this.m_cultureData.IDEFAULTANSICODEPAGE);
+ return (_cultureData.IDEFAULTANSICODEPAGE);
}
}
-
- public virtual int OEMCodePage
+
+ public virtual int OEMCodePage
{
- get
+ get
{
- return (this.m_cultureData.IDEFAULTOEMCODEPAGE);
+ return (_cultureData.IDEFAULTOEMCODEPAGE);
}
}
- public virtual int MacCodePage
+ public virtual int MacCodePage
{
- get
+ get
{
- return (this.m_cultureData.IDEFAULTMACCODEPAGE);
+ return (_cultureData.IDEFAULTMACCODEPAGE);
}
}
- public virtual int EBCDICCodePage
+ public virtual int EBCDICCodePage
{
- get
+ get
{
- return (this.m_cultureData.IDEFAULTEBCDICCODEPAGE);
+ return (_cultureData.IDEFAULTEBCDICCODEPAGE);
}
}
- ////////////////////////////////////////////////////////////////////////
- //
- // LCID
- //
- // We need a way to get an LCID from outside of the BCL. This prop is the way.
- // NOTE: neutral cultures will cause GPS incorrect LCIDS from this
- //
- ////////////////////////////////////////////////////////////////////////
-
-#if FEATURE_USE_LCID
public int LCID
{
- get
+ get
{
// Just use the LCID from our text info name
- return CultureInfo.GetCultureInfo(this.m_textInfoName).LCID;
+ return CultureInfo.GetCultureInfo(_textInfoName).LCID;
}
}
-#endif
- ////////////////////////////////////////////////////////////////////////
- //
- // CultureName
- //
- // The name of the culture associated with the current TextInfo.
- //
- ////////////////////////////////////////////////////////////////////////
- public string CultureName
+
+ //////////////////////////////////////////////////////////////////////////
+ ////
+ //// CultureName
+ ////
+ //// The name of the culture associated with the current TextInfo.
+ ////
+ //////////////////////////////////////////////////////////////////////////
+ public string CultureName
{
- get
+ get
{
- return(this.m_textInfoName);
+ return _textInfoName;
}
}
@@ -407,25 +239,25 @@ namespace System.Globalization {
// Detect if the object is readonly.
//
////////////////////////////////////////////////////////////////////////
- public bool IsReadOnly
+ public bool IsReadOnly
{
- get { return (m_isReadOnly); }
+ get { return (_isReadOnly); }
}
- ////////////////////////////////////////////////////////////////////////
- //
- // Clone
- //
- // Is the implementation of ICloneable.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual Object Clone()
+ //////////////////////////////////////////////////////////////////////////
+ ////
+ //// Clone
+ ////
+ //// Is the implementation of ICloneable.
+ ////
+ //////////////////////////////////////////////////////////////////////////
+ public virtual object Clone()
{
object o = MemberwiseClone();
- ((TextInfo) o).SetReadOnlyState(false);
+ ((TextInfo)o).SetReadOnlyState(false);
return (o);
}
-
+
////////////////////////////////////////////////////////////////////////
//
// ReadOnly
@@ -434,30 +266,29 @@ namespace System.Globalization {
// readonly.
//
////////////////////////////////////////////////////////////////////////
- public static TextInfo ReadOnly(TextInfo textInfo)
+ public static TextInfo ReadOnly(TextInfo textInfo)
{
- if (textInfo == null) { throw new ArgumentNullException(nameof(textInfo)); }
+ if (textInfo == null) { throw new ArgumentNullException(nameof(textInfo)); }
Contract.EndContractBlock();
- if (textInfo.IsReadOnly) { return (textInfo); }
-
+ if (textInfo.IsReadOnly) { return (textInfo); }
+
TextInfo clonedTextInfo = (TextInfo)(textInfo.MemberwiseClone());
clonedTextInfo.SetReadOnlyState(true);
-
+
return (clonedTextInfo);
}
private void VerifyWritable()
{
- if (m_isReadOnly)
+ if (_isReadOnly)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
- Contract.EndContractBlock();
}
internal void SetReadOnlyState(bool readOnly)
{
- m_isReadOnly = readOnly;
+ _isReadOnly = readOnly;
}
@@ -468,27 +299,25 @@ namespace System.Globalization {
// Returns the string used to separate items in a list.
//
////////////////////////////////////////////////////////////////////////
-
-
- public virtual String ListSeparator
+ public virtual String ListSeparator
{
- get
+ get
{
- if (m_listSeparator == null) {
- m_listSeparator = this.m_cultureData.SLIST;
+ if (_listSeparator == null)
+ {
+ _listSeparator = _cultureData.SLIST;
}
- return (m_listSeparator);
+ return (_listSeparator);
}
- set
+ set
{
- if (value == null)
+ if (value == null)
{
- throw new ArgumentNullException(nameof(value), Environment.GetResourceString("ArgumentNull_String"));
+ throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String);
}
- Contract.EndContractBlock();
VerifyWritable();
- m_listSeparator = value;
+ _listSeparator = value;
}
}
@@ -500,28 +329,123 @@ namespace System.Globalization {
// have different casing semantics from the file systems in Win32.
//
////////////////////////////////////////////////////////////////////////
-
- public unsafe virtual char ToLower(char c)
+ public unsafe virtual char ToLower(char c)
{
- if(IsAscii(c) && IsAsciiCasingSameAsInvariant)
+ if (_invariantMode || (IsAscii(c) && IsAsciiCasingSameAsInvariant))
{
return ToLowerAsciiInvariant(c);
}
- return (InternalChangeCaseChar(this.m_dataHandle, this.m_handleOrigin, this.m_textInfoName, c, false));
+
+ return (ChangeCase(c, toUpper: false));
}
- public unsafe virtual String ToLower(String str)
+ public unsafe virtual String ToLower(String str)
{
if (str == null) { throw new ArgumentNullException(nameof(str)); }
- Contract.EndContractBlock();
- return InternalChangeCaseString(this.m_dataHandle, this.m_handleOrigin, this.m_textInfoName, str, false);
+ if (_invariantMode)
+ {
+ return ToLowerAsciiInvariant(str);
+ }
+ return ChangeCase(str, toUpper: false);
}
- static private Char ToLowerAsciiInvariant(Char c)
+ private unsafe string ToLowerAsciiInvariant(string s)
{
- if ('A' <= c && c <= 'Z')
+ if (s.Length == 0)
+ {
+ return string.Empty;
+ }
+
+ fixed (char* pSource = s)
+ {
+ int i = 0;
+ while (i < s.Length)
+ {
+ if ((uint)(pSource[i] - 'A') <= (uint)('Z' - 'A'))
+ {
+ break;
+ }
+ i++;
+ }
+
+ if (i >= s.Length)
+ {
+ return s;
+ }
+
+ string result = string.FastAllocateString(s.Length);
+ fixed (char* pResult = result)
+ {
+ for (int j = 0; j < i; j++)
+ {
+ pResult[j] = pSource[j];
+ }
+
+ pResult[i] = (Char)(pSource[i] | 0x20);
+ i++;
+
+ while (i < s.Length)
+ {
+ pResult[i] = ToLowerAsciiInvariant(pSource[i]);
+ i++;
+ }
+ }
+
+ return result;
+ }
+ }
+
+ private unsafe string ToUpperAsciiInvariant(string s)
+ {
+ if (s.Length == 0)
+ {
+ return string.Empty;
+ }
+
+ fixed (char* pSource = s)
+ {
+ int i = 0;
+ while (i < s.Length)
+ {
+ if ((uint)(pSource[i] - 'a') <= (uint)('z' - 'a'))
+ {
+ break;
+ }
+ i++;
+ }
+
+ if (i >= s.Length)
+ {
+ return s;
+ }
+
+ string result = string.FastAllocateString(s.Length);
+ fixed (char* pResult = result)
+ {
+ for (int j = 0; j < i; j++)
+ {
+ pResult[j] = pSource[j];
+ }
+
+ pResult[i] = (char)(pSource[i] & ~0x20);
+ i++;
+
+ while (i < s.Length)
+ {
+ pResult[i] = ToUpperAsciiInvariant(pSource[i]);
+ i++;
+ }
+ }
+
+ return result;
+ }
+ }
+
+ private static Char ToLowerAsciiInvariant(Char c)
+ {
+ if ((uint)(c - 'A') <= (uint)('Z' - 'A'))
{
c = (Char)(c | 0x20);
}
@@ -536,34 +460,38 @@ namespace System.Globalization {
// have different casing semantics from the file systems in Win32.
//
////////////////////////////////////////////////////////////////////////
-
- public unsafe virtual char ToUpper(char c)
+ public unsafe virtual char ToUpper(char c)
{
- if (IsAscii(c) && IsAsciiCasingSameAsInvariant)
+ if (_invariantMode || (IsAscii(c) && IsAsciiCasingSameAsInvariant))
{
return ToUpperAsciiInvariant(c);
}
- return (InternalChangeCaseChar(this.m_dataHandle, this.m_handleOrigin, this.m_textInfoName, c, true));
+
+ return (ChangeCase(c, toUpper: true));
}
-
- public unsafe virtual String ToUpper(String str)
+ public unsafe virtual String ToUpper(String str)
{
if (str == null) { throw new ArgumentNullException(nameof(str)); }
- Contract.EndContractBlock();
- return InternalChangeCaseString(this.m_dataHandle, this.m_handleOrigin, this.m_textInfoName, str, true);
+
+ if (_invariantMode)
+ {
+ return ToUpperAsciiInvariant(str);
+ }
+
+ return ChangeCase(str, toUpper: true);
}
- static private Char ToUpperAsciiInvariant(Char c)
+ private static Char ToUpperAsciiInvariant(Char c)
{
- if ('a' <= c && c <= 'z')
+ if ((uint)(c - 'a') <= (uint)('z' - 'a'))
{
c = (Char)(c & ~0x20);
}
return c;
}
- static private bool IsAscii(Char c)
+ private static bool IsAscii(Char c)
{
return c < 0x80;
}
@@ -572,14 +500,25 @@ namespace System.Globalization {
{
get
{
- if (m_IsAsciiCasingSameAsInvariant == Tristate.NotInitialized)
+ if (_isAsciiCasingSameAsInvariant == Tristate.NotInitialized)
{
- m_IsAsciiCasingSameAsInvariant =
- CultureInfo.GetCultureInfo(m_textInfoName).CompareInfo.Compare("abcdefghijklmnopqrstuvwxyz",
+ _isAsciiCasingSameAsInvariant = CultureInfo.GetCultureInfo(_textInfoName).CompareInfo.Compare("abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
CompareOptions.IgnoreCase) == 0 ? Tristate.True : Tristate.False;
}
- return m_IsAsciiCasingSameAsInvariant == Tristate.True;
+ return _isAsciiCasingSameAsInvariant == Tristate.True;
+ }
+ }
+
+ // IsRightToLeft
+ //
+ // Returns true if the dominant direction of text and UI such as the relative position of buttons and scroll bars
+ //
+ public bool IsRightToLeft
+ {
+ get
+ {
+ return _cultureData.IsRightToLeft;
}
}
@@ -591,21 +530,18 @@ namespace System.Globalization {
// or not object refers to the same CultureInfo as the current instance.
//
////////////////////////////////////////////////////////////////////////
-
-
public override bool Equals(Object obj)
{
TextInfo that = obj as TextInfo;
-
+
if (that != null)
{
return this.CultureName.Equals(that.CultureName);
}
-
+
return (false);
}
-
////////////////////////////////////////////////////////////////////////
//
// GetHashCode
@@ -615,14 +551,11 @@ namespace System.Globalization {
// and B where A.Equals(B) is true.
//
////////////////////////////////////////////////////////////////////////
-
-
public override int GetHashCode()
{
return (this.CultureName.GetHashCode());
}
-
////////////////////////////////////////////////////////////////////////
//
// ToString
@@ -631,14 +564,11 @@ namespace System.Globalization {
// TextInfo.
//
////////////////////////////////////////////////////////////////////////
-
-
public override String ToString()
{
- return ("TextInfo - " + this.m_cultureData.CultureName);
+ return ("TextInfo - " + _cultureData.CultureName);
}
-
//
// Titlecasing:
// -----------
@@ -653,41 +583,44 @@ namespace System.Globalization {
// influence which letter or letters of a "word" are uppercased when titlecasing strings. For example
// "l'arbre" is considered two words in French, whereas "can't" is considered one word in English.
//
- //
- // Differences between UNICODE 5.0 and the .NET Framework:
- // -------------------------------------------------------------------------------------
- // The .NET Framework previously shipped a naive titlecasing implementation. Every word is titlecased
- // regardless of language or orthographic practice. Furthermore, apostrophe is always considered to be
- // a word joiner as used in English. The longterm vision is to depend on the operating system for
- // titlecasing. Windows 7 is expected to be the first release with this feature. On the Macintosh side,
- // titlecasing is not available as of version 10.5 of the operating system.
- //
- public unsafe String ToTitleCase(String str)
+ public unsafe String ToTitleCase(String str)
{
- if (str == null)
+ if (str == null)
{
throw new ArgumentNullException(nameof(str));
}
Contract.EndContractBlock();
- if (str.Length == 0)
+ if (str.Length == 0)
{
return (str);
}
StringBuilder result = new StringBuilder();
- String lowercaseData = null;
+ string lowercaseData = null;
+ // Store if the current culture is Dutch (special case)
+ bool isDutchCulture = CultureName.StartsWith("nl-", StringComparison.OrdinalIgnoreCase);
- for (int i = 0; i < str.Length; i++)
+ for (int i = 0; i < str.Length; i++)
{
UnicodeCategory charType;
int charLen;
charType = CharUnicodeInfo.InternalGetUnicodeCategory(str, i, out charLen);
- if (Char.CheckLetter(charType))
+ if (Char.CheckLetter(charType))
{
- // Do the titlecasing for the first character of the word.
- i = AddTitlecaseLetter(ref result, ref str, i, charLen) + 1;
-
+ // Special case to check for Dutch specific titlecasing with "IJ" characters
+ // at the beginning of a word
+ if (isDutchCulture && i < str.Length - 1 && (str[i] == 'i' || str[i] == 'I') && (str[i+1] == 'j' || str[i+1] == 'J'))
+ {
+ result.Append("IJ");
+ i += 2;
+ }
+ else
+ {
+ // Do the titlecasing for the first character of the word.
+ i = AddTitlecaseLetter(ref result, ref str, i, charLen) + 1;
+ }
+
//
// Convert the characters until the end of the this word
// to lowercase.
@@ -700,42 +633,42 @@ namespace System.Globalization {
//
bool hasLowerCase = (charType == UnicodeCategory.LowercaseLetter);
// Use a loop to find all of the other letters following this letter.
- while (i < str.Length)
+ while (i < str.Length)
{
charType = CharUnicodeInfo.InternalGetUnicodeCategory(str, i, out charLen);
- if (IsLetterCategory(charType))
+ if (IsLetterCategory(charType))
{
- if (charType == UnicodeCategory.LowercaseLetter)
+ if (charType == UnicodeCategory.LowercaseLetter)
{
hasLowerCase = true;
}
i += charLen;
- }
- else if (str[i] == '\'')
+ }
+ else if (str[i] == '\'')
{
i++;
- if (hasLowerCase)
+ if (hasLowerCase)
{
- if (lowercaseData == null)
+ if (lowercaseData == null)
{
lowercaseData = this.ToLower(str);
}
result.Append(lowercaseData, lowercaseStart, i - lowercaseStart);
- }
- else
+ }
+ else
{
result.Append(str, lowercaseStart, i - lowercaseStart);
}
lowercaseStart = i;
hasLowerCase = true;
- }
- else if (!IsWordSeparator(charType))
+ }
+ else if (!IsWordSeparator(charType))
{
// This category is considered to be part of the word.
// This is any category that is marked as false in wordSeprator array.
i+= charLen;
- }
- else
+ }
+ else
{
// A word separator. Break out of the loop.
break;
@@ -744,29 +677,29 @@ namespace System.Globalization {
int count = i - lowercaseStart;
- if (count>0)
+ if (count > 0)
{
- if (hasLowerCase)
+ if (hasLowerCase)
{
- if (lowercaseData == null)
+ if (lowercaseData == null)
{
lowercaseData = this.ToLower(str);
}
result.Append(lowercaseData, lowercaseStart, count);
- }
- else
+ }
+ else
{
result.Append(str, lowercaseStart, count);
}
}
- if (i < str.Length)
+ if (i < str.Length)
{
// not a letter, just append it
i = AddNonLetter(ref result, ref str, i, charLen);
}
}
- else
+ else
{
// not a letter, just append it
i = AddNonLetter(ref result, ref str, i, charLen);
@@ -775,75 +708,73 @@ namespace System.Globalization {
return (result.ToString());
}
- private static int AddNonLetter(ref StringBuilder result, ref String input, int inputIndex, int charLen)
+ private static int AddNonLetter(ref StringBuilder result, ref String input, int inputIndex, int charLen)
{
Debug.Assert(charLen == 1 || charLen == 2, "[TextInfo.AddNonLetter] CharUnicodeInfo.InternalGetUnicodeCategory returned an unexpected charLen!");
- if (charLen == 2)
+ if (charLen == 2)
{
// Surrogate pair
result.Append(input[inputIndex++]);
result.Append(input[inputIndex]);
}
- else
+ else
{
result.Append(input[inputIndex]);
- }
+ }
return inputIndex;
}
-
- private int AddTitlecaseLetter(ref StringBuilder result, ref String input, int inputIndex, int charLen)
+ private int AddTitlecaseLetter(ref StringBuilder result, ref String input, int inputIndex, int charLen)
{
Debug.Assert(charLen == 1 || charLen == 2, "[TextInfo.AddTitlecaseLetter] CharUnicodeInfo.InternalGetUnicodeCategory returned an unexpected charLen!");
// for surrogate pairs do a simple ToUpper operation on the substring
- if (charLen == 2)
+ if (charLen == 2)
{
// Surrogate pair
- result.Append( this.ToUpper(input.Substring(inputIndex, charLen)) );
+ result.Append(ToUpper(input.Substring(inputIndex, charLen)));
inputIndex++;
}
- else
+ else
{
- switch (input[inputIndex])
+ switch (input[inputIndex])
{
//
// For AppCompat, the Titlecase Case Mapping data from NDP 2.0 is used below.
- case (char)0x01C4: // DZ with Caron -> Dz with Caron
- case (char)0x01C5: // Dz with Caron -> Dz with Caron
- case (char)0x01C6: // dz with Caron -> Dz with Caron
- result.Append( (char)0x01C5 );
+ case (char) 0x01C4: // DZ with Caron -> Dz with Caron
+ case (char) 0x01C5: // Dz with Caron -> Dz with Caron
+ case (char) 0x01C6: // dz with Caron -> Dz with Caron
+ result.Append((char) 0x01C5);
break;
- case (char)0x01C7: // LJ -> Lj
- case (char)0x01C8: // Lj -> Lj
- case (char)0x01C9: // lj -> Lj
- result.Append( (char)0x01C8 );
+ case (char) 0x01C7: // LJ -> Lj
+ case (char) 0x01C8: // Lj -> Lj
+ case (char) 0x01C9: // lj -> Lj
+ result.Append((char) 0x01C8);
break;
- case (char)0x01CA: // NJ -> Nj
- case (char)0x01CB: // Nj -> Nj
- case (char)0x01CC: // nj -> Nj
- result.Append( (char)0x01CB );
+ case (char) 0x01CA: // NJ -> Nj
+ case (char) 0x01CB: // Nj -> Nj
+ case (char) 0x01CC: // nj -> Nj
+ result.Append((char) 0x01CB);
break;
- case (char)0x01F1: // DZ -> Dz
- case (char)0x01F2: // Dz -> Dz
- case (char)0x01F3: // dz -> Dz
- result.Append( (char)0x01F2 );
+ case (char) 0x01F1: // DZ -> Dz
+ case (char) 0x01F2: // Dz -> Dz
+ case (char) 0x01F3: // dz -> Dz
+ result.Append((char) 0x01F2);
break;
default:
- result.Append( this.ToUpper(input[inputIndex]) );
+ result.Append(ToUpper(input[inputIndex]));
break;
}
- }
+ }
return inputIndex;
}
-
//
// Used in ToTitleCase():
// When we find a starting letter, the following array decides if a category should be
// considered as word seprator or not.
//
- private const int wordSeparatorMask =
+ private const int c_wordSeparatorMask =
/* false */ (0 << 0) | // UppercaseLetter = 0,
/* false */ (0 << 1) | // LowercaseLetter = 1,
/* false */ (0 << 2) | // TitlecaseLetter = 2,
@@ -874,13 +805,13 @@ namespace System.Globalization {
/* true */ (1 << 27) | // ModifierSymbol = 27,
/* true */ (1 << 28) | // OtherSymbol = 28,
/* false */ (0 << 29); // OtherNotAssigned = 29;
-
+
private static bool IsWordSeparator(UnicodeCategory category)
{
- return (wordSeparatorMask & (1 << (int)category)) != 0;
+ return (c_wordSeparatorMask & (1 << (int) category)) != 0;
}
- private static bool IsLetterCategory(UnicodeCategory uc)
+ private static bool IsLetterCategory(UnicodeCategory uc)
{
return (uc == UnicodeCategory.UppercaseLetter
|| uc == UnicodeCategory.LowercaseLetter
@@ -889,76 +820,63 @@ namespace System.Globalization {
|| uc == UnicodeCategory.OtherLetter);
}
- // IsRightToLeft
//
- // Returns true if the dominant direction of text and UI such as the relative position of buttons and scroll bars
+ // Get case-insensitive hash code for the specified string.
//
- public bool IsRightToLeft
+ internal unsafe int GetCaseInsensitiveHashCode(String str)
{
- get
+ // Validate inputs
+ if (str == null)
{
- return this.m_cultureData.IsRightToLeft;
+ throw new ArgumentNullException(nameof(str));
}
- }
- /// <internalonly/>
- void IDeserializationCallback.OnDeserialization(Object sender)
- {
- OnDeserialized();
- }
+ // This code assumes that ASCII casing is safe for whatever context is passed in.
+ // this is true today, because we only ever call these methods on Invariant. It would be ideal to refactor
+ // these methods so they were correct by construction and we could only ever use Invariant.
- //
- // Get case-insensitive hash code for the specified string.
- //
- // NOTENOTE: this is an internal function. The caller should verify the string
- // is not null before calling this. Currenlty, CaseInsensitiveHashCodeProvider
- // does that.
- //
- internal unsafe int GetCaseInsensitiveHashCode(String str)
- {
- return GetCaseInsensitiveHashCode(str, false, 0);
- }
+ uint hash = 5381;
+ uint c;
- internal unsafe int GetCaseInsensitiveHashCode(String str, bool forceRandomizedHashing, long additionalEntropy)
- {
- // Validate inputs
- if (str==null)
+ // Note: We assume that str contains only ASCII characters until
+ // we hit a non-ASCII character to optimize the common case.
+ for (int i = 0; i < str.Length; i++)
{
- throw new ArgumentNullException(nameof(str));
+ c = str[i];
+ if (c >= 0x80)
+ {
+ return GetCaseInsensitiveHashCodeSlow(str);
+ }
+
+ // If we have a lowercase character, ANDing off 0x20
+ // will make it an uppercase character.
+ if ((c - 'a') <= ('z' - 'a'))
+ {
+ c = (uint)((int)c & ~0x20);
+ }
+
+ hash = ((hash << 5) + hash) ^ c;
}
- Contract.EndContractBlock();
- // Return our result
- return (InternalGetCaseInsHash(this.m_dataHandle, this.m_handleOrigin, this.m_textInfoName, str, forceRandomizedHashing, additionalEntropy));
+ return (int)hash;
}
- // Change case (ToUpper/ToLower) -- COMNlsInfo::InternalChangeCaseChar
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static unsafe extern char InternalChangeCaseChar(IntPtr handle, IntPtr handleOrigin, String localeName, char ch, bool isToUpper);
-
- // Change case (ToUpper/ToLower) -- COMNlsInfo::InternalChangeCaseString
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static unsafe extern String InternalChangeCaseString(IntPtr handle, IntPtr handleOrigin, String localeName, String str, bool isToUpper);
-
- // Get case insensitive hash -- ComNlsInfo::InternalGetCaseInsHash
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static unsafe extern int InternalGetCaseInsHash(IntPtr handle, IntPtr handleOrigin, String localeName, String str, bool forceRandomizedHashing, long additionalEntropy);
-
- // Call ::CompareStringOrdinal -- ComNlsInfo::InternalCompareStringOrdinalIgnoreCase
- // Start at indexes and compare for length characters (or remainder of string if length == -1)
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static unsafe extern int InternalCompareStringOrdinalIgnoreCase(String string1, int index1, String string2, int index2, int length1, int length2);
-
- // ComNlsInfo::InternalTryFindStringOrdinalIgnoreCase attempts a faster IndexOf/LastIndexOf OrdinalIgnoreCase using a kernel function.
- // Returns true if FindStringOrdinal was handled, with foundIndex set to the target's index into the source
- // Returns false when FindStringOrdinal wasn't handled
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static unsafe extern bool InternalTryFindStringOrdinalIgnoreCase(int searchFlags, String source, int sourceCount, int startIndex, String target, int targetCount, ref int foundIndex);
- }
+ private unsafe int GetCaseInsensitiveHashCodeSlow(String str)
+ {
+ Debug.Assert(str != null);
-}
+ string upper = ToUpper(str);
+ uint hash = 5381;
+ uint c;
+
+ for (int i = 0; i < upper.Length; i++)
+ {
+ c = upper[i];
+ hash = ((hash << 5) + hash) ^ c;
+ }
+ return (int)hash;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Globalization/ThaiBuddhistCalendar.cs b/src/mscorlib/src/System/Globalization/ThaiBuddhistCalendar.cs
deleted file mode 100644
index 762c3ca7cb..0000000000
--- a/src/mscorlib/src/System/Globalization/ThaiBuddhistCalendar.cs
+++ /dev/null
@@ -1,219 +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.
-
-namespace System.Globalization {
-
- using System;
- using System.Diagnostics.CodeAnalysis;
- using System.Diagnostics.Contracts;
-
- /*=================================ThaiBuddhistCalendar==========================
- **
- ** ThaiBuddhistCalendar is based on Gregorian calendar. Its year value has
- ** an offset to the Gregorain calendar.
- **
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 0001/01/01 9999/12/31
- ** Thai 0544/01/01 10542/12/31
- ============================================================================*/
-
-
- [Serializable] public class ThaiBuddhistCalendar: Calendar {
-
- // Initialize our era info.
- static internal EraInfo[] thaiBuddhistEraInfo = new EraInfo[] {
- new EraInfo( 1, 1, 1, 1, -543, 544, GregorianCalendar.MaxYear + 543) // era #, start year/month/day, yearOffset, minEraYear
- };
-
- //
- // The era value for the current era.
- //
-
- public const int ThaiBuddhistEra = 1;
-
- //internal static Calendar m_defaultInstance;
-
- internal GregorianCalendarHelper helper;
-
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (DateTime.MinValue);
- }
- }
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (DateTime.MaxValue);
- }
- }
-
- // Return the type of the Thai Buddhist calendar.
- //
-
- public override CalendarAlgorithmType AlgorithmType
- {
- get
- {
- return CalendarAlgorithmType.SolarCalendar;
- }
- }
-
- public ThaiBuddhistCalendar() {
- helper = new GregorianCalendarHelper(this, thaiBuddhistEraInfo);
- }
-
- internal override int ID {
- get {
- return (CAL_THAI);
- }
- }
-
-
- public override DateTime AddMonths(DateTime time, int months) {
- return (helper.AddMonths(time, months));
- }
-
-
- public override DateTime AddYears(DateTime time, int years) {
- return (helper.AddYears(time, years));
- }
-
-
- public override int GetDaysInMonth(int year, int month, int era) {
- return (helper.GetDaysInMonth(year, month, era));
- }
-
-
- public override int GetDaysInYear(int year, int era) {
- return (helper.GetDaysInYear(year, era));
- }
-
-
- public override int GetDayOfMonth(DateTime time) {
- return (helper.GetDayOfMonth(time));
- }
-
-
- public override DayOfWeek GetDayOfWeek(DateTime time) {
- return (helper.GetDayOfWeek(time));
- }
-
-
- public override int GetDayOfYear(DateTime time)
- {
- return (helper.GetDayOfYear(time));
- }
-
-
- public override int GetMonthsInYear(int year, int era) {
- return (helper.GetMonthsInYear(year, era));
- }
-
-
- [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
- public override int GetWeekOfYear(DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek)
- {
- return (helper.GetWeekOfYear(time, rule, firstDayOfWeek));
- }
-
-
- public override int GetEra(DateTime time) {
- return (helper.GetEra(time));
- }
-
- public override int GetMonth(DateTime time) {
- return (helper.GetMonth(time));
- }
-
-
- public override int GetYear(DateTime time) {
- return (helper.GetYear(time));
- }
-
-
- public override bool IsLeapDay(int year, int month, int day, int era)
- {
- return (helper.IsLeapDay(year, month, day, era));
- }
-
-
- public override bool IsLeapYear(int year, int era) {
- return (helper.IsLeapYear(year, era));
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
- public override int GetLeapMonth(int year, int era)
- {
- return (helper.GetLeapMonth(year, era));
- }
-
-
- public override bool IsLeapMonth(int year, int month, int era) {
- return (helper.IsLeapMonth(year, month, era));
- }
-
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) {
- return (helper.ToDateTime(year, month, day, hour, minute, second, millisecond, era));
- }
-
-
- public override int[] Eras {
- get {
- return (helper.Eras);
- }
- }
-
- private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 2572;
-
-
- public override int TwoDigitYearMax
- {
- get
- {
- if (twoDigitYearMax == -1) {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
- }
- return (twoDigitYearMax);
- }
-
- set {
- VerifyWritable();
- if (value < 99 || value > helper.MaxYear) {
- throw new ArgumentOutOfRangeException(
- "year",
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- 99,
- helper.MaxYear));
-
- }
- twoDigitYearMax = value;
- }
- }
-
-
- public override int ToFourDigitYear(int year) {
- if (year < 0) {
- throw new ArgumentOutOfRangeException(nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- Contract.EndContractBlock();
-
- return (helper.ToFourDigitYear(year, this.TwoDigitYearMax));
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/Globalization/TimeSpanFormat.cs b/src/mscorlib/src/System/Globalization/TimeSpanFormat.cs
index e5e615f1b3..ca053eded3 100644
--- a/src/mscorlib/src/System/Globalization/TimeSpanFormat.cs
+++ b/src/mscorlib/src/System/Globalization/TimeSpanFormat.cs
@@ -3,44 +3,51 @@
// See the LICENSE file in the project root for more information.
//
-namespace System.Globalization {
- using System.Text;
- using System;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- internal static class TimeSpanFormat {
-
- private static String IntToString(int n, int digits) {
+using System.Text;
+using System;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+
+namespace System.Globalization
+{
+ internal static class TimeSpanFormat
+ {
+ private static String IntToString(int n, int digits)
+ {
return ParseNumbers.IntToString(n, 10, digits, '0', 0);
}
- internal static readonly FormatLiterals PositiveInvariantFormatLiterals = TimeSpanFormat.FormatLiterals.InitInvariant(false /*isNegative*/);
- internal static readonly FormatLiterals NegativeInvariantFormatLiterals = TimeSpanFormat.FormatLiterals.InitInvariant(true /*isNegative*/);
+ internal static readonly FormatLiterals PositiveInvariantFormatLiterals = TimeSpanFormat.FormatLiterals.InitInvariant(false /*isNegative*/);
+ internal static readonly FormatLiterals NegativeInvariantFormatLiterals = TimeSpanFormat.FormatLiterals.InitInvariant(true /*isNegative*/);
- internal enum Pattern {
- None = 0,
+ internal enum Pattern
+ {
+ None = 0,
Minimum = 1,
- Full = 2,
- }
+ Full = 2,
+ }
//
// Format
//
// Actions: Main method called from TimeSpan.ToString
//
- internal static String Format(TimeSpan value, String format, IFormatProvider formatProvider) {
+ internal static String Format(TimeSpan value, String format, IFormatProvider formatProvider)
+ {
if (format == null || format.Length == 0)
format = "c";
// standard formats
- if (format.Length == 1) {
+ if (format.Length == 1)
+ {
char f = format[0];
if (f == 'c' || f == 't' || f == 'T')
return FormatStandard(value, true, format, Pattern.Minimum);
- if (f == 'g' || f == 'G') {
+ if (f == 'g' || f == 'G')
+ {
Pattern pattern;
DateTimeFormatInfo dtfi = DateTimeFormatInfo.GetInstance(formatProvider);
@@ -52,10 +59,10 @@ namespace System.Globalization {
pattern = Pattern.Minimum;
else
pattern = Pattern.Full;
-
+
return FormatStandard(value, false, format, pattern);
}
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ throw new FormatException(SR.Format_InvalidString);
}
return FormatCustomized(value, format, DateTimeFormatInfo.GetInstance(formatProvider));
@@ -66,32 +73,37 @@ namespace System.Globalization {
//
// Actions: Format the TimeSpan instance using the specified format.
//
- private static String FormatStandard(TimeSpan value, bool isInvariant, String format, Pattern pattern) {
+ private static String FormatStandard(TimeSpan value, bool isInvariant, String format, Pattern pattern)
+ {
StringBuilder sb = StringBuilderCache.Acquire();
int day = (int)(value._ticks / TimeSpan.TicksPerDay);
long time = value._ticks % TimeSpan.TicksPerDay;
- if (value._ticks < 0) {
+ if (value._ticks < 0)
+ {
day = -day;
time = -time;
}
- int hours = (int)(time / TimeSpan.TicksPerHour % 24);
- int minutes = (int)(time / TimeSpan.TicksPerMinute % 60);
- int seconds = (int)(time / TimeSpan.TicksPerSecond % 60);
+ int hours = (int)(time / TimeSpan.TicksPerHour % 24);
+ int minutes = (int)(time / TimeSpan.TicksPerMinute % 60);
+ int seconds = (int)(time / TimeSpan.TicksPerSecond % 60);
int fraction = (int)(time % TimeSpan.TicksPerSecond);
FormatLiterals literal;
- if (isInvariant) {
+ if (isInvariant)
+ {
if (value._ticks < 0)
literal = NegativeInvariantFormatLiterals;
else
literal = PositiveInvariantFormatLiterals;
}
- else {
+ else
+ {
literal = new FormatLiterals();
literal.Init(format, pattern == Pattern.Full);
}
- if (fraction != 0) { // truncate the partial second to the specified length
+ if (fraction != 0)
+ { // truncate the partial second to the specified length
fraction = (int)((long)fraction / (long)Math.Pow(10, DateTimeFormat.MaxSecondsFractionDigits - literal.ff));
}
@@ -99,7 +111,8 @@ namespace System.Globalization {
// Pattern.Minimum: [-][d.]hh:mm:ss[.fffffff]
sb.Append(literal.Start); // [-]
- if (pattern == Pattern.Full || day != 0) { //
+ if (pattern == Pattern.Full || day != 0)
+ { //
sb.Append(day); // [dd]
sb.Append(literal.DayHourSep); // [.]
} //
@@ -108,23 +121,29 @@ namespace System.Globalization {
sb.Append(IntToString(minutes, literal.mm)); // mm
sb.Append(literal.MinuteSecondSep); // :
sb.Append(IntToString(seconds, literal.ss)); // ss
- if (!isInvariant && pattern == Pattern.Minimum) {
+ if (!isInvariant && pattern == Pattern.Minimum)
+ {
int effectiveDigits = literal.ff;
- while (effectiveDigits > 0) {
- if (fraction % 10 == 0) {
+ while (effectiveDigits > 0)
+ {
+ if (fraction % 10 == 0)
+ {
fraction = fraction / 10;
effectiveDigits--;
}
- else {
+ else
+ {
break;
}
}
- if (effectiveDigits > 0) {
+ if (effectiveDigits > 0)
+ {
sb.Append(literal.SecondFractionSep); // [.FFFFFFF]
sb.Append((fraction).ToString(DateTimeFormat.fixedNumberFormats[effectiveDigits - 1], CultureInfo.InvariantCulture));
}
}
- else if (pattern == Pattern.Full || fraction != 0) {
+ else if (pattern == Pattern.Full || fraction != 0)
+ {
sb.Append(literal.SecondFractionSep); // [.]
sb.Append(IntToString(fraction, literal.ff)); // [fffffff]
} //
@@ -141,47 +160,50 @@ namespace System.Globalization {
//
// Actions: Format the TimeSpan instance using the specified format.
//
- internal static String FormatCustomized(TimeSpan value, String format, DateTimeFormatInfo dtfi) {
-
+ internal static String FormatCustomized(TimeSpan value, String format, DateTimeFormatInfo dtfi)
+ {
Debug.Assert(dtfi != null, "dtfi == null");
int day = (int)(value._ticks / TimeSpan.TicksPerDay);
long time = value._ticks % TimeSpan.TicksPerDay;
- if (value._ticks < 0) {
+ if (value._ticks < 0)
+ {
day = -day;
time = -time;
}
- int hours = (int)(time / TimeSpan.TicksPerHour % 24);
- int minutes = (int)(time / TimeSpan.TicksPerMinute % 60);
- int seconds = (int)(time / TimeSpan.TicksPerSecond % 60);
+ int hours = (int)(time / TimeSpan.TicksPerHour % 24);
+ int minutes = (int)(time / TimeSpan.TicksPerMinute % 60);
+ int seconds = (int)(time / TimeSpan.TicksPerSecond % 60);
int fraction = (int)(time % TimeSpan.TicksPerSecond);
long tmp = 0;
int i = 0;
int tokenLen;
StringBuilder result = StringBuilderCache.Acquire();
-
- while (i < format.Length) {
+
+ while (i < format.Length)
+ {
char ch = format[i];
int nextChar;
- switch (ch) {
+ switch (ch)
+ {
case 'h':
tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch);
if (tokenLen > 2)
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ throw new FormatException(SR.Format_InvalidString);
DateTimeFormat.FormatDigits(result, hours, tokenLen);
break;
case 'm':
tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch);
if (tokenLen > 2)
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ throw new FormatException(SR.Format_InvalidString);
DateTimeFormat.FormatDigits(result, minutes, tokenLen);
break;
case 's':
tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch);
if (tokenLen > 2)
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ throw new FormatException(SR.Format_InvalidString);
DateTimeFormat.FormatDigits(result, seconds, tokenLen);
break;
case 'f':
@@ -190,7 +212,7 @@ namespace System.Globalization {
//
tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch);
if (tokenLen > DateTimeFormat.MaxSecondsFractionDigits)
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ throw new FormatException(SR.Format_InvalidString);
tmp = (long)fraction;
tmp /= (long)Math.Pow(10, DateTimeFormat.MaxSecondsFractionDigits - tokenLen);
@@ -202,21 +224,25 @@ namespace System.Globalization {
//
tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch);
if (tokenLen > DateTimeFormat.MaxSecondsFractionDigits)
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ throw new FormatException(SR.Format_InvalidString);
tmp = (long)fraction;
tmp /= (long)Math.Pow(10, DateTimeFormat.MaxSecondsFractionDigits - tokenLen);
int effectiveDigits = tokenLen;
- while (effectiveDigits > 0) {
- if (tmp % 10 == 0) {
+ while (effectiveDigits > 0)
+ {
+ if (tmp % 10 == 0)
+ {
tmp = tmp / 10;
effectiveDigits--;
}
- else {
+ else
+ {
break;
}
}
- if (effectiveDigits > 0) {
+ if (effectiveDigits > 0)
+ {
result.Append((tmp).ToString(DateTimeFormat.fixedNumberFormats[effectiveDigits - 1], CultureInfo.InvariantCulture));
}
break;
@@ -227,12 +253,12 @@ namespace System.Globalization {
//
tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch);
if (tokenLen > 8)
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ throw new FormatException(SR.Format_InvalidString);
DateTimeFormat.FormatDigits(result, day, tokenLen, true);
break;
case '\'':
case '\"':
- tokenLen = DateTimeFormat.ParseQuoteString(format, i, result);
+ tokenLen = DateTimeFormat.ParseQuoteString(format, i, result);
break;
case '%':
// Optional format character.
@@ -241,7 +267,8 @@ namespace System.Globalization {
nextChar = DateTimeFormat.ParseNextChar(format, i);
// nextChar will be -1 if we already reach the end of the format string.
// Besides, we will not allow "%%" appear in the pattern.
- if (nextChar >= 0 && nextChar != (int)'%') {
+ if (nextChar >= 0 && nextChar != (int)'%')
+ {
result.Append(TimeSpanFormat.FormatCustomized(value, ((char)nextChar).ToString(), dtfi));
tokenLen = 2;
}
@@ -251,7 +278,7 @@ namespace System.Globalization {
// This means that '%' is at the end of the format string or
// "%%" appears in the format string.
//
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ throw new FormatException(SR.Format_InvalidString);
}
break;
case '\\':
@@ -263,55 +290,67 @@ namespace System.Globalization {
{
result.Append(((char)nextChar));
tokenLen = 2;
- }
+ }
else
{
//
// This means that '\' is at the end of the formatting string.
//
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ throw new FormatException(SR.Format_InvalidString);
}
break;
default:
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ throw new FormatException(SR.Format_InvalidString);
}
i += tokenLen;
}
return StringBuilderCache.GetStringAndRelease(result);
-
}
- internal struct FormatLiterals {
- internal String Start {
- get {
+ internal struct FormatLiterals
+ {
+ internal String Start
+ {
+ get
+ {
return literals[0];
}
}
- internal String DayHourSep {
- get {
+ internal String DayHourSep
+ {
+ get
+ {
return literals[1];
}
}
- internal String HourMinuteSep {
- get {
+ internal String HourMinuteSep
+ {
+ get
+ {
return literals[2];
}
}
- internal String MinuteSecondSep {
- get {
+ internal String MinuteSecondSep
+ {
+ get
+ {
return literals[3];
}
}
- internal String SecondFractionSep {
- get {
+ internal String SecondFractionSep
+ {
+ get
+ {
return literals[4];
}
}
- internal String End {
- get {
+ internal String End
+ {
+ get
+ {
return literals[5];
}
}
@@ -320,13 +359,14 @@ namespace System.Globalization {
internal int hh;
internal int mm;
internal int ss;
- internal int ff;
+ internal int ff;
private String[] literals;
/* factory method for static invariant FormatLiterals */
- internal static FormatLiterals InitInvariant(bool isNegative) {
+ internal static FormatLiterals InitInvariant(bool isNegative)
+ {
FormatLiterals x = new FormatLiterals();
x.literals = new String[6];
x.literals[0] = isNegative ? "-" : String.Empty;
@@ -334,7 +374,7 @@ namespace System.Globalization {
x.literals[2] = ":";
x.literals[3] = ":";
x.literals[4] = ".";
- x.literals[5] = String.Empty;
+ x.literals[5] = String.Empty;
x.AppCompatLiteral = ":."; // MinuteSecondSep+SecondFractionSep;
x.dd = 2;
x.hh = 2;
@@ -348,9 +388,10 @@ namespace System.Globalization {
// the constants guaranteed to include DHMSF ordered greatest to least significant.
// Once the data becomes more complex than this we will need to write a proper tokenizer for
// parsing and formatting
- internal void Init(String format, bool useInvariantFieldLengths) {
+ internal void Init(String format, bool useInvariantFieldLengths)
+ {
literals = new String[6];
- for (int i = 0; i < literals.Length; i++)
+ for (int i = 0; i < literals.Length; i++)
literals[i] = String.Empty;
dd = 0;
hh = 0;
@@ -361,30 +402,37 @@ namespace System.Globalization {
StringBuilder sb = StringBuilderCache.Acquire();
bool inQuote = false;
char quote = '\'';
- int field = 0;
+ int field = 0;
- for (int i = 0; i < format.Length; i++) {
- switch (format[i]) {
+ for (int i = 0; i < format.Length; i++)
+ {
+ switch (format[i])
+ {
case '\'':
case '\"':
- if (inQuote && (quote == format[i])) {
+ if (inQuote && (quote == format[i]))
+ {
/* we were in a quote and found a matching exit quote, so we are outside a quote now */
Debug.Assert(field >= 0 && field <= 5, "field >= 0 && field <= 5");
- if (field >= 0 && field <= 5) {
+ if (field >= 0 && field <= 5)
+ {
literals[field] = sb.ToString();
sb.Length = 0;
inQuote = false;
}
- else {
+ else
+ {
return; // how did we get here?
}
}
- else if (!inQuote) {
+ else if (!inQuote)
+ {
/* we are at the start of a new quote block */
quote = format[i];
inQuote = true;
}
- else {
+ else
+ {
/* we were in a quote and saw the other type of quote character, so we are still in a quote */
}
break;
@@ -392,13 +440,15 @@ namespace System.Globalization {
Debug.Assert(false, "Unexpected special token '%', Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
goto default;
case '\\':
- if (!inQuote) {
+ if (!inQuote)
+ {
i++; /* skip next character that is escaped by this backslash or percent sign */
break;
}
goto default;
case 'd':
- if (!inQuote) {
+ if (!inQuote)
+ {
Debug.Assert((field == 0 && sb.Length == 0) || field == 1,
"field == 0 || field == 1, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
field = 1; // DayHourSep
@@ -406,7 +456,8 @@ namespace System.Globalization {
}
break;
case 'h':
- if (!inQuote) {
+ if (!inQuote)
+ {
Debug.Assert((field == 1 && sb.Length == 0) || field == 2,
"field == 1 || field == 2, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
field = 2; // HourMinuteSep
@@ -414,7 +465,8 @@ namespace System.Globalization {
}
break;
case 'm':
- if (!inQuote) {
+ if (!inQuote)
+ {
Debug.Assert((field == 2 && sb.Length == 0) || field == 3,
"field == 2 || field == 3, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
field = 3; // MinuteSecondSep
@@ -422,7 +474,8 @@ namespace System.Globalization {
}
break;
case 's':
- if (!inQuote) {
+ if (!inQuote)
+ {
Debug.Assert((field == 3 && sb.Length == 0) || field == 4,
"field == 3 || field == 4, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
field = 4; // SecondFractionSep
@@ -431,7 +484,8 @@ namespace System.Globalization {
break;
case 'f':
case 'F':
- if (!inQuote) {
+ if (!inQuote)
+ {
Debug.Assert((field == 4 && sb.Length == 0) || field == 5,
"field == 4 || field == 5, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
field = 5; // End
@@ -453,14 +507,16 @@ namespace System.Globalization {
Debug.Assert(0 < ss && ss < 3, "0 < ss && ss < 3, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
Debug.Assert(0 < ff && ff < 8, "0 < ff && ff < 8, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern");
- if (useInvariantFieldLengths) {
+ if (useInvariantFieldLengths)
+ {
dd = 2;
hh = 2;
mm = 2;
ss = 2;
ff = DateTimeFormat.MaxSecondsFractionDigits;
}
- else {
+ else
+ {
if (dd < 1 || dd > 2) dd = 2; // The DTFI property has a problem. let's try to make the best of the situation.
if (hh < 1 || hh > 2) hh = 2;
if (mm < 1 || mm > 2) mm = 2;
diff --git a/src/mscorlib/src/System/Globalization/TimeSpanParse.cs b/src/mscorlib/src/System/Globalization/TimeSpanParse.cs
index d83c5fa151..a29e6c2e29 100644
--- a/src/mscorlib/src/System/Globalization/TimeSpanParse.cs
+++ b/src/mscorlib/src/System/Globalization/TimeSpanParse.cs
@@ -50,83 +50,95 @@
// TimeSpanTokenizer.NextChar and TimeSpanTokenizer.BackOne() are called directly.
//
////////////////////////////////////////////////////////////////////////////
-namespace System.Globalization {
- using System.Text;
- using System;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Globalization;
-
- internal static class TimeSpanParse {
+
+using System.Text;
+using System;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+
+namespace System.Globalization
+{
+ internal static class TimeSpanParse
+ {
// ---- SECTION: members for internal support ---------*
- internal static void ValidateStyles(TimeSpanStyles style, String parameterName) {
+ internal static void ValidateStyles(TimeSpanStyles style, String parameterName)
+ {
if (style != TimeSpanStyles.None && style != TimeSpanStyles.AssumeNegative)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTimeSpanStyles"), parameterName);
+ throw new ArgumentException(SR.Argument_InvalidTimeSpanStyles, parameterName);
}
internal const int unlimitedDigits = -1;
internal const int maxFractionDigits = 7;
- internal const int maxDays = 10675199;
- internal const int maxHours = 23;
- internal const int maxMinutes = 59;
- internal const int maxSeconds = 59;
+ internal const int maxDays = 10675199;
+ internal const int maxHours = 23;
+ internal const int maxMinutes = 59;
+ internal const int maxSeconds = 59;
internal const int maxFraction = 9999999;
#region InternalSupport
- enum TimeSpanThrowStyle {
- None = 0,
- All = 1,
+ private enum TimeSpanThrowStyle
+ {
+ None = 0,
+ All = 1,
}
- private enum ParseFailureKind {
- None = 0,
- ArgumentNull = 1,
- Format = 2,
- FormatWithParameter = 3,
- Overflow = 4,
+ private enum ParseFailureKind
+ {
+ None = 0,
+ ArgumentNull = 1,
+ Format = 2,
+ FormatWithParameter = 3,
+ Overflow = 4,
}
[Flags]
- enum TimeSpanStandardStyles { // Standard Format Styles
- None = 0x00000000,
- Invariant = 0x00000001, //Allow Invariant Culture
- Localized = 0x00000002, //Allow Localized Culture
- RequireFull = 0x00000004, //Require the input to be in DHMSF format
- Any = Invariant | Localized,
+ private enum TimeSpanStandardStyles
+ { // Standard Format Styles
+ None = 0x00000000,
+ Invariant = 0x00000001, //Allow Invariant Culture
+ Localized = 0x00000002, //Allow Localized Culture
+ RequireFull = 0x00000004, //Require the input to be in DHMSF format
+ Any = Invariant | Localized,
}
// TimeSpan Token Types
- private enum TTT {
- None = 0, // None of the TimeSpanToken fields are set
- End = 1, // '\0'
- Num = 2, // Number
- Sep = 3, // literal
- NumOverflow = 4, // Number that overflowed
+ private enum TTT
+ {
+ None = 0, // None of the TimeSpanToken fields are set
+ End = 1, // '\0'
+ Num = 2, // Number
+ Sep = 3, // literal
+ NumOverflow = 4, // Number that overflowed
}
private static readonly TimeSpanToken zero = new TimeSpanToken(0);
- struct TimeSpanToken {
+ private struct TimeSpanToken
+ {
internal TTT ttt;
internal int num; // Store the number that we are parsing (if any)
internal int zeroes; // Store the number of leading zeroes (if any)
internal String sep; // Store the literal that we are parsing (if any)
- public TimeSpanToken(int number) {
+ public TimeSpanToken(int number)
+ {
ttt = TTT.Num;
num = number;
zeroes = 0;
sep = null;
}
- public TimeSpanToken(int leadingZeroes, int number) {
+ public TimeSpanToken(int leadingZeroes, int number)
+ {
ttt = TTT.Num;
num = number;
zeroes = leadingZeroes;
sep = null;
}
- public bool IsInvalidNumber(int maxValue, int maxPrecision) {
+ public bool IsInvalidNumber(int maxValue, int maxPrecision)
+ {
Debug.Assert(ttt == TTT.Num);
Debug.Assert(num > -1);
Debug.Assert(maxValue > 0);
@@ -138,12 +150,12 @@ namespace System.Globalization {
return false; // all validation past this point applies only to fields with precision limits
if (zeroes > maxPrecision)
return true;
- if (num == 0 || zeroes == 0)
+ if (num == 0 || zeroes == 0)
return false;
// num > 0 && zeroes > 0 && num <= maxValue && zeroes <= maxPrecision
- return (num >= (maxValue/(long)Math.Pow(10, zeroes-1)));
- }
+ return (num >= (maxValue / (long)Math.Pow(10, zeroes - 1)));
+ }
}
//
@@ -151,41 +163,50 @@ namespace System.Globalization {
//
// Actions: TimeSpanTokenizer.GetNextToken() returns the next token in the input string.
//
- struct TimeSpanTokenizer {
+ private struct TimeSpanTokenizer
+ {
private int m_pos;
private String m_value;
- internal void Init(String input) {
+ internal void Init(String input)
+ {
Init(input, 0);
}
- internal void Init(String input, int startPosition) {
+ internal void Init(String input, int startPosition)
+ {
m_pos = startPosition;
m_value = input;
}
// used by the parsing routines that operate on standard-formats
- internal TimeSpanToken GetNextToken() {
+ internal TimeSpanToken GetNextToken()
+ {
Debug.Assert(m_pos > -1);
TimeSpanToken tok = new TimeSpanToken();
char ch = CurrentChar;
- if (ch == (char)0) {
+ if (ch == (char)0)
+ {
tok.ttt = TTT.End;
return tok;
}
- if (ch >= '0' && ch <= '9') {
+ if (ch >= '0' && ch <= '9')
+ {
tok.ttt = TTT.Num;
tok.num = 0;
tok.zeroes = 0;
- do {
- if ((tok.num & 0xF0000000) != 0) {
+ do
+ {
+ if ((tok.num & 0xF0000000) != 0)
+ {
tok.ttt = TTT.NumOverflow;
return tok;
}
tok.num = tok.num * 10 + ch - '0';
if (tok.num == 0) tok.zeroes++;
- if (tok.num < 0) {
+ if (tok.num < 0)
+ {
tok.ttt = TTT.NumOverflow;
return tok;
}
@@ -193,12 +214,14 @@ namespace System.Globalization {
} while (ch >= '0' && ch <= '9');
return tok;
}
- else {
+ else
+ {
tok.ttt = TTT.Sep;
int startIndex = m_pos;
int length = 0;
- while (ch != (char)0 && (ch < '0' || '9' < ch)) {
+ while (ch != (char)0 && (ch < '0' || '9' < ch))
+ {
ch = NextChar;
length++;
}
@@ -207,53 +230,70 @@ namespace System.Globalization {
}
}
- internal Boolean EOL {
- get {
- return m_pos >= (m_value.Length-1);
+ internal Boolean EOL
+ {
+ get
+ {
+ return m_pos >= (m_value.Length - 1);
}
}
// BackOne, NextChar, CurrentChar - used by ParseExact (ParseByFormat) to operate
// on custom-formats where exact character-by-character control is allowed
- internal void BackOne() {
+ internal void BackOne()
+ {
if (m_pos > 0) --m_pos;
}
- internal char NextChar {
- get {
+ internal char NextChar
+ {
+ get
+ {
m_pos++;
return CurrentChar;
}
}
- internal char CurrentChar {
- get {
- if (m_pos > -1 && m_pos < m_value.Length) {
+ internal char CurrentChar
+ {
+ get
+ {
+ if (m_pos > -1 && m_pos < m_value.Length)
+ {
return m_value[m_pos];
}
- else {
- return (char) 0;
+ else
+ {
+ return (char)0;
}
}
}
}
-
+
// This stores intermediary parsing state for the standard formats
- struct TimeSpanRawInfo {
- internal TimeSpanFormat.FormatLiterals PositiveInvariant {
- get {
+ private struct TimeSpanRawInfo
+ {
+ internal TimeSpanFormat.FormatLiterals PositiveInvariant
+ {
+ get
+ {
return TimeSpanFormat.PositiveInvariantFormatLiterals;
}
}
- internal TimeSpanFormat.FormatLiterals NegativeInvariant {
- get {
+ internal TimeSpanFormat.FormatLiterals NegativeInvariant
+ {
+ get
+ {
return TimeSpanFormat.NegativeInvariantFormatLiterals;
}
}
- internal TimeSpanFormat.FormatLiterals PositiveLocalized {
- get {
- if (!m_posLocInit) {
+ internal TimeSpanFormat.FormatLiterals PositiveLocalized
+ {
+ get
+ {
+ if (!m_posLocInit)
+ {
m_posLoc = new TimeSpanFormat.FormatLiterals();
m_posLoc.Init(m_fullPosPattern, false);
m_posLocInit = true;
@@ -261,99 +301,110 @@ namespace System.Globalization {
return m_posLoc;
}
}
- internal TimeSpanFormat.FormatLiterals NegativeLocalized {
- get {
- if (!m_negLocInit) {
+ internal TimeSpanFormat.FormatLiterals NegativeLocalized
+ {
+ get
+ {
+ if (!m_negLocInit)
+ {
m_negLoc = new TimeSpanFormat.FormatLiterals();
- m_negLoc.Init(m_fullNegPattern, false);
- m_negLocInit = true;
+ m_negLoc.Init(m_fullNegPattern, false);
+ m_negLocInit = true;
}
return m_negLoc;
}
}
- internal Boolean FullAppCompatMatch(TimeSpanFormat.FormatLiterals pattern) {
- return SepCount == 5
- && NumCount == 4
- && pattern.Start == literals[0]
- && pattern.DayHourSep == literals[1]
- && pattern.HourMinuteSep == literals[2]
- && pattern.AppCompatLiteral == literals[3]
- && pattern.End == literals[4];
+ internal Boolean FullAppCompatMatch(TimeSpanFormat.FormatLiterals pattern)
+ {
+ return SepCount == 5
+ && NumCount == 4
+ && pattern.Start == literals[0]
+ && pattern.DayHourSep == literals[1]
+ && pattern.HourMinuteSep == literals[2]
+ && pattern.AppCompatLiteral == literals[3]
+ && pattern.End == literals[4];
}
- internal Boolean PartialAppCompatMatch(TimeSpanFormat.FormatLiterals pattern) {
- return SepCount == 4
- && NumCount == 3
- && pattern.Start == literals[0]
- && pattern.HourMinuteSep == literals[1]
- && pattern.AppCompatLiteral == literals[2]
- && pattern.End == literals[3];
+ internal Boolean PartialAppCompatMatch(TimeSpanFormat.FormatLiterals pattern)
+ {
+ return SepCount == 4
+ && NumCount == 3
+ && pattern.Start == literals[0]
+ && pattern.HourMinuteSep == literals[1]
+ && pattern.AppCompatLiteral == literals[2]
+ && pattern.End == literals[3];
}
// DHMSF (all values matched)
- internal Boolean FullMatch(TimeSpanFormat.FormatLiterals pattern) {
- return SepCount == MaxLiteralTokens
- && NumCount == MaxNumericTokens
- && pattern.Start == literals[0]
- && pattern.DayHourSep == literals[1]
- && pattern.HourMinuteSep == literals[2]
- && pattern.MinuteSecondSep == literals[3]
+ internal Boolean FullMatch(TimeSpanFormat.FormatLiterals pattern)
+ {
+ return SepCount == MaxLiteralTokens
+ && NumCount == MaxNumericTokens
+ && pattern.Start == literals[0]
+ && pattern.DayHourSep == literals[1]
+ && pattern.HourMinuteSep == literals[2]
+ && pattern.MinuteSecondSep == literals[3]
&& pattern.SecondFractionSep == literals[4]
- && pattern.End == literals[5];
+ && pattern.End == literals[5];
}
// D (no hours, minutes, seconds, or fractions)
- internal Boolean FullDMatch(TimeSpanFormat.FormatLiterals pattern) {
- return SepCount == 2
- && NumCount == 1
- && pattern.Start == literals[0]
- && pattern.End == literals[1];
+ internal Boolean FullDMatch(TimeSpanFormat.FormatLiterals pattern)
+ {
+ return SepCount == 2
+ && NumCount == 1
+ && pattern.Start == literals[0]
+ && pattern.End == literals[1];
}
// HM (no days, seconds, or fractions)
- internal Boolean FullHMMatch(TimeSpanFormat.FormatLiterals pattern) {
- return SepCount == 3
- && NumCount == 2
- && pattern.Start == literals[0]
- && pattern.HourMinuteSep == literals[1]
- && pattern.End == literals[2];
+ internal Boolean FullHMMatch(TimeSpanFormat.FormatLiterals pattern)
+ {
+ return SepCount == 3
+ && NumCount == 2
+ && pattern.Start == literals[0]
+ && pattern.HourMinuteSep == literals[1]
+ && pattern.End == literals[2];
}
// DHM (no seconds or fraction)
- internal Boolean FullDHMMatch(TimeSpanFormat.FormatLiterals pattern) {
- return SepCount == 4
- && NumCount == 3
- && pattern.Start == literals[0]
- && pattern.DayHourSep == literals[1]
- && pattern.HourMinuteSep == literals[2]
- && pattern.End == literals[3];
-
+ internal Boolean FullDHMMatch(TimeSpanFormat.FormatLiterals pattern)
+ {
+ return SepCount == 4
+ && NumCount == 3
+ && pattern.Start == literals[0]
+ && pattern.DayHourSep == literals[1]
+ && pattern.HourMinuteSep == literals[2]
+ && pattern.End == literals[3];
}
// HMS (no days or fraction)
- internal Boolean FullHMSMatch(TimeSpanFormat.FormatLiterals pattern) {
- return SepCount == 4
- && NumCount == 3
- && pattern.Start == literals[0]
- && pattern.HourMinuteSep == literals[1]
- && pattern.MinuteSecondSep == literals[2]
- && pattern.End == literals[3];
+ internal Boolean FullHMSMatch(TimeSpanFormat.FormatLiterals pattern)
+ {
+ return SepCount == 4
+ && NumCount == 3
+ && pattern.Start == literals[0]
+ && pattern.HourMinuteSep == literals[1]
+ && pattern.MinuteSecondSep == literals[2]
+ && pattern.End == literals[3];
}
// DHMS (no fraction)
- internal Boolean FullDHMSMatch(TimeSpanFormat.FormatLiterals pattern) {
- return SepCount == 5
- && NumCount == 4
- && pattern.Start == literals[0]
- && pattern.DayHourSep == literals[1]
- && pattern.HourMinuteSep == literals[2]
- && pattern.MinuteSecondSep == literals[3]
- && pattern.End == literals[4];
+ internal Boolean FullDHMSMatch(TimeSpanFormat.FormatLiterals pattern)
+ {
+ return SepCount == 5
+ && NumCount == 4
+ && pattern.Start == literals[0]
+ && pattern.DayHourSep == literals[1]
+ && pattern.HourMinuteSep == literals[2]
+ && pattern.MinuteSecondSep == literals[3]
+ && pattern.End == literals[4];
}
// HMSF (no days)
- internal Boolean FullHMSFMatch(TimeSpanFormat.FormatLiterals pattern) {
- return SepCount == 5
- && NumCount == 4
- && pattern.Start == literals[0]
- && pattern.HourMinuteSep == literals[1]
- && pattern.MinuteSecondSep == literals[2]
+ internal Boolean FullHMSFMatch(TimeSpanFormat.FormatLiterals pattern)
+ {
+ return SepCount == 5
+ && NumCount == 4
+ && pattern.Start == literals[0]
+ && pattern.HourMinuteSep == literals[1]
+ && pattern.MinuteSecondSep == literals[2]
&& pattern.SecondFractionSep == literals[3]
- && pattern.End == literals[4];
+ && pattern.End == literals[4];
}
internal TTT lastSeenTTT;
@@ -374,7 +425,8 @@ namespace System.Globalization {
private const int MaxLiteralTokens = 6;
private const int MaxNumericTokens = 5;
- internal void Init(DateTimeFormatInfo dtfi) {
+ internal void Init(DateTimeFormatInfo dtfi)
+ {
Debug.Assert(dtfi != null);
lastSeenTTT = TTT.None;
@@ -383,7 +435,7 @@ namespace System.Globalization {
NumCount = 0;
literals = new String[MaxLiteralTokens];
- numbers = new TimeSpanToken[MaxNumericTokens];
+ numbers = new TimeSpanToken[MaxNumericTokens];
m_fullPosPattern = dtfi.FullTimeSpanPositivePattern;
m_fullNegPattern = dtfi.FullTimeSpanNegativePattern;
@@ -391,23 +443,28 @@ namespace System.Globalization {
m_negLocInit = false;
}
- internal Boolean ProcessToken(ref TimeSpanToken tok, ref TimeSpanResult result) {
- if (tok.ttt == TTT.NumOverflow) {
+ internal Boolean ProcessToken(ref TimeSpanToken tok, ref TimeSpanResult result)
+ {
+ if (tok.ttt == TTT.NumOverflow)
+ {
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge", null);
return false;
}
- if (tok.ttt != TTT.Sep && tok.ttt != TTT.Num) {
+ if (tok.ttt != TTT.Sep && tok.ttt != TTT.Num)
+ {
// Some unknown token or a repeat token type in the input
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan", null);
return false;
}
- switch (tok.ttt) {
+ switch (tok.ttt)
+ {
case TTT.Sep:
if (!AddSep(tok.sep, ref result)) return false;
break;
case TTT.Num:
- if (tokenCount == 0) {
+ if (tokenCount == 0)
+ {
if (!AddSep(String.Empty, ref result)) return false;
}
if (!AddNum(tok, ref result)) return false;
@@ -421,8 +478,10 @@ namespace System.Globalization {
return true;
}
- private bool AddSep(String sep, ref TimeSpanResult result) {
- if (SepCount >= MaxLiteralTokens || tokenCount >= MaxTokens) {
+ private bool AddSep(String sep, ref TimeSpanResult result)
+ {
+ if (SepCount >= MaxLiteralTokens || tokenCount >= MaxTokens)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan", null);
return false;
}
@@ -430,19 +489,22 @@ namespace System.Globalization {
tokenCount++;
return true;
}
- private bool AddNum(TimeSpanToken num, ref TimeSpanResult result) {
- if (NumCount >= MaxNumericTokens || tokenCount >= MaxTokens) {
+ private bool AddNum(TimeSpanToken num, ref TimeSpanResult result)
+ {
+ if (NumCount >= MaxNumericTokens || tokenCount >= MaxTokens)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan", null);
return false;
}
- numbers[NumCount++] = num;
+ numbers[NumCount++] = num;
tokenCount++;
return true;
}
}
// This will store the result of the parsing. And it will eventually be used to construct a TimeSpan instance.
- struct TimeSpanResult {
+ private struct TimeSpanResult
+ {
internal TimeSpan parsedTimeSpan;
internal TimeSpanThrowStyle throwStyle;
@@ -451,60 +513,70 @@ namespace System.Globalization {
internal object m_failureMessageFormatArgument;
internal string m_failureArgumentName;
- internal void Init(TimeSpanThrowStyle canThrow) {
+ internal void Init(TimeSpanThrowStyle canThrow)
+ {
parsedTimeSpan = default(TimeSpan);
- throwStyle = canThrow;
+ throwStyle = canThrow;
}
- internal void SetFailure(ParseFailureKind failure, string failureMessageID) {
+ internal void SetFailure(ParseFailureKind failure, string failureMessageID)
+ {
SetFailure(failure, failureMessageID, null, null);
}
- internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument) {
+ internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument)
+ {
SetFailure(failure, failureMessageID, failureMessageFormatArgument, null);
}
internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument,
- string failureArgumentName) {
+ string failureArgumentName)
+ {
m_failure = failure;
m_failureMessageID = failureMessageID;
m_failureMessageFormatArgument = failureMessageFormatArgument;
m_failureArgumentName = failureArgumentName;
- if (throwStyle != TimeSpanThrowStyle.None) {
+ if (throwStyle != TimeSpanThrowStyle.None)
+ {
throw GetTimeSpanParseException();
}
}
- internal Exception GetTimeSpanParseException() {
- switch (m_failure) {
- case ParseFailureKind.ArgumentNull:
- return new ArgumentNullException(m_failureArgumentName, Environment.GetResourceString(m_failureMessageID));
+ internal Exception GetTimeSpanParseException()
+ {
+ switch (m_failure)
+ {
+ case ParseFailureKind.ArgumentNull:
+ return new ArgumentNullException(m_failureArgumentName, SR.GetResourceString(m_failureMessageID));
- case ParseFailureKind.FormatWithParameter:
- return new FormatException(Environment.GetResourceString(m_failureMessageID, m_failureMessageFormatArgument));
+ case ParseFailureKind.FormatWithParameter:
+ return new FormatException(SR.Format(SR.GetResourceString(m_failureMessageID), m_failureMessageFormatArgument));
- case ParseFailureKind.Format:
- return new FormatException(Environment.GetResourceString(m_failureMessageID));
+ case ParseFailureKind.Format:
+ return new FormatException(SR.GetResourceString(m_failureMessageID));
- case ParseFailureKind.Overflow:
- return new OverflowException(Environment.GetResourceString(m_failureMessageID));
+ case ParseFailureKind.Overflow:
+ return new OverflowException(SR.GetResourceString(m_failureMessageID));
- default:
- Debug.Assert(false, "Unknown TimeSpanParseFailure: " + m_failure);
- return new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ default:
+ Debug.Assert(false, "Unknown TimeSpanParseFailure: " + m_failure);
+ return new FormatException(SR.Format_InvalidString);
}
}
}
- static bool TryTimeToTicks(bool positive, TimeSpanToken days, TimeSpanToken hours, TimeSpanToken minutes, TimeSpanToken seconds, TimeSpanToken fraction, out long result) {
+ private static bool TryTimeToTicks(bool positive, TimeSpanToken days, TimeSpanToken hours, TimeSpanToken minutes, TimeSpanToken seconds, TimeSpanToken fraction, out long result)
+ {
if (days.IsInvalidNumber(maxDays, unlimitedDigits)
|| hours.IsInvalidNumber(maxHours, unlimitedDigits)
|| minutes.IsInvalidNumber(maxMinutes, unlimitedDigits)
|| seconds.IsInvalidNumber(maxSeconds, unlimitedDigits)
- || fraction.IsInvalidNumber(maxFraction, maxFractionDigits)) {
+ || fraction.IsInvalidNumber(maxFraction, maxFractionDigits))
+ {
result = 0;
return false;
}
Int64 ticks = ((Int64)days.num * 3600 * 24 + (Int64)hours.num * 3600 + (Int64)minutes.num * 60 + seconds.num) * 1000;
- if (ticks > TimeSpan.MaxMilliSeconds || ticks < TimeSpan.MinMilliSeconds) {
+ if (ticks > TimeSpan.MaxMilliSeconds || ticks < TimeSpan.MinMilliSeconds)
+ {
result = 0;
return false;
}
@@ -518,18 +590,22 @@ namespace System.Globalization {
// ".01" => (1,1) => 100,000 ticks
// ".001" => (2,1) => 10,000 ticks
long f = fraction.num;
- if (f != 0) {
+ if (f != 0)
+ {
long lowerLimit = TimeSpan.TicksPerTenthSecond;
- if (fraction.zeroes > 0) {
+ if (fraction.zeroes > 0)
+ {
long divisor = (long)Math.Pow(10, fraction.zeroes);
lowerLimit = lowerLimit / divisor;
}
- while (f < lowerLimit) {
+ while (f < lowerLimit)
+ {
f *= 10;
}
}
result = ((long)ticks * TimeSpan.TicksPerMillisecond) + f;
- if (positive && result < 0) {
+ if (positive && result < 0)
+ {
result = 0;
return false;
}
@@ -544,74 +620,92 @@ namespace System.Globalization {
//
// Actions: Main methods called from TimeSpan.Parse
#region ParseMethods
- internal static TimeSpan Parse(String input, IFormatProvider formatProvider) {
+ internal static TimeSpan Parse(String input, IFormatProvider formatProvider)
+ {
TimeSpanResult parseResult = new TimeSpanResult();
parseResult.Init(TimeSpanThrowStyle.All);
- if (TryParseTimeSpan(input, TimeSpanStandardStyles.Any, formatProvider, ref parseResult)) {
+ if (TryParseTimeSpan(input, TimeSpanStandardStyles.Any, formatProvider, ref parseResult))
+ {
return parseResult.parsedTimeSpan;
}
- else {
+ else
+ {
throw parseResult.GetTimeSpanParseException();
}
}
- internal static Boolean TryParse(String input, IFormatProvider formatProvider, out TimeSpan result) {
+ internal static Boolean TryParse(String input, IFormatProvider formatProvider, out TimeSpan result)
+ {
TimeSpanResult parseResult = new TimeSpanResult();
parseResult.Init(TimeSpanThrowStyle.None);
- if (TryParseTimeSpan(input, TimeSpanStandardStyles.Any, formatProvider, ref parseResult)) {
+ if (TryParseTimeSpan(input, TimeSpanStandardStyles.Any, formatProvider, ref parseResult))
+ {
result = parseResult.parsedTimeSpan;
return true;
}
- else {
+ else
+ {
result = default(TimeSpan);
return false;
}
}
- internal static TimeSpan ParseExact(String input, String format, IFormatProvider formatProvider, TimeSpanStyles styles) {
+ internal static TimeSpan ParseExact(String input, String format, IFormatProvider formatProvider, TimeSpanStyles styles)
+ {
TimeSpanResult parseResult = new TimeSpanResult();
parseResult.Init(TimeSpanThrowStyle.All);
- if (TryParseExactTimeSpan(input, format, formatProvider, styles, ref parseResult)) {
+ if (TryParseExactTimeSpan(input, format, formatProvider, styles, ref parseResult))
+ {
return parseResult.parsedTimeSpan;
}
- else {
+ else
+ {
throw parseResult.GetTimeSpanParseException();
}
}
- internal static Boolean TryParseExact(String input, String format, IFormatProvider formatProvider, TimeSpanStyles styles, out TimeSpan result) {
+ internal static Boolean TryParseExact(String input, String format, IFormatProvider formatProvider, TimeSpanStyles styles, out TimeSpan result)
+ {
TimeSpanResult parseResult = new TimeSpanResult();
parseResult.Init(TimeSpanThrowStyle.None);
- if (TryParseExactTimeSpan(input, format, formatProvider, styles, ref parseResult)) {
+ if (TryParseExactTimeSpan(input, format, formatProvider, styles, ref parseResult))
+ {
result = parseResult.parsedTimeSpan;
return true;
}
- else {
+ else
+ {
result = default(TimeSpan);
return false;
}
}
- internal static TimeSpan ParseExactMultiple(String input, String[] formats, IFormatProvider formatProvider, TimeSpanStyles styles) {
+ internal static TimeSpan ParseExactMultiple(String input, String[] formats, IFormatProvider formatProvider, TimeSpanStyles styles)
+ {
TimeSpanResult parseResult = new TimeSpanResult();
parseResult.Init(TimeSpanThrowStyle.All);
- if (TryParseExactMultipleTimeSpan(input, formats, formatProvider, styles, ref parseResult)) {
+ if (TryParseExactMultipleTimeSpan(input, formats, formatProvider, styles, ref parseResult))
+ {
return parseResult.parsedTimeSpan;
}
- else {
+ else
+ {
throw parseResult.GetTimeSpanParseException();
}
}
- internal static Boolean TryParseExactMultiple(String input, String[] formats, IFormatProvider formatProvider, TimeSpanStyles styles, out TimeSpan result) {
+ internal static Boolean TryParseExactMultiple(String input, String[] formats, IFormatProvider formatProvider, TimeSpanStyles styles, out TimeSpan result)
+ {
TimeSpanResult parseResult = new TimeSpanResult();
parseResult.Init(TimeSpanThrowStyle.None);
- if (TryParseExactMultipleTimeSpan(input, formats, formatProvider, styles, ref parseResult)) {
+ if (TryParseExactMultipleTimeSpan(input, formats, formatProvider, styles, ref parseResult))
+ {
result = parseResult.parsedTimeSpan;
return true;
}
- else {
+ else
+ {
result = default(TimeSpan);
return false;
}
@@ -626,14 +720,17 @@ namespace System.Globalization {
//
// Actions: Common private Parse method called by both Parse and TryParse
//
- private static Boolean TryParseTimeSpan(String input, TimeSpanStandardStyles style, IFormatProvider formatProvider, ref TimeSpanResult result) {
- if (input == null) {
+ private static Boolean TryParseTimeSpan(String input, TimeSpanStandardStyles style, IFormatProvider formatProvider, ref TimeSpanResult result)
+ {
+ if (input == null)
+ {
result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(input));
return false;
}
input = input.Trim();
- if (input == String.Empty) {
+ if (input == String.Empty)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
}
@@ -648,19 +745,23 @@ namespace System.Globalization {
/* The following loop will break out when we reach the end of the str or
* when we can determine that the input is invalid. */
- while (tok.ttt != TTT.End) {
- if (!raw.ProcessToken(ref tok, ref result)) {
+ while (tok.ttt != TTT.End)
+ {
+ if (!raw.ProcessToken(ref tok, ref result))
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
}
tok = tokenizer.GetNextToken();
}
- if (!tokenizer.EOL) {
+ if (!tokenizer.EOL)
+ {
// embedded nulls in the input string
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
}
- if (!ProcessTerminalState(ref raw, style, ref result)) {
+ if (!ProcessTerminalState(ref raw, style, ref result))
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
}
@@ -685,18 +786,22 @@ namespace System.Globalization {
// 3 numbers => h:m:s | d.h:m | h:m:.f
// 4 numbers => h:m:s.f | d.h:m:s | d.h:m:.f
// 5 numbers => d.h:m:s.f
- private static Boolean ProcessTerminalState(ref TimeSpanRawInfo raw, TimeSpanStandardStyles style, ref TimeSpanResult result) {
- if (raw.lastSeenTTT == TTT.Num) {
+ private static Boolean ProcessTerminalState(ref TimeSpanRawInfo raw, TimeSpanStandardStyles style, ref TimeSpanResult result)
+ {
+ if (raw.lastSeenTTT == TTT.Num)
+ {
TimeSpanToken tok = new TimeSpanToken();
tok.ttt = TTT.Sep;
tok.sep = String.Empty;
- if (!raw.ProcessToken(ref tok, ref result)) {
+ if (!raw.ProcessToken(ref tok, ref result))
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
}
}
- switch (raw.NumCount) {
+ switch (raw.NumCount)
+ {
case 1:
return ProcessTerminal_D(ref raw, style, ref result);
case 2:
@@ -711,7 +816,7 @@ namespace System.Globalization {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
}
- }
+ }
//
// ProcessTerminal_DHMSF
@@ -719,8 +824,10 @@ namespace System.Globalization {
// Actions: Validate the 5-number "Days.Hours:Minutes:Seconds.Fraction" terminal case.
// Sets result.parsedTimeSpan on success.
//
- private static Boolean ProcessTerminal_DHMSF(ref TimeSpanRawInfo raw, TimeSpanStandardStyles style, ref TimeSpanResult result) {
- if (raw.SepCount != 6 || raw.NumCount != 5) {
+ private static Boolean ProcessTerminal_DHMSF(ref TimeSpanRawInfo raw, TimeSpanStandardStyles style, ref TimeSpanResult result)
+ {
+ if (raw.SepCount != 6 || raw.NumCount != 5)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
}
@@ -731,42 +838,52 @@ namespace System.Globalization {
bool positive = false;
bool match = false;
- if (inv) {
- if (raw.FullMatch(raw.PositiveInvariant)) {
+ if (inv)
+ {
+ if (raw.FullMatch(raw.PositiveInvariant))
+ {
match = true;
- positive = true;
+ positive = true;
}
- if (!match && raw.FullMatch(raw.NegativeInvariant)) {
+ if (!match && raw.FullMatch(raw.NegativeInvariant))
+ {
match = true;
- positive = false;
+ positive = false;
}
}
- if (loc) {
- if (!match && raw.FullMatch(raw.PositiveLocalized)) {
+ if (loc)
+ {
+ if (!match && raw.FullMatch(raw.PositiveLocalized))
+ {
match = true;
- positive = true;
+ positive = true;
}
- if (!match && raw.FullMatch(raw.NegativeLocalized)) {
+ if (!match && raw.FullMatch(raw.NegativeLocalized))
+ {
match = true;
- positive = false;
+ positive = false;
}
}
long ticks;
- if (match) {
- if (!TryTimeToTicks(positive, raw.numbers[0], raw.numbers[1], raw.numbers[2], raw.numbers[3], raw.numbers[4], out ticks)) {
+ if (match)
+ {
+ if (!TryTimeToTicks(positive, raw.numbers[0], raw.numbers[1], raw.numbers[2], raw.numbers[3], raw.numbers[4], out ticks))
+ {
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
return false;
- }
- if (!positive) {
+ }
+ if (!positive)
+ {
ticks = -ticks;
- if (ticks > 0) {
+ if (ticks > 0)
+ {
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
return false;
}
}
result.parsedTimeSpan._ticks = ticks;
return true;
- }
+ }
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
@@ -778,8 +895,10 @@ namespace System.Globalization {
// Actions: Validate the ambiguous 4-number "Hours:Minutes:Seconds.Fraction", "Days.Hours:Minutes:Seconds", or "Days.Hours:Minutes:.Fraction" terminal case.
// Sets result.parsedTimeSpan on success.
//
- private static Boolean ProcessTerminal_HMS_F_D(ref TimeSpanRawInfo raw, TimeSpanStandardStyles style, ref TimeSpanResult result) {
- if (raw.SepCount != 5 || raw.NumCount != 4 || (style & TimeSpanStandardStyles.RequireFull) != 0) {
+ private static Boolean ProcessTerminal_HMS_F_D(ref TimeSpanRawInfo raw, TimeSpanStandardStyles style, ref TimeSpanResult result)
+ {
+ if (raw.SepCount != 5 || raw.NumCount != 4 || (style & TimeSpanStandardStyles.RequireFull) != 0)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
}
@@ -792,75 +911,92 @@ namespace System.Globalization {
bool match = false;
bool overflow = false;
- if (inv) {
- if (raw.FullHMSFMatch(raw.PositiveInvariant)) {
- positive = true;
+ if (inv)
+ {
+ if (raw.FullHMSFMatch(raw.PositiveInvariant))
+ {
+ positive = true;
match = TryTimeToTicks(positive, zero, raw.numbers[0], raw.numbers[1], raw.numbers[2], raw.numbers[3], out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullDHMSMatch(raw.PositiveInvariant)) {
- positive = true;
+ if (!match && raw.FullDHMSMatch(raw.PositiveInvariant))
+ {
+ positive = true;
match = TryTimeToTicks(positive, raw.numbers[0], raw.numbers[1], raw.numbers[2], raw.numbers[3], zero, out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullAppCompatMatch(raw.PositiveInvariant)) {
+ if (!match && raw.FullAppCompatMatch(raw.PositiveInvariant))
+ {
positive = true;
match = TryTimeToTicks(positive, raw.numbers[0], raw.numbers[1], raw.numbers[2], zero, raw.numbers[3], out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullHMSFMatch(raw.NegativeInvariant)) {
- positive = false;
+ if (!match && raw.FullHMSFMatch(raw.NegativeInvariant))
+ {
+ positive = false;
match = TryTimeToTicks(positive, zero, raw.numbers[0], raw.numbers[1], raw.numbers[2], raw.numbers[3], out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullDHMSMatch(raw.NegativeInvariant)) {
- positive = false;
+ if (!match && raw.FullDHMSMatch(raw.NegativeInvariant))
+ {
+ positive = false;
match = TryTimeToTicks(positive, raw.numbers[0], raw.numbers[1], raw.numbers[2], raw.numbers[3], zero, out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullAppCompatMatch(raw.NegativeInvariant)) {
+ if (!match && raw.FullAppCompatMatch(raw.NegativeInvariant))
+ {
positive = false;
match = TryTimeToTicks(positive, raw.numbers[0], raw.numbers[1], raw.numbers[2], zero, raw.numbers[3], out ticks);
overflow = overflow || !match;
}
}
- if (loc) {
- if (!match && raw.FullHMSFMatch(raw.PositiveLocalized)) {
- positive = true;
+ if (loc)
+ {
+ if (!match && raw.FullHMSFMatch(raw.PositiveLocalized))
+ {
+ positive = true;
match = TryTimeToTicks(positive, zero, raw.numbers[0], raw.numbers[1], raw.numbers[2], raw.numbers[3], out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullDHMSMatch(raw.PositiveLocalized)) {
- positive = true;
+ if (!match && raw.FullDHMSMatch(raw.PositiveLocalized))
+ {
+ positive = true;
match = TryTimeToTicks(positive, raw.numbers[0], raw.numbers[1], raw.numbers[2], raw.numbers[3], zero, out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullAppCompatMatch(raw.PositiveLocalized)) {
+ if (!match && raw.FullAppCompatMatch(raw.PositiveLocalized))
+ {
positive = true;
match = TryTimeToTicks(positive, raw.numbers[0], raw.numbers[1], raw.numbers[2], zero, raw.numbers[3], out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullHMSFMatch(raw.NegativeLocalized)) {
- positive = false;
+ if (!match && raw.FullHMSFMatch(raw.NegativeLocalized))
+ {
+ positive = false;
match = TryTimeToTicks(positive, zero, raw.numbers[0], raw.numbers[1], raw.numbers[2], raw.numbers[3], out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullDHMSMatch(raw.NegativeLocalized)) {
- positive = false;
+ if (!match && raw.FullDHMSMatch(raw.NegativeLocalized))
+ {
+ positive = false;
match = TryTimeToTicks(positive, raw.numbers[0], raw.numbers[1], raw.numbers[2], raw.numbers[3], zero, out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullAppCompatMatch(raw.NegativeLocalized)) {
+ if (!match && raw.FullAppCompatMatch(raw.NegativeLocalized))
+ {
positive = false;
match = TryTimeToTicks(positive, raw.numbers[0], raw.numbers[1], raw.numbers[2], zero, raw.numbers[3], out ticks);
overflow = overflow || !match;
}
}
-
- if (match) {
- if (!positive) {
+
+ if (match)
+ {
+ if (!positive)
+ {
ticks = -ticks;
- if (ticks > 0) {
+ if (ticks > 0)
+ {
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
return false;
}
@@ -869,12 +1005,14 @@ namespace System.Globalization {
return true;
}
- if (overflow) {
+ if (overflow)
+ {
// we found at least one literal pattern match but the numbers just didn't fit
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
return false;
}
- else {
+ else
+ {
// we couldn't find a thing
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
@@ -886,8 +1024,10 @@ namespace System.Globalization {
//
// Actions: Validate the ambiguous 3-number "Hours:Minutes:Seconds", "Days.Hours:Minutes", or "Hours:Minutes:.Fraction" terminal case
//
- private static Boolean ProcessTerminal_HM_S_D(ref TimeSpanRawInfo raw, TimeSpanStandardStyles style, ref TimeSpanResult result) {
- if (raw.SepCount != 4 || raw.NumCount != 3 || (style & TimeSpanStandardStyles.RequireFull) != 0) {
+ private static Boolean ProcessTerminal_HM_S_D(ref TimeSpanRawInfo raw, TimeSpanStandardStyles style, ref TimeSpanResult result)
+ {
+ if (raw.SepCount != 4 || raw.NumCount != 3 || (style & TimeSpanStandardStyles.RequireFull) != 0)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
}
@@ -901,89 +1041,108 @@ namespace System.Globalization {
long ticks = 0;
- if (inv) {
- if (raw.FullHMSMatch(raw.PositiveInvariant)) {
- positive = true;
+ if (inv)
+ {
+ if (raw.FullHMSMatch(raw.PositiveInvariant))
+ {
+ positive = true;
match = TryTimeToTicks(positive, zero, raw.numbers[0], raw.numbers[1], raw.numbers[2], zero, out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullDHMMatch(raw.PositiveInvariant)) {
+ if (!match && raw.FullDHMMatch(raw.PositiveInvariant))
+ {
positive = true;
match = TryTimeToTicks(positive, raw.numbers[0], raw.numbers[1], raw.numbers[2], zero, zero, out ticks);
overflow = overflow || !match;
- }
- if (!match && raw.PartialAppCompatMatch(raw.PositiveInvariant)) {
+ }
+ if (!match && raw.PartialAppCompatMatch(raw.PositiveInvariant))
+ {
positive = true;
match = TryTimeToTicks(positive, zero, raw.numbers[0], raw.numbers[1], zero, raw.numbers[2], out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullHMSMatch(raw.NegativeInvariant)) {
+ if (!match && raw.FullHMSMatch(raw.NegativeInvariant))
+ {
positive = false;
match = TryTimeToTicks(positive, zero, raw.numbers[0], raw.numbers[1], raw.numbers[2], zero, out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullDHMMatch(raw.NegativeInvariant)) {
+ if (!match && raw.FullDHMMatch(raw.NegativeInvariant))
+ {
positive = false;
match = TryTimeToTicks(positive, raw.numbers[0], raw.numbers[1], raw.numbers[2], zero, zero, out ticks);
overflow = overflow || !match;
- }
- if (!match && raw.PartialAppCompatMatch(raw.NegativeInvariant)) {
+ }
+ if (!match && raw.PartialAppCompatMatch(raw.NegativeInvariant))
+ {
positive = false;
match = TryTimeToTicks(positive, zero, raw.numbers[0], raw.numbers[1], zero, raw.numbers[2], out ticks);
overflow = overflow || !match;
}
}
- if (loc) {
- if (!match && raw.FullHMSMatch(raw.PositiveLocalized)) {
- positive = true;
+ if (loc)
+ {
+ if (!match && raw.FullHMSMatch(raw.PositiveLocalized))
+ {
+ positive = true;
match = TryTimeToTicks(positive, zero, raw.numbers[0], raw.numbers[1], raw.numbers[2], zero, out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullDHMMatch(raw.PositiveLocalized)) {
+ if (!match && raw.FullDHMMatch(raw.PositiveLocalized))
+ {
positive = true;
match = TryTimeToTicks(positive, raw.numbers[0], raw.numbers[1], raw.numbers[2], zero, zero, out ticks);
overflow = overflow || !match;
}
- if (!match && raw.PartialAppCompatMatch(raw.PositiveLocalized)) {
+ if (!match && raw.PartialAppCompatMatch(raw.PositiveLocalized))
+ {
positive = true;
match = TryTimeToTicks(positive, zero, raw.numbers[0], raw.numbers[1], zero, raw.numbers[2], out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullHMSMatch(raw.NegativeLocalized)) {
+ if (!match && raw.FullHMSMatch(raw.NegativeLocalized))
+ {
positive = false;
match = TryTimeToTicks(positive, zero, raw.numbers[0], raw.numbers[1], raw.numbers[2], zero, out ticks);
overflow = overflow || !match;
}
- if (!match && raw.FullDHMMatch(raw.NegativeLocalized)) {
+ if (!match && raw.FullDHMMatch(raw.NegativeLocalized))
+ {
positive = false;
match = TryTimeToTicks(positive, raw.numbers[0], raw.numbers[1], raw.numbers[2], zero, zero, out ticks);
overflow = overflow || !match;
- }
- if (!match && raw.PartialAppCompatMatch(raw.NegativeLocalized)) {
+ }
+ if (!match && raw.PartialAppCompatMatch(raw.NegativeLocalized))
+ {
positive = false;
match = TryTimeToTicks(positive, zero, raw.numbers[0], raw.numbers[1], zero, raw.numbers[2], out ticks);
overflow = overflow || !match;
}
}
- if (match) {
- if (!positive) {
+ if (match)
+ {
+ if (!positive)
+ {
ticks = -ticks;
- if (ticks > 0) {
+ if (ticks > 0)
+ {
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
return false;
}
}
result.parsedTimeSpan._ticks = ticks;
return true;
- }
+ }
- if (overflow) {
+ if (overflow)
+ {
// we found at least one literal pattern match but the numbers just didn't fit
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
return false;
}
- else {
+ else
+ {
// we couldn't find a thing
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
@@ -995,8 +1154,10 @@ namespace System.Globalization {
//
// Actions: Validate the 2-number "Hours:Minutes" terminal case
//
- private static Boolean ProcessTerminal_HM(ref TimeSpanRawInfo raw, TimeSpanStandardStyles style, ref TimeSpanResult result) {
- if (raw.SepCount != 3 || raw.NumCount != 2 || (style & TimeSpanStandardStyles.RequireFull) != 0) {
+ private static Boolean ProcessTerminal_HM(ref TimeSpanRawInfo raw, TimeSpanStandardStyles style, ref TimeSpanResult result)
+ {
+ if (raw.SepCount != 3 || raw.NumCount != 2 || (style & TimeSpanStandardStyles.RequireFull) != 0)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
}
@@ -1007,43 +1168,53 @@ namespace System.Globalization {
bool positive = false;
bool match = false;
- if (inv) {
- if (raw.FullHMMatch(raw.PositiveInvariant)) {
+ if (inv)
+ {
+ if (raw.FullHMMatch(raw.PositiveInvariant))
+ {
match = true;
- positive = true;
+ positive = true;
}
- if (!match && raw.FullHMMatch(raw.NegativeInvariant)) {
+ if (!match && raw.FullHMMatch(raw.NegativeInvariant))
+ {
match = true;
positive = false;
}
}
- if (loc) {
- if (!match && raw.FullHMMatch(raw.PositiveLocalized)) {
+ if (loc)
+ {
+ if (!match && raw.FullHMMatch(raw.PositiveLocalized))
+ {
match = true;
- positive = true;
+ positive = true;
}
- if (!match && raw.FullHMMatch(raw.NegativeLocalized)) {
+ if (!match && raw.FullHMMatch(raw.NegativeLocalized))
+ {
match = true;
positive = false;
}
}
long ticks = 0;
- if (match) {
- if (!TryTimeToTicks(positive, zero, raw.numbers[0], raw.numbers[1], zero, zero, out ticks)) {
+ if (match)
+ {
+ if (!TryTimeToTicks(positive, zero, raw.numbers[0], raw.numbers[1], zero, zero, out ticks))
+ {
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
return false;
}
- if (!positive) {
+ if (!positive)
+ {
ticks = -ticks;
- if (ticks > 0) {
+ if (ticks > 0)
+ {
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
return false;
}
}
result.parsedTimeSpan._ticks = ticks;
return true;
- }
+ }
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
@@ -1055,8 +1226,10 @@ namespace System.Globalization {
//
// Actions: Validate the 1-number "Days" terminal case
//
- private static Boolean ProcessTerminal_D(ref TimeSpanRawInfo raw, TimeSpanStandardStyles style, ref TimeSpanResult result) {
- if (raw.SepCount != 2 || raw.NumCount != 1 || (style & TimeSpanStandardStyles.RequireFull) != 0) {
+ private static Boolean ProcessTerminal_D(ref TimeSpanRawInfo raw, TimeSpanStandardStyles style, ref TimeSpanResult result)
+ {
+ if (raw.SepCount != 2 || raw.NumCount != 1 || (style & TimeSpanStandardStyles.RequireFull) != 0)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
}
@@ -1067,43 +1240,53 @@ namespace System.Globalization {
bool positive = false;
bool match = false;
- if (inv) {
- if (raw.FullDMatch(raw.PositiveInvariant)) {
+ if (inv)
+ {
+ if (raw.FullDMatch(raw.PositiveInvariant))
+ {
match = true;
- positive = true;
+ positive = true;
}
- if (!match && raw.FullDMatch(raw.NegativeInvariant)) {
+ if (!match && raw.FullDMatch(raw.NegativeInvariant))
+ {
match = true;
positive = false;
}
}
- if (loc) {
- if (!match && raw.FullDMatch(raw.PositiveLocalized)) {
+ if (loc)
+ {
+ if (!match && raw.FullDMatch(raw.PositiveLocalized))
+ {
match = true;
- positive = true;
+ positive = true;
}
- if (!match && raw.FullDMatch(raw.NegativeLocalized)) {
+ if (!match && raw.FullDMatch(raw.NegativeLocalized))
+ {
match = true;
positive = false;
}
}
long ticks = 0;
- if (match) {
- if (!TryTimeToTicks(positive, raw.numbers[0], zero, zero, zero, zero, out ticks)) {
+ if (match)
+ {
+ if (!TryTimeToTicks(positive, raw.numbers[0], zero, zero, zero, zero, out ticks))
+ {
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
return false;
}
- if (!positive) {
+ if (!positive)
+ {
ticks = -ticks;
- if (ticks > 0) {
+ if (ticks > 0)
+ {
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
return false;
}
}
result.parsedTimeSpan._ticks = ticks;
return true;
- }
+ }
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
@@ -1116,40 +1299,49 @@ namespace System.Globalization {
//
// Actions: Common private ParseExact method called by both ParseExact and TryParseExact
//
- private static Boolean TryParseExactTimeSpan(String input, String format, IFormatProvider formatProvider, TimeSpanStyles styles, ref TimeSpanResult result) {
- if (input == null) {
+ private static Boolean TryParseExactTimeSpan(String input, String format, IFormatProvider formatProvider, TimeSpanStyles styles, ref TimeSpanResult result)
+ {
+ if (input == null)
+ {
result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(input));
return false;
}
- if (format == null) {
+ if (format == null)
+ {
result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(format));
return false;
}
- if (format.Length == 0) {
+ if (format.Length == 0)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier");
return false;
}
- if (format.Length == 1) {
+ if (format.Length == 1)
+ {
TimeSpanStandardStyles style = TimeSpanStandardStyles.None;
- if (format[0] == 'c' || format[0] == 't' || format[0] == 'T') {
+ if (format[0] == 'c' || format[0] == 't' || format[0] == 'T')
+ {
// fast path for legacy style TimeSpan formats.
return TryParseTimeSpanConstant(input, ref result);
}
- else if (format[0] == 'g') {
+ else if (format[0] == 'g')
+ {
style = TimeSpanStandardStyles.Localized;
}
- else if (format[0] == 'G') {
+ else if (format[0] == 'G')
+ {
style = TimeSpanStandardStyles.Localized | TimeSpanStandardStyles.RequireFull;
}
- else {
+ else
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier");
return false;
}
return TryParseTimeSpan(input, style, formatProvider, ref result);
}
-
+
return TryParseByFormat(input, format, styles, ref result);
}
@@ -1158,7 +1350,8 @@ namespace System.Globalization {
//
// Actions: Parse the TimeSpan instance using the specified format. Used by TryParseExactTimeSpan.
//
- private static Boolean TryParseByFormat(String input, String format, TimeSpanStyles styles, ref TimeSpanResult result) {
+ private static Boolean TryParseByFormat(String input, String format, TimeSpanStyles styles, ref TimeSpanResult result)
+ {
Debug.Assert(input != null, "input != null");
Debug.Assert(format != null, "format != null");
@@ -1179,13 +1372,16 @@ namespace System.Globalization {
TimeSpanTokenizer tokenizer = new TimeSpanTokenizer();
tokenizer.Init(input, -1);
- while (i < format.Length) {
+ while (i < format.Length)
+ {
char ch = format[i];
int nextFormatChar;
- switch (ch) {
+ switch (ch)
+ {
case 'h':
tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch);
- if (tokenLen > 2 || seenHH || !ParseExactDigits(ref tokenizer, tokenLen, out hh)) {
+ if (tokenLen > 2 || seenHH || !ParseExactDigits(ref tokenizer, tokenLen, out hh))
+ {
result.SetFailure(ParseFailureKind.Format, "Format_InvalidString");
return false;
}
@@ -1193,7 +1389,8 @@ namespace System.Globalization {
break;
case 'm':
tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch);
- if (tokenLen > 2 || seenMM || !ParseExactDigits(ref tokenizer, tokenLen, out mm)) {
+ if (tokenLen > 2 || seenMM || !ParseExactDigits(ref tokenizer, tokenLen, out mm))
+ {
result.SetFailure(ParseFailureKind.Format, "Format_InvalidString");
return false;
}
@@ -1201,7 +1398,8 @@ namespace System.Globalization {
break;
case 's':
tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch);
- if (tokenLen > 2 || seenSS || !ParseExactDigits(ref tokenizer, tokenLen, out ss)) {
+ if (tokenLen > 2 || seenSS || !ParseExactDigits(ref tokenizer, tokenLen, out ss))
+ {
result.SetFailure(ParseFailureKind.Format, "Format_InvalidString");
return false;
}
@@ -1209,7 +1407,8 @@ namespace System.Globalization {
break;
case 'f':
tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch);
- if (tokenLen > DateTimeFormat.MaxSecondsFractionDigits || seenFF || !ParseExactDigits(ref tokenizer, tokenLen, tokenLen, out leadingZeroes, out ff)) {
+ if (tokenLen > DateTimeFormat.MaxSecondsFractionDigits || seenFF || !ParseExactDigits(ref tokenizer, tokenLen, tokenLen, out leadingZeroes, out ff))
+ {
result.SetFailure(ParseFailureKind.Format, "Format_InvalidString");
return false;
}
@@ -1217,7 +1416,8 @@ namespace System.Globalization {
break;
case 'F':
tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch);
- if (tokenLen > DateTimeFormat.MaxSecondsFractionDigits || seenFF) {
+ if (tokenLen > DateTimeFormat.MaxSecondsFractionDigits || seenFF)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_InvalidString");
return false;
}
@@ -1227,7 +1427,8 @@ namespace System.Globalization {
case 'd':
tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch);
int tmp = 0;
- if (tokenLen > 8 || seenDD || !ParseExactDigits(ref tokenizer, (tokenLen<2) ? 1 : tokenLen, (tokenLen<2) ? 8 : tokenLen, out tmp, out dd)) {
+ if (tokenLen > 8 || seenDD || !ParseExactDigits(ref tokenizer, (tokenLen < 2) ? 1 : tokenLen, (tokenLen < 2) ? 8 : tokenLen, out tmp, out dd))
+ {
result.SetFailure(ParseFailureKind.Format, "Format_InvalidString");
return false;
}
@@ -1236,11 +1437,13 @@ namespace System.Globalization {
case '\'':
case '\"':
StringBuilder enquotedString = new StringBuilder();
- if (!DateTimeParse.TryParseQuoteString(format, i, enquotedString, out tokenLen)) {
+ if (!DateTimeParse.TryParseQuoteString(format, i, enquotedString, out tokenLen))
+ {
result.SetFailure(ParseFailureKind.FormatWithParameter, "Format_BadQuote", ch);
return false;
}
- if (!ParseExactLiteral(ref tokenizer, enquotedString)) {
+ if (!ParseExactLiteral(ref tokenizer, enquotedString))
+ {
result.SetFailure(ParseFailureKind.Format, "Format_InvalidString");
return false;
}
@@ -1252,11 +1455,13 @@ namespace System.Globalization {
nextFormatChar = DateTimeFormat.ParseNextChar(format, i);
// nextFormatChar will be -1 if we already reach the end of the format string.
// Besides, we will not allow "%%" appear in the pattern.
- if (nextFormatChar >= 0 && nextFormatChar != (int)'%') {
+ if (nextFormatChar >= 0 && nextFormatChar != (int)'%')
+ {
tokenLen = 1; // skip the '%' and process the format character
break;
}
- else {
+ else
+ {
// This means that '%' is at the end of the format string or
// "%%" appears in the format string.
result.SetFailure(ParseFailureKind.Format, "Format_InvalidString");
@@ -1267,10 +1472,12 @@ namespace System.Globalization {
// For example, "\d" will insert the character 'd' into the string.
//
nextFormatChar = DateTimeFormat.ParseNextChar(format, i);
- if (nextFormatChar >= 0 && tokenizer.NextChar == (char)nextFormatChar) {
+ if (nextFormatChar >= 0 && tokenizer.NextChar == (char)nextFormatChar)
+ {
tokenLen = 2;
- }
- else {
+ }
+ else
+ {
// This means that '\' is at the end of the format string or the literal match failed.
result.SetFailure(ParseFailureKind.Format, "Format_InvalidString");
return false;
@@ -1284,12 +1491,13 @@ namespace System.Globalization {
}
- if (!tokenizer.EOL) {
+ if (!tokenizer.EOL)
+ {
// the custom format didn't consume the entire input
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
}
-
+
long ticks = 0;
bool positive = (styles & TimeSpanStyles.AssumeNegative) == 0;
if (TryTimeToTicks(positive, new TimeSpanToken(dd),
@@ -1297,33 +1505,38 @@ namespace System.Globalization {
new TimeSpanToken(mm),
new TimeSpanToken(ss),
new TimeSpanToken(leadingZeroes, ff),
- out ticks)) {
+ out ticks))
+ {
if (!positive) ticks = -ticks;
result.parsedTimeSpan._ticks = ticks;
return true;
}
- else {
+ else
+ {
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
return false;
-
}
}
- private static Boolean ParseExactDigits(ref TimeSpanTokenizer tokenizer, int minDigitLength, out int result) {
+ private static Boolean ParseExactDigits(ref TimeSpanTokenizer tokenizer, int minDigitLength, out int result)
+ {
result = 0;
int zeroes = 0;
int maxDigitLength = (minDigitLength == 1) ? 2 : minDigitLength;
return ParseExactDigits(ref tokenizer, minDigitLength, maxDigitLength, out zeroes, out result);
}
- private static Boolean ParseExactDigits(ref TimeSpanTokenizer tokenizer, int minDigitLength, int maxDigitLength, out int zeroes, out int result) {
+ private static Boolean ParseExactDigits(ref TimeSpanTokenizer tokenizer, int minDigitLength, int maxDigitLength, out int zeroes, out int result)
+ {
result = 0;
zeroes = 0;
int tokenLength = 0;
- while (tokenLength < maxDigitLength) {
+ while (tokenLength < maxDigitLength)
+ {
char ch = tokenizer.NextChar;
- if (ch < '0' || ch > '9') {
- tokenizer.BackOne();
+ if (ch < '0' || ch > '9')
+ {
+ tokenizer.BackOne();
break;
}
result = result * 10 + (ch - '0');
@@ -1332,8 +1545,10 @@ namespace System.Globalization {
}
return (tokenLength >= minDigitLength);
}
- private static Boolean ParseExactLiteral(ref TimeSpanTokenizer tokenizer, StringBuilder enquotedString) {
- for (int i = 0; i < enquotedString.Length; i++) {
+ private static Boolean ParseExactLiteral(ref TimeSpanTokenizer tokenizer, StringBuilder enquotedString)
+ {
+ for (int i = 0; i < enquotedString.Length; i++)
+ {
if (enquotedString[i] != tokenizer.NextChar)
return false;
}
@@ -1348,35 +1563,42 @@ namespace System.Globalization {
// Actions: Parses the "c" (constant) format. This code is 100% identical to the non-globalized v1.0-v3.5 TimeSpan.Parse() routine
// and exists for performance/appcompat with legacy callers who cannot move onto the globalized Parse overloads.
//
- private static Boolean TryParseTimeSpanConstant(String input, ref TimeSpanResult result) {
+ private static Boolean TryParseTimeSpanConstant(String input, ref TimeSpanResult result)
+ {
return (new StringParser().TryParse(input, ref result));
}
- private struct StringParser {
+ private struct StringParser
+ {
private String str;
private char ch;
private int pos;
private int len;
- internal void NextChar() {
+ internal void NextChar()
+ {
if (pos < len) pos++;
- ch = pos < len? str[pos]: (char) 0;
+ ch = pos < len ? str[pos] : (char)0;
}
- internal char NextNonDigit() {
+ internal char NextNonDigit()
+ {
int i = pos;
- while (i < len) {
+ while (i < len)
+ {
char ch = str[i];
if (ch < '0' || ch > '9') return ch;
i++;
}
- return (char) 0;
+ return (char)0;
}
-
- internal bool TryParse(String input, ref TimeSpanResult result) {
+
+ internal bool TryParse(String input, ref TimeSpanResult result)
+ {
result.parsedTimeSpan._ticks = 0;
- if (input == null) {
+ if (input == null)
+ {
result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(input));
return false;
}
@@ -1386,109 +1608,136 @@ namespace System.Globalization {
NextChar();
SkipBlanks();
bool negative = false;
- if (ch == '-') {
+ if (ch == '-')
+ {
negative = true;
NextChar();
}
long time;
- if (NextNonDigit() == ':') {
- if (!ParseTime(out time, ref result)) {
+ if (NextNonDigit() == ':')
+ {
+ if (!ParseTime(out time, ref result))
+ {
return false;
};
}
- else {
+ else
+ {
int days;
- if (!ParseInt((int)(0x7FFFFFFFFFFFFFFFL / TimeSpan.TicksPerDay), out days, ref result)) {
+ if (!ParseInt((int)(0x7FFFFFFFFFFFFFFFL / TimeSpan.TicksPerDay), out days, ref result))
+ {
return false;
}
time = days * TimeSpan.TicksPerDay;
- if (ch == '.') {
+ if (ch == '.')
+ {
NextChar();
long remainingTime;
- if (!ParseTime(out remainingTime, ref result)) {
+ if (!ParseTime(out remainingTime, ref result))
+ {
return false;
};
time += remainingTime;
}
}
- if (negative) {
+ if (negative)
+ {
time = -time;
// Allow -0 as well
- if (time > 0) {
+ if (time > 0)
+ {
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
- return false;
+ return false;
}
}
- else {
- if (time < 0) {
+ else
+ {
+ if (time < 0)
+ {
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
- return false;
+ return false;
}
}
SkipBlanks();
- if (pos < len) {
+ if (pos < len)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
- return false;
+ return false;
}
result.parsedTimeSpan._ticks = time;
return true;
}
- internal bool ParseInt(int max, out int i, ref TimeSpanResult result) {
+ internal bool ParseInt(int max, out int i, ref TimeSpanResult result)
+ {
i = 0;
int p = pos;
- while (ch >= '0' && ch <= '9') {
- if ((i & 0xF0000000) != 0) {
+ while (ch >= '0' && ch <= '9')
+ {
+ if ((i & 0xF0000000) != 0)
+ {
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
return false;
}
i = i * 10 + ch - '0';
- if (i < 0) {
+ if (i < 0)
+ {
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
return false;
}
NextChar();
}
- if (p == pos) {
+ if (p == pos)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
}
- if (i > max) {
+ if (i > max)
+ {
result.SetFailure(ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge");
return false;
}
return true;
}
- internal bool ParseTime(out long time, ref TimeSpanResult result) {
+ internal bool ParseTime(out long time, ref TimeSpanResult result)
+ {
time = 0;
int unit;
- if (!ParseInt(23, out unit, ref result)) {
+ if (!ParseInt(23, out unit, ref result))
+ {
return false;
}
time = unit * TimeSpan.TicksPerHour;
- if (ch != ':') {
+ if (ch != ':')
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
- return false;
+ return false;
}
- NextChar();
- if (!ParseInt(59, out unit, ref result)) {
+ NextChar();
+ if (!ParseInt(59, out unit, ref result))
+ {
return false;
- }
+ }
time += unit * TimeSpan.TicksPerMinute;
- if (ch == ':') {
+ if (ch == ':')
+ {
NextChar();
// allow seconds with the leading zero
- if (ch != '.') {
- if (!ParseInt(59, out unit, ref result)) {
+ if (ch != '.')
+ {
+ if (!ParseInt(59, out unit, ref result))
+ {
return false;
- }
+ }
time += unit * TimeSpan.TicksPerSecond;
}
- if (ch == '.') {
+ if (ch == '.')
+ {
NextChar();
int f = (int)TimeSpan.TicksPerSecond;
- while (f > 1 && ch >= '0' && ch <= '9') {
+ while (f > 1 && ch >= '0' && ch <= '9')
+ {
f /= 10;
time += (ch - '0') * f;
NextChar();
@@ -1498,10 +1747,11 @@ namespace System.Globalization {
return true;
}
- internal void SkipBlanks() {
+ internal void SkipBlanks()
+ {
while (ch == ' ' || ch == '\t') NextChar();
}
- }
+ }
#endregion
#region TryParseExactMultipleTimeSpan
@@ -1510,22 +1760,27 @@ namespace System.Globalization {
//
// Actions: Common private ParseExactMultiple method called by both ParseExactMultiple and TryParseExactMultiple
//
- private static Boolean TryParseExactMultipleTimeSpan(String input, String[] formats, IFormatProvider formatProvider, TimeSpanStyles styles, ref TimeSpanResult result) {
- if (input == null) {
+ private static Boolean TryParseExactMultipleTimeSpan(String input, String[] formats, IFormatProvider formatProvider, TimeSpanStyles styles, ref TimeSpanResult result)
+ {
+ if (input == null)
+ {
result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(input));
return false;
}
- if (formats == null) {
+ if (formats == null)
+ {
result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(formats));
return false;
}
- if (input.Length == 0) {
+ if (input.Length == 0)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan");
return false;
}
- if (formats.Length == 0) {
+ if (formats.Length == 0)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier");
return false;
}
@@ -1534,8 +1789,10 @@ namespace System.Globalization {
// Do a loop through the provided formats and see if we can parse succesfully in
// one of the formats.
//
- for (int i = 0; i < formats.Length; i++) {
- if (formats[i] == null || formats[i].Length == 0) {
+ for (int i = 0; i < formats.Length; i++)
+ {
+ if (formats[i] == null || formats[i].Length == 0)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_BadFormatSpecifier");
return false;
}
@@ -1544,7 +1801,8 @@ namespace System.Globalization {
TimeSpanResult innerResult = new TimeSpanResult();
innerResult.Init(TimeSpanThrowStyle.None);
- if(TryParseExactTimeSpan(input, formats[i], formatProvider, styles, ref innerResult)) {
+ if (TryParseExactTimeSpan(input, formats[i], formatProvider, styles, ref innerResult))
+ {
result.parsedTimeSpan = innerResult.parsedTimeSpan;
return true;
}
diff --git a/src/mscorlib/src/System/Globalization/TimeSpanStyles.cs b/src/mscorlib/src/System/Globalization/TimeSpanStyles.cs
deleted file mode 100644
index 7ba5327324..0000000000
--- a/src/mscorlib/src/System/Globalization/TimeSpanStyles.cs
+++ /dev/null
@@ -1,12 +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.
-
-namespace System.Globalization {
-
- [Flags]
- public enum TimeSpanStyles {
- None = 0x00000000,
- AssumeNegative = 0x00000001,
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/UmAlQuraCalendar.cs b/src/mscorlib/src/System/Globalization/UmAlQuraCalendar.cs
deleted file mode 100644
index 06e7c7d75a..0000000000
--- a/src/mscorlib/src/System/Globalization/UmAlQuraCalendar.cs
+++ /dev/null
@@ -1,850 +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.
-
-namespace System.Globalization {
- using System;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about UmAlQuraCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
- /*
- ** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 1900/04/30 2077/11/17
- ** UmAlQura 1318/01/01 1500/12/30
- */
-
- [Serializable]
- public class UmAlQuraCalendar : Calendar {
-
- internal const int MinCalendarYear = 1318;
- internal const int MaxCalendarYear = 1500;
-
- internal struct DateMapping
- {
- internal DateMapping(int MonthsLengthFlags, int GYear, int GMonth, int GDay)
- {
- HijriMonthsLengthFlags = MonthsLengthFlags;
- GregorianDate = new DateTime(GYear, GMonth, GDay);
- }
- internal int HijriMonthsLengthFlags;
- internal DateTime GregorianDate;
- }
-
- static readonly DateMapping [] HijriYearInfo = InitDateMapping();
-
- static DateMapping[] InitDateMapping()
- {
- short[] rawData = new short[] {
-//These data is taken from Tables/Excel/UmAlQura.xls please make sure that the two places are in sync
-/* DaysPerM GY GM GD D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12
-1318*/0x02EA, 1900, 4, 30,/* 0 1 0 1 0 1 1 1 0 1 0 0 4/30/1900
-1319*/0x06E9, 1901, 4, 19,/* 1 0 0 1 0 1 1 1 0 1 1 0 4/19/1901
-1320*/0x0ED2, 1902, 4, 9,/* 0 1 0 0 1 0 1 1 0 1 1 1 4/9/1902
-1321*/0x0EA4, 1903, 3, 30,/* 0 0 1 0 0 1 0 1 0 1 1 1 3/30/1903
-1322*/0x0D4A, 1904, 3, 18,/* 0 1 0 1 0 0 1 0 1 0 1 1 3/18/1904
-1323*/0x0A96, 1905, 3, 7,/* 0 1 1 0 1 0 0 1 0 1 0 1 3/7/1905
-1324*/0x0536, 1906, 2, 24,/* 0 1 1 0 1 1 0 0 1 0 1 0 2/24/1906
-1325*/0x0AB5, 1907, 2, 13,/* 1 0 1 0 1 1 0 1 0 1 0 1 2/13/1907
-1326*/0x0DAA, 1908, 2, 3,/* 0 1 0 1 0 1 0 1 1 0 1 1 2/3/1908
-1327*/0x0BA4, 1909, 1, 23,/* 0 0 1 0 0 1 0 1 1 1 0 1 1/23/1909
-1328*/0x0B49, 1910, 1, 12,/* 1 0 0 1 0 0 1 0 1 1 0 1 1/12/1910
-1329*/0x0A93, 1911, 1, 1,/* 1 1 0 0 1 0 0 1 0 1 0 1 1/1/1911
-1330*/0x052B, 1911, 12, 21,/* 1 1 0 1 0 1 0 0 1 0 1 0 12/21/1911
-1331*/0x0A57, 1912, 12, 9,/* 1 1 1 0 1 0 1 0 0 1 0 1 12/9/1912
-1332*/0x04B6, 1913, 11, 29,/* 0 1 1 0 1 1 0 1 0 0 1 0 11/29/1913
-1333*/0x0AB5, 1914, 11, 18,/* 1 0 1 0 1 1 0 1 0 1 0 1 11/18/1914
-1334*/0x05AA, 1915, 11, 8,/* 0 1 0 1 0 1 0 1 1 0 1 0 11/8/1915
-1335*/0x0D55, 1916, 10, 27,/* 1 0 1 0 1 0 1 0 1 0 1 1 10/27/1916
-1336*/0x0D2A, 1917, 10, 17,/* 0 1 0 1 0 1 0 0 1 0 1 1 10/17/1917
-1337*/0x0A56, 1918, 10, 6,/* 0 1 1 0 1 0 1 0 0 1 0 1 10/6/1918
-1338*/0x04AE, 1919, 9, 25,/* 0 1 1 1 0 1 0 1 0 0 1 0 9/25/1919
-1339*/0x095D, 1920, 9, 13,/* 1 0 1 1 1 0 1 0 1 0 0 1 9/13/1920
-1340*/0x02EC, 1921, 9, 3,/* 0 0 1 1 0 1 1 1 0 1 0 0 9/3/1921
-1341*/0x06D5, 1922, 8, 23,/* 1 0 1 0 1 0 1 1 0 1 1 0 8/23/1922
-1342*/0x06AA, 1923, 8, 13,/* 0 1 0 1 0 1 0 1 0 1 1 0 8/13/1923
-1343*/0x0555, 1924, 8, 1,/* 1 0 1 0 1 0 1 0 1 0 1 0 8/1/1924
-1344*/0x04AB, 1925, 7, 21,/* 1 1 0 1 0 1 0 1 0 0 1 0 7/21/1925
-1345*/0x095B, 1926, 7, 10,/* 1 1 0 1 1 0 1 0 1 0 0 1 7/10/1926
-1346*/0x02BA, 1927, 6, 30,/* 0 1 0 1 1 1 0 1 0 1 0 0 6/30/1927
-1347*/0x0575, 1928, 6, 18,/* 1 0 1 0 1 1 1 0 1 0 1 0 6/18/1928
-1348*/0x0BB2, 1929, 6, 8,/* 0 1 0 0 1 1 0 1 1 1 0 1 6/8/1929
-1349*/0x0764, 1930, 5, 29,/* 0 0 1 0 0 1 1 0 1 1 1 0 5/29/1930
-1350*/0x0749, 1931, 5, 18,/* 1 0 0 1 0 0 1 0 1 1 1 0 5/18/1931
-1351*/0x0655, 1932, 5, 6,/* 1 0 1 0 1 0 1 0 0 1 1 0 5/6/1932
-1352*/0x02AB, 1933, 4, 25,/* 1 1 0 1 0 1 0 1 0 1 0 0 4/25/1933
-1353*/0x055B, 1934, 4, 14,/* 1 1 0 1 1 0 1 0 1 0 1 0 4/14/1934
-1354*/0x0ADA, 1935, 4, 4,/* 0 1 0 1 1 0 1 1 0 1 0 1 4/4/1935
-1355*/0x06D4, 1936, 3, 24,/* 0 0 1 0 1 0 1 1 0 1 1 0 3/24/1936
-1356*/0x0EC9, 1937, 3, 13,/* 1 0 0 1 0 0 1 1 0 1 1 1 3/13/1937
-1357*/0x0D92, 1938, 3, 3,/* 0 1 0 0 1 0 0 1 1 0 1 1 3/3/1938
-1358*/0x0D25, 1939, 2, 20,/* 1 0 1 0 0 1 0 0 1 0 1 1 2/20/1939
-1359*/0x0A4D, 1940, 2, 9,/* 1 0 1 1 0 0 1 0 0 1 0 1 2/9/1940
-1360*/0x02AD, 1941, 1, 28,/* 1 0 1 1 0 1 0 1 0 1 0 0 1/28/1941
-1361*/0x056D, 1942, 1, 17,/* 1 0 1 1 0 1 1 0 1 0 1 0 1/17/1942
-1362*/0x0B6A, 1943, 1, 7,/* 0 1 0 1 0 1 1 0 1 1 0 1 1/7/1943
-1363*/0x0B52, 1943, 12, 28,/* 0 1 0 0 1 0 1 0 1 1 0 1 12/28/1943
-1364*/0x0AA5, 1944, 12, 16,/* 1 0 1 0 0 1 0 1 0 1 0 1 12/16/1944
-1365*/0x0A4B, 1945, 12, 5,/* 1 1 0 1 0 0 1 0 0 1 0 1 12/5/1945
-1366*/0x0497, 1946, 11, 24,/* 1 1 1 0 1 0 0 1 0 0 1 0 11/24/1946
-1367*/0x0937, 1947, 11, 13,/* 1 1 1 0 1 1 0 0 1 0 0 1 11/13/1947
-1368*/0x02B6, 1948, 11, 2,/* 0 1 1 0 1 1 0 1 0 1 0 0 11/2/1948
-1369*/0x0575, 1949, 10, 22,/* 1 0 1 0 1 1 1 0 1 0 1 0 10/22/1949
-1370*/0x0D6A, 1950, 10, 12,/* 0 1 0 1 0 1 1 0 1 0 1 1 10/12/1950
-1371*/0x0D52, 1951, 10, 2,/* 0 1 0 0 1 0 1 0 1 0 1 1 10/2/1951
-1372*/0x0A96, 1952, 9, 20,/* 0 1 1 0 1 0 0 1 0 1 0 1 9/20/1952
-1373*/0x092D, 1953, 9, 9,/* 1 0 1 1 0 1 0 0 1 0 0 1 9/9/1953
-1374*/0x025D, 1954, 8, 29,/* 1 0 1 1 1 0 1 0 0 1 0 0 8/29/1954
-1375*/0x04DD, 1955, 8, 18,/* 1 0 1 1 1 0 1 1 0 0 1 0 8/18/1955
-1376*/0x0ADA, 1956, 8, 7,/* 0 1 0 1 1 0 1 1 0 1 0 1 8/7/1956
-1377*/0x05D4, 1957, 7, 28,/* 0 0 1 0 1 0 1 1 1 0 1 0 7/28/1957
-1378*/0x0DA9, 1958, 7, 17,/* 1 0 0 1 0 1 0 1 1 0 1 1 7/17/1958
-1379*/0x0D52, 1959, 7, 7,/* 0 1 0 0 1 0 1 0 1 0 1 1 7/7/1959
-1380*/0x0AAA, 1960, 6, 25,/* 0 1 0 1 0 1 0 1 0 1 0 1 6/25/1960
-1381*/0x04D6, 1961, 6, 14,/* 0 1 1 0 1 0 1 1 0 0 1 0 6/14/1961
-1382*/0x09B6, 1962, 6, 3,/* 0 1 1 0 1 1 0 1 1 0 0 1 6/3/1962
-1383*/0x0374, 1963, 5, 24,/* 0 0 1 0 1 1 1 0 1 1 0 0 5/24/1963
-1384*/0x0769, 1964, 5, 12,/* 1 0 0 1 0 1 1 0 1 1 1 0 5/12/1964
-1385*/0x0752, 1965, 5, 2,/* 0 1 0 0 1 0 1 0 1 1 1 0 5/2/1965
-1386*/0x06A5, 1966, 4, 21,/* 1 0 1 0 0 1 0 1 0 1 1 0 4/21/1966
-1387*/0x054B, 1967, 4, 10,/* 1 1 0 1 0 0 1 0 1 0 1 0 4/10/1967
-1388*/0x0AAB, 1968, 3, 29,/* 1 1 0 1 0 1 0 1 0 1 0 1 3/29/1968
-1389*/0x055A, 1969, 3, 19,/* 0 1 0 1 1 0 1 0 1 0 1 0 3/19/1969
-1390*/0x0AD5, 1970, 3, 8,/* 1 0 1 0 1 0 1 1 0 1 0 1 3/8/1970
-1391*/0x0DD2, 1971, 2, 26,/* 0 1 0 0 1 0 1 1 1 0 1 1 2/26/1971
-1392*/0x0DA4, 1972, 2, 16,/* 0 0 1 0 0 1 0 1 1 0 1 1 2/16/1972
-1393*/0x0D49, 1973, 2, 4,/* 1 0 0 1 0 0 1 0 1 0 1 1 2/4/1973
-1394*/0x0A95, 1974, 1, 24,/* 1 0 1 0 1 0 0 1 0 1 0 1 1/24/1974
-1395*/0x052D, 1975, 1, 13,/* 1 0 1 1 0 1 0 0 1 0 1 0 1/13/1975
-1396*/0x0A5D, 1976, 1, 2,/* 1 0 1 1 1 0 1 0 0 1 0 1 1/2/1976
-1397*/0x055A, 1976, 12, 22,/* 0 1 0 1 1 0 1 0 1 0 1 0 12/22/1976
-1398*/0x0AD5, 1977, 12, 11,/* 1 0 1 0 1 0 1 1 0 1 0 1 12/11/1977
-1399*/0x06AA, 1978, 12, 1,/* 0 1 0 1 0 1 0 1 0 1 1 0 12/1/1978
-1400*/0x0695, 1979, 11, 20,/* 1 0 1 0 1 0 0 1 0 1 1 0 11/20/1979
-1401*/0x052B, 1980, 11, 8,/* 1 1 0 1 0 1 0 0 1 0 1 0 11/8/1980
-1402*/0x0A57, 1981, 10, 28,/* 1 1 1 0 1 0 1 0 0 1 0 1 10/28/1981
-1403*/0x04AE, 1982, 10, 18,/* 0 1 1 1 0 1 0 1 0 0 1 0 10/18/1982
-1404*/0x0976, 1983, 10, 7,/* 0 1 1 0 1 1 1 0 1 0 0 1 10/7/1983
-1405*/0x056C, 1984, 9, 26,/* 0 0 1 1 0 1 1 0 1 0 1 0 9/26/1984
-1406*/0x0B55, 1985, 9, 15,/* 1 0 1 0 1 0 1 0 1 1 0 1 9/15/1985
-1407*/0x0AAA, 1986, 9, 5,/* 0 1 0 1 0 1 0 1 0 1 0 1 9/5/1986
-1408*/0x0A55, 1987, 8, 25,/* 1 0 1 0 1 0 1 0 0 1 0 1 8/25/1987
-1409*/0x04AD, 1988, 8, 13,/* 1 0 1 1 0 1 0 1 0 0 1 0 8/13/1988
-1410*/0x095D, 1989, 8, 2,/* 1 0 1 1 1 0 1 0 1 0 0 1 8/2/1989
-1411*/0x02DA, 1990, 7, 23,/* 0 1 0 1 1 0 1 1 0 1 0 0 7/23/1990
-1412*/0x05D9, 1991, 7, 12,/* 1 0 0 1 1 0 1 1 1 0 1 0 7/12/1991
-1413*/0x0DB2, 1992, 7, 1,/* 0 1 0 0 1 1 0 1 1 0 1 1 7/1/1992
-1414*/0x0BA4, 1993, 6, 21,/* 0 0 1 0 0 1 0 1 1 1 0 1 6/21/1993
-1415*/0x0B4A, 1994, 6, 10,/* 0 1 0 1 0 0 1 0 1 1 0 1 6/10/1994
-1416*/0x0A55, 1995, 5, 30,/* 1 0 1 0 1 0 1 0 0 1 0 1 5/30/1995
-1417*/0x02B5, 1996, 5, 18,/* 1 0 1 0 1 1 0 1 0 1 0 0 5/18/1996
-1418*/0x0575, 1997, 5, 7,/* 1 0 1 0 1 1 1 0 1 0 1 0 5/7/1997
-1419*/0x0B6A, 1998, 4, 27,/* 0 1 0 1 0 1 1 0 1 1 0 1 4/27/1998
-1420*/0x0BD2, 1999, 4, 17,/* 0 1 0 0 1 0 1 1 1 1 0 1 4/17/1999
-1421*/0x0BC4, 2000, 4, 6,/* 0 0 1 0 0 0 1 1 1 1 0 1 4/6/2000
-1422*/0x0B89, 2001, 3, 26,/* 1 0 0 1 0 0 0 1 1 1 0 1 3/26/2001
-1423*/0x0A95, 2002, 3, 15,/* 1 0 1 0 1 0 0 1 0 1 0 1 3/15/2002
-1424*/0x052D, 2003, 3, 4,/* 1 0 1 1 0 1 0 0 1 0 1 0 3/4/2003
-1425*/0x05AD, 2004, 2, 21,/* 1 0 1 1 0 1 0 1 1 0 1 0 2/21/2004
-1426*/0x0B6A, 2005, 2, 10,/* 0 1 0 1 0 1 1 0 1 1 0 1 2/10/2005
-1427*/0x06D4, 2006, 1, 31,/* 0 0 1 0 1 0 1 1 0 1 1 0 1/31/2006
-1428*/0x0DC9, 2007, 1, 20,/* 1 0 0 1 0 0 1 1 1 0 1 1 1/20/2007
-1429*/0x0D92, 2008, 1, 10,/* 0 1 0 0 1 0 0 1 1 0 1 1 1/10/2008
-1430*/0x0AA6, 2008, 12, 29,/* 0 1 1 0 0 1 0 1 0 1 0 1 12/29/2008
-1431*/0x0956, 2009, 12, 18,/* 0 1 1 0 1 0 1 0 1 0 0 1 12/18/2009
-1432*/0x02AE, 2010, 12, 7,/* 0 1 1 1 0 1 0 1 0 1 0 0 12/7/2010
-1433*/0x056D, 2011, 11, 26,/* 1 0 1 1 0 1 1 0 1 0 1 0 11/26/2011
-1434*/0x036A, 2012, 11, 15,/* 0 1 0 1 0 1 1 0 1 1 0 0 11/15/2012
-1435*/0x0B55, 2013, 11, 4,/* 1 0 1 0 1 0 1 0 1 1 0 1 11/4/2013
-1436*/0x0AAA, 2014, 10, 25,/* 0 1 0 1 0 1 0 1 0 1 0 1 10/25/2014
-1437*/0x094D, 2015, 10, 14,/* 1 0 1 1 0 0 1 0 1 0 0 1 10/14/2015
-1438*/0x049D, 2016, 10, 2,/* 1 0 1 1 1 0 0 1 0 0 1 0 10/2/2016
-1439*/0x095D, 2017, 9, 21,/* 1 0 1 1 1 0 1 0 1 0 0 1 9/21/2017
-1440*/0x02BA, 2018, 9, 11,/* 0 1 0 1 1 1 0 1 0 1 0 0 9/11/2018
-1441*/0x05B5, 2019, 8, 31,/* 1 0 1 0 1 1 0 1 1 0 1 0 8/31/2019
-1442*/0x05AA, 2020, 8, 20,/* 0 1 0 1 0 1 0 1 1 0 1 0 8/20/2020
-1443*/0x0D55, 2021, 8, 9,/* 1 0 1 0 1 0 1 0 1 0 1 1 8/9/2021
-1444*/0x0A9A, 2022, 7, 30,/* 0 1 0 1 1 0 0 1 0 1 0 1 7/30/2022
-1445*/0x092E, 2023, 7, 19,/* 0 1 1 1 0 1 0 0 1 0 0 1 7/19/2023
-1446*/0x026E, 2024, 7, 7,/* 0 1 1 1 0 1 1 0 0 1 0 0 7/7/2024
-1447*/0x055D, 2025, 6, 26,/* 1 0 1 1 1 0 1 0 1 0 1 0 6/26/2025
-1448*/0x0ADA, 2026, 6, 16,/* 0 1 0 1 1 0 1 1 0 1 0 1 6/16/2026
-1449*/0x06D4, 2027, 6, 6,/* 0 0 1 0 1 0 1 1 0 1 1 0 6/6/2027
-1450*/0x06A5, 2028, 5, 25,/* 1 0 1 0 0 1 0 1 0 1 1 0 5/25/2028
-1451*/0x054B, 2029, 5, 14,/* 1 1 0 1 0 0 1 0 1 0 1 0 5/14/2029
-1452*/0x0A97, 2030, 5, 3,/* 1 1 1 0 1 0 0 1 0 1 0 1 5/3/2030
-1453*/0x054E, 2031, 4, 23,/* 0 1 1 1 0 0 1 0 1 0 1 0 4/23/2031
-1454*/0x0AAE, 2032, 4, 11,/* 0 1 1 1 0 1 0 1 0 1 0 1 4/11/2032
-1455*/0x05AC, 2033, 4, 1,/* 0 0 1 1 0 1 0 1 1 0 1 0 4/1/2033
-1456*/0x0BA9, 2034, 3, 21,/* 1 0 0 1 0 1 0 1 1 1 0 1 3/21/2034
-1457*/0x0D92, 2035, 3, 11,/* 0 1 0 0 1 0 0 1 1 0 1 1 3/11/2035
-1458*/0x0B25, 2036, 2, 28,/* 1 0 1 0 0 1 0 0 1 1 0 1 2/28/2036
-1459*/0x064B, 2037, 2, 16,/* 1 1 0 1 0 0 1 0 0 1 1 0 2/16/2037
-1460*/0x0CAB, 2038, 2, 5,/* 1 1 0 1 0 1 0 1 0 0 1 1 2/5/2038
-1461*/0x055A, 2039, 1, 26,/* 0 1 0 1 1 0 1 0 1 0 1 0 1/26/2039
-1462*/0x0B55, 2040, 1, 15,/* 1 0 1 0 1 0 1 0 1 1 0 1 1/15/2040
-1463*/0x06D2, 2041, 1, 4,/* 0 1 0 0 1 0 1 1 0 1 1 0 1/4/2041
-1464*/0x0EA5, 2041, 12, 24,/* 1 0 1 0 0 1 0 1 0 1 1 1 12/24/2041
-1465*/0x0E4A, 2042, 12, 14,/* 0 1 0 1 0 0 1 0 0 1 1 1 12/14/2042
-1466*/0x0A95, 2043, 12, 3,/* 1 0 1 0 1 0 0 1 0 1 0 1 12/3/2043
-1467*/0x052D, 2044, 11, 21,/* 1 0 1 1 0 1 0 0 1 0 1 0 11/21/2044
-1468*/0x0AAD, 2045, 11, 10,/* 1 0 1 1 0 1 0 1 0 1 0 1 11/10/2045
-1469*/0x036C, 2046, 10, 31,/* 0 0 1 1 0 1 1 0 1 1 0 0 10/31/2046
-1470*/0x0759, 2047, 10, 20,/* 1 0 0 1 1 0 1 0 1 1 1 0 10/20/2047
-1471*/0x06D2, 2048, 10, 9,/* 0 1 0 0 1 0 1 1 0 1 1 0 10/9/2048
-1472*/0x0695, 2049, 9, 28,/* 1 0 1 0 1 0 0 1 0 1 1 0 9/28/2049
-1473*/0x052D, 2050, 9, 17,/* 1 0 1 1 0 1 0 0 1 0 1 0 9/17/2050
-1474*/0x0A5B, 2051, 9, 6,/* 1 1 0 1 1 0 1 0 0 1 0 1 9/6/2051
-1475*/0x04BA, 2052, 8, 26,/* 0 1 0 1 1 1 0 1 0 0 1 0 8/26/2052
-1476*/0x09BA, 2053, 8, 15,/* 0 1 0 1 1 1 0 1 1 0 0 1 8/15/2053
-1477*/0x03B4, 2054, 8, 5,/* 0 0 1 0 1 1 0 1 1 1 0 0 8/5/2054
-1478*/0x0B69, 2055, 7, 25,/* 1 0 0 1 0 1 1 0 1 1 0 1 7/25/2055
-1479*/0x0B52, 2056, 7, 14,/* 0 1 0 0 1 0 1 0 1 1 0 1 7/14/2056
-1480*/0x0AA6, 2057, 7, 3,/* 0 1 1 0 0 1 0 1 0 1 0 1 7/3/2057
-1481*/0x04B6, 2058, 6, 22,/* 0 1 1 0 1 1 0 1 0 0 1 0 6/22/2058
-1482*/0x096D, 2059, 6, 11,/* 1 0 1 1 0 1 1 0 1 0 0 1 6/11/2059
-1483*/0x02EC, 2060, 5, 31,/* 0 0 1 1 0 1 1 1 0 1 0 0 5/31/2060
-1484*/0x06D9, 2061, 5, 20,/* 1 0 0 1 1 0 1 1 0 1 1 0 5/20/2061
-1485*/0x0EB2, 2062, 5, 10,/* 0 1 0 0 1 1 0 1 0 1 1 1 5/10/2062
-1486*/0x0D54, 2063, 4, 30,/* 0 0 1 0 1 0 1 0 1 0 1 1 4/30/2063
-1487*/0x0D2A, 2064, 4, 18,/* 0 1 0 1 0 1 0 0 1 0 1 1 4/18/2064
-1488*/0x0A56, 2065, 4, 7,/* 0 1 1 0 1 0 1 0 0 1 0 1 4/7/2065
-1489*/0x04AE, 2066, 3, 27,/* 0 1 1 1 0 1 0 1 0 0 1 0 3/27/2066
-1490*/0x096D, 2067, 3, 16,/* 1 0 1 1 0 1 1 0 1 0 0 1 3/16/2067
-1491*/0x0D6A, 2068, 3, 5,/* 0 1 0 1 0 1 1 0 1 0 1 1 3/5/2068
-1492*/0x0B54, 2069, 2, 23,/* 0 0 1 0 1 0 1 0 1 1 0 1 2/23/2069
-1493*/0x0B29, 2070, 2, 12,/* 1 0 0 1 0 1 0 0 1 1 0 1 2/12/2070
-1494*/0x0A93, 2071, 2, 1,/* 1 1 0 0 1 0 0 1 0 1 0 1 2/1/2071
-1495*/0x052B, 2072, 1, 21,/* 1 1 0 1 0 1 0 0 1 0 1 0 1/21/2072
-1496*/0x0A57, 2073, 1, 9,/* 1 1 1 0 1 0 1 0 0 1 0 1 1/9/2073
-1497*/0x0536, 2073, 12, 30,/* 0 1 1 0 1 1 0 0 1 0 1 0 12/30/2073
-1498*/0x0AB5, 2074, 12, 19,/* 1 0 1 0 1 1 0 1 0 1 0 1 12/19/2074
-1499*/0x06AA, 2075, 12, 9,/* 0 1 0 1 0 1 0 1 0 1 1 0 12/9/2075
-1500*/0x0E93, 2076, 11, 27,/* 1 1 0 0 1 0 0 1 0 1 1 1 11/27/2076
-1501*/ 0, 2077, 11, 17,/* 0 0 0 0 0 0 0 0 0 0 0 0 11/17/2077
-
-*/ };
-
- // Direct inline initialization of DateMapping array would produce a lot of code bloat.
-
- // We take advantage of C# compiler compiles inline initialization of primitive type array into very compact code.
- // So we start with raw data stored in primitive type array, and initialize the DateMapping out of it
-
- DateMapping[] mapping = new DateMapping[rawData.Length / 4];
- for (int i = 0; i < mapping.Length; i++)
- mapping[i] = new DateMapping(rawData[i * 4], rawData[i * 4 + 1], rawData[i * 4 + 2], rawData[i * 4 + 3]);
- return mapping;
- }
-
- public const int UmAlQuraEra = 1;
-
- internal const int DateCycle = 30;
- internal const int DatePartYear = 0;
- internal const int DatePartDayOfYear = 1;
- internal const int DatePartMonth = 2;
- internal const int DatePartDay = 3;
-
- //internal static Calendar m_defaultInstance;
-
-
- // This is the minimal Gregorian date that we support in the UmAlQuraCalendar.
- internal static DateTime minDate = new DateTime(1900, 4, 30);
- internal static DateTime maxDate = new DateTime((new DateTime(2077, 11, 16, 23, 59, 59, 999)).Ticks + 9999);
-
- /*=================================GetDefaultInstance==========================
- **Action: Internal method to provide a default intance of UmAlQuraCalendar. Used by NLS+ implementation
- ** and other calendars.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
- /*
- internal static Calendar GetDefaultInstance() {
- if (m_defaultInstance == null) {
- m_defaultInstance = new UmAlQuraCalendar();
- }
- return (m_defaultInstance);
- }
- */
-
-
-
- public override DateTime MinSupportedDateTime
- {
- get
- {
- return (minDate);
- }
- }
-
-
- public override DateTime MaxSupportedDateTime
- {
- get
- {
- return (maxDate);
- }
- }
-
-
- // Return the type of the UmAlQura calendar.
- //
-
-
- public override CalendarAlgorithmType AlgorithmType {
- get {
- return CalendarAlgorithmType.LunarCalendar;
- }
- }
-
- // Construct an instance of UmAlQura calendar.
-
- public UmAlQuraCalendar() {
- }
-
- internal override int BaseCalendarID {
- get {
- return (CAL_HIJRI);
- }
- }
-
- internal override int ID {
- get {
- return (CAL_UMALQURA);
- }
- }
-
- protected override int DaysInYearBeforeMinSupportedYear
- {
- get
- {
- // HijriCalendar has same number of days as UmAlQuraCalendar for any given year
- // HijriCalendar says year 1317 has 355 days.
- return 355;
- }
- }
-
- /*==========================ConvertHijriToGregorian==========================
- ** Purpose: convert Hdate(year,month,day) to Gdate(year,month,day)
- ** Arguments:
- ** Input: Hijrah date: year:HijriYear, month:HijriMonth, day:HijriDay
- ** Output: Gregorian date: year:yg, month:mg, day:dg
- =========================ConvertHijriToGregorian============================*/
- static void ConvertHijriToGregorian(int HijriYear, int HijriMonth, int HijriDay, ref int yg, ref int mg, ref int dg)
- {
- Debug.Assert( (HijriYear >= MinCalendarYear) && (HijriYear <= MaxCalendarYear), "Hijri year is out of range.");
- Debug.Assert( HijriMonth >= 1, "Hijri month is out of range.");
- Debug.Assert( HijriDay >= 1, "Hijri day is out of range.");
- int index, b, nDays = HijriDay-1;
- DateTime dt;
-
-
- index = HijriYear - MinCalendarYear;
- dt = HijriYearInfo[index].GregorianDate;
-
-
- b = HijriYearInfo[index].HijriMonthsLengthFlags;
-
- for(int m = 1; m < HijriMonth; m++)
- {
- nDays += 29 + (b & 0x1);
- b = b >> 1;
- }
-
- dt = dt.AddDays(nDays);
- yg = dt.Year;
- mg = dt.Month;
- dg = dt.Day;
- }
-
- /*=================================GetAbsoluteDateUmAlQura==========================
- **Action: Gets the Absolute date for the given UmAlQura date. The absolute date means
- ** the number of days from January 1st, 1 A.D.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
- static long GetAbsoluteDateUmAlQura(int year, int month, int day) {
- //Caller should check the validaty of year, month and day.
-
- int yg=0,mg=0,dg=0;
- ConvertHijriToGregorian(year, month, day, ref yg, ref mg, ref dg);
- return GregorianCalendar.GetAbsoluteDate(yg,mg,dg);
- }
-
- static internal void CheckTicksRange(long ticks) {
- if (ticks < minDate.Ticks || ticks > maxDate.Ticks) {
- throw new ArgumentOutOfRangeException(
- "time",
- String.Format(
- CultureInfo.InvariantCulture,
- Environment.GetResourceString("ArgumentOutOfRange_CalendarRange"),
- minDate,
- maxDate));
- }
- }
-
- static internal void CheckEraRange(int era) {
- if (era != CurrentEra && era != UmAlQuraEra) {
- throw new ArgumentOutOfRangeException(nameof(era), Environment.GetResourceString("ArgumentOutOfRange_InvalidEraValue"));
- }
- }
-
- static internal void CheckYearRange(int year, int era) {
- CheckEraRange(era);
- if (year < MinCalendarYear || year > MaxCalendarYear) {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- MinCalendarYear,
- MaxCalendarYear));
- }
- }
-
- static internal void CheckYearMonthRange(int year, int month, int era) {
- CheckYearRange(year, era);
- if (month < 1 || month > 12) {
- throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_Month"));
- }
- }
-
- /*========================ConvertGregorianToHijri============================
- ** Purpose: convert DateTime to Hdate(year,month,day)
- ** Arguments:
- ** Input: DateTime
- ** Output: Hijrah date: year:HijriYear, month:HijriMonth, day:HijriDay
- ============================================================================*/
- static void ConvertGregorianToHijri(DateTime time, ref int HijriYear, ref int HijriMonth, ref int HijriDay)
- {
-
- int index, b, DaysPerThisMonth;
- double nDays;
- TimeSpan ts;
- int yh1=0, mh1=0, dh1=0;
-
- Debug.Assert((time.Ticks >= minDate.Ticks) && (time.Ticks <= maxDate.Ticks), "Gregorian date is out of range.");
-
- // Find the index where we should start our search by quessing the Hijri year that we will be in HijriYearInfo.
- // A Hijri year is 354 or 355 days. Use 355 days so that we will search from a lower index.
-
- index = (int)((time.Ticks - minDate.Ticks) / Calendar.TicksPerDay) / 355;
- do
- {
- } while (time.CompareTo(HijriYearInfo[++index].GregorianDate)>0); //while greater
-
- if (time.CompareTo(HijriYearInfo[index].GregorianDate) != 0)
- {
- index--;
- }
-
- ts = time.Subtract(HijriYearInfo[index].GregorianDate);
- yh1 = index + MinCalendarYear;
-
- mh1 = 1;
- dh1 = 1;
- nDays = ts.TotalDays;
- b = HijriYearInfo[index].HijriMonthsLengthFlags;
- DaysPerThisMonth = 29 + (b&1);
-
- while (nDays >= DaysPerThisMonth)
- {
- nDays -= DaysPerThisMonth;
- b = b >> 1;
- DaysPerThisMonth = 29 + (b&1);
- mh1++;
- }
- dh1 += (int)nDays;
-
- HijriDay = dh1;
- HijriMonth = mh1;
- HijriYear = yh1;
- }
-
- /*=================================GetDatePart==========================
- **Action: Returns a given date part of this <i>DateTime</i>. This method is used
- ** to compute the year, day-of-year, month, or day part.
- **Returns:
- **Arguments:
- **Exceptions: ArgumentException if part is incorrect.
- **Notes:
- ** First, we get the absolute date (the number of days from January 1st, 1 A.C) for the given ticks.
- ** Use the formula (((AbsoluteDate - 226894) * 33) / (33 * 365 + 8)) + 1, we can a rough value for the UmAlQura year.
- ** In order to get the exact UmAlQura year, we compare the exact absolute date for UmAlQuraYear and (UmAlQuraYear + 1).
- ** From here, we can get the correct UmAlQura year.
- ============================================================================*/
-
- internal virtual int GetDatePart(DateTime time, int part) {
- int UmAlQuraYear=0; // UmAlQura year
- int UmAlQuraMonth=0; // UmAlQura month
- int UmAlQuraDay=0; // UmAlQura day
- long ticks = time.Ticks;
- CheckTicksRange(ticks);
-
- ConvertGregorianToHijri(time, ref UmAlQuraYear, ref UmAlQuraMonth, ref UmAlQuraDay);
-
- if (part == DatePartYear)
- return (UmAlQuraYear);
-
- if (part == DatePartMonth)
- return (UmAlQuraMonth);
-
- if (part == DatePartDay)
- return (UmAlQuraDay);
-
- if (part == DatePartDayOfYear)
- return (int)(GetAbsoluteDateUmAlQura(UmAlQuraYear, UmAlQuraMonth, UmAlQuraDay) - GetAbsoluteDateUmAlQura(UmAlQuraYear, 1, 1) + 1);
-
- // Incorrect part value.
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_DateTimeParsing"));
- }
-
- // Returns the DateTime resulting from adding the given number of
- // months to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year and month parts of the specified DateTime by
- // value months, and, if required, adjusting the day part of the
- // resulting date downwards to the last day of the resulting month in the
- // resulting year. The time-of-day part of the result is the same as the
- // time-of-day part of the specified DateTime.
- //
- // In more precise terms, considering the specified DateTime to be of the
- // form y / m / d + t, where y is the
- // year, m is the month, d is the day, and t is the
- // time-of-day, the result is y1 / m1 / d1 + t,
- // where y1 and m1 are computed by adding value months
- // to y and m, and d1 is the largest value less than
- // or equal to d that denotes a valid day in month m1 of year
- // y1.
- //
-
-
- public override DateTime AddMonths(DateTime time, int months) {
- if (months < -120000 || months > 120000) {
- throw new ArgumentOutOfRangeException(
- nameof(months),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- -120000,
- 120000));
- }
- Contract.EndContractBlock();
- // Get the date in UmAlQura calendar.
- int y = GetDatePart(time, DatePartYear);
- int m = GetDatePart(time, DatePartMonth);
- int d = GetDatePart(time, DatePartDay);
- int i = m - 1 + months;
-
- if (i >= 0) {
- m = i % 12 + 1;
- y = y + i / 12;
- } else {
- m = 12 + (i + 1) % 12;
- y = y + (i - 11) / 12;
- }
-
- if (d>29)
- {
- int days = GetDaysInMonth(y, m);
- if (d > days) {
- d = days;
- }
- }
- CheckYearRange(y, UmAlQuraEra);
- DateTime dt = new DateTime(GetAbsoluteDateUmAlQura(y, m, d) * TicksPerDay + time.Ticks % TicksPerDay);
- Calendar.CheckAddResult(dt.Ticks, MinSupportedDateTime, MaxSupportedDateTime);
- return (dt);
- }
-
- // Returns the DateTime resulting from adding the given number of
- // years to the specified DateTime. The result is computed by incrementing
- // (or decrementing) the year part of the specified DateTime by value
- // years. If the month and day of the specified DateTime is 2/29, and if the
- // resulting year is not a leap year, the month and day of the resulting
- // DateTime becomes 2/28. Otherwise, the month, day, and time-of-day
- // parts of the result are the same as those of the specified DateTime.
- //
-
-
- public override DateTime AddYears(DateTime time, int years) {
- return (AddMonths(time, years * 12));
- }
-
- // Returns the day-of-month part of the specified DateTime. The returned
- // value is an integer between 1 and 31.
- //
-
-
- public override int GetDayOfMonth(DateTime time) {
- return (GetDatePart(time, DatePartDay));
- }
-
- // Returns the day-of-week part of the specified DateTime. The returned value
- // is an integer between 0 and 6, where 0 indicates Sunday, 1 indicates
- // Monday, 2 indicates Tuesday, 3 indicates Wednesday, 4 indicates
- // Thursday, 5 indicates Friday, and 6 indicates Saturday.
- //
-
-
- public override DayOfWeek GetDayOfWeek(DateTime time) {
- return ((DayOfWeek)((int)(time.Ticks / TicksPerDay + 1) % 7));
- }
-
- // Returns the day-of-year part of the specified DateTime. The returned value
- // is an integer between 1 and 354 or 355.
- //
-
-
- public override int GetDayOfYear(DateTime time) {
- return (GetDatePart(time, DatePartDayOfYear));
- }
-
- /*
- internal bool CouldBeLeapYear(int year)
- {
- return ((((year * 11) + 14) % 30) < 11);
- }
- */
-
- // Returns the number of days in the month given by the year and
- // month arguments.
- //
-
-
- public override int GetDaysInMonth(int year, int month, int era) {
- CheckYearMonthRange(year, month, era);
-
- if ((HijriYearInfo[year-MinCalendarYear].HijriMonthsLengthFlags & (1<<month-1))==0)
- return 29;
- else
- return 30;
- }
-
- static internal int RealGetDaysInYear(int year)
- {
- int days = 0, b;
-
- Debug.Assert( (year >= MinCalendarYear) && (year <= MaxCalendarYear), "Hijri year is out of range.");
-
- b = HijriYearInfo[year-MinCalendarYear].HijriMonthsLengthFlags;
-
- for(int m = 1; m <= 12; m++)
- {
- days += 29 + (b & 0x1);
- b = b >> 1;
- }
- Debug.Assert((days == 354)||(days == 355), "Hijri year has to be 354 or 355 days.");
- return days;
- }
-
- // Returns the number of days in the year given by the year argument for the current era.
- //
-
-
- public override int GetDaysInYear(int year, int era)
- {
- CheckYearRange(year, era);
- return (RealGetDaysInYear(year));
- }
-
- // Returns the era for the specified DateTime value.
-
-
- public override int GetEra(DateTime time) {
- CheckTicksRange(time.Ticks);
- return (UmAlQuraEra);
- }
-
-
-
- public override int[] Eras {
- get {
- return (new int[] {UmAlQuraEra});
- }
- }
-
- // Returns the month part of the specified DateTime. The returned value is an
- // integer between 1 and 12.
- //
-
-
- public override int GetMonth(DateTime time) {
- return (GetDatePart(time, DatePartMonth));
- }
-
- // Returns the number of months in the specified year and era.
-
-
- public override int GetMonthsInYear(int year, int era) {
- CheckYearRange(year, era);
- return (12);
- }
-
- // Returns the year part of the specified DateTime. The returned value is an
- // integer between MinCalendarYear and MaxCalendarYear.
- //
-
-
- public override int GetYear(DateTime time) {
- return (GetDatePart(time, DatePartYear));
- }
-
- // Checks whether a given day in the specified era is a leap day. This method returns true if
- // the date is a leap day, or false if not.
- //
-
-
- public override bool IsLeapDay(int year, int month, int day, int era) {
- if (day>=1 && day <=29)
- {
- CheckYearMonthRange(year, month, era);
- return (false);
- }
-
- // The year/month/era value checking is done in GetDaysInMonth().
- int daysInMonth = GetDaysInMonth(year, month, era);
- if (day < 1 || day > daysInMonth) {
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Day"),
- daysInMonth,
- month));
- }
- return (false);
- }
-
- // Returns the leap month in a calendar year of the specified era. This method returns 0
- // if this calendar does not have leap month, or this year is not a leap year.
- //
-
-
- public override int GetLeapMonth(int year, int era)
- {
- CheckYearRange(year, era);
- return (0);
- }
-
- // Checks whether a given month in the specified era is a leap month. This method returns true if
- // month is a leap month, or false if not.
- //
-
-
- public override bool IsLeapMonth(int year, int month, int era) {
- CheckYearMonthRange(year, month, era);
- return (false);
- }
-
- // Checks whether a given year in the specified era is a leap year. This method returns true if
- // year is a leap year, or false if not.
- //
-
-
- public override bool IsLeapYear(int year, int era)
- {
- CheckYearRange(year, era);
- if (RealGetDaysInYear(year) == 355)
- return true;
- else
- return false;
- }
-
- // Returns the date and time converted to a DateTime value. Throws an exception if the n-tuple is invalid.
- //
-
-
- public override DateTime ToDateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int era) {
- if (day >= 1 && day <= 29)
- {
- CheckYearMonthRange(year, month, era);
- goto DayInRang;
- }
-
- // The year/month/era value checking is done in GetDaysInMonth().
- int daysInMonth = GetDaysInMonth(year, month, era);
-
- if (day < 1 || day > daysInMonth) {
- BCLDebug.Log("year = " + year + ", month = " + month + ", day = " + day);
- throw new ArgumentOutOfRangeException(
- nameof(day),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Day"),
- daysInMonth,
- month));
- }
-DayInRang:
- long lDate = GetAbsoluteDateUmAlQura(year, month, day);
-
- if (lDate >= 0) {
- return (new DateTime(lDate * GregorianCalendar.TicksPerDay + TimeToTicks(hour, minute, second, millisecond)));
- } else {
- throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("ArgumentOutOfRange_BadYearMonthDay"));
- }
- }
-
- private const int DEFAULT_TWO_DIGIT_YEAR_MAX = 1451;
-
-
-
- public override int TwoDigitYearMax {
- get {
- if (twoDigitYearMax == -1) {
- twoDigitYearMax = GetSystemTwoDigitYearSetting(ID, DEFAULT_TWO_DIGIT_YEAR_MAX);
- }
- return (twoDigitYearMax);
- }
-
- set {
- if (value != 99 && (value < MinCalendarYear || value > MaxCalendarYear)) {
- throw new ArgumentOutOfRangeException(
- nameof(value),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- MinCalendarYear,
- MaxCalendarYear));
- }
- Contract.EndContractBlock();
- VerifyWritable();
- // We allow year 99 to be set so that one can make ToFourDigitYearMax a no-op by setting TwoDigitYearMax to 99.
- twoDigitYearMax = value;
- }
- }
-
-
-
- public override int ToFourDigitYear(int year) {
- if (year < 0) {
- throw new ArgumentOutOfRangeException(nameof(year),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- Contract.EndContractBlock();
-
- if (year < 100) {
- return (base.ToFourDigitYear(year));
- }
-
- if ((year < MinCalendarYear) || (year > MaxCalendarYear)) {
- throw new ArgumentOutOfRangeException(
- nameof(year),
- String.Format(
- CultureInfo.CurrentCulture,
- Environment.GetResourceString("ArgumentOutOfRange_Range"),
- MinCalendarYear,
- MaxCalendarYear));
- }
- return (year);
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/Globalization/UnicodeCategory.cs b/src/mscorlib/src/System/Globalization/UnicodeCategory.cs
deleted file mode 100644
index c9898f135b..0000000000
--- a/src/mscorlib/src/System/Globalization/UnicodeCategory.cs
+++ /dev/null
@@ -1,78 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose:
-**
-**
-============================================================*/
-namespace System.Globalization {
-
- [Serializable]
- public enum UnicodeCategory {
-
- UppercaseLetter = 0,
-
- LowercaseLetter = 1,
-
- TitlecaseLetter = 2,
-
- ModifierLetter = 3,
-
- OtherLetter = 4,
-
- NonSpacingMark = 5,
-
- SpacingCombiningMark = 6,
-
- EnclosingMark = 7,
-
- DecimalDigitNumber = 8,
-
- LetterNumber = 9,
-
- OtherNumber = 10,
-
- SpaceSeparator = 11,
-
- LineSeparator = 12,
-
- ParagraphSeparator = 13,
-
- Control = 14,
-
- Format = 15,
-
- Surrogate = 16,
-
- PrivateUse = 17,
-
- ConnectorPunctuation = 18,
-
- DashPunctuation = 19,
-
- OpenPunctuation = 20,
-
- ClosePunctuation = 21,
-
- InitialQuotePunctuation = 22,
-
- FinalQuotePunctuation = 23,
-
- OtherPunctuation = 24,
-
- MathSymbol = 25,
-
- CurrencySymbol = 26,
-
- ModifierSymbol = 27,
-
- OtherSymbol = 28,
-
- OtherNotAssigned = 29,
- }
-}
diff --git a/src/mscorlib/src/System/Guid.cs b/src/mscorlib/src/System/Guid.cs
index 1116faf027..f64211d5d0 100644
--- a/src/mscorlib/src/System/Guid.cs
+++ b/src/mscorlib/src/System/Guid.cs
@@ -2,17 +2,18 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System {
-
- using System;
- using System.Globalization;
- using System.Text;
- using Microsoft.Win32;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
+using System;
+using System.Globalization;
+using System.Text;
+using Microsoft.Win32;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
// Represents a Globally Unique Identifier.
[StructLayout(LayoutKind.Sequential)]
[Serializable]
@@ -24,17 +25,17 @@ namespace System {
////////////////////////////////////////////////////////////////////////////////
// Member variables
////////////////////////////////////////////////////////////////////////////////
- private int _a;
- private short _b;
- private short _c;
- private byte _d;
- private byte _e;
- private byte _f;
- private byte _g;
- private byte _h;
- private byte _i;
- private byte _j;
- private byte _k;
+ private int _a;
+ private short _b;
+ private short _c;
+ private byte _d;
+ private byte _e;
+ private byte _f;
+ private byte _g;
+ private byte _h;
+ private byte _i;
+ private byte _j;
+ private byte _k;
@@ -46,10 +47,10 @@ namespace System {
//
public Guid(byte[] b)
{
- if (b==null)
+ if (b == null)
throw new ArgumentNullException(nameof(b));
if (b.Length != 16)
- throw new ArgumentException(Environment.GetResourceString("Arg_GuidArrayCtor", "16"), nameof(b));
+ throw new ArgumentException(SR.Format(SR.Arg_GuidArrayCtor, "16"), nameof(b));
Contract.EndContractBlock();
_a = ((int)b[3] << 24) | ((int)b[2] << 16) | ((int)b[1] << 8) | b[0];
@@ -66,7 +67,7 @@ namespace System {
}
[CLSCompliant(false)]
- public Guid (uint a, ushort b, ushort c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k)
+ public Guid(uint a, ushort b, ushort c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k)
{
_a = (int)a;
_b = (short)b;
@@ -86,16 +87,16 @@ namespace System {
//
public Guid(int a, short b, short c, byte[] d)
{
- if (d==null)
+ if (d == null)
throw new ArgumentNullException(nameof(d));
// Check that array is not too big
- if(d.Length != 8)
- throw new ArgumentException(Environment.GetResourceString("Arg_GuidArrayCtor", "8"), nameof(d));
+ if (d.Length != 8)
+ throw new ArgumentException(SR.Format(SR.Arg_GuidArrayCtor, "8"), nameof(d));
Contract.EndContractBlock();
- _a = a;
- _b = b;
- _c = c;
+ _a = a;
+ _b = b;
+ _c = c;
_d = d[0];
_e = d[1];
_f = d[2];
@@ -125,41 +126,45 @@ namespace System {
}
[Flags]
- private enum GuidStyles {
- None = 0x00000000,
- AllowParenthesis = 0x00000001, //Allow the guid to be enclosed in parens
- AllowBraces = 0x00000002, //Allow the guid to be enclosed in braces
- AllowDashes = 0x00000004, //Allow the guid to contain dash group separators
- AllowHexPrefix = 0x00000008, //Allow the guid to contain {0xdd,0xdd}
- RequireParenthesis = 0x00000010, //Require the guid to be enclosed in parens
- RequireBraces = 0x00000020, //Require the guid to be enclosed in braces
- RequireDashes = 0x00000040, //Require the guid to contain dash group separators
- RequireHexPrefix = 0x00000080, //Require the guid to contain {0xdd,0xdd}
-
- HexFormat = RequireBraces | RequireHexPrefix, /* X */
- NumberFormat = None, /* N */
- DigitFormat = RequireDashes, /* D */
- BraceFormat = RequireBraces | RequireDashes, /* B */
- ParenthesisFormat = RequireParenthesis | RequireDashes, /* P */
-
- Any = AllowParenthesis | AllowBraces | AllowDashes | AllowHexPrefix,
+ private enum GuidStyles
+ {
+ None = 0x00000000,
+ AllowParenthesis = 0x00000001, //Allow the guid to be enclosed in parens
+ AllowBraces = 0x00000002, //Allow the guid to be enclosed in braces
+ AllowDashes = 0x00000004, //Allow the guid to contain dash group separators
+ AllowHexPrefix = 0x00000008, //Allow the guid to contain {0xdd,0xdd}
+ RequireParenthesis = 0x00000010, //Require the guid to be enclosed in parens
+ RequireBraces = 0x00000020, //Require the guid to be enclosed in braces
+ RequireDashes = 0x00000040, //Require the guid to contain dash group separators
+ RequireHexPrefix = 0x00000080, //Require the guid to contain {0xdd,0xdd}
+
+ HexFormat = RequireBraces | RequireHexPrefix, /* X */
+ NumberFormat = None, /* N */
+ DigitFormat = RequireDashes, /* D */
+ BraceFormat = RequireBraces | RequireDashes, /* B */
+ ParenthesisFormat = RequireParenthesis | RequireDashes, /* P */
+
+ Any = AllowParenthesis | AllowBraces | AllowDashes | AllowHexPrefix,
}
- private enum GuidParseThrowStyle {
- None = 0,
- All = 1,
- AllButOverflow = 2
+ private enum GuidParseThrowStyle
+ {
+ None = 0,
+ All = 1,
+ AllButOverflow = 2
}
- private enum ParseFailureKind {
- None = 0,
- ArgumentNull = 1,
- Format = 2,
- FormatWithParameter = 3,
- NativeException = 4,
+ private enum ParseFailureKind
+ {
+ None = 0,
+ ArgumentNull = 1,
+ Format = 2,
+ FormatWithParameter = 3,
+ NativeException = 4,
FormatWithInnerException = 5
}
// This will store the result of the parsing. And it will eventually be used to construct a Guid instance.
- private struct GuidResult {
+ private struct GuidResult
+ {
internal Guid parsedGuid;
internal GuidParseThrowStyle throwStyle;
@@ -169,53 +174,61 @@ namespace System {
internal string m_failureArgumentName;
internal Exception m_innerException;
- internal void Init(GuidParseThrowStyle canThrow) {
+ internal void Init(GuidParseThrowStyle canThrow)
+ {
parsedGuid = Guid.Empty;
- throwStyle = canThrow;
+ throwStyle = canThrow;
}
- internal void SetFailure(Exception nativeException) {
+ internal void SetFailure(Exception nativeException)
+ {
m_failure = ParseFailureKind.NativeException;
m_innerException = nativeException;
}
- internal void SetFailure(ParseFailureKind failure, string failureMessageID) {
+ internal void SetFailure(ParseFailureKind failure, string failureMessageID)
+ {
SetFailure(failure, failureMessageID, null, null, null);
}
- internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument) {
+ internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument)
+ {
SetFailure(failure, failureMessageID, failureMessageFormatArgument, null, null);
}
internal void SetFailure(ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument,
- string failureArgumentName, Exception innerException) {
+ string failureArgumentName, Exception innerException)
+ {
Debug.Assert(failure != ParseFailureKind.NativeException, "ParseFailureKind.NativeException should not be used with this overload");
m_failure = failure;
m_failureMessageID = failureMessageID;
m_failureMessageFormatArgument = failureMessageFormatArgument;
m_failureArgumentName = failureArgumentName;
m_innerException = innerException;
- if (throwStyle != GuidParseThrowStyle.None) {
+ if (throwStyle != GuidParseThrowStyle.None)
+ {
throw GetGuidParseException();
}
}
- internal Exception GetGuidParseException() {
- switch (m_failure) {
- case ParseFailureKind.ArgumentNull:
- return new ArgumentNullException(m_failureArgumentName, Environment.GetResourceString(m_failureMessageID));
+ internal Exception GetGuidParseException()
+ {
+ switch (m_failure)
+ {
+ case ParseFailureKind.ArgumentNull:
+ return new ArgumentNullException(m_failureArgumentName, SR.GetResourceString(m_failureMessageID));
- case ParseFailureKind.FormatWithInnerException:
- return new FormatException(Environment.GetResourceString(m_failureMessageID), m_innerException);
+ case ParseFailureKind.FormatWithInnerException:
+ return new FormatException(SR.GetResourceString(m_failureMessageID), m_innerException);
- case ParseFailureKind.FormatWithParameter:
- return new FormatException(Environment.GetResourceString(m_failureMessageID, m_failureMessageFormatArgument));
+ case ParseFailureKind.FormatWithParameter:
+ return new FormatException(SR.Format(SR.GetResourceString(m_failureMessageID), m_failureMessageFormatArgument));
- case ParseFailureKind.Format:
- return new FormatException(Environment.GetResourceString(m_failureMessageID));
+ case ParseFailureKind.Format:
+ return new FormatException(SR.GetResourceString(m_failureMessageID));
- case ParseFailureKind.NativeException:
- return m_innerException;
+ case ParseFailureKind.NativeException:
+ return m_innerException;
- default:
- Debug.Assert(false, "Unknown GuidParseFailure: " + m_failure);
- return new FormatException(Environment.GetResourceString("Format_GuidUnrecognized"));
+ default:
+ Debug.Assert(false, "Unknown GuidParseFailure: " + m_failure);
+ return new FormatException(SR.Format_GuidUnrecognized);
}
}
}
@@ -230,7 +243,8 @@ namespace System {
//
public Guid(String g)
{
- if (g==null) {
+ if (g == null)
+ {
throw new ArgumentNullException(nameof(g));
}
Contract.EndContractBlock();
@@ -238,10 +252,12 @@ namespace System {
GuidResult result = new GuidResult();
result.Init(GuidParseThrowStyle.All);
- if (TryParseGuid(g, GuidStyles.Any, ref result)) {
+ if (TryParseGuid(g, GuidStyles.Any, ref result))
+ {
this = result.parsedGuid;
}
- else {
+ else
+ {
throw result.GetGuidParseException();
}
}
@@ -249,17 +265,20 @@ namespace System {
public static Guid Parse(String input)
{
- if (input == null) {
+ if (input == null)
+ {
throw new ArgumentNullException(nameof(input));
}
Contract.EndContractBlock();
GuidResult result = new GuidResult();
result.Init(GuidParseThrowStyle.AllButOverflow);
- if (TryParseGuid(input, GuidStyles.Any, ref result)) {
+ if (TryParseGuid(input, GuidStyles.Any, ref result))
+ {
return result.parsedGuid;
}
- else {
+ else
+ {
throw result.GetGuidParseException();
}
}
@@ -268,11 +287,13 @@ namespace System {
{
GuidResult parseResult = new GuidResult();
parseResult.Init(GuidParseThrowStyle.None);
- if (TryParseGuid(input, GuidStyles.Any, ref parseResult)) {
+ if (TryParseGuid(input, GuidStyles.Any, ref parseResult))
+ {
result = parseResult.parsedGuid;
return true;
}
- else {
+ else
+ {
result = Guid.Empty;
return false;
}
@@ -286,45 +307,55 @@ namespace System {
if (format == null)
throw new ArgumentNullException(nameof(format));
- if( format.Length != 1) {
+ if (format.Length != 1)
+ {
// all acceptable format strings are of length 1
- throw new FormatException(Environment.GetResourceString("Format_InvalidGuidFormatSpecification"));
+ throw new FormatException(SR.Format_InvalidGuidFormatSpecification);
}
GuidStyles style;
char formatCh = format[0];
- if (formatCh == 'D' || formatCh == 'd') {
+ if (formatCh == 'D' || formatCh == 'd')
+ {
style = GuidStyles.DigitFormat;
- }
- else if (formatCh == 'N' || formatCh == 'n') {
+ }
+ else if (formatCh == 'N' || formatCh == 'n')
+ {
style = GuidStyles.NumberFormat;
}
- else if (formatCh == 'B' || formatCh == 'b') {
+ else if (formatCh == 'B' || formatCh == 'b')
+ {
style = GuidStyles.BraceFormat;
}
- else if (formatCh == 'P' || formatCh == 'p') {
+ else if (formatCh == 'P' || formatCh == 'p')
+ {
style = GuidStyles.ParenthesisFormat;
}
- else if (formatCh == 'X' || formatCh == 'x') {
+ else if (formatCh == 'X' || formatCh == 'x')
+ {
style = GuidStyles.HexFormat;
}
- else {
- throw new FormatException(Environment.GetResourceString("Format_InvalidGuidFormatSpecification"));
+ else
+ {
+ throw new FormatException(SR.Format_InvalidGuidFormatSpecification);
}
GuidResult result = new GuidResult();
result.Init(GuidParseThrowStyle.AllButOverflow);
- if (TryParseGuid(input, style, ref result)) {
+ if (TryParseGuid(input, style, ref result))
+ {
return result.parsedGuid;
}
- else {
+ else
+ {
throw result.GetGuidParseException();
}
}
public static bool TryParseExact(String input, String format, out Guid result)
{
- if (format == null || format.Length != 1) {
+ if (format == null || format.Length != 1)
+ {
result = Guid.Empty;
return false;
}
@@ -332,22 +363,28 @@ namespace System {
GuidStyles style;
char formatCh = format[0];
- if (formatCh == 'D' || formatCh == 'd') {
+ if (formatCh == 'D' || formatCh == 'd')
+ {
style = GuidStyles.DigitFormat;
- }
- else if (formatCh == 'N' || formatCh == 'n') {
+ }
+ else if (formatCh == 'N' || formatCh == 'n')
+ {
style = GuidStyles.NumberFormat;
}
- else if (formatCh == 'B' || formatCh == 'b') {
+ else if (formatCh == 'B' || formatCh == 'b')
+ {
style = GuidStyles.BraceFormat;
}
- else if (formatCh == 'P' || formatCh == 'p') {
+ else if (formatCh == 'P' || formatCh == 'p')
+ {
style = GuidStyles.ParenthesisFormat;
}
- else if (formatCh == 'X' || formatCh == 'x') {
+ else if (formatCh == 'X' || formatCh == 'x')
+ {
style = GuidStyles.HexFormat;
}
- else {
+ else
+ {
// invalid guid format specification
result = Guid.Empty;
return false;
@@ -355,11 +392,13 @@ namespace System {
GuidResult parseResult = new GuidResult();
parseResult.Init(GuidParseThrowStyle.None);
- if (TryParseGuid(input, style, ref parseResult)) {
+ if (TryParseGuid(input, style, ref parseResult))
+ {
result = parseResult.parsedGuid;
return true;
}
- else {
+ else
+ {
result = Guid.Empty;
return false;
}
@@ -368,13 +407,15 @@ namespace System {
private static bool TryParseGuid(String g, GuidStyles flags, ref GuidResult result)
{
- if (g == null) {
+ if (g == null)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
return false;
}
String guidString = g.Trim(); //Remove Whitespace
- if (guidString.Length == 0) {
+ if (guidString.Length == 0)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
return false;
}
@@ -382,15 +423,19 @@ namespace System {
// Check for dashes
bool dashesExistInString = (guidString.IndexOf('-', 0) >= 0);
- if (dashesExistInString) {
- if ((flags & (GuidStyles.AllowDashes | GuidStyles.RequireDashes)) == 0) {
+ if (dashesExistInString)
+ {
+ if ((flags & (GuidStyles.AllowDashes | GuidStyles.RequireDashes)) == 0)
+ {
// dashes are not allowed
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
return false;
}
}
- else {
- if ((flags & GuidStyles.RequireDashes) != 0) {
+ else
+ {
+ if ((flags & GuidStyles.RequireDashes) != 0)
+ {
// dashes are required
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
return false;
@@ -400,15 +445,19 @@ namespace System {
// Check for braces
bool bracesExistInString = (guidString.IndexOf('{', 0) >= 0);
- if (bracesExistInString) {
- if ((flags & (GuidStyles.AllowBraces | GuidStyles.RequireBraces)) == 0) {
+ if (bracesExistInString)
+ {
+ if ((flags & (GuidStyles.AllowBraces | GuidStyles.RequireBraces)) == 0)
+ {
// braces are not allowed
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
return false;
}
}
- else {
- if ((flags & GuidStyles.RequireBraces) != 0) {
+ else
+ {
+ if ((flags & GuidStyles.RequireBraces) != 0)
+ {
// braces are required
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
return false;
@@ -417,50 +466,61 @@ namespace System {
// Check for parenthesis
bool parenthesisExistInString = (guidString.IndexOf('(', 0) >= 0);
-
- if (parenthesisExistInString) {
- if ((flags & (GuidStyles.AllowParenthesis | GuidStyles.RequireParenthesis)) == 0) {
+
+ if (parenthesisExistInString)
+ {
+ if ((flags & (GuidStyles.AllowParenthesis | GuidStyles.RequireParenthesis)) == 0)
+ {
// parenthesis are not allowed
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
return false;
}
}
- else {
- if ((flags & GuidStyles.RequireParenthesis) != 0) {
+ else
+ {
+ if ((flags & GuidStyles.RequireParenthesis) != 0)
+ {
// parenthesis are required
result.SetFailure(ParseFailureKind.Format, "Format_GuidUnrecognized");
return false;
}
}
- try {
+ try
+ {
// let's get on with the parsing
- if (dashesExistInString) {
+ if (dashesExistInString)
+ {
// Check if it's of the form [{|(]dddddddd-dddd-dddd-dddd-dddddddddddd[}|)]
return TryParseGuidWithDashes(guidString, ref result);
}
- else if (bracesExistInString) {
+ else if (bracesExistInString)
+ {
// Check if it's of the form {0xdddddddd,0xdddd,0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}}
return TryParseGuidWithHexPrefix(guidString, ref result);
}
- else {
+ else
+ {
// Check if it's of the form dddddddddddddddddddddddddddddddd
return TryParseGuidWithNoStyle(guidString, ref result);
}
}
- catch(IndexOutOfRangeException ex) {
+ catch (IndexOutOfRangeException ex)
+ {
result.SetFailure(ParseFailureKind.FormatWithInnerException, "Format_GuidUnrecognized", null, null, ex);
return false;
}
- catch (ArgumentException ex) {
+ catch (ArgumentException ex)
+ {
result.SetFailure(ParseFailureKind.FormatWithInnerException, "Format_GuidUnrecognized", null, null, ex);
return false;
- }
+ }
}
-
+
// Check if it's of the form {0xdddddddd,0xdddd,0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}}
- private static bool TryParseGuidWithHexPrefix(String guidString, ref GuidResult result) {
+ private static bool TryParseGuidWithHexPrefix(String guidString, ref GuidResult result)
+ {
int numStart = 0;
int numLen = 0;
@@ -468,13 +528,15 @@ namespace System {
guidString = EatAllWhitespace(guidString);
// Check for leading '{'
- if(String.IsNullOrEmpty(guidString) || guidString[0] != '{') {
+ if (String.IsNullOrEmpty(guidString) || guidString[0] != '{')
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidBrace");
return false;
}
// Check for '0x'
- if(!IsHexPrefix(guidString, 1)) {
+ if (!IsHexPrefix(guidString, 1))
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidHexPrefix", "{0xdddddddd, etc}");
return false;
}
@@ -482,7 +544,8 @@ namespace System {
// Find the end of this hex number (since it is not fixed length)
numStart = 3;
numLen = guidString.IndexOf(',', numStart) - numStart;
- if(numLen <= 0) {
+ if (numLen <= 0)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidComma");
return false;
}
@@ -492,14 +555,16 @@ namespace System {
return false;
// Check for '0x'
- if(!IsHexPrefix(guidString, numStart+numLen+1)) {
+ if (!IsHexPrefix(guidString, numStart + numLen + 1))
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidHexPrefix", "{0xdddddddd, 0xdddd, etc}");
return false;
}
// +3 to get by ',0x'
numStart = numStart + numLen + 3;
numLen = guidString.IndexOf(',', numStart) - numStart;
- if(numLen <= 0) {
+ if (numLen <= 0)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidComma");
return false;
}
@@ -508,14 +573,16 @@ namespace System {
if (!StringToShort(guidString.Substring(numStart, numLen) /*first DWORD*/, -1, ParseNumbers.IsTight, out result.parsedGuid._b, ref result))
return false;
// Check for '0x'
- if(!IsHexPrefix(guidString, numStart+numLen+1)) {
+ if (!IsHexPrefix(guidString, numStart + numLen + 1))
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidHexPrefix", "{0xdddddddd, 0xdddd, 0xdddd, etc}");
return false;
}
// +3 to get by ',0x'
numStart = numStart + numLen + 3;
numLen = guidString.IndexOf(',', numStart) - numStart;
- if(numLen <= 0) {
+ if (numLen <= 0)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidComma");
return false;
}
@@ -523,9 +590,10 @@ namespace System {
// Read in the number
if (!StringToShort(guidString.Substring(numStart, numLen) /*first DWORD*/, -1, ParseNumbers.IsTight, out result.parsedGuid._c, ref result))
return false;
-
+
// Check for '{'
- if(guidString.Length <= numStart+numLen+1 || guidString[numStart+numLen+1] != '{') {
+ if (guidString.Length <= numStart + numLen + 1 || guidString[numStart + numLen + 1] != '{')
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidBrace");
return false;
}
@@ -534,10 +602,11 @@ namespace System {
numLen++;
byte[] bytes = new byte[8];
- for(int i = 0; i < 8; i++)
+ for (int i = 0; i < 8; i++)
{
// Check for '0x'
- if(!IsHexPrefix(guidString, numStart+numLen+1)) {
+ if (!IsHexPrefix(guidString, numStart + numLen + 1))
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidHexPrefix", "{... { ... 0xdd, ...}}");
return false;
}
@@ -546,33 +615,37 @@ namespace System {
numStart = numStart + numLen + 3;
// Calculate number length
- if(i < 7) // first 7 cases
+ if (i < 7) // first 7 cases
{
numLen = guidString.IndexOf(',', numStart) - numStart;
- if(numLen <= 0) {
+ if (numLen <= 0)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidComma");
return false;
- }
+ }
}
else // last case ends with '}', not ','
{
numLen = guidString.IndexOf('}', numStart) - numStart;
- if(numLen <= 0) {
+ if (numLen <= 0)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidBraceAfterLastNumber");
return false;
- }
+ }
}
// Read in the number
int signedNumber;
- if (!StringToInt(guidString.Substring(numStart, numLen), -1, ParseNumbers.IsTight, out signedNumber, ref result)) {
+ if (!StringToInt(guidString.Substring(numStart, numLen), -1, ParseNumbers.IsTight, out signedNumber, ref result))
+ {
return false;
}
uint number = (uint)signedNumber;
// check for overflow
- if(number > 255) {
- result.SetFailure(ParseFailureKind.Format, "Overflow_Byte");
+ if (number > 255)
+ {
+ result.SetFailure(ParseFailureKind.Format, "Overflow_Byte");
return false;
}
bytes[i] = (byte)number;
@@ -588,40 +661,48 @@ namespace System {
result.parsedGuid._k = bytes[7];
// Check for last '}'
- if(numStart+numLen+1 >= guidString.Length || guidString[numStart+numLen+1] != '}') {
+ if (numStart + numLen + 1 >= guidString.Length || guidString[numStart + numLen + 1] != '}')
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidEndBrace");
return false;
}
// Check if we have extra characters at the end
- if( numStart+numLen+1 != guidString.Length -1) {
+ if (numStart + numLen + 1 != guidString.Length - 1)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_ExtraJunkAtEnd");
return false;
}
-
+
return true;
}
-
+
// Check if it's of the form dddddddddddddddddddddddddddddddd
- private static bool TryParseGuidWithNoStyle(String guidString, ref GuidResult result) {
- int startPos=0;
+ private static bool TryParseGuidWithNoStyle(String guidString, ref GuidResult result)
+ {
+ int startPos = 0;
int temp;
long templ;
int currentPos = 0;
- if(guidString.Length != 32) {
+ if (guidString.Length != 32)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidInvLen");
return false;
}
- for(int i= 0; i< guidString.Length; i++) {
+ for (int i = 0; i < guidString.Length; i++)
+ {
char ch = guidString[i];
- if(ch >= '0' && ch <= '9') {
+ if (ch >= '0' && ch <= '9')
+ {
continue;
}
- else {
+ else
+ {
char upperCaseCh = Char.ToUpper(ch, CultureInfo.InvariantCulture);
- if(upperCaseCh >= 'A' && upperCaseCh <= 'F') {
+ if (upperCaseCh >= 'A' && upperCaseCh <= 'F')
+ {
continue;
}
}
@@ -651,20 +732,21 @@ namespace System {
if (!StringToLong(guidString, ref currentPos, ParseNumbers.NoSpace, out templ, ref result))
return false;
- if (currentPos - startPos!=12) {
+ if (currentPos - startPos != 12)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidInvLen");
return false;
}
- result.parsedGuid._d = (byte)(temp>>8);
+ result.parsedGuid._d = (byte)(temp >> 8);
result.parsedGuid._e = (byte)(temp);
temp = (int)(templ >> 32);
- result.parsedGuid._f = (byte)(temp>>8);
+ result.parsedGuid._f = (byte)(temp >> 8);
result.parsedGuid._g = (byte)(temp);
temp = (int)(templ);
- result.parsedGuid._h = (byte)(temp>>24);
- result.parsedGuid._i = (byte)(temp>>16);
- result.parsedGuid._j = (byte)(temp>>8);
+ result.parsedGuid._h = (byte)(temp >> 24);
+ result.parsedGuid._i = (byte)(temp >> 16);
+ result.parsedGuid._j = (byte)(temp >> 8);
result.parsedGuid._k = (byte)(temp);
return true;
@@ -672,36 +754,43 @@ namespace System {
// Check if it's of the form [{|(]dddddddd-dddd-dddd-dddd-dddddddddddd[}|)]
- private static bool TryParseGuidWithDashes(String guidString, ref GuidResult result) {
- int startPos=0;
+ private static bool TryParseGuidWithDashes(String guidString, ref GuidResult result)
+ {
+ int startPos = 0;
int temp;
long templ;
int currentPos = 0;
// check to see that it's the proper length
- if (guidString[0]=='{') {
- if (guidString.Length!=38 || guidString[37]!='}') {
+ if (guidString[0] == '{')
+ {
+ if (guidString.Length != 38 || guidString[37] != '}')
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidInvLen");
return false;
}
- startPos=1;
+ startPos = 1;
}
- else if (guidString[0]=='(') {
- if (guidString.Length!=38 || guidString[37]!=')') {
+ else if (guidString[0] == '(')
+ {
+ if (guidString.Length != 38 || guidString[37] != ')')
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidInvLen");
return false;
}
- startPos=1;
+ startPos = 1;
}
- else if(guidString.Length != 36) {
+ else if (guidString.Length != 36)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidInvLen");
return false;
}
- if (guidString[8+startPos] != '-' ||
- guidString[13+startPos] != '-' ||
- guidString[18+startPos] != '-' ||
- guidString[23+startPos] != '-') {
+ if (guidString[8 + startPos] != '-' ||
+ guidString[13 + startPos] != '-' ||
+ guidString[18 + startPos] != '-' ||
+ guidString[23 + startPos] != '-')
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidDashes");
return false;
}
@@ -725,24 +814,25 @@ namespace System {
if (!StringToInt(guidString, ref currentPos, 4, ParseNumbers.NoSpace, out temp, ref result))
return false;
++currentPos; //Increment past the '-';
- startPos=currentPos;
+ startPos = currentPos;
if (!StringToLong(guidString, ref currentPos, ParseNumbers.NoSpace, out templ, ref result))
return false;
- if (currentPos - startPos != 12) {
+ if (currentPos - startPos != 12)
+ {
result.SetFailure(ParseFailureKind.Format, "Format_GuidInvLen");
return false;
}
- result.parsedGuid._d = (byte)(temp>>8);
+ result.parsedGuid._d = (byte)(temp >> 8);
result.parsedGuid._e = (byte)(temp);
temp = (int)(templ >> 32);
- result.parsedGuid._f = (byte)(temp>>8);
+ result.parsedGuid._f = (byte)(temp >> 8);
result.parsedGuid._g = (byte)(temp);
temp = (int)(templ);
- result.parsedGuid._h = (byte)(temp>>24);
- result.parsedGuid._i = (byte)(temp>>16);
- result.parsedGuid._j = (byte)(temp>>8);
+ result.parsedGuid._h = (byte)(temp >> 24);
+ result.parsedGuid._i = (byte)(temp >> 16);
+ result.parsedGuid._j = (byte)(temp >> 8);
result.parsedGuid._k = (byte)(temp);
return true;
@@ -752,10 +842,12 @@ namespace System {
//
// StringToShort, StringToInt, and StringToLong are wrappers around COMUtilNative integer parsing routines;
- private static unsafe bool StringToShort(String str, int requiredLength, int flags, out short result, ref GuidResult parseResult) {
+ private static unsafe bool StringToShort(String str, int requiredLength, int flags, out short result, ref GuidResult parseResult)
+ {
return StringToShort(str, null, requiredLength, flags, out result, ref parseResult);
}
- private static unsafe bool StringToShort(String str, int* parsePos, int requiredLength, int flags, out short result, ref GuidResult parseResult) {
+ private static unsafe bool StringToShort(String str, int* parsePos, int requiredLength, int flags, out short result, ref GuidResult parseResult)
+ {
result = 0;
int x;
bool retValue = StringToInt(str, parsePos, requiredLength, flags, out x, ref parseResult);
@@ -763,79 +855,103 @@ namespace System {
return retValue;
}
- private static unsafe bool StringToInt(String str, int requiredLength, int flags, out int result, ref GuidResult parseResult) {
+ private static unsafe bool StringToInt(String str, int requiredLength, int flags, out int result, ref GuidResult parseResult)
+ {
return StringToInt(str, null, requiredLength, flags, out result, ref parseResult);
}
- private static unsafe bool StringToInt(String str, ref int parsePos, int requiredLength, int flags, out int result, ref GuidResult parseResult) {
- fixed(int * ppos = &parsePos) {
+ private static unsafe bool StringToInt(String str, ref int parsePos, int requiredLength, int flags, out int result, ref GuidResult parseResult)
+ {
+ fixed (int* ppos = &parsePos)
+ {
return StringToInt(str, ppos, requiredLength, flags, out result, ref parseResult);
}
}
- private static unsafe bool StringToInt(String str, int* parsePos, int requiredLength, int flags, out int result, ref GuidResult parseResult) {
+ private static unsafe bool StringToInt(String str, int* parsePos, int requiredLength, int flags, out int result, ref GuidResult parseResult)
+ {
result = 0;
int currStart = (parsePos == null) ? 0 : (*parsePos);
- try {
+ try
+ {
result = ParseNumbers.StringToInt(str, 16, flags, parsePos);
}
- catch (OverflowException ex) {
- if (parseResult.throwStyle == GuidParseThrowStyle.All) {
+ catch (OverflowException ex)
+ {
+ if (parseResult.throwStyle == GuidParseThrowStyle.All)
+ {
throw;
}
- else if (parseResult.throwStyle == GuidParseThrowStyle.AllButOverflow) {
- throw new FormatException(Environment.GetResourceString("Format_GuidUnrecognized"), ex);
+ else if (parseResult.throwStyle == GuidParseThrowStyle.AllButOverflow)
+ {
+ throw new FormatException(SR.Format_GuidUnrecognized, ex);
}
- else {
+ else
+ {
parseResult.SetFailure(ex);
return false;
}
}
- catch (Exception ex) {
- if (parseResult.throwStyle == GuidParseThrowStyle.None) {
+ catch (Exception ex)
+ {
+ if (parseResult.throwStyle == GuidParseThrowStyle.None)
+ {
parseResult.SetFailure(ex);
return false;
}
- else {
+ else
+ {
throw;
}
}
//If we didn't parse enough characters, there's clearly an error.
- if (requiredLength != -1 && parsePos != null && (*parsePos) - currStart != requiredLength) {
+ if (requiredLength != -1 && parsePos != null && (*parsePos) - currStart != requiredLength)
+ {
parseResult.SetFailure(ParseFailureKind.Format, "Format_GuidInvalidChar");
return false;
}
return true;
}
- private static unsafe bool StringToLong(String str, ref int parsePos, int flags, out long result, ref GuidResult parseResult) {
- fixed(int * ppos = &parsePos) {
+ private static unsafe bool StringToLong(String str, ref int parsePos, int flags, out long result, ref GuidResult parseResult)
+ {
+ fixed (int* ppos = &parsePos)
+ {
return StringToLong(str, ppos, flags, out result, ref parseResult);
}
}
- private static unsafe bool StringToLong(String str, int* parsePos, int flags, out long result, ref GuidResult parseResult) {
+ private static unsafe bool StringToLong(String str, int* parsePos, int flags, out long result, ref GuidResult parseResult)
+ {
result = 0;
- try {
+ try
+ {
result = ParseNumbers.StringToLong(str, 16, flags, parsePos);
}
- catch (OverflowException ex) {
- if (parseResult.throwStyle == GuidParseThrowStyle.All) {
+ catch (OverflowException ex)
+ {
+ if (parseResult.throwStyle == GuidParseThrowStyle.All)
+ {
throw;
}
- else if (parseResult.throwStyle == GuidParseThrowStyle.AllButOverflow) {
- throw new FormatException(Environment.GetResourceString("Format_GuidUnrecognized"), ex);
+ else if (parseResult.throwStyle == GuidParseThrowStyle.AllButOverflow)
+ {
+ throw new FormatException(SR.Format_GuidUnrecognized, ex);
}
- else {
+ else
+ {
parseResult.SetFailure(ex);
return false;
}
}
- catch (Exception ex) {
- if (parseResult.throwStyle == GuidParseThrowStyle.None) {
+ catch (Exception ex)
+ {
+ if (parseResult.throwStyle == GuidParseThrowStyle.None)
+ {
parseResult.SetFailure(ex);
return false;
}
- else {
+ else
+ {
throw;
}
}
@@ -850,10 +966,10 @@ namespace System {
char curChar;
// Now get each char from str and if it is not whitespace add it to chArr
- for(int i = 0; i < str.Length; i++)
+ for (int i = 0; i < str.Length; i++)
{
curChar = str[i];
- if(!Char.IsWhiteSpace(curChar))
+ if (!Char.IsWhiteSpace(curChar))
{
chArr[newLength++] = curChar;
}
@@ -865,7 +981,7 @@ namespace System {
private static bool IsHexPrefix(String str, int i)
{
- if(str.Length > i+1 && str[i] == '0' && (Char.ToLower(str[i+1], CultureInfo.InvariantCulture) == 'x'))
+ if (str.Length > i + 1 && str[i] == '0' && (Char.ToLower(str[i + 1], CultureInfo.InvariantCulture) == 'x'))
return true;
else
return false;
@@ -879,7 +995,7 @@ namespace System {
g[0] = (byte)(_a);
g[1] = (byte)(_a >> 8);
- g[2] = (byte)(_a >> 16);
+ g[2] = (byte)(_a >> 16);
g[3] = (byte)(_a >> 24);
g[4] = (byte)(_b);
g[5] = (byte)(_b >> 8);
@@ -901,14 +1017,14 @@ namespace System {
// Returns the guid in "registry" format.
public override String ToString()
{
- return ToString("D",null);
+ return ToString("D", null);
}
public unsafe override int GetHashCode()
{
// Simply XOR all the bits of the GUID 32 bits at a time.
- fixed (int* ptr = &this._a)
- return ptr[0] ^ ptr[1] ^ ptr[2] ^ ptr[3];
+ fixed (int* ptr = &_a)
+ return ptr[0] ^ ptr[1] ^ ptr[2] ^ ptr[3];
}
// Returns true if and only if the guid represented
@@ -917,16 +1033,16 @@ namespace System {
{
Guid g;
// Check that o is a Guid first
- if(o == null || !(o is Guid))
+ if (o == null || !(o is Guid))
return false;
- else g = (Guid) o;
+ else g = (Guid)o;
// Now compare each of the elements
- if(g._a != _a)
+ if (g._a != _a)
return false;
- if(g._b != _b)
+ if (g._b != _b)
return false;
- if(g._c != _c)
+ if (g._c != _c)
return false;
if (g._d != _d)
return false;
@@ -951,11 +1067,11 @@ namespace System {
public bool Equals(Guid g)
{
// Now compare each of the elements
- if(g._a != _a)
+ if (g._a != _a)
return false;
- if(g._b != _b)
+ if (g._b != _b)
return false;
- if(g._c != _c)
+ if (g._c != _c)
return false;
if (g._d != _d)
return false;
@@ -977,64 +1093,80 @@ namespace System {
return true;
}
- private int GetResult(uint me, uint them) {
- if (me<them) {
+ private int GetResult(uint me, uint them)
+ {
+ if (me < them)
+ {
return -1;
}
return 1;
}
- public int CompareTo(Object value) {
- if (value == null) {
+ public int CompareTo(Object value)
+ {
+ if (value == null)
+ {
return 1;
}
- if (!(value is Guid)) {
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeGuid"), nameof(value));
+ if (!(value is Guid))
+ {
+ throw new ArgumentException(SR.Arg_MustBeGuid, nameof(value));
}
Guid g = (Guid)value;
- if (g._a!=this._a) {
- return GetResult((uint)this._a, (uint)g._a);
+ if (g._a != _a)
+ {
+ return GetResult((uint)_a, (uint)g._a);
}
- if (g._b!=this._b) {
- return GetResult((uint)this._b, (uint)g._b);
+ if (g._b != _b)
+ {
+ return GetResult((uint)_b, (uint)g._b);
}
- if (g._c!=this._c) {
- return GetResult((uint)this._c, (uint)g._c);
+ if (g._c != _c)
+ {
+ return GetResult((uint)_c, (uint)g._c);
}
- if (g._d!=this._d) {
- return GetResult((uint)this._d, (uint)g._d);
+ if (g._d != _d)
+ {
+ return GetResult((uint)_d, (uint)g._d);
}
- if (g._e!=this._e) {
- return GetResult((uint)this._e, (uint)g._e);
+ if (g._e != _e)
+ {
+ return GetResult((uint)_e, (uint)g._e);
}
- if (g._f!=this._f) {
- return GetResult((uint)this._f, (uint)g._f);
+ if (g._f != _f)
+ {
+ return GetResult((uint)_f, (uint)g._f);
}
- if (g._g!=this._g) {
- return GetResult((uint)this._g, (uint)g._g);
+ if (g._g != _g)
+ {
+ return GetResult((uint)_g, (uint)g._g);
}
- if (g._h!=this._h) {
- return GetResult((uint)this._h, (uint)g._h);
+ if (g._h != _h)
+ {
+ return GetResult((uint)_h, (uint)g._h);
}
- if (g._i!=this._i) {
- return GetResult((uint)this._i, (uint)g._i);
+ if (g._i != _i)
+ {
+ return GetResult((uint)_i, (uint)g._i);
}
- if (g._j!=this._j) {
- return GetResult((uint)this._j, (uint)g._j);
+ if (g._j != _j)
+ {
+ return GetResult((uint)_j, (uint)g._j);
}
- if (g._k!=this._k) {
- return GetResult((uint)this._k, (uint)g._k);
+ if (g._k != _k)
+ {
+ return GetResult((uint)_k, (uint)g._k);
}
return 0;
@@ -1042,48 +1174,59 @@ namespace System {
public int CompareTo(Guid value)
{
- if (value._a!=this._a) {
- return GetResult((uint)this._a, (uint)value._a);
+ if (value._a != _a)
+ {
+ return GetResult((uint)_a, (uint)value._a);
}
- if (value._b!=this._b) {
- return GetResult((uint)this._b, (uint)value._b);
+ if (value._b != _b)
+ {
+ return GetResult((uint)_b, (uint)value._b);
}
- if (value._c!=this._c) {
- return GetResult((uint)this._c, (uint)value._c);
+ if (value._c != _c)
+ {
+ return GetResult((uint)_c, (uint)value._c);
}
- if (value._d!=this._d) {
- return GetResult((uint)this._d, (uint)value._d);
+ if (value._d != _d)
+ {
+ return GetResult((uint)_d, (uint)value._d);
}
- if (value._e!=this._e) {
- return GetResult((uint)this._e, (uint)value._e);
+ if (value._e != _e)
+ {
+ return GetResult((uint)_e, (uint)value._e);
}
- if (value._f!=this._f) {
- return GetResult((uint)this._f, (uint)value._f);
+ if (value._f != _f)
+ {
+ return GetResult((uint)_f, (uint)value._f);
}
- if (value._g!=this._g) {
- return GetResult((uint)this._g, (uint)value._g);
+ if (value._g != _g)
+ {
+ return GetResult((uint)_g, (uint)value._g);
}
- if (value._h!=this._h) {
- return GetResult((uint)this._h, (uint)value._h);
+ if (value._h != _h)
+ {
+ return GetResult((uint)_h, (uint)value._h);
}
- if (value._i!=this._i) {
- return GetResult((uint)this._i, (uint)value._i);
+ if (value._i != _i)
+ {
+ return GetResult((uint)_i, (uint)value._i);
}
- if (value._j!=this._j) {
- return GetResult((uint)this._j, (uint)value._j);
+ if (value._j != _j)
+ {
+ return GetResult((uint)_j, (uint)value._j);
}
- if (value._k!=this._k) {
- return GetResult((uint)this._k, (uint)value._k);
+ if (value._k != _k)
+ {
+ return GetResult((uint)_k, (uint)value._k);
}
return 0;
@@ -1092,27 +1235,27 @@ namespace System {
public static bool operator ==(Guid a, Guid b)
{
// Now compare each of the elements
- if(a._a != b._a)
+ if (a._a != b._a)
return false;
- if(a._b != b._b)
+ if (a._b != b._b)
return false;
- if(a._c != b._c)
+ if (a._c != b._c)
return false;
- if(a._d != b._d)
+ if (a._d != b._d)
return false;
- if(a._e != b._e)
+ if (a._e != b._e)
return false;
- if(a._f != b._f)
+ if (a._f != b._f)
return false;
- if(a._g != b._g)
+ if (a._g != b._g)
return false;
- if(a._h != b._h)
+ if (a._h != b._h)
return false;
- if(a._i != b._i)
+ if (a._i != b._i)
return false;
- if(a._j != b._j)
+ if (a._j != b._j)
return false;
- if(a._k != b._k)
+ if (a._k != b._k)
return false;
return true;
@@ -1125,7 +1268,8 @@ namespace System {
// This will create a new guid. Since we've now decided that constructors should 0-init,
// we need a method that allows users to create a guid.
- public static Guid NewGuid() {
+ public static Guid NewGuid()
+ {
// CoCreateGuid should never return Guid.Empty, since it attempts to maintain some
// uniqueness guarantees. It should also never return a known GUID, but it's unclear
// how extensively it checks for known values.
@@ -1136,37 +1280,45 @@ namespace System {
return guid;
}
- public String ToString(String format) {
+ public String ToString(String format)
+ {
return ToString(format, null);
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static char HexToChar(int a)
{
a = a & 0xf;
- return (char) ((a > 9) ? a - 10 + 0x61 : a + 0x30);
+ return (char)((a > 9) ? a - 10 + 0x61 : a + 0x30);
}
- unsafe private static int HexsToChars(char* guidChars, int offset, int a, int b)
+ unsafe private static int HexsToChars(char* guidChars, int a, int b)
{
- return HexsToChars(guidChars, offset, a, b, false);
+ guidChars[0] = HexToChar(a >> 4);
+ guidChars[1] = HexToChar(a);
+
+ guidChars[2] = HexToChar(b >> 4);
+ guidChars[3] = HexToChar(b);
+
+ return 4;
}
- unsafe private static int HexsToChars(char* guidChars, int offset, int a, int b, bool hex)
+ unsafe private static int HexsToCharsHexOutput(char* guidChars, int a, int b)
{
- if (hex) {
- guidChars[offset++] = '0';
- guidChars[offset++] = 'x';
- }
- guidChars[offset++] = HexToChar(a>>4);
- guidChars[offset++] = HexToChar(a);
- if (hex) {
- guidChars[offset++] = ',';
- guidChars[offset++] = '0';
- guidChars[offset++] = 'x';
- }
- guidChars[offset++] = HexToChar(b>>4);
- guidChars[offset++] = HexToChar(b);
- return offset;
+ guidChars[0] = '0';
+ guidChars[1] = 'x';
+
+ guidChars[2] = HexToChar(a >> 4);
+ guidChars[3] = HexToChar(a);
+
+ guidChars[4] = ',';
+ guidChars[5] = '0';
+ guidChars[6] = 'x';
+
+ guidChars[7] = HexToChar(b >> 4);
+ guidChars[8] = HexToChar(b);
+
+ return 9;
}
// IFormattable interface
@@ -1181,41 +1333,53 @@ namespace System {
bool dash = true;
bool hex = false;
- if( format.Length != 1) {
+ if (format.Length != 1)
+ {
// all acceptable format strings are of length 1
- throw new FormatException(Environment.GetResourceString("Format_InvalidGuidFormatSpecification"));
+ throw new FormatException(SR.Format_InvalidGuidFormatSpecification);
}
-
+
char formatCh = format[0];
- if (formatCh == 'D' || formatCh == 'd') {
+ if (formatCh == 'D' || formatCh == 'd')
+ {
guidString = string.FastAllocateString(36);
- }
- else if (formatCh == 'N' || formatCh == 'n') {
+ }
+ else if (formatCh == 'N' || formatCh == 'n')
+ {
guidString = string.FastAllocateString(32);
dash = false;
}
- else if (formatCh == 'B' || formatCh == 'b') {
+ else if (formatCh == 'B' || formatCh == 'b')
+ {
guidString = string.FastAllocateString(38);
- unsafe {
- fixed (char* guidChars = guidString) {
+ unsafe
+ {
+ fixed (char* guidChars = guidString)
+ {
guidChars[offset++] = '{';
guidChars[37] = '}';
}
}
}
- else if (formatCh == 'P' || formatCh == 'p') {
+ else if (formatCh == 'P' || formatCh == 'p')
+ {
guidString = string.FastAllocateString(38);
- unsafe {
- fixed (char* guidChars = guidString) {
+ unsafe
+ {
+ fixed (char* guidChars = guidString)
+ {
guidChars[offset++] = '(';
guidChars[37] = ')';
}
}
}
- else if (formatCh == 'X' || formatCh == 'x') {
+ else if (formatCh == 'X' || formatCh == 'x')
+ {
guidString = string.FastAllocateString(68);
- unsafe {
- fixed (char* guidChars = guidString) {
+ unsafe
+ {
+ fixed (char* guidChars = guidString)
+ {
guidChars[offset++] = '{';
guidChars[67] = '}';
}
@@ -1223,51 +1387,56 @@ namespace System {
dash = false;
hex = true;
}
- else {
- throw new FormatException(Environment.GetResourceString("Format_InvalidGuidFormatSpecification"));
+ else
+ {
+ throw new FormatException(SR.Format_InvalidGuidFormatSpecification);
}
- unsafe {
- fixed (char* guidChars = guidString) {
- if (hex) {
+ unsafe
+ {
+ fixed (char* guidChars = guidString)
+ {
+ if (hex)
+ {
// {0xdddddddd,0xdddd,0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}}
guidChars[offset++] = '0';
guidChars[offset++] = 'x';
- offset = HexsToChars(guidChars, offset, _a >> 24, _a >> 16);
- offset = HexsToChars(guidChars, offset, _a >> 8, _a);
+ offset += HexsToChars(guidChars + offset, _a >> 24, _a >> 16);
+ offset += HexsToChars(guidChars + offset, _a >> 8, _a);
guidChars[offset++] = ',';
guidChars[offset++] = '0';
guidChars[offset++] = 'x';
- offset = HexsToChars(guidChars, offset, _b >> 8, _b);
+ offset += HexsToChars(guidChars + offset, _b >> 8, _b);
guidChars[offset++] = ',';
guidChars[offset++] = '0';
guidChars[offset++] = 'x';
- offset = HexsToChars(guidChars, offset, _c >> 8, _c);
+ offset += HexsToChars(guidChars + offset, _c >> 8, _c);
guidChars[offset++] = ',';
guidChars[offset++] = '{';
- offset = HexsToChars(guidChars, offset, _d, _e, true);
+ offset += HexsToCharsHexOutput(guidChars + offset, _d, _e);
guidChars[offset++] = ',';
- offset = HexsToChars(guidChars, offset, _f, _g, true);
+ offset += HexsToCharsHexOutput(guidChars + offset, _f, _g);
guidChars[offset++] = ',';
- offset = HexsToChars(guidChars, offset, _h, _i, true);
+ offset += HexsToCharsHexOutput(guidChars + offset, _h, _i);
guidChars[offset++] = ',';
- offset = HexsToChars(guidChars, offset, _j, _k, true);
+ offset += HexsToCharsHexOutput(guidChars + offset, _j, _k);
guidChars[offset++] = '}';
}
- else {
+ else
+ {
// [{|(]dddddddd[-]dddd[-]dddd[-]dddd[-]dddddddddddd[}|)]
- offset = HexsToChars(guidChars, offset, _a >> 24, _a >> 16);
- offset = HexsToChars(guidChars, offset, _a >> 8, _a);
+ offset += HexsToChars(guidChars + offset, _a >> 24, _a >> 16);
+ offset += HexsToChars(guidChars + offset, _a >> 8, _a);
if (dash) guidChars[offset++] = '-';
- offset = HexsToChars(guidChars, offset, _b >> 8, _b);
+ offset += HexsToChars(guidChars + offset, _b >> 8, _b);
if (dash) guidChars[offset++] = '-';
- offset = HexsToChars(guidChars, offset, _c >> 8, _c);
+ offset += HexsToChars(guidChars + offset, _c >> 8, _c);
if (dash) guidChars[offset++] = '-';
- offset = HexsToChars(guidChars, offset, _d, _e);
+ offset += HexsToChars(guidChars + offset, _d, _e);
if (dash) guidChars[offset++] = '-';
- offset = HexsToChars(guidChars, offset, _f, _g);
- offset = HexsToChars(guidChars, offset, _h, _i);
- offset = HexsToChars(guidChars, offset, _j, _k);
+ offset += HexsToChars(guidChars + offset, _f, _g);
+ offset += HexsToChars(guidChars + offset, _h, _i);
+ offset += HexsToChars(guidChars + offset, _j, _k);
}
}
}
diff --git a/src/mscorlib/corefx/System/HResults.cs b/src/mscorlib/src/System/HResults.cs
index fa0e24f00b..fa0e24f00b 100644
--- a/src/mscorlib/corefx/System/HResults.cs
+++ b/src/mscorlib/src/System/HResults.cs
diff --git a/src/mscorlib/src/System/IAppDomainPauseManager.cs b/src/mscorlib/src/System/IAppDomainPauseManager.cs
index cd3a9033de..8696e48664 100644
--- a/src/mscorlib/src/System/IAppDomainPauseManager.cs
+++ b/src/mscorlib/src/System/IAppDomainPauseManager.cs
@@ -11,15 +11,15 @@
**
=============================================================================*/
+using System;
+using System.Threading;
+using System.Security;
+using System.Diagnostics.Contracts;
+using System.Runtime.Versioning;
+using System.Runtime.CompilerServices;
+
namespace System
{
- using System;
- using System.Threading;
- using System.Security;
- using System.Diagnostics.Contracts;
- using System.Runtime.Versioning;
- using System.Runtime.CompilerServices;
-
internal class AppDomainPauseManager
{
public AppDomainPauseManager()
@@ -30,9 +30,9 @@ namespace System
static AppDomainPauseManager()
{
}
-
- static readonly AppDomainPauseManager instance = new AppDomainPauseManager();
-
+
+ private static readonly AppDomainPauseManager instance = new AppDomainPauseManager();
+
private static volatile bool isPaused;
internal static bool IsPaused
@@ -42,7 +42,7 @@ namespace System
internal static ManualResetEvent ResumeEvent
{
- get;
+ get;
set;
}
}
diff --git a/src/mscorlib/src/System/ICloneable.cs b/src/mscorlib/src/System/ICloneable.cs
deleted file mode 100644
index 49657c2765..0000000000
--- a/src/mscorlib/src/System/ICloneable.cs
+++ /dev/null
@@ -1,28 +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.
-
-/*============================================================
-**
-**
-** This interface is implemented by classes that support cloning.
-**
-===========================================================*/
-namespace System {
-
- using System;
- // Defines an interface indicating that an object may be cloned. Only objects
- // that implement ICloneable may be cloned. The interface defines a single
- // method which is called to create a clone of the object. Object defines a method
- // MemberwiseClone to support default clone operations.
- //
- public interface ICloneable
- {
- // Interface does not need to be marked with the serializable attribute
- // Make a new object which is a copy of the object instanced. This object may be either
- // deep copy or a shallow copy depending on the implementation of clone. The default
- // Object support for clone does a shallow copy.
- //
- Object Clone();
- }
-}
diff --git a/src/mscorlib/src/System/IO/BinaryReader.cs b/src/mscorlib/src/System/IO/BinaryReader.cs
index d973860472..54358d601d 100644
--- a/src/mscorlib/src/System/IO/BinaryReader.cs
+++ b/src/mscorlib/src/System/IO/BinaryReader.cs
@@ -13,54 +13,60 @@
**
**
============================================================*/
-namespace System.IO {
- using System;
- using System.Runtime;
- using System.Text;
- using System.Globalization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Security;
+using System;
+using System.Runtime;
+using System.Text;
+using System.Globalization;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Security;
+namespace System.IO
+{
public class BinaryReader : IDisposable
{
private const int MaxCharBytesSize = 128;
- private Stream m_stream;
- private byte[] m_buffer;
- private Decoder m_decoder;
- private byte[] m_charBytes;
- private char[] m_singleChar;
- private char[] m_charBuffer;
- private int m_maxCharsSize; // From MaxCharBytesSize & Encoding
+ private Stream m_stream;
+ private byte[] m_buffer;
+ private Decoder m_decoder;
+ private byte[] m_charBytes;
+ private char[] m_singleChar;
+ private char[] m_charBuffer;
+ private int m_maxCharsSize; // From MaxCharBytesSize & Encoding
// Performance optimization for Read() w/ Unicode. Speeds us up by ~40%
- private bool m_2BytesPerChar;
- private bool m_isMemoryStream; // "do we sit on MemoryStream?" for Read/ReadInt32 perf
- private bool m_leaveOpen;
+ private bool m_2BytesPerChar;
+ private bool m_isMemoryStream; // "do we sit on MemoryStream?" for Read/ReadInt32 perf
+ private bool m_leaveOpen;
- public BinaryReader(Stream input) : this(input, Encoding.UTF8, false) {
+ public BinaryReader(Stream input) : this(input, Encoding.UTF8, false)
+ {
}
- public BinaryReader(Stream input, Encoding encoding) : this(input, encoding, false) {
+ public BinaryReader(Stream input, Encoding encoding) : this(input, encoding, false)
+ {
}
- public BinaryReader(Stream input, Encoding encoding, bool leaveOpen) {
- if (input==null) {
+ public BinaryReader(Stream input, Encoding encoding, bool leaveOpen)
+ {
+ if (input == null)
+ {
throw new ArgumentNullException(nameof(input));
}
- if (encoding==null) {
+ if (encoding == null)
+ {
throw new ArgumentNullException(nameof(encoding));
}
if (!input.CanRead)
- throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotReadable"));
+ throw new ArgumentException(SR.Argument_StreamNotReadable);
Contract.EndContractBlock();
m_stream = input;
m_decoder = encoding.GetDecoder();
m_maxCharsSize = encoding.GetMaxCharCount(MaxCharBytesSize);
int minBufferSize = encoding.GetMaxByteCount(1); // max bytes per one char
- if (minBufferSize < 16)
+ if (minBufferSize < 16)
minBufferSize = 16;
m_buffer = new byte[minBufferSize];
// m_charBuffer and m_charBytes will be left null.
@@ -73,21 +79,26 @@ namespace System.IO {
m_isMemoryStream = (m_stream.GetType() == typeof(MemoryStream));
m_leaveOpen = leaveOpen;
- Debug.Assert(m_decoder!=null, "[BinaryReader.ctor]m_decoder!=null");
+ Debug.Assert(m_decoder != null, "[BinaryReader.ctor]m_decoder!=null");
}
- public virtual Stream BaseStream {
- get {
+ public virtual Stream BaseStream
+ {
+ get
+ {
return m_stream;
}
}
- public virtual void Close() {
+ public virtual void Close()
+ {
Dispose(true);
}
- protected virtual void Dispose(bool disposing) {
- if (disposing) {
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
Stream copyOfStream = m_stream;
m_stream = null;
if (copyOfStream != null && !m_leaveOpen)
@@ -106,10 +117,11 @@ namespace System.IO {
Dispose(true);
}
- public virtual int PeekChar() {
+ public virtual int PeekChar()
+ {
Contract.Ensures(Contract.Result<int>() >= -1);
- if (m_stream==null) __Error.FileNotOpen();
+ if (m_stream == null) __Error.FileNotOpen();
if (!m_stream.CanSeek)
return -1;
@@ -118,59 +130,70 @@ namespace System.IO {
m_stream.Position = origPos;
return ch;
}
-
- public virtual int Read() {
+
+ public virtual int Read()
+ {
Contract.Ensures(Contract.Result<int>() >= -1);
- if (m_stream==null) {
+ if (m_stream == null)
+ {
__Error.FileNotOpen();
}
return InternalReadOneChar();
}
- public virtual bool ReadBoolean(){
+ public virtual bool ReadBoolean()
+ {
FillBuffer(1);
- return (m_buffer[0]!=0);
+ return (m_buffer[0] != 0);
}
- public virtual byte ReadByte() {
+ public virtual byte ReadByte()
+ {
// Inlined to avoid some method call overhead with FillBuffer.
- if (m_stream==null) __Error.FileNotOpen();
+ if (m_stream == null) __Error.FileNotOpen();
int b = m_stream.ReadByte();
if (b == -1)
__Error.EndOfFile();
- return (byte) b;
+ return (byte)b;
}
[CLSCompliant(false)]
- public virtual sbyte ReadSByte() {
+ public virtual sbyte ReadSByte()
+ {
FillBuffer(1);
return (sbyte)(m_buffer[0]);
}
- public virtual char ReadChar() {
+ public virtual char ReadChar()
+ {
int value = Read();
- if (value==-1) {
+ if (value == -1)
+ {
__Error.EndOfFile();
}
return (char)value;
}
- public virtual short ReadInt16() {
+ public virtual short ReadInt16()
+ {
FillBuffer(2);
return (short)(m_buffer[0] | m_buffer[1] << 8);
}
[CLSCompliant(false)]
- public virtual ushort ReadUInt16(){
+ public virtual ushort ReadUInt16()
+ {
FillBuffer(2);
return (ushort)(m_buffer[0] | m_buffer[1] << 8);
}
- public virtual int ReadInt32() {
- if (m_isMemoryStream) {
- if (m_stream==null) __Error.FileNotOpen();
+ public virtual int ReadInt32()
+ {
+ if (m_isMemoryStream)
+ {
+ if (m_stream == null) __Error.FileNotOpen();
// read directly from MemoryStream buffer
MemoryStream mStream = m_stream as MemoryStream;
Debug.Assert(mStream != null, "m_stream as MemoryStream != null");
@@ -185,22 +208,25 @@ namespace System.IO {
}
[CLSCompliant(false)]
- public virtual uint ReadUInt32() {
+ public virtual uint ReadUInt32()
+ {
FillBuffer(4);
return (uint)(m_buffer[0] | m_buffer[1] << 8 | m_buffer[2] << 16 | m_buffer[3] << 24);
}
- public virtual long ReadInt64() {
+ public virtual long ReadInt64()
+ {
FillBuffer(8);
uint lo = (uint)(m_buffer[0] | m_buffer[1] << 8 |
m_buffer[2] << 16 | m_buffer[3] << 24);
uint hi = (uint)(m_buffer[4] | m_buffer[5] << 8 |
m_buffer[6] << 16 | m_buffer[7] << 24);
- return (long) ((ulong)hi) << 32 | lo;
+ return (long)((ulong)hi) << 32 | lo;
}
[CLSCompliant(false)]
- public virtual ulong ReadUInt64() {
+ public virtual ulong ReadUInt64()
+ {
FillBuffer(8);
uint lo = (uint)(m_buffer[0] | m_buffer[1] << 8 |
m_buffer[2] << 16 | m_buffer[3] << 24);
@@ -209,13 +235,15 @@ namespace System.IO {
return ((ulong)hi) << 32 | lo;
}
- public virtual unsafe float ReadSingle() {
+ public virtual unsafe float ReadSingle()
+ {
FillBuffer(4);
uint tmpBuffer = (uint)(m_buffer[0] | m_buffer[1] << 8 | m_buffer[2] << 16 | m_buffer[3] << 24);
return *((float*)&tmpBuffer);
}
- public virtual unsafe double ReadDouble() {
+ public virtual unsafe double ReadDouble()
+ {
FillBuffer(8);
uint lo = (uint)(m_buffer[0] | m_buffer[1] << 8 |
m_buffer[2] << 16 | m_buffer[3] << 24);
@@ -226,18 +254,22 @@ namespace System.IO {
return *((double*)&tmpBuffer);
}
- public virtual decimal ReadDecimal() {
+ public virtual decimal ReadDecimal()
+ {
FillBuffer(16);
- try {
+ try
+ {
return Decimal.ToDecimal(m_buffer);
}
- catch (ArgumentException e) {
+ catch (ArgumentException e)
+ {
// ReadDecimal cannot leak out ArgumentException
- throw new IOException(Environment.GetResourceString("Arg_DecBitCtor"), e);
+ throw new IOException(SR.Arg_DecBitCtor, e);
}
}
- public virtual String ReadString() {
+ public virtual String ReadString()
+ {
Contract.Ensures(Contract.Result<String>() != null);
if (m_stream == null)
@@ -251,29 +283,34 @@ namespace System.IO {
// Length of the string in bytes, not chars
stringLength = Read7BitEncodedInt();
- if (stringLength<0) {
- throw new IOException(Environment.GetResourceString("IO.IO_InvalidStringLen_Len", stringLength));
+ if (stringLength < 0)
+ {
+ throw new IOException(SR.Format(SR.IO_InvalidStringLen_Len, stringLength));
}
- if (stringLength==0) {
+ if (stringLength == 0)
+ {
return String.Empty;
}
- if (m_charBytes==null) {
- m_charBytes = new byte[MaxCharBytesSize];
+ if (m_charBytes == null)
+ {
+ m_charBytes = new byte[MaxCharBytesSize];
}
-
- if (m_charBuffer == null) {
+
+ if (m_charBuffer == null)
+ {
m_charBuffer = new char[m_maxCharsSize];
}
-
- StringBuilder sb = null;
+
+ StringBuilder sb = null;
do
{
- readLength = ((stringLength - currPos)>MaxCharBytesSize)?MaxCharBytesSize:(stringLength - currPos);
+ readLength = ((stringLength - currPos) > MaxCharBytesSize) ? MaxCharBytesSize : (stringLength - currPos);
n = m_stream.Read(m_charBytes, 0, readLength);
- if (n==0) {
+ if (n == 0)
+ {
__Error.EndOfFile();
}
@@ -285,38 +322,43 @@ namespace System.IO {
if (sb == null)
sb = StringBuilderCache.Acquire(stringLength); // Actual string length in chars may be smaller.
sb.Append(m_charBuffer, 0, charsRead);
- currPos +=n;
-
- } while (currPos<stringLength);
+ currPos += n;
+ } while (currPos < stringLength);
return StringBuilderCache.GetStringAndRelease(sb);
}
- public virtual int Read(char[] buffer, int index, int count) {
- if (buffer==null) {
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ public virtual int Read(char[] buffer, int index, int count)
+ {
+ if (buffer == null)
+ {
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
}
- if (index < 0) {
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (index < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
}
- if (count < 0) {
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (count < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
}
- if (buffer.Length - index < count) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ if (buffer.Length - index < count)
+ {
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
}
Contract.Ensures(Contract.Result<int>() >= 0);
Contract.Ensures(Contract.Result<int>() <= count);
Contract.EndContractBlock();
- if (m_stream==null)
+ if (m_stream == null)
__Error.FileNotOpen();
// SafeCritical: index and count have already been verified to be a valid range for the buffer
return InternalReadChars(buffer, index, count);
}
- private int InternalReadChars(char[] buffer, int index, int count) {
+ private int InternalReadChars(char[] buffer, int index, int count)
+ {
Contract.Requires(buffer != null);
Contract.Requires(index >= 0 && count >= 0);
Debug.Assert(m_stream != null);
@@ -324,11 +366,13 @@ namespace System.IO {
int numBytes = 0;
int charsRemaining = count;
- if (m_charBytes==null) {
+ if (m_charBytes == null)
+ {
m_charBytes = new byte[MaxCharBytesSize];
}
- while (charsRemaining > 0) {
+ while (charsRemaining > 0)
+ {
int charsRead = 0;
// We really want to know what the minimum number of bytes per char
// is for our encoding. Otherwise for UnicodeEncoding we'd have to
@@ -337,7 +381,8 @@ namespace System.IO {
// special case for DecoderNLS subclasses when there is a hanging byte from the previous loop
DecoderNLS decoder = m_decoder as DecoderNLS;
- if (decoder != null && decoder.HasState && numBytes > 1) {
+ if (decoder != null && decoder.HasState && numBytes > 1)
+ {
numBytes -= 1;
}
@@ -360,10 +405,11 @@ namespace System.IO {
else
{
numBytes = m_stream.Read(m_charBytes, 0, numBytes);
- byteBuffer = m_charBytes;
+ byteBuffer = m_charBytes;
}
- if (numBytes == 0) {
+ if (numBytes == 0)
+ {
return (count - charsRemaining);
}
@@ -390,7 +436,7 @@ namespace System.IO {
}
charsRemaining -= charsRead;
- index+=charsRead;
+ index += charsRead;
}
// this should never fail
@@ -401,7 +447,8 @@ namespace System.IO {
return (count - charsRemaining);
}
- private int InternalReadOneChar() {
+ private int InternalReadOneChar()
+ {
// I know having a separate InternalReadOneChar method seems a little
// redundant, but this makes a scenario like the security parser code
// 20% faster, in addition to the optimizations for UnicodeEncoding I
@@ -409,18 +456,21 @@ namespace System.IO {
int charsRead = 0;
int numBytes = 0;
long posSav = posSav = 0;
-
+
if (m_stream.CanSeek)
posSav = m_stream.Position;
- if (m_charBytes==null) {
+ if (m_charBytes == null)
+ {
m_charBytes = new byte[MaxCharBytesSize];
}
- if (m_singleChar==null) {
+ if (m_singleChar == null)
+ {
m_singleChar = new char[1];
}
- while (charsRead == 0) {
+ while (charsRead == 0)
+ {
// We really want to know what the minimum number of bytes per char
// is for our encoding. Otherwise for UnicodeEncoding we'd have to
// do ~1+log(n) reads to read n characters.
@@ -428,25 +478,27 @@ namespace System.IO {
numBytes = m_2BytesPerChar ? 2 : 1;
int r = m_stream.ReadByte();
- m_charBytes[0] = (byte) r;
+ m_charBytes[0] = (byte)r;
if (r == -1)
numBytes = 0;
- if (numBytes == 2) {
+ if (numBytes == 2)
+ {
r = m_stream.ReadByte();
- m_charBytes[1] = (byte) r;
+ m_charBytes[1] = (byte)r;
if (r == -1)
numBytes = 1;
}
- if (numBytes==0) {
+ if (numBytes == 0)
+ {
// Console.WriteLine("Found no bytes. We're outta here.");
return -1;
}
Debug.Assert(numBytes == 1 || numBytes == 2, "BinaryReader::InternalReadOneChar assumes it's reading one or 2 bytes only.");
- try {
-
+ try
+ {
charsRead = m_decoder.GetChars(m_charBytes, 0, numBytes, m_singleChar, 0);
}
catch
@@ -468,65 +520,74 @@ namespace System.IO {
return m_singleChar[0];
}
- public virtual char[] ReadChars(int count) {
- if (count<0) {
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ public virtual char[] ReadChars(int count)
+ {
+ if (count < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.Ensures(Contract.Result<char[]>() != null);
Contract.Ensures(Contract.Result<char[]>().Length <= count);
Contract.EndContractBlock();
- if (m_stream == null) {
+ if (m_stream == null)
+ {
__Error.FileNotOpen();
}
- if (count == 0) {
- return EmptyArray<Char>.Value;
+ if (count == 0)
+ {
+ return Array.Empty<Char>();
}
// SafeCritical: we own the chars buffer, and therefore can guarantee that the index and count are valid
char[] chars = new char[count];
int n = InternalReadChars(chars, 0, count);
- if (n!=count) {
+ if (n != count)
+ {
char[] copy = new char[n];
- Buffer.InternalBlockCopy(chars, 0, copy, 0, 2*n); // sizeof(char)
+ Buffer.InternalBlockCopy(chars, 0, copy, 0, 2 * n); // sizeof(char)
chars = copy;
}
return chars;
}
- public virtual int Read(byte[] buffer, int index, int count) {
- if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ public virtual int Read(byte[] buffer, int index, int count)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.Ensures(Contract.Result<int>() >= 0);
Contract.Ensures(Contract.Result<int>() <= count);
Contract.EndContractBlock();
- if (m_stream==null) __Error.FileNotOpen();
+ if (m_stream == null) __Error.FileNotOpen();
return m_stream.Read(buffer, index, count);
}
- public virtual byte[] ReadBytes(int count) {
- if (count < 0) throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ public virtual byte[] ReadBytes(int count)
+ {
+ if (count < 0) throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.Ensures(Contract.Result<byte[]>() != null);
Contract.Ensures(Contract.Result<byte[]>().Length <= Contract.OldValue(count));
Contract.EndContractBlock();
- if (m_stream==null) __Error.FileNotOpen();
+ if (m_stream == null) __Error.FileNotOpen();
- if (count == 0) {
- return EmptyArray<Byte>.Value;
+ if (count == 0)
+ {
+ return Array.Empty<Byte>();
}
byte[] result = new byte[count];
int numRead = 0;
- do {
+ do
+ {
int n = m_stream.Read(result, numRead, count);
if (n == 0)
break;
@@ -534,7 +595,8 @@ namespace System.IO {
count -= n;
} while (count > 0);
- if (numRead != result.Length) {
+ if (numRead != result.Length)
+ {
// Trim array. This should happen on EOF & possibly net streams.
byte[] copy = new byte[numRead];
Buffer.InternalBlockCopy(result, 0, copy, 0, numRead);
@@ -544,46 +606,53 @@ namespace System.IO {
return result;
}
- protected virtual void FillBuffer(int numBytes) {
- if (m_buffer != null && (numBytes < 0 || numBytes > m_buffer.Length)) {
- throw new ArgumentOutOfRangeException(nameof(numBytes), Environment.GetResourceString("ArgumentOutOfRange_BinaryReaderFillBuffer"));
+ protected virtual void FillBuffer(int numBytes)
+ {
+ if (m_buffer != null && (numBytes < 0 || numBytes > m_buffer.Length))
+ {
+ throw new ArgumentOutOfRangeException(nameof(numBytes), SR.ArgumentOutOfRange_BinaryReaderFillBuffer);
}
- int bytesRead=0;
+ int bytesRead = 0;
int n = 0;
- if (m_stream==null) __Error.FileNotOpen();
+ if (m_stream == null) __Error.FileNotOpen();
// Need to find a good threshold for calling ReadByte() repeatedly
// vs. calling Read(byte[], int, int) for both buffered & unbuffered
// streams.
- if (numBytes==1) {
+ if (numBytes == 1)
+ {
n = m_stream.ReadByte();
- if (n==-1)
+ if (n == -1)
__Error.EndOfFile();
m_buffer[0] = (byte)n;
return;
}
- do {
- n = m_stream.Read(m_buffer, bytesRead, numBytes-bytesRead);
- if (n==0) {
+ do
+ {
+ n = m_stream.Read(m_buffer, bytesRead, numBytes - bytesRead);
+ if (n == 0)
+ {
__Error.EndOfFile();
}
- bytesRead+=n;
- } while (bytesRead<numBytes);
+ bytesRead += n;
+ } while (bytesRead < numBytes);
}
- internal protected int Read7BitEncodedInt() {
+ internal protected int Read7BitEncodedInt()
+ {
// Read out an Int32 7 bits at a time. The high bit
// of the byte when on means to continue reading more bytes.
int count = 0;
int shift = 0;
byte b;
- do {
+ do
+ {
// Check for a corrupted stream. Read a max of 5 bytes.
// In a future version, add a DataFormatException.
if (shift == 5 * 7) // 5 bytes max per Int32, shift += 7
- throw new FormatException(Environment.GetResourceString("Format_Bad7BitInt32"));
+ throw new FormatException(SR.Format_Bad7BitInt32);
// ReadByte handles end of stream cases for us.
b = ReadByte();
diff --git a/src/mscorlib/src/System/IO/BinaryWriter.cs b/src/mscorlib/src/System/IO/BinaryWriter.cs
index b6c562534c..3d9839f46e 100644
--- a/src/mscorlib/src/System/IO/BinaryWriter.cs
+++ b/src/mscorlib/src/System/IO/BinaryWriter.cs
@@ -13,6 +13,7 @@
**
**
===========================================================*/
+
using System;
using System.Runtime;
using System.Runtime.Serialization;
@@ -20,7 +21,8 @@ using System.Text;
using System.Diagnostics;
using System.Diagnostics.Contracts;
-namespace System.IO {
+namespace System.IO
+{
// This abstract base class represents a writer that can write
// primitives to an arbitrary stream. A subclass can override methods to
// give unique encodings.
@@ -29,7 +31,7 @@ namespace System.IO {
public class BinaryWriter : IDisposable
{
public static readonly BinaryWriter Null = new BinaryWriter();
-
+
protected Stream OutStream;
private byte[] _buffer; // temp space for writing primitives to.
private Encoding _encoding;
@@ -42,7 +44,7 @@ namespace System.IO {
private byte[] _largeByteBuffer; // temp space for writing chars.
private int _maxChars; // max # of chars we can put in _largeByteBuffer
// Size should be around the max number of chars/string * Encoding's max bytes/char
- private const int LargeByteBufferSize = 256;
+ private const int LargeByteBufferSize = 256;
// Protected default constructor that sets the output stream
// to a null stream (a bit bucket).
@@ -53,7 +55,7 @@ namespace System.IO {
_encoding = EncodingCache.UTF8NoBOM;
_encoder = _encoding.GetEncoder();
}
-
+
public BinaryWriter(Stream output) : this(output, EncodingCache.UTF8NoBOM, false)
{
}
@@ -64,21 +66,21 @@ namespace System.IO {
public BinaryWriter(Stream output, Encoding encoding, bool leaveOpen)
{
- if (output==null)
+ if (output == null)
throw new ArgumentNullException(nameof(output));
- if (encoding==null)
+ if (encoding == null)
throw new ArgumentNullException(nameof(encoding));
if (!output.CanWrite)
- throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotWritable"));
+ throw new ArgumentException(SR.Argument_StreamNotWritable);
Contract.EndContractBlock();
-
+
OutStream = output;
_buffer = new byte[16];
_encoding = encoding;
_encoder = _encoding.GetEncoder();
_leaveOpen = leaveOpen;
}
-
+
// Closes this writer and releases any system resources associated with the
// writer. Following a call to Close, any operations on the writer
// may raise exceptions.
@@ -89,7 +91,8 @@ namespace System.IO {
protected virtual void Dispose(bool disposing)
{
- if (disposing) {
+ if (disposing)
+ {
if (_leaveOpen)
OutStream.Flush();
else
@@ -101,54 +104,57 @@ namespace System.IO {
{
Dispose(true);
}
-
+
/*
* Returns the stream associate with the writer. It flushes all pending
* writes before returning. All subclasses should override Flush to
* ensure that all buffered data is sent to the stream.
*/
- public virtual Stream BaseStream {
- get {
+ public virtual Stream BaseStream
+ {
+ get
+ {
Flush();
return OutStream;
}
}
-
+
// Clears all buffers for this writer and causes any buffered data to be
// written to the underlying device.
- public virtual void Flush()
+ public virtual void Flush()
{
OutStream.Flush();
}
-
+
public virtual long Seek(int offset, SeekOrigin origin)
{
return OutStream.Seek(offset, origin);
}
-
+
// Writes a boolean to this stream. A single byte is written to the stream
// with the value 0 representing false or the value 1 representing true.
//
- public virtual void Write(bool value) {
- _buffer[0] = (byte) (value ? 1 : 0);
+ public virtual void Write(bool value)
+ {
+ _buffer[0] = (byte)(value ? 1 : 0);
OutStream.Write(_buffer, 0, 1);
}
-
+
// Writes a byte to this stream. The current position of the stream is
// advanced by one.
//
- public virtual void Write(byte value)
+ public virtual void Write(byte value)
{
OutStream.WriteByte(value);
}
-
+
// Writes a signed byte to this stream. The current position of the stream
// is advanced by one.
//
[CLSCompliant(false)]
- public virtual void Write(sbyte value)
+ public virtual void Write(sbyte value)
{
- OutStream.WriteByte((byte) value);
+ OutStream.WriteByte((byte)value);
}
// Writes a byte array to this stream.
@@ -156,46 +162,50 @@ namespace System.IO {
// This default implementation calls the Write(Object, int, int)
// method to write the byte array.
//
- public virtual void Write(byte[] buffer) {
+ public virtual void Write(byte[] buffer)
+ {
if (buffer == null)
throw new ArgumentNullException(nameof(buffer));
Contract.EndContractBlock();
OutStream.Write(buffer, 0, buffer.Length);
}
-
+
// Writes a section of a byte array to this stream.
//
// This default implementation calls the Write(Object, int, int)
// method to write the byte array.
//
- public virtual void Write(byte[] buffer, int index, int count) {
+ public virtual void Write(byte[] buffer, int index, int count)
+ {
OutStream.Write(buffer, index, count);
}
-
-
+
+
// Writes a character to this stream. The current position of the stream is
// advanced by two.
// Note this method cannot handle surrogates properly in UTF-8.
//
- public unsafe virtual void Write(char ch) {
+ public unsafe virtual void Write(char ch)
+ {
if (Char.IsSurrogate(ch))
- throw new ArgumentException(Environment.GetResourceString("Arg_SurrogatesNotAllowedAsSingleChar"));
+ throw new ArgumentException(SR.Arg_SurrogatesNotAllowedAsSingleChar);
Contract.EndContractBlock();
Debug.Assert(_encoding.GetMaxByteCount(1) <= 16, "_encoding.GetMaxByteCount(1) <= 16)");
int numBytes = 0;
- fixed(byte * pBytes = &_buffer[0]) {
+ fixed (byte* pBytes = &_buffer[0])
+ {
numBytes = _encoder.GetBytes(&ch, 1, pBytes, _buffer.Length, flush: true);
}
OutStream.Write(_buffer, 0, numBytes);
}
-
+
// Writes a character array to this stream.
//
// This default implementation calls the Write(Object, int, int)
// method to write the character array.
//
- public virtual void Write(char[] chars)
+ public virtual void Write(char[] chars)
{
if (chars == null)
throw new ArgumentNullException(nameof(chars));
@@ -204,49 +214,49 @@ namespace System.IO {
byte[] bytes = _encoding.GetBytes(chars, 0, chars.Length);
OutStream.Write(bytes, 0, bytes.Length);
}
-
+
// Writes a section of a character array to this stream.
//
// This default implementation calls the Write(Object, int, int)
// method to write the character array.
//
- public virtual void Write(char[] chars, int index, int count)
+ public virtual void Write(char[] chars, int index, int count)
{
byte[] bytes = _encoding.GetBytes(chars, index, count);
OutStream.Write(bytes, 0, bytes.Length);
}
-
-
+
+
// Writes a double to this stream. The current position of the stream is
// advanced by eight.
//
public unsafe virtual void Write(double value)
{
- ulong TmpValue = *(ulong *)&value;
- _buffer[0] = (byte) TmpValue;
- _buffer[1] = (byte) (TmpValue >> 8);
- _buffer[2] = (byte) (TmpValue >> 16);
- _buffer[3] = (byte) (TmpValue >> 24);
- _buffer[4] = (byte) (TmpValue >> 32);
- _buffer[5] = (byte) (TmpValue >> 40);
- _buffer[6] = (byte) (TmpValue >> 48);
- _buffer[7] = (byte) (TmpValue >> 56);
+ ulong TmpValue = *(ulong*)&value;
+ _buffer[0] = (byte)TmpValue;
+ _buffer[1] = (byte)(TmpValue >> 8);
+ _buffer[2] = (byte)(TmpValue >> 16);
+ _buffer[3] = (byte)(TmpValue >> 24);
+ _buffer[4] = (byte)(TmpValue >> 32);
+ _buffer[5] = (byte)(TmpValue >> 40);
+ _buffer[6] = (byte)(TmpValue >> 48);
+ _buffer[7] = (byte)(TmpValue >> 56);
OutStream.Write(_buffer, 0, 8);
}
public virtual void Write(decimal value)
{
- Decimal.GetBytes(value,_buffer);
+ Decimal.GetBytes(value, _buffer);
OutStream.Write(_buffer, 0, 16);
}
-
+
// Writes a two-byte signed integer to this stream. The current position of
// the stream is advanced by two.
//
public virtual void Write(short value)
{
- _buffer[0] = (byte) value;
- _buffer[1] = (byte) (value >> 8);
+ _buffer[0] = (byte)value;
+ _buffer[1] = (byte)(value >> 8);
OutStream.Write(_buffer, 0, 2);
}
@@ -256,20 +266,20 @@ namespace System.IO {
[CLSCompliant(false)]
public virtual void Write(ushort value)
{
- _buffer[0] = (byte) value;
- _buffer[1] = (byte) (value >> 8);
+ _buffer[0] = (byte)value;
+ _buffer[1] = (byte)(value >> 8);
OutStream.Write(_buffer, 0, 2);
}
-
+
// Writes a four-byte signed integer to this stream. The current position
// of the stream is advanced by four.
//
public virtual void Write(int value)
{
- _buffer[0] = (byte) value;
- _buffer[1] = (byte) (value >> 8);
- _buffer[2] = (byte) (value >> 16);
- _buffer[3] = (byte) (value >> 24);
+ _buffer[0] = (byte)value;
+ _buffer[1] = (byte)(value >> 8);
+ _buffer[2] = (byte)(value >> 16);
+ _buffer[3] = (byte)(value >> 24);
OutStream.Write(_buffer, 0, 4);
}
@@ -279,26 +289,26 @@ namespace System.IO {
[CLSCompliant(false)]
public virtual void Write(uint value)
{
- _buffer[0] = (byte) value;
- _buffer[1] = (byte) (value >> 8);
- _buffer[2] = (byte) (value >> 16);
- _buffer[3] = (byte) (value >> 24);
+ _buffer[0] = (byte)value;
+ _buffer[1] = (byte)(value >> 8);
+ _buffer[2] = (byte)(value >> 16);
+ _buffer[3] = (byte)(value >> 24);
OutStream.Write(_buffer, 0, 4);
}
-
+
// Writes an eight-byte signed integer to this stream. The current position
// of the stream is advanced by eight.
//
public virtual void Write(long value)
{
- _buffer[0] = (byte) value;
- _buffer[1] = (byte) (value >> 8);
- _buffer[2] = (byte) (value >> 16);
- _buffer[3] = (byte) (value >> 24);
- _buffer[4] = (byte) (value >> 32);
- _buffer[5] = (byte) (value >> 40);
- _buffer[6] = (byte) (value >> 48);
- _buffer[7] = (byte) (value >> 56);
+ _buffer[0] = (byte)value;
+ _buffer[1] = (byte)(value >> 8);
+ _buffer[2] = (byte)(value >> 16);
+ _buffer[3] = (byte)(value >> 24);
+ _buffer[4] = (byte)(value >> 32);
+ _buffer[5] = (byte)(value >> 40);
+ _buffer[6] = (byte)(value >> 48);
+ _buffer[7] = (byte)(value >> 56);
OutStream.Write(_buffer, 0, 8);
}
@@ -308,46 +318,47 @@ namespace System.IO {
[CLSCompliant(false)]
public virtual void Write(ulong value)
{
- _buffer[0] = (byte) value;
- _buffer[1] = (byte) (value >> 8);
- _buffer[2] = (byte) (value >> 16);
- _buffer[3] = (byte) (value >> 24);
- _buffer[4] = (byte) (value >> 32);
- _buffer[5] = (byte) (value >> 40);
- _buffer[6] = (byte) (value >> 48);
- _buffer[7] = (byte) (value >> 56);
+ _buffer[0] = (byte)value;
+ _buffer[1] = (byte)(value >> 8);
+ _buffer[2] = (byte)(value >> 16);
+ _buffer[3] = (byte)(value >> 24);
+ _buffer[4] = (byte)(value >> 32);
+ _buffer[5] = (byte)(value >> 40);
+ _buffer[6] = (byte)(value >> 48);
+ _buffer[7] = (byte)(value >> 56);
OutStream.Write(_buffer, 0, 8);
}
-
+
// Writes a float to this stream. The current position of the stream is
// advanced by four.
//
public unsafe virtual void Write(float value)
{
- uint TmpValue = *(uint *)&value;
- _buffer[0] = (byte) TmpValue;
- _buffer[1] = (byte) (TmpValue >> 8);
- _buffer[2] = (byte) (TmpValue >> 16);
- _buffer[3] = (byte) (TmpValue >> 24);
+ uint TmpValue = *(uint*)&value;
+ _buffer[0] = (byte)TmpValue;
+ _buffer[1] = (byte)(TmpValue >> 8);
+ _buffer[2] = (byte)(TmpValue >> 16);
+ _buffer[3] = (byte)(TmpValue >> 24);
OutStream.Write(_buffer, 0, 4);
}
-
-
+
+
// Writes a length-prefixed string to this stream in the BinaryWriter's
// current Encoding. This method first writes the length of the string as
// a four-byte unsigned integer, and then writes that many characters
// to the stream.
//
- public unsafe virtual void Write(String value)
+ public unsafe virtual void Write(String value)
{
- if (value==null)
+ if (value == null)
throw new ArgumentNullException(nameof(value));
Contract.EndContractBlock();
int len = _encoding.GetByteCount(value);
Write7BitEncodedInt(len);
- if (_largeByteBuffer == null) {
+ if (_largeByteBuffer == null)
+ {
_largeByteBuffer = new byte[LargeByteBufferSize];
_maxChars = _largeByteBuffer.Length / _encoding.GetMaxByteCount(1);
}
@@ -358,7 +369,8 @@ namespace System.IO {
_encoding.GetBytes(value, 0, value.Length, _largeByteBuffer, 0);
OutStream.Write(_largeByteBuffer, 0, len);
}
- else {
+ else
+ {
// Aggressively try to not allocate memory in this loop for
// runtime performance reasons. Use an Encoder to write out
// the string correctly (handling surrogates crossing buffer
@@ -368,7 +380,8 @@ namespace System.IO {
#if _DEBUG
int totalBytes = 0;
#endif
- while (numLeft > 0) {
+ while (numLeft > 0)
+ {
// Figure out how many chars to process this round.
int charCount = (numLeft > _maxChars) ? _maxChars : numLeft;
int byteLen;
@@ -389,7 +402,7 @@ namespace System.IO {
}
#if _DEBUG
totalBytes += byteLen;
- Debug.Assert (totalBytes <= len && byteLen <= _largeByteBuffer.Length, "BinaryWriter::Write(String) - More bytes encoded than expected!");
+ Debug.Assert(totalBytes <= len && byteLen <= _largeByteBuffer.Length, "BinaryWriter::Write(String) - More bytes encoded than expected!");
#endif
OutStream.Write(_largeByteBuffer, 0, byteLen);
charStart += charCount;
@@ -400,13 +413,15 @@ namespace System.IO {
#endif
}
}
-
- protected void Write7BitEncodedInt(int value) {
+
+ protected void Write7BitEncodedInt(int value)
+ {
// Write out an int 7 bits at a time. The high bit of the byte,
// when on, tells reader to continue reading more bytes.
- uint v = (uint) value; // support negative numbers
- while (v >= 0x80) {
- Write((byte) (v | 0x80));
+ uint v = (uint)value; // support negative numbers
+ while (v >= 0x80)
+ {
+ Write((byte)(v | 0x80));
v >>= 7;
}
Write((byte)v);
diff --git a/src/mscorlib/src/System/IO/Directory.cs b/src/mscorlib/src/System/IO/Directory.cs
index 88a669a971..6417207d38 100644
--- a/src/mscorlib/src/System/IO/Directory.cs
+++ b/src/mscorlib/src/System/IO/Directory.cs
@@ -25,8 +25,8 @@ using System.Diagnostics.Contracts;
namespace System.IO
{
- internal static class Directory {
-
+ internal static class Directory
+ {
// Private class that holds search data that is passed around
// in the heap based stack recursion
internal sealed class SearchData
@@ -55,7 +55,7 @@ namespace System.IO
if (searchPattern == null)
throw new ArgumentNullException(nameof(searchPattern));
if ((searchOption != SearchOption.TopDirectoryOnly) && (searchOption != SearchOption.AllDirectories))
- throw new ArgumentOutOfRangeException(nameof(searchOption), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(searchOption), SR.ArgumentOutOfRange_Enum);
Contract.Ensures(Contract.Result<IEnumerable<String>>() != null);
Contract.EndContractBlock();
@@ -85,8 +85,9 @@ namespace System.IO
}
#endif // PLATFORM_UNIX
- internal static String InternalGetDirectoryRoot(String path) {
- if (path == null) return null;
+ internal static String InternalGetDirectoryRoot(String path)
+ {
+ if (path == null) return null;
return path.Substring(0, PathInternal.GetRootLength(path));
}
@@ -116,10 +117,10 @@ namespace System.IO
buffer.Length = (int)result;
-#if !PLATFORM_UNIX
+#if PLATFORM_WINDOWS
if (buffer.Contains('~'))
return Path.GetFullPath(buffer.ToString());
-#endif
+#endif // PLATFORM_WINDOWS
return buffer.ToString();
}
@@ -131,16 +132,17 @@ namespace System.IO
public static void SetCurrentDirectory(String path)
{
- if (path==null)
+ if (path == null)
throw new ArgumentNullException(nameof(path));
- if (path.Length==0)
- throw new ArgumentException(Environment.GetResourceString("Argument_PathEmpty"));
+ if (path.Length == 0)
+ throw new ArgumentException(SR.Argument_PathEmpty);
if (path.Length >= Path.MaxPath)
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
+ throw new PathTooLongException(SR.IO_PathTooLong);
String fulldestDirName = Path.GetFullPath(path);
-
- if (!Win32Native.SetCurrentDirectory(fulldestDirName)) {
+
+ if (!Win32Native.SetCurrentDirectory(fulldestDirName))
+ {
// If path doesn't exist, this sets last error to 2 (File
// not Found). LEGACY: This may potentially have worked correctly
// on Win9x, maybe.
diff --git a/src/mscorlib/src/System/IO/DirectoryNotFoundException.cs b/src/mscorlib/src/System/IO/DirectoryNotFoundException.cs
deleted file mode 100644
index 21211a61e7..0000000000
--- a/src/mscorlib/src/System/IO/DirectoryNotFoundException.cs
+++ /dev/null
@@ -1,45 +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.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Exception for accessing a path that doesn't exist.
-**
-**
-===========================================================*/
-using System;
-using System.Runtime.Serialization;
-
-namespace System.IO {
- /*
- * Thrown when trying to access a directory that doesn't exist on disk.
- * From COM Interop, this exception is thrown for 2 HRESULTS:
- * the Win32 errorcode-as-HRESULT ERROR_PATH_NOT_FOUND (0x80070003)
- * and STG_E_PATHNOTFOUND (0x80030003).
- */
- [Serializable]
- public class DirectoryNotFoundException : IOException {
- public DirectoryNotFoundException()
- : base(Environment.GetResourceString("Arg_DirectoryNotFoundException")) {
- SetErrorCode(__HResults.COR_E_DIRECTORYNOTFOUND);
- }
-
- public DirectoryNotFoundException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_DIRECTORYNOTFOUND);
- }
-
- public DirectoryNotFoundException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(__HResults.COR_E_DIRECTORYNOTFOUND);
- }
-
- protected DirectoryNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) {
- }
- }
-}
diff --git a/src/mscorlib/src/System/IO/DriveNotFoundException.cs b/src/mscorlib/src/System/IO/DriveNotFoundException.cs
index f0245a8b28..27b6f9015d 100644
--- a/src/mscorlib/src/System/IO/DriveNotFoundException.cs
+++ b/src/mscorlib/src/System/IO/DriveNotFoundException.cs
@@ -10,25 +10,30 @@
//
//
//============================================================
+
using System;
using System.Runtime.Serialization;
-namespace System.IO {
-
+namespace System.IO
+{
//Thrown when trying to access a drive that is not availabe.
[Serializable]
- internal class DriveNotFoundException : IOException {
- public DriveNotFoundException()
- : base(Environment.GetResourceString("Arg_DriveNotFoundException")) {
- SetErrorCode(__HResults.COR_E_DIRECTORYNOTFOUND);
+ internal class DriveNotFoundException : IOException
+ {
+ public DriveNotFoundException()
+ : base(SR.Arg_DriveNotFoundException)
+ {
+ HResult = __HResults.COR_E_DIRECTORYNOTFOUND;
}
-
- public DriveNotFoundException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_DIRECTORYNOTFOUND);
+
+ public DriveNotFoundException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_DIRECTORYNOTFOUND;
}
-
- protected DriveNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) {
+
+ protected DriveNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
}
}
}
diff --git a/src/mscorlib/src/System/IO/EndOfStreamException.cs b/src/mscorlib/src/System/IO/EndOfStreamException.cs
deleted file mode 100644
index 558c792a9e..0000000000
--- a/src/mscorlib/src/System/IO/EndOfStreamException.cs
+++ /dev/null
@@ -1,42 +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.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Exception to be thrown when reading past end-of-file.
-**
-**
-===========================================================*/
-
-using System;
-using System.Runtime.Serialization;
-
-namespace System.IO {
- [Serializable]
- public class EndOfStreamException : IOException
- {
- public EndOfStreamException()
- : base(Environment.GetResourceString("Arg_EndOfStreamException")) {
- SetErrorCode(__HResults.COR_E_ENDOFSTREAM);
- }
-
- public EndOfStreamException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_ENDOFSTREAM);
- }
-
- public EndOfStreamException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(__HResults.COR_E_ENDOFSTREAM);
- }
-
- protected EndOfStreamException(SerializationInfo info, StreamingContext context) : base (info, context) {
- }
- }
-
-}
diff --git a/src/mscorlib/src/System/IO/File.cs b/src/mscorlib/src/System/IO/File.cs
index 7cc3f431a9..4aba1488ec 100644
--- a/src/mscorlib/src/System/IO/File.cs
+++ b/src/mscorlib/src/System/IO/File.cs
@@ -74,27 +74,30 @@ namespace System.IO
return false;
}
- internal static bool InternalExists(String path) {
+ internal static bool InternalExists(String path)
+ {
Win32Native.WIN32_FILE_ATTRIBUTE_DATA data = new Win32Native.WIN32_FILE_ATTRIBUTE_DATA();
int dataInitialised = FillAttributeInfo(path, ref data, false, true);
- return (dataInitialised == 0) && (data.fileAttributes != -1)
- && ((data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0);
+ return (dataInitialised == 0) && (data.fileAttributes != -1)
+ && ((data.fileAttributes & Win32Native.FILE_ATTRIBUTE_DIRECTORY) == 0);
}
public static byte[] ReadAllBytes(String path)
{
byte[] bytes;
- using(FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read,
- FileStream.DefaultBufferSize, FileOptions.None)) {
+ using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read,
+ FileStream.DefaultBufferSize, FileOptions.None))
+ {
// Do a blocking read
int index = 0;
long fileLength = fs.Length;
if (fileLength > Int32.MaxValue)
- throw new IOException(Environment.GetResourceString("IO.IO_FileTooLong2GB"));
- int count = (int) fileLength;
+ throw new IOException(SR.IO_FileTooLong2GB);
+ int count = (int)fileLength;
bytes = new byte[count];
- while(count > 0) {
+ while (count > 0)
+ {
int n = fs.Read(bytes, index, count);
if (n == 0)
__Error.EndOfFile();
@@ -111,7 +114,7 @@ namespace System.IO
if (path == null)
throw new ArgumentNullException(nameof(path));
if (path.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
+ throw new ArgumentException(SR.Argument_EmptyPath);
Contract.EndContractBlock();
return InternalReadAllLines(path, Encoding.UTF8);
@@ -133,7 +136,7 @@ namespace System.IO
return lines.ToArray();
}
#endif // PLATFORM_UNIX
-
+
// Returns 0 on success, otherwise a Win32 error code. Note that
// classes should use -1 as the uninitialized state for dataInitialized.
internal static int FillAttributeInfo(String path, ref Win32Native.WIN32_FILE_ATTRIBUTE_DATA data, bool tryagain, bool returnErrorOnNotFound)
@@ -142,29 +145,33 @@ namespace System.IO
if (tryagain) // someone has a handle to the file open, or other error
{
Win32Native.WIN32_FIND_DATA findData;
- findData = new Win32Native.WIN32_FIND_DATA ();
-
+ findData = new Win32Native.WIN32_FIND_DATA();
+
// Remove trialing slash since this can cause grief to FindFirstFile. You will get an invalid argument error
- String tempPath = path.TrimEnd(new char [] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar});
+ String tempPath = path.TrimEnd(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar });
// For floppy drives, normally the OS will pop up a dialog saying
// there is no disk in drive A:, please insert one. We don't want that.
// SetErrorMode will let us disable this, but we should set the error
// mode back, since this may have wide-ranging effects.
int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
- try {
+ try
+ {
bool error = false;
- SafeFindHandle handle = Win32Native.FindFirstFile(tempPath,findData);
- try {
- if (handle.IsInvalid) {
+ SafeFindHandle handle = Win32Native.FindFirstFile(tempPath, findData);
+ try
+ {
+ if (handle.IsInvalid)
+ {
error = true;
dataInitialised = Marshal.GetLastWin32Error();
-
+
if (dataInitialised == Win32Native.ERROR_FILE_NOT_FOUND ||
dataInitialised == Win32Native.ERROR_PATH_NOT_FOUND ||
dataInitialised == Win32Native.ERROR_NOT_READY) // floppy device not ready
{
- if (!returnErrorOnNotFound) {
+ if (!returnErrorOnNotFound)
+ {
// Return default value for backward compatibility
dataInitialised = 0;
data.fileAttributes = -1;
@@ -173,21 +180,26 @@ namespace System.IO
return dataInitialised;
}
}
- finally {
+ finally
+ {
// Close the Win32 handle
- try {
+ try
+ {
handle.Close();
}
- catch {
+ catch
+ {
// if we're already returning an error, don't throw another one.
- if (!error) {
+ if (!error)
+ {
Debug.Assert(false, "File::FillAttributeInfo - FindClose failed!");
__Error.WinIOError();
}
}
}
}
- finally {
+ finally
+ {
Win32Native.SetErrorMode(oldMode);
}
@@ -195,31 +207,36 @@ namespace System.IO
data.PopulateFrom(findData);
}
else
- {
- // For floppy drives, normally the OS will pop up a dialog saying
+ {
+ // For floppy drives, normally the OS will pop up a dialog saying
// there is no disk in drive A:, please insert one. We don't want that.
// SetErrorMode will let us disable this, but we should set the error
// mode back, since this may have wide-ranging effects.
bool success = false;
int oldMode = Win32Native.SetErrorMode(Win32Native.SEM_FAILCRITICALERRORS);
- try {
+ try
+ {
success = Win32Native.GetFileAttributesEx(path, GetFileExInfoStandard, ref data);
}
- finally {
+ finally
+ {
Win32Native.SetErrorMode(oldMode);
}
- if (!success) {
+ if (!success)
+ {
dataInitialised = Marshal.GetLastWin32Error();
if (dataInitialised != Win32Native.ERROR_FILE_NOT_FOUND &&
dataInitialised != Win32Native.ERROR_PATH_NOT_FOUND &&
dataInitialised != Win32Native.ERROR_NOT_READY) // floppy device not ready
{
- // In case someone latched onto the file. Take the perf hit only for failure
+ // In case someone latched onto the file. Take the perf hit only for failure
return FillAttributeInfo(path, ref data, true, returnErrorOnNotFound);
}
- else {
- if (!returnErrorOnNotFound) {
+ else
+ {
+ if (!returnErrorOnNotFound)
+ {
// Return default value for backward compbatibility
dataInitialised = 0;
data.fileAttributes = -1;
diff --git a/src/mscorlib/src/System/IO/FileAccess.cs b/src/mscorlib/src/System/IO/FileAccess.cs
deleted file mode 100644
index 707b58f78b..0000000000
--- a/src/mscorlib/src/System/IO/FileAccess.cs
+++ /dev/null
@@ -1,41 +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.
-
-/*============================================================
-**
-** Enum: FileAccess
-**
-**
-**
-**
-** Purpose: Enum describing whether you want read and/or write
-** permission to a file.
-**
-**
-===========================================================*/
-
-using System;
-
-namespace System.IO {
- // Contains constants for specifying the access you want for a file.
- // You can have Read, Write or ReadWrite access.
- //
-[Serializable]
-[Flags]
- public enum FileAccess
- {
- // Specifies read access to the file. Data can be read from the file and
- // the file pointer can be moved. Combine with WRITE for read-write access.
- Read = 1,
-
- // Specifies write access to the file. Data can be written to the file and
- // the file pointer can be moved. Combine with READ for read-write access.
- Write = 2,
-
- // Specifies read and write access to the file. Data can be written to the
- // file and the file pointer can be moved. Data can also be read from the
- // file.
- ReadWrite = 3,
- }
-}
diff --git a/src/mscorlib/src/System/IO/FileLoadException.CoreCLR.cs b/src/mscorlib/src/System/IO/FileLoadException.CoreCLR.cs
new file mode 100644
index 0000000000..f6415670e3
--- /dev/null
+++ b/src/mscorlib/src/System/IO/FileLoadException.CoreCLR.cs
@@ -0,0 +1,43 @@
+// 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.Globalization;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Security;
+
+namespace System.IO
+{
+ public partial class FileLoadException
+ {
+ // Do not delete: this is invoked from native code.
+ private FileLoadException(string fileName, string fusionLog, int hResult)
+ : base(null)
+ {
+ HResult = hResult;
+ FileName = fileName;
+ FusionLog = fusionLog;
+ _message = FormatFileLoadExceptionMessage(FileName, HResult);
+ }
+
+ internal static string FormatFileLoadExceptionMessage(string fileName, int hResult)
+ {
+ string format = null;
+ GetFileLoadExceptionMessage(hResult, JitHelpers.GetStringHandleOnStack(ref format));
+
+ string message = null;
+ GetMessageForHR(hResult, JitHelpers.GetStringHandleOnStack(ref message));
+
+ return string.Format(CultureInfo.CurrentCulture, format, fileName, message);
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern void GetFileLoadExceptionMessage(int hResult, StringHandleOnStack retString);
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern void GetMessageForHR(int hresult, StringHandleOnStack retString);
+ }
+}
diff --git a/src/mscorlib/src/System/IO/FileLoadException.cs b/src/mscorlib/src/System/IO/FileLoadException.cs
deleted file mode 100644
index 980d2514aa..0000000000
--- a/src/mscorlib/src/System/IO/FileLoadException.cs
+++ /dev/null
@@ -1,175 +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.
-
-/*============================================================
-**
-**
-**
-**
-**
-**
-** Purpose: Exception for failure to load a file that was successfully found.
-**
-**
-===========================================================*/
-
-using System;
-using System.Globalization;
-using System.Runtime.Serialization;
-using System.Runtime.InteropServices;
-using System.Runtime.CompilerServices;
-using System.Security;
-using System.Runtime.Versioning;
-using SecurityException = System.Security.SecurityException;
-
-namespace System.IO {
-
- [Serializable]
- public class FileLoadException : IOException {
-
- private String _fileName; // the name of the file we could not load.
- private String _fusionLog; // fusion log (when applicable)
-
- public FileLoadException()
- : base(Environment.GetResourceString("IO.FileLoad")) {
- SetErrorCode(__HResults.COR_E_FILELOAD);
- }
-
- public FileLoadException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_FILELOAD);
- }
-
- public FileLoadException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_FILELOAD);
- }
-
- public FileLoadException(String message, String fileName) : base(message)
- {
- SetErrorCode(__HResults.COR_E_FILELOAD);
- _fileName = fileName;
- }
-
- public FileLoadException(String message, String fileName, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_FILELOAD);
- _fileName = fileName;
- }
-
- public override String Message
- {
- get {
- SetMessageField();
- return _message;
- }
- }
-
- private void SetMessageField()
- {
- if (_message == null)
- _message = FormatFileLoadExceptionMessage(_fileName, HResult);
- }
-
- public String FileName {
- get { return _fileName; }
- }
-
- public override String ToString()
- {
- String s = GetType().FullName + ": " + Message;
-
- if (_fileName != null && _fileName.Length != 0)
- s += Environment.NewLine + Environment.GetResourceString("IO.FileName_Name", _fileName);
-
- if (InnerException != null)
- s = s + " ---> " + InnerException.ToString();
-
- if (StackTrace != null)
- s += Environment.NewLine + StackTrace;
-
- try
- {
- if(FusionLog!=null)
- {
- if (s==null)
- s=" ";
- s+=Environment.NewLine;
- s+=Environment.NewLine;
- s+=FusionLog;
- }
- }
- catch(SecurityException)
- {
-
- }
-
- return s;
- }
-
- protected FileLoadException(SerializationInfo info, StreamingContext context) : base (info, context) {
- // Base class constructor will check info != null.
-
- _fileName = info.GetString("FileLoad_FileName");
-
- try
- {
- _fusionLog = info.GetString("FileLoad_FusionLog");
- }
- catch
- {
- _fusionLog = null;
- }
- }
-
- private FileLoadException(String fileName, String fusionLog,int hResult)
- : base(null)
- {
- SetErrorCode(hResult);
- _fileName = fileName;
- _fusionLog=fusionLog;
- SetMessageField();
- }
-
- public String FusionLog {
- get { return _fusionLog; }
- }
-
- public override void GetObjectData(SerializationInfo info, StreamingContext context) {
- // Serialize data for our base classes. base will verify info != null.
- base.GetObjectData(info, context);
-
- // Serialize data for this class
- info.AddValue("FileLoad_FileName", _fileName, typeof(String));
-
- try
- {
- info.AddValue("FileLoad_FusionLog", FusionLog, typeof(String));
- }
- catch (SecurityException)
- {
- }
- }
-
- internal static String FormatFileLoadExceptionMessage(String fileName,
- int hResult)
- {
- string format = null;
- GetFileLoadExceptionMessage(hResult, JitHelpers.GetStringHandleOnStack(ref format));
-
- string message = null;
- GetMessageForHR(hResult, JitHelpers.GetStringHandleOnStack(ref message));
-
- return String.Format(CultureInfo.CurrentCulture, format, fileName, message);
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern void GetFileLoadExceptionMessage(int hResult, StringHandleOnStack retString);
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern void GetMessageForHR(int hresult, StringHandleOnStack retString);
- }
-}
diff --git a/src/mscorlib/src/System/IO/FileMode.cs b/src/mscorlib/src/System/IO/FileMode.cs
deleted file mode 100644
index 3972cf0533..0000000000
--- a/src/mscorlib/src/System/IO/FileMode.cs
+++ /dev/null
@@ -1,53 +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.
-
-/*============================================================
-**
-** Enum: FileMode
-**
-**
-**
-**
-** Purpose: Enum describing whether to create a new file or
-** open an existing one.
-**
-**
-===========================================================*/
-
-using System;
-
-namespace System.IO {
- // Contains constants for specifying how the OS should open a file.
- // These will control whether you overwrite a file, open an existing
- // file, or some combination thereof.
- //
- // To append to a file, use Append (which maps to OpenOrCreate then we seek
- // to the end of the file). To truncate a file or create it if it doesn't
- // exist, use Create.
- //
- [Serializable]
- public enum FileMode
- {
- // Creates a new file. An exception is raised if the file already exists.
- CreateNew = 1,
-
- // Creates a new file. If the file already exists, it is overwritten.
- Create = 2,
-
- // Opens an existing file. An exception is raised if the file does not exist.
- Open = 3,
-
- // Opens the file if it exists. Otherwise, creates a new file.
- OpenOrCreate = 4,
-
- // Opens an existing file. Once opened, the file is truncated so that its
- // size is zero bytes. The calling process must open the file with at least
- // WRITE access. An exception is raised if the file does not exist.
- Truncate = 5,
-
- // Opens the file if it exists and seeks to the end. Otherwise,
- // creates a new file.
- Append = 6,
- }
-}
diff --git a/src/mscorlib/src/System/IO/FileNotFoundException.CoreCLR.cs b/src/mscorlib/src/System/IO/FileNotFoundException.CoreCLR.cs
new file mode 100644
index 0000000000..99645f0f2d
--- /dev/null
+++ b/src/mscorlib/src/System/IO/FileNotFoundException.CoreCLR.cs
@@ -0,0 +1,20 @@
+// 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.
+
+namespace System.IO
+{
+ public partial class FileNotFoundException
+ {
+ // Do not delete: this is invoked from native code.
+ private FileNotFoundException(string fileName, string fusionLog, int hResult)
+ : base(null)
+ {
+ HResult = hResult;
+ FileName = fileName;
+ FusionLog = fusionLog;
+ SetMessageField();
+ }
+ }
+}
+
diff --git a/src/mscorlib/src/System/IO/FileNotFoundException.cs b/src/mscorlib/src/System/IO/FileNotFoundException.cs
deleted file mode 100644
index ad6b5386ba..0000000000
--- a/src/mscorlib/src/System/IO/FileNotFoundException.cs
+++ /dev/null
@@ -1,157 +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.
-
-/*============================================================
-**
-**
-**
-**
-**
-**
-** Purpose: Exception for accessing a file that doesn't exist.
-**
-**
-===========================================================*/
-
-using System;
-using System.Runtime.Serialization;
-using SecurityException = System.Security.SecurityException;
-using System.Globalization;
-
-namespace System.IO {
- // Thrown when trying to access a file that doesn't exist on disk.
- [Serializable]
- public class FileNotFoundException : IOException {
-
- private String _fileName; // The name of the file that isn't found.
- private String _fusionLog; // fusion log (when applicable)
-
- public FileNotFoundException()
- : base(Environment.GetResourceString("IO.FileNotFound")) {
- SetErrorCode(__HResults.COR_E_FILENOTFOUND);
- }
-
- public FileNotFoundException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_FILENOTFOUND);
- }
-
- public FileNotFoundException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(__HResults.COR_E_FILENOTFOUND);
- }
-
- public FileNotFoundException(String message, String fileName) : base(message)
- {
- SetErrorCode(__HResults.COR_E_FILENOTFOUND);
- _fileName = fileName;
- }
-
- public FileNotFoundException(String message, String fileName, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(__HResults.COR_E_FILENOTFOUND);
- _fileName = fileName;
- }
-
- public override String Message
- {
- get {
- SetMessageField();
- return _message;
- }
- }
-
- private void SetMessageField()
- {
- if (_message == null) {
- if ((_fileName == null) &&
- (HResult == System.__HResults.COR_E_EXCEPTION))
- _message = Environment.GetResourceString("IO.FileNotFound");
-
- else if( _fileName != null)
- _message = FileLoadException.FormatFileLoadExceptionMessage(_fileName, HResult);
- }
- }
-
- public String FileName {
- get { return _fileName; }
- }
-
- public override String ToString()
- {
- String s = GetType().FullName + ": " + Message;
-
- if (_fileName != null && _fileName.Length != 0)
- s += Environment.NewLine + Environment.GetResourceString("IO.FileName_Name", _fileName);
-
- if (InnerException != null)
- s = s + " ---> " + InnerException.ToString();
-
- if (StackTrace != null)
- s += Environment.NewLine + StackTrace;
-
- try
- {
- if(FusionLog!=null)
- {
- if (s==null)
- s=" ";
- s+=Environment.NewLine;
- s+=Environment.NewLine;
- s+=FusionLog;
- }
- }
- catch(SecurityException)
- {
-
- }
- return s;
-
- }
-
- protected FileNotFoundException(SerializationInfo info, StreamingContext context) : base (info, context) {
- // Base class constructor will check info != null.
-
- _fileName = info.GetString("FileNotFound_FileName");
- try
- {
- _fusionLog = info.GetString("FileNotFound_FusionLog");
- }
- catch
- {
- _fusionLog = null;
- }
- }
-
- private FileNotFoundException(String fileName, String fusionLog,int hResult)
- : base(null)
- {
- SetErrorCode(hResult);
- _fileName = fileName;
- _fusionLog=fusionLog;
- SetMessageField();
- }
-
- public String FusionLog {
- get { return _fusionLog; }
- }
-
- public override void GetObjectData(SerializationInfo info, StreamingContext context) {
- // Serialize data for our base classes. base will verify info != null.
- base.GetObjectData(info, context);
-
- // Serialize data for this class
- info.AddValue("FileNotFound_FileName", _fileName, typeof(String));
-
- try
- {
- info.AddValue("FileNotFound_FusionLog", FusionLog, typeof(String));
- }
- catch (SecurityException)
- {
- }
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/IO/FileOptions.cs b/src/mscorlib/src/System/IO/FileOptions.cs
deleted file mode 100644
index 02bc99eea4..0000000000
--- a/src/mscorlib/src/System/IO/FileOptions.cs
+++ /dev/null
@@ -1,46 +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.
-
-/*============================================================
-**
-** Enum: FileOptions
-**
-**
-**
-**
-** Purpose: Additional options to how to create a FileStream.
-** Exposes the more obscure CreateFile functionality.
-**
-**
-===========================================================*/
-
-using System;
-using System.Runtime.InteropServices;
-
-namespace System.IO {
- // Maps to FILE_FLAG_DELETE_ON_CLOSE and similar values from winbase.h.
- // We didn't expose a number of these values because we didn't believe
- // a number of them made sense in managed code, at least not yet.
- [Serializable]
- [Flags]
- public enum FileOptions
- {
- // NOTE: any change to FileOptions enum needs to be
- // matched in the FileStream ctor for error validation
- None = 0,
- WriteThrough = unchecked((int)0x80000000),
- Asynchronous = unchecked((int)0x40000000), // FILE_FLAG_OVERLAPPED
- // NoBuffering = 0x20000000,
- RandomAccess = 0x10000000,
- DeleteOnClose = 0x04000000,
- SequentialScan = 0x08000000,
- // AllowPosix = 0x01000000, // FILE_FLAG_POSIX_SEMANTICS
- // BackupOrRestore,
- // DisallowReparsePoint = 0x00200000, // FILE_FLAG_OPEN_REPARSE_POINT
- // NoRemoteRecall = 0x00100000, // FILE_FLAG_OPEN_NO_RECALL
- // FirstPipeInstance = 0x00080000, // FILE_FLAG_FIRST_PIPE_INSTANCE
- Encrypted = 0x00004000, // FILE_ATTRIBUTE_ENCRYPTED
- }
-}
-
diff --git a/src/mscorlib/src/System/IO/FileShare.cs b/src/mscorlib/src/System/IO/FileShare.cs
deleted file mode 100644
index 8a7d1f05e9..0000000000
--- a/src/mscorlib/src/System/IO/FileShare.cs
+++ /dev/null
@@ -1,59 +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.
-
-/*============================================================
-**
-** Enum: FileShare
-**
-**
-**
-**
-** Purpose: Enum describing how to share files with other
-** processes - ie, whether two processes can simultaneously
-** read from the same file.
-**
-**
-===========================================================*/
-
-using System;
-
-namespace System.IO {
- // Contains constants for controlling file sharing options while
- // opening files. You can specify what access other processes trying
- // to open the same file concurrently can have.
- //
- // Note these values currently match the values for FILE_SHARE_READ,
- // FILE_SHARE_WRITE, and FILE_SHARE_DELETE in winnt.h
- //
-[Serializable]
-[Flags]
- public enum FileShare
- {
- // No sharing. Any request to open the file (by this process or another
- // process) will fail until the file is closed.
- None = 0,
-
- // Allows subsequent opening of the file for reading. If this flag is not
- // specified, any request to open the file for reading (by this process or
- // another process) will fail until the file is closed.
- Read = 1,
-
- // Allows subsequent opening of the file for writing. If this flag is not
- // specified, any request to open the file for writing (by this process or
- // another process) will fail until the file is closed.
- Write = 2,
-
- // Allows subsequent opening of the file for writing or reading. If this flag
- // is not specified, any request to open the file for writing or reading (by
- // this process or another process) will fail until the file is closed.
- ReadWrite = 3,
-
- // Open the file, but allow someone else to delete the file.
- Delete = 4,
-
- // Whether the file handle should be inheritable by child processes.
- // Note this is not directly supported like this by Win32.
- Inheritable = 0x10,
- }
-}
diff --git a/src/mscorlib/src/System/IO/IOException.cs b/src/mscorlib/src/System/IO/IOException.cs
index ab612811b0..2628f7b652 100644
--- a/src/mscorlib/src/System/IO/IOException.cs
+++ b/src/mscorlib/src/System/IO/IOException.cs
@@ -16,8 +16,8 @@
using System;
using System.Runtime.Serialization;
-namespace System.IO {
-
+namespace System.IO
+{
[Serializable]
public class IOException : SystemException
{
@@ -32,36 +32,42 @@ namespace System.IO {
[NonSerialized]
private String _maybeFullPath; // For debuggers on partial trust code
- public IOException()
- : base(Environment.GetResourceString("Arg_IOException")) {
- SetErrorCode(__HResults.COR_E_IO);
+ public IOException()
+ : base(SR.Arg_IOException)
+ {
+ HResult = __HResults.COR_E_IO;
}
-
- public IOException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_IO);
+
+ public IOException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_IO;
}
- public IOException(String message, int hresult)
- : base(message) {
- SetErrorCode(hresult);
+ public IOException(String message, int hresult)
+ : base(message)
+ {
+ HResult = hresult;
}
// Adding this for debuggers when looking at exceptions in partial
// trust code that may not have interesting path information in
// the exception message.
- internal IOException(String message, int hresult, String maybeFullPath)
- : base(message) {
- SetErrorCode(hresult);
+ internal IOException(String message, int hresult, String maybeFullPath)
+ : base(message)
+ {
+ HResult = hresult;
_maybeFullPath = maybeFullPath;
}
-
- public IOException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(__HResults.COR_E_IO);
+
+ public IOException(String message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_IO;
}
- protected IOException(SerializationInfo info, StreamingContext context) : base (info, context) {
+ protected IOException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
}
}
}
diff --git a/src/mscorlib/src/System/IO/MemoryStream.cs b/src/mscorlib/src/System/IO/MemoryStream.cs
index 05aac909b5..3d5668d774 100644
--- a/src/mscorlib/src/System/IO/MemoryStream.cs
+++ b/src/mscorlib/src/System/IO/MemoryStream.cs
@@ -24,7 +24,8 @@ using System.Diagnostics.Contracts;
using System.Threading;
using System.Threading.Tasks;
-namespace System.IO {
+namespace System.IO
+{
// A MemoryStream represents a Stream in memory (ie, it has no backing store).
// This stream may reduce the need for temporary buffers and files in
// an application.
@@ -54,17 +55,20 @@ namespace System.IO {
private const int MemStreamMaxLength = Int32.MaxValue;
- public MemoryStream()
- : this(0) {
+ public MemoryStream()
+ : this(0)
+ {
}
-
- public MemoryStream(int capacity) {
- if (capacity < 0) {
- throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_NegativeCapacity"));
+
+ public MemoryStream(int capacity)
+ {
+ if (capacity < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_NegativeCapacity);
}
Contract.EndContractBlock();
- _buffer = capacity != 0 ? new byte[capacity] : EmptyArray<byte>.Value;
+ _buffer = capacity != 0 ? new byte[capacity] : Array.Empty<byte>();
_capacity = capacity;
_expandable = true;
_writable = true;
@@ -72,13 +76,15 @@ namespace System.IO {
_origin = 0; // Must be 0 for byte[]'s created by MemoryStream
_isOpen = true;
}
-
- public MemoryStream(byte[] buffer)
- : this(buffer, true) {
+
+ public MemoryStream(byte[] buffer)
+ : this(buffer, true)
+ {
}
-
- public MemoryStream(byte[] buffer, bool writable) {
- if (buffer == null) throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+
+ public MemoryStream(byte[] buffer, bool writable)
+ {
+ if (buffer == null) throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
Contract.EndContractBlock();
_buffer = buffer;
_length = _capacity = buffer.Length;
@@ -87,26 +93,29 @@ namespace System.IO {
_origin = 0;
_isOpen = true;
}
-
- public MemoryStream(byte[] buffer, int index, int count)
- : this(buffer, index, count, true, false) {
+
+ public MemoryStream(byte[] buffer, int index, int count)
+ : this(buffer, index, count, true, false)
+ {
}
-
- public MemoryStream(byte[] buffer, int index, int count, bool writable)
- : this(buffer, index, count, writable, false) {
+
+ public MemoryStream(byte[] buffer, int index, int count, bool writable)
+ : this(buffer, index, count, writable, false)
+ {
}
-
- public MemoryStream(byte[] buffer, int index, int count, bool writable, bool publiclyVisible) {
- if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+
+ public MemoryStream(byte[] buffer, int index, int count, bool writable, bool publiclyVisible)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
-
+
_buffer = buffer;
_origin = _position = index;
_length = _capacity = index + count;
@@ -115,30 +124,36 @@ namespace System.IO {
_expandable = false;
_isOpen = true;
}
-
- public override bool CanRead {
+
+ public override bool CanRead
+ {
[Pure]
get { return _isOpen; }
}
-
- public override bool CanSeek {
+
+ public override bool CanSeek
+ {
[Pure]
get { return _isOpen; }
}
-
- public override bool CanWrite {
+
+ public override bool CanWrite
+ {
[Pure]
get { return _writable; }
}
- private void EnsureWriteable() {
+ private void EnsureWriteable()
+ {
if (!CanWrite) __Error.WriteNotSupported();
}
protected override void Dispose(bool disposing)
{
- try {
- if (disposing) {
+ try
+ {
+ if (disposing)
+ {
_isOpen = false;
_writable = false;
_expandable = false;
@@ -146,18 +161,21 @@ namespace System.IO {
_lastReadTask = null;
}
}
- finally {
+ finally
+ {
// Call base.Close() to cleanup async IO resources
base.Dispose(disposing);
}
}
-
+
// returns a bool saying whether we allocated a new array.
- private bool EnsureCapacity(int value) {
+ private bool EnsureCapacity(int value)
+ {
// Check for overflow
if (value < 0)
- throw new IOException(Environment.GetResourceString("IO.IO_StreamTooLong"));
- if (value > _capacity) {
+ throw new IOException(SR.IO_StreamTooLong);
+ if (value > _capacity)
+ {
int newCapacity = value;
if (newCapacity < 256)
newCapacity = 256;
@@ -169,53 +187,58 @@ namespace System.IO {
// And we want to give the user the value that they asked for
if ((uint)(_capacity * 2) > Array.MaxByteArrayLength)
newCapacity = value > Array.MaxByteArrayLength ? value : Array.MaxByteArrayLength;
-
+
Capacity = newCapacity;
return true;
}
return false;
}
-
- public override void Flush() {
- }
- public override Task FlushAsync(CancellationToken cancellationToken) {
+ public override void Flush()
+ {
+ }
+ public override Task FlushAsync(CancellationToken cancellationToken)
+ {
if (cancellationToken.IsCancellationRequested)
return Task.FromCanceled(cancellationToken);
- try {
-
+ try
+ {
Flush();
return Task.CompletedTask;
-
- } catch(Exception ex) {
-
+ }
+ catch (Exception ex)
+ {
return Task.FromException(ex);
}
}
- public virtual byte[] GetBuffer() {
+ public virtual byte[] GetBuffer()
+ {
if (!_exposable)
- throw new UnauthorizedAccessException(Environment.GetResourceString("UnauthorizedAccess_MemStreamBuffer"));
+ throw new UnauthorizedAccessException(SR.UnauthorizedAccess_MemStreamBuffer);
return _buffer;
}
- public virtual bool TryGetBuffer(out ArraySegment<byte> buffer) {
- if (!_exposable) {
+ public virtual bool TryGetBuffer(out ArraySegment<byte> buffer)
+ {
+ if (!_exposable)
+ {
buffer = default(ArraySegment<byte>);
return false;
}
- buffer = new ArraySegment<byte>(_buffer, offset:_origin, count:(_length - _origin));
+ buffer = new ArraySegment<byte>(_buffer, offset: _origin, count: (_length - _origin));
return true;
}
// -------------- PERF: Internal functions for fast direct access of MemoryStream buffer (cf. BinaryReader for usage) ---------------
// PERF: Internal sibling of GetBuffer, always returns a buffer (cf. GetBuffer())
- internal byte[] InternalGetBuffer() {
+ internal byte[] InternalGetBuffer()
+ {
return _buffer;
}
@@ -229,27 +252,30 @@ namespace System.IO {
}
// PERF: True cursor position, we don't need _origin for direct access
- internal int InternalGetPosition() {
+ internal int InternalGetPosition()
+ {
if (!_isOpen) __Error.StreamIsClosed();
return _position;
}
// PERF: Takes out Int32 as fast as possible
- internal int InternalReadInt32() {
- if (!_isOpen)
- __Error.StreamIsClosed();
+ internal int InternalReadInt32()
+ {
+ if (!_isOpen)
+ __Error.StreamIsClosed();
- int pos = (_position += 4); // use temp to avoid a race condition
- if (pos > _length)
- {
- _position = _length;
- __Error.EndOfFile();
- }
- return (int)(_buffer[pos-4] | _buffer[pos-3] << 8 | _buffer[pos-2] << 16 | _buffer[pos-1] << 24);
+ int pos = (_position += 4); // use temp to avoid a race condition
+ if (pos > _length)
+ {
+ _position = _length;
+ __Error.EndOfFile();
+ }
+ return (int)(_buffer[pos - 4] | _buffer[pos - 3] << 8 | _buffer[pos - 2] << 16 | _buffer[pos - 1] << 24);
}
// PERF: Get actual length of bytes available for read; do sanity checks; shift position - i.e. everything except actual copying bytes
- internal int InternalEmulateRead(int count) {
+ internal int InternalEmulateRead(int count)
+ {
if (!_isOpen) __Error.StreamIsClosed();
int n = _length - _position;
@@ -260,20 +286,23 @@ namespace System.IO {
_position += n;
return n;
}
-
+
// Gets & sets the capacity (number of bytes allocated) for this stream.
// The capacity cannot be set to a value less than the current length
// of the stream.
//
- public virtual int Capacity {
- get {
+ public virtual int Capacity
+ {
+ get
+ {
if (!_isOpen) __Error.StreamIsClosed();
return _capacity - _origin;
}
- set {
+ set
+ {
// Only update the capacity if the MS is expandable and the value is different than the current capacity.
// Special behavior if the MS isn't expandable: we don't throw if value is the same as the current capacity
- if (value < Length) throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
+ if (value < Length) throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_SmallCapacity);
Contract.Ensures(_capacity - _origin == value);
Contract.EndContractBlock();
@@ -281,55 +310,64 @@ namespace System.IO {
if (!_expandable && (value != Capacity)) __Error.MemoryStreamNotExpandable();
// MemoryStream has this invariant: _origin > 0 => !expandable (see ctors)
- if (_expandable && value != _capacity) {
- if (value > 0) {
+ if (_expandable && value != _capacity)
+ {
+ if (value > 0)
+ {
byte[] newBuffer = new byte[value];
if (_length > 0) Buffer.InternalBlockCopy(_buffer, 0, newBuffer, 0, _length);
_buffer = newBuffer;
}
- else {
+ else
+ {
_buffer = null;
}
_capacity = value;
}
}
- }
+ }
- public override long Length {
- get {
+ public override long Length
+ {
+ get
+ {
if (!_isOpen) __Error.StreamIsClosed();
return _length - _origin;
}
}
- public override long Position {
- get {
+ public override long Position
+ {
+ get
+ {
if (!_isOpen) __Error.StreamIsClosed();
return _position - _origin;
}
- set {
+ set
+ {
if (value < 0)
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.Ensures(Position == value);
Contract.EndContractBlock();
if (!_isOpen) __Error.StreamIsClosed();
if (value > MemStreamMaxLength)
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_StreamLength);
_position = _origin + (int)value;
}
}
- public override int Read([In, Out] byte[] buffer, int offset, int count) {
- if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ public override int Read([In, Out] byte[] buffer, int offset, int count)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (offset < 0)
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
if (!_isOpen) __Error.StreamIsClosed();
@@ -356,25 +394,25 @@ namespace System.IO {
public override Task<int> ReadAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
- if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (offset < 0)
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock(); // contract validation copied from Read(...)
// If cancellation was requested, bail early
- if (cancellationToken.IsCancellationRequested)
+ if (cancellationToken.IsCancellationRequested)
return Task.FromCanceled<int>(cancellationToken);
try
{
int n = Read(buffer, offset, count);
var t = _lastReadTask;
- Debug.Assert(t == null || t.Status == TaskStatus.RanToCompletion,
+ Debug.Assert(t == null || t.Status == TaskStatus.RanToCompletion,
"Expected that a stored last task completed successfully");
return (t != null && t.Result == n) ? t : (_lastReadTask = Task.FromResult<int>(n));
}
@@ -389,9 +427,10 @@ namespace System.IO {
}
- public override int ReadByte() {
+ public override int ReadByte()
+ {
if (!_isOpen) __Error.StreamIsClosed();
-
+
if (_position >= _length) return -1;
return _buffer[_position++];
@@ -412,7 +451,7 @@ namespace System.IO {
base.CopyTo(destination, bufferSize);
return;
}
-
+
int originalPosition = _position;
// Seek to the end of the MemoryStream.
@@ -427,8 +466,8 @@ namespace System.IO {
}
}
- public override Task CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken) {
-
+ public override Task CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
+ {
// This implementation offers beter performance compared to the base class version.
StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize);
@@ -443,7 +482,7 @@ namespace System.IO {
// If cancelled - return fast:
if (cancellationToken.IsCancellationRequested)
return Task.FromCanceled(cancellationToken);
-
+
// Avoid copying data from this buffer into a temp buffer:
// (require that InternalEmulateRead does not throw,
// otherwise it needs to be wrapped into try-catch-Task.FromException like memStrDest.Write below)
@@ -453,56 +492,62 @@ namespace System.IO {
// If destination is not a memory stream, write there asynchronously:
MemoryStream memStrDest = destination as MemoryStream;
- if (memStrDest == null)
+ if (memStrDest == null)
return destination.WriteAsync(_buffer, pos, n, cancellationToken);
-
- try {
+ try
+ {
// If destination is a MemoryStream, CopyTo synchronously:
memStrDest.Write(_buffer, pos, n);
return Task.CompletedTask;
-
- } catch(Exception ex) {
+ }
+ catch (Exception ex)
+ {
return Task.FromException(ex);
}
}
- public override long Seek(long offset, SeekOrigin loc) {
+ public override long Seek(long offset, SeekOrigin loc)
+ {
if (!_isOpen) __Error.StreamIsClosed();
if (offset > MemStreamMaxLength)
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
- switch(loc) {
- case SeekOrigin.Begin: {
- int tempPosition = unchecked(_origin + (int)offset);
- if (offset < 0 || tempPosition < _origin)
- throw new IOException(Environment.GetResourceString("IO.IO_SeekBeforeBegin"));
- _position = tempPosition;
- break;
- }
- case SeekOrigin.Current: {
- int tempPosition = unchecked(_position + (int)offset);
- if (unchecked(_position + offset) < _origin || tempPosition < _origin)
- throw new IOException(Environment.GetResourceString("IO.IO_SeekBeforeBegin"));
- _position = tempPosition;
- break;
- }
- case SeekOrigin.End: {
- int tempPosition = unchecked(_length + (int)offset);
- if ( unchecked(_length + offset) < _origin || tempPosition < _origin )
- throw new IOException(Environment.GetResourceString("IO.IO_SeekBeforeBegin"));
- _position = tempPosition;
- break;
- }
- default:
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSeekOrigin"));
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_StreamLength);
+ switch (loc)
+ {
+ case SeekOrigin.Begin:
+ {
+ int tempPosition = unchecked(_origin + (int)offset);
+ if (offset < 0 || tempPosition < _origin)
+ throw new IOException(SR.IO_SeekBeforeBegin);
+ _position = tempPosition;
+ break;
+ }
+ case SeekOrigin.Current:
+ {
+ int tempPosition = unchecked(_position + (int)offset);
+ if (unchecked(_position + offset) < _origin || tempPosition < _origin)
+ throw new IOException(SR.IO_SeekBeforeBegin);
+ _position = tempPosition;
+ break;
+ }
+ case SeekOrigin.End:
+ {
+ int tempPosition = unchecked(_length + (int)offset);
+ if (unchecked(_length + offset) < _origin || tempPosition < _origin)
+ throw new IOException(SR.IO_SeekBeforeBegin);
+ _position = tempPosition;
+ break;
+ }
+ default:
+ throw new ArgumentException(SR.Argument_InvalidSeekOrigin);
}
Debug.Assert(_position >= 0, "_position >= 0");
return _position;
}
-
+
// Sets the length of the stream to a given value. The new
// value must be nonnegative and less than the space remaining in
// the array, Int32.MaxValue - origin
@@ -513,9 +558,11 @@ namespace System.IO {
// the stream is made longer than the maximum possible length of the
// array (Int32.MaxValue).
//
- public override void SetLength(long value) {
- if (value < 0 || value > Int32.MaxValue) {
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
+ public override void SetLength(long value)
+ {
+ if (value < 0 || value > Int32.MaxValue)
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_StreamLength);
}
Contract.Ensures(_length - _origin == value);
Contract.EndContractBlock();
@@ -523,8 +570,9 @@ namespace System.IO {
// Origin wasn't publicly exposed above.
Debug.Assert(MemStreamMaxLength == Int32.MaxValue); // Check parameter validation logic in this method if this fails.
- if (value > (Int32.MaxValue - _origin)) {
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
+ if (value > (Int32.MaxValue - _origin))
+ {
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_StreamLength);
}
int newLength = _origin + (int)value;
@@ -533,25 +581,26 @@ namespace System.IO {
Array.Clear(_buffer, _length, newLength - _length);
_length = newLength;
if (_position > newLength) _position = newLength;
-
}
-
- public virtual byte[] ToArray() {
+
+ public virtual byte[] ToArray()
+ {
BCLDebug.Perf(_exposable, "MemoryStream::GetBuffer will let you avoid a copy.");
byte[] copy = new byte[_length - _origin];
Buffer.InternalBlockCopy(_buffer, _origin, copy, 0, _length - _origin);
return copy;
}
-
- public override void Write(byte[] buffer, int offset, int count) {
- if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (offset < 0)
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
if (!_isOpen) __Error.StreamIsClosed();
@@ -560,11 +609,13 @@ namespace System.IO {
int i = _position + count;
// Check for overflow
if (i < 0)
- throw new IOException(Environment.GetResourceString("IO.IO_StreamTooLong"));
+ throw new IOException(SR.IO_StreamTooLong);
- if (i > _length) {
+ if (i > _length)
+ {
bool mustZero = _position > _length;
- if (i > _capacity) {
+ if (i > _capacity)
+ {
bool allocatedNewArray = EnsureCapacity(i);
if (allocatedNewArray)
mustZero = false;
@@ -582,23 +633,22 @@ namespace System.IO {
else
Buffer.InternalBlockCopy(buffer, offset, _buffer, _position, count);
_position = i;
-
}
public override Task WriteAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
if (buffer == null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (offset < 0)
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock(); // contract validation copied from Write(...)
// If cancellation is already requested, bail early
- if (cancellationToken.IsCancellationRequested)
+ if (cancellationToken.IsCancellationRequested)
return Task.FromCanceled(cancellationToken);
try
@@ -616,14 +666,17 @@ namespace System.IO {
}
}
- public override void WriteByte(byte value) {
+ public override void WriteByte(byte value)
+ {
if (!_isOpen) __Error.StreamIsClosed();
EnsureWriteable();
-
- if (_position >= _length) {
+
+ if (_position >= _length)
+ {
int newLength = _position + 1;
bool mustZero = _position > _length;
- if (newLength >= _capacity) {
+ if (newLength >= _capacity)
+ {
bool allocatedNewArray = EnsureCapacity(newLength);
if (allocatedNewArray)
mustZero = false;
@@ -633,13 +686,13 @@ namespace System.IO {
_length = newLength;
}
_buffer[_position++] = value;
-
}
-
+
// Writes this MemoryStream to another stream.
- public virtual void WriteTo(Stream stream) {
- if (stream==null)
- throw new ArgumentNullException(nameof(stream), Environment.GetResourceString("ArgumentNull_Stream"));
+ public virtual void WriteTo(Stream stream)
+ {
+ if (stream == null)
+ throw new ArgumentNullException(nameof(stream), SR.ArgumentNull_Stream);
Contract.EndContractBlock();
if (!_isOpen) __Error.StreamIsClosed();
diff --git a/src/mscorlib/src/System/IO/PathTooLongException.cs b/src/mscorlib/src/System/IO/PathTooLongException.cs
deleted file mode 100644
index a84fdfbb36..0000000000
--- a/src/mscorlib/src/System/IO/PathTooLongException.cs
+++ /dev/null
@@ -1,43 +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.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Exception for paths and/or filenames that are
-** too long.
-**
-**
-===========================================================*/
-
-using System;
-using System.Runtime.Serialization;
-
-namespace System.IO {
-
- [Serializable]
- public class PathTooLongException : IOException
- {
- public PathTooLongException()
- : base(Environment.GetResourceString("IO.PathTooLong")) {
- SetErrorCode(__HResults.COR_E_PATHTOOLONG);
- }
-
- public PathTooLongException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_PATHTOOLONG);
- }
-
- public PathTooLongException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(__HResults.COR_E_PATHTOOLONG);
- }
-
- protected PathTooLongException(SerializationInfo info, StreamingContext context) : base (info, context) {
- }
- }
-}
diff --git a/src/mscorlib/src/System/IO/PinnedBufferMemoryStream.cs b/src/mscorlib/src/System/IO/PinnedBufferMemoryStream.cs
index 2cbd14f734..284cd927dc 100644
--- a/src/mscorlib/src/System/IO/PinnedBufferMemoryStream.cs
+++ b/src/mscorlib/src/System/IO/PinnedBufferMemoryStream.cs
@@ -13,19 +13,21 @@
**
**
===========================================================*/
+
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Diagnostics.Contracts;
-namespace System.IO {
+namespace System.IO
+{
internal sealed unsafe class PinnedBufferMemoryStream : UnmanagedMemoryStream
{
private byte[] _array;
private GCHandle _pinningHandle;
// The new inheritance model requires a Critical default ctor since base (UnmanagedMemoryStream) has one
- private PinnedBufferMemoryStream():base(){}
+ private PinnedBufferMemoryStream() : base() { }
internal PinnedBufferMemoryStream(byte[] array)
{
@@ -33,7 +35,8 @@ namespace System.IO {
int len = array.Length;
// Handle 0 length byte arrays specially.
- if (len == 0) {
+ if (len == 0)
+ {
array = new byte[1];
len = 0;
}
@@ -42,7 +45,7 @@ namespace System.IO {
_pinningHandle = new GCHandle(array, GCHandleType.Pinned);
// Now the byte[] is pinned for the lifetime of this instance.
// But I also need to get a pointer to that block of memory...
- fixed(byte* ptr = &_array[0])
+ fixed (byte* ptr = &_array[0])
Initialize(ptr, len, len, FileAccess.Read);
}
@@ -53,14 +56,16 @@ namespace System.IO {
protected override void Dispose(bool disposing)
{
- if (_isOpen) {
+ if (_isOpen)
+ {
_pinningHandle.Free();
_isOpen = false;
}
#if _DEBUG
// To help track down lifetime issues on checked builds, force
//a full GC here.
- if (disposing) {
+ if (disposing)
+ {
GC.Collect();
GC.WaitForPendingFinalizers();
}
diff --git a/src/mscorlib/src/System/IO/SearchOption.cs b/src/mscorlib/src/System/IO/SearchOption.cs
index e2f761cd54..75909d7499 100644
--- a/src/mscorlib/src/System/IO/SearchOption.cs
+++ b/src/mscorlib/src/System/IO/SearchOption.cs
@@ -18,9 +18,10 @@
using System;
-namespace System.IO {
+namespace System.IO
+{
[Serializable]
- public enum SearchOption
+ internal enum SearchOption
{
// Include only the current directory in the search operation
TopDirectoryOnly,
diff --git a/src/mscorlib/src/System/IO/SeekOrigin.cs b/src/mscorlib/src/System/IO/SeekOrigin.cs
deleted file mode 100644
index bff49e610f..0000000000
--- a/src/mscorlib/src/System/IO/SeekOrigin.cs
+++ /dev/null
@@ -1,31 +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.
-
-/*============================================================
-**
-** Enum: SeekOrigin
-**
-**
-**
-**
-** Purpose: Enum describing locations in a stream you could
-** seek relative to.
-**
-**
-===========================================================*/
-
-using System;
-
-namespace System.IO {
- // Provides seek reference points. To seek to the end of a stream,
- // call stream.Seek(0, SeekOrigin.End).
- [Serializable]
- public enum SeekOrigin
- {
- // These constants match Win32's FILE_BEGIN, FILE_CURRENT, and FILE_END
- Begin = 0,
- Current = 1,
- End = 2,
- }
-}
diff --git a/src/mscorlib/src/System/IO/Stream.cs b/src/mscorlib/src/System/IO/Stream.cs
index 790f0a09ab..92fe374f19 100644
--- a/src/mscorlib/src/System/IO/Stream.cs
+++ b/src/mscorlib/src/System/IO/Stream.cs
@@ -14,6 +14,7 @@
**
**
===========================================================*/
+
using System;
using System.Buffers;
using System.Threading;
@@ -27,10 +28,11 @@ using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Reflection;
-namespace System.IO {
+namespace System.IO
+{
[Serializable]
- public abstract class Stream : MarshalByRefObject, IDisposable {
-
+ public abstract class Stream : MarshalByRefObject, IDisposable
+ {
public static readonly Stream Null = new NullStream();
//We pick a value that is the largest multiple of 4096 that is still smaller than the large object heap threshold (85K).
@@ -52,55 +54,68 @@ namespace System.IO {
return LazyInitializer.EnsureInitialized(ref _asyncActiveSemaphore, () => new SemaphoreSlim(1, 1));
}
- public abstract bool CanRead {
+ public abstract bool CanRead
+ {
[Pure]
get;
}
// If CanSeek is false, Position, Seek, Length, and SetLength should throw.
- public abstract bool CanSeek {
+ public abstract bool CanSeek
+ {
[Pure]
get;
}
- public virtual bool CanTimeout {
+ public virtual bool CanTimeout
+ {
[Pure]
- get {
+ get
+ {
return false;
}
}
-
- public abstract bool CanWrite {
+
+ public abstract bool CanWrite
+ {
[Pure]
get;
}
- public abstract long Length {
+ public abstract long Length
+ {
get;
}
- public abstract long Position {
+ public abstract long Position
+ {
get;
set;
}
- public virtual int ReadTimeout {
- get {
+ public virtual int ReadTimeout
+ {
+ get
+ {
Contract.Ensures(Contract.Result<int>() >= 0);
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TimeoutsNotSupported"));
+ throw new InvalidOperationException(SR.InvalidOperation_TimeoutsNotSupported);
}
- set {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TimeoutsNotSupported"));
+ set
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_TimeoutsNotSupported);
}
}
- public virtual int WriteTimeout {
- get {
+ public virtual int WriteTimeout
+ {
+ get
+ {
Contract.Ensures(Contract.Result<int>() >= 0);
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TimeoutsNotSupported"));
+ throw new InvalidOperationException(SR.InvalidOperation_TimeoutsNotSupported);
}
- set {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TimeoutsNotSupported"));
+ set
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_TimeoutsNotSupported);
}
}
@@ -127,7 +142,7 @@ namespace System.IO {
// because it would be a breaking change if the stream's override didn't throw before,
// or in a different order. So for simplicity, we just set the bufferSize to 1
// (not 0 since the default implementation throws for 0) and forward to the virtual method.
- bufferSize = 1;
+ bufferSize = 1;
}
else
{
@@ -295,7 +310,7 @@ namespace System.IO {
}
internal IAsyncResult BeginReadInternal(
- byte[] buffer, int offset, int count, AsyncCallback callback, Object state,
+ byte[] buffer, int offset, int count, AsyncCallback callback, Object state,
bool serializeAsynchronously, bool apm)
{
Contract.Ensures(Contract.Result<IAsyncResult>() != null);
@@ -341,7 +356,7 @@ namespace System.IO {
{
thisTask._stream.FinishTrackingAsyncOperation();
}
-
+
thisTask.ClearBeginState(); // just to help alleviate some memory pressure
}
}, state, this, buffer, offset, count, callback);
@@ -352,7 +367,7 @@ namespace System.IO {
else
RunReadWriteTask(asyncResult);
-
+
return asyncResult; // return it
}
@@ -367,18 +382,18 @@ namespace System.IO {
if (readTask == null)
{
- throw new ArgumentException(Environment.GetResourceString("InvalidOperation_WrongAsyncResultOrEndReadCalledMultiple"));
+ throw new ArgumentException(SR.InvalidOperation_WrongAsyncResultOrEndReadCalledMultiple);
}
else if (readTask != asyncResult)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WrongAsyncResultOrEndReadCalledMultiple"));
+ throw new InvalidOperationException(SR.InvalidOperation_WrongAsyncResultOrEndReadCalledMultiple);
}
else if (!readTask._isRead)
{
- throw new ArgumentException(Environment.GetResourceString("InvalidOperation_WrongAsyncResultOrEndReadCalledMultiple"));
+ throw new ArgumentException(SR.InvalidOperation_WrongAsyncResultOrEndReadCalledMultiple);
}
-
- try
+
+ try
{
return readTask.GetAwaiter().GetResult(); // block until completion, then get result / propagate any exception
}
@@ -437,12 +452,12 @@ namespace System.IO {
}
internal IAsyncResult BeginWriteInternal(
- byte[] buffer, int offset, int count, AsyncCallback callback, Object state,
+ byte[] buffer, int offset, int count, AsyncCallback callback, Object state,
bool serializeAsynchronously, bool apm)
{
Contract.Ensures(Contract.Result<IAsyncResult>() != null);
if (!CanWrite) __Error.WriteNotSupported();
-
+
// To avoid a race condition with a stream's position pointer & generating conditions
// with internal buffer indexes in our own streams that
// don't natively support async IO operations when there are multiple
@@ -472,7 +487,7 @@ namespace System.IO {
try
{
// Do the Write
- thisTask._stream.Write(thisTask._buffer, thisTask._offset, thisTask._count);
+ thisTask._stream.Write(thisTask._buffer, thisTask._offset, thisTask._count);
return 0; // not used, but signature requires a value be returned
}
finally
@@ -501,7 +516,7 @@ namespace System.IO {
private void RunReadWriteTaskWhenReady(Task asyncWaiter, ReadWriteTask readWriteTask)
{
Debug.Assert(readWriteTask != null); // Should be Contract.Requires, but CCRewrite is doing a poor job with
- // preconditions in async methods that await.
+ // preconditions in async methods that await.
Debug.Assert(asyncWaiter != null); // Ditto
// If the wait has already completed, run the task.
@@ -509,10 +524,11 @@ namespace System.IO {
{
Debug.Assert(asyncWaiter.IsRanToCompletion, "The semaphore wait should always complete successfully.");
RunReadWriteTask(readWriteTask);
- }
+ }
else // Otherwise, wait for our turn, and then run the task.
{
- asyncWaiter.ContinueWith((t, state) => {
+ asyncWaiter.ContinueWith((t, state) =>
+ {
Debug.Assert(t.IsRanToCompletion, "The semaphore wait should always complete successfully.");
var rwt = (ReadWriteTask)state;
rwt._stream.RunReadWriteTask(rwt); // RunReadWriteTask(readWriteTask);
@@ -536,32 +552,32 @@ namespace System.IO {
private void FinishTrackingAsyncOperation()
{
- _activeReadWriteTask = null;
+ _activeReadWriteTask = null;
Debug.Assert(_asyncActiveSemaphore != null, "Must have been initialized in order to get here.");
_asyncActiveSemaphore.Release();
}
public virtual void EndWrite(IAsyncResult asyncResult)
{
- if (asyncResult==null)
+ if (asyncResult == null)
throw new ArgumentNullException(nameof(asyncResult));
Contract.EndContractBlock();
var writeTask = _activeReadWriteTask;
if (writeTask == null)
{
- throw new ArgumentException(Environment.GetResourceString("InvalidOperation_WrongAsyncResultOrEndWriteCalledMultiple"));
+ throw new ArgumentException(SR.InvalidOperation_WrongAsyncResultOrEndWriteCalledMultiple);
}
else if (writeTask != asyncResult)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WrongAsyncResultOrEndWriteCalledMultiple"));
+ throw new InvalidOperationException(SR.InvalidOperation_WrongAsyncResultOrEndWriteCalledMultiple);
}
else if (writeTask._isRead)
{
- throw new ArgumentException(Environment.GetResourceString("InvalidOperation_WrongAsyncResultOrEndWriteCalledMultiple"));
+ throw new ArgumentException(SR.InvalidOperation_WrongAsyncResultOrEndWriteCalledMultiple);
}
- try
+ try
{
writeTask.GetAwaiter().GetResult(); // block until completion, then propagate any exceptions
Debug.Assert(writeTask.Status == TaskStatus.RanToCompletion);
@@ -590,10 +606,10 @@ namespace System.IO {
// with a single allocation.
private sealed class ReadWriteTask : Task<int>, ITaskCompletionAction
{
- internal readonly bool _isRead;
+ internal readonly bool _isRead;
internal readonly bool _apm; // true if this is from Begin/EndXx; false if it's from XxAsync
internal Stream _stream;
- internal byte [] _buffer;
+ internal byte[] _buffer;
internal readonly int _offset;
internal readonly int _count;
private AsyncCallback _callback;
@@ -608,7 +624,7 @@ namespace System.IO {
public ReadWriteTask(
bool isRead,
bool apm,
- Func<object,int> function, object state,
+ Func<object, int> function, object state,
Stream stream, byte[] buffer, int offset, int count, AsyncCallback callback) :
base(function, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach)
{
@@ -647,23 +663,23 @@ namespace System.IO {
}
private static ContextCallback s_invokeAsyncCallback;
-
+
void ITaskCompletionAction.Invoke(Task completingTask)
{
// Get the ExecutionContext. If there is none, just run the callback
// directly, passing in the completed task as the IAsyncResult.
// If there is one, process it with ExecutionContext.Run.
var context = _context;
- if (context == null)
+ if (context == null)
{
var callback = _callback;
_callback = null;
callback(completingTask);
}
- else
+ else
{
_context = null;
-
+
var invokeAsyncCallback = s_invokeAsyncCallback;
if (invokeAsyncCallback == null) s_invokeAsyncCallback = invokeAsyncCallback = InvokeAsyncCallback; // benign race condition
@@ -704,14 +720,14 @@ namespace System.IO {
// Otherwise, we need to wrap calls to Begin/EndWrite to ensure we use the derived type's functionality.
return TaskFactory<VoidTaskResult>.FromAsyncTrim(
- this, new ReadWriteParameters { Buffer=buffer, Offset=offset, Count=count },
+ this, new ReadWriteParameters { Buffer = buffer, Offset = offset, Count = count },
(stream, args, callback, state) => stream.BeginWrite(args.Buffer, args.Offset, args.Count, callback, state), // cached by compiler
(stream, asyncResult) => // cached by compiler
{
stream.EndWrite(asyncResult);
return default(VoidTaskResult);
});
- }
+ }
public abstract long Seek(long offset, SeekOrigin origin);
@@ -732,7 +748,7 @@ namespace System.IO {
byte[] oneByteArray = new byte[1];
int r = Read(oneByteArray, 0, 1);
- if (r==0)
+ if (r == 0)
return -1;
return oneByteArray[0];
}
@@ -751,20 +767,20 @@ namespace System.IO {
Write(oneByteArray, 0, 1);
}
- public static Stream Synchronized(Stream stream)
+ public static Stream Synchronized(Stream stream)
{
- if (stream==null)
+ if (stream == null)
throw new ArgumentNullException(nameof(stream));
Contract.Ensures(Contract.Result<Stream>() != null);
Contract.EndContractBlock();
if (stream is SyncStream)
return stream;
-
+
return new SyncStream(stream);
}
[Obsolete("Do not call or override this method.")]
- protected virtual void ObjectInvariant()
+ protected virtual void ObjectInvariant()
{
}
@@ -778,16 +794,19 @@ namespace System.IO {
// async requests outstanding, we will block the application's main
// thread and do the IO synchronously.
// This can't perform well - use a different approach.
- SynchronousAsyncResult asyncResult;
- try {
+ SynchronousAsyncResult asyncResult;
+ try
+ {
int numRead = Read(buffer, offset, count);
asyncResult = new SynchronousAsyncResult(numRead, state);
}
- catch (IOException ex) {
+ catch (IOException ex)
+ {
asyncResult = new SynchronousAsyncResult(ex, state, isWrite: false);
}
-
- if (callback != null) {
+
+ if (callback != null)
+ {
callback(asyncResult);
}
@@ -812,15 +831,18 @@ namespace System.IO {
// thread and do the IO synchronously.
// This can't perform well - use a different approach.
SynchronousAsyncResult asyncResult;
- try {
+ try
+ {
Write(buffer, offset, count);
asyncResult = new SynchronousAsyncResult(state);
}
- catch (IOException ex) {
+ catch (IOException ex)
+ {
asyncResult = new SynchronousAsyncResult(ex, state, isWrite: true);
}
- if (callback != null) {
+ if (callback != null)
+ {
callback(asyncResult);
}
@@ -835,45 +857,50 @@ namespace System.IO {
[Serializable]
private sealed class NullStream : Stream
{
- internal NullStream() {}
+ internal NullStream() { }
- public override bool CanRead {
+ public override bool CanRead
+ {
[Pure]
get { return true; }
}
- public override bool CanWrite {
+ public override bool CanWrite
+ {
[Pure]
get { return true; }
}
- public override bool CanSeek {
+ public override bool CanSeek
+ {
[Pure]
get { return true; }
}
- public override long Length {
+ public override long Length
+ {
get { return 0; }
}
- public override long Position {
+ public override long Position
+ {
get { return 0; }
- set {}
+ set { }
}
-
+
public override void CopyTo(Stream destination, int bufferSize)
{
StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize);
-
+
// After we validate arguments this is a nop.
}
-
+
public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
{
// Validate arguments here for compat, since previously this method
// was inherited from Stream (which did check its arguments).
StreamHelpers.ValidateCopyToArgs(this, destination, bufferSize);
-
+
return cancellationToken.IsCancellationRequested ?
Task.FromCanceled(cancellationToken) :
Task.CompletedTask;
@@ -935,7 +962,7 @@ namespace System.IO {
public override Task<int> ReadAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
var nullReadTask = s_nullReadTask;
- if (nullReadTask == null)
+ if (nullReadTask == null)
s_nullReadTask = nullReadTask = new Task<int>(false, 0, (TaskCreationOptions)InternalTaskOptions.DoNotDispose, CancellationToken.None); // benign race condition
return nullReadTask;
}
@@ -971,11 +998,11 @@ namespace System.IO {
}
}
-
+
/// <summary>Used as the IAsyncResult object when using asynchronous IO methods on the base Stream class.</summary>
- internal sealed class SynchronousAsyncResult : IAsyncResult {
-
- private readonly Object _stateObject;
+ internal sealed class SynchronousAsyncResult : IAsyncResult
+ {
+ private readonly Object _stateObject;
private readonly bool _isWrite;
private ManualResetEvent _waitHandle;
private ExceptionDispatchInfo _exceptionInfo;
@@ -983,49 +1010,58 @@ namespace System.IO {
private bool _endXxxCalled;
private Int32 _bytesRead;
- internal SynchronousAsyncResult(Int32 bytesRead, Object asyncStateObject) {
+ internal SynchronousAsyncResult(Int32 bytesRead, Object asyncStateObject)
+ {
_bytesRead = bytesRead;
_stateObject = asyncStateObject;
//_isWrite = false;
}
- internal SynchronousAsyncResult(Object asyncStateObject) {
+ internal SynchronousAsyncResult(Object asyncStateObject)
+ {
_stateObject = asyncStateObject;
_isWrite = true;
}
- internal SynchronousAsyncResult(Exception ex, Object asyncStateObject, bool isWrite) {
+ internal SynchronousAsyncResult(Exception ex, Object asyncStateObject, bool isWrite)
+ {
_exceptionInfo = ExceptionDispatchInfo.Capture(ex);
_stateObject = asyncStateObject;
- _isWrite = isWrite;
+ _isWrite = isWrite;
}
- public bool IsCompleted {
+ public bool IsCompleted
+ {
// We never hand out objects of this type to the user before the synchronous IO completed:
get { return true; }
}
- public WaitHandle AsyncWaitHandle {
- get {
- return LazyInitializer.EnsureInitialized(ref _waitHandle, () => new ManualResetEvent(true));
+ public WaitHandle AsyncWaitHandle
+ {
+ get
+ {
+ return LazyInitializer.EnsureInitialized(ref _waitHandle, () => new ManualResetEvent(true));
}
}
- public Object AsyncState {
+ public Object AsyncState
+ {
get { return _stateObject; }
}
- public bool CompletedSynchronously {
+ public bool CompletedSynchronously
+ {
get { return true; }
}
- internal void ThrowIfError() {
+ internal void ThrowIfError()
+ {
if (_exceptionInfo != null)
_exceptionInfo.Throw();
- }
-
- internal static Int32 EndRead(IAsyncResult asyncResult) {
+ }
+ internal static Int32 EndRead(IAsyncResult asyncResult)
+ {
SynchronousAsyncResult ar = asyncResult as SynchronousAsyncResult;
if (ar == null || ar._isWrite)
__Error.WrongAsyncResult();
@@ -1039,8 +1075,8 @@ namespace System.IO {
return ar._bytesRead;
}
- internal static void EndWrite(IAsyncResult asyncResult) {
-
+ internal static void EndWrite(IAsyncResult asyncResult)
+ {
SynchronousAsyncResult ar = asyncResult as SynchronousAsyncResult;
if (ar == null || !ar._isWrite)
__Error.WrongAsyncResult();
@@ -1069,64 +1105,83 @@ namespace System.IO {
Contract.EndContractBlock();
_stream = stream;
}
-
- public override bool CanRead {
+
+ public override bool CanRead
+ {
[Pure]
get { return _stream.CanRead; }
}
-
- public override bool CanWrite {
+
+ public override bool CanWrite
+ {
[Pure]
get { return _stream.CanWrite; }
}
-
- public override bool CanSeek {
+
+ public override bool CanSeek
+ {
[Pure]
get { return _stream.CanSeek; }
}
-
- public override bool CanTimeout {
+
+ public override bool CanTimeout
+ {
[Pure]
- get {
+ get
+ {
return _stream.CanTimeout;
}
}
- public override long Length {
- get {
- lock(_stream) {
+ public override long Length
+ {
+ get
+ {
+ lock (_stream)
+ {
return _stream.Length;
}
}
}
-
- public override long Position {
- get {
- lock(_stream) {
+
+ public override long Position
+ {
+ get
+ {
+ lock (_stream)
+ {
return _stream.Position;
}
}
- set {
- lock(_stream) {
+ set
+ {
+ lock (_stream)
+ {
_stream.Position = value;
}
}
}
- public override int ReadTimeout {
- get {
+ public override int ReadTimeout
+ {
+ get
+ {
return _stream.ReadTimeout;
}
- set {
+ set
+ {
_stream.ReadTimeout = value;
}
}
- public override int WriteTimeout {
- get {
+ public override int WriteTimeout
+ {
+ get
+ {
return _stream.WriteTimeout;
}
- set {
+ set
+ {
_stream.WriteTimeout = value;
}
}
@@ -1135,48 +1190,54 @@ namespace System.IO {
// semantics for Close vs. Dispose, let's preserve that.
public override void Close()
{
- lock(_stream) {
- try {
+ lock (_stream)
+ {
+ try
+ {
_stream.Close();
}
- finally {
+ finally
+ {
base.Dispose(true);
}
}
}
-
+
protected override void Dispose(bool disposing)
{
- lock(_stream) {
- try {
+ lock (_stream)
+ {
+ try
+ {
// Explicitly pick up a potentially methodimpl'ed Dispose
if (disposing)
((IDisposable)_stream).Dispose();
}
- finally {
+ finally
+ {
base.Dispose(disposing);
}
}
}
-
+
public override void Flush()
{
- lock(_stream)
+ lock (_stream)
_stream.Flush();
}
-
+
public override int Read([In, Out]byte[] bytes, int offset, int count)
{
- lock(_stream)
+ lock (_stream)
return _stream.Read(bytes, offset, count);
}
-
+
public override int ReadByte()
{
- lock(_stream)
+ lock (_stream)
return _stream.ReadByte();
}
-
+
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
{
bool overridesBeginRead = _stream.HasOverriddenBeginEndRead();
@@ -1194,7 +1255,7 @@ namespace System.IO {
_stream.BeginReadInternal(buffer, offset, count, callback, state, serializeAsynchronously: true, apm: true);
}
}
-
+
public override int EndRead(IAsyncResult asyncResult)
{
if (asyncResult == null)
@@ -1202,34 +1263,34 @@ namespace System.IO {
Contract.Ensures(Contract.Result<int>() >= 0);
Contract.EndContractBlock();
- lock(_stream)
+ lock (_stream)
return _stream.EndRead(asyncResult);
}
-
+
public override long Seek(long offset, SeekOrigin origin)
{
- lock(_stream)
+ lock (_stream)
return _stream.Seek(offset, origin);
}
-
+
public override void SetLength(long length)
{
- lock(_stream)
+ lock (_stream)
_stream.SetLength(length);
}
-
+
public override void Write(byte[] bytes, int offset, int count)
{
- lock(_stream)
+ lock (_stream)
_stream.Write(bytes, offset, count);
}
-
+
public override void WriteByte(byte b)
{
- lock(_stream)
+ lock (_stream)
_stream.WriteByte(b);
}
-
+
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
{
bool overridesBeginWrite = _stream.HasOverriddenBeginEndWrite();
@@ -1247,14 +1308,14 @@ namespace System.IO {
_stream.BeginWriteInternal(buffer, offset, count, callback, state, serializeAsynchronously: true, apm: true);
}
}
-
+
public override void EndWrite(IAsyncResult asyncResult)
{
if (asyncResult == null)
throw new ArgumentNullException(nameof(asyncResult));
Contract.EndContractBlock();
- lock(_stream)
+ lock (_stream)
_stream.EndWrite(asyncResult);
}
}
diff --git a/src/mscorlib/src/System/IO/StreamHelpers.CopyValidation.cs b/src/mscorlib/src/System/IO/StreamHelpers.CopyValidation.cs
deleted file mode 100644
index 8ff0e045ca..0000000000
--- a/src/mscorlib/src/System/IO/StreamHelpers.CopyValidation.cs
+++ /dev/null
@@ -1,46 +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.
-
-namespace System.IO
-{
- /// <summary>Provides methods to help in the implementation of Stream-derived types.</summary>
- internal static partial class StreamHelpers
- {
- /// <summary>Validate the arguments to CopyTo, as would Stream.CopyTo.</summary>
- public static void ValidateCopyToArgs(Stream source, Stream destination, int bufferSize)
- {
- if (destination == null)
- {
- throw new ArgumentNullException(nameof(destination));
- }
-
- if (bufferSize <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(bufferSize), bufferSize, Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
- }
-
- bool sourceCanRead = source.CanRead;
- if (!sourceCanRead && !source.CanWrite)
- {
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_StreamClosed"));
- }
-
- bool destinationCanWrite = destination.CanWrite;
- if (!destinationCanWrite && !destination.CanRead)
- {
- throw new ObjectDisposedException(nameof(destination), Environment.GetResourceString("ObjectDisposed_StreamClosed"));
- }
-
- if (!sourceCanRead)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnreadableStream"));
- }
-
- if (!destinationCanWrite)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnwritableStream"));
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/IO/StreamReader.cs b/src/mscorlib/src/System/IO/StreamReader.cs
index 6d50347b1a..dfb928c85d 100644
--- a/src/mscorlib/src/System/IO/StreamReader.cs
+++ b/src/mscorlib/src/System/IO/StreamReader.cs
@@ -103,7 +103,7 @@ namespace System.IO
Task t = _asyncReadTask;
if (t != null && !t.IsCompleted)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncIOInProgress"));
+ throw new InvalidOperationException(SR.InvalidOperation_AsyncIOInProgress);
}
// StreamReader by default will ignore illegal UTF8 characters. We don't want to
@@ -149,9 +149,9 @@ namespace System.IO
if (stream == null || encoding == null)
throw new ArgumentNullException((stream == null ? nameof(stream) : nameof(encoding)));
if (!stream.CanRead)
- throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotReadable"));
+ throw new ArgumentException(SR.Argument_StreamNotReadable);
if (bufferSize <= 0)
- throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ throw new ArgumentOutOfRangeException(nameof(bufferSize), SR.ArgumentOutOfRange_NeedPosNum);
Contract.EndContractBlock();
Init(stream, encoding, detectEncodingFromByteOrderMarks, bufferSize, leaveOpen);
@@ -181,9 +181,9 @@ namespace System.IO
if (path==null || encoding==null)
throw new ArgumentNullException((path==null ? nameof(path) : nameof(encoding)));
if (path.Length==0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
+ throw new ArgumentException(SR.Argument_EmptyPath);
if (bufferSize <= 0)
- throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ throw new ArgumentOutOfRangeException(nameof(bufferSize), SR.ArgumentOutOfRange_NeedPosNum);
Contract.EndContractBlock();
Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.SequentialScan);
@@ -338,11 +338,11 @@ namespace System.IO
public override int Read([In, Out] char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
if (stream == null)
@@ -396,11 +396,11 @@ namespace System.IO
public override int ReadBlock([In, Out] char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
if (stream == null)
@@ -540,7 +540,7 @@ namespace System.IO
return sb.ToString();
}
- internal virtual int ReadBuffer() {
+ internal int ReadBuffer() {
charLen = 0;
charPos = 0;
@@ -777,16 +777,16 @@ namespace System.IO
private async Task<String> ReadLineAsyncInternal()
{
- if (CharPos_Prop == CharLen_Prop && (await ReadBufferAsync().ConfigureAwait(false)) == 0)
+ if (charPos == charLen && (await ReadBufferAsync().ConfigureAwait(false)) == 0)
return null;
StringBuilder sb = null;
do
{
- char[] tmpCharBuffer = CharBuffer_Prop;
- int tmpCharLen = CharLen_Prop;
- int tmpCharPos = CharPos_Prop;
+ char[] tmpCharBuffer = charBuffer;
+ int tmpCharLen = charLen;
+ int tmpCharPos = charPos;
int i = tmpCharPos;
do
@@ -809,13 +809,13 @@ namespace System.IO
s = new String(tmpCharBuffer, tmpCharPos, i - tmpCharPos);
}
- CharPos_Prop = tmpCharPos = i + 1;
+ charPos = tmpCharPos = i + 1;
if (ch == '\r' && (tmpCharPos < tmpCharLen || (await ReadBufferAsync().ConfigureAwait(false)) > 0))
{
- tmpCharPos = CharPos_Prop;
- if (CharBuffer_Prop[tmpCharPos] == '\n')
- CharPos_Prop = ++tmpCharPos;
+ tmpCharPos = charPos;
+ if (charBuffer[tmpCharPos] == '\n')
+ charPos = ++tmpCharPos;
}
return s;
@@ -857,14 +857,14 @@ namespace System.IO
private async Task<String> ReadToEndAsyncInternal()
{
// Call ReadBuffer, then pull data out of charBuffer.
- StringBuilder sb = AcquireSharedStringBuilder(CharLen_Prop - CharPos_Prop);
+ StringBuilder sb = AcquireSharedStringBuilder(charLen - charPos);
do
{
- int tmpCharPos = CharPos_Prop;
- sb.Append(CharBuffer_Prop, tmpCharPos, CharLen_Prop - tmpCharPos);
- CharPos_Prop = CharLen_Prop; // We consumed these characters
+ int tmpCharPos = charPos;
+ sb.Append(charBuffer, tmpCharPos, charLen - tmpCharPos);
+ charPos = charLen; // We consumed these characters
await ReadBufferAsync().ConfigureAwait(false);
- } while (CharLen_Prop > 0);
+ } while (charLen > 0);
return GetStringAndReleaseSharedStringBuilder(sb);
}
@@ -872,11 +872,11 @@ namespace System.IO
public override Task<int> ReadAsync(char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
// If we have been inherited into a subclass, the following implementation could be incorrect
@@ -899,7 +899,7 @@ namespace System.IO
internal override async Task<int> ReadAsyncInternal(char[] buffer, int index, int count)
{
- if (CharPos_Prop == CharLen_Prop && (await ReadBufferAsync().ConfigureAwait(false)) == 0)
+ if (charPos == charLen && (await ReadBufferAsync().ConfigureAwait(false)) == 0)
return 0;
int charsRead = 0;
@@ -908,24 +908,24 @@ namespace System.IO
// data read in, let's try writing directly to the user's buffer.
bool readToUserBuffer = false;
- Byte[] tmpByteBuffer = ByteBuffer_Prop;
- Stream tmpStream = Stream_Prop;
+ Byte[] tmpByteBuffer = byteBuffer;
+ Stream tmpStream = stream;
while (count > 0)
{
// n is the characters available in _charBuffer
- int n = CharLen_Prop - CharPos_Prop;
+ int n = charLen - charPos;
// charBuffer is empty, let's read from the stream
if (n == 0)
{
- CharLen_Prop = 0;
- CharPos_Prop = 0;
+ charLen = 0;
+ charPos = 0;
- if (!CheckPreamble_Prop)
- ByteLen_Prop = 0;
+ if (!_checkPreamble)
+ byteLen = 0;
- readToUserBuffer = count >= MaxCharsPerBuffer_Prop;
+ readToUserBuffer = count >= _maxCharsPerBuffer;
// We loop here so that we read in enough bytes to yield at least 1 char.
// We break out of the loop if the stream is blocked (EOF is reached).
@@ -933,10 +933,10 @@ namespace System.IO
{
Debug.Assert(n == 0);
- if (CheckPreamble_Prop)
+ if (_checkPreamble)
{
- Debug.Assert(BytePos_Prop <= Preamble_Prop.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?");
- int tmpBytePos = BytePos_Prop;
+ Debug.Assert(bytePos <= _preamble.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?");
+ int tmpBytePos = bytePos;
int len = await tmpStream.ReadAsync(tmpByteBuffer, tmpBytePos, tmpByteBuffer.Length - tmpBytePos).ConfigureAwait(false);
Debug.Assert(len >= 0, "Stream.Read returned a negative number! This is a bug in your stream class.");
@@ -944,42 +944,42 @@ namespace System.IO
{
// EOF but we might have buffered bytes from previous
// attempts to detect preamble that needs to be decoded now
- if (ByteLen_Prop > 0)
+ if (byteLen > 0)
{
if (readToUserBuffer)
{
- n = Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, buffer, index + charsRead);
- CharLen_Prop = 0; // StreamReader's buffer is empty.
+ n = decoder.GetChars(tmpByteBuffer, 0, byteLen, buffer, index + charsRead);
+ charLen = 0; // StreamReader's buffer is empty.
}
else
{
- n = Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, CharBuffer_Prop, 0);
- CharLen_Prop += n; // Number of chars in StreamReader's buffer.
+ n = decoder.GetChars(tmpByteBuffer, 0, byteLen, charBuffer, 0);
+ charLen += n; // Number of chars in StreamReader's buffer.
}
}
// How can part of the preamble yield any chars?
Debug.Assert(n == 0);
- IsBlocked_Prop = true;
+ _isBlocked = true;
break;
}
else
{
- ByteLen_Prop += len;
+ byteLen += len;
}
}
else
{
- Debug.Assert(BytePos_Prop == 0, "_bytePos can be non zero only when we are trying to _checkPreamble. Are two threads using this StreamReader at the same time?");
+ Debug.Assert(bytePos == 0, "_bytePos can be non zero only when we are trying to _checkPreamble. Are two threads using this StreamReader at the same time?");
- ByteLen_Prop = await tmpStream.ReadAsync(tmpByteBuffer, 0, tmpByteBuffer.Length).ConfigureAwait(false);
+ byteLen = await tmpStream.ReadAsync(tmpByteBuffer, 0, tmpByteBuffer.Length).ConfigureAwait(false);
- Debug.Assert(ByteLen_Prop >= 0, "Stream.Read returned a negative number! This is a bug in your stream class.");
+ Debug.Assert(byteLen >= 0, "Stream.Read returned a negative number! This is a bug in your stream class.");
- if (ByteLen_Prop == 0) // EOF
+ if (byteLen == 0) // EOF
{
- IsBlocked_Prop = true;
+ _isBlocked = true;
break;
}
}
@@ -987,7 +987,7 @@ namespace System.IO
// _isBlocked == whether we read fewer bytes than we asked for.
// Note we must check it here because CompressBuffer or
// DetectEncoding will change _byteLen.
- IsBlocked_Prop = (ByteLen_Prop < tmpByteBuffer.Length);
+ _isBlocked = (byteLen < tmpByteBuffer.Length);
// Check for preamble before detect encoding. This is not to override the
// user suppplied Encoding for the one we implicitly detect. The user could
@@ -998,33 +998,33 @@ namespace System.IO
continue;
// On the first call to ReadBuffer, if we're supposed to detect the encoding, do it.
- if (DetectEncoding_Prop && ByteLen_Prop >= 2)
+ if (_detectEncoding && byteLen >= 2)
{
DetectEncoding();
// DetectEncoding changes some buffer state. Recompute this.
- readToUserBuffer = count >= MaxCharsPerBuffer_Prop;
+ readToUserBuffer = count >= _maxCharsPerBuffer;
}
Debug.Assert(n == 0);
- CharPos_Prop = 0;
+ charPos = 0;
if (readToUserBuffer)
{
- n += Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, buffer, index + charsRead);
+ n += decoder.GetChars(tmpByteBuffer, 0, byteLen, buffer, index + charsRead);
// Why did the bytes yield no chars?
Debug.Assert(n > 0);
- CharLen_Prop = 0; // StreamReader's buffer is empty.
+ charLen = 0; // StreamReader's buffer is empty.
}
else
{
- n = Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, CharBuffer_Prop, 0);
+ n = decoder.GetChars(tmpByteBuffer, 0, byteLen, charBuffer, 0);
// Why did the bytes yield no chars?
Debug.Assert(n > 0);
- CharLen_Prop += n; // Number of chars in StreamReader's buffer.
+ charLen += n; // Number of chars in StreamReader's buffer.
}
} while (n == 0);
@@ -1038,8 +1038,8 @@ namespace System.IO
if (!readToUserBuffer)
{
- Buffer.InternalBlockCopy(CharBuffer_Prop, CharPos_Prop * 2, buffer, (index + charsRead) * 2, n * 2);
- CharPos_Prop += n;
+ Buffer.InternalBlockCopy(charBuffer, charPos * 2, buffer, (index + charsRead) * 2, n * 2);
+ charPos += n;
}
charsRead += n;
@@ -1048,7 +1048,7 @@ namespace System.IO
// This function shouldn't block for an indefinite amount of time,
// or reading from a network stream won't work right. If we got
// fewer bytes than we requested, then we want to break right here.
- if (IsBlocked_Prop)
+ if (_isBlocked)
break;
} // while (count > 0)
@@ -1058,11 +1058,11 @@ namespace System.IO
public override Task<int> ReadBlockAsync(char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
// If we have been inherited into a subclass, the following implementation could be incorrect
@@ -1083,113 +1083,50 @@ namespace System.IO
return task;
}
- #region Private properties for async method performance
- // Access to instance fields of MarshalByRefObject-derived types requires special JIT helpers that check
- // if the instance operated on is remote. This is optimised for fields on this but if a method is Async
- // and is thus lifted to a state machine type, access will be slow.
- // As a workaround, we either cache instance fields in locals or use properties to access such fields.
-
- private Int32 CharLen_Prop {
- get { return charLen; }
- set { charLen = value; }
- }
-
- private Int32 CharPos_Prop {
- get { return charPos; }
- set { charPos = value; }
- }
-
- private Int32 ByteLen_Prop {
- get { return byteLen; }
- set { byteLen = value; }
- }
-
- private Int32 BytePos_Prop {
- get { return bytePos; }
- set { bytePos = value; }
- }
-
- private Byte[] Preamble_Prop {
- get { return _preamble; }
- }
-
- private bool CheckPreamble_Prop {
- get { return _checkPreamble; }
- }
-
- private Decoder Decoder_Prop {
- get { return decoder; }
- }
-
- private bool DetectEncoding_Prop {
- get { return _detectEncoding; }
- }
-
- private Char[] CharBuffer_Prop {
- get { return charBuffer; }
- }
-
- private Byte[] ByteBuffer_Prop {
- get { return byteBuffer; }
- }
-
- private bool IsBlocked_Prop {
- get { return _isBlocked; }
- set { _isBlocked = value; }
- }
-
- private Stream Stream_Prop {
- get { return stream; }
- }
-
- private Int32 MaxCharsPerBuffer_Prop {
- get { return _maxCharsPerBuffer; }
- }
- #endregion Private properties for async method performance
private async Task<int> ReadBufferAsync()
{
- CharLen_Prop = 0;
- CharPos_Prop = 0;
- Byte[] tmpByteBuffer = ByteBuffer_Prop;
- Stream tmpStream = Stream_Prop;
+ charLen = 0;
+ charPos = 0;
+ Byte[] tmpByteBuffer = byteBuffer;
+ Stream tmpStream = stream;
- if (!CheckPreamble_Prop)
- ByteLen_Prop = 0;
+ if (!_checkPreamble)
+ byteLen = 0;
do {
- if (CheckPreamble_Prop) {
- Debug.Assert(BytePos_Prop <= Preamble_Prop.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?");
- int tmpBytePos = BytePos_Prop;
+ if (_checkPreamble) {
+ Debug.Assert(bytePos <= _preamble.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?");
+ int tmpBytePos = bytePos;
int len = await tmpStream.ReadAsync(tmpByteBuffer, tmpBytePos, tmpByteBuffer.Length - tmpBytePos).ConfigureAwait(false);
Debug.Assert(len >= 0, "Stream.Read returned a negative number! This is a bug in your stream class.");
if (len == 0) {
// EOF but we might have buffered bytes from previous
// attempt to detect preamble that needs to be decoded now
- if (ByteLen_Prop > 0)
+ if (byteLen > 0)
{
- CharLen_Prop += Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, CharBuffer_Prop, CharLen_Prop);
+ charLen += decoder.GetChars(tmpByteBuffer, 0, byteLen, charBuffer, charLen);
// Need to zero out the _byteLen after we consume these bytes so that we don't keep infinitely hitting this code path
- BytePos_Prop = 0; ByteLen_Prop = 0;
+ bytePos = 0; byteLen = 0;
}
- return CharLen_Prop;
+ return charLen;
}
- ByteLen_Prop += len;
+ byteLen += len;
}
else {
- Debug.Assert(BytePos_Prop == 0, "_bytePos can be non zero only when we are trying to _checkPreamble. Are two threads using this StreamReader at the same time?");
- ByteLen_Prop = await tmpStream.ReadAsync(tmpByteBuffer, 0, tmpByteBuffer.Length).ConfigureAwait(false);
- Debug.Assert(ByteLen_Prop >= 0, "Stream.Read returned a negative number! Bug in stream class.");
+ Debug.Assert(bytePos == 0, "_bytePos can be non zero only when we are trying to _checkPreamble. Are two threads using this StreamReader at the same time?");
+ byteLen = await tmpStream.ReadAsync(tmpByteBuffer, 0, tmpByteBuffer.Length).ConfigureAwait(false);
+ Debug.Assert(byteLen >= 0, "Stream.Read returned a negative number! Bug in stream class.");
- if (ByteLen_Prop == 0) // We're at EOF
- return CharLen_Prop;
+ if (byteLen == 0) // We're at EOF
+ return charLen;
}
// _isBlocked == whether we read fewer bytes than we asked for.
// Note we must check it here because CompressBuffer or
// DetectEncoding will change _byteLen.
- IsBlocked_Prop = (ByteLen_Prop < tmpByteBuffer.Length);
+ _isBlocked = (byteLen < tmpByteBuffer.Length);
// Check for preamble before detect encoding. This is not to override the
// user suppplied Encoding for the one we implicitly detect. The user could
@@ -1199,13 +1136,13 @@ namespace System.IO
// If we're supposed to detect the encoding and haven't done so yet,
// do it. Note this may need to be called more than once.
- if (DetectEncoding_Prop && ByteLen_Prop >= 2)
+ if (_detectEncoding && byteLen >= 2)
DetectEncoding();
- CharLen_Prop += Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, CharBuffer_Prop, CharLen_Prop);
- } while (CharLen_Prop == 0);
+ charLen += decoder.GetChars(tmpByteBuffer, 0, byteLen, charBuffer, charLen);
+ } while (charLen == 0);
- return CharLen_Prop;
+ return charLen;
}
#endregion
@@ -1254,12 +1191,6 @@ namespace System.IO
{
return String.Empty;
}
-
- internal override int ReadBuffer()
- {
- return 0;
- }
-
}
}
}
diff --git a/src/mscorlib/src/System/IO/TextReader.cs b/src/mscorlib/src/System/IO/TextReader.cs
index 15ba8fba7d..3da68591b0 100644
--- a/src/mscorlib/src/System/IO/TextReader.cs
+++ b/src/mscorlib/src/System/IO/TextReader.cs
@@ -93,13 +93,13 @@ namespace System.IO {
public virtual int Read([In, Out] char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.Ensures(Contract.Result<int>() >= 0);
Contract.Ensures(Contract.Result<int>() <= Contract.OldValue(count));
Contract.EndContractBlock();
@@ -192,11 +192,11 @@ namespace System.IO {
public virtual Task<int> ReadAsync(char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
return ReadAsyncInternal(buffer, index, count);
@@ -221,11 +221,11 @@ namespace System.IO {
public virtual Task<int> ReadBlockAsync(char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
@@ -362,11 +362,11 @@ namespace System.IO {
public override Task<int> ReadBlockAsync(char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
@@ -377,11 +377,11 @@ namespace System.IO {
public override Task<int> ReadAsync(char[] buffer, int index, int count)
{
if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
return Task.FromResult(Read(buffer, index, count));
diff --git a/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs b/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs
index f3fd71833c..5f6f588cbe 100644
--- a/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs
+++ b/src/mscorlib/src/System/IO/UnmanagedMemoryAccessor.cs
@@ -12,6 +12,7 @@
**
**
===========================================================*/
+
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -21,13 +22,13 @@ using Microsoft.Win32.SafeHandles;
using System.Diagnostics;
using System.Diagnostics.Contracts;
-namespace System.IO {
-
+namespace System.IO
+{
/// Perf notes: ReadXXX, WriteXXX (for basic types) acquire and release the
/// SafeBuffer pointer rather than relying on generic Read(T) from SafeBuffer because
/// this gives better throughput; benchmarks showed about 12-15% better.
- public class UnmanagedMemoryAccessor : IDisposable {
-
+ public class UnmanagedMemoryAccessor : IDisposable
+ {
private SafeBuffer _buffer;
private Int64 _offset;
[ContractPublicPropertyName("Capacity")]
@@ -37,7 +38,8 @@ namespace System.IO {
private bool _canRead;
private bool _canWrite;
- protected UnmanagedMemoryAccessor() {
+ protected UnmanagedMemoryAccessor()
+ {
_isOpen = false;
}
@@ -45,47 +47,61 @@ namespace System.IO {
// <SecurityKernel Critical="True" Ring="1">
// <ReferencesCritical Name="Method: Initialize(SafeBuffer, Int64, Int64, FileAccess):Void" Ring="1" />
// </SecurityKernel>
- public UnmanagedMemoryAccessor(SafeBuffer buffer, Int64 offset, Int64 capacity) {
+ public UnmanagedMemoryAccessor(SafeBuffer buffer, Int64 offset, Int64 capacity)
+ {
Initialize(buffer, offset, capacity, FileAccess.Read);
}
- public UnmanagedMemoryAccessor(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access) {
+ public UnmanagedMemoryAccessor(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access)
+ {
Initialize(buffer, offset, capacity, access);
}
- protected void Initialize(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access) {
- if (buffer == null) {
+ protected void Initialize(SafeBuffer buffer, Int64 offset, Int64 capacity, FileAccess access)
+ {
+ if (buffer == null)
+ {
throw new ArgumentNullException(nameof(buffer));
}
- if (offset < 0) {
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (offset < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
}
- if (capacity < 0) {
- throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (capacity < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_NeedNonNegNum);
}
- if (buffer.ByteLength < (UInt64)(offset + capacity)) {
- throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndCapacityOutOfBounds"));
+ if (buffer.ByteLength < (UInt64)(offset + capacity))
+ {
+ throw new ArgumentException(SR.Argument_OffsetAndCapacityOutOfBounds);
}
- if (access < FileAccess.Read || access > FileAccess.ReadWrite) {
+ if (access < FileAccess.Read || access > FileAccess.ReadWrite)
+ {
throw new ArgumentOutOfRangeException(nameof(access));
}
Contract.EndContractBlock();
- if (_isOpen) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice"));
+ if (_isOpen)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_CalledTwice);
}
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
buffer.AcquirePointer(ref pointer);
- if (((byte*)((Int64)pointer + offset + capacity)) < pointer) {
- throw new ArgumentException(Environment.GetResourceString("Argument_UnmanagedMemAccessorWrapAround"));
+ if (((byte*)((Int64)pointer + offset + capacity)) < pointer)
+ {
+ throw new ArgumentException(SR.Argument_UnmanagedMemAccessorWrapAround);
}
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
buffer.ReleasePointer();
}
}
@@ -102,38 +118,48 @@ namespace System.IO {
#endregion
- public Int64 Capacity {
- get {
- return _capacity;
+ public Int64 Capacity
+ {
+ get
+ {
+ return _capacity;
}
}
- public bool CanRead {
- get {
- return _isOpen && _canRead;
+ public bool CanRead
+ {
+ get
+ {
+ return _isOpen && _canRead;
}
}
- public bool CanWrite {
- get {
- return _isOpen && _canWrite;
+ public bool CanWrite
+ {
+ get
+ {
+ return _isOpen && _canWrite;
}
}
- protected virtual void Dispose(bool disposing) {
+ protected virtual void Dispose(bool disposing)
+ {
_isOpen = false;
}
- public void Dispose() {
+ public void Dispose()
+ {
Dispose(true);
GC.SuppressFinalize(this);
}
- protected bool IsOpen {
+ protected bool IsOpen
+ {
get { return _isOpen; }
}
- public bool ReadBoolean(Int64 position) {
+ public bool ReadBoolean(Int64 position)
+ {
int sizeOfType = sizeof(bool);
EnsureSafeToRead(position, sizeOfType);
@@ -141,40 +167,32 @@ namespace System.IO {
return b != 0;
}
- public byte ReadByte(Int64 position) {
+ public byte ReadByte(Int64 position)
+ {
int sizeOfType = sizeof(byte);
EnsureSafeToRead(position, sizeOfType);
return InternalReadByte(position);
}
- public char ReadChar(Int64 position) {
- int sizeOfType = sizeof(char);
- EnsureSafeToRead(position, sizeOfType);
-
- char result;
+ public char ReadChar(Int64 position)
+ {
+ EnsureSafeToRead(position, sizeof(char));
- unsafe {
+ char result;
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- result = *((char*)(pointer));
-#if ALIGN_ACCESS
- }
- else {
- result = (char)( *pointer | *(pointer + 1) << 8 ) ;
- }
-#endif
+ result = Unsafe.ReadUnaligned<char>(pointer + _offset + position);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -184,33 +202,24 @@ namespace System.IO {
}
// See comment above.
- public Int16 ReadInt16(Int64 position) {
- int sizeOfType = sizeof(Int16);
- EnsureSafeToRead(position, sizeOfType);
+ public Int16 ReadInt16(Int64 position)
+ {
+ EnsureSafeToRead(position, sizeof(Int16));
Int16 result;
-
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- result = *((Int16*)(pointer));
-#if ALIGN_ACCESS
- }
- else {
- result = (Int16)( *pointer | *(pointer + 1) << 8 );
- }
-#endif
+ result = Unsafe.ReadUnaligned<Int16>(pointer + _offset + position);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -220,32 +229,24 @@ namespace System.IO {
}
- public Int32 ReadInt32(Int64 position) {
- int sizeOfType = sizeof(Int32);
- EnsureSafeToRead(position, sizeOfType);
+ public Int32 ReadInt32(Int64 position)
+ {
+ EnsureSafeToRead(position, sizeof(Int32));
Int32 result;
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- result = *((Int32*)(pointer));
-#if ALIGN_ACCESS
- }
- else {
- result = (Int32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 );
- }
-#endif
+ result = Unsafe.ReadUnaligned<Int32>(pointer + _offset + position);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -254,34 +255,24 @@ namespace System.IO {
return result;
}
- public Int64 ReadInt64(Int64 position) {
- int sizeOfType = sizeof(Int64);
- EnsureSafeToRead(position, sizeOfType);
+ public Int64 ReadInt64(Int64 position)
+ {
+ EnsureSafeToRead(position, sizeof(Int64));
Int64 result;
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- result = *((Int64*)(pointer));
-#if ALIGN_ACCESS
- }
- else {
- int lo = *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24;
- int hi = *(pointer + 4) | *(pointer + 5) << 8 | *(pointer + 6) << 16 | *(pointer + 7) << 24;
- result = (Int64)(((Int64)hi << 32) | (UInt32)lo);
- }
-#endif
- }
- finally {
- if (pointer != null) {
+ result = Unsafe.ReadUnaligned<Int64>(pointer + _offset + position);
+ }
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -290,28 +281,14 @@ namespace System.IO {
return result;
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private unsafe Int32 UnsafeReadInt32(byte* pointer)
+ public Decimal ReadDecimal(Int64 position)
{
- Int32 result;
- // check if pointer is aligned
- if (((int)pointer & (sizeof(Int32) - 1)) == 0)
- {
- result = *((Int32*)pointer);
- }
- else
- {
- result = (Int32)(*(pointer) | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24);
- }
-
- return result;
- }
- public Decimal ReadDecimal(Int64 position) {
const int ScaleMask = 0x00FF0000;
const int SignMask = unchecked((int)0x80000000);
- int sizeOfType = sizeof(Decimal);
- EnsureSafeToRead(position, sizeOfType);
+ EnsureSafeToRead(position, sizeof(Decimal));
+
+ int lo, mid, hi, flags;
unsafe
{
@@ -319,23 +296,11 @@ namespace System.IO {
try
{
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
- int lo = UnsafeReadInt32(pointer);
- int mid = UnsafeReadInt32(pointer + 4);
- int hi = UnsafeReadInt32(pointer + 8);
- int flags = UnsafeReadInt32(pointer + 12);
-
- // Check for invalid Decimal values
- if (!((flags & ~(SignMask | ScaleMask)) == 0 && (flags & ScaleMask) <= (28 << 16)))
- {
- throw new ArgumentException(Environment.GetResourceString("Arg_BadDecimal")); // Throw same Exception type as Decimal(int[]) ctor for compat
- }
-
- bool isNegative = (flags & SignMask) != 0;
- byte scale = (byte)(flags >> 16);
-
- return new decimal(lo, mid, hi, isNegative, scale);
+
+ lo = Unsafe.ReadUnaligned<Int32>(pointer + _offset + position);
+ mid = Unsafe.ReadUnaligned<Int32>(pointer + _offset + position + 4);
+ hi = Unsafe.ReadUnaligned<Int32>(pointer + _offset + position + 8);
+ flags = Unsafe.ReadUnaligned<Int32>(pointer + _offset + position + 12);
}
finally
{
@@ -345,35 +310,37 @@ namespace System.IO {
}
}
}
+
+ // Check for invalid Decimal values
+ if (!((flags & ~(SignMask | ScaleMask)) == 0 && (flags & ScaleMask) <= (28 << 16)))
+ {
+ throw new ArgumentException(SR.Arg_BadDecimal); // Throw same Exception type as Decimal(int[]) ctor for compat
+ }
+
+ bool isNegative = (flags & SignMask) != 0;
+ byte scale = (byte)(flags >> 16);
+
+ return new decimal(lo, mid, hi, isNegative, scale);
}
- public Single ReadSingle(Int64 position) {
- int sizeOfType = sizeof(Single);
- EnsureSafeToRead(position, sizeOfType);
+ public Single ReadSingle(Int64 position)
+ {
+ EnsureSafeToRead(position, sizeof(Single));
Single result;
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- result = BitConverter.Int32BitsToSingle(*((int*)(pointer)));
-#if ALIGN_ACCESS
- }
- else {
- UInt32 tempResult = (UInt32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 );
- result = *((float*)&tempResult);
- }
-#endif
+ result = Unsafe.ReadUnaligned<Single>(pointer + _offset + position);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -382,37 +349,24 @@ namespace System.IO {
return result;
}
- public Double ReadDouble(Int64 position) {
- int sizeOfType = sizeof(Double);
- EnsureSafeToRead(position, sizeOfType);
+ public Double ReadDouble(Int64 position)
+ {
+ EnsureSafeToRead(position, sizeof(Double));
Double result;
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- result = BitConverter.Int64BitsToDouble(*((long*)(pointer)));
-#if ALIGN_ACCESS
- }
- else {
-
- UInt32 lo = (UInt32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 );
- UInt32 hi = (UInt32)( *(pointer + 4) | *(pointer + 5) << 8 | *(pointer + 6) << 16 | *(pointer + 7) << 24 );
- UInt64 tempResult = ((UInt64)hi) << 32 | lo;
- result = *((double*)&tempResult);
-
- }
-#endif
+ result = Unsafe.ReadUnaligned<Double>(pointer + _offset + position);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -422,21 +376,25 @@ namespace System.IO {
}
[CLSCompliant(false)]
- public SByte ReadSByte(Int64 position) {
+ public SByte ReadSByte(Int64 position)
+ {
int sizeOfType = sizeof(SByte);
EnsureSafeToRead(position, sizeOfType);
SByte result;
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
- result = *((SByte*)pointer);
+ result = *((SByte*)(pointer + _offset + position));
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -444,35 +402,26 @@ namespace System.IO {
return result;
}
-
+
[CLSCompliant(false)]
- public UInt16 ReadUInt16(Int64 position) {
- int sizeOfType = sizeof(UInt16);
- EnsureSafeToRead(position, sizeOfType);
+ public UInt16 ReadUInt16(Int64 position)
+ {
+ EnsureSafeToRead(position, sizeof(UInt16));
UInt16 result;
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- result = *((UInt16*)(pointer));
-#if ALIGN_ACCESS
- }
- else {
- result = (UInt16)( *pointer | *(pointer + 1) << 8 );
- }
-#endif
-
+ result = Unsafe.ReadUnaligned<UInt16>(pointer + _offset + position);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -480,35 +429,26 @@ namespace System.IO {
return result;
}
-
+
[CLSCompliant(false)]
- public UInt32 ReadUInt32(Int64 position) {
- int sizeOfType = sizeof(UInt32);
- EnsureSafeToRead(position, sizeOfType);
+ public UInt32 ReadUInt32(Int64 position)
+ {
+ EnsureSafeToRead(position, sizeof(UInt32));
UInt32 result;
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- result = *((UInt32*)(pointer));
-#if ALIGN_ACCESS
- }
- else {
- result = (UInt32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 );
- }
-#endif
-
+ result = Unsafe.ReadUnaligned<UInt32>(pointer + _offset + position);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -518,35 +458,24 @@ namespace System.IO {
}
[CLSCompliant(false)]
- public UInt64 ReadUInt64(Int64 position) {
- int sizeOfType = sizeof(UInt64);
- EnsureSafeToRead(position, sizeOfType);
+ public UInt64 ReadUInt64(Int64 position)
+ {
+ EnsureSafeToRead(position, sizeof(UInt64));
UInt64 result;
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- result = *((UInt64*)(pointer));
-#if ALIGN_ACCESS
- }
- else {
- UInt32 lo = (UInt32)( *pointer | *(pointer + 1) << 8 | *(pointer + 2) << 16 | *(pointer + 3) << 24 );
- UInt32 hi = (UInt32)( *(pointer + 4) | *(pointer + 5) << 8 | *(pointer + 6) << 16 | *(pointer + 7) << 24 );
- result = (UInt64)(((UInt64)hi << 32) | lo );
- }
-#endif
-
+ result = Unsafe.ReadUnaligned<UInt64>(pointer + _offset + position);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -569,26 +498,33 @@ namespace System.IO {
// such, it is best to use the ReadXXX methods for small standard types such as ints, longs,
// bools, etc.
- public void Read<T>(Int64 position, out T structure) where T : struct {
- if (position < 0) {
- throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ public void Read<T>(Int64 position, out T structure) where T : struct
+ {
+ if (position < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
- if (!_isOpen) {
- throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
+ if (!_isOpen)
+ {
+ throw new ObjectDisposedException("UnmanagedMemoryAccessor", SR.ObjectDisposed_ViewAccessorClosed);
}
- if (!CanRead) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_Reading"));
+ if (!CanRead)
+ {
+ throw new NotSupportedException(SR.NotSupported_Reading);
}
UInt32 sizeOfT = Marshal.SizeOfType(typeof(T));
- if (position > _capacity - sizeOfT) {
- if (position >= _capacity) {
- throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
+ if (position > _capacity - sizeOfT)
+ {
+ if (position >= _capacity)
+ {
+ throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_PositionLessThanCapacityRequired);
}
- else {
- throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToRead", typeof(T).FullName), nameof(position));
+ else
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_NotEnoughBytesToRead, typeof (T).FullName), nameof(position));
}
}
@@ -601,47 +537,60 @@ namespace System.IO {
// struct that contains reference members will most likely cause the runtime to AV. This
// is consistent with Marshal.PtrToStructure.
- public int ReadArray<T>(Int64 position, T[] array, Int32 offset, Int32 count) where T : struct {
- if (array == null) {
+ public int ReadArray<T>(Int64 position, T[] array, Int32 offset, Int32 count) where T : struct
+ {
+ if (array == null)
+ {
throw new ArgumentNullException(nameof(array), "Buffer cannot be null.");
}
- if (offset < 0) {
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (offset < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
}
- if (count < 0) {
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (count < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
}
- if (array.Length - offset < count) {
- throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndLengthOutOfBounds"));
+ if (array.Length - offset < count)
+ {
+ throw new ArgumentException(SR.Argument_OffsetAndLengthOutOfBounds);
}
Contract.EndContractBlock();
- if (!CanRead) {
- if (!_isOpen) {
- throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
+ if (!CanRead)
+ {
+ if (!_isOpen)
+ {
+ throw new ObjectDisposedException("UnmanagedMemoryAccessor", SR.ObjectDisposed_ViewAccessorClosed);
}
- else {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_Reading"));
+ else
+ {
+ throw new NotSupportedException(SR.NotSupported_Reading);
}
}
- if (position < 0) {
- throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (position < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_NeedNonNegNum);
}
UInt32 sizeOfT = Marshal.AlignedSizeOf<T>();
// only check position and ask for fewer Ts if count is too big
- if (position >= _capacity) {
- throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
+ if (position >= _capacity)
+ {
+ throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_PositionLessThanCapacityRequired);
}
int n = count;
long spaceLeft = _capacity - position;
- if (spaceLeft < 0) {
+ if (spaceLeft < 0)
+ {
n = 0;
}
- else {
+ else
+ {
ulong spaceNeeded = (ulong)(sizeOfT * count);
- if ((ulong)spaceLeft < spaceNeeded) {
+ if ((ulong)spaceLeft < spaceNeeded)
+ {
n = (int)(spaceLeft / sizeOfT);
}
}
@@ -659,7 +608,8 @@ namespace System.IO {
// double, short, int, long, sbyte, float, ushort, uint, or ulong.
- public void Write(Int64 position, bool value) {
+ public void Write(Int64 position, bool value)
+ {
int sizeOfType = sizeof(bool);
EnsureSafeToWrite(position, sizeOfType);
@@ -667,73 +617,55 @@ namespace System.IO {
InternalWrite(position, b);
}
- public void Write(Int64 position, byte value) {
+ public void Write(Int64 position, byte value)
+ {
int sizeOfType = sizeof(byte);
EnsureSafeToWrite(position, sizeOfType);
InternalWrite(position, value);
}
- public void Write(Int64 position, char value) {
- int sizeOfType = sizeof(char);
- EnsureSafeToWrite(position, sizeOfType);
+ public void Write(Int64 position, char value)
+ {
+ EnsureSafeToWrite(position, sizeof(char));
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- *((char*)pointer) = value;
-#if ALIGN_ACCESS
- }
- else {
- *(pointer) = (byte)value;
- *(pointer+1) = (byte)(value >> 8);
- }
-#endif
+ Unsafe.WriteUnaligned<char>(pointer + _offset + position, value);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
}
-
}
- public void Write(Int64 position, Int16 value) {
- int sizeOfType = sizeof(Int16);
- EnsureSafeToWrite(position, sizeOfType);
+ public void Write(Int64 position, Int16 value)
+ {
+ EnsureSafeToWrite(position, sizeof(Int16));
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- *((Int16*)pointer) = value;
-#if ALIGN_ACCESS
- }
- else {
- *(pointer) = (byte)value;
- *(pointer + 1) = (byte)(value >> 8);
- }
-#endif
+ Unsafe.WriteUnaligned<Int16>(pointer + _offset + position, value);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -741,116 +673,73 @@ namespace System.IO {
}
- public void Write(Int64 position, Int32 value) {
- int sizeOfType = sizeof(Int32);
- EnsureSafeToWrite(position, sizeOfType);
+ public void Write(Int64 position, Int32 value)
+ {
+ EnsureSafeToWrite(position, sizeof(Int32));
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- *((Int32*)pointer) = value;
-#if ALIGN_ACCESS
- }
- else {
- *(pointer) = (byte)value;
- *(pointer + 1) = (byte)(value >> 8);
- *(pointer + 2) = (byte)(value >> 16);
- *(pointer + 3) = (byte)(value >> 24);
- }
-#endif
+ Unsafe.WriteUnaligned<Int32>(pointer + _offset + position, value);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
}
}
- public void Write(Int64 position, Int64 value) {
- int sizeOfType = sizeof(Int64);
- EnsureSafeToWrite(position, sizeOfType);
+ public void Write(Int64 position, Int64 value)
+ {
+ EnsureSafeToWrite(position, sizeof(Int64));
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- *((Int64*)pointer) = value;
-#if ALIGN_ACCESS
- }
- else {
- *(pointer) = (byte)value;
- *(pointer + 1) = (byte)(value >> 8);
- *(pointer + 2) = (byte)(value >> 16);
- *(pointer + 3) = (byte)(value >> 24);
- *(pointer + 4) = (byte)(value >> 32);
- *(pointer + 5) = (byte)(value >> 40);
- *(pointer + 6) = (byte)(value >> 48);
- *(pointer + 7) = (byte)(value >> 56);
- }
-#endif
+ Unsafe.WriteUnaligned<Int64>(pointer + _offset + position, value);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
}
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private unsafe void UnsafeWriteInt32(byte* pointer, Int32 value)
+ public void Write(Int64 position, Decimal value)
{
- // check if pointer is aligned
- if (((int)pointer & (sizeof(Int32) - 1)) == 0)
- {
- *((Int32*)pointer) = value;
- }
- else
- {
- *(pointer) = (byte)value;
- *(pointer + 1) = (byte)(value >> 8);
- *(pointer + 2) = (byte)(value >> 16);
- *(pointer + 3) = (byte)(value >> 24);
- }
- }
-
- public void Write(Int64 position, Decimal value) {
- int sizeOfType = sizeof(Decimal);
- EnsureSafeToWrite(position, sizeOfType);
+ EnsureSafeToWrite(position, sizeof(Decimal));
unsafe
{
+ int* valuePtr = (int*)(&value);
+ int flags = *valuePtr;
+ int hi = *(valuePtr + 1);
+ int lo = *(valuePtr + 2);
+ int mid = *(valuePtr + 3);
+
byte* pointer = null;
try
{
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
- int* valuePtr = (int*)(&value);
- int flags = *valuePtr;
- int hi = *(valuePtr + 1);
- int lo = *(valuePtr + 2);
- int mid = *(valuePtr + 3);
-
- UnsafeWriteInt32(pointer, lo);
- UnsafeWriteInt32(pointer + 4, mid);
- UnsafeWriteInt32(pointer + 8, hi);
- UnsafeWriteInt32(pointer + 12, flags);
+
+ Unsafe.WriteUnaligned<Int32>(pointer + _offset + position, lo);
+ Unsafe.WriteUnaligned<Int32>(pointer + _offset + position + 4, mid);
+ Unsafe.WriteUnaligned<Int32>(pointer + _offset + position + 8, hi);
+ Unsafe.WriteUnaligned<Int32>(pointer + _offset + position + 12, flags);
}
finally
{
@@ -862,74 +751,46 @@ namespace System.IO {
}
}
- public void Write(Int64 position, Single value) {
- int sizeOfType = sizeof(Single);
- EnsureSafeToWrite(position, sizeOfType);
+ public void Write(Int64 position, Single value)
+ {
+ EnsureSafeToWrite(position, sizeof(Single));
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- *((int*)pointer) = BitConverter.SingleToInt32Bits(value);
-#if ALIGN_ACCESS
- }
- else {
- UInt32 tmpValue = *(UInt32*)&value;
- *(pointer) = (byte)tmpValue;
- *(pointer + 1) = (byte)(tmpValue >> 8);
- *(pointer + 2) = (byte)(tmpValue >> 16);
- *(pointer + 3) = (byte)(tmpValue >> 24);
-
- }
-#endif
+ Unsafe.WriteUnaligned<Single>(pointer + _offset + position, value);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
}
}
- public void Write(Int64 position, Double value) {
- int sizeOfType = sizeof(Double);
- EnsureSafeToWrite(position, sizeOfType);
+ public void Write(Int64 position, Double value)
+ {
+ EnsureSafeToWrite(position, sizeof(Double));
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- *((long*)pointer) = BitConverter.DoubleToInt64Bits(value);
-#if ALIGN_ACCESS
- }
- else {
- UInt64 tmpValue = *(UInt64 *)&value;
- *(pointer) = (byte) tmpValue;
- *(pointer + 1) = (byte) (tmpValue >> 8);
- *(pointer + 2) = (byte) (tmpValue >> 16);
- *(pointer + 3) = (byte) (tmpValue >> 24);
- *(pointer + 4) = (byte) (tmpValue >> 32);
- *(pointer + 5) = (byte) (tmpValue >> 40);
- *(pointer + 6) = (byte) (tmpValue >> 48);
- *(pointer + 7) = (byte) (tmpValue >> 56);
-
- }
-#endif
+ Unsafe.WriteUnaligned<Double>(pointer + _offset + position, value);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -937,20 +798,23 @@ namespace System.IO {
}
[CLSCompliant(false)]
- public void Write(Int64 position, SByte value) {
- int sizeOfType = sizeof(SByte);
- EnsureSafeToWrite(position, sizeOfType);
+ public void Write(Int64 position, SByte value)
+ {
+ EnsureSafeToWrite(position, sizeof(SByte));
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
- *((SByte*)pointer) = value;
+ *((SByte*)(pointer + _offset + position)) = value;
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -958,32 +822,24 @@ namespace System.IO {
}
[CLSCompliant(false)]
- public void Write(Int64 position, UInt16 value) {
+ public void Write(Int64 position, UInt16 value)
+ {
int sizeOfType = sizeof(UInt16);
EnsureSafeToWrite(position, sizeOfType);
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- *((UInt16*)pointer) = value;
-#if ALIGN_ACCESS
- }
- else {
- *(pointer) = (byte)value;
- *(pointer + 1) = (byte)(value >> 8);
- }
-#endif
+ Unsafe.WriteUnaligned<UInt16>(pointer + _offset + position, value);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -991,35 +847,23 @@ namespace System.IO {
}
[CLSCompliant(false)]
- public void Write(Int64 position, UInt32 value) {
- int sizeOfType = sizeof(UInt32);
- EnsureSafeToWrite(position, sizeOfType);
+ public void Write(Int64 position, UInt32 value)
+ {
+ EnsureSafeToWrite(position, sizeof(UInt32));
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- *((UInt32*)pointer) = value;
-#if ALIGN_ACCESS
- }
- else {
- *(pointer) = (byte)value;
- *(pointer + 1) = (byte)(value >> 8);
- *(pointer + 2) = (byte)(value >> 16);
- *(pointer + 3) = (byte)(value >> 24);
- }
-#endif
-
+ Unsafe.WriteUnaligned<UInt32>(pointer + _offset + position, value);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -1027,38 +871,23 @@ namespace System.IO {
}
[CLSCompliant(false)]
- public void Write(Int64 position, UInt64 value) {
- int sizeOfType = sizeof(UInt64);
- EnsureSafeToWrite(position, sizeOfType);
+ public void Write(Int64 position, UInt64 value)
+ {
+ EnsureSafeToWrite(position, sizeof(UInt64));
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- pointer += (_offset + position);
-#if ALIGN_ACCESS
- // check if pointer is aligned
- if (((int)pointer & (sizeOfType - 1)) == 0) {
-#endif
- *((UInt64*)pointer) = value;
-#if ALIGN_ACCESS
- }
- else {
- *(pointer) = (byte)value;
- *(pointer + 1) = (byte)(value >> 8);
- *(pointer + 2) = (byte)(value >> 16);
- *(pointer + 3) = (byte)(value >> 24);
- *(pointer + 4) = (byte)(value >> 32);
- *(pointer + 5) = (byte)(value >> 40);
- *(pointer + 6) = (byte)(value >> 48);
- *(pointer + 7) = (byte)(value >> 56);
- }
-#endif
-
+ Unsafe.WriteUnaligned<UInt64>(pointer + _offset + position, value);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -1070,26 +899,33 @@ namespace System.IO {
// though this is number is JIT and architecture dependent). As such, it is best to use
// the WriteX methods for small standard types such as ints, longs, bools, etc.
- public void Write<T>(Int64 position, ref T structure) where T : struct {
- if (position < 0) {
- throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ public void Write<T>(Int64 position, ref T structure) where T : struct
+ {
+ if (position < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
- if (!_isOpen) {
- throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
+ if (!_isOpen)
+ {
+ throw new ObjectDisposedException("UnmanagedMemoryAccessor", SR.ObjectDisposed_ViewAccessorClosed);
}
- if (!CanWrite) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_Writing"));
+ if (!CanWrite)
+ {
+ throw new NotSupportedException(SR.NotSupported_Writing);
}
UInt32 sizeOfT = Marshal.SizeOfType(typeof(T));
- if (position > _capacity - sizeOfT) {
- if (position >= _capacity) {
- throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
+ if (position > _capacity - sizeOfT)
+ {
+ if (position >= _capacity)
+ {
+ throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_PositionLessThanCapacityRequired);
}
- else {
- throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToWrite", typeof(T).FullName), nameof(position));
+ else
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_NotEnoughBytesToWrite, typeof (T).FullName), nameof(position));
}
}
@@ -1099,52 +935,66 @@ namespace System.IO {
// Writes 'count' structs of type T from 'array' (starting at 'offset') into unmanaged memory.
- public void WriteArray<T>(Int64 position, T[] array, Int32 offset, Int32 count) where T : struct {
- if (array == null) {
+ public void WriteArray<T>(Int64 position, T[] array, Int32 offset, Int32 count) where T : struct
+ {
+ if (array == null)
+ {
throw new ArgumentNullException(nameof(array), "Buffer cannot be null.");
}
- if (offset < 0) {
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (offset < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
}
- if (count < 0) {
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (count < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
}
- if (array.Length - offset < count) {
- throw new ArgumentException(Environment.GetResourceString("Argument_OffsetAndLengthOutOfBounds"));
+ if (array.Length - offset < count)
+ {
+ throw new ArgumentException(SR.Argument_OffsetAndLengthOutOfBounds);
}
- if (position < 0) {
- throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (position < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_NeedNonNegNum);
}
- if (position >= Capacity) {
- throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
+ if (position >= Capacity)
+ {
+ throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_PositionLessThanCapacityRequired);
}
Contract.EndContractBlock();
- if (!_isOpen) {
- throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
+ if (!_isOpen)
+ {
+ throw new ObjectDisposedException("UnmanagedMemoryAccessor", SR.ObjectDisposed_ViewAccessorClosed);
}
- if (!CanWrite) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_Writing"));
+ if (!CanWrite)
+ {
+ throw new NotSupportedException(SR.NotSupported_Writing);
}
_buffer.WriteArray<T>((UInt64)(_offset + position), array, offset, count);
}
- private byte InternalReadByte(Int64 position) {
+ private byte InternalReadByte(Int64 position)
+ {
Debug.Assert(CanRead, "UMA not readable");
Debug.Assert(position >= 0, "position less than 0");
Debug.Assert(position <= _capacity - sizeof(byte), "position is greater than capacity - sizeof(byte)");
byte result;
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- result = *((byte*)(pointer + _offset + position));
+ result = *(pointer + _offset + position);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
@@ -1152,67 +1002,85 @@ namespace System.IO {
return result;
}
- private void InternalWrite(Int64 position, byte value) {
+ private void InternalWrite(Int64 position, byte value)
+ {
Debug.Assert(CanWrite, "UMA not writable");
Debug.Assert(position >= 0, "position less than 0");
Debug.Assert(position <= _capacity - sizeof(byte), "position is greater than capacity - sizeof(byte)");
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
- *((byte*)(pointer + _offset + position)) = value;
+ *(pointer + _offset + position) = value;
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
}
}
- private void EnsureSafeToRead(Int64 position, int sizeOfType) {
- if (!_isOpen) {
- throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
+ private void EnsureSafeToRead(Int64 position, int sizeOfType)
+ {
+ if (!_isOpen)
+ {
+ throw new ObjectDisposedException("UnmanagedMemoryAccessor", SR.ObjectDisposed_ViewAccessorClosed);
}
- if (!CanRead) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_Reading"));
+ if (!CanRead)
+ {
+ throw new NotSupportedException(SR.NotSupported_Reading);
}
- if (position < 0) {
- throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (position < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
- if (position > _capacity - sizeOfType) {
- if (position >= _capacity) {
- throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
+ if (position > _capacity - sizeOfType)
+ {
+ if (position >= _capacity)
+ {
+ throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_PositionLessThanCapacityRequired);
}
- else {
- throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToRead"), nameof(position));
+ else
+ {
+ throw new ArgumentException(SR.Argument_NotEnoughBytesToRead, nameof(position));
}
}
}
- private void EnsureSafeToWrite(Int64 position, int sizeOfType) {
- if (!_isOpen) {
- throw new ObjectDisposedException("UnmanagedMemoryAccessor", Environment.GetResourceString("ObjectDisposed_ViewAccessorClosed"));
+ private void EnsureSafeToWrite(Int64 position, int sizeOfType)
+ {
+ if (!_isOpen)
+ {
+ throw new ObjectDisposedException("UnmanagedMemoryAccessor", SR.ObjectDisposed_ViewAccessorClosed);
}
- if (!CanWrite) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_Writing"));
+ if (!CanWrite)
+ {
+ throw new NotSupportedException(SR.NotSupported_Writing);
}
- if (position < 0) {
- throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (position < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_NeedNonNegNum);
}
Contract.EndContractBlock();
- if (position > _capacity - sizeOfType) {
- if (position >= _capacity) {
- throw new ArgumentOutOfRangeException(nameof(position), Environment.GetResourceString("ArgumentOutOfRange_PositionLessThanCapacityRequired"));
+ if (position > _capacity - sizeOfType)
+ {
+ if (position >= _capacity)
+ {
+ throw new ArgumentOutOfRangeException(nameof(position), SR.ArgumentOutOfRange_PositionLessThanCapacityRequired);
}
- else {
- throw new ArgumentException(Environment.GetResourceString("Argument_NotEnoughBytesToWrite", nameof(Byte)), nameof(position));
+ else
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_NotEnoughBytesToWrite, nameof(Byte)), nameof(position));
}
}
}
-
}
}
diff --git a/src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs b/src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs
index 165b6d2b19..f21fe47371 100644
--- a/src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs
+++ b/src/mscorlib/src/System/IO/UnmanagedMemoryStream.cs
@@ -12,6 +12,7 @@
**
**
===========================================================*/
+
using System;
using System.Runtime;
using System.Runtime.CompilerServices;
@@ -20,11 +21,11 @@ using System.Security;
using System.Threading;
using System.Diagnostics;
using System.Diagnostics.Contracts;
-using System.Threading.Tasks;
-
+using System.Threading.Tasks;
-namespace System.IO {
+namespace System.IO
+{
/*
* This class is used to access a contiguous block of memory, likely outside
* the GC heap (or pinned in place in the GC heap, but a MemoryStream may
@@ -93,61 +94,76 @@ namespace System.IO {
private long _offset;
private FileAccess _access;
internal bool _isOpen;
- [NonSerialized]
+ [NonSerialized]
private Task<Int32> _lastReadTask; // The last successful task returned from ReadAsync
// Needed for subclasses that need to map a file, etc.
protected UnmanagedMemoryStream()
{
- unsafe {
+ unsafe
+ {
_mem = null;
}
_isOpen = false;
}
- public UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length) {
+ public UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length)
+ {
Initialize(buffer, offset, length, FileAccess.Read);
}
- public UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length, FileAccess access) {
+ public UnmanagedMemoryStream(SafeBuffer buffer, long offset, long length, FileAccess access)
+ {
Initialize(buffer, offset, length, access);
}
- protected void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access) {
- if (buffer == null) {
+ protected void Initialize(SafeBuffer buffer, long offset, long length, FileAccess access)
+ {
+ if (buffer == null)
+ {
throw new ArgumentNullException(nameof(buffer));
}
- if (offset < 0) {
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (offset < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
}
- if (length < 0) {
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ if (length < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NeedNonNegNum);
}
- if (buffer.ByteLength < (ulong)(offset + length)) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSafeBufferOffLen"));
+ if (buffer.ByteLength < (ulong)(offset + length))
+ {
+ throw new ArgumentException(SR.Argument_InvalidSafeBufferOffLen);
}
- if (access < FileAccess.Read || access > FileAccess.ReadWrite) {
+ if (access < FileAccess.Read || access > FileAccess.ReadWrite)
+ {
throw new ArgumentOutOfRangeException(nameof(access));
}
Contract.EndContractBlock();
- if (_isOpen) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice"));
+ if (_isOpen)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_CalledTwice);
}
// check for wraparound
- unsafe {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
buffer.AcquirePointer(ref pointer);
- if ( (pointer + offset + length) < pointer) {
- throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamWrapAround"));
+ if ((pointer + offset + length) < pointer)
+ {
+ throw new ArgumentException(SR.ArgumentOutOfRange_UnmanagedMemStreamWrapAround);
}
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
buffer.ReleasePointer();
}
}
@@ -168,28 +184,28 @@ namespace System.IO {
}
[CLSCompliant(false)]
- public unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, FileAccess access)
+ public unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, FileAccess access)
{
Initialize(pointer, length, capacity, access);
}
[CLSCompliant(false)]
- protected unsafe void Initialize(byte* pointer, long length, long capacity, FileAccess access)
+ protected unsafe void Initialize(byte* pointer, long length, long capacity, FileAccess access)
{
if (pointer == null)
throw new ArgumentNullException(nameof(pointer));
if (length < 0 || capacity < 0)
- throw new ArgumentOutOfRangeException((length < 0) ? nameof(length) : nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((length < 0) ? nameof(length) : nameof(capacity), SR.ArgumentOutOfRange_NeedNonNegNum);
if (length > capacity)
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_LengthGreaterThanCapacity"));
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_LengthGreaterThanCapacity);
Contract.EndContractBlock();
// Check for wraparound.
- if (((byte*) ((long)pointer + capacity)) < pointer)
- throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamWrapAround"));
+ if (((byte*)((long)pointer + capacity)) < pointer)
+ throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_UnmanagedMemStreamWrapAround);
if (access < FileAccess.Read || access > FileAccess.ReadWrite)
- throw new ArgumentOutOfRangeException(nameof(access), Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(nameof(access), SR.ArgumentOutOfRange_Enum);
if (_isOpen)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CalledTwice"));
+ throw new InvalidOperationException(SR.InvalidOperation_CalledTwice);
_mem = pointer;
_offset = 0;
@@ -199,17 +215,20 @@ namespace System.IO {
_isOpen = true;
}
- public override bool CanRead {
+ public override bool CanRead
+ {
[Pure]
get { return _isOpen && (_access & FileAccess.Read) != 0; }
}
- public override bool CanSeek {
+ public override bool CanSeek
+ {
[Pure]
get { return _isOpen; }
}
- public override bool CanWrite {
+ public override bool CanWrite
+ {
[Pure]
get { return _isOpen && (_access & FileAccess.Write) != 0; }
}
@@ -225,58 +244,66 @@ namespace System.IO {
base.Dispose(disposing);
}
- public override void Flush() {
+ public override void Flush()
+ {
if (!_isOpen) __Error.StreamIsClosed();
}
-
- public override Task FlushAsync(CancellationToken cancellationToken) {
-
- if (cancellationToken.IsCancellationRequested)
- return Task.FromCanceled(cancellationToken);
-
- try {
-
- Flush();
- return Task.CompletedTask;
-
- } catch(Exception ex) {
-
- return Task.FromException(ex);
- }
- }
-
-
- public override long Length {
- get {
+
+ public override Task FlushAsync(CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ return Task.FromCanceled(cancellationToken);
+
+ try
+ {
+ Flush();
+ return Task.CompletedTask;
+ }
+ catch (Exception ex)
+ {
+ return Task.FromException(ex);
+ }
+ }
+
+
+ public override long Length
+ {
+ get
+ {
if (!_isOpen) __Error.StreamIsClosed();
return Interlocked.Read(ref _length);
}
}
- public long Capacity {
- get {
+ public long Capacity
+ {
+ get
+ {
if (!_isOpen) __Error.StreamIsClosed();
return _capacity;
}
}
- public override long Position {
- get {
+ public override long Position
+ {
+ get
+ {
if (!CanSeek) __Error.StreamIsClosed();
Contract.EndContractBlock();
return Interlocked.Read(ref _position);
}
- set {
+ set
+ {
if (value < 0)
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
if (!CanSeek) __Error.StreamIsClosed();
-
+
#if !BIT64
unsafe {
// On 32 bit machines, ensure we don't wrap around.
if (value > (long) Int32.MaxValue || _mem + value < _mem)
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_StreamLength"));
+ throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_StreamLength);
}
#endif
Interlocked.Exchange(ref _position, value);
@@ -284,54 +311,61 @@ namespace System.IO {
}
[CLSCompliant(false)]
- public unsafe byte* PositionPointer {
- get {
- if (_buffer != null) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer"));
+ public unsafe byte* PositionPointer
+ {
+ get
+ {
+ if (_buffer != null)
+ {
+ throw new NotSupportedException(SR.NotSupported_UmsSafeBuffer);
}
// Use a temp to avoid a race
long pos = Interlocked.Read(ref _position);
if (pos > _capacity)
- throw new IndexOutOfRangeException(Environment.GetResourceString("IndexOutOfRange_UMSPosition"));
- byte * ptr = _mem + pos;
+ throw new IndexOutOfRangeException(SR.IndexOutOfRange_UMSPosition);
+ byte* ptr = _mem + pos;
if (!_isOpen) __Error.StreamIsClosed();
return ptr;
}
- set {
+ set
+ {
if (_buffer != null)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer"));
+ throw new NotSupportedException(SR.NotSupported_UmsSafeBuffer);
if (!_isOpen) __Error.StreamIsClosed();
// Note: subtracting pointers returns an Int64. Working around
// to avoid hitting compiler warning CS0652 on this line.
if (new IntPtr(value - _mem).ToInt64() > UnmanagedMemStreamMaxLength)
- throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamLength"));
+ throw new ArgumentOutOfRangeException("offset", SR.ArgumentOutOfRange_UnmanagedMemStreamLength);
if (value < _mem)
- throw new IOException(Environment.GetResourceString("IO.IO_SeekBeforeBegin"));
+ throw new IOException(SR.IO_SeekBeforeBegin);
Interlocked.Exchange(ref _position, value - _mem);
}
}
- internal unsafe byte* Pointer {
- get {
+ internal unsafe byte* Pointer
+ {
+ get
+ {
if (_buffer != null)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer"));
+ throw new NotSupportedException(SR.NotSupported_UmsSafeBuffer);
return _mem;
}
}
-
- public override int Read([In, Out] byte[] buffer, int offset, int count) {
- if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+
+ public override int Read([In, Out] byte[] buffer, int offset, int count)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (offset < 0)
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock(); // Keep this in sync with contract validation in ReadAsync
if (!_isOpen) __Error.StreamIsClosed();
@@ -347,7 +381,7 @@ namespace System.IO {
if (n <= 0)
return 0;
- int nInt = (int) n; // Safe because n <= count, which is an Int32
+ int nInt = (int)n; // Safe because n <= count, which is an Int32
if (nInt < 0)
return 0; // _position could be beyond EOF
Debug.Assert(pos + nInt >= 0, "_position + n >= 0"); // len is less than 2^63 -1.
@@ -383,35 +417,37 @@ namespace System.IO {
Interlocked.Exchange(ref _position, pos + n);
return nInt;
}
-
- public override Task<Int32> ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) {
- if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+
+ public override Task<Int32> ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (offset < 0)
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock(); // contract validation copied from Read(...)
-
- if (cancellationToken.IsCancellationRequested)
- return Task.FromCanceled<Int32>(cancellationToken);
-
- try {
-
- Int32 n = Read(buffer, offset, count);
+
+ if (cancellationToken.IsCancellationRequested)
+ return Task.FromCanceled<Int32>(cancellationToken);
+
+ try
+ {
+ Int32 n = Read(buffer, offset, count);
Task<Int32> t = _lastReadTask;
- return (t != null && t.Result == n) ? t : (_lastReadTask = Task.FromResult<Int32>(n));
-
- } catch (Exception ex) {
-
- Debug.Assert(! (ex is OperationCanceledException));
- return Task.FromException<Int32>(ex);
- }
- }
-
- public override int ReadByte() {
+ return (t != null && t.Result == n) ? t : (_lastReadTask = Task.FromResult<Int32>(n));
+ }
+ catch (Exception ex)
+ {
+ Debug.Assert(!(ex is OperationCanceledException));
+ return Task.FromException<Int32>(ex);
+ }
+ }
+
+ public override int ReadByte()
+ {
if (!_isOpen) __Error.StreamIsClosed();
if (!CanRead) __Error.ReadNotSupported();
@@ -421,56 +457,65 @@ namespace System.IO {
return -1;
Interlocked.Exchange(ref _position, pos + 1);
int result;
- if (_buffer != null) {
- unsafe {
+ if (_buffer != null)
+ {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
result = *(pointer + pos + _offset);
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
}
}
- else {
- unsafe {
+ else
+ {
+ unsafe
+ {
result = _mem[pos];
}
}
return result;
}
- public override long Seek(long offset, SeekOrigin loc) {
+ public override long Seek(long offset, SeekOrigin loc)
+ {
if (!_isOpen) __Error.StreamIsClosed();
if (offset > UnmanagedMemStreamMaxLength)
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_UnmanagedMemStreamLength"));
- switch(loc) {
- case SeekOrigin.Begin:
- if (offset < 0)
- throw new IOException(Environment.GetResourceString("IO.IO_SeekBeforeBegin"));
- Interlocked.Exchange(ref _position, offset);
- break;
-
- case SeekOrigin.Current:
- long pos = Interlocked.Read(ref _position);
- if (offset + pos < 0)
- throw new IOException(Environment.GetResourceString("IO.IO_SeekBeforeBegin"));
- Interlocked.Exchange(ref _position, offset + pos);
- break;
-
- case SeekOrigin.End:
- long len = Interlocked.Read(ref _length);
- if (len + offset < 0)
- throw new IOException(Environment.GetResourceString("IO.IO_SeekBeforeBegin"));
- Interlocked.Exchange(ref _position, len + offset);
- break;
-
- default:
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSeekOrigin"));
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_UnmanagedMemStreamLength);
+ switch (loc)
+ {
+ case SeekOrigin.Begin:
+ if (offset < 0)
+ throw new IOException(SR.IO_SeekBeforeBegin);
+ Interlocked.Exchange(ref _position, offset);
+ break;
+
+ case SeekOrigin.Current:
+ long pos = Interlocked.Read(ref _position);
+ if (offset + pos < 0)
+ throw new IOException(SR.IO_SeekBeforeBegin);
+ Interlocked.Exchange(ref _position, offset + pos);
+ break;
+
+ case SeekOrigin.End:
+ long len = Interlocked.Read(ref _length);
+ if (len + offset < 0)
+ throw new IOException(SR.IO_SeekBeforeBegin);
+ Interlocked.Exchange(ref _position, len + offset);
+ break;
+
+ default:
+ throw new ArgumentException(SR.Argument_InvalidSeekOrigin);
}
long finalPos = Interlocked.Read(ref _position);
@@ -478,40 +523,45 @@ namespace System.IO {
return finalPos;
}
- public override void SetLength(long value) {
+ public override void SetLength(long value)
+ {
if (value < 0)
- throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException("length", SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
if (_buffer != null)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UmsSafeBuffer"));
+ throw new NotSupportedException(SR.NotSupported_UmsSafeBuffer);
if (!_isOpen) __Error.StreamIsClosed();
if (!CanWrite) __Error.WriteNotSupported();
if (value > _capacity)
- throw new IOException(Environment.GetResourceString("IO.IO_FixedCapacity"));
+ throw new IOException(SR.IO_FixedCapacity);
long pos = Interlocked.Read(ref _position);
long len = Interlocked.Read(ref _length);
- if (value > len) {
- unsafe {
- Buffer.ZeroMemory(_mem+len, value-len);
+ if (value > len)
+ {
+ unsafe
+ {
+ Buffer.ZeroMemory(_mem + len, value - len);
}
}
Interlocked.Exchange(ref _length, value);
- if (pos > value) {
+ if (pos > value)
+ {
Interlocked.Exchange(ref _position, value);
- }
+ }
}
- public override void Write(byte[] buffer, int offset, int count) {
- if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (offset < 0)
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock(); // Keep contract validation in sync with WriteAsync(..)
if (!_isOpen) __Error.StreamIsClosed();
@@ -522,23 +572,28 @@ namespace System.IO {
long n = pos + count;
// Check for overflow
if (n < 0)
- throw new IOException(Environment.GetResourceString("IO.IO_StreamTooLong"));
+ throw new IOException(SR.IO_StreamTooLong);
- if (n > _capacity) {
- throw new NotSupportedException(Environment.GetResourceString("IO.IO_FixedCapacity"));
+ if (n > _capacity)
+ {
+ throw new NotSupportedException(SR.IO_FixedCapacity);
}
- if (_buffer == null) {
+ if (_buffer == null)
+ {
// Check to see whether we are now expanding the stream and must
// zero any memory in the middle.
- if (pos > len) {
- unsafe {
- Buffer.ZeroMemory(_mem+len, pos-len);
+ if (pos > len)
+ {
+ unsafe
+ {
+ Buffer.ZeroMemory(_mem + len, pos - len);
}
}
// set length after zeroing memory to avoid race condition of accessing unzeroed memory
- if (n > len) {
+ if (n > len)
+ {
Interlocked.Exchange(ref _length, n);
}
}
@@ -552,7 +607,7 @@ namespace System.IO {
long bytesLeft = _capacity - pos;
if (bytesLeft < count)
{
- throw new ArgumentException(Environment.GetResourceString("Arg_BufferTooSmall"));
+ throw new ArgumentException(SR.Arg_BufferTooSmall);
}
byte* pointer = null;
@@ -579,57 +634,62 @@ namespace System.IO {
Interlocked.Exchange(ref _position, n);
return;
}
-
- public override Task WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) {
-
- if (buffer==null)
- throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer"));
+
+ public override Task WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer);
if (offset < 0)
- throw new ArgumentOutOfRangeException(nameof(offset), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (buffer.Length - offset < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock(); // contract validation copied from Write(..)
-
- if (cancellationToken.IsCancellationRequested)
- return Task.FromCanceled(cancellationToken);
-
- try {
-
- Write(buffer, offset, count);
- return Task.CompletedTask;
-
- } catch (Exception ex) {
-
- Debug.Assert(! (ex is OperationCanceledException));
- return Task.FromException<Int32>(ex);
- }
- }
-
-
- public override void WriteByte(byte value) {
+
+ if (cancellationToken.IsCancellationRequested)
+ return Task.FromCanceled(cancellationToken);
+
+ try
+ {
+ Write(buffer, offset, count);
+ return Task.CompletedTask;
+ }
+ catch (Exception ex)
+ {
+ Debug.Assert(!(ex is OperationCanceledException));
+ return Task.FromException<Int32>(ex);
+ }
+ }
+
+
+ public override void WriteByte(byte value)
+ {
if (!_isOpen) __Error.StreamIsClosed();
if (!CanWrite) __Error.WriteNotSupported();
long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition
long len = Interlocked.Read(ref _length);
long n = pos + 1;
- if (pos >= len) {
+ if (pos >= len)
+ {
// Check for overflow
if (n < 0)
- throw new IOException(Environment.GetResourceString("IO.IO_StreamTooLong"));
-
+ throw new IOException(SR.IO_StreamTooLong);
+
if (n > _capacity)
- throw new NotSupportedException(Environment.GetResourceString("IO.IO_FixedCapacity"));
+ throw new NotSupportedException(SR.IO_FixedCapacity);
// Check to see whether we are now expanding the stream and must
// zero any memory in the middle.
// don't do if created from SafeBuffer
- if (_buffer == null) {
- if (pos > len) {
- unsafe {
- Buffer.ZeroMemory(_mem+len, pos-len);
+ if (_buffer == null)
+ {
+ if (pos > len)
+ {
+ unsafe
+ {
+ Buffer.ZeroMemory(_mem + len, pos - len);
}
}
@@ -638,24 +698,31 @@ namespace System.IO {
}
}
- if (_buffer != null) {
- unsafe {
+ if (_buffer != null)
+ {
+ unsafe
+ {
byte* pointer = null;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
_buffer.AcquirePointer(ref pointer);
*(pointer + pos + _offset) = value;
}
- finally {
- if (pointer != null) {
+ finally
+ {
+ if (pointer != null)
+ {
_buffer.ReleasePointer();
}
}
}
}
- else {
- unsafe {
- _mem[pos] = value;
+ else
+ {
+ unsafe
+ {
+ _mem[pos] = value;
}
}
Interlocked.Exchange(ref _position, n);
diff --git a/src/mscorlib/src/System/IO/UnmanagedMemoryStreamWrapper.cs b/src/mscorlib/src/System/IO/UnmanagedMemoryStreamWrapper.cs
index 99b257ea56..86e4707dfd 100644
--- a/src/mscorlib/src/System/IO/UnmanagedMemoryStreamWrapper.cs
+++ b/src/mscorlib/src/System/IO/UnmanagedMemoryStreamWrapper.cs
@@ -18,94 +18,117 @@ using System.Diagnostics.Contracts;
using System.Threading;
using System.Threading.Tasks;
-namespace System.IO {
+namespace System.IO
+{
// Needed for backwards compatibility with V1.x usages of the
// ResourceManager, where a MemoryStream is now returned as an
// UnmanagedMemoryStream from ResourceReader.
- internal sealed class UnmanagedMemoryStreamWrapper : MemoryStream {
+ internal sealed class UnmanagedMemoryStreamWrapper : MemoryStream
+ {
private UnmanagedMemoryStream _unmanagedStream;
-
- internal UnmanagedMemoryStreamWrapper(UnmanagedMemoryStream stream) {
+
+ internal UnmanagedMemoryStreamWrapper(UnmanagedMemoryStream stream)
+ {
_unmanagedStream = stream;
}
-
- public override bool CanRead {
+
+ public override bool CanRead
+ {
[Pure]
get { return _unmanagedStream.CanRead; }
}
-
- public override bool CanSeek {
+
+ public override bool CanSeek
+ {
[Pure]
get { return _unmanagedStream.CanSeek; }
}
-
- public override bool CanWrite {
+
+ public override bool CanWrite
+ {
[Pure]
get { return _unmanagedStream.CanWrite; }
}
-
+
protected override void Dispose(bool disposing)
{
- try {
+ try
+ {
if (disposing)
_unmanagedStream.Close();
}
- finally {
+ finally
+ {
base.Dispose(disposing);
}
}
-
- public override void Flush() {
+
+ public override void Flush()
+ {
_unmanagedStream.Flush();
}
-
- public override byte[] GetBuffer() {
- throw new UnauthorizedAccessException(Environment.GetResourceString("UnauthorizedAccess_MemStreamBuffer"));
+
+ public override byte[] GetBuffer()
+ {
+ throw new UnauthorizedAccessException(SR.UnauthorizedAccess_MemStreamBuffer);
}
- public override bool TryGetBuffer(out ArraySegment<byte> buffer) {
+ public override bool TryGetBuffer(out ArraySegment<byte> buffer)
+ {
buffer = default(ArraySegment<byte>);
return false;
}
- public override int Capacity {
- get {
- return (int) _unmanagedStream.Capacity;
+ public override int Capacity
+ {
+ get
+ {
+ return (int)_unmanagedStream.Capacity;
}
[SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
- set {
- throw new IOException(Environment.GetResourceString("IO.IO_FixedCapacity"));
+ set
+ {
+ throw new IOException(SR.IO_FixedCapacity);
}
- }
-
- public override long Length {
- get {
+ }
+
+ public override long Length
+ {
+ get
+ {
return _unmanagedStream.Length;
}
}
- public override long Position {
- get {
+ public override long Position
+ {
+ get
+ {
return _unmanagedStream.Position;
}
- set {
+ set
+ {
_unmanagedStream.Position = value;
}
}
-
- public override int Read([In, Out] byte[] buffer, int offset, int count) {
+
+ public override int Read([In, Out] byte[] buffer, int offset, int count)
+ {
return _unmanagedStream.Read(buffer, offset, count);
}
-
- public override int ReadByte() {
+
+ public override int ReadByte()
+ {
return _unmanagedStream.ReadByte();
}
-
- public override long Seek(long offset, SeekOrigin loc) {
+
+ public override long Seek(long offset, SeekOrigin loc)
+ {
return _unmanagedStream.Seek(offset, loc);
}
- public unsafe override byte[] ToArray() {
+ public unsafe override byte[] ToArray()
+ {
if (!_unmanagedStream._isOpen) __Error.StreamIsClosed();
if (!_unmanagedStream.CanRead) __Error.ReadNotSupported();
@@ -113,31 +136,34 @@ namespace System.IO {
Buffer.Memcpy(buffer, 0, _unmanagedStream.Pointer, 0, (int)_unmanagedStream.Length);
return buffer;
}
-
- public override void Write(byte[] buffer, int offset, int count) {
+
+ public override void Write(byte[] buffer, int offset, int count)
+ {
_unmanagedStream.Write(buffer, offset, count);
}
-
- public override void WriteByte(byte value) {
+
+ public override void WriteByte(byte value)
+ {
_unmanagedStream.WriteByte(value);
}
-
+
// Writes this MemoryStream to another stream.
- public unsafe override void WriteTo(Stream stream) {
- if (stream==null)
- throw new ArgumentNullException(nameof(stream), Environment.GetResourceString("ArgumentNull_Stream"));
+ public unsafe override void WriteTo(Stream stream)
+ {
+ if (stream == null)
+ throw new ArgumentNullException(nameof(stream), SR.ArgumentNull_Stream);
Contract.EndContractBlock();
if (!_unmanagedStream._isOpen) __Error.StreamIsClosed();
if (!CanRead) __Error.ReadNotSupported();
byte[] buffer = ToArray();
-
+
stream.Write(buffer, 0, buffer.Length);
}
- public override void SetLength(Int64 value) {
-
+ public override void SetLength(Int64 value)
+ {
// This was probably meant to call _unmanagedStream.SetLength(value), but it was forgotten in V.4.0.
// Now this results in a call to the base which touches the underlying array which is never actually used.
// We cannot fix it due to compat now, but we should fix this at the next SxS release oportunity.
@@ -145,26 +171,26 @@ namespace System.IO {
}
- public override Task CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken) {
-
+ public override Task CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
+ {
// The parameter checks must be in sync with the base version:
if (destination == null)
throw new ArgumentNullException(nameof(destination));
-
+
if (bufferSize <= 0)
- throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ throw new ArgumentOutOfRangeException(nameof(bufferSize), SR.ArgumentOutOfRange_NeedPosNum);
if (!CanRead && !CanWrite)
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_StreamClosed"));
+ throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed);
if (!destination.CanRead && !destination.CanWrite)
- throw new ObjectDisposedException(nameof(destination), Environment.GetResourceString("ObjectDisposed_StreamClosed"));
+ throw new ObjectDisposedException(nameof(destination), SR.ObjectDisposed_StreamClosed);
if (!CanRead)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnreadableStream"));
+ throw new NotSupportedException(SR.NotSupported_UnreadableStream);
if (!destination.CanWrite)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnwritableStream"));
+ throw new NotSupportedException(SR.NotSupported_UnwritableStream);
Contract.EndContractBlock();
@@ -172,23 +198,22 @@ namespace System.IO {
}
- public override Task FlushAsync(CancellationToken cancellationToken) {
-
+ public override Task FlushAsync(CancellationToken cancellationToken)
+ {
return _unmanagedStream.FlushAsync(cancellationToken);
}
- public override Task<Int32> ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) {
-
+ public override Task<Int32> ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
+ {
return _unmanagedStream.ReadAsync(buffer, offset, count, cancellationToken);
}
- public override Task WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) {
-
+ public override Task WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
+ {
return _unmanagedStream.WriteAsync(buffer, offset, count, cancellationToken);
}
-
} // class UnmanagedMemoryStreamWrapper
} // namespace
diff --git a/src/mscorlib/src/System/IO/__Error.cs b/src/mscorlib/src/System/IO/__Error.cs
index 955ddbec63..70f83261ed 100644
--- a/src/mscorlib/src/System/IO/__Error.cs
+++ b/src/mscorlib/src/System/IO/__Error.cs
@@ -23,46 +23,56 @@ using System.Globalization;
using System.Security;
using System.Diagnostics.Contracts;
-namespace System.IO {
+namespace System.IO
+{
[Pure]
internal static class __Error
{
- internal static void EndOfFile() {
- throw new EndOfStreamException(Environment.GetResourceString("IO.EOF_ReadBeyondEOF"));
+ internal static void EndOfFile()
+ {
+ throw new EndOfStreamException(SR.IO_EOF_ReadBeyondEOF);
}
- internal static void FileNotOpen() {
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_FileClosed"));
+ internal static void FileNotOpen()
+ {
+ throw new ObjectDisposedException(null, SR.ObjectDisposed_FileClosed);
}
-
- internal static void StreamIsClosed() {
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_StreamClosed"));
+
+ internal static void StreamIsClosed()
+ {
+ throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed);
}
-
- internal static void MemoryStreamNotExpandable() {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_MemStreamNotExpandable"));
+
+ internal static void MemoryStreamNotExpandable()
+ {
+ throw new NotSupportedException(SR.NotSupported_MemStreamNotExpandable);
}
-
- internal static void ReaderClosed() {
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ReaderClosed"));
+
+ internal static void ReaderClosed()
+ {
+ throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed);
}
- internal static void ReadNotSupported() {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnreadableStream"));
+ internal static void ReadNotSupported()
+ {
+ throw new NotSupportedException(SR.NotSupported_UnreadableStream);
}
- internal static void WrongAsyncResult() {
- throw new ArgumentException(Environment.GetResourceString("Arg_WrongAsyncResult"));
+ internal static void WrongAsyncResult()
+ {
+ throw new ArgumentException(SR.Arg_WrongAsyncResult);
}
- internal static void EndReadCalledTwice() {
+ internal static void EndReadCalledTwice()
+ {
// Should ideally be InvalidOperationExc but we can't maitain parity with Stream and FileStream without some work
- throw new ArgumentException(Environment.GetResourceString("InvalidOperation_EndReadCalledMultiple"));
+ throw new ArgumentException(SR.InvalidOperation_EndReadCalledMultiple);
}
- internal static void EndWriteCalledTwice() {
+ internal static void EndWriteCalledTwice()
+ {
// Should ideally be InvalidOperationExc but we can't maintain parity with Stream and FileStream without some work
- throw new ArgumentException(Environment.GetResourceString("InvalidOperation_EndWriteCalledMultiple"));
+ throw new ArgumentException(SR.InvalidOperation_EndWriteCalledMultiple);
}
// Given a possible fully qualified path, ensure that we have path
@@ -71,7 +81,6 @@ namespace System.IO {
// directory name.
internal static String GetDisplayablePath(String path, bool isInvalidPath)
{
-
if (String.IsNullOrEmpty(path))
return String.Empty;
@@ -81,7 +90,8 @@ namespace System.IO {
return path;
if (PathInternal.IsDirectorySeparator(path[0]) && PathInternal.IsDirectorySeparator(path[1]))
isFullyQualified = true;
- else if (path[1] == Path.VolumeSeparatorChar) {
+ else if (path[1] == Path.VolumeSeparatorChar)
+ {
isFullyQualified = true;
}
@@ -89,26 +99,32 @@ namespace System.IO {
return path;
bool safeToReturn = false;
- try {
- if (!isInvalidPath) {
+ try
+ {
+ if (!isInvalidPath)
+ {
safeToReturn = true;
}
}
- catch (SecurityException) {
+ catch (SecurityException)
+ {
}
- catch (ArgumentException) {
+ catch (ArgumentException)
+ {
// ? and * characters cause ArgumentException to be thrown from HasIllegalCharacters
// inside FileIOPermission.AddPathList
}
- catch (NotSupportedException) {
+ catch (NotSupportedException)
+ {
// paths like "!Bogus\\dir:with/junk_.in it" can cause NotSupportedException to be thrown
// from Security.Util.StringExpressionSet.CanonicalizePath when ':' is found in the path
// beyond string index position 1.
}
-
- if (!safeToReturn) {
+
+ if (!safeToReturn)
+ {
if (PathInternal.IsDirectorySeparator(path[path.Length - 1]))
- path = Environment.GetResourceString("IO.IO_NoPermissionToDirectoryName");
+ path = SR.IO_NoPermissionToDirectoryName;
else
path = Path.GetFileName(path);
}
@@ -116,81 +132,85 @@ namespace System.IO {
return path;
}
- internal static void WinIOError() {
+ internal static void WinIOError()
+ {
int errorCode = Marshal.GetLastWin32Error();
WinIOError(errorCode, String.Empty);
}
-
+
// After calling GetLastWin32Error(), it clears the last error field,
// so you must save the HResult and pass it to this method. This method
// will determine the appropriate exception to throw dependent on your
// error, and depending on the error, insert a string into the message
// gotten from the ResourceManager.
- internal static void WinIOError(int errorCode, String maybeFullPath) {
+ internal static void WinIOError(int errorCode, String maybeFullPath)
+ {
// This doesn't have to be perfect, but is a perf optimization.
bool isInvalidPath = errorCode == Win32Native.ERROR_INVALID_NAME || errorCode == Win32Native.ERROR_BAD_PATHNAME;
String str = GetDisplayablePath(maybeFullPath, isInvalidPath);
- switch (errorCode) {
- case Win32Native.ERROR_FILE_NOT_FOUND:
- if (str.Length == 0)
- throw new FileNotFoundException(Environment.GetResourceString("IO.FileNotFound"));
- else
- throw new FileNotFoundException(Environment.GetResourceString("IO.FileNotFound_FileName", str), str);
-
- case Win32Native.ERROR_PATH_NOT_FOUND:
- if (str.Length == 0)
- throw new DirectoryNotFoundException(Environment.GetResourceString("IO.PathNotFound_NoPathName"));
- else
- throw new DirectoryNotFoundException(Environment.GetResourceString("IO.PathNotFound_Path", str));
-
- case Win32Native.ERROR_ACCESS_DENIED:
- if (str.Length == 0)
- throw new UnauthorizedAccessException(Environment.GetResourceString("UnauthorizedAccess_IODenied_NoPathName"));
- else
- throw new UnauthorizedAccessException(Environment.GetResourceString("UnauthorizedAccess_IODenied_Path", str));
-
- case Win32Native.ERROR_ALREADY_EXISTS:
- if (str.Length == 0)
- goto default;
- throw new IOException(Environment.GetResourceString("IO.IO_AlreadyExists_Name", str), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
-
- case Win32Native.ERROR_FILENAME_EXCED_RANGE:
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
-
- case Win32Native.ERROR_INVALID_DRIVE:
- throw new DriveNotFoundException(Environment.GetResourceString("IO.DriveNotFound_Drive", str));
-
- case Win32Native.ERROR_INVALID_PARAMETER:
- throw new IOException(Win32Native.GetMessage(errorCode), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
-
- case Win32Native.ERROR_SHARING_VIOLATION:
- if (str.Length == 0)
- throw new IOException(Environment.GetResourceString("IO.IO_SharingViolation_NoFileName"), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
- else
- throw new IOException(Environment.GetResourceString("IO.IO_SharingViolation_File", str), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
-
- case Win32Native.ERROR_FILE_EXISTS:
- if (str.Length == 0)
- goto default;
- throw new IOException(Environment.GetResourceString("IO.IO_FileExists_Name", str), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
-
- case Win32Native.ERROR_OPERATION_ABORTED:
- throw new OperationCanceledException();
-
- default:
- throw new IOException(Win32Native.GetMessage(errorCode), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
+ switch (errorCode)
+ {
+ case Win32Native.ERROR_FILE_NOT_FOUND:
+ if (str.Length == 0)
+ throw new FileNotFoundException(SR.IO_FileNotFound);
+ else
+ throw new FileNotFoundException(SR.Format(SR.IO_FileNotFound_FileName, str), str);
+
+ case Win32Native.ERROR_PATH_NOT_FOUND:
+ if (str.Length == 0)
+ throw new DirectoryNotFoundException(SR.IO_PathNotFound_NoPathName);
+ else
+ throw new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, str));
+
+ case Win32Native.ERROR_ACCESS_DENIED:
+ if (str.Length == 0)
+ throw new UnauthorizedAccessException(SR.UnauthorizedAccess_IODenied_NoPathName);
+ else
+ throw new UnauthorizedAccessException(SR.Format(SR.UnauthorizedAccess_IODenied_Path, str));
+
+ case Win32Native.ERROR_ALREADY_EXISTS:
+ if (str.Length == 0)
+ goto default;
+ throw new IOException(SR.Format(SR.IO_AlreadyExists_Name, str), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
+
+ case Win32Native.ERROR_FILENAME_EXCED_RANGE:
+ throw new PathTooLongException(SR.IO_PathTooLong);
+
+ case Win32Native.ERROR_INVALID_DRIVE:
+ throw new DriveNotFoundException(SR.Format(SR.IO_DriveNotFound_Drive, str));
+
+ case Win32Native.ERROR_INVALID_PARAMETER:
+ throw new IOException(Win32Native.GetMessage(errorCode), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
+
+ case Win32Native.ERROR_SHARING_VIOLATION:
+ if (str.Length == 0)
+ throw new IOException(SR.IO_SharingViolation_NoFileName, Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
+ else
+ throw new IOException(SR.Format(SR.IO_SharingViolation_File, str), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
+
+ case Win32Native.ERROR_FILE_EXISTS:
+ if (str.Length == 0)
+ goto default;
+ throw new IOException(SR.Format(SR.IO_FileExists_Name, str), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
+
+ case Win32Native.ERROR_OPERATION_ABORTED:
+ throw new OperationCanceledException();
+
+ default:
+ throw new IOException(Win32Native.GetMessage(errorCode), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
}
}
-
- internal static void WriteNotSupported() {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnwritableStream"));
+
+ internal static void WriteNotSupported()
+ {
+ throw new NotSupportedException(SR.NotSupported_UnwritableStream);
}
// From WinError.h
internal const int ERROR_FILE_NOT_FOUND = Win32Native.ERROR_FILE_NOT_FOUND;
internal const int ERROR_PATH_NOT_FOUND = Win32Native.ERROR_PATH_NOT_FOUND;
- internal const int ERROR_ACCESS_DENIED = Win32Native.ERROR_ACCESS_DENIED;
+ internal const int ERROR_ACCESS_DENIED = Win32Native.ERROR_ACCESS_DENIED;
internal const int ERROR_INVALID_PARAMETER = Win32Native.ERROR_INVALID_PARAMETER;
}
}
diff --git a/src/mscorlib/src/System/IO/__HResults.cs b/src/mscorlib/src/System/IO/__HResults.cs
index e19f28f833..633c3538c5 100644
--- a/src/mscorlib/src/System/IO/__HResults.cs
+++ b/src/mscorlib/src/System/IO/__HResults.cs
@@ -11,8 +11,11 @@
//
//
//===========================================================================*/
-namespace System.IO {
- using System;
+
+using System;
+
+namespace System.IO
+{
// Only static data no need to serialize
internal static class __HResults
{
diff --git a/src/mscorlib/src/System/IServiceObjectProvider.cs b/src/mscorlib/src/System/IServiceObjectProvider.cs
deleted file mode 100644
index feb1143487..0000000000
--- a/src/mscorlib/src/System/IServiceObjectProvider.cs
+++ /dev/null
@@ -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.
-
-namespace System {
-
- using System;
- using System.Runtime.InteropServices;
-
-
- public interface IServiceProvider
- {
- // Interface does not need to be marked with the serializable attribute
- Object GetService(Type serviceType);
- }
-}
diff --git a/src/mscorlib/src/System/InsufficientMemoryException.cs b/src/mscorlib/src/System/InsufficientMemoryException.cs
index 448a061821..eb5e4d7430 100644
--- a/src/mscorlib/src/System/InsufficientMemoryException.cs
+++ b/src/mscorlib/src/System/InsufficientMemoryException.cs
@@ -16,30 +16,35 @@
**
=============================================================================*/
-namespace System {
-
- using System;
- using System.Runtime.Serialization;
+using System;
+using System.Runtime.Serialization;
+
+namespace System
+{
[Serializable]
public sealed class InsufficientMemoryException : OutOfMemoryException
{
- public InsufficientMemoryException()
- : base(GetMessageFromNativeResources(ExceptionMessageKind.OutOfMemory)) {
- SetErrorCode(__HResults.COR_E_INSUFFICIENTMEMORY);
+ public InsufficientMemoryException()
+ : base(GetMessageFromNativeResources(ExceptionMessageKind.OutOfMemory))
+ {
+ HResult = __HResults.COR_E_INSUFFICIENTMEMORY;
}
-
- public InsufficientMemoryException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_INSUFFICIENTMEMORY);
+
+ public InsufficientMemoryException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_INSUFFICIENTMEMORY;
}
-
- public InsufficientMemoryException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(__HResults.COR_E_INSUFFICIENTMEMORY);
+
+ public InsufficientMemoryException(String message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_INSUFFICIENTMEMORY;
}
- private InsufficientMemoryException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ private InsufficientMemoryException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
}
}
}
diff --git a/src/mscorlib/src/System/Int16.cs b/src/mscorlib/src/System/Int16.cs
index a5e62233e4..69f71af278 100644
--- a/src/mscorlib/src/System/Int16.cs
+++ b/src/mscorlib/src/System/Int16.cs
@@ -12,47 +12,54 @@
**
===========================================================*/
-namespace System {
-
- using System;
- using System.Globalization;
- using System.Runtime.InteropServices;
- using System.Diagnostics.Contracts;
-
-[Serializable]
-[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
+
+using System;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
+ [Serializable]
+ [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public struct Int16 : IComparable, IFormattable, IConvertible
- , IComparable<Int16>, IEquatable<Int16>
+ , IComparable<Int16>, IEquatable<Int16>
{
internal short m_value;
-
+
public const short MaxValue = (short)0x7FFF;
public const short MinValue = unchecked((short)0x8000);
-
+
// Compares this object to another object, returning an integer that
// indicates the relationship.
// Returns a value less than zero if this object
// null is considered to be less than any instance.
// If object is not of type Int16, this method throws an ArgumentException.
//
- public int CompareTo(Object value) {
- if (value == null) {
+ public int CompareTo(Object value)
+ {
+ if (value == null)
+ {
return 1;
}
-
- if (value is Int16) {
+
+ if (value is Int16)
+ {
return m_value - ((Int16)value).m_value;
}
-
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeInt16"));
+
+ throw new ArgumentException(SR.Arg_MustBeInt16);
}
- public int CompareTo(Int16 value) {
+ public int CompareTo(Int16 value)
+ {
return m_value - value;
}
-
- public override bool Equals(Object obj) {
- if (!(obj is Int16)) {
+
+ public override bool Equals(Object obj)
+ {
+ if (!(obj is Int16))
+ {
return false;
}
return m_value == ((Int16)obj).m_value;
@@ -65,199 +72,220 @@ namespace System {
}
// Returns a HashCode for the Int16
- public override int GetHashCode() {
+ public override int GetHashCode()
+ {
return ((int)((ushort)m_value) | (((int)m_value) << 16));
}
-
- public override String ToString() {
+
+ public override String ToString()
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, null, NumberFormatInfo.CurrentInfo);
}
-
- public String ToString(IFormatProvider provider) {
+
+ public String ToString(IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, null, NumberFormatInfo.GetInstance(provider));
- }
+ }
- public String ToString(String format) {
+ public String ToString(String format)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return ToString(format, NumberFormatInfo.CurrentInfo);
- }
-
- public String ToString(String format, IFormatProvider provider) {
+ }
+
+ public String ToString(String format, IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return ToString(format, NumberFormatInfo.GetInstance(provider));
}
- private String ToString(String format, NumberFormatInfo info) {
+ private String ToString(String format, NumberFormatInfo info)
+ {
Contract.Ensures(Contract.Result<String>() != null);
- if (m_value<0 && format!=null && format.Length>0 && (format[0]=='X' || format[0]=='x')) {
+ if (m_value < 0 && format != null && format.Length > 0 && (format[0] == 'X' || format[0] == 'x'))
+ {
uint temp = (uint)(m_value & 0x0000FFFF);
- return Number.FormatUInt32(temp,format, info);
+ return Number.FormatUInt32(temp, format, info);
}
return Number.FormatInt32(m_value, format, info);
}
-
- public static short Parse(String s) {
+
+ public static short Parse(String s)
+ {
return Parse(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
-
- public static short Parse(String s, NumberStyles style) {
+
+ public static short Parse(String s, NumberStyles style)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Parse(s, style, NumberFormatInfo.CurrentInfo);
}
- public static short Parse(String s, IFormatProvider provider) {
+ public static short Parse(String s, IFormatProvider provider)
+ {
return Parse(s, NumberStyles.Integer, NumberFormatInfo.GetInstance(provider));
}
- public static short Parse(String s, NumberStyles style, IFormatProvider provider) {
+ public static short Parse(String s, NumberStyles style, IFormatProvider provider)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Parse(s, style, NumberFormatInfo.GetInstance(provider));
}
-
- private static short Parse(String s, NumberStyles style, NumberFormatInfo info) {
+ private static short Parse(String s, NumberStyles style, NumberFormatInfo info)
+ {
int i = 0;
- try {
+ try
+ {
i = Number.ParseInt32(s, style, info);
}
- catch(OverflowException e) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Int16"), e);
+ catch (OverflowException e)
+ {
+ throw new OverflowException(SR.Overflow_Int16, e);
}
// We need this check here since we don't allow signs to specified in hex numbers. So we fixup the result
// for negative numbers
- if ((style & NumberStyles.AllowHexSpecifier) != 0) { // We are parsing a hexadecimal number
- if ((i < 0) || (i > UInt16.MaxValue)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Int16"));
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ { // We are parsing a hexadecimal number
+ if ((i < 0) || (i > UInt16.MaxValue))
+ {
+ throw new OverflowException(SR.Overflow_Int16);
}
return (short)i;
}
-
- if (i < MinValue || i > MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_Int16"));
+
+ if (i < MinValue || i > MaxValue) throw new OverflowException(SR.Overflow_Int16);
return (short)i;
}
- public static bool TryParse(String s, out Int16 result) {
+ public static bool TryParse(String s, out Int16 result)
+ {
return TryParse(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result);
}
- public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out Int16 result) {
+ public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out Int16 result)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return TryParse(s, style, NumberFormatInfo.GetInstance(provider), out result);
}
-
- private static bool TryParse(String s, NumberStyles style, NumberFormatInfo info, out Int16 result) {
+ private static bool TryParse(String s, NumberStyles style, NumberFormatInfo info, out Int16 result)
+ {
result = 0;
int i;
- if (!Number.TryParseInt32(s, style, info, out i)) {
+ if (!Number.TryParseInt32(s, style, info, out i))
+ {
return false;
}
// We need this check here since we don't allow signs to specified in hex numbers. So we fixup the result
// for negative numbers
- if ((style & NumberStyles.AllowHexSpecifier) != 0) { // We are parsing a hexadecimal number
- if ((i < 0) || i > UInt16.MaxValue) {
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ { // We are parsing a hexadecimal number
+ if ((i < 0) || i > UInt16.MaxValue)
+ {
return false;
}
- result = (Int16) i;
+ result = (Int16)i;
return true;
}
-
- if (i < MinValue || i > MaxValue) {
+
+ if (i < MinValue || i > MaxValue)
+ {
return false;
}
- result = (Int16) i;
+ result = (Int16)i;
return true;
}
//
// IConvertible implementation
//
-
- public TypeCode GetTypeCode() {
+
+ public TypeCode GetTypeCode()
+ {
return TypeCode.Int16;
}
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
return Convert.ToBoolean(m_value);
}
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
return Convert.ToChar(m_value);
}
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
return Convert.ToSByte(m_value);
}
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
return Convert.ToByte(m_value);
}
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
return m_value;
}
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
return Convert.ToUInt16(m_value);
}
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
return Convert.ToInt32(m_value);
}
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
return Convert.ToUInt32(m_value);
}
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
return Convert.ToInt64(m_value);
}
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
return Convert.ToUInt64(m_value);
}
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
return Convert.ToSingle(m_value);
}
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
return Convert.ToDouble(m_value);
}
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider) {
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
return Convert.ToDecimal(m_value);
}
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Int16", "DateTime"));
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Int16", "DateTime"));
}
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
return Convert.DefaultToType((IConvertible)this, type, provider);
}
-
}
}
diff --git a/src/mscorlib/src/System/Int32.cs b/src/mscorlib/src/System/Int32.cs
index 0e1ed56a41..90b70a9554 100644
--- a/src/mscorlib/src/System/Int32.cs
+++ b/src/mscorlib/src/System/Int32.cs
@@ -11,35 +11,39 @@
**
**
===========================================================*/
-namespace System {
-
- using System;
- using System.Globalization;
- using System.Runtime;
- using System.Runtime.InteropServices;
- using System.Diagnostics.Contracts;
-
-[Serializable]
-[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
+
+using System;
+using System.Globalization;
+using System.Runtime;
+using System.Runtime.InteropServices;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
+ [Serializable]
+ [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public struct Int32 : IComparable, IFormattable, IConvertible
- , IComparable<Int32>, IEquatable<Int32>
+ , IComparable<Int32>, IEquatable<Int32>
{
internal int m_value;
-
+
public const int MaxValue = 0x7fffffff;
public const int MinValue = unchecked((int)0x80000000);
-
+
// Compares this object to another object, returning an integer that
// indicates the relationship.
// Returns a value less than zero if this object
// null is considered to be less than any instance.
// If object is not of type Int32, this method throws an ArgumentException.
//
- public int CompareTo(Object value) {
- if (value == null) {
+ public int CompareTo(Object value)
+ {
+ if (value == null)
+ {
return 1;
}
- if (value is Int32) {
+ if (value is Int32)
+ {
// Need to use compare because subtraction will wrap
// to positive for very large neg numbers, etc.
int i = (int)value;
@@ -47,19 +51,22 @@ namespace System {
if (m_value > i) return 1;
return 0;
}
- throw new ArgumentException (Environment.GetResourceString("Arg_MustBeInt32"));
+ throw new ArgumentException(SR.Arg_MustBeInt32);
}
- public int CompareTo(int value) {
+ public int CompareTo(int value)
+ {
// Need to use compare because subtraction will wrap
// to positive for very large neg numbers, etc.
if (m_value < value) return -1;
if (m_value > value) return 1;
return 0;
}
-
- public override bool Equals(Object obj) {
- if (!(obj is Int32)) {
+
+ public override bool Equals(Object obj)
+ {
+ if (!(obj is Int32))
+ {
return false;
}
return m_value == ((Int32)obj).m_value;
@@ -72,41 +79,48 @@ namespace System {
}
// The absolute value of the int contained.
- public override int GetHashCode() {
+ public override int GetHashCode()
+ {
return m_value;
}
[Pure]
- public override String ToString() {
+ public override String ToString()
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, null, NumberFormatInfo.CurrentInfo);
}
[Pure]
- public String ToString(String format) {
+ public String ToString(String format)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, format, NumberFormatInfo.CurrentInfo);
}
-
+
[Pure]
- public String ToString(IFormatProvider provider) {
+ public String ToString(IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, null, NumberFormatInfo.GetInstance(provider));
}
[Pure]
- public String ToString(String format, IFormatProvider provider) {
+ public String ToString(String format, IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, format, NumberFormatInfo.GetInstance(provider));
}
[Pure]
- public static int Parse(String s) {
+ public static int Parse(String s)
+ {
return Number.ParseInt32(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
[Pure]
- public static int Parse(String s, NumberStyles style) {
+ public static int Parse(String s, NumberStyles style)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Number.ParseInt32(s, style, NumberFormatInfo.CurrentInfo);
}
@@ -116,16 +130,18 @@ namespace System {
// NumberFormatInfo is assumed.
//
[Pure]
- public static int Parse(String s, IFormatProvider provider) {
+ public static int Parse(String s, IFormatProvider provider)
+ {
return Number.ParseInt32(s, NumberStyles.Integer, NumberFormatInfo.GetInstance(provider));
}
-
+
// Parses an integer from a String in the given style. If
// a NumberFormatInfo isn't specified, the current culture's
// NumberFormatInfo is assumed.
//
[Pure]
- public static int Parse(String s, NumberStyles style, IFormatProvider provider) {
+ public static int Parse(String s, NumberStyles style, IFormatProvider provider)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Number.ParseInt32(s, style, NumberFormatInfo.GetInstance(provider));
}
@@ -134,7 +150,8 @@ namespace System {
// than throwing exceptin if input is invalid
//
[Pure]
- public static bool TryParse(String s, out Int32 result) {
+ public static bool TryParse(String s, out Int32 result)
+ {
return Number.TryParseInt32(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result);
}
@@ -142,7 +159,8 @@ namespace System {
// than throwing exceptin if input is invalid
//
[Pure]
- public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out Int32 result) {
+ public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out Int32 result)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Number.TryParseInt32(s, style, NumberFormatInfo.GetInstance(provider), out result);
}
@@ -150,84 +168,85 @@ namespace System {
//
// IConvertible implementation
//
-
+
[Pure]
- public TypeCode GetTypeCode() {
+ public TypeCode GetTypeCode()
+ {
return TypeCode.Int32;
}
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
return Convert.ToBoolean(m_value);
}
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
return Convert.ToChar(m_value);
}
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
return Convert.ToSByte(m_value);
}
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
return Convert.ToByte(m_value);
}
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
return Convert.ToInt16(m_value);
}
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
return Convert.ToUInt16(m_value);
}
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
return m_value;
}
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
return Convert.ToUInt32(m_value);
}
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
return Convert.ToInt64(m_value);
}
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
return Convert.ToUInt64(m_value);
}
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
return Convert.ToSingle(m_value);
}
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
return Convert.ToDouble(m_value);
}
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider) {
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
return Convert.ToDecimal(m_value);
}
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Int32", "DateTime"));
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Int32", "DateTime"));
}
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
return Convert.DefaultToType((IConvertible)this, type, provider);
}
}
diff --git a/src/mscorlib/src/System/Int64.cs b/src/mscorlib/src/System/Int64.cs
index 3520ede533..3d64362e30 100644
--- a/src/mscorlib/src/System/Int64.cs
+++ b/src/mscorlib/src/System/Int64.cs
@@ -11,20 +11,21 @@
**
**
===========================================================*/
-namespace System {
-
- using System;
- using System.Globalization;
- using System.Runtime.InteropServices;
- using System.Diagnostics.Contracts;
-
-[Serializable]
-[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
+
+using System;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
+ [Serializable]
+ [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public struct Int64 : IComparable, IFormattable, IConvertible
- , IComparable<Int64>, IEquatable<Int64>
+ , IComparable<Int64>, IEquatable<Int64>
{
internal long m_value;
-
+
public const long MaxValue = 0x7fffffffffffffffL;
public const long MinValue = unchecked((long)0x8000000000000000L);
@@ -34,11 +35,14 @@ namespace System {
// null is considered to be less than any instance.
// If object is not of type Int64, this method throws an ArgumentException.
//
- public int CompareTo(Object value) {
- if (value == null) {
+ public int CompareTo(Object value)
+ {
+ if (value == null)
+ {
return 1;
}
- if (value is Int64) {
+ if (value is Int64)
+ {
// Need to use compare because subtraction will wrap
// to positive for very large neg numbers, etc.
long i = (long)value;
@@ -46,19 +50,22 @@ namespace System {
if (m_value > i) return 1;
return 0;
}
- throw new ArgumentException (Environment.GetResourceString("Arg_MustBeInt64"));
+ throw new ArgumentException(SR.Arg_MustBeInt64);
}
- public int CompareTo(Int64 value) {
+ public int CompareTo(Int64 value)
+ {
// Need to use compare because subtraction will wrap
// to positive for very large neg numbers, etc.
if (m_value < value) return -1;
if (m_value > value) return 1;
return 0;
}
-
- public override bool Equals(Object obj) {
- if (!(obj is Int64)) {
+
+ public override bool Equals(Object obj)
+ {
+ if (!(obj is Int64))
+ {
return false;
}
return m_value == ((Int64)obj).m_value;
@@ -71,40 +78,48 @@ namespace System {
}
// The value of the lower 32 bits XORed with the uppper 32 bits.
- public override int GetHashCode() {
+ public override int GetHashCode()
+ {
return (unchecked((int)((long)m_value)) ^ (int)(m_value >> 32));
}
- public override String ToString() {
+ public override String ToString()
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt64(m_value, null, NumberFormatInfo.CurrentInfo);
}
-
- public String ToString(IFormatProvider provider) {
+
+ public String ToString(IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt64(m_value, null, NumberFormatInfo.GetInstance(provider));
}
-
- public String ToString(String format) {
+
+ public String ToString(String format)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt64(m_value, format, NumberFormatInfo.CurrentInfo);
}
- public String ToString(String format, IFormatProvider provider) {
+ public String ToString(String format, IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt64(m_value, format, NumberFormatInfo.GetInstance(provider));
}
- public static long Parse(String s) {
+ public static long Parse(String s)
+ {
return Number.ParseInt64(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
-
- public static long Parse(String s, NumberStyles style) {
+
+ public static long Parse(String s, NumberStyles style)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Number.ParseInt64(s, style, NumberFormatInfo.CurrentInfo);
}
- public static long Parse(String s, IFormatProvider provider) {
+ public static long Parse(String s, IFormatProvider provider)
+ {
return Number.ParseInt64(s, NumberStyles.Integer, NumberFormatInfo.GetInstance(provider));
}
@@ -113,16 +128,19 @@ namespace System {
// a NumberFormatInfo isn't specified, the current culture's
// NumberFormatInfo is assumed.
//
- public static long Parse(String s, NumberStyles style, IFormatProvider provider) {
+ public static long Parse(String s, NumberStyles style, IFormatProvider provider)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Number.ParseInt64(s, style, NumberFormatInfo.GetInstance(provider));
}
- public static Boolean TryParse(String s, out Int64 result) {
+ public static Boolean TryParse(String s, out Int64 result)
+ {
return Number.TryParseInt64(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result);
}
- public static Boolean TryParse(String s, NumberStyles style, IFormatProvider provider, out Int64 result) {
+ public static Boolean TryParse(String s, NumberStyles style, IFormatProvider provider, out Int64 result)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Number.TryParseInt64(s, style, NumberFormatInfo.GetInstance(provider), out result);
}
@@ -130,83 +148,84 @@ namespace System {
//
// IConvertible implementation
//
-
- public TypeCode GetTypeCode() {
+
+ public TypeCode GetTypeCode()
+ {
return TypeCode.Int64;
}
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
return Convert.ToBoolean(m_value);
}
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
return Convert.ToChar(m_value);
}
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
return Convert.ToSByte(m_value);
}
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
return Convert.ToByte(m_value);
}
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
return Convert.ToInt16(m_value);
}
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
return Convert.ToUInt16(m_value);
}
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
return Convert.ToInt32(m_value);
}
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
return Convert.ToUInt32(m_value);
}
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
return m_value;
}
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
return Convert.ToUInt64(m_value);
}
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
return Convert.ToSingle(m_value);
}
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
return Convert.ToDouble(m_value);
}
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider) {
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
return Convert.ToDecimal(m_value);
}
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Int64", "DateTime"));
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Int64", "DateTime"));
}
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
return Convert.DefaultToType((IConvertible)this, type, provider);
}
}
diff --git a/src/mscorlib/src/System/IntPtr.cs b/src/mscorlib/src/System/IntPtr.cs
index dbddcd319a..28f1b1baa8 100644
--- a/src/mscorlib/src/System/IntPtr.cs
+++ b/src/mscorlib/src/System/IntPtr.cs
@@ -11,8 +11,8 @@
**
===========================================================*/
-namespace System {
-
+namespace System
+{
using System;
using System.Globalization;
using System.Runtime;
@@ -26,31 +26,31 @@ namespace System {
public struct IntPtr : IEquatable<IntPtr>, ISerializable
{
unsafe private void* m_value; // The compiler treats void* closest to uint hence explicit casts are required to preserve int behavior
-
+
public static readonly IntPtr Zero;
// fast way to compare IntPtr to (IntPtr)0 while IntPtr.Zero doesn't work due to slow statics access
[Pure]
internal unsafe bool IsNull()
{
- return (this.m_value == null);
+ return (m_value == null);
}
[System.Runtime.Versioning.NonVersionable]
public unsafe IntPtr(int value)
{
#if BIT64
- m_value = (void *)(long)value;
+ m_value = (void*)(long)value;
#else // !BIT64 (32)
m_value = (void *)value;
#endif
}
-
+
[System.Runtime.Versioning.NonVersionable]
public unsafe IntPtr(long value)
{
#if BIT64
- m_value = (void *)value;
+ m_value = (void*)value;
#else // !BIT64 (32)
m_value = (void *)checked((int)value);
#endif
@@ -63,30 +63,36 @@ namespace System {
m_value = value;
}
- private unsafe IntPtr(SerializationInfo info, StreamingContext context) {
+ private unsafe IntPtr(SerializationInfo info, StreamingContext context)
+ {
long l = info.GetInt64("value");
- if (Size==4 && (l>Int32.MaxValue || l<Int32.MinValue)) {
- throw new ArgumentException(Environment.GetResourceString("Serialization_InvalidPtrValue"));
+ if (Size == 4 && (l > Int32.MaxValue || l < Int32.MinValue))
+ {
+ throw new ArgumentException(SR.Serialization_InvalidPtrValue);
}
- m_value = (void *)l;
+ m_value = (void*)l;
}
- unsafe void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
+ unsafe void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
#if BIT64
- info.AddValue("value", (long)(m_value));
+ info.AddValue("value", (long)(m_value));
#else // !BIT64 (32)
info.AddValue("value", (long)((int)m_value));
#endif
}
- public unsafe override bool Equals(Object obj) {
- if (obj is IntPtr) {
+ public unsafe override bool Equals(Object obj)
+ {
+ if (obj is IntPtr)
+ {
return (m_value == ((IntPtr)obj).m_value);
}
return false;
@@ -96,8 +102,9 @@ namespace System {
{
return m_value == other.m_value;
}
-
- public unsafe override int GetHashCode() {
+
+ public unsafe override int GetHashCode()
+ {
#if BIT64
long l = (long)m_value;
return (unchecked((int)l) ^ (int)(l >> 32));
@@ -107,38 +114,41 @@ namespace System {
}
[System.Runtime.Versioning.NonVersionable]
- public unsafe int ToInt32() {
+ public unsafe int ToInt32()
+ {
#if BIT64
- long l = (long)m_value;
- return checked((int)l);
+ long l = (long)m_value;
+ return checked((int)l);
#else // !BIT64 (32)
return (int)m_value;
#endif
}
[System.Runtime.Versioning.NonVersionable]
- public unsafe long ToInt64() {
+ public unsafe long ToInt64()
+ {
#if BIT64
- return (long)m_value;
+ return (long)m_value;
#else // !BIT64 (32)
return (long)(int)m_value;
#endif
}
- public unsafe override String ToString() {
+ public unsafe override String ToString()
+ {
#if BIT64
- return ((long)m_value).ToString(CultureInfo.InvariantCulture);
+ return ((long)m_value).ToString(CultureInfo.InvariantCulture);
#else // !BIT64 (32)
return ((int)m_value).ToString(CultureInfo.InvariantCulture);
#endif
}
- public unsafe String ToString(String format)
+ public unsafe String ToString(String format)
{
Contract.Ensures(Contract.Result<String>() != null);
#if BIT64
- return ((long)m_value).ToString(format, CultureInfo.InvariantCulture);
+ return ((long)m_value).ToString(format, CultureInfo.InvariantCulture);
#else // !BIT64 (32)
return ((int)m_value).ToString(format, CultureInfo.InvariantCulture);
#endif
@@ -146,20 +156,20 @@ namespace System {
[System.Runtime.Versioning.NonVersionable]
- public static explicit operator IntPtr (int value)
+ public static explicit operator IntPtr(int value)
{
return new IntPtr(value);
}
[System.Runtime.Versioning.NonVersionable]
- public static explicit operator IntPtr (long value)
+ public static explicit operator IntPtr(long value)
{
return new IntPtr(value);
}
[CLSCompliant(false), ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
[System.Runtime.Versioning.NonVersionable]
- public static unsafe explicit operator IntPtr (void* value)
+ public static unsafe explicit operator IntPtr(void* value)
{
return new IntPtr(value);
}
@@ -172,34 +182,34 @@ namespace System {
}
[System.Runtime.Versioning.NonVersionable]
- public unsafe static explicit operator int (IntPtr value)
+ public unsafe static explicit operator int(IntPtr value)
{
#if BIT64
- long l = (long)value.m_value;
- return checked((int)l);
+ long l = (long)value.m_value;
+ return checked((int)l);
#else // !BIT64 (32)
return (int)value.m_value;
#endif
}
[System.Runtime.Versioning.NonVersionable]
- public unsafe static explicit operator long (IntPtr value)
+ public unsafe static explicit operator long(IntPtr value)
{
#if BIT64
- return (long)value.m_value;
+ return (long)value.m_value;
#else // !BIT64 (32)
return (long)(int)value.m_value;
#endif
}
[System.Runtime.Versioning.NonVersionable]
- public unsafe static bool operator == (IntPtr value1, IntPtr value2)
+ public unsafe static bool operator ==(IntPtr value1, IntPtr value2)
{
return value1.m_value == value2.m_value;
}
[System.Runtime.Versioning.NonVersionable]
- public unsafe static bool operator != (IntPtr value1, IntPtr value2)
+ public unsafe static bool operator !=(IntPtr value1, IntPtr value2)
{
return value1.m_value != value2.m_value;
}
@@ -211,24 +221,26 @@ namespace System {
}
[System.Runtime.Versioning.NonVersionable]
- public static IntPtr operator +(IntPtr pointer, int offset)
+ public static IntPtr operator +(IntPtr pointer, int offset)
{
#if BIT64
- return new IntPtr(pointer.ToInt64() + offset);
+ return new IntPtr(pointer.ToInt64() + offset);
#else // !BIT64 (32)
return new IntPtr(pointer.ToInt32() + offset);
#endif
}
[System.Runtime.Versioning.NonVersionable]
- public static IntPtr Subtract(IntPtr pointer, int offset) {
+ public static IntPtr Subtract(IntPtr pointer, int offset)
+ {
return pointer - offset;
}
[System.Runtime.Versioning.NonVersionable]
- public static IntPtr operator -(IntPtr pointer, int offset) {
+ public static IntPtr operator -(IntPtr pointer, int offset)
+ {
#if BIT64
- return new IntPtr(pointer.ToInt64() - offset);
+ return new IntPtr(pointer.ToInt64() - offset);
#else // !BIT64 (32)
return new IntPtr(pointer.ToInt32() - offset);
#endif
@@ -241,13 +253,13 @@ namespace System {
get
{
#if BIT64
- return 8;
+ return 8;
#else // !BIT64 (32)
return 4;
#endif
}
}
-
+
[CLSCompliant(false)]
[System.Runtime.Versioning.NonVersionable]
diff --git a/src/mscorlib/src/System/Internal.cs b/src/mscorlib/src/System/Internal.cs
index b0860109d9..1534326921 100644
--- a/src/mscorlib/src/System/Internal.cs
+++ b/src/mscorlib/src/System/Internal.cs
@@ -10,6 +10,7 @@
**
**
===========================================================*/
+
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Collections.Generic;
@@ -22,13 +23,13 @@ using System.Threading.Tasks;
using System.Runtime.InteropServices.WindowsRuntime;
#endif // FEATURE_COMINTEROP
-[assembly:DefaultDependencyAttribute(LoadHint.Always)]
+[assembly: DefaultDependencyAttribute(LoadHint.Always)]
// mscorlib would like to have its literal strings frozen if possible
[assembly: System.Runtime.CompilerServices.StringFreezingAttribute()]
namespace System
{
- static class Internal
+ static class CommonlyUsedGenericInstantiations
{
// This method is purely an aid for NGen to statically deduce which
// instantiations to save in the ngen image.
@@ -44,7 +45,7 @@ namespace System
// instantiation closure process is driven by "fixup" references
// left in the final code stream.
[MethodImplAttribute(MethodImplOptions.NoOptimization)]
- static void CommonlyUsedGenericInstantiations()
+ static CommonlyUsedGenericInstantiations()
{
// Make absolutely sure we include some of the most common
// instantiations here in mscorlib's ngen image.
@@ -86,14 +87,14 @@ namespace System
new EnumEqualityComparer<System.Reflection.MemberTypes>();
// Microsoft.Expression.DesignModel
- new Dictionary<Object, KeyValuePair<Object,Object>>();
- new Dictionary<KeyValuePair<Object,Object>, Object>();
+ new Dictionary<Object, KeyValuePair<Object, Object>>();
+ new Dictionary<KeyValuePair<Object, Object>, Object>();
NullableHelper<Boolean>();
NullableHelper<Byte>();
NullableHelper<Char>();
- NullableHelper<DateTime>();
- NullableHelper<Decimal>();
+ NullableHelper<DateTime>();
+ NullableHelper<Decimal>();
NullableHelper<Double>();
NullableHelper<Guid>();
NullableHelper<Int16>();
@@ -127,7 +128,7 @@ namespace System
new KeyValuePair<Char, UInt16>('\0', UInt16.MinValue);
new KeyValuePair<UInt16, Double>(UInt16.MinValue, Double.MinValue);
new KeyValuePair<Object, Int32>(String.Empty, Int32.MinValue);
- new KeyValuePair<Int32, Int32>(Int32.MinValue, Int32.MinValue);
+ new KeyValuePair<Int32, Int32>(Int32.MinValue, Int32.MinValue);
SZArrayHelper<Boolean>(null);
SZArrayHelper<Byte>(null);
SZArrayHelper<DateTime>(null);
@@ -156,15 +157,15 @@ namespace System
#pragma warning restore 4014
}
- static T NullableHelper<T>() where T : struct
+ private static T NullableHelper<T>() where T : struct
{
- Nullable.Compare<T>(null, null);
- Nullable.Equals<T>(null, null);
+ Nullable.Compare<T>(null, null);
+ Nullable.Equals<T>(null, null);
Nullable<T> nullable = new Nullable<T>();
return nullable.GetValueOrDefault();
- }
+ }
- static void SZArrayHelper<T>(SZArrayHelper oSZArrayHelper)
+ private static void SZArrayHelper<T>(SZArrayHelper oSZArrayHelper)
{
// Instantiate common methods for IList implementation on Array
oSZArrayHelper.get_Count<T>();
@@ -174,20 +175,20 @@ namespace System
// System.Runtime.CompilerServices.AsyncVoidMethodBuilder
// System.Runtime.CompilerServices.TaskAwaiter
- static async void AsyncHelper<T>()
+ private static async void AsyncHelper<T>()
{
await Task.Delay(1);
}
// System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[System.__Canon]
// System.Runtime.CompilerServices.TaskAwaiter'[System.__Canon]
- static async Task<String> AsyncHelper2<T>()
+ private static async Task<String> AsyncHelper2<T>()
{
return await Task.FromResult<string>("");
}
// System.Runtime.CompilerServices.AsyncTaskMethodBuilder
// System.Runtime.CompilerServices.AsyncTaskMethodBuilder'1[VoidTaskResult]
- static async Task AsyncHelper3()
+ private static async Task AsyncHelper3()
{
await Task.FromResult<string>("");
}
@@ -201,7 +202,7 @@ namespace System
// typed as matching instantiations of mscorlib copies of WinRT interfaces (IIterable<T>, IVector<T>,
// IMap<K, V>, ...) which is necessary to generate all required IL stubs.
- static void CommonlyUsedWinRTRedirectedInterfaceStubs()
+ private static void CommonlyUsedWinRTRedirectedInterfaceStubs()
{
WinRT_IEnumerable<byte>(null, null, null);
WinRT_IEnumerable<char>(null, null, null);
@@ -247,14 +248,14 @@ namespace System
WinRT_Nullable<double>();
}
- static void WinRT_IEnumerable<T>(IterableToEnumerableAdapter iterableToEnumerableAdapter, EnumerableToIterableAdapter enumerableToIterableAdapter, IIterable<T> iterable)
+ private static void WinRT_IEnumerable<T>(IterableToEnumerableAdapter iterableToEnumerableAdapter, EnumerableToIterableAdapter enumerableToIterableAdapter, IIterable<T> iterable)
{
// instantiate stubs for the one method on IEnumerable<T> and the one method on IIterable<T>
iterableToEnumerableAdapter.GetEnumerator_Stub<T>();
enumerableToIterableAdapter.First_Stub<T>();
}
- static void WinRT_IList<T>(VectorToListAdapter vectorToListAdapter, VectorToCollectionAdapter vectorToCollectionAdapter, ListToVectorAdapter listToVectorAdapter, IVector<T> vector)
+ private static void WinRT_IList<T>(VectorToListAdapter vectorToListAdapter, VectorToCollectionAdapter vectorToCollectionAdapter, ListToVectorAdapter listToVectorAdapter, IVector<T> vector)
{
WinRT_IEnumerable<T>(null, null, null);
@@ -278,7 +279,7 @@ namespace System
listToVectorAdapter.Clear<T>();
}
- static void WinRT_IReadOnlyCollection<T>(VectorViewToReadOnlyCollectionAdapter vectorViewToReadOnlyCollectionAdapter)
+ private static void WinRT_IReadOnlyCollection<T>(VectorViewToReadOnlyCollectionAdapter vectorViewToReadOnlyCollectionAdapter)
{
WinRT_IEnumerable<T>(null, null, null);
@@ -286,7 +287,7 @@ namespace System
vectorViewToReadOnlyCollectionAdapter.Count<T>();
}
- static void WinRT_IReadOnlyList<T>(IVectorViewToIReadOnlyListAdapter vectorToListAdapter, IReadOnlyListToIVectorViewAdapter listToVectorAdapter, IVectorView<T> vectorView)
+ private static void WinRT_IReadOnlyList<T>(IVectorViewToIReadOnlyListAdapter vectorToListAdapter, IReadOnlyListToIVectorViewAdapter listToVectorAdapter, IVectorView<T> vectorView)
{
WinRT_IEnumerable<T>(null, null, null);
WinRT_IReadOnlyCollection<T>(null);
@@ -299,7 +300,7 @@ namespace System
listToVectorAdapter.Size<T>();
}
- static void WinRT_IDictionary<K, V>(MapToDictionaryAdapter mapToDictionaryAdapter, MapToCollectionAdapter mapToCollectionAdapter, DictionaryToMapAdapter dictionaryToMapAdapter, IMap<K, V> map)
+ private static void WinRT_IDictionary<K, V>(MapToDictionaryAdapter mapToDictionaryAdapter, MapToCollectionAdapter mapToCollectionAdapter, DictionaryToMapAdapter dictionaryToMapAdapter, IMap<K, V> map)
{
WinRT_IEnumerable<KeyValuePair<K, V>>(null, null, null);
@@ -324,7 +325,7 @@ namespace System
dictionaryToMapAdapter.Clear<K, V>();
}
- static void WinRT_IReadOnlyDictionary<K, V>(IMapViewToIReadOnlyDictionaryAdapter mapToDictionaryAdapter, IReadOnlyDictionaryToIMapViewAdapter dictionaryToMapAdapter, IMapView<K, V> mapView, MapViewToReadOnlyCollectionAdapter mapViewToReadOnlyCollectionAdapter)
+ private static void WinRT_IReadOnlyDictionary<K, V>(IMapViewToIReadOnlyDictionaryAdapter mapToDictionaryAdapter, IReadOnlyDictionaryToIMapViewAdapter dictionaryToMapAdapter, IMapView<K, V> mapView, MapViewToReadOnlyCollectionAdapter mapViewToReadOnlyCollectionAdapter)
{
WinRT_IEnumerable<KeyValuePair<K, V>>(null, null, null);
WinRT_IReadOnlyCollection<KeyValuePair<K, V>>(null);
@@ -344,7 +345,7 @@ namespace System
dictionaryToMapAdapter.HasKey<K, V>(default(K));
}
- static void WinRT_Nullable<T>() where T : struct
+ private static void WinRT_Nullable<T>() where T : struct
{
Nullable<T> nullable = new Nullable<T>();
NullableMarshaler.ConvertToNative(ref nullable);
diff --git a/src/mscorlib/src/System/Lazy.cs b/src/mscorlib/src/System/Lazy.cs
deleted file mode 100644
index 0ddd6da3a2..0000000000
--- a/src/mscorlib/src/System/Lazy.cs
+++ /dev/null
@@ -1,506 +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.
-#pragma warning disable 0420
-
-// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-//
-//
-//
-// --------------------------------------------------------------------------------------
-//
-// A class that provides a simple, lightweight implementation of lazy initialization,
-// obviating the need for a developer to implement a custom, thread-safe lazy initialization
-// solution.
-//
-// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-using System.Runtime;
-using System.Runtime.InteropServices;
-using System.Security;
-using System.Diagnostics;
-using System.Runtime.Serialization;
-using System.Threading;
-using System.Diagnostics.Contracts;
-using System.Runtime.ExceptionServices;
-
-namespace System
-{
- // Lazy<T> is generic, but not all of its state needs to be generic. Avoid creating duplicate
- // objects per instantiation by putting them here.
- internal static class LazyHelpers
- {
- // Dummy object used as the value of m_threadSafeObj if in PublicationOnly mode.
- internal static readonly object PUBLICATION_ONLY_SENTINEL = new object();
- }
-
- /// <summary>
- /// Provides support for lazy initialization.
- /// </summary>
- /// <typeparam name="T">Specifies the type of element being lazily initialized.</typeparam>
- /// <remarks>
- /// <para>
- /// By default, all public and protected members of <see cref="Lazy{T}"/> are thread-safe and may be used
- /// concurrently from multiple threads. These thread-safety guarantees may be removed optionally and per instance
- /// using parameters to the type's constructors.
- /// </para>
- /// </remarks>
- [Serializable]
- [DebuggerTypeProxy(typeof(System_LazyDebugView<>))]
- [DebuggerDisplay("ThreadSafetyMode={Mode}, IsValueCreated={IsValueCreated}, IsValueFaulted={IsValueFaulted}, Value={ValueForDebugDisplay}")]
- public class Lazy<T>
- {
-
-#region Inner classes
- /// <summary>
- /// wrapper class to box the initialized value, this is mainly created to avoid boxing/unboxing the value each time the value is called in case T is
- /// a value type
- /// </summary>
- [Serializable]
- class Boxed
- {
- internal Boxed(T value)
- {
- m_value = value;
- }
- internal T m_value;
- }
-
-
- /// <summary>
- /// Wrapper class to wrap the excpetion thrown by the value factory
- /// </summary>
- class LazyInternalExceptionHolder
- {
- internal ExceptionDispatchInfo m_edi;
- internal LazyInternalExceptionHolder(Exception ex)
- {
- m_edi = ExceptionDispatchInfo.Capture(ex);
- }
- }
-#endregion
-
- // A dummy delegate used as a :
- // 1- Flag to avoid recursive call to Value in None and ExecutionAndPublication modes in m_valueFactory
- // 2- Flag to m_threadSafeObj if ExecutionAndPublication mode and the value is known to be initialized
- static readonly Func<T> ALREADY_INVOKED_SENTINEL = delegate
- {
- Debug.Assert(false, "ALREADY_INVOKED_SENTINEL should never be invoked.");
- return default(T);
- };
-
- //null --> value is not created
- //m_value is Boxed --> the value is created, and m_value holds the value
- //m_value is LazyExceptionHolder --> it holds an exception
- private object m_boxed;
-
- // The factory delegate that returns the value.
- // In None and ExecutionAndPublication modes, this will be set to ALREADY_INVOKED_SENTINEL as a flag to avoid recursive calls
- [NonSerialized]
- private Func<T> m_valueFactory;
-
- // null if it is not thread safe mode
- // LazyHelpers.PUBLICATION_ONLY_SENTINEL if PublicationOnly mode
- // object if ExecutionAndPublication mode (may be ALREADY_INVOKED_SENTINEL if the value is already initialized)
- [NonSerialized]
- private object m_threadSafeObj;
-
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/> class that
- /// uses <typeparamref name="T"/>'s default constructor for lazy initialization.
- /// </summary>
- /// <remarks>
- /// An instance created with this constructor may be used concurrently from multiple threads.
- /// </remarks>
- public Lazy()
- : this(LazyThreadSafetyMode.ExecutionAndPublication)
- {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/> class that
- /// uses a pre-initialized specified value.
- /// </summary>
- /// <remarks>
- /// An instance created with this constructor should be usable by multiple threads
- // concurrently.
- /// </remarks>
- public Lazy(T value)
- {
- m_boxed = new Boxed(value);
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/> class that uses a
- /// specified initialization function.
- /// </summary>
- /// <param name="valueFactory">
- /// The <see cref="T:System.Func{T}"/> invoked to produce the lazily-initialized value when it is
- /// needed.
- /// </param>
- /// <exception cref="System.ArgumentNullException"><paramref name="valueFactory"/> is a null
- /// reference (Nothing in Visual Basic).</exception>
- /// <remarks>
- /// An instance created with this constructor may be used concurrently from multiple threads.
- /// </remarks>
- public Lazy(Func<T> valueFactory)
- : this(valueFactory, LazyThreadSafetyMode.ExecutionAndPublication)
- {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/>
- /// class that uses <typeparamref name="T"/>'s default constructor and a specified thread-safety mode.
- /// </summary>
- /// <param name="isThreadSafe">true if this instance should be usable by multiple threads concurrently; false if the instance will only be used by one thread at a time.
- /// </param>
- public Lazy(bool isThreadSafe) :
- this(isThreadSafe? LazyThreadSafetyMode.ExecutionAndPublication : LazyThreadSafetyMode.None)
- {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/>
- /// class that uses <typeparamref name="T"/>'s default constructor and a specified thread-safety mode.
- /// </summary>
- /// <param name="mode">The lazy thread-safety mode mode</param>
- /// <exception cref="System.ArgumentOutOfRangeException"><paramref name="mode"/> mode contains an invalid valuee</exception>
- public Lazy(LazyThreadSafetyMode mode)
- {
- m_threadSafeObj = GetObjectFromMode(mode);
- }
-
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/> class
- /// that uses a specified initialization function and a specified thread-safety mode.
- /// </summary>
- /// <param name="valueFactory">
- /// The <see cref="T:System.Func{T}"/> invoked to produce the lazily-initialized value when it is needed.
- /// </param>
- /// <param name="isThreadSafe">true if this instance should be usable by multiple threads concurrently; false if the instance will only be used by one thread at a time.
- /// </param>
- /// <exception cref="System.ArgumentNullException"><paramref name="valueFactory"/> is
- /// a null reference (Nothing in Visual Basic).</exception>
- public Lazy(Func<T> valueFactory, bool isThreadSafe)
- : this(valueFactory, isThreadSafe ? LazyThreadSafetyMode.ExecutionAndPublication : LazyThreadSafetyMode.None)
- {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Lazy{T}"/> class
- /// that uses a specified initialization function and a specified thread-safety mode.
- /// </summary>
- /// <param name="valueFactory">
- /// The <see cref="T:System.Func{T}"/> invoked to produce the lazily-initialized value when it is needed.
- /// </param>
- /// <param name="mode">The lazy thread-safety mode.</param>
- /// <exception cref="System.ArgumentNullException"><paramref name="valueFactory"/> is
- /// a null reference (Nothing in Visual Basic).</exception>
- /// <exception cref="System.ArgumentOutOfRangeException"><paramref name="mode"/> mode contains an invalid value.</exception>
- public Lazy(Func<T> valueFactory, LazyThreadSafetyMode mode)
- {
- if (valueFactory == null)
- throw new ArgumentNullException(nameof(valueFactory));
-
- m_threadSafeObj = GetObjectFromMode(mode);
- m_valueFactory = valueFactory;
- }
-
- /// <summary>
- /// Static helper function that returns an object based on the given mode. it also throws an exception if the mode is invalid
- /// </summary>
- private static object GetObjectFromMode(LazyThreadSafetyMode mode)
- {
- if (mode == LazyThreadSafetyMode.ExecutionAndPublication)
- return new object();
- else if (mode == LazyThreadSafetyMode.PublicationOnly)
- return LazyHelpers.PUBLICATION_ONLY_SENTINEL;
- else if (mode != LazyThreadSafetyMode.None)
- throw new ArgumentOutOfRangeException(nameof(mode), Environment.GetResourceString("Lazy_ctor_ModeInvalid"));
-
- return null; // None mode
- }
-
- /// <summary>Forces initialization during serialization.</summary>
- /// <param name="context">The StreamingContext for the serialization operation.</param>
- [OnSerializing]
- private void OnSerializing(StreamingContext context)
- {
- // Force initialization
- T dummy = Value;
- }
-
- /// <summary>Creates and returns a string representation of this instance.</summary>
- /// <returns>The result of calling <see cref="System.Object.ToString"/> on the <see
- /// cref="Value"/>.</returns>
- /// <exception cref="T:System.NullReferenceException">
- /// The <see cref="Value"/> is null.
- /// </exception>
- public override string ToString()
- {
- return IsValueCreated ? Value.ToString() : Environment.GetResourceString("Lazy_ToString_ValueNotCreated");
- }
-
- /// <summary>Gets the value of the Lazy&lt;T&gt; for debugging display purposes.</summary>
- internal T ValueForDebugDisplay
- {
- get
- {
- if (!IsValueCreated)
- {
- return default(T);
- }
- return ((Boxed)m_boxed).m_value;
- }
- }
-
- /// <summary>
- /// Gets a value indicating whether this instance may be used concurrently from multiple threads.
- /// </summary>
- internal LazyThreadSafetyMode Mode
- {
- get
- {
- if (m_threadSafeObj == null) return LazyThreadSafetyMode.None;
- if (m_threadSafeObj == (object)LazyHelpers.PUBLICATION_ONLY_SENTINEL) return LazyThreadSafetyMode.PublicationOnly;
- return LazyThreadSafetyMode.ExecutionAndPublication;
- }
- }
-
- /// <summary>
- /// Gets whether the value creation is faulted or not
- /// </summary>
- internal bool IsValueFaulted
- {
- get { return m_boxed is LazyInternalExceptionHolder; }
- }
-
- /// <summary>Gets a value indicating whether the <see cref="T:System.Lazy{T}"/> has been initialized.
- /// </summary>
- /// <value>true if the <see cref="T:System.Lazy{T}"/> instance has been initialized;
- /// otherwise, false.</value>
- /// <remarks>
- /// The initialization of a <see cref="T:System.Lazy{T}"/> instance may result in either
- /// a value being produced or an exception being thrown. If an exception goes unhandled during initialization,
- /// <see cref="IsValueCreated"/> will return false.
- /// </remarks>
- public bool IsValueCreated
- {
- get
- {
- return m_boxed != null && m_boxed is Boxed;
- }
- }
-
- /// <summary>Gets the lazily initialized value of the current <see
- /// cref="T:System.Threading.Lazy{T}"/>.</summary>
- /// <value>The lazily initialized value of the current <see
- /// cref="T:System.Threading.Lazy{T}"/>.</value>
- /// <exception cref="T:System.MissingMemberException">
- /// The <see cref="T:System.Threading.Lazy{T}"/> was initialized to use the default constructor
- /// of the type being lazily initialized, and that type does not have a public, parameterless constructor.
- /// </exception>
- /// <exception cref="T:System.MemberAccessException">
- /// The <see cref="T:System.Threading.Lazy{T}"/> was initialized to use the default constructor
- /// of the type being lazily initialized, and permissions to access the constructor were missing.
- /// </exception>
- /// <exception cref="T:System.InvalidOperationException">
- /// The <see cref="T:System.Threading.Lazy{T}"/> was constructed with the <see cref="T:System.Threading.LazyThreadSafetyMode.ExecutionAndPublication"/> or
- /// <see cref="T:System.Threading.LazyThreadSafetyMode.None"/> and the initialization function attempted to access <see cref="Value"/> on this instance.
- /// </exception>
- /// <remarks>
- /// If <see cref="IsValueCreated"/> is false, accessing <see cref="Value"/> will force initialization.
- /// Please <see cref="System.Threading.LazyThreadSafetyMode"> for more information on how <see cref="T:System.Threading.Lazy{T}"/> will behave if an exception is thrown
- /// from initialization delegate.
- /// </remarks>
- [DebuggerBrowsable(DebuggerBrowsableState.Never)]
- public T Value
- {
- get
- {
- Boxed boxed = null;
- if (m_boxed != null )
- {
- // Do a quick check up front for the fast path.
- boxed = m_boxed as Boxed;
- if (boxed != null)
- {
- return boxed.m_value;
- }
-
- LazyInternalExceptionHolder exc = m_boxed as LazyInternalExceptionHolder;
- Debug.Assert(exc != null);
- exc.m_edi.Throw();
- }
-
- // Fall through to the slow path.
- return LazyInitValue();
- }
- }
-
- /// <summary>
- /// local helper method to initialize the value
- /// </summary>
- /// <returns>The inititialized T value</returns>
- private T LazyInitValue()
- {
- Boxed boxed = null;
- LazyThreadSafetyMode mode = Mode;
- if (mode == LazyThreadSafetyMode.None)
- {
- boxed = CreateValue();
- m_boxed = boxed;
- }
- else if (mode == LazyThreadSafetyMode.PublicationOnly)
- {
- boxed = CreateValue();
- if (boxed == null ||
- Interlocked.CompareExchange(ref m_boxed, boxed, null) != null)
- {
- // If CreateValue returns null, it means another thread successfully invoked the value factory
- // and stored the result, so we should just take what was stored. If CreateValue returns non-null
- // but another thread set the value we should just take what was stored.
- boxed = (Boxed)m_boxed;
- }
- else
- {
- // We successfully created and stored the value. At this point, the value factory delegate is
- // no longer needed, and we don't want to hold onto its resources.
- m_valueFactory = ALREADY_INVOKED_SENTINEL;
- }
- }
- else
- {
- object threadSafeObj = Volatile.Read(ref m_threadSafeObj);
- bool lockTaken = false;
- try
- {
- if (threadSafeObj != (object)ALREADY_INVOKED_SENTINEL)
- Monitor.Enter(threadSafeObj, ref lockTaken);
- else
- Debug.Assert(m_boxed != null);
-
- if (m_boxed == null)
- {
- boxed = CreateValue();
- m_boxed = boxed;
- Volatile.Write(ref m_threadSafeObj, ALREADY_INVOKED_SENTINEL);
- }
- else // got the lock but the value is not null anymore, check if it is created by another thread or faulted and throw if so
- {
- boxed = m_boxed as Boxed;
- if (boxed == null) // it is not Boxed, so it is a LazyInternalExceptionHolder
- {
- LazyInternalExceptionHolder exHolder = m_boxed as LazyInternalExceptionHolder;
- Debug.Assert(exHolder != null);
- exHolder.m_edi.Throw();
- }
- }
- }
- finally
- {
- if (lockTaken)
- Monitor.Exit(threadSafeObj);
- }
- }
- Debug.Assert(boxed != null);
- return boxed.m_value;
- }
-
- /// <summary>Creates an instance of T using m_valueFactory in case its not null or use reflection to create a new T()</summary>
- /// <returns>An instance of Boxed.</returns>
- private Boxed CreateValue()
- {
- Boxed boxed = null;
- LazyThreadSafetyMode mode = Mode;
- if (m_valueFactory != null)
- {
- try
- {
- // check for recursion
- if (mode != LazyThreadSafetyMode.PublicationOnly && m_valueFactory == ALREADY_INVOKED_SENTINEL)
- throw new InvalidOperationException(Environment.GetResourceString("Lazy_Value_RecursiveCallsToValue"));
-
- Func<T> factory = m_valueFactory;
- if (mode != LazyThreadSafetyMode.PublicationOnly) // only detect recursion on None and ExecutionAndPublication modes
- {
- m_valueFactory = ALREADY_INVOKED_SENTINEL;
- }
- else if (factory == ALREADY_INVOKED_SENTINEL)
- {
- // Another thread raced to successfully invoke the factory.
- return null;
- }
- boxed = new Boxed(factory());
- }
- catch (Exception ex)
- {
- if (mode != LazyThreadSafetyMode.PublicationOnly) // don't cache the exception for PublicationOnly mode
- m_boxed = new LazyInternalExceptionHolder(ex);
- throw;
- }
- }
- else
- {
- try
- {
- boxed = new Boxed((T)Activator.CreateInstance(typeof(T)));
-
- }
- catch (System.MissingMethodException)
- {
- Exception ex = new System.MissingMemberException(Environment.GetResourceString("Lazy_CreateValue_NoParameterlessCtorForT"));
- if (mode != LazyThreadSafetyMode.PublicationOnly) // don't cache the exception for PublicationOnly mode
- m_boxed = new LazyInternalExceptionHolder(ex);
- throw ex;
- }
- }
-
- return boxed;
- }
-
- }
-
- /// <summary>A debugger view of the Lazy&lt;T&gt; to surface additional debugging properties and
- /// to ensure that the Lazy&lt;T&gt; does not become initialized if it was not already.</summary>
- internal sealed class System_LazyDebugView<T>
- {
- //The Lazy object being viewed.
- private readonly Lazy<T> m_lazy;
-
- /// <summary>Constructs a new debugger view object for the provided Lazy object.</summary>
- /// <param name="lazy">A Lazy object to browse in the debugger.</param>
- public System_LazyDebugView(Lazy<T> lazy)
- {
- m_lazy = lazy;
- }
-
- /// <summary>Returns whether the Lazy object is initialized or not.</summary>
- public bool IsValueCreated
- {
- get { return m_lazy.IsValueCreated; }
- }
-
- /// <summary>Returns the value of the Lazy object.</summary>
- public T Value
- {
- get
- { return m_lazy.ValueForDebugDisplay; }
- }
-
- /// <summary>Returns the execution mode of the Lazy object</summary>
- public LazyThreadSafetyMode Mode
- {
- get { return m_lazy.Mode; }
- }
-
- /// <summary>Returns the execution mode of the Lazy object</summary>
- public bool IsValueFaulted
- {
- get { return m_lazy.IsValueFaulted; }
- }
-
- }
-}
diff --git a/src/mscorlib/src/System/LowLevelConsole.cs b/src/mscorlib/src/System/LowLevelConsole.cs
deleted file mode 100644
index 29e69185ac..0000000000
--- a/src/mscorlib/src/System/LowLevelConsole.cs
+++ /dev/null
@@ -1,65 +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.Text;
-using System.Security;
-using Microsoft.Win32;
-using Microsoft.Win32.SafeHandles;
-
-namespace System
-{
- //
- // Simple limited console class for internal printf-style debugging in System.Private.CoreLib
- // and low-level tests that want to call System.Private.CoreLib directly
- //
-
- public static class LowLevelConsole
- {
- private static readonly SafeFileHandle _outputHandle =
- new SafeFileHandle(Win32Native.GetStdHandle(Win32Native.STD_OUTPUT_HANDLE), false);
-
- public static unsafe void Write(string s)
- {
- byte[] bytes = Encoding.UTF8.GetBytes(s);
-
- fixed (byte * pBytes = bytes)
- {
- int bytesWritten;
- Win32Native.WriteFile(_outputHandle, pBytes, bytes.Length, out bytesWritten, IntPtr.Zero);
- }
- }
-
- public static void WriteLine(string s)
- {
- Write(s + Environment.NewLine);
- }
-
- public static void WriteLine()
- {
- Write(Environment.NewLine);
- }
- }
-
- //
- // Internal wrapper with the regular name for convenience. Note that it cannot be public to avoid colliding
- // with the full Console type.
- //
- internal static class Console
- {
- public static void Write(string s)
- {
- LowLevelConsole.Write(s);
- }
-
- public static void WriteLine(string s)
- {
- LowLevelConsole.WriteLine(s);
- }
-
- public static void WriteLine()
- {
- LowLevelConsole.WriteLine();
- }
- }
-}
diff --git a/src/mscorlib/src/System/MarshalByRefObject.cs b/src/mscorlib/src/System/MarshalByRefObject.cs
deleted file mode 100644
index 9014de00c7..0000000000
--- a/src/mscorlib/src/System/MarshalByRefObject.cs
+++ /dev/null
@@ -1,30 +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.
-
-namespace System
-{
- [Serializable]
- public abstract class MarshalByRefObject
- {
- protected MarshalByRefObject()
- {
- }
-
- public object GetLifetimeService()
- {
- throw new PlatformNotSupportedException();
- }
-
- public virtual object InitializeLifetimeService()
- {
- throw new PlatformNotSupportedException();
- }
-
- protected MarshalByRefObject MemberwiseClone(bool cloneIdentity)
- {
- MarshalByRefObject mbr = (MarshalByRefObject)base.MemberwiseClone();
- return mbr;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Math.cs b/src/mscorlib/src/System/Math.cs
index 8b2af3d3e4..6f7d731ab1 100644
--- a/src/mscorlib/src/System/Math.cs
+++ b/src/mscorlib/src/System/Math.cs
@@ -10,260 +10,297 @@
**
**
===========================================================*/
-namespace System {
-
- //This class contains only static members and doesn't require serialization.
- using System;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.Versioning;
- using System.Diagnostics.Contracts;
-
- public static class Math {
-
- private static double doubleRoundLimit = 1e16d;
-
- private const int maxRoundingDigits = 15;
-
- // This table is required for the Round function which can specify the number of digits to round to
- private static double[] roundPower10Double = new double[] {
+
+//This class contains only static members and doesn't require serialization.
+
+using System;
+using System.Runtime;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.Versioning;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
+ public static class Math
+ {
+ private static double doubleRoundLimit = 1e16d;
+
+ private const int maxRoundingDigits = 15;
+
+ // This table is required for the Round function which can specify the number of digits to round to
+ private static double[] roundPower10Double = new double[] {
1E0, 1E1, 1E2, 1E3, 1E4, 1E5, 1E6, 1E7, 1E8,
1E9, 1E10, 1E11, 1E12, 1E13, 1E14, 1E15
- };
-
- public const double PI = 3.14159265358979323846;
- public const double E = 2.7182818284590452354;
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Acos(double d);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Asin(double d);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Atan(double d);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Atan2(double y,double x);
-
- public static Decimal Ceiling(Decimal d) {
- return Decimal.Ceiling(d);
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Ceiling(double a);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Cos (double d);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Cosh(double value);
-
- public static Decimal Floor(Decimal d) {
- return Decimal.Floor(d);
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Floor(double d);
-
- private static unsafe double InternalRound(double value, int digits, MidpointRounding mode) {
- if (Abs(value) < doubleRoundLimit) {
- Double power10 = roundPower10Double[digits];
- value *= power10;
- if (mode == MidpointRounding.AwayFromZero) {
- double fraction = SplitFractionDouble(&value);
- if (Abs(fraction) >= 0.5d) {
- value += Sign(fraction);
+ };
+
+ public const double PI = 3.14159265358979323846;
+ public const double E = 2.7182818284590452354;
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Acos(double d);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Asin(double d);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Atan(double d);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Atan2(double y, double x);
+
+ public static Decimal Ceiling(Decimal d)
+ {
+ return Decimal.Ceiling(d);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Ceiling(double a);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Cos(double d);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Cosh(double value);
+
+ public static Decimal Floor(Decimal d)
+ {
+ return Decimal.Floor(d);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Floor(double d);
+
+ private static unsafe double InternalRound(double value, int digits, MidpointRounding mode)
+ {
+ if (Abs(value) < doubleRoundLimit)
+ {
+ Double power10 = roundPower10Double[digits];
+ value *= power10;
+ if (mode == MidpointRounding.AwayFromZero)
+ {
+ double fraction = SplitFractionDouble(&value);
+ if (Abs(fraction) >= 0.5d)
+ {
+ value += Sign(fraction);
+ }
}
+ else
+ {
+ // On X86 this can be inlined to just a few instructions
+ value = Round(value);
+ }
+ value /= power10;
}
- else {
- // On X86 this can be inlined to just a few instructions
- value = Round(value);
- }
- value /= power10;
- }
- return value;
- }
-
- private unsafe static double InternalTruncate(double d) {
- SplitFractionDouble(&d);
- return d;
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Sin(double a);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Tan(double a);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Sinh(double value);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Tanh(double value);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Round(double a);
-
- public static double Round(double value, int digits)
- {
- if ((digits < 0) || (digits > maxRoundingDigits))
- throw new ArgumentOutOfRangeException(nameof(digits), Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
- Contract.EndContractBlock();
- return InternalRound(value, digits, MidpointRounding.ToEven);
- }
-
- public static double Round(double value, MidpointRounding mode) {
- return Round(value, 0, mode);
- }
-
- public static double Round(double value, int digits, MidpointRounding mode) {
- if ((digits < 0) || (digits > maxRoundingDigits))
- throw new ArgumentOutOfRangeException(nameof(digits), Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
- if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnumValue", mode, nameof(MidpointRounding)), nameof(mode));
- }
- Contract.EndContractBlock();
- return InternalRound(value, digits, mode);
- }
-
- public static Decimal Round(Decimal d) {
- return Decimal.Round(d,0);
- }
-
- public static Decimal Round(Decimal d, int decimals) {
- return Decimal.Round(d,decimals);
- }
-
- public static Decimal Round(Decimal d, MidpointRounding mode) {
- return Decimal.Round(d, 0, mode);
- }
-
- public static Decimal Round(Decimal d, int decimals, MidpointRounding mode) {
- return Decimal.Round(d, decimals, mode);
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static unsafe extern double SplitFractionDouble(double* value);
-
- public static Decimal Truncate(Decimal d) {
- return Decimal.Truncate(d);
- }
-
- public static double Truncate(double d) {
- return InternalTruncate(d);
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Sqrt(double d);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Log (double d);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Log10(double d);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Exp(double d);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double Pow(double x, double y);
-
- public static double IEEERemainder(double x, double y) {
- if (Double.IsNaN(x)) {
- return x; // IEEE 754-2008: NaN payload must be preserved
- }
- if (Double.IsNaN(y)) {
- return y; // IEEE 754-2008: NaN payload must be preserved
- }
-
- double regularMod = x % y;
- if (Double.IsNaN(regularMod)) {
- return Double.NaN;
- }
- if (regularMod == 0) {
- if (Double.IsNegative(x)) {
- return Double.NegativeZero;
- }
- }
- double alternativeResult;
- alternativeResult = regularMod - (Math.Abs(y) * Math.Sign(x));
- if (Math.Abs(alternativeResult) == Math.Abs(regularMod)) {
- double divisionResult = x/y;
- double roundedResult = Math.Round(divisionResult);
- if (Math.Abs(roundedResult) > Math.Abs(divisionResult)) {
- return alternativeResult;
- }
- else {
- return regularMod;
- }
- }
- if (Math.Abs(alternativeResult) < Math.Abs(regularMod)) {
- return alternativeResult;
- }
- else {
- return regularMod;
- }
- }
-
- /*================================Abs=========================================
- **Returns the absolute value of it's argument.
- ============================================================================*/
- [CLSCompliant(false)]
- public static sbyte Abs(sbyte value) {
- if (value >= 0)
return value;
- else
- return AbsHelper(value);
- }
-
- private static sbyte AbsHelper(sbyte value)
- {
- Contract.Requires(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)");
- if (value == SByte.MinValue)
- throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum"));
- Contract.EndContractBlock();
- return ((sbyte)(-value));
- }
-
- public static short Abs(short value) {
- if (value >= 0)
- return value;
- else
- return AbsHelper(value);
- }
-
- private static short AbsHelper(short value) {
- Contract.Requires(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)");
- if (value == Int16.MinValue)
- throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum"));
- Contract.EndContractBlock();
- return (short) -value;
- }
-
- public static int Abs(int value) {
- if (value >= 0)
- return value;
- else
- return AbsHelper(value);
- }
-
- private static int AbsHelper(int value) {
- Contract.Requires(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)");
- if (value == Int32.MinValue)
- throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum"));
- Contract.EndContractBlock();
- return -value;
- }
-
- public static long Abs(long value) {
- if (value >= 0)
- return value;
- else
- return AbsHelper(value);
- }
-
- private static long AbsHelper(long value) {
- Contract.Requires(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)");
- if (value == Int64.MinValue)
- throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum"));
- Contract.EndContractBlock();
- return -value;
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- extern public static float Abs(float value);
+ }
+
+ private unsafe static double InternalTruncate(double d)
+ {
+ SplitFractionDouble(&d);
+ return d;
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Sin(double a);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Tan(double a);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Sinh(double value);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Tanh(double value);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Round(double a);
+
+ public static double Round(double value, int digits)
+ {
+ if ((digits < 0) || (digits > maxRoundingDigits))
+ throw new ArgumentOutOfRangeException(nameof(digits), SR.ArgumentOutOfRange_RoundingDigits);
+ Contract.EndContractBlock();
+ return InternalRound(value, digits, MidpointRounding.ToEven);
+ }
+
+ public static double Round(double value, MidpointRounding mode)
+ {
+ return Round(value, 0, mode);
+ }
+
+ public static double Round(double value, int digits, MidpointRounding mode)
+ {
+ if ((digits < 0) || (digits > maxRoundingDigits))
+ throw new ArgumentOutOfRangeException(nameof(digits), SR.ArgumentOutOfRange_RoundingDigits);
+ if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero)
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidEnumValue, mode, nameof(MidpointRounding)), nameof(mode));
+ }
+ Contract.EndContractBlock();
+ return InternalRound(value, digits, mode);
+ }
+
+ public static Decimal Round(Decimal d)
+ {
+ return Decimal.Round(d, 0);
+ }
+
+ public static Decimal Round(Decimal d, int decimals)
+ {
+ return Decimal.Round(d, decimals);
+ }
+
+ public static Decimal Round(Decimal d, MidpointRounding mode)
+ {
+ return Decimal.Round(d, 0, mode);
+ }
+
+ public static Decimal Round(Decimal d, int decimals, MidpointRounding mode)
+ {
+ return Decimal.Round(d, decimals, mode);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static unsafe extern double SplitFractionDouble(double* value);
+
+ public static Decimal Truncate(Decimal d)
+ {
+ return Decimal.Truncate(d);
+ }
+
+ public static double Truncate(double d)
+ {
+ return InternalTruncate(d);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Sqrt(double d);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Log(double d);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Log10(double d);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Exp(double d);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern double Pow(double x, double y);
+
+ public static double IEEERemainder(double x, double y)
+ {
+ if (Double.IsNaN(x))
+ {
+ return x; // IEEE 754-2008: NaN payload must be preserved
+ }
+ if (Double.IsNaN(y))
+ {
+ return y; // IEEE 754-2008: NaN payload must be preserved
+ }
+
+ double regularMod = x % y;
+ if (Double.IsNaN(regularMod))
+ {
+ return Double.NaN;
+ }
+ if (regularMod == 0)
+ {
+ if (Double.IsNegative(x))
+ {
+ return Double.NegativeZero;
+ }
+ }
+ double alternativeResult;
+ alternativeResult = regularMod - (Math.Abs(y) * Math.Sign(x));
+ if (Math.Abs(alternativeResult) == Math.Abs(regularMod))
+ {
+ double divisionResult = x / y;
+ double roundedResult = Math.Round(divisionResult);
+ if (Math.Abs(roundedResult) > Math.Abs(divisionResult))
+ {
+ return alternativeResult;
+ }
+ else
+ {
+ return regularMod;
+ }
+ }
+ if (Math.Abs(alternativeResult) < Math.Abs(regularMod))
+ {
+ return alternativeResult;
+ }
+ else
+ {
+ return regularMod;
+ }
+ }
+
+ /*================================Abs=========================================
+ **Returns the absolute value of it's argument.
+ ============================================================================*/
+ [CLSCompliant(false)]
+ public static sbyte Abs(sbyte value)
+ {
+ if (value >= 0)
+ return value;
+ else
+ return AbsHelper(value);
+ }
+
+ private static sbyte AbsHelper(sbyte value)
+ {
+ Contract.Requires(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)");
+ if (value == SByte.MinValue)
+ throw new OverflowException(SR.Overflow_NegateTwosCompNum);
+ Contract.EndContractBlock();
+ return ((sbyte)(-value));
+ }
+
+ public static short Abs(short value)
+ {
+ if (value >= 0)
+ return value;
+ else
+ return AbsHelper(value);
+ }
+
+ private static short AbsHelper(short value)
+ {
+ Contract.Requires(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)");
+ if (value == Int16.MinValue)
+ throw new OverflowException(SR.Overflow_NegateTwosCompNum);
+ Contract.EndContractBlock();
+ return (short)-value;
+ }
+
+ public static int Abs(int value)
+ {
+ if (value >= 0)
+ return value;
+ else
+ return AbsHelper(value);
+ }
+
+ private static int AbsHelper(int value)
+ {
+ Contract.Requires(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)");
+ if (value == Int32.MinValue)
+ throw new OverflowException(SR.Overflow_NegateTwosCompNum);
+ Contract.EndContractBlock();
+ return -value;
+ }
+
+ public static long Abs(long value)
+ {
+ if (value >= 0)
+ return value;
+ else
+ return AbsHelper(value);
+ }
+
+ private static long AbsHelper(long value)
+ {
+ Contract.Requires(value < 0, "AbsHelper should only be called for negative values! (workaround for JIT inlining)");
+ if (value == Int64.MinValue)
+ throw new OverflowException(SR.Overflow_NegateTwosCompNum);
+ Contract.EndContractBlock();
+ return -value;
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ extern public static float Abs(float value);
// This is special code to handle NaN (We need to make sure NaN's aren't
// negated). In CSharp, the else clause here should always be taken if
// value is NaN, since the normal case is taken if and only if value < 0.
@@ -272,9 +309,9 @@ namespace System {
// The bge command branches for comparisons with the unordered NaN. So
// it runs the else case, which returns +value instead of negating it.
// return (value < 0) ? -value : value;
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- extern public static double Abs(double value);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ extern public static double Abs(double value);
// This is special code to handle NaN (We need to make sure NaN's aren't
// negated). In CSharp, the else clause here should always be taken if
// value is NaN, since the normal case is taken if and only if value < 0.
@@ -284,152 +321,174 @@ namespace System {
// it runs the else case, which returns +value instead of negating it.
// return (value < 0) ? -value : value;
- public static Decimal Abs(Decimal value)
- {
- return Decimal.Abs(value);
- }
-
- /*================================MAX=========================================
- **Returns the larger of val1 and val2
- ============================================================================*/
- [CLSCompliant(false)]
- [System.Runtime.Versioning.NonVersionable]
- public static sbyte Max(sbyte val1, sbyte val2) {
- return (val1>=val2)?val1:val2;
- }
-
- [System.Runtime.Versioning.NonVersionable]
- public static byte Max(byte val1, byte val2) {
- return (val1>=val2)?val1:val2;
- }
-
- [System.Runtime.Versioning.NonVersionable]
- public static short Max(short val1, short val2) {
- return (val1>=val2)?val1:val2;
- }
-
- [CLSCompliant(false)]
- [System.Runtime.Versioning.NonVersionable]
- public static ushort Max(ushort val1, ushort val2) {
- return (val1>=val2)?val1:val2;
- }
-
- [System.Runtime.Versioning.NonVersionable]
- public static int Max(int val1, int val2) {
- return (val1>=val2)?val1:val2;
- }
-
- [CLSCompliant(false)]
- [System.Runtime.Versioning.NonVersionable]
- public static uint Max(uint val1, uint val2) {
- return (val1>=val2)?val1:val2;
- }
-
- [System.Runtime.Versioning.NonVersionable]
- public static long Max(long val1, long val2) {
- return (val1>=val2)?val1:val2;
- }
-
- [CLSCompliant(false)]
- [System.Runtime.Versioning.NonVersionable]
- public static ulong Max(ulong val1, ulong val2) {
- return (val1>=val2)?val1:val2;
- }
-
- public static float Max(float val1, float val2) {
- if (val1 > val2)
- return val1;
-
- if (Single.IsNaN(val1))
- return val1;
-
- return val2;
- }
-
- public static double Max(double val1, double val2) {
- if (val1 > val2)
- return val1;
-
- if (Double.IsNaN(val1))
- return val1;
-
- return val2;
- }
-
- public static Decimal Max(Decimal val1, Decimal val2) {
- return Decimal.Max(val1,val2);
- }
-
- /*================================MIN=========================================
- **Returns the smaller of val1 and val2.
- ============================================================================*/
- [CLSCompliant(false)]
- [System.Runtime.Versioning.NonVersionable]
- public static sbyte Min(sbyte val1, sbyte val2) {
- return (val1<=val2)?val1:val2;
- }
-
- [System.Runtime.Versioning.NonVersionable]
- public static byte Min(byte val1, byte val2) {
- return (val1<=val2)?val1:val2;
- }
-
- [System.Runtime.Versioning.NonVersionable]
- public static short Min(short val1, short val2) {
- return (val1<=val2)?val1:val2;
- }
-
- [CLSCompliant(false)]
- [System.Runtime.Versioning.NonVersionable]
- public static ushort Min(ushort val1, ushort val2) {
- return (val1<=val2)?val1:val2;
- }
-
- [System.Runtime.Versioning.NonVersionable]
- public static int Min(int val1, int val2) {
- return (val1<=val2)?val1:val2;
- }
-
- [CLSCompliant(false)]
- [System.Runtime.Versioning.NonVersionable]
- public static uint Min(uint val1, uint val2) {
- return (val1<=val2)?val1:val2;
- }
-
- [System.Runtime.Versioning.NonVersionable]
- public static long Min(long val1, long val2) {
- return (val1<=val2)?val1:val2;
- }
-
- [CLSCompliant(false)]
- [System.Runtime.Versioning.NonVersionable]
- public static ulong Min(ulong val1, ulong val2) {
- return (val1<=val2)?val1:val2;
- }
-
- public static float Min(float val1, float val2) {
- if (val1 < val2)
- return val1;
-
- if (Single.IsNaN(val1))
- return val1;
-
- return val2;
- }
-
- public static double Min(double val1, double val2) {
- if (val1 < val2)
- return val1;
-
- if (Double.IsNaN(val1))
- return val1;
-
- return val2;
- }
-
- public static Decimal Min(Decimal val1, Decimal val2) {
- return Decimal.Min(val1,val2);
- }
+ public static Decimal Abs(Decimal value)
+ {
+ return Decimal.Abs(value);
+ }
+
+ /*================================MAX=========================================
+ **Returns the larger of val1 and val2
+ ============================================================================*/
+ [CLSCompliant(false)]
+ [System.Runtime.Versioning.NonVersionable]
+ public static sbyte Max(sbyte val1, sbyte val2)
+ {
+ return (val1 >= val2) ? val1 : val2;
+ }
+
+ [System.Runtime.Versioning.NonVersionable]
+ public static byte Max(byte val1, byte val2)
+ {
+ return (val1 >= val2) ? val1 : val2;
+ }
+
+ [System.Runtime.Versioning.NonVersionable]
+ public static short Max(short val1, short val2)
+ {
+ return (val1 >= val2) ? val1 : val2;
+ }
+
+ [CLSCompliant(false)]
+ [System.Runtime.Versioning.NonVersionable]
+ public static ushort Max(ushort val1, ushort val2)
+ {
+ return (val1 >= val2) ? val1 : val2;
+ }
+
+ [System.Runtime.Versioning.NonVersionable]
+ public static int Max(int val1, int val2)
+ {
+ return (val1 >= val2) ? val1 : val2;
+ }
+
+ [CLSCompliant(false)]
+ [System.Runtime.Versioning.NonVersionable]
+ public static uint Max(uint val1, uint val2)
+ {
+ return (val1 >= val2) ? val1 : val2;
+ }
+
+ [System.Runtime.Versioning.NonVersionable]
+ public static long Max(long val1, long val2)
+ {
+ return (val1 >= val2) ? val1 : val2;
+ }
+
+ [CLSCompliant(false)]
+ [System.Runtime.Versioning.NonVersionable]
+ public static ulong Max(ulong val1, ulong val2)
+ {
+ return (val1 >= val2) ? val1 : val2;
+ }
+
+ public static float Max(float val1, float val2)
+ {
+ if (val1 > val2)
+ return val1;
+
+ if (Single.IsNaN(val1))
+ return val1;
+
+ return val2;
+ }
+
+ public static double Max(double val1, double val2)
+ {
+ if (val1 > val2)
+ return val1;
+
+ if (Double.IsNaN(val1))
+ return val1;
+
+ return val2;
+ }
+
+ public static Decimal Max(Decimal val1, Decimal val2)
+ {
+ return Decimal.Max(val1, val2);
+ }
+
+ /*================================MIN=========================================
+ **Returns the smaller of val1 and val2.
+ ============================================================================*/
+ [CLSCompliant(false)]
+ [System.Runtime.Versioning.NonVersionable]
+ public static sbyte Min(sbyte val1, sbyte val2)
+ {
+ return (val1 <= val2) ? val1 : val2;
+ }
+
+ [System.Runtime.Versioning.NonVersionable]
+ public static byte Min(byte val1, byte val2)
+ {
+ return (val1 <= val2) ? val1 : val2;
+ }
+
+ [System.Runtime.Versioning.NonVersionable]
+ public static short Min(short val1, short val2)
+ {
+ return (val1 <= val2) ? val1 : val2;
+ }
+
+ [CLSCompliant(false)]
+ [System.Runtime.Versioning.NonVersionable]
+ public static ushort Min(ushort val1, ushort val2)
+ {
+ return (val1 <= val2) ? val1 : val2;
+ }
+
+ [System.Runtime.Versioning.NonVersionable]
+ public static int Min(int val1, int val2)
+ {
+ return (val1 <= val2) ? val1 : val2;
+ }
+
+ [CLSCompliant(false)]
+ [System.Runtime.Versioning.NonVersionable]
+ public static uint Min(uint val1, uint val2)
+ {
+ return (val1 <= val2) ? val1 : val2;
+ }
+
+ [System.Runtime.Versioning.NonVersionable]
+ public static long Min(long val1, long val2)
+ {
+ return (val1 <= val2) ? val1 : val2;
+ }
+
+ [CLSCompliant(false)]
+ [System.Runtime.Versioning.NonVersionable]
+ public static ulong Min(ulong val1, ulong val2)
+ {
+ return (val1 <= val2) ? val1 : val2;
+ }
+
+ public static float Min(float val1, float val2)
+ {
+ if (val1 < val2)
+ return val1;
+
+ if (Single.IsNaN(val1))
+ return val1;
+
+ return val2;
+ }
+
+ public static double Min(double val1, double val2)
+ {
+ if (val1 < val2)
+ return val1;
+
+ if (Double.IsNaN(val1))
+ return val1;
+
+ return val2;
+ }
+
+ public static Decimal Min(Decimal val1, Decimal val2)
+ {
+ return Decimal.Min(val1, val2);
+ }
/*=====================================Clamp====================================
**
@@ -572,29 +631,32 @@ namespace System {
private static void ThrowMinMaxException<T>(T min, T max)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_MinMaxValue", min, max));
- }
-
- /*=====================================Log======================================
- **
- ==============================================================================*/
- public static double Log(double a, double newBase) {
- if (Double.IsNaN(a)) {
- return a; // IEEE 754-2008: NaN payload must be preserved
- }
- if (Double.IsNaN(newBase)) {
- return newBase; // IEEE 754-2008: NaN payload must be preserved
- }
-
- if (newBase == 1)
- return Double.NaN;
- if (a != 1 && (newBase == 0 || Double.IsPositiveInfinity(newBase)))
- return Double.NaN;
-
- return (Log(a)/Log(newBase));
- }
-
-
+ throw new ArgumentException(SR.Format(SR.Argument_MinMaxValue, min, max));
+ }
+
+ /*=====================================Log======================================
+ **
+ ==============================================================================*/
+ public static double Log(double a, double newBase)
+ {
+ if (Double.IsNaN(a))
+ {
+ return a; // IEEE 754-2008: NaN payload must be preserved
+ }
+ if (Double.IsNaN(newBase))
+ {
+ return newBase; // IEEE 754-2008: NaN payload must be preserved
+ }
+
+ if (newBase == 1)
+ return Double.NaN;
+ if (a != 1 && (newBase == 0 || Double.IsPositiveInfinity(newBase)))
+ return Double.NaN;
+
+ return (Log(a) / Log(newBase));
+ }
+
+
// Sign function for VB. Returns -1, 0, or 1 if the sign of the number
// is negative, 0, or positive. Throws for floating point NaN's.
[CLSCompliant(false)]
@@ -642,8 +704,8 @@ namespace System {
else
return 0;
}
-
- public static int Sign (float value)
+
+ public static int Sign(float value)
{
if (value < 0)
return -1;
@@ -651,7 +713,7 @@ namespace System {
return 1;
else if (value == 0)
return 0;
- throw new ArithmeticException(Environment.GetResourceString("Arithmetic_NaN"));
+ throw new ArithmeticException(SR.Arithmetic_NaN);
}
public static int Sign(double value)
@@ -662,7 +724,7 @@ namespace System {
return 1;
else if (value == 0)
return 0;
- throw new ArithmeticException(Environment.GetResourceString("Arithmetic_NaN"));
+ throw new ArithmeticException(SR.Arithmetic_NaN);
}
public static int Sign(Decimal value)
@@ -675,11 +737,13 @@ namespace System {
return 0;
}
- public static long BigMul(int a, int b) {
+ public static long BigMul(int a, int b)
+ {
return ((long)a) * b;
}
- public static int DivRem(int a, int b, out int result) {
+ public static int DivRem(int a, int b, out int result)
+ {
// TODO https://github.com/dotnet/coreclr/issues/3439:
// Restore to using % and / when the JIT is able to eliminate one of the idivs.
// In the meantime, a * and - is measurably faster than an extra /.
@@ -688,7 +752,8 @@ namespace System {
return div;
}
- public static long DivRem(long a, long b, out long result) {
+ public static long DivRem(long a, long b, out long result)
+ {
// TODO https://github.com/dotnet/coreclr/issues/3439:
// Restore to using % and / when the JIT is able to eliminate one of the idivs.
// In the meantime, a * and - is measurably faster than an extra /.
diff --git a/src/mscorlib/src/System/MathF.cs b/src/mscorlib/src/System/MathF.cs
index 545774cc32..60669a4561 100644
--- a/src/mscorlib/src/System/MathF.cs
+++ b/src/mscorlib/src/System/MathF.cs
@@ -7,16 +7,18 @@
** Purpose: Some single-precision floating-point math operations
**
===========================================================*/
-namespace System {
- //This class contains only static members and doesn't require serialization.
- using System;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.Versioning;
- using System.Diagnostics.Contracts;
+//This class contains only static members and doesn't require serialization.
+using System;
+using System.Runtime;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.Versioning;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
public static class MathF
{
private static float singleRoundLimit = 1e8f;
@@ -77,7 +79,7 @@ namespace System {
if (float.IsNaN(regularMod))
{
- return float.NaN;
+ return float.NaN;
}
if ((regularMod == 0) && float.IsNegative(x))
@@ -157,7 +159,7 @@ namespace System {
{
if ((digits < 0) || (digits > maxRoundingDigits))
{
- throw new ArgumentOutOfRangeException(nameof(digits), Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
+ throw new ArgumentOutOfRangeException(nameof(digits), SR.ArgumentOutOfRange_RoundingDigits);
}
Contract.EndContractBlock();
@@ -168,12 +170,12 @@ namespace System {
{
if ((digits < 0) || (digits > maxRoundingDigits))
{
- throw new ArgumentOutOfRangeException(nameof(digits), Environment.GetResourceString("ArgumentOutOfRange_RoundingDigits"));
+ throw new ArgumentOutOfRangeException(nameof(digits), SR.ArgumentOutOfRange_RoundingDigits);
}
-
+
if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnumx", mode, nameof(MidpointRounding)), nameof(mode));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidEnum, mode, nameof(MidpointRounding)), nameof(mode));
}
Contract.EndContractBlock();
@@ -184,10 +186,10 @@ namespace System {
{
if (mode < MidpointRounding.ToEven || mode > MidpointRounding.AwayFromZero)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnumx", mode, nameof(MidpointRounding)), nameof(mode));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidEnum, mode, nameof(MidpointRounding)), nameof(mode));
}
Contract.EndContractBlock();
-
+
return InternalRound(x, 0, mode);
}
@@ -215,13 +217,13 @@ namespace System {
if (Abs(x) < singleRoundLimit)
{
var power10 = roundPower10Single[digits];
-
+
x *= power10;
-
+
if (mode == MidpointRounding.AwayFromZero)
{
var fraction = SplitFractionSingle(&x);
-
+
if (Abs(fraction) >= 0.5f)
{
x += Sign(fraction);
diff --git a/src/mscorlib/src/System/MissingFieldException.cs b/src/mscorlib/src/System/MissingFieldException.cs
index 660e39cb47..5668f9e9b3 100644
--- a/src/mscorlib/src/System/MissingFieldException.cs
+++ b/src/mscorlib/src/System/MissingFieldException.cs
@@ -9,53 +9,62 @@
**
=============================================================================*/
-namespace System {
-
- using System;
- using System.Runtime.Remoting;
- using System.Runtime.Serialization;
- using System.Runtime.CompilerServices;
- using System.Globalization;
+
+using System;
+using System.Runtime.Remoting;
+using System.Runtime.Serialization;
+using System.Runtime.CompilerServices;
+using System.Globalization;
+
+namespace System
+{
[Serializable]
- public class MissingFieldException : MissingMemberException, ISerializable {
- public MissingFieldException()
- : base(Environment.GetResourceString("Arg_MissingFieldException")) {
- SetErrorCode(__HResults.COR_E_MISSINGFIELD);
+ public class MissingFieldException : MissingMemberException, ISerializable
+ {
+ public MissingFieldException()
+ : base(SR.Arg_MissingFieldException)
+ {
+ HResult = __HResults.COR_E_MISSINGFIELD;
}
-
- public MissingFieldException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_MISSINGFIELD);
+
+ public MissingFieldException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_MISSINGFIELD;
}
-
- public MissingFieldException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_MISSINGFIELD);
+
+ public MissingFieldException(String message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_MISSINGFIELD;
}
- protected MissingFieldException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ protected MissingFieldException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
}
-
+
public override String Message
{
- get {
- if (ClassName == null) {
+ get
+ {
+ if (ClassName == null)
+ {
return base.Message;
- } else {
+ }
+ else
+ {
// do any desired fixups to classname here.
- return Environment.GetResourceString("MissingField_Name",
- (Signature != null ? FormatSignature(Signature) + " " : "") +
- ClassName + "." + MemberName);
+ return SR.Format(SR.MissingField_Name, (Signature != null ? FormatSignature(Signature) + " " : "") + ClassName + "." + MemberName);
}
}
}
-
+
public MissingFieldException(String className, String fieldName)
{
- ClassName = className;
- MemberName = fieldName;
+ ClassName = className;
+ MemberName = fieldName;
}
-
+
// If ClassName != null, Message will construct on the fly using it
// and the other variables. This allows customization of the
// format depending on the language environment.
diff --git a/src/mscorlib/src/System/MissingMemberException.cs b/src/mscorlib/src/System/MissingMemberException.cs
index bb9be8827a..51150e113c 100644
--- a/src/mscorlib/src/System/MissingMemberException.cs
+++ b/src/mscorlib/src/System/MissingMemberException.cs
@@ -11,65 +11,75 @@
**
=============================================================================*/
-namespace System {
-
- using System;
- using System.Runtime.Remoting;
- using System.Runtime.Serialization;
- using System.Runtime.CompilerServices;
- using System.Globalization;
- using System.Runtime.Versioning;
- using System.Diagnostics.Contracts;
-
+
+using System;
+using System.Runtime.Remoting;
+using System.Runtime.Serialization;
+using System.Runtime.CompilerServices;
+using System.Globalization;
+using System.Runtime.Versioning;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
[Serializable]
- public class MissingMemberException : MemberAccessException, ISerializable {
- public MissingMemberException()
- : base(Environment.GetResourceString("Arg_MissingMemberException")) {
- SetErrorCode(__HResults.COR_E_MISSINGMEMBER);
+ public class MissingMemberException : MemberAccessException, ISerializable
+ {
+ public MissingMemberException()
+ : base(SR.Arg_MissingMemberException)
+ {
+ HResult = __HResults.COR_E_MISSINGMEMBER;
}
-
- public MissingMemberException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_MISSINGMEMBER);
+
+ public MissingMemberException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_MISSINGMEMBER;
}
-
- public MissingMemberException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_MISSINGMEMBER);
+
+ public MissingMemberException(String message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_MISSINGMEMBER;
}
- protected MissingMemberException(SerializationInfo info, StreamingContext context) : base (info, context) {
+ protected MissingMemberException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
ClassName = (String)info.GetString("MMClassName");
MemberName = (String)info.GetString("MMMemberName");
Signature = (byte[])info.GetValue("MMSignature", typeof(byte[]));
}
-
+
public override String Message
{
- get {
- if (ClassName == null) {
+ get
+ {
+ if (ClassName == null)
+ {
return base.Message;
- } else {
+ }
+ else
+ {
// do any desired fixups to classname here.
- return Environment.GetResourceString("MissingMember_Name",
- ClassName + "." + MemberName +
- (Signature != null ? " " + FormatSignature(Signature) : ""));
+ return SR.Format(SR.MissingMember_Name, ClassName + "." + MemberName + (Signature != null ? " " + FormatSignature(Signature) : ""));
}
}
}
-
+
// Called to format signature
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern String FormatSignature(byte [] signature);
-
+ internal static extern String FormatSignature(byte[] signature);
+
public MissingMemberException(String className, String memberName)
{
- ClassName = className;
- MemberName = memberName;
+ ClassName = className;
+ MemberName = memberName;
}
-
- public override void GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
+
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
@@ -78,13 +88,13 @@ namespace System {
info.AddValue("MMMemberName", MemberName, typeof(String));
info.AddValue("MMSignature", Signature, typeof(byte[]));
}
-
-
+
+
// If ClassName != null, GetMessage will construct on the fly using it
// and the other variables. This allows customization of the
// format depending on the language environment.
- protected String ClassName;
- protected String MemberName;
- protected byte[] Signature;
+ protected String ClassName;
+ protected String MemberName;
+ protected byte[] Signature;
}
}
diff --git a/src/mscorlib/src/System/MissingMethodException.cs b/src/mscorlib/src/System/MissingMethodException.cs
deleted file mode 100644
index 426711f953..0000000000
--- a/src/mscorlib/src/System/MissingMethodException.cs
+++ /dev/null
@@ -1,65 +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.
-
-/*=============================================================================
-**
-**
-**
-** Purpose: The exception class for class loading failures.
-**
-**
-=============================================================================*/
-
-namespace System {
-
- using System;
- using System.Runtime.Remoting;
- using System.Runtime.Serialization;
- using System.Runtime.CompilerServices;
- using System.Globalization;
- [Serializable]
- public class MissingMethodException : MissingMemberException, ISerializable {
- public MissingMethodException()
- : base(Environment.GetResourceString("Arg_MissingMethodException")) {
- SetErrorCode(__HResults.COR_E_MISSINGMETHOD);
- }
-
- public MissingMethodException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_MISSINGMETHOD);
- }
-
- public MissingMethodException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_MISSINGMETHOD);
- }
-
- protected MissingMethodException(SerializationInfo info, StreamingContext context) : base(info, context) {
- }
-
- public override String Message
- {
- get {
- if (ClassName == null) {
- return base.Message;
- } else {
- // do any desired fixups to classname here.
- return Environment.GetResourceString("MissingMethod_Name",
- ClassName + "." + MemberName +
- (Signature != null ? " " + FormatSignature(Signature) : ""));
- }
- }
- }
-
- public MissingMethodException(String className, String methodName)
- {
- ClassName = className;
- MemberName = methodName;
- }
-
- // If ClassName != null, Message will construct on the fly using it
- // and the other variables. This allows customization of the
- // format depending on the language environment.
- }
-}
diff --git a/src/mscorlib/src/System/MulticastDelegate.cs b/src/mscorlib/src/System/MulticastDelegate.cs
index aa3271ceab..440c9a60bc 100644
--- a/src/mscorlib/src/System/MulticastDelegate.cs
+++ b/src/mscorlib/src/System/MulticastDelegate.cs
@@ -2,17 +2,17 @@
// 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 System.Runtime;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Reflection.Emit;
+
namespace System
{
- using System;
- using System.Reflection;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.Runtime.Serialization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Reflection.Emit;
-
[Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public abstract class MulticastDelegate : Delegate
@@ -21,8 +21,8 @@ namespace System
// 1. Multicast delegate
// 2. Secure/Wrapper delegate
// 3. Inner delegate of secure delegate where the secure delegate security context is a collectible method
- private Object _invocationList;
- private IntPtr _invocationCount;
+ private Object _invocationList;
+ private IntPtr _invocationCount;
// This constructor is called from the class generated by the
// compiler generated code (This must match the constructor
@@ -30,11 +30,11 @@ namespace System
protected MulticastDelegate(Object target, String method) : base(target, method)
{
}
-
+
// This constructor is called from a class to generate a
// delegate based upon a static method name and the Type object
// for the class defining the method.
- protected MulticastDelegate(Type target, String method) : base(target, method)
+ protected MulticastDelegate(Type target, String method) : base(target, method)
{
}
@@ -58,25 +58,25 @@ namespace System
// A MethodInfo object can be a RuntimeMethodInfo, a RefEmit method (MethodBuilder, etc), or a DynamicMethod
// One can only create delegates on RuntimeMethodInfo and DynamicMethod.
// If it is not a RuntimeMethodInfo (must be a DynamicMethod) or if it is an unmanaged function pointer, throw
- if ( !(method is RuntimeMethodInfo) || IsUnmanagedFunctionPtr() )
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidDelegateType"));
+ if (!(method is RuntimeMethodInfo) || IsUnmanagedFunctionPtr())
+ throw new SerializationException(SR.Serialization_InvalidDelegateType);
// We can't deal with secure delegates either.
if (!InvocationListLogicallyNull() && !_invocationCount.IsNull() && !_methodPtrAux.IsNull())
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidDelegateType"));
+ throw new SerializationException(SR.Serialization_InvalidDelegateType);
- DelegateSerializationHolder.GetDelegateSerializationInfo(info, this.GetType(), Target, method, targetIndex);
+ DelegateSerializationHolder.GetDelegateSerializationInfo(info, this.GetType(), Target, method, targetIndex);
}
else
{
DelegateSerializationHolder.DelegateEntry nextDe = null;
int invocationCount = (int)_invocationCount;
- for (int i = invocationCount; --i >= 0; )
+ for (int i = invocationCount; --i >= 0;)
{
MulticastDelegate d = (MulticastDelegate)invocationList[i];
MethodInfo method = d.Method;
// If it is not a RuntimeMethodInfo (must be a DynamicMethod) or if it is an unmanaged function pointer, skip
- if ( !(method is RuntimeMethodInfo) || IsUnmanagedFunctionPtr() )
+ if (!(method is RuntimeMethodInfo) || IsUnmanagedFunctionPtr())
continue;
// We can't deal with secure delegates either.
@@ -86,12 +86,12 @@ namespace System
DelegateSerializationHolder.DelegateEntry de = DelegateSerializationHolder.GetDelegateSerializationInfo(info, d.GetType(), d.Target, method, targetIndex++);
if (nextDe != null)
nextDe.Entry = de;
-
+
nextDe = de;
}
// if nothing was serialized it is a delegate over a DynamicMethod, so just throw
- if (nextDe == null)
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidDelegateType"));
+ if (nextDe == null)
+ throw new SerializationException(SR.Serialization_InvalidDelegateType);
}
}
@@ -105,14 +105,14 @@ namespace System
return true;
if (!InternalEqualTypes(this, obj))
return false;
-
+
// Since this is a MulticastDelegate and we know
// the types are the same, obj should also be a
// MulticastDelegate
Debug.Assert(obj is MulticastDelegate, "Shouldn't have failed here since we already checked the types are the same!");
var d = JitHelpers.UnsafeCast<MulticastDelegate>(obj);
- if (_invocationCount != (IntPtr)0)
+ if (_invocationCount != (IntPtr)0)
{
// there are 4 kind of delegate kinds that fall into this bucket
// 1- Multicast (_invocationList is Object[])
@@ -134,17 +134,17 @@ namespace System
if ((d._invocationList as Delegate) != null)
// this is a secure/wrapper delegate so we need to unwrap and check the inner one
return Equals(d._invocationList);
-
+
return base.Equals(obj);
}
else
{
- if ((_invocationList as Delegate) != null)
+ if ((_invocationList as Delegate) != null)
{
// this is a secure/wrapper delegate so we need to unwrap and check the inner one
- return _invocationList.Equals(obj);
+ return _invocationList.Equals(obj);
}
- else
+ else
{
Debug.Assert((_invocationList as Object[]) != null, "empty invocation list on multicast delegate");
return InvocationListEquals(d);
@@ -159,11 +159,11 @@ namespace System
// and call the base.Equals()
if (!InvocationListLogicallyNull())
{
- if (!_invocationList.Equals(d._invocationList))
+ if (!_invocationList.Equals(d._invocationList))
return false;
return base.Equals(d);
}
-
+
// now we know 'this' is not a special one, so we can work out what the other is
if ((d._invocationList as Delegate) != null)
// this is a secure/wrapper delegate so we need to unwrap and check the inner one
@@ -173,7 +173,7 @@ namespace System
return base.Equals(d);
}
}
-
+
// Recursive function which will check for equality of the invocation list.
private bool InvocationListEquals(MulticastDelegate d)
{
@@ -181,7 +181,7 @@ namespace System
Object[] invocationList = _invocationList as Object[];
if (d._invocationCount != _invocationCount)
return false;
-
+
int invocationCount = (int)_invocationCount;
for (int i = 0; i < invocationCount; i++)
{
@@ -197,16 +197,16 @@ namespace System
{
if (a[index] == null && System.Threading.Interlocked.CompareExchange<Object>(ref a[index], o, null) == null)
return true;
-
+
// The slot may be already set because we have added and removed the same method before.
// Optimize this case, because it's cheaper than copying the array.
if (a[index] != null)
{
- MulticastDelegate d = (MulticastDelegate)o;
+ MulticastDelegate d = (MulticastDelegate)o;
MulticastDelegate dd = (MulticastDelegate)a[index];
-
- if (dd._methodPtr == d._methodPtr &&
- dd._target == d._target &&
+
+ if (dd._methodPtr == d._methodPtr &&
+ dd._target == d._target &&
dd._methodPtrAux == d._methodPtrAux)
{
return true;
@@ -224,12 +224,12 @@ namespace System
// copy _methodPtr and _methodPtrAux fields rather than calling into the EE to get them
if (thisIsMultiCastAlready)
{
- result._methodPtr = this._methodPtr;
+ result._methodPtr = this._methodPtr;
result._methodPtrAux = this._methodPtrAux;
}
else
{
- result._methodPtr = GetMulticastInvoke();
+ result._methodPtr = GetMulticastInvoke();
result._methodPtrAux = GetInvokeMethod();
}
result._target = result;
@@ -244,17 +244,16 @@ namespace System
return NewMulticastDelegate(invocationList, invocationCount, false);
}
- internal void StoreDynamicMethod(MethodInfo dynamicMethod)
+ internal void StoreDynamicMethod(MethodInfo dynamicMethod)
{
- if (_invocationCount != (IntPtr)0)
+ if (_invocationCount != (IntPtr)0)
{
Debug.Assert(!IsUnmanagedFunctionPtr(), "dynamic method and unmanaged fntptr delegate combined");
// must be a secure/wrapper one, unwrap and save
MulticastDelegate d = (MulticastDelegate)_invocationList;
d._methodBase = dynamicMethod;
-
}
- else
+ else
_methodBase = dynamicMethod;
}
@@ -267,15 +266,15 @@ namespace System
// Verify that the types are the same...
if (!InternalEqualTypes(this, follow))
- throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTypeMis"));
+ throw new ArgumentException(SR.Arg_DlgtTypeMis);
MulticastDelegate dFollow = (MulticastDelegate)follow;
Object[] resultList;
int followCount = 1;
Object[] followList = dFollow._invocationList as Object[];
if (followList != null)
- followCount = (int)dFollow._invocationCount;
-
+ followCount = (int)dFollow._invocationCount;
+
int resultCount;
Object[] invocationList = _invocationList as Object[];
if (invocationList == null)
@@ -325,12 +324,12 @@ namespace System
int allocCount = invocationList.Length;
while (allocCount < resultCount)
allocCount *= 2;
-
+
resultList = new Object[allocCount];
-
+
for (int i = 0; i < invocationCount; i++)
resultList[i] = invocationList[i];
-
+
if (followList == null)
{
resultList[invocationCount] = dFollow;
@@ -344,22 +343,22 @@ namespace System
return NewMulticastDelegate(resultList, resultCount, true);
}
}
-
+
private Object[] DeleteFromInvocationList(Object[] invocationList, int invocationCount, int deleteIndex, int deleteCount)
{
Object[] thisInvocationList = _invocationList as Object[];
int allocCount = thisInvocationList.Length;
- while (allocCount/2 >= invocationCount - deleteCount)
+ while (allocCount / 2 >= invocationCount - deleteCount)
allocCount /= 2;
-
+
Object[] newInvocationList = new Object[allocCount];
-
+
for (int i = 0; i < deleteIndex; i++)
newInvocationList[i] = invocationList[i];
-
+
for (int i = deleteIndex + deleteCount; i < invocationCount; i++)
newInvocationList[i - deleteCount] = invocationList[i];
-
+
return newInvocationList;
}
@@ -384,8 +383,8 @@ namespace System
// the value we need to check for this case
//
MulticastDelegate v = value as MulticastDelegate;
-
- if (v == null)
+
+ if (v == null)
return this;
if (v._invocationList as Object[] == null)
{
@@ -399,19 +398,19 @@ namespace System
else
{
int invocationCount = (int)_invocationCount;
- for (int i = invocationCount; --i >= 0; )
+ for (int i = invocationCount; --i >= 0;)
{
if (value.Equals(invocationList[i]))
{
if (invocationCount == 2)
{
// Special case - only one value left, either at the beginning or the end
- return (Delegate)invocationList[1-i];
+ return (Delegate)invocationList[1 - i];
}
else
{
Object[] list = DeleteFromInvocationList(invocationList, invocationCount, i, 1);
- return NewMulticastDelegate(list, invocationCount-1, true);
+ return NewMulticastDelegate(list, invocationCount - 1, true);
}
}
}
@@ -420,7 +419,8 @@ namespace System
else
{
Object[] invocationList = _invocationList as Object[];
- if (invocationList != null) {
+ if (invocationList != null)
+ {
int invocationCount = (int)_invocationCount;
int vInvocationCount = (int)v._invocationCount;
for (int i = invocationCount - vInvocationCount; i >= 0; i--)
@@ -435,7 +435,7 @@ namespace System
else if (invocationCount - vInvocationCount == 1)
{
// Special case - only one value left, either at the beginning or the end
- return (Delegate)invocationList[i != 0 ? 0 : invocationCount-1];
+ return (Delegate)invocationList[i != 0 ? 0 : invocationCount - 1];
}
else
{
@@ -446,7 +446,7 @@ namespace System
}
}
}
-
+
return this;
}
@@ -467,7 +467,7 @@ namespace System
// Create an array of delegate copies and each
// element into the array
del = new Delegate[(int)_invocationCount];
-
+
for (int i = 0; i < del.Length; i++)
del[i] = (Delegate)invocationList[i];
}
@@ -478,7 +478,7 @@ namespace System
{
if ((Object)d1 == null)
return (Object)d2 == null;
-
+
return d1.Equals(d2);
}
@@ -486,10 +486,10 @@ namespace System
{
if ((Object)d1 == null)
return (Object)d2 != null;
-
+
return !d1.Equals(d2);
}
-
+
public override sealed int GetHashCode()
{
if (IsUnmanagedFunctionPtr())
@@ -505,16 +505,16 @@ namespace System
int hash = 0;
for (int i = 0; i < (int)_invocationCount; i++)
{
- hash = hash*33 + invocationList[i].GetHashCode();
+ hash = hash * 33 + invocationList[i].GetHashCode();
}
-
+
return hash;
}
}
internal override Object GetTarget()
{
- if (_invocationCount != (IntPtr)0)
+ if (_invocationCount != (IntPtr)0)
{
// _invocationCount != 0 we are in one of these cases:
// - Multicast -> return the target of the last delegate in the list
@@ -529,7 +529,7 @@ namespace System
else
{
Object[] invocationList = _invocationList as Object[];
- if (invocationList != null)
+ if (invocationList != null)
{
int invocationCount = (int)_invocationCount;
return ((Delegate)invocationList[invocationCount - 1]).GetTarget();
@@ -537,7 +537,7 @@ namespace System
else
{
Delegate receiver = _invocationList as Delegate;
- if (receiver != null)
+ if (receiver != null)
return receiver.GetTarget();
}
}
@@ -587,18 +587,18 @@ namespace System
// Otherwise, must be an inner delegate of a SecureDelegate of an open virtual method. In that case, call base implementation
return base.GetMethodImpl();
}
-
+
// this should help inlining
[System.Diagnostics.DebuggerNonUserCode]
- private void ThrowNullThisInDelegateToInstance()
+ private void ThrowNullThisInDelegateToInstance()
{
- throw new ArgumentException(Environment.GetResourceString("Arg_DlgtNullInst"));
+ throw new ArgumentException(SR.Arg_DlgtNullInst);
}
[System.Diagnostics.DebuggerNonUserCode]
private void CtorClosed(Object target, IntPtr methodPtr)
{
- if (target == null)
+ if (target == null)
ThrowNullThisInDelegateToInstance();
this._target = target;
this._methodPtr = methodPtr;
@@ -631,35 +631,35 @@ namespace System
{
MulticastDelegate realDelegate = (MulticastDelegate)Delegate.InternalAllocLike(this);
realDelegate.CtorClosed(target, methodPtr);
- this._invocationList = realDelegate;
+ _invocationList = realDelegate;
this._target = this;
this._methodPtr = callThunk;
this._methodPtrAux = creatorMethod;
- this._invocationCount = GetInvokeMethod();
+ _invocationCount = GetInvokeMethod();
}
-
+
[System.Diagnostics.DebuggerNonUserCode]
private void CtorSecureClosedStatic(Object target, IntPtr methodPtr, IntPtr callThunk, IntPtr creatorMethod)
{
MulticastDelegate realDelegate = (MulticastDelegate)Delegate.InternalAllocLike(this);
realDelegate.CtorClosedStatic(target, methodPtr);
- this._invocationList = realDelegate;
+ _invocationList = realDelegate;
this._target = this;
this._methodPtr = callThunk;
this._methodPtrAux = creatorMethod;
- this._invocationCount = GetInvokeMethod();
+ _invocationCount = GetInvokeMethod();
}
-
+
[System.Diagnostics.DebuggerNonUserCode]
private void CtorSecureRTClosed(Object target, IntPtr methodPtr, IntPtr callThunk, IntPtr creatorMethod)
{
MulticastDelegate realDelegate = Delegate.InternalAllocLike(this);
realDelegate.CtorRTClosed(target, methodPtr);
- this._invocationList = realDelegate;
+ _invocationList = realDelegate;
this._target = this;
this._methodPtr = callThunk;
this._methodPtrAux = creatorMethod;
- this._invocationCount = GetInvokeMethod();
+ _invocationCount = GetInvokeMethod();
}
[System.Diagnostics.DebuggerNonUserCode]
@@ -667,11 +667,11 @@ namespace System
{
MulticastDelegate realDelegate = Delegate.InternalAllocLike(this);
realDelegate.CtorOpened(target, methodPtr, shuffleThunk);
- this._invocationList = realDelegate;
+ _invocationList = realDelegate;
this._target = this;
this._methodPtr = callThunk;
this._methodPtrAux = creatorMethod;
- this._invocationCount = GetInvokeMethod();
+ _invocationCount = GetInvokeMethod();
}
[System.Diagnostics.DebuggerNonUserCode]
@@ -687,11 +687,11 @@ namespace System
{
MulticastDelegate realDelegate = Delegate.InternalAllocLike(this);
realDelegate.CtorVirtualDispatch(target, methodPtr, shuffleThunk);
- this._invocationList = realDelegate;
+ _invocationList = realDelegate;
this._target = this;
this._methodPtr = callThunk;
this._methodPtrAux = creatorMethod;
- this._invocationCount = GetInvokeMethod();
+ _invocationCount = GetInvokeMethod();
}
[System.Diagnostics.DebuggerNonUserCode]
diff --git a/src/mscorlib/src/System/NonSerializedAttribute.cs b/src/mscorlib/src/System/NonSerializedAttribute.cs
index 39f186212a..be05e113c6 100644
--- a/src/mscorlib/src/System/NonSerializedAttribute.cs
+++ b/src/mscorlib/src/System/NonSerializedAttribute.cs
@@ -10,23 +10,24 @@
**
**
============================================================*/
-namespace System
-{
- using System.Reflection;
- [AttributeUsage(AttributeTargets.Field, Inherited=false)]
- public sealed class NonSerializedAttribute : Attribute
+using System.Reflection;
+
+namespace System
+{
+ [AttributeUsage(AttributeTargets.Field, Inherited = false)]
+ public sealed class NonSerializedAttribute : Attribute
{
- internal static Attribute GetCustomAttribute(RuntimeFieldInfo field)
- {
+ internal static Attribute GetCustomAttribute(RuntimeFieldInfo field)
+ {
if ((field.Attributes & FieldAttributes.NotSerialized) == 0)
return null;
return new NonSerializedAttribute();
}
- internal static bool IsDefined(RuntimeFieldInfo field)
- {
+ internal static bool IsDefined(RuntimeFieldInfo field)
+ {
return (field.Attributes & FieldAttributes.NotSerialized) != 0;
}
diff --git a/src/mscorlib/src/System/NotFiniteNumberException.cs b/src/mscorlib/src/System/NotFiniteNumberException.cs
deleted file mode 100644
index 68e8f88d81..0000000000
--- a/src/mscorlib/src/System/NotFiniteNumberException.cs
+++ /dev/null
@@ -1,71 +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.Runtime.Serialization;
-
-namespace System
-{
- [Serializable]
- public class NotFiniteNumberException : ArithmeticException
- {
- private double _offendingNumber;
-
- public NotFiniteNumberException()
- : base(SR.Arg_NotFiniteNumberException)
- {
- _offendingNumber = 0;
- HResult = __HResults.COR_E_NOTFINITENUMBER;
- }
-
- public NotFiniteNumberException(double offendingNumber)
- : base()
- {
- _offendingNumber = offendingNumber;
- HResult = __HResults.COR_E_NOTFINITENUMBER;
- }
-
- public NotFiniteNumberException(String message)
- : base(message)
- {
- _offendingNumber = 0;
- HResult = __HResults.COR_E_NOTFINITENUMBER;
- }
-
- public NotFiniteNumberException(String message, double offendingNumber)
- : base(message)
- {
- _offendingNumber = offendingNumber;
- HResult = __HResults.COR_E_NOTFINITENUMBER;
- }
-
- public NotFiniteNumberException(String message, Exception innerException)
- : base(message, innerException)
- {
- HResult = __HResults.COR_E_NOTFINITENUMBER;
- }
-
- public NotFiniteNumberException(String message, double offendingNumber, Exception innerException)
- : base(message, innerException)
- {
- _offendingNumber = offendingNumber;
- HResult = __HResults.COR_E_NOTFINITENUMBER;
- }
-
- protected NotFiniteNumberException(SerializationInfo info, StreamingContext context) : base(info, context)
- {
- _offendingNumber = info.GetInt32("OffendingNumber");
- }
-
- public override void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- base.GetObjectData(info, context);
- info.AddValue("OffendingNumber", _offendingNumber, typeof(Int32));
- }
-
- public double OffendingNumber
- {
- get { return _offendingNumber; }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Nullable.cs b/src/mscorlib/src/System/Nullable.cs
index 5ade2875c5..31a62ecea8 100644
--- a/src/mscorlib/src/System/Nullable.cs
+++ b/src/mscorlib/src/System/Nullable.cs
@@ -3,18 +3,18 @@
// See the LICENSE file in the project root for more information.
- using System;
+using System;
+
+using System.Globalization;
+using System.Reflection;
+using System.Collections.Generic;
+using System.Runtime;
+using System.Runtime.CompilerServices;
+using System.Security;
+using System.Diagnostics.Contracts;
namespace System
{
- using System.Globalization;
- using System.Reflection;
- using System.Collections.Generic;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.Security;
- using System.Diagnostics.Contracts;
-
// Warning, don't put System.Runtime.Serialization.On*Serializ*Attribute
// on this class without first fixing ObjectClone::InvokeVtsCallbacks
// Also, because we have special type system support that says a a boxed Nullable<T>
@@ -25,25 +25,31 @@ namespace System
[System.Runtime.Versioning.NonVersionable] // This only applies to field layout
public struct Nullable<T> where T : struct
{
- private bool hasValue;
+ private bool hasValue;
internal T value;
[System.Runtime.Versioning.NonVersionable]
- public Nullable(T value) {
+ public Nullable(T value)
+ {
this.value = value;
- this.hasValue = true;
- }
+ hasValue = true;
+ }
- public bool HasValue {
+ public bool HasValue
+ {
[System.Runtime.Versioning.NonVersionable]
- get {
+ get
+ {
return hasValue;
- }
- }
+ }
+ }
- public T Value {
- get {
- if (!hasValue) {
+ public T Value
+ {
+ get
+ {
+ if (!hasValue)
+ {
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue);
}
return value;
@@ -51,36 +57,43 @@ namespace System
}
[System.Runtime.Versioning.NonVersionable]
- public T GetValueOrDefault() {
+ public T GetValueOrDefault()
+ {
return value;
}
[System.Runtime.Versioning.NonVersionable]
- public T GetValueOrDefault(T defaultValue) {
+ public T GetValueOrDefault(T defaultValue)
+ {
return hasValue ? value : defaultValue;
}
- public override bool Equals(object other) {
+ public override bool Equals(object other)
+ {
if (!hasValue) return other == null;
if (other == null) return false;
return value.Equals(other);
}
- public override int GetHashCode() {
+ public override int GetHashCode()
+ {
return hasValue ? value.GetHashCode() : 0;
}
- public override string ToString() {
+ public override string ToString()
+ {
return hasValue ? value.ToString() : "";
}
[System.Runtime.Versioning.NonVersionable]
- public static implicit operator Nullable<T>(T value) {
+ public static implicit operator Nullable<T>(T value)
+ {
return new Nullable<T>(value);
}
[System.Runtime.Versioning.NonVersionable]
- public static explicit operator T(Nullable<T> value) {
+ public static explicit operator T(Nullable<T> value)
+ {
return value.Value;
}
@@ -93,48 +106,54 @@ namespace System
// public string ToString(string format)
// public string ToString(IFormatProvider provider)
// public string ToString(string format, IFormatProvider provider)
-
+
// The following newly obsoleted methods were removed:
// string IFormattable.ToString(string format, IFormatProvider provider)
// int IComparable.CompareTo(object other)
// int IComparable<Nullable<T>>.CompareTo(Nullable<T> other)
// bool IEquatable<Nullable<T>>.Equals(Nullable<T> other)
- }
-
+ }
+
public static class Nullable
{
public static int Compare<T>(Nullable<T> n1, Nullable<T> n2) where T : struct
{
- if (n1.HasValue) {
+ if (n1.HasValue)
+ {
if (n2.HasValue) return Comparer<T>.Default.Compare(n1.value, n2.value);
return 1;
}
if (n2.HasValue) return -1;
- return 0;
- }
-
+ return 0;
+ }
+
public static bool Equals<T>(Nullable<T> n1, Nullable<T> n2) where T : struct
{
- if (n1.HasValue) {
+ if (n1.HasValue)
+ {
if (n2.HasValue) return EqualityComparer<T>.Default.Equals(n1.value, n2.value);
return false;
- }
+ }
if (n2.HasValue) return false;
- return true;
- }
+ return true;
+ }
// If the type provided is not a Nullable Type, return null.
// Otherwise, returns the underlying type of the Nullable type
- public static Type GetUnderlyingType(Type nullableType) {
- if((object)nullableType == null) {
+ public static Type GetUnderlyingType(Type nullableType)
+ {
+ if ((object)nullableType == null)
+ {
throw new ArgumentNullException(nameof(nullableType));
}
Contract.EndContractBlock();
Type result = null;
- if( nullableType.IsGenericType && !nullableType.IsGenericTypeDefinition) {
+ if (nullableType.IsGenericType && !nullableType.IsGenericTypeDefinition)
+ {
// instantiated generic type only
Type genericType = nullableType.GetGenericTypeDefinition();
- if( Object.ReferenceEquals(genericType, typeof(Nullable<>))) {
+ if (Object.ReferenceEquals(genericType, typeof(Nullable<>)))
+ {
result = nullableType.GetGenericArguments()[0];
}
}
@@ -151,5 +170,5 @@ namespace System
// public static object ToObject<T>(Nullable<T> value)
// public static object Wrap(object value, Type type)
// public static object Unwrap(object value)
- }
+ }
}
diff --git a/src/mscorlib/src/System/Number.cs b/src/mscorlib/src/System/Number.cs
index 66d05673a6..b30d4e643f 100644
--- a/src/mscorlib/src/System/Number.cs
+++ b/src/mscorlib/src/System/Number.cs
@@ -2,18 +2,19 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System {
-
- using System;
- using System.Globalization;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Security;
- using System.Text;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
+using System;
+using System.Globalization;
+using System.Runtime;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+using System.Security;
+using System.Text;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
// The Number class implements methods for formatting and parsing
// numeric values. To format and parse numeric values, applications should
// use the Format and Parse methods provided by the numeric
@@ -287,9 +288,10 @@ namespace System {
[System.Runtime.CompilerServices.FriendAccessAllowed]
internal class Number
{
- private Number() {
+ private Number()
+ {
}
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern String FormatDecimal(Decimal value, String format, NumberFormatInfo info);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -304,7 +306,7 @@ namespace System {
public static extern String FormatUInt64(ulong value, String format, NumberFormatInfo info);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern String FormatSingle(float value, String format, NumberFormatInfo info);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public unsafe static extern Boolean NumberBufferToDecimal(byte* number, ref Decimal value);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -332,27 +334,29 @@ namespace System {
// structure, except for the digits, and pack those values into the byte buffer
// if called out to managed.
[System.Runtime.CompilerServices.FriendAccessAllowed]
- internal unsafe struct NumberBuffer {
-
+ internal unsafe struct NumberBuffer
+ {
// Enough space for NumberMaxDigit characters plus null and 3 32 bit integers and a pointer
public static readonly Int32 NumberBufferBytes = 12 + ((NumberMaxDigits + 1) * 2) + IntPtr.Size;
- private Byte * baseAddress;
- public Char * digits;
+ private Byte* baseAddress;
+ public Char* digits;
public Int32 precision;
public Int32 scale;
public Boolean sign;
- public NumberBuffer(Byte* stackBuffer) {
- this.baseAddress = stackBuffer;
- this.digits = (((Char*) stackBuffer) + 6);
+ public NumberBuffer(Byte* stackBuffer)
+ {
+ baseAddress = stackBuffer;
+ this.digits = (((Char*)stackBuffer) + 6);
this.precision = 0;
this.scale = 0;
this.sign = false;
}
- public Byte* PackForNative() {
- Int32* baseInteger = (Int32*) baseAddress;
+ public Byte* PackForNative()
+ {
+ Int32* baseInteger = (Int32*)baseAddress;
baseInteger[0] = precision;
baseInteger[1] = scale;
baseInteger[2] = sign ? 1 : 0;
@@ -360,55 +364,67 @@ namespace System {
}
}
- private static Boolean HexNumberToInt32(ref NumberBuffer number, ref Int32 value) {
+ private static Boolean HexNumberToInt32(ref NumberBuffer number, ref Int32 value)
+ {
UInt32 passedValue = 0;
Boolean returnValue = HexNumberToUInt32(ref number, ref passedValue);
value = (Int32)passedValue;
return returnValue;
}
- private static Boolean HexNumberToInt64(ref NumberBuffer number, ref Int64 value) {
+ private static Boolean HexNumberToInt64(ref NumberBuffer number, ref Int64 value)
+ {
UInt64 passedValue = 0;
Boolean returnValue = HexNumberToUInt64(ref number, ref passedValue);
value = (Int64)passedValue;
return returnValue;
}
- private unsafe static Boolean HexNumberToUInt32(ref NumberBuffer number, ref UInt32 value) {
-
+ private unsafe static Boolean HexNumberToUInt32(ref NumberBuffer number, ref UInt32 value)
+ {
Int32 i = number.scale;
- if (i > UInt32Precision || i < number.precision) {
+ if (i > UInt32Precision || i < number.precision)
+ {
return false;
}
Char* p = number.digits;
Debug.Assert(p != null, "");
UInt32 n = 0;
- while (--i >= 0) {
- if (n > ((UInt32)0xFFFFFFFF / 16)) {
+ while (--i >= 0)
+ {
+ if (n > ((UInt32)0xFFFFFFFF / 16))
+ {
return false;
}
n *= 16;
- if (*p != '\0') {
+ if (*p != '\0')
+ {
UInt32 newN = n;
- if (*p != '\0') {
- if (*p >= '0' && *p <= '9') {
+ if (*p != '\0')
+ {
+ if (*p >= '0' && *p <= '9')
+ {
newN += (UInt32)(*p - '0');
}
- else {
- if (*p >= 'A' && *p <= 'F') {
+ else
+ {
+ if (*p >= 'A' && *p <= 'F')
+ {
newN += (UInt32)((*p - 'A') + 10);
}
- else {
+ else
+ {
Debug.Assert(*p >= 'a' && *p <= 'f', "");
newN += (UInt32)((*p - 'a') + 10);
}
}
p++;
}
-
+
// Detect an overflow here...
- if (newN < n) {
+ if (newN < n)
+ {
return false;
}
n = newN;
@@ -418,41 +434,51 @@ namespace System {
return true;
}
- private unsafe static Boolean HexNumberToUInt64(ref NumberBuffer number, ref UInt64 value) {
-
+ private unsafe static Boolean HexNumberToUInt64(ref NumberBuffer number, ref UInt64 value)
+ {
Int32 i = number.scale;
- if (i > UInt64Precision || i < number.precision) {
+ if (i > UInt64Precision || i < number.precision)
+ {
return false;
}
Char* p = number.digits;
Debug.Assert(p != null, "");
-
+
UInt64 n = 0;
- while (--i >= 0) {
- if (n > (0xFFFFFFFFFFFFFFFF / 16)) {
+ while (--i >= 0)
+ {
+ if (n > (0xFFFFFFFFFFFFFFFF / 16))
+ {
return false;
}
n *= 16;
- if (*p != '\0') {
- UInt64 newN = n;
- if (*p != '\0') {
- if (*p >= '0' && *p <= '9') {
+ if (*p != '\0')
+ {
+ UInt64 newN = n;
+ if (*p != '\0')
+ {
+ if (*p >= '0' && *p <= '9')
+ {
newN += (UInt64)(*p - '0');
}
- else {
- if (*p >= 'A' && *p <= 'F') {
+ else
+ {
+ if (*p >= 'A' && *p <= 'F')
+ {
newN += (UInt64)((*p - 'A') + 10);
}
- else {
+ else
+ {
Debug.Assert(*p >= 'a' && *p <= 'f', "");
newN += (UInt64)((*p - 'a') + 10);
}
}
p++;
}
-
+
// Detect an overflow here...
- if (newN < n) {
+ if (newN < n)
+ {
return false;
}
n = newN;
@@ -462,36 +488,45 @@ namespace System {
return true;
}
- private static Boolean IsWhite(char ch) {
+ private static Boolean IsWhite(char ch)
+ {
return (((ch) == 0x20) || ((ch) >= 0x09 && (ch) <= 0x0D));
}
- private unsafe static Boolean NumberToInt32(ref NumberBuffer number, ref Int32 value) {
-
+ private unsafe static Boolean NumberToInt32(ref NumberBuffer number, ref Int32 value)
+ {
Int32 i = number.scale;
- if (i > Int32Precision || i < number.precision) {
+ if (i > Int32Precision || i < number.precision)
+ {
return false;
}
- char * p = number.digits;
+ char* p = number.digits;
Debug.Assert(p != null, "");
Int32 n = 0;
- while (--i >= 0) {
- if ((UInt32)n > (0x7FFFFFFF / 10)) {
+ while (--i >= 0)
+ {
+ if ((UInt32)n > (0x7FFFFFFF / 10))
+ {
return false;
}
n *= 10;
- if (*p != '\0') {
+ if (*p != '\0')
+ {
n += (Int32)(*p++ - '0');
}
}
- if (number.sign) {
+ if (number.sign)
+ {
n = -n;
- if (n > 0) {
+ if (n > 0)
+ {
return false;
}
}
- else {
- if (n < 0) {
+ else
+ {
+ if (n < 0)
+ {
return false;
}
}
@@ -499,32 +534,40 @@ namespace System {
return true;
}
- private unsafe static Boolean NumberToInt64(ref NumberBuffer number, ref Int64 value) {
-
+ private unsafe static Boolean NumberToInt64(ref NumberBuffer number, ref Int64 value)
+ {
Int32 i = number.scale;
- if (i > Int64Precision || i < number.precision) {
+ if (i > Int64Precision || i < number.precision)
+ {
return false;
}
char* p = number.digits;
Debug.Assert(p != null, "");
Int64 n = 0;
- while (--i >= 0) {
- if ((UInt64)n > (0x7FFFFFFFFFFFFFFF / 10)) {
+ while (--i >= 0)
+ {
+ if ((UInt64)n > (0x7FFFFFFFFFFFFFFF / 10))
+ {
return false;
}
n *= 10;
- if (*p != '\0') {
+ if (*p != '\0')
+ {
n += (Int32)(*p++ - '0');
}
}
- if (number.sign) {
+ if (number.sign)
+ {
n = -n;
- if (n > 0) {
+ if (n > 0)
+ {
return false;
}
}
- else {
- if (n < 0) {
+ else
+ {
+ if (n < 0)
+ {
return false;
}
}
@@ -532,24 +575,29 @@ namespace System {
return true;
}
- private unsafe static Boolean NumberToUInt32(ref NumberBuffer number, ref UInt32 value) {
-
+ private unsafe static Boolean NumberToUInt32(ref NumberBuffer number, ref UInt32 value)
+ {
Int32 i = number.scale;
- if (i > UInt32Precision || i < number.precision || number.sign ) {
+ if (i > UInt32Precision || i < number.precision || number.sign)
+ {
return false;
}
char* p = number.digits;
Debug.Assert(p != null, "");
UInt32 n = 0;
- while (--i >= 0) {
- if (n > (0xFFFFFFFF / 10)) {
+ while (--i >= 0)
+ {
+ if (n > (0xFFFFFFFF / 10))
+ {
return false;
}
n *= 10;
- if (*p != '\0') {
+ if (*p != '\0')
+ {
UInt32 newN = n + (UInt32)(*p++ - '0');
// Detect an overflow here...
- if (newN < n) {
+ if (newN < n)
+ {
return false;
}
n = newN;
@@ -559,24 +607,29 @@ namespace System {
return true;
}
- private unsafe static Boolean NumberToUInt64(ref NumberBuffer number, ref UInt64 value) {
-
+ private unsafe static Boolean NumberToUInt64(ref NumberBuffer number, ref UInt64 value)
+ {
Int32 i = number.scale;
- if (i > UInt64Precision || i < number.precision || number.sign) {
+ if (i > UInt64Precision || i < number.precision || number.sign)
+ {
return false;
}
- char * p = number.digits;
+ char* p = number.digits;
Debug.Assert(p != null, "");
UInt64 n = 0;
- while (--i >= 0) {
- if (n > (0xFFFFFFFFFFFFFFFF / 10)) {
+ while (--i >= 0)
+ {
+ if (n > (0xFFFFFFFFFFFFFFFF / 10))
+ {
return false;
}
n *= 10;
- if (*p != '\0') {
+ if (*p != '\0')
+ {
UInt64 newN = n + (UInt64)(*p++ - '0');
// Detect an overflow here...
- if (newN < n) {
+ if (newN < n)
+ {
return false;
}
n = newN;
@@ -586,20 +639,24 @@ namespace System {
return true;
}
- private unsafe static char * MatchChars(char* p, string str) {
- fixed (char* stringPointer = str) {
+ private unsafe static char* MatchChars(char* p, string str)
+ {
+ fixed (char* stringPointer = str)
+ {
return MatchChars(p, stringPointer);
}
}
- private unsafe static char * MatchChars(char* p, char* str) {
+ private unsafe static char* MatchChars(char* p, char* str)
+ {
Debug.Assert(p != null && str != null, "");
- if (*str == '\0') {
+ if (*str == '\0')
+ {
return null;
}
- // We only hurt the failure case
- // This fix is for French or Kazakh cultures. Since a user cannot type 0xA0 as a
- // space character we use 0x20 space character instead to mean the same.
+ // We only hurt the failure case
+ // This fix is for French or Kazakh cultures. Since a user cannot type 0xA0 as a
+ // space character we use 0x20 space character instead to mean the same.
while (*p == *str || (*str == '\u00a0' && *p == '\u0020'))
{
p++;
@@ -609,96 +666,113 @@ namespace System {
return null;
}
- internal unsafe static Decimal ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Decimal ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
Decimal result = 0;
-
+
StringToNumber(value, options, ref number, numfmt, true);
- if (!NumberBufferToDecimal(number.PackForNative(), ref result)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Decimal"));
+ if (!NumberBufferToDecimal(number.PackForNative(), ref result))
+ {
+ throw new OverflowException(SR.Overflow_Decimal);
}
return result;
}
- internal unsafe static Double ParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt) {
- if (value == null) {
+ internal unsafe static Double ParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
Double d = 0;
-
- if (!TryStringToNumber(value, options, ref number, numfmt, false)) {
+
+ if (!TryStringToNumber(value, options, ref number, numfmt, false))
+ {
//If we failed TryStringToNumber, it may be from one of our special strings.
//Check the three with which we're concerned and rethrow if it's not one of
//those strings.
String sTrim = value.Trim();
- if (sTrim.Equals(numfmt.PositiveInfinitySymbol)) {
+ if (sTrim.Equals(numfmt.PositiveInfinitySymbol))
+ {
return Double.PositiveInfinity;
}
- if (sTrim.Equals(numfmt.NegativeInfinitySymbol)) {
+ if (sTrim.Equals(numfmt.NegativeInfinitySymbol))
+ {
return Double.NegativeInfinity;
}
- if (sTrim.Equals(numfmt.NaNSymbol)) {
+ if (sTrim.Equals(numfmt.NaNSymbol))
+ {
return Double.NaN;
}
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ throw new FormatException(SR.Format_InvalidString);
}
- if (!NumberBufferToDouble(number.PackForNative(), ref d)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Double"));
+ if (!NumberBufferToDouble(number.PackForNative(), ref d))
+ {
+ throw new OverflowException(SR.Overflow_Double);
}
return d;
}
- internal unsafe static Int32 ParseInt32(String s, NumberStyles style, NumberFormatInfo info) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Int32 ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
Int32 i = 0;
-
+
StringToNumber(s, style, ref number, info, false);
- if ((style & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToInt32(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToInt32(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_Int32);
}
}
- else {
- if (!NumberToInt32(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Int32"));
+ else
+ {
+ if (!NumberToInt32(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_Int32);
}
}
- return i;
+ return i;
}
- internal unsafe static Int64 ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt) {
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Int64 ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
Int64 i = 0;
StringToNumber(value, options, ref number, numfmt, false);
- if ((options & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToInt64(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Int64"));
+ if ((options & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToInt64(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_Int64);
}
}
- else {
- if (!NumberToInt64(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Int64"));
+ else
+ {
+ if (!NumberToInt64(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_Int64);
}
}
return i;
}
- private unsafe static Boolean ParseNumber(ref char * str, NumberStyles options, ref NumberBuffer number, StringBuilder sb, NumberFormatInfo numfmt, Boolean parseDecimal) {
-
+ private unsafe static Boolean ParseNumber(ref char* str, NumberStyles options, ref NumberBuffer number, StringBuilder sb, NumberFormatInfo numfmt, Boolean parseDecimal)
+ {
const Int32 StateSign = 0x0001;
const Int32 StateParens = 0x0002;
const Int32 StateDigits = 0x0004;
@@ -712,8 +786,9 @@ namespace System {
string groupSep; // group separator from NumberFormatInfo.
string currSymbol = null; // currency symbol from NumberFormatInfo.
- Boolean parsingCurrency = false;
- if ((options & NumberStyles.AllowCurrencySymbol) != 0) {
+ Boolean parsingCurrency = false;
+ if ((options & NumberStyles.AllowCurrencySymbol) != 0)
+ {
currSymbol = numfmt.CurrencySymbol;
// The idea here is to match the currency separators and on failure match the number separators to keep the perf of VB's IsNumeric fast.
@@ -722,7 +797,8 @@ namespace System {
groupSep = numfmt.CurrencyGroupSeparator;
parsingCurrency = true;
}
- else {
+ else
+ {
decSep = numfmt.NumberDecimalSeparator;
groupSep = numfmt.NumberGroupSeparator;
}
@@ -730,69 +806,85 @@ namespace System {
Int32 state = 0;
Boolean bigNumber = (sb != null); // When a StringBuilder is provided then we use it in place of the number.digits char[50]
Int32 maxParseDigits = bigNumber ? Int32.MaxValue : NumberMaxDigits;
-
+
char* p = str;
char ch = *p;
char* next;
- while (true) {
+ while (true)
+ {
// Eat whitespace unless we've found a sign which isn't followed by a currency symbol.
// "-Kr 1231.47" is legal but "- 1231.47" is not.
- if (!IsWhite(ch) || (options & NumberStyles.AllowLeadingWhite) == 0 || ((state & StateSign) != 0 && ((state & StateCurrency) == 0 && numfmt.NumberNegativePattern != 2))){
- if ((((options & NumberStyles.AllowLeadingSign) != 0) && (state & StateSign) == 0) && ((next = MatchChars(p, numfmt.PositiveSign)) != null || ((next = MatchChars(p, numfmt.NegativeSign)) != null && (number.sign = true)))){
- state |= StateSign;
- p = next - 1;
- }
- else if (ch == '(' && ((options & NumberStyles.AllowParentheses) != 0) && ((state & StateSign) == 0)) {
- state |= StateSign | StateParens;
- number.sign = true;
- }
- else if (currSymbol != null && (next = MatchChars(p, currSymbol)) != null) {
- state |= StateCurrency;
- currSymbol = null;
- // We already found the currency symbol. There should not be more currency symbols. Set
- // currSymbol to NULL so that we won't search it again in the later code path.
- p = next - 1;
- }
- else {
- break;
- }
- }
+ if (!IsWhite(ch) || (options & NumberStyles.AllowLeadingWhite) == 0 || ((state & StateSign) != 0 && ((state & StateCurrency) == 0 && numfmt.NumberNegativePattern != 2)))
+ {
+ if ((((options & NumberStyles.AllowLeadingSign) != 0) && (state & StateSign) == 0) && ((next = MatchChars(p, numfmt.PositiveSign)) != null || ((next = MatchChars(p, numfmt.NegativeSign)) != null && (number.sign = true))))
+ {
+ state |= StateSign;
+ p = next - 1;
+ }
+ else if (ch == '(' && ((options & NumberStyles.AllowParentheses) != 0) && ((state & StateSign) == 0))
+ {
+ state |= StateSign | StateParens;
+ number.sign = true;
+ }
+ else if (currSymbol != null && (next = MatchChars(p, currSymbol)) != null)
+ {
+ state |= StateCurrency;
+ currSymbol = null;
+ // We already found the currency symbol. There should not be more currency symbols. Set
+ // currSymbol to NULL so that we won't search it again in the later code path.
+ p = next - 1;
+ }
+ else
+ {
+ break;
+ }
+ }
ch = *++p;
}
Int32 digCount = 0;
Int32 digEnd = 0;
- while (true) {
- if ((ch >= '0' && ch <= '9') || (((options & NumberStyles.AllowHexSpecifier) != 0) && ((ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')))) {
+ while (true)
+ {
+ if ((ch >= '0' && ch <= '9') || (((options & NumberStyles.AllowHexSpecifier) != 0) && ((ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'))))
+ {
state |= StateDigits;
- if (ch != '0' || (state & StateNonZero) != 0 || (bigNumber && ((options & NumberStyles.AllowHexSpecifier) != 0))) {
- if (digCount < maxParseDigits) {
+ if (ch != '0' || (state & StateNonZero) != 0 || (bigNumber && ((options & NumberStyles.AllowHexSpecifier) != 0)))
+ {
+ if (digCount < maxParseDigits)
+ {
if (bigNumber)
sb.Append(ch);
else
number.digits[digCount++] = ch;
- if (ch != '0' || parseDecimal) {
+ if (ch != '0' || parseDecimal)
+ {
digEnd = digCount;
}
}
- if ((state & StateDecimal) == 0) {
+ if ((state & StateDecimal) == 0)
+ {
number.scale++;
}
state |= StateNonZero;
}
- else if ((state & StateDecimal) != 0) {
+ else if ((state & StateDecimal) != 0)
+ {
number.scale--;
}
}
- else if (((options & NumberStyles.AllowDecimalPoint) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, decSep)) != null || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, numfmt.NumberDecimalSeparator)) != null)) {
+ else if (((options & NumberStyles.AllowDecimalPoint) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, decSep)) != null || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, numfmt.NumberDecimalSeparator)) != null))
+ {
state |= StateDecimal;
p = next - 1;
}
- else if (((options & NumberStyles.AllowThousands) != 0) && ((state & StateDigits) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, groupSep)) != null || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, numfmt.NumberGroupSeparator)) != null)) {
+ else if (((options & NumberStyles.AllowThousands) != 0) && ((state & StateDigits) != 0) && ((state & StateDecimal) == 0) && ((next = MatchChars(p, groupSep)) != null || ((parsingCurrency) && (state & StateCurrency) == 0) && (next = MatchChars(p, numfmt.NumberGroupSeparator)) != null))
+ {
p = next - 1;
}
- else {
+ else
+ {
break;
}
ch = *++p;
@@ -804,64 +896,84 @@ namespace System {
sb.Append('\0');
else
number.digits[digEnd] = '\0';
- if ((state & StateDigits) != 0) {
- if ((ch == 'E' || ch == 'e') && ((options & NumberStyles.AllowExponent) != 0)) {
+ if ((state & StateDigits) != 0)
+ {
+ if ((ch == 'E' || ch == 'e') && ((options & NumberStyles.AllowExponent) != 0))
+ {
char* temp = p;
ch = *++p;
- if ((next = MatchChars(p, numfmt.positiveSign)) != null) {
+ if ((next = MatchChars(p, numfmt.positiveSign)) != null)
+ {
ch = *(p = next);
}
- else if ((next = MatchChars(p, numfmt.negativeSign)) != null) {
+ else if ((next = MatchChars(p, numfmt.negativeSign)) != null)
+ {
ch = *(p = next);
negExp = true;
}
- if (ch >= '0' && ch <= '9') {
+ if (ch >= '0' && ch <= '9')
+ {
Int32 exp = 0;
- do {
+ do
+ {
exp = exp * 10 + (ch - '0');
ch = *++p;
- if (exp > 1000) {
+ if (exp > 1000)
+ {
exp = 9999;
- while (ch >= '0' && ch <= '9') {
+ while (ch >= '0' && ch <= '9')
+ {
ch = *++p;
}
}
} while (ch >= '0' && ch <= '9');
- if (negExp) {
+ if (negExp)
+ {
exp = -exp;
}
number.scale += exp;
}
- else {
+ else
+ {
p = temp;
ch = *p;
}
}
- while (true) {
- if (!IsWhite(ch) || (options & NumberStyles.AllowTrailingWhite) == 0){
- if (((options & NumberStyles.AllowTrailingSign) != 0 && ((state & StateSign) == 0)) && ((next = MatchChars(p, numfmt.PositiveSign)) != null || (((next = MatchChars(p, numfmt.NegativeSign)) != null) && (number.sign = true)))) {
- state |= StateSign;
- p = next - 1;
- }
- else if (ch == ')' && ((state & StateParens) != 0)) {
- state &= ~StateParens;
- }
- else if (currSymbol != null && (next = MatchChars(p, currSymbol)) != null) {
- currSymbol = null;
- p = next - 1;
- }
- else {
- break;
- }
- }
+ while (true)
+ {
+ if (!IsWhite(ch) || (options & NumberStyles.AllowTrailingWhite) == 0)
+ {
+ if (((options & NumberStyles.AllowTrailingSign) != 0 && ((state & StateSign) == 0)) && ((next = MatchChars(p, numfmt.PositiveSign)) != null || (((next = MatchChars(p, numfmt.NegativeSign)) != null) && (number.sign = true))))
+ {
+ state |= StateSign;
+ p = next - 1;
+ }
+ else if (ch == ')' && ((state & StateParens) != 0))
+ {
+ state &= ~StateParens;
+ }
+ else if (currSymbol != null && (next = MatchChars(p, currSymbol)) != null)
+ {
+ currSymbol = null;
+ p = next - 1;
+ }
+ else
+ {
+ break;
+ }
+ }
ch = *++p;
}
- if ((state & StateParens) == 0) {
- if ((state & StateNonZero) == 0) {
- if (!parseDecimal) {
+ if ((state & StateParens) == 0)
+ {
+ if ((state & StateNonZero) == 0)
+ {
+ if (!parseDecimal)
+ {
number.scale = 0;
}
- if ((state & StateDecimal) == 0) {
+ if ((state & StateDecimal) == 0)
+ {
number.sign = false;
}
}
@@ -873,200 +985,242 @@ namespace System {
return false;
}
- internal unsafe static Single ParseSingle(String value, NumberStyles options, NumberFormatInfo numfmt) {
- if (value == null) {
+ internal unsafe static Single ParseSingle(String value, NumberStyles options, NumberFormatInfo numfmt)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
Double d = 0;
- if (!TryStringToNumber(value, options, ref number, numfmt, false)) {
+ if (!TryStringToNumber(value, options, ref number, numfmt, false))
+ {
//If we failed TryStringToNumber, it may be from one of our special strings.
//Check the three with which we're concerned and rethrow if it's not one of
//those strings.
String sTrim = value.Trim();
- if (sTrim.Equals(numfmt.PositiveInfinitySymbol)) {
+ if (sTrim.Equals(numfmt.PositiveInfinitySymbol))
+ {
return Single.PositiveInfinity;
}
- if (sTrim.Equals(numfmt.NegativeInfinitySymbol)) {
+ if (sTrim.Equals(numfmt.NegativeInfinitySymbol))
+ {
return Single.NegativeInfinity;
}
- if (sTrim.Equals(numfmt.NaNSymbol)) {
+ if (sTrim.Equals(numfmt.NaNSymbol))
+ {
return Single.NaN;
}
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ throw new FormatException(SR.Format_InvalidString);
}
- if (!NumberBufferToDouble(number.PackForNative(), ref d)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Single"));
+ if (!NumberBufferToDouble(number.PackForNative(), ref d))
+ {
+ throw new OverflowException(SR.Overflow_Single);
}
Single castSingle = (Single)d;
- if (Single.IsInfinity(castSingle)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_Single"));
+ if (Single.IsInfinity(castSingle))
+ {
+ throw new OverflowException(SR.Overflow_Single);
}
return castSingle;
}
- internal unsafe static UInt32 ParseUInt32(String value, NumberStyles options, NumberFormatInfo numfmt) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static UInt32 ParseUInt32(String value, NumberStyles options, NumberFormatInfo numfmt)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
UInt32 i = 0;
-
+
StringToNumber(value, options, ref number, numfmt, false);
- if ((options & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToUInt32(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_UInt32"));
+ if ((options & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToUInt32(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_UInt32);
}
}
- else {
- if (!NumberToUInt32(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_UInt32"));
+ else
+ {
+ if (!NumberToUInt32(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_UInt32);
}
}
-
+
return i;
}
- internal unsafe static UInt64 ParseUInt64(String value, NumberStyles options, NumberFormatInfo numfmt) {
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static UInt64 ParseUInt64(String value, NumberStyles options, NumberFormatInfo numfmt)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
UInt64 i = 0;
StringToNumber(value, options, ref number, numfmt, false);
- if ((options & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToUInt64(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_UInt64"));
+ if ((options & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToUInt64(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_UInt64);
}
}
- else {
- if (!NumberToUInt64(ref number, ref i)) {
- throw new OverflowException(Environment.GetResourceString("Overflow_UInt64"));
+ else
+ {
+ if (!NumberToUInt64(ref number, ref i))
+ {
+ throw new OverflowException(SR.Overflow_UInt64);
}
}
return i;
}
- private unsafe static void StringToNumber(String str, NumberStyles options, ref NumberBuffer number, NumberFormatInfo info, Boolean parseDecimal) {
-
- if (str == null) {
+ private unsafe static void StringToNumber(String str, NumberStyles options, ref NumberBuffer number, NumberFormatInfo info, Boolean parseDecimal)
+ {
+ if (str == null)
+ {
throw new ArgumentNullException(nameof(String));
}
Contract.EndContractBlock();
Debug.Assert(info != null, "");
- fixed (char* stringPointer = str) {
- char * p = stringPointer;
- if (!ParseNumber(ref p, options, ref number, null, info , parseDecimal)
- || (p - stringPointer < str.Length && !TrailingZeros(str, (int)(p - stringPointer)))) {
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
+ fixed (char* stringPointer = str)
+ {
+ char* p = stringPointer;
+ if (!ParseNumber(ref p, options, ref number, null, info, parseDecimal)
+ || (p - stringPointer < str.Length && !TrailingZeros(str, (int)(p - stringPointer))))
+ {
+ throw new FormatException(SR.Format_InvalidString);
}
}
}
-
- private static Boolean TrailingZeros(String s, Int32 index) {
+
+ private static Boolean TrailingZeros(String s, Int32 index)
+ {
// For compatibility, we need to allow trailing zeros at the end of a number string
- for (int i = index; i < s.Length; i++) {
- if (s[i] != '\0') {
+ for (int i = index; i < s.Length; i++)
+ {
+ if (s[i] != '\0')
+ {
return false;
}
}
return true;
}
- internal unsafe static Boolean TryParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt, out Decimal result) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Boolean TryParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt, out Decimal result)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
result = 0;
-
- if (!TryStringToNumber(value, options, ref number, numfmt, true)) {
+
+ if (!TryStringToNumber(value, options, ref number, numfmt, true))
+ {
return false;
}
- if (!NumberBufferToDecimal(number.PackForNative(), ref result)) {
+ if (!NumberBufferToDecimal(number.PackForNative(), ref result))
+ {
return false;
}
return true;
}
- internal unsafe static Boolean TryParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt, out Double result) {
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Boolean TryParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt, out Double result)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
result = 0;
- if (!TryStringToNumber(value, options, ref number, numfmt, false)) {
+ if (!TryStringToNumber(value, options, ref number, numfmt, false))
+ {
return false;
}
- if (!NumberBufferToDouble(number.PackForNative(), ref result)) {
+ if (!NumberBufferToDouble(number.PackForNative(), ref result))
+ {
return false;
}
return true;
}
- internal unsafe static Boolean TryParseInt32(String s, NumberStyles style, NumberFormatInfo info, out Int32 result) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Boolean TryParseInt32(String s, NumberStyles style, NumberFormatInfo info, out Int32 result)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
result = 0;
-
- if (!TryStringToNumber(s, style, ref number, info, false)) {
+
+ if (!TryStringToNumber(s, style, ref number, info, false))
+ {
return false;
}
- if ((style & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToInt32(ref number, ref result)) {
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToInt32(ref number, ref result))
+ {
return false;
}
}
- else {
- if (!NumberToInt32(ref number, ref result)) {
+ else
+ {
+ if (!NumberToInt32(ref number, ref result))
+ {
return false;
}
}
- return true;
+ return true;
}
- internal unsafe static Boolean TryParseInt64(String s, NumberStyles style, NumberFormatInfo info, out Int64 result) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Boolean TryParseInt64(String s, NumberStyles style, NumberFormatInfo info, out Int64 result)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
result = 0;
-
- if (!TryStringToNumber(s, style, ref number, info, false)) {
+
+ if (!TryStringToNumber(s, style, ref number, info, false))
+ {
return false;
}
- if ((style & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToInt64(ref number, ref result)) {
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToInt64(ref number, ref result))
+ {
return false;
}
}
- else {
- if (!NumberToInt64(ref number, ref result)) {
+ else
+ {
+ if (!NumberToInt64(ref number, ref result))
+ {
return false;
}
}
- return true;
+ return true;
}
- internal unsafe static Boolean TryParseSingle(String value, NumberStyles options, NumberFormatInfo numfmt, out Single result) {
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Boolean TryParseSingle(String value, NumberStyles options, NumberFormatInfo numfmt, out Single result)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
result = 0;
Double d = 0;
- if (!TryStringToNumber(value, options, ref number, numfmt, false)) {
+ if (!TryStringToNumber(value, options, ref number, numfmt, false))
+ {
return false;
}
- if (!NumberBufferToDouble(number.PackForNative(), ref d)) {
+ if (!NumberBufferToDouble(number.PackForNative(), ref d))
+ {
return false;
}
Single castSingle = (Single)d;
- if (Single.IsInfinity(castSingle)) {
+ if (Single.IsInfinity(castSingle))
+ {
return false;
}
@@ -1074,68 +1228,82 @@ namespace System {
return true;
}
- internal unsafe static Boolean TryParseUInt32(String s, NumberStyles style, NumberFormatInfo info, out UInt32 result) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Boolean TryParseUInt32(String s, NumberStyles style, NumberFormatInfo info, out UInt32 result)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
result = 0;
-
- if (!TryStringToNumber(s, style, ref number, info, false)) {
+
+ if (!TryStringToNumber(s, style, ref number, info, false))
+ {
return false;
}
- if ((style & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToUInt32(ref number, ref result)) {
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToUInt32(ref number, ref result))
+ {
return false;
}
}
- else {
- if (!NumberToUInt32(ref number, ref result)) {
+ else
+ {
+ if (!NumberToUInt32(ref number, ref result))
+ {
return false;
}
}
- return true;
+ return true;
}
- internal unsafe static Boolean TryParseUInt64(String s, NumberStyles style, NumberFormatInfo info, out UInt64 result) {
-
- Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
+ internal unsafe static Boolean TryParseUInt64(String s, NumberStyles style, NumberFormatInfo info, out UInt64 result)
+ {
+ Byte* numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
result = 0;
-
- if (!TryStringToNumber(s, style, ref number, info, false)) {
+
+ if (!TryStringToNumber(s, style, ref number, info, false))
+ {
return false;
}
- if ((style & NumberStyles.AllowHexSpecifier) != 0) {
- if (!HexNumberToUInt64(ref number, ref result)) {
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ {
+ if (!HexNumberToUInt64(ref number, ref result))
+ {
return false;
}
}
- else {
- if (!NumberToUInt64(ref number, ref result)) {
+ else
+ {
+ if (!NumberToUInt64(ref number, ref result))
+ {
return false;
}
}
- return true;
+ return true;
}
- internal static Boolean TryStringToNumber(String str, NumberStyles options, ref NumberBuffer number, NumberFormatInfo numfmt, Boolean parseDecimal) {
+ internal static Boolean TryStringToNumber(String str, NumberStyles options, ref NumberBuffer number, NumberFormatInfo numfmt, Boolean parseDecimal)
+ {
return TryStringToNumber(str, options, ref number, null, numfmt, parseDecimal);
}
[System.Runtime.CompilerServices.FriendAccessAllowed]
- internal unsafe static Boolean TryStringToNumber(String str, NumberStyles options, ref NumberBuffer number, StringBuilder sb, NumberFormatInfo numfmt, Boolean parseDecimal) {
-
- if (str == null) {
+ internal unsafe static Boolean TryStringToNumber(String str, NumberStyles options, ref NumberBuffer number, StringBuilder sb, NumberFormatInfo numfmt, Boolean parseDecimal)
+ {
+ if (str == null)
+ {
return false;
}
Debug.Assert(numfmt != null, "");
- fixed (char* stringPointer = str) {
- char * p = stringPointer;
- if (!ParseNumber(ref p, options, ref number, sb, numfmt, parseDecimal)
- || (p - stringPointer < str.Length && !TrailingZeros(str, (int)(p - stringPointer)))) {
+ fixed (char* stringPointer = str)
+ {
+ char* p = stringPointer;
+ if (!ParseNumber(ref p, options, ref number, sb, numfmt, parseDecimal)
+ || (p - stringPointer < str.Length && !TrailingZeros(str, (int)(p - stringPointer))))
+ {
return false;
}
}
diff --git a/src/mscorlib/src/System/Object.cs b/src/mscorlib/src/System/Object.cs
index 1f47d8cdef..3c304422ac 100644
--- a/src/mscorlib/src/System/Object.cs
+++ b/src/mscorlib/src/System/Object.cs
@@ -25,200 +25,202 @@ namespace System
using FieldInfo = System.Reflection.FieldInfo;
using BindingFlags = System.Reflection.BindingFlags;
-// The Object is the root class for all object in the CLR System. Object
-// is the super class for all other CLR objects and provide a set of methods and low level
-// services to subclasses. These services include object synchronization and support for clone
-// operations.
-//
- //This class contains no data and does not need to be serializable
-[Serializable]
-[ClassInterface(ClassInterfaceType.AutoDual)]
-[System.Runtime.InteropServices.ComVisible(true)]
-public class Object
-{
- // Creates a new instance of an Object.
- [System.Runtime.Versioning.NonVersionable]
- public Object()
- {
- }
-
- // Returns a String which represents the object instance. The default
- // for an object is to return the fully qualified name of the class.
- //
- public virtual String ToString()
- {
- return GetType().ToString();
- }
-
- // Returns a boolean indicating if the passed in object obj is
- // Equal to this. Equality is defined as object equality for reference
- // types and bitwise equality for value types using a loader trick to
- // replace Equals with EqualsValue for value types).
+ // The Object is the root class for all object in the CLR System. Object
+ // is the super class for all other CLR objects and provide a set of methods and low level
+ // services to subclasses. These services include object synchronization and support for clone
+ // operations.
//
-
- public virtual bool Equals(Object obj)
+ //This class contains no data and does not need to be serializable
+ [Serializable]
+ [ClassInterface(ClassInterfaceType.AutoDual)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public class Object
{
- return RuntimeHelpers.Equals(this, obj);
- }
-
- public static bool Equals(Object objA, Object objB)
- {
- if (objA==objB) {
- return true;
+ // Creates a new instance of an Object.
+ [System.Runtime.Versioning.NonVersionable]
+ public Object()
+ {
}
- if (objA==null || objB==null) {
- return false;
+
+ // Returns a String which represents the object instance. The default
+ // for an object is to return the fully qualified name of the class.
+ //
+ public virtual String ToString()
+ {
+ return GetType().ToString();
}
- return objA.Equals(objB);
- }
- [System.Runtime.Versioning.NonVersionable]
- public static bool ReferenceEquals (Object objA, Object objB) {
- return objA == objB;
- }
-
- // GetHashCode is intended to serve as a hash function for this object.
- // Based on the contents of the object, the hash function will return a suitable
- // value with a relatively random distribution over the various inputs.
- //
- // The default implementation returns the sync block index for this instance.
- // Calling it on the same object multiple times will return the same value, so
- // it will technically meet the needs of a hash function, but it's less than ideal.
- // Objects (& especially value classes) should override this method.
- //
- public virtual int GetHashCode()
- {
- return RuntimeHelpers.GetHashCode(this);
- }
-
- // Returns a Type object which represent this object instance.
- //
- [Pure]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public extern Type GetType();
+ // Returns a boolean indicating if the passed in object obj is
+ // Equal to this. Equality is defined as object equality for reference
+ // types and bitwise equality for value types using a loader trick to
+ // replace Equals with EqualsValue for value types).
+ //
- // Allow an object to free resources before the object is reclaimed by the GC.
- //
- [System.Runtime.Versioning.NonVersionable]
- ~Object()
- {
- }
-
- // Returns a new object instance that is a memberwise copy of this
- // object. This is always a shallow copy of the instance. The method is protected
- // so that other object may only call this method on themselves. It is entended to
- // support the ICloneable interface.
- //
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- protected extern Object MemberwiseClone();
-
-
- // Sets the value specified in the variant on the field
- //
- private void FieldSetter(String typeName, String fieldName, Object val)
- {
- Contract.Requires(typeName != null);
- Contract.Requires(fieldName != null);
+ public virtual bool Equals(Object obj)
+ {
+ return RuntimeHelpers.Equals(this, obj);
+ }
- // Extract the field info object
- FieldInfo fldInfo = GetFieldInfo(typeName, fieldName);
+ public static bool Equals(Object objA, Object objB)
+ {
+ if (objA == objB)
+ {
+ return true;
+ }
+ if (objA == null || objB == null)
+ {
+ return false;
+ }
+ return objA.Equals(objB);
+ }
- if (fldInfo.IsInitOnly)
- throw new FieldAccessException(Environment.GetResourceString("FieldAccess_InitOnly"));
+ [System.Runtime.Versioning.NonVersionable]
+ public static bool ReferenceEquals(Object objA, Object objB)
+ {
+ return objA == objB;
+ }
- // Make sure that the value is compatible with the type
- // of field
- Type pt=fldInfo.FieldType;
- if (pt.IsByRef)
+ // GetHashCode is intended to serve as a hash function for this object.
+ // Based on the contents of the object, the hash function will return a suitable
+ // value with a relatively random distribution over the various inputs.
+ //
+ // The default implementation returns the sync block index for this instance.
+ // Calling it on the same object multiple times will return the same value, so
+ // it will technically meet the needs of a hash function, but it's less than ideal.
+ // Objects (& especially value classes) should override this method.
+ //
+ public virtual int GetHashCode()
{
- pt = pt.GetElementType();
+ return RuntimeHelpers.GetHashCode(this);
}
- if (!pt.IsInstanceOfType(val))
+ // Returns a Type object which represent this object instance.
+ //
+ [Pure]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern Type GetType();
+
+ // Allow an object to free resources before the object is reclaimed by the GC.
+ //
+ [System.Runtime.Versioning.NonVersionable]
+ ~Object()
{
- val = Convert.ChangeType(val, pt, CultureInfo.InvariantCulture);
}
- // Set the value
- fldInfo.SetValue(this, val);
- }
+ // Returns a new object instance that is a memberwise copy of this
+ // object. This is always a shallow copy of the instance. The method is protected
+ // so that other object may only call this method on themselves. It is entended to
+ // support the ICloneable interface.
+ //
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ protected extern Object MemberwiseClone();
- // Gets the value specified in the variant on the field
- //
- private void FieldGetter(String typeName, String fieldName, ref Object val)
- {
- Contract.Requires(typeName != null);
- Contract.Requires(fieldName != null);
- // Extract the field info object
- FieldInfo fldInfo = GetFieldInfo(typeName, fieldName);
+ // Sets the value specified in the variant on the field
+ //
+ private void FieldSetter(String typeName, String fieldName, Object val)
+ {
+ Contract.Requires(typeName != null);
+ Contract.Requires(fieldName != null);
- // Get the value
- val = fldInfo.GetValue(this);
- }
+ // Extract the field info object
+ FieldInfo fldInfo = GetFieldInfo(typeName, fieldName);
- // Gets the field info object given the type name and field name.
- //
- private FieldInfo GetFieldInfo(String typeName, String fieldName)
- {
- Contract.Requires(typeName != null);
- Contract.Requires(fieldName != null);
- Contract.Ensures(Contract.Result<FieldInfo>() != null);
+ if (fldInfo.IsInitOnly)
+ throw new FieldAccessException(SR.FieldAccess_InitOnly);
- Type t = GetType();
- while(null != t)
- {
- if(t.FullName.Equals(typeName))
+ // Make sure that the value is compatible with the type
+ // of field
+ Type pt = fldInfo.FieldType;
+ if (pt.IsByRef)
{
- break;
+ pt = pt.GetElementType();
}
- t = t.BaseType;
- }
-
- if (null == t)
- {
- throw new ArgumentException();
+ if (!pt.IsInstanceOfType(val))
+ {
+ val = Convert.ChangeType(val, pt, CultureInfo.InvariantCulture);
+ }
+
+ // Set the value
+ fldInfo.SetValue(this, val);
}
- FieldInfo fldInfo = t.GetField(fieldName, BindingFlags.Public |
- BindingFlags.Instance |
- BindingFlags.IgnoreCase);
- if(null == fldInfo)
+ // Gets the value specified in the variant on the field
+ //
+ private void FieldGetter(String typeName, String fieldName, ref Object val)
{
- throw new ArgumentException();
+ Contract.Requires(typeName != null);
+ Contract.Requires(fieldName != null);
+
+ // Extract the field info object
+ FieldInfo fldInfo = GetFieldInfo(typeName, fieldName);
+
+ // Get the value
+ val = fldInfo.GetValue(this);
}
- return fldInfo;
- }
-}
+ // Gets the field info object given the type name and field name.
+ //
+ private FieldInfo GetFieldInfo(String typeName, String fieldName)
+ {
+ Contract.Requires(typeName != null);
+ Contract.Requires(fieldName != null);
+ Contract.Ensures(Contract.Result<FieldInfo>() != null);
+ Type t = GetType();
+ while (null != t)
+ {
+ if (t.FullName.Equals(typeName))
+ {
+ break;
+ }
-// Internal methodtable used to instantiate the "canonical" methodtable for generic instantiations.
-// The name "__Canon" will never been seen by users but it will appear a lot in debugger stack traces
-// involving generics so it is kept deliberately short as to avoid being a nuisance.
+ t = t.BaseType;
+ }
-[Serializable]
-[ClassInterface(ClassInterfaceType.AutoDual)]
-[System.Runtime.InteropServices.ComVisible(true)]
-internal class __Canon
-{
-}
+ if (null == t)
+ {
+ throw new ArgumentException();
+ }
-// This class is used to define the name of the base class library
-internal class CoreLib
-{
- public const string Name = "System.Private.CoreLib";
+ FieldInfo fldInfo = t.GetField(fieldName, BindingFlags.Public |
+ BindingFlags.Instance |
+ BindingFlags.IgnoreCase);
+ if (null == fldInfo)
+ {
+ throw new ArgumentException();
+ }
- public static string FixupCoreLibName(string strToFixup)
- {
- if (!String.IsNullOrEmpty(strToFixup))
- {
- strToFixup = strToFixup.Replace("mscorlib", System.CoreLib.Name);
+ return fldInfo;
}
+ }
+
- return strToFixup;
+ // Internal methodtable used to instantiate the "canonical" methodtable for generic instantiations.
+ // The name "__Canon" will never been seen by users but it will appear a lot in debugger stack traces
+ // involving generics so it is kept deliberately short as to avoid being a nuisance.
+
+ [Serializable]
+ [ClassInterface(ClassInterfaceType.AutoDual)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ internal class __Canon
+ {
}
-}
+ // This class is used to define the name of the base class library
+ internal class CoreLib
+ {
+ public const string Name = "System.Private.CoreLib";
+
+ public static string FixupCoreLibName(string strToFixup)
+ {
+ if (!String.IsNullOrEmpty(strToFixup))
+ {
+ strToFixup = strToFixup.Replace("mscorlib", System.CoreLib.Name);
+ }
+
+ return strToFixup;
+ }
+ }
}
diff --git a/src/mscorlib/src/System/ObjectDisposedException.cs b/src/mscorlib/src/System/ObjectDisposedException.cs
deleted file mode 100644
index 1f77b1f009..0000000000
--- a/src/mscorlib/src/System/ObjectDisposedException.cs
+++ /dev/null
@@ -1,82 +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.Globalization;
-using System.Runtime.Serialization;
-
-namespace System
-{
- /// <devdoc>
- /// <para> The exception that is thrown when accessing an object that was
- /// disposed.</para>
- /// </devdoc>
- [Serializable]
- public class ObjectDisposedException : InvalidOperationException
- {
- private String _objectName;
-
- // This constructor should only be called by the EE (COMPlusThrow)
- private ObjectDisposedException() :
- this(null, SR.ObjectDisposed_Generic)
- {
- }
-
- public ObjectDisposedException(String objectName) :
- this(objectName, SR.ObjectDisposed_Generic)
- {
- }
-
- public ObjectDisposedException(String objectName, String message) : base(message)
- {
- HResult = __HResults.COR_E_OBJECTDISPOSED;
- _objectName = objectName;
- }
-
- public ObjectDisposedException(String message, Exception innerException)
- : base(message, innerException)
- {
- HResult = __HResults.COR_E_OBJECTDISPOSED;
- }
-
- protected ObjectDisposedException(SerializationInfo info, StreamingContext context)
- : base(info, context)
- {
- _objectName = info.GetString("ObjectName");
- }
-
- public override void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- base.GetObjectData(info, context);
- info.AddValue("ObjectName",ObjectName,typeof(String));
- }
-
- /// <devdoc>
- /// <para>Gets the text for the message for this exception.</para>
- /// </devdoc>
- public override String Message
- {
- get
- {
- String name = ObjectName;
- if (name == null || name.Length == 0)
- return base.Message;
-
- String objectDisposed = SR.Format(SR.ObjectDisposed_ObjectName_Name, name);
- return base.Message + Environment.NewLine + objectDisposed;
- }
- }
-
- public String ObjectName
- {
- get
- {
- if ((_objectName == null)) // && !CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
- {
- return String.Empty;
- }
- return _objectName;
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/OleAutBinder.cs b/src/mscorlib/src/System/OleAutBinder.cs
index acae95a214..1db61bb30e 100644
--- a/src/mscorlib/src/System/OleAutBinder.cs
+++ b/src/mscorlib/src/System/OleAutBinder.cs
@@ -6,13 +6,13 @@
// #define DISPLAY_DEBUG_INFO
-namespace System {
-
+namespace System
+{
using System;
using System.Runtime.InteropServices;
using System.Reflection;
using Microsoft.Win32;
- using CultureInfo = System.Globalization.CultureInfo;
+ using CultureInfo = System.Globalization.CultureInfo;
// Made serializable in anticipation of this class eventually having state.
[Serializable]
@@ -25,16 +25,16 @@ namespace System {
Variant myValue = new Variant(value);
if (cultureInfo == null)
cultureInfo = CultureInfo.CurrentCulture;
-
- #if DISPLAY_DEBUG_INFO
+
+#if DISPLAY_DEBUG_INFO
Console.WriteLine("In OleAutBinder::ChangeType converting variant of type: {0} to type: {1}", myValue.VariantType, type.Name);
- #endif
+#endif
if (type.IsByRef)
{
- #if DISPLAY_DEBUG_INFO
+#if DISPLAY_DEBUG_INFO
Console.WriteLine("Stripping byref from the type to convert to.");
- #endif
+#endif
type = type.GetElementType();
}
@@ -42,9 +42,9 @@ namespace System {
// need the OLEAUT change type, we can just use the normal COM+ mechanisms.
if (!type.IsPrimitive && type.IsInstanceOfType(value))
{
- #if DISPLAY_DEBUG_INFO
+#if DISPLAY_DEBUG_INFO
Console.WriteLine("Source variant can be assigned to destination type");
- #endif
+#endif
return value;
}
@@ -53,9 +53,9 @@ namespace System {
// Handle converting primitives to enums.
if (type.IsEnum && srcType.IsPrimitive)
{
- #if DISPLAY_DEBUG_INFO
+#if DISPLAY_DEBUG_INFO
Console.WriteLine("Converting primitive to enum");
- #endif
+#endif
return Enum.Parse(type, value.ToString());
}
@@ -78,14 +78,14 @@ namespace System {
#if DISPLAY_DEBUG_INFO
catch(NotSupportedException e)
#else
- catch(NotSupportedException)
+ catch (NotSupportedException)
#endif
{
#if DISPLAY_DEBUG_INFO
Console.Write("Exception thrown: ");
Console.WriteLine(e);
#endif
- throw new COMException(Environment.GetResourceString("Interop.COM_TypeMismatch"), unchecked((int)0x80020005));
+ throw new COMException(SR.Interop_COM_TypeMismatch, unchecked((int)0x80020005));
}
}
}
diff --git a/src/mscorlib/src/System/OperatingSystem.cs b/src/mscorlib/src/System/OperatingSystem.cs
index a388fc6e33..5eb1253fa5 100644
--- a/src/mscorlib/src/System/OperatingSystem.cs
+++ b/src/mscorlib/src/System/OperatingSystem.cs
@@ -10,15 +10,16 @@
**
**
===========================================================*/
-namespace System {
- using System.Runtime.Serialization;
- using System.Globalization;
- using System.Runtime.InteropServices;
- using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Diagnostics.Contracts;
+namespace System
+{
[Serializable]
- internal sealed class OperatingSystem : ICloneable , ISerializable
+ internal sealed class OperatingSystem : ICloneable, ISerializable
{
private Version _version;
private PlatformID _platform;
@@ -28,32 +29,37 @@ namespace System {
private OperatingSystem()
{
}
-
- internal OperatingSystem(PlatformID platform, Version version, string servicePack) {
- if( platform < PlatformID.Win32S || platform > PlatformID.MacOSX) {
+
+ internal OperatingSystem(PlatformID platform, Version version, string servicePack)
+ {
+ if (platform < PlatformID.Win32S || platform > PlatformID.MacOSX)
+ {
throw new ArgumentException(
- Environment.GetResourceString("Arg_EnumIllegalVal", (int)platform),
+ SR.Format(SR.Arg_EnumIllegalVal, (int)platform),
nameof(platform));
}
- if ((Object) version == null)
+ if ((Object)version == null)
throw new ArgumentNullException(nameof(version));
Contract.EndContractBlock();
_platform = platform;
- _version = (Version) version.Clone();
+ _version = (Version)version.Clone();
_servicePack = servicePack;
}
-
- private OperatingSystem(SerializationInfo info, StreamingContext context) {
- SerializationInfoEnumerator enumerator = info.GetEnumerator();
- while( enumerator.MoveNext()) {
- switch( enumerator.Name) {
+
+ private OperatingSystem(SerializationInfo info, StreamingContext context)
+ {
+ SerializationInfoEnumerator enumerator = info.GetEnumerator();
+ while (enumerator.MoveNext())
+ {
+ switch (enumerator.Name)
+ {
case "_version":
- _version = (Version) info.GetValue("_version", typeof(Version));
+ _version = (Version)info.GetValue("_version", typeof(Version));
break;
case "_platform":
- _platform = (PlatformID) info.GetValue("_platform", typeof(PlatformID));
+ _platform = (PlatformID)info.GetValue("_platform", typeof(PlatformID));
break;
case "_servicePack":
_servicePack = info.GetString("_servicePack");
@@ -61,13 +67,16 @@ namespace System {
}
}
- if (_version == null ) {
- throw new SerializationException(Environment.GetResourceString("Serialization_MissField", "_version"));
+ if (_version == null)
+ {
+ throw new SerializationException(SR.Format(SR.Serialization_MissField, "_version"));
}
}
- public void GetObjectData(SerializationInfo info, StreamingContext context) {
- if( info == null ) {
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
@@ -75,29 +84,35 @@ namespace System {
info.AddValue("_version", _version);
info.AddValue("_platform", _platform);
info.AddValue("_servicePack", _servicePack);
- }
+ }
- public Version Version {
+ public Version Version
+ {
get { return _version; }
}
-
- public Object Clone() {
+
+ public Object Clone()
+ {
return new OperatingSystem(_platform,
- _version, _servicePack );
+ _version, _servicePack);
}
-
- public override String ToString() {
+
+ public override String ToString()
+ {
return VersionString;
}
- public String VersionString {
- get {
- if(_versionString != null) {
+ public String VersionString
+ {
+ get
+ {
+ if (_versionString != null)
+ {
return _versionString;
}
String os;
- switch(_platform)
+ switch (_platform)
{
case PlatformID.Win32NT:
os = "Microsoft Windows NT ";
@@ -123,14 +138,16 @@ namespace System {
break;
}
- if( String.IsNullOrEmpty(_servicePack)) {
+ if (String.IsNullOrEmpty(_servicePack))
+ {
_versionString = os + _version.ToString();
}
- else {
+ else
+ {
_versionString = os + _version.ToString(3) + " " + _servicePack;
}
- return _versionString;
+ return _versionString;
}
}
}
diff --git a/src/mscorlib/src/System/OperationCanceledException.cs b/src/mscorlib/src/System/OperationCanceledException.cs
index 061201637a..826561776f 100644
--- a/src/mscorlib/src/System/OperationCanceledException.cs
+++ b/src/mscorlib/src/System/OperationCanceledException.cs
@@ -15,43 +15,46 @@ using System;
using System.Runtime.Serialization;
using System.Threading;
-namespace System {
-
+namespace System
+{
[Serializable]
public class OperationCanceledException : SystemException
{
- [NonSerialized]
+ [NonSerialized]
private CancellationToken _cancellationToken;
-
+
public CancellationToken CancellationToken
{
- get { return _cancellationToken;}
- private set { _cancellationToken = value;}
+ get { return _cancellationToken; }
+ private set { _cancellationToken = value; }
}
- public OperationCanceledException()
- : base(Environment.GetResourceString("OperationCanceled")) {
- SetErrorCode(__HResults.COR_E_OPERATIONCANCELED);
+ public OperationCanceledException()
+ : base(SR.OperationCanceled)
+ {
+ HResult = __HResults.COR_E_OPERATIONCANCELED;
}
-
- public OperationCanceledException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_OPERATIONCANCELED);
+
+ public OperationCanceledException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_OPERATIONCANCELED;
}
-
- public OperationCanceledException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(__HResults.COR_E_OPERATIONCANCELED);
+
+ public OperationCanceledException(String message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_OPERATIONCANCELED;
}
public OperationCanceledException(CancellationToken token)
- :this()
+ : this()
{
CancellationToken = token;
}
- public OperationCanceledException(String message, CancellationToken token)
+ public OperationCanceledException(String message, CancellationToken token)
: this(message)
{
CancellationToken = token;
@@ -63,7 +66,8 @@ namespace System {
CancellationToken = token;
}
- protected OperationCanceledException(SerializationInfo info, StreamingContext context) : base (info, context) {
+ protected OperationCanceledException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
}
}
}
diff --git a/src/mscorlib/src/System/OutOfMemoryException.cs b/src/mscorlib/src/System/OutOfMemoryException.cs
index 46d5195405..154d0f92e2 100644
--- a/src/mscorlib/src/System/OutOfMemoryException.cs
+++ b/src/mscorlib/src/System/OutOfMemoryException.cs
@@ -11,29 +11,35 @@
**
=============================================================================*/
-namespace System {
-
- using System;
- using System.Runtime.Serialization;
+using System;
+using System.Runtime.Serialization;
+
+namespace System
+{
[Serializable]
- public class OutOfMemoryException : SystemException {
- public OutOfMemoryException()
- : base(GetMessageFromNativeResources(ExceptionMessageKind.OutOfMemory)) {
- SetErrorCode(__HResults.COR_E_OUTOFMEMORY);
+ public class OutOfMemoryException : SystemException
+ {
+ public OutOfMemoryException()
+ : base(GetMessageFromNativeResources(ExceptionMessageKind.OutOfMemory))
+ {
+ HResult = __HResults.COR_E_OUTOFMEMORY;
}
-
- public OutOfMemoryException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_OUTOFMEMORY);
+
+ public OutOfMemoryException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_OUTOFMEMORY;
}
-
- public OutOfMemoryException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(__HResults.COR_E_OUTOFMEMORY);
+
+ public OutOfMemoryException(String message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_OUTOFMEMORY;
}
- protected OutOfMemoryException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ protected OutOfMemoryException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
}
}
}
diff --git a/src/mscorlib/src/System/ParamsArray.cs b/src/mscorlib/src/System/ParamsArray.cs
deleted file mode 100644
index ed8919c586..0000000000
--- a/src/mscorlib/src/System/ParamsArray.cs
+++ /dev/null
@@ -1,81 +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.
-namespace System
-{
- internal struct ParamsArray
- {
- // Sentinel fixed-length arrays eliminate the need for a "count" field keeping this
- // struct down to just 4 fields. These are only used for their "Length" property,
- // that is, their elements are never set or referenced.
- private static readonly object[] oneArgArray = new object[1];
- private static readonly object[] twoArgArray = new object[2];
- private static readonly object[] threeArgArray = new object[3];
-
- private readonly object arg0;
- private readonly object arg1;
- private readonly object arg2;
-
- // After construction, the first three elements of this array will never be accessed
- // because the indexer will retrieve those values from arg0, arg1, and arg2.
- private readonly object[] args;
-
- public ParamsArray(object arg0)
- {
- this.arg0 = arg0;
- this.arg1 = null;
- this.arg2 = null;
-
- // Always assign this.args to make use of its "Length" property
- this.args = oneArgArray;
- }
-
- public ParamsArray(object arg0, object arg1)
- {
- this.arg0 = arg0;
- this.arg1 = arg1;
- this.arg2 = null;
-
- // Always assign this.args to make use of its "Length" property
- this.args = twoArgArray;
- }
-
- public ParamsArray(object arg0, object arg1, object arg2)
- {
- this.arg0 = arg0;
- this.arg1 = arg1;
- this.arg2 = arg2;
-
- // Always assign this.args to make use of its "Length" property
- this.args = threeArgArray;
- }
-
- public ParamsArray(object[] args)
- {
- int len = args.Length;
- this.arg0 = len > 0 ? args[0] : null;
- this.arg1 = len > 1 ? args[1] : null;
- this.arg2 = len > 2 ? args[2] : null;
- this.args = args;
- }
-
- public int Length
- {
- get { return this.args.Length; }
- }
-
- public object this[int index]
- {
- get { return index == 0 ? this.arg0 : GetAtSlow(index); }
- }
-
- private object GetAtSlow(int index)
- {
- if (index == 1)
- return this.arg1;
- if (index == 2)
- return this.arg2;
- return this.args[index];
- }
- }
-}
diff --git a/src/mscorlib/src/System/ParseNumbers.cs b/src/mscorlib/src/System/ParseNumbers.cs
index 2a375f7584..5287e27669 100644
--- a/src/mscorlib/src/System/ParseNumbers.cs
+++ b/src/mscorlib/src/System/ParseNumbers.cs
@@ -11,52 +11,61 @@
**
**
===========================================================*/
-namespace System {
-
- //This class contains only static members and does not need to be serializable.
- using System;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- internal static class ParseNumbers {
- internal const int PrintAsI1=0x40;
- internal const int PrintAsI2=0x80;
- internal const int PrintAsI4=0x100;
- internal const int TreatAsUnsigned=0x200;
- internal const int TreatAsI1=0x400;
- internal const int TreatAsI2=0x800;
- internal const int IsTight=0x1000;
- internal const int NoSpace=0x2000;
-
+//This class contains only static members and does not need to be serializable.
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+
+namespace System
+{
+ internal static class ParseNumbers
+ {
+ internal const int PrintAsI1 = 0x40;
+ internal const int PrintAsI2 = 0x80;
+ internal const int PrintAsI4 = 0x100;
+ internal const int TreatAsUnsigned = 0x200;
+ internal const int TreatAsI1 = 0x400;
+ internal const int TreatAsI2 = 0x800;
+ internal const int IsTight = 0x1000;
+ internal const int NoSpace = 0x2000;
+
//
//
// NATIVE METHODS
// For comments on these methods please see $\src\vm\COMUtilNative.cpp
//
- public unsafe static long StringToLong(System.String s, int radix, int flags) {
- return StringToLong(s,radix,flags, null);
+ public unsafe static long StringToLong(System.String s, int radix, int flags)
+ {
+ return StringToLong(s, radix, flags, null);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public unsafe extern static long StringToLong(System.String s, int radix, int flags, int* currPos);
- public unsafe static long StringToLong(System.String s, int radix, int flags, ref int currPos) {
- fixed(int * ppos = &currPos) {
- return StringToLong( s, radix, flags, ppos);
+ public unsafe static long StringToLong(System.String s, int radix, int flags, ref int currPos)
+ {
+ fixed (int* ppos = &currPos)
+ {
+ return StringToLong(s, radix, flags, ppos);
}
}
-
- public unsafe static int StringToInt(System.String s, int radix, int flags) {
- return StringToInt(s,radix,flags, null);
+
+ public unsafe static int StringToInt(System.String s, int radix, int flags)
+ {
+ return StringToInt(s, radix, flags, null);
}
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public unsafe extern static int StringToInt(System.String s, int radix, int flags, int* currPos);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public unsafe extern static int StringToInt(System.String s, int radix, int flags, int* currPos);
- public unsafe static int StringToInt(System.String s, int radix, int flags, ref int currPos) {
- fixed(int * ppos = &currPos) {
- return StringToInt( s, radix, flags, ppos);
+ public unsafe static int StringToInt(System.String s, int radix, int flags, ref int currPos)
+ {
+ fixed (int* ppos = &currPos)
+ {
+ return StringToInt(s, radix, flags, ppos);
}
- }
-
+ }
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern static String IntToString(int l, int radix, int width, char paddingChar, int flags);
diff --git a/src/mscorlib/src/System/PlatformID.cs b/src/mscorlib/src/System/PlatformID.cs
index 16128079e2..dfab2175ab 100644
--- a/src/mscorlib/src/System/PlatformID.cs
+++ b/src/mscorlib/src/System/PlatformID.cs
@@ -10,18 +10,18 @@
**
**
===========================================================*/
-namespace System {
+namespace System
+{
[Serializable]
internal enum PlatformID
{
- Win32S = 0,
- Win32Windows = 1,
- Win32NT = 2,
- WinCE = 3,
- Unix = 4,
- Xbox = 5,
- MacOSX = 6
+ Win32S = 0,
+ Win32Windows = 1,
+ Win32NT = 2,
+ WinCE = 3,
+ Unix = 4,
+ Xbox = 5,
+ MacOSX = 6
}
-
}
diff --git a/src/mscorlib/src/System/Random.cs b/src/mscorlib/src/System/Random.cs
deleted file mode 100644
index db6da0ea8b..0000000000
--- a/src/mscorlib/src/System/Random.cs
+++ /dev/null
@@ -1,249 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose: A random number generator.
-**
-**
-===========================================================*/
-namespace System {
-
- using System;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.Globalization;
- using System.Diagnostics.Contracts;
-
- [Serializable]
- public class Random {
- //
- // Private Constants
- //
- private const int MBIG = Int32.MaxValue;
- private const int MSEED = 161803398;
- private const int MZ = 0;
-
-
- //
- // Member Variables
- //
- private int inext;
- private int inextp;
- private int[] SeedArray = new int[56];
-
- //
- // Public Constants
- //
-
- //
- // Native Declarations
- //
-
- //
- // Constructors
- //
-
- /*=========================================================================================
- **Action: Initializes a new instance of the Random class, using a default seed value
- ===========================================================================================*/
- public Random()
- : this(GenerateSeed()) {
- }
-
- /*=========================================================================================
- **Action: Initializes a new instance of the Random class, using a specified seed value
- ===========================================================================================*/
- public Random(int Seed) {
- int ii = 0;
- int mj, mk;
-
- //Initialize our Seed array.
- int subtraction = (Seed == Int32.MinValue) ? Int32.MaxValue : Math.Abs(Seed);
- mj = MSEED - subtraction;
- SeedArray[55]=mj;
- mk=1;
- for (int i=1; i<55; i++) { //Apparently the range [1..55] is special (Knuth) and so we're wasting the 0'th position.
- if ((ii += 21) >= 55) ii -= 55;
- SeedArray[ii]=mk;
- mk = mj - mk;
- if (mk<0) mk+=MBIG;
- mj=SeedArray[ii];
- }
- for (int k=1; k<5; k++) {
- for (int i=1; i<56; i++) {
- int n = i + 30;
- if (n >= 55) n -= 55;
- SeedArray[i] -= SeedArray[1 + n];
- if (SeedArray[i]<0) SeedArray[i]+=MBIG;
- }
- }
- inext=0;
- inextp = 21;
- Seed = 1;
- }
-
- //
- // Package Private Methods
- //
-
- /*====================================Sample====================================
- **Action: Return a new random number [0..1) and reSeed the Seed array.
- **Returns: A double [0..1)
- **Arguments: None
- **Exceptions: None
- ==============================================================================*/
- protected virtual double Sample() {
- //Including this division at the end gives us significantly improved
- //random number distribution.
- return (InternalSample()*(1.0/MBIG));
- }
-
- private int InternalSample() {
- int retVal;
- int locINext = inext;
- int locINextp = inextp;
-
- if (++locINext >=56) locINext=1;
- if (++locINextp>= 56) locINextp = 1;
-
- retVal = SeedArray[locINext]-SeedArray[locINextp];
-
- if (retVal == MBIG) retVal--;
- if (retVal<0) retVal+=MBIG;
-
- SeedArray[locINext]=retVal;
-
- inext = locINext;
- inextp = locINextp;
-
- return retVal;
- }
-
-
- [ThreadStatic]
- private static Random t_threadRandom;
- private static readonly Random s_globalRandom = new Random(GenerateGlobalSeed());
-
- /*=====================================GenerateSeed=====================================
- **Returns: An integer that can be used as seed values for consecutively
- creating lots of instances on the same thread within a short period of time.
- ========================================================================================*/
- private static int GenerateSeed() {
- Random rnd = t_threadRandom;
- if (rnd == null) {
- int seed;
- lock (s_globalRandom) {
- seed = s_globalRandom.Next();
- }
- rnd = new Random(seed);
- t_threadRandom = rnd;
- }
- return rnd.Next();
- }
-
- /*==================================GenerateGlobalSeed====================================
- **Action: Creates a number to use as global seed.
- **Returns: An integer that is safe to use as seed values for thread-local seed generators.
- ==========================================================================================*/
- private static int GenerateGlobalSeed() {
- return Guid.NewGuid().GetHashCode();
- }
-
- //
- // Public Instance Methods
- //
-
-
- /*=====================================Next=====================================
- **Returns: An int [0..Int32.MaxValue)
- **Arguments: None
- **Exceptions: None.
- ==============================================================================*/
- public virtual int Next() {
- return InternalSample();
- }
-
- private double GetSampleForLargeRange() {
- // The distribution of double value returned by Sample
- // is not distributed well enough for a large range.
- // If we use Sample for a range [Int32.MinValue..Int32.MaxValue)
- // We will end up getting even numbers only.
-
- int result = InternalSample();
- // Note we can't use addition here. The distribution will be bad if we do that.
- bool negative = (InternalSample()%2 == 0) ? true : false; // decide the sign based on second sample
- if( negative) {
- result = -result;
- }
- double d = result;
- d += (Int32.MaxValue - 1); // get a number in range [0 .. 2 * Int32MaxValue - 1)
- d /= 2*(uint)Int32.MaxValue - 1 ;
- return d;
- }
-
-
- /*=====================================Next=====================================
- **Returns: An int [minvalue..maxvalue)
- **Arguments: minValue -- the least legal value for the Random number.
- ** maxValue -- One greater than the greatest legal return value.
- **Exceptions: None.
- ==============================================================================*/
- public virtual int Next(int minValue, int maxValue) {
- if (minValue>maxValue) {
- throw new ArgumentOutOfRangeException(nameof(minValue),Environment.GetResourceString("Argument_MinMaxValue", nameof(minValue), nameof(maxValue)));
- }
- Contract.EndContractBlock();
-
- long range = (long)maxValue-minValue;
- if( range <= (long)Int32.MaxValue) {
- return ((int)(Sample() * range) + minValue);
- }
- else {
- return (int)((long)(GetSampleForLargeRange() * range) + minValue);
- }
- }
-
-
- /*=====================================Next=====================================
- **Returns: An int [0..maxValue)
- **Arguments: maxValue -- One more than the greatest legal return value.
- **Exceptions: None.
- ==============================================================================*/
- public virtual int Next(int maxValue) {
- if (maxValue<0) {
- throw new ArgumentOutOfRangeException(nameof(maxValue), Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", nameof(maxValue)));
- }
- Contract.EndContractBlock();
- return (int)(Sample()*maxValue);
- }
-
-
- /*=====================================Next=====================================
- **Returns: A double [0..1)
- **Arguments: None
- **Exceptions: None
- ==============================================================================*/
- public virtual double NextDouble() {
- return Sample();
- }
-
-
- /*==================================NextBytes===================================
- **Action: Fills the byte array with random bytes [0..0x7f]. The entire array is filled.
- **Returns:Void
- **Arugments: buffer -- the array to be filled.
- **Exceptions: None
- ==============================================================================*/
- public virtual void NextBytes(byte [] buffer){
- if (buffer==null) throw new ArgumentNullException(nameof(buffer));
- Contract.EndContractBlock();
- for (int i=0; i<buffer.Length; i++) {
- buffer[i]=(byte)(InternalSample()%(Byte.MaxValue+1));
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/ReadOnlySpan.cs b/src/mscorlib/src/System/ReadOnlySpan.cs
index 76c63d5d8b..8d0fbad0fc 100644
--- a/src/mscorlib/src/System/ReadOnlySpan.cs
+++ b/src/mscorlib/src/System/ReadOnlySpan.cs
@@ -103,7 +103,7 @@ namespace System
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe ReadOnlySpan(void* pointer, int length)
{
- if (JitHelpers.ContainsReferences<T>())
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T));
if (length < 0)
ThrowHelper.ThrowArgumentOutOfRangeException();
@@ -114,28 +114,15 @@ namespace System
/// <summary>
/// Create a new read-only span over a portion of a regular managed object. This can be useful
- /// if part of a managed object represents a "fixed array." This is dangerous because
- /// "length" is not checked, nor is the fact that "rawPointer" actually lies within the object.
+ /// if part of a managed object represents a "fixed array." This is dangerous because neither the
+ /// <paramref name="length"/> is checked, nor <paramref name="obj"/> being null, nor the fact that
+ /// "rawPointer" actually lies within <paramref name="obj"/>.
/// </summary>
/// <param name="obj">The managed object that contains the data to span over.</param>
/// <param name="objectData">A reference to data within that object.</param>
/// <param name="length">The number of <typeparamref name="T"/> elements the memory contains.</param>
- /// <exception cref="System.ArgumentNullException">
- /// Thrown when the specified object is null.
- /// </exception>
- /// <exception cref="System.ArgumentOutOfRangeException">
- /// Thrown when the specified <paramref name="length"/> is negative.
- /// </exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlySpan<T> DangerousCreate(object obj, ref T objectData, int length)
- {
- if (obj == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.obj);
- if (length < 0)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length);
-
- return new ReadOnlySpan<T>(ref objectData, length);
- }
+ public static ReadOnlySpan<T> DangerousCreate(object obj, ref T objectData, int length) => new ReadOnlySpan<T>(ref objectData, length);
// Constructor for internal use only.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -244,9 +231,7 @@ namespace System
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj)
{
- ThrowHelper.ThrowNotSupportedException_CannotCallEqualsOnSpan();
- // Prevent compiler error CS0161: 'Span<T>.Equals(object)': not all code paths return a value
- return default(bool);
+ throw new NotSupportedException(SR.NotSupported_CannotCallEqualsOnSpan);
}
/// <summary>
@@ -259,9 +244,7 @@ namespace System
[EditorBrowsable(EditorBrowsableState.Never)]
public override int GetHashCode()
{
- ThrowHelper.ThrowNotSupportedException_CannotCallGetHashCodeOnSpan();
- // Prevent compiler error CS0161: 'Span<T>.GetHashCode()': not all code paths return a value
- return default(int);
+ throw new NotSupportedException(SR.NotSupported_CannotCallGetHashCodeOnSpan);
}
/// <summary>
diff --git a/src/mscorlib/src/System/Reflection/AmbiguousMatchException.cs b/src/mscorlib/src/System/Reflection/AmbiguousMatchException.cs
deleted file mode 100644
index 795a8714d1..0000000000
--- a/src/mscorlib/src/System/Reflection/AmbiguousMatchException.cs
+++ /dev/null
@@ -1,41 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// AmbiguousMatchException is thrown when binding to a method results in more
-//
-// than one method matching the binding criteria. This exception is thrown in
-// general when something is Ambiguous.
-//
-//
-//
-//
-namespace System.Reflection {
- using System;
- using SystemException = System.SystemException;
- using System.Runtime.Serialization;
- [Serializable]
- public sealed class AmbiguousMatchException : SystemException
- {
-
- public AmbiguousMatchException()
- : base(Environment.GetResourceString("RFLCT.Ambiguous")) {
- SetErrorCode(__HResults.COR_E_AMBIGUOUSMATCH);
- }
-
- public AmbiguousMatchException(String message) : base(message) {
- SetErrorCode(__HResults.COR_E_AMBIGUOUSMATCH);
- }
-
- public AmbiguousMatchException(String message, Exception inner) : base(message, inner) {
- SetErrorCode(__HResults.COR_E_AMBIGUOUSMATCH);
- }
-
- internal AmbiguousMatchException(SerializationInfo info, StreamingContext context) : base(info, context) {
- }
-
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs b/src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs
new file mode 100644
index 0000000000..82966dba60
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs
@@ -0,0 +1,211 @@
+// 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.Collections.Generic;
+using System.Security.Policy;
+using System.IO;
+using System.Configuration.Assemblies;
+using StackCrawlMark = System.Threading.StackCrawlMark;
+using System.Runtime.Serialization;
+using System.Diagnostics.Contracts;
+using System.Runtime.Loader;
+
+namespace System.Reflection
+{
+ public abstract partial class Assembly : ICustomAttributeProvider, ISerializable
+ {
+ public static Assembly LoadFrom(String assemblyFile)
+ {
+ if (assemblyFile == null)
+ throw new ArgumentNullException(nameof(assemblyFile));
+ string fullPath = Path.GetFullPath(assemblyFile);
+ return AssemblyLoadContext.Default.LoadFromAssemblyPath(fullPath);
+ }
+
+ // Evidence is protected in Assembly.Load()
+ [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use an overload of LoadFrom which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ internal static Assembly LoadFrom(String assemblyFile,
+ Evidence securityEvidence)
+ {
+ Contract.Ensures(Contract.Result<Assembly>() != null);
+
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+
+ return RuntimeAssembly.InternalLoadFrom(
+ assemblyFile,
+ securityEvidence,
+ null, // hashValue
+ AssemblyHashAlgorithm.None,
+ false,// forIntrospection);
+ ref stackMark);
+ }
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public static Assembly LoadFrom(String assemblyFile,
+ byte[] hashValue,
+ AssemblyHashAlgorithm hashAlgorithm)
+ {
+ throw new NotSupportedException(SR.NotSupported_AssemblyLoadFromHash);
+ }
+
+ // Locate an assembly by the long form of the assembly name.
+ // eg. "Toolbox.dll, version=1.1.10.1220, locale=en, publickey=1234567890123456789012345678901234567890"
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public static Assembly Load(String assemblyString)
+ {
+ Contract.Ensures(Contract.Result<Assembly>() != null);
+ Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
+
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return RuntimeAssembly.InternalLoad(assemblyString, null, ref stackMark, false /*forIntrospection*/);
+ }
+
+ // Returns type from the assembly while keeping compatibility with Assembly.Load(assemblyString).GetType(typeName) for managed types.
+ // Calls Type.GetType for WinRT types.
+ // Note: Type.GetType fails for assembly names that start with weird characters like '['. By calling it for managed types we would
+ // break AppCompat.
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ internal static Type GetType_Compat(String assemblyString, String typeName)
+ {
+ // Normally we would get the stackMark only in public APIs. This is internal API, but it is AppCompat replacement of public API
+ // call Assembly.Load(assemblyString).GetType(typeName), therefore we take the stackMark here as well, to be fully compatible with
+ // the call sequence.
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+
+ RuntimeAssembly assembly;
+ AssemblyName assemblyName = RuntimeAssembly.CreateAssemblyName(
+ assemblyString,
+ false /*forIntrospection*/,
+ out assembly);
+
+ if (assembly == null)
+ {
+ if (assemblyName.ContentType == AssemblyContentType.WindowsRuntime)
+ {
+ return Type.GetType(typeName + ", " + assemblyString, true /*throwOnError*/, false /*ignoreCase*/);
+ }
+
+ assembly = RuntimeAssembly.InternalLoadAssemblyName(
+ assemblyName, null, null, ref stackMark,
+ true /*thrownOnFileNotFound*/, false /*forIntrospection*/);
+ }
+ return assembly.GetType(typeName, true /*throwOnError*/, false /*ignoreCase*/);
+ }
+
+ // Locate an assembly by its name. The name can be strong or
+ // weak. The assembly is loaded into the domain of the caller.
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public static Assembly Load(AssemblyName assemblyRef)
+ {
+ Contract.Ensures(Contract.Result<Assembly>() != null);
+ Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
+
+ if (assemblyRef != null && assemblyRef.CodeBase != null)
+ {
+ throw new NotSupportedException(SR.NotSupported_AssemblyLoadCodeBase);
+ }
+
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return RuntimeAssembly.InternalLoadAssemblyName(assemblyRef, null, null, ref stackMark, true /*thrownOnFileNotFound*/, false /*forIntrospection*/);
+ }
+
+ // Locate an assembly by its name. The name can be strong or
+ // weak. The assembly is loaded into the domain of the caller.
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ internal static Assembly Load(AssemblyName assemblyRef, IntPtr ptrLoadContextBinder)
+ {
+ Contract.Ensures(Contract.Result<Assembly>() != null);
+ Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
+
+ if (assemblyRef != null && assemblyRef.CodeBase != null)
+ {
+ throw new NotSupportedException(SR.NotSupported_AssemblyLoadCodeBase);
+ }
+
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return RuntimeAssembly.InternalLoadAssemblyName(assemblyRef, null, null, ref stackMark, true /*thrownOnFileNotFound*/, false /*forIntrospection*/, ptrLoadContextBinder);
+ }
+
+ // Loads the assembly with a COFF based IMAGE containing
+ // an emitted assembly. The assembly is loaded into the domain
+ // of the caller. The second parameter is the raw bytes
+ // representing the symbol store that matches the assembly.
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public static Assembly Load(byte[] rawAssembly,
+ byte[] rawSymbolStore)
+ {
+ Contract.Ensures(Contract.Result<Assembly>() != null);
+ Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
+
+ AppDomain.CheckLoadByteArraySupported();
+
+ if (rawAssembly == null)
+ throw new ArgumentNullException(nameof(rawAssembly));
+ AssemblyLoadContext alc = new IndividualAssemblyLoadContext();
+ MemoryStream assemblyStream = new MemoryStream(rawAssembly);
+ MemoryStream symbolStream = (rawSymbolStore != null) ? new MemoryStream(rawSymbolStore) : null;
+ return alc.LoadFromStream(assemblyStream, symbolStream);
+ }
+
+ private static Dictionary<string, Assembly> s_loadfile = new Dictionary<string, Assembly>();
+
+ public static Assembly LoadFile(String path)
+ {
+ Contract.Ensures(Contract.Result<Assembly>() != null);
+ Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
+
+ AppDomain.CheckLoadFileSupported();
+
+ Assembly result = null;
+ if (path == null)
+ throw new ArgumentNullException(nameof(path));
+
+ if (PathInternal.IsPartiallyQualified(path))
+ {
+ throw new ArgumentException(SR.Argument_AbsolutePathRequired, nameof(path));
+ }
+
+ string normalizedPath = Path.GetFullPath(path);
+
+ lock (s_loadfile)
+ {
+ if (s_loadfile.TryGetValue(normalizedPath, out result))
+ return result;
+ AssemblyLoadContext alc = new IndividualAssemblyLoadContext();
+ result = alc.LoadFromAssemblyPath(normalizedPath);
+ s_loadfile.Add(normalizedPath, result);
+ }
+ return result;
+ }
+
+ /*
+ * Get the assembly that the current code is running from.
+ */
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public static Assembly GetExecutingAssembly()
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return RuntimeAssembly.GetExecutingAssembly(ref stackMark);
+ }
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public static Assembly GetCallingAssembly()
+ {
+ // LookForMyCallersCaller is not guarantee to return the correct stack frame
+ // because of inlining, tail calls, etc. As a result GetCallingAssembly is not
+ // ganranteed to return the correct result. We should document it as such.
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCallersCaller;
+ return RuntimeAssembly.GetExecutingAssembly(ref stackMark);
+ }
+
+ public static Assembly GetEntryAssembly()
+ {
+ AppDomainManager domainManager = AppDomain.CurrentDomain.DomainManager;
+ if (domainManager == null)
+ domainManager = new AppDomainManager();
+ return domainManager.EntryAssembly;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/Assembly.cs b/src/mscorlib/src/System/Reflection/Assembly.cs
deleted file mode 100644
index eaedc6ded4..0000000000
--- a/src/mscorlib/src/System/Reflection/Assembly.cs
+++ /dev/null
@@ -1,1680 +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.
-
-/*=============================================================================
-**
-**
-**
-**
-**
-**
-** Purpose: For Assembly-related stuff.
-**
-**
-=============================================================================*/
-
-namespace System.Reflection
-{
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using CultureInfo = System.Globalization.CultureInfo;
- using System.Security;
- using System.Security.Policy;
- using System.IO;
- using StringBuilder = System.Text.StringBuilder;
- using System.Configuration.Assemblies;
- using StackCrawlMark = System.Threading.StackCrawlMark;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Runtime.Serialization;
- using Microsoft.Win32;
- using System.Threading;
- using __HResults = System.__HResults;
- using System.Runtime.Versioning;
- using System.Diagnostics.Contracts;
- using System.Runtime.Loader;
-
- [Serializable]
- public delegate Module ModuleResolveEventHandler(Object sender, ResolveEventArgs e);
-
-
- [Serializable]
- public abstract class Assembly : ICustomAttributeProvider, ISerializable
- {
- protected Assembly() {}
-
-#region public static methods
-
- public static String CreateQualifiedName(String assemblyName, String typeName)
- {
- return typeName + ", " + assemblyName;
- }
-
- public static Assembly GetAssembly(Type type)
- {
- if (type == null)
- throw new ArgumentNullException(nameof(type));
- Contract.EndContractBlock();
-
- Module m = type.Module;
- if (m == null)
- return null;
- else
- return m.Assembly;
- }
-
- public static bool operator ==(Assembly left, Assembly right)
- {
- if (ReferenceEquals(left, right))
- return true;
-
- if ((object)left == null || (object)right == null ||
- left is RuntimeAssembly || right is RuntimeAssembly)
- {
- return false;
- }
- return left.Equals(right);
- }
-
- public static bool operator !=(Assembly left, Assembly right)
- {
- return !(left == right);
- }
-
- public override bool Equals(object o)
- {
- return base.Equals(o);
- }
-
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
-
- public static Assembly LoadFrom(String assemblyFile)
- {
- if(assemblyFile == null)
- throw new ArgumentNullException(nameof(assemblyFile));
- string fullPath = Path.GetFullPath(assemblyFile);
- return AssemblyLoadContext.Default.LoadFromAssemblyPath(fullPath);
- }
-
- // Locate an assembly for reflection by the name of the file containing the manifest.
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Assembly ReflectionOnlyLoadFrom(String assemblyFile)
- {
- if (assemblyFile == null)
- throw new ArgumentNullException(nameof(assemblyFile));
- if (assemblyFile.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Format_StringZeroLength"));
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReflectionOnlyLoad"));
- }
-
- // Evidence is protected in Assembly.Load()
- [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use an overload of LoadFrom which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- internal static Assembly LoadFrom(String assemblyFile,
- Evidence securityEvidence)
- {
- Contract.Ensures(Contract.Result<Assembly>() != null);
-
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
-
- return RuntimeAssembly.InternalLoadFrom(
- assemblyFile,
- securityEvidence,
- null, // hashValue
- AssemblyHashAlgorithm.None,
- false,// forIntrospection);
- ref stackMark);
- }
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Assembly LoadFrom(String assemblyFile,
- byte[] hashValue,
- AssemblyHashAlgorithm hashAlgorithm)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_AssemblyLoadFromHash"));
- }
-
- public static Assembly UnsafeLoadFrom(string assemblyFile)
- {
- return LoadFrom(assemblyFile);
- }
-
- // Locate an assembly by the long form of the assembly name.
- // eg. "Toolbox.dll, version=1.1.10.1220, locale=en, publickey=1234567890123456789012345678901234567890"
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Assembly Load(String assemblyString)
- {
- Contract.Ensures(Contract.Result<Assembly>() != null);
- Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
-
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RuntimeAssembly.InternalLoad(assemblyString, null, ref stackMark, false /*forIntrospection*/);
- }
-
- // Returns type from the assembly while keeping compatibility with Assembly.Load(assemblyString).GetType(typeName) for managed types.
- // Calls Type.GetType for WinRT types.
- // Note: Type.GetType fails for assembly names that start with weird characters like '['. By calling it for managed types we would
- // break AppCompat.
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- internal static Type GetType_Compat(String assemblyString, String typeName)
- {
- // Normally we would get the stackMark only in public APIs. This is internal API, but it is AppCompat replacement of public API
- // call Assembly.Load(assemblyString).GetType(typeName), therefore we take the stackMark here as well, to be fully compatible with
- // the call sequence.
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
-
- RuntimeAssembly assembly;
- AssemblyName assemblyName = RuntimeAssembly.CreateAssemblyName(
- assemblyString,
- false /*forIntrospection*/,
- out assembly);
-
- if (assembly == null) {
- if (assemblyName.ContentType == AssemblyContentType.WindowsRuntime) {
- return Type.GetType(typeName + ", " + assemblyString, true /*throwOnError*/, false /*ignoreCase*/);
- }
-
- assembly = RuntimeAssembly.InternalLoadAssemblyName(
- assemblyName, null, null, ref stackMark,
- true /*thrownOnFileNotFound*/, false /*forIntrospection*/);
- }
- return assembly.GetType(typeName, true /*throwOnError*/, false /*ignoreCase*/);
- }
-
- // Locate an assembly for reflection by the long form of the assembly name.
- // eg. "Toolbox.dll, version=1.1.10.1220, locale=en, publickey=1234567890123456789012345678901234567890"
- //
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Assembly ReflectionOnlyLoad(String assemblyString)
- {
- if (assemblyString == null)
- throw new ArgumentNullException(nameof(assemblyString));
- if (assemblyString.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Format_StringZeroLength"));
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReflectionOnlyLoad"));
- }
-
- // Locate an assembly by its name. The name can be strong or
- // weak. The assembly is loaded into the domain of the caller.
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Assembly Load(AssemblyName assemblyRef)
- {
- Contract.Ensures(Contract.Result<Assembly>() != null);
- Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
-
- if (assemblyRef != null && assemblyRef.CodeBase != null)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_AssemblyLoadCodeBase"));
- }
-
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RuntimeAssembly.InternalLoadAssemblyName(assemblyRef, null, null, ref stackMark, true /*thrownOnFileNotFound*/, false /*forIntrospection*/);
- }
-
- // Locate an assembly by its name. The name can be strong or
- // weak. The assembly is loaded into the domain of the caller.
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- internal static Assembly Load(AssemblyName assemblyRef, IntPtr ptrLoadContextBinder)
- {
- Contract.Ensures(Contract.Result<Assembly>() != null);
- Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
-
- if (assemblyRef != null && assemblyRef.CodeBase != null)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_AssemblyLoadCodeBase"));
- }
-
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RuntimeAssembly.InternalLoadAssemblyName(assemblyRef, null, null, ref stackMark, true /*thrownOnFileNotFound*/, false /*forIntrospection*/, ptrLoadContextBinder);
- }
-
- [Obsolete("This method has been deprecated. Please use Assembly.Load() instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- public static Assembly LoadWithPartialName(String partialName)
- {
- if(partialName == null)
- throw new ArgumentNullException(nameof(partialName));
- return Load(partialName);
- }
-
- // Loads the assembly with a COFF based IMAGE containing
- // an emitted assembly. The assembly is loaded into the domain
- // of the caller.
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Assembly Load(byte[] rawAssembly)
- {
- Contract.Ensures(Contract.Result<Assembly>() != null);
- Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
-
- AppDomain.CheckLoadByteArraySupported();
-
- return Load(rawAssembly, null);
- }
-
- // Loads the assembly for reflection with a COFF based IMAGE containing
- // an emitted assembly. The assembly is loaded into the domain
- // of the caller.
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Assembly ReflectionOnlyLoad(byte[] rawAssembly)
- {
- if (rawAssembly == null)
- throw new ArgumentNullException(nameof(rawAssembly));
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReflectionOnlyLoad"));
- }
-
- // Loads the assembly with a COFF based IMAGE containing
- // an emitted assembly. The assembly is loaded into the domain
- // of the caller. The second parameter is the raw bytes
- // representing the symbol store that matches the assembly.
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Assembly Load(byte[] rawAssembly,
- byte[] rawSymbolStore)
- {
- Contract.Ensures(Contract.Result<Assembly>() != null);
- Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
-
- AppDomain.CheckLoadByteArraySupported();
-
- if(rawAssembly == null)
- throw new ArgumentNullException(nameof(rawAssembly));
- AssemblyLoadContext alc = new IndividualAssemblyLoadContext();
- MemoryStream assemblyStream = new MemoryStream(rawAssembly);
- MemoryStream symbolStream = (rawSymbolStore!=null)?new MemoryStream(rawSymbolStore):null;
- return alc.LoadFromStream(assemblyStream, symbolStream);
- }
-
- private static Dictionary<string, Assembly> s_loadfile = new Dictionary<string, Assembly>();
-
- public static Assembly LoadFile(String path)
- {
- Contract.Ensures(Contract.Result<Assembly>() != null);
- Contract.Ensures(!Contract.Result<Assembly>().ReflectionOnly);
-
- AppDomain.CheckLoadFileSupported();
-
- Assembly result = null;
- if(path == null)
- throw new ArgumentNullException(nameof(path));
-
- if (PathInternal.IsPartiallyQualified(path))
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_AbsolutePathRequired"), nameof(path));
- }
-
- string normalizedPath = Path.GetFullPath(path);
-
- lock(s_loadfile)
- {
- if(s_loadfile.TryGetValue(normalizedPath, out result))
- return result;
- AssemblyLoadContext alc = new IndividualAssemblyLoadContext();
- result = alc.LoadFromAssemblyPath(normalizedPath);
- s_loadfile.Add(normalizedPath, result);
- }
- return result;
- }
-
- /*
- * Get the assembly that the current code is running from.
- */
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Assembly GetExecutingAssembly()
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RuntimeAssembly.GetExecutingAssembly(ref stackMark);
- }
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Assembly GetCallingAssembly()
- {
- // LookForMyCallersCaller is not guarantee to return the correct stack frame
- // because of inlining, tail calls, etc. As a result GetCallingAssembly is not
- // ganranteed to return the correct result. We should document it as such.
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCallersCaller;
- return RuntimeAssembly.GetExecutingAssembly(ref stackMark);
- }
-
- public static Assembly GetEntryAssembly() {
- AppDomainManager domainManager = AppDomain.CurrentDomain.DomainManager;
- if (domainManager == null)
- domainManager = new AppDomainManager();
- return domainManager.EntryAssembly;
- }
-
-#endregion // public static methods
-
-#region public methods
- public virtual event ModuleResolveEventHandler ModuleResolve
- {
- add
- {
- throw new NotImplementedException();
- }
- remove
- {
- throw new NotImplementedException();
- }
- }
-
- public virtual String CodeBase
- {
- get
- {
- throw new NotImplementedException();
- }
- }
-
- public virtual String EscapedCodeBase
- {
- get
- {
- return AssemblyName.EscapeCodeBase(CodeBase);
- }
- }
-
- public virtual AssemblyName GetName()
- {
- return GetName(false);
- }
-
- public virtual AssemblyName GetName(bool copiedName)
- {
- throw new NotImplementedException();
- }
-
- public virtual String FullName
- {
- get
- {
- throw new NotImplementedException();
- }
- }
-
- public virtual MethodInfo EntryPoint
- {
- get
- {
- throw new NotImplementedException();
- }
- }
-
- public virtual Type GetType(String name)
- {
- return GetType(name, false, false);
- }
-
- public virtual Type GetType(String name, bool throwOnError)
- {
- return GetType(name, throwOnError, false);
- }
-
- public virtual Type GetType(String name, bool throwOnError, bool ignoreCase)
- {
- throw new NotImplementedException();
- }
-
- public virtual IEnumerable<Type> ExportedTypes
- {
- get
- {
- return GetExportedTypes();
- }
- }
-
- public virtual Type[] GetExportedTypes()
- {
- throw new NotImplementedException();
- }
-
- public virtual IEnumerable<TypeInfo> DefinedTypes
- {
- get
- {
- Type[] types = GetTypes();
-
- TypeInfo[] typeinfos = new TypeInfo[types.Length];
-
- for (int i = 0; i < types.Length; i++)
- {
-
- TypeInfo typeinfo = types[i].GetTypeInfo();
- if (typeinfo == null)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NoTypeInfo", types[i].FullName));
-
- typeinfos[i] = typeinfo;
- }
-
- return typeinfos;
- }
- }
-
- public virtual Type[] GetTypes()
- {
- Module[] m = GetModules(false);
-
- int iFinalLength = 0;
- Type[][] ModuleTypes = new Type[m.Length][];
-
- for (int i = 0; i < ModuleTypes.Length; i++)
- {
- ModuleTypes[i] = m[i].GetTypes();
- iFinalLength += ModuleTypes[i].Length;
- }
-
- int iCurrent = 0;
- Type[] ret = new Type[iFinalLength];
- for (int i = 0; i < ModuleTypes.Length; i++)
- {
- int iLength = ModuleTypes[i].Length;
- Array.Copy(ModuleTypes[i], 0, ret, iCurrent, iLength);
- iCurrent += iLength;
- }
-
- return ret;
- }
-
- // Load a resource based on the NameSpace of the type.
- public virtual Stream GetManifestResourceStream(Type type, String name)
- {
- throw new NotImplementedException();
- }
-
- public virtual Stream GetManifestResourceStream(String name)
- {
- throw new NotImplementedException();
- }
-
- public virtual Assembly GetSatelliteAssembly(CultureInfo culture)
- {
- throw new NotImplementedException();
- }
-
- // Useful for binding to a very specific version of a satellite assembly
- public virtual Assembly GetSatelliteAssembly(CultureInfo culture, Version version)
- {
- throw new NotImplementedException();
- }
-
- public bool IsFullyTrusted
- {
- get
- {
- return true;
- }
- }
-
- public virtual SecurityRuleSet SecurityRuleSet
- {
- get
- {
- return SecurityRuleSet.None;
- }
- }
-
- // ISerializable implementation
- public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- throw new NotImplementedException();
- }
-
- public virtual Module ManifestModule
- {
- get
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeAssembly rtAssembly = this as RuntimeAssembly;
- if (rtAssembly != null)
- return rtAssembly.ManifestModule;
-
- throw new NotImplementedException();
- }
- }
-
- public virtual IEnumerable<CustomAttributeData> CustomAttributes
- {
- get
- {
- return GetCustomAttributesData();
- }
- }
- public virtual Object[] GetCustomAttributes(bool inherit)
- {
- Contract.Ensures(Contract.Result<Object[]>() != null);
- throw new NotImplementedException();
- }
-
- public virtual Object[] GetCustomAttributes(Type attributeType, bool inherit)
- {
- Contract.Ensures(Contract.Result<Object[]>() != null);
- throw new NotImplementedException();
- }
-
- public virtual bool IsDefined(Type attributeType, bool inherit)
- {
- throw new NotImplementedException();
- }
-
- public virtual IList<CustomAttributeData> GetCustomAttributesData()
- {
- throw new NotImplementedException();
- }
-
- public virtual bool ReflectionOnly
- {
- get
- {
- throw new NotImplementedException();
- }
- }
-
- public Module LoadModule(String moduleName,
- byte[] rawModule)
- {
- return LoadModule(moduleName, rawModule, null);
- }
-
- public virtual Module LoadModule(String moduleName,
- byte[] rawModule,
- byte[] rawSymbolStore)
- {
- throw new NotImplementedException();
- }
-
- //
- // Locates a type from this assembly and creates an instance of it using
- // the system activator.
- //
- public Object CreateInstance(String typeName)
- {
- return CreateInstance(typeName,
- false, // ignore case
- BindingFlags.Public | BindingFlags.Instance,
- null, // binder
- null, // args
- null, // culture
- null); // activation attributes
- }
-
- public Object CreateInstance(String typeName,
- bool ignoreCase)
- {
- return CreateInstance(typeName,
- ignoreCase,
- BindingFlags.Public | BindingFlags.Instance,
- null, // binder
- null, // args
- null, // culture
- null); // activation attributes
- }
-
- public virtual Object CreateInstance(String typeName,
- bool ignoreCase,
- BindingFlags bindingAttr,
- Binder binder,
- Object[] args,
- CultureInfo culture,
- Object[] activationAttributes)
- {
- Type t = GetType(typeName, false, ignoreCase);
- if (t == null) return null;
- return Activator.CreateInstance(t,
- bindingAttr,
- binder,
- args,
- culture,
- activationAttributes);
- }
-
- public virtual IEnumerable<Module> Modules
- {
- get
- {
- return GetLoadedModules(true);
- }
- }
-
- public Module[] GetLoadedModules()
- {
- return GetLoadedModules(false);
- }
-
- public virtual Module[] GetLoadedModules(bool getResourceModules)
- {
- throw new NotImplementedException();
- }
-
- public Module[] GetModules()
- {
- return GetModules(false);
- }
-
- public virtual Module[] GetModules(bool getResourceModules)
- {
- throw new NotImplementedException();
- }
-
- public virtual Module GetModule(String name)
- {
- throw new NotImplementedException();
- }
-
- // Returns the file in the File table of the manifest that matches the
- // given name. (Name should not include path.)
- public virtual FileStream GetFile(String name)
- {
- throw new NotImplementedException();
- }
-
- public virtual FileStream[] GetFiles()
- {
- return GetFiles(false);
- }
-
- public virtual FileStream[] GetFiles(bool getResourceModules)
- {
- throw new NotImplementedException();
- }
-
- // Returns the names of all the resources
- public virtual String[] GetManifestResourceNames()
- {
- throw new NotImplementedException();
- }
-
- public virtual AssemblyName[] GetReferencedAssemblies()
- {
- throw new NotImplementedException();
- }
-
- public virtual ManifestResourceInfo GetManifestResourceInfo(String resourceName)
- {
- throw new NotImplementedException();
- }
-
- public override String ToString()
- {
- String displayName = FullName;
- if (displayName == null)
- return base.ToString();
- else
- return displayName;
- }
-
- public virtual String Location
- {
- get
- {
- throw new NotImplementedException();
- }
- }
-
- public virtual String ImageRuntimeVersion
- {
- get
- {
- throw new NotImplementedException();
- }
- }
-
- /*
- Returns true if the assembly was loaded from the global assembly cache.
- */
- public virtual bool GlobalAssemblyCache
- {
- get
- {
- throw new NotImplementedException();
- }
- }
-
- public virtual Int64 HostContext
- {
- get
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeAssembly rtAssembly = this as RuntimeAssembly;
- if (rtAssembly != null)
- return rtAssembly.HostContext;
-
- throw new NotImplementedException();
- }
- }
-
- public virtual bool IsDynamic
- {
- get
- {
- return false;
- }
- }
-#endregion // public methods
-
- }
-
- [Serializable]
- internal class RuntimeAssembly : Assembly
- {
-#if FEATURE_APPX
- // The highest byte is the flags and the lowest 3 bytes are
- // the cached ctor token of [DynamicallyInvocableAttribute].
- private enum ASSEMBLY_FLAGS : uint
- {
- ASSEMBLY_FLAGS_UNKNOWN = 0x00000000,
- ASSEMBLY_FLAGS_INITIALIZED = 0x01000000,
- ASSEMBLY_FLAGS_FRAMEWORK = 0x02000000,
- ASSEMBLY_FLAGS_SAFE_REFLECTION = 0x04000000,
- ASSEMBLY_FLAGS_TOKEN_MASK = 0x00FFFFFF,
- }
-#endif // FEATURE_APPX
-
- private const uint COR_E_LOADING_REFERENCE_ASSEMBLY = 0x80131058U;
-
- internal RuntimeAssembly() { throw new NotSupportedException(); }
-
-#region private data members
- private event ModuleResolveEventHandler _ModuleResolve;
- private string m_fullname;
- private object m_syncRoot; // Used to keep collectible types alive and as the syncroot for reflection.emit
- private IntPtr m_assembly; // slack for ptr datum on unmanaged side
-
-#if FEATURE_APPX
- private ASSEMBLY_FLAGS m_flags;
-#endif
-#endregion
-
-#if FEATURE_APPX
- internal int InvocableAttributeCtorToken
- {
- get
- {
- int token = (int)(Flags & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_TOKEN_MASK);
-
- return token | (int)MetadataTokenType.MethodDef;
- }
- }
-
- private ASSEMBLY_FLAGS Flags
- {
- get
- {
- if ((m_flags & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_INITIALIZED) == 0)
- {
- ASSEMBLY_FLAGS flags = ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_UNKNOWN
- | ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_FRAMEWORK | ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_SAFE_REFLECTION;
-
- m_flags = flags | ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_INITIALIZED;
- }
-
- return m_flags;
- }
- }
-#endif // FEATURE_APPX
-
- internal object SyncRoot
- {
- get
- {
- if (m_syncRoot == null)
- {
- Interlocked.CompareExchange<object>(ref m_syncRoot, new object(), null);
- }
- return m_syncRoot;
- }
- }
-
- public override event ModuleResolveEventHandler ModuleResolve
- {
- add
- {
- _ModuleResolve += value;
- }
- remove
- {
- _ModuleResolve -= value;
- }
- }
-
- private const String s_localFilePrefix = "file:";
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern void GetCodeBase(RuntimeAssembly assembly,
- bool copiedName,
- StringHandleOnStack retString);
-
- internal String GetCodeBase(bool copiedName)
- {
- String codeBase = null;
- GetCodeBase(GetNativeHandle(), copiedName, JitHelpers.GetStringHandleOnStack(ref codeBase));
- return codeBase;
- }
-
- public override String CodeBase
- {
- get {
- String codeBase = GetCodeBase(false);
- return codeBase;
- }
- }
-
- internal RuntimeAssembly GetNativeHandle()
- {
- return this;
- }
-
- // If the assembly is copied before it is loaded, the codebase will be set to the
- // actual file loaded if copiedName is true. If it is false, then the original code base
- // is returned.
- public override AssemblyName GetName(bool copiedName)
- {
- AssemblyName an = new AssemblyName();
-
- String codeBase = GetCodeBase(copiedName);
-
- an.Init(GetSimpleName(),
- GetPublicKey(),
- null, // public key token
- GetVersion(),
- GetLocale(),
- GetHashAlgorithm(),
- AssemblyVersionCompatibility.SameMachine,
- codeBase,
- GetFlags() | AssemblyNameFlags.PublicKey,
- null); // strong name key pair
-
- PortableExecutableKinds pek;
- ImageFileMachine ifm;
-
- Module manifestModule = ManifestModule;
- if (manifestModule != null)
- {
- if (manifestModule.MDStreamVersion > 0x10000)
- {
- ManifestModule.GetPEKind(out pek, out ifm);
- an.SetProcArchIndex(pek,ifm);
- }
- }
- return an;
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private extern static void GetFullName(RuntimeAssembly assembly, StringHandleOnStack retString);
-
- public override String FullName
- {
- get {
- // If called by Object.ToString(), return val may be NULL.
- if (m_fullname == null)
- {
- string s = null;
- GetFullName(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref s));
- Interlocked.CompareExchange<string>(ref m_fullname, s, null);
- }
-
- return m_fullname;
- }
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern void GetEntryPoint(RuntimeAssembly assembly, ObjectHandleOnStack retMethod);
-
- public override MethodInfo EntryPoint
- {
- get {
- IRuntimeMethodInfo methodHandle = null;
- GetEntryPoint(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref methodHandle));
-
- if (methodHandle == null)
- return null;
-
- return (MethodInfo)RuntimeType.GetMethodBase(methodHandle);
- }
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern void GetType(RuntimeAssembly assembly,
- String name,
- bool throwOnError,
- bool ignoreCase,
- ObjectHandleOnStack type,
- ObjectHandleOnStack keepAlive);
-
- public override Type GetType(String name, bool throwOnError, bool ignoreCase)
- {
- // throw on null strings regardless of the value of "throwOnError"
- if (name == null)
- throw new ArgumentNullException(nameof(name));
-
- RuntimeType type = null;
- Object keepAlive = null;
- GetType(GetNativeHandle(), name, throwOnError, ignoreCase, JitHelpers.GetObjectHandleOnStack(ref type), JitHelpers.GetObjectHandleOnStack(ref keepAlive));
- GC.KeepAlive(keepAlive);
-
- return type;
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private extern static void GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes);
-
- public override Type[] GetExportedTypes()
- {
- Type[] types = null;
- GetExportedTypes(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref types));
- return types;
- }
-
- public override IEnumerable<TypeInfo> DefinedTypes
- {
- get
- {
- List<RuntimeType> rtTypes = new List<RuntimeType>();
-
- RuntimeModule[] modules = GetModulesInternal(true, false);
-
- for (int i = 0; i < modules.Length; i++)
- {
- rtTypes.AddRange(modules[i].GetDefinedTypes());
- }
-
- return rtTypes.ToArray();
- }
- }
-
- // Load a resource based on the NameSpace of the type.
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public override Stream GetManifestResourceStream(Type type, String name)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return GetManifestResourceStream(type, name, false, ref stackMark);
- }
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public override Stream GetManifestResourceStream(String name)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return GetManifestResourceStream(name, ref stackMark, false);
- }
-
- // ISerializable implementation
- public override void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- if (info==null)
- throw new ArgumentNullException(nameof(info));
-
- Contract.EndContractBlock();
-
- UnitySerializationHolder.GetUnitySerializationInfo(info,
- UnitySerializationHolder.AssemblyUnity,
- this.FullName,
- this);
- }
-
- public override Module ManifestModule
- {
- get
- {
- // We don't need to return the "external" ModuleBuilder because
- // it is meant to be read-only
- return RuntimeAssembly.GetManifestModule(GetNativeHandle());
- }
- }
-
- public override Object[] GetCustomAttributes(bool inherit)
- {
- return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
- }
-
- public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
-
- return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
- }
-
- public override bool IsDefined(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
-
- return CustomAttribute.IsDefined(this, attributeRuntimeType);
- }
-
- public override IList<CustomAttributeData> GetCustomAttributesData()
- {
- return CustomAttributeData.GetCustomAttributesInternal(this);
- }
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- internal static RuntimeAssembly InternalLoadFrom(String assemblyFile,
- Evidence securityEvidence,
- byte[] hashValue,
- AssemblyHashAlgorithm hashAlgorithm,
- bool forIntrospection,
- ref StackCrawlMark stackMark)
- {
- if (assemblyFile == null)
- throw new ArgumentNullException(nameof(assemblyFile));
-
- Contract.EndContractBlock();
-
- AssemblyName an = new AssemblyName();
- an.CodeBase = assemblyFile;
- an.SetHashControl(hashValue, hashAlgorithm);
- // The stack mark is used for MDA filtering
- return InternalLoadAssemblyName(an, securityEvidence, null, ref stackMark, true /*thrownOnFileNotFound*/, forIntrospection);
- }
-
- // Wrapper function to wrap the typical use of InternalLoad.
- internal static RuntimeAssembly InternalLoad(String assemblyString,
- Evidence assemblySecurity,
- ref StackCrawlMark stackMark,
- bool forIntrospection)
- {
- return InternalLoad(assemblyString, assemblySecurity, ref stackMark, IntPtr.Zero, forIntrospection);
- }
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- internal static RuntimeAssembly InternalLoad(String assemblyString,
- Evidence assemblySecurity,
- ref StackCrawlMark stackMark,
- IntPtr pPrivHostBinder,
- bool forIntrospection)
- {
- RuntimeAssembly assembly;
- AssemblyName an = CreateAssemblyName(assemblyString, forIntrospection, out assembly);
-
- if (assembly != null) {
- // The assembly was returned from ResolveAssemblyEvent
- return assembly;
- }
-
- return InternalLoadAssemblyName(an, assemblySecurity, null, ref stackMark,
- pPrivHostBinder,
- true /*thrownOnFileNotFound*/, forIntrospection);
- }
-
- // Creates AssemblyName. Fills assembly if AssemblyResolve event has been raised.
- internal static AssemblyName CreateAssemblyName(
- String assemblyString,
- bool forIntrospection,
- out RuntimeAssembly assemblyFromResolveEvent)
- {
- if (assemblyString == null)
- throw new ArgumentNullException(nameof(assemblyString));
- Contract.EndContractBlock();
-
- if ((assemblyString.Length == 0) ||
- (assemblyString[0] == '\0'))
- throw new ArgumentException(Environment.GetResourceString("Format_StringZeroLength"));
-
- if (forIntrospection)
- AppDomain.CheckReflectionOnlyLoadSupported();
-
- AssemblyName an = new AssemblyName();
-
- an.Name = assemblyString;
- an.nInit(out assemblyFromResolveEvent, forIntrospection, true);
-
- return an;
- }
-
- // Wrapper function to wrap the typical use of InternalLoadAssemblyName.
- internal static RuntimeAssembly InternalLoadAssemblyName(
- AssemblyName assemblyRef,
- Evidence assemblySecurity,
- RuntimeAssembly reqAssembly,
- ref StackCrawlMark stackMark,
- bool throwOnFileNotFound,
- bool forIntrospection,
- IntPtr ptrLoadContextBinder = default(IntPtr))
- {
- return InternalLoadAssemblyName(assemblyRef, assemblySecurity, reqAssembly, ref stackMark, IntPtr.Zero, true /*throwOnError*/, forIntrospection, ptrLoadContextBinder);
- }
-
- internal static RuntimeAssembly InternalLoadAssemblyName(
- AssemblyName assemblyRef,
- Evidence assemblySecurity,
- RuntimeAssembly reqAssembly,
- ref StackCrawlMark stackMark,
- IntPtr pPrivHostBinder,
- bool throwOnFileNotFound,
- bool forIntrospection,
- IntPtr ptrLoadContextBinder = default(IntPtr))
- {
-
- if (assemblyRef == null)
- throw new ArgumentNullException(nameof(assemblyRef));
- Contract.EndContractBlock();
-
- if (assemblyRef.CodeBase != null)
- {
- AppDomain.CheckLoadFromSupported();
- }
-
- assemblyRef = (AssemblyName)assemblyRef.Clone();
- if (!forIntrospection &&
- (assemblyRef.ProcessorArchitecture != ProcessorArchitecture.None)) {
- // PA does not have a semantics for by-name binds for execution
- assemblyRef.ProcessorArchitecture = ProcessorArchitecture.None;
- }
-
- String codeBase = VerifyCodeBase(assemblyRef.CodeBase);
-
- return nLoad(assemblyRef, codeBase, assemblySecurity, reqAssembly, ref stackMark,
- pPrivHostBinder,
- throwOnFileNotFound, forIntrospection, ptrLoadContextBinder);
- }
-
- // These are the framework assemblies that does reflection invocation
- // on behalf of user code. We allow framework code to invoke non-W8P
- // framework APIs but don't want user code to gain that privilege
- // through these assemblies. So we blaklist them.
- static string[] s_unsafeFrameworkAssemblyNames = new string[] {
- "System.Reflection.Context",
- "Microsoft.VisualBasic"
- };
-
-#if FEATURE_APPX
- internal bool IsFrameworkAssembly()
- {
- ASSEMBLY_FLAGS flags = Flags;
- return (flags & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_FRAMEWORK) != 0;
- }
-
- // Returns true if we want to allow this assembly to invoke non-W8P
- // framework APIs through reflection.
- internal bool IsSafeForReflection()
- {
- ASSEMBLY_FLAGS flags = Flags;
- return (flags & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_SAFE_REFLECTION) != 0;
- }
-#endif
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern RuntimeAssembly _nLoad(AssemblyName fileName,
- String codeBase,
- Evidence assemblySecurity,
- RuntimeAssembly locationHint,
- ref StackCrawlMark stackMark,
- IntPtr pPrivHostBinder,
- bool throwOnFileNotFound,
- bool forIntrospection,
- bool suppressSecurityChecks,
- IntPtr ptrLoadContextBinder);
-
- private static RuntimeAssembly nLoad(AssemblyName fileName,
- String codeBase,
- Evidence assemblySecurity,
- RuntimeAssembly locationHint,
- ref StackCrawlMark stackMark,
- IntPtr pPrivHostBinder,
- bool throwOnFileNotFound,
- bool forIntrospection,
- IntPtr ptrLoadContextBinder = default(IntPtr))
- {
- return _nLoad(fileName, codeBase, assemblySecurity, locationHint, ref stackMark,
- pPrivHostBinder,
- throwOnFileNotFound, forIntrospection, true /* suppressSecurityChecks */, ptrLoadContextBinder);
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern bool IsReflectionOnly(RuntimeAssembly assembly);
-
- public override bool ReflectionOnly
- {
- get
- {
- return IsReflectionOnly(GetNativeHandle());
- }
- }
-
- // Returns the module in this assembly with name 'name'
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern void GetModule(RuntimeAssembly assembly, String name, ObjectHandleOnStack retModule);
-
- public override Module GetModule(String name)
- {
- Module retModule = null;
- GetModule(GetNativeHandle(), name, JitHelpers.GetObjectHandleOnStack(ref retModule));
- return retModule;
- }
-
- // Returns the file in the File table of the manifest that matches the
- // given name. (Name should not include path.)
- public override FileStream GetFile(String name)
- {
- RuntimeModule m = (RuntimeModule)GetModule(name);
- if (m == null)
- return null;
-
- return new FileStream(m.GetFullyQualifiedName(),
- FileMode.Open,
- FileAccess.Read, FileShare.Read, FileStream.DefaultBufferSize, false);
- }
-
- public override FileStream[] GetFiles(bool getResourceModules)
- {
- Module[] m = GetModules(getResourceModules);
- FileStream[] fs = new FileStream[m.Length];
-
- for (int i = 0; i < fs.Length; i++)
- {
- fs[i] = new FileStream(((RuntimeModule)m[i]).GetFullyQualifiedName(),
- FileMode.Open,
- FileAccess.Read, FileShare.Read, FileStream.DefaultBufferSize, false);
- }
-
- return fs;
- }
-
- // Returns the names of all the resources
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern String[] GetManifestResourceNames(RuntimeAssembly assembly);
-
- // Returns the names of all the resources
- public override String[] GetManifestResourceNames()
- {
- return GetManifestResourceNames(GetNativeHandle());
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private extern static void GetExecutingAssembly(StackCrawlMarkHandle stackMark, ObjectHandleOnStack retAssembly);
-
- internal static RuntimeAssembly GetExecutingAssembly(ref StackCrawlMark stackMark)
- {
- RuntimeAssembly retAssembly = null;
- GetExecutingAssembly(JitHelpers.GetStackCrawlMarkHandle(ref stackMark), JitHelpers.GetObjectHandleOnStack(ref retAssembly));
- return retAssembly;
- }
-
- // Returns the names of all the resources
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern AssemblyName[] GetReferencedAssemblies(RuntimeAssembly assembly);
-
- public override AssemblyName[] GetReferencedAssemblies()
- {
- return GetReferencedAssemblies(GetNativeHandle());
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern int GetManifestResourceInfo(RuntimeAssembly assembly,
- String resourceName,
- ObjectHandleOnStack assemblyRef,
- StringHandleOnStack retFileName,
- StackCrawlMarkHandle stackMark);
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public override ManifestResourceInfo GetManifestResourceInfo(String resourceName)
- {
- RuntimeAssembly retAssembly = null;
- String fileName = null;
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- int location = GetManifestResourceInfo(GetNativeHandle(), resourceName,
- JitHelpers.GetObjectHandleOnStack(ref retAssembly),
- JitHelpers.GetStringHandleOnStack(ref fileName),
- JitHelpers.GetStackCrawlMarkHandle(ref stackMark));
-
- if (location == -1)
- return null;
-
- return new ManifestResourceInfo(retAssembly, fileName,
- (ResourceLocation) location);
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern void GetLocation(RuntimeAssembly assembly, StringHandleOnStack retString);
-
- public override String Location
- {
- get {
- String location = null;
-
- GetLocation(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref location));
-
- return location;
- }
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private extern static void GetImageRuntimeVersion(RuntimeAssembly assembly, StringHandleOnStack retString);
-
- public override String ImageRuntimeVersion
- {
- get{
- String s = null;
- GetImageRuntimeVersion(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref s));
- return s;
- }
- }
-
- public override bool GlobalAssemblyCache
- {
- get
- {
- return false;
- }
- }
-
- public override Int64 HostContext
- {
- get
- {
- return 0;
- }
- }
-
- private static String VerifyCodeBase(String codebase)
- {
- if(codebase == null)
- return null;
-
- int len = codebase.Length;
- if (len == 0)
- return null;
-
-
- int j = codebase.IndexOf(':');
- // Check to see if the url has a prefix
- if( (j != -1) &&
- (j+2 < len) &&
- ((codebase[j+1] == '/') || (codebase[j+1] == '\\')) &&
- ((codebase[j+2] == '/') || (codebase[j+2] == '\\')) )
- return codebase;
-#if !PLATFORM_UNIX
- else if ((len > 2) && (codebase[0] == '\\') && (codebase[1] == '\\'))
- return "file://" + codebase;
- else
- return "file:///" + Path.GetFullPath(codebase);
-#else
- else
- return "file://" + Path.GetFullPath(codebase);
-#endif // !PLATFORM_UNIX
- }
-
- internal Stream GetManifestResourceStream(
- Type type,
- String name,
- bool skipSecurityCheck,
- ref StackCrawlMark stackMark)
- {
- StringBuilder sb = new StringBuilder();
- if(type == null) {
- if (name == null)
- throw new ArgumentNullException(nameof(type));
- }
- else {
- String nameSpace = type.Namespace;
- if(nameSpace != null) {
- sb.Append(nameSpace);
- if(name != null)
- sb.Append(Type.Delimiter);
- }
- }
-
- if(name != null)
- sb.Append(name);
-
- return GetManifestResourceStream(sb.ToString(), ref stackMark, skipSecurityCheck);
- }
-
- // GetResource will return a pointer to the resources in memory.
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static unsafe extern byte* GetResource(RuntimeAssembly assembly,
- String resourceName,
- out ulong length,
- StackCrawlMarkHandle stackMark,
- bool skipSecurityCheck);
-
- internal unsafe Stream GetManifestResourceStream(String name, ref StackCrawlMark stackMark, bool skipSecurityCheck)
- {
- ulong length = 0;
- byte* pbInMemoryResource = GetResource(GetNativeHandle(), name, out length, JitHelpers.GetStackCrawlMarkHandle(ref stackMark), skipSecurityCheck);
-
- if (pbInMemoryResource != null) {
- //Console.WriteLine("Creating an unmanaged memory stream of length "+length);
- if (length > Int64.MaxValue)
- throw new NotImplementedException(Environment.GetResourceString("NotImplemented_ResourcesLongerThan2^63"));
-
- return new UnmanagedMemoryStream(pbInMemoryResource, (long)length, (long)length, FileAccess.Read);
- }
-
- //Console.WriteLine("GetManifestResourceStream: Blob "+name+" not found...");
- return null;
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern void GetVersion(RuntimeAssembly assembly,
- out int majVer,
- out int minVer,
- out int buildNum,
- out int revNum);
-
- internal Version GetVersion()
- {
- int majorVer, minorVer, build, revision;
- GetVersion(GetNativeHandle(), out majorVer, out minorVer, out build, out revision);
- return new Version (majorVer, minorVer, build, revision);
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern void GetLocale(RuntimeAssembly assembly, StringHandleOnStack retString);
-
- internal CultureInfo GetLocale()
- {
- String locale = null;
-
- GetLocale(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref locale));
-
- if (locale == null)
- return CultureInfo.InvariantCulture;
-
- return new CultureInfo(locale);
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern bool FCallIsDynamic(RuntimeAssembly assembly);
-
- public override bool IsDynamic
- {
- get {
- return FCallIsDynamic(GetNativeHandle());
- }
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern void GetSimpleName(RuntimeAssembly assembly, StringHandleOnStack retSimpleName);
-
- internal String GetSimpleName()
- {
- string name = null;
- GetSimpleName(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref name));
- return name;
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private extern static AssemblyHashAlgorithm GetHashAlgorithm(RuntimeAssembly assembly);
-
- private AssemblyHashAlgorithm GetHashAlgorithm()
- {
- return GetHashAlgorithm(GetNativeHandle());
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private extern static AssemblyNameFlags GetFlags(RuntimeAssembly assembly);
-
- private AssemblyNameFlags GetFlags()
- {
- return GetFlags(GetNativeHandle());
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern void GetPublicKey(RuntimeAssembly assembly, ObjectHandleOnStack retPublicKey);
-
- internal byte[] GetPublicKey()
- {
- byte[] publicKey = null;
- GetPublicKey(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref publicKey));
- return publicKey;
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- [return: MarshalAs(UnmanagedType.Bool)]
- private extern static bool IsAllSecurityTransparent(RuntimeAssembly assembly);
-
- // Is everything introduced by this assembly transparent
- internal bool IsAllSecurityTransparent()
- {
- return IsAllSecurityTransparent(GetNativeHandle());
- }
-
- // This method is called by the VM.
- private RuntimeModule OnModuleResolveEvent(String moduleName)
- {
- ModuleResolveEventHandler moduleResolve = _ModuleResolve;
- if (moduleResolve == null)
- return null;
-
- Delegate[] ds = moduleResolve.GetInvocationList();
- int len = ds.Length;
- for (int i = 0; i < len; i++) {
- RuntimeModule ret = (RuntimeModule)((ModuleResolveEventHandler) ds[i])(this, new ResolveEventArgs(moduleName,this));
- if (ret != null)
- return ret;
- }
-
- return null;
- }
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public override Assembly GetSatelliteAssembly(CultureInfo culture)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return InternalGetSatelliteAssembly(culture, null, ref stackMark);
- }
-
- // Useful for binding to a very specific version of a satellite assembly
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public override Assembly GetSatelliteAssembly(CultureInfo culture, Version version)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return InternalGetSatelliteAssembly(culture, version, ref stackMark);
- }
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- internal Assembly InternalGetSatelliteAssembly(CultureInfo culture,
- Version version,
- ref StackCrawlMark stackMark)
- {
- if (culture == null)
- throw new ArgumentNullException(nameof(culture));
- Contract.EndContractBlock();
-
-
- String name = GetSimpleName() + ".resources";
- return InternalGetSatelliteAssembly(name, culture, version, true, ref stackMark);
- }
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- internal RuntimeAssembly InternalGetSatelliteAssembly(String name,
- CultureInfo culture,
- Version version,
- bool throwOnFileNotFound,
- ref StackCrawlMark stackMark)
- {
-
- AssemblyName an = new AssemblyName();
-
- an.SetPublicKey(GetPublicKey());
- an.Flags = GetFlags() | AssemblyNameFlags.PublicKey;
-
- if (version == null)
- an.Version = GetVersion();
- else
- an.Version = version;
-
- an.CultureInfo = culture;
- an.Name = name;
-
- RuntimeAssembly retAssembly = nLoad(an, null, null, this, ref stackMark,
- IntPtr.Zero,
- throwOnFileNotFound, false);
-
- if (retAssembly == this || (retAssembly == null && throwOnFileNotFound))
- {
- throw new FileNotFoundException(String.Format(culture, Environment.GetResourceString("IO.FileNotFound_FileName"), an.Name));
- }
-
- return retAssembly;
- }
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private extern static void GetModules(RuntimeAssembly assembly,
- bool loadIfNotFound,
- bool getResourceModules,
- ObjectHandleOnStack retModuleHandles);
-
- private RuntimeModule[] GetModulesInternal(bool loadIfNotFound,
- bool getResourceModules)
- {
- RuntimeModule[] modules = null;
- GetModules(GetNativeHandle(), loadIfNotFound, getResourceModules, JitHelpers.GetObjectHandleOnStack(ref modules));
- return modules;
- }
-
- public override Module[] GetModules(bool getResourceModules)
- {
- return GetModulesInternal(true, getResourceModules);
- }
-
- public override Module[] GetLoadedModules(bool getResourceModules)
- {
- return GetModulesInternal(false, getResourceModules);
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern RuntimeModule GetManifestModule(RuntimeAssembly assembly);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern int GetToken(RuntimeAssembly assembly);
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/AssemblyAttributes.cs b/src/mscorlib/src/System/Reflection/AssemblyAttributes.cs
deleted file mode 100644
index 1e6688d1f4..0000000000
--- a/src/mscorlib/src/System/Reflection/AssemblyAttributes.cs
+++ /dev/null
@@ -1,387 +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.
-
-/*=============================================================================
-**
-**
-**
-**
-**
-** Purpose: For Assembly-related custom attributes.
-**
-**
-=============================================================================*/
-
-namespace System.Reflection {
-
- using System;
- using System.Configuration.Assemblies;
- using System.Diagnostics.Contracts;
-
- [AttributeUsage (AttributeTargets.Assembly, Inherited=false)]
- public sealed class AssemblyCopyrightAttribute : Attribute
- {
- private String m_copyright;
-
- public AssemblyCopyrightAttribute(String copyright)
- {
- m_copyright = copyright;
- }
-
- public String Copyright
- {
- get { return m_copyright; }
- }
- }
-
-
- [AttributeUsage (AttributeTargets.Assembly, Inherited=false)]
- public sealed class AssemblyTrademarkAttribute : Attribute
- {
- private String m_trademark;
-
- public AssemblyTrademarkAttribute(String trademark)
- {
- m_trademark = trademark;
- }
-
- public String Trademark
- {
- get { return m_trademark; }
- }
- }
-
-
- [AttributeUsage (AttributeTargets.Assembly, Inherited=false)]
- public sealed class AssemblyProductAttribute : Attribute
- {
- private String m_product;
-
- public AssemblyProductAttribute(String product)
- {
- m_product = product;
- }
-
- public String Product
- {
- get { return m_product; }
- }
- }
-
-
- [AttributeUsage (AttributeTargets.Assembly, Inherited=false)]
- public sealed class AssemblyCompanyAttribute : Attribute
- {
- private String m_company;
-
- public AssemblyCompanyAttribute(String company)
- {
- m_company = company;
- }
-
- public String Company
- {
- get { return m_company; }
- }
- }
-
-
- [AttributeUsage (AttributeTargets.Assembly, Inherited=false)]
- public sealed class AssemblyDescriptionAttribute : Attribute
- {
- private String m_description;
-
- public AssemblyDescriptionAttribute(String description)
- {
- m_description = description;
- }
-
- public String Description
- {
- get { return m_description; }
- }
- }
-
-
- [AttributeUsage (AttributeTargets.Assembly, Inherited=false)]
- public sealed class AssemblyTitleAttribute : Attribute
- {
- private String m_title;
-
- public AssemblyTitleAttribute(String title)
- {
- m_title = title;
- }
-
- public String Title
- {
- get { return m_title; }
- }
- }
-
-
- [AttributeUsage (AttributeTargets.Assembly, Inherited=false)]
- public sealed class AssemblyConfigurationAttribute : Attribute
- {
- private String m_configuration;
-
- public AssemblyConfigurationAttribute(String configuration)
- {
- m_configuration = configuration;
- }
-
- public String Configuration
- {
- get { return m_configuration; }
- }
- }
-
-
- [AttributeUsage (AttributeTargets.Assembly, Inherited=false)]
- public sealed class AssemblyDefaultAliasAttribute : Attribute
- {
- private String m_defaultAlias;
-
- public AssemblyDefaultAliasAttribute(String defaultAlias)
- {
- m_defaultAlias = defaultAlias;
- }
-
- public String DefaultAlias
- {
- get { return m_defaultAlias; }
- }
- }
-
-
- [AttributeUsage (AttributeTargets.Assembly, Inherited=false)]
- public sealed class AssemblyInformationalVersionAttribute : Attribute
- {
- private String m_informationalVersion;
-
- public AssemblyInformationalVersionAttribute(String informationalVersion)
- {
- m_informationalVersion = informationalVersion;
- }
-
- public String InformationalVersion
- {
- get { return m_informationalVersion; }
- }
- }
-
-
- [AttributeUsage(AttributeTargets.Assembly, Inherited=false)]
- public sealed class AssemblyFileVersionAttribute : Attribute
- {
- private String _version;
-
- public AssemblyFileVersionAttribute(String version)
- {
- if (version == null)
- throw new ArgumentNullException(nameof(version));
- Contract.EndContractBlock();
- _version = version;
- }
-
- public String Version {
- get { return _version; }
- }
- }
-
-
- [AttributeUsage (AttributeTargets.Assembly, Inherited=false)]
- public unsafe sealed class AssemblyCultureAttribute : Attribute
- {
- private String m_culture;
-
- public AssemblyCultureAttribute(String culture)
- {
- m_culture = culture;
- }
-
- public String Culture
- {
- get { return m_culture; }
- }
- }
-
-
- [AttributeUsage (AttributeTargets.Assembly, Inherited=false)]
- public unsafe sealed class AssemblyVersionAttribute : Attribute
- {
- private String m_version;
-
- public AssemblyVersionAttribute(String version)
- {
- m_version = version;
- }
-
- public String Version
- {
- get { return m_version; }
- }
- }
-
-
- [AttributeUsage (AttributeTargets.Assembly, Inherited=false)]
- public sealed class AssemblyKeyFileAttribute : Attribute
- {
- private String m_keyFile;
-
- public AssemblyKeyFileAttribute(String keyFile)
- {
- m_keyFile = keyFile;
- }
-
- public String KeyFile
- {
- get { return m_keyFile; }
- }
- }
-
-
- [AttributeUsage (AttributeTargets.Assembly, Inherited=false)]
- public sealed class AssemblyDelaySignAttribute : Attribute
- {
- private bool m_delaySign;
-
- public AssemblyDelaySignAttribute(bool delaySign)
- {
- m_delaySign = delaySign;
- }
-
- public bool DelaySign
- { get
- { return m_delaySign; }
- }
- }
-
-
- [AttributeUsage(AttributeTargets.Assembly, Inherited=false)]
- public unsafe sealed class AssemblyAlgorithmIdAttribute : Attribute
- {
- private uint m_algId;
-
- public AssemblyAlgorithmIdAttribute(AssemblyHashAlgorithm algorithmId)
- {
- m_algId = (uint) algorithmId;
- }
-
- [CLSCompliant(false)]
- public AssemblyAlgorithmIdAttribute(uint algorithmId)
- {
- m_algId = algorithmId;
- }
-
- [CLSCompliant(false)]
- public uint AlgorithmId
- {
- get { return m_algId; }
- }
- }
-
-
- [AttributeUsage(AttributeTargets.Assembly, Inherited=false)]
- public unsafe sealed class AssemblyFlagsAttribute : Attribute
- {
- private AssemblyNameFlags m_flags;
-
- [Obsolete("This constructor has been deprecated. Please use AssemblyFlagsAttribute(AssemblyNameFlags) instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- [CLSCompliant(false)]
- public AssemblyFlagsAttribute(uint flags)
- {
- m_flags = (AssemblyNameFlags)flags;
- }
-
- [Obsolete("This property has been deprecated. Please use AssemblyFlags instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- [CLSCompliant(false)]
- public uint Flags
- {
- get { return (uint)m_flags; }
- }
-
- // This, of course, should be typed as AssemblyNameFlags. The compat police don't allow such changes.
- public int AssemblyFlags
- {
- get { return (int)m_flags; }
- }
-
- [Obsolete("This constructor has been deprecated. Please use AssemblyFlagsAttribute(AssemblyNameFlags) instead. http://go.microsoft.com/fwlink/?linkid=14202")]
- public AssemblyFlagsAttribute(int assemblyFlags)
- {
- m_flags = (AssemblyNameFlags)assemblyFlags;
- }
-
-
- public AssemblyFlagsAttribute(AssemblyNameFlags assemblyFlags)
- {
- m_flags = assemblyFlags;
- }
- }
-
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=true, Inherited=false)]
- public sealed class AssemblyMetadataAttribute : Attribute
- {
- private String m_key;
- private String m_value;
-
- public AssemblyMetadataAttribute(string key, string value)
- {
- m_key = key;
- m_value = value;
- }
-
- public string Key
- {
- get { return m_key; }
- }
-
- public string Value
- {
- get { return m_value;}
- }
- }
-
- [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple=false)]
- public sealed class AssemblySignatureKeyAttribute : Attribute
- {
- private String _publicKey;
- private String _countersignature;
-
- public AssemblySignatureKeyAttribute(String publicKey, String countersignature)
- {
- _publicKey = publicKey;
- _countersignature = countersignature;
- }
-
- public String PublicKey
- {
- get { return _publicKey; }
- }
-
- public String Countersignature
- {
- get { return _countersignature; }
- }
- }
-
- [AttributeUsage (AttributeTargets.Assembly, Inherited=false)]
- public sealed class AssemblyKeyNameAttribute : Attribute
- {
- private String m_keyName;
-
- public AssemblyKeyNameAttribute(String keyName)
- {
- m_keyName = keyName;
- }
-
- public String KeyName
- {
- get { return m_keyName; }
- }
- }
-
-}
-
diff --git a/src/mscorlib/src/System/Reflection/AssemblyName.cs b/src/mscorlib/src/System/Reflection/AssemblyName.cs
index 01be855646..80fdf5d162 100644
--- a/src/mscorlib/src/System/Reflection/AssemblyName.cs
+++ b/src/mscorlib/src/System/Reflection/AssemblyName.cs
@@ -13,7 +13,9 @@
**
**
===========================================================*/
-namespace System.Reflection {
+
+namespace System.Reflection
+{
using System;
using System.IO;
using System.Configuration.Assemblies;
@@ -33,31 +35,31 @@ namespace System.Reflection {
// If you modify any of these fields, you must also update the
// AssemblyBaseObject structure in object.h
//
- private String _Name; // Name
- private byte[] _PublicKey;
- private byte[] _PublicKeyToken;
- private CultureInfo _CultureInfo;
- private String _CodeBase; // Potential location to get the file
- private Version _Version;
-
- private StrongNameKeyPair _StrongNameKeyPair;
+ private String _Name; // Name
+ private byte[] _PublicKey;
+ private byte[] _PublicKeyToken;
+ private CultureInfo _CultureInfo;
+ private String _CodeBase; // Potential location to get the file
+ private Version _Version;
+
+ private StrongNameKeyPair _StrongNameKeyPair;
private SerializationInfo m_siInfo; //A temporary variable which we need during deserialization.
- private byte[] _HashForControl;
+ private byte[] _HashForControl;
private AssemblyHashAlgorithm _HashAlgorithm;
private AssemblyHashAlgorithm _HashAlgorithmForControl;
private AssemblyVersionCompatibility _VersionCompatibility;
- private AssemblyNameFlags _Flags;
-
+ private AssemblyNameFlags _Flags;
+
public AssemblyName()
- {
+ {
_HashAlgorithm = AssemblyHashAlgorithm.None;
_VersionCompatibility = AssemblyVersionCompatibility.SameMachine;
_Flags = AssemblyNameFlags.None;
}
-
+
// Set and get the name of the assembly. If this is a weak Name
// then it optionally contains a site. For strong assembly names,
// the name partitions up the strong name's namespace
@@ -69,10 +71,12 @@ namespace System.Reflection {
public Version Version
{
- get {
+ get
+ {
return _Version;
}
- set {
+ set
+ {
_Version = value;
}
}
@@ -80,30 +84,34 @@ namespace System.Reflection {
// Locales, internally the LCID is used for the match.
public CultureInfo CultureInfo
{
- get {
+ get
+ {
return _CultureInfo;
}
- set {
- _CultureInfo = value;
+ set
+ {
+ _CultureInfo = value;
}
}
public String CultureName
{
- get {
+ get
+ {
return (_CultureInfo == null) ? null : _CultureInfo.Name;
}
- set {
+ set
+ {
_CultureInfo = (value == null) ? null : new CultureInfo(value);
}
}
-
+
public String CodeBase
{
get { return _CodeBase; }
set { _CodeBase = value; }
}
-
+
public String EscapedCodeBase
{
get
@@ -114,18 +122,21 @@ namespace System.Reflection {
return EscapeCodeBase(_CodeBase);
}
}
-
- public ProcessorArchitecture ProcessorArchitecture
+
+ public ProcessorArchitecture ProcessorArchitecture
{
- get {
+ get
+ {
int x = (((int)_Flags) & 0x70) >> 4;
- if(x > 5)
+ if (x > 5)
x = 0;
return (ProcessorArchitecture)x;
}
- set {
+ set
+ {
int x = ((int)value) & 0x07;
- if(x <= 5) {
+ if (x <= 5)
+ {
_Flags = (AssemblyNameFlags)((int)_Flags & 0xFFFFFF0F);
_Flags |= (AssemblyNameFlags)(x << 4);
}
@@ -151,8 +162,8 @@ namespace System.Reflection {
}
}
}
-
-
+
+
// Make a copy of this assembly name.
public Object Clone()
@@ -168,8 +179,8 @@ namespace System.Reflection {
_CodeBase,
_Flags,
_StrongNameKeyPair);
- name._HashForControl=_HashForControl;
- name._HashAlgorithmForControl=_HashAlgorithmForControl;
+ name._HashForControl = _HashForControl;
+ name._HashAlgorithmForControl = _HashAlgorithmForControl;
return name;
}
@@ -180,7 +191,7 @@ namespace System.Reflection {
*/
static public AssemblyName GetAssemblyName(String assemblyFile)
{
- if(assemblyFile == null)
+ if (assemblyFile == null)
throw new ArgumentNullException(nameof(assemblyFile));
Contract.EndContractBlock();
@@ -189,11 +200,11 @@ namespace System.Reflection {
string fullPath = Path.GetFullPath(assemblyFile);
return nGetFileInformation(fullPath);
}
-
+
internal void SetHashControl(byte[] hash, AssemblyHashAlgorithm hashAlgorithm)
{
- _HashForControl=hash;
- _HashAlgorithmForControl=hashAlgorithm;
+ _HashForControl = hash;
+ _HashAlgorithmForControl = hashAlgorithm;
}
// The public key that is used to verify an assemblies
@@ -239,7 +250,8 @@ namespace System.Reflection {
public AssemblyNameFlags Flags
{
get { return (AssemblyNameFlags)((uint)_Flags & 0xFFFFF10F); }
- set {
+ set
+ {
_Flags &= unchecked((AssemblyNameFlags)0x00000EF0);
_Flags |= (value & unchecked((AssemblyNameFlags)0xFFFFF10F));
}
@@ -250,7 +262,7 @@ namespace System.Reflection {
get { return _HashAlgorithm; }
set { _HashAlgorithm = value; }
}
-
+
public AssemblyVersionCompatibility VersionCompatibility
{
get { return _VersionCompatibility; }
@@ -262,21 +274,22 @@ namespace System.Reflection {
get { return _StrongNameKeyPair; }
set { _StrongNameKeyPair = value; }
}
-
+
public String FullName
{
- get {
+ get
+ {
return nToString();
}
}
-
+
// Returns the stringized version of the assembly name.
public override String ToString()
{
String s = FullName;
- if(s == null)
+ if (s == null)
return base.ToString();
- else
+ else
return s;
}
@@ -291,7 +304,7 @@ namespace System.Reflection {
info.AddValue("_PublicKey", _PublicKey, typeof(byte[]));
info.AddValue("_PublicKeyToken", _PublicKeyToken, typeof(byte[]));
#if FEATURE_USE_LCID
- info.AddValue("_CultureInfo", (_CultureInfo == null) ? -1 :_CultureInfo.LCID);
+ info.AddValue("_CultureInfo", (_CultureInfo == null) ? -1 : _CultureInfo.LCID);
#endif
info.AddValue("_CodeBase", _CodeBase);
info.AddValue("_Version", _Version);
@@ -300,8 +313,8 @@ namespace System.Reflection {
info.AddValue("_StrongNameKeyPair", _StrongNameKeyPair, typeof(StrongNameKeyPair));
info.AddValue("_VersionCompatibility", _VersionCompatibility, typeof(AssemblyVersionCompatibility));
info.AddValue("_Flags", _Flags, typeof(AssemblyNameFlags));
- info.AddValue("_HashForControl",_HashForControl,typeof(byte[]));
- }
+ info.AddValue("_HashForControl", _HashForControl, typeof(byte[]));
+ }
public void OnDeserialization(Object sender)
{
@@ -310,8 +323,8 @@ namespace System.Reflection {
return;
_Name = m_siInfo.GetString("_Name");
- _PublicKey = (byte[]) m_siInfo.GetValue("_PublicKey", typeof(byte[]));
- _PublicKeyToken = (byte[]) m_siInfo.GetValue("_PublicKeyToken", typeof(byte[]));
+ _PublicKey = (byte[])m_siInfo.GetValue("_PublicKey", typeof(byte[]));
+ _PublicKeyToken = (byte[])m_siInfo.GetValue("_PublicKeyToken", typeof(byte[]));
#if FEATURE_USE_LCID
int lcid = (int)m_siInfo.GetInt32("_CultureInfo");
if (lcid != -1)
@@ -319,17 +332,19 @@ namespace System.Reflection {
#endif
_CodeBase = m_siInfo.GetString("_CodeBase");
- _Version = (Version) m_siInfo.GetValue("_Version", typeof(Version));
- _HashAlgorithm = (AssemblyHashAlgorithm) m_siInfo.GetValue("_HashAlgorithm", typeof(AssemblyHashAlgorithm));
- _StrongNameKeyPair = (StrongNameKeyPair) m_siInfo.GetValue("_StrongNameKeyPair", typeof(StrongNameKeyPair));
+ _Version = (Version)m_siInfo.GetValue("_Version", typeof(Version));
+ _HashAlgorithm = (AssemblyHashAlgorithm)m_siInfo.GetValue("_HashAlgorithm", typeof(AssemblyHashAlgorithm));
+ _StrongNameKeyPair = (StrongNameKeyPair)m_siInfo.GetValue("_StrongNameKeyPair", typeof(StrongNameKeyPair));
_VersionCompatibility = (AssemblyVersionCompatibility)m_siInfo.GetValue("_VersionCompatibility", typeof(AssemblyVersionCompatibility));
- _Flags = (AssemblyNameFlags) m_siInfo.GetValue("_Flags", typeof(AssemblyNameFlags));
+ _Flags = (AssemblyNameFlags)m_siInfo.GetValue("_Flags", typeof(AssemblyNameFlags));
- try {
- _HashAlgorithmForControl = (AssemblyHashAlgorithm) m_siInfo.GetValue("_HashAlgorithmForControl", typeof(AssemblyHashAlgorithm));
- _HashForControl = (byte[]) m_siInfo.GetValue("_HashForControl", typeof(byte[]));
+ try
+ {
+ _HashAlgorithmForControl = (AssemblyHashAlgorithm)m_siInfo.GetValue("_HashAlgorithmForControl", typeof(AssemblyHashAlgorithm));
+ _HashForControl = (byte[])m_siInfo.GetValue("_HashForControl", typeof(byte[]));
}
- catch (SerializationException) { // RTM did not have these defined
+ catch (SerializationException)
+ { // RTM did not have these defined
_HashAlgorithmForControl = AssemblyHashAlgorithm.None;
_HashForControl = null;
}
@@ -341,7 +356,7 @@ namespace System.Reflection {
internal AssemblyName(SerializationInfo info, StreamingContext context)
{
//The graph is not valid until OnDeserialization() has been called.
- m_siInfo = info;
+ m_siInfo = info;
}
public AssemblyName(String assemblyName)
@@ -351,32 +366,32 @@ namespace System.Reflection {
Contract.EndContractBlock();
if ((assemblyName.Length == 0) ||
(assemblyName[0] == '\0'))
- throw new ArgumentException(Environment.GetResourceString("Format_StringZeroLength"));
+ throw new ArgumentException(SR.Format_StringZeroLength);
_Name = assemblyName;
nInit();
}
- static public bool ReferenceMatchesDefinition(AssemblyName reference,
- AssemblyName definition)
+ /// <summary>
+ /// Compares the simple names disregarding Version, Culture and PKT. While this clearly does not
+ /// match the intent of this api, this api has been broken this way since its debut and we cannot
+ /// change its behavior now.
+ /// </summary>
+ public static bool ReferenceMatchesDefinition(AssemblyName reference, AssemblyName definition)
{
- // Optimization for common use case
- if (Object.ReferenceEquals(reference, definition))
- {
+ if (object.ReferenceEquals(reference, definition))
return true;
- }
- return ReferenceMatchesDefinitionInternal(reference, definition, true);
- }
-
- /// "parse" tells us to parse the simple name of the assembly as if it was the full name
- /// almost never the right thing to do, but needed for compat
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static internal extern bool ReferenceMatchesDefinitionInternal(AssemblyName reference,
- AssemblyName definition,
- bool parse);
+ if (reference == null)
+ throw new ArgumentNullException(nameof(reference));
+ if (definition == null)
+ throw new ArgumentNullException(nameof(definition));
+ string refName = reference.Name ?? string.Empty;
+ string defName = definition.Name ?? string.Empty;
+ return refName.Equals(defName, StringComparison.OrdinalIgnoreCase);
+ }
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void nInit(out RuntimeAssembly assembly, bool forIntrospection, bool raiseResolveEvent);
@@ -431,7 +446,7 @@ namespace System.Reflection {
return ProcessorArchitecture.None;
}
- internal void Init(String name,
+ internal void Init(String name,
byte[] publicKey,
byte[] publicKeyToken,
Version version,
@@ -444,18 +459,20 @@ namespace System.Reflection {
{
_Name = name;
- if (publicKey != null) {
+ if (publicKey != null)
+ {
_PublicKey = new byte[publicKey.Length];
Array.Copy(publicKey, _PublicKey, publicKey.Length);
}
-
- if (publicKeyToken != null) {
+
+ if (publicKeyToken != null)
+ {
_PublicKeyToken = new byte[publicKeyToken.Length];
Array.Copy(publicKeyToken, _PublicKeyToken, publicKeyToken.Length);
}
-
+
if (version != null)
- _Version = (Version) version.Clone();
+ _Version = (Version)version.Clone();
_CultureInfo = cultureInfo;
_HashAlgorithm = hashAlgorithm;
@@ -480,7 +497,7 @@ namespace System.Reflection {
{
if (codebase == null)
return string.Empty;
-
+
int position = 0;
char[] dest = EscapeString(codebase, 0, codebase.Length, null, ref position, true, c_DummyChar, c_DummyChar, c_DummyChar);
if (dest == null)
@@ -528,7 +545,7 @@ namespace System.Reflection {
{
// Should be a rare case where the app tries to feed an invalid Unicode surrogates pair
if (count == 1 || count == end - i)
- throw new FormatException(Environment.GetResourceString("Arg_FormatException"));
+ throw new FormatException(SR.Arg_FormatException);
// need to grab one more char as a Surrogate except when it's a bogus input
++count;
}
@@ -544,7 +561,7 @@ namespace System.Reflection {
// This is the only exception that built in UriParser can throw after a Uri ctor.
// Should not happen unless the app tries to feed an invalid Unicode String
if (numberOfBytes == 0)
- throw new FormatException(Environment.GetResourceString("Arg_FormatException"));
+ throw new FormatException(SR.Arg_FormatException);
i += (count - 1);
@@ -620,7 +637,7 @@ namespace System.Reflection {
dest[destPos++] = pStr[prevInputPos++];
return dest;
}
-
+
internal static void EscapeAsciiChar(char ch, char[] to, ref int pos)
{
to[pos++] = '%';
@@ -657,7 +674,7 @@ namespace System.Reflection {
? ((int)next - (int)'A')
: ((int)next - (int)'a'))
+ 10)));
- }
+ }
private static unsafe bool IsReservedUnreservedOrHash(char c)
{
@@ -688,7 +705,7 @@ namespace System.Reflection {
{
return IsAsciiLetter(character) || (character >= '0' && character <= '9');
}
-
+
private static readonly char[] s_hexUpperChars = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
@@ -696,7 +713,7 @@ namespace System.Reflection {
private const short c_MaxAsciiCharsReallocate = 40;
private const short c_MaxUnicodeCharsReallocate = 40;
private const short c_MaxUTF_8BytesPerUnicodeChar = 4;
- private const short c_EncodedCharsPerByte = 3;
+ private const short c_EncodedCharsPerByte = 3;
private const string RFC3986ReservedMarks = @":/?#[]@!$&'()*+,;=";
private const string RFC3986UnreservedMarks = @"-._~";
}
diff --git a/src/mscorlib/src/System/Reflection/AssemblyNameFlags.cs b/src/mscorlib/src/System/Reflection/AssemblyNameFlags.cs
deleted file mode 100644
index b86955efa5..0000000000
--- a/src/mscorlib/src/System/Reflection/AssemblyNameFlags.cs
+++ /dev/null
@@ -1,53 +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.
-
-/*============================================================
-**
-**
-**
-**
-**
-**
-** Purpose: Flags controlling how an AssemblyName is used
-** during binding
-**
-**
-===========================================================*/
-namespace System.Reflection {
-
- using System;
- [Serializable]
- [FlagsAttribute()]
- public enum AssemblyNameFlags
- {
- None = 0x0000,
- // Flag used to indicate that an assembly ref contains the full public key, not the compressed token.
- // Must match afPublicKey in CorHdr.h.
- PublicKey = 0x0001,
- //ProcArchMask = 0x00F0, // Bits describing the processor architecture
- // Accessible via AssemblyName.ProcessorArchitecture
- EnableJITcompileOptimizer = 0x4000,
- EnableJITcompileTracking = 0x8000,
- Retargetable = 0x0100,
- //ContentType = 0x0E00, // Bits describing the ContentType are accessible via AssemblyName.ContentType
- }
-
- [Serializable]
- public enum AssemblyContentType
- {
- Default = 0x0000,
- WindowsRuntime = 0x0001
- }
-
- [Serializable]
- public enum ProcessorArchitecture
- {
- None = 0x0000,
- MSIL = 0x0001,
- X86 = 0x0002,
- IA64 = 0x0003,
- Amd64 = 0x0004,
- Arm = 0x0005
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/Associates.cs b/src/mscorlib/src/System/Reflection/Associates.cs
index 9eaf74a6e9..ed06cb46fc 100644
--- a/src/mscorlib/src/System/Reflection/Associates.cs
+++ b/src/mscorlib/src/System/Reflection/Associates.cs
@@ -4,22 +4,22 @@
//
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
namespace System.Reflection
{
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
internal static class Associates
{
[Flags]
internal enum Attributes
{
ComposedOfAllVirtualMethods = 0x1,
- ComposedOfAllPrivateMethods = 0x2,
- ComposedOfNoPublicMembers = 0x4,
- ComposedOfNoStaticMembers = 0x8,
+ ComposedOfAllPrivateMethods = 0x2,
+ ComposedOfNoPublicMembers = 0x4,
+ ComposedOfNoStaticMembers = 0x8,
}
internal static bool IncludeAccessor(MethodInfo associate, bool nonPublic)
@@ -51,7 +51,7 @@ namespace System.Reflection
IntPtr[] genericArgumentHandles = null;
int genericArgumentCount = 0;
- RuntimeType [] genericArguments = declaredType.GetTypeHandleInternal().GetInstantiationInternal();
+ RuntimeType[] genericArguments = declaredType.GetTypeHandleInternal().GetInstantiationInternal();
if (genericArguments != null)
{
genericArgumentCount = genericArguments.Length;
@@ -85,7 +85,7 @@ namespace System.Reflection
// the same or any property in the derived class.
if ((methAttr & MethodAttributes.Virtual) != 0)
{
- bool declaringTypeIsClass =
+ bool declaringTypeIsClass =
(RuntimeTypeHandle.GetAttributes(declaredType) & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class;
// It makes no sense to search for a virtual override of a method declared on an interface.
@@ -99,7 +99,7 @@ namespace System.Reflection
}
}
- RuntimeMethodInfo associateMethod =
+ RuntimeMethodInfo associateMethod =
RuntimeType.GetMethodBase(reflectedType, associateMethodHandle) as RuntimeMethodInfo;
// suppose a property was mapped to a method not in the derivation hierarchy of the reflectedTypeHandle
@@ -125,13 +125,13 @@ namespace System.Reflection
{
addOn = removeOn = fireOn = getter = setter = null;
- Attributes attributes =
+ Attributes attributes =
Attributes.ComposedOfAllPrivateMethods |
Attributes.ComposedOfAllVirtualMethods |
Attributes.ComposedOfNoPublicMembers |
Attributes.ComposedOfNoStaticMembers;
- while(RuntimeTypeHandle.IsGenericVariable(reflectedType))
+ while (RuntimeTypeHandle.IsGenericVariable(reflectedType))
reflectedType = (RuntimeType)reflectedType.BaseType;
bool isInherited = declaringType != reflectedType;
@@ -156,12 +156,12 @@ namespace System.Reflection
continue;
MethodAttributes methAttr = associateMethod.Attributes;
- bool isPrivate =(methAttr & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;
- bool isVirtual =(methAttr & MethodAttributes.Virtual) != 0;
+ bool isPrivate = (methAttr & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;
+ bool isVirtual = (methAttr & MethodAttributes.Virtual) != 0;
MethodAttributes visibility = methAttr & MethodAttributes.MemberAccessMask;
bool isPublic = visibility == MethodAttributes.Public;
- bool isStatic =(methAttr & MethodAttributes.Static) != 0;
+ bool isStatic = (methAttr & MethodAttributes.Static) != 0;
if (isPublic)
{
@@ -202,10 +202,9 @@ namespace System.Reflection
bool isPseudoStatic = (attributes & Attributes.ComposedOfNoStaticMembers) == 0;
bindingFlags = RuntimeType.FilterPreCalculate(isPseudoPublic, isInherited, isPseudoStatic);
- composedOfAllPrivateMethods =(attributes & Attributes.ComposedOfAllPrivateMethods) != 0;
+ composedOfAllPrivateMethods = (attributes & Attributes.ComposedOfAllPrivateMethods) != 0;
other = (otherList != null) ? otherList.ToArray() : null;
}
}
-
}
diff --git a/src/mscorlib/src/System/Reflection/Binder.cs b/src/mscorlib/src/System/Reflection/Binder.cs
deleted file mode 100644
index bf4545fe81..0000000000
--- a/src/mscorlib/src/System/Reflection/Binder.cs
+++ /dev/null
@@ -1,49 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-//
-//
-// This interface defines a set of methods which interact with reflection
-// during the binding process. This control allows systems to apply language
-// specific semantics to the binding and invocation process.
-//
-//
-namespace System.Reflection {
- using System;
- using System.Runtime.InteropServices;
- using CultureInfo = System.Globalization.CultureInfo;
-
- [Serializable]
- public abstract class Binder
- {
- // Given a set of methods that match the basic criteria, select a method to
- // invoke. When this method is finished, we should have
- public abstract MethodBase BindToMethod(BindingFlags bindingAttr,MethodBase[] match,ref Object[] args,
- ParameterModifier[] modifiers,CultureInfo culture,String[] names, out Object state);
-
- // Given a set of methods that match the basic criteria, select a method to
- // invoke. When this method is finished, we should have
- public abstract FieldInfo BindToField(BindingFlags bindingAttr,FieldInfo[] match,
- Object value,CultureInfo culture);
-
- // Given a set of methods that match the base criteria, select a method based
- // upon an array of types. This method should return null if no method matchs
- // the criteria.
- public abstract MethodBase SelectMethod(BindingFlags bindingAttr,MethodBase[] match,
- Type[] types,ParameterModifier[] modifiers);
-
-
- // Given a set of propreties that match the base criteria, select one.
- public abstract PropertyInfo SelectProperty(BindingFlags bindingAttr,PropertyInfo[] match,
- Type returnType,Type[] indexes,ParameterModifier[] modifiers);
-
- // ChangeType
- // This method will convert the value into the property type.
- // It throws a cast exception if this fails.
- public abstract Object ChangeType(Object value,Type type,CultureInfo culture);
-
- public abstract void ReorderArgumentArray(ref Object[] args, Object state);
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/BindingFlags.cs b/src/mscorlib/src/System/Reflection/BindingFlags.cs
deleted file mode 100644
index ae0a6d68d3..0000000000
--- a/src/mscorlib/src/System/Reflection/BindingFlags.cs
+++ /dev/null
@@ -1,63 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// BindingFlags are a set of flags that control the binding and invocation process
-//
-// in Reflection. There are two processes. The first is selection of a Member which
-// is the binding phase. The second, is invocation. These flags control how this
-// process works.
-//
-//
-namespace System.Reflection {
-
- using System;
- [Serializable]
- [Flags]
- public enum BindingFlags
- {
-
- // NOTES: We have lookup masks defined in RuntimeType and Activator. If we
- // change the lookup values then these masks may need to change also.
-
- // a place holder for no flag specifed
- Default = 0x00,
-
- // These flags indicate what to search for when binding
- IgnoreCase = 0x01, // Ignore the case of Names while searching
- DeclaredOnly = 0x02, // Only look at the members declared on the Type
- Instance = 0x04, // Include Instance members in search
- Static = 0x08, // Include Static members in search
- Public = 0x10, // Include Public members in search
- NonPublic = 0x20, // Include Non-Public members in search
- FlattenHierarchy = 0x40, // Rollup the statics into the class.
-
- // These flags are used by InvokeMember to determine
- // what type of member we are trying to Invoke.
- // BindingAccess = 0xFF00;
- InvokeMethod = 0x0100,
- CreateInstance = 0x0200,
- GetField = 0x0400,
- SetField = 0x0800,
- GetProperty = 0x1000,
- SetProperty = 0x2000,
-
- // These flags are also used by InvokeMember but they should only
- // be used when calling InvokeMember on a COM object.
- PutDispProperty = 0x4000,
- PutRefDispProperty = 0x8000,
-
- ExactBinding = 0x010000, // Bind with Exact Type matching, No Change type
- SuppressChangeType = 0x020000,
-
- // DefaultValueBinding will return the set of methods having ArgCount or
- // more parameters. This is used for default values, etc.
- OptionalParamBinding = 0x040000,
-
- // These are a couple of misc attributes used
- IgnoreReturn = 0x01000000, // This is used in COM Interop
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/CallingConventions.cs b/src/mscorlib/src/System/Reflection/CallingConventions.cs
deleted file mode 100644
index 266dd55184..0000000000
--- a/src/mscorlib/src/System/Reflection/CallingConventions.cs
+++ /dev/null
@@ -1,28 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// CallingConventions is a set of Bits representing the calling conventions
-//
-// in the system.
-//
-//
-namespace System.Reflection {
- using System.Runtime.InteropServices;
- using System;
- [Serializable]
- [Flags]
- public enum CallingConventions
- {
- //NOTE: If you change this please update COMMember.cpp. These
- // are defined there.
- Standard = 0x0001,
- VarArgs = 0x0002,
- Any = Standard | VarArgs,
- HasThis = 0x0020,
- ExplicitThis = 0x0040,
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/ConstructorInfo.CoreCLR.cs b/src/mscorlib/src/System/Reflection/ConstructorInfo.CoreCLR.cs
new file mode 100644
index 0000000000..c96bfb5ac1
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/ConstructorInfo.CoreCLR.cs
@@ -0,0 +1,11 @@
+// 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.
+
+namespace System.Reflection
+{
+ public abstract partial class ConstructorInfo : MethodBase
+ {
+ internal virtual Type GetReturnType() { throw new NotImplementedException(); }
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/ConstructorInfo.cs b/src/mscorlib/src/System/Reflection/ConstructorInfo.cs
deleted file mode 100644
index c8d71bc1f9..0000000000
--- a/src/mscorlib/src/System/Reflection/ConstructorInfo.cs
+++ /dev/null
@@ -1,614 +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.
-
-//
-
-namespace System.Reflection
-{
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- using System.Runtime;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.InteropServices;
- using System.Runtime.Serialization;
- using System.Security;
- using System.Threading;
- using MemberListType = System.RuntimeType.MemberListType;
- using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
- using System.Runtime.CompilerServices;
-
- [Serializable]
- public abstract class ConstructorInfo : MethodBase
- {
- #region Static Members
- public readonly static String ConstructorName = ".ctor";
-
- public readonly static String TypeConstructorName = ".cctor";
- #endregion
-
- #region Constructor
- protected ConstructorInfo() { }
- #endregion
-
- public static bool operator ==(ConstructorInfo left, ConstructorInfo right)
- {
- if (ReferenceEquals(left, right))
- return true;
-
- if ((object)left == null || (object)right == null ||
- left is RuntimeConstructorInfo || right is RuntimeConstructorInfo)
- {
- return false;
- }
- return left.Equals(right);
- }
-
- public static bool operator !=(ConstructorInfo left, ConstructorInfo right)
- {
- return !(left == right);
- }
-
- public override bool Equals(object obj)
- {
- return base.Equals(obj);
- }
-
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
-
- #region Internal Members
- internal virtual Type GetReturnType() { throw new NotImplementedException(); }
- #endregion
-
- #region MemberInfo Overrides
- public override MemberTypes MemberType { get { return System.Reflection.MemberTypes.Constructor; } }
- #endregion
-
- #region Public Abstract\Virtual Members
- public abstract Object Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture);
- #endregion
-
- #region Public Members
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public Object Invoke(Object[] parameters)
- {
- // Theoretically we should set up a LookForMyCaller stack mark here and pass that along.
- // But to maintain backward compatibility we can't switch to calling an
- // internal overload that takes a stack mark.
- // Fortunately the stack walker skips all the reflection invocation frames including this one.
- // So this method will never be returned by the stack walker as the caller.
- // See SystemDomain::CallersMethodCallbackWithStackMark in AppDomain.cpp.
- return Invoke(BindingFlags.Default, null, parameters, null);
- }
- #endregion
- }
-
- [Serializable]
- internal sealed class RuntimeConstructorInfo : ConstructorInfo, ISerializable, IRuntimeMethodInfo
- {
- #region Private Data Members
- private volatile RuntimeType m_declaringType;
- private RuntimeTypeCache m_reflectedTypeCache;
- private string m_toString;
- private ParameterInfo[] m_parameters = null; // Created lazily when GetParameters() is called.
-#pragma warning disable 169
- private object _empty1; // These empties are used to ensure that RuntimeConstructorInfo and RuntimeMethodInfo are have a layout which is sufficiently similar
- private object _empty2;
- private object _empty3;
-#pragma warning restore 169
- private IntPtr m_handle;
- private MethodAttributes m_methodAttributes;
- private BindingFlags m_bindingFlags;
- private volatile Signature m_signature;
- private INVOCATION_FLAGS m_invocationFlags;
-
-#if FEATURE_APPX
- private bool IsNonW8PFrameworkAPI()
- {
- if (DeclaringType.IsArray && IsPublic && !IsStatic)
- return false;
-
- RuntimeAssembly rtAssembly = GetRuntimeAssembly();
- if (rtAssembly.IsFrameworkAssembly())
- {
- int ctorToken = rtAssembly.InvocableAttributeCtorToken;
- if (System.Reflection.MetadataToken.IsNullToken(ctorToken) ||
- !CustomAttribute.IsAttributeDefined(GetRuntimeModule(), MetadataToken, ctorToken))
- return true;
- }
-
- if (GetRuntimeType().IsNonW8PFrameworkAPI())
- return true;
-
- return false;
- }
-#endif // FEATURE_APPX
-
- internal INVOCATION_FLAGS InvocationFlags
- {
- get
- {
- if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0)
- {
- INVOCATION_FLAGS invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_IS_CTOR; // this is a given
-
- Type declaringType = DeclaringType;
-
- //
- // first take care of all the NO_INVOKE cases.
- if ( declaringType == typeof(void) ||
- (declaringType != null && declaringType.ContainsGenericParameters) ||
- ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) ||
- ((Attributes & MethodAttributes.RequireSecObject) == MethodAttributes.RequireSecObject))
- {
- // We don't need other flags if this method cannot be invoked
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE;
- }
- else if (IsStatic || declaringType != null && declaringType.IsAbstract)
- {
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NO_CTOR_INVOKE;
- }
- else
- {
- // this should be an invocable method, determine the other flags that participate in invocation
- invocationFlags |= RuntimeMethodHandle.GetSecurityFlags(this);
-
- if ( (invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) == 0 &&
- ((Attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public ||
- (declaringType != null && declaringType.NeedsReflectionSecurityCheck)) )
- {
- // If method is non-public, or declaring type is not visible
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
- }
-
- // Check for attempt to create a delegate class, we demand unmanaged
- // code permission for this since it's hard to validate the target address.
- if (typeof(Delegate).IsAssignableFrom(DeclaringType))
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_IS_DELEGATE_CTOR;
- }
-
-#if FEATURE_APPX
- if (AppDomain.ProfileAPICheck && IsNonW8PFrameworkAPI())
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API;
-#endif // FEATURE_APPX
-
- m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED;
- }
-
- return m_invocationFlags;
- }
- }
- #endregion
-
- #region Constructor
- internal RuntimeConstructorInfo(
- RuntimeMethodHandleInternal handle, RuntimeType declaringType, RuntimeTypeCache reflectedTypeCache,
- MethodAttributes methodAttributes, BindingFlags bindingFlags)
- {
- Contract.Ensures(methodAttributes == RuntimeMethodHandle.GetAttributes(handle));
-
- m_bindingFlags = bindingFlags;
- m_reflectedTypeCache = reflectedTypeCache;
- m_declaringType = declaringType;
- m_handle = handle.Value;
- m_methodAttributes = methodAttributes;
- }
- #endregion
-
- #region NonPublic Methods
- RuntimeMethodHandleInternal IRuntimeMethodInfo.Value
- {
- get
- {
- return new RuntimeMethodHandleInternal(m_handle);
- }
- }
-
- internal override bool CacheEquals(object o)
- {
- RuntimeConstructorInfo m = o as RuntimeConstructorInfo;
-
- if ((object)m == null)
- return false;
-
- return m.m_handle == m_handle;
- }
-
- private Signature Signature
- {
- get
- {
- if (m_signature == null)
- m_signature = new Signature(this, m_declaringType);
-
- return m_signature;
- }
- }
-
- private RuntimeType ReflectedTypeInternal
- {
- get
- {
- return m_reflectedTypeCache.GetRuntimeType();
- }
- }
-
- private void CheckConsistency(Object target)
- {
- if (target == null && IsStatic)
- return;
-
- if (!m_declaringType.IsInstanceOfType(target))
- {
- if (target == null)
- throw new TargetException(Environment.GetResourceString("RFLCT.Targ_StatMethReqTarg"));
-
- throw new TargetException(Environment.GetResourceString("RFLCT.Targ_ITargMismatch"));
- }
- }
-
- internal BindingFlags BindingFlags { get { return m_bindingFlags; } }
- #endregion
-
- #region Object Overrides
- public override String ToString()
- {
- // "Void" really doesn't make sense here. But we'll keep it for compat reasons.
- if (m_toString == null)
- m_toString = "Void " + FormatNameAndSig();
-
- return m_toString;
- }
- #endregion
-
- #region ICustomAttributeProvider
- public override Object[] GetCustomAttributes(bool inherit)
- {
- return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
- }
-
- public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
-
- return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
- }
-
- public override bool IsDefined(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
-
- return CustomAttribute.IsDefined(this, attributeRuntimeType);
- }
-
- public override IList<CustomAttributeData> GetCustomAttributesData()
- {
- return CustomAttributeData.GetCustomAttributesInternal(this);
- }
- #endregion
-
-
- #region MemberInfo Overrides
- public override String Name
- {
- get { return RuntimeMethodHandle.GetName(this); }
- }
- public override MemberTypes MemberType { get { return MemberTypes.Constructor; } }
-
- public override Type DeclaringType
- {
- get
- {
- return m_reflectedTypeCache.IsGlobal ? null : m_declaringType;
- }
- }
-
- public override Type ReflectedType
- {
- get
- {
- return m_reflectedTypeCache.IsGlobal ? null : ReflectedTypeInternal;
- }
- }
-
- public override int MetadataToken
- {
- get { return RuntimeMethodHandle.GetMethodDef(this); }
- }
- public override Module Module
- {
- get { return GetRuntimeModule(); }
- }
-
- internal RuntimeType GetRuntimeType() { return m_declaringType; }
- internal RuntimeModule GetRuntimeModule() { return RuntimeTypeHandle.GetModule(m_declaringType); }
- internal RuntimeAssembly GetRuntimeAssembly() { return GetRuntimeModule().GetRuntimeAssembly(); }
- #endregion
-
- #region MethodBase Overrides
-
- // This seems to always returns System.Void.
- internal override Type GetReturnType() { return Signature.ReturnType; }
-
- internal override ParameterInfo[] GetParametersNoCopy()
- {
- if (m_parameters == null)
- m_parameters = RuntimeParameterInfo.GetParameters(this, this, Signature);
-
- return m_parameters;
- }
-
- [Pure]
- public override ParameterInfo[] GetParameters()
- {
- ParameterInfo[] parameters = GetParametersNoCopy();
-
- if (parameters.Length == 0)
- return parameters;
-
- ParameterInfo[] ret = new ParameterInfo[parameters.Length];
- Array.Copy(parameters, ret, parameters.Length);
- return ret;
- }
-
- public override MethodImplAttributes GetMethodImplementationFlags()
- {
- return RuntimeMethodHandle.GetImplAttributes(this);
- }
-
- public override RuntimeMethodHandle MethodHandle
- {
- get
- {
- Type declaringType = DeclaringType;
- if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly"));
- return new RuntimeMethodHandle(this);
- }
- }
-
- public override MethodAttributes Attributes
- {
- get
- {
- return m_methodAttributes;
- }
- }
-
- public override CallingConventions CallingConvention
- {
- get
- {
- return Signature.CallingConvention;
- }
- }
-
- internal static void CheckCanCreateInstance(Type declaringType, bool isVarArg)
- {
- if (declaringType == null)
- throw new ArgumentNullException(nameof(declaringType));
- Contract.EndContractBlock();
-
- // ctor is ReflectOnly
- if (declaringType is ReflectionOnlyType)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyInvoke"));
-
- // ctor is declared on interface class
- else if (declaringType.IsInterface)
- throw new MemberAccessException(
- String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Acc_CreateInterfaceEx"), declaringType));
-
- // ctor is on an abstract class
- else if (declaringType.IsAbstract)
- throw new MemberAccessException(
- String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Acc_CreateAbstEx"), declaringType));
-
- // ctor is on a class that contains stack pointers
- else if (declaringType.GetRootElementType() == typeof(ArgIterator))
- throw new NotSupportedException();
-
- // ctor is vararg
- else if (isVarArg)
- throw new NotSupportedException();
-
- // ctor is generic or on a generic class
- else if (declaringType.ContainsGenericParameters)
- {
- throw new MemberAccessException(
- String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Acc_CreateGenericEx"), declaringType));
- }
-
- // ctor is declared on System.Void
- else if (declaringType == typeof(void))
- throw new MemberAccessException(Environment.GetResourceString("Access_Void"));
- }
-
- internal void ThrowNoInvokeException()
- {
- CheckCanCreateInstance(DeclaringType, (CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs);
-
- // ctor is .cctor
- if ((Attributes & MethodAttributes.Static) == MethodAttributes.Static)
- throw new MemberAccessException(Environment.GetResourceString("Acc_NotClassInit"));
-
- throw new TargetException();
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public override Object Invoke(
- Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
- {
- INVOCATION_FLAGS invocationFlags = InvocationFlags;
-
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE) != 0)
- ThrowNoInvokeException();
-
- // check basic method consistency. This call will throw if there are problems in the target/method relationship
- CheckConsistency(obj);
-
-#if FEATURE_APPX
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
- if (caller != null && !caller.IsSafeForReflection())
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", FullName));
- }
-#endif
-
- if (obj != null)
- {
- // For unverifiable code, we require the caller to be critical.
- // Adding the INVOCATION_FLAGS_NEED_SECURITY flag makes that check happen
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
- }
-
- Signature sig = Signature;
-
- // get the signature
- int formalCount = sig.Arguments.Length;
- int actualCount =(parameters != null) ? parameters.Length : 0;
- if (formalCount != actualCount)
- throw new TargetParameterCountException(Environment.GetResourceString("Arg_ParmCnt"));
-
- // if we are here we passed all the previous checks. Time to look at the arguments
- if (actualCount > 0)
- {
- Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig);
- Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, sig, false);
- // copy out. This should be made only if ByRef are present.
- for (int index = 0; index < arguments.Length; index++)
- parameters[index] = arguments[index];
- return retValue;
- }
- return RuntimeMethodHandle.InvokeMethod(obj, null, sig, false);
- }
-
- public override MethodBody GetMethodBody()
- {
- MethodBody mb = RuntimeMethodHandle.GetMethodBody(this, ReflectedTypeInternal);
- if (mb != null)
- mb.m_methodBase = this;
- return mb;
- }
-
- public override bool IsSecurityCritical
- {
- get { return true; }
- }
-
- public override bool IsSecuritySafeCritical
- {
- get { return false; }
- }
-
- public override bool IsSecurityTransparent
- {
- get { return false; }
- }
-
- public override bool ContainsGenericParameters
- {
- get
- {
- return (DeclaringType != null && DeclaringType.ContainsGenericParameters);
- }
- }
- #endregion
-
- #region ConstructorInfo Overrides
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public override Object Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
- {
- INVOCATION_FLAGS invocationFlags = InvocationFlags;
-
- // get the declaring TypeHandle early for consistent exceptions in IntrospectionOnly context
- RuntimeTypeHandle declaringTypeHandle = m_declaringType.TypeHandle;
-
- if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE | INVOCATION_FLAGS.INVOCATION_FLAGS_CONTAINS_STACK_POINTERS | INVOCATION_FLAGS.INVOCATION_FLAGS_NO_CTOR_INVOKE)) != 0)
- ThrowNoInvokeException();
-
-#if FEATURE_APPX
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
- if (caller != null && !caller.IsSafeForReflection())
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", FullName));
- }
-#endif
-
- // get the signature
- Signature sig = Signature;
-
- int formalCount = sig.Arguments.Length;
- int actualCount =(parameters != null) ? parameters.Length : 0;
- if (formalCount != actualCount)
- throw new TargetParameterCountException(Environment.GetResourceString("Arg_ParmCnt"));
-
- // We don't need to explicitly invoke the class constructor here,
- // JIT/NGen will insert the call to .cctor in the instance ctor.
-
- // if we are here we passed all the previous checks. Time to look at the arguments
- if (actualCount > 0)
- {
- Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig);
- Object retValue = RuntimeMethodHandle.InvokeMethod(null, arguments, sig, true);
- // copy out. This should be made only if ByRef are present.
- for (int index = 0; index < arguments.Length; index++)
- parameters[index] = arguments[index];
- return retValue;
- }
- return RuntimeMethodHandle.InvokeMethod(null, null, sig, true);
- }
- #endregion
-
- #region ISerializable Implementation
- public void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
- MemberInfoSerializationHolder.GetSerializationInfo(
- info,
- Name,
- ReflectedTypeInternal,
- ToString(),
- SerializationToString(),
- MemberTypes.Constructor,
- null);
- }
-
- internal string SerializationToString()
- {
- // We don't need the return type for constructors.
- return FormatNameAndSig(true);
- }
- #endregion
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/CustomAttribute.cs b/src/mscorlib/src/System/Reflection/CustomAttribute.cs
index b71c7bbff3..96eb45f3e4 100644
--- a/src/mscorlib/src/System/Reflection/CustomAttribute.cs
+++ b/src/mscorlib/src/System/Reflection/CustomAttribute.cs
@@ -18,7 +18,7 @@ using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
-namespace System.Reflection
+namespace System.Reflection
{
[Serializable]
public class CustomAttributeData
@@ -268,7 +268,7 @@ namespace System.Reflection
if (type.IsValueType)
return CustomAttributeEncoding.Undefined;
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidKindOfTypeForCA"), nameof(type));
+ throw new ArgumentException(SR.Argument_InvalidKindOfTypeForCA, nameof(type));
}
private static CustomAttributeType InitCustomAttributeType(RuntimeType parameterType)
{
@@ -300,8 +300,8 @@ namespace System.Reflection
customAttributes[i] = new CustomAttributeData(module, records[i]);
return Array.AsReadOnly(customAttributes);
- }
- #endregion
+ }
+ #endregion
#region Internal Static Members
internal unsafe static CustomAttributeRecord[] GetCustomAttributeRecords(RuntimeModule module, int targetToken)
@@ -361,7 +361,7 @@ namespace System.Reflection
m_scope = scope;
m_ctor = (RuntimeConstructorInfo)RuntimeType.GetMethodBase(scope, caRecord.tkCtor);
- ParameterInfo[] parameters = m_ctor.GetParametersNoCopy();
+ ParameterInfo[] parameters = m_ctor.GetParametersNoCopy();
m_ctorParams = new CustomAttributeCtorParameter[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
m_ctorParams[i] = new CustomAttributeCtorParameter(InitCustomAttributeType((RuntimeType)parameters[i].ParameterType));
@@ -417,8 +417,7 @@ namespace System.Reflection
new CustomAttributeNamedArgument(type.GetField("CallingConvention"), dllImport.CallingConvention),
new CustomAttributeNamedArgument(type.GetField("BestFitMapping"), dllImport.BestFitMapping),
new CustomAttributeNamedArgument(type.GetField("ThrowOnUnmappableChar"), dllImport.ThrowOnUnmappableChar)
-
- });
+});
}
private void Init(FieldOffsetAttribute fieldOffset)
{
@@ -491,11 +490,11 @@ namespace System.Reflection
public override string ToString()
{
string ctorArgs = "";
- for (int i = 0; i < ConstructorArguments.Count; i ++)
+ for (int i = 0; i < ConstructorArguments.Count; i++)
ctorArgs += String.Format(CultureInfo.CurrentCulture, i == 0 ? "{0}" : ", {0}", ConstructorArguments[i]);
string namedArgs = "";
- for (int i = 0; i < NamedArguments.Count; i ++)
+ for (int i = 0; i < NamedArguments.Count; i++)
namedArgs += String.Format(CultureInfo.CurrentCulture, i == 0 && ctorArgs.Length == 0 ? "{0}" : ", {0}", NamedArguments[i]);
return String.Format(CultureInfo.CurrentCulture, "[{0}({1}{2})]", Constructor.DeclaringType.FullName, ctorArgs, namedArgs);
@@ -514,7 +513,7 @@ namespace System.Reflection
public Type AttributeType { get { return Constructor.DeclaringType; } }
public virtual ConstructorInfo Constructor { get { return m_ctor; } }
-
+
public virtual IList<CustomAttributeTypedArgument> ConstructorArguments
{
get
@@ -605,7 +604,7 @@ namespace System.Reflection
else if (property != null)
type = property.PropertyType;
else
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidMemberForNamedArgument"));
+ throw new ArgumentException(SR.Argument_InvalidMemberForNamedArgument);
m_memberInfo = memberInfo;
m_value = new CustomAttributeTypedArgument(type, value);
@@ -627,7 +626,7 @@ namespace System.Reflection
if (m_memberInfo == null)
return base.ToString();
- return String.Format(CultureInfo.CurrentCulture, "{0} = {1}", MemberInfo.Name, TypedValue.ToString(ArgumentType != typeof(object)));
+ return String.Format(CultureInfo.CurrentCulture, "{0} = {1}", MemberInfo.Name, TypedValue.ToString(ArgumentType != typeof(object)));
}
public override int GetHashCode()
{
@@ -640,14 +639,14 @@ namespace System.Reflection
#endregion
#region Internal Members
- internal Type ArgumentType
- {
- get
- {
- return m_memberInfo is FieldInfo ?
- ((FieldInfo)m_memberInfo).FieldType :
- ((PropertyInfo)m_memberInfo).PropertyType;
- }
+ internal Type ArgumentType
+ {
+ get
+ {
+ return m_memberInfo is FieldInfo ?
+ ((FieldInfo)m_memberInfo).FieldType :
+ ((PropertyInfo)m_memberInfo).PropertyType;
+ }
}
#endregion
@@ -730,8 +729,8 @@ namespace System.Reflection
case (CustomAttributeEncoding.Object):
return typeof(object);
- default :
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)encodedType), nameof(encodedType));
+ default:
+ throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, (int)encodedType), nameof(encodedType));
}
}
@@ -776,7 +775,7 @@ namespace System.Reflection
unsafe { return *(double*)&val; }
default:
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)val), nameof(val));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, (int)val), nameof(val));
}
}
private static RuntimeType ResolveType(RuntimeModule scope, string typeName)
@@ -785,7 +784,7 @@ namespace System.Reflection
if (type == null)
throw new InvalidOperationException(
- String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_CATypeResolutionFailed"), typeName));
+ String.Format(CultureInfo.CurrentUICulture, SR.Arg_CATypeResolutionFailed, typeName));
return type;
}
@@ -848,17 +847,17 @@ namespace System.Reflection
else if (encodedType == CustomAttributeEncoding.Type)
{
m_argumentType = typeof(Type);
-
+
m_value = null;
if (encodedArg.StringValue != null)
m_value = ResolveType(scope, encodedArg.StringValue);
}
else if (encodedType == CustomAttributeEncoding.Array)
- {
+ {
encodedType = encodedArg.CustomAttributeType.EncodedArrayType;
Type elementType;
-
+
if (encodedType == CustomAttributeEncoding.Enum)
{
elementType = ResolveType(scope, encodedArg.CustomAttributeType.EnumName);
@@ -869,10 +868,10 @@ namespace System.Reflection
}
m_argumentType = elementType.MakeArrayType();
-
+
if (encodedArg.ArrayValue == null)
{
- m_value = null;
+ m_value = null;
}
else
{
@@ -949,12 +948,12 @@ namespace System.Reflection
return m_argumentType;
}
}
- public object Value
- {
- get
+ public object Value
+ {
+ get
{
return m_value;
- }
+ }
}
#endregion
}
@@ -994,17 +993,17 @@ namespace System.Reflection
[Serializable]
[StructLayout(LayoutKind.Auto)]
internal struct CustomAttributeEncodedArgument
- {
+ {
#region Parser
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void ParseAttributeArguments(
- IntPtr pCa,
- int cCa,
+ IntPtr pCa,
+ int cCa,
ref CustomAttributeCtorParameter[] CustomAttributeCtorParameters,
ref CustomAttributeNamedParameter[] CustomAttributeTypedArgument,
RuntimeAssembly assembly);
- internal static void ParseAttributeArguments(ConstArray attributeBlob,
+ internal static void ParseAttributeArguments(ConstArray attributeBlob,
ref CustomAttributeCtorParameter[] customAttributeCtorParameters,
ref CustomAttributeNamedParameter[] customAttributeNamedParameters,
RuntimeModule customAttributeModule)
@@ -1045,7 +1044,7 @@ namespace System.Reflection
public string StringValue { get { return m_stringValue; } }
#endregion
}
-
+
[Serializable]
[StructLayout(LayoutKind.Auto)]
internal struct CustomAttributeNamedParameter
@@ -1077,7 +1076,7 @@ namespace System.Reflection
public CustomAttributeEncodedArgument EncodedArgument { get { return m_encodedArgument; } }
#endregion
}
-
+
[Serializable]
[StructLayout(LayoutKind.Auto)]
internal struct CustomAttributeCtorParameter
@@ -1110,18 +1109,18 @@ namespace System.Reflection
private CustomAttributeEncoding m_encodedType; // ...array
private CustomAttributeEncoding m_encodedEnumType; // ...enum
private CustomAttributeEncoding m_encodedArrayType; // ...enum type
- private CustomAttributeEncoding m_padding;
+ private CustomAttributeEncoding m_padding;
#endregion
#region Constructor
- public CustomAttributeType(CustomAttributeEncoding encodedType, CustomAttributeEncoding encodedArrayType,
+ public CustomAttributeType(CustomAttributeEncoding encodedType, CustomAttributeEncoding encodedArrayType,
CustomAttributeEncoding encodedEnumType, string enumName)
{
m_encodedType = encodedType;
m_encodedArrayType = encodedArrayType;
m_encodedEnumType = encodedEnumType;
m_enumName = enumName;
- m_padding = m_encodedType;
+ m_padding = m_encodedType;
}
#endregion
@@ -1145,7 +1144,7 @@ namespace System.Reflection
{
Contract.Requires(type != null);
- if (type.GetElementType() != null)
+ if (type.GetElementType() != null)
return false;
if (PseudoCustomAttribute.IsDefined(type, caType))
@@ -1252,7 +1251,7 @@ namespace System.Reflection
return IsCustomAttributeDefined(parameter.GetRuntimeModule(), parameter.MetadataToken, caType);
}
- internal static bool IsDefined(RuntimeAssembly assembly, RuntimeType caType)
+ internal static bool IsDefined(RuntimeAssembly assembly, RuntimeType caType)
{
Contract.Requires(assembly != null);
Contract.Requires(caType != null);
@@ -1279,8 +1278,8 @@ namespace System.Reflection
Contract.Requires(type != null);
Contract.Requires(caType != null);
- if (type.GetElementType() != null)
- return (caType.IsValueType) ? EmptyArray<Object>.Value : CreateAttributeArrayHelper(caType, 0);
+ if (type.GetElementType() != null)
+ return (caType.IsValueType) ? Array.Empty<Object>() : CreateAttributeArrayHelper(caType, 0);
if (type.IsGenericType && !type.IsGenericTypeDefinition)
type = type.GetGenericTypeDefinition() as RuntimeType;
@@ -1323,7 +1322,7 @@ namespace System.Reflection
private static bool AllowCriticalCustomAttributes(RuntimeType type)
{
- if (type.IsGenericParameter)
+ if (type.IsGenericParameter)
{
// Generic parameters don't have transparency state, so look at the
// declaring method/type. One of declaringMethod or declaringType
@@ -1331,7 +1330,7 @@ namespace System.Reflection
MethodBase declaringMethod = type.DeclaringMethod;
if (declaringMethod != null)
{
- return AllowCriticalCustomAttributes(declaringMethod);
+ return AllowCriticalCustomAttributes(declaringMethod);
}
else
{
@@ -1394,9 +1393,9 @@ namespace System.Reflection
bool useObjectArray = (caType == null || caType.IsValueType || caType.ContainsGenericParameters);
Type arrayType = useObjectArray ? typeof(object) : caType;
- while (pcaCount > 0)
+ while (pcaCount > 0)
result.Add(pca[--pcaCount]);
-
+
while (method != null)
{
object[] attributes = GetCustomAttributes(method.GetRuntimeModule(), method.MetadataToken, 0, caType, mustBeInheritable, result, !AllowCriticalCustomAttributes(method));
@@ -1478,12 +1477,12 @@ namespace System.Reflection
int pcaCount = 0;
Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(parameter, caType, out pcaCount);
- object[] attributes = GetCustomAttributes(parameter.GetRuntimeModule(), parameter.MetadataToken, pcaCount, caType, !AllowCriticalCustomAttributes(parameter));
+ object[] attributes = GetCustomAttributes(parameter.GetRuntimeModule(), parameter.MetadataToken, pcaCount, caType, !AllowCriticalCustomAttributes(parameter));
if (pcaCount > 0) Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount);
return attributes;
}
- internal static Object[] GetCustomAttributes(RuntimeAssembly assembly, RuntimeType caType)
+ internal static Object[] GetCustomAttributes(RuntimeAssembly assembly, RuntimeType caType)
{
Contract.Requires(assembly != null);
Contract.Requires(caType != null);
@@ -1497,7 +1496,7 @@ namespace System.Reflection
return attributes;
}
- internal static Object[] GetCustomAttributes(RuntimeModule module, RuntimeType caType)
+ internal static Object[] GetCustomAttributes(RuntimeModule module, RuntimeType caType)
{
Contract.Requires(module != null);
Contract.Requires(caType != null);
@@ -1525,7 +1524,7 @@ namespace System.Reflection
RuntimeModule decoratedModule, int decoratedMetadataToken, RuntimeType attributeFilterType, int attributeCtorToken, bool mustBeInheritable)
{
if (decoratedModule.Assembly.ReflectionOnly)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyCA"));
+ throw new InvalidOperationException(SR.Arg_ReflectionOnlyCA);
Contract.EndContractBlock();
CustomAttributeRecord[] car = CustomAttributeData.GetCustomAttributeRecords(decoratedModule, decoratedMetadataToken);
@@ -1577,11 +1576,11 @@ namespace System.Reflection
}
private unsafe static object[] GetCustomAttributes(
- RuntimeModule decoratedModule, int decoratedMetadataToken, int pcaCount,
+ RuntimeModule decoratedModule, int decoratedMetadataToken, int pcaCount,
RuntimeType attributeFilterType, bool mustBeInheritable, IList derivedAttributes, bool isDecoratedTargetSecurityTransparent)
{
if (decoratedModule.Assembly.ReflectionOnly)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyCA"));
+ throw new InvalidOperationException(SR.Arg_ReflectionOnlyCA);
Contract.EndContractBlock();
MetadataImport scope = decoratedModule.MetadataImport;
@@ -1614,8 +1613,8 @@ namespace System.Reflection
IntPtr blobEnd = (IntPtr)((byte*)blobStart + caRecord.blob.Length);
int blobLen = (int)((byte*)blobEnd - (byte*)blobStart);
- if (!FilterCustomAttributeRecord(caRecord, scope, ref lastAptcaOkAssembly,
- decoratedModule, decoratedMetadataToken, attributeFilterType, mustBeInheritable,
+ if (!FilterCustomAttributeRecord(caRecord, scope, ref lastAptcaOkAssembly,
+ decoratedModule, decoratedMetadataToken, attributeFilterType, mustBeInheritable,
attributes, derivedAttributes,
out attributeType, out ctor, out ctorHasParameters, out isVarArg))
continue;
@@ -1628,16 +1627,15 @@ namespace System.Reflection
}
else
{
-
}
// Leverage RuntimeConstructorInfo standard .ctor verfication
- RuntimeConstructorInfo.CheckCanCreateInstance(attributeType, isVarArg);
+ RuntimeConstructorInfo.CheckCanCreateInstance(attributeType, isVarArg);
// Create custom attribute object
if (ctorHasParameters)
{
- attribute = CreateCaObject(decoratedModule, ctor, ref blobStart, blobEnd, out cNamedArgs);
+ attribute = CreateCaObject(decoratedModule, ctor, ref blobStart, blobEnd, out cNamedArgs);
}
else
{
@@ -1674,7 +1672,7 @@ namespace System.Reflection
bool isProperty;
RuntimeType type;
object value;
-
+
IntPtr blobItr = caRecord.blob.Signature;
GetPropertyOrFieldData(decoratedModule, ref blobStart, blobEnd, out name, out isProperty, out type, out value);
@@ -1702,12 +1700,12 @@ namespace System.Reflection
if (property == null)
{
throw new CustomAttributeFormatException(
- String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString(
- isProperty ? "RFLCT.InvalidPropFail" : "RFLCT.InvalidFieldFail"), name));
+ String.Format(CultureInfo.CurrentUICulture,
+ isProperty ? SR.RFLCT_InvalidPropFail : SR.RFLCT_InvalidFieldFail, name));
}
RuntimeMethodInfo setMethod = property.GetSetMethod(true) as RuntimeMethodInfo;
-
+
// Public properties may have non-public setter methods
if (!setMethod.IsPublic)
continue;
@@ -1733,8 +1731,8 @@ namespace System.Reflection
catch (Exception e)
{
throw new CustomAttributeFormatException(
- String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString(
- isProperty ? "RFLCT.InvalidPropFail" : "RFLCT.InvalidFieldFail"), name), e);
+ String.Format(CultureInfo.CurrentUICulture,
+ isProperty ? SR.RFLCT_InvalidPropFail : SR.RFLCT_InvalidFieldFail, name), e);
}
#endregion
}
@@ -1756,7 +1754,7 @@ namespace System.Reflection
private unsafe static bool FilterCustomAttributeRecord(
CustomAttributeRecord caRecord,
MetadataImport scope,
- ref Assembly lastAptcaOkAssembly,
+ ref Assembly lastAptcaOkAssembly,
RuntimeModule decoratedModule,
MetadataToken decoratedToken,
RuntimeType attributeFilterType,
@@ -1772,7 +1770,7 @@ namespace System.Reflection
attributeType = null;
ctorHasParameters = false;
isVarArg = false;
-
+
IntPtr blobStart = caRecord.blob.Signature;
IntPtr blobEnd = (IntPtr)((byte*)blobStart + caRecord.blob.Length);
@@ -1817,13 +1815,13 @@ namespace System.Reflection
// Visibility checks
MetadataToken tkParent = new MetadataToken();
-
+
if (decoratedToken.IsParamDef)
{
tkParent = new MetadataToken(scope.GetParentToken(decoratedToken));
tkParent = new MetadataToken(scope.GetParentToken(tkParent));
- }
- else if (decoratedToken.IsMethodDef || decoratedToken.IsProperty || decoratedToken.IsEvent || decoratedToken.IsFieldDef)
+ }
+ else if (decoratedToken.IsMethodDef || decoratedToken.IsProperty || decoratedToken.IsEvent || decoratedToken.IsFieldDef)
{
tkParent = new MetadataToken(scope.GetParentToken(decoratedToken));
}
@@ -1842,7 +1840,7 @@ namespace System.Reflection
else
{
// We need to relax this when we add support for other types of decorated tokens.
- Debug.Assert(decoratedToken.IsModule || decoratedToken.IsAssembly,
+ Debug.Assert(decoratedToken.IsModule || decoratedToken.IsAssembly,
"The decoratedToken must be either an assembly, a module, a type, or a member.");
}
@@ -1907,7 +1905,7 @@ namespace System.Reflection
if (attributeUsageAttribute != null)
throw new FormatException(String.Format(
- CultureInfo.CurrentUICulture, Environment.GetResourceString("Format_AttributeUsage"), attributeType));
+ CultureInfo.CurrentUICulture, SR.Format_AttributeUsage, attributeType));
AttributeTargets targets;
bool inherited, allowMultiple;
@@ -1940,7 +1938,7 @@ namespace System.Reflection
{
byte* pBlob = (byte*)blob;
byte* pBlobEnd = (byte*)blobEnd;
- int cNamedArgs;
+ int cNamedArgs;
object ca = _CreateCaObject(module, ctor, &pBlob, pBlobEnd, &cNamedArgs);
blob = (IntPtr)pBlob;
namedArgs = cNamedArgs;
@@ -2025,9 +2023,9 @@ namespace System.Reflection
//AllowMultiple is true for TypeForwardedToAttribute
//Debug.Assert(usage.AllowMultiple == false, "Pseudo CA Error");
}
-#endregion
+ #endregion
-#region Internal Static
+ #region Internal Static
internal static bool IsSecurityAttribute(RuntimeType type)
{
// TODO: Cleanup
@@ -2083,12 +2081,12 @@ namespace System.Reflection
if (!all && s_pca.GetValueOrDefault(caType) == null && !IsSecurityAttribute(caType))
return false;
- if (all || caType == (RuntimeType)typeof(SerializableAttribute))
- {
+ if (all || caType == (RuntimeType)typeof(SerializableAttribute))
+ {
if (SerializableAttribute.IsDefined(type)) return true;
}
- if (all || caType == (RuntimeType)typeof(ComImportAttribute))
- {
+ if (all || caType == (RuntimeType)typeof(ComImportAttribute))
+ {
if (ComImportAttribute.IsDefined(type)) return true;
}
if (all || IsSecurityAttribute(caType))
@@ -2322,8 +2320,8 @@ namespace System.Reflection
{
if (FieldOffsetAttribute.IsDefined(field)) return true;
}
- if (all || caType == (RuntimeType)typeof(NonSerializedAttribute))
- {
+ if (all || caType == (RuntimeType)typeof(NonSerializedAttribute))
+ {
if (NonSerializedAttribute.IsDefined(field)) return true;
}
@@ -2392,6 +2390,6 @@ namespace System.Reflection
{
return false;
}
-#endregion
+ #endregion
}
}
diff --git a/src/mscorlib/src/System/Reflection/CustomAttributeExtensions.cs b/src/mscorlib/src/System/Reflection/CustomAttributeExtensions.cs
index c3287e17d1..24e5055b8d 100644
--- a/src/mscorlib/src/System/Reflection/CustomAttributeExtensions.cs
+++ b/src/mscorlib/src/System/Reflection/CustomAttributeExtensions.cs
@@ -1,6 +1,7 @@
// 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.Collections.Generic;
namespace System.Reflection
diff --git a/src/mscorlib/src/System/Reflection/CustomAttributeFormatException.cs b/src/mscorlib/src/System/Reflection/CustomAttributeFormatException.cs
deleted file mode 100644
index 9aee911a6c..0000000000
--- a/src/mscorlib/src/System/Reflection/CustomAttributeFormatException.cs
+++ /dev/null
@@ -1,37 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// CustomAttributeFormatException is thrown when the binary format of a
-//
-// custom attribute is invalid.
-//
-//
-namespace System.Reflection {
- using System;
- using ApplicationException = System.ApplicationException;
- using System.Runtime.Serialization;
- [Serializable]
- public class CustomAttributeFormatException : FormatException {
-
- public CustomAttributeFormatException()
- : base(Environment.GetResourceString("Arg_CustomAttributeFormatException")) {
- SetErrorCode(__HResults.COR_E_CUSTOMATTRIBUTEFORMAT);
- }
-
- public CustomAttributeFormatException(String message) : base(message) {
- SetErrorCode(__HResults.COR_E_CUSTOMATTRIBUTEFORMAT);
- }
-
- public CustomAttributeFormatException(String message, Exception inner) : base(message, inner) {
- SetErrorCode(__HResults.COR_E_CUSTOMATTRIBUTEFORMAT);
- }
-
- protected CustomAttributeFormatException(SerializationInfo info, StreamingContext context) : base(info, context) {
- }
-
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/DefaultMemberAttribute.cs b/src/mscorlib/src/System/Reflection/DefaultMemberAttribute.cs
deleted file mode 100644
index 4232fcd2a1..0000000000
--- a/src/mscorlib/src/System/Reflection/DefaultMemberAttribute.cs
+++ /dev/null
@@ -1,39 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// DefaultMemberAttribute is defines the Member of a Type that is the "default"
-//
-// member used by Type.InvokeMember. The default member is simply a name given
-// to a type.
-//
-//
-//
-//
-namespace System.Reflection {
-
- using System;
-
-[Serializable]
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface)]
- public sealed class DefaultMemberAttribute : Attribute
- {
- // The name of the member
- private String m_memberName;
-
- // You must provide the name of the member, this is required
- public DefaultMemberAttribute(String memberName) {
- m_memberName = memberName;
- }
-
- // A get accessor to return the name from the attribute.
- // NOTE: There is no setter because the name must be provided
- // to the constructor. The name is not optional.
- public String MemberName {
- get {return m_memberName;}
- }
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/Emit/AQNBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/AQNBuilder.cs
index fb9324902a..e7499e57f0 100644
--- a/src/mscorlib/src/System/Reflection/Emit/AQNBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/AQNBuilder.cs
@@ -20,7 +20,7 @@ namespace System.Reflection.Emit
FullName,
AssemblyQualifiedName,
}
-
+
#region QCalls
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
@@ -76,7 +76,7 @@ namespace System.Reflection.Emit
if (!type.IsGenericTypeDefinition && type.ContainsGenericParameters)
return null;
}
-
+
TypeNameBuilder tnb = new TypeNameBuilder(CreateTypeNameBuilder());
tnb.Clear();
tnb.ConstructAssemblyQualifiedNameWorker(type, format);
@@ -100,20 +100,20 @@ namespace System.Reflection.Emit
{
if (elementType.HasElementType)
AddElementType(elementType.GetElementType());
-
+
if (elementType.IsPointer)
AddPointer();
else if (elementType.IsByRef)
AddByRef();
- else if (elementType.IsSzArray)
+ else if (elementType.IsSZArray)
AddSzArray();
else if (elementType.IsArray)
AddArray(elementType.GetArrayRank());
}
-
+
private void ConstructAssemblyQualifiedNameWorker(Type type, Format format)
{
Type rootType = type;
@@ -125,13 +125,13 @@ namespace System.Reflection.Emit
List<Type> nestings = new List<Type>();
for (Type t = rootType; t != null; t = t.IsGenericParameter ? null : t.DeclaringType)
nestings.Add(t);
-
+
for (int i = nestings.Count - 1; i >= 0; i--)
{
Type enclosingType = nestings[i];
string name = enclosingType.Name;
- if (i == nestings.Count - 1 && enclosingType.Namespace != null && enclosingType.Namespace.Length != 0)
+ if (i == nestings.Count - 1 && enclosingType.Namespace != null && enclosingType.Namespace.Length != 0)
name = enclosingType.Namespace + "." + name;
AddName(name);
@@ -146,7 +146,7 @@ namespace System.Reflection.Emit
for (int i = 0; i < genericArguments.Length; i++)
{
Format genericArgumentsFormat = format == Format.FullName ? Format.AssemblyQualifiedName : format;
-
+
OpenGenericArgument();
ConstructAssemblyQualifiedNameWorker(genericArguments[i], genericArgumentsFormat);
CloseGenericArgument();
@@ -160,7 +160,7 @@ namespace System.Reflection.Emit
if (format == Format.AssemblyQualifiedName)
AddAssemblySpec(type.Module.Assembly.FullName);
}
-
+
private void OpenGenericArguments() { OpenGenericArguments(m_typeNameBuilder); }
private void CloseGenericArguments() { CloseGenericArguments(m_typeNameBuilder); }
private void OpenGenericArgument() { OpenGenericArgument(m_typeNameBuilder); }
diff --git a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs
index 5575e28917..6d9cb0db2f 100644
--- a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs
@@ -48,11 +48,11 @@ namespace System.Reflection.Emit
None = 0x00000000,
// Security attributes which affect the module security descriptor
- AllCritical = 0x00000001,
- Aptca = 0x00000002,
- Critical = 0x00000004,
- Transparent = 0x00000008,
- TreatAsSafe = 0x00000010,
+ AllCritical = 0x00000001,
+ Aptca = 0x00000002,
+ Critical = 0x00000004,
+ Transparent = 0x00000008,
+ TreatAsSafe = 0x00000010,
}
// When the user calls AppDomain.DefineDynamicAssembly the loader creates a new InternalAssemblyBuilder.
@@ -61,7 +61,7 @@ namespace System.Reflection.Emit
// Assembly to an AssemblyBuilder and emit code with the elevated permissions of the trusted code which
// origionally created the AssemblyBuilder via DefineDynamicAssembly. Today, this can no longer happen
// because the Assembly returned via AssemblyGetAssemblies() will be an InternalAssemblyBuilder.
-
+
// Only the caller of DefineDynamicAssembly will get an AssemblyBuilder.
// There is a 1-1 relationship between InternalAssemblyBuilder and AssemblyBuilder.
// AssemblyBuilder is composed of its InternalAssemblyBuilder.
@@ -94,39 +94,39 @@ namespace System.Reflection.Emit
#region Methods inherited from Assembly
public override String[] GetManifestResourceNames()
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
}
public override FileStream GetFile(String name)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
}
public override FileStream[] GetFiles(bool getResourceModules)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
}
public override Stream GetManifestResourceStream(Type type, String name)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
}
public override Stream GetManifestResourceStream(String name)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
}
public override ManifestResourceInfo GetManifestResourceInfo(String resourceName)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
}
public override String Location
{
get
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
}
}
@@ -134,13 +134,13 @@ namespace System.Reflection.Emit
{
get
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
}
}
public override Type[] GetExportedTypes()
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ throw new NotSupportedException(SR.NotSupported_DynamicAssembly);
}
public override String ImageRuntimeVersion
@@ -177,16 +177,12 @@ namespace System.Reflection.Emit
private bool m_fManifestModuleUsedAsDefinedModule;
internal const string MANIFEST_MODULE_NAME = "RefEmit_InMemoryManifestModule";
-#if FEATURE_APPX
- private bool m_profileAPICheck;
-#endif
-
internal ModuleBuilder GetModuleBuilder(InternalModuleBuilder module)
{
Contract.Requires(module != null);
Debug.Assert(this.InternalAssembly == module.Assembly);
- lock(SyncRoot)
+ lock (SyncRoot)
{
// in CoreCLR there is only one module in each dynamic assembly, the manifest module
if (m_manifestModuleBuilder.InternalModule == module)
@@ -216,16 +212,6 @@ namespace System.Reflection.Emit
{
return InternalAssembly.GetNativeHandle();
}
-
-#if FEATURE_APPX
- internal bool ProfileAPICheck
- {
- get
- {
- return m_profileAPICheck;
- }
- }
-#endif
#endregion
#region Constructor
@@ -242,13 +228,10 @@ namespace System.Reflection.Emit
throw new ArgumentNullException(nameof(name));
if (access != AssemblyBuilderAccess.Run
-#if FEATURE_REFLECTION_ONLY_LOAD
- && access != AssemblyBuilderAccess.ReflectionOnly
-#endif // FEATURE_REFLECTION_ONLY_LOAD
&& access != AssemblyBuilderAccess.RunAndCollect
)
{
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)access), nameof(access));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, (int)access), nameof(access));
}
if (securityContextSource < SecurityContextSource.CurrentAppDomain ||
@@ -304,14 +287,7 @@ namespace System.Reflection.Emit
name.Name,
access,
dir);
-#if FEATURE_APPX
- if (AppDomain.ProfileAPICheck)
- {
- RuntimeAssembly creator = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
- if (creator != null && !creator.IsFrameworkAssembly())
- m_profileAPICheck = true;
- }
-#endif
+
// Make sure that ManifestModule is properly initialized
// We need to do this before setting any CustomAttribute
InitManifestModule();
@@ -331,7 +307,7 @@ namespace System.Reflection.Emit
// because it hasn't been initialized.
// However, it can be used to set the custom attribute on the Assembly
m_manifestModuleBuilder = new ModuleBuilder(this, modBuilder);
-
+
// We are only setting the name in the managed ModuleBuilderData here.
// The name in the underlying metadata will be set when the
// manifest module is created during nCreateDynamicAssembly.
@@ -351,7 +327,7 @@ namespace System.Reflection.Emit
* to have a strong name and a hash will be computed when the assembly
* is saved.
**********************************************/
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public static AssemblyBuilder DefineDynamicAssembly(
AssemblyName name,
AssemblyBuilderAccess access)
@@ -363,7 +339,7 @@ namespace System.Reflection.Emit
null, ref stackMark, null, SecurityContextSource.CurrentAssembly);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public static AssemblyBuilder DefineDynamicAssembly(
AssemblyName name,
AssemblyBuilderAccess access,
@@ -425,9 +401,9 @@ namespace System.Reflection.Emit
* a transient module.
*
**********************************************/
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public ModuleBuilder DefineDynamicModule(
- String name)
+ String name)
{
Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
@@ -435,39 +411,39 @@ namespace System.Reflection.Emit
return DefineDynamicModuleInternal(name, false, ref stackMark);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public ModuleBuilder DefineDynamicModule(
- String name,
- bool emitSymbolInfo) // specify if emit symbol info or not
+ String name,
+ bool emitSymbolInfo) // specify if emit symbol info or not
{
Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return DefineDynamicModuleInternal( name, emitSymbolInfo, ref stackMark );
+ return DefineDynamicModuleInternal(name, emitSymbolInfo, ref stackMark);
}
private ModuleBuilder DefineDynamicModuleInternal(
- String name,
- bool emitSymbolInfo, // specify if emit symbol info or not
+ String name,
+ bool emitSymbolInfo, // specify if emit symbol info or not
ref StackCrawlMark stackMark)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineDynamicModuleInternalNoLock(name, emitSymbolInfo, ref stackMark);
}
}
private ModuleBuilder DefineDynamicModuleInternalNoLock(
- String name,
- bool emitSymbolInfo, // specify if emit symbol info or not
+ String name,
+ bool emitSymbolInfo, // specify if emit symbol info or not
ref StackCrawlMark stackMark)
{
if (name == null)
throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
if (name[0] == '\0')
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidName"), nameof(name));
+ throw new ArgumentException(SR.Argument_InvalidName, nameof(name));
Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
Contract.EndContractBlock();
@@ -481,7 +457,7 @@ namespace System.Reflection.Emit
// create the dynamic module- only one ModuleBuilder per AssemblyBuilder can be created
if (m_fManifestModuleUsedAsDefinedModule == true)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoMultiModuleAssembly"));
+ throw new InvalidOperationException(SR.InvalidOperation_NoMultiModuleAssembly);
// Init(...) has already been called on m_manifestModuleBuilder in InitManifestModule()
dynModule = m_manifestModuleBuilder;
@@ -492,7 +468,7 @@ namespace System.Reflection.Emit
writer = SymWrapperCore.SymWriter.CreateSymWriter();
String fileName = "Unused"; // this symfile is never written to disk so filename does not matter.
-
+
// Pass the "real" module to the VM
pInternalSymWriter = ModuleBuilder.nCreateISymWriterForDynamicModule(dynModule.InternalModule, fileName);
@@ -512,14 +488,14 @@ namespace System.Reflection.Emit
return dynModule;
} // DefineDynamicModuleInternalNoLock
-#endregion
+ #endregion
internal void CheckContext(params Type[][] typess)
{
if (typess == null)
return;
-
- foreach(Type[] types in typess)
+
+ foreach (Type[] types in typess)
if (types != null)
CheckContext(types);
}
@@ -528,23 +504,23 @@ namespace System.Reflection.Emit
{
if (types == null)
return;
-
+
foreach (Type type in types)
{
if (type == null)
continue;
if (type.Module == null || type.Module.Assembly == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_TypeNotValid"));
+ throw new ArgumentException(SR.Argument_TypeNotValid);
if (type.Module.Assembly == typeof(object).Module.Assembly)
continue;
if (type.Module.Assembly.ReflectionOnly && !ReflectionOnly)
- throw new InvalidOperationException(Environment.GetResourceString("Arugment_EmitMixedContext1", type.AssemblyQualifiedName));
+ throw new InvalidOperationException(SR.Format(SR.Arugment_EmitMixedContext1, type.AssemblyQualifiedName));
if (!type.Module.Assembly.ReflectionOnly && ReflectionOnly)
- throw new InvalidOperationException(Environment.GetResourceString("Arugment_EmitMixedContext2", type.AssemblyQualifiedName));
+ throw new InvalidOperationException(SR.Format(SR.Arugment_EmitMixedContext2, type.AssemblyQualifiedName));
}
}
@@ -585,27 +561,27 @@ namespace System.Reflection.Emit
{
return InternalAssembly.GetManifestResourceNames();
}
-
+
public override FileStream GetFile(String name)
{
return InternalAssembly.GetFile(name);
}
-
+
public override FileStream[] GetFiles(bool getResourceModules)
{
return InternalAssembly.GetFiles(getResourceModules);
}
-
+
public override Stream GetManifestResourceStream(Type type, String name)
{
return InternalAssembly.GetManifestResourceStream(type, name);
}
-
+
public override Stream GetManifestResourceStream(String name)
{
return InternalAssembly.GetManifestResourceStream(name);
}
-
+
public override ManifestResourceInfo GetManifestResourceInfo(String resourceName)
{
return InternalAssembly.GetManifestResourceInfo(resourceName);
@@ -626,7 +602,7 @@ namespace System.Reflection.Emit
return InternalAssembly.ImageRuntimeVersion;
}
}
-
+
public override String CodeBase
{
get
@@ -637,9 +613,9 @@ namespace System.Reflection.Emit
// Override the EntryPoint method on Assembly.
// This doesn't need to be synchronized because it is simple enough
- public override MethodInfo EntryPoint
+ public override MethodInfo EntryPoint
{
- get
+ get
{
return m_assemblyData.m_entryPointMethod;
}
@@ -721,7 +697,7 @@ namespace System.Reflection.Emit
return InternalAssembly.GetLoadedModules(getResourceModules);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public override Assembly GetSatelliteAssembly(CultureInfo culture)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -729,7 +705,7 @@ namespace System.Reflection.Emit
}
// Useful for binding to a very specific version of a satellite assembly
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public override Assembly GetSatelliteAssembly(CultureInfo culture, Version version)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -738,7 +714,8 @@ namespace System.Reflection.Emit
public override bool IsDynamic
{
- get {
+ get
+ {
return true;
}
}
@@ -751,28 +728,28 @@ namespace System.Reflection.Emit
*
**********************************************/
public ModuleBuilder GetDynamicModule(
- String name) // the name of module for the look up
+ String name) // the name of module for the look up
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return GetDynamicModuleNoLock(name);
}
}
private ModuleBuilder GetDynamicModuleNoLock(
- String name) // the name of module for the look up
+ String name) // the name of module for the look up
{
if (name == null)
throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
Contract.EndContractBlock();
BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.GetDynamicModule( " + name + " )");
int size = m_assemblyData.m_moduleBuilderList.Count;
for (int i = 0; i < size; i++)
{
- ModuleBuilder moduleBuilder = (ModuleBuilder) m_assemblyData.m_moduleBuilderList[i];
+ ModuleBuilder moduleBuilder = (ModuleBuilder)m_assemblyData.m_moduleBuilderList[i];
if (moduleBuilder.m_moduleData.m_strModuleName.Equals(name))
{
return moduleBuilder;
@@ -792,8 +769,8 @@ namespace System.Reflection.Emit
if (binaryAttribute == null)
throw new ArgumentNullException(nameof(binaryAttribute));
Contract.EndContractBlock();
-
- lock(SyncRoot)
+
+ lock (SyncRoot)
{
SetCustomAttributeNoLock(con, binaryAttribute);
}
@@ -828,7 +805,7 @@ namespace System.Reflection.Emit
}
Contract.EndContractBlock();
- lock(SyncRoot)
+ lock (SyncRoot)
{
SetCustomAttributeNoLock(customBuilder);
}
@@ -837,7 +814,7 @@ namespace System.Reflection.Emit
private void SetCustomAttributeNoLock(CustomAttributeBuilder customBuilder)
{
customBuilder.CreateCustomAttribute(
- m_manifestModuleBuilder,
+ m_manifestModuleBuilder,
AssemblyBuilderData.m_tkAssembly); // This is the AssemblyDef token
// Track the CA for persistence
@@ -852,11 +829,11 @@ namespace System.Reflection.Emit
* Private methods
*
**********************************************/
-
+
/**********************************************
* Make a private constructor so these cannot be constructed externally.
* @internonly
**********************************************/
- private AssemblyBuilder() {}
+ private AssemblyBuilder() { }
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderAccess.cs b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderAccess.cs
index b3d1711307..ead2fafcef 100644
--- a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderAccess.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderAccess.cs
@@ -7,16 +7,13 @@ using System;
// This enumeration defines the access modes for a dynamic assembly.
// EE uses these enum values..look for m_dwDynamicAssemblyAccess in Assembly.hpp
-namespace System.Reflection.Emit
+namespace System.Reflection.Emit
{
[Serializable]
[Flags]
public enum AssemblyBuilderAccess
{
Run = 1,
-#if FEATURE_REFLECTION_ONLY_LOAD
- ReflectionOnly = 6, // 4 | Save,
-#endif // FEATURE_REFLECTION_ONLY_LOAD
RunAndCollect = 8 | Run
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderData.cs b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderData.cs
index 7ac9daeac0..529ba54514 100644
--- a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderData.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderData.cs
@@ -6,7 +6,8 @@
////////////////////////////////////////////////////////////////////////////////
//
-namespace System.Reflection.Emit {
+namespace System.Reflection.Emit
+{
using System;
using IList = System.Collections.IList;
using System.Collections.Generic;
@@ -25,10 +26,10 @@ namespace System.Reflection.Emit {
internal class AssemblyBuilderData
{
internal AssemblyBuilderData(
- InternalAssemblyBuilder assembly,
- String strAssemblyName,
- AssemblyBuilderAccess access,
- String dir)
+ InternalAssemblyBuilder assembly,
+ String strAssemblyName,
+ AssemblyBuilderAccess access,
+ String dir)
{
m_assembly = assembly;
m_strAssemblyName = strAssemblyName;
@@ -44,8 +45,8 @@ namespace System.Reflection.Emit {
m_strDir = dir;
m_peFileKind = PEFileKinds.Dll;
- }
-
+ }
+
// Helper to add a dynamic module into the tracking list
internal void AddModule(ModuleBuilder dynModule)
{
@@ -56,7 +57,6 @@ namespace System.Reflection.Emit {
// Helper to track CAs to persist onto disk
internal void AddCustomAttribute(CustomAttributeBuilder customBuilder)
{
-
// make sure we have room for this CA
if (m_CABuilders == null)
{
@@ -64,31 +64,30 @@ namespace System.Reflection.Emit {
}
if (m_iCABuilder == m_CABuilders.Length)
{
- CustomAttributeBuilder[] tempCABuilders = new CustomAttributeBuilder[m_iCABuilder * 2];
+ CustomAttributeBuilder[] tempCABuilders = new CustomAttributeBuilder[m_iCABuilder * 2];
Array.Copy(m_CABuilders, 0, tempCABuilders, 0, m_iCABuilder);
- m_CABuilders = tempCABuilders;
+ m_CABuilders = tempCABuilders;
}
m_CABuilders[m_iCABuilder] = customBuilder;
-
+
m_iCABuilder++;
}
// Helper to track CAs to persist onto disk
internal void AddCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
-
// make sure we have room for this CA
if (m_CABytes == null)
{
m_CABytes = new byte[m_iInitialSize][];
- m_CACons = new ConstructorInfo[m_iInitialSize];
+ m_CACons = new ConstructorInfo[m_iInitialSize];
}
if (m_iCAs == m_CABytes.Length)
{
// enlarge the arrays
- byte[][] temp = new byte[m_iCAs * 2][];
+ byte[][] temp = new byte[m_iCAs * 2][];
ConstructorInfo[] tempCon = new ConstructorInfo[m_iCAs * 2];
- for (int i=0; i < m_iCAs; i++)
+ for (int i = 0; i < m_iCAs; i++)
{
temp[i] = m_CABytes[i];
tempCon[i] = m_CACons[i];
@@ -103,12 +102,12 @@ namespace System.Reflection.Emit {
m_CACons[m_iCAs] = con;
m_iCAs++;
}
-
+
// Helper to ensure the type name is unique underneath assemblyBuilder
internal void CheckTypeNameConflict(String strTypeName, TypeBuilder enclosingType)
{
- BCLDebug.Log("DYNIL","## DYNIL LOGGING: AssemblyBuilderData.CheckTypeNameConflict( " + strTypeName + " )");
- for (int i = 0; i < m_moduleBuilderList.Count; i++)
+ BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilderData.CheckTypeNameConflict( " + strTypeName + " )");
+ for (int i = 0; i < m_moduleBuilderList.Count; i++)
{
ModuleBuilder curModule = m_moduleBuilderList[i];
curModule.CheckTypeNameConflict(strTypeName, enclosingType);
@@ -121,60 +120,59 @@ namespace System.Reflection.Emit {
// if (enclosingType == null && m_assembly.GetType(strTypeName, false, false) != null)
// {
// // Cannot have two types with the same name
- // throw new ArgumentException(Environment.GetResourceString("Argument_DuplicateTypeName"));
+ // throw new ArgumentException(SR.Argument_DuplicateTypeName);
// }
}
-
- internal List<ModuleBuilder> m_moduleBuilderList;
- internal List<ResWriterData> m_resWriterList;
- internal String m_strAssemblyName;
- internal AssemblyBuilderAccess m_access;
+
+ internal List<ModuleBuilder> m_moduleBuilderList;
+ internal List<ResWriterData> m_resWriterList;
+ internal String m_strAssemblyName;
+ internal AssemblyBuilderAccess m_access;
private InternalAssemblyBuilder m_assembly;
-
- internal Type[] m_publicComTypeList;
- internal int m_iPublicComTypeCount;
-
- internal bool m_isSaved;
- internal const int m_iInitialSize = 16;
- internal String m_strDir;
+
+ internal Type[] m_publicComTypeList;
+ internal int m_iPublicComTypeCount;
+
+ internal bool m_isSaved;
+ internal const int m_iInitialSize = 16;
+ internal String m_strDir;
// hard coding the assembly def token
- internal const int m_tkAssembly = 0x20000001;
-
+ internal const int m_tkAssembly = 0x20000001;
+
// tracking AssemblyDef's CAs for persistence to disk
internal CustomAttributeBuilder[] m_CABuilders;
- internal int m_iCABuilder;
- internal byte[][] m_CABytes;
- internal ConstructorInfo[] m_CACons;
- internal int m_iCAs;
- internal PEFileKinds m_peFileKind; // assembly file kind
- internal MethodInfo m_entryPointMethod;
- internal Assembly m_ISymWrapperAssembly;
+ internal int m_iCABuilder;
+ internal byte[][] m_CABytes;
+ internal ConstructorInfo[] m_CACons;
+ internal int m_iCAs;
+ internal PEFileKinds m_peFileKind; // assembly file kind
+ internal MethodInfo m_entryPointMethod;
+ internal Assembly m_ISymWrapperAssembly;
// For unmanaged resources
- internal String m_strResourceFileName;
- internal byte[] m_resourceBytes;
- internal NativeVersionInfo m_nativeVersion;
- internal bool m_hasUnmanagedVersionInfo;
- internal bool m_OverrideUnmanagedVersionInfo;
-
+ internal String m_strResourceFileName;
+ internal byte[] m_resourceBytes;
+ internal NativeVersionInfo m_nativeVersion;
+ internal bool m_hasUnmanagedVersionInfo;
+ internal bool m_OverrideUnmanagedVersionInfo;
}
-
+
/**********************************************
*
* Internal structure to track the list of ResourceWriter for
* AssemblyBuilder & ModuleBuilder.
*
**********************************************/
- internal class ResWriterData
+ internal class ResWriterData
{
- internal String m_strName;
- internal String m_strFileName;
- internal String m_strFullFileName;
- internal Stream m_memoryStream;
- internal ResWriterData m_nextResWriter;
- internal ResourceAttributes m_attribute;
+ internal String m_strName;
+ internal String m_strFileName;
+ internal String m_strFullFileName;
+ internal Stream m_memoryStream;
+ internal ResWriterData m_nextResWriter;
+ internal ResourceAttributes m_attribute;
}
internal class NativeVersionInfo
@@ -191,15 +189,15 @@ namespace System.Reflection.Emit {
m_strFileVersion = null;
m_lcid = -1;
}
-
- internal String m_strDescription;
- internal String m_strCompany;
- internal String m_strTitle;
- internal String m_strCopyright;
- internal String m_strTrademark;
- internal String m_strProduct;
- internal String m_strProductVersion;
- internal String m_strFileVersion;
- internal int m_lcid;
+
+ internal String m_strDescription;
+ internal String m_strCompany;
+ internal String m_strTitle;
+ internal String m_strCopyright;
+ internal String m_strTrademark;
+ internal String m_strProduct;
+ internal String m_strProductVersion;
+ internal String m_strFileVersion;
+ internal int m_lcid;
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/ConstructorBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/ConstructorBuilder.cs
index 3bc02860a1..3ca9b2eb9d 100644
--- a/src/mscorlib/src/System/Reflection/Emit/ConstructorBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/ConstructorBuilder.cs
@@ -4,8 +4,8 @@
//
-namespace System.Reflection.Emit
-{
+namespace System.Reflection.Emit
+{
using System;
using System.Reflection;
using CultureInfo = System.Globalization.CultureInfo;
@@ -14,9 +14,9 @@ namespace System.Reflection.Emit
using System.Security;
using System.Runtime.InteropServices;
using System.Diagnostics.Contracts;
-
+
public sealed class ConstructorBuilder : ConstructorInfo
- {
+ {
private readonly MethodBuilder m_methodBuilder;
internal bool m_isDefaultConstructor;
@@ -25,7 +25,7 @@ namespace System.Reflection.Emit
private ConstructorBuilder()
{
}
-
+
internal ConstructorBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers, ModuleBuilder mod, TypeBuilder type)
{
@@ -33,18 +33,18 @@ namespace System.Reflection.Emit
byte[] sigBytes;
MethodToken token;
- m_methodBuilder = new MethodBuilder(name, attributes, callingConvention, null, null, null,
+ m_methodBuilder = new MethodBuilder(name, attributes, callingConvention, null, null, null,
parameterTypes, requiredCustomModifiers, optionalCustomModifiers, mod, type, false);
type.m_listMethods.Add(m_methodBuilder);
-
+
sigBytes = m_methodBuilder.GetMethodSignature().InternalGetSignature(out sigLength);
-
+
token = m_methodBuilder.GetToken();
}
internal ConstructorBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention,
- Type[] parameterTypes, ModuleBuilder mod, TypeBuilder type) :
+ Type[] parameterTypes, ModuleBuilder mod, TypeBuilder type) :
this(name, attributes, callingConvention, parameterTypes, null, null, mod, type)
{
}
@@ -68,7 +68,7 @@ namespace System.Reflection.Emit
{
return m_methodBuilder.ToString();
}
-
+
#endregion
#region MemberInfo Overrides
@@ -76,12 +76,12 @@ namespace System.Reflection.Emit
{
get { return m_methodBuilder.MetadataTokenInternal; }
}
-
+
public override Module Module
{
get { return m_methodBuilder.Module; }
}
-
+
public override Type ReflectedType
{
get { return m_methodBuilder.ReflectedType; }
@@ -91,8 +91,8 @@ namespace System.Reflection.Emit
{
get { return m_methodBuilder.DeclaringType; }
}
-
- public override String Name
+
+ public override String Name
{
get { return m_methodBuilder.Name; }
}
@@ -100,9 +100,9 @@ namespace System.Reflection.Emit
#endregion
#region MethodBase Overrides
- public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+ public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
[Pure]
@@ -111,7 +111,7 @@ namespace System.Reflection.Emit
ConstructorInfo rci = GetTypeBuilder().GetConstructor(m_methodBuilder.m_parameterTypes);
return rci.GetParameters();
}
-
+
public override MethodAttributes Attributes
{
get { return m_methodBuilder.Attributes; }
@@ -121,20 +121,20 @@ namespace System.Reflection.Emit
{
return m_methodBuilder.GetMethodImplementationFlags();
}
-
- public override RuntimeMethodHandle MethodHandle
+
+ public override RuntimeMethodHandle MethodHandle
{
get { return m_methodBuilder.MethodHandle; }
}
-
+
#endregion
#region ConstructorInfo Overrides
public override Object Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
-
+
#endregion
#region ICustomAttributeProvider Implementation
@@ -147,8 +147,8 @@ namespace System.Reflection.Emit
{
return m_methodBuilder.GetCustomAttributes(attributeType, inherit);
}
-
- public override bool IsDefined (Type attributeType, bool inherit)
+
+ public override bool IsDefined(Type attributeType, bool inherit)
{
return m_methodBuilder.IsDefined(attributeType, inherit);
}
@@ -160,7 +160,7 @@ namespace System.Reflection.Emit
{
return m_methodBuilder.GetToken();
}
-
+
public ParameterBuilder DefineParameter(int iSequence, ParameterAttributes attributes, String strParamName)
{
// Theoretically we shouldn't allow iSequence to be 0 because in reflection ctors don't have
@@ -171,50 +171,50 @@ namespace System.Reflection.Emit
attributes = attributes & ~ParameterAttributes.ReservedMask;
return m_methodBuilder.DefineParameter(iSequence, attributes, strParamName);
}
-
- public ILGenerator GetILGenerator()
+
+ public ILGenerator GetILGenerator()
{
if (m_isDefaultConstructor)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_DefaultConstructorILGen"));
+ throw new InvalidOperationException(SR.InvalidOperation_DefaultConstructorILGen);
return m_methodBuilder.GetILGenerator();
}
-
+
public ILGenerator GetILGenerator(int streamSize)
{
if (m_isDefaultConstructor)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_DefaultConstructorILGen"));
+ throw new InvalidOperationException(SR.InvalidOperation_DefaultConstructorILGen);
return m_methodBuilder.GetILGenerator(streamSize);
}
- public override CallingConventions CallingConvention
- {
- get
- {
+ public override CallingConventions CallingConvention
+ {
+ get
+ {
if (DeclaringType.IsGenericType)
return CallingConventions.HasThis;
-
- return CallingConventions.Standard;
- }
+
+ return CallingConventions.Standard;
+ }
}
-
+
public Module GetModule()
{
return m_methodBuilder.GetModule();
}
-
+
// This always returns null. Is that what we want?
- internal override Type GetReturnType()
+ internal override Type GetReturnType()
{
return m_methodBuilder.ReturnType;
}
-
- public String Signature
+
+ public String Signature
{
get { return m_methodBuilder.Signature; }
}
-
+
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
m_methodBuilder.SetCustomAttribute(con, binaryAttribute);
@@ -225,12 +225,12 @@ namespace System.Reflection.Emit
m_methodBuilder.SetCustomAttribute(customBuilder);
}
- public void SetImplementationFlags(MethodImplAttributes attributes)
+ public void SetImplementationFlags(MethodImplAttributes attributes)
{
m_methodBuilder.SetImplementationFlags(attributes);
}
-
- public bool InitLocals
+
+ public bool InitLocals
{
get { return m_methodBuilder.InitLocals; }
set { m_methodBuilder.InitLocals = value; }
diff --git a/src/mscorlib/src/System/Reflection/Emit/CustomAttributeBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/CustomAttributeBuilder.cs
index 5d08ca08f0..cf5bd11de6 100644
--- a/src/mscorlib/src/System/Reflection/Emit/CustomAttributeBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/CustomAttributeBuilder.cs
@@ -12,18 +12,19 @@
**
**
===========================================================*/
-namespace System.Reflection.Emit {
-
-
- using System;
- using System.Reflection;
- using System.IO;
- using System.Text;
- using System.Runtime.InteropServices;
- using System.Globalization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
+
+
+using System;
+using System.Reflection;
+using System.IO;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.Globalization;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System.Reflection.Emit
+{
public class CustomAttributeBuilder
{
// public constructor to form the custom attribute with constructor and constructor
@@ -31,17 +32,17 @@ namespace System.Reflection.Emit {
public CustomAttributeBuilder(ConstructorInfo con, Object[] constructorArgs)
{
InitCustomAttributeBuilder(con, constructorArgs,
- new PropertyInfo[]{}, new Object[]{},
- new FieldInfo[]{}, new Object[]{});
+ new PropertyInfo[] { }, new Object[] { },
+ new FieldInfo[] { }, new Object[] { });
}
-
+
// public constructor to form the custom attribute with constructor, constructor
// parameters and named properties.
public CustomAttributeBuilder(ConstructorInfo con, Object[] constructorArgs,
PropertyInfo[] namedProperties, Object[] propertyValues)
{
InitCustomAttributeBuilder(con, constructorArgs, namedProperties,
- propertyValues, new FieldInfo[]{}, new Object[]{});
+ propertyValues, new FieldInfo[] { }, new Object[] { });
}
// public constructor to form the custom attribute with constructor and constructor
@@ -49,8 +50,8 @@ namespace System.Reflection.Emit {
public CustomAttributeBuilder(ConstructorInfo con, Object[] constructorArgs,
FieldInfo[] namedFields, Object[] fieldValues)
{
- InitCustomAttributeBuilder(con, constructorArgs, new PropertyInfo[]{},
- new Object[]{}, namedFields, fieldValues);
+ InitCustomAttributeBuilder(con, constructorArgs, new PropertyInfo[] { },
+ new Object[] { }, namedFields, fieldValues);
}
// public constructor to form the custom attribute with constructor and constructor
@@ -117,17 +118,17 @@ namespace System.Reflection.Emit {
if (fieldValues == null)
throw new ArgumentNullException(nameof(fieldValues));
if (namedProperties.Length != propertyValues.Length)
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayLengthsDiffer"), "namedProperties, propertyValues");
+ throw new ArgumentException(SR.Arg_ArrayLengthsDiffer, "namedProperties, propertyValues");
if (namedFields.Length != fieldValues.Length)
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayLengthsDiffer"), "namedFields, fieldValues");
+ throw new ArgumentException(SR.Arg_ArrayLengthsDiffer, "namedFields, fieldValues");
Contract.EndContractBlock();
if ((con.Attributes & MethodAttributes.Static) == MethodAttributes.Static ||
(con.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private)
- throw new ArgumentException(Environment.GetResourceString("Argument_BadConstructor"));
+ throw new ArgumentException(SR.Argument_BadConstructor);
if ((con.CallingConvention & CallingConventions.Standard) != CallingConventions.Standard)
- throw new ArgumentException(Environment.GetResourceString("Argument_BadConstructorCallConv"));
+ throw new ArgumentException(SR.Argument_BadConstructorCallConv);
// Cache information used elsewhere.
m_con = con;
@@ -142,12 +143,12 @@ namespace System.Reflection.Emit {
// Since we're guaranteed a non-var calling convention, the number of arguments must equal the number of parameters.
if (paramTypes.Length != constructorArgs.Length)
- throw new ArgumentException(Environment.GetResourceString("Argument_BadParameterCountsForConstructor"));
+ throw new ArgumentException(SR.Argument_BadParameterCountsForConstructor);
// Verify that the constructor has a valid signature (custom attributes only support a subset of our type system).
for (i = 0; i < paramTypes.Length; i++)
if (!ValidateType(paramTypes[i]))
- throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeInCustomAttribute"));
+ throw new ArgumentException(SR.Argument_BadTypeInCustomAttribute);
// Now verify that the types of the actual parameters are compatible with the types of the formal parameters.
for (i = 0; i < paramTypes.Length; i++)
@@ -194,11 +195,11 @@ namespace System.Reflection.Emit {
// Validate property type.
if (!ValidateType(propType))
- throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeInCustomAttribute"));
+ throw new ArgumentException(SR.Argument_BadTypeInCustomAttribute);
// Property has to be writable.
if (!property.CanWrite)
- throw new ArgumentException(Environment.GetResourceString("Argument_NotAWritableProperty"));
+ throw new ArgumentException(SR.Argument_NotAWritableProperty);
// Property has to be from the same class or base class as ConstructorInfo.
if (property.DeclaringType != con.DeclaringType
@@ -216,7 +217,7 @@ namespace System.Reflection.Emit {
// type is one.
if (!(property.DeclaringType is TypeBuilder) ||
!con.DeclaringType.IsSubclassOf(((TypeBuilder)property.DeclaringType).BakedRuntimeType))
- throw new ArgumentException(Environment.GetResourceString("Argument_BadPropertyForConstructorBuilder"));
+ throw new ArgumentException(SR.Argument_BadPropertyForConstructorBuilder);
}
}
@@ -252,7 +253,7 @@ namespace System.Reflection.Emit {
// Validate field type.
if (!ValidateType(fldType))
- throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeInCustomAttribute"));
+ throw new ArgumentException(SR.Argument_BadTypeInCustomAttribute);
// Field has to be from the same class or base class as ConstructorInfo.
if (namedField.DeclaringType != con.DeclaringType
@@ -270,7 +271,7 @@ namespace System.Reflection.Emit {
// type is one.
if (!(namedField.DeclaringType is TypeBuilder) ||
!con.DeclaringType.IsSubclassOf(((TypeBuilder)namedFields[i].DeclaringType).BakedRuntimeType))
- throw new ArgumentException(Environment.GetResourceString("Argument_BadFieldForConstructorBuilder"));
+ throw new ArgumentException(SR.Argument_BadFieldForConstructorBuilder);
}
}
@@ -280,7 +281,7 @@ namespace System.Reflection.Emit {
{
VerifyTypeAndPassedObjectType(fldType, fieldValue.GetType(), $"{nameof(fieldValues)}[{i}]");
}
-
+
// First a byte indicating that this is a field.
writer.Write((byte)CustomAttributeEncoding.Field);
@@ -298,11 +299,11 @@ namespace System.Reflection.Emit {
{
if (type != typeof(object) && Type.GetTypeCode(passedType) != Type.GetTypeCode(type))
{
- throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch"));
+ throw new ArgumentException(SR.Argument_ConstantDoesntMatch);
}
if (passedType == typeof(IntPtr) || passedType == typeof(UIntPtr))
{
- throw new ArgumentException(Environment.GetResourceString("Argument_BadParameterTypeForCAB"), paramName);
+ throw new ArgumentException(SR.Argument_BadParameterTypeForCAB, paramName);
}
}
@@ -452,8 +453,7 @@ namespace System.Reflection.Emit {
{
String typeName = TypeNameBuilder.ToString((Type)value, TypeNameBuilder.Format.AssemblyQualifiedName);
if (typeName == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeForCA",
- value.GetType()));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidTypeForCA, value.GetType()));
EmitString(writer, typeName);
}
}
@@ -526,8 +526,8 @@ namespace System.Reflection.Emit {
// value cannot be a "System.Object" object.
// If we allow this we will get into an infinite recursion
if (ot == typeof(object))
- throw new ArgumentException(Environment.GetResourceString("Argument_BadParameterTypeForCAB", ot.ToString()));
-
+ throw new ArgumentException(SR.Format(SR.Argument_BadParameterTypeForCAB, ot.ToString()));
+
EmitType(writer, ot);
EmitValue(writer, ot, value);
}
@@ -537,13 +537,13 @@ namespace System.Reflection.Emit {
if (value != null)
typename = value.GetType().ToString();
-
- throw new ArgumentException(Environment.GetResourceString("Argument_BadParameterTypeForCAB", typename));
+
+ throw new ArgumentException(SR.Format(SR.Argument_BadParameterTypeForCAB, typename));
}
}
-
-
+
+
// return the byte interpretation of the custom attribute
internal void CreateCustomAttribute(ModuleBuilder mod, int tkOwner)
@@ -556,12 +556,12 @@ namespace System.Reflection.Emit {
//*************************************************
internal void CreateCustomAttribute(ModuleBuilder mod, int tkOwner, int tkAttrib, bool toDisk)
{
- TypeBuilder.DefineCustomAttribute(mod, tkOwner, tkAttrib, m_blob, toDisk,
+ TypeBuilder.DefineCustomAttribute(mod, tkOwner, tkAttrib, m_blob, toDisk,
typeof(System.Diagnostics.DebuggableAttribute) == m_con.DeclaringType);
}
- internal ConstructorInfo m_con;
- internal Object[] m_constructorArgs;
- internal byte[] m_blob;
+ internal ConstructorInfo m_con;
+ internal Object[] m_constructorArgs;
+ internal byte[] m_blob;
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/DynamicILGenerator.cs b/src/mscorlib/src/System/Reflection/Emit/DynamicILGenerator.cs
index cb2667a104..b592053f9f 100644
--- a/src/mscorlib/src/System/Reflection/Emit/DynamicILGenerator.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/DynamicILGenerator.cs
@@ -6,7 +6,6 @@
namespace System.Reflection.Emit
{
-
using System;
using System.Globalization;
using System.Diagnostics.SymbolStore;
@@ -22,7 +21,6 @@ namespace System.Reflection.Emit
internal class DynamicILGenerator : ILGenerator
{
-
internal DynamicScope m_scope;
private int m_methodSigToken;
@@ -44,16 +42,6 @@ namespace System.Reflection.Emit
new DynamicResolver(this));
}
-#if FEATURE_APPX
- private bool ProfileAPICheck
- {
- get
- {
- return ((DynamicMethod)m_methodBuilder).ProfileAPICheck;
- }
- }
-#endif // FEATURE_APPX
-
// *** ILGenerator api ***
public override LocalBuilder DeclareLocal(Type localType, bool pinned)
@@ -66,12 +54,7 @@ namespace System.Reflection.Emit
RuntimeType rtType = localType as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"));
-
-#if FEATURE_APPX
- if (ProfileAPICheck && (rtType.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtType.FullName));
-#endif
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType);
localBuilder = new LocalBuilder(m_localCount, localType, m_methodBuilder);
// add the localType to local signature
@@ -98,7 +81,7 @@ namespace System.Reflection.Emit
{
RuntimeMethodInfo rtMeth = meth as RuntimeMethodInfo;
if (rtMeth == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), nameof(meth));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, nameof(meth));
RuntimeType declaringType = rtMeth.GetRuntimeType();
if (declaringType != null && (declaringType.IsGenericType || declaringType.IsArray))
@@ -111,7 +94,7 @@ namespace System.Reflection.Emit
// rule out not allowed operations on DynamicMethods
if (opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn) || opcode.Equals(OpCodes.Ldvirtftn))
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOpCodeOnDynamicMethod"));
+ throw new ArgumentException(SR.Argument_InvalidOpCodeOnDynamicMethod);
}
token = GetTokenFor(dynMeth);
}
@@ -149,7 +132,7 @@ namespace System.Reflection.Emit
RuntimeConstructorInfo rtConstructor = con as RuntimeConstructorInfo;
if (rtConstructor == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), nameof(con));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, nameof(con));
RuntimeType declaringType = rtConstructor.GetRuntimeType();
int token;
@@ -178,7 +161,7 @@ namespace System.Reflection.Emit
RuntimeType rtType = type as RuntimeType;
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType);
int token = GetTokenFor(rtType);
EnsureCapacity(7);
@@ -194,7 +177,7 @@ namespace System.Reflection.Emit
RuntimeFieldInfo runtimeField = field as RuntimeFieldInfo;
if (runtimeField == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeFieldInfo"), nameof(field));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeFieldInfo, nameof(field));
int token;
if (field.DeclaringType == null)
@@ -235,7 +218,7 @@ namespace System.Reflection.Emit
if (optionalParameterTypes != null)
if ((callingConvention & CallingConventions.VarArgs) == 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAVarArgCallingConvention"));
+ throw new InvalidOperationException(SR.InvalidOperation_NotAVarArgCallingConvention);
sig = GetMemberRefSignature(callingConvention,
returnType,
@@ -271,13 +254,13 @@ namespace System.Reflection.Emit
throw new ArgumentNullException(nameof(methodInfo));
if (!(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj)))
- throw new ArgumentException(Environment.GetResourceString("Argument_NotMethodCallOpcode"), nameof(opcode));
+ throw new ArgumentException(SR.Argument_NotMethodCallOpcode, nameof(opcode));
if (methodInfo.ContainsGenericParameters)
- throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), nameof(methodInfo));
+ throw new ArgumentException(SR.Argument_GenericsInvalid, nameof(methodInfo));
if (methodInfo.DeclaringType != null && methodInfo.DeclaringType.ContainsGenericParameters)
- throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), nameof(methodInfo));
+ throw new ArgumentException(SR.Argument_GenericsInvalid, nameof(methodInfo));
Contract.EndContractBlock();
int tk;
@@ -345,7 +328,7 @@ namespace System.Reflection.Emit
// Begins an exception filter block. Emits a branch instruction to the end of the current exception block.
if (CurrExcStackCount == 0)
- throw new NotSupportedException(Environment.GetResourceString("Argument_NotInExceptionBlock"));
+ throw new NotSupportedException(SR.Argument_NotInExceptionBlock);
__ExceptionInfo current = CurrExcStack[CurrExcStackCount - 1];
@@ -359,7 +342,7 @@ namespace System.Reflection.Emit
public override void BeginCatchBlock(Type exceptionType)
{
if (CurrExcStackCount == 0)
- throw new NotSupportedException(Environment.GetResourceString("Argument_NotInExceptionBlock"));
+ throw new NotSupportedException(SR.Argument_NotInExceptionBlock);
Contract.EndContractBlock();
__ExceptionInfo current = CurrExcStack[CurrExcStackCount - 1];
@@ -370,7 +353,7 @@ namespace System.Reflection.Emit
{
if (exceptionType != null)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_ShouldNotSpecifyExceptionType"));
+ throw new ArgumentException(SR.Argument_ShouldNotSpecifyExceptionType);
}
this.Emit(OpCodes.Endfilter);
@@ -384,7 +367,7 @@ namespace System.Reflection.Emit
throw new ArgumentNullException(nameof(exceptionType));
if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType);
Label endLabel = current.GetEndLabel();
this.Emit(OpCodes.Leave, endLabel);
@@ -409,7 +392,7 @@ namespace System.Reflection.Emit
[SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
public override void UsingNamespace(String ns)
{
- throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod"));
+ throw new NotSupportedException(SR.InvalidOperation_NotAllowedInDynamicMethod);
}
[SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
@@ -419,17 +402,17 @@ namespace System.Reflection.Emit
int endLine,
int endColumn)
{
- throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod"));
+ throw new NotSupportedException(SR.InvalidOperation_NotAllowedInDynamicMethod);
}
public override void BeginScope()
{
- throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod"));
+ throw new NotSupportedException(SR.InvalidOperation_NotAllowedInDynamicMethod);
}
public override void EndScope()
{
- throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod"));
+ throw new NotSupportedException(SR.InvalidOperation_NotAllowedInDynamicMethod);
}
private int GetMemberRefToken(MethodBase methodInfo, Type[] optionalParameterTypes)
@@ -437,13 +420,13 @@ namespace System.Reflection.Emit
Type[] parameterTypes;
if (optionalParameterTypes != null && (methodInfo.CallingConvention & CallingConventions.VarArgs) == 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAVarArgCallingConvention"));
+ throw new InvalidOperationException(SR.InvalidOperation_NotAVarArgCallingConvention);
RuntimeMethodInfo rtMeth = methodInfo as RuntimeMethodInfo;
DynamicMethod dm = methodInfo as DynamicMethod;
if (rtMeth == null && dm == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), nameof(methodInfo));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, nameof(methodInfo));
ParameterInfo[] paramInfo = methodInfo.GetParametersNoCopy();
if (paramInfo != null && paramInfo.Length != 0)
@@ -498,94 +481,36 @@ namespace System.Reflection.Emit
#region GetTokenFor helpers
private int GetTokenFor(RuntimeType rtType)
{
-#if FEATURE_APPX
- if (ProfileAPICheck && (rtType.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtType.FullName));
-#endif
-
return m_scope.GetTokenFor(rtType.TypeHandle);
}
private int GetTokenFor(RuntimeFieldInfo runtimeField)
{
-#if FEATURE_APPX
- if (ProfileAPICheck)
- {
- RtFieldInfo rtField = runtimeField as RtFieldInfo;
- if (rtField != null && (rtField.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtField.FullName));
- }
-#endif
-
return m_scope.GetTokenFor(runtimeField.FieldHandle);
}
private int GetTokenFor(RuntimeFieldInfo runtimeField, RuntimeType rtType)
{
-#if FEATURE_APPX
- if (ProfileAPICheck)
- {
- RtFieldInfo rtField = runtimeField as RtFieldInfo;
- if (rtField != null && (rtField.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtField.FullName));
-
- if ((rtType.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtType.FullName));
- }
-#endif
-
return m_scope.GetTokenFor(runtimeField.FieldHandle, rtType.TypeHandle);
}
private int GetTokenFor(RuntimeConstructorInfo rtMeth)
{
-#if FEATURE_APPX
- if (ProfileAPICheck && (rtMeth.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtMeth.FullName));
-#endif
-
return m_scope.GetTokenFor(rtMeth.MethodHandle);
}
private int GetTokenFor(RuntimeConstructorInfo rtMeth, RuntimeType rtType)
{
-#if FEATURE_APPX
- if (ProfileAPICheck)
- {
- if ((rtMeth.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtMeth.FullName));
-
- if ((rtType.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtType.FullName));
- }
-#endif
-
return m_scope.GetTokenFor(rtMeth.MethodHandle, rtType.TypeHandle);
}
private int GetTokenFor(RuntimeMethodInfo rtMeth)
{
-#if FEATURE_APPX
- if (ProfileAPICheck && (rtMeth.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtMeth.FullName));
-#endif
-
return m_scope.GetTokenFor(rtMeth.MethodHandle);
}
private int GetTokenFor(RuntimeMethodInfo rtMeth, RuntimeType rtType)
{
-#if FEATURE_APPX
- if (ProfileAPICheck)
- {
- if ((rtMeth.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtMeth.FullName));
-
- if ((rtType.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtType.FullName));
- }
-#endif
-
return m_scope.GetTokenFor(rtMeth.MethodHandle, rtType.TypeHandle);
}
@@ -596,10 +521,6 @@ namespace System.Reflection.Emit
private int GetTokenForVarArgMethod(RuntimeMethodInfo rtMeth, SignatureHelper sig)
{
-#if FEATURE_APPX
- if (ProfileAPICheck && (rtMeth.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtMeth.FullName));
-#endif
VarArgMethod varArgMeth = new VarArgMethod(rtMeth, sig);
return m_scope.GetTokenFor(varArgMeth);
}
@@ -962,8 +883,8 @@ namespace System.Reflection.Emit
public DynamicMethod DynamicMethod { get { return m_method; } }
internal DynamicScope DynamicScope { get { return m_scope; } }
-#endregion
-#region Public Scope Methods
+ #endregion
+ #region Public Scope Methods
#endregion
}
@@ -1032,7 +953,7 @@ namespace System.Reflection.Emit
Type t = m.DeclaringType.GetGenericTypeDefinition();
throw new ArgumentException(String.Format(
- CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_MethodDeclaringTypeGenericLcg"), m, t));
+ CultureInfo.CurrentCulture, SR.Argument_MethodDeclaringTypeGenericLcg, m, t));
}
}
@@ -1119,5 +1040,4 @@ namespace System.Reflection.Emit
m_signature = signature;
}
}
-
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs b/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs
index f1d99d3c2c..2d2d3097a1 100644
--- a/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs
@@ -42,13 +42,6 @@ namespace System.Reflection.Emit
// assigned by the DynamicResolver ctor
internal DynamicResolver m_resolver;
- // Always false unless we are in an immersive (non dev mode) process.
-#if FEATURE_APPX
- private bool m_profileAPICheck;
-
- private RuntimeAssembly m_creatorAssembly;
-#endif
-
internal bool m_restrictedSkipVisibility;
// The context when the method was created. We use this to do the RestrictedMemberAccess checks.
// These checks are done when the method is compiled. This can happen at an arbitrary time,
@@ -58,40 +51,33 @@ namespace System.Reflection.Emit
// it is ready for use since there is not API which indictates that IL generation has completed.
private static volatile InternalModuleBuilder s_anonymouslyHostedDynamicMethodsModule;
private static readonly object s_anonymouslyHostedDynamicMethodsModuleLock = new object();
-
+
//
// class initialization (ctor and init)
//
private DynamicMethod() { }
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public DynamicMethod(string name,
Type returnType,
Type[] parameterTypes)
{
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
-
- Init(name,
- MethodAttributes.Public | MethodAttributes.Static,
- CallingConventions.Standard,
- returnType,
+ Init(name,
+ MethodAttributes.Public | MethodAttributes.Static,
+ CallingConventions.Standard,
+ returnType,
parameterTypes,
null, // owner
null, // m
false, // skipVisibility
- true,
- ref stackMark); // transparentMethod
+ true);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
public DynamicMethod(string name,
Type returnType,
Type[] parameterTypes,
bool restrictedSkipVisibility)
{
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
-
Init(name,
MethodAttributes.Public | MethodAttributes.Static,
CallingConventions.Standard,
@@ -100,17 +86,17 @@ namespace System.Reflection.Emit
null, // owner
null, // m
restrictedSkipVisibility,
- true,
- ref stackMark); // transparentMethod
+ true);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public DynamicMethod(string name,
- Type returnType,
- Type[] parameterTypes,
- Module m) {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- PerformSecurityCheck(m, ref stackMark, false);
+ public DynamicMethod(string name,
+ Type returnType,
+ Type[] parameterTypes,
+ Module m)
+ {
+ if (m == null)
+ throw new ArgumentNullException(nameof(m));
+
Init(name,
MethodAttributes.Public | MethodAttributes.Static,
CallingConventions.Standard,
@@ -119,18 +105,18 @@ namespace System.Reflection.Emit
null, // owner
m, // m
false, // skipVisibility
- false,
- ref stackMark); // transparentMethod
+ false);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public DynamicMethod(string name,
- Type returnType,
- Type[] parameterTypes,
- Module m,
- bool skipVisibility) {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- PerformSecurityCheck(m, ref stackMark, skipVisibility);
+ public DynamicMethod(string name,
+ Type returnType,
+ Type[] parameterTypes,
+ Module m,
+ bool skipVisibility)
+ {
+ if (m == null)
+ throw new ArgumentNullException(nameof(m));
+
Init(name,
MethodAttributes.Public | MethodAttributes.Static,
CallingConventions.Standard,
@@ -139,20 +125,20 @@ namespace System.Reflection.Emit
null, // owner
m, // m
skipVisibility,
- false,
- ref stackMark); // transparentMethod
+ false);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public DynamicMethod(string name,
- MethodAttributes attributes,
- CallingConventions callingConvention,
- Type returnType,
- Type[] parameterTypes,
- Module m,
- bool skipVisibility) {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- PerformSecurityCheck(m, ref stackMark, skipVisibility);
+ public DynamicMethod(string name,
+ MethodAttributes attributes,
+ CallingConventions callingConvention,
+ Type returnType,
+ Type[] parameterTypes,
+ Module m,
+ bool skipVisibility)
+ {
+ if (m == null)
+ throw new ArgumentNullException(nameof(m));
+
Init(name,
attributes,
callingConvention,
@@ -161,93 +147,93 @@ namespace System.Reflection.Emit
null, // owner
m, // m
skipVisibility,
- false,
- ref stackMark); // transparentMethod
+ false);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public DynamicMethod(string name,
- Type returnType,
- Type[] parameterTypes,
- Type owner) {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- PerformSecurityCheck(owner, ref stackMark, false);
- Init(name,
- MethodAttributes.Public | MethodAttributes.Static,
- CallingConventions.Standard,
- returnType,
+ public DynamicMethod(string name,
+ Type returnType,
+ Type[] parameterTypes,
+ Type owner)
+ {
+ if (owner == null)
+ throw new ArgumentNullException(nameof(owner));
+
+ Init(name,
+ MethodAttributes.Public | MethodAttributes.Static,
+ CallingConventions.Standard,
+ returnType,
parameterTypes,
owner, // owner
null, // m
false, // skipVisibility
- false,
- ref stackMark); // transparentMethod
+ false);
}
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public DynamicMethod(string name,
- Type returnType,
- Type[] parameterTypes,
- Type owner,
- bool skipVisibility) {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- PerformSecurityCheck(owner, ref stackMark, skipVisibility);
- Init(name,
- MethodAttributes.Public | MethodAttributes.Static,
- CallingConventions.Standard,
- returnType,
- parameterTypes,
+
+ public DynamicMethod(string name,
+ Type returnType,
+ Type[] parameterTypes,
+ Type owner,
+ bool skipVisibility)
+ {
+ if (owner == null)
+ throw new ArgumentNullException(nameof(owner));
+
+ Init(name,
+ MethodAttributes.Public | MethodAttributes.Static,
+ CallingConventions.Standard,
+ returnType,
+ parameterTypes,
owner, // owner
null, // m
skipVisibility,
- false,
- ref stackMark); // transparentMethod
+ false);
}
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public DynamicMethod(string name,
- MethodAttributes attributes,
- CallingConventions callingConvention,
- Type returnType,
- Type[] parameterTypes,
- Type owner,
- bool skipVisibility) {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- PerformSecurityCheck(owner, ref stackMark, skipVisibility);
- Init(name,
- attributes,
- callingConvention,
- returnType,
- parameterTypes,
+
+ public DynamicMethod(string name,
+ MethodAttributes attributes,
+ CallingConventions callingConvention,
+ Type returnType,
+ Type[] parameterTypes,
+ Type owner,
+ bool skipVisibility)
+ {
+ if (owner == null)
+ throw new ArgumentNullException(nameof(owner));
+
+ Init(name,
+ attributes,
+ callingConvention,
+ returnType,
+ parameterTypes,
owner, // owner
null, // m
- skipVisibility,
- false,
- ref stackMark); // transparentMethod
+ skipVisibility,
+ false);
}
// helpers for intialization
- static private void CheckConsistency(MethodAttributes attributes, CallingConventions callingConvention) {
+ static private void CheckConsistency(MethodAttributes attributes, CallingConventions callingConvention)
+ {
// only static public for method attributes
if ((attributes & ~MethodAttributes.MemberAccessMask) != MethodAttributes.Static)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags"));
+ throw new NotSupportedException(SR.NotSupported_DynamicMethodFlags);
if ((attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags"));
+ throw new NotSupportedException(SR.NotSupported_DynamicMethodFlags);
Contract.EndContractBlock();
// only standard or varargs supported
if (callingConvention != CallingConventions.Standard && callingConvention != CallingConventions.VarArgs)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags"));
-
+ throw new NotSupportedException(SR.NotSupported_DynamicMethodFlags);
+
// vararg is not supported at the moment
if (callingConvention == CallingConventions.VarArgs)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags"));
+ throw new NotSupportedException(SR.NotSupported_DynamicMethodFlags);
}
// We create a transparent assembly to host DynamicMethods. Since the assembly does not have any
// non-public fields (or any fields at all), it is a safe anonymous assembly to host DynamicMethods
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
private static RuntimeModule GetDynamicMethodsModule()
{
if (s_anonymouslyHostedDynamicMethodsModule != null)
@@ -259,7 +245,7 @@ namespace System.Reflection.Emit
return s_anonymouslyHostedDynamicMethodsModule;
ConstructorInfo transparencyCtor = typeof(SecurityTransparentAttribute).GetConstructor(Type.EmptyTypes);
- CustomAttributeBuilder transparencyAttribute = new CustomAttributeBuilder(transparencyCtor, EmptyArray<Object>.Value);
+ CustomAttributeBuilder transparencyAttribute = new CustomAttributeBuilder(transparencyCtor, Array.Empty<Object>());
List<CustomAttributeBuilder> assemblyAttributes = new List<CustomAttributeBuilder>();
assemblyAttributes.Add(transparencyAttribute);
@@ -283,38 +269,40 @@ namespace System.Reflection.Emit
return s_anonymouslyHostedDynamicMethodsModule;
}
- private unsafe void Init(String name,
- MethodAttributes attributes,
- CallingConventions callingConvention,
- Type returnType,
- Type[] signature,
- Type owner,
- Module m,
+ private unsafe void Init(String name,
+ MethodAttributes attributes,
+ CallingConventions callingConvention,
+ Type returnType,
+ Type[] signature,
+ Type owner,
+ Module m,
bool skipVisibility,
- bool transparentMethod,
- ref StackCrawlMark stackMark)
+ bool transparentMethod)
{
DynamicMethod.CheckConsistency(attributes, callingConvention);
// check and store the signature
- if (signature != null) {
+ if (signature != null)
+ {
m_parameterTypes = new RuntimeType[signature.Length];
- for (int i = 0; i < signature.Length; i++) {
- if (signature[i] == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidTypeInSignature"));
+ for (int i = 0; i < signature.Length; i++)
+ {
+ if (signature[i] == null)
+ throw new ArgumentException(SR.Arg_InvalidTypeInSignature);
m_parameterTypes[i] = signature[i].UnderlyingSystemType as RuntimeType;
- if ( m_parameterTypes[i] == null || !(m_parameterTypes[i] is RuntimeType) || m_parameterTypes[i] == (RuntimeType)typeof(void) )
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidTypeInSignature"));
+ if (m_parameterTypes[i] == null || !(m_parameterTypes[i] is RuntimeType) || m_parameterTypes[i] == (RuntimeType)typeof(void))
+ throw new ArgumentException(SR.Arg_InvalidTypeInSignature);
}
}
- else {
+ else
+ {
m_parameterTypes = Array.Empty<RuntimeType>();
}
-
+
// check and store the return value
m_returnType = (returnType == null) ? (RuntimeType)typeof(void) : returnType.UnderlyingSystemType as RuntimeType;
- if ( (m_returnType == null) || !(m_returnType is RuntimeType) || m_returnType.IsByRef )
- throw new NotSupportedException(Environment.GetResourceString("Arg_InvalidTypeInRetType"));
+ if ((m_returnType == null) || !(m_returnType is RuntimeType) || m_returnType.IsByRef)
+ throw new NotSupportedException(SR.Arg_InvalidTypeInRetType);
if (transparentMethod)
{
@@ -324,11 +312,10 @@ namespace System.Reflection.Emit
{
m_restrictedSkipVisibility = true;
}
-
}
else
{
- Debug.Assert(m != null || owner != null, "PerformSecurityCheck should ensure that either m or owner is set");
+ Debug.Assert(m != null || owner != null, "Constructor should ensure that either m or owner is set");
Debug.Assert(m == null || !m.Equals(s_anonymouslyHostedDynamicMethodsModule), "The user cannot explicitly use this assembly");
Debug.Assert(m == null || owner == null, "m and owner cannot both be set");
@@ -344,7 +331,7 @@ namespace System.Reflection.Emit
{
if (rtOwner.HasElementType || rtOwner.ContainsGenericParameters
|| rtOwner.IsGenericParameter || rtOwner.IsInterface)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeForDynamicMethod"));
+ throw new ArgumentException(SR.Argument_InvalidTypeForDynamicMethod);
m_typeOwner = rtOwner;
m_module = rtOwner.GetRuntimeModule();
@@ -359,41 +346,18 @@ namespace System.Reflection.Emit
m_fInitLocals = true;
m_methodHandle = null;
- if (name == null)
+ if (name == null)
throw new ArgumentNullException(nameof(name));
-#if FEATURE_APPX
- if (AppDomain.ProfileAPICheck)
- {
- if (m_creatorAssembly == null)
- m_creatorAssembly = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
-
- if (m_creatorAssembly != null && !m_creatorAssembly.IsFrameworkAssembly())
- m_profileAPICheck = true;
- }
-#endif // FEATURE_APPX
-
m_dynMethod = new RTDynamicMethod(this, name, attributes, callingConvention);
}
- private void PerformSecurityCheck(Module m, ref StackCrawlMark stackMark, bool skipVisibility)
- {
- if (m == null)
- throw new ArgumentNullException(nameof(m));
- Contract.EndContractBlock();
- }
-
- private void PerformSecurityCheck(Type owner, ref StackCrawlMark stackMark, bool skipVisibility)
- {
- if (owner == null)
- throw new ArgumentNullException(nameof(owner));
- }
-
//
// Delegate and method creation
//
- public sealed override Delegate CreateDelegate(Type delegateType) {
+ public sealed override Delegate CreateDelegate(Type delegateType)
+ {
if (m_restrictedSkipVisibility)
{
// Compile the method since accessibility checks are done as part of compilation.
@@ -407,7 +371,8 @@ namespace System.Reflection.Emit
return d;
}
- public sealed override Delegate CreateDelegate(Type delegateType, Object target) {
+ public sealed override Delegate CreateDelegate(Type delegateType, Object target)
+ {
if (m_restrictedSkipVisibility)
{
// Compile the method since accessibility checks are done as part of compilation
@@ -421,33 +386,22 @@ namespace System.Reflection.Emit
return d;
}
-#if FEATURE_APPX
- internal bool ProfileAPICheck
+ // This is guaranteed to return a valid handle
+ internal unsafe RuntimeMethodHandle GetMethodDescriptor()
{
- get
- {
- return m_profileAPICheck;
- }
-
- [FriendAccessAllowed]
- set
+ if (m_methodHandle == null)
{
- m_profileAPICheck = value;
- }
- }
-#endif
-
- // This is guaranteed to return a valid handle
- internal unsafe RuntimeMethodHandle GetMethodDescriptor() {
- if (m_methodHandle == null) {
- lock (this) {
- if (m_methodHandle == null) {
+ lock (this)
+ {
+ if (m_methodHandle == null)
+ {
if (m_DynamicILInfo != null)
m_DynamicILInfo.GetCallableMethod(m_module, this);
- else {
+ else
+ {
if (m_ilGenerator == null || m_ilGenerator.ILOffset == 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadEmptyMethodBody", Name));
-
+ throw new InvalidOperationException(SR.Format(SR.InvalidOperation_BadEmptyMethodBody, Name));
+
m_ilGenerator.GetCallableMethod(m_module, this);
}
}
@@ -471,7 +425,7 @@ namespace System.Reflection.Emit
public override Module Module { get { return m_dynMethod.Module; } }
// we cannot return a MethodHandle because we cannot track it via GC so this method is off limits
- public override RuntimeMethodHandle MethodHandle { get { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); } }
+ public override RuntimeMethodHandle MethodHandle { get { throw new InvalidOperationException(SR.InvalidOperation_NotAllowedInDynamicMethod); } }
public override MethodAttributes Attributes { get { return m_dynMethod.Attributes; } }
@@ -508,9 +462,10 @@ namespace System.Reflection.Emit
get { return false; }
}
- public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
+ public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+ {
if ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_CallToVarArg"));
+ throw new NotSupportedException(SR.NotSupported_CallToVarArg);
Contract.EndContractBlock();
//
@@ -531,7 +486,7 @@ namespace System.Reflection.Emit
int formalCount = sig.Arguments.Length;
int actualCount = (parameters != null) ? parameters.Length : 0;
if (formalCount != actualCount)
- throw new TargetParameterCountException(Environment.GetResourceString("Arg_ParmCnt"));
+ throw new TargetParameterCountException(SR.Arg_ParmCnt);
// if we are here we passed all the previous checks. Time to look at the arguments
Object retValue = null;
@@ -554,7 +509,7 @@ namespace System.Reflection.Emit
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
- return m_dynMethod.GetCustomAttributes(attributeType, inherit);
+ return m_dynMethod.GetCustomAttributes(attributeType, inherit);
}
public override Object[] GetCustomAttributes(bool inherit) { return m_dynMethod.GetCustomAttributes(inherit); }
@@ -571,24 +526,27 @@ namespace System.Reflection.Emit
// DynamicMethod specific methods
//
- public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, String parameterName) {
+ public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, String parameterName)
+ {
if (position < 0 || position > m_parameterTypes.Length)
- throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_ParamSequence"));
+ throw new ArgumentOutOfRangeException(SR.ArgumentOutOfRange_ParamSequence);
position--; // it's 1 based. 0 is the return value
-
- if (position >= 0) {
- ParameterInfo[] parameters = m_dynMethod.LoadParameters();
+
+ if (position >= 0)
+ {
+ RuntimeParameterInfo[] parameters = m_dynMethod.LoadParameters();
parameters[position].SetName(parameterName);
parameters[position].SetAttributes(attributes);
}
return null;
}
- public ILGenerator GetILGenerator() {
+ public ILGenerator GetILGenerator()
+ {
return GetILGenerator(64);
}
- public ILGenerator GetILGenerator(int streamSize)
+ public ILGenerator GetILGenerator(int streamSize)
{
if (m_ilGenerator == null)
{
@@ -599,16 +557,18 @@ namespace System.Reflection.Emit
return m_ilGenerator;
}
- public bool InitLocals {
- get {return m_fInitLocals;}
- set {m_fInitLocals = value;}
+ public bool InitLocals
+ {
+ get { return m_fInitLocals; }
+ set { m_fInitLocals = value; }
}
//
// Internal API
//
-
- internal MethodInfo GetMethodInfo() {
+
+ internal MethodInfo GetMethodInfo()
+ {
return m_dynMethod;
}
@@ -620,109 +580,125 @@ namespace System.Reflection.Emit
// This way the DynamicMethod creator is the only one responsible for DynamicMethod access,
// and can control exactly who gets access to it.
//
- internal class RTDynamicMethod : MethodInfo {
-
+ internal class RTDynamicMethod : MethodInfo
+ {
internal DynamicMethod m_owner;
- ParameterInfo[] m_parameters;
- String m_name;
- MethodAttributes m_attributes;
- CallingConventions m_callingConvention;
+ private RuntimeParameterInfo[] m_parameters;
+ private String m_name;
+ private MethodAttributes m_attributes;
+ private CallingConventions m_callingConvention;
//
// ctors
//
- private RTDynamicMethod() {}
+ private RTDynamicMethod() { }
- internal RTDynamicMethod(DynamicMethod owner, String name, MethodAttributes attributes, CallingConventions callingConvention) {
+ internal RTDynamicMethod(DynamicMethod owner, String name, MethodAttributes attributes, CallingConventions callingConvention)
+ {
m_owner = owner;
m_name = name;
m_attributes = attributes;
m_callingConvention = callingConvention;
}
-
+
//
// MethodInfo api
//
- public override String ToString() {
+ public override String ToString()
+ {
return ReturnType.FormatTypeName() + " " + FormatNameAndSig();
}
- public override String Name {
+ public override String Name
+ {
get { return m_name; }
}
- public override Type DeclaringType {
+ public override Type DeclaringType
+ {
get { return null; }
}
- public override Type ReflectedType {
+ public override Type ReflectedType
+ {
get { return null; }
}
- public override Module Module {
+ public override Module Module
+ {
get { return m_owner.m_module; }
}
- public override RuntimeMethodHandle MethodHandle {
- get { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); }
+ public override RuntimeMethodHandle MethodHandle
+ {
+ get { throw new InvalidOperationException(SR.InvalidOperation_NotAllowedInDynamicMethod); }
}
- public override MethodAttributes Attributes {
+ public override MethodAttributes Attributes
+ {
get { return m_attributes; }
- }
+ }
- public override CallingConventions CallingConvention {
+ public override CallingConventions CallingConvention
+ {
get { return m_callingConvention; }
}
-
- public override MethodInfo GetBaseDefinition() {
+
+ public override MethodInfo GetBaseDefinition()
+ {
return this;
}
-
+
[Pure]
- public override ParameterInfo[] GetParameters() {
+ public override ParameterInfo[] GetParameters()
+ {
ParameterInfo[] privateParameters = LoadParameters();
ParameterInfo[] parameters = new ParameterInfo[privateParameters.Length];
Array.Copy(privateParameters, 0, parameters, 0, privateParameters.Length);
return parameters;
}
-
- public override MethodImplAttributes GetMethodImplementationFlags() {
+
+ public override MethodImplAttributes GetMethodImplementationFlags()
+ {
return MethodImplAttributes.IL | MethodImplAttributes.NoInlining;
}
- public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) {
+ public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+ {
// We want the creator of the DynamicMethod to control who has access to the
// DynamicMethod (just like we do for delegates). However, a user can get to
// the corresponding RTDynamicMethod using Exception.TargetSite, StackFrame.GetMethod, etc.
// If we allowed use of RTDynamicMethod, the creator of the DynamicMethod would
// not be able to bound access to the DynamicMethod. Hence, we do not allow
// direct use of RTDynamicMethod.
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "this");
+ throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo, "this");
}
- public override Object[] GetCustomAttributes(Type attributeType, bool inherit) {
+ public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
+ {
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
- if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute)))
+ if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute)))
return new Object[] { new MethodImplAttribute(GetMethodImplementationFlags()) };
else
- return EmptyArray<Object>.Value;
+ return Array.Empty<Object>();
}
- public override Object[] GetCustomAttributes(bool inherit) {
+ public override Object[] GetCustomAttributes(bool inherit)
+ {
// support for MethodImplAttribute PCA
return new Object[] { new MethodImplAttribute(GetMethodImplementationFlags()) };
}
-
- public override bool IsDefined(Type attributeType, bool inherit) {
+
+ public override bool IsDefined(Type attributeType, bool inherit)
+ {
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));
Contract.EndContractBlock();
- if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute)))
+ if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute)))
return true;
else
return false;
@@ -751,11 +727,13 @@ namespace System.Reflection.Emit
}
}
- public override ParameterInfo ReturnParameter {
- get { return null; }
+ public override ParameterInfo ReturnParameter
+ {
+ get { return null; }
}
- public override ICustomAttributeProvider ReturnTypeCustomAttributes {
+ public override ICustomAttributeProvider ReturnTypeCustomAttributes
+ {
get { return GetEmptyCAHolder(); }
}
@@ -763,45 +741,49 @@ namespace System.Reflection.Emit
// private implementation
//
- internal ParameterInfo[] LoadParameters() {
- if (m_parameters == null) {
+ internal RuntimeParameterInfo[] LoadParameters()
+ {
+ if (m_parameters == null)
+ {
Type[] parameterTypes = m_owner.m_parameterTypes;
- ParameterInfo[] parameters = new ParameterInfo[parameterTypes.Length];
- for (int i = 0; i < parameterTypes.Length; i++)
+ RuntimeParameterInfo[] parameters = new RuntimeParameterInfo[parameterTypes.Length];
+ for (int i = 0; i < parameterTypes.Length; i++)
parameters[i] = new RuntimeParameterInfo(this, null, parameterTypes[i], i);
- if (m_parameters == null)
+ if (m_parameters == null)
// should we interlockexchange?
m_parameters = parameters;
}
return m_parameters;
}
-
+
// private implementation of CA for the return type
- private ICustomAttributeProvider GetEmptyCAHolder() {
+ private ICustomAttributeProvider GetEmptyCAHolder()
+ {
return new EmptyCAHolder();
}
///////////////////////////////////////////////////
// EmptyCAHolder
- private class EmptyCAHolder : ICustomAttributeProvider {
- internal EmptyCAHolder() {}
+ private class EmptyCAHolder : ICustomAttributeProvider
+ {
+ internal EmptyCAHolder() { }
- Object[] ICustomAttributeProvider.GetCustomAttributes(Type attributeType, bool inherit) {
- return EmptyArray<Object>.Value;
+ Object[] ICustomAttributeProvider.GetCustomAttributes(Type attributeType, bool inherit)
+ {
+ return Array.Empty<Object>();
}
- Object[] ICustomAttributeProvider.GetCustomAttributes(bool inherit) {
- return EmptyArray<Object>.Value;
+ Object[] ICustomAttributeProvider.GetCustomAttributes(bool inherit)
+ {
+ return Array.Empty<Object>();
}
- bool ICustomAttributeProvider.IsDefined (Type attributeType, bool inherit) {
+ bool ICustomAttributeProvider.IsDefined(Type attributeType, bool inherit)
+ {
return false;
}
}
-
}
-
}
-
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/EnumBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/EnumBuilder.cs
index 96564d537b..55aa5c5a8f 100644
--- a/src/mscorlib/src/System/Reflection/Emit/EnumBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/EnumBuilder.cs
@@ -12,8 +12,9 @@
**
**
===========================================================*/
-namespace System.Reflection.Emit {
-
+
+namespace System.Reflection.Emit
+{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
@@ -23,21 +24,22 @@ namespace System.Reflection.Emit {
sealed public class EnumBuilder : TypeInfo
{
- public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){
- if(typeInfo==null) return false;
+ public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo)
+ {
+ if (typeInfo == null) return false;
return IsAssignableFrom(typeInfo.AsType());
}
// Define literal for enum
public FieldBuilder DefineLiteral(String literalName, Object literalValue)
- {
- BCLDebug.Log("DYNIL","## DYNIL LOGGING: EnumBuilder.DefineLiteral( " + literalName + " )");
+ {
+ BCLDebug.Log("DYNIL", "## DYNIL LOGGING: EnumBuilder.DefineLiteral( " + literalName + " )");
// Define the underlying field for the enum. It will be a non-static, private field with special name bit set.
FieldBuilder fieldBuilder = m_typeBuilder.DefineField(
- literalName,
- this,
+ literalName,
+ this,
FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal);
fieldBuilder.SetConstant(literalValue);
return fieldBuilder;
@@ -50,143 +52,156 @@ namespace System.Reflection.Emit {
}
// CreateType cause EnumBuilder to be baked.
- public Type CreateType()
+ public Type CreateType()
{
- BCLDebug.Log("DYNIL","## DYNIL LOGGING: EnumBuilder.CreateType() ");
+ BCLDebug.Log("DYNIL", "## DYNIL LOGGING: EnumBuilder.CreateType() ");
return m_typeBuilder.CreateType();
}
-
+
// Get the internal metadata token for this class.
- public TypeToken TypeToken {
- get {return m_typeBuilder.TypeToken; }
+ public TypeToken TypeToken
+ {
+ get { return m_typeBuilder.TypeToken; }
}
-
+
// return the underlying field for the enum
- public FieldBuilder UnderlyingField {
- get {return m_underlyingField; }
+ public FieldBuilder UnderlyingField
+ {
+ get { return m_underlyingField; }
}
- public override String Name {
+ public override String Name
+ {
get { return m_typeBuilder.Name; }
}
-
+
/****************************************************
*
* abstract methods defined in the base class
*
*/
- public override Guid GUID {
- get {
+ public override Guid GUID
+ {
+ get
+ {
return m_typeBuilder.GUID;
}
}
public override Object InvokeMember(
- String name,
+ String name,
BindingFlags invokeAttr,
- Binder binder,
- Object target,
- Object[] args,
- ParameterModifier[] modifiers,
+ Binder binder,
+ Object target,
+ Object[] args,
+ ParameterModifier[] modifiers,
CultureInfo culture,
- String[] namedParameters)
+ String[] namedParameters)
{
return m_typeBuilder.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
}
-
- public override Module Module {
- get {return m_typeBuilder.Module;}
+
+ public override Module Module
+ {
+ get { return m_typeBuilder.Module; }
}
-
- public override Assembly Assembly {
- get {return m_typeBuilder.Assembly;}
+
+ public override Assembly Assembly
+ {
+ get { return m_typeBuilder.Assembly; }
}
- public override RuntimeTypeHandle TypeHandle {
- get {return m_typeBuilder.TypeHandle;}
+ public override RuntimeTypeHandle TypeHandle
+ {
+ get { return m_typeBuilder.TypeHandle; }
}
-
- public override String FullName {
- get { return m_typeBuilder.FullName;}
+
+ public override String FullName
+ {
+ get { return m_typeBuilder.FullName; }
}
-
- public override String AssemblyQualifiedName {
- get {
+
+ public override String AssemblyQualifiedName
+ {
+ get
+ {
return m_typeBuilder.AssemblyQualifiedName;
}
}
-
- public override String Namespace {
- get { return m_typeBuilder.Namespace;}
+
+ public override String Namespace
+ {
+ get { return m_typeBuilder.Namespace; }
}
-
- public override Type BaseType {
- get{return m_typeBuilder.BaseType;}
+
+ public override Type BaseType
+ {
+ get { return m_typeBuilder.BaseType; }
}
-
- protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr,Binder binder,
- CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers)
+
+ protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder,
+ CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
{
return m_typeBuilder.GetConstructor(bindingAttr, binder, callConvention,
types, modifiers);
}
-
+
public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
{
return m_typeBuilder.GetConstructors(bindingAttr);
}
-
- protected override MethodInfo GetMethodImpl(String name,BindingFlags bindingAttr,Binder binder,
- CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers)
+
+ protected override MethodInfo GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder,
+ CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
{
if (types == null)
return m_typeBuilder.GetMethod(name, bindingAttr);
else
return m_typeBuilder.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers);
}
-
+
public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
{
return m_typeBuilder.GetMethods(bindingAttr);
}
-
+
public override FieldInfo GetField(String name, BindingFlags bindingAttr)
{
return m_typeBuilder.GetField(name, bindingAttr);
}
-
+
public override FieldInfo[] GetFields(BindingFlags bindingAttr)
{
return m_typeBuilder.GetFields(bindingAttr);
}
-
+
public override Type GetInterface(String name, bool ignoreCase)
{
return m_typeBuilder.GetInterface(name, ignoreCase);
}
-
+
public override Type[] GetInterfaces()
{
return m_typeBuilder.GetInterfaces();
}
-
+
public override EventInfo GetEvent(String name, BindingFlags bindingAttr)
{
return m_typeBuilder.GetEvent(name, bindingAttr);
}
-
+
public override EventInfo[] GetEvents()
{
return m_typeBuilder.GetEvents();
}
-
- protected override PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder,
+
+ protected override PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder,
Type returnType, Type[] types, ParameterModifier[] modifiers)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
-
+
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
{
return m_typeBuilder.GetProperties(bindingAttr);
@@ -199,14 +214,14 @@ namespace System.Reflection.Emit {
public override Type GetNestedType(String name, BindingFlags bindingAttr)
{
- return m_typeBuilder.GetNestedType(name,bindingAttr);
+ return m_typeBuilder.GetNestedType(name, bindingAttr);
}
-
- public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
+
+ public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
{
return m_typeBuilder.GetMember(name, type, bindingAttr);
}
-
+
public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
{
return m_typeBuilder.GetMembers(bindingAttr);
@@ -221,12 +236,14 @@ namespace System.Reflection.Emit {
{
return m_typeBuilder.GetEvents(bindingAttr);
}
-
+
protected override TypeAttributes GetAttributeFlagsImpl()
{
return m_typeBuilder.Attributes;
}
-
+
+ public override bool IsSZArray => false;
+
protected override bool IsArrayImpl()
{
return false;
@@ -236,7 +253,7 @@ namespace System.Reflection.Emit {
return false;
}
- protected override bool IsValueTypeImpl()
+ protected override bool IsValueTypeImpl()
{
return true;
}
@@ -250,7 +267,7 @@ namespace System.Reflection.Emit {
{
return false;
}
-
+
protected override bool IsCOMObjectImpl()
{
return false;
@@ -290,7 +307,7 @@ namespace System.Reflection.Emit {
return GetEnumUnderlyingType();
}
}
-
+
//ICustomAttributeProvider
public override Object[] GetCustomAttributes(bool inherit)
{
@@ -303,64 +320,66 @@ namespace System.Reflection.Emit {
return m_typeBuilder.GetCustomAttributes(attributeType, inherit);
}
- // Use this function if client decides to form the custom attribute blob themselves
+ // Use this function if client decides to form the custom attribute blob themselves
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
- m_typeBuilder.SetCustomAttribute(con, binaryAttribute);
+ m_typeBuilder.SetCustomAttribute(con, binaryAttribute);
}
- // Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder
+ // Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder
public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
{
m_typeBuilder.SetCustomAttribute(customBuilder);
}
// Return the class that declared this Field.
- public override Type DeclaringType {
- get {return m_typeBuilder.DeclaringType;}
+ public override Type DeclaringType
+ {
+ get { return m_typeBuilder.DeclaringType; }
}
// Return the class that was used to obtain this field.
-
- public override Type ReflectedType {
- get {return m_typeBuilder.ReflectedType;}
+
+ public override Type ReflectedType
+ {
+ get { return m_typeBuilder.ReflectedType; }
}
- // Returns true if one or more instance of attributeType is defined on this member.
- public override bool IsDefined (Type attributeType, bool inherit)
+ // Returns true if one or more instance of attributeType is defined on this member.
+ public override bool IsDefined(Type attributeType, bool inherit)
{
return m_typeBuilder.IsDefined(attributeType, inherit);
}
-
+
/*****************************************************
*
* private/protected functions
*
*/
-
+
//*******************************
// Make a private constructor so these cannot be constructed externally.
//*******************************
- private EnumBuilder() {}
-
- public override Type MakePointerType()
- {
- return SymbolType.FormCompoundType("*", this, 0);
+ private EnumBuilder() { }
+
+ public override Type MakePointerType()
+ {
+ return SymbolType.FormCompoundType("*", this, 0);
}
- public override Type MakeByRefType()
+ public override Type MakeByRefType()
{
return SymbolType.FormCompoundType("&", this, 0);
}
- public override Type MakeArrayType()
+ public override Type MakeArrayType()
{
return SymbolType.FormCompoundType("[]", this, 0);
}
- public override Type MakeArrayType(int rank)
+ public override Type MakeArrayType(int rank)
{
if (rank <= 0)
throw new IndexOutOfRangeException();
@@ -370,9 +389,9 @@ namespace System.Reflection.Emit {
{
szrank = "*";
}
- else
+ else
{
- for(int i = 1; i < rank; i++)
+ for (int i = 1; i < rank; i++)
szrank += ",";
}
@@ -380,18 +399,18 @@ namespace System.Reflection.Emit {
return SymbolType.FormCompoundType(s, this, 0);
}
-
+
// Constructs a EnumBuilder.
// EnumBuilder can only be a top-level (not nested) enum type.
internal EnumBuilder(
- String name, // name of type
- Type underlyingType, // underlying type for an Enum
+ String name, // name of type
+ Type underlyingType, // underlying type for an Enum
TypeAttributes visibility, // any bits on TypeAttributes.VisibilityMask)
- ModuleBuilder module) // module containing this type
+ ModuleBuilder module) // module containing this type
{
// Client should not set any bits other than the visibility bits.
if ((visibility & ~TypeAttributes.VisibilityMask) != 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_ShouldOnlySetVisibilityFlags"), nameof(name));
+ throw new ArgumentException(SR.Argument_ShouldOnlySetVisibilityFlags, nameof(name));
m_typeBuilder = new TypeBuilder(name, visibility | TypeAttributes.Sealed, typeof(System.Enum), null, module, PackingSize.Unspecified, TypeBuilder.UnspecifiedTypeSize, null);
// Define the underlying field for the enum. It will be a non-static, private field with special name bit set.
@@ -403,7 +422,7 @@ namespace System.Reflection.Emit {
* private data members
*
*/
- internal TypeBuilder m_typeBuilder;
- private FieldBuilder m_underlyingField;
+ internal TypeBuilder m_typeBuilder;
+ private FieldBuilder m_underlyingField;
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/EventBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/EventBuilder.cs
index 34c76b93d1..ef60d05172 100644
--- a/src/mscorlib/src/System/Reflection/Emit/EventBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/EventBuilder.cs
@@ -12,40 +12,40 @@
**
**
===========================================================*/
-namespace System.Reflection.Emit {
-
- using System;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using System.Diagnostics.Contracts;
-
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Diagnostics.Contracts;
+
+namespace System.Reflection.Emit
+{
//
// A EventBuilder is always associated with a TypeBuilder. The TypeBuilder.DefineEvent
// method will return a new EventBuilder to a client.
//
public sealed class EventBuilder
- {
-
+ {
// Make a private constructor so these cannot be constructed externally.
- private EventBuilder() {}
-
+ private EventBuilder() { }
+
// Constructs a EventBuilder.
//
internal EventBuilder(
- ModuleBuilder mod, // the module containing this EventBuilder
- String name, // Event name
+ ModuleBuilder mod, // the module containing this EventBuilder
+ String name, // Event name
EventAttributes attr, // event attribute such as Public, Private, and Protected defined above
- //int eventType, // event type
- TypeBuilder type, // containing type
- EventToken evToken)
- {
+ //int eventType, // event type
+ TypeBuilder type, // containing type
+ EventToken evToken)
+ {
m_name = name;
m_module = mod;
m_attributes = attr;
m_evToken = evToken;
m_type = type;
}
-
+
// Return the Token for this event within the TypeBuilder that the
// event is defined within.
public EventToken GetEventToken()
@@ -73,22 +73,22 @@ namespace System.Reflection.Emit {
{
SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.AddOn);
}
-
+
public void SetRemoveOnMethod(MethodBuilder mdBuilder)
{
SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.RemoveOn);
}
-
+
public void SetRaiseMethod(MethodBuilder mdBuilder)
{
SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.Fire);
}
-
+
public void AddOtherMethod(MethodBuilder mdBuilder)
{
SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.Other);
}
-
+
// Use this function if client decides to form the custom attribute blob themselves
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
@@ -121,10 +121,10 @@ namespace System.Reflection.Emit {
}
// These are package private so that TypeBuilder can access them.
- private String m_name; // The name of the event
- private EventToken m_evToken; // The token of this event
- private ModuleBuilder m_module;
- private EventAttributes m_attributes;
- private TypeBuilder m_type;
+ private String m_name; // The name of the event
+ private EventToken m_evToken; // The token of this event
+ private ModuleBuilder m_module;
+ private EventAttributes m_attributes;
+ private TypeBuilder m_type;
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/EventToken.cs b/src/mscorlib/src/System/Reflection/Emit/EventToken.cs
index 8ffdce9732..18ec630b5f 100644
--- a/src/mscorlib/src/System/Reflection/Emit/EventToken.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/EventToken.cs
@@ -12,30 +12,34 @@
**
**
===========================================================*/
-namespace System.Reflection.Emit {
-
- using System;
- using System.Reflection;
+
+using System;
+using System.Reflection;
+
+namespace System.Reflection.Emit
+{
[Serializable]
public struct EventToken
{
public static readonly EventToken Empty = new EventToken();
-
+
internal int m_event;
- internal EventToken(int str) {
- m_event=str;
+ internal EventToken(int str)
+ {
+ m_event = str;
}
-
- public int Token {
+
+ public int Token
+ {
get { return m_event; }
}
-
+
public override int GetHashCode()
{
return m_event;
}
-
+
public override bool Equals(Object obj)
{
if (obj is EventToken)
@@ -43,25 +47,20 @@ namespace System.Reflection.Emit {
else
return false;
}
-
+
public bool Equals(EventToken obj)
{
return obj.m_event == m_event;
}
-
+
public static bool operator ==(EventToken a, EventToken b)
{
return a.Equals(b);
}
-
+
public static bool operator !=(EventToken a, EventToken b)
{
return !(a == b);
}
-
}
-
-
-
-
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/FieldBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/FieldBuilder.cs
index 5953b67173..d0e9d3483c 100644
--- a/src/mscorlib/src/System/Reflection/Emit/FieldBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/FieldBuilder.cs
@@ -4,14 +4,14 @@
//
-namespace System.Reflection.Emit
+namespace System.Reflection.Emit
{
using System.Runtime.InteropServices;
using System;
using CultureInfo = System.Globalization.CultureInfo;
using System.Reflection;
using System.Diagnostics.Contracts;
-
+
public sealed class FieldBuilder : FieldInfo
{
#region Private Data Members
@@ -24,36 +24,36 @@ namespace System.Reflection.Emit
#endregion
#region Constructor
- internal FieldBuilder(TypeBuilder typeBuilder, String fieldName, Type type,
+ internal FieldBuilder(TypeBuilder typeBuilder, String fieldName, Type type,
Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes)
{
if (fieldName == null)
throw new ArgumentNullException(nameof(fieldName));
if (fieldName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(fieldName));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(fieldName));
if (fieldName[0] == '\0')
- throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), nameof(fieldName));
+ throw new ArgumentException(SR.Argument_IllegalName, nameof(fieldName));
if (type == null)
throw new ArgumentNullException(nameof(type));
if (type == typeof(void))
- throw new ArgumentException(Environment.GetResourceString("Argument_BadFieldType"));
+ throw new ArgumentException(SR.Argument_BadFieldType);
Contract.EndContractBlock();
m_fieldName = fieldName;
m_typeBuilder = typeBuilder;
m_fieldType = type;
m_Attributes = attributes & ~FieldAttributes.ReservedMask;
-
+
SignatureHelper sigHelp = SignatureHelper.GetFieldSigHelper(m_typeBuilder.Module);
sigHelp.AddArgument(type, requiredCustomModifiers, optionalCustomModifiers);
int sigLength;
byte[] signature = sigHelp.InternalGetSignature(out sigLength);
-
+
m_fieldTok = TypeBuilder.DefineField(m_typeBuilder.GetModuleBuilder().GetNativeHandle(),
typeBuilder.TypeToken.Token, fieldName, signature, sigLength, m_Attributes);
@@ -74,20 +74,20 @@ namespace System.Reflection.Emit
{
get { return m_fieldTok; }
}
-
+
public override Module Module
{
get { return m_typeBuilder.Module; }
}
- public override String Name
+ public override String Name
{
- get {return m_fieldName; }
+ get { return m_fieldName; }
}
- public override Type DeclaringType
+ public override Type DeclaringType
{
- get
+ get
{
if (m_typeBuilder.m_isHiddenGlobalType == true)
return null;
@@ -95,10 +95,10 @@ namespace System.Reflection.Emit
return m_typeBuilder;
}
}
-
- public override Type ReflectedType
+
+ public override Type ReflectedType
{
- get
+ get
{
if (m_typeBuilder.m_isHiddenGlobalType == true)
return null;
@@ -110,35 +110,35 @@ namespace System.Reflection.Emit
#endregion
#region FieldInfo Overrides
- public override Type FieldType
+ public override Type FieldType
{
get { return m_fieldType; }
}
public override Object GetValue(Object obj)
- {
+ {
// NOTE!! If this is implemented, make sure that this throws
// a NotSupportedException for Save-only dynamic assemblies.
// Otherwise, it could cause the .cctor to be executed.
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
- public override void SetValue(Object obj,Object val,BindingFlags invokeAttr,Binder binder,CultureInfo culture)
- {
+ public override void SetValue(Object obj, Object val, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
+ {
// NOTE!! If this is implemented, make sure that this throws
// a NotSupportedException for Save-only dynamic assemblies.
// Otherwise, it could cause the .cctor to be executed.
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
- public override RuntimeFieldHandle FieldHandle
+ public override RuntimeFieldHandle FieldHandle
{
- get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); }
+ get { throw new NotSupportedException(SR.NotSupported_DynamicModule); }
}
- public override FieldAttributes Attributes
+ public override FieldAttributes Attributes
{
get { return m_Attributes; }
}
@@ -148,44 +148,41 @@ namespace System.Reflection.Emit
#region ICustomAttributeProvider Implementation
public override Object[] GetCustomAttributes(bool inherit)
{
-
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
-
+
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
-
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
public override bool IsDefined(Type attributeType, bool inherit)
{
-
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
#endregion
#region Public Members
- public FieldToken GetToken()
+ public FieldToken GetToken()
{
return m_tkField;
}
- public void SetOffset(int iOffset)
+ public void SetOffset(int iOffset)
{
- m_typeBuilder.ThrowIfCreated();
-
+ m_typeBuilder.ThrowIfCreated();
+
TypeBuilder.SetFieldLayoutOffset(m_typeBuilder.GetModuleBuilder().GetNativeHandle(), GetToken().Token, iOffset);
}
- public void SetConstant(Object defaultValue)
+ public void SetConstant(Object defaultValue)
{
- m_typeBuilder.ThrowIfCreated();
-
+ m_typeBuilder.ThrowIfCreated();
+
TypeBuilder.SetConstantValue(m_typeBuilder.GetModuleBuilder(), GetToken().Token, m_fieldType, defaultValue);
}
-
+
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
diff --git a/src/mscorlib/src/System/Reflection/Emit/FieldToken.cs b/src/mscorlib/src/System/Reflection/Emit/FieldToken.cs
index add428f96e..6c5d778d8f 100644
--- a/src/mscorlib/src/System/Reflection/Emit/FieldToken.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/FieldToken.cs
@@ -12,11 +12,12 @@
**
**
===========================================================*/
-namespace System.Reflection.Emit {
-
- using System;
- using System.Reflection;
+using System;
+using System.Reflection;
+
+namespace System.Reflection.Emit
+{
// The FieldToken class is an opaque representation of the Token returned
// by the Metadata to represent the field. FieldTokens are generated by
// Module.GetFieldToken(). There are no meaningful accessors on this class,
@@ -28,7 +29,7 @@ namespace System.Reflection.Emit {
internal int m_fieldTok;
internal Object m_class;
-
+
// Creates an empty FieldToken. A publicly visible constructor so that
// it can be created on the stack.
//public FieldToken() {
@@ -38,23 +39,25 @@ namespace System.Reflection.Emit {
//}
// The actual constructor. Sets the field, attributes and class
// variables
-
- internal FieldToken (int field, Type fieldClass) {
- m_fieldTok=field;
+
+ internal FieldToken(int field, Type fieldClass)
+ {
+ m_fieldTok = field;
m_class = fieldClass;
}
-
- public int Token {
+
+ public int Token
+ {
get { return m_fieldTok; }
}
-
-
+
+
// Generates the hash code for this field.
public override int GetHashCode()
{
return (m_fieldTok);
}
-
+
// Returns true if obj is an instance of FieldToken and is
// equal to this instance.
public override bool Equals(Object obj)
@@ -69,16 +72,15 @@ namespace System.Reflection.Emit {
{
return obj.m_fieldTok == m_fieldTok && obj.m_class == m_class;
}
-
+
public static bool operator ==(FieldToken a, FieldToken b)
{
return a.Equals(b);
}
-
+
public static bool operator !=(FieldToken a, FieldToken b)
{
return !(a == b);
}
-
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/FlowControl.cs b/src/mscorlib/src/System/Reflection/Emit/FlowControl.cs
index 9e528b2551..fb8564652f 100644
--- a/src/mscorlib/src/System/Reflection/Emit/FlowControl.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/FlowControl.cs
@@ -11,23 +11,23 @@
** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND!
** See clrsrcincopcodegen.pl for more information.**
============================================================*/
-namespace System.Reflection.Emit {
using System;
-[Serializable]
-public enum FlowControl
+namespace System.Reflection.Emit
{
-
- Branch = 0,
- Break = 1,
- Call = 2,
- Cond_Branch = 3,
- Meta = 4,
- Next = 5,
- [Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")]
- Phi = 6,
- Return = 7,
- Throw = 8,
-}
+ [Serializable]
+ public enum FlowControl
+ {
+ Branch = 0,
+ Break = 1,
+ Call = 2,
+ Cond_Branch = 3,
+ Meta = 4,
+ Next = 5,
+ [Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")]
+ Phi = 6,
+ Return = 7,
+ Throw = 8,
+ }
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs
index 894f57d49c..dd5ffa92a9 100644
--- a/src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs
@@ -4,19 +4,20 @@
//
+using System;
+using System.Reflection;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Diagnostics.Contracts;
+
namespace System.Reflection.Emit
{
- using System;
- using System.Reflection;
- using System.Collections;
- using System.Collections.Generic;
- using System.Globalization;
- using System.Diagnostics.Contracts;
-
- public sealed class GenericTypeParameterBuilder: TypeInfo
+ public sealed class GenericTypeParameterBuilder : TypeInfo
{
- public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){
- if(typeInfo==null) return false;
+ public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo)
+ {
+ if (typeInfo == null) return false;
return IsAssignableFrom(typeInfo.AsType());
}
@@ -32,14 +33,14 @@ namespace System.Reflection.Emit
#endregion
#region Object Overrides
- public override String ToString()
- {
+ public override String ToString()
+ {
return m_type.Name;
}
- public override bool Equals(object o)
- {
+ public override bool Equals(object o)
+ {
GenericTypeParameterBuilder g = o as GenericTypeParameterBuilder;
-
+
if (g == null)
return false;
@@ -62,22 +63,22 @@ namespace System.Reflection.Emit
#region Type Overrides
- public override Type MakePointerType()
- {
- return SymbolType.FormCompoundType("*", this, 0);
+ public override Type MakePointerType()
+ {
+ return SymbolType.FormCompoundType("*", this, 0);
}
- public override Type MakeByRefType()
+ public override Type MakeByRefType()
{
return SymbolType.FormCompoundType("&", this, 0);
}
- public override Type MakeArrayType()
+ public override Type MakeArrayType()
{
return SymbolType.FormCompoundType("[]", this, 0);
}
- public override Type MakeArrayType(int rank)
+ public override Type MakeArrayType(int rank)
{
if (rank <= 0)
throw new IndexOutOfRangeException();
@@ -88,9 +89,9 @@ namespace System.Reflection.Emit
{
szrank = "*";
}
- else
+ else
{
- for(int i = 1; i < rank; i++)
+ for (int i = 1; i < rank; i++)
szrank += ",";
}
@@ -113,7 +114,7 @@ namespace System.Reflection.Emit
public override String AssemblyQualifiedName { get { return null; } }
- public override Type BaseType { get { return m_type.BaseType; } }
+ public override Type BaseType { get { return m_type.BaseType; } }
protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { throw new NotSupportedException(); }
@@ -153,6 +154,8 @@ namespace System.Reflection.Emit
protected override TypeAttributes GetAttributeFlagsImpl() { return TypeAttributes.Public; }
+ public override bool IsSZArray => false;
+
protected override bool IsArrayImpl() { return false; }
protected override bool IsByRefImpl() { return false; }
@@ -189,7 +192,7 @@ namespace System.Reflection.Emit
public override Type GetGenericTypeDefinition() { throw new InvalidOperationException(); }
- public override Type MakeGenericType(params Type[] typeArguments) { throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericTypeDefinition")); }
+ public override Type MakeGenericType(params Type[] typeArguments) { throw new InvalidOperationException(SR.Arg_NotGenericTypeDefinition); }
protected override bool IsValueTypeImpl() { return false; }
@@ -209,7 +212,7 @@ namespace System.Reflection.Emit
#region Public Members
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
- {
+ {
m_type.SetGenParamCustomAttribute(con, binaryAttribute);
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs b/src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs
index 2cee63ff2e..4021410a33 100644
--- a/src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs
@@ -4,16 +4,16 @@
//
-namespace System.Reflection.Emit
+using System;
+using System.Diagnostics.SymbolStore;
+using System.Runtime.InteropServices;
+using System.Reflection;
+using System.Globalization;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System.Reflection.Emit
{
- using System;
- using System.Diagnostics.SymbolStore;
- using System.Runtime.InteropServices;
- using System.Reflection;
- using System.Globalization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
public class ILGenerator
{
#region Const Members
@@ -28,18 +28,18 @@ namespace System.Reflection.Emit
{
return EnlargeArray(incoming, incoming.Length * 2);
}
-
+
internal static T[] EnlargeArray<T>(T[] incoming, int requiredSize)
{
Contract.Requires(incoming != null);
Contract.Ensures(Contract.Result<T[]>() != null);
Contract.Ensures(Contract.Result<T[]>().Length == requiredSize);
-
+
T[] temp = new T[requiredSize];
Array.Copy(incoming, 0, temp, 0, incoming.Length);
return temp;
}
-
+
private static byte[] EnlargeArray(byte[] incoming)
{
return EnlargeArray(incoming, incoming.Length * 2);
@@ -50,7 +50,7 @@ namespace System.Reflection.Emit
Contract.Requires(incoming != null);
Contract.Ensures(Contract.Result<byte[]>() != null);
Contract.Ensures(Contract.Result<byte[]>().Length == requiredSize);
-
+
byte[] temp = new byte[requiredSize];
Buffer.BlockCopy(incoming, 0, temp, 0, incoming.Length);
return temp;
@@ -58,35 +58,35 @@ namespace System.Reflection.Emit
#endregion
#region Internal Data Members
- private int m_length;
- private byte[] m_ILStream;
+ private int m_length;
+ private byte[] m_ILStream;
+
+ private int[] m_labelList;
+ private int m_labelCount;
- private int[] m_labelList;
- private int m_labelCount;
+ private __FixupData[] m_fixupData;
- private __FixupData[] m_fixupData;
-
- private int m_fixupCount;
+ private int m_fixupCount;
- private int[] m_RelocFixupList;
- private int m_RelocFixupCount;
+ private int[] m_RelocFixupList;
+ private int m_RelocFixupCount;
- private int m_exceptionCount;
- private int m_currExcStackCount;
- private __ExceptionInfo[] m_exceptions; //This is the list of all of the exceptions in this ILStream.
- private __ExceptionInfo[] m_currExcStack; //This is the stack of exceptions which we're currently in.
+ private int m_exceptionCount;
+ private int m_currExcStackCount;
+ private __ExceptionInfo[] m_exceptions; //This is the list of all of the exceptions in this ILStream.
+ private __ExceptionInfo[] m_currExcStack; //This is the stack of exceptions which we're currently in.
- internal ScopeTree m_ScopeTree; // this variable tracks all debugging scope information
- internal LineNumberInfo m_LineNumberInfo; // this variable tracks all line number information
+ internal ScopeTree m_ScopeTree; // this variable tracks all debugging scope information
+ internal LineNumberInfo m_LineNumberInfo; // this variable tracks all line number information
- internal MethodInfo m_methodBuilder;
- internal int m_localCount;
- internal SignatureHelper m_localSignature;
+ internal MethodInfo m_methodBuilder;
+ internal int m_localCount;
+ internal SignatureHelper m_localSignature;
- private int m_maxStackSize = 0; // Maximum stack size not counting the exceptions.
+ private int m_maxStackSize = 0; // Maximum stack size not counting the exceptions.
- private int m_maxMidStack = 0; // Maximum stack size for a given basic block.
- private int m_maxMidStackCur = 0; // Running count of the maximum stack size for the current basic block.
+ private int m_maxMidStack = 0; // Maximum stack size for a given basic block.
+ private int m_maxMidStackCur = 0; // Running count of the maximum stack size for the current basic block.
internal int CurrExcStackCount
{
@@ -128,9 +128,9 @@ namespace System.Reflection.Emit
m_fixupData = null;
- m_exceptions = null;
+ m_exceptions = null;
m_exceptionCount = 0;
- m_currExcStack = null;
+ m_currExcStack = null;
m_currExcStackCount = 0;
m_RelocFixupList = null;
@@ -144,7 +144,7 @@ namespace System.Reflection.Emit
// initialize local signature
m_localCount = 0;
MethodBuilder mb = m_methodBuilder as MethodBuilder;
- if (mb == null)
+ if (mb == null)
m_localSignature = SignatureHelper.GetLocalVarSigHelper(null);
else
m_localSignature = SignatureHelper.GetLocalVarSigHelper(mb.GetTypeBuilder().Module);
@@ -173,7 +173,6 @@ namespace System.Reflection.Emit
m_ILStream[m_length++] = (byte)opcode.Value;
UpdateStackSize(opcode, opcode.StackChange());
-
}
internal void UpdateStackSize(OpCode opcode, int stackchange)
@@ -211,13 +210,13 @@ namespace System.Reflection.Emit
return ((ModuleBuilder)m_methodBuilder.Module).GetMethodTokenInternal(method, optionalParameterTypes, useMethodDef);
}
- internal virtual SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType,
+ internal virtual SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType,
Type[] parameterTypes, Type[] optionalParameterTypes)
{
return GetMemberRefSignature(call, returnType, parameterTypes, optionalParameterTypes, 0);
}
- private SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType,
+ private SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType,
Type[] parameterTypes, Type[] optionalParameterTypes, int cGenericParameters)
{
return ((ModuleBuilder)m_methodBuilder.Module).GetMemberRefSignature(call, returnType, parameterTypes, optionalParameterTypes, cGenericParameters);
@@ -234,7 +233,7 @@ namespace System.Reflection.Emit
if (m_currExcStackCount != 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_UnclosedExceptionBlock"));
+ throw new ArgumentException(SR.Argument_UnclosedExceptionBlock);
}
if (m_length == 0)
return null;
@@ -251,7 +250,7 @@ namespace System.Reflection.Emit
//Do the fixups.
//This involves iterating over all of the labels and
//replacing them with their proper values.
- for (int i =0; i < m_fixupCount; i++)
+ for (int i = 0; i < m_fixupCount; i++)
{
updateAddr = GetLabelPos(m_fixupData[i].m_fixupLabel) - (m_fixupData[i].m_fixupPos + m_fixupData[i].m_fixupInstSize);
@@ -259,11 +258,10 @@ namespace System.Reflection.Emit
//Throw an exception if they're trying to store a jump in a single byte instruction that doesn't fit.
if (m_fixupData[i].m_fixupInstSize == 1)
{
-
//Verify that our one-byte arg will fit into a Signed Byte.
if (updateAddr < SByte.MinValue || updateAddr > SByte.MaxValue)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_IllegalOneByteBranch",m_fixupData[i].m_fixupPos, updateAddr));
+ throw new NotSupportedException(SR.Format(SR.NotSupported_IllegalOneByteBranch, m_fixupData[i].m_fixupPos, updateAddr));
}
//Place the one-byte arg
@@ -287,17 +285,17 @@ namespace System.Reflection.Emit
internal __ExceptionInfo[] GetExceptions()
{
- __ExceptionInfo []temp;
+ __ExceptionInfo[] temp;
if (m_currExcStackCount != 0)
{
- throw new NotSupportedException(Environment.GetResourceString(ResId.Argument_UnclosedExceptionBlock));
+ throw new NotSupportedException(SR.GetResourceString(ResId.Argument_UnclosedExceptionBlock));
}
-
+
if (m_exceptionCount == 0)
{
return null;
}
-
+
temp = new __ExceptionInfo[m_exceptionCount];
Array.Copy(m_exceptions, 0, temp, 0, m_exceptionCount);
SortExceptions(temp);
@@ -325,14 +323,14 @@ namespace System.Reflection.Emit
m_length = PutInteger4InArray(value, m_length, m_ILStream);
}
- private static int PutInteger4InArray(int value, int startPos, byte []array)
+ private static int PutInteger4InArray(int value, int startPos, byte[] array)
{
// Puts an Int32 onto the stream. This is an internal routine, so it does not do any error checking.
array[startPos++] = (byte)value;
- array[startPos++] = (byte)(value >>8);
- array[startPos++] = (byte)(value >>16);
- array[startPos++] = (byte)(value >>24);
+ array[startPos++] = (byte)(value >> 8);
+ array[startPos++] = (byte)(value >> 16);
+ array[startPos++] = (byte)(value >> 24);
return startPos;
}
@@ -342,12 +340,12 @@ namespace System.Reflection.Emit
// Verifies that the label exists and that it has been given a value.
int index = lbl.GetLabelValue();
-
+
if (index < 0 || index >= m_labelCount)
- throw new ArgumentException(Environment.GetResourceString("Argument_BadLabel"));
+ throw new ArgumentException(SR.Argument_BadLabel);
if (m_labelList[index] < 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_BadLabelContent"));
+ throw new ArgumentException(SR.Argument_BadLabelContent);
return m_labelList[index];
}
@@ -378,7 +376,7 @@ namespace System.Reflection.Emit
return m_maxStackSize;
}
- private static void SortExceptions(__ExceptionInfo []exceptions)
+ private static void SortExceptions(__ExceptionInfo[] exceptions)
{
// In order to call exceptions properly we have to sort them in ascending order by their end position.
// Just a cheap insertion sort. We don't expect many exceptions (<10), where InsertionSort beats QuickSort.
@@ -421,40 +419,42 @@ namespace System.Reflection.Emit
{
EnsureCapacity(3);
InternalEmit(opcode);
-
}
- public virtual void Emit(OpCode opcode, byte arg)
+ public virtual void Emit(OpCode opcode, byte arg)
{
EnsureCapacity(4);
InternalEmit(opcode);
- m_ILStream[m_length++]=arg;
+ m_ILStream[m_length++] = arg;
}
[CLSCompliant(false)]
- public void Emit(OpCode opcode, sbyte arg)
+ public void Emit(OpCode opcode, sbyte arg)
{
// Puts opcode onto the stream of instructions followed by arg
EnsureCapacity(4);
InternalEmit(opcode);
- if (arg<0) {
- m_ILStream[m_length++]=(byte)(256+arg);
- } else {
- m_ILStream[m_length++]=(byte) arg;
+ if (arg < 0)
+ {
+ m_ILStream[m_length++] = (byte)(256 + arg);
+ }
+ else
+ {
+ m_ILStream[m_length++] = (byte)arg;
}
}
- public virtual void Emit(OpCode opcode, short arg)
+ public virtual void Emit(OpCode opcode, short arg)
{
// Puts opcode onto the stream of instructions followed by arg
EnsureCapacity(5);
InternalEmit(opcode);
- m_ILStream[m_length++]=(byte) arg;
- m_ILStream[m_length++]=(byte) (arg>>8);
+ m_ILStream[m_length++] = (byte)arg;
+ m_ILStream[m_length++] = (byte)(arg >> 8);
}
- public virtual void Emit(OpCode opcode, int arg)
+ public virtual void Emit(OpCode opcode, int arg)
{
// Puts opcode onto the stream of instructions followed by arg
EnsureCapacity(7);
@@ -488,26 +488,26 @@ namespace System.Reflection.Emit
UpdateStackSize(opcode, stackchange);
RecordTokenFixup();
- PutInteger4(tk);
+ PutInteger4(tk);
}
}
- public virtual void EmitCalli(OpCode opcode, CallingConventions callingConvention,
+ public virtual void EmitCalli(OpCode opcode, CallingConventions callingConvention,
Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes)
{
int stackchange = 0;
- SignatureHelper sig;
+ SignatureHelper sig;
if (optionalParameterTypes != null)
{
if ((callingConvention & CallingConventions.VarArgs) == 0)
{
// Client should not supply optional parameter in default calling convention
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAVarArgCallingConvention"));
+ throw new InvalidOperationException(SR.InvalidOperation_NotAVarArgCallingConvention);
}
}
- ModuleBuilder modBuilder = (ModuleBuilder) m_methodBuilder.Module;
+ ModuleBuilder modBuilder = (ModuleBuilder)m_methodBuilder.Module;
sig = GetMemberRefSignature(callingConvention,
returnType,
parameterTypes,
@@ -542,7 +542,7 @@ namespace System.Reflection.Emit
throw new ArgumentNullException(nameof(methodInfo));
if (!(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj)))
- throw new ArgumentException(Environment.GetResourceString("Argument_NotMethodCallOpcode"), nameof(opcode));
+ throw new ArgumentException(SR.Argument_NotMethodCallOpcode, nameof(opcode));
Contract.EndContractBlock();
@@ -657,11 +657,11 @@ namespace System.Reflection.Emit
// patched if necessary when persisting the module to a PE.
int tempVal = 0;
- ModuleBuilder modBuilder = (ModuleBuilder) m_methodBuilder.Module;
+ ModuleBuilder modBuilder = (ModuleBuilder)m_methodBuilder.Module;
if (opcode == OpCodes.Ldtoken && cls != null && cls.IsGenericTypeDefinition)
{
// This gets the token for the generic type definition if cls is one.
- tempVal = modBuilder.GetTypeToken( cls ).Token;
+ tempVal = modBuilder.GetTypeToken(cls).Token;
}
else
{
@@ -676,44 +676,47 @@ namespace System.Reflection.Emit
PutInteger4(tempVal);
}
- public virtual void Emit(OpCode opcode, long arg) {
+ public virtual void Emit(OpCode opcode, long arg)
+ {
EnsureCapacity(11);
InternalEmit(opcode);
- m_ILStream[m_length++] = (byte) arg;
- m_ILStream[m_length++] = (byte) (arg>>8);
- m_ILStream[m_length++] = (byte) (arg>>16);
- m_ILStream[m_length++] = (byte) (arg>>24);
- m_ILStream[m_length++] = (byte) (arg>>32);
- m_ILStream[m_length++] = (byte) (arg>>40);
- m_ILStream[m_length++] = (byte) (arg>>48);
- m_ILStream[m_length++] = (byte) (arg>>56);
+ m_ILStream[m_length++] = (byte)arg;
+ m_ILStream[m_length++] = (byte)(arg >> 8);
+ m_ILStream[m_length++] = (byte)(arg >> 16);
+ m_ILStream[m_length++] = (byte)(arg >> 24);
+ m_ILStream[m_length++] = (byte)(arg >> 32);
+ m_ILStream[m_length++] = (byte)(arg >> 40);
+ m_ILStream[m_length++] = (byte)(arg >> 48);
+ m_ILStream[m_length++] = (byte)(arg >> 56);
}
- unsafe public virtual void Emit(OpCode opcode, float arg) {
+ unsafe public virtual void Emit(OpCode opcode, float arg)
+ {
EnsureCapacity(7);
InternalEmit(opcode);
uint tempVal = *(uint*)&arg;
- m_ILStream[m_length++] = (byte) tempVal;
- m_ILStream[m_length++] = (byte) (tempVal>>8);
- m_ILStream[m_length++] = (byte) (tempVal>>16);
- m_ILStream[m_length++] = (byte) (tempVal>>24);
+ m_ILStream[m_length++] = (byte)tempVal;
+ m_ILStream[m_length++] = (byte)(tempVal >> 8);
+ m_ILStream[m_length++] = (byte)(tempVal >> 16);
+ m_ILStream[m_length++] = (byte)(tempVal >> 24);
}
- unsafe public virtual void Emit(OpCode opcode, double arg) {
+ unsafe public virtual void Emit(OpCode opcode, double arg)
+ {
EnsureCapacity(11);
InternalEmit(opcode);
- ulong tempVal = *(ulong*)&arg;
- m_ILStream[m_length++] = (byte) tempVal;
- m_ILStream[m_length++] = (byte) (tempVal>>8);
- m_ILStream[m_length++] = (byte) (tempVal>>16);
- m_ILStream[m_length++] = (byte) (tempVal>>24);
- m_ILStream[m_length++] = (byte) (tempVal>>32);
- m_ILStream[m_length++] = (byte) (tempVal>>40);
- m_ILStream[m_length++] = (byte) (tempVal>>48);
- m_ILStream[m_length++] = (byte) (tempVal>>56);
+ ulong tempVal = *(ulong*)&arg;
+ m_ILStream[m_length++] = (byte)tempVal;
+ m_ILStream[m_length++] = (byte)(tempVal >> 8);
+ m_ILStream[m_length++] = (byte)(tempVal >> 16);
+ m_ILStream[m_length++] = (byte)(tempVal >> 24);
+ m_ILStream[m_length++] = (byte)(tempVal >> 32);
+ m_ILStream[m_length++] = (byte)(tempVal >> 40);
+ m_ILStream[m_length++] = (byte)(tempVal >> 48);
+ m_ILStream[m_length++] = (byte)(tempVal >> 56);
}
- public virtual void Emit(OpCode opcode, Label label)
+ public virtual void Emit(OpCode opcode, Label label)
{
// Puts opcode onto the stream and leaves space to include label
// when fixups are done. Labels are created using ILGenerator.DefineLabel and
@@ -724,18 +727,21 @@ namespace System.Reflection.Emit
// opcode must represent a branch instruction (although we don't explicitly
// verify this). Since branches are relative instructions, label will be replaced with the
// correct offset to branch during the fixup process.
-
+
int tempVal = label.GetLabelValue();
EnsureCapacity(7);
-
+
InternalEmit(opcode);
- if (OpCodes.TakesSingleByteArgument(opcode)) {
+ if (OpCodes.TakesSingleByteArgument(opcode))
+ {
AddFixup(label, m_length, 1);
m_length++;
- } else {
+ }
+ else
+ {
AddFixup(label, m_length, 4);
- m_length+=4;
+ m_length += 4;
}
}
@@ -753,32 +759,33 @@ namespace System.Reflection.Emit
int count = labels.Length;
- EnsureCapacity( count * 4 + 7 );
+ EnsureCapacity(count * 4 + 7);
InternalEmit(opcode);
PutInteger4(count);
- for ( remaining = count * 4, i = 0; remaining > 0; remaining -= 4, i++ ) {
- AddFixup( labels[i], m_length, remaining );
+ for (remaining = count * 4, i = 0; remaining > 0; remaining -= 4, i++)
+ {
+ AddFixup(labels[i], m_length, remaining);
m_length += 4;
}
}
public virtual void Emit(OpCode opcode, FieldInfo field)
{
- ModuleBuilder modBuilder = (ModuleBuilder) m_methodBuilder.Module;
- int tempVal = modBuilder.GetFieldToken( field ).Token;
+ ModuleBuilder modBuilder = (ModuleBuilder)m_methodBuilder.Module;
+ int tempVal = modBuilder.GetFieldToken(field).Token;
EnsureCapacity(7);
InternalEmit(opcode);
RecordTokenFixup();
PutInteger4(tempVal);
}
- public virtual void Emit(OpCode opcode, String str)
+ public virtual void Emit(OpCode opcode, String str)
{
// Puts the opcode onto the IL stream followed by the metadata token
// represented by str. The location of str is recorded for future
// fixups if the module is persisted to a PE.
- ModuleBuilder modBuilder = (ModuleBuilder) m_methodBuilder.Module;
+ ModuleBuilder modBuilder = (ModuleBuilder)m_methodBuilder.Module;
int tempVal = modBuilder.GetStringConstant(str).Token;
EnsureCapacity(7);
InternalEmit(opcode);
@@ -797,12 +804,12 @@ namespace System.Reflection.Emit
int tempVal = local.GetLocalIndex();
if (local.GetMethodBuilder() != m_methodBuilder)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_UnmatchedMethodForLocal"), nameof(local));
+ throw new ArgumentException(SR.Argument_UnmatchedMethodForLocal, nameof(local));
}
// If the instruction is a ldloc, ldloca a stloc, morph it to the optimal form.
if (opcode.Equals(OpCodes.Ldloc))
{
- switch(tempVal)
+ switch (tempVal)
{
case 0:
opcode = OpCodes.Ldloc_0;
@@ -824,7 +831,7 @@ namespace System.Reflection.Emit
}
else if (opcode.Equals(OpCodes.Stloc))
{
- switch(tempVal)
+ switch (tempVal)
{
case 0:
opcode = OpCodes.Stloc_0;
@@ -852,28 +859,28 @@ namespace System.Reflection.Emit
EnsureCapacity(7);
InternalEmit(opcode);
-
+
if (opcode.OperandType == OperandType.InlineNone)
return;
else if (!OpCodes.TakesSingleByteArgument(opcode))
{
- m_ILStream[m_length++]=(byte) tempVal;
- m_ILStream[m_length++]=(byte) (tempVal>>8);
+ m_ILStream[m_length++] = (byte)tempVal;
+ m_ILStream[m_length++] = (byte)(tempVal >> 8);
}
else
{
//Handle stloc_1, ldloc_1
if (tempVal > Byte.MaxValue)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadInstructionOrIndexOutOfBound"));
+ throw new InvalidOperationException(SR.InvalidOperation_BadInstructionOrIndexOutOfBound);
}
- m_ILStream[m_length++]=(byte)tempVal;
+ m_ILStream[m_length++] = (byte)tempVal;
}
}
#endregion
#region Exceptions
- public virtual Label BeginExceptionBlock()
+ public virtual Label BeginExceptionBlock()
{
// Begin an Exception block. Creating an Exception block records some information,
// but does not actually emit any IL onto the stream. Exceptions should be created and
@@ -898,11 +905,13 @@ namespace System.Reflection.Emit
m_currExcStack = new __ExceptionInfo[DefaultExceptionArraySize];
}
- if (m_exceptionCount>=m_exceptions.Length) {
- m_exceptions=EnlargeArray(m_exceptions);
+ if (m_exceptionCount >= m_exceptions.Length)
+ {
+ m_exceptions = EnlargeArray(m_exceptions);
}
- if (m_currExcStackCount>=m_currExcStack.Length) {
+ if (m_currExcStackCount >= m_currExcStack.Length)
+ {
m_currExcStack = EnlargeArray(m_currExcStack);
}
@@ -917,14 +926,16 @@ namespace System.Reflection.Emit
return endLabel;
}
- public virtual void EndExceptionBlock() {
- if (m_currExcStackCount==0) {
- throw new NotSupportedException(Environment.GetResourceString("Argument_NotInExceptionBlock"));
+ public virtual void EndExceptionBlock()
+ {
+ if (m_currExcStackCount == 0)
+ {
+ throw new NotSupportedException(SR.Argument_NotInExceptionBlock);
}
- // Pop the current exception block
- __ExceptionInfo current = m_currExcStack[m_currExcStackCount-1];
- m_currExcStack[m_currExcStackCount-1] = null;
+ // Pop the current exception block
+ __ExceptionInfo current = m_currExcStack[m_currExcStackCount - 1];
+ m_currExcStack[m_currExcStackCount - 1] = null;
m_currExcStackCount--;
Label endLabel = current.GetEndLabel();
@@ -933,36 +944,40 @@ namespace System.Reflection.Emit
if (state == __ExceptionInfo.State_Filter ||
state == __ExceptionInfo.State_Try)
{
-
-
- throw new InvalidOperationException(Environment.GetResourceString("Argument_BadExceptionCodeGen"));
+ throw new InvalidOperationException(SR.Argument_BadExceptionCodeGen);
}
- if (state == __ExceptionInfo.State_Catch) {
+ if (state == __ExceptionInfo.State_Catch)
+ {
this.Emit(OpCodes.Leave, endLabel);
- } else if (state == __ExceptionInfo.State_Finally || state == __ExceptionInfo.State_Fault) {
+ }
+ else if (state == __ExceptionInfo.State_Finally || state == __ExceptionInfo.State_Fault)
+ {
this.Emit(OpCodes.Endfinally);
}
//Check if we've alredy set this label.
//The only reason why we might have set this is if we have a finally block.
- if (m_labelList[endLabel.GetLabelValue()]==-1) {
+ if (m_labelList[endLabel.GetLabelValue()] == -1)
+ {
MarkLabel(endLabel);
- } else {
+ }
+ else
+ {
MarkLabel(current.GetFinallyEndLabel());
}
current.Done(m_length);
}
- public virtual void BeginExceptFilterBlock()
+ public virtual void BeginExceptFilterBlock()
{
// Begins an exception filter block. Emits a branch instruction to the end of the current exception block.
if (m_currExcStackCount == 0)
- throw new NotSupportedException(Environment.GetResourceString("Argument_NotInExceptionBlock"));
+ throw new NotSupportedException(SR.Argument_NotInExceptionBlock);
- __ExceptionInfo current = m_currExcStack[m_currExcStackCount-1];
+ __ExceptionInfo current = m_currExcStack[m_currExcStackCount - 1];
Label endLabel = current.GetEndLabel();
this.Emit(OpCodes.Leave, endLabel);
@@ -970,30 +985,35 @@ namespace System.Reflection.Emit
current.MarkFilterAddr(m_length);
}
- public virtual void BeginCatchBlock(Type exceptionType)
+ public virtual void BeginCatchBlock(Type exceptionType)
{
// Begins a catch block. Emits a branch instruction to the end of the current exception block.
- if (m_currExcStackCount==0) {
- throw new NotSupportedException(Environment.GetResourceString("Argument_NotInExceptionBlock"));
+ if (m_currExcStackCount == 0)
+ {
+ throw new NotSupportedException(SR.Argument_NotInExceptionBlock);
}
- __ExceptionInfo current = m_currExcStack[m_currExcStackCount-1];
+ __ExceptionInfo current = m_currExcStack[m_currExcStackCount - 1];
- if (current.GetCurrentState() == __ExceptionInfo.State_Filter) {
- if (exceptionType != null) {
- throw new ArgumentException(Environment.GetResourceString("Argument_ShouldNotSpecifyExceptionType"));
+ if (current.GetCurrentState() == __ExceptionInfo.State_Filter)
+ {
+ if (exceptionType != null)
+ {
+ throw new ArgumentException(SR.Argument_ShouldNotSpecifyExceptionType);
}
this.Emit(OpCodes.Endfilter);
- } else {
+ }
+ else
+ {
// execute this branch if previous clause is Catch or Fault
- if (exceptionType==null) {
+ if (exceptionType == null)
+ {
throw new ArgumentNullException(nameof(exceptionType));
}
Label endLabel = current.GetEndLabel();
this.Emit(OpCodes.Leave, endLabel);
-
}
current.MarkCatchAddr(m_length, exceptionType);
@@ -1001,10 +1021,11 @@ namespace System.Reflection.Emit
public virtual void BeginFaultBlock()
{
- if (m_currExcStackCount==0) {
- throw new NotSupportedException(Environment.GetResourceString("Argument_NotInExceptionBlock"));
+ if (m_currExcStackCount == 0)
+ {
+ throw new NotSupportedException(SR.Argument_NotInExceptionBlock);
}
- __ExceptionInfo current = m_currExcStack[m_currExcStackCount-1];
+ __ExceptionInfo current = m_currExcStack[m_currExcStackCount - 1];
// emit the leave for the clause before this one.
Label endLabel = current.GetEndLabel();
@@ -1013,28 +1034,29 @@ namespace System.Reflection.Emit
current.MarkFaultAddr(m_length);
}
- public virtual void BeginFinallyBlock()
+ public virtual void BeginFinallyBlock()
{
- if (m_currExcStackCount==0) {
- throw new NotSupportedException(Environment.GetResourceString("Argument_NotInExceptionBlock"));
+ if (m_currExcStackCount == 0)
+ {
+ throw new NotSupportedException(SR.Argument_NotInExceptionBlock);
}
- __ExceptionInfo current = m_currExcStack[m_currExcStackCount-1];
- int state = current.GetCurrentState();
- Label endLabel = current.GetEndLabel();
- int catchEndAddr = 0;
+ __ExceptionInfo current = m_currExcStack[m_currExcStackCount - 1];
+ int state = current.GetCurrentState();
+ Label endLabel = current.GetEndLabel();
+ int catchEndAddr = 0;
if (state != __ExceptionInfo.State_Try)
{
// generate leave for any preceeding catch clause
- this.Emit(OpCodes.Leave, endLabel);
+ this.Emit(OpCodes.Leave, endLabel);
catchEndAddr = m_length;
}
-
+
MarkLabel(endLabel);
Label finallyEndLabel = this.DefineLabel();
current.SetFinallyEndLabel(finallyEndLabel);
-
+
// generate leave for try clause
this.Emit(OpCodes.Leave, finallyEndLabel);
if (catchEndAddr == 0)
@@ -1045,25 +1067,27 @@ namespace System.Reflection.Emit
#endregion
#region Labels
- public virtual Label DefineLabel()
+ public virtual Label DefineLabel()
{
// Declares a new Label. This is just a token and does not yet represent any particular location
// within the stream. In order to set the position of the label within the stream, you must call
// Mark Label.
// Delay init the lable array in case we dont use it
- if (m_labelList == null){
+ if (m_labelList == null)
+ {
m_labelList = new int[DefaultLabelArraySize];
}
- if (m_labelCount>=m_labelList.Length) {
+ if (m_labelCount >= m_labelList.Length)
+ {
m_labelList = EnlargeArray(m_labelList);
}
- m_labelList[m_labelCount]=-1;
+ m_labelList[m_labelCount] = -1;
return new Label(m_labelCount++);
}
- public virtual void MarkLabel(Label loc)
+ public virtual void MarkLabel(Label loc)
{
// Defines a label by setting the position where that label is found within the stream.
// Does not allow a label to be defined more than once.
@@ -1071,15 +1095,17 @@ namespace System.Reflection.Emit
int labelIndex = loc.GetLabelValue();
//This should never happen.
- if (labelIndex<0 || labelIndex>=m_labelList.Length) {
- throw new ArgumentException (Environment.GetResourceString("Argument_InvalidLabel"));
+ if (labelIndex < 0 || labelIndex >= m_labelList.Length)
+ {
+ throw new ArgumentException(SR.Argument_InvalidLabel);
}
- if (m_labelList[labelIndex]!=-1) {
- throw new ArgumentException (Environment.GetResourceString("Argument_RedefinedLabel"));
+ if (m_labelList[labelIndex] != -1)
+ {
+ throw new ArgumentException(SR.Argument_RedefinedLabel);
}
- m_labelList[labelIndex]=m_length;
+ m_labelList[labelIndex] = m_length;
}
#endregion
@@ -1089,17 +1115,20 @@ namespace System.Reflection.Emit
{
// Emits the il to throw an exception
- if (excType==null) {
+ if (excType == null)
+ {
throw new ArgumentNullException(nameof(excType));
}
- if (!excType.IsSubclassOf(typeof(Exception)) && excType!=typeof(Exception)) {
- throw new ArgumentException(Environment.GetResourceString("Argument_NotExceptionType"));
+ if (!excType.IsSubclassOf(typeof(Exception)) && excType != typeof(Exception))
+ {
+ throw new ArgumentException(SR.Argument_NotExceptionType);
}
Contract.EndContractBlock();
ConstructorInfo con = excType.GetConstructor(Type.EmptyTypes);
- if (con==null) {
- throw new ArgumentException(Environment.GetResourceString("Argument_MissingDefaultConstructor"));
+ if (con == null)
+ {
+ throw new ArgumentException(SR.Argument_MissingDefaultConstructor);
}
this.Emit(OpCodes.Newobj, con);
this.Emit(OpCodes.Throw);
@@ -1108,7 +1137,7 @@ namespace System.Reflection.Emit
private static Type GetConsoleType()
{
return Type.GetType(
- "System.Console, System.Console, Version=4.0.0.0, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken,
+ "System.Console, System.Console, Version=4.0.0.0, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken,
throwOnError: true);
}
@@ -1123,17 +1152,17 @@ namespace System.Reflection.Emit
Emit(OpCodes.Call, mi);
}
- public virtual void EmitWriteLine(LocalBuilder localBuilder)
+ public virtual void EmitWriteLine(LocalBuilder localBuilder)
{
// Emits the IL necessary to call WriteLine with lcl. It is
// an error to call EmitWriteLine with a lcl which is not of
// one of the types for which Console.WriteLine implements overloads. (e.g.
// we do *not* call ToString on the locals.
- Object cls;
- if (m_methodBuilder==null)
+ Object cls;
+ if (m_methodBuilder == null)
{
- throw new ArgumentException(Environment.GetResourceString("InvalidOperation_BadILGeneratorUsage"));
+ throw new ArgumentException(SR.InvalidOperation_BadILGeneratorUsage);
}
MethodInfo prop = GetConsoleType().GetMethod("get_Out");
@@ -1141,13 +1170,15 @@ namespace System.Reflection.Emit
Emit(OpCodes.Ldloc, localBuilder);
Type[] parameterTypes = new Type[1];
cls = localBuilder.LocalType;
- if (cls is TypeBuilder || cls is EnumBuilder) {
- throw new ArgumentException(Environment.GetResourceString("NotSupported_OutputStreamUsingTypeBuilder"));
+ if (cls is TypeBuilder || cls is EnumBuilder)
+ {
+ throw new ArgumentException(SR.NotSupported_OutputStreamUsingTypeBuilder);
}
parameterTypes[0] = (Type)cls;
MethodInfo mi = prop.ReturnType.GetMethod("WriteLine", parameterTypes);
- if (mi==null) {
- throw new ArgumentException(Environment.GetResourceString("Argument_EmitWriteLineType"), nameof(localBuilder));
+ if (mi == null)
+ {
+ throw new ArgumentException(SR.Argument_EmitWriteLineType, nameof(localBuilder));
}
Emit(OpCodes.Callvirt, mi);
@@ -1167,25 +1198,30 @@ namespace System.Reflection.Emit
throw new ArgumentNullException(nameof(fld));
}
Contract.EndContractBlock();
-
+
MethodInfo prop = GetConsoleType().GetMethod("get_Out");
Emit(OpCodes.Call, prop);
- if ((fld.Attributes & FieldAttributes.Static)!=0) {
+ if ((fld.Attributes & FieldAttributes.Static) != 0)
+ {
Emit(OpCodes.Ldsfld, fld);
- } else {
+ }
+ else
+ {
Emit(OpCodes.Ldarg, (short)0); //Load the this ref.
Emit(OpCodes.Ldfld, fld);
}
Type[] parameterTypes = new Type[1];
cls = fld.FieldType;
- if (cls is TypeBuilder || cls is EnumBuilder) {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_OutputStreamUsingTypeBuilder"));
+ if (cls is TypeBuilder || cls is EnumBuilder)
+ {
+ throw new NotSupportedException(SR.NotSupported_OutputStreamUsingTypeBuilder);
}
parameterTypes[0] = (Type)cls;
MethodInfo mi = prop.ReturnType.GetMethod("WriteLine", parameterTypes);
- if (mi==null) {
- throw new ArgumentException(Environment.GetResourceString("Argument_EmitWriteLineType"), nameof(fld));
+ if (mi == null)
+ {
+ throw new ArgumentException(SR.Argument_EmitWriteLineType, nameof(fld));
}
Emit(OpCodes.Callvirt, mi);
}
@@ -1203,24 +1239,26 @@ namespace System.Reflection.Emit
// Declare a local of type "local". The current active lexical scope
// will be the scope that local will live.
- LocalBuilder localBuilder;
+ LocalBuilder localBuilder;
MethodBuilder methodBuilder = m_methodBuilder as MethodBuilder;
- if (methodBuilder == null)
+ if (methodBuilder == null)
throw new NotSupportedException();
if (methodBuilder.IsTypeCreated())
{
// cannot change method after its containing type has been created
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TypeHasBeenCreated"));
+ throw new InvalidOperationException(SR.InvalidOperation_TypeHasBeenCreated);
}
- if (localType==null) {
+ if (localType == null)
+ {
throw new ArgumentNullException(nameof(localType));
}
- if (methodBuilder.m_bIsBaked) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodBaked"));
+ if (methodBuilder.m_bIsBaked)
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_MethodBaked);
}
// add the localType to local signature
@@ -1240,12 +1278,12 @@ namespace System.Reflection.Emit
throw new ArgumentNullException(nameof(usingNamespace));
if (usingNamespace.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(usingNamespace));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(usingNamespace));
Contract.EndContractBlock();
int index;
MethodBuilder methodBuilder = m_methodBuilder as MethodBuilder;
- if (methodBuilder == null)
+ if (methodBuilder == null)
throw new NotSupportedException();
index = methodBuilder.GetILGenerator().m_ScopeTree.GetCurrentActiveScopeIndex();
@@ -1301,43 +1339,44 @@ namespace System.Reflection.Emit
{
internal Label m_fixupLabel;
internal int m_fixupPos;
-
+
internal int m_fixupInstSize;
}
- internal sealed class __ExceptionInfo {
-
- internal const int None = 0x0000; //COR_ILEXCEPTION_CLAUSE_NONE
- internal const int Filter = 0x0001; //COR_ILEXCEPTION_CLAUSE_FILTER
- internal const int Finally = 0x0002; //COR_ILEXCEPTION_CLAUSE_FINALLY
- internal const int Fault = 0x0004; //COR_ILEXCEPTION_CLAUSE_FAULT
- internal const int PreserveStack = 0x0004; //COR_ILEXCEPTION_CLAUSE_PRESERVESTACK
+ internal sealed class __ExceptionInfo
+ {
+ internal const int None = 0x0000; //COR_ILEXCEPTION_CLAUSE_NONE
+ internal const int Filter = 0x0001; //COR_ILEXCEPTION_CLAUSE_FILTER
+ internal const int Finally = 0x0002; //COR_ILEXCEPTION_CLAUSE_FINALLY
+ internal const int Fault = 0x0004; //COR_ILEXCEPTION_CLAUSE_FAULT
+ internal const int PreserveStack = 0x0004; //COR_ILEXCEPTION_CLAUSE_PRESERVESTACK
internal const int State_Try = 0;
- internal const int State_Filter =1;
+ internal const int State_Filter = 1;
internal const int State_Catch = 2;
internal const int State_Finally = 3;
internal const int State_Fault = 4;
internal const int State_Done = 5;
internal int m_startAddr;
- internal int []m_filterAddr;
- internal int []m_catchAddr;
- internal int []m_catchEndAddr;
- internal int []m_type;
- internal Type []m_catchClass;
+ internal int[] m_filterAddr;
+ internal int[] m_catchAddr;
+ internal int[] m_catchEndAddr;
+ internal int[] m_type;
+ internal Type[] m_catchClass;
internal Label m_endLabel;
internal Label m_finallyEndLabel;
internal int m_endAddr;
internal int m_endFinally;
internal int m_currentCatch;
- int m_currentState;
+ private int m_currentState;
//This will never get called. The values exist merely to keep the
//compiler happy.
- private __ExceptionInfo() {
+ private __ExceptionInfo()
+ {
m_startAddr = 0;
m_filterAddr = null;
m_catchAddr = null;
@@ -1349,68 +1388,70 @@ namespace System.Reflection.Emit
m_currentState = State_Try;
}
- internal __ExceptionInfo(int startAddr, Label endLabel) {
- m_startAddr=startAddr;
- m_endAddr=-1;
- m_filterAddr=new int[4];
- m_catchAddr=new int[4];
- m_catchEndAddr=new int[4];
- m_catchClass=new Type[4];
- m_currentCatch=0;
- m_endLabel=endLabel;
- m_type=new int[4];
- m_endFinally=-1;
+ internal __ExceptionInfo(int startAddr, Label endLabel)
+ {
+ m_startAddr = startAddr;
+ m_endAddr = -1;
+ m_filterAddr = new int[4];
+ m_catchAddr = new int[4];
+ m_catchEndAddr = new int[4];
+ m_catchClass = new Type[4];
+ m_currentCatch = 0;
+ m_endLabel = endLabel;
+ m_type = new int[4];
+ m_endFinally = -1;
m_currentState = State_Try;
}
private void MarkHelper(
- int catchorfilterAddr, // the starting address of a clause
- int catchEndAddr, // the end address of a previous catch clause. Only use when finally is following a catch
- Type catchClass, // catch exception type
- int type) // kind of clause
- {
- if (m_currentCatch>=m_catchAddr.Length) {
- m_filterAddr=ILGenerator.EnlargeArray(m_filterAddr);
- m_catchAddr=ILGenerator.EnlargeArray(m_catchAddr);
- m_catchEndAddr=ILGenerator.EnlargeArray(m_catchEndAddr);
- m_catchClass=ILGenerator.EnlargeArray(m_catchClass);
+ int catchorfilterAddr, // the starting address of a clause
+ int catchEndAddr, // the end address of a previous catch clause. Only use when finally is following a catch
+ Type catchClass, // catch exception type
+ int type) // kind of clause
+ {
+ if (m_currentCatch >= m_catchAddr.Length)
+ {
+ m_filterAddr = ILGenerator.EnlargeArray(m_filterAddr);
+ m_catchAddr = ILGenerator.EnlargeArray(m_catchAddr);
+ m_catchEndAddr = ILGenerator.EnlargeArray(m_catchEndAddr);
+ m_catchClass = ILGenerator.EnlargeArray(m_catchClass);
m_type = ILGenerator.EnlargeArray(m_type);
}
if (type == Filter)
{
- m_type[m_currentCatch]=type;
+ m_type[m_currentCatch] = type;
m_filterAddr[m_currentCatch] = catchorfilterAddr;
m_catchAddr[m_currentCatch] = -1;
if (m_currentCatch > 0)
{
- Debug.Assert(m_catchEndAddr[m_currentCatch-1] == -1,"m_catchEndAddr[m_currentCatch-1] == -1");
- m_catchEndAddr[m_currentCatch-1] = catchorfilterAddr;
+ Debug.Assert(m_catchEndAddr[m_currentCatch - 1] == -1, "m_catchEndAddr[m_currentCatch-1] == -1");
+ m_catchEndAddr[m_currentCatch - 1] = catchorfilterAddr;
}
}
else
{
// catch or Fault clause
- m_catchClass[m_currentCatch]=catchClass;
+ m_catchClass[m_currentCatch] = catchClass;
if (m_type[m_currentCatch] != Filter)
{
- m_type[m_currentCatch]=type;
+ m_type[m_currentCatch] = type;
}
- m_catchAddr[m_currentCatch]=catchorfilterAddr;
+ m_catchAddr[m_currentCatch] = catchorfilterAddr;
if (m_currentCatch > 0)
{
- if (m_type[m_currentCatch] != Filter)
- {
- Debug.Assert(m_catchEndAddr[m_currentCatch-1] == -1,"m_catchEndAddr[m_currentCatch-1] == -1");
- m_catchEndAddr[m_currentCatch-1] = catchEndAddr;
- }
+ if (m_type[m_currentCatch] != Filter)
+ {
+ Debug.Assert(m_catchEndAddr[m_currentCatch - 1] == -1, "m_catchEndAddr[m_currentCatch-1] == -1");
+ m_catchEndAddr[m_currentCatch - 1] = catchEndAddr;
+ }
}
- m_catchEndAddr[m_currentCatch]=-1;
+ m_catchEndAddr[m_currentCatch] = -1;
m_currentCatch++;
}
- if (m_endAddr==-1)
+ if (m_endAddr == -1)
{
- m_endAddr=catchorfilterAddr;
+ m_endAddr = catchorfilterAddr;
}
}
@@ -1426,74 +1467,92 @@ namespace System.Reflection.Emit
MarkHelper(faultAddr, faultAddr, null, Fault);
}
- internal void MarkCatchAddr(int catchAddr, Type catchException) {
+ internal void MarkCatchAddr(int catchAddr, Type catchException)
+ {
m_currentState = State_Catch;
MarkHelper(catchAddr, catchAddr, catchException, None);
}
- internal void MarkFinallyAddr(int finallyAddr, int endCatchAddr) {
- if (m_endFinally!=-1) {
- throw new ArgumentException(Environment.GetResourceString("Argument_TooManyFinallyClause"));
- } else {
+ internal void MarkFinallyAddr(int finallyAddr, int endCatchAddr)
+ {
+ if (m_endFinally != -1)
+ {
+ throw new ArgumentException(SR.Argument_TooManyFinallyClause);
+ }
+ else
+ {
m_currentState = State_Finally;
- m_endFinally=finallyAddr;
+ m_endFinally = finallyAddr;
}
MarkHelper(finallyAddr, endCatchAddr, null, Finally);
}
- internal void Done(int endAddr) {
- Debug.Assert(m_currentCatch > 0,"m_currentCatch > 0");
- Debug.Assert(m_catchAddr[m_currentCatch-1] > 0,"m_catchAddr[m_currentCatch-1] > 0");
- Debug.Assert(m_catchEndAddr[m_currentCatch-1] == -1,"m_catchEndAddr[m_currentCatch-1] == -1");
- m_catchEndAddr[m_currentCatch-1] = endAddr;
+ internal void Done(int endAddr)
+ {
+ Debug.Assert(m_currentCatch > 0, "m_currentCatch > 0");
+ Debug.Assert(m_catchAddr[m_currentCatch - 1] > 0, "m_catchAddr[m_currentCatch-1] > 0");
+ Debug.Assert(m_catchEndAddr[m_currentCatch - 1] == -1, "m_catchEndAddr[m_currentCatch-1] == -1");
+ m_catchEndAddr[m_currentCatch - 1] = endAddr;
m_currentState = State_Done;
}
- internal int GetStartAddress() {
+ internal int GetStartAddress()
+ {
return m_startAddr;
}
- internal int GetEndAddress() {
+ internal int GetEndAddress()
+ {
return m_endAddr;
}
- internal int GetFinallyEndAddress() {
+ internal int GetFinallyEndAddress()
+ {
return m_endFinally;
}
- internal Label GetEndLabel() {
+ internal Label GetEndLabel()
+ {
return m_endLabel;
}
- internal int [] GetFilterAddresses() {
+ internal int[] GetFilterAddresses()
+ {
return m_filterAddr;
}
- internal int [] GetCatchAddresses() {
+ internal int[] GetCatchAddresses()
+ {
return m_catchAddr;
}
- internal int [] GetCatchEndAddresses() {
+ internal int[] GetCatchEndAddresses()
+ {
return m_catchEndAddr;
}
- internal Type [] GetCatchClass() {
+ internal Type[] GetCatchClass()
+ {
return m_catchClass;
}
- internal int GetNumberOfCatches() {
+ internal int GetNumberOfCatches()
+ {
return m_currentCatch;
}
- internal int[] GetExceptionTypes() {
+ internal int[] GetExceptionTypes()
+ {
return m_type;
}
- internal void SetFinallyEndLabel(Label lbl) {
- m_finallyEndLabel=lbl;
+ internal void SetFinallyEndLabel(Label lbl)
+ {
+ m_finallyEndLabel = lbl;
}
- internal Label GetFinallyEndLabel() {
+ internal Label GetFinallyEndLabel()
+ {
return m_finallyEndLabel;
}
@@ -1505,15 +1564,16 @@ namespace System.Reflection.Emit
// of an exception. This is somewhat of a mis-nomer. This gives a
// random result for cases where the two exceptions being compared do
// not having a nesting relation.
- internal bool IsInner(__ExceptionInfo exc) {
+ internal bool IsInner(__ExceptionInfo exc)
+ {
Contract.Requires(exc != null);
- Debug.Assert(m_currentCatch > 0,"m_currentCatch > 0");
- Debug.Assert(exc.m_currentCatch > 0,"exc.m_currentCatch > 0");
+ Debug.Assert(m_currentCatch > 0, "m_currentCatch > 0");
+ Debug.Assert(exc.m_currentCatch > 0, "exc.m_currentCatch > 0");
int exclast = exc.m_currentCatch - 1;
int last = m_currentCatch - 1;
- if (exc.m_catchEndAddr[exclast] < m_catchEndAddr[last])
+ if (exc.m_catchEndAddr[exclast] < m_catchEndAddr[last])
return true;
else if (exc.m_catchEndAddr[exclast] == m_catchEndAddr[last])
{
@@ -1530,7 +1590,8 @@ namespace System.Reflection.Emit
// 2 indicates in a catch block
// 3 indicates in a finally block
// 4 indicates Done
- internal int GetCurrentState() {
+ internal int GetCurrentState()
+ {
return m_currentState;
}
}
@@ -1545,10 +1606,10 @@ namespace System.Reflection.Emit
*
***************************/
[Serializable]
- enum ScopeAction
+ internal enum ScopeAction
{
- Open = 0x0,
- Close = 0x1,
+ Open = 0x0,
+ Close = 0x1,
}
internal sealed class ScopeTree
@@ -1569,8 +1630,8 @@ namespace System.Reflection.Emit
***************************/
internal int GetCurrentActiveScopeIndex()
{
- int cClose = 0;
- int i = m_iCount - 1;
+ int cClose = 0;
+ int i = m_iCount - 1;
if (m_iCount == 0)
{
@@ -1590,13 +1651,13 @@ namespace System.Reflection.Emit
}
internal void AddLocalSymInfoToCurrentScope(
- String strName,
- byte[] signature,
- int slot,
- int startOffset,
- int endOffset)
+ String strName,
+ byte[] signature,
+ int slot,
+ int startOffset,
+ int endOffset)
{
- int i = GetCurrentActiveScopeIndex();
+ int i = GetCurrentActiveScopeIndex();
if (m_localSymInfos[i] == null)
{
m_localSymInfos[i] = new LocalSymInfo();
@@ -1605,9 +1666,9 @@ namespace System.Reflection.Emit
}
internal void AddUsingNamespaceToCurrentScope(
- String strNamespace)
+ String strNamespace)
{
- int i = GetCurrentActiveScopeIndex();
+ int i = GetCurrentActiveScopeIndex();
if (m_localSymInfos[i] == null)
{
m_localSymInfos[i] = new LocalSymInfo();
@@ -1617,16 +1678,16 @@ namespace System.Reflection.Emit
internal void AddScopeInfo(ScopeAction sa, int iOffset)
{
- if (sa == ScopeAction.Close && m_iOpenScopeCount <=0)
+ if (sa == ScopeAction.Close && m_iOpenScopeCount <= 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_UnmatchingSymScope"));
+ throw new ArgumentException(SR.Argument_UnmatchingSymScope);
}
Contract.EndContractBlock();
// make sure that arrays are large enough to hold addition info
- EnsureCapacity();
-
-
+ EnsureCapacity();
+
+
m_ScopeActions[m_iCount] = sa;
m_iOffsets[m_iCount] = iOffset;
m_localSymInfos[m_iCount] = null;
@@ -1637,7 +1698,6 @@ namespace System.Reflection.Emit
}
else
m_iOpenScopeCount--;
-
}
/**************************
@@ -1675,7 +1735,7 @@ namespace System.Reflection.Emit
internal void EmitScopeTree(ISymbolWriter symWriter)
{
- int i;
+ int i;
for (i = 0; i < m_iCount; i++)
{
if (m_ScopeActions[i] == ScopeAction.Open)
@@ -1693,11 +1753,11 @@ namespace System.Reflection.Emit
}
}
- internal int[] m_iOffsets; // array of offsets
- internal ScopeAction[] m_ScopeActions; // array of scope actions
- internal int m_iCount; // how many entries in the arrays are occupied
- internal int m_iOpenScopeCount; // keep track how many scopes are open
- internal const int InitialSize = 16;
+ internal int[] m_iOffsets; // array of offsets
+ internal ScopeAction[] m_ScopeActions; // array of scope actions
+ internal int m_iCount; // how many entries in the arrays are occupied
+ internal int m_iOpenScopeCount; // keep track how many scopes are open
+ internal const int InitialSize = 16;
internal LocalSymInfo[] m_localSymInfos; // keep track debugging local information
}
@@ -1718,32 +1778,32 @@ namespace System.Reflection.Emit
internal void AddLineNumberInfo(
ISymbolDocumentWriter document,
- int iOffset,
- int iStartLine,
- int iStartColumn,
- int iEndLine,
- int iEndColumn)
- {
- int i;
-
+ int iOffset,
+ int iStartLine,
+ int iStartColumn,
+ int iEndLine,
+ int iEndColumn)
+ {
+ int i;
+
// make sure that arrays are large enough to hold addition info
i = FindDocument(document);
-
+
Debug.Assert(i < m_DocumentCount, "Bad document look up!");
m_Documents[i].AddLineNumberInfo(document, iOffset, iStartLine, iStartColumn, iEndLine, iEndColumn);
}
-
+
// Find a REDocument representing document. If we cannot find one, we will add a new entry into
// the REDocument array.
private int FindDocument(ISymbolDocumentWriter document)
{
- int i;
-
+ int i;
+
// This is an optimization. The chance that the previous line is coming from the same
// document is very high.
if (m_iLastFound < m_DocumentCount && m_Documents[m_iLastFound].m_document == document)
return m_iLastFound;
-
+
for (i = 0; i < m_DocumentCount; i++)
{
if (m_Documents[i].m_document == document)
@@ -1752,7 +1812,7 @@ namespace System.Reflection.Emit
return m_iLastFound;
}
}
-
+
// cannot find an existing document so add one to the array
EnsureCapacity();
m_iLastFound = m_DocumentCount;
@@ -1776,7 +1836,7 @@ namespace System.Reflection.Emit
else if (m_DocumentCount == m_Documents.Length)
{
// the arrays are full. Enlarge the arrays
- REDocument[] temp = new REDocument [m_DocumentCount * 2];
+ REDocument[] temp = new REDocument[m_DocumentCount * 2];
Array.Copy(m_Documents, 0, temp, 0, m_DocumentCount);
m_Documents = temp;
}
@@ -1788,10 +1848,10 @@ namespace System.Reflection.Emit
m_Documents[i].EmitLineNumberInfo(symWriter);
}
- private int m_DocumentCount; // how many documents that we have right now
+ private int m_DocumentCount; // how many documents that we have right now
private REDocument[] m_Documents; // array of documents
- private const int InitialSize = 16;
- private int m_iLastFound;
+ private const int InitialSize = 16;
+ private int m_iLastFound;
}
@@ -1811,17 +1871,17 @@ namespace System.Reflection.Emit
internal void AddLineNumberInfo(
ISymbolDocumentWriter document,
- int iOffset,
- int iStartLine,
- int iStartColumn,
- int iEndLine,
- int iEndColumn)
+ int iOffset,
+ int iStartLine,
+ int iStartColumn,
+ int iEndLine,
+ int iEndColumn)
{
Debug.Assert(document == m_document, "Bad document look up!");
-
+
// make sure that arrays are large enough to hold addition info
EnsureCapacity();
-
+
m_iOffsets[m_iLineNumberCount] = iOffset;
m_iLines[m_iLineNumberCount] = iStartLine;
m_iColumns[m_iLineNumberCount] = iStartColumn;
@@ -1847,27 +1907,27 @@ namespace System.Reflection.Emit
m_iEndColumns = new int[InitialSize];
}
else if (m_iLineNumberCount == m_iOffsets.Length)
- {
+ {
// the arrays are full. Enlarge the arrays
// It would probably be simpler to just use Lists here
int newSize = checked(m_iLineNumberCount * 2);
- int[] temp = new int [newSize];
+ int[] temp = new int[newSize];
Array.Copy(m_iOffsets, 0, temp, 0, m_iLineNumberCount);
m_iOffsets = temp;
- temp = new int [newSize];
+ temp = new int[newSize];
Array.Copy(m_iLines, 0, temp, 0, m_iLineNumberCount);
m_iLines = temp;
- temp = new int [newSize];
+ temp = new int[newSize];
Array.Copy(m_iColumns, 0, temp, 0, m_iLineNumberCount);
m_iColumns = temp;
- temp = new int [newSize];
+ temp = new int[newSize];
Array.Copy(m_iEndLines, 0, temp, 0, m_iLineNumberCount);
m_iEndLines = temp;
- temp = new int [newSize];
+ temp = new int[newSize];
Array.Copy(m_iEndColumns, 0, temp, 0, m_iLineNumberCount);
m_iEndColumns = temp;
}
@@ -1875,40 +1935,40 @@ namespace System.Reflection.Emit
internal void EmitLineNumberInfo(ISymbolWriter symWriter)
{
- int[] iOffsetsTemp;
- int[] iLinesTemp;
- int[] iColumnsTemp;
- int[] iEndLinesTemp;
- int[] iEndColumnsTemp;
+ int[] iOffsetsTemp;
+ int[] iLinesTemp;
+ int[] iColumnsTemp;
+ int[] iEndLinesTemp;
+ int[] iEndColumnsTemp;
if (m_iLineNumberCount == 0)
return;
// reduce the array size to be exact
- iOffsetsTemp = new int [m_iLineNumberCount];
+ iOffsetsTemp = new int[m_iLineNumberCount];
Array.Copy(m_iOffsets, 0, iOffsetsTemp, 0, m_iLineNumberCount);
- iLinesTemp = new int [m_iLineNumberCount];
+ iLinesTemp = new int[m_iLineNumberCount];
Array.Copy(m_iLines, 0, iLinesTemp, 0, m_iLineNumberCount);
- iColumnsTemp = new int [m_iLineNumberCount];
+ iColumnsTemp = new int[m_iLineNumberCount];
Array.Copy(m_iColumns, 0, iColumnsTemp, 0, m_iLineNumberCount);
- iEndLinesTemp = new int [m_iLineNumberCount];
+ iEndLinesTemp = new int[m_iLineNumberCount];
Array.Copy(m_iEndLines, 0, iEndLinesTemp, 0, m_iLineNumberCount);
- iEndColumnsTemp = new int [m_iLineNumberCount];
+ iEndColumnsTemp = new int[m_iLineNumberCount];
Array.Copy(m_iEndColumns, 0, iEndColumnsTemp, 0, m_iLineNumberCount);
- symWriter.DefineSequencePoints(m_document, iOffsetsTemp, iLinesTemp, iColumnsTemp, iEndLinesTemp, iEndColumnsTemp);
+ symWriter.DefineSequencePoints(m_document, iOffsetsTemp, iLinesTemp, iColumnsTemp, iEndLinesTemp, iEndColumnsTemp);
}
- private int[] m_iOffsets; // array of offsets
- private int[] m_iLines; // array of offsets
- private int[] m_iColumns; // array of offsets
- private int[] m_iEndLines; // array of offsets
- private int[] m_iEndColumns; // array of offsets
+ private int[] m_iOffsets; // array of offsets
+ private int[] m_iLines; // array of offsets
+ private int[] m_iColumns; // array of offsets
+ private int[] m_iEndLines; // array of offsets
+ private int[] m_iEndColumns; // array of offsets
internal ISymbolDocumentWriter m_document; // The ISymbolDocumentWriter that this REDocument is tracking.
- private int m_iLineNumberCount; // how many entries in the arrays are occupied
- private const int InitialSize = 16;
+ private int m_iLineNumberCount; // how many entries in the arrays are occupied
+ private const int InitialSize = 16;
} // end of REDocument
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/ISymWrapperCore.cs b/src/mscorlib/src/System/Reflection/Emit/ISymWrapperCore.cs
index e6f4622f0e..cda651c9ce 100644
--- a/src/mscorlib/src/System/Reflection/Emit/ISymWrapperCore.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/ISymWrapperCore.cs
@@ -2,14 +2,14 @@
// 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.Security;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.SymbolStore;
+
namespace System.Reflection.Emit
{
- using System;
- using System.Security;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Diagnostics.SymbolStore;
-
//-----------------------------------------------------------------------------------
// On Telesto, we don't ship the ISymWrapper.dll assembly. However, ReflectionEmit
// relies on that assembly to write out managed PDBs.
@@ -31,7 +31,7 @@ namespace System.Reflection.Emit
// SymWrapperCore is never instantiated and is used as an encapsulation class.
// It is our "ISymWrapper.dll" assembly within an assembly.
//------------------------------------------------------------------------------
- class SymWrapperCore
+ internal class SymWrapperCore
{
//------------------------------------------------------------------------------
// Block instantiation
@@ -49,7 +49,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
private unsafe class SymDocumentWriter : ISymbolDocumentWriter
{
-
//------------------------------------------------------------------------------
// Ctor
//------------------------------------------------------------------------------
@@ -57,10 +56,10 @@ namespace System.Reflection.Emit
{
m_pDocumentWriterSafeHandle = pDocumentWriterSafeHandle;
// The handle is actually a pointer to a native ISymUnmanagedDocumentWriter.
- m_pDocWriter = (ISymUnmanagedDocumentWriter *)m_pDocumentWriterSafeHandle.DangerousGetHandle();
+ m_pDocWriter = (ISymUnmanagedDocumentWriter*)m_pDocumentWriterSafeHandle.DangerousGetHandle();
m_vtable = (ISymUnmanagedDocumentWriterVTable)(Marshal.PtrToStructure(m_pDocWriter->m_unmanagedVTable, typeof(ISymUnmanagedDocumentWriterVTable)));
}
-
+
//------------------------------------------------------------------------------
// Returns the underlying ISymUnmanagedDocumentWriter* (as a safehandle.)
//------------------------------------------------------------------------------
@@ -68,7 +67,7 @@ namespace System.Reflection.Emit
{
return m_pDocumentWriterSafeHandle;
}
-
+
//=========================================================================================
// Public interface methods start here. (Well actually, they're all NotSupported
@@ -82,11 +81,11 @@ namespace System.Reflection.Emit
{
throw new NotSupportedException(); // Intentionally not supported to match desktop CLR
}
-
+
//------------------------------------------------------------------------------
// SetCheckSum() wrapper
//------------------------------------------------------------------------------
- void ISymbolDocumentWriter.SetCheckSum(Guid algorithmId, byte [] checkSum)
+ void ISymbolDocumentWriter.SetCheckSum(Guid algorithmId, byte[] checkSum)
{
int hr = m_vtable.SetCheckSum(m_pDocWriter, algorithmId, (uint)checkSum.Length, checkSum);
if (hr < 0)
@@ -94,8 +93,8 @@ namespace System.Reflection.Emit
throw Marshal.GetExceptionForHR(hr);
}
}
-
- private delegate int DSetCheckSum(ISymUnmanagedDocumentWriter * pThis, Guid algorithmId, uint checkSumSize, [In] byte[] checkSum);
+
+ private delegate int DSetCheckSum(ISymUnmanagedDocumentWriter* pThis, Guid algorithmId, uint checkSumSize, [In] byte[] checkSum);
//------------------------------------------------------------------------------
// This layout must match the unmanaged ISymUnmanagedDocumentWriter* COM vtable
@@ -105,14 +104,14 @@ namespace System.Reflection.Emit
[StructLayout(LayoutKind.Sequential)]
private struct ISymUnmanagedDocumentWriterVTable
{
- internal IntPtr QueryInterface;
- internal IntPtr AddRef;
- internal IntPtr Release;
+ internal IntPtr QueryInterface;
+ internal IntPtr AddRef;
+ internal IntPtr Release;
- internal IntPtr SetSource;
- internal DSetCheckSum SetCheckSum;
+ internal IntPtr SetSource;
+ internal DSetCheckSum SetCheckSum;
}
-
+
//------------------------------------------------------------------------------
// This layout must match the (start) of the unmanaged ISymUnmanagedDocumentWriter
// COM object.
@@ -128,15 +127,13 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
private PunkSafeHandle m_pDocumentWriterSafeHandle;
- private ISymUnmanagedDocumentWriter * m_pDocWriter;
+ private ISymUnmanagedDocumentWriter* m_pDocWriter;
//------------------------------------------------------------------------------
// Stores the "managed vtable" (actually a structure full of delegates that
// P/Invoke to the corresponding unmanaged COM methods.)
//------------------------------------------------------------------------------
private ISymUnmanagedDocumentWriterVTable m_vtable;
-
-
} // class SymDocumentWriter
@@ -146,8 +143,6 @@ namespace System.Reflection.Emit
//------------------------------------------------------------------------------
internal unsafe class SymWriter : ISymbolWriter
{
-
-
//------------------------------------------------------------------------------
// Creates a SymWriter. The SymWriter is a managed wrapper around the unmanaged
// symbol writer provided by the runtime (ildbsymlib or diasymreader.dll).
@@ -166,7 +161,7 @@ namespace System.Reflection.Emit
private SymWriter()
{
}
-
+
//------------------------------------------------------------------------------
// DefineDocument() wrapper
//------------------------------------------------------------------------------
@@ -188,7 +183,7 @@ namespace System.Reflection.Emit
}
return new SymDocumentWriter(psymUnmanagedDocumentWriter);
}
-
+
//------------------------------------------------------------------------------
// OpenMethod() wrapper
//------------------------------------------------------------------------------
@@ -200,7 +195,7 @@ namespace System.Reflection.Emit
throw Marshal.GetExceptionForHR(hr);
}
}
-
+
//------------------------------------------------------------------------------
// CloseMethod() wrapper
//------------------------------------------------------------------------------
@@ -212,7 +207,7 @@ namespace System.Reflection.Emit
throw Marshal.GetExceptionForHR(hr);
}
}
-
+
//------------------------------------------------------------------------------
// DefineSequencePoints() wrapper
//------------------------------------------------------------------------------
@@ -248,11 +243,11 @@ namespace System.Reflection.Emit
{
return;
}
- if ( (offsets != null && offsets.Length != spCount) ||
- (lines != null && lines.Length != spCount) ||
+ if ((offsets != null && offsets.Length != spCount) ||
+ (lines != null && lines.Length != spCount) ||
(columns != null && columns.Length != spCount) ||
(endLines != null && endLines.Length != spCount) ||
- (endColumns != null && endColumns.Length != spCount) )
+ (endColumns != null && endColumns.Length != spCount))
{
throw new ArgumentException();
}
@@ -269,9 +264,8 @@ namespace System.Reflection.Emit
{
throw Marshal.GetExceptionForHR(hr);
}
-
}
-
+
//------------------------------------------------------------------------------
// OpenScope() wrapper
//------------------------------------------------------------------------------
@@ -285,7 +279,7 @@ namespace System.Reflection.Emit
}
return ret;
}
-
+
//------------------------------------------------------------------------------
// CloseScope() wrapper
//------------------------------------------------------------------------------
@@ -297,7 +291,7 @@ namespace System.Reflection.Emit
throw Marshal.GetExceptionForHR(hr);
}
}
-
+
//------------------------------------------------------------------------------
// DefineLocalVariable() wrapper
//------------------------------------------------------------------------------
@@ -339,7 +333,7 @@ namespace System.Reflection.Emit
throw Marshal.GetExceptionForHR(hr);
}
}
-
+
//------------------------------------------------------------------------------
// UsingNamespace() wrapper
//------------------------------------------------------------------------------
@@ -364,65 +358,65 @@ namespace System.Reflection.Emit
internal void InternalSetUnderlyingWriter(IntPtr ppUnderlyingWriter)
{
m_pWriter = *((ISymUnmanagedWriter**)ppUnderlyingWriter);
- m_vtable = (ISymUnmanagedWriterVTable) (Marshal.PtrToStructure(m_pWriter->m_unmanagedVTable, typeof(ISymUnmanagedWriterVTable)));
+ m_vtable = (ISymUnmanagedWriterVTable)(Marshal.PtrToStructure(m_pWriter->m_unmanagedVTable, typeof(ISymUnmanagedWriterVTable)));
}
//------------------------------------------------------------------------------
// Define delegates for the unmanaged COM methods we invoke.
//------------------------------------------------------------------------------
- private delegate int DInitialize(ISymUnmanagedWriter* pthis,
- IntPtr emitter, //IUnknown*
+ private delegate int DInitialize(ISymUnmanagedWriter* pthis,
+ IntPtr emitter, //IUnknown*
[MarshalAs(UnmanagedType.LPWStr)] String filename, //WCHAR*
- IntPtr pIStream, //IStream*
- [MarshalAs(UnmanagedType.Bool)] bool fFullBuild
+ IntPtr pIStream, //IStream*
+ [MarshalAs(UnmanagedType.Bool)] bool fFullBuild
);
- private delegate int DDefineDocument(ISymUnmanagedWriter* pthis,
+ private delegate int DDefineDocument(ISymUnmanagedWriter* pthis,
[MarshalAs(UnmanagedType.LPWStr)] String url,
- [In] ref Guid language,
- [In] ref Guid languageVender,
- [In] ref Guid documentType,
- [Out] out PunkSafeHandle ppsymUnmanagedDocumentWriter
+ [In] ref Guid language,
+ [In] ref Guid languageVender,
+ [In] ref Guid documentType,
+ [Out] out PunkSafeHandle ppsymUnmanagedDocumentWriter
);
-
+
private delegate int DSetUserEntryPoint(ISymUnmanagedWriter* pthis, int entryMethod);
private delegate int DOpenMethod(ISymUnmanagedWriter* pthis, int entryMethod);
private delegate int DCloseMethod(ISymUnmanagedWriter* pthis);
private delegate int DDefineSequencePoints(ISymUnmanagedWriter* pthis,
- PunkSafeHandle document,
- int spCount,
- [In] int[] offsets,
- [In] int[] lines,
- [In] int[] columns,
- [In] int[] endLines,
- [In] int[] endColumns);
+ PunkSafeHandle document,
+ int spCount,
+ [In] int[] offsets,
+ [In] int[] lines,
+ [In] int[] columns,
+ [In] int[] endLines,
+ [In] int[] endColumns);
private delegate int DOpenScope(ISymUnmanagedWriter* pthis, int startOffset, [Out] out int pretval);
private delegate int DCloseScope(ISymUnmanagedWriter* pthis, int endOffset);
private delegate int DSetScopeRange(ISymUnmanagedWriter* pthis, int scopeID, int startOffset, int endOffset);
- private delegate int DDefineLocalVariable(ISymUnmanagedWriter* pthis,
+ private delegate int DDefineLocalVariable(ISymUnmanagedWriter* pthis,
[MarshalAs(UnmanagedType.LPWStr)] String name,
- int attributes,
- int cSig,
- [In] byte[] signature,
- int addrKind,
- int addr1,
- int addr2,
- int addr3,
- int startOffset,
- int endOffset
+ int attributes,
+ int cSig,
+ [In] byte[] signature,
+ int addrKind,
+ int addr1,
+ int addr2,
+ int addr3,
+ int startOffset,
+ int endOffset
);
private delegate int DClose(ISymUnmanagedWriter* pthis);
- private delegate int DSetSymAttribute(ISymUnmanagedWriter* pthis,
- int parent,
+ private delegate int DSetSymAttribute(ISymUnmanagedWriter* pthis,
+ int parent,
[MarshalAs(UnmanagedType.LPWStr)] String name,
- int cData,
- [In] byte[] data
+ int cData,
+ [In] byte[] data
);
@@ -440,38 +434,37 @@ namespace System.Reflection.Emit
[StructLayout(LayoutKind.Sequential)]
private struct ISymUnmanagedWriterVTable
{
- internal IntPtr QueryInterface;
- internal IntPtr AddRef;
- internal IntPtr Release;
+ internal IntPtr QueryInterface;
+ internal IntPtr AddRef;
+ internal IntPtr Release;
- internal DDefineDocument DefineDocument;
- internal DSetUserEntryPoint SetUserEntryPoint;
+ internal DDefineDocument DefineDocument;
+ internal DSetUserEntryPoint SetUserEntryPoint;
- internal DOpenMethod OpenMethod;
- internal DCloseMethod CloseMethod;
+ internal DOpenMethod OpenMethod;
+ internal DCloseMethod CloseMethod;
- internal DOpenScope OpenScope;
- internal DCloseScope CloseScope;
+ internal DOpenScope OpenScope;
+ internal DCloseScope CloseScope;
- internal DSetScopeRange SetScopeRange;
+ internal DSetScopeRange SetScopeRange;
- internal DDefineLocalVariable DefineLocalVariable;
- internal IntPtr DefineParameter;
- internal IntPtr DefineField;
- internal IntPtr DefineGlobalVariable;
+ internal DDefineLocalVariable DefineLocalVariable;
+ internal IntPtr DefineParameter;
+ internal IntPtr DefineField;
+ internal IntPtr DefineGlobalVariable;
- internal DClose Close;
- internal DSetSymAttribute SetSymAttribute;
+ internal DClose Close;
+ internal DSetSymAttribute SetSymAttribute;
- internal DOpenNamespace OpenNamespace;
- internal DCloseNamespace CloseNamespace;
- internal DUsingNamespace UsingNamespace;
+ internal DOpenNamespace OpenNamespace;
+ internal DCloseNamespace CloseNamespace;
+ internal DUsingNamespace UsingNamespace;
- internal IntPtr SetMethodSourceRange;
- internal DInitialize Initialize;
- internal IntPtr GetDebugInfo;
+ internal IntPtr SetMethodSourceRange;
+ internal DInitialize Initialize;
+ internal IntPtr GetDebugInfo;
internal DDefineSequencePoints DefineSequencePoints;
-
}
//------------------------------------------------------------------------------
@@ -490,19 +483,14 @@ namespace System.Reflection.Emit
// As with the real ISymWrapper.dll, ISymWrapper performs *no* Release (or AddRef) on this pointer.
// Managing lifetime is up to the caller (coreclr.dll).
//------------------------------------------------------------------------------
- private ISymUnmanagedWriter *m_pWriter;
+ private ISymUnmanagedWriter* m_pWriter;
//------------------------------------------------------------------------------
// Stores the "managed vtable" (actually a structure full of delegates that
// P/Invoke to the corresponding unmanaged COM methods.)
//------------------------------------------------------------------------------
private ISymUnmanagedWriterVTable m_vtable;
-
} // class SymWriter
-
-
-
-
} //class SymWrapperCore
@@ -518,7 +506,7 @@ namespace System.Reflection.Emit
//
// Had to make this a non-nested class since FCall's don't like to bind to nested classes.
//--------------------------------------------------------------------------------------
- sealed class PunkSafeHandle : SafeHandle
+ internal sealed class PunkSafeHandle : SafeHandle
{
internal PunkSafeHandle()
: base((IntPtr)0, true)
diff --git a/src/mscorlib/src/System/Reflection/Emit/Label.cs b/src/mscorlib/src/System/Reflection/Emit/Label.cs
index c7b987ff10..f6315a67d2 100644
--- a/src/mscorlib/src/System/Reflection/Emit/Label.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/Label.cs
@@ -13,11 +13,13 @@
**
**
===========================================================*/
-namespace System.Reflection.Emit {
- using System;
- using System.Reflection;
- using System.Runtime.InteropServices;
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+namespace System.Reflection.Emit
+{
// The Label class is an opaque representation of a label used by the
// ILGenerator class. The token is used to mark where labels occur in the IL
// stream and then the necessary offsets are put back in the code when the ILGenerator
@@ -25,27 +27,29 @@ namespace System.Reflection.Emit {
// Labels are created by using ILGenerator.CreateLabel and their position is set
// by using ILGenerator.MarkLabel.
[Serializable]
- public struct Label {
-
+ public struct Label
+ {
internal int m_label;
-
+
//public Label() {
// m_label=0;
//}
-
- internal Label (int label) {
- m_label=label;
+
+ internal Label(int label)
+ {
+ m_label = label;
}
-
- internal int GetLabelValue() {
+
+ internal int GetLabelValue()
+ {
return m_label;
}
-
+
public override int GetHashCode()
{
return m_label;
}
-
+
public override bool Equals(Object obj)
{
if (obj is Label)
@@ -53,17 +57,17 @@ namespace System.Reflection.Emit {
else
return false;
}
-
+
public bool Equals(Label obj)
{
return obj.m_label == m_label;
}
-
+
public static bool operator ==(Label a, Label b)
{
return a.Equals(b);
}
-
+
public static bool operator !=(Label a, Label b)
{
return !(a == b);
diff --git a/src/mscorlib/src/System/Reflection/Emit/LocalBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/LocalBuilder.cs
index fe4c33160a..c04c3c8434 100644
--- a/src/mscorlib/src/System/Reflection/Emit/LocalBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/LocalBuilder.cs
@@ -6,10 +6,10 @@ using System;
using System.Reflection;
using System.Runtime.InteropServices;
-namespace System.Reflection.Emit
+namespace System.Reflection.Emit
{
public sealed class LocalBuilder : LocalVariableInfo
- {
+ {
#region Private Data Members
private int m_localIndex;
private Type m_localType;
@@ -19,9 +19,9 @@ namespace System.Reflection.Emit
#region Constructor
private LocalBuilder() { }
- internal LocalBuilder(int localIndex, Type localType, MethodInfo methodBuilder)
+ internal LocalBuilder(int localIndex, Type localType, MethodInfo methodBuilder)
: this(localIndex, localType, methodBuilder, false) { }
- internal LocalBuilder(int localIndex, Type localType, MethodInfo methodBuilder, bool isPinned)
+ internal LocalBuilder(int localIndex, Type localType, MethodInfo methodBuilder, bool isPinned)
{
m_isPinned = isPinned;
m_localIndex = localIndex;
@@ -31,11 +31,11 @@ namespace System.Reflection.Emit
#endregion
#region Internal Members
- internal int GetLocalIndex()
+ internal int GetLocalIndex()
{
return m_localIndex;
}
- internal MethodInfo GetMethodBuilder()
+ internal MethodInfo GetMethodBuilder()
{
return m_methodBuilder;
}
@@ -43,13 +43,13 @@ namespace System.Reflection.Emit
#region LocalVariableInfo Override
public override bool IsPinned { get { return m_isPinned; } }
- public override Type LocalType
+ public override Type LocalType
{
- get
- {
- return m_localType;
+ get
+ {
+ return m_localType;
}
- }
+ }
public override int LocalIndex { get { return m_localIndex; } }
#endregion
@@ -57,7 +57,7 @@ namespace System.Reflection.Emit
public void SetLocalSymInfo(String name)
{
SetLocalSymInfo(name, 0, 0);
- }
+ }
public void SetLocalSymInfo(String name, int startOffset, int endOffset)
{
@@ -69,27 +69,27 @@ namespace System.Reflection.Emit
int index;
MethodBuilder methodBuilder = m_methodBuilder as MethodBuilder;
- if (methodBuilder == null)
+ if (methodBuilder == null)
// it's a light code gen entity
throw new NotSupportedException();
- dynMod = (ModuleBuilder) methodBuilder.Module;
+ dynMod = (ModuleBuilder)methodBuilder.Module;
if (methodBuilder.IsTypeCreated())
{
// cannot change method after its containing type has been created
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TypeHasBeenCreated"));
+ throw new InvalidOperationException(SR.InvalidOperation_TypeHasBeenCreated);
}
-
+
// set the name and range of offset for the local
if (dynMod.GetSymWriter() == null)
{
// cannot set local name if not debug module
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule"));
+ throw new InvalidOperationException(SR.InvalidOperation_NotADebugModule);
}
-
+
sigHelp = SignatureHelper.GetFieldSigHelper(dynMod);
sigHelp.AddArgument(m_localType);
signature = sigHelp.InternalGetSignature(out sigLength);
-
+
// The symbol store doesn't want the calling convention on the
// front of the signature, but InternalGetSignature returns
// the callinging convention. So we strip it off. This is a
@@ -97,7 +97,7 @@ namespace System.Reflection.Emit
// yet another array of bytes...
mungedSig = new byte[sigLength - 1];
Buffer.BlockCopy(signature, 1, mungedSig, 0, sigLength - 1);
-
+
index = methodBuilder.GetILGenerator().m_ScopeTree.GetCurrentActiveScopeIndex();
if (index == -1)
{
@@ -105,7 +105,7 @@ namespace System.Reflection.Emit
methodBuilder.m_localSymInfo.AddLocalSymInfo(
name,
mungedSig,
- m_localIndex,
+ m_localIndex,
startOffset,
endOffset);
}
@@ -114,7 +114,7 @@ namespace System.Reflection.Emit
methodBuilder.GetILGenerator().m_ScopeTree.AddLocalSymInfoToCurrentScope(
name,
mungedSig,
- m_localIndex,
+ m_localIndex,
startOffset,
endOffset);
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/MethodBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/MethodBuilder.cs
index 17c8ce074d..530a5ee092 100644
--- a/src/mscorlib/src/System/Reflection/Emit/MethodBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/MethodBuilder.cs
@@ -4,7 +4,7 @@
//
-namespace System.Reflection.Emit
+namespace System.Reflection.Emit
{
using System.Text;
using System;
@@ -35,7 +35,7 @@ namespace System.Reflection.Emit
private byte[] m_ubBody; // The IL for the method
private ExceptionHandler[] m_exceptions; // Exception handlers or null if there are none.
private const int DefaultMaxStack = 16;
- private int m_maxStack = DefaultMaxStack;
+ private int m_maxStack = DefaultMaxStack;
// Flags
internal bool m_bIsBaked;
@@ -69,7 +69,7 @@ namespace System.Reflection.Emit
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers,
ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod)
{
- Init(name, attributes, callingConvention,
+ Init(name, attributes, callingConvention,
returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers,
mod, type, bIsGlobalMethod);
@@ -77,17 +77,17 @@ namespace System.Reflection.Emit
private void Init(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
- Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers,
+ Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers,
ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod)
{
if (name == null)
throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
if (name[0] == '\0')
- throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), nameof(name));
+ throw new ArgumentException(SR.Argument_IllegalName, nameof(name));
if (mod == null)
throw new ArgumentNullException(nameof(mod));
@@ -95,7 +95,7 @@ namespace System.Reflection.Emit
if (parameterTypes != null)
{
- foreach(Type t in parameterTypes)
+ foreach (Type t in parameterTypes)
{
if (t == null)
throw new ArgumentNullException(nameof(parameterTypes));
@@ -124,7 +124,7 @@ namespace System.Reflection.Emit
else if ((attributes & MethodAttributes.Virtual) != 0)
{
// A method can't be both static and virtual
- throw new ArgumentException(Environment.GetResourceString("Arg_NoStaticVirtual"));
+ throw new ArgumentException(SR.Arg_NoStaticVirtual);
}
if ((attributes & MethodAttributes.SpecialName) != MethodAttributes.SpecialName)
@@ -132,10 +132,10 @@ namespace System.Reflection.Emit
if ((type.Attributes & TypeAttributes.Interface) == TypeAttributes.Interface)
{
// methods on interface have to be abstract + virtual except special name methods such as type initializer
- if ((attributes & (MethodAttributes.Abstract | MethodAttributes.Virtual)) !=
- (MethodAttributes.Abstract | MethodAttributes.Virtual) &&
+ if ((attributes & (MethodAttributes.Abstract | MethodAttributes.Virtual)) !=
+ (MethodAttributes.Abstract | MethodAttributes.Virtual) &&
(attributes & MethodAttributes.Static) == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_BadAttributeOnInterfaceMethod"));
+ throw new ArgumentException(SR.Argument_BadAttributeOnInterfaceMethod);
}
}
@@ -156,9 +156,9 @@ namespace System.Reflection.Emit
m_parameterTypeRequiredCustomModifiers = parameterTypeRequiredCustomModifiers;
m_parameterTypeOptionalCustomModifiers = parameterTypeOptionalCustomModifiers;
-// m_signature = SignatureHelper.GetMethodSigHelper(mod, callingConvention,
-// returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
-// parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
+ // m_signature = SignatureHelper.GetMethodSigHelper(mod, callingConvention,
+ // returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
+ // parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
m_iAttributes = attributes;
m_bIsGlobalMethod = bIsGlobalMethod;
@@ -179,9 +179,9 @@ namespace System.Reflection.Emit
internal void CheckContext(params Type[][] typess)
{
- m_module.CheckContext(typess);
+ m_module.CheckContext(typess);
}
-
+
internal void CheckContext(params Type[] types)
{
m_module.CheckContext(types);
@@ -197,22 +197,22 @@ namespace System.Reflection.Emit
}
Contract.EndContractBlock();
- __ExceptionInfo[] excp;
- int counter=0;
- int[] filterAddrs;
- int[] catchAddrs;
- int[] catchEndAddrs;
- Type[] catchClass;
- int[] type;
- int numCatch;
- int start, end;
- ModuleBuilder dynMod = (ModuleBuilder) m_module;
+ __ExceptionInfo[] excp;
+ int counter = 0;
+ int[] filterAddrs;
+ int[] catchAddrs;
+ int[] catchEndAddrs;
+ Type[] catchClass;
+ int[] type;
+ int numCatch;
+ int start, end;
+ ModuleBuilder dynMod = (ModuleBuilder)m_module;
m_containingType.ThrowIfCreated();
if (m_bIsBaked)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodHasBody"));
+ throw new InvalidOperationException(SR.InvalidOperation_MethodHasBody);
}
if (il.m_methodBuilder != this && il.m_methodBuilder != null)
@@ -221,15 +221,15 @@ namespace System.Reflection.Emit
// through MethodBuilder::GetILGenerator.
//
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadILGeneratorUsage"));
+ throw new InvalidOperationException(SR.InvalidOperation_BadILGeneratorUsage);
}
-
+
ThrowIfShouldNotHaveBody();
if (il.m_ScopeTree.m_iOpenScopeCount != 0)
{
// There are still unclosed local scope
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_OpenLocalVariableScope"));
+ throw new InvalidOperationException(SR.InvalidOperation_OpenLocalVariableScope);
}
@@ -276,20 +276,18 @@ namespace System.Reflection.Emit
break;
}
}
-
}
}
- m_bIsBaked=true;
+ m_bIsBaked = true;
if (dynMod.GetSymWriter() != null)
{
-
// set the debugging information such as scope and line number
// if it is in a debug module
//
- SymbolToken tk = new SymbolToken(MetadataTokenInternal);
+ SymbolToken tk = new SymbolToken(MetadataTokenInternal);
ISymbolWriter symWriter = dynMod.GetSymWriter();
// call OpenMethod to make this method the current method
@@ -299,16 +297,16 @@ namespace System.Reflection.Emit
// the top-levelsmethod scope
//
symWriter.OpenScope(0);
-
+
if (m_symCustomAttrs != null)
{
- foreach(SymCustomAttr symCustomAttr in m_symCustomAttrs)
+ foreach (SymCustomAttr symCustomAttr in m_symCustomAttrs)
dynMod.GetSymWriter().SetSymAttribute(
- new SymbolToken (MetadataTokenInternal),
- symCustomAttr.m_name,
+ new SymbolToken(MetadataTokenInternal),
+ symCustomAttr.m_name,
symCustomAttr.m_data);
}
-
+
if (m_localSymInfo != null)
m_localSymInfo.EmitLocalSymInfo(symWriter);
il.m_ScopeTree.EmitScopeTree(symWriter);
@@ -330,14 +328,14 @@ namespace System.Reflection.Emit
m_ubBody = null;
m_localSymInfo = null;
m_mdMethodFixups = null;
- m_localSignature = null;
+ m_localSignature = null;
m_exceptions = null;
}
internal override Type[] GetParameterTypes()
{
if (m_parameterTypes == null)
- m_parameterTypes = EmptyArray<Type>.Value;
+ m_parameterTypes = Array.Empty<Type>();
return m_parameterTypes;
}
@@ -347,11 +345,11 @@ namespace System.Reflection.Emit
MethodInfo mi = null;
ConstructorInfo ci = null;
- if ( (mi = method as MethodInfo) != null )
+ if ((mi = method as MethodInfo) != null)
{
return mi.ReturnType;
}
- else if ( (ci = method as ConstructorInfo) != null)
+ else if ((ci = method as ConstructorInfo) != null)
{
return ci.GetReturnType();
}
@@ -377,9 +375,9 @@ namespace System.Reflection.Emit
internal SignatureHelper GetMethodSignature()
{
if (m_parameterTypes == null)
- m_parameterTypes = EmptyArray<Type>.Value;
+ m_parameterTypes = Array.Empty<Type>();
- m_signature = SignatureHelper.GetMethodSigHelper (m_module, m_callingConvention, m_inst != null ? m_inst.Length : 0,
+ m_signature = SignatureHelper.GetMethodSigHelper(m_module, m_callingConvention, m_inst != null ? m_inst.Length : 0,
m_returnType == null ? typeof(void) : m_returnType, m_returnTypeRequiredCustomModifiers, m_returnTypeOptionalCustomModifiers,
m_parameterTypes, m_parameterTypeRequiredCustomModifiers, m_parameterTypeOptionalCustomModifiers);
@@ -394,7 +392,7 @@ namespace System.Reflection.Emit
signatureLength = m_localSignature.Length;
return m_localSignature;
}
-
+
if (m_ilGenerator != null)
{
if (m_ilGenerator.m_localCount != 0)
@@ -432,28 +430,28 @@ namespace System.Reflection.Emit
internal int CalculateNumberOfExceptions(__ExceptionInfo[] excp)
{
- int num=0;
+ int num = 0;
- if (excp==null)
+ if (excp == null)
{
return 0;
}
- for (int i=0; i<excp.Length; i++)
+ for (int i = 0; i < excp.Length; i++)
{
- num+=excp[i].GetNumberOfCatches();
+ num += excp[i].GetNumberOfCatches();
}
return num;
}
internal bool IsTypeCreated()
- {
- return (m_containingType != null && m_containingType.IsCreated());
+ {
+ return (m_containingType != null && m_containingType.IsCreated());
}
internal TypeBuilder GetTypeBuilder()
- {
+ {
return m_containingType;
}
@@ -464,20 +462,25 @@ namespace System.Reflection.Emit
#endregion
#region Object Overrides
- public override bool Equals(Object obj) {
- if (!(obj is MethodBuilder)) {
+ public override bool Equals(Object obj)
+ {
+ if (!(obj is MethodBuilder))
+ {
return false;
}
- if (!(this.m_strName.Equals(((MethodBuilder)obj).m_strName))) {
+ if (!(this.m_strName.Equals(((MethodBuilder)obj).m_strName)))
+ {
return false;
}
- if (m_iAttributes!=(((MethodBuilder)obj).m_iAttributes)) {
+ if (m_iAttributes != (((MethodBuilder)obj).m_iAttributes))
+ {
return false;
}
SignatureHelper thatSig = ((MethodBuilder)obj).GetMethodSignature();
- if (thatSig.Equals(GetMethodSignature())) {
+ if (thatSig.Equals(GetMethodSignature()))
+ {
return true;
}
return false;
@@ -503,15 +506,15 @@ namespace System.Reflection.Emit
#region MemberInfo Overrides
public override String Name
{
- get
- {
- return m_strName;
+ get
+ {
+ return m_strName;
}
}
internal int MetadataTokenInternal
{
- get
+ get
{
return GetToken().Token;
}
@@ -519,7 +522,7 @@ namespace System.Reflection.Emit
public override Module Module
{
- get
+ get
{
return m_containingType.Module;
}
@@ -535,9 +538,9 @@ namespace System.Reflection.Emit
}
}
- public override ICustomAttributeProvider ReturnTypeCustomAttributes
+ public override ICustomAttributeProvider ReturnTypeCustomAttributes
{
- get
+ get
{
return null;
}
@@ -556,7 +559,7 @@ namespace System.Reflection.Emit
#region MethodBase Overrides
public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
public override MethodImplAttributes GetMethodImplementationFlags()
@@ -571,12 +574,12 @@ namespace System.Reflection.Emit
public override CallingConventions CallingConvention
{
- get {return m_callingConvention;}
+ get { return m_callingConvention; }
}
public override RuntimeMethodHandle MethodHandle
{
- get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); }
+ get { throw new NotSupportedException(SR.NotSupported_DynamicModule); }
}
public override bool IsSecurityCritical
@@ -613,7 +616,7 @@ namespace System.Reflection.Emit
public override ParameterInfo[] GetParameters()
{
if (!m_bIsBaked || m_containingType == null || m_containingType.BakedRuntimeType == null)
- throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_TypeNotCreated"));
+ throw new NotSupportedException(SR.InvalidOperation_TypeNotCreated);
MethodInfo rmi = m_containingType.GetMethod(m_strName, m_parameterTypes);
@@ -625,7 +628,7 @@ namespace System.Reflection.Emit
get
{
if (!m_bIsBaked || m_containingType == null || m_containingType.BakedRuntimeType == null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TypeNotCreated"));
+ throw new InvalidOperationException(SR.InvalidOperation_TypeNotCreated);
MethodInfo rmi = m_containingType.GetMethod(m_strName, m_parameterTypes);
@@ -637,20 +640,17 @@ namespace System.Reflection.Emit
#region ICustomAttributeProvider Implementation
public override Object[] GetCustomAttributes(bool inherit)
{
-
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
-
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
public override bool IsDefined(Type attributeType, bool inherit)
{
-
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
#endregion
@@ -663,43 +663,43 @@ namespace System.Reflection.Emit
public override MethodInfo GetGenericMethodDefinition() { if (!IsGenericMethod) throw new InvalidOperationException(); return this; }
public override bool IsGenericMethod { get { return m_inst != null; } }
-
+
public override Type[] GetGenericArguments() { return m_inst; }
- public override MethodInfo MakeGenericMethod(params Type[] typeArguments)
+ public override MethodInfo MakeGenericMethod(params Type[] typeArguments)
{
- return MethodBuilderInstantiation.MakeGenericMethod(this, typeArguments);
+ return MethodBuilderInstantiation.MakeGenericMethod(this, typeArguments);
}
-
-
- public GenericTypeParameterBuilder[] DefineGenericParameters (params string[] names)
+
+
+ public GenericTypeParameterBuilder[] DefineGenericParameters(params string[] names)
{
if (names == null)
throw new ArgumentNullException(nameof(names));
if (names.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_EmptyArray"), nameof(names));
+ throw new ArgumentException(SR.Arg_EmptyArray, nameof(names));
Contract.EndContractBlock();
if (m_inst != null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GenericParametersAlreadySet"));
+ throw new InvalidOperationException(SR.InvalidOperation_GenericParametersAlreadySet);
- for (int i = 0; i < names.Length; i ++)
+ for (int i = 0; i < names.Length; i++)
if (names[i] == null)
throw new ArgumentNullException(nameof(names));
if (m_tkMethod.Token != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodBuilderBaked"));
+ throw new InvalidOperationException(SR.InvalidOperation_MethodBuilderBaked);
m_bIsGenMethDef = true;
m_inst = new GenericTypeParameterBuilder[names.Length];
- for (int i = 0; i < names.Length; i ++)
+ for (int i = 0; i < names.Length; i++)
m_inst[i] = new GenericTypeParameterBuilder(new TypeBuilder(names[i], i, this));
return m_inst;
}
-
- internal void ThrowIfGeneric () { if (IsGenericMethod && !IsGenericMethodDefinition) throw new InvalidOperationException (); }
+
+ internal void ThrowIfGeneric() { if (IsGenericMethod && !IsGenericMethodDefinition) throw new InvalidOperationException(); }
#endregion
#region Public Members
@@ -773,22 +773,22 @@ namespace System.Reflection.Emit
return m_tkMethod;
}
- public void SetParameters (params Type[] parameterTypes)
+ public void SetParameters(params Type[] parameterTypes)
{
CheckContext(parameterTypes);
-
- SetSignature (null, null, null, parameterTypes, null, null);
+
+ SetSignature(null, null, null, parameterTypes, null, null);
}
- public void SetReturnType (Type returnType)
+ public void SetReturnType(Type returnType)
{
CheckContext(returnType);
-
- SetSignature (returnType, null, null, null, null, null);
+
+ SetSignature(returnType, null, null, null, null, null);
}
public void SetSignature(
- Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
+ Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
{
// We should throw InvalidOperation_MethodBuilderBaked here if the method signature has been baked.
@@ -800,7 +800,7 @@ namespace System.Reflection.Emit
CheckContext(returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes);
CheckContext(parameterTypeRequiredCustomModifiers);
CheckContext(parameterTypeOptionalCustomModifiers);
-
+
ThrowIfGeneric();
if (returnType != null)
@@ -811,7 +811,7 @@ namespace System.Reflection.Emit
if (parameterTypes != null)
{
m_parameterTypes = new Type[parameterTypes.Length];
- Array.Copy (parameterTypes, 0, m_parameterTypes, 0, parameterTypes.Length);
+ Array.Copy(parameterTypes, 0, m_parameterTypes, 0, parameterTypes.Length);
}
m_returnTypeRequiredCustomModifiers = returnTypeRequiredCustomModifiers;
@@ -820,18 +820,18 @@ namespace System.Reflection.Emit
m_parameterTypeOptionalCustomModifiers = parameterTypeOptionalCustomModifiers;
}
-
+
public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, String strParamName)
{
if (position < 0)
- throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_ParamSequence"));
+ throw new ArgumentOutOfRangeException(SR.ArgumentOutOfRange_ParamSequence);
Contract.EndContractBlock();
ThrowIfGeneric();
- m_containingType.ThrowIfCreated ();
+ m_containingType.ThrowIfCreated();
if (position > 0 && (m_parameterTypes == null || position > m_parameterTypes.Length))
- throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_ParamSequence"));
+ throw new ArgumentOutOfRangeException(SR.ArgumentOutOfRange_ParamSequence);
attributes = attributes & ~ParameterAttributes.ReservedMask;
return new ParameterBuilder(this, position, attributes, strParamName);
@@ -844,11 +844,11 @@ namespace System.Reflection.Emit
public byte[] m_data;
}
- public void SetImplementationFlags(MethodImplAttributes attributes)
+ public void SetImplementationFlags(MethodImplAttributes attributes)
{
- ThrowIfGeneric ();
+ ThrowIfGeneric();
- m_containingType.ThrowIfCreated ();
+ m_containingType.ThrowIfCreated();
m_dwMethodImplFlags = attributes;
@@ -857,7 +857,8 @@ namespace System.Reflection.Emit
TypeBuilder.SetMethodImpl(m_module.GetNativeHandle(), MetadataTokenInternal, attributes);
}
- public ILGenerator GetILGenerator() {
+ public ILGenerator GetILGenerator()
+ {
Contract.Ensures(Contract.Result<ILGenerator>() != null);
ThrowIfGeneric();
@@ -868,18 +869,20 @@ namespace System.Reflection.Emit
return m_ilGenerator;
}
- public ILGenerator GetILGenerator(int size) {
+ public ILGenerator GetILGenerator(int size)
+ {
Contract.Ensures(Contract.Result<ILGenerator>() != null);
- ThrowIfGeneric ();
+ ThrowIfGeneric();
ThrowIfShouldNotHaveBody();
-
+
if (m_ilGenerator == null)
m_ilGenerator = new ILGenerator(this, size);
return m_ilGenerator;
}
- private void ThrowIfShouldNotHaveBody() {
+ private void ThrowIfShouldNotHaveBody()
+ {
if ((m_dwMethodImplFlags & MethodImplAttributes.CodeTypeMask) != MethodImplAttributes.IL ||
(m_dwMethodImplFlags & MethodImplAttributes.Unmanaged) != 0 ||
(m_iAttributes & MethodAttributes.PinvokeImpl) != 0 ||
@@ -887,16 +890,16 @@ namespace System.Reflection.Emit
{
// cannot attach method body if methodimpl is marked not marked as managed IL
//
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ShouldNotHaveMethodBody"));
+ throw new InvalidOperationException(SR.InvalidOperation_ShouldNotHaveMethodBody);
}
}
-
- public bool InitLocals
- {
+
+ public bool InitLocals
+ {
// Property is set to true if user wishes to have zero initialized stack frame for this method. Default to false.
- get { ThrowIfGeneric (); return m_fInitLocals; }
- set { ThrowIfGeneric (); m_fInitLocals = value; }
+ get { ThrowIfGeneric(); return m_fInitLocals; }
+ set { ThrowIfGeneric(); m_fInitLocals = value; }
}
public Module GetModule()
@@ -904,12 +907,12 @@ namespace System.Reflection.Emit
return GetModuleBuilder();
}
- public String Signature
- {
- get
- {
- return GetMethodSignature().ToString();
- }
+ public String Signature
+ {
+ get
+ {
+ return GetMethodSignature().ToString();
+ }
}
@@ -941,7 +944,7 @@ namespace System.Reflection.Emit
ThrowIfGeneric();
customBuilder.CreateCustomAttribute((ModuleBuilder)m_module, MetadataTokenInternal);
-
+
if (IsKnownCA(customBuilder.m_con))
ParseCA(customBuilder.m_con, customBuilder.m_blob);
}
@@ -959,7 +962,7 @@ namespace System.Reflection.Emit
private void ParseCA(ConstructorInfo con, byte[] blob)
{
Type caType = con.DeclaringType;
- if (caType == typeof(System.Runtime.CompilerServices.MethodImplAttribute))
+ if (caType == typeof(System.Runtime.CompilerServices.MethodImplAttribute))
{
// dig through the blob looking for the MethodImplAttributes flag
// that must be in the MethodCodeType field
@@ -968,11 +971,11 @@ namespace System.Reflection.Emit
// allows this method to have no body when any kind of MethodImplAttribute is present
m_canBeRuntimeImpl = true;
}
- else if (caType == typeof(DllImportAttribute)) {
+ else if (caType == typeof(DllImportAttribute))
+ {
m_canBeRuntimeImpl = true;
m_isDllImport = true;
}
-
}
internal bool m_canBeRuntimeImpl = false;
@@ -987,15 +990,15 @@ namespace System.Reflection.Emit
// and namespace information with a given active lexical scope.
#region Internal Data Members
- internal String[] m_strName;
- internal byte[][] m_ubSignature;
- internal int[] m_iLocalSlot;
- internal int[] m_iStartOffset;
- internal int[] m_iEndOffset;
- internal int m_iLocalSymCount; // how many entries in the arrays are occupied
- internal String[] m_namespace;
- internal int m_iNameSpaceCount;
- internal const int InitialSize = 16;
+ internal String[] m_strName;
+ internal byte[][] m_ubSignature;
+ internal int[] m_iLocalSlot;
+ internal int[] m_iStartOffset;
+ internal int[] m_iEndOffset;
+ internal int m_iLocalSymCount; // how many entries in the arrays are occupied
+ internal String[] m_namespace;
+ internal int m_iNameSpaceCount;
+ internal const int InitialSize = 16;
#endregion
#region Constructor
@@ -1016,7 +1019,7 @@ namespace System.Reflection.Emit
}
else if (m_iNameSpaceCount == m_namespace.Length)
{
- String [] strTemp = new String [checked(m_iNameSpaceCount * 2)];
+ String[] strTemp = new String[checked(m_iNameSpaceCount * 2)];
Array.Copy(m_namespace, 0, strTemp, 0, m_iNameSpaceCount);
m_namespace = strTemp;
}
@@ -1038,33 +1041,32 @@ namespace System.Reflection.Emit
// the arrays are full. Enlarge the arrays
// why aren't we just using lists here?
int newSize = checked(m_iLocalSymCount * 2);
- int[] temp = new int [newSize];
+ int[] temp = new int[newSize];
Array.Copy(m_iLocalSlot, 0, temp, 0, m_iLocalSymCount);
m_iLocalSlot = temp;
- temp = new int [newSize];
+ temp = new int[newSize];
Array.Copy(m_iStartOffset, 0, temp, 0, m_iLocalSymCount);
m_iStartOffset = temp;
- temp = new int [newSize];
+ temp = new int[newSize];
Array.Copy(m_iEndOffset, 0, temp, 0, m_iLocalSymCount);
m_iEndOffset = temp;
- String [] strTemp = new String [newSize];
+ String[] strTemp = new String[newSize];
Array.Copy(m_strName, 0, strTemp, 0, m_iLocalSymCount);
m_strName = strTemp;
byte[][] ubTemp = new byte[newSize][];
Array.Copy(m_ubSignature, 0, ubTemp, 0, m_iLocalSymCount);
m_ubSignature = ubTemp;
-
}
}
#endregion
#region Internal Members
- internal void AddLocalSymInfo(String strName,byte[] signature,int slot,int startOffset,int endOffset)
+ internal void AddLocalSymInfo(String strName, byte[] signature, int slot, int startOffset, int endOffset)
{
// make sure that arrays are large enough to hold addition info
EnsureCapacity();
@@ -1073,7 +1075,7 @@ namespace System.Reflection.Emit
m_iLocalSlot[m_iLocalSymCount] = slot;
m_strName[m_iLocalSymCount] = strName;
m_ubSignature[m_iLocalSymCount] = signature;
- checked {m_iLocalSymCount++; }
+ checked { m_iLocalSymCount++; }
}
internal void AddUsingNamespace(String strNamespace)
@@ -1085,13 +1087,13 @@ namespace System.Reflection.Emit
internal virtual void EmitLocalSymInfo(ISymbolWriter symWriter)
{
- int i;
+ int i;
- for (i = 0; i < m_iLocalSymCount; i ++)
+ for (i = 0; i < m_iLocalSymCount; i++)
{
symWriter.DefineLocalVariable(
m_strName[i],
- FieldAttributes.PrivateScope,
+ FieldAttributes.PrivateScope,
m_ubSignature[i],
SymAddressKind.ILOffset,
m_iLocalSlot[i],
@@ -1100,7 +1102,7 @@ namespace System.Reflection.Emit
m_iStartOffset[i],
m_iEndOffset[i]);
}
- for (i = 0; i < m_iNameSpaceCount; i ++)
+ for (i = 0; i < m_iNameSpaceCount; i++)
{
symWriter.UsingNamespace(m_namespace[i]);
}
@@ -1124,7 +1126,7 @@ namespace System.Reflection.Emit
internal readonly int m_handlerEndOffset;
internal readonly ExceptionHandlingClauseOptions m_kind;
-#region Constructors
+ #region Constructors
internal ExceptionHandler(int tryStartOffset, int tryEndOffset, int filterOffset, int handlerStartOffset, int handlerEndOffset,
int kind, int exceptionTypeToken)
@@ -1160,7 +1162,7 @@ namespace System.Reflection.Emit
return false;
}
}
-
+
#endregion
#region Equality
@@ -1187,7 +1189,7 @@ namespace System.Reflection.Emit
other.m_kind == m_kind;
}
- public static bool operator ==(ExceptionHandler left, ExceptionHandler right)
+ public static bool operator ==(ExceptionHandler left, ExceptionHandler right)
{
return left.Equals(right);
}
@@ -1196,7 +1198,7 @@ namespace System.Reflection.Emit
{
return !left.Equals(right);
}
-
+
#endregion
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/MethodBuilderInstantiation.cs b/src/mscorlib/src/System/Reflection/Emit/MethodBuilderInstantiation.cs
index 57ad1665c0..2d0a9b41dd 100644
--- a/src/mscorlib/src/System/Reflection/Emit/MethodBuilderInstantiation.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/MethodBuilderInstantiation.cs
@@ -4,14 +4,14 @@
//
+using System;
+using System.Reflection;
+using System.Collections;
+using System.Globalization;
+using System.Diagnostics.Contracts;
+
namespace System.Reflection.Emit
{
- using System;
- using System.Reflection;
- using System.Collections;
- using System.Globalization;
- using System.Diagnostics.Contracts;
-
internal sealed class MethodBuilderInstantiation : MethodInfo
{
#region Static Members
@@ -38,18 +38,18 @@ namespace System.Reflection.Emit
m_inst = inst;
}
#endregion
-
+
internal override Type[] GetParameterTypes()
{
return m_method.GetParameterTypes();
}
#region MemberBase
- public override MemberTypes MemberType { get { return m_method.MemberType; } }
+ public override MemberTypes MemberType { get { return m_method.MemberType; } }
public override String Name { get { return m_method.Name; } }
- public override Type DeclaringType { get { return m_method.DeclaringType; } }
+ public override Type DeclaringType { get { return m_method.DeclaringType; } }
public override Type ReflectedType { get { return m_method.ReflectedType; } }
- public override Object[] GetCustomAttributes(bool inherit) { return m_method.GetCustomAttributes(inherit); }
+ public override Object[] GetCustomAttributes(bool inherit) { return m_method.GetCustomAttributes(inherit); }
public override Object[] GetCustomAttributes(Type attributeType, bool inherit) { return m_method.GetCustomAttributes(attributeType, inherit); }
public override bool IsDefined(Type attributeType, bool inherit) { return m_method.IsDefined(attributeType, inherit); }
public override Module Module { get { return m_method.Module; } }
@@ -57,9 +57,9 @@ namespace System.Reflection.Emit
#region MethodBase Members
[Pure]
- public override ParameterInfo[] GetParameters() { throw new NotSupportedException(); }
+ public override ParameterInfo[] GetParameters() { throw new NotSupportedException(); }
public override MethodImplAttributes GetMethodImplementationFlags() { return m_method.GetMethodImplementationFlags(); }
- public override RuntimeMethodHandle MethodHandle { get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); } }
+ public override RuntimeMethodHandle MethodHandle { get { throw new NotSupportedException(SR.NotSupported_DynamicModule); } }
public override MethodAttributes Attributes { get { return m_method.Attributes; } }
public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
{
@@ -88,11 +88,11 @@ namespace System.Reflection.Emit
public override MethodInfo MakeGenericMethod(params Type[] arguments)
{
- throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericMethodDefinition"));
+ throw new InvalidOperationException(SR.Arg_NotGenericMethodDefinition);
}
public override bool IsGenericMethod { get { return true; } }
-
+
#endregion
#region Public Abstract\Virtual Members
diff --git a/src/mscorlib/src/System/Reflection/Emit/MethodToken.cs b/src/mscorlib/src/System/Reflection/Emit/MethodToken.cs
index 76b7279f30..0905ac922a 100644
--- a/src/mscorlib/src/System/Reflection/Emit/MethodToken.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/MethodToken.cs
@@ -12,25 +12,28 @@
**
**
===========================================================*/
-namespace System.Reflection.Emit {
-
- using System;
- using System.Reflection;
+using System;
+using System.Reflection;
+
+namespace System.Reflection.Emit
+{
[Serializable]
public struct MethodToken
{
public static readonly MethodToken Empty = new MethodToken();
internal int m_method;
-
- internal MethodToken(int str) {
- m_method=str;
+
+ internal MethodToken(int str)
+ {
+ m_method = str;
}
-
- public int Token {
+
+ public int Token
+ {
get { return m_method; }
}
-
+
public override int GetHashCode()
{
return m_method;
@@ -43,21 +46,20 @@ namespace System.Reflection.Emit {
else
return false;
}
-
+
public bool Equals(MethodToken obj)
{
return obj.m_method == m_method;
}
-
+
public static bool operator ==(MethodToken a, MethodToken b)
{
return a.Equals(b);
}
-
+
public static bool operator !=(MethodToken a, MethodToken b)
{
return !(a == b);
}
-
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs
index 30e6382550..d92d8220b8 100644
--- a/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs
@@ -4,7 +4,7 @@
//
-namespace System.Reflection.Emit
+namespace System.Reflection.Emit
{
using System.Runtime.InteropServices;
using System;
@@ -120,7 +120,7 @@ namespace System.Reflection.Emit
object.ReferenceEquals(foundType.DeclaringType, enclosingType))
{
// Cannot have two types with the same name
- throw new ArgumentException(Environment.GetResourceString("Argument_DuplicateTypeName"));
+ throw new ArgumentException(SR.Argument_DuplicateTypeName);
}
}
@@ -135,10 +135,9 @@ namespace System.Reflection.Emit
// convert the format string to byte array and then call FormCompoundType
return SymbolType.FormCompoundType(strFormat, baseType, 0);
-
}
-
-
+
+
internal void CheckContext(params Type[][] typess)
{
ContainingAssemblyBuilder.CheckContext(typess);
@@ -179,14 +178,6 @@ namespace System.Reflection.Emit
{
Debug.Assert(method != null);
-#if FEATURE_APPX
- if (ContainingAssemblyBuilder.ProfileAPICheck)
- {
- if ((method.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", method.FullName));
- }
-#endif
-
return GetMemberRefOfMethodInfo(GetNativeHandle(), tr, method);
}
@@ -194,14 +185,6 @@ namespace System.Reflection.Emit
{
Debug.Assert(method != null);
-#if FEATURE_APPX
- if (ContainingAssemblyBuilder.ProfileAPICheck)
- {
- if ((method.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", method.FullName));
- }
-#endif
-
return GetMemberRefOfMethodInfo(GetNativeHandle(), tr, method);
}
@@ -213,15 +196,6 @@ namespace System.Reflection.Emit
{
Debug.Assert(runtimeField != null);
-#if FEATURE_APPX
- if (ContainingAssemblyBuilder.ProfileAPICheck)
- {
- RtFieldInfo rtField = runtimeField as RtFieldInfo;
- if (rtField != null && (rtField.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtField.FullName));
- }
-#endif
-
return GetMemberRefOfFieldInfo(GetNativeHandle(), tkType, declaringType, runtimeField.MetadataToken);
}
@@ -286,17 +260,6 @@ namespace System.Reflection.Emit
Debug.Assert(!type.IsByRef, "Must not be ByRef.");
Debug.Assert(!type.IsGenericType || type.IsGenericTypeDefinition, "Must not have generic arguments.");
-#if FEATURE_APPX
- if (ContainingAssemblyBuilder.ProfileAPICheck)
- {
- RuntimeType rtType = type as RuntimeType;
- if (rtType != null && (rtType.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtType.FullName));
- }
- }
-#endif
-
return GetTypeRef(GetNativeHandle(), typeName, GetRuntimeModuleFromModule(refedModule).GetNativeHandle(), strRefedModuleFileName, tkResolution);
}
@@ -315,7 +278,7 @@ namespace System.Reflection.Emit
ConstructorOnTypeBuilderInstantiation conOnTypeBuilderInst = null;
RuntimeConstructorInfo rtCon = null;
- if ( (conBuilder = con as ConstructorBuilder) != null )
+ if ((conBuilder = con as ConstructorBuilder) != null)
{
if (usingRef == false && conBuilder.Module.Equals(this))
return conBuilder.GetToken();
@@ -324,14 +287,14 @@ namespace System.Reflection.Emit
tr = GetTypeTokenInternal(con.ReflectedType).Token;
mr = GetMemberRef(con.ReflectedType.Module, tr, conBuilder.GetToken().Token);
}
- else if ( (conOnTypeBuilderInst = con as ConstructorOnTypeBuilderInstantiation) != null )
+ else if ((conOnTypeBuilderInst = con as ConstructorOnTypeBuilderInstantiation) != null)
{
if (usingRef == true) throw new InvalidOperationException();
tr = GetTypeTokenInternal(con.DeclaringType).Token;
mr = GetMemberRef(con.DeclaringType.Module, tr, conOnTypeBuilderInst.MetadataTokenInternal);
}
- else if ( (rtCon = con as RuntimeConstructorInfo) != null && con.ReflectedType.IsArray == false)
+ else if ((rtCon = con as RuntimeConstructorInfo) != null && con.ReflectedType.IsArray == false)
{
// constructor is not a dynamic field
// We need to get the TypeRef tokens
@@ -345,7 +308,7 @@ namespace System.Reflection.Emit
// go through the slower code path, i.e. retrieve parameters and form signature helper.
ParameterInfo[] parameters = con.GetParameters();
if (parameters == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidConstructorInfo"));
+ throw new ArgumentException(SR.Argument_InvalidConstructorInfo);
Type[] parameterTypes = new Type[parameters.Length];
Type[][] requiredCustomModifiers = new Type[parameters.Length][];
@@ -354,7 +317,7 @@ namespace System.Reflection.Emit
for (int i = 0; i < parameters.Length; i++)
{
if (parameters[i] == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidConstructorInfo"));
+ throw new ArgumentException(SR.Argument_InvalidConstructorInfo);
parameterTypes[i] = parameters[i].ParameterType;
requiredCustomModifiers[i] = parameters[i].GetRequiredCustomModifiers();
@@ -369,8 +332,8 @@ namespace System.Reflection.Emit
mr = GetMemberRefFromSignature(tr, con.Name, sigBytes, length);
}
-
- return new MethodToken( mr );
+
+ return new MethodToken(mr);
}
internal void Init(String strModuleName, String strFileName, int tkFile)
@@ -395,7 +358,7 @@ namespace System.Reflection.Emit
#endregion
#region Module Overrides
-
+
// m_internalModuleBuilder is null iff this is a "internal" ModuleBuilder
internal InternalModuleBuilder InternalModule
{
@@ -405,7 +368,7 @@ namespace System.Reflection.Emit
}
}
- internal override ModuleHandle GetModuleHandle()
+ protected override ModuleHandle GetModuleHandleImpl()
{
return new ModuleHandle(GetNativeHandle());
}
@@ -446,7 +409,7 @@ namespace System.Reflection.Emit
if ((method.CallingConvention & CallingConventions.VarArgs) == 0)
{
// Client should not supply optional parameter in default calling convention
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAVarArgCallingConvention"));
+ throw new InvalidOperationException(SR.InvalidOperation_NotAVarArgCallingConvention);
}
}
@@ -532,7 +495,7 @@ namespace System.Reflection.Emit
}
internal SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType,
- Type[] parameterTypes, IEnumerable<Type> optionalParameterTypes, int cGenericParameters)
+ Type[] parameterTypes, IEnumerable<Type> optionalParameterTypes, int cGenericParameters)
{
SignatureHelper sig = SignatureHelper.GetMethodSigHelper(this, call, returnType, cGenericParameters);
@@ -544,7 +507,8 @@ namespace System.Reflection.Emit
}
}
- if (optionalParameterTypes != null) {
+ if (optionalParameterTypes != null)
+ {
int i = 0;
foreach (Type type in optionalParameterTypes)
{
@@ -599,7 +563,7 @@ namespace System.Reflection.Emit
public override Type[] GetTypes()
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return GetTypesNoLock();
}
@@ -620,7 +584,7 @@ namespace System.Reflection.Emit
tmpTypeBldr = enumBldr.m_typeBuilder;
else
tmpTypeBldr = (TypeBuilder)builder;
-
+
// We should not return TypeBuilders.
// Otherwise anyone can emit code in it.
if (tmpTypeBldr.IsCreated())
@@ -636,15 +600,15 @@ namespace System.Reflection.Emit
{
return GetType(className, false, false);
}
-
+
public override Type GetType(String className, bool ignoreCase)
{
return GetType(className, false, ignoreCase);
}
-
+
public override Type GetType(String className, bool throwOnError, bool ignoreCase)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return GetTypeNoLock(className, throwOnError, ignoreCase);
}
@@ -658,7 +622,7 @@ namespace System.Reflection.Emit
// This API first delegate to the Module.GetType implementation. If succeeded, great!
// If not, we have to look up the current module to find the TypeBuilder to represent the base
// type and form the Type object for "foo[,]".
-
+
// Module.GetType() will verify className.
Type baseType = InternalModule.GetType(className, throwOnError, ignoreCase);
if (baseType != null)
@@ -674,7 +638,7 @@ namespace System.Reflection.Emit
while (startIndex <= className.Length)
{
// Are there any possible special characters left?
- int i = className.IndexOfAny(new char[]{'[', '*', '&'}, startIndex);
+ int i = className.IndexOfAny(new char[] { '[', '*', '&' }, startIndex);
if (i == -1)
{
// No, type name is simple.
@@ -709,7 +673,7 @@ namespace System.Reflection.Emit
parameters = null;
}
- baseName = baseName.Replace(@"\\",@"\").Replace(@"\[",@"[").Replace(@"\*",@"*").Replace(@"\&",@"&");
+ baseName = baseName.Replace(@"\\", @"\").Replace(@"\[", @"[").Replace(@"\*", @"*").Replace(@"\&", @"&");
if (parameters != null)
{
@@ -742,9 +706,9 @@ namespace System.Reflection.Emit
return null;
}
- if (parameters == null)
+ if (parameters == null)
return baseType;
-
+
return GetType(parameters, baseType);
}
@@ -885,7 +849,7 @@ namespace System.Reflection.Emit
{
Contract.Ensures(Contract.Result<TypeBuilder>() != null);
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineTypeNoLock(name, TypeAttributes.NotPublic, null, null, PackingSize.Unspecified, TypeBuilder.UnspecifiedTypeSize);
}
@@ -895,7 +859,7 @@ namespace System.Reflection.Emit
{
Contract.Ensures(Contract.Result<TypeBuilder>() != null);
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineTypeNoLock(name, attr, null, null, PackingSize.Unspecified, TypeBuilder.UnspecifiedTypeSize);
}
@@ -905,7 +869,7 @@ namespace System.Reflection.Emit
{
Contract.Ensures(Contract.Result<TypeBuilder>() != null);
- lock(SyncRoot)
+ lock (SyncRoot)
{
// Why do we only call CheckContext here? Why don't we call it in the other overloads?
CheckContext(parent);
@@ -918,7 +882,7 @@ namespace System.Reflection.Emit
{
Contract.Ensures(Contract.Result<TypeBuilder>() != null);
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineTypeNoLock(name, attr, parent, null, PackingSize.Unspecified, typesize);
}
@@ -938,7 +902,7 @@ namespace System.Reflection.Emit
{
Contract.Ensures(Contract.Result<TypeBuilder>() != null);
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineTypeNoLock(name, attr, parent, interfaces, PackingSize.Unspecified, TypeBuilder.UnspecifiedTypeSize);
}
@@ -955,7 +919,7 @@ namespace System.Reflection.Emit
{
Contract.Ensures(Contract.Result<TypeBuilder>() != null);
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineTypeNoLock(name, attr, parent, packsize);
}
@@ -979,7 +943,7 @@ namespace System.Reflection.Emit
Contract.Ensures(Contract.Result<EnumBuilder>() != null);
CheckContext(underlyingType);
- lock(SyncRoot)
+ lock (SyncRoot)
{
EnumBuilder enumBuilder = DefineEnumNoLock(name, visibility, underlyingType);
@@ -1006,7 +970,7 @@ namespace System.Reflection.Emit
return new EnumBuilder(name, underlyingType, visibility, this);
}
-
+
#endregion
#region Define Resource
@@ -1021,7 +985,7 @@ namespace System.Reflection.Emit
return DefineGlobalMethod(name, attributes, CallingConventions.Standard, returnType, parameterTypes);
}
- public MethodBuilder DefineGlobalMethod(String name, MethodAttributes attributes, CallingConventions callingConvention,
+ public MethodBuilder DefineGlobalMethod(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] parameterTypes)
{
Contract.Ensures(Contract.Result<MethodBuilder>() != null);
@@ -1029,33 +993,33 @@ namespace System.Reflection.Emit
return DefineGlobalMethod(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null);
}
- public MethodBuilder DefineGlobalMethod(String name, MethodAttributes attributes, CallingConventions callingConvention,
+ public MethodBuilder DefineGlobalMethod(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
- return DefineGlobalMethodNoLock(name, attributes, callingConvention, returnType,
+ return DefineGlobalMethodNoLock(name, attributes, callingConvention, returnType,
requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers,
parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
}
}
- private MethodBuilder DefineGlobalMethodNoLock(String name, MethodAttributes attributes, CallingConventions callingConvention,
+ private MethodBuilder DefineGlobalMethodNoLock(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
{
if (m_moduleData.m_fGlobalBeenCreated == true)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GlobalsHaveBeenCreated"));
-
+ throw new InvalidOperationException(SR.InvalidOperation_GlobalsHaveBeenCreated);
+
if (name == null)
throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
-
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
+
if ((attributes & MethodAttributes.Static) == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_GlobalFunctionHasToBeStatic"));
+ throw new ArgumentException(SR.Argument_GlobalFunctionHasToBeStatic);
Contract.Ensures(Contract.Result<MethodBuilder>() != null);
Contract.EndContractBlock();
@@ -1066,14 +1030,14 @@ namespace System.Reflection.Emit
m_moduleData.m_fHasGlobal = true;
- return m_moduleData.m_globalTypeBuilder.DefineMethod(name, attributes, callingConvention,
- returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers,
+ return m_moduleData.m_globalTypeBuilder.DefineMethod(name, attributes, callingConvention,
+ returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers,
parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
}
-
+
public void CreateGlobalFunctions()
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
CreateGlobalFunctionsNoLock();
}
@@ -1084,12 +1048,12 @@ namespace System.Reflection.Emit
if (m_moduleData.m_fGlobalBeenCreated)
{
// cannot create globals twice
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule"));
+ throw new InvalidOperationException(SR.InvalidOperation_NotADebugModule);
}
m_moduleData.m_globalTypeBuilder.CreateType();
m_moduleData.m_fGlobalBeenCreated = true;
}
-
+
#endregion
#region Define Data
@@ -1101,7 +1065,7 @@ namespace System.Reflection.Emit
// will be the signature for the Field.
Contract.Ensures(Contract.Result<FieldBuilder>() != null);
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineInitializedDataNoLock(name, data, attributes);
}
@@ -1114,20 +1078,20 @@ namespace System.Reflection.Emit
// will be the signature for the Field.
if (m_moduleData.m_fGlobalBeenCreated == true)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GlobalsHaveBeenCreated"));
+ throw new InvalidOperationException(SR.InvalidOperation_GlobalsHaveBeenCreated);
}
Contract.Ensures(Contract.Result<FieldBuilder>() != null);
Contract.EndContractBlock();
-
+
m_moduleData.m_fHasGlobal = true;
return m_moduleData.m_globalTypeBuilder.DefineInitializedData(name, data, attributes);
}
-
+
public FieldBuilder DefineUninitializedData(String name, int size, FieldAttributes attributes)
{
Contract.Ensures(Contract.Result<FieldBuilder>() != null);
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineUninitializedDataNoLock(name, size, attributes);
}
@@ -1141,15 +1105,15 @@ namespace System.Reflection.Emit
if (m_moduleData.m_fGlobalBeenCreated == true)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GlobalsHaveBeenCreated"));
+ throw new InvalidOperationException(SR.InvalidOperation_GlobalsHaveBeenCreated);
}
Contract.Ensures(Contract.Result<FieldBuilder>() != null);
Contract.EndContractBlock();
-
+
m_moduleData.m_fHasGlobal = true;
return m_moduleData.m_globalTypeBuilder.DefineUninitializedData(name, size, attributes);
}
-
+
#endregion
#region GetToken
@@ -1164,14 +1128,14 @@ namespace System.Reflection.Emit
private TypeToken GetTypeTokenInternal(Type type, bool getGenericDefinition)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return GetTypeTokenWorkerNoLock(type, getGenericDefinition);
}
}
public TypeToken GetTypeToken(Type type)
- {
+ {
return GetTypeTokenInternal(type, true);
}
@@ -1182,7 +1146,7 @@ namespace System.Reflection.Emit
Contract.EndContractBlock();
CheckContext(type);
-
+
// Return a token for the class relative to the Module. Tokens
// are used to indentify objects when the objects are used in IL
// instructions. Tokens are always relative to the Module. For example,
@@ -1194,7 +1158,7 @@ namespace System.Reflection.Emit
// We should also be aware of multiple dynamic modules and multiple implementation of Type!!!
if (type.IsByRef)
- throw new ArgumentException(Environment.GetResourceString("Argument_CannotGetTypeTokenForByRef"));
+ throw new ArgumentException(SR.Argument_CannotGetTypeTokenForByRef);
if ((type.IsGenericType && (!type.IsGenericTypeDefinition || !getGenericDefinition)) ||
type.IsGenericParameter ||
@@ -1231,10 +1195,10 @@ namespace System.Reflection.Emit
{
return new TypeToken(paramBuilder.MetadataTokenInternal);
}
-
+
return new TypeToken(GetTypeRefNested(type, this, String.Empty));
}
-
+
// After this point, the referenced module is not the same as the referencing
// module.
//
@@ -1258,21 +1222,21 @@ namespace System.Reflection.Emit
return new TypeToken(GetTypeRefNested(type, refedModule, strRefedModuleFileName));
}
-
+
public TypeToken GetTypeToken(String name)
{
// Return a token for the class relative to the Module.
// Module.GetType() verifies name
-
+
// Unfortunately, we will need to load the Type and then call GetTypeToken in
// order to correctly track the assembly reference information.
-
+
return GetTypeToken(InternalModule.GetType(name, false, true));
}
public MethodToken GetMethodToken(MethodInfo method)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return GetMethodTokenNoLock(method, true);
}
@@ -1280,7 +1244,7 @@ namespace System.Reflection.Emit
internal MethodToken GetMethodTokenInternal(MethodInfo method)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return GetMethodTokenNoLock(method, false);
}
@@ -1300,18 +1264,18 @@ namespace System.Reflection.Emit
int tr;
int mr = 0;
-
+
SymbolMethod symMethod = null;
MethodBuilder methBuilder = null;
- if ( (methBuilder = method as MethodBuilder) != null )
+ if ((methBuilder = method as MethodBuilder) != null)
{
int methodToken = methBuilder.MetadataTokenInternal;
if (method.Module.Equals(this))
return new MethodToken(methodToken);
if (method.DeclaringType == null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule"));
+ throw new InvalidOperationException(SR.InvalidOperation_CannotImportGlobalFromDifferentModule);
// method is defined in a different module
tr = getGenericTypeDefinition ? GetTypeToken(method.DeclaringType).Token : GetTypeTokenInternal(method.DeclaringType).Token;
@@ -1335,7 +1299,7 @@ namespace System.Reflection.Emit
// We need to get the TypeRef tokens
if (declaringType == null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule"));
+ throw new InvalidOperationException(SR.InvalidOperation_CannotImportGlobalFromDifferentModule);
RuntimeMethodInfo rtMeth = null;
@@ -1343,15 +1307,15 @@ namespace System.Reflection.Emit
{
// use reflection to build signature to work around the E_T_VAR problem in EEClass
ParameterInfo[] paramInfo = method.GetParameters();
-
+
Type[] tt = new Type[paramInfo.Length];
-
+
for (int i = 0; i < paramInfo.Length; i++)
tt[i] = paramInfo[i].ParameterType;
return GetArrayMethodToken(declaringType, method.Name, method.CallingConvention, method.ReturnType, tt);
}
- else if ( (rtMeth = method as RuntimeMethodInfo) != null )
+ else if ((rtMeth = method as RuntimeMethodInfo) != null)
{
tr = getGenericTypeDefinition ? GetTypeToken(method.DeclaringType).Token : GetTypeTokenInternal(method.DeclaringType).Token;
mr = GetMemberRefOfMethodInfo(tr, rtMeth);
@@ -1372,25 +1336,25 @@ namespace System.Reflection.Emit
requiredCustomModifiers[i] = parameters[i].GetRequiredCustomModifiers();
optionalCustomModifiers[i] = parameters[i].GetOptionalCustomModifiers();
}
-
+
tr = getGenericTypeDefinition ? GetTypeToken(method.DeclaringType).Token : GetTypeTokenInternal(method.DeclaringType).Token;
SignatureHelper sigHelp;
- try
+ try
{
sigHelp = SignatureHelper.GetMethodSigHelper(
- this, method.CallingConvention, method.ReturnType,
- method.ReturnParameter.GetRequiredCustomModifiers(), method.ReturnParameter.GetOptionalCustomModifiers(),
+ this, method.CallingConvention, method.ReturnType,
+ method.ReturnParameter.GetRequiredCustomModifiers(), method.ReturnParameter.GetOptionalCustomModifiers(),
parameterTypes, requiredCustomModifiers, optionalCustomModifiers);
- }
- catch(NotImplementedException)
+ }
+ catch (NotImplementedException)
{
// Legacy code deriving from MethodInfo may not have implemented ReturnParameter.
sigHelp = SignatureHelper.GetMethodSigHelper(this, method.ReturnType, parameterTypes);
}
- int length;
+ int length;
byte[] sigBytes = sigHelp.InternalGetSignature(out length);
mr = GetMemberRefFromSignature(tr, method.Name, sigBytes, length);
}
@@ -1464,17 +1428,17 @@ namespace System.Reflection.Emit
return tk;
}
-
- public MethodToken GetArrayMethodToken(Type arrayClass, String methodName, CallingConventions callingConvention,
+
+ public MethodToken GetArrayMethodToken(Type arrayClass, String methodName, CallingConventions callingConvention,
Type returnType, Type[] parameterTypes)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return GetArrayMethodTokenNoLock(arrayClass, methodName, callingConvention, returnType, parameterTypes);
}
}
- private MethodToken GetArrayMethodTokenNoLock(Type arrayClass, String methodName, CallingConventions callingConvention,
+ private MethodToken GetArrayMethodTokenNoLock(Type arrayClass, String methodName, CallingConventions callingConvention,
Type returnType, Type[] parameterTypes)
{
if (arrayClass == null)
@@ -1484,10 +1448,10 @@ namespace System.Reflection.Emit
throw new ArgumentNullException(nameof(methodName));
if (methodName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(methodName));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(methodName));
if (arrayClass.IsArray == false)
- throw new ArgumentException(Environment.GetResourceString("Argument_HasToBeArrayClass"));
+ throw new ArgumentException(SR.Argument_HasToBeArrayClass);
Contract.EndContractBlock();
CheckContext(returnType, arrayClass);
@@ -1509,7 +1473,7 @@ namespace System.Reflection.Emit
typeSpec.Token, methodName, sigBytes, length));
}
- public MethodInfo GetArrayMethod(Type arrayClass, String methodName, CallingConventions callingConvention,
+ public MethodInfo GetArrayMethod(Type arrayClass, String methodName, CallingConventions callingConvention,
Type returnType, Type[] parameterTypes)
{
CheckContext(returnType, arrayClass);
@@ -1531,23 +1495,24 @@ namespace System.Reflection.Emit
return InternalGetConstructorToken(con, false);
}
- public FieldToken GetFieldToken(FieldInfo field)
+ public FieldToken GetFieldToken(FieldInfo field)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return GetFieldTokenNoLock(field);
}
}
- private FieldToken GetFieldTokenNoLock(FieldInfo field)
+ private FieldToken GetFieldTokenNoLock(FieldInfo field)
{
- if (field == null) {
+ if (field == null)
+ {
throw new ArgumentNullException(nameof(field));
}
Contract.EndContractBlock();
- int tr;
- int mr = 0;
+ int tr;
+ int mr = 0;
FieldBuilder fdBuilder = null;
RuntimeFieldInfo rtField = null;
@@ -1572,22 +1537,22 @@ namespace System.Reflection.Emit
// field is defined in a different module
if (field.DeclaringType == null)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule"));
+ throw new InvalidOperationException(SR.InvalidOperation_CannotImportGlobalFromDifferentModule);
}
tr = GetTypeTokenInternal(field.DeclaringType).Token;
mr = GetMemberRef(field.ReflectedType.Module, tr, fdBuilder.GetToken().Token);
}
}
- else if ( (rtField = field as RuntimeFieldInfo) != null)
+ else if ((rtField = field as RuntimeFieldInfo) != null)
{
// FieldInfo is not an dynamic field
-
+
// We need to get the TypeRef tokens
if (field.DeclaringType == null)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule"));
+ throw new InvalidOperationException(SR.InvalidOperation_CannotImportGlobalFromDifferentModule);
}
-
+
if (field.DeclaringType != null && field.DeclaringType.IsGenericType)
{
int length;
@@ -1597,11 +1562,11 @@ namespace System.Reflection.Emit
}
else
{
- tr = GetTypeTokenInternal(field.DeclaringType).Token;
+ tr = GetTypeTokenInternal(field.DeclaringType).Token;
mr = GetMemberRefOfFieldInfo(tr, field.DeclaringType.GetTypeHandleInternal(), rtField);
}
}
- else if ( (fOnTB = field as FieldOnTypeBuilderInstantiation) != null)
+ else if ((fOnTB = field as FieldOnTypeBuilderInstantiation) != null)
{
FieldInfo fb = fOnTB.FieldInfo;
int length;
@@ -1623,11 +1588,11 @@ namespace System.Reflection.Emit
mr = GetMemberRefFromSignature(tr, field.Name, sigBytes, length);
}
-
+
return new FieldToken(mr, field.GetType());
}
-
- public StringToken GetStringConstant(String str)
+
+ public StringToken GetStringConstant(String str)
{
if (str == null)
{
@@ -1639,7 +1604,7 @@ namespace System.Reflection.Emit
// value has already been defined, the existing token will be returned.
return new StringToken(GetStringConstant(GetNativeHandle(), str, str.Length));
}
-
+
public SignatureToken GetSignatureToken(SignatureHelper sigHelper)
{
// Define signature token given a signature helper. This will define a metadata
@@ -1653,11 +1618,11 @@ namespace System.Reflection.Emit
int sigLength;
byte[] sigBytes;
-
+
// get the signature in byte form
sigBytes = sigHelper.InternalGetSignature(out sigLength);
return new SignatureToken(TypeBuilder.GetTokenFromSig(GetNativeHandle(), sigBytes, sigLength), this);
- }
+ }
public SignatureToken GetSignatureToken(byte[] sigBytes, int sigLength)
{
if (sigBytes == null)
@@ -1669,7 +1634,7 @@ namespace System.Reflection.Emit
return new SignatureToken(TypeBuilder.GetTokenFromSig(GetNativeHandle(), localSigBytes, sigLength), this);
}
-
+
#endregion
#region Other
@@ -1681,7 +1646,7 @@ namespace System.Reflection.Emit
if (binaryAttribute == null)
throw new ArgumentNullException(nameof(binaryAttribute));
Contract.EndContractBlock();
-
+
TypeBuilder.DefineCustomAttribute(
this,
1, // This is hard coding the module token to 1
@@ -1742,7 +1707,7 @@ namespace System.Reflection.Emit
throw new ArgumentNullException(nameof(url));
Contract.EndContractBlock();
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineDocumentNoLock(url, language, languageVendor, documentType);
}
@@ -1753,12 +1718,12 @@ namespace System.Reflection.Emit
if (m_iSymWriter == null)
{
// Cannot DefineDocument when it is not a debug module
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule"));
+ throw new InvalidOperationException(SR.InvalidOperation_NotADebugModule);
}
return m_iSymWriter.DefineDocument(url, language, languageVendor, documentType);
}
-
+
[Pure]
public bool IsTransient()
{
diff --git a/src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs
index 4b6f8b4efe..4f1b8eb713 100644
--- a/src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs
@@ -6,16 +6,16 @@
////////////////////////////////////////////////////////////////////////////////
//
+using System;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.IO;
+using System.Reflection;
+using System.Runtime.Versioning;
+
namespace System.Reflection.Emit
{
- using System;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- using System.IO;
- using System.Reflection;
- using System.Runtime.Versioning;
-
// This is a package private class. This class hold all of the managed
// data member for ModuleBuilder. Note that what ever data members added to
// this class cannot be accessed from the EE.
@@ -46,25 +46,25 @@ namespace System.Reflection.Emit
if (strExtension == null || strExtension == String.Empty)
{
// This is required by our loader. It cannot load module file that does not have file extension.
- throw new ArgumentException(Environment.GetResourceString("Argument_NoModuleFileExtension", strFileName));
+ throw new ArgumentException(SR.Format(SR.Argument_NoModuleFileExtension, strFileName));
}
m_strFileName = strFileName;
}
}
- internal String m_strModuleName; // scope name (can be different from file name)
- internal String m_strFileName;
- internal bool m_fGlobalBeenCreated;
- internal bool m_fHasGlobal;
+ internal String m_strModuleName; // scope name (can be different from file name)
+ internal String m_strFileName;
+ internal bool m_fGlobalBeenCreated;
+ internal bool m_fHasGlobal;
[NonSerialized]
- internal TypeBuilder m_globalTypeBuilder;
+ internal TypeBuilder m_globalTypeBuilder;
[NonSerialized]
internal ModuleBuilder m_module;
- private int m_tkFile;
- internal bool m_isSaved;
+ private int m_tkFile;
+ internal bool m_isSaved;
internal const String MULTI_BYTE_VALUE_CLASS = "$ArrayType$";
- internal String m_strResourceFileName;
- internal byte[] m_resourceBytes;
+ internal String m_strResourceFileName;
+ internal byte[] m_resourceBytes;
} // class ModuleBuilderData
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/OpCodes.cs b/src/mscorlib/src/System/Reflection/Emit/OpCodes.cs
index 324fad9ceb..99915492c1 100644
--- a/src/mscorlib/src/System/Reflection/Emit/OpCodes.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/OpCodes.cs
@@ -10,2540 +10,2543 @@
**
**
============================================================*/
-namespace System.Reflection.Emit {
using System;
-//
-// Internal enums for opcode values. Note that the value names are used to construct
-// publicly visible ilasm-compatible opcode names, so their exact form is important!
-//
-internal enum OpCodeValues {
- Nop = 0x00,
- Break = 0x01,
- Ldarg_0 = 0x02,
- Ldarg_1 = 0x03,
- Ldarg_2 = 0x04,
- Ldarg_3 = 0x05,
- Ldloc_0 = 0x06,
- Ldloc_1 = 0x07,
- Ldloc_2 = 0x08,
- Ldloc_3 = 0x09,
- Stloc_0 = 0x0a,
- Stloc_1 = 0x0b,
- Stloc_2 = 0x0c,
- Stloc_3 = 0x0d,
- Ldarg_S = 0x0e,
- Ldarga_S = 0x0f,
- Starg_S = 0x10,
- Ldloc_S = 0x11,
- Ldloca_S = 0x12,
- Stloc_S = 0x13,
- Ldnull = 0x14,
- Ldc_I4_M1 = 0x15,
- Ldc_I4_0 = 0x16,
- Ldc_I4_1 = 0x17,
- Ldc_I4_2 = 0x18,
- Ldc_I4_3 = 0x19,
- Ldc_I4_4 = 0x1a,
- Ldc_I4_5 = 0x1b,
- Ldc_I4_6 = 0x1c,
- Ldc_I4_7 = 0x1d,
- Ldc_I4_8 = 0x1e,
- Ldc_I4_S = 0x1f,
- Ldc_I4 = 0x20,
- Ldc_I8 = 0x21,
- Ldc_R4 = 0x22,
- Ldc_R8 = 0x23,
- Dup = 0x25,
- Pop = 0x26,
- Jmp = 0x27,
- Call = 0x28,
- Calli = 0x29,
- Ret = 0x2a,
- Br_S = 0x2b,
- Brfalse_S = 0x2c,
- Brtrue_S = 0x2d,
- Beq_S = 0x2e,
- Bge_S = 0x2f,
- Bgt_S = 0x30,
- Ble_S = 0x31,
- Blt_S = 0x32,
- Bne_Un_S = 0x33,
- Bge_Un_S = 0x34,
- Bgt_Un_S = 0x35,
- Ble_Un_S = 0x36,
- Blt_Un_S = 0x37,
- Br = 0x38,
- Brfalse = 0x39,
- Brtrue = 0x3a,
- Beq = 0x3b,
- Bge = 0x3c,
- Bgt = 0x3d,
- Ble = 0x3e,
- Blt = 0x3f,
- Bne_Un = 0x40,
- Bge_Un = 0x41,
- Bgt_Un = 0x42,
- Ble_Un = 0x43,
- Blt_Un = 0x44,
- Switch = 0x45,
- Ldind_I1 = 0x46,
- Ldind_U1 = 0x47,
- Ldind_I2 = 0x48,
- Ldind_U2 = 0x49,
- Ldind_I4 = 0x4a,
- Ldind_U4 = 0x4b,
- Ldind_I8 = 0x4c,
- Ldind_I = 0x4d,
- Ldind_R4 = 0x4e,
- Ldind_R8 = 0x4f,
- Ldind_Ref = 0x50,
- Stind_Ref = 0x51,
- Stind_I1 = 0x52,
- Stind_I2 = 0x53,
- Stind_I4 = 0x54,
- Stind_I8 = 0x55,
- Stind_R4 = 0x56,
- Stind_R8 = 0x57,
- Add = 0x58,
- Sub = 0x59,
- Mul = 0x5a,
- Div = 0x5b,
- Div_Un = 0x5c,
- Rem = 0x5d,
- Rem_Un = 0x5e,
- And = 0x5f,
- Or = 0x60,
- Xor = 0x61,
- Shl = 0x62,
- Shr = 0x63,
- Shr_Un = 0x64,
- Neg = 0x65,
- Not = 0x66,
- Conv_I1 = 0x67,
- Conv_I2 = 0x68,
- Conv_I4 = 0x69,
- Conv_I8 = 0x6a,
- Conv_R4 = 0x6b,
- Conv_R8 = 0x6c,
- Conv_U4 = 0x6d,
- Conv_U8 = 0x6e,
- Callvirt = 0x6f,
- Cpobj = 0x70,
- Ldobj = 0x71,
- Ldstr = 0x72,
- Newobj = 0x73,
- Castclass = 0x74,
- Isinst = 0x75,
- Conv_R_Un = 0x76,
- Unbox = 0x79,
- Throw = 0x7a,
- Ldfld = 0x7b,
- Ldflda = 0x7c,
- Stfld = 0x7d,
- Ldsfld = 0x7e,
- Ldsflda = 0x7f,
- Stsfld = 0x80,
- Stobj = 0x81,
- Conv_Ovf_I1_Un = 0x82,
- Conv_Ovf_I2_Un = 0x83,
- Conv_Ovf_I4_Un = 0x84,
- Conv_Ovf_I8_Un = 0x85,
- Conv_Ovf_U1_Un = 0x86,
- Conv_Ovf_U2_Un = 0x87,
- Conv_Ovf_U4_Un = 0x88,
- Conv_Ovf_U8_Un = 0x89,
- Conv_Ovf_I_Un = 0x8a,
- Conv_Ovf_U_Un = 0x8b,
- Box = 0x8c,
- Newarr = 0x8d,
- Ldlen = 0x8e,
- Ldelema = 0x8f,
- Ldelem_I1 = 0x90,
- Ldelem_U1 = 0x91,
- Ldelem_I2 = 0x92,
- Ldelem_U2 = 0x93,
- Ldelem_I4 = 0x94,
- Ldelem_U4 = 0x95,
- Ldelem_I8 = 0x96,
- Ldelem_I = 0x97,
- Ldelem_R4 = 0x98,
- Ldelem_R8 = 0x99,
- Ldelem_Ref = 0x9a,
- Stelem_I = 0x9b,
- Stelem_I1 = 0x9c,
- Stelem_I2 = 0x9d,
- Stelem_I4 = 0x9e,
- Stelem_I8 = 0x9f,
- Stelem_R4 = 0xa0,
- Stelem_R8 = 0xa1,
- Stelem_Ref = 0xa2,
- Ldelem = 0xa3,
- Stelem = 0xa4,
- Unbox_Any = 0xa5,
- Conv_Ovf_I1 = 0xb3,
- Conv_Ovf_U1 = 0xb4,
- Conv_Ovf_I2 = 0xb5,
- Conv_Ovf_U2 = 0xb6,
- Conv_Ovf_I4 = 0xb7,
- Conv_Ovf_U4 = 0xb8,
- Conv_Ovf_I8 = 0xb9,
- Conv_Ovf_U8 = 0xba,
- Refanyval = 0xc2,
- Ckfinite = 0xc3,
- Mkrefany = 0xc6,
- Ldtoken = 0xd0,
- Conv_U2 = 0xd1,
- Conv_U1 = 0xd2,
- Conv_I = 0xd3,
- Conv_Ovf_I = 0xd4,
- Conv_Ovf_U = 0xd5,
- Add_Ovf = 0xd6,
- Add_Ovf_Un = 0xd7,
- Mul_Ovf = 0xd8,
- Mul_Ovf_Un = 0xd9,
- Sub_Ovf = 0xda,
- Sub_Ovf_Un = 0xdb,
- Endfinally = 0xdc,
- Leave = 0xdd,
- Leave_S = 0xde,
- Stind_I = 0xdf,
- Conv_U = 0xe0,
- Prefix7 = 0xf8,
- Prefix6 = 0xf9,
- Prefix5 = 0xfa,
- Prefix4 = 0xfb,
- Prefix3 = 0xfc,
- Prefix2 = 0xfd,
- Prefix1 = 0xfe,
- Prefixref = 0xff,
- Arglist = 0xfe00,
- Ceq = 0xfe01,
- Cgt = 0xfe02,
- Cgt_Un = 0xfe03,
- Clt = 0xfe04,
- Clt_Un = 0xfe05,
- Ldftn = 0xfe06,
- Ldvirtftn = 0xfe07,
- Ldarg = 0xfe09,
- Ldarga = 0xfe0a,
- Starg = 0xfe0b,
- Ldloc = 0xfe0c,
- Ldloca = 0xfe0d,
- Stloc = 0xfe0e,
- Localloc = 0xfe0f,
- Endfilter = 0xfe11,
- Unaligned_ = 0xfe12,
- Volatile_ = 0xfe13,
- Tail_ = 0xfe14,
- Initobj = 0xfe15,
- Constrained_ = 0xfe16,
- Cpblk = 0xfe17,
- Initblk = 0xfe18,
- Rethrow = 0xfe1a,
- Sizeof = 0xfe1c,
- Refanytype = 0xfe1d,
- Readonly_ = 0xfe1e,
-
- // If you add more opcodes here, modify OpCode.Name to handle them correctly
-};
-
-public class OpCodes {
-
-/// <summary>
-/// <para>
-/// The IL instruction opcodes supported by the
-/// runtime. The IL Instruction Specification describes each
-/// Opcode.
-/// </para>
-/// </summary>
-/// <seealso topic='IL Instruction Set Specification'/>
-
- private OpCodes() {
- }
-
- public static readonly OpCode Nop = new OpCode(OpCodeValues.Nop,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Break = new OpCode(OpCodeValues.Break,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Break << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldarg_0 = new OpCode(OpCodeValues.Ldarg_0,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldarg_1 = new OpCode(OpCodeValues.Ldarg_1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldarg_2 = new OpCode(OpCodeValues.Ldarg_2,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldarg_3 = new OpCode(OpCodeValues.Ldarg_3,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldloc_0 = new OpCode(OpCodeValues.Ldloc_0,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldloc_1 = new OpCode(OpCodeValues.Ldloc_1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldloc_2 = new OpCode(OpCodeValues.Ldloc_2,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldloc_3 = new OpCode(OpCodeValues.Ldloc_3,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stloc_0 = new OpCode(OpCodeValues.Stloc_0,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stloc_1 = new OpCode(OpCodeValues.Stloc_1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stloc_2 = new OpCode(OpCodeValues.Stloc_2,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stloc_3 = new OpCode(OpCodeValues.Stloc_3,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldarg_S = new OpCode(OpCodeValues.Ldarg_S,
- ((int)OperandType.ShortInlineVar) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldarga_S = new OpCode(OpCodeValues.Ldarga_S,
- ((int)OperandType.ShortInlineVar) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Starg_S = new OpCode(OpCodeValues.Starg_S,
- ((int)OperandType.ShortInlineVar) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldloc_S = new OpCode(OpCodeValues.Ldloc_S,
- ((int)OperandType.ShortInlineVar) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldloca_S = new OpCode(OpCodeValues.Ldloca_S,
- ((int)OperandType.ShortInlineVar) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stloc_S = new OpCode(OpCodeValues.Stloc_S,
- ((int)OperandType.ShortInlineVar) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldnull = new OpCode(OpCodeValues.Ldnull,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldc_I4_M1 = new OpCode(OpCodeValues.Ldc_I4_M1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldc_I4_0 = new OpCode(OpCodeValues.Ldc_I4_0,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldc_I4_1 = new OpCode(OpCodeValues.Ldc_I4_1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldc_I4_2 = new OpCode(OpCodeValues.Ldc_I4_2,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldc_I4_3 = new OpCode(OpCodeValues.Ldc_I4_3,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldc_I4_4 = new OpCode(OpCodeValues.Ldc_I4_4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldc_I4_5 = new OpCode(OpCodeValues.Ldc_I4_5,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldc_I4_6 = new OpCode(OpCodeValues.Ldc_I4_6,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldc_I4_7 = new OpCode(OpCodeValues.Ldc_I4_7,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldc_I4_8 = new OpCode(OpCodeValues.Ldc_I4_8,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldc_I4_S = new OpCode(OpCodeValues.Ldc_I4_S,
- ((int)OperandType.ShortInlineI) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldc_I4 = new OpCode(OpCodeValues.Ldc_I4,
- ((int)OperandType.InlineI) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldc_I8 = new OpCode(OpCodeValues.Ldc_I8,
- ((int)OperandType.InlineI8) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldc_R4 = new OpCode(OpCodeValues.Ldc_R4,
- ((int)OperandType.ShortInlineR) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushr4 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldc_R8 = new OpCode(OpCodeValues.Ldc_R8,
- ((int)OperandType.InlineR) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Dup = new OpCode(OpCodeValues.Dup,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1_push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Pop = new OpCode(OpCodeValues.Pop,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Jmp = new OpCode(OpCodeValues.Jmp,
- ((int)OperandType.InlineMethod) |
- ((int)FlowControl.Call << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- OpCode.EndsUncondJmpBlkFlag |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Call = new OpCode(OpCodeValues.Call,
- ((int)OperandType.InlineMethod) |
- ((int)FlowControl.Call << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Varpop << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Varpush << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Calli = new OpCode(OpCodeValues.Calli,
- ((int)OperandType.InlineSig) |
- ((int)FlowControl.Call << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Varpop << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Varpush << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ret = new OpCode(OpCodeValues.Ret,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Return << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Varpop << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- OpCode.EndsUncondJmpBlkFlag |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Br_S = new OpCode(OpCodeValues.Br_S,
- ((int)OperandType.ShortInlineBrTarget) |
- ((int)FlowControl.Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- OpCode.EndsUncondJmpBlkFlag |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Brfalse_S = new OpCode(OpCodeValues.Brfalse_S,
- ((int)OperandType.ShortInlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Brtrue_S = new OpCode(OpCodeValues.Brtrue_S,
- ((int)OperandType.ShortInlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Beq_S = new OpCode(OpCodeValues.Beq_S,
- ((int)OperandType.ShortInlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Bge_S = new OpCode(OpCodeValues.Bge_S,
- ((int)OperandType.ShortInlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Bgt_S = new OpCode(OpCodeValues.Bgt_S,
- ((int)OperandType.ShortInlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ble_S = new OpCode(OpCodeValues.Ble_S,
- ((int)OperandType.ShortInlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Blt_S = new OpCode(OpCodeValues.Blt_S,
- ((int)OperandType.ShortInlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Bne_Un_S = new OpCode(OpCodeValues.Bne_Un_S,
- ((int)OperandType.ShortInlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Bge_Un_S = new OpCode(OpCodeValues.Bge_Un_S,
- ((int)OperandType.ShortInlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Bgt_Un_S = new OpCode(OpCodeValues.Bgt_Un_S,
- ((int)OperandType.ShortInlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ble_Un_S = new OpCode(OpCodeValues.Ble_Un_S,
- ((int)OperandType.ShortInlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Blt_Un_S = new OpCode(OpCodeValues.Blt_Un_S,
- ((int)OperandType.ShortInlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Br = new OpCode(OpCodeValues.Br,
- ((int)OperandType.InlineBrTarget) |
- ((int)FlowControl.Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- OpCode.EndsUncondJmpBlkFlag |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Brfalse = new OpCode(OpCodeValues.Brfalse,
- ((int)OperandType.InlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Brtrue = new OpCode(OpCodeValues.Brtrue,
- ((int)OperandType.InlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Beq = new OpCode(OpCodeValues.Beq,
- ((int)OperandType.InlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Bge = new OpCode(OpCodeValues.Bge,
- ((int)OperandType.InlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Bgt = new OpCode(OpCodeValues.Bgt,
- ((int)OperandType.InlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ble = new OpCode(OpCodeValues.Ble,
- ((int)OperandType.InlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Blt = new OpCode(OpCodeValues.Blt,
- ((int)OperandType.InlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Bne_Un = new OpCode(OpCodeValues.Bne_Un,
- ((int)OperandType.InlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Bge_Un = new OpCode(OpCodeValues.Bge_Un,
- ((int)OperandType.InlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Bgt_Un = new OpCode(OpCodeValues.Bgt_Un,
- ((int)OperandType.InlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ble_Un = new OpCode(OpCodeValues.Ble_Un,
- ((int)OperandType.InlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Blt_Un = new OpCode(OpCodeValues.Blt_Un,
- ((int)OperandType.InlineBrTarget) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Switch = new OpCode(OpCodeValues.Switch,
- ((int)OperandType.InlineSwitch) |
- ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldind_I1 = new OpCode(OpCodeValues.Ldind_I1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldind_U1 = new OpCode(OpCodeValues.Ldind_U1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldind_I2 = new OpCode(OpCodeValues.Ldind_I2,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldind_U2 = new OpCode(OpCodeValues.Ldind_U2,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldind_I4 = new OpCode(OpCodeValues.Ldind_I4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldind_U4 = new OpCode(OpCodeValues.Ldind_U4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldind_I8 = new OpCode(OpCodeValues.Ldind_I8,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldind_I = new OpCode(OpCodeValues.Ldind_I,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldind_R4 = new OpCode(OpCodeValues.Ldind_R4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushr4 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldind_R8 = new OpCode(OpCodeValues.Ldind_R8,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldind_Ref = new OpCode(OpCodeValues.Ldind_Ref,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stind_Ref = new OpCode(OpCodeValues.Stind_Ref,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stind_I1 = new OpCode(OpCodeValues.Stind_I1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stind_I2 = new OpCode(OpCodeValues.Stind_I2,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stind_I4 = new OpCode(OpCodeValues.Stind_I4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stind_I8 = new OpCode(OpCodeValues.Stind_I8,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi_popi8 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stind_R4 = new OpCode(OpCodeValues.Stind_R4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi_popr4 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stind_R8 = new OpCode(OpCodeValues.Stind_R8,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi_popr8 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Add = new OpCode(OpCodeValues.Add,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Sub = new OpCode(OpCodeValues.Sub,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Mul = new OpCode(OpCodeValues.Mul,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Div = new OpCode(OpCodeValues.Div,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Div_Un = new OpCode(OpCodeValues.Div_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Rem = new OpCode(OpCodeValues.Rem,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Rem_Un = new OpCode(OpCodeValues.Rem_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode And = new OpCode(OpCodeValues.And,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Or = new OpCode(OpCodeValues.Or,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Xor = new OpCode(OpCodeValues.Xor,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Shl = new OpCode(OpCodeValues.Shl,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Shr = new OpCode(OpCodeValues.Shr,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Shr_Un = new OpCode(OpCodeValues.Shr_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Neg = new OpCode(OpCodeValues.Neg,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Not = new OpCode(OpCodeValues.Not,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_I1 = new OpCode(OpCodeValues.Conv_I1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_I2 = new OpCode(OpCodeValues.Conv_I2,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_I4 = new OpCode(OpCodeValues.Conv_I4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_I8 = new OpCode(OpCodeValues.Conv_I8,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_R4 = new OpCode(OpCodeValues.Conv_R4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushr4 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_R8 = new OpCode(OpCodeValues.Conv_R8,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_U4 = new OpCode(OpCodeValues.Conv_U4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_U8 = new OpCode(OpCodeValues.Conv_U8,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Callvirt = new OpCode(OpCodeValues.Callvirt,
- ((int)OperandType.InlineMethod) |
- ((int)FlowControl.Call << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Varpop << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Varpush << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Cpobj = new OpCode(OpCodeValues.Cpobj,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldobj = new OpCode(OpCodeValues.Ldobj,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldstr = new OpCode(OpCodeValues.Ldstr,
- ((int)OperandType.InlineString) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Newobj = new OpCode(OpCodeValues.Newobj,
- ((int)OperandType.InlineMethod) |
- ((int)FlowControl.Call << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Varpop << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Castclass = new OpCode(OpCodeValues.Castclass,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Isinst = new OpCode(OpCodeValues.Isinst,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_R_Un = new OpCode(OpCodeValues.Conv_R_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Unbox = new OpCode(OpCodeValues.Unbox,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Throw = new OpCode(OpCodeValues.Throw,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Throw << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- OpCode.EndsUncondJmpBlkFlag |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldfld = new OpCode(OpCodeValues.Ldfld,
- ((int)OperandType.InlineField) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldflda = new OpCode(OpCodeValues.Ldflda,
- ((int)OperandType.InlineField) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stfld = new OpCode(OpCodeValues.Stfld,
- ((int)OperandType.InlineField) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldsfld = new OpCode(OpCodeValues.Ldsfld,
- ((int)OperandType.InlineField) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldsflda = new OpCode(OpCodeValues.Ldsflda,
- ((int)OperandType.InlineField) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stsfld = new OpCode(OpCodeValues.Stsfld,
- ((int)OperandType.InlineField) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stobj = new OpCode(OpCodeValues.Stobj,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_I1_Un = new OpCode(OpCodeValues.Conv_Ovf_I1_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_I2_Un = new OpCode(OpCodeValues.Conv_Ovf_I2_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_I4_Un = new OpCode(OpCodeValues.Conv_Ovf_I4_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_I8_Un = new OpCode(OpCodeValues.Conv_Ovf_I8_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_U1_Un = new OpCode(OpCodeValues.Conv_Ovf_U1_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_U2_Un = new OpCode(OpCodeValues.Conv_Ovf_U2_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_U4_Un = new OpCode(OpCodeValues.Conv_Ovf_U4_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_U8_Un = new OpCode(OpCodeValues.Conv_Ovf_U8_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_I_Un = new OpCode(OpCodeValues.Conv_Ovf_I_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_U_Un = new OpCode(OpCodeValues.Conv_Ovf_U_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Box = new OpCode(OpCodeValues.Box,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Newarr = new OpCode(OpCodeValues.Newarr,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldlen = new OpCode(OpCodeValues.Ldlen,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldelema = new OpCode(OpCodeValues.Ldelema,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldelem_I1 = new OpCode(OpCodeValues.Ldelem_I1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldelem_U1 = new OpCode(OpCodeValues.Ldelem_U1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldelem_I2 = new OpCode(OpCodeValues.Ldelem_I2,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldelem_U2 = new OpCode(OpCodeValues.Ldelem_U2,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldelem_I4 = new OpCode(OpCodeValues.Ldelem_I4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldelem_U4 = new OpCode(OpCodeValues.Ldelem_U4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldelem_I8 = new OpCode(OpCodeValues.Ldelem_I8,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldelem_I = new OpCode(OpCodeValues.Ldelem_I,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldelem_R4 = new OpCode(OpCodeValues.Ldelem_R4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushr4 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldelem_R8 = new OpCode(OpCodeValues.Ldelem_R8,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldelem_Ref = new OpCode(OpCodeValues.Ldelem_Ref,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stelem_I = new OpCode(OpCodeValues.Stelem_I,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-3 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stelem_I1 = new OpCode(OpCodeValues.Stelem_I1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-3 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stelem_I2 = new OpCode(OpCodeValues.Stelem_I2,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-3 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stelem_I4 = new OpCode(OpCodeValues.Stelem_I4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-3 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stelem_I8 = new OpCode(OpCodeValues.Stelem_I8,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi_popi8 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-3 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stelem_R4 = new OpCode(OpCodeValues.Stelem_R4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi_popr4 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-3 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stelem_R8 = new OpCode(OpCodeValues.Stelem_R8,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi_popr8 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-3 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stelem_Ref = new OpCode(OpCodeValues.Stelem_Ref,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi_popref << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-3 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldelem = new OpCode(OpCodeValues.Ldelem,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stelem = new OpCode(OpCodeValues.Stelem,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref_popi_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Unbox_Any = new OpCode(OpCodeValues.Unbox_Any,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_I1 = new OpCode(OpCodeValues.Conv_Ovf_I1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_U1 = new OpCode(OpCodeValues.Conv_Ovf_U1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_I2 = new OpCode(OpCodeValues.Conv_Ovf_I2,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_U2 = new OpCode(OpCodeValues.Conv_Ovf_U2,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_I4 = new OpCode(OpCodeValues.Conv_Ovf_I4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_U4 = new OpCode(OpCodeValues.Conv_Ovf_U4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_I8 = new OpCode(OpCodeValues.Conv_Ovf_I8,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_U8 = new OpCode(OpCodeValues.Conv_Ovf_U8,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Refanyval = new OpCode(OpCodeValues.Refanyval,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ckfinite = new OpCode(OpCodeValues.Ckfinite,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Mkrefany = new OpCode(OpCodeValues.Mkrefany,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldtoken = new OpCode(OpCodeValues.Ldtoken,
- ((int)OperandType.InlineTok) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_U2 = new OpCode(OpCodeValues.Conv_U2,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_U1 = new OpCode(OpCodeValues.Conv_U1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_I = new OpCode(OpCodeValues.Conv_I,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_I = new OpCode(OpCodeValues.Conv_Ovf_I,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_Ovf_U = new OpCode(OpCodeValues.Conv_Ovf_U,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Add_Ovf = new OpCode(OpCodeValues.Add_Ovf,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Add_Ovf_Un = new OpCode(OpCodeValues.Add_Ovf_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Mul_Ovf = new OpCode(OpCodeValues.Mul_Ovf,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Mul_Ovf_Un = new OpCode(OpCodeValues.Mul_Ovf_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Sub_Ovf = new OpCode(OpCodeValues.Sub_Ovf,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Sub_Ovf_Un = new OpCode(OpCodeValues.Sub_Ovf_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Endfinally = new OpCode(OpCodeValues.Endfinally,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Return << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- OpCode.EndsUncondJmpBlkFlag |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Leave = new OpCode(OpCodeValues.Leave,
- ((int)OperandType.InlineBrTarget) |
- ((int)FlowControl.Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- OpCode.EndsUncondJmpBlkFlag |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Leave_S = new OpCode(OpCodeValues.Leave_S,
- ((int)OperandType.ShortInlineBrTarget) |
- ((int)FlowControl.Branch << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- OpCode.EndsUncondJmpBlkFlag |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stind_I = new OpCode(OpCodeValues.Stind_I,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (-2 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Conv_U = new OpCode(OpCodeValues.Conv_U,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Prefix7 = new OpCode(OpCodeValues.Prefix7,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Meta << OpCode.FlowControlShift) |
- ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Prefix6 = new OpCode(OpCodeValues.Prefix6,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Meta << OpCode.FlowControlShift) |
- ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Prefix5 = new OpCode(OpCodeValues.Prefix5,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Meta << OpCode.FlowControlShift) |
- ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Prefix4 = new OpCode(OpCodeValues.Prefix4,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Meta << OpCode.FlowControlShift) |
- ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Prefix3 = new OpCode(OpCodeValues.Prefix3,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Meta << OpCode.FlowControlShift) |
- ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Prefix2 = new OpCode(OpCodeValues.Prefix2,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Meta << OpCode.FlowControlShift) |
- ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Prefix1 = new OpCode(OpCodeValues.Prefix1,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Meta << OpCode.FlowControlShift) |
- ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Prefixref = new OpCode(OpCodeValues.Prefixref,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Meta << OpCode.FlowControlShift) |
- ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (1 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Arglist = new OpCode(OpCodeValues.Arglist,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ceq = new OpCode(OpCodeValues.Ceq,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Cgt = new OpCode(OpCodeValues.Cgt,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Cgt_Un = new OpCode(OpCodeValues.Cgt_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Clt = new OpCode(OpCodeValues.Clt,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Clt_Un = new OpCode(OpCodeValues.Clt_Un,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldftn = new OpCode(OpCodeValues.Ldftn,
- ((int)OperandType.InlineMethod) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldvirtftn = new OpCode(OpCodeValues.Ldvirtftn,
- ((int)OperandType.InlineMethod) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldarg = new OpCode(OpCodeValues.Ldarg,
- ((int)OperandType.InlineVar) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldarga = new OpCode(OpCodeValues.Ldarga,
- ((int)OperandType.InlineVar) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Starg = new OpCode(OpCodeValues.Starg,
- ((int)OperandType.InlineVar) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldloc = new OpCode(OpCodeValues.Ldloc,
- ((int)OperandType.InlineVar) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Ldloca = new OpCode(OpCodeValues.Ldloca,
- ((int)OperandType.InlineVar) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Stloc = new OpCode(OpCodeValues.Stloc,
- ((int)OperandType.InlineVar) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Localloc = new OpCode(OpCodeValues.Localloc,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Endfilter = new OpCode(OpCodeValues.Endfilter,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Return << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- OpCode.EndsUncondJmpBlkFlag |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Unaligned = new OpCode(OpCodeValues.Unaligned_,
- ((int)OperandType.ShortInlineI) |
- ((int)FlowControl.Meta << OpCode.FlowControlShift) |
- ((int)OpCodeType.Prefix << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Volatile = new OpCode(OpCodeValues.Volatile_,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Meta << OpCode.FlowControlShift) |
- ((int)OpCodeType.Prefix << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Tailcall = new OpCode(OpCodeValues.Tail_,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Meta << OpCode.FlowControlShift) |
- ((int)OpCodeType.Prefix << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Initobj = new OpCode(OpCodeValues.Initobj,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (-1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Constrained = new OpCode(OpCodeValues.Constrained_,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Meta << OpCode.FlowControlShift) |
- ((int)OpCodeType.Prefix << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Cpblk = new OpCode(OpCodeValues.Cpblk,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi_popi_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (-3 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Initblk = new OpCode(OpCodeValues.Initblk,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Popi_popi_popi << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (-3 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Rethrow = new OpCode(OpCodeValues.Rethrow,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Throw << OpCode.FlowControlShift) |
- ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- OpCode.EndsUncondJmpBlkFlag |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Sizeof = new OpCode(OpCodeValues.Sizeof,
- ((int)OperandType.InlineType) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (1 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Refanytype = new OpCode(OpCodeValues.Refanytype,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Next << OpCode.FlowControlShift) |
- ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
- public static readonly OpCode Readonly = new OpCode(OpCodeValues.Readonly_,
- ((int)OperandType.InlineNone) |
- ((int)FlowControl.Meta << OpCode.FlowControlShift) |
- ((int)OpCodeType.Prefix << OpCode.OpCodeTypeShift) |
- ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
- ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
- (2 << OpCode.SizeShift) |
- (0 << OpCode.StackChangeShift)
- );
-
-
- public static bool TakesSingleByteArgument(OpCode inst)
+namespace System.Reflection.Emit
+{
+ //
+ // Internal enums for opcode values. Note that the value names are used to construct
+ // publicly visible ilasm-compatible opcode names, so their exact form is important!
+ //
+ internal enum OpCodeValues
+ {
+ Nop = 0x00,
+ Break = 0x01,
+ Ldarg_0 = 0x02,
+ Ldarg_1 = 0x03,
+ Ldarg_2 = 0x04,
+ Ldarg_3 = 0x05,
+ Ldloc_0 = 0x06,
+ Ldloc_1 = 0x07,
+ Ldloc_2 = 0x08,
+ Ldloc_3 = 0x09,
+ Stloc_0 = 0x0a,
+ Stloc_1 = 0x0b,
+ Stloc_2 = 0x0c,
+ Stloc_3 = 0x0d,
+ Ldarg_S = 0x0e,
+ Ldarga_S = 0x0f,
+ Starg_S = 0x10,
+ Ldloc_S = 0x11,
+ Ldloca_S = 0x12,
+ Stloc_S = 0x13,
+ Ldnull = 0x14,
+ Ldc_I4_M1 = 0x15,
+ Ldc_I4_0 = 0x16,
+ Ldc_I4_1 = 0x17,
+ Ldc_I4_2 = 0x18,
+ Ldc_I4_3 = 0x19,
+ Ldc_I4_4 = 0x1a,
+ Ldc_I4_5 = 0x1b,
+ Ldc_I4_6 = 0x1c,
+ Ldc_I4_7 = 0x1d,
+ Ldc_I4_8 = 0x1e,
+ Ldc_I4_S = 0x1f,
+ Ldc_I4 = 0x20,
+ Ldc_I8 = 0x21,
+ Ldc_R4 = 0x22,
+ Ldc_R8 = 0x23,
+ Dup = 0x25,
+ Pop = 0x26,
+ Jmp = 0x27,
+ Call = 0x28,
+ Calli = 0x29,
+ Ret = 0x2a,
+ Br_S = 0x2b,
+ Brfalse_S = 0x2c,
+ Brtrue_S = 0x2d,
+ Beq_S = 0x2e,
+ Bge_S = 0x2f,
+ Bgt_S = 0x30,
+ Ble_S = 0x31,
+ Blt_S = 0x32,
+ Bne_Un_S = 0x33,
+ Bge_Un_S = 0x34,
+ Bgt_Un_S = 0x35,
+ Ble_Un_S = 0x36,
+ Blt_Un_S = 0x37,
+ Br = 0x38,
+ Brfalse = 0x39,
+ Brtrue = 0x3a,
+ Beq = 0x3b,
+ Bge = 0x3c,
+ Bgt = 0x3d,
+ Ble = 0x3e,
+ Blt = 0x3f,
+ Bne_Un = 0x40,
+ Bge_Un = 0x41,
+ Bgt_Un = 0x42,
+ Ble_Un = 0x43,
+ Blt_Un = 0x44,
+ Switch = 0x45,
+ Ldind_I1 = 0x46,
+ Ldind_U1 = 0x47,
+ Ldind_I2 = 0x48,
+ Ldind_U2 = 0x49,
+ Ldind_I4 = 0x4a,
+ Ldind_U4 = 0x4b,
+ Ldind_I8 = 0x4c,
+ Ldind_I = 0x4d,
+ Ldind_R4 = 0x4e,
+ Ldind_R8 = 0x4f,
+ Ldind_Ref = 0x50,
+ Stind_Ref = 0x51,
+ Stind_I1 = 0x52,
+ Stind_I2 = 0x53,
+ Stind_I4 = 0x54,
+ Stind_I8 = 0x55,
+ Stind_R4 = 0x56,
+ Stind_R8 = 0x57,
+ Add = 0x58,
+ Sub = 0x59,
+ Mul = 0x5a,
+ Div = 0x5b,
+ Div_Un = 0x5c,
+ Rem = 0x5d,
+ Rem_Un = 0x5e,
+ And = 0x5f,
+ Or = 0x60,
+ Xor = 0x61,
+ Shl = 0x62,
+ Shr = 0x63,
+ Shr_Un = 0x64,
+ Neg = 0x65,
+ Not = 0x66,
+ Conv_I1 = 0x67,
+ Conv_I2 = 0x68,
+ Conv_I4 = 0x69,
+ Conv_I8 = 0x6a,
+ Conv_R4 = 0x6b,
+ Conv_R8 = 0x6c,
+ Conv_U4 = 0x6d,
+ Conv_U8 = 0x6e,
+ Callvirt = 0x6f,
+ Cpobj = 0x70,
+ Ldobj = 0x71,
+ Ldstr = 0x72,
+ Newobj = 0x73,
+ Castclass = 0x74,
+ Isinst = 0x75,
+ Conv_R_Un = 0x76,
+ Unbox = 0x79,
+ Throw = 0x7a,
+ Ldfld = 0x7b,
+ Ldflda = 0x7c,
+ Stfld = 0x7d,
+ Ldsfld = 0x7e,
+ Ldsflda = 0x7f,
+ Stsfld = 0x80,
+ Stobj = 0x81,
+ Conv_Ovf_I1_Un = 0x82,
+ Conv_Ovf_I2_Un = 0x83,
+ Conv_Ovf_I4_Un = 0x84,
+ Conv_Ovf_I8_Un = 0x85,
+ Conv_Ovf_U1_Un = 0x86,
+ Conv_Ovf_U2_Un = 0x87,
+ Conv_Ovf_U4_Un = 0x88,
+ Conv_Ovf_U8_Un = 0x89,
+ Conv_Ovf_I_Un = 0x8a,
+ Conv_Ovf_U_Un = 0x8b,
+ Box = 0x8c,
+ Newarr = 0x8d,
+ Ldlen = 0x8e,
+ Ldelema = 0x8f,
+ Ldelem_I1 = 0x90,
+ Ldelem_U1 = 0x91,
+ Ldelem_I2 = 0x92,
+ Ldelem_U2 = 0x93,
+ Ldelem_I4 = 0x94,
+ Ldelem_U4 = 0x95,
+ Ldelem_I8 = 0x96,
+ Ldelem_I = 0x97,
+ Ldelem_R4 = 0x98,
+ Ldelem_R8 = 0x99,
+ Ldelem_Ref = 0x9a,
+ Stelem_I = 0x9b,
+ Stelem_I1 = 0x9c,
+ Stelem_I2 = 0x9d,
+ Stelem_I4 = 0x9e,
+ Stelem_I8 = 0x9f,
+ Stelem_R4 = 0xa0,
+ Stelem_R8 = 0xa1,
+ Stelem_Ref = 0xa2,
+ Ldelem = 0xa3,
+ Stelem = 0xa4,
+ Unbox_Any = 0xa5,
+ Conv_Ovf_I1 = 0xb3,
+ Conv_Ovf_U1 = 0xb4,
+ Conv_Ovf_I2 = 0xb5,
+ Conv_Ovf_U2 = 0xb6,
+ Conv_Ovf_I4 = 0xb7,
+ Conv_Ovf_U4 = 0xb8,
+ Conv_Ovf_I8 = 0xb9,
+ Conv_Ovf_U8 = 0xba,
+ Refanyval = 0xc2,
+ Ckfinite = 0xc3,
+ Mkrefany = 0xc6,
+ Ldtoken = 0xd0,
+ Conv_U2 = 0xd1,
+ Conv_U1 = 0xd2,
+ Conv_I = 0xd3,
+ Conv_Ovf_I = 0xd4,
+ Conv_Ovf_U = 0xd5,
+ Add_Ovf = 0xd6,
+ Add_Ovf_Un = 0xd7,
+ Mul_Ovf = 0xd8,
+ Mul_Ovf_Un = 0xd9,
+ Sub_Ovf = 0xda,
+ Sub_Ovf_Un = 0xdb,
+ Endfinally = 0xdc,
+ Leave = 0xdd,
+ Leave_S = 0xde,
+ Stind_I = 0xdf,
+ Conv_U = 0xe0,
+ Prefix7 = 0xf8,
+ Prefix6 = 0xf9,
+ Prefix5 = 0xfa,
+ Prefix4 = 0xfb,
+ Prefix3 = 0xfc,
+ Prefix2 = 0xfd,
+ Prefix1 = 0xfe,
+ Prefixref = 0xff,
+ Arglist = 0xfe00,
+ Ceq = 0xfe01,
+ Cgt = 0xfe02,
+ Cgt_Un = 0xfe03,
+ Clt = 0xfe04,
+ Clt_Un = 0xfe05,
+ Ldftn = 0xfe06,
+ Ldvirtftn = 0xfe07,
+ Ldarg = 0xfe09,
+ Ldarga = 0xfe0a,
+ Starg = 0xfe0b,
+ Ldloc = 0xfe0c,
+ Ldloca = 0xfe0d,
+ Stloc = 0xfe0e,
+ Localloc = 0xfe0f,
+ Endfilter = 0xfe11,
+ Unaligned_ = 0xfe12,
+ Volatile_ = 0xfe13,
+ Tail_ = 0xfe14,
+ Initobj = 0xfe15,
+ Constrained_ = 0xfe16,
+ Cpblk = 0xfe17,
+ Initblk = 0xfe18,
+ Rethrow = 0xfe1a,
+ Sizeof = 0xfe1c,
+ Refanytype = 0xfe1d,
+ Readonly_ = 0xfe1e,
+
+ // If you add more opcodes here, modify OpCode.Name to handle them correctly
+ };
+
+ public class OpCodes
{
- switch (inst.OperandType)
+ /// <summary>
+ /// <para>
+ /// The IL instruction opcodes supported by the
+ /// runtime. The IL Instruction Specification describes each
+ /// Opcode.
+ /// </para>
+ /// </summary>
+ /// <seealso topic='IL Instruction Set Specification'/>
+
+ private OpCodes()
{
- case OperandType.ShortInlineBrTarget :
- case OperandType.ShortInlineI :
- case OperandType.ShortInlineVar :
- return true;
- };
- return false;
+ }
+
+ public static readonly OpCode Nop = new OpCode(OpCodeValues.Nop,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Break = new OpCode(OpCodeValues.Break,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Break << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldarg_0 = new OpCode(OpCodeValues.Ldarg_0,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldarg_1 = new OpCode(OpCodeValues.Ldarg_1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldarg_2 = new OpCode(OpCodeValues.Ldarg_2,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldarg_3 = new OpCode(OpCodeValues.Ldarg_3,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldloc_0 = new OpCode(OpCodeValues.Ldloc_0,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldloc_1 = new OpCode(OpCodeValues.Ldloc_1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldloc_2 = new OpCode(OpCodeValues.Ldloc_2,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldloc_3 = new OpCode(OpCodeValues.Ldloc_3,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stloc_0 = new OpCode(OpCodeValues.Stloc_0,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stloc_1 = new OpCode(OpCodeValues.Stloc_1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stloc_2 = new OpCode(OpCodeValues.Stloc_2,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stloc_3 = new OpCode(OpCodeValues.Stloc_3,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldarg_S = new OpCode(OpCodeValues.Ldarg_S,
+ ((int)OperandType.ShortInlineVar) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldarga_S = new OpCode(OpCodeValues.Ldarga_S,
+ ((int)OperandType.ShortInlineVar) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Starg_S = new OpCode(OpCodeValues.Starg_S,
+ ((int)OperandType.ShortInlineVar) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldloc_S = new OpCode(OpCodeValues.Ldloc_S,
+ ((int)OperandType.ShortInlineVar) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldloca_S = new OpCode(OpCodeValues.Ldloca_S,
+ ((int)OperandType.ShortInlineVar) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stloc_S = new OpCode(OpCodeValues.Stloc_S,
+ ((int)OperandType.ShortInlineVar) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldnull = new OpCode(OpCodeValues.Ldnull,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldc_I4_M1 = new OpCode(OpCodeValues.Ldc_I4_M1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldc_I4_0 = new OpCode(OpCodeValues.Ldc_I4_0,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldc_I4_1 = new OpCode(OpCodeValues.Ldc_I4_1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldc_I4_2 = new OpCode(OpCodeValues.Ldc_I4_2,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldc_I4_3 = new OpCode(OpCodeValues.Ldc_I4_3,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldc_I4_4 = new OpCode(OpCodeValues.Ldc_I4_4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldc_I4_5 = new OpCode(OpCodeValues.Ldc_I4_5,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldc_I4_6 = new OpCode(OpCodeValues.Ldc_I4_6,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldc_I4_7 = new OpCode(OpCodeValues.Ldc_I4_7,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldc_I4_8 = new OpCode(OpCodeValues.Ldc_I4_8,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldc_I4_S = new OpCode(OpCodeValues.Ldc_I4_S,
+ ((int)OperandType.ShortInlineI) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldc_I4 = new OpCode(OpCodeValues.Ldc_I4,
+ ((int)OperandType.InlineI) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldc_I8 = new OpCode(OpCodeValues.Ldc_I8,
+ ((int)OperandType.InlineI8) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldc_R4 = new OpCode(OpCodeValues.Ldc_R4,
+ ((int)OperandType.ShortInlineR) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushr4 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldc_R8 = new OpCode(OpCodeValues.Ldc_R8,
+ ((int)OperandType.InlineR) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Dup = new OpCode(OpCodeValues.Dup,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1_push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Pop = new OpCode(OpCodeValues.Pop,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Jmp = new OpCode(OpCodeValues.Jmp,
+ ((int)OperandType.InlineMethod) |
+ ((int)FlowControl.Call << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ OpCode.EndsUncondJmpBlkFlag |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Call = new OpCode(OpCodeValues.Call,
+ ((int)OperandType.InlineMethod) |
+ ((int)FlowControl.Call << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Varpop << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Varpush << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Calli = new OpCode(OpCodeValues.Calli,
+ ((int)OperandType.InlineSig) |
+ ((int)FlowControl.Call << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Varpop << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Varpush << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ret = new OpCode(OpCodeValues.Ret,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Return << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Varpop << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ OpCode.EndsUncondJmpBlkFlag |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Br_S = new OpCode(OpCodeValues.Br_S,
+ ((int)OperandType.ShortInlineBrTarget) |
+ ((int)FlowControl.Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ OpCode.EndsUncondJmpBlkFlag |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Brfalse_S = new OpCode(OpCodeValues.Brfalse_S,
+ ((int)OperandType.ShortInlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Brtrue_S = new OpCode(OpCodeValues.Brtrue_S,
+ ((int)OperandType.ShortInlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Beq_S = new OpCode(OpCodeValues.Beq_S,
+ ((int)OperandType.ShortInlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Bge_S = new OpCode(OpCodeValues.Bge_S,
+ ((int)OperandType.ShortInlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Bgt_S = new OpCode(OpCodeValues.Bgt_S,
+ ((int)OperandType.ShortInlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ble_S = new OpCode(OpCodeValues.Ble_S,
+ ((int)OperandType.ShortInlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Blt_S = new OpCode(OpCodeValues.Blt_S,
+ ((int)OperandType.ShortInlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Bne_Un_S = new OpCode(OpCodeValues.Bne_Un_S,
+ ((int)OperandType.ShortInlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Bge_Un_S = new OpCode(OpCodeValues.Bge_Un_S,
+ ((int)OperandType.ShortInlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Bgt_Un_S = new OpCode(OpCodeValues.Bgt_Un_S,
+ ((int)OperandType.ShortInlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ble_Un_S = new OpCode(OpCodeValues.Ble_Un_S,
+ ((int)OperandType.ShortInlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Blt_Un_S = new OpCode(OpCodeValues.Blt_Un_S,
+ ((int)OperandType.ShortInlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Br = new OpCode(OpCodeValues.Br,
+ ((int)OperandType.InlineBrTarget) |
+ ((int)FlowControl.Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ OpCode.EndsUncondJmpBlkFlag |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Brfalse = new OpCode(OpCodeValues.Brfalse,
+ ((int)OperandType.InlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Brtrue = new OpCode(OpCodeValues.Brtrue,
+ ((int)OperandType.InlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Beq = new OpCode(OpCodeValues.Beq,
+ ((int)OperandType.InlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Bge = new OpCode(OpCodeValues.Bge,
+ ((int)OperandType.InlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Bgt = new OpCode(OpCodeValues.Bgt,
+ ((int)OperandType.InlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ble = new OpCode(OpCodeValues.Ble,
+ ((int)OperandType.InlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Blt = new OpCode(OpCodeValues.Blt,
+ ((int)OperandType.InlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Bne_Un = new OpCode(OpCodeValues.Bne_Un,
+ ((int)OperandType.InlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Bge_Un = new OpCode(OpCodeValues.Bge_Un,
+ ((int)OperandType.InlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Bgt_Un = new OpCode(OpCodeValues.Bgt_Un,
+ ((int)OperandType.InlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ble_Un = new OpCode(OpCodeValues.Ble_Un,
+ ((int)OperandType.InlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Blt_Un = new OpCode(OpCodeValues.Blt_Un,
+ ((int)OperandType.InlineBrTarget) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Switch = new OpCode(OpCodeValues.Switch,
+ ((int)OperandType.InlineSwitch) |
+ ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldind_I1 = new OpCode(OpCodeValues.Ldind_I1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldind_U1 = new OpCode(OpCodeValues.Ldind_U1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldind_I2 = new OpCode(OpCodeValues.Ldind_I2,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldind_U2 = new OpCode(OpCodeValues.Ldind_U2,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldind_I4 = new OpCode(OpCodeValues.Ldind_I4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldind_U4 = new OpCode(OpCodeValues.Ldind_U4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldind_I8 = new OpCode(OpCodeValues.Ldind_I8,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldind_I = new OpCode(OpCodeValues.Ldind_I,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldind_R4 = new OpCode(OpCodeValues.Ldind_R4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushr4 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldind_R8 = new OpCode(OpCodeValues.Ldind_R8,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldind_Ref = new OpCode(OpCodeValues.Ldind_Ref,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stind_Ref = new OpCode(OpCodeValues.Stind_Ref,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stind_I1 = new OpCode(OpCodeValues.Stind_I1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stind_I2 = new OpCode(OpCodeValues.Stind_I2,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stind_I4 = new OpCode(OpCodeValues.Stind_I4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stind_I8 = new OpCode(OpCodeValues.Stind_I8,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi_popi8 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stind_R4 = new OpCode(OpCodeValues.Stind_R4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi_popr4 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stind_R8 = new OpCode(OpCodeValues.Stind_R8,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi_popr8 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Add = new OpCode(OpCodeValues.Add,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Sub = new OpCode(OpCodeValues.Sub,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Mul = new OpCode(OpCodeValues.Mul,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Div = new OpCode(OpCodeValues.Div,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Div_Un = new OpCode(OpCodeValues.Div_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Rem = new OpCode(OpCodeValues.Rem,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Rem_Un = new OpCode(OpCodeValues.Rem_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode And = new OpCode(OpCodeValues.And,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Or = new OpCode(OpCodeValues.Or,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Xor = new OpCode(OpCodeValues.Xor,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Shl = new OpCode(OpCodeValues.Shl,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Shr = new OpCode(OpCodeValues.Shr,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Shr_Un = new OpCode(OpCodeValues.Shr_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Neg = new OpCode(OpCodeValues.Neg,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Not = new OpCode(OpCodeValues.Not,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_I1 = new OpCode(OpCodeValues.Conv_I1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_I2 = new OpCode(OpCodeValues.Conv_I2,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_I4 = new OpCode(OpCodeValues.Conv_I4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_I8 = new OpCode(OpCodeValues.Conv_I8,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_R4 = new OpCode(OpCodeValues.Conv_R4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushr4 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_R8 = new OpCode(OpCodeValues.Conv_R8,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_U4 = new OpCode(OpCodeValues.Conv_U4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_U8 = new OpCode(OpCodeValues.Conv_U8,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Callvirt = new OpCode(OpCodeValues.Callvirt,
+ ((int)OperandType.InlineMethod) |
+ ((int)FlowControl.Call << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Varpop << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Varpush << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Cpobj = new OpCode(OpCodeValues.Cpobj,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldobj = new OpCode(OpCodeValues.Ldobj,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldstr = new OpCode(OpCodeValues.Ldstr,
+ ((int)OperandType.InlineString) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Newobj = new OpCode(OpCodeValues.Newobj,
+ ((int)OperandType.InlineMethod) |
+ ((int)FlowControl.Call << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Varpop << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Castclass = new OpCode(OpCodeValues.Castclass,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Isinst = new OpCode(OpCodeValues.Isinst,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_R_Un = new OpCode(OpCodeValues.Conv_R_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Unbox = new OpCode(OpCodeValues.Unbox,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Throw = new OpCode(OpCodeValues.Throw,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Throw << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ OpCode.EndsUncondJmpBlkFlag |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldfld = new OpCode(OpCodeValues.Ldfld,
+ ((int)OperandType.InlineField) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldflda = new OpCode(OpCodeValues.Ldflda,
+ ((int)OperandType.InlineField) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stfld = new OpCode(OpCodeValues.Stfld,
+ ((int)OperandType.InlineField) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldsfld = new OpCode(OpCodeValues.Ldsfld,
+ ((int)OperandType.InlineField) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldsflda = new OpCode(OpCodeValues.Ldsflda,
+ ((int)OperandType.InlineField) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stsfld = new OpCode(OpCodeValues.Stsfld,
+ ((int)OperandType.InlineField) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stobj = new OpCode(OpCodeValues.Stobj,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_I1_Un = new OpCode(OpCodeValues.Conv_Ovf_I1_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_I2_Un = new OpCode(OpCodeValues.Conv_Ovf_I2_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_I4_Un = new OpCode(OpCodeValues.Conv_Ovf_I4_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_I8_Un = new OpCode(OpCodeValues.Conv_Ovf_I8_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_U1_Un = new OpCode(OpCodeValues.Conv_Ovf_U1_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_U2_Un = new OpCode(OpCodeValues.Conv_Ovf_U2_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_U4_Un = new OpCode(OpCodeValues.Conv_Ovf_U4_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_U8_Un = new OpCode(OpCodeValues.Conv_Ovf_U8_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_I_Un = new OpCode(OpCodeValues.Conv_Ovf_I_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_U_Un = new OpCode(OpCodeValues.Conv_Ovf_U_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Box = new OpCode(OpCodeValues.Box,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Newarr = new OpCode(OpCodeValues.Newarr,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldlen = new OpCode(OpCodeValues.Ldlen,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldelema = new OpCode(OpCodeValues.Ldelema,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldelem_I1 = new OpCode(OpCodeValues.Ldelem_I1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldelem_U1 = new OpCode(OpCodeValues.Ldelem_U1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldelem_I2 = new OpCode(OpCodeValues.Ldelem_I2,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldelem_U2 = new OpCode(OpCodeValues.Ldelem_U2,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldelem_I4 = new OpCode(OpCodeValues.Ldelem_I4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldelem_U4 = new OpCode(OpCodeValues.Ldelem_U4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldelem_I8 = new OpCode(OpCodeValues.Ldelem_I8,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldelem_I = new OpCode(OpCodeValues.Ldelem_I,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldelem_R4 = new OpCode(OpCodeValues.Ldelem_R4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushr4 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldelem_R8 = new OpCode(OpCodeValues.Ldelem_R8,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldelem_Ref = new OpCode(OpCodeValues.Ldelem_Ref,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stelem_I = new OpCode(OpCodeValues.Stelem_I,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-3 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stelem_I1 = new OpCode(OpCodeValues.Stelem_I1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-3 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stelem_I2 = new OpCode(OpCodeValues.Stelem_I2,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-3 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stelem_I4 = new OpCode(OpCodeValues.Stelem_I4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-3 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stelem_I8 = new OpCode(OpCodeValues.Stelem_I8,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi_popi8 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-3 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stelem_R4 = new OpCode(OpCodeValues.Stelem_R4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi_popr4 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-3 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stelem_R8 = new OpCode(OpCodeValues.Stelem_R8,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi_popr8 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-3 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stelem_Ref = new OpCode(OpCodeValues.Stelem_Ref,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi_popref << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-3 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldelem = new OpCode(OpCodeValues.Ldelem,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stelem = new OpCode(OpCodeValues.Stelem,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref_popi_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Unbox_Any = new OpCode(OpCodeValues.Unbox_Any,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_I1 = new OpCode(OpCodeValues.Conv_Ovf_I1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_U1 = new OpCode(OpCodeValues.Conv_Ovf_U1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_I2 = new OpCode(OpCodeValues.Conv_Ovf_I2,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_U2 = new OpCode(OpCodeValues.Conv_Ovf_U2,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_I4 = new OpCode(OpCodeValues.Conv_Ovf_I4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_U4 = new OpCode(OpCodeValues.Conv_Ovf_U4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_I8 = new OpCode(OpCodeValues.Conv_Ovf_I8,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_U8 = new OpCode(OpCodeValues.Conv_Ovf_U8,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Refanyval = new OpCode(OpCodeValues.Refanyval,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ckfinite = new OpCode(OpCodeValues.Ckfinite,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Mkrefany = new OpCode(OpCodeValues.Mkrefany,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldtoken = new OpCode(OpCodeValues.Ldtoken,
+ ((int)OperandType.InlineTok) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_U2 = new OpCode(OpCodeValues.Conv_U2,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_U1 = new OpCode(OpCodeValues.Conv_U1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_I = new OpCode(OpCodeValues.Conv_I,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_I = new OpCode(OpCodeValues.Conv_Ovf_I,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_Ovf_U = new OpCode(OpCodeValues.Conv_Ovf_U,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Add_Ovf = new OpCode(OpCodeValues.Add_Ovf,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Add_Ovf_Un = new OpCode(OpCodeValues.Add_Ovf_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Mul_Ovf = new OpCode(OpCodeValues.Mul_Ovf,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Mul_Ovf_Un = new OpCode(OpCodeValues.Mul_Ovf_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Sub_Ovf = new OpCode(OpCodeValues.Sub_Ovf,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Sub_Ovf_Un = new OpCode(OpCodeValues.Sub_Ovf_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Endfinally = new OpCode(OpCodeValues.Endfinally,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Return << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ OpCode.EndsUncondJmpBlkFlag |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Leave = new OpCode(OpCodeValues.Leave,
+ ((int)OperandType.InlineBrTarget) |
+ ((int)FlowControl.Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ OpCode.EndsUncondJmpBlkFlag |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Leave_S = new OpCode(OpCodeValues.Leave_S,
+ ((int)OperandType.ShortInlineBrTarget) |
+ ((int)FlowControl.Branch << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ OpCode.EndsUncondJmpBlkFlag |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stind_I = new OpCode(OpCodeValues.Stind_I,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (-2 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Conv_U = new OpCode(OpCodeValues.Conv_U,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Prefix7 = new OpCode(OpCodeValues.Prefix7,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Meta << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Prefix6 = new OpCode(OpCodeValues.Prefix6,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Meta << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Prefix5 = new OpCode(OpCodeValues.Prefix5,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Meta << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Prefix4 = new OpCode(OpCodeValues.Prefix4,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Meta << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Prefix3 = new OpCode(OpCodeValues.Prefix3,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Meta << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Prefix2 = new OpCode(OpCodeValues.Prefix2,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Meta << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Prefix1 = new OpCode(OpCodeValues.Prefix1,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Meta << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Prefixref = new OpCode(OpCodeValues.Prefixref,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Meta << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (1 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Arglist = new OpCode(OpCodeValues.Arglist,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ceq = new OpCode(OpCodeValues.Ceq,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Cgt = new OpCode(OpCodeValues.Cgt,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Cgt_Un = new OpCode(OpCodeValues.Cgt_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Clt = new OpCode(OpCodeValues.Clt,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Clt_Un = new OpCode(OpCodeValues.Clt_Un,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldftn = new OpCode(OpCodeValues.Ldftn,
+ ((int)OperandType.InlineMethod) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldvirtftn = new OpCode(OpCodeValues.Ldvirtftn,
+ ((int)OperandType.InlineMethod) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldarg = new OpCode(OpCodeValues.Ldarg,
+ ((int)OperandType.InlineVar) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldarga = new OpCode(OpCodeValues.Ldarga,
+ ((int)OperandType.InlineVar) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Starg = new OpCode(OpCodeValues.Starg,
+ ((int)OperandType.InlineVar) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldloc = new OpCode(OpCodeValues.Ldloc,
+ ((int)OperandType.InlineVar) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Ldloca = new OpCode(OpCodeValues.Ldloca,
+ ((int)OperandType.InlineVar) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Stloc = new OpCode(OpCodeValues.Stloc,
+ ((int)OperandType.InlineVar) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Localloc = new OpCode(OpCodeValues.Localloc,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Endfilter = new OpCode(OpCodeValues.Endfilter,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Return << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ OpCode.EndsUncondJmpBlkFlag |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Unaligned = new OpCode(OpCodeValues.Unaligned_,
+ ((int)OperandType.ShortInlineI) |
+ ((int)FlowControl.Meta << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Prefix << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Volatile = new OpCode(OpCodeValues.Volatile_,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Meta << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Prefix << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Tailcall = new OpCode(OpCodeValues.Tail_,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Meta << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Prefix << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Initobj = new OpCode(OpCodeValues.Initobj,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (-1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Constrained = new OpCode(OpCodeValues.Constrained_,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Meta << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Prefix << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Cpblk = new OpCode(OpCodeValues.Cpblk,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi_popi_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (-3 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Initblk = new OpCode(OpCodeValues.Initblk,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Popi_popi_popi << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (-3 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Rethrow = new OpCode(OpCodeValues.Rethrow,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Throw << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ OpCode.EndsUncondJmpBlkFlag |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Sizeof = new OpCode(OpCodeValues.Sizeof,
+ ((int)OperandType.InlineType) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (1 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Refanytype = new OpCode(OpCodeValues.Refanytype,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Next << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+ public static readonly OpCode Readonly = new OpCode(OpCodeValues.Readonly_,
+ ((int)OperandType.InlineNone) |
+ ((int)FlowControl.Meta << OpCode.FlowControlShift) |
+ ((int)OpCodeType.Prefix << OpCode.OpCodeTypeShift) |
+ ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) |
+ ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) |
+ (2 << OpCode.SizeShift) |
+ (0 << OpCode.StackChangeShift)
+ );
+
+
+ public static bool TakesSingleByteArgument(OpCode inst)
+ {
+ switch (inst.OperandType)
+ {
+ case OperandType.ShortInlineBrTarget:
+ case OperandType.ShortInlineI:
+ case OperandType.ShortInlineVar:
+ return true;
+ };
+ return false;
+ }
}
}
-}
diff --git a/src/mscorlib/src/System/Reflection/Emit/Opcode.cs b/src/mscorlib/src/System/Reflection/Emit/Opcode.cs
index 74a9de16b6..37768be9d7 100644
--- a/src/mscorlib/src/System/Reflection/Emit/Opcode.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/Opcode.cs
@@ -2,191 +2,196 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Reflection.Emit {
using System;
using System.Threading;
using System.Diagnostics.Contracts;
-public struct OpCode
+namespace System.Reflection.Emit
{
- //
- // Use packed bitfield for flags to avoid code bloat
- //
-
- internal const int OperandTypeMask = 0x1F; // 000000000000000000000000000XXXXX
-
- internal const int FlowControlShift = 5; // 00000000000000000000000XXXX00000
- internal const int FlowControlMask = 0x0F;
+ public struct OpCode
+ {
+ //
+ // Use packed bitfield for flags to avoid code bloat
+ //
- internal const int OpCodeTypeShift = 9; // 00000000000000000000XXX000000000
- internal const int OpCodeTypeMask = 0x07;
+ internal const int OperandTypeMask = 0x1F; // 000000000000000000000000000XXXXX
- internal const int StackBehaviourPopShift = 12; // 000000000000000XXXXX000000000000
- internal const int StackBehaviourPushShift = 17; // 0000000000XXXXX00000000000000000
- internal const int StackBehaviourMask = 0x1F;
+ internal const int FlowControlShift = 5; // 00000000000000000000000XXXX00000
+ internal const int FlowControlMask = 0x0F;
- internal const int SizeShift = 22; // 00000000XX0000000000000000000000
- internal const int SizeMask = 0x03;
+ internal const int OpCodeTypeShift = 9; // 00000000000000000000XXX000000000
+ internal const int OpCodeTypeMask = 0x07;
- internal const int EndsUncondJmpBlkFlag = 0x01000000; // 0000000X000000000000000000000000
+ internal const int StackBehaviourPopShift = 12; // 000000000000000XXXXX000000000000
+ internal const int StackBehaviourPushShift = 17; // 0000000000XXXXX00000000000000000
+ internal const int StackBehaviourMask = 0x1F;
- // unused // 0000XXX0000000000000000000000000
+ internal const int SizeShift = 22; // 00000000XX0000000000000000000000
+ internal const int SizeMask = 0x03;
- internal const int StackChangeShift = 28; // XXXX0000000000000000000000000000
+ internal const int EndsUncondJmpBlkFlag = 0x01000000; // 0000000X000000000000000000000000
- private OpCodeValues m_value;
- private int m_flags;
+ // unused // 0000XXX0000000000000000000000000
- internal OpCode(OpCodeValues value, int flags)
- {
- m_value = value;
- m_flags = flags;
- }
+ internal const int StackChangeShift = 28; // XXXX0000000000000000000000000000
- internal bool EndsUncondJmpBlk()
- {
- return (m_flags & EndsUncondJmpBlkFlag) != 0;
- }
-
- internal int StackChange()
- {
- return (m_flags >> StackChangeShift);
- }
+ private OpCodeValues m_value;
+ private int m_flags;
- public OperandType OperandType
- {
- get
+ internal OpCode(OpCodeValues value, int flags)
{
- return (OperandType)(m_flags & OperandTypeMask);
+ m_value = value;
+ m_flags = flags;
}
- }
- public FlowControl FlowControl
- {
- get
+ internal bool EndsUncondJmpBlk()
{
- return (FlowControl)((m_flags >> FlowControlShift) & FlowControlMask);
+ return (m_flags & EndsUncondJmpBlkFlag) != 0;
}
- }
- public OpCodeType OpCodeType
- {
- get
+ internal int StackChange()
{
- return (OpCodeType)((m_flags >> OpCodeTypeShift) & OpCodeTypeMask);
+ return (m_flags >> StackChangeShift);
}
- }
- public StackBehaviour StackBehaviourPop
- {
- get
+ public OperandType OperandType
{
- return (StackBehaviour)((m_flags >> StackBehaviourPopShift) & StackBehaviourMask);
+ get
+ {
+ return (OperandType)(m_flags & OperandTypeMask);
+ }
}
- }
- public StackBehaviour StackBehaviourPush
- {
- get
+ public FlowControl FlowControl
{
- return (StackBehaviour)((m_flags >> StackBehaviourPushShift) & StackBehaviourMask);
+ get
+ {
+ return (FlowControl)((m_flags >> FlowControlShift) & FlowControlMask);
+ }
}
- }
- public int Size
- {
- get
+ public OpCodeType OpCodeType
{
- return (m_flags >> SizeShift) & SizeMask;
+ get
+ {
+ return (OpCodeType)((m_flags >> OpCodeTypeShift) & OpCodeTypeMask);
+ }
}
- }
- public short Value
- {
- get
+ public StackBehaviour StackBehaviourPop
{
- return (short)m_value;
+ get
+ {
+ return (StackBehaviour)((m_flags >> StackBehaviourPopShift) & StackBehaviourMask);
+ }
}
- }
- private static volatile string[] g_nameCache;
+ public StackBehaviour StackBehaviourPush
+ {
+ get
+ {
+ return (StackBehaviour)((m_flags >> StackBehaviourPushShift) & StackBehaviourMask);
+ }
+ }
- public String Name
- {
- get
+ public int Size
{
- if (Size == 0)
- return null;
+ get
+ {
+ return (m_flags >> SizeShift) & SizeMask;
+ }
+ }
- // Create and cache the opcode names lazily. They should be rarely used (only for logging, etc.)
- // Note that we do not any locks here because of we always get the same names. The last one wins.
- string[] nameCache = g_nameCache;
- if (nameCache == null) {
- nameCache = new String[0x11f];
- g_nameCache = nameCache;
+ public short Value
+ {
+ get
+ {
+ return (short)m_value;
}
+ }
- OpCodeValues opCodeValue = (OpCodeValues)(ushort)Value;
+ private static volatile string[] g_nameCache;
- int idx = (int)opCodeValue;
- if (idx > 0xFF) {
- if (idx >= 0xfe00 && idx <= 0xfe1e) {
- // Transform two byte opcode value to lower range that's suitable
- // for array index
- idx = 0x100 + (idx - 0xfe00);
- }
- else {
- // Unknown opcode
+ public String Name
+ {
+ get
+ {
+ if (Size == 0)
return null;
+
+ // Create and cache the opcode names lazily. They should be rarely used (only for logging, etc.)
+ // Note that we do not any locks here because of we always get the same names. The last one wins.
+ string[] nameCache = g_nameCache;
+ if (nameCache == null)
+ {
+ nameCache = new String[0x11f];
+ g_nameCache = nameCache;
}
- }
- String name = Volatile.Read(ref nameCache[idx]);
- if (name != null)
- return name;
+ OpCodeValues opCodeValue = (OpCodeValues)(ushort)Value;
+
+ int idx = (int)opCodeValue;
+ if (idx > 0xFF)
+ {
+ if (idx >= 0xfe00 && idx <= 0xfe1e)
+ {
+ // Transform two byte opcode value to lower range that's suitable
+ // for array index
+ idx = 0x100 + (idx - 0xfe00);
+ }
+ else
+ {
+ // Unknown opcode
+ return null;
+ }
+ }
- // Create ilasm style name from the enum value name.
- name = Enum.GetName(typeof(OpCodeValues), opCodeValue).ToLowerInvariant().Replace("_", ".");
- Volatile.Write(ref nameCache[idx], name);
- return name;
+ String name = Volatile.Read(ref nameCache[idx]);
+ if (name != null)
+ return name;
+
+ // Create ilasm style name from the enum value name.
+ name = Enum.GetName(typeof(OpCodeValues), opCodeValue).ToLowerInvariant().Replace("_", ".");
+ Volatile.Write(ref nameCache[idx], name);
+ return name;
+ }
}
- }
- [Pure]
- public override bool Equals(Object obj)
- {
- if (obj is OpCode)
- return Equals((OpCode)obj);
- else
- return false;
- }
+ [Pure]
+ public override bool Equals(Object obj)
+ {
+ if (obj is OpCode)
+ return Equals((OpCode)obj);
+ else
+ return false;
+ }
- [Pure]
- public bool Equals(OpCode obj)
- {
- return obj.Value == Value;
- }
+ [Pure]
+ public bool Equals(OpCode obj)
+ {
+ return obj.Value == Value;
+ }
- [Pure]
- public static bool operator ==(OpCode a, OpCode b)
- {
- return a.Equals(b);
- }
+ [Pure]
+ public static bool operator ==(OpCode a, OpCode b)
+ {
+ return a.Equals(b);
+ }
- [Pure]
- public static bool operator !=(OpCode a, OpCode b)
- {
- return !(a == b);
- }
+ [Pure]
+ public static bool operator !=(OpCode a, OpCode b)
+ {
+ return !(a == b);
+ }
- public override int GetHashCode()
- {
- return Value;
- }
+ public override int GetHashCode()
+ {
+ return Value;
+ }
- public override String ToString()
- {
- return Name;
+ public override String ToString()
+ {
+ return Name;
+ }
}
}
-}
diff --git a/src/mscorlib/src/System/Reflection/Emit/OpcodeType.cs b/src/mscorlib/src/System/Reflection/Emit/OpcodeType.cs
index 87dea058e5..2363d607fc 100644
--- a/src/mscorlib/src/System/Reflection/Emit/OpcodeType.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/OpcodeType.cs
@@ -12,20 +12,20 @@
** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND!
** See opcodegen.pl for more information.**
============================================================*/
-namespace System.Reflection.Emit {
using System;
-[Serializable]
-public enum OpCodeType
+namespace System.Reflection.Emit
{
-
- [Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")]
- Annotation = 0,
- Macro = 1,
- Nternal = 2,
- Objmodel = 3,
- Prefix = 4,
- Primitive = 5,
-}
+ [Serializable]
+ public enum OpCodeType
+ {
+ [Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")]
+ Annotation = 0,
+ Macro = 1,
+ Nternal = 2,
+ Objmodel = 3,
+ Prefix = 4,
+ Primitive = 5,
+ }
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/OperandType.cs b/src/mscorlib/src/System/Reflection/Emit/OperandType.cs
index e972e8603d..033539b999 100644
--- a/src/mscorlib/src/System/Reflection/Emit/OperandType.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/OperandType.cs
@@ -12,32 +12,32 @@
** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND!
** See opcodegen.pl for more information.**
============================================================*/
-namespace System.Reflection.Emit {
using System;
-[Serializable]
-public enum OperandType
+namespace System.Reflection.Emit
{
-
- InlineBrTarget = 0,
- InlineField = 1,
- InlineI = 2,
- InlineI8 = 3,
- InlineMethod = 4,
- InlineNone = 5,
- [Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")]
- InlinePhi = 6,
- InlineR = 7,
- InlineSig = 9,
- InlineString = 10,
- InlineSwitch = 11,
- InlineTok = 12,
- InlineType = 13,
- InlineVar = 14,
- ShortInlineBrTarget = 15,
- ShortInlineI = 16,
- ShortInlineR = 17,
- ShortInlineVar = 18,
-}
+ [Serializable]
+ public enum OperandType
+ {
+ InlineBrTarget = 0,
+ InlineField = 1,
+ InlineI = 2,
+ InlineI8 = 3,
+ InlineMethod = 4,
+ InlineNone = 5,
+ [Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")]
+ InlinePhi = 6,
+ InlineR = 7,
+ InlineSig = 9,
+ InlineString = 10,
+ InlineSwitch = 11,
+ InlineTok = 12,
+ InlineType = 13,
+ InlineVar = 14,
+ ShortInlineBrTarget = 15,
+ ShortInlineI = 16,
+ ShortInlineR = 17,
+ ShortInlineVar = 18,
+ }
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/PEFileKinds.cs b/src/mscorlib/src/System/Reflection/Emit/PEFileKinds.cs
index 531ff41dd7..f9246fce6d 100644
--- a/src/mscorlib/src/System/Reflection/Emit/PEFileKinds.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/PEFileKinds.cs
@@ -2,14 +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.
-namespace System.Reflection.Emit {
-
- using System;
+
+using System;
+
+namespace System.Reflection.Emit
+{
// This Enum matchs the CorFieldAttr defined in CorHdr.h
[Serializable]
public enum PEFileKinds
{
- Dll = 0x0001,
+ Dll = 0x0001,
ConsoleApplication = 0x0002,
WindowApplication = 0x0003,
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/ParameterBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/ParameterBuilder.cs
index 1b3babf595..636825956a 100644
--- a/src/mscorlib/src/System/Reflection/Emit/ParameterBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/ParameterBuilder.cs
@@ -12,17 +12,18 @@
**
**
===========================================================*/
-namespace System.Reflection.Emit {
- using System.Runtime.InteropServices;
- using System;
- using System.Reflection;
- using System.Diagnostics.Contracts;
+using System.Runtime.InteropServices;
+using System;
+using System.Reflection;
+using System.Diagnostics.Contracts;
+
+namespace System.Reflection.Emit
+{
public class ParameterBuilder
{
-
// Set the default value of the parameter
- public virtual void SetConstant(Object defaultValue)
+ public virtual void SetConstant(Object defaultValue)
{
TypeBuilder.SetConstantValue(
m_methodBuilder.GetModuleBuilder(),
@@ -30,7 +31,7 @@ namespace System.Reflection.Emit {
m_iPosition == 0 ? m_methodBuilder.ReturnType : m_methodBuilder.m_parameterTypes[m_iPosition - 1],
defaultValue);
}
-
+
// Use this function if client decides to form the custom attribute blob themselves
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
@@ -44,7 +45,7 @@ namespace System.Reflection.Emit {
TypeBuilder.DefineCustomAttribute(
m_methodBuilder.GetModuleBuilder(),
m_pdToken.Token,
- ((ModuleBuilder )m_methodBuilder.GetModule()).GetConstructorToken(con).Token,
+ ((ModuleBuilder)m_methodBuilder.GetModule()).GetConstructorToken(con).Token,
binaryAttribute,
false, false);
}
@@ -57,65 +58,71 @@ namespace System.Reflection.Emit {
throw new ArgumentNullException(nameof(customBuilder));
}
Contract.EndContractBlock();
- customBuilder.CreateCustomAttribute((ModuleBuilder) (m_methodBuilder .GetModule()), m_pdToken.Token);
+ customBuilder.CreateCustomAttribute((ModuleBuilder)(m_methodBuilder.GetModule()), m_pdToken.Token);
}
-
+
//*******************************
// Make a private constructor so these cannot be constructed externally.
//*******************************
- private ParameterBuilder() {}
+ private ParameterBuilder() { }
internal ParameterBuilder(
- MethodBuilder methodBuilder,
- int sequence,
- ParameterAttributes attributes,
- String strParamName) // can be NULL string
+ MethodBuilder methodBuilder,
+ int sequence,
+ ParameterAttributes attributes,
+ String strParamName) // can be NULL string
{
m_iPosition = sequence;
m_strParamName = strParamName;
m_methodBuilder = methodBuilder;
m_strParamName = strParamName;
m_attributes = attributes;
- m_pdToken = new ParameterToken( TypeBuilder.SetParamInfo(
+ m_pdToken = new ParameterToken(TypeBuilder.SetParamInfo(
m_methodBuilder.GetModuleBuilder().GetNativeHandle(),
- m_methodBuilder.GetToken().Token,
- sequence,
- attributes,
+ m_methodBuilder.GetToken().Token,
+ sequence,
+ attributes,
strParamName));
}
-
+
public virtual ParameterToken GetToken()
{
return m_pdToken;
- }
-
- public virtual String Name {
- get {return m_strParamName;}
}
-
- public virtual int Position {
- get {return m_iPosition;}
+
+ public virtual String Name
+ {
+ get { return m_strParamName; }
+ }
+
+ public virtual int Position
+ {
+ get { return m_iPosition; }
}
-
- public virtual int Attributes {
- get {return (int) m_attributes;}
+
+ public virtual int Attributes
+ {
+ get { return (int)m_attributes; }
}
-
- public bool IsIn {
- get {return ((m_attributes & ParameterAttributes.In) != 0);}
+
+ public bool IsIn
+ {
+ get { return ((m_attributes & ParameterAttributes.In) != 0); }
}
- public bool IsOut {
- get {return ((m_attributes & ParameterAttributes.Out) != 0);}
+ public bool IsOut
+ {
+ get { return ((m_attributes & ParameterAttributes.Out) != 0); }
}
- public bool IsOptional {
- get {return ((m_attributes & ParameterAttributes.Optional) != 0);}
+ public bool IsOptional
+ {
+ get { return ((m_attributes & ParameterAttributes.Optional) != 0); }
}
-
- private String m_strParamName;
- private int m_iPosition;
+
+ private String m_strParamName;
+ private int m_iPosition;
private ParameterAttributes m_attributes;
- private MethodBuilder m_methodBuilder;
- private ParameterToken m_pdToken;
+ private MethodBuilder m_methodBuilder;
+ private ParameterToken m_pdToken;
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/ParameterToken.cs b/src/mscorlib/src/System/Reflection/Emit/ParameterToken.cs
index a4a32a51fb..42f85af464 100644
--- a/src/mscorlib/src/System/Reflection/Emit/ParameterToken.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/ParameterToken.cs
@@ -12,33 +12,36 @@
**
**
===========================================================*/
-namespace System.Reflection.Emit {
-
- using System;
- using System.Reflection;
+using System;
+using System.Reflection;
+
+namespace System.Reflection.Emit
+{
// The ParameterToken class is an opaque representation of the Token returned
// by the Metadata to represent the parameter.
[Serializable]
- public struct ParameterToken {
-
+ public struct ParameterToken
+ {
public static readonly ParameterToken Empty = new ParameterToken();
internal int m_tkParameter;
-
-
- internal ParameterToken(int tkParam) {
+
+
+ internal ParameterToken(int tkParam)
+ {
m_tkParameter = tkParam;
}
-
- public int Token {
+
+ public int Token
+ {
get { return m_tkParameter; }
}
-
+
public override int GetHashCode()
{
return m_tkParameter;
}
-
+
public override bool Equals(Object obj)
{
if (obj is ParameterToken)
@@ -46,21 +49,20 @@ namespace System.Reflection.Emit {
else
return false;
}
-
+
public bool Equals(ParameterToken obj)
{
return obj.m_tkParameter == m_tkParameter;
}
-
+
public static bool operator ==(ParameterToken a, ParameterToken b)
{
return a.Equals(b);
}
-
+
public static bool operator !=(ParameterToken a, ParameterToken b)
{
return !(a == b);
}
-
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/PropertyBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/PropertyBuilder.cs
index 7c4ed9dc0f..6dbcba251f 100644
--- a/src/mscorlib/src/System/Reflection/Emit/PropertyBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/PropertyBuilder.cs
@@ -12,8 +12,9 @@
**
**
===========================================================*/
-namespace System.Reflection.Emit {
-
+
+namespace System.Reflection.Emit
+{
using System;
using System.Reflection;
using CultureInfo = System.Globalization.CultureInfo;
@@ -25,30 +26,29 @@ namespace System.Reflection.Emit {
// method will return a new PropertyBuilder to a client.
//
public sealed class PropertyBuilder : PropertyInfo
- {
-
+ {
// Make a private constructor so these cannot be constructed externally.
- private PropertyBuilder() {}
-
+ private PropertyBuilder() { }
+
// Constructs a PropertyBuilder.
//
internal PropertyBuilder(
- ModuleBuilder mod, // the module containing this PropertyBuilder
- String name, // property name
- SignatureHelper sig, // property signature descriptor info
- PropertyAttributes attr, // property attribute such as DefaultProperty, Bindable, DisplayBind, etc
- Type returnType, // return type of the property.
- PropertyToken prToken, // the metadata token for this property
- TypeBuilder containingType) // the containing type
+ ModuleBuilder mod, // the module containing this PropertyBuilder
+ String name, // property name
+ SignatureHelper sig, // property signature descriptor info
+ PropertyAttributes attr, // property attribute such as DefaultProperty, Bindable, DisplayBind, etc
+ Type returnType, // return type of the property.
+ PropertyToken prToken, // the metadata token for this property
+ TypeBuilder containingType) // the containing type
{
if (name == null)
throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
if (name[0] == '\0')
- throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), nameof(name));
+ throw new ArgumentException(SR.Argument_IllegalName, nameof(name));
Contract.EndContractBlock();
-
+
m_name = name;
m_moduleBuilder = mod;
m_signature = sig;
@@ -58,32 +58,32 @@ namespace System.Reflection.Emit {
m_tkProperty = prToken.Token;
m_containingType = containingType;
}
-
+
//************************************************
// Set the default value of the Property
//************************************************
- public void SetConstant(Object defaultValue)
+ public void SetConstant(Object defaultValue)
{
m_containingType.ThrowIfCreated();
-
+
TypeBuilder.SetConstantValue(
m_moduleBuilder,
m_prToken.Token,
m_returnType,
defaultValue);
}
-
+
// Return the Token for this property within the TypeBuilder that the
// property is defined within.
public PropertyToken PropertyToken
{
- get {return m_prToken;}
+ get { return m_prToken; }
}
-
+
public override Module Module
{
- get
+ get
{
return m_containingType.Module;
}
@@ -102,25 +102,25 @@ namespace System.Reflection.Emit {
m_prToken.Token,
semantics,
mdBuilder.GetToken().Token);
- }
+ }
public void SetGetMethod(MethodBuilder mdBuilder)
{
SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.Getter);
m_getMethod = mdBuilder;
}
-
+
public void SetSetMethod(MethodBuilder mdBuilder)
{
SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.Setter);
- m_setMethod = mdBuilder;
+ m_setMethod = mdBuilder;
}
public void AddOtherMethod(MethodBuilder mdBuilder)
{
SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.Other);
}
-
+
// Use this function if client decides to form the custom attribute blob themselves
public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
@@ -129,7 +129,7 @@ namespace System.Reflection.Emit {
throw new ArgumentNullException(nameof(con));
if (binaryAttribute == null)
throw new ArgumentNullException(nameof(binaryAttribute));
-
+
m_containingType.ThrowIfCreated();
TypeBuilder.DefineCustomAttribute(
m_moduleBuilder,
@@ -151,29 +151,29 @@ namespace System.Reflection.Emit {
}
// Not supported functions in dynamic module.
- public override Object GetValue(Object obj,Object[] index)
+ public override Object GetValue(Object obj, Object[] index)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
- public override Object GetValue(Object obj,BindingFlags invokeAttr,Binder binder,Object[] index,CultureInfo culture)
+ public override Object GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
- public override void SetValue(Object obj,Object value,Object[] index)
+ public override void SetValue(Object obj, Object value, Object[] index)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
- public override void SetValue(Object obj,Object value,BindingFlags invokeAttr,Binder binder,Object[] index,CultureInfo culture)
+ public override void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
public override MethodInfo[] GetAccessors(bool nonPublic)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
public override MethodInfo GetGetMethod(bool nonPublic)
@@ -198,61 +198,69 @@ namespace System.Reflection.Emit {
public override ParameterInfo[] GetIndexParameters()
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
- public override Type PropertyType {
+ public override Type PropertyType
+ {
get { return m_returnType; }
}
- public override PropertyAttributes Attributes {
- get { return m_attributes;}
+ public override PropertyAttributes Attributes
+ {
+ get { return m_attributes; }
}
- public override bool CanRead {
- get { if (m_getMethod != null) return true; else return false; } }
+ public override bool CanRead
+ {
+ get { if (m_getMethod != null) return true; else return false; }
+ }
- public override bool CanWrite {
+ public override bool CanWrite
+ {
get { if (m_setMethod != null) return true; else return false; }
}
public override Object[] GetCustomAttributes(bool inherit)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
- public override bool IsDefined (Type attributeType, bool inherit)
+ public override bool IsDefined(Type attributeType, bool inherit)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
- public override String Name {
+ public override String Name
+ {
get { return m_name; }
}
- public override Type DeclaringType {
+ public override Type DeclaringType
+ {
get { return m_containingType; }
}
- public override Type ReflectedType {
+ public override Type ReflectedType
+ {
get { return m_containingType; }
}
// These are package private so that TypeBuilder can access them.
- private String m_name; // The name of the property
- private PropertyToken m_prToken; // The token of this property
- private int m_tkProperty;
- private ModuleBuilder m_moduleBuilder;
- private SignatureHelper m_signature;
- private PropertyAttributes m_attributes; // property's attribute flags
- private Type m_returnType; // property's return type
- private MethodInfo m_getMethod;
- private MethodInfo m_setMethod;
- private TypeBuilder m_containingType;
+ private String m_name; // The name of the property
+ private PropertyToken m_prToken; // The token of this property
+ private int m_tkProperty;
+ private ModuleBuilder m_moduleBuilder;
+ private SignatureHelper m_signature;
+ private PropertyAttributes m_attributes; // property's attribute flags
+ private Type m_returnType; // property's return type
+ private MethodInfo m_getMethod;
+ private MethodInfo m_setMethod;
+ private TypeBuilder m_containingType;
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/PropertyToken.cs b/src/mscorlib/src/System/Reflection/Emit/PropertyToken.cs
index 72ab983bb9..b450b198d2 100644
--- a/src/mscorlib/src/System/Reflection/Emit/PropertyToken.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/PropertyToken.cs
@@ -12,26 +12,29 @@
**
**
===========================================================*/
-namespace System.Reflection.Emit {
-
- using System;
- using System.Reflection;
+using System;
+using System.Reflection;
+
+namespace System.Reflection.Emit
+{
[Serializable]
- public struct PropertyToken {
-
+ public struct PropertyToken
+ {
public static readonly PropertyToken Empty = new PropertyToken();
internal int m_property;
- internal PropertyToken(int str) {
- m_property=str;
+ internal PropertyToken(int str)
+ {
+ m_property = str;
}
-
- public int Token {
+
+ public int Token
+ {
get { return m_property; }
}
-
+
// Satisfy value class requirements
public override int GetHashCode()
{
@@ -46,23 +49,20 @@ namespace System.Reflection.Emit {
else
return false;
}
-
+
public bool Equals(PropertyToken obj)
{
return obj.m_property == m_property;
}
-
+
public static bool operator ==(PropertyToken a, PropertyToken b)
{
return a.Equals(b);
}
-
+
public static bool operator !=(PropertyToken a, PropertyToken b)
{
return !(a == b);
}
-
}
-
-
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/SignatureHelper.cs b/src/mscorlib/src/System/Reflection/Emit/SignatureHelper.cs
index b43abcb51c..fd1a8e70fe 100644
--- a/src/mscorlib/src/System/Reflection/Emit/SignatureHelper.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/SignatureHelper.cs
@@ -4,23 +4,23 @@
//
-namespace System.Reflection.Emit
+using System.Text;
+using System;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+
+namespace System.Reflection.Emit
{
- using System.Text;
- using System;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Reflection;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
-
public sealed class SignatureHelper
{
#region Consts Fields
private const int NO_SIZE_IN_SIG = -1;
#endregion
-
+
#region Static Members
public static SignatureHelper GetMethodSigHelper(Module mod, Type returnType, Type[] parameterTypes)
{
@@ -31,7 +31,7 @@ namespace System.Reflection.Emit
{
return GetMethodSigHelper(mod, callingConvention, cGenericParam, returnType, null, null, null, null, null);
}
-
+
public static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType)
{
return GetMethodSigHelper(mod, callingConvention, returnType, null, null, null, null, null);
@@ -41,17 +41,17 @@ namespace System.Reflection.Emit
{
SignatureHelper sigHelp = new SignatureHelper(scope, MdSigCallingConvention.GenericInst);
sigHelp.AddData(inst.Length);
- foreach(Type t in inst)
+ foreach (Type t in inst)
sigHelp.AddArgument(t);
return sigHelp;
}
-
+
internal static SignatureHelper GetMethodSigHelper(
Module scope, CallingConventions callingConvention,
Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
{
- return GetMethodSigHelper(scope, callingConvention, 0, returnType, requiredReturnTypeCustomModifiers,
+ return GetMethodSigHelper(scope, callingConvention, 0, returnType, requiredReturnTypeCustomModifiers,
optionalReturnTypeCustomModifiers, parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
}
@@ -62,11 +62,11 @@ namespace System.Reflection.Emit
{
SignatureHelper sigHelp;
MdSigCallingConvention intCall;
-
+
if (returnType == null)
{
returnType = typeof(void);
- }
+ }
intCall = MdSigCallingConvention.Default;
@@ -81,8 +81,8 @@ namespace System.Reflection.Emit
if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis)
intCall |= MdSigCallingConvention.HasThis;
- sigHelp = new SignatureHelper(scope, intCall, cGenericParam, returnType,
- requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers);
+ sigHelp = new SignatureHelper(scope, intCall, cGenericParam, returnType,
+ requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers);
sigHelp.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
return sigHelp;
@@ -92,7 +92,7 @@ namespace System.Reflection.Emit
{
SignatureHelper sigHelp;
MdSigCallingConvention intCall;
-
+
if (returnType == null)
returnType = typeof(void);
@@ -114,19 +114,19 @@ namespace System.Reflection.Emit
}
else
{
- throw new ArgumentException(Environment.GetResourceString("Argument_UnknownUnmanagedCallConv"), nameof(unmanagedCallConv));
+ throw new ArgumentException(SR.Argument_UnknownUnmanagedCallConv, nameof(unmanagedCallConv));
}
-
+
sigHelp = new SignatureHelper(mod, intCall, returnType, null, null);
-
+
return sigHelp;
}
public static SignatureHelper GetLocalVarSigHelper()
- {
+ {
return GetLocalVarSigHelper(null);
}
-
+
public static SignatureHelper GetMethodSigHelper(CallingConventions callingConvention, Type returnType)
{
return GetMethodSigHelper(null, callingConvention, returnType);
@@ -141,47 +141,47 @@ namespace System.Reflection.Emit
{
return new SignatureHelper(mod, MdSigCallingConvention.LocalSig);
}
-
+
public static SignatureHelper GetFieldSigHelper(Module mod)
{
return new SignatureHelper(mod, MdSigCallingConvention.Field);
}
-
+
public static SignatureHelper GetPropertySigHelper(Module mod, Type returnType, Type[] parameterTypes)
{
return GetPropertySigHelper(mod, returnType, null, null, parameterTypes, null, null);
}
- public static SignatureHelper GetPropertySigHelper(Module mod,
- Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
+ public static SignatureHelper GetPropertySigHelper(Module mod,
+ Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
{
- return GetPropertySigHelper(mod, (CallingConventions)0, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers,
+ return GetPropertySigHelper(mod, (CallingConventions)0, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers,
parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
}
public static SignatureHelper GetPropertySigHelper(Module mod, CallingConventions callingConvention,
- Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
+ Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers,
Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers)
{
SignatureHelper sigHelp;
-
+
if (returnType == null)
{
returnType = typeof(void);
- }
+ }
MdSigCallingConvention intCall = MdSigCallingConvention.Property;
if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis)
intCall |= MdSigCallingConvention.HasThis;
- sigHelp = new SignatureHelper(mod, intCall,
+ sigHelp = new SignatureHelper(mod, intCall,
returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers);
sigHelp.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers);
return sigHelp;
}
-
+
internal static SignatureHelper GetTypeSigToken(Module module, Type type)
{
if (module == null)
@@ -216,13 +216,13 @@ namespace System.Reflection.Emit
// Use this constructor to instantiate a any signatures that will require a return type.
Init(mod, callingConvention, cGenericParameters);
- if (callingConvention == MdSigCallingConvention.Field)
- throw new ArgumentException(Environment.GetResourceString("Argument_BadFieldSig"));
+ if (callingConvention == MdSigCallingConvention.Field)
+ throw new ArgumentException(SR.Argument_BadFieldSig);
- AddOneArgTypeHelper(returnType, requiredCustomModifiers, optionalCustomModifiers);
+ AddOneArgTypeHelper(returnType, requiredCustomModifiers, optionalCustomModifiers);
}
- private SignatureHelper(Module mod, MdSigCallingConvention callingConvention,
+ private SignatureHelper(Module mod, MdSigCallingConvention callingConvention,
Type returnType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
: this(mod, callingConvention, 0, returnType, requiredCustomModifiers, optionalCustomModifiers)
{
@@ -244,31 +244,31 @@ namespace System.Reflection.Emit
m_sigDone = false;
m_sizeLoc = NO_SIZE_IN_SIG;
- if (m_module == null && mod != null)
- throw new ArgumentException(Environment.GetResourceString("NotSupported_MustBeModuleBuilder"));
+ if (m_module == null && mod != null)
+ throw new ArgumentException(SR.NotSupported_MustBeModuleBuilder);
}
private void Init(Module mod, MdSigCallingConvention callingConvention)
{
Init(mod, callingConvention, 0);
}
-
+
private void Init(Module mod, MdSigCallingConvention callingConvention, int cGenericParam)
- {
+ {
Init(mod);
AddData((byte)callingConvention);
if (callingConvention == MdSigCallingConvention.Field ||
- callingConvention == MdSigCallingConvention.GenericInst)
+ callingConvention == MdSigCallingConvention.GenericInst)
{
m_sizeLoc = NO_SIZE_IN_SIG;
- }
- else
+ }
+ else
{
if (cGenericParam > 0)
AddData(cGenericParam);
-
+
m_sizeLoc = m_currSig++;
}
}
@@ -302,10 +302,10 @@ namespace System.Reflection.Emit
throw new ArgumentNullException(nameof(optionalCustomModifiers));
if (t.HasElementType)
- throw new ArgumentException(Environment.GetResourceString("Argument_ArraysInvalid"), nameof(optionalCustomModifiers));
+ throw new ArgumentException(SR.Argument_ArraysInvalid, nameof(optionalCustomModifiers));
if (t.ContainsGenericParameters)
- throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), nameof(optionalCustomModifiers));
+ throw new ArgumentException(SR.Argument_GenericsInvalid, nameof(optionalCustomModifiers));
AddElementType(CorElementType.CModOpt);
@@ -325,10 +325,10 @@ namespace System.Reflection.Emit
throw new ArgumentNullException(nameof(requiredCustomModifiers));
if (t.HasElementType)
- throw new ArgumentException(Environment.GetResourceString("Argument_ArraysInvalid"), nameof(requiredCustomModifiers));
+ throw new ArgumentException(SR.Argument_ArraysInvalid, nameof(requiredCustomModifiers));
if (t.ContainsGenericParameters)
- throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), nameof(requiredCustomModifiers));
+ throw new ArgumentException(SR.Argument_GenericsInvalid, nameof(requiredCustomModifiers));
AddElementType(CorElementType.CModReqd);
@@ -425,7 +425,7 @@ namespace System.Reflection.Emit
}
else if (clsArgument.IsArray)
{
- if (clsArgument.IsSzArray)
+ if (clsArgument.IsSZArray)
{
AddElementType(CorElementType.SzArray);
@@ -482,7 +482,7 @@ namespace System.Reflection.Emit
}
}
}
-
+
private void AddData(int data)
{
// A managed representation of CorSigCompressData;
@@ -491,80 +491,79 @@ namespace System.Reflection.Emit
{
m_signature = ExpandArray(m_signature);
}
-
+
if (data <= 0x7F)
{
m_signature[m_currSig++] = (byte)(data & 0xFF);
- }
+ }
else if (data <= 0x3FFF)
{
- m_signature[m_currSig++] = (byte)((data >>8) | 0x80);
+ m_signature[m_currSig++] = (byte)((data >> 8) | 0x80);
m_signature[m_currSig++] = (byte)(data & 0xFF);
- }
+ }
else if (data <= 0x1FFFFFFF)
{
- m_signature[m_currSig++] = (byte)((data >>24) | 0xC0);
- m_signature[m_currSig++] = (byte)((data >>16) & 0xFF);
- m_signature[m_currSig++] = (byte)((data >>8) & 0xFF);
+ m_signature[m_currSig++] = (byte)((data >> 24) | 0xC0);
+ m_signature[m_currSig++] = (byte)((data >> 16) & 0xFF);
+ m_signature[m_currSig++] = (byte)((data >> 8) & 0xFF);
m_signature[m_currSig++] = (byte)((data) & 0xFF);
- }
+ }
else
{
- throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger"));
- }
-
+ throw new ArgumentException(SR.Argument_LargeInteger);
+ }
}
-
+
private void AddElementType(CorElementType cvt)
{
// Adds an element to the signature. A managed represenation of CorSigCompressElement
- if (m_currSig + 1 > m_signature.Length)
+ if (m_currSig + 1 > m_signature.Length)
m_signature = ExpandArray(m_signature);
m_signature[m_currSig++] = (byte)cvt;
}
-
- private void AddToken(int token)
+
+ private void AddToken(int token)
{
// A managed represenation of CompressToken
// Pulls the token appart to get a rid, adds some appropriate bits
// to the token and then adds this to the signature.
- int rid = (token & 0x00FFFFFF); //This is RidFromToken;
+ int rid = (token & 0x00FFFFFF); //This is RidFromToken;
MetadataTokenType type = (MetadataTokenType)(token & unchecked((int)0xFF000000)); //This is TypeFromToken;
-
- if (rid > 0x3FFFFFF)
+
+ if (rid > 0x3FFFFFF)
{
// token is too big to be compressed
- throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger"));
+ throw new ArgumentException(SR.Argument_LargeInteger);
}
-
- rid = (rid << 2);
-
+
+ rid = (rid << 2);
+
// TypeDef is encoded with low bits 00
// TypeRef is encoded with low bits 01
// TypeSpec is encoded with low bits 10
- if (type == MetadataTokenType.TypeRef)
- {
+ if (type == MetadataTokenType.TypeRef)
+ {
//if type is mdtTypeRef
- rid|=0x1;
- }
- else if (type == MetadataTokenType.TypeSpec)
- {
+ rid |= 0x1;
+ }
+ else if (type == MetadataTokenType.TypeSpec)
+ {
//if type is mdtTypeSpec
- rid|=0x2;
+ rid |= 0x2;
}
-
+
AddData(rid);
}
-
+
private void InternalAddTypeToken(TypeToken clsToken, CorElementType CorType)
{
// Add a type token into signature. CorType will be either CorElementType.Class or CorElementType.ValueType
AddElementType(CorType);
AddToken(clsToken.Token);
}
-
+
private unsafe void InternalAddRuntimeType(Type type)
{
// Add a runtime type into the signature.
@@ -580,11 +579,11 @@ namespace System.Reflection.Emit
if (m_currSig + sizeof(void*) > m_signature.Length)
m_signature = ExpandArray(m_signature);
- byte *phandle = (byte*)&handle;
+ byte* phandle = (byte*)&handle;
for (int i = 0; i < sizeof(void*); i++)
m_signature[m_currSig++] = phandle[i];
}
-
+
private byte[] ExpandArray(byte[] inArray)
{
// Expand the signature buffer size
@@ -595,25 +594,25 @@ namespace System.Reflection.Emit
{
// Expand the signature buffer size
- if (requiredLength < inArray.Length)
- requiredLength = inArray.Length*2;
+ if (requiredLength < inArray.Length)
+ requiredLength = inArray.Length * 2;
byte[] outArray = new byte[requiredLength];
Buffer.BlockCopy(inArray, 0, outArray, 0, inArray.Length);
return outArray;
}
-
+
private void IncrementArgCounts()
{
- if (m_sizeLoc == NO_SIZE_IN_SIG)
- {
+ if (m_sizeLoc == NO_SIZE_IN_SIG)
+ {
//We don't have a size if this is a field.
return;
}
m_argCount++;
}
-
+
private void SetNumberOfSignatureElements(bool forceCopy)
{
// For most signatures, this will set the number of elements in a byte which we have reserved for it.
@@ -628,18 +627,18 @@ namespace System.Reflection.Emit
byte[] temp;
int newSigSize;
int currSigHolder = m_currSig;
-
- if (m_sizeLoc == NO_SIZE_IN_SIG)
+
+ if (m_sizeLoc == NO_SIZE_IN_SIG)
return;
-
+
//If we have fewer than 128 arguments and we haven't been told to copy the
//array, we can just set the appropriate bit and return.
- if (m_argCount < 0x80 && !forceCopy)
+ if (m_argCount < 0x80 && !forceCopy)
{
m_signature[m_sizeLoc] = (byte)m_argCount;
return;
- }
-
+ }
+
//We need to have more bytes for the size. Figure out how many bytes here.
//Since we need to copy anyway, we're just going to take the cost of doing a
//new allocation.
@@ -655,45 +654,45 @@ namespace System.Reflection.Emit
{
newSigSize = 4;
}
-
+
//Allocate the new array.
temp = new byte[m_currSig + newSigSize - 1];
-
+
//Copy the calling convention. The calling convention is always just one byte
//so we just copy that byte. Then copy the rest of the array, shifting everything
//to make room for the new number of elements.
temp[0] = m_signature[0];
Buffer.BlockCopy(m_signature, m_sizeLoc + 1, temp, m_sizeLoc + newSigSize, currSigHolder - (m_sizeLoc + 1));
m_signature = temp;
-
+
//Use the AddData method to add the number of elements appropriately compressed.
m_currSig = m_sizeLoc;
AddData(m_argCount);
m_currSig = currSigHolder + (newSigSize - 1);
}
-
+
#endregion
#region Internal Members
internal int ArgumentCount
- {
- get
- {
- return m_argCount;
- }
+ {
+ get
+ {
+ return m_argCount;
+ }
}
internal static bool IsSimpleType(CorElementType type)
{
- if (type <= CorElementType.String)
+ if (type <= CorElementType.String)
return true;
- if (type == CorElementType.TypedByRef || type == CorElementType.I || type == CorElementType.U || type == CorElementType.Object)
+ if (type == CorElementType.TypedByRef || type == CorElementType.I || type == CorElementType.U || type == CorElementType.Object)
return true;
return false;
}
-
+
internal byte[] InternalGetSignature(out int length)
{
// An internal method to return the signature. Does not trim the
@@ -703,7 +702,7 @@ namespace System.Reflection.Emit
//
// param length : an out param indicating the length of the array.
// return : A reference to the internal ubyte array.
-
+
if (!m_sigDone)
{
m_sigDone = true;
@@ -713,20 +712,20 @@ namespace System.Reflection.Emit
// array. Bummer, eh?
SetNumberOfSignatureElements(false);
}
-
+
length = m_currSig;
return m_signature;
}
-
-
-
-
+
+
+
+
internal byte[] InternalGetSignatureArray()
{
- int argCount = m_argCount;
+ int argCount = m_argCount;
int currSigLength = m_currSig;
int newSigSize = currSigLength;
-
+
//Allocate the new array.
if (argCount < 0x7F)
newSigSize += 1;
@@ -745,26 +744,26 @@ namespace System.Reflection.Emit
temp[sigCopyIndex++] = (byte)(argCount & 0xFF);
else if (argCount <= 0x3FFF)
{
- temp[sigCopyIndex++] = (byte)((argCount >>8) | 0x80);
+ temp[sigCopyIndex++] = (byte)((argCount >> 8) | 0x80);
temp[sigCopyIndex++] = (byte)(argCount & 0xFF);
- }
+ }
else if (argCount <= 0x1FFFFFFF)
{
- temp[sigCopyIndex++] = (byte)((argCount >>24) | 0xC0);
- temp[sigCopyIndex++] = (byte)((argCount >>16) & 0xFF);
- temp[sigCopyIndex++] = (byte)((argCount >>8) & 0xFF);
+ temp[sigCopyIndex++] = (byte)((argCount >> 24) | 0xC0);
+ temp[sigCopyIndex++] = (byte)((argCount >> 16) & 0xFF);
+ temp[sigCopyIndex++] = (byte)((argCount >> 8) & 0xFF);
temp[sigCopyIndex++] = (byte)((argCount) & 0xFF);
- }
+ }
else
- throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger"));
+ throw new ArgumentException(SR.Argument_LargeInteger);
// copy the sig part of the sig
Buffer.BlockCopy(m_signature, 2, temp, sigCopyIndex, currSigLength - 2);
// mark the end of sig
temp[newSigSize - 1] = (byte)CorElementType.End;
-
+
return temp;
}
-
+
#endregion
#region Public Methods
@@ -781,21 +780,21 @@ namespace System.Reflection.Emit
IncrementArgCounts();
AddOneArgTypeHelper(argument, pinned);
}
-
+
public void AddArguments(Type[] arguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
{
if (requiredCustomModifiers != null && (arguments == null || requiredCustomModifiers.Length != arguments.Length))
- throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", nameof(requiredCustomModifiers), nameof(arguments)));
+ throw new ArgumentException(SR.Format(SR.Argument_MismatchedArrays, nameof(requiredCustomModifiers), nameof(arguments)));
if (optionalCustomModifiers != null && (arguments == null || optionalCustomModifiers.Length != arguments.Length))
- throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", nameof(optionalCustomModifiers), nameof(arguments)));
+ throw new ArgumentException(SR.Format(SR.Argument_MismatchedArrays, nameof(optionalCustomModifiers), nameof(arguments)));
if (arguments != null)
{
- for (int i =0; i < arguments.Length; i++)
+ for (int i = 0; i < arguments.Length; i++)
{
- AddArgument(arguments[i],
- requiredCustomModifiers == null ? null : requiredCustomModifiers[i],
+ AddArgument(arguments[i],
+ requiredCustomModifiers == null ? null : requiredCustomModifiers[i],
optionalCustomModifiers == null ? null : optionalCustomModifiers[i]);
}
}
@@ -804,13 +803,13 @@ namespace System.Reflection.Emit
public void AddArgument(Type argument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers)
{
if (m_sigDone)
- throw new ArgumentException(Environment.GetResourceString("Argument_SigIsFinalized"));
-
+ throw new ArgumentException(SR.Argument_SigIsFinalized);
+
if (argument == null)
throw new ArgumentNullException(nameof(argument));
IncrementArgCounts();
-
+
// Add an argument to the signature. Takes a Type and determines whether it
// is one of the primitive types of which we have special knowledge or a more
// general class. In the former case, we only add the appropriate short cut encoding,
@@ -825,26 +824,26 @@ namespace System.Reflection.Emit
public override bool Equals(Object obj)
{
- if (!(obj is SignatureHelper))
+ if (!(obj is SignatureHelper))
{
return false;
}
-
+
SignatureHelper temp = (SignatureHelper)obj;
-
- if ( !temp.m_module.Equals(m_module) || temp.m_currSig!=m_currSig || temp.m_sizeLoc!=m_sizeLoc || temp.m_sigDone !=m_sigDone )
+
+ if (!temp.m_module.Equals(m_module) || temp.m_currSig != m_currSig || temp.m_sizeLoc != m_sizeLoc || temp.m_sigDone != m_sigDone)
{
return false;
}
-
- for (int i=0; i<m_currSig; i++)
+
+ for (int i = 0; i < m_currSig; i++)
{
- if (m_signature[i]!=temp.m_signature[i])
+ if (m_signature[i] != temp.m_signature[i])
return false;
}
return true;
}
-
+
public override int GetHashCode()
{
// Start the hash code with the hash code of the module and the values of the member variables.
@@ -855,7 +854,7 @@ namespace System.Reflection.Emit
HashCode += 1;
// Then add the hash code of all the arguments.
- for (int i=0; i < m_currSig; i++)
+ for (int i = 0; i < m_currSig; i++)
HashCode += m_signature[i].GetHashCode();
return HashCode;
@@ -865,23 +864,23 @@ namespace System.Reflection.Emit
{
return GetSignature(false);
}
-
+
internal byte[] GetSignature(bool appendEndOfSig)
{
// Chops the internal signature to the appropriate length. Adds the
// end token to the signature and marks the signature as finished so that
// no further tokens can be added. Return the full signature in a trimmed array.
- if (!m_sigDone)
+ if (!m_sigDone)
{
- if (appendEndOfSig)
+ if (appendEndOfSig)
AddElementType(CorElementType.End);
SetNumberOfSignatureElements(true);
m_sigDone = true;
}
-
+
// This case will only happen if the user got the signature through
// InternalGetSignature first and then called GetSignature.
- if (m_signature.Length > m_currSig)
+ if (m_signature.Length > m_currSig)
{
byte[] temp = new byte[m_currSig];
Array.Copy(m_signature, 0, temp, 0, m_currSig);
@@ -890,7 +889,7 @@ namespace System.Reflection.Emit
return m_signature;
}
-
+
public override String ToString()
{
StringBuilder sb = new StringBuilder();
@@ -906,7 +905,7 @@ namespace System.Reflection.Emit
}
sb.Append("Signature: " + Environment.NewLine);
- for (int i=0; i<=m_currSig; i++)
+ for (int i = 0; i <= m_currSig; i++)
{
sb.Append(m_signature[i] + " ");
}
@@ -914,9 +913,8 @@ namespace System.Reflection.Emit
sb.Append(Environment.NewLine);
return sb.ToString();
}
-
- #endregion
+ #endregion
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/SignatureToken.cs b/src/mscorlib/src/System/Reflection/Emit/SignatureToken.cs
index 5c908b89c7..e17e0c955e 100644
--- a/src/mscorlib/src/System/Reflection/Emit/SignatureToken.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/SignatureToken.cs
@@ -13,32 +13,35 @@
**
**
===========================================================*/
-namespace System.Reflection.Emit {
-
- using System;
- using System.Reflection;
- public struct SignatureToken {
-
+using System;
+using System.Reflection;
+
+namespace System.Reflection.Emit
+{
+ public struct SignatureToken
+ {
public static readonly SignatureToken Empty = new SignatureToken();
internal int m_signature;
internal ModuleBuilder m_moduleBuilder;
-
- internal SignatureToken(int str, ModuleBuilder mod) {
- m_signature=str;
+
+ internal SignatureToken(int str, ModuleBuilder mod)
+ {
+ m_signature = str;
m_moduleBuilder = mod;
}
-
- public int Token {
+
+ public int Token
+ {
get { return m_signature; }
}
-
+
public override int GetHashCode()
{
return m_signature;
}
-
+
public override bool Equals(Object obj)
{
if (obj is SignatureToken)
@@ -46,21 +49,20 @@ namespace System.Reflection.Emit {
else
return false;
}
-
+
public bool Equals(SignatureToken obj)
{
return obj.m_signature == m_signature;
}
-
+
public static bool operator ==(SignatureToken a, SignatureToken b)
{
return a.Equals(b);
}
-
+
public static bool operator !=(SignatureToken a, SignatureToken b)
{
return !(a == b);
}
-
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/StackBehaviour.cs b/src/mscorlib/src/System/Reflection/Emit/StackBehaviour.cs
index 8a447d03fc..afcf2ddf0a 100644
--- a/src/mscorlib/src/System/Reflection/Emit/StackBehaviour.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/StackBehaviour.cs
@@ -12,42 +12,42 @@
** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND!
** See clr\src\inc\opcodegen.pl for more information.**
============================================================*/
-namespace System.Reflection.Emit {
using System;
-[Serializable]
-public enum StackBehaviour
+namespace System.Reflection.Emit
{
-
- Pop0 = 0,
- Pop1 = 1,
- Pop1_pop1 = 2,
- Popi = 3,
- Popi_pop1 = 4,
- Popi_popi = 5,
- Popi_popi8 = 6,
- Popi_popi_popi = 7,
- Popi_popr4 = 8,
- Popi_popr8 = 9,
- Popref = 10,
- Popref_pop1 = 11,
- Popref_popi = 12,
- Popref_popi_popi = 13,
- Popref_popi_popi8 = 14,
- Popref_popi_popr4 = 15,
- Popref_popi_popr8 = 16,
- Popref_popi_popref = 17,
- Push0 = 18,
- Push1 = 19,
- Push1_push1 = 20,
- Pushi = 21,
- Pushi8 = 22,
- Pushr4 = 23,
- Pushr8 = 24,
- Pushref = 25,
- Varpop = 26,
- Varpush = 27,
- Popref_popi_pop1 = 28,
-}
+ [Serializable]
+ public enum StackBehaviour
+ {
+ Pop0 = 0,
+ Pop1 = 1,
+ Pop1_pop1 = 2,
+ Popi = 3,
+ Popi_pop1 = 4,
+ Popi_popi = 5,
+ Popi_popi8 = 6,
+ Popi_popi_popi = 7,
+ Popi_popr4 = 8,
+ Popi_popr8 = 9,
+ Popref = 10,
+ Popref_pop1 = 11,
+ Popref_popi = 12,
+ Popref_popi_popi = 13,
+ Popref_popi_popi8 = 14,
+ Popref_popi_popr4 = 15,
+ Popref_popi_popr8 = 16,
+ Popref_popi_popref = 17,
+ Push0 = 18,
+ Push1 = 19,
+ Push1_push1 = 20,
+ Pushi = 21,
+ Pushi8 = 22,
+ Pushr4 = 23,
+ Pushr8 = 24,
+ Pushref = 25,
+ Varpop = 26,
+ Varpush = 27,
+ Popref_popi_pop1 = 28,
+ }
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/StringToken.cs b/src/mscorlib/src/System/Reflection/Emit/StringToken.cs
index 852225697c..1d90816fc6 100644
--- a/src/mscorlib/src/System/Reflection/Emit/StringToken.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/StringToken.cs
@@ -12,36 +12,39 @@
**
**
===========================================================*/
-namespace System.Reflection.Emit {
-
- using System;
- using System.Reflection;
+using System;
+using System.Reflection;
+
+namespace System.Reflection.Emit
+{
[Serializable]
- public struct StringToken {
-
+ public struct StringToken
+ {
internal int m_string;
-
+
//public StringToken() {
// m_string=0;
//}
-
- internal StringToken(int str) {
- m_string=str;
+
+ internal StringToken(int str)
+ {
+ m_string = str;
}
-
+
// Returns the metadata token for this particular string.
// Generated by a call to Module.GetStringConstant().
//
- public int Token {
+ public int Token
+ {
get { return m_string; }
}
-
+
public override int GetHashCode()
{
return m_string;
}
-
+
public override bool Equals(Object obj)
{
if (obj is StringToken)
@@ -49,29 +52,20 @@ namespace System.Reflection.Emit {
else
return false;
}
-
+
public bool Equals(StringToken obj)
{
return obj.m_string == m_string;
}
-
+
public static bool operator ==(StringToken a, StringToken b)
{
return a.Equals(b);
}
-
+
public static bool operator !=(StringToken a, StringToken b)
{
return !(a == b);
}
-
}
-
-
-
-
-
-
-
-
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/SymbolMethod.cs b/src/mscorlib/src/System/Reflection/Emit/SymbolMethod.cs
index 6b47770608..42713b86db 100644
--- a/src/mscorlib/src/System/Reflection/Emit/SymbolMethod.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/SymbolMethod.cs
@@ -4,14 +4,14 @@
//
-namespace System.Reflection.Emit
+namespace System.Reflection.Emit
{
using System.Runtime.InteropServices;
using System;
using System.Reflection;
using System.Diagnostics.Contracts;
using CultureInfo = System.Globalization.CultureInfo;
-
+
internal sealed class SymbolMethod : MethodInfo
{
#region Private Data Members
@@ -26,7 +26,7 @@ namespace System.Reflection.Emit
#endregion
#region Constructor
- internal SymbolMethod(ModuleBuilder mod, MethodToken token, Type arrayClass, String methodName,
+ internal SymbolMethod(ModuleBuilder mod, MethodToken token, Type arrayClass, String methodName,
CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
{
// This is a kind of MethodInfo to represent methods for array type of unbaked type
@@ -47,9 +47,9 @@ namespace System.Reflection.Emit
}
else
{
- m_parameterTypes = EmptyArray<Type>.Value;
+ m_parameterTypes = Array.Empty<Type>();
}
-
+
m_module = mod;
m_containingType = arrayClass;
m_name = methodName;
@@ -70,28 +70,28 @@ namespace System.Reflection.Emit
{
return mod.GetArrayMethodToken(m_containingType, m_name, m_callingConvention, m_returnType, m_parameterTypes);
}
-
+
#endregion
#region MemberInfo Overrides
- public override Module Module
- {
- get { return m_module; }
- }
+ public override Module Module
+ {
+ get { return m_module; }
+ }
public override Type ReflectedType
{
get { return m_containingType as Type; }
}
- public override String Name
+ public override String Name
{
get { return m_name; }
}
- public override Type DeclaringType
+ public override Type DeclaringType
{
- get {return m_containingType;}
+ get { return m_containingType; }
}
#endregion
@@ -99,27 +99,27 @@ namespace System.Reflection.Emit
[Pure]
public override ParameterInfo[] GetParameters()
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod"));
+ throw new NotSupportedException(SR.NotSupported_SymbolMethod);
}
-
+
public override MethodImplAttributes GetMethodImplementationFlags()
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod"));
+ throw new NotSupportedException(SR.NotSupported_SymbolMethod);
}
-
- public override MethodAttributes Attributes
+
+ public override MethodAttributes Attributes
{
- get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod")); }
+ get { throw new NotSupportedException(SR.NotSupported_SymbolMethod); }
}
-
- public override CallingConventions CallingConvention
+
+ public override CallingConventions CallingConvention
{
get { return m_callingConvention; }
}
- public override RuntimeMethodHandle MethodHandle
+ public override RuntimeMethodHandle MethodHandle
{
- get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod")); }
+ get { throw new NotSupportedException(SR.NotSupported_SymbolMethod); }
}
#endregion
@@ -133,16 +133,16 @@ namespace System.Reflection.Emit
}
}
- public override ICustomAttributeProvider ReturnTypeCustomAttributes
+ public override ICustomAttributeProvider ReturnTypeCustomAttributes
{
- get { return null; }
+ get { return null; }
}
-
+
public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod"));
+ throw new NotSupportedException(SR.NotSupported_SymbolMethod);
}
-
+
public override MethodInfo GetBaseDefinition()
{
return this;
@@ -152,19 +152,19 @@ namespace System.Reflection.Emit
#region ICustomAttributeProvider Implementation
public override Object[] GetCustomAttributes(bool inherit)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod"));
+ throw new NotSupportedException(SR.NotSupported_SymbolMethod);
}
-
+
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod"));
+ throw new NotSupportedException(SR.NotSupported_SymbolMethod);
}
public override bool IsDefined(Type attributeType, bool inherit)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod"));
+ throw new NotSupportedException(SR.NotSupported_SymbolMethod);
}
-
+
#endregion
#region Public Members
diff --git a/src/mscorlib/src/System/Reflection/Emit/SymbolType.cs b/src/mscorlib/src/System/Reflection/Emit/SymbolType.cs
index 205299125b..16848b43dd 100644
--- a/src/mscorlib/src/System/Reflection/Emit/SymbolType.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/SymbolType.cs
@@ -4,7 +4,7 @@
//
-namespace System.Reflection.Emit
+namespace System.Reflection.Emit
{
using System.Runtime.InteropServices;
using System;
@@ -15,16 +15,17 @@ namespace System.Reflection.Emit
[Serializable]
internal enum TypeKind
{
- IsArray = 1,
+ IsArray = 1,
IsPointer = 2,
- IsByRef = 3,
+ IsByRef = 3,
}
// This is a kind of Type object that will represent the compound expression of a parameter type or field type.
internal sealed class SymbolType : TypeInfo
{
- public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){
- if(typeInfo==null) return false;
+ public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo)
+ {
+ if (typeInfo == null) return false;
return IsAssignableFrom(typeInfo.AsType());
}
@@ -52,8 +53,8 @@ namespace System.Reflection.Emit
return baseType;
}
-
-
+
+
if (format[curIndex] == '&')
{
@@ -62,10 +63,10 @@ namespace System.Reflection.Emit
symbolType = new SymbolType(TypeKind.IsByRef);
symbolType.SetFormat(format, curIndex, 1);
curIndex++;
-
+
if (curIndex != format.Length)
// ByRef has to be the last char!!
- throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat"));
+ throw new ArgumentException(SR.Argument_BadSigFormat);
symbolType.SetElementType(baseType);
return symbolType;
@@ -84,13 +85,13 @@ namespace System.Reflection.Emit
// Example: [2..4] - one dimension array with lower bound 2 and size of 3
// Example: [3, 5, 6] - three dimension array with lower bound 3, 5, 6
// Example: [-3, ] [] - one dimensional array of two dimensional array (with lower bound -3 sepcified)
-
+
while (format[curIndex] != ']')
{
if (format[curIndex] == '*')
{
symbolType.m_isSzArray = false;
- curIndex++;
+ curIndex++;
}
// consume, one dimension at a time
if ((format[curIndex] >= '0' && format[curIndex] <= '9') || format[curIndex] == '-')
@@ -117,10 +118,9 @@ namespace System.Reflection.Emit
// set the upper bound to be less than LowerBound to indicate that upper bound it not specified yet!
iUpperBound = iLowerBound - 1;
-
}
if (format[curIndex] == '.')
- {
+ {
// upper bound is specified
// skip over ".."
@@ -128,7 +128,7 @@ namespace System.Reflection.Emit
if (format[curIndex] != '.')
{
// bad format!! Throw exception
- throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat"));
+ throw new ArgumentException(SR.Argument_BadSigFormat);
}
curIndex++;
@@ -158,7 +158,7 @@ namespace System.Reflection.Emit
{
// User specified upper bound less than lower bound, this is an error.
// Throw error exception.
- throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat"));
+ throw new ArgumentException(SR.Argument_BadSigFormat);
}
}
}
@@ -176,10 +176,10 @@ namespace System.Reflection.Emit
}
else if (format[curIndex] != ']')
{
- throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat"));
+ throw new ArgumentException(SR.Argument_BadSigFormat);
}
}
-
+
// The last dimension information
symbolType.SetBounds(iLowerBound, iUpperBound);
@@ -209,21 +209,21 @@ namespace System.Reflection.Emit
#endregion
#region Data Members
- internal TypeKind m_typeKind;
- internal Type m_baseType;
- internal int m_cRank; // count of dimension
+ internal TypeKind m_typeKind;
+ internal Type m_baseType;
+ internal int m_cRank; // count of dimension
// If LowerBound and UpperBound is equal, that means one element.
// If UpperBound is less than LowerBound, then the size is not specified.
- internal int[] m_iaLowerBound;
- internal int[] m_iaUpperBound; // count of dimension
- private string m_format; // format string to form the full name.
- private bool m_isSzArray = true;
+ internal int[] m_iaLowerBound;
+ internal int[] m_iaUpperBound; // count of dimension
+ private string m_format; // format string to form the full name.
+ private bool m_isSzArray = true;
#endregion
#region Constructor
internal SymbolType(TypeKind typeKind)
{
- m_typeKind = typeKind;
+ m_typeKind = typeKind;
m_iaLowerBound = new int[4];
m_iaUpperBound = new int[4];
}
@@ -246,15 +246,15 @@ namespace System.Reflection.Emit
if (lower != 0 || upper != -1)
m_isSzArray = false;
-
+
if (m_iaLowerBound.Length <= m_cRank)
{
// resize the bound array
- int[] iaTemp = new int[m_cRank * 2];
+ int[] iaTemp = new int[m_cRank * 2];
Array.Copy(m_iaLowerBound, 0, iaTemp, 0, m_cRank);
- m_iaLowerBound = iaTemp;
+ m_iaLowerBound = iaTemp;
Array.Copy(m_iaUpperBound, 0, iaTemp, 0, m_cRank);
- m_iaUpperBound = iaTemp;
+ m_iaUpperBound = iaTemp;
}
m_iaLowerBound[m_cRank] = lower;
@@ -269,36 +269,27 @@ namespace System.Reflection.Emit
m_format = format.Substring(curIndex, length);
}
#endregion
-
+
#region Type Overrides
- internal override bool IsSzArray
- {
- get
- {
- if (m_cRank > 1)
- return false;
-
- return m_isSzArray;
- }
- }
+ public override bool IsSZArray => m_cRank <= 1 && m_isSzArray;
- public override Type MakePointerType()
- {
+ public override Type MakePointerType()
+ {
return SymbolType.FormCompoundType(m_format + "*", m_baseType, 0);
}
- public override Type MakeByRefType()
- {
+ public override Type MakeByRefType()
+ {
return SymbolType.FormCompoundType(m_format + "&", m_baseType, 0);
}
-
- public override Type MakeArrayType()
- {
+
+ public override Type MakeArrayType()
+ {
return SymbolType.FormCompoundType(m_format + "[]", m_baseType, 0);
}
-
- public override Type MakeArrayType(int rank)
- {
+
+ public override Type MakeArrayType(int rank)
+ {
if (rank <= 0)
throw new IndexOutOfRangeException();
Contract.EndContractBlock();
@@ -308,9 +299,9 @@ namespace System.Reflection.Emit
{
szrank = "*";
}
- else
+ else
{
- for(int i = 1; i < rank; i++)
+ for (int i = 1; i < rank; i++)
szrank += ",";
}
@@ -322,55 +313,55 @@ namespace System.Reflection.Emit
public override int GetArrayRank()
{
if (!IsArray)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
+ throw new NotSupportedException(SR.NotSupported_SubclassOverride);
Contract.EndContractBlock();
return m_cRank;
}
-
- public override Guid GUID
+
+ public override Guid GUID
{
- get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); }
+ get { throw new NotSupportedException(SR.NotSupported_NonReflectedType); }
}
- public override Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target,
+ public override Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target,
Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
- public override Module Module
+ public override Module Module
{
- get
+ get
{
Type baseType;
- for (baseType = m_baseType; baseType is SymbolType; baseType = ((SymbolType) baseType).m_baseType);
+ for (baseType = m_baseType; baseType is SymbolType; baseType = ((SymbolType)baseType).m_baseType) ;
return baseType.Module;
}
}
- public override Assembly Assembly
+ public override Assembly Assembly
{
- get
+ get
{
Type baseType;
- for (baseType = m_baseType; baseType is SymbolType; baseType = ((SymbolType) baseType).m_baseType);
+ for (baseType = m_baseType; baseType is SymbolType; baseType = ((SymbolType)baseType).m_baseType) ;
return baseType.Assembly;
}
}
-
- public override RuntimeTypeHandle TypeHandle
+
+ public override RuntimeTypeHandle TypeHandle
{
- get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); }
+ get { throw new NotSupportedException(SR.NotSupported_NonReflectedType); }
}
-
- public override String Name
+
+ public override String Name
{
- get
- {
+ get
+ {
Type baseType;
String sFormat = m_format;
@@ -380,140 +371,139 @@ namespace System.Reflection.Emit
return baseType.Name + sFormat;
}
}
-
- public override String FullName
+
+ public override String FullName
{
- get
- {
+ get
+ {
return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.FullName);
}
}
- public override String AssemblyQualifiedName
+ public override String AssemblyQualifiedName
{
- get
- {
+ get
+ {
return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.AssemblyQualifiedName);
}
}
public override String ToString()
- {
- return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.ToString);
+ {
+ return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.ToString);
}
-
- public override String Namespace
+
+ public override String Namespace
{
get { return m_baseType.Namespace; }
}
-
- public override Type BaseType
+
+ public override Type BaseType
{
-
get { return typeof(System.Array); }
}
-
- protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr,Binder binder,
- CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers)
+
+ protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder,
+ CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
-
+
public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
-
- protected override MethodInfo GetMethodImpl(String name,BindingFlags bindingAttr,Binder binder,
- CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers)
+
+ protected override MethodInfo GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder,
+ CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
-
+
public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
-
+
public override FieldInfo GetField(String name, BindingFlags bindingAttr)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
-
+
public override FieldInfo[] GetFields(BindingFlags bindingAttr)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
-
- public override Type GetInterface(String name,bool ignoreCase)
+
+ public override Type GetInterface(String name, bool ignoreCase)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
-
+
public override Type[] GetInterfaces()
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
-
- public override EventInfo GetEvent(String name,BindingFlags bindingAttr)
+
+ public override EventInfo GetEvent(String name, BindingFlags bindingAttr)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
-
+
public override EventInfo[] GetEvents()
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
-
- protected override PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder,
+
+ protected override PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder,
Type returnType, Type[] types, ParameterModifier[] modifiers)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
-
+
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
public override Type[] GetNestedTypes(BindingFlags bindingAttr)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
-
+
public override Type GetNestedType(String name, BindingFlags bindingAttr)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
- public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
+ public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
-
+
public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
public override InterfaceMapping GetInterfaceMap(Type interfaceType)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
public override EventInfo[] GetEvents(BindingFlags bindingAttr)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
-
+
protected override TypeAttributes GetAttributeFlagsImpl()
{
// Return the attribute flags of the base type?
Type baseType;
- for (baseType = m_baseType; baseType is SymbolType; baseType = ((SymbolType)baseType).m_baseType);
+ for (baseType = m_baseType; baseType is SymbolType; baseType = ((SymbolType)baseType).m_baseType) ;
return baseType.Attributes;
}
-
+
protected override bool IsArrayImpl()
{
return m_typeKind == TypeKind.IsArray;
@@ -533,12 +523,12 @@ namespace System.Reflection.Emit
{
return false;
}
-
- protected override bool IsValueTypeImpl()
+
+ protected override bool IsValueTypeImpl()
{
return false;
}
-
+
protected override bool IsCOMObjectImpl()
{
return false;
@@ -556,31 +546,30 @@ namespace System.Reflection.Emit
{
return m_baseType;
}
-
+
protected override bool HasElementTypeImpl()
{
return m_baseType != null;
}
-
- public override Type UnderlyingSystemType
+
+ public override Type UnderlyingSystemType
{
-
get { return this; }
}
-
+
public override Object[] GetCustomAttributes(bool inherit)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
- public override bool IsDefined (Type attributeType, bool inherit)
+ public override bool IsDefined(Type attributeType, bool inherit)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType"));
+ throw new NotSupportedException(SR.NotSupported_NonReflectedType);
}
#endregion
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs
index 88502cb096..a98af2bdcf 100644
--- a/src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs
@@ -5,7 +5,8 @@
//
-namespace System.Reflection.Emit {
+namespace System.Reflection.Emit
+{
using System;
using System.Reflection;
using System.Security;
@@ -22,21 +23,22 @@ namespace System.Reflection.Emit {
[Serializable]
public enum PackingSize
{
- Unspecified = 0,
- Size1 = 1,
- Size2 = 2,
- Size4 = 4,
- Size8 = 8,
- Size16 = 16,
- Size32 = 32,
- Size64 = 64,
- Size128 = 128,
+ Unspecified = 0,
+ Size1 = 1,
+ Size2 = 2,
+ Size4 = 4,
+ Size8 = 8,
+ Size16 = 16,
+ Size32 = 32,
+ Size64 = 64,
+ Size128 = 128,
}
public sealed class TypeBuilder : TypeInfo
{
- public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){
- if(typeInfo==null) return false;
+ public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo)
+ {
+ if (typeInfo == null) return false;
return IsAssignableFrom(typeInfo.AsType());
}
@@ -46,7 +48,7 @@ namespace System.Reflection.Emit {
private ConstructorInfo m_con;
private byte[] m_binaryAttribute;
private CustomAttributeBuilder m_customBuilder;
-
+
public CustAttr(ConstructorInfo con, byte[] binaryAttribute)
{
if (con == null)
@@ -83,12 +85,12 @@ namespace System.Reflection.Emit {
}
}
#endregion
-
+
#region Public Static Methods
public static MethodInfo GetMethod(Type type, MethodInfo method)
{
if (!(type is TypeBuilder) && !(type is TypeBuilderInstantiation))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeTypeBuilder"));
+ throw new ArgumentException(SR.Argument_MustBeTypeBuilder);
// The following checks establishes invariants that more simply put require type to be generic and
// method to be a generic method definition declared on the generic type definition of type.
@@ -96,15 +98,15 @@ namespace System.Reflection.Emit {
// this function followed by MakeGenericMethod on the resulting MethodInfo to finally get G<Foo>.M<Bar>.
// We could also allow G<T>.M<Bar> to be created before G<Foo>.M<Bar> (BindGenParm followed by this method)
// if we wanted to but that just complicates things so these checks are designed to prevent that scenario.
-
+
if (method.IsGenericMethod && !method.IsGenericMethodDefinition)
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedGenericMethodDefinition"), nameof(method));
-
+ throw new ArgumentException(SR.Argument_NeedGenericMethodDefinition, nameof(method));
+
if (method.DeclaringType == null || !method.DeclaringType.IsGenericTypeDefinition)
- throw new ArgumentException(Environment.GetResourceString("Argument_MethodNeedGenericDeclaringType"), nameof(method));
-
+ throw new ArgumentException(SR.Argument_MethodNeedGenericDeclaringType, nameof(method));
+
if (type.GetGenericTypeDefinition() != method.DeclaringType)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidMethodDeclaringType"), nameof(type));
+ throw new ArgumentException(SR.Argument_InvalidMethodDeclaringType, nameof(type));
Contract.EndContractBlock();
// The following converts from Type or TypeBuilder of G<T> to TypeBuilderInstantiation G<T>. These types
@@ -112,51 +114,51 @@ namespace System.Reflection.Emit {
// G<M>.M() be encoded by a typeSpec whose parent is the typeDef for G<M> and whose instantiation is also G<M>.
if (type.IsGenericTypeDefinition)
type = type.MakeGenericType(type.GetGenericArguments());
-
+
if (!(type is TypeBuilderInstantiation))
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), nameof(type));
+ throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(type));
return MethodOnTypeBuilderInstantiation.GetMethod(method, type as TypeBuilderInstantiation);
}
public static ConstructorInfo GetConstructor(Type type, ConstructorInfo constructor)
- {
+ {
if (!(type is TypeBuilder) && !(type is TypeBuilderInstantiation))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeTypeBuilder"));
+ throw new ArgumentException(SR.Argument_MustBeTypeBuilder);
if (!constructor.DeclaringType.IsGenericTypeDefinition)
- throw new ArgumentException(Environment.GetResourceString("Argument_ConstructorNeedGenericDeclaringType"), nameof(constructor));
+ throw new ArgumentException(SR.Argument_ConstructorNeedGenericDeclaringType, nameof(constructor));
Contract.EndContractBlock();
-
+
if (!(type is TypeBuilderInstantiation))
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), nameof(type));
+ throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(type));
// TypeBuilder G<T> ==> TypeBuilderInstantiation G<T>
if (type is TypeBuilder && type.IsGenericTypeDefinition)
type = type.MakeGenericType(type.GetGenericArguments());
if (type.GetGenericTypeDefinition() != constructor.DeclaringType)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidConstructorDeclaringType"), nameof(type));
+ throw new ArgumentException(SR.Argument_InvalidConstructorDeclaringType, nameof(type));
return ConstructorOnTypeBuilderInstantiation.GetConstructor(constructor, type as TypeBuilderInstantiation);
}
public static FieldInfo GetField(Type type, FieldInfo field)
{
if (!(type is TypeBuilder) && !(type is TypeBuilderInstantiation))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeTypeBuilder"));
+ throw new ArgumentException(SR.Argument_MustBeTypeBuilder);
if (!field.DeclaringType.IsGenericTypeDefinition)
- throw new ArgumentException(Environment.GetResourceString("Argument_FieldNeedGenericDeclaringType"), nameof(field));
+ throw new ArgumentException(SR.Argument_FieldNeedGenericDeclaringType, nameof(field));
Contract.EndContractBlock();
-
+
if (!(type is TypeBuilderInstantiation))
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), nameof(type));
+ throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(type));
// TypeBuilder G<T> ==> TypeBuilderInstantiation G<T>
if (type is TypeBuilder && type.IsGenericTypeDefinition)
type = type.MakeGenericType(type.GetGenericArguments());
if (type.GetGenericTypeDefinition() != field.DeclaringType)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFieldDeclaringType"), nameof(type));
+ throw new ArgumentException(SR.Argument_InvalidFieldDeclaringType, nameof(type));
return FieldOnTypeBuilderInstantiation.GetField(field, type as TypeBuilderInstantiation);
}
@@ -168,41 +170,41 @@ namespace System.Reflection.Emit {
#region Private Static FCalls
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
+ [SuppressUnmanagedCodeSecurity]
private static extern void SetParentType(RuntimeModule module, int tdTypeDef, int tkParent);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
+ [SuppressUnmanagedCodeSecurity]
private static extern void AddInterfaceImpl(RuntimeModule module, int tdTypeDef, int tkInterface);
#endregion
#region Internal Static FCalls
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- internal static extern int DefineMethod(RuntimeModule module, int tkParent, String name, byte[] signature, int sigLength,
+ [SuppressUnmanagedCodeSecurity]
+ internal static extern int DefineMethod(RuntimeModule module, int tkParent, String name, byte[] signature, int sigLength,
MethodAttributes attributes);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
+ [SuppressUnmanagedCodeSecurity]
internal static extern int DefineMethodSpec(RuntimeModule module, int tkParent, byte[] signature, int sigLength);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- internal static extern int DefineField(RuntimeModule module, int tkParent, String name, byte[] signature, int sigLength,
+ [SuppressUnmanagedCodeSecurity]
+ internal static extern int DefineField(RuntimeModule module, int tkParent, String name, byte[] signature, int sigLength,
FieldAttributes attributes);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern void SetMethodIL(RuntimeModule module, int tk, bool isInitLocals,
+ [SuppressUnmanagedCodeSecurity]
+ private static extern void SetMethodIL(RuntimeModule module, int tk, bool isInitLocals,
byte[] body, int bodyLength,
- byte[] LocalSig, int sigLength,
+ byte[] LocalSig, int sigLength,
int maxStackSize,
- ExceptionHandler[] exceptions, int numExceptions,
- int [] tokenFixups, int numTokenFixups);
+ ExceptionHandler[] exceptions, int numExceptions,
+ int[] tokenFixups, int numTokenFixups);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private static extern void DefineCustomAttribute(RuntimeModule module, int tkAssociate, int tkConstructor,
+ [SuppressUnmanagedCodeSecurity]
+ private static extern void DefineCustomAttribute(RuntimeModule module, int tkAssociate, int tkConstructor,
byte[] attr, int attrLength, bool toDisk, bool updateCompilerFlags);
internal static void DefineCustomAttribute(ModuleBuilder module, int tkAssociate, int tkConstructor,
@@ -216,55 +218,55 @@ namespace System.Reflection.Emit {
Buffer.BlockCopy(attr, 0, localAttr, 0, attr.Length);
}
- DefineCustomAttribute(module.GetNativeHandle(), tkAssociate, tkConstructor,
+ DefineCustomAttribute(module.GetNativeHandle(), tkAssociate, tkConstructor,
localAttr, (localAttr != null) ? localAttr.Length : 0, toDisk, updateCompilerFlags);
}
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
+ [SuppressUnmanagedCodeSecurity]
internal static extern int DefineProperty(RuntimeModule module, int tkParent, String name, PropertyAttributes attributes,
byte[] signature, int sigLength);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
+ [SuppressUnmanagedCodeSecurity]
internal static extern int DefineEvent(RuntimeModule module, int tkParent, String name, EventAttributes attributes, int tkEventType);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- internal static extern void DefineMethodSemantics(RuntimeModule module, int tkAssociation,
+ [SuppressUnmanagedCodeSecurity]
+ internal static extern void DefineMethodSemantics(RuntimeModule module, int tkAssociation,
MethodSemanticsAttributes semantics, int tkMethod);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
+ [SuppressUnmanagedCodeSecurity]
internal static extern void DefineMethodImpl(RuntimeModule module, int tkType, int tkBody, int tkDecl);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
+ [SuppressUnmanagedCodeSecurity]
internal static extern void SetMethodImpl(RuntimeModule module, int tkMethod, MethodImplAttributes MethodImplAttributes);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- internal static extern int SetParamInfo(RuntimeModule module, int tkMethod, int iSequence,
+ [SuppressUnmanagedCodeSecurity]
+ internal static extern int SetParamInfo(RuntimeModule module, int tkMethod, int iSequence,
ParameterAttributes iParamAttributes, String strParamName);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
+ [SuppressUnmanagedCodeSecurity]
internal static extern int GetTokenFromSig(RuntimeModule module, byte[] signature, int sigLength);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
+ [SuppressUnmanagedCodeSecurity]
internal static extern void SetFieldLayoutOffset(RuntimeModule module, int fdToken, int iOffset);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
+ [SuppressUnmanagedCodeSecurity]
internal static extern void SetClassLayout(RuntimeModule module, int tk, PackingSize iPackingSize, int iTypeSize);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
+ [SuppressUnmanagedCodeSecurity]
private static extern unsafe void SetConstantValue(RuntimeModule module, int tk, int corType, void* pValue);
-#endregion
-#region Internal\Private Static Members
+ #endregion
+ #region Internal\Private Static Members
[Pure]
internal static bool IsTypeEqual(Type t1, Type t2)
@@ -273,14 +275,14 @@ namespace System.Reflection.Emit {
if (t1 == t2)
return true;
TypeBuilder tb1 = null;
- TypeBuilder tb2 = null;
- Type runtimeType1 = null;
- Type runtimeType2 = null;
-
+ TypeBuilder tb2 = null;
+ Type runtimeType1 = null;
+ Type runtimeType2 = null;
+
// set up the runtimeType and TypeBuilder type corresponding to t1 and t2
if (t1 is TypeBuilder)
{
- tb1 =(TypeBuilder)t1;
+ tb1 = (TypeBuilder)t1;
// This will be null if it is not baked.
runtimeType1 = tb1.m_bakedRuntimeType;
}
@@ -291,7 +293,7 @@ namespace System.Reflection.Emit {
if (t2 is TypeBuilder)
{
- tb2 =(TypeBuilder)t2;
+ tb2 = (TypeBuilder)t2;
// This will be null if it is not baked.
runtimeType2 = tb2.m_bakedRuntimeType;
}
@@ -299,16 +301,16 @@ namespace System.Reflection.Emit {
{
runtimeType2 = t2;
}
-
+
// If the type builder view is eqaul then it is equal
if (tb1 != null && tb2 != null && Object.ReferenceEquals(tb1, tb2))
return true;
// if the runtimetype view is eqaul than it is equal
- if (runtimeType1 != null && runtimeType2 != null && runtimeType1 == runtimeType2)
+ if (runtimeType1 != null && runtimeType2 != null && runtimeType1 == runtimeType2)
return true;
- return false;
+ return false;
}
internal static unsafe void SetConstantValue(ModuleBuilder module, int tk, Type destType, Object value)
@@ -349,7 +351,7 @@ namespace System.Reflection.Emit {
// The constant value supplied should match either the baked enum type or its underlying type
// we don't need to compare it with the EnumBuilder itself because you can never have an object of that type
if (type != enumBldr.m_typeBuilder.m_bakedRuntimeType && type != underlyingType)
- throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch"));
+ throw new ArgumentException(SR.Argument_ConstantDoesntMatch);
}
else if ((typeBldr = destType as TypeBuilder) != null)
{
@@ -358,7 +360,7 @@ namespace System.Reflection.Emit {
// The constant value supplied should match either the baked enum type or its underlying type
// typeBldr.m_enumUnderlyingType is null if the user hasn't created a "value__" field on the enum
if (underlyingType == null || (type != typeBldr.UnderlyingSystemType && type != underlyingType))
- throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch"));
+ throw new ArgumentException(SR.Argument_ConstantDoesntMatch);
}
else // must be a runtime Enum Type
{
@@ -368,7 +370,7 @@ namespace System.Reflection.Emit {
// The constant value supplied should match either the enum itself or its underlying type
if (type != destType && type != underlyingType)
- throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch"));
+ throw new ArgumentException(SR.Argument_ConstantDoesntMatch);
}
type = underlyingType;
@@ -377,9 +379,9 @@ namespace System.Reflection.Emit {
{
// Note that it is non CLS compliant if destType != type. But RefEmit never guarantees CLS-Compliance.
if (!destType.IsAssignableFrom(type))
- throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch"));
+ throw new ArgumentException(SR.Argument_ConstantDoesntMatch);
}
-
+
CorElementType corType = RuntimeTypeHandle.GetCorElementType((RuntimeType)type);
switch (corType)
@@ -414,7 +416,7 @@ namespace System.Reflection.Emit {
}
else
{
- throw new ArgumentException(Environment.GetResourceString("Argument_ConstantNotSupported", type.ToString()));
+ throw new ArgumentException(SR.Format(SR.Argument_ConstantNotSupported, type.ToString()));
}
break;
}
@@ -425,7 +427,7 @@ namespace System.Reflection.Emit {
{
// nullable types can hold null value.
if (!(destType.IsGenericType && destType.GetGenericTypeDefinition() == typeof(Nullable<>)))
- throw new ArgumentException(Environment.GetResourceString("Argument_ConstantNull"));
+ throw new ArgumentException(SR.Argument_ConstantNull);
}
SetConstantValue(module.GetNativeHandle(), tk, (int)CorElementType.Class, null);
@@ -436,7 +438,7 @@ namespace System.Reflection.Emit {
#region Private Data Members
private List<CustAttr> m_ca;
- private TypeToken m_tdType;
+ private TypeToken m_tdType;
private ModuleBuilder m_module;
private String m_strName;
private String m_strNameSpace;
@@ -483,8 +485,8 @@ namespace System.Reflection.Emit {
{
Contract.Requires(declMeth != null);
m_declMeth = declMeth;
- m_DeclaringType =m_declMeth.GetTypeBuilder();
- m_module =declMeth.GetModuleBuilder();
+ m_DeclaringType = m_declMeth.GetTypeBuilder();
+ m_module = declMeth.GetModuleBuilder();
InitAsGenericParam(szName, genParamPos);
}
@@ -493,7 +495,7 @@ namespace System.Reflection.Emit {
{
Contract.Requires(declType != null);
m_DeclaringType = declType;
- m_module =declType.GetModuleBuilder();
+ m_module = declType.GetModuleBuilder();
InitAsGenericParam(szName, genParamPos);
}
@@ -512,7 +514,7 @@ namespace System.Reflection.Emit {
Type[] interfaces,
ModuleBuilder module,
PackingSize iPackingSize,
- int iTypeSize,
+ int iTypeSize,
TypeBuilder enclosingType)
{
Init(name, attr, parent, interfaces, module, iPackingSize, iTypeSize, enclosingType);
@@ -525,14 +527,14 @@ namespace System.Reflection.Emit {
throw new ArgumentNullException(nameof(fullname));
if (fullname.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(fullname));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(fullname));
if (fullname[0] == '\0')
- throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), nameof(fullname));
+ throw new ArgumentException(SR.Argument_IllegalName, nameof(fullname));
if (fullname.Length > 1023)
- throw new ArgumentException(Environment.GetResourceString("Argument_TypeNameTooLong"), nameof(fullname));
+ throw new ArgumentException(SR.Argument_TypeNameTooLong, nameof(fullname));
Contract.EndContractBlock();
int i;
@@ -547,14 +549,14 @@ namespace System.Reflection.Emit {
{
// Nested Type should have nested attribute set.
// If we are renumbering TypeAttributes' bit, we need to change the logic here.
- if (((attr & TypeAttributes.VisibilityMask) == TypeAttributes.Public) ||((attr & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic))
- throw new ArgumentException(Environment.GetResourceString("Argument_BadNestedTypeFlags"), nameof(attr));
+ if (((attr & TypeAttributes.VisibilityMask) == TypeAttributes.Public) || ((attr & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic))
+ throw new ArgumentException(SR.Argument_BadNestedTypeFlags, nameof(attr));
}
int[] interfaceTokens = null;
if (interfaces != null)
{
- for(i = 0; i < interfaces.Length; i++)
+ for (i = 0; i < interfaces.Length; i++)
{
if (interfaces[i] == null)
{
@@ -563,7 +565,7 @@ namespace System.Reflection.Emit {
}
}
interfaceTokens = new int[interfaces.Length + 1];
- for(i = 0; i < interfaces.Length; i++)
+ for (i = 0; i < interfaces.Length; i++)
{
interfaceTokens[i] = m_module.GetTypeTokenInternal(interfaces[i]).Token;
}
@@ -609,14 +611,14 @@ namespace System.Reflection.Emit {
m_iPackingSize = iPackingSize;
m_iTypeSize = iTypeSize;
- if ((m_iPackingSize != 0) ||(m_iTypeSize != 0))
+ if ((m_iPackingSize != 0) || (m_iTypeSize != 0))
SetClassLayout(GetModuleBuilder().GetNativeHandle(), m_tdType.Token, m_iPackingSize, m_iTypeSize);
m_module.AddType(FullName, this);
}
-#endregion
-#region Private Members
+ #endregion
+ #region Private Members
private FieldBuilder DefineDataHelper(String name, byte[] data, int size, FieldAttributes attributes)
{
@@ -629,10 +631,10 @@ namespace System.Reflection.Emit {
throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
if (size <= 0 || size >= 0x003f0000)
- throw new ArgumentException(Environment.GetResourceString("Argument_BadSizeForData"));
+ throw new ArgumentException(SR.Argument_BadSizeForData);
Contract.EndContractBlock();
ThrowIfCreated();
@@ -653,7 +655,7 @@ namespace System.Reflection.Emit {
valueClassType.CreateType();
}
- fdBuilder = DefineField(name, valueClassType,(attributes | FieldAttributes.Static));
+ fdBuilder = DefineField(name, valueClassType, (attributes | FieldAttributes.Static));
// now we need to set the RVA
fdBuilder.SetData(data, size);
@@ -666,54 +668,54 @@ namespace System.Reflection.Emit {
if (DeclaringType == null)
{
// Not a nested class.
- if (((attr & TypeAttributes.VisibilityMask) != TypeAttributes.NotPublic) &&((attr & TypeAttributes.VisibilityMask) != TypeAttributes.Public))
+ if (((attr & TypeAttributes.VisibilityMask) != TypeAttributes.NotPublic) && ((attr & TypeAttributes.VisibilityMask) != TypeAttributes.Public))
{
- throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeAttrNestedVisibilityOnNonNestedType"));
+ throw new ArgumentException(SR.Argument_BadTypeAttrNestedVisibilityOnNonNestedType);
}
}
else
{
// Nested class.
- if (((attr & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic) ||((attr & TypeAttributes.VisibilityMask) == TypeAttributes.Public))
+ if (((attr & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic) || ((attr & TypeAttributes.VisibilityMask) == TypeAttributes.Public))
{
- throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeAttrNonNestedVisibilityNestedType"));
+ throw new ArgumentException(SR.Argument_BadTypeAttrNonNestedVisibilityNestedType);
}
}
// Verify that the layout mask is valid.
- if (((attr & TypeAttributes.LayoutMask) != TypeAttributes.AutoLayout) &&((attr & TypeAttributes.LayoutMask) != TypeAttributes.SequentialLayout) &&((attr & TypeAttributes.LayoutMask) != TypeAttributes.ExplicitLayout))
+ if (((attr & TypeAttributes.LayoutMask) != TypeAttributes.AutoLayout) && ((attr & TypeAttributes.LayoutMask) != TypeAttributes.SequentialLayout) && ((attr & TypeAttributes.LayoutMask) != TypeAttributes.ExplicitLayout))
{
- throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeAttrInvalidLayout"));
+ throw new ArgumentException(SR.Argument_BadTypeAttrInvalidLayout);
}
// Check if the user attempted to set any reserved bits.
if ((attr & TypeAttributes.ReservedMask) != 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeAttrReservedBitsSet"));
+ throw new ArgumentException(SR.Argument_BadTypeAttrReservedBitsSet);
}
}
[Pure]
public bool IsCreated()
- {
+ {
return m_hasBeenCreated;
}
-
+
#endregion
#region FCalls
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
+ [SuppressUnmanagedCodeSecurity]
private extern static int DefineType(RuntimeModule module,
String fullname, int tkParent, TypeAttributes attributes, int tkEnclosingType, int[] interfaceTokens);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
+ [SuppressUnmanagedCodeSecurity]
private extern static int DefineGenericParam(RuntimeModule module,
String name, int tkParent, GenericParameterAttributes attributes, int position, int[] constraints);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
+ [SuppressUnmanagedCodeSecurity]
private static extern void TermCreateClass(RuntimeModule module, int tk, ObjectHandleOnStack type);
#endregion
@@ -721,7 +723,7 @@ namespace System.Reflection.Emit {
internal void ThrowIfCreated()
{
if (IsCreated())
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TypeHasBeenCreated"));
+ throw new InvalidOperationException(SR.InvalidOperation_TypeHasBeenCreated);
}
internal object SyncRoot
@@ -749,12 +751,12 @@ namespace System.Reflection.Emit {
{
m_genParamAttributes = genericParameterAttributes;
}
-
+
internal void SetGenParamCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
{
CustAttr ca = new CustAttr(con, binaryAttribute);
- lock(SyncRoot)
+ lock (SyncRoot)
{
SetGenParamCustomAttributeNoLock(ca);
}
@@ -764,7 +766,7 @@ namespace System.Reflection.Emit {
{
CustAttr ca = new CustAttr(customBuilder);
- lock(SyncRoot)
+ lock (SyncRoot)
{
SetGenParamCustomAttributeNoLock(ca);
}
@@ -774,7 +776,7 @@ namespace System.Reflection.Emit {
{
if (m_ca == null)
m_ca = new List<TypeBuilder.CustAttr>();
-
+
m_ca.Add(ca);
}
#endregion
@@ -782,30 +784,30 @@ namespace System.Reflection.Emit {
#region Object Overrides
public override String ToString()
{
- return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.ToString);
+ return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.ToString);
}
#endregion
#region MemberInfo Overrides
- public override Type DeclaringType
+ public override Type DeclaringType
{
get { return m_DeclaringType; }
}
- public override Type ReflectedType
+ public override Type ReflectedType
{
// Return the class that was used to obtain this field.
-
+
get { return m_DeclaringType; }
}
- public override String Name
+ public override String Name
{
get { return m_strName; }
}
- public override Module Module
+ public override Module Module
{
get { return GetModuleBuilder(); }
}
@@ -818,12 +820,12 @@ namespace System.Reflection.Emit {
#endregion
#region Type Overrides
- public override Guid GUID
+ public override Guid GUID
{
- get
+ get
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return m_bakedRuntimeType.GUID;
@@ -834,27 +836,26 @@ namespace System.Reflection.Emit {
Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return m_bakedRuntimeType.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
}
- public override Assembly Assembly
+ public override Assembly Assembly
{
get { return m_module.Assembly; }
}
- public override RuntimeTypeHandle TypeHandle
+ public override RuntimeTypeHandle TypeHandle
{
-
- get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); }
+ get { throw new NotSupportedException(SR.NotSupported_DynamicModule); }
}
- public override String FullName
+ public override String FullName
{
- get
- {
+ get
+ {
if (m_strFullQualName == null)
m_strFullQualName = TypeNameBuilder.ToString(this, TypeNameBuilder.Format.FullName);
@@ -862,29 +863,29 @@ namespace System.Reflection.Emit {
}
}
- public override String Namespace
+ public override String Namespace
{
get { return m_strNameSpace; }
}
- public override String AssemblyQualifiedName
+ public override String AssemblyQualifiedName
{
- get
- {
+ get
+ {
return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.AssemblyQualifiedName);
}
}
- public override Type BaseType
+ public override Type BaseType
{
- get{ return m_typeParent; }
+ get { return m_typeParent; }
}
- protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr,Binder binder,
- CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers)
+ protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder,
+ CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return m_bakedRuntimeType.GetConstructor(bindingAttr, binder, callConvention, types, modifiers);
@@ -893,17 +894,17 @@ namespace System.Reflection.Emit {
public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return m_bakedRuntimeType.GetConstructors(bindingAttr);
}
- protected override MethodInfo GetMethodImpl(String name,BindingFlags bindingAttr,Binder binder,
- CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers)
+ protected override MethodInfo GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder,
+ CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
if (types == null)
@@ -919,7 +920,7 @@ namespace System.Reflection.Emit {
public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return m_bakedRuntimeType.GetMethods(bindingAttr);
@@ -928,7 +929,7 @@ namespace System.Reflection.Emit {
public override FieldInfo GetField(String name, BindingFlags bindingAttr)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return m_bakedRuntimeType.GetField(name, bindingAttr);
@@ -937,18 +938,18 @@ namespace System.Reflection.Emit {
public override FieldInfo[] GetFields(BindingFlags bindingAttr)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return m_bakedRuntimeType.GetFields(bindingAttr);
}
- public override Type GetInterface(String name,bool ignoreCase)
+ public override Type GetInterface(String name, bool ignoreCase)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
-
+
return m_bakedRuntimeType.GetInterface(name, ignoreCase);
}
@@ -961,16 +962,16 @@ namespace System.Reflection.Emit {
if (m_typeInterfaces == null)
{
- return EmptyArray<Type>.Value;
+ return Array.Empty<Type>();
}
return m_typeInterfaces.ToArray();
}
- public override EventInfo GetEvent(String name,BindingFlags bindingAttr)
+ public override EventInfo GetEvent(String name, BindingFlags bindingAttr)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return m_bakedRuntimeType.GetEvent(name, bindingAttr);
@@ -979,7 +980,7 @@ namespace System.Reflection.Emit {
public override EventInfo[] GetEvents()
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return m_bakedRuntimeType.GetEvents();
@@ -988,13 +989,13 @@ namespace System.Reflection.Emit {
protected override PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder,
Type returnType, Type[] types, ParameterModifier[] modifiers)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return m_bakedRuntimeType.GetProperties(bindingAttr);
@@ -1003,7 +1004,7 @@ namespace System.Reflection.Emit {
public override Type[] GetNestedTypes(BindingFlags bindingAttr)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return m_bakedRuntimeType.GetNestedTypes(bindingAttr);
@@ -1012,16 +1013,16 @@ namespace System.Reflection.Emit {
public override Type GetNestedType(String name, BindingFlags bindingAttr)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
- return m_bakedRuntimeType.GetNestedType(name,bindingAttr);
+ return m_bakedRuntimeType.GetNestedType(name, bindingAttr);
}
public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return m_bakedRuntimeType.GetMember(name, type, bindingAttr);
@@ -1030,7 +1031,7 @@ namespace System.Reflection.Emit {
public override InterfaceMapping GetInterfaceMap(Type interfaceType)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return m_bakedRuntimeType.GetInterfaceMap(interfaceType);
@@ -1039,7 +1040,7 @@ namespace System.Reflection.Emit {
public override EventInfo[] GetEvents(BindingFlags bindingAttr)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return m_bakedRuntimeType.GetEvents(bindingAttr);
@@ -1048,66 +1049,68 @@ namespace System.Reflection.Emit {
public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return m_bakedRuntimeType.GetMembers(bindingAttr);
}
-
+
public override bool IsAssignableFrom(Type c)
{
if (TypeBuilder.IsTypeEqual(c, this))
return true;
-
+
Type fromRuntimeType = null;
TypeBuilder fromTypeBuilder = c as TypeBuilder;
-
+
if (fromTypeBuilder != null)
fromRuntimeType = fromTypeBuilder.m_bakedRuntimeType;
else
fromRuntimeType = c;
-
+
if (fromRuntimeType != null && fromRuntimeType is RuntimeType)
{
// fromType is baked. So if this type is not baked, it cannot be assignable to!
if (m_bakedRuntimeType == null)
return false;
-
+
// since toType is also baked, delegate to the base
return m_bakedRuntimeType.IsAssignableFrom(fromRuntimeType);
}
-
+
// So if c is not a runtimeType nor TypeBuilder. We don't know how to deal with it.
// return false then.
if (fromTypeBuilder == null)
return false;
-
+
// If fromTypeBuilder is a subclass of this class, then c can be cast to this type.
if (fromTypeBuilder.IsSubclassOf(this))
return true;
-
+
if (this.IsInterface == false)
return false;
-
+
// now is This type a base type on one of the interface impl?
Type[] interfaces = fromTypeBuilder.GetInterfaces();
- for(int i = 0; i < interfaces.Length; i++)
+ for (int i = 0; i < interfaces.Length; i++)
{
// unfortunately, IsSubclassOf does not cover the case when they are the same type.
if (TypeBuilder.IsTypeEqual(interfaces[i], this))
return true;
-
+
if (interfaces[i].IsSubclassOf(this))
return true;
}
- return false;
- }
+ return false;
+ }
protected override TypeAttributes GetAttributeFlagsImpl()
{
return m_iAttr;
}
+ public override bool IsSZArray => false;
+
protected override bool IsArrayImpl()
{
return false;
@@ -1127,14 +1130,13 @@ namespace System.Reflection.Emit {
protected override bool IsCOMObjectImpl()
{
- return((GetAttributeFlagsImpl() & TypeAttributes.Import) != 0) ? true : false;
+ return ((GetAttributeFlagsImpl() & TypeAttributes.Import) != 0) ? true : false;
}
public override Type GetElementType()
{
-
// You will never have to deal with a TypeBuilder if you are just referring to arrays.
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
}
protected override bool HasElementTypeImpl()
@@ -1165,9 +1167,9 @@ namespace System.Reflection.Emit {
if (TypeBuilder.IsTypeEqual(p, c))
return false;
- p = p.BaseType;
-
- while(p != null)
+ p = p.BaseType;
+
+ while (p != null)
{
if (TypeBuilder.IsTypeEqual(p, c))
return true;
@@ -1177,10 +1179,10 @@ namespace System.Reflection.Emit {
return false;
}
-
- public override Type UnderlyingSystemType
+
+ public override Type UnderlyingSystemType
{
- get
+ get
{
if (m_bakedRuntimeType != null)
return m_bakedRuntimeType;
@@ -1188,9 +1190,9 @@ namespace System.Reflection.Emit {
if (IsEnum)
{
if (m_enumUnderlyingType == null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoUnderlyingTypeOnEnum"));
-
- return m_enumUnderlyingType;
+ throw new InvalidOperationException(SR.InvalidOperation_NoUnderlyingTypeOnEnum);
+
+ return m_enumUnderlyingType;
}
else
{
@@ -1199,22 +1201,22 @@ namespace System.Reflection.Emit {
}
}
- public override Type MakePointerType()
- {
- return SymbolType.FormCompoundType("*", this, 0);
+ public override Type MakePointerType()
+ {
+ return SymbolType.FormCompoundType("*", this, 0);
}
- public override Type MakeByRefType()
+ public override Type MakeByRefType()
{
return SymbolType.FormCompoundType("&", this, 0);
}
- public override Type MakeArrayType()
+ public override Type MakeArrayType()
{
return SymbolType.FormCompoundType("[]", this, 0);
}
- public override Type MakeArrayType(int rank)
+ public override Type MakeArrayType(int rank)
{
if (rank <= 0)
throw new IndexOutOfRangeException();
@@ -1225,9 +1227,9 @@ namespace System.Reflection.Emit {
{
szrank = "*";
}
- else
+ else
{
- for(int i = 1; i < rank; i++)
+ for (int i = 1; i < rank; i++)
szrank += ",";
}
@@ -1241,7 +1243,7 @@ namespace System.Reflection.Emit {
public override Object[] GetCustomAttributes(bool inherit)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
Contract.EndContractBlock();
return CustomAttribute.GetCustomAttributes(m_bakedRuntimeType, typeof(object) as RuntimeType, inherit);
@@ -1250,7 +1252,7 @@ namespace System.Reflection.Emit {
public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));
@@ -1259,7 +1261,7 @@ namespace System.Reflection.Emit {
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
return CustomAttribute.GetCustomAttributes(m_bakedRuntimeType, attributeRuntimeType, inherit);
}
@@ -1267,7 +1269,7 @@ namespace System.Reflection.Emit {
public override bool IsDefined(Type attributeType, bool inherit)
{
if (!IsCreated())
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated"));
+ throw new NotSupportedException(SR.NotSupported_TypeNotYetCreated);
if (attributeType == null)
throw new ArgumentNullException(nameof(attributeType));
@@ -1276,7 +1278,7 @@ namespace System.Reflection.Emit {
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
return CustomAttribute.IsDefined(m_bakedRuntimeType, attributeRuntimeType, inherit);
}
@@ -1284,12 +1286,12 @@ namespace System.Reflection.Emit {
#endregion
#region Public Member
-
+
#region DefineType
public override GenericParameterAttributes GenericParameterAttributes { get { return m_genParamAttributes; } }
- internal void SetInterfaces(params Type[] interfaces)
- {
+ internal void SetInterfaces(params Type[] interfaces)
+ {
ThrowIfCreated();
m_typeInterfaces = new List<Type>();
@@ -1308,8 +1310,8 @@ namespace System.Reflection.Emit {
if (names.Length == 0)
throw new ArgumentException();
Contract.EndContractBlock();
-
- for (int i = 0; i < names.Length; i ++)
+
+ for (int i = 0; i < names.Length; i++)
if (names[i] == null)
throw new ArgumentNullException(nameof(names));
@@ -1317,25 +1319,25 @@ namespace System.Reflection.Emit {
throw new InvalidOperationException();
m_inst = new GenericTypeParameterBuilder[names.Length];
- for(int i = 0; i < names.Length; i ++)
+ for (int i = 0; i < names.Length; i++)
m_inst[i] = new GenericTypeParameterBuilder(new TypeBuilder(names[i], i, this));
return m_inst;
}
-
- public override Type MakeGenericType(params Type[] typeArguments)
- {
+
+ public override Type MakeGenericType(params Type[] typeArguments)
+ {
CheckContext(typeArguments);
-
- return TypeBuilderInstantiation.MakeGenericType(this, typeArguments);
+
+ return TypeBuilderInstantiation.MakeGenericType(this, typeArguments);
}
-
+
public override Type[] GetGenericArguments() { return m_inst; }
// If a TypeBuilder is generic, it must be a generic type definition
// All instantiated generic types are TypeBuilderInstantiation.
public override bool IsGenericTypeDefinition { get { return IsGenericType; } }
- public override bool IsGenericType { get { return m_inst != null; } }
+ public override bool IsGenericType { get { return m_inst != null; } }
public override bool IsGenericParameter { get { return m_bIsGenParam; } }
public override bool IsConstructedGenericType { get { return false; } }
@@ -1347,7 +1349,7 @@ namespace System.Reflection.Emit {
#region Define Method
public void DefineMethodOverride(MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
DefineMethodOverrideNoLock(methodInfoBody, methodInfoDeclaration);
}
@@ -1363,13 +1365,13 @@ namespace System.Reflection.Emit {
Contract.EndContractBlock();
ThrowIfCreated();
-
+
if (!object.ReferenceEquals(methodInfoBody.DeclaringType, this))
// Loader restriction: body method has to be from this class
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_BadMethodImplBody"));
-
- MethodToken tkBody;
- MethodToken tkDecl;
+ throw new ArgumentException(SR.ArgumentException_BadMethodImplBody);
+
+ MethodToken tkBody;
+ MethodToken tkDecl;
tkBody = m_module.GetMethodTokenInternal(methodInfoBody);
tkDecl = m_module.GetMethodTokenInternal(methodInfoDeclaration);
@@ -1405,21 +1407,21 @@ namespace System.Reflection.Emit {
return DefineMethod(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null);
}
-
+
public MethodBuilder DefineMethod(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
{
Contract.Ensures(Contract.Result<MethodBuilder>() != null);
- lock(SyncRoot)
+ lock (SyncRoot)
{
- return DefineMethodNoLock(name, attributes, callingConvention, returnType, returnTypeRequiredCustomModifiers,
- returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers,
+ return DefineMethodNoLock(name, attributes, callingConvention, returnType, returnTypeRequiredCustomModifiers,
+ returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers,
parameterTypeOptionalCustomModifiers);
}
}
-
+
private MethodBuilder DefineMethodNoLock(String name, MethodAttributes attributes, CallingConventions callingConvention,
Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
@@ -1428,7 +1430,7 @@ namespace System.Reflection.Emit {
throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
Contract.Ensures(Contract.Result<MethodBuilder>() != null);
Contract.EndContractBlock();
@@ -1440,10 +1442,10 @@ namespace System.Reflection.Emit {
if (parameterTypes != null)
{
if (parameterTypeOptionalCustomModifiers != null && parameterTypeOptionalCustomModifiers.Length != parameterTypes.Length)
- throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", nameof(parameterTypeOptionalCustomModifiers), nameof(parameterTypes)));
+ throw new ArgumentException(SR.Format(SR.Argument_MismatchedArrays, nameof(parameterTypeOptionalCustomModifiers), nameof(parameterTypes)));
if (parameterTypeRequiredCustomModifiers != null && parameterTypeRequiredCustomModifiers.Length != parameterTypes.Length)
- throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", nameof(parameterTypeRequiredCustomModifiers), nameof(parameterTypes)));
+ throw new ArgumentException(SR.Format(SR.Argument_MismatchedArrays, nameof(parameterTypeRequiredCustomModifiers), nameof(parameterTypes)));
}
ThrowIfCreated();
@@ -1451,21 +1453,21 @@ namespace System.Reflection.Emit {
if (!m_isHiddenGlobalType)
{
if (((m_iAttr & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface) &&
- (attributes & MethodAttributes.Abstract) == 0 &&(attributes & MethodAttributes.Static) == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_BadAttributeOnInterfaceMethod"));
+ (attributes & MethodAttributes.Abstract) == 0 && (attributes & MethodAttributes.Static) == 0)
+ throw new ArgumentException(SR.Argument_BadAttributeOnInterfaceMethod);
}
// pass in Method attributes
MethodBuilder method = new MethodBuilder(
- name, attributes, callingConvention,
+ name, attributes, callingConvention,
returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
- parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers,
+ parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers,
m_module, this, false);
if (!m_isHiddenGlobalType)
{
//If this method is declared to be a constructor, increment our constructor count.
- if ((method.Attributes & MethodAttributes.SpecialName) != 0 && method.Name.Equals(ConstructorInfo.ConstructorName))
+ if ((method.Attributes & MethodAttributes.SpecialName) != 0 && method.Name.Equals(ConstructorInfo.ConstructorName))
{
m_constructorCount++;
}
@@ -1481,7 +1483,7 @@ namespace System.Reflection.Emit {
#region Define Constructor
public ConstructorBuilder DefineTypeInitializer()
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineTypeInitializerNoLock();
}
@@ -1504,10 +1506,10 @@ namespace System.Reflection.Emit {
{
if ((m_iAttr & TypeAttributes.Interface) == TypeAttributes.Interface)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ConstructorNotAllowedOnInterface"));
+ throw new InvalidOperationException(SR.InvalidOperation_ConstructorNotAllowedOnInterface);
}
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineDefaultConstructorNoLock(attributes);
}
@@ -1533,14 +1535,14 @@ namespace System.Reflection.Emit {
genericTypeDefinition = ((TypeBuilder)genericTypeDefinition).m_bakedRuntimeType;
if (genericTypeDefinition == null)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule"));
+ throw new NotSupportedException(SR.NotSupported_DynamicModule);
Type inst = genericTypeDefinition.MakeGenericType(m_typeParent.GetGenericArguments());
if (inst is TypeBuilderInstantiation)
con = TypeBuilder.GetConstructor(inst, genericTypeDefinition.GetConstructor(
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null));
- else
+ else
con = inst.GetConstructor(
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
}
@@ -1551,7 +1553,7 @@ namespace System.Reflection.Emit {
}
if (con == null)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NoParentDefaultConstructor"));
+ throw new NotSupportedException(SR.NotSupported_NoParentDefaultConstructor);
// Define the constructor Builder
constBuilder = DefineConstructor(attributes, CallingConventions.Standard, null);
@@ -1560,7 +1562,7 @@ namespace System.Reflection.Emit {
// generate the code to call the parent's default constructor
ILGenerator il = constBuilder.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
- il.Emit(OpCodes.Call,con);
+ il.Emit(OpCodes.Call, con);
il.Emit(OpCodes.Ret);
constBuilder.m_isDefaultConstructor = true;
@@ -1572,21 +1574,21 @@ namespace System.Reflection.Emit {
return DefineConstructor(attributes, callingConvention, parameterTypes, null, null);
}
- public ConstructorBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention,
+ public ConstructorBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention,
Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
{
if ((m_iAttr & TypeAttributes.Interface) == TypeAttributes.Interface && (attributes & MethodAttributes.Static) != MethodAttributes.Static)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ConstructorNotAllowedOnInterface"));
+ throw new InvalidOperationException(SR.InvalidOperation_ConstructorNotAllowedOnInterface);
}
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineConstructorNoLock(attributes, callingConvention, parameterTypes, requiredCustomModifiers, optionalCustomModifiers);
}
}
- private ConstructorBuilder DefineConstructorNoLock(MethodAttributes attributes, CallingConventions callingConvention,
+ private ConstructorBuilder DefineConstructorNoLock(MethodAttributes attributes, CallingConventions callingConvention,
Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
{
CheckContext(parameterTypes);
@@ -1608,8 +1610,8 @@ namespace System.Reflection.Emit {
attributes = attributes | MethodAttributes.SpecialName;
- ConstructorBuilder constBuilder =
- new ConstructorBuilder(name, attributes, callingConvention,
+ ConstructorBuilder constBuilder =
+ new ConstructorBuilder(name, attributes, callingConvention,
parameterTypes, requiredCustomModifiers, optionalCustomModifiers, m_module, this);
m_constructorCount++;
@@ -1622,7 +1624,7 @@ namespace System.Reflection.Emit {
#region Define Nested Type
public TypeBuilder DefineNestedType(String name)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineNestedTypeNoLock(name, TypeAttributes.NestedPrivate, null, null, PackingSize.Unspecified, UnspecifiedTypeSize);
}
@@ -1630,7 +1632,7 @@ namespace System.Reflection.Emit {
public TypeBuilder DefineNestedType(String name, TypeAttributes attr, Type parent, Type[] interfaces)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
// Why do we only call CheckContext here? Why don't we call it in the other overloads?
CheckContext(parent);
@@ -1642,7 +1644,7 @@ namespace System.Reflection.Emit {
public TypeBuilder DefineNestedType(String name, TypeAttributes attr, Type parent)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineNestedTypeNoLock(name, attr, parent, null, PackingSize.Unspecified, UnspecifiedTypeSize);
}
@@ -1650,7 +1652,7 @@ namespace System.Reflection.Emit {
public TypeBuilder DefineNestedType(String name, TypeAttributes attr)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineNestedTypeNoLock(name, attr, null, null, PackingSize.Unspecified, UnspecifiedTypeSize);
}
@@ -1658,7 +1660,7 @@ namespace System.Reflection.Emit {
public TypeBuilder DefineNestedType(String name, TypeAttributes attr, Type parent, int typeSize)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineNestedTypeNoLock(name, attr, parent, null, PackingSize.Unspecified, typeSize);
}
@@ -1666,7 +1668,7 @@ namespace System.Reflection.Emit {
public TypeBuilder DefineNestedType(String name, TypeAttributes attr, Type parent, PackingSize packSize)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineNestedTypeNoLock(name, attr, parent, null, packSize, UnspecifiedTypeSize);
}
@@ -1688,22 +1690,22 @@ namespace System.Reflection.Emit {
#endregion
#region Define Field
- public FieldBuilder DefineField(String fieldName, Type type, FieldAttributes attributes)
+ public FieldBuilder DefineField(String fieldName, Type type, FieldAttributes attributes)
{
return DefineField(fieldName, type, null, null, attributes);
}
- public FieldBuilder DefineField(String fieldName, Type type, Type[] requiredCustomModifiers,
- Type[] optionalCustomModifiers, FieldAttributes attributes)
+ public FieldBuilder DefineField(String fieldName, Type type, Type[] requiredCustomModifiers,
+ Type[] optionalCustomModifiers, FieldAttributes attributes)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineFieldNoLock(fieldName, type, requiredCustomModifiers, optionalCustomModifiers, attributes);
}
}
- private FieldBuilder DefineFieldNoLock(String fieldName, Type type, Type[] requiredCustomModifiers,
- Type[] optionalCustomModifiers, FieldAttributes attributes)
+ private FieldBuilder DefineFieldNoLock(String fieldName, Type type, Type[] requiredCustomModifiers,
+ Type[] optionalCustomModifiers, FieldAttributes attributes)
{
ThrowIfCreated();
CheckContext(type);
@@ -1715,7 +1717,7 @@ namespace System.Reflection.Emit {
{
// remember the underlying type for enum type
m_enumUnderlyingType = type;
- }
+ }
}
return new FieldBuilder(this, fieldName, type, requiredCustomModifiers, optionalCustomModifiers, attributes);
@@ -1723,7 +1725,7 @@ namespace System.Reflection.Emit {
public FieldBuilder DefineInitializedData(String name, byte[] data, FieldAttributes attributes)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineInitializedDataNoLock(name, data, attributes);
}
@@ -1744,7 +1746,7 @@ namespace System.Reflection.Emit {
public FieldBuilder DefineUninitializedData(String name, int size, FieldAttributes attributes)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineUninitializedDataNoLock(name, size, attributes);
}
@@ -1763,44 +1765,44 @@ namespace System.Reflection.Emit {
#region Define Properties and Events
public PropertyBuilder DefineProperty(String name, PropertyAttributes attributes, Type returnType, Type[] parameterTypes)
{
- return DefineProperty(name, attributes, returnType, null, null, parameterTypes, null, null);
+ return DefineProperty(name, attributes, returnType, null, null, parameterTypes, null, null);
}
- public PropertyBuilder DefineProperty(String name, PropertyAttributes attributes,
+ public PropertyBuilder DefineProperty(String name, PropertyAttributes attributes,
CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
{
- return DefineProperty(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null);
+ return DefineProperty(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null);
}
- public PropertyBuilder DefineProperty(String name, PropertyAttributes attributes,
- Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
+ public PropertyBuilder DefineProperty(String name, PropertyAttributes attributes,
+ Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
{
- return DefineProperty(name, attributes, (CallingConventions)0, returnType,
- returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
- parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
+ return DefineProperty(name, attributes, (CallingConventions)0, returnType,
+ returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
+ parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
}
- public PropertyBuilder DefineProperty(String name, PropertyAttributes attributes, CallingConventions callingConvention,
- Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
+ public PropertyBuilder DefineProperty(String name, PropertyAttributes attributes, CallingConventions callingConvention,
+ Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
- return DefinePropertyNoLock(name, attributes, callingConvention, returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
+ return DefinePropertyNoLock(name, attributes, callingConvention, returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
}
}
private PropertyBuilder DefinePropertyNoLock(String name, PropertyAttributes attributes, CallingConventions callingConvention,
- Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
+ Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
{
if (name == null)
throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
Contract.EndContractBlock();
CheckContext(returnType);
@@ -1809,8 +1811,8 @@ namespace System.Reflection.Emit {
CheckContext(parameterTypeOptionalCustomModifiers);
SignatureHelper sigHelper;
- int sigLength;
- byte[] sigBytes;
+ int sigLength;
+ byte[] sigBytes;
ThrowIfCreated();
@@ -1844,7 +1846,7 @@ namespace System.Reflection.Emit {
public EventBuilder DefineEvent(String name, EventAttributes attributes, Type eventtype)
{
- lock(SyncRoot)
+ lock (SyncRoot)
{
return DefineEventNoLock(name, attributes, eventtype);
}
@@ -1855,19 +1857,19 @@ namespace System.Reflection.Emit {
if (name == null)
throw new ArgumentNullException(nameof(name));
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
if (name[0] == '\0')
- throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), nameof(name));
+ throw new ArgumentException(SR.Argument_IllegalName, nameof(name));
Contract.EndContractBlock();
int tkType;
- EventToken evToken;
-
+ EventToken evToken;
+
CheckContext(eventtype);
ThrowIfCreated();
- tkType = m_module.GetTypeTokenInternal( eventtype ).Token;
+ tkType = m_module.GetTypeTokenInternal(eventtype).Token;
// Internal helpers to define property records
evToken = new EventToken(DefineEvent(
@@ -1909,7 +1911,7 @@ namespace System.Reflection.Emit {
internal void CheckContext(params Type[][] typess)
{
- m_module.CheckContext(typess);
+ m_module.CheckContext(typess);
}
internal void CheckContext(params Type[] types)
{
@@ -1927,7 +1929,7 @@ namespace System.Reflection.Emit {
m_typeInterfaces = new List<Type>();
int[] interfaceTokens = new int[m_typeInterfaces.Count];
- for(int i = 0; i < m_typeInterfaces.Count; i++)
+ for (int i = 0; i < m_typeInterfaces.Count; i++)
{
interfaceTokens[i] = m_module.GetTypeTokenInternal(m_typeInterfaces[i]).Token;
}
@@ -1976,16 +1978,16 @@ namespace System.Reflection.Emit {
// Check for global typebuilder
if (((m_tdType.Token & 0x00FFFFFF) != 0) && ((tkParent & 0x00FFFFFF) != 0))
SetParentType(m_module.GetNativeHandle(), m_tdType.Token, tkParent);
-
+
if (m_inst != null)
foreach (Type tb in m_inst)
if (tb is GenericTypeParameterBuilder)
((GenericTypeParameterBuilder)tb).m_type.CreateType();
}
- byte [] body;
+ byte[] body;
MethodAttributes methodAttrs;
-
+
if (!m_isHiddenGlobalType)
{
// create a public default constructor if this class has no constructor.
@@ -1998,7 +2000,7 @@ namespace System.Reflection.Emit {
int size = m_listMethods.Count;
- for(int i = 0; i < size; i++)
+ for (int i = 0; i < size; i++)
{
MethodBuilder meth = m_listMethods[i];
@@ -2009,19 +2011,19 @@ namespace System.Reflection.Emit {
methodAttrs = meth.Attributes;
// Any of these flags in the implemenation flags is set, we will not attach the IL method body
- if (((meth.GetMethodImplementationFlags() &(MethodImplAttributes.CodeTypeMask|MethodImplAttributes.PreserveSig|MethodImplAttributes.Unmanaged)) != MethodImplAttributes.IL) ||
- ((methodAttrs & MethodAttributes.PinvokeImpl) !=(MethodAttributes) 0))
+ if (((meth.GetMethodImplementationFlags() & (MethodImplAttributes.CodeTypeMask | MethodImplAttributes.PreserveSig | MethodImplAttributes.Unmanaged)) != MethodImplAttributes.IL) ||
+ ((methodAttrs & MethodAttributes.PinvokeImpl) != (MethodAttributes)0))
{
continue;
}
int sigLength;
byte[] localSig = meth.GetLocalSignature(out sigLength);
-
+
// Check that they haven't declared an abstract method on a non-abstract class
- if (((methodAttrs & MethodAttributes.Abstract) != 0) &&((m_iAttr & TypeAttributes.Abstract) == 0))
+ if (((methodAttrs & MethodAttributes.Abstract) != 0) && ((m_iAttr & TypeAttributes.Abstract) == 0))
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadTypeAttributesNotAbstract"));
+ throw new InvalidOperationException(SR.InvalidOperation_BadTypeAttributesNotAbstract);
}
body = meth.GetBody();
@@ -2036,7 +2038,7 @@ namespace System.Reflection.Emit {
//((m_iAttr & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface))
if (body != null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadMethodBody"));
+ throw new InvalidOperationException(SR.InvalidOperation_BadMethodBody);
}
else if (body == null || body.Length == 0)
{
@@ -2051,7 +2053,7 @@ namespace System.Reflection.Emit {
if ((body == null || body.Length == 0) && !meth.m_canBeRuntimeImpl)
throw new InvalidOperationException(
- Environment.GetResourceString("InvalidOperation_BadEmptyMethodBody", meth.Name) );
+ SR.Format(SR.InvalidOperation_BadEmptyMethodBody, meth.Name));
}
int maxStack = meth.GetMaxStack();
@@ -2059,7 +2061,7 @@ namespace System.Reflection.Emit {
ExceptionHandler[] exceptions = meth.GetExceptionHandlers();
int[] tokenFixups = meth.GetTokenFixups();
- SetMethodIL(m_module.GetNativeHandle(), meth.GetToken().Token, meth.InitLocals,
+ SetMethodIL(m_module.GetNativeHandle(), meth.GetToken().Token, meth.InitLocals,
body, (body != null) ? body.Length : 0,
localSig, sigLength, maxStack,
exceptions, (exceptions != null) ? exceptions.Length : 0,
@@ -2086,7 +2088,7 @@ namespace System.Reflection.Emit {
// if this type is a nested type, we need to invalidate the cached nested runtime type on the nesting type
if (m_DeclaringType != null && m_DeclaringType.m_bakedRuntimeType != null)
{
- m_DeclaringType.m_bakedRuntimeType.InvalidateCachedNestedType();
+ m_DeclaringType.m_bakedRuntimeType.InvalidateCachedNestedType();
}
return cls;
@@ -2104,8 +2106,8 @@ namespace System.Reflection.Emit {
{
get { return m_iTypeSize; }
}
-
- public PackingSize PackingSize
+
+ public PackingSize PackingSize
{
get { return m_iPackingSize; }
}
@@ -2119,7 +2121,7 @@ namespace System.Reflection.Emit {
CheckContext(parent);
if (parent.IsInterface)
- throw new ArgumentException(Environment.GetResourceString("Argument_CannotSetParentToInterface"));
+ throw new ArgumentException(SR.Argument_CannotSetParentToInterface);
m_typeParent = parent;
}
@@ -2132,7 +2134,7 @@ namespace System.Reflection.Emit {
else
{
if ((m_iAttr & TypeAttributes.Abstract) == 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadInterfaceNotAbstract"));
+ throw new InvalidOperationException(SR.InvalidOperation_BadInterfaceNotAbstract);
// there is no extends for interface class
m_typeParent = null;
@@ -2149,7 +2151,7 @@ namespace System.Reflection.Emit {
Contract.EndContractBlock();
CheckContext(interfaceType);
-
+
ThrowIfCreated();
TypeToken tkInterface = m_module.GetTypeTokenInternal(interfaceType);
@@ -2158,14 +2160,14 @@ namespace System.Reflection.Emit {
m_typeInterfaces.Add(interfaceType);
}
-public TypeToken TypeToken
+ public TypeToken TypeToken
{
- get
+ get
{
if (IsGenericParameter)
ThrowIfCreated();
- return m_tdType;
+ return m_tdType;
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs b/src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs
index da5a56ba28..6d46362f91 100644
--- a/src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs
@@ -4,18 +4,19 @@
//
+using System;
+using System.Reflection;
+using System.Collections;
+using System.Globalization;
+using System.Diagnostics.Contracts;
+
namespace System.Reflection.Emit
{
- using System;
- using System.Reflection;
- using System.Collections;
- using System.Globalization;
- using System.Diagnostics.Contracts;
-
internal sealed class TypeBuilderInstantiation : TypeInfo
{
- public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){
- if(typeInfo==null) return false;
+ public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo)
+ {
+ if (typeInfo == null) return false;
return IsAssignableFrom(typeInfo.AsType());
}
@@ -34,9 +35,9 @@ namespace System.Reflection.Emit
foreach (Type t in typeArguments)
{
if (t == null)
- throw new ArgumentNullException(nameof(typeArguments));
+ throw new ArgumentNullException(nameof(typeArguments));
}
-
+
return new TypeBuilderInstantiation(type, typeArguments);
}
@@ -77,26 +78,26 @@ namespace System.Reflection.Emit
#endregion
#region Type Overrides
- public override Type MakePointerType()
- {
- return SymbolType.FormCompoundType("*", this, 0);
+ public override Type MakePointerType()
+ {
+ return SymbolType.FormCompoundType("*", this, 0);
}
- public override Type MakeByRefType()
+ public override Type MakeByRefType()
{
return SymbolType.FormCompoundType("&", this, 0);
}
- public override Type MakeArrayType()
+ public override Type MakeArrayType()
{
return SymbolType.FormCompoundType("[]", this, 0);
}
- public override Type MakeArrayType(int rank)
+ public override Type MakeArrayType(int rank)
{
if (rank <= 0)
throw new IndexOutOfRangeException();
Contract.EndContractBlock();
string comma = "";
- for(int i = 1; i < rank; i++)
+ for (int i = 1; i < rank; i++)
comma += ",";
string s = String.Format(CultureInfo.InvariantCulture, "[{0}]", comma);
@@ -106,14 +107,14 @@ namespace System.Reflection.Emit
public override Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters) { throw new NotSupportedException(); }
public override Assembly Assembly { get { return m_type.Assembly; } }
public override RuntimeTypeHandle TypeHandle { get { throw new NotSupportedException(); } }
- public override String FullName
- {
- get
- {
+ public override String FullName
+ {
+ get
+ {
if (m_strFullQualName == null)
- m_strFullQualName = TypeNameBuilder.ToString(this, TypeNameBuilder.Format.FullName);
+ m_strFullQualName = TypeNameBuilder.ToString(this, TypeNameBuilder.Format.FullName);
return m_strFullQualName;
- }
+ }
}
public override String Namespace { get { return m_type.Namespace; } }
public override String AssemblyQualifiedName { get { return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.AssemblyQualifiedName); } }
@@ -125,7 +126,7 @@ namespace System.Reflection.Emit
for (int i = 0; i < instSubstituted.Length; i++)
{
Type t = inst[i];
-
+
if (t is TypeBuilderInstantiation)
{
instSubstituted[i] = (t as TypeBuilderInstantiation).Substitute(substitutes);
@@ -147,7 +148,7 @@ namespace System.Reflection.Emit
{
// B<A,B,C>
// D<T,S> : B<S,List<T>,char>
-
+
// D<string,int> : B<int,List<string>,char>
// D<S,T> : B<T,List<S>,char>
// D<S,string> : B<string,List<S>,char>
@@ -159,7 +160,7 @@ namespace System.Reflection.Emit
return null;
TypeBuilderInstantiation typeBldrBaseAs = typeBldrBase as TypeBuilderInstantiation;
-
+
if (typeBldrBaseAs == null)
return typeBldrBase;
@@ -167,7 +168,7 @@ namespace System.Reflection.Emit
}
}
protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { throw new NotSupportedException(); }
-
+
public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { throw new NotSupportedException(); }
protected override MethodInfo GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { throw new NotSupportedException(); }
public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { throw new NotSupportedException(); }
@@ -187,6 +188,9 @@ namespace System.Reflection.Emit
public override EventInfo[] GetEvents(BindingFlags bindingAttr) { throw new NotSupportedException(); }
public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { throw new NotSupportedException(); }
protected override TypeAttributes GetAttributeFlagsImpl() { return m_type.Attributes; }
+
+ public override bool IsSZArray => false;
+
protected override bool IsArrayImpl() { return false; }
protected override bool IsByRefImpl() { return false; }
protected override bool IsPointerImpl() { return false; }
@@ -217,7 +221,7 @@ namespace System.Reflection.Emit
}
public override MethodBase DeclaringMethod { get { return null; } }
public override Type GetGenericTypeDefinition() { return m_type; }
- public override Type MakeGenericType(params Type[] inst) { throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericTypeDefinition")); }
+ public override Type MakeGenericType(params Type[] inst) { throw new InvalidOperationException(SR.Arg_NotGenericTypeDefinition); }
public override bool IsAssignableFrom(Type c) { throw new NotSupportedException(); }
[Pure]
diff --git a/src/mscorlib/src/System/Reflection/Emit/TypeToken.cs b/src/mscorlib/src/System/Reflection/Emit/TypeToken.cs
index 4fa851c529..4f0c1b3dac 100644
--- a/src/mscorlib/src/System/Reflection/Emit/TypeToken.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/TypeToken.cs
@@ -12,33 +12,36 @@
**
**
===========================================================*/
-namespace System.Reflection.Emit {
-
- using System;
- using System.Reflection;
- using System.Threading;
+using System;
+using System.Reflection;
+using System.Threading;
+
+namespace System.Reflection.Emit
+{
[Serializable]
- public struct TypeToken {
-
+ public struct TypeToken
+ {
public static readonly TypeToken Empty = new TypeToken();
internal int m_class;
-
-
- internal TypeToken(int str) {
- m_class=str;
+
+
+ internal TypeToken(int str)
+ {
+ m_class = str;
}
-
- public int Token {
+
+ public int Token
+ {
get { return m_class; }
}
-
+
public override int GetHashCode()
{
return m_class;
}
-
+
public override bool Equals(Object obj)
{
if (obj is TypeToken)
@@ -46,22 +49,21 @@ namespace System.Reflection.Emit {
else
return false;
}
-
+
public bool Equals(TypeToken obj)
{
return obj.m_class == m_class;
}
-
+
public static bool operator ==(TypeToken a, TypeToken b)
{
return a.Equals(b);
}
-
+
public static bool operator !=(TypeToken a, TypeToken b)
{
return !(a == b);
}
-
}
}
diff --git a/src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs b/src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs
index ca0faf31ca..78238c02b7 100644
--- a/src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs
+++ b/src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs
@@ -4,16 +4,16 @@
//
+using System;
+using System.Reflection;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
namespace System.Reflection.Emit
{
- using System;
- using System.Reflection;
- using System.Collections;
- using System.Collections.Generic;
- using System.Globalization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
internal sealed class MethodOnTypeBuilderInstantiation : MethodInfo
{
#region Private Static Members
@@ -37,21 +37,21 @@ namespace System.Reflection.Emit
m_type = type;
}
#endregion
-
+
internal override Type[] GetParameterTypes()
{
return m_method.GetParameterTypes();
}
#region MemberInfo Overrides
- public override MemberTypes MemberType { get { return m_method.MemberType; } }
+ public override MemberTypes MemberType { get { return m_method.MemberType; } }
public override String Name { get { return m_method.Name; } }
public override Type DeclaringType { get { return m_type; } }
public override Type ReflectedType { get { return m_type; } }
- public override Object[] GetCustomAttributes(bool inherit) { return m_method.GetCustomAttributes(inherit); }
+ public override Object[] GetCustomAttributes(bool inherit) { return m_method.GetCustomAttributes(inherit); }
public override Object[] GetCustomAttributes(Type attributeType, bool inherit) { return m_method.GetCustomAttributes(attributeType, inherit); }
public override bool IsDefined(Type attributeType, bool inherit) { return m_method.IsDefined(attributeType, inherit); }
- public override Module Module { get { return m_method.Module; } }
+ public override Module Module { get { return m_method.Module; } }
#endregion
#region MethodBase Members
@@ -65,21 +65,21 @@ namespace System.Reflection.Emit
throw new NotSupportedException();
}
public override CallingConventions CallingConvention { get { return m_method.CallingConvention; } }
- public override Type [] GetGenericArguments() { return m_method.GetGenericArguments(); }
+ public override Type[] GetGenericArguments() { return m_method.GetGenericArguments(); }
public override MethodInfo GetGenericMethodDefinition() { return m_method; }
public override bool IsGenericMethodDefinition { get { return m_method.IsGenericMethodDefinition; } }
public override bool ContainsGenericParameters { get { return m_method.ContainsGenericParameters; } }
public override MethodInfo MakeGenericMethod(params Type[] typeArgs)
{
if (!IsGenericMethodDefinition)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericMethodDefinition"));
+ throw new InvalidOperationException(SR.Arg_NotGenericMethodDefinition);
Contract.EndContractBlock();
return MethodBuilderInstantiation.MakeGenericMethod(this, typeArgs);
}
public override bool IsGenericMethod { get { return m_method.IsGenericMethod; } }
-
+
#endregion
#region Public Abstract\Virtual Members
@@ -113,7 +113,7 @@ namespace System.Reflection.Emit
m_type = type;
}
#endregion
-
+
internal override Type[] GetParameterTypes()
{
return m_ctor.GetParameterTypes();
@@ -129,7 +129,7 @@ namespace System.Reflection.Emit
public override String Name { get { return m_ctor.Name; } }
public override Type DeclaringType { get { return m_type; } }
public override Type ReflectedType { get { return m_type; } }
- public override Object[] GetCustomAttributes(bool inherit) { return m_ctor.GetCustomAttributes(inherit); }
+ public override Object[] GetCustomAttributes(bool inherit) { return m_ctor.GetCustomAttributes(inherit); }
public override Object[] GetCustomAttributes(Type attributeType, bool inherit) { return m_ctor.GetCustomAttributes(attributeType, inherit); }
public override bool IsDefined(Type attributeType, bool inherit) { return m_ctor.IsDefined(attributeType, inherit); }
internal int MetadataTokenInternal
@@ -147,7 +147,7 @@ namespace System.Reflection.Emit
}
}
}
- public override Module Module { get { return m_ctor.Module; } }
+ public override Module Module { get { return m_ctor.Module; } }
#endregion
#region MethodBase Members
@@ -195,10 +195,12 @@ namespace System.Reflection.Emit
// We're not entirely sure if this cache helps any specific scenarios, so
// long-term, one could investigate whether it's needed. In any case, this
// method isn't expected to be on any critical paths for performance.
- if (type.m_hashtable.Contains(Field)) {
+ if (type.m_hashtable.Contains(Field))
+ {
m = type.m_hashtable[Field] as FieldInfo;
}
- else {
+ else
+ {
m = new FieldOnTypeBuilderInstantiation(Field, type);
type.m_hashtable[Field] = m;
}
@@ -225,11 +227,11 @@ namespace System.Reflection.Emit
internal FieldInfo FieldInfo { get { return m_field; } }
#region MemberInfo Overrides
- public override MemberTypes MemberType { get { return System.Reflection.MemberTypes.Field; } }
+ public override MemberTypes MemberType { get { return System.Reflection.MemberTypes.Field; } }
public override String Name { get { return m_field.Name; } }
public override Type DeclaringType { get { return m_type; } }
public override Type ReflectedType { get { return m_type; } }
- public override Object[] GetCustomAttributes(bool inherit) { return m_field.GetCustomAttributes(inherit); }
+ public override Object[] GetCustomAttributes(bool inherit) { return m_field.GetCustomAttributes(inherit); }
public override Object[] GetCustomAttributes(Type attributeType, bool inherit) { return m_field.GetCustomAttributes(attributeType, inherit); }
public override bool IsDefined(Type attributeType, bool inherit) { return m_field.IsDefined(attributeType, inherit); }
internal int MetadataTokenInternal
@@ -247,7 +249,7 @@ namespace System.Reflection.Emit
}
}
}
- public override Module Module { get { return m_field.Module; } }
+ public override Module Module { get { return m_field.Module; } }
#endregion
#region Public Abstract\Virtual Members
@@ -260,15 +262,15 @@ namespace System.Reflection.Emit
public override Object GetValueDirect(TypedReference obj)
{
throw new NotImplementedException();
- }
- public override RuntimeFieldHandle FieldHandle
+ }
+ public override RuntimeFieldHandle FieldHandle
{
get { throw new NotImplementedException(); }
- }
+ }
public override Type FieldType { get { throw new NotImplementedException(); } }
public override Object GetValue(Object obj) { throw new InvalidOperationException(); }
public override void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture) { throw new InvalidOperationException(); }
- public override FieldAttributes Attributes { get { return m_field.Attributes; } }
+ public override FieldAttributes Attributes { get { return m_field.Attributes; } }
#endregion
}
}
diff --git a/src/mscorlib/src/System/Reflection/EventAttributes.cs b/src/mscorlib/src/System/Reflection/EventAttributes.cs
deleted file mode 100644
index 4cc08f62d3..0000000000
--- a/src/mscorlib/src/System/Reflection/EventAttributes.cs
+++ /dev/null
@@ -1,29 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// EventAttributes are an enum defining the attributes associated with
-//
-// and Event. These are defined in CorHdr.h and are a combination of
-// bits and enums.
-//
-//
-namespace System.Reflection {
-
- using System;
- [Serializable]
- [Flags]
- public enum EventAttributes {
- None = 0x0000,
-
- // This Enum matchs the CorEventAttr defined in CorHdr.h
- SpecialName = 0x0200, // event is special. Name describes how.
-
- // Reserved flags for Runtime use only.
- ReservedMask = 0x0400,
- RTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding.
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/EventInfo.cs b/src/mscorlib/src/System/Reflection/EventInfo.cs
deleted file mode 100644
index 9b529c2960..0000000000
--- a/src/mscorlib/src/System/Reflection/EventInfo.cs
+++ /dev/null
@@ -1,401 +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.
-
-//
-
-namespace System.Reflection
-{
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Runtime.InteropServices;
- using System.Runtime.Serialization;
- using System.Runtime.ConstrainedExecution;
- using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
-
- [Serializable]
- public abstract class EventInfo : MemberInfo
- {
- #region Constructor
- protected EventInfo() { }
- #endregion
-
- public static bool operator ==(EventInfo left, EventInfo right)
- {
- if (ReferenceEquals(left, right))
- return true;
-
- if ((object)left == null || (object)right == null ||
- left is RuntimeEventInfo || right is RuntimeEventInfo)
- {
- return false;
- }
- return left.Equals(right);
- }
-
- public static bool operator !=(EventInfo left, EventInfo right)
- {
- return !(left == right);
- }
-
- public override bool Equals(object obj)
- {
- return base.Equals(obj);
- }
-
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
-
- #region MemberInfo Overrides
- public override MemberTypes MemberType { get { return MemberTypes.Event; } }
- #endregion
-
- #region Public Abstract\Virtual Members
- public virtual MethodInfo[] GetOtherMethods(bool nonPublic)
- {
- throw new NotImplementedException();
- }
-
- public abstract MethodInfo GetAddMethod(bool nonPublic);
-
- public abstract MethodInfo GetRemoveMethod(bool nonPublic);
-
- public abstract MethodInfo GetRaiseMethod(bool nonPublic);
-
- public abstract EventAttributes Attributes { get; }
- #endregion
-
- #region Public Members
- public virtual MethodInfo AddMethod
- {
- get
- {
- return GetAddMethod(true);
- }
- }
-
- public virtual MethodInfo RemoveMethod
- {
- get
- {
- return GetRemoveMethod(true);
- }
- }
-
- public virtual MethodInfo RaiseMethod
- {
- get
- {
- return GetRaiseMethod(true);
- }
- }
-
- public MethodInfo[] GetOtherMethods() { return GetOtherMethods(false); }
-
- public MethodInfo GetAddMethod() { return GetAddMethod(false); }
-
- public MethodInfo GetRemoveMethod() { return GetRemoveMethod(false); }
-
- public MethodInfo GetRaiseMethod() { return GetRaiseMethod(false); }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public virtual void AddEventHandler(Object target, Delegate handler)
- {
- MethodInfo addMethod = GetAddMethod();
-
- if (addMethod == null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoPublicAddMethod"));
-
-#if FEATURE_COMINTEROP
- if (addMethod.ReturnType == typeof(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken))
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotSupportedOnWinRTEvent"));
-
- // Must be a normal non-WinRT event
- Debug.Assert(addMethod.ReturnType == typeof(void));
-#endif // FEATURE_COMINTEROP
-
- addMethod.Invoke(target, new object[] { handler });
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public virtual void RemoveEventHandler(Object target, Delegate handler)
- {
- MethodInfo removeMethod = GetRemoveMethod();
-
- if (removeMethod == null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoPublicRemoveMethod"));
-
-#if FEATURE_COMINTEROP
- ParameterInfo[] parameters = removeMethod.GetParametersNoCopy();
- Debug.Assert(parameters != null && parameters.Length == 1);
-
- if (parameters[0].ParameterType == typeof(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken))
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotSupportedOnWinRTEvent"));
-
- // Must be a normal non-WinRT event
- Debug.Assert(parameters[0].ParameterType.BaseType == typeof(MulticastDelegate));
-#endif // FEATURE_COMINTEROP
-
- removeMethod.Invoke(target, new object[] { handler });
- }
-
- public virtual Type EventHandlerType
- {
- get
- {
- MethodInfo m = GetAddMethod(true);
-
- ParameterInfo[] p = m.GetParametersNoCopy();
-
- Type del = typeof(Delegate);
-
- for (int i = 0; i < p.Length; i++)
- {
- Type c = p[i].ParameterType;
-
- if (c.IsSubclassOf(del))
- return c;
- }
- return null;
- }
- }
- public bool IsSpecialName
- {
- get
- {
- return(Attributes & EventAttributes.SpecialName) != 0;
- }
- }
-
- public virtual bool IsMulticast
- {
- get
- {
- Type cl = EventHandlerType;
- Type mc = typeof(MulticastDelegate);
- return mc.IsAssignableFrom(cl);
- }
- }
- #endregion
- }
-
- [Serializable]
- internal unsafe sealed class RuntimeEventInfo : EventInfo, ISerializable
- {
- #region Private Data Members
- private int m_token;
- private EventAttributes m_flags;
- private string m_name;
- private void* m_utf8name;
- private RuntimeTypeCache m_reflectedTypeCache;
- private RuntimeMethodInfo m_addMethod;
- private RuntimeMethodInfo m_removeMethod;
- private RuntimeMethodInfo m_raiseMethod;
- private MethodInfo[] m_otherMethod;
- private RuntimeType m_declaringType;
- private BindingFlags m_bindingFlags;
- #endregion
-
- #region Constructor
- internal RuntimeEventInfo()
- {
- // Used for dummy head node during population
- }
- internal RuntimeEventInfo(int tkEvent, RuntimeType declaredType, RuntimeTypeCache reflectedTypeCache, out bool isPrivate)
- {
- Contract.Requires(declaredType != null);
- Contract.Requires(reflectedTypeCache != null);
- Debug.Assert(!reflectedTypeCache.IsGlobal);
-
- MetadataImport scope = declaredType.GetRuntimeModule().MetadataImport;
-
- m_token = tkEvent;
- m_reflectedTypeCache = reflectedTypeCache;
- m_declaringType = declaredType;
-
-
- RuntimeType reflectedType = reflectedTypeCache.GetRuntimeType();
-
- scope.GetEventProps(tkEvent, out m_utf8name, out m_flags);
-
- RuntimeMethodInfo dummy;
- Associates.AssignAssociates(scope, tkEvent, declaredType, reflectedType,
- out m_addMethod, out m_removeMethod, out m_raiseMethod,
- out dummy, out dummy, out m_otherMethod, out isPrivate, out m_bindingFlags);
- }
- #endregion
-
- #region Internal Members
- internal override bool CacheEquals(object o)
- {
- RuntimeEventInfo m = o as RuntimeEventInfo;
-
- if ((object)m == null)
- return false;
-
- return m.m_token == m_token &&
- RuntimeTypeHandle.GetModule(m_declaringType).Equals(
- RuntimeTypeHandle.GetModule(m.m_declaringType));
- }
-
- internal BindingFlags BindingFlags { get { return m_bindingFlags; } }
- #endregion
-
- #region Object Overrides
- public override String ToString()
- {
- if (m_addMethod == null || m_addMethod.GetParametersNoCopy().Length == 0)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoPublicAddMethod"));
-
- return m_addMethod.GetParametersNoCopy()[0].ParameterType.FormatTypeName() + " " + Name;
- }
- #endregion
-
- #region ICustomAttributeProvider
- public override Object[] GetCustomAttributes(bool inherit)
- {
- return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
- }
-
- public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
-
- return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
- }
-
- public override bool IsDefined(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
-
- return CustomAttribute.IsDefined(this, attributeRuntimeType);
- }
-
- public override IList<CustomAttributeData> GetCustomAttributesData()
- {
- return CustomAttributeData.GetCustomAttributesInternal(this);
- }
- #endregion
-
- #region MemberInfo Overrides
- public override MemberTypes MemberType { get { return MemberTypes.Event; } }
- public override String Name
- {
- get
- {
- if (m_name == null)
- m_name = new Utf8String(m_utf8name).ToString();
-
- return m_name;
- }
- }
- public override Type DeclaringType { get { return m_declaringType; } }
- public override Type ReflectedType
- {
- get
- {
- return ReflectedTypeInternal;
- }
- }
-
- private RuntimeType ReflectedTypeInternal
- {
- get
- {
- return m_reflectedTypeCache.GetRuntimeType();
- }
- }
-
- public override int MetadataToken { get { return m_token; } }
- public override Module Module { get { return GetRuntimeModule(); } }
- internal RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); }
- #endregion
-
- #region ISerializable
- public void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- MemberInfoSerializationHolder.GetSerializationInfo(
- info,
- Name,
- ReflectedTypeInternal,
- null,
- MemberTypes.Event);
- }
- #endregion
-
- #region EventInfo Overrides
- public override MethodInfo[] GetOtherMethods(bool nonPublic)
- {
- List<MethodInfo> ret = new List<MethodInfo>();
-
- if ((object)m_otherMethod == null)
- return new MethodInfo[0];
-
- for(int i = 0; i < m_otherMethod.Length; i ++)
- {
- if (Associates.IncludeAccessor((MethodInfo)m_otherMethod[i], nonPublic))
- ret.Add(m_otherMethod[i]);
- }
-
- return ret.ToArray();
- }
-
- public override MethodInfo GetAddMethod(bool nonPublic)
- {
- if (!Associates.IncludeAccessor(m_addMethod, nonPublic))
- return null;
-
- return m_addMethod;
- }
-
- public override MethodInfo GetRemoveMethod(bool nonPublic)
- {
- if (!Associates.IncludeAccessor(m_removeMethod, nonPublic))
- return null;
-
- return m_removeMethod;
- }
-
- public override MethodInfo GetRaiseMethod(bool nonPublic)
- {
- if (!Associates.IncludeAccessor(m_raiseMethod, nonPublic))
- return null;
-
- return m_raiseMethod;
- }
-
- public override EventAttributes Attributes
- {
- get
- {
- return m_flags;
- }
- }
- #endregion
- }
-
-}
diff --git a/src/mscorlib/src/System/Reflection/ExceptionHandlingClause.cs b/src/mscorlib/src/System/Reflection/ExceptionHandlingClause.cs
new file mode 100644
index 0000000000..9bb45aebb2
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/ExceptionHandlingClause.cs
@@ -0,0 +1,93 @@
+// 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.Globalization;
+using System.Diagnostics.Contracts;
+
+namespace System.Reflection
+{
+ public class ExceptionHandlingClause
+ {
+ #region costructor
+ // This class can only be created from inside the EE.
+ protected ExceptionHandlingClause() { }
+ #endregion
+
+ #region Private Data Members
+ private MethodBody m_methodBody;
+ [ContractPublicPropertyName("Flags")]
+ private ExceptionHandlingClauseOptions m_flags;
+ private int m_tryOffset;
+ private int m_tryLength;
+ private int m_handlerOffset;
+ private int m_handlerLength;
+ private int m_catchMetadataToken;
+ private int m_filterOffset;
+ #endregion
+
+ #region Public Members
+ public virtual ExceptionHandlingClauseOptions Flags { get { return m_flags; } }
+ public virtual int TryOffset { get { return m_tryOffset; } }
+ public virtual int TryLength { get { return m_tryLength; } }
+ public virtual int HandlerOffset { get { return m_handlerOffset; } }
+ public virtual int HandlerLength { get { return m_handlerLength; } }
+
+ public virtual int FilterOffset
+ {
+ get
+ {
+ if (m_flags != ExceptionHandlingClauseOptions.Filter)
+ throw new InvalidOperationException(SR.Arg_EHClauseNotFilter);
+
+ return m_filterOffset;
+ }
+ }
+
+ public virtual Type CatchType
+ {
+ get
+ {
+ if (m_flags != ExceptionHandlingClauseOptions.Clause)
+ throw new InvalidOperationException(SR.Arg_EHClauseNotClause);
+
+ Type type = null;
+
+ if (!MetadataToken.IsNullToken(m_catchMetadataToken))
+ {
+ Type declaringType = m_methodBody.m_methodBase.DeclaringType;
+ Module module = (declaringType == null) ? m_methodBody.m_methodBase.Module : declaringType.Module;
+ type = module.ResolveType(m_catchMetadataToken, (declaringType == null) ? null : declaringType.GetGenericArguments(),
+ m_methodBody.m_methodBase is MethodInfo ? m_methodBody.m_methodBase.GetGenericArguments() : null);
+ }
+
+ return type;
+ }
+ }
+ #endregion
+
+ #region Object Overrides
+ public override string ToString()
+ {
+ if (Flags == ExceptionHandlingClauseOptions.Clause)
+ {
+ return String.Format(CultureInfo.CurrentUICulture,
+ "Flags={0}, TryOffset={1}, TryLength={2}, HandlerOffset={3}, HandlerLength={4}, CatchType={5}",
+ Flags, TryOffset, TryLength, HandlerOffset, HandlerLength, CatchType);
+ }
+
+ if (Flags == ExceptionHandlingClauseOptions.Filter)
+ {
+ return String.Format(CultureInfo.CurrentUICulture,
+ "Flags={0}, TryOffset={1}, TryLength={2}, HandlerOffset={3}, HandlerLength={4}, FilterOffset={5}",
+ Flags, TryOffset, TryLength, HandlerOffset, HandlerLength, FilterOffset);
+ }
+
+ return String.Format(CultureInfo.CurrentUICulture,
+ "Flags={0}, TryOffset={1}, TryLength={2}, HandlerOffset={3}, HandlerLength={4}",
+ Flags, TryOffset, TryLength, HandlerOffset, HandlerLength);
+ }
+ #endregion
+ }
+}
+
diff --git a/src/mscorlib/src/System/Reflection/FieldAttributes.cs b/src/mscorlib/src/System/Reflection/FieldAttributes.cs
deleted file mode 100644
index e49a0a45b1..0000000000
--- a/src/mscorlib/src/System/Reflection/FieldAttributes.cs
+++ /dev/null
@@ -1,42 +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.
-
-namespace System.Reflection
-{
- using System;
- // This Enum matchs the CorFieldAttr defined in CorHdr.h
- [Serializable]
- [Flags()]
- public enum FieldAttributes
- {
- // member access mask - Use this mask to retrieve accessibility information.
- FieldAccessMask = 0x0007,
- PrivateScope = 0x0000, // Member not referenceable.
- Private = 0x0001, // Accessible only by the parent type.
- FamANDAssem = 0x0002, // Accessible by sub-types only in this Assembly.
- Assembly = 0x0003, // Accessibly by anyone in the Assembly.
- Family = 0x0004, // Accessible only by type and sub-types.
- FamORAssem = 0x0005, // Accessibly by sub-types anywhere, plus anyone in assembly.
- Public = 0x0006, // Accessibly by anyone who has visibility to this scope.
- // end member access mask
-
- // field contract attributes.
- Static = 0x0010, // Defined on type, else per instance.
- InitOnly = 0x0020, // Field may only be initialized, not written to after init.
- Literal = 0x0040, // Value is compile time constant.
- NotSerialized = 0x0080, // Field does not have to be serialized when type is remoted.
-
- SpecialName = 0x0200, // field is special. Name describes how.
-
- // interop attributes
- PinvokeImpl = 0x2000, // Implementation is forwarded through pinvoke.
-
- // Reserved flags for runtime use only.
- ReservedMask = 0x9500,
- RTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding.
- HasFieldMarshal = 0x1000, // Field has marshalling information.
- HasDefault = 0x8000, // Field has default.
- HasFieldRVA = 0x0100, // Field has RVA.
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/FieldInfo.CoreCLR.cs b/src/mscorlib/src/System/Reflection/FieldInfo.CoreCLR.cs
new file mode 100644
index 0000000000..bcda3418fa
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/FieldInfo.CoreCLR.cs
@@ -0,0 +1,35 @@
+// 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.Globalization;
+
+namespace System.Reflection
+{
+ public abstract partial class FieldInfo : MemberInfo
+ {
+ public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle handle)
+ {
+ if (handle.IsNullHandle())
+ throw new ArgumentException(SR.Argument_InvalidHandle, nameof(handle));
+
+ FieldInfo f = RuntimeType.GetFieldInfo(handle.GetRuntimeFieldInfo());
+
+ Type declaringType = f.DeclaringType;
+ if (declaringType != null && declaringType.IsGenericType)
+ throw new ArgumentException(String.Format(
+ CultureInfo.CurrentCulture, SR.Argument_FieldDeclaringTypeGeneric,
+ f.Name, declaringType.GetGenericTypeDefinition()));
+
+ return f;
+ }
+
+ public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle handle, RuntimeTypeHandle declaringType)
+ {
+ if (handle.IsNullHandle())
+ throw new ArgumentException(SR.Argument_InvalidHandle);
+
+ return RuntimeType.GetFieldInfo(declaringType.GetRuntimeType(), handle.GetRuntimeFieldInfo());
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/FieldInfo.cs b/src/mscorlib/src/System/Reflection/FieldInfo.cs
deleted file mode 100644
index 7b6517c2bb..0000000000
--- a/src/mscorlib/src/System/Reflection/FieldInfo.cs
+++ /dev/null
@@ -1,862 +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.
-
-//
-
-namespace System.Reflection
-{
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.InteropServices;
- using System.Runtime.Serialization;
- using System.Threading;
- using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
-
- [Serializable]
- public abstract class FieldInfo : MemberInfo
- {
- #region Static Members
- public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle handle)
- {
- if (handle.IsNullHandle())
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHandle"), nameof(handle));
-
- FieldInfo f = RuntimeType.GetFieldInfo(handle.GetRuntimeFieldInfo());
-
- Type declaringType = f.DeclaringType;
- if (declaringType != null && declaringType.IsGenericType)
- throw new ArgumentException(String.Format(
- CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_FieldDeclaringTypeGeneric"),
- f.Name, declaringType.GetGenericTypeDefinition()));
-
- return f;
- }
-
- public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle handle, RuntimeTypeHandle declaringType)
- {
- if (handle.IsNullHandle())
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHandle"));
-
- return RuntimeType.GetFieldInfo(declaringType.GetRuntimeType(), handle.GetRuntimeFieldInfo());
- }
- #endregion
-
- #region Constructor
- protected FieldInfo() { }
- #endregion
-
- public static bool operator ==(FieldInfo left, FieldInfo right)
- {
- if (ReferenceEquals(left, right))
- return true;
-
- if ((object)left == null || (object)right == null ||
- left is RuntimeFieldInfo || right is RuntimeFieldInfo)
- {
- return false;
- }
- return left.Equals(right);
- }
-
- public static bool operator !=(FieldInfo left, FieldInfo right)
- {
- return !(left == right);
- }
-
- public override bool Equals(object obj)
- {
- return base.Equals(obj);
- }
-
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
-
- #region MemberInfo Overrides
- public override MemberTypes MemberType { get { return System.Reflection.MemberTypes.Field; } }
- #endregion
-
- #region Public Abstract\Virtual Members
-
- public virtual Type[] GetRequiredCustomModifiers()
- {
- throw new NotImplementedException();
- }
-
- public virtual Type[] GetOptionalCustomModifiers()
- {
- throw new NotImplementedException();
- }
-
- [CLSCompliant(false)]
- public virtual void SetValueDirect(TypedReference obj, Object value)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_AbstractNonCLS"));
- }
-
- [CLSCompliant(false)]
- public virtual Object GetValueDirect(TypedReference obj)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_AbstractNonCLS"));
- }
-
- public abstract RuntimeFieldHandle FieldHandle { get; }
-
- public abstract Type FieldType { get; }
-
- public abstract Object GetValue(Object obj);
-
- public virtual Object GetRawConstantValue() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_AbstractNonCLS")); }
-
- public abstract void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture);
-
- public abstract FieldAttributes Attributes { get; }
- #endregion
-
- #region Public Members
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public void SetValue(Object obj, Object value)
- {
- // Theoretically we should set up a LookForMyCaller stack mark here and pass that along.
- // But to maintain backward compatibility we can't switch to calling an
- // internal overload that takes a stack mark.
- // Fortunately the stack walker skips all the reflection invocation frames including this one.
- // So this method will never be returned by the stack walker as the caller.
- // See SystemDomain::CallersMethodCallbackWithStackMark in AppDomain.cpp.
- SetValue(obj, value, BindingFlags.Default, Type.DefaultBinder, null);
- }
-
- public bool IsPublic { get { return(Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public; } }
-
- public bool IsPrivate { get { return(Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Private; } }
-
- public bool IsFamily { get { return(Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Family; } }
-
- public bool IsAssembly { get { return(Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Assembly; } }
-
- public bool IsFamilyAndAssembly { get { return(Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamANDAssem; } }
-
- public bool IsFamilyOrAssembly { get { return(Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamORAssem; } }
-
- public bool IsStatic { get { return(Attributes & FieldAttributes.Static) != 0; } }
-
- public bool IsInitOnly { get { return(Attributes & FieldAttributes.InitOnly) != 0; } }
-
- public bool IsLiteral { get { return(Attributes & FieldAttributes.Literal) != 0; } }
-
- public bool IsNotSerialized { get { return(Attributes & FieldAttributes.NotSerialized) != 0; } }
-
- public bool IsSpecialName { get { return(Attributes & FieldAttributes.SpecialName) != 0; } }
-
- public bool IsPinvokeImpl { get { return(Attributes & FieldAttributes.PinvokeImpl) != 0; } }
-
- public virtual bool IsSecurityCritical
- {
- get { return FieldHandle.IsSecurityCritical(); }
- }
-
- public virtual bool IsSecuritySafeCritical
- {
- get { return FieldHandle.IsSecuritySafeCritical(); }
- }
-
- public virtual bool IsSecurityTransparent
- {
- get { return FieldHandle.IsSecurityTransparent(); }
- }
-
- #endregion
- }
-
- [Serializable]
- internal abstract class RuntimeFieldInfo : FieldInfo, ISerializable
- {
- #region Private Data Members
- private BindingFlags m_bindingFlags;
- protected RuntimeTypeCache m_reflectedTypeCache;
- protected RuntimeType m_declaringType;
- #endregion
-
- #region Constructor
- protected RuntimeFieldInfo()
- {
- // Used for dummy head node during population
- }
- protected RuntimeFieldInfo(RuntimeTypeCache reflectedTypeCache, RuntimeType declaringType, BindingFlags bindingFlags)
- {
- m_bindingFlags = bindingFlags;
- m_declaringType = declaringType;
- m_reflectedTypeCache = reflectedTypeCache;
- }
- #endregion
-
- #region NonPublic Members
- internal BindingFlags BindingFlags { get { return m_bindingFlags; } }
- private RuntimeType ReflectedTypeInternal
- {
- get
- {
- return m_reflectedTypeCache.GetRuntimeType();
- }
- }
-
- internal RuntimeType GetDeclaringTypeInternal()
- {
- return m_declaringType;
- }
-
- internal RuntimeType GetRuntimeType() { return m_declaringType; }
- internal abstract RuntimeModule GetRuntimeModule();
- #endregion
-
- #region MemberInfo Overrides
- public override MemberTypes MemberType { get { return MemberTypes.Field; } }
- public override Type ReflectedType
- {
- get
- {
- return m_reflectedTypeCache.IsGlobal ? null : ReflectedTypeInternal;
- }
- }
-
- public override Type DeclaringType
- {
- get
- {
- return m_reflectedTypeCache.IsGlobal ? null : m_declaringType;
- }
- }
-
- public override Module Module { get { return GetRuntimeModule(); } }
- #endregion
-
- #region Object Overrides
- public unsafe override String ToString()
- {
- return FieldType.FormatTypeName() + " " + Name;
- }
- #endregion
-
- #region ICustomAttributeProvider
- public override Object[] GetCustomAttributes(bool inherit)
- {
- return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
- }
-
- public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
-
- return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
- }
-
- public override bool IsDefined(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
-
- return CustomAttribute.IsDefined(this, attributeRuntimeType);
- }
-
- public override IList<CustomAttributeData> GetCustomAttributesData()
- {
- return CustomAttributeData.GetCustomAttributesInternal(this);
- }
- #endregion
-
- #region FieldInfo Overrides
- // All implemented on derived classes
- #endregion
-
- #region ISerializable Implementation
- public void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
- MemberInfoSerializationHolder.GetSerializationInfo(
- info,
- Name,
- ReflectedTypeInternal,
- ToString(),
- MemberTypes.Field);
- }
- #endregion
- }
-
- [Serializable]
- internal unsafe sealed class RtFieldInfo : RuntimeFieldInfo, IRuntimeFieldInfo
- {
- #region FCalls
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static private extern void PerformVisibilityCheckOnField(IntPtr field, Object target, RuntimeType declaringType, FieldAttributes attr, uint invocationFlags);
- #endregion
-
- #region Private Data Members
- // agressive caching
- private IntPtr m_fieldHandle;
- private FieldAttributes m_fieldAttributes;
- // lazy caching
- private string m_name;
- private RuntimeType m_fieldType;
- private INVOCATION_FLAGS m_invocationFlags;
-
-#if FEATURE_APPX
- private bool IsNonW8PFrameworkAPI()
- {
- if (GetRuntimeType().IsNonW8PFrameworkAPI())
- return true;
-
- // Allow "value__"
- if (m_declaringType.IsEnum)
- return false;
-
- RuntimeAssembly rtAssembly = GetRuntimeAssembly();
- if (rtAssembly.IsFrameworkAssembly())
- {
- int ctorToken = rtAssembly.InvocableAttributeCtorToken;
- if (System.Reflection.MetadataToken.IsNullToken(ctorToken) ||
- !CustomAttribute.IsAttributeDefined(GetRuntimeModule(), MetadataToken, ctorToken))
- return true;
- }
-
- return false;
- }
-#endif
-
- internal INVOCATION_FLAGS InvocationFlags
- {
- get
- {
- if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0)
- {
- Type declaringType = DeclaringType;
- bool fIsReflectionOnlyType = (declaringType is ReflectionOnlyType);
-
- INVOCATION_FLAGS invocationFlags = 0;
-
- // first take care of all the NO_INVOKE cases
- if (
- (declaringType != null && declaringType.ContainsGenericParameters) ||
- (declaringType == null && Module.Assembly.ReflectionOnly) ||
- (fIsReflectionOnlyType)
- )
- {
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE;
- }
-
- // If the invocationFlags are still 0, then
- // this should be an usable field, determine the other flags
- if (invocationFlags == 0)
- {
- if ((m_fieldAttributes & FieldAttributes.InitOnly) != (FieldAttributes)0)
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_SPECIAL_FIELD;
-
- if ((m_fieldAttributes & FieldAttributes.HasFieldRVA) != (FieldAttributes)0)
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_SPECIAL_FIELD;
-
- // A public field is inaccesible to Transparent code if the field is Critical.
- bool needsTransparencySecurityCheck = IsSecurityCritical && !IsSecuritySafeCritical;
- bool needsVisibilitySecurityCheck = ((m_fieldAttributes & FieldAttributes.FieldAccessMask) != FieldAttributes.Public) ||
- (declaringType != null && declaringType.NeedsReflectionSecurityCheck);
- if (needsTransparencySecurityCheck || needsVisibilitySecurityCheck)
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
-
- // find out if the field type is one of the following: Primitive, Enum or Pointer
- Type fieldType = FieldType;
- if (fieldType.IsPointer || fieldType.IsEnum || fieldType.IsPrimitive)
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_FIELD_SPECIAL_CAST;
- }
-
-#if FEATURE_APPX
- if (AppDomain.ProfileAPICheck && IsNonW8PFrameworkAPI())
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API;
-#endif // FEATURE_APPX
-
- // must be last to avoid threading problems
- m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED;
- }
-
- return m_invocationFlags;
- }
- }
- #endregion
-
- private RuntimeAssembly GetRuntimeAssembly() { return m_declaringType.GetRuntimeAssembly(); }
-
- #region Constructor
- internal RtFieldInfo(
- RuntimeFieldHandleInternal handle, RuntimeType declaringType, RuntimeTypeCache reflectedTypeCache, BindingFlags bindingFlags)
- : base(reflectedTypeCache, declaringType, bindingFlags)
- {
- m_fieldHandle = handle.Value;
- m_fieldAttributes = RuntimeFieldHandle.GetAttributes(handle);
- }
- #endregion
-
- #region Private Members
- RuntimeFieldHandleInternal IRuntimeFieldInfo.Value
- {
- get
- {
- return new RuntimeFieldHandleInternal(m_fieldHandle);
- }
- }
-
- #endregion
-
- #region Internal Members
- internal void CheckConsistency(Object target)
- {
- // only test instance fields
- if ((m_fieldAttributes & FieldAttributes.Static) != FieldAttributes.Static)
- {
- if (!m_declaringType.IsInstanceOfType(target))
- {
- if (target == null)
- {
- throw new TargetException(Environment.GetResourceString("RFLCT.Targ_StatFldReqTarg"));
- }
- else
- {
- throw new ArgumentException(
- String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_FieldDeclTarget"),
- Name, m_declaringType, target.GetType()));
- }
- }
- }
- }
-
- internal override bool CacheEquals(object o)
- {
- RtFieldInfo m = o as RtFieldInfo;
-
- if ((object)m == null)
- return false;
-
- return m.m_fieldHandle == m_fieldHandle;
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- internal void InternalSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture, ref StackCrawlMark stackMark)
- {
- INVOCATION_FLAGS invocationFlags = InvocationFlags;
- RuntimeType declaringType = DeclaringType as RuntimeType;
-
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE) != 0)
- {
- if (declaringType != null && declaringType.ContainsGenericParameters)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_UnboundGenField"));
-
- if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyField"));
-
- throw new FieldAccessException();
- }
-
- CheckConsistency(obj);
-
- RuntimeType fieldType = (RuntimeType)FieldType;
- value = fieldType.CheckValue(value, binder, culture, invokeAttr);
-
- #region Security Check
-#if FEATURE_APPX
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- {
- RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
- if (caller != null && !caller.IsSafeForReflection())
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", FullName));
- }
-#endif
-
- if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_SPECIAL_FIELD | INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY)) != 0)
- PerformVisibilityCheckOnField(m_fieldHandle, obj, m_declaringType, m_fieldAttributes, (uint)m_invocationFlags);
- #endregion
-
- bool domainInitialized = false;
- if (declaringType == null)
- {
- RuntimeFieldHandle.SetValue(this, obj, value, fieldType, m_fieldAttributes, null, ref domainInitialized);
- }
- else
- {
- domainInitialized = declaringType.DomainInitialized;
- RuntimeFieldHandle.SetValue(this, obj, value, fieldType, m_fieldAttributes, declaringType, ref domainInitialized);
- declaringType.DomainInitialized = domainInitialized;
- }
- }
-
- // UnsafeSetValue doesn't perform any consistency or visibility check.
- // It is the caller's responsibility to ensure the operation is safe.
- // When the caller needs to perform visibility checks they should call
- // InternalSetValue() instead. When the caller needs to perform
- // consistency checks they should call CheckConsistency() before
- // calling this method.
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- internal void UnsafeSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
- {
- RuntimeType declaringType = DeclaringType as RuntimeType;
- RuntimeType fieldType = (RuntimeType)FieldType;
- value = fieldType.CheckValue(value, binder, culture, invokeAttr);
-
- bool domainInitialized = false;
- if (declaringType == null)
- {
- RuntimeFieldHandle.SetValue(this, obj, value, fieldType, m_fieldAttributes, null, ref domainInitialized);
- }
- else
- {
- domainInitialized = declaringType.DomainInitialized;
- RuntimeFieldHandle.SetValue(this, obj, value, fieldType, m_fieldAttributes, declaringType, ref domainInitialized);
- declaringType.DomainInitialized = domainInitialized;
- }
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- internal Object InternalGetValue(Object obj, ref StackCrawlMark stackMark)
- {
- INVOCATION_FLAGS invocationFlags = InvocationFlags;
- RuntimeType declaringType = DeclaringType as RuntimeType;
-
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE) != 0)
- {
- if (declaringType != null && DeclaringType.ContainsGenericParameters)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_UnboundGenField"));
-
- if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyField"));
-
- throw new FieldAccessException();
- }
-
- CheckConsistency(obj);
-
-#if FEATURE_APPX
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- {
- RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
- if (caller != null && !caller.IsSafeForReflection())
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", FullName));
- }
-#endif
-
- RuntimeType fieldType = (RuntimeType)FieldType;
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) != 0)
- PerformVisibilityCheckOnField(m_fieldHandle, obj, m_declaringType, m_fieldAttributes, (uint)(m_invocationFlags & ~INVOCATION_FLAGS.INVOCATION_FLAGS_SPECIAL_FIELD));
-
- return UnsafeGetValue(obj);
- }
-
- // UnsafeGetValue doesn't perform any consistency or visibility check.
- // It is the caller's responsibility to ensure the operation is safe.
- // When the caller needs to perform visibility checks they should call
- // InternalGetValue() instead. When the caller needs to perform
- // consistency checks they should call CheckConsistency() before
- // calling this method.
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- internal Object UnsafeGetValue(Object obj)
- {
- RuntimeType declaringType = DeclaringType as RuntimeType;
-
- RuntimeType fieldType = (RuntimeType)FieldType;
-
- bool domainInitialized = false;
- if (declaringType == null)
- {
- return RuntimeFieldHandle.GetValue(this, obj, fieldType, null, ref domainInitialized);
- }
- else
- {
- domainInitialized = declaringType.DomainInitialized;
- object retVal = RuntimeFieldHandle.GetValue(this, obj, fieldType, declaringType, ref domainInitialized);
- declaringType.DomainInitialized = domainInitialized;
- return retVal;
- }
- }
-
- #endregion
-
- #region MemberInfo Overrides
- public override String Name
- {
- get
- {
- if (m_name == null)
- m_name = RuntimeFieldHandle.GetName(this);
-
- return m_name;
- }
- }
-
- internal String FullName
- {
- get
- {
- return String.Format("{0}.{1}", DeclaringType.FullName, Name);
- }
- }
-
- public override int MetadataToken
- {
- get { return RuntimeFieldHandle.GetToken(this); }
- }
-
- internal override RuntimeModule GetRuntimeModule()
- {
- return RuntimeTypeHandle.GetModule(RuntimeFieldHandle.GetApproxDeclaringType(this));
- }
-
- #endregion
-
- #region FieldInfo Overrides
- public override Object GetValue(Object obj)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return InternalGetValue(obj, ref stackMark);
- }
-
- public override object GetRawConstantValue() { throw new InvalidOperationException(); }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public override Object GetValueDirect(TypedReference obj)
- {
- if (obj.IsNull)
- throw new ArgumentException(Environment.GetResourceString("Arg_TypedReference_Null"));
- Contract.EndContractBlock();
-
- unsafe
- {
- // Passing TypedReference by reference is easier to make correct in native code
- return RuntimeFieldHandle.GetValueDirect(this, (RuntimeType)FieldType, &obj, (RuntimeType)DeclaringType);
- }
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public override void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- InternalSetValue(obj, value, invokeAttr, binder, culture, ref stackMark);
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public override void SetValueDirect(TypedReference obj, Object value)
- {
- if (obj.IsNull)
- throw new ArgumentException(Environment.GetResourceString("Arg_TypedReference_Null"));
- Contract.EndContractBlock();
-
- unsafe
- {
- // Passing TypedReference by reference is easier to make correct in native code
- RuntimeFieldHandle.SetValueDirect(this, (RuntimeType)FieldType, &obj, value, (RuntimeType)DeclaringType);
- }
- }
-
- public override RuntimeFieldHandle FieldHandle
- {
- get
- {
- Type declaringType = DeclaringType;
- if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly"));
- return new RuntimeFieldHandle(this);
- }
- }
-
- internal IntPtr GetFieldHandle()
- {
- return m_fieldHandle;
- }
-
- public override FieldAttributes Attributes
- {
- get
- {
- return m_fieldAttributes;
- }
- }
-
- public override Type FieldType
- {
- get
- {
- if (m_fieldType == null)
- m_fieldType = new Signature(this, m_declaringType).FieldType;
-
- return m_fieldType;
- }
- }
-
- public override Type[] GetRequiredCustomModifiers()
- {
- return new Signature(this, m_declaringType).GetCustomModifiers(1, true);
- }
-
- public override Type[] GetOptionalCustomModifiers()
- {
- return new Signature(this, m_declaringType).GetCustomModifiers(1, false);
- }
-
- #endregion
- }
-
- [Serializable]
- internal sealed unsafe class MdFieldInfo : RuntimeFieldInfo, ISerializable
- {
- #region Private Data Members
- private int m_tkField;
- private string m_name;
- private RuntimeType m_fieldType;
- private FieldAttributes m_fieldAttributes;
- #endregion
-
- #region Constructor
- internal MdFieldInfo(
- int tkField, FieldAttributes fieldAttributes, RuntimeTypeHandle declaringTypeHandle, RuntimeTypeCache reflectedTypeCache, BindingFlags bindingFlags)
- : base(reflectedTypeCache, declaringTypeHandle.GetRuntimeType(), bindingFlags)
- {
- m_tkField = tkField;
- m_name = null;
- m_fieldAttributes = fieldAttributes;
- }
- #endregion
-
- #region Internal Members
- internal override bool CacheEquals(object o)
- {
- MdFieldInfo m = o as MdFieldInfo;
-
- if ((object)m == null)
- return false;
-
- return m.m_tkField == m_tkField &&
- m_declaringType.GetTypeHandleInternal().GetModuleHandle().Equals(
- m.m_declaringType.GetTypeHandleInternal().GetModuleHandle());
- }
- #endregion
-
- #region MemberInfo Overrides
- public override String Name
- {
- get
- {
- if (m_name == null)
- m_name = GetRuntimeModule().MetadataImport.GetName(m_tkField).ToString();
-
- return m_name;
- }
- }
-
- public override int MetadataToken { get { return m_tkField; } }
- internal override RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); }
- #endregion
-
- #region FieldInfo Overrides
- public override RuntimeFieldHandle FieldHandle { get { throw new NotSupportedException(); } }
- public override FieldAttributes Attributes { get { return m_fieldAttributes; } }
-
- public override bool IsSecurityCritical { get { return DeclaringType.IsSecurityCritical; } }
- public override bool IsSecuritySafeCritical { get { return DeclaringType.IsSecuritySafeCritical; } }
- public override bool IsSecurityTransparent { get { return DeclaringType.IsSecurityTransparent; } }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public override Object GetValueDirect(TypedReference obj)
- {
- return GetValue(null);
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public override void SetValueDirect(TypedReference obj,Object value)
- {
- throw new FieldAccessException(Environment.GetResourceString("Acc_ReadOnly"));
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public unsafe override Object GetValue(Object obj)
- {
- return GetValue(false);
- }
-
- public unsafe override Object GetRawConstantValue() { return GetValue(true); }
-
- private unsafe Object GetValue(bool raw)
- {
- // Cannot cache these because they could be user defined non-agile enumerations
-
- Object value = MdConstant.GetValue(GetRuntimeModule().MetadataImport, m_tkField, FieldType.GetTypeHandleInternal(), raw);
-
- if (value == DBNull.Value)
- throw new NotSupportedException(Environment.GetResourceString("Arg_EnumLitValueNotFound"));
-
- return value;
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public override void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
- {
- throw new FieldAccessException(Environment.GetResourceString("Acc_ReadOnly"));
- }
-
- public override Type FieldType
- {
- get
- {
- if (m_fieldType == null)
- {
- ConstArray fieldMarshal = GetRuntimeModule().MetadataImport.GetSigOfFieldDef(m_tkField);
-
- m_fieldType = new Signature(fieldMarshal.Signature.ToPointer(),
- (int)fieldMarshal.Length, m_declaringType).FieldType;
- }
-
- return m_fieldType;
- }
- }
-
- public override Type[] GetRequiredCustomModifiers()
- {
- return EmptyArray<Type>.Value;
- }
-
- public override Type[] GetOptionalCustomModifiers()
- {
- return EmptyArray<Type>.Value;
- }
-
- #endregion
- }
-
-}
diff --git a/src/mscorlib/src/System/Reflection/GenericParameterAttributes.cs b/src/mscorlib/src/System/Reflection/GenericParameterAttributes.cs
deleted file mode 100644
index d954b2e0f2..0000000000
--- a/src/mscorlib/src/System/Reflection/GenericParameterAttributes.cs
+++ /dev/null
@@ -1,22 +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.
-
-//
-
-namespace System.Reflection
-{
- [Flags()]
- public enum GenericParameterAttributes
- {
- None = 0x0000,
- VarianceMask = 0x0003,
- Covariant = 0x0001,
- Contravariant = 0x0002,
- SpecialConstraintMask = 0x001C,
- ReferenceTypeConstraint = 0x0004,
- NotNullableValueTypeConstraint = 0x0008,
- DefaultConstructorConstraint = 0x0010,
- }
-}
-
diff --git a/src/mscorlib/src/System/Reflection/ICustomAttributeProvider.cs b/src/mscorlib/src/System/Reflection/ICustomAttributeProvider.cs
deleted file mode 100644
index faea91a81e..0000000000
--- a/src/mscorlib/src/System/Reflection/ICustomAttributeProvider.cs
+++ /dev/null
@@ -1,33 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// ICustomAttributeProvider is an interface that is implemented by reflection
-//
-// objects which support custom attributes.
-//
-//
-namespace System.Reflection {
-
- using System;
-
- // Interface does not need to be marked with the serializable attribute
- public interface ICustomAttributeProvider
- {
-
- // Return an array of custom attributes identified by Type
- Object[] GetCustomAttributes(Type attributeType, bool inherit);
-
-
- // Return an array of all of the custom attributes (named attributes are not included)
- Object[] GetCustomAttributes(bool inherit);
-
-
- // Returns true if one or more instance of attributeType is defined on this member.
- bool IsDefined (Type attributeType, bool inherit);
-
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/INVOCATION_FLAGS.cs b/src/mscorlib/src/System/Reflection/INVOCATION_FLAGS.cs
new file mode 100644
index 0000000000..6ffc3e968b
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/INVOCATION_FLAGS.cs
@@ -0,0 +1,38 @@
+// 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.
+
+namespace System.Reflection
+{
+ //
+ // Invocation cached flags. Those are used in unmanaged code as well
+ // so be careful if you change them
+ //
+ [Flags]
+ internal enum INVOCATION_FLAGS : uint
+ {
+ INVOCATION_FLAGS_UNKNOWN = 0x00000000,
+ INVOCATION_FLAGS_INITIALIZED = 0x00000001,
+ // it's used for both method and field to signify that no access is allowed
+ INVOCATION_FLAGS_NO_INVOKE = 0x00000002,
+ INVOCATION_FLAGS_NEED_SECURITY = 0x00000004,
+ // Set for static ctors and ctors on abstract types, which
+ // can be invoked only if the "this" object is provided (even if it's null).
+ INVOCATION_FLAGS_NO_CTOR_INVOKE = 0x00000008,
+ // because field and method are different we can reuse the same bits
+ // method
+ INVOCATION_FLAGS_IS_CTOR = 0x00000010,
+ INVOCATION_FLAGS_RISKY_METHOD = 0x00000020,
+ /* unused 0x00000040 */
+ INVOCATION_FLAGS_IS_DELEGATE_CTOR = 0x00000080,
+ INVOCATION_FLAGS_CONTAINS_STACK_POINTERS = 0x00000100,
+ // field
+ INVOCATION_FLAGS_SPECIAL_FIELD = 0x00000010,
+ INVOCATION_FLAGS_FIELD_SPECIAL_CAST = 0x00000020,
+
+ // temporary flag used for flagging invocation of method vs ctor
+ // this flag never appears on the instance m_invocationFlag and is simply
+ // passed down from within ConstructorInfo.Invoke()
+ INVOCATION_FLAGS_CONSTRUCTOR_INVOKE = 0x10000000,
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/IReflect.cs b/src/mscorlib/src/System/Reflection/IReflect.cs
deleted file mode 100644
index 1c3c57613b..0000000000
--- a/src/mscorlib/src/System/Reflection/IReflect.cs
+++ /dev/null
@@ -1,116 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// IReflect is an interface that defines a subset of the Type reflection methods.
-//
-// This interface is used to access and invoke members of a Type. It can be either
-// type based (like Type) or instance based (like Expando). This interface is used in
-// combination with IExpando to model the IDispatchEx expando capibilities in
-// the interop layer.
-//
-//
-namespace System.Reflection {
- using System;
- using System.Runtime.InteropServices;
- using CultureInfo = System.Globalization.CultureInfo;
-
- // Interface does not need to be marked with the serializable attribute
- [Guid("AFBF15E5-C37C-11d2-B88E-00A0C9B471B8")]
- public interface IReflect
- {
- // Return the requested method if it is implemented by the Reflection object. The
- // match is based upon the name and DescriptorInfo which describes the signature
- // of the method.
- MethodInfo GetMethod(String name,BindingFlags bindingAttr,Binder binder,
- Type[] types,ParameterModifier[] modifiers);
-
- // Return the requested method if it is implemented by the Reflection object. The
- // match is based upon the name of the method. If the object implementes multiple methods
- // with the same name an AmbiguousMatchException is thrown.
- MethodInfo GetMethod(String name,BindingFlags bindingAttr);
-
- MethodInfo[] GetMethods(BindingFlags bindingAttr);
-
- // Return the requestion field if it is implemented by the Reflection object. The
- // match is based upon a name. There cannot be more than a single field with
- // a name.
- FieldInfo GetField(
- String name,
- BindingFlags bindingAttr);
-
- FieldInfo[] GetFields(
- BindingFlags bindingAttr);
-
- // Return the property based upon name. If more than one property has the given
- // name an AmbiguousMatchException will be thrown. Returns null if no property
- // is found.
- PropertyInfo GetProperty(
- String name,
- BindingFlags bindingAttr);
-
- // Return the property based upon the name and Descriptor info describing the property
- // indexing. Return null if no property is found.
- PropertyInfo GetProperty(
- String name,
- BindingFlags bindingAttr,
- Binder binder,
- Type returnType,
- Type[] types,
- ParameterModifier[] modifiers);
-
- // Returns an array of PropertyInfos for all the properties defined on
- // the Reflection object.
- PropertyInfo[] GetProperties(
- BindingFlags bindingAttr);
-
- // Return an array of members which match the passed in name.
- MemberInfo[] GetMember(
- String name,
- BindingFlags bindingAttr);
-
- // Return an array of all of the members defined for this object.
- MemberInfo[] GetMembers(
- BindingFlags bindingAttr);
-
- // Description of the Binding Process.
- // We must invoke a method that is accessable and for which the provided
- // parameters have the most specific match. A method may be called if
- // 1. The number of parameters in the method declaration equals the number of
- // arguments provided to the invocation
- // 2. The type of each argument can be converted by the binder to the
- // type of the type of the parameter.
- //
- // The binder will find all of the matching methods. These method are found based
- // upon the type of binding requested (MethodInvoke, Get/Set Properties). The set
- // of methods is filtered by the name, number of arguments and a set of search modifiers
- // defined in the Binder.
- //
- // After the method is selected, it will be invoked. Accessability is checked
- // at that point. The search may be control which set of methods are searched based
- // upon the accessibility attribute associated with the method.
- //
- // The BindToMethod method is responsible for selecting the method to be invoked.
- // For the default binder, the most specific method will be selected.
- //
- // This will invoke a specific member...
- Object InvokeMember(
- String name,
- BindingFlags invokeAttr,
- Binder binder,
- Object target,
- Object[] args,
- ParameterModifier[] modifiers,
- CultureInfo culture,
- String[] namedParameters);
-
- // Return the underlying Type that represents the IReflect Object. For expando object,
- // this is the (Object) IReflectInstance.GetType(). For Type object it is this.
- Type UnderlyingSystemType {
- get;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/IReflectableType.cs b/src/mscorlib/src/System/Reflection/IReflectableType.cs
deleted file mode 100644
index 7d4936868b..0000000000
--- a/src/mscorlib/src/System/Reflection/IReflectableType.cs
+++ /dev/null
@@ -1,20 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// IReflectableType is an interface that is implemented by a Type produced
-// by a ReflectionContext
-//
-
-//
-namespace System.Reflection {
-
- using System;
-
- public interface IReflectableType {
- TypeInfo GetTypeInfo();
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/InterfaceMapping.cs b/src/mscorlib/src/System/Reflection/InterfaceMapping.cs
deleted file mode 100644
index bf994f7b47..0000000000
--- a/src/mscorlib/src/System/Reflection/InterfaceMapping.cs
+++ /dev/null
@@ -1,22 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-//
-// Interface Map. This struct returns the mapping of an interface into the actual methods on a class
-// that implement that interface.
-//
-//
-namespace System.Reflection {
- using System;
-
- public struct InterfaceMapping {
- public Type TargetType; // The type implementing the interface
- public Type InterfaceType; // The type representing the interface
- public MethodInfo[] TargetMethods; // The methods implementing the interface
- public MethodInfo[] InterfaceMethods; // The methods defined on the interface
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/IntrospectionExtensions.cs b/src/mscorlib/src/System/Reflection/IntrospectionExtensions.cs
deleted file mode 100644
index 49819a942f..0000000000
--- a/src/mscorlib/src/System/Reflection/IntrospectionExtensions.cs
+++ /dev/null
@@ -1,28 +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.
-
-/*=============================================================================
-**
-**
-**
-**
-**
-** Purpose: Get the underlying TypeInfo from a Type
-**
-**
-=============================================================================*/
-namespace System.Reflection
-{
- public static class IntrospectionExtensions
- {
- public static TypeInfo GetTypeInfo(this Type type)
- {
- if (type == null)
- throw new ArgumentNullException(nameof(type));
-
- var rcType=(IReflectableType)type;
- return rcType.GetTypeInfo();
- }
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/InvalidFilterCriteriaException.cs b/src/mscorlib/src/System/Reflection/InvalidFilterCriteriaException.cs
deleted file mode 100644
index 8b8c06d9cf..0000000000
--- a/src/mscorlib/src/System/Reflection/InvalidFilterCriteriaException.cs
+++ /dev/null
@@ -1,39 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// InvalidFilterCriteriaException is thrown in FindMembers when the
-//
-// filter criteria is not valid for the type of filter being used.
-//
-//
-//
-//
-namespace System.Reflection {
-
- using System;
- using System.Runtime.Serialization;
- using ApplicationException = System.ApplicationException;
- [Serializable]
- public class InvalidFilterCriteriaException : ApplicationException {
- public InvalidFilterCriteriaException()
- : base(Environment.GetResourceString("Arg_InvalidFilterCriteriaException")) {
- SetErrorCode(__HResults.COR_E_INVALIDFILTERCRITERIA);
- }
-
- public InvalidFilterCriteriaException(String message) : base(message) {
- SetErrorCode(__HResults.COR_E_INVALIDFILTERCRITERIA);
- }
-
- public InvalidFilterCriteriaException(String message, Exception inner) : base(message, inner) {
- SetErrorCode(__HResults.COR_E_INVALIDFILTERCRITERIA);
- }
-
- protected InvalidFilterCriteriaException(SerializationInfo info, StreamingContext context) : base(info, context) {
- }
-
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/LoaderAllocator.cs b/src/mscorlib/src/System/Reflection/LoaderAllocator.cs
index 7c6c6bd0e8..035f158251 100644
--- a/src/mscorlib/src/System/Reflection/LoaderAllocator.cs
+++ b/src/mscorlib/src/System/Reflection/LoaderAllocator.cs
@@ -49,7 +49,6 @@ namespace System.Reflection
if (!Environment.HasShutdownStarted &&
!AppDomain.CurrentDomain.IsFinalizingForUnload())
{
-
// Destroy returns false if the managed LoaderAllocator is still alive.
if (!Destroy(m_nativeLoaderAllocator))
{
@@ -63,9 +62,9 @@ namespace System.Reflection
internal sealed class LoaderAllocator
{
- LoaderAllocator()
+ private LoaderAllocator()
{
- m_slots = new object [5];
+ m_slots = new object[5];
// m_slotsUsed = 0;
m_scout = new LoaderAllocatorScout();
@@ -73,10 +72,10 @@ namespace System.Reflection
#pragma warning disable 169
#pragma warning disable 414
- LoaderAllocatorScout m_scout;
- object [] m_slots;
+ private LoaderAllocatorScout m_scout;
+ private object[] m_slots;
internal CerHashtable<RuntimeMethodInfo, RuntimeMethodInfo> m_methodInstantiations;
- int m_slotsUsed;
+ private int m_slotsUsed;
#pragma warning restore 414
#pragma warning restore 169
}
diff --git a/src/mscorlib/src/System/Reflection/LocalVariableInfo.cs b/src/mscorlib/src/System/Reflection/LocalVariableInfo.cs
new file mode 100644
index 0000000000..241a3c4de6
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/LocalVariableInfo.cs
@@ -0,0 +1,40 @@
+// 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.Diagnostics;
+
+namespace System.Reflection
+{
+ public class LocalVariableInfo
+ {
+ #region Private Data Members
+ private RuntimeType m_type;
+ private int m_isPinned;
+ private int m_localIndex;
+ #endregion
+
+ #region Constructor
+ protected LocalVariableInfo() { }
+ #endregion
+
+ #region Object Overrides
+ public override string ToString()
+ {
+ string toString = LocalType.ToString() + " (" + LocalIndex + ")";
+
+ if (IsPinned)
+ toString += " (pinned)";
+
+ return toString;
+ }
+ #endregion
+
+ #region Public Members
+ public virtual Type LocalType { get { Debug.Assert(m_type != null, "type must be set!"); return m_type; } }
+ public virtual bool IsPinned { get { return m_isPinned != 0; } }
+ public virtual int LocalIndex { get { return m_localIndex; } }
+ #endregion
+ }
+}
+
diff --git a/src/mscorlib/src/System/Reflection/ManifestResourceInfo.cs b/src/mscorlib/src/System/Reflection/ManifestResourceInfo.cs
deleted file mode 100644
index 91c7ceb2ea..0000000000
--- a/src/mscorlib/src/System/Reflection/ManifestResourceInfo.cs
+++ /dev/null
@@ -1,65 +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.
-
-/*=============================================================================
-**
-**
-**
-**
-**
-** Purpose: For info regarding a manifest resource's topology.
-**
-**
-=============================================================================*/
-
-namespace System.Reflection {
- using System;
-
- public class ManifestResourceInfo {
- private Assembly _containingAssembly;
- private String _containingFileName;
- private ResourceLocation _resourceLocation;
-
- public ManifestResourceInfo(Assembly containingAssembly,
- String containingFileName,
- ResourceLocation resourceLocation)
- {
- _containingAssembly = containingAssembly;
- _containingFileName = containingFileName;
- _resourceLocation = resourceLocation;
- }
-
- public virtual Assembly ReferencedAssembly
- {
- get {
- return _containingAssembly;
- }
- }
-
- public virtual String FileName
- {
- get {
- return _containingFileName;
- }
- }
-
- public virtual ResourceLocation ResourceLocation
- {
- get {
- return _resourceLocation;
- }
- }
- }
-
- // The ResourceLocation is a combination of these flags, set or not.
- // Linked means not Embedded.
-[Serializable]
- [Flags]
- public enum ResourceLocation
- {
- Embedded = 0x1,
- ContainedInAnotherAssembly = 0x2,
- ContainedInManifestFile = 0x4
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/MdConstant.cs b/src/mscorlib/src/System/Reflection/MdConstant.cs
index e59244f109..8e5b65724d 100644
--- a/src/mscorlib/src/System/Reflection/MdConstant.cs
+++ b/src/mscorlib/src/System/Reflection/MdConstant.cs
@@ -4,10 +4,10 @@
//
+using System;
+
namespace System.Reflection
{
- using System;
-
internal static class MdConstant
{
public static unsafe Object GetValue(MetadataImport scope, int token, RuntimeTypeHandle fieldTypeHandle, bool raw)
@@ -67,13 +67,13 @@ namespace System.Reflection
case CorElementType.U8:
defaultValue = buffer;
break;
-
+
default:
- throw new FormatException(Environment.GetResourceString("Arg_BadLiteralFormat"));
- #endregion
+ throw new FormatException(SR.Arg_BadLiteralFormat);
+ #endregion
}
- return RuntimeType.CreateEnum(fieldType, defaultValue);
+ return RuntimeType.CreateEnum(fieldType, defaultValue);
}
else if (fieldType == typeof(DateTime))
{
@@ -85,7 +85,7 @@ namespace System.Reflection
case CorElementType.Void:
return DBNull.Value;
-
+
case CorElementType.I8:
defaultValue = buffer;
break;
@@ -93,10 +93,10 @@ namespace System.Reflection
case CorElementType.U8:
defaultValue = buffer;
break;
-
+
default:
- throw new FormatException(Environment.GetResourceString("Arg_BadLiteralFormat"));
- #endregion
+ throw new FormatException(SR.Arg_BadLiteralFormat);
+ #endregion
}
return new DateTime(defaultValue);
@@ -136,14 +136,14 @@ namespace System.Reflection
case CorElementType.U8:
return (ulong)buffer;
-
- case CorElementType.Boolean :
+
+ case CorElementType.Boolean:
// The boolean value returned from the metadata engine is stored as a
// BOOL, which actually maps to an int. We need to read it out as an int
// to avoid problems on big-endian machines.
return (*(int*)&buffer != 0);
- case CorElementType.R4 :
+ case CorElementType.R4:
return *(float*)&buffer;
case CorElementType.R8:
@@ -156,13 +156,12 @@ namespace System.Reflection
case CorElementType.Class:
return null;
-
+
default:
- throw new FormatException(Environment.GetResourceString("Arg_BadLiteralFormat"));
- #endregion
+ throw new FormatException(SR.Arg_BadLiteralFormat);
+ #endregion
}
}
- }
+ }
}
-
}
diff --git a/src/mscorlib/src/System/Reflection/MdFieldInfo.cs b/src/mscorlib/src/System/Reflection/MdFieldInfo.cs
new file mode 100644
index 0000000000..41ee4d9297
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/MdFieldInfo.cs
@@ -0,0 +1,141 @@
+// 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.Diagnostics;
+using System.Globalization;
+using System.Runtime.Serialization;
+using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
+
+namespace System.Reflection
+{
+ [Serializable]
+ internal sealed unsafe class MdFieldInfo : RuntimeFieldInfo, ISerializable
+ {
+ #region Private Data Members
+ private int m_tkField;
+ private string m_name;
+ private RuntimeType m_fieldType;
+ private FieldAttributes m_fieldAttributes;
+ #endregion
+
+ #region Constructor
+ internal MdFieldInfo(
+ int tkField, FieldAttributes fieldAttributes, RuntimeTypeHandle declaringTypeHandle, RuntimeTypeCache reflectedTypeCache, BindingFlags bindingFlags)
+ : base(reflectedTypeCache, declaringTypeHandle.GetRuntimeType(), bindingFlags)
+ {
+ m_tkField = tkField;
+ m_name = null;
+ m_fieldAttributes = fieldAttributes;
+ }
+ #endregion
+
+ #region Internal Members
+ internal override bool CacheEquals(object o)
+ {
+ MdFieldInfo m = o as MdFieldInfo;
+
+ if ((object)m == null)
+ return false;
+
+ return m.m_tkField == m_tkField &&
+ m_declaringType.GetTypeHandleInternal().GetModuleHandle().Equals(
+ m.m_declaringType.GetTypeHandleInternal().GetModuleHandle());
+ }
+ #endregion
+
+ #region MemberInfo Overrides
+ public override String Name
+ {
+ get
+ {
+ if (m_name == null)
+ m_name = GetRuntimeModule().MetadataImport.GetName(m_tkField).ToString();
+
+ return m_name;
+ }
+ }
+
+ public override int MetadataToken { get { return m_tkField; } }
+ internal override RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); }
+ #endregion
+
+ #region FieldInfo Overrides
+ public override RuntimeFieldHandle FieldHandle { get { throw new NotSupportedException(); } }
+ public override FieldAttributes Attributes { get { return m_fieldAttributes; } }
+
+ public override bool IsSecurityCritical { get { return DeclaringType.IsSecurityCritical; } }
+ public override bool IsSecuritySafeCritical { get { return DeclaringType.IsSecuritySafeCritical; } }
+ public override bool IsSecurityTransparent { get { return DeclaringType.IsSecurityTransparent; } }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ public override Object GetValueDirect(TypedReference obj)
+ {
+ return GetValue(null);
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ public override void SetValueDirect(TypedReference obj, Object value)
+ {
+ throw new FieldAccessException(SR.Acc_ReadOnly);
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ public unsafe override Object GetValue(Object obj)
+ {
+ return GetValue(false);
+ }
+
+ public unsafe override Object GetRawConstantValue() { return GetValue(true); }
+
+ private unsafe Object GetValue(bool raw)
+ {
+ // Cannot cache these because they could be user defined non-agile enumerations
+
+ Object value = MdConstant.GetValue(GetRuntimeModule().MetadataImport, m_tkField, FieldType.GetTypeHandleInternal(), raw);
+
+ if (value == DBNull.Value)
+ throw new NotSupportedException(SR.Arg_EnumLitValueNotFound);
+
+ return value;
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ public override void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
+ {
+ throw new FieldAccessException(SR.Acc_ReadOnly);
+ }
+
+ public override Type FieldType
+ {
+ get
+ {
+ if (m_fieldType == null)
+ {
+ ConstArray fieldMarshal = GetRuntimeModule().MetadataImport.GetSigOfFieldDef(m_tkField);
+
+ m_fieldType = new Signature(fieldMarshal.Signature.ToPointer(),
+ (int)fieldMarshal.Length, m_declaringType).FieldType;
+ }
+
+ return m_fieldType;
+ }
+ }
+
+ public override Type[] GetRequiredCustomModifiers()
+ {
+ return Array.Empty<Type>();
+ }
+
+ public override Type[] GetOptionalCustomModifiers()
+ {
+ return Array.Empty<Type>();
+ }
+
+ #endregion
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/MdImport.cs b/src/mscorlib/src/System/Reflection/MdImport.cs
index b1d9c5eae8..a224a50513 100644
--- a/src/mscorlib/src/System/Reflection/MdImport.cs
+++ b/src/mscorlib/src/System/Reflection/MdImport.cs
@@ -21,149 +21,149 @@ using System.Diagnostics.Contracts;
namespace System.Reflection
{
[Serializable]
- internal enum CorElementType : byte
+ internal enum CorElementType : byte
{
- End = 0x00,
- Void = 0x01,
- Boolean = 0x02,
- Char = 0x03,
- I1 = 0x04,
- U1 = 0x05,
- I2 = 0x06,
- U2 = 0x07,
- I4 = 0x08,
- U4 = 0x09,
- I8 = 0x0A,
- U8 = 0x0B,
- R4 = 0x0C,
- R8 = 0x0D,
- String = 0x0E,
- Ptr = 0x0F,
- ByRef = 0x10,
- ValueType = 0x11,
- Class = 0x12,
- Var = 0x13,
- Array = 0x14,
- GenericInst = 0x15,
- TypedByRef = 0x16,
- I = 0x18,
- U = 0x19,
- FnPtr = 0x1B,
- Object = 0x1C,
- SzArray = 0x1D,
- MVar = 0x1E,
- CModReqd = 0x1F,
- CModOpt = 0x20,
- Internal = 0x21,
- Max = 0x22,
- Modifier = 0x40,
- Sentinel = 0x41,
- Pinned = 0x45,
+ End = 0x00,
+ Void = 0x01,
+ Boolean = 0x02,
+ Char = 0x03,
+ I1 = 0x04,
+ U1 = 0x05,
+ I2 = 0x06,
+ U2 = 0x07,
+ I4 = 0x08,
+ U4 = 0x09,
+ I8 = 0x0A,
+ U8 = 0x0B,
+ R4 = 0x0C,
+ R8 = 0x0D,
+ String = 0x0E,
+ Ptr = 0x0F,
+ ByRef = 0x10,
+ ValueType = 0x11,
+ Class = 0x12,
+ Var = 0x13,
+ Array = 0x14,
+ GenericInst = 0x15,
+ TypedByRef = 0x16,
+ I = 0x18,
+ U = 0x19,
+ FnPtr = 0x1B,
+ Object = 0x1C,
+ SzArray = 0x1D,
+ MVar = 0x1E,
+ CModReqd = 0x1F,
+ CModOpt = 0x20,
+ Internal = 0x21,
+ Max = 0x22,
+ Modifier = 0x40,
+ Sentinel = 0x41,
+ Pinned = 0x45,
}
-[Serializable]
-[Flags()]
- internal enum MdSigCallingConvention: byte
+ [Serializable]
+ [Flags()]
+ internal enum MdSigCallingConvention : byte
{
- CallConvMask = 0x0f, // Calling convention is bottom 4 bits
-
- Default = 0x00,
- C = 0x01,
- StdCall = 0x02,
- ThisCall = 0x03,
- FastCall = 0x04,
- Vararg = 0x05,
- Field = 0x06,
- LocalSig = 0x07,
- Property = 0x08,
- Unmgd = 0x09,
- GenericInst = 0x0a, // generic method instantiation
-
- Generic = 0x10, // Generic method sig with explicit number of type arguments (precedes ordinary parameter count)
- HasThis = 0x20, // Top bit indicates a 'this' parameter
- ExplicitThis = 0x40, // This parameter is explicitly in the signature
+ CallConvMask = 0x0f, // Calling convention is bottom 4 bits
+
+ Default = 0x00,
+ C = 0x01,
+ StdCall = 0x02,
+ ThisCall = 0x03,
+ FastCall = 0x04,
+ Vararg = 0x05,
+ Field = 0x06,
+ LocalSig = 0x07,
+ Property = 0x08,
+ Unmgd = 0x09,
+ GenericInst = 0x0a, // generic method instantiation
+
+ Generic = 0x10, // Generic method sig with explicit number of type arguments (precedes ordinary parameter count)
+ HasThis = 0x20, // Top bit indicates a 'this' parameter
+ ExplicitThis = 0x40, // This parameter is explicitly in the signature
}
-[Serializable]
-[Flags()]
+ [Serializable]
+ [Flags()]
internal enum PInvokeAttributes
- {
- NoMangle = 0x0001,
-
-
- CharSetMask = 0x0006,
- CharSetNotSpec = 0x0000,
- CharSetAnsi = 0x0002,
- CharSetUnicode = 0x0004,
- CharSetAuto = 0x0006,
-
-
- BestFitUseAssem = 0x0000,
- BestFitEnabled = 0x0010,
- BestFitDisabled = 0x0020,
- BestFitMask = 0x0030,
-
- ThrowOnUnmappableCharUseAssem = 0x0000,
- ThrowOnUnmappableCharEnabled = 0x1000,
- ThrowOnUnmappableCharDisabled = 0x2000,
- ThrowOnUnmappableCharMask = 0x3000,
-
- SupportsLastError = 0x0040,
-
- CallConvMask = 0x0700,
- CallConvWinapi = 0x0100,
- CallConvCdecl = 0x0200,
- CallConvStdcall = 0x0300,
- CallConvThiscall = 0x0400,
- CallConvFastcall = 0x0500,
-
- MaxValue = 0xFFFF,
+ {
+ NoMangle = 0x0001,
+
+
+ CharSetMask = 0x0006,
+ CharSetNotSpec = 0x0000,
+ CharSetAnsi = 0x0002,
+ CharSetUnicode = 0x0004,
+ CharSetAuto = 0x0006,
+
+
+ BestFitUseAssem = 0x0000,
+ BestFitEnabled = 0x0010,
+ BestFitDisabled = 0x0020,
+ BestFitMask = 0x0030,
+
+ ThrowOnUnmappableCharUseAssem = 0x0000,
+ ThrowOnUnmappableCharEnabled = 0x1000,
+ ThrowOnUnmappableCharDisabled = 0x2000,
+ ThrowOnUnmappableCharMask = 0x3000,
+
+ SupportsLastError = 0x0040,
+
+ CallConvMask = 0x0700,
+ CallConvWinapi = 0x0100,
+ CallConvCdecl = 0x0200,
+ CallConvStdcall = 0x0300,
+ CallConvThiscall = 0x0400,
+ CallConvFastcall = 0x0500,
+
+ MaxValue = 0xFFFF,
}
-[Serializable]
-[Flags()]
+ [Serializable]
+ [Flags()]
internal enum MethodSemanticsAttributes
{
- Setter = 0x0001,
- Getter = 0x0002,
- Other = 0x0004,
- AddOn = 0x0008,
- RemoveOn = 0x0010,
- Fire = 0x0020,
+ Setter = 0x0001,
+ Getter = 0x0002,
+ Other = 0x0004,
+ AddOn = 0x0008,
+ RemoveOn = 0x0010,
+ Fire = 0x0020,
}
[Serializable]
internal enum MetadataTokenType
{
- Module = 0x00000000,
- TypeRef = 0x01000000,
- TypeDef = 0x02000000,
- FieldDef = 0x04000000,
- MethodDef = 0x06000000,
- ParamDef = 0x08000000,
- InterfaceImpl = 0x09000000,
- MemberRef = 0x0a000000,
- CustomAttribute = 0x0c000000,
- Permission = 0x0e000000,
- Signature = 0x11000000,
- Event = 0x14000000,
- Property = 0x17000000,
- ModuleRef = 0x1a000000,
- TypeSpec = 0x1b000000,
- Assembly = 0x20000000,
- AssemblyRef = 0x23000000,
- File = 0x26000000,
- ExportedType = 0x27000000,
- ManifestResource = 0x28000000,
- GenericPar = 0x2a000000,
- MethodSpec = 0x2b000000,
- String = 0x70000000,
- Name = 0x71000000,
- BaseType = 0x72000000,
- Invalid = 0x7FFFFFFF,
+ Module = 0x00000000,
+ TypeRef = 0x01000000,
+ TypeDef = 0x02000000,
+ FieldDef = 0x04000000,
+ MethodDef = 0x06000000,
+ ParamDef = 0x08000000,
+ InterfaceImpl = 0x09000000,
+ MemberRef = 0x0a000000,
+ CustomAttribute = 0x0c000000,
+ Permission = 0x0e000000,
+ Signature = 0x11000000,
+ Event = 0x14000000,
+ Property = 0x17000000,
+ ModuleRef = 0x1a000000,
+ TypeSpec = 0x1b000000,
+ Assembly = 0x20000000,
+ AssemblyRef = 0x23000000,
+ File = 0x26000000,
+ ExportedType = 0x27000000,
+ ManifestResource = 0x28000000,
+ GenericPar = 0x2a000000,
+ MethodSpec = 0x2b000000,
+ String = 0x70000000,
+ Name = 0x71000000,
+ BaseType = 0x72000000,
+ Invalid = 0x7FFFFFFF,
}
[Serializable]
@@ -179,7 +179,7 @@ namespace System.Reflection
throw new IndexOutOfRangeException();
Contract.EndContractBlock();
- unsafe
+ unsafe
{
return ((byte*)m_constArray.ToPointer())[index];
}
@@ -190,7 +190,7 @@ namespace System.Reflection
internal int m_length;
internal IntPtr m_constArray;
}
-
+
[Serializable]
internal struct MetadataToken
{
@@ -211,9 +211,9 @@ namespace System.Reflection
return false;
}
- public static bool IsNullToken(int token)
- {
- return (token & 0x00FFFFFF) == 0;
+ public static bool IsNullToken(int token)
+ {
+ return (token & 0x00FFFFFF) == 0;
}
#endregion
@@ -222,11 +222,11 @@ namespace System.Reflection
#endregion
#region Constructor
- public MetadataToken(int token) { Value = token; }
+ public MetadataToken(int token) { Value = token; }
#endregion
-
+
#region Public Members
- public bool IsGlobalTypeDefToken { get { return (Value == 0x02000001); } }
+ public bool IsGlobalTypeDefToken { get { return (Value == 0x02000001); } }
public MetadataTokenType TokenType { get { return (MetadataTokenType)(Value & 0xFF000000); } }
public bool IsTypeRef { get { return TokenType == MetadataTokenType.TypeRef; } }
public bool IsTypeDef { get { return TokenType == MetadataTokenType.TypeDef; } }
@@ -288,7 +288,7 @@ namespace System.Reflection
#region Override methods from Object
internal static readonly MetadataImport EmptyImport = new MetadataImport((IntPtr)0, null);
-
+
public override int GetHashCode()
{
return ValueType.GetHashCodeOfPtr(m_metadataImport2);
@@ -296,11 +296,11 @@ namespace System.Reflection
public override bool Equals(object obj)
{
- if(!(obj is MetadataImport))
+ if (!(obj is MetadataImport))
return false;
return Equals((MetadataImport)obj);
}
-
+
private bool Equals(MetadataImport import)
{
return import.m_metadataImport2 == m_metadataImport2;
@@ -310,18 +310,18 @@ namespace System.Reflection
#region Static Members
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void _GetMarshalAs(IntPtr pNativeType, int cNativeType, out int unmanagedType, out int safeArraySubType, out string safeArrayUserDefinedSubType,
+ private static extern void _GetMarshalAs(IntPtr pNativeType, int cNativeType, out int unmanagedType, out int safeArraySubType, out string safeArrayUserDefinedSubType,
out int arraySubType, out int sizeParamIndex, out int sizeConst, out string marshalType, out string marshalCookie,
out int iidParamIndex);
- internal static void GetMarshalAs(ConstArray nativeType,
- out UnmanagedType unmanagedType, out VarEnum safeArraySubType, out string safeArrayUserDefinedSubType,
+ internal static void GetMarshalAs(ConstArray nativeType,
+ out UnmanagedType unmanagedType, out VarEnum safeArraySubType, out string safeArrayUserDefinedSubType,
out UnmanagedType arraySubType, out int sizeParamIndex, out int sizeConst, out string marshalType, out string marshalCookie,
out int iidParamIndex)
{
int _unmanagedType, _safeArraySubType, _arraySubType;
_GetMarshalAs(nativeType.Signature, (int)nativeType.Length,
- out _unmanagedType, out _safeArraySubType, out safeArrayUserDefinedSubType,
+ out _unmanagedType, out _safeArraySubType, out safeArrayUserDefinedSubType,
out _arraySubType, out sizeParamIndex, out sizeConst, out marshalType, out marshalCookie,
out iidParamIndex);
unmanagedType = (UnmanagedType)_unmanagedType;
@@ -339,32 +339,32 @@ namespace System.Reflection
#region Constructor
internal MetadataImport(IntPtr metadataImport2, object keepalive)
- {
+ {
m_metadataImport2 = metadataImport2;
m_keepalive = keepalive;
}
#endregion
#region FCalls
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
private unsafe static extern void _Enum(IntPtr scope, int type, int parent, out MetadataEnumResult result);
- public unsafe void Enum(MetadataTokenType type, int parent, out MetadataEnumResult result)
- {
+ public unsafe void Enum(MetadataTokenType type, int parent, out MetadataEnumResult result)
+ {
_Enum(m_metadataImport2, (int)type, parent, out result);
}
- public unsafe void EnumNestedTypes(int mdTypeDef, out MetadataEnumResult result)
+ public unsafe void EnumNestedTypes(int mdTypeDef, out MetadataEnumResult result)
{
Enum(MetadataTokenType.TypeDef, mdTypeDef, out result);
}
- public unsafe void EnumCustomAttributes(int mdToken, out MetadataEnumResult result)
+ public unsafe void EnumCustomAttributes(int mdToken, out MetadataEnumResult result)
{
Enum(MetadataTokenType.CustomAttribute, mdToken, out result);
}
- public unsafe void EnumParams(int mdMethodDef, out MetadataEnumResult result)
+ public unsafe void EnumParams(int mdMethodDef, out MetadataEnumResult result)
{
Enum(MetadataTokenType.ParamDef, mdMethodDef, out result);
}
@@ -384,30 +384,30 @@ namespace System.Reflection
Enum(MetadataTokenType.Event, mdTypeDef, out result);
}
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern String _GetDefaultValue(IntPtr scope, int mdToken, out long value, out int length, out int corElementType);
- public String GetDefaultValue(int mdToken, out long value, out int length, out CorElementType corElementType)
- {
- int _corElementType;
+ public String GetDefaultValue(int mdToken, out long value, out int length, out CorElementType corElementType)
+ {
+ int _corElementType;
String stringVal;
- stringVal = _GetDefaultValue(m_metadataImport2, mdToken, out value, out length, out _corElementType);
+ stringVal = _GetDefaultValue(m_metadataImport2, mdToken, out value, out length, out _corElementType);
corElementType = (CorElementType)_corElementType;
return stringVal;
}
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
private static unsafe extern void _GetUserString(IntPtr scope, int mdToken, void** name, out int length);
- public unsafe String GetUserString(int mdToken)
- {
+ public unsafe String GetUserString(int mdToken)
+ {
void* name;
int length;
- _GetUserString(m_metadataImport2, mdToken, &name, out length);
+ _GetUserString(m_metadataImport2, mdToken, &name, out length);
if (name == null)
return null;
char[] c = new char[length];
- for (int i = 0; i < c.Length; i ++)
+ for (int i = 0; i < c.Length; i++)
{
#if ALIGN_ACCESS
c[i] = (char)Marshal.ReadInt16( (IntPtr) (((char*)name) + i) );
@@ -419,87 +419,87 @@ namespace System.Reflection
return new String(c);
}
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
private static unsafe extern void _GetName(IntPtr scope, int mdToken, void** name);
- public unsafe Utf8String GetName(int mdToken)
- {
+ public unsafe Utf8String GetName(int mdToken)
+ {
void* name;
- _GetName(m_metadataImport2, mdToken, &name);
-
+ _GetName(m_metadataImport2, mdToken, &name);
+
return new Utf8String(name);
}
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
private static unsafe extern void _GetNamespace(IntPtr scope, int mdToken, void** namesp);
- public unsafe Utf8String GetNamespace(int mdToken)
- {
+ public unsafe Utf8String GetNamespace(int mdToken)
+ {
void* namesp;
_GetNamespace(m_metadataImport2, mdToken, &namesp);
-
+
return new Utf8String(namesp);
}
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
private unsafe static extern void _GetEventProps(IntPtr scope, int mdToken, void** name, out int eventAttributes);
- public unsafe void GetEventProps(int mdToken, out void* name, out EventAttributes eventAttributes)
- {
- int _eventAttributes;
+ public unsafe void GetEventProps(int mdToken, out void* name, out EventAttributes eventAttributes)
+ {
+ int _eventAttributes;
void* _name;
_GetEventProps(m_metadataImport2, mdToken, &_name, out _eventAttributes);
name = _name;
eventAttributes = (EventAttributes)_eventAttributes;
}
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _GetFieldDefProps(IntPtr scope, int mdToken, out int fieldAttributes);
- public void GetFieldDefProps(int mdToken, out FieldAttributes fieldAttributes)
- {
- int _fieldAttributes;
+ public void GetFieldDefProps(int mdToken, out FieldAttributes fieldAttributes)
+ {
+ int _fieldAttributes;
_GetFieldDefProps(m_metadataImport2, mdToken, out _fieldAttributes);
fieldAttributes = (FieldAttributes)_fieldAttributes;
}
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- private unsafe static extern void _GetPropertyProps(IntPtr scope,
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private unsafe static extern void _GetPropertyProps(IntPtr scope,
int mdToken, void** name, out int propertyAttributes, out ConstArray signature);
- public unsafe void GetPropertyProps(int mdToken, out void* name, out PropertyAttributes propertyAttributes, out ConstArray signature)
- {
- int _propertyAttributes;
+ public unsafe void GetPropertyProps(int mdToken, out void* name, out PropertyAttributes propertyAttributes, out ConstArray signature)
+ {
+ int _propertyAttributes;
void* _name;
- _GetPropertyProps(m_metadataImport2, mdToken, &_name, out _propertyAttributes, out signature);
+ _GetPropertyProps(m_metadataImport2, mdToken, &_name, out _propertyAttributes, out signature);
name = _name;
propertyAttributes = (PropertyAttributes)_propertyAttributes;
}
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- private static extern void _GetParentToken(IntPtr scope,
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void _GetParentToken(IntPtr scope,
int mdToken, out int tkParent);
- public int GetParentToken(int tkToken)
- {
+ public int GetParentToken(int tkToken)
+ {
int tkParent;
- _GetParentToken(m_metadataImport2, tkToken, out tkParent);
+ _GetParentToken(m_metadataImport2, tkToken, out tkParent);
return tkParent;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void _GetParamDefProps(IntPtr scope,
+ private static extern void _GetParamDefProps(IntPtr scope,
int parameterToken, out int sequence, out int attributes);
public void GetParamDefProps(int parameterToken, out int sequence, out ParameterAttributes attributes)
{
int _attributes;
_GetParamDefProps(m_metadataImport2, parameterToken, out sequence, out _attributes);
-
+
attributes = (ParameterAttributes)_attributes;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void _GetGenericParamProps(IntPtr scope,
- int genericParameter,
+ private static extern void _GetGenericParamProps(IntPtr scope,
+ int genericParameter,
out int flags);
-
+
public void GetGenericParamProps(
- int genericParameter,
+ int genericParameter,
out GenericParameterAttributes attributes)
{
int _attributes;
@@ -508,9 +508,9 @@ namespace System.Reflection
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void _GetScopeProps(IntPtr scope,
+ private static extern void _GetScopeProps(IntPtr scope,
out Guid mvid);
-
+
public void GetScopeProps(
out Guid mvid)
{
@@ -522,15 +522,15 @@ namespace System.Reflection
{
if (token.IsMemberRef)
return GetMemberRefProps(token);
-
+
return GetSigOfMethodDef(token);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void _GetSigOfMethodDef(IntPtr scope,
- int methodToken,
+ private static extern void _GetSigOfMethodDef(IntPtr scope,
+ int methodToken,
ref ConstArray signature);
-
+
public ConstArray GetSigOfMethodDef(int methodToken)
{
ConstArray signature = new ConstArray();
@@ -541,10 +541,10 @@ namespace System.Reflection
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void _GetSignatureFromToken(IntPtr scope,
- int methodToken,
+ private static extern void _GetSignatureFromToken(IntPtr scope,
+ int methodToken,
ref ConstArray signature);
-
+
public ConstArray GetSignatureFromToken(int token)
{
ConstArray signature = new ConstArray();
@@ -555,61 +555,61 @@ namespace System.Reflection
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void _GetMemberRefProps(IntPtr scope,
- int memberTokenRef,
+ private static extern void _GetMemberRefProps(IntPtr scope,
+ int memberTokenRef,
out ConstArray signature);
-
+
public ConstArray GetMemberRefProps(int memberTokenRef)
{
ConstArray signature = new ConstArray();
-
+
_GetMemberRefProps(m_metadataImport2, memberTokenRef, out signature);
return signature;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void _GetCustomAttributeProps(IntPtr scope,
- int customAttributeToken,
- out int constructorToken,
+ private static extern void _GetCustomAttributeProps(IntPtr scope,
+ int customAttributeToken,
+ out int constructorToken,
out ConstArray signature);
-
- public void GetCustomAttributeProps(
- int customAttributeToken,
- out int constructorToken,
+
+ public void GetCustomAttributeProps(
+ int customAttributeToken,
+ out int constructorToken,
out ConstArray signature)
{
- _GetCustomAttributeProps(m_metadataImport2, customAttributeToken,
+ _GetCustomAttributeProps(m_metadataImport2, customAttributeToken,
out constructorToken, out signature);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void _GetClassLayout(IntPtr scope,
+ private static extern void _GetClassLayout(IntPtr scope,
int typeTokenDef, out int packSize, out int classSize);
public void GetClassLayout(
- int typeTokenDef,
- out int packSize,
+ int typeTokenDef,
+ out int packSize,
out int classSize)
{
_GetClassLayout(m_metadataImport2, typeTokenDef, out packSize, out classSize);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern bool _GetFieldOffset(IntPtr scope,
+ private static extern bool _GetFieldOffset(IntPtr scope,
int typeTokenDef, int fieldTokenDef, out int offset);
public bool GetFieldOffset(
- int typeTokenDef,
- int fieldTokenDef,
+ int typeTokenDef,
+ int fieldTokenDef,
out int offset)
{
return _GetFieldOffset(m_metadataImport2, typeTokenDef, fieldTokenDef, out offset);
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void _GetSigOfFieldDef(IntPtr scope,
- int fieldToken,
+ private static extern void _GetSigOfFieldDef(IntPtr scope,
+ int fieldToken,
ref ConstArray fieldMarshal);
-
+
public ConstArray GetSigOfFieldDef(int fieldToken)
{
ConstArray fieldMarshal = new ConstArray();
@@ -620,10 +620,10 @@ namespace System.Reflection
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern void _GetFieldMarshal(IntPtr scope,
- int fieldToken,
+ private static extern void _GetFieldMarshal(IntPtr scope,
+ int fieldToken,
ref ConstArray fieldMarshal);
-
+
public ConstArray GetFieldMarshal(int fieldToken)
{
ConstArray fieldMarshal = new ConstArray();
@@ -634,16 +634,16 @@ namespace System.Reflection
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private unsafe static extern void _GetPInvokeMap(IntPtr scope,
- int token,
- out int attributes,
- void** importName,
- void** importDll);
-
+ private unsafe static extern void _GetPInvokeMap(IntPtr scope,
+ int token,
+ out int attributes,
+ void** importName,
+ void** importDll);
+
public unsafe void GetPInvokeMap(
- int token,
- out PInvokeAttributes attributes,
- out String importName,
+ int token,
+ out PInvokeAttributes attributes,
+ out String importName,
out String importDll)
{
int _attributes;
@@ -656,10 +656,10 @@ namespace System.Reflection
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern bool _IsValidToken(IntPtr scope, int token);
- public bool IsValidToken(int token)
- {
- return _IsValidToken(m_metadataImport2, token);
+ private static extern bool _IsValidToken(IntPtr scope, int token);
+ public bool IsValidToken(int token)
+ {
+ return _IsValidToken(m_metadataImport2, token);
}
#endregion
}
diff --git a/src/mscorlib/src/System/Reflection/MemberFilter.cs b/src/mscorlib/src/System/Reflection/MemberFilter.cs
deleted file mode 100644
index 56fc9c0804..0000000000
--- a/src/mscorlib/src/System/Reflection/MemberFilter.cs
+++ /dev/null
@@ -1,18 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// MemberFilter is a delegate used to filter Members. This delegate is used
-//
-// as a callback from Type.FindMembers.
-//
-//
-namespace System.Reflection {
-
- // Define the delegate
- [Serializable]
- public delegate bool MemberFilter(MemberInfo m, Object filterCriteria);
-}
diff --git a/src/mscorlib/src/System/Reflection/MemberInfo.Internal.cs b/src/mscorlib/src/System/Reflection/MemberInfo.Internal.cs
new file mode 100644
index 0000000000..8e7be56511
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/MemberInfo.Internal.cs
@@ -0,0 +1,11 @@
+// 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.
+
+namespace System.Reflection
+{
+ public abstract partial class MemberInfo
+ {
+ internal virtual bool CacheEquals(object o) { throw new NotImplementedException(); }
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/MemberInfo.cs b/src/mscorlib/src/System/Reflection/MemberInfo.cs
deleted file mode 100644
index 5ecbfe06a1..0000000000
--- a/src/mscorlib/src/System/Reflection/MemberInfo.cs
+++ /dev/null
@@ -1,113 +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.
-
-//
-
-namespace System.Reflection
-{
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.Contracts;
- using System.Runtime;
- using System.Runtime.InteropServices;
-
- [Serializable]
- public abstract class MemberInfo : ICustomAttributeProvider
- {
- #region Constructor
- protected MemberInfo() { }
- #endregion
-
- #region Internal Methods
- internal virtual bool CacheEquals(object o) { throw new NotImplementedException(); }
- #endregion
-
- #region Public Abstract\Virtual Members
- public abstract MemberTypes MemberType { get; }
-
- public abstract String Name { get; }
-
- public abstract Type DeclaringType { get; }
-
- public abstract Type ReflectedType { get; }
-
- public virtual IEnumerable<CustomAttributeData> CustomAttributes
- {
- get
- {
- return GetCustomAttributesData();
- }
- }
- public abstract Object[] GetCustomAttributes(bool inherit);
-
- public abstract Object[] GetCustomAttributes(Type attributeType, bool inherit);
-
- public abstract bool IsDefined(Type attributeType, bool inherit);
-
- public virtual IList<CustomAttributeData> GetCustomAttributesData()
- {
- throw new NotImplementedException();
- }
-
- public virtual int MetadataToken { get { throw new InvalidOperationException(); } }
-
- public virtual Module Module
- {
- get
- {
- if (this is Type)
- return ((Type)this).Module;
-
- throw new NotImplementedException();
- }
- }
-
-
-
- #endregion
-
- public static bool operator ==(MemberInfo left, MemberInfo right)
- {
- if (ReferenceEquals(left, right))
- return true;
-
- if ((object)left == null || (object)right == null)
- return false;
-
- Type type1, type2;
- MethodBase method1, method2;
- FieldInfo field1, field2;
- EventInfo event1, event2;
- PropertyInfo property1, property2;
-
- if ((type1 = left as Type) != null && (type2 = right as Type) != null)
- return type1 == type2;
- else if ((method1 = left as MethodBase) != null && (method2 = right as MethodBase) != null)
- return method1 == method2;
- else if ((field1 = left as FieldInfo) != null && (field2 = right as FieldInfo) != null)
- return field1 == field2;
- else if ((event1 = left as EventInfo) != null && (event2 = right as EventInfo) != null)
- return event1 == event2;
- else if ((property1 = left as PropertyInfo) != null && (property2 = right as PropertyInfo) != null)
- return property1 == property2;
-
- return false;
- }
-
- public static bool operator !=(MemberInfo left, MemberInfo right)
- {
- return !(left == right);
- }
-
- public override bool Equals(object obj)
- {
- return base.Equals(obj);
- }
-
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/MemberInfoSerializationHolder.cs b/src/mscorlib/src/System/Reflection/MemberInfoSerializationHolder.cs
deleted file mode 100644
index 20ff37650c..0000000000
--- a/src/mscorlib/src/System/Reflection/MemberInfoSerializationHolder.cs
+++ /dev/null
@@ -1,285 +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.Remoting;
-using System.Runtime.Serialization;
-using System.Globalization;
-using System.Diagnostics.Contracts;
-
-namespace System.Reflection
-{
- [Serializable]
- internal class MemberInfoSerializationHolder : ISerializable, IObjectReference
- {
- #region Staitc Public Members
- public static void GetSerializationInfo(SerializationInfo info, String name, RuntimeType reflectedClass, String signature, MemberTypes type)
- {
- GetSerializationInfo(info, name, reflectedClass, signature, null, type, null);
- }
-
- public static void GetSerializationInfo(
- SerializationInfo info,
- String name,
- RuntimeType reflectedClass,
- String signature,
- String signature2,
- MemberTypes type,
- Type[] genericArguments)
- {
- if (info == null)
- throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- String assemblyName = reflectedClass.Module.Assembly.FullName;
- String typeName = reflectedClass.FullName;
-
- info.SetType(typeof(MemberInfoSerializationHolder));
- info.AddValue("Name", name, typeof(String));
- info.AddValue("AssemblyName", assemblyName, typeof(String));
- info.AddValue("ClassName", typeName, typeof(String));
- info.AddValue("Signature", signature, typeof(String));
- info.AddValue("Signature2", signature2, typeof(String));
- info.AddValue("MemberType", (int)type);
- info.AddValue("GenericArguments", genericArguments, typeof(Type[]));
- }
- #endregion
-
- #region Private Data Members
- private String m_memberName;
- private RuntimeType m_reflectedType;
- // m_signature stores the ToString() representation of the member which is sometimes ambiguous.
- // Mulitple overloads of the same methods or properties can identical ToString().
- // m_signature2 stores the SerializationToString() representation which should be unique for each member.
- // It is only written and used by post 4.0 CLR versions.
- private String m_signature;
- private String m_signature2;
- private MemberTypes m_memberType;
- private SerializationInfo m_info;
- #endregion
-
- #region Constructor
- internal MemberInfoSerializationHolder(SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- String assemblyName = info.GetString("AssemblyName");
- String typeName = info.GetString("ClassName");
-
- if (assemblyName == null || typeName == null)
- throw new SerializationException(Environment.GetResourceString("Serialization_InsufficientState"));
-
- Assembly assem = FormatterServices.LoadAssemblyFromString(assemblyName);
- m_reflectedType = assem.GetType(typeName, true, false) as RuntimeType;
- m_memberName = info.GetString("Name");
- m_signature = info.GetString("Signature");
- // Only v4.0 and later generates and consumes Signature2
- m_signature2 = (string)info.GetValueNoThrow("Signature2", typeof(string));
- m_memberType = (MemberTypes)info.GetInt32("MemberType");
- m_info = info;
- }
- #endregion
-
- #region ISerializable
- public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- throw new NotSupportedException(Environment.GetResourceString(ResId.NotSupported_Method));
- }
- #endregion
-
- #region IObjectReference
- public virtual Object GetRealObject(StreamingContext context)
- {
- if (m_memberName == null || m_reflectedType == null || m_memberType == 0)
- throw new SerializationException(Environment.GetResourceString(ResId.Serialization_InsufficientState));
-
- BindingFlags bindingFlags =
- BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic |
- BindingFlags.Static | BindingFlags.OptionalParamBinding;
-
- switch (m_memberType)
- {
- #region case MemberTypes.Field:
- case MemberTypes.Field:
- {
- FieldInfo[] fields = m_reflectedType.GetMember(m_memberName, MemberTypes.Field, bindingFlags) as FieldInfo[];
-
- if (fields.Length == 0)
- throw new SerializationException(Environment.GetResourceString("Serialization_UnknownMember", m_memberName));
-
- return fields[0];
- }
- #endregion
-
- #region case MemberTypes.Event:
- case MemberTypes.Event:
- {
- EventInfo[] events = m_reflectedType.GetMember(m_memberName, MemberTypes.Event, bindingFlags) as EventInfo[];
-
- if (events.Length == 0)
- throw new SerializationException(Environment.GetResourceString("Serialization_UnknownMember", m_memberName));
-
- return events[0];
- }
- #endregion
-
- #region case MemberTypes.Property:
- case MemberTypes.Property:
- {
- PropertyInfo[] properties = m_reflectedType.GetMember(m_memberName, MemberTypes.Property, bindingFlags) as PropertyInfo[];
-
- if (properties.Length == 0)
- throw new SerializationException(Environment.GetResourceString("Serialization_UnknownMember", m_memberName));
-
- if (properties.Length == 1)
- return properties[0];
-
- if (properties.Length > 1)
- {
- for (int i = 0; i < properties.Length; i++)
- {
- if (m_signature2 != null)
- {
- if (((RuntimePropertyInfo)properties[i]).SerializationToString().Equals(m_signature2))
- return properties[i];
- }
- else
- {
- if ((properties[i]).ToString().Equals(m_signature))
- return properties[i];
- }
- }
- }
-
- throw new SerializationException(Environment.GetResourceString(ResId.Serialization_UnknownMember, m_memberName));
- }
- #endregion
-
- #region case MemberTypes.Constructor:
- case MemberTypes.Constructor:
- {
- if (m_signature == null)
- throw new SerializationException(Environment.GetResourceString(ResId.Serialization_NullSignature));
-
- ConstructorInfo[] constructors = m_reflectedType.GetMember(m_memberName, MemberTypes.Constructor, bindingFlags) as ConstructorInfo[];
-
- if (constructors.Length == 1)
- return constructors[0];
-
- if (constructors.Length > 1)
- {
- for (int i = 0; i < constructors.Length; i++)
- {
- if (m_signature2 != null)
- {
- if (((RuntimeConstructorInfo)constructors[i]).SerializationToString().Equals(m_signature2))
- return constructors[i];
- }
- else
- {
- if (constructors[i].ToString().Equals(m_signature))
- return constructors[i];
- }
- }
- }
-
- throw new SerializationException(Environment.GetResourceString(ResId.Serialization_UnknownMember, m_memberName));
- }
- #endregion
-
- #region case MemberTypes.Method:
- case MemberTypes.Method:
- {
- MethodInfo methodInfo = null;
-
- if (m_signature == null)
- throw new SerializationException(Environment.GetResourceString(ResId.Serialization_NullSignature));
-
- Type[] genericArguments = m_info.GetValueNoThrow("GenericArguments", typeof(Type[])) as Type[];
-
- MethodInfo[] methods = m_reflectedType.GetMember(m_memberName, MemberTypes.Method, bindingFlags) as MethodInfo[];
-
- if (methods.Length == 1)
- methodInfo = methods[0];
-
- else if (methods.Length > 1)
- {
- for (int i = 0; i < methods.Length; i++)
- {
- if (m_signature2 != null)
- {
- if (((RuntimeMethodInfo)methods[i]).SerializationToString().Equals(m_signature2))
- {
- methodInfo = methods[i];
- break;
- }
- }
- else
- {
-
- if (methods[i].ToString().Equals(m_signature))
- {
- methodInfo = methods[i];
- break;
- }
- }
-
- // Handle generic methods specially since the signature match above probably won't work (the candidate
- // method info hasn't been instantiated). If our target method is generic as well we can skip this.
- if (genericArguments != null && methods[i].IsGenericMethod)
- {
- if (methods[i].GetGenericArguments().Length == genericArguments.Length)
- {
- MethodInfo candidateMethod = methods[i].MakeGenericMethod(genericArguments);
-
- if (m_signature2 != null)
- {
- if (((RuntimeMethodInfo)candidateMethod).SerializationToString().Equals(m_signature2))
- {
- methodInfo = candidateMethod;
- break;
- }
- }
- else
- {
- if (candidateMethod.ToString().Equals(m_signature))
- {
- methodInfo = candidateMethod;
- break;
- }
- }
- }
- }
- }
- }
-
- if (methodInfo == null)
- throw new SerializationException(Environment.GetResourceString(ResId.Serialization_UnknownMember, m_memberName));
-
- if (!methodInfo.IsGenericMethodDefinition)
- return methodInfo;
-
- if (genericArguments == null)
- return methodInfo;
-
- if (genericArguments[0] == null)
- return null;
-
- return methodInfo.MakeGenericMethod(genericArguments);
- }
- #endregion
-
- default:
- throw new ArgumentException(Environment.GetResourceString("Serialization_MemberTypeNotRecognized"));
- }
- }
- #endregion
- }
-
-
-}
diff --git a/src/mscorlib/src/System/Reflection/MemberSerializationStringGenerator.cs b/src/mscorlib/src/System/Reflection/MemberSerializationStringGenerator.cs
new file mode 100644
index 0000000000..d25c746a85
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/MemberSerializationStringGenerator.cs
@@ -0,0 +1,39 @@
+// 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.Text;
+using System.Reflection;
+using System.Diagnostics;
+using System.Collections.Generic;
+
+namespace System
+{
+ internal static class MemberSerializationStringGenerator
+ {
+ //
+ // Generate the "Signature2" binary serialization string for PropertyInfos
+ //
+ // Because the string is effectively a file format for serialized Reflection objects, it must be exactly correct. If missing
+ // metadata prevents generating the string, this method throws a MissingMetadata exception.
+ //
+ public static string SerializationToString(this PropertyInfo property) => ((RuntimePropertyInfo)property).SerializationToString();
+
+ //
+ // Generate the "Signature2" binary serialization string for ConstructorInfos
+ //
+ // Because the string is effectively a file format for serialized Reflection objects, it must be exactly correct. If missing
+ // metadata prevents generating the string, this method throws a MissingMetadata exception.
+ //
+ public static string SerializationToString(this ConstructorInfo constructor) => ((RuntimeConstructorInfo)constructor).SerializationToString();
+
+ //
+ // Generate the "Signature2" binary serialization string for MethodInfos
+ //
+ // Because the string is effectively a file format for serialized Reflection objects, it must be exactly correct. If missing
+ // metadata prevents generating the string, this method throws a MissingMetadata exception.
+ //
+ public static string SerializationToString(this MethodInfo method) => ((RuntimeMethodInfo)method).SerializationToString();
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/MemberTypes.cs b/src/mscorlib/src/System/Reflection/MemberTypes.cs
deleted file mode 100644
index 95c41022f1..0000000000
--- a/src/mscorlib/src/System/Reflection/MemberTypes.cs
+++ /dev/null
@@ -1,33 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// MemberTypes is an bit mask marking each type of Member that is defined as
-//
-// a subclass of MemberInfo. These are returned by MemberInfo.MemberType and
-// are useful in switch statements.
-//
-//
-namespace System.Reflection {
-
- using System;
- // This Enum matchs the CorTypeAttr defined in CorHdr.h
- [Serializable]
- [Flags()]
- public enum MemberTypes
- {
- // The following are the known classes which extend MemberInfo
- Constructor = 0x01,
- Event = 0x02,
- Field = 0x04,
- Method = 0x08,
- Property = 0x10,
- TypeInfo = 0x20,
- Custom = 0x40,
- NestedType = 0x80,
- All = Constructor | Event | Field | Method | Property | TypeInfo | NestedType,
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/MethodAttributes.cs b/src/mscorlib/src/System/Reflection/MethodAttributes.cs
deleted file mode 100644
index 7e4391cccd..0000000000
--- a/src/mscorlib/src/System/Reflection/MethodAttributes.cs
+++ /dev/null
@@ -1,55 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-//
-
-namespace System.Reflection
-{
- using System;
- [Serializable]
- [Flags]
- public enum MethodAttributes
- {
- // NOTE: This Enum matchs the CorMethodAttr defined in CorHdr.h
-
- // member access mask - Use this mask to retrieve accessibility information.
- MemberAccessMask = 0x0007,
- PrivateScope = 0x0000, // Member not referenceable.
- Private = 0x0001, // Accessible only by the parent type.
- FamANDAssem = 0x0002, // Accessible by sub-types only in this Assembly.
- Assembly = 0x0003, // Accessibly by anyone in the Assembly.
- Family = 0x0004, // Accessible only by type and sub-types.
- FamORAssem = 0x0005, // Accessibly by sub-types anywhere, plus anyone in assembly.
- Public = 0x0006, // Accessibly by anyone who has visibility to this scope.
- // end member access mask
-
- // method contract attributes.
- Static = 0x0010, // Defined on type, else per instance.
- Final = 0x0020, // Method may not be overridden.
- Virtual = 0x0040, // Method virtual.
- HideBySig = 0x0080, // Method hides by name+sig, else just by name.
- CheckAccessOnOverride= 0x0200,
-
- // vtable layout mask - Use this mask to retrieve vtable attributes.
- VtableLayoutMask = 0x0100,
- ReuseSlot = 0x0000, // The default.
- NewSlot = 0x0100, // Method always gets a new slot in the vtable.
- // end vtable layout mask
-
- // method implementation attributes.
- Abstract = 0x0400, // Method does not provide an implementation.
- SpecialName = 0x0800, // Method is special. Name describes how.
-
- // interop attributes
- PinvokeImpl = 0x2000, // Implementation is forwarded through pinvoke.
- UnmanagedExport = 0x0008, // Managed method exported via thunk to unmanaged code.
- RTSpecialName = 0x1000, // Runtime should check name encoding.
-
- // Reserved flags for runtime use only.
- ReservedMask = 0xd000,
- HasSecurity = 0x4000, // Method has security associate with it.
- RequireSecObject = 0x8000, // Method calls another method containing security code.
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/MethodBase.CoreCLR.cs b/src/mscorlib/src/System/Reflection/MethodBase.CoreCLR.cs
new file mode 100644
index 0000000000..3afd396471
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/MethodBase.CoreCLR.cs
@@ -0,0 +1,157 @@
+// 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.Diagnostics;
+using System.Globalization;
+using System.Text;
+using System.Threading;
+
+namespace System.Reflection
+{
+ public abstract partial class MethodBase : MemberInfo
+ {
+ #region Static Members
+ public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle)
+ {
+ if (handle.IsNullHandle())
+ throw new ArgumentException(SR.Argument_InvalidHandle);
+
+ MethodBase m = RuntimeType.GetMethodBase(handle.GetMethodInfo());
+
+ Type declaringType = m.DeclaringType;
+ if (declaringType != null && declaringType.IsGenericType)
+ throw new ArgumentException(String.Format(
+ CultureInfo.CurrentCulture, SR.Argument_MethodDeclaringTypeGeneric,
+ m, declaringType.GetGenericTypeDefinition()));
+
+ return m;
+ }
+
+ public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle, RuntimeTypeHandle declaringType)
+ {
+ if (handle.IsNullHandle())
+ throw new ArgumentException(SR.Argument_InvalidHandle);
+
+ return RuntimeType.GetMethodBase(declaringType.GetRuntimeType(), handle.GetMethodInfo());
+ }
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public static MethodBase GetCurrentMethod()
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return RuntimeMethodInfo.InternalGetCurrentMethod(ref stackMark);
+ }
+ #endregion
+
+ #region Internal Members
+ // used by EE
+ private IntPtr GetMethodDesc() { return MethodHandle.Value; }
+
+ internal virtual ParameterInfo[] GetParametersNoCopy() { return GetParameters(); }
+ #endregion
+
+ #region Internal Methods
+ // helper method to construct the string representation of the parameter list
+
+ internal static string ConstructParameters(Type[] parameterTypes, CallingConventions callingConvention, bool serialization)
+ {
+ StringBuilder sbParamList = new StringBuilder();
+ string comma = "";
+
+ for (int i = 0; i < parameterTypes.Length; i++)
+ {
+ Type t = parameterTypes[i];
+
+ sbParamList.Append(comma);
+
+ string typeName = t.FormatTypeName(serialization);
+
+ // Legacy: Why use "ByRef" for by ref parameters? What language is this?
+ // VB uses "ByRef" but it should precede (not follow) the parameter name.
+ // Why don't we just use "&"?
+ if (t.IsByRef && !serialization)
+ {
+ sbParamList.Append(typeName.TrimEnd('&'));
+ sbParamList.Append(" ByRef");
+ }
+ else
+ {
+ sbParamList.Append(typeName);
+ }
+
+ comma = ", ";
+ }
+
+ if ((callingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs)
+ {
+ sbParamList.Append(comma);
+ sbParamList.Append("...");
+ }
+
+ return sbParamList.ToString();
+ }
+
+ internal string FullName
+ {
+ get
+ {
+ return String.Format("{0}.{1}", DeclaringType.FullName, FormatNameAndSig());
+ }
+ }
+ internal string FormatNameAndSig()
+ {
+ return FormatNameAndSig(false);
+ }
+
+ internal virtual string FormatNameAndSig(bool serialization)
+ {
+ // Serialization uses ToString to resolve MethodInfo overloads.
+ StringBuilder sbName = new StringBuilder(Name);
+
+ sbName.Append("(");
+ sbName.Append(ConstructParameters(GetParameterTypes(), CallingConvention, serialization));
+ sbName.Append(")");
+
+ return sbName.ToString();
+ }
+
+ internal virtual Type[] GetParameterTypes()
+ {
+ ParameterInfo[] paramInfo = GetParametersNoCopy();
+
+ Type[] parameterTypes = new Type[paramInfo.Length];
+ for (int i = 0; i < paramInfo.Length; i++)
+ parameterTypes[i] = paramInfo[i].ParameterType;
+
+ return parameterTypes;
+ }
+
+ internal Object[] CheckArguments(Object[] parameters, Binder binder,
+ BindingFlags invokeAttr, CultureInfo culture, Signature sig)
+ {
+ // copy the arguments in a different array so we detach from any user changes
+ Object[] copyOfParameters = new Object[parameters.Length];
+
+ ParameterInfo[] p = null;
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ Object arg = parameters[i];
+ RuntimeType argRT = sig.Arguments[i];
+
+ if (arg == Type.Missing)
+ {
+ if (p == null)
+ p = GetParametersNoCopy();
+ if (p[i].DefaultValue == System.DBNull.Value)
+ throw new ArgumentException(SR.Arg_VarMissNull, nameof(parameters));
+ arg = p[i].DefaultValue;
+ }
+ copyOfParameters[i] = argRT.CheckValue(arg, binder, culture, invokeAttr);
+ }
+
+ return copyOfParameters;
+ }
+ #endregion
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/MethodBase.cs b/src/mscorlib/src/System/Reflection/MethodBase.cs
deleted file mode 100644
index 3109821ac9..0000000000
--- a/src/mscorlib/src/System/Reflection/MethodBase.cs
+++ /dev/null
@@ -1,330 +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.
-
-//
-
-namespace System.Reflection
-{
- using System;
- using System.Diagnostics;
- using System.Globalization;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading;
-
- //
- // Invocation cached flags. Those are used in unmanaged code as well
- // so be careful if you change them
- //
- [Flags]
- internal enum INVOCATION_FLAGS : uint
- {
- INVOCATION_FLAGS_UNKNOWN = 0x00000000,
- INVOCATION_FLAGS_INITIALIZED = 0x00000001,
- // it's used for both method and field to signify that no access is allowed
- INVOCATION_FLAGS_NO_INVOKE = 0x00000002,
- INVOCATION_FLAGS_NEED_SECURITY = 0x00000004,
- // Set for static ctors and ctors on abstract types, which
- // can be invoked only if the "this" object is provided (even if it's null).
- INVOCATION_FLAGS_NO_CTOR_INVOKE = 0x00000008,
- // because field and method are different we can reuse the same bits
- // method
- INVOCATION_FLAGS_IS_CTOR = 0x00000010,
- INVOCATION_FLAGS_RISKY_METHOD = 0x00000020,
- INVOCATION_FLAGS_NON_W8P_FX_API = 0x00000040,
- INVOCATION_FLAGS_IS_DELEGATE_CTOR = 0x00000080,
- INVOCATION_FLAGS_CONTAINS_STACK_POINTERS = 0x00000100,
- // field
- INVOCATION_FLAGS_SPECIAL_FIELD = 0x00000010,
- INVOCATION_FLAGS_FIELD_SPECIAL_CAST = 0x00000020,
-
- // temporary flag used for flagging invocation of method vs ctor
- // this flag never appears on the instance m_invocationFlag and is simply
- // passed down from within ConstructorInfo.Invoke()
- INVOCATION_FLAGS_CONSTRUCTOR_INVOKE = 0x10000000,
- }
-
- [Serializable]
- public abstract class MethodBase : MemberInfo
- {
- #region Static Members
- public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle)
- {
- if (handle.IsNullHandle())
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHandle"));
-
- MethodBase m = RuntimeType.GetMethodBase(handle.GetMethodInfo());
-
- Type declaringType = m.DeclaringType;
- if (declaringType != null && declaringType.IsGenericType)
- throw new ArgumentException(String.Format(
- CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_MethodDeclaringTypeGeneric"),
- m, declaringType.GetGenericTypeDefinition()));
-
- return m;
- }
-
- public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle, RuntimeTypeHandle declaringType)
- {
- if (handle.IsNullHandle())
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHandle"));
-
- return RuntimeType.GetMethodBase(declaringType.GetRuntimeType(), handle.GetMethodInfo());
- }
-
- [System.Security.DynamicSecurityMethod] // Specify DynamicSecurityMethod attribute to prevent inlining of the caller.
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static MethodBase GetCurrentMethod()
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RuntimeMethodInfo.InternalGetCurrentMethod(ref stackMark);
- }
- #endregion
-
- #region Constructor
- protected MethodBase() { }
- #endregion
-
- public static bool operator ==(MethodBase left, MethodBase right)
- {
- if (ReferenceEquals(left, right))
- return true;
-
- if ((object)left == null || (object)right == null)
- return false;
-
- MethodInfo method1, method2;
- ConstructorInfo constructor1, constructor2;
-
- if ((method1 = left as MethodInfo) != null && (method2 = right as MethodInfo) != null)
- return method1 == method2;
- else if ((constructor1 = left as ConstructorInfo) != null && (constructor2 = right as ConstructorInfo) != null)
- return constructor1 == constructor2;
-
- return false;
- }
-
- public static bool operator !=(MethodBase left, MethodBase right)
- {
- return !(left == right);
- }
-
- public override bool Equals(object obj)
- {
- return base.Equals(obj);
- }
-
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
-
- #region Internal Members
- // used by EE
- private IntPtr GetMethodDesc() { return MethodHandle.Value; }
-
-#if FEATURE_APPX
-#endif
- #endregion
-
- #region Public Abstract\Virtual Members
- internal virtual ParameterInfo[] GetParametersNoCopy() { return GetParameters (); }
-
- [System.Diagnostics.Contracts.Pure]
- public abstract ParameterInfo[] GetParameters();
-
- public virtual MethodImplAttributes MethodImplementationFlags
- {
- get
- {
- return GetMethodImplementationFlags();
- }
- }
-
- public abstract MethodImplAttributes GetMethodImplementationFlags();
-
- public abstract RuntimeMethodHandle MethodHandle { get; }
-
- public abstract MethodAttributes Attributes { get; }
-
- public abstract Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture);
-
- public virtual CallingConventions CallingConvention { get { return CallingConventions.Standard; } }
-
- public virtual Type[] GetGenericArguments() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
-
- public virtual bool IsGenericMethodDefinition { get { return false; } }
-
- public virtual bool ContainsGenericParameters { get { return false; } }
-
- public virtual bool IsGenericMethod { get { return false; } }
-
- public virtual bool IsSecurityCritical { get { throw new NotImplementedException(); } }
-
- public virtual bool IsSecuritySafeCritical { get { throw new NotImplementedException(); } }
-
- public virtual bool IsSecurityTransparent { get { throw new NotImplementedException(); } }
-
- #endregion
-
- #region Public Members
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public Object Invoke(Object obj, Object[] parameters)
- {
- // Theoretically we should set up a LookForMyCaller stack mark here and pass that along.
- // But to maintain backward compatibility we can't switch to calling an
- // internal overload that takes a stack mark.
- // Fortunately the stack walker skips all the reflection invocation frames including this one.
- // So this method will never be returned by the stack walker as the caller.
- // See SystemDomain::CallersMethodCallbackWithStackMark in AppDomain.cpp.
- return Invoke(obj, BindingFlags.Default, null, parameters, null);
- }
-
- public bool IsPublic { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public; } }
-
- public bool IsPrivate { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private; } }
-
- public bool IsFamily { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family; } }
-
- public bool IsAssembly { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly; } }
-
- public bool IsFamilyAndAssembly { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem; } }
-
- public bool IsFamilyOrAssembly { get {return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem; } }
-
- public bool IsStatic { get { return(Attributes & MethodAttributes.Static) != 0; } }
-
- public bool IsFinal { get { return(Attributes & MethodAttributes.Final) != 0; }
- }
- public bool IsVirtual { get { return(Attributes & MethodAttributes.Virtual) != 0; }
- }
- public bool IsHideBySig { get { return(Attributes & MethodAttributes.HideBySig) != 0; } }
-
- public bool IsAbstract { get { return(Attributes & MethodAttributes.Abstract) != 0; } }
-
- public bool IsSpecialName { get { return(Attributes & MethodAttributes.SpecialName) != 0; } }
-
- public bool IsConstructor
- {
- get
- {
- // To be backward compatible we only return true for instance RTSpecialName ctors.
- return (this is ConstructorInfo &&
- !IsStatic &&
- ((Attributes & MethodAttributes.RTSpecialName) == MethodAttributes.RTSpecialName));
- }
- }
-
- public virtual MethodBody GetMethodBody()
- {
- throw new InvalidOperationException();
- }
- #endregion
-
- #region Internal Methods
- // helper method to construct the string representation of the parameter list
-
- internal static string ConstructParameters(Type[] parameterTypes, CallingConventions callingConvention, bool serialization)
- {
- StringBuilder sbParamList = new StringBuilder();
- string comma = "";
-
- for (int i = 0; i < parameterTypes.Length; i++)
- {
- Type t = parameterTypes[i];
-
- sbParamList.Append(comma);
-
- string typeName = t.FormatTypeName(serialization);
-
- // Legacy: Why use "ByRef" for by ref parameters? What language is this?
- // VB uses "ByRef" but it should precede (not follow) the parameter name.
- // Why don't we just use "&"?
- if (t.IsByRef && !serialization)
- {
- sbParamList.Append(typeName.TrimEnd('&'));
- sbParamList.Append(" ByRef");
- }
- else
- {
- sbParamList.Append(typeName);
- }
-
- comma = ", ";
- }
-
- if ((callingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs)
- {
- sbParamList.Append(comma);
- sbParamList.Append("...");
- }
-
- return sbParamList.ToString();
- }
-
- internal string FullName
- {
- get
- {
- return String.Format("{0}.{1}", DeclaringType.FullName, FormatNameAndSig());
- }
- }
- internal string FormatNameAndSig()
- {
- return FormatNameAndSig(false);
- }
-
- internal virtual string FormatNameAndSig(bool serialization)
- {
- // Serialization uses ToString to resolve MethodInfo overloads.
- StringBuilder sbName = new StringBuilder(Name);
-
- sbName.Append("(");
- sbName.Append(ConstructParameters(GetParameterTypes(), CallingConvention, serialization));
- sbName.Append(")");
-
- return sbName.ToString();
- }
-
- internal virtual Type[] GetParameterTypes()
- {
- ParameterInfo[] paramInfo = GetParametersNoCopy();
-
- Type[] parameterTypes = new Type[paramInfo.Length];
- for (int i = 0; i < paramInfo.Length; i++)
- parameterTypes[i] = paramInfo[i].ParameterType;
-
- return parameterTypes;
- }
-
- internal Object[] CheckArguments(Object[] parameters, Binder binder,
- BindingFlags invokeAttr, CultureInfo culture, Signature sig)
- {
- // copy the arguments in a different array so we detach from any user changes
- Object[] copyOfParameters = new Object[parameters.Length];
-
- ParameterInfo[] p = null;
- for (int i = 0; i < parameters.Length; i++)
- {
- Object arg = parameters[i];
- RuntimeType argRT = sig.Arguments[i];
-
- if (arg == Type.Missing)
- {
- if (p == null)
- p = GetParametersNoCopy();
- if (p[i].DefaultValue == System.DBNull.Value)
- throw new ArgumentException(Environment.GetResourceString("Arg_VarMissNull"),nameof(parameters));
- arg = p[i].DefaultValue;
- }
- copyOfParameters[i] = argRT.CheckValue(arg, binder, culture, invokeAttr);
- }
-
- return copyOfParameters;
- }
- #endregion
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/MethodBody.cs b/src/mscorlib/src/System/Reflection/MethodBody.cs
index 7cbaeaf9b9..4335177efb 100644
--- a/src/mscorlib/src/System/Reflection/MethodBody.cs
+++ b/src/mscorlib/src/System/Reflection/MethodBody.cs
@@ -2,116 +2,17 @@
// 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.Globalization;
using System.Collections.Generic;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
namespace System.Reflection
-{
- [Flags()]
- public enum ExceptionHandlingClauseOptions: int
- {
- Clause = 0x0,
- Filter = 0x1,
- Finally = 0x2,
- Fault = 0x4,
- }
-
- public class ExceptionHandlingClause
- {
- #region costructor
- // This class can only be created from inside the EE.
- protected ExceptionHandlingClause() { }
- #endregion
-
- #region Private Data Members
- private MethodBody m_methodBody;
- [ContractPublicPropertyName("Flags")]
- private ExceptionHandlingClauseOptions m_flags;
- private int m_tryOffset;
- private int m_tryLength;
- private int m_handlerOffset;
- private int m_handlerLength;
- private int m_catchMetadataToken;
- private int m_filterOffset;
- #endregion
-
- #region Public Members
- public virtual ExceptionHandlingClauseOptions Flags { get { return m_flags; } }
- public virtual int TryOffset { get { return m_tryOffset; } }
- public virtual int TryLength { get { return m_tryLength; } }
- public virtual int HandlerOffset { get { return m_handlerOffset; } }
- public virtual int HandlerLength { get { return m_handlerLength; } }
-
- public virtual int FilterOffset
- {
- get
- {
- if (m_flags != ExceptionHandlingClauseOptions.Filter)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_EHClauseNotFilter"));
-
- return m_filterOffset;
- }
- }
-
- public virtual Type CatchType
- {
- get
- {
- if (m_flags != ExceptionHandlingClauseOptions.Clause)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_EHClauseNotClause"));
-
- Type type = null;
-
- if (!MetadataToken.IsNullToken(m_catchMetadataToken))
- {
- Type declaringType = m_methodBody.m_methodBase.DeclaringType;
- Module module = (declaringType == null) ? m_methodBody.m_methodBase.Module : declaringType.Module;
- type = module.ResolveType(m_catchMetadataToken, (declaringType == null) ? null : declaringType.GetGenericArguments(),
- m_methodBody.m_methodBase is MethodInfo ? m_methodBody.m_methodBase.GetGenericArguments() : null);
- }
-
- return type;
- }
- }
- #endregion
-
- #region Object Overrides
- public override string ToString()
- {
- if (Flags == ExceptionHandlingClauseOptions.Clause)
- {
- return String.Format(CultureInfo.CurrentUICulture,
- "Flags={0}, TryOffset={1}, TryLength={2}, HandlerOffset={3}, HandlerLength={4}, CatchType={5}",
- Flags, TryOffset, TryLength, HandlerOffset, HandlerLength, CatchType);
- }
-
- if (Flags == ExceptionHandlingClauseOptions.Filter)
- {
- return String.Format(CultureInfo.CurrentUICulture,
- "Flags={0}, TryOffset={1}, TryLength={2}, HandlerOffset={3}, HandlerLength={4}, FilterOffset={5}",
- Flags, TryOffset, TryLength, HandlerOffset, HandlerLength, FilterOffset);
- }
-
- return String.Format(CultureInfo.CurrentUICulture,
- "Flags={0}, TryOffset={1}, TryLength={2}, HandlerOffset={3}, HandlerLength={4}",
- Flags, TryOffset, TryLength, HandlerOffset, HandlerLength);
-
- }
- #endregion
- }
-
+{
public class MethodBody
{
#region costructor
// This class can only be created from inside the EE.
protected MethodBody() { }
#endregion
-
+
#region Private Data Members
private byte[] m_IL;
private ExceptionHandlingClause[] m_exceptionHandlingClauses;
@@ -119,7 +20,7 @@ namespace System.Reflection
internal MethodBase m_methodBase;
private int m_localSignatureMetadataToken;
private int m_maxStackSize;
- private bool m_initLocals;
+ private bool m_initLocals;
#endregion
#region Public Members
@@ -130,37 +31,6 @@ namespace System.Reflection
public virtual byte[] GetILAsByteArray() { return m_IL; }
public virtual IList<ExceptionHandlingClause> ExceptionHandlingClauses { get { return Array.AsReadOnly(m_exceptionHandlingClauses); } }
#endregion
- }
-
- public class LocalVariableInfo
- {
- #region Private Data Members
- private RuntimeType m_type;
- private int m_isPinned;
- private int m_localIndex;
- #endregion
-
- #region Constructor
- protected LocalVariableInfo() { }
- #endregion
-
- #region Object Overrides
- public override string ToString()
- {
- string toString = LocalType.ToString() + " (" + LocalIndex + ")";
-
- if (IsPinned)
- toString += " (pinned)";
-
- return toString;
- }
- #endregion
-
- #region Public Members
- public virtual Type LocalType { get { Debug.Assert(m_type != null, "type must be set!"); return m_type; } }
- public virtual bool IsPinned { get { return m_isPinned != 0; } }
- public virtual int LocalIndex { get { return m_localIndex; } }
- #endregion
}
}
diff --git a/src/mscorlib/src/System/Reflection/MethodImplAttributes.cs b/src/mscorlib/src/System/Reflection/MethodImplAttributes.cs
deleted file mode 100644
index 1bd6b9dbd1..0000000000
--- a/src/mscorlib/src/System/Reflection/MethodImplAttributes.cs
+++ /dev/null
@@ -1,43 +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.
-
-//
-
-namespace System.Reflection
-{
-
- using System;
- // This Enum matchs the CorMethodImpl defined in CorHdr.h
- [Serializable]
- public enum MethodImplAttributes
- {
- // code impl mask
- CodeTypeMask = 0x0003, // Flags about code type.
- IL = 0x0000, // Method impl is IL.
- Native = 0x0001, // Method impl is native.
- /// <internalonly/>
- OPTIL = 0x0002, // Method impl is OPTIL
- Runtime = 0x0003, // Method impl is provided by the runtime.
- // end code impl mask
-
- // managed mask
- ManagedMask = 0x0004, // Flags specifying whether the code is managed or unmanaged.
- Unmanaged = 0x0004, // Method impl is unmanaged, otherwise managed.
- Managed = 0x0000, // Method impl is managed.
- // end managed mask
-
- // implementation info and interop
- ForwardRef = 0x0010, // Indicates method is not defined; used primarily in merge scenarios.
- PreserveSig = 0x0080, // Indicates method sig is exported exactly as declared.
-
- InternalCall = 0x1000, // Internal Call...
-
- Synchronized = 0x0020, // Method is single threaded through the body.
- NoInlining = 0x0008, // Method may not be inlined.
- AggressiveInlining = 0x0100, // Method should be inlined if possible.
- NoOptimization = 0x0040, // Method may not be optimized.
-
- MaxMethodImplVal = 0xFFFF, // Range check value
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/MethodInfo.cs b/src/mscorlib/src/System/Reflection/MethodInfo.cs
deleted file mode 100644
index 5ce124614c..0000000000
--- a/src/mscorlib/src/System/Reflection/MethodInfo.cs
+++ /dev/null
@@ -1,926 +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.
-
-//
-
-namespace System.Reflection
-{
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- using System.Runtime;
- using System.Runtime.InteropServices;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.Serialization;
- using System.Security;
- using System.Text;
- using System.Threading;
- using MemberListType = System.RuntimeType.MemberListType;
- using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
- using System.Runtime.CompilerServices;
-
- [Serializable]
- public abstract class MethodInfo : MethodBase
- {
- #region Constructor
- protected MethodInfo() { }
- #endregion
-
- public static bool operator ==(MethodInfo left, MethodInfo right)
- {
- if (ReferenceEquals(left, right))
- return true;
-
- if ((object)left == null || (object)right == null ||
- left is RuntimeMethodInfo || right is RuntimeMethodInfo)
- {
- return false;
- }
- return left.Equals(right);
- }
-
- public static bool operator !=(MethodInfo left, MethodInfo right)
- {
- return !(left == right);
- }
-
- public override bool Equals(object obj)
- {
- return base.Equals(obj);
- }
-
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
-
- #region MemberInfo Overrides
- public override MemberTypes MemberType { get { return System.Reflection.MemberTypes.Method; } }
- #endregion
-
- #region Public Abstract\Virtual Members
- public virtual Type ReturnType { get { throw new NotImplementedException(); } }
-
- public virtual ParameterInfo ReturnParameter { get { throw new NotImplementedException(); } }
-
- public abstract ICustomAttributeProvider ReturnTypeCustomAttributes { get; }
-
- public abstract MethodInfo GetBaseDefinition();
-
- public override Type[] GetGenericArguments() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
-
- public virtual MethodInfo GetGenericMethodDefinition() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
-
- public virtual MethodInfo MakeGenericMethod(params Type[] typeArguments) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
-
- public virtual Delegate CreateDelegate(Type delegateType) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
- public virtual Delegate CreateDelegate(Type delegateType, Object target) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); }
- #endregion
- }
-
- [Serializable]
- internal sealed class RuntimeMethodInfo : MethodInfo, ISerializable, IRuntimeMethodInfo
- {
- #region Private Data Members
- private IntPtr m_handle;
- private RuntimeTypeCache m_reflectedTypeCache;
- private string m_name;
- private string m_toString;
- private ParameterInfo[] m_parameters;
- private ParameterInfo m_returnParameter;
- private BindingFlags m_bindingFlags;
- private MethodAttributes m_methodAttributes;
- private Signature m_signature;
- private RuntimeType m_declaringType;
- private object m_keepalive;
- private INVOCATION_FLAGS m_invocationFlags;
-
-#if FEATURE_APPX
- private bool IsNonW8PFrameworkAPI()
- {
- if (m_declaringType.IsArray && IsPublic && !IsStatic)
- return false;
-
- RuntimeAssembly rtAssembly = GetRuntimeAssembly();
- if (rtAssembly.IsFrameworkAssembly())
- {
- int ctorToken = rtAssembly.InvocableAttributeCtorToken;
- if (System.Reflection.MetadataToken.IsNullToken(ctorToken) ||
- !CustomAttribute.IsAttributeDefined(GetRuntimeModule(), MetadataToken, ctorToken))
- return true;
- }
-
- if (GetRuntimeType().IsNonW8PFrameworkAPI())
- return true;
-
- if (IsGenericMethod && !IsGenericMethodDefinition)
- {
- foreach (Type t in GetGenericArguments())
- {
- if (((RuntimeType)t).IsNonW8PFrameworkAPI())
- return true;
- }
- }
-
- return false;
- }
-#endif
-
- internal INVOCATION_FLAGS InvocationFlags
- {
- get
- {
- if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0)
- {
- INVOCATION_FLAGS invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_UNKNOWN;
-
- Type declaringType = DeclaringType;
-
- //
- // first take care of all the NO_INVOKE cases.
- if (ContainsGenericParameters ||
- ReturnType.IsByRef ||
- (declaringType != null && declaringType.ContainsGenericParameters) ||
- ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) ||
- ((Attributes & MethodAttributes.RequireSecObject) == MethodAttributes.RequireSecObject))
- {
- // We don't need other flags if this method cannot be invoked
- invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE;
- }
- else
- {
- // this should be an invocable method, determine the other flags that participate in invocation
- invocationFlags = RuntimeMethodHandle.GetSecurityFlags(this);
-
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) == 0)
- {
- if ( (Attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public ||
- (declaringType != null && declaringType.NeedsReflectionSecurityCheck) )
- {
- // If method is non-public, or declaring type is not visible
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
- }
- else if (IsGenericMethod)
- {
- Type[] genericArguments = GetGenericArguments();
-
- for (int i = 0; i < genericArguments.Length; i++)
- {
- if (genericArguments[i].NeedsReflectionSecurityCheck)
- {
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
- break;
- }
- }
- }
- }
- }
-
-#if FEATURE_APPX
- if (AppDomain.ProfileAPICheck && IsNonW8PFrameworkAPI())
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API;
-#endif // FEATURE_APPX
-
- m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED;
- }
-
- return m_invocationFlags;
- }
- }
- #endregion
-
- #region Constructor
- internal RuntimeMethodInfo(
- RuntimeMethodHandleInternal handle, RuntimeType declaringType,
- RuntimeTypeCache reflectedTypeCache, MethodAttributes methodAttributes, BindingFlags bindingFlags, object keepalive)
- {
- Contract.Ensures(!m_handle.IsNull());
-
- Debug.Assert(!handle.IsNullHandle());
- Debug.Assert(methodAttributes == RuntimeMethodHandle.GetAttributes(handle));
-
- m_bindingFlags = bindingFlags;
- m_declaringType = declaringType;
- m_keepalive = keepalive;
- m_handle = handle.Value;
- m_reflectedTypeCache = reflectedTypeCache;
- m_methodAttributes = methodAttributes;
- }
- #endregion
-
- #region Private Methods
- RuntimeMethodHandleInternal IRuntimeMethodInfo.Value
- {
- get
- {
- return new RuntimeMethodHandleInternal(m_handle);
- }
- }
-
- private RuntimeType ReflectedTypeInternal
- {
- get
- {
- return m_reflectedTypeCache.GetRuntimeType();
- }
- }
-
- private ParameterInfo[] FetchNonReturnParameters()
- {
- if (m_parameters == null)
- m_parameters = RuntimeParameterInfo.GetParameters(this, this, Signature);
-
- return m_parameters;
- }
-
- private ParameterInfo FetchReturnParameter()
- {
- if (m_returnParameter == null)
- m_returnParameter = RuntimeParameterInfo.GetReturnParameter(this, this, Signature);
-
- return m_returnParameter;
- }
- #endregion
-
- #region Internal Members
- internal override string FormatNameAndSig(bool serialization)
- {
- // Serialization uses ToString to resolve MethodInfo overloads.
- StringBuilder sbName = new StringBuilder(Name);
-
- // serialization == true: use unambiguous (except for assembly name) type names to distinguish between overloads.
- // serialization == false: use basic format to maintain backward compatibility of MethodInfo.ToString().
- TypeNameFormatFlags format = serialization ? TypeNameFormatFlags.FormatSerialization : TypeNameFormatFlags.FormatBasic;
-
- if (IsGenericMethod)
- sbName.Append(RuntimeMethodHandle.ConstructInstantiation(this, format));
-
- sbName.Append("(");
- sbName.Append(ConstructParameters(GetParameterTypes(), CallingConvention, serialization));
- sbName.Append(")");
-
- return sbName.ToString();
- }
-
- internal override bool CacheEquals(object o)
- {
- RuntimeMethodInfo m = o as RuntimeMethodInfo;
-
- if ((object)m == null)
- return false;
-
- return m.m_handle == m_handle;
- }
-
- internal Signature Signature
- {
- get
- {
- if (m_signature == null)
- m_signature = new Signature(this, m_declaringType);
-
- return m_signature;
- }
- }
-
- internal BindingFlags BindingFlags { get { return m_bindingFlags; } }
-
- internal RuntimeMethodInfo GetParentDefinition()
- {
- if (!IsVirtual || m_declaringType.IsInterface)
- return null;
-
- RuntimeType parent = (RuntimeType)m_declaringType.BaseType;
-
- if (parent == null)
- return null;
-
- int slot = RuntimeMethodHandle.GetSlot(this);
-
- if (RuntimeTypeHandle.GetNumVirtuals(parent) <= slot)
- return null;
-
- return (RuntimeMethodInfo)RuntimeType.GetMethodBase(parent, RuntimeTypeHandle.GetMethodAt(parent, slot));
- }
-
- // Unlike DeclaringType, this will return a valid type even for global methods
- internal RuntimeType GetDeclaringTypeInternal()
- {
- return m_declaringType;
- }
-
- #endregion
-
- #region Object Overrides
- public override String ToString()
- {
- if (m_toString == null)
- m_toString = ReturnType.FormatTypeName() + " " + FormatNameAndSig();
-
- return m_toString;
- }
-
- public override int GetHashCode()
- {
- // See RuntimeMethodInfo.Equals() below.
- if (IsGenericMethod)
- return ValueType.GetHashCodeOfPtr(m_handle);
- else
- return base.GetHashCode();
- }
-
- public override bool Equals(object obj)
- {
- if (!IsGenericMethod)
- return obj == (object)this;
-
- // We cannot do simple object identity comparisons for generic methods.
- // Equals will be called in CerHashTable when RuntimeType+RuntimeTypeCache.GetGenericMethodInfo()
- // retrieve items from and insert items into s_methodInstantiations which is a CerHashtable.
-
- RuntimeMethodInfo mi = obj as RuntimeMethodInfo;
-
- if (mi == null || !mi.IsGenericMethod)
- return false;
-
- // now we know that both operands are generic methods
-
- IRuntimeMethodInfo handle1 = RuntimeMethodHandle.StripMethodInstantiation(this);
- IRuntimeMethodInfo handle2 = RuntimeMethodHandle.StripMethodInstantiation(mi);
- if (handle1.Value.Value != handle2.Value.Value)
- return false;
-
- Type[] lhs = GetGenericArguments();
- Type[] rhs = mi.GetGenericArguments();
-
- if (lhs.Length != rhs.Length)
- return false;
-
- for (int i = 0; i < lhs.Length; i++)
- {
- if (lhs[i] != rhs[i])
- return false;
- }
-
- if (DeclaringType != mi.DeclaringType)
- return false;
-
- if (ReflectedType != mi.ReflectedType)
- return false;
-
- return true;
- }
- #endregion
-
- #region ICustomAttributeProvider
- public override Object[] GetCustomAttributes(bool inherit)
- {
- return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType as RuntimeType, inherit);
- }
-
- public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
-
- return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
- }
-
- public override bool IsDefined(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
-
- return CustomAttribute.IsDefined(this, attributeRuntimeType, inherit);
- }
-
- public override IList<CustomAttributeData> GetCustomAttributesData()
- {
- return CustomAttributeData.GetCustomAttributesInternal(this);
- }
- #endregion
-
- #region MemberInfo Overrides
- public override String Name
- {
- get
- {
- if (m_name == null)
- m_name = RuntimeMethodHandle.GetName(this);
-
- return m_name;
- }
- }
-
- public override Type DeclaringType
- {
- get
- {
- if (m_reflectedTypeCache.IsGlobal)
- return null;
-
- return m_declaringType;
- }
- }
-
- public override Type ReflectedType
- {
- get
- {
- if (m_reflectedTypeCache.IsGlobal)
- return null;
-
- return m_reflectedTypeCache.GetRuntimeType();
- }
- }
-
- public override MemberTypes MemberType { get { return MemberTypes.Method; } }
- public override int MetadataToken
- {
- get { return RuntimeMethodHandle.GetMethodDef(this); }
- }
- public override Module Module { get { return GetRuntimeModule(); } }
- internal RuntimeType GetRuntimeType() { return m_declaringType; }
- internal RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); }
- internal RuntimeAssembly GetRuntimeAssembly() { return GetRuntimeModule().GetRuntimeAssembly(); }
-
- public override bool IsSecurityCritical
- {
- get { return true; }
- }
- public override bool IsSecuritySafeCritical
- {
- get { return false; }
- }
- public override bool IsSecurityTransparent
- {
- get { return false; }
- }
-#endregion
-
-#region MethodBase Overrides
- internal override ParameterInfo[] GetParametersNoCopy()
- {
- FetchNonReturnParameters();
-
- return m_parameters;
- }
-
- [System.Diagnostics.Contracts.Pure]
- public override ParameterInfo[] GetParameters()
- {
- FetchNonReturnParameters();
-
- if (m_parameters.Length == 0)
- return m_parameters;
-
- ParameterInfo[] ret = new ParameterInfo[m_parameters.Length];
-
- Array.Copy(m_parameters, ret, m_parameters.Length);
-
- return ret;
- }
-
- public override MethodImplAttributes GetMethodImplementationFlags()
- {
- return RuntimeMethodHandle.GetImplAttributes(this);
- }
-
- public override RuntimeMethodHandle MethodHandle
- {
- get
- {
- Type declaringType = DeclaringType;
- if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly"));
- return new RuntimeMethodHandle(this);
- }
- }
-
- public override MethodAttributes Attributes { get { return m_methodAttributes; } }
-
- public override CallingConventions CallingConvention
- {
- get
- {
- return Signature.CallingConvention;
- }
- }
-
- public override MethodBody GetMethodBody()
- {
- MethodBody mb = RuntimeMethodHandle.GetMethodBody(this, ReflectedTypeInternal);
- if (mb != null)
- mb.m_methodBase = this;
- return mb;
- }
-#endregion
-
-#region Invocation Logic(On MemberBase)
- private void CheckConsistency(Object target)
- {
- // only test instance methods
- if ((m_methodAttributes & MethodAttributes.Static) != MethodAttributes.Static)
- {
- if (!m_declaringType.IsInstanceOfType(target))
- {
- if (target == null)
- throw new TargetException(Environment.GetResourceString("RFLCT.Targ_StatMethReqTarg"));
- else
- throw new TargetException(Environment.GetResourceString("RFLCT.Targ_ITargMismatch"));
- }
- }
- }
-
- private void ThrowNoInvokeException()
- {
- // method is ReflectionOnly
- Type declaringType = DeclaringType;
- if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
- {
- throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyInvoke"));
- }
- // method is on a class that contains stack pointers
- else if ((InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_CONTAINS_STACK_POINTERS) != 0)
- {
- throw new NotSupportedException();
- }
- // method is vararg
- else if ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs)
- {
- throw new NotSupportedException();
- }
- // method is generic or on a generic class
- else if (DeclaringType.ContainsGenericParameters || ContainsGenericParameters)
- {
- throw new InvalidOperationException(Environment.GetResourceString("Arg_UnboundGenParam"));
- }
- // method is abstract class
- else if (IsAbstract)
- {
- throw new MemberAccessException();
- }
- // ByRef return are not allowed in reflection
- else if (ReturnType.IsByRef)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ByRefReturn"));
- }
-
- throw new TargetException();
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
- {
- object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture);
-
-#region Security Check
- INVOCATION_FLAGS invocationFlags = InvocationFlags;
-
-#if FEATURE_APPX
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
- if (caller != null && !caller.IsSafeForReflection())
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", FullName));
- }
-#endif
-#endregion
-
- return UnsafeInvokeInternal(obj, parameters, arguments);
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- internal object UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
- {
- object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture);
-
- return UnsafeInvokeInternal(obj, parameters, arguments);
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- private object UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
- {
- if (arguments == null || arguments.Length == 0)
- return RuntimeMethodHandle.InvokeMethod(obj, null, Signature, false);
- else
- {
- Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, Signature, false);
-
- // copy out. This should be made only if ByRef are present.
- for (int index = 0; index < arguments.Length; index++)
- parameters[index] = arguments[index];
-
- return retValue;
- }
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- private object[] InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
- {
- Signature sig = Signature;
-
- // get the signature
- int formalCount = sig.Arguments.Length;
- int actualCount = (parameters != null) ? parameters.Length : 0;
-
- INVOCATION_FLAGS invocationFlags = InvocationFlags;
-
- // INVOCATION_FLAGS_CONTAINS_STACK_POINTERS means that the struct (either the declaring type or the return type)
- // contains pointers that point to the stack. This is either a ByRef or a TypedReference. These structs cannot
- // be boxed and thus cannot be invoked through reflection which only deals with boxed value type objects.
- if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE | INVOCATION_FLAGS.INVOCATION_FLAGS_CONTAINS_STACK_POINTERS)) != 0)
- ThrowNoInvokeException();
-
- // check basic method consistency. This call will throw if there are problems in the target/method relationship
- CheckConsistency(obj);
-
- if (formalCount != actualCount)
- throw new TargetParameterCountException(Environment.GetResourceString("Arg_ParmCnt"));
-
- if (actualCount != 0)
- return CheckArguments(parameters, binder, invokeAttr, culture, sig);
- else
- return null;
- }
-
-#endregion
-
-#region MethodInfo Overrides
- public override Type ReturnType
- {
- get { return Signature.ReturnType; }
- }
-
- public override ICustomAttributeProvider ReturnTypeCustomAttributes
- {
- get { return ReturnParameter; }
- }
-
- public override ParameterInfo ReturnParameter
- {
- get
- {
- Contract.Ensures(m_returnParameter != null);
-
- FetchReturnParameter();
- return m_returnParameter as ParameterInfo;
- }
- }
-
- public override MethodInfo GetBaseDefinition()
- {
- if (!IsVirtual || IsStatic || m_declaringType == null || m_declaringType.IsInterface)
- return this;
-
- int slot = RuntimeMethodHandle.GetSlot(this);
- RuntimeType declaringType = (RuntimeType)DeclaringType;
- RuntimeType baseDeclaringType = declaringType;
- RuntimeMethodHandleInternal baseMethodHandle = new RuntimeMethodHandleInternal();
-
- do {
- int cVtblSlots = RuntimeTypeHandle.GetNumVirtuals(declaringType);
-
- if (cVtblSlots <= slot)
- break;
-
- baseMethodHandle = RuntimeTypeHandle.GetMethodAt(declaringType, slot);
- baseDeclaringType = declaringType;
-
- declaringType = (RuntimeType)declaringType.BaseType;
- } while (declaringType != null);
-
- return(MethodInfo)RuntimeType.GetMethodBase(baseDeclaringType, baseMethodHandle);
- }
-
- public override Delegate CreateDelegate(Type delegateType)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
-
- // This API existed in v1/v1.1 and only expected to create closed
- // instance delegates. Constrain the call to BindToMethodInfo to
- // open delegates only for backwards compatibility. But we'll allow
- // relaxed signature checking and open static delegates because
- // there's no ambiguity there (the caller would have to explicitly
- // pass us a static method or a method with a non-exact signature
- // and the only change in behavior from v1.1 there is that we won't
- // fail the call).
- return CreateDelegateInternal(
- delegateType,
- null,
- DelegateBindingFlags.OpenDelegateOnly | DelegateBindingFlags.RelaxedSignature,
- ref stackMark);
- }
-
- public override Delegate CreateDelegate(Type delegateType, Object target)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
-
- // This API is new in Whidbey and allows the full range of delegate
- // flexability (open or closed delegates binding to static or
- // instance methods with relaxed signature checking). The delegate
- // can also be closed over null. There's no ambiguity with all these
- // options since the caller is providing us a specific MethodInfo.
- return CreateDelegateInternal(
- delegateType,
- target,
- DelegateBindingFlags.RelaxedSignature,
- ref stackMark);
- }
-
- private Delegate CreateDelegateInternal(Type delegateType, Object firstArgument, DelegateBindingFlags bindingFlags, ref StackCrawlMark stackMark)
- {
- // Validate the parameters.
- if (delegateType == null)
- throw new ArgumentNullException(nameof(delegateType));
- Contract.EndContractBlock();
-
- RuntimeType rtType = delegateType as RuntimeType;
- if (rtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(delegateType));
-
- if (!rtType.IsDelegate())
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), nameof(delegateType));
-
- Delegate d = Delegate.CreateDelegateInternal(rtType, this, firstArgument, bindingFlags, ref stackMark);
- if (d == null)
- {
- throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTargMeth"));
- }
-
- return d;
- }
-
-#endregion
-
-#region Generics
- public override MethodInfo MakeGenericMethod(params Type[] methodInstantiation)
- {
- if (methodInstantiation == null)
- throw new ArgumentNullException(nameof(methodInstantiation));
- Contract.EndContractBlock();
-
- RuntimeType[] methodInstantionRuntimeType = new RuntimeType[methodInstantiation.Length];
-
- if (!IsGenericMethodDefinition)
- throw new InvalidOperationException(
- Environment.GetResourceString("Arg_NotGenericMethodDefinition", this));
-
- for (int i = 0; i < methodInstantiation.Length; i++)
- {
- Type methodInstantiationElem = methodInstantiation[i];
-
- if (methodInstantiationElem == null)
- throw new ArgumentNullException();
-
- RuntimeType rtMethodInstantiationElem = methodInstantiationElem as RuntimeType;
-
- if (rtMethodInstantiationElem == null)
- {
- Type[] methodInstantiationCopy = new Type[methodInstantiation.Length];
- for (int iCopy = 0; iCopy < methodInstantiation.Length; iCopy++)
- methodInstantiationCopy[iCopy] = methodInstantiation[iCopy];
- methodInstantiation = methodInstantiationCopy;
- return System.Reflection.Emit.MethodBuilderInstantiation.MakeGenericMethod(this, methodInstantiation);
- }
-
- methodInstantionRuntimeType[i] = rtMethodInstantiationElem;
- }
-
- RuntimeType[] genericParameters = GetGenericArgumentsInternal();
-
- RuntimeType.SanityCheckGenericArguments(methodInstantionRuntimeType, genericParameters);
-
- MethodInfo ret = null;
-
- try
- {
- ret = RuntimeType.GetMethodBase(ReflectedTypeInternal,
- RuntimeMethodHandle.GetStubIfNeeded(new RuntimeMethodHandleInternal(this.m_handle), m_declaringType, methodInstantionRuntimeType)) as MethodInfo;
- }
- catch (VerificationException e)
- {
- RuntimeType.ValidateGenericArguments(this, methodInstantionRuntimeType, e);
- throw;
- }
-
- return ret;
- }
-
- internal RuntimeType[] GetGenericArgumentsInternal()
- {
- return RuntimeMethodHandle.GetMethodInstantiationInternal(this);
- }
-
- public override Type[] GetGenericArguments()
- {
- Type[] types = RuntimeMethodHandle.GetMethodInstantiationPublic(this);
-
- if (types == null)
- {
- types = EmptyArray<Type>.Value;
- }
- return types;
- }
-
- public override MethodInfo GetGenericMethodDefinition()
- {
- if (!IsGenericMethod)
- throw new InvalidOperationException();
- Contract.EndContractBlock();
-
- return RuntimeType.GetMethodBase(m_declaringType, RuntimeMethodHandle.StripMethodInstantiation(this)) as MethodInfo;
- }
-
- public override bool IsGenericMethod
- {
- get { return RuntimeMethodHandle.HasMethodInstantiation(this); }
- }
-
- public override bool IsGenericMethodDefinition
- {
- get { return RuntimeMethodHandle.IsGenericMethodDefinition(this); }
- }
-
- public override bool ContainsGenericParameters
- {
- get
- {
- if (DeclaringType != null && DeclaringType.ContainsGenericParameters)
- return true;
-
- if (!IsGenericMethod)
- return false;
-
- Type[] pis = GetGenericArguments();
- for (int i = 0; i < pis.Length; i++)
- {
- if (pis[i].ContainsGenericParameters)
- return true;
- }
-
- return false;
- }
- }
-#endregion
-
-#region ISerializable Implementation
- public void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- if (m_reflectedTypeCache.IsGlobal)
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_GlobalMethodSerialization"));
-
- MemberInfoSerializationHolder.GetSerializationInfo(
- info,
- Name,
- ReflectedTypeInternal,
- ToString(),
- SerializationToString(),
- MemberTypes.Method,
- IsGenericMethod & !IsGenericMethodDefinition ? GetGenericArguments() : null);
- }
-
- internal string SerializationToString()
- {
- return ReturnType.FormatTypeName(true) + " " + FormatNameAndSig(true);
- }
-#endregion
-
-#region Legacy Internal
- internal static MethodBase InternalGetCurrentMethod(ref StackCrawlMark stackMark)
- {
- IRuntimeMethodInfo method = RuntimeMethodHandle.GetCurrentMethod(ref stackMark);
-
- if (method == null)
- return null;
-
- return RuntimeType.GetMethodBase(method);
- }
-#endregion
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/Missing.cs b/src/mscorlib/src/System/Reflection/Missing.cs
deleted file mode 100644
index f62c5b538c..0000000000
--- a/src/mscorlib/src/System/Reflection/Missing.cs
+++ /dev/null
@@ -1,35 +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.
-
-//
-
-namespace System.Reflection
-{
- using System;
- using System.Runtime.Remoting;
- using System.Runtime.Serialization;
- using System.Diagnostics.Contracts;
-
- // This is not serializable because it is a reflection command.
- [Serializable]
- public sealed class Missing : ISerializable
- {
- public static readonly Missing Value = new Missing();
-
- #region Constructor
- private Missing() { }
- #endregion
-
- #region ISerializable
- void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- UnitySerializationHolder.GetUnitySerializationInfo(info, this);
- }
- #endregion
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/Module.cs b/src/mscorlib/src/System/Reflection/Module.cs
deleted file mode 100644
index bdf95fca26..0000000000
--- a/src/mscorlib/src/System/Reflection/Module.cs
+++ /dev/null
@@ -1,1120 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-//
-
-namespace System.Reflection
-{
- using System;
- using System.Diagnostics.SymbolStore;
- using System.Runtime.Remoting;
- using System.Runtime.InteropServices;
- using System.Runtime.Serialization;
- using System.Collections;
- using System.Collections.Generic;
- using System.Threading;
- using System.Runtime.CompilerServices;
- using System.Security;
- using System.IO;
- using System.Globalization;
- using System.Runtime.Versioning;
- using System.Diagnostics.Contracts;
-
- [Serializable]
- [Flags]
- public enum PortableExecutableKinds
- {
- NotAPortableExecutableImage = 0x0,
-
- ILOnly = 0x1,
-
- Required32Bit = 0x2,
-
- PE32Plus = 0x4,
-
- Unmanaged32Bit = 0x8,
-
- Preferred32Bit = 0x10,
- }
-
- [Serializable]
- public enum ImageFileMachine
- {
- I386 = 0x014c,
-
- IA64 = 0x0200,
-
- AMD64 = 0x8664,
-
- ARM = 0x01c4,
- }
-
- [Serializable]
- public abstract class Module : ISerializable, ICustomAttributeProvider
- {
- #region Static Constructor
- static Module()
- {
- __Filters _fltObj;
- _fltObj = new __Filters();
- FilterTypeName = new TypeFilter(_fltObj.FilterTypeName);
- FilterTypeNameIgnoreCase = new TypeFilter(_fltObj.FilterTypeNameIgnoreCase);
- }
- #endregion
-
- #region Constructor
- protected Module()
- {
- }
- #endregion
-
- #region Public Statics
- public static readonly TypeFilter FilterTypeName;
- public static readonly TypeFilter FilterTypeNameIgnoreCase;
-
- public static bool operator ==(Module left, Module right)
- {
- if (ReferenceEquals(left, right))
- return true;
-
- if ((object)left == null || (object)right == null ||
- left is RuntimeModule || right is RuntimeModule)
- {
- return false;
- }
-
- return left.Equals(right);
- }
-
- public static bool operator !=(Module left, Module right)
- {
- return !(left == right);
- }
-
- public override bool Equals(object o)
- {
- return base.Equals(o);
- }
-
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
- #endregion
-
- #region Literals
- private const BindingFlags DefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
- #endregion
-
- #region object overrides
- public override String ToString()
- {
- return ScopeName;
- }
- #endregion
-
- public virtual IEnumerable<CustomAttributeData> CustomAttributes
- {
- get
- {
- return GetCustomAttributesData();
- }
- }
- #region ICustomAttributeProvider Members
- public virtual Object[] GetCustomAttributes(bool inherit)
- {
- throw new NotImplementedException();
- }
-
- public virtual Object[] GetCustomAttributes(Type attributeType, bool inherit)
- {
- throw new NotImplementedException();
- }
-
- public virtual bool IsDefined(Type attributeType, bool inherit)
- {
- throw new NotImplementedException();
- }
-
- public virtual IList<CustomAttributeData> GetCustomAttributesData()
- {
- throw new NotImplementedException();
- }
- #endregion
-
- #region public instances members
- public MethodBase ResolveMethod(int metadataToken)
- {
- return ResolveMethod(metadataToken, null, null);
- }
-
- public virtual MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.ResolveMethod(metadataToken, genericTypeArguments, genericMethodArguments);
-
- throw new NotImplementedException();
- }
-
- public FieldInfo ResolveField(int metadataToken)
- {
- return ResolveField(metadataToken, null, null);
- }
-
- public virtual FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.ResolveField(metadataToken, genericTypeArguments, genericMethodArguments);
-
- throw new NotImplementedException();
- }
-
- public Type ResolveType(int metadataToken)
- {
- return ResolveType(metadataToken, null, null);
- }
-
- public virtual Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.ResolveType(metadataToken, genericTypeArguments, genericMethodArguments);
-
- throw new NotImplementedException();
- }
-
- public MemberInfo ResolveMember(int metadataToken)
- {
- return ResolveMember(metadataToken, null, null);
- }
-
- public virtual MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.ResolveMember(metadataToken, genericTypeArguments, genericMethodArguments);
-
- throw new NotImplementedException();
- }
-
- public virtual byte[] ResolveSignature(int metadataToken)
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.ResolveSignature(metadataToken);
-
- throw new NotImplementedException();
- }
-
- public virtual string ResolveString(int metadataToken)
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.ResolveString(metadataToken);
-
- throw new NotImplementedException();
- }
-
- public virtual void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine)
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- rtModule.GetPEKind(out peKind, out machine);
-
- throw new NotImplementedException();
- }
-
- public virtual int MDStreamVersion
- {
- get
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.MDStreamVersion;
-
- throw new NotImplementedException();
- }
- }
-
- public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- throw new NotImplementedException();
- }
-
- public virtual Type GetType(String className, bool ignoreCase)
- {
- return GetType(className, false, ignoreCase);
- }
-
- public virtual Type GetType(String className) {
- return GetType(className, false, false);
- }
-
- public virtual Type GetType(String className, bool throwOnError, bool ignoreCase)
- {
- throw new NotImplementedException();
- }
-
- public virtual String FullyQualifiedName
- {
- get
- {
- throw new NotImplementedException();
- }
- }
-
- public virtual Type[] FindTypes(TypeFilter filter,Object filterCriteria)
- {
- Type[] c = GetTypes();
- int cnt = 0;
- for (int i = 0;i<c.Length;i++) {
- if (filter!=null && !filter(c[i],filterCriteria))
- c[i] = null;
- else
- cnt++;
- }
- if (cnt == c.Length)
- return c;
-
- Type[] ret = new Type[cnt];
- cnt=0;
- for (int i=0;i<c.Length;i++) {
- if (c[i] != null)
- ret[cnt++] = c[i];
- }
- return ret;
- }
-
- public virtual Type[] GetTypes()
- {
- throw new NotImplementedException();
- }
-
- public virtual Guid ModuleVersionId
- {
- get
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.ModuleVersionId;
-
- throw new NotImplementedException();
- }
- }
-
- public virtual int MetadataToken
- {
- get
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.MetadataToken;
-
- throw new NotImplementedException();
- }
- }
-
- public virtual bool IsResource()
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.IsResource();
-
- throw new NotImplementedException();
- }
-
- public FieldInfo[] GetFields()
- {
- return GetFields(Module.DefaultLookup);
- }
-
- public virtual FieldInfo[] GetFields(BindingFlags bindingFlags)
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.GetFields(bindingFlags);
-
- throw new NotImplementedException();
- }
-
- public FieldInfo GetField(String name)
- {
- return GetField(name,Module.DefaultLookup);
- }
-
- public virtual FieldInfo GetField(String name, BindingFlags bindingAttr)
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.GetField(name, bindingAttr);
-
- throw new NotImplementedException();
- }
-
- public MethodInfo[] GetMethods()
- {
- return GetMethods(Module.DefaultLookup);
- }
-
- public virtual MethodInfo[] GetMethods(BindingFlags bindingFlags)
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.GetMethods(bindingFlags);
-
- throw new NotImplementedException();
- }
-
- public MethodInfo GetMethod(
- String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
-
- if (types == null)
- throw new ArgumentNullException(nameof(types));
- Contract.EndContractBlock();
-
- for (int i = 0; i < types.Length; i++)
- {
- if (types[i] == null)
- throw new ArgumentNullException(nameof(types));
- }
-
- return GetMethodImpl(name, bindingAttr, binder, callConvention, types, modifiers);
- }
-
- public MethodInfo GetMethod(String name, Type[] types)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
-
- if (types == null)
- throw new ArgumentNullException(nameof(types));
- Contract.EndContractBlock();
-
- for (int i = 0; i < types.Length; i++)
- {
- if (types[i] == null)
- throw new ArgumentNullException(nameof(types));
- }
-
- return GetMethodImpl(name, Module.DefaultLookup, null, CallingConventions.Any, types, null);
- }
-
- public MethodInfo GetMethod(String name)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
- Contract.EndContractBlock();
-
- return GetMethodImpl(name, Module.DefaultLookup, null, CallingConventions.Any,
- null, null);
- }
-
- protected virtual MethodInfo GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder,
- CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
- {
- throw new NotImplementedException();
- }
-
- public virtual String ScopeName
- {
- get
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.ScopeName;
-
- throw new NotImplementedException();
- }
- }
-
- public virtual String Name
- {
- get
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.Name;
-
- throw new NotImplementedException();
- }
- }
-
- public virtual Assembly Assembly
- {
- [Pure]
- get
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeModule rtModule = this as RuntimeModule;
- if (rtModule != null)
- return rtModule.Assembly;
-
- throw new NotImplementedException();
- }
- }
-
- // This API never fails, it will return an empty handle for non-runtime handles and
- // a valid handle for reflection only modules.
- public ModuleHandle ModuleHandle
- {
- get
- {
- return GetModuleHandle();
- }
- }
-
- // Used to provide implementation and overriding point for ModuleHandle.
- // To get a module handle inside mscorlib, use GetNativeHandle instead.
- internal virtual ModuleHandle GetModuleHandle()
- {
- return ModuleHandle.EmptyHandle;
- }
- #endregion
- }
-
- [Serializable]
- internal class RuntimeModule : Module
- {
- internal RuntimeModule() { throw new NotSupportedException(); }
-
- #region FCalls
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private extern static void GetType(RuntimeModule module, String className, bool ignoreCase, bool throwOnError, ObjectHandleOnStack type, ObjectHandleOnStack keepAlive);
-
- [DllImport(JitHelpers.QCall)]
- [SuppressUnmanagedCodeSecurity]
- private static extern bool nIsTransientInternal(RuntimeModule module);
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private extern static void GetScopeName(RuntimeModule module, StringHandleOnStack retString);
-
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
- private extern static void GetFullyQualifiedName(RuntimeModule module, StringHandleOnStack retString);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern static RuntimeType[] GetTypes(RuntimeModule module);
-
- internal RuntimeType[] GetDefinedTypes()
- {
- return GetTypes(GetNativeHandle());
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern static bool IsResource(RuntimeModule module);
- #endregion
-
- #region Module overrides
- private static RuntimeTypeHandle[] ConvertToTypeHandleArray(Type[] genericArguments)
- {
- if (genericArguments == null)
- return null;
-
- int size = genericArguments.Length;
- RuntimeTypeHandle[] typeHandleArgs = new RuntimeTypeHandle[size];
- for (int i = 0; i < size; i++)
- {
- Type typeArg = genericArguments[i];
- if (typeArg == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidGenericInstArray"));
- typeArg = typeArg.UnderlyingSystemType;
- if (typeArg == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidGenericInstArray"));
- if (!(typeArg is RuntimeType))
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidGenericInstArray"));
- typeHandleArgs[i] = typeArg.GetTypeHandleInternal();
- }
- return typeHandleArgs;
- }
-
- public override byte[] ResolveSignature(int metadataToken)
- {
- MetadataToken tk = new MetadataToken(metadataToken);
-
- if (!MetadataImport.IsValidToken(tk))
- throw new ArgumentOutOfRangeException(nameof(metadataToken),
- Environment.GetResourceString("Argument_InvalidToken", tk, this));
-
- if (!tk.IsMemberRef && !tk.IsMethodDef && !tk.IsTypeSpec && !tk.IsSignature && !tk.IsFieldDef)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidToken", tk, this),
- nameof(metadataToken));
-
- ConstArray signature;
- if (tk.IsMemberRef)
- signature = MetadataImport.GetMemberRefProps(metadataToken);
- else
- signature = MetadataImport.GetSignatureFromToken(metadataToken);
-
- byte[] sig = new byte[signature.Length];
-
- for (int i = 0; i < signature.Length; i++)
- sig[i] = signature[i];
-
- return sig;
- }
-
- public override MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
- {
- MetadataToken tk = new MetadataToken(metadataToken);
-
- if (!MetadataImport.IsValidToken(tk))
- throw new ArgumentOutOfRangeException(nameof(metadataToken),
- Environment.GetResourceString("Argument_InvalidToken", tk, this));
-
- RuntimeTypeHandle[] typeArgs = ConvertToTypeHandleArray(genericTypeArguments);
- RuntimeTypeHandle[] methodArgs = ConvertToTypeHandleArray(genericMethodArguments);
-
- try
- {
- if (!tk.IsMethodDef && !tk.IsMethodSpec)
- {
- if (!tk.IsMemberRef)
- throw new ArgumentException(Environment.GetResourceString("Argument_ResolveMethod", tk, this),
- nameof(metadataToken));
-
- unsafe
- {
- ConstArray sig = MetadataImport.GetMemberRefProps(tk);
-
- if (*(MdSigCallingConvention*)sig.Signature.ToPointer() == MdSigCallingConvention.Field)
- throw new ArgumentException(Environment.GetResourceString("Argument_ResolveMethod", tk, this),
- nameof(metadataToken));
- }
- }
-
- IRuntimeMethodInfo methodHandle = ModuleHandle.ResolveMethodHandleInternal(GetNativeHandle(), tk, typeArgs, methodArgs);
- Type declaringType = RuntimeMethodHandle.GetDeclaringType(methodHandle);
-
- if (declaringType.IsGenericType || declaringType.IsArray)
- {
- MetadataToken tkDeclaringType = new MetadataToken(MetadataImport.GetParentToken(tk));
-
- if (tk.IsMethodSpec)
- tkDeclaringType = new MetadataToken(MetadataImport.GetParentToken(tkDeclaringType));
-
- declaringType = ResolveType(tkDeclaringType, genericTypeArguments, genericMethodArguments);
- }
-
- return System.RuntimeType.GetMethodBase(declaringType as RuntimeType, methodHandle);
- }
- catch (BadImageFormatException e)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_BadImageFormatExceptionResolve"), e);
- }
- }
-
- private FieldInfo ResolveLiteralField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
- {
- MetadataToken tk = new MetadataToken(metadataToken);
-
- if (!MetadataImport.IsValidToken(tk) || !tk.IsFieldDef)
- throw new ArgumentOutOfRangeException(nameof(metadataToken),
- String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Argument_InvalidToken", tk, this)));
-
- int tkDeclaringType;
- string fieldName;
-
- fieldName = MetadataImport.GetName(tk).ToString();
- tkDeclaringType = MetadataImport.GetParentToken(tk);
-
- Type declaringType = ResolveType(tkDeclaringType, genericTypeArguments, genericMethodArguments);
-
- declaringType.GetFields();
-
- try
- {
- return declaringType.GetField(fieldName,
- BindingFlags.Static | BindingFlags.Instance |
- BindingFlags.Public | BindingFlags.NonPublic |
- BindingFlags.DeclaredOnly);
- }
- catch
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_ResolveField", tk, this), nameof(metadataToken));
- }
- }
-
- public override FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
- {
- MetadataToken tk = new MetadataToken(metadataToken);
-
- if (!MetadataImport.IsValidToken(tk))
- throw new ArgumentOutOfRangeException(nameof(metadataToken),
- Environment.GetResourceString("Argument_InvalidToken", tk, this));
-
- RuntimeTypeHandle[] typeArgs = ConvertToTypeHandleArray(genericTypeArguments);
- RuntimeTypeHandle[] methodArgs = ConvertToTypeHandleArray(genericMethodArguments);
-
- try
- {
- IRuntimeFieldInfo fieldHandle = null;
-
- if (!tk.IsFieldDef)
- {
- if (!tk.IsMemberRef)
- throw new ArgumentException(Environment.GetResourceString("Argument_ResolveField", tk, this),
- nameof(metadataToken));
-
- unsafe
- {
- ConstArray sig = MetadataImport.GetMemberRefProps(tk);
-
- if (*(MdSigCallingConvention*)sig.Signature.ToPointer() != MdSigCallingConvention.Field)
- throw new ArgumentException(Environment.GetResourceString("Argument_ResolveField", tk, this),
- nameof(metadataToken));
- }
-
- fieldHandle = ModuleHandle.ResolveFieldHandleInternal(GetNativeHandle(), tk, typeArgs, methodArgs);
- }
-
- fieldHandle = ModuleHandle.ResolveFieldHandleInternal(GetNativeHandle(), metadataToken, typeArgs, methodArgs);
- RuntimeType declaringType = RuntimeFieldHandle.GetApproxDeclaringType(fieldHandle.Value);
-
- if (declaringType.IsGenericType || declaringType.IsArray)
- {
- int tkDeclaringType = ModuleHandle.GetMetadataImport(GetNativeHandle()).GetParentToken(metadataToken);
- declaringType = (RuntimeType)ResolveType(tkDeclaringType, genericTypeArguments, genericMethodArguments);
- }
-
- return System.RuntimeType.GetFieldInfo(declaringType, fieldHandle);
- }
- catch(MissingFieldException)
- {
- return ResolveLiteralField(tk, genericTypeArguments, genericMethodArguments);
- }
- catch (BadImageFormatException e)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_BadImageFormatExceptionResolve"), e);
- }
- }
-
- public override Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
- {
- MetadataToken tk = new MetadataToken(metadataToken);
-
- if (tk.IsGlobalTypeDefToken)
- throw new ArgumentException(Environment.GetResourceString("Argument_ResolveModuleType", tk), nameof(metadataToken));
-
- if (!MetadataImport.IsValidToken(tk))
- throw new ArgumentOutOfRangeException(nameof(metadataToken),
- Environment.GetResourceString("Argument_InvalidToken", tk, this));
-
- if (!tk.IsTypeDef && !tk.IsTypeSpec && !tk.IsTypeRef)
- throw new ArgumentException(Environment.GetResourceString("Argument_ResolveType", tk, this), nameof(metadataToken));
-
- RuntimeTypeHandle[] typeArgs = ConvertToTypeHandleArray(genericTypeArguments);
- RuntimeTypeHandle[] methodArgs = ConvertToTypeHandleArray(genericMethodArguments);
-
- try
- {
- Type t = GetModuleHandle().ResolveTypeHandle(metadataToken, typeArgs, methodArgs).GetRuntimeType();
-
- if (t == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_ResolveType", tk, this), nameof(metadataToken));
-
- return t;
- }
- catch (BadImageFormatException e)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_BadImageFormatExceptionResolve"), e);
- }
- }
-
- public override MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
- {
- MetadataToken tk = new MetadataToken(metadataToken);
-
- if (tk.IsProperty)
- throw new ArgumentException(Environment.GetResourceString("InvalidOperation_PropertyInfoNotAvailable"));
-
- if (tk.IsEvent)
- throw new ArgumentException(Environment.GetResourceString("InvalidOperation_EventInfoNotAvailable"));
-
- if (tk.IsMethodSpec || tk.IsMethodDef)
- return ResolveMethod(metadataToken, genericTypeArguments, genericMethodArguments);
-
- if (tk.IsFieldDef)
- return ResolveField(metadataToken, genericTypeArguments, genericMethodArguments);
-
- if (tk.IsTypeRef || tk.IsTypeDef || tk.IsTypeSpec)
- return ResolveType(metadataToken, genericTypeArguments, genericMethodArguments);
-
- if (tk.IsMemberRef)
- {
- if (!MetadataImport.IsValidToken(tk))
- throw new ArgumentOutOfRangeException(nameof(metadataToken),
- Environment.GetResourceString("Argument_InvalidToken", tk, this));
-
- ConstArray sig = MetadataImport.GetMemberRefProps(tk);
-
- unsafe
- {
- if (*(MdSigCallingConvention*)sig.Signature.ToPointer() == MdSigCallingConvention.Field)
- {
- return ResolveField(tk, genericTypeArguments, genericMethodArguments);
- }
- else
- {
- return ResolveMethod(tk, genericTypeArguments, genericMethodArguments);
- }
- }
- }
-
- throw new ArgumentException(Environment.GetResourceString("Argument_ResolveMember", tk, this),
- nameof(metadataToken));
- }
-
- public override string ResolveString(int metadataToken)
- {
- MetadataToken tk = new MetadataToken(metadataToken);
- if (!tk.IsString)
- throw new ArgumentException(
- String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Argument_ResolveString"), metadataToken, ToString()));
-
- if (!MetadataImport.IsValidToken(tk))
- throw new ArgumentOutOfRangeException(nameof(metadataToken),
- String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Argument_InvalidToken", tk, this)));
-
- string str = MetadataImport.GetUserString(metadataToken);
-
- if (str == null)
- throw new ArgumentException(
- String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Argument_ResolveString"), metadataToken, ToString()));
-
- return str;
- }
-
- public override void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine)
- {
- ModuleHandle.GetPEKind(GetNativeHandle(), out peKind, out machine);
- }
-
- public override int MDStreamVersion
- {
- get
- {
- return ModuleHandle.GetMDStreamVersion(GetNativeHandle());
- }
- }
- #endregion
-
- #region Data Members
- #pragma warning disable 169
- // If you add any data members, you need to update the native declaration ReflectModuleBaseObject.
- private RuntimeType m_runtimeType;
- private RuntimeAssembly m_runtimeAssembly;
- private IntPtr m_pRefClass;
- private IntPtr m_pData;
- private IntPtr m_pGlobals;
- private IntPtr m_pFields;
-#pragma warning restore 169
- #endregion
-
- #region Protected Virtuals
- protected override MethodInfo GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder,
- CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
- {
- return GetMethodInternal(name, bindingAttr, binder, callConvention, types, modifiers);
- }
-
- internal MethodInfo GetMethodInternal(String name, BindingFlags bindingAttr, Binder binder,
- CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
- {
- if (RuntimeType == null)
- return null;
-
- if (types == null)
- {
- return RuntimeType.GetMethod(name, bindingAttr);
- }
- else
- {
- return RuntimeType.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers);
- }
- }
- #endregion
-
- #region Internal Members
- internal RuntimeType RuntimeType
- {
- get
- {
- if (m_runtimeType == null)
- m_runtimeType = ModuleHandle.GetModuleType(GetNativeHandle());
-
- return m_runtimeType;
- }
- }
-
- internal bool IsTransientInternal()
- {
- return RuntimeModule.nIsTransientInternal(this.GetNativeHandle());
- }
-
- internal MetadataImport MetadataImport
- {
- get
- {
- unsafe
- {
- return ModuleHandle.GetMetadataImport(GetNativeHandle());
- }
- }
- }
- #endregion
-
- #region ICustomAttributeProvider Members
- public override Object[] GetCustomAttributes(bool inherit)
- {
- return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
- }
-
- public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
-
- return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
- }
-
- public override bool IsDefined(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
-
- return CustomAttribute.IsDefined(this, attributeRuntimeType);
- }
-
- public override IList<CustomAttributeData> GetCustomAttributesData()
- {
- return CustomAttributeData.GetCustomAttributesInternal(this);
- }
- #endregion
-
- #region Public Virtuals
- public override void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- {
- throw new ArgumentNullException(nameof(info));
- }
- Contract.EndContractBlock();
- UnitySerializationHolder.GetUnitySerializationInfo(info, UnitySerializationHolder.ModuleUnity, this.ScopeName, this.GetRuntimeAssembly());
- }
-
- public override Type GetType(String className, bool throwOnError, bool ignoreCase)
- {
- // throw on null strings regardless of the value of "throwOnError"
- if (className == null)
- throw new ArgumentNullException(nameof(className));
-
- RuntimeType retType = null;
- Object keepAlive = null;
- GetType(GetNativeHandle(), className, throwOnError, ignoreCase, JitHelpers.GetObjectHandleOnStack(ref retType), JitHelpers.GetObjectHandleOnStack(ref keepAlive));
- GC.KeepAlive(keepAlive);
- return retType;
- }
-
- internal string GetFullyQualifiedName()
- {
- String fullyQualifiedName = null;
- GetFullyQualifiedName(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref fullyQualifiedName));
- return fullyQualifiedName;
- }
-
- public override String FullyQualifiedName
- {
- get
- {
- return GetFullyQualifiedName();
- }
- }
-
- public override Type[] GetTypes()
- {
- return GetTypes(GetNativeHandle());
- }
-
- #endregion
-
- #region Public Members
-
- public override Guid ModuleVersionId
- {
- get
- {
- unsafe
- {
- Guid mvid;
- MetadataImport.GetScopeProps(out mvid);
- return mvid;
- }
- }
- }
-
- public override int MetadataToken
- {
- get
- {
- return ModuleHandle.GetToken(GetNativeHandle());
- }
- }
-
- public override bool IsResource()
- {
- return IsResource(GetNativeHandle());
- }
-
- public override FieldInfo[] GetFields(BindingFlags bindingFlags)
- {
- if (RuntimeType == null)
- return new FieldInfo[0];
-
- return RuntimeType.GetFields(bindingFlags);
- }
-
- public override FieldInfo GetField(String name, BindingFlags bindingAttr)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
-
- if (RuntimeType == null)
- return null;
-
- return RuntimeType.GetField(name, bindingAttr);
- }
-
- public override MethodInfo[] GetMethods(BindingFlags bindingFlags)
- {
- if (RuntimeType == null)
- return new MethodInfo[0];
-
- return RuntimeType.GetMethods(bindingFlags);
- }
-
- public override String ScopeName
- {
- get
- {
- string scopeName = null;
- GetScopeName(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref scopeName));
- return scopeName;
- }
- }
-
- public override String Name
- {
- get
- {
- String s = GetFullyQualifiedName();
-
-#if !FEATURE_PAL
- int i = s.LastIndexOf('\\');
-#else
- int i = s.LastIndexOf(System.IO.Path.DirectorySeparatorChar);
-#endif
- if (i == -1)
- return s;
-
- return s.Substring(i + 1);
- }
- }
-
- public override Assembly Assembly
- {
- [Pure]
- get
- {
- return GetRuntimeAssembly();
- }
- }
-
- internal RuntimeAssembly GetRuntimeAssembly()
- {
- return m_runtimeAssembly;
- }
-
-
- internal override ModuleHandle GetModuleHandle()
- {
- return new ModuleHandle(this);
- }
-
- internal RuntimeModule GetNativeHandle()
- {
- return this;
- }
- #endregion
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/ObfuscateAssemblyAttribute.cs b/src/mscorlib/src/System/Reflection/ObfuscateAssemblyAttribute.cs
deleted file mode 100644
index 787f37bced..0000000000
--- a/src/mscorlib/src/System/Reflection/ObfuscateAssemblyAttribute.cs
+++ /dev/null
@@ -1,45 +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;
-
-
-namespace System.Reflection
-{
- [AttributeUsage (AttributeTargets.Assembly, AllowMultiple=false, Inherited=false)]
- public sealed class ObfuscateAssemblyAttribute : Attribute
- {
- private bool m_assemblyIsPrivate;
- private bool m_strip = true;
-
- public ObfuscateAssemblyAttribute(bool assemblyIsPrivate)
- {
- m_assemblyIsPrivate = assemblyIsPrivate;
- }
-
- public bool AssemblyIsPrivate
- {
- get
- {
- return m_assemblyIsPrivate;
- }
- }
-
- public bool StripAfterObfuscation
- {
- get
- {
- return m_strip;
- }
- set
- {
- m_strip = value;
- }
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/Reflection/ObfuscationAttribute.cs b/src/mscorlib/src/System/Reflection/ObfuscationAttribute.cs
deleted file mode 100644
index c7c7c18550..0000000000
--- a/src/mscorlib/src/System/Reflection/ObfuscationAttribute.cs
+++ /dev/null
@@ -1,74 +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;
-
-namespace System.Reflection
-{
- [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Delegate,
- AllowMultiple = true, Inherited = false)]
- public sealed class ObfuscationAttribute: Attribute
- {
- private bool m_strip = true;
- private bool m_exclude = true;
- private bool m_applyToMembers = true;
- private string m_feature = "all";
-
- public ObfuscationAttribute()
- {
- }
-
- public bool StripAfterObfuscation
- {
- get
- {
- return m_strip;
- }
- set
- {
- m_strip = value;
- }
- }
-
- public bool Exclude
- {
- get
- {
- return m_exclude;
- }
- set
- {
- m_exclude = value;
- }
- }
-
- public bool ApplyToMembers
- {
- get
- {
- return m_applyToMembers;
- }
- set
- {
- m_applyToMembers = value;
- }
- }
-
- public string Feature
- {
- get
- {
- return m_feature;
- }
- set
- {
- m_feature = value;
- }
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/Reflection/ParameterAttributes.cs b/src/mscorlib/src/System/Reflection/ParameterAttributes.cs
deleted file mode 100644
index acae3a6ec1..0000000000
--- a/src/mscorlib/src/System/Reflection/ParameterAttributes.cs
+++ /dev/null
@@ -1,35 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// ParameterAttributes is an enum defining the attributes that may be
-//
-// associated with a Parameter. These are defined in CorHdr.h.
-//
-//
-namespace System.Reflection {
-
- using System;
- // This Enum matchs the CorParamAttr defined in CorHdr.h
-[Serializable]
- [Flags]
- public enum ParameterAttributes
- {
- None = 0x0000, // no flag is specified
- In = 0x0001, // Param is [In]
- Out = 0x0002, // Param is [Out]
- Lcid = 0x0004, // Param is [lcid]
- Retval = 0x0008, // Param is [Retval]
- Optional = 0x0010, // Param is optional
-
- // Reserved flags for Runtime use only.
- ReservedMask = 0xf000,
- HasDefault = 0x1000, // Param has default value.
- HasFieldMarshal = 0x2000, // Param has FieldMarshal.
- Reserved3 = 0x4000, // reserved bit
- Reserved4 = 0x8000 // reserved bit
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/ParameterInfo.cs b/src/mscorlib/src/System/Reflection/ParameterInfo.cs
deleted file mode 100644
index fad4402aff..0000000000
--- a/src/mscorlib/src/System/Reflection/ParameterInfo.cs
+++ /dev/null
@@ -1,733 +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.
-
-//
-
-namespace System.Reflection
-{
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Runtime.InteropServices;
- using System.Runtime.Serialization;
- using System.Runtime.CompilerServices;
- using System.Threading;
- using MdToken = System.Reflection.MetadataToken;
-
- [Serializable]
- public class ParameterInfo : ICustomAttributeProvider, IObjectReference
- {
- #region Legacy Protected Members
- protected String NameImpl;
- protected Type ClassImpl;
- protected int PositionImpl;
- protected ParameterAttributes AttrsImpl;
- protected Object DefaultValueImpl; // cannot cache this as it may be non agile user defined enum
- protected MemberInfo MemberImpl;
- #endregion
-
- #region Legacy Private Members
- // These are here only for backwards compatibility -- they are not set
- // until this instance is serialized, so don't rely on their values from
- // arbitrary code.
-#pragma warning disable 169
- [OptionalField]
- private IntPtr _importer;
- [OptionalField]
- private int _token;
- [OptionalField]
- private bool bExtraConstChecked;
-#pragma warning restore 169
- #endregion
-
- #region Constructor
- protected ParameterInfo()
- {
- }
- #endregion
-
- #region Internal Members
- // this is an internal api for DynamicMethod. A better solution is to change the relationship
- // between ParameterInfo and ParameterBuilder so that a ParameterBuilder can be seen as a writer
- // api over a ParameterInfo. However that is a possible breaking change so it needs to go through some process first
- internal void SetName(String name)
- {
- NameImpl = name;
- }
-
- internal void SetAttributes(ParameterAttributes attributes)
- {
- AttrsImpl = attributes;
- }
- #endregion
-
- #region Public Methods
- public virtual Type ParameterType
- {
- get
- {
- return ClassImpl;
- }
- }
-
- public virtual String Name
- {
- get
- {
- return NameImpl;
- }
- }
-
- public virtual bool HasDefaultValue { get { throw new NotImplementedException(); } }
-
- public virtual Object DefaultValue { get { throw new NotImplementedException(); } }
- public virtual Object RawDefaultValue { get { throw new NotImplementedException(); } }
-
- public virtual int Position { get { return PositionImpl; } }
- public virtual ParameterAttributes Attributes { get { return AttrsImpl; } }
-
- public virtual MemberInfo Member {
- get {
- Contract.Ensures(Contract.Result<MemberInfo>() != null);
- return MemberImpl;
- }
- }
-
- public bool IsIn { get { return((Attributes & ParameterAttributes.In) != 0); } }
- public bool IsOut { get { return((Attributes & ParameterAttributes.Out) != 0); } }
- public bool IsLcid { get { return((Attributes & ParameterAttributes.Lcid) != 0); } }
- public bool IsRetval { get { return((Attributes & ParameterAttributes.Retval) != 0); } }
- public bool IsOptional { get { return((Attributes & ParameterAttributes.Optional) != 0); } }
-
- public virtual int MetadataToken
- {
- get
- {
- // This API was made virtual in V4. Code compiled against V2 might use
- // "call" rather than "callvirt" to call it.
- // This makes sure those code still works.
- RuntimeParameterInfo rtParam = this as RuntimeParameterInfo;
- if (rtParam != null)
- return rtParam.MetadataToken;
-
- // return a null token
- return (int)MetadataTokenType.ParamDef;
- }
- }
-
- public virtual Type[] GetRequiredCustomModifiers()
- {
- return EmptyArray<Type>.Value;
- }
-
- public virtual Type[] GetOptionalCustomModifiers()
- {
- return EmptyArray<Type>.Value;
- }
- #endregion
-
- #region Object Overrides
- public override String ToString()
- {
- return ParameterType.FormatTypeName() + " " + Name;
- }
- #endregion
-
- public virtual IEnumerable<CustomAttributeData> CustomAttributes
- {
- get
- {
- return GetCustomAttributesData();
- }
- }
- #region ICustomAttributeProvider
- public virtual Object[] GetCustomAttributes(bool inherit)
- {
- return EmptyArray<Object>.Value;
- }
-
- public virtual Object[] GetCustomAttributes(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- return EmptyArray<Object>.Value;
- }
-
- public virtual bool IsDefined(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- return false;
- }
-
- public virtual IList<CustomAttributeData> GetCustomAttributesData()
- {
- throw new NotImplementedException();
- }
- #endregion
-
- #region _ParameterInfo implementation
-
- #endregion
-
- #region IObjectReference
- // In V4 RuntimeParameterInfo is introduced.
- // To support deserializing ParameterInfo instances serialized in earlier versions
- // we need to implement IObjectReference.
- public object GetRealObject(StreamingContext context)
- {
- Contract.Ensures(Contract.Result<Object>() != null);
-
- // Once all the serializable fields have come in we can set up the real
- // instance based on just two of them (MemberImpl and PositionImpl).
-
- if (MemberImpl == null)
- throw new SerializationException(Environment.GetResourceString(ResId.Serialization_InsufficientState));
-
- ParameterInfo[] args = null;
-
- switch (MemberImpl.MemberType)
- {
- case MemberTypes.Constructor:
- case MemberTypes.Method:
- if (PositionImpl == -1)
- {
- if (MemberImpl.MemberType == MemberTypes.Method)
- return ((MethodInfo)MemberImpl).ReturnParameter;
- else
- throw new SerializationException(Environment.GetResourceString(ResId.Serialization_BadParameterInfo));
- }
- else
- {
- args = ((MethodBase)MemberImpl).GetParametersNoCopy();
-
- if (args != null && PositionImpl < args.Length)
- return args[PositionImpl];
- else
- throw new SerializationException(Environment.GetResourceString(ResId.Serialization_BadParameterInfo));
- }
-
- case MemberTypes.Property:
- args = ((RuntimePropertyInfo)MemberImpl).GetIndexParametersNoCopy();
-
- if (args != null && PositionImpl > -1 && PositionImpl < args.Length)
- return args[PositionImpl];
- else
- throw new SerializationException(Environment.GetResourceString(ResId.Serialization_BadParameterInfo));
-
- default:
- throw new SerializationException(Environment.GetResourceString(ResId.Serialization_NoParameterInfo));
- }
- }
- #endregion
- }
-
- [Serializable]
- internal unsafe sealed class RuntimeParameterInfo : ParameterInfo, ISerializable
- {
- #region Static Members
- internal unsafe static ParameterInfo[] GetParameters(IRuntimeMethodInfo method, MemberInfo member, Signature sig)
- {
- Debug.Assert(method is RuntimeMethodInfo || method is RuntimeConstructorInfo);
-
- ParameterInfo dummy;
- return GetParameters(method, member, sig, out dummy, false);
- }
-
- internal unsafe static ParameterInfo GetReturnParameter(IRuntimeMethodInfo method, MemberInfo member, Signature sig)
- {
- Debug.Assert(method is RuntimeMethodInfo || method is RuntimeConstructorInfo);
-
- ParameterInfo returnParameter;
- GetParameters(method, member, sig, out returnParameter, true);
- return returnParameter;
- }
-
- internal unsafe static ParameterInfo[] GetParameters(
- IRuntimeMethodInfo methodHandle, MemberInfo member, Signature sig, out ParameterInfo returnParameter, bool fetchReturnParameter)
- {
- returnParameter = null;
- int sigArgCount = sig.Arguments.Length;
- ParameterInfo[] args = fetchReturnParameter ? null : new ParameterInfo[sigArgCount];
-
- int tkMethodDef = RuntimeMethodHandle.GetMethodDef(methodHandle);
- int cParamDefs = 0;
-
- // Not all methods have tokens. Arrays, pointers and byRef types do not have tokens as they
- // are generated on the fly by the runtime.
- if (!MdToken.IsNullToken(tkMethodDef))
- {
- MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(RuntimeMethodHandle.GetDeclaringType(methodHandle));
-
- MetadataEnumResult tkParamDefs;
- scope.EnumParams(tkMethodDef, out tkParamDefs);
-
- cParamDefs = tkParamDefs.Length;
-
- // Not all parameters have tokens. Parameters may have no token
- // if they have no name and no attributes.
- if (cParamDefs > sigArgCount + 1 /* return type */)
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ParameterSignatureMismatch"));
-
- for (int i = 0; i < cParamDefs; i++)
- {
- #region Populate ParameterInfos
- ParameterAttributes attr;
- int position, tkParamDef = tkParamDefs[i];
-
- scope.GetParamDefProps(tkParamDef, out position, out attr);
-
- position--;
-
- if (fetchReturnParameter == true && position == -1)
- {
- // more than one return parameter?
- if (returnParameter != null)
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ParameterSignatureMismatch"));
-
- returnParameter = new RuntimeParameterInfo(sig, scope, tkParamDef, position, attr, member);
- }
- else if (fetchReturnParameter == false && position >= 0)
- {
- // position beyong sigArgCount?
- if (position >= sigArgCount)
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ParameterSignatureMismatch"));
-
- args[position] = new RuntimeParameterInfo(sig, scope, tkParamDef, position, attr, member);
- }
- #endregion
- }
- }
-
- // Fill in empty ParameterInfos for those without tokens
- if (fetchReturnParameter)
- {
- if (returnParameter == null)
- {
- returnParameter = new RuntimeParameterInfo(sig, MetadataImport.EmptyImport, 0, -1, (ParameterAttributes)0, member);
- }
- }
- else
- {
- if (cParamDefs < args.Length + 1)
- {
- for (int i = 0; i < args.Length; i++)
- {
- if (args[i] != null)
- continue;
-
- args[i] = new RuntimeParameterInfo(sig, MetadataImport.EmptyImport, 0, i, (ParameterAttributes)0, member);
- }
- }
- }
-
- return args;
- }
- #endregion
-
- #region Private Statics
- private static readonly Type s_DecimalConstantAttributeType = typeof(DecimalConstantAttribute);
- private static readonly Type s_CustomConstantAttributeType = typeof(CustomConstantAttribute);
- #endregion
-
- #region Private Data Members
- // These are new in Whidbey, so we cannot serialize them directly or we break backwards compatibility.
- [NonSerialized]
- private int m_tkParamDef;
- [NonSerialized]
- private MetadataImport m_scope;
- [NonSerialized]
- private Signature m_signature;
- [NonSerialized]
- private volatile bool m_nameIsCached = false;
- [NonSerialized]
- private readonly bool m_noMetadata = false;
- [NonSerialized]
- private bool m_noDefaultValue = false;
- [NonSerialized]
- private MethodBase m_originalMember = null;
- #endregion
-
- #region Internal Properties
- internal MethodBase DefiningMethod
- {
- get
- {
- MethodBase result = m_originalMember != null ? m_originalMember : MemberImpl as MethodBase;
- Debug.Assert(result != null);
- return result;
- }
- }
- #endregion
-
- #region VTS magic to serialize/deserialized to/from pre-Whidbey endpoints.
- public void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- // We could be serializing for consumption by a pre-Whidbey
- // endpoint. Therefore we set up all the serialized fields to look
- // just like a v1.0/v1.1 instance.
-
- // Need to set the type to ParameterInfo so that pre-Whidbey and Whidbey code
- // can deserialize this. This is also why we cannot simply use [OnSerializing].
- info.SetType(typeof(ParameterInfo));
-
- // Use the properties intead of the fields in case the fields haven't been et
- // _importer, bExtraConstChecked, and m_cachedData don't need to be set
-
- // Now set the legacy fields that the current implementation doesn't
- // use any more. Note that _importer is a raw pointer that should
- // never have been serialized in V1. We set it to zero here; if the
- // deserializer uses it (by calling GetCustomAttributes() on this
- // instance) they'll AV, but at least it will be a well defined
- // exception and not a random AV.
-
- info.AddValue("AttrsImpl", Attributes);
- info.AddValue("ClassImpl", ParameterType);
- info.AddValue("DefaultValueImpl", DefaultValue);
- info.AddValue("MemberImpl", Member);
- info.AddValue("NameImpl", Name);
- info.AddValue("PositionImpl", Position);
- info.AddValue("_token", m_tkParamDef);
- }
- #endregion
-
- #region Constructor
- // used by RuntimePropertyInfo
- internal RuntimeParameterInfo(RuntimeParameterInfo accessor, RuntimePropertyInfo property)
- : this(accessor, (MemberInfo)property)
- {
- m_signature = property.Signature;
- }
-
- private RuntimeParameterInfo(RuntimeParameterInfo accessor, MemberInfo member)
- {
- // Change ownership
- MemberImpl = member;
-
- // The original owner should always be a method, because this method is only used to
- // change the owner from a method to a property.
- m_originalMember = accessor.MemberImpl as MethodBase;
- Debug.Assert(m_originalMember != null);
-
- // Populate all the caches -- we inherit this behavior from RTM
- NameImpl = accessor.Name;
- m_nameIsCached = true;
- ClassImpl = accessor.ParameterType;
- PositionImpl = accessor.Position;
- AttrsImpl = accessor.Attributes;
-
- // Strictly speeking, property's don't contain paramter tokens
- // However we need this to make ca's work... oh well...
- m_tkParamDef = MdToken.IsNullToken(accessor.MetadataToken) ? (int)MetadataTokenType.ParamDef : accessor.MetadataToken;
- m_scope = accessor.m_scope;
- }
-
- private RuntimeParameterInfo(
- Signature signature, MetadataImport scope, int tkParamDef,
- int position, ParameterAttributes attributes, MemberInfo member)
- {
- Contract.Requires(member != null);
- Debug.Assert(MdToken.IsNullToken(tkParamDef) == scope.Equals(MetadataImport.EmptyImport));
- Debug.Assert(MdToken.IsNullToken(tkParamDef) || MdToken.IsTokenOfType(tkParamDef, MetadataTokenType.ParamDef));
-
- PositionImpl = position;
- MemberImpl = member;
- m_signature = signature;
- m_tkParamDef = MdToken.IsNullToken(tkParamDef) ? (int)MetadataTokenType.ParamDef : tkParamDef;
- m_scope = scope;
- AttrsImpl = attributes;
-
- ClassImpl = null;
- NameImpl = null;
- }
-
- // ctor for no metadata MethodInfo in the DynamicMethod and RuntimeMethodInfo cases
- internal RuntimeParameterInfo(MethodInfo owner, String name, Type parameterType, int position)
- {
- MemberImpl = owner;
- NameImpl = name;
- m_nameIsCached = true;
- m_noMetadata = true;
- ClassImpl = parameterType;
- PositionImpl = position;
- AttrsImpl = ParameterAttributes.None;
- m_tkParamDef = (int)MetadataTokenType.ParamDef;
- m_scope = MetadataImport.EmptyImport;
- }
- #endregion
-
- #region Public Methods
- public override Type ParameterType
- {
- get
- {
- // only instance of ParameterInfo has ClassImpl, all its subclasses don't
- if (ClassImpl == null)
- {
- RuntimeType parameterType;
- if (PositionImpl == -1)
- parameterType = m_signature.ReturnType;
- else
- parameterType = m_signature.Arguments[PositionImpl];
-
- Debug.Assert(parameterType != null);
- // different thread could only write ClassImpl to the same value, so a race condition is not a problem here
- ClassImpl = parameterType;
- }
-
- return ClassImpl;
- }
- }
-
- public override String Name
- {
- get
- {
- if (!m_nameIsCached)
- {
- if (!MdToken.IsNullToken(m_tkParamDef))
- {
- string name;
- name = m_scope.GetName(m_tkParamDef).ToString();
- NameImpl = name;
- }
-
- // other threads could only write it to true, so a race condition is OK
- // this field is volatile, so the write ordering is guaranteed
- m_nameIsCached = true;
- }
-
- // name may be null
- return NameImpl;
- }
- }
-
- public override bool HasDefaultValue
- {
- get
- {
- if (m_noMetadata || m_noDefaultValue)
- return false;
-
- object defaultValue = GetDefaultValueInternal(false);
-
- return (defaultValue != DBNull.Value);
- }
- }
-
- public override Object DefaultValue { get { return GetDefaultValue(false); } }
- public override Object RawDefaultValue { get { return GetDefaultValue(true); } }
-
- private Object GetDefaultValue(bool raw)
- {
- // OLD COMMENT (Is this even true?)
- // Cannot cache because default value could be non-agile user defined enumeration.
- // OLD COMMENT ends
- if (m_noMetadata)
- return null;
-
- // for dynamic method we pretend to have cached the value so we do not go to metadata
- object defaultValue = GetDefaultValueInternal(raw);
-
- if (defaultValue == DBNull.Value)
- {
- #region Handle case if no default value was found
- if (IsOptional)
- {
- // If the argument is marked as optional then the default value is Missing.Value.
- defaultValue = Type.Missing;
- }
- #endregion
- }
-
- return defaultValue;
- }
-
- // returns DBNull.Value if the parameter doesn't have a default value
- private Object GetDefaultValueInternal(bool raw)
- {
- Debug.Assert(!m_noMetadata);
-
- if (m_noDefaultValue)
- return DBNull.Value;
-
- object defaultValue = null;
-
- // Why check the parameter type only for DateTime and only for the ctor arguments?
- // No check on the parameter type is done for named args and for Decimal.
-
- // We should move this after MdToken.IsNullToken(m_tkParamDef) and combine it
- // with the other custom attribute logic. But will that be a breaking change?
- // For a DateTime parameter on which both an md constant and a ca constant are set,
- // which one should win?
- if (ParameterType == typeof(DateTime))
- {
- if (raw)
- {
- CustomAttributeTypedArgument value =
- CustomAttributeData.Filter(
- CustomAttributeData.GetCustomAttributes(this), typeof(DateTimeConstantAttribute), 0);
-
- if (value.ArgumentType != null)
- return new DateTime((long)value.Value);
- }
- else
- {
- object[] dt = GetCustomAttributes(typeof(DateTimeConstantAttribute), false);
- if (dt != null && dt.Length != 0)
- return ((DateTimeConstantAttribute)dt[0]).Value;
- }
- }
-
- #region Look for a default value in metadata
- if (!MdToken.IsNullToken(m_tkParamDef))
- {
- // This will return DBNull.Value if no constant value is defined on m_tkParamDef in the metadata.
- defaultValue = MdConstant.GetValue(m_scope, m_tkParamDef, ParameterType.GetTypeHandleInternal(), raw);
- }
- #endregion
-
- if (defaultValue == DBNull.Value)
- {
- #region Look for a default value in the custom attributes
- if (raw)
- {
- foreach (CustomAttributeData attr in CustomAttributeData.GetCustomAttributes(this))
- {
- Type attrType = attr.Constructor.DeclaringType;
-
- if (attrType == typeof(DateTimeConstantAttribute))
- {
- defaultValue = DateTimeConstantAttribute.GetRawDateTimeConstant(attr);
- }
- else if (attrType == typeof(DecimalConstantAttribute))
- {
- defaultValue = DecimalConstantAttribute.GetRawDecimalConstant(attr);
- }
- else if (attrType.IsSubclassOf(s_CustomConstantAttributeType))
- {
- defaultValue = CustomConstantAttribute.GetRawConstant(attr);
- }
- }
- }
- else
- {
- Object[] CustomAttrs = GetCustomAttributes(s_CustomConstantAttributeType, false);
- if (CustomAttrs.Length != 0)
- {
- defaultValue = ((CustomConstantAttribute)CustomAttrs[0]).Value;
- }
- else
- {
- CustomAttrs = GetCustomAttributes(s_DecimalConstantAttributeType, false);
- if (CustomAttrs.Length != 0)
- {
- defaultValue = ((DecimalConstantAttribute)CustomAttrs[0]).Value;
- }
- }
- }
- #endregion
- }
-
- if (defaultValue == DBNull.Value)
- m_noDefaultValue = true;
-
- return defaultValue;
- }
-
- internal RuntimeModule GetRuntimeModule()
- {
- RuntimeMethodInfo method = Member as RuntimeMethodInfo;
- RuntimeConstructorInfo constructor = Member as RuntimeConstructorInfo;
- RuntimePropertyInfo property = Member as RuntimePropertyInfo;
-
- if (method != null)
- return method.GetRuntimeModule();
- else if (constructor != null)
- return constructor.GetRuntimeModule();
- else if (property != null)
- return property.GetRuntimeModule();
- else
- return null;
- }
-
- public override int MetadataToken
- {
- get
- {
- return m_tkParamDef;
- }
- }
-
- public override Type[] GetRequiredCustomModifiers()
- {
- return m_signature.GetCustomModifiers(PositionImpl + 1, true);
- }
-
- public override Type[] GetOptionalCustomModifiers()
- {
- return m_signature.GetCustomModifiers(PositionImpl + 1, false);
- }
-
- #endregion
-
- #region ICustomAttributeProvider
- public override Object[] GetCustomAttributes(bool inherit)
- {
- if (MdToken.IsNullToken(m_tkParamDef))
- return EmptyArray<Object>.Value;
-
- return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
- }
-
- public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- if (MdToken.IsNullToken(m_tkParamDef))
- return EmptyArray<Object>.Value;
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(attributeType));
-
- return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
- }
-
- public override bool IsDefined(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- if (MdToken.IsNullToken(m_tkParamDef))
- return false;
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(attributeType));
-
- return CustomAttribute.IsDefined(this, attributeRuntimeType);
- }
-
- public override IList<CustomAttributeData> GetCustomAttributesData()
- {
- return CustomAttributeData.GetCustomAttributesInternal(this);
- }
- #endregion
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/ParameterModifier.cs b/src/mscorlib/src/System/Reflection/ParameterModifier.cs
deleted file mode 100644
index a2bfeab934..0000000000
--- a/src/mscorlib/src/System/Reflection/ParameterModifier.cs
+++ /dev/null
@@ -1,45 +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.Diagnostics.Contracts;
-namespace System.Reflection
-{
- using System;
-
- [Serializable]
- public struct ParameterModifier
- {
- #region Private Data Members
- private bool[] _byRef;
- #endregion
-
- #region Constructor
- public ParameterModifier(int parameterCount)
- {
- if (parameterCount <= 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_ParmArraySize"));
- Contract.EndContractBlock();
-
- _byRef = new bool[parameterCount];
- }
- #endregion
-
- #region Internal Members
- internal bool[] IsByRefArray { get { return _byRef; } }
- #endregion
-
- #region Public Members
- public bool this[int index]
- {
- get
- {
- return _byRef[index];
- }
- set
- {
- _byRef[index] = value;
- }
- }
- #endregion
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/Pointer.cs b/src/mscorlib/src/System/Reflection/Pointer.cs
deleted file mode 100644
index 9f1a38366a..0000000000
--- a/src/mscorlib/src/System/Reflection/Pointer.cs
+++ /dev/null
@@ -1,75 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// This is a wrapper class for Pointers
-//
-//
-//
-//
-//
-namespace System.Reflection {
- using System;
- using CultureInfo = System.Globalization.CultureInfo;
- using System.Runtime.Serialization;
- using System.Security;
- using System.Diagnostics.Contracts;
-
- [CLSCompliant(false)]
- [Serializable]
- public sealed class Pointer : ISerializable
- {
- unsafe private void* _ptr;
- private RuntimeType _ptrType;
-
- private Pointer() {}
-
- private unsafe Pointer(SerializationInfo info, StreamingContext context)
- {
- _ptr = ((IntPtr)(info.GetValue("_ptr", typeof(IntPtr)))).ToPointer();
- _ptrType = (RuntimeType)info.GetValue("_ptrType", typeof(RuntimeType));
- }
-
- // This method will box an pointer. We save both the
- // value and the type so we can access it from the native code
- // during an Invoke.
- public static unsafe Object Box(void *ptr,Type type) {
- if (type == null)
- throw new ArgumentNullException(nameof(type));
- if (!type.IsPointer)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBePointer"),nameof(ptr));
- Contract.EndContractBlock();
-
- RuntimeType rt = type as RuntimeType;
- if (rt == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBePointer"), nameof(ptr));
-
- Pointer x = new Pointer();
- x._ptr = ptr;
- x._ptrType = rt;
- return x;
- }
-
- // Returned the stored pointer.
- public static unsafe void* Unbox(Object ptr) {
- if (!(ptr is Pointer))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBePointer"),nameof(ptr));
- return ((Pointer)ptr)._ptr;
- }
-
- internal RuntimeType GetPointerType() {
- return _ptrType;
- }
-
- internal unsafe Object GetPointerValue() {
- return (IntPtr)_ptr;
- }
-
- unsafe void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
- info.AddValue("_ptr", new IntPtr(_ptr));
- info.AddValue("_ptrType", _ptrType);
- }
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/PropertyAttributes.cs b/src/mscorlib/src/System/Reflection/PropertyAttributes.cs
deleted file mode 100644
index 4a5617ba5e..0000000000
--- a/src/mscorlib/src/System/Reflection/PropertyAttributes.cs
+++ /dev/null
@@ -1,32 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// PropertyAttributes is an enum which defines the attributes that may be associated
-//
-// with a property. The values here are defined in Corhdr.h.
-//
-//
-namespace System.Reflection {
-
- using System;
- // This Enum matchs the CorPropertyAttr defined in CorHdr.h
-[Serializable]
-[Flags]
- public enum PropertyAttributes
- {
- None = 0x0000,
- SpecialName = 0x0200, // property is special. Name describes how.
-
- // Reserved flags for Runtime use only.
- ReservedMask = 0xf400,
- RTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding.
- HasDefault = 0x1000, // Property has default
- Reserved2 = 0x2000, // reserved bit
- Reserved3 = 0x4000, // reserved bit
- Reserved4 = 0x8000 // reserved bit
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/PropertyInfo.cs b/src/mscorlib/src/System/Reflection/PropertyInfo.cs
deleted file mode 100644
index e8c2837785..0000000000
--- a/src/mscorlib/src/System/Reflection/PropertyInfo.cs
+++ /dev/null
@@ -1,613 +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.
-
-//
-
-namespace System.Reflection
-{
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- using System.Runtime;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.InteropServices;
- using System.Runtime.Serialization;
- using System.Text;
- using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
-
- [Serializable]
- public abstract class PropertyInfo : MemberInfo
- {
- #region Constructor
- protected PropertyInfo() { }
- #endregion
-
- public static bool operator ==(PropertyInfo left, PropertyInfo right)
- {
- if (ReferenceEquals(left, right))
- return true;
-
- if ((object)left == null || (object)right == null ||
- left is RuntimePropertyInfo || right is RuntimePropertyInfo)
- {
- return false;
- }
- return left.Equals(right);
- }
-
- public static bool operator !=(PropertyInfo left, PropertyInfo right)
- {
- return !(left == right);
- }
-
- public override bool Equals(object obj)
- {
- return base.Equals(obj);
- }
-
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
-
- #region MemberInfo Overrides
- public override MemberTypes MemberType { get { return System.Reflection.MemberTypes.Property; } }
- #endregion
-
- #region Public Abstract\Virtual Members
- public virtual object GetConstantValue()
- {
- throw new NotImplementedException();
- }
-
- public virtual object GetRawConstantValue()
- {
- throw new NotImplementedException();
- }
-
- public abstract Type PropertyType { get; }
-
- public abstract void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture);
-
- public abstract MethodInfo[] GetAccessors(bool nonPublic);
-
- public abstract MethodInfo GetGetMethod(bool nonPublic);
-
- public abstract MethodInfo GetSetMethod(bool nonPublic);
-
- public abstract ParameterInfo[] GetIndexParameters();
-
- public abstract PropertyAttributes Attributes { get; }
-
- public abstract bool CanRead { get; }
-
- public abstract bool CanWrite { get; }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public Object GetValue(Object obj)
- {
- return GetValue(obj, null);
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public virtual Object GetValue(Object obj,Object[] index)
- {
- return GetValue(obj, BindingFlags.Default, null, index, null);
- }
-
- public abstract Object GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture);
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public void SetValue(Object obj, Object value)
- {
- SetValue(obj, value, null);
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public virtual void SetValue(Object obj, Object value, Object[] index)
- {
- SetValue(obj, value, BindingFlags.Default, null, index, null);
- }
- #endregion
-
- #region Public Members
- public virtual Type[] GetRequiredCustomModifiers() { return EmptyArray<Type>.Value; }
-
- public virtual Type[] GetOptionalCustomModifiers() { return EmptyArray<Type>.Value; }
-
- public MethodInfo[] GetAccessors() { return GetAccessors(false); }
-
- public virtual MethodInfo GetMethod
- {
- get
- {
- return GetGetMethod(true);
- }
- }
-
- public virtual MethodInfo SetMethod
- {
- get
- {
- return GetSetMethod(true);
- }
- }
-
- public MethodInfo GetGetMethod() { return GetGetMethod(false); }
-
- public MethodInfo GetSetMethod() { return GetSetMethod(false); }
-
- public bool IsSpecialName { get { return(Attributes & PropertyAttributes.SpecialName) != 0; } }
- #endregion
- }
-
- [Serializable]
- internal unsafe sealed class RuntimePropertyInfo : PropertyInfo, ISerializable
- {
- #region Private Data Members
- private int m_token;
- private string m_name;
- private void* m_utf8name;
- private PropertyAttributes m_flags;
- private RuntimeTypeCache m_reflectedTypeCache;
- private RuntimeMethodInfo m_getterMethod;
- private RuntimeMethodInfo m_setterMethod;
- private MethodInfo[] m_otherMethod;
- private RuntimeType m_declaringType;
- private BindingFlags m_bindingFlags;
- private Signature m_signature;
- private ParameterInfo[] m_parameters;
- #endregion
-
- #region Constructor
- internal RuntimePropertyInfo(
- int tkProperty, RuntimeType declaredType, RuntimeTypeCache reflectedTypeCache, out bool isPrivate)
- {
- Contract.Requires(declaredType != null);
- Contract.Requires(reflectedTypeCache != null);
- Debug.Assert(!reflectedTypeCache.IsGlobal);
-
- MetadataImport scope = declaredType.GetRuntimeModule().MetadataImport;
-
- m_token = tkProperty;
- m_reflectedTypeCache = reflectedTypeCache;
- m_declaringType = declaredType;
-
- ConstArray sig;
- scope.GetPropertyProps(tkProperty, out m_utf8name, out m_flags, out sig);
-
- RuntimeMethodInfo dummy;
- Associates.AssignAssociates(scope, tkProperty, declaredType, reflectedTypeCache.GetRuntimeType(),
- out dummy, out dummy, out dummy,
- out m_getterMethod, out m_setterMethod, out m_otherMethod,
- out isPrivate, out m_bindingFlags);
- }
- #endregion
-
- #region Internal Members
- internal override bool CacheEquals(object o)
- {
- RuntimePropertyInfo m = o as RuntimePropertyInfo;
-
- if ((object)m == null)
- return false;
-
- return m.m_token == m_token &&
- RuntimeTypeHandle.GetModule(m_declaringType).Equals(
- RuntimeTypeHandle.GetModule(m.m_declaringType));
- }
-
- internal Signature Signature
- {
- get
- {
- if (m_signature == null)
- {
- PropertyAttributes flags;
- ConstArray sig;
-
- void* name;
- GetRuntimeModule().MetadataImport.GetPropertyProps(
- m_token, out name, out flags, out sig);
-
- m_signature = new Signature(sig.Signature.ToPointer(), (int)sig.Length, m_declaringType);
- }
-
- return m_signature;
- }
- }
- internal bool EqualsSig(RuntimePropertyInfo target)
- {
- //@Asymmetry - Legacy policy is to remove duplicate properties, including hidden properties.
- // The comparison is done by name and by sig. The EqualsSig comparison is expensive
- // but forutnetly it is only called when an inherited property is hidden by name or
- // when an interfaces declare properies with the same signature.
- // Note that we intentionally don't resolve generic arguments so that we don't treat
- // signatures that only match in certain instantiations as duplicates. This has the
- // down side of treating overriding and overriden properties as different properties
- // in some cases. But PopulateProperties in rttype.cs should have taken care of that
- // by comparing VTable slots.
- //
- // Class C1(Of T, Y)
- // Property Prop1(ByVal t1 As T) As Integer
- // Get
- // ... ...
- // End Get
- // End Property
- // Property Prop1(ByVal y1 As Y) As Integer
- // Get
- // ... ...
- // End Get
- // End Property
- // End Class
- //
-
- Contract.Requires(Name.Equals(target.Name));
- Contract.Requires(this != target);
- Contract.Requires(this.ReflectedType == target.ReflectedType);
-
- return Signature.CompareSig(this.Signature, target.Signature);
- }
- internal BindingFlags BindingFlags { get { return m_bindingFlags; } }
- #endregion
-
- #region Object Overrides
- public override String ToString()
- {
- return FormatNameAndSig(false);
- }
-
- private string FormatNameAndSig(bool serialization)
- {
- StringBuilder sbName = new StringBuilder(PropertyType.FormatTypeName(serialization));
-
- sbName.Append(" ");
- sbName.Append(Name);
-
- RuntimeType[] arguments = Signature.Arguments;
- if (arguments.Length > 0)
- {
- sbName.Append(" [");
- sbName.Append(MethodBase.ConstructParameters(arguments, Signature.CallingConvention, serialization));
- sbName.Append("]");
- }
-
- return sbName.ToString();
- }
- #endregion
-
- #region ICustomAttributeProvider
- public override Object[] GetCustomAttributes(bool inherit)
- {
- return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
- }
-
- public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
-
- return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
- }
-
- public override bool IsDefined(Type attributeType, bool inherit)
- {
- if (attributeType == null)
- throw new ArgumentNullException(nameof(attributeType));
- Contract.EndContractBlock();
-
- RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
-
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
-
- return CustomAttribute.IsDefined(this, attributeRuntimeType);
- }
-
- public override IList<CustomAttributeData> GetCustomAttributesData()
- {
- return CustomAttributeData.GetCustomAttributesInternal(this);
- }
- #endregion
-
- #region MemberInfo Overrides
- public override MemberTypes MemberType { get { return MemberTypes.Property; } }
- public override String Name
- {
- get
- {
- if (m_name == null)
- m_name = new Utf8String(m_utf8name).ToString();
-
- return m_name;
- }
- }
- public override Type DeclaringType
- {
- get
- {
- return m_declaringType;
- }
- }
-
- public override Type ReflectedType
- {
- get
- {
- return ReflectedTypeInternal;
- }
- }
-
- private RuntimeType ReflectedTypeInternal
- {
- get
- {
- return m_reflectedTypeCache.GetRuntimeType();
- }
- }
-
- public override int MetadataToken { get { return m_token; } }
-
- public override Module Module { get { return GetRuntimeModule(); } }
- internal RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); }
- #endregion
-
- #region PropertyInfo Overrides
-
- #region Non Dynamic
-
- public override Type[] GetRequiredCustomModifiers()
- {
- return Signature.GetCustomModifiers(0, true);
- }
-
- public override Type[] GetOptionalCustomModifiers()
- {
- return Signature.GetCustomModifiers(0, false);
- }
-
- internal object GetConstantValue(bool raw)
- {
- Object defaultValue = MdConstant.GetValue(GetRuntimeModule().MetadataImport, m_token, PropertyType.GetTypeHandleInternal(), raw);
-
- if (defaultValue == DBNull.Value)
- // Arg_EnumLitValueNotFound -> "Literal value was not found."
- throw new InvalidOperationException(Environment.GetResourceString("Arg_EnumLitValueNotFound"));
-
- return defaultValue;
- }
-
- public override object GetConstantValue() { return GetConstantValue(false); }
-
- public override object GetRawConstantValue() { return GetConstantValue(true); }
-
- public override MethodInfo[] GetAccessors(bool nonPublic)
- {
- List<MethodInfo> accessorList = new List<MethodInfo>();
-
- if (Associates.IncludeAccessor(m_getterMethod, nonPublic))
- accessorList.Add(m_getterMethod);
-
- if (Associates.IncludeAccessor(m_setterMethod, nonPublic))
- accessorList.Add(m_setterMethod);
-
- if ((object)m_otherMethod != null)
- {
- for(int i = 0; i < m_otherMethod.Length; i ++)
- {
- if (Associates.IncludeAccessor(m_otherMethod[i] as MethodInfo, nonPublic))
- accessorList.Add(m_otherMethod[i]);
- }
- }
- return accessorList.ToArray();
- }
-
- public override Type PropertyType
- {
- get { return Signature.ReturnType; }
- }
-
- public override MethodInfo GetGetMethod(bool nonPublic)
- {
- if (!Associates.IncludeAccessor(m_getterMethod, nonPublic))
- return null;
-
- return m_getterMethod;
- }
-
- public override MethodInfo GetSetMethod(bool nonPublic)
- {
- if (!Associates.IncludeAccessor(m_setterMethod, nonPublic))
- return null;
-
- return m_setterMethod;
- }
-
- public override ParameterInfo[] GetIndexParameters()
- {
- ParameterInfo[] indexParams = GetIndexParametersNoCopy();
-
- int numParams = indexParams.Length;
-
- if (numParams == 0)
- return indexParams;
-
- ParameterInfo[] ret = new ParameterInfo[numParams];
-
- Array.Copy(indexParams, ret, numParams);
-
- return ret;
- }
-
- internal ParameterInfo[] GetIndexParametersNoCopy()
- {
- // @History - Logic ported from RTM
-
- // No need to lock because we don't guarantee the uniqueness of ParameterInfo objects
- if (m_parameters == null)
- {
- int numParams = 0;
- ParameterInfo[] methParams = null;
-
- // First try to get the Get method.
- MethodInfo m = GetGetMethod(true);
- if (m != null)
- {
- // There is a Get method so use it.
- methParams = m.GetParametersNoCopy();
- numParams = methParams.Length;
- }
- else
- {
- // If there is no Get method then use the Set method.
- m = GetSetMethod(true);
-
- if (m != null)
- {
- methParams = m.GetParametersNoCopy();
- numParams = methParams.Length - 1;
- }
- }
-
- // Now copy over the parameter info's and change their
- // owning member info to the current property info.
-
- ParameterInfo[] propParams = new ParameterInfo[numParams];
-
- for (int i = 0; i < numParams; i++)
- propParams[i] = new RuntimeParameterInfo((RuntimeParameterInfo)methParams[i], this);
-
- m_parameters = propParams;
- }
-
- return m_parameters;
- }
-
- public override PropertyAttributes Attributes
- {
- get
- {
- return m_flags;
- }
- }
-
- public override bool CanRead
- {
- get
- {
- return m_getterMethod != null;
- }
- }
-
- public override bool CanWrite
- {
- get
- {
- return m_setterMethod != null;
- }
- }
- #endregion
-
- #region Dynamic
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public override Object GetValue(Object obj,Object[] index)
- {
- return GetValue(obj, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static,
- null, index, null);
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public override Object GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
- {
-
- MethodInfo m = GetGetMethod(true);
- if (m == null)
- throw new ArgumentException(System.Environment.GetResourceString("Arg_GetMethNotFnd"));
- return m.Invoke(obj, invokeAttr, binder, index, null);
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public override void SetValue(Object obj, Object value, Object[] index)
- {
- SetValue(obj,
- value,
- BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static,
- null,
- index,
- null);
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public override void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
- {
-
- MethodInfo m = GetSetMethod(true);
-
- if (m == null)
- throw new ArgumentException(System.Environment.GetResourceString("Arg_SetMethNotFnd"));
-
- Object[] args = null;
-
- if (index != null)
- {
- args = new Object[index.Length + 1];
-
- for(int i=0;i<index.Length;i++)
- args[i] = index[i];
-
- args[index.Length] = value;
- }
- else
- {
- args = new Object[1];
- args[0] = value;
- }
-
- m.Invoke(obj, invokeAttr, binder, args, culture);
- }
- #endregion
-
- #endregion
-
- #region ISerializable Implementation
- public void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- MemberInfoSerializationHolder.GetSerializationInfo(
- info,
- Name,
- ReflectedTypeInternal,
- ToString(),
- SerializationToString(),
- MemberTypes.Property,
- null);
- }
-
- internal string SerializationToString()
- {
- return FormatNameAndSig(true);
- }
- #endregion
- }
-
-}
diff --git a/src/mscorlib/src/System/Reflection/ReflectionContext.cs b/src/mscorlib/src/System/Reflection/ReflectionContext.cs
deleted file mode 100644
index 34f692166c..0000000000
--- a/src/mscorlib/src/System/Reflection/ReflectionContext.cs
+++ /dev/null
@@ -1,36 +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.
-
-/*=============================================================================
-**
-**
-**
-**
-**
-** Purpose: For Assembly-related stuff.
-**
-**
-=============================================================================*/
-
-namespace System.Reflection
-{
- using System;
-
- public abstract class ReflectionContext
- {
- protected ReflectionContext() { }
-
- public abstract Assembly MapAssembly(Assembly assembly);
-
- public abstract TypeInfo MapType(TypeInfo type);
-
- public virtual TypeInfo GetTypeForObject(object value)
- {
- if (value == null)
- throw new ArgumentNullException(nameof(value));
-
- return MapType(value.GetType().GetTypeInfo());
- }
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/ReflectionTypeLoadException.cs b/src/mscorlib/src/System/Reflection/ReflectionTypeLoadException.cs
deleted file mode 100644
index cccf060645..0000000000
--- a/src/mscorlib/src/System/Reflection/ReflectionTypeLoadException.cs
+++ /dev/null
@@ -1,72 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// ReflectionTypeLoadException is thrown when multiple TypeLoadExceptions may occur.
-//
-// Specifically, when you call Module.GetTypes() this causes multiple class loads to occur.
-// If there are failures, we continue to load classes and build an array of the successfully
-// loaded classes. We also build an array of the errors that occur. Then we throw this exception
-// which exposes both the array of classes and the array of TypeLoadExceptions.
-//
-//
-//
-//
-namespace System.Reflection {
-
- using System;
- using System.Runtime.Serialization;
- using System.Diagnostics.Contracts;
- [Serializable]
- public sealed class ReflectionTypeLoadException : SystemException, ISerializable {
- private Type[] _classes;
- private Exception[] _exceptions;
-
- // private constructor. This is not called.
- private ReflectionTypeLoadException()
- : base(Environment.GetResourceString("ReflectionTypeLoad_LoadFailed")) {
- SetErrorCode(__HResults.COR_E_REFLECTIONTYPELOAD);
- }
-
- public ReflectionTypeLoadException(Type[] classes, Exception[] exceptions) : base(null)
- {
- _classes = classes;
- _exceptions = exceptions;
- SetErrorCode(__HResults.COR_E_REFLECTIONTYPELOAD);
- }
-
- public ReflectionTypeLoadException(Type[] classes, Exception[] exceptions, String message) : base(message)
- {
- _classes = classes;
- _exceptions = exceptions;
- SetErrorCode(__HResults.COR_E_REFLECTIONTYPELOAD);
- }
-
- internal ReflectionTypeLoadException(SerializationInfo info, StreamingContext context) : base (info, context) {
- _classes = (Type[])(info.GetValue("Types", typeof(Type[])));
- _exceptions = (Exception[])(info.GetValue("Exceptions", typeof(Exception[])));
- }
-
- public Type[] Types {
- get {return _classes;}
- }
-
- public Exception[] LoaderExceptions {
- get {return _exceptions;}
- }
-
- public override void GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
- throw new ArgumentNullException(nameof(info));
- }
- Contract.EndContractBlock();
- base.GetObjectData(info, context);
- info.AddValue("Types", _classes, typeof(Type[]));
- info.AddValue("Exceptions", _exceptions, typeof(Exception[]));
- }
-
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/ResourceAttributes.cs b/src/mscorlib/src/System/Reflection/ResourceAttributes.cs
deleted file mode 100644
index 5c419ebb2d..0000000000
--- a/src/mscorlib/src/System/Reflection/ResourceAttributes.cs
+++ /dev/null
@@ -1,23 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// ResourceAttributes is an enum which defines the attributes that may be associated
-//
-// with a manifest resource. The values here are defined in Corhdr.h.
-//
-//
-namespace System.Reflection {
-
- using System;
-[Serializable]
-[Flags]
- public enum ResourceAttributes
- {
- Public = 0x0001,
- Private = 0x0002,
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/RtFieldInfo.cs b/src/mscorlib/src/System/Reflection/RtFieldInfo.cs
new file mode 100644
index 0000000000..20d6e6392f
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/RtFieldInfo.cs
@@ -0,0 +1,390 @@
+// 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.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
+
+namespace System.Reflection
+{
+ [Serializable]
+ internal unsafe sealed class RtFieldInfo : RuntimeFieldInfo, IRuntimeFieldInfo
+ {
+ #region FCalls
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ static private extern void PerformVisibilityCheckOnField(IntPtr field, Object target, RuntimeType declaringType, FieldAttributes attr, uint invocationFlags);
+ #endregion
+
+ #region Private Data Members
+ // agressive caching
+ private IntPtr m_fieldHandle;
+ private FieldAttributes m_fieldAttributes;
+ // lazy caching
+ private string m_name;
+ private RuntimeType m_fieldType;
+ private INVOCATION_FLAGS m_invocationFlags;
+
+ internal INVOCATION_FLAGS InvocationFlags
+ {
+ get
+ {
+ if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0)
+ {
+ Type declaringType = DeclaringType;
+ bool fIsReflectionOnlyType = (declaringType is ReflectionOnlyType);
+
+ INVOCATION_FLAGS invocationFlags = 0;
+
+ // first take care of all the NO_INVOKE cases
+ if (
+ (declaringType != null && declaringType.ContainsGenericParameters) ||
+ (declaringType == null && Module.Assembly.ReflectionOnly) ||
+ (fIsReflectionOnlyType)
+ )
+ {
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE;
+ }
+
+ // If the invocationFlags are still 0, then
+ // this should be an usable field, determine the other flags
+ if (invocationFlags == 0)
+ {
+ if ((m_fieldAttributes & FieldAttributes.InitOnly) != (FieldAttributes)0)
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_SPECIAL_FIELD;
+
+ if ((m_fieldAttributes & FieldAttributes.HasFieldRVA) != (FieldAttributes)0)
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_SPECIAL_FIELD;
+
+ // A public field is inaccesible to Transparent code if the field is Critical.
+ bool needsTransparencySecurityCheck = IsSecurityCritical && !IsSecuritySafeCritical;
+ bool needsVisibilitySecurityCheck = ((m_fieldAttributes & FieldAttributes.FieldAccessMask) != FieldAttributes.Public) ||
+ (declaringType != null && declaringType.NeedsReflectionSecurityCheck);
+ if (needsTransparencySecurityCheck || needsVisibilitySecurityCheck)
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
+
+ // find out if the field type is one of the following: Primitive, Enum or Pointer
+ Type fieldType = FieldType;
+ if (fieldType.IsPointer || fieldType.IsEnum || fieldType.IsPrimitive)
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_FIELD_SPECIAL_CAST;
+ }
+
+ // must be last to avoid threading problems
+ m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED;
+ }
+
+ return m_invocationFlags;
+ }
+ }
+ #endregion
+
+ private RuntimeAssembly GetRuntimeAssembly() { return m_declaringType.GetRuntimeAssembly(); }
+
+ #region Constructor
+ internal RtFieldInfo(
+ RuntimeFieldHandleInternal handle, RuntimeType declaringType, RuntimeTypeCache reflectedTypeCache, BindingFlags bindingFlags)
+ : base(reflectedTypeCache, declaringType, bindingFlags)
+ {
+ m_fieldHandle = handle.Value;
+ m_fieldAttributes = RuntimeFieldHandle.GetAttributes(handle);
+ }
+ #endregion
+
+ #region Private Members
+ RuntimeFieldHandleInternal IRuntimeFieldInfo.Value
+ {
+ get
+ {
+ return new RuntimeFieldHandleInternal(m_fieldHandle);
+ }
+ }
+
+ #endregion
+
+ #region Internal Members
+ internal void CheckConsistency(Object target)
+ {
+ // only test instance fields
+ if ((m_fieldAttributes & FieldAttributes.Static) != FieldAttributes.Static)
+ {
+ if (!m_declaringType.IsInstanceOfType(target))
+ {
+ if (target == null)
+ {
+ throw new TargetException(SR.RFLCT_Targ_StatFldReqTarg);
+ }
+ else
+ {
+ throw new ArgumentException(
+ String.Format(CultureInfo.CurrentUICulture, SR.Arg_FieldDeclTarget,
+ Name, m_declaringType, target.GetType()));
+ }
+ }
+ }
+ }
+
+ internal override bool CacheEquals(object o)
+ {
+ RtFieldInfo m = o as RtFieldInfo;
+
+ if ((object)m == null)
+ return false;
+
+ return m.m_fieldHandle == m_fieldHandle;
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ internal void InternalSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture, ref StackCrawlMark stackMark)
+ {
+ INVOCATION_FLAGS invocationFlags = InvocationFlags;
+ RuntimeType declaringType = DeclaringType as RuntimeType;
+
+ if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE) != 0)
+ {
+ if (declaringType != null && declaringType.ContainsGenericParameters)
+ throw new InvalidOperationException(SR.Arg_UnboundGenField);
+
+ if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
+ throw new InvalidOperationException(SR.Arg_ReflectionOnlyField);
+
+ throw new FieldAccessException();
+ }
+
+ CheckConsistency(obj);
+
+ RuntimeType fieldType = (RuntimeType)FieldType;
+ value = fieldType.CheckValue(value, binder, culture, invokeAttr);
+
+ #region Security Check
+ if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_SPECIAL_FIELD | INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY)) != 0)
+ PerformVisibilityCheckOnField(m_fieldHandle, obj, m_declaringType, m_fieldAttributes, (uint)m_invocationFlags);
+ #endregion
+
+ bool domainInitialized = false;
+ if (declaringType == null)
+ {
+ RuntimeFieldHandle.SetValue(this, obj, value, fieldType, m_fieldAttributes, null, ref domainInitialized);
+ }
+ else
+ {
+ domainInitialized = declaringType.DomainInitialized;
+ RuntimeFieldHandle.SetValue(this, obj, value, fieldType, m_fieldAttributes, declaringType, ref domainInitialized);
+ declaringType.DomainInitialized = domainInitialized;
+ }
+ }
+
+ // UnsafeSetValue doesn't perform any consistency or visibility check.
+ // It is the caller's responsibility to ensure the operation is safe.
+ // When the caller needs to perform visibility checks they should call
+ // InternalSetValue() instead. When the caller needs to perform
+ // consistency checks they should call CheckConsistency() before
+ // calling this method.
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ internal void UnsafeSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
+ {
+ RuntimeType declaringType = DeclaringType as RuntimeType;
+ RuntimeType fieldType = (RuntimeType)FieldType;
+ value = fieldType.CheckValue(value, binder, culture, invokeAttr);
+
+ bool domainInitialized = false;
+ if (declaringType == null)
+ {
+ RuntimeFieldHandle.SetValue(this, obj, value, fieldType, m_fieldAttributes, null, ref domainInitialized);
+ }
+ else
+ {
+ domainInitialized = declaringType.DomainInitialized;
+ RuntimeFieldHandle.SetValue(this, obj, value, fieldType, m_fieldAttributes, declaringType, ref domainInitialized);
+ declaringType.DomainInitialized = domainInitialized;
+ }
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ internal Object InternalGetValue(Object obj, ref StackCrawlMark stackMark)
+ {
+ INVOCATION_FLAGS invocationFlags = InvocationFlags;
+ RuntimeType declaringType = DeclaringType as RuntimeType;
+
+ if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE) != 0)
+ {
+ if (declaringType != null && DeclaringType.ContainsGenericParameters)
+ throw new InvalidOperationException(SR.Arg_UnboundGenField);
+
+ if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
+ throw new InvalidOperationException(SR.Arg_ReflectionOnlyField);
+
+ throw new FieldAccessException();
+ }
+
+ CheckConsistency(obj);
+
+ RuntimeType fieldType = (RuntimeType)FieldType;
+ if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) != 0)
+ PerformVisibilityCheckOnField(m_fieldHandle, obj, m_declaringType, m_fieldAttributes, (uint)(m_invocationFlags & ~INVOCATION_FLAGS.INVOCATION_FLAGS_SPECIAL_FIELD));
+
+ return UnsafeGetValue(obj);
+ }
+
+ // UnsafeGetValue doesn't perform any consistency or visibility check.
+ // It is the caller's responsibility to ensure the operation is safe.
+ // When the caller needs to perform visibility checks they should call
+ // InternalGetValue() instead. When the caller needs to perform
+ // consistency checks they should call CheckConsistency() before
+ // calling this method.
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ internal Object UnsafeGetValue(Object obj)
+ {
+ RuntimeType declaringType = DeclaringType as RuntimeType;
+
+ RuntimeType fieldType = (RuntimeType)FieldType;
+
+ bool domainInitialized = false;
+ if (declaringType == null)
+ {
+ return RuntimeFieldHandle.GetValue(this, obj, fieldType, null, ref domainInitialized);
+ }
+ else
+ {
+ domainInitialized = declaringType.DomainInitialized;
+ object retVal = RuntimeFieldHandle.GetValue(this, obj, fieldType, declaringType, ref domainInitialized);
+ declaringType.DomainInitialized = domainInitialized;
+ return retVal;
+ }
+ }
+
+ #endregion
+
+ #region MemberInfo Overrides
+ public override String Name
+ {
+ get
+ {
+ if (m_name == null)
+ m_name = RuntimeFieldHandle.GetName(this);
+
+ return m_name;
+ }
+ }
+
+ internal String FullName
+ {
+ get
+ {
+ return String.Format("{0}.{1}", DeclaringType.FullName, Name);
+ }
+ }
+
+ public override int MetadataToken
+ {
+ get { return RuntimeFieldHandle.GetToken(this); }
+ }
+
+ internal override RuntimeModule GetRuntimeModule()
+ {
+ return RuntimeTypeHandle.GetModule(RuntimeFieldHandle.GetApproxDeclaringType(this));
+ }
+
+ #endregion
+
+ #region FieldInfo Overrides
+ public override Object GetValue(Object obj)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return InternalGetValue(obj, ref stackMark);
+ }
+
+ public override object GetRawConstantValue() { throw new InvalidOperationException(); }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ public override Object GetValueDirect(TypedReference obj)
+ {
+ if (obj.IsNull)
+ throw new ArgumentException(SR.Arg_TypedReference_Null);
+ Contract.EndContractBlock();
+
+ unsafe
+ {
+ // Passing TypedReference by reference is easier to make correct in native code
+ return RuntimeFieldHandle.GetValueDirect(this, (RuntimeType)FieldType, &obj, (RuntimeType)DeclaringType);
+ }
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ public override void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ InternalSetValue(obj, value, invokeAttr, binder, culture, ref stackMark);
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ public override void SetValueDirect(TypedReference obj, Object value)
+ {
+ if (obj.IsNull)
+ throw new ArgumentException(SR.Arg_TypedReference_Null);
+ Contract.EndContractBlock();
+
+ unsafe
+ {
+ // Passing TypedReference by reference is easier to make correct in native code
+ RuntimeFieldHandle.SetValueDirect(this, (RuntimeType)FieldType, &obj, value, (RuntimeType)DeclaringType);
+ }
+ }
+
+ public override RuntimeFieldHandle FieldHandle
+ {
+ get
+ {
+ Type declaringType = DeclaringType;
+ if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
+ throw new InvalidOperationException(SR.InvalidOperation_NotAllowedInReflectionOnly);
+ return new RuntimeFieldHandle(this);
+ }
+ }
+
+ internal IntPtr GetFieldHandle()
+ {
+ return m_fieldHandle;
+ }
+
+ public override FieldAttributes Attributes
+ {
+ get
+ {
+ return m_fieldAttributes;
+ }
+ }
+
+ public override Type FieldType
+ {
+ get
+ {
+ if (m_fieldType == null)
+ m_fieldType = new Signature(this, m_declaringType).FieldType;
+
+ return m_fieldType;
+ }
+ }
+
+ public override Type[] GetRequiredCustomModifiers()
+ {
+ return new Signature(this, m_declaringType).GetCustomModifiers(1, true);
+ }
+
+ public override Type[] GetOptionalCustomModifiers()
+ {
+ return new Signature(this, m_declaringType).GetCustomModifiers(1, false);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/RuntimeAssembly.cs b/src/mscorlib/src/System/Reflection/RuntimeAssembly.cs
new file mode 100644
index 0000000000..4632525453
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/RuntimeAssembly.cs
@@ -0,0 +1,931 @@
+// 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.Collections.Generic;
+using CultureInfo = System.Globalization.CultureInfo;
+using System.Security;
+using System.Security.Policy;
+using System.IO;
+using StringBuilder = System.Text.StringBuilder;
+using System.Configuration.Assemblies;
+using StackCrawlMark = System.Threading.StackCrawlMark;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
+using System.Threading;
+using System.Diagnostics.Contracts;
+
+namespace System.Reflection
+{
+ [Serializable]
+ internal class RuntimeAssembly : Assembly
+ {
+#if FEATURE_APPX
+ // The highest byte is the flags and the lowest 3 bytes are
+ // the cached ctor token of [DynamicallyInvocableAttribute].
+ private enum ASSEMBLY_FLAGS : uint
+ {
+ ASSEMBLY_FLAGS_UNKNOWN = 0x00000000,
+ ASSEMBLY_FLAGS_INITIALIZED = 0x01000000,
+ ASSEMBLY_FLAGS_FRAMEWORK = 0x02000000,
+ ASSEMBLY_FLAGS_TOKEN_MASK = 0x00FFFFFF,
+ }
+#endif // FEATURE_APPX
+
+ private const uint COR_E_LOADING_REFERENCE_ASSEMBLY = 0x80131058U;
+
+ internal RuntimeAssembly() { throw new NotSupportedException(); }
+
+ #region private data members
+ private event ModuleResolveEventHandler _ModuleResolve;
+ private string m_fullname;
+ private object m_syncRoot; // Used to keep collectible types alive and as the syncroot for reflection.emit
+ private IntPtr m_assembly; // slack for ptr datum on unmanaged side
+
+#if FEATURE_APPX
+ private ASSEMBLY_FLAGS m_flags;
+#endif
+ #endregion
+
+#if FEATURE_APPX
+ private ASSEMBLY_FLAGS Flags
+ {
+ get
+ {
+ if ((m_flags & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_INITIALIZED) == 0)
+ {
+ ASSEMBLY_FLAGS flags = ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_UNKNOWN
+ | ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_FRAMEWORK;
+
+ m_flags = flags | ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_INITIALIZED;
+ }
+
+ return m_flags;
+ }
+ }
+#endif // FEATURE_APPX
+
+ internal object SyncRoot
+ {
+ get
+ {
+ if (m_syncRoot == null)
+ {
+ Interlocked.CompareExchange<object>(ref m_syncRoot, new object(), null);
+ }
+ return m_syncRoot;
+ }
+ }
+
+ public override event ModuleResolveEventHandler ModuleResolve
+ {
+ add
+ {
+ _ModuleResolve += value;
+ }
+ remove
+ {
+ _ModuleResolve -= value;
+ }
+ }
+
+ private const String s_localFilePrefix = "file:";
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern void GetCodeBase(RuntimeAssembly assembly,
+ bool copiedName,
+ StringHandleOnStack retString);
+
+ internal String GetCodeBase(bool copiedName)
+ {
+ String codeBase = null;
+ GetCodeBase(GetNativeHandle(), copiedName, JitHelpers.GetStringHandleOnStack(ref codeBase));
+ return codeBase;
+ }
+
+ public override String CodeBase
+ {
+ get
+ {
+ String codeBase = GetCodeBase(false);
+ return codeBase;
+ }
+ }
+
+ internal RuntimeAssembly GetNativeHandle()
+ {
+ return this;
+ }
+
+ // If the assembly is copied before it is loaded, the codebase will be set to the
+ // actual file loaded if copiedName is true. If it is false, then the original code base
+ // is returned.
+ public override AssemblyName GetName(bool copiedName)
+ {
+ AssemblyName an = new AssemblyName();
+
+ String codeBase = GetCodeBase(copiedName);
+
+ an.Init(GetSimpleName(),
+ GetPublicKey(),
+ null, // public key token
+ GetVersion(),
+ GetLocale(),
+ GetHashAlgorithm(),
+ AssemblyVersionCompatibility.SameMachine,
+ codeBase,
+ GetFlags() | AssemblyNameFlags.PublicKey,
+ null); // strong name key pair
+
+ PortableExecutableKinds pek;
+ ImageFileMachine ifm;
+
+ Module manifestModule = ManifestModule;
+ if (manifestModule != null)
+ {
+ if (manifestModule.MDStreamVersion > 0x10000)
+ {
+ ManifestModule.GetPEKind(out pek, out ifm);
+ an.SetProcArchIndex(pek, ifm);
+ }
+ }
+ return an;
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private extern static void GetFullName(RuntimeAssembly assembly, StringHandleOnStack retString);
+
+ public override String FullName
+ {
+ get
+ {
+ // If called by Object.ToString(), return val may be NULL.
+ if (m_fullname == null)
+ {
+ string s = null;
+ GetFullName(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref s));
+ Interlocked.CompareExchange<string>(ref m_fullname, s, null);
+ }
+
+ return m_fullname;
+ }
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern void GetEntryPoint(RuntimeAssembly assembly, ObjectHandleOnStack retMethod);
+
+ public override MethodInfo EntryPoint
+ {
+ get
+ {
+ IRuntimeMethodInfo methodHandle = null;
+ GetEntryPoint(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref methodHandle));
+
+ if (methodHandle == null)
+ return null;
+
+ return (MethodInfo)RuntimeType.GetMethodBase(methodHandle);
+ }
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern void GetType(RuntimeAssembly assembly,
+ String name,
+ bool throwOnError,
+ bool ignoreCase,
+ ObjectHandleOnStack type,
+ ObjectHandleOnStack keepAlive);
+
+ public override Type GetType(String name, bool throwOnError, bool ignoreCase)
+ {
+ // throw on null strings regardless of the value of "throwOnError"
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+
+ RuntimeType type = null;
+ Object keepAlive = null;
+ GetType(GetNativeHandle(), name, throwOnError, ignoreCase, JitHelpers.GetObjectHandleOnStack(ref type), JitHelpers.GetObjectHandleOnStack(ref keepAlive));
+ GC.KeepAlive(keepAlive);
+
+ return type;
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private extern static void GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes);
+
+ public override Type[] GetExportedTypes()
+ {
+ Type[] types = null;
+ GetExportedTypes(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref types));
+ return types;
+ }
+
+ public override IEnumerable<TypeInfo> DefinedTypes
+ {
+ get
+ {
+ List<RuntimeType> rtTypes = new List<RuntimeType>();
+
+ RuntimeModule[] modules = GetModulesInternal(true, false);
+
+ for (int i = 0; i < modules.Length; i++)
+ {
+ rtTypes.AddRange(modules[i].GetDefinedTypes());
+ }
+
+ return rtTypes.ToArray();
+ }
+ }
+
+ // Load a resource based on the NameSpace of the type.
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public override Stream GetManifestResourceStream(Type type, String name)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return GetManifestResourceStream(type, name, false, ref stackMark);
+ }
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public override Stream GetManifestResourceStream(String name)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return GetManifestResourceStream(name, ref stackMark, false);
+ }
+
+ // ISerializable implementation
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
+
+ Contract.EndContractBlock();
+
+ UnitySerializationHolder.GetUnitySerializationInfo(info,
+ UnitySerializationHolder.AssemblyUnity,
+ this.FullName,
+ this);
+ }
+
+ public override Module ManifestModule
+ {
+ get
+ {
+ // We don't need to return the "external" ModuleBuilder because
+ // it is meant to be read-only
+ return RuntimeAssembly.GetManifestModule(GetNativeHandle());
+ }
+ }
+
+ public override Object[] GetCustomAttributes(bool inherit)
+ {
+ return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
+ }
+
+ public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
+ }
+
+ public override bool IsDefined(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.IsDefined(this, attributeRuntimeType);
+ }
+
+ public override IList<CustomAttributeData> GetCustomAttributesData()
+ {
+ return CustomAttributeData.GetCustomAttributesInternal(this);
+ }
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ internal static RuntimeAssembly InternalLoadFrom(String assemblyFile,
+ Evidence securityEvidence,
+ byte[] hashValue,
+ AssemblyHashAlgorithm hashAlgorithm,
+ bool forIntrospection,
+ ref StackCrawlMark stackMark)
+ {
+ if (assemblyFile == null)
+ throw new ArgumentNullException(nameof(assemblyFile));
+
+ Contract.EndContractBlock();
+
+ AssemblyName an = new AssemblyName();
+ an.CodeBase = assemblyFile;
+ an.SetHashControl(hashValue, hashAlgorithm);
+ // The stack mark is used for MDA filtering
+ return InternalLoadAssemblyName(an, securityEvidence, null, ref stackMark, true /*thrownOnFileNotFound*/, forIntrospection);
+ }
+
+ // Wrapper function to wrap the typical use of InternalLoad.
+ internal static RuntimeAssembly InternalLoad(String assemblyString,
+ Evidence assemblySecurity,
+ ref StackCrawlMark stackMark,
+ bool forIntrospection)
+ {
+ return InternalLoad(assemblyString, assemblySecurity, ref stackMark, IntPtr.Zero, forIntrospection);
+ }
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ internal static RuntimeAssembly InternalLoad(String assemblyString,
+ Evidence assemblySecurity,
+ ref StackCrawlMark stackMark,
+ IntPtr pPrivHostBinder,
+ bool forIntrospection)
+ {
+ RuntimeAssembly assembly;
+ AssemblyName an = CreateAssemblyName(assemblyString, forIntrospection, out assembly);
+
+ if (assembly != null)
+ {
+ // The assembly was returned from ResolveAssemblyEvent
+ return assembly;
+ }
+
+ return InternalLoadAssemblyName(an, assemblySecurity, null, ref stackMark,
+ pPrivHostBinder,
+ true /*thrownOnFileNotFound*/, forIntrospection);
+ }
+
+ // Creates AssemblyName. Fills assembly if AssemblyResolve event has been raised.
+ internal static AssemblyName CreateAssemblyName(
+ String assemblyString,
+ bool forIntrospection,
+ out RuntimeAssembly assemblyFromResolveEvent)
+ {
+ if (assemblyString == null)
+ throw new ArgumentNullException(nameof(assemblyString));
+ Contract.EndContractBlock();
+
+ if ((assemblyString.Length == 0) ||
+ (assemblyString[0] == '\0'))
+ throw new ArgumentException(SR.Format_StringZeroLength);
+
+ if (forIntrospection)
+ AppDomain.CheckReflectionOnlyLoadSupported();
+
+ AssemblyName an = new AssemblyName();
+
+ an.Name = assemblyString;
+ an.nInit(out assemblyFromResolveEvent, forIntrospection, true);
+
+ return an;
+ }
+
+ // Wrapper function to wrap the typical use of InternalLoadAssemblyName.
+ internal static RuntimeAssembly InternalLoadAssemblyName(
+ AssemblyName assemblyRef,
+ Evidence assemblySecurity,
+ RuntimeAssembly reqAssembly,
+ ref StackCrawlMark stackMark,
+ bool throwOnFileNotFound,
+ bool forIntrospection,
+ IntPtr ptrLoadContextBinder = default(IntPtr))
+ {
+ return InternalLoadAssemblyName(assemblyRef, assemblySecurity, reqAssembly, ref stackMark, IntPtr.Zero, true /*throwOnError*/, forIntrospection, ptrLoadContextBinder);
+ }
+
+ internal static RuntimeAssembly InternalLoadAssemblyName(
+ AssemblyName assemblyRef,
+ Evidence assemblySecurity,
+ RuntimeAssembly reqAssembly,
+ ref StackCrawlMark stackMark,
+ IntPtr pPrivHostBinder,
+ bool throwOnFileNotFound,
+ bool forIntrospection,
+ IntPtr ptrLoadContextBinder = default(IntPtr))
+ {
+ if (assemblyRef == null)
+ throw new ArgumentNullException(nameof(assemblyRef));
+ Contract.EndContractBlock();
+
+ if (assemblyRef.CodeBase != null)
+ {
+ AppDomain.CheckLoadFromSupported();
+ }
+
+ assemblyRef = (AssemblyName)assemblyRef.Clone();
+ if (!forIntrospection &&
+ (assemblyRef.ProcessorArchitecture != ProcessorArchitecture.None))
+ {
+ // PA does not have a semantics for by-name binds for execution
+ assemblyRef.ProcessorArchitecture = ProcessorArchitecture.None;
+ }
+
+ String codeBase = VerifyCodeBase(assemblyRef.CodeBase);
+
+ return nLoad(assemblyRef, codeBase, assemblySecurity, reqAssembly, ref stackMark,
+ pPrivHostBinder,
+ throwOnFileNotFound, forIntrospection, ptrLoadContextBinder);
+ }
+
+ // These are the framework assemblies that does reflection invocation
+ // on behalf of user code. We allow framework code to invoke non-W8P
+ // framework APIs but don't want user code to gain that privilege
+ // through these assemblies. So we blaklist them.
+ private static string[] s_unsafeFrameworkAssemblyNames = new string[] {
+ "System.Reflection.Context",
+ "Microsoft.VisualBasic"
+ };
+
+#if FEATURE_APPX
+ internal bool IsFrameworkAssembly()
+ {
+ ASSEMBLY_FLAGS flags = Flags;
+ return (flags & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_FRAMEWORK) != 0;
+ }
+#endif
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern RuntimeAssembly _nLoad(AssemblyName fileName,
+ String codeBase,
+ Evidence assemblySecurity,
+ RuntimeAssembly locationHint,
+ ref StackCrawlMark stackMark,
+ IntPtr pPrivHostBinder,
+ bool throwOnFileNotFound,
+ bool forIntrospection,
+ bool suppressSecurityChecks,
+ IntPtr ptrLoadContextBinder);
+
+ private static RuntimeAssembly nLoad(AssemblyName fileName,
+ String codeBase,
+ Evidence assemblySecurity,
+ RuntimeAssembly locationHint,
+ ref StackCrawlMark stackMark,
+ IntPtr pPrivHostBinder,
+ bool throwOnFileNotFound,
+ bool forIntrospection,
+ IntPtr ptrLoadContextBinder = default(IntPtr))
+ {
+ return _nLoad(fileName, codeBase, assemblySecurity, locationHint, ref stackMark,
+ pPrivHostBinder,
+ throwOnFileNotFound, forIntrospection, true /* suppressSecurityChecks */, ptrLoadContextBinder);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern bool IsReflectionOnly(RuntimeAssembly assembly);
+
+ public override bool ReflectionOnly
+ {
+ get
+ {
+ return IsReflectionOnly(GetNativeHandle());
+ }
+ }
+
+ // Returns the module in this assembly with name 'name'
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern void GetModule(RuntimeAssembly assembly, String name, ObjectHandleOnStack retModule);
+
+ public override Module GetModule(String name)
+ {
+ Module retModule = null;
+ GetModule(GetNativeHandle(), name, JitHelpers.GetObjectHandleOnStack(ref retModule));
+ return retModule;
+ }
+
+ // Returns the file in the File table of the manifest that matches the
+ // given name. (Name should not include path.)
+ public override FileStream GetFile(String name)
+ {
+ RuntimeModule m = (RuntimeModule)GetModule(name);
+ if (m == null)
+ return null;
+
+ return new FileStream(m.GetFullyQualifiedName(),
+ FileMode.Open,
+ FileAccess.Read, FileShare.Read, FileStream.DefaultBufferSize, false);
+ }
+
+ public override FileStream[] GetFiles(bool getResourceModules)
+ {
+ Module[] m = GetModules(getResourceModules);
+ FileStream[] fs = new FileStream[m.Length];
+
+ for (int i = 0; i < fs.Length; i++)
+ {
+ fs[i] = new FileStream(((RuntimeModule)m[i]).GetFullyQualifiedName(),
+ FileMode.Open,
+ FileAccess.Read, FileShare.Read, FileStream.DefaultBufferSize, false);
+ }
+
+ return fs;
+ }
+
+ // Returns the names of all the resources
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern String[] GetManifestResourceNames(RuntimeAssembly assembly);
+
+ // Returns the names of all the resources
+ public override String[] GetManifestResourceNames()
+ {
+ return GetManifestResourceNames(GetNativeHandle());
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private extern static void GetExecutingAssembly(StackCrawlMarkHandle stackMark, ObjectHandleOnStack retAssembly);
+
+ internal static RuntimeAssembly GetExecutingAssembly(ref StackCrawlMark stackMark)
+ {
+ RuntimeAssembly retAssembly = null;
+ GetExecutingAssembly(JitHelpers.GetStackCrawlMarkHandle(ref stackMark), JitHelpers.GetObjectHandleOnStack(ref retAssembly));
+ return retAssembly;
+ }
+
+ // Returns the names of all the resources
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern AssemblyName[] GetReferencedAssemblies(RuntimeAssembly assembly);
+
+ public override AssemblyName[] GetReferencedAssemblies()
+ {
+ return GetReferencedAssemblies(GetNativeHandle());
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern int GetManifestResourceInfo(RuntimeAssembly assembly,
+ String resourceName,
+ ObjectHandleOnStack assemblyRef,
+ StringHandleOnStack retFileName,
+ StackCrawlMarkHandle stackMark);
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public override ManifestResourceInfo GetManifestResourceInfo(String resourceName)
+ {
+ RuntimeAssembly retAssembly = null;
+ String fileName = null;
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ int location = GetManifestResourceInfo(GetNativeHandle(), resourceName,
+ JitHelpers.GetObjectHandleOnStack(ref retAssembly),
+ JitHelpers.GetStringHandleOnStack(ref fileName),
+ JitHelpers.GetStackCrawlMarkHandle(ref stackMark));
+
+ if (location == -1)
+ return null;
+
+ return new ManifestResourceInfo(retAssembly, fileName,
+ (ResourceLocation)location);
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern void GetLocation(RuntimeAssembly assembly, StringHandleOnStack retString);
+
+ public override String Location
+ {
+ get
+ {
+ String location = null;
+
+ GetLocation(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref location));
+
+ return location;
+ }
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private extern static void GetImageRuntimeVersion(RuntimeAssembly assembly, StringHandleOnStack retString);
+
+ public override String ImageRuntimeVersion
+ {
+ get
+ {
+ String s = null;
+ GetImageRuntimeVersion(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref s));
+ return s;
+ }
+ }
+
+ public override bool GlobalAssemblyCache
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public override Int64 HostContext
+ {
+ get
+ {
+ return 0;
+ }
+ }
+
+ private static String VerifyCodeBase(String codebase)
+ {
+ if (codebase == null)
+ return null;
+
+ int len = codebase.Length;
+ if (len == 0)
+ return null;
+
+
+ int j = codebase.IndexOf(':');
+ // Check to see if the url has a prefix
+ if ((j != -1) &&
+ (j + 2 < len) &&
+ ((codebase[j + 1] == '/') || (codebase[j + 1] == '\\')) &&
+ ((codebase[j + 2] == '/') || (codebase[j + 2] == '\\')))
+ return codebase;
+#if PLATFORM_WINDOWS
+ else if ((len > 2) && (codebase[0] == '\\') && (codebase[1] == '\\'))
+ return "file://" + codebase;
+ else
+ return "file:///" + Path.GetFullPath(codebase);
+#else
+ else
+ return "file://" + Path.GetFullPath(codebase);
+#endif // PLATFORM_WINDOWS
+ }
+
+ internal Stream GetManifestResourceStream(
+ Type type,
+ String name,
+ bool skipSecurityCheck,
+ ref StackCrawlMark stackMark)
+ {
+ StringBuilder sb = new StringBuilder();
+ if (type == null)
+ {
+ if (name == null)
+ throw new ArgumentNullException(nameof(type));
+ }
+ else
+ {
+ String nameSpace = type.Namespace;
+ if (nameSpace != null)
+ {
+ sb.Append(nameSpace);
+ if (name != null)
+ sb.Append(Type.Delimiter);
+ }
+ }
+
+ if (name != null)
+ sb.Append(name);
+
+ return GetManifestResourceStream(sb.ToString(), ref stackMark, skipSecurityCheck);
+ }
+
+ // GetResource will return a pointer to the resources in memory.
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static unsafe extern byte* GetResource(RuntimeAssembly assembly,
+ String resourceName,
+ out ulong length,
+ StackCrawlMarkHandle stackMark,
+ bool skipSecurityCheck);
+
+ internal unsafe Stream GetManifestResourceStream(String name, ref StackCrawlMark stackMark, bool skipSecurityCheck)
+ {
+ ulong length = 0;
+ byte* pbInMemoryResource = GetResource(GetNativeHandle(), name, out length, JitHelpers.GetStackCrawlMarkHandle(ref stackMark), skipSecurityCheck);
+
+ if (pbInMemoryResource != null)
+ {
+ //Console.WriteLine("Creating an unmanaged memory stream of length "+length);
+ if (length > Int64.MaxValue)
+ throw new NotImplementedException(SR.NotImplemented_ResourcesLongerThanInt64Max);
+
+ return new UnmanagedMemoryStream(pbInMemoryResource, (long)length, (long)length, FileAccess.Read);
+ }
+
+ //Console.WriteLine("GetManifestResourceStream: Blob "+name+" not found...");
+ return null;
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern void GetVersion(RuntimeAssembly assembly,
+ out int majVer,
+ out int minVer,
+ out int buildNum,
+ out int revNum);
+
+ internal Version GetVersion()
+ {
+ int majorVer, minorVer, build, revision;
+ GetVersion(GetNativeHandle(), out majorVer, out minorVer, out build, out revision);
+ return new Version(majorVer, minorVer, build, revision);
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern void GetLocale(RuntimeAssembly assembly, StringHandleOnStack retString);
+
+ internal CultureInfo GetLocale()
+ {
+ String locale = null;
+
+ GetLocale(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref locale));
+
+ if (locale == null)
+ return CultureInfo.InvariantCulture;
+
+ return new CultureInfo(locale);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern bool FCallIsDynamic(RuntimeAssembly assembly);
+
+ public override bool IsDynamic
+ {
+ get
+ {
+ return FCallIsDynamic(GetNativeHandle());
+ }
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern void GetSimpleName(RuntimeAssembly assembly, StringHandleOnStack retSimpleName);
+
+ internal String GetSimpleName()
+ {
+ string name = null;
+ GetSimpleName(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref name));
+ return name;
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private extern static AssemblyHashAlgorithm GetHashAlgorithm(RuntimeAssembly assembly);
+
+ private AssemblyHashAlgorithm GetHashAlgorithm()
+ {
+ return GetHashAlgorithm(GetNativeHandle());
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private extern static AssemblyNameFlags GetFlags(RuntimeAssembly assembly);
+
+ private AssemblyNameFlags GetFlags()
+ {
+ return GetFlags(GetNativeHandle());
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern void GetPublicKey(RuntimeAssembly assembly, ObjectHandleOnStack retPublicKey);
+
+ internal byte[] GetPublicKey()
+ {
+ byte[] publicKey = null;
+ GetPublicKey(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref publicKey));
+ return publicKey;
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ private extern static bool IsAllSecurityTransparent(RuntimeAssembly assembly);
+
+ // Is everything introduced by this assembly transparent
+ internal bool IsAllSecurityTransparent()
+ {
+ return IsAllSecurityTransparent(GetNativeHandle());
+ }
+
+ // This method is called by the VM.
+ private RuntimeModule OnModuleResolveEvent(String moduleName)
+ {
+ ModuleResolveEventHandler moduleResolve = _ModuleResolve;
+ if (moduleResolve == null)
+ return null;
+
+ Delegate[] ds = moduleResolve.GetInvocationList();
+ int len = ds.Length;
+ for (int i = 0; i < len; i++)
+ {
+ RuntimeModule ret = (RuntimeModule)((ModuleResolveEventHandler)ds[i])(this, new ResolveEventArgs(moduleName, this));
+ if (ret != null)
+ return ret;
+ }
+
+ return null;
+ }
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public override Assembly GetSatelliteAssembly(CultureInfo culture)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return InternalGetSatelliteAssembly(culture, null, ref stackMark);
+ }
+
+ // Useful for binding to a very specific version of a satellite assembly
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public override Assembly GetSatelliteAssembly(CultureInfo culture, Version version)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return InternalGetSatelliteAssembly(culture, version, ref stackMark);
+ }
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ internal Assembly InternalGetSatelliteAssembly(CultureInfo culture,
+ Version version,
+ ref StackCrawlMark stackMark)
+ {
+ if (culture == null)
+ throw new ArgumentNullException(nameof(culture));
+ Contract.EndContractBlock();
+
+
+ String name = GetSimpleName() + ".resources";
+ return InternalGetSatelliteAssembly(name, culture, version, true, ref stackMark);
+ }
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ internal RuntimeAssembly InternalGetSatelliteAssembly(String name,
+ CultureInfo culture,
+ Version version,
+ bool throwOnFileNotFound,
+ ref StackCrawlMark stackMark)
+ {
+ AssemblyName an = new AssemblyName();
+
+ an.SetPublicKey(GetPublicKey());
+ an.Flags = GetFlags() | AssemblyNameFlags.PublicKey;
+
+ if (version == null)
+ an.Version = GetVersion();
+ else
+ an.Version = version;
+
+ an.CultureInfo = culture;
+ an.Name = name;
+
+ RuntimeAssembly retAssembly = nLoad(an, null, null, this, ref stackMark,
+ IntPtr.Zero,
+ throwOnFileNotFound, false);
+
+ if (retAssembly == this || (retAssembly == null && throwOnFileNotFound))
+ {
+ throw new FileNotFoundException(String.Format(culture, SR.IO_FileNotFound_FileName, an.Name));
+ }
+
+ return retAssembly;
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private extern static void GetModules(RuntimeAssembly assembly,
+ bool loadIfNotFound,
+ bool getResourceModules,
+ ObjectHandleOnStack retModuleHandles);
+
+ private RuntimeModule[] GetModulesInternal(bool loadIfNotFound,
+ bool getResourceModules)
+ {
+ RuntimeModule[] modules = null;
+ GetModules(GetNativeHandle(), loadIfNotFound, getResourceModules, JitHelpers.GetObjectHandleOnStack(ref modules));
+ return modules;
+ }
+
+ public override Module[] GetModules(bool getResourceModules)
+ {
+ return GetModulesInternal(true, getResourceModules);
+ }
+
+ public override Module[] GetLoadedModules(bool getResourceModules)
+ {
+ return GetModulesInternal(false, getResourceModules);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern RuntimeModule GetManifestModule(RuntimeAssembly assembly);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern int GetToken(RuntimeAssembly assembly);
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/RuntimeConstructorInfo.cs b/src/mscorlib/src/System/Reflection/RuntimeConstructorInfo.cs
new file mode 100644
index 0000000000..8c3b1fce98
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/RuntimeConstructorInfo.cs
@@ -0,0 +1,481 @@
+// 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.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Runtime.Serialization;
+using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
+
+namespace System.Reflection
+{
+ [Serializable]
+ internal sealed class RuntimeConstructorInfo : ConstructorInfo, ISerializable, IRuntimeMethodInfo
+ {
+ #region Private Data Members
+ private volatile RuntimeType m_declaringType;
+ private RuntimeTypeCache m_reflectedTypeCache;
+ private string m_toString;
+ private ParameterInfo[] m_parameters = null; // Created lazily when GetParameters() is called.
+#pragma warning disable 169
+ private object _empty1; // These empties are used to ensure that RuntimeConstructorInfo and RuntimeMethodInfo are have a layout which is sufficiently similar
+ private object _empty2;
+ private object _empty3;
+#pragma warning restore 169
+ private IntPtr m_handle;
+ private MethodAttributes m_methodAttributes;
+ private BindingFlags m_bindingFlags;
+ private volatile Signature m_signature;
+ private INVOCATION_FLAGS m_invocationFlags;
+
+ internal INVOCATION_FLAGS InvocationFlags
+ {
+ get
+ {
+ if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0)
+ {
+ INVOCATION_FLAGS invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_IS_CTOR; // this is a given
+
+ Type declaringType = DeclaringType;
+
+ //
+ // first take care of all the NO_INVOKE cases.
+ if (declaringType == typeof(void) ||
+ (declaringType != null && declaringType.ContainsGenericParameters) ||
+ ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) ||
+ ((Attributes & MethodAttributes.RequireSecObject) == MethodAttributes.RequireSecObject))
+ {
+ // We don't need other flags if this method cannot be invoked
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE;
+ }
+ else if (IsStatic || declaringType != null && declaringType.IsAbstract)
+ {
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NO_CTOR_INVOKE;
+ }
+ else
+ {
+ // this should be an invocable method, determine the other flags that participate in invocation
+ invocationFlags |= RuntimeMethodHandle.GetSecurityFlags(this);
+
+ if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) == 0 &&
+ ((Attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public ||
+ (declaringType != null && declaringType.NeedsReflectionSecurityCheck)))
+ {
+ // If method is non-public, or declaring type is not visible
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
+ }
+
+ // Check for attempt to create a delegate class, we demand unmanaged
+ // code permission for this since it's hard to validate the target address.
+ if (typeof(Delegate).IsAssignableFrom(DeclaringType))
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_IS_DELEGATE_CTOR;
+ }
+
+ m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED;
+ }
+
+ return m_invocationFlags;
+ }
+ }
+ #endregion
+
+ #region Constructor
+ internal RuntimeConstructorInfo(
+ RuntimeMethodHandleInternal handle, RuntimeType declaringType, RuntimeTypeCache reflectedTypeCache,
+ MethodAttributes methodAttributes, BindingFlags bindingFlags)
+ {
+ Contract.Ensures(methodAttributes == RuntimeMethodHandle.GetAttributes(handle));
+
+ m_bindingFlags = bindingFlags;
+ m_reflectedTypeCache = reflectedTypeCache;
+ m_declaringType = declaringType;
+ m_handle = handle.Value;
+ m_methodAttributes = methodAttributes;
+ }
+ #endregion
+
+ #region NonPublic Methods
+ RuntimeMethodHandleInternal IRuntimeMethodInfo.Value
+ {
+ get
+ {
+ return new RuntimeMethodHandleInternal(m_handle);
+ }
+ }
+
+ internal override bool CacheEquals(object o)
+ {
+ RuntimeConstructorInfo m = o as RuntimeConstructorInfo;
+
+ if ((object)m == null)
+ return false;
+
+ return m.m_handle == m_handle;
+ }
+
+ private Signature Signature
+ {
+ get
+ {
+ if (m_signature == null)
+ m_signature = new Signature(this, m_declaringType);
+
+ return m_signature;
+ }
+ }
+
+ private RuntimeType ReflectedTypeInternal
+ {
+ get
+ {
+ return m_reflectedTypeCache.GetRuntimeType();
+ }
+ }
+
+ private void CheckConsistency(Object target)
+ {
+ if (target == null && IsStatic)
+ return;
+
+ if (!m_declaringType.IsInstanceOfType(target))
+ {
+ if (target == null)
+ throw new TargetException(SR.RFLCT_Targ_StatMethReqTarg);
+
+ throw new TargetException(SR.RFLCT_Targ_ITargMismatch);
+ }
+ }
+
+ internal BindingFlags BindingFlags { get { return m_bindingFlags; } }
+ #endregion
+
+ #region Object Overrides
+ public override String ToString()
+ {
+ // "Void" really doesn't make sense here. But we'll keep it for compat reasons.
+ if (m_toString == null)
+ m_toString = "Void " + FormatNameAndSig();
+
+ return m_toString;
+ }
+ #endregion
+
+ #region ICustomAttributeProvider
+ public override Object[] GetCustomAttributes(bool inherit)
+ {
+ return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
+ }
+
+ public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
+ }
+
+ public override bool IsDefined(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.IsDefined(this, attributeRuntimeType);
+ }
+
+ public override IList<CustomAttributeData> GetCustomAttributesData()
+ {
+ return CustomAttributeData.GetCustomAttributesInternal(this);
+ }
+ #endregion
+
+
+ #region MemberInfo Overrides
+ public override String Name
+ {
+ get { return RuntimeMethodHandle.GetName(this); }
+ }
+ public override MemberTypes MemberType { get { return MemberTypes.Constructor; } }
+
+ public override Type DeclaringType
+ {
+ get
+ {
+ return m_reflectedTypeCache.IsGlobal ? null : m_declaringType;
+ }
+ }
+
+ public override Type ReflectedType
+ {
+ get
+ {
+ return m_reflectedTypeCache.IsGlobal ? null : ReflectedTypeInternal;
+ }
+ }
+
+ public override int MetadataToken
+ {
+ get { return RuntimeMethodHandle.GetMethodDef(this); }
+ }
+ public override Module Module
+ {
+ get { return GetRuntimeModule(); }
+ }
+
+ internal RuntimeType GetRuntimeType() { return m_declaringType; }
+ internal RuntimeModule GetRuntimeModule() { return RuntimeTypeHandle.GetModule(m_declaringType); }
+ internal RuntimeAssembly GetRuntimeAssembly() { return GetRuntimeModule().GetRuntimeAssembly(); }
+ #endregion
+
+ #region MethodBase Overrides
+
+ // This seems to always returns System.Void.
+ internal override Type GetReturnType() { return Signature.ReturnType; }
+
+ internal override ParameterInfo[] GetParametersNoCopy()
+ {
+ if (m_parameters == null)
+ m_parameters = RuntimeParameterInfo.GetParameters(this, this, Signature);
+
+ return m_parameters;
+ }
+
+ [Pure]
+ public override ParameterInfo[] GetParameters()
+ {
+ ParameterInfo[] parameters = GetParametersNoCopy();
+
+ if (parameters.Length == 0)
+ return parameters;
+
+ ParameterInfo[] ret = new ParameterInfo[parameters.Length];
+ Array.Copy(parameters, ret, parameters.Length);
+ return ret;
+ }
+
+ public override MethodImplAttributes GetMethodImplementationFlags()
+ {
+ return RuntimeMethodHandle.GetImplAttributes(this);
+ }
+
+ public override RuntimeMethodHandle MethodHandle
+ {
+ get
+ {
+ Type declaringType = DeclaringType;
+ if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
+ throw new InvalidOperationException(SR.InvalidOperation_NotAllowedInReflectionOnly);
+ return new RuntimeMethodHandle(this);
+ }
+ }
+
+ public override MethodAttributes Attributes
+ {
+ get
+ {
+ return m_methodAttributes;
+ }
+ }
+
+ public override CallingConventions CallingConvention
+ {
+ get
+ {
+ return Signature.CallingConvention;
+ }
+ }
+
+ internal static void CheckCanCreateInstance(Type declaringType, bool isVarArg)
+ {
+ if (declaringType == null)
+ throw new ArgumentNullException(nameof(declaringType));
+ Contract.EndContractBlock();
+
+ // ctor is ReflectOnly
+ if (declaringType is ReflectionOnlyType)
+ throw new InvalidOperationException(SR.Arg_ReflectionOnlyInvoke);
+
+ // ctor is declared on interface class
+ else if (declaringType.IsInterface)
+ throw new MemberAccessException(
+ String.Format(CultureInfo.CurrentUICulture, SR.Acc_CreateInterfaceEx, declaringType));
+
+ // ctor is on an abstract class
+ else if (declaringType.IsAbstract)
+ throw new MemberAccessException(
+ String.Format(CultureInfo.CurrentUICulture, SR.Acc_CreateAbstEx, declaringType));
+
+ // ctor is on a class that contains stack pointers
+ else if (declaringType.GetRootElementType() == typeof(ArgIterator))
+ throw new NotSupportedException();
+
+ // ctor is vararg
+ else if (isVarArg)
+ throw new NotSupportedException();
+
+ // ctor is generic or on a generic class
+ else if (declaringType.ContainsGenericParameters)
+ {
+ throw new MemberAccessException(
+ String.Format(CultureInfo.CurrentUICulture, SR.Acc_CreateGenericEx, declaringType));
+ }
+
+ // ctor is declared on System.Void
+ else if (declaringType == typeof(void))
+ throw new MemberAccessException(SR.Access_Void);
+ }
+
+ internal void ThrowNoInvokeException()
+ {
+ CheckCanCreateInstance(DeclaringType, (CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs);
+
+ // ctor is .cctor
+ if ((Attributes & MethodAttributes.Static) == MethodAttributes.Static)
+ throw new MemberAccessException(SR.Acc_NotClassInit);
+
+ throw new TargetException();
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public override Object Invoke(
+ Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+ {
+ INVOCATION_FLAGS invocationFlags = InvocationFlags;
+
+ if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE) != 0)
+ ThrowNoInvokeException();
+
+ // check basic method consistency. This call will throw if there are problems in the target/method relationship
+ CheckConsistency(obj);
+
+ if (obj != null)
+ {
+ // For unverifiable code, we require the caller to be critical.
+ // Adding the INVOCATION_FLAGS_NEED_SECURITY flag makes that check happen
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
+ }
+
+ Signature sig = Signature;
+
+ // get the signature
+ int formalCount = sig.Arguments.Length;
+ int actualCount = (parameters != null) ? parameters.Length : 0;
+ if (formalCount != actualCount)
+ throw new TargetParameterCountException(SR.Arg_ParmCnt);
+
+ // if we are here we passed all the previous checks. Time to look at the arguments
+ if (actualCount > 0)
+ {
+ Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig);
+ Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, sig, false);
+ // copy out. This should be made only if ByRef are present.
+ for (int index = 0; index < arguments.Length; index++)
+ parameters[index] = arguments[index];
+ return retValue;
+ }
+ return RuntimeMethodHandle.InvokeMethod(obj, null, sig, false);
+ }
+
+ public override MethodBody GetMethodBody()
+ {
+ MethodBody mb = RuntimeMethodHandle.GetMethodBody(this, ReflectedTypeInternal);
+ if (mb != null)
+ mb.m_methodBase = this;
+ return mb;
+ }
+
+ public override bool IsSecurityCritical
+ {
+ get { return true; }
+ }
+
+ public override bool IsSecuritySafeCritical
+ {
+ get { return false; }
+ }
+
+ public override bool IsSecurityTransparent
+ {
+ get { return false; }
+ }
+
+ public override bool ContainsGenericParameters
+ {
+ get
+ {
+ return (DeclaringType != null && DeclaringType.ContainsGenericParameters);
+ }
+ }
+ #endregion
+
+ #region ConstructorInfo Overrides
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public override Object Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+ {
+ INVOCATION_FLAGS invocationFlags = InvocationFlags;
+
+ // get the declaring TypeHandle early for consistent exceptions in IntrospectionOnly context
+ RuntimeTypeHandle declaringTypeHandle = m_declaringType.TypeHandle;
+
+ if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE | INVOCATION_FLAGS.INVOCATION_FLAGS_CONTAINS_STACK_POINTERS | INVOCATION_FLAGS.INVOCATION_FLAGS_NO_CTOR_INVOKE)) != 0)
+ ThrowNoInvokeException();
+
+ // get the signature
+ Signature sig = Signature;
+
+ int formalCount = sig.Arguments.Length;
+ int actualCount = (parameters != null) ? parameters.Length : 0;
+ if (formalCount != actualCount)
+ throw new TargetParameterCountException(SR.Arg_ParmCnt);
+
+ // We don't need to explicitly invoke the class constructor here,
+ // JIT/NGen will insert the call to .cctor in the instance ctor.
+
+ // if we are here we passed all the previous checks. Time to look at the arguments
+ if (actualCount > 0)
+ {
+ Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig);
+ Object retValue = RuntimeMethodHandle.InvokeMethod(null, arguments, sig, true);
+ // copy out. This should be made only if ByRef are present.
+ for (int index = 0; index < arguments.Length; index++)
+ parameters[index] = arguments[index];
+ return retValue;
+ }
+ return RuntimeMethodHandle.InvokeMethod(null, null, sig, true);
+ }
+ #endregion
+
+ #region ISerializable Implementation
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+ MemberInfoSerializationHolder.GetSerializationInfo(info, this);
+ }
+
+ internal string SerializationToString()
+ {
+ // We don't need the return type for constructors.
+ return FormatNameAndSig(true);
+ }
+ #endregion
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/RuntimeEventInfo.cs b/src/mscorlib/src/System/Reflection/RuntimeEventInfo.cs
new file mode 100644
index 0000000000..930e1820bd
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/RuntimeEventInfo.cs
@@ -0,0 +1,220 @@
+// 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.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
+
+namespace System.Reflection
+{
+ [Serializable]
+ internal unsafe sealed class RuntimeEventInfo : EventInfo, ISerializable
+ {
+ #region Private Data Members
+ private int m_token;
+ private EventAttributes m_flags;
+ private string m_name;
+ private void* m_utf8name;
+ private RuntimeTypeCache m_reflectedTypeCache;
+ private RuntimeMethodInfo m_addMethod;
+ private RuntimeMethodInfo m_removeMethod;
+ private RuntimeMethodInfo m_raiseMethod;
+ private MethodInfo[] m_otherMethod;
+ private RuntimeType m_declaringType;
+ private BindingFlags m_bindingFlags;
+ #endregion
+
+ #region Constructor
+ internal RuntimeEventInfo()
+ {
+ // Used for dummy head node during population
+ }
+ internal RuntimeEventInfo(int tkEvent, RuntimeType declaredType, RuntimeTypeCache reflectedTypeCache, out bool isPrivate)
+ {
+ Contract.Requires(declaredType != null);
+ Contract.Requires(reflectedTypeCache != null);
+ Debug.Assert(!reflectedTypeCache.IsGlobal);
+
+ MetadataImport scope = declaredType.GetRuntimeModule().MetadataImport;
+
+ m_token = tkEvent;
+ m_reflectedTypeCache = reflectedTypeCache;
+ m_declaringType = declaredType;
+
+
+ RuntimeType reflectedType = reflectedTypeCache.GetRuntimeType();
+
+ scope.GetEventProps(tkEvent, out m_utf8name, out m_flags);
+
+ RuntimeMethodInfo dummy;
+ Associates.AssignAssociates(scope, tkEvent, declaredType, reflectedType,
+ out m_addMethod, out m_removeMethod, out m_raiseMethod,
+ out dummy, out dummy, out m_otherMethod, out isPrivate, out m_bindingFlags);
+ }
+ #endregion
+
+ #region Internal Members
+ internal override bool CacheEquals(object o)
+ {
+ RuntimeEventInfo m = o as RuntimeEventInfo;
+
+ if ((object)m == null)
+ return false;
+
+ return m.m_token == m_token &&
+ RuntimeTypeHandle.GetModule(m_declaringType).Equals(
+ RuntimeTypeHandle.GetModule(m.m_declaringType));
+ }
+
+ internal BindingFlags BindingFlags { get { return m_bindingFlags; } }
+ #endregion
+
+ #region Object Overrides
+ public override String ToString()
+ {
+ if (m_addMethod == null || m_addMethod.GetParametersNoCopy().Length == 0)
+ throw new InvalidOperationException(SR.InvalidOperation_NoPublicAddMethod);
+
+ return m_addMethod.GetParametersNoCopy()[0].ParameterType.FormatTypeName() + " " + Name;
+ }
+ #endregion
+
+ #region ICustomAttributeProvider
+ public override Object[] GetCustomAttributes(bool inherit)
+ {
+ return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
+ }
+
+ public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
+ }
+
+ public override bool IsDefined(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.IsDefined(this, attributeRuntimeType);
+ }
+
+ public override IList<CustomAttributeData> GetCustomAttributesData()
+ {
+ return CustomAttributeData.GetCustomAttributesInternal(this);
+ }
+ #endregion
+
+ #region MemberInfo Overrides
+ public override MemberTypes MemberType { get { return MemberTypes.Event; } }
+ public override String Name
+ {
+ get
+ {
+ if (m_name == null)
+ m_name = new Utf8String(m_utf8name).ToString();
+
+ return m_name;
+ }
+ }
+ public override Type DeclaringType { get { return m_declaringType; } }
+ public override Type ReflectedType
+ {
+ get
+ {
+ return ReflectedTypeInternal;
+ }
+ }
+
+ private RuntimeType ReflectedTypeInternal
+ {
+ get
+ {
+ return m_reflectedTypeCache.GetRuntimeType();
+ }
+ }
+
+ public override int MetadataToken { get { return m_token; } }
+ public override Module Module { get { return GetRuntimeModule(); } }
+ internal RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); }
+ #endregion
+
+ #region ISerializable
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ MemberInfoSerializationHolder.GetSerializationInfo(info, this);
+ }
+ #endregion
+
+ #region EventInfo Overrides
+ public override MethodInfo[] GetOtherMethods(bool nonPublic)
+ {
+ List<MethodInfo> ret = new List<MethodInfo>();
+
+ if ((object)m_otherMethod == null)
+ return new MethodInfo[0];
+
+ for (int i = 0; i < m_otherMethod.Length; i++)
+ {
+ if (Associates.IncludeAccessor((MethodInfo)m_otherMethod[i], nonPublic))
+ ret.Add(m_otherMethod[i]);
+ }
+
+ return ret.ToArray();
+ }
+
+ public override MethodInfo GetAddMethod(bool nonPublic)
+ {
+ if (!Associates.IncludeAccessor(m_addMethod, nonPublic))
+ return null;
+
+ return m_addMethod;
+ }
+
+ public override MethodInfo GetRemoveMethod(bool nonPublic)
+ {
+ if (!Associates.IncludeAccessor(m_removeMethod, nonPublic))
+ return null;
+
+ return m_removeMethod;
+ }
+
+ public override MethodInfo GetRaiseMethod(bool nonPublic)
+ {
+ if (!Associates.IncludeAccessor(m_raiseMethod, nonPublic))
+ return null;
+
+ return m_raiseMethod;
+ }
+
+ public override EventAttributes Attributes
+ {
+ get
+ {
+ return m_flags;
+ }
+ }
+ #endregion
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/RuntimeFieldInfo.cs b/src/mscorlib/src/System/Reflection/RuntimeFieldInfo.cs
new file mode 100644
index 0000000000..29cc97d225
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/RuntimeFieldInfo.cs
@@ -0,0 +1,136 @@
+// 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.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
+
+namespace System.Reflection
+{
+ [Serializable]
+ internal abstract class RuntimeFieldInfo : FieldInfo, ISerializable
+ {
+ #region Private Data Members
+ private BindingFlags m_bindingFlags;
+ protected RuntimeTypeCache m_reflectedTypeCache;
+ protected RuntimeType m_declaringType;
+ #endregion
+
+ #region Constructor
+ protected RuntimeFieldInfo()
+ {
+ // Used for dummy head node during population
+ }
+ protected RuntimeFieldInfo(RuntimeTypeCache reflectedTypeCache, RuntimeType declaringType, BindingFlags bindingFlags)
+ {
+ m_bindingFlags = bindingFlags;
+ m_declaringType = declaringType;
+ m_reflectedTypeCache = reflectedTypeCache;
+ }
+ #endregion
+
+ #region NonPublic Members
+ internal BindingFlags BindingFlags { get { return m_bindingFlags; } }
+ private RuntimeType ReflectedTypeInternal
+ {
+ get
+ {
+ return m_reflectedTypeCache.GetRuntimeType();
+ }
+ }
+
+ internal RuntimeType GetDeclaringTypeInternal()
+ {
+ return m_declaringType;
+ }
+
+ internal RuntimeType GetRuntimeType() { return m_declaringType; }
+ internal abstract RuntimeModule GetRuntimeModule();
+ #endregion
+
+ #region MemberInfo Overrides
+ public override MemberTypes MemberType { get { return MemberTypes.Field; } }
+ public override Type ReflectedType
+ {
+ get
+ {
+ return m_reflectedTypeCache.IsGlobal ? null : ReflectedTypeInternal;
+ }
+ }
+
+ public override Type DeclaringType
+ {
+ get
+ {
+ return m_reflectedTypeCache.IsGlobal ? null : m_declaringType;
+ }
+ }
+
+ public override Module Module { get { return GetRuntimeModule(); } }
+ #endregion
+
+ #region Object Overrides
+ public unsafe override String ToString()
+ {
+ return FieldType.FormatTypeName() + " " + Name;
+ }
+ #endregion
+
+ #region ICustomAttributeProvider
+ public override Object[] GetCustomAttributes(bool inherit)
+ {
+ return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
+ }
+
+ public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
+ }
+
+ public override bool IsDefined(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.IsDefined(this, attributeRuntimeType);
+ }
+
+ public override IList<CustomAttributeData> GetCustomAttributesData()
+ {
+ return CustomAttributeData.GetCustomAttributesInternal(this);
+ }
+ #endregion
+
+ #region FieldInfo Overrides
+ // All implemented on derived classes
+ #endregion
+
+ #region ISerializable Implementation
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ MemberInfoSerializationHolder.GetSerializationInfo(info, this);
+ }
+ #endregion
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/RuntimeMethodInfo.cs b/src/mscorlib/src/System/Reflection/RuntimeMethodInfo.cs
new file mode 100644
index 0000000000..b8a2341e4e
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/RuntimeMethodInfo.cs
@@ -0,0 +1,803 @@
+// 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.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Runtime.Serialization;
+using System.Security;
+using System.Text;
+using System.Threading;
+using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
+
+namespace System.Reflection
+{
+ [Serializable]
+ internal sealed class RuntimeMethodInfo : MethodInfo, ISerializable, IRuntimeMethodInfo
+ {
+ #region Private Data Members
+ private IntPtr m_handle;
+ private RuntimeTypeCache m_reflectedTypeCache;
+ private string m_name;
+ private string m_toString;
+ private ParameterInfo[] m_parameters;
+ private ParameterInfo m_returnParameter;
+ private BindingFlags m_bindingFlags;
+ private MethodAttributes m_methodAttributes;
+ private Signature m_signature;
+ private RuntimeType m_declaringType;
+ private object m_keepalive;
+ private INVOCATION_FLAGS m_invocationFlags;
+
+ internal INVOCATION_FLAGS InvocationFlags
+ {
+ get
+ {
+ if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0)
+ {
+ INVOCATION_FLAGS invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_UNKNOWN;
+
+ Type declaringType = DeclaringType;
+
+ //
+ // first take care of all the NO_INVOKE cases.
+ if (ContainsGenericParameters ||
+ ReturnType.IsByRef ||
+ (declaringType != null && declaringType.ContainsGenericParameters) ||
+ ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) ||
+ ((Attributes & MethodAttributes.RequireSecObject) == MethodAttributes.RequireSecObject))
+ {
+ // We don't need other flags if this method cannot be invoked
+ invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE;
+ }
+ else
+ {
+ // this should be an invocable method, determine the other flags that participate in invocation
+ invocationFlags = RuntimeMethodHandle.GetSecurityFlags(this);
+
+ if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) == 0)
+ {
+ if ((Attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public ||
+ (declaringType != null && declaringType.NeedsReflectionSecurityCheck))
+ {
+ // If method is non-public, or declaring type is not visible
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
+ }
+ else if (IsGenericMethod)
+ {
+ Type[] genericArguments = GetGenericArguments();
+
+ for (int i = 0; i < genericArguments.Length; i++)
+ {
+ if (genericArguments[i].NeedsReflectionSecurityCheck)
+ {
+ invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED;
+ }
+
+ return m_invocationFlags;
+ }
+ }
+ #endregion
+
+ #region Constructor
+ internal RuntimeMethodInfo(
+ RuntimeMethodHandleInternal handle, RuntimeType declaringType,
+ RuntimeTypeCache reflectedTypeCache, MethodAttributes methodAttributes, BindingFlags bindingFlags, object keepalive)
+ {
+ Contract.Ensures(!m_handle.IsNull());
+
+ Debug.Assert(!handle.IsNullHandle());
+ Debug.Assert(methodAttributes == RuntimeMethodHandle.GetAttributes(handle));
+
+ m_bindingFlags = bindingFlags;
+ m_declaringType = declaringType;
+ m_keepalive = keepalive;
+ m_handle = handle.Value;
+ m_reflectedTypeCache = reflectedTypeCache;
+ m_methodAttributes = methodAttributes;
+ }
+ #endregion
+
+ #region Private Methods
+ RuntimeMethodHandleInternal IRuntimeMethodInfo.Value
+ {
+ get
+ {
+ return new RuntimeMethodHandleInternal(m_handle);
+ }
+ }
+
+ private RuntimeType ReflectedTypeInternal
+ {
+ get
+ {
+ return m_reflectedTypeCache.GetRuntimeType();
+ }
+ }
+
+ private ParameterInfo[] FetchNonReturnParameters()
+ {
+ if (m_parameters == null)
+ m_parameters = RuntimeParameterInfo.GetParameters(this, this, Signature);
+
+ return m_parameters;
+ }
+
+ private ParameterInfo FetchReturnParameter()
+ {
+ if (m_returnParameter == null)
+ m_returnParameter = RuntimeParameterInfo.GetReturnParameter(this, this, Signature);
+
+ return m_returnParameter;
+ }
+ #endregion
+
+ #region Internal Members
+ internal override string FormatNameAndSig(bool serialization)
+ {
+ // Serialization uses ToString to resolve MethodInfo overloads.
+ StringBuilder sbName = new StringBuilder(Name);
+
+ // serialization == true: use unambiguous (except for assembly name) type names to distinguish between overloads.
+ // serialization == false: use basic format to maintain backward compatibility of MethodInfo.ToString().
+ TypeNameFormatFlags format = serialization ? TypeNameFormatFlags.FormatSerialization : TypeNameFormatFlags.FormatBasic;
+
+ if (IsGenericMethod)
+ sbName.Append(RuntimeMethodHandle.ConstructInstantiation(this, format));
+
+ sbName.Append("(");
+ sbName.Append(ConstructParameters(GetParameterTypes(), CallingConvention, serialization));
+ sbName.Append(")");
+
+ return sbName.ToString();
+ }
+
+ internal override bool CacheEquals(object o)
+ {
+ RuntimeMethodInfo m = o as RuntimeMethodInfo;
+
+ if ((object)m == null)
+ return false;
+
+ return m.m_handle == m_handle;
+ }
+
+ internal Signature Signature
+ {
+ get
+ {
+ if (m_signature == null)
+ m_signature = new Signature(this, m_declaringType);
+
+ return m_signature;
+ }
+ }
+
+ internal BindingFlags BindingFlags { get { return m_bindingFlags; } }
+
+ internal RuntimeMethodInfo GetParentDefinition()
+ {
+ if (!IsVirtual || m_declaringType.IsInterface)
+ return null;
+
+ RuntimeType parent = (RuntimeType)m_declaringType.BaseType;
+
+ if (parent == null)
+ return null;
+
+ int slot = RuntimeMethodHandle.GetSlot(this);
+
+ if (RuntimeTypeHandle.GetNumVirtuals(parent) <= slot)
+ return null;
+
+ return (RuntimeMethodInfo)RuntimeType.GetMethodBase(parent, RuntimeTypeHandle.GetMethodAt(parent, slot));
+ }
+
+ // Unlike DeclaringType, this will return a valid type even for global methods
+ internal RuntimeType GetDeclaringTypeInternal()
+ {
+ return m_declaringType;
+ }
+
+ #endregion
+
+ #region Object Overrides
+ public override String ToString()
+ {
+ if (m_toString == null)
+ m_toString = ReturnType.FormatTypeName() + " " + FormatNameAndSig();
+
+ return m_toString;
+ }
+
+ public override int GetHashCode()
+ {
+ // See RuntimeMethodInfo.Equals() below.
+ if (IsGenericMethod)
+ return ValueType.GetHashCodeOfPtr(m_handle);
+ else
+ return base.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (!IsGenericMethod)
+ return obj == (object)this;
+
+ // We cannot do simple object identity comparisons for generic methods.
+ // Equals will be called in CerHashTable when RuntimeType+RuntimeTypeCache.GetGenericMethodInfo()
+ // retrieve items from and insert items into s_methodInstantiations which is a CerHashtable.
+
+ RuntimeMethodInfo mi = obj as RuntimeMethodInfo;
+
+ if (mi == null || !mi.IsGenericMethod)
+ return false;
+
+ // now we know that both operands are generic methods
+
+ IRuntimeMethodInfo handle1 = RuntimeMethodHandle.StripMethodInstantiation(this);
+ IRuntimeMethodInfo handle2 = RuntimeMethodHandle.StripMethodInstantiation(mi);
+ if (handle1.Value.Value != handle2.Value.Value)
+ return false;
+
+ Type[] lhs = GetGenericArguments();
+ Type[] rhs = mi.GetGenericArguments();
+
+ if (lhs.Length != rhs.Length)
+ return false;
+
+ for (int i = 0; i < lhs.Length; i++)
+ {
+ if (lhs[i] != rhs[i])
+ return false;
+ }
+
+ if (DeclaringType != mi.DeclaringType)
+ return false;
+
+ if (ReflectedType != mi.ReflectedType)
+ return false;
+
+ return true;
+ }
+ #endregion
+
+ #region ICustomAttributeProvider
+ public override Object[] GetCustomAttributes(bool inherit)
+ {
+ return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType as RuntimeType, inherit);
+ }
+
+ public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
+ }
+
+ public override bool IsDefined(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.IsDefined(this, attributeRuntimeType, inherit);
+ }
+
+ public override IList<CustomAttributeData> GetCustomAttributesData()
+ {
+ return CustomAttributeData.GetCustomAttributesInternal(this);
+ }
+ #endregion
+
+ #region MemberInfo Overrides
+ public override String Name
+ {
+ get
+ {
+ if (m_name == null)
+ m_name = RuntimeMethodHandle.GetName(this);
+
+ return m_name;
+ }
+ }
+
+ public override Type DeclaringType
+ {
+ get
+ {
+ if (m_reflectedTypeCache.IsGlobal)
+ return null;
+
+ return m_declaringType;
+ }
+ }
+
+ public override Type ReflectedType
+ {
+ get
+ {
+ if (m_reflectedTypeCache.IsGlobal)
+ return null;
+
+ return m_reflectedTypeCache.GetRuntimeType();
+ }
+ }
+
+ public override MemberTypes MemberType { get { return MemberTypes.Method; } }
+ public override int MetadataToken
+ {
+ get { return RuntimeMethodHandle.GetMethodDef(this); }
+ }
+ public override Module Module { get { return GetRuntimeModule(); } }
+ internal RuntimeType GetRuntimeType() { return m_declaringType; }
+ internal RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); }
+ internal RuntimeAssembly GetRuntimeAssembly() { return GetRuntimeModule().GetRuntimeAssembly(); }
+
+ public override bool IsSecurityCritical
+ {
+ get { return true; }
+ }
+ public override bool IsSecuritySafeCritical
+ {
+ get { return false; }
+ }
+ public override bool IsSecurityTransparent
+ {
+ get { return false; }
+ }
+ #endregion
+
+ #region MethodBase Overrides
+ internal override ParameterInfo[] GetParametersNoCopy()
+ {
+ FetchNonReturnParameters();
+
+ return m_parameters;
+ }
+
+ [System.Diagnostics.Contracts.Pure]
+ public override ParameterInfo[] GetParameters()
+ {
+ FetchNonReturnParameters();
+
+ if (m_parameters.Length == 0)
+ return m_parameters;
+
+ ParameterInfo[] ret = new ParameterInfo[m_parameters.Length];
+
+ Array.Copy(m_parameters, ret, m_parameters.Length);
+
+ return ret;
+ }
+
+ public override MethodImplAttributes GetMethodImplementationFlags()
+ {
+ return RuntimeMethodHandle.GetImplAttributes(this);
+ }
+
+ public override RuntimeMethodHandle MethodHandle
+ {
+ get
+ {
+ Type declaringType = DeclaringType;
+ if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
+ throw new InvalidOperationException(SR.InvalidOperation_NotAllowedInReflectionOnly);
+ return new RuntimeMethodHandle(this);
+ }
+ }
+
+ public override MethodAttributes Attributes { get { return m_methodAttributes; } }
+
+ public override CallingConventions CallingConvention
+ {
+ get
+ {
+ return Signature.CallingConvention;
+ }
+ }
+
+ public override MethodBody GetMethodBody()
+ {
+ MethodBody mb = RuntimeMethodHandle.GetMethodBody(this, ReflectedTypeInternal);
+ if (mb != null)
+ mb.m_methodBase = this;
+ return mb;
+ }
+ #endregion
+
+ #region Invocation Logic(On MemberBase)
+ private void CheckConsistency(Object target)
+ {
+ // only test instance methods
+ if ((m_methodAttributes & MethodAttributes.Static) != MethodAttributes.Static)
+ {
+ if (!m_declaringType.IsInstanceOfType(target))
+ {
+ if (target == null)
+ throw new TargetException(SR.RFLCT_Targ_StatMethReqTarg);
+ else
+ throw new TargetException(SR.RFLCT_Targ_ITargMismatch);
+ }
+ }
+ }
+
+ private void ThrowNoInvokeException()
+ {
+ // method is ReflectionOnly
+ Type declaringType = DeclaringType;
+ if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType)
+ {
+ throw new InvalidOperationException(SR.Arg_ReflectionOnlyInvoke);
+ }
+ // method is on a class that contains stack pointers
+ else if ((InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_CONTAINS_STACK_POINTERS) != 0)
+ {
+ throw new NotSupportedException();
+ }
+ // method is vararg
+ else if ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs)
+ {
+ throw new NotSupportedException();
+ }
+ // method is generic or on a generic class
+ else if (DeclaringType.ContainsGenericParameters || ContainsGenericParameters)
+ {
+ throw new InvalidOperationException(SR.Arg_UnboundGenParam);
+ }
+ // method is abstract class
+ else if (IsAbstract)
+ {
+ throw new MemberAccessException();
+ }
+ // ByRef return are not allowed in reflection
+ else if (ReturnType.IsByRef)
+ {
+ throw new NotSupportedException(SR.NotSupported_ByRefReturn);
+ }
+
+ throw new TargetException();
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+ {
+ object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture);
+
+ return UnsafeInvokeInternal(obj, parameters, arguments);
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ internal object UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+ {
+ object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture);
+
+ return UnsafeInvokeInternal(obj, parameters, arguments);
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ private object UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
+ {
+ if (arguments == null || arguments.Length == 0)
+ return RuntimeMethodHandle.InvokeMethod(obj, null, Signature, false);
+ else
+ {
+ Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, Signature, false);
+
+ // copy out. This should be made only if ByRef are present.
+ for (int index = 0; index < arguments.Length; index++)
+ parameters[index] = arguments[index];
+
+ return retValue;
+ }
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ private object[] InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
+ {
+ Signature sig = Signature;
+
+ // get the signature
+ int formalCount = sig.Arguments.Length;
+ int actualCount = (parameters != null) ? parameters.Length : 0;
+
+ INVOCATION_FLAGS invocationFlags = InvocationFlags;
+
+ // INVOCATION_FLAGS_CONTAINS_STACK_POINTERS means that the struct (either the declaring type or the return type)
+ // contains pointers that point to the stack. This is either a ByRef or a TypedReference. These structs cannot
+ // be boxed and thus cannot be invoked through reflection which only deals with boxed value type objects.
+ if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE | INVOCATION_FLAGS.INVOCATION_FLAGS_CONTAINS_STACK_POINTERS)) != 0)
+ ThrowNoInvokeException();
+
+ // check basic method consistency. This call will throw if there are problems in the target/method relationship
+ CheckConsistency(obj);
+
+ if (formalCount != actualCount)
+ throw new TargetParameterCountException(SR.Arg_ParmCnt);
+
+ if (actualCount != 0)
+ return CheckArguments(parameters, binder, invokeAttr, culture, sig);
+ else
+ return null;
+ }
+
+ #endregion
+
+ #region MethodInfo Overrides
+ public override Type ReturnType
+ {
+ get { return Signature.ReturnType; }
+ }
+
+ public override ICustomAttributeProvider ReturnTypeCustomAttributes
+ {
+ get { return ReturnParameter; }
+ }
+
+ public override ParameterInfo ReturnParameter
+ {
+ get
+ {
+ Contract.Ensures(m_returnParameter != null);
+
+ FetchReturnParameter();
+ return m_returnParameter as ParameterInfo;
+ }
+ }
+
+ public override MethodInfo GetBaseDefinition()
+ {
+ if (!IsVirtual || IsStatic || m_declaringType == null || m_declaringType.IsInterface)
+ return this;
+
+ int slot = RuntimeMethodHandle.GetSlot(this);
+ RuntimeType declaringType = (RuntimeType)DeclaringType;
+ RuntimeType baseDeclaringType = declaringType;
+ RuntimeMethodHandleInternal baseMethodHandle = new RuntimeMethodHandleInternal();
+
+ do
+ {
+ int cVtblSlots = RuntimeTypeHandle.GetNumVirtuals(declaringType);
+
+ if (cVtblSlots <= slot)
+ break;
+
+ baseMethodHandle = RuntimeTypeHandle.GetMethodAt(declaringType, slot);
+ baseDeclaringType = declaringType;
+
+ declaringType = (RuntimeType)declaringType.BaseType;
+ } while (declaringType != null);
+
+ return (MethodInfo)RuntimeType.GetMethodBase(baseDeclaringType, baseMethodHandle);
+ }
+
+ public override Delegate CreateDelegate(Type delegateType)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+
+ // This API existed in v1/v1.1 and only expected to create closed
+ // instance delegates. Constrain the call to BindToMethodInfo to
+ // open delegates only for backwards compatibility. But we'll allow
+ // relaxed signature checking and open static delegates because
+ // there's no ambiguity there (the caller would have to explicitly
+ // pass us a static method or a method with a non-exact signature
+ // and the only change in behavior from v1.1 there is that we won't
+ // fail the call).
+ return CreateDelegateInternal(
+ delegateType,
+ null,
+ DelegateBindingFlags.OpenDelegateOnly | DelegateBindingFlags.RelaxedSignature,
+ ref stackMark);
+ }
+
+ public override Delegate CreateDelegate(Type delegateType, Object target)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+
+ // This API is new in Whidbey and allows the full range of delegate
+ // flexability (open or closed delegates binding to static or
+ // instance methods with relaxed signature checking). The delegate
+ // can also be closed over null. There's no ambiguity with all these
+ // options since the caller is providing us a specific MethodInfo.
+ return CreateDelegateInternal(
+ delegateType,
+ target,
+ DelegateBindingFlags.RelaxedSignature,
+ ref stackMark);
+ }
+
+ private Delegate CreateDelegateInternal(Type delegateType, Object firstArgument, DelegateBindingFlags bindingFlags, ref StackCrawlMark stackMark)
+ {
+ // Validate the parameters.
+ if (delegateType == null)
+ throw new ArgumentNullException(nameof(delegateType));
+ Contract.EndContractBlock();
+
+ RuntimeType rtType = delegateType as RuntimeType;
+ if (rtType == null)
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(delegateType));
+
+ if (!rtType.IsDelegate())
+ throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(delegateType));
+
+ Delegate d = Delegate.CreateDelegateInternal(rtType, this, firstArgument, bindingFlags, ref stackMark);
+ if (d == null)
+ {
+ throw new ArgumentException(SR.Arg_DlgtTargMeth);
+ }
+
+ return d;
+ }
+
+ #endregion
+
+ #region Generics
+ public override MethodInfo MakeGenericMethod(params Type[] methodInstantiation)
+ {
+ if (methodInstantiation == null)
+ throw new ArgumentNullException(nameof(methodInstantiation));
+ Contract.EndContractBlock();
+
+ RuntimeType[] methodInstantionRuntimeType = new RuntimeType[methodInstantiation.Length];
+
+ if (!IsGenericMethodDefinition)
+ throw new InvalidOperationException(
+ SR.Format(SR.Arg_NotGenericMethodDefinition, this));
+
+ for (int i = 0; i < methodInstantiation.Length; i++)
+ {
+ Type methodInstantiationElem = methodInstantiation[i];
+
+ if (methodInstantiationElem == null)
+ throw new ArgumentNullException();
+
+ RuntimeType rtMethodInstantiationElem = methodInstantiationElem as RuntimeType;
+
+ if (rtMethodInstantiationElem == null)
+ {
+ Type[] methodInstantiationCopy = new Type[methodInstantiation.Length];
+ for (int iCopy = 0; iCopy < methodInstantiation.Length; iCopy++)
+ methodInstantiationCopy[iCopy] = methodInstantiation[iCopy];
+ methodInstantiation = methodInstantiationCopy;
+ return System.Reflection.Emit.MethodBuilderInstantiation.MakeGenericMethod(this, methodInstantiation);
+ }
+
+ methodInstantionRuntimeType[i] = rtMethodInstantiationElem;
+ }
+
+ RuntimeType[] genericParameters = GetGenericArgumentsInternal();
+
+ RuntimeType.SanityCheckGenericArguments(methodInstantionRuntimeType, genericParameters);
+
+ MethodInfo ret = null;
+
+ try
+ {
+ ret = RuntimeType.GetMethodBase(ReflectedTypeInternal,
+ RuntimeMethodHandle.GetStubIfNeeded(new RuntimeMethodHandleInternal(m_handle), m_declaringType, methodInstantionRuntimeType)) as MethodInfo;
+ }
+ catch (VerificationException e)
+ {
+ RuntimeType.ValidateGenericArguments(this, methodInstantionRuntimeType, e);
+ throw;
+ }
+
+ return ret;
+ }
+
+ internal RuntimeType[] GetGenericArgumentsInternal()
+ {
+ return RuntimeMethodHandle.GetMethodInstantiationInternal(this);
+ }
+
+ public override Type[] GetGenericArguments()
+ {
+ Type[] types = RuntimeMethodHandle.GetMethodInstantiationPublic(this);
+
+ if (types == null)
+ {
+ types = Array.Empty<Type>();
+ }
+ return types;
+ }
+
+ public override MethodInfo GetGenericMethodDefinition()
+ {
+ if (!IsGenericMethod)
+ throw new InvalidOperationException();
+ Contract.EndContractBlock();
+
+ return RuntimeType.GetMethodBase(m_declaringType, RuntimeMethodHandle.StripMethodInstantiation(this)) as MethodInfo;
+ }
+
+ public override bool IsGenericMethod
+ {
+ get { return RuntimeMethodHandle.HasMethodInstantiation(this); }
+ }
+
+ public override bool IsGenericMethodDefinition
+ {
+ get { return RuntimeMethodHandle.IsGenericMethodDefinition(this); }
+ }
+
+ public override bool ContainsGenericParameters
+ {
+ get
+ {
+ if (DeclaringType != null && DeclaringType.ContainsGenericParameters)
+ return true;
+
+ if (!IsGenericMethod)
+ return false;
+
+ Type[] pis = GetGenericArguments();
+ for (int i = 0; i < pis.Length; i++)
+ {
+ if (pis[i].ContainsGenericParameters)
+ return true;
+ }
+
+ return false;
+ }
+ }
+ #endregion
+
+ #region ISerializable Implementation
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ if (m_reflectedTypeCache.IsGlobal)
+ throw new NotSupportedException(SR.NotSupported_GlobalMethodSerialization);
+
+ MemberInfoSerializationHolder.GetSerializationInfo(info, this);
+ }
+
+ internal string SerializationToString()
+ {
+ return ReturnType.FormatTypeName(true) + " " + FormatNameAndSig(true);
+ }
+ #endregion
+
+ #region Legacy Internal
+ internal static MethodBase InternalGetCurrentMethod(ref StackCrawlMark stackMark)
+ {
+ IRuntimeMethodInfo method = RuntimeMethodHandle.GetCurrentMethod(ref stackMark);
+
+ if (method == null)
+ return null;
+
+ return RuntimeType.GetMethodBase(method);
+ }
+ #endregion
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/RuntimeModule.cs b/src/mscorlib/src/System/Reflection/RuntimeModule.cs
new file mode 100644
index 0000000000..75809cba01
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/RuntimeModule.cs
@@ -0,0 +1,602 @@
+// 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.Runtime.InteropServices;
+using System.Runtime.Serialization;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Security;
+using System.Globalization;
+using System.Diagnostics.Contracts;
+
+namespace System.Reflection
+{
+ [Serializable]
+ internal class RuntimeModule : Module
+ {
+ internal RuntimeModule() { throw new NotSupportedException(); }
+
+ #region FCalls
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private extern static void GetType(RuntimeModule module, String className, bool throwOnError, bool ignoreCase, ObjectHandleOnStack type, ObjectHandleOnStack keepAlive);
+
+ [DllImport(JitHelpers.QCall)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern bool nIsTransientInternal(RuntimeModule module);
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private extern static void GetScopeName(RuntimeModule module, StringHandleOnStack retString);
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private extern static void GetFullyQualifiedName(RuntimeModule module, StringHandleOnStack retString);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern static RuntimeType[] GetTypes(RuntimeModule module);
+
+ internal RuntimeType[] GetDefinedTypes()
+ {
+ return GetTypes(GetNativeHandle());
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern static bool IsResource(RuntimeModule module);
+ #endregion
+
+ #region Module overrides
+ private static RuntimeTypeHandle[] ConvertToTypeHandleArray(Type[] genericArguments)
+ {
+ if (genericArguments == null)
+ return null;
+
+ int size = genericArguments.Length;
+ RuntimeTypeHandle[] typeHandleArgs = new RuntimeTypeHandle[size];
+ for (int i = 0; i < size; i++)
+ {
+ Type typeArg = genericArguments[i];
+ if (typeArg == null)
+ throw new ArgumentException(SR.Argument_InvalidGenericInstArray);
+ typeArg = typeArg.UnderlyingSystemType;
+ if (typeArg == null)
+ throw new ArgumentException(SR.Argument_InvalidGenericInstArray);
+ if (!(typeArg is RuntimeType))
+ throw new ArgumentException(SR.Argument_InvalidGenericInstArray);
+ typeHandleArgs[i] = typeArg.GetTypeHandleInternal();
+ }
+ return typeHandleArgs;
+ }
+
+ public override byte[] ResolveSignature(int metadataToken)
+ {
+ MetadataToken tk = new MetadataToken(metadataToken);
+
+ if (!MetadataImport.IsValidToken(tk))
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
+ SR.Format(SR.Argument_InvalidToken, tk, this));
+
+ if (!tk.IsMemberRef && !tk.IsMethodDef && !tk.IsTypeSpec && !tk.IsSignature && !tk.IsFieldDef)
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidToken, tk, this),
+ nameof(metadataToken));
+
+ ConstArray signature;
+ if (tk.IsMemberRef)
+ signature = MetadataImport.GetMemberRefProps(metadataToken);
+ else
+ signature = MetadataImport.GetSignatureFromToken(metadataToken);
+
+ byte[] sig = new byte[signature.Length];
+
+ for (int i = 0; i < signature.Length; i++)
+ sig[i] = signature[i];
+
+ return sig;
+ }
+
+ public override MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
+ {
+ MetadataToken tk = new MetadataToken(metadataToken);
+
+ if (!MetadataImport.IsValidToken(tk))
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
+ SR.Format(SR.Argument_InvalidToken, tk, this));
+
+ RuntimeTypeHandle[] typeArgs = ConvertToTypeHandleArray(genericTypeArguments);
+ RuntimeTypeHandle[] methodArgs = ConvertToTypeHandleArray(genericMethodArguments);
+
+ try
+ {
+ if (!tk.IsMethodDef && !tk.IsMethodSpec)
+ {
+ if (!tk.IsMemberRef)
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveMethod, tk, this),
+ nameof(metadataToken));
+
+ unsafe
+ {
+ ConstArray sig = MetadataImport.GetMemberRefProps(tk);
+
+ if (*(MdSigCallingConvention*)sig.Signature.ToPointer() == MdSigCallingConvention.Field)
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveMethod, tk, this),
+ nameof(metadataToken));
+ }
+ }
+
+ IRuntimeMethodInfo methodHandle = ModuleHandle.ResolveMethodHandleInternal(GetNativeHandle(), tk, typeArgs, methodArgs);
+ Type declaringType = RuntimeMethodHandle.GetDeclaringType(methodHandle);
+
+ if (declaringType.IsGenericType || declaringType.IsArray)
+ {
+ MetadataToken tkDeclaringType = new MetadataToken(MetadataImport.GetParentToken(tk));
+
+ if (tk.IsMethodSpec)
+ tkDeclaringType = new MetadataToken(MetadataImport.GetParentToken(tkDeclaringType));
+
+ declaringType = ResolveType(tkDeclaringType, genericTypeArguments, genericMethodArguments);
+ }
+
+ return System.RuntimeType.GetMethodBase(declaringType as RuntimeType, methodHandle);
+ }
+ catch (BadImageFormatException e)
+ {
+ throw new ArgumentException(SR.Argument_BadImageFormatExceptionResolve, e);
+ }
+ }
+
+ private FieldInfo ResolveLiteralField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
+ {
+ MetadataToken tk = new MetadataToken(metadataToken);
+
+ if (!MetadataImport.IsValidToken(tk) || !tk.IsFieldDef)
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
+ String.Format(CultureInfo.CurrentUICulture, SR.Format(SR.Argument_InvalidToken, tk, this)));
+
+ int tkDeclaringType;
+ string fieldName;
+
+ fieldName = MetadataImport.GetName(tk).ToString();
+ tkDeclaringType = MetadataImport.GetParentToken(tk);
+
+ Type declaringType = ResolveType(tkDeclaringType, genericTypeArguments, genericMethodArguments);
+
+ declaringType.GetFields();
+
+ try
+ {
+ return declaringType.GetField(fieldName,
+ BindingFlags.Static | BindingFlags.Instance |
+ BindingFlags.Public | BindingFlags.NonPublic |
+ BindingFlags.DeclaredOnly);
+ }
+ catch
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveField, tk, this), nameof(metadataToken));
+ }
+ }
+
+ public override FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
+ {
+ MetadataToken tk = new MetadataToken(metadataToken);
+
+ if (!MetadataImport.IsValidToken(tk))
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
+ SR.Format(SR.Argument_InvalidToken, tk, this));
+
+ RuntimeTypeHandle[] typeArgs = ConvertToTypeHandleArray(genericTypeArguments);
+ RuntimeTypeHandle[] methodArgs = ConvertToTypeHandleArray(genericMethodArguments);
+
+ try
+ {
+ IRuntimeFieldInfo fieldHandle = null;
+
+ if (!tk.IsFieldDef)
+ {
+ if (!tk.IsMemberRef)
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveField, tk, this),
+ nameof(metadataToken));
+
+ unsafe
+ {
+ ConstArray sig = MetadataImport.GetMemberRefProps(tk);
+
+ if (*(MdSigCallingConvention*)sig.Signature.ToPointer() != MdSigCallingConvention.Field)
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveField, tk, this),
+ nameof(metadataToken));
+ }
+
+ fieldHandle = ModuleHandle.ResolveFieldHandleInternal(GetNativeHandle(), tk, typeArgs, methodArgs);
+ }
+
+ fieldHandle = ModuleHandle.ResolveFieldHandleInternal(GetNativeHandle(), metadataToken, typeArgs, methodArgs);
+ RuntimeType declaringType = RuntimeFieldHandle.GetApproxDeclaringType(fieldHandle.Value);
+
+ if (declaringType.IsGenericType || declaringType.IsArray)
+ {
+ int tkDeclaringType = ModuleHandle.GetMetadataImport(GetNativeHandle()).GetParentToken(metadataToken);
+ declaringType = (RuntimeType)ResolveType(tkDeclaringType, genericTypeArguments, genericMethodArguments);
+ }
+
+ return System.RuntimeType.GetFieldInfo(declaringType, fieldHandle);
+ }
+ catch (MissingFieldException)
+ {
+ return ResolveLiteralField(tk, genericTypeArguments, genericMethodArguments);
+ }
+ catch (BadImageFormatException e)
+ {
+ throw new ArgumentException(SR.Argument_BadImageFormatExceptionResolve, e);
+ }
+ }
+
+ public override Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
+ {
+ MetadataToken tk = new MetadataToken(metadataToken);
+
+ if (tk.IsGlobalTypeDefToken)
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveModuleType, tk), nameof(metadataToken));
+
+ if (!MetadataImport.IsValidToken(tk))
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
+ SR.Format(SR.Argument_InvalidToken, tk, this));
+
+ if (!tk.IsTypeDef && !tk.IsTypeSpec && !tk.IsTypeRef)
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveType, tk, this), nameof(metadataToken));
+
+ RuntimeTypeHandle[] typeArgs = ConvertToTypeHandleArray(genericTypeArguments);
+ RuntimeTypeHandle[] methodArgs = ConvertToTypeHandleArray(genericMethodArguments);
+
+ try
+ {
+ Type t = GetModuleHandleImpl().ResolveTypeHandle(metadataToken, typeArgs, methodArgs).GetRuntimeType();
+
+ if (t == null)
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveType, tk, this), nameof(metadataToken));
+
+ return t;
+ }
+ catch (BadImageFormatException e)
+ {
+ throw new ArgumentException(SR.Argument_BadImageFormatExceptionResolve, e);
+ }
+ }
+
+ public override MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
+ {
+ MetadataToken tk = new MetadataToken(metadataToken);
+
+ if (tk.IsProperty)
+ throw new ArgumentException(SR.InvalidOperation_PropertyInfoNotAvailable);
+
+ if (tk.IsEvent)
+ throw new ArgumentException(SR.InvalidOperation_EventInfoNotAvailable);
+
+ if (tk.IsMethodSpec || tk.IsMethodDef)
+ return ResolveMethod(metadataToken, genericTypeArguments, genericMethodArguments);
+
+ if (tk.IsFieldDef)
+ return ResolveField(metadataToken, genericTypeArguments, genericMethodArguments);
+
+ if (tk.IsTypeRef || tk.IsTypeDef || tk.IsTypeSpec)
+ return ResolveType(metadataToken, genericTypeArguments, genericMethodArguments);
+
+ if (tk.IsMemberRef)
+ {
+ if (!MetadataImport.IsValidToken(tk))
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
+ SR.Format(SR.Argument_InvalidToken, tk, this));
+
+ ConstArray sig = MetadataImport.GetMemberRefProps(tk);
+
+ unsafe
+ {
+ if (*(MdSigCallingConvention*)sig.Signature.ToPointer() == MdSigCallingConvention.Field)
+ {
+ return ResolveField(tk, genericTypeArguments, genericMethodArguments);
+ }
+ else
+ {
+ return ResolveMethod(tk, genericTypeArguments, genericMethodArguments);
+ }
+ }
+ }
+
+ throw new ArgumentException(SR.Format(SR.Argument_ResolveMember, tk, this),
+ nameof(metadataToken));
+ }
+
+ public override string ResolveString(int metadataToken)
+ {
+ MetadataToken tk = new MetadataToken(metadataToken);
+ if (!tk.IsString)
+ throw new ArgumentException(
+ String.Format(CultureInfo.CurrentUICulture, SR.Argument_ResolveString, metadataToken, ToString()));
+
+ if (!MetadataImport.IsValidToken(tk))
+ throw new ArgumentOutOfRangeException(nameof(metadataToken),
+ String.Format(CultureInfo.CurrentUICulture, SR.Format(SR.Argument_InvalidToken, tk, this)));
+
+ string str = MetadataImport.GetUserString(metadataToken);
+
+ if (str == null)
+ throw new ArgumentException(
+ String.Format(CultureInfo.CurrentUICulture, SR.Argument_ResolveString, metadataToken, ToString()));
+
+ return str;
+ }
+
+ public override void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine)
+ {
+ ModuleHandle.GetPEKind(GetNativeHandle(), out peKind, out machine);
+ }
+
+ public override int MDStreamVersion
+ {
+ get
+ {
+ return ModuleHandle.GetMDStreamVersion(GetNativeHandle());
+ }
+ }
+ #endregion
+
+ #region Data Members
+#pragma warning disable 169
+ // If you add any data members, you need to update the native declaration ReflectModuleBaseObject.
+ private RuntimeType m_runtimeType;
+ private RuntimeAssembly m_runtimeAssembly;
+ private IntPtr m_pRefClass;
+ private IntPtr m_pData;
+ private IntPtr m_pGlobals;
+ private IntPtr m_pFields;
+#pragma warning restore 169
+ #endregion
+
+ #region Protected Virtuals
+ protected override MethodInfo GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder,
+ CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
+ {
+ return GetMethodInternal(name, bindingAttr, binder, callConvention, types, modifiers);
+ }
+
+ internal MethodInfo GetMethodInternal(String name, BindingFlags bindingAttr, Binder binder,
+ CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
+ {
+ if (RuntimeType == null)
+ return null;
+
+ if (types == null)
+ {
+ return RuntimeType.GetMethod(name, bindingAttr);
+ }
+ else
+ {
+ return RuntimeType.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers);
+ }
+ }
+ #endregion
+
+ #region Internal Members
+ internal RuntimeType RuntimeType
+ {
+ get
+ {
+ if (m_runtimeType == null)
+ m_runtimeType = ModuleHandle.GetModuleType(GetNativeHandle());
+
+ return m_runtimeType;
+ }
+ }
+
+ internal bool IsTransientInternal()
+ {
+ return RuntimeModule.nIsTransientInternal(this.GetNativeHandle());
+ }
+
+ internal MetadataImport MetadataImport
+ {
+ get
+ {
+ unsafe
+ {
+ return ModuleHandle.GetMetadataImport(GetNativeHandle());
+ }
+ }
+ }
+ #endregion
+
+ #region ICustomAttributeProvider Members
+ public override Object[] GetCustomAttributes(bool inherit)
+ {
+ return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
+ }
+
+ public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
+ }
+
+ public override bool IsDefined(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.IsDefined(this, attributeRuntimeType);
+ }
+
+ public override IList<CustomAttributeData> GetCustomAttributesData()
+ {
+ return CustomAttributeData.GetCustomAttributesInternal(this);
+ }
+ #endregion
+
+ #region Public Virtuals
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
+ throw new ArgumentNullException(nameof(info));
+ }
+ Contract.EndContractBlock();
+ UnitySerializationHolder.GetUnitySerializationInfo(info, UnitySerializationHolder.ModuleUnity, this.ScopeName, this.GetRuntimeAssembly());
+ }
+
+ public override Type GetType(String className, bool throwOnError, bool ignoreCase)
+ {
+ // throw on null strings regardless of the value of "throwOnError"
+ if (className == null)
+ throw new ArgumentNullException(nameof(className));
+
+ RuntimeType retType = null;
+ Object keepAlive = null;
+ GetType(GetNativeHandle(), className, throwOnError, ignoreCase, JitHelpers.GetObjectHandleOnStack(ref retType), JitHelpers.GetObjectHandleOnStack(ref keepAlive));
+ GC.KeepAlive(keepAlive);
+ return retType;
+ }
+
+ internal string GetFullyQualifiedName()
+ {
+ String fullyQualifiedName = null;
+ GetFullyQualifiedName(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref fullyQualifiedName));
+ return fullyQualifiedName;
+ }
+
+ public override String FullyQualifiedName
+ {
+ get
+ {
+ return GetFullyQualifiedName();
+ }
+ }
+
+ public override Type[] GetTypes()
+ {
+ return GetTypes(GetNativeHandle());
+ }
+
+ #endregion
+
+ #region Public Members
+
+ public override Guid ModuleVersionId
+ {
+ get
+ {
+ unsafe
+ {
+ Guid mvid;
+ MetadataImport.GetScopeProps(out mvid);
+ return mvid;
+ }
+ }
+ }
+
+ public override int MetadataToken
+ {
+ get
+ {
+ return ModuleHandle.GetToken(GetNativeHandle());
+ }
+ }
+
+ public override bool IsResource()
+ {
+ return IsResource(GetNativeHandle());
+ }
+
+ public override FieldInfo[] GetFields(BindingFlags bindingFlags)
+ {
+ if (RuntimeType == null)
+ return new FieldInfo[0];
+
+ return RuntimeType.GetFields(bindingFlags);
+ }
+
+ public override FieldInfo GetField(String name, BindingFlags bindingAttr)
+ {
+ if (name == null)
+ throw new ArgumentNullException(nameof(name));
+
+ if (RuntimeType == null)
+ return null;
+
+ return RuntimeType.GetField(name, bindingAttr);
+ }
+
+ public override MethodInfo[] GetMethods(BindingFlags bindingFlags)
+ {
+ if (RuntimeType == null)
+ return new MethodInfo[0];
+
+ return RuntimeType.GetMethods(bindingFlags);
+ }
+
+ public override String ScopeName
+ {
+ get
+ {
+ string scopeName = null;
+ GetScopeName(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref scopeName));
+ return scopeName;
+ }
+ }
+
+ public override String Name
+ {
+ get
+ {
+ String s = GetFullyQualifiedName();
+
+#if !FEATURE_PAL
+ int i = s.LastIndexOf('\\');
+#else
+ int i = s.LastIndexOf(System.IO.Path.DirectorySeparatorChar);
+#endif
+ if (i == -1)
+ return s;
+
+ return s.Substring(i + 1);
+ }
+ }
+
+ public override Assembly Assembly
+ {
+ [Pure]
+ get
+ {
+ return GetRuntimeAssembly();
+ }
+ }
+
+ internal RuntimeAssembly GetRuntimeAssembly()
+ {
+ return m_runtimeAssembly;
+ }
+
+ protected override ModuleHandle GetModuleHandleImpl()
+ {
+ return new ModuleHandle(this);
+ }
+
+ internal RuntimeModule GetNativeHandle()
+ {
+ return this;
+ }
+ #endregion
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/RuntimeParameterInfo.cs b/src/mscorlib/src/System/Reflection/RuntimeParameterInfo.cs
new file mode 100644
index 0000000000..addf68e75d
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/RuntimeParameterInfo.cs
@@ -0,0 +1,528 @@
+// 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.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Runtime.Serialization;
+using System.Runtime.CompilerServices;
+using MdToken = System.Reflection.MetadataToken;
+
+namespace System.Reflection
+{
+ [Serializable]
+ internal unsafe sealed class RuntimeParameterInfo : ParameterInfo, ISerializable
+ {
+ #region Static Members
+ internal unsafe static ParameterInfo[] GetParameters(IRuntimeMethodInfo method, MemberInfo member, Signature sig)
+ {
+ Debug.Assert(method is RuntimeMethodInfo || method is RuntimeConstructorInfo);
+
+ ParameterInfo dummy;
+ return GetParameters(method, member, sig, out dummy, false);
+ }
+
+ internal unsafe static ParameterInfo GetReturnParameter(IRuntimeMethodInfo method, MemberInfo member, Signature sig)
+ {
+ Debug.Assert(method is RuntimeMethodInfo || method is RuntimeConstructorInfo);
+
+ ParameterInfo returnParameter;
+ GetParameters(method, member, sig, out returnParameter, true);
+ return returnParameter;
+ }
+
+ internal unsafe static ParameterInfo[] GetParameters(
+ IRuntimeMethodInfo methodHandle, MemberInfo member, Signature sig, out ParameterInfo returnParameter, bool fetchReturnParameter)
+ {
+ returnParameter = null;
+ int sigArgCount = sig.Arguments.Length;
+ ParameterInfo[] args = fetchReturnParameter ? null : new ParameterInfo[sigArgCount];
+
+ int tkMethodDef = RuntimeMethodHandle.GetMethodDef(methodHandle);
+ int cParamDefs = 0;
+
+ // Not all methods have tokens. Arrays, pointers and byRef types do not have tokens as they
+ // are generated on the fly by the runtime.
+ if (!MdToken.IsNullToken(tkMethodDef))
+ {
+ MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(RuntimeMethodHandle.GetDeclaringType(methodHandle));
+
+ MetadataEnumResult tkParamDefs;
+ scope.EnumParams(tkMethodDef, out tkParamDefs);
+
+ cParamDefs = tkParamDefs.Length;
+
+ // Not all parameters have tokens. Parameters may have no token
+ // if they have no name and no attributes.
+ if (cParamDefs > sigArgCount + 1 /* return type */)
+ throw new BadImageFormatException(SR.BadImageFormat_ParameterSignatureMismatch);
+
+ for (int i = 0; i < cParamDefs; i++)
+ {
+ #region Populate ParameterInfos
+ ParameterAttributes attr;
+ int position, tkParamDef = tkParamDefs[i];
+
+ scope.GetParamDefProps(tkParamDef, out position, out attr);
+
+ position--;
+
+ if (fetchReturnParameter == true && position == -1)
+ {
+ // more than one return parameter?
+ if (returnParameter != null)
+ throw new BadImageFormatException(SR.BadImageFormat_ParameterSignatureMismatch);
+
+ returnParameter = new RuntimeParameterInfo(sig, scope, tkParamDef, position, attr, member);
+ }
+ else if (fetchReturnParameter == false && position >= 0)
+ {
+ // position beyong sigArgCount?
+ if (position >= sigArgCount)
+ throw new BadImageFormatException(SR.BadImageFormat_ParameterSignatureMismatch);
+
+ args[position] = new RuntimeParameterInfo(sig, scope, tkParamDef, position, attr, member);
+ }
+ #endregion
+ }
+ }
+
+ // Fill in empty ParameterInfos for those without tokens
+ if (fetchReturnParameter)
+ {
+ if (returnParameter == null)
+ {
+ returnParameter = new RuntimeParameterInfo(sig, MetadataImport.EmptyImport, 0, -1, (ParameterAttributes)0, member);
+ }
+ }
+ else
+ {
+ if (cParamDefs < args.Length + 1)
+ {
+ for (int i = 0; i < args.Length; i++)
+ {
+ if (args[i] != null)
+ continue;
+
+ args[i] = new RuntimeParameterInfo(sig, MetadataImport.EmptyImport, 0, i, (ParameterAttributes)0, member);
+ }
+ }
+ }
+
+ return args;
+ }
+ #endregion
+
+ #region Private Statics
+ private static readonly Type s_DecimalConstantAttributeType = typeof(DecimalConstantAttribute);
+ private static readonly Type s_CustomConstantAttributeType = typeof(CustomConstantAttribute);
+ #endregion
+
+ #region Private Data Members
+ // These are new in Whidbey, so we cannot serialize them directly or we break backwards compatibility.
+ [NonSerialized]
+ private int m_tkParamDef;
+ [NonSerialized]
+ private MetadataImport m_scope;
+ [NonSerialized]
+ private Signature m_signature;
+ [NonSerialized]
+ private volatile bool m_nameIsCached = false;
+ [NonSerialized]
+ private readonly bool m_noMetadata = false;
+ [NonSerialized]
+ private bool m_noDefaultValue = false;
+ [NonSerialized]
+ private MethodBase m_originalMember = null;
+ #endregion
+
+ #region Internal Properties
+ internal MethodBase DefiningMethod
+ {
+ get
+ {
+ MethodBase result = m_originalMember != null ? m_originalMember : MemberImpl as MethodBase;
+ Debug.Assert(result != null);
+ return result;
+ }
+ }
+ #endregion
+
+ #region Internal Methods
+ internal void SetName(string name)
+ {
+ NameImpl = name;
+ }
+
+ internal void SetAttributes(ParameterAttributes attributes)
+ {
+ AttrsImpl = attributes;
+ }
+ #endregion
+
+ #region VTS magic to serialize/deserialized to/from pre-Whidbey endpoints.
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ // We could be serializing for consumption by a pre-Whidbey
+ // endpoint. Therefore we set up all the serialized fields to look
+ // just like a v1.0/v1.1 instance.
+
+ // Need to set the type to ParameterInfo so that pre-Whidbey and Whidbey code
+ // can deserialize this. This is also why we cannot simply use [OnSerializing].
+ info.SetType(typeof(ParameterInfo));
+
+ // Use the properties intead of the fields in case the fields haven't been et
+ // _importer, bExtraConstChecked, and m_cachedData don't need to be set
+
+ // Now set the legacy fields that the current implementation doesn't
+ // use any more. Note that _importer is a raw pointer that should
+ // never have been serialized in V1. We set it to zero here; if the
+ // deserializer uses it (by calling GetCustomAttributes() on this
+ // instance) they'll AV, but at least it will be a well defined
+ // exception and not a random AV.
+
+ info.AddValue("AttrsImpl", Attributes);
+ info.AddValue("ClassImpl", ParameterType);
+ info.AddValue("DefaultValueImpl", DefaultValue);
+ info.AddValue("MemberImpl", Member);
+ info.AddValue("NameImpl", Name);
+ info.AddValue("PositionImpl", Position);
+ info.AddValue("_token", m_tkParamDef);
+ }
+ #endregion
+
+ #region Constructor
+ // used by RuntimePropertyInfo
+ internal RuntimeParameterInfo(RuntimeParameterInfo accessor, RuntimePropertyInfo property)
+ : this(accessor, (MemberInfo)property)
+ {
+ m_signature = property.Signature;
+ }
+
+ private RuntimeParameterInfo(RuntimeParameterInfo accessor, MemberInfo member)
+ {
+ // Change ownership
+ MemberImpl = member;
+
+ // The original owner should always be a method, because this method is only used to
+ // change the owner from a method to a property.
+ m_originalMember = accessor.MemberImpl as MethodBase;
+ Debug.Assert(m_originalMember != null);
+
+ // Populate all the caches -- we inherit this behavior from RTM
+ NameImpl = accessor.Name;
+ m_nameIsCached = true;
+ ClassImpl = accessor.ParameterType;
+ PositionImpl = accessor.Position;
+ AttrsImpl = accessor.Attributes;
+
+ // Strictly speeking, property's don't contain paramter tokens
+ // However we need this to make ca's work... oh well...
+ m_tkParamDef = MdToken.IsNullToken(accessor.MetadataToken) ? (int)MetadataTokenType.ParamDef : accessor.MetadataToken;
+ m_scope = accessor.m_scope;
+ }
+
+ private RuntimeParameterInfo(
+ Signature signature, MetadataImport scope, int tkParamDef,
+ int position, ParameterAttributes attributes, MemberInfo member)
+ {
+ Contract.Requires(member != null);
+ Debug.Assert(MdToken.IsNullToken(tkParamDef) == scope.Equals(MetadataImport.EmptyImport));
+ Debug.Assert(MdToken.IsNullToken(tkParamDef) || MdToken.IsTokenOfType(tkParamDef, MetadataTokenType.ParamDef));
+
+ PositionImpl = position;
+ MemberImpl = member;
+ m_signature = signature;
+ m_tkParamDef = MdToken.IsNullToken(tkParamDef) ? (int)MetadataTokenType.ParamDef : tkParamDef;
+ m_scope = scope;
+ AttrsImpl = attributes;
+
+ ClassImpl = null;
+ NameImpl = null;
+ }
+
+ // ctor for no metadata MethodInfo in the DynamicMethod and RuntimeMethodInfo cases
+ internal RuntimeParameterInfo(MethodInfo owner, String name, Type parameterType, int position)
+ {
+ MemberImpl = owner;
+ NameImpl = name;
+ m_nameIsCached = true;
+ m_noMetadata = true;
+ ClassImpl = parameterType;
+ PositionImpl = position;
+ AttrsImpl = ParameterAttributes.None;
+ m_tkParamDef = (int)MetadataTokenType.ParamDef;
+ m_scope = MetadataImport.EmptyImport;
+ }
+ #endregion
+
+ #region Public Methods
+ public override Type ParameterType
+ {
+ get
+ {
+ // only instance of ParameterInfo has ClassImpl, all its subclasses don't
+ if (ClassImpl == null)
+ {
+ RuntimeType parameterType;
+ if (PositionImpl == -1)
+ parameterType = m_signature.ReturnType;
+ else
+ parameterType = m_signature.Arguments[PositionImpl];
+
+ Debug.Assert(parameterType != null);
+ // different thread could only write ClassImpl to the same value, so a race condition is not a problem here
+ ClassImpl = parameterType;
+ }
+
+ return ClassImpl;
+ }
+ }
+
+ public override String Name
+ {
+ get
+ {
+ if (!m_nameIsCached)
+ {
+ if (!MdToken.IsNullToken(m_tkParamDef))
+ {
+ string name;
+ name = m_scope.GetName(m_tkParamDef).ToString();
+ NameImpl = name;
+ }
+
+ // other threads could only write it to true, so a race condition is OK
+ // this field is volatile, so the write ordering is guaranteed
+ m_nameIsCached = true;
+ }
+
+ // name may be null
+ return NameImpl;
+ }
+ }
+
+ public override bool HasDefaultValue
+ {
+ get
+ {
+ if (m_noMetadata || m_noDefaultValue)
+ return false;
+
+ object defaultValue = GetDefaultValueInternal(false);
+
+ return (defaultValue != DBNull.Value);
+ }
+ }
+
+ public override Object DefaultValue { get { return GetDefaultValue(false); } }
+ public override Object RawDefaultValue { get { return GetDefaultValue(true); } }
+
+ private Object GetDefaultValue(bool raw)
+ {
+ // OLD COMMENT (Is this even true?)
+ // Cannot cache because default value could be non-agile user defined enumeration.
+ // OLD COMMENT ends
+ if (m_noMetadata)
+ return null;
+
+ // for dynamic method we pretend to have cached the value so we do not go to metadata
+ object defaultValue = GetDefaultValueInternal(raw);
+
+ if (defaultValue == DBNull.Value)
+ {
+ #region Handle case if no default value was found
+ if (IsOptional)
+ {
+ // If the argument is marked as optional then the default value is Missing.Value.
+ defaultValue = Type.Missing;
+ }
+ #endregion
+ }
+
+ return defaultValue;
+ }
+
+ // returns DBNull.Value if the parameter doesn't have a default value
+ private Object GetDefaultValueInternal(bool raw)
+ {
+ Debug.Assert(!m_noMetadata);
+
+ if (m_noDefaultValue)
+ return DBNull.Value;
+
+ object defaultValue = null;
+
+ // Why check the parameter type only for DateTime and only for the ctor arguments?
+ // No check on the parameter type is done for named args and for Decimal.
+
+ // We should move this after MdToken.IsNullToken(m_tkParamDef) and combine it
+ // with the other custom attribute logic. But will that be a breaking change?
+ // For a DateTime parameter on which both an md constant and a ca constant are set,
+ // which one should win?
+ if (ParameterType == typeof(DateTime))
+ {
+ if (raw)
+ {
+ CustomAttributeTypedArgument value =
+ CustomAttributeData.Filter(
+ CustomAttributeData.GetCustomAttributes(this), typeof(DateTimeConstantAttribute), 0);
+
+ if (value.ArgumentType != null)
+ return new DateTime((long)value.Value);
+ }
+ else
+ {
+ object[] dt = GetCustomAttributes(typeof(DateTimeConstantAttribute), false);
+ if (dt != null && dt.Length != 0)
+ return ((DateTimeConstantAttribute)dt[0]).Value;
+ }
+ }
+
+ #region Look for a default value in metadata
+ if (!MdToken.IsNullToken(m_tkParamDef))
+ {
+ // This will return DBNull.Value if no constant value is defined on m_tkParamDef in the metadata.
+ defaultValue = MdConstant.GetValue(m_scope, m_tkParamDef, ParameterType.GetTypeHandleInternal(), raw);
+ }
+ #endregion
+
+ if (defaultValue == DBNull.Value)
+ {
+ #region Look for a default value in the custom attributes
+ if (raw)
+ {
+ foreach (CustomAttributeData attr in CustomAttributeData.GetCustomAttributes(this))
+ {
+ Type attrType = attr.Constructor.DeclaringType;
+
+ if (attrType == typeof(DateTimeConstantAttribute))
+ {
+ defaultValue = DateTimeConstantAttribute.GetRawDateTimeConstant(attr);
+ }
+ else if (attrType == typeof(DecimalConstantAttribute))
+ {
+ defaultValue = DecimalConstantAttribute.GetRawDecimalConstant(attr);
+ }
+ else if (attrType.IsSubclassOf(s_CustomConstantAttributeType))
+ {
+ defaultValue = CustomConstantAttribute.GetRawConstant(attr);
+ }
+ }
+ }
+ else
+ {
+ Object[] CustomAttrs = GetCustomAttributes(s_CustomConstantAttributeType, false);
+ if (CustomAttrs.Length != 0)
+ {
+ defaultValue = ((CustomConstantAttribute)CustomAttrs[0]).Value;
+ }
+ else
+ {
+ CustomAttrs = GetCustomAttributes(s_DecimalConstantAttributeType, false);
+ if (CustomAttrs.Length != 0)
+ {
+ defaultValue = ((DecimalConstantAttribute)CustomAttrs[0]).Value;
+ }
+ }
+ }
+ #endregion
+ }
+
+ if (defaultValue == DBNull.Value)
+ m_noDefaultValue = true;
+
+ return defaultValue;
+ }
+
+ internal RuntimeModule GetRuntimeModule()
+ {
+ RuntimeMethodInfo method = Member as RuntimeMethodInfo;
+ RuntimeConstructorInfo constructor = Member as RuntimeConstructorInfo;
+ RuntimePropertyInfo property = Member as RuntimePropertyInfo;
+
+ if (method != null)
+ return method.GetRuntimeModule();
+ else if (constructor != null)
+ return constructor.GetRuntimeModule();
+ else if (property != null)
+ return property.GetRuntimeModule();
+ else
+ return null;
+ }
+
+ public override int MetadataToken
+ {
+ get
+ {
+ return m_tkParamDef;
+ }
+ }
+
+ public override Type[] GetRequiredCustomModifiers()
+ {
+ return m_signature.GetCustomModifiers(PositionImpl + 1, true);
+ }
+
+ public override Type[] GetOptionalCustomModifiers()
+ {
+ return m_signature.GetCustomModifiers(PositionImpl + 1, false);
+ }
+
+ #endregion
+
+ #region ICustomAttributeProvider
+ public override Object[] GetCustomAttributes(bool inherit)
+ {
+ if (MdToken.IsNullToken(m_tkParamDef))
+ return Array.Empty<Object>();
+
+ return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
+ }
+
+ public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ if (MdToken.IsNullToken(m_tkParamDef))
+ return Array.Empty<Object>();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
+ }
+
+ public override bool IsDefined(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ if (MdToken.IsNullToken(m_tkParamDef))
+ return false;
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.IsDefined(this, attributeRuntimeType);
+ }
+
+ public override IList<CustomAttributeData> GetCustomAttributesData()
+ {
+ return CustomAttributeData.GetCustomAttributesInternal(this);
+ }
+ #endregion
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/RuntimePropertyInfo.cs b/src/mscorlib/src/System/Reflection/RuntimePropertyInfo.cs
new file mode 100644
index 0000000000..b6a4792e4f
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/RuntimePropertyInfo.cs
@@ -0,0 +1,467 @@
+// 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.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Runtime.Serialization;
+using System.Text;
+using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
+
+namespace System.Reflection
+{
+ [Serializable]
+ internal unsafe sealed class RuntimePropertyInfo : PropertyInfo, ISerializable
+ {
+ #region Private Data Members
+ private int m_token;
+ private string m_name;
+ private void* m_utf8name;
+ private PropertyAttributes m_flags;
+ private RuntimeTypeCache m_reflectedTypeCache;
+ private RuntimeMethodInfo m_getterMethod;
+ private RuntimeMethodInfo m_setterMethod;
+ private MethodInfo[] m_otherMethod;
+ private RuntimeType m_declaringType;
+ private BindingFlags m_bindingFlags;
+ private Signature m_signature;
+ private ParameterInfo[] m_parameters;
+ #endregion
+
+ #region Constructor
+ internal RuntimePropertyInfo(
+ int tkProperty, RuntimeType declaredType, RuntimeTypeCache reflectedTypeCache, out bool isPrivate)
+ {
+ Contract.Requires(declaredType != null);
+ Contract.Requires(reflectedTypeCache != null);
+ Debug.Assert(!reflectedTypeCache.IsGlobal);
+
+ MetadataImport scope = declaredType.GetRuntimeModule().MetadataImport;
+
+ m_token = tkProperty;
+ m_reflectedTypeCache = reflectedTypeCache;
+ m_declaringType = declaredType;
+
+ ConstArray sig;
+ scope.GetPropertyProps(tkProperty, out m_utf8name, out m_flags, out sig);
+
+ RuntimeMethodInfo dummy;
+ Associates.AssignAssociates(scope, tkProperty, declaredType, reflectedTypeCache.GetRuntimeType(),
+ out dummy, out dummy, out dummy,
+ out m_getterMethod, out m_setterMethod, out m_otherMethod,
+ out isPrivate, out m_bindingFlags);
+ }
+ #endregion
+
+ #region Internal Members
+ internal override bool CacheEquals(object o)
+ {
+ RuntimePropertyInfo m = o as RuntimePropertyInfo;
+
+ if ((object)m == null)
+ return false;
+
+ return m.m_token == m_token &&
+ RuntimeTypeHandle.GetModule(m_declaringType).Equals(
+ RuntimeTypeHandle.GetModule(m.m_declaringType));
+ }
+
+ internal Signature Signature
+ {
+ get
+ {
+ if (m_signature == null)
+ {
+ PropertyAttributes flags;
+ ConstArray sig;
+
+ void* name;
+ GetRuntimeModule().MetadataImport.GetPropertyProps(
+ m_token, out name, out flags, out sig);
+
+ m_signature = new Signature(sig.Signature.ToPointer(), (int)sig.Length, m_declaringType);
+ }
+
+ return m_signature;
+ }
+ }
+ internal bool EqualsSig(RuntimePropertyInfo target)
+ {
+ //@Asymmetry - Legacy policy is to remove duplicate properties, including hidden properties.
+ // The comparison is done by name and by sig. The EqualsSig comparison is expensive
+ // but forutnetly it is only called when an inherited property is hidden by name or
+ // when an interfaces declare properies with the same signature.
+ // Note that we intentionally don't resolve generic arguments so that we don't treat
+ // signatures that only match in certain instantiations as duplicates. This has the
+ // down side of treating overriding and overriden properties as different properties
+ // in some cases. But PopulateProperties in rttype.cs should have taken care of that
+ // by comparing VTable slots.
+ //
+ // Class C1(Of T, Y)
+ // Property Prop1(ByVal t1 As T) As Integer
+ // Get
+ // ... ...
+ // End Get
+ // End Property
+ // Property Prop1(ByVal y1 As Y) As Integer
+ // Get
+ // ... ...
+ // End Get
+ // End Property
+ // End Class
+ //
+
+ Contract.Requires(Name.Equals(target.Name));
+ Contract.Requires(this != target);
+ Contract.Requires(this.ReflectedType == target.ReflectedType);
+
+ return Signature.CompareSig(this.Signature, target.Signature);
+ }
+ internal BindingFlags BindingFlags { get { return m_bindingFlags; } }
+ #endregion
+
+ #region Object Overrides
+ public override String ToString()
+ {
+ return FormatNameAndSig(false);
+ }
+
+ private string FormatNameAndSig(bool serialization)
+ {
+ StringBuilder sbName = new StringBuilder(PropertyType.FormatTypeName(serialization));
+
+ sbName.Append(" ");
+ sbName.Append(Name);
+
+ RuntimeType[] arguments = Signature.Arguments;
+ if (arguments.Length > 0)
+ {
+ sbName.Append(" [");
+ sbName.Append(MethodBase.ConstructParameters(arguments, Signature.CallingConvention, serialization));
+ sbName.Append("]");
+ }
+
+ return sbName.ToString();
+ }
+ #endregion
+
+ #region ICustomAttributeProvider
+ public override Object[] GetCustomAttributes(bool inherit)
+ {
+ return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType);
+ }
+
+ public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType);
+ }
+
+ public override bool IsDefined(Type attributeType, bool inherit)
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException(nameof(attributeType));
+ Contract.EndContractBlock();
+
+ RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
+
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
+
+ return CustomAttribute.IsDefined(this, attributeRuntimeType);
+ }
+
+ public override IList<CustomAttributeData> GetCustomAttributesData()
+ {
+ return CustomAttributeData.GetCustomAttributesInternal(this);
+ }
+ #endregion
+
+ #region MemberInfo Overrides
+ public override MemberTypes MemberType { get { return MemberTypes.Property; } }
+ public override String Name
+ {
+ get
+ {
+ if (m_name == null)
+ m_name = new Utf8String(m_utf8name).ToString();
+
+ return m_name;
+ }
+ }
+ public override Type DeclaringType
+ {
+ get
+ {
+ return m_declaringType;
+ }
+ }
+
+ public override Type ReflectedType
+ {
+ get
+ {
+ return ReflectedTypeInternal;
+ }
+ }
+
+ private RuntimeType ReflectedTypeInternal
+ {
+ get
+ {
+ return m_reflectedTypeCache.GetRuntimeType();
+ }
+ }
+
+ public override int MetadataToken { get { return m_token; } }
+
+ public override Module Module { get { return GetRuntimeModule(); } }
+ internal RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); }
+ #endregion
+
+ #region PropertyInfo Overrides
+
+ #region Non Dynamic
+
+ public override Type[] GetRequiredCustomModifiers()
+ {
+ return Signature.GetCustomModifiers(0, true);
+ }
+
+ public override Type[] GetOptionalCustomModifiers()
+ {
+ return Signature.GetCustomModifiers(0, false);
+ }
+
+ internal object GetConstantValue(bool raw)
+ {
+ Object defaultValue = MdConstant.GetValue(GetRuntimeModule().MetadataImport, m_token, PropertyType.GetTypeHandleInternal(), raw);
+
+ if (defaultValue == DBNull.Value)
+ // Arg_EnumLitValueNotFound -> "Literal value was not found."
+ throw new InvalidOperationException(SR.Arg_EnumLitValueNotFound);
+
+ return defaultValue;
+ }
+
+ public override object GetConstantValue() { return GetConstantValue(false); }
+
+ public override object GetRawConstantValue() { return GetConstantValue(true); }
+
+ public override MethodInfo[] GetAccessors(bool nonPublic)
+ {
+ List<MethodInfo> accessorList = new List<MethodInfo>();
+
+ if (Associates.IncludeAccessor(m_getterMethod, nonPublic))
+ accessorList.Add(m_getterMethod);
+
+ if (Associates.IncludeAccessor(m_setterMethod, nonPublic))
+ accessorList.Add(m_setterMethod);
+
+ if ((object)m_otherMethod != null)
+ {
+ for (int i = 0; i < m_otherMethod.Length; i++)
+ {
+ if (Associates.IncludeAccessor(m_otherMethod[i] as MethodInfo, nonPublic))
+ accessorList.Add(m_otherMethod[i]);
+ }
+ }
+ return accessorList.ToArray();
+ }
+
+ public override Type PropertyType
+ {
+ get { return Signature.ReturnType; }
+ }
+
+ public override MethodInfo GetGetMethod(bool nonPublic)
+ {
+ if (!Associates.IncludeAccessor(m_getterMethod, nonPublic))
+ return null;
+
+ return m_getterMethod;
+ }
+
+ public override MethodInfo GetSetMethod(bool nonPublic)
+ {
+ if (!Associates.IncludeAccessor(m_setterMethod, nonPublic))
+ return null;
+
+ return m_setterMethod;
+ }
+
+ public override ParameterInfo[] GetIndexParameters()
+ {
+ ParameterInfo[] indexParams = GetIndexParametersNoCopy();
+
+ int numParams = indexParams.Length;
+
+ if (numParams == 0)
+ return indexParams;
+
+ ParameterInfo[] ret = new ParameterInfo[numParams];
+
+ Array.Copy(indexParams, ret, numParams);
+
+ return ret;
+ }
+
+ internal ParameterInfo[] GetIndexParametersNoCopy()
+ {
+ // @History - Logic ported from RTM
+
+ // No need to lock because we don't guarantee the uniqueness of ParameterInfo objects
+ if (m_parameters == null)
+ {
+ int numParams = 0;
+ ParameterInfo[] methParams = null;
+
+ // First try to get the Get method.
+ MethodInfo m = GetGetMethod(true);
+ if (m != null)
+ {
+ // There is a Get method so use it.
+ methParams = m.GetParametersNoCopy();
+ numParams = methParams.Length;
+ }
+ else
+ {
+ // If there is no Get method then use the Set method.
+ m = GetSetMethod(true);
+
+ if (m != null)
+ {
+ methParams = m.GetParametersNoCopy();
+ numParams = methParams.Length - 1;
+ }
+ }
+
+ // Now copy over the parameter info's and change their
+ // owning member info to the current property info.
+
+ ParameterInfo[] propParams = new ParameterInfo[numParams];
+
+ for (int i = 0; i < numParams; i++)
+ propParams[i] = new RuntimeParameterInfo((RuntimeParameterInfo)methParams[i], this);
+
+ m_parameters = propParams;
+ }
+
+ return m_parameters;
+ }
+
+ public override PropertyAttributes Attributes
+ {
+ get
+ {
+ return m_flags;
+ }
+ }
+
+ public override bool CanRead
+ {
+ get
+ {
+ return m_getterMethod != null;
+ }
+ }
+
+ public override bool CanWrite
+ {
+ get
+ {
+ return m_setterMethod != null;
+ }
+ }
+ #endregion
+
+ #region Dynamic
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ public override Object GetValue(Object obj, Object[] index)
+ {
+ return GetValue(obj, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static,
+ null, index, null);
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ public override Object GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
+ {
+ MethodInfo m = GetGetMethod(true);
+ if (m == null)
+ throw new ArgumentException(System.SR.Arg_GetMethNotFnd);
+ return m.Invoke(obj, invokeAttr, binder, index, null);
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ public override void SetValue(Object obj, Object value, Object[] index)
+ {
+ SetValue(obj,
+ value,
+ BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static,
+ null,
+ index,
+ null);
+ }
+
+ [DebuggerStepThroughAttribute]
+ [Diagnostics.DebuggerHidden]
+ public override void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
+ {
+ MethodInfo m = GetSetMethod(true);
+
+ if (m == null)
+ throw new ArgumentException(System.SR.Arg_SetMethNotFnd);
+
+ Object[] args = null;
+
+ if (index != null)
+ {
+ args = new Object[index.Length + 1];
+
+ for (int i = 0; i < index.Length; i++)
+ args[i] = index[i];
+
+ args[index.Length] = value;
+ }
+ else
+ {
+ args = new Object[1];
+ args[0] = value;
+ }
+
+ m.Invoke(obj, invokeAttr, binder, args, culture);
+ }
+ #endregion
+
+ #endregion
+
+ #region ISerializable Implementation
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ throw new ArgumentNullException(nameof(info));
+ Contract.EndContractBlock();
+
+ MemberInfoSerializationHolder.GetSerializationInfo(info, this);
+ }
+
+ internal string SerializationToString()
+ {
+ return FormatNameAndSig(true);
+ }
+ #endregion
+ }
+}
diff --git a/src/mscorlib/src/System/Reflection/RuntimeReflectionExtensions.cs b/src/mscorlib/src/System/Reflection/RuntimeReflectionExtensions.cs
deleted file mode 100644
index 49262634e3..0000000000
--- a/src/mscorlib/src/System/Reflection/RuntimeReflectionExtensions.cs
+++ /dev/null
@@ -1,88 +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.Collections.Generic;
-
-namespace System.Reflection
-{
- public static class RuntimeReflectionExtensions
- {
- private const BindingFlags everything = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
-
- private static void CheckAndThrow(Type type)
- {
- if (type == null) throw new ArgumentNullException(nameof(type));
- if (!(type is RuntimeType)) throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"));
- }
-
- private static void CheckAndThrow(MethodInfo method)
- {
- if (method == null) throw new ArgumentNullException(nameof(method));
- if (!(method is RuntimeMethodInfo)) throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"));
- }
-
- public static IEnumerable<PropertyInfo> GetRuntimeProperties(this Type type)
- {
- CheckAndThrow(type);
- return type.GetProperties(everything);
- }
- public static IEnumerable<EventInfo> GetRuntimeEvents(this Type type)
- {
- CheckAndThrow(type);
- return type.GetEvents(everything);
- }
-
- public static IEnumerable<MethodInfo> GetRuntimeMethods(this Type type)
- {
- CheckAndThrow(type);
- return type.GetMethods(everything);
- }
-
- public static IEnumerable<FieldInfo> GetRuntimeFields(this Type type)
- {
- CheckAndThrow(type);
- return type.GetFields(everything);
- }
-
- public static PropertyInfo GetRuntimeProperty(this Type type, string name)
- {
- CheckAndThrow(type);
- return type.GetProperty(name);
- }
- public static EventInfo GetRuntimeEvent(this Type type, string name)
- {
- CheckAndThrow(type);
- return type.GetEvent(name);
- }
- public static MethodInfo GetRuntimeMethod(this Type type, string name, Type[] parameters)
- {
- CheckAndThrow(type);
- return type.GetMethod(name, parameters);
- }
- public static FieldInfo GetRuntimeField(this Type type, string name)
- {
- CheckAndThrow(type);
- return type.GetField(name);
- }
- public static MethodInfo GetRuntimeBaseDefinition(this MethodInfo method){
- CheckAndThrow(method);
- return method.GetBaseDefinition();
- }
-
- public static InterfaceMapping GetRuntimeInterfaceMap(this TypeInfo typeInfo, Type interfaceType)
- {
- if (typeInfo == null) throw new ArgumentNullException(nameof(typeInfo));
- if (!(typeInfo is RuntimeType)) throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"));
-
- return typeInfo.GetInterfaceMap(interfaceType);
- }
-
- public static MethodInfo GetMethodInfo(this Delegate del)
- {
- if (del == null) throw new ArgumentNullException(nameof(del));
-
- return del.Method;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/StrongNameKeyPair.cs b/src/mscorlib/src/System/Reflection/StrongNameKeyPair.cs
deleted file mode 100644
index 0121982489..0000000000
--- a/src/mscorlib/src/System/Reflection/StrongNameKeyPair.cs
+++ /dev/null
@@ -1,95 +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.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Encapsulate access to a public/private key pair
-** used to sign strong name assemblies.
-**
-**
-===========================================================*/
-namespace System.Reflection
-{
- using System;
- using System.IO;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.InteropServices;
- using System.Runtime.Serialization;
- using System.Security;
- using System.Runtime.Versioning;
- using Microsoft.Win32;
- using System.Diagnostics.Contracts;
-
- [Serializable]
- public class StrongNameKeyPair : IDeserializationCallback, ISerializable
- {
- private bool _keyPairExported;
- private byte[] _keyPairArray;
- private String _keyPairContainer;
- private byte[] _publicKey;
-
- // Build key pair from file.
- public StrongNameKeyPair(FileStream keyPairFile)
- {
- if (keyPairFile == null)
- throw new ArgumentNullException(nameof(keyPairFile));
- Contract.EndContractBlock();
-
- int length = (int)keyPairFile.Length;
- _keyPairArray = new byte[length];
- keyPairFile.Read(_keyPairArray, 0, length);
-
- _keyPairExported = true;
- }
-
- // Build key pair from byte array in memory.
- public StrongNameKeyPair(byte[] keyPairArray)
- {
- if (keyPairArray == null)
- throw new ArgumentNullException(nameof(keyPairArray));
- Contract.EndContractBlock();
-
- _keyPairArray = new byte[keyPairArray.Length];
- Array.Copy(keyPairArray, _keyPairArray, keyPairArray.Length);
-
- _keyPairExported = true;
- }
-
- protected StrongNameKeyPair (SerializationInfo info, StreamingContext context) {
- _keyPairExported = (bool) info.GetValue("_keyPairExported", typeof(bool));
- _keyPairArray = (byte[]) info.GetValue("_keyPairArray", typeof(byte[]));
- _keyPairContainer = (string) info.GetValue("_keyPairContainer", typeof(string));
- _publicKey = (byte[]) info.GetValue("_publicKey", typeof(byte[]));
- }
-
- public StrongNameKeyPair(String keyPairContainer)
- {
- throw new PlatformNotSupportedException();
- }
-
- public byte[] PublicKey
- {
- get
- {
- throw new PlatformNotSupportedException();
- }
- }
-
- /// <internalonly/>
- void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context) {
- info.AddValue("_keyPairExported", _keyPairExported);
- info.AddValue("_keyPairArray", _keyPairArray);
- info.AddValue("_keyPairContainer", _keyPairContainer);
- info.AddValue("_publicKey", _publicKey);
- }
-
- /// <internalonly/>
- void IDeserializationCallback.OnDeserialization (Object sender) {}
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/TargetException.cs b/src/mscorlib/src/System/Reflection/TargetException.cs
deleted file mode 100644
index dcbb38833e..0000000000
--- a/src/mscorlib/src/System/Reflection/TargetException.cs
+++ /dev/null
@@ -1,37 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// TargetException is thrown when the target to an Invoke is invalid. This may
-//
-// occur because the caller doesn't have access to the member, or the target doesn't
-// define the member, etc.
-//
-//
-//
-//
-namespace System.Reflection {
-
- using System;
- using System.Runtime.Serialization;
- [Serializable]
- public class TargetException : ApplicationException {
- public TargetException() : base() {
- SetErrorCode(__HResults.COR_E_TARGET);
- }
-
- public TargetException(String message) : base(message) {
- SetErrorCode(__HResults.COR_E_TARGET);
- }
-
- public TargetException(String message, Exception inner) : base(message, inner) {
- SetErrorCode(__HResults.COR_E_TARGET);
- }
-
- protected TargetException(SerializationInfo info, StreamingContext context) : base (info, context) {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/TargetInvocationException.cs b/src/mscorlib/src/System/Reflection/TargetInvocationException.cs
deleted file mode 100644
index 7bbc93df2a..0000000000
--- a/src/mscorlib/src/System/Reflection/TargetInvocationException.cs
+++ /dev/null
@@ -1,46 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// TargetInvocationException is used to report an exception that was thrown
-//
-// by the target of an invocation.
-//
-//
-//
-//
-namespace System.Reflection {
-
-
- using System;
- using System.Runtime.Serialization;
- [Serializable]
- public sealed class TargetInvocationException : ApplicationException {
- // This exception is not creatable without specifying the
- // inner exception.
- private TargetInvocationException()
- : base(Environment.GetResourceString("Arg_TargetInvocationException")) {
- SetErrorCode(__HResults.COR_E_TARGETINVOCATION);
- }
-
- // This is called from within the runtime.
- private TargetInvocationException(String message) : base(message) {
- SetErrorCode(__HResults.COR_E_TARGETINVOCATION);
- }
-
- public TargetInvocationException(System.Exception inner)
- : base(Environment.GetResourceString("Arg_TargetInvocationException"), inner) {
- SetErrorCode(__HResults.COR_E_TARGETINVOCATION);
- }
-
- public TargetInvocationException(String message, Exception inner) : base(message, inner) {
- SetErrorCode(__HResults.COR_E_TARGETINVOCATION);
- }
-
- internal TargetInvocationException(SerializationInfo info, StreamingContext context) : base (info, context) {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/TargetParameterCountException.cs b/src/mscorlib/src/System/Reflection/TargetParameterCountException.cs
deleted file mode 100644
index 7a07b20acd..0000000000
--- a/src/mscorlib/src/System/Reflection/TargetParameterCountException.cs
+++ /dev/null
@@ -1,40 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// TargetParameterCountException is thrown when the number of parameter to an
-//
-// invocation doesn't match the number expected.
-//
-//
-//
-//
-namespace System.Reflection {
-
- using System;
- using SystemException = System.SystemException;
- using System.Runtime.Serialization;
- [Serializable]
- public sealed class TargetParameterCountException : ApplicationException {
- public TargetParameterCountException()
- : base(Environment.GetResourceString("Arg_TargetParameterCountException")) {
- SetErrorCode(__HResults.COR_E_TARGETPARAMCOUNT);
- }
-
- public TargetParameterCountException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_TARGETPARAMCOUNT);
- }
-
- public TargetParameterCountException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_TARGETPARAMCOUNT);
- }
-
- internal TargetParameterCountException(SerializationInfo info, StreamingContext context) : base (info, context) {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/TypeAttributes.cs b/src/mscorlib/src/System/Reflection/TypeAttributes.cs
deleted file mode 100644
index 25aa113d2e..0000000000
--- a/src/mscorlib/src/System/Reflection/TypeAttributes.cs
+++ /dev/null
@@ -1,64 +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.
-
-namespace System.Reflection {
- using System.Runtime.InteropServices;
- using System;
- // This Enum matchs the CorTypeAttr defined in CorHdr.h
-[Serializable]
-[Flags]
- public enum TypeAttributes
- {
- VisibilityMask = 0x00000007,
- NotPublic = 0x00000000, // Class is not public scope.
- Public = 0x00000001, // Class is public scope.
- NestedPublic = 0x00000002, // Class is nested with public visibility.
- NestedPrivate = 0x00000003, // Class is nested with private visibility.
- NestedFamily = 0x00000004, // Class is nested with family visibility.
- NestedAssembly = 0x00000005, // Class is nested with assembly visibility.
- NestedFamANDAssem = 0x00000006, // Class is nested with family and assembly visibility.
- NestedFamORAssem = 0x00000007, // Class is nested with family or assembly visibility.
-
- // Use this mask to retrieve class layout informaiton
- // 0 is AutoLayout, 0x2 is SequentialLayout, 4 is ExplicitLayout
- LayoutMask = 0x00000018,
- AutoLayout = 0x00000000, // Class fields are auto-laid out
- SequentialLayout = 0x00000008, // Class fields are laid out sequentially
- ExplicitLayout = 0x00000010, // Layout is supplied explicitly
- // end layout mask
-
- // Use this mask to distinguish whether a type declaration is an interface. (Class vs. ValueType done based on whether it subclasses S.ValueType)
- ClassSemanticsMask= 0x00000020,
- Class = 0x00000000, // Type is a class (or a value type).
- Interface = 0x00000020, // Type is an interface.
-
- // Special semantics in addition to class semantics.
- Abstract = 0x00000080, // Class is abstract
- Sealed = 0x00000100, // Class is concrete and may not be extended
- SpecialName = 0x00000400, // Class name is special. Name describes how.
-
- // Implementation attributes.
- Import = 0x00001000, // Class / interface is imported
- Serializable = 0x00002000, // The class is Serializable.
-
- WindowsRuntime = 0x00004000, // Type is a Windows Runtime type.
-
- // Use tdStringFormatMask to retrieve string information for native interop
- StringFormatMask = 0x00030000,
- AnsiClass = 0x00000000, // LPTSTR is interpreted as ANSI in this class
- UnicodeClass = 0x00010000, // LPTSTR is interpreted as UNICODE
- AutoClass = 0x00020000, // LPTSTR is interpreted automatically
- CustomFormatClass = 0x00030000, // A non-standard encoding specified by CustomFormatMask
- CustomFormatMask = 0x00C00000, // Use this mask to retrieve non-standard encoding information for native interop. The meaning of the values of these 2 bits is unspecified.
-
- // end string format mask
-
- BeforeFieldInit = 0x00100000, // Initialize the class any time before first static field access.
-
- // Flags reserved for runtime use.
- ReservedMask = 0x00040800,
- RTSpecialName = 0x00000800, // Runtime should check name encoding.
- HasSecurity = 0x00040000, // Class has security associate with it.
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/TypeDelegator.cs b/src/mscorlib/src/System/Reflection/TypeDelegator.cs
deleted file mode 100644
index 6a77a95853..0000000000
--- a/src/mscorlib/src/System/Reflection/TypeDelegator.cs
+++ /dev/null
@@ -1,257 +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.
-
-// TypeDelegator
-//
-// This class wraps a Type object and delegates all methods to that Type.
-
-namespace System.Reflection {
-
- using System;
- using System.Runtime.InteropServices;
- using System.Diagnostics.Contracts;
- using CultureInfo = System.Globalization.CultureInfo;
-
- [Serializable]
- public class TypeDelegator : TypeInfo
- {
- public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){
- if(typeInfo==null) return false;
- return IsAssignableFrom(typeInfo.AsType());
- }
-
- protected Type typeImpl;
-
- protected TypeDelegator() {}
-
- public TypeDelegator(Type delegatingType) {
- if (delegatingType == null)
- throw new ArgumentNullException(nameof(delegatingType));
- Contract.EndContractBlock();
-
- typeImpl = delegatingType;
- }
-
- public override Guid GUID {
- get {return typeImpl.GUID;}
- }
-
- public override int MetadataToken { get { return typeImpl.MetadataToken; } }
-
- public override Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder,Object target,
- Object[] args,ParameterModifier[] modifiers,CultureInfo culture,String[] namedParameters)
- {
- return typeImpl.InvokeMember(name,invokeAttr,binder,target,args,modifiers,culture,namedParameters);
- }
-
- public override Module Module {
- get {return typeImpl.Module;}
- }
-
- public override Assembly Assembly {
- get {return typeImpl.Assembly;}
- }
-
- public override RuntimeTypeHandle TypeHandle {
- get{return typeImpl.TypeHandle;}
- }
-
- public override String Name {
- get{return typeImpl.Name;}
- }
-
- public override String FullName {
- get{return typeImpl.FullName;}
- }
-
- public override String Namespace {
- get{return typeImpl.Namespace;}
- }
-
- public override String AssemblyQualifiedName {
- get {
- return typeImpl.AssemblyQualifiedName;
- }
- }
-
- public override Type BaseType {
- get{return typeImpl.BaseType;}
- }
-
- protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr,Binder binder,
- CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers)
- {
- return typeImpl.GetConstructor(bindingAttr,binder,callConvention,types,modifiers);
- }
-
- public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
- {
- return typeImpl.GetConstructors(bindingAttr);
- }
-
- protected override MethodInfo GetMethodImpl(String name,BindingFlags bindingAttr,Binder binder,
- CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers)
- {
- // This is interesting there are two paths into the impl. One that validates
- // type as non-null and one where type may be null.
- if (types == null)
- return typeImpl.GetMethod(name,bindingAttr);
- else
- return typeImpl.GetMethod(name,bindingAttr,binder,callConvention,types,modifiers);
- }
-
- public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
- {
- return typeImpl.GetMethods(bindingAttr);
- }
-
- public override FieldInfo GetField(String name, BindingFlags bindingAttr)
- {
- return typeImpl.GetField(name,bindingAttr);
- }
-
- public override FieldInfo[] GetFields(BindingFlags bindingAttr)
- {
- return typeImpl.GetFields(bindingAttr);
- }
-
- public override Type GetInterface(String name, bool ignoreCase)
- {
- return typeImpl.GetInterface(name,ignoreCase);
- }
-
- public override Type[] GetInterfaces()
- {
- return typeImpl.GetInterfaces();
- }
-
- public override EventInfo GetEvent(String name,BindingFlags bindingAttr)
- {
- return typeImpl.GetEvent(name,bindingAttr);
- }
-
- public override EventInfo[] GetEvents()
- {
- return typeImpl.GetEvents();
- }
-
- protected override PropertyInfo GetPropertyImpl(String name,BindingFlags bindingAttr,Binder binder,
- Type returnType, Type[] types, ParameterModifier[] modifiers)
- {
- if (returnType == null && types == null)
- return typeImpl.GetProperty(name,bindingAttr);
- else
- return typeImpl.GetProperty(name,bindingAttr,binder,returnType,types,modifiers);
- }
-
- public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
- {
- return typeImpl.GetProperties(bindingAttr);
- }
-
- public override EventInfo[] GetEvents(BindingFlags bindingAttr)
- {
- return typeImpl.GetEvents(bindingAttr);
- }
-
- public override Type[] GetNestedTypes(BindingFlags bindingAttr)
- {
- return typeImpl.GetNestedTypes(bindingAttr);
- }
-
- public override Type GetNestedType(String name, BindingFlags bindingAttr)
- {
- return typeImpl.GetNestedType(name,bindingAttr);
- }
-
- public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
- {
- return typeImpl.GetMember(name,type,bindingAttr);
- }
-
- public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
- {
- return typeImpl.GetMembers(bindingAttr);
- }
-
- protected override TypeAttributes GetAttributeFlagsImpl()
- {
- return typeImpl.Attributes;
- }
-
- protected override bool IsArrayImpl()
- {
- return typeImpl.IsArray;
- }
-
- protected override bool IsPrimitiveImpl()
- {
- return typeImpl.IsPrimitive;
- }
-
- protected override bool IsByRefImpl()
- {
- return typeImpl.IsByRef;
- }
-
- protected override bool IsPointerImpl()
- {
- return typeImpl.IsPointer;
- }
-
- protected override bool IsValueTypeImpl()
- {
- return typeImpl.IsValueType;
- }
-
- protected override bool IsCOMObjectImpl()
- {
- return typeImpl.IsCOMObject;
- }
-
- public override bool IsConstructedGenericType
- {
- get
- {
- return typeImpl.IsConstructedGenericType;
- }
- }
-
- public override Type GetElementType()
- {
- return typeImpl.GetElementType();
- }
-
- protected override bool HasElementTypeImpl()
- {
- return typeImpl.HasElementType;
- }
-
- public override Type UnderlyingSystemType
- {
- get {return typeImpl.UnderlyingSystemType;}
- }
-
- // ICustomAttributeProvider
- public override Object[] GetCustomAttributes(bool inherit)
- {
- return typeImpl.GetCustomAttributes(inherit);
- }
-
- public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
- {
- return typeImpl.GetCustomAttributes(attributeType, inherit);
- }
-
- public override bool IsDefined(Type attributeType, bool inherit)
- {
- return typeImpl.IsDefined(attributeType, inherit);
- }
-
- public override InterfaceMapping GetInterfaceMap(Type interfaceType)
- {
- return typeImpl.GetInterfaceMap(interfaceType);
- }
- }
-}
diff --git a/src/mscorlib/src/System/Reflection/TypeFilter.cs b/src/mscorlib/src/System/Reflection/TypeFilter.cs
deleted file mode 100644
index 4837a303a1..0000000000
--- a/src/mscorlib/src/System/Reflection/TypeFilter.cs
+++ /dev/null
@@ -1,18 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// TypeFilter defines a delegate that is as a callback function for filtering
-//
-// a list of Types.
-//
-//
-namespace System.Reflection {
-
- // Define the delegate
- [Serializable]
- public delegate bool TypeFilter(Type m, Object filterCriteria);
-}
diff --git a/src/mscorlib/src/System/Reflection/TypeInfo.cs b/src/mscorlib/src/System/Reflection/TypeInfo.cs
deleted file mode 100644
index 61d7bb27a9..0000000000
--- a/src/mscorlib/src/System/Reflection/TypeInfo.cs
+++ /dev/null
@@ -1,194 +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.
-
-/*=============================================================================
-**
-**
-**
-**
-**
-** Purpose: Notion of a type definition
-**
-**
-=============================================================================*/
-
-namespace System.Reflection
-{
- using System;
- using System.Runtime.CompilerServices;
- using System.Collections.Generic;
- using System.Diagnostics.Contracts;
-
- //all today's runtime Type derivations derive now from TypeInfo
- //we make TypeInfo implement IRCT - simplifies work
- [Serializable]
- public abstract class TypeInfo:Type,IReflectableType
- {
- [FriendAccessAllowed]
- internal TypeInfo() { }
-
- TypeInfo IReflectableType.GetTypeInfo(){
- return this;
- }
- public virtual Type AsType(){
- return (Type)this;
- }
-
- public virtual Type[] GenericTypeParameters{
- get{
- if(IsGenericTypeDefinition){
- return GetGenericArguments();
- }
- else{
- return Type.EmptyTypes;
- }
-
- }
- }
- //a re-implementation of ISAF from Type, skipping the use of UnderlyingType
- [Pure]
- public virtual bool IsAssignableFrom(TypeInfo typeInfo)
- {
- if (typeInfo == null)
- return false;
-
- if (this == typeInfo)
- return true;
-
- // If c is a subclass of this class, then c can be cast to this type.
- if (typeInfo.IsSubclassOf(this))
- return true;
-
- if (this.IsInterface)
- {
- return typeInfo.ImplementInterface(this);
- }
- else if (IsGenericParameter)
- {
- Type[] constraints = GetGenericParameterConstraints();
- for (int i = 0; i < constraints.Length; i++)
- if (!constraints[i].IsAssignableFrom(typeInfo))
- return false;
-
- return true;
- }
-
- return false;
- }
-#region moved over from Type
- // Fields
-
- public virtual EventInfo GetDeclaredEvent(String name)
- {
- return GetEvent(name, Type.DeclaredOnlyLookup);
- }
- public virtual FieldInfo GetDeclaredField(String name)
- {
- return GetField(name, Type.DeclaredOnlyLookup);
- }
- public virtual MethodInfo GetDeclaredMethod(String name)
- {
- return GetMethod(name, Type.DeclaredOnlyLookup);
- }
-
- public virtual IEnumerable<MethodInfo> GetDeclaredMethods(String name)
- {
- foreach (MethodInfo method in GetMethods(Type.DeclaredOnlyLookup))
- {
- if (method.Name == name)
- yield return method;
- }
- }
- public virtual System.Reflection.TypeInfo GetDeclaredNestedType(String name)
- {
- var nt=GetNestedType(name, Type.DeclaredOnlyLookup);
- if(nt == null){
- return null; //the extension method GetTypeInfo throws for null
- }else{
- return nt.GetTypeInfo();
- }
- }
- public virtual PropertyInfo GetDeclaredProperty(String name)
- {
- return GetProperty(name, Type.DeclaredOnlyLookup);
- }
-
-
-
-
-
- // Properties
-
- public virtual IEnumerable<ConstructorInfo> DeclaredConstructors
- {
- get
- {
- return GetConstructors(Type.DeclaredOnlyLookup);
- }
- }
-
- public virtual IEnumerable<EventInfo> DeclaredEvents
- {
- get
- {
- return GetEvents(Type.DeclaredOnlyLookup);
- }
- }
-
- public virtual IEnumerable<FieldInfo> DeclaredFields
- {
- get
- {
- return GetFields(Type.DeclaredOnlyLookup);
- }
- }
-
- public virtual IEnumerable<MemberInfo> DeclaredMembers
- {
- get
- {
- return GetMembers(Type.DeclaredOnlyLookup);
- }
- }
-
- public virtual IEnumerable<MethodInfo> DeclaredMethods
- {
- get
- {
- return GetMethods(Type.DeclaredOnlyLookup);
- }
- }
- public virtual IEnumerable<System.Reflection.TypeInfo> DeclaredNestedTypes
- {
- get
- {
- foreach (var t in GetNestedTypes(Type.DeclaredOnlyLookup)){
- yield return t.GetTypeInfo();
- }
- }
- }
-
- public virtual IEnumerable<PropertyInfo> DeclaredProperties
- {
- get
- {
- return GetProperties(Type.DeclaredOnlyLookup);
- }
- }
-
-
- public virtual IEnumerable<Type> ImplementedInterfaces
- {
- get
- {
- return GetInterfaces();
- }
- }
-
-
-#endregion
-
- }
-}
-
diff --git a/src/mscorlib/src/System/Reflection/__Filters.cs b/src/mscorlib/src/System/Reflection/__Filters.cs
deleted file mode 100644
index 8edcd0d7cb..0000000000
--- a/src/mscorlib/src/System/Reflection/__Filters.cs
+++ /dev/null
@@ -1,67 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-//
-// This class defines the delegate methods for the COM+ implemented filters.
-// This is the reflection version of these. There is also a _Filters class in
-// runtime which is related to this.
-//
-//
-//
-//
-namespace System.Reflection {
- using System;
- using System.Globalization;
-
- [Serializable]
- internal class __Filters {
-
- // FilterTypeName
- // This method will filter the class based upon the name. It supports
- // a trailing wild card.
- public virtual bool FilterTypeName(Type cls,Object filterCriteria)
- {
- // Check that the criteria object is a String object
- if (filterCriteria == null || !(filterCriteria is String))
- throw new InvalidFilterCriteriaException(System.Environment.GetResourceString("RFLCT.FltCritString"));
-
- String str = (String) filterCriteria;
- //str = str.Trim();
-
- // Check to see if this is a prefix or exact match requirement
- if (str.Length > 0 && str[str.Length - 1] == '*') {
- str = str.Substring(0, str.Length - 1);
- return cls.Name.StartsWith(str, StringComparison.Ordinal);
- }
-
- return cls.Name.Equals(str);
- }
-
- // FilterFieldNameIgnoreCase
- // This method filter the Type based upon name, it ignores case.
- public virtual bool FilterTypeNameIgnoreCase(Type cls, Object filterCriteria)
- {
- // Check that the criteria object is a String object
- if(filterCriteria == null || !(filterCriteria is String))
- throw new InvalidFilterCriteriaException(System.Environment.GetResourceString("RFLCT.FltCritString"));
-
- String str = (String) filterCriteria;
- //str = str.Trim();
-
- // Check to see if this is a prefix or exact match requirement
- if (str.Length > 0 && str[str.Length - 1] == '*') {
- str = str.Substring(0, str.Length - 1);
- String name = cls.Name;
- if (name.Length >= str.Length)
- return (String.Compare(name,0,str,0,str.Length, StringComparison.OrdinalIgnoreCase)==0);
- else
- return false;
- }
- return (String.Compare(str,cls.Name, StringComparison.OrdinalIgnoreCase) == 0);
- }
- }
-}
diff --git a/src/mscorlib/src/System/ResId.cs b/src/mscorlib/src/System/ResId.cs
index e6a2423c28..7be46145b0 100644
--- a/src/mscorlib/src/System/ResId.cs
+++ b/src/mscorlib/src/System/ResId.cs
@@ -11,83 +11,87 @@
**
**
===========================================================*/
-namespace System {
- //This class contains only static members and does not need to be serializable.
- using System.Configuration.Assemblies;
- using System;
- internal static class ResId {
+//This class contains only static members and does not need to be serializable.
+
+using System.Configuration.Assemblies;
+using System;
+
+namespace System
+{
+ internal static class ResId
+ {
// Only statics, does not need to be marked with the serializable attribute
- internal const String Arg_ArrayLengthsDiffer="Arg_ArrayLengthsDiffer";
- internal const String Argument_InvalidNumberOfMembers="Argument_InvalidNumberOfMembers";
- internal const String Argument_UnequalMembers="Argument_UnequalMembers";
- internal const String Argument_SpecifyValueSize="Argument_SpecifyValueSize";
- internal const String Argument_UnmatchingSymScope="Argument_UnmatchingSymScope";
- internal const String Argument_NotInExceptionBlock="Argument_NotInExceptionBlock";
- internal const String Argument_NotExceptionType="Argument_NotExceptionType";
- internal const String Argument_InvalidLabel="Argument_InvalidLabel";
- internal const String Argument_UnclosedExceptionBlock="Argument_UnclosedExceptionBlock";
- internal const String Argument_MissingDefaultConstructor="Argument_MissingDefaultConstructor";
- internal const String Argument_TooManyFinallyClause="Argument_TooManyFinallyClause";
- internal const String Argument_NotInTheSameModuleBuilder="Argument_NotInTheSameModuleBuilder";
- internal const String Argument_BadCurrentLocalVariable="Argument_BadCurrentLocalVariable";
- internal const String Argument_DuplicateModuleName="Argument_DuplicateModuleName";
- internal const String Argument_BadPersistableModuleInTransientAssembly="Argument_BadPersistableModuleInTransientAssembly";
- internal const String Argument_HasToBeArrayClass="Argument_HasToBeArrayClass";
- internal const String Argument_InvalidDirectory="Argument_InvalidDirectory";
-
- internal const String MissingType="MissingType";
- internal const String MissingModule="MissingModule";
-
- internal const String ArgumentOutOfRange_Index="ArgumentOutOfRange_Index";
- internal const String ArgumentOutOfRange_Range="ArgumentOutOfRange_Range";
-
- internal const String ExecutionEngine_YoureHosed="ExecutionEngine_YoureHosed";
-
- internal const String Format_NeedSingleChar="Format_NeedSingleChar";
- internal const String Format_StringZeroLength="Format_StringZeroLength";
-
- internal const String InvalidOperation_EnumEnded="InvalidOperation_EnumEnded";
- internal const String InvalidOperation_EnumFailedVersion="InvalidOperation_EnumFailedVersion";
- internal const String InvalidOperation_EnumNotStarted="InvalidOperation_EnumNotStarted";
- internal const String InvalidOperation_EnumOpCantHappen="InvalidOperation_EnumOpCantHappen";
- internal const String InvalidOperation_InternalState="InvalidOperation_InternalState";
- internal const String InvalidOperation_ModifyRONumFmtInfo="InvalidOperation_ModifyRONumFmtInfo";
- internal const String InvalidOperation_MethodBaked="InvalidOperation_MethodBaked";
- internal const String InvalidOperation_NotADebugModule="InvalidOperation_NotADebugModule";
- internal const String InvalidOperation_MethodHasBody="InvalidOperation_MethodHasBody";
- internal const String InvalidOperation_OpenLocalVariableScope="InvalidOperation_OpenLocalVariableScope";
- internal const String InvalidOperation_TypeHasBeenCreated="InvalidOperation_TypeHasBeenCreated";
- internal const String InvalidOperation_RefedAssemblyNotSaved="InvalidOperation_RefedAssemblyNotSaved";
- internal const String InvalidOperation_AssemblyHasBeenSaved="InvalidOperation_AssemblyHasBeenSaved";
- internal const String InvalidOperation_ModuleHasBeenSaved="InvalidOperation_ModuleHasBeenSaved";
- internal const String InvalidOperation_CannotAlterAssembly="InvalidOperation_CannotAlterAssembly";
-
- internal const String NotSupported_CannotSaveModuleIndividually="NotSupported_CannotSaveModuleIndividually";
- internal const String NotSupported_Constructor="NotSupported_Constructor";
- internal const String NotSupported_Method="NotSupported_Method";
- internal const String NotSupported_NYI="NotSupported_NYI";
- internal const String NotSupported_DynamicModule="NotSupported_DynamicModule";
- internal const String NotSupported_NotDynamicModule="NotSupported_NotDynamicModule";
- internal const String NotSupported_NotAllTypesAreBaked="NotSupported_NotAllTypesAreBaked";
- internal const String NotSupported_SortedListNestedWrite="NotSupported_SortedListNestedWrite";
-
-
- internal const String Serialization_ArrayInvalidLength="Serialization_ArrayInvalidLength";
- internal const String Serialization_ArrayNoLength="Serialization_ArrayNoLength";
- internal const String Serialization_CannotGetType="Serialization_CannotGetType";
- internal const String Serialization_InsufficientState="Serialization_InsufficientState";
- internal const String Serialization_InvalidID="Serialization_InvalidID";
- internal const String Serialization_MalformedArray="Serialization_MalformedArray";
- internal const String Serialization_MultipleMembers="Serialization_MultipleMembers";
- internal const String Serialization_NoID="Serialization_NoID";
- internal const String Serialization_NoType="Serialization_NoType";
- internal const String Serialization_NoBaseType="Serialization_NoBaseType";
- internal const String Serialization_NullSignature="Serialization_NullSignature";
- internal const String Serialization_UnknownMember="Serialization_UnknownMember";
- internal const String Serialization_BadParameterInfo="Serialization_BadParameterInfo";
- internal const String Serialization_NoParameterInfo="Serialization_NoParameterInfo";
+ internal const String Arg_ArrayLengthsDiffer = "Arg_ArrayLengthsDiffer";
+ internal const String Argument_InvalidNumberOfMembers = "Argument_InvalidNumberOfMembers";
+ internal const String Argument_UnequalMembers = "Argument_UnequalMembers";
+ internal const String Argument_SpecifyValueSize = "Argument_SpecifyValueSize";
+ internal const String Argument_UnmatchingSymScope = "Argument_UnmatchingSymScope";
+ internal const String Argument_NotInExceptionBlock = "Argument_NotInExceptionBlock";
+ internal const String Argument_NotExceptionType = "Argument_NotExceptionType";
+ internal const String Argument_InvalidLabel = "Argument_InvalidLabel";
+ internal const String Argument_UnclosedExceptionBlock = "Argument_UnclosedExceptionBlock";
+ internal const String Argument_MissingDefaultConstructor = "Argument_MissingDefaultConstructor";
+ internal const String Argument_TooManyFinallyClause = "Argument_TooManyFinallyClause";
+ internal const String Argument_NotInTheSameModuleBuilder = "Argument_NotInTheSameModuleBuilder";
+ internal const String Argument_BadCurrentLocalVariable = "Argument_BadCurrentLocalVariable";
+ internal const String Argument_DuplicateModuleName = "Argument_DuplicateModuleName";
+ internal const String Argument_BadPersistableModuleInTransientAssembly = "Argument_BadPersistableModuleInTransientAssembly";
+ internal const String Argument_HasToBeArrayClass = "Argument_HasToBeArrayClass";
+ internal const String Argument_InvalidDirectory = "Argument_InvalidDirectory";
+
+ internal const String MissingType = "MissingType";
+ internal const String MissingModule = "MissingModule";
+
+ internal const String ArgumentOutOfRange_Index = "ArgumentOutOfRange_Index";
+ internal const String ArgumentOutOfRange_Range = "ArgumentOutOfRange_Range";
+
+ internal const String ExecutionEngine_YoureHosed = "ExecutionEngine_YoureHosed";
+
+ internal const String Format_NeedSingleChar = "Format_NeedSingleChar";
+ internal const String Format_StringZeroLength = "Format_StringZeroLength";
+
+ internal const String InvalidOperation_EnumEnded = "InvalidOperation_EnumEnded";
+ internal const String InvalidOperation_EnumFailedVersion = "InvalidOperation_EnumFailedVersion";
+ internal const String InvalidOperation_EnumNotStarted = "InvalidOperation_EnumNotStarted";
+ internal const String InvalidOperation_EnumOpCantHappen = "InvalidOperation_EnumOpCantHappen";
+ internal const String InvalidOperation_InternalState = "InvalidOperation_InternalState";
+ internal const String InvalidOperation_ModifyRONumFmtInfo = "InvalidOperation_ModifyRONumFmtInfo";
+ internal const String InvalidOperation_MethodBaked = "InvalidOperation_MethodBaked";
+ internal const String InvalidOperation_NotADebugModule = "InvalidOperation_NotADebugModule";
+ internal const String InvalidOperation_MethodHasBody = "InvalidOperation_MethodHasBody";
+ internal const String InvalidOperation_OpenLocalVariableScope = "InvalidOperation_OpenLocalVariableScope";
+ internal const String InvalidOperation_TypeHasBeenCreated = "InvalidOperation_TypeHasBeenCreated";
+ internal const String InvalidOperation_RefedAssemblyNotSaved = "InvalidOperation_RefedAssemblyNotSaved";
+ internal const String InvalidOperation_AssemblyHasBeenSaved = "InvalidOperation_AssemblyHasBeenSaved";
+ internal const String InvalidOperation_ModuleHasBeenSaved = "InvalidOperation_ModuleHasBeenSaved";
+ internal const String InvalidOperation_CannotAlterAssembly = "InvalidOperation_CannotAlterAssembly";
+
+ internal const String NotSupported_CannotSaveModuleIndividually = "NotSupported_CannotSaveModuleIndividually";
+ internal const String NotSupported_Constructor = "NotSupported_Constructor";
+ internal const String NotSupported_Method = "NotSupported_Method";
+ internal const String NotSupported_NYI = "NotSupported_NYI";
+ internal const String NotSupported_DynamicModule = "NotSupported_DynamicModule";
+ internal const String NotSupported_NotDynamicModule = "NotSupported_NotDynamicModule";
+ internal const String NotSupported_NotAllTypesAreBaked = "NotSupported_NotAllTypesAreBaked";
+ internal const String NotSupported_SortedListNestedWrite = "NotSupported_SortedListNestedWrite";
+
+
+ internal const String Serialization_ArrayInvalidLength = "Serialization_ArrayInvalidLength";
+ internal const String Serialization_ArrayNoLength = "Serialization_ArrayNoLength";
+ internal const String Serialization_CannotGetType = "Serialization_CannotGetType";
+ internal const String Serialization_InsufficientState = "Serialization_InsufficientState";
+ internal const String Serialization_InvalidID = "Serialization_InvalidID";
+ internal const String Serialization_MalformedArray = "Serialization_MalformedArray";
+ internal const String Serialization_MultipleMembers = "Serialization_MultipleMembers";
+ internal const String Serialization_NoID = "Serialization_NoID";
+ internal const String Serialization_NoType = "Serialization_NoType";
+ internal const String Serialization_NoBaseType = "Serialization_NoBaseType";
+ internal const String Serialization_NullSignature = "Serialization_NullSignature";
+ internal const String Serialization_UnknownMember = "Serialization_UnknownMember";
+ internal const String Serialization_BadParameterInfo = "Serialization_BadParameterInfo";
+ internal const String Serialization_NoParameterInfo = "Serialization_NoParameterInfo";
- internal const String WeakReference_NoLongerValid="WeakReference_NoLongerValid";
- internal const String Loader_InvalidPath="Loader_InvalidPath";
+ internal const String WeakReference_NoLongerValid = "WeakReference_NoLongerValid";
+ internal const String Loader_InvalidPath = "Loader_InvalidPath";
}
}
diff --git a/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs b/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs
index c5e92165f1..e1bbd2814a 100644
--- a/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs
+++ b/src/mscorlib/src/System/Resources/FileBasedResourceGroveler.cs
@@ -13,7 +13,9 @@
**
**
===========================================================*/
-namespace System.Resources {
+
+namespace System.Resources
+{
using System;
using System.Collections;
using System.Collections.Generic;
@@ -39,7 +41,7 @@ namespace System.Resources {
// Consider modifying IResourceGroveler interface (hence this method signature) when we figure out
// serialization compat story for moving ResourceManager members to either file-based or
// manifest-based classes. Want to continue tightening the design to get rid of unused params.
- public ResourceSet GrovelForResourceSet(CultureInfo culture, Dictionary<String, ResourceSet> localResourceSets, bool tryParents, bool createIfNotExists, ref StackCrawlMark stackMark)
+ public ResourceSet GrovelForResourceSet(CultureInfo culture, Dictionary<String, ResourceSet> localResourceSets, bool tryParents, bool createIfNotExists, ref StackCrawlMark stackMark)
{
Debug.Assert(culture != null, "culture shouldn't be null; check caller");
@@ -60,7 +62,7 @@ namespace System.Resources {
{
// We really don't think this should happen - we always
// expect the neutral locale's resources to be present.
- throw new MissingManifestResourceException(Environment.GetResourceString("MissingManifestResource_NoNeutralDisk") + Environment.NewLine + "baseName: " + _mediator.BaseNameField + " locationInfo: " + (_mediator.LocationInfo == null ? "<null>" : _mediator.LocationInfo.FullName) + " fileName: " + _mediator.GetResourceFileName(culture));
+ throw new MissingManifestResourceException(SR.MissingManifestResource_NoNeutralDisk + Environment.NewLine + "baseName: " + _mediator.BaseNameField + " locationInfo: " + (_mediator.LocationInfo == null ? "<null>" : _mediator.LocationInfo.FullName) + " fileName: " + _mediator.GetResourceFileName(culture));
}
}
}
@@ -90,7 +92,7 @@ namespace System.Resources {
{
#if _DEBUG
if (ResourceManager.DEBUG >= 3)
- BCLDebug.Log("FindResourceFile: checking module dir: \""+_mediator.ModuleDir+'\"');
+ BCLDebug.Log("FindResourceFile: checking module dir: \"" + _mediator.ModuleDir + '\"');
#endif
String path = Path.Combine(_mediator.ModuleDir, fileName);
@@ -98,7 +100,7 @@ namespace System.Resources {
{
#if _DEBUG
if (ResourceManager.DEBUG >= 3)
- BCLDebug.Log("Found resource file in module dir! "+path);
+ BCLDebug.Log("Found resource file in module dir! " + path);
#endif
return path;
}
@@ -106,7 +108,7 @@ namespace System.Resources {
#if _DEBUG
if (ResourceManager.DEBUG >= 3)
- BCLDebug.Log("Couldn't find resource file in module dir, checking .\\"+fileName);
+ BCLDebug.Log("Couldn't find resource file in module dir, checking .\\" + fileName);
#endif
// look in .
@@ -140,7 +142,7 @@ namespace System.Resources {
}
catch (MissingMethodException e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResMgrBadResSet_Type", _mediator.UserResourceSet.AssemblyQualifiedName), e);
+ throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResMgrBadResSet_Type, _mediator.UserResourceSet.AssemblyQualifiedName), e);
}
}
}
diff --git a/src/mscorlib/src/System/Resources/IResourceGroveler.cs b/src/mscorlib/src/System/Resources/IResourceGroveler.cs
index 77c5c95890..bdd8826c77 100644
--- a/src/mscorlib/src/System/Resources/IResourceGroveler.cs
+++ b/src/mscorlib/src/System/Resources/IResourceGroveler.cs
@@ -12,16 +12,18 @@
**
**
===========================================================*/
-namespace System.Resources {
- using System;
- using System.Globalization;
- using System.Threading;
- using System.Collections.Generic;
- using System.Runtime.Versioning;
+using System;
+using System.Globalization;
+using System.Threading;
+using System.Collections.Generic;
+using System.Runtime.Versioning;
+
+namespace System.Resources
+{
internal interface IResourceGroveler
{
- ResourceSet GrovelForResourceSet(CultureInfo culture, Dictionary<String, ResourceSet> localResourceSets, bool tryParents,
+ ResourceSet GrovelForResourceSet(CultureInfo culture, Dictionary<String, ResourceSet> localResourceSets, bool tryParents,
bool createIfNotExists, ref StackCrawlMark stackMark);
}
}
diff --git a/src/mscorlib/src/System/Resources/IResourceReader.cs b/src/mscorlib/src/System/Resources/IResourceReader.cs
deleted file mode 100644
index de8f9db18e..0000000000
--- a/src/mscorlib/src/System/Resources/IResourceReader.cs
+++ /dev/null
@@ -1,30 +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.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Abstraction to read streams of resources.
-**
-**
-===========================================================*/
-namespace System.Resources {
- using System;
- using System.IO;
- using System.Collections;
-
- public interface IResourceReader : IEnumerable, IDisposable
- {
- // Interface does not need to be marked with the serializable attribute
- // Closes the ResourceReader, releasing any resources associated with it.
- // This could close a network connection, a file, or do nothing.
- void Close();
-
-
- new IDictionaryEnumerator GetEnumerator();
- }
-}
diff --git a/src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs b/src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs
index 9287ae4590..3179df09b7 100644
--- a/src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs
+++ b/src/mscorlib/src/System/Resources/LooselyLinkedResourceReference.cs
@@ -39,9 +39,9 @@ namespace System.Resources {
if (typeName == null)
throw new ArgumentNullException(nameof(typeName));
if (looselyLinkedResourceName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(looselyLinkedResourceName));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(looselyLinkedResourceName));
if (typeName.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(typeName));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(typeName));
Contract.EndContractBlock();
_manifestResourceName = looselyLinkedResourceName;
@@ -64,7 +64,7 @@ namespace System.Resources {
Stream data = assembly.GetManifestResourceStream(_manifestResourceName);
if (data == null)
- throw new MissingManifestResourceException(Environment.GetResourceString("MissingManifestResource_LooselyLinked", _manifestResourceName, assembly.FullName));
+ throw new MissingManifestResourceException(SR.Format(SR.MissingManifestResource_LooselyLinked, _manifestResourceName, assembly.FullName));
Type type = Type.GetType(_typeName, true);
diff --git a/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs b/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs
index 78e961a7f9..0e9666b2b1 100644
--- a/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs
+++ b/src/mscorlib/src/System/Resources/ManifestBasedResourceGroveler.cs
@@ -13,8 +13,9 @@
**
**
===========================================================*/
-namespace System.Resources {
+namespace System.Resources
+{
using System;
using System.Collections;
using System.Collections.Generic;
@@ -41,7 +42,6 @@ namespace System.Resources {
//
internal class ManifestBasedResourceGroveler : IResourceGroveler
{
-
private ResourceManager.ResourceManagerMediator _mediator;
public ManifestBasedResourceGroveler(ResourceManager.ResourceManagerMediator mediator)
@@ -52,7 +52,6 @@ namespace System.Resources {
_mediator = mediator;
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
public ResourceSet GrovelForResourceSet(CultureInfo culture, Dictionary<String, ResourceSet> localResourceSets, bool tryParents, bool createIfNotExists, ref StackCrawlMark stackMark)
{
Debug.Assert(culture != null, "culture shouldn't be null; check caller");
@@ -132,7 +131,6 @@ namespace System.Resources {
private CultureInfo UltimateFallbackFixup(CultureInfo lookForCulture)
{
-
CultureInfo returnCulture = lookForCulture;
// If our neutral resources were written in this culture AND we know the main assembly
@@ -155,15 +153,18 @@ namespace System.Resources {
Debug.Assert(a != null, "assembly != null");
string cultureName = null;
short fallback = 0;
- if (GetNeutralResourcesLanguageAttribute(((RuntimeAssembly)a).GetNativeHandle(),
- JitHelpers.GetStringHandleOnStack(ref cultureName),
- out fallback)) {
- if ((UltimateResourceFallbackLocation)fallback < UltimateResourceFallbackLocation.MainAssembly || (UltimateResourceFallbackLocation)fallback > UltimateResourceFallbackLocation.Satellite) {
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidNeutralResourcesLanguage_FallbackLoc", fallback));
+ if (GetNeutralResourcesLanguageAttribute(((RuntimeAssembly)a).GetNativeHandle(),
+ JitHelpers.GetStringHandleOnStack(ref cultureName),
+ out fallback))
+ {
+ if ((UltimateResourceFallbackLocation)fallback < UltimateResourceFallbackLocation.MainAssembly || (UltimateResourceFallbackLocation)fallback > UltimateResourceFallbackLocation.Satellite)
+ {
+ throw new ArgumentException(SR.Format(SR.Arg_InvalidNeutralResourcesLanguage_FallbackLoc, fallback));
}
fallbackLocation = (UltimateResourceFallbackLocation)fallback;
}
- else {
+ else
+ {
fallbackLocation = UltimateResourceFallbackLocation.MainAssembly;
return CultureInfo.InvariantCulture;
}
@@ -180,11 +181,11 @@ namespace System.Resources {
// fires, please fix the build process for the BCL directory.
if (a == typeof(Object).Assembly)
{
- Debug.Assert(false, System.CoreLib.Name+"'s NeutralResourcesLanguageAttribute is a malformed culture name! name: \"" + cultureName + "\" Exception: " + e);
+ Debug.Assert(false, System.CoreLib.Name + "'s NeutralResourcesLanguageAttribute is a malformed culture name! name: \"" + cultureName + "\" Exception: " + e);
return CultureInfo.InvariantCulture;
}
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidNeutralResourcesLanguage_Asm_Culture", a.ToString(), cultureName), e);
+ throw new ArgumentException(SR.Format(SR.Arg_InvalidNeutralResourcesLanguage_Asm_Culture, a.ToString(), cultureName), e);
}
}
@@ -202,10 +203,10 @@ namespace System.Resources {
if (store.CanSeek && store.Length > 4)
{
long startPos = store.Position;
-
+
// not disposing because we want to leave stream open
BinaryReader br = new BinaryReader(store);
-
+
// Look for our magic number as a little endian Int32.
int bytes = br.ReadInt32();
if (bytes == ResourceManager.MagicNumber)
@@ -237,7 +238,7 @@ namespace System.Resources {
// resMgrHeaderVersion is older than this ResMgr version.
// We should add in backwards compatibility support here.
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ObsoleteResourcesFile", _mediator.MainAssembly.GetSimpleName()));
+ throw new NotSupportedException(SR.Format(SR.NotSupported_ObsoleteResourcesFile, _mediator.MainAssembly.GetSimpleName()));
}
store.Position = startPos;
@@ -294,7 +295,6 @@ namespace System.Resources {
{
store.Position = startPos;
}
-
}
if (_mediator.UserResourceSet == null)
@@ -334,7 +334,7 @@ namespace System.Resources {
}
catch (MissingMethodException e)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResMgrBadResSet_Type", _mediator.UserResourceSet.AssemblyQualifiedName), e);
+ throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResMgrBadResSet_Type, _mediator.UserResourceSet.AssemblyQualifiedName), e);
}
}
}
@@ -362,7 +362,7 @@ namespace System.Resources {
// case-insensitive lookup rules. Yes, this is slow. The metadata
// dev lead refuses to make all assembly manifest resource lookups case-insensitive,
// even optionally case-insensitive.
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
private Stream CaseInsensitiveManifestResourceStreamLookup(RuntimeAssembly satellite, String name)
{
Contract.Requires(satellite != null, "satellite shouldn't be null; check caller");
@@ -394,7 +394,7 @@ namespace System.Resources {
}
else
{
- throw new MissingManifestResourceException(Environment.GetResourceString("MissingManifestResource_MultipleBlobs", givenName, satellite.ToString()));
+ throw new MissingManifestResourceException(SR.Format(SR.MissingManifestResource_MultipleBlobs, givenName, satellite.ToString()));
}
}
}
@@ -412,7 +412,6 @@ namespace System.Resources {
return satellite.GetManifestResourceStream(canonicalName, ref stackMark, canSkipSecurityCheck);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
private RuntimeAssembly GetSatelliteAssembly(CultureInfo lookForCulture, ref StackCrawlMark stackMark)
{
if (!_mediator.LookedForSatelliteContractVersion)
@@ -493,7 +492,7 @@ namespace System.Resources {
private String GetSatelliteAssemblyName()
{
String satAssemblyName = _mediator.MainAssembly.GetSimpleName();
- satAssemblyName += ".resources";
+ satAssemblyName += ".resources";
return satAssemblyName;
}
@@ -522,7 +521,7 @@ namespace System.Resources {
{
missingCultureName = "<invariant>";
}
- throw new MissingSatelliteAssemblyException(Environment.GetResourceString("MissingSatelliteAssembly_Culture_Name", _mediator.NeutralResourcesCulture, satAssemName), missingCultureName);
+ throw new MissingSatelliteAssemblyException(SR.Format(SR.MissingSatelliteAssembly_Culture_Name, _mediator.NeutralResourcesCulture, satAssemName), missingCultureName);
}
private void HandleResourceStreamMissing(String fileName)
@@ -531,8 +530,8 @@ namespace System.Resources {
if (_mediator.MainAssembly == typeof(Object).Assembly && _mediator.BaseName.Equals(System.CoreLib.Name))
{
// This would break CultureInfo & all our exceptions.
- Debug.Assert(false, "Couldn't get " + System.CoreLib.Name+ResourceManager.ResFileExtension + " from "+System.CoreLib.Name+"'s assembly" + Environment.NewLine + Environment.NewLine + "Are you building the runtime on your machine? Chances are the BCL directory didn't build correctly. Type 'build -c' in the BCL directory. If you get build errors, look at buildd.log. If you then can't figure out what's wrong (and you aren't changing the assembly-related metadata code), ask a BCL dev.\n\nIf you did NOT build the runtime, you shouldn't be seeing this and you've found a bug.");
-
+ Debug.Assert(false, "Couldn't get " + System.CoreLib.Name + ResourceManager.ResFileExtension + " from " + System.CoreLib.Name + "'s assembly" + Environment.NewLine + Environment.NewLine + "Are you building the runtime on your machine? Chances are the BCL directory didn't build correctly. Type 'build -c' in the BCL directory. If you get build errors, look at buildd.log. If you then can't figure out what's wrong (and you aren't changing the assembly-related metadata code), ask a BCL dev.\n\nIf you did NOT build the runtime, you shouldn't be seeing this and you've found a bug.");
+
// We cannot continue further - simply FailFast.
string mesgFailFast = System.CoreLib.Name + ResourceManager.ResFileExtension + " couldn't be found! Large parts of the BCL won't work!";
System.Environment.FailFast(mesgFailFast);
@@ -543,12 +542,12 @@ namespace System.Resources {
if (_mediator.LocationInfo != null && _mediator.LocationInfo.Namespace != null)
resName = _mediator.LocationInfo.Namespace + Type.Delimiter;
resName += fileName;
- throw new MissingManifestResourceException(Environment.GetResourceString("MissingManifestResource_NoNeutralAsm", resName, _mediator.MainAssembly.GetSimpleName()));
+ throw new MissingManifestResourceException(SR.Format(SR.MissingManifestResource_NoNeutralAsm, resName, _mediator.MainAssembly.GetSimpleName()));
}
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [System.Security.SuppressUnmanagedCodeSecurity]
- [return: MarshalAs(UnmanagedType.Bool)]
- internal static extern bool GetNeutralResourcesLanguageAttribute(RuntimeAssembly assemblyHandle, StringHandleOnStack cultureName, out short fallbackLocation);
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [System.Security.SuppressUnmanagedCodeSecurity]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ internal static extern bool GetNeutralResourcesLanguageAttribute(RuntimeAssembly assemblyHandle, StringHandleOnStack cultureName, out short fallbackLocation);
}
}
diff --git a/src/mscorlib/src/System/Resources/MissingManifestResourceException.cs b/src/mscorlib/src/System/Resources/MissingManifestResourceException.cs
deleted file mode 100644
index 2e82f19c7b..0000000000
--- a/src/mscorlib/src/System/Resources/MissingManifestResourceException.cs
+++ /dev/null
@@ -1,41 +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.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Exception for a missing assembly-level resource
-**
-**
-===========================================================*/
-
-using System;
-using System.Runtime.Serialization;
-
-namespace System.Resources {
- [Serializable]
- public class MissingManifestResourceException : SystemException
- {
- public MissingManifestResourceException()
- : base(Environment.GetResourceString("Arg_MissingManifestResourceException")) {
- SetErrorCode(System.__HResults.COR_E_MISSINGMANIFESTRESOURCE);
- }
-
- public MissingManifestResourceException(String message)
- : base(message) {
- SetErrorCode(System.__HResults.COR_E_MISSINGMANIFESTRESOURCE);
- }
-
- public MissingManifestResourceException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(System.__HResults.COR_E_MISSINGMANIFESTRESOURCE);
- }
-
- protected MissingManifestResourceException(SerializationInfo info, StreamingContext context) : base (info, context) {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Resources/MissingSatelliteAssemblyException.cs b/src/mscorlib/src/System/Resources/MissingSatelliteAssemblyException.cs
deleted file mode 100644
index fc676a8dd5..0000000000
--- a/src/mscorlib/src/System/Resources/MissingSatelliteAssemblyException.cs
+++ /dev/null
@@ -1,55 +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.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Exception for a missing satellite assembly needed
-** for ultimate resource fallback. This usually
-** indicates a setup and/or deployment problem.
-**
-**
-===========================================================*/
-
-using System;
-using System.Runtime.Serialization;
-
-namespace System.Resources {
- [Serializable]
- public class MissingSatelliteAssemblyException : SystemException
- {
- private String _cultureName;
-
- public MissingSatelliteAssemblyException()
- : base(Environment.GetResourceString("MissingSatelliteAssembly_Default")) {
- SetErrorCode(System.__HResults.COR_E_MISSINGSATELLITEASSEMBLY);
- }
-
- public MissingSatelliteAssemblyException(String message)
- : base(message) {
- SetErrorCode(System.__HResults.COR_E_MISSINGSATELLITEASSEMBLY);
- }
-
- public MissingSatelliteAssemblyException(String message, String cultureName)
- : base(message) {
- SetErrorCode(System.__HResults.COR_E_MISSINGSATELLITEASSEMBLY);
- _cultureName = cultureName;
- }
-
- public MissingSatelliteAssemblyException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(System.__HResults.COR_E_MISSINGSATELLITEASSEMBLY);
- }
-
- protected MissingSatelliteAssemblyException(SerializationInfo info, StreamingContext context) : base (info, context) {
- }
-
- public String CultureName {
- get { return _cultureName; }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Resources/NeutralResourcesLanguageAttribute.cs b/src/mscorlib/src/System/Resources/NeutralResourcesLanguageAttribute.cs
deleted file mode 100644
index a2ed6fbd57..0000000000
--- a/src/mscorlib/src/System/Resources/NeutralResourcesLanguageAttribute.cs
+++ /dev/null
@@ -1,64 +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.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Tells the ResourceManager what language your main
-** assembly's resources are written in. The
-** ResourceManager won't try loading a satellite
-** assembly for that culture, which helps perf.
-**
-**
-** NOTE:
-**
-** This custom attribute is no longer implemented in managed code. As part of a perf optimization,
-** it is now read in Module::GetNeutralResourcesLanguage, accessed from ManifestBasedResourceGroveler
-** through an internal runtime call.
-===========================================================*/
-
-namespace System.Resources {
- using System;
- using System.Diagnostics.Contracts;
-
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=false)]
- public sealed class NeutralResourcesLanguageAttribute : Attribute
- {
- private String _culture;
- private UltimateResourceFallbackLocation _fallbackLoc;
-
- public NeutralResourcesLanguageAttribute(String cultureName)
- {
- if (cultureName == null)
- throw new ArgumentNullException(nameof(cultureName));
- Contract.EndContractBlock();
-
- _culture = cultureName;
- _fallbackLoc = UltimateResourceFallbackLocation.MainAssembly;
- }
-
- public NeutralResourcesLanguageAttribute(String cultureName, UltimateResourceFallbackLocation location)
- {
- if (cultureName == null)
- throw new ArgumentNullException(nameof(cultureName));
- if (!Enum.IsDefined(typeof(UltimateResourceFallbackLocation), location))
- throw new ArgumentException(Environment.GetResourceString("Arg_InvalidNeutralResourcesLanguage_FallbackLoc", location));
- Contract.EndContractBlock();
-
- _culture = cultureName;
- _fallbackLoc = location;
- }
-
- public String CultureName {
- get { return _culture; }
- }
-
- public UltimateResourceFallbackLocation Location {
- get { return _fallbackLoc; }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Resources/ResourceFallbackManager.cs b/src/mscorlib/src/System/Resources/ResourceFallbackManager.cs
index de50cccc33..4ad7b4c93a 100644
--- a/src/mscorlib/src/System/Resources/ResourceFallbackManager.cs
+++ b/src/mscorlib/src/System/Resources/ResourceFallbackManager.cs
@@ -68,7 +68,7 @@ namespace System.Resources
CultureInfo currentCulture = m_startingCulture;
do
{
- if (m_neutralResourcesCulture != null && currentCulture.Name == m_neutralResourcesCulture.Name)
+ if (m_neutralResourcesCulture != null && currentCulture.Name == m_neutralResourcesCulture.Name)
{
// Return the invariant culture all the time, even if the UltimateResourceFallbackLocation
// is a satellite assembly. This is fixed up later in ManifestBasedResourceGroveler::UltimateFallbackFixup.
@@ -85,180 +85,12 @@ namespace System.Resources
yield break;
}
- // 2. user preferred cultures, omitting starting culture if tried already
- // Compat note: For console apps, this API will return cultures like Arabic
- // or Hebrew that are displayed right-to-left. These don't work with today's
- // CMD.exe. Since not all apps can short-circuit RTL languages to look at
- // US English resources, we're exposing an appcompat flag for this, to make the
- // osFallbackArray an empty array, mimicing our V2 behavior. Apps should instead
- // be using CultureInfo.GetConsoleFallbackUICulture, and then test whether that
- // culture's code page can be displayed on the console, and if not, they should
- // set their culture to their neutral resources language.
- // Note: the app compat switch will omit the OS Preferred fallback culture.
- // Compat note 2: This feature breaks certain apps dependent on fallback to neutral
- // resources. See extensive note in GetResourceFallbackArray.
- CultureInfo[] osFallbackArray = LoadPreferredCultures();
- if (osFallbackArray != null)
- {
- foreach (CultureInfo ci in osFallbackArray)
- {
- // only have to check starting culture and immediate parent for now.
- // in Dev10, revisit this policy.
- if (m_startingCulture.Name != ci.Name && m_startingCulture.Parent.Name != ci.Name)
- {
- yield return ci;
- }
- }
- }
-
- // 3. invariant
+ // 2. invariant
// Don't return invariant twice though.
if (reachedNeutralResourcesCulture)
yield break;
yield return CultureInfo.InvariantCulture;
}
-
- private static CultureInfo[] LoadPreferredCultures()
- {
- // The list of preferred cultures includes thread, process, user, and OS
- // information and may theoretically change every time we call it.
- // The caching does save us some allocations - this complexity saved about
- // 7% of the wall clock time on a US English machine, and may save more on non-English
- // boxes (since the fallback list may be longer).
- String[] cultureNames = GetResourceFallbackArray();
- if (cultureNames == null)
- return null;
-
- bool useCachedNames = (cachedOsFallbackArray != null && cultureNames.Length == cachedOsFallbackArray.Length);
- if (useCachedNames)
- {
- for (int i = 0; i < cultureNames.Length; i++)
- {
- if (!String.Equals(cultureNames[i], cachedOsFallbackArray[i].Name))
- {
- useCachedNames = false;
- break;
- }
- }
- }
- if (useCachedNames)
- return cachedOsFallbackArray;
-
- cachedOsFallbackArray = LoadCulturesFromNames(cultureNames);
- return cachedOsFallbackArray;
- }
-
- private static CultureInfo[] LoadCulturesFromNames(String[] cultureNames)
- {
- if (cultureNames == null)
- return null;
-
- CultureInfo[] cultures = new CultureInfo[cultureNames.Length];
- int culturesIndex = 0;
- for (int i = 0; i < cultureNames.Length; i++)
- {
- // get cached, read-only cultures to avoid excess allocations
- cultures[culturesIndex] = CultureInfo.GetCultureInfo(cultureNames[i]);
- // Note GetCultureInfo can return null for a culture name that we don't support on the current OS.
- // Don't leave a null in the middle of the array.
- if (!Object.ReferenceEquals(cultures[culturesIndex], null))
- culturesIndex++;
- }
-
- // If we couldn't create a culture, return an array of the right length.
- if (culturesIndex != cultureNames.Length)
- {
- CultureInfo[] ret = new CultureInfo[culturesIndex];
- Array.Copy(cultures, ret, culturesIndex);
- cultures = ret;
- }
-
- return cultures;
- }
-
-
- // Note: May return null.
- private static String[] GetResourceFallbackArray()
- {
- // AppCompat note: We've added this feature for desktop V4 but we ripped it out
- // before shipping V4. It shipped in SL 2 and SL 3. We preserved this behavior in SL 4
- // for compat with previous Silverlight releases. We considered re-introducing this in .NET
- // 4.5 for Windows 8 but chose not to because the Windows 8 immersive resources model
- // has been redesigned from the ground up and we chose to support it (for portable libraries
- // only) instead of further enhancing support for the classic resources model.
- // ---------------------------------------------------------------------
- //
- // We have an appcompat problem that prevents us from adopting the ideal MUI model for
- // culture fallback. Up until .NET Framework v4, our fallback was this:
- //
- // CurrentUICulture & parents Neutral
- //
- // We also had applications that took a dependency on falling back to neutral resources.
- // IE, say an app is developed by US English developers - they may include English resources
- // in the main assembly, not ship an "en" satellite assembly, and ship a French satellite.
- // They may also omit the NeutralResourcesLanguageAttribute.
- //
- // Starting with Silverlight v2 and following advice from the MUI team, we wanted to call
- // the OS's GetThreadPreferredUILanguages, inserting the results like this:
- //
- // CurrentUICulture & parents user-preferred fallback OS-preferred fallback Neutral
- //
- // This does not fit well for two reasons:
- // 1) There is no concept of neutral resources in MUI
- // 2) The user-preferred culture fallbacks make no sense in servers & non-interactive apps
- // This leads to bad results on certain combinations of OS language installations, user
- // settings, and applications built in certain styles. The OS-preferred fallback should
- // be last, and the user-preferred fallback just breaks certain apps no matter where you put it.
- //
- // Necessary and sufficient conditions for an AppCompat bug (if we respected user & OS fallbacks):
- // 1) A French OS (ie, you walk into an Internet café in Paris)
- // 2) A .NET application whose neutral resources are authored in English.
- // 3) The application did not provide an English satellite assembly (a common pattern).
- // 4) The application is localized to French.
- // 5) The user wants to read English, expressed in either of two ways:
- // a. Changing Windows’ Display Language in the Regional Options Control Panel
- // b. The application explicitly ASKS THE USER what language to display.
- //
- // Obviously the exact languages above can be interchanged a bit - I’m keeping this concrete.
- // Also the NeutralResourcesLanguageAttribute will allow this to work, but usually we set it
- // to en-US for our assemblies, meaning all other English cultures are broken.
- //
- // Workarounds:
- // *) Use the NeutralResourcesLanguageAttribute and tell us that your neutral resources
- // are in region-neutral English (en).
- // *) Consider shipping a region-neutral English satellite assembly.
-
- // Future work:
- // 2) Consider a mechanism for individual assemblies to opt into wanting user-preferred fallback.
- // They should ship their neutral resources in a satellite assembly, or use the
- // NeutralResourcesLanguageAttribute to say their neutral resources are in a REGION-NEUTRAL
- // language. An appdomain or process-wide flag may not be sufficient.
- // 3) Ask Windows to clarify the scenario for the OS preferred fallback list, to decide whether
- // we should probe there before or after looking at the neutral resources. If we move it
- // to after the neutral resources, ask Windows to return a user-preferred fallback list
- // without the OS preferred fallback included. This is a feature request for
- // GetThreadPreferredUILanguages. We can muddle through without it by removing the OS
- // preferred fallback cultures from end of the combined user + OS preferred fallback list, carefully.
- // 4) Do not look at user-preferred fallback if Environment.UserInteractive is false. (IE,
- // the Windows user who launches ASP.NET shouldn't determine how a web page gets
- // localized - the server itself must respect the remote client's requested languages.)
- // 6) Figure out what should happen in servers (ASP.NET, SQL, NT Services, etc).
- //
- // Done:
- // 1) Got data from Windows on priority of supporting OS preferred fallback. We need to do it.
- // Helps with consistency w/ Windows, and may be necessary for a long tail of other languages
- // (ie, Windows has various degrees of localization support for ~135 languages, and fallbacks
- // to certain languages is important.)
- // 5) Revisited guidance for using the NeutralResourcesLanguageAttribute. Our docs should now say
- // always pick a region-neutral language (ie, "en").
-
-// TODO (matell): I think we actually want to pull this into the PAL on CultureInfo?
-#if FEATURE_COREFX_GLOBALIZATION
- return null;
-#else
- return CultureInfo.nativeGetResourceFallbackArray();
-#endif
- }
}
}
diff --git a/src/mscorlib/src/System/Resources/ResourceManager.cs b/src/mscorlib/src/System/Resources/ResourceManager.cs
index f17a7c8f8e..993efddbfc 100644
--- a/src/mscorlib/src/System/Resources/ResourceManager.cs
+++ b/src/mscorlib/src/System/Resources/ResourceManager.cs
@@ -14,7 +14,8 @@
**
===========================================================*/
-namespace System.Resources {
+namespace System.Resources
+{
using System;
using System.IO;
using System.Globalization;
@@ -38,20 +39,21 @@ namespace System.Resources {
// allowing us to ask for a WinRT-specific ResourceManager.
// It is important to have WindowsRuntimeResourceManagerBase as regular class with virtual methods and default implementations.
// Defining WindowsRuntimeResourceManagerBase as abstract class or interface will cause issues when adding more methods to it
- // because it’ll create dependency between mscorlib and System.Runtime.WindowsRuntime which will require always shipping both DLLs together.
+ // because it�ll create dependency between mscorlib and System.Runtime.WindowsRuntime which will require always shipping both DLLs together.
// Also using interface or abstract class will not play nice with FriendAccessAllowed.
//
[FriendAccessAllowed]
internal class WindowsRuntimeResourceManagerBase
{
- public virtual bool Initialize(string libpath, string reswFilename, out PRIExceptionInfo exceptionInfo){exceptionInfo = null; return false;}
+ public virtual bool Initialize(string libpath, string reswFilename, out PRIExceptionInfo exceptionInfo) { exceptionInfo = null; return false; }
- public virtual String GetString(String stringName, String startingCulture, String neutralResourcesCulture){return null;}
+ public virtual String GetString(String stringName, String startingCulture, String neutralResourcesCulture) { return null; }
- public virtual CultureInfo GlobalResourceContextBestFitCultureInfo {
- get { return null; }
+ public virtual CultureInfo GlobalResourceContextBestFitCultureInfo
+ {
+ get { return null; }
}
-
+
public virtual bool SetGlobalResourceContextDefaultCulture(CultureInfo ci) { return false; }
}
@@ -150,8 +152,8 @@ namespace System.Resources {
[Serializable]
public class ResourceManager
{
-
- internal class CultureNameResourceSetPair {
+ internal class CultureNameResourceSetPair
+ {
public String lastCultureName;
public ResourceSet lastResourceSet;
}
@@ -161,11 +163,11 @@ namespace System.Resources {
// Don't synchronize ResourceSets - too fine-grained a lock to be effective
[Obsolete("call InternalGetResourceSet instead")]
internal Hashtable ResourceSets;
-
+
// don't serialize the cache of ResourceSets
[NonSerialized]
- private Dictionary <String,ResourceSet> _resourceSets;
+ private Dictionary<String, ResourceSet> _resourceSets;
private String moduleDir; // For assembly-ignorant directory location
protected Assembly MainAssembly; // Need the assembly manifest sometimes.
private Type _locationInfo; // For Assembly or type-based directory layout
@@ -182,11 +184,11 @@ namespace System.Resources {
// unused! But need to keep for serialization
[OptionalField(VersionAdded = 1)]
private bool UseSatelliteAssem; // Are all the .resources files in the
- // main assembly, or in satellite assemblies for each culture?
+ // main assembly, or in satellite assemblies for each culture?
#if RESOURCE_SATELLITE_CONFIG
private static volatile Hashtable _installedSatelliteInfo; // Give the user the option
- // to prevent certain satellite assembly probes via a config file.
- // Note that config files are per-appdomain, not per-assembly nor process
+ // to prevent certain satellite assembly probes via a config file.
+ // Note that config files are per-appdomain, not per-assembly nor process
private static volatile bool _checkedConfigFile; // Did we read the app's config file?
#endif
@@ -246,16 +248,16 @@ namespace System.Resources {
// My private debugging aid. Set to 5 or 6 for verbose output. Set to 3
// for summary level information.
internal static readonly int DEBUG = 0; //Making this const causes C# to consider all of the code that it guards unreachable.
-
+
private static volatile bool s_IsAppXModel;
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
private void Init()
{
m_callingAssembly = (RuntimeAssembly)Assembly.GetCallingAssembly();
}
- protected ResourceManager()
+ protected ResourceManager()
{
Init();
@@ -263,7 +265,7 @@ namespace System.Resources {
ResourceManagerMediator mediator = new ResourceManagerMediator(this);
resourceGroveler = new ManifestBasedResourceGroveler(mediator);
}
-
+
// Constructs a Resource Manager for files beginning with
// baseName in the directory specified by resourceDir
// or in the current directory. This Assembly-ignorant constructor is
@@ -274,10 +276,11 @@ namespace System.Resources {
//
// Note: System.Windows.Forms uses this method at design time.
//
- private ResourceManager(String baseName, String resourceDir, Type usingResourceSet) {
- if (null==baseName)
+ private ResourceManager(String baseName, String resourceDir, Type usingResourceSet)
+ {
+ if (null == baseName)
throw new ArgumentNullException(nameof(baseName));
- if (null==resourceDir)
+ if (null == resourceDir)
throw new ArgumentNullException(nameof(resourceDir));
Contract.EndContractBlock();
@@ -296,18 +299,18 @@ namespace System.Resources {
resourceGroveler = new FileBasedResourceGroveler(mediator);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public ResourceManager(String baseName, Assembly assembly)
{
- if (null==baseName)
+ if (null == baseName)
throw new ArgumentNullException(nameof(baseName));
- if (null==assembly)
+ if (null == assembly)
throw new ArgumentNullException(nameof(assembly));
Contract.EndContractBlock();
if (!(assembly is RuntimeAssembly))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly);
MainAssembly = assembly;
BaseNameField = baseName;
@@ -327,23 +330,23 @@ namespace System.Resources {
}
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public ResourceManager(String baseName, Assembly assembly, Type usingResourceSet)
{
- if (null==baseName)
+ if (null == baseName)
throw new ArgumentNullException(nameof(baseName));
- if (null==assembly)
+ if (null == assembly)
throw new ArgumentNullException(nameof(assembly));
Contract.EndContractBlock();
if (!(assembly is RuntimeAssembly))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly);
MainAssembly = assembly;
BaseNameField = baseName;
-
+
if (usingResourceSet != null && (usingResourceSet != _minResourceSet) && !(usingResourceSet.IsSubclassOf(_minResourceSet)))
- throw new ArgumentException(Environment.GetResourceString("Arg_ResMgrNotResSet"), nameof(usingResourceSet));
+ throw new ArgumentException(SR.Arg_ResMgrNotResSet, nameof(usingResourceSet));
_userResourceSet = usingResourceSet;
CommonAssemblyInit();
@@ -355,21 +358,21 @@ namespace System.Resources {
if (assembly == typeof(Object).Assembly && m_callingAssembly != assembly)
m_callingAssembly = null;
}
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public ResourceManager(Type resourceSource)
{
- if (null==resourceSource)
+ if (null == resourceSource)
throw new ArgumentNullException(nameof(resourceSource));
Contract.EndContractBlock();
if (!(resourceSource is RuntimeType))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType);
_locationInfo = resourceSource;
MainAssembly = _locationInfo.Assembly;
BaseNameField = resourceSource.Name;
-
+
SetAppXConfiguration();
CommonAssemblyInit();
@@ -385,9 +388,9 @@ namespace System.Resources {
[OnDeserializing]
private void OnDeserializing(StreamingContext ctx)
{
- this._resourceSets = null;
- this.resourceGroveler = null;
- this._lastUsedResourceCache = null;
+ _resourceSets = null;
+ resourceGroveler = null;
+ _lastUsedResourceCache = null;
}
[OnDeserialized]
@@ -408,13 +411,13 @@ namespace System.Resources {
}
// correct callingAssembly for v2
- if (this.m_callingAssembly == null)
+ if (m_callingAssembly == null)
{
- this.m_callingAssembly = (RuntimeAssembly)_callingAssembly;
+ m_callingAssembly = (RuntimeAssembly)_callingAssembly;
}
// v2 does this lazily
- if (UseManifest && this._neutralResourcesCulture == null)
+ if (UseManifest && _neutralResourcesCulture == null)
{
_neutralResourcesCulture = ManifestBasedResourceGroveler.GetNeutralResourcesLanguage(MainAssembly, ref _fallbackLoc);
}
@@ -430,7 +433,7 @@ namespace System.Resources {
ResourceSets = new Hashtable(); // for backward compatibility
#pragma warning restore 618
}
-
+
// Trying to unify code as much as possible, even though having to do a
// security check in each constructor prevents it.
@@ -439,8 +442,8 @@ namespace System.Resources {
if (_bUsingModernResourceManagement == false)
{
UseManifest = true;
-
- _resourceSets = new Dictionary<String,ResourceSet>();
+
+ _resourceSets = new Dictionary<String, ResourceSet>();
_lastUsedResourceCache = new CultureNameResourceSetPair();
_fallbackLoc = UltimateResourceFallbackLocation.MainAssembly;
@@ -453,20 +456,23 @@ namespace System.Resources {
}
// Gets the base name for the ResourceManager.
- public virtual String BaseName {
+ public virtual String BaseName
+ {
get { return BaseNameField; }
}
-
+
// Whether we should ignore the capitalization of resources when calling
// GetString or GetObject.
- public virtual bool IgnoreCase {
+ public virtual bool IgnoreCase
+ {
get { return _ignoreCase; }
set { _ignoreCase = value; }
}
// Returns the Type of the ResourceSet the ResourceManager uses
// to construct ResourceSets.
- public virtual Type ResourceSetType {
+ public virtual Type ResourceSetType
+ {
get { return (_userResourceSet == null) ? typeof(RuntimeResourceSet) : _userResourceSet; }
}
@@ -491,13 +497,15 @@ namespace System.Resources {
// If any calls to Close throw, at least leave ourselves in a
// consistent state.
- _resourceSets = new Dictionary<String,ResourceSet>();
+ _resourceSets = new Dictionary<String, ResourceSet>();
_lastUsedResourceCache = new CultureNameResourceSetPair();
-
- lock(localResourceSets) {
+
+ lock (localResourceSets)
+ {
IDictionaryEnumerator setEnum = localResourceSets.GetEnumerator();
- while (setEnum.MoveNext()) {
+ while (setEnum.MoveNext())
+ {
((ResourceSet)setEnum.Value).Close();
}
}
@@ -507,7 +515,7 @@ namespace System.Resources {
{
return new ResourceManager(baseName, resourceDir, usingResourceSet);
}
-
+
// Given a CultureInfo, GetResourceFileName generates the name for
// the binary file for the given CultureInfo. This method uses
// CultureInfo's Name property as part of the file name for all cultures
@@ -518,7 +526,8 @@ namespace System.Resources {
//
// This method can be overriden to look for a different extension,
// such as ".ResX", or a completely different format for naming files.
- protected virtual String GetResourceFileName(CultureInfo culture) {
+ protected virtual String GetResourceFileName(CultureInfo culture)
+ {
StringBuilder sb = new StringBuilder(255);
sb.Append(BaseNameField);
// If this is the neutral culture, don't append culture name.
@@ -537,24 +546,26 @@ namespace System.Resources {
internal ResourceSet GetFirstResourceSet(CultureInfo culture)
{
// Logic from ResourceFallbackManager.GetEnumerator()
- if (_neutralResourcesCulture != null && culture.Name == _neutralResourcesCulture.Name)
+ if (_neutralResourcesCulture != null && culture.Name == _neutralResourcesCulture.Name)
{
culture = CultureInfo.InvariantCulture;
}
- if(_lastUsedResourceCache != null) {
- lock (_lastUsedResourceCache) {
+ if (_lastUsedResourceCache != null)
+ {
+ lock (_lastUsedResourceCache)
+ {
if (culture.Name == _lastUsedResourceCache.lastCultureName)
return _lastUsedResourceCache.lastResourceSet;
}
}
// Look in the ResourceSet table
- Dictionary<String,ResourceSet> localResourceSets = _resourceSets;
+ Dictionary<String, ResourceSet> localResourceSets = _resourceSets;
ResourceSet rs = null;
- if (localResourceSets != null)
+ if (localResourceSets != null)
{
- lock (localResourceSets)
+ lock (localResourceSets)
{
localResourceSets.TryGetValue(culture.Name, out rs);
}
@@ -563,8 +574,10 @@ namespace System.Resources {
if (rs != null)
{
// update the cache with the most recent ResourceSet
- if (_lastUsedResourceCache != null) {
- lock (_lastUsedResourceCache) {
+ if (_lastUsedResourceCache != null)
+ {
+ lock (_lastUsedResourceCache)
+ {
_lastUsedResourceCache.lastCultureName = culture.Name;
_lastUsedResourceCache.lastResourceSet = rs;
}
@@ -574,7 +587,7 @@ namespace System.Resources {
return null;
}
-
+
// Looks up a set of resources for a particular CultureInfo. This is
// not useful for most users of the ResourceManager - call
// GetString() or GetObject() instead.
@@ -583,16 +596,19 @@ namespace System.Resources {
// if it hasn't yet been loaded and if parent CultureInfos should be
// loaded as well for resource inheritance.
//
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
- public virtual ResourceSet GetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents) {
- if (null==culture)
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public virtual ResourceSet GetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents)
+ {
+ if (null == culture)
throw new ArgumentNullException(nameof(culture));
Contract.EndContractBlock();
- Dictionary<String,ResourceSet> localResourceSets = _resourceSets;
+ Dictionary<String, ResourceSet> localResourceSets = _resourceSets;
ResourceSet rs;
- if (localResourceSets != null) {
- lock (localResourceSets) {
+ if (localResourceSets != null)
+ {
+ lock (localResourceSets)
+ {
if (localResourceSets.TryGetValue(culture.Name, out rs))
return rs;
}
@@ -600,13 +616,15 @@ namespace System.Resources {
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- if (UseManifest && culture.HasInvariantCultureName) {
+ if (UseManifest && culture.HasInvariantCultureName)
+ {
string fileName = GetResourceFileName(culture);
RuntimeAssembly mainAssembly = (RuntimeAssembly)MainAssembly;
Stream stream = mainAssembly.GetManifestResourceStream(_locationInfo, fileName, m_callingAssembly == MainAssembly, ref stackMark);
- if (createIfNotExists && stream!=null) {
+ if (createIfNotExists && stream != null)
+ {
rs = ((ManifestBasedResourceGroveler)resourceGroveler).CreateResourceSet(stream, MainAssembly);
- AddResourceSet(localResourceSets, culture.Name, ref rs);
+ AddResourceSet(localResourceSets, culture.Name, ref rs);
return rs;
}
}
@@ -626,13 +644,13 @@ namespace System.Resources {
// for getting a resource set lives. Access to it is controlled by
// threadsafe methods such as GetResourceSet, GetString, & GetObject.
// This will take a minimal number of locks.
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- protected virtual ResourceSet InternalGetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents)
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ protected virtual ResourceSet InternalGetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents)
{
Debug.Assert(culture != null, "culture != null");
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return InternalGetResourceSet(culture,createIfNotExists,tryParents, ref stackMark);
+ return InternalGetResourceSet(culture, createIfNotExists, tryParents, ref stackMark);
}
// InternalGetResourceSet is a non-threadsafe method where all the logic
@@ -644,8 +662,10 @@ namespace System.Resources {
Dictionary<String, ResourceSet> localResourceSets = _resourceSets;
ResourceSet rs = null;
CultureInfo foundCulture = null;
- lock (localResourceSets) {
- if (localResourceSets.TryGetValue(requestedCulture.Name, out rs)) {
+ lock (localResourceSets)
+ {
+ if (localResourceSets.TryGetValue(requestedCulture.Name, out rs))
+ {
return rs;
}
}
@@ -654,10 +674,12 @@ namespace System.Resources {
foreach (CultureInfo currentCultureInfo in mgr)
{
- lock(localResourceSets) {
- if (localResourceSets.TryGetValue(currentCultureInfo.Name, out rs)) {
+ lock (localResourceSets)
+ {
+ if (localResourceSets.TryGetValue(currentCultureInfo.Name, out rs))
+ {
// we need to update the cache if we fellback
- if(requestedCulture != currentCultureInfo) foundCulture = currentCultureInfo;
+ if (requestedCulture != currentCultureInfo) foundCulture = currentCultureInfo;
break;
}
}
@@ -668,7 +690,7 @@ namespace System.Resources {
// Assembly load event, which could fail then call back into the
// ResourceManager). It's happened.
- rs = resourceGroveler.GrovelForResourceSet(currentCultureInfo, localResourceSets,
+ rs = resourceGroveler.GrovelForResourceSet(currentCultureInfo, localResourceSets,
tryParents, createIfNotExists, ref stackMark);
// found a ResourceSet; we're done
@@ -677,7 +699,6 @@ namespace System.Resources {
foundCulture = currentCultureInfo;
break;
}
-
}
if (rs != null && foundCulture != null)
@@ -696,23 +717,26 @@ namespace System.Resources {
{
break;
}
- }
+ }
}
return rs;
}
// Simple helper to ease maintenance and improve readability.
- private static void AddResourceSet(Dictionary<String,ResourceSet> localResourceSets, String cultureName, ref ResourceSet rs)
+ private static void AddResourceSet(Dictionary<String, ResourceSet> localResourceSets, String cultureName, ref ResourceSet rs)
{
// InternalGetResourceSet is both recursive and reentrant -
// assembly load callbacks in particular are a way we can call
// back into the ResourceManager in unexpectedly on the same thread.
- lock(localResourceSets) {
+ lock (localResourceSets)
+ {
// If another thread added this culture, return that.
ResourceSet lostRace;
- if (localResourceSets.TryGetValue(cultureName, out lostRace)) {
- if (!Object.ReferenceEquals(lostRace, rs)) {
+ if (localResourceSets.TryGetValue(cultureName, out lostRace))
+ {
+ if (!Object.ReferenceEquals(lostRace, rs))
+ {
// Note: In certain cases, we can be trying to add a ResourceSet for multiple
// cultures on one thread, while a second thread added another ResourceSet for one
// of those cultures. If there is a race condition we must make sure our ResourceSet
@@ -722,7 +746,8 @@ namespace System.Resources {
rs = lostRace;
}
}
- else {
+ else
+ {
localResourceSets.Add(cultureName, rs);
}
}
@@ -731,8 +756,9 @@ namespace System.Resources {
protected static Version GetSatelliteContractVersion(Assembly a)
{
// Ensure that the assembly reference is not null
- if (a == null) {
- throw new ArgumentNullException(nameof(a), Environment.GetResourceString("ArgumentNull_Assembly"));
+ if (a == null)
+ {
+ throw new ArgumentNullException(nameof(a), SR.ArgumentNull_Assembly);
}
Contract.EndContractBlock();
@@ -752,7 +778,7 @@ namespace System.Resources {
// IGNORES VERSION
internal static bool CompareNames(String asmTypeName1,
- String typeName2,
+ String typeName2,
AssemblyName asmName2)
{
Debug.Assert(asmTypeName1 != null, "asmTypeName1 was unexpectedly null");
@@ -770,7 +796,7 @@ namespace System.Resources {
// Now, compare assembly display names (IGNORES VERSION AND PROCESSORARCHITECTURE)
// also, for mscorlib ignores everything, since that's what the binder is going to do
- while(Char.IsWhiteSpace(asmTypeName1[++comma]));
+ while (Char.IsWhiteSpace(asmTypeName1[++comma])) ;
// case insensitive
AssemblyName an1 = new AssemblyName(asmTypeName1.Substring(comma));
@@ -793,12 +819,14 @@ namespace System.Resources {
byte[] pkt1 = an1.GetPublicKeyToken();
byte[] pkt2 = asmName2.GetPublicKeyToken();
- if ((pkt1 != null) && (pkt2 != null)) {
+ if ((pkt1 != null) && (pkt2 != null))
+ {
if (pkt1.Length != pkt2.Length)
return false;
- for(int i=0; i < pkt1.Length; i++) {
- if(pkt1[i] != pkt2[i])
+ for (int i = 0; i < pkt1.Length; i++)
+ {
+ if (pkt1[i] != pkt2[i])
return false;
}
}
@@ -807,15 +835,16 @@ namespace System.Resources {
}
#if FEATURE_APPX
- private string GetStringFromPRI(String stringName, String startingCulture, String neutralResourcesCulture) {
+ private string GetStringFromPRI(String stringName, String startingCulture, String neutralResourcesCulture)
+ {
Debug.Assert(_bUsingModernResourceManagement);
Debug.Assert(_WinRTResourceManager != null);
Debug.Assert(_PRIonAppXInitialized);
Debug.Assert(AppDomain.IsAppXModel());
-
+
if (stringName.Length == 0)
return null;
-
+
string resourceString = null;
// Do not handle exceptions. See the comment in SetAppXConfiguration about throwing
@@ -824,7 +853,7 @@ namespace System.Resources {
stringName,
String.IsNullOrEmpty(startingCulture) ? null : startingCulture,
String.IsNullOrEmpty(neutralResourcesCulture) ? null : neutralResourcesCulture);
-
+
return resourceString;
}
@@ -882,9 +911,9 @@ namespace System.Resources {
if ((platformResourceRoots != null) && (platformResourceRoots != String.Empty))
{
string resourceAssemblyPath = resourcesAssembly.Location;
-
+
// Loop through the PLATFORM_RESOURCE_ROOTS and see if the assembly is contained in it.
- foreach(string pathPlatformResourceRoot in platformResourceRoots.Split(Path.PathSeparator))
+ foreach (string pathPlatformResourceRoot in platformResourceRoots.Split(Path.PathSeparator))
{
if (resourceAssemblyPath.StartsWith(pathPlatformResourceRoot, StringComparison.CurrentCultureIgnoreCase))
{
@@ -924,7 +953,7 @@ namespace System.Resources {
{
// Cannot load the WindowsRuntimeResourceManager when in a compilation process, since it
// lives in System.Runtime.WindowsRuntime and only mscorlib may be loaded for execution.
- if (AppDomain.IsAppXModel() && !AppDomain.IsAppXNGen)
+ if (AppDomain.IsAppXModel())
{
s_IsAppXModel = true;
@@ -945,16 +974,17 @@ namespace System.Resources {
WindowsRuntimeResourceManagerBase WRRM = null;
bool bWRRM_Initialized = false;
-
+
if (AppDomain.IsAppXDesignMode())
{
WRRM = GetWinRTResourceManager();
- try {
+ try
+ {
PRIExceptionInfo exceptionInfo; // If the exception info is filled in, we will ignore it.
bWRRM_Initialized = WRRM.Initialize(resourcesAssembly.Location, reswFilename, out exceptionInfo);
bUsingSatelliteAssembliesUnderAppX = !bWRRM_Initialized;
}
- catch(Exception e)
+ catch (Exception e)
{
bUsingSatelliteAssembliesUnderAppX = true;
if (e.IsTransient)
@@ -966,7 +996,7 @@ namespace System.Resources {
{
// See AssemblyNative::IsFrameworkAssembly for details on which kinds of assemblies are considered Framework assemblies.
// The Modern Resource Manager is not used for such assemblies - they continue to use satellite assemblies (i.e. .resources.dll files).
- _bUsingModernResourceManagement = !ShouldUseSatelliteAssemblyResourceLookupUnderAppX(resourcesAssembly);
+ _bUsingModernResourceManagement = !ShouldUseSatelliteAssemblyResourceLookupUnderAppX(resourcesAssembly);
if (_bUsingModernResourceManagement)
{
@@ -989,11 +1019,12 @@ namespace System.Resources {
_WinRTResourceManager = WRRM;
_PRIonAppXInitialized = true;
}
- else
+ else
{
_WinRTResourceManager = GetWinRTResourceManager();
-
- try {
+
+ try
+ {
_PRIonAppXInitialized = _WinRTResourceManager.Initialize(resourcesAssembly.Location, reswFilename, out _PRIExceptionInfo);
// Note that _PRIExceptionInfo might be null - this is OK.
@@ -1007,12 +1038,12 @@ namespace System.Resources {
// and since they are part of the portable profile, we cannot start throwing a new exception type
// as that would break existing portable libraries. Hence we must save the exception information
// now and throw the exception on the first call to GetString.
- catch(FileNotFoundException)
+ catch (FileNotFoundException)
{
// We will throw MissingManifestResource_NoPRIresources from GetString
// when we see that _PRIonAppXInitialized is false.
}
- catch(Exception e)
+ catch (Exception e)
{
// ERROR_MRM_MAP_NOT_FOUND can be thrown by the call to ResourceManager.get_AllResourceMaps
// in WindowsRuntimeResourceManager.Initialize.
@@ -1053,31 +1084,33 @@ namespace System.Resources {
// current thread's CultureInfo, and if not found, all parent CultureInfos.
// Returns null if the resource wasn't found.
//
- public virtual String GetString(String name) {
+ public virtual String GetString(String name)
+ {
return GetString(name, (CultureInfo)null);
}
-
+
// Looks up a resource value for a particular name. Looks in the
// specified CultureInfo, and if not found, all parent CultureInfos.
// Returns null if the resource wasn't found.
//
- public virtual String GetString(String name, CultureInfo culture) {
- if (null==name)
+ public virtual String GetString(String name, CultureInfo culture)
+ {
+ if (null == name)
throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
#if FEATURE_APPX
- if(s_IsAppXModel)
+ if (s_IsAppXModel)
{
- // If the caller explictily passed in a culture that was obtained by calling CultureInfo.CurrentUICulture,
- // null it out, so that we re-compute it. If we use modern resource lookup, we may end up getting a "better"
- // match, since CultureInfo objects can't represent all the different languages the AppX resource model supports.
- // For classic resources, this causes us to ignore the languages list and instead use the older Win32 behavior,
- // which is the design choice we've made. (See the call a little later to GetCurrentUICultureNoAppX()).
- if(Object.ReferenceEquals(culture, CultureInfo.CurrentUICulture))
- {
- culture = null;
- }
+ // If the caller explictily passed in a culture that was obtained by calling CultureInfo.CurrentUICulture,
+ // null it out, so that we re-compute it. If we use modern resource lookup, we may end up getting a "better"
+ // match, since CultureInfo objects can't represent all the different languages the AppX resource model supports.
+ // For classic resources, this causes us to ignore the languages list and instead use the older Win32 behavior,
+ // which is the design choice we've made. (See the call a little later to GetCurrentUICultureNoAppX()).
+ if (Object.ReferenceEquals(culture, CultureInfo.CurrentUICulture))
+ {
+ culture = null;
+ }
}
if (_bUsingModernResourceManagement)
@@ -1087,11 +1120,11 @@ namespace System.Resources {
// Always throw if we did not fully succeed in initializing the WinRT Resource Manager.
if (_PRIExceptionInfo != null && _PRIExceptionInfo._PackageSimpleName != null && _PRIExceptionInfo._ResWFile != null)
- throw new MissingManifestResourceException(Environment.GetResourceString("MissingManifestResource_ResWFileNotLoaded", _PRIExceptionInfo._ResWFile, _PRIExceptionInfo._PackageSimpleName));
+ throw new MissingManifestResourceException(SR.Format(SR.MissingManifestResource_ResWFileNotLoaded, _PRIExceptionInfo._ResWFile, _PRIExceptionInfo._PackageSimpleName));
- throw new MissingManifestResourceException(Environment.GetResourceString("MissingManifestResource_NoPRIresources"));
+ throw new MissingManifestResourceException(SR.MissingManifestResource_NoPRIresources);
}
-
+
// Throws WinRT hresults.
return GetStringFromPRI(name,
culture == null ? null : culture.Name,
@@ -1100,10 +1133,11 @@ namespace System.Resources {
else
#endif // FEATURE_APPX
{
- if (null==culture) {
+ if (culture == null)
+ {
// When running inside AppX we want to ignore the languages list when trying to come up with our CurrentUICulture.
// This line behaves the same way as CultureInfo.CurrentUICulture would have in .NET 4
- culture = Thread.CurrentThread.GetCurrentUICultureNoAppX();
+ culture = CultureInfo.GetCurrentUICultureNoAppX();
}
ResourceSet last = GetFirstResourceSet(culture);
@@ -1114,25 +1148,28 @@ namespace System.Resources {
if (value != null)
return value;
}
-
-
+
+
// This is the CultureInfo hierarchy traversal code for resource
// lookups, similar but necessarily orthogonal to the ResourceSet
// lookup logic.
ResourceFallbackManager mgr = new ResourceFallbackManager(culture, _neutralResourcesCulture, true);
- foreach (CultureInfo currentCultureInfo in mgr) {
-
+ foreach (CultureInfo currentCultureInfo in mgr)
+ {
ResourceSet rs = InternalGetResourceSet(currentCultureInfo, true, true);
if (rs == null)
break;
- if (rs != last) {
+ if (rs != last)
+ {
String value = rs.GetString(name, _ignoreCase);
if (value != null)
{
// update last used ResourceSet
- if (_lastUsedResourceCache != null) {
- lock (_lastUsedResourceCache) {
+ if (_lastUsedResourceCache != null)
+ {
+ lock (_lastUsedResourceCache)
+ {
_lastUsedResourceCache.lastCultureName = currentCultureInfo.Name;
_lastUsedResourceCache.lastResourceSet = rs;
}
@@ -1147,46 +1184,49 @@ namespace System.Resources {
return null;
}
-
-
+
+
// Looks up a resource value for a particular name. Looks in the
// current thread's CultureInfo, and if not found, all parent CultureInfos.
// Returns null if the resource wasn't found.
//
- public virtual Object GetObject(String name) {
+ public virtual Object GetObject(String name)
+ {
return GetObject(name, (CultureInfo)null, true);
}
-
+
// Looks up a resource value for a particular name. Looks in the
// specified CultureInfo, and if not found, all parent CultureInfos.
// Returns null if the resource wasn't found.
- public virtual Object GetObject(String name, CultureInfo culture) {
+ public virtual Object GetObject(String name, CultureInfo culture)
+ {
return GetObject(name, culture, true);
}
private Object GetObject(String name, CultureInfo culture, bool wrapUnmanagedMemStream)
{
- if (null==name)
+ if (null == name)
throw new ArgumentNullException(nameof(name));
Contract.EndContractBlock();
#if FEATURE_APPX
- if(s_IsAppXModel)
+ if (s_IsAppXModel)
{
- // If the caller explictily passed in a culture that was obtained by calling CultureInfo.CurrentUICulture,
- // null it out, so that we re-compute it based on the Win32 value and not the AppX language list value.
- // (See the call a little later to GetCurrentUICultureNoAppX()).
- if(Object.ReferenceEquals(culture, CultureInfo.CurrentUICulture))
- {
- culture = null;
- }
+ // If the caller explictily passed in a culture that was obtained by calling CultureInfo.CurrentUICulture,
+ // null it out, so that we re-compute it based on the Win32 value and not the AppX language list value.
+ // (See the call a little later to GetCurrentUICultureNoAppX()).
+ if (Object.ReferenceEquals(culture, CultureInfo.CurrentUICulture))
+ {
+ culture = null;
+ }
}
#endif
- if (null==culture) {
+ if (null == culture)
+ {
// When running inside AppX we want to ignore the languages list when trying to come up with our CurrentUICulture.
// This line behaves the same way as CultureInfo.CurrentUICulture would have in .NET 4
- culture = Thread.CurrentThread.GetCurrentUICultureNoAppX();
+ culture = CultureInfo.GetCurrentUICultureNoAppX();
}
ResourceSet last = GetFirstResourceSet(culture);
@@ -1194,7 +1234,7 @@ namespace System.Resources {
{
Object value = last.GetObject(name, _ignoreCase);
- if (value != null)
+ if (value != null)
{
UnmanagedMemoryStream stream = value as UnmanagedMemoryStream;
if (stream != null && wrapUnmanagedMemStream)
@@ -1203,13 +1243,14 @@ namespace System.Resources {
return value;
}
}
-
+
// This is the CultureInfo hierarchy traversal code for resource
// lookups, similar but necessarily orthogonal to the ResourceSet
// lookup logic.
ResourceFallbackManager mgr = new ResourceFallbackManager(culture, _neutralResourcesCulture, true);
-
- foreach (CultureInfo currentCultureInfo in mgr) {
+
+ foreach (CultureInfo currentCultureInfo in mgr)
+ {
// Note: Technically this method should be passed in a stack crawl mark that we then pass
// to InternalGetResourceSet for ensuring we demand permissions to read your private resources
// if you're reading resources from an assembly other than yourself. But, we must call our
@@ -1219,12 +1260,16 @@ namespace System.Resources {
if (rs == null)
break;
- if (rs != last) {
+ if (rs != last)
+ {
Object value = rs.GetObject(name, _ignoreCase);
- if (value != null) {
+ if (value != null)
+ {
// update the last used ResourceSet
- if (_lastUsedResourceCache != null) {
- lock (_lastUsedResourceCache) {
+ if (_lastUsedResourceCache != null)
+ {
+ lock (_lastUsedResourceCache)
+ {
_lastUsedResourceCache.lastCultureName = currentCultureInfo.Name;
_lastUsedResourceCache.lastResourceSet = rs;
}
@@ -1244,15 +1289,17 @@ namespace System.Resources {
return null;
}
- public UnmanagedMemoryStream GetStream(String name) {
+ public UnmanagedMemoryStream GetStream(String name)
+ {
return GetStream(name, (CultureInfo)null);
}
-
- public UnmanagedMemoryStream GetStream(String name, CultureInfo culture) {
+
+ public UnmanagedMemoryStream GetStream(String name, CultureInfo culture)
+ {
Object obj = GetObject(name, culture, false);
UnmanagedMemoryStream ums = obj as UnmanagedMemoryStream;
if (ums == null && obj != null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotStream_Name", name));
+ throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResourceNotStream_Name, name));
return ums;
}
@@ -1261,9 +1308,12 @@ namespace System.Resources {
// satellite assembly probes for certain cultures via a config file.
private bool TryLookingForSatellite(CultureInfo lookForCulture)
{
- if (!_checkedConfigFile) {
- lock (this) {
- if (!_checkedConfigFile) {
+ if (!_checkedConfigFile)
+ {
+ lock (this)
+ {
+ if (!_checkedConfigFile)
+ {
_checkedConfigFile = true;
_installedSatelliteInfo = GetSatelliteAssembliesFromConfig();
}
@@ -1273,7 +1323,7 @@ namespace System.Resources {
if (_installedSatelliteInfo == null)
return true;
- String[] installedSatellites = (String[]) _installedSatelliteInfo[MainAssembly.FullName];
+ String[] installedSatellites = (String[])_installedSatelliteInfo[MainAssembly.FullName];
if (installedSatellites == null)
return true;
@@ -1317,7 +1367,7 @@ namespace System.Resources {
get { return _rm._locationInfo; }
}
- internal Type UserResourceSet
+ internal Type UserResourceSet
{
get { return _rm._userResourceSet; }
}
@@ -1358,7 +1408,7 @@ namespace System.Resources {
internal UltimateResourceFallbackLocation FallbackLoc
{
- get { return _rm.FallbackLocation; }
+ get { return _rm.FallbackLocation; }
set { _rm._fallbackLoc = value; }
}
diff --git a/src/mscorlib/src/System/Resources/ResourceReader.cs b/src/mscorlib/src/System/Resources/ResourceReader.cs
index d752771020..9734343f92 100644
--- a/src/mscorlib/src/System/Resources/ResourceReader.cs
+++ b/src/mscorlib/src/System/Resources/ResourceReader.cs
@@ -14,7 +14,9 @@
** Version 2 support on October 6, 2003
**
===========================================================*/
-namespace System.Resources {
+
+namespace System.Resources
+{
using System;
using System.IO;
using System.Text;
@@ -47,14 +49,16 @@ namespace System.Resources {
_value = value;
}
- internal int DataPosition {
+ internal int DataPosition
+ {
get { return _dataPos; }
//set { _dataPos = value; }
}
// Allows adding in profiling data in a future version, or a special
// resource profiling build. We could also use WeakReference.
- internal Object Value {
+ internal Object Value
+ {
get { return _value; }
set { _value = value; }
}
@@ -63,7 +67,7 @@ namespace System.Resources {
{
Debug.Assert(value >= 0, "negative ResourceTypeCode. What?");
return value <= ResourceTypeCode.LastPrimitive;
- }
+ }
}
@@ -111,23 +115,25 @@ namespace System.Resources {
{
_resCache = new Dictionary<String, ResourceLocator>(FastResourceComparer.Default);
_store = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.RandomAccess), Encoding.UTF8);
- BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(String). UnmanagedMemoryStream: "+(_ums!=null));
+ BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(String). UnmanagedMemoryStream: " + (_ums != null));
- try {
+ try
+ {
ReadResources();
}
- catch {
+ catch
+ {
_store.Close(); // If we threw an exception, close the file.
throw;
}
}
-
+
public ResourceReader(Stream stream)
{
- if (stream==null)
+ if (stream == null)
throw new ArgumentNullException(nameof(stream));
if (!stream.CanRead)
- throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotReadable"));
+ throw new ArgumentException(SR.Argument_StreamNotReadable);
Contract.EndContractBlock();
_resCache = new Dictionary<String, ResourceLocator>(FastResourceComparer.Default);
@@ -135,10 +141,10 @@ namespace System.Resources {
// We have a faster code path for reading resource files from an assembly.
_ums = stream as UnmanagedMemoryStream;
- BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(Stream). UnmanagedMemoryStream: "+(_ums!=null));
+ BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(Stream). UnmanagedMemoryStream: " + (_ums != null));
ReadResources();
}
-
+
// This is the constructor the RuntimeResourceSet calls,
// passing in the stream to read from and the RuntimeResourceSet's
// internal hash table (hash table of names with file offsets
@@ -154,16 +160,16 @@ namespace System.Resources {
_ums = stream as UnmanagedMemoryStream;
- BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(Stream, Hashtable). UnmanagedMemoryStream: "+(_ums!=null));
+ BCLDebug.Log("RESMGRFILEFORMAT", "ResourceReader .ctor(Stream, Hashtable). UnmanagedMemoryStream: " + (_ums != null));
ReadResources();
}
-
+
public void Close()
{
Dispose(true);
}
-
+
public void Dispose()
{
Close();
@@ -171,9 +177,11 @@ namespace System.Resources {
private unsafe void Dispose(bool disposing)
{
- if (_store != null) {
+ if (_store != null)
+ {
_resCache = null;
- if (disposing) {
+ if (disposing)
+ {
// Close the stream in a thread-safe way. This fix means
// that we may call Close n times, but that's safe.
BinaryReader copyOfStore = _store;
@@ -189,27 +197,29 @@ namespace System.Resources {
_nameHashesPtr = null;
}
}
-
+
internal static unsafe int ReadUnalignedI4(int* p)
{
byte* buffer = (byte*)p;
// Unaligned, little endian format
return buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
}
-
- private void SkipString() {
+
+ private void SkipString()
+ {
int stringLength = _store.Read7BitEncodedInt();
- if (stringLength < 0) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_NegativeStringLength"));
+ if (stringLength < 0)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_NegativeStringLength);
}
_store.BaseStream.Seek(stringLength, SeekOrigin.Current);
}
private unsafe int GetNameHash(int index)
{
- Debug.Assert(index >=0 && index < _numResources, "Bad index into hash array. index: "+index);
- Debug.Assert((_ums == null && _nameHashes != null && _nameHashesPtr == null) ||
+ Debug.Assert(index >= 0 && index < _numResources, "Bad index into hash array. index: " + index);
+ Debug.Assert((_ums == null && _nameHashes != null && _nameHashesPtr == null) ||
(_ums != null && _nameHashes == null && _nameHashesPtr != null), "Internal state mangled.");
if (_ums == null)
return _nameHashes[index];
@@ -219,16 +229,17 @@ namespace System.Resources {
private unsafe int GetNamePosition(int index)
{
- Debug.Assert(index >=0 && index < _numResources, "Bad index into name position array. index: "+index);
- Debug.Assert((_ums == null && _namePositions != null && _namePositionsPtr == null) ||
+ Debug.Assert(index >= 0 && index < _numResources, "Bad index into name position array. index: " + index);
+ Debug.Assert((_ums == null && _namePositions != null && _namePositionsPtr == null) ||
(_ums != null && _namePositions == null && _namePositionsPtr != null), "Internal state mangled.");
int r;
if (_ums == null)
r = _namePositions[index];
else
r = ReadUnalignedI4(&_namePositionsPtr[index]);
- if (r < 0 || r > _dataSectionOffset - _nameSectionOffset) {
- throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesNameInvalidOffset", r));
+ if (r < 0 || r > _dataSectionOffset - _nameSectionOffset)
+ {
+ throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesNameInvalidOffset, r));
}
return r;
}
@@ -241,7 +252,7 @@ namespace System.Resources {
public IDictionaryEnumerator GetEnumerator()
{
if (_resCache == null)
- throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed"));
+ throw new InvalidOperationException(SR.ResourceReaderIsClosed);
return new ResourceEnumerator(this);
}
@@ -258,14 +269,15 @@ namespace System.Resources {
{
Debug.Assert(_store != null, "ResourceReader is closed!");
int hash = FastResourceComparer.HashFunction(name);
- BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for "+name+" hash: "+hash.ToString("x", CultureInfo.InvariantCulture));
+ BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for " + name + " hash: " + hash.ToString("x", CultureInfo.InvariantCulture));
// Binary search over the hashes. Use the _namePositions array to
// determine where they exist in the underlying stream.
int lo = 0;
int hi = _numResources - 1;
int index = -1;
bool success = false;
- while (lo <= hi) {
+ while (lo <= hi)
+ {
index = (lo + hi) >> 1;
// Do NOT use subtraction here, since it will wrap for large
// negative numbers.
@@ -278,7 +290,8 @@ namespace System.Resources {
else
c = 1;
//BCLDebug.Log("RESMGRFILEFORMAT", " Probing index "+index+" lo: "+lo+" hi: "+hi+" c: "+c);
- if (c == 0) {
+ if (c == 0)
+ {
success = true;
break;
}
@@ -287,7 +300,8 @@ namespace System.Resources {
else
hi = index - 1;
}
- if (!success) {
+ if (!success)
+ {
#if RESOURCE_FILE_FORMAT_DEBUG
String lastReadString;
lock(this) {
@@ -298,36 +312,42 @@ namespace System.Resources {
#endif
return -1;
}
-
+
// index is the location in our hash array that corresponds with a
// value in the namePositions array.
// There could be collisions in our hash function. Check on both sides
// of index to find the range of hash values that are equal to the
// target hash value.
- if (lo != index) {
+ if (lo != index)
+ {
lo = index;
while (lo > 0 && GetNameHash(lo - 1) == hash)
lo--;
}
- if (hi != index) {
+ if (hi != index)
+ {
hi = index;
while (hi < _numResources - 1 && GetNameHash(hi + 1) == hash)
hi++;
}
- lock(this) {
- for(int i = lo; i<=hi; i++) {
+ lock (this)
+ {
+ for (int i = lo; i <= hi; i++)
+ {
_store.BaseStream.Seek(_nameSectionOffset + GetNamePosition(i), SeekOrigin.Begin);
- if (CompareStringEqualsName(name)) {
+ if (CompareStringEqualsName(name))
+ {
int dataPos = _store.ReadInt32();
- if (dataPos < 0 || dataPos >= _store.BaseStream.Length - _dataSectionOffset) {
- throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dataPos));
+ if (dataPos < 0 || dataPos >= _store.BaseStream.Length - _dataSectionOffset)
+ {
+ throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataPos));
}
return dataPos;
}
}
}
- BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for "+name+": Found a hash collision, HOWEVER, neither of these collided values equaled the given string.");
+ BCLDebug.Log("RESMGRFILEFORMAT", "FindPosForResource for " + name + ": Found a hash collision, HOWEVER, neither of these collided values equaled the given string.");
return -1;
}
@@ -339,15 +359,18 @@ namespace System.Resources {
{
Debug.Assert(_store != null, "ResourceReader is closed!");
int byteLen = _store.Read7BitEncodedInt();
- if (byteLen < 0) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_NegativeStringLength"));
+ if (byteLen < 0)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_NegativeStringLength);
}
- if (_ums != null) {
+ if (_ums != null)
+ {
byte* bytes = _ums.PositionPointer;
// Skip over the data in the Stream, positioning ourselves right after it.
_ums.Seek(byteLen, SeekOrigin.Current);
- if (_ums.Position > _ums.Length) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesNameTooLong"));
+ if (_ums.Position > _ums.Length)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_ResourcesNameTooLong);
}
// On 64-bit machines, these char*'s may be misaligned. Use a
@@ -355,17 +378,19 @@ namespace System.Resources {
//return FastResourceComparer.CompareOrdinal((char*)bytes, byteLen/2, name) == 0;
return FastResourceComparer.CompareOrdinal(bytes, byteLen, name) == 0;
}
- else {
+ else
+ {
// This code needs to be fast
byte[] bytes = new byte[byteLen];
int numBytesToRead = byteLen;
- while(numBytesToRead > 0) {
+ while (numBytesToRead > 0)
+ {
int n = _store.Read(bytes, byteLen - numBytesToRead, numBytesToRead);
if (n == 0)
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceNameCorrupted"));
+ throw new BadImageFormatException(SR.BadImageFormat_ResourceNameCorrupted);
numBytesToRead -= n;
}
- return FastResourceComparer.CompareOrdinal(bytes, byteLen/2, name) == 0;
+ return FastResourceComparer.CompareOrdinal(bytes, byteLen / 2, name) == 0;
}
}
@@ -378,17 +403,20 @@ namespace System.Resources {
byte[] bytes;
int byteLen;
long nameVA = GetNamePosition(index);
- lock (this) {
+ lock (this)
+ {
_store.BaseStream.Seek(nameVA + _nameSectionOffset, SeekOrigin.Begin);
// Can't use _store.ReadString, since it's using UTF-8!
byteLen = _store.Read7BitEncodedInt();
- if (byteLen < 0) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_NegativeStringLength"));
+ if (byteLen < 0)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_NegativeStringLength);
}
- if (_ums != null) {
+ if (_ums != null)
+ {
if (_ums.Position > _ums.Length - byteLen)
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesIndexTooLong", index));
+ throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourcesIndexTooLong, index));
String s = null;
char* charPtr = (char*)_ums.PositionPointer;
@@ -402,14 +430,15 @@ namespace System.Resources {
}
else {
#endif //IA64
- s = new String(charPtr, 0, byteLen/2);
+ s = new String(charPtr, 0, byteLen / 2);
#if IA64
}
#endif //IA64
_ums.Position += byteLen;
dataOffset = _store.ReadInt32();
- if (dataOffset < 0 || dataOffset >= _store.BaseStream.Length - _dataSectionOffset) {
- throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dataOffset));
+ if (dataOffset < 0 || dataOffset >= _store.BaseStream.Length - _dataSectionOffset)
+ {
+ throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataOffset));
}
return s;
}
@@ -419,15 +448,17 @@ namespace System.Resources {
// Use a blocking read in case the stream doesn't give us back
// everything immediately.
int count = byteLen;
- while(count > 0) {
+ while (count > 0)
+ {
int n = _store.Read(bytes, byteLen - count, count);
if (n == 0)
- throw new EndOfStreamException(Environment.GetResourceString("BadImageFormat_ResourceNameCorrupted_NameIndex", index));
+ throw new EndOfStreamException(SR.Format(SR.BadImageFormat_ResourceNameCorrupted_NameIndex, index));
count -= n;
}
dataOffset = _store.ReadInt32();
- if (dataOffset < 0 || dataOffset >= _store.BaseStream.Length - _dataSectionOffset) {
- throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dataOffset));
+ if (dataOffset < 0 || dataOffset >= _store.BaseStream.Length - _dataSectionOffset)
+ {
+ throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataOffset));
}
}
return Encoding.Unicode.GetString(bytes, 0, byteLen);
@@ -440,15 +471,17 @@ namespace System.Resources {
{
Debug.Assert(_store != null, "ResourceReader is closed!");
long nameVA = GetNamePosition(index);
- lock(this) {
+ lock (this)
+ {
_store.BaseStream.Seek(nameVA + _nameSectionOffset, SeekOrigin.Begin);
SkipString();
//BCLDebug.Log("RESMGRFILEFORMAT", "GetValueForNameIndex for index: "+index+" skip (name length): "+skip);
int dataPos = _store.ReadInt32();
- if (dataPos < 0 || dataPos >= _store.BaseStream.Length - _dataSectionOffset) {
- throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dataPos));
+ if (dataPos < 0 || dataPos >= _store.BaseStream.Length - _dataSectionOffset)
+ {
+ throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dataPos));
}
- BCLDebug.Log("RESMGRFILEFORMAT", "GetValueForNameIndex: dataPos: "+dataPos);
+ BCLDebug.Log("RESMGRFILEFORMAT", "GetValueForNameIndex: dataPos: " + dataPos);
ResourceTypeCode junk;
if (_version == 1)
return LoadObjectV1(dataPos);
@@ -464,30 +497,33 @@ namespace System.Resources {
internal String LoadString(int pos)
{
Debug.Assert(_store != null, "ResourceReader is closed!");
- _store.BaseStream.Seek(_dataSectionOffset+pos, SeekOrigin.Begin);
+ _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin);
String s = null;
int typeIndex = _store.Read7BitEncodedInt();
- if (_version == 1) {
+ if (_version == 1)
+ {
if (typeIndex == -1)
return null;
if (FindType(typeIndex) != typeof(String))
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Type", FindType(typeIndex).FullName));
+ throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResourceNotString_Type, FindType(typeIndex).FullName));
s = _store.ReadString();
}
- else {
- ResourceTypeCode typeCode = (ResourceTypeCode) typeIndex;
- if (typeCode != ResourceTypeCode.String && typeCode != ResourceTypeCode.Null) {
+ else
+ {
+ ResourceTypeCode typeCode = (ResourceTypeCode)typeIndex;
+ if (typeCode != ResourceTypeCode.String && typeCode != ResourceTypeCode.Null)
+ {
String typeString;
if (typeCode < ResourceTypeCode.StartOfUserTypes)
typeString = typeCode.ToString();
else
typeString = FindType(typeCode - ResourceTypeCode.StartOfUserTypes).FullName;
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Type", typeString));
+ throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResourceNotString_Type, typeString));
}
if (typeCode == ResourceTypeCode.String) // ignore Null
s = _store.ReadString();
}
- BCLDebug.Log("RESMGRFILEFORMAT", "LoadString("+pos.ToString("x", CultureInfo.InvariantCulture)+" returned "+(s==null ? "[a null string]" : s));
+ BCLDebug.Log("RESMGRFILEFORMAT", "LoadString(" + pos.ToString("x", CultureInfo.InvariantCulture) + " returned " + (s == null ? "[a null string]" : s));
return s;
}
@@ -502,7 +538,8 @@ namespace System.Resources {
internal Object LoadObject(int pos, out ResourceTypeCode typeCode)
{
- if (_version == 1) {
+ if (_version == 1)
+ {
Object o = LoadObjectV1(pos);
typeCode = (o is String) ? ResourceTypeCode.String : ResourceTypeCode.StartOfUserTypes;
return o;
@@ -519,26 +556,30 @@ namespace System.Resources {
Debug.Assert(_store != null, "ResourceReader is closed!");
Debug.Assert(_version == 1, ".resources file was not a V1 .resources file!");
- try {
+ try
+ {
// mega try-catch performs exceptionally bad on x64; factored out body into
// _LoadObjectV1 and wrap here.
return _LoadObjectV1(pos);
}
- catch (EndOfStreamException eof) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"), eof);
+ catch (EndOfStreamException eof)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch, eof);
}
- catch (ArgumentOutOfRangeException e) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"), e);
+ catch (ArgumentOutOfRangeException e)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch, e);
}
}
- private Object _LoadObjectV1(int pos) {
- _store.BaseStream.Seek(_dataSectionOffset+pos, SeekOrigin.Begin);
+ private Object _LoadObjectV1(int pos)
+ {
+ _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin);
int typeIndex = _store.Read7BitEncodedInt();
if (typeIndex == -1)
return null;
RuntimeType type = FindType(typeIndex);
- BCLDebug.Log("RESMGRFILEFORMAT", "LoadObject type: "+type.Name+" pos: 0x"+_store.BaseStream.Position.ToString("x", CultureInfo.InvariantCulture));
+ BCLDebug.Log("RESMGRFILEFORMAT", "LoadObject type: " + type.Name + " pos: 0x" + _store.BaseStream.Position.ToString("x", CultureInfo.InvariantCulture));
// Consider putting in logic to see if this type is a
// primitive or a value type first, so we can reach the
// deserialization code faster for arbitrary objects.
@@ -565,21 +606,24 @@ namespace System.Resources {
return _store.ReadSingle();
else if (type == typeof(Double))
return _store.ReadDouble();
- else if (type == typeof(DateTime)) {
+ else if (type == typeof(DateTime))
+ {
// Ideally we should use DateTime's ToBinary & FromBinary,
// but we can't for compatibility reasons.
return new DateTime(_store.ReadInt64());
}
else if (type == typeof(TimeSpan))
return new TimeSpan(_store.ReadInt64());
- else if (type == typeof(Decimal)) {
+ else if (type == typeof(Decimal))
+ {
int[] bits = new int[4];
- for(int i=0; i<bits.Length; i++)
+ for (int i = 0; i < bits.Length; i++)
bits[i] = _store.ReadInt32();
return new Decimal(bits);
}
- else {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ResourceObjectSerialization"));
+ else
+ {
+ throw new NotSupportedException(SR.NotSupported_ResourceObjectSerialization);
}
}
@@ -588,136 +632,152 @@ namespace System.Resources {
Debug.Assert(_store != null, "ResourceReader is closed!");
Debug.Assert(_version >= 2, ".resources file was not a V2 (or higher) .resources file!");
- try {
+ try
+ {
// mega try-catch performs exceptionally bad on x64; factored out body into
// _LoadObjectV2 and wrap here.
return _LoadObjectV2(pos, out typeCode);
}
- catch (EndOfStreamException eof) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"), eof);
+ catch (EndOfStreamException eof)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch, eof);
}
- catch (ArgumentOutOfRangeException e) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"), e);
+ catch (ArgumentOutOfRangeException e)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch, e);
}
}
- private Object _LoadObjectV2(int pos, out ResourceTypeCode typeCode) {
- _store.BaseStream.Seek(_dataSectionOffset+pos, SeekOrigin.Begin);
- typeCode = (ResourceTypeCode) _store.Read7BitEncodedInt();
+ private Object _LoadObjectV2(int pos, out ResourceTypeCode typeCode)
+ {
+ _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin);
+ typeCode = (ResourceTypeCode)_store.Read7BitEncodedInt();
- BCLDebug.Log("RESMGRFILEFORMAT", "LoadObjectV2 type: "+typeCode+" pos: 0x"+_store.BaseStream.Position.ToString("x", CultureInfo.InvariantCulture));
-
- switch(typeCode) {
- case ResourceTypeCode.Null:
- return null;
+ BCLDebug.Log("RESMGRFILEFORMAT", "LoadObjectV2 type: " + typeCode + " pos: 0x" + _store.BaseStream.Position.ToString("x", CultureInfo.InvariantCulture));
- case ResourceTypeCode.String:
- return _store.ReadString();
-
- case ResourceTypeCode.Boolean:
- return _store.ReadBoolean();
+ switch (typeCode)
+ {
+ case ResourceTypeCode.Null:
+ return null;
- case ResourceTypeCode.Char:
- return (char) _store.ReadUInt16();
+ case ResourceTypeCode.String:
+ return _store.ReadString();
- case ResourceTypeCode.Byte:
- return _store.ReadByte();
+ case ResourceTypeCode.Boolean:
+ return _store.ReadBoolean();
- case ResourceTypeCode.SByte:
- return _store.ReadSByte();
+ case ResourceTypeCode.Char:
+ return (char)_store.ReadUInt16();
- case ResourceTypeCode.Int16:
- return _store.ReadInt16();
+ case ResourceTypeCode.Byte:
+ return _store.ReadByte();
- case ResourceTypeCode.UInt16:
- return _store.ReadUInt16();
+ case ResourceTypeCode.SByte:
+ return _store.ReadSByte();
- case ResourceTypeCode.Int32:
- return _store.ReadInt32();
+ case ResourceTypeCode.Int16:
+ return _store.ReadInt16();
- case ResourceTypeCode.UInt32:
- return _store.ReadUInt32();
+ case ResourceTypeCode.UInt16:
+ return _store.ReadUInt16();
- case ResourceTypeCode.Int64:
- return _store.ReadInt64();
+ case ResourceTypeCode.Int32:
+ return _store.ReadInt32();
- case ResourceTypeCode.UInt64:
- return _store.ReadUInt64();
+ case ResourceTypeCode.UInt32:
+ return _store.ReadUInt32();
- case ResourceTypeCode.Single:
- return _store.ReadSingle();
+ case ResourceTypeCode.Int64:
+ return _store.ReadInt64();
- case ResourceTypeCode.Double:
- return _store.ReadDouble();
+ case ResourceTypeCode.UInt64:
+ return _store.ReadUInt64();
- case ResourceTypeCode.Decimal:
- return _store.ReadDecimal();
-
- case ResourceTypeCode.DateTime:
- // Use DateTime's ToBinary & FromBinary.
- Int64 data = _store.ReadInt64();
- return DateTime.FromBinary(data);
-
- case ResourceTypeCode.TimeSpan:
- Int64 ticks = _store.ReadInt64();
- return new TimeSpan(ticks);
-
- // Special types
- case ResourceTypeCode.ByteArray: {
- int len = _store.ReadInt32();
- if (len < 0) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", len));
- }
+ case ResourceTypeCode.Single:
+ return _store.ReadSingle();
+
+ case ResourceTypeCode.Double:
+ return _store.ReadDouble();
+
+ case ResourceTypeCode.Decimal:
+ return _store.ReadDecimal();
- if (_ums == null) {
- if (len > _store.BaseStream.Length) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", len));
+ case ResourceTypeCode.DateTime:
+ // Use DateTime's ToBinary & FromBinary.
+ Int64 data = _store.ReadInt64();
+ return DateTime.FromBinary(data);
+
+ case ResourceTypeCode.TimeSpan:
+ Int64 ticks = _store.ReadInt64();
+ return new TimeSpan(ticks);
+
+ // Special types
+ case ResourceTypeCode.ByteArray:
+ {
+ int len = _store.ReadInt32();
+ if (len < 0)
+ {
+ throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len));
}
- return _store.ReadBytes(len);
- }
- if (len > _ums.Length - _ums.Position) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", len));
- }
+ if (_ums == null)
+ {
+ if (len > _store.BaseStream.Length)
+ {
+ throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len));
+ }
+ return _store.ReadBytes(len);
+ }
- byte[] bytes = new byte[len];
- int r = _ums.Read(bytes, 0, len);
- Debug.Assert(r == len, "ResourceReader needs to use a blocking read here. (Call _store.ReadBytes(len)?)");
- return bytes;
- }
+ if (len > _ums.Length - _ums.Position)
+ {
+ throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len));
+ }
- case ResourceTypeCode.Stream: {
- int len = _store.ReadInt32();
- if (len < 0) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", len));
- }
- if (_ums == null) {
- byte[] bytes = _store.ReadBytes(len);
- // Lifetime of memory == lifetime of this stream.
- return new PinnedBufferMemoryStream(bytes);
+ byte[] bytes = new byte[len];
+ int r = _ums.Read(bytes, 0, len);
+ Debug.Assert(r == len, "ResourceReader needs to use a blocking read here. (Call _store.ReadBytes(len)?)");
+ return bytes;
}
- // make sure we don't create an UnmanagedMemoryStream that is longer than the resource stream.
- if (len > _ums.Length - _ums.Position) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", len));
+ case ResourceTypeCode.Stream:
+ {
+ int len = _store.ReadInt32();
+ if (len < 0)
+ {
+ throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len));
+ }
+ if (_ums == null)
+ {
+ byte[] bytes = _store.ReadBytes(len);
+ // Lifetime of memory == lifetime of this stream.
+ return new PinnedBufferMemoryStream(bytes);
+ }
+
+ // make sure we don't create an UnmanagedMemoryStream that is longer than the resource stream.
+ if (len > _ums.Length - _ums.Position)
+ {
+ throw new BadImageFormatException(SR.Format(SR.BadImageFormat_ResourceDataLengthInvalid, len));
+ }
+
+ // For the case that we've memory mapped in the .resources
+ // file, just return a Stream pointing to that block of memory.
+ unsafe
+ {
+ return new UnmanagedMemoryStream(_ums.PositionPointer, len, len, FileAccess.Read);
+ }
}
- // For the case that we've memory mapped in the .resources
- // file, just return a Stream pointing to that block of memory.
- unsafe {
- return new UnmanagedMemoryStream(_ums.PositionPointer, len, len, FileAccess.Read);
+ default:
+ if (typeCode < ResourceTypeCode.StartOfUserTypes)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_TypeMismatch);
}
- }
-
- default:
- if (typeCode < ResourceTypeCode.StartOfUserTypes) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"));
- }
- break;
+ break;
}
// Normal serialized objects
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ResourceObjectSerialization"));
+ throw new NotSupportedException(SR.NotSupported_ResourceObjectSerialization);
}
@@ -729,16 +789,19 @@ namespace System.Resources {
{
Debug.Assert(_store != null, "ResourceReader is closed!");
- try {
+ try
+ {
// mega try-catch performs exceptionally bad on x64; factored out body into
// _ReadResources and wrap here.
_ReadResources();
}
- catch (EndOfStreamException eof) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"), eof);
+ catch (EndOfStreamException eof)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted, eof);
}
- catch (IndexOutOfRangeException e) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"), e);
+ catch (IndexOutOfRangeException e)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted, e);
}
}
@@ -748,21 +811,24 @@ namespace System.Resources {
// Check for magic number
int magicNum = _store.ReadInt32();
if (magicNum != ResourceManager.MagicNumber)
- throw new ArgumentException(Environment.GetResourceString("Resources_StreamNotValid"));
+ throw new ArgumentException(SR.Resources_StreamNotValid);
// Assuming this is ResourceManager header V1 or greater, hopefully
// after the version number there is a number of bytes to skip
// to bypass the rest of the ResMgr header. For V2 or greater, we
// use this to skip to the end of the header
int resMgrHeaderVersion = _store.ReadInt32();
int numBytesToSkip = _store.ReadInt32();
- if (numBytesToSkip < 0 || resMgrHeaderVersion < 0) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
+ if (numBytesToSkip < 0 || resMgrHeaderVersion < 0)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
}
- if (resMgrHeaderVersion > 1) {
+ if (resMgrHeaderVersion > 1)
+ {
BCLDebug.Log("RESMGRFILEFORMAT", LogLevel.Status, "ReadResources: Unexpected ResMgr header version: {0} Skipping ahead {1} bytes.", resMgrHeaderVersion, numBytesToSkip);
_store.BaseStream.Seek(numBytesToSkip, SeekOrigin.Current);
}
- else {
+ else
+ {
BCLDebug.Log("RESMGRFILEFORMAT", "ReadResources: Parsing ResMgr header v1.");
// We don't care about numBytesToSkip; read the rest of the header
@@ -773,7 +839,7 @@ namespace System.Resources {
AssemblyName mscorlib = new AssemblyName(ResourceManager.MscorlibName);
if (!ResourceManager.CompareNames(readerType, ResourceManager.ResReaderTypeName, mscorlib))
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_WrongResourceReader_Type", readerType));
+ throw new NotSupportedException(SR.Format(SR.NotSupported_WrongResourceReader_Type, readerType));
// Skip over type name for a suitable ResourceSet
SkipString();
@@ -783,7 +849,7 @@ namespace System.Resources {
// Do file version check
int version = _store.ReadInt32();
if (version != RuntimeResourceSet.Version && version != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_ResourceFileUnsupportedVersion", RuntimeResourceSet.Version, version));
+ throw new ArgumentException(SR.Format(SR.Arg_ResourceFileUnsupportedVersion, RuntimeResourceSet.Version, version));
_version = version;
#if RESOURCE_FILE_FORMAT_DEBUG
@@ -807,8 +873,9 @@ namespace System.Resources {
#endif
_numResources = _store.ReadInt32();
- if (_numResources < 0) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
+ if (_numResources < 0)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
}
BCLDebug.Log("RESMGRFILEFORMAT", "ReadResources: Expecting " + _numResources + " resources.");
#if RESOURCE_FILE_FORMAT_DEBUG
@@ -819,13 +886,15 @@ namespace System.Resources {
// Read type positions into type positions array.
// But delay initialize the type table.
int numTypes = _store.ReadInt32();
- if (numTypes < 0) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
+ if (numTypes < 0)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
}
_typeTable = new RuntimeType[numTypes];
_typeNamePositions = new int[numTypes];
- for (int i=0; i<numTypes; i++) {
- _typeNamePositions[i] = (int) _store.BaseStream.Position;
+ for (int i = 0; i < numTypes; i++)
+ {
+ _typeNamePositions[i] = (int)_store.BaseStream.Position;
// Skip over the Strings in the file. Don't create types.
SkipString();
@@ -844,8 +913,10 @@ namespace System.Resources {
// should be aligned No need to verify the byte values.
long pos = _store.BaseStream.Position;
int alignBytes = ((int)pos) & 7;
- if (alignBytes != 0) {
- for (int i = 0; i < 8 - alignBytes; i++) {
+ if (alignBytes != 0)
+ {
+ for (int i = 0; i < 8 - alignBytes; i++)
+ {
_store.ReadByte();
}
}
@@ -858,18 +929,23 @@ namespace System.Resources {
}
#endif
- if (_ums == null) {
+ if (_ums == null)
+ {
_nameHashes = new int[_numResources];
- for (int i = 0; i < _numResources; i++) {
+ for (int i = 0; i < _numResources; i++)
+ {
_nameHashes[i] = _store.ReadInt32();
}
}
- else {
+ else
+ {
int seekPos = unchecked(4 * _numResources);
- if (seekPos < 0) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
+ if (seekPos < 0)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
}
- unsafe {
+ unsafe
+ {
_nameHashesPtr = (int*)_ums.PositionPointer;
// Skip over the array of nameHashes.
_ums.Seek(seekPos, SeekOrigin.Current);
@@ -885,23 +961,29 @@ namespace System.Resources {
_store.BaseStream.Position += 8;
}
#endif
- if (_ums == null) {
+ if (_ums == null)
+ {
_namePositions = new int[_numResources];
- for (int i = 0; i < _numResources; i++) {
+ for (int i = 0; i < _numResources; i++)
+ {
int namePosition = _store.ReadInt32();
- if (namePosition < 0) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
+ if (namePosition < 0)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
}
_namePositions[i] = namePosition;
}
}
- else {
+ else
+ {
int seekPos = unchecked(4 * _numResources);
- if (seekPos < 0) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
+ if (seekPos < 0)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
}
- unsafe {
+ unsafe
+ {
_namePositionsPtr = (int*)_ums.PositionPointer;
// Skip over the array of namePositions.
_ums.Seek(seekPos, SeekOrigin.Current);
@@ -912,16 +994,18 @@ namespace System.Resources {
// Read location of data section.
_dataSectionOffset = _store.ReadInt32();
- if (_dataSectionOffset < 0) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
+ if (_dataSectionOffset < 0)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
}
// Store current location as start of name section
_nameSectionOffset = _store.BaseStream.Position;
// _nameSectionOffset should be <= _dataSectionOffset; if not, it's corrupt
- if (_dataSectionOffset < _nameSectionOffset) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
+ if (_dataSectionOffset < _nameSectionOffset)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_ResourcesHeaderCorrupted);
}
BCLDebug.Log("RESMGRFILEFORMAT", String.Format(CultureInfo.InvariantCulture, "ReadResources: _nameOffset = 0x{0:x} _dataOffset = 0x{1:x}", _nameSectionOffset, _dataSectionOffset));
@@ -932,12 +1016,15 @@ namespace System.Resources {
// and initialize Reflection.
private RuntimeType FindType(int typeIndex)
{
- if (typeIndex < 0 || typeIndex >= _typeTable.Length) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_InvalidType"));
+ if (typeIndex < 0 || typeIndex >= _typeTable.Length)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_InvalidType);
}
- if (_typeTable[typeIndex] == null) {
+ if (_typeTable[typeIndex] == null)
+ {
long oldPos = _store.BaseStream.Position;
- try {
+ try
+ {
_store.BaseStream.Position = _typeNamePositions[typeIndex];
String typeName = _store.ReadString();
_typeTable[typeIndex] = (RuntimeType)Type.GetType(typeName, true);
@@ -954,9 +1041,10 @@ namespace System.Resources {
// getting to Type.GetType -- this is costly with v1 resource formats.
catch (FileNotFoundException)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ResourceObjectSerialization"));
+ throw new NotSupportedException(SR.NotSupported_ResourceObjectSerialization);
}
- finally {
+ finally
+ {
_store.BaseStream.Position = oldPos;
}
}
@@ -971,7 +1059,7 @@ namespace System.Resources {
throw new ArgumentNullException(nameof(resourceName));
Contract.EndContractBlock();
if (_resCache == null)
- throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed"));
+ throw new InvalidOperationException(SR.ResourceReaderIsClosed);
// Get the type information from the data section. Also,
// sort all of the data section's indexes to compute length of
@@ -979,24 +1067,29 @@ namespace System.Resources {
// off the length of the type code).
int[] sortedDataPositions = new int[_numResources];
int dataPos = FindPosForResource(resourceName);
- if( dataPos == -1) {
- throw new ArgumentException(Environment.GetResourceString("Arg_ResourceNameNotExist", resourceName));
+ if (dataPos == -1)
+ {
+ throw new ArgumentException(SR.Format(SR.Arg_ResourceNameNotExist, resourceName));
}
-
- lock(this) {
+
+ lock (this)
+ {
// Read all the positions of data within the data section.
- for(int i=0; i<_numResources; i++) {
+ for (int i = 0; i < _numResources; i++)
+ {
_store.BaseStream.Position = _nameSectionOffset + GetNamePosition(i);
// Skip over name of resource
int numBytesToSkip = _store.Read7BitEncodedInt();
- if (numBytesToSkip < 0) {
- throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesNameInvalidOffset", numBytesToSkip));
+ if (numBytesToSkip < 0)
+ {
+ throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesNameInvalidOffset, numBytesToSkip));
}
_store.BaseStream.Position += numBytesToSkip;
int dPos = _store.ReadInt32();
- if (dPos < 0 || dPos >= _store.BaseStream.Length - _dataSectionOffset) {
- throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dPos));
+ if (dPos < 0 || dPos >= _store.BaseStream.Length - _dataSectionOffset)
+ {
+ throw new FormatException(SR.Format(SR.BadImageFormat_ResourcesDataInvalidOffset, dPos));
}
sortedDataPositions[i] = dPos;
}
@@ -1005,23 +1098,24 @@ namespace System.Resources {
int index = Array.BinarySearch(sortedDataPositions, dataPos);
Debug.Assert(index >= 0 && index < _numResources, "Couldn't find data position within sorted data positions array!");
long nextData = (index < _numResources - 1) ? sortedDataPositions[index + 1] + _dataSectionOffset : _store.BaseStream.Length;
- int len = (int) (nextData - (dataPos + _dataSectionOffset));
- Debug.Assert(len >= 0 && len <= (int) _store.BaseStream.Length - dataPos + _dataSectionOffset, "Length was negative or outside the bounds of the file!");
+ int len = (int)(nextData - (dataPos + _dataSectionOffset));
+ Debug.Assert(len >= 0 && len <= (int)_store.BaseStream.Length - dataPos + _dataSectionOffset, "Length was negative or outside the bounds of the file!");
// Read type code then byte[]
_store.BaseStream.Position = _dataSectionOffset + dataPos;
- ResourceTypeCode typeCode = (ResourceTypeCode) _store.Read7BitEncodedInt();
- if (typeCode < 0 || typeCode >= ResourceTypeCode.StartOfUserTypes + _typeTable.Length) {
- throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_InvalidType"));
+ ResourceTypeCode typeCode = (ResourceTypeCode)_store.Read7BitEncodedInt();
+ if (typeCode < 0 || typeCode >= ResourceTypeCode.StartOfUserTypes + _typeTable.Length)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_InvalidType);
}
resourceType = TypeNameFromTypeCode(typeCode);
// The length must be adjusted to subtract off the number
// of bytes in the 7 bit encoded type code.
- len -= (int) (_store.BaseStream.Position - (_dataSectionOffset + dataPos));
+ len -= (int)(_store.BaseStream.Position - (_dataSectionOffset + dataPos));
byte[] bytes = _store.ReadBytes(len);
if (bytes.Length != len)
- throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourceNameCorrupted"));
+ throw new FormatException(SR.BadImageFormat_ResourceNameCorrupted);
resourceData = bytes;
}
}
@@ -1029,19 +1123,23 @@ namespace System.Resources {
private String TypeNameFromTypeCode(ResourceTypeCode typeCode)
{
Contract.Requires(typeCode >= 0, "can't be negative");
- if (typeCode < ResourceTypeCode.StartOfUserTypes) {
+ if (typeCode < ResourceTypeCode.StartOfUserTypes)
+ {
Debug.Assert(!String.Equals(typeCode.ToString(), "LastPrimitive"), "Change ResourceTypeCode metadata order so LastPrimitive isn't what Enum.ToString prefers.");
return "ResourceTypeCode." + typeCode.ToString();
}
- else {
+ else
+ {
int typeIndex = typeCode - ResourceTypeCode.StartOfUserTypes;
Debug.Assert(typeIndex >= 0 && typeIndex < _typeTable.Length, "TypeCode is broken or corrupted!");
long oldPos = _store.BaseStream.Position;
- try {
+ try
+ {
_store.BaseStream.Position = _typeNamePositions[typeIndex];
return _store.ReadString();
}
- finally {
+ finally
+ {
_store.BaseStream.Position = oldPos;
}
}
@@ -1068,7 +1166,8 @@ namespace System.Resources {
public bool MoveNext()
{
- if (_currentName == _reader._numResources - 1 || _currentName == ENUM_DONE) {
+ if (_currentName == _reader._numResources - 1 || _currentName == ENUM_DONE)
+ {
_currentIsValid = false;
_currentName = ENUM_DONE;
return false;
@@ -1077,49 +1176,61 @@ namespace System.Resources {
_currentName++;
return true;
}
-
- public Object Key {
- get {
- if (_currentName == ENUM_DONE) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded));
- if (!_currentIsValid) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
- if (_reader._resCache == null) throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed"));
+
+ public Object Key
+ {
+ get
+ {
+ if (_currentName == ENUM_DONE) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumEnded));
+ if (!_currentIsValid) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
+ if (_reader._resCache == null) throw new InvalidOperationException(SR.ResourceReaderIsClosed);
return _reader.AllocateStringForNameIndex(_currentName, out _dataPosition);
}
}
-
- public Object Current {
- get {
+
+ public Object Current
+ {
+ get
+ {
return Entry;
}
}
// Warning: This requires that you call the Key or Entry property FIRST before calling it!
- internal int DataPosition {
- get {
+ internal int DataPosition
+ {
+ get
+ {
return _dataPosition;
}
}
- public DictionaryEntry Entry {
- get {
- if (_currentName == ENUM_DONE) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded));
- if (!_currentIsValid) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
- if (_reader._resCache == null) throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed"));
+ public DictionaryEntry Entry
+ {
+ get
+ {
+ if (_currentName == ENUM_DONE) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumEnded));
+ if (!_currentIsValid) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
+ if (_reader._resCache == null) throw new InvalidOperationException(SR.ResourceReaderIsClosed);
String key;
Object value = null;
- lock (_reader) { // locks should be taken in the same order as in RuntimeResourceSet.GetObject to avoid deadlock
- lock (_reader._resCache) {
+ lock (_reader)
+ { // locks should be taken in the same order as in RuntimeResourceSet.GetObject to avoid deadlock
+ lock (_reader._resCache)
+ {
key = _reader.AllocateStringForNameIndex(_currentName, out _dataPosition); // AllocateStringForNameIndex could lock on _reader
ResourceLocator locator;
- if (_reader._resCache.TryGetValue(key, out locator)) {
+ if (_reader._resCache.TryGetValue(key, out locator))
+ {
value = locator.Value;
}
- if (value == null) {
- if (_dataPosition == -1)
+ if (value == null)
+ {
+ if (_dataPosition == -1)
value = _reader.GetValueForNameIndex(_currentName);
- else
+ else
value = _reader.LoadObject(_dataPosition);
// If enumeration and subsequent lookups happen very
// frequently in the same process, add a ResourceLocator
@@ -1132,12 +1243,14 @@ namespace System.Resources {
return new DictionaryEntry(key, value);
}
}
-
- public Object Value {
- get {
- if (_currentName == ENUM_DONE) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded));
- if (!_currentIsValid) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
- if (_reader._resCache == null) throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed"));
+
+ public Object Value
+ {
+ get
+ {
+ if (_currentName == ENUM_DONE) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumEnded));
+ if (!_currentIsValid) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
+ if (_reader._resCache == null) throw new InvalidOperationException(SR.ResourceReaderIsClosed);
// Consider using _resCache here, eventually, if
// this proves to be an interesting perf scenario.
@@ -1149,7 +1262,7 @@ namespace System.Resources {
public void Reset()
{
- if (_reader._resCache == null) throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed"));
+ if (_reader._resCache == null) throw new InvalidOperationException(SR.ResourceReaderIsClosed);
_currentIsValid = false;
_currentName = ENUM_NOT_STARTED;
}
diff --git a/src/mscorlib/src/System/Resources/ResourceSet.cs b/src/mscorlib/src/System/Resources/ResourceSet.cs
index 8fd9346f91..8775f6411a 100644
--- a/src/mscorlib/src/System/Resources/ResourceSet.cs
+++ b/src/mscorlib/src/System/Resources/ResourceSet.cs
@@ -12,7 +12,9 @@
**
**
===========================================================*/
-namespace System.Resources {
+
+namespace System.Resources
+{
using System;
using System.Collections;
using System.IO;
@@ -75,7 +77,7 @@ namespace System.Resources {
ReadResources();
}
#endif // LOOSELY_LINKED_RESOURCE_REFERENCE
-
+
// Creates a ResourceSet using the system default ResourceReader
// implementation. Use this constructor to read from an open stream
// of data.
@@ -119,7 +121,7 @@ namespace System.Resources {
ReadResources();
}
#endif // LOOSELY_LINKED_RESOURCE_REFERENCE
-
+
private void CommonInit()
{
Table = new Hashtable();
@@ -133,10 +135,11 @@ namespace System.Resources {
{
Dispose(true);
}
-
+
protected virtual void Dispose(bool disposing)
{
- if (disposing) {
+ if (disposing)
+ {
// Close the Reader in a thread-safe way.
IResourceReader copyOfReader = Reader;
Reader = null;
@@ -169,7 +172,7 @@ namespace System.Resources {
{
return typeof(ResourceReader);
}
-
+
// Returns the preferred IResourceWriter class for this kind of ResourceSet.
// Subclasses of ResourceSet using their own Readers &; should override
// GetDefaultReader and GetDefaultWriter.
@@ -183,7 +186,6 @@ namespace System.Resources {
return GetEnumeratorHelper();
}
- /// <internalonly/>
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumeratorHelper();
@@ -193,7 +195,7 @@ namespace System.Resources {
{
Hashtable copyOfTable = Table; // Avoid a race with Dispose
if (copyOfTable == null)
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet"));
+ throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet);
return copyOfTable.GetEnumerator();
}
@@ -202,11 +204,13 @@ namespace System.Resources {
public virtual String GetString(String name)
{
Object obj = GetObjectInternal(name);
- try {
+ try
+ {
return (String)obj;
}
- catch (InvalidCastException) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Name", name));
+ catch (InvalidCastException)
+ {
+ throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResourceNotString_Name, name));
}
}
@@ -217,28 +221,33 @@ namespace System.Resources {
// Case-sensitive lookup
obj = GetObjectInternal(name);
- try {
+ try
+ {
s = (String)obj;
}
- catch (InvalidCastException) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Name", name));
+ catch (InvalidCastException)
+ {
+ throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResourceNotString_Name, name));
}
// case-sensitive lookup succeeded
- if (s != null || !ignoreCase) {
+ if (s != null || !ignoreCase)
+ {
return s;
- }
+ }
// Try doing a case-insensitive lookup
obj = GetCaseInsensitiveObjectInternal(name);
- try {
+ try
+ {
return (String)obj;
}
- catch (InvalidCastException) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Name", name));
+ catch (InvalidCastException)
+ {
+ throw new InvalidOperationException(SR.Format(SR.InvalidOperation_ResourceNotString_Name, name));
}
}
-
+
// Look up an object value for a resource given its name.
//
public virtual Object GetObject(String name)
@@ -249,17 +258,18 @@ namespace System.Resources {
public virtual Object GetObject(String name, bool ignoreCase)
{
Object obj = GetObjectInternal(name);
-
+
if (obj != null || !ignoreCase)
return obj;
return GetCaseInsensitiveObjectInternal(name);
}
-
+
protected virtual void ReadResources()
{
IDictionaryEnumerator en = Reader.GetEnumerator();
- while (en.MoveNext()) {
+ while (en.MoveNext())
+ {
Object value = en.Value;
#if LOOSELY_LINKED_RESOURCE_REFERENCE
if (Assembly != null && value is LooselyLinkedResourceReference) {
@@ -282,7 +292,7 @@ namespace System.Resources {
Hashtable copyOfTable = Table; // Avoid a race with Dispose
if (copyOfTable == null)
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet"));
+ throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet);
return copyOfTable[name];
}
@@ -292,7 +302,7 @@ namespace System.Resources {
Hashtable copyOfTable = Table; // Avoid a race with Dispose
if (copyOfTable == null)
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet"));
+ throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet);
Hashtable caseTable = _caseInsensitiveTable; // Avoid a race condition with Close
if (caseTable == null)
@@ -300,7 +310,7 @@ namespace System.Resources {
caseTable = new Hashtable(StringComparer.OrdinalIgnoreCase);
#if _DEBUG
//Console.WriteLine("ResourceSet::GetObject loading up case-insensitive data");
- BCLDebug.Perf(false, "Using case-insensitive lookups is bad perf-wise. Consider capitalizing "+name+" correctly in your source");
+ BCLDebug.Perf(false, "Using case-insensitive lookups is bad perf-wise. Consider capitalizing " + name + " correctly in your source");
#endif
IDictionaryEnumerator en = copyOfTable.GetEnumerator();
diff --git a/src/mscorlib/src/System/Resources/ResourceTypeCode.cs b/src/mscorlib/src/System/Resources/ResourceTypeCode.cs
deleted file mode 100644
index 64fb076eb5..0000000000
--- a/src/mscorlib/src/System/Resources/ResourceTypeCode.cs
+++ /dev/null
@@ -1,57 +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.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Marker for types in .resources files
-**
-**
-===========================================================*/
-
-namespace System.Resources {
- /* An internal implementation detail for .resources files, describing
- what type an object is.
- Ranges:
- 0 - 0x1F Primitives and reserved values
- 0x20 - 0x3F Specially recognized types, like byte[] and Streams
-
- Note this data must be included in any documentation describing the
- internals of .resources files.
- */
- [Serializable]
- internal enum ResourceTypeCode {
- // Primitives
- Null = 0,
- String = 1,
- Boolean = 2,
- Char = 3,
- Byte = 4,
- SByte = 5,
- Int16 = 6,
- UInt16 = 7,
- Int32 = 8,
- UInt32 = 9,
- Int64 = 0xa,
- UInt64 = 0xb,
- Single = 0xc,
- Double = 0xd,
- Decimal = 0xe,
- DateTime = 0xf,
- TimeSpan = 0x10,
-
- // A meta-value - change this if you add new primitives
- LastPrimitive = TimeSpan,
-
- // Types with a special representation, like byte[] and Stream
- ByteArray = 0x20,
- Stream = 0x21,
-
- // User types - serialized using the binary formatter.
- StartOfUserTypes = 0x40
- }
-}
diff --git a/src/mscorlib/src/System/Resources/RuntimeResourceSet.cs b/src/mscorlib/src/System/Resources/RuntimeResourceSet.cs
index a94ac82781..e9c038a498 100644
--- a/src/mscorlib/src/System/Resources/RuntimeResourceSet.cs
+++ b/src/mscorlib/src/System/Resources/RuntimeResourceSet.cs
@@ -12,7 +12,9 @@
**
**
===========================================================*/
-namespace System.Resources {
+
+namespace System.Resources
+{
using System;
using System.IO;
using System.Collections;
@@ -162,7 +164,7 @@ namespace System.Resources {
internal sealed class RuntimeResourceSet : ResourceSet, IEnumerable
{
internal const int Version = 2; // File format version number
-
+
// Cache for resources. Key is the resource name, which can be cached
// for arbitrarily long times, since the object is usually a string
// literal that will live for the lifetime of the appdomain. The
@@ -217,11 +219,14 @@ namespace System.Resources {
{
if (Reader == null)
return;
-
- if (disposing) {
- lock(Reader) {
+
+ if (disposing)
+ {
+ lock (Reader)
+ {
_resCache = null;
- if (_defaultReader != null) {
+ if (_defaultReader != null)
+ {
_defaultReader.Close();
_defaultReader = null;
}
@@ -229,8 +234,9 @@ namespace System.Resources {
// Set Reader to null to avoid a race in GetObject.
base.Dispose(disposing);
}
- }
- else {
+ }
+ else
+ {
// Just to make sure we always clear these fields in the future...
_resCache = null;
_caseInsensitiveTable = null;
@@ -253,7 +259,7 @@ namespace System.Resources {
{
IResourceReader copyOfReader = Reader;
if (copyOfReader == null || _resCache == null)
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet"));
+ throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet);
return copyOfReader.GetEnumerator();
}
@@ -262,13 +268,13 @@ namespace System.Resources {
public override String GetString(String key)
{
Object o = GetObject(key, false, true);
- return (String) o;
+ return (String)o;
}
public override String GetString(String key, bool ignoreCase)
{
Object o = GetObject(key, ignoreCase, true);
- return (String) o;
+ return (String)o;
}
public override Object GetObject(String key)
@@ -283,34 +289,39 @@ namespace System.Resources {
private Object GetObject(String key, bool ignoreCase, bool isString)
{
- if (key==null)
+ if (key == null)
throw new ArgumentNullException(nameof(key));
if (Reader == null || _resCache == null)
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet"));
+ throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet);
Contract.EndContractBlock();
Object value = null;
ResourceLocator resLocation;
-
- lock(Reader) {
+
+ lock (Reader)
+ {
if (Reader == null)
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_ResourceSet"));
-
- if (_defaultReader != null) {
+ throw new ObjectDisposedException(null, SR.ObjectDisposed_ResourceSet);
+
+ if (_defaultReader != null)
+ {
BCLDebug.Log("RESMGRFILEFORMAT", "Going down fast path in RuntimeResourceSet::GetObject");
-
+
// Find the offset within the data section
int dataPos = -1;
- if (_resCache.TryGetValue(key, out resLocation)) {
+ if (_resCache.TryGetValue(key, out resLocation))
+ {
value = resLocation.Value;
dataPos = resLocation.DataPosition;
}
-
- if (dataPos == -1 && value == null) {
+
+ if (dataPos == -1 && value == null)
+ {
dataPos = _defaultReader.FindPosForResource(key);
}
- if (dataPos != -1 && value == null) {
+ if (dataPos != -1 && value == null)
+ {
Debug.Assert(dataPos >= 0, "data section offset cannot be negative!");
// Normally calling LoadString or LoadObject requires
// taking a lock. Note that in this case, we took a
@@ -318,28 +329,32 @@ namespace System.Resources {
// sufficient since we never pass this ResourceReader
// to anyone else.
ResourceTypeCode typeCode;
- if (isString) {
+ if (isString)
+ {
value = _defaultReader.LoadString(dataPos);
typeCode = ResourceTypeCode.String;
}
- else {
+ else
+ {
value = _defaultReader.LoadObject(dataPos, out typeCode);
}
resLocation = new ResourceLocator(dataPos, (ResourceLocator.CanCache(typeCode)) ? value : null);
- lock(_resCache) {
+ lock (_resCache)
+ {
_resCache[key] = resLocation;
}
}
-
- if (value != null || !ignoreCase) {
+
+ if (value != null || !ignoreCase)
+ {
#if LOOSELY_LINKED_RESOURCE_REFERENCE
if (Assembly != null && (value is LooselyLinkedResourceReference)) {
LooselyLinkedResourceReference assRef = (LooselyLinkedResourceReference) value;
value = assRef.Resolve(Assembly);
}
#endif // LOOSELY_LINKED_RESOURCE_REFERENCE
-
+
return value; // may be null
}
} // if (_defaultReader != null)
@@ -347,20 +362,24 @@ namespace System.Resources {
// At this point, we either don't have our default resource reader
// or we haven't found the particular resource we're looking for
// and may have to search for it in a case-insensitive way.
- if (!_haveReadFromReader) {
+ if (!_haveReadFromReader)
+ {
// If necessary, init our case insensitive hash table.
- if (ignoreCase && _caseInsensitiveTable == null) {
+ if (ignoreCase && _caseInsensitiveTable == null)
+ {
_caseInsensitiveTable = new Dictionary<String, ResourceLocator>(StringComparer.OrdinalIgnoreCase);
}
#if _DEBUG
- BCLDebug.Perf(!ignoreCase, "Using case-insensitive lookups is bad perf-wise. Consider capitalizing "+key+" correctly in your source");
+ BCLDebug.Perf(!ignoreCase, "Using case-insensitive lookups is bad perf-wise. Consider capitalizing " + key + " correctly in your source");
#endif
- if (_defaultReader == null) {
+ if (_defaultReader == null)
+ {
IDictionaryEnumerator en = Reader.GetEnumerator();
- while (en.MoveNext()) {
+ while (en.MoveNext())
+ {
DictionaryEntry entry = en.Entry;
- String readKey = (String) entry.Key;
+ String readKey = (String)entry.Key;
ResourceLocator resLoc = new ResourceLocator(-1, entry.Value);
_resCache.Add(readKey, resLoc);
if (ignoreCase)
@@ -371,12 +390,14 @@ namespace System.Resources {
if (!ignoreCase)
Reader.Close();
}
- else {
+ else
+ {
Debug.Assert(ignoreCase, "This should only happen for case-insensitive lookups");
ResourceReader.ResourceEnumerator en = _defaultReader.GetEnumeratorInternal();
- while (en.MoveNext()) {
+ while (en.MoveNext())
+ {
// Note: Always ask for the resource key before the data position.
- String currentKey = (String) en.Key;
+ String currentKey = (String)en.Key;
int dataPos = en.DataPosition;
ResourceLocator resLoc = new ResourceLocator(dataPos, null);
_caseInsensitiveTable.Add(currentKey, resLoc);
@@ -387,19 +408,23 @@ namespace System.Resources {
Object obj = null;
bool found = false;
bool keyInWrongCase = false;
- if (_defaultReader != null) {
- if (_resCache.TryGetValue(key, out resLocation)) {
+ if (_defaultReader != null)
+ {
+ if (_resCache.TryGetValue(key, out resLocation))
+ {
found = true;
- obj = ResolveResourceLocator(resLocation, key, _resCache, keyInWrongCase);
+ obj = ResolveResourceLocator(resLocation, key, _resCache, keyInWrongCase);
}
}
- if (!found && ignoreCase) {
- if (_caseInsensitiveTable.TryGetValue(key, out resLocation)) {
+ if (!found && ignoreCase)
+ {
+ if (_caseInsensitiveTable.TryGetValue(key, out resLocation))
+ {
found = true;
keyInWrongCase = true;
obj = ResolveResourceLocator(resLocation, key, _resCache, keyInWrongCase);
}
- }
+ }
return obj;
} // lock(Reader)
}
@@ -412,12 +437,15 @@ namespace System.Resources {
// We need to explicitly resolve loosely linked manifest
// resources, and we need to resolve ResourceLocators with null objects.
Object value = resLocation.Value;
- if (value == null) {
+ if (value == null)
+ {
ResourceTypeCode typeCode;
- lock(Reader) {
+ lock (Reader)
+ {
value = _defaultReader.LoadObject(resLocation.DataPosition, out typeCode);
}
- if (!keyInWrongCase && ResourceLocator.CanCache(typeCode)) {
+ if (!keyInWrongCase && ResourceLocator.CanCache(typeCode))
+ {
resLocation.Value = value;
copyOfCache[key] = resLocation;
}
diff --git a/src/mscorlib/src/System/Resources/SatelliteContractVersionAttribute.cs b/src/mscorlib/src/System/Resources/SatelliteContractVersionAttribute.cs
deleted file mode 100644
index 86e972efdd..0000000000
--- a/src/mscorlib/src/System/Resources/SatelliteContractVersionAttribute.cs
+++ /dev/null
@@ -1,38 +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.
-
-/*============================================================
-**
-**
-**
-**
-**
-** Purpose: Specifies which version of a satellite assembly
-** the ResourceManager should ask for.
-**
-**
-===========================================================*/
-
-namespace System.Resources {
- using System;
- using System.Diagnostics.Contracts;
-
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=false)]
- public sealed class SatelliteContractVersionAttribute : Attribute
- {
- private String _version;
-
- public SatelliteContractVersionAttribute(String version)
- {
- if (version == null)
- throw new ArgumentNullException(nameof(version));
- Contract.EndContractBlock();
- _version = version;
- }
-
- public String Version {
- get { return _version; }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Resources/UltimateResourceFallbackLocation.cs b/src/mscorlib/src/System/Resources/UltimateResourceFallbackLocation.cs
deleted file mode 100644
index aa4069a366..0000000000
--- a/src/mscorlib/src/System/Resources/UltimateResourceFallbackLocation.cs
+++ /dev/null
@@ -1,28 +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.
-
-/*============================================================
-**
-**
-**
-**
-**
-**
-** Purpose: Tells the ResourceManager where to find the
-** ultimate fallback resources for your assembly.
-**
-**
-===========================================================*/
-
-using System;
-
-namespace System.Resources {
-
-[Serializable]
- public enum UltimateResourceFallbackLocation
- {
- MainAssembly,
- Satellite
- }
-}
diff --git a/src/mscorlib/src/System/Resources/__FastResourceComparer.cs b/src/mscorlib/src/System/Resources/__FastResourceComparer.cs
index e0911fae1d..8bce02abc3 100644
--- a/src/mscorlib/src/System/Resources/__FastResourceComparer.cs
+++ b/src/mscorlib/src/System/Resources/__FastResourceComparer.cs
@@ -13,13 +13,15 @@
**
**
===========================================================*/
-namespace System.Resources {
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System.Resources
+{
internal sealed class FastResourceComparer : IComparer, IEqualityComparer, IComparer<String>, IEqualityComparer<String>
{
internal static readonly FastResourceComparer Default = new FastResourceComparer();
@@ -27,7 +29,7 @@ namespace System.Resources {
// Implements IHashCodeProvider too, due to Hashtable requirements.
public int GetHashCode(Object key)
{
- String s = (String) key;
+ String s = (String)key;
return FastResourceComparer.HashFunction(s);
}
@@ -45,9 +47,9 @@ namespace System.Resources {
// others can read & write our .resources files. Additionally, we
// have a copy of it in InternalResGen as well.
uint hash = 5381;
- for(int i=0; i<key.Length; i++)
+ for (int i = 0; i < key.Length; i++)
hash = ((hash << 5) + hash) ^ key[i];
- return (int) hash;
+ return (int)hash;
}
// Compares Strings quickly in a case-sensitive way
@@ -74,7 +76,7 @@ namespace System.Resources {
if (a == b) return true;
String sa = (String)a;
String sb = (String)b;
- return String.Equals(sa,sb);
+ return String.Equals(sa, sb);
}
// Input is one string to compare with, and a byte[] containing chars in
@@ -93,10 +95,11 @@ namespace System.Resources {
numChars = bCharLength;
if (bCharLength == 0) // Can't use fixed on a 0-element array.
return (a.Length == 0) ? 0 : -1;
- fixed(byte* pb = bytes) {
-
- byte *pChar = pb;
- while (i < numChars && r == 0) {
+ fixed (byte* pb = bytes)
+ {
+ byte* pChar = pb;
+ while (i < numChars && r == 0)
+ {
// little endian format
int b = pChar[0] | pChar[1] << 8;
r = a[i++] - b;
@@ -126,9 +129,10 @@ namespace System.Resources {
int numChars = byteLen >> 1;
if (numChars > b.Length)
numChars = b.Length;
- while(i < numChars && r == 0) {
+ while (i < numChars && r == 0)
+ {
// Must compare character by character, not byte by byte.
- char aCh = (char) (*a++ | (*a++ << 8));
+ char aCh = (char)(*a++ | (*a++ << 8));
r = aCh - b[i++];
}
if (r != 0) return r;
diff --git a/src/mscorlib/src/System/Resources/__HResults.cs b/src/mscorlib/src/System/Resources/__HResults.cs
index c1546edc63..5817161665 100644
--- a/src/mscorlib/src/System/Resources/__HResults.cs
+++ b/src/mscorlib/src/System/Resources/__HResults.cs
@@ -11,7 +11,8 @@
//
//===========================================================================*/
#if FEATURE_APPX
-namespace System.Resources {
+namespace System.Resources
+{
using System;
// Only static data no need to serialize
internal static class __HResults
diff --git a/src/mscorlib/src/System/RtType.cs b/src/mscorlib/src/System/RtType.cs
index a24ee679d3..ef3ba29787 100644
--- a/src/mscorlib/src/System/RtType.cs
+++ b/src/mscorlib/src/System/RtType.cs
@@ -19,7 +19,7 @@ using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.Runtime;
-using System.Runtime.Serialization;
+using System.Runtime.Serialization;
using System.Runtime.CompilerServices;
using System.Security;
using System.Text;
@@ -32,7 +32,7 @@ using MdToken = System.Reflection.MetadataToken;
using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
-namespace System
+namespace System
{
// this is a work around to get the concept of a calli. It's not as fast but it would be interesting to
// see how it compares to the current implementation.
@@ -43,18 +43,18 @@ namespace System
// Keep this in sync with FormatFlags defined in typestring.h
internal enum TypeNameFormatFlags
{
- FormatBasic = 0x00000000, // Not a bitmask, simply the tersest flag settings possible
- FormatNamespace = 0x00000001, // Include namespace and/or enclosing class names in type names
- FormatFullInst = 0x00000002, // Include namespace and assembly in generic types (regardless of other flag settings)
- FormatAssembly = 0x00000004, // Include assembly display name in type names
- FormatSignature = 0x00000008, // Include signature in method names
- FormatNoVersion = 0x00000010, // Suppress version and culture information in all assembly names
+ FormatBasic = 0x00000000, // Not a bitmask, simply the tersest flag settings possible
+ FormatNamespace = 0x00000001, // Include namespace and/or enclosing class names in type names
+ FormatFullInst = 0x00000002, // Include namespace and assembly in generic types (regardless of other flag settings)
+ FormatAssembly = 0x00000004, // Include assembly display name in type names
+ FormatSignature = 0x00000008, // Include signature in method names
+ FormatNoVersion = 0x00000010, // Suppress version and culture information in all assembly names
#if _DEBUG
- FormatDebug = 0x00000020, // For debug printing of types only
+ FormatDebug = 0x00000020, // For debug printing of types only
#endif
FormatAngleBrackets = 0x00000040, // Whether generic types are C<T> or C[T]
- FormatStubInfo = 0x00000080, // Include stub info like {unbox-stub}
- FormatGenericParam = 0x00000100, // Use !name and !!name for generic type and method parameters
+ FormatStubInfo = 0x00000080, // Include stub info like {unbox-stub}
+ FormatGenericParam = 0x00000100, // Use !name and !!name for generic type and method parameters
// If we want to be able to distinguish between overloads whose parameter types have the same name but come from different assemblies,
// we can add FormatAssembly | FormatNoVersion to FormatSerialization. But we are omitting it because it is not a useful scenario
@@ -73,7 +73,7 @@ namespace System
}
[Serializable]
- internal class RuntimeType :
+ internal class RuntimeType :
System.Reflection.TypeInfo, ISerializable, ICloneable
{
#region Definitions
@@ -89,10 +89,10 @@ namespace System
// Helper to build lists of MemberInfos. Special cased to avoid allocations for lists of one element.
private struct ListBuilder<T> where T : class
{
- T[] _items;
- T _item;
- int _count;
- int _capacity;
+ private T[] _items;
+ private T _item;
+ private int _count;
+ private int _capacity;
public ListBuilder(int capacity)
{
@@ -114,7 +114,7 @@ namespace System
public T[] ToArray()
{
if (_count == 0)
- return EmptyArray<T>.Value;
+ return Array.Empty<T>();
if (_count == 1)
return new T[1] { _item };
@@ -151,7 +151,7 @@ namespace System
{
_item = item;
}
- else
+ else
{
if (_count == 1)
{
@@ -198,9 +198,9 @@ namespace System
public unsafe Filter(byte* pUtf8Name, int cUtf8Name, MemberListType listType)
{
- this.m_name = new Utf8String((void*) pUtf8Name, cUtf8Name);
- this.m_listType = listType;
- this.m_nameHash = 0;
+ m_name = new Utf8String((void*)pUtf8Name, cUtf8Name);
+ m_listType = listType;
+ m_nameHash = 0;
if (RequiresStringComparison())
{
@@ -208,10 +208,10 @@ namespace System
}
}
- public bool Match(Utf8String name)
+ public bool Match(Utf8String name)
{
bool retVal = true;
-
+
if (m_listType == MemberListType.CaseSensitive)
retVal = m_name.Equals(name);
else if (m_listType == MemberListType.CaseInsensitive)
@@ -283,16 +283,16 @@ namespace System
BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
switch (cacheType)
{
- case CacheType.Method:
- list = (T[])(object)new RuntimeMethodInfo[1] {
+ case CacheType.Method:
+ list = (T[])(object)new RuntimeMethodInfo[1] {
new RuntimeMethodInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags, null)
};
- break;
- case CacheType.Constructor:
- list = (T[])(object)new RuntimeConstructorInfo[1] {
- new RuntimeConstructorInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags)
+ break;
+ case CacheType.Constructor:
+ list = (T[])(object)new RuntimeConstructorInfo[1] {
+ new RuntimeConstructorInfo(method, declaringType, m_runtimeTypeCache, methodAttributes, bindingFlags)
};
- break;
+ break;
}
Insert(ref list, null, MemberListType.HandleToInfo);
@@ -313,7 +313,7 @@ namespace System
BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
- T[] list = (T[])(object)new RuntimeFieldInfo[1] {
+ T[] list = (T[])(object)new RuntimeFieldInfo[1] {
new RtFieldInfo(field, ReflectedType, m_runtimeTypeCache, bindingFlags)
};
@@ -408,8 +408,8 @@ namespace System
bool lockTaken = false;
RuntimeHelpers.PrepareConstrainedRegions();
- try
- {
+ try
+ {
Monitor.Enter(this, ref lockTaken);
switch (listType)
@@ -453,7 +453,7 @@ namespace System
int memberCount = m_allMembers.Length;
while (memberCount > 0)
{
- if (m_allMembers[memberCount-1] != null)
+ if (m_allMembers[memberCount - 1] != null)
break;
memberCount--;
}
@@ -618,7 +618,7 @@ namespace System
else
{
#region IsClass or GenericParameter
- while(RuntimeTypeHandle.IsGenericVariable(declaringType))
+ while (RuntimeTypeHandle.IsGenericVariable(declaringType))
declaringType = declaringType.GetBaseType();
bool* overrides = stackalloc bool[RuntimeTypeHandle.GetNumVirtuals(declaringType)];
@@ -730,12 +730,12 @@ namespace System
{
if (ReflectedType.IsGenericParameter)
{
- return EmptyArray<RuntimeConstructorInfo>.Value;
+ return Array.Empty<RuntimeConstructorInfo>();
}
ListBuilder<RuntimeConstructorInfo> list = new ListBuilder<RuntimeConstructorInfo>();
- RuntimeType declaringType= ReflectedType;
+ RuntimeType declaringType = ReflectedType;
foreach (RuntimeMethodHandleInternal methodHandle in RuntimeTypeHandle.GetIntroducedMethods(declaringType))
{
@@ -785,14 +785,14 @@ namespace System
private unsafe RuntimeFieldInfo[] PopulateFields(Filter filter)
{
ListBuilder<RuntimeFieldInfo> list = new ListBuilder<RuntimeFieldInfo>();
-
+
RuntimeType declaringType = ReflectedType;
#region Populate all static, instance and literal fields
- while(RuntimeTypeHandle.IsGenericVariable(declaringType))
+ while (RuntimeTypeHandle.IsGenericVariable(declaringType))
declaringType = declaringType.GetBaseType();
- while(declaringType != null)
+ while (declaringType != null)
{
PopulateRtFields(filter, declaringType, ref list);
@@ -806,13 +806,13 @@ namespace System
if (ReflectedType.IsGenericParameter)
{
Type[] interfaces = ReflectedType.BaseType.GetInterfaces();
-
+
for (int i = 0; i < interfaces.Length; i++)
{
// Populate literal fields defined on any of the interfaces implemented by the declaring type
PopulateLiteralFields(filter, (RuntimeType)interfaces[i], ref list);
PopulateRtFields(filter, (RuntimeType)interfaces[i], ref list);
- }
+ }
}
else
{
@@ -825,7 +825,7 @@ namespace System
// Populate literal fields defined on any of the interfaces implemented by the declaring type
PopulateLiteralFields(filter, (RuntimeType)interfaces[i], ref list);
PopulateRtFields(filter, (RuntimeType)interfaces[i], ref list);
- }
+ }
}
}
#endregion
@@ -837,10 +837,10 @@ namespace System
{
IntPtr* pResult = stackalloc IntPtr[64];
int count = 64;
-
+
if (!RuntimeTypeHandle.GetFields(declaringType, pResult, &count))
{
- fixed(IntPtr* pBigResult = new IntPtr[count])
+ fixed (IntPtr* pBigResult = new IntPtr[count])
{
RuntimeTypeHandle.GetFields(declaringType, pBigResult, &count);
PopulateRtFields(filter, pBigResult, count, declaringType, ref list);
@@ -851,7 +851,7 @@ namespace System
PopulateRtFields(filter, pResult, count, declaringType, ref list);
}
}
-
+
private unsafe void PopulateRtFields(Filter filter,
IntPtr* ppFieldHandles, int count, RuntimeType declaringType, ref ListBuilder<RuntimeFieldInfo> list)
{
@@ -861,7 +861,7 @@ namespace System
bool needsStaticFieldForGeneric = RuntimeTypeHandle.HasInstantiation(declaringType) && !RuntimeTypeHandle.ContainsGenericVariables(declaringType);
bool isInherited = declaringType != ReflectedType;
- for(int i = 0; i < count; i ++)
+ for (int i = 0; i < count; i++)
{
RuntimeFieldHandleInternal runtimeFieldHandle = new RuntimeFieldHandleInternal(ppFieldHandles[i]);
@@ -892,13 +892,13 @@ namespace System
bool isPublic = fieldAccess == FieldAttributes.Public;
bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0;
BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
- #endregion
-
+ #endregion
+
// correct the FieldDesc if needed
if (needsStaticFieldForGeneric && isStatic)
runtimeFieldHandle = RuntimeFieldHandle.GetStaticFieldForGenericType(runtimeFieldHandle, declaringType);
- RuntimeFieldInfo runtimeFieldInfo =
+ RuntimeFieldInfo runtimeFieldInfo =
new RtFieldInfo(runtimeFieldHandle, declaringType, m_runtimeTypeCache, bindingFlags);
list.Add(runtimeFieldInfo);
@@ -955,8 +955,8 @@ namespace System
bool isPublic = fieldAccess == FieldAttributes.Public;
bool isStatic = (fieldAttributes & FieldAttributes.Static) != 0;
BindingFlags bindingFlags = RuntimeType.FilterPreCalculate(isPublic, isInherited, isStatic);
- #endregion
-
+ #endregion
+
RuntimeFieldInfo runtimeFieldInfo =
new MdFieldInfo(tkField, fieldAttributes, declaringType.GetTypeHandleInternal(), m_runtimeTypeCache, bindingFlags);
@@ -983,7 +983,6 @@ namespace System
}
}
}
-
}
private RuntimeType[] PopulateInterfaces(Filter filter)
@@ -1007,20 +1006,20 @@ namespace System
if (!filter.Match(RuntimeTypeHandle.GetUtf8Name(interfaceType)))
continue;
}
-
+
Debug.Assert(interfaceType.IsInterface);
list.Add(interfaceType);
}
}
- if (ReflectedType.IsSzArray)
+ if (ReflectedType.IsSZArray)
{
RuntimeType arrayType = (RuntimeType)ReflectedType.GetElementType();
-
+
if (!arrayType.IsPointer)
{
AddSpecialInterface(ref list, filter, (RuntimeType)typeof(IList<>).MakeGenericType(arrayType), true);
-
+
// To avoid adding a duplicate IEnumerable<T>, we don't add the sub interfaces of IReadOnlyList.
// Instead, we add IReadOnlyCollection<T> separately.
AddSpecialInterface(ref list, filter, (RuntimeType)typeof(IReadOnlyList<>).MakeGenericType(arrayType), false);
@@ -1088,7 +1087,7 @@ namespace System
// For example, TypeDescs do not have metadata tokens
if (MdToken.IsNullToken(tkEnclosingType))
- return EmptyArray<RuntimeType>.Value;
+ return Array.Empty<RuntimeType>();
ListBuilder<RuntimeType> list = new ListBuilder<RuntimeType>();
@@ -1106,7 +1105,7 @@ namespace System
{
nestedType = ModuleHandle.ResolveTypeHandleInternal(moduleHandle, tkNestedClasses[i], null, null);
}
- catch(System.TypeLoadException)
+ catch (System.TypeLoadException)
{
// In a reflection emit scenario, we may have a token for a class which
// has not been baked and hence cannot be loaded.
@@ -1124,7 +1123,7 @@ namespace System
return list.ToArray();
}
-
+
private unsafe RuntimeEventInfo[] PopulateEvents(Filter filter)
{
Contract.Requires(ReflectedType != null);
@@ -1138,11 +1137,11 @@ namespace System
if (!RuntimeTypeHandle.IsInterface(declaringType))
{
- while(RuntimeTypeHandle.IsGenericVariable(declaringType))
+ while (RuntimeTypeHandle.IsGenericVariable(declaringType))
declaringType = declaringType.GetBaseType();
// Populate associates off of the class hierarchy
- while(declaringType != null)
+ while (declaringType != null)
{
PopulateEvents(filter, declaringType, csEventInfos, ref list);
declaringType = RuntimeTypeHandle.GetBaseType(declaringType);
@@ -1231,7 +1230,7 @@ namespace System
if (!RuntimeTypeHandle.IsInterface(declaringType))
{
- while(RuntimeTypeHandle.IsGenericVariable(declaringType))
+ while (RuntimeTypeHandle.IsGenericVariable(declaringType))
declaringType = declaringType.GetBaseType();
// Do not create the dictionary if we are filtering the properties by name already
@@ -1258,8 +1257,8 @@ namespace System
}
private unsafe void PopulateProperties(
- Filter filter,
- RuntimeType declaringType,
+ Filter filter,
+ RuntimeType declaringType,
Dictionary<String, List<RuntimePropertyInfo>> csPropertyInfos,
bool[] usedSlots,
ref ListBuilder<RuntimePropertyInfo> list)
@@ -1408,7 +1407,7 @@ namespace System
{
T[] list = null;
- switch(listType)
+ switch (listType)
{
case MemberListType.CaseSensitive:
list = m_csMemberInfos[name];
@@ -1480,21 +1479,21 @@ namespace System
#region Private Members
private string ConstructName(ref string name, TypeNameFormatFlags formatFlags)
{
- if (name == null)
+ if (name == null)
{
name = new RuntimeTypeHandle(m_runtimeType).ConstructName(formatFlags);
}
return name;
}
- private T[] GetMemberList<T>(ref MemberInfoCache<T> m_cache, MemberListType listType, string name, CacheType cacheType)
+ private T[] GetMemberList<T>(ref MemberInfoCache<T> m_cache, MemberListType listType, string name, CacheType cacheType)
where T : MemberInfo
{
MemberInfoCache<T> existingCache = GetMemberCache<T>(ref m_cache);
return existingCache.GetMemberList(listType, name, cacheType);
}
- private MemberInfoCache<T> GetMemberCache<T>(ref MemberInfoCache<T> m_cache)
+ private MemberInfoCache<T> GetMemberCache<T>(ref MemberInfoCache<T> m_cache)
where T : MemberInfo
{
MemberInfoCache<T> existingCache = m_cache;
@@ -1524,7 +1523,7 @@ namespace System
get { return m_bIsDomainInitialized; }
set { m_bIsDomainInitialized = value; }
}
-
+
internal string GetName(TypeNameKind kind)
{
switch (kind)
@@ -1565,11 +1564,11 @@ namespace System
{
// @Optimization - Use ConstructName to populate m_namespace
if (m_namespace == null)
- {
+ {
Type type = m_runtimeType;
type = type.GetRootElementType();
-
- while (type.IsNested)
+
+ while (type.IsNested)
type = type.DeclaringType;
m_namespace = RuntimeTypeHandle.GetMetadataImport((RuntimeType)type).GetNamespace(type.MetadataToken).ToString();
@@ -1581,11 +1580,11 @@ namespace System
internal TypeCode TypeCode
{
get { return m_typeCode; }
- set { m_typeCode = value; }
+ set { m_typeCode = value; }
}
internal unsafe RuntimeType GetEnclosingType()
- {
+ {
if (m_enclosingType == null)
{
// Use void as a marker of null enclosing type
@@ -1602,9 +1601,9 @@ namespace System
return m_runtimeType;
}
- internal bool IsGlobal
- {
- get { return m_isGlobal; }
+ internal bool IsGlobal
+ {
+ get { return m_isGlobal; }
}
internal void InvalidateCachedNestedType()
@@ -1698,55 +1697,55 @@ namespace System
return rmi;
}
- internal RuntimeMethodInfo[] GetMethodList(MemberListType listType, string name)
- {
+ internal RuntimeMethodInfo[] GetMethodList(MemberListType listType, string name)
+ {
return GetMemberList<RuntimeMethodInfo>(ref m_methodInfoCache, listType, name, CacheType.Method);
}
internal RuntimeConstructorInfo[] GetConstructorList(MemberListType listType, string name)
- {
+ {
return GetMemberList<RuntimeConstructorInfo>(ref m_constructorInfoCache, listType, name, CacheType.Constructor);
}
internal RuntimePropertyInfo[] GetPropertyList(MemberListType listType, string name)
- {
+ {
return GetMemberList<RuntimePropertyInfo>(ref m_propertyInfoCache, listType, name, CacheType.Property);
}
internal RuntimeEventInfo[] GetEventList(MemberListType listType, string name)
- {
+ {
return GetMemberList<RuntimeEventInfo>(ref m_eventInfoCache, listType, name, CacheType.Event);
}
internal RuntimeFieldInfo[] GetFieldList(MemberListType listType, string name)
- {
+ {
return GetMemberList<RuntimeFieldInfo>(ref m_fieldInfoCache, listType, name, CacheType.Field);
}
internal RuntimeType[] GetInterfaceList(MemberListType listType, string name)
- {
+ {
return GetMemberList<RuntimeType>(ref m_interfaceCache, listType, name, CacheType.Interface);
}
internal RuntimeType[] GetNestedTypeList(MemberListType listType, string name)
- {
+ {
return GetMemberList<RuntimeType>(ref m_nestedClassesCache, listType, name, CacheType.NestedType);
}
- internal MethodBase GetMethod(RuntimeType declaringType, RuntimeMethodHandleInternal method)
- {
+ internal MethodBase GetMethod(RuntimeType declaringType, RuntimeMethodHandleInternal method)
+ {
GetMemberCache<RuntimeMethodInfo>(ref m_methodInfoCache);
return m_methodInfoCache.AddMethod(declaringType, method, CacheType.Method);
}
internal MethodBase GetConstructor(RuntimeType declaringType, RuntimeMethodHandleInternal constructor)
- {
+ {
GetMemberCache<RuntimeConstructorInfo>(ref m_constructorInfoCache);
return m_constructorInfoCache.AddMethod(declaringType, constructor, CacheType.Constructor);
}
internal FieldInfo GetField(RuntimeFieldHandleInternal field)
- {
+ {
GetMemberCache<RuntimeFieldInfo>(ref m_fieldInfoCache);
return m_fieldInfoCache.AddField(field);
}
@@ -1833,7 +1832,7 @@ namespace System
if (!loaderAssuredCompatible)
throw new ArgumentException(String.Format(
- CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"),
+ CultureInfo.CurrentCulture, SR.Argument_ResolveMethodHandle,
reflectedType.ToString(), declaredType.ToString()));
}
// Action<in string> is assignable from, but not a subclass of Action<in object>.
@@ -1861,7 +1860,7 @@ namespace System
{
// ignoring instantiation is the ReflectedType is not a subtype of the DeclaringType
throw new ArgumentException(String.Format(
- CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"),
+ CultureInfo.CurrentCulture, SR.Argument_ResolveMethodHandle,
reflectedType.ToString(), declaredType.ToString()));
}
@@ -1883,7 +1882,7 @@ namespace System
{
// declaredType is not Array, not generic, and not assignable from reflectedType
throw new ArgumentException(String.Format(
- CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveMethodHandle"),
+ CultureInfo.CurrentCulture, SR.Argument_ResolveMethodHandle,
reflectedType.ToString(), declaredType.ToString()));
}
}
@@ -1938,7 +1937,7 @@ namespace System
RuntimeFieldHandleInternal fieldHandle = field.Value;
// verify the type/method relationship
- if (reflectedType == null)
+ if (reflectedType == null)
{
reflectedType = RuntimeFieldHandle.GetApproxDeclaringType(fieldHandle);
}
@@ -1951,7 +1950,7 @@ namespace System
!RuntimeTypeHandle.CompareCanonicalHandles(declaredType, reflectedType))
{
throw new ArgumentException(String.Format(
- CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_ResolveFieldHandle"),
+ CultureInfo.CurrentCulture, SR.Argument_ResolveFieldHandle,
reflectedType.ToString(),
declaredType.ToString()));
}
@@ -1967,7 +1966,7 @@ namespace System
private unsafe static PropertyInfo GetPropertyInfo(RuntimeType reflectedType, int tkProperty)
{
RuntimePropertyInfo property = null;
- RuntimePropertyInfo[] candidates =
+ RuntimePropertyInfo[] candidates =
reflectedType.Cache.GetPropertyList(MemberListType.All, null);
for (int i = 0; i < candidates.Length; i++)
@@ -1985,7 +1984,7 @@ namespace System
{
if (type.IsPointer || type.IsByRef || type == typeof(void))
throw new ArgumentException(
- Environment.GetResourceString("Argument_NeverValidGenericArgument", type.ToString()));
+ SR.Format(SR.Argument_NeverValidGenericArgument, type.ToString()));
}
@@ -1995,29 +1994,29 @@ namespace System
throw new ArgumentNullException();
Contract.EndContractBlock();
- for(int i = 0; i < genericArguments.Length; i++)
- {
+ for (int i = 0; i < genericArguments.Length; i++)
+ {
if (genericArguments[i] == null)
throw new ArgumentNullException();
-
+
ThrowIfTypeNeverValidGenericArgument(genericArguments[i]);
}
if (genericArguments.Length != genericParamters.Length)
throw new ArgumentException(
- Environment.GetResourceString("Argument_NotEnoughGenArguments", genericArguments.Length, genericParamters.Length));
+ SR.Format(SR.Argument_NotEnoughGenArguments, genericArguments.Length, genericParamters.Length));
}
-
+
internal static void ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
{
RuntimeType[] typeContext = null;
RuntimeType[] methodContext = null;
RuntimeType[] genericParamters = null;
-
+
if (definition is Type)
{
RuntimeType genericTypeDefinition = (RuntimeType)definition;
- genericParamters = genericTypeDefinition.GetGenericArgumentsInternal();
+ genericParamters = genericTypeDefinition.GetGenericArgumentsInternal();
typeContext = genericArguments;
}
else
@@ -2025,14 +2024,14 @@ namespace System
RuntimeMethodInfo genericMethodDefinition = (RuntimeMethodInfo)definition;
genericParamters = genericMethodDefinition.GetGenericArgumentsInternal();
methodContext = genericArguments;
-
+
RuntimeType declaringType = (RuntimeType)genericMethodDefinition.DeclaringType;
if (declaringType != null)
{
typeContext = declaringType.GetTypeHandleInternal().GetInstantiationInternal();
}
}
-
+
for (int i = 0; i < genericArguments.Length; i++)
{
Type genericArgument = genericArguments[i];
@@ -2042,8 +2041,7 @@ namespace System
typeContext, methodContext, genericArgument.GetTypeHandleInternal().GetTypeChecked()))
{
throw new ArgumentException(
- Environment.GetResourceString("Argument_GenConstraintViolation",
- i.ToString(CultureInfo.CurrentCulture), genericArgument.ToString(), definition.ToString(), genericParameter.ToString()), e);
+ SR.Format(SR.Argument_GenConstraintViolation, i.ToString(CultureInfo.CurrentCulture), genericArgument.ToString(), definition.ToString(), genericParameter.ToString()), e);
}
}
}
@@ -2058,7 +2056,7 @@ namespace System
// Get namespace
int nsDelimiter = fullname.LastIndexOf(".", StringComparison.Ordinal);
- if (nsDelimiter != -1 )
+ if (nsDelimiter != -1)
{
ns = fullname.Substring(0, nsDelimiter);
int nameLength = fullname.Length - ns.Length - 1;
@@ -2072,7 +2070,6 @@ namespace System
{
name = fullname;
}
-
}
#endregion
@@ -2081,10 +2078,10 @@ namespace System
{
BindingFlags bindingFlags = isPublic ? BindingFlags.Public : BindingFlags.NonPublic;
- if (isInherited)
- {
+ if (isInherited)
+ {
// We arrange things so the DeclaredOnly flag means "include inherited members"
- bindingFlags |= BindingFlags.DeclaredOnly;
+ bindingFlags |= BindingFlags.DeclaredOnly;
if (isStatic)
{
@@ -2112,7 +2109,7 @@ namespace System
// Calculate prefixLookup, ignoreCase, and listType for use by GetXXXCandidates
private static void FilterHelper(
- BindingFlags bindingFlags, ref string name, bool allowPrefixLookup, out bool prefixLookup,
+ BindingFlags bindingFlags, ref string name, bool allowPrefixLookup, out bool prefixLookup,
out bool ignoreCase, out MemberListType listType)
{
prefixLookup = false;
@@ -2169,7 +2166,7 @@ namespace System
{
if (!memberInfo.Name.StartsWith(name, StringComparison.Ordinal))
return false;
- }
+ }
return true;
}
@@ -2206,7 +2203,7 @@ namespace System
#endregion
#region Filter by Static & Instance
- if (memberInfo.MemberType != MemberTypes.TypeInfo &&
+ if (memberInfo.MemberType != MemberTypes.TypeInfo &&
memberInfo.MemberType != MemberTypes.NestedType)
{
if (isStatic)
@@ -2237,8 +2234,8 @@ namespace System
// @Asymmetry - Internal, inherited, instance, non-protected, non-virtual, non-abstract members returned
// iff BindingFlags !DeclaredOnly, Instance and Public are present except for fields
if (((bindingFlags & BindingFlags.DeclaredOnly) == 0) && // DeclaredOnly not present
- isInherited && // Is inherited Member
-
+ isInherited && // Is inherited Member
+
(isNonProtectedInternal) && // Is non-protected internal member
((bindingFlags & BindingFlags.NonPublic) != 0) && // BindingFlag.NonPublic present
@@ -2310,11 +2307,11 @@ namespace System
#region Check CallingConvention
if ((callConv & CallingConventions.Any) == 0)
{
- if ((callConv & CallingConventions.VarArgs) != 0 &&
+ if ((callConv & CallingConventions.VarArgs) != 0 &&
(methodBase.CallingConvention & CallingConventions.VarArgs) == 0)
return false;
- if ((callConv & CallingConventions.Standard) != 0 &&
+ if ((callConv & CallingConventions.Standard) != 0 &&
(methodBase.CallingConvention & CallingConventions.Standard) == 0)
return false;
}
@@ -2330,14 +2327,14 @@ namespace System
#region Invoke Member, Get\Set & Create Instance specific case
// If the number of supplied arguments differs than the number in the signature AND
// we are not filtering for a dynamic call -- InvokeMethod or CreateInstance -- filter out the method.
- if ((bindingFlags &
+ if ((bindingFlags &
(BindingFlags.InvokeMethod | BindingFlags.CreateInstance | BindingFlags.GetProperty | BindingFlags.SetProperty)) == 0)
return false;
-
+
bool testForParamArray = false;
bool excessSuppliedArguments = argumentTypes.Length > parameterInfos.Length;
- if (excessSuppliedArguments)
+ if (excessSuppliedArguments)
{ // more supplied arguments than parameters, additional arguments could be vararg
#region Varargs
// If method is not vararg, additional arguments can not be passed as vararg
@@ -2345,7 +2342,7 @@ namespace System
{
testForParamArray = true;
}
- else
+ else
{
// If Binding flags did not include varargs we would have filtered this vararg method.
// This Invariant established during callConv check.
@@ -2353,7 +2350,7 @@ namespace System
}
#endregion
}
- else
+ else
{// fewer supplied arguments than parameters, missing arguments could be optional
#region OptionalParamBinding
if ((bindingFlags & BindingFlags.OptionalParamBinding) == 0)
@@ -2375,7 +2372,7 @@ namespace System
#region ParamArray
if (testForParamArray)
{
- if (parameterInfos.Length == 0)
+ if (parameterInfos.Length == 0)
return false;
// The last argument of the signature could be a param array.
@@ -2408,7 +2405,7 @@ namespace System
// in this if statement? That's just InvokeMethod with a constructor, right?
if ((bindingFlags & (BindingFlags.InvokeMethod)) == 0)
{
- for(int i = 0; i < parameterInfos.Length; i ++)
+ for (int i = 0; i < parameterInfos.Length; i++)
{
// a null argument type implies a null arg which is always a perfect match
if ((object)argumentTypes[i] != null && !Object.ReferenceEquals(parameterInfos[i].ParameterType, argumentTypes[i]))
@@ -2420,7 +2417,7 @@ namespace System
}
}
#endregion
-
+
return true;
}
@@ -2433,65 +2430,6 @@ namespace System
private IntPtr m_cache;
internal IntPtr m_handle;
-#if FEATURE_APPX
- private INVOCATION_FLAGS m_invocationFlags;
-
- internal bool IsNonW8PFrameworkAPI()
- {
- if (IsGenericParameter)
- return false;
-
- if (HasElementType)
- return ((RuntimeType)GetElementType()).IsNonW8PFrameworkAPI();
-
- if (IsSimpleTypeNonW8PFrameworkAPI())
- return true;
-
- if (IsGenericType && !IsGenericTypeDefinition)
- {
- foreach (Type t in GetGenericArguments())
- {
- if (((RuntimeType)t).IsNonW8PFrameworkAPI())
- return true;
- }
- }
-
- return false;
- }
-
- private bool IsSimpleTypeNonW8PFrameworkAPI()
- {
- RuntimeAssembly rtAssembly = GetRuntimeAssembly();
- if (rtAssembly.IsFrameworkAssembly())
- {
- int ctorToken = rtAssembly.InvocableAttributeCtorToken;
- if (System.Reflection.MetadataToken.IsNullToken(ctorToken) ||
- !CustomAttribute.IsAttributeDefined(GetRuntimeModule(), MetadataToken, ctorToken))
- return true;
- }
-
- return false;
- }
-
- internal INVOCATION_FLAGS InvocationFlags
- {
- get
- {
- if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0)
- {
- INVOCATION_FLAGS invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_UNKNOWN;
-
- if (AppDomain.ProfileAPICheck && IsNonW8PFrameworkAPI())
- invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API;
-
- m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED;
- }
-
- return m_invocationFlags;
- }
- }
-#endif // FEATURE_APPX
-
internal static readonly RuntimeType ValueType = (RuntimeType)typeof(System.ValueType);
internal static readonly RuntimeType EnumType = (RuntimeType)typeof(System.Enum);
@@ -2525,16 +2463,16 @@ namespace System
IntPtr gcHandle = Interlocked.CompareExchange(ref m_cache, newgcHandle, (IntPtr)0);
// Leak the handle if the type is collectible. It will be reclaimed when
// the type goes away.
- if (!gcHandle.IsNull() && !IsCollectible())
+ if (!gcHandle.IsNull() && !IsCollectible())
GCHandle.InternalFree(newgcHandle);
}
RuntimeTypeCache cache = GCHandle.InternalGet(m_cache) as RuntimeTypeCache;
- if (cache == null)
+ if (cache == null)
{
cache = new RuntimeTypeCache(this);
RuntimeTypeCache existingCache = GCHandle.InternalCompareExchange(m_cache, cache, null, false) as RuntimeTypeCache;
- if (existingCache != null)
+ if (existingCache != null)
cache = existingCache;
}
@@ -2543,24 +2481,6 @@ namespace System
}
}
- internal bool IsSpecialSerializableType()
- {
- RuntimeType rt = this;
- do
- {
- // In all sane cases we only need to compare the direct level base type with
- // System.Enum and System.MulticastDelegate. However, a generic argument can
- // have a base type constraint that is Delegate or even a real delegate type.
- // Let's maintain compatibility and return true for them.
- if (rt == RuntimeType.DelegateType || rt == RuntimeType.EnumType)
- return true;
-
- rt = rt.GetBaseType();
- } while (rt != null);
-
- return false;
- }
-
private string GetDefaultMemberName()
{
return Cache.GetDefaultMemberName();
@@ -2595,7 +2515,7 @@ namespace System
}
private ListBuilder<ConstructorInfo> GetConstructorCandidates(
- string name, BindingFlags bindingAttr, CallingConventions callConv,
+ string name, BindingFlags bindingAttr, CallingConventions callConv,
Type[] types, bool allowPrefixLookup)
{
bool prefixLookup, ignoreCase;
@@ -2610,7 +2530,7 @@ namespace System
RuntimeConstructorInfo constructorInfo = cache[i];
if (FilterApplyConstructorInfo(constructorInfo, bindingAttr, callConv, types) &&
(!prefixLookup || RuntimeType.FilterApplyPrefixLookup(constructorInfo, name, ignoreCase)))
- {
+ {
candidates.Add(constructorInfo);
}
}
@@ -2621,7 +2541,7 @@ namespace System
private ListBuilder<PropertyInfo> GetPropertyCandidates(
String name, BindingFlags bindingAttr, Type[] types, bool allowPrefixLookup)
- {
+ {
bool prefixLookup, ignoreCase;
MemberListType listType;
RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
@@ -2683,7 +2603,7 @@ namespace System
for (int i = 0; i < cache.Length; i++)
{
RuntimeFieldInfo fieldInfo = cache[i];
- if ((bindingAttr & fieldInfo.BindingFlags) == fieldInfo.BindingFlags &&
+ if ((bindingAttr & fieldInfo.BindingFlags) == fieldInfo.BindingFlags &&
(!prefixLookup || FilterApplyPrefixLookup(fieldInfo, name, ignoreCase)))
{
candidates.Add(fieldInfo);
@@ -2699,7 +2619,7 @@ namespace System
bindingAttr &= ~BindingFlags.Static;
string name, ns;
MemberListType listType;
- SplitName(fullname, out name, out ns);
+ SplitName(fullname, out name, out ns);
RuntimeType.FilterHelper(bindingAttr, ref name, allowPrefixLookup, out prefixLookup, out ignoreCase, out listType);
RuntimeType[] cache = Cache.GetNestedTypeList(listType, name);
@@ -2746,12 +2666,12 @@ namespace System
public override Type[] GetInterfaces()
{
- RuntimeType[] candidates = this.Cache.GetInterfaceList(MemberListType.All, null);
- Type[] interfaces = new Type[candidates.Length];
- for (int i = 0; i < candidates.Length; i++)
- JitHelpers.UnsafeSetArrayElement(interfaces, i, candidates[i]);
+ RuntimeType[] candidates = this.Cache.GetInterfaceList(MemberListType.All, null);
+ Type[] interfaces = new Type[candidates.Length];
+ for (int i = 0; i < candidates.Length; i++)
+ JitHelpers.UnsafeSetArrayElement(interfaces, i, candidates[i]);
- return interfaces;
+ return interfaces;
}
public override Type[] GetNestedTypes(BindingFlags bindingAttr)
@@ -2792,8 +2712,8 @@ namespace System
public override InterfaceMapping GetInterfaceMap(Type ifaceType)
{
if (IsGenericParameter)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
-
+ throw new InvalidOperationException(SR.Arg_GenericParameter);
+
if ((object)ifaceType == null)
throw new ArgumentNullException(nameof(ifaceType));
Contract.EndContractBlock();
@@ -2801,7 +2721,7 @@ namespace System
RuntimeType ifaceRtType = ifaceType as RuntimeType;
if (ifaceRtType == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(ifaceType));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(ifaceType));
RuntimeTypeHandle ifaceRtTypeHandle = ifaceRtType.GetTypeHandleInternal();
@@ -2811,8 +2731,8 @@ namespace System
// SZArrays implement the methods on IList`1, IEnumerable`1, and ICollection`1 with
// SZArrayHelper and some runtime magic. We don't have accurate interface maps for them.
- if (IsSzArray && ifaceType.IsGenericType)
- throw new ArgumentException(Environment.GetResourceString("Argument_ArrayGetInterfaceMap"));
+ if (IsSZArray && ifaceType.IsGenericType)
+ throw new ArgumentException(SR.Argument_ArrayGetInterfaceMap);
int ifaceInstanceMethodCount = RuntimeTypeHandle.GetNumVirtuals(ifaceRtType);
@@ -2851,15 +2771,15 @@ namespace System
#region Find XXXInfo
protected override MethodInfo GetMethodImpl(
- String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv,
- Type[] types, ParameterModifier[] modifiers)
- {
+ String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConv,
+ Type[] types, ParameterModifier[] modifiers)
+ {
ListBuilder<MethodInfo> candidates = GetMethodCandidates(name, bindingAttr, callConv, types, false);
- if (candidates.Count == 0)
+ if (candidates.Count == 0)
return null;
- if (types == null || types.Length == 0)
+ if (types == null || types.Length == 0)
{
MethodInfo firstCandidate = candidates[0];
@@ -2867,44 +2787,44 @@ namespace System
{
return firstCandidate;
}
- else if (types == null)
- {
+ else if (types == null)
+ {
for (int j = 1; j < candidates.Count; j++)
{
MethodInfo methodInfo = candidates[j];
- if (!System.DefaultBinder.CompareMethodSigAndName(methodInfo, firstCandidate))
+ if (!System.DefaultBinder.CompareMethodSig(methodInfo, firstCandidate))
{
- throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
+ throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
}
}
// All the methods have the exact same name and sig so return the most derived one.
return System.DefaultBinder.FindMostDerivedNewSlotMeth(candidates.ToArray(), candidates.Count) as MethodInfo;
}
- }
+ }
- if (binder == null)
+ if (binder == null)
binder = DefaultBinder;
- return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as MethodInfo;
+ return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as MethodInfo;
}
protected override ConstructorInfo GetConstructorImpl(
- BindingFlags bindingAttr, Binder binder, CallingConventions callConvention,
- Type[] types, ParameterModifier[] modifiers)
+ BindingFlags bindingAttr, Binder binder, CallingConventions callConvention,
+ Type[] types, ParameterModifier[] modifiers)
{
ListBuilder<ConstructorInfo> candidates = GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, types, false);
if (candidates.Count == 0)
return null;
-
- if (types.Length == 0 && candidates.Count == 1)
+
+ if (types.Length == 0 && candidates.Count == 1)
{
ConstructorInfo firstCandidate = candidates[0];
ParameterInfo[] parameters = firstCandidate.GetParametersNoCopy();
- if (parameters == null || parameters.Length == 0)
+ if (parameters == null || parameters.Length == 0)
{
return firstCandidate;
}
@@ -2921,7 +2841,7 @@ namespace System
protected override PropertyInfo GetPropertyImpl(
- String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
+ String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
{
if (name == null) throw new ArgumentNullException();
Contract.EndContractBlock();
@@ -2930,11 +2850,11 @@ namespace System
if (candidates.Count == 0)
return null;
-
- if (types == null || types.Length == 0)
+
+ if (types == null || types.Length == 0)
{
// no arguments
- if (candidates.Count == 1)
+ if (candidates.Count == 1)
{
PropertyInfo firstCandidate = candidates[0];
@@ -2943,25 +2863,25 @@ namespace System
return firstCandidate;
}
- else
+ else
{
if ((object)returnType == null)
// if we are here we have no args or property type to select over and we have more than one property with that name
- throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
+ throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
}
}
-
+
if ((bindingAttr & BindingFlags.ExactBinding) != 0)
return System.DefaultBinder.ExactPropertyBinding(candidates.ToArray(), returnType, types, modifiers);
if (binder == null)
binder = DefaultBinder;
-
+
return binder.SelectProperty(bindingAttr, candidates.ToArray(), returnType, types, modifiers);
}
- public override EventInfo GetEvent(String name, BindingFlags bindingAttr)
+ public override EventInfo GetEvent(String name, BindingFlags bindingAttr)
{
if (name == null) throw new ArgumentNullException();
Contract.EndContractBlock();
@@ -2969,7 +2889,7 @@ namespace System
bool ignoreCase;
MemberListType listType;
RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
-
+
RuntimeEventInfo[] cache = Cache.GetEventList(listType, name);
EventInfo match = null;
@@ -2981,7 +2901,7 @@ namespace System
if ((bindingAttr & eventInfo.BindingFlags) == eventInfo.BindingFlags)
{
if (match != null)
- throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
+ throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
match = eventInfo;
}
@@ -2990,7 +2910,7 @@ namespace System
return match;
}
- public override FieldInfo GetField(String name, BindingFlags bindingAttr)
+ public override FieldInfo GetField(String name, BindingFlags bindingAttr)
{
if (name == null) throw new ArgumentNullException();
Contract.EndContractBlock();
@@ -3013,30 +2933,30 @@ namespace System
if (match != null)
{
if (Object.ReferenceEquals(fieldInfo.DeclaringType, match.DeclaringType))
- throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
+ throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
if ((match.DeclaringType.IsInterface == true) && (fieldInfo.DeclaringType.IsInterface == true))
multipleStaticFieldMatches = true;
}
-
+
if (match == null || fieldInfo.DeclaringType.IsSubclassOf(match.DeclaringType) || match.DeclaringType.IsInterface)
match = fieldInfo;
}
}
if (multipleStaticFieldMatches && match.DeclaringType.IsInterface)
- throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
+ throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
return match;
}
- public override Type GetInterface(String fullname, bool ignoreCase)
+ public override Type GetInterface(String fullname, bool ignoreCase)
{
if (fullname == null) throw new ArgumentNullException();
Contract.EndContractBlock();
BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.NonPublic;
-
+
bindingAttr &= ~BindingFlags.Static;
if (ignoreCase)
@@ -3044,10 +2964,10 @@ namespace System
string name, ns;
MemberListType listType;
- SplitName(fullname, out name, out ns);
+ SplitName(fullname, out name, out ns);
RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
- RuntimeType[] cache = Cache.GetInterfaceList(listType, name);
+ RuntimeType[] cache = Cache.GetInterfaceList(listType, name);
RuntimeType match = null;
@@ -3057,7 +2977,7 @@ namespace System
if (RuntimeType.FilterApplyType(iface, bindingAttr, name, false, ns))
{
if (match != null)
- throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
+ throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
match = iface;
}
@@ -3066,7 +2986,7 @@ namespace System
return match;
}
- public override Type GetNestedType(String fullname, BindingFlags bindingAttr)
+ public override Type GetNestedType(String fullname, BindingFlags bindingAttr)
{
if (fullname == null) throw new ArgumentNullException();
Contract.EndContractBlock();
@@ -3075,7 +2995,7 @@ namespace System
bindingAttr &= ~BindingFlags.Static;
string name, ns;
MemberListType listType;
- SplitName(fullname, out name, out ns);
+ SplitName(fullname, out name, out ns);
RuntimeType.FilterHelper(bindingAttr, ref name, out ignoreCase, out listType);
RuntimeType[] cache = Cache.GetNestedTypeList(listType, name);
@@ -3088,7 +3008,7 @@ namespace System
if (RuntimeType.FilterApplyType(nestedType, bindingAttr, name, false, ns))
{
if (match != null)
- throw new AmbiguousMatchException(Environment.GetResourceString("Arg_AmbiguousMatchException"));
+ throw new AmbiguousMatchException(SR.Arg_AmbiguousMatchException);
match = nestedType;
}
@@ -3097,7 +3017,7 @@ namespace System
return match;
}
- public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
+ public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
{
if (name == null) throw new ArgumentNullException();
Contract.EndContractBlock();
@@ -3106,7 +3026,7 @@ namespace System
ListBuilder<ConstructorInfo> constructors = new ListBuilder<ConstructorInfo>();
ListBuilder<PropertyInfo> properties = new ListBuilder<PropertyInfo>();
ListBuilder<EventInfo> events = new ListBuilder<EventInfo>();
- ListBuilder<FieldInfo> fields = new ListBuilder<FieldInfo>();
+ ListBuilder<FieldInfo> fields = new ListBuilder<FieldInfo>();
ListBuilder<Type> nestedTypes = new ListBuilder<Type>();
int totalCount = 0;
@@ -3195,9 +3115,9 @@ namespace System
return RuntimeTypeHandle.GetModule(this);
}
- public override Assembly Assembly
+ public override Assembly Assembly
{
- get
+ get
{
return GetRuntimeAssembly();
}
@@ -3208,9 +3128,9 @@ namespace System
return RuntimeTypeHandle.GetAssembly(this);
}
- public override RuntimeTypeHandle TypeHandle
+ public override RuntimeTypeHandle TypeHandle
{
- get
+ get
{
return new RuntimeTypeHandle(this);
}
@@ -3226,7 +3146,7 @@ namespace System
return RuntimeTypeHandle.IsCollectible(GetTypeHandleInternal());
}
- protected override TypeCode GetTypeCodeImpl()
+ protected override TypeCode GetTypeCodeImpl()
{
TypeCode typeCode = Cache.TypeCode;
@@ -3234,7 +3154,7 @@ namespace System
return typeCode;
CorElementType corElementType = RuntimeTypeHandle.GetCorElementType(this);
- switch (corElementType)
+ switch (corElementType)
{
case CorElementType.Boolean:
typeCode = TypeCode.Boolean; break;
@@ -3270,7 +3190,7 @@ namespace System
else if (this.IsEnum)
typeCode = Type.GetTypeCode(Enum.GetUnderlyingType(this));
else
- typeCode = TypeCode.Object;
+ typeCode = TypeCode.Object;
break;
default:
if (this == Convert.ConvertTypes[(int)TypeCode.DBNull])
@@ -3292,7 +3212,7 @@ namespace System
get
{
if (!IsGenericParameter)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
+ throw new InvalidOperationException(SR.Arg_NotGenericParameter);
Contract.EndContractBlock();
IRuntimeMethodInfo declaringMethod = RuntimeTypeHandle.GetDeclaringMethod(this);
@@ -3312,7 +3232,7 @@ namespace System
}
[Pure]
- public override bool IsSubclassOf(Type type)
+ public override bool IsSubclassOf(Type type)
{
if ((object)type == null)
throw new ArgumentNullException(nameof(type));
@@ -3334,14 +3254,15 @@ namespace System
// pretty much everything is a subclass of object, even interfaces
// notice that interfaces are really odd because they do not have a BaseType
// yet IsSubclassOf(typeof(object)) returns true
- if (rtType == RuntimeType.ObjectType && rtType != this)
+ if (rtType == RuntimeType.ObjectType && rtType != this)
return true;
return false;
}
- public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){
- if(typeInfo==null) return false;
+ public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo)
+ {
+ if (typeInfo == null) return false;
return IsAssignableFrom(typeInfo.AsType());
}
@@ -3388,9 +3309,9 @@ namespace System
return false;
}
- public override Type BaseType
+ public override Type BaseType
{
- get
+ get
{
return GetBaseType();
}
@@ -3441,9 +3362,9 @@ namespace System
return RuntimeTypeHandle.GetBaseType(this);
}
- public override Type UnderlyingSystemType
+ public override Type UnderlyingSystemType
{
- get
+ get
{
return this;
}
@@ -3451,34 +3372,34 @@ namespace System
#endregion
#region Name
- public override String FullName
+ public override String FullName
{
- get
+ get
{
return GetCachedName(TypeNameKind.FullName);
}
}
- public override String AssemblyQualifiedName
+ public override String AssemblyQualifiedName
{
- get
+ get
{
string fullname = FullName;
// FullName is null if this type contains generic parameters but is not a generic type definition.
if (fullname == null)
return null;
-
- return Assembly.CreateQualifiedName(this.Assembly.FullName, fullname);
+
+ return Assembly.CreateQualifiedName(this.Assembly.FullName, fullname);
}
}
- public override String Namespace
+ public override String Namespace
{
- get
+ get
{
string ns = Cache.GetNameSpace();
-
+
if (ns == null || ns.Length == 0)
return null;
@@ -3488,45 +3409,45 @@ namespace System
#endregion
#region Attributes
- protected override TypeAttributes GetAttributeFlagsImpl()
+ protected override TypeAttributes GetAttributeFlagsImpl()
{
return RuntimeTypeHandle.GetAttributes(this);
}
- public override Guid GUID
+ public override Guid GUID
{
- get
+ get
{
- Guid result = new Guid ();
+ Guid result = new Guid();
GetGUID(ref result);
return result;
}
}
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void GetGUID(ref Guid result);
- protected override bool IsContextfulImpl()
+ protected override bool IsContextfulImpl()
{
return false;
}
- protected override bool IsByRefImpl()
+ protected override bool IsByRefImpl()
{
return RuntimeTypeHandle.IsByRef(this);
}
- protected override bool IsPrimitiveImpl()
+ protected override bool IsPrimitiveImpl()
{
return RuntimeTypeHandle.IsPrimitive(this);
}
- protected override bool IsPointerImpl()
+ protected override bool IsPointerImpl()
{
return RuntimeTypeHandle.IsPointer(this);
}
- protected override bool IsCOMObjectImpl()
+ protected override bool IsCOMObjectImpl()
{
return RuntimeTypeHandle.IsComObject(this, false);
}
@@ -3560,13 +3481,13 @@ namespace System
// We need to return true for generic parameters with the ValueType constraint.
// So we cannot use the faster RuntimeTypeHandle.IsValueType because it returns
// false for all generic parameters.
- if (this == typeof(ValueType) || this == typeof(Enum))
+ if (this == typeof(ValueType) || this == typeof(Enum))
return false;
return IsSubclassOf(typeof(ValueType));
}
- protected override bool HasElementTypeImpl()
+ protected override bool HasElementTypeImpl()
{
return RuntimeTypeHandle.HasElementType(this);
}
@@ -3576,7 +3497,7 @@ namespace System
get
{
if (!IsGenericParameter)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
+ throw new InvalidOperationException(SR.Arg_NotGenericParameter);
Contract.EndContractBlock();
GenericParameterAttributes attributes;
@@ -3587,9 +3508,9 @@ namespace System
}
}
- public override bool IsSecurityCritical
+ public override bool IsSecurityCritical
{
- get { return new RuntimeTypeHandle(this).IsSecurityCritical(); }
+ get { return new RuntimeTypeHandle(this).IsSecurityCritical(); }
}
public override bool IsSecuritySafeCritical
{
@@ -3602,28 +3523,28 @@ namespace System
#endregion
#region Arrays
- internal override bool IsSzArray
+ public sealed override bool IsSZArray
{
- get
+ get
{
- return RuntimeTypeHandle.IsSzArray(this);
+ return RuntimeTypeHandle.IsSZArray(this);
}
}
- protected override bool IsArrayImpl()
+ protected override bool IsArrayImpl()
{
return RuntimeTypeHandle.IsArray(this);
}
- public override int GetArrayRank()
+ public override int GetArrayRank()
{
if (!IsArrayImpl())
- throw new ArgumentException(Environment.GetResourceString("Argument_HasToBeArrayClass"));
+ throw new ArgumentException(SR.Argument_HasToBeArrayClass);
return RuntimeTypeHandle.GetArrayRank(this);
}
- public override Type GetElementType()
+ public override Type GetElementType()
{
return RuntimeTypeHandle.GetElementType(this);
}
@@ -3633,7 +3554,7 @@ namespace System
public override string[] GetEnumNames()
{
if (!IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
Contract.EndContractBlock();
String[] ret = Enum.InternalGetNames(this);
@@ -3649,7 +3570,7 @@ namespace System
public override Array GetEnumValues()
{
if (!IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
Contract.EndContractBlock();
// Get all of the values
@@ -3670,7 +3591,7 @@ namespace System
public override Type GetEnumUnderlyingType()
{
if (!IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
+ throw new ArgumentException(SR.Arg_MustBeEnum, "enumType");
Contract.EndContractBlock();
return Enum.InternalGetUnderlyingType(this);
@@ -3689,7 +3610,7 @@ namespace System
if (valueType.IsEnum)
{
if (!valueType.IsEquivalentTo(this))
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumAndObjectMustBeSameType", valueType.ToString(), this.ToString()));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, valueType.ToString(), this.ToString()));
valueType = (RuntimeType)valueType.GetEnumUnderlyingType();
}
@@ -3710,7 +3631,7 @@ namespace System
{
RuntimeType underlyingType = Enum.InternalGetUnderlyingType(this);
if (underlyingType != valueType)
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), underlyingType.ToString()));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumUnderlyingTypeAndObjectMustBeSameType, valueType.ToString(), underlyingType.ToString()));
ulong[] ulValues = Enum.InternalGetValues(this);
ulong ulValue = Enum.ToUInt64(value);
@@ -3719,7 +3640,7 @@ namespace System
}
else
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
+ throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
}
}
@@ -3732,7 +3653,7 @@ namespace System
Type valueType = value.GetType();
if (!(valueType.IsEnum || IsIntegerType(valueType)))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), nameof(value));
+ throw new ArgumentException(SR.Arg_MustBeEnumBaseTypeOrEnum, nameof(value));
ulong ulValue = Enum.ToUInt64(value);
@@ -3746,12 +3667,12 @@ namespace System
return GetRootElementType().GetTypeHandleInternal().GetInstantiationInternal();
}
- public override Type[] GetGenericArguments()
+ public override Type[] GetGenericArguments()
{
Type[] types = GetRootElementType().GetTypeHandleInternal().GetInstantiationPublic();
if (types == null)
- types = EmptyArray<Type>.Value;
+ types = Array.Empty<Type>();
return types;
}
@@ -3766,12 +3687,12 @@ namespace System
if (!IsGenericTypeDefinition)
throw new InvalidOperationException(
- Environment.GetResourceString("Arg_NotGenericTypeDefinition", this));
+ SR.Format(SR.Arg_NotGenericTypeDefinition, this));
if (GetGenericArguments().Length != instantiation.Length)
- throw new ArgumentException(Environment.GetResourceString("Argument_GenericArgsCount"), nameof(instantiation));
+ throw new ArgumentException(SR.Argument_GenericArgsCount, nameof(instantiation));
- for (int i = 0; i < instantiation.Length; i ++)
+ for (int i = 0; i < instantiation.Length; i++)
{
Type instantiationElem = instantiation[i];
if (instantiationElem == null)
@@ -3796,7 +3717,7 @@ namespace System
SanityCheckGenericArguments(instantiationRuntimeType, genericParameters);
Type ret = null;
- try
+ try
{
ret = new RuntimeTypeHandle(this).Instantiate(instantiationRuntimeType);
}
@@ -3821,20 +3742,20 @@ namespace System
public override int GenericParameterPosition
{
- get
+ get
{
if (!IsGenericParameter)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
+ throw new InvalidOperationException(SR.Arg_NotGenericParameter);
Contract.EndContractBlock();
-
- return new RuntimeTypeHandle(this).GetGenericVariableIndex();
+
+ return new RuntimeTypeHandle(this).GetGenericVariableIndex();
}
}
- public override Type GetGenericTypeDefinition()
+ public override Type GetGenericTypeDefinition()
{
if (!IsGenericType)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotGenericType"));
+ throw new InvalidOperationException(SR.InvalidOperation_NotGenericType);
Contract.EndContractBlock();
return RuntimeTypeHandle.GetGenericTypeDefinition(this);
@@ -3852,19 +3773,19 @@ namespace System
public override bool ContainsGenericParameters
{
- get { return GetRootElementType().GetTypeHandleInternal().ContainsGenericVariables(); }
+ get { return GetRootElementType().GetTypeHandleInternal().ContainsGenericVariables(); }
}
public override Type[] GetGenericParameterConstraints()
{
if (!IsGenericParameter)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
+ throw new InvalidOperationException(SR.Arg_NotGenericParameter);
Contract.EndContractBlock();
Type[] constraints = new RuntimeTypeHandle(this).GetConstraints();
if (constraints == null)
- constraints = EmptyArray<Type>.Value;
+ constraints = Array.Empty<Type>();
return constraints;
}
@@ -3874,44 +3795,44 @@ namespace System
public override Type MakePointerType() { return new RuntimeTypeHandle(this).MakePointer(); }
public override Type MakeByRefType() { return new RuntimeTypeHandle(this).MakeByRef(); }
public override Type MakeArrayType() { return new RuntimeTypeHandle(this).MakeSZArray(); }
- public override Type MakeArrayType(int rank)
+ public override Type MakeArrayType(int rank)
{
if (rank <= 0)
throw new IndexOutOfRangeException();
Contract.EndContractBlock();
- return new RuntimeTypeHandle(this).MakeArray(rank);
+ return new RuntimeTypeHandle(this).MakeArray(rank);
}
public override StructLayoutAttribute StructLayoutAttribute
{
- get
- {
- return (StructLayoutAttribute)StructLayoutAttribute.GetCustomAttribute(this);
- }
+ get
+ {
+ return (StructLayoutAttribute)StructLayoutAttribute.GetCustomAttribute(this);
+ }
}
#endregion
#region Invoke Member
- private const BindingFlags MemberBindingMask = (BindingFlags)0x000000FF;
- private const BindingFlags InvocationMask = (BindingFlags)0x0000FF00;
- private const BindingFlags BinderNonCreateInstance = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty;
- private const BindingFlags BinderGetSetProperty = BindingFlags.GetProperty | BindingFlags.SetProperty;
- private const BindingFlags BinderSetInvokeProperty = BindingFlags.InvokeMethod | BindingFlags.SetProperty;
- private const BindingFlags BinderGetSetField = BindingFlags.GetField | BindingFlags.SetField;
- private const BindingFlags BinderSetInvokeField = BindingFlags.SetField | BindingFlags.InvokeMethod;
- private const BindingFlags BinderNonFieldGetSet = (BindingFlags)0x00FFF300;
- private const BindingFlags ClassicBindingMask =
- BindingFlags.InvokeMethod | BindingFlags.GetProperty | BindingFlags.SetProperty |
+ private const BindingFlags MemberBindingMask = (BindingFlags)0x000000FF;
+ private const BindingFlags InvocationMask = (BindingFlags)0x0000FF00;
+ private const BindingFlags BinderNonCreateInstance = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty;
+ private const BindingFlags BinderGetSetProperty = BindingFlags.GetProperty | BindingFlags.SetProperty;
+ private const BindingFlags BinderSetInvokeProperty = BindingFlags.InvokeMethod | BindingFlags.SetProperty;
+ private const BindingFlags BinderGetSetField = BindingFlags.GetField | BindingFlags.SetField;
+ private const BindingFlags BinderSetInvokeField = BindingFlags.SetField | BindingFlags.InvokeMethod;
+ private const BindingFlags BinderNonFieldGetSet = (BindingFlags)0x00FFF300;
+ private const BindingFlags ClassicBindingMask =
+ BindingFlags.InvokeMethod | BindingFlags.GetProperty | BindingFlags.SetProperty |
BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty;
private static RuntimeType s_typedRef = (RuntimeType)typeof(TypedReference);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static private extern bool CanValueSpecialCast(RuntimeType valueType, RuntimeType targetType);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- static private extern Object AllocateValueType(RuntimeType type, object value, bool fForceTypeChange);
+ static private extern Object AllocateValueType(RuntimeType type, object value, bool fForceTypeChange);
- internal unsafe Object CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
+ internal unsafe Object CheckValue(Object value, Binder binder, CultureInfo culture, BindingFlags invokeAttr)
{
// this method is used by invocation in reflection to check whether a value can be assigned to type.
if (IsInstanceOfType(value))
@@ -3935,16 +3856,16 @@ namespace System
// if this is a ByRef get the element type and check if it's compatible
bool isByRef = IsByRef;
- if (isByRef)
+ if (isByRef)
{
RuntimeType elementType = RuntimeTypeHandle.GetElementType(this);
- if (elementType.IsInstanceOfType(value) || value == null)
+ if (elementType.IsInstanceOfType(value) || value == null)
{
// need to create an instance of the ByRef if null was provided, but only if primitive, enum or value type
return AllocateValueType(elementType, value, false);
}
}
- else if (value == null)
+ else if (value == null)
return value;
else if (this == s_typedRef)
// everything works for a typedref
@@ -3955,26 +3876,26 @@ namespace System
// - enum treated as underlying type
// - IntPtr and System.Reflection.Pointer to pointer types
bool needsSpecialCast = IsPointer || IsEnum || IsPrimitive;
- if (needsSpecialCast)
+ if (needsSpecialCast)
{
RuntimeType valueType;
Pointer pointer = value as Pointer;
- if (pointer != null)
- valueType = pointer.GetPointerType();
+ if (pointer != null)
+ valueType = (RuntimeType)pointer.GetPointerType();
else
valueType = (RuntimeType)value.GetType();
if (CanValueSpecialCast(valueType, this))
{
- if (pointer != null)
+ if (pointer != null)
return pointer.GetPointerValue();
else
return value;
}
}
-
+
if ((invokeAttr & BindingFlags.ExactBinding) == BindingFlags.ExactBinding)
- throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
+ throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, SR.Arg_ObjObjEx, value.GetType(), this));
return TryChangeType(value, binder, culture, needsSpecialCast);
}
@@ -3982,32 +3903,32 @@ namespace System
// Factored out of CheckValue to reduce code complexity.
private Object TryChangeType(Object value, Binder binder, CultureInfo culture, bool needsSpecialCast)
{
- if (binder != null && binder != Type.DefaultBinder)
+ if (binder != null && binder != Type.DefaultBinder)
{
- value = binder.ChangeType(value, this, culture);
- if (IsInstanceOfType(value))
+ value = binder.ChangeType(value, this, culture);
+ if (IsInstanceOfType(value))
return value;
// if this is a ByRef get the element type and check if it's compatible
- if (IsByRef)
+ if (IsByRef)
{
RuntimeType elementType = RuntimeTypeHandle.GetElementType(this);
- if (elementType.IsInstanceOfType(value) || value == null)
+ if (elementType.IsInstanceOfType(value) || value == null)
return AllocateValueType(elementType, value, false);
}
- else if (value == null)
+ else if (value == null)
return value;
- if (needsSpecialCast)
+ if (needsSpecialCast)
{
RuntimeType valueType;
Pointer pointer = value as Pointer;
- if (pointer != null)
- valueType = pointer.GetPointerType();
+ if (pointer != null)
+ valueType = (RuntimeType)pointer.GetPointerType();
else
valueType = (RuntimeType)value.GetType();
- if (CanValueSpecialCast(valueType, this))
+ if (CanValueSpecialCast(valueType, this))
{
- if (pointer != null)
+ if (pointer != null)
return pointer.GetPointerValue();
else
return value;
@@ -4015,7 +3936,7 @@ namespace System
}
}
- throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_ObjObjEx"), value.GetType(), this));
+ throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, SR.Arg_ObjObjEx, value.GetType(), this));
}
// GetDefaultMembers
@@ -4032,7 +3953,7 @@ namespace System
}
if (members == null)
- members = EmptyArray<MemberInfo>.Value;
+ members = Array.Empty<MemberInfo>();
return members;
}
@@ -4042,24 +3963,24 @@ namespace System
[DebuggerStepThroughAttribute]
[Diagnostics.DebuggerHidden]
public override Object InvokeMember(
- String name, BindingFlags bindingFlags, Binder binder, Object target,
- Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
+ String name, BindingFlags bindingFlags, Binder binder, Object target,
+ Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
{
if (IsGenericParameter)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_GenericParameter"));
+ throw new InvalidOperationException(SR.Arg_GenericParameter);
Contract.EndContractBlock();
-
+
#region Preconditions
if ((bindingFlags & InvocationMask) == 0)
// "Must specify binding flags describing the invoke operation required."
- throw new ArgumentException(Environment.GetResourceString("Arg_NoAccessSpec"),nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_NoAccessSpec, nameof(bindingFlags));
// Provide a default binding mask if none is provided
- if ((bindingFlags & MemberBindingMask) == 0)
+ if ((bindingFlags & MemberBindingMask) == 0)
{
bindingFlags |= BindingFlags.Instance | BindingFlags.Public;
- if ((bindingFlags & BindingFlags.CreateInstance) == 0)
+ if ((bindingFlags & BindingFlags.CreateInstance) == 0)
bindingFlags |= BindingFlags.Static;
}
@@ -4070,13 +3991,13 @@ namespace System
{
if (namedParams.Length > providedArgs.Length)
// "Named parameter array can not be bigger than argument array."
- throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamTooBig"), nameof(namedParams));
+ throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
}
else
{
if (namedParams.Length != 0)
// "Named parameter array can not be bigger than argument array."
- throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamTooBig"), nameof(namedParams));
+ throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams));
}
}
#endregion
@@ -4087,22 +4008,22 @@ namespace System
{
#region Preconditions
if ((bindingFlags & ClassicBindingMask) == 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_COMAccess"), nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_COMAccess, nameof(bindingFlags));
if ((bindingFlags & BindingFlags.GetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_PropSetGet"), nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags));
if ((bindingFlags & BindingFlags.InvokeMethod) != 0 && (bindingFlags & ClassicBindingMask & ~(BindingFlags.GetProperty | BindingFlags.InvokeMethod)) != 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_PropSetInvoke"), nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags));
if ((bindingFlags & BindingFlags.SetProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.SetProperty) != 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_COMPropSetPut, nameof(bindingFlags));
if ((bindingFlags & BindingFlags.PutDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutDispProperty) != 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_COMPropSetPut, nameof(bindingFlags));
if ((bindingFlags & BindingFlags.PutRefDispProperty) != 0 && (bindingFlags & ClassicBindingMask & ~BindingFlags.PutRefDispProperty) != 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_COMPropSetPut"), nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_COMPropSetPut, nameof(bindingFlags));
#endregion
{
@@ -4111,7 +4032,7 @@ namespace System
throw new ArgumentNullException(nameof(name));
bool[] isByRef = modifiers == null ? null : modifiers[0].IsByRefArray;
-
+
// pass LCID_ENGLISH_US if no explicit culture is specified to match the behavior of VB
int lcid = (culture == null ? 0x0409 : culture.LCID);
@@ -4121,28 +4042,28 @@ namespace System
}
#endif // FEATURE_COMINTEROP && FEATURE_USE_LCID
#endregion
-
+
#region Check that any named paramters are not null
if (namedParams != null && Array.IndexOf(namedParams, null) != -1)
// "Named parameter value must not be null."
- throw new ArgumentException(Environment.GetResourceString("Arg_NamedParamNull"),nameof(namedParams));
+ throw new ArgumentException(SR.Arg_NamedParamNull, nameof(namedParams));
#endregion
int argCnt = (providedArgs != null) ? providedArgs.Length : 0;
-
+
#region Get a Binder
if (binder == null)
binder = DefaultBinder;
bool bDefaultBinder = (binder == DefaultBinder);
#endregion
-
+
#region Delegate to Activator.CreateInstance
- if ((bindingFlags & BindingFlags.CreateInstance) != 0)
+ if ((bindingFlags & BindingFlags.CreateInstance) != 0)
{
if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0)
// "Can not specify both CreateInstance and another access type."
- throw new ArgumentException(Environment.GetResourceString("Arg_CreatInstAccess"),nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_CreatInstAccess, nameof(bindingFlags));
return Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture);
}
@@ -4155,12 +4076,12 @@ namespace System
#region Name
if (name == null)
throw new ArgumentNullException(nameof(name));
-
- if (name.Length == 0 || name.Equals(@"[DISPID=0]"))
+
+ if (name.Length == 0 || name.Equals(@"[DISPID=0]"))
{
name = GetDefaultMemberName();
- if (name == null)
+ if (name == null)
{
// in InvokeMember we always pretend there is a default member if none is provided and we make it ToString
name = "ToString";
@@ -4179,31 +4100,31 @@ namespace System
{
if (IsSetField)
// "Can not specify both Get and Set on a field."
- throw new ArgumentException(Environment.GetResourceString("Arg_FldSetGet"),nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_FldSetGet, nameof(bindingFlags));
if ((bindingFlags & BindingFlags.SetProperty) != 0)
// "Can not specify both GetField and SetProperty."
- throw new ArgumentException(Environment.GetResourceString("Arg_FldGetPropSet"),nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_FldGetPropSet, nameof(bindingFlags));
}
else
{
Debug.Assert(IsSetField);
- if (providedArgs == null)
+ if (providedArgs == null)
throw new ArgumentNullException(nameof(providedArgs));
if ((bindingFlags & BindingFlags.GetProperty) != 0)
// "Can not specify both SetField and GetProperty."
- throw new ArgumentException(Environment.GetResourceString("Arg_FldSetPropGet"),nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_FldSetPropGet, nameof(bindingFlags));
if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
// "Can not specify Set on a Field and Invoke on a method."
- throw new ArgumentException(Environment.GetResourceString("Arg_FldSetInvoke"),nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_FldSetInvoke, nameof(bindingFlags));
}
#endregion
-
+
#region Lookup Field
- FieldInfo selFld = null;
+ FieldInfo selFld = null;
FieldInfo[] flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[];
Debug.Assert(flds != null);
@@ -4217,8 +4138,8 @@ namespace System
selFld = binder.BindToField(bindingFlags, flds, IsGetField ? Empty.Value : providedArgs[0], culture);
}
#endregion
-
- if (selFld != null)
+
+ if (selFld != null)
{
#region Invocation on a field
if (selFld.FieldType.IsArray || Object.ReferenceEquals(selFld.FieldType, typeof(System.Array)))
@@ -4226,53 +4147,53 @@ namespace System
#region Invocation of an array Field
int idxCnt;
- if ((bindingFlags & BindingFlags.GetField) != 0)
+ if ((bindingFlags & BindingFlags.GetField) != 0)
{
- idxCnt = argCnt;
+ idxCnt = argCnt;
}
else
{
idxCnt = argCnt - 1;
}
- if (idxCnt > 0)
+ if (idxCnt > 0)
{
// Verify that all of the index values are ints
int[] idx = new int[idxCnt];
- for (int i=0;i<idxCnt;i++)
+ for (int i = 0; i < idxCnt; i++)
{
- try
+ try
{
idx[i] = ((IConvertible)providedArgs[i]).ToInt32(null);
}
catch (InvalidCastException)
{
- throw new ArgumentException(Environment.GetResourceString("Arg_IndexMustBeInt"));
+ throw new ArgumentException(SR.Arg_IndexMustBeInt);
}
}
-
+
// Set or get the value...
- Array a = (Array) selFld.GetValue(target);
-
+ Array a = (Array)selFld.GetValue(target);
+
// Set or get the value in the array
- if ((bindingFlags & BindingFlags.GetField) != 0)
+ if ((bindingFlags & BindingFlags.GetField) != 0)
{
return a.GetValue(idx);
}
- else
+ else
{
- a.SetValue(providedArgs[idxCnt],idx);
+ a.SetValue(providedArgs[idxCnt], idx);
return null;
- }
+ }
}
#endregion
}
-
+
if (IsGetField)
{
#region Get the field value
if (argCnt != 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_FldGetArgErr"),nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_FldGetArgErr, nameof(bindingFlags));
return selFld.GetValue(target);
#endregion
@@ -4281,9 +4202,9 @@ namespace System
{
#region Set the field Value
if (argCnt != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_FldSetArgErr"),nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_FldSetArgErr, nameof(bindingFlags));
- selFld.SetValue(target,providedArgs[0],bindingFlags,binder,culture);
+ selFld.SetValue(target, providedArgs[0], bindingFlags, binder, culture);
return null;
#endregion
@@ -4291,7 +4212,7 @@ namespace System
#endregion
}
- if ((bindingFlags & BinderNonFieldGetSet) == 0)
+ if ((bindingFlags & BinderNonFieldGetSet) == 0)
throw new MissingFieldException(FullName, name);
}
#endregion
@@ -4324,7 +4245,7 @@ namespace System
bool isGetProperty = (bindingFlags & BindingFlags.GetProperty) != 0;
bool isSetProperty = (bindingFlags & BindingFlags.SetProperty) != 0;
- if (isGetProperty || isSetProperty)
+ if (isGetProperty || isSetProperty)
{
#region Preconditions
if (isGetProperty)
@@ -4332,16 +4253,16 @@ namespace System
Debug.Assert(!IsSetField);
if (isSetProperty)
- throw new ArgumentException(Environment.GetResourceString("Arg_PropSetGet"), nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags));
}
else
{
Debug.Assert(isSetProperty);
Debug.Assert(!IsGetField);
-
+
if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_PropSetInvoke"), nameof(bindingFlags));
+ throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags));
}
#endregion
}
@@ -4351,20 +4272,20 @@ namespace System
MethodInfo finalist = null;
#region BindingFlags.InvokeMethod
- if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
+ if ((bindingFlags & BindingFlags.InvokeMethod) != 0)
{
#region Lookup Methods
MethodInfo[] semiFinalists = GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[];
List<MethodInfo> results = null;
-
- for(int i = 0; i < semiFinalists.Length; i ++)
+
+ for (int i = 0; i < semiFinalists.Length; i++)
{
MethodInfo semiFinalist = semiFinalists[i];
Debug.Assert(semiFinalist != null);
if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
continue;
-
+
if (finalist == null)
{
finalist = semiFinalist;
@@ -4380,7 +4301,7 @@ namespace System
results.Add(semiFinalist);
}
}
-
+
if (results != null)
{
Debug.Assert(results.Count > 1);
@@ -4390,17 +4311,17 @@ namespace System
#endregion
}
#endregion
-
+
Debug.Assert(finalists == null || finalist != null);
#region BindingFlags.GetProperty or BindingFlags.SetProperty
- if (finalist == null && isGetProperty || isSetProperty)
+ if (finalist == null && isGetProperty || isSetProperty)
{
#region Lookup Property
- PropertyInfo[] semiFinalists = GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[];
+ PropertyInfo[] semiFinalists = GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[];
List<MethodInfo> results = null;
- for(int i = 0; i < semiFinalists.Length; i ++)
+ for (int i = 0; i < semiFinalists.Length; i++)
{
MethodInfo semiFinalist = null;
@@ -4418,7 +4339,7 @@ namespace System
if (!FilterApplyMethodInfo((RuntimeMethodInfo)semiFinalist, bindingFlags, CallingConventions.Any, new Type[argCnt]))
continue;
-
+
if (finalist == null)
{
finalist = semiFinalist;
@@ -4445,12 +4366,12 @@ namespace System
}
#endregion
- if (finalist != null)
+ if (finalist != null)
{
#region Invoke
- if (finalists == null &&
- argCnt == 0 &&
- finalist.GetParametersNoCopy().Length == 0 &&
+ if (finalists == null &&
+ argCnt == 0 &&
+ finalist.GetParametersNoCopy().Length == 0 &&
(bindingFlags & BindingFlags.OptionalParamBinding) == 0)
{
//if (useCache && argCnt == props[0].GetParameters().Length)
@@ -4458,20 +4379,20 @@ namespace System
return finalist.Invoke(target, bindingFlags, binder, providedArgs, culture);
}
-
+
if (finalists == null)
finalists = new MethodInfo[] { finalist };
if (providedArgs == null)
- providedArgs = EmptyArray<Object>.Value;
+ providedArgs = Array.Empty<Object>();
Object state = null;
-
+
MethodBase invokeMethod = null;
try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs, modifiers, culture, namedParams, out state); }
- catch(MissingMethodException) { }
+ catch (MissingMethodException) { }
if (invokeMethod == null)
throw new MissingMethodException(FullName, name);
@@ -4487,9 +4408,9 @@ namespace System
return result;
#endregion
}
-
+
throw new MissingMethodException(FullName, name);
- }
+ }
#endregion
#endregion
@@ -4502,28 +4423,28 @@ namespace System
return obj == (object)this;
}
- public override int GetHashCode()
+ public override int GetHashCode()
{
return RuntimeHelpers.GetHashCode(this);
}
- public override String ToString()
+ public override String ToString()
{
return GetCachedName(TypeNameKind.ToString);
}
#endregion
#region ICloneable
- public Object Clone()
+ public Object Clone()
{
return this;
}
#endregion
#region ISerializable
- public void GetObjectData(SerializationInfo info, StreamingContext context)
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
{
- if (info==null)
+ if (info == null)
throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
@@ -4545,8 +4466,8 @@ namespace System
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit);
}
@@ -4559,8 +4480,8 @@ namespace System
RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType;
- if (attributeRuntimeType == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),nameof(attributeType));
+ if (attributeRuntimeType == null)
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(attributeType));
return CustomAttribute.IsDefined(this, attributeRuntimeType, inherit);
}
@@ -4572,9 +4493,9 @@ namespace System
#endregion
#region MemberInfo Overrides
- public override String Name
+ public override String Name
{
- get
+ get
{
return GetCachedName(TypeNameKind.Name);
}
@@ -4623,9 +4544,9 @@ namespace System
return Cache.GetName(kind);
}
- public override MemberTypes MemberType
+ public override MemberTypes MemberType
{
- get
+ get
{
if (this.IsPublic || this.IsNotPublic)
return MemberTypes.TypeInfo;
@@ -4634,17 +4555,17 @@ namespace System
}
}
- public override Type DeclaringType
+ public override Type DeclaringType
{
- get
+ get
{
return Cache.GetEnclosingType();
}
}
- public override Type ReflectedType
+ public override Type ReflectedType
{
- get
+ get
{
return DeclaringType;
}
@@ -4652,7 +4573,7 @@ namespace System
public override int MetadataToken
{
- get
+ get
{
return RuntimeTypeHandle.GetToken(this);
}
@@ -4663,31 +4584,31 @@ namespace System
private void CreateInstanceCheckThis()
{
if (this is ReflectionOnlyType)
- throw new ArgumentException(Environment.GetResourceString("Arg_ReflectionOnlyInvoke"));
+ throw new ArgumentException(SR.Arg_ReflectionOnlyInvoke);
if (ContainsGenericParameters)
throw new ArgumentException(
- Environment.GetResourceString("Acc_CreateGenericEx", this));
+ SR.Format(SR.Acc_CreateGenericEx, this));
Contract.EndContractBlock();
Type elementType = this.GetRootElementType();
if (Object.ReferenceEquals(elementType, typeof(ArgIterator)))
- throw new NotSupportedException(Environment.GetResourceString("Acc_CreateArgIterator"));
+ throw new NotSupportedException(SR.Acc_CreateArgIterator);
if (Object.ReferenceEquals(elementType, typeof(void)))
- throw new NotSupportedException(Environment.GetResourceString("Acc_CreateVoid"));
+ throw new NotSupportedException(SR.Acc_CreateVoid);
}
-
+
internal Object CreateInstanceImpl(
BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, ref StackCrawlMark stackMark)
- {
+ {
CreateInstanceCheckThis();
-
+
Object server = null;
if (args == null)
- args = EmptyArray<Object>.Value;
+ args = Array.Empty<Object>();
int argCnt = args.Length;
@@ -4698,9 +4619,9 @@ namespace System
// deal with the __COMObject case first. It is very special because from a reflection point of view it has no ctors
// so a call to GetMemberCons would fail
if (argCnt == 0 && (bindingAttr & BindingFlags.Public) != 0 && (bindingAttr & BindingFlags.Instance) != 0
- && (IsGenericCOMObjectImpl() || IsValueType))
+ && (IsGenericCOMObjectImpl() || IsValueType))
{
- server = CreateInstanceDefaultCtor((bindingAttr & BindingFlags.NonPublic) == 0 , false, true, ref stackMark);
+ server = CreateInstanceDefaultCtor((bindingAttr & BindingFlags.NonPublic) == 0, false, true, ref stackMark);
}
else
{
@@ -4717,7 +4638,7 @@ namespace System
}
}
- for(int i = 0; i < candidates.Length; i ++)
+ for (int i = 0; i < candidates.Length; i++)
{
if (FilterApplyConstructorInfo((RuntimeConstructorInfo)candidates[i], bindingAttr, CallingConventions.Any, argsType))
matches.Add(candidates[i]);
@@ -4730,7 +4651,7 @@ namespace System
if (cons == null)
{
- throw new MissingMethodException(Environment.GetResourceString("MissingConstructor_Name", FullName));
+ throw new MissingMethodException(SR.Format(SR.MissingConstructor_Name, FullName));
}
MethodBase invokeMethod;
@@ -4744,18 +4665,17 @@ namespace System
if (invokeMethod == null)
{
- throw new MissingMethodException(Environment.GetResourceString("MissingConstructor_Name", FullName));
+ throw new MissingMethodException(SR.Format(SR.MissingConstructor_Name, FullName));
}
if (invokeMethod.GetParametersNoCopy().Length == 0)
{
if (args.Length != 0)
{
-
- Debug.Assert((invokeMethod.CallingConvention & CallingConventions.VarArgs) ==
- CallingConventions.VarArgs);
- throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture,
- Environment.GetResourceString("NotSupported_CallToVarArg")));
+ Debug.Assert((invokeMethod.CallingConvention & CallingConventions.VarArgs) ==
+ CallingConventions.VarArgs);
+ throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture,
+ SR.NotSupported_CallToVarArg));
}
// fast path??
@@ -4773,7 +4693,7 @@ namespace System
}
// the cache entry
- class ActivatorCacheEntry
+ private class ActivatorCacheEntry
{
// the type to cache
internal readonly RuntimeType m_type;
@@ -4781,15 +4701,12 @@ namespace System
internal volatile CtorDelegate m_ctor;
internal readonly RuntimeMethodHandleInternal m_hCtorMethodHandle;
internal readonly MethodAttributes m_ctorAttributes;
- // Is a security check needed before this constructor is invoked?
- internal readonly bool m_bNeedSecurityCheck;
// Lazy initialization was performed
internal volatile bool m_bFullyInitialized;
- internal ActivatorCacheEntry(RuntimeType t, RuntimeMethodHandleInternal rmh, bool bNeedSecurityCheck)
+ internal ActivatorCacheEntry(RuntimeType t, RuntimeMethodHandleInternal rmh)
{
m_type = t;
- m_bNeedSecurityCheck = bNeedSecurityCheck;
m_hCtorMethodHandle = rmh;
if (!m_hCtorMethodHandle.IsNullHandle())
m_ctorAttributes = RuntimeMethodHandle.GetAttributes(m_hCtorMethodHandle);
@@ -4797,16 +4714,17 @@ namespace System
}
//ActivatorCache
- class ActivatorCache
+ private class ActivatorCache
{
- const int CACHE_SIZE = 16;
- volatile int hash_counter; //Counter for wrap around
- readonly ActivatorCacheEntry[] cache = new ActivatorCacheEntry[CACHE_SIZE];
+ private const int CACHE_SIZE = 16;
+ private volatile int hash_counter; //Counter for wrap around
+ private readonly ActivatorCacheEntry[] cache = new ActivatorCacheEntry[CACHE_SIZE];
- volatile ConstructorInfo delegateCtorInfo;
+ private volatile ConstructorInfo delegateCtorInfo;
- private void InitializeDelegateCreator() {
- ConstructorInfo ctorInfo = typeof(CtorDelegate).GetConstructor(new Type[] {typeof(Object), typeof(IntPtr)});
+ private void InitializeDelegateCreator()
+ {
+ ConstructorInfo ctorInfo = typeof(CtorDelegate).GetConstructor(new Type[] { typeof(Object), typeof(IntPtr) });
delegateCtorInfo = ctorInfo; // this assignment should be last
}
@@ -4815,7 +4733,7 @@ namespace System
if (!ace.m_type.IsValueType)
{
Debug.Assert(!ace.m_hCtorMethodHandle.IsNullHandle(), "Expected the default ctor method handle for a reference type.");
-
+
if (delegateCtorInfo == null)
InitializeDelegateCreator();
@@ -4829,7 +4747,7 @@ namespace System
internal ActivatorCacheEntry GetEntry(RuntimeType t)
{
int index = hash_counter;
- for(int i = 0; i < CACHE_SIZE; i++)
+ for (int i = 0; i < CACHE_SIZE; i++)
{
ActivatorCacheEntry ace = Volatile.Read(ref cache[index]);
if (ace != null && ace.m_type == t) //check for type match..
@@ -4838,7 +4756,7 @@ namespace System
InitializeCacheEntry(ace);
return ace;
}
- index = (index+1)&(ActivatorCache.CACHE_SIZE-1);
+ index = (index + 1) & (ActivatorCache.CACHE_SIZE - 1);
}
return null;
}
@@ -4846,7 +4764,7 @@ namespace System
internal void SetEntry(ActivatorCacheEntry ace)
{
// fill the the array backwards to hit the most recently filled entries first in GetEntry
- int index = (hash_counter-1)&(ActivatorCache.CACHE_SIZE-1);
+ int index = (hash_counter - 1) & (ActivatorCache.CACHE_SIZE - 1);
hash_counter = index;
Volatile.Write(ref cache[index], ace);
}
@@ -4858,33 +4776,12 @@ namespace System
internal Object CreateInstanceSlow(bool publicOnly, bool skipCheckThis, bool fillCache, ref StackCrawlMark stackMark)
{
RuntimeMethodHandleInternal runtime_ctor = default(RuntimeMethodHandleInternal);
- bool bNeedSecurityCheck = true;
bool bCanBeCached = false;
- bool bSecurityCheckOff = false;
if (!skipCheckThis)
CreateInstanceCheckThis();
- if (!fillCache)
- bSecurityCheckOff = true;
-
-#if FEATURE_APPX
- INVOCATION_FLAGS invocationFlags = InvocationFlags;
- if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0)
- {
- RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
- if (caller != null && !caller.IsSafeForReflection())
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", this.FullName));
-
- // Allow it because the caller is framework code, but don't cache the result
- // because we need to do the stack walk every time this type is instantiated.
- bSecurityCheckOff = false;
- bCanBeCached = false;
- }
-#endif
- bSecurityCheckOff = true; // CoreCLR does not use security at all.
-
- Object instance = RuntimeTypeHandle.CreateInstance(this, publicOnly, bSecurityCheckOff, ref bCanBeCached, ref runtime_ctor, ref bNeedSecurityCheck);
+ Object instance = RuntimeTypeHandle.CreateInstance(this, publicOnly, ref bCanBeCached, ref runtime_ctor);
if (bCanBeCached && fillCache)
{
@@ -4897,7 +4794,7 @@ namespace System
}
// cache the ctor
- ActivatorCacheEntry ace = new ActivatorCacheEntry(this, runtime_ctor, bNeedSecurityCheck);
+ ActivatorCacheEntry ace = new ActivatorCacheEntry(this, runtime_ctor);
activatorCache.SetEntry(ace);
}
@@ -4911,7 +4808,7 @@ namespace System
internal Object CreateInstanceDefaultCtor(bool publicOnly, bool skipCheckThis, bool fillCache, ref StackCrawlMark stackMark)
{
if (GetType() == typeof(ReflectionOnlyType))
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly"));
+ throw new InvalidOperationException(SR.InvalidOperation_NotAllowedInReflectionOnly);
ActivatorCache activatorCache = s_ActivatorCache;
if (activatorCache != null)
@@ -4921,16 +4818,16 @@ namespace System
{
if (publicOnly)
{
- if (ace.m_ctor != null &&
+ if (ace.m_ctor != null &&
(ace.m_ctorAttributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
{
- throw new MissingMethodException(Environment.GetResourceString("Arg_NoDefCTor"));
+ throw new MissingMethodException(SR.Arg_NoDefCTor);
}
}
-
+
// Allocate empty object
Object instance = RuntimeTypeHandle.Allocate(this);
-
+
// if m_ctor is null, this type doesn't have a default ctor
Debug.Assert(ace.m_ctor != null || this.IsValueType);
@@ -5012,19 +4909,18 @@ namespace System
// first place. However given RuntimeType is not public all its methods are protected and require full trust
// to be accessed
[Serializable]
- internal class ReflectionOnlyType : RuntimeType {
-
- private ReflectionOnlyType() {}
+ internal class ReflectionOnlyType : RuntimeType
+ {
+ private ReflectionOnlyType() { }
// always throw
- public override RuntimeTypeHandle TypeHandle
+ public override RuntimeTypeHandle TypeHandle
{
- get
+ get
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly"));
+ throw new InvalidOperationException(SR.InvalidOperation_NotAllowedInReflectionOnly);
}
}
-
}
#region Library
@@ -5162,7 +5058,6 @@ namespace System.Reflection
internal void Insert(K key, V value)
{
-
int hashcode = GetHashCodeHelper(key);
if (hashcode < 0)
hashcode = ~hashcode;
@@ -5208,15 +5103,14 @@ namespace System.Reflection
string sKey = key as string;
// For strings we don't want the key to differ across domains as CerHashtable might be shared.
- if(sKey == null)
+ if (sKey == null)
{
- return key.GetHashCode();
-
+ return key.GetHashCode();
}
else
{
return sKey.GetLegacyNonRandomizedHashCode();
- }
+ }
}
private void Rehash(int newSize)
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs
deleted file mode 100644
index 34e66beade..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs
+++ /dev/null
@@ -1,30 +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.
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-namespace System.Runtime.CompilerServices
-{
- using System;
-
- [AttributeUsage(AttributeTargets.Field)]
- public sealed class AccessedThroughPropertyAttribute : Attribute
- {
- private readonly string propertyName;
-
- public AccessedThroughPropertyAttribute(string propertyName)
- {
- this.propertyName = propertyName;
- }
-
- public string PropertyName
- {
- get
- {
- return propertyName;
- }
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/AssemblySettingAttributes.cs b/src/mscorlib/src/System/Runtime/CompilerServices/AssemblySettingAttributes.cs
deleted file mode 100644
index 5251122629..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/AssemblySettingAttributes.cs
+++ /dev/null
@@ -1,94 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-namespace System.Runtime.CompilerServices
-{
-
- using System;
- using System.Runtime.InteropServices;
-
- /*
- NGenHint is not supported in Whidbey
-
- [Serializable]
- public enum NGenHint
- {
- Default = 0x0000, // No preference specified
-
- Eager = 0x0001, // NGen at install time
- Lazy = 0x0002, // NGen after install time
- Never = 0x0003, // Assembly should not be ngened
- }
- */
-
- [Serializable]
- public enum LoadHint
- {
- Default = 0x0000, // No preference specified
-
- Always = 0x0001, // Dependency is always loaded
- Sometimes = 0x0002, // Dependency is sometimes loaded
- //Never = 0x0003, // Dependency is never loaded
- }
-
- [Serializable]
- [AttributeUsage(AttributeTargets.Assembly)]
- public sealed class DefaultDependencyAttribute : Attribute
- {
- private LoadHint loadHint;
-
- public DefaultDependencyAttribute (
- LoadHint loadHintArgument
- )
- {
- loadHint = loadHintArgument;
- }
-
- public LoadHint LoadHint
- {
- get
- {
- return loadHint;
- }
- }
- }
-
-
-[Serializable]
-[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
- public sealed class DependencyAttribute : Attribute
- {
- private String dependentAssembly;
- private LoadHint loadHint;
-
- public DependencyAttribute (
- String dependentAssemblyArgument,
- LoadHint loadHintArgument
- )
- {
- dependentAssembly = dependentAssemblyArgument;
- loadHint = loadHintArgument;
- }
-
- public String DependentAssembly
- {
- get
- {
- return dependentAssembly;
- }
- }
-
- public LoadHint LoadHint
- {
- get
- {
- return loadHint;
- }
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs b/src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs
index afb0c22778..fc7a7f01a3 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs
@@ -63,7 +63,7 @@ namespace System.Runtime.CompilerServices
// See comment on AsyncMethodBuilderCore.Start
// AsyncMethodBuilderCore.Start(ref stateMachine);
- if (stateMachine == null) throw new ArgumentNullException(nameof(stateMachine));
+ if (stateMachine == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.stateMachine);
Contract.EndContractBlock();
// Run the MoveNext method within a copy-on-write ExecutionContext scope.
@@ -72,7 +72,6 @@ namespace System.Runtime.CompilerServices
Thread currentThread = Thread.CurrentThread;
ExecutionContextSwitcher ecs = default(ExecutionContextSwitcher);
- RuntimeHelpers.PrepareConstrainedRegions();
try
{
ExecutionContext.EstablishCopyOnWriteScope(currentThread, ref ecs);
@@ -240,15 +239,8 @@ namespace System.Runtime.CompilerServices
}
}
- // This property lazily instantiates the Task in a non-thread-safe manner.
- private Task Task
- {
- get
- {
- if (m_task == null) m_task = new Task();
- return m_task;
- }
- }
+ /// <summary>Lazily instantiate the Task in a non-thread-safe manner.</summary>
+ private Task Task => m_task ?? (m_task = new Task());
/// <summary>
/// Gets an object that may be used to uniquely identify this builder to the debugger.
@@ -295,7 +287,7 @@ namespace System.Runtime.CompilerServices
// See comment on AsyncMethodBuilderCore.Start
// AsyncMethodBuilderCore.Start(ref stateMachine);
- if (stateMachine == null) throw new ArgumentNullException(nameof(stateMachine));
+ if (stateMachine == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.stateMachine);
Contract.EndContractBlock();
// Run the MoveNext method within a copy-on-write ExecutionContext scope.
@@ -304,7 +296,6 @@ namespace System.Runtime.CompilerServices
Thread currentThread = Thread.CurrentThread;
ExecutionContextSwitcher ecs = default(ExecutionContextSwitcher);
- RuntimeHelpers.PrepareConstrainedRegions();
try
{
ExecutionContext.EstablishCopyOnWriteScope(currentThread, ref ecs);
@@ -358,7 +349,11 @@ namespace System.Runtime.CompilerServices
/// <summary>Gets the <see cref="System.Threading.Tasks.Task"/> for this builder.</summary>
/// <returns>The <see cref="System.Threading.Tasks.Task"/> representing the builder's asynchronous operation.</returns>
/// <exception cref="System.InvalidOperationException">The builder is not initialized.</exception>
- public Task Task { get { return m_builder.Task; } }
+ public Task Task
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get { return m_builder.Task; }
+ }
/// <summary>
/// Completes the <see cref="System.Threading.Tasks.Task"/> in the
@@ -449,7 +444,7 @@ namespace System.Runtime.CompilerServices
// See comment on AsyncMethodBuilderCore.Start
// AsyncMethodBuilderCore.Start(ref stateMachine);
- if (stateMachine == null) throw new ArgumentNullException(nameof(stateMachine));
+ if (stateMachine == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.stateMachine);
Contract.EndContractBlock();
// Run the MoveNext method within a copy-on-write ExecutionContext scope.
@@ -458,7 +453,6 @@ namespace System.Runtime.CompilerServices
Thread currentThread = Thread.CurrentThread;
ExecutionContextSwitcher ecs = default(ExecutionContextSwitcher);
- RuntimeHelpers.PrepareConstrainedRegions();
try
{
ExecutionContext.EstablishCopyOnWriteScope(currentThread, ref ecs);
@@ -502,7 +496,7 @@ namespace System.Runtime.CompilerServices
{
// Force the Task to be initialized prior to the first suspending await so
// that the original stack-based builder has a reference to the right Task.
- var builtTask = this.Task;
+ Task builtTask = this.Task;
// Box the state machine, then tell the boxed instance to call back into its own builder,
// so we can cache the boxed reference. NOTE: The language compiler may choose to use
@@ -542,7 +536,7 @@ namespace System.Runtime.CompilerServices
{
// Force the Task to be initialized prior to the first suspending await so
// that the original stack-based builder has a reference to the right Task.
- var builtTask = this.Task;
+ Task<TResult> builtTask = this.Task;
// Box the state machine, then tell the boxed instance to call back into its own builder,
// so we can cache the boxed reference. NOTE: The language compiler may choose to use
@@ -563,15 +557,14 @@ namespace System.Runtime.CompilerServices
/// <returns>The <see cref="System.Threading.Tasks.Task{TResult}"/> representing the builder's asynchronous operation.</returns>
public Task<TResult> Task
{
- get
- {
- // Get and return the task. If there isn't one, first create one and store it.
- var task = m_task;
- if (task == null) { m_task = task = new Task<TResult>(); }
- return task;
- }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get { return m_task ?? InitializeTask(); }
}
+ /// <summary>Initializes the task, which must not yet be initialized.</summary>
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private Task<TResult> InitializeTask() => (m_task = new Task<TResult>());
+
/// <summary>
/// Completes the <see cref="System.Threading.Tasks.Task{TResult}"/> in the
/// <see cref="System.Threading.Tasks.TaskStatus">RanToCompletion</see> state with the specified result.
@@ -582,28 +575,49 @@ namespace System.Runtime.CompilerServices
{
// Get the currently stored task, which will be non-null if get_Task has already been accessed.
// If there isn't one, get a task and store it.
- var task = m_task;
- if (task == null)
+ if (m_task == null)
{
m_task = GetTaskForResult(result);
Debug.Assert(m_task != null, "GetTaskForResult should never return null");
}
- // Slow path: complete the existing task.
else
{
- if (AsyncCausalityTracer.LoggingOn)
- AsyncCausalityTracer.TraceOperationCompletion(CausalityTraceLevel.Required, task.Id, AsyncCausalityStatus.Completed);
+ // Slow path: complete the existing task.
+ SetExistingTaskResult(result);
+ }
+ }
- //only log if we have a real task that was previously created
- if (System.Threading.Tasks.Task.s_asyncDebuggingEnabled)
- {
- System.Threading.Tasks.Task.RemoveFromActiveTasks(task.Id);
- }
+ /// <summary>Completes the already initialized task with the specified result.</summary>
+ /// <param name="result">The result to use to complete the task.</param>
+ private void SetExistingTaskResult(TResult result)
+ {
+ Debug.Assert(m_task != null, "Expected non-null task");
- if (!task.TrySetResult(result))
- {
- throw new InvalidOperationException(Environment.GetResourceString("TaskT_TransitionToFinal_AlreadyCompleted"));
- }
+ if (AsyncCausalityTracer.LoggingOn || System.Threading.Tasks.Task.s_asyncDebuggingEnabled)
+ {
+ LogExistingTaskCompletion();
+ }
+
+ if (!m_task.TrySetResult(result))
+ {
+ ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted);
+ }
+ }
+
+ /// <summary>Handles logging for the successful completion of an operation.</summary>
+ private void LogExistingTaskCompletion()
+ {
+ Debug.Assert(m_task != null);
+
+ if (AsyncCausalityTracer.LoggingOn)
+ {
+ AsyncCausalityTracer.TraceOperationCompletion(CausalityTraceLevel.Required, m_task.Id, AsyncCausalityStatus.Completed);
+ }
+
+ // only log if we have a real task that was previously created
+ if (System.Threading.Tasks.Task.s_asyncDebuggingEnabled)
+ {
+ System.Threading.Tasks.Task.RemoveFromActiveTasks(m_task.Id);
}
}
@@ -620,15 +634,14 @@ namespace System.Runtime.CompilerServices
// Get the currently stored task, which will be non-null if get_Task has already been accessed.
// If there isn't one, store the supplied completed task.
- var task = m_task;
- if (task == null)
+ if (m_task == null)
{
m_task = completedTask;
}
else
{
// Otherwise, complete the task that's there.
- SetResult(default(TResult));
+ SetExistingTaskResult(default(TResult));
}
}
@@ -667,7 +680,7 @@ namespace System.Runtime.CompilerServices
if (!successfullySet)
{
- throw new InvalidOperationException(Environment.GetResourceString("TaskT_TransitionToFinal_AlreadyCompleted"));
+ ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted);
}
}
@@ -704,6 +717,7 @@ namespace System.Runtime.CompilerServices
/// </summary>
/// <param name="result">The result for which we need a task.</param>
/// <returns>The completed task containing the result.</returns>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)] // method looks long, but for a given TResult it results in a relatively small amount of asm
private Task<TResult> GetTaskForResult(TResult result)
{
Contract.Ensures(
@@ -846,9 +860,9 @@ namespace System.Runtime.CompilerServices
/// <exception cref="System.InvalidOperationException">The builder is incorrectly initialized.</exception>
public void SetStateMachine(IAsyncStateMachine stateMachine)
{
- if (stateMachine == null) throw new ArgumentNullException(nameof(stateMachine));
+ if (stateMachine == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.stateMachine);
Contract.EndContractBlock();
- if (m_stateMachine != null) throw new InvalidOperationException(Environment.GetResourceString("AsyncMethodBuilder_InstanceNotInitialized"));
+ if (m_stateMachine != null) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.AsyncMethodBuilder_InstanceNotInitialized);
m_stateMachine = stateMachine;
}
@@ -1104,12 +1118,12 @@ namespace System.Runtime.CompilerServices
return action;
}
- ///<summary>
- /// Given an action, see if it is a contiunation wrapper and has a Task associated with it. If so return it (null otherwise)
- ///</summary>
+ ///<summary>
+ /// Given an action, see if it is a contiunation wrapper and has a Task associated with it. If so return it (null otherwise)
+ ///</summary>
internal static Task TryGetContinuationTask(Action action)
{
- if (action != null)
+ if (action != null)
{
var asWrapper = action.Target as ContinuationWrapper;
if (asWrapper != null)
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs
deleted file mode 100644
index f1fc9ced82..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs
+++ /dev/null
@@ -1,18 +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;
-
-namespace System.Runtime.CompilerServices
-{
- [Serializable, AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
- public sealed class AsyncStateMachineAttribute : StateMachineAttribute
- {
- public AsyncStateMachineAttribute(Type stateMachineType)
- : base(stateMachineType)
- {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CallerFilePathAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CallerFilePathAttribute.cs
deleted file mode 100644
index 330934cf95..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/CallerFilePathAttribute.cs
+++ /dev/null
@@ -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.
-
-
-using System;
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
- public sealed class CallerFilePathAttribute : Attribute
- {
- public CallerFilePathAttribute()
- {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CallerLineNumberAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CallerLineNumberAttribute.cs
deleted file mode 100644
index 9c87e8e25f..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/CallerLineNumberAttribute.cs
+++ /dev/null
@@ -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.
-
-
-using System;
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
- public sealed class CallerLineNumberAttribute : Attribute
- {
- public CallerLineNumberAttribute()
- {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CallerMemberNameAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CallerMemberNameAttribute.cs
deleted file mode 100644
index 4fc70908fb..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/CallerMemberNameAttribute.cs
+++ /dev/null
@@ -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.
-
-
-using System;
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
- public sealed class CallerMemberNameAttribute : Attribute
- {
- public CallerMemberNameAttribute()
- {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CompilationRelaxations.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CompilationRelaxations.cs
deleted file mode 100644
index c3679b610c..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/CompilationRelaxations.cs
+++ /dev/null
@@ -1,50 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-namespace System.Runtime.CompilerServices
-{
-
- using System;
-
- /// IMPORTANT: Keep this in sync with corhdr.h
-[Serializable]
-[Flags]
- public enum CompilationRelaxations : int
- {
- NoStringInterning = 0x0008, // Start in 0x0008, we had other non public flags in this enum before,
- // so we'll start here just in case somebody used them. This flag is only
- // valid when set for Assemblies.
- };
-
-[Serializable]
-[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Method)]
- public class CompilationRelaxationsAttribute : Attribute
- {
- private int m_relaxations; // The relaxations.
-
- public CompilationRelaxationsAttribute (
- int relaxations)
- {
- m_relaxations = relaxations;
- }
-
- public CompilationRelaxationsAttribute (
- CompilationRelaxations relaxations)
- {
- m_relaxations = (int) relaxations;
- }
-
- public int CompilationRelaxations
- {
- get
- {
- return m_relaxations;
- }
- }
- }
-
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs
deleted file mode 100644
index 1778506c7c..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs
+++ /dev/null
@@ -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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-namespace System.Runtime.CompilerServices {
-
-[Serializable]
-[AttributeUsage(AttributeTargets.All, Inherited = true)]
- public sealed class CompilerGeneratedAttribute : Attribute
- {
- public CompilerGeneratedAttribute () {}
- }
-}
-
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs
deleted file mode 100644
index 1cd830cfca..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs
+++ /dev/null
@@ -1,26 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose: Attribute used to communicate to the VS7 debugger
-** that a class should be treated as if it has
-** global scope.
-**
-**
-===========================================================*/
-
-
-namespace System.Runtime.CompilerServices
-{
- [Serializable]
- [AttributeUsage(AttributeTargets.Class)]
- public class CompilerGlobalScopeAttribute : Attribute
- {
- public CompilerGlobalScopeAttribute () {}
- }
-}
-
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CompilerMarshalOverride.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CompilerMarshalOverride.cs
deleted file mode 100644
index a7b4aca480..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/CompilerMarshalOverride.cs
+++ /dev/null
@@ -1,23 +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.
-
-namespace System.Runtime.CompilerServices
-{
- // The CLR data marshaler has some behaviors that are incompatible with
- // C++. Specifically, C++ treats boolean variables as byte size, whereas
- // the marshaller treats them as 4-byte size. Similarly, C++ treats
- // wchar_t variables as 4-byte size, whereas the marshaller treats them
- // as single byte size under certain conditions. In order to work around
- // such issues, the C++ compiler will emit a type that the marshaller will
- // marshal using the correct sizes. In addition, the compiler will place
- // this modopt onto the variables to indicate that the specified type is
- // not the true type. Any compiler that needed to deal with similar
- // marshalling incompatibilities could use this attribute as well.
- //
- // Indicates that the modified instance differs from its true type for
- // correct marshalling.
- public static class CompilerMarshalOverride
- {
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs b/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs
index 4b2648ba6f..f32cc2b510 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs
@@ -61,6 +61,7 @@
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
@@ -164,7 +165,6 @@ namespace System.Runtime.CompilerServices
{
CreateEntry(key, value);
}
-
}
}
@@ -797,7 +797,7 @@ namespace System.Runtime.CompilerServices
}
return Resize(newSize);
- }
+ }
internal Container Resize(int newSize)
{
@@ -974,7 +974,7 @@ namespace System.Runtime.CompilerServices
{
if (_invalid)
{
- throw new InvalidOperationException(Environment.GetResourceString("CollectionCorrupted"));
+ throw new InvalidOperationException(SR.InvalidOperation_CollectionCorrupted);
}
}
@@ -1114,7 +1114,7 @@ namespace System.Runtime.CompilerServices
{
IntPtr handle = _handle;
_handle = (IntPtr)0;
- nFree(handle);
+ nFree(handle);
}
}
#endregion
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CustomConstantAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CustomConstantAttribute.cs
index 1a5dcfdc11..8f4c79cd94 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/CustomConstantAttribute.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/CustomConstantAttribute.cs
@@ -8,7 +8,7 @@ using System.Collections.Generic;
namespace System.Runtime.CompilerServices
{
[Serializable]
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited=false)]
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
public abstract class CustomConstantAttribute : Attribute
{
public abstract Object Value { get; }
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/DateTimeConstantAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/DateTimeConstantAttribute.cs
index 148d916be1..7aca42b627 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/DateTimeConstantAttribute.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/DateTimeConstantAttribute.cs
@@ -8,7 +8,7 @@ using System.Diagnostics.Contracts;
namespace System.Runtime.CompilerServices
{
[Serializable]
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited=false)]
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
public sealed class DateTimeConstantAttribute : CustomConstantAttribute
{
public DateTimeConstantAttribute(long ticks)
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/DecimalConstantAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/DecimalConstantAttribute.cs
index f05191840d..0e2b6f8418 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/DecimalConstantAttribute.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/DecimalConstantAttribute.cs
@@ -13,7 +13,7 @@ using System.Collections.Generic;
namespace System.Runtime.CompilerServices
{
[Serializable]
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited=false)]
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
public sealed class DecimalConstantAttribute : Attribute
{
[CLSCompliant(false)]
@@ -25,7 +25,7 @@ namespace System.Runtime.CompilerServices
uint low
)
{
- dec = new System.Decimal((int) low, (int)mid, (int)hi, (sign != 0), scale);
+ dec = new System.Decimal((int)low, (int)mid, (int)hi, (sign != 0), scale);
}
public DecimalConstantAttribute(
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs
deleted file mode 100644
index 46dae10fdd..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs
+++ /dev/null
@@ -1,18 +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.
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-namespace System.Runtime.CompilerServices
-{
- using System;
-
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=false, Inherited=false)]
- public sealed class DisablePrivateReflectionAttribute : Attribute
- {
- public DisablePrivateReflectionAttribute() {}
- }
-}
-
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/DiscardableAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/DiscardableAttribute.cs
deleted file mode 100644
index 3fda4624d4..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/DiscardableAttribute.cs
+++ /dev/null
@@ -1,18 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-namespace System.Runtime.CompilerServices {
-
- using System;
-
- // Custom attribute to indicating a TypeDef is a discardable attribute
- public class DiscardableAttribute : Attribute
- {
- public DiscardableAttribute()
- {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/ExtensionAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/ExtensionAttribute.cs
deleted file mode 100644
index 6ec8fa04f5..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/ExtensionAttribute.cs
+++ /dev/null
@@ -1,13 +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;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// Indicates that a method is an extension method, or that a class or assembly contains extension methods.
- /// </summary>
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
- public sealed class ExtensionAttribute : Attribute { }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs
deleted file mode 100644
index 679e304ad1..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs
+++ /dev/null
@@ -1,14 +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.
-
-namespace System.Runtime.CompilerServices
-{
- using System;
-
-[Serializable]
-[AttributeUsage(AttributeTargets.Field)]
- sealed public class FixedAddressValueTypeAttribute : Attribute
- {
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/FixedBufferAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/FixedBufferAttribute.cs
deleted file mode 100644
index a7d01b12c4..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/FixedBufferAttribute.cs
+++ /dev/null
@@ -1,43 +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.
-
-/*============================================================
-**
-**
-** Purpose: Used by a compiler for generating value types
-** in-place within other value types containing a certain
-** number of elements of the given (primitive) type. Somewhat
-** similar to P/Invoke's ByValTStr attribute.
-** Used by C# with this syntax: "fixed int buffer[10];"
-**
-===========================================================*/
-using System;
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Field, Inherited=false)]
- public sealed class FixedBufferAttribute : Attribute
- {
- private Type elementType;
- private int length;
-
- public FixedBufferAttribute(Type elementType, int length)
- {
- this.elementType = elementType;
- this.length = length;
- }
-
- public Type ElementType {
- get {
- return elementType;
- }
- }
-
- public int Length {
- get {
- return length;
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/FormattableStringFactory.cs b/src/mscorlib/src/System/Runtime/CompilerServices/FormattableStringFactory.cs
deleted file mode 100644
index 4b99a8a5d9..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/FormattableStringFactory.cs
+++ /dev/null
@@ -1,58 +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.
-
-/*============================================================
-**
-** Class: FormattableStringFactory
-**
-**
-** Purpose: implementation of the FormattableStringFactory
-** class.
-**
-===========================================================*/
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// A factory type used by compilers to create instances of the type <see cref="FormattableString"/>.
- /// </summary>
- public static class FormattableStringFactory
- {
- /// <summary>
- /// Create a <see cref="FormattableString"/> from a composite format string and object
- /// array containing zero or more objects to format.
- /// </summary>
- public static FormattableString Create(string format, params object[] arguments)
- {
- if (format == null)
- {
- throw new ArgumentNullException(nameof(format));
- }
-
- if (arguments == null)
- {
- throw new ArgumentNullException(nameof(arguments));
- }
-
- return new ConcreteFormattableString(format, arguments);
- }
-
- private sealed class ConcreteFormattableString : FormattableString
- {
- private readonly string _format;
- private readonly object[] _arguments;
-
- internal ConcreteFormattableString(string format, object[] arguments)
- {
- _format = format;
- _arguments = arguments;
- }
-
- public override string Format { get { return _format; } }
- public override object[] GetArguments() { return _arguments; }
- public override int ArgumentCount { get { return _arguments.Length; } }
- public override object GetArgument(int index) { return _arguments[index]; }
- public override string ToString(IFormatProvider formatProvider) { return string.Format(formatProvider, _format, _arguments); }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/FriendAccessAllowedAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/FriendAccessAllowedAttribute.cs
new file mode 100644
index 0000000000..9d380e1070
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/FriendAccessAllowedAttribute.cs
@@ -0,0 +1,26 @@
+// 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.
+
+namespace System.Runtime.CompilerServices
+{
+ /// <summary>
+ /// If AllInternalsVisible is not true for a friend assembly, the FriendAccessAllowed attribute
+ /// indicates which internals are shared with that friend assembly.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class |
+ AttributeTargets.Constructor |
+ AttributeTargets.Enum |
+ AttributeTargets.Event |
+ AttributeTargets.Field |
+ AttributeTargets.Interface |
+ AttributeTargets.Method |
+ AttributeTargets.Property |
+ AttributeTargets.Struct,
+ AllowMultiple = false,
+ Inherited = false)]
+ [FriendAccessAllowed]
+ internal sealed class FriendAccessAllowedAttribute : Attribute
+ {
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/ICastable.cs b/src/mscorlib/src/System/Runtime/CompilerServices/ICastable.cs
index 7ba9434575..e2b76ed973 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/ICastable.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/ICastable.cs
@@ -61,22 +61,22 @@ namespace System.Runtime.CompilerServices
// IsInstanceOfInterface.
RuntimeTypeHandle GetImplType(RuntimeTypeHandle interfaceType);
}
-
+
/// <summary>
/// Helpers that allows VM to call into ICastable methods without having to deal with RuntimeTypeHandle.
/// RuntimeTypeHandle is a struct and is always passed in stack in x86, which our VM call helpers don't
/// particularly like.
/// </summary>
- class ICastableHelpers
+ internal class ICastableHelpers
{
internal static bool IsInstanceOfInterface(ICastable castable, RuntimeType type, out Exception castError)
{
return castable.IsInstanceOfInterface(new RuntimeTypeHandle(type), out castError);
- }
-
+ }
+
internal static RuntimeType GetImplType(ICastable castable, RuntimeType interfaceType)
{
- return castable.GetImplType(new RuntimeTypeHandle(interfaceType)).GetRuntimeType();
- }
+ return castable.GetImplType(new RuntimeTypeHandle(interfaceType)).GetRuntimeType();
+ }
}
}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IndexerNameAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IndexerNameAttribute.cs
deleted file mode 100644
index c32be6f3a2..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IndexerNameAttribute.cs
+++ /dev/null
@@ -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.
-
-namespace System.Runtime.CompilerServices
-{
- using System;
-
-[Serializable]
-[AttributeUsage(AttributeTargets.Property, Inherited = true)]
- public sealed class IndexerNameAttribute: Attribute
- {
- public IndexerNameAttribute(String indexerName)
- {}
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs
deleted file mode 100644
index ee7807a5dd..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs
+++ /dev/null
@@ -1,58 +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.
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-namespace System.Runtime.CompilerServices
-{
- using System;
-
-
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=true, Inherited=false)]
- public sealed class InternalsVisibleToAttribute : Attribute
- {
- private string _assemblyName;
- private bool _allInternalsVisible = true;
-
- public InternalsVisibleToAttribute(string assemblyName)
- {
- this._assemblyName = assemblyName;
- }
-
- public string AssemblyName
- {
- get
- {
- return _assemblyName;
- }
- }
-
- public bool AllInternalsVisible
- {
- get { return _allInternalsVisible; }
- set { _allInternalsVisible = value; }
- }
- }
-
- /// <summary>
- /// If AllInternalsVisible is not true for a friend assembly, the FriendAccessAllowed attribute
- /// indicates which internals are shared with that friend assembly.
- /// </summary>
- [AttributeUsage(AttributeTargets.Class |
- AttributeTargets.Constructor |
- AttributeTargets.Enum |
- AttributeTargets.Event |
- AttributeTargets.Field |
- AttributeTargets.Interface |
- AttributeTargets.Method |
- AttributeTargets.Property |
- AttributeTargets.Struct,
- AllowMultiple = false,
- Inherited = false)]
- [FriendAccessAllowed]
- internal sealed class FriendAccessAllowedAttribute : Attribute {
- }
-}
-
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsVolatile.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsVolatile.cs
deleted file mode 100644
index 5287e82b7b..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IsVolatile.cs
+++ /dev/null
@@ -1,12 +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.
-
-namespace System.Runtime.CompilerServices
-{
- public static class IsVolatile
- {
- // no instantiation, please!
- }
-}
-
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs
deleted file mode 100644
index 4bb9b4eb8f..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs
+++ /dev/null
@@ -1,18 +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;
-
-namespace System.Runtime.CompilerServices
-{
- [Serializable, AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
- public sealed class IteratorStateMachineAttribute : StateMachineAttribute
- {
- public IteratorStateMachineAttribute(Type stateMachineType)
- : base(stateMachineType)
- {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/MethodImplAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/MethodImplAttribute.cs
index b4991110f8..b24018cf78 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/MethodImplAttribute.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/MethodImplAttribute.cs
@@ -2,72 +2,47 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Runtime.CompilerServices {
-
- using System;
- using System.Reflection;
-
+
+using System;
+using System.Reflection;
+
+namespace System.Runtime.CompilerServices
+{
// This Enum matchs the miImpl flags defined in corhdr.h. It is used to specify
// certain method properties.
-
- [Serializable]
- [Flags]
- public enum MethodImplOptions
- {
- Unmanaged = System.Reflection.MethodImplAttributes.Unmanaged,
- ForwardRef = System.Reflection.MethodImplAttributes.ForwardRef,
- PreserveSig = System.Reflection.MethodImplAttributes.PreserveSig,
- InternalCall = System.Reflection.MethodImplAttributes.InternalCall,
- Synchronized = System.Reflection.MethodImplAttributes.Synchronized,
- NoInlining = System.Reflection.MethodImplAttributes.NoInlining,
- AggressiveInlining = System.Reflection.MethodImplAttributes.AggressiveInlining,
- NoOptimization = System.Reflection.MethodImplAttributes.NoOptimization,
- // **** If you add something, update internal MethodImplAttribute(MethodImplAttributes methodImplAttributes)! ****
- }
+ // Custom attribute to specify additional method properties.
[Serializable]
- public enum MethodCodeType
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)]
+ sealed public class MethodImplAttribute : Attribute
{
- IL = System.Reflection.MethodImplAttributes.IL,
- Native = System.Reflection.MethodImplAttributes.Native,
- /// <internalonly/>
- OPTIL = System.Reflection.MethodImplAttributes.OPTIL,
- Runtime = System.Reflection.MethodImplAttributes.Runtime
- }
-
- // Custom attribute to specify additional method properties.
-[Serializable]
-[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)]
- sealed public class MethodImplAttribute : Attribute
- {
- internal MethodImplOptions _val;
- public MethodCodeType MethodCodeType;
+ internal MethodImplOptions _val;
+ public MethodCodeType MethodCodeType;
internal MethodImplAttribute(MethodImplAttributes methodImplAttributes)
{
- MethodImplOptions all =
- MethodImplOptions.Unmanaged | MethodImplOptions.ForwardRef | MethodImplOptions.PreserveSig |
+ MethodImplOptions all =
+ MethodImplOptions.Unmanaged | MethodImplOptions.ForwardRef | MethodImplOptions.PreserveSig |
MethodImplOptions.InternalCall | MethodImplOptions.Synchronized |
MethodImplOptions.NoInlining | MethodImplOptions.AggressiveInlining |
MethodImplOptions.NoOptimization;
_val = ((MethodImplOptions)methodImplAttributes) & all;
}
-
+
public MethodImplAttribute(MethodImplOptions methodImplOptions)
{
_val = methodImplOptions;
}
-
+
public MethodImplAttribute(short value)
{
_val = (MethodImplOptions)value;
}
-
+
public MethodImplAttribute()
{
}
-
- public MethodImplOptions Value { get {return _val;} }
- }
+ public MethodImplOptions Value { get { return _val; } }
+ }
}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs
deleted file mode 100644
index d5e64a1177..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs
+++ /dev/null
@@ -1,39 +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.
-
-/*============================================================
-**
-** Attribute: ReferenceAssemblyAttribute
-**
-** Purpose: Identifies an assembly as being a "reference
-** assembly", meaning it contains public surface area but
-** no usable implementation. Reference assemblies
-** should be loadable for introspection, but not execution.
-**
-============================================================*/
-namespace System.Runtime.CompilerServices
-{
- using System;
-
- [Serializable]
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=false)]
- public sealed class ReferenceAssemblyAttribute : Attribute
- {
- private String _description; // Maybe ".NET FX v4.0 SP1, partial trust"?
-
- public ReferenceAssemblyAttribute()
- {
- }
-
- public ReferenceAssemblyAttribute(String description)
- {
- _description = description;
- }
-
- public String Description
- {
- get { return _description; }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs
deleted file mode 100644
index 40a9b7c568..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs
+++ /dev/null
@@ -1,48 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-/*=============================================================================
-**
-**
-**
-** Purpose: Mark up the program to indicate various legacy or new opt-in behaviors.
-**
-**
-=============================================================================*/
-
-namespace System.Runtime.CompilerServices
-{
-
- using System;
-
-[Serializable]
-[AttributeUsage(AttributeTargets.Assembly, Inherited=false, AllowMultiple=false)]
- public sealed class RuntimeCompatibilityAttribute : Attribute
- {
- // fields
- private bool m_wrapNonExceptionThrows;
-
- // constructors
- public RuntimeCompatibilityAttribute() {
- // legacy behavior is the default, and m_wrapNonExceptionThrows is implicitly
- // false thanks to the CLR's guarantee of zeroed memory.
- }
-
- // properties
-
- // If a non-CLSCompliant exception (i.e. one that doesn't derive from System.Exception) is
- // thrown, should it be wrapped up in a System.Runtime.CompilerServices.RuntimeWrappedException
- // instance when presented to catch handlers?
- public bool WrapNonExceptionThrows {
- get {
- return m_wrapNonExceptionThrows;
- }
- set {
- m_wrapNonExceptionThrows = value;
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs
index 509e527ecb..0338b18bee 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs
@@ -9,8 +9,9 @@
// This class defines a set of static methods that provide support for compilers.
//
//
-namespace System.Runtime.CompilerServices {
+namespace System.Runtime.CompilerServices
+{
using System;
using System.Security;
using System.Runtime;
@@ -32,7 +33,7 @@ namespace System.Runtime.CompilerServices {
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern void InitializeArray(Array array,RuntimeFieldHandle fldHandle);
+ public static extern void InitializeArray(Array array, RuntimeFieldHandle fldHandle);
// GetObjectValue is intended to allow value classes to be manipulated as 'Object'
// but have aliasing behavior of a value class. The intent is that you would use
@@ -61,7 +62,7 @@ namespace System.Runtime.CompilerServices {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _RunClassConstructor(RuntimeType type);
- public static void RunClassConstructor(RuntimeTypeHandle type)
+ public static void RunClassConstructor(RuntimeTypeHandle type)
{
_RunClassConstructor(type.GetRuntimeType());
}
@@ -77,24 +78,24 @@ namespace System.Runtime.CompilerServices {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void _RunModuleConstructor(System.Reflection.RuntimeModule module);
- public static void RunModuleConstructor(ModuleHandle module)
+ public static void RunModuleConstructor(ModuleHandle module)
{
- _RunModuleConstructor(module.GetRuntimeModule());
+ _RunModuleConstructor(module.GetRuntimeModule());
}
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
internal static extern void _CompileMethod(IRuntimeMethodInfo method);
- public static void PrepareMethod(RuntimeMethodHandle method){}
- public static void PrepareMethod(RuntimeMethodHandle method, RuntimeTypeHandle[] instantiation){}
- public static void PrepareContractedDelegate(Delegate d){}
-
+ public static void PrepareMethod(RuntimeMethodHandle method) { }
+ public static void PrepareMethod(RuntimeMethodHandle method, RuntimeTypeHandle[] instantiation) { }
+ public static void PrepareContractedDelegate(Delegate d) { }
+
public static void PrepareDelegate(Delegate d)
{
if (d == null)
{
- throw new ArgumentNullException ("d");
+ throw new ArgumentNullException("d");
}
}
@@ -108,8 +109,9 @@ namespace System.Runtime.CompilerServices {
{
// This offset is baked in by string indexer intrinsic, so there is no harm
// in getting it baked in here as well.
- [System.Runtime.Versioning.NonVersionable]
- get {
+ [System.Runtime.Versioning.NonVersionable]
+ get
+ {
// Number of bytes from the address pointed to by a reference to
// a String to the first 16-bit character in the String. Skip
// over the MethodTable pointer, & String
@@ -167,6 +169,14 @@ namespace System.Runtime.CompilerServices {
{
((CleanupCode)backoutCode)(userData, exceptionThrown);
}
+
+ /// <returns>true if given type is reference type or value type that contains references</returns>
+ static public bool IsReferenceOrContainsReferences<T>()
+ {
+ // The body of this function will be replaced by the EE with unsafe code!!!
+ // See getILIntrinsicImplementation for how this happens.
+ throw new InvalidOperationException();
+ }
}
}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeWrappedException.cs b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeWrappedException.cs
index e3b2d2ce62..c050000169 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeWrappedException.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeWrappedException.cs
@@ -11,29 +11,34 @@
**
=============================================================================*/
-namespace System.Runtime.CompilerServices {
- using System;
- using System.Runtime.Serialization;
- using System.Runtime.Remoting;
- using System.Diagnostics.Contracts;
-
+using System;
+using System.Runtime.Serialization;
+using System.Runtime.Remoting;
+using System.Diagnostics.Contracts;
+
+namespace System.Runtime.CompilerServices
+{
[Serializable]
public sealed class RuntimeWrappedException : Exception
{
private RuntimeWrappedException(Object thrownObject)
- : base(Environment.GetResourceString("RuntimeWrappedException")) {
- SetErrorCode(System.__HResults.COR_E_RUNTIMEWRAPPED);
+ : base(SR.RuntimeWrappedException)
+ {
+ HResult = System.__HResults.COR_E_RUNTIMEWRAPPED;
m_wrappedException = thrownObject;
}
-
- public Object WrappedException {
+
+ public Object WrappedException
+ {
get { return m_wrappedException; }
}
private Object m_wrappedException;
- public override void GetObjectData(SerializationInfo info, StreamingContext context) {
- if (info==null) {
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
@@ -42,7 +47,8 @@ namespace System.Runtime.CompilerServices {
}
internal RuntimeWrappedException(SerializationInfo info, StreamingContext context)
- : base(info, context) {
+ : base(info, context)
+ {
m_wrappedException = info.GetValue("WrappedException", typeof(Object));
}
}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/SpecialNameAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/SpecialNameAttribute.cs
deleted file mode 100644
index 38e5538b44..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/SpecialNameAttribute.cs
+++ /dev/null
@@ -1,27 +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 System.Runtime.InteropServices;
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Class |
- AttributeTargets.Method |
- AttributeTargets.Property |
- AttributeTargets.Field |
- AttributeTargets.Event |
- AttributeTargets.Struct)]
-
-
- public sealed class SpecialNameAttribute : Attribute
- {
- public SpecialNameAttribute() { }
- }
-}
-
-
-
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/StateMachineAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/StateMachineAttribute.cs
deleted file mode 100644
index 7c84009e1f..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/StateMachineAttribute.cs
+++ /dev/null
@@ -1,20 +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;
-
-namespace System.Runtime.CompilerServices
-{
- [Serializable, AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
- public class StateMachineAttribute : Attribute
- {
- public Type StateMachineType { get; private set; }
-
- public StateMachineAttribute(Type stateMachineType)
- {
- this.StateMachineType = stateMachineType;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs
deleted file mode 100644
index eb019eecbf..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs
+++ /dev/null
@@ -1,19 +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.
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-namespace System.Runtime.CompilerServices
-{
- using System;
-
- [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module)]
- public sealed class SuppressIldasmAttribute : Attribute
- {
- public SuppressIldasmAttribute()
- {
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/SuppressMergeCheckAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/SuppressMergeCheckAttribute.cs
deleted file mode 100644
index 6bb36c4bf5..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/SuppressMergeCheckAttribute.cs
+++ /dev/null
@@ -1,23 +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.Runtime.InteropServices;
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Class |
- AttributeTargets.Constructor |
- AttributeTargets.Method |
- AttributeTargets.Field |
- AttributeTargets.Event |
- AttributeTargets.Property)]
-
- internal sealed class SuppressMergeCheckAttribute : Attribute
- {
- public SuppressMergeCheckAttribute()
- {}
- }
-}
-
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/TaskAwaiter.cs b/src/mscorlib/src/System/Runtime/CompilerServices/TaskAwaiter.cs
index f01900a5bf..e2fa6caa2d 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/TaskAwaiter.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/TaskAwaiter.cs
@@ -72,7 +72,7 @@ namespace System.Runtime.CompilerServices
/// <summary>Gets whether the task being awaited is completed.</summary>
/// <remarks>This property is intended for compiler user rather than use directly in code.</remarks>
/// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- public bool IsCompleted
+ public bool IsCompleted
{
get { return m_task.IsCompleted; }
}
@@ -84,7 +84,7 @@ namespace System.Runtime.CompilerServices
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
public void OnCompleted(Action continuation)
{
- OnCompletedInternal(m_task, continuation, continueOnCapturedContext:true, flowExecutionContext:true);
+ OnCompletedInternal(m_task, continuation, continueOnCapturedContext: true, flowExecutionContext: true);
}
/// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
@@ -94,7 +94,7 @@ namespace System.Runtime.CompilerServices
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
public void UnsafeOnCompleted(Action continuation)
{
- OnCompletedInternal(m_task, continuation, continueOnCapturedContext:true, flowExecutionContext:false);
+ OnCompletedInternal(m_task, continuation, continueOnCapturedContext: true, flowExecutionContext: false);
}
/// <summary>Ends the await on the completed <see cref="System.Threading.Tasks.Task"/>.</summary>
@@ -240,7 +240,7 @@ namespace System.Runtime.CompilerServices
etwLog.TaskWaitBegin(
(currentTaskAtBegin != null ? currentTaskAtBegin.m_taskScheduler.Id : TaskScheduler.Default.Id),
(currentTaskAtBegin != null ? currentTaskAtBegin.Id : 0),
- task.Id, TplEtwProvider.TaskWaitBehavior.Asynchronous,
+ task.Id, TplEtwProvider.TaskWaitBehavior.Asynchronous,
(continuationTask != null ? continuationTask.Id : 0));
}
@@ -303,7 +303,7 @@ namespace System.Runtime.CompilerServices
/// <summary>Gets whether the task being awaited is completed.</summary>
/// <remarks>This property is intended for compiler user rather than use directly in code.</remarks>
/// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- public bool IsCompleted
+ public bool IsCompleted
{
get { return m_task.IsCompleted; }
}
@@ -315,7 +315,7 @@ namespace System.Runtime.CompilerServices
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
public void OnCompleted(Action continuation)
{
- TaskAwaiter.OnCompletedInternal(m_task, continuation, continueOnCapturedContext:true, flowExecutionContext:true);
+ TaskAwaiter.OnCompletedInternal(m_task, continuation, continueOnCapturedContext: true, flowExecutionContext: true);
}
/// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
@@ -325,7 +325,7 @@ namespace System.Runtime.CompilerServices
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
public void UnsafeOnCompleted(Action continuation)
{
- TaskAwaiter.OnCompletedInternal(m_task, continuation, continueOnCapturedContext:true, flowExecutionContext:false);
+ TaskAwaiter.OnCompletedInternal(m_task, continuation, continueOnCapturedContext: true, flowExecutionContext: false);
}
/// <summary>Ends the await on the completed <see cref="System.Threading.Tasks.Task{TResult}"/>.</summary>
@@ -390,7 +390,7 @@ namespace System.Runtime.CompilerServices
/// <summary>Gets whether the task being awaited is completed.</summary>
/// <remarks>This property is intended for compiler user rather than use directly in code.</remarks>
/// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- public bool IsCompleted
+ public bool IsCompleted
{
get { return m_task.IsCompleted; }
}
@@ -402,7 +402,7 @@ namespace System.Runtime.CompilerServices
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
public void OnCompleted(Action continuation)
{
- TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext:true);
+ TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext: true);
}
/// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
@@ -412,7 +412,7 @@ namespace System.Runtime.CompilerServices
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
public void UnsafeOnCompleted(Action continuation)
{
- TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext:false);
+ TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext: false);
}
/// <summary>Ends the await on the completed <see cref="System.Threading.Tasks.Task"/>.</summary>
@@ -475,7 +475,7 @@ namespace System.Runtime.CompilerServices
/// <summary>Gets whether the task being awaited is completed.</summary>
/// <remarks>This property is intended for compiler user rather than use directly in code.</remarks>
/// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
- public bool IsCompleted
+ public bool IsCompleted
{
get { return m_task.IsCompleted; }
}
@@ -487,7 +487,7 @@ namespace System.Runtime.CompilerServices
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
public void OnCompleted(Action continuation)
{
- TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext:true);
+ TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext: true);
}
/// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
@@ -497,7 +497,7 @@ namespace System.Runtime.CompilerServices
/// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
public void UnsafeOnCompleted(Action continuation)
{
- TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext:false);
+ TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext: false);
}
/// <summary>Ends the await on the completed <see cref="System.Threading.Tasks.Task{TResult}"/>.</summary>
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs
deleted file mode 100644
index 65b120e6b4..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/TupleElementNamesAttribute.cs
+++ /dev/null
@@ -1,57 +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.Collections.Generic;
-
-namespace System.Runtime.CompilerServices
-{
- /// <summary>
- /// Indicates that the use of <see cref="System.ValueTuple"/> on a member is meant to be treated as a tuple with element names.
- /// </summary>
- [CLSCompliant(false)]
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Event)]
- public sealed class TupleElementNamesAttribute : Attribute
- {
- private readonly string[] _transformNames;
-
- /// <summary>
- /// Initializes a new instance of the <see
- /// cref="TupleElementNamesAttribute"/> class.
- /// </summary>
- /// <param name="transformNames">
- /// Specifies, in a pre-order depth-first traversal of a type's
- /// construction, which <see cref="System.ValueType"/> occurrences are
- /// meant to carry element names.
- /// </param>
- /// <remarks>
- /// This constructor is meant to be used on types that contain an
- /// instantiation of <see cref="System.ValueType"/> that contains
- /// element names. For instance, if <c>C</c> is a generic type with
- /// two type parameters, then a use of the constructed type <c>C{<see
- /// cref="System.ValueTuple{T1, T2}"/>, <see
- /// cref="System.ValueTuple{T1, T2, T3}"/></c> might be intended to
- /// treat the first type argument as a tuple with element names and the
- /// second as a tuple without element names. In which case, the
- /// appropriate attribute specification should use a
- /// <c>transformNames</c> value of <c>{ "name1", "name2", null, null,
- /// null }</c>.
- /// </remarks>
- public TupleElementNamesAttribute(string[] transformNames)
- {
- if (transformNames == null)
- {
- throw new ArgumentNullException(nameof(transformNames));
- }
-
- _transformNames = transformNames;
- }
-
- /// <summary>
- /// Specifies, in a pre-order depth-first traversal of a type's
- /// construction, which <see cref="System.ValueTuple"/> elements are
- /// meant to carry element names.
- /// </summary>
- public IList<string> TransformNames => _transformNames;
- }
-} \ No newline at end of file
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/TypeDependencyAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/TypeDependencyAttribute.cs
index 2de9c1f785..929cbe7608 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/TypeDependencyAttribute.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/TypeDependencyAttribute.cs
@@ -2,28 +2,26 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Runtime.CompilerServices
-{
- using System;
- using System.Diagnostics.Contracts;
+using System;
+using System.Diagnostics.Contracts;
+namespace System.Runtime.CompilerServices
+{
// We might want to make this inherited someday. But I suspect it shouldn't
// be necessary.
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)]
- internal sealed class TypeDependencyAttribute: Attribute
+ internal sealed class TypeDependencyAttribute : Attribute
{
-
private string typeName;
- public TypeDependencyAttribute (string typeName)
+ public TypeDependencyAttribute(string typeName)
{
- if(typeName == null) throw new ArgumentNullException(nameof(typeName));
+ if (typeName == null) throw new ArgumentNullException(nameof(typeName));
Contract.EndContractBlock();
this.typeName = typeName;
}
}
-
}
-
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs
deleted file mode 100644
index 671d1f0071..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs
+++ /dev/null
@@ -1,35 +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.
-
-
-namespace System.Runtime.CompilerServices
-{
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
- public sealed class TypeForwardedFromAttribute : Attribute
- {
- string assemblyFullName;
-
- private TypeForwardedFromAttribute()
- {
- // Disallow default constructor
- }
-
-
- public TypeForwardedFromAttribute(string assemblyFullName)
- {
- if (String.IsNullOrEmpty(assemblyFullName))
- {
- throw new ArgumentNullException(nameof(assemblyFullName));
- }
- this.assemblyFullName = assemblyFullName;
- }
-
- public string AssemblyFullName
- {
- get {
- return assemblyFullName;
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs
deleted file mode 100644
index 147c103047..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs
+++ /dev/null
@@ -1,34 +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;
-
-namespace System.Runtime.CompilerServices
-{
- using System;
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=true, Inherited=false)]
- public sealed class TypeForwardedToAttribute : Attribute
- {
- private Type _destination;
-
- public TypeForwardedToAttribute(Type destination)
- {
- _destination = destination;
- }
-
- public Type Destination
- {
- get {
- return _destination;
- }
- }
-
- }
-}
-
-
-
-
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs b/src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs
index adfa015161..b184cd9fa8 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/Unsafe.cs
@@ -4,6 +4,12 @@
using System.Runtime.Versioning;
+#if BIT64
+using nuint = System.UInt64;
+#else
+using nuint = System.UInt32;
+#endif
+
namespace System.Runtime.CompilerServices
{
//
@@ -37,6 +43,7 @@ namespace System.Runtime.CompilerServices
{
// The body of this function will be replaced by the EE with unsafe code that just returns sizeof !!T
// See getILIntrinsicImplementationForUnsafe for how this happens.
+ typeof(T).ToString(); // Type token used by the actual method body
throw new InvalidOperationException();
}
@@ -61,7 +68,19 @@ namespace System.Runtime.CompilerServices
{
// The body of this function will be replaced by the EE with unsafe code!!!
// See getILIntrinsicImplementationForUnsafe for how this happens.
- typeof(T).ToString(); // Type used by the actual method body
+ typeof(T).ToString(); // Type token used by the actual method body
+ throw new InvalidOperationException();
+ }
+
+ /// <summary>
+ /// Adds an element offset to the given reference.
+ /// </summary>
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ref T AddByteOffset<T>(ref T source, nuint byteOffset)
+ {
+ // The body of this function will be replaced by the EE with unsafe code!!!
+ // See getILIntrinsicImplementationForUnsafe for how this happens.
throw new InvalidOperationException();
}
@@ -89,5 +108,45 @@ namespace System.Runtime.CompilerServices
// See getILIntrinsicImplementationForUnsafe for how this happens.
throw new InvalidOperationException();
}
+
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static T ReadUnaligned<T>(void* source)
+ {
+ // The body of this function will be replaced by the EE with unsafe code!!!
+ // See getILIntrinsicImplementationForUnsafe for how this happens.
+ typeof(T).ToString(); // Type token used by the actual method body
+ throw new InvalidOperationException();
+ }
+
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static T ReadUnaligned<T>(ref byte source)
+ {
+ // The body of this function will be replaced by the EE with unsafe code!!!
+ // See getILIntrinsicImplementationForUnsafe for how this happens.
+ typeof(T).ToString(); // Type token used by the actual method body
+ throw new InvalidOperationException();
+ }
+
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void WriteUnaligned<T>(void* destination, T value)
+ {
+ // The body of this function will be replaced by the EE with unsafe code!!!
+ // See getILIntrinsicImplementationForUnsafe for how this happens.
+ typeof(T).ToString(); // Type token used by the actual method body
+ throw new InvalidOperationException();
+ }
+
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void WriteUnaligned<T>(ref byte destination, T value)
+ {
+ // The body of this function will be replaced by the EE with unsafe code!!!
+ // See getILIntrinsicImplementationForUnsafe for how this happens.
+ typeof(T).ToString(); // Type token used by the actual method body
+ throw new InvalidOperationException();
+ }
}
}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs
deleted file mode 100644
index bc210ccb71..0000000000
--- a/src/mscorlib/src/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs
+++ /dev/null
@@ -1,14 +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.
-
-namespace System.Runtime.CompilerServices
-{
- using System;
-
-[Serializable]
-[AttributeUsage(AttributeTargets.Struct)]
- sealed public class UnsafeValueTypeAttribute : Attribute
- {
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/YieldAwaitable.cs b/src/mscorlib/src/System/Runtime/CompilerServices/YieldAwaitable.cs
index 92d1b4f95b..f1c7772526 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/YieldAwaitable.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/YieldAwaitable.cs
@@ -144,7 +144,6 @@ namespace System.Runtime.CompilerServices
etwLog.TaskWaitContinuationComplete(continuationId);
});
-
}
/// <summary>WaitCallback that invokes the Action supplied as object state.</summary>
@@ -157,7 +156,7 @@ namespace System.Runtime.CompilerServices
private static void RunAction(object state) { ((Action)state)(); }
/// <summary>Ends the await operation.</summary>
- public void GetResult() {} // Nop. It exists purely because the compiler pattern demands it.
+ public void GetResult() { } // Nop. It exists purely because the compiler pattern demands it.
}
}
}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs b/src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs
index 080e42f46f..b86835f778 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs
@@ -16,8 +16,8 @@ using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using System.Security;
-namespace System.Runtime.CompilerServices {
-
+namespace System.Runtime.CompilerServices
+{
// Wrapper for address of a string variable on stack
internal struct StringHandleOnStack
{
@@ -114,14 +114,14 @@ namespace System.Runtime.CompilerServices {
static internal int UnsafeEnumCast<T>(T val) where T : struct // Actually T must be 4 byte (or less) enum
{
- Debug.Assert(typeof(T).IsEnum
- && (Enum.GetUnderlyingType(typeof(T)) == typeof(int)
- || Enum.GetUnderlyingType(typeof(T)) == typeof(uint)
+ Debug.Assert(typeof(T).IsEnum
+ && (Enum.GetUnderlyingType(typeof(T)) == typeof(int)
+ || Enum.GetUnderlyingType(typeof(T)) == typeof(uint)
|| Enum.GetUnderlyingType(typeof(T)) == typeof(short)
|| Enum.GetUnderlyingType(typeof(T)) == typeof(ushort)
|| Enum.GetUnderlyingType(typeof(T)) == typeof(byte)
|| Enum.GetUnderlyingType(typeof(T)) == typeof(sbyte)),
- "Error, T must be an 4 byte (or less) enum JitHelpers.UnsafeEnumCast!");
+ "Error, T must be an 4 byte (or less) enum JitHelpers.UnsafeEnumCast!");
return UnsafeEnumCastInternal<T>(val);
}
@@ -134,9 +134,9 @@ namespace System.Runtime.CompilerServices {
static internal long UnsafeEnumCastLong<T>(T val) where T : struct // Actually T must be 8 byte enum
{
- Debug.Assert(typeof(T).IsEnum
- && (Enum.GetUnderlyingType(typeof(T)) == typeof(long)
- || Enum.GetUnderlyingType(typeof(T)) == typeof(ulong)),
+ Debug.Assert(typeof(T).IsEnum
+ && (Enum.GetUnderlyingType(typeof(T)) == typeof(long)
+ || Enum.GetUnderlyingType(typeof(T)) == typeof(ulong)),
"Error, T must be an 8 byte enum JitHelpers.UnsafeEnumCastLong!");
return UnsafeEnumCastLongInternal<T>(val);
}
@@ -213,7 +213,7 @@ namespace System.Runtime.CompilerServices {
#if _DEBUG
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- extern static bool IsAddressInStack(IntPtr ptr);
+ private extern static bool IsAddressInStack(IntPtr ptr);
#endif
static internal bool ByRefLessThan<T>(ref T refA, ref T refB)
@@ -223,14 +223,6 @@ namespace System.Runtime.CompilerServices {
throw new InvalidOperationException();
}
- /// <returns>true if given type is reference type or value type that contains references</returns>
- static internal bool ContainsReferences<T>()
- {
- // The body of this function will be replaced by the EE with unsafe code!!!
- // See getILIntrinsicImplementation for how this happens.
- throw new InvalidOperationException();
- }
-
static internal ref T GetArrayData<T>(T[] array)
{
// The body of this function will be replaced by the EE with unsafe code!!!
diff --git a/src/mscorlib/src/System/Runtime/ExceptionServices/CorruptingExceptionCommon.cs b/src/mscorlib/src/System/Runtime/ExceptionServices/CorruptingExceptionCommon.cs
index f04ddf065a..00067748f2 100644
--- a/src/mscorlib/src/System/Runtime/ExceptionServices/CorruptingExceptionCommon.cs
+++ b/src/mscorlib/src/System/Runtime/ExceptionServices/CorruptingExceptionCommon.cs
@@ -14,9 +14,10 @@
**
=============================================================================*/
-namespace System.Runtime.ExceptionServices {
- using System;
-
+using System;
+
+namespace System.Runtime.ExceptionServices
+{
// This attribute can be applied to methods to indicate that ProcessCorruptedState
// Exceptions should be delivered to them.
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
diff --git a/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionNotification.cs b/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionNotification.cs
index 1b3e25b8b2..d986ea9c24 100644
--- a/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionNotification.cs
+++ b/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionNotification.cs
@@ -1,22 +1,21 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// 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.
/*=============================================================================
**
-** File: ExceptionNotification.cs
**
**
** Purpose: Contains definitions for supporting Exception Notifications.
**
** Created: 10/07/2008
**
-** <owner>gkhanna</owner>
**
=============================================================================*/
-namespace System.Runtime.ExceptionServices {
- using System;
- using System.Runtime.ConstrainedExecution;
-
+using System;
+using System.Runtime.ConstrainedExecution;
+
+namespace System.Runtime.ExceptionServices
+{
// Definition of the argument-type passed to the FirstChanceException event handler
public class FirstChanceExceptionEventArgs : EventArgs
{
diff --git a/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionServicesCommon.cs b/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionServicesCommon.cs
index e8eb6916b7..8d5ced089f 100644
--- a/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionServicesCommon.cs
+++ b/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionServicesCommon.cs
@@ -15,9 +15,10 @@
**
=============================================================================*/
-namespace System.Runtime.ExceptionServices {
- using System;
-
+using System;
+
+namespace System.Runtime.ExceptionServices
+{
// This class defines support for seperating the exception dispatch details
// (like stack trace, watson buckets, etc) from the actual managed exception
// object. This allows us to track error (via the exception object) independent
@@ -34,13 +35,13 @@ namespace System.Runtime.ExceptionServices {
private object m_dynamicMethods;
private UIntPtr m_IPForWatsonBuckets;
private Object m_WatsonBuckets;
-
+
private ExceptionDispatchInfo(Exception exception)
{
// Copy over the details we need to save.
m_Exception = exception;
m_remoteStackTrace = exception.RemoteStackTrace;
-
+
// NOTE: don't be tempted to pass the fields for the out params; the containing object
// might be relocated during the call so the pointers will no longer be valid.
object stackTrace;
@@ -50,14 +51,14 @@ namespace System.Runtime.ExceptionServices {
m_dynamicMethods = dynamicMethods;
m_IPForWatsonBuckets = exception.IPForWatsonBuckets;
- m_WatsonBuckets = exception.WatsonBuckets;
+ m_WatsonBuckets = exception.WatsonBuckets;
}
internal UIntPtr IPForWatsonBuckets
{
get
{
- return m_IPForWatsonBuckets;
+ return m_IPForWatsonBuckets;
}
}
@@ -65,10 +66,10 @@ namespace System.Runtime.ExceptionServices {
{
get
{
- return m_WatsonBuckets;
+ return m_WatsonBuckets;
}
}
-
+
internal object BinaryStackTraceArray
{
get
@@ -100,22 +101,21 @@ namespace System.Runtime.ExceptionServices {
{
if (source == null)
{
- throw new ArgumentNullException(nameof(source), Environment.GetResourceString("ArgumentNull_Obj"));
+ throw new ArgumentNullException(nameof(source), SR.ArgumentNull_Obj);
}
-
+
return new ExceptionDispatchInfo(source);
}
-
+
// Return the exception object represented by this ExceptionDispatchInfo instance
public Exception SourceException
{
-
get
{
- return m_Exception;
+ return m_Exception;
}
}
-
+
// When a framework needs to "Rethrow" an exception on a thread different (but not necessarily so) from
// where it was thrown, it should invoke this method against the ExceptionDispatchInfo (EDI)
// created for the exception in question.
@@ -127,7 +127,11 @@ namespace System.Runtime.ExceptionServices {
{
// Restore the exception dispatch details before throwing the exception.
m_Exception.RestoreExceptionDispatchInfo(this);
- throw m_Exception;
+ throw m_Exception;
}
+
+ // Throws the source exception, maintaining the original bucketing details and augmenting
+ // rather than replacing the original stack trace.
+ public static void Throw(Exception source) => Capture(source).Throw();
}
}
diff --git a/src/mscorlib/src/System/Runtime/GcSettings.cs b/src/mscorlib/src/System/Runtime/GcSettings.cs
index 11143c5ee2..993a24f986 100644
--- a/src/mscorlib/src/System/Runtime/GcSettings.cs
+++ b/src/mscorlib/src/System/Runtime/GcSettings.cs
@@ -3,12 +3,13 @@
// See the LICENSE file in the project root for more information.
-namespace System.Runtime {
- using System;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Diagnostics.Contracts;
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Diagnostics.Contracts;
+namespace System.Runtime
+{
// These settings are the same format as in clr\src\vm\gcpriv.h
// make sure you change that file if you change this file!
@@ -22,34 +23,34 @@ namespace System.Runtime {
[Serializable]
public enum GCLatencyMode
{
- Batch = 0,
+ Batch = 0,
Interactive = 1,
LowLatency = 2,
SustainedLowLatency = 3,
NoGCRegion = 4
}
- public static class GCSettings
+ public static class GCSettings
{
- enum SetLatencyModeStatus
+ private enum SetLatencyModeStatus
{
Succeeded = 0,
NoGCInProgress = 1 // NoGCRegion is in progress, can't change pause mode.
};
-
+
public static GCLatencyMode LatencyMode
{
- get
+ get
{
return (GCLatencyMode)(GC.GetGCLatencyMode());
}
// We don't want to allow this API when hosted.
- set
+ set
{
if ((value < GCLatencyMode.Batch) || (value > GCLatencyMode.SustainedLowLatency))
{
- throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(SR.ArgumentOutOfRange_Enum);
}
Contract.EndContractBlock();
@@ -60,18 +61,18 @@ namespace System.Runtime {
public static GCLargeObjectHeapCompactionMode LargeObjectHeapCompactionMode
{
- get
+ get
{
return (GCLargeObjectHeapCompactionMode)(GC.GetLOHCompactionMode());
}
// We don't want to allow this API when hosted.
- set
+ set
{
- if ((value < GCLargeObjectHeapCompactionMode.Default) ||
+ if ((value < GCLargeObjectHeapCompactionMode.Default) ||
(value > GCLargeObjectHeapCompactionMode.CompactOnce))
{
- throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_Enum"));
+ throw new ArgumentOutOfRangeException(SR.ArgumentOutOfRange_Enum);
}
Contract.EndContractBlock();
@@ -79,11 +80,12 @@ namespace System.Runtime {
}
}
- public static bool IsServerGC
+ public static bool IsServerGC
{
- get {
+ get
+ {
return GC.IsServerGC();
}
- }
+ }
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ArrayWithOffset.cs b/src/mscorlib/src/System/Runtime/InteropServices/ArrayWithOffset.cs
index fc15f4e1a7..c4beb024b1 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ArrayWithOffset.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ArrayWithOffset.cs
@@ -2,12 +2,13 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Runtime.InteropServices {
- using System;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+namespace System.Runtime.InteropServices
+{
[Serializable]
public struct ArrayWithOffset
{
@@ -15,30 +16,30 @@ namespace System.Runtime.InteropServices {
//{
// throw new Exception();
//}
-
+
public ArrayWithOffset(Object array, int offset)
{
- m_array = array;
+ m_array = array;
m_offset = offset;
- m_count = 0;
- m_count = CalculateCount();
+ m_count = 0;
+ m_count = CalculateCount();
}
-
+
public Object GetArray()
{
return m_array;
}
-
+
public int GetOffset()
{
return m_offset;
}
-
+
public override int GetHashCode()
{
return m_count + m_offset;
}
-
+
public override bool Equals(Object obj)
{
if (obj is ArrayWithOffset)
@@ -51,12 +52,12 @@ namespace System.Runtime.InteropServices {
{
return obj.m_array == m_array && obj.m_offset == m_offset && obj.m_count == m_count;
}
-
+
public static bool operator ==(ArrayWithOffset a, ArrayWithOffset b)
{
return a.Equals(b);
}
-
+
public static bool operator !=(ArrayWithOffset a, ArrayWithOffset b)
{
return !(a == b);
@@ -64,10 +65,9 @@ namespace System.Runtime.InteropServices {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern int CalculateCount();
-
+
private Object m_array;
- private int m_offset;
- private int m_count;
+ private int m_offset;
+ private int m_count;
}
-
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/Attributes.cs b/src/mscorlib/src/System/Runtime/InteropServices/Attributes.cs
index b5bde22057..ccba51e840 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/Attributes.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/Attributes.cs
@@ -4,33 +4,14 @@
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
-namespace System.Runtime.InteropServices{
- using System;
- using System.Reflection;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- [AttributeUsage(AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
- public sealed class UnmanagedFunctionPointerAttribute : Attribute
- {
- CallingConvention m_callingConvention;
-
- public UnmanagedFunctionPointerAttribute(CallingConvention callingConvention) { m_callingConvention = callingConvention; }
-
- public CallingConvention CallingConvention { get { return m_callingConvention; } }
-
- public CharSet CharSet;
- public bool BestFitMapping;
- public bool ThrowOnUnmappableChar;
-
- // This field is ignored and marshaling behaves as if it was true (for historical reasons).
- public bool SetLastError;
-
- // P/Invoke via delegate always preserves signature, HRESULT swapping is not supported.
- //public bool PreserveSig;
- }
+using System;
+using System.Reflection;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+namespace System.Runtime.InteropServices
+{
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Struct | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
public sealed class TypeIdentifierAttribute : Attribute
{
@@ -118,7 +99,6 @@ namespace System.Runtime.InteropServices{
public ClassInterfaceAttribute(ClassInterfaceType classInterfaceType)
{
_val = classInterfaceType;
-
}
public ClassInterfaceAttribute(short classInterfaceType)
{
@@ -127,17 +107,6 @@ namespace System.Runtime.InteropServices{
public ClassInterfaceType Value { get { return _val; } }
}
- [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Delegate | AttributeTargets.Enum | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Property, Inherited = false)]
- public sealed class ComVisibleAttribute : Attribute
- {
- internal bool _val;
- public ComVisibleAttribute(bool visibility)
- {
- _val = visibility;
- }
- public bool Value { get { return _val; } }
- }
-
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public sealed class LCIDConversionAttribute : Attribute
{
@@ -146,7 +115,7 @@ namespace System.Runtime.InteropServices{
{
_val = lcid;
}
- public int Value { get {return _val;} }
+ public int Value { get { return _val; } }
}
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
@@ -157,10 +126,10 @@ namespace System.Runtime.InteropServices{
{
_val = progId;
}
- public String Value { get {return _val;} }
+ public String Value { get { return _val; } }
}
- [AttributeUsage(AttributeTargets.Class, Inherited = true)]
+ [AttributeUsage(AttributeTargets.Class, Inherited = true)]
public sealed class ComSourceInterfacesAttribute : Attribute
{
internal String _val;
@@ -184,137 +153,7 @@ namespace System.Runtime.InteropServices{
{
_val = sourceInterface1.FullName + "\0" + sourceInterface2.FullName + "\0" + sourceInterface3.FullName + "\0" + sourceInterface4.FullName;
}
- public String Value { get {return _val;} }
- }
-
- [Serializable]
- public enum VarEnum
- {
- VT_EMPTY = 0,
- VT_NULL = 1,
- VT_I2 = 2,
- VT_I4 = 3,
- VT_R4 = 4,
- VT_R8 = 5,
- VT_CY = 6,
- VT_DATE = 7,
- VT_BSTR = 8,
- VT_DISPATCH = 9,
- VT_ERROR = 10,
- VT_BOOL = 11,
- VT_VARIANT = 12,
- VT_UNKNOWN = 13,
- VT_DECIMAL = 14,
- VT_I1 = 16,
- VT_UI1 = 17,
- VT_UI2 = 18,
- VT_UI4 = 19,
- VT_I8 = 20,
- VT_UI8 = 21,
- VT_INT = 22,
- VT_UINT = 23,
- VT_VOID = 24,
- VT_HRESULT = 25,
- VT_PTR = 26,
- VT_SAFEARRAY = 27,
- VT_CARRAY = 28,
- VT_USERDEFINED = 29,
- VT_LPSTR = 30,
- VT_LPWSTR = 31,
- VT_RECORD = 36,
- VT_FILETIME = 64,
- VT_BLOB = 65,
- VT_STREAM = 66,
- VT_STORAGE = 67,
- VT_STREAMED_OBJECT = 68,
- VT_STORED_OBJECT = 69,
- VT_BLOB_OBJECT = 70,
- VT_CF = 71,
- VT_CLSID = 72,
- VT_VECTOR = 0x1000,
- VT_ARRAY = 0x2000,
- VT_BYREF = 0x4000
- }
-
- [Serializable]
- // Note that this enum should remain in-sync with the CorNativeType enum in corhdr.h
- public enum UnmanagedType
- {
- Bool = 0x2, // 4 byte boolean value (true != 0, false == 0)
-
- I1 = 0x3, // 1 byte signed value
-
- U1 = 0x4, // 1 byte unsigned value
-
- I2 = 0x5, // 2 byte signed value
-
- U2 = 0x6, // 2 byte unsigned value
-
- I4 = 0x7, // 4 byte signed value
-
- U4 = 0x8, // 4 byte unsigned value
-
- I8 = 0x9, // 8 byte signed value
-
- U8 = 0xa, // 8 byte unsigned value
-
- R4 = 0xb, // 4 byte floating point
-
- R8 = 0xc, // 8 byte floating point
-
- Currency = 0xf, // A currency
-
- BStr = 0x13, // OLE Unicode BSTR
-
- LPStr = 0x14, // Ptr to SBCS string
-
- LPWStr = 0x15, // Ptr to Unicode string
-
- LPTStr = 0x16, // Ptr to OS preferred (SBCS/Unicode) string
-
- ByValTStr = 0x17, // OS preferred (SBCS/Unicode) inline string (only valid in structs)
-
- IUnknown = 0x19, // COM IUnknown pointer.
-
- IDispatch = 0x1a, // COM IDispatch pointer
-
- Struct = 0x1b, // Structure
-
- Interface = 0x1c, // COM interface
-
- SafeArray = 0x1d, // OLE SafeArray
-
- ByValArray = 0x1e, // Array of fixed size (only valid in structs)
-
- SysInt = 0x1f, // Hardware natural sized signed integer
-
- SysUInt = 0x20,
-
- VBByRefStr = 0x22,
-
- AnsiBStr = 0x23, // OLE BSTR containing SBCS characters
-
- TBStr = 0x24, // Ptr to OS preferred (SBCS/Unicode) BSTR
-
- VariantBool = 0x25, // OLE defined BOOLEAN (2 bytes, true == -1, false == 0)
-
- FunctionPtr = 0x26, // Function pointer
-
- AsAny = 0x28, // Paired with Object type and does runtime marshalling determination
-
- LPArray = 0x2a, // C style array
-
- LPStruct = 0x2b, // Pointer to a structure
-
- CustomMarshaler = 0x2c,
-
- Error = 0x2d,
-
- IInspectable = 0x2e,
-
- HString = 0x2f, // Windows Runtime HSTRING
-
- LPUTF8Str = 0x30, // UTF8 string
+ public String Value { get { return _val; } }
}
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.ReturnValue, Inherited = false)]
@@ -403,11 +242,11 @@ namespace System.Runtime.InteropServices{
public UnmanagedType Value { get { return _val; } }
// Fields used with SubType = SafeArray.
- public VarEnum SafeArraySubType;
- public Type SafeArrayUserDefinedSubType;
+ public VarEnum SafeArraySubType;
+ public Type SafeArrayUserDefinedSubType;
// Field used with iid_is attribute (interface pointers).
- public int IidParameterIndex;
+ public int IidParameterIndex;
// Fields used with SubType = ByValArray and LPArray.
// Array size = parameter(PI) * PM + C
@@ -639,7 +478,6 @@ namespace System.Runtime.InteropServices{
public CallingConvention CallingConvention;
public bool BestFitMapping;
public bool ThrowOnUnmappableChar;
-
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)]
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/BStrWrapper.cs b/src/mscorlib/src/System/Runtime/InteropServices/BStrWrapper.cs
index d36f8cfa39..77c38139cd 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/BStrWrapper.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/BStrWrapper.cs
@@ -11,11 +11,12 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
-
- using System;
- using System.Security;
+using System;
+using System.Security;
+
+namespace System.Runtime.InteropServices
+{
[Serializable]
public sealed class BStrWrapper
{
@@ -29,9 +30,9 @@ namespace System.Runtime.InteropServices {
m_WrappedObject = (String)value;
}
- public String WrappedObject
+ public String WrappedObject
{
- get
+ get
{
return m_WrappedObject;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/COMException.cs b/src/mscorlib/src/System/Runtime/InteropServices/COMException.cs
index 87e6be6d4e..889a74f6bc 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/COMException.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/COMException.cs
@@ -12,55 +12,63 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
- using System;
- using System.Runtime.Serialization;
- using System.Globalization;
- using System.Security;
- using Microsoft.Win32;
+using System;
+using System.Runtime.Serialization;
+using System.Globalization;
+using System.Security;
+using Microsoft.Win32;
+namespace System.Runtime.InteropServices
+{
// Exception for COM Interop errors where we don't recognize the HResult.
//
[Serializable]
- public class COMException : ExternalException {
- public COMException()
- : base(Environment.GetResourceString("Arg_COMException"))
+ public class COMException : ExternalException
+ {
+ public COMException()
+ : base(SR.Arg_COMException)
{
- SetErrorCode(__HResults.E_FAIL);
+ HResult = __HResults.E_FAIL;
}
-
- public COMException(String message)
+
+ public COMException(String message)
: base(message)
{
- SetErrorCode(__HResults.E_FAIL);
+ HResult = __HResults.E_FAIL;
}
-
- public COMException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.E_FAIL);
+
+ public COMException(String message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.E_FAIL;
}
-
- public COMException(String message,int errorCode)
- : base(message) {
- SetErrorCode(errorCode);
+
+ public COMException(String message, int errorCode)
+ : base(message)
+ {
+ HResult = errorCode;
}
- protected COMException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ protected COMException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
}
- public override String ToString() {
+ public override String ToString()
+ {
String message = Message;
String s;
String _className = GetType().ToString();
s = _className + " (0x" + HResult.ToString("X8", CultureInfo.InvariantCulture) + ")";
- if (!(message == null || message.Length <= 0)) {
+ if (!(message == null || message.Length <= 0))
+ {
s = s + ": " + message;
}
Exception _innerException = InnerException;
- if (_innerException!=null) {
+ if (_innerException != null)
+ {
s = s + " ---> " + _innerException.ToString();
}
@@ -70,7 +78,5 @@ namespace System.Runtime.InteropServices {
return s;
}
-
-
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/CallingConvention.cs b/src/mscorlib/src/System/Runtime/InteropServices/CallingConvention.cs
deleted file mode 100644
index 2ef1cf496e..0000000000
--- a/src/mscorlib/src/System/Runtime/InteropServices/CallingConvention.cs
+++ /dev/null
@@ -1,21 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-namespace System.Runtime.InteropServices {
-
- using System;
- // Used for the CallingConvention named argument to the DllImport attribute
- [Serializable]
- public enum CallingConvention
- {
- Winapi = 1,
- Cdecl = 2,
- StdCall = 3,
- ThisCall = 4,
- FastCall = 5,
- }
-
-}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/CharSet.cs b/src/mscorlib/src/System/Runtime/InteropServices/CharSet.cs
deleted file mode 100644
index e60d676557..0000000000
--- a/src/mscorlib/src/System/Runtime/InteropServices/CharSet.cs
+++ /dev/null
@@ -1,23 +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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-namespace System.Runtime.InteropServices {
- using System;
- // Use this in P/Direct function prototypes to specify
- // which character set to use when marshalling Strings.
- // Using Ansi will marshal the strings as 1 byte char*'s.
- // Using Unicode will marshal the strings as 2 byte wchar*'s.
- // Generally you probably want to use Auto, which does the
- // right thing 99% of the time.
- [Serializable]
- public enum CharSet
- {
- None = 1, // User didn't specify how to marshal strings.
- Ansi = 2, // Strings should be marshalled as ANSI 1 byte chars.
- Unicode = 3, // Strings should be marshalled as Unicode 2 byte chars.
- Auto = 4, // Marshal Strings in the right way for the target system.
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsHelper.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsHelper.cs
index 82692c1c54..8198d9fd18 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsHelper.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsHelper.cs
@@ -10,104 +10,105 @@
** managed delegates to COM's connection point based events.
**
**/
-namespace System.Runtime.InteropServices {
- //
- // #ComEventsFeature
- //
- // code:#ComEventsFeature defines two public methods allowing to add/remove .NET delegates handling
- // events from COM objects. Those methods are defined as part of code:ComEventsHelper static class
- // * code:ComEventsHelper.Combine - will create/reuse-an-existing COM event sink and register the
- // specified delegate to be raised when corresponding COM event is raised
- // * code:ComEventsHelper.Remove
- //
- //
- // To bind an event handler to the COM object you need to provide the following data:
- // * rcw - the instance of the COM object you want to bind to
- // * iid - Guid of the source interface you want the sink to implement
- // * dispid - dispatch identifier of the event on the source interface you are interested in
- // * d - delegate to invoked when corresponding COM event is raised.
- //
- // #ComEventsArchitecture:
- // In COM world, events are handled by so-called event sinks. What these are? COM-based Object Models
- // (OMs) define "source" interfaces that need to be implemented by the COM clients to receive events. So,
- // event sinks are COM objects implementing a source interfaces. Once an event sink is passed to the COM
- // server (through a mechanism known as 'binding/advising to connection point'), COM server will be
- // calling source interface methods to "fire events" (advising, connection points, firing events etc. -
- // is all COM jargon).
- //
- // There are few interesting obervations about source interfaces. Usually source interfaces are defined
- // as 'dispinterface' - meaning that only late-bound invocations on this interface are allowed. Even
- // though it is not illegal to use early bound invocations on source interfaces - the practice is
- // discouraged because of versioning concerns.
- //
- // Notice also that each COM server object might define multiple source interfaces and hence have
- // multiple connection points (each CP handles exactly one source interface). COM objects that want to
- // fire events are required to implement IConnectionPointContainer interface which is used by the COM
- // clients to discovery connection poitns - objects implementing IConnectionPoint interface. Once
- // connection point is found - clients can bind to it using IConnectionPoint::Advise (see
- // code:ComEventsSink.Advise).
- //
- // The idea behind code:#ComEventsFeature is to write a "universal event sink" COM component that is
- // generic enough to handle all late-bound event firings and invoke corresponding COM delegates (through
- // reflection).
- //
- // When delegate is registered (using code:ComEventsHelper.Combine) we will verify we have corresponding
- // event sink created and bound.
- //
- // But what happens when COM events are fired? code:ComEventsSink.Invoke implements IDispatch::Invoke method
- // and this is the entry point that is called. Once our event sink is invoked, we need to find the
- // corresponding delegate to invoke . We need to match the dispid of the call that is coming in to a
- // dispid of .NET delegate that has been registered for this object. Once this is found we do call the
- // delegates using reflection (code:ComEventsMethod.Invoke).
- //
- // #ComEventsArgsMarshalling
- // Notice, that we may not have a delegate registered against every method on the source interface. If we
- // were to marshal all the input parameters for methods that do not reach user code - we would end up
- // generatic RCWs that are not reachable for user code (the inconvenience it might create is there will
- // be RCWs that users can not call Marshal.ReleaseComObject on to explicitly manage the lifetime of these
- // COM objects). The above behavior was one of the shortcoimings of legacy TLBIMP's implementation of COM
- // event sinking. In our code we will not marshal any data if there is no delegate registered to handle
- // the event. (code:ComEventsMethod.Invoke)
- //
- // #ComEventsFinalization:
- // Additional area of interest is when COM sink should be unadvised from the connection point. Legacy
- // TLBIMP's implementation of COM event sinks will unadvises the sink when corresponding RCW is GCed.
- // This is achieved by rooting the event sinks in a finalizable object stored in RCW's property bag
- // (using Marshal.SetComObjectData). Hence, once RCW is no longer reachable - the finalizer is called and
- // it would unadvise all the event sinks. We are employing the same strategy here. See storing an
- // instance in the RCW at code:ComEventsInfo.FromObject and undadvsing the sinks at
- // code:ComEventsInfo.~ComEventsInfo
- //
- // Classes of interest:
- // * code:ComEventsHelpers - defines public methods but there are also a number of internal classes that
- // implement the actual COM event sink:
- // * code:ComEventsInfo - represents a finalizable container for all event sinks for a particular RCW.
- // Lifetime of this instance corresponds to the lifetime of the RCW object
- // * code:ComEventsSink - represents a single event sink. Maintains an internal pointer to the next
- // instance (in a singly linked list). A collection of code:ComEventsSink is stored at
- // code:ComEventsInfo._sinks
- // * code:ComEventsMethod - represents a single method from the source interface which has .NET delegates
- // attached to it. Maintains an internal pointer to the next instance (in a singly linked list). A
- // collection of code:ComEventMethod is stored at code:ComEventsSink._methods
- //
- // #ComEventsRetValIssue:
- // Issue: normally, COM events would not return any value. However, it may happen as described in
- // http://support.microsoft.com/kb/810228. Such design might represent a problem for us - e.g. what is
- // the return value of a chain of delegates - is it the value of the last call in the chain or the the
- // first one? As the above KB article indicates, in cases where OM has events returning values, it is
- // suggested that people implement their event sink by explicitly implementing the source interface. This
- // means that the problem is already quite complex and we should not be dealing with it - see
- // code:ComEventsMethod.Invoke
-
- using System;
- using System.Runtime.Remoting;
-
+//
+// #ComEventsFeature
+//
+// code:#ComEventsFeature defines two public methods allowing to add/remove .NET delegates handling
+// events from COM objects. Those methods are defined as part of code:ComEventsHelper static class
+// * code:ComEventsHelper.Combine - will create/reuse-an-existing COM event sink and register the
+// specified delegate to be raised when corresponding COM event is raised
+// * code:ComEventsHelper.Remove
+//
+//
+// To bind an event handler to the COM object you need to provide the following data:
+// * rcw - the instance of the COM object you want to bind to
+// * iid - Guid of the source interface you want the sink to implement
+// * dispid - dispatch identifier of the event on the source interface you are interested in
+// * d - delegate to invoked when corresponding COM event is raised.
+//
+// #ComEventsArchitecture:
+// In COM world, events are handled by so-called event sinks. What these are? COM-based Object Models
+// (OMs) define "source" interfaces that need to be implemented by the COM clients to receive events. So,
+// event sinks are COM objects implementing a source interfaces. Once an event sink is passed to the COM
+// server (through a mechanism known as 'binding/advising to connection point'), COM server will be
+// calling source interface methods to "fire events" (advising, connection points, firing events etc. -
+// is all COM jargon).
+//
+// There are few interesting obervations about source interfaces. Usually source interfaces are defined
+// as 'dispinterface' - meaning that only late-bound invocations on this interface are allowed. Even
+// though it is not illegal to use early bound invocations on source interfaces - the practice is
+// discouraged because of versioning concerns.
+//
+// Notice also that each COM server object might define multiple source interfaces and hence have
+// multiple connection points (each CP handles exactly one source interface). COM objects that want to
+// fire events are required to implement IConnectionPointContainer interface which is used by the COM
+// clients to discovery connection poitns - objects implementing IConnectionPoint interface. Once
+// connection point is found - clients can bind to it using IConnectionPoint::Advise (see
+// code:ComEventsSink.Advise).
+//
+// The idea behind code:#ComEventsFeature is to write a "universal event sink" COM component that is
+// generic enough to handle all late-bound event firings and invoke corresponding COM delegates (through
+// reflection).
+//
+// When delegate is registered (using code:ComEventsHelper.Combine) we will verify we have corresponding
+// event sink created and bound.
+//
+// But what happens when COM events are fired? code:ComEventsSink.Invoke implements IDispatch::Invoke method
+// and this is the entry point that is called. Once our event sink is invoked, we need to find the
+// corresponding delegate to invoke . We need to match the dispid of the call that is coming in to a
+// dispid of .NET delegate that has been registered for this object. Once this is found we do call the
+// delegates using reflection (code:ComEventsMethod.Invoke).
+//
+// #ComEventsArgsMarshalling
+// Notice, that we may not have a delegate registered against every method on the source interface. If we
+// were to marshal all the input parameters for methods that do not reach user code - we would end up
+// generatic RCWs that are not reachable for user code (the inconvenience it might create is there will
+// be RCWs that users can not call Marshal.ReleaseComObject on to explicitly manage the lifetime of these
+// COM objects). The above behavior was one of the shortcoimings of legacy TLBIMP's implementation of COM
+// event sinking. In our code we will not marshal any data if there is no delegate registered to handle
+// the event. (code:ComEventsMethod.Invoke)
+//
+// #ComEventsFinalization:
+// Additional area of interest is when COM sink should be unadvised from the connection point. Legacy
+// TLBIMP's implementation of COM event sinks will unadvises the sink when corresponding RCW is GCed.
+// This is achieved by rooting the event sinks in a finalizable object stored in RCW's property bag
+// (using Marshal.SetComObjectData). Hence, once RCW is no longer reachable - the finalizer is called and
+// it would unadvise all the event sinks. We are employing the same strategy here. See storing an
+// instance in the RCW at code:ComEventsInfo.FromObject and undadvsing the sinks at
+// code:ComEventsInfo.~ComEventsInfo
+//
+// Classes of interest:
+// * code:ComEventsHelpers - defines public methods but there are also a number of internal classes that
+// implement the actual COM event sink:
+// * code:ComEventsInfo - represents a finalizable container for all event sinks for a particular RCW.
+// Lifetime of this instance corresponds to the lifetime of the RCW object
+// * code:ComEventsSink - represents a single event sink. Maintains an internal pointer to the next
+// instance (in a singly linked list). A collection of code:ComEventsSink is stored at
+// code:ComEventsInfo._sinks
+// * code:ComEventsMethod - represents a single method from the source interface which has .NET delegates
+// attached to it. Maintains an internal pointer to the next instance (in a singly linked list). A
+// collection of code:ComEventMethod is stored at code:ComEventsSink._methods
+//
+// #ComEventsRetValIssue:
+// Issue: normally, COM events would not return any value. However, it may happen as described in
+// http://support.microsoft.com/kb/810228. Such design might represent a problem for us - e.g. what is
+// the return value of a chain of delegates - is it the value of the last call in the chain or the the
+// first one? As the above KB article indicates, in cases where OM has events returning values, it is
+// suggested that people implement their event sink by explicitly implementing the source interface. This
+// means that the problem is already quite complex and we should not be dealing with it - see
+// code:ComEventsMethod.Invoke
+
+using System;
+using System.Runtime.Remoting;
+
+namespace System.Runtime.InteropServices
+{
/// <summary>
/// The static methods provided in ComEventsHelper allow using .NET delegates to subscribe to events
/// raised COM objects.
/// </summary>
- public static class ComEventsHelper {
-
+ public static class ComEventsHelper
+ {
/// <summary>
/// Adds a delegate to the invocation list of events originating from the COM object.
/// </summary>
@@ -115,21 +116,24 @@ namespace System.Runtime.InteropServices {
/// <param name="iid">identifier of the source interface used by COM object to fire events</param>
/// <param name="dispid">dispatch identifier of the method on the source interface</param>
/// <param name="d">delegate to invoke when specifed COM event is fired</param>
- public static void Combine(object rcw, Guid iid, int dispid, System.Delegate d) {
-
+ public static void Combine(object rcw, Guid iid, int dispid, System.Delegate d)
+ {
rcw = UnwrapIfTransparentProxy(rcw);
- lock (rcw) {
+ lock (rcw)
+ {
ComEventsInfo eventsInfo = ComEventsInfo.FromObject(rcw);
ComEventsSink sink = eventsInfo.FindSink(ref iid);
- if (sink == null) {
+ if (sink == null)
+ {
sink = eventsInfo.AddSink(ref iid);
}
ComEventsMethod method = sink.FindMethod(dispid);
- if (method == null) {
+ if (method == null)
+ {
method = sink.AddMethod(dispid);
}
@@ -145,12 +149,12 @@ namespace System.Runtime.InteropServices {
/// <param name="dispid">dispatch identifier of the method on the source interface</param>
/// <param name="d">delegate to remove from the invocation list</param>
/// <returns></returns>
- public static Delegate Remove(object rcw, Guid iid, int dispid, System.Delegate d) {
-
+ public static Delegate Remove(object rcw, Guid iid, int dispid, System.Delegate d)
+ {
rcw = UnwrapIfTransparentProxy(rcw);
- lock (rcw) {
-
+ lock (rcw)
+ {
ComEventsInfo eventsInfo = ComEventsInfo.Find(rcw);
if (eventsInfo == null)
return null;
@@ -163,15 +167,18 @@ namespace System.Runtime.InteropServices {
method.RemoveDelegate(d);
- if (method.Empty) {
+ if (method.Empty)
+ {
// removed the last event handler for this dispid - need to remove dispid handler
method = sink.RemoveMethod(method);
}
- if (method == null) {
+ if (method == null)
+ {
// removed last dispid handler for this sink - need to remove the sink
sink = eventsInfo.RemoveSink(sink);
}
- if (sink == null) {
+ if (sink == null)
+ {
// removed last sink for this rcw - need to remove all traces of event info
Marshal.SetComObjectData(rcw, typeof(ComEventsInfo), null);
GC.SuppressFinalize(eventsInfo);
@@ -186,5 +193,4 @@ namespace System.Runtime.InteropServices {
return rcw;
}
}
-
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsInfo.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsInfo.cs
index 2456ba35bf..0fbe34db8d 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsInfo.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsInfo.cs
@@ -11,64 +11,70 @@
**
**/
-namespace System.Runtime.InteropServices {
-
+namespace System.Runtime.InteropServices
+{
using System;
using ComTypes = System.Runtime.InteropServices.ComTypes;
// see code:ComEventsHelper#ComEventsArchitecture
- internal class ComEventsInfo {
-
-
-#region fields
+ internal class ComEventsInfo
+ {
+ #region fields
private ComEventsSink _sinks;
private object _rcw;
-#endregion
+ #endregion
-#region ctor/dtor
+ #region ctor/dtor
- ComEventsInfo(object rcw) {
+ private ComEventsInfo(object rcw)
+ {
_rcw = rcw;
}
- ~ComEventsInfo() {
+ ~ComEventsInfo()
+ {
// see code:ComEventsHelper#ComEventsFinalization
_sinks = ComEventsSink.RemoveAll(_sinks);
}
-#endregion
+ #endregion
-#region static methods
+ #region static methods
- internal static ComEventsInfo Find(object rcw) {
+ internal static ComEventsInfo Find(object rcw)
+ {
return (ComEventsInfo)Marshal.GetComObjectData(rcw, typeof(ComEventsInfo));
}
// it is caller's responsibility to call this method under lock(rcw)
- internal static ComEventsInfo FromObject(object rcw) {
+ internal static ComEventsInfo FromObject(object rcw)
+ {
ComEventsInfo eventsInfo = Find(rcw);
- if (eventsInfo == null) {
+ if (eventsInfo == null)
+ {
eventsInfo = new ComEventsInfo(rcw);
Marshal.SetComObjectData(rcw, typeof(ComEventsInfo), eventsInfo);
}
return eventsInfo;
}
-#endregion
+ #endregion
-#region internal methods
+ #region internal methods
- internal ComEventsSink FindSink(ref Guid iid) {
+ internal ComEventsSink FindSink(ref Guid iid)
+ {
return ComEventsSink.Find(_sinks, ref iid);
}
// it is caller's responsibility to call this method under lock(rcw)
- internal ComEventsSink AddSink(ref Guid iid) {
+ internal ComEventsSink AddSink(ref Guid iid)
+ {
ComEventsSink sink = new ComEventsSink(_rcw, iid);
_sinks = ComEventsSink.Add(_sinks, sink);
@@ -76,12 +82,12 @@ namespace System.Runtime.InteropServices {
}
// it is caller's responsibility to call this method under lock(rcw)
- internal ComEventsSink RemoveSink(ComEventsSink sink) {
+ internal ComEventsSink RemoveSink(ComEventsSink sink)
+ {
_sinks = ComEventsSink.Remove(_sinks, sink);
return _sinks;
}
-#endregion
-
+ #endregion
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsMethod.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsMethod.cs
index c2f56b0580..f7e84cabb5 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsMethod.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsMethod.cs
@@ -10,6 +10,7 @@
** managed delegates to COM's connection point based events.
**
**/
+
using System;
using System.Collections.Generic;
using System.Text;
@@ -18,11 +19,11 @@ using System.Runtime.InteropServices;
using System.Reflection;
-namespace System.Runtime.InteropServices {
-
+namespace System.Runtime.InteropServices
+{
// see code:ComEventsHelper#ComEventsArchitecture
- internal class ComEventsMethod {
-
+ internal class ComEventsMethod
+ {
// This delegate wrapper class handles dynamic invocation of delegates. The reason for the wrapper's
// existence is that under certain circumstances we need to coerce arguments to types expected by the
// delegates signature. Normally, reflection (Delegate.DynamicInvoke) handles types coercion
@@ -30,18 +31,21 @@ namespace System.Runtime.InteropServices {
// reflection by design does not do the coercion. Since we need to be compatible with COM interop
// handling of this scenario - we are pre-processing delegate's signature by looking for 'ref enums'
// and cache the types required for such coercion.
- internal class DelegateWrapper {
+ internal class DelegateWrapper
+ {
private Delegate _d;
private bool _once = false;
private int _expectedParamsCount;
private Type[] _cachedTargetTypes;
- public DelegateWrapper(Delegate d) {
+ public DelegateWrapper(Delegate d)
+ {
_d = d;
}
- public Delegate Delegate {
+ public Delegate Delegate
+ {
get { return _d; }
set { _d = value; }
}
@@ -54,42 +58,50 @@ namespace System.Runtime.InteropServices {
/// Since multicast delegate's built-in chaining supports only chaining instances of the same type,
/// we need to complement this design by using an explicit linked list data structure.
/// </summary>
- private DelegateWrapper [] _delegateWrappers;
+ private DelegateWrapper[] _delegateWrappers;
private int _dispid;
private ComEventsMethod _next;
#endregion
-
+
#region ctor
-
- internal ComEventsMethod(int dispid) {
+
+ internal ComEventsMethod(int dispid)
+ {
_delegateWrappers = null;
_dispid = dispid;
}
-
+
#endregion
-
+
#region static internal methods
-
- internal static ComEventsMethod Find(ComEventsMethod methods, int dispid) {
- while (methods != null && methods._dispid != dispid) {
+
+ internal static ComEventsMethod Find(ComEventsMethod methods, int dispid)
+ {
+ while (methods != null && methods._dispid != dispid)
+ {
methods = methods._next;
}
return methods;
}
- internal static ComEventsMethod Add(ComEventsMethod methods, ComEventsMethod method) {
+ internal static ComEventsMethod Add(ComEventsMethod methods, ComEventsMethod method)
+ {
method._next = methods;
return method;
}
- internal static ComEventsMethod Remove(ComEventsMethod methods, ComEventsMethod method) {
- if (methods == method) {
+ internal static ComEventsMethod Remove(ComEventsMethod methods, ComEventsMethod method)
+ {
+ if (methods == method)
+ {
methods = methods._next;
- } else {
+ }
+ else
+ {
ComEventsMethod current = methods;
while (current != null && current._next != method)
current = current._next;
@@ -100,28 +112,34 @@ namespace System.Runtime.InteropServices {
return methods;
}
-#endregion
-#region public properties / methods
+ #endregion
+ #region public properties / methods
- internal bool Empty {
+ internal bool Empty
+ {
get { return _delegateWrappers == null || _delegateWrappers.Length == 0; }
}
- internal void AddDelegate(Delegate d) {
+ internal void AddDelegate(Delegate d)
+ {
int count = 0;
- if (_delegateWrappers != null) {
+ if (_delegateWrappers != null)
+ {
count = _delegateWrappers.Length;
}
- for (int i = 0; i < count; i++) {
- if (_delegateWrappers[i].Delegate.GetType() == d.GetType()) {
+ for (int i = 0; i < count; i++)
+ {
+ if (_delegateWrappers[i].Delegate.GetType() == d.GetType())
+ {
_delegateWrappers[i].Delegate = Delegate.Combine(_delegateWrappers[i].Delegate, d);
return;
}
}
- DelegateWrapper [] newDelegateWrappers = new DelegateWrapper[count + 1];
- if (count > 0) {
+ DelegateWrapper[] newDelegateWrappers = new DelegateWrapper[count + 1];
+ if (count > 0)
+ {
_delegateWrappers.CopyTo(newDelegateWrappers, 0);
}
@@ -131,13 +149,15 @@ namespace System.Runtime.InteropServices {
_delegateWrappers = newDelegateWrappers;
}
- internal void RemoveDelegate(Delegate d) {
-
+ internal void RemoveDelegate(Delegate d)
+ {
int count = _delegateWrappers.Length;
int removeIdx = -1;
- for (int i = 0; i < count; i++) {
- if (_delegateWrappers[i].Delegate.GetType() == d.GetType()) {
+ for (int i = 0; i < count; i++)
+ {
+ if (_delegateWrappers[i].Delegate.GetType() == d.GetType())
+ {
removeIdx = i;
break;
}
@@ -147,25 +167,29 @@ namespace System.Runtime.InteropServices {
return;
Delegate newDelegate = Delegate.Remove(_delegateWrappers[removeIdx].Delegate, d);
- if (newDelegate != null) {
+ if (newDelegate != null)
+ {
_delegateWrappers[removeIdx].Delegate = newDelegate;
return;
}
// now remove the found entry from the _delegates array
- if (count == 1) {
+ if (count == 1)
+ {
_delegateWrappers = null;
return;
}
- DelegateWrapper [] newDelegateWrappers = new DelegateWrapper[count - 1];
+ DelegateWrapper[] newDelegateWrappers = new DelegateWrapper[count - 1];
int j = 0;
- while (j < removeIdx) {
+ while (j < removeIdx)
+ {
newDelegateWrappers[j] = _delegateWrappers[j];
j++;
}
- while (j < count-1) {
+ while (j < count - 1)
+ {
newDelegateWrappers[j] = _delegateWrappers[j + 1];
j++;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsSink.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsSink.cs
index f2b22e3ceb..08f27dc038 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComEventsSink.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComEventsSink.cs
@@ -11,14 +11,15 @@
**
**/
-namespace System.Runtime.InteropServices {
- using System;
- using System.Diagnostics;
+using System;
+using System.Diagnostics;
+namespace System.Runtime.InteropServices
+{
// see code:ComEventsHelper#ComEventsArchitecture
internal class ComEventsSink : ICustomQueryInterface
{
-#region private fields
+ #region private fields
private Guid _iidSourceItf;
private ComTypes.IConnectionPoint _connectionPoint;
@@ -26,38 +27,43 @@ namespace System.Runtime.InteropServices {
private ComEventsMethod _methods;
private ComEventsSink _next;
-#endregion
+ #endregion
-
-#region ctor
- internal ComEventsSink(object rcw, Guid iid) {
+ #region ctor
+
+ internal ComEventsSink(object rcw, Guid iid)
+ {
_iidSourceItf = iid;
this.Advise(rcw);
- }
+ }
-#endregion
+ #endregion
-
-#region static members
- internal static ComEventsSink Find(ComEventsSink sinks, ref Guid iid) {
+ #region static members
+ internal static ComEventsSink Find(ComEventsSink sinks, ref Guid iid)
+ {
ComEventsSink sink = sinks;
- while (sink != null && sink._iidSourceItf != iid) {
+ while (sink != null && sink._iidSourceItf != iid)
+ {
sink = sink._next;
}
return sink;
}
- internal static ComEventsSink Add(ComEventsSink sinks, ComEventsSink sink) {
+ internal static ComEventsSink Add(ComEventsSink sinks, ComEventsSink sink)
+ {
sink._next = sinks;
return sink;
}
- internal static ComEventsSink RemoveAll(ComEventsSink sinks) {
- while (sinks != null) {
+ internal static ComEventsSink RemoveAll(ComEventsSink sinks)
+ {
+ while (sinks != null)
+ {
sinks.Unadvise();
sinks = sinks._next;
}
@@ -65,18 +71,23 @@ namespace System.Runtime.InteropServices {
return null;
}
- internal static ComEventsSink Remove(ComEventsSink sinks, ComEventsSink sink) {
+ internal static ComEventsSink Remove(ComEventsSink sinks, ComEventsSink sink)
+ {
BCLDebug.Assert(sinks != null, "removing event sink from empty sinks collection");
BCLDebug.Assert(sink != null, "specify event sink is null");
- if (sink == sinks) {
+ if (sink == sinks)
+ {
sinks = sinks._next;
- } else {
+ }
+ else
+ {
ComEventsSink current = sinks;
while (current != null && current._next != sink)
current = current._next;
- if (current != null) {
+ if (current != null)
+ {
current._next = sink._next;
}
}
@@ -84,35 +95,40 @@ namespace System.Runtime.InteropServices {
sink.Unadvise();
return sinks;
- }
+ }
-#endregion
+ #endregion
-#region public methods
+ #region public methods
- public ComEventsMethod RemoveMethod(ComEventsMethod method) {
+ public ComEventsMethod RemoveMethod(ComEventsMethod method)
+ {
_methods = ComEventsMethod.Remove(_methods, method);
return _methods;
}
- public ComEventsMethod FindMethod(int dispid) {
+ public ComEventsMethod FindMethod(int dispid)
+ {
return ComEventsMethod.Find(_methods, dispid);
}
- public ComEventsMethod AddMethod(int dispid) {
+ public ComEventsMethod AddMethod(int dispid)
+ {
ComEventsMethod method = new ComEventsMethod(dispid);
_methods = ComEventsMethod.Add(_methods, method);
return method;
- }
+ }
-#endregion
+ #endregion
- static Guid IID_IManagedObject = new Guid("{C3FCC19E-A970-11D2-8B5A-00A0C9B7C9C4}");
+ private static Guid IID_IManagedObject = new Guid("{C3FCC19E-A970-11D2-8B5A-00A0C9B7C9C4}");
- CustomQueryInterfaceResult ICustomQueryInterface.GetInterface(ref Guid iid, out IntPtr ppv) {
+ CustomQueryInterfaceResult ICustomQueryInterface.GetInterface(ref Guid iid, out IntPtr ppv)
+ {
ppv = IntPtr.Zero;
- if (iid == this._iidSourceItf || iid == typeof(NativeMethods.IDispatch).GUID) {
+ if (iid == _iidSourceItf || iid == typeof(NativeMethods.IDispatch).GUID)
+ {
ppv = Marshal.GetComInterfaceForObject(this, typeof(NativeMethods.IDispatch), CustomQueryInterfaceMode.Ignore);
return CustomQueryInterfaceResult.Handled;
}
@@ -124,10 +140,11 @@ namespace System.Runtime.InteropServices {
return CustomQueryInterfaceResult.NotHandled;
}
-#region private methods
+ #region private methods
- private void Advise(object rcw) {
+ private void Advise(object rcw)
+ {
BCLDebug.Assert(_connectionPoint == null, "comevent sink is already advised");
ComTypes.IConnectionPointContainer cpc = (ComTypes.IConnectionPointContainer)rcw;
@@ -141,21 +158,26 @@ namespace System.Runtime.InteropServices {
_connectionPoint = cp;
}
- private void Unadvise() {
+ private void Unadvise()
+ {
BCLDebug.Assert(_connectionPoint != null, "can not unadvise from empty connection point");
- try {
+ try
+ {
_connectionPoint.Unadvise(_cookie);
Marshal.ReleaseComObject(_connectionPoint);
- } catch (System.Exception) {
+ }
+ catch (System.Exception)
+ {
// swallow all exceptions on unadvise
// the host may not be available at this point
- } finally {
+ }
+ finally
+ {
_connectionPoint = null;
}
+ }
- }
-
-#endregion
+ #endregion
};
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComMemberType.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComMemberType.cs
index c61d1b21be..ea99781975 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComMemberType.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComMemberType.cs
@@ -4,15 +4,16 @@
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
-namespace System.Runtime.InteropServices {
- using System;
+using System;
+namespace System.Runtime.InteropServices
+{
[Serializable]
public enum ComMemberType
{
- Method = 0,
- PropGet = 1,
- PropSet = 2
+ Method = 0,
+ PropGet = 1,
+ PropSet = 2
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IBindCtx.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IBindCtx.cs
index aac3f59d0f..152f1cd655 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IBindCtx.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IBindCtx.cs
@@ -11,13 +11,13 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
[StructLayout(LayoutKind.Sequential)]
- public struct BIND_OPTS
+ public struct BIND_OPTS
{
public int cbStruct;
public int grfFlags;
@@ -28,7 +28,7 @@ namespace System.Runtime.InteropServices.ComTypes
[Guid("0000000e-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
- public interface IBindCtx
+ public interface IBindCtx
{
void RegisterObjectBound([MarshalAs(UnmanagedType.Interface)] Object punk);
void RevokeObjectBound([MarshalAs(UnmanagedType.Interface)] Object punk);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPoint.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPoint.cs
index f70973e60d..3933d528a9 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPoint.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPoint.cs
@@ -11,15 +11,15 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
[Guid("B196B286-BAB4-101A-B69C-00AA00341D07")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
public interface IConnectionPoint
- {
+ {
void GetConnectionInterface(out Guid pIID);
void GetConnectionPointContainer(out IConnectionPointContainer ppCPC);
void Advise([MarshalAs(UnmanagedType.Interface)] Object pUnkSink, out int pdwCookie);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPointContainer.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPointContainer.cs
index fffff3c170..881dd8acfe 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPointContainer.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IConnectionPointContainer.cs
@@ -11,11 +11,11 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
- [Guid("B196B284-BAB4-101A-B69C-00AA00341D07")]
+ [Guid("B196B284-BAB4-101A-B69C-00AA00341D07")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
public interface IConnectionPointContainer
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnectionPoints.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnectionPoints.cs
index d667925b7e..32ad1f7f06 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnectionPoints.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnectionPoints.cs
@@ -11,15 +11,15 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
[Guid("B196B285-BAB4-101A-B69C-00AA00341D07")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
public interface IEnumConnectionPoints
- {
+ {
[PreserveSig]
int Next(int celt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), Out] IConnectionPoint[] rgelt, IntPtr pceltFetched);
[PreserveSig]
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnections.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnections.cs
index 8a2b4f0e6f..1acfe54657 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnections.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumConnections.cs
@@ -11,15 +11,15 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CONNECTDATA
- {
- [MarshalAs(UnmanagedType.Interface)]
+ {
+ [MarshalAs(UnmanagedType.Interface)]
public Object pUnk;
public int dwCookie;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumMoniker.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumMoniker.cs
index 57994b66bc..4513bc86ff 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumMoniker.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumMoniker.cs
@@ -11,14 +11,14 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
[Guid("00000102-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
- public interface IEnumMoniker
+ public interface IEnumMoniker
{
[PreserveSig]
int Next(int celt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), Out] IMoniker[] rgelt, IntPtr pceltFetched);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumString.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumString.cs
index f1e9233581..5738a42751 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumString.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumString.cs
@@ -11,14 +11,14 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
[Guid("00000101-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
- public interface IEnumString
+ public interface IEnumString
{
[PreserveSig]
int Next(int celt, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 0), Out] String[] rgelt, IntPtr pceltFetched);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumVARIANT.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumVARIANT.cs
index ea9b74b7c1..b94ac5e4c9 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumVARIANT.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IEnumVARIANT.cs
@@ -11,17 +11,17 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
- [Guid("00020404-0000-0000-C000-000000000046")]
+ [Guid("00020404-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
public interface IEnumVARIANT
{
[PreserveSig]
- int Next(int celt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0), Out] object[] rgVar, IntPtr pceltFetched);
+ int Next(int celt, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0), Out] object[] rgVar, IntPtr pceltFetched);
[PreserveSig]
int Skip(int celt);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IMoniker.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IMoniker.cs
index caee5e7fa3..ea45149b29 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IMoniker.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IMoniker.cs
@@ -11,22 +11,22 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
[StructLayout(LayoutKind.Sequential)]
- public struct FILETIME
+ public struct FILETIME
{
- public int dwLowDateTime;
- public int dwHighDateTime;
+ public int dwLowDateTime;
+ public int dwHighDateTime;
}
[Guid("0000000f-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
- public interface IMoniker
+ public interface IMoniker
{
// IPersist portion
void GetClassID(out Guid pClassID);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IPersistFile.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IPersistFile.cs
index a9f118a354..467a9e3a6a 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IPersistFile.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IPersistFile.cs
@@ -11,10 +11,10 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
[Guid("0000010b-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
@@ -22,7 +22,7 @@ namespace System.Runtime.InteropServices.ComTypes
{
// IPersist portion
void GetClassID(out Guid pClassID);
-
+
// IPersistFile portion
[PreserveSig]
int IsDirty();
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IRunningObjectTable.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IRunningObjectTable.cs
index bebbdec70c..ffca35ae83 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IRunningObjectTable.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IRunningObjectTable.cs
@@ -11,14 +11,14 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
[Guid("00000010-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
- public interface IRunningObjectTable
+ public interface IRunningObjectTable
{
int Register(int grfFlags, [MarshalAs(UnmanagedType.Interface)] Object punkObject, IMoniker pmkObjectName);
void Revoke(int dwRegister);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IStream.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IStream.cs
index 616ecbfa18..1a2d81f7ea 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IStream.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/IStream.cs
@@ -11,11 +11,11 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct STATSTG
{
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeComp.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeComp.cs
index f938ba91a7..967746f379 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeComp.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeComp.cs
@@ -11,22 +11,22 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
[Serializable]
public enum DESCKIND
{
- DESCKIND_NONE = 0,
- DESCKIND_FUNCDESC = DESCKIND_NONE + 1,
- DESCKIND_VARDESC = DESCKIND_FUNCDESC + 1,
- DESCKIND_TYPECOMP = DESCKIND_VARDESC + 1,
- DESCKIND_IMPLICITAPPOBJ = DESCKIND_TYPECOMP + 1,
- DESCKIND_MAX = DESCKIND_IMPLICITAPPOBJ + 1
+ DESCKIND_NONE = 0,
+ DESCKIND_FUNCDESC = DESCKIND_NONE + 1,
+ DESCKIND_VARDESC = DESCKIND_FUNCDESC + 1,
+ DESCKIND_TYPECOMP = DESCKIND_VARDESC + 1,
+ DESCKIND_IMPLICITAPPOBJ = DESCKIND_TYPECOMP + 1,
+ DESCKIND_MAX = DESCKIND_IMPLICITAPPOBJ + 1
}
- [StructLayout(LayoutKind.Explicit, CharSet=CharSet.Unicode)]
+ [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
public struct BINDPTR
{
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo.cs
index 7a12605f20..1857fdbb35 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo.cs
@@ -11,61 +11,61 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
[Serializable]
- public enum TYPEKIND
+ public enum TYPEKIND
{
- TKIND_ENUM = 0,
- TKIND_RECORD = TKIND_ENUM + 1,
- TKIND_MODULE = TKIND_RECORD + 1,
+ TKIND_ENUM = 0,
+ TKIND_RECORD = TKIND_ENUM + 1,
+ TKIND_MODULE = TKIND_RECORD + 1,
TKIND_INTERFACE = TKIND_MODULE + 1,
- TKIND_DISPATCH = TKIND_INTERFACE + 1,
- TKIND_COCLASS = TKIND_DISPATCH + 1,
- TKIND_ALIAS = TKIND_COCLASS + 1,
- TKIND_UNION = TKIND_ALIAS + 1,
- TKIND_MAX = TKIND_UNION + 1
+ TKIND_DISPATCH = TKIND_INTERFACE + 1,
+ TKIND_COCLASS = TKIND_DISPATCH + 1,
+ TKIND_ALIAS = TKIND_COCLASS + 1,
+ TKIND_UNION = TKIND_ALIAS + 1,
+ TKIND_MAX = TKIND_UNION + 1
}
-[Serializable]
-[Flags()]
+ [Serializable]
+ [Flags()]
public enum TYPEFLAGS : short
{
- TYPEFLAG_FAPPOBJECT = 0x1,
- TYPEFLAG_FCANCREATE = 0x2,
- TYPEFLAG_FLICENSED = 0x4,
- TYPEFLAG_FPREDECLID = 0x8,
- TYPEFLAG_FHIDDEN = 0x10,
- TYPEFLAG_FCONTROL = 0x20,
- TYPEFLAG_FDUAL = 0x40,
- TYPEFLAG_FNONEXTENSIBLE = 0x80,
- TYPEFLAG_FOLEAUTOMATION = 0x100,
- TYPEFLAG_FRESTRICTED = 0x200,
- TYPEFLAG_FAGGREGATABLE = 0x400,
- TYPEFLAG_FREPLACEABLE = 0x800,
- TYPEFLAG_FDISPATCHABLE = 0x1000,
- TYPEFLAG_FREVERSEBIND = 0x2000,
- TYPEFLAG_FPROXY = 0x4000
+ TYPEFLAG_FAPPOBJECT = 0x1,
+ TYPEFLAG_FCANCREATE = 0x2,
+ TYPEFLAG_FLICENSED = 0x4,
+ TYPEFLAG_FPREDECLID = 0x8,
+ TYPEFLAG_FHIDDEN = 0x10,
+ TYPEFLAG_FCONTROL = 0x20,
+ TYPEFLAG_FDUAL = 0x40,
+ TYPEFLAG_FNONEXTENSIBLE = 0x80,
+ TYPEFLAG_FOLEAUTOMATION = 0x100,
+ TYPEFLAG_FRESTRICTED = 0x200,
+ TYPEFLAG_FAGGREGATABLE = 0x400,
+ TYPEFLAG_FREPLACEABLE = 0x800,
+ TYPEFLAG_FDISPATCHABLE = 0x1000,
+ TYPEFLAG_FREVERSEBIND = 0x2000,
+ TYPEFLAG_FPROXY = 0x4000
}
-[Serializable]
-[Flags()]
+ [Serializable]
+ [Flags()]
public enum IMPLTYPEFLAGS
{
- IMPLTYPEFLAG_FDEFAULT = 0x1,
- IMPLTYPEFLAG_FSOURCE = 0x2,
- IMPLTYPEFLAG_FRESTRICTED = 0x4,
+ IMPLTYPEFLAG_FDEFAULT = 0x1,
+ IMPLTYPEFLAG_FSOURCE = 0x2,
+ IMPLTYPEFLAG_FRESTRICTED = 0x4,
IMPLTYPEFLAG_FDEFAULTVTABLE = 0x8,
}
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TYPEATTR
- {
+ {
// Constant used with the memid fields.
- public const int MEMBER_ID_NIL = unchecked((int)0xFFFFFFFF);
+ public const int MEMBER_ID_NIL = unchecked((int)0xFFFFFFFF);
// Actual fields of the TypeAttr struct.
public Guid guid;
@@ -91,55 +91,55 @@ namespace System.Runtime.InteropServices.ComTypes
[StructLayout(LayoutKind.Sequential)]
public struct FUNCDESC
- {
+ {
public int memid; //MEMBERID memid;
public IntPtr lprgscode; // /* [size_is(cScodes)] */ SCODE RPC_FAR *lprgscode;
public IntPtr lprgelemdescParam; // /* [size_is(cParams)] */ ELEMDESC __RPC_FAR *lprgelemdescParam;
- public FUNCKIND funckind; //FUNCKIND funckind;
+ public FUNCKIND funckind; //FUNCKIND funckind;
public INVOKEKIND invkind; //INVOKEKIND invkind;
- public CALLCONV callconv; //CALLCONV callconv;
+ public CALLCONV callconv; //CALLCONV callconv;
public Int16 cParams; //short cParams;
public Int16 cParamsOpt; //short cParamsOpt;
public Int16 oVft; //short oVft;
public Int16 cScodes; //short cScodes;
- public ELEMDESC elemdescFunc; //ELEMDESC elemdescFunc;
+ public ELEMDESC elemdescFunc; //ELEMDESC elemdescFunc;
public Int16 wFuncFlags; //WORD wFuncFlags;
}
-[Serializable]
-[Flags()]
- public enum IDLFLAG : short
+ [Serializable]
+ [Flags()]
+ public enum IDLFLAG : short
{
- IDLFLAG_NONE = PARAMFLAG.PARAMFLAG_NONE,
- IDLFLAG_FIN = PARAMFLAG.PARAMFLAG_FIN,
- IDLFLAG_FOUT = PARAMFLAG.PARAMFLAG_FOUT,
- IDLFLAG_FLCID = PARAMFLAG.PARAMFLAG_FLCID,
+ IDLFLAG_NONE = PARAMFLAG.PARAMFLAG_NONE,
+ IDLFLAG_FIN = PARAMFLAG.PARAMFLAG_FIN,
+ IDLFLAG_FOUT = PARAMFLAG.PARAMFLAG_FOUT,
+ IDLFLAG_FLCID = PARAMFLAG.PARAMFLAG_FLCID,
IDLFLAG_FRETVAL = PARAMFLAG.PARAMFLAG_FRETVAL
}
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct IDLDESC
{
- public IntPtr dwReserved;
- public IDLFLAG wIDLFlags;
+ public IntPtr dwReserved;
+ public IDLFLAG wIDLFlags;
}
-[Serializable]
-[Flags()]
- public enum PARAMFLAG :short
+ [Serializable]
+ [Flags()]
+ public enum PARAMFLAG : short
{
- PARAMFLAG_NONE = 0,
- PARAMFLAG_FIN = 0x1,
- PARAMFLAG_FOUT = 0x2,
- PARAMFLAG_FLCID = 0x4,
+ PARAMFLAG_NONE = 0,
+ PARAMFLAG_FIN = 0x1,
+ PARAMFLAG_FOUT = 0x2,
+ PARAMFLAG_FLCID = 0x4,
PARAMFLAG_FRETVAL = 0x8,
- PARAMFLAG_FOPT = 0x10,
+ PARAMFLAG_FOPT = 0x10,
PARAMFLAG_FHASDEFAULT = 0x20,
PARAMFLAG_FHASCUSTDATA = 0x40
}
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct PARAMDESC
{
@@ -147,21 +147,21 @@ namespace System.Runtime.InteropServices.ComTypes
public PARAMFLAG wParamFlags;
}
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TYPEDESC
- {
+ {
public IntPtr lpValue;
public Int16 vt;
}
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct ELEMDESC
{
public TYPEDESC tdesc;
- [System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit, CharSet=CharSet.Unicode)]
+ [System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
public struct DESCUNION
{
@@ -176,20 +176,20 @@ namespace System.Runtime.InteropServices.ComTypes
[Serializable]
public enum VARKIND : int
{
- VAR_PERINSTANCE = 0x0,
- VAR_STATIC = 0x1,
- VAR_CONST = 0x2,
- VAR_DISPATCH = 0x3
+ VAR_PERINSTANCE = 0x0,
+ VAR_STATIC = 0x1,
+ VAR_CONST = 0x2,
+ VAR_DISPATCH = 0x3
}
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct VARDESC
{
- public int memid;
+ public int memid;
public String lpstrSchema;
- [System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit, CharSet=CharSet.Unicode)]
+ [System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
public struct DESCUNION
{
@@ -206,7 +206,7 @@ namespace System.Runtime.InteropServices.ComTypes
public VARKIND varkind;
}
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DISPPARAMS
{
@@ -216,7 +216,7 @@ namespace System.Runtime.InteropServices.ComTypes
public int cNamedArgs;
}
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct EXCEPINFO
{
@@ -228,7 +228,7 @@ namespace System.Runtime.InteropServices.ComTypes
public int dwHelpContext;
public IntPtr pvReserved;
public IntPtr pfnDeferredFillIn;
- public Int32 scode;
+ public Int32 scode;
}
[Serializable]
@@ -241,8 +241,8 @@ namespace System.Runtime.InteropServices.ComTypes
FUNC_DISPATCH = 4
}
-[Serializable]
-[Flags]
+ [Serializable]
+ [Flags]
public enum INVOKEKIND : int
{
INVOKE_FUNC = 0x1,
@@ -254,54 +254,54 @@ namespace System.Runtime.InteropServices.ComTypes
[Serializable]
public enum CALLCONV : int
{
- CC_CDECL =1,
- CC_MSCPASCAL=2,
- CC_PASCAL =CC_MSCPASCAL,
- CC_MACPASCAL=3,
- CC_STDCALL =4,
- CC_RESERVED =5,
- CC_SYSCALL =6,
- CC_MPWCDECL =7,
- CC_MPWPASCAL=8,
- CC_MAX =9
+ CC_CDECL = 1,
+ CC_MSCPASCAL = 2,
+ CC_PASCAL = CC_MSCPASCAL,
+ CC_MACPASCAL = 3,
+ CC_STDCALL = 4,
+ CC_RESERVED = 5,
+ CC_SYSCALL = 6,
+ CC_MPWCDECL = 7,
+ CC_MPWPASCAL = 8,
+ CC_MAX = 9
}
-[Serializable]
-[Flags()]
+ [Serializable]
+ [Flags()]
public enum FUNCFLAGS : short
{
- FUNCFLAG_FRESTRICTED= 0x1,
- FUNCFLAG_FSOURCE = 0x2,
- FUNCFLAG_FBINDABLE = 0x4,
- FUNCFLAG_FREQUESTEDIT = 0x8,
- FUNCFLAG_FDISPLAYBIND = 0x10,
- FUNCFLAG_FDEFAULTBIND = 0x20,
- FUNCFLAG_FHIDDEN = 0x40,
- FUNCFLAG_FUSESGETLASTERROR= 0x80,
- FUNCFLAG_FDEFAULTCOLLELEM= 0x100,
- FUNCFLAG_FUIDEFAULT = 0x200,
- FUNCFLAG_FNONBROWSABLE = 0x400,
- FUNCFLAG_FREPLACEABLE = 0x800,
- FUNCFLAG_FIMMEDIATEBIND = 0x1000
+ FUNCFLAG_FRESTRICTED = 0x1,
+ FUNCFLAG_FSOURCE = 0x2,
+ FUNCFLAG_FBINDABLE = 0x4,
+ FUNCFLAG_FREQUESTEDIT = 0x8,
+ FUNCFLAG_FDISPLAYBIND = 0x10,
+ FUNCFLAG_FDEFAULTBIND = 0x20,
+ FUNCFLAG_FHIDDEN = 0x40,
+ FUNCFLAG_FUSESGETLASTERROR = 0x80,
+ FUNCFLAG_FDEFAULTCOLLELEM = 0x100,
+ FUNCFLAG_FUIDEFAULT = 0x200,
+ FUNCFLAG_FNONBROWSABLE = 0x400,
+ FUNCFLAG_FREPLACEABLE = 0x800,
+ FUNCFLAG_FIMMEDIATEBIND = 0x1000
}
-[Serializable]
-[Flags()]
+ [Serializable]
+ [Flags()]
public enum VARFLAGS : short
{
- VARFLAG_FREADONLY =0x1,
- VARFLAG_FSOURCE =0x2,
- VARFLAG_FBINDABLE =0x4,
- VARFLAG_FREQUESTEDIT =0x8,
- VARFLAG_FDISPLAYBIND =0x10,
- VARFLAG_FDEFAULTBIND =0x20,
- VARFLAG_FHIDDEN =0x40,
- VARFLAG_FRESTRICTED =0x80,
- VARFLAG_FDEFAULTCOLLELEM =0x100,
- VARFLAG_FUIDEFAULT =0x200,
- VARFLAG_FNONBROWSABLE =0x400,
- VARFLAG_FREPLACEABLE =0x800,
- VARFLAG_FIMMEDIATEBIND =0x1000
+ VARFLAG_FREADONLY = 0x1,
+ VARFLAG_FSOURCE = 0x2,
+ VARFLAG_FBINDABLE = 0x4,
+ VARFLAG_FREQUESTEDIT = 0x8,
+ VARFLAG_FDISPLAYBIND = 0x10,
+ VARFLAG_FDEFAULTBIND = 0x20,
+ VARFLAG_FHIDDEN = 0x40,
+ VARFLAG_FRESTRICTED = 0x80,
+ VARFLAG_FDEFAULTCOLLELEM = 0x100,
+ VARFLAG_FUIDEFAULT = 0x200,
+ VARFLAG_FNONBROWSABLE = 0x400,
+ VARFLAG_FREPLACEABLE = 0x800,
+ VARFLAG_FIMMEDIATEBIND = 0x1000
}
[Guid("00020401-0000-0000-C000-000000000046")]
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo2.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo2.cs
index a782b9edd6..7bb7138c46 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo2.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeInfo2.cs
@@ -11,10 +11,10 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
[Guid("00020412-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib.cs
index c39b088c0b..3ed6e42d08 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib.cs
@@ -11,36 +11,36 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
[Serializable]
public enum SYSKIND
{
- SYS_WIN16 = 0,
- SYS_WIN32 = SYS_WIN16 + 1,
- SYS_MAC = SYS_WIN32 + 1,
- SYS_WIN64 = SYS_MAC + 1
+ SYS_WIN16 = 0,
+ SYS_WIN32 = SYS_WIN16 + 1,
+ SYS_MAC = SYS_WIN32 + 1,
+ SYS_WIN64 = SYS_MAC + 1
}
-[Serializable]
-[Flags()]
+ [Serializable]
+ [Flags()]
public enum LIBFLAGS : short
{
- LIBFLAG_FRESTRICTED = 0x1,
- LIBFLAG_FCONTROL = 0x2,
- LIBFLAG_FHIDDEN = 0x4,
- LIBFLAG_FHASDISKIMAGE = 0x8
+ LIBFLAG_FRESTRICTED = 0x1,
+ LIBFLAG_FCONTROL = 0x2,
+ LIBFLAG_FHIDDEN = 0x4,
+ LIBFLAG_FHASDISKIMAGE = 0x8
}
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
[Serializable]
public struct TYPELIBATTR
- {
+ {
public Guid guid;
public int lcid;
- public SYSKIND syskind;
+ public SYSKIND syskind;
public Int16 wMajorVerNum;
public Int16 wMinorVerNum;
public LIBFLAGS wLibFlags;
@@ -54,12 +54,12 @@ namespace System.Runtime.InteropServices.ComTypes
[PreserveSig]
int GetTypeInfoCount();
void GetTypeInfo(int index, out ITypeInfo ppTI);
- void GetTypeInfoType(int index, out TYPEKIND pTKind);
- void GetTypeInfoOfGuid(ref Guid guid, out ITypeInfo ppTInfo);
- void GetLibAttr(out IntPtr ppTLibAttr);
- void GetTypeComp(out ITypeComp ppTComp);
+ void GetTypeInfoType(int index, out TYPEKIND pTKind);
+ void GetTypeInfoOfGuid(ref Guid guid, out ITypeInfo ppTInfo);
+ void GetLibAttr(out IntPtr ppTLibAttr);
+ void GetTypeComp(out ITypeComp ppTComp);
void GetDocumentation(int index, out String strName, out String strDocString, out int dwHelpContext, out String strHelpFile);
- [return : MarshalAs(UnmanagedType.Bool)]
+ [return: MarshalAs(UnmanagedType.Bool)]
bool IsName([MarshalAs(UnmanagedType.LPWStr)] String szNameBuf, int lHashVal);
void FindName([MarshalAs(UnmanagedType.LPWStr)] String szNameBuf, int lHashVal, [MarshalAs(UnmanagedType.LPArray), Out] ITypeInfo[] ppTInfo, [MarshalAs(UnmanagedType.LPArray), Out] int[] rgMemId, ref Int16 pcFound);
[PreserveSig]
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib2.cs b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib2.cs
index 5a7d07c001..48f4fb3782 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib2.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ComTypes/ITypeLib2.cs
@@ -11,10 +11,10 @@
**
=============================================================================*/
+using System;
+
namespace System.Runtime.InteropServices.ComTypes
{
- using System;
-
[Guid("00020411-0000-0000-C000-000000000046")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
[ComImport]
@@ -23,12 +23,12 @@ namespace System.Runtime.InteropServices.ComTypes
[PreserveSig]
new int GetTypeInfoCount();
new void GetTypeInfo(int index, out ITypeInfo ppTI);
- new void GetTypeInfoType(int index, out TYPEKIND pTKind);
- new void GetTypeInfoOfGuid(ref Guid guid, out ITypeInfo ppTInfo);
+ new void GetTypeInfoType(int index, out TYPEKIND pTKind);
+ new void GetTypeInfoOfGuid(ref Guid guid, out ITypeInfo ppTInfo);
new void GetLibAttr(out IntPtr ppTLibAttr);
- new void GetTypeComp(out ITypeComp ppTComp);
+ new void GetTypeComp(out ITypeComp ppTComp);
new void GetDocumentation(int index, out String strName, out String strDocString, out int dwHelpContext, out String strHelpFile);
- [return : MarshalAs(UnmanagedType.Bool)]
+ [return: MarshalAs(UnmanagedType.Bool)]
new bool IsName([MarshalAs(UnmanagedType.LPWStr)] String szNameBuf, int lHashVal);
new void FindName([MarshalAs(UnmanagedType.LPWStr)] String szNameBuf, int lHashVal, [MarshalAs(UnmanagedType.LPArray), Out] ITypeInfo[] ppTInfo, [MarshalAs(UnmanagedType.LPArray), Out] int[] rgMemId, ref Int16 pcFound);
[PreserveSig]
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/CriticalHandle.cs b/src/mscorlib/src/System/Runtime/InteropServices/CriticalHandle.cs
index 840270141b..734a494bdb 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/CriticalHandle.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/CriticalHandle.cs
@@ -130,122 +130,124 @@ using System.IO;
namespace System.Runtime.InteropServices
{
-
-// This class should not be serializable - it's a handle. We require unmanaged
-// code permission to subclass CriticalHandle to prevent people from writing a
-// subclass and suddenly being able to run arbitrary native code with the
-// same signature as CloseHandle. This is technically a little redundant, but
-// we'll do this to ensure we've cut off all attack vectors. Similarly, all
-// methods have a link demand to ensure untrusted code cannot directly edit
-// or alter a handle.
-public abstract class CriticalHandle : CriticalFinalizerObject, IDisposable
-{
- // ! Do not add or rearrange fields as the EE depends on this layout.
- //------------------------------------------------------------------
+ // This class should not be serializable - it's a handle. We require unmanaged
+ // code permission to subclass CriticalHandle to prevent people from writing a
+ // subclass and suddenly being able to run arbitrary native code with the
+ // same signature as CloseHandle. This is technically a little redundant, but
+ // we'll do this to ensure we've cut off all attack vectors. Similarly, all
+ // methods have a link demand to ensure untrusted code cannot directly edit
+ // or alter a handle.
+ public abstract class CriticalHandle : CriticalFinalizerObject, IDisposable
+ {
+ // ! Do not add or rearrange fields as the EE depends on this layout.
+ //------------------------------------------------------------------
#if DEBUG
- private String _stackTrace; // Where we allocated this CriticalHandle.
+ private String _stackTrace; // Where we allocated this CriticalHandle.
#endif
- protected IntPtr handle; // This must be protected so derived classes can use out params.
- private bool _isClosed; // Set by SetHandleAsInvalid or Close/Dispose/finalization.
+ protected IntPtr handle; // This must be protected so derived classes can use out params.
+ private bool _isClosed; // Set by SetHandleAsInvalid or Close/Dispose/finalization.
- // Creates a CriticalHandle class. Users must then set the Handle property or allow P/Invoke marshaling to set it implicitly.
- protected CriticalHandle(IntPtr invalidHandleValue)
- {
- handle = invalidHandleValue;
- _isClosed = false;
+ // Creates a CriticalHandle class. Users must then set the Handle property or allow P/Invoke marshaling to set it implicitly.
+ protected CriticalHandle(IntPtr invalidHandleValue)
+ {
+ handle = invalidHandleValue;
+ _isClosed = false;
#if DEBUG
- if (BCLDebug.SafeHandleStackTracesEnabled)
- _stackTrace = Environment.GetStackTrace(null, false);
- else
- _stackTrace = "For a stack trace showing who allocated this CriticalHandle, set SafeHandleStackTraces to 1 and rerun your app.";
+ if (BCLDebug.SafeHandleStackTracesEnabled)
+ _stackTrace = Environment.GetStackTrace(null, false);
+ else
+ _stackTrace = "For a stack trace showing who allocated this CriticalHandle, set SafeHandleStackTraces to 1 and rerun your app.";
#endif
+ }
+
+ // Adding an empty default constructor for annotation purposes
+ private CriticalHandle() { }
+
+ ~CriticalHandle()
+ {
+ Dispose(false);
+ }
+
+ private void Cleanup()
+ {
+ if (IsClosed)
+ return;
+ _isClosed = true;
+
+ if (IsInvalid)
+ return;
+
+ // Save last error from P/Invoke in case the implementation of
+ // ReleaseHandle trashes it (important because this ReleaseHandle could
+ // occur implicitly as part of unmarshaling another P/Invoke).
+ int lastError = Marshal.GetLastWin32Error();
+
+ if (!ReleaseHandle())
+ FireCustomerDebugProbe();
+
+ Marshal.SetLastWin32Error(lastError);
+
+ GC.SuppressFinalize(this);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern void FireCustomerDebugProbe();
+
+ protected void SetHandle(IntPtr handle)
+ {
+ this.handle = handle;
+ }
+
+ // Returns whether the handle has been explicitly marked as closed
+ // (Close/Dispose) or invalid (SetHandleAsInvalid).
+ public bool IsClosed
+ {
+ get { return _isClosed; }
+ }
+
+ // Returns whether the handle looks like an invalid value (i.e. matches one
+ // of the handle's designated illegal values). CriticalHandle itself doesn't
+ // know what an invalid handle looks like, so this method is abstract and
+ // must be provided by a derived type.
+ public abstract bool IsInvalid
+ {
+ get;
+ }
+
+ public void Close()
+ {
+ Dispose(true);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ Cleanup();
+ }
+
+ // This should only be called for cases when you know for a fact that
+ // your handle is invalid and you want to record that information.
+ // An example is calling a syscall and getting back ERROR_INVALID_HANDLE.
+ // This method will normally leak handles!
+ public void SetHandleAsInvalid()
+ {
+ _isClosed = true;
+ GC.SuppressFinalize(this);
+ }
+
+ // Implement this abstract method in your derived class to specify how to
+ // free the handle. Be careful not write any code that's subject to faults
+ // in this method (the runtime will prepare the infrastructure for you so
+ // that no jit allocations etc. will occur, but don't allocate memory unless
+ // you can deal with the failure and still free the handle).
+ // The boolean returned should be true for success and false if a
+ // catastrophic error occurred and you wish to trigger a diagnostic for
+ // debugging purposes (the SafeHandleCriticalFailure MDA).
+ protected abstract bool ReleaseHandle();
}
-
- // Adding an empty default constructor for annotation purposes
- private CriticalHandle(){}
-
- ~CriticalHandle()
- {
- Dispose(false);
- }
-
- private void Cleanup()
- {
- if (IsClosed)
- return;
- _isClosed = true;
-
- if (IsInvalid)
- return;
-
- // Save last error from P/Invoke in case the implementation of
- // ReleaseHandle trashes it (important because this ReleaseHandle could
- // occur implicitly as part of unmarshaling another P/Invoke).
- int lastError = Marshal.GetLastWin32Error();
-
- if (!ReleaseHandle())
- FireCustomerDebugProbe();
-
- Marshal.SetLastWin32Error(lastError);
-
- GC.SuppressFinalize(this);
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern void FireCustomerDebugProbe();
-
- protected void SetHandle(IntPtr handle) {
- this.handle = handle;
- }
-
- // Returns whether the handle has been explicitly marked as closed
- // (Close/Dispose) or invalid (SetHandleAsInvalid).
- public bool IsClosed {
- get { return _isClosed; }
- }
-
- // Returns whether the handle looks like an invalid value (i.e. matches one
- // of the handle's designated illegal values). CriticalHandle itself doesn't
- // know what an invalid handle looks like, so this method is abstract and
- // must be provided by a derived type.
- public abstract bool IsInvalid {
- get;
- }
-
- public void Close() {
- Dispose(true);
- }
-
- public void Dispose()
- {
- Dispose(true);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- Cleanup();
- }
-
- // This should only be called for cases when you know for a fact that
- // your handle is invalid and you want to record that information.
- // An example is calling a syscall and getting back ERROR_INVALID_HANDLE.
- // This method will normally leak handles!
- public void SetHandleAsInvalid()
- {
- _isClosed = true;
- GC.SuppressFinalize(this);
- }
-
- // Implement this abstract method in your derived class to specify how to
- // free the handle. Be careful not write any code that's subject to faults
- // in this method (the runtime will prepare the infrastructure for you so
- // that no jit allocations etc. will occur, but don't allocate memory unless
- // you can deal with the failure and still free the handle).
- // The boolean returned should be true for success and false if a
- // catastrophic error occurred and you wish to trigger a diagnostic for
- // debugging purposes (the SafeHandleCriticalFailure MDA).
- protected abstract bool ReleaseHandle();
-}
-
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/CurrencyWrapper.cs b/src/mscorlib/src/System/Runtime/InteropServices/CurrencyWrapper.cs
index 304419e5b0..4b436825e8 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/CurrencyWrapper.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/CurrencyWrapper.cs
@@ -11,10 +11,11 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
-
- using System;
+using System;
+
+namespace System.Runtime.InteropServices
+{
[Serializable]
public sealed class CurrencyWrapper
{
@@ -24,15 +25,15 @@ namespace System.Runtime.InteropServices {
}
public CurrencyWrapper(Object obj)
- {
+ {
if (!(obj is Decimal))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDecimal"), nameof(obj));
+ throw new ArgumentException(SR.Arg_MustBeDecimal, nameof(obj));
m_WrappedObject = (Decimal)obj;
}
- public Decimal WrappedObject
+ public Decimal WrappedObject
{
- get
+ get
{
return m_WrappedObject;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/DispatchWrapper.cs b/src/mscorlib/src/System/Runtime/InteropServices/DispatchWrapper.cs
index ccf25af0f9..87ec4ed15e 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/DispatchWrapper.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/DispatchWrapper.cs
@@ -11,11 +11,12 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
-
- using System;
- using System.Security;
+using System;
+using System.Security;
+
+namespace System.Runtime.InteropServices
+{
[Serializable]
public sealed class DispatchWrapper
{
@@ -32,9 +33,9 @@ namespace System.Runtime.InteropServices {
m_WrappedObject = obj;
}
- public Object WrappedObject
+ public Object WrappedObject
{
- get
+ get
{
return m_WrappedObject;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ErrorWrapper.cs b/src/mscorlib/src/System/Runtime/InteropServices/ErrorWrapper.cs
index da02893b1e..73be2c5777 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ErrorWrapper.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ErrorWrapper.cs
@@ -11,10 +11,11 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
-
- using System;
+using System;
+
+namespace System.Runtime.InteropServices
+{
[Serializable]
public sealed class ErrorWrapper
{
@@ -26,18 +27,18 @@ namespace System.Runtime.InteropServices {
public ErrorWrapper(Object errorCode)
{
if (!(errorCode is int))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeInt32"), nameof(errorCode));
+ throw new ArgumentException(SR.Arg_MustBeInt32, nameof(errorCode));
m_ErrorCode = (int)errorCode;
- }
+ }
public ErrorWrapper(Exception e)
{
m_ErrorCode = Marshal.GetHRForException(e);
}
- public int ErrorCode
+ public int ErrorCode
{
- get
+ get
{
return m_ErrorCode;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/Expando/IExpando.cs b/src/mscorlib/src/System/Runtime/InteropServices/Expando/IExpando.cs
index 429ce13918..2bd398b7a9 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/Expando/IExpando.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/Expando/IExpando.cs
@@ -11,11 +11,12 @@
//
//
// The IExpando Interface.
-namespace System.Runtime.InteropServices.Expando {
-
- using System;
- using System.Reflection;
+using System;
+using System.Reflection;
+
+namespace System.Runtime.InteropServices.Expando
+{
[Guid("AFBF15E6-C37C-11d2-B88E-00A0C9B471B8")]
internal interface IExpando : IReflect
{
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ExternalException.cs b/src/mscorlib/src/System/Runtime/InteropServices/ExternalException.cs
deleted file mode 100644
index 7e1f395e4e..0000000000
--- a/src/mscorlib/src/System/Runtime/InteropServices/ExternalException.cs
+++ /dev/null
@@ -1,77 +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.
-
-/*=============================================================================
-**
-**
-**
-** Purpose: Exception base class for all errors from Interop or Structured
-** Exception Handling code.
-**
-**
-=============================================================================*/
-
-namespace System.Runtime.InteropServices {
-
- using System;
- using System.Globalization;
- using System.Runtime.Serialization;
- // Base exception for COM Interop errors &; Structured Exception Handler
- // exceptions.
- //
- [Serializable]
- public class ExternalException : SystemException {
- public ExternalException()
- : base(Environment.GetResourceString("Arg_ExternalException")) {
- SetErrorCode(__HResults.E_FAIL);
- }
-
- public ExternalException(String message)
- : base(message) {
- SetErrorCode(__HResults.E_FAIL);
- }
-
- public ExternalException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.E_FAIL);
- }
-
- public ExternalException(String message,int errorCode)
- : base(message) {
- SetErrorCode(errorCode);
- }
-
- protected ExternalException(SerializationInfo info, StreamingContext context) : base(info, context) {
- }
-
- public virtual int ErrorCode {
- get {
- return HResult;
- }
- }
-
- public override String ToString() {
- String message = Message;
- String s;
- String _className = GetType().ToString();
- s = _className + " (0x" + HResult.ToString("X8", CultureInfo.InvariantCulture) + ")";
-
- if (!(String.IsNullOrEmpty(message))) {
- s = s + ": " + message;
- }
-
- Exception _innerException = InnerException;
-
- if (_innerException!=null) {
- s = s + " ---> " + _innerException.ToString();
- }
-
-
- if (StackTrace != null)
- s += Environment.NewLine + StackTrace;
-
- return s;
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/GCHandleCookieTable.cs b/src/mscorlib/src/System/Runtime/InteropServices/GCHandleCookieTable.cs
index 304f369879..9e813d9bd9 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/GCHandleCookieTable.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/GCHandleCookieTable.cs
@@ -91,7 +91,7 @@ namespace System.Runtime.InteropServices
}
if (cookie == GCHandleCookie.Zero)
- throw new OutOfMemoryException(Environment.GetResourceString("OutOfMemory_GCHandleMDA"));
+ throw new OutOfMemoryException(SR.OutOfMemory_GCHandleMDA);
// This handle hasn't been added to the map yet so add it.
m_HandleToCookieMap.Add(handle, cookie);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/GcHandle.cs b/src/mscorlib/src/System/Runtime/InteropServices/GcHandle.cs
index 598fee0618..dcb9e24258 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/GcHandle.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/GcHandle.cs
@@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.
namespace System.Runtime.InteropServices
-{
+{
using System;
using System.Runtime.CompilerServices;
using System.Threading;
@@ -113,7 +113,7 @@ namespace System.Runtime.InteropServices
#endif
InternalFree(GetHandleValue(handle));
}
-
+
// Target property - allows getting / updating of the handle's referent.
public Object Target
{
@@ -122,7 +122,7 @@ namespace System.Runtime.InteropServices
ValidateHandle();
return InternalGet(GetHandleValue());
}
-
+
set
{
ValidateHandle();
@@ -140,7 +140,7 @@ namespace System.Runtime.InteropServices
ValidateHandle();
// You can only get the address of pinned handles.
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_HandleIsNotPinned"));
+ throw new InvalidOperationException(SR.InvalidOperation_HandleIsNotPinned);
}
// Get the address.
@@ -198,7 +198,7 @@ namespace System.Runtime.InteropServices
}
#endif
return value.m_handle;
- }
+ }
public override int GetHashCode()
{
@@ -208,12 +208,12 @@ namespace System.Runtime.InteropServices
public override bool Equals(Object o)
{
GCHandle hnd;
-
+
// Check that o is a GCHandle first
- if(o == null || !(o is GCHandle))
+ if (o == null || !(o is GCHandle))
return false;
- else
- hnd = (GCHandle) o;
+ else
+ hnd = (GCHandle)o;
return m_handle == hnd.m_handle;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/HandleRef.cs b/src/mscorlib/src/System/Runtime/InteropServices/HandleRef.cs
index b1171025ee..41eb1c24ba 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/HandleRef.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/HandleRef.cs
@@ -2,14 +2,13 @@
// 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;
+
namespace System.Runtime.InteropServices
{
-
- using System;
-
public struct HandleRef
{
-
// ! Do not add or rearrange fields as the EE depends on this layout.
//------------------------------------------------------------------
internal Object m_wrapper;
@@ -20,22 +19,26 @@ namespace System.Runtime.InteropServices
public HandleRef(Object wrapper, IntPtr handle)
{
m_wrapper = wrapper;
- m_handle = handle;
+ m_handle = handle;
}
- public Object Wrapper {
- get {
+ public Object Wrapper
+ {
+ get
+ {
return m_wrapper;
}
}
-
- public IntPtr Handle {
- get {
+
+ public IntPtr Handle
+ {
+ get
+ {
return m_handle;
}
}
-
-
+
+
public static explicit operator IntPtr(HandleRef value)
{
return value.m_handle;
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ICustomAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/ICustomAdapter.cs
index 002c48a171..f47d348699 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ICustomAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ICustomAdapter.cs
@@ -12,11 +12,12 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
- using System;
+using System;
+namespace System.Runtime.InteropServices
+{
public interface ICustomAdapter
- {
- [return:MarshalAs(UnmanagedType.IUnknown)] Object GetUnderlyingObject();
+ {
+ [return: MarshalAs(UnmanagedType.IUnknown)] Object GetUnderlyingObject();
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ICustomFactory.cs b/src/mscorlib/src/System/Runtime/InteropServices/ICustomFactory.cs
index 8e7af10b6e..e7bfc47281 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ICustomFactory.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ICustomFactory.cs
@@ -4,13 +4,13 @@
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
-namespace System.Runtime.InteropServices {
- using System;
+using System;
+namespace System.Runtime.InteropServices
+{
public interface ICustomFactory
{
MarshalByRefObject CreateInstance(Type serverType);
}
-
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ICustomMarshaler.cs b/src/mscorlib/src/System/Runtime/InteropServices/ICustomMarshaler.cs
index d9ed289145..571d78dfe3 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ICustomMarshaler.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ICustomMarshaler.cs
@@ -12,18 +12,19 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
- using System;
+using System;
+namespace System.Runtime.InteropServices
+{
public interface ICustomMarshaler
- {
- Object MarshalNativeToManaged( IntPtr pNativeData );
+ {
+ Object MarshalNativeToManaged(IntPtr pNativeData);
- IntPtr MarshalManagedToNative( Object ManagedObj );
+ IntPtr MarshalManagedToNative(Object ManagedObj);
- void CleanUpNativeData( IntPtr pNativeData );
+ void CleanUpNativeData(IntPtr pNativeData);
- void CleanUpManagedData( Object ManagedObj );
+ void CleanUpManagedData(Object ManagedObj);
int GetNativeDataSize();
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ICustomQueryInterface.cs b/src/mscorlib/src/System/Runtime/InteropServices/ICustomQueryInterface.cs
index 5675b1f2d6..4f4b10bbf0 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ICustomQueryInterface.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ICustomQueryInterface.cs
@@ -12,18 +12,19 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
- using System;
+using System;
+namespace System.Runtime.InteropServices
+{
//====================================================================
// The enum of the return value of IQuerable.GetInterface
//====================================================================
[Serializable]
public enum CustomQueryInterfaceResult
{
- Handled = 0,
- NotHandled = 1,
- Failed = 2,
+ Handled = 0,
+ NotHandled = 1,
+ Failed = 2,
}
//====================================================================
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ITypeLibConverter.cs b/src/mscorlib/src/System/Runtime/InteropServices/ITypeLibConverter.cs
index afa934caaf..85756cf84f 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/ITypeLibConverter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/ITypeLibConverter.cs
@@ -16,9 +16,11 @@
// *** in src/inc/TlbImpExp.idl.
// ***************************************************************************
-namespace System.Runtime.InteropServices {
-
- using System;
- using System.Reflection;
- using System.Reflection.Emit;
+
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+
+namespace System.Runtime.InteropServices
+{
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/InvalidComObjectException.cs b/src/mscorlib/src/System/Runtime/InteropServices/InvalidComObjectException.cs
index 760210bc28..2fae2b6e52 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/InvalidComObjectException.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/InvalidComObjectException.cs
@@ -11,29 +11,35 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
- using System;
- using System.Runtime.Serialization;
+using System;
+using System.Runtime.Serialization;
+namespace System.Runtime.InteropServices
+{
[Serializable]
- public class InvalidComObjectException : SystemException {
- public InvalidComObjectException()
- : base(Environment.GetResourceString("Arg_InvalidComObjectException")) {
- SetErrorCode(__HResults.COR_E_INVALIDCOMOBJECT);
+ public class InvalidComObjectException : SystemException
+ {
+ public InvalidComObjectException()
+ : base(SR.Arg_InvalidComObjectException)
+ {
+ HResult = __HResults.COR_E_INVALIDCOMOBJECT;
}
-
- public InvalidComObjectException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_INVALIDCOMOBJECT);
+
+ public InvalidComObjectException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_INVALIDCOMOBJECT;
}
-
- public InvalidComObjectException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_INVALIDCOMOBJECT);
+
+ public InvalidComObjectException(String message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_INVALIDCOMOBJECT;
}
- protected InvalidComObjectException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ protected InvalidComObjectException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
}
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/InvalidOleVariantTypeException.cs b/src/mscorlib/src/System/Runtime/InteropServices/InvalidOleVariantTypeException.cs
index 4ca3da5619..5154a028ad 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/InvalidOleVariantTypeException.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/InvalidOleVariantTypeException.cs
@@ -10,29 +10,35 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
-
- using System;
- using System.Runtime.Serialization;
+using System;
+using System.Runtime.Serialization;
+
+namespace System.Runtime.InteropServices
+{
[Serializable]
- public class InvalidOleVariantTypeException : SystemException {
- public InvalidOleVariantTypeException()
- : base(Environment.GetResourceString("Arg_InvalidOleVariantTypeException")) {
- SetErrorCode(__HResults.COR_E_INVALIDOLEVARIANTTYPE);
+ public class InvalidOleVariantTypeException : SystemException
+ {
+ public InvalidOleVariantTypeException()
+ : base(SR.Arg_InvalidOleVariantTypeException)
+ {
+ HResult = __HResults.COR_E_INVALIDOLEVARIANTTYPE;
}
-
- public InvalidOleVariantTypeException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_INVALIDOLEVARIANTTYPE);
+
+ public InvalidOleVariantTypeException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_INVALIDOLEVARIANTTYPE;
}
-
- public InvalidOleVariantTypeException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_INVALIDOLEVARIANTTYPE);
+
+ public InvalidOleVariantTypeException(String message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_INVALIDOLEVARIANTTYPE;
}
- protected InvalidOleVariantTypeException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ protected InvalidOleVariantTypeException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
}
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/LayoutKind.cs b/src/mscorlib/src/System/Runtime/InteropServices/LayoutKind.cs
deleted file mode 100644
index f7def3a8e9..0000000000
--- a/src/mscorlib/src/System/Runtime/InteropServices/LayoutKind.cs
+++ /dev/null
@@ -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.
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-namespace System.Runtime.InteropServices {
- using System;
- // Used in the StructLayoutAttribute class
- [Serializable]
- public enum LayoutKind
- {
- Sequential = 0, // 0x00000008,
- Explicit = 2, // 0x00000010,
- Auto = 3, // 0x00000000,
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs b/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs
index 9e9103b9c2..248e0d5778 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/Marshal.cs
@@ -13,7 +13,7 @@
=============================================================================*/
namespace System.Runtime.InteropServices
-{
+{
using System;
using System.Collections.Generic;
using System.Reflection;
@@ -35,7 +35,7 @@ namespace System.Runtime.InteropServices
[Serializable]
public enum CustomQueryInterfaceMode
{
- Ignore = 0,
+ Ignore = 0,
Allow = 1
}
@@ -46,7 +46,7 @@ namespace System.Runtime.InteropServices
//========================================================================
public static partial class Marshal
- {
+ {
//====================================================================
// Defines used inside the Marshal class.
//====================================================================
@@ -101,10 +101,10 @@ namespace System.Runtime.InteropServices
// The name, title and description of the assembly that will contain
// the dynamically generated interop types.
//====================================================================
- private const String s_strConvertedTypeInfoAssemblyName = "InteropDynamicTypes";
- private const String s_strConvertedTypeInfoAssemblyTitle = "Interop Dynamic Types";
- private const String s_strConvertedTypeInfoAssemblyDesc = "Type dynamically generated from ITypeInfo's";
- private const String s_strConvertedTypeInfoNameSpace = "InteropDynamicTypes";
+ private const String s_strConvertedTypeInfoAssemblyName = "InteropDynamicTypes";
+ private const String s_strConvertedTypeInfoAssemblyTitle = "Interop Dynamic Types";
+ private const String s_strConvertedTypeInfoAssemblyDesc = "Type dynamically generated from ITypeInfo's";
+ private const String s_strConvertedTypeInfoNameSpace = "InteropDynamicTypes";
//====================================================================
@@ -112,22 +112,27 @@ namespace System.Runtime.InteropServices
//====================================================================
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int GetSystemMaxDBCSCharSize();
-
+
unsafe public static String PtrToStringAnsi(IntPtr ptr)
{
- if (IntPtr.Zero == ptr) {
+ if (IntPtr.Zero == ptr)
+ {
return null;
}
- else if (IsWin32Atom(ptr)) {
+ else if (IsWin32Atom(ptr))
+ {
return null;
}
- else {
+ else
+ {
int nb = Win32Native.lstrlenA(ptr);
- if( nb == 0) {
+ if (nb == 0)
+ {
return string.Empty;
}
- else {
- return new String((sbyte *)ptr);
+ else
+ {
+ return new String((sbyte*)ptr);
}
}
}
@@ -139,7 +144,7 @@ namespace System.Runtime.InteropServices
if (len < 0)
throw new ArgumentException(null, nameof(len));
- return new String((sbyte *)ptr, 0, len);
+ return new String((sbyte*)ptr, 0, len);
}
unsafe public static String PtrToStringUni(IntPtr ptr, int len)
@@ -149,28 +154,31 @@ namespace System.Runtime.InteropServices
if (len < 0)
throw new ArgumentException(null, nameof(len));
- return new String((char *)ptr, 0, len);
+ return new String((char*)ptr, 0, len);
}
-
+
public static String PtrToStringAuto(IntPtr ptr, int len)
{
// Ansi platforms are no longer supported
return PtrToStringUni(ptr, len);
- }
-
+ }
+
unsafe public static String PtrToStringUni(IntPtr ptr)
{
- if (IntPtr.Zero == ptr) {
+ if (IntPtr.Zero == ptr)
+ {
return null;
}
- else if (IsWin32Atom(ptr)) {
+ else if (IsWin32Atom(ptr))
+ {
return null;
- }
- else {
- return new String((char *)ptr);
+ }
+ else
+ {
+ return new String((char*)ptr);
}
}
-
+
public static String PtrToStringAuto(IntPtr ptr)
{
// Ansi platforms are no longer supported
@@ -183,7 +191,7 @@ namespace System.Runtime.InteropServices
return PtrToStringUTF8(ptr, nbBytes);
}
- unsafe public static String PtrToStringUTF8(IntPtr ptr,int byteLen)
+ unsafe public static String PtrToStringUTF8(IntPtr ptr, int byteLen)
{
if (byteLen < 0)
{
@@ -232,9 +240,9 @@ namespace System.Runtime.InteropServices
if (t == null)
throw new ArgumentNullException(nameof(t));
if (!(t is RuntimeType))
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(t));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(t));
if (t.IsGenericType)
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), nameof(t));
+ throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t));
Contract.EndContractBlock();
return SizeOfHelper(t, true);
@@ -285,13 +293,13 @@ namespace System.Runtime.InteropServices
if (t == null)
throw new ArgumentNullException(nameof(t));
Contract.EndContractBlock();
-
+
FieldInfo f = t.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (f == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_OffsetOfFieldNotFound", t.FullName), nameof(fieldName));
+ throw new ArgumentException(SR.Format(SR.Argument_OffsetOfFieldNotFound, t.FullName), nameof(fieldName));
RtFieldInfo rtField = f as RtFieldInfo;
if (rtField == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeFieldInfo"), nameof(fieldName));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeFieldInfo, nameof(fieldName));
return OffsetOfHelper(rtField);
}
@@ -322,27 +330,27 @@ namespace System.Runtime.InteropServices
//====================================================================
// Copy blocks from CLR arrays to native memory.
//====================================================================
- public static void Copy(int[] source, int startIndex, IntPtr destination, int length)
+ public static void Copy(int[] source, int startIndex, IntPtr destination, int length)
{
CopyToNative(source, startIndex, destination, length);
}
- public static void Copy(char[] source, int startIndex, IntPtr destination, int length)
+ public static void Copy(char[] source, int startIndex, IntPtr destination, int length)
{
CopyToNative(source, startIndex, destination, length);
}
- public static void Copy(short[] source, int startIndex, IntPtr destination, int length)
+ public static void Copy(short[] source, int startIndex, IntPtr destination, int length)
{
CopyToNative(source, startIndex, destination, length);
}
- public static void Copy(long[] source, int startIndex, IntPtr destination, int length)
+ public static void Copy(long[] source, int startIndex, IntPtr destination, int length)
{
CopyToNative(source, startIndex, destination, length);
}
- public static void Copy(float[] source, int startIndex, IntPtr destination, int length)
+ public static void Copy(float[] source, int startIndex, IntPtr destination, int length)
{
CopyToNative(source, startIndex, destination, length);
}
- public static void Copy(double[] source, int startIndex, IntPtr destination, int length)
+ public static void Copy(double[] source, int startIndex, IntPtr destination, int length)
{
CopyToNative(source, startIndex, destination, length);
}
@@ -360,27 +368,27 @@ namespace System.Runtime.InteropServices
//====================================================================
// Copy blocks from native memory to CLR arrays
//====================================================================
- public static void Copy(IntPtr source, int[] destination, int startIndex, int length)
+ public static void Copy(IntPtr source, int[] destination, int startIndex, int length)
{
CopyToManaged(source, destination, startIndex, length);
}
- public static void Copy(IntPtr source, char[] destination, int startIndex, int length)
+ public static void Copy(IntPtr source, char[] destination, int startIndex, int length)
{
CopyToManaged(source, destination, startIndex, length);
}
- public static void Copy(IntPtr source, short[] destination, int startIndex, int length)
+ public static void Copy(IntPtr source, short[] destination, int startIndex, int length)
{
CopyToManaged(source, destination, startIndex, length);
}
- public static void Copy(IntPtr source, long[] destination, int startIndex, int length)
+ public static void Copy(IntPtr source, long[] destination, int startIndex, int length)
{
CopyToManaged(source, destination, startIndex, length);
}
- public static void Copy(IntPtr source, float[] destination, int startIndex, int length)
+ public static void Copy(IntPtr source, float[] destination, int startIndex, int length)
{
CopyToManaged(source, destination, startIndex, length);
}
- public static void Copy(IntPtr source, double[] destination, int startIndex, int length)
+ public static void Copy(IntPtr source, double[] destination, int startIndex, int length)
{
CopyToManaged(source, destination, startIndex, length);
}
@@ -400,14 +408,14 @@ namespace System.Runtime.InteropServices
//====================================================================
public static byte ReadByte([MarshalAs(UnmanagedType.AsAny), In] Object ptr, int ofs)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
}
public static unsafe byte ReadByte(IntPtr ptr, int ofs)
{
try
{
- byte *addr = (byte *)ptr + ofs;
+ byte* addr = (byte*)ptr + ofs;
return *addr;
}
catch (NullReferenceException)
@@ -419,29 +427,29 @@ namespace System.Runtime.InteropServices
public static byte ReadByte(IntPtr ptr)
{
- return ReadByte(ptr,0);
+ return ReadByte(ptr, 0);
}
- public static short ReadInt16([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs)
+ public static short ReadInt16([MarshalAs(UnmanagedType.AsAny), In] Object ptr, int ofs)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
}
-
+
public static unsafe short ReadInt16(IntPtr ptr, int ofs)
{
try
{
- byte *addr = (byte *)ptr + ofs;
+ byte* addr = (byte*)ptr + ofs;
if ((unchecked((int)addr) & 0x1) == 0)
{
// aligned read
- return *((short *)addr);
+ return *((short*)addr);
}
else
{
// unaligned read
short val;
- byte *valPtr = (byte *)&val;
+ byte* valPtr = (byte*)&val;
valPtr[0] = addr[0];
valPtr[1] = addr[1];
return val;
@@ -459,26 +467,26 @@ namespace System.Runtime.InteropServices
return ReadInt16(ptr, 0);
}
- public static int ReadInt32([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs)
+ public static int ReadInt32([MarshalAs(UnmanagedType.AsAny), In] Object ptr, int ofs)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
}
-
+
public static unsafe int ReadInt32(IntPtr ptr, int ofs)
{
try
{
- byte *addr = (byte *)ptr + ofs;
+ byte* addr = (byte*)ptr + ofs;
if ((unchecked((int)addr) & 0x3) == 0)
{
// aligned read
- return *((int *)addr);
+ return *((int*)addr);
}
else
{
// unaligned read
int val;
- byte *valPtr = (byte *)&val;
+ byte* valPtr = (byte*)&val;
valPtr[0] = addr[0];
valPtr[1] = addr[1];
valPtr[2] = addr[2];
@@ -492,59 +500,59 @@ namespace System.Runtime.InteropServices
throw new AccessViolationException();
}
}
-
+
public static int ReadInt32(IntPtr ptr)
{
- return ReadInt32(ptr,0);
+ return ReadInt32(ptr, 0);
}
-
- public static IntPtr ReadIntPtr([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs)
+
+ public static IntPtr ReadIntPtr([MarshalAs(UnmanagedType.AsAny), In] Object ptr, int ofs)
{
- #if BIT64
- return (IntPtr) ReadInt64(ptr, ofs);
- #else // 32
+#if BIT64
+ return (IntPtr)ReadInt64(ptr, ofs);
+#else // 32
return (IntPtr) ReadInt32(ptr, ofs);
- #endif
+#endif
}
public static IntPtr ReadIntPtr(IntPtr ptr, int ofs)
{
- #if BIT64
- return (IntPtr) ReadInt64(ptr, ofs);
- #else // 32
+#if BIT64
+ return (IntPtr)ReadInt64(ptr, ofs);
+#else // 32
return (IntPtr) ReadInt32(ptr, ofs);
- #endif
+#endif
}
-
+
public static IntPtr ReadIntPtr(IntPtr ptr)
{
- #if BIT64
- return (IntPtr) ReadInt64(ptr, 0);
- #else // 32
+#if BIT64
+ return (IntPtr)ReadInt64(ptr, 0);
+#else // 32
return (IntPtr) ReadInt32(ptr, 0);
- #endif
+#endif
}
- public static long ReadInt64([MarshalAs(UnmanagedType.AsAny),In] Object ptr, int ofs)
+ public static long ReadInt64([MarshalAs(UnmanagedType.AsAny), In] Object ptr, int ofs)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
}
public static unsafe long ReadInt64(IntPtr ptr, int ofs)
{
try
{
- byte *addr = (byte *)ptr + ofs;
+ byte* addr = (byte*)ptr + ofs;
if ((unchecked((int)addr) & 0x7) == 0)
{
// aligned read
- return *((long *)addr);
+ return *((long*)addr);
}
else
{
// unaligned read
long val;
- byte *valPtr = (byte *)&val;
+ byte* valPtr = (byte*)&val;
valPtr[0] = addr[0];
valPtr[1] = addr[1];
valPtr[2] = addr[2];
@@ -562,13 +570,13 @@ namespace System.Runtime.InteropServices
throw new AccessViolationException();
}
}
-
+
public static long ReadInt64(IntPtr ptr)
{
- return ReadInt64(ptr,0);
+ return ReadInt64(ptr, 0);
}
-
-
+
+
//====================================================================
// Write to memory
//====================================================================
@@ -576,7 +584,7 @@ namespace System.Runtime.InteropServices
{
try
{
- byte *addr = (byte *)ptr + ofs;
+ byte* addr = (byte*)ptr + ofs;
*addr = val;
}
catch (NullReferenceException)
@@ -586,30 +594,30 @@ namespace System.Runtime.InteropServices
}
}
- public static void WriteByte([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, byte val)
+ public static void WriteByte([MarshalAs(UnmanagedType.AsAny), In, Out] Object ptr, int ofs, byte val)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
}
public static void WriteByte(IntPtr ptr, byte val)
{
WriteByte(ptr, 0, val);
}
-
+
public static unsafe void WriteInt16(IntPtr ptr, int ofs, short val)
{
try
{
- byte *addr = (byte *)ptr + ofs;
+ byte* addr = (byte*)ptr + ofs;
if ((unchecked((int)addr) & 0x1) == 0)
{
// aligned write
- *((short *)addr) = val;
+ *((short*)addr) = val;
}
else
{
// unaligned write
- byte *valPtr = (byte *)&val;
+ byte* valPtr = (byte*)&val;
addr[0] = valPtr[0];
addr[1] = valPtr[1];
}
@@ -621,45 +629,45 @@ namespace System.Runtime.InteropServices
}
}
- public static void WriteInt16([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, short val)
+ public static void WriteInt16([MarshalAs(UnmanagedType.AsAny), In, Out] Object ptr, int ofs, short val)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
}
public static void WriteInt16(IntPtr ptr, short val)
{
WriteInt16(ptr, 0, val);
- }
-
+ }
+
public static void WriteInt16(IntPtr ptr, int ofs, char val)
{
WriteInt16(ptr, ofs, (short)val);
}
-
- public static void WriteInt16([In,Out]Object ptr, int ofs, char val)
+
+ public static void WriteInt16([In, Out]Object ptr, int ofs, char val)
{
WriteInt16(ptr, ofs, (short)val);
}
-
+
public static void WriteInt16(IntPtr ptr, char val)
{
WriteInt16(ptr, 0, (short)val);
}
-
+
public static unsafe void WriteInt32(IntPtr ptr, int ofs, int val)
{
try
{
- byte *addr = (byte *)ptr + ofs;
+ byte* addr = (byte*)ptr + ofs;
if ((unchecked((int)addr) & 0x3) == 0)
{
// aligned write
- *((int *)addr) = val;
+ *((int*)addr) = val;
}
else
{
// unaligned write
- byte *valPtr = (byte *)&val;
+ byte* valPtr = (byte*)&val;
addr[0] = valPtr[0];
addr[1] = valPtr[1];
addr[2] = valPtr[2];
@@ -673,57 +681,57 @@ namespace System.Runtime.InteropServices
}
}
- public static void WriteInt32([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, int val)
+ public static void WriteInt32([MarshalAs(UnmanagedType.AsAny), In, Out] Object ptr, int ofs, int val)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
}
public static void WriteInt32(IntPtr ptr, int val)
{
- WriteInt32(ptr,0,val);
- }
-
+ WriteInt32(ptr, 0, val);
+ }
+
public static void WriteIntPtr(IntPtr ptr, int ofs, IntPtr val)
{
- #if BIT64
- WriteInt64(ptr, ofs, (long)val);
- #else // 32
+#if BIT64
+ WriteInt64(ptr, ofs, (long)val);
+#else // 32
WriteInt32(ptr, ofs, (int)val);
- #endif
+#endif
}
-
- public static void WriteIntPtr([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, IntPtr val)
+
+ public static void WriteIntPtr([MarshalAs(UnmanagedType.AsAny), In, Out] Object ptr, int ofs, IntPtr val)
{
- #if BIT64
- WriteInt64(ptr, ofs, (long)val);
- #else // 32
+#if BIT64
+ WriteInt64(ptr, ofs, (long)val);
+#else // 32
WriteInt32(ptr, ofs, (int)val);
- #endif
+#endif
}
-
+
public static void WriteIntPtr(IntPtr ptr, IntPtr val)
{
- #if BIT64
- WriteInt64(ptr, 0, (long)val);
- #else // 32
+#if BIT64
+ WriteInt64(ptr, 0, (long)val);
+#else // 32
WriteInt32(ptr, 0, (int)val);
- #endif
+#endif
}
public static unsafe void WriteInt64(IntPtr ptr, int ofs, long val)
{
try
{
- byte *addr = (byte *)ptr + ofs;
+ byte* addr = (byte*)ptr + ofs;
if ((unchecked((int)addr) & 0x7) == 0)
{
// aligned write
- *((long *)addr) = val;
+ *((long*)addr) = val;
}
else
{
// unaligned write
- byte *valPtr = (byte *)&val;
+ byte* valPtr = (byte*)&val;
addr[0] = valPtr[0];
addr[1] = valPtr[1];
addr[2] = valPtr[2];
@@ -741,30 +749,30 @@ namespace System.Runtime.InteropServices
}
}
- public static void WriteInt64([MarshalAs(UnmanagedType.AsAny),In,Out] Object ptr, int ofs, long val)
+ public static void WriteInt64([MarshalAs(UnmanagedType.AsAny), In, Out] Object ptr, int ofs, long val)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10442
}
public static void WriteInt64(IntPtr ptr, long val)
{
WriteInt64(ptr, 0, val);
}
-
-
+
+
//====================================================================
// GetLastWin32Error
//====================================================================
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern int GetLastWin32Error();
-
+
//====================================================================
// SetLastWin32Error
//====================================================================
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void SetLastWin32Error(int error);
-
+
//====================================================================
// GetHRForLastWin32Error
@@ -784,18 +792,18 @@ namespace System.Runtime.InteropServices
//====================================================================
public static void Prelink(MethodInfo m)
{
- if (m == null)
+ if (m == null)
throw new ArgumentNullException(nameof(m));
Contract.EndContractBlock();
RuntimeMethodInfo rmi = m as RuntimeMethodInfo;
if (rmi == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo);
InternalPrelink(rmi);
}
-
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
private static extern void InternalPrelink(IRuntimeMethodInfo m);
@@ -806,15 +814,15 @@ namespace System.Runtime.InteropServices
Contract.EndContractBlock();
MethodInfo[] mi = c.GetMethods();
- if (mi != null)
+ if (mi != null)
{
- for (int i = 0; i < mi.Length; i++)
+ for (int i = 0; i < mi.Length; i++)
{
Prelink(mi[i]);
}
}
}
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern int GetExceptionCode();
@@ -844,12 +852,12 @@ namespace System.Runtime.InteropServices
{
PtrToStructure(ptr, (object)structure);
}
-
+
//====================================================================
// Creates a new instance of "structuretype" and marshals data from a
// native memory block to it.
//====================================================================
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public static Object PtrToStructure(IntPtr ptr, Type structureType)
{
if (ptr == IntPtr.Zero) return null;
@@ -858,12 +866,12 @@ namespace System.Runtime.InteropServices
throw new ArgumentNullException(nameof(structureType));
if (structureType.IsGenericType)
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), nameof(structureType));
+ throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(structureType));
RuntimeType rt = structureType.UnderlyingSystemType as RuntimeType;
if (rt == null)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), nameof(structureType));
+ throw new ArgumentException(SR.Arg_MustBeType, nameof(structureType));
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -917,10 +925,10 @@ namespace System.Runtime.InteropServices
}
if (rtModule == null)
- throw new ArgumentNullException(nameof(m),Environment.GetResourceString("Argument_MustBeRuntimeModule"));
+ throw new ArgumentNullException(nameof(m), SR.Argument_MustBeRuntimeModule);
return GetHINSTANCE(rtModule.GetNativeHandle());
- }
+ }
[SuppressUnmanagedCodeSecurity]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
@@ -952,14 +960,14 @@ namespace System.Runtime.InteropServices
{
if (errorCode < 0)
return GetExceptionForHRInternal(errorCode, IntPtr.Zero);
- else
+ else
return null;
}
public static Exception GetExceptionForHR(int errorCode, IntPtr errorInfo)
{
if (errorCode < 0)
return GetExceptionForHRInternal(errorCode, errorInfo);
- else
+ else
return null;
}
@@ -987,7 +995,8 @@ namespace System.Runtime.InteropServices
IntPtr pNewMem = Win32Native.LocalAlloc_NoSafeHandle(LMEM_FIXED, unchecked(numBytes));
- if (pNewMem == IntPtr.Zero) {
+ if (pNewMem == IntPtr.Zero)
+ {
throw new OutOfMemoryException();
}
return pNewMem;
@@ -997,11 +1006,13 @@ namespace System.Runtime.InteropServices
{
return AllocHGlobal((IntPtr)cb);
}
-
+
public static void FreeHGlobal(IntPtr hglobal)
{
- if (IsNotWin32Atom(hglobal)) {
- if (IntPtr.Zero != Win32Native.LocalFree(hglobal)) {
+ if (IsNotWin32Atom(hglobal))
+ {
+ if (IntPtr.Zero != Win32Native.LocalFree(hglobal))
+ {
ThrowExceptionForHR(GetHRForLastWin32Error());
}
}
@@ -1010,7 +1021,8 @@ namespace System.Runtime.InteropServices
public static IntPtr ReAllocHGlobal(IntPtr pv, IntPtr cb)
{
IntPtr pNewMem = Win32Native.LocalReAlloc(pv, cb, LMEM_MOVEABLE);
- if (pNewMem == IntPtr.Zero) {
+ if (pNewMem == IntPtr.Zero)
+ {
throw new OutOfMemoryException();
}
return pNewMem;
@@ -1036,18 +1048,18 @@ namespace System.Runtime.InteropServices
UIntPtr len = new UIntPtr((uint)nb);
IntPtr hglobal = Win32Native.LocalAlloc_NoSafeHandle(LMEM_FIXED, len);
-
+
if (hglobal == IntPtr.Zero)
{
throw new OutOfMemoryException();
}
else
{
- s.ConvertToAnsi((byte *)hglobal, nb, false, false);
+ s.ConvertToAnsi((byte*)hglobal, nb, false, false);
return hglobal;
}
}
- }
+ }
unsafe public static IntPtr StringToHGlobalUni(String s)
{
@@ -1065,7 +1077,7 @@ namespace System.Runtime.InteropServices
UIntPtr len = new UIntPtr((uint)nb);
IntPtr hglobal = Win32Native.LocalAlloc_NoSafeHandle(LMEM_FIXED, len);
-
+
if (hglobal == IntPtr.Zero)
{
throw new OutOfMemoryException();
@@ -1105,7 +1117,7 @@ namespace System.Runtime.InteropServices
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int GetHRForException_WinRT(Exception e);
- internal static readonly Guid ManagedNameGuid = new Guid("{0F21F359-AB84-41E8-9A78-36D110E6D2F9}");
+ internal static readonly Guid ManagedNameGuid = new Guid("{0F21F359-AB84-41E8-9A78-36D110E6D2F9}");
//====================================================================
// Given a managed object that wraps an ITypeInfo, return its name
@@ -1115,7 +1127,7 @@ namespace System.Runtime.InteropServices
if (typeInfo == null)
throw new ArgumentNullException(nameof(typeInfo));
Contract.EndContractBlock();
-
+
String strTypeLibName = null;
String strDocString = null;
int dwHelpContext = 0;
@@ -1162,7 +1174,7 @@ namespace System.Runtime.InteropServices
{
throw new PlatformNotSupportedException();
}
-
+
#if FEATURE_COMINTEROP
//====================================================================
@@ -1263,7 +1275,7 @@ namespace System.Runtime.InteropServices
// Overflow checking
if (nb < s.Length)
throw new ArgumentOutOfRangeException(nameof(s));
-
+
IntPtr hglobal = Win32Native.CoTaskMemAlloc(new UIntPtr((uint)nb));
if (hglobal == IntPtr.Zero)
@@ -1274,7 +1286,7 @@ namespace System.Runtime.InteropServices
{
fixed (char* firstChar = s)
{
- String.wstrcpy((char *)hglobal, firstChar, s.Length + 1);
+ String.wstrcpy((char*)hglobal, firstChar, s.Length + 1);
}
return hglobal;
}
@@ -1296,7 +1308,7 @@ namespace System.Runtime.InteropServices
if (nb < s.Length)
throw new ArgumentOutOfRangeException(nameof(s));
- IntPtr pMem = Win32Native.CoTaskMemAlloc(new UIntPtr((uint)nb +1));
+ IntPtr pMem = Win32Native.CoTaskMemAlloc(new UIntPtr((uint)nb + 1));
if (pMem == IntPtr.Zero)
{
@@ -1316,8 +1328,8 @@ namespace System.Runtime.InteropServices
{
// Ansi platforms are no longer supported
return StringToCoTaskMemUni(s);
- }
-
+ }
+
unsafe public static IntPtr StringToCoTaskMemAnsi(String s)
{
if (s == null)
@@ -1340,7 +1352,7 @@ namespace System.Runtime.InteropServices
}
else
{
- s.ConvertToAnsi((byte *)hglobal, nb, false, false);
+ s.ConvertToAnsi((byte*)hglobal, nb, false, false);
return hglobal;
}
}
@@ -1348,7 +1360,8 @@ namespace System.Runtime.InteropServices
public static void FreeCoTaskMem(IntPtr ptr)
{
- if (IsNotWin32Atom(ptr)) {
+ if (IsNotWin32Atom(ptr))
+ {
Win32Native.CoTaskMemFree(ptr);
}
}
@@ -1403,7 +1416,7 @@ namespace System.Runtime.InteropServices
public static int ReleaseComObject(Object o)
{
__ComObject co = null;
-
+
// Make sure the obj is an __ComObject.
try
{
@@ -1411,16 +1424,16 @@ namespace System.Runtime.InteropServices
}
catch (InvalidCastException)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), nameof(o));
+ throw new ArgumentException(SR.Argument_ObjNotComObject, nameof(o));
}
-
+
return co.ReleaseSelf();
- }
+ }
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int InternalReleaseComObject(Object o);
-
+
//====================================================================
// release the COM component and zombie this object
// further usage of this Object might throw an exception
@@ -1440,13 +1453,13 @@ namespace System.Runtime.InteropServices
}
catch (InvalidCastException)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), nameof(o));
+ throw new ArgumentException(SR.Argument_ObjNotComObject, nameof(o));
}
-
+
co.FinalReleaseSelf();
return 0;
- }
+ }
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void InternalFinalReleaseComObject(Object o);
@@ -1457,7 +1470,7 @@ namespace System.Runtime.InteropServices
//====================================================================
public static Object GetComObjectData(Object obj, Object key)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.Arg_PlatformNotSupported);
}
//====================================================================
@@ -1468,7 +1481,7 @@ namespace System.Runtime.InteropServices
//====================================================================
public static bool SetComObjectData(Object obj, Object key, Object data)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.Arg_PlatformNotSupported);
}
#if FEATURE_COMINTEROP
@@ -1482,13 +1495,13 @@ namespace System.Runtime.InteropServices
if (t == null)
throw new ArgumentNullException(nameof(t));
if (!t.IsCOMObject)
- throw new ArgumentException(Environment.GetResourceString("Argument_TypeNotComObject"), nameof(t));
+ throw new ArgumentException(SR.Argument_TypeNotComObject, nameof(t));
if (t.IsGenericType)
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), nameof(t));
+ throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t));
Contract.EndContractBlock();
if (t.IsWindowsRuntimeObject)
- throw new ArgumentException(Environment.GetResourceString("Argument_TypeIsWinRTType"), nameof(t));
+ throw new ArgumentException(SR.Argument_TypeIsWinRTType, nameof(t));
// Check for the null case.
if (o == null)
@@ -1496,9 +1509,9 @@ namespace System.Runtime.InteropServices
// Make sure the object is a COM object.
if (!o.GetType().IsCOMObject)
- throw new ArgumentException(Environment.GetResourceString("Argument_ObjNotComObject"), nameof(o));
+ throw new ArgumentException(SR.Argument_ObjNotComObject, nameof(o));
if (o.GetType().IsWindowsRuntimeObject)
- throw new ArgumentException(Environment.GetResourceString("Argument_ObjIsWinRTObject"), nameof(o));
+ throw new ArgumentException(SR.Argument_ObjIsWinRTObject, nameof(o));
// Check to see if the type of the object is the requested type.
if (o.GetType() == t)
@@ -1537,12 +1550,12 @@ namespace System.Runtime.InteropServices
// IUnknown Helpers
//====================================================================
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern int /* HRESULT */ QueryInterface(IntPtr /* IUnknown */ pUnk, ref Guid iid, out IntPtr ppv);
+ public static extern int /* HRESULT */ QueryInterface(IntPtr /* IUnknown */ pUnk, ref Guid iid, out IntPtr ppv);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern int /* ULONG */ AddRef(IntPtr /* IUnknown */ pUnk );
+ public static extern int /* ULONG */ AddRef(IntPtr /* IUnknown */ pUnk);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern int /* ULONG */ Release(IntPtr /* IUnknown */ pUnk );
+ public static extern int /* ULONG */ Release(IntPtr /* IUnknown */ pUnk);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void GetNativeVariantForObject(Object obj, /* VARIANT * */ IntPtr pDstNativeVariant);
@@ -1553,7 +1566,7 @@ namespace System.Runtime.InteropServices
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern Object GetObjectForNativeVariant(/* VARIANT * */ IntPtr pSrcNativeVariant );
+ public static extern Object GetObjectForNativeVariant(/* VARIANT * */ IntPtr pSrcNativeVariant);
public static T GetObjectForNativeVariant<T>(IntPtr pSrcNativeVariant)
{
@@ -1561,13 +1574,13 @@ namespace System.Runtime.InteropServices
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern Object[] GetObjectsForNativeVariants(/* VARIANT * */ IntPtr aSrcNativeVariant, int cVars );
+ public static extern Object[] GetObjectsForNativeVariants(/* VARIANT * */ IntPtr aSrcNativeVariant, int cVars);
public static T[] GetObjectsForNativeVariants<T>(IntPtr aSrcNativeVariant, int cVars)
{
object[] objects = GetObjectsForNativeVariants(aSrcNativeVariant, cVars);
T[] result = null;
-
+
if (objects != null)
{
result = new T[objects.Length];
@@ -1608,28 +1621,28 @@ namespace System.Runtime.InteropServices
if (type == null)
throw new ArgumentNullException(nameof(type));
if (type.IsImport)
- throw new ArgumentException(Environment.GetResourceString("Argument_TypeMustNotBeComImport"), nameof(type));
+ throw new ArgumentException(SR.Argument_TypeMustNotBeComImport, nameof(type));
if (type.IsGenericType)
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), nameof(type));
+ throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(type));
Contract.EndContractBlock();
IList<CustomAttributeData> cas = CustomAttributeData.GetCustomAttributes(type);
- for (int i = 0; i < cas.Count; i ++)
+ for (int i = 0; i < cas.Count; i++)
{
if (cas[i].Constructor.DeclaringType == typeof(ProgIdAttribute))
{
// Retrieve the PROGID string from the ProgIdAttribute.
IList<CustomAttributeTypedArgument> caConstructorArgs = cas[i].ConstructorArguments;
Debug.Assert(caConstructorArgs.Count == 1, "caConstructorArgs.Count == 1");
-
- CustomAttributeTypedArgument progIdConstructorArg = caConstructorArgs[0];
+
+ CustomAttributeTypedArgument progIdConstructorArg = caConstructorArgs[0];
Debug.Assert(progIdConstructorArg.ArgumentType == typeof(String), "progIdConstructorArg.ArgumentType == typeof(String)");
-
+
String strProgId = (String)progIdConstructorArg.Value;
-
+
if (strProgId == null)
- strProgId = String.Empty;
-
+ strProgId = String.Empty;
+
return strProgId;
}
}
@@ -1673,10 +1686,10 @@ namespace System.Runtime.InteropServices
//========================================================================
private static IntPtr LoadLicenseManager()
{
- Assembly sys = Assembly.Load("System, Version="+ ThisAssembly.Version +
+ Assembly sys = Assembly.Load("System, Version=" + ThisAssembly.Version +
", Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken);
Type t = sys.GetType("System.ComponentModel.LicenseManager");
- if (t == null || !t.IsVisible)
+ if (t == null || !t.IsVisible)
return IntPtr.Zero;
return t.TypeHandle.Value;
}
@@ -1705,20 +1718,20 @@ namespace System.Runtime.InteropServices
// Validate the parameters
if (ptr == IntPtr.Zero)
throw new ArgumentNullException(nameof(ptr));
-
+
if (t == null)
throw new ArgumentNullException(nameof(t));
Contract.EndContractBlock();
-
+
if ((t as RuntimeType) == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), nameof(t));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType, nameof(t));
if (t.IsGenericType)
- throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), nameof(t));
-
+ throw new ArgumentException(SR.Argument_NeedNonGenericType, nameof(t));
+
Type c = t.BaseType;
if (c == null || (c != typeof(Delegate) && c != typeof(MulticastDelegate)))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), nameof(t));
+ throw new ArgumentException(SR.Arg_MustBeDelegate, nameof(t));
return GetDelegateForFunctionPointerInternal(ptr, t);
}
@@ -1748,21 +1761,25 @@ namespace System.Runtime.InteropServices
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern IntPtr GetFunctionPointerForDelegateInternal(Delegate d);
- public static IntPtr SecureStringToBSTR(SecureString s) {
- if( s == null) {
+ public static IntPtr SecureStringToBSTR(SecureString s)
+ {
+ if (s == null)
+ {
throw new ArgumentNullException(nameof(s));
}
Contract.EndContractBlock();
-
+
#if FEATURE_COMINTEROP
return s.MarshalToBSTR();
#else
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(); // https://github.com/dotnet/coreclr/issues/10443
#endif
}
- public static IntPtr SecureStringToCoTaskMemAnsi(SecureString s) {
- if( s == null) {
+ public static IntPtr SecureStringToCoTaskMemAnsi(SecureString s)
+ {
+ if (s == null)
+ {
throw new ArgumentNullException(nameof(s));
}
Contract.EndContractBlock();
@@ -1772,12 +1789,13 @@ namespace System.Runtime.InteropServices
public static IntPtr SecureStringToCoTaskMemUnicode(SecureString s)
{
- if( s == null) {
+ if (s == null)
+ {
throw new ArgumentNullException(nameof(s));
}
Contract.EndContractBlock();
- return s.MarshalToString(globalAlloc: false, unicode: true);
+ return s.MarshalToString(globalAlloc: false, unicode: true);
}
#if FEATURE_COMINTEROP
@@ -1806,8 +1824,10 @@ namespace System.Runtime.InteropServices
FreeCoTaskMem(s);
}
- public static IntPtr SecureStringToGlobalAllocAnsi(SecureString s) {
- if( s == null) {
+ public static IntPtr SecureStringToGlobalAllocAnsi(SecureString s)
+ {
+ if (s == null)
+ {
throw new ArgumentNullException(nameof(s));
}
Contract.EndContractBlock();
@@ -1815,21 +1835,25 @@ namespace System.Runtime.InteropServices
return s.MarshalToString(globalAlloc: true, unicode: false);
}
- public static IntPtr SecureStringToGlobalAllocUnicode(SecureString s) {
- if( s == null) {
+ public static IntPtr SecureStringToGlobalAllocUnicode(SecureString s)
+ {
+ if (s == null)
+ {
throw new ArgumentNullException(nameof(s));
}
Contract.EndContractBlock();
- return s.MarshalToString(globalAlloc: true, unicode: true);;
+ return s.MarshalToString(globalAlloc: true, unicode: true); ;
}
- public static void ZeroFreeGlobalAllocAnsi(IntPtr s) {
+ public static void ZeroFreeGlobalAllocAnsi(IntPtr s)
+ {
Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.lstrlenA(s)));
FreeHGlobal(s);
}
- public static void ZeroFreeGlobalAllocUnicode(IntPtr s) {
+ public static void ZeroFreeGlobalAllocUnicode(IntPtr s)
+ {
Win32Native.ZeroMemory(s, (UIntPtr)(Win32Native.lstrlenW(s) * 2));
FreeHGlobal(s);
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/MarshalDirectiveException.cs b/src/mscorlib/src/System/Runtime/InteropServices/MarshalDirectiveException.cs
index ec1014ecf8..6fe7574e26 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/MarshalDirectiveException.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/MarshalDirectiveException.cs
@@ -11,29 +11,35 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
- using System;
- using System.Runtime.Serialization;
+using System;
+using System.Runtime.Serialization;
+namespace System.Runtime.InteropServices
+{
[Serializable]
- public class MarshalDirectiveException : SystemException {
- public MarshalDirectiveException()
- : base(Environment.GetResourceString("Arg_MarshalDirectiveException")) {
- SetErrorCode(__HResults.COR_E_MARSHALDIRECTIVE);
+ public class MarshalDirectiveException : SystemException
+ {
+ public MarshalDirectiveException()
+ : base(SR.Arg_MarshalDirectiveException)
+ {
+ HResult = __HResults.COR_E_MARSHALDIRECTIVE;
}
-
- public MarshalDirectiveException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_MARSHALDIRECTIVE);
+
+ public MarshalDirectiveException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_MARSHALDIRECTIVE;
}
-
- public MarshalDirectiveException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_MARSHALDIRECTIVE);
+
+ public MarshalDirectiveException(String message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_MARSHALDIRECTIVE;
}
- protected MarshalDirectiveException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ protected MarshalDirectiveException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
}
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/NativeCallableAttribute.cs b/src/mscorlib/src/System/Runtime/InteropServices/NativeCallableAttribute.cs
index 706ef80019..d0ab0d9460 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/NativeCallableAttribute.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/NativeCallableAttribute.cs
@@ -13,7 +13,6 @@ using System.Runtime.CompilerServices;
namespace System.Runtime.InteropServices
{
-
[AttributeUsage(AttributeTargets.Method)]
public sealed class NativeCallableAttribute : Attribute
{
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/NativeMethods.cs b/src/mscorlib/src/System/Runtime/InteropServices/NativeMethods.cs
index 818034ee34..ddd15c2b95 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/NativeMethods.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/NativeMethods.cs
@@ -12,17 +12,18 @@
**/
#if FEATURE_COMINTEROP
-namespace System.Runtime.InteropServices {
-
- internal static class NativeMethods {
-
+namespace System.Runtime.InteropServices
+{
+ internal static class NativeMethods
+ {
[
System.Security.SuppressUnmanagedCodeSecurity,
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("00020400-0000-0000-C000-000000000046")
]
- internal interface IDispatch {
+ internal interface IDispatch
+ {
}
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/NonPortable.cs b/src/mscorlib/src/System/Runtime/InteropServices/NonPortable.cs
index ae974460f7..7b7c5efb90 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/NonPortable.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/NonPortable.cs
@@ -15,7 +15,7 @@ namespace System.Runtime.InteropServices
public static int AddRef(System.IntPtr pUnk)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static bool AreComObjectsAvailableForCleanup()
@@ -25,12 +25,12 @@ namespace System.Runtime.InteropServices
public static System.IntPtr CreateAggregatedObject(System.IntPtr pOuter, object o)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static Object BindToMoniker(String monikerName)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static void CleanupUnusedObjectsInCurrentContext()
@@ -40,42 +40,42 @@ namespace System.Runtime.InteropServices
public static System.IntPtr CreateAggregatedObject<T>(System.IntPtr pOuter, T o)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static object CreateWrapperOfType(object o, System.Type t)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static TWrapper CreateWrapperOfType<T, TWrapper>(T o)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static void ChangeWrapperHandleStrength(Object otp, bool fIsWeak)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static int FinalReleaseComObject(object o)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static System.IntPtr GetComInterfaceForObject(object o, System.Type T)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static System.IntPtr GetComInterfaceForObject(object o, System.Type T, System.Runtime.InteropServices.CustomQueryInterfaceMode mode)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static System.IntPtr GetComInterfaceForObject<T, TInterface>(T o)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static System.IntPtr GetHINSTANCE(System.Reflection.Module m)
@@ -89,67 +89,67 @@ namespace System.Runtime.InteropServices
public static System.IntPtr GetIUnknownForObject(object o)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static void GetNativeVariantForObject(object obj, System.IntPtr pDstNativeVariant)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static void GetNativeVariantForObject<T>(T obj, System.IntPtr pDstNativeVariant)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static Object GetTypedObjectForIUnknown(System.IntPtr pUnk, System.Type t)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static object GetObjectForIUnknown(System.IntPtr pUnk)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static object GetObjectForNativeVariant(System.IntPtr pSrcNativeVariant)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static T GetObjectForNativeVariant<T>(System.IntPtr pSrcNativeVariant)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static object[] GetObjectsForNativeVariants(System.IntPtr aSrcNativeVariant, int cVars)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static T[] GetObjectsForNativeVariants<T>(System.IntPtr aSrcNativeVariant, int cVars)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static int GetStartComSlot(System.Type t)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static System.Type GetTypeFromCLSID(System.Guid clsid)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static string GetTypeInfoName(System.Runtime.InteropServices.ComTypes.ITypeInfo typeInfo)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static object GetUniqueObjectForIUnknown(System.IntPtr unknown)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static bool IsComObject(object o)
@@ -159,22 +159,22 @@ namespace System.Runtime.InteropServices
public static int QueryInterface(System.IntPtr pUnk, ref System.Guid iid, out System.IntPtr ppv)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static int Release(System.IntPtr pUnk)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static int ReleaseComObject(object o)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static void ZeroFreeBSTR(System.IntPtr s)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
}
@@ -182,14 +182,14 @@ namespace System.Runtime.InteropServices
{
public DispatchWrapper(object obj)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public object WrappedObject
{
get
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
}
}
@@ -198,12 +198,12 @@ namespace System.Runtime.InteropServices
{
public static void Combine(object rcw, System.Guid iid, int dispid, System.Delegate d)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
public static System.Delegate Remove(object rcw, System.Guid iid, int dispid, System.Delegate d)
{
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop);
}
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/PInvokeMap.cs b/src/mscorlib/src/System/Runtime/InteropServices/PInvokeMap.cs
index f47165544a..ed289fd14b 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/PInvokeMap.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/PInvokeMap.cs
@@ -9,40 +9,42 @@
// values are defined in CorHdr.h.
//
//
-namespace System.Runtime.InteropServices {
- using System.Runtime.InteropServices;
- using System;
-
+
+using System.Runtime.InteropServices;
+using System;
+
+namespace System.Runtime.InteropServices
+{
// This Enum matchs the CorPinvokeMap defined in CorHdr.h
[Serializable]
internal enum PInvokeMap
{
- NoMangle = 0x0001, // Pinvoke is to use the member name as specified.
- CharSetMask = 0x0006, // Heuristic used in data type & name mapping.
- CharSetNotSpec = 0x0000,
- CharSetAnsi = 0x0002,
- CharSetUnicode = 0x0004,
- CharSetAuto = 0x0006,
-
- PinvokeOLE = 0x0020, // Heuristic: pinvoke will return hresult, with return value becoming the retval param. Not relevant for fields.
- SupportsLastError = 0x0040, // Information about target function. Not relevant for fields.
+ NoMangle = 0x0001, // Pinvoke is to use the member name as specified.
+ CharSetMask = 0x0006, // Heuristic used in data type & name mapping.
+ CharSetNotSpec = 0x0000,
+ CharSetAnsi = 0x0002,
+ CharSetUnicode = 0x0004,
+ CharSetAuto = 0x0006,
+
+ PinvokeOLE = 0x0020, // Heuristic: pinvoke will return hresult, with return value becoming the retval param. Not relevant for fields.
+ SupportsLastError = 0x0040, // Information about target function. Not relevant for fields.
+
+ BestFitMask = 0x0030,
+ BestFitEnabled = 0x0010,
+ BestFitDisabled = 0x0020,
+ BestFitUseAsm = 0x0030,
+
+ ThrowOnUnmappableCharMask = 0x3000,
+ ThrowOnUnmappableCharEnabled = 0x1000,
+ ThrowOnUnmappableCharDisabled = 0x2000,
+ ThrowOnUnmappableCharUseAsm = 0x3000,
- BestFitMask = 0x0030,
- BestFitEnabled = 0x0010,
- BestFitDisabled = 0x0020,
- BestFitUseAsm = 0x0030,
-
- ThrowOnUnmappableCharMask = 0x3000,
- ThrowOnUnmappableCharEnabled = 0x1000,
- ThrowOnUnmappableCharDisabled = 0x2000,
- ThrowOnUnmappableCharUseAsm = 0x3000,
-
// None of the calling convention flags is relevant for fields.
- CallConvMask = 0x0700,
- CallConvWinapi = 0x0100, // Pinvoke will use native callconv appropriate to target windows platform.
- CallConvCdecl = 0x0200,
- CallConvStdcall = 0x0300,
- CallConvThiscall = 0x0400, // In M9, pinvoke will raise exception.
- CallConvFastcall = 0x0500,
+ CallConvMask = 0x0700,
+ CallConvWinapi = 0x0100, // Pinvoke will use native callconv appropriate to target windows platform.
+ CallConvCdecl = 0x0200,
+ CallConvStdcall = 0x0300,
+ CallConvThiscall = 0x0400, // In M9, pinvoke will raise exception.
+ CallConvFastcall = 0x0500,
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/RuntimeEnvironment.cs b/src/mscorlib/src/System/Runtime/InteropServices/RuntimeEnvironment.cs
index 28abe0cb3b..e11e3a437d 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/RuntimeEnvironment.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/RuntimeEnvironment.cs
@@ -24,18 +24,14 @@ using StackCrawlMark = System.Threading.StackCrawlMark;
namespace System.Runtime.InteropServices
{
- static internal class RuntimeEnvironment {
-
+ static internal class RuntimeEnvironment
+ {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern String GetModuleFileName();
- [MethodImpl (MethodImplOptions.NoInlining)]
public static String GetSystemVersion()
{
return Assembly.GetExecutingAssembly().ImageRuntimeVersion;
}
-
-#if FEATURE_COMINTEROP
-#endif // FEATURE_COMINTEROP
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/SEHException.cs b/src/mscorlib/src/System/Runtime/InteropServices/SEHException.cs
index 72b98738ae..5595fadc43 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/SEHException.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/SEHException.cs
@@ -11,30 +11,37 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
- using System.Runtime.InteropServices;
- using System;
- using System.Runtime.Serialization;
+using System.Runtime.InteropServices;
+using System;
+using System.Runtime.Serialization;
+
+namespace System.Runtime.InteropServices
+{
// Exception for Structured Exception Handler exceptions.
//
[Serializable]
- public class SEHException : ExternalException {
- public SEHException()
- : base() {
- SetErrorCode(__HResults.E_FAIL);
+ public class SEHException : ExternalException
+ {
+ public SEHException()
+ : base()
+ {
+ HResult = __HResults.E_FAIL;
}
-
- public SEHException(String message)
- : base(message) {
- SetErrorCode(__HResults.E_FAIL);
+
+ public SEHException(String message)
+ : base(message)
+ {
+ HResult = __HResults.E_FAIL;
}
-
- public SEHException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.E_FAIL);
+
+ public SEHException(String message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.E_FAIL;
}
-
- protected SEHException(SerializationInfo info, StreamingContext context) : base(info, context) {
+
+ protected SEHException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
}
// Exceptions can be resumable, meaning a filtered exception
@@ -48,6 +55,6 @@ namespace System.Runtime.InteropServices {
public virtual bool CanResume()
{
return false;
- }
+ }
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/SafeArrayRankMismatchException.cs b/src/mscorlib/src/System/Runtime/InteropServices/SafeArrayRankMismatchException.cs
index 12bf7e7e47..f39f1f3a41 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/SafeArrayRankMismatchException.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/SafeArrayRankMismatchException.cs
@@ -10,31 +10,35 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
- using System;
- using System.Runtime.Serialization;
+using System;
+using System.Runtime.Serialization;
+namespace System.Runtime.InteropServices
+{
[Serializable]
- public class SafeArrayRankMismatchException : SystemException {
- public SafeArrayRankMismatchException()
- : base(Environment.GetResourceString("Arg_SafeArrayRankMismatchException")) {
- SetErrorCode(__HResults.COR_E_SAFEARRAYRANKMISMATCH);
+ public class SafeArrayRankMismatchException : SystemException
+ {
+ public SafeArrayRankMismatchException()
+ : base(SR.Arg_SafeArrayRankMismatchException)
+ {
+ HResult = __HResults.COR_E_SAFEARRAYRANKMISMATCH;
}
-
- public SafeArrayRankMismatchException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_SAFEARRAYRANKMISMATCH);
- }
-
- public SafeArrayRankMismatchException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_SAFEARRAYRANKMISMATCH);
+
+ public SafeArrayRankMismatchException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_SAFEARRAYRANKMISMATCH;
}
- protected SafeArrayRankMismatchException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ public SafeArrayRankMismatchException(String message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_SAFEARRAYRANKMISMATCH;
}
+ protected SafeArrayRankMismatchException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ }
}
-
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/SafeArrayTypeMismatchException.cs b/src/mscorlib/src/System/Runtime/InteropServices/SafeArrayTypeMismatchException.cs
index 050772af2c..2283263422 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/SafeArrayTypeMismatchException.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/SafeArrayTypeMismatchException.cs
@@ -11,31 +11,35 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
- using System;
- using System.Runtime.Serialization;
+using System;
+using System.Runtime.Serialization;
+namespace System.Runtime.InteropServices
+{
[Serializable]
- public class SafeArrayTypeMismatchException : SystemException {
- public SafeArrayTypeMismatchException()
- : base(Environment.GetResourceString("Arg_SafeArrayTypeMismatchException")) {
- SetErrorCode(__HResults.COR_E_SAFEARRAYTYPEMISMATCH);
+ public class SafeArrayTypeMismatchException : SystemException
+ {
+ public SafeArrayTypeMismatchException()
+ : base(SR.Arg_SafeArrayTypeMismatchException)
+ {
+ HResult = __HResults.COR_E_SAFEARRAYTYPEMISMATCH;
}
-
- public SafeArrayTypeMismatchException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_SAFEARRAYTYPEMISMATCH);
- }
-
- public SafeArrayTypeMismatchException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_SAFEARRAYTYPEMISMATCH);
+
+ public SafeArrayTypeMismatchException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_SAFEARRAYTYPEMISMATCH;
}
- protected SafeArrayTypeMismatchException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ public SafeArrayTypeMismatchException(String message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_SAFEARRAYTYPEMISMATCH;
}
+ protected SafeArrayTypeMismatchException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
+ }
}
-
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs b/src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs
index ee5c3d8e87..aba25e94a3 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs
@@ -66,8 +66,6 @@
// assignments in a static class constructor are under a lock implicitly.
-namespace System.Runtime.InteropServices
-{
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -77,12 +75,13 @@ using Microsoft.Win32.SafeHandles;
using System.Diagnostics;
using System.Diagnostics.Contracts;
-
+namespace System.Runtime.InteropServices
+{
public abstract unsafe class SafeBuffer : SafeHandleZeroOrMinusOneIsInvalid
{
// Steal UIntPtr.MaxValue as our uninitialized value.
- private static readonly UIntPtr Uninitialized = (UIntPtr.Size == 4) ?
- ((UIntPtr) UInt32.MaxValue) : ((UIntPtr) UInt64.MaxValue);
+ private static readonly UIntPtr Uninitialized = (UIntPtr.Size == 4) ?
+ ((UIntPtr)UInt32.MaxValue) : ((UIntPtr)UInt64.MaxValue);
private UIntPtr _numBytes;
@@ -100,15 +99,15 @@ using System.Diagnostics.Contracts;
public void Initialize(ulong numBytes)
{
if (numBytes < 0)
- throw new ArgumentOutOfRangeException(nameof(numBytes), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(numBytes), SR.ArgumentOutOfRange_NeedNonNegNum);
if (IntPtr.Size == 4 && numBytes > UInt32.MaxValue)
- throw new ArgumentOutOfRangeException(nameof(numBytes), Environment.GetResourceString("ArgumentOutOfRange_AddressSpace"));
+ throw new ArgumentOutOfRangeException(nameof(numBytes), SR.ArgumentOutOfRange_AddressSpace);
Contract.EndContractBlock();
if (numBytes >= (ulong)Uninitialized)
- throw new ArgumentOutOfRangeException(nameof(numBytes), Environment.GetResourceString("ArgumentOutOfRange_UIntPtrMax-1"));
+ throw new ArgumentOutOfRangeException(nameof(numBytes), SR.ArgumentOutOfRange_UIntPtrMax);
- _numBytes = (UIntPtr) numBytes;
+ _numBytes = (UIntPtr)numBytes;
}
/// <summary>
@@ -119,18 +118,18 @@ using System.Diagnostics.Contracts;
public void Initialize(uint numElements, uint sizeOfEachElement)
{
if (numElements < 0)
- throw new ArgumentOutOfRangeException(nameof(numElements), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(numElements), SR.ArgumentOutOfRange_NeedNonNegNum);
if (sizeOfEachElement < 0)
- throw new ArgumentOutOfRangeException(nameof(sizeOfEachElement), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(sizeOfEachElement), SR.ArgumentOutOfRange_NeedNonNegNum);
if (IntPtr.Size == 4 && numElements * sizeOfEachElement > UInt32.MaxValue)
- throw new ArgumentOutOfRangeException("numBytes", Environment.GetResourceString("ArgumentOutOfRange_AddressSpace"));
+ throw new ArgumentOutOfRangeException("numBytes", SR.ArgumentOutOfRange_AddressSpace);
Contract.EndContractBlock();
if (numElements * sizeOfEachElement >= (ulong)Uninitialized)
- throw new ArgumentOutOfRangeException(nameof(numElements), Environment.GetResourceString("ArgumentOutOfRange_UIntPtrMax-1"));
+ throw new ArgumentOutOfRangeException(nameof(numElements), SR.ArgumentOutOfRange_UIntPtrMax);
- _numBytes = checked((UIntPtr) (numElements * sizeOfEachElement));
+ _numBytes = checked((UIntPtr)(numElements * sizeOfEachElement));
}
/// <summary>
@@ -209,7 +208,8 @@ using System.Diagnostics.Contracts;
/// may have to consider alignment.</param>
/// <returns>An instance of T read from memory.</returns>
[CLSCompliant(false)]
- public T Read<T>(ulong byteOffset) where T : struct {
+ public T Read<T>(ulong byteOffset) where T : struct
+ {
if (_numBytes == Uninitialized)
throw NotInitialized();
@@ -240,13 +240,13 @@ using System.Diagnostics.Contracts;
where T : struct
{
if (array == null)
- throw new ArgumentNullException(nameof(array), Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(array), SR.ArgumentNull_Buffer);
if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (array.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
if (_numBytes == Uninitialized)
@@ -282,7 +282,8 @@ using System.Diagnostics.Contracts;
/// may have to consider alignment.</param>
/// <param name="value">The value type to write to memory.</param>
[CLSCompliant(false)]
- public void Write<T>(ulong byteOffset, T value) where T : struct {
+ public void Write<T>(ulong byteOffset, T value) where T : struct
+ {
if (_numBytes == Uninitialized)
throw NotInitialized();
@@ -310,13 +311,13 @@ using System.Diagnostics.Contracts;
where T : struct
{
if (array == null)
- throw new ArgumentNullException(nameof(array), Environment.GetResourceString("ArgumentNull_Buffer"));
+ throw new ArgumentNullException(nameof(array), SR.ArgumentNull_Buffer);
if (index < 0)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
if (array.Length - index < count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
+ throw new ArgumentException(SR.Argument_InvalidOffLen);
Contract.EndContractBlock();
if (_numBytes == Uninitialized)
@@ -326,7 +327,7 @@ using System.Diagnostics.Contracts;
uint alignedSizeofT = Marshal.AlignedSizeOf<T>();
byte* ptr = (byte*)handle + byteOffset;
SpaceCheck(ptr, checked((ulong)(alignedSizeofT * count)));
-
+
bool mustCallRelease = false;
RuntimeHelpers.PrepareConstrainedRegions();
try
@@ -347,35 +348,37 @@ using System.Diagnostics.Contracts;
/// Returns the number of bytes in the memory region.
/// </summary>
[CLSCompliant(false)]
- public ulong ByteLength {
- get {
+ public ulong ByteLength
+ {
+ get
+ {
if (_numBytes == Uninitialized)
throw NotInitialized();
- return (ulong) _numBytes;
+ return (ulong)_numBytes;
}
}
/* No indexer. The perf would be misleadingly bad. People should use
* AcquirePointer and ReleasePointer instead. */
-
+
private void SpaceCheck(byte* ptr, ulong sizeInBytes)
{
if ((ulong)_numBytes < sizeInBytes)
NotEnoughRoom();
- if ((ulong)(ptr - (byte*) handle) > ((ulong)_numBytes) - sizeInBytes)
+ if ((ulong)(ptr - (byte*)handle) > ((ulong)_numBytes) - sizeInBytes)
NotEnoughRoom();
}
private static void NotEnoughRoom()
{
- throw new ArgumentException(Environment.GetResourceString("Arg_BufferTooSmall"));
+ throw new ArgumentException(SR.Arg_BufferTooSmall);
}
private static InvalidOperationException NotInitialized()
{
Debug.Assert(false, "Uninitialized SafeBuffer! Someone needs to call Initialize before using this instance!");
- return new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MustCallInitialize"));
+ return new InvalidOperationException(SR.InvalidOperation_MustCallInitialize);
}
// FCALL limitations mean we can't have generic FCALL methods. However, we can pass
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/SafeHandle.cs b/src/mscorlib/src/System/Runtime/InteropServices/SafeHandle.cs
index 591caa2877..6654ec9b00 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/SafeHandle.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/SafeHandle.cs
@@ -14,276 +14,281 @@
**
===========================================================*/
-namespace System.Runtime.InteropServices {
-
-using System;
-using System.Reflection;
-using System.Threading;
-using System.Runtime;
-using System.Runtime.CompilerServices;
-using System.IO;
-using System.Runtime.ConstrainedExecution;
-using System.Runtime.Versioning;
-
-/*
- Problems addressed by the SafeHandle class:
- 1) Critical finalization - ensure we never leak OS resources in SQL. Done
- without running truly arbitrary & unbounded amounts of managed code.
- 2) Reduced graph promotion - during finalization, keep object graph small
- 3) GC.KeepAlive behavior - P/Invoke vs. finalizer thread race conditions (HandleRef)
- 4) Elimination of security race conditions w/ explicit calls to Close (HandleProtector)
- 5) Enforcement of the above via the type system - Don't use IntPtr anymore.
- 6) Allows the handle lifetime to be controlled externally via a boolean.
-
- Subclasses of SafeHandle will implement the ReleaseHandle abstract method
- used to execute any code required to free the handle. This method will be
- prepared as a constrained execution region at instance construction time
- (along with all the methods in its statically determinable call graph). This
- implies that we won't get any inconvenient jit allocation errors or rude
- thread abort interrupts while releasing the handle but the user must still
- write careful code to avoid injecting fault paths of their own (see the CER
- spec for more details). In particular, any sub-methods you call should be
- decorated with a reliability contract of the appropriate level. In most cases
- this should be:
- ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)
- Also, any P/Invoke methods should use the SuppressUnmanagedCodeSecurity
- attribute to avoid a runtime security check that can also inject failures
- (even if the check is guaranteed to pass).
-
- The GC will run ReleaseHandle methods after any normal finalizers have been
- run for objects that were collected at the same time. This ensures classes
- like FileStream can run a normal finalizer to flush out existing buffered
- data. This is key - it means adding this class to a class like FileStream does
- not alter our current semantics w.r.t. finalization today.
-
- Subclasses must also implement the IsInvalid property so that the
- infrastructure can tell when critical finalization is actually required.
- Again, this method is prepared ahead of time. It's envisioned that direct
- subclasses of SafeHandle will provide an IsInvalid implementation that suits
- the general type of handle they support (null is invalid, -1 is invalid etc.)
- and then these classes will be further derived for specific safe handle types.
-
- Most classes using SafeHandle should not provide a finalizer. If they do
- need to do so (ie, for flushing out file buffers, needing to write some data
- back into memory, etc), then they can provide a finalizer that will be
- guaranteed to run before the SafeHandle's critical finalizer.
-
- Note that SafeHandle's ReleaseHandle is called from a constrained execution
- region, and is eagerly prepared before we create your class. This means you
- should only call methods with an appropriate reliability contract from your
- ReleaseHandle method.
-
- Subclasses are expected to be written as follows (note that
- SuppressUnmanagedCodeSecurity should always be used on any P/Invoke methods
- invoked as part of ReleaseHandle, in order to switch the security check from
- runtime to jit time and thus remove a possible failure path from the
- invocation of the method):
-
- internal sealed MySafeHandleSubclass : SafeHandle {
- // Called by P/Invoke when returning SafeHandles
- private MySafeHandleSubclass() : base(IntPtr.Zero, true)
- {
+namespace System.Runtime.InteropServices
+{
+ using System;
+ using System.Reflection;
+ using System.Threading;
+ using System.Runtime;
+ using System.Runtime.CompilerServices;
+ using System.IO;
+ using System.Runtime.ConstrainedExecution;
+ using System.Runtime.Versioning;
+
+ /*
+ Problems addressed by the SafeHandle class:
+ 1) Critical finalization - ensure we never leak OS resources in SQL. Done
+ without running truly arbitrary & unbounded amounts of managed code.
+ 2) Reduced graph promotion - during finalization, keep object graph small
+ 3) GC.KeepAlive behavior - P/Invoke vs. finalizer thread race conditions (HandleRef)
+ 4) Elimination of security race conditions w/ explicit calls to Close (HandleProtector)
+ 5) Enforcement of the above via the type system - Don't use IntPtr anymore.
+ 6) Allows the handle lifetime to be controlled externally via a boolean.
+
+ Subclasses of SafeHandle will implement the ReleaseHandle abstract method
+ used to execute any code required to free the handle. This method will be
+ prepared as a constrained execution region at instance construction time
+ (along with all the methods in its statically determinable call graph). This
+ implies that we won't get any inconvenient jit allocation errors or rude
+ thread abort interrupts while releasing the handle but the user must still
+ write careful code to avoid injecting fault paths of their own (see the CER
+ spec for more details). In particular, any sub-methods you call should be
+ decorated with a reliability contract of the appropriate level. In most cases
+ this should be:
+ ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)
+ Also, any P/Invoke methods should use the SuppressUnmanagedCodeSecurity
+ attribute to avoid a runtime security check that can also inject failures
+ (even if the check is guaranteed to pass).
+
+ The GC will run ReleaseHandle methods after any normal finalizers have been
+ run for objects that were collected at the same time. This ensures classes
+ like FileStream can run a normal finalizer to flush out existing buffered
+ data. This is key - it means adding this class to a class like FileStream does
+ not alter our current semantics w.r.t. finalization today.
+
+ Subclasses must also implement the IsInvalid property so that the
+ infrastructure can tell when critical finalization is actually required.
+ Again, this method is prepared ahead of time. It's envisioned that direct
+ subclasses of SafeHandle will provide an IsInvalid implementation that suits
+ the general type of handle they support (null is invalid, -1 is invalid etc.)
+ and then these classes will be further derived for specific safe handle types.
+
+ Most classes using SafeHandle should not provide a finalizer. If they do
+ need to do so (ie, for flushing out file buffers, needing to write some data
+ back into memory, etc), then they can provide a finalizer that will be
+ guaranteed to run before the SafeHandle's critical finalizer.
+
+ Note that SafeHandle's ReleaseHandle is called from a constrained execution
+ region, and is eagerly prepared before we create your class. This means you
+ should only call methods with an appropriate reliability contract from your
+ ReleaseHandle method.
+
+ Subclasses are expected to be written as follows (note that
+ SuppressUnmanagedCodeSecurity should always be used on any P/Invoke methods
+ invoked as part of ReleaseHandle, in order to switch the security check from
+ runtime to jit time and thus remove a possible failure path from the
+ invocation of the method):
+
+ internal sealed MySafeHandleSubclass : SafeHandle {
+ // Called by P/Invoke when returning SafeHandles
+ private MySafeHandleSubclass() : base(IntPtr.Zero, true)
+ {
+ }
+
+ // If & only if you need to support user-supplied handles
+ internal MySafeHandleSubclass(IntPtr preexistingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(preexistingHandle);
+ }
+
+ // Do not provide a finalizer - SafeHandle's critical finalizer will
+ // call ReleaseHandle for you.
+
+ public override bool IsInvalid {
+ get { return handle == IntPtr.Zero; }
+ }
+
+ override protected bool ReleaseHandle()
+ {
+ return MyNativeMethods.CloseHandle(handle);
+ }
}
- // If & only if you need to support user-supplied handles
- internal MySafeHandleSubclass(IntPtr preexistingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
- {
- SetHandle(preexistingHandle);
- }
+ Then elsewhere to create one of these SafeHandles, define a method
+ with the following type of signature (CreateFile follows this model).
+ Note that when returning a SafeHandle like this, P/Invoke will call your
+ class's default constructor. Also, you probably want to define CloseHandle
+ somewhere, and remember to apply a reliability contract to it.
- // Do not provide a finalizer - SafeHandle's critical finalizer will
- // call ReleaseHandle for you.
+ [SuppressUnmanagedCodeSecurity]
+ internal static class MyNativeMethods {
+ [DllImport("kernel32")]
+ private static extern MySafeHandleSubclass CreateHandle(int someState);
- public override bool IsInvalid {
- get { return handle == IntPtr.Zero; }
+ [DllImport("kernel32", SetLastError=true), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ private static extern bool CloseHandle(IntPtr handle);
}
- override protected bool ReleaseHandle()
- {
- return MyNativeMethods.CloseHandle(handle);
- }
- }
-
- Then elsewhere to create one of these SafeHandles, define a method
- with the following type of signature (CreateFile follows this model).
- Note that when returning a SafeHandle like this, P/Invoke will call your
- class's default constructor. Also, you probably want to define CloseHandle
- somewhere, and remember to apply a reliability contract to it.
-
- [SuppressUnmanagedCodeSecurity]
- internal static class MyNativeMethods {
- [DllImport("kernel32")]
- private static extern MySafeHandleSubclass CreateHandle(int someState);
-
- [DllImport("kernel32", SetLastError=true), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- private static extern bool CloseHandle(IntPtr handle);
- }
-
- Drawbacks with this implementation:
- 1) Requires some magic to run the critical finalizer.
- 2) Requires more memory than just an IntPtr.
- 3) If you use DangerousAddRef and forget to call DangerousRelease, you can leak a SafeHandle. Use CER's & don't do that.
- */
-
-
-// This class should not be serializable - it's a handle. We require unmanaged
-// code permission to subclass SafeHandle to prevent people from writing a
-// subclass and suddenly being able to run arbitrary native code with the
-// same signature as CloseHandle. This is technically a little redundant, but
-// we'll do this to ensure we've cut off all attack vectors. Similarly, all
-// methods have a link demand to ensure untrusted code cannot directly edit
-// or alter a handle.
-public abstract class SafeHandle : CriticalFinalizerObject, IDisposable
-{
- // ! Do not add or rearrange fields as the EE depends on this layout.
- //------------------------------------------------------------------
+ Drawbacks with this implementation:
+ 1) Requires some magic to run the critical finalizer.
+ 2) Requires more memory than just an IntPtr.
+ 3) If you use DangerousAddRef and forget to call DangerousRelease, you can leak a SafeHandle. Use CER's & don't do that.
+ */
+
+
+ // This class should not be serializable - it's a handle. We require unmanaged
+ // code permission to subclass SafeHandle to prevent people from writing a
+ // subclass and suddenly being able to run arbitrary native code with the
+ // same signature as CloseHandle. This is technically a little redundant, but
+ // we'll do this to ensure we've cut off all attack vectors. Similarly, all
+ // methods have a link demand to ensure untrusted code cannot directly edit
+ // or alter a handle.
+ public abstract class SafeHandle : CriticalFinalizerObject, IDisposable
+ {
+ // ! Do not add or rearrange fields as the EE depends on this layout.
+ //------------------------------------------------------------------
#if DEBUG
- // FxCop thinks this field is marshaled and so it raises a CA2101 error unless
- // we specify this. In practice this is never presented to Win32.
- [MarshalAs(UnmanagedType.LPWStr)]
- private String _stackTrace; // Where we allocated this SafeHandle.
+ // FxCop thinks this field is marshaled and so it raises a CA2101 error unless
+ // we specify this. In practice this is never presented to Win32.
+ [MarshalAs(UnmanagedType.LPWStr)]
+ private String _stackTrace; // Where we allocated this SafeHandle.
#endif
- protected IntPtr handle; // this must be protected so derived classes can use out params.
- private int _state; // Combined ref count and closed/disposed flags (so we can atomically modify them).
- private bool _ownsHandle; // Whether we can release this handle.
+ protected IntPtr handle; // this must be protected so derived classes can use out params.
+ private int _state; // Combined ref count and closed/disposed flags (so we can atomically modify them).
+ private bool _ownsHandle; // Whether we can release this handle.
#pragma warning disable 414
- private bool _fullyInitialized; // Whether constructor completed.
+ private bool _fullyInitialized; // Whether constructor completed.
#pragma warning restore 414
- // Creates a SafeHandle class. Users must then set the Handle property.
- // To prevent the SafeHandle from being freed, write a subclass that
- // doesn't define a finalizer.
- protected SafeHandle(IntPtr invalidHandleValue, bool ownsHandle)
- {
- handle = invalidHandleValue;
- _state = 4; // Ref count 1 and not closed or disposed.
- _ownsHandle = ownsHandle;
+ // Creates a SafeHandle class. Users must then set the Handle property.
+ // To prevent the SafeHandle from being freed, write a subclass that
+ // doesn't define a finalizer.
+ protected SafeHandle(IntPtr invalidHandleValue, bool ownsHandle)
+ {
+ handle = invalidHandleValue;
+ _state = 4; // Ref count 1 and not closed or disposed.
+ _ownsHandle = ownsHandle;
- if (!ownsHandle)
- GC.SuppressFinalize(this);
+ if (!ownsHandle)
+ GC.SuppressFinalize(this);
#if DEBUG
- if (BCLDebug.SafeHandleStackTracesEnabled)
- _stackTrace = Environment.GetStackTrace(null, false);
- else
- _stackTrace = "For a stack trace showing who allocated this SafeHandle, set SafeHandleStackTraces to 1 and rerun your app.";
+ if (BCLDebug.SafeHandleStackTracesEnabled)
+ _stackTrace = Environment.GetStackTrace(null, false);
+ else
+ _stackTrace = "For a stack trace showing who allocated this SafeHandle, set SafeHandleStackTraces to 1 and rerun your app.";
#endif
- // Set this last to prevent SafeHandle's finalizer from freeing an
- // invalid handle. This means we don't have to worry about
- // ThreadAbortExceptions interrupting this constructor or the managed
- // constructors on subclasses that call this constructor.
- _fullyInitialized = true;
- }
-
- // Migrating InheritanceDemands requires this default ctor, so we can mark it critical
- protected SafeHandle()
- {
- BCLDebug.Assert(false, "SafeHandle's protected default ctor should never be used!");
- throw new NotImplementedException();
- }
-
- ~SafeHandle()
- {
- Dispose(false);
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- extern void InternalFinalize();
-
- protected void SetHandle(IntPtr handle) {
- this.handle = handle;
+ // Set this last to prevent SafeHandle's finalizer from freeing an
+ // invalid handle. This means we don't have to worry about
+ // ThreadAbortExceptions interrupting this constructor or the managed
+ // constructors on subclasses that call this constructor.
+ _fullyInitialized = true;
+ }
+
+ // Migrating InheritanceDemands requires this default ctor, so we can mark it critical
+ protected SafeHandle()
+ {
+ BCLDebug.Assert(false, "SafeHandle's protected default ctor should never be used!");
+ throw new NotImplementedException();
+ }
+
+ ~SafeHandle()
+ {
+ Dispose(false);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern void InternalFinalize();
+
+ protected void SetHandle(IntPtr handle)
+ {
+ this.handle = handle;
+ }
+
+ // This method is necessary for getting an IntPtr out of a SafeHandle.
+ // Used to tell whether a call to create the handle succeeded by comparing
+ // the handle against a known invalid value, and for backwards
+ // compatibility to support the handle properties returning IntPtrs on
+ // many of our Framework classes.
+ // Note that this method is dangerous for two reasons:
+ // 1) If the handle has been marked invalid with SetHandleasInvalid,
+ // DangerousGetHandle will still return the original handle value.
+ // 2) The handle returned may be recycled at any point. At best this means
+ // the handle might stop working suddenly. At worst, if the handle or
+ // the resource the handle represents is exposed to untrusted code in
+ // any way, this can lead to a handle recycling security attack (i.e. an
+ // untrusted caller can query data on the handle you've just returned
+ // and get back information for an entirely unrelated resource).
+ public IntPtr DangerousGetHandle()
+ {
+ return handle;
+ }
+
+ public bool IsClosed
+ {
+ get { return (_state & 1) == 1; }
+ }
+
+ public abstract bool IsInvalid
+ {
+ get;
+ }
+
+ public void Close()
+ {
+ Dispose(true);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ InternalDispose();
+ else
+ InternalFinalize();
+ }
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern void InternalDispose();
+
+ // This should only be called for cases when you know for a fact that
+ // your handle is invalid and you want to record that information.
+ // An example is calling a syscall and getting back ERROR_INVALID_HANDLE.
+ // This method will normally leak handles!
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern void SetHandleAsInvalid();
+
+ // Implement this abstract method in your derived class to specify how to
+ // free the handle. Be careful not write any code that's subject to faults
+ // in this method (the runtime will prepare the infrastructure for you so
+ // that no jit allocations etc. will occur, but don't allocate memory unless
+ // you can deal with the failure and still free the handle).
+ // The boolean returned should be true for success and false if the runtime
+ // should fire a SafeHandleCriticalFailure MDA (CustomerDebugProbe) if that
+ // MDA is enabled.
+ protected abstract bool ReleaseHandle();
+
+ // Add a reason why this handle should not be relinquished (i.e. have
+ // ReleaseHandle called on it). This method has dangerous in the name since
+ // it must always be used carefully (e.g. called within a CER) to avoid
+ // leakage of the handle. It returns a boolean indicating whether the
+ // increment was actually performed to make it easy for program logic to
+ // back out in failure cases (i.e. is a call to DangerousRelease needed).
+ // It is passed back via a ref parameter rather than as a direct return so
+ // that callers need not worry about the atomicity of calling the routine
+ // and assigning the return value to a variable (the variable should be
+ // explicitly set to false prior to the call). The only failure cases are
+ // when the method is interrupted prior to processing by a thread abort or
+ // when the handle has already been (or is in the process of being)
+ // released.
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern void DangerousAddRef(ref bool success);
+
+ // Partner to DangerousAddRef. This should always be successful when used in
+ // a correct manner (i.e. matching a successful DangerousAddRef and called
+ // from a region such as a CER where a thread abort cannot interrupt
+ // processing). In the same way that unbalanced DangerousAddRef calls can
+ // cause resource leakage, unbalanced DangerousRelease calls may cause
+ // invalid handle states to become visible to other threads. This
+ // constitutes a potential security hole (via handle recycling) as well as a
+ // correctness problem -- so don't ever expose Dangerous* calls out to
+ // untrusted code.
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern void DangerousRelease();
}
-
- // This method is necessary for getting an IntPtr out of a SafeHandle.
- // Used to tell whether a call to create the handle succeeded by comparing
- // the handle against a known invalid value, and for backwards
- // compatibility to support the handle properties returning IntPtrs on
- // many of our Framework classes.
- // Note that this method is dangerous for two reasons:
- // 1) If the handle has been marked invalid with SetHandleasInvalid,
- // DangerousGetHandle will still return the original handle value.
- // 2) The handle returned may be recycled at any point. At best this means
- // the handle might stop working suddenly. At worst, if the handle or
- // the resource the handle represents is exposed to untrusted code in
- // any way, this can lead to a handle recycling security attack (i.e. an
- // untrusted caller can query data on the handle you've just returned
- // and get back information for an entirely unrelated resource).
- public IntPtr DangerousGetHandle()
- {
- return handle;
- }
-
- public bool IsClosed {
- get { return (_state & 1) == 1; }
- }
-
- public abstract bool IsInvalid {
- get;
- }
-
- public void Close() {
- Dispose(true);
- }
-
- public void Dispose() {
- Dispose(true);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- InternalDispose();
- else
- InternalFinalize();
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern void InternalDispose();
-
- // This should only be called for cases when you know for a fact that
- // your handle is invalid and you want to record that information.
- // An example is calling a syscall and getting back ERROR_INVALID_HANDLE.
- // This method will normally leak handles!
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public extern void SetHandleAsInvalid();
-
- // Implement this abstract method in your derived class to specify how to
- // free the handle. Be careful not write any code that's subject to faults
- // in this method (the runtime will prepare the infrastructure for you so
- // that no jit allocations etc. will occur, but don't allocate memory unless
- // you can deal with the failure and still free the handle).
- // The boolean returned should be true for success and false if the runtime
- // should fire a SafeHandleCriticalFailure MDA (CustomerDebugProbe) if that
- // MDA is enabled.
- protected abstract bool ReleaseHandle();
-
- // Add a reason why this handle should not be relinquished (i.e. have
- // ReleaseHandle called on it). This method has dangerous in the name since
- // it must always be used carefully (e.g. called within a CER) to avoid
- // leakage of the handle. It returns a boolean indicating whether the
- // increment was actually performed to make it easy for program logic to
- // back out in failure cases (i.e. is a call to DangerousRelease needed).
- // It is passed back via a ref parameter rather than as a direct return so
- // that callers need not worry about the atomicity of calling the routine
- // and assigning the return value to a variable (the variable should be
- // explicitly set to false prior to the call). The only failure cases are
- // when the method is interrupted prior to processing by a thread abort or
- // when the handle has already been (or is in the process of being)
- // released.
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public extern void DangerousAddRef(ref bool success);
-
- // Partner to DangerousAddRef. This should always be successful when used in
- // a correct manner (i.e. matching a successful DangerousAddRef and called
- // from a region such as a CER where a thread abort cannot interrupt
- // processing). In the same way that unbalanced DangerousAddRef calls can
- // cause resource leakage, unbalanced DangerousRelease calls may cause
- // invalid handle states to become visible to other threads. This
- // constitutes a potential security hole (via handle recycling) as well as a
- // correctness problem -- so don't ever expose Dangerous* calls out to
- // untrusted code.
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public extern void DangerousRelease();
-}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/UnknownWrapper.cs b/src/mscorlib/src/System/Runtime/InteropServices/UnknownWrapper.cs
index 1f70108a02..c758ae1b4f 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/UnknownWrapper.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/UnknownWrapper.cs
@@ -11,10 +11,11 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
-
- using System;
+using System;
+
+namespace System.Runtime.InteropServices
+{
[Serializable]
public sealed class UnknownWrapper
{
@@ -23,9 +24,9 @@ namespace System.Runtime.InteropServices {
m_WrappedObject = obj;
}
- public Object WrappedObject
+ public Object WrappedObject
{
- get
+ get
{
return m_WrappedObject;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/VariantWrapper.cs b/src/mscorlib/src/System/Runtime/InteropServices/VariantWrapper.cs
index 3f5120af39..50689e08f8 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/VariantWrapper.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/VariantWrapper.cs
@@ -11,10 +11,11 @@
**
=============================================================================*/
-namespace System.Runtime.InteropServices {
-
- using System;
+using System;
+
+namespace System.Runtime.InteropServices
+{
[Serializable]
public sealed class VariantWrapper
@@ -24,9 +25,9 @@ namespace System.Runtime.InteropServices {
m_WrappedObject = obj;
}
- public Object WrappedObject
+ public Object WrappedObject
{
- get
+ get
{
return m_WrappedObject;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/Attributes.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/Attributes.cs
index 7fa2420530..d78aae216b 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/Attributes.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/Attributes.cs
@@ -90,14 +90,14 @@ namespace System.Runtime.InteropServices.WindowsRuntime
[AttributeUsage(AttributeTargets.Parameter, Inherited = false, AllowMultiple = false)]
public sealed class ReadOnlyArrayAttribute : Attribute
{
- public ReadOnlyArrayAttribute() {}
+ public ReadOnlyArrayAttribute() { }
}
// Applies to write-only array parameters
[AttributeUsage(AttributeTargets.Parameter, Inherited = false, AllowMultiple = false)]
public sealed class WriteOnlyArrayAttribute : Attribute
{
- public WriteOnlyArrayAttribute() {}
+ public WriteOnlyArrayAttribute() { }
}
@@ -119,5 +119,4 @@ namespace System.Runtime.InteropServices.WindowsRuntime
get { return m_Name; }
}
}
-
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToCollectionAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToCollectionAdapter.cs
index e3c6a926d3..350920564a 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToCollectionAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToCollectionAdapter.cs
@@ -39,7 +39,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
uint size = _this.Size;
if (((uint)Int32.MaxValue) < size)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CollectionBackingListTooLarge"));
+ throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingListTooLarge);
}
return (int)size;
@@ -68,7 +68,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// ICollection expects the destination array to be single-dimensional.
if (array.Rank != 1)
- throw new ArgumentException(Environment.GetResourceString("Arg_RankMultiDimNotSupported"));
+ throw new ArgumentException(SR.Arg_RankMultiDimNotSupported);
int destLB = array.GetLowerBound(0);
@@ -87,11 +87,11 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Array items = Array.CreateInstance(typeof(object), new int[] { 1 }, new int[] { -1 });
// list.CopyTo(items, 0);
- if(srcLen > (destLen - (arrayIndex - destLB)))
- throw new ArgumentException(Environment.GetResourceString("Argument_InsufficientSpaceToCopyCollection"));
+ if (srcLen > (destLen - (arrayIndex - destLB)))
+ throw new ArgumentException(SR.Argument_InsufficientSpaceToCopyCollection);
- if(arrayIndex - destLB > destLen)
- throw new ArgumentException(Environment.GetResourceString("Argument_IndexOutOfArrayBounds"));
+ if (arrayIndex - destLB > destLen)
+ throw new ArgumentException(SR.Argument_IndexOutOfArrayBounds);
// We need to verify the index as we;
IBindableVector _this = JitHelpers.UnsafeCast<IBindableVector>(this);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToListAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToListAdapter.cs
index d6e50f5164..539b8020b8 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToListAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/BindableVectorToListAdapter.cs
@@ -60,7 +60,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
uint size = _this.Size;
if (((uint)Int32.MaxValue) < size)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CollectionBackingListTooLarge"));
+ throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingListTooLarge);
}
return (int)(size - 1);
@@ -109,7 +109,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (((uint)Int32.MaxValue) < index)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CollectionBackingListTooLarge"));
+ throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingListTooLarge);
}
return (int)index;
@@ -137,7 +137,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
if (((uint)Int32.MaxValue) < index)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CollectionBackingListTooLarge"));
+ throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingListTooLarge);
}
RemoveAtHelper(_this, index);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIKeyValuePairImpl.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIKeyValuePairImpl.cs
index 3a52d12234..86321e6191 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIKeyValuePairImpl.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIKeyValuePairImpl.cs
@@ -47,7 +47,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal static object UnboxHelper(object wrapper)
{
Contract.Requires(wrapper != null);
-
+
CLRIKeyValuePairImpl<K, V> reference = (CLRIKeyValuePairImpl<K, V>)wrapper;
return reference._pair;
}
@@ -61,6 +61,5 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
return _pair;
}
-
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs
index b7dad17a6b..aa0f3ba056 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIPropertyValueImpl.cs
@@ -25,9 +25,12 @@ namespace System.Runtime.InteropServices.WindowsRuntime
_data = data;
}
- private static Tuple<Type, PropertyType>[] NumericScalarTypes {
- get {
- if (s_numericScalarTypes == null) {
+ private static Tuple<Type, PropertyType>[] NumericScalarTypes
+ {
+ get
+ {
+ if (s_numericScalarTypes == null)
+ {
Tuple<Type, PropertyType>[] numericScalarTypes = new Tuple<Type, PropertyType>[] {
new Tuple<Type, PropertyType>(typeof(Byte), PropertyType.UInt8),
new Tuple<Type, PropertyType>(typeof(Int16), PropertyType.Int16),
@@ -47,14 +50,17 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
}
- public PropertyType Type {
+ public PropertyType Type
+ {
[Pure]
get { return _type; }
}
- public bool IsNumericScalar {
+ public bool IsNumericScalar
+ {
[Pure]
- get {
+ get
+ {
return IsNumericScalarImpl(_type, _data);
}
}
@@ -128,7 +134,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public char GetChar16()
{
if (this.Type != PropertyType.Char16)
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Char16"), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Char16"), __HResults.TYPE_E_TYPEMISMATCH);
Contract.EndContractBlock();
return (char)_data;
}
@@ -137,7 +143,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public Boolean GetBoolean()
{
if (this.Type != PropertyType.Boolean)
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Boolean"), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Boolean"), __HResults.TYPE_E_TYPEMISMATCH);
Contract.EndContractBlock();
return (bool)_data;
}
@@ -160,7 +166,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public DateTimeOffset GetDateTime()
{
if (this.Type != PropertyType.DateTime)
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "DateTime"), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "DateTime"), __HResults.TYPE_E_TYPEMISMATCH);
Contract.EndContractBlock();
return (DateTimeOffset)_data;
}
@@ -169,7 +175,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public TimeSpan GetTimeSpan()
{
if (this.Type != PropertyType.TimeSpan)
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "TimeSpan"), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "TimeSpan"), __HResults.TYPE_E_TYPEMISMATCH);
Contract.EndContractBlock();
return (TimeSpan)_data;
}
@@ -178,7 +184,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public Point GetPoint()
{
if (this.Type != PropertyType.Point)
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Point"), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Point"), __HResults.TYPE_E_TYPEMISMATCH);
Contract.EndContractBlock();
return Unbox<Point>(IReferenceFactory.s_pointType);
@@ -188,9 +194,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public Size GetSize()
{
if (this.Type != PropertyType.Size)
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Size"), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Size"), __HResults.TYPE_E_TYPEMISMATCH);
Contract.EndContractBlock();
-
+
return Unbox<Size>(IReferenceFactory.s_sizeType);
}
@@ -198,9 +204,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public Rect GetRect()
{
if (this.Type != PropertyType.Rect)
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Rect"), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Rect"), __HResults.TYPE_E_TYPEMISMATCH);
Contract.EndContractBlock();
-
+
return Unbox<Rect>(IReferenceFactory.s_rectType);
}
@@ -262,7 +268,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public char[] GetChar16Array()
{
if (this.Type != PropertyType.Char16Array)
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Char16[]"), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Char16[]"), __HResults.TYPE_E_TYPEMISMATCH);
Contract.EndContractBlock();
return (char[])_data;
}
@@ -271,7 +277,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public Boolean[] GetBooleanArray()
{
if (this.Type != PropertyType.BooleanArray)
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Boolean[]"), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Boolean[]"), __HResults.TYPE_E_TYPEMISMATCH);
Contract.EndContractBlock();
return (bool[])_data;
}
@@ -286,7 +292,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public Object[] GetInspectableArray()
{
if (this.Type != PropertyType.InspectableArray)
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Inspectable[]"), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Inspectable[]"), __HResults.TYPE_E_TYPEMISMATCH);
Contract.EndContractBlock();
return (Object[])_data;
}
@@ -301,7 +307,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public DateTimeOffset[] GetDateTimeArray()
{
if (this.Type != PropertyType.DateTimeArray)
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "DateTimeOffset[]"), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "DateTimeOffset[]"), __HResults.TYPE_E_TYPEMISMATCH);
Contract.EndContractBlock();
return (DateTimeOffset[])_data;
}
@@ -310,7 +316,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public TimeSpan[] GetTimeSpanArray()
{
if (this.Type != PropertyType.TimeSpanArray)
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "TimeSpan[]"), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "TimeSpan[]"), __HResults.TYPE_E_TYPEMISMATCH);
Contract.EndContractBlock();
return (TimeSpan[])_data;
}
@@ -319,9 +325,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public Point[] GetPointArray()
{
if (this.Type != PropertyType.PointArray)
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Point[]"), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Point[]"), __HResults.TYPE_E_TYPEMISMATCH);
Contract.EndContractBlock();
-
+
return UnboxArray<Point>(IReferenceFactory.s_pointType);
}
@@ -329,7 +335,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public Size[] GetSizeArray()
{
if (this.Type != PropertyType.SizeArray)
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Size[]"), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Size[]"), __HResults.TYPE_E_TYPEMISMATCH);
Contract.EndContractBlock();
@@ -340,22 +346,25 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public Rect[] GetRectArray()
{
if (this.Type != PropertyType.RectArray)
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, "Rect[]"), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, "Rect[]"), __HResults.TYPE_E_TYPEMISMATCH);
Contract.EndContractBlock();
return UnboxArray<Rect>(IReferenceFactory.s_rectType);
}
- private T[] CoerceArrayValue<T>(PropertyType unboxType) {
+ private T[] CoerceArrayValue<T>(PropertyType unboxType)
+ {
// If we contain the type being looked for directly, then take the fast-path
- if (Type == unboxType) {
+ if (Type == unboxType)
+ {
return (T[])_data;
}
// Make sure we have an array to begin with
Array dataArray = _data as Array;
- if (dataArray == null) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", this.Type, typeof(T).MakeArrayType().Name), __HResults.TYPE_E_TYPEMISMATCH);
+ if (dataArray == null)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, this.Type, typeof (T).MakeArrayType().Name), __HResults.TYPE_E_TYPEMISMATCH);
}
// Array types are 1024 larger than their equivilent scalar counterpart
@@ -365,11 +374,15 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// If we do not have the correct array type, then we need to convert the array element-by-element
// to a new array of the requested type
T[] coercedArray = new T[dataArray.Length];
- for (int i = 0; i < dataArray.Length; ++i) {
- try {
+ for (int i = 0; i < dataArray.Length; ++i)
+ {
+ try
+ {
coercedArray[i] = CoerceScalarValue<T>(scalarType, dataArray.GetValue(i));
- } catch (InvalidCastException elementCastException) {
- Exception e = new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueArrayCoersion", this.Type, typeof(T).MakeArrayType().Name, i, elementCastException.Message), elementCastException);
+ }
+ catch (InvalidCastException elementCastException)
+ {
+ Exception e = new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueArrayCoersion, this.Type, typeof (T).MakeArrayType().Name, i, elementCastException.Message), elementCastException);
e.SetErrorCode(elementCastException._HResult);
throw e;
}
@@ -381,92 +394,117 @@ namespace System.Runtime.InteropServices.WindowsRuntime
private T CoerceScalarValue<T>(PropertyType unboxType)
{
// If we are just a boxed version of the requested type, then take the fast path out
- if (Type == unboxType) {
+ if (Type == unboxType)
+ {
return (T)_data;
}
return CoerceScalarValue<T>(Type, _data);
}
- private static T CoerceScalarValue<T>(PropertyType type, object value) {
+ private static T CoerceScalarValue<T>(PropertyType type, object value)
+ {
// If the property type is neither one of the coercable numeric types nor IInspectable, we
// should not attempt coersion, even if the underlying value is technically convertable
- if (!IsCoercable(type, value) && type != PropertyType.Inspectable) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", type, typeof(T).Name), __HResults.TYPE_E_TYPEMISMATCH);
+ if (!IsCoercable(type, value) && type != PropertyType.Inspectable)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, type, typeof (T).Name), __HResults.TYPE_E_TYPEMISMATCH);
}
- try {
+ try
+ {
// Try to coerce:
// * String <--> Guid
// * Numeric scalars
- if (type == PropertyType.String && typeof(T) == typeof(Guid)) {
+ if (type == PropertyType.String && typeof(T) == typeof(Guid))
+ {
return (T)(object)Guid.Parse((string)value);
}
- else if (type == PropertyType.Guid && typeof(T) == typeof(String)) {
- return (T)(object)((Guid)value).ToString("D", System.Globalization.CultureInfo.InvariantCulture);
+ else if (type == PropertyType.Guid && typeof(T) == typeof(String))
+ {
+ return (T)(object)((Guid)value).ToString("D", System.Globalization.CultureInfo.InvariantCulture);
}
- else {
+ else
+ {
// Iterate over the numeric scalars, to see if we have a match for one of the known conversions
- foreach (Tuple<Type, PropertyType> numericScalar in NumericScalarTypes) {
- if (numericScalar.Item1 == typeof(T)) {
+ foreach (Tuple<Type, PropertyType> numericScalar in NumericScalarTypes)
+ {
+ if (numericScalar.Item1 == typeof(T))
+ {
return (T)Convert.ChangeType(value, typeof(T), System.Globalization.CultureInfo.InvariantCulture);
}
}
}
}
- catch (FormatException) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", type, typeof(T).Name), __HResults.TYPE_E_TYPEMISMATCH);
+ catch (FormatException)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, type, typeof (T).Name), __HResults.TYPE_E_TYPEMISMATCH);
}
- catch (InvalidCastException) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", type, typeof(T).Name), __HResults.TYPE_E_TYPEMISMATCH);
+ catch (InvalidCastException)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, type, typeof (T).Name), __HResults.TYPE_E_TYPEMISMATCH);
}
- catch (OverflowException) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueCoersion", type, value, typeof(T).Name), __HResults.DISP_E_OVERFLOW);
+ catch (OverflowException)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueCoersion, type, value, typeof (T).Name), __HResults.DISP_E_OVERFLOW);
}
// If the property type is IInspectable, and we have a nested IPropertyValue, then we need
// to pass along the request to coerce the value.
IPropertyValue ipv = value as IPropertyValue;
- if (type == PropertyType.Inspectable && ipv != null) {
- if (typeof(T) == typeof(Byte)) {
+ if (type == PropertyType.Inspectable && ipv != null)
+ {
+ if (typeof(T) == typeof(Byte))
+ {
return (T)(object)ipv.GetUInt8();
}
- else if (typeof(T) == typeof(Int16)) {
+ else if (typeof(T) == typeof(Int16))
+ {
return (T)(object)ipv.GetInt16();
}
- else if (typeof(T) == typeof(UInt16)) {
+ else if (typeof(T) == typeof(UInt16))
+ {
return (T)(object)ipv.GetUInt16();
}
- else if (typeof(T) == typeof(Int32)) {
+ else if (typeof(T) == typeof(Int32))
+ {
return (T)(object)ipv.GetUInt32();
}
- else if (typeof(T) == typeof(UInt32)) {
+ else if (typeof(T) == typeof(UInt32))
+ {
return (T)(object)ipv.GetUInt32();
}
- else if (typeof(T) == typeof(Int64)) {
+ else if (typeof(T) == typeof(Int64))
+ {
return (T)(object)ipv.GetInt64();
}
- else if (typeof(T) == typeof(UInt64)) {
+ else if (typeof(T) == typeof(UInt64))
+ {
return (T)(object)ipv.GetUInt64();
}
- else if (typeof(T) == typeof(Single)) {
+ else if (typeof(T) == typeof(Single))
+ {
return (T)(object)ipv.GetSingle();
}
- else if (typeof(T) == typeof(Double)) {
+ else if (typeof(T) == typeof(Double))
+ {
return (T)(object)ipv.GetDouble();
}
- else {
+ else
+ {
BCLDebug.Assert(false, "T in coersion function wasn't understood as a type that can be coerced - make sure that CoerceScalarValue and NumericScalarTypes are in sync");
}
}
// Otherwise, this is an invalid coersion
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", type, typeof(T).Name), __HResults.TYPE_E_TYPEMISMATCH);
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, type, typeof (T).Name), __HResults.TYPE_E_TYPEMISMATCH);
}
- private static bool IsCoercable(PropertyType type, object data) {
+ private static bool IsCoercable(PropertyType type, object data)
+ {
// String <--> Guid is allowed
- if (type == PropertyType.Guid || type == PropertyType.String) {
+ if (type == PropertyType.Guid || type == PropertyType.String)
+ {
return true;
}
@@ -474,13 +512,17 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return IsNumericScalarImpl(type, data);
}
- private static bool IsNumericScalarImpl(PropertyType type, object data) {
- if (data.GetType().IsEnum) {
+ private static bool IsNumericScalarImpl(PropertyType type, object data)
+ {
+ if (data.GetType().IsEnum)
+ {
return true;
}
- foreach (Tuple<Type, PropertyType> numericScalar in NumericScalarTypes) {
- if (numericScalar.Item2 == type) {
+ foreach (Tuple<Type, PropertyType> numericScalar in NumericScalarTypes)
+ {
+ if (numericScalar.Item2 == type)
+ {
return true;
}
}
@@ -490,42 +532,50 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Unbox the data stored in the property value to a structurally equivilent type
[Pure]
- private unsafe T Unbox<T>(Type expectedBoxedType) where T : struct {
+ private unsafe T Unbox<T>(Type expectedBoxedType) where T : struct
+ {
Contract.Requires(expectedBoxedType != null);
Contract.Requires(Marshal.SizeOf(expectedBoxedType) == Marshal.SizeOf(typeof(T)));
- if (_data.GetType() != expectedBoxedType) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", _data.GetType(), expectedBoxedType.Name), __HResults.TYPE_E_TYPEMISMATCH);
+ if (_data.GetType() != expectedBoxedType)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, _data.GetType(), expectedBoxedType.Name), __HResults.TYPE_E_TYPEMISMATCH);
}
T unboxed = new T();
- fixed (byte *pData = &JitHelpers.GetPinningHelper(_data).m_data) {
+ fixed (byte* pData = &JitHelpers.GetPinningHelper(_data).m_data)
+ {
byte* pUnboxed = (byte*)JitHelpers.UnsafeCastToStackPointer(ref unboxed);
Buffer.Memcpy(pUnboxed, pData, Marshal.SizeOf(unboxed));
}
-
+
return unboxed;
}
// Convert the array stored in the property value to a structurally equivilent array type
[Pure]
- private unsafe T[] UnboxArray<T>(Type expectedArrayElementType) where T : struct {
+ private unsafe T[] UnboxArray<T>(Type expectedArrayElementType) where T : struct
+ {
Contract.Requires(expectedArrayElementType != null);
Contract.Requires(Marshal.SizeOf(expectedArrayElementType) == Marshal.SizeOf(typeof(T)));
Array dataArray = _data as Array;
- if (dataArray == null || _data.GetType().GetElementType() != expectedArrayElementType) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_WinRTIPropertyValueElement", _data.GetType(), expectedArrayElementType.MakeArrayType().Name), __HResults.TYPE_E_TYPEMISMATCH);
+ if (dataArray == null || _data.GetType().GetElementType() != expectedArrayElementType)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_WinRTIPropertyValueElement, _data.GetType(), expectedArrayElementType.MakeArrayType().Name), __HResults.TYPE_E_TYPEMISMATCH);
}
T[] converted = new T[dataArray.Length];
- if (converted.Length > 0) {
- fixed (byte * dataPin = &JitHelpers.GetPinningHelper(dataArray).m_data) {
- fixed (byte * convertedPin = &JitHelpers.GetPinningHelper(converted).m_data) {
- byte *pData = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(dataArray, 0);
- byte *pConverted = (byte *)Marshal.UnsafeAddrOfPinnedArrayElement(converted, 0);
+ if (converted.Length > 0)
+ {
+ fixed (byte* dataPin = &JitHelpers.GetPinningHelper(dataArray).m_data)
+ {
+ fixed (byte* convertedPin = &JitHelpers.GetPinningHelper(converted).m_data)
+ {
+ byte* pData = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(dataArray, 0);
+ byte* pConverted = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(converted, 0);
Buffer.Memcpy(pConverted, pData, checked(Marshal.SizeOf(typeof(T)) * converted.Length));
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIReferenceImpl.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIReferenceImpl.cs
index 9705b61148..3afd87ab12 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIReferenceImpl.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CLRIReferenceImpl.cs
@@ -13,7 +13,7 @@ using System.Security;
namespace System.Runtime.InteropServices.WindowsRuntime
{
- internal sealed class CLRIReferenceImpl<T> : CLRIPropertyValueImpl, IReference<T>, IGetProxyTarget
+ internal sealed class CLRIReferenceImpl<T> : CLRIPropertyValueImpl, IReference<T>, IGetProxyTarget
{
private T _value;
@@ -24,7 +24,8 @@ namespace System.Runtime.InteropServices.WindowsRuntime
_value = obj;
}
- public T Value {
+ public T Value
+ {
get { return _value; }
}
@@ -55,16 +56,16 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal static Object UnboxHelper(Object wrapper)
{
Contract.Requires(wrapper != null);
- IReference<T> reference = (IReference<T>) wrapper;
- Debug.Assert(reference != null, "CLRIReferenceImpl::UnboxHelper - QI'ed for IReference<"+typeof(T)+">, but that failed.");
+ IReference<T> reference = (IReference<T>)wrapper;
+ Debug.Assert(reference != null, "CLRIReferenceImpl::UnboxHelper - QI'ed for IReference<" + typeof(T) + ">, but that failed.");
return reference.Value;
}
}
// T can be any WinRT-compatible type
internal sealed class CLRIReferenceArrayImpl<T> : CLRIPropertyValueImpl,
- IGetProxyTarget,
- IReferenceArray<T>,
+ IGetProxyTarget,
+ IReferenceArray<T>,
IList // Jupiter data binding needs IList/IEnumerable
{
private T[] _value;
@@ -77,10 +78,11 @@ namespace System.Runtime.InteropServices.WindowsRuntime
_value = obj;
- _list = (IList) _value;
+ _list = (IList)_value;
}
- public T[] Value {
+ public T[] Value
+ {
get { return _value; }
}
@@ -109,7 +111,8 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// IList & ICollection methods.
// This enables two-way data binding and index access in Jupiter
//
- Object IList.this[int index] {
+ Object IList.this[int index]
+ {
get
{
return _list[index];
@@ -120,30 +123,30 @@ namespace System.Runtime.InteropServices.WindowsRuntime
_list[index] = value;
}
}
-
+
int IList.Add(Object value)
{
return _list.Add(value);
}
-
+
bool IList.Contains(Object value)
{
return _list.Contains(value);
}
-
+
void IList.Clear()
{
_list.Clear();
}
- bool IList.IsReadOnly
- {
+ bool IList.IsReadOnly
+ {
get
{
return _list.IsReadOnly;
}
}
-
+
bool IList.IsFixedSize
{
get
@@ -156,17 +159,17 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
return _list.IndexOf(value);
}
-
+
void IList.Insert(int index, Object value)
{
_list.Insert(index, value);
}
-
+
void IList.Remove(Object value)
{
_list.Remove(value);
}
-
+
void IList.RemoveAt(int index)
{
_list.RemoveAt(index);
@@ -176,9 +179,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
_list.CopyTo(array, index);
}
-
+
int ICollection.Count
- {
+ {
get
{
return _list.Count;
@@ -186,15 +189,15 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
Object ICollection.SyncRoot
- {
+ {
get
{
return _list.SyncRoot;
}
}
-
+
bool ICollection.IsSynchronized
- {
+ {
get
{
return _list.IsSynchronized;
@@ -205,7 +208,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
return (object)_value;
}
-
+
// We have T in an IReferenceArray<T>. Need to QI for IReferenceArray<T> with the appropriate GUID, call
// the get_Value property, allocate an appropriately-sized managed object, marshal the native object
// to the managed object, and free the native method.
@@ -238,7 +241,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
Type type = obj.GetType();
if (type.IsArray)
- return CreateIReferenceArray((Array) obj);
+ return CreateIReferenceArray((Array)obj);
if (type == typeof(int))
return new CLRIReferenceImpl<int>(PropertyType.Int32, (int)obj);
@@ -313,7 +316,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
Contract.Ensures(Contract.Result<Object>() != null);
Type type = obj.GetType().GetElementType();
-
+
Debug.Assert(obj.Rank == 1 && obj.GetLowerBound(0) == 0 && !type.IsArray);
if (type == typeof(int))
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ConstantSplittableMap.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ConstantSplittableMap.cs
index 3a896ecbe3..4549a407e0 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ConstantSplittableMap.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ConstantSplittableMap.cs
@@ -48,9 +48,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
throw new ArgumentNullException(nameof(data));
Contract.EndContractBlock();
- this.firstItemIndex = 0;
- this.lastItemIndex = data.Count - 1;
- this.items = CreateKeyValueArray(data.Count, data.GetEnumerator());
+ firstItemIndex = 0;
+ lastItemIndex = data.Count - 1;
+ items = CreateKeyValueArray(data.Count, data.GetEnumerator());
}
@@ -61,7 +61,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
this.lastItemIndex = lastItemIndex;
}
-
+
private KeyValuePair<TKey, TValue>[] CreateKeyValueArray(Int32 count, IEnumerator<KeyValuePair<TKey, TValue>> data)
{
KeyValuePair<TKey, TValue>[] kvArray = new KeyValuePair<TKey, TValue>[count];
@@ -76,16 +76,20 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
- public int Count {
- get {
+ public int Count
+ {
+ get
+ {
return lastItemIndex - firstItemIndex + 1;
}
}
// [CLSCompliant(false)]
- public UInt32 Size {
- get {
+ public UInt32 Size
+ {
+ get
+ {
return (UInt32)(lastItemIndex - firstItemIndex + 1);
}
}
@@ -98,7 +102,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (!found)
{
- Exception e = new KeyNotFoundException(Environment.GetResourceString("Arg_KeyNotFound"));
+ Exception e = new KeyNotFoundException(SR.Arg_KeyNotFound);
e.SetErrorCode(__HResults.E_BOUNDS);
throw e;
}
@@ -118,17 +122,17 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
return ((IEnumerable<IKeyValuePair<TKey, TValue>>)this).GetEnumerator();
}
-
+
public IIterator<IKeyValuePair<TKey, TValue>> First()
{
return new EnumeratorToIteratorAdapter<IKeyValuePair<TKey, TValue>>(GetEnumerator());
}
-
+
public IEnumerator<IKeyValuePair<TKey, TValue>> GetEnumerator()
{
return new IKeyValuePairEnumerator(items, firstItemIndex, lastItemIndex);
}
-
+
public void Split(out IMapView<TKey, TValue> firstPartition, out IMapView<TKey, TValue> secondPartition)
{
if (Count < 2)
@@ -144,7 +148,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
secondPartition = new ConstantSplittableMap<TKey, TValue>(items, pivot + 1, lastItemIndex);
}
-#region IReadOnlyDictionary members
+ #region IReadOnlyDictionary members
public bool TryGetValue(TKey key, out TValue value)
{
@@ -197,16 +201,20 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return false;
}
- public IKeyValuePair<TKey, TValue> Current {
- get {
- if (_current < _start) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
- if (_current > _end) throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_EnumEnded));
+ public IKeyValuePair<TKey, TValue> Current
+ {
+ get
+ {
+ if (_current < _start) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumNotStarted));
+ if (_current > _end) throw new InvalidOperationException(SR.GetResourceString(ResId.InvalidOperation_EnumEnded));
return new CLRIKeyValuePairImpl<TKey, TValue>(ref _array[_current]);
}
}
- Object IEnumerator.Current {
- get {
+ Object IEnumerator.Current
+ {
+ get
+ {
return Current;
}
}
@@ -222,7 +230,5 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
#endregion IKeyValuePair Enumerator
-
} // internal ConstantSplittableMap<TKey, TValue>
-
} // namespace System.Runtime.InteropServices.WindowsRuntime
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs
index 9f822d5ced..63565a39b8 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs
@@ -21,8 +21,8 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// ICustomProperty implementation - basically a wrapper of PropertyInfo
//
internal sealed class CustomPropertyImpl : ICustomProperty
- {
- private PropertyInfo m_property;
+ {
+ private PropertyInfo m_property;
//
// Constructor
@@ -46,11 +46,11 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return m_property.Name;
}
}
-
+
public bool CanRead
{
- get
- {
+ get
+ {
// Return false if the getter is not public
return m_property.GetGetMethod() != null;
}
@@ -58,7 +58,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public bool CanWrite
{
- get
+ get
{
// Return false if the setter is not public
return m_property.GetSetMethod() != null;
@@ -105,21 +105,21 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// We get non-public accessors just so that we can throw the correct exception.
MethodInfo accessor = getValue ? m_property.GetGetMethod(true) : m_property.GetSetMethod(true);
-
+
if (accessor == null)
- throw new ArgumentException(System.Environment.GetResourceString(getValue ? "Arg_GetMethNotFnd" : "Arg_SetMethNotFnd"));
+ throw new ArgumentException(getValue ? SR.Arg_GetMethNotFnd : SR.Arg_SetMethNotFnd);
if (!accessor.IsPublic)
throw new MethodAccessException(
String.Format(
CultureInfo.CurrentCulture,
- Environment.GetResourceString("Arg_MethodAccessException_WithMethodName"),
+ SR.Arg_MethodAccessException_WithMethodName,
accessor.ToString(),
accessor.DeclaringType.FullName));
RuntimeMethodInfo rtMethod = accessor as RuntimeMethodInfo;
if (rtMethod == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeMethodInfo);
// We can safely skip access check because this is only used in full trust scenarios.
// And we have already verified that the property accessor is public.
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryKeyCollection.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryKeyCollection.cs
index c33e002e0e..2a34aba717 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryKeyCollection.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryKeyCollection.cs
@@ -30,9 +30,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (index < 0)
throw new ArgumentOutOfRangeException(nameof(index));
if (array.Length <= index && this.Count > 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_IndexOutOfRangeException"));
+ throw new ArgumentException(SR.Arg_IndexOutOfRangeException);
if (array.Length - index < dictionary.Count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InsufficientSpaceToCopyCollection"));
+ throw new ArgumentException(SR.Argument_InsufficientSpaceToCopyCollection);
int i = index;
foreach (KeyValuePair<TKey, TValue> mapping in dictionary)
@@ -41,22 +41,24 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
}
- public int Count {
+ public int Count
+ {
get { return dictionary.Count; }
}
- bool ICollection<TKey>.IsReadOnly {
+ bool ICollection<TKey>.IsReadOnly
+ {
get { return true; }
}
void ICollection<TKey>.Add(TKey item)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_KeyCollectionSet"));
+ throw new NotSupportedException(SR.NotSupported_KeyCollectionSet);
}
void ICollection<TKey>.Clear()
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_KeyCollectionSet"));
+ throw new NotSupportedException(SR.NotSupported_KeyCollectionSet);
}
public bool Contains(TKey item)
@@ -66,7 +68,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
bool ICollection<TKey>.Remove(TKey item)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_KeyCollectionSet"));
+ throw new NotSupportedException(SR.NotSupported_KeyCollectionSet);
}
IEnumerator IEnumerable.GetEnumerator()
@@ -93,7 +95,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
throw new ArgumentNullException(nameof(dictionary));
this.dictionary = dictionary;
- this.enumeration = dictionary.GetEnumerator();
+ enumeration = dictionary.GetEnumerator();
}
void IDisposable.Dispose()
@@ -106,11 +108,13 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return enumeration.MoveNext();
}
- Object IEnumerator.Current {
+ Object IEnumerator.Current
+ {
get { return ((IEnumerator<TKey>)this).Current; }
}
- public TKey Current {
+ public TKey Current
+ {
get { return enumeration.Current.Key; }
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryToMapAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryToMapAdapter.cs
index 24e5777768..bb54d49b60 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryToMapAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryToMapAdapter.cs
@@ -41,7 +41,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (!keyFound)
{
- Exception e = new KeyNotFoundException(Environment.GetResourceString("Arg_KeyNotFound"));
+ Exception e = new KeyNotFoundException(SR.Arg_KeyNotFound);
e.SetErrorCode(__HResults.E_BOUNDS);
throw e;
}
@@ -55,7 +55,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
IDictionary<K, V> _this = JitHelpers.UnsafeCast<IDictionary<K, V>>(this);
return (uint)_this.Count;
}
-
+
// bool HasKey(K key)
internal bool HasKey<K, V>(K key)
{
@@ -96,7 +96,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (!removed)
{
- Exception e = new KeyNotFoundException(Environment.GetResourceString("Arg_KeyNotFound"));
+ Exception e = new KeyNotFoundException(SR.Arg_KeyNotFound);
e.SetErrorCode(__HResults.E_BOUNDS);
throw e;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryValueCollection.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryValueCollection.cs
index fcc7755d67..083b0ffcb1 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryValueCollection.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/DictionaryValueCollection.cs
@@ -11,7 +11,8 @@ using System.Runtime.InteropServices;
using System.Runtime.InteropServices.WindowsRuntime;
-namespace System.Runtime.InteropServices.WindowsRuntime {
+namespace System.Runtime.InteropServices.WindowsRuntime
+{
[Serializable]
[DebuggerDisplay("Count = {Count}")]
internal sealed class DictionaryValueCollection<TKey, TValue> : ICollection<TValue>
@@ -33,9 +34,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
if (index < 0)
throw new ArgumentOutOfRangeException(nameof(index));
if (array.Length <= index && this.Count > 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_IndexOutOfRangeException"));
+ throw new ArgumentException(SR.Arg_IndexOutOfRangeException);
if (array.Length - index < dictionary.Count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InsufficientSpaceToCopyCollection"));
+ throw new ArgumentException(SR.Argument_InsufficientSpaceToCopyCollection);
int i = index;
foreach (KeyValuePair<TKey, TValue> mapping in dictionary)
@@ -44,22 +45,24 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
}
}
- public int Count {
+ public int Count
+ {
get { return dictionary.Count; }
}
- bool ICollection<TValue>.IsReadOnly {
+ bool ICollection<TValue>.IsReadOnly
+ {
get { return true; }
}
void ICollection<TValue>.Add(TValue item)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ValueCollectionSet"));
+ throw new NotSupportedException(SR.NotSupported_ValueCollectionSet);
}
void ICollection<TValue>.Clear()
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ValueCollectionSet"));
+ throw new NotSupportedException(SR.NotSupported_ValueCollectionSet);
}
public bool Contains(TValue item)
@@ -73,7 +76,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
bool ICollection<TValue>.Remove(TValue item)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ValueCollectionSet"));
+ throw new NotSupportedException(SR.NotSupported_ValueCollectionSet);
}
IEnumerator IEnumerable.GetEnumerator()
@@ -100,7 +103,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
throw new ArgumentNullException(nameof(dictionary));
this.dictionary = dictionary;
- this.enumeration = dictionary.GetEnumerator();
+ enumeration = dictionary.GetEnumerator();
}
void IDisposable.Dispose()
@@ -113,11 +116,13 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
return enumeration.MoveNext();
}
- Object IEnumerator.Current {
+ Object IEnumerator.Current
+ {
get { return ((IEnumerator<TValue>)this).Current; }
}
- public TValue Current {
+ public TValue Current
+ {
get { return enumeration.Current.Value; }
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EnumeratorToIteratorAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EnumeratorToIteratorAdapter.cs
index 3f9d516162..75b8480eeb 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EnumeratorToIteratorAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EnumeratorToIteratorAdapter.cs
@@ -51,20 +51,20 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public NonGenericToGenericEnumerator(IEnumerator enumerator)
{ this.enumerator = enumerator; }
- public object Current { get { return enumerator.Current; } }
+ public object Current { get { return enumerator.Current; } }
public bool MoveNext() { return enumerator.MoveNext(); }
- public void Reset() { enumerator.Reset(); }
- public void Dispose() { }
+ public void Reset() { enumerator.Reset(); }
+ public void Dispose() { }
}
// This method is invoked when First is called on a managed implementation of IBindableIterable.
internal IBindableIterator First_Stub()
{
IEnumerable _this = JitHelpers.UnsafeCast<IEnumerable>(this);
- return new EnumeratorToIteratorAdapter<object>(new NonGenericToGenericEnumerator(_this.GetEnumerator()) );
+ return new EnumeratorToIteratorAdapter<object>(new NonGenericToGenericEnumerator(_this.GetEnumerator()));
}
}
-
+
// Adapter class which holds a managed IEnumerator<T>, exposing it as a Windows Runtime IIterator<T>
internal sealed class EnumeratorToIteratorAdapter<T> : IIterator<T>, IBindableIterator
{
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EventRegistrationTokenTable.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EventRegistrationTokenTable.cs
index 03b17d9261..974da48a42 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EventRegistrationTokenTable.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/EventRegistrationTokenTable.cs
@@ -28,7 +28,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// static check at construction time
if (!typeof(Delegate).IsAssignableFrom(typeof(T)))
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EventTokenTableRequiresDelegate", typeof(T)));
+ throw new InvalidOperationException(SR.Format(SR.InvalidOperation_EventTokenTableRequiresDelegate, typeof (T)));
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IClosable.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IClosable.cs
index 4c6169a4e8..d62649e7a7 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IClosable.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IClosable.cs
@@ -13,7 +13,6 @@ using System.Runtime.CompilerServices;
namespace System.Runtime.InteropServices.WindowsRuntime
{
-
// Local definition of Windows.Foundation.IClosable
[ComImport]
[Guid("30d5a829-7fa4-4026-83bb-d75bae4ea99e")]
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomProperty.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomProperty.cs
index 88472a46b8..3ff4ffd098 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomProperty.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomProperty.cs
@@ -19,34 +19,34 @@ namespace System.Runtime.InteropServices.WindowsRuntime
[Pure]
get;
}
-
- string Name
- {
+
+ string Name
+ {
[Pure]
- get;
+ get;
}
[Pure]
object GetValue(object target);
void SetValue(object target, object value);
-
+
[Pure]
object GetValue(object target, object indexValue);
-
+
void SetValue(object target, object value, object indexValue);
-
- bool CanWrite
- {
+
+ bool CanWrite
+ {
[Pure]
- get;
+ get;
}
- bool CanRead
- {
+ bool CanRead
+ {
[Pure]
- get;
- }
+ get;
+ }
}
}
-
+
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomPropertyProvider.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomPropertyProvider.cs
index 3bbde35a3c..f461327712 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomPropertyProvider.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ICustomPropertyProvider.cs
@@ -16,7 +16,6 @@ using System.Security;
namespace System.Runtime.InteropServices.WindowsRuntime
{
-
//
// ICustomProperty Implementation helpers
//
@@ -32,7 +31,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
Contract.Requires(propertyName != null);
IGetProxyTarget proxy = target as IGetProxyTarget;
- if (proxy != null)
+ if (proxy != null)
target = proxy.GetTarget();
// Only return public instance/static properties
@@ -50,7 +49,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Creates a ICustomProperty implementation for Jupiter
// Called from ICustomPropertyProvider_GetIndexedProperty from within runtime
//
- static internal unsafe ICustomProperty CreateIndexedProperty(object target, string propertyName, TypeNameNative *pIndexedParamType)
+ static internal unsafe ICustomProperty CreateIndexedProperty(object target, string propertyName, TypeNameNative* pIndexedParamType)
{
Contract.Requires(target != null);
Contract.Requires(propertyName != null);
@@ -58,7 +57,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
Type indexedParamType = null;
SystemTypeMarshaler.ConvertToManaged(pIndexedParamType, ref indexedParamType);
- return CreateIndexedProperty(target, propertyName, indexedParamType);
+ return CreateIndexedProperty(target, propertyName, indexedParamType);
}
static internal ICustomProperty CreateIndexedProperty(object target, string propertyName, Type indexedParamType)
@@ -67,7 +66,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
Contract.Requires(propertyName != null);
IGetProxyTarget proxy = target as IGetProxyTarget;
- if (proxy != null)
+ if (proxy != null)
target = proxy.GetTarget();
// Only return public instance/static properties
@@ -86,25 +85,25 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return new CustomPropertyImpl(propertyInfo);
}
- static internal unsafe void GetType(object target, TypeNameNative *pIndexedParamType)
- {
+ static internal unsafe void GetType(object target, TypeNameNative* pIndexedParamType)
+ {
IGetProxyTarget proxy = target as IGetProxyTarget;
- if (proxy != null)
+ if (proxy != null)
target = proxy.GetTarget();
SystemTypeMarshaler.ConvertToNative(target.GetType(), pIndexedParamType);
- }
+ }
}
[Flags]
- enum InterfaceForwardingSupport
+ internal enum InterfaceForwardingSupport
{
- None = 0,
- IBindableVector = 0x1, // IBindableVector -> IBindableVector
- IVector = 0x2, // IBindableVector -> IVector<T>
- IBindableVectorView = 0x4, // IBindableVectorView -> IBindableVectorView
- IVectorView = 0x8, // IBindableVectorView -> IVectorView<T>
- IBindableIterableOrIIterable= 0x10 // IBindableIterable -> IBindableIterable/IIterable<T>
+ None = 0,
+ IBindableVector = 0x1, // IBindableVector -> IBindableVector
+ IVector = 0x2, // IBindableVector -> IVector<T>
+ IBindableVectorView = 0x4, // IBindableVectorView -> IBindableVectorView
+ IVectorView = 0x8, // IBindableVectorView -> IVectorView<T>
+ IBindableIterableOrIIterable = 0x10 // IBindableIterable -> IBindableIterable/IIterable<T>
}
//
@@ -113,9 +112,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
//
internal interface IGetProxyTarget
{
- object GetTarget();
+ object GetTarget();
}
-
+
//
// Proxy that supports data binding on another object
//
@@ -164,7 +163,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// doesn't recognize, and therefore IEnumerable cast won't be able to take advantage of this QI
if (target as IList<T1> != null)
supportFlags |= InterfaceForwardingSupport.IVector;
-
+
if (target as IBindableVectorView != null)
supportFlags |= InterfaceForwardingSupport.IBindableVectorView;
@@ -181,8 +180,8 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// succeeded, IEnumerable needs to know that
if (target as IEnumerable != null)
supportFlags |= InterfaceForwardingSupport.IBindableIterableOrIIterable;
-
- return new ICustomPropertyProviderProxy<T1, T2>(target, supportFlags);
+
+ return new ICustomPropertyProviderProxy<T1, T2>(target, supportFlags);
}
@@ -213,26 +212,26 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
// Reject the QI if target doesn't implement IEnumerable
if ((_flags & (InterfaceForwardingSupport.IBindableIterableOrIIterable)) == 0)
- return CustomQueryInterfaceResult.Failed;
+ return CustomQueryInterfaceResult.Failed;
}
if (iid == typeof(IBindableVector).GUID)
{
// Reject the QI if target doesn't implement IBindableVector/IVector
if ((_flags & (InterfaceForwardingSupport.IBindableVector | InterfaceForwardingSupport.IVector)) == 0)
- return CustomQueryInterfaceResult.Failed;
+ return CustomQueryInterfaceResult.Failed;
}
if (iid == typeof(IBindableVectorView).GUID)
{
// Reject the QI if target doesn't implement IBindableVectorView/IVectorView
if ((_flags & (InterfaceForwardingSupport.IBindableVectorView | InterfaceForwardingSupport.IVectorView)) == 0)
- return CustomQueryInterfaceResult.Failed;
+ return CustomQueryInterfaceResult.Failed;
}
-
+
return CustomQueryInterfaceResult.NotHandled;
}
-
+
//
// IEnumerable methods
//
@@ -257,14 +256,14 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
// IBindableVector -> IVector<T>
return GetVectorOfT().GetAt(index);
- }
+ }
}
-
+
[Pure]
- uint IBindableVector.Size
- {
+ uint IBindableVector.Size
+ {
get
- {
+ {
IBindableVector bindableVector = GetIBindableVectorNoThrow();
if (bindableVector != null)
{
@@ -275,10 +274,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
// IBindableVector -> IVector<T>
return GetVectorOfT().Size;
- }
+ }
}
}
-
+
[Pure]
IBindableVectorView IBindableVector.GetView()
{
@@ -292,7 +291,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
// IBindableVector -> IVector<T>
return new IVectorViewToIBindableVectorViewAdapter<T1>(GetVectorOfT().GetView());
- }
+ }
}
private sealed class IVectorViewToIBindableVectorViewAdapter<T> : IBindableVectorView
@@ -300,8 +299,8 @@ namespace System.Runtime.InteropServices.WindowsRuntime
private IVectorView<T> _vectorView;
public IVectorViewToIBindableVectorViewAdapter(IVectorView<T> vectorView)
- {
- this._vectorView = vectorView;
+ {
+ _vectorView = vectorView;
}
[Pure]
@@ -309,16 +308,16 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
return _vectorView.GetAt(index);
}
-
+
[Pure]
uint IBindableVectorView.Size
- {
+ {
get
{
return _vectorView.Size;
}
}
-
+
[Pure]
bool IBindableVectorView.IndexOf(object value, out uint index)
{
@@ -329,9 +328,8 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
return new IteratorOfTToIteratorAdapter<T>(_vectorView.First());
}
+ }
- }
-
[Pure]
bool IBindableVector.IndexOf(object value, out uint index)
{
@@ -345,9 +343,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
// IBindableVector -> IVector<T>
return GetVectorOfT().IndexOf(ConvertTo<T1>(value), out index);
- }
+ }
}
-
+
void IBindableVector.SetAt(uint index, object value)
{
IBindableVector bindableVector = GetIBindableVectorNoThrow();
@@ -360,9 +358,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
// IBindableVector -> IVector<T>
GetVectorOfT().SetAt(index, ConvertTo<T1>(value));
- }
+ }
}
-
+
void IBindableVector.InsertAt(uint index, object value)
{
IBindableVector bindableVector = GetIBindableVectorNoThrow();
@@ -375,9 +373,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
// IBindableVector -> IVector<T>
GetVectorOfT().InsertAt(index, ConvertTo<T1>(value));
- }
+ }
}
-
+
void IBindableVector.RemoveAt(uint index)
{
IBindableVector bindableVector = GetIBindableVectorNoThrow();
@@ -390,9 +388,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
// IBindableVector -> IVector<T>
GetVectorOfT().RemoveAt(index);
- }
+ }
}
-
+
void IBindableVector.Append(object value)
{
IBindableVector bindableVector = GetIBindableVectorNoThrow();
@@ -405,9 +403,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
// IBindableVector -> IVector<T>
GetVectorOfT().Append(ConvertTo<T1>(value));
- }
- }
-
+ }
+ }
+
void IBindableVector.RemoveAtEnd()
{
IBindableVector bindableVector = GetIBindableVectorNoThrow();
@@ -420,9 +418,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
// IBindableVector -> IVector<T>
GetVectorOfT().RemoveAtEnd();
- }
+ }
}
-
+
void IBindableVector.Clear()
{
IBindableVector bindableVector = GetIBindableVectorNoThrow();
@@ -435,7 +433,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
// IBindableVector -> IVector<T>
GetVectorOfT().Clear();
- }
+ }
}
private IBindableVector GetIBindableVectorNoThrow()
@@ -454,7 +452,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
throw new InvalidOperationException(); // We should not go down this path, unless Jupiter pass this out to managed code
// and managed code use reflection to do the cast
}
-
+
//
// IBindableVectorView implementation (forwarding to IBindableVectorView or IVectorView<T>)
//
@@ -467,10 +465,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
else
return GetVectorViewOfT().GetAt(index);
}
-
+
[Pure]
uint IBindableVectorView.Size
- {
+ {
get
{
IBindableVectorView bindableVectorView = GetIBindableVectorViewNoThrow();
@@ -480,7 +478,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return GetVectorViewOfT().Size;
}
}
-
+
[Pure]
bool IBindableVectorView.IndexOf(object value, out uint index)
{
@@ -505,12 +503,12 @@ namespace System.Runtime.InteropServices.WindowsRuntime
private IIterator<T> _iterator;
public IteratorOfTToIteratorAdapter(IIterator<T> iterator)
- { this._iterator = iterator; }
+ { _iterator = iterator; }
public bool HasCurrent { get { return _iterator.HasCurrent; } }
- public object Current { get { return (object)_iterator.Current; } }
+ public object Current { get { return (object)_iterator.Current; } }
public bool MoveNext() { return _iterator.MoveNext(); }
- }
+ }
private IBindableVectorView GetIBindableVectorViewNoThrow()
{
@@ -537,9 +535,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Throw ArgumentNullException if value is null (otherwise we'll throw NullReferenceException
// when casting value to T)
ThrowHelper.IfNullAndNullsAreIllegalThenThrow<T>(value, ExceptionArgument.value);
-
+
// No coersion support needed. If we need coersion later, this is the place
- return (T) value;
+ return (T)value;
}
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IIterable.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IIterable.cs
index dbf4771cf6..30ce895423 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IIterable.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IIterable.cs
@@ -10,6 +10,7 @@ using System.Diagnostics.Contracts;
// Windows.Foundation.Collections.IIterable`1 cannot be referenced from managed code because it's hidden
// by the metadata adapter. We redeclare the interface manually to be able to talk to native WinRT objects.
+
namespace System.Runtime.InteropServices.WindowsRuntime
{
[ComImport]
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMap.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMap.cs
index 8160e6afc9..1f954a66b0 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMap.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMap.cs
@@ -11,6 +11,7 @@ using System.Diagnostics.Contracts;
// Windows.Foundation.Collections.IMap`2, IMapView`2, and IKeyValuePair`2 cannot be referenced from
// managed code because they're hidden by the metadata adapter. We redeclare the interfaces manually
// to be able to talk to native WinRT objects.
+
namespace System.Runtime.InteropServices.WindowsRuntime
{
[ComImport]
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMapViewToIReadOnlyDictionaryAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMapViewToIReadOnlyDictionaryAdapter.cs
index a7424da3fb..e06364dcae 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMapViewToIReadOnlyDictionaryAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IMapViewToIReadOnlyDictionaryAdapter.cs
@@ -114,7 +114,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
catch (Exception ex)
{
if (__HResults.E_BOUNDS == ex._HResult)
- throw new KeyNotFoundException(Environment.GetResourceString("Arg_KeyNotFound"));
+ throw new KeyNotFoundException(SR.Arg_KeyNotFound);
throw;
}
}
@@ -145,9 +145,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (index < 0)
throw new ArgumentOutOfRangeException(nameof(index));
if (array.Length <= index && this.Count > 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_IndexOutOfRangeException"));
+ throw new ArgumentException(SR.Arg_IndexOutOfRangeException);
if (array.Length - index < dictionary.Count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InsufficientSpaceToCopyCollection"));
+ throw new ArgumentException(SR.Argument_InsufficientSpaceToCopyCollection);
int i = index;
foreach (KeyValuePair<TKey, TValue> mapping in dictionary)
@@ -190,7 +190,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
throw new ArgumentNullException(nameof(dictionary));
this.dictionary = dictionary;
- this.enumeration = dictionary.GetEnumerator();
+ enumeration = dictionary.GetEnumerator();
}
void IDisposable.Dispose()
@@ -203,11 +203,13 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return enumeration.MoveNext();
}
- Object IEnumerator.Current {
+ Object IEnumerator.Current
+ {
get { return ((IEnumerator<TKey>)this).Current; }
}
- public TKey Current {
+ public TKey Current
+ {
get { return enumeration.Current.Key; }
}
@@ -240,9 +242,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (index < 0)
throw new ArgumentOutOfRangeException(nameof(index));
if (array.Length <= index && this.Count > 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_IndexOutOfRangeException"));
+ throw new ArgumentException(SR.Arg_IndexOutOfRangeException);
if (array.Length - index < dictionary.Count)
- throw new ArgumentException(Environment.GetResourceString("Argument_InsufficientSpaceToCopyCollection"));
+ throw new ArgumentException(SR.Argument_InsufficientSpaceToCopyCollection);
int i = index;
foreach (KeyValuePair<TKey, TValue> mapping in dictionary)
@@ -289,7 +291,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
throw new ArgumentNullException(nameof(dictionary));
this.dictionary = dictionary;
- this.enumeration = dictionary.GetEnumerator();
+ enumeration = dictionary.GetEnumerator();
}
void IDisposable.Dispose()
@@ -302,11 +304,13 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return enumeration.MoveNext();
}
- Object IEnumerator.Current {
+ Object IEnumerator.Current
+ {
get { return ((IEnumerator<TValue>)this).Current; }
}
- public TValue Current {
+ public TValue Current
+ {
get { return enumeration.Current.Value; }
}
@@ -315,5 +319,4 @@ namespace System.Runtime.InteropServices.WindowsRuntime
enumeration = dictionary.GetEnumerator();
}
} // class ReadOnlyDictionaryValueEnumerator<TKey, TValue>
-
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IPropertyValue.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IPropertyValue.cs
index 4065406dfa..a2b07b2ea7 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IPropertyValue.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IPropertyValue.cs
@@ -139,27 +139,25 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
// Specify size directly instead of fields to avoid warnings
- [StructLayoutAttribute(LayoutKind.Sequential, Size=8)]
+ [StructLayoutAttribute(LayoutKind.Sequential, Size = 8)]
[WindowsRuntimeImport]
internal struct Point
{
-
// float X;
// float Y;
}
// Specify size directly instead of fields to avoid warnings
- [StructLayoutAttribute(LayoutKind.Sequential, Size=8)]
+ [StructLayoutAttribute(LayoutKind.Sequential, Size = 8)]
[WindowsRuntimeImport]
internal struct Size
{
-
// float Width;
// float Height;
}
// Specify size directly instead of fields to avoid warnings
- [StructLayoutAttribute(LayoutKind.Sequential, Size=16)]
+ [StructLayoutAttribute(LayoutKind.Sequential, Size = 16)]
[WindowsRuntimeImport]
internal struct Rect
{
@@ -167,5 +165,5 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// float Y;
// float Width;
// float Height;
- }
+ }
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyDictionaryToIMapViewAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyDictionaryToIMapViewAdapter.cs
index b185b41be0..73daf876cd 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyDictionaryToIMapViewAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyDictionaryToIMapViewAdapter.cs
@@ -40,7 +40,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (!keyFound)
{
- Exception e = new KeyNotFoundException(Environment.GetResourceString("Arg_KeyNotFound"));
+ Exception e = new KeyNotFoundException(SR.Arg_KeyNotFound);
e.SetErrorCode(__HResults.E_BOUNDS);
throw e;
}
@@ -54,7 +54,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
IReadOnlyDictionary<K, V> _this = JitHelpers.UnsafeCast<IReadOnlyDictionary<K, V>>(this);
return (uint)_this.Count;
}
-
+
// bool HasKey(K key)
internal bool HasKey<K, V>(K key)
{
@@ -67,7 +67,8 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
IReadOnlyDictionary<K, V> _this = JitHelpers.UnsafeCast<IReadOnlyDictionary<K, V>>(this);
- if (_this.Count < 2) {
+ if (_this.Count < 2)
+ {
first = null;
second = null;
return;
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyListToIVectorViewAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyListToIVectorViewAdapter.cs
index 431d16256e..5dce7dfc8d 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyListToIVectorViewAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IReadOnlyListToIVectorViewAdapter.cs
@@ -35,11 +35,11 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal T GetAt<T>(uint index)
{
IReadOnlyList<T> _this = JitHelpers.UnsafeCast<IReadOnlyList<T>>(this);
- EnsureIndexInt32(index, _this.Count);
+ EnsureIndexInt32(index, _this.Count);
try
{
- return _this[(int) index];
+ return _this[(int)index];
}
catch (ArgumentOutOfRangeException ex)
{
@@ -126,7 +126,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// that Size > Int32.MaxValue:
if (((uint)Int32.MaxValue) <= index || index >= (uint)listCapacity)
{
- Exception e = new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_IndexLargerThanMaxValue"));
+ Exception e = new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexLargerThanMaxValue);
e.SetErrorCode(__HResults.E_BOUNDS);
throw e;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVector.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVector.cs
index 6982911a13..e88f4f3b9f 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVector.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVector.cs
@@ -11,6 +11,7 @@ using System.Diagnostics.Contracts;
// Windows.Foundation.Collections.IVector`1 and IVectorView`1 cannot be referenced from managed
// code because they're hidden by the metadata adapter. We redeclare the interfaces manually
// to be able to talk to native WinRT objects.
+
namespace System.Runtime.InteropServices.WindowsRuntime
{
[ComImport]
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVectorViewToIReadOnlyListAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVectorViewToIReadOnlyListAdapter.cs
index 37f21307dc..76b0fff00d 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVectorViewToIReadOnlyListAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IVectorViewToIReadOnlyListAdapter.cs
@@ -43,7 +43,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
try
{
- return _this.GetAt((uint) index);
+ return _this.GetAt((uint)index);
// We delegate bounds checking to the underlying collection and if it detected a fault,
// we translate it to the right exception:
@@ -62,15 +62,15 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
bool fUseString;
Delegate target = System.StubHelpers.StubHelpers.GetTargetForAmbiguousVariantCall(
- this,
- typeof(IReadOnlyList<T>).TypeHandle.Value,
+ this,
+ typeof(IReadOnlyList<T>).TypeHandle.Value,
out fUseString);
if (target != null)
{
return (JitHelpers.UnsafeCast<Indexer_Get_Delegate<T>>(target))(index);
}
-
+
if (fUseString)
{
return JitHelpers.UnsafeCast<T>(Indexer_Get<string>(index));
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IteratorToEnumeratorAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IteratorToEnumeratorAdapter.cs
index e219a86769..417476dbbe 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IteratorToEnumeratorAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/IteratorToEnumeratorAdapter.cs
@@ -31,7 +31,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
Debug.Assert(false, "This class is never instantiated");
}
-
+
// This method is invoked when GetEnumerator is called on a WinRT-backed implementation of IEnumerable<T>.
internal IEnumerator<T> GetEnumerator_Stub<T>()
{
@@ -55,7 +55,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
return (JitHelpers.UnsafeCast<GetEnumerator_Delegate<T>>(target))();
}
-
+
if (fUseString)
{
return JitHelpers.UnsafeCast<IEnumerator<T>>(GetEnumerator_Stub<string>());
@@ -79,7 +79,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public NonGenericToGenericIterator(IBindableIterator iterator)
{ this.iterator = iterator; }
- public object Current { get { return iterator.Current; } }
+ public object Current { get { return iterator.Current; } }
public bool HasCurrent { get { return iterator.HasCurrent; } }
public bool MoveNext() { return iterator.MoveNext(); }
public int GetMany(object[] items) { throw new NotSupportedException(); }
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorAdapter.cs
index b9fe11557d..5f12322ea8 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorAdapter.cs
@@ -36,7 +36,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal object GetAt(uint index)
{
IList _this = JitHelpers.UnsafeCast<IList>(this);
- EnsureIndexInt32(index, _this.Count);
+ EnsureIndexInt32(index, _this.Count);
try
{
@@ -119,7 +119,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal void RemoveAt(uint index)
{
IList _this = JitHelpers.UnsafeCast<IList>(this);
- EnsureIndexInt32(index, _this.Count);
+ EnsureIndexInt32(index, _this.Count);
try
{
@@ -146,7 +146,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
IList _this = JitHelpers.UnsafeCast<IList>(this);
if (_this.Count == 0)
{
- Exception e = new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotRemoveLastFromEmptyCollection"));
+ Exception e = new InvalidOperationException(SR.InvalidOperation_CannotRemoveLastFromEmptyCollection);
e.SetErrorCode(__HResults.E_BOUNDS);
throw e;
}
@@ -170,7 +170,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// that Size > Int32.MaxValue:
if (((uint)Int32.MaxValue) <= index || index >= (uint)listCapacity)
{
- Exception e = new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_IndexLargerThanMaxValue"));
+ Exception e = new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexLargerThanMaxValue);
e.SetErrorCode(__HResults.E_BOUNDS);
throw e;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorViewAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorViewAdapter.cs
index 2e2ea9b876..fc02bedfa6 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorViewAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToBindableVectorViewAdapter.cs
@@ -38,7 +38,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// that Size > Int32.MaxValue:
if (((uint)Int32.MaxValue) <= index || index >= (uint)listCapacity)
{
- Exception e = new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_IndexLargerThanMaxValue"));
+ Exception e = new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexLargerThanMaxValue);
e.SetErrorCode(__HResults.E_BOUNDS);
throw e;
}
@@ -61,7 +61,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
try
{
return list[(int)index];
-
}
catch (ArgumentOutOfRangeException ex)
{
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToVectorAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToVectorAdapter.cs
index b73f4d7a99..87330e2559 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToVectorAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ListToVectorAdapter.cs
@@ -36,7 +36,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal T GetAt<T>(uint index)
{
IList<T> _this = JitHelpers.UnsafeCast<IList<T>>(this);
- EnsureIndexInt32(index, _this.Count);
+ EnsureIndexInt32(index, _this.Count);
try
{
@@ -128,7 +128,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal void RemoveAt<T>(uint index)
{
IList<T> _this = JitHelpers.UnsafeCast<IList<T>>(this);
- EnsureIndexInt32(index, _this.Count);
+ EnsureIndexInt32(index, _this.Count);
try
{
@@ -155,7 +155,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
IList<T> _this = JitHelpers.UnsafeCast<IList<T>>(this);
if (_this.Count == 0)
{
- Exception e = new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotRemoveLastFromEmptyCollection"));
+ Exception e = new InvalidOperationException(SR.InvalidOperation_CannotRemoveLastFromEmptyCollection);
e.SetErrorCode(__HResults.E_BOUNDS);
throw e;
}
@@ -201,7 +201,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// that Size > Int32.MaxValue:
if (((uint)Int32.MaxValue) <= index || index >= (uint)listCapacity)
{
- Exception e = new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_IndexLargerThanMaxValue"));
+ Exception e = new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_IndexLargerThanMaxValue);
e.SetErrorCode(__HResults.E_BOUNDS);
throw e;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ManagedActivationFactory.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ManagedActivationFactory.cs
index 2d08cab0ee..12b13ac79b 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ManagedActivationFactory.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/ManagedActivationFactory.cs
@@ -41,8 +41,8 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Check whether the type is "exported to WinRT", i.e. it is declared in a managed .winmd and is decorated
// with at least one ActivatableAttribute or StaticAttribute.
if (!(type is RuntimeType) || !type.IsExportedToWindowsRuntime)
- throw new ArgumentException(Environment.GetResourceString("Argument_TypeNotActivatableViaWindowsRuntime", type), nameof(type));
-
+ throw new ArgumentException(SR.Format(SR.Argument_TypeNotActivatableViaWindowsRuntime, type), nameof(type));
+
m_type = type;
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToCollectionAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToCollectionAdapter.cs
index f11260eb4a..6b6c1719c3 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToCollectionAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToCollectionAdapter.cs
@@ -46,7 +46,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (((uint)Int32.MaxValue) < size)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CollectionBackingDictionaryTooLarge"));
+ throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingDictionaryTooLarge);
}
return (int)size;
@@ -58,7 +58,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (((uint)Int32.MaxValue) < size)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CollectionBackingListTooLarge"));
+ throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingListTooLarge);
}
return (int)size;
@@ -140,10 +140,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
if (array.Length <= arrayIndex && Count<K, V>() > 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_IndexOutOfArrayBounds"));
+ throw new ArgumentException(SR.Argument_IndexOutOfArrayBounds);
if (array.Length - arrayIndex < Count<K, V>())
- throw new ArgumentException(Environment.GetResourceString("Argument_InsufficientSpaceToCopyCollection"));
+ throw new ArgumentException(SR.Argument_InsufficientSpaceToCopyCollection);
Contract.EndContractBlock();
@@ -175,7 +175,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (((uint)Int32.MaxValue) < index)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CollectionBackingListTooLarge"));
+ throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingListTooLarge);
}
VectorToListAdapter.RemoveAtHelper<KeyValuePair<K, V>>(_this_vector, index);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToDictionaryAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToDictionaryAdapter.cs
index 981972ca9f..224a266b07 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToDictionaryAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapToDictionaryAdapter.cs
@@ -88,7 +88,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
throw new ArgumentNullException(nameof(key));
if (ContainsKey<K, V>(key))
- throw new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicate"));
+ throw new ArgumentException(SR.Argument_AddingDuplicate);
Contract.EndContractBlock();
@@ -110,7 +110,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
_this.Remove(key);
return true;
-
}
catch (Exception ex)
{
@@ -158,9 +157,8 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
catch (Exception ex)
{
-
if (__HResults.E_BOUNDS == ex._HResult)
- throw new KeyNotFoundException(Environment.GetResourceString("Arg_KeyNotFound"));
+ throw new KeyNotFoundException(SR.Arg_KeyNotFound);
throw;
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapViewToReadOnlyCollectionAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapViewToReadOnlyCollectionAdapter.cs
index a3715da0b0..5d509549d3 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapViewToReadOnlyCollectionAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/MapViewToReadOnlyCollectionAdapter.cs
@@ -46,7 +46,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (((uint)Int32.MaxValue) < size)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CollectionBackingDictionaryTooLarge"));
+ throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingDictionaryTooLarge);
}
return (int)size;
@@ -58,7 +58,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (((uint)Int32.MaxValue) < size)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CollectionBackingListTooLarge"));
+ throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingListTooLarge);
}
return (int)size;
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/NativeMethods.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/NativeMethods.cs
index 627de8d400..ccae412987 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/NativeMethods.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/NativeMethods.cs
@@ -38,14 +38,14 @@ namespace System.Runtime.InteropServices.WindowsRuntime
[SuppressUnmanagedCodeSecurity]
internal static unsafe extern int WindowsCreateString([MarshalAs(UnmanagedType.LPWStr)] string sourceString,
int length,
- [Out] IntPtr *hstring);
+ [Out] IntPtr* hstring);
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
[SuppressUnmanagedCodeSecurity]
- internal static unsafe extern int WindowsCreateStringReference(char *sourceString,
+ internal static unsafe extern int WindowsCreateStringReference(char* sourceString,
int length,
- [Out] HSTRING_HEADER *hstringHeader,
- [Out] IntPtr *hstring);
+ [Out] HSTRING_HEADER* hstringHeader,
+ [Out] IntPtr* hstring);
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
[SuppressUnmanagedCodeSecurity]
@@ -53,6 +53,6 @@ namespace System.Runtime.InteropServices.WindowsRuntime
[DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)]
[SuppressUnmanagedCodeSecurity]
- internal static unsafe extern char* WindowsGetStringRawBuffer(IntPtr hstring, [Out] uint *length);
+ internal static unsafe extern char* WindowsGetStringRawBuffer(IntPtr hstring, [Out] uint* length);
}
}
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/PropertyValue.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/PropertyValue.cs
index ad64c9917f..8a3e2066cf 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/PropertyValue.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/PropertyValue.cs
@@ -17,20 +17,20 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal enum PropertyType
{
// WARNING: These values have to match enum Windows.Foundation.PropertyType !!!
- Empty = 0,
- UInt8 = 1,
+ Empty = 0,
+ UInt8 = 1,
Int16 = 2,
UInt16 = 3,
- Int32 = 4,
- UInt32 = 5,
- Int64 = 6,
- UInt64 = 7,
- Single = 8,
- Double = 9,
- Char16 = 10,
- Boolean = 11,
- String = 12,
- Inspectable = 13,
+ Int32 = 4,
+ UInt32 = 5,
+ Int64 = 6,
+ UInt64 = 7,
+ Single = 8,
+ Double = 9,
+ Char16 = 10,
+ Boolean = 11,
+ String = 12,
+ Inspectable = 13,
DateTime = 14,
TimeSpan = 15,
Guid = 16,
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/RuntimeClass.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/RuntimeClass.cs
index cd3c53ab4e..fdc0d22632 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/RuntimeClass.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/RuntimeClass.cs
@@ -10,15 +10,15 @@
**
**
===========================================================*/
-namespace System.Runtime.InteropServices.WindowsRuntime {
-
- using System;
- using System.Runtime.InteropServices;
- using System.Runtime.InteropServices.WindowsRuntime;
- using System.Runtime.CompilerServices;
- using System.Security;
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.WindowsRuntime;
+using System.Runtime.CompilerServices;
+using System.Security;
+namespace System.Runtime.InteropServices.WindowsRuntime
+{
// Local definition of Windows.Foundation.IStringable
[ComImport]
[Guid("96369f54-8eb6-48f0-abce-c1b211e627c3")]
@@ -33,7 +33,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
internal static string ToString(object obj)
{
IGetProxyTarget proxy = obj as IGetProxyTarget;
- if (proxy != null)
+ if (proxy != null)
obj = proxy.GetTarget();
// Check whether the type implements IStringable.
@@ -41,12 +41,12 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
if (stringableType != null)
{
return stringableType.ToString();
- }
-
+ }
+
return obj.ToString();
- }
+ }
}
-
+
//
// Base class for every WinRT class
// We'll make it a ComImport and WindowsRuntimeImport in the type loader
@@ -57,11 +57,11 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
//
// Support for ToString/GetHashCode/Equals override
//
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern IntPtr GetRedirectedGetHashCodeMD();
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern int RedirectGetHashCode(IntPtr pMD);
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern IntPtr GetRedirectedGetHashCodeMD();
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern int RedirectGetHashCode(IntPtr pMD);
public override int GetHashCode()
{
@@ -71,10 +71,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
return RedirectGetHashCode(pMD);
}
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern IntPtr GetRedirectedToStringMD();
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern IntPtr GetRedirectedToStringMD();
- [MethodImpl(MethodImplOptions.InternalCall)]
+ [MethodImpl(MethodImplOptions.InternalCall)]
internal extern string RedirectToString(IntPtr pMD);
public override string ToString()
@@ -96,11 +96,11 @@ namespace System.Runtime.InteropServices.WindowsRuntime {
}
}
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern IntPtr GetRedirectedEqualsMD();
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern IntPtr GetRedirectedEqualsMD();
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal extern bool RedirectEquals(object obj, IntPtr pMD);
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern bool RedirectEquals(object obj, IntPtr pMD);
public override bool Equals(object obj)
{
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToCollectionAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToCollectionAdapter.cs
index 898f1a68a0..3065b83c30 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToCollectionAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToCollectionAdapter.cs
@@ -38,7 +38,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
uint size = _this.Size;
if (((uint)Int32.MaxValue) < size)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CollectionBackingListTooLarge"));
+ throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingListTooLarge);
}
return (int)size;
@@ -83,10 +83,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
if (array.Length <= arrayIndex && Count<T>() > 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_IndexOutOfArrayBounds"));
+ throw new ArgumentException(SR.Argument_IndexOutOfArrayBounds);
if (array.Length - arrayIndex < Count<T>())
- throw new ArgumentException(Environment.GetResourceString("Argument_InsufficientSpaceToCopyCollection"));
+ throw new ArgumentException(SR.Argument_InsufficientSpaceToCopyCollection);
Contract.EndContractBlock();
@@ -111,7 +111,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (((uint)Int32.MaxValue) < index)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CollectionBackingListTooLarge"));
+ throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingListTooLarge);
}
VectorToListAdapter.RemoveAtHelper<T>(_this, index);
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToListAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToListAdapter.cs
index 3e3324864d..56e62a25e7 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToListAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorToListAdapter.cs
@@ -63,7 +63,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (((uint)Int32.MaxValue) < index)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CollectionBackingListTooLarge"));
+ throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingListTooLarge);
}
return (int)index;
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorViewToReadOnlyCollectionAdapter.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorViewToReadOnlyCollectionAdapter.cs
index 6b7785d2dc..84c12f8a5c 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorViewToReadOnlyCollectionAdapter.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/VectorViewToReadOnlyCollectionAdapter.cs
@@ -38,7 +38,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
uint size = _this.Size;
if (((uint)Int32.MaxValue) < size)
{
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CollectionBackingListTooLarge"));
+ throw new InvalidOperationException(SR.InvalidOperation_CollectionBackingListTooLarge);
}
return (int)size;
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeBufferHelper.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeBufferHelper.cs
index 551ee65153..55c356de93 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeBufferHelper.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeBufferHelper.cs
@@ -9,29 +9,26 @@ using System.Security;
using System.Threading;
-namespace System.Runtime.InteropServices.WindowsRuntime {
-
-/// <summary>
-/// Exposes a helper method that allows <code>WindowsRuntimeBuffer : IBuffer, IBufferInternal</code> which is implemented in
-/// <code>System.Runtime.WindowsRuntime.dll</code> to call into the VM.
-/// </summary>
-[FriendAccessAllowed]
-internal static class WindowsRuntimeBufferHelper {
-
-
- [DllImport(JitHelpers.QCall)]
- [SuppressUnmanagedCodeSecurity]
- private unsafe extern static void StoreOverlappedPtrInCCW(ObjectHandleOnStack windowsRuntimeBuffer, NativeOverlapped* overlapped);
-
-
+namespace System.Runtime.InteropServices.WindowsRuntime
+{
+ /// <summary>
+ /// Exposes a helper method that allows <code>WindowsRuntimeBuffer : IBuffer, IBufferInternal</code> which is implemented in
+ /// <code>System.Runtime.WindowsRuntime.dll</code> to call into the VM.
+ /// </summary>
[FriendAccessAllowed]
- internal unsafe static void StoreOverlappedInCCW(Object windowsRuntimeBuffer, NativeOverlapped* overlapped) {
-
- StoreOverlappedPtrInCCW(JitHelpers.GetObjectHandleOnStack(ref windowsRuntimeBuffer), overlapped);
- }
-
-} // class WindowsRuntimeBufferHelper
-
+ internal static class WindowsRuntimeBufferHelper
+ {
+ [DllImport(JitHelpers.QCall)]
+ [SuppressUnmanagedCodeSecurity]
+ private unsafe extern static void StoreOverlappedPtrInCCW(ObjectHandleOnStack windowsRuntimeBuffer, NativeOverlapped* overlapped);
+
+
+ [FriendAccessAllowed]
+ internal unsafe static void StoreOverlappedInCCW(Object windowsRuntimeBuffer, NativeOverlapped* overlapped)
+ {
+ StoreOverlappedPtrInCCW(JitHelpers.GetObjectHandleOnStack(ref windowsRuntimeBuffer), overlapped);
+ }
+ } // class WindowsRuntimeBufferHelper
} // namespace
// WindowsRuntimeBufferHelper.cs
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs
index 57655ec861..0b7ba10d62 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMarshal.cs
@@ -75,9 +75,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (target == null || Marshal.IsComObject(target))
NativeOrStaticEventRegistrationImpl.RemoveEventHandler<T>(removeMethod, handler);
else
- ManagedEventRegistrationImpl.RemoveEventHandler<T>(removeMethod, handler);
+ ManagedEventRegistrationImpl.RemoveEventHandler<T>(removeMethod, handler);
}
-
+
public static void RemoveAllEventHandlers(Action<EventRegistrationToken> removeMethod)
{
if (removeMethod == null)
@@ -108,7 +108,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
count += ManagedEventRegistrationImpl.s_eventRegistrations.Keys.Count;
}
}
-
+
if (NativeOrStaticEventRegistrationImpl.s_eventRegistrations != null)
{
lock (NativeOrStaticEventRegistrationImpl.s_eventRegistrations)
@@ -116,7 +116,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
count += NativeOrStaticEventRegistrationImpl.s_eventRegistrations.Count;
}
}
-
+
return count;
}
@@ -124,11 +124,11 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Optimized version of List of EventRegistrationToken
// It is made a struct to reduce overhead
//
- internal struct EventRegistrationTokenList
+ internal struct EventRegistrationTokenList
{
- private EventRegistrationToken firstToken; // Optimization for common case where there is only one token
- private List<EventRegistrationToken> restTokens; // Rest of the tokens
-
+ private EventRegistrationToken firstToken; // Optimization for common case where there is only one token
+ private List<EventRegistrationToken> restTokens; // Rest of the tokens
+
internal EventRegistrationTokenList(EventRegistrationToken token)
{
firstToken = token;
@@ -141,18 +141,18 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public bool Push(EventRegistrationToken token)
{
bool needCopy = false;
-
+
if (restTokens == null)
{
restTokens = new List<EventRegistrationToken>();
needCopy = true;
}
-
+
restTokens.Add(token);
return needCopy;
}
-
+
// Pops the last token
// Returns false if no more tokens left, true otherwise
public bool Pop(out EventRegistrationToken token)
@@ -163,14 +163,14 @@ namespace System.Runtime.InteropServices.WindowsRuntime
token = firstToken;
return false;
}
-
+
int last = restTokens.Count - 1;
token = restTokens[last];
restTokens.RemoveAt(last);
-
+
return true;
}
-
+
public void CopyTo(List<EventRegistrationToken> tokens)
{
tokens.Add(firstToken);
@@ -183,7 +183,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Event registration support for managed objects events & static events
//
internal static class ManagedEventRegistrationImpl
- {
+ {
// Mappings of delegates registered for events -> their registration tokens.
// These mappings are stored indexed by the remove method which can be used to undo the registrations.
//
@@ -208,10 +208,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// If the delegates aren't alive, it means either they have been unsubscribed, or the object itself is gone,
// and in either case, they've been already taken care of.
//
- internal volatile static
- ConditionalWeakTable<object, Dictionary<MethodInfo, Dictionary<object, EventRegistrationTokenList>>> s_eventRegistrations =
+ internal volatile static
+ ConditionalWeakTable<object, Dictionary<MethodInfo, Dictionary<object, EventRegistrationTokenList>>> s_eventRegistrations =
new ConditionalWeakTable<object, Dictionary<MethodInfo, Dictionary<object, EventRegistrationTokenList>>>();
-
+
internal static void AddEventHandler<T>(Func<T, EventRegistrationToken> addMethod,
Action<EventRegistrationToken> removeMethod,
T handler)
@@ -239,18 +239,18 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (needCopy)
registrationTokens[handler] = tokens;
}
-
+
BCLDebug.Log("INTEROP", "[WinRT_Eventing] Event subscribed for managed instance = " + instance + ", handler = " + handler + "\n");
}
}
-
+
// Get the event registration token table for an event. These are indexed by the remove method of the event.
private static Dictionary<object, EventRegistrationTokenList> GetEventRegistrationTokenTable(object instance, Action<EventRegistrationToken> removeMethod)
{
Contract.Requires(instance != null);
Contract.Requires(removeMethod != null);
- Contract.Requires(s_eventRegistrations != null);
-
+ Contract.Requires(s_eventRegistrations != null);
+
lock (s_eventRegistrations)
{
Dictionary<MethodInfo, Dictionary<object, EventRegistrationTokenList>> instanceMap = null;
@@ -259,14 +259,14 @@ namespace System.Runtime.InteropServices.WindowsRuntime
instanceMap = new Dictionary<MethodInfo, Dictionary<object, EventRegistrationTokenList>>();
s_eventRegistrations.Add(instance, instanceMap);
}
-
+
Dictionary<object, EventRegistrationTokenList> tokens = null;
if (!instanceMap.TryGetValue(removeMethod.Method, out tokens))
{
tokens = new Dictionary<object, EventRegistrationTokenList>();
instanceMap.Add(removeMethod.Method, tokens);
}
-
+
return tokens;
}
}
@@ -278,19 +278,19 @@ namespace System.Runtime.InteropServices.WindowsRuntime
object instance = removeMethod.Target;
Dictionary<object, EventRegistrationTokenList> registrationTokens = GetEventRegistrationTokenTable(instance, removeMethod);
EventRegistrationToken token;
-
+
lock (registrationTokens)
{
EventRegistrationTokenList tokens;
-
+
// Failure to find a registration for a token is not an error - it's simply a no-op.
if (!registrationTokens.TryGetValue(handler, out tokens))
{
- BCLDebug.Log("INTEROP", "[WinRT_Eventing] no registrationTokens found for instance=" + instance + ", handler= " + handler + "\n");
-
+ BCLDebug.Log("INTEROP", "[WinRT_Eventing] no registrationTokens found for instance=" + instance + ", handler= " + handler + "\n");
+
return;
}
-
+
// Select a registration token to unregister
// We don't care which one but I'm returning the last registered token to be consistent
// with native event registration implementation
@@ -306,23 +306,23 @@ namespace System.Runtime.InteropServices.WindowsRuntime
registrationTokens.Remove(handler);
}
}
-
+
removeMethod(token);
- BCLDebug.Log("INTEROP", "[WinRT_Eventing] Event unsubscribed for managed instance = " + instance + ", handler = " + handler + ", token = " + token.m_value + "\n");
+ BCLDebug.Log("INTEROP", "[WinRT_Eventing] Event unsubscribed for managed instance = " + instance + ", handler = " + handler + ", token = " + token.m_value + "\n");
}
internal static void RemoveAllEventHandlers(Action<EventRegistrationToken> removeMethod)
{
- Contract.Requires(removeMethod != null);
+ Contract.Requires(removeMethod != null);
object instance = removeMethod.Target;
Dictionary<object, EventRegistrationTokenList> registrationTokens = GetEventRegistrationTokenTable(instance, removeMethod);
List<EventRegistrationToken> tokensToRemove = new List<EventRegistrationToken>();
-
+
lock (registrationTokens)
- {
+ {
// Copy all tokens to tokensToRemove array which later we'll call removeMethod on
// outside this lock
foreach (EventRegistrationTokenList tokens in registrationTokens.Values)
@@ -339,9 +339,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
//
// Remove all handlers outside the lock
//
- BCLDebug.Log("INTEROP", "[WinRT_Eventing] Start removing all events for instance = " + instance + "\n");
+ BCLDebug.Log("INTEROP", "[WinRT_Eventing] Start removing all events for instance = " + instance + "\n");
CallRemoveMethods(removeMethod, tokensToRemove);
- BCLDebug.Log("INTEROP", "[WinRT_Eventing] Finished removing all events for instance = " + instance + "\n");
+ BCLDebug.Log("INTEROP", "[WinRT_Eventing] Finished removing all events for instance = " + instance + "\n");
}
}
@@ -349,15 +349,15 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// WinRT event registration implementation code
//
internal static class NativeOrStaticEventRegistrationImpl
- {
+ {
//
// Key = (target object, event)
// We use a key of object+event to save an extra dictionary
//
internal struct EventCacheKey
{
- internal object target;
- internal MethodInfo method;
+ internal object target;
+ internal MethodInfo method;
public override string ToString()
{
@@ -377,7 +377,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return key.target.GetHashCode() ^ key.method.GetHashCode();
}
}
-
+
//
// EventRegistrationTokenListWithCount
//
@@ -390,9 +390,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
//
internal class EventRegistrationTokenListWithCount
{
- private TokenListCount _tokenListCount;
- EventRegistrationTokenList _tokenList;
-
+ private TokenListCount _tokenListCount;
+ private EventRegistrationTokenList _tokenList;
+
internal EventRegistrationTokenListWithCount(TokenListCount tokenListCount, EventRegistrationToken token)
{
_tokenListCount = tokenListCount;
@@ -400,30 +400,30 @@ namespace System.Runtime.InteropServices.WindowsRuntime
_tokenList = new EventRegistrationTokenList(token);
}
-
+
~EventRegistrationTokenListWithCount()
- {
+ {
// Decrement token list count
// This is need to correctly keep trace of number of tokens for EventCacheKey
// and remove it from cache when the token count drop to 0
// we don't need to take locks for decrement the count - we only need to take a global
// lock when we decide to destroy cache for the IUnknown */type instance
- BCLDebug.Log("INTEROP", "[WinRT_Eventing] Finalizing EventRegistrationTokenList for " + _tokenListCount.Key + "\n");
+ BCLDebug.Log("INTEROP", "[WinRT_Eventing] Finalizing EventRegistrationTokenList for " + _tokenListCount.Key + "\n");
_tokenListCount.Dec();
}
-
+
public void Push(EventRegistrationToken token)
{
// Since EventRegistrationTokenListWithCount is a reference type, there is no need
// to copy back. Ignore the return value
_tokenList.Push(token);
}
-
+
public bool Pop(out EventRegistrationToken token)
{
return _tokenList.Pop(out token);
}
-
+
public void CopyTo(List<EventRegistrationToken> tokens)
{
_tokenList.CopyTo(tokens);
@@ -438,8 +438,8 @@ namespace System.Runtime.InteropServices.WindowsRuntime
//
internal class TokenListCount
{
- private int _count;
- private EventCacheKey _key;
+ private int _count;
+ private EventCacheKey _key;
internal TokenListCount(EventCacheKey key)
{
@@ -448,14 +448,13 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal EventCacheKey Key
{
-
get { return _key; }
}
-
+
internal void Inc()
{
int newCount = Interlocked.Increment(ref _count);
- BCLDebug.Log("INTEROP", "[WinRT_Eventing] Incremented TokenListCount for " + _key + ", Value = " + newCount + "\n");
+ BCLDebug.Log("INTEROP", "[WinRT_Eventing] Incremented TokenListCount for " + _key + ", Value = " + newCount + "\n");
}
internal void Dec()
@@ -466,7 +465,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
try
{
int newCount = Interlocked.Decrement(ref _count);
- BCLDebug.Log("INTEROP", "[WinRT_Eventing] Decremented TokenListCount for " + _key + ", Value = " + newCount + "\n");
+ BCLDebug.Log("INTEROP", "[WinRT_Eventing] Decremented TokenListCount for " + _key + ", Value = " + newCount + "\n");
if (newCount == 0)
CleanupCache();
}
@@ -482,7 +481,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// because the total token list count has dropped to 0 and we don't have any events subscribed
Contract.Requires(s_eventRegistrations != null);
- BCLDebug.Log("INTEROP", "[WinRT_Eventing] Removing " + _key + " from cache" + "\n");
+ BCLDebug.Log("INTEROP", "[WinRT_Eventing] Removing " + _key + " from cache" + "\n");
s_eventRegistrations.Remove(_key);
BCLDebug.Log("INTEROP", "[WinRT_Eventing] s_eventRegistrations size = " + s_eventRegistrations.Count + "\n");
}
@@ -520,7 +519,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// b. The same delegate is subscribed then unsubscribed. We need to make sure give
// them the latest token in this case. This is guaranteed by always giving the last token and always use equality to
// add/remove event handlers
- internal volatile static Dictionary<EventCacheKey, EventCacheEntry> s_eventRegistrations =
+ internal volatile static Dictionary<EventCacheKey, EventCacheEntry> s_eventRegistrations =
new Dictionary<EventCacheKey, EventCacheEntry>(new EventCacheKeyEqualityComparer());
// Prevent add/remove handler code to run at the same with with cache cleanup code
@@ -533,11 +532,11 @@ namespace System.Runtime.InteropServices.WindowsRuntime
Debug.Assert(target == null || Marshal.IsComObject(target), "Must be null or a RCW");
if (target == null)
return removeMethod.Method.DeclaringType;
-
+
// Need the "Raw" IUnknown pointer for the RCW that is not bound to the current context
- return (object) Marshal.GetRawIUnknownForComObjectNoAddRef(target);
+ return (object)Marshal.GetRawIUnknownForComObjectNoAddRef(target);
}
-
+
internal static void AddEventHandler<T>(Func<T, EventRegistrationToken> addMethod,
Action<EventRegistrationToken> removeMethod,
T handler)
@@ -552,11 +551,11 @@ namespace System.Runtime.InteropServices.WindowsRuntime
EventRegistrationToken token = addMethod(handler);
bool tokenAdded = false;
-
+
try
{
EventRegistrationTokenListWithCount tokens;
-
+
//
// The whole add/remove code has to be protected by a reader/writer lock
// Add/Remove cannot run at the same time with cache cleanup but Add/Remove can run at the same time
@@ -592,8 +591,8 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
tokens.Push(token);
}
-
- tokenAdded = true;
+
+ tokenAdded = true;
}
}
finally
@@ -601,10 +600,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
s_eventCacheRWLock.ReleaseReaderLock();
}
- BCLDebug.Log("INTEROP", "[WinRT_Eventing] Event subscribed for instance = " + instanceKey + ", handler = " + handler + "\n");
+ BCLDebug.Log("INTEROP", "[WinRT_Eventing] Event subscribed for instance = " + instanceKey + ", handler = " + handler + "\n");
}
- catch(Exception)
- {
+ catch (Exception)
+ {
// If we've already added the token and go there, we don't need to "UNDO" anything
if (!tokenAdded)
{
@@ -613,8 +612,8 @@ namespace System.Runtime.InteropServices.WindowsRuntime
removeMethod(token);
}
-
- throw;
+
+ throw;
}
}
@@ -633,18 +632,18 @@ namespace System.Runtime.InteropServices.WindowsRuntime
return GetEventRegistrationTokenTableInternal(instance, removeMethod, out tokenListCount, /* createIfNotFound = */ true);
}
-
+
// Get the event registration token table for an event. These are indexed by the remove method of the event.
private static ConditionalWeakTable<object, EventRegistrationTokenListWithCount> GetEventRegistrationTokenTableInternal(object instance, Action<EventRegistrationToken> removeMethod, out TokenListCount tokenListCount, bool createIfNotFound)
{
Contract.Requires(instance != null);
Contract.Requires(removeMethod != null);
- Contract.Requires(s_eventRegistrations != null);
+ Contract.Requires(s_eventRegistrations != null);
EventCacheKey eventCacheKey;
eventCacheKey.target = instance;
eventCacheKey.method = removeMethod.Method;
-
+
lock (s_eventRegistrations)
{
EventCacheEntry eventCacheEntry;
@@ -656,18 +655,18 @@ namespace System.Runtime.InteropServices.WindowsRuntime
tokenListCount = null;
return null;
}
-
+
BCLDebug.Log("INTEROP", "[WinRT_Eventing] Adding (" + instance + "," + removeMethod.Method + ") into cache" + "\n");
-
+
eventCacheEntry = new EventCacheEntry();
eventCacheEntry.registrationTable = new ConditionalWeakTable<object, EventRegistrationTokenListWithCount>();
eventCacheEntry.tokenListCount = new TokenListCount(eventCacheKey);
-
+
s_eventRegistrations.Add(eventCacheKey, eventCacheEntry);
}
-
+
tokenListCount = eventCacheEntry.tokenListCount;
-
+
return eventCacheEntry.registrationTable;
}
}
@@ -677,7 +676,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
object instanceKey = GetInstanceKey(removeMethod);
EventRegistrationToken token;
-
+
//
// The whole add/remove code has to be protected by a reader/writer lock
// Add/Remove cannot run at the same time with cache cleanup but Add/Remove can run at the same time
@@ -691,10 +690,10 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
// We have no information regarding this particular instance (IUnknown*/type) - just return
// This is necessary to avoid leaking empty dictionary/conditionalWeakTables for this instance
- BCLDebug.Log("INTEROP", "[WinRT_Eventing] no registrationTokens found for instance=" + instanceKey + ", handler= " + handler + "\n");
+ BCLDebug.Log("INTEROP", "[WinRT_Eventing] no registrationTokens found for instance=" + instanceKey + ", handler= " + handler + "\n");
return;
}
-
+
lock (registrationTokens)
{
EventRegistrationTokenListWithCount tokens;
@@ -707,12 +706,12 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Note that inside TryGetValueWithValueEquality we assumes that any delegate
// with the same value equality would have the same hash code
object key = registrationTokens.FindEquivalentKeyUnsafe(handler, out tokens);
- Debug.Assert((key != null && tokens != null) || (key == null && tokens == null),
+ Debug.Assert((key != null && tokens != null) || (key == null && tokens == null),
"key and tokens must be both null or non-null");
if (tokens == null)
{
// Failure to find a registration for a token is not an error - it's simply a no-op.
- BCLDebug.Log("INTEROP", "[WinRT_Eventing] no token list found for instance=" + instanceKey + ", handler= " + handler + "\n");
+ BCLDebug.Log("INTEROP", "[WinRT_Eventing] no token list found for instance=" + instanceKey + ", handler= " + handler + "\n");
return;
}
@@ -721,7 +720,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// is created at the same address before the entry for the old one goes away.
// See comments above s_eventRegistrations for more details
bool moreItems = tokens.Pop(out token);
-
+
// If the last token is removed from token list, we need to remove it from the cache
// otherwise FindEquivalentKeyUnsafe may found this empty token list even though there could be other
// equivalent keys in there with non-0 token list
@@ -733,8 +732,8 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// EventRegistrationTokenList
registrationTokens.Remove(key);
}
-
- BCLDebug.Log("INTEROP", "[WinRT_Eventing] Event unsubscribed for managed instance = " + instanceKey + ", handler = " + handler + ", token = " + token.m_value + "\n");
+
+ BCLDebug.Log("INTEROP", "[WinRT_Eventing] Event unsubscribed for managed instance = " + instanceKey + ", handler = " + handler + ", token = " + token.m_value + "\n");
}
}
finally
@@ -745,7 +744,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Call removeMethod outside of RW lock
// At this point we don't need to worry about race conditions and we can avoid deadlocks
// if removeMethod waits on finalizer thread
- removeMethod(token);
+ removeMethod(token);
}
internal static void RemoveAllEventHandlers(Action<EventRegistrationToken> removeMethod)
@@ -753,7 +752,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
object instanceKey = GetInstanceKey(removeMethod);
List<EventRegistrationToken> tokensToRemove = new List<EventRegistrationToken>();
-
+
//
// The whole add/remove code has to be protected by a reader/writer lock
// Add/Remove cannot run at the same time with cache cleanup but Add/Remove can run at the same time
@@ -769,7 +768,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// This is necessary to avoid leaking empty dictionary/conditionalWeakTables for this instance
return;
}
-
+
lock (registrationTokens)
{
// Copy all tokens to tokensToRemove array which later we'll call removeMethod on
@@ -782,7 +781,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Clear the table - at this point all event handlers are no longer in the cache
// but they are not removed yet
registrationTokens.Clear();
- BCLDebug.Log("INTEROP", "[WinRT_Eventing] Cache cleared for managed instance = " + instanceKey + "\n");
+ BCLDebug.Log("INTEROP", "[WinRT_Eventing] Cache cleared for managed instance = " + instanceKey + "\n");
}
}
finally
@@ -793,18 +792,17 @@ namespace System.Runtime.InteropServices.WindowsRuntime
//
// Remove all handlers outside the lock
//
- BCLDebug.Log("INTEROP", "[WinRT_Eventing] Start removing all events for instance = " + instanceKey + "\n");
+ BCLDebug.Log("INTEROP", "[WinRT_Eventing] Start removing all events for instance = " + instanceKey + "\n");
CallRemoveMethods(removeMethod, tokensToRemove);
- BCLDebug.Log("INTEROP", "[WinRT_Eventing] Finished removing all events for instance = " + instanceKey + "\n");
+ BCLDebug.Log("INTEROP", "[WinRT_Eventing] Finished removing all events for instance = " + instanceKey + "\n");
}
-
+
internal class ReaderWriterLockTimedOutException : ApplicationException
{
}
- /// I borrowed Vance's reader writer lock implementation from his blog as ReaderWriterLockSlim is
- /// available in System.Core.dll!
+ /// Discussed @ https://blogs.msdn.microsoft.com/vancem/2006/03/29/analysis-of-reader-writer-lock/
///
/// <summary>
/// A reader-writer lock implementation that is intended to be simple, yet very
@@ -821,19 +819,19 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Lock specifiation for myLock: This lock protects exactly the local fields associted
// instance of MyReaderWriterLock. It does NOT protect the memory associted with the
// the events that hang off this lock (eg writeEvent, readEvent upgradeEvent).
- int myLock;
+ private int myLock;
// Who owns the lock owners > 0 => readers
// owners = -1 means there is one writer. Owners must be >= -1.
- int owners;
+ private int owners;
// These variables allow use to avoid Setting events (which is expensive) if we don't have to.
- uint numWriteWaiters; // maximum number of threads that can be doing a WaitOne on the writeEvent
- uint numReadWaiters; // maximum number of threads that can be doing a WaitOne on the readEvent
+ private uint numWriteWaiters; // maximum number of threads that can be doing a WaitOne on the writeEvent
+ private uint numReadWaiters; // maximum number of threads that can be doing a WaitOne on the readEvent
// conditions we wait on.
- EventWaitHandle writeEvent; // threads waiting to aquire a write lock go here.
- EventWaitHandle readEvent; // threads waiting to aquire a read lock go here (will be released in bulk)
+ private EventWaitHandle writeEvent; // threads waiting to aquire a write lock go here.
+ private EventWaitHandle readEvent; // threads waiting to aquire a read lock go here (will be released in bulk)
internal MyReaderWriterLock()
{
@@ -843,7 +841,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal void AcquireReaderLock(int millisecondsTimeout)
{
EnterMyLock();
- for (; ; )
+ for (;;)
{
// We can enter a read lock if there are only read-locks have been given out
// and a writer is not trying to get in.
@@ -869,7 +867,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
internal void AcquireWriterLock(int millisecondsTimeout)
{
EnterMyLock();
- for (; ; )
+ for (;;)
{
if (owners == 0)
{
@@ -912,15 +910,16 @@ namespace System.Runtime.InteropServices.WindowsRuntime
/// while holding a spin lock). If all goes well, reenter the lock and
/// set 'waitEvent'
/// </summary>
- private void LazyCreateEvent(ref EventWaitHandle waitEvent, bool makeAutoResetEvent) {
+ private void LazyCreateEvent(ref EventWaitHandle waitEvent, bool makeAutoResetEvent)
+ {
Debug.Assert(myLock != 0, "Lock must be held");
Debug.Assert(waitEvent == null, "Wait event must be null");
ExitMyLock();
EventWaitHandle newEvent;
- if (makeAutoResetEvent)
+ if (makeAutoResetEvent)
newEvent = new AutoResetEvent(false);
- else
+ else
newEvent = new ManualResetEvent(false);
EnterMyLock();
if (waitEvent == null) // maybe someone snuck in.
@@ -944,7 +943,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
if (!waitEvent.WaitOne(millisecondsTimeout, false))
throw new ReaderWriterLockTimedOutException();
-
+
waitSuccessful = true;
}
finally
@@ -977,18 +976,19 @@ namespace System.Runtime.InteropServices.WindowsRuntime
ExitMyLock();
}
- private void EnterMyLock() {
+ private void EnterMyLock()
+ {
if (Interlocked.CompareExchange(ref myLock, 1, 0) != 0)
EnterMyLockSpin();
}
private void EnterMyLockSpin()
{
- for (int i = 0; ;i++)
+ for (int i = 0; ; i++)
{
if (i < 3 && Environment.ProcessorCount > 1)
Thread.SpinWait(20); // Wait a few dozen instructions to let another processor release lock.
- else
+ else
Thread.Sleep(0); // Give up my quantum.
if (Interlocked.CompareExchange(ref myLock, 1, 0) == 0)
@@ -1000,7 +1000,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
Debug.Assert(myLock != 0, "Exiting spin lock that is not held");
myLock = 0;
}
- };
+ };
}
//
@@ -1008,27 +1008,26 @@ namespace System.Runtime.InteropServices.WindowsRuntime
//
internal static void CallRemoveMethods(Action<EventRegistrationToken> removeMethod, List<EventRegistrationToken> tokensToRemove)
{
-
List<Exception> exceptions = new List<Exception>();
-
+
foreach (EventRegistrationToken token in tokensToRemove)
{
try
{
removeMethod(token);
}
- catch(Exception ex)
+ catch (Exception ex)
{
exceptions.Add(ex);
}
-
+
BCLDebug.Log("INTEROP", "[WinRT_Eventing] Event unsubscribed for token = " + token.m_value + "\n");
- }
+ }
if (exceptions.Count > 0)
throw new AggregateException(exceptions.ToArray());
}
-
+
internal static unsafe string HStringToString(IntPtr hstring)
{
Contract.Requires(Environment.IsWinRTSupported);
@@ -1055,13 +1054,13 @@ namespace System.Runtime.InteropServices.WindowsRuntime
string message = innerException.Message;
if (message == null && messageResource != null)
{
- message = Environment.GetResourceString(messageResource);
+ message = SR.GetResourceString(messageResource);
}
e = new Exception(message, innerException);
}
else
{
- string message = (messageResource != null ? Environment.GetResourceString(messageResource) : null);
+ string message = (messageResource != null ? SR.GetResourceString(messageResource): null);
e = new Exception(message);
}
@@ -1109,7 +1108,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
private static Guid s_iidIErrorInfo = new Guid(0x1CF2B120, 0x547D, 0x101B, 0x8E, 0x65, 0x08, 0x00, 0x2B, 0x2B, 0xD1, 0x19);
-
+
/// <summary>
/// Report that an exception has occurred which went user unhandled. This allows the global error handler
/// for the application to be invoked to process the error.
@@ -1183,14 +1182,14 @@ namespace System.Runtime.InteropServices.WindowsRuntime
// Get an IActivationFactory * for a managed type
internal static IntPtr GetActivationFactoryForType(Type type)
{
- ManagedActivationFactory activationFactory = GetManagedActivationFactory(type);
+ ManagedActivationFactory activationFactory = GetManagedActivationFactory(type);
return Marshal.GetComInterfaceForObject(activationFactory, typeof(IActivationFactory));
- }
+ }
internal static ManagedActivationFactory GetManagedActivationFactory(Type type)
{
ManagedActivationFactory activationFactory = new ManagedActivationFactory(type);
-
+
// If the type has any associated factory interfaces (i.e. supports non-default activation
// or has statics), the CCW for this instance of ManagedActivationFactory must support them.
Marshal.InitializeManagedWinRTFactoryObject(activationFactory, (RuntimeType)type);
@@ -1235,7 +1234,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public static IntPtr StringToHString(String s)
{
if (!Environment.IsWinRTSupported)
- throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_WinRT);
if (s == null)
throw new ArgumentNullException(nameof(s));
@@ -1253,7 +1252,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
if (!Environment.IsWinRTSupported)
{
- throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_WinRT);
}
return HStringToString(ptr);
@@ -1262,7 +1261,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
public static void FreeHString(IntPtr ptr)
{
if (!Environment.IsWinRTSupported)
- throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_WinRT);
if (ptr != IntPtr.Zero)
{
diff --git a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMetadata.cs b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMetadata.cs
index f097c6a0db..0f28d3b080 100644
--- a/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMetadata.cs
+++ b/src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeMetadata.cs
@@ -4,22 +4,22 @@
//
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics.Contracts;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Security;
+
namespace System.Runtime.InteropServices.WindowsRuntime
{
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Diagnostics.Contracts;
- using System.Reflection;
- using System.Reflection.Emit;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Security;
-
internal static class WindowsRuntimeMetadata
{
private static EventHandler<DesignerNamespaceResolveEventArgs> DesignerNamespaceResolve;
-
+
internal static string[] OnDesignerNamespaceResolveEvent(AppDomain appDomain, string namespaceName)
{
EventHandler<DesignerNamespaceResolveEventArgs> eventHandler = DesignerNamespaceResolve;
@@ -42,7 +42,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
{
if (String.IsNullOrEmpty(assemblyFile))
{ // DesignerNamespaceResolve event returned null or empty file name - that is not allowed
- throw new ArgumentException(Environment.GetResourceString("Arg_EmptyOrNullString"), "DesignerNamespaceResolveEventArgs.ResolvedAssemblyFiles");
+ throw new ArgumentException(SR.Arg_EmptyOrNullString, "DesignerNamespaceResolveEventArgs.ResolvedAssemblyFiles");
}
retAssemblyFiles[retIndex] = assemblyFile;
retIndex++;
@@ -52,50 +52,11 @@ namespace System.Runtime.InteropServices.WindowsRuntime
}
}
}
-
+
return null;
}
}
-
-#if FEATURE_REFLECTION_ONLY_LOAD
- public class NamespaceResolveEventArgs : EventArgs
- {
- private string _NamespaceName;
- private Assembly _RequestingAssembly;
- private Collection<Assembly> _ResolvedAssemblies;
-
- public string NamespaceName
- {
- get
- {
- return _NamespaceName;
- }
- }
-
- public Assembly RequestingAssembly
- {
- get
- {
- return _RequestingAssembly;
- }
- }
- public Collection<Assembly> ResolvedAssemblies
- {
- get
- {
- return _ResolvedAssemblies;
- }
- }
-
- public NamespaceResolveEventArgs(string namespaceName, Assembly requestingAssembly)
- {
- _NamespaceName = namespaceName;
- _RequestingAssembly = requestingAssembly;
- _ResolvedAssemblies = new Collection<Assembly>();
- }
- }
-#endif //FEATURE_REFLECTION_ONLY
internal class DesignerNamespaceResolveEventArgs : EventArgs
{
diff --git a/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs b/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs
index 2be8b13274..de8137f1ec 100644
--- a/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs
+++ b/src/mscorlib/src/System/Runtime/Loader/AssemblyLoadContext.cs
@@ -18,19 +18,18 @@ namespace System.Runtime.Loader
{
public abstract class AssemblyLoadContext
{
-
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern bool CanUseAppPathAssemblyLoadContextInCurrentDomain();
-
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern IntPtr InitializeAssemblyLoadContext(IntPtr ptrAssemblyLoadContext, bool fRepresentsTPALoadContext);
-
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern IntPtr LoadFromStream(IntPtr ptrNativeAssemblyLoadContext, IntPtr ptrAssemblyArray, int iAssemblyArrayLen, IntPtr ptrSymbols, int iSymbolArrayLen, ObjectHandleOnStack retAssembly);
-
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal static extern void InternalSetProfileRoot(string directoryPath);
@@ -50,8 +49,8 @@ namespace System.Runtime.Loader
// Initialize the ALC representing TPA LoadContext
InitializeLoadContext(fRepresentsTPALoadContext);
}
-
- void InitializeLoadContext(bool fRepresentsTPALoadContext)
+
+ private void InitializeLoadContext(bool fRepresentsTPALoadContext)
{
// Initialize the VM side of AssemblyLoadContext if not already done.
GCHandle gchALC = GCHandle.Alloc(this);
@@ -75,14 +74,14 @@ namespace System.Runtime.Loader
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetLoadedAssembliesInternal(ObjectHandleOnStack assemblies);
-
+
public static Assembly[] GetLoadedAssemblies()
{
Assembly[] assemblies = null;
GetLoadedAssembliesInternal(JitHelpers.GetObjectHandleOnStack(ref assemblies));
return assemblies;
}
-
+
// These are helpers that can be used by AssemblyLoadContext derivations.
// They are used to load assemblies in DefaultContext.
public Assembly LoadFromAssemblyPath(string assemblyPath)
@@ -94,14 +93,14 @@ namespace System.Runtime.Loader
if (PathInternal.IsPartiallyQualified(assemblyPath))
{
- throw new ArgumentException( Environment.GetResourceString("Argument_AbsolutePathRequired"), nameof(assemblyPath));
+ throw new ArgumentException(SR.Argument_AbsolutePathRequired, nameof(assemblyPath));
}
RuntimeAssembly loadedAssembly = null;
LoadFromPath(m_pNativeAssemblyLoadContext, assemblyPath, null, JitHelpers.GetObjectHandleOnStack(ref loadedAssembly));
return loadedAssembly;
}
-
+
public Assembly LoadFromNativeImagePath(string nativeImagePath, string assemblyPath)
{
if (nativeImagePath == null)
@@ -111,12 +110,12 @@ namespace System.Runtime.Loader
if (PathInternal.IsPartiallyQualified(nativeImagePath))
{
- throw new ArgumentException( Environment.GetResourceString("Argument_AbsolutePathRequired"), nameof(nativeImagePath));
+ throw new ArgumentException(SR.Argument_AbsolutePathRequired, nameof(nativeImagePath));
}
if (assemblyPath != null && PathInternal.IsPartiallyQualified(assemblyPath))
{
- throw new ArgumentException(Environment.GetResourceString("Argument_AbsolutePathRequired"), nameof(assemblyPath));
+ throw new ArgumentException(SR.Argument_AbsolutePathRequired, nameof(assemblyPath));
}
// Basic validation has succeeded - lets try to load the NI image.
@@ -125,74 +124,79 @@ namespace System.Runtime.Loader
LoadFromPath(m_pNativeAssemblyLoadContext, assemblyPath, nativeImagePath, JitHelpers.GetObjectHandleOnStack(ref loadedAssembly));
return loadedAssembly;
}
-
+
public Assembly LoadFromStream(Stream assembly)
{
return LoadFromStream(assembly, null);
}
-
+
public Assembly LoadFromStream(Stream assembly, Stream assemblySymbols)
{
if (assembly == null)
{
throw new ArgumentNullException(nameof(assembly));
}
-
+
+ if (assembly.Length <= 0)
+ {
+ throw new BadImageFormatException(SR.BadImageFormat_BadILFormat);
+ }
+
int iAssemblyStreamLength = (int)assembly.Length;
int iSymbolLength = 0;
-
+
// Allocate the byte[] to hold the assembly
byte[] arrAssembly = new byte[iAssemblyStreamLength];
-
+
// Copy the assembly to the byte array
assembly.Read(arrAssembly, 0, iAssemblyStreamLength);
-
+
// Get the symbol stream in byte[] if provided
byte[] arrSymbols = null;
if (assemblySymbols != null)
{
iSymbolLength = (int)assemblySymbols.Length;
arrSymbols = new byte[iSymbolLength];
-
+
assemblySymbols.Read(arrSymbols, 0, iSymbolLength);
}
-
+
RuntimeAssembly loadedAssembly = null;
- unsafe
+ unsafe
{
- fixed(byte *ptrAssembly = arrAssembly, ptrSymbols = arrSymbols)
+ fixed (byte* ptrAssembly = arrAssembly, ptrSymbols = arrSymbols)
{
LoadFromStream(m_pNativeAssemblyLoadContext, new IntPtr(ptrAssembly), iAssemblyStreamLength, new IntPtr(ptrSymbols), iSymbolLength, JitHelpers.GetObjectHandleOnStack(ref loadedAssembly));
}
}
-
+
return loadedAssembly;
}
-
+
// Custom AssemblyLoadContext implementations can override this
// method to perform custom processing and use one of the protected
// helpers above to load the assembly.
protected abstract Assembly Load(AssemblyName assemblyName);
-
+
// This method is invoked by the VM when using the host-provided assembly load context
// implementation.
private static Assembly Resolve(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
{
AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target);
-
+
return context.ResolveUsingLoad(assemblyName);
}
-
+
// This method is invoked by the VM to resolve an assembly reference using the Resolving event
// after trying assembly resolution via Load override and TPA load context without success.
private static Assembly ResolveUsingResolvingEvent(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
{
AssemblyLoadContext context = (AssemblyLoadContext)(GCHandle.FromIntPtr(gchManagedAssemblyLoadContext).Target);
-
+
// Invoke the AssemblyResolve event callbacks if wired up
return context.ResolveUsingEvent(assemblyName);
}
-
+
private Assembly GetFirstResolvedAssembly(AssemblyName assemblyName)
{
Assembly resolvedAssembly = null;
@@ -202,8 +206,8 @@ namespace System.Runtime.Loader
if (assemblyResolveHandler != null)
{
// Loop through the event subscribers and return the first non-null Assembly instance
- Delegate [] arrSubscribers = assemblyResolveHandler.GetInvocationList();
- for(int i = 0; i < arrSubscribers.Length; i++)
+ Delegate[] arrSubscribers = assemblyResolveHandler.GetInvocationList();
+ for (int i = 0; i < arrSubscribers.Length; i++)
{
resolvedAssembly = ((Func<AssemblyLoadContext, AssemblyName, Assembly>)arrSubscribers[i])(this, assemblyName);
if (resolvedAssembly != null)
@@ -212,7 +216,7 @@ namespace System.Runtime.Loader
}
}
}
-
+
return resolvedAssembly;
}
@@ -220,7 +224,7 @@ namespace System.Runtime.Loader
{
// Get the name of the loaded assembly
string loadedSimpleName = null;
-
+
// Derived type's Load implementation is expected to use one of the LoadFrom* methods to get the assembly
// which is a RuntimeAssembly instance. However, since Assembly type can be used build any other artifact (e.g. AssemblyBuilder),
// we need to check for RuntimeAssembly.
@@ -229,49 +233,48 @@ namespace System.Runtime.Loader
{
loadedSimpleName = rtLoadedAssembly.GetSimpleName();
}
-
+
// The simple names should match at the very least
if (String.IsNullOrEmpty(loadedSimpleName) || (!requestedSimpleName.Equals(loadedSimpleName, StringComparison.InvariantCultureIgnoreCase)))
- throw new InvalidOperationException(Environment.GetResourceString("Argument_CustomAssemblyLoadContextRequestedNameMismatch"));
-
+ throw new InvalidOperationException(SR.Argument_CustomAssemblyLoadContextRequestedNameMismatch);
+
return assembly;
-
}
-
+
private Assembly ResolveUsingLoad(AssemblyName assemblyName)
{
string simpleName = assemblyName.Name;
Assembly assembly = Load(assemblyName);
-
+
if (assembly != null)
{
assembly = ValidateAssemblyNameWithSimpleName(assembly, simpleName);
}
-
+
return assembly;
}
-
+
private Assembly ResolveUsingEvent(AssemblyName assemblyName)
{
string simpleName = assemblyName.Name;
-
+
// Invoke the AssemblyResolve event callbacks if wired up
Assembly assembly = GetFirstResolvedAssembly(assemblyName);
if (assembly != null)
{
assembly = ValidateAssemblyNameWithSimpleName(assembly, simpleName);
}
-
+
// Since attempt to resolve the assembly via Resolving event is the last option,
// throw an exception if we do not find any assembly.
if (assembly == null)
{
- throw new FileNotFoundException(Environment.GetResourceString("IO.FileLoad"), simpleName);
+ throw new FileNotFoundException(SR.IO_FileLoad, simpleName);
}
-
+
return assembly;
}
-
+
public Assembly LoadFromAssemblyName(AssemblyName assemblyName)
{
// Attempt to load the assembly, using the same ordering as static load, in the current load context.
@@ -294,23 +297,23 @@ namespace System.Runtime.Loader
}
if (unmanagedDllPath.Length == 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"), nameof(unmanagedDllPath));
+ throw new ArgumentException(SR.Argument_EmptyPath, nameof(unmanagedDllPath));
}
if (PathInternal.IsPartiallyQualified(unmanagedDllPath))
{
- throw new ArgumentException(Environment.GetResourceString("Argument_AbsolutePathRequired"), nameof(unmanagedDllPath));
+ throw new ArgumentException(SR.Argument_AbsolutePathRequired, nameof(unmanagedDllPath));
}
return InternalLoadUnmanagedDllFromPath(unmanagedDllPath);
}
-
+
// Custom AssemblyLoadContext implementations can override this
// method to perform the load of unmanaged native dll
// This function needs to return the HMODULE of the dll it loads
protected virtual IntPtr LoadUnmanagedDll(String unmanagedDllName)
{
//defer to default coreclr policy of loading unmanaged dll
- return IntPtr.Zero;
+ return IntPtr.Zero;
}
// This method is invoked by the VM when using the host-provided assembly load context
@@ -331,7 +334,7 @@ namespace System.Runtime.Loader
if (AssemblyLoadContext.CanUseAppPathAssemblyLoadContextInCurrentDomain())
{
// Synchronize access to initializing Default ALC
- lock(s_initLock)
+ lock (s_initLock)
{
if (s_DefaultAssemblyLoadContext == null)
{
@@ -340,16 +343,11 @@ namespace System.Runtime.Loader
}
}
}
-
+
return s_DefaultAssemblyLoadContext;
}
}
-
- // This call opens and closes the file, but does not add the
- // assembly to the domain.
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static internal extern AssemblyName nGetFileInformation(String s);
-
+
// Helper to return AssemblyName corresponding to the path of an IL assembly
public static AssemblyName GetAssemblyName(string assemblyPath)
{
@@ -358,14 +356,13 @@ namespace System.Runtime.Loader
throw new ArgumentNullException(nameof(assemblyPath));
}
- string fullPath = Path.GetFullPath(assemblyPath);
- return nGetFileInformation(fullPath);
+ return AssemblyName.GetAssemblyName(assemblyPath);
}
-
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern IntPtr GetLoadContextForAssembly(RuntimeAssembly assembly);
-
+
// Returns the load context in which the specified assembly has been loaded
public static AssemblyLoadContext GetLoadContext(Assembly assembly)
{
@@ -373,11 +370,11 @@ namespace System.Runtime.Loader
{
throw new ArgumentNullException(nameof(assembly));
}
-
+
AssemblyLoadContext loadContextForAssembly = null;
RuntimeAssembly rtAsm = assembly as RuntimeAssembly;
-
+
// We only support looking up load context for runtime assemblies.
if (rtAsm != null)
{
@@ -397,7 +394,7 @@ namespace System.Runtime.Loader
return loadContextForAssembly;
}
-
+
// Set the root directory path for profile optimization.
public void SetProfileOptimizationRoot(string directoryPath)
{
@@ -424,7 +421,7 @@ namespace System.Runtime.Loader
// Contains the reference to VM's representation of the AssemblyLoadContext
private IntPtr m_pNativeAssemblyLoadContext;
-
+
// Each AppDomain contains the reference to its AssemblyLoadContext instance, if one is
// specified by the host. By having the field as a static, we are
// making it an AppDomain-wide field.
@@ -434,36 +431,36 @@ namespace System.Runtime.Loader
private static readonly object s_initLock = new Object();
// Occurs when an Assembly is loaded
- public static event AssemblyLoadEventHandler AssemblyLoad
- {
- add { AppDomain.CurrentDomain.AssemblyLoad += value; }
- remove { AppDomain.CurrentDomain.AssemblyLoad -= value; }
+ public static event AssemblyLoadEventHandler AssemblyLoad
+ {
+ add { AppDomain.CurrentDomain.AssemblyLoad += value; }
+ remove { AppDomain.CurrentDomain.AssemblyLoad -= value; }
}
// Occurs when resolution of type fails
- public static event ResolveEventHandler TypeResolve
- {
- add { AppDomain.CurrentDomain.TypeResolve += value; }
- remove { AppDomain.CurrentDomain.TypeResolve -= value; }
+ public static event ResolveEventHandler TypeResolve
+ {
+ add { AppDomain.CurrentDomain.TypeResolve += value; }
+ remove { AppDomain.CurrentDomain.TypeResolve -= value; }
}
// Occurs when resolution of resource fails
- public static event ResolveEventHandler ResourceResolve
- {
- add { AppDomain.CurrentDomain.ResourceResolve += value; }
- remove { AppDomain.CurrentDomain.ResourceResolve -= value; }
- }
+ public static event ResolveEventHandler ResourceResolve
+ {
+ add { AppDomain.CurrentDomain.ResourceResolve += value; }
+ remove { AppDomain.CurrentDomain.ResourceResolve -= value; }
+ }
// Occurs when resolution of assembly fails
// This event is fired after resolve events of AssemblyLoadContext fails
public static event ResolveEventHandler AssemblyResolve
{
- add { AppDomain.CurrentDomain.AssemblyResolve += value; }
- remove { AppDomain.CurrentDomain.AssemblyResolve -= value; }
+ add { AppDomain.CurrentDomain.AssemblyResolve += value; }
+ remove { AppDomain.CurrentDomain.AssemblyResolve -= value; }
}
}
- class AppPathAssemblyLoadContext : AssemblyLoadContext
+ internal class AppPathAssemblyLoadContext : AssemblyLoadContext
{
internal AppPathAssemblyLoadContext() : base(true)
{
diff --git a/src/mscorlib/src/System/Runtime/MemoryFailPoint.cs b/src/mscorlib/src/System/Runtime/MemoryFailPoint.cs
index 84b8ba9e1e..f9f87bc928 100644
--- a/src/mscorlib/src/System/Runtime/MemoryFailPoint.cs
+++ b/src/mscorlib/src/System/Runtime/MemoryFailPoint.cs
@@ -139,7 +139,7 @@ namespace System.Runtime
// count of "reserved" memory, and decrement this in Dispose and
// in the critical finalizer. See
// SharedStatics.MemoryFailPointReservedMemory
-
+
private ulong _reservedMemory; // The size of this request (from user)
private bool _mustSubtractReservation; // Did we add data to SharedStatics?
@@ -155,7 +155,7 @@ namespace System.Runtime
public MemoryFailPoint(int sizeInMegabytes)
{
if (sizeInMegabytes <= 0)
- throw new ArgumentOutOfRangeException(nameof(sizeInMegabytes), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(sizeInMegabytes), SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
#if !FEATURE_PAL // Remove this when CheckForAvailableMemory is able to provide legitimate estimates
@@ -168,9 +168,9 @@ namespace System.Runtime
// size, not the amount of memory the user wants to allocate.
// Consider correcting this to reflect free memory within the GC
// heap, and to check both the normal & large object heaps.
- ulong segmentSize = (ulong) (Math.Ceiling((double)size / GCSegmentSize) * GCSegmentSize);
+ ulong segmentSize = (ulong)(Math.Ceiling((double)size / GCSegmentSize) * GCSegmentSize);
if (segmentSize >= TopOfMemory)
- throw new InsufficientMemoryException(Environment.GetResourceString("InsufficientMemory_MemFailPoint_TooBig"));
+ throw new InsufficientMemoryException(SR.InsufficientMemory_MemFailPoint_TooBig);
ulong requestedSizeRounded = (ulong)(Math.Ceiling((double)sizeInMegabytes / MemoryCheckGranularity) * MemoryCheckGranularity);
//re-convert into bytes
@@ -191,7 +191,8 @@ namespace System.Runtime
// GC.WaitForPendingFinalizers, noting that this method uses a CER
// so it can't be aborted, and we have a critical finalizer. It
// would probably work, but do some thinking first.)
- for(int stage = 0; stage < 3; stage++) {
+ for (int stage = 0; stage < 3; stage++)
+ {
CheckForAvailableMemory(out availPageFile, out totalAddressSpaceFree);
// If we have enough room, then skip some stages.
@@ -206,99 +207,109 @@ namespace System.Runtime
// Ensure our cached amount of free address space is not stale.
long now = Environment.TickCount; // Handle wraparound.
if ((now > LastTimeCheckingAddressSpace + CheckThreshold || now < LastTimeCheckingAddressSpace) ||
- LastKnownFreeAddressSpace < (long) segmentSize) {
+ LastKnownFreeAddressSpace < (long)segmentSize)
+ {
CheckForFreeAddressSpace(segmentSize, false);
}
- bool needContiguousVASpace = (ulong) LastKnownFreeAddressSpace < segmentSize;
+ bool needContiguousVASpace = (ulong)LastKnownFreeAddressSpace < segmentSize;
BCLDebug.Trace("MEMORYFAILPOINT", "MemoryFailPoint: Checking for {0} MB, for allocation size of {1} MB, stage {9}. Need page file? {2} Need Address Space? {3} Need Contiguous address space? {4} Avail page file: {5} MB Total free VA space: {6} MB Contiguous free address space (found): {7} MB Space reserved via process's MemoryFailPoints: {8} MB",
- segmentSize >> 20, sizeInMegabytes, needPageFile,
- needAddressSpace, needContiguousVASpace,
- availPageFile >> 20, totalAddressSpaceFree >> 20,
+ segmentSize >> 20, sizeInMegabytes, needPageFile,
+ needAddressSpace, needContiguousVASpace,
+ availPageFile >> 20, totalAddressSpaceFree >> 20,
LastKnownFreeAddressSpace >> 20, reserved, stage);
if (!needPageFile && !needAddressSpace && !needContiguousVASpace)
break;
- switch(stage) {
- case 0:
- // The GC will release empty segments to the OS. This will
- // relieve us from having to guess whether there's
- // enough memory in either GC heap, and whether
- // internal fragmentation will prevent those
- // allocations from succeeding.
- GC.Collect();
- continue;
-
- case 1:
- // Do this step if and only if the page file is too small.
- if (!needPageFile)
+ switch (stage)
+ {
+ case 0:
+ // The GC will release empty segments to the OS. This will
+ // relieve us from having to guess whether there's
+ // enough memory in either GC heap, and whether
+ // internal fragmentation will prevent those
+ // allocations from succeeding.
+ GC.Collect();
continue;
- // Attempt to grow the OS's page file. Note that we ignore
- // any allocation routines from the host intentionally.
- RuntimeHelpers.PrepareConstrainedRegions();
- try {
- }
- finally {
- // This shouldn't overflow due to the if clauses above.
- UIntPtr numBytes = new UIntPtr(segmentSize);
- unsafe {
- void * pMemory = Win32Native.VirtualAlloc(null, numBytes, Win32Native.MEM_COMMIT, Win32Native.PAGE_READWRITE);
- if (pMemory != null) {
- bool r = Win32Native.VirtualFree(pMemory, UIntPtr.Zero, Win32Native.MEM_RELEASE);
- if (!r)
- __Error.WinIOError();
+ case 1:
+ // Do this step if and only if the page file is too small.
+ if (!needPageFile)
+ continue;
+
+ // Attempt to grow the OS's page file. Note that we ignore
+ // any allocation routines from the host intentionally.
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ }
+ finally
+ {
+ // This shouldn't overflow due to the if clauses above.
+ UIntPtr numBytes = new UIntPtr(segmentSize);
+ unsafe
+ {
+ void* pMemory = Win32Native.VirtualAlloc(null, numBytes, Win32Native.MEM_COMMIT, Win32Native.PAGE_READWRITE);
+ if (pMemory != null)
+ {
+ bool r = Win32Native.VirtualFree(pMemory, UIntPtr.Zero, Win32Native.MEM_RELEASE);
+ if (!r)
+ __Error.WinIOError();
+ }
}
}
- }
- continue;
-
- case 2:
- // The call to CheckForAvailableMemory above updated our
- // state.
- if (needPageFile || needAddressSpace) {
- InsufficientMemoryException e = new InsufficientMemoryException(Environment.GetResourceString("InsufficientMemory_MemFailPoint"));
+ continue;
+
+ case 2:
+ // The call to CheckForAvailableMemory above updated our
+ // state.
+ if (needPageFile || needAddressSpace)
+ {
+ InsufficientMemoryException e = new InsufficientMemoryException(SR.InsufficientMemory_MemFailPoint);
#if _DEBUG
- e.Data["MemFailPointState"] = new MemoryFailPointState(sizeInMegabytes, segmentSize,
- needPageFile, needAddressSpace, needContiguousVASpace,
- availPageFile >> 20, totalAddressSpaceFree >> 20,
- LastKnownFreeAddressSpace >> 20, reserved);
+ e.Data["MemFailPointState"] = new MemoryFailPointState(sizeInMegabytes, segmentSize,
+ needPageFile, needAddressSpace, needContiguousVASpace,
+ availPageFile >> 20, totalAddressSpaceFree >> 20,
+ LastKnownFreeAddressSpace >> 20, reserved);
#endif
- throw e;
- }
+ throw e;
+ }
- if (needContiguousVASpace) {
- InsufficientMemoryException e = new InsufficientMemoryException(Environment.GetResourceString("InsufficientMemory_MemFailPoint_VAFrag"));
+ if (needContiguousVASpace)
+ {
+ InsufficientMemoryException e = new InsufficientMemoryException(SR.InsufficientMemory_MemFailPoint_VAFrag);
#if _DEBUG
- e.Data["MemFailPointState"] = new MemoryFailPointState(sizeInMegabytes, segmentSize,
- needPageFile, needAddressSpace, needContiguousVASpace,
- availPageFile >> 20, totalAddressSpaceFree >> 20,
- LastKnownFreeAddressSpace >> 20, reserved);
+ e.Data["MemFailPointState"] = new MemoryFailPointState(sizeInMegabytes, segmentSize,
+ needPageFile, needAddressSpace, needContiguousVASpace,
+ availPageFile >> 20, totalAddressSpaceFree >> 20,
+ LastKnownFreeAddressSpace >> 20, reserved);
#endif
- throw e;
- }
+ throw e;
+ }
- break;
+ break;
- default:
- Debug.Assert(false, "Fell through switch statement!");
- break;
+ default:
+ Debug.Assert(false, "Fell through switch statement!");
+ break;
}
}
// Success - we have enough room the last time we checked.
// Now update our shared state in a somewhat atomic fashion
// and handle a simple race condition with other MemoryFailPoint instances.
- AddToLastKnownFreeAddressSpace(-((long) size));
+ AddToLastKnownFreeAddressSpace(-((long)size));
if (LastKnownFreeAddressSpace < 0)
CheckForFreeAddressSpace(segmentSize, true);
-
+
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
}
- finally {
- SharedStatics.AddMemoryFailPointReservation((long) size);
+ finally
+ {
+ SharedStatics.AddMemoryFailPointReservation((long)size);
_mustSubtractReservation = true;
}
#endif
@@ -334,11 +345,11 @@ namespace System.Runtime
// this will hurt, as long as we never increment this number in
// the Dispose method. If we do an extra bit of checking every
// once in a while, but we avoid taking a lock, we may win.
- LastKnownFreeAddressSpace = (long) freeSpaceAfterGCHeap;
+ LastKnownFreeAddressSpace = (long)freeSpaceAfterGCHeap;
LastTimeCheckingAddressSpace = Environment.TickCount;
if (freeSpaceAfterGCHeap < size && shouldThrow)
- throw new InsufficientMemoryException(Environment.GetResourceString("InsufficientMemory_MemFailPoint_VAFrag"));
+ throw new InsufficientMemoryException(SR.InsufficientMemory_MemFailPoint_VAFrag);
return freeSpaceAfterGCHeap >= size;
}
@@ -346,28 +357,30 @@ namespace System.Runtime
// of pages. If we didn't have enough address space, we still return
// a positive value < size, to help potentially avoid the overhead of
// this check if we use a MemoryFailPoint with a smaller size next.
- private static unsafe ulong MemFreeAfterAddress(void * address, ulong size)
+ private static unsafe ulong MemFreeAfterAddress(void* address, ulong size)
{
if (size >= TopOfMemory)
return 0;
ulong largestFreeRegion = 0;
Win32Native.MEMORY_BASIC_INFORMATION memInfo = new Win32Native.MEMORY_BASIC_INFORMATION();
- UIntPtr sizeOfMemInfo = (UIntPtr) Marshal.SizeOf(memInfo);
-
- while (((ulong)address) + size < TopOfMemory) {
+ UIntPtr sizeOfMemInfo = (UIntPtr)Marshal.SizeOf(memInfo);
+
+ while (((ulong)address) + size < TopOfMemory)
+ {
UIntPtr r = Win32Native.VirtualQuery(address, ref memInfo, sizeOfMemInfo);
if (r == UIntPtr.Zero)
__Error.WinIOError();
ulong regionSize = memInfo.RegionSize.ToUInt64();
- if (memInfo.State == Win32Native.MEM_FREE) {
+ if (memInfo.State == Win32Native.MEM_FREE)
+ {
if (regionSize >= size)
return regionSize;
else
largestFreeRegion = Math.Max(largestFreeRegion, regionSize);
}
- address = (void *) ((ulong) address + regionSize);
+ address = (void*)((ulong)address + regionSize);
}
return largestFreeRegion;
}
@@ -398,11 +411,14 @@ namespace System.Runtime
// This is just bookkeeping to ensure multiple threads can really
// get enough memory, and this does not actually reserve memory
// within the GC heap.
- if (_mustSubtractReservation) {
+ if (_mustSubtractReservation)
+ {
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
}
- finally {
+ finally
+ {
SharedStatics.AddMemoryFailPointReservation(-((long)_reservedMemory));
_mustSubtractReservation = false;
}
@@ -465,9 +481,9 @@ namespace System.Runtime
public override String ToString()
{
return String.Format(System.Globalization.CultureInfo.InvariantCulture, "MemoryFailPoint detected insufficient memory to guarantee an operation could complete. Checked for {0} MB, for allocation size of {1} MB. Need page file? {2} Need Address Space? {3} Need Contiguous address space? {4} Avail page file: {5} MB Total free VA space: {6} MB Contiguous free address space (found): {7} MB Space reserved by process's MemoryFailPoints: {8} MB",
- _segmentSize >> 20, _allocationSizeInMB, _needPageFile,
- _needAddressSpace, _needContiguousVASpace,
- _availPageFile >> 20, _totalFreeAddressSpace >> 20,
+ _segmentSize >> 20, _allocationSizeInMB, _needPageFile,
+ _needAddressSpace, _needContiguousVASpace,
+ _availPageFile >> 20, _totalFreeAddressSpace >> 20,
_lastKnownFreeAddressSpace >> 20, _reservedMem);
}
}
diff --git a/src/mscorlib/src/System/Runtime/Reliability/PrePrepareMethodAttribute.cs b/src/mscorlib/src/System/Runtime/Reliability/PrePrepareMethodAttribute.cs
index 67c934d034..6594562b97 100644
--- a/src/mscorlib/src/System/Runtime/Reliability/PrePrepareMethodAttribute.cs
+++ b/src/mscorlib/src/System/Runtime/Reliability/PrePrepareMethodAttribute.cs
@@ -16,11 +16,12 @@
**
**
===========================================================*/
+
+using System;
+using System.Runtime.InteropServices;
+
namespace System.Runtime.ConstrainedExecution
{
- using System;
- using System.Runtime.InteropServices;
-
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
internal sealed class PrePrepareMethodAttribute : Attribute
diff --git a/src/mscorlib/src/System/Runtime/Reliability/ReliabilityContractAttribute.cs b/src/mscorlib/src/System/Runtime/Reliability/ReliabilityContractAttribute.cs
deleted file mode 100644
index 4a14e5733c..0000000000
--- a/src/mscorlib/src/System/Runtime/Reliability/ReliabilityContractAttribute.cs
+++ /dev/null
@@ -1,67 +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.
-
-//
-/*============================================================
-**
-**
-**
-** Purpose: Defines a publically documentable contract for
-** reliability between a method and its callers, expressing
-** what state will remain consistent in the presence of
-** failures (ie async exceptions like thread abort) and whether
-** the method needs to be called from within a CER.
-**
-**
-===========================================================*/
-
-namespace System.Runtime.ConstrainedExecution {
- using System.Runtime.InteropServices;
- using System;
-
- // **************************************************************************************************************************
- //
- // Note that if you change either of the enums below or the constructors, fields or properties of the custom attribute itself
- // you must also change the logic and definitions in vm\ConstrainedExecutionRegion.cpp to match.
- //
- // **************************************************************************************************************************
-
- [Serializable]
- public enum Consistency : int
- {
- MayCorruptProcess = 0,
- MayCorruptAppDomain = 1,
- MayCorruptInstance = 2,
- WillNotCorruptState = 3,
- }
-
- [Serializable]
- public enum Cer : int
- {
- None = 0,
- MayFail = 1, // Might fail, but the method will say it failed
- Success = 2,
- }
-
- [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Interface /* | AttributeTargets.Delegate*/, Inherited = false)]
- public sealed class ReliabilityContractAttribute : Attribute
- {
- private Consistency _consistency;
- private Cer _cer;
-
- public ReliabilityContractAttribute(Consistency consistencyGuarantee, Cer cer)
- {
- _consistency = consistencyGuarantee;
- _cer = cer;
- }
-
- public Consistency ConsistencyGuarantee {
- get { return _consistency; }
- }
-
- public Cer Cer {
- get { return _cer; }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/Remoting/ObjectHandle.cs b/src/mscorlib/src/System/Runtime/Remoting/ObjectHandle.cs
index ed3444e15d..e76882d6df 100644
--- a/src/mscorlib/src/System/Runtime/Remoting/ObjectHandle.cs
+++ b/src/mscorlib/src/System/Runtime/Remoting/ObjectHandle.cs
@@ -14,15 +14,15 @@
**
===========================================================*/
+using System;
+using System.Runtime.InteropServices;
+
namespace System.Runtime.Remoting
{
- using System;
- using System.Runtime.InteropServices;
-
- public class ObjectHandle
+ public class ObjectHandle
{
private Object WrappedObject;
-
+
private ObjectHandle()
{
}
diff --git a/src/mscorlib/src/System/Runtime/RuntimeImports.cs b/src/mscorlib/src/System/Runtime/RuntimeImports.cs
new file mode 100644
index 0000000000..16d41d3951
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/RuntimeImports.cs
@@ -0,0 +1,35 @@
+// 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.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+#if BIT64
+using nuint = System.UInt64;
+#else
+ using nuint = System.UInt32;
+#endif
+
+namespace System.Runtime
+{
+ public class RuntimeImports
+ {
+ // Non-inlinable wrapper around the QCall that avoids poluting the fast path
+ // with P/Invoke prolog/epilog.
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ internal unsafe static void RhZeroMemory(ref byte b, nuint byteLength)
+ {
+ fixed (byte* bytePointer = &b)
+ {
+ RhZeroMemory(bytePointer, byteLength);
+ }
+ }
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ extern private unsafe static void RhZeroMemory(byte* b, nuint byteLength);
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern unsafe static void RhBulkMoveWithWriteBarrier(ref byte destination, ref byte source, nuint byteCount);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs b/src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs
index 27f7ecf9d2..52e748db89 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/FormatterConverter.cs
@@ -12,42 +12,53 @@
**
**
============================================================*/
-namespace System.Runtime.Serialization {
- using System;
- using System.Globalization;
- using System.Diagnostics.Contracts;
- internal class FormatterConverter : IFormatterConverter {
+using System;
+using System.Globalization;
+using System.Diagnostics.Contracts;
- public FormatterConverter() {
+namespace System.Runtime.Serialization
+{
+ internal class FormatterConverter : IFormatterConverter
+ {
+ public FormatterConverter()
+ {
}
- public Object Convert(Object value, Type type) {
- if (value==null) {
+ public Object Convert(Object value, Type type)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ChangeType(value, type, CultureInfo.InvariantCulture);
}
- public Object Convert(Object value, TypeCode typeCode) {
- if (value==null) {
+ public Object Convert(Object value, TypeCode typeCode)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ChangeType(value, typeCode, CultureInfo.InvariantCulture);
}
- public bool ToBoolean(Object value) {
- if (value==null) {
+ public bool ToBoolean(Object value)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToBoolean(value, CultureInfo.InvariantCulture);
}
- public char ToChar(Object value) {
- if (value==null) {
+ public char ToChar(Object value)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
@@ -55,24 +66,30 @@ namespace System.Runtime.Serialization {
}
[CLSCompliant(false)]
- public sbyte ToSByte(Object value) {
- if (value==null) {
+ public sbyte ToSByte(Object value)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToSByte(value, CultureInfo.InvariantCulture);
}
- public byte ToByte(Object value) {
- if (value==null) {
+ public byte ToByte(Object value)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToByte(value, CultureInfo.InvariantCulture);
}
- public short ToInt16(Object value) {
- if (value==null) {
+ public short ToInt16(Object value)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
@@ -80,16 +97,20 @@ namespace System.Runtime.Serialization {
}
[CLSCompliant(false)]
- public ushort ToUInt16(Object value) {
- if (value==null) {
+ public ushort ToUInt16(Object value)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToUInt16(value, CultureInfo.InvariantCulture);
}
- public int ToInt32(Object value) {
- if (value==null) {
+ public int ToInt32(Object value)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
@@ -97,16 +118,20 @@ namespace System.Runtime.Serialization {
}
[CLSCompliant(false)]
- public uint ToUInt32(Object value) {
- if (value==null) {
+ public uint ToUInt32(Object value)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToUInt32(value, CultureInfo.InvariantCulture);
}
- public long ToInt64(Object value) {
- if (value==null) {
+ public long ToInt64(Object value)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
@@ -114,48 +139,60 @@ namespace System.Runtime.Serialization {
}
[CLSCompliant(false)]
- public ulong ToUInt64(Object value) {
- if (value==null) {
+ public ulong ToUInt64(Object value)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToUInt64(value, CultureInfo.InvariantCulture);
- }
+ }
- public float ToSingle(Object value) {
- if (value==null) {
+ public float ToSingle(Object value)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToSingle(value, CultureInfo.InvariantCulture);
}
- public double ToDouble(Object value) {
- if (value==null) {
+ public double ToDouble(Object value)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToDouble(value, CultureInfo.InvariantCulture);
}
- public Decimal ToDecimal(Object value) {
- if (value==null) {
+ public Decimal ToDecimal(Object value)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToDecimal(value, CultureInfo.InvariantCulture);
}
- public DateTime ToDateTime(Object value) {
- if (value==null) {
+ public DateTime ToDateTime(Object value)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
return System.Convert.ToDateTime(value, CultureInfo.InvariantCulture);
}
- public String ToString(Object value) {
- if (value==null) {
+ public String ToString(Object value)
+ {
+ if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
@@ -163,4 +200,4 @@ namespace System.Runtime.Serialization {
}
}
}
-
+
diff --git a/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs b/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs
index c3f9eb4452..18139324a3 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs
@@ -11,25 +11,28 @@
**
**
============================================================*/
-namespace System.Runtime.Serialization {
-
- using System;
- using System.Reflection;
- using System.Collections;
- using System.Collections.Generic;
- using System.Security;
- using System.Runtime.Remoting;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Threading;
- using System.IO;
- using System.Text;
- using System.Globalization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- public static class FormatterServices {
-
+using System;
+using System.Reflection;
+using System.Collections;
+using System.Collections.Generic;
+using System.Security;
+using System.Runtime.Remoting;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+using System.Threading;
+using System.IO;
+using System.Text;
+using System.Globalization;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System.Runtime.Serialization
+{
+ // This class duplicates a class on CoreFX. We are keeping it here -- just this one method --
+ // as it was widely invoked by reflection to workaround it being missing in .NET Core 1.0
+ internal static class FormatterServices
+ {
// Gets a new instance of the object. The entire object is initalized to 0 and no
// constructors have been run. **THIS MEANS THAT THE OBJECT MAY NOT BE IN A STATE
// CONSISTENT WITH ITS INTERNAL REQUIREMENTS** This method should only be used for
@@ -37,42 +40,24 @@ namespace System.Runtime.Serialization {
// will not create an unitialized string because it is non-sensical to create an empty
// instance of an immutable type.
//
- public static Object GetUninitializedObject(Type type) {
- if ((object)type == null) {
+ public static Object GetUninitializedObject(Type type)
+ {
+ if ((object)type == null)
+ {
throw new ArgumentNullException(nameof(type));
}
Contract.EndContractBlock();
-
- if (!(type is RuntimeType)) {
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidType", type.ToString()));
+
+ if (!(type is RuntimeType))
+ {
+ throw new SerializationException(SR.Format(SR.Serialization_InvalidType, type.ToString()));
}
return nativeGetUninitializedObject((RuntimeType)type);
}
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern Object nativeGetUninitializedObject(RuntimeType type);
- private static Binder s_binder = Type.DefaultBinder;
-
- /*============================LoadAssemblyFromString============================
- **Action: Loads an assembly from a given string. The current assembly loading story
- ** is quite confusing. If the assembly is in the fusion cache, we can load it
- ** using the stringized-name which we transmitted over the wire. If that fails,
- ** we try for a lookup of the assembly using the simple name which is the first
- ** part of the assembly name. If we can't find it that way, we'll return null
- ** as our failure result.
- **Returns: The loaded assembly or null if it can't be found.
- **Arguments: assemblyName -- The stringized assembly name.
- **Exceptions: None
- ==============================================================================*/
- internal static Assembly LoadAssemblyFromString(String assemblyName) {
- //
- // Try using the stringized assembly name to load from the fusion cache.
- //
- BCLDebug.Trace("SER", "[LoadAssemblyFromString]Looking for assembly: ", assemblyName);
- Assembly found = Assembly.Load(assemblyName);
- return found;
- }
}
}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/IDeserializationCallback.cs b/src/mscorlib/src/System/Runtime/Serialization/IDeserializationCallback.cs
deleted file mode 100644
index 2911a4016e..0000000000
--- a/src/mscorlib/src/System/Runtime/Serialization/IDeserializationCallback.cs
+++ /dev/null
@@ -1,22 +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.
-
-/*============================================================
-**
-** Interface: IDeserializationEventListener
-**
-**
-** Purpose: Implemented by any class that wants to indicate that
-** it wishes to receive deserialization events.
-**
-**
-===========================================================*/
-namespace System.Runtime.Serialization {
- using System;
-
- // Interface does not need to be marked with the serializable attribute
- public interface IDeserializationCallback {
- void OnDeserialization(Object sender);
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/IFormatterConverter.cs b/src/mscorlib/src/System/Runtime/Serialization/IFormatterConverter.cs
deleted file mode 100644
index 0be0db9acd..0000000000
--- a/src/mscorlib/src/System/Runtime/Serialization/IFormatterConverter.cs
+++ /dev/null
@@ -1,39 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose: The interface provides the connection between an
-** instance of SerializationInfo and the formatter-provided
-** class which knows how to parse the data inside the
-** SerializationInfo.
-**
-**
-============================================================*/
-namespace System.Runtime.Serialization {
- using System;
-
- [CLSCompliant(false)]
- public interface IFormatterConverter {
- Object Convert(Object value, Type type);
- Object Convert(Object value, TypeCode typeCode);
- bool ToBoolean(Object value);
- char ToChar(Object value);
- sbyte ToSByte(Object value);
- byte ToByte(Object value);
- short ToInt16(Object value);
- ushort ToUInt16(Object value);
- int ToInt32(Object value);
- uint ToUInt32(Object value);
- long ToInt64(Object value);
- ulong ToUInt64(Object value);
- float ToSingle(Object value);
- double ToDouble(Object value);
- Decimal ToDecimal(Object value);
- DateTime ToDateTime(Object value);
- String ToString(Object value);
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs b/src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs
deleted file mode 100644
index ef5ee6ade0..0000000000
--- a/src/mscorlib/src/System/Runtime/Serialization/IObjectReference.cs
+++ /dev/null
@@ -1,27 +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.
-
-/*============================================================
-**
-** Interface: IObjectReference
-**
-**
-** Purpose: Implemented by objects that are actually references
-** to a different object which can't be discovered until
-** this one is completely restored. During the fixup stage,
-** any object implementing IObjectReference is asked for it's
-** "real" object and that object is inserted into the graph.
-**
-**
-===========================================================*/
-namespace System.Runtime.Serialization {
-
- using System;
- // Interface does not need to be marked with the serializable attribute
- public interface IObjectReference {
- Object GetRealObject(StreamingContext context);
- }
-}
-
-
diff --git a/src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs b/src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs
deleted file mode 100644
index 816aa0484b..0000000000
--- a/src/mscorlib/src/System/Runtime/Serialization/ISerializable.cs
+++ /dev/null
@@ -1,30 +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.
-
-/*============================================================
-**
-** Interface: ISerializable
-**
-**
-** Purpose: Implemented by any object that needs to control its
-** own serialization.
-**
-**
-===========================================================*/
-
-namespace System.Runtime.Serialization {
- using System.Runtime.Remoting;
- using System.Runtime.Serialization;
- using System;
- using System.Reflection;
-
- public interface ISerializable {
- void GetObjectData(SerializationInfo info, StreamingContext context);
- }
-
-}
-
-
-
-
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs b/src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs
deleted file mode 100644
index 260e873bc7..0000000000
--- a/src/mscorlib/src/System/Runtime/Serialization/SafeSerializationManager.cs
+++ /dev/null
@@ -1,240 +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.Collections;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using System.Reflection;
-using System.Security;
-
-namespace System.Runtime.Serialization
-{
- //
- // #SafeSerialization
- //
- // Types which are serializable via the ISerializable interface have a problem when it comes to allowing
- // transparent subtypes which can allow themselves to serialize since the GetObjectData method is
- // SecurityCritical.
- //
- // For instance, System.Exception implements ISerializable, however it is also desirable to have
- // transparent exceptions with their own fields that need to be serialized. (For instance, in transparent
- // assemblies such as the DLR and F#, or even in partial trust application code). Since overriding
- // GetObjectData requires that the overriding method be security critical, this won't work directly.
- //
- // SafeSerializationManager solves this problem by allowing any partial trust code to contribute
- // individual chunks of serializable data to be included in the serialized version of the derived class.
- // These chunks are then deserialized back out of the serialized type and notified that they should
- // populate the fields of the deserialized object when serialization is complete. This allows partial
- // trust or transparent code to participate in serialization of an ISerializable type without having to
- // override GetObjectData or implement the ISerializable constructor.
- //
- // On the serialization side, SafeSerializationManager has an event SerializeObjectState which it will
- // fire in response to serialization in order to gather the units of serializable data that should be
- // stored with the rest of the object during serialization. Methods which respond to these events
- // create serializable objects which implement the ISafeSerializationData interface and add them to the
- // collection of other serialized data by calling AddSerializedState on the SafeSerializationEventArgs
- // passed into the event.
- //
- // By using an event rather than a virtual method on the base ISerializable object, we allow multiple
- // potentially untrusted subclasses to participate in serialization, without each one having to ensure
- // that it calls up to the base type in order for the whole system to work. (For instance Exception :
- // TrustedException : UntrustedException, in this scenario UntrustedException would be able to override
- // the virtual method an prevent TrustedException from ever seeing the method call, either accidentally
- // or maliciously).
- //
- // Further, by only allowing additions of new chunks of serialization state rather than exposing the
- // whole underlying list, we avoid exposing potentially sensitive serialized state to any of the
- // potentially untrusted subclasses.
- //
- // At deserialization time, SafeSerializationManager performs the reverse operation. It deserializes the
- // chunks of serialized state, and then notifies them that the object they belong to is deserialized by
- // calling their CompleteSerialization method. In repsonse to this call, the state objects populate the
- // fields of the object being deserialized with the state that they held.
- //
- // From a security perspective, the chunks of serialized state can only contain data that the specific
- // subclass itself had access to read (otherwise it wouldn't be able to populate the type with that
- // data), as opposed to having access to far more data in the SerializationInfo that GetObjectData uses.
- // Similarly, at deserialization time, the serialized state can only modify fields that the type itself
- // has access to (again, as opposed to the full SerializationInfo which could be modified).
- //
- // Individual types which wish to participate in safe serialization do so by containing an instance of a
- // SafeSerializationManager and exposing its serialization event. During GetObjectData, the
- // SafeSerializationManager is serialized just like any other field of the containing type. However, at
- // the end of serialization it is called back one last time to CompleteSerialization.
- //
- // In CompleteSerialization, if the SafeSerializationManager detects that it has extra chunks of
- // data to handle, it substitutes the root type being serialized (formerly the real type hosting the
- // SafeSerializationManager) with itself. This allows it to gain more control over the deserialization
- // process. It also saves away an extra bit of state in the serialization info indicating the real type
- // of object that should be recreated during deserialization.
- //
- // At this point the serialized state looks like this:
- // Data:
- // realSerializedData1
- // ...
- // realSerializedDataN
- // safeSerializationData -> this is the serialization data member of the parent type
- // m_serializedState -> list of saved serialized states from subclasses responding to the safe
- // serialization event
- // RealTypeSerializationName -> type which is using safe serialization
- // Type:
- // SafeSerializationManager
- //
- // That is, the serialized data claims to be of type SafeSerializationManager, however contains only the
- // data from the real object being serialized along with one bit of safe serialization metadata.
- //
- // At deserialization time, since the serialized data claims to be of type SafeSerializationManager, the
- // root object being created is an instance of the SafeSerializationManager class. However, it detects
- // that this isn't a real SafeSerializationManager (by looking for the real type field in the metadata),
- // and simply saves away the SerializationInfo and the real type being deserialized.
- //
- // Since SafeSerializationManager implements IObjectReference, the next step of deserialization is the
- // GetRealObject callback. This callback is the one responsible for getting the
- // SafeSerializationManager out of the way and instead creating an instance of the actual type which was
- // serialized.
- //
- // It does this by first creating an instance of the real type being deserialzed (saved away in the
- // deserialzation constructor), but not running any of its constructors. Instead, it walks the
- // inheritance hierarchy (moving toward the most derived type) looking for the last full trust type to
- // implement the standard ISerializable constructor before any type does not implement the constructor.
- // It is this last type's deserialization constructor which is then invoked, passing in the saved
- // SerializationInfo. Once the constructors are run, we return this object as the real deserialized
- // object.
- //
- // The reason that we do this walk is so that ISerializable types can protect themselves from malicious
- // input during deserialization by making their deserialization constructors unavailable to partial
- // trust code. By not requiring every type have a copy of this constructor, partial trust code can
- // participate in safe serialization and not be required to have access to the parent's constructor.
- //
- // It should be noted however, that this heuristic means that if a full trust type does derive from
- // a transparent or partial trust type using this safe serialization mechanism, that full trust type
- // will not have its constructor called. Further, the protection of not invoking partial trust
- // deserialization constructors only comes into play if SafeSerializationManager is in control of
- // deserialization, which means there must be at least one (even empty) safe serialization event
- // handler registered.
- //
- // Another interesting note is that at this point there are now two SafeSerializationManagers alive for
- // this deserialization. The first object is the one which is controlling the deserialization and was
- // created as the root object of the deserialization. The second one is the object which contains the
- // serialized data chunks and is a data member of the real object being deserialized. For this reason,
- // the data objects cannot be notified that the deserialization is complete during GetRealObject since
- // the ISafeSerializationData objects are not members of the active SafeSerializationManager instance.
- //
- // The next step is the OnDeserialized callback, which comes to SafeSerializableObject since it was
- // pretending to be the root object of the deserialization. It responds to this callback by calling
- // any existing OnDeserialized callback on the real type that was deserialized.
- //
- // The real type needs to call its data member SafeSerializationData object's CompleteDeserialization
- // method in response to the OnDeserialized call. This CompleteDeserialization call will then iterate
- // through the ISafeSerializationData objects calling each of their CompleteDeserialization methods so
- // that they can plug the nearly-complete object with their saved data.
- //
- // The reason for having a new ISafeSerializationData interface which is basically identical to
- // IDeserializationCallback is that IDeserializationCallback will be called on the stored data chunks
- // by the serialization code when they are deserialized, and that's not a desirable behavior.
- // Essentially, we need to change the meaning of the object parameter to mean "parent object which
- // participated in safe serialization", rather than "this object".
- //
- // Implementing safe serialization on an ISerialiable type is relatively straight forward. (For an
- // example, see System.Exception):
- //
- // 1. Include a data member of type SafeSerializationManager:
- //
- // private SafeSerializationManager m_safeSerializationManager;
- //
- // 2. Add a protected SerializeObjectState event, which passes through to the SafeSerializationManager:
- //
- // protected event EventHandler<SafeSerializationEventArgs> SerializeObjectState
- // {
- // add { m_safeSerializationManager.SerializeObjectState += value; }
- // remove { m_safeSerializationManager.SerializeObjectState -= value; }
- // }
- //
- // 3. Serialize the safe serialization object in GetObjectData, and call its CompleteSerialization method:
- //
- // {
- // info.AddValue("m_safeSerializationManager", m_safeSerializationManager, typeof(SafeSerializationManager));
- // m_safeSerializationManager.CompleteSerialization(this, info, context);
- // }
- //
- // 4. Add an OnDeserialized handler if one doesn't already exist, and call CompleteDeserialization in it:
- //
- // [OnDeserialized]
- // private void OnDeserialized(StreamingContext context)
- // {
- // m_safeSerializationManager.CompleteDeserialization(this);
- // }
- //
- // On the client side, using safe serialization is also pretty easy. For example:
- //
- // [Serializable]
- // public class TransparentException : Exception
- // {
- // [Serializable]
- // private struct TransparentExceptionState : ISafeSerializationData
- // {
- // public string m_extraData;
- //
- // void ISafeSerializationData.CompleteDeserialization(object obj)
- // {
- // TransparentException exception = obj as TransparentException;
- // exception.m_state = this;
- // }
- // }
- //
- // [NonSerialized]
- // private TransparentExceptionState m_state = new TransparentExceptionState();
- //
- // public TransparentException()
- // {
- // SerializeObjectState += delegate(object exception, SafeSerializationEventArgs eventArgs)
- // {
- // eventArgs.AddSerializedState(m_state);
- // };
- // }
- //
- // public string ExtraData
- // {
- // get { return m_state.m_extraData; }
- // set { m_state.m_extraData = value; }
- // }
- // }
- //
-
- // SafeSerializationEventArgs are provided to the delegates which do safe serialization. Each delegate
- // serializes its own state into an IDeserializationCallback instance which must, itself, be serializable.
- // These indivdiual states are then added to the SafeSerializationEventArgs in order to be saved away when
- // the original ISerializable type is serialized.
- public sealed class SafeSerializationEventArgs : EventArgs
- {
- private StreamingContext m_streamingContext;
- private List<object> m_serializedStates = new List<object>();
-
- internal SafeSerializationEventArgs() {}
-
- public void AddSerializedState(ISafeSerializationData serializedState)
- {
- if (serializedState == null)
- throw new ArgumentNullException(nameof(serializedState));
- if (!serializedState.GetType().IsSerializable)
- throw new ArgumentException(Environment.GetResourceString("Serialization_NonSerType", serializedState.GetType(), serializedState.GetType().Assembly.FullName));
-
- m_serializedStates.Add(serializedState);
- }
-
- public StreamingContext StreamingContext
- {
- get { return m_streamingContext; }
- }
- }
-
- // Interface to be supported by objects which are stored in safe serialization stores
- public interface ISafeSerializationData
- {
- // CompleteDeserialization is called when the object to which the extra serialized data was attached
- // has completed its deserialization, and now needs to be populated with the extra data stored in
- // this object.
- void CompleteDeserialization(object deserialized);
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationAttributes.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationAttributes.cs
deleted file mode 100644
index 38abffa66e..0000000000
--- a/src/mscorlib/src/System/Runtime/Serialization/SerializationAttributes.cs
+++ /dev/null
@@ -1,59 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose: Various Attributes for Serialization
-**
-**
-============================================================*/
-namespace System.Runtime.Serialization
-{
- using System;
- using System.Diagnostics.Contracts;
- using System.Reflection;
-
- [AttributeUsage(AttributeTargets.Field, Inherited=false)]
- public sealed class OptionalFieldAttribute : Attribute
- {
- int versionAdded = 1;
- public OptionalFieldAttribute() { }
-
- public int VersionAdded
- {
- get {
- return this.versionAdded;
- }
- set {
- if (value < 1)
- throw new ArgumentException(Environment.GetResourceString("Serialization_OptionalFieldVersionValue"));
- Contract.EndContractBlock();
- this.versionAdded = value;
- }
- }
- }
-
- [AttributeUsage(AttributeTargets.Method, Inherited=false)]
- public sealed class OnSerializingAttribute : Attribute
- {
- }
-
- [AttributeUsage(AttributeTargets.Method, Inherited=false)]
- public sealed class OnSerializedAttribute : Attribute
- {
- }
-
- [AttributeUsage(AttributeTargets.Method, Inherited=false)]
- public sealed class OnDeserializingAttribute : Attribute
- {
- }
-
- [AttributeUsage(AttributeTargets.Method, Inherited=false)]
- public sealed class OnDeserializedAttribute : Attribute
- {
- }
-
-}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationException.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationException.cs
deleted file mode 100644
index e9cb79b7af..0000000000
--- a/src/mscorlib/src/System/Runtime/Serialization/SerializationException.cs
+++ /dev/null
@@ -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.
-
-/*=============================================================================
-**
-**
-**
-** Purpose: Thrown when something goes wrong during serialization or
-** deserialization.
-**
-**
-=============================================================================*/
-
-namespace System.Runtime.Serialization {
-
- using System;
- using System.Runtime.Serialization;
-
- [Serializable]
- public class SerializationException : SystemException {
-
- private static String _nullMessage = Environment.GetResourceString("Arg_SerializationException");
-
- // Creates a new SerializationException with its message
- // string set to a default message.
- public SerializationException()
- : base(_nullMessage) {
- SetErrorCode(__HResults.COR_E_SERIALIZATION);
- }
-
- public SerializationException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_SERIALIZATION);
- }
-
- public SerializationException(String message, Exception innerException) : base (message, innerException) {
- SetErrorCode(__HResults.COR_E_SERIALIZATION);
- }
-
- protected SerializationException(SerializationInfo info, StreamingContext context) : base (info, context) {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs
index 45521f2397..7fc3ce27d9 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/SerializationInfo.cs
@@ -11,25 +11,25 @@
**
**
===========================================================*/
-namespace System.Runtime.Serialization
-{
- using System;
- using System.Collections.Generic;
- using System.Reflection;
- using System.Runtime.Remoting;
- using System.Globalization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Security;
- using System.Runtime.CompilerServices;
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Runtime.Remoting;
+using System.Globalization;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Security;
+using System.Runtime.CompilerServices;
+namespace System.Runtime.Serialization
+{
public sealed class SerializationInfo
{
private const int defaultSize = 4;
private const string s_mscorlibAssemblySimpleName = System.CoreLib.Name;
private const string s_mscorlibFileName = s_mscorlibAssemblySimpleName + ".dll";
-
+
// Even though we have a dictionary, we're still keeping all the arrays around for back-compat.
// Otherwise we may run into potentially breaking behaviors like GetEnumerator() not returning entries in the same order they were added.
internal String[] m_members;
@@ -94,7 +94,7 @@ namespace System.Runtime.Serialization
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
-
+
m_fullTypeName = value;
isFullTypeNameSetExplicit = true;
}
@@ -113,9 +113,9 @@ namespace System.Runtime.Serialization
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
- if (this.requireSameTokenInPartialTrust)
+ if (requireSameTokenInPartialTrust)
{
- DemandForUnsafeAssemblyNameAssignments(this.m_assemName, value);
+ DemandForUnsafeAssemblyNameAssignments(m_assemName, value);
}
m_assemName = value;
isAssemblyNameSetExplicit = true;
@@ -130,7 +130,7 @@ namespace System.Runtime.Serialization
}
Contract.EndContractBlock();
- if (this.requireSameTokenInPartialTrust)
+ if (requireSameTokenInPartialTrust)
{
DemandForUnsafeAssemblyNameAssignments(this.ObjectType.Assembly.FullName, type.Assembly.FullName);
}
@@ -331,7 +331,7 @@ namespace System.Runtime.Serialization
if (m_nameToIndex.ContainsKey(name))
{
BCLDebug.Trace("SER", "[SerializationInfo.AddValue]Tried to add ", name, " twice to the SI.");
- throw new SerializationException(Environment.GetResourceString("Serialization_SameNameTwice"));
+ throw new SerializationException(SR.Serialization_SameNameTwice);
}
m_nameToIndex.Add(name, m_currMember);
@@ -382,7 +382,6 @@ namespace System.Runtime.Serialization
m_data[index] = value;
m_types[index] = type;
}
-
}
private int FindElement(String name)
@@ -416,7 +415,7 @@ namespace System.Runtime.Serialization
int index = FindElement(name);
if (index == -1)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_NotFound", name));
+ throw new SerializationException(SR.Format(SR.Serialization_NotFound, name));
}
Debug.Assert(index < m_data.Length, "[SerializationInfo.GetElement]index<m_data.Length");
@@ -451,7 +450,6 @@ namespace System.Runtime.Serialization
public Object GetValue(String name, Type type)
{
-
if ((object)type == null)
{
throw new ArgumentNullException(nameof(type));
@@ -460,7 +458,7 @@ namespace System.Runtime.Serialization
RuntimeType rt = type as RuntimeType;
if (rt == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeType);
Type foundType;
Object value;
@@ -698,6 +696,5 @@ namespace System.Runtime.Serialization
}
return m_converter.ToString(value);
}
-
}
}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs b/src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs
deleted file mode 100644
index 0858dfc19f..0000000000
--- a/src/mscorlib/src/System/Runtime/Serialization/SerializationInfoEnumerator.cs
+++ /dev/null
@@ -1,145 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose: A formatter-friendly mechanism for walking all of
-** the data in a SerializationInfo. Follows the IEnumerator
-** mechanism from Collections.
-**
-**
-============================================================*/
-namespace System.Runtime.Serialization {
- using System;
- using System.Diagnostics;
- using System.Collections;
- using System.Diagnostics.Contracts;
-
- //
- // The tuple returned by SerializationInfoEnumerator.Current.
- //
- public struct SerializationEntry {
- private Type m_type;
- private Object m_value;
- private String m_name;
-
- public Object Value {
- get {
- return m_value;
- }
- }
-
- public String Name {
- get {
- return m_name;
- }
- }
-
- public Type ObjectType {
- get {
- return m_type;
- }
- }
-
- internal SerializationEntry(String entryName, Object entryValue, Type entryType) {
- m_value = entryValue;
- m_name = entryName;
- m_type = entryType;
- }
- }
-
- //
- // A simple enumerator over the values stored in the SerializationInfo.
- // This does not snapshot the values, it just keeps pointers to the
- // member variables of the SerializationInfo that created it.
- //
- public sealed class SerializationInfoEnumerator : IEnumerator {
- String[] m_members;
- Object[] m_data;
- Type[] m_types;
- int m_numItems;
- int m_currItem;
- bool m_current;
-
- internal SerializationInfoEnumerator(String[] members, Object[] info, Type[] types, int numItems) {
- Debug.Assert(members!=null, "[SerializationInfoEnumerator.ctor]members!=null");
- Debug.Assert(info!=null, "[SerializationInfoEnumerator.ctor]info!=null");
- Debug.Assert(types!=null, "[SerializationInfoEnumerator.ctor]types!=null");
- Debug.Assert(numItems>=0, "[SerializationInfoEnumerator.ctor]numItems>=0");
- Debug.Assert(members.Length>=numItems, "[SerializationInfoEnumerator.ctor]members.Length>=numItems");
- Debug.Assert(info.Length>=numItems, "[SerializationInfoEnumerator.ctor]info.Length>=numItems");
- Debug.Assert(types.Length>=numItems, "[SerializationInfoEnumerator.ctor]types.Length>=numItems");
-
- m_members = members;
- m_data = info;
- m_types = types;
- //The MoveNext semantic is much easier if we enforce that [0..m_numItems] are valid entries
- //in the enumerator, hence we subtract 1.
- m_numItems = numItems-1;
- m_currItem = -1;
- m_current = false;
- }
-
- public bool MoveNext() {
- if (m_currItem<m_numItems) {
- m_currItem++;
- m_current = true;
- } else {
- m_current = false;
- }
- return m_current;
- }
-
- /// <internalonly/>
- Object IEnumerator.Current { //Actually returns a SerializationEntry
- get {
- if (m_current==false) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
- }
- return (Object)(new SerializationEntry(m_members[m_currItem], m_data[m_currItem], m_types[m_currItem]));
- }
- }
-
- public SerializationEntry Current { //Actually returns a SerializationEntry
- get {
- if (m_current==false) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
- }
- return (new SerializationEntry(m_members[m_currItem], m_data[m_currItem], m_types[m_currItem]));
- }
- }
-
- public void Reset() {
- m_currItem = -1;
- m_current = false;
- }
-
- public String Name {
- get {
- if (m_current==false) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
- }
- return m_members[m_currItem];
- }
- }
- public Object Value {
- get {
- if (m_current==false) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
- }
- return m_data[m_currItem];
- }
- }
- public Type ObjectType {
- get {
- if (m_current==false) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumOpCantHappen"));
- }
- return m_types[m_currItem];
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/Serialization/StreamingContext.cs b/src/mscorlib/src/System/Runtime/Serialization/StreamingContext.cs
deleted file mode 100644
index c01a3edc4f..0000000000
--- a/src/mscorlib/src/System/Runtime/Serialization/StreamingContext.cs
+++ /dev/null
@@ -1,72 +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.
-
-/*============================================================
-**
-** ValueType: StreamingContext
-**
-**
-** Purpose: A value type indicating the source or destination of our streaming.
-**
-**
-===========================================================*/
-namespace System.Runtime.Serialization {
-
- using System.Runtime.Remoting;
- using System;
- [Serializable]
- public struct StreamingContext {
- internal Object m_additionalContext;
- internal StreamingContextStates m_state;
-
- public StreamingContext(StreamingContextStates state)
- : this (state, null) {
- }
-
- public StreamingContext(StreamingContextStates state, Object additional) {
- m_state = state;
- m_additionalContext = additional;
- }
-
- public Object Context {
- get { return m_additionalContext; }
- }
-
- public override bool Equals(Object obj) {
- if (!(obj is StreamingContext)) {
- return false;
- }
- if (((StreamingContext)obj).m_additionalContext == m_additionalContext &&
- ((StreamingContext)obj).m_state == m_state) {
- return true;
- }
- return false;
- }
-
- public override int GetHashCode() {
- return (int)m_state;
- }
-
- public StreamingContextStates State {
- get { return m_state; }
- }
- }
-
- // **********************************************************
- // Keep these in sync with the version in vm\runtimehandles.h
- // **********************************************************
-[Serializable]
-[Flags]
- public enum StreamingContextStates {
- CrossProcess=0x01,
- CrossMachine=0x02,
- File =0x04,
- Persistence =0x08,
- Remoting =0x10,
- Other =0x20,
- Clone =0x40,
- CrossAppDomain =0x80,
- All =0xFF,
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/Versioning/NonVersionableAttribute.cs b/src/mscorlib/src/System/Runtime/Versioning/NonVersionableAttribute.cs
deleted file mode 100644
index 0a9845d9c2..0000000000
--- a/src/mscorlib/src/System/Runtime/Versioning/NonVersionableAttribute.cs
+++ /dev/null
@@ -1,33 +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.
-
-/*============================================================
-**
-** Class: NonVersionableAttribute
-**
-**
-** The [NonVersionable] attribute is applied to indicate that the implementation
-** of a particular member or layout of a struct cannot be changed for given platform in incompatible way.
-** This allows cross-module inlining of methods and data structures whose implementation
-** is never changed in ReadyToRun native images. Any changes to such members or types would be
-** breaking changes for ReadyToRun.
-**
-===========================================================*/
-using System;
-using System.Diagnostics;
-
-namespace System.Runtime.Versioning {
-
- // This Conditional is here to strip the annotations for targets where ReadyToRun is not supported.
- // If this attribute is ever made public, this Conditional should be removed.
- [Conditional("FEATURE_READYTORUN")]
- [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Constructor,
- AllowMultiple = false, Inherited = false)]
- sealed class NonVersionableAttribute : Attribute {
-
- public NonVersionableAttribute()
- {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Runtime/Versioning/TargetFrameworkAttribute.cs b/src/mscorlib/src/System/Runtime/Versioning/TargetFrameworkAttribute.cs
deleted file mode 100644
index 600ba3f154..0000000000
--- a/src/mscorlib/src/System/Runtime/Versioning/TargetFrameworkAttribute.cs
+++ /dev/null
@@ -1,45 +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.
-
-//
-/*============================================================
-**
-**
-**
-** Purpose: Identifies which SKU and version of the .NET
-** Framework that a particular library was compiled against.
-** Emitted by VS, and can help catch deployment problems.
-**
-===========================================================*/
-using System;
-using System.Diagnostics.Contracts;
-
-namespace System.Runtime.Versioning {
-
- [AttributeUsageAttribute(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
- public sealed class TargetFrameworkAttribute : Attribute {
- private String _frameworkName; // A target framework moniker
- private String _frameworkDisplayName;
-
- // The frameworkName parameter is intended to be the string form of a FrameworkName instance.
- public TargetFrameworkAttribute(String frameworkName)
- {
- if (frameworkName == null)
- throw new ArgumentNullException(nameof(frameworkName));
- Contract.EndContractBlock();
- _frameworkName = frameworkName;
- }
-
- // The target framework moniker that this assembly was compiled against.
- // Use the FrameworkName class to interpret target framework monikers.
- public String FrameworkName {
- get { return _frameworkName; }
- }
-
- public String FrameworkDisplayName {
- get { return _frameworkDisplayName; }
- set { _frameworkDisplayName = value; }
- }
- }
-}
diff --git a/src/mscorlib/src/System/RuntimeArgumentHandle.cs b/src/mscorlib/src/System/RuntimeArgumentHandle.cs
index 3e13614930..6b56ae8f01 100644
--- a/src/mscorlib/src/System/RuntimeArgumentHandle.cs
+++ b/src/mscorlib/src/System/RuntimeArgumentHandle.cs
@@ -2,9 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System {
-
- using System;
+
+using System;
+
+namespace System
+{
// This value type is used for constructing System.ArgIterator.
//
// SECURITY : m_ptr cannot be set to anything other than null by untrusted
@@ -19,5 +21,4 @@ namespace System {
internal IntPtr Value { get { return m_ptr; } }
}
-
}
diff --git a/src/mscorlib/src/System/RuntimeHandles.cs b/src/mscorlib/src/System/RuntimeHandles.cs
index 39c85ad4e2..ab125e741e 100644
--- a/src/mscorlib/src/System/RuntimeHandles.cs
+++ b/src/mscorlib/src/System/RuntimeHandles.cs
@@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.
-namespace System
+namespace System
{
using System;
using System.Reflection;
@@ -32,7 +32,7 @@ namespace System
// Create local copy to avoid a race condition
RuntimeType type = m_type;
if (type == null)
- throw new ArgumentNullException(null, Environment.GetResourceString("Arg_InvalidHandle"));
+ throw new ArgumentNullException(null, SR.Arg_InvalidHandle);
return new RuntimeTypeHandle(type);
}
@@ -42,13 +42,13 @@ namespace System
// Create local copy to avoid a race condition
RuntimeType type = m_type;
if (type == null)
- throw new ArgumentNullException(null, Environment.GetResourceString("Arg_InvalidHandle"));
+ throw new ArgumentNullException(null, SR.Arg_InvalidHandle);
return type;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsInstanceOfType(RuntimeType type, Object o);
-
+
internal unsafe static Type GetTypeHelper(Type typeStart, Type[] genericArgs, IntPtr pModifiers, int cModifiers)
{
Type type = typeStart;
@@ -61,11 +61,11 @@ namespace System
if (cModifiers > 0)
{
int* arModifiers = (int*)pModifiers.ToPointer();
- for(int i = 0; i < cModifiers; i++)
+ for (int i = 0; i < cModifiers; i++)
{
if ((CorElementType)Marshal.ReadInt32((IntPtr)arModifiers, i * sizeof(int)) == CorElementType.Ptr)
type = type.MakePointerType();
-
+
else if ((CorElementType)Marshal.ReadInt32((IntPtr)arModifiers, i * sizeof(int)) == CorElementType.ByRef)
type = type.MakeByRefType();
@@ -76,18 +76,18 @@ namespace System
type = type.MakeArrayType(Marshal.ReadInt32((IntPtr)arModifiers, ++i * sizeof(int)));
}
}
-
+
return type;
}
public static bool operator ==(RuntimeTypeHandle left, object right) { return left.Equals(right); }
-
+
public static bool operator ==(object left, RuntimeTypeHandle right) { return right.Equals(left); }
-
+
public static bool operator !=(RuntimeTypeHandle left, object right) { return !left.Equals(right); }
public static bool operator !=(object left, RuntimeTypeHandle right) { return !right.Equals(left); }
-
+
// This is the RuntimeType for the type
private RuntimeType m_type;
@@ -99,10 +99,10 @@ namespace System
public override bool Equals(object obj)
{
- if(!(obj is RuntimeTypeHandle))
+ if (!(obj is RuntimeTypeHandle))
return false;
- RuntimeTypeHandle handle =(RuntimeTypeHandle)obj;
+ RuntimeTypeHandle handle = (RuntimeTypeHandle)obj;
return handle.m_type == m_type;
}
@@ -153,7 +153,7 @@ namespace System
return (corElemType == CorElementType.Array || corElemType == CorElementType.SzArray);
}
- internal static bool IsSzArray(RuntimeType type)
+ internal static bool IsSZArray(RuntimeType type)
{
CorElementType corElemType = GetCorElementType(type);
return (corElemType == CorElementType.SzArray);
@@ -203,7 +203,7 @@ namespace System
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern Object CreateInstance(RuntimeType type, bool publicOnly, bool noCheck, ref bool canBeCached, ref RuntimeMethodHandleInternal ctor, ref bool bNeedSecurityCheck);
+ internal static extern Object CreateInstance(RuntimeType type, bool publicOnly, ref bool canBeCached, ref RuntimeMethodHandleInternal ctor);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Object CreateCaInstance(RuntimeType type, IRuntimeMethodInfo ctor);
@@ -213,7 +213,7 @@ namespace System
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Object CreateInstanceForAnotherGenericParameter(RuntimeType type, RuntimeType genericParameter);
-
+
internal RuntimeType GetRuntimeType()
{
return m_type;
@@ -233,12 +233,12 @@ namespace System
{
return new ModuleHandle(RuntimeTypeHandle.GetModule(m_type));
}
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static RuntimeType GetBaseType(RuntimeType type);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern static TypeAttributes GetAttributes(RuntimeType type);
+ internal extern static TypeAttributes GetAttributes(RuntimeType type);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static RuntimeType GetElementType(RuntimeType type);
@@ -247,27 +247,27 @@ namespace System
internal extern static bool CompareCanonicalHandles(RuntimeType left, RuntimeType right);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern static int GetArrayRank(RuntimeType type);
+ internal extern static int GetArrayRank(RuntimeType type);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern static int GetToken(RuntimeType type);
-
+ internal extern static int GetToken(RuntimeType type);
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static RuntimeMethodHandleInternal GetMethodAt(RuntimeType type, int slot);
// This is managed wrapper for MethodTable::IntroducedMethodIterator
internal struct IntroducedMethodEnumerator
{
- bool _firstCall;
- RuntimeMethodHandleInternal _handle;
+ private bool _firstCall;
+ private RuntimeMethodHandleInternal _handle;
internal IntroducedMethodEnumerator(RuntimeType type)
{
_handle = RuntimeTypeHandle.GetFirstIntroducedMethod(type);
_firstCall = true;
}
-
- public bool MoveNext()
+
+ public bool MoveNext()
{
if (_firstCall)
{
@@ -281,8 +281,9 @@ namespace System
}
public RuntimeMethodHandleInternal Current
- {
- get {
+ {
+ get
+ {
return _handle;
}
}
@@ -304,13 +305,13 @@ namespace System
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void GetNextIntroducedMethod(ref RuntimeMethodHandleInternal method);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool GetFields(RuntimeType type, IntPtr* result, int* count);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static Type[] GetInterfaces(RuntimeType type);
-
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetConstraints(RuntimeTypeHandle handle, ObjectHandleOnStack types);
@@ -333,7 +334,7 @@ namespace System
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern static int GetNumVirtuals(RuntimeType type);
+ internal extern static int GetNumVirtuals(RuntimeType type);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
@@ -354,7 +355,7 @@ namespace System
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern static bool IsComObject(RuntimeType type, bool isGenericCOM);
+ internal extern static bool IsComObject(RuntimeType type, bool isGenericCOM);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsInterface(RuntimeType type);
@@ -363,7 +364,7 @@ namespace System
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private extern static bool _IsVisible(RuntimeTypeHandle typeHandle);
-
+
internal static bool IsVisible(RuntimeType type)
{
return _IsVisible(new RuntimeTypeHandle(type));
@@ -427,24 +428,24 @@ namespace System
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static RuntimeType GetDeclaringType(RuntimeType type);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static IRuntimeMethodInfo GetDeclaringMethod(RuntimeType type);
-
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetDefaultConstructor(RuntimeTypeHandle handle, ObjectHandleOnStack method);
- internal IRuntimeMethodInfo GetDefaultConstructor()
+ internal IRuntimeMethodInfo GetDefaultConstructor()
{
IRuntimeMethodInfo ctor = null;
GetDefaultConstructor(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref ctor));
return ctor;
}
-
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
- private extern static void GetTypeByName(string name, bool throwOnError, bool ignoreCase, bool reflectionOnly, StackCrawlMarkHandle stackMark,
+ private extern static void GetTypeByName(string name, bool throwOnError, bool ignoreCase, bool reflectionOnly, StackCrawlMarkHandle stackMark,
IntPtr pPrivHostBinder,
bool loadTypeFromPartialName, ObjectHandleOnStack type, ObjectHandleOnStack keepalive);
@@ -461,7 +462,7 @@ namespace System
if (name == null || name.Length == 0)
{
if (throwOnError)
- throw new TypeLoadException(Environment.GetResourceString("Arg_TypeLoadNullStr"));
+ throw new TypeLoadException(SR.Arg_TypeLoadNullStr);
return null;
}
@@ -485,7 +486,7 @@ namespace System
internal static RuntimeType GetTypeByNameUsingCARules(string name, RuntimeModule scope)
{
if (name == null || name.Length == 0)
- throw new ArgumentException(null, nameof(name));
+ throw new ArgumentException(null, nameof(name));
Contract.EndContractBlock();
RuntimeType type = null;
@@ -520,7 +521,7 @@ namespace System
{
// defensive copy to be sure array is not mutated from the outside during processing
int instCount;
- IntPtr []instHandles = CopyRuntimeTypeHandles(inst, out instCount);
+ IntPtr[] instHandles = CopyRuntimeTypeHandles(inst, out instCount);
fixed (IntPtr* pInst = instHandles)
{
@@ -552,7 +553,7 @@ namespace System
MakeSZArray(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref type));
return type;
}
-
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void MakeByRef(RuntimeTypeHandle handle, ObjectHandleOnStack type);
@@ -563,7 +564,7 @@ namespace System
MakeByRef(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref type));
return type;
}
-
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void MakePointer(RuntimeTypeHandle handle, ObjectHandleOnStack type);
@@ -578,7 +579,7 @@ namespace System
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
internal extern static bool IsCollectible(RuntimeTypeHandle handle);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool HasInstantiation(RuntimeType type);
@@ -598,7 +599,7 @@ namespace System
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsGenericTypeDefinition(RuntimeType type);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsGenericVariable(RuntimeType type);
@@ -610,7 +611,7 @@ namespace System
RuntimeType type = GetTypeChecked();
if (!IsGenericVariable(type))
- throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
+ throw new InvalidOperationException(SR.Arg_NotGenericParameter);
return GetGenericVariableIndex(type);
}
@@ -622,9 +623,9 @@ namespace System
{
return ContainsGenericVariables(GetTypeChecked());
}
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern static bool SatisfiesConstraints(RuntimeType paramType, IntPtr *pTypeContext, int typeContextLength, IntPtr *pMethodContext, int methodContextLength, RuntimeType toType);
+ private extern static bool SatisfiesConstraints(RuntimeType paramType, IntPtr* pTypeContext, int typeContextLength, IntPtr* pMethodContext, int methodContextLength, RuntimeType toType);
internal static bool SatisfiesConstraints(RuntimeType paramType, RuntimeType[] typeContext, RuntimeType[] methodContext, RuntimeType toType)
{
@@ -632,8 +633,8 @@ namespace System
int methodContextLength;
IntPtr[] typeContextHandles = CopyRuntimeTypeHandles(typeContext, out typeContextLength);
IntPtr[] methodContextHandles = CopyRuntimeTypeHandles(methodContext, out methodContextLength);
-
- fixed (IntPtr *pTypeContextHandles = typeContextHandles, pMethodContextHandles = methodContextHandles)
+
+ fixed (IntPtr* pTypeContextHandles = typeContextHandles, pMethodContextHandles = methodContextHandles)
{
bool result = SatisfiesConstraints(paramType, pTypeContextHandles, typeContextLength, pMethodContextHandles, methodContextLength, toType);
@@ -651,10 +652,10 @@ namespace System
{
return new MetadataImport(_GetMetadataImport(type), type);
}
-
+
private RuntimeTypeHandle(SerializationInfo info, StreamingContext context)
{
- if(info == null)
+ if (info == null)
throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
@@ -663,17 +664,17 @@ namespace System
m_type = m;
if (m_type == null)
- throw new SerializationException(Environment.GetResourceString("Serialization_InsufficientState"));
+ throw new SerializationException(SR.Serialization_InsufficientState);
}
- public void GetObjectData(SerializationInfo info, StreamingContext context)
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
{
- if(info == null)
+ if (info == null)
throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
if (m_type == null)
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidFieldState"));
+ throw new SerializationException(SR.Serialization_InvalidFieldState);
info.AddValue("TypeObj", m_type, typeof(RuntimeType));
}
@@ -715,7 +716,7 @@ namespace System
{
m_handle = value;
}
-
+
internal IntPtr m_handle;
}
@@ -733,17 +734,17 @@ namespace System
m_value = new RuntimeMethodHandleInternal(methodHandleValue);
}
- object m_keepalive;
+ private object m_keepalive;
// These unused variables are used to ensure that this class has the same layout as RuntimeMethodInfo
#pragma warning disable 169
- object m_a;
- object m_b;
- object m_c;
- object m_d;
- object m_e;
- object m_f;
- object m_g;
+ private object m_a;
+ private object m_b;
+ private object m_c;
+ private object m_d;
+ private object m_e;
+ private object m_f;
+ private object m_g;
#pragma warning restore 169
public RuntimeMethodHandleInternal m_value;
@@ -772,12 +773,12 @@ namespace System
internal static IRuntimeMethodInfo EnsureNonNullMethodInfo(IRuntimeMethodInfo method)
{
if (method == null)
- throw new ArgumentNullException(null, Environment.GetResourceString("Arg_InvalidHandle"));
+ throw new ArgumentNullException(null, SR.Arg_InvalidHandle);
return method;
}
private IRuntimeMethodInfo m_value;
-
+
internal RuntimeMethodHandle(IRuntimeMethodInfo method)
{
m_value = method;
@@ -793,31 +794,31 @@ namespace System
{
return rmh.Value;
}
-
+
// ISerializable interface
private RuntimeMethodHandle(SerializationInfo info, StreamingContext context)
{
- if(info == null)
+ if (info == null)
throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
-
- MethodBase m =(MethodBase)info.GetValue("MethodObj", typeof(MethodBase));
+
+ MethodBase m = (MethodBase)info.GetValue("MethodObj", typeof(MethodBase));
m_value = m.MethodHandle.m_value;
if (m_value == null)
- throw new SerializationException(Environment.GetResourceString("Serialization_InsufficientState"));
+ throw new SerializationException(SR.Serialization_InsufficientState);
}
- public void GetObjectData(SerializationInfo info, StreamingContext context)
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
{
- if (info == null)
+ if (info == null)
throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
if (m_value == null)
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidFieldState"));
-
+ throw new SerializationException(SR.Serialization_InvalidFieldState);
+
// This is either a RuntimeMethodInfo or a RuntimeConstructorInfo
MethodBase methodInfo = RuntimeType.GetMethodBase(m_value);
@@ -863,9 +864,9 @@ namespace System
}
[Pure]
- internal bool IsNullHandle()
- {
- return m_value == null;
+ internal bool IsNullHandle()
+ {
+ return m_value == null;
}
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
@@ -896,7 +897,7 @@ namespace System
{
return _GetCurrentMethod(ref stackMark);
}
-
+
[Pure]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern MethodAttributes GetAttributes(RuntimeMethodHandleInternal method);
@@ -910,7 +911,7 @@ namespace System
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern MethodImplAttributes GetImplAttributes(IRuntimeMethodInfo method);
-
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void ConstructInstantiation(IRuntimeMethodInfo method, TypeNameFormatFlags format, StringHandleOnStack retString);
@@ -943,7 +944,7 @@ namespace System
GC.KeepAlive(method);
return slot;
}
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static int GetMethodDef(IRuntimeMethodInfo method);
@@ -973,7 +974,7 @@ namespace System
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static object InvokeMethod(object target, object[] arguments, Signature sig, bool constructor);
-#region Private Invocation Helpers
+ #region Private Invocation Helpers
internal static INVOCATION_FLAGS GetSecurityFlags(IRuntimeMethodInfo handle)
{
return (INVOCATION_FLAGS)RuntimeMethodHandle.GetSpecialSecurityFlags(handle);
@@ -982,10 +983,10 @@ namespace System
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static extern internal uint GetSpecialSecurityFlags(IRuntimeMethodInfo method);
-#endregion
+ #endregion
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- [SuppressUnmanagedCodeSecurity]
+ [SuppressUnmanagedCodeSecurity]
private extern static void GetMethodInstantiation(RuntimeMethodHandleInternal method, ObjectHandleOnStack types, bool fAsRuntimeTypeArray);
internal static RuntimeType[] GetMethodInstantiationInternal(IRuntimeMethodInfo method)
@@ -1023,10 +1024,10 @@ namespace System
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static RuntimeMethodHandleInternal GetStubIfNeeded(RuntimeMethodHandleInternal method, RuntimeType declaringType, RuntimeType[] methodInstantiation);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static RuntimeMethodHandleInternal GetMethodFromCanonical(RuntimeMethodHandleInternal method, RuntimeType declaringType);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static bool IsGenericMethodDefinition(RuntimeMethodHandleInternal method);
@@ -1044,7 +1045,7 @@ namespace System
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetTypicalMethodDefinition(IRuntimeMethodInfo method, ObjectHandleOnStack outMethod);
-
+
internal static IRuntimeMethodInfo GetTypicalMethodDefinition(IRuntimeMethodInfo method)
{
if (!IsTypicalMethodDefinition(method))
@@ -1056,7 +1057,7 @@ namespace System
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void StripMethodInstantiation(IRuntimeMethodInfo method, ObjectHandleOnStack outMethod);
-
+
internal static IRuntimeMethodInfo StripMethodInstantiation(IRuntimeMethodInfo method)
{
IRuntimeMethodInfo strippedMethod = method;
@@ -1097,7 +1098,6 @@ namespace System
// When in doubt, do not use.
internal struct RuntimeFieldHandleInternal
{
-
internal bool IsNullHandle()
{
return m_handle.IsNull();
@@ -1130,15 +1130,14 @@ namespace System
[StructLayout(LayoutKind.Sequential)]
internal class RuntimeFieldInfoStub : IRuntimeFieldInfo
{
-
// These unused variables are used to ensure that this class has the same layout as RuntimeFieldInfo
#pragma warning disable 169
- object m_keepalive;
- object m_c;
- object m_d;
- int m_b;
- object m_e;
- RuntimeFieldHandleInternal m_fieldHandle;
+ private object m_keepalive;
+ private object m_c;
+ private object m_d;
+ private int m_b;
+ private object m_e;
+ private RuntimeFieldHandleInternal m_fieldHandle;
#pragma warning restore 169
RuntimeFieldHandleInternal IRuntimeFieldInfo.Value
@@ -1159,7 +1158,7 @@ namespace System
// Create local copy to avoid a race condition
IRuntimeFieldInfo field = m_ptr;
if (field == null)
- throw new ArgumentNullException(null, Environment.GetResourceString("Arg_InvalidHandle"));
+ throw new ArgumentNullException(null, SR.Arg_InvalidHandle);
return new RuntimeFieldHandle(field);
}
@@ -1183,16 +1182,16 @@ namespace System
}
}
- internal bool IsNullHandle()
+ internal bool IsNullHandle()
{
- return m_ptr == null;
+ return m_ptr == null;
}
public override int GetHashCode()
{
return ValueType.GetHashCodeOfPtr(Value);
}
-
+
public override bool Equals(object obj)
{
if (!(obj is RuntimeFieldHandle))
@@ -1218,11 +1217,11 @@ namespace System
return !left.Equals(right);
}
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern String GetName(RtFieldInfo field);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern String GetName(RtFieldInfo field);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern unsafe void* _GetUtf8Name(RuntimeFieldHandleInternal field);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern unsafe void* _GetUtf8Name(RuntimeFieldHandleInternal field);
internal static unsafe Utf8String GetUtf8Name(RuntimeFieldHandleInternal field) { return new Utf8String(_GetUtf8Name(field)); }
@@ -1230,8 +1229,8 @@ namespace System
internal static extern bool MatchesNameHash(RuntimeFieldHandleInternal handle, uint hash);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern FieldAttributes GetAttributes(RuntimeFieldHandleInternal field);
-
+ internal static extern FieldAttributes GetAttributes(RuntimeFieldHandleInternal field);
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern RuntimeType GetApproxDeclaringType(RuntimeFieldHandleInternal field);
@@ -1242,16 +1241,16 @@ namespace System
return type;
}
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern int GetToken(RtFieldInfo field);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern int GetToken(RtFieldInfo field);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern Object GetValue(RtFieldInfo field, Object instance, RuntimeType fieldType, RuntimeType declaringType, ref bool domainInitialized);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern Object GetValueDirect(RtFieldInfo field, RuntimeType fieldType, void *pTypedRef, RuntimeType contextType);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern Object GetValueDirect(RtFieldInfo field, RuntimeType fieldType, void* pTypedRef, RuntimeType contextType);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void SetValue(RtFieldInfo field, Object obj, Object value, RuntimeType fieldType, FieldAttributes fieldAttr, RuntimeType declaringType, ref bool domainInitialized);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -1300,68 +1299,68 @@ namespace System
// ISerializable interface
private RuntimeFieldHandle(SerializationInfo info, StreamingContext context)
{
- if(info==null)
+ if (info == null)
throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
-
- FieldInfo f =(RuntimeFieldInfo) info.GetValue("FieldObj", typeof(RuntimeFieldInfo));
-
- if( f == null)
- throw new SerializationException(Environment.GetResourceString("Serialization_InsufficientState"));
+
+ FieldInfo f = (RuntimeFieldInfo)info.GetValue("FieldObj", typeof(RuntimeFieldInfo));
+
+ if (f == null)
+ throw new SerializationException(SR.Serialization_InsufficientState);
m_ptr = f.FieldHandle.m_ptr;
if (m_ptr == null)
- throw new SerializationException(Environment.GetResourceString("Serialization_InsufficientState"));
+ throw new SerializationException(SR.Serialization_InsufficientState);
}
- public void GetObjectData(SerializationInfo info, StreamingContext context)
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
{
- if (info == null)
+ if (info == null)
throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
if (m_ptr == null)
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidFieldState"));
+ throw new SerializationException(SR.Serialization_InvalidFieldState);
+
+ RuntimeFieldInfo fldInfo = (RuntimeFieldInfo)RuntimeType.GetFieldInfo(this.GetRuntimeFieldInfo());
- RuntimeFieldInfo fldInfo = (RuntimeFieldInfo)RuntimeType.GetFieldInfo(this.GetRuntimeFieldInfo());
-
- info.AddValue("FieldObj",fldInfo, typeof(RuntimeFieldInfo));
+ info.AddValue("FieldObj", fldInfo, typeof(RuntimeFieldInfo));
}
}
public unsafe struct ModuleHandle
{
// Returns handle for interop with EE. The handle is guaranteed to be non-null.
-#region Public Static Members
+ #region Public Static Members
public static readonly ModuleHandle EmptyHandle = GetEmptyMH();
-#endregion
+ #endregion
unsafe static private ModuleHandle GetEmptyMH()
{
return new ModuleHandle();
}
-#region Private Data Members
+ #region Private Data Members
private RuntimeModule m_ptr;
-#endregion
-
-#region Constructor
- internal ModuleHandle(RuntimeModule module)
+ #endregion
+
+ #region Constructor
+ internal ModuleHandle(RuntimeModule module)
{
m_ptr = module;
}
-#endregion
+ #endregion
-#region Internal FCalls
+ #region Internal FCalls
internal RuntimeModule GetRuntimeModule()
{
return m_ptr;
}
-
+
public override int GetHashCode()
- {
+ {
return m_ptr != null ? m_ptr.GetHashCode() : 0;
}
@@ -1400,16 +1399,16 @@ namespace System
{
// Make sure we have a valid Module to resolve against.
if (module == null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NullModuleHandle"));
+ throw new InvalidOperationException(SR.InvalidOperation_NullModuleHandle);
}
// SQL-CLR LKG9 Compiler dependency
public RuntimeTypeHandle GetRuntimeTypeHandleFromMetadataToken(int typeToken) { return ResolveTypeHandle(typeToken); }
- public RuntimeTypeHandle ResolveTypeHandle(int typeToken)
+ public RuntimeTypeHandle ResolveTypeHandle(int typeToken)
{
return new RuntimeTypeHandle(ResolveTypeHandleInternal(GetRuntimeModule(), typeToken, null, null));
}
- public RuntimeTypeHandle ResolveTypeHandle(int typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
+ public RuntimeTypeHandle ResolveTypeHandle(int typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
{
return new RuntimeTypeHandle(ModuleHandle.ResolveTypeHandleInternal(GetRuntimeModule(), typeToken, typeInstantiationContext, methodInstantiationContext));
}
@@ -1419,8 +1418,8 @@ namespace System
ValidateModulePointer(module);
if (!ModuleHandle.GetMetadataImport(module).IsValidToken(typeToken))
throw new ArgumentOutOfRangeException(nameof(typeToken),
- Environment.GetResourceString("Argument_InvalidToken", typeToken, new ModuleHandle(module)));
-
+ SR.Format(SR.Argument_InvalidToken, typeToken, new ModuleHandle(module)));
+
int typeInstCount, methodInstCount;
IntPtr[] typeInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(typeInstantiationContext, out typeInstCount);
IntPtr[] methodInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(methodInstantiationContext, out methodInstCount);
@@ -1439,7 +1438,7 @@ namespace System
[SuppressUnmanagedCodeSecurity]
private extern static void ResolveType(RuntimeModule module,
int typeToken,
- IntPtr* typeInstArgs,
+ IntPtr* typeInstArgs,
int typeInstCount,
IntPtr* methodInstArgs,
int methodInstCount,
@@ -1473,7 +1472,7 @@ namespace System
ValidateModulePointer(module);
if (!ModuleHandle.GetMetadataImport(module.GetNativeHandle()).IsValidToken(methodToken))
throw new ArgumentOutOfRangeException(nameof(methodToken),
- Environment.GetResourceString("Argument_InvalidToken", methodToken, new ModuleHandle(module)));
+ SR.Format(SR.Argument_InvalidToken, methodToken, new ModuleHandle(module)));
fixed (IntPtr* typeInstArgs = typeInstantiationContext, methodInstArgs = methodInstantiationContext)
{
@@ -1485,7 +1484,7 @@ namespace System
[SuppressUnmanagedCodeSecurity]
private extern static RuntimeMethodHandleInternal ResolveMethod(RuntimeModule module,
int methodToken,
- IntPtr* typeInstArgs,
+ IntPtr* typeInstArgs,
int typeInstCount,
IntPtr* methodInstArgs,
int methodInstCount);
@@ -1494,19 +1493,19 @@ namespace System
public RuntimeFieldHandle GetRuntimeFieldHandleFromMetadataToken(int fieldToken) { return ResolveFieldHandle(fieldToken); }
public RuntimeFieldHandle ResolveFieldHandle(int fieldToken) { return new RuntimeFieldHandle(ResolveFieldHandleInternal(GetRuntimeModule(), fieldToken, null, null)); }
public RuntimeFieldHandle ResolveFieldHandle(int fieldToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
- { return new RuntimeFieldHandle(ResolveFieldHandleInternal(GetRuntimeModule(), fieldToken, typeInstantiationContext, methodInstantiationContext)); }
+ { return new RuntimeFieldHandle(ResolveFieldHandleInternal(GetRuntimeModule(), fieldToken, typeInstantiationContext, methodInstantiationContext)); }
internal static IRuntimeFieldInfo ResolveFieldHandleInternal(RuntimeModule module, int fieldToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
{
ValidateModulePointer(module);
if (!ModuleHandle.GetMetadataImport(module.GetNativeHandle()).IsValidToken(fieldToken))
throw new ArgumentOutOfRangeException(nameof(fieldToken),
- Environment.GetResourceString("Argument_InvalidToken", fieldToken, new ModuleHandle(module)));
-
+ SR.Format(SR.Argument_InvalidToken, fieldToken, new ModuleHandle(module)));
+
// defensive copy to be sure array is not mutated from the outside during processing
int typeInstCount, methodInstCount;
- IntPtr [] typeInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(typeInstantiationContext, out typeInstCount);
- IntPtr [] methodInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(methodInstantiationContext, out methodInstCount);
+ IntPtr[] typeInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(typeInstantiationContext, out typeInstCount);
+ IntPtr[] methodInstantiationContextHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(methodInstantiationContext, out methodInstCount);
fixed (IntPtr* typeInstArgs = typeInstantiationContextHandles, methodInstArgs = methodInstantiationContextHandles)
{
@@ -1522,7 +1521,7 @@ namespace System
[SuppressUnmanagedCodeSecurity]
private extern static void ResolveField(RuntimeModule module,
int fieldToken,
- IntPtr* typeInstArgs,
+ IntPtr* typeInstArgs,
int typeInstCount,
IntPtr* methodInstArgs,
int methodInstCount,
@@ -1547,11 +1546,11 @@ namespace System
GetModuleType(module.GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref type));
return type;
}
-
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private extern static void GetPEKind(RuntimeModule handle, out int peKind, out int machine);
-
+
// making this internal, used by Module.GetPEKind
internal static void GetPEKind(RuntimeModule module, out PortableExecutableKinds peKind, out ImageFileMachine machine)
{
@@ -1560,15 +1559,15 @@ namespace System
peKind = (PortableExecutableKinds)lKind;
machine = (ImageFileMachine)lMachine;
}
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern static int GetMDStreamVersion(RuntimeModule module);
public int MDStreamVersion
{
get { return GetMDStreamVersion(GetRuntimeModule().GetNativeHandle()); }
}
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static IntPtr _GetMetadataImport(RuntimeModule module);
@@ -1576,42 +1575,42 @@ namespace System
{
return new MetadataImport(_GetMetadataImport(module.GetNativeHandle()), module);
}
-#endregion
+ #endregion
}
internal unsafe class Signature
{
-#region Definitions
+ #region Definitions
internal enum MdSigCallingConvention : byte
{
- Generics = 0x10,
- HasThis = 0x20,
- ExplicitThis = 0x40,
- CallConvMask = 0x0F,
- Default = 0x00,
- C = 0x01,
- StdCall = 0x02,
- ThisCall = 0x03,
- FastCall = 0x04,
- Vararg = 0x05,
- Field = 0x06,
- LocalSig = 0x07,
- Property = 0x08,
- Unmgd = 0x09,
- GenericInst = 0x0A,
- Max = 0x0B,
- }
-#endregion
-
-#region FCalls
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ Generics = 0x10,
+ HasThis = 0x20,
+ ExplicitThis = 0x40,
+ CallConvMask = 0x0F,
+ Default = 0x00,
+ C = 0x01,
+ StdCall = 0x02,
+ ThisCall = 0x03,
+ FastCall = 0x04,
+ Vararg = 0x05,
+ Field = 0x06,
+ LocalSig = 0x07,
+ Property = 0x08,
+ Unmgd = 0x09,
+ GenericInst = 0x0A,
+ Max = 0x0B,
+ }
+ #endregion
+
+ #region FCalls
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void GetSignature(
void* pCorSig, int cCorSig,
RuntimeFieldHandleInternal fieldHandle, IRuntimeMethodInfo methodHandle, RuntimeType declaringType);
-#endregion
+ #endregion
-#region Private Data Members
+ #region Private Data Members
//
// Keep the layout in sync with SignatureNative in the VM
//
@@ -1624,10 +1623,10 @@ namespace System
internal int m_nSizeOfArgStack;
internal int m_csig;
internal RuntimeMethodHandleInternal m_pMethod;
-#endregion
+ #endregion
-#region Constructors
- public Signature (
+ #region Constructors
+ public Signature(
IRuntimeMethodInfo method,
RuntimeType[] arguments,
RuntimeType returnType,
@@ -1656,9 +1655,9 @@ namespace System
{
GetSignature(pCorSig, cCorSig, new RuntimeFieldHandleInternal(), null, declaringType);
}
-#endregion
+ #endregion
-#region Internal Members
+ #region Internal Members
internal CallingConventions CallingConvention { get { return (CallingConventions)(byte)m_managedCallingConventionAndArgIteratorFlags; } }
internal RuntimeType[] Arguments { get { return m_arguments; } }
internal RuntimeType ReturnType { get { return m_returnTypeORfieldType; } }
@@ -1669,20 +1668,20 @@ namespace System
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern Type[] GetCustomModifiers(int position, bool required);
-#endregion
+ #endregion
}
internal abstract class Resolver
{
- internal struct CORINFO_EH_CLAUSE
+ internal struct CORINFO_EH_CLAUSE
{
internal int Flags;
internal int TryOffset;
internal int TryLength;
internal int HandlerOffset;
internal int HandlerLength;
- internal int ClassTokenOrFilterOffset;
+ internal int ClassTokenOrFilterOffset;
}
// ILHeader info
@@ -1698,5 +1697,4 @@ namespace System
//
internal abstract MethodInfo GetDynamicMethod();
}
-
}
diff --git a/src/mscorlib/src/System/SByte.cs b/src/mscorlib/src/System/SByte.cs
index e738dfc546..2f1b2da947 100644
--- a/src/mscorlib/src/System/SByte.cs
+++ b/src/mscorlib/src/System/SByte.cs
@@ -10,50 +10,58 @@
**
**
===========================================================*/
-namespace System {
- using System.Globalization;
- using System;
- using System.Runtime.InteropServices;
- using System.Diagnostics.Contracts;
+using System.Globalization;
+using System;
+using System.Runtime.InteropServices;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
// A place holder class for signed bytes.
-[Serializable]
-[CLSCompliant(false), System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
+ [Serializable]
+ [CLSCompliant(false), System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public struct SByte : IComparable, IFormattable, IConvertible
- , IComparable<SByte>, IEquatable<SByte>
+ , IComparable<SByte>, IEquatable<SByte>
{
private sbyte m_value;
-
+
// The maximum value that a Byte may represent: 127.
public const sbyte MaxValue = (sbyte)0x7F;
-
+
// The minimum value that a Byte may represent: -128.
public const sbyte MinValue = unchecked((sbyte)0x80);
-
+
// Compares this object to another object, returning an integer that
// indicates the relationship.
// Returns a value less than zero if this object
// null is considered to be less than any instance.
// If object is not of type SByte, this method throws an ArgumentException.
//
- public int CompareTo(Object obj) {
- if (obj == null) {
+ public int CompareTo(Object obj)
+ {
+ if (obj == null)
+ {
return 1;
}
- if (!(obj is SByte)) {
- throw new ArgumentException (Environment.GetResourceString("Arg_MustBeSByte"));
+ if (!(obj is SByte))
+ {
+ throw new ArgumentException(SR.Arg_MustBeSByte);
}
return m_value - ((SByte)obj).m_value;
}
- public int CompareTo(SByte value) {
+ public int CompareTo(SByte value)
+ {
return m_value - value;
}
-
+
// Determines whether two Byte objects are equal.
- public override bool Equals(Object obj) {
- if (!(obj is SByte)) {
+ public override bool Equals(Object obj)
+ {
+ if (!(obj is SByte))
+ {
return false;
}
return m_value == ((SByte)obj).m_value;
@@ -66,204 +74,226 @@ namespace System {
}
// Gets a hash code for this instance.
- public override int GetHashCode() {
+ public override int GetHashCode()
+ {
return ((int)m_value ^ (int)m_value << 8);
}
-
-
+
+
// Provides a string representation of a byte.
- public override String ToString() {
+ public override String ToString()
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, null, NumberFormatInfo.CurrentInfo);
}
- public String ToString(IFormatProvider provider) {
+ public String ToString(IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatInt32(m_value, null, NumberFormatInfo.GetInstance(provider));
}
-
- public String ToString(String format) {
+
+ public String ToString(String format)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return ToString(format, NumberFormatInfo.CurrentInfo);
}
- public String ToString(String format, IFormatProvider provider) {
+ public String ToString(String format, IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return ToString(format, NumberFormatInfo.GetInstance(provider));
}
- private String ToString(String format, NumberFormatInfo info) {
+ private String ToString(String format, NumberFormatInfo info)
+ {
Contract.Ensures(Contract.Result<String>() != null);
- if (m_value<0 && format!=null && format.Length>0 && (format[0]=='X' || format[0]=='x')) {
+ if (m_value < 0 && format != null && format.Length > 0 && (format[0] == 'X' || format[0] == 'x'))
+ {
uint temp = (uint)(m_value & 0x000000FF);
return Number.FormatUInt32(temp, format, info);
}
return Number.FormatInt32(m_value, format, info);
}
-
+
[CLSCompliant(false)]
- public static sbyte Parse(String s) {
+ public static sbyte Parse(String s)
+ {
return Parse(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
-
+
[CLSCompliant(false)]
- public static sbyte Parse(String s, NumberStyles style) {
- NumberFormatInfo.ValidateParseStyleInteger(style);
+ public static sbyte Parse(String s, NumberStyles style)
+ {
+ NumberFormatInfo.ValidateParseStyleInteger(style);
return Parse(s, style, NumberFormatInfo.CurrentInfo);
}
[CLSCompliant(false)]
- public static sbyte Parse(String s, IFormatProvider provider) {
+ public static sbyte Parse(String s, IFormatProvider provider)
+ {
return Parse(s, NumberStyles.Integer, NumberFormatInfo.GetInstance(provider));
}
-
+
// Parses a signed byte from a String in the given style. If
// a NumberFormatInfo isn't specified, the current culture's
// NumberFormatInfo is assumed.
//
[CLSCompliant(false)]
- public static sbyte Parse(String s, NumberStyles style, IFormatProvider provider) {
- NumberFormatInfo.ValidateParseStyleInteger(style);
+ public static sbyte Parse(String s, NumberStyles style, IFormatProvider provider)
+ {
+ NumberFormatInfo.ValidateParseStyleInteger(style);
return Parse(s, style, NumberFormatInfo.GetInstance(provider));
}
-
- private static sbyte Parse(String s, NumberStyles style, NumberFormatInfo info) {
-
+
+ private static sbyte Parse(String s, NumberStyles style, NumberFormatInfo info)
+ {
int i = 0;
- try {
+ try
+ {
i = Number.ParseInt32(s, style, info);
}
- catch(OverflowException e) {
- throw new OverflowException(Environment.GetResourceString("Overflow_SByte"), e);
+ catch (OverflowException e)
+ {
+ throw new OverflowException(SR.Overflow_SByte, e);
}
- if ((style & NumberStyles.AllowHexSpecifier) != 0) { // We are parsing a hexadecimal number
- if ((i < 0) || i > Byte.MaxValue) {
- throw new OverflowException(Environment.GetResourceString("Overflow_SByte"));
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ { // We are parsing a hexadecimal number
+ if ((i < 0) || i > Byte.MaxValue)
+ {
+ throw new OverflowException(SR.Overflow_SByte);
}
return (sbyte)i;
}
-
- if (i < MinValue || i > MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_SByte"));
+
+ if (i < MinValue || i > MaxValue) throw new OverflowException(SR.Overflow_SByte);
return (sbyte)i;
}
[CLSCompliant(false)]
- public static bool TryParse(String s, out SByte result) {
+ public static bool TryParse(String s, out SByte result)
+ {
return TryParse(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result);
}
[CLSCompliant(false)]
- public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out SByte result) {
- NumberFormatInfo.ValidateParseStyleInteger(style);
+ public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out SByte result)
+ {
+ NumberFormatInfo.ValidateParseStyleInteger(style);
return TryParse(s, style, NumberFormatInfo.GetInstance(provider), out result);
}
-
- private static bool TryParse(String s, NumberStyles style, NumberFormatInfo info, out SByte result) {
+ private static bool TryParse(String s, NumberStyles style, NumberFormatInfo info, out SByte result)
+ {
result = 0;
int i;
- if (!Number.TryParseInt32(s, style, info, out i)) {
+ if (!Number.TryParseInt32(s, style, info, out i))
+ {
return false;
}
- if ((style & NumberStyles.AllowHexSpecifier) != 0) { // We are parsing a hexadecimal number
- if ((i < 0) || i > Byte.MaxValue) {
+ if ((style & NumberStyles.AllowHexSpecifier) != 0)
+ { // We are parsing a hexadecimal number
+ if ((i < 0) || i > Byte.MaxValue)
+ {
return false;
}
result = (sbyte)i;
return true;
}
-
- if (i < MinValue || i > MaxValue) {
+
+ if (i < MinValue || i > MaxValue)
+ {
return false;
}
- result = (sbyte) i;
+ result = (sbyte)i;
return true;
}
-
+
//
// IConvertible implementation
//
-
- public TypeCode GetTypeCode() {
+
+ public TypeCode GetTypeCode()
+ {
return TypeCode.SByte;
}
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
return Convert.ToBoolean(m_value);
}
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
return Convert.ToChar(m_value);
}
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
return m_value;
}
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
return Convert.ToByte(m_value);
}
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
return Convert.ToInt16(m_value);
}
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
return Convert.ToUInt16(m_value);
}
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
return m_value;
}
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
return Convert.ToUInt32(m_value);
}
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
return Convert.ToInt64(m_value);
}
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
return Convert.ToUInt64(m_value);
}
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
return Convert.ToSingle(m_value);
}
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
return Convert.ToDouble(m_value);
}
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider) {
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
return Convert.ToDecimal(m_value);
}
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "SByte", "DateTime"));
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "SByte", "DateTime"));
}
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
return Convert.DefaultToType((IConvertible)this, type, provider);
}
}
diff --git a/src/mscorlib/src/System/Security/Attributes.cs b/src/mscorlib/src/System/Security/Attributes.cs
deleted file mode 100644
index f67a9f0ad1..0000000000
--- a/src/mscorlib/src/System/Security/Attributes.cs
+++ /dev/null
@@ -1,199 +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.Runtime.InteropServices;
-
-namespace System.Security
-{
- // DynamicSecurityMethodAttribute:
- // Indicates that calling the target method requires space for a security
- // object to be allocated on the callers stack. This attribute is only ever
- // set on certain security methods defined within mscorlib.
- [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false )]
- sealed internal class DynamicSecurityMethodAttribute : System.Attribute
- {
- }
-
- // SuppressUnmanagedCodeSecurityAttribute:
- // Indicates that the target P/Invoke method(s) should skip the per-call
- // security checked for unmanaged code permission.
- [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = true, Inherited = false )]
- sealed public class SuppressUnmanagedCodeSecurityAttribute : System.Attribute
- {
- }
-
- // UnverifiableCodeAttribute:
- // Indicates that the target module contains unverifiable code.
- [AttributeUsage(AttributeTargets.Module, AllowMultiple = true, Inherited = false )]
- sealed public class UnverifiableCodeAttribute : System.Attribute
- {
- }
-
- // AllowPartiallyTrustedCallersAttribute:
- // Indicates that the Assembly is secure and can be used by untrusted
- // and semitrusted clients
- // For v.1, this is valid only on Assemblies, but could be expanded to
- // include Module, Method, class
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false )]
- sealed public class AllowPartiallyTrustedCallersAttribute : System.Attribute
- {
- private PartialTrustVisibilityLevel _visibilityLevel;
- public AllowPartiallyTrustedCallersAttribute () { }
-
- public PartialTrustVisibilityLevel PartialTrustVisibilityLevel
- {
- get { return _visibilityLevel; }
- set { _visibilityLevel = value; }
- }
- }
-
- public enum PartialTrustVisibilityLevel
- {
- VisibleToAllHosts = 0,
- NotVisibleByDefault = 1
- }
-
- [Obsolete("SecurityCriticalScope is only used for .NET 2.0 transparency compatibility.")]
- public enum SecurityCriticalScope
- {
- Explicit = 0,
- Everything = 0x1
- }
-
- // SecurityCriticalAttribute
- // Indicates that the decorated code or assembly performs security critical operations (e.g. Assert, "unsafe", LinkDemand, etc.)
- // The attribute can be placed on most targets, except on arguments/return values.
- [AttributeUsage(AttributeTargets.Assembly |
- AttributeTargets.Class |
- AttributeTargets.Struct |
- AttributeTargets.Enum |
- AttributeTargets.Constructor |
- AttributeTargets.Method |
- AttributeTargets.Field |
- AttributeTargets.Interface |
- AttributeTargets.Delegate,
- AllowMultiple = false,
- Inherited = false )]
- sealed public class SecurityCriticalAttribute : System.Attribute
- {
-#pragma warning disable 618 // We still use SecurityCriticalScope for v2 compat
-
- private SecurityCriticalScope _val;
-
- public SecurityCriticalAttribute () {}
-
- public SecurityCriticalAttribute(SecurityCriticalScope scope)
- {
- _val = scope;
- }
-
- [Obsolete("SecurityCriticalScope is only used for .NET 2.0 transparency compatibility.")]
- public SecurityCriticalScope Scope {
- get {
- return _val;
- }
- }
-
-#pragma warning restore 618
- }
-
- // SecurityTreatAsSafeAttribute:
- // Indicates that the code may contain violations to the security critical rules (e.g. transitions from
- // critical to non-public transparent, transparent to non-public critical, etc.), has been audited for
- // security concerns and is considered security clean.
- // At assembly-scope, all rule checks will be suppressed within the assembly and for calls made against the assembly.
- // At type-scope, all rule checks will be suppressed for members within the type and for calls made against the type.
- // At member level (e.g. field and method) the code will be treated as public - i.e. no rule checks for the members.
-
- [AttributeUsage(AttributeTargets.Assembly |
- AttributeTargets.Class |
- AttributeTargets.Struct |
- AttributeTargets.Enum |
- AttributeTargets.Constructor |
- AttributeTargets.Method |
- AttributeTargets.Field |
- AttributeTargets.Interface |
- AttributeTargets.Delegate,
- AllowMultiple = false,
- Inherited = false )]
- [Obsolete("SecurityTreatAsSafe is only used for .NET 2.0 transparency compatibility. Please use the SecuritySafeCriticalAttribute instead.")]
- sealed public class SecurityTreatAsSafeAttribute : System.Attribute
- {
- public SecurityTreatAsSafeAttribute () { }
- }
-
- // SecuritySafeCriticalAttribute:
- // Indicates that the code may contain violations to the security critical rules (e.g. transitions from
- // critical to non-public transparent, transparent to non-public critical, etc.), has been audited for
- // security concerns and is considered security clean. Also indicates that the code is considered SecurityCritical.
- // The effect of this attribute is as if the code was marked [SecurityCritical][SecurityTreatAsSafe].
- // At assembly-scope, all rule checks will be suppressed within the assembly and for calls made against the assembly.
- // At type-scope, all rule checks will be suppressed for members within the type and for calls made against the type.
- // At member level (e.g. field and method) the code will be treated as public - i.e. no rule checks for the members.
-
- [AttributeUsage(AttributeTargets.Class |
- AttributeTargets.Struct |
- AttributeTargets.Enum |
- AttributeTargets.Constructor |
- AttributeTargets.Method |
- AttributeTargets.Field |
- AttributeTargets.Interface |
- AttributeTargets.Delegate,
- AllowMultiple = false,
- Inherited = false )]
- sealed public class SecuritySafeCriticalAttribute : System.Attribute
- {
- public SecuritySafeCriticalAttribute () { }
- }
-
- // SecurityTransparentAttribute:
- // Indicates the assembly contains only transparent code.
- // Security critical actions will be restricted or converted into less critical actions. For example,
- // Assert will be restricted, SuppressUnmanagedCode, LinkDemand, unsafe, and unverifiable code will be converted
- // into Full-Demands.
-
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false )]
- sealed public class SecurityTransparentAttribute : System.Attribute
- {
- public SecurityTransparentAttribute () {}
- }
-
- public enum SecurityRuleSet : byte
- {
- None = 0,
- Level1 = 1, // v2.0 transparency model
- Level2 = 2, // v4.0 transparency model
- }
-
- // SecurityRulesAttribute
- //
- // Indicates which set of security rules an assembly was authored against, and therefore which set of
- // rules the runtime should enforce on the assembly. For instance, an assembly marked with
- // [SecurityRules(SecurityRuleSet.Level1)] will follow the v2.0 transparency rules, where transparent code
- // can call a LinkDemand by converting it to a full demand, public critical methods are implicitly
- // treat as safe, and the remainder of the v2.0 rules apply.
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
- public sealed class SecurityRulesAttribute : Attribute
- {
- private SecurityRuleSet m_ruleSet;
- private bool m_skipVerificationInFullTrust = false;
-
- public SecurityRulesAttribute(SecurityRuleSet ruleSet)
- {
- m_ruleSet = ruleSet;
- }
-
- // Should fully trusted transparent code skip IL verification
- public bool SkipVerificationInFullTrust
- {
- get { return m_skipVerificationInFullTrust; }
- set { m_skipVerificationInFullTrust = value; }
- }
-
- public SecurityRuleSet RuleSet
- {
- get { return m_ruleSet; }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Security/DynamicSecurityMethodAttribute.cs b/src/mscorlib/src/System/Security/DynamicSecurityMethodAttribute.cs
new file mode 100644
index 0000000000..83be902a2c
--- /dev/null
+++ b/src/mscorlib/src/System/Security/DynamicSecurityMethodAttribute.cs
@@ -0,0 +1,21 @@
+// 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.Runtime.InteropServices;
+
+namespace System.Security
+{
+ // DynamicSecurityMethodAttribute:
+ // All methods that use StackCrawlMark should be marked with this attribute. This attribute
+ // disables inlining of the calling method to allow stackwalking to find the exact caller.
+ //
+ // This attribute used to indicate that the target method requires space for a security object
+ // to be allocated on the callers stack. It is not used for this purpose anymore because of security
+ // stackwalks are not ever done in CoreCLR.
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, AllowMultiple = true, Inherited = false)]
+ internal sealed class DynamicSecurityMethodAttribute : Attribute
+ {
+ public DynamicSecurityMethodAttribute() { }
+ }
+}
diff --git a/src/mscorlib/src/System/Security/SecurityException.cs b/src/mscorlib/src/System/Security/SecurityException.cs
deleted file mode 100644
index 8811be82ff..0000000000
--- a/src/mscorlib/src/System/Security/SecurityException.cs
+++ /dev/null
@@ -1,110 +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.
-
-/*=============================================================================
-**
-**
-**
-**
-**
-** Purpose: Exception class for security
-**
-**
-=============================================================================*/
-
-namespace System.Security
-{
- using System.Security;
- using System;
- using System.Runtime.Serialization;
- using System.Reflection;
- using System.Text;
- using System.Security.Policy;
- using System.IO;
- using System.Globalization;
- using System.Diagnostics.Contracts;
-
- [Serializable]
- public class SecurityException : SystemException
- {
- internal static string GetResString(string sResourceName)
- {
- return Environment.GetResourceString(sResourceName);
- }
-
-#pragma warning disable 618
- internal static Exception MakeSecurityException(AssemblyName asmName, Evidence asmEvidence, RuntimeMethodHandleInternal rmh, Object demand)
-#pragma warning restore 618
- {
- return new SecurityException(GetResString("Arg_SecurityException"));
- }
-
- public SecurityException()
- : base(GetResString("Arg_SecurityException"))
- {
- SetErrorCode(System.__HResults.COR_E_SECURITY);
- }
-
- public SecurityException(String message)
- : base(message)
- {
- // This is the constructor that gets called if you Assert but don't have permission to Assert. (So don't assert in here.)
- SetErrorCode(System.__HResults.COR_E_SECURITY);
- }
-
- public SecurityException(String message, Exception inner)
- : base(message, inner)
- {
- SetErrorCode(System.__HResults.COR_E_SECURITY);
- }
-
- protected SecurityException(SerializationInfo info, StreamingContext context) : base(info, context)
- {
- if (info == null)
- throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
- }
-
- public override String ToString()
- {
- return base.ToString();
- }
-
- public override void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- base.GetObjectData(info, context);
- }
-
- // Stubs for surface area compatibility only
- public SecurityException(String message, Type type)
- : base(message)
- {
- SetErrorCode(System.__HResults.COR_E_SECURITY);
- PermissionType = type;
- }
-
- public SecurityException(string message, System.Type type, string state)
- : base(message)
- {
- SetErrorCode(System.__HResults.COR_E_SECURITY);
- PermissionType = type;
- PermissionState = state;
- }
-
- public object Demanded { get; set; }
- public object DenySetInstance { get; set; }
- public System.Reflection.AssemblyName FailedAssemblyInfo { get; set; }
- public string GrantedSet { get; set; }
- public System.Reflection.MethodInfo Method { get; set; }
- public string PermissionState { get; set; }
- public System.Type PermissionType { get; set; }
- public object PermitOnlySetInstance { get; set; }
- public string RefusedSet { get; set; }
- public string Url { get; set; }
- }
-}
diff --git a/src/mscorlib/src/System/Security/SecurityState.cs b/src/mscorlib/src/System/Security/SecurityState.cs
deleted file mode 100644
index 55dcce07c0..0000000000
--- a/src/mscorlib/src/System/Security/SecurityState.cs
+++ /dev/null
@@ -1,25 +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.Security;
-
-namespace System.Security
-{
- public abstract class SecurityState
- {
- protected SecurityState(){}
-
- public bool IsStateAvailable()
- {
- AppDomainManager domainManager = AppDomainManager.CurrentAppDomainManager;
-
- // CheckSecuritySettings only when appdomainManager is present. So if there is no
- // appDomain Manager return true as by default coreclr runs in fulltrust.
- return domainManager != null ? domainManager.CheckSecuritySettings(this) : true;
- }
- // override this function and throw the appropriate
- public abstract void EnsureState();
- }
-
-}
diff --git a/src/mscorlib/src/System/Security/Util/URLString.cs b/src/mscorlib/src/System/Security/Util/URLString.cs
deleted file mode 100644
index 4ec353876a..0000000000
--- a/src/mscorlib/src/System/Security/Util/URLString.cs
+++ /dev/null
@@ -1,138 +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.
-
-// URLString
-//
-//
-// Implementation of membership condition for zones
-//
-
-namespace System.Security.Util {
-
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
- using System.Runtime.Serialization;
- using System.Globalization;
- using System.Text;
- using System.IO;
- using System.Diagnostics.Contracts;
-
- internal static class URLString
- {
- internal static string PreProcessForExtendedPathRemoval(bool checkPathLength, string url, bool isFileUrl)
- {
- bool isUncShare = false;
- return PreProcessForExtendedPathRemoval(checkPathLength: checkPathLength, url: url, isFileUrl: isFileUrl, isUncShare: ref isUncShare);
- }
-
- // Keeping this signature to avoid reflection breaks
- private static string PreProcessForExtendedPathRemoval(string url, bool isFileUrl, ref bool isUncShare)
- {
- return PreProcessForExtendedPathRemoval(checkPathLength: true, url: url, isFileUrl: isFileUrl, isUncShare: ref isUncShare);
- }
-
- private static string PreProcessForExtendedPathRemoval(bool checkPathLength, string url, bool isFileUrl, ref bool isUncShare)
- {
- // This is the modified URL that we will return
- StringBuilder modifiedUrl = new StringBuilder(url);
-
- // ITEM 1 - remove extended path characters.
- {
- // Keep track of where we are in both the comparison and altered strings.
- int curCmpIdx = 0;
- int curModIdx = 0;
-
- // If all the '\' have already been converted to '/', just check for //?/ or //./
- if ((url.Length - curCmpIdx) >= 4 &&
- (String.Compare(url, curCmpIdx, "//?/", 0, 4, StringComparison.OrdinalIgnoreCase) == 0 ||
- String.Compare(url, curCmpIdx, "//./", 0, 4, StringComparison.OrdinalIgnoreCase) == 0))
- {
- modifiedUrl.Remove(curModIdx, 4);
- curCmpIdx += 4;
- }
- else
- {
- if (isFileUrl)
- {
- // We need to handle an indefinite number of leading front slashes for file URLs since we could
- // get something like:
- // file://\\?\
- // file:/\\?\
- // file:\\?\
- // etc...
- while (url[curCmpIdx] == '/')
- {
- curCmpIdx++;
- curModIdx++;
- }
- }
-
- // Remove the extended path characters
- if ((url.Length - curCmpIdx) >= 4 &&
- (String.Compare(url, curCmpIdx, "\\\\?\\", 0, 4, StringComparison.OrdinalIgnoreCase) == 0 ||
- String.Compare(url, curCmpIdx, "\\\\?/", 0, 4, StringComparison.OrdinalIgnoreCase) == 0 ||
- String.Compare(url, curCmpIdx, "\\\\.\\", 0, 4, StringComparison.OrdinalIgnoreCase) == 0 ||
- String.Compare(url, curCmpIdx, "\\\\./", 0, 4, StringComparison.OrdinalIgnoreCase) == 0))
- {
- modifiedUrl.Remove(curModIdx, 4);
- curCmpIdx += 4;
- }
- }
- }
-
- // ITEM 2 - convert all slashes to forward slashes, and strip leading slashes.
- if (isFileUrl)
- {
- int slashCount = 0;
- bool seenFirstBackslash = false;
-
- while (slashCount < modifiedUrl.Length && (modifiedUrl[slashCount] == '/' || modifiedUrl[slashCount] == '\\'))
- {
- // Look for sets of consecutive backslashes. We can't just look for these at the start
- // of the string, since file:// might come first. Instead, once we see the first \, look
- // for a second one following it.
- if (!seenFirstBackslash && modifiedUrl[slashCount] == '\\')
- {
- seenFirstBackslash = true;
- if (slashCount + 1 < modifiedUrl.Length && modifiedUrl[slashCount + 1] == '\\')
- isUncShare = true;
- }
-
- slashCount++;
- }
-
- modifiedUrl.Remove(0, slashCount);
- modifiedUrl.Replace('\\', '/');
- }
-
- // ITEM 3 - If the path is greater than or equal (due to terminating NULL in windows) MAX_PATH, we throw.
- if (checkPathLength)
- {
- // This needs to be a separate method to avoid hitting the static constructor on AppContextSwitches
- CheckPathTooLong(modifiedUrl);
- }
-
- // Create the result string from the StringBuilder
- return modifiedUrl.ToString();
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static void CheckPathTooLong(StringBuilder path)
- {
- if (path.Length >= (
-#if PLATFORM_UNIX
- Interop.Sys.MaxPath))
-#else
- PathInternal.MaxLongPath))
-#endif
- {
- throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Security/VerificationException.cs b/src/mscorlib/src/System/Security/VerificationException.cs
deleted file mode 100644
index 5defbd6603..0000000000
--- a/src/mscorlib/src/System/Security/VerificationException.cs
+++ /dev/null
@@ -1,32 +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.
-
-//
-
-namespace System.Security {
- using System.Security;
- using System;
- using System.Runtime.Serialization;
-
- [Serializable]
- public class VerificationException : SystemException {
- public VerificationException()
- : base(Environment.GetResourceString("Verification_Exception")) {
- SetErrorCode(__HResults.COR_E_VERIFICATION);
- }
-
- public VerificationException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_VERIFICATION);
- }
-
- public VerificationException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(__HResults.COR_E_VERIFICATION);
- }
-
- protected VerificationException(SerializationInfo info, StreamingContext context) : base(info, context) {
- }
- }
-}
diff --git a/src/mscorlib/src/System/SerializableAttribute.cs b/src/mscorlib/src/System/SerializableAttribute.cs
index 1c99654eec..266e73d78d 100644
--- a/src/mscorlib/src/System/SerializableAttribute.cs
+++ b/src/mscorlib/src/System/SerializableAttribute.cs
@@ -10,24 +10,26 @@
**
**
============================================================*/
-namespace System {
- using System;
- using System.Reflection;
+using System;
+using System.Reflection;
+namespace System
+{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false)]
- public sealed class SerializableAttribute : Attribute
+ public sealed class SerializableAttribute : Attribute
{
- internal static Attribute GetCustomAttribute(RuntimeType type)
- {
- return (type.Attributes & TypeAttributes.Serializable) == TypeAttributes.Serializable ? new SerializableAttribute() : null;
+ internal static Attribute GetCustomAttribute(RuntimeType type)
+ {
+ return (type.Attributes & TypeAttributes.Serializable) == TypeAttributes.Serializable ? new SerializableAttribute() : null;
}
- internal static bool IsDefined(RuntimeType type)
- {
- return type.IsSerializable;
+ internal static bool IsDefined(RuntimeType type)
+ {
+ return type.IsSerializable;
}
- public SerializableAttribute() {
+ public SerializableAttribute()
+ {
}
}
}
diff --git a/src/mscorlib/src/System/SharedStatics.cs b/src/mscorlib/src/System/SharedStatics.cs
index d9364335f5..a6a04d9614 100644
--- a/src/mscorlib/src/System/SharedStatics.cs
+++ b/src/mscorlib/src/System/SharedStatics.cs
@@ -11,22 +11,22 @@
**
=============================================================================*/
+using System.Threading;
+using System.Runtime.Remoting;
+using System.Security;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
namespace System
{
- using System.Threading;
- using System.Runtime.Remoting;
- using System.Security;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
internal sealed class SharedStatics
{
// this is declared static but is actually forced to be the same object
// for each AppDomain at AppDomain create time.
private static SharedStatics _sharedStatics;
-
+
// Note: Do not add any code in this ctor because it is not called
// when we set up _sharedStatics via AppDomain::SetupSharedStatics
private SharedStatics()
@@ -34,12 +34,6 @@ namespace System
BCLDebug.Assert(false, "SharedStatics..ctor() is never called.");
}
- private volatile String _Remoting_Identity_IDGuid;
-
- // Note this may not need to be process-wide.
- private int _Remoting_Identity_IDSeqNum;
-
-
// This is the total amount of memory currently "reserved" via
// all MemoryFailPoints allocated within the process.
// Stored as a long because we need to use Interlocked.Add.
@@ -48,13 +42,15 @@ namespace System
internal static long AddMemoryFailPointReservation(long size)
{
// Size can legitimately be negative - see Dispose.
- return Interlocked.Add(ref _sharedStatics._memFailPointReservedMemory, (long) size);
+ return Interlocked.Add(ref _sharedStatics._memFailPointReservedMemory, (long)size);
}
- internal static ulong MemoryFailPointReservedMemory {
- get {
+ internal static ulong MemoryFailPointReservedMemory
+ {
+ get
+ {
Debug.Assert(Volatile.Read(ref _sharedStatics._memFailPointReservedMemory) >= 0, "Process-wide MemoryFailPoint reserved memory was negative!");
- return (ulong) Volatile.Read(ref _sharedStatics._memFailPointReservedMemory);
+ return (ulong)Volatile.Read(ref _sharedStatics._memFailPointReservedMemory);
}
}
}
diff --git a/src/mscorlib/src/System/Single.cs b/src/mscorlib/src/System/Single.cs
index 657d7aef32..1c39df7d94 100644
--- a/src/mscorlib/src/System/Single.cs
+++ b/src/mscorlib/src/System/Single.cs
@@ -10,19 +10,20 @@
**
**
===========================================================*/
-namespace System {
- using System.Globalization;
- using System;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Diagnostics.Contracts;
-
-[Serializable]
-[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
+using System.Globalization;
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
+ [Serializable]
+ [System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public struct Single : IComparable, IFormattable, IConvertible
- , IComparable<Single>, IEquatable<Single>
+ , IComparable<Single>, IEquatable<Single>
{
internal float m_value;
@@ -37,33 +38,38 @@ namespace System {
public const float NaN = (float)0.0 / (float)0.0;
internal static float NegativeZero = BitConverter.Int32BitsToSingle(unchecked((int)0x80000000));
-
+
[Pure]
[System.Runtime.Versioning.NonVersionable]
- public unsafe static bool IsInfinity(float f) {
+ public unsafe static bool IsInfinity(float f)
+ {
return (*(int*)(&f) & 0x7FFFFFFF) == 0x7F800000;
}
[Pure]
[System.Runtime.Versioning.NonVersionable]
- public unsafe static bool IsPositiveInfinity(float f) {
+ public unsafe static bool IsPositiveInfinity(float f)
+ {
return *(int*)(&f) == 0x7F800000;
}
[Pure]
[System.Runtime.Versioning.NonVersionable]
- public unsafe static bool IsNegativeInfinity(float f) {
+ public unsafe static bool IsNegativeInfinity(float f)
+ {
return *(int*)(&f) == unchecked((int)0xFF800000);
}
[Pure]
[System.Runtime.Versioning.NonVersionable]
- public unsafe static bool IsNaN(float f) {
+ public unsafe static bool IsNaN(float f)
+ {
return (*(int*)(&f) & 0x7FFFFFFF) > 0x7F800000;
}
-
+
[Pure]
- internal unsafe static bool IsNegative(float f) {
+ internal unsafe static bool IsNegative(float f)
+ {
return (*(uint*)(&f) & 0x80000000) == 0x80000000;
}
@@ -73,11 +79,14 @@ namespace System {
// null is considered to be less than any instance.
// If object is not of type Single, this method throws an ArgumentException.
//
- public int CompareTo(Object value) {
- if (value == null) {
+ public int CompareTo(Object value)
+ {
+ if (value == null)
+ {
return 1;
}
- if (value is Single) {
+ if (value is Single)
+ {
float f = (float)value;
if (m_value < f) return -1;
if (m_value > f) return 1;
@@ -89,11 +98,12 @@ namespace System {
else // f is NaN.
return 1;
}
- throw new ArgumentException (Environment.GetResourceString("Arg_MustBeSingle"));
+ throw new ArgumentException(SR.Arg_MustBeSingle);
}
- public int CompareTo(Single value) {
+ public int CompareTo(Single value)
+ {
if (m_value < value) return -1;
if (m_value > value) return 1;
if (m_value == value) return 0;
@@ -106,41 +116,50 @@ namespace System {
}
[System.Runtime.Versioning.NonVersionable]
- public static bool operator ==(Single left, Single right) {
+ public static bool operator ==(Single left, Single right)
+ {
return left == right;
}
[System.Runtime.Versioning.NonVersionable]
- public static bool operator !=(Single left, Single right) {
+ public static bool operator !=(Single left, Single right)
+ {
return left != right;
}
[System.Runtime.Versioning.NonVersionable]
- public static bool operator <(Single left, Single right) {
+ public static bool operator <(Single left, Single right)
+ {
return left < right;
}
[System.Runtime.Versioning.NonVersionable]
- public static bool operator >(Single left, Single right) {
+ public static bool operator >(Single left, Single right)
+ {
return left > right;
}
[System.Runtime.Versioning.NonVersionable]
- public static bool operator <=(Single left, Single right) {
+ public static bool operator <=(Single left, Single right)
+ {
return left <= right;
}
[System.Runtime.Versioning.NonVersionable]
- public static bool operator >=(Single left, Single right) {
+ public static bool operator >=(Single left, Single right)
+ {
return left >= right;
}
- public override bool Equals(Object obj) {
- if (!(obj is Single)) {
+ public override bool Equals(Object obj)
+ {
+ if (!(obj is Single))
+ {
return false;
}
float temp = ((Single)obj).m_value;
- if (temp == m_value) {
+ if (temp == m_value)
+ {
return true;
}
@@ -149,16 +168,19 @@ namespace System {
public bool Equals(Single obj)
{
- if (obj == m_value) {
+ if (obj == m_value)
+ {
return true;
}
return IsNaN(obj) && IsNaN(m_value);
}
- public unsafe override int GetHashCode() {
+ public unsafe override int GetHashCode()
+ {
float f = m_value;
- if (f == 0) {
+ if (f == 0)
+ {
// Ensure that 0 and -0 have the same hash code
return 0;
}
@@ -166,22 +188,26 @@ namespace System {
return v;
}
- public override String ToString() {
+ public override String ToString()
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatSingle(m_value, null, NumberFormatInfo.CurrentInfo);
}
- public String ToString(IFormatProvider provider) {
+ public String ToString(IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatSingle(m_value, null, NumberFormatInfo.GetInstance(provider));
}
- public String ToString(String format) {
+ public String ToString(String format)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatSingle(m_value, format, NumberFormatInfo.CurrentInfo);
}
- public String ToString(String format, IFormatProvider provider) {
+ public String ToString(String format, IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatSingle(m_value, format, NumberFormatInfo.GetInstance(provider));
}
@@ -194,139 +220,155 @@ namespace System {
// PositiveInfinity or NegativeInfinity for a number that is too
// large or too small.
//
- public static float Parse(String s) {
+ public static float Parse(String s)
+ {
return Parse(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo);
}
- public static float Parse(String s, NumberStyles style) {
+ public static float Parse(String s, NumberStyles style)
+ {
NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
return Parse(s, style, NumberFormatInfo.CurrentInfo);
}
- public static float Parse(String s, IFormatProvider provider) {
+ public static float Parse(String s, IFormatProvider provider)
+ {
return Parse(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.GetInstance(provider));
}
- public static float Parse(String s, NumberStyles style, IFormatProvider provider) {
+ public static float Parse(String s, NumberStyles style, IFormatProvider provider)
+ {
NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
return Parse(s, style, NumberFormatInfo.GetInstance(provider));
}
-
- private static float Parse(String s, NumberStyles style, NumberFormatInfo info) {
+
+ private static float Parse(String s, NumberStyles style, NumberFormatInfo info)
+ {
return Number.ParseSingle(s, style, info);
}
- public static Boolean TryParse(String s, out Single result) {
+ public static Boolean TryParse(String s, out Single result)
+ {
return TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo, out result);
}
- public static Boolean TryParse(String s, NumberStyles style, IFormatProvider provider, out Single result) {
+ public static Boolean TryParse(String s, NumberStyles style, IFormatProvider provider, out Single result)
+ {
NumberFormatInfo.ValidateParseStyleFloatingPoint(style);
return TryParse(s, style, NumberFormatInfo.GetInstance(provider), out result);
}
-
- private static Boolean TryParse(String s, NumberStyles style, NumberFormatInfo info, out Single result) {
- if (s == null) {
+
+ private static Boolean TryParse(String s, NumberStyles style, NumberFormatInfo info, out Single result)
+ {
+ if (s == null)
+ {
result = 0;
return false;
}
bool success = Number.TryParseSingle(s, style, info, out result);
- if (!success) {
+ if (!success)
+ {
String sTrim = s.Trim();
- if (sTrim.Equals(info.PositiveInfinitySymbol)) {
+ if (sTrim.Equals(info.PositiveInfinitySymbol))
+ {
result = PositiveInfinity;
- } else if (sTrim.Equals(info.NegativeInfinitySymbol)) {
+ }
+ else if (sTrim.Equals(info.NegativeInfinitySymbol))
+ {
result = NegativeInfinity;
- } else if (sTrim.Equals(info.NaNSymbol)) {
+ }
+ else if (sTrim.Equals(info.NaNSymbol))
+ {
result = NaN;
- } else
+ }
+ else
return false; // We really failed
}
return true;
-
}
//
// IConvertible implementation
//
- public TypeCode GetTypeCode() {
+ public TypeCode GetTypeCode()
+ {
return TypeCode.Single;
}
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
return Convert.ToBoolean(m_value);
}
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Single", "Char"));
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Single", "Char"));
}
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
return Convert.ToSByte(m_value);
}
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
return Convert.ToByte(m_value);
}
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
return Convert.ToInt16(m_value);
}
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
return Convert.ToUInt16(m_value);
}
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
return Convert.ToInt32(m_value);
}
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
return Convert.ToUInt32(m_value);
}
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
return Convert.ToInt64(m_value);
}
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
return Convert.ToUInt64(m_value);
}
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
return m_value;
}
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
return Convert.ToDouble(m_value);
}
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider) {
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
return Convert.ToDecimal(m_value);
}
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "Single", "DateTime"));
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "Single", "DateTime"));
}
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
return Convert.DefaultToType((IConvertible)this, type, provider);
}
}
diff --git a/src/mscorlib/src/System/Span.cs b/src/mscorlib/src/System/Span.cs
index c77a1994c9..4211083def 100644
--- a/src/mscorlib/src/System/Span.cs
+++ b/src/mscorlib/src/System/Span.cs
@@ -3,12 +3,20 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
+using System.Runtime;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using EditorBrowsableState = System.ComponentModel.EditorBrowsableState;
using EditorBrowsableAttribute = System.ComponentModel.EditorBrowsableAttribute;
#pragma warning disable 0809 //warning CS0809: Obsolete member 'Span<T>.Equals(object)' overrides non-obsolete member 'object.Equals(object)'
+#if BIT64
+using nuint = System.UInt64;
+#else
+using nuint = System.UInt32;
+#endif
+
namespace System
{
/// <summary>
@@ -112,7 +120,7 @@ namespace System
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe Span(void* pointer, int length)
{
- if (JitHelpers.ContainsReferences<T>())
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T));
if (length < 0)
ThrowHelper.ThrowArgumentOutOfRangeException();
@@ -123,28 +131,15 @@ namespace System
/// <summary>
/// Create a new span over a portion of a regular managed object. This can be useful
- /// if part of a managed object represents a "fixed array." This is dangerous because
- /// "length" is not checked, nor is the fact that "rawPointer" actually lies within the object.
+ /// if part of a managed object represents a "fixed array." This is dangerous because neither the
+ /// <paramref name="length"/> is checked, nor <paramref name="obj"/> being null, nor the fact that
+ /// "rawPointer" actually lies within <paramref name="obj"/>.
/// </summary>
/// <param name="obj">The managed object that contains the data to span over.</param>
/// <param name="objectData">A reference to data within that object.</param>
/// <param name="length">The number of <typeparamref name="T"/> elements the memory contains.</param>
- /// <exception cref="System.ArgumentNullException">
- /// Thrown when the specified object is null.
- /// </exception>
- /// <exception cref="System.ArgumentOutOfRangeException">
- /// Thrown when the specified <paramref name="length"/> is negative.
- /// </exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Span<T> DangerousCreate(object obj, ref T objectData, int length)
- {
- if (obj == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.obj);
- if (length < 0)
- ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length);
-
- return new Span<T>(ref objectData, length);
- }
+ public static Span<T> DangerousCreate(object obj, ref T objectData, int length) => new Span<T>(ref objectData, length);
// Constructor for internal use only.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -183,11 +178,7 @@ namespace System
/// <exception cref="System.IndexOutOfRangeException">
/// Thrown when index less than 0 or index greater than or equal to Length
/// </exception>
-
- // TODO: https://github.com/dotnet/corefx/issues/13681
- // Until we get over the hurdle of C# 7 tooling, this indexer will return "T" and have a setter rather than a "ref T". (The doc comments
- // continue to reflect the original intent of returning "ref T")
- public T this[int index]
+ public ref T this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
@@ -195,49 +186,23 @@ namespace System
if ((uint)index >= (uint)_length)
ThrowHelper.ThrowIndexOutOfRangeException();
- return Unsafe.Add(ref _pointer.Value, index);
- }
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- set
- {
- if ((uint)index >= (uint)_length)
- ThrowHelper.ThrowIndexOutOfRangeException();
-
- Unsafe.Add(ref _pointer.Value, index) = value;
+ return ref Unsafe.Add(ref _pointer.Value, index);
}
}
/// <summary>
- /// Returns a reference to specified element of the Span.
- /// </summary>
- /// <param name="index"></param>
- /// <returns></returns>
- /// <exception cref="System.IndexOutOfRangeException">
- /// Thrown when index less than 0 or index greater than or equal to Length
- /// </exception>
-
- // TODO: https://github.com/dotnet/corefx/issues/13681
- // Until we get over the hurdle of C# 7 tooling, this temporary method will simulate the intended "ref T" indexer for those
- // who need bypass the workaround for performance.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public ref T GetItem(int index)
- {
- if ((uint)index >= ((uint)_length))
- ThrowHelper.ThrowIndexOutOfRangeException();
-
- return ref Unsafe.Add(ref _pointer.Value, index);
- }
-
- /// <summary>
/// Clears the contents of this span.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Clear()
{
- // TODO: Optimize - https://github.com/dotnet/coreclr/issues/9161
- for (int i = 0; i < _length; i++)
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
+ {
+ SpanHelper.ClearWithReferences(ref Unsafe.As<T, IntPtr>(ref _pointer.Value), (nuint)_length * (nuint)(Unsafe.SizeOf<T>() / sizeof(nuint)));
+ }
+ else
{
- this[i] = default(T);
+ SpanHelper.ClearWithoutReferences(ref Unsafe.As<T, byte>(ref _pointer.Value), (nuint)_length * (nuint)Unsafe.SizeOf<T>());
}
}
@@ -246,47 +211,50 @@ namespace System
/// </summary>
public void Fill(T value)
{
- int length = _length;
-
- if (length == 0)
- return;
-
if (Unsafe.SizeOf<T>() == 1)
{
- byte fill = Unsafe.As<T, byte>(ref value);
- ref byte r = ref Unsafe.As<T, byte>(ref _pointer.Value);
- Unsafe.InitBlockUnaligned(ref r, fill, (uint)length);
+ uint length = (uint)_length;
+ if (length == 0)
+ return;
+
+ T tmp = value; // Avoid taking address of the "value" argument. It would regress performance of the loop below.
+ Unsafe.InitBlockUnaligned(ref Unsafe.As<T, byte>(ref _pointer.Value), Unsafe.As<T, byte>(ref tmp), length);
}
else
{
+ // Do all math as nuint to avoid unnecessary 64->32->64 bit integer truncations
+ nuint length = (uint)_length;
+ if (length == 0)
+ return;
+
ref T r = ref DangerousGetPinnableReference();
// TODO: Create block fill for value types of power of two sizes e.g. 2,4,8,16
- // Simple loop unrolling
- int i = 0;
- for (; i < (length & ~7); i += 8)
+ nuint elementSize = (uint)Unsafe.SizeOf<T>();
+ nuint i = 0;
+ for (; i < (length & ~(nuint)7); i += 8)
{
- Unsafe.Add<T>(ref r, i + 0) = value;
- Unsafe.Add<T>(ref r, i + 1) = value;
- Unsafe.Add<T>(ref r, i + 2) = value;
- Unsafe.Add<T>(ref r, i + 3) = value;
- Unsafe.Add<T>(ref r, i + 4) = value;
- Unsafe.Add<T>(ref r, i + 5) = value;
- Unsafe.Add<T>(ref r, i + 6) = value;
- Unsafe.Add<T>(ref r, i + 7) = value;
+ Unsafe.AddByteOffset<T>(ref r, (i + 0) * elementSize) = value;
+ Unsafe.AddByteOffset<T>(ref r, (i + 1) * elementSize) = value;
+ Unsafe.AddByteOffset<T>(ref r, (i + 2) * elementSize) = value;
+ Unsafe.AddByteOffset<T>(ref r, (i + 3) * elementSize) = value;
+ Unsafe.AddByteOffset<T>(ref r, (i + 4) * elementSize) = value;
+ Unsafe.AddByteOffset<T>(ref r, (i + 5) * elementSize) = value;
+ Unsafe.AddByteOffset<T>(ref r, (i + 6) * elementSize) = value;
+ Unsafe.AddByteOffset<T>(ref r, (i + 7) * elementSize) = value;
}
- if (i < (length & ~3))
+ if (i < (length & ~(nuint)3))
{
- Unsafe.Add<T>(ref r, i + 0) = value;
- Unsafe.Add<T>(ref r, i + 1) = value;
- Unsafe.Add<T>(ref r, i + 2) = value;
- Unsafe.Add<T>(ref r, i + 3) = value;
+ Unsafe.AddByteOffset<T>(ref r, (i + 0) * elementSize) = value;
+ Unsafe.AddByteOffset<T>(ref r, (i + 1) * elementSize) = value;
+ Unsafe.AddByteOffset<T>(ref r, (i + 2) * elementSize) = value;
+ Unsafe.AddByteOffset<T>(ref r, (i + 3) * elementSize) = value;
i += 4;
}
for (; i < length; i++)
{
- Unsafe.Add<T>(ref r, i) = value;
+ Unsafe.AddByteOffset<T>(ref r, i * elementSize) = value;
}
}
}
@@ -348,9 +316,7 @@ namespace System
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj)
{
- ThrowHelper.ThrowNotSupportedException_CannotCallEqualsOnSpan();
- // Prevent compiler error CS0161: 'Span<T>.Equals(object)': not all code paths return a value
- return default(bool);
+ throw new NotSupportedException(SR.NotSupported_CannotCallEqualsOnSpan);
}
/// <summary>
@@ -363,9 +329,7 @@ namespace System
[EditorBrowsable(EditorBrowsableState.Never)]
public override int GetHashCode()
{
- ThrowHelper.ThrowNotSupportedException_CannotCallGetHashCodeOnSpan();
- // Prevent compiler error CS0161: 'Span<T>.GetHashCode()': not all code paths return a value
- return default(int);
+ throw new NotSupportedException(SR.NotSupported_CannotCallGetHashCodeOnSpan);
}
/// <summary>
@@ -448,10 +412,11 @@ namespace System
/// <exception cref="System.ArgumentException">
/// Thrown when <typeparamref name="T"/> contains pointers.
/// </exception>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Span<byte> AsBytes<T>(this Span<T> source)
where T : struct
{
- if (JitHelpers.ContainsReferences<T>())
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T));
return new Span<byte>(
@@ -467,10 +432,11 @@ namespace System
/// <exception cref="System.ArgumentException">
/// Thrown when <typeparamref name="T"/> contains pointers.
/// </exception>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ReadOnlySpan<byte> AsBytes<T>(this ReadOnlySpan<T> source)
where T : struct
{
- if (JitHelpers.ContainsReferences<T>())
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T));
return new ReadOnlySpan<byte>(
@@ -489,13 +455,14 @@ namespace System
/// <exception cref="System.ArgumentException">
/// Thrown when <typeparamref name="TFrom"/> or <typeparamref name="TTo"/> contains pointers.
/// </exception>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Span<TTo> NonPortableCast<TFrom, TTo>(this Span<TFrom> source)
where TFrom : struct
where TTo : struct
{
- if (JitHelpers.ContainsReferences<TFrom>())
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<TFrom>())
ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TFrom));
- if (JitHelpers.ContainsReferences<TTo>())
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<TTo>())
ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TTo));
return new Span<TTo>(
@@ -514,13 +481,14 @@ namespace System
/// <exception cref="System.ArgumentException">
/// Thrown when <typeparamref name="TFrom"/> or <typeparamref name="TTo"/> contains pointers.
/// </exception>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ReadOnlySpan<TTo> NonPortableCast<TFrom, TTo>(this ReadOnlySpan<TFrom> source)
where TFrom : struct
where TTo : struct
{
- if (JitHelpers.ContainsReferences<TFrom>())
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<TFrom>())
ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TFrom));
- if (JitHelpers.ContainsReferences<TTo>())
+ if (RuntimeHelpers.IsReferenceOrContainsReferences<TTo>())
ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TTo));
return new ReadOnlySpan<TTo>(
@@ -535,94 +503,407 @@ namespace System
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null
/// reference (Nothing in Visual Basic).</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlySpan<char> Slice(this string text)
+ public static ReadOnlySpan<char> AsSpan(this string text)
{
if (text == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
return new ReadOnlySpan<char>(ref text.GetFirstCharRef(), text.Length);
}
-
- /// <summary>
- /// Creates a new readonly span over the portion of the target string, beginning at 'start'.
- /// </summary>
- /// <param name="text">The target string.</param>
- /// <param name="start">The index at which to begin this slice.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null
- /// reference (Nothing in Visual Basic).</exception>
- /// <exception cref="System.ArgumentOutOfRangeException">
- /// Thrown when the specified <paramref name="start"/> index is not in range (&lt;0 or &gt;Length).
- /// </exception>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlySpan<char> Slice(this string text, int start)
- {
- if (text == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
- if ((uint)start > (uint)text.Length)
- ThrowHelper.ThrowArgumentOutOfRangeException();
-
- return new ReadOnlySpan<char>(ref Unsafe.Add(ref text.GetFirstCharRef(), start), text.Length - start);
- }
-
- /// <summary>
- /// Creates a new readonly span over the portion of the target string, beginning at <paramref name="start"/>, of given <paramref name="length"/>.
- /// </summary>
- /// <param name="text">The target string.</param>
- /// <param name="start">The index at which to begin this slice.</param>
- /// <param name="length">The number of items in the span.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null
- /// reference (Nothing in Visual Basic).</exception>
- /// <exception cref="System.ArgumentOutOfRangeException">
- /// Thrown when the specified <paramref name="start"/> or end index is not in range (&lt;0 or &gt;&eq;Length).
- /// </exception>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlySpan<char> Slice(this string text, int start, int length)
- {
- if (text == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
- if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
- ThrowHelper.ThrowArgumentOutOfRangeException();
-
- return new ReadOnlySpan<char>(ref Unsafe.Add(ref text.GetFirstCharRef(), start), length);
- }
}
internal static class SpanHelper
{
internal static unsafe void CopyTo<T>(ref T destination, ref T source, int elementsCount)
{
- if (elementsCount == 0)
+ if (Unsafe.AreSame(ref destination, ref source))
return;
- if (Unsafe.AreSame(ref destination, ref source))
+ if (elementsCount <= 1)
+ {
+ if (elementsCount == 1)
+ {
+ destination = source;
+ }
return;
+ }
- if (!JitHelpers.ContainsReferences<T>())
+ nuint byteCount = (nuint)elementsCount * (nuint)Unsafe.SizeOf<T>();
+ if (!RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
fixed (byte* pDestination = &Unsafe.As<T, byte>(ref destination))
{
fixed (byte* pSource = &Unsafe.As<T, byte>(ref source))
{
-#if BIT64
- Buffer.Memmove(pDestination, pSource, (ulong)elementsCount * (ulong)Unsafe.SizeOf<T>());
-#else
- Buffer.Memmove(pDestination, pSource, (uint)elementsCount * (uint)Unsafe.SizeOf<T>());
-#endif
+ Buffer.Memmove(pDestination, pSource, byteCount);
}
}
}
else
{
- if (JitHelpers.ByRefLessThan(ref destination, ref source)) // copy forward
- {
- for (int i = 0; i < elementsCount; i++)
- Unsafe.Add(ref destination, i) = Unsafe.Add(ref source, i);
- }
- else // copy backward to avoid overlapping issues
+ RuntimeImports.RhBulkMoveWithWriteBarrier(
+ ref Unsafe.As<T, byte>(ref destination),
+ ref Unsafe.As<T, byte>(ref source),
+ byteCount);
+ }
+ }
+
+ internal static unsafe void ClearWithoutReferences(ref byte b, nuint byteLength)
+ {
+ if (byteLength == 0)
+ return;
+
+#if AMD64
+ if (byteLength > 4096) goto PInvoke;
+ Unsafe.InitBlockUnaligned(ref b, 0, (uint)byteLength);
+ return;
+#else // AMD64
+ // TODO: Optimize this method on X86 machine
+ // Note: It's important that this switch handles lengths at least up to 22.
+ // See notes below near the main loop for why.
+
+ // The switch will be very fast since it can be implemented using a jump
+ // table in assembly. See http://stackoverflow.com/a/449297/4077294 for more info.
+
+ switch (byteLength)
+ {
+ case 1:
+ b = 0;
+ return;
+ case 2:
+ Unsafe.As<byte, short>(ref b) = 0;
+ return;
+ case 3:
+ Unsafe.As<byte, short>(ref b) = 0;
+ Unsafe.Add<byte>(ref b, 2) = 0;
+ return;
+ case 4:
+ Unsafe.As<byte, int>(ref b) = 0;
+ return;
+ case 5:
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.Add<byte>(ref b, 4) = 0;
+ return;
+ case 6:
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, short>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+ return;
+ case 7:
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, short>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+ Unsafe.Add<byte>(ref b, 6) = 0;
+ return;
+ case 8:
+#if BIT64
+ Unsafe.As<byte, long>(ref b) = 0;
+#else
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+#endif
+ return;
+ case 9:
+#if BIT64
+ Unsafe.As<byte, long>(ref b) = 0;
+#else
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+#endif
+ Unsafe.Add<byte>(ref b, 8) = 0;
+ return;
+ case 10:
+#if BIT64
+ Unsafe.As<byte, long>(ref b) = 0;
+#else
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+#endif
+ Unsafe.As<byte, short>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+ return;
+ case 11:
+#if BIT64
+ Unsafe.As<byte, long>(ref b) = 0;
+#else
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+#endif
+ Unsafe.As<byte, short>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+ Unsafe.Add<byte>(ref b, 10) = 0;
+ return;
+ case 12:
+#if BIT64
+ Unsafe.As<byte, long>(ref b) = 0;
+#else
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+#endif
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+ return;
+ case 13:
+#if BIT64
+ Unsafe.As<byte, long>(ref b) = 0;
+#else
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+#endif
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+ Unsafe.Add<byte>(ref b, 12) = 0;
+ return;
+ case 14:
+#if BIT64
+ Unsafe.As<byte, long>(ref b) = 0;
+#else
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+#endif
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+ Unsafe.As<byte, short>(ref Unsafe.Add<byte>(ref b, 12)) = 0;
+ return;
+ case 15:
+#if BIT64
+ Unsafe.As<byte, long>(ref b) = 0;
+#else
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+#endif
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+ Unsafe.As<byte, short>(ref Unsafe.Add<byte>(ref b, 12)) = 0;
+ Unsafe.Add<byte>(ref b, 14) = 0;
+ return;
+ case 16:
+#if BIT64
+ Unsafe.As<byte, long>(ref b) = 0;
+ Unsafe.As<byte, long>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+#else
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 12)) = 0;
+#endif
+ return;
+ case 17:
+#if BIT64
+ Unsafe.As<byte, long>(ref b) = 0;
+ Unsafe.As<byte, long>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+#else
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 12)) = 0;
+#endif
+ Unsafe.Add<byte>(ref b, 16) = 0;
+ return;
+ case 18:
+#if BIT64
+ Unsafe.As<byte, long>(ref b) = 0;
+ Unsafe.As<byte, long>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+#else
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 12)) = 0;
+#endif
+ Unsafe.As<byte, short>(ref Unsafe.Add<byte>(ref b, 16)) = 0;
+ return;
+ case 19:
+#if BIT64
+ Unsafe.As<byte, long>(ref b) = 0;
+ Unsafe.As<byte, long>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+#else
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 12)) = 0;
+#endif
+ Unsafe.As<byte, short>(ref Unsafe.Add<byte>(ref b, 16)) = 0;
+ Unsafe.Add<byte>(ref b, 18) = 0;
+ return;
+ case 20:
+#if BIT64
+ Unsafe.As<byte, long>(ref b) = 0;
+ Unsafe.As<byte, long>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+#else
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 12)) = 0;
+#endif
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 16)) = 0;
+ return;
+ case 21:
+#if BIT64
+ Unsafe.As<byte, long>(ref b) = 0;
+ Unsafe.As<byte, long>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+#else
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 12)) = 0;
+#endif
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 16)) = 0;
+ Unsafe.Add<byte>(ref b, 20) = 0;
+ return;
+ case 22:
+#if BIT64
+ Unsafe.As<byte, long>(ref b) = 0;
+ Unsafe.As<byte, long>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+#else
+ Unsafe.As<byte, int>(ref b) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 4)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 8)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 12)) = 0;
+#endif
+ Unsafe.As<byte, int>(ref Unsafe.Add<byte>(ref b, 16)) = 0;
+ Unsafe.As<byte, short>(ref Unsafe.Add<byte>(ref b, 20)) = 0;
+ return;
+ }
+
+ // P/Invoke into the native version for large lengths
+ if (byteLength >= 512) goto PInvoke;
+
+ nuint i = 0; // byte offset at which we're copying
+
+ if ((Unsafe.As<byte, int>(ref b) & 3) != 0)
+ {
+ if ((Unsafe.As<byte, int>(ref b) & 1) != 0)
{
- for (int i = elementsCount - 1; i >= 0; i--)
- Unsafe.Add(ref destination, i) = Unsafe.Add(ref source, i);
+ Unsafe.AddByteOffset<byte>(ref b, i) = 0;
+ i += 1;
+ if ((Unsafe.As<byte, int>(ref b) & 2) != 0)
+ goto IntAligned;
}
+ Unsafe.As<byte, short>(ref Unsafe.AddByteOffset<byte>(ref b, i)) = 0;
+ i += 2;
+ }
+
+ IntAligned:
+
+ // On 64-bit IntPtr.Size == 8, so we want to advance to the next 8-aligned address. If
+ // (int)b % 8 is 0, 5, 6, or 7, we will already have advanced by 0, 3, 2, or 1
+ // bytes to the next aligned address (respectively), so do nothing. On the other hand,
+ // if it is 1, 2, 3, or 4 we will want to copy-and-advance another 4 bytes until
+ // we're aligned.
+ // The thing 1, 2, 3, and 4 have in common that the others don't is that if you
+ // subtract one from them, their 3rd lsb will not be set. Hence, the below check.
+
+ if (((Unsafe.As<byte, int>(ref b) - 1) & 4) == 0)
+ {
+ Unsafe.As<byte, int>(ref Unsafe.AddByteOffset<byte>(ref b, i)) = 0;
+ i += 4;
+ }
+
+ nuint end = byteLength - 16;
+ byteLength -= i; // lower 4 bits of byteLength represent how many bytes are left *after* the unrolled loop
+
+ // We know due to the above switch-case that this loop will always run 1 iteration; max
+ // bytes we clear before checking is 23 (7 to align the pointers, 16 for 1 iteration) so
+ // the switch handles lengths 0-22.
+ Debug.Assert(end >= 7 && i <= end);
+
+ // This is separated out into a different variable, so the i + 16 addition can be
+ // performed at the start of the pipeline and the loop condition does not have
+ // a dependency on the writes.
+ nuint counter;
+
+ do
+ {
+ counter = i + 16;
+
+ // This loop looks very costly since there appear to be a bunch of temporary values
+ // being created with the adds, but the jit (for x86 anyways) will convert each of
+ // these to use memory addressing operands.
+
+ // So the only cost is a bit of code size, which is made up for by the fact that
+ // we save on writes to b.
+
+#if BIT64
+ Unsafe.As<byte, long>(ref Unsafe.AddByteOffset<byte>(ref b, i)) = 0;
+ Unsafe.As<byte, long>(ref Unsafe.AddByteOffset<byte>(ref b, i + 8)) = 0;
+#else
+ Unsafe.As<byte, int>(ref Unsafe.AddByteOffset<byte>(ref b, i)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.AddByteOffset<byte>(ref b, i + 4)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.AddByteOffset<byte>(ref b, i + 8)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.AddByteOffset<byte>(ref b, i + 12)) = 0;
+#endif
+
+ i = counter;
+
+ // See notes above for why this wasn't used instead
+ // i += 16;
+ }
+ while (counter <= end);
+
+ if ((byteLength & 8) != 0)
+ {
+#if BIT64
+ Unsafe.As<byte, long>(ref Unsafe.AddByteOffset<byte>(ref b, i)) = 0;
+#else
+ Unsafe.As<byte, int>(ref Unsafe.AddByteOffset<byte>(ref b, i)) = 0;
+ Unsafe.As<byte, int>(ref Unsafe.AddByteOffset<byte>(ref b, i + 4)) = 0;
+#endif
+ i += 8;
+ }
+ if ((byteLength & 4) != 0)
+ {
+ Unsafe.As<byte, int>(ref Unsafe.AddByteOffset<byte>(ref b, i)) = 0;
+ i += 4;
+ }
+ if ((byteLength & 2) != 0)
+ {
+ Unsafe.As<byte, short>(ref Unsafe.AddByteOffset<byte>(ref b, i)) = 0;
+ i += 2;
+ }
+ if ((byteLength & 1) != 0)
+ {
+ Unsafe.AddByteOffset<byte>(ref b, i) = 0;
+ // We're not using i after this, so not needed
+ // i += 1;
+ }
+
+ return;
+#endif // AMD64
+
+ PInvoke:
+ RuntimeImports.RhZeroMemory(ref b, byteLength);
+ }
+
+ internal static unsafe void ClearWithReferences(ref IntPtr ip, nuint pointerSizeLength)
+ {
+ if (pointerSizeLength == 0)
+ return;
+
+ // TODO: Perhaps do switch casing to improve small size perf
+
+ nuint i = 0;
+ nuint n = 0;
+ while ((n = i + 8) <= (pointerSizeLength))
+ {
+ Unsafe.AddByteOffset<IntPtr>(ref ip, (i + 0) * (nuint)sizeof(IntPtr)) = default(IntPtr);
+ Unsafe.AddByteOffset<IntPtr>(ref ip, (i + 1) * (nuint)sizeof(IntPtr)) = default(IntPtr);
+ Unsafe.AddByteOffset<IntPtr>(ref ip, (i + 2) * (nuint)sizeof(IntPtr)) = default(IntPtr);
+ Unsafe.AddByteOffset<IntPtr>(ref ip, (i + 3) * (nuint)sizeof(IntPtr)) = default(IntPtr);
+ Unsafe.AddByteOffset<IntPtr>(ref ip, (i + 4) * (nuint)sizeof(IntPtr)) = default(IntPtr);
+ Unsafe.AddByteOffset<IntPtr>(ref ip, (i + 5) * (nuint)sizeof(IntPtr)) = default(IntPtr);
+ Unsafe.AddByteOffset<IntPtr>(ref ip, (i + 6) * (nuint)sizeof(IntPtr)) = default(IntPtr);
+ Unsafe.AddByteOffset<IntPtr>(ref ip, (i + 7) * (nuint)sizeof(IntPtr)) = default(IntPtr);
+ i = n;
+ }
+ if ((n = i + 4) <= (pointerSizeLength))
+ {
+ Unsafe.AddByteOffset<IntPtr>(ref ip, (i + 0) * (nuint)sizeof(IntPtr)) = default(IntPtr);
+ Unsafe.AddByteOffset<IntPtr>(ref ip, (i + 1) * (nuint)sizeof(IntPtr)) = default(IntPtr);
+ Unsafe.AddByteOffset<IntPtr>(ref ip, (i + 2) * (nuint)sizeof(IntPtr)) = default(IntPtr);
+ Unsafe.AddByteOffset<IntPtr>(ref ip, (i + 3) * (nuint)sizeof(IntPtr)) = default(IntPtr);
+ i = n;
+ }
+ if ((n = i + 2) <= (pointerSizeLength))
+ {
+ Unsafe.AddByteOffset<IntPtr>(ref ip, (i + 0) * (nuint)sizeof(IntPtr)) = default(IntPtr);
+ Unsafe.AddByteOffset<IntPtr>(ref ip, (i + 1) * (nuint)sizeof(IntPtr)) = default(IntPtr);
+ i = n;
+ }
+ if ((i + 1) <= (pointerSizeLength))
+ {
+ Unsafe.AddByteOffset<IntPtr>(ref ip, (i + 0) * (nuint)sizeof(IntPtr)) = default(IntPtr);
}
}
}
diff --git a/src/mscorlib/src/System/String.Comparison.cs b/src/mscorlib/src/System/String.Comparison.cs
index 2ac1d78997..c2c3a8709a 100644
--- a/src/mscorlib/src/System/String.Comparison.cs
+++ b/src/mscorlib/src/System/String.Comparison.cs
@@ -24,16 +24,17 @@ namespace System
Contract.Requires(strB != null);
Contract.EndContractBlock();
int length = Math.Min(strA.Length, strB.Length);
-
+
fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar)
{
char* a = ap;
char* b = bp;
+ int charA = 0, charB = 0;
- while (length != 0)
+ while (length != 0)
{
- int charA = *a;
- int charB = *b;
+ charA = *a;
+ charB = *b;
Debug.Assert((charA | charB) <= 0x7F, "strings have to be ASCII");
@@ -43,7 +44,7 @@ namespace System
//Return the (case-insensitive) difference between them.
if (charA != charB)
- return charA - charB;
+ goto ReturnCharAMinusCharB; // TODO: Workaround for https://github.com/dotnet/coreclr/issues/9692
// Next char
a++; b++;
@@ -51,6 +52,9 @@ namespace System
}
return strA.Length - strB.Length;
+
+ ReturnCharAMinusCharB:
+ return charA - charB;
}
}
@@ -61,14 +65,14 @@ namespace System
//This will not work in case-insensitive mode for any character greater than 0x80.
//We'll throw an ArgumentException.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe internal static extern int nativeCompareOrdinalIgnoreCaseWC(String strA, sbyte *strBBytes);
+ unsafe internal static extern int nativeCompareOrdinalIgnoreCaseWC(String strA, sbyte* strBBytes);
//
//
// NATIVE INSTANCE METHODS
//
//
-
+
//
// Search/Query methods
//
@@ -120,7 +124,7 @@ namespace System
// always zero terminated and that the terminating zero is not included
// in the length. For odd string sizes, the last compare will include
// the zero terminator.
- while (length > 0)
+ while (length > 0)
{
if (*(int*)a != *(int*)b) goto ReturnFalse;
length -= 2; a += 2; b += 2;
@@ -128,7 +132,49 @@ namespace System
return true;
- ReturnFalse:
+ ReturnFalse:
+ return false;
+ }
+ }
+
+ private unsafe static bool EqualsIgnoreCaseAsciiHelper(String strA, String strB)
+ {
+ Contract.Requires(strA != null);
+ Contract.Requires(strB != null);
+ Contract.Requires(strA.Length == strB.Length);
+ Contract.EndContractBlock();
+ int length = strA.Length;
+
+ fixed (char* ap = &strA.m_firstChar) fixed (char* bp = &strB.m_firstChar)
+ {
+ char* a = ap;
+ char* b = bp;
+
+ while (length != 0)
+ {
+ int charA = *a;
+ int charB = *b;
+
+ Debug.Assert((charA | charB) <= 0x7F, "strings have to be ASCII");
+
+ // Ordinal equals or lowercase equals if the result ends up in the a-z range
+ if (charA == charB ||
+ ((charA | 0x20) == (charB | 0x20) &&
+ (uint)((charA | 0x20) - 'a') <= (uint)('z' - 'a')))
+ {
+ a++;
+ b++;
+ length--;
+ }
+ else
+ {
+ goto ReturnFalse;
+ }
+ }
+
+ return true;
+
+ ReturnFalse:
return false;
}
}
@@ -183,7 +229,7 @@ namespace System
// this compare can include the zero terminator. Bitwise OR avoids a branch.
return length == 0 | *a == *b;
- ReturnFalse:
+ ReturnFalse:
return false;
}
}
@@ -214,7 +260,7 @@ namespace System
// if the first two chars the same we can increment by 4 bytes,
// leaving us word-aligned on both 32-bit (12 bytes into the string)
// and 64-bit (16 bytes) platforms.
-
+
// For empty strings, the second char will be null due to padding.
// The start of the string (not including sync block pointer)
// is the method table pointer + string length, which takes up
@@ -222,7 +268,7 @@ namespace System
// terminator immediately follows, leaving us with an object
// 10/14 bytes in size. Since everything needs to be a multiple
// of 4/8, this will get padded and zeroed out.
-
+
// For one-char strings the second char will be the null terminator.
// NOTE: If in the future there is a way to read the second char
@@ -231,7 +277,7 @@ namespace System
// then do that and short-circuit before the fixed.
if (*(a + 1) != *(b + 1)) goto DiffOffset1;
-
+
// Since we know that the first two chars are the same,
// we can increment by 2 here and skip 4 bytes.
// This leaves us 8-byte aligned, which results
@@ -269,17 +315,17 @@ namespace System
{
if (*(int*)a != *(int*)b) goto DiffNextInt;
length -= 2;
- a += 2;
- b += 2;
+ a += 2;
+ b += 2;
}
// At this point, we have compared all the characters in at least one string.
// The longer string will be larger.
return strA.Length - strB.Length;
-
+
#if BIT64
- DiffOffset8: a += 4; b += 4;
- DiffOffset4: a += 4; b += 4;
+ DiffOffset8: a += 4; b += 4;
+ DiffOffset4: a += 4; b += 4;
#else // BIT64
// Use jumps instead of falling through, since
// otherwise going to DiffOffset8 will involve
@@ -289,8 +335,8 @@ namespace System
DiffOffset4: a += 2; b += 2;
DiffOffset2: a += 2; b += 2;
#endif // BIT64
-
- DiffOffset0:
+
+ DiffOffset0:
// If we reached here, we already see a difference in the unrolled loop above
#if BIT64
if (*(int*)a == *(int*)b)
@@ -299,7 +345,7 @@ namespace System
}
#endif // BIT64
- DiffNextInt:
+ DiffNextInt:
if (*a != *b) return *a - *b;
DiffOffset1:
@@ -307,7 +353,7 @@ namespace System
return *(a + 1) - *(b + 1);
}
}
-
+
// Provides a culture-correct string comparison. StrA is compared to StrB
// to determine whether it is lexicographically less, equal, or greater, and then returns
// either a negative integer, 0, or a positive integer; respectively.
@@ -317,7 +363,7 @@ namespace System
{
return Compare(strA, strB, StringComparison.CurrentCulture);
}
-
+
// Provides a culture-correct string comparison. strA is compared to strB
// to determine whether it is lexicographically less, equal, or greater, and then a
@@ -331,16 +377,16 @@ namespace System
return Compare(strA, strB, comparisonType);
}
-
+
// Provides a more flexible function for string comparision. See StringComparison
// for meaning of different comparisonType.
[Pure]
- public static int Compare(String strA, String strB, StringComparison comparisonType)
+ public static int Compare(String strA, String strB, StringComparison comparisonType)
{
// Single comparison to check if comparisonType is within [CurrentCulture .. OrdinalIgnoreCase]
if ((uint)(comparisonType - StringComparison.CurrentCulture) > (uint)(StringComparison.OrdinalIgnoreCase - StringComparison.CurrentCulture))
{
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
+ throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType));
}
Contract.EndContractBlock();
@@ -359,7 +405,8 @@ namespace System
return 1;
}
- switch (comparisonType) {
+ switch (comparisonType)
+ {
case StringComparison.CurrentCulture:
return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, strB, CompareOptions.None);
@@ -384,19 +431,15 @@ namespace System
case StringComparison.OrdinalIgnoreCase:
// If both strings are ASCII strings, we can take the fast path.
- if (strA.IsAscii() && strB.IsAscii()) {
+ if (strA.IsAscii() && strB.IsAscii())
+ {
return (CompareOrdinalIgnoreCaseHelper(strA, strB));
}
-#if FEATURE_COREFX_GLOBALIZATION
return CompareInfo.CompareOrdinalIgnoreCase(strA, 0, strA.Length, strB, 0, strB.Length);
-#else
- // Take the slow path.
- return TextInfo.CompareOrdinalIgnoreCase(strA, strB);
-#endif
default:
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_StringComparison"));
+ throw new NotSupportedException(SR.NotSupported_StringComparison);
}
}
@@ -406,7 +449,8 @@ namespace System
// negative integer, 0, or a positive integer is returned; respectively.
//
[Pure]
- public static int Compare(String strA, String strB, CultureInfo culture, CompareOptions options) {
+ public static int Compare(String strA, String strB, CultureInfo culture, CompareOptions options)
+ {
if (culture == null)
{
throw new ArgumentNullException(nameof(culture));
@@ -466,7 +510,7 @@ namespace System
int lengthA = length;
int lengthB = length;
-
+
if (strA != null)
{
lengthA = Math.Min(lengthA, strA.Length - indexA);
@@ -519,17 +563,19 @@ namespace System
{
lengthB = Math.Min(lengthB, strB.Length - indexB);
}
-
+
return culture.CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, options);
}
[Pure]
- public static int Compare(String strA, int indexA, String strB, int indexB, int length, StringComparison comparisonType) {
- if (comparisonType < StringComparison.CurrentCulture || comparisonType > StringComparison.OrdinalIgnoreCase) {
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
+ public static int Compare(String strA, int indexA, String strB, int indexB, int length, StringComparison comparisonType)
+ {
+ if (comparisonType < StringComparison.CurrentCulture || comparisonType > StringComparison.OrdinalIgnoreCase)
+ {
+ throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType));
}
Contract.EndContractBlock();
-
+
if (strA == null || strB == null)
{
if (object.ReferenceEquals(strA, strB))
@@ -543,19 +589,19 @@ namespace System
if (length < 0)
{
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NegativeLength);
}
if (indexA < 0 || indexB < 0)
{
string paramName = indexA < 0 ? nameof(indexA) : nameof(indexB);
- throw new ArgumentOutOfRangeException(paramName, Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(paramName, SR.ArgumentOutOfRange_Index);
}
if (strA.Length - indexA < 0 || strB.Length - indexB < 0)
{
string paramName = strA.Length - indexA < 0 ? nameof(indexA) : nameof(indexB);
- throw new ArgumentOutOfRangeException(paramName, Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(paramName, SR.ArgumentOutOfRange_Index);
}
if (length == 0 || (object.ReferenceEquals(strA, strB) && indexA == indexB))
@@ -566,7 +612,8 @@ namespace System
int lengthA = Math.Min(length, strA.Length - indexA);
int lengthB = Math.Min(length, strB.Length - indexB);
- switch (comparisonType) {
+ switch (comparisonType)
+ {
case StringComparison.CurrentCulture:
return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, CompareOptions.None);
@@ -583,16 +630,11 @@ namespace System
return CompareOrdinalHelper(strA, indexA, lengthA, strB, indexB, lengthB);
case StringComparison.OrdinalIgnoreCase:
-#if FEATURE_COREFX_GLOBALIZATION
return (CompareInfo.CompareOrdinalIgnoreCase(strA, indexA, lengthA, strB, indexB, lengthB));
-#else
- return (TextInfo.CompareOrdinalIgnoreCaseEx(strA, indexA, strB, indexB, lengthA, lengthB));
-#endif
default:
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"));
+ throw new ArgumentException(SR.NotSupported_StringComparison);
}
-
}
// Compares strA and strB using an ordinal (code-point) comparison.
@@ -624,7 +666,7 @@ namespace System
return CompareOrdinalHelper(strA, strB);
}
-
+
// Compares strA and strB using an ordinal (code-point) comparison.
//
@@ -647,22 +689,22 @@ namespace System
if (length < 0)
{
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NegativeCount);
}
if (indexA < 0 || indexB < 0)
{
string paramName = indexA < 0 ? nameof(indexA) : nameof(indexB);
- throw new ArgumentOutOfRangeException(paramName, Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(paramName, SR.ArgumentOutOfRange_Index);
}
-
+
int lengthA = Math.Min(length, strA.Length - indexA);
int lengthB = Math.Min(length, strB.Length - indexB);
if (lengthA < 0 || lengthB < 0)
{
string paramName = lengthA < 0 ? nameof(indexA) : nameof(indexB);
- throw new ArgumentOutOfRangeException(paramName, Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(paramName, SR.ArgumentOutOfRange_Index);
}
if (length == 0 || (object.ReferenceEquals(strA, strB) && indexA == indexB))
@@ -689,12 +731,12 @@ namespace System
if (other == null)
{
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeString"));
+ throw new ArgumentException(SR.Arg_MustBeString);
}
return CompareTo(other); // will call the string-based overload
}
-
+
// Determines the sorting relation of StrB to the current instance.
//
[Pure]
@@ -709,30 +751,37 @@ namespace System
// and the default culture is used.
//
[Pure]
- public Boolean EndsWith(String value) {
+ public Boolean EndsWith(String value)
+ {
return EndsWith(value, StringComparison.CurrentCulture);
}
[Pure]
- public Boolean EndsWith(String value, StringComparison comparisonType) {
- if( (Object)value == null) {
- throw new ArgumentNullException(nameof(value));
+ public Boolean EndsWith(String value, StringComparison comparisonType)
+ {
+ if ((Object)value == null)
+ {
+ throw new ArgumentNullException(nameof(value));
}
- if( comparisonType < StringComparison.CurrentCulture || comparisonType > StringComparison.OrdinalIgnoreCase) {
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
+ if (comparisonType < StringComparison.CurrentCulture || comparisonType > StringComparison.OrdinalIgnoreCase)
+ {
+ throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType));
}
Contract.EndContractBlock();
- if( (Object)this == (Object)value) {
+ if ((Object)this == (Object)value)
+ {
return true;
}
- if( value.Length == 0) {
+ if (value.Length == 0)
+ {
return true;
}
-
- switch (comparisonType) {
+
+ switch (comparisonType)
+ {
case StringComparison.CurrentCulture:
return CultureInfo.CurrentCulture.CompareInfo.IsSuffix(this, value, CompareOptions.None);
@@ -743,30 +792,29 @@ namespace System
return CultureInfo.InvariantCulture.CompareInfo.IsSuffix(this, value, CompareOptions.None);
case StringComparison.InvariantCultureIgnoreCase:
- return CultureInfo.InvariantCulture.CompareInfo.IsSuffix(this, value, CompareOptions.IgnoreCase);
+ return CultureInfo.InvariantCulture.CompareInfo.IsSuffix(this, value, CompareOptions.IgnoreCase);
case StringComparison.Ordinal:
return this.Length < value.Length ? false : (CompareOrdinalHelper(this, this.Length - value.Length, value.Length, value, 0, value.Length) == 0);
case StringComparison.OrdinalIgnoreCase:
-#if FEATURE_COREFX_GLOBALIZATION
return this.Length < value.Length ? false : (CompareInfo.CompareOrdinalIgnoreCase(this, this.Length - value.Length, value.Length, value, 0, value.Length) == 0);
-#else
- return this.Length < value.Length ? false : (TextInfo.CompareOrdinalIgnoreCaseEx(this, this.Length - value.Length, value, 0, value.Length, value.Length) == 0);
-#endif
default:
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
- }
+ throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType));
+ }
}
[Pure]
- public Boolean EndsWith(String value, Boolean ignoreCase, CultureInfo culture) {
- if (null==value) {
+ public Boolean EndsWith(String value, Boolean ignoreCase, CultureInfo culture)
+ {
+ if (null == value)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
-
- if((object)this == (object)value) {
+
+ if ((object)this == (object)value)
+ {
return true;
}
@@ -780,21 +828,15 @@ namespace System
}
[Pure]
- internal bool EndsWith(char value) {
- int thisLen = this.Length;
- if (thisLen != 0) {
- if (this[thisLen - 1] == value)
- return true;
- }
- return false;
+ public bool EndsWith(char value)
+ {
+ int thisLen = Length;
+ return thisLen != 0 && this[thisLen - 1] == value;
}
// Determines whether two strings match.
public override bool Equals(Object obj)
{
- if (this == null) // this is necessary to guard against reverse-pinvokes and
- throw new NullReferenceException(); // other callers who do not use the callvirt instruction
-
if (object.ReferenceEquals(this, obj))
return true;
@@ -812,9 +854,6 @@ namespace System
[Pure]
public bool Equals(String value)
{
- if (this == null) // this is necessary to guard against reverse-pinvokes and
- throw new NullReferenceException(); // other callers who do not use the callvirt instruction
-
if (object.ReferenceEquals(this, value))
return true;
@@ -824,7 +863,7 @@ namespace System
// instead of calling string.op_Equality.
if (value == null)
return false;
-
+
if (this.Length != value.Length)
return false;
@@ -832,20 +871,24 @@ namespace System
}
[Pure]
- public bool Equals(String value, StringComparison comparisonType) {
+ public bool Equals(String value, StringComparison comparisonType)
+ {
if (comparisonType < StringComparison.CurrentCulture || comparisonType > StringComparison.OrdinalIgnoreCase)
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
+ throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType));
Contract.EndContractBlock();
- if ((Object)this == (Object)value) {
+ if ((Object)this == (Object)value)
+ {
return true;
}
- if ((Object)value == null) {
+ if ((Object)value == null)
+ {
return false;
}
- switch (comparisonType) {
+ switch (comparisonType)
+ {
case StringComparison.CurrentCulture:
return (CultureInfo.CurrentCulture.CompareInfo.Compare(this, value, CompareOptions.None) == 0);
@@ -868,31 +911,30 @@ namespace System
return false;
// If both strings are ASCII strings, we can take the fast path.
- if (this.IsAscii() && value.IsAscii()) {
- return (CompareOrdinalIgnoreCaseHelper(this, value) == 0);
+ if (this.IsAscii() && value.IsAscii())
+ {
+ return EqualsIgnoreCaseAsciiHelper(this, value);
}
-#if FEATURE_COREFX_GLOBALIZATION
return (CompareInfo.CompareOrdinalIgnoreCase(this, 0, this.Length, value, 0, value.Length) == 0);
-#else
- // Take the slow path.
- return (TextInfo.CompareOrdinalIgnoreCase(this, value) == 0);
-#endif
default:
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
+ throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType));
}
}
// Determines whether two Strings match.
[Pure]
- public static bool Equals(String a, String b) {
- if ((Object)a==(Object)b) {
+ public static bool Equals(String a, String b)
+ {
+ if ((Object)a == (Object)b)
+ {
return true;
}
- if ((Object)a == null || (Object)b == null || a.Length != b.Length) {
+ if ((Object)a == null || (Object)b == null || a.Length != b.Length)
+ {
return false;
}
@@ -900,20 +942,24 @@ namespace System
}
[Pure]
- public static bool Equals(String a, String b, StringComparison comparisonType) {
+ public static bool Equals(String a, String b, StringComparison comparisonType)
+ {
if (comparisonType < StringComparison.CurrentCulture || comparisonType > StringComparison.OrdinalIgnoreCase)
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
+ throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType));
Contract.EndContractBlock();
- if ((Object)a==(Object)b) {
+ if ((Object)a == (Object)b)
+ {
return true;
}
-
- if ((Object)a==null || (Object)b==null) {
+
+ if ((Object)a == null || (Object)b == null)
+ {
return false;
}
- switch (comparisonType) {
+ switch (comparisonType)
+ {
case StringComparison.CurrentCulture:
return (CultureInfo.CurrentCulture.CompareInfo.Compare(a, b, CompareOptions.None) == 0);
@@ -935,31 +981,31 @@ namespace System
case StringComparison.OrdinalIgnoreCase:
if (a.Length != b.Length)
return false;
- else {
+ else
+ {
// If both strings are ASCII strings, we can take the fast path.
- if (a.IsAscii() && b.IsAscii()) {
- return (CompareOrdinalIgnoreCaseHelper(a, b) == 0);
+ if (a.IsAscii() && b.IsAscii())
+ {
+ return EqualsIgnoreCaseAsciiHelper(a, b);
}
// Take the slow path.
-#if FEATURE_COREFX_GLOBALIZATION
return (CompareInfo.CompareOrdinalIgnoreCase(a, 0, a.Length, b, 0, b.Length) == 0);
-#else
- return (TextInfo.CompareOrdinalIgnoreCase(a, b) == 0);
-#endif
}
default:
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
+ throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType));
}
}
- public static bool operator == (String a, String b) {
- return String.Equals(a, b);
+ public static bool operator ==(String a, String b)
+ {
+ return String.Equals(a, b);
}
- public static bool operator != (String a, String b) {
- return !String.Equals(a, b);
+ public static bool operator !=(String a, String b)
+ {
+ return !String.Equals(a, b);
}
#if FEATURE_RANDOMIZED_STRING_HASHING
@@ -968,7 +1014,8 @@ namespace System
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern int InternalMarvin32HashString(string s, int strLen, long additionalEntropy);
- internal static bool UseRandomizedHashing() {
+ internal static bool UseRandomizedHashing()
+ {
return InternalUseRandomizedHashing();
}
@@ -997,11 +1044,14 @@ namespace System
// Use this if and only if you need the hashcode to not change across app domains (e.g. you have an app domain agile
// hash table).
- internal int GetLegacyNonRandomizedHashCode() {
- unsafe {
- fixed (char* src = &m_firstChar) {
+ internal int GetLegacyNonRandomizedHashCode()
+ {
+ unsafe
+ {
+ fixed (char* src = &m_firstChar)
+ {
Debug.Assert(src[this.Length] == '\0', "src[this.Length] == '\\0'");
- Debug.Assert( ((int)src)%4 == 0, "Managed string should start at 4 bytes boundary");
+ Debug.Assert(((int)src) % 4 == 0, "Managed string should start at 4 bytes boundary");
#if BIT64
int hash1 = 5381;
#else // !BIT64 (32)
@@ -1010,9 +1060,10 @@ namespace System
int hash2 = hash1;
#if BIT64
- int c;
- char *s = src;
- while ((c = s[0]) != 0) {
+ int c;
+ char* s = src;
+ while ((c = s[0]) != 0)
+ {
hash1 = ((hash1 << 5) + hash1) ^ c;
c = s[1];
if (c == 0)
@@ -1048,12 +1099,14 @@ namespace System
}
}
}
-
+
// Determines whether a specified string is a prefix of the current instance
//
[Pure]
- public Boolean StartsWith(String value) {
- if ((Object)value == null) {
+ public Boolean StartsWith(String value)
+ {
+ if ((Object)value == null)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
@@ -1061,25 +1114,31 @@ namespace System
}
[Pure]
- public Boolean StartsWith(String value, StringComparison comparisonType) {
- if( (Object)value == null) {
- throw new ArgumentNullException(nameof(value));
+ public Boolean StartsWith(String value, StringComparison comparisonType)
+ {
+ if ((Object)value == null)
+ {
+ throw new ArgumentNullException(nameof(value));
}
- if( comparisonType < StringComparison.CurrentCulture || comparisonType > StringComparison.OrdinalIgnoreCase) {
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
+ if (comparisonType < StringComparison.CurrentCulture || comparisonType > StringComparison.OrdinalIgnoreCase)
+ {
+ throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType));
}
Contract.EndContractBlock();
- if( (Object)this == (Object)value) {
+ if ((Object)this == (Object)value)
+ {
return true;
}
- if( value.Length == 0) {
+ if (value.Length == 0)
+ {
return true;
}
- switch (comparisonType) {
+ switch (comparisonType)
+ {
case StringComparison.CurrentCulture:
return CultureInfo.CurrentCulture.CompareInfo.IsPrefix(this, value, CompareOptions.None);
@@ -1090,10 +1149,11 @@ namespace System
return CultureInfo.InvariantCulture.CompareInfo.IsPrefix(this, value, CompareOptions.None);
case StringComparison.InvariantCultureIgnoreCase:
- return CultureInfo.InvariantCulture.CompareInfo.IsPrefix(this, value, CompareOptions.IgnoreCase);
+ return CultureInfo.InvariantCulture.CompareInfo.IsPrefix(this, value, CompareOptions.IgnoreCase);
case StringComparison.Ordinal:
- if( this.Length < value.Length || m_firstChar != value.m_firstChar) {
+ if (this.Length < value.Length || m_firstChar != value.m_firstChar)
+ {
return false;
}
return (value.Length == 1) ?
@@ -1101,29 +1161,29 @@ namespace System
StartsWithOrdinalHelper(this, value);
case StringComparison.OrdinalIgnoreCase:
- if( this.Length < value.Length) {
+ if (this.Length < value.Length)
+ {
return false;
}
-
-#if FEATURE_COREFX_GLOBALIZATION
+
return (CompareInfo.CompareOrdinalIgnoreCase(this, 0, value.Length, value, 0, value.Length) == 0);
-#else
- return (TextInfo.CompareOrdinalIgnoreCaseEx(this, 0, value, 0, value.Length, value.Length) == 0);
-#endif
default:
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
- }
+ throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType));
+ }
}
[Pure]
- public Boolean StartsWith(String value, Boolean ignoreCase, CultureInfo culture) {
- if (null==value) {
+ public Boolean StartsWith(String value, Boolean ignoreCase, CultureInfo culture)
+ {
+ if (null == value)
+ {
throw new ArgumentNullException(nameof(value));
}
Contract.EndContractBlock();
- if((object)this == (object)value) {
+ if ((object)this == (object)value)
+ {
return true;
}
@@ -1135,5 +1195,8 @@ namespace System
return referenceCulture.CompareInfo.IsPrefix(this, value, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None);
}
+
+ [Pure]
+ public bool StartsWith(char value) => Length != 0 && m_firstChar == value;
}
-} \ No newline at end of file
+}
diff --git a/src/mscorlib/src/System/String.Manipulation.cs b/src/mscorlib/src/System/String.Manipulation.cs
index e06141d669..33e341c58e 100644
--- a/src/mscorlib/src/System/String.Manipulation.cs
+++ b/src/mscorlib/src/System/String.Manipulation.cs
@@ -18,18 +18,21 @@ namespace System
{
Contract.Requires(dest != null);
Contract.Requires(src != null);
- if (src.Length > dest.Length - destPos) {
+ if (src.Length > dest.Length - destPos)
+ {
throw new IndexOutOfRangeException();
}
Contract.EndContractBlock();
- fixed(char *pDest = &dest.m_firstChar)
- fixed (char *pSrc = &src.m_firstChar) {
- wstrcpy(pDest + destPos, pSrc, src.Length);
- }
+ fixed (char* pDest = &dest.m_firstChar)
+ fixed (char* pSrc = &src.m_firstChar)
+ {
+ wstrcpy(pDest + destPos, pSrc, src.Length);
+ }
}
- public static String Concat(Object arg0) {
+ public static String Concat(Object arg0)
+ {
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
@@ -39,8 +42,9 @@ namespace System
}
return arg0.ToString();
}
-
- public static String Concat(Object arg0, Object arg1) {
+
+ public static String Concat(Object arg0, Object arg1)
+ {
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
@@ -48,14 +52,16 @@ namespace System
{
arg0 = String.Empty;
}
-
- if (arg1==null) {
+
+ if (arg1 == null)
+ {
arg1 = String.Empty;
}
return Concat(arg0.ToString(), arg1.ToString());
}
-
- public static String Concat(Object arg0, Object arg1, Object arg2) {
+
+ public static String Concat(Object arg0, Object arg1, Object arg2)
+ {
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
@@ -63,42 +69,45 @@ namespace System
{
arg0 = String.Empty;
}
-
- if (arg1==null) {
+
+ if (arg1 == null)
+ {
arg1 = String.Empty;
}
-
- if (arg2==null) {
+
+ if (arg2 == null)
+ {
arg2 = String.Empty;
}
-
+
return Concat(arg0.ToString(), arg1.ToString(), arg2.ToString());
}
- [CLSCompliant(false)]
- public static String Concat(Object arg0, Object arg1, Object arg2, Object arg3, __arglist)
+ [CLSCompliant(false)]
+ public static String Concat(Object arg0, Object arg1, Object arg2, Object arg3, __arglist)
{
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
- Object[] objArgs;
- int argCount;
-
+ Object[] objArgs;
+ int argCount;
+
ArgIterator args = new ArgIterator(__arglist);
//+4 to account for the 4 hard-coded arguments at the beginning of the list.
argCount = args.GetRemainingCount() + 4;
-
+
objArgs = new Object[argCount];
-
+
//Handle the hard-coded arguments
objArgs[0] = arg0;
objArgs[1] = arg1;
objArgs[2] = arg2;
objArgs[3] = arg3;
-
+
//Walk all of the args in the variable part of the argument list.
- for (int i=4; i<argCount; i++) {
+ for (int i = 4; i < argCount; i++)
+ {
objArgs[i] = TypedReference.ToObject(args.GetNextArg());
}
@@ -131,7 +140,7 @@ namespace System
// linked-list style implementation)
var strings = new string[args.Length];
-
+
int totalLength = 0;
for (int i = 0; i < args.Length; i++)
@@ -183,7 +192,7 @@ namespace System
{
if (!en.MoveNext())
return string.Empty;
-
+
// We called MoveNext once, so this will be the first item
T currentValue = en.Current;
@@ -203,7 +212,7 @@ namespace System
}
StringBuilder result = StringBuilderCache.Acquire();
-
+
result.Append(firstString);
do
@@ -233,7 +242,7 @@ namespace System
{
if (!en.MoveNext())
return string.Empty;
-
+
string firstValue = en.Current;
if (!en.MoveNext())
@@ -255,35 +264,40 @@ namespace System
}
- public static String Concat(String str0, String str1) {
+ public static String Concat(String str0, String str1)
+ {
Contract.Ensures(Contract.Result<String>() != null);
Contract.Ensures(Contract.Result<String>().Length ==
(str0 == null ? 0 : str0.Length) +
(str1 == null ? 0 : str1.Length));
Contract.EndContractBlock();
- if (IsNullOrEmpty(str0)) {
- if (IsNullOrEmpty(str1)) {
+ if (IsNullOrEmpty(str0))
+ {
+ if (IsNullOrEmpty(str1))
+ {
return String.Empty;
}
return str1;
}
- if (IsNullOrEmpty(str1)) {
+ if (IsNullOrEmpty(str1))
+ {
return str0;
}
int str0Length = str0.Length;
-
+
String result = FastAllocateString(str0Length + str1.Length);
-
- FillStringChecked(result, 0, str0);
+
+ FillStringChecked(result, 0, str0);
FillStringChecked(result, str0Length, str1);
-
+
return result;
}
- public static String Concat(String str0, String str1, String str2) {
+ public static String Concat(String str0, String str1, String str2)
+ {
Contract.Ensures(Contract.Result<String>() != null);
Contract.Ensures(Contract.Result<String>().Length ==
(str0 == null ? 0 : str0.Length) +
@@ -316,9 +330,10 @@ namespace System
return result;
}
- public static String Concat(String str0, String str1, String str2, String str3) {
+ public static String Concat(String str0, String str1, String str2, String str3)
+ {
Contract.Ensures(Contract.Result<String>() != null);
- Contract.Ensures(Contract.Result<String>().Length ==
+ Contract.Ensures(Contract.Result<String>().Length ==
(str0 == null ? 0 : str0.Length) +
(str1 == null ? 0 : str1.Length) +
(str2 == null ? 0 : str2.Length) +
@@ -356,7 +371,8 @@ namespace System
return result;
}
- public static String Concat(params String[] values) {
+ public static String Concat(params String[] values)
+ {
if (values == null)
throw new ArgumentNullException(nameof(values));
Contract.Ensures(Contract.Result<String>() != null);
@@ -424,23 +440,27 @@ namespace System
// fall back should be extremely rare.
return copiedLength == totalLength ? result : Concat((string[])values.Clone());
}
-
- public static String Format(String format, Object arg0) {
+
+ public static String Format(String format, Object arg0)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return FormatHelper(null, format, new ParamsArray(arg0));
}
-
- public static String Format(String format, Object arg0, Object arg1) {
+
+ public static String Format(String format, Object arg0, Object arg1)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return FormatHelper(null, format, new ParamsArray(arg0, arg1));
}
-
- public static String Format(String format, Object arg0, Object arg1, Object arg2) {
+
+ public static String Format(String format, Object arg0, Object arg1, Object arg2)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return FormatHelper(null, format, new ParamsArray(arg0, arg1, arg2));
}
- public static String Format(String format, params Object[] args) {
+ public static String Format(String format, params Object[] args)
+ {
if (args == null)
{
// To preserve the original exception behavior, throw an exception about format if both
@@ -449,26 +469,30 @@ namespace System
}
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
-
+
return FormatHelper(null, format, new ParamsArray(args));
}
-
- public static String Format(IFormatProvider provider, String format, Object arg0) {
+
+ public static String Format(IFormatProvider provider, String format, Object arg0)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return FormatHelper(provider, format, new ParamsArray(arg0));
}
-
- public static String Format(IFormatProvider provider, String format, Object arg0, Object arg1) {
+
+ public static String Format(IFormatProvider provider, String format, Object arg0, Object arg1)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return FormatHelper(provider, format, new ParamsArray(arg0, arg1));
}
-
- public static String Format(IFormatProvider provider, String format, Object arg0, Object arg1, Object arg2) {
+
+ public static String Format(IFormatProvider provider, String format, Object arg0, Object arg1, Object arg2)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return FormatHelper(provider, format, new ParamsArray(arg0, arg1, arg2));
}
- public static String Format(IFormatProvider provider, String format, params Object[] args) {
+ public static String Format(IFormatProvider provider, String format, params Object[] args)
+ {
if (args == null)
{
// To preserve the original exception behavior, throw an exception about format if both
@@ -477,20 +501,21 @@ namespace System
}
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
-
+
return FormatHelper(provider, format, new ParamsArray(args));
}
-
- private static String FormatHelper(IFormatProvider provider, String format, ParamsArray args) {
+
+ private static String FormatHelper(IFormatProvider provider, String format, ParamsArray args)
+ {
if (format == null)
throw new ArgumentNullException(nameof(format));
-
+
return StringBuilderCache.GetStringAndRelease(
StringBuilderCache
.Acquire(format.Length + args.Length * 8)
.AppendFormatHelper(provider, format, args));
}
-
+
public String Insert(int startIndex, String value)
{
if (value == null)
@@ -500,15 +525,15 @@ namespace System
Contract.Ensures(Contract.Result<String>() != null);
Contract.Ensures(Contract.Result<String>().Length == this.Length + value.Length);
Contract.EndContractBlock();
-
+
int oldLength = Length;
int insertLength = value.Length;
-
+
if (oldLength == 0)
return value;
if (insertLength == 0)
return this;
-
+
// In case this computation overflows, newLength will be negative and FastAllocateString throws OutOfMemoryException
int newLength = oldLength + insertLength;
String result = FastAllocateString(newLength);
@@ -557,7 +582,7 @@ namespace System
// Defer argument validation to the internal function
return JoinCore(&separator, 1, value, startIndex, count);
}
-
+
// Joins an array of strings together as one string with a separator between each original string.
//
public static string Join(string separator, params string[] value)
@@ -686,7 +711,7 @@ namespace System
{
return string.Empty;
}
-
+
// We called MoveNext once, so this will be the first item
T currentValue = en.Current;
@@ -738,17 +763,17 @@ namespace System
}
if (startIndex < 0)
{
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex);
}
if (count < 0)
{
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NegativeCount);
}
if (startIndex > value.Length - count)
{
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_IndexCountBuffer);
}
-
+
if (count <= 1)
{
return count == 0 ?
@@ -803,7 +828,7 @@ namespace System
FillStringChecked(result, copiedLength, currentValue);
copiedLength += valueLen;
}
-
+
if (i < end - 1)
{
// Fill in the separator.
@@ -833,18 +858,20 @@ namespace System
result :
JoinCore(separator, separatorLength, (string[])value.Clone(), startIndex, count);
}
-
+
//
//
[Pure]
- public String PadLeft(int totalWidth) {
+ public String PadLeft(int totalWidth)
+ {
return PadLeft(totalWidth, ' ');
}
[Pure]
- public String PadLeft(int totalWidth, char paddingChar) {
+ public String PadLeft(int totalWidth, char paddingChar)
+ {
if (totalWidth < 0)
- throw new ArgumentOutOfRangeException(nameof(totalWidth), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(totalWidth), SR.ArgumentOutOfRange_NeedNonNegNum);
int oldLength = Length;
int count = totalWidth - oldLength;
if (count <= 0)
@@ -866,14 +893,16 @@ namespace System
}
[Pure]
- public String PadRight(int totalWidth) {
+ public String PadRight(int totalWidth)
+ {
return PadRight(totalWidth, ' ');
}
[Pure]
- public String PadRight(int totalWidth, char paddingChar) {
+ public String PadRight(int totalWidth, char paddingChar)
+ {
if (totalWidth < 0)
- throw new ArgumentOutOfRangeException(nameof(totalWidth), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(totalWidth), SR.ArgumentOutOfRange_NeedNonNegNum);
int oldLength = Length;
int count = totalWidth - oldLength;
if (count <= 0)
@@ -897,24 +926,24 @@ namespace System
public String Remove(int startIndex, int count)
{
if (startIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(startIndex),
- Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex),
+ SR.ArgumentOutOfRange_StartIndex);
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count),
- Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
+ throw new ArgumentOutOfRangeException(nameof(count),
+ SR.ArgumentOutOfRange_NegativeCount);
if (count > Length - startIndex)
- throw new ArgumentOutOfRangeException(nameof(count),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
+ throw new ArgumentOutOfRangeException(nameof(count),
+ SR.ArgumentOutOfRange_IndexCount);
Contract.Ensures(Contract.Result<String>() != null);
Contract.Ensures(Contract.Result<String>().Length == this.Length - count);
Contract.EndContractBlock();
-
+
if (count == 0)
return this;
int newLength = Length - count;
if (newLength == 0)
return String.Empty;
-
+
String result = FastAllocateString(newLength);
unsafe
{
@@ -931,22 +960,113 @@ namespace System
}
// a remove that just takes a startindex.
- public string Remove( int startIndex ) {
- if (startIndex < 0) {
- throw new ArgumentOutOfRangeException(nameof(startIndex),
- Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ public string Remove(int startIndex)
+ {
+ if (startIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex),
+ SR.ArgumentOutOfRange_StartIndex);
}
-
- if (startIndex >= Length) {
- throw new ArgumentOutOfRangeException(nameof(startIndex),
- Environment.GetResourceString("ArgumentOutOfRange_StartIndexLessThanLength"));
+
+ if (startIndex >= Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex),
+ SR.ArgumentOutOfRange_StartIndexLessThanLength);
}
-
+
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
return Substring(0, startIndex);
- }
+ }
+
+ public string Replace(string oldValue, string newValue, bool ignoreCase, CultureInfo culture)
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+ Contract.EndContractBlock();
+
+ return ReplaceCore(oldValue, newValue, culture, ignoreCase ? CompareOptions.IgnoreCase : CompareOptions.None);
+ }
+
+ public string Replace(string oldValue, string newValue, StringComparison comparisonType)
+ {
+ Contract.Ensures(Contract.Result<String>() != null);
+ Contract.EndContractBlock();
+
+ switch (comparisonType)
+ {
+ case StringComparison.CurrentCulture:
+ return ReplaceCore(oldValue, newValue, CultureInfo.CurrentCulture, CompareOptions.None);
+
+ case StringComparison.CurrentCultureIgnoreCase:
+ return ReplaceCore(oldValue, newValue, CultureInfo.CurrentCulture, CompareOptions.IgnoreCase);
+
+ case StringComparison.InvariantCulture:
+ return ReplaceCore(oldValue, newValue, CultureInfo.InvariantCulture, CompareOptions.None);
+
+ case StringComparison.InvariantCultureIgnoreCase:
+ return ReplaceCore(oldValue, newValue, CultureInfo.InvariantCulture, CompareOptions.IgnoreCase);
+
+ case StringComparison.Ordinal:
+ return ReplaceCore(oldValue, newValue, CultureInfo.InvariantCulture, CompareOptions.Ordinal);
+
+ case StringComparison.OrdinalIgnoreCase:
+ return ReplaceCore(oldValue, newValue, CultureInfo.InvariantCulture, CompareOptions.OrdinalIgnoreCase);
+
+ default:
+ throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType));
+ }
+ }
+
+ private unsafe String ReplaceCore(string oldValue, string newValue, CultureInfo culture, CompareOptions options)
+ {
+ if (oldValue == null)
+ throw new ArgumentNullException(nameof(oldValue));
+
+ // If they asked to replace oldValue with a null, replace all occurences
+ // with the empty string.
+ if (newValue == null)
+ newValue = string.Empty;
+
+ CultureInfo referenceCulture = culture ?? CultureInfo.CurrentCulture;
+ StringBuilder result = StringBuilderCache.Acquire();
+
+ int startIndex = 0;
+ int index = 0;
+
+ int matchLength = 0;
+
+ bool hasDoneAnyReplacements = false;
+
+ do
+ {
+ index = referenceCulture.CompareInfo.IndexOfCore(this, oldValue, startIndex, m_stringLength - startIndex, options, &matchLength);
+ if (index >= 0)
+ {
+ // append the unmodified portion of string
+ result.Append(this, startIndex, index - startIndex);
+
+ // append the replacement
+ result.Append(newValue);
+
+ startIndex = index + matchLength;
+ hasDoneAnyReplacements = true;
+ }
+ else if (!hasDoneAnyReplacements)
+ {
+ // small optimization,
+ // if we have not done any replacements,
+ // we will return the original string
+ return this;
+ }
+ else
+ {
+ result.Append(this, startIndex, m_stringLength - startIndex);
+ }
+ } while (index >= 0);
+
+ return StringBuilderCache.GetStringAndRelease(result);
+ }
// Replaces all instances of oldChar with newChar.
//
@@ -1034,12 +1154,14 @@ namespace System
return ReplaceInternal(oldValue, newValue);
}
- public unsafe String[] Split(char separator, StringSplitOptions options = StringSplitOptions.None) {
+ public unsafe String[] Split(char separator, StringSplitOptions options = StringSplitOptions.None)
+ {
Contract.Ensures(Contract.Result<String[]>() != null);
return SplitInternal(&separator, 1, int.MaxValue, options);
}
- public unsafe String[] Split(char separator, int count, StringSplitOptions options = StringSplitOptions.None) {
+ public unsafe String[] Split(char separator, int count, StringSplitOptions options = StringSplitOptions.None)
+ {
Contract.Ensures(Contract.Result<String[]>() != null);
return SplitInternal(&separator, 1, count, options);
}
@@ -1053,7 +1175,8 @@ namespace System
// If the separator is null
// whitespace (i.e., Character.IsWhitespace) is used as the separator.
//
- public String [] Split(params char [] separator) {
+ public String[] Split(params char[] separator)
+ {
Contract.Ensures(Contract.Result<String[]>() != null);
return SplitInternal(separator, Int32.MaxValue, StringSplitOptions.None);
}
@@ -1069,12 +1192,14 @@ namespace System
// If there are more than count different strings, the last n-(count-1)
// elements are concatenated and added as the last String.
//
- public string[] Split(char[] separator, int count) {
+ public string[] Split(char[] separator, int count)
+ {
Contract.Ensures(Contract.Result<String[]>() != null);
return SplitInternal(separator, count, StringSplitOptions.None);
}
- public String[] Split(char[] separator, StringSplitOptions options) {
+ public String[] Split(char[] separator, StringSplitOptions options)
+ {
Contract.Ensures(Contract.Result<String[]>() != null);
return SplitInternal(separator, Int32.MaxValue, options);
}
@@ -1098,72 +1223,79 @@ namespace System
{
if (count < 0)
throw new ArgumentOutOfRangeException(nameof(count),
- Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
+ SR.ArgumentOutOfRange_NegativeCount);
if (options < StringSplitOptions.None || options > StringSplitOptions.RemoveEmptyEntries)
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", options));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, options));
Contract.Ensures(Contract.Result<String[]>() != null);
Contract.EndContractBlock();
bool omitEmptyEntries = (options == StringSplitOptions.RemoveEmptyEntries);
- if ((count == 0) || (omitEmptyEntries && this.Length == 0))
+ if ((count == 0) || (omitEmptyEntries && this.Length == 0))
{
- return EmptyArray<String>.Value;
+ return Array.Empty<String>();
}
if (count == 1)
{
return new String[] { this };
}
-
+
int[] sepList = new int[Length];
int numReplaces = MakeSeparatorList(separators, separatorsLength, sepList);
-
+
// Handle the special case of no replaces.
- if (0 == numReplaces) {
+ if (0 == numReplaces)
+ {
return new String[] { this };
}
- if(omitEmptyEntries)
+ if (omitEmptyEntries)
{
return SplitOmitEmptyEntries(sepList, null, 1, numReplaces, count);
}
- else
+ else
{
return SplitKeepEmptyEntries(sepList, null, 1, numReplaces, count);
}
}
- public String[] Split(String separator, StringSplitOptions options = StringSplitOptions.None) {
+ public String[] Split(String separator, StringSplitOptions options = StringSplitOptions.None)
+ {
Contract.Ensures(Contract.Result<String[]>() != null);
return SplitInternal(separator ?? String.Empty, null, Int32.MaxValue, options);
}
- public String[] Split(String separator, Int32 count, StringSplitOptions options = StringSplitOptions.None) {
+ public String[] Split(String separator, Int32 count, StringSplitOptions options = StringSplitOptions.None)
+ {
Contract.Ensures(Contract.Result<String[]>() != null);
return SplitInternal(separator ?? String.Empty, null, count, options);
}
- public String [] Split(String[] separator, StringSplitOptions options) {
+ public String[] Split(String[] separator, StringSplitOptions options)
+ {
Contract.Ensures(Contract.Result<String[]>() != null);
return SplitInternal(null, separator, Int32.MaxValue, options);
}
- public String[] Split(String[] separator, Int32 count, StringSplitOptions options) {
+ public String[] Split(String[] separator, Int32 count, StringSplitOptions options)
+ {
Contract.Ensures(Contract.Result<String[]>() != null);
return SplitInternal(null, separator, count, options);
}
private String[] SplitInternal(String separator, String[] separators, Int32 count, StringSplitOptions options)
{
- if (count < 0) {
+ if (count < 0)
+ {
throw new ArgumentOutOfRangeException(nameof(count),
- Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
+ SR.ArgumentOutOfRange_NegativeCount);
}
- if (options < StringSplitOptions.None || options > StringSplitOptions.RemoveEmptyEntries) {
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)options));
+ if (options < StringSplitOptions.None || options > StringSplitOptions.RemoveEmptyEntries)
+ {
+ throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, (int)options));
}
Contract.EndContractBlock();
@@ -1171,15 +1303,18 @@ namespace System
bool singleSeparator = separator != null;
- if (!singleSeparator && (separators == null || separators.Length == 0)) {
- return SplitInternal((char[]) null, count, options);
+ if (!singleSeparator && (separators == null || separators.Length == 0))
+ {
+ return SplitInternal((char[])null, count, options);
}
-
- if ((count == 0) || (omitEmptyEntries && this.Length ==0)) {
- return EmptyArray<String>.Value;
+
+ if ((count == 0) || (omitEmptyEntries && this.Length == 0))
+ {
+ return Array.Empty<String>();
}
- if (count == 1 || (singleSeparator && separator.Length == 0)) {
+ if (count == 1 || (singleSeparator && separator.Length == 0))
+ {
return new String[] { this };
}
@@ -1188,40 +1323,46 @@ namespace System
int defaultLength;
int numReplaces;
- if (singleSeparator) {
+ if (singleSeparator)
+ {
lengthList = null;
defaultLength = separator.Length;
numReplaces = MakeSeparatorList(separator, sepList);
}
- else {
+ else
+ {
lengthList = new int[Length];
defaultLength = 0;
numReplaces = MakeSeparatorList(separators, sepList, lengthList);
}
// Handle the special case of no replaces.
- if (0 == numReplaces) {
+ if (0 == numReplaces)
+ {
return new String[] { this };
}
-
- if (omitEmptyEntries) {
+
+ if (omitEmptyEntries)
+ {
return SplitOmitEmptyEntries(sepList, lengthList, defaultLength, numReplaces, count);
}
- else {
+ else
+ {
return SplitKeepEmptyEntries(sepList, lengthList, defaultLength, numReplaces, count);
}
- }
-
+ }
+
// Note a special case in this function:
// If there is no separator in the string, a string array which only contains
// the original string will be returned regardless of the count.
//
- private String[] SplitKeepEmptyEntries(Int32[] sepList, Int32[] lengthList, Int32 defaultLength, Int32 numReplaces, int count) {
+ private String[] SplitKeepEmptyEntries(Int32[] sepList, Int32[] lengthList, Int32 defaultLength, Int32 numReplaces, int count)
+ {
Contract.Requires(numReplaces >= 0);
Contract.Requires(count >= 2);
Contract.Ensures(Contract.Result<String[]>() != null);
-
+
int currIndex = 0;
int arrIndex = 0;
@@ -1230,30 +1371,33 @@ namespace System
//Allocate space for the new array.
//+1 for the string from the end of the last replace to the end of the String.
- String[] splitStrings = new String[numActualReplaces+1];
+ String[] splitStrings = new String[numActualReplaces + 1];
- for (int i = 0; i < numActualReplaces && currIndex < Length; i++) {
- splitStrings[arrIndex++] = Substring(currIndex, sepList[i]-currIndex );
- currIndex=sepList[i] + ((lengthList == null) ? defaultLength : lengthList[i]);
+ for (int i = 0; i < numActualReplaces && currIndex < Length; i++)
+ {
+ splitStrings[arrIndex++] = Substring(currIndex, sepList[i] - currIndex);
+ currIndex = sepList[i] + ((lengthList == null) ? defaultLength : lengthList[i]);
}
//Handle the last string at the end of the array if there is one.
- if (currIndex < Length && numActualReplaces >= 0) {
+ if (currIndex < Length && numActualReplaces >= 0)
+ {
splitStrings[arrIndex] = Substring(currIndex);
- }
- else if (arrIndex==numActualReplaces) {
+ }
+ else if (arrIndex == numActualReplaces)
+ {
//We had a separator character at the end of a string. Rather than just allowing
//a null character, we'll replace the last element in the array with an empty string.
splitStrings[arrIndex] = String.Empty;
-
}
return splitStrings;
}
-
+
// This function will not keep the Empty String
- private String[] SplitOmitEmptyEntries(Int32[] sepList, Int32[] lengthList, Int32 defaultLength, Int32 numReplaces, int count) {
+ private String[] SplitOmitEmptyEntries(Int32[] sepList, Int32[] lengthList, Int32 defaultLength, Int32 numReplaces, int count)
+ {
Contract.Requires(numReplaces >= 0);
Contract.Requires(count >= 2);
Contract.Ensures(Contract.Result<String[]>() != null);
@@ -1262,20 +1406,24 @@ namespace System
// filled completely in this function, we will create a
// new array and copy string references to that new array.
- int maxItems = (numReplaces < count) ? (numReplaces+1): count ;
+ int maxItems = (numReplaces < count) ? (numReplaces + 1) : count;
String[] splitStrings = new String[maxItems];
int currIndex = 0;
int arrIndex = 0;
- for(int i=0; i< numReplaces && currIndex < Length; i++) {
- if( sepList[i]-currIndex > 0) {
- splitStrings[arrIndex++] = Substring(currIndex, sepList[i]-currIndex );
+ for (int i = 0; i < numReplaces && currIndex < Length; i++)
+ {
+ if (sepList[i] - currIndex > 0)
+ {
+ splitStrings[arrIndex++] = Substring(currIndex, sepList[i] - currIndex);
}
- currIndex=sepList[i] + ((lengthList == null) ? defaultLength : lengthList[i]);
- if( arrIndex == count -1 ) {
+ currIndex = sepList[i] + ((lengthList == null) ? defaultLength : lengthList[i]);
+ if (arrIndex == count - 1)
+ {
// If all the remaining entries at the end are empty, skip them
- while( i < numReplaces - 1 && currIndex == sepList[++i]) {
+ while (i < numReplaces - 1 && currIndex == sepList[++i])
+ {
currIndex += ((lengthList == null) ? defaultLength : lengthList[i]);
}
break;
@@ -1286,19 +1434,22 @@ namespace System
Debug.Assert(arrIndex < maxItems);
//Handle the last string at the end of the array if there is one.
- if (currIndex< Length) {
+ if (currIndex < Length)
+ {
splitStrings[arrIndex++] = Substring(currIndex);
}
String[] stringArray = splitStrings;
- if( arrIndex!= maxItems) {
+ if (arrIndex != maxItems)
+ {
stringArray = new String[arrIndex];
- for( int j = 0; j < arrIndex; j++) {
+ for (int j = 0; j < arrIndex; j++)
+ {
stringArray[j] = splitStrings[j];
- }
+ }
}
return stringArray;
- }
+ }
//--------------------------------------------------------------------
// This function returns the number of the places within this instance where
@@ -1306,56 +1457,71 @@ namespace System
// Args: separator -- A string containing all of the split characters.
// sepList -- an array of ints for split char indicies.
//--------------------------------------------------------------------
- private unsafe int MakeSeparatorList(char* separators, int separatorsLength, int[] sepList) {
+ private unsafe int MakeSeparatorList(char* separators, int separatorsLength, int[] sepList)
+ {
Debug.Assert(separatorsLength >= 0, "separatorsLength >= 0");
- int foundCount=0;
+ int foundCount = 0;
- if (separators == null || separatorsLength == 0) {
- fixed (char* pwzChars = &this.m_firstChar) {
+ if (separators == null || separatorsLength == 0)
+ {
+ fixed (char* pwzChars = &m_firstChar)
+ {
//If they passed null or an empty string, look for whitespace.
- for (int i=0; i < Length && foundCount < sepList.Length; i++) {
- if (Char.IsWhiteSpace(pwzChars[i])) {
- sepList[foundCount++]=i;
+ for (int i = 0; i < Length && foundCount < sepList.Length; i++)
+ {
+ if (Char.IsWhiteSpace(pwzChars[i]))
+ {
+ sepList[foundCount++] = i;
}
}
}
- }
- else {
+ }
+ else
+ {
int sepListCount = sepList.Length;
//If they passed in a string of chars, actually look for those chars.
- fixed (char* pwzChars = &this.m_firstChar) {
- for (int i=0; i< Length && foundCount < sepListCount; i++) {
+ fixed (char* pwzChars = &m_firstChar)
+ {
+ for (int i = 0; i < Length && foundCount < sepListCount; i++)
+ {
char* pSep = separators;
- for (int j = 0; j < separatorsLength; j++, pSep++) {
- if ( pwzChars[i] == *pSep) {
- sepList[foundCount++]=i;
- break;
- }
+ for (int j = 0; j < separatorsLength; j++, pSep++)
+ {
+ if (pwzChars[i] == *pSep)
+ {
+ sepList[foundCount++] = i;
+ break;
+ }
}
}
}
}
return foundCount;
- }
-
+ }
+
//--------------------------------------------------------------------
// This function returns number of the places within baseString where
// instances of the separator string occurs.
// Args: separator -- the separator
// sepList -- an array of ints for split string indicies.
//--------------------------------------------------------------------
- private unsafe int MakeSeparatorList(string separator, int[] sepList) {
+ private unsafe int MakeSeparatorList(string separator, int[] sepList)
+ {
Debug.Assert(!string.IsNullOrEmpty(separator), "!string.IsNullOrEmpty(separator)");
int foundCount = 0;
int sepListCount = sepList.Length;
int currentSepLength = separator.Length;
- fixed (char* pwzChars = &this.m_firstChar) {
- for (int i = 0; i < Length && foundCount < sepListCount; i++) {
- if (pwzChars[i] == separator[0] && currentSepLength <= Length - i) {
+ fixed (char* pwzChars = &m_firstChar)
+ {
+ for (int i = 0; i < Length && foundCount < sepListCount; i++)
+ {
+ if (pwzChars[i] == separator[0] && currentSepLength <= Length - i)
+ {
if (currentSepLength == 1
- || String.CompareOrdinal(this, i, separator, 0, currentSepLength) == 0) {
+ || String.CompareOrdinal(this, i, separator, 0, currentSepLength) == 0)
+ {
sepList[foundCount] = i;
foundCount++;
i += currentSepLength - 1;
@@ -1373,24 +1539,31 @@ namespace System
// sepList -- an array of ints for split string indicies.
// lengthList -- an array of ints for split string lengths.
//--------------------------------------------------------------------
- private unsafe int MakeSeparatorList(String[] separators, int[] sepList, int[] lengthList) {
+ private unsafe int MakeSeparatorList(String[] separators, int[] sepList, int[] lengthList)
+ {
Debug.Assert(separators != null && separators.Length > 0, "separators != null && separators.Length > 0");
-
+
int foundCount = 0;
int sepListCount = sepList.Length;
int sepCount = separators.Length;
- fixed (char* pwzChars = &this.m_firstChar) {
- for (int i=0; i< Length && foundCount < sepListCount; i++) {
- for( int j =0; j < separators.Length; j++) {
+ fixed (char* pwzChars = &m_firstChar)
+ {
+ for (int i = 0; i < Length && foundCount < sepListCount; i++)
+ {
+ for (int j = 0; j < separators.Length; j++)
+ {
String separator = separators[j];
- if (String.IsNullOrEmpty(separator)) {
+ if (String.IsNullOrEmpty(separator))
+ {
continue;
}
Int32 currentSepLength = separator.Length;
- if ( pwzChars[i] == separator[0] && currentSepLength <= Length - i) {
- if (currentSepLength == 1
- || String.CompareOrdinal(this, i, separator, 0, currentSepLength) == 0) {
+ if (pwzChars[i] == separator[0] && currentSepLength <= Length - i)
+ {
+ if (currentSepLength == 1
+ || String.CompareOrdinal(this, i, separator, 0, currentSepLength) == 0)
+ {
sepList[foundCount] = i;
lengthList[foundCount] = currentSepLength;
foundCount++;
@@ -1403,71 +1576,82 @@ namespace System
}
return foundCount;
}
-
+
// Returns a substring of this string.
//
- public String Substring (int startIndex) {
- return this.Substring (startIndex, Length-startIndex);
+ public String Substring(int startIndex)
+ {
+ return this.Substring(startIndex, Length - startIndex);
}
-
+
// Returns a substring of this string.
//
- public String Substring(int startIndex, int length) {
-
+ public String Substring(int startIndex, int length)
+ {
//Bounds Checking.
- if (startIndex < 0) {
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ if (startIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex);
}
- if (startIndex > Length) {
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndexLargerThanLength"));
+ if (startIndex > Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndexLargerThanLength);
}
- if (length < 0) {
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
+ if (length < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NegativeLength);
}
- if (startIndex > Length - length) {
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_IndexLength"));
+ if (startIndex > Length - length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_IndexLength);
}
Contract.EndContractBlock();
- if( length == 0) {
+ if (length == 0)
+ {
return String.Empty;
}
- if( startIndex == 0 && length == this.Length) {
+ if (startIndex == 0 && length == this.Length)
+ {
return this;
}
return InternalSubString(startIndex, length);
}
- unsafe string InternalSubString(int startIndex, int length) {
- Debug.Assert( startIndex >= 0 && startIndex <= this.Length, "StartIndex is out of range!");
- Debug.Assert( length >= 0 && startIndex <= this.Length - length, "length is out of range!");
-
+ private unsafe string InternalSubString(int startIndex, int length)
+ {
+ Debug.Assert(startIndex >= 0 && startIndex <= this.Length, "StartIndex is out of range!");
+ Debug.Assert(length >= 0 && startIndex <= this.Length - length, "length is out of range!");
+
String result = FastAllocateString(length);
- fixed(char* dest = &result.m_firstChar)
- fixed(char* src = &this.m_firstChar) {
- wstrcpy(dest, src + startIndex, length);
- }
+ fixed (char* dest = &result.m_firstChar)
+ fixed (char* src = &m_firstChar)
+ {
+ wstrcpy(dest, src + startIndex, length);
+ }
return result;
}
-
+
// Creates a copy of this string in lower case.
[Pure]
- public String ToLower() {
+ public String ToLower()
+ {
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
return this.ToLower(CultureInfo.CurrentCulture);
}
-
+
// Creates a copy of this string in lower case. The culture is set by culture.
[Pure]
- public String ToLower(CultureInfo culture) {
+ public String ToLower(CultureInfo culture)
+ {
if (culture == null)
{
throw new ArgumentNullException(nameof(culture));
@@ -1479,24 +1663,27 @@ namespace System
// Creates a copy of this string in lower case based on invariant culture.
[Pure]
- public String ToLowerInvariant() {
+ public String ToLowerInvariant()
+ {
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
return this.ToLower(CultureInfo.InvariantCulture);
}
-
+
// Creates a copy of this string in upper case.
[Pure]
- public String ToUpper() {
+ public String ToUpper()
+ {
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
return this.ToUpper(CultureInfo.CurrentCulture);
}
-
+
// Creates a copy of this string in upper case. The culture is set by culture.
[Pure]
- public String ToUpper(CultureInfo culture) {
+ public String ToUpper(CultureInfo culture)
+ {
if (culture == null)
{
throw new ArgumentNullException(nameof(culture));
@@ -1509,7 +1696,8 @@ namespace System
//Creates a copy of this string in upper case based on invariant culture.
[Pure]
- public String ToUpperInvariant() {
+ public String ToUpperInvariant()
+ {
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
return this.ToUpper(CultureInfo.InvariantCulture);
diff --git a/src/mscorlib/src/System/String.Searching.cs b/src/mscorlib/src/System/String.Searching.cs
index 2620cfd0dc..411a45c1a7 100644
--- a/src/mscorlib/src/System/String.Searching.cs
+++ b/src/mscorlib/src/System/String.Searching.cs
@@ -11,30 +11,34 @@ namespace System
public partial class String
{
[Pure]
- public bool Contains( string value ) {
- return ( IndexOf(value, StringComparison.Ordinal) >=0 );
+ public bool Contains(string value)
+ {
+ return (IndexOf(value, StringComparison.Ordinal) >= 0);
}
-
+
// Returns the index of the first occurrence of a specified character in the current instance.
// The search starts at startIndex and runs thorough the next count characters.
//
[Pure]
- public int IndexOf(char value) {
+ public int IndexOf(char value)
+ {
return IndexOf(value, 0, this.Length);
}
[Pure]
- public int IndexOf(char value, int startIndex) {
+ public int IndexOf(char value, int startIndex)
+ {
return IndexOf(value, startIndex, this.Length - startIndex);
}
[Pure]
- public unsafe int IndexOf(char value, int startIndex, int count) {
+ public unsafe int IndexOf(char value, int startIndex, int count)
+ {
if (startIndex < 0 || startIndex > Length)
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
if (count < 0 || count > Length - startIndex)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
fixed (char* pChars = &m_firstChar)
{
@@ -62,39 +66,42 @@ namespace System
return -1;
- ReturnIndex3: pCh++;
- ReturnIndex2: pCh++;
- ReturnIndex1: pCh++;
- ReturnIndex:
+ ReturnIndex3: pCh++;
+ ReturnIndex2: pCh++;
+ ReturnIndex1: pCh++;
+ ReturnIndex:
return (int)(pCh - pChars);
}
}
-
+
// Returns the index of the first occurrence of any specified character in the current instance.
// The search starts at startIndex and runs to startIndex + count -1.
//
- [Pure]
- public int IndexOfAny(char [] anyOf) {
- return IndexOfAny(anyOf,0, this.Length);
+ [Pure]
+ public int IndexOfAny(char[] anyOf)
+ {
+ return IndexOfAny(anyOf, 0, this.Length);
}
-
+
[Pure]
- public int IndexOfAny(char [] anyOf, int startIndex) {
+ public int IndexOfAny(char[] anyOf, int startIndex)
+ {
return IndexOfAny(anyOf, startIndex, this.Length - startIndex);
}
-
+
[Pure]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public extern int IndexOfAny(char [] anyOf, int startIndex, int count);
-
-
+ public extern int IndexOfAny(char[] anyOf, int startIndex, int count);
+
+
// Determines the position within this string of the first occurrence of the specified
// string, according to the specified search criteria. The search begins at
// the first character of this string, it is case-sensitive and the current culture
// comparison is used.
//
[Pure]
- public int IndexOf(String value) {
+ public int IndexOf(String value)
+ {
return IndexOf(value, StringComparison.CurrentCulture);
}
@@ -103,7 +110,8 @@ namespace System
// startIndex, it is case-sensitive and the current culture comparison is used.
//
[Pure]
- public int IndexOf(String value, int startIndex) {
+ public int IndexOf(String value, int startIndex)
+ {
return IndexOf(value, startIndex, StringComparison.CurrentCulture);
}
@@ -112,43 +120,50 @@ namespace System
// startIndex, ends at endIndex and the current culture comparison is used.
//
[Pure]
- public int IndexOf(String value, int startIndex, int count) {
- if (startIndex < 0 || startIndex > this.Length) {
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ public int IndexOf(String value, int startIndex, int count)
+ {
+ if (startIndex < 0 || startIndex > this.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
}
- if (count < 0 || count > this.Length - startIndex) {
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ if (count < 0 || count > this.Length - startIndex)
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
}
Contract.EndContractBlock();
-
+
return IndexOf(value, startIndex, count, StringComparison.CurrentCulture);
}
[Pure]
- public int IndexOf(String value, StringComparison comparisonType) {
+ public int IndexOf(String value, StringComparison comparisonType)
+ {
return IndexOf(value, 0, this.Length, comparisonType);
}
[Pure]
- public int IndexOf(String value, int startIndex, StringComparison comparisonType) {
+ public int IndexOf(String value, int startIndex, StringComparison comparisonType)
+ {
return IndexOf(value, startIndex, this.Length - startIndex, comparisonType);
}
[Pure]
- public int IndexOf(String value, int startIndex, int count, StringComparison comparisonType) {
+ public int IndexOf(String value, int startIndex, int count, StringComparison comparisonType)
+ {
// Validate inputs
if (value == null)
throw new ArgumentNullException(nameof(value));
if (startIndex < 0 || startIndex > this.Length)
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
if (count < 0 || startIndex > this.Length - count)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
Contract.EndContractBlock();
- switch (comparisonType) {
+ switch (comparisonType)
+ {
case StringComparison.CurrentCulture:
return CultureInfo.CurrentCulture.CompareInfo.IndexOf(this, value, startIndex, count, CompareOptions.None);
@@ -171,8 +186,8 @@ namespace System
return TextInfo.IndexOfStringOrdinalIgnoreCase(this, value, startIndex, count);
default:
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
- }
+ throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType));
+ }
}
// Returns the index of the last occurrence of a specified character in the current instance.
@@ -181,25 +196,28 @@ namespace System
// index within the string.
//
[Pure]
- public int LastIndexOf(char value) {
- return LastIndexOf(value, this.Length-1, this.Length);
+ public int LastIndexOf(char value)
+ {
+ return LastIndexOf(value, this.Length - 1, this.Length);
}
[Pure]
- public int LastIndexOf(char value, int startIndex){
- return LastIndexOf(value,startIndex,startIndex + 1);
+ public int LastIndexOf(char value, int startIndex)
+ {
+ return LastIndexOf(value, startIndex, startIndex + 1);
}
[Pure]
- public unsafe int LastIndexOf(char value, int startIndex, int count) {
+ public unsafe int LastIndexOf(char value, int startIndex, int count)
+ {
if (Length == 0)
return -1;
if (startIndex < 0 || startIndex >= Length)
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
if (count < 0 || count - 1 > startIndex)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
fixed (char* pChars = &m_firstChar)
{
@@ -228,55 +246,61 @@ namespace System
return -1;
- ReturnIndex3: pCh--;
- ReturnIndex2: pCh--;
- ReturnIndex1: pCh--;
- ReturnIndex:
+ ReturnIndex3: pCh--;
+ ReturnIndex2: pCh--;
+ ReturnIndex1: pCh--;
+ ReturnIndex:
return (int)(pCh - pChars);
}
}
-
+
// Returns the index of the last occurrence of any specified character in the current instance.
// The search starts at startIndex and runs backwards to startIndex - count + 1.
// The character at position startIndex is included in the search. startIndex is the larger
// index within the string.
//
-
+
//ForceInline ... Jit can't recognize String.get_Length to determine that this is "fluff"
[Pure]
- public int LastIndexOfAny(char [] anyOf) {
- return LastIndexOfAny(anyOf,this.Length-1,this.Length);
+ public int LastIndexOfAny(char[] anyOf)
+ {
+ return LastIndexOfAny(anyOf, this.Length - 1, this.Length);
}
-
+
[Pure]
- public int LastIndexOfAny(char [] anyOf, int startIndex) {
- return LastIndexOfAny(anyOf,startIndex,startIndex + 1);
+ public int LastIndexOfAny(char[] anyOf, int startIndex)
+ {
+ return LastIndexOfAny(anyOf, startIndex, startIndex + 1);
}
[Pure]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public extern int LastIndexOfAny(char [] anyOf, int startIndex, int count);
-
-
+ public extern int LastIndexOfAny(char[] anyOf, int startIndex, int count);
+
+
// Returns the index of the last occurrence of any character in value in the current instance.
// The search starts at startIndex and runs backwards to startIndex - count + 1.
// The character at position startIndex is included in the search. startIndex is the larger
// index within the string.
//
[Pure]
- public int LastIndexOf(String value) {
- return LastIndexOf(value, this.Length-1,this.Length, StringComparison.CurrentCulture);
+ public int LastIndexOf(String value)
+ {
+ return LastIndexOf(value, this.Length - 1, this.Length, StringComparison.CurrentCulture);
}
[Pure]
- public int LastIndexOf(String value, int startIndex) {
+ public int LastIndexOf(String value, int startIndex)
+ {
return LastIndexOf(value, startIndex, startIndex + 1, StringComparison.CurrentCulture);
}
[Pure]
- public int LastIndexOf(String value, int startIndex, int count) {
- if (count<0) {
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ public int LastIndexOf(String value, int startIndex, int count)
+ {
+ if (count < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
}
Contract.EndContractBlock();
@@ -284,17 +308,20 @@ namespace System
}
[Pure]
- public int LastIndexOf(String value, StringComparison comparisonType) {
- return LastIndexOf(value, this.Length-1, this.Length, comparisonType);
+ public int LastIndexOf(String value, StringComparison comparisonType)
+ {
+ return LastIndexOf(value, this.Length - 1, this.Length, comparisonType);
}
[Pure]
- public int LastIndexOf(String value, int startIndex, StringComparison comparisonType) {
+ public int LastIndexOf(String value, int startIndex, StringComparison comparisonType)
+ {
return LastIndexOf(value, startIndex, startIndex + 1, comparisonType);
}
[Pure]
- public int LastIndexOf(String value, int startIndex, int count, StringComparison comparisonType) {
+ public int LastIndexOf(String value, int startIndex, int count, StringComparison comparisonType)
+ {
if (value == null)
throw new ArgumentNullException(nameof(value));
Contract.EndContractBlock();
@@ -305,8 +332,8 @@ namespace System
// Now after handling empty strings, make sure we're not out of range
if (startIndex < 0 || startIndex > this.Length)
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
-
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
+
// Make sure that we allow startIndex == this.Length
if (startIndex == this.Length)
{
@@ -321,10 +348,11 @@ namespace System
// 2nd half of this also catches when startIndex == MAXINT, so MAXINT - 0 + 1 == -1, which is < 0.
if (count < 0 || startIndex - count + 1 < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Count"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
- switch (comparisonType) {
+ switch (comparisonType)
+ {
case StringComparison.CurrentCulture:
return CultureInfo.CurrentCulture.CompareInfo.LastIndexOf(this, value, startIndex, count, CompareOptions.None);
@@ -338,15 +366,15 @@ namespace System
return CultureInfo.InvariantCulture.CompareInfo.LastIndexOf(this, value, startIndex, count, CompareOptions.IgnoreCase);
case StringComparison.Ordinal:
return CultureInfo.InvariantCulture.CompareInfo.LastIndexOf(this, value, startIndex, count, CompareOptions.Ordinal);
-
+
case StringComparison.OrdinalIgnoreCase:
if (value.IsAscii() && this.IsAscii())
return CultureInfo.InvariantCulture.CompareInfo.LastIndexOf(this, value, startIndex, count, CompareOptions.IgnoreCase);
else
return TextInfo.LastIndexOfStringOrdinalIgnoreCase(this, value, startIndex, count);
default:
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
- }
+ throw new ArgumentException(SR.NotSupported_StringComparison, nameof(comparisonType));
+ }
}
}
}
diff --git a/src/mscorlib/src/System/String.cs b/src/mscorlib/src/System/String.cs
index 175e396633..f3a4d0f197 100644
--- a/src/mscorlib/src/System/String.cs
+++ b/src/mscorlib/src/System/String.cs
@@ -11,7 +11,9 @@
**
**
===========================================================*/
-namespace System {
+
+namespace System
+{
using System.Text;
using System;
using System.Runtime;
@@ -19,9 +21,9 @@ namespace System {
using System.Globalization;
using System.Threading;
using System.Collections;
- using System.Collections.Generic;
+ using System.Collections.Generic;
using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
+ using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using Microsoft.Win32;
using System.Diagnostics;
@@ -36,12 +38,11 @@ namespace System {
// instance and return the result as a new String. All comparison methods are
// implemented as a part of String. As with arrays, character positions
// (indices) are zero-based.
-
+
[Serializable]
public sealed partial class String : IComparable, ICloneable, IConvertible, IEnumerable
, IComparable<String>, IEnumerable<char>, IEquatable<String>
{
-
//
//NOTE NOTE NOTE NOTE
//These fields map directly onto the fields in an EE StringObject. See object.h for the layout.
@@ -51,7 +52,7 @@ namespace System {
// For empty strings, this will be '\0' since
// strings are both null-terminated and length prefixed
[NonSerialized] private char m_firstChar;
-
+
// The Empty constant holds the empty string value. It is initialized by the EE during startup.
// It is treated as intrinsic by the JIT as so the static constructor would never run.
// Leaving it uninitialized would confuse debuggers.
@@ -67,7 +68,8 @@ namespace System {
// than 0x80) before security is fully initialized. Without security initialized, we can't grab resources (the nlp's)
// from the assembly. This provides a workaround for that problem and should NOT be used anywhere else.
//
- internal unsafe static string SmallCharToUpper(string strIn) {
+ internal unsafe static string SmallCharToUpper(string strIn)
+ {
Contract.Requires(strIn != null);
Contract.EndContractBlock();
//
@@ -78,9 +80,10 @@ namespace System {
//
int length = strIn.Length;
String strOut = FastAllocateString(length);
- fixed (char * inBuff = &strIn.m_firstChar, outBuff = &strOut.m_firstChar) {
-
- for(int i = 0; i < length; i++) {
+ fixed (char* inBuff = &strIn.m_firstChar, outBuff = &strOut.m_firstChar)
+ {
+ for (int i = 0; i < length; i++)
+ {
int c = inBuff[i];
Debug.Assert(c <= 0x7F, "string has to be ASCII");
@@ -90,16 +93,17 @@ namespace System {
outBuff[i] = (char)c;
}
- Debug.Assert(outBuff[length]=='\0', "outBuff[length]=='\0'");
+ Debug.Assert(outBuff[length] == '\0', "outBuff[length]=='\0'");
}
return strOut;
}
-
+
// Gets the character at a specified position.
//
// Spec#: Apply the precondition here using a contract assembly. Potential perf issue.
[System.Runtime.CompilerServices.IndexerName("Chars")]
- public extern char this[int index] {
+ public extern char this[int index]
+ {
[MethodImpl(MethodImplOptions.InternalCall)]
get;
}
@@ -114,31 +118,32 @@ namespace System {
if (destination == null)
throw new ArgumentNullException(nameof(destination));
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NegativeCount);
if (sourceIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(sourceIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(sourceIndex), SR.ArgumentOutOfRange_Index);
if (count > Length - sourceIndex)
- throw new ArgumentOutOfRangeException(nameof(sourceIndex), Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
+ throw new ArgumentOutOfRangeException(nameof(sourceIndex), SR.ArgumentOutOfRange_IndexCount);
if (destinationIndex > destination.Length - count || destinationIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(destinationIndex), Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
+ throw new ArgumentOutOfRangeException(nameof(destinationIndex), SR.ArgumentOutOfRange_IndexCount);
Contract.EndContractBlock();
// Note: fixed does not like empty arrays
if (count > 0)
{
- fixed (char* src = &this.m_firstChar)
- fixed (char* dest = destination)
- wstrcpy(dest + destinationIndex, src + sourceIndex, count);
+ fixed (char* src = &m_firstChar)
+ fixed (char* dest = destination)
+ wstrcpy(dest + destinationIndex, src + sourceIndex, count);
}
}
-
+
// Returns the entire string as an array of characters.
- unsafe public char[] ToCharArray() {
+ unsafe public char[] ToCharArray()
+ {
int length = Length;
if (length > 0)
{
char[] chars = new char[length];
- fixed (char* src = &this.m_firstChar) fixed (char* dest = chars)
+ fixed (char* src = &m_firstChar) fixed (char* dest = chars)
{
wstrcpy(dest, src, length);
}
@@ -147,22 +152,22 @@ namespace System {
return Array.Empty<char>();
}
-
+
// Returns a substring of this string as an array of characters.
//
unsafe public char[] ToCharArray(int startIndex, int length)
{
// Range check everything.
if (startIndex < 0 || startIndex > Length || startIndex > Length - length)
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
if (length < 0)
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_Index);
Contract.EndContractBlock();
if (length > 0)
{
char[] chars = new char[length];
- fixed (char* src = &this.m_firstChar) fixed (char* dest = chars)
+ fixed (char* src = &m_firstChar) fixed (char* dest = chars)
{
wstrcpy(dest, src + startIndex, length);
}
@@ -173,16 +178,19 @@ namespace System {
}
[Pure]
- public static bool IsNullOrEmpty(String value) {
+ public static bool IsNullOrEmpty(String value)
+ {
return (value == null || value.Length == 0);
}
[Pure]
- public static bool IsNullOrWhiteSpace(String value) {
+ public static bool IsNullOrWhiteSpace(String value)
+ {
if (value == null) return true;
- for(int i = 0; i < value.Length; i++) {
- if(!Char.IsWhiteSpace(value[i])) return false;
+ for (int i = 0; i < value.Length; i++)
+ {
+ if (!Char.IsWhiteSpace(value[i])) return false;
}
return true;
@@ -196,55 +204,60 @@ namespace System {
/// The actually code generated for this will be one instruction and will be inlined.
//
// Spec#: Add postcondition in a contract assembly. Potential perf problem.
- public extern int Length {
+ public extern int Length
+ {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
}
-
+
// Creates a new string with the characters copied in from ptr. If
// ptr is null, a 0-length string (like String.Empty) is returned.
//
[CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe public extern String(char *value);
+ unsafe public extern String(char* value);
[CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe public extern String(char *value, int startIndex, int length);
-
+ unsafe public extern String(char* value, int startIndex, int length);
+
[CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe public extern String(sbyte *value);
+ unsafe public extern String(sbyte* value);
[CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe public extern String(sbyte *value, int startIndex, int length);
+ unsafe public extern String(sbyte* value, int startIndex, int length);
[CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe public extern String(sbyte *value, int startIndex, int length, Encoding enc);
-
- unsafe static private String CreateString(sbyte *value, int startIndex, int length, Encoding enc) {
+ unsafe public extern String(sbyte* value, int startIndex, int length, Encoding enc);
+
+ unsafe static private String CreateString(sbyte* value, int startIndex, int length, Encoding enc)
+ {
if (enc == null)
return new String(value, startIndex, length); // default to ANSI
if (length < 0)
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NeedNonNegNum);
if (startIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
- if ((value + startIndex) < value) {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex);
+ if ((value + startIndex) < value)
+ {
// overflow check
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_PartialWCHAR"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_PartialWCHAR);
}
- byte [] b = new byte[length];
+ byte[] b = new byte[length];
- try {
+ try
+ {
Buffer.Memcpy(b, 0, (byte*)value, startIndex, length);
}
- catch(NullReferenceException) {
+ catch (NullReferenceException)
+ {
// If we got a NullReferencException. It means the pointer or
// the index is out of range
- throw new ArgumentOutOfRangeException(nameof(value),
- Environment.GetResourceString("ArgumentOutOfRange_PartialWCHAR"));
+ throw new ArgumentOutOfRangeException(nameof(value),
+ SR.ArgumentOutOfRange_PartialWCHAR);
}
return enc.GetString(b);
}
-
+
// Helper for encodings so they can talk to our buffer directly
// stringLength must be the exact size we'll expect
unsafe static internal String CreateStringFromEncoding(
@@ -256,17 +269,17 @@ namespace System {
// Get our string length
int stringLength = encoding.GetCharCount(bytes, byteLength, null);
Debug.Assert(stringLength >= 0, "stringLength >= 0");
-
+
// They gave us an empty string if they needed one
// 0 bytelength might be possible if there's something in an encoder
if (stringLength == 0)
return String.Empty;
-
+
String s = FastAllocateString(stringLength);
- fixed(char* pTempChars = &s.m_firstChar)
+ fixed (char* pTempChars = &s.m_firstChar)
{
int doubleCheck = encoding.GetChars(bytes, byteLength, pTempChars, stringLength, null);
- Debug.Assert(stringLength == doubleCheck,
+ Debug.Assert(stringLength == doubleCheck,
"Expected encoding.GetChars to return same length as encoding.GetCharCount");
}
@@ -282,17 +295,17 @@ namespace System {
result.m_firstChar = c;
return result;
}
-
- unsafe internal int GetBytesFromEncoding(byte* pbNativeBuffer, int cbNativeBuffer,Encoding encoding)
+
+ unsafe internal int GetBytesFromEncoding(byte* pbNativeBuffer, int cbNativeBuffer, Encoding encoding)
{
// encoding == Encoding.UTF8
- fixed (char* pwzChar = &this.m_firstChar)
+ fixed (char* pwzChar = &m_firstChar)
{
return encoding.GetBytes(pwzChar, m_stringLength, pbNativeBuffer, cbNativeBuffer);
- }
+ }
}
- unsafe internal int ConvertToAnsi(byte *pbNativeBuffer, int cbNativeBuffer, bool fBestFit, bool fThrowOnUnmappableChar)
+ unsafe internal int ConvertToAnsi(byte* pbNativeBuffer, int cbNativeBuffer, bool fBestFit, bool fThrowOnUnmappableChar)
{
Debug.Assert(cbNativeBuffer >= (Length + 1) * Marshal.SystemMaxDBCSCharSize, "Insufficient buffer length passed to ConvertToAnsi");
@@ -304,7 +317,7 @@ namespace System {
uint flgs = (fBestFit ? 0 : WC_NO_BEST_FIT_CHARS);
uint DefaultCharUsed = 0;
- fixed (char* pwzChar = &this.m_firstChar)
+ fixed (char* pwzChar = &m_firstChar)
{
nb = Win32Native.WideCharToMultiByte(
CP_ACP,
@@ -319,7 +332,7 @@ namespace System {
if (0 != DefaultCharUsed)
{
- throw new ArgumentException(Environment.GetResourceString("Interop_Marshal_Unmappable_Char"));
+ throw new ArgumentException(SR.Interop_Marshal_Unmappable_Char);
}
pbNativeBuffer[nb] = 0;
@@ -339,12 +352,12 @@ namespace System {
if (this.IsFastSort())
{
// If its FastSort && one of the 4 main forms, then its already normalized
- if( normalizationForm == NormalizationForm.FormC ||
+ if (normalizationForm == NormalizationForm.FormC ||
normalizationForm == NormalizationForm.FormKC ||
normalizationForm == NormalizationForm.FormD ||
- normalizationForm == NormalizationForm.FormKD )
+ normalizationForm == NormalizationForm.FormKD)
return true;
- }
+ }
return Normalization.IsNormalized(this, normalizationForm);
}
@@ -359,10 +372,10 @@ namespace System {
if (this.IsAscii())
{
// If its FastSort && one of the 4 main forms, then its already normalized
- if( normalizationForm == NormalizationForm.FormC ||
+ if (normalizationForm == NormalizationForm.FormC ||
normalizationForm == NormalizationForm.FormKC ||
normalizationForm == NormalizationForm.FormD ||
- normalizationForm == NormalizationForm.FormKD )
+ normalizationForm == NormalizationForm.FormKD)
return this;
}
return Normalization.Normalize(this, normalizationForm);
@@ -376,27 +389,30 @@ namespace System {
// startIndex + length - 1.
//
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public extern String(char [] value, int startIndex, int length);
-
+ public extern String(char[] value, int startIndex, int length);
+
// Creates a new string from the characters in a subarray. The new string will be
// created from the characters in value.
//
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public extern String(char [] value);
+ public extern String(char[] value);
- internal static unsafe void wstrcpy(char *dmem, char *smem, int charCount)
+ internal static unsafe void wstrcpy(char* dmem, char* smem, int charCount)
{
Buffer.Memcpy((byte*)dmem, (byte*)smem, charCount * 2); // 2 used everywhere instead of sizeof(char)
}
- private String CtorCharArray(char [] value)
+ private String CtorCharArray(char[] value)
{
- if (value != null && value.Length != 0) {
+ if (value != null && value.Length != 0)
+ {
String result = FastAllocateString(value.Length);
- unsafe {
- fixed (char* dest = &result.m_firstChar, source = value) {
+ unsafe
+ {
+ fixed (char* dest = &result.m_firstChar, source = value)
+ {
wstrcpy(dest, source, value.Length);
}
}
@@ -406,26 +422,29 @@ namespace System {
return String.Empty;
}
- private String CtorCharArrayStartLength(char [] value, int startIndex, int length)
+ private String CtorCharArrayStartLength(char[] value, int startIndex, int length)
{
if (value == null)
throw new ArgumentNullException(nameof(value));
if (startIndex < 0)
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex);
if (length < 0)
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NegativeLength);
if (startIndex > value.Length - length)
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
Contract.EndContractBlock();
- if (length > 0) {
+ if (length > 0)
+ {
String result = FastAllocateString(length);
- unsafe {
- fixed (char* dest = &result.m_firstChar, source = value) {
+ unsafe
+ {
+ fixed (char* dest = &result.m_firstChar, source = value)
+ {
wstrcpy(dest, source + startIndex, length);
}
}
@@ -437,29 +456,36 @@ namespace System {
private String CtorCharCount(char c, int count)
{
- if (count > 0) {
+ if (count > 0)
+ {
String result = FastAllocateString(count);
if (c != 0)
{
- unsafe {
- fixed (char* dest = &result.m_firstChar) {
- char *dmem = dest;
- while (((uint)dmem & 3) != 0 && count > 0) {
+ unsafe
+ {
+ fixed (char* dest = &result.m_firstChar)
+ {
+ char* dmem = dest;
+ while (((uint)dmem & 3) != 0 && count > 0)
+ {
*dmem++ = c;
count--;
}
uint cc = (uint)((c << 16) | c);
- if (count >= 4) {
+ if (count >= 4)
+ {
count -= 4;
- do{
- ((uint *)dmem)[0] = cc;
- ((uint *)dmem)[1] = cc;
+ do
+ {
+ ((uint*)dmem)[0] = cc;
+ ((uint*)dmem)[1] = cc;
dmem += 4;
count -= 4;
} while (count >= 0);
}
- if ((count & 2) != 0) {
- ((uint *)dmem)[0] = cc;
+ if ((count & 2) != 0)
+ {
+ ((uint*)dmem)[0] = cc;
dmem += 2;
}
if ((count & 1) != 0)
@@ -472,13 +498,13 @@ namespace System {
else if (count == 0)
return String.Empty;
else
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", nameof(count)));
+ throw new ArgumentOutOfRangeException(nameof(count), SR.Format(SR.ArgumentOutOfRange_MustBeNonNegNum, nameof(count)));
}
- private static unsafe int wcslen(char *ptr)
+ internal static unsafe int wcslen(char* ptr)
{
- char *end = ptr;
-
+ char* end = ptr;
+
// First make sure our pointer is aligned on a word boundary
int alignment = IntPtr.Size - 1;
@@ -527,7 +553,7 @@ namespace System {
// NOTE: We can access a ulong a time since the ptr is aligned,
// and therefore we're only accessing the same word/page. (See notes
// for the 32-bit version above.)
-
+
const ulong MagicMask = 0x7fff7fff7fff7fff;
while (true)
@@ -555,13 +581,13 @@ namespace System {
end += 4;
}
- EndAt3: end++;
- EndAt2: end++;
- EndAt1: end++;
- EndAt0:
+ EndAt3: end++;
+ EndAt2: end++;
+ EndAt1: end++;
+ EndAt0:
#endif // !BIT64
- FoundZero:
+ FoundZero:
Debug.Assert(*end == 0);
int count = (int)(end - ptr);
@@ -569,19 +595,20 @@ namespace System {
return count;
}
- private unsafe String CtorCharPtr(char *ptr)
+ private unsafe String CtorCharPtr(char* ptr)
{
if (ptr == null)
return String.Empty;
#if !FEATURE_PAL
if (ptr < (char*)64000)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeStringPtrNotAtom"));
+ throw new ArgumentException(SR.Arg_MustBeStringPtrNotAtom);
#endif // FEATURE_PAL
Debug.Assert(this == null, "this == null"); // this is the string constructor, we allocate it
- try {
+ try
+ {
int count = wcslen(ptr);
if (count == 0)
return String.Empty;
@@ -591,27 +618,31 @@ namespace System {
wstrcpy(dest, ptr, count);
return result;
}
- catch (NullReferenceException) {
- throw new ArgumentOutOfRangeException(nameof(ptr), Environment.GetResourceString("ArgumentOutOfRange_PartialWCHAR"));
+ catch (NullReferenceException)
+ {
+ throw new ArgumentOutOfRangeException(nameof(ptr), SR.ArgumentOutOfRange_PartialWCHAR);
}
}
- private unsafe String CtorCharPtrStartLength(char *ptr, int startIndex, int length)
+ private unsafe String CtorCharPtrStartLength(char* ptr, int startIndex, int length)
{
- if (length < 0) {
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
+ if (length < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_NegativeLength);
}
- if (startIndex < 0) {
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
+ if (startIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_StartIndex);
}
Contract.EndContractBlock();
Debug.Assert(this == null, "this == null"); // this is the string constructor, we allocate it
- char *pFrom = ptr + startIndex;
- if (pFrom < ptr) {
+ char* pFrom = ptr + startIndex;
+ if (pFrom < ptr)
+ {
// This means that the pointer operation has had an overflow
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_PartialWCHAR"));
+ throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_PartialWCHAR);
}
if (length == 0)
@@ -619,43 +650,50 @@ namespace System {
String result = FastAllocateString(length);
- try {
+ try
+ {
fixed (char* dest = &result.m_firstChar)
wstrcpy(dest, pFrom, length);
return result;
}
- catch (NullReferenceException) {
- throw new ArgumentOutOfRangeException(nameof(ptr), Environment.GetResourceString("ArgumentOutOfRange_PartialWCHAR"));
+ catch (NullReferenceException)
+ {
+ throw new ArgumentOutOfRangeException(nameof(ptr), SR.ArgumentOutOfRange_PartialWCHAR);
}
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern String(char c, int count);
-
+
// Returns this string.
- public override String ToString() {
+ public override String ToString()
+ {
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
return this;
}
- public String ToString(IFormatProvider provider) {
+ public String ToString(IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
Contract.EndContractBlock();
return this;
}
-
+
// Method required for the ICloneable interface.
// There's no point in cloning a string since they're immutable, so we simply return this.
- public Object Clone() {
+ public Object Clone()
+ {
Contract.Ensures(Contract.Result<Object>() != null);
Contract.EndContractBlock();
return this;
}
-
- unsafe public static String Copy (String str) {
- if (str==null) {
+
+ unsafe public static String Copy(String str)
+ {
+ if (str == null)
+ {
throw new ArgumentNullException(nameof(str));
}
Contract.Ensures(Contract.Result<String>() != null);
@@ -665,15 +703,18 @@ namespace System {
String result = FastAllocateString(length);
- fixed(char* dest = &result.m_firstChar)
- fixed(char* src = &str.m_firstChar) {
- wstrcpy(dest, src, length);
- }
- return result;
+ fixed (char* dest = &result.m_firstChar)
+ fixed (char* src = &str.m_firstChar)
+ {
+ wstrcpy(dest, src, length);
+ }
+ return result;
}
-
- public static String Intern(String str) {
- if (str==null) {
+
+ public static String Intern(String str)
+ {
+ if (str == null)
+ {
throw new ArgumentNullException(nameof(str));
}
Contract.Ensures(Contract.Result<String>().Length == str.Length);
@@ -684,8 +725,10 @@ namespace System {
}
[Pure]
- public static String IsInterned(String str) {
- if (str==null) {
+ public static String IsInterned(String str)
+ {
+ if (str == null)
+ {
throw new ArgumentNullException(nameof(str));
}
Contract.Ensures(Contract.Result<String>() == null || Contract.Result<String>().Length == str.Length);
@@ -698,83 +741,84 @@ namespace System {
//
// IConvertible implementation
//
-
- public TypeCode GetTypeCode() {
+
+ public TypeCode GetTypeCode()
+ {
return TypeCode.String;
}
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
return Convert.ToBoolean(this, provider);
}
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
return Convert.ToChar(this, provider);
}
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
return Convert.ToSByte(this, provider);
}
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
return Convert.ToByte(this, provider);
}
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
return Convert.ToInt16(this, provider);
}
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
return Convert.ToUInt16(this, provider);
}
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
return Convert.ToInt32(this, provider);
}
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
return Convert.ToUInt32(this, provider);
}
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
return Convert.ToInt64(this, provider);
}
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
return Convert.ToUInt64(this, provider);
}
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
return Convert.ToSingle(this, provider);
}
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
return Convert.ToDouble(this, provider);
}
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider) {
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
return Convert.ToDecimal(this, provider);
}
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
return Convert.ToDateTime(this, provider);
}
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
return Convert.DefaultToType((IConvertible)this, type, provider);
}
@@ -795,41 +839,45 @@ namespace System {
internal extern bool TryGetTrailByte(out byte data);
#endif
- public CharEnumerator GetEnumerator() {
+ public CharEnumerator GetEnumerator()
+ {
Contract.Ensures(Contract.Result<CharEnumerator>() != null);
Contract.EndContractBlock();
BCLDebug.Perf(false, "Avoid using String's CharEnumerator until C# special cases foreach on String - use the indexed property on String instead.");
return new CharEnumerator(this);
}
- IEnumerator<char> IEnumerable<char>.GetEnumerator() {
+ IEnumerator<char> IEnumerable<char>.GetEnumerator()
+ {
Contract.Ensures(Contract.Result<IEnumerator<char>>() != null);
Contract.EndContractBlock();
BCLDebug.Perf(false, "Avoid using String's CharEnumerator until C# special cases foreach on String - use the indexed property on String instead.");
return new CharEnumerator(this);
}
- /// <internalonly/>
- IEnumerator IEnumerable.GetEnumerator() {
+ IEnumerator IEnumerable.GetEnumerator()
+ {
Contract.Ensures(Contract.Result<IEnumerator>() != null);
Contract.EndContractBlock();
BCLDebug.Perf(false, "Avoid using String's CharEnumerator until C# special cases foreach on String - use the indexed property on String instead.");
return new CharEnumerator(this);
}
- // Copies the source String (byte buffer) to the destination IntPtr memory allocated with len bytes.
- internal unsafe static void InternalCopy(String src, IntPtr dest,int len)
+ // Copies the source String (byte buffer) to the destination IntPtr memory allocated with len bytes.
+ internal unsafe static void InternalCopy(String src, IntPtr dest, int len)
{
if (len == 0)
return;
- fixed(char* charPtr = &src.m_firstChar) {
- byte* srcPtr = (byte*) charPtr;
- byte* dstPtr = (byte*) dest;
+ fixed (char* charPtr = &src.m_firstChar)
+ {
+ byte* srcPtr = (byte*)charPtr;
+ byte* dstPtr = (byte*)dest;
Buffer.Memcpy(dstPtr, srcPtr, len);
}
}
- internal ref char GetFirstCharRef() {
+ internal ref char GetFirstCharRef()
+ {
return ref m_firstChar;
}
}
diff --git a/src/mscorlib/src/System/StringComparer.cs b/src/mscorlib/src/System/StringComparer.cs
deleted file mode 100644
index cf65c48c2b..0000000000
--- a/src/mscorlib/src/System/StringComparer.cs
+++ /dev/null
@@ -1,300 +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.
-
-
-namespace System {
- using System.Collections;
- using System.Collections.Generic;
- using System.Globalization;
- using System.Diagnostics.Contracts;
- using System.Runtime.Serialization;
- using System.Runtime.CompilerServices;
-
-
- [Serializable]
- public abstract class StringComparer : IComparer, IEqualityComparer, IComparer<string>, IEqualityComparer<string>{
- private static readonly StringComparer _invariantCulture = new CultureAwareComparer(CultureInfo.InvariantCulture, false);
- private static readonly StringComparer _invariantCultureIgnoreCase = new CultureAwareComparer(CultureInfo.InvariantCulture, true);
- private static readonly StringComparer _ordinal = new OrdinalComparer(false);
- private static readonly StringComparer _ordinalIgnoreCase = new OrdinalComparer(true);
-
- public static StringComparer InvariantCulture {
- get {
- Contract.Ensures(Contract.Result<StringComparer>() != null);
- return _invariantCulture;
- }
- }
-
- public static StringComparer InvariantCultureIgnoreCase {
- get {
- Contract.Ensures(Contract.Result<StringComparer>() != null);
- return _invariantCultureIgnoreCase;
- }
- }
-
- public static StringComparer CurrentCulture {
- get {
- Contract.Ensures(Contract.Result<StringComparer>() != null);
- return new CultureAwareComparer(CultureInfo.CurrentCulture, false);
- }
- }
-
- public static StringComparer CurrentCultureIgnoreCase {
- get {
- Contract.Ensures(Contract.Result<StringComparer>() != null);
- return new CultureAwareComparer(CultureInfo.CurrentCulture, true);
- }
- }
-
- public static StringComparer Ordinal {
- get {
- Contract.Ensures(Contract.Result<StringComparer>() != null);
- return _ordinal;
- }
- }
-
- public static StringComparer OrdinalIgnoreCase {
- get {
- Contract.Ensures(Contract.Result<StringComparer>() != null);
- return _ordinalIgnoreCase;
- }
- }
-
- // Convert a StringComparison to a StringComparer
- public static StringComparer FromComparison(StringComparison comparisonType)
- {
- switch (comparisonType)
- {
- case StringComparison.CurrentCulture:
- return CurrentCulture;
- case StringComparison.CurrentCultureIgnoreCase:
- return CurrentCultureIgnoreCase;
- case StringComparison.InvariantCulture:
- return InvariantCulture;
- case StringComparison.InvariantCultureIgnoreCase:
- return InvariantCultureIgnoreCase;
- case StringComparison.Ordinal:
- return Ordinal;
- case StringComparison.OrdinalIgnoreCase:
- return OrdinalIgnoreCase;
- default:
- throw new ArgumentException(Environment.GetResourceString("NotSupported_StringComparison"), nameof(comparisonType));
- }
- }
-
- public static StringComparer Create(CultureInfo culture, bool ignoreCase) {
- if( culture == null) {
- throw new ArgumentNullException(nameof(culture));
- }
- Contract.Ensures(Contract.Result<StringComparer>() != null);
- Contract.EndContractBlock();
-
- return new CultureAwareComparer(culture, ignoreCase);
- }
-
- public int Compare(object x, object y) {
- if (x == y) return 0;
- if (x == null) return -1;
- if (y == null) return 1;
-
- String sa = x as String;
- if (sa != null) {
- String sb = y as String;
- if( sb != null) {
- return Compare(sa, sb);
- }
- }
-
- IComparable ia = x as IComparable;
- if (ia != null) {
- return ia.CompareTo(y);
- }
-
- throw new ArgumentException(Environment.GetResourceString("Argument_ImplementIComparable"));
- }
-
-
- public new bool Equals(Object x, Object y) {
- if (x == y) return true;
- if (x == null || y == null) return false;
-
- String sa = x as String;
- if (sa != null) {
- String sb = y as String;
- if( sb != null) {
- return Equals(sa, sb);
- }
- }
- return x.Equals(y);
- }
-
- public int GetHashCode(object obj) {
- if( obj == null) {
- throw new ArgumentNullException(nameof(obj));
- }
- Contract.EndContractBlock();
-
- string s = obj as string;
- if( s != null) {
- return GetHashCode(s);
- }
- return obj.GetHashCode();
- }
-
- public abstract int Compare(String x, String y);
- public abstract bool Equals(String x, String y);
- public abstract int GetHashCode(string obj);
- }
-
- [Serializable]
- internal sealed class CultureAwareComparer : StringComparer
-#if FEATURE_RANDOMIZED_STRING_HASHING
- , IWellKnownStringEqualityComparer
-#endif
- {
- private CompareInfo _compareInfo;
- private bool _ignoreCase;
-
- internal CultureAwareComparer(CultureInfo culture, bool ignoreCase) {
- _compareInfo = culture.CompareInfo;
- _ignoreCase = ignoreCase;
- }
-
- public override int Compare(string x, string y) {
- if (Object.ReferenceEquals(x, y)) return 0;
- if (x == null) return -1;
- if (y == null) return 1;
- return _compareInfo.Compare(x, y, _ignoreCase? CompareOptions.IgnoreCase : CompareOptions.None);
- }
-
- public override bool Equals(string x, string y) {
- if (Object.ReferenceEquals(x ,y)) return true;
- if (x == null || y == null) return false;
-
- return (_compareInfo.Compare(x, y, _ignoreCase? CompareOptions.IgnoreCase : CompareOptions.None) == 0);
- }
-
- public override int GetHashCode(string obj) {
- if( obj == null) {
- throw new ArgumentNullException(nameof(obj));
- }
- Contract.EndContractBlock();
-
- CompareOptions options = CompareOptions.None;
-
- if( _ignoreCase) {
- options |= CompareOptions.IgnoreCase;
- }
-
- return _compareInfo.GetHashCodeOfString(obj, options);
- }
-
- // Equals method for the comparer itself.
- public override bool Equals(Object obj){
- CultureAwareComparer comparer = obj as CultureAwareComparer;
- if( comparer == null) {
- return false;
- }
- return (this._ignoreCase == comparer._ignoreCase) && (this._compareInfo.Equals(comparer._compareInfo));
- }
-
- public override int GetHashCode() {
- int hashCode = _compareInfo.GetHashCode() ;
- return _ignoreCase ? (~hashCode) : hashCode;
- }
-
-#if FEATURE_RANDOMIZED_STRING_HASHING
-
- IEqualityComparer IWellKnownStringEqualityComparer.GetEqualityComparerForSerialization() {
- return this;
- }
-#endif
-
- }
-
- // Provide x more optimal implementation of ordinal comparison.
- [Serializable]
- internal sealed class OrdinalComparer : StringComparer
-#if FEATURE_RANDOMIZED_STRING_HASHING
- , IWellKnownStringEqualityComparer
-#endif
- {
- private bool _ignoreCase;
-
- internal OrdinalComparer(bool ignoreCase) {
- _ignoreCase = ignoreCase;
- }
-
- public override int Compare(string x, string y) {
- if (Object.ReferenceEquals(x, y)) return 0;
- if (x == null) return -1;
- if (y == null) return 1;
-
- if( _ignoreCase) {
- return String.Compare(x, y, StringComparison.OrdinalIgnoreCase);
- }
-
- return String.CompareOrdinal(x, y);
- }
-
- public override bool Equals(string x, string y) {
- if (Object.ReferenceEquals(x ,y)) return true;
- if (x == null || y == null) return false;
-
- if( _ignoreCase) {
- if( x.Length != y.Length) {
- return false;
- }
- return (String.Compare(x, y, StringComparison.OrdinalIgnoreCase) == 0);
- }
- return x.Equals(y);
- }
-
- public override int GetHashCode(string obj) {
- if( obj == null) {
- throw new ArgumentNullException(nameof(obj));
- }
- Contract.EndContractBlock();
-
- if( _ignoreCase) {
- return TextInfo.GetHashCodeOrdinalIgnoreCase(obj);
- }
-
- return obj.GetHashCode();
- }
-
- // Equals method for the comparer itself.
- public override bool Equals(Object obj){
- OrdinalComparer comparer = obj as OrdinalComparer;
- if( comparer == null) {
- return false;
- }
- return (this._ignoreCase == comparer._ignoreCase);
- }
-
- public override int GetHashCode() {
- string name = "OrdinalComparer";
- int hashCode = name.GetHashCode();
- return _ignoreCase ? (~hashCode) : hashCode;
- }
-
-#if FEATURE_RANDOMIZED_STRING_HASHING
-
- IEqualityComparer IWellKnownStringEqualityComparer.GetEqualityComparerForSerialization() {
- return this;
- }
-#endif
-
- }
-
-#if FEATURE_RANDOMIZED_STRING_HASHING
-
- // This interface is implemented by string comparers in the framework that can opt into
- // randomized hashing behaviors.
- internal interface IWellKnownStringEqualityComparer {
- // Get an IEqaulityComparer that can be serailzied (e.g., it exists in older versions).
- IEqualityComparer GetEqualityComparerForSerialization();
- }
-#endif
-}
diff --git a/src/mscorlib/src/System/StringComparison.cs b/src/mscorlib/src/System/StringComparison.cs
deleted file mode 100644
index c654f7200f..0000000000
--- a/src/mscorlib/src/System/StringComparison.cs
+++ /dev/null
@@ -1,29 +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.
-
-/*============================================================
-**
-** Enum: StringComparison
-**
-**
-** Purpose: A mechanism to expose a simplified infrastructure for
-** Comparing strings. This enum lets you choose of the custom
-** implementations provided by the runtime for the user.
-**
-**
-===========================================================*/
-
-namespace System
-{
- [Serializable]
- public enum StringComparison
- {
- CurrentCulture = 0,
- CurrentCultureIgnoreCase = 1,
- InvariantCulture = 2,
- InvariantCultureIgnoreCase = 3,
- Ordinal = 4,
- OrdinalIgnoreCase = 5,
- }
-}
diff --git a/src/mscorlib/src/System/StringFreezingAttribute.cs b/src/mscorlib/src/System/StringFreezingAttribute.cs
deleted file mode 100644
index d488a88445..0000000000
--- a/src/mscorlib/src/System/StringFreezingAttribute.cs
+++ /dev/null
@@ -1,25 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose: Custom attribute to indicate that strings should be frozen
-**
-**
-===========================================================*/
-
-namespace System.Runtime.CompilerServices
-{
-
-[Serializable]
- [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
- public sealed class StringFreezingAttribute : Attribute
- {
- public StringFreezingAttribute()
- {
- }
- }
-}
diff --git a/src/mscorlib/src/System/StringSplitOptions.cs b/src/mscorlib/src/System/StringSplitOptions.cs
deleted file mode 100644
index 43b626a010..0000000000
--- a/src/mscorlib/src/System/StringSplitOptions.cs
+++ /dev/null
@@ -1,13 +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.
-
-namespace System
-{
- [Flags]
- public enum StringSplitOptions
- {
- None = 0,
- RemoveEmptyEntries = 1
- }
-} \ No newline at end of file
diff --git a/src/mscorlib/src/System/StubHelpers.cs b/src/mscorlib/src/System/StubHelpers.cs
index 2d5926b923..f584ece6fc 100644
--- a/src/mscorlib/src/System/StubHelpers.cs
+++ b/src/mscorlib/src/System/StubHelpers.cs
@@ -3,8 +3,8 @@
// See the LICENSE file in the project root for more information.
-namespace System.StubHelpers {
-
+namespace System.StubHelpers
+{
using System.Text;
using Microsoft.Win32;
using System.Security;
@@ -27,7 +27,7 @@ namespace System.StubHelpers {
{
byte[] buffer = new byte[(str.Length + 1) * Marshal.SystemMaxDBCSCharSize];
BCLDebug.Assert(buffer.Length != 0);
- fixed (byte *bufferPtr = &buffer[0])
+ fixed (byte* bufferPtr = &buffer[0])
{
cbLength = str.ConvertToAnsi(bufferPtr, buffer.Length, fBestFit, fThrowOnUnmappableChar);
}
@@ -65,7 +65,7 @@ namespace System.StubHelpers {
StubHelpers.CheckStringLength(strManaged.Length);
int nb;
- byte *pbNativeBuffer = (byte *)pNativeBuffer;
+ byte* pbNativeBuffer = (byte*)pNativeBuffer;
if (pbNativeBuffer != null || Marshal.SystemMaxDBCSCharSize == 1)
{
@@ -100,11 +100,11 @@ namespace System.StubHelpers {
Buffer.Memcpy(pbNativeBuffer, 0, bytes, 0, nb);
}
- pbNativeBuffer[nb] = 0x00;
+ pbNativeBuffer[nb] = 0x00;
pbNativeBuffer[nb + 1] = 0x00;
return (IntPtr)pbNativeBuffer;
- }
+ }
static internal unsafe string ConvertToManaged(IntPtr cstr)
{
@@ -122,7 +122,7 @@ namespace System.StubHelpers {
internal static class UTF8Marshaler
{
- const int MAX_UTF8_CHAR_SIZE = 3;
+ private const int MAX_UTF8_CHAR_SIZE = 3;
static internal unsafe IntPtr ConvertToNative(int flags, string strManaged, IntPtr pNativeBuffer)
{
if (null == strManaged)
@@ -249,29 +249,29 @@ namespace System.StubHelpers {
lengthInBytes++;
}
- byte *ptrToFirstChar;
+ byte* ptrToFirstChar;
if (pNativeBuffer != IntPtr.Zero)
{
// If caller provided a buffer, construct the BSTR manually. The size
// of the buffer must be at least (lengthInBytes + 6) bytes.
#if _DEBUG
- uint length = *((uint *)pNativeBuffer.ToPointer());
+ uint length = *((uint*)pNativeBuffer.ToPointer());
BCLDebug.Assert(length >= lengthInBytes + 6, "BSTR localloc'ed buffer is too small");
#endif // _DEBUG
// set length
- *((uint *)pNativeBuffer.ToPointer()) = lengthInBytes;
+ *((uint*)pNativeBuffer.ToPointer()) = lengthInBytes;
- ptrToFirstChar = (byte *)pNativeBuffer.ToPointer() + 4;
+ ptrToFirstChar = (byte*)pNativeBuffer.ToPointer() + 4;
}
else
{
// If not provided, allocate the buffer using SysAllocStringByteLen so
// that odd-sized strings will be handled as well.
- ptrToFirstChar = (byte *)Win32Native.SysAllocStringByteLen(null, lengthInBytes).ToPointer();
+ ptrToFirstChar = (byte*)Win32Native.SysAllocStringByteLen(null, lengthInBytes).ToPointer();
- if (ptrToFirstChar == null)
+ if (ptrToFirstChar == null)
{
throw new OutOfMemoryException();
}
@@ -282,7 +282,7 @@ namespace System.StubHelpers {
{
Buffer.Memcpy(
ptrToFirstChar,
- (byte *)ch,
+ (byte*)ch,
(strManaged.Length + 1) * 2);
}
@@ -334,7 +334,7 @@ namespace System.StubHelpers {
if ((length & 1) == 1)
{
// odd-sized strings need to have the trailing byte saved in their sync block
- ret.SetTrailByte(((byte *)bstr.ToPointer())[length - 1]);
+ ret.SetTrailByte(((byte*)bstr.ToPointer())[length - 1]);
}
return ret;
@@ -363,7 +363,7 @@ namespace System.StubHelpers {
}
byte* pNative;
-
+
cch = strManaged.Length;
StubHelpers.CheckStringLength(cch);
@@ -373,7 +373,7 @@ namespace System.StubHelpers {
pNative = (byte*)Marshal.AllocCoTaskMem(nbytes);
int* pLength = (int*)pNative;
-
+
pNative = pNative + sizeof(uint);
if (0 == cch)
@@ -405,7 +405,7 @@ namespace System.StubHelpers {
return new String((sbyte*)pNative, 0, cch);
}
-
+
static internal unsafe void ClearNative(IntPtr pNative)
{
if (IntPtr.Zero != pNative)
@@ -431,8 +431,8 @@ namespace System.StubHelpers {
StubHelpers.CheckStringLength(length);
- byte[] bytes = null;
- int nb = 0;
+ byte[] bytes = null;
+ int nb = 0;
if (length > 0)
{
@@ -499,23 +499,23 @@ namespace System.StubHelpers {
public Int64 UniversalTime;
};
- internal static class DateTimeOffsetMarshaler {
-
+ internal static class DateTimeOffsetMarshaler
+ {
// Numer of ticks counted between 0001-01-01, 00:00:00 and 1601-01-01, 00:00:00.
// You can get this through: (new DateTimeOffset(1601, 1, 1, 0, 0, 1, TimeSpan.Zero)).Ticks;
private const Int64 ManagedUtcTicksAtNativeZero = 504911232000000000;
- internal static void ConvertToNative(ref DateTimeOffset managedDTO, out DateTimeNative dateTime) {
-
+ internal static void ConvertToNative(ref DateTimeOffset managedDTO, out DateTimeNative dateTime)
+ {
Int64 managedUtcTicks = managedDTO.UtcTicks;
dateTime.UniversalTime = managedUtcTicks - ManagedUtcTicksAtNativeZero;
}
- internal static void ConvertToManaged(out DateTimeOffset managedLocalDTO, ref DateTimeNative nativeTicks) {
-
+ internal static void ConvertToManaged(out DateTimeOffset managedLocalDTO, ref DateTimeNative nativeTicks)
+ {
Int64 managedUtcTicks = ManagedUtcTicksAtNativeZero + nativeTicks.UniversalTime;
DateTimeOffset managedUtcDTO = new DateTimeOffset(managedUtcTicks, TimeSpan.Zero);
-
+
// Some Utc times cannot be represented in local time in certain timezones. E.g. 0001-01-01 12:00:00 AM cannot
// be represented in any timezones with a negative offset from Utc. We throw an ArgumentException in that case.
managedLocalDTO = managedUtcDTO.ToLocalTime(true);
@@ -532,7 +532,7 @@ namespace System.StubHelpers {
internal static unsafe IntPtr ConvertToNative(string managed)
{
if (!Environment.IsWinRTSupported)
- throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_WinRT);
if (managed == null)
throw new ArgumentNullException(); // We don't have enough information to get the argument name
@@ -549,16 +549,16 @@ namespace System.StubHelpers {
// the returned HSTRING object. If the string is not pinned, or becomes unpinned before the HSTRING's
// lifetime ends, the HSTRING instance will be corrupted.
internal static unsafe IntPtr ConvertToNativeReference(string managed,
- [Out] HSTRING_HEADER *hstringHeader)
+ [Out] HSTRING_HEADER* hstringHeader)
{
if (!Environment.IsWinRTSupported)
- throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_WinRT);
if (managed == null)
throw new ArgumentNullException(); // We don't have enough information to get the argument name
// The string must also be pinned by the caller to ConvertToNativeReference, which also owns
// the HSTRING_HEADER.
- fixed (char *pManaged = managed)
+ fixed (char* pManaged = managed)
{
IntPtr hstring;
int hrCreate = System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateStringReference(pManaged, managed.Length, hstringHeader, &hstring);
@@ -571,7 +571,7 @@ namespace System.StubHelpers {
{
if (!Environment.IsWinRTSupported)
{
- throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_WinRT);
}
return WindowsRuntimeMarshal.HStringToString(hstring);
@@ -651,15 +651,14 @@ namespace System.StubHelpers {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static unsafe internal extern IntPtr CreateNativeUriInstanceHelper(char* rawUri, int strLen);
-
+
static unsafe internal IntPtr CreateNativeUriInstance(string rawUri)
{
- fixed(char* pManaged = rawUri)
+ fixed (char* pManaged = rawUri)
{
return CreateNativeUriInstanceHelper(pManaged, rawUri.Length);
}
}
-
} // class InterfaceMarshaler
[FriendAccessAllowed]
@@ -703,7 +702,7 @@ namespace System.StubHelpers {
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, int dwFlags);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void ConvertSpaceToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
@@ -719,7 +718,7 @@ namespace System.StubHelpers {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void ClearNative(IntPtr pMarshalState, IntPtr pNativeHome, int cElements);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void ClearNativeContents(IntPtr pMarshalState, IntPtr pNativeHome, int cElements);
} // class MngdNativeArrayMarshaler
@@ -729,7 +728,7 @@ namespace System.StubHelpers {
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, int iRank, int dwFlags);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void ConvertSpaceToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
@@ -750,7 +749,7 @@ namespace System.StubHelpers {
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pMT, IntPtr cbElementSize, ushort vt);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void ConvertSpaceToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
@@ -761,7 +760,7 @@ namespace System.StubHelpers {
{
if (managedArray != null)
{
- DateTimeNative *nativeBuffer = *(DateTimeNative **)pNativeHome;
+ DateTimeNative* nativeBuffer = *(DateTimeNative**)pNativeHome;
for (int i = 0; i < managedArray.Length; i++)
{
DateTimeOffsetMarshaler.ConvertToNative(ref managedArray[i], out nativeBuffer[i]);
@@ -773,7 +772,7 @@ namespace System.StubHelpers {
{
if (managedArray != null)
{
- TypeNameNative *nativeBuffer = *(TypeNameNative **)pNativeHome;
+ TypeNameNative* nativeBuffer = *(TypeNameNative**)pNativeHome;
for (int i = 0; i < managedArray.Length; i++)
{
SystemTypeMarshaler.ConvertToNative(managedArray[i], &nativeBuffer[i]);
@@ -785,7 +784,7 @@ namespace System.StubHelpers {
{
if (managedArray != null)
{
- Int32 *nativeBuffer = *(Int32 **)pNativeHome;
+ Int32* nativeBuffer = *(Int32**)pNativeHome;
for (int i = 0; i < managedArray.Length; i++)
{
nativeBuffer[i] = HResultExceptionMarshaler.ConvertToNative(managedArray[i]);
@@ -798,7 +797,7 @@ namespace System.StubHelpers {
{
if (managedArray != null)
{
- IntPtr *nativeBuffer = *(IntPtr **)pNativeHome;
+ IntPtr* nativeBuffer = *(IntPtr**)pNativeHome;
for (int i = 0; i < managedArray.Length; i++)
{
nativeBuffer[i] = NullableMarshaler.ConvertToNative<T>(ref managedArray[i]);
@@ -810,7 +809,7 @@ namespace System.StubHelpers {
{
if (managedArray != null)
{
- IntPtr *nativeBuffer = *(IntPtr **)pNativeHome;
+ IntPtr* nativeBuffer = *(IntPtr**)pNativeHome;
for (int i = 0; i < managedArray.Length; i++)
{
nativeBuffer[i] = KeyValuePairMarshaler.ConvertToNative<K, V>(ref managedArray[i]);
@@ -828,7 +827,7 @@ namespace System.StubHelpers {
{
if (managedArray != null)
{
- DateTimeNative *nativeBuffer = *(DateTimeNative **)pNativeHome;
+ DateTimeNative* nativeBuffer = *(DateTimeNative**)pNativeHome;
for (int i = 0; i < managedArray.Length; i++)
{
DateTimeOffsetMarshaler.ConvertToManaged(out managedArray[i], ref nativeBuffer[i]);
@@ -840,7 +839,7 @@ namespace System.StubHelpers {
{
if (managedArray != null)
{
- TypeNameNative *nativeBuffer = *(TypeNameNative **)pNativeHome;
+ TypeNameNative* nativeBuffer = *(TypeNameNative**)pNativeHome;
for (int i = 0; i < managedArray.Length; i++)
{
SystemTypeMarshaler.ConvertToManaged(&nativeBuffer[i], ref managedArray[i]);
@@ -852,7 +851,7 @@ namespace System.StubHelpers {
{
if (managedArray != null)
{
- Int32 *nativeBuffer = *(Int32 **)pNativeHome;
+ Int32* nativeBuffer = *(Int32**)pNativeHome;
for (int i = 0; i < managedArray.Length; i++)
{
managedArray[i] = HResultExceptionMarshaler.ConvertToManaged(nativeBuffer[i]);
@@ -865,7 +864,7 @@ namespace System.StubHelpers {
{
if (managedArray != null)
{
- IntPtr *nativeBuffer = *(IntPtr **)pNativeHome;
+ IntPtr* nativeBuffer = *(IntPtr**)pNativeHome;
for (int i = 0; i < managedArray.Length; i++)
{
managedArray[i] = NullableMarshaler.ConvertToManaged<T>(nativeBuffer[i]);
@@ -877,7 +876,7 @@ namespace System.StubHelpers {
{
if (managedArray != null)
{
- IntPtr *nativeBuffer = *(IntPtr **)pNativeHome;
+ IntPtr* nativeBuffer = *(IntPtr**)pNativeHome;
for (int i = 0; i < managedArray.Length; i++)
{
managedArray[i] = KeyValuePairMarshaler.ConvertToManaged<K, V>(nativeBuffer[i]);
@@ -892,7 +891,7 @@ namespace System.StubHelpers {
{
Debug.Assert(Environment.IsWinRTSupported);
- TypeNameNative *pNativeTypeArray = *(TypeNameNative **)pNativeHome;
+ TypeNameNative* pNativeTypeArray = *(TypeNameNative**)pNativeHome;
if (pNativeTypeArray != null)
{
for (int i = 0; i < cElements; ++i)
@@ -910,7 +909,7 @@ namespace System.StubHelpers {
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void CreateMarshaler(IntPtr pMarshalState, IntPtr pCMHelper);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void ConvertContentsToNative(IntPtr pMarshalState, ref object pManagedHome, IntPtr pNativeHome);
@@ -927,7 +926,7 @@ namespace System.StubHelpers {
internal struct AsAnyMarshaler
{
private const ushort VTHACK_ANSICHAR = 253;
- private const ushort VTHACK_WINBOOL = 254;
+ private const ushort VTHACK_WINBOOL = 254;
private enum BackPropAction
{
@@ -950,9 +949,9 @@ namespace System.StubHelpers {
// Cleanup list to be destroyed when clearing the native view (for layouts with SafeHandles).
private CleanupWorkList cleanupWorkList;
- private static bool IsIn(int dwFlags) { return ((dwFlags & 0x10000000) != 0); }
- private static bool IsOut(int dwFlags) { return ((dwFlags & 0x20000000) != 0); }
- private static bool IsAnsi(int dwFlags) { return ((dwFlags & 0x00FF0000) != 0); }
+ private static bool IsIn(int dwFlags) { return ((dwFlags & 0x10000000) != 0); }
+ private static bool IsOut(int dwFlags) { return ((dwFlags & 0x20000000) != 0); }
+ private static bool IsAnsi(int dwFlags) { return ((dwFlags & 0x00FF0000) != 0); }
private static bool IsThrowOn(int dwFlags) { return ((dwFlags & 0x0000FF00) != 0); }
private static bool IsBestFit(int dwFlags) { return ((dwFlags & 0x000000FF) != 0); }
@@ -962,9 +961,9 @@ namespace System.StubHelpers {
BCLDebug.Assert(pvArrayMarshaler != IntPtr.Zero, "pvArrayMarshaler must not be null");
this.pvArrayMarshaler = pvArrayMarshaler;
- this.backPropAction = BackPropAction.None;
- this.layoutType = null;
- this.cleanupWorkList = null;
+ backPropAction = BackPropAction.None;
+ layoutType = null;
+ cleanupWorkList = null;
}
#region ConvertToNative helpers
@@ -976,35 +975,35 @@ namespace System.StubHelpers {
switch (Type.GetTypeCode(elementType))
{
- case TypeCode.SByte: vt = VarEnum.VT_I1; break;
- case TypeCode.Byte: vt = VarEnum.VT_UI1; break;
- case TypeCode.Int16: vt = VarEnum.VT_I2; break;
- case TypeCode.UInt16: vt = VarEnum.VT_UI2; break;
- case TypeCode.Int32: vt = VarEnum.VT_I4; break;
- case TypeCode.UInt32: vt = VarEnum.VT_UI4; break;
- case TypeCode.Int64: vt = VarEnum.VT_I8; break;
- case TypeCode.UInt64: vt = VarEnum.VT_UI8; break;
- case TypeCode.Single: vt = VarEnum.VT_R4; break;
- case TypeCode.Double: vt = VarEnum.VT_R8; break;
- case TypeCode.Char: vt = (IsAnsi(dwFlags) ? (VarEnum)VTHACK_ANSICHAR : VarEnum.VT_UI2); break;
+ case TypeCode.SByte: vt = VarEnum.VT_I1; break;
+ case TypeCode.Byte: vt = VarEnum.VT_UI1; break;
+ case TypeCode.Int16: vt = VarEnum.VT_I2; break;
+ case TypeCode.UInt16: vt = VarEnum.VT_UI2; break;
+ case TypeCode.Int32: vt = VarEnum.VT_I4; break;
+ case TypeCode.UInt32: vt = VarEnum.VT_UI4; break;
+ case TypeCode.Int64: vt = VarEnum.VT_I8; break;
+ case TypeCode.UInt64: vt = VarEnum.VT_UI8; break;
+ case TypeCode.Single: vt = VarEnum.VT_R4; break;
+ case TypeCode.Double: vt = VarEnum.VT_R8; break;
+ case TypeCode.Char: vt = (IsAnsi(dwFlags) ? (VarEnum)VTHACK_ANSICHAR : VarEnum.VT_UI2); break;
case TypeCode.Boolean: vt = (VarEnum)VTHACK_WINBOOL; break;
case TypeCode.Object:
- {
- if (elementType == typeof(IntPtr))
- {
- vt = (IntPtr.Size == 4 ? VarEnum.VT_I4 : VarEnum.VT_I8);
- }
- else if (elementType == typeof(UIntPtr))
{
- vt = (IntPtr.Size == 4 ? VarEnum.VT_UI4 : VarEnum.VT_UI8);
+ if (elementType == typeof(IntPtr))
+ {
+ vt = (IntPtr.Size == 4 ? VarEnum.VT_I4 : VarEnum.VT_I8);
+ }
+ else if (elementType == typeof(UIntPtr))
+ {
+ vt = (IntPtr.Size == 4 ? VarEnum.VT_UI4 : VarEnum.VT_UI8);
+ }
+ else goto default;
+ break;
}
- else goto default;
- break;
- }
default:
- throw new ArgumentException(Environment.GetResourceString("Arg_NDirectBadObject"));
+ throw new ArgumentException(SR.Arg_NDirectBadObject);
}
// marshal the object as C-style array (UnmanagedType.LPArray)
@@ -1152,7 +1151,7 @@ namespace System.StubHelpers {
// marshal the object as class with layout (UnmanagedType.LPStruct)
if (IsIn(dwFlags))
{
- StubHelpers.FmtClassUpdateNativeInternal(pManagedHome, (byte *)pNativeHome.ToPointer(), ref cleanupWorkList);
+ StubHelpers.FmtClassUpdateNativeInternal(pManagedHome, (byte*)pNativeHome.ToPointer(), ref cleanupWorkList);
}
if (IsOut(dwFlags))
{
@@ -1171,7 +1170,7 @@ namespace System.StubHelpers {
return IntPtr.Zero;
if (pManagedHome is ArrayWithOffset)
- throw new ArgumentException(Environment.GetResourceString("Arg_MarshalAsAnyRestriction"));
+ throw new ArgumentException(SR.Arg_MarshalAsAnyRestriction);
IntPtr pNativeHome;
@@ -1203,7 +1202,7 @@ namespace System.StubHelpers {
else
{
// this type is not supported for AsAny marshaling
- throw new ArgumentException(Environment.GetResourceString("Arg_NDirectBadObject"));
+ throw new ArgumentException(SR.Arg_NDirectBadObject);
}
}
@@ -1215,35 +1214,35 @@ namespace System.StubHelpers {
switch (backPropAction)
{
case BackPropAction.Array:
- {
- MngdNativeArrayMarshaler.ConvertContentsToManaged(
- pvArrayMarshaler,
- ref pManagedHome,
- new IntPtr(&pNativeHome));
- break;
- }
+ {
+ MngdNativeArrayMarshaler.ConvertContentsToManaged(
+ pvArrayMarshaler,
+ ref pManagedHome,
+ new IntPtr(&pNativeHome));
+ break;
+ }
case BackPropAction.Layout:
- {
- StubHelpers.FmtClassUpdateCLRInternal(pManagedHome, (byte *)pNativeHome.ToPointer());
- break;
- }
+ {
+ StubHelpers.FmtClassUpdateCLRInternal(pManagedHome, (byte*)pNativeHome.ToPointer());
+ break;
+ }
case BackPropAction.StringBuilderAnsi:
- {
- sbyte* ptr = (sbyte*)pNativeHome.ToPointer();
- ((StringBuilder)pManagedHome).ReplaceBufferAnsiInternal(ptr, Win32Native.lstrlenA(pNativeHome));
- break;
- }
+ {
+ sbyte* ptr = (sbyte*)pNativeHome.ToPointer();
+ ((StringBuilder)pManagedHome).ReplaceBufferAnsiInternal(ptr, Win32Native.lstrlenA(pNativeHome));
+ break;
+ }
case BackPropAction.StringBuilderUnicode:
- {
- char* ptr = (char*)pNativeHome.ToPointer();
- ((StringBuilder)pManagedHome).ReplaceBufferInternal(ptr, Win32Native.lstrlenW(pNativeHome));
- break;
- }
+ {
+ char* ptr = (char*)pNativeHome.ToPointer();
+ ((StringBuilder)pManagedHome).ReplaceBufferInternal(ptr, Win32Native.lstrlenW(pNativeHome));
+ break;
+ }
- // nothing to do for BackPropAction.None
+ // nothing to do for BackPropAction.None
}
}
@@ -1264,7 +1263,7 @@ namespace System.StubHelpers {
#if FEATURE_COMINTEROP
internal static class NullableMarshaler
- {
+ {
static internal IntPtr ConvertToNative<T>(ref Nullable<T> pManaged) where T : struct
{
if (pManaged.HasValue)
@@ -1277,7 +1276,7 @@ namespace System.StubHelpers {
return IntPtr.Zero;
}
}
-
+
static internal void ConvertToManagedRetVoid<T>(IntPtr pNative, ref Nullable<T> retObj) where T : struct
{
retObj = ConvertToManaged<T>(pNative);
@@ -1302,9 +1301,8 @@ namespace System.StubHelpers {
[StructLayout(LayoutKind.Sequential)]
internal struct TypeNameNative
{
-
- internal IntPtr typeName; // HSTRING
- internal TypeKind typeKind; // TypeKind enum
+ internal IntPtr typeName; // HSTRING
+ internal TypeKind typeKind; // TypeKind enum
}
// Corresponds to Windows.UI.Xaml.TypeSource
@@ -1319,26 +1317,26 @@ namespace System.StubHelpers {
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern string ConvertToWinRTTypeName(System.Type managedType, out bool isPrimitive);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern System.Type GetTypeFromWinRTTypeName(string typeName, out bool isPrimitive);
}
-
+
internal static class SystemTypeMarshaler
- {
- internal static unsafe void ConvertToNative(System.Type managedType, TypeNameNative *pNativeType)
+ {
+ internal static unsafe void ConvertToNative(System.Type managedType, TypeNameNative* pNativeType)
{
if (!Environment.IsWinRTSupported)
{
- throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_WinRT);
}
-
+
string typeName;
if (managedType != null)
{
if (managedType.GetType() != typeof(System.RuntimeType))
{ // The type should be exactly System.RuntimeType (and not its child System.ReflectionOnlyType, or other System.Type children)
- throw new ArgumentException(Environment.GetResourceString("Argument_WinRTSystemRuntimeType", managedType.GetType().ToString()));
+ throw new ArgumentException(SR.Format(SR.Argument_WinRTSystemRuntimeType, managedType.GetType().ToString()));
}
bool isPrimitive;
@@ -1368,14 +1366,14 @@ namespace System.StubHelpers {
int hrCreate = System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString(typeName, typeName.Length, &pNativeType->typeName);
Marshal.ThrowExceptionForHR(hrCreate, new IntPtr(-1));
}
-
- internal static unsafe void ConvertToManaged(TypeNameNative *pNativeType, ref System.Type managedType)
+
+ internal static unsafe void ConvertToManaged(TypeNameNative* pNativeType, ref System.Type managedType)
{
if (!Environment.IsWinRTSupported)
{
- throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_WinRT);
}
-
+
string typeName = WindowsRuntimeMarshal.HStringToString(pNativeType->typeName);
if (String.IsNullOrEmpty(typeName))
{
@@ -1394,11 +1392,11 @@ namespace System.StubHelpers {
// TypeSource must match
if (isPrimitive != (pNativeType->typeKind == TypeKind.Primitive))
- throw new ArgumentException(Environment.GetResourceString("Argument_Unexpected_TypeSource"));
+ throw new ArgumentException(SR.Argument_Unexpected_TypeSource);
}
}
-
- internal static unsafe void ClearNative(TypeNameNative *pNativeType)
+
+ internal static unsafe void ClearNative(TypeNameNative* pNativeType)
{
Debug.Assert(Environment.IsWinRTSupported);
@@ -1416,7 +1414,7 @@ namespace System.StubHelpers {
{
if (!Environment.IsWinRTSupported)
{
- throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_WinRT);
}
if (ex == null)
@@ -1431,7 +1429,7 @@ namespace System.StubHelpers {
if (!Environment.IsWinRTSupported)
{
- throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_WinRT"));
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_WinRT);
}
Exception e = null;
@@ -1448,13 +1446,13 @@ namespace System.StubHelpers {
} // class HResultExceptionMarshaler
internal static class KeyValuePairMarshaler
- {
+ {
internal static IntPtr ConvertToNative<K, V>([In] ref KeyValuePair<K, V> pair)
{
IKeyValuePair<K, V> impl = new CLRIKeyValuePairImpl<K, V>(ref pair);
return Marshal.GetComInterfaceForObject(impl, typeof(IKeyValuePair<K, V>));
}
-
+
internal static KeyValuePair<K, V> ConvertToManaged<K, V>(IntPtr pInsp)
{
object obj = InterfaceMarshaler.ConvertToManagedWithoutUnboxing(pInsp);
@@ -1475,10 +1473,10 @@ namespace System.StubHelpers {
[StructLayout(LayoutKind.Sequential)]
internal struct NativeVariant
{
- ushort vt;
- ushort wReserved1;
- ushort wReserved2;
- ushort wReserved3;
+ private ushort vt;
+ private ushort wReserved1;
+ private ushort wReserved2;
+ private ushort wReserved3;
// The union portion of the structure contains at least one 64-bit type that on some 32-bit platforms
// (notably ARM) requires 64-bit alignment. So on 32-bit platforms we'll actually size the variant
@@ -1487,8 +1485,8 @@ namespace System.StubHelpers {
// VARIANTs). Note that the field names here don't matter: none of the code refers to these fields,
// the structure just exists to provide size information to the IL marshaler.
#if BIT64
- IntPtr data1;
- IntPtr data2;
+ private IntPtr data1;
+ private IntPtr data2;
#else
Int64 data1;
#endif
@@ -1514,7 +1512,7 @@ namespace System.StubHelpers {
internal sealed class CleanupWorkList
{
private List<CleanupWorkListElement> m_list = new List<CleanupWorkListElement>();
-
+
public void Add(CleanupWorkListElement elem)
{
BCLDebug.Assert(elem.m_owned == false, "m_owned is supposed to be false and set later by DangerousAddRef");
@@ -1612,19 +1610,17 @@ namespace System.StubHelpers {
//-------------------------------------------------------
// SafeHandle Helpers
//-------------------------------------------------------
-
+
// AddRefs the SH and returns the underlying unmanaged handle.
static internal IntPtr SafeHandleAddRef(SafeHandle pHandle, ref bool success)
{
if (pHandle == null)
{
- throw new ArgumentNullException(nameof(pHandle), Environment.GetResourceString("ArgumentNull_SafeHandle"));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.pHandle, ExceptionResource.ArgumentNull_SafeHandle);
}
- Contract.EndContractBlock();
pHandle.DangerousAddRef(ref success);
-
- return (success ? pHandle.DangerousGetHandle() : IntPtr.Zero);
+ return pHandle.DangerousGetHandle();
}
// Releases the SH (to be called from finally block).
@@ -1632,9 +1628,8 @@ namespace System.StubHelpers {
{
if (pHandle == null)
{
- throw new ArgumentNullException(nameof(pHandle), Environment.GetResourceString("ArgumentNull_SafeHandle"));
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.pHandle, ExceptionResource.ArgumentNull_SafeHandle);
}
- Contract.EndContractBlock();
try
{
@@ -1673,7 +1668,7 @@ namespace System.StubHelpers {
//-------------------------------------------------------
// Helper for the MDA RaceOnRCWCleanup
//-------------------------------------------------------
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void StubRegisterRCW(object pThis);
@@ -1727,7 +1722,7 @@ namespace System.StubHelpers {
{
if (length > 0x7ffffff0)
{
- throw new MarshalDirectiveException(Environment.GetResourceString("Marshaler_StringTooLong"));
+ throw new MarshalDirectiveException(SR.Marshaler_StringTooLong);
}
}
@@ -1736,7 +1731,7 @@ namespace System.StubHelpers {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void DecimalCanonicalizeInternal(ref Decimal dec);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal unsafe extern void FmtClassUpdateNativeInternal(object obj, byte* pNative, ref CleanupWorkList pCleanupWorkList);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -1751,10 +1746,10 @@ namespace System.StubHelpers {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void MarshalToManagedVaListInternal(IntPtr va_list, IntPtr pArgIterator);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern uint CalcVaListSize(IntPtr va_list);
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
static internal extern void ValidateObject(object obj, IntPtr pMD, object pThis);
diff --git a/src/mscorlib/src/System/Text/ASCIIEncoding.cs b/src/mscorlib/src/System/Text/ASCIIEncoding.cs
deleted file mode 100644
index 07b7f3e890..0000000000
--- a/src/mscorlib/src/System/Text/ASCIIEncoding.cs
+++ /dev/null
@@ -1,757 +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.
-
-namespace System.Text
-{
- using System;
- using System.Runtime.Serialization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- // ASCIIEncoding
- //
- // Note that ASCIIEncoding is optomized with no best fit and ? for fallback.
- // It doesn't come in other flavors.
- //
- // Note: ASCIIEncoding is the only encoding that doesn't do best fit (windows has best fit).
- //
- // Note: IsAlwaysNormalized remains false because 1/2 the code points are unassigned, so they'd
- // use fallbacks, and we cannot guarantee that fallbacks are normalized.
- //
-
- [Serializable]
- public class ASCIIEncoding : Encoding
- {
- // Used by Encoding.ASCII for lazy initialization
- // The initialization code will not be run until a static member of the class is referenced
- internal static readonly ASCIIEncoding s_default = new ASCIIEncoding();
-
- public ASCIIEncoding() : base(Encoding.CodePageASCII)
- {
- }
-
- internal override void SetDefaultFallbacks()
- {
- // For ASCIIEncoding we just use default replacement fallback
- this.encoderFallback = EncoderFallback.ReplacementFallback;
- this.decoderFallback = DecoderFallback.ReplacementFallback;
- }
-
- // WARNING: GetByteCount(string chars), GetBytes(string chars,...), and GetString(byte[] byteIndex...)
- // WARNING: have different variable names than EncodingNLS.cs, so this can't just be cut & pasted,
- // WARNING: or it'll break VB's way of calling these.
-
- // NOTE: Many methods in this class forward to EncodingForwarder for
- // validating arguments/wrapping the unsafe methods in this class
- // which do the actual work. That class contains
- // shared logic for doing this which is used by
- // ASCIIEncoding, EncodingNLS, UnicodeEncoding, UTF32Encoding,
- // UTF7Encoding, and UTF8Encoding.
- // The reason the code is separated out into a static class, rather
- // than a base class which overrides all of these methods for us
- // (which is what EncodingNLS is for internal Encodings) is because
- // that's really more of an implementation detail so it's internal.
- // At the same time, C# doesn't allow a public class subclassing an
- // internal/private one, so we end up having to re-override these
- // methods in all of the public Encodings + EncodingNLS.
-
- // Returns the number of bytes required to encode a range of characters in
- // a character array.
-
- public override int GetByteCount(char[] chars, int index, int count)
- {
- return EncodingForwarder.GetByteCount(this, chars, index, count);
- }
-
- public override int GetByteCount(String chars)
- {
- return EncodingForwarder.GetByteCount(this, chars);
- }
-
- [CLSCompliant(false)]
- public override unsafe int GetByteCount(char* chars, int count)
- {
- return EncodingForwarder.GetByteCount(this, chars, count);
- }
-
- public override int GetBytes(String chars, int charIndex, int charCount,
- byte[] bytes, int byteIndex)
- {
- return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
- }
-
- // Encodes a range of characters in a character array into a range of bytes
- // in a byte array. An exception occurs if the byte array is not large
- // enough to hold the complete encoding of the characters. The
- // GetByteCount method can be used to determine the exact number of
- // bytes that will be produced for a given range of characters.
- // Alternatively, the GetMaxByteCount method can be used to
- // determine the maximum number of bytes that will be produced for a given
- // number of characters, regardless of the actual character values.
-
- public override int GetBytes(char[] chars, int charIndex, int charCount,
- byte[] bytes, int byteIndex)
- {
- return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
- }
-
- [CLSCompliant(false)]
- public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
- {
- return EncodingForwarder.GetBytes(this, chars, charCount, bytes, byteCount);
- }
-
- // Returns the number of characters produced by decoding a range of bytes
- // in a byte array.
-
- public override int GetCharCount(byte[] bytes, int index, int count)
- {
- return EncodingForwarder.GetCharCount(this, bytes, index, count);
- }
-
- [CLSCompliant(false)]
- public override unsafe int GetCharCount(byte* bytes, int count)
- {
- return EncodingForwarder.GetCharCount(this, bytes, count);
- }
-
- public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
- char[] chars, int charIndex)
- {
- return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
- }
-
- [CLSCompliant(false)]
- public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
- {
- return EncodingForwarder.GetChars(this, bytes, byteCount, chars, charCount);
- }
-
- // Returns a string containing the decoded representation of a range of
- // bytes in a byte array.
-
- public override String GetString(byte[] bytes, int byteIndex, int byteCount)
- {
- return EncodingForwarder.GetString(this, bytes, byteIndex, byteCount);
- }
-
- // End of overridden methods which use EncodingForwarder
-
- // GetByteCount
- // Note: We start by assuming that the output will be the same as count. Having
- // an encoder or fallback may change that assumption
- internal override unsafe int GetByteCount(char* chars, int charCount, EncoderNLS encoder)
- {
- // Just need to ASSERT, this is called by something else internal that checked parameters already
- Debug.Assert(charCount >= 0, "[ASCIIEncoding.GetByteCount]count is negative");
- Debug.Assert(chars != null, "[ASCIIEncoding.GetByteCount]chars is null");
-
- // Assert because we shouldn't be able to have a null encoder.
- Debug.Assert(encoderFallback != null, "[ASCIIEncoding.GetByteCount]Attempting to use null fallback encoder");
-
- char charLeftOver = (char)0;
- EncoderReplacementFallback fallback = null;
-
- // Start by assuming default count, then +/- for fallback characters
- char* charEnd = chars + charCount;
-
- // For fallback we may need a fallback buffer, we know we aren't default fallback.
- EncoderFallbackBuffer fallbackBuffer = null;
-
- if (encoder != null)
- {
- charLeftOver = encoder.charLeftOver;
- Debug.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
- "[ASCIIEncoding.GetByteCount]leftover character should be high surrogate");
-
- fallback = encoder.Fallback as EncoderReplacementFallback;
-
- // We mustn't have left over fallback data when counting
- if (encoder.InternalHasFallbackBuffer)
- {
- // We always need the fallback buffer in get bytes so we can flush any remaining ones if necessary
- fallbackBuffer = encoder.FallbackBuffer;
- if (fallbackBuffer.Remaining > 0 && encoder.m_throwOnOverflow)
- throw new ArgumentException(Environment.GetResourceString("Argument_EncoderFallbackNotEmpty",
- this.EncodingName, encoder.Fallback.GetType()));
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(chars, charEnd, encoder, false);
- }
-
- // Verify that we have no fallbackbuffer, for ASCII its always empty, so just assert
- Debug.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
- encoder.FallbackBuffer.Remaining == 0,
- "[ASCIICodePageEncoding.GetByteCount]Expected empty fallback buffer");
-// if (encoder.InternalHasFallbackBuffer && encoder.FallbackBuffer.Remaining > 0)
-// throw new ArgumentException(Environment.GetResourceString("Argument_EncoderFallbackNotEmpty",
-// this.EncodingName, encoder.Fallback.GetType()));
- }
- else
- {
- fallback = this.EncoderFallback as EncoderReplacementFallback;
- }
-
- // If we have an encoder AND we aren't using default fallback,
- // then we may have a complicated count.
- if (fallback != null && fallback.MaxCharCount == 1)
- {
- // Replacement fallback encodes surrogate pairs as two ?? (or two whatever), so return size is always
- // same as input size.
- // Note that no existing SBCS code pages map code points to supplimentary characters, so this is easy.
-
- // We could however have 1 extra byte if the last call had an encoder and a funky fallback and
- // if we don't use the funky fallback this time.
-
- // Do we have an extra char left over from last time?
- if (charLeftOver > 0)
- charCount++;
-
- return (charCount);
- }
-
- // Count is more complicated if you have a funky fallback
- // For fallback we may need a fallback buffer, we know we're not default fallback
- int byteCount = 0;
-
- // We may have a left over character from last time, try and process it.
- if (charLeftOver > 0)
- {
- Debug.Assert(Char.IsHighSurrogate(charLeftOver), "[ASCIIEncoding.GetByteCount]leftover character should be high surrogate");
- Debug.Assert(encoder != null, "[ASCIIEncoding.GetByteCount]Expected encoder");
-
- // Since left over char was a surrogate, it'll have to be fallen back.
- // Get Fallback
- fallbackBuffer = encoder.FallbackBuffer;
- fallbackBuffer.InternalInitialize(chars, charEnd, encoder, false);
-
- // This will fallback a pair if *chars is a low surrogate
- fallbackBuffer.InternalFallback(charLeftOver, ref chars);
- }
-
- // Now we may have fallback char[] already from the encoder
-
- // Go ahead and do it, including the fallback.
- char ch;
- while ((ch = (fallbackBuffer == null) ? '\0' : fallbackBuffer.InternalGetNextChar()) != 0 ||
- chars < charEnd)
- {
-
- // First unwind any fallback
- if (ch == 0)
- {
- // No fallback, just get next char
- ch = *chars;
- chars++;
- }
-
- // Check for fallback, this'll catch surrogate pairs too.
- // no chars >= 0x80 are allowed.
- if (ch > 0x7f)
- {
- if (fallbackBuffer == null)
- {
- // Initialize the buffer
- if (encoder == null)
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = encoder.FallbackBuffer;
- fallbackBuffer.InternalInitialize(charEnd - charCount, charEnd, encoder, false);
- }
-
- // Get Fallback
- fallbackBuffer.InternalFallback(ch, ref chars);
- continue;
- }
-
- // We'll use this one
- byteCount++;
- }
-
- Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
- "[ASCIIEncoding.GetByteCount]Expected Empty fallback buffer");
-
- return byteCount;
- }
-
- internal override unsafe int GetBytes(char* chars, int charCount,
- byte* bytes, int byteCount, EncoderNLS encoder)
- {
- // Just need to ASSERT, this is called by something else internal that checked parameters already
- Debug.Assert(bytes != null, "[ASCIIEncoding.GetBytes]bytes is null");
- Debug.Assert(byteCount >= 0, "[ASCIIEncoding.GetBytes]byteCount is negative");
- Debug.Assert(chars != null, "[ASCIIEncoding.GetBytes]chars is null");
- Debug.Assert(charCount >= 0, "[ASCIIEncoding.GetBytes]charCount is negative");
-
- // Assert because we shouldn't be able to have a null encoder.
- Debug.Assert(encoderFallback != null, "[ASCIIEncoding.GetBytes]Attempting to use null encoder fallback");
-
- // Get any left over characters
- char charLeftOver = (char)0;
- EncoderReplacementFallback fallback = null;
-
- // For fallback we may need a fallback buffer, we know we aren't default fallback.
- EncoderFallbackBuffer fallbackBuffer = null;
-
- // prepare our end
- char* charEnd = chars + charCount;
- byte* byteStart = bytes;
- char* charStart = chars;
-
- if (encoder != null)
- {
- charLeftOver = encoder.charLeftOver;
- fallback = encoder.Fallback as EncoderReplacementFallback;
-
- // We mustn't have left over fallback data when counting
- if (encoder.InternalHasFallbackBuffer)
- {
- // We always need the fallback buffer in get bytes so we can flush any remaining ones if necessary
- fallbackBuffer = encoder.FallbackBuffer;
- if (fallbackBuffer.Remaining > 0 && encoder.m_throwOnOverflow)
- throw new ArgumentException(Environment.GetResourceString("Argument_EncoderFallbackNotEmpty",
- this.EncodingName, encoder.Fallback.GetType()));
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, true);
- }
-
- Debug.Assert(charLeftOver == 0 || Char.IsHighSurrogate(charLeftOver),
- "[ASCIIEncoding.GetBytes]leftover character should be high surrogate");
-
- // Verify that we have no fallbackbuffer, for ASCII its always empty, so just assert
- Debug.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
- encoder.FallbackBuffer.Remaining == 0,
- "[ASCIICodePageEncoding.GetBytes]Expected empty fallback buffer");
-// if (encoder.m_throwOnOverflow && encoder.InternalHasFallbackBuffer &&
-// encoder.FallbackBuffer.Remaining > 0)
-// throw new ArgumentException(Environment.GetResourceString("Argument_EncoderFallbackNotEmpty",
-// this.EncodingName, encoder.Fallback.GetType()));
- }
- else
- {
- fallback = this.EncoderFallback as EncoderReplacementFallback;
- }
-
-
- // See if we do the fast default or slightly slower fallback
- if (fallback != null && fallback.MaxCharCount == 1)
- {
- // Fast version
- char cReplacement = fallback.DefaultString[0];
-
- // Check for replacements in range, otherwise fall back to slow version.
- if (cReplacement <= (char)0x7f)
- {
- // We should have exactly as many output bytes as input bytes, unless there's a left
- // over character, in which case we may need one more.
- // If we had a left over character will have to add a ? (This happens if they had a funky
- // fallback last time, but not this time.) (We can't spit any out though
- // because with fallback encoder each surrogate is treated as a seperate code point)
- if (charLeftOver > 0)
- {
- // Have to have room
- // Throw even if doing no throw version because this is just 1 char,
- // so buffer will never be big enough
- if (byteCount == 0)
- ThrowBytesOverflow(encoder, true);
-
- // This'll make sure we still have more room and also make sure our return value is correct.
- *(bytes++) = (byte)cReplacement;
- byteCount--; // We used one of the ones we were counting.
- }
-
- // This keeps us from overrunning our output buffer
- if (byteCount < charCount)
- {
- // Throw or make buffer smaller?
- ThrowBytesOverflow(encoder, byteCount < 1);
-
- // Just use what we can
- charEnd = chars + byteCount;
- }
-
- // We just do a quick copy
- while (chars < charEnd)
- {
- char ch2 = *(chars++);
- if (ch2 >= 0x0080) *(bytes++) = (byte)cReplacement;
- else *(bytes++) = unchecked((byte)(ch2));
- }
-
- // Clear encoder
- if (encoder != null)
- {
- encoder.charLeftOver = (char)0;
- encoder.m_charsUsed = (int)(chars-charStart);
- }
-
- return (int)(bytes - byteStart);
- }
- }
-
- // Slower version, have to do real fallback.
-
- // prepare our end
- byte* byteEnd = bytes + byteCount;
-
- // We may have a left over character from last time, try and process it.
- if (charLeftOver > 0)
- {
- // Initialize the buffer
- Debug.Assert(encoder != null,
- "[ASCIIEncoding.GetBytes]Expected non null encoder if we have surrogate left over");
- fallbackBuffer = encoder.FallbackBuffer;
- fallbackBuffer.InternalInitialize(chars, charEnd, encoder, true);
-
- // Since left over char was a surrogate, it'll have to be fallen back.
- // Get Fallback
- // This will fallback a pair if *chars is a low surrogate
- fallbackBuffer.InternalFallback(charLeftOver, ref chars);
- }
-
- // Now we may have fallback char[] already from the encoder
-
- // Go ahead and do it, including the fallback.
- char ch;
- while ((ch = (fallbackBuffer == null) ? '\0' : fallbackBuffer.InternalGetNextChar()) != 0 ||
- chars < charEnd)
- {
- // First unwind any fallback
- if (ch == 0)
- {
- // No fallback, just get next char
- ch = *chars;
- chars++;
- }
-
- // Check for fallback, this'll catch surrogate pairs too.
- // All characters >= 0x80 must fall back.
- if (ch > 0x7f)
- {
- // Initialize the buffer
- if (fallbackBuffer == null)
- {
- if (encoder == null)
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = encoder.FallbackBuffer;
- fallbackBuffer.InternalInitialize(charEnd - charCount, charEnd, encoder, true);
- }
-
- // Get Fallback
- fallbackBuffer.InternalFallback(ch, ref chars);
-
- // Go ahead & continue (& do the fallback)
- continue;
- }
-
- // We'll use this one
- // Bounds check
- if (bytes >= byteEnd)
- {
- // didn't use this char, we'll throw or use buffer
- if (fallbackBuffer == null || fallbackBuffer.bFallingBack == false)
- {
- Debug.Assert(chars > charStart || bytes == byteStart,
- "[ASCIIEncoding.GetBytes]Expected chars to have advanced already.");
- chars--; // don't use last char
- }
- else
- fallbackBuffer.MovePrevious();
-
- // Are we throwing or using buffer?
- ThrowBytesOverflow(encoder, bytes == byteStart); // throw?
- break; // don't throw, stop
- }
-
- // Go ahead and add it
- *bytes = unchecked((byte)ch);
- bytes++;
- }
-
- // Need to do encoder stuff
- if (encoder != null)
- {
- // Fallback stuck it in encoder if necessary, but we have to clear MustFlush cases
- if (fallbackBuffer != null && !fallbackBuffer.bUsedEncoder)
- // Clear it in case of MustFlush
- encoder.charLeftOver = (char)0;
-
- // Set our chars used count
- encoder.m_charsUsed = (int)(chars - charStart);
- }
-
- Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0 ||
- (encoder != null && !encoder.m_throwOnOverflow ),
- "[ASCIIEncoding.GetBytes]Expected Empty fallback buffer at end");
-
- return (int)(bytes - byteStart);
- }
-
- // This is internal and called by something else,
- internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS decoder)
- {
- // Just assert, we're called internally so these should be safe, checked already
- Debug.Assert(bytes != null, "[ASCIIEncoding.GetCharCount]bytes is null");
- Debug.Assert(count >= 0, "[ASCIIEncoding.GetCharCount]byteCount is negative");
-
- // ASCII doesn't do best fit, so don't have to check for it, find out which decoder fallback we're using
- DecoderReplacementFallback fallback = null;
-
- if (decoder == null)
- fallback = this.DecoderFallback as DecoderReplacementFallback;
- else
- {
- fallback = decoder.Fallback as DecoderReplacementFallback;
- Debug.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer ||
- decoder.FallbackBuffer.Remaining == 0,
- "[ASCIICodePageEncoding.GetCharCount]Expected empty fallback buffer");
- }
-
- if (fallback != null && fallback.MaxCharCount == 1)
- {
- // Just return length, SBCS stay the same length because they don't map to surrogate
- // pairs and we don't have a decoder fallback.
-
- return count;
- }
-
- // Only need decoder fallback buffer if not using default replacement fallback, no best fit for ASCII
- DecoderFallbackBuffer fallbackBuffer = null;
-
- // Have to do it the hard way.
- // Assume charCount will be == count
- int charCount = count;
- byte[] byteBuffer = new byte[1];
-
- // Do it our fast way
- byte* byteEnd = bytes + count;
-
- // Quick loop
- while (bytes < byteEnd)
- {
- // Faster if don't use *bytes++;
- byte b = *bytes;
- bytes++;
-
- // If unknown we have to do fallback count
- if (b >= 0x80)
- {
- if (fallbackBuffer == null)
- {
- if (decoder == null)
- fallbackBuffer = this.DecoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = decoder.FallbackBuffer;
- fallbackBuffer.InternalInitialize(byteEnd - count, null);
- }
-
- // Use fallback buffer
- byteBuffer[0] = b;
- charCount--; // Have to unreserve the one we already allocated for b
- charCount += fallbackBuffer.InternalFallback(byteBuffer, bytes);
- }
- }
-
- // Fallback buffer must be empty
- Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
- "[ASCIIEncoding.GetCharCount]Expected Empty fallback buffer");
-
- // Converted sequence is same length as input
- return charCount;
- }
-
- internal override unsafe int GetChars(byte* bytes, int byteCount,
- char* chars, int charCount, DecoderNLS decoder)
- {
- // Just need to ASSERT, this is called by something else internal that checked parameters already
- Debug.Assert(bytes != null, "[ASCIIEncoding.GetChars]bytes is null");
- Debug.Assert(byteCount >= 0, "[ASCIIEncoding.GetChars]byteCount is negative");
- Debug.Assert(chars != null, "[ASCIIEncoding.GetChars]chars is null");
- Debug.Assert(charCount >= 0, "[ASCIIEncoding.GetChars]charCount is negative");
-
- // Do it fast way if using ? replacement fallback
- byte* byteEnd = bytes + byteCount;
- byte* byteStart = bytes;
- char* charStart = chars;
-
- // Note: ASCII doesn't do best fit, but we have to fallback if they use something > 0x7f
- // Only need decoder fallback buffer if not using ? fallback.
- // ASCII doesn't do best fit, so don't have to check for it, find out which decoder fallback we're using
- DecoderReplacementFallback fallback = null;
-
- if (decoder == null)
- fallback = this.DecoderFallback as DecoderReplacementFallback;
- else
- {
- fallback = decoder.Fallback as DecoderReplacementFallback;
- Debug.Assert(!decoder.m_throwOnOverflow || !decoder.InternalHasFallbackBuffer ||
- decoder.FallbackBuffer.Remaining == 0,
- "[ASCIICodePageEncoding.GetChars]Expected empty fallback buffer");
- }
-
- if (fallback != null && fallback.MaxCharCount == 1)
- {
- // Try it the fast way
- char replacementChar = fallback.DefaultString[0];
-
- // Need byteCount chars, otherwise too small buffer
- if (charCount < byteCount)
- {
- // Need at least 1 output byte, throw if must throw
- ThrowCharsOverflow(decoder, charCount < 1);
-
- // Not throwing, use what we can
- byteEnd = bytes + charCount;
- }
-
- // Quick loop, just do '?' replacement because we don't have fallbacks for decodings.
- while (bytes < byteEnd)
- {
- byte b = *(bytes++);
- if (b >= 0x80)
- // This is an invalid byte in the ASCII encoding.
- *(chars++) = replacementChar;
- else
- *(chars++) = unchecked((char)b);
- }
-
- // bytes & chars used are the same
- if (decoder != null)
- decoder.m_bytesUsed = (int)(bytes - byteStart);
- return (int)(chars - charStart);
- }
-
- // Slower way's going to need a fallback buffer
- DecoderFallbackBuffer fallbackBuffer = null;
- byte[] byteBuffer = new byte[1];
- char* charEnd = chars + charCount;
-
- // Not quite so fast loop
- while (bytes < byteEnd)
- {
- // Faster if don't use *bytes++;
- byte b = *(bytes);
- bytes++;
-
- if (b >= 0x80)
- {
- // This is an invalid byte in the ASCII encoding.
- if (fallbackBuffer == null)
- {
- if (decoder == null)
- fallbackBuffer = this.DecoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = decoder.FallbackBuffer;
- fallbackBuffer.InternalInitialize(byteEnd - byteCount, charEnd);
- }
-
- // Use fallback buffer
- byteBuffer[0] = b;
-
- // Note that chars won't get updated unless this succeeds
- if (!fallbackBuffer.InternalFallback(byteBuffer, bytes, ref chars))
- {
- // May or may not throw, but we didn't get this byte
- Debug.Assert(bytes > byteStart || chars == charStart,
- "[ASCIIEncoding.GetChars]Expected bytes to have advanced already (fallback case)");
- bytes--; // unused byte
- fallbackBuffer.InternalReset(); // Didn't fall this back
- ThrowCharsOverflow(decoder, chars == charStart); // throw?
- break; // don't throw, but stop loop
- }
- }
- else
- {
- // Make sure we have buffer space
- if (chars >= charEnd)
- {
- Debug.Assert(bytes > byteStart || chars == charStart,
- "[ASCIIEncoding.GetChars]Expected bytes to have advanced already (normal case)");
- bytes--; // unused byte
- ThrowCharsOverflow(decoder, chars == charStart); // throw?
- break; // don't throw, but stop loop
- }
-
- *(chars) = unchecked((char)b);
- chars++;
- }
- }
-
- // Might have had decoder fallback stuff.
- if (decoder != null)
- decoder.m_bytesUsed = (int)(bytes - byteStart);
-
- // Expect Empty fallback buffer for GetChars
- Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
- "[ASCIIEncoding.GetChars]Expected Empty fallback buffer");
-
- return (int)(chars - charStart);
- }
-
-
- public override int GetMaxByteCount(int charCount)
- {
- if (charCount < 0)
- throw new ArgumentOutOfRangeException(nameof(charCount),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Characters would be # of characters + 1 in case high surrogate is ? * max fallback
- long byteCount = (long)charCount + 1;
-
- if (EncoderFallback.MaxCharCount > 1)
- byteCount *= EncoderFallback.MaxCharCount;
-
- // 1 to 1 for most characters. Only surrogates with fallbacks have less.
-
- if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
- return (int)byteCount;
- }
-
-
- public override int GetMaxCharCount(int byteCount)
- {
- if (byteCount < 0)
- throw new ArgumentOutOfRangeException(nameof(byteCount),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Just return length, SBCS stay the same length because they don't map to surrogate
- long charCount = (long)byteCount;
-
- // 1 to 1 for most characters. Only surrogates with fallbacks have less, unknown fallbacks could be longer.
- if (DecoderFallback.MaxCharCount > 1)
- charCount *= DecoderFallback.MaxCharCount;
-
- if (charCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
-
- return (int)charCount;
- }
-
- // True if and only if the encoding only uses single byte code points. (Ie, ASCII, 1252, etc)
-
- public override bool IsSingleByte
- {
- get
- {
- return true;
- }
- }
-
- public override Decoder GetDecoder()
- {
- return new DecoderNLS(this);
- }
-
-
- public override Encoder GetEncoder()
- {
- return new EncoderNLS(this);
- }
- }
-}
diff --git a/src/mscorlib/src/System/Text/Decoder.cs b/src/mscorlib/src/System/Text/Decoder.cs
deleted file mode 100644
index a9fea82a39..0000000000
--- a/src/mscorlib/src/System/Text/Decoder.cs
+++ /dev/null
@@ -1,338 +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.
-
-namespace System.Text
-{
- using System.Runtime.Serialization;
- using System.Text;
- using System;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- // A Decoder is used to decode a sequence of blocks of bytes into a
- // sequence of blocks of characters. Following instantiation of a decoder,
- // sequential blocks of bytes are converted into blocks of characters through
- // calls to the GetChars method. The decoder maintains state between the
- // conversions, allowing it to correctly decode byte sequences that span
- // adjacent blocks.
- //
- // Instances of specific implementations of the Decoder abstract base
- // class are typically obtained through calls to the GetDecoder method
- // of Encoding objects.
- //
- [Serializable]
- public abstract class Decoder
- {
- internal DecoderFallback m_fallback = null;
-
- [NonSerialized]
- internal DecoderFallbackBuffer m_fallbackBuffer = null;
-
- internal void SerializeDecoder(SerializationInfo info)
- {
- info.AddValue("m_fallback", this.m_fallback);
- }
-
- protected Decoder( )
- {
- // We don't call default reset because default reset probably isn't good if we aren't initialized.
- }
-
- public DecoderFallback Fallback
- {
- get
- {
- return m_fallback;
- }
-
- set
- {
- if (value == null)
- throw new ArgumentNullException(nameof(value));
- Contract.EndContractBlock();
-
- // Can't change fallback if buffer is wrong
- if (m_fallbackBuffer != null && m_fallbackBuffer.Remaining > 0)
- throw new ArgumentException(
- Environment.GetResourceString("Argument_FallbackBufferNotEmpty"), nameof(value));
-
- m_fallback = value;
- m_fallbackBuffer = null;
- }
- }
-
- // Note: we don't test for threading here because async access to Encoders and Decoders
- // doesn't work anyway.
- public DecoderFallbackBuffer FallbackBuffer
- {
- get
- {
- if (m_fallbackBuffer == null)
- {
- if (m_fallback != null)
- m_fallbackBuffer = m_fallback.CreateFallbackBuffer();
- else
- m_fallbackBuffer = DecoderFallback.ReplacementFallback.CreateFallbackBuffer();
- }
-
- return m_fallbackBuffer;
- }
- }
-
- internal bool InternalHasFallbackBuffer
- {
- get
- {
- return m_fallbackBuffer != null;
- }
- }
-
- // Reset the Decoder
- //
- // Normally if we call GetChars() and an error is thrown we don't change the state of the Decoder. This
- // would allow the caller to correct the error condition and try again (such as if they need a bigger buffer.)
- //
- // If the caller doesn't want to try again after GetChars() throws an error, then they need to call Reset().
- //
- // Virtual implimentation has to call GetChars with flush and a big enough buffer to clear a 0 byte string
- // We avoid GetMaxCharCount() because a) we can't call the base encoder and b) it might be really big.
- public virtual void Reset()
- {
- byte[] byteTemp = Array.Empty<byte>();
- char[] charTemp = new char[GetCharCount(byteTemp, 0, 0, true)];
- GetChars(byteTemp, 0, 0, charTemp, 0, true);
- if (m_fallbackBuffer != null)
- m_fallbackBuffer.Reset();
- }
-
- // Returns the number of characters the next call to GetChars will
- // produce if presented with the given range of bytes. The returned value
- // takes into account the state in which the decoder was left following the
- // last call to GetChars. The state of the decoder is not affected
- // by a call to this method.
- //
- public abstract int GetCharCount(byte[] bytes, int index, int count);
-
- public virtual int GetCharCount(byte[] bytes, int index, int count, bool flush)
- {
- return GetCharCount(bytes, index, count);
- }
-
- // We expect this to be the workhorse for NLS Encodings, but for existing
- // ones we need a working (if slow) default implimentation)
- [CLSCompliant(false)]
- public virtual unsafe int GetCharCount(byte* bytes, int count, bool flush)
- {
- // Validate input parameters
- if (bytes == null)
- throw new ArgumentNullException(nameof(bytes),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- byte[] arrbyte = new byte[count];
- int index;
-
- for (index = 0; index < count; index++)
- arrbyte[index] = bytes[index];
-
- return GetCharCount(arrbyte, 0, count);
- }
-
- // Decodes a range of bytes in a byte array into a range of characters
- // in a character array. The method decodes byteCount bytes from
- // bytes starting at index byteIndex, storing the resulting
- // characters in chars starting at index charIndex. The
- // decoding takes into account the state in which the decoder was left
- // following the last call to this method.
- //
- // An exception occurs if the character array is not large enough to
- // hold the complete decoding of the bytes. The GetCharCount method
- // can be used to determine the exact number of characters that will be
- // produced for a given range of bytes. Alternatively, the
- // GetMaxCharCount method of the Encoding that produced this
- // decoder can be used to determine the maximum number of characters that
- // will be produced for a given number of bytes, regardless of the actual
- // byte values.
- //
- public abstract int GetChars(byte[] bytes, int byteIndex, int byteCount,
- char[] chars, int charIndex);
-
- public virtual int GetChars(byte[] bytes, int byteIndex, int byteCount,
- char[] chars, int charIndex, bool flush)
- {
- return GetChars(bytes, byteIndex, byteCount, chars, charIndex);
- }
-
- // We expect this to be the workhorse for NLS Encodings, but for existing
- // ones we need a working (if slow) default implimentation)
- //
- // WARNING WARNING WARNING
- //
- // WARNING: If this breaks it could be a security threat. Obviously we
- // call this internally, so you need to make sure that your pointers, counts
- // and indexes are correct when you call this method.
- //
- // In addition, we have internal code, which will be marked as "safe" calling
- // this code. However this code is dependent upon the implimentation of an
- // external GetChars() method, which could be overridden by a third party and
- // the results of which cannot be guaranteed. We use that result to copy
- // the char[] to our char* output buffer. If the result count was wrong, we
- // could easily overflow our output buffer. Therefore we do an extra test
- // when we copy the buffer so that we don't overflow charCount either.
- [CLSCompliant(false)]
- public virtual unsafe int GetChars(byte* bytes, int byteCount,
- char* chars, int charCount, bool flush)
- {
- // Validate input parameters
- if (chars == null || bytes == null)
- throw new ArgumentNullException(chars == null ? nameof(chars) : nameof(bytes),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (byteCount < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((byteCount<0 ? nameof(byteCount) : nameof(charCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Get the byte array to convert
- byte[] arrByte = new byte[byteCount];
-
- int index;
- for (index = 0; index < byteCount; index++)
- arrByte[index] = bytes[index];
-
- // Get the char array to fill
- char[] arrChar = new char[charCount];
-
- // Do the work
- int result = GetChars(arrByte, 0, byteCount, arrChar, 0, flush);
-
- Debug.Assert(result <= charCount, "Returned more chars than we have space for");
-
- // Copy the char array
- // WARNING: We MUST make sure that we don't copy too many chars. We can't
- // rely on result because it could be a 3rd party implimentation. We need
- // to make sure we never copy more than charCount chars no matter the value
- // of result
- if (result < charCount)
- charCount = result;
-
- // We check both result and charCount so that we don't accidentally overrun
- // our pointer buffer just because of an issue in GetChars
- for (index = 0; index < charCount; index++)
- chars[index] = arrChar[index];
-
- return charCount;
- }
-
- // This method is used when the output buffer might not be large enough.
- // It will decode until it runs out of bytes, and then it will return
- // true if it the entire input was converted. In either case it
- // will also return the number of converted bytes and output characters used.
- // It will only throw a buffer overflow exception if the entire lenght of chars[] is
- // too small to store the next char. (like 0 or maybe 1 or 4 for some encodings)
- // We're done processing this buffer only if completed returns true.
- //
- // Might consider checking Max...Count to avoid the extra counting step.
- //
- // Note that if all of the input bytes are not consumed, then we'll do a /2, which means
- // that its likely that we didn't consume as many bytes as we could have. For some
- // applications this could be slow. (Like trying to exactly fill an output buffer from a bigger stream)
- public virtual void Convert(byte[] bytes, int byteIndex, int byteCount,
- char[] chars, int charIndex, int charCount, bool flush,
- out int bytesUsed, out int charsUsed, out bool completed)
- {
- // Validate parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException((bytes == null ? nameof(bytes) : nameof(chars)),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? nameof(byteIndex) : nameof(byteCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? nameof(charIndex) : nameof(charCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException(nameof(bytes),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
-
- if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException(nameof(chars),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- Contract.EndContractBlock();
-
- bytesUsed = byteCount;
-
- // Its easy to do if it won't overrun our buffer.
- while (bytesUsed > 0)
- {
- if (GetCharCount(bytes, byteIndex, bytesUsed, flush) <= charCount)
- {
- charsUsed = GetChars(bytes, byteIndex, bytesUsed, chars, charIndex, flush);
- completed = (bytesUsed == byteCount &&
- (m_fallbackBuffer == null || m_fallbackBuffer.Remaining == 0));
- return;
- }
-
- // Try again with 1/2 the count, won't flush then 'cause won't read it all
- flush = false;
- bytesUsed /= 2;
- }
-
- // Oops, we didn't have anything, we'll have to throw an overflow
- throw new ArgumentException(Environment.GetResourceString("Argument_ConversionOverflow"));
- }
-
- // This is the version that uses *.
- // We're done processing this buffer only if completed returns true.
- //
- // Might consider checking Max...Count to avoid the extra counting step.
- //
- // Note that if all of the input bytes are not consumed, then we'll do a /2, which means
- // that its likely that we didn't consume as many bytes as we could have. For some
- // applications this could be slow. (Like trying to exactly fill an output buffer from a bigger stream)
- [CLSCompliant(false)]
- public virtual unsafe void Convert(byte* bytes, int byteCount,
- char* chars, int charCount, bool flush,
- out int bytesUsed, out int charsUsed, out bool completed)
- {
- // Validate input parameters
- if (chars == null || bytes == null)
- throw new ArgumentNullException(chars == null ? nameof(chars) : nameof(bytes),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (byteCount < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((byteCount<0 ? nameof(byteCount) : nameof(charCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Get ready to do it
- bytesUsed = byteCount;
-
- // Its easy to do if it won't overrun our buffer.
- while (bytesUsed > 0)
- {
- if (GetCharCount(bytes, bytesUsed, flush) <= charCount)
- {
- charsUsed = GetChars(bytes, bytesUsed, chars, charCount, flush);
- completed = (bytesUsed == byteCount &&
- (m_fallbackBuffer == null || m_fallbackBuffer.Remaining == 0));
- return;
- }
-
- // Try again with 1/2 the count, won't flush then 'cause won't read it all
- flush = false;
- bytesUsed /= 2;
- }
-
- // Oops, we didn't have anything, we'll have to throw an overflow
- throw new ArgumentException(Environment.GetResourceString("Argument_ConversionOverflow"));
- }
- }
-}
diff --git a/src/mscorlib/src/System/Text/DecoderBestFitFallback.cs b/src/mscorlib/src/System/Text/DecoderBestFitFallback.cs
index 6389b4b141..ad88ef4400 100644
--- a/src/mscorlib/src/System/Text/DecoderBestFitFallback.cs
+++ b/src/mscorlib/src/System/Text/DecoderBestFitFallback.cs
@@ -5,21 +5,22 @@
//
// This is used internally to create best fit behavior as per the original windows best fit behavior.
//
+
+using System;
+using System.Text;
+using System.Threading;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
namespace System.Text
{
- using System;
- using System.Text;
- using System.Threading;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
[Serializable]
internal sealed class InternalDecoderBestFitFallback : DecoderFallback
{
// Our variables
internal Encoding encoding = null;
- internal char[] arrayBestFit = null;
- internal char cReplacement = '?';
+ internal char[] arrayBestFit = null;
+ internal char cReplacement = '?';
internal InternalDecoderBestFitFallback(Encoding encoding)
{
@@ -61,10 +62,10 @@ namespace System.Text
internal sealed class InternalDecoderBestFitFallbackBuffer : DecoderFallbackBuffer
{
// Our variables
- internal char cBestFit = '\0';
- internal int iCount = -1;
- internal int iSize;
- private InternalDecoderBestFitFallback oFallback;
+ internal char cBestFit = '\0';
+ internal int iCount = -1;
+ internal int iSize;
+ private InternalDecoderBestFitFallback oFallback;
// Private object for locking instead of locking on a public type for SQL reliability work.
private static Object s_InternalSyncObject;
@@ -84,12 +85,12 @@ namespace System.Text
// Constructor
public InternalDecoderBestFitFallbackBuffer(InternalDecoderBestFitFallback fallback)
{
- this.oFallback = fallback;
+ oFallback = fallback;
if (oFallback.arrayBestFit == null)
{
// Lock so we don't confuse ourselves.
- lock(InternalSyncObject)
+ lock (InternalSyncObject)
{
// Double check before we do it again.
if (oFallback.arrayBestFit == null)
@@ -119,7 +120,7 @@ namespace System.Text
// We want it to get < 0 because == 0 means that the current/last character is a fallback
// and we need to detect recursion. We could have a flag but we already have this counter.
iCount--;
-
+
// Do we have anything left? 0 is now last fallback char, negative is nothing left
if (iCount < 0)
return '\0';
@@ -228,7 +229,7 @@ namespace System.Text
}
for (index = lowBound; index < highBound; index += 2)
- {
+ {
if (oFallback.arrayBestFit[index] == cCheck)
{
// We found it
diff --git a/src/mscorlib/src/System/Text/DecoderExceptionFallback.cs b/src/mscorlib/src/System/Text/DecoderExceptionFallback.cs
index 7a0478de20..b98ef74ed2 100644
--- a/src/mscorlib/src/System/Text/DecoderExceptionFallback.cs
+++ b/src/mscorlib/src/System/Text/DecoderExceptionFallback.cs
@@ -2,12 +2,12 @@
// 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.Serialization;
+using System.Globalization;
+
namespace System.Text
{
- using System;
- using System.Runtime.Serialization;
- using System.Globalization;
-
[Serializable]
public sealed class DecoderExceptionFallback : DecoderFallback
{
@@ -87,42 +87,40 @@ namespace System.Text
strBytes.Append(bytesUnknown[i].ToString("X2", CultureInfo.InvariantCulture));
strBytes.Append("]");
}
-
+
// In case the string's really long
if (i == 20)
strBytes.Append(" ...");
// Known index
throw new DecoderFallbackException(
- Environment.GetResourceString("Argument_InvalidCodePageBytesIndex",
- strBytes, index), bytesUnknown, index);
+ SR.Format(SR.Argument_InvalidCodePageBytesIndex, strBytes, index), bytesUnknown, index);
}
-
}
// Exception for decoding unknown byte sequences.
[Serializable]
public sealed class DecoderFallbackException : ArgumentException
{
- byte[] bytesUnknown = null;
- int index = 0;
+ private byte[] bytesUnknown = null;
+ private int index = 0;
public DecoderFallbackException()
- : base(Environment.GetResourceString("Arg_ArgumentException"))
+ : base(SR.Arg_ArgumentException)
{
- SetErrorCode(__HResults.COR_E_ARGUMENT);
+ HResult = __HResults.COR_E_ARGUMENT;
}
public DecoderFallbackException(String message)
: base(message)
{
- SetErrorCode(__HResults.COR_E_ARGUMENT);
+ HResult = __HResults.COR_E_ARGUMENT;
}
public DecoderFallbackException(String message, Exception innerException)
: base(message, innerException)
{
- SetErrorCode(__HResults.COR_E_ARGUMENT);
+ HResult = __HResults.COR_E_ARGUMENT;
}
internal DecoderFallbackException(SerializationInfo info, StreamingContext context) : base(info, context)
@@ -148,7 +146,7 @@ namespace System.Text
{
get
{
- return this.index;
+ return index;
}
}
}
diff --git a/src/mscorlib/src/System/Text/DecoderFallback.cs b/src/mscorlib/src/System/Text/DecoderFallback.cs
index bfd4a2852d..9311cda585 100644
--- a/src/mscorlib/src/System/Text/DecoderFallback.cs
+++ b/src/mscorlib/src/System/Text/DecoderFallback.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
//
+
using System;
using System.Security;
using System.Threading;
@@ -15,7 +16,7 @@ namespace System.Text
[Serializable]
public abstract class DecoderFallback
{
- internal bool bIsMicrosoftBestFitFallback = false;
+ internal bool bIsMicrosoftBestFitFallback = false;
private static volatile DecoderFallback replacementFallback; // Default fallback, uses no best fit & "?"
private static volatile DecoderFallback exceptionFallback;
@@ -42,7 +43,7 @@ namespace System.Text
get
{
if (replacementFallback == null)
- lock(InternalSyncObject)
+ lock (InternalSyncObject)
if (replacementFallback == null)
replacementFallback = new DecoderReplacementFallback();
@@ -56,7 +57,7 @@ namespace System.Text
get
{
if (exceptionFallback == null)
- lock(InternalSyncObject)
+ lock (InternalSyncObject)
if (exceptionFallback == null)
exceptionFallback = new DecoderExceptionFallback();
@@ -103,13 +104,13 @@ namespace System.Text
public virtual void Reset()
{
- while (GetNextChar() != (char)0);
+ while (GetNextChar() != (char)0) ;
}
// Internal items to help us figure out what we're doing as far as error messages, etc.
// These help us with our performance and messages internally
- internal unsafe byte* byteStart;
- internal unsafe char* charEnd;
+ internal unsafe byte* byteStart;
+ internal unsafe char* charEnd;
// Internal Reset
internal unsafe void InternalReset()
@@ -137,9 +138,9 @@ namespace System.Text
internal unsafe virtual bool InternalFallback(byte[] bytes, byte* pBytes, ref char* chars)
{
// Copy bytes to array (slow, but right now that's what we get to do.
- // byte[] bytesUnknown = new byte[count];
-// for (int i = 0; i < count; i++)
-// bytesUnknown[i] = *(bytes++);
+ // byte[] bytesUnknown = new byte[count];
+ // for (int i = 0; i < count; i++)
+ // bytesUnknown[i] = *(bytes++);
Debug.Assert(byteStart != null, "[DecoderFallback.InternalFallback]Used InternalFallback without calling InternalInitialize");
@@ -159,14 +160,14 @@ namespace System.Text
{
// High Surrogate
if (bHighSurrogate)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"));
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex);
bHighSurrogate = true;
}
else
{
// Low surrogate
if (bHighSurrogate == false)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"));
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex);
bHighSurrogate = false;
}
}
@@ -182,7 +183,7 @@ namespace System.Text
// Need to make sure that bHighSurrogate isn't true
if (bHighSurrogate)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"));
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex);
// Now we aren't going to be false, so its OK to update chars
chars = charTemp;
@@ -197,9 +198,9 @@ namespace System.Text
// array, and we might need the index, hence the byte*
{
// Copy bytes to array (slow, but right now that's what we get to do.
-// byte[] bytesUnknown = new byte[count];
-// for (int i = 0; i < count; i++)
- // bytesUnknown[i] = *(bytes++);
+ // byte[] bytesUnknown = new byte[count];
+ // for (int i = 0; i < count; i++)
+ // bytesUnknown[i] = *(bytes++);
Debug.Assert(byteStart != null, "[DecoderFallback.InternalFallback]Used InternalFallback without calling InternalInitialize");
@@ -219,14 +220,14 @@ namespace System.Text
{
// High Surrogate
if (bHighSurrogate)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"));
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex);
bHighSurrogate = true;
}
else
{
// Low surrogate
if (bHighSurrogate == false)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"));
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex);
bHighSurrogate = false;
}
}
@@ -236,7 +237,7 @@ namespace System.Text
// Need to make sure that bHighSurrogate isn't true
if (bHighSurrogate)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"));
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex);
return count;
}
@@ -263,9 +264,7 @@ namespace System.Text
// Throw it, using our complete bytes
throw new ArgumentException(
- Environment.GetResourceString("Argument_RecursiveFallbackBytes",
- strBytes.ToString()), nameof(bytesUnknown));
+ SR.Format(SR.Argument_RecursiveFallbackBytes, strBytes.ToString()), nameof(bytesUnknown));
}
-
}
}
diff --git a/src/mscorlib/src/System/Text/DecoderNLS.cs b/src/mscorlib/src/System/Text/DecoderNLS.cs
index 79474f8d8c..6fcfc79140 100644
--- a/src/mscorlib/src/System/Text/DecoderNLS.cs
+++ b/src/mscorlib/src/System/Text/DecoderNLS.cs
@@ -2,12 +2,13 @@
// 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.Runtime.Serialization;
+using System.Text;
+using System;
+using System.Diagnostics.Contracts;
+
namespace System.Text
{
- using System.Runtime.Serialization;
- using System.Text;
- using System;
- using System.Diagnostics.Contracts;
// A Decoder is used to decode a sequence of blocks of bytes into a
// sequence of blocks of characters. Following instantiation of a decoder,
// sequential blocks of bytes are converted into blocks of characters through
@@ -24,20 +25,20 @@ namespace System.Text
internal class DecoderNLS : Decoder, ISerializable
{
// Remember our encoding
- protected Encoding m_encoding;
- [NonSerialized] protected bool m_mustFlush;
- [NonSerialized] internal bool m_throwOnOverflow;
- [NonSerialized] internal int m_bytesUsed;
+ protected Encoding m_encoding;
+ [NonSerialized] protected bool m_mustFlush;
+ [NonSerialized] internal bool m_throwOnOverflow;
+ [NonSerialized] internal int m_bytesUsed;
-#region Serialization
+ #region Serialization
// Constructor called by serialization. called during deserialization.
internal DecoderNLS(SerializationInfo info, StreamingContext context)
{
throw new NotSupportedException(
String.Format(
- System.Globalization.CultureInfo.CurrentCulture,
- Environment.GetResourceString("NotSupported_TypeCannotDeserialized"), this.GetType()));
+ System.Globalization.CultureInfo.CurrentCulture,
+ SR.NotSupported_TypeCannotDeserialized, this.GetType()));
}
// ISerializable implementation. called during serialization.
@@ -48,9 +49,9 @@ namespace System.Text
info.SetType(typeof(Encoding.DefaultDecoder));
}
-#endregion Serialization
+ #endregion Serialization
- internal DecoderNLS( Encoding encoding )
+ internal DecoderNLS(Encoding encoding)
{
this.m_encoding = encoding;
this.m_fallback = this.m_encoding.DecoderFallback;
@@ -58,7 +59,7 @@ namespace System.Text
}
// This is used by our child deserializers
- internal DecoderNLS( )
+ internal DecoderNLS()
{
this.m_encoding = null;
this.Reset();
@@ -80,15 +81,15 @@ namespace System.Text
// Validate Parameters
if (bytes == null)
throw new ArgumentNullException(nameof(bytes),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
if (bytes.Length - index < count)
throw new ArgumentOutOfRangeException(nameof(bytes),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ SR.ArgumentOutOfRange_IndexCountBuffer);
Contract.EndContractBlock();
@@ -106,11 +107,11 @@ namespace System.Text
// Validate parameters
if (bytes == null)
throw new ArgumentNullException(nameof(bytes),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (count < 0)
throw new ArgumentOutOfRangeException(nameof(count),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
// Remember the flush
@@ -133,19 +134,19 @@ namespace System.Text
// Validate Parameters
if (bytes == null || chars == null)
throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? nameof(byteIndex) : nameof(byteCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((byteIndex < 0 ? nameof(byteIndex) : nameof(byteCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
- if ( bytes.Length - byteIndex < byteCount)
+ if (bytes.Length - byteIndex < byteCount)
throw new ArgumentOutOfRangeException(nameof(bytes),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ SR.ArgumentOutOfRange_IndexCountBuffer);
if (charIndex < 0 || charIndex > chars.Length)
throw new ArgumentOutOfRangeException(nameof(charIndex),
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ SR.ArgumentOutOfRange_Index);
Contract.EndContractBlock();
@@ -159,10 +160,10 @@ namespace System.Text
// Just call pointer version
fixed (byte* pBytes = &bytes[0])
- fixed (char* pChars = &chars[0])
- // Remember that charCount is # to decode, not size of array
- return GetChars(pBytes + byteIndex, byteCount,
- pChars + charIndex, charCount, flush);
+ fixed (char* pChars = &chars[0])
+ // Remember that charCount is # to decode, not size of array
+ return GetChars(pBytes + byteIndex, byteCount,
+ pChars + charIndex, charCount, flush);
}
public unsafe override int GetChars(byte* bytes, int byteCount,
@@ -171,11 +172,11 @@ namespace System.Text
// Validate parameters
if (chars == null || bytes == null)
throw new ArgumentNullException((chars == null ? nameof(chars) : nameof(bytes)),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (byteCount < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((byteCount<0 ? nameof(byteCount) : nameof(charCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((byteCount < 0 ? nameof(byteCount) : nameof(charCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
// Remember our flush
@@ -195,23 +196,23 @@ namespace System.Text
// Validate parameters
if (bytes == null || chars == null)
throw new ArgumentNullException((bytes == null ? nameof(bytes) : nameof(chars)),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? nameof(byteIndex) : nameof(byteCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((byteIndex < 0 ? nameof(byteIndex) : nameof(byteCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? nameof(charIndex) : nameof(charCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? nameof(charIndex) : nameof(charCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
if (bytes.Length - byteIndex < byteCount)
throw new ArgumentOutOfRangeException(nameof(bytes),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ SR.ArgumentOutOfRange_IndexCountBuffer);
if (chars.Length - charIndex < charCount)
throw new ArgumentOutOfRangeException(nameof(chars),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ SR.ArgumentOutOfRange_IndexCountBuffer);
Contract.EndContractBlock();
@@ -241,11 +242,11 @@ namespace System.Text
// Validate input parameters
if (chars == null || bytes == null)
throw new ArgumentNullException(chars == null ? nameof(chars) : nameof(bytes),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (byteCount < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((byteCount<0 ? nameof(byteCount) : nameof(charCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((byteCount < 0 ? nameof(byteCount) : nameof(charCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
// We don't want to throw
diff --git a/src/mscorlib/src/System/Text/DecoderReplacementFallback.cs b/src/mscorlib/src/System/Text/DecoderReplacementFallback.cs
index 77c856046d..b27469156d 100644
--- a/src/mscorlib/src/System/Text/DecoderReplacementFallback.cs
+++ b/src/mscorlib/src/System/Text/DecoderReplacementFallback.cs
@@ -2,12 +2,12 @@
// 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.Diagnostics;
+using System.Diagnostics.Contracts;
+
namespace System.Text
{
- using System;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
[Serializable]
public sealed class DecoderReplacementFallback : DecoderFallback
{
@@ -26,11 +26,11 @@ namespace System.Text
Contract.EndContractBlock();
// Make sure it doesn't have bad surrogate pairs
- bool bFoundHigh=false;
+ bool bFoundHigh = false;
for (int i = 0; i < replacement.Length; i++)
{
// Found a surrogate?
- if (Char.IsSurrogate(replacement,i))
+ if (Char.IsSurrogate(replacement, i))
{
// High or Low?
if (Char.IsHighSurrogate(replacement, i))
@@ -59,17 +59,17 @@ namespace System.Text
break;
}
if (bFoundHigh)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex", nameof(replacement)));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidCharSequenceNoIndex, nameof(replacement)));
strDefault = replacement;
}
public String DefaultString
{
- get
- {
+ get
+ {
return strDefault;
- }
+ }
}
public override DecoderFallbackBuffer CreateFallbackBuffer()
@@ -91,7 +91,7 @@ namespace System.Text
DecoderReplacementFallback that = value as DecoderReplacementFallback;
if (that != null)
{
- return (this.strDefault == that.strDefault);
+ return (strDefault == that.strDefault);
}
return (false);
}
@@ -108,13 +108,13 @@ namespace System.Text
{
// Store our default string
private String strDefault;
- int fallbackCount = -1;
- int fallbackIndex = -1;
+ private int fallbackCount = -1;
+ private int fallbackIndex = -1;
// Construction
public DecoderReplacementFallbackBuffer(DecoderReplacementFallback fallback)
{
- this.strDefault = fallback.DefaultString;
+ strDefault = fallback.DefaultString;
}
// Fallback Methods
@@ -160,7 +160,7 @@ namespace System.Text
Debug.Assert(fallbackIndex < strDefault.Length && fallbackIndex >= 0,
"Index exceeds buffer range");
- return strDefault[fallbackIndex];
+ return strDefault[fallbackIndex];
}
public override bool MovePrevious()
diff --git a/src/mscorlib/src/System/Text/Encoder.cs b/src/mscorlib/src/System/Text/Encoder.cs
deleted file mode 100644
index f766f98142..0000000000
--- a/src/mscorlib/src/System/Text/Encoder.cs
+++ /dev/null
@@ -1,332 +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.
-
-namespace System.Text
-{
- using System.Runtime.Serialization;
- using System.Text;
- using System;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- // An Encoder is used to encode a sequence of blocks of characters into
- // a sequence of blocks of bytes. Following instantiation of an encoder,
- // sequential blocks of characters are converted into blocks of bytes through
- // calls to the GetBytes method. The encoder maintains state between the
- // conversions, allowing it to correctly encode character sequences that span
- // adjacent blocks.
- //
- // Instances of specific implementations of the Encoder abstract base
- // class are typically obtained through calls to the GetEncoder method
- // of Encoding objects.
- //
- [Serializable]
- public abstract class Encoder
- {
- internal EncoderFallback m_fallback = null;
-
- [NonSerialized]
- internal EncoderFallbackBuffer m_fallbackBuffer = null;
-
- internal void SerializeEncoder(SerializationInfo info)
- {
- info.AddValue("m_fallback", this.m_fallback);
- }
-
- protected Encoder()
- {
- // We don't call default reset because default reset probably isn't good if we aren't initialized.
- }
-
- public EncoderFallback Fallback
- {
- get
- {
- return m_fallback;
- }
-
- set
- {
- if (value == null)
- throw new ArgumentNullException(nameof(value));
- Contract.EndContractBlock();
-
- // Can't change fallback if buffer is wrong
- if (m_fallbackBuffer != null && m_fallbackBuffer.Remaining > 0)
- throw new ArgumentException(
- Environment.GetResourceString("Argument_FallbackBufferNotEmpty"), nameof(value));
-
- m_fallback = value;
- m_fallbackBuffer = null;
- }
- }
-
- // Note: we don't test for threading here because async access to Encoders and Decoders
- // doesn't work anyway.
- public EncoderFallbackBuffer FallbackBuffer
- {
- get
- {
- if (m_fallbackBuffer == null)
- {
- if (m_fallback != null)
- m_fallbackBuffer = m_fallback.CreateFallbackBuffer();
- else
- m_fallbackBuffer = EncoderFallback.ReplacementFallback.CreateFallbackBuffer();
- }
-
- return m_fallbackBuffer;
- }
- }
-
- internal bool InternalHasFallbackBuffer
- {
- get
- {
- return m_fallbackBuffer != null;
- }
- }
-
- // Reset the Encoder
- //
- // Normally if we call GetBytes() and an error is thrown we don't change the state of the encoder. This
- // would allow the caller to correct the error condition and try again (such as if they need a bigger buffer.)
- //
- // If the caller doesn't want to try again after GetBytes() throws an error, then they need to call Reset().
- //
- // Virtual implimentation has to call GetBytes with flush and a big enough buffer to clear a 0 char string
- // We avoid GetMaxByteCount() because a) we can't call the base encoder and b) it might be really big.
- public virtual void Reset()
- {
- char[] charTemp = {};
- byte[] byteTemp = new byte[GetByteCount(charTemp, 0, 0, true)];
- GetBytes(charTemp, 0, 0, byteTemp, 0, true);
- if (m_fallbackBuffer != null)
- m_fallbackBuffer.Reset();
- }
-
- // Returns the number of bytes the next call to GetBytes will
- // produce if presented with the given range of characters and the given
- // value of the flush parameter. The returned value takes into
- // account the state in which the encoder was left following the last call
- // to GetBytes. The state of the encoder is not affected by a call
- // to this method.
- //
- public abstract int GetByteCount(char[] chars, int index, int count, bool flush);
-
- // We expect this to be the workhorse for NLS encodings
- // unfortunately for existing overrides, it has to call the [] version,
- // which is really slow, so avoid this method if you might be calling external encodings.
- [CLSCompliant(false)]
- public virtual unsafe int GetByteCount(char* chars, int count, bool flush)
- {
- // Validate input parameters
- if (chars == null)
- throw new ArgumentNullException(nameof(chars),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- char[] arrChar = new char[count];
- int index;
-
- for (index = 0; index < count; index++)
- arrChar[index] = chars[index];
-
- return GetByteCount(arrChar, 0, count, flush);
- }
-
- // Encodes a range of characters in a character array into a range of bytes
- // in a byte array. The method encodes charCount characters from
- // chars starting at index charIndex, storing the resulting
- // bytes in bytes starting at index byteIndex. The encoding
- // takes into account the state in which the encoder was left following the
- // last call to this method. The flush parameter indicates whether
- // the encoder should flush any shift-states and partial characters at the
- // end of the conversion. To ensure correct termination of a sequence of
- // blocks of encoded bytes, the last call to GetBytes should specify
- // a value of true for the flush parameter.
- //
- // An exception occurs if the byte array is not large enough to hold the
- // complete encoding of the characters. The GetByteCount method can
- // be used to determine the exact number of bytes that will be produced for
- // a given range of characters. Alternatively, the GetMaxByteCount
- // method of the Encoding that produced this encoder can be used to
- // determine the maximum number of bytes that will be produced for a given
- // number of characters, regardless of the actual character values.
- //
- public abstract int GetBytes(char[] chars, int charIndex, int charCount,
- byte[] bytes, int byteIndex, bool flush);
-
- // We expect this to be the workhorse for NLS Encodings, but for existing
- // ones we need a working (if slow) default implimentation)
- //
- // WARNING WARNING WARNING
- //
- // WARNING: If this breaks it could be a security threat. Obviously we
- // call this internally, so you need to make sure that your pointers, counts
- // and indexes are correct when you call this method.
- //
- // In addition, we have internal code, which will be marked as "safe" calling
- // this code. However this code is dependent upon the implimentation of an
- // external GetBytes() method, which could be overridden by a third party and
- // the results of which cannot be guaranteed. We use that result to copy
- // the byte[] to our byte* output buffer. If the result count was wrong, we
- // could easily overflow our output buffer. Therefore we do an extra test
- // when we copy the buffer so that we don't overflow byteCount either.
- [CLSCompliant(false)]
- public virtual unsafe int GetBytes(char* chars, int charCount,
- byte* bytes, int byteCount, bool flush)
- {
- // Validate input parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? nameof(charCount) : nameof(byteCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Get the char array to convert
- char[] arrChar = new char[charCount];
-
- int index;
- for (index = 0; index < charCount; index++)
- arrChar[index] = chars[index];
-
- // Get the byte array to fill
- byte[] arrByte = new byte[byteCount];
-
- // Do the work
- int result = GetBytes(arrChar, 0, charCount, arrByte, 0, flush);
-
- Debug.Assert(result <= byteCount, "Returned more bytes than we have space for");
-
- // Copy the byte array
- // WARNING: We MUST make sure that we don't copy too many bytes. We can't
- // rely on result because it could be a 3rd party implimentation. We need
- // to make sure we never copy more than byteCount bytes no matter the value
- // of result
- if (result < byteCount)
- byteCount = result;
-
- // Don't copy too many bytes!
- for (index = 0; index < byteCount; index++)
- bytes[index] = arrByte[index];
-
- return byteCount;
- }
-
- // This method is used to avoid running out of output buffer space.
- // It will encode until it runs out of chars, and then it will return
- // true if it the entire input was converted. In either case it
- // will also return the number of converted chars and output bytes used.
- // It will only throw a buffer overflow exception if the entire lenght of bytes[] is
- // too small to store the next byte. (like 0 or maybe 1 or 4 for some encodings)
- // We're done processing this buffer only if completed returns true.
- //
- // Might consider checking Max...Count to avoid the extra counting step.
- //
- // Note that if all of the input chars are not consumed, then we'll do a /2, which means
- // that its likely that we didn't consume as many chars as we could have. For some
- // applications this could be slow. (Like trying to exactly fill an output buffer from a bigger stream)
- public virtual void Convert(char[] chars, int charIndex, int charCount,
- byte[] bytes, int byteIndex, int byteCount, bool flush,
- out int charsUsed, out int bytesUsed, out bool completed)
- {
- // Validate parameters
- if (chars == null || bytes == null)
- throw new ArgumentNullException((chars == null ? nameof(chars) : nameof(bytes)),
- Environment.GetResourceString("ArgumentNull_Array"));
-
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? nameof(charIndex) : nameof(charCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? nameof(byteIndex) : nameof(byteCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
-
- if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException(nameof(chars),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
-
- if (bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException(nameof(bytes),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- Contract.EndContractBlock();
-
- charsUsed = charCount;
-
- // Its easy to do if it won't overrun our buffer.
- // Note: We don't want to call unsafe version because that might be an untrusted version
- // which could be really unsafe and we don't want to mix it up.
- while (charsUsed > 0)
- {
- if (GetByteCount(chars, charIndex, charsUsed, flush) <= byteCount)
- {
- bytesUsed = GetBytes(chars, charIndex, charsUsed, bytes, byteIndex, flush);
- completed = (charsUsed == charCount &&
- (m_fallbackBuffer == null || m_fallbackBuffer.Remaining == 0));
- return;
- }
-
- // Try again with 1/2 the count, won't flush then 'cause won't read it all
- flush = false;
- charsUsed /= 2;
- }
-
- // Oops, we didn't have anything, we'll have to throw an overflow
- throw new ArgumentException(Environment.GetResourceString("Argument_ConversionOverflow"));
- }
-
- // Same thing, but using pointers
- //
- // Might consider checking Max...Count to avoid the extra counting step.
- //
- // Note that if all of the input chars are not consumed, then we'll do a /2, which means
- // that its likely that we didn't consume as many chars as we could have. For some
- // applications this could be slow. (Like trying to exactly fill an output buffer from a bigger stream)
- [CLSCompliant(false)]
- public virtual unsafe void Convert(char* chars, int charCount,
- byte* bytes, int byteCount, bool flush,
- out int charsUsed, out int bytesUsed, out bool completed)
- {
- // Validate input parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars),
- Environment.GetResourceString("ArgumentNull_Array"));
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? nameof(charCount) : nameof(byteCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Get ready to do it
- charsUsed = charCount;
-
- // Its easy to do if it won't overrun our buffer.
- while (charsUsed > 0)
- {
- if (GetByteCount(chars, charsUsed, flush) <= byteCount)
- {
- bytesUsed = GetBytes(chars, charsUsed, bytes, byteCount, flush);
- completed = (charsUsed == charCount &&
- (m_fallbackBuffer == null || m_fallbackBuffer.Remaining == 0));
- return;
- }
-
- // Try again with 1/2 the count, won't flush then 'cause won't read it all
- flush = false;
- charsUsed /= 2;
- }
-
- // Oops, we didn't have anything, we'll have to throw an overflow
- throw new ArgumentException(Environment.GetResourceString("Argument_ConversionOverflow"));
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/Text/EncoderBestFitFallback.cs b/src/mscorlib/src/System/Text/EncoderBestFitFallback.cs
index 9be095bbd8..eb3165526b 100644
--- a/src/mscorlib/src/System/Text/EncoderBestFitFallback.cs
+++ b/src/mscorlib/src/System/Text/EncoderBestFitFallback.cs
@@ -5,21 +5,22 @@
//
// This is used internally to create best fit behavior as per the original windows best fit behavior.
//
+
+using System;
+using System.Globalization;
+using System.Text;
+using System.Threading;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
namespace System.Text
{
- using System;
- using System.Globalization;
- using System.Text;
- using System.Threading;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
[Serializable]
- internal class InternalEncoderBestFitFallback : EncoderFallback
+ internal sealed class InternalEncoderBestFitFallback : EncoderFallback
{
// Our variables
internal Encoding encoding = null;
- internal char[] arrayBestFit = null;
+ internal char[] arrayBestFit = null;
internal InternalEncoderBestFitFallback(Encoding encoding)
{
@@ -61,10 +62,10 @@ namespace System.Text
internal sealed class InternalEncoderBestFitFallbackBuffer : EncoderFallbackBuffer
{
// Our variables
- private char cBestFit = '\0';
- private InternalEncoderBestFitFallback oFallback;
- private int iCount = -1;
- private int iSize;
+ private char cBestFit = '\0';
+ private InternalEncoderBestFitFallback oFallback;
+ private int iCount = -1;
+ private int iSize;
// Private object for locking instead of locking on a public type for SQL reliability work.
private static Object s_InternalSyncObject;
@@ -84,12 +85,12 @@ namespace System.Text
// Constructor
public InternalEncoderBestFitFallbackBuffer(InternalEncoderBestFitFallback fallback)
{
- this.oFallback = fallback;
+ oFallback = fallback;
if (oFallback.arrayBestFit == null)
{
// Lock so we don't confuse ourselves.
- lock(InternalSyncObject)
+ lock (InternalSyncObject)
{
// Double check before we do it again.
if (oFallback.arrayBestFit == null)
@@ -119,13 +120,11 @@ namespace System.Text
// Double check input surrogate pair
if (!Char.IsHighSurrogate(charUnknownHigh))
throw new ArgumentOutOfRangeException(nameof(charUnknownHigh),
- Environment.GetResourceString("ArgumentOutOfRange_Range",
- 0xD800, 0xDBFF));
+ SR.Format(SR.ArgumentOutOfRange_Range, 0xD800, 0xDBFF));
if (!Char.IsLowSurrogate(charUnknownLow))
throw new ArgumentOutOfRangeException(nameof(charUnknownLow),
- Environment.GetResourceString("ArgumentOutOfRange_Range",
- 0xDC00, 0xDFFF));
+ SR.Format(SR.ArgumentOutOfRange_Range, 0xDC00, 0xDFFF));
Contract.EndContractBlock();
// If we had a buffer already we're being recursive, throw, it's probably at the suspect
@@ -146,7 +145,7 @@ namespace System.Text
// We want it to get < 0 because == 0 means that the current/last character is a fallback
// and we need to detect recursion. We could have a flag but we already have this counter.
iCount--;
-
+
// Do we have anything left? 0 is now last fallback char, negative is nothing left
if (iCount < 0)
return '\0';
diff --git a/src/mscorlib/src/System/Text/EncoderExceptionFallback.cs b/src/mscorlib/src/System/Text/EncoderExceptionFallback.cs
index 6735e7a5f8..b75847d1e7 100644
--- a/src/mscorlib/src/System/Text/EncoderExceptionFallback.cs
+++ b/src/mscorlib/src/System/Text/EncoderExceptionFallback.cs
@@ -2,12 +2,12 @@
// 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.Serialization;
+using System.Diagnostics.Contracts;
+
namespace System.Text
{
- using System;
- using System.Runtime.Serialization;
- using System.Diagnostics.Contracts;
-
[Serializable]
public sealed class EncoderExceptionFallback : EncoderFallback
{
@@ -49,13 +49,12 @@ namespace System.Text
public sealed class EncoderExceptionFallbackBuffer : EncoderFallbackBuffer
{
- public EncoderExceptionFallbackBuffer(){}
+ public EncoderExceptionFallbackBuffer() { }
public override bool Fallback(char charUnknown, int index)
{
// Fall back our char
throw new EncoderFallbackException(
- Environment.GetResourceString("Argument_InvalidCodePageConversionIndex",
- (int)charUnknown, index), charUnknown, index);
+ SR.Format(SR.Argument_InvalidCodePageConversionIndex, (int)charUnknown, index), charUnknown, index);
}
public override bool Fallback(char charUnknownHigh, char charUnknownLow, int index)
@@ -63,14 +62,12 @@ namespace System.Text
if (!Char.IsHighSurrogate(charUnknownHigh))
{
throw new ArgumentOutOfRangeException(nameof(charUnknownHigh),
- Environment.GetResourceString("ArgumentOutOfRange_Range",
- 0xD800, 0xDBFF));
+ SR.Format(SR.ArgumentOutOfRange_Range, 0xD800, 0xDBFF));
}
if (!Char.IsLowSurrogate(charUnknownLow))
{
throw new ArgumentOutOfRangeException(nameof(charUnknownLow),
- Environment.GetResourceString("ArgumentOutOfRange_Range",
- 0xDC00, 0xDFFF));
+ SR.Format(SR.ArgumentOutOfRange_Range, 0xDC00, 0xDFFF));
}
Contract.EndContractBlock();
@@ -78,8 +75,7 @@ namespace System.Text
// Fall back our char
throw new EncoderFallbackException(
- Environment.GetResourceString("Argument_InvalidCodePageConversionIndex",
- iTemp, index), charUnknownHigh, charUnknownLow, index);
+ SR.Format(SR.Argument_InvalidCodePageConversionIndex, iTemp, index), charUnknownHigh, charUnknownLow, index);
}
public override char GetNextChar()
@@ -106,27 +102,27 @@ namespace System.Text
[Serializable]
public sealed class EncoderFallbackException : ArgumentException
{
- char charUnknown;
- char charUnknownHigh;
- char charUnknownLow;
- int index;
+ private char charUnknown;
+ private char charUnknownHigh;
+ private char charUnknownLow;
+ private int index;
public EncoderFallbackException()
- : base(Environment.GetResourceString("Arg_ArgumentException"))
+ : base(SR.Arg_ArgumentException)
{
- SetErrorCode(__HResults.COR_E_ARGUMENT);
+ HResult = __HResults.COR_E_ARGUMENT;
}
public EncoderFallbackException(String message)
: base(message)
{
- SetErrorCode(__HResults.COR_E_ARGUMENT);
+ HResult = __HResults.COR_E_ARGUMENT;
}
public EncoderFallbackException(String message, Exception innerException)
: base(message, innerException)
{
- SetErrorCode(__HResults.COR_E_ARGUMENT);
+ HResult = __HResults.COR_E_ARGUMENT;
}
internal EncoderFallbackException(SerializationInfo info, StreamingContext context) : base(info, context)
@@ -146,14 +142,12 @@ namespace System.Text
if (!Char.IsHighSurrogate(charUnknownHigh))
{
throw new ArgumentOutOfRangeException(nameof(charUnknownHigh),
- Environment.GetResourceString("ArgumentOutOfRange_Range",
- 0xD800, 0xDBFF));
+ SR.Format(SR.ArgumentOutOfRange_Range, 0xD800, 0xDBFF));
}
if (!Char.IsLowSurrogate(charUnknownLow))
{
throw new ArgumentOutOfRangeException(nameof(CharUnknownLow),
- Environment.GetResourceString("ArgumentOutOfRange_Range",
- 0xDC00, 0xDFFF));
+ SR.Format(SR.ArgumentOutOfRange_Range, 0xDC00, 0xDFFF));
}
Contract.EndContractBlock();
@@ -197,7 +191,7 @@ namespace System.Text
// Return true if the unknown character is a surrogate pair.
public bool IsUnknownSurrogate()
{
- return (this.charUnknownHigh != '\0');
+ return (charUnknownHigh != '\0');
}
}
}
diff --git a/src/mscorlib/src/System/Text/EncoderFallback.cs b/src/mscorlib/src/System/Text/EncoderFallback.cs
index db2bf93bdd..410b6f5016 100644
--- a/src/mscorlib/src/System/Text/EncoderFallback.cs
+++ b/src/mscorlib/src/System/Text/EncoderFallback.cs
@@ -13,9 +13,9 @@ namespace System.Text
[Serializable]
public abstract class EncoderFallback
{
-// disable csharp compiler warning #0414: field assigned unused value
+ // disable csharp compiler warning #0414: field assigned unused value
#pragma warning disable 0414
- internal bool bIsMicrosoftBestFitFallback = false;
+ internal bool bIsMicrosoftBestFitFallback = false;
#pragma warning restore 0414
private static volatile EncoderFallback replacementFallback; // Default fallback, uses no best fit & "?"
@@ -43,7 +43,7 @@ namespace System.Text
get
{
if (replacementFallback == null)
- lock(InternalSyncObject)
+ lock (InternalSyncObject)
if (replacementFallback == null)
replacementFallback = new EncoderReplacementFallback();
@@ -57,7 +57,7 @@ namespace System.Text
get
{
if (exceptionFallback == null)
- lock(InternalSyncObject)
+ lock (InternalSyncObject)
if (exceptionFallback == null)
exceptionFallback = new EncoderExceptionFallback();
@@ -107,19 +107,19 @@ namespace System.Text
public virtual void Reset()
{
- while (GetNextChar() != (char)0);
+ while (GetNextChar() != (char)0) ;
}
// Internal items to help us figure out what we're doing as far as error messages, etc.
// These help us with our performance and messages internally
- internal unsafe char* charStart;
- internal unsafe char* charEnd;
- internal EncoderNLS encoder;
- internal bool setEncoder;
- internal bool bUsedEncoder;
- internal bool bFallingBack = false;
- internal int iRecursionCount = 0;
- private const int iMaxRecursion = 250;
+ internal unsafe char* charStart;
+ internal unsafe char* charEnd;
+ internal EncoderNLS encoder;
+ internal bool setEncoder;
+ internal bool bUsedEncoder;
+ internal bool bFallingBack = false;
+ internal int iRecursionCount = 0;
+ private const int iMaxRecursion = 250;
// Internal Reset
// For example, what if someone fails a conversion and wants to reset one of our fallback buffers?
@@ -224,9 +224,7 @@ namespace System.Text
{
// Throw it, using our complete character
throw new ArgumentException(
- Environment.GetResourceString("Argument_RecursiveFallback",
- charRecursive), "chars");
+ SR.Format(SR.Argument_RecursiveFallback, charRecursive), "chars");
}
-
}
}
diff --git a/src/mscorlib/src/System/Text/EncoderNLS.cs b/src/mscorlib/src/System/Text/EncoderNLS.cs
index 95901e01f4..99a26ca575 100644
--- a/src/mscorlib/src/System/Text/EncoderNLS.cs
+++ b/src/mscorlib/src/System/Text/EncoderNLS.cs
@@ -2,12 +2,13 @@
// 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.Runtime.Serialization;
+using System.Text;
+using System;
+using System.Diagnostics.Contracts;
+
namespace System.Text
{
- using System.Runtime.Serialization;
- using System.Text;
- using System;
- using System.Diagnostics.Contracts;
// An Encoder is used to encode a sequence of blocks of characters into
// a sequence of blocks of bytes. Following instantiation of an encoder,
// sequential blocks of characters are converted into blocks of bytes through
@@ -24,23 +25,23 @@ namespace System.Text
internal class EncoderNLS : Encoder, ISerializable
{
// Need a place for the last left over character, most of our encodings use this
- internal char charLeftOver;
-
+ internal char charLeftOver;
+
protected Encoding m_encoding;
-
- [NonSerialized] protected bool m_mustFlush;
- [NonSerialized] internal bool m_throwOnOverflow;
- [NonSerialized] internal int m_charsUsed;
-#region Serialization
+ [NonSerialized] protected bool m_mustFlush;
+ [NonSerialized] internal bool m_throwOnOverflow;
+ [NonSerialized] internal int m_charsUsed;
+
+ #region Serialization
// Constructor called by serialization. called during deserialization.
internal EncoderNLS(SerializationInfo info, StreamingContext context)
{
throw new NotSupportedException(
String.Format(
- System.Globalization.CultureInfo.CurrentCulture,
- Environment.GetResourceString("NotSupported_TypeCannotDeserialized"), this.GetType()));
+ System.Globalization.CultureInfo.CurrentCulture,
+ SR.NotSupported_TypeCannotDeserialized, this.GetType()));
}
// ISerializable implementation. called during serialization.
@@ -52,7 +53,7 @@ namespace System.Text
info.SetType(typeof(Encoding.DefaultEncoder));
}
-#endregion Serialization
+ #endregion Serialization
internal EncoderNLS(Encoding encoding)
{
@@ -80,15 +81,15 @@ namespace System.Text
// Validate input parameters
if (chars == null)
throw new ArgumentNullException(nameof(chars),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index<0 ? nameof(index) : nameof(count)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
if (chars.Length - index < count)
throw new ArgumentOutOfRangeException(nameof(chars),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ SR.ArgumentOutOfRange_IndexCountBuffer);
Contract.EndContractBlock();
// Avoid empty input problem
@@ -109,11 +110,11 @@ namespace System.Text
// Validate input parameters
if (chars == null)
throw new ArgumentNullException(nameof(chars),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (count < 0)
throw new ArgumentOutOfRangeException(nameof(count),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
this.m_mustFlush = flush;
@@ -127,19 +128,19 @@ namespace System.Text
// Validate parameters
if (chars == null || bytes == null)
throw new ArgumentNullException((chars == null ? nameof(chars) : nameof(bytes)),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? nameof(charIndex) : nameof(charCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? nameof(charIndex) : nameof(charCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
if (chars.Length - charIndex < charCount)
throw new ArgumentOutOfRangeException(nameof(chars),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ SR.ArgumentOutOfRange_IndexCountBuffer);
if (byteIndex < 0 || byteIndex > bytes.Length)
throw new ArgumentOutOfRangeException(nameof(byteIndex),
- Environment.GetResourceString("ArgumentOutOfRange_Index"));
+ SR.ArgumentOutOfRange_Index);
Contract.EndContractBlock();
if (chars.Length == 0)
@@ -151,11 +152,11 @@ namespace System.Text
// Just call pointer version
fixed (char* pChars = &chars[0])
- fixed (byte* pBytes = &bytes[0])
+ fixed (byte* pBytes = &bytes[0])
- // Remember that charCount is # to decode, not size of array.
- return GetBytes(pChars + charIndex, charCount,
- pBytes + byteIndex, byteCount, flush);
+ // Remember that charCount is # to decode, not size of array.
+ return GetBytes(pChars + charIndex, charCount,
+ pBytes + byteIndex, byteCount, flush);
}
public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, bool flush)
@@ -163,11 +164,11 @@ namespace System.Text
// Validate parameters
if (chars == null || bytes == null)
throw new ArgumentNullException((chars == null ? nameof(chars) : nameof(bytes)),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (byteCount < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((byteCount<0 ? nameof(byteCount) : nameof(charCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((byteCount < 0 ? nameof(byteCount) : nameof(charCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
this.m_mustFlush = flush;
@@ -184,23 +185,23 @@ namespace System.Text
// Validate parameters
if (chars == null || bytes == null)
throw new ArgumentNullException((chars == null ? nameof(chars) : nameof(bytes)),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex<0 ? nameof(charIndex) : nameof(charCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? nameof(charIndex) : nameof(charCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex<0 ? nameof(byteIndex) : nameof(byteCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((byteIndex < 0 ? nameof(byteIndex) : nameof(byteCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
if (chars.Length - charIndex < charCount)
throw new ArgumentOutOfRangeException(nameof(chars),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ SR.ArgumentOutOfRange_IndexCountBuffer);
if (bytes.Length - byteIndex < byteCount)
throw new ArgumentOutOfRangeException(nameof(bytes),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
+ SR.ArgumentOutOfRange_IndexCountBuffer);
Contract.EndContractBlock();
@@ -230,10 +231,10 @@ namespace System.Text
// Validate input parameters
if (bytes == null || chars == null)
throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? nameof(charCount) : nameof(byteCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((charCount < 0 ? nameof(charCount) : nameof(byteCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
// We don't want to throw
@@ -283,6 +284,5 @@ namespace System.Text
{
m_mustFlush = false;
}
-
}
}
diff --git a/src/mscorlib/src/System/Text/EncoderReplacementFallback.cs b/src/mscorlib/src/System/Text/EncoderReplacementFallback.cs
index b0657ff18d..65b807c1bd 100644
--- a/src/mscorlib/src/System/Text/EncoderReplacementFallback.cs
+++ b/src/mscorlib/src/System/Text/EncoderReplacementFallback.cs
@@ -2,13 +2,13 @@
// 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;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
namespace System.Text
{
- using System;
- using System.Runtime;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
[Serializable]
public sealed class EncoderReplacementFallback : EncoderFallback
{
@@ -28,11 +28,11 @@ namespace System.Text
Contract.EndContractBlock();
// Make sure it doesn't have bad surrogate pairs
- bool bFoundHigh=false;
+ bool bFoundHigh = false;
for (int i = 0; i < replacement.Length; i++)
{
// Found a surrogate?
- if (Char.IsSurrogate(replacement,i))
+ if (Char.IsSurrogate(replacement, i))
{
// High or Low?
if (Char.IsHighSurrogate(replacement, i))
@@ -61,17 +61,17 @@ namespace System.Text
break;
}
if (bFoundHigh)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex", nameof(replacement)));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidCharSequenceNoIndex, nameof(replacement)));
strDefault = replacement;
}
public String DefaultString
{
- get
- {
+ get
+ {
return strDefault;
- }
+ }
}
public override EncoderFallbackBuffer CreateFallbackBuffer()
@@ -93,7 +93,7 @@ namespace System.Text
EncoderReplacementFallback that = value as EncoderReplacementFallback;
if (that != null)
{
- return (this.strDefault == that.strDefault);
+ return (strDefault == that.strDefault);
}
return (false);
}
@@ -110,14 +110,14 @@ namespace System.Text
{
// Store our default string
private String strDefault;
- int fallbackCount = -1;
- int fallbackIndex = -1;
+ private int fallbackCount = -1;
+ private int fallbackIndex = -1;
// Construction
public EncoderReplacementFallbackBuffer(EncoderReplacementFallback fallback)
{
// 2X in case we're a surrogate pair
- this.strDefault = fallback.DefaultString + fallback.DefaultString;
+ strDefault = fallback.DefaultString + fallback.DefaultString;
}
// Fallback Methods
@@ -129,8 +129,8 @@ namespace System.Text
{
// If we're recursive we may still have something in our buffer that makes this a surrogate
if (char.IsHighSurrogate(charUnknown) && fallbackCount >= 0 &&
- char.IsLowSurrogate(strDefault[fallbackIndex+1]))
- ThrowLastCharRecursive(Char.ConvertToUtf32(charUnknown, strDefault[fallbackIndex+1]));
+ char.IsLowSurrogate(strDefault[fallbackIndex + 1]))
+ ThrowLastCharRecursive(Char.ConvertToUtf32(charUnknown, strDefault[fallbackIndex + 1]));
// Nope, just one character
ThrowLastCharRecursive(unchecked((int)charUnknown));
@@ -138,7 +138,7 @@ namespace System.Text
// Go ahead and get our fallback
// Divide by 2 because we aren't a surrogate pair
- fallbackCount = strDefault.Length/2;
+ fallbackCount = strDefault.Length / 2;
fallbackIndex = -1;
return fallbackCount != 0;
@@ -149,13 +149,11 @@ namespace System.Text
// Double check input surrogate pair
if (!Char.IsHighSurrogate(charUnknownHigh))
throw new ArgumentOutOfRangeException(nameof(charUnknownHigh),
- Environment.GetResourceString("ArgumentOutOfRange_Range",
- 0xD800, 0xDBFF));
+ SR.Format(SR.ArgumentOutOfRange_Range, 0xD800, 0xDBFF));
if (!Char.IsLowSurrogate(charUnknownLow))
throw new ArgumentOutOfRangeException(nameof(charUnknownLow),
- Environment.GetResourceString("ArgumentOutOfRange_Range",
- 0xDC00, 0xDFFF));
+ SR.Format(SR.ArgumentOutOfRange_Range, 0xDC00, 0xDFFF));
Contract.EndContractBlock();
// If we had a buffer already we're being recursive, throw, it's probably at the suspect
@@ -176,7 +174,7 @@ namespace System.Text
// and we need to detect recursion. We could have a flag but we already have this counter.
fallbackCount--;
fallbackIndex++;
-
+
// Do we have anything left? 0 is now last fallback char, negative is nothing left
if (fallbackCount < 0)
return '\0';
diff --git a/src/mscorlib/src/System/Text/Encoding.cs b/src/mscorlib/src/System/Text/Encoding.cs
index 8cb01e41fa..159123495b 100644
--- a/src/mscorlib/src/System/Text/Encoding.cs
+++ b/src/mscorlib/src/System/Text/Encoding.cs
@@ -85,79 +85,83 @@ namespace System.Text
[Serializable]
public abstract class Encoding : ICloneable
{
- private static Encoding defaultEncoding;
+ // For netcore we use UTF8 as default encoding since ANSI isn't available
+ private static readonly UTF8Encoding.UTF8EncodingSealed s_defaultEncoding = new UTF8Encoding.UTF8EncodingSealed(encoderShouldEmitUTF8Identifier: false);
+
+ // Returns an encoding for the system's current ANSI code page.
+ public static Encoding Default => s_defaultEncoding;
//
// The following values are from mlang.idl. These values
// should be in sync with those in mlang.idl.
//
- internal const int MIMECONTF_MAILNEWS = 0x00000001;
- internal const int MIMECONTF_BROWSER = 0x00000002;
- internal const int MIMECONTF_SAVABLE_MAILNEWS = 0x00000100;
- internal const int MIMECONTF_SAVABLE_BROWSER = 0x00000200;
+ internal const int MIMECONTF_MAILNEWS = 0x00000001;
+ internal const int MIMECONTF_BROWSER = 0x00000002;
+ internal const int MIMECONTF_SAVABLE_MAILNEWS = 0x00000100;
+ internal const int MIMECONTF_SAVABLE_BROWSER = 0x00000200;
// Special Case Code Pages
- private const int CodePageDefault = 0;
- private const int CodePageNoOEM = 1; // OEM Code page not supported
- private const int CodePageNoMac = 2; // MAC code page not supported
- private const int CodePageNoThread = 3; // Thread code page not supported
- private const int CodePageNoSymbol = 42; // Symbol code page not supported
- private const int CodePageUnicode = 1200; // Unicode
- private const int CodePageBigEndian = 1201; // Big Endian Unicode
- private const int CodePageWindows1252 = 1252; // Windows 1252 code page
+ private const int CodePageDefault = 0;
+ private const int CodePageNoOEM = 1; // OEM Code page not supported
+ private const int CodePageNoMac = 2; // MAC code page not supported
+ private const int CodePageNoThread = 3; // Thread code page not supported
+ private const int CodePageNoSymbol = 42; // Symbol code page not supported
+ private const int CodePageUnicode = 1200; // Unicode
+ private const int CodePageBigEndian = 1201; // Big Endian Unicode
+ private const int CodePageWindows1252 = 1252; // Windows 1252 code page
// 20936 has same code page as 10008, so we'll special case it
private const int CodePageMacGB2312 = 10008;
- private const int CodePageGB2312 = 20936;
+ private const int CodePageGB2312 = 20936;
private const int CodePageMacKorean = 10003;
private const int CodePageDLLKorean = 20949;
// ISO 2022 Code Pages
- private const int ISO2022JP = 50220;
- private const int ISO2022JPESC = 50221;
- private const int ISO2022JPSISO = 50222;
- private const int ISOKorean = 50225;
- private const int ISOSimplifiedCN = 50227;
- private const int EUCJP = 51932;
- private const int ChineseHZ = 52936; // HZ has ~}~{~~ sequences
+ private const int ISO2022JP = 50220;
+ private const int ISO2022JPESC = 50221;
+ private const int ISO2022JPSISO = 50222;
+ private const int ISOKorean = 50225;
+ private const int ISOSimplifiedCN = 50227;
+ private const int EUCJP = 51932;
+ private const int ChineseHZ = 52936; // HZ has ~}~{~~ sequences
// 51936 is the same as 936
- private const int DuplicateEUCCN = 51936;
- private const int EUCCN = 936;
+ private const int DuplicateEUCCN = 51936;
+ private const int EUCCN = 936;
- private const int EUCKR = 51949;
+ private const int EUCKR = 51949;
// Latin 1 & ASCII Code Pages
- internal const int CodePageASCII = 20127; // ASCII
- internal const int ISO_8859_1 = 28591; // Latin1
+ internal const int CodePageASCII = 20127; // ASCII
+ internal const int ISO_8859_1 = 28591; // Latin1
// ISCII
- private const int ISCIIAssemese = 57006;
- private const int ISCIIBengali = 57003;
- private const int ISCIIDevanagari = 57002;
- private const int ISCIIGujarathi = 57010;
- private const int ISCIIKannada = 57008;
- private const int ISCIIMalayalam = 57009;
- private const int ISCIIOriya = 57007;
- private const int ISCIIPanjabi = 57011;
- private const int ISCIITamil = 57004;
- private const int ISCIITelugu = 57005;
+ private const int ISCIIAssemese = 57006;
+ private const int ISCIIBengali = 57003;
+ private const int ISCIIDevanagari = 57002;
+ private const int ISCIIGujarathi = 57010;
+ private const int ISCIIKannada = 57008;
+ private const int ISCIIMalayalam = 57009;
+ private const int ISCIIOriya = 57007;
+ private const int ISCIIPanjabi = 57011;
+ private const int ISCIITamil = 57004;
+ private const int ISCIITelugu = 57005;
// GB18030
- private const int GB18030 = 54936;
+ private const int GB18030 = 54936;
// Other
- private const int ISO_8859_8I = 38598;
+ private const int ISO_8859_8I = 38598;
private const int ISO_8859_8_Visual = 28598;
// 50229 is currently unsupported // "Chinese Traditional (ISO-2022)"
- private const int ENC50229 = 50229;
+ private const int ENC50229 = 50229;
// Special code pages
- private const int CodePageUTF7 = 65000;
- private const int CodePageUTF8 = 65001;
- private const int CodePageUTF32 = 12000;
- private const int CodePageUTF32BE = 12001;
+ private const int CodePageUTF7 = 65000;
+ private const int CodePageUTF8 = 65001;
+ private const int CodePageUTF32 = 12000;
+ private const int CodePageUTF32BE = 12001;
internal int m_codePage = 0;
@@ -228,13 +232,13 @@ namespace System.Text
}
-#region Serialization
+ #region Serialization
internal void OnDeserializing()
{
// intialize the optional Whidbey fields
encoderFallback = null;
decoderFallback = null;
- m_isReadOnly = true;
+ m_isReadOnly = true;
}
internal void OnDeserialized()
@@ -246,7 +250,7 @@ namespace System.Text
}
// dataItem is always recalculated from the code page #
- dataItem = null;
+ dataItem = null;
}
[OnDeserializing]
@@ -274,7 +278,7 @@ namespace System.Text
internal void DeserializeEncoding(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException(nameof(info));
+ if (info == null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// All versions have a code page
@@ -282,7 +286,7 @@ namespace System.Text
// We can get dataItem on the fly if needed, and the index is different between versions
// so ignore whatever dataItem data we get from Everett.
- this.dataItem = null;
+ this.dataItem = null;
// See if we have a code page
try
@@ -291,7 +295,7 @@ namespace System.Text
// Try Whidbey V2.0 Fields
//
- this.m_isReadOnly = (bool)info.GetValue("m_isReadOnly", typeof(bool));
+ m_isReadOnly = (bool)info.GetValue("m_isReadOnly", typeof(bool));
this.encoderFallback = (EncoderFallback)info.GetValue("encoderFallback", typeof(EncoderFallback));
this.decoderFallback = (DecoderFallback)info.GetValue("decoderFallback", typeof(DecoderFallback));
@@ -304,7 +308,7 @@ namespace System.Text
this.m_deserializedFromEverett = true;
// May as well be read only
- this.m_isReadOnly = true;
+ m_isReadOnly = true;
SetDefaultFallbacks();
}
}
@@ -313,11 +317,11 @@ namespace System.Text
internal void SerializeEncoding(SerializationInfo info, StreamingContext context)
{
// Any Info?
- if (info==null) throw new ArgumentNullException(nameof(info));
+ if (info == null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// These are new V2.0 Whidbey stuff
- info.AddValue("m_isReadOnly", this.m_isReadOnly);
+ info.AddValue("m_isReadOnly", m_isReadOnly);
info.AddValue("encoderFallback", this.EncoderFallback);
info.AddValue("decoderFallback", this.DecoderFallback);
@@ -332,7 +336,7 @@ namespace System.Text
info.AddValue("Encoding+dataItem", null);
}
-#endregion Serialization
+ #endregion Serialization
// Converts a byte array from one encoding to another. The bytes in the
// bytes array are converted from srcEncoding to
@@ -341,11 +345,12 @@ namespace System.Text
//
[Pure]
public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding,
- byte[] bytes) {
- if (bytes==null)
+ byte[] bytes)
+ {
+ if (bytes == null)
throw new ArgumentNullException(nameof(bytes));
Contract.Ensures(Contract.Result<byte[]>() != null);
-
+
return Convert(srcEncoding, dstEncoding, bytes, 0, bytes.Length);
}
@@ -356,22 +361,25 @@ namespace System.Text
//
[Pure]
public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding,
- byte[] bytes, int index, int count) {
- if (srcEncoding == null || dstEncoding == null) {
+ byte[] bytes, int index, int count)
+ {
+ if (srcEncoding == null || dstEncoding == null)
+ {
throw new ArgumentNullException((srcEncoding == null ? nameof(srcEncoding) : nameof(dstEncoding)),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
}
- if (bytes == null) {
+ if (bytes == null)
+ {
throw new ArgumentNullException(nameof(bytes),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
}
Contract.Ensures(Contract.Result<byte[]>() != null);
-
+
return dstEncoding.GetBytes(srcEncoding.GetChars(bytes, index, count));
}
- public static void RegisterProvider(EncodingProvider provider)
+ public static void RegisterProvider(EncodingProvider provider)
{
// Parameters validated inside EncodingProvider
EncodingProvider.AddProvider(provider);
@@ -390,10 +398,10 @@ namespace System.Text
// Otherwise, the code below will throw exception when trying to call
// EncodingTable.GetDataItem().
//
- if (codepage < 0 || codepage > 65535) {
+ if (codepage < 0 || codepage > 65535)
+ {
throw new ArgumentOutOfRangeException(
- nameof(codepage), Environment.GetResourceString("ArgumentOutOfRange_Range",
- 0, 65535));
+ nameof(codepage), SR.Format(SR.ArgumentOutOfRange_Range, 0, 65535));
}
Contract.EndContractBlock();
@@ -418,15 +426,14 @@ namespace System.Text
case CodePageNoMac: // 2 CP_MACCP
case CodePageNoThread: // 3 CP_THREAD_ACP
case CodePageNoSymbol: // 42 CP_SYMBOL
- throw new ArgumentException(Environment.GetResourceString(
- "Argument_CodepageNotSupported", codepage), nameof(codepage));
+ throw new ArgumentException(SR.Format(SR.Argument_CodepageNotSupported, codepage), nameof(codepage));
}
// Is it a valid code page?
if (EncodingTable.GetCodePageDataItem(codepage) == null)
{
throw new NotSupportedException(
- Environment.GetResourceString("NotSupported_NoCodepageData", codepage));
+ SR.Format(SR.NotSupported_NoCodepageData, codepage));
}
return UTF8;
@@ -498,15 +505,18 @@ namespace System.Text
[Pure]
public virtual byte[] GetPreamble()
{
- return EmptyArray<Byte>.Value;
+ return Array.Empty<Byte>();
}
- private void GetDataItem() {
- if (dataItem==null) {
+ private void GetDataItem()
+ {
+ if (dataItem == null)
+ {
dataItem = EncodingTable.GetCodePageDataItem(m_codePage);
- if(dataItem==null) {
+ if (dataItem == null)
+ {
throw new NotSupportedException(
- Environment.GetResourceString("NotSupported_NoCodepageData", m_codePage));
+ SR.Format(SR.NotSupported_NoCodepageData, m_codePage));
}
}
}
@@ -518,7 +528,8 @@ namespace System.Text
{
get
{
- if (dataItem==null) {
+ if (dataItem == null)
+ {
GetDataItem();
}
return (dataItem.BodyName);
@@ -531,7 +542,7 @@ namespace System.Text
{
get
{
- return Environment.GetResourceString("Globalization.cp_" + m_codePage.ToString());
+ return SR.GetResourceString("Globalization_cp_" + m_codePage.ToString());
}
}
@@ -542,7 +553,8 @@ namespace System.Text
{
get
{
- if (dataItem==null) {
+ if (dataItem == null)
+ {
GetDataItem();
}
return (dataItem.HeaderName);
@@ -556,7 +568,8 @@ namespace System.Text
{
get
{
- if (dataItem==null) {
+ if (dataItem == null)
+ {
GetDataItem();
}
return (dataItem.WebName);
@@ -569,7 +582,8 @@ namespace System.Text
{
get
{
- if (dataItem==null) {
+ if (dataItem == null)
+ {
GetDataItem();
}
return (dataItem.UIFamilyCodePage);
@@ -579,9 +593,12 @@ namespace System.Text
// True if and only if the encoding is used for display by browsers clients.
- public virtual bool IsBrowserDisplay {
- get {
- if (dataItem==null) {
+ public virtual bool IsBrowserDisplay
+ {
+ get
+ {
+ if (dataItem == null)
+ {
GetDataItem();
}
return ((dataItem.Flags & MIMECONTF_BROWSER) != 0);
@@ -590,9 +607,12 @@ namespace System.Text
// True if and only if the encoding is used for saving by browsers clients.
- public virtual bool IsBrowserSave {
- get {
- if (dataItem==null) {
+ public virtual bool IsBrowserSave
+ {
+ get
+ {
+ if (dataItem == null)
+ {
GetDataItem();
}
return ((dataItem.Flags & MIMECONTF_SAVABLE_BROWSER) != 0);
@@ -601,9 +621,12 @@ namespace System.Text
// True if and only if the encoding is used for display by mail and news clients.
- public virtual bool IsMailNewsDisplay {
- get {
- if (dataItem==null) {
+ public virtual bool IsMailNewsDisplay
+ {
+ get
+ {
+ if (dataItem == null)
+ {
GetDataItem();
}
return ((dataItem.Flags & MIMECONTF_MAILNEWS) != 0);
@@ -614,9 +637,12 @@ namespace System.Text
// True if and only if the encoding is used for saving documents by mail and
// news clients
- public virtual bool IsMailNewsSave {
- get {
- if (dataItem==null) {
+ public virtual bool IsMailNewsSave
+ {
+ get
+ {
+ if (dataItem == null)
+ {
GetDataItem();
}
return ((dataItem.Flags & MIMECONTF_SAVABLE_MAILNEWS) != 0);
@@ -644,7 +670,7 @@ namespace System.Text
set
{
if (this.IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
throw new ArgumentNullException(nameof(value));
@@ -665,7 +691,7 @@ namespace System.Text
set
{
if (this.IsReadOnly)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ReadOnly"));
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
if (value == null)
throw new ArgumentNullException(nameof(value));
@@ -715,7 +741,7 @@ namespace System.Text
if (chars == null)
{
throw new ArgumentNullException(nameof(chars),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
}
Contract.EndContractBlock();
@@ -731,7 +757,6 @@ namespace System.Text
char[] chars = s.ToCharArray();
return GetByteCount(chars, 0, chars.Length);
-
}
// Returns the number of bytes required to encode a range of characters in
@@ -746,17 +771,17 @@ namespace System.Text
public int GetByteCount(string s, int index, int count)
{
if (s == null)
- throw new ArgumentNullException(nameof(s),
- Environment.GetResourceString("ArgumentNull_String"));
+ throw new ArgumentNullException(nameof(s),
+ SR.ArgumentNull_String);
if (index < 0)
throw new ArgumentOutOfRangeException(nameof(index),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
throw new ArgumentOutOfRangeException(nameof(count),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ SR.ArgumentOutOfRange_NeedNonNegNum);
if (index > s.Length - count)
throw new ArgumentOutOfRangeException(nameof(index),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
+ SR.ArgumentOutOfRange_IndexCount);
Contract.EndContractBlock();
unsafe
@@ -779,11 +804,11 @@ namespace System.Text
// Validate input parameters
if (chars == null)
throw new ArgumentNullException(nameof(chars),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (count < 0)
throw new ArgumentOutOfRangeException(nameof(count),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
char[] arrChar = new char[count];
@@ -814,7 +839,7 @@ namespace System.Text
if (chars == null)
{
throw new ArgumentNullException(nameof(chars),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
}
Contract.EndContractBlock();
return GetBytes(chars, 0, chars.Length);
@@ -851,7 +876,7 @@ namespace System.Text
{
if (s == null)
throw new ArgumentNullException(nameof(s),
- Environment.GetResourceString("ArgumentNull_String"));
+ SR.ArgumentNull_String);
Contract.EndContractBlock();
int byteCount = GetByteCount(s);
@@ -869,16 +894,16 @@ namespace System.Text
{
if (s == null)
throw new ArgumentNullException(nameof(s),
- Environment.GetResourceString("ArgumentNull_String"));
+ SR.ArgumentNull_String);
if (index < 0)
throw new ArgumentOutOfRangeException(nameof(index),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ SR.ArgumentOutOfRange_NeedNonNegNum);
if (count < 0)
throw new ArgumentOutOfRangeException(nameof(count),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ SR.ArgumentOutOfRange_NeedNonNegNum);
if (index > s.Length - count)
throw new ArgumentOutOfRangeException(nameof(index),
- Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
+ SR.ArgumentOutOfRange_IndexCount);
Contract.EndContractBlock();
unsafe
@@ -941,11 +966,11 @@ namespace System.Text
// Validate input parameters
if (bytes == null || chars == null)
throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount<0 ? nameof(charCount) : nameof(byteCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((charCount < 0 ? nameof(charCount) : nameof(byteCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
// Get the char array to convert
@@ -987,7 +1012,7 @@ namespace System.Text
if (bytes == null)
{
throw new ArgumentNullException(nameof(bytes),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
}
Contract.EndContractBlock();
return GetCharCount(bytes, 0, bytes.Length);
@@ -1008,11 +1033,11 @@ namespace System.Text
// Validate input parameters
if (bytes == null)
throw new ArgumentNullException(nameof(bytes),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (count < 0)
throw new ArgumentOutOfRangeException(nameof(count),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
byte[] arrbyte = new byte[count];
@@ -1040,7 +1065,7 @@ namespace System.Text
if (bytes == null)
{
throw new ArgumentNullException(nameof(bytes),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
}
Contract.EndContractBlock();
return GetChars(bytes, 0, bytes.Length);
@@ -1095,11 +1120,11 @@ namespace System.Text
// Validate input parameters
if (chars == null || bytes == null)
throw new ArgumentNullException(chars == null ? nameof(chars) : nameof(bytes),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
if (byteCount < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((byteCount<0 ? nameof(byteCount) : nameof(charCount)),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException((byteCount < 0 ? nameof(byteCount) : nameof(charCount)),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
// Get the byte array to convert
@@ -1146,10 +1171,10 @@ namespace System.Text
public unsafe string GetString(byte* bytes, int byteCount)
{
if (bytes == null)
- throw new ArgumentNullException(nameof(bytes), Environment.GetResourceString("ArgumentNull_Array"));
+ throw new ArgumentNullException(nameof(bytes), SR.ArgumentNull_Array);
if (byteCount < 0)
- throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(byteCount), SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
return String.CreateStringFromEncoding(bytes, byteCount, this);
@@ -1202,26 +1227,6 @@ namespace System.Text
return new DefaultDecoder(this);
}
- private static Encoding CreateDefaultEncoding()
- {
- // defaultEncoding should be null if we get here, but we can't
- // assert that in case another thread beat us to the initialization
-
- Encoding enc;
-
-
- // For silverlight we use UTF8 since ANSI isn't available
- enc = UTF8;
-
-
- // This method should only ever return one Encoding instance
- return Interlocked.CompareExchange(ref defaultEncoding, enc, null) ?? enc;
- }
-
- // Returns an encoding for the system's current ANSI code page.
-
- public static Encoding Default => defaultEncoding ?? CreateDefaultEncoding();
-
// Returns an Encoder object for this encoding. The returned object
// can be used to encode a sequence of characters into a sequence of bytes.
// Contrary to the GetBytes family of methods, an Encoder can
@@ -1274,7 +1279,7 @@ namespace System.Text
{
if (bytes == null)
throw new ArgumentNullException(nameof(bytes),
- Environment.GetResourceString("ArgumentNull_Array"));
+ SR.ArgumentNull_Array);
Contract.EndContractBlock();
return GetString(bytes, 0, bytes.Length);
@@ -1311,7 +1316,7 @@ namespace System.Text
// an instance of the UTF7Encoding class.
public static Encoding UTF7 => UTF7Encoding.s_default;
-
+
// Returns an encoding for the UTF-8 format. The returned encoding will be
// an instance of the UTF8Encoding class.
@@ -1329,7 +1334,8 @@ namespace System.Text
private static Encoding BigEndianUTF32 => UTF32Encoding.s_bigEndianDefault;
- public override bool Equals(Object value) {
+ public override bool Equals(Object value)
+ {
Encoding that = value as Encoding;
if (that != null)
return (m_codePage == that.m_codePage) &&
@@ -1339,20 +1345,21 @@ namespace System.Text
}
- public override int GetHashCode() {
+ public override int GetHashCode()
+ {
return m_codePage + this.EncoderFallback.GetHashCode() + this.DecoderFallback.GetHashCode();
}
internal virtual char[] GetBestFitUnicodeToBytesData()
{
// Normally we don't have any best fit data.
- return EmptyArray<Char>.Value;
+ return Array.Empty<Char>();
}
internal virtual char[] GetBestFitBytesToUnicodeData()
{
// Normally we don't have any best fit data.
- return EmptyArray<Char>.Value;
+ return Array.Empty<Char>();
}
internal void ThrowBytesOverflow()
@@ -1360,8 +1367,7 @@ namespace System.Text
// Special message to include fallback type in case fallback's GetMaxCharCount is broken
// This happens if user has implimented an encoder fallback with a broken GetMaxCharCount
throw new ArgumentException(
- Environment.GetResourceString("Argument_EncodingConversionOverflowBytes",
- EncodingName, EncoderFallback.GetType()), "bytes");
+ SR.Format(SR.Argument_EncodingConversionOverflowBytes, EncodingName, EncoderFallback.GetType()), "bytes");
}
internal void ThrowBytesOverflow(EncoderNLS encoder, bool nothingEncoded)
@@ -1384,8 +1390,7 @@ namespace System.Text
// Special message to include fallback type in case fallback's GetMaxCharCount is broken
// This happens if user has implimented a decoder fallback with a broken GetMaxCharCount
throw new ArgumentException(
- Environment.GetResourceString("Argument_EncodingConversionOverflowChars",
- EncodingName, DecoderFallback.GetType()), "chars");
+ SR.Format(SR.Argument_EncodingConversionOverflowChars, EncodingName, DecoderFallback.GetType()), "chars");
}
internal void ThrowCharsOverflow(DecoderNLS decoder, bool nothingDecoded)
@@ -1405,7 +1410,7 @@ namespace System.Text
}
[Serializable]
- internal class DefaultEncoder : Encoder, IObjectReference, ISerializable
+ internal sealed class DefaultEncoder : Encoder, IObjectReference, ISerializable
{
private Encoding m_encoding;
[NonSerialized] private bool m_hasInitializedEncoding;
@@ -1421,16 +1426,16 @@ namespace System.Text
// Constructor called by serialization, have to handle deserializing from Everett
internal DefaultEncoder(SerializationInfo info, StreamingContext context)
{
- if (info==null) throw new ArgumentNullException(nameof(info));
+ if (info == null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// All we have is our encoding
- this.m_encoding = (Encoding)info.GetValue("encoding", typeof(Encoding));
+ m_encoding = (Encoding)info.GetValue("encoding", typeof(Encoding));
- try
+ try
{
- this.m_fallback = (EncoderFallback) info.GetValue("m_fallback", typeof(EncoderFallback));
- this.charLeftOver = (Char) info.GetValue("charLeftOver", typeof(Char));
+ this.m_fallback = (EncoderFallback)info.GetValue("m_fallback", typeof(EncoderFallback));
+ this.charLeftOver = (Char)info.GetValue("charLeftOver", typeof(Char));
}
catch (SerializationException)
{
@@ -1453,7 +1458,7 @@ namespace System.Text
Encoder encoder = m_encoding.GetEncoder();
if (m_fallback != null)
encoder.m_fallback = m_fallback;
- if (charLeftOver != (char) 0)
+ if (charLeftOver != (char)0)
{
EncoderNLS encoderNls = encoder as EncoderNLS;
if (encoderNls != null)
@@ -1466,11 +1471,11 @@ namespace System.Text
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException(nameof(info));
+ if (info == null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// All we have is our encoding
- info.AddValue("encoding", this.m_encoding);
+ info.AddValue("encoding", m_encoding);
}
// Returns the number of bytes the next call to GetBytes will
@@ -1527,7 +1532,7 @@ namespace System.Text
}
[Serializable]
- internal class DefaultDecoder : Decoder, IObjectReference, ISerializable
+ internal sealed class DefaultDecoder : Decoder, IObjectReference, ISerializable
{
private Encoding m_encoding;
[NonSerialized]
@@ -1537,21 +1542,21 @@ namespace System.Text
{
m_encoding = encoding;
m_hasInitializedEncoding = true;
- }
+ }
// Constructor called by serialization, have to handle deserializing from Everett
internal DefaultDecoder(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException(nameof(info));
+ if (info == null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// All we have is our encoding
- this.m_encoding = (Encoding)info.GetValue("encoding", typeof(Encoding));
-
- try
+ m_encoding = (Encoding)info.GetValue("encoding", typeof(Encoding));
+
+ try
{
- this.m_fallback = (DecoderFallback) info.GetValue("m_fallback", typeof(DecoderFallback));
+ this.m_fallback = (DecoderFallback)info.GetValue("m_fallback", typeof(DecoderFallback));
}
catch (SerializationException)
{
@@ -1583,11 +1588,11 @@ namespace System.Text
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException(nameof(info));
+ if (info == null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// All we have is our encoding
- info.AddValue("encoding", this.m_encoding);
+ info.AddValue("encoding", m_encoding);
}
// Returns the number of characters the next call to GetChars will
@@ -1654,16 +1659,16 @@ namespace System.Text
internal class EncodingCharBuffer
{
- unsafe char* chars;
- unsafe char* charStart;
- unsafe char* charEnd;
- int charCountResult = 0;
- Encoding enc;
- DecoderNLS decoder;
- unsafe byte* byteStart;
- unsafe byte* byteEnd;
- unsafe byte* bytes;
- DecoderFallbackBuffer fallbackBuffer;
+ private unsafe char* chars;
+ private unsafe char* charStart;
+ private unsafe char* charEnd;
+ private int charCountResult = 0;
+ private Encoding enc;
+ private DecoderNLS decoder;
+ private unsafe byte* byteStart;
+ private unsafe byte* byteEnd;
+ private unsafe byte* bytes;
+ private DecoderFallbackBuffer fallbackBuffer;
internal unsafe EncodingCharBuffer(Encoding enc, DecoderNLS decoder, char* charStart, int charCount,
byte* byteStart, int byteCount)
@@ -1671,18 +1676,18 @@ namespace System.Text
this.enc = enc;
this.decoder = decoder;
- this.chars = charStart;
+ chars = charStart;
this.charStart = charStart;
- this.charEnd = charStart + charCount;
+ charEnd = charStart + charCount;
this.byteStart = byteStart;
- this.bytes = byteStart;
- this.byteEnd = byteStart + byteCount;
+ bytes = byteStart;
+ byteEnd = byteStart + byteCount;
if (this.decoder == null)
- this.fallbackBuffer = enc.DecoderFallback.CreateFallbackBuffer();
+ fallbackBuffer = enc.DecoderFallback.CreateFallbackBuffer();
else
- this.fallbackBuffer = this.decoder.FallbackBuffer;
+ fallbackBuffer = this.decoder.FallbackBuffer;
// If we're getting chars or getting char count we don't expect to have
// to remember fallbacks between calls (so it should be empty)
@@ -1698,7 +1703,7 @@ namespace System.Text
if (chars >= charEnd)
{
// Throw maybe
- bytes-=numBytes; // Didn't encode these bytes
+ bytes -= numBytes; // Didn't encode these bytes
enc.ThrowCharsOverflow(decoder, bytes <= byteStart); // Throw?
return false; // No throw, but no store either
}
@@ -1711,7 +1716,7 @@ namespace System.Text
internal unsafe bool AddChar(char ch)
{
- return AddChar(ch,1);
+ return AddChar(ch, 1);
}
internal unsafe void AdjustBytes(int count)
@@ -1789,41 +1794,40 @@ namespace System.Text
internal class EncodingByteBuffer
{
- unsafe byte* bytes;
- unsafe byte* byteStart;
- unsafe byte* byteEnd;
- unsafe char* chars;
- unsafe char* charStart;
- unsafe char* charEnd;
- int byteCountResult = 0;
- Encoding enc;
- EncoderNLS encoder;
+ private unsafe byte* bytes;
+ private unsafe byte* byteStart;
+ private unsafe byte* byteEnd;
+ private unsafe char* chars;
+ private unsafe char* charStart;
+ private unsafe char* charEnd;
+ private int byteCountResult = 0;
+ private Encoding enc;
+ private EncoderNLS encoder;
internal EncoderFallbackBuffer fallbackBuffer;
internal unsafe EncodingByteBuffer(Encoding inEncoding, EncoderNLS inEncoder,
byte* inByteStart, int inByteCount, char* inCharStart, int inCharCount)
{
- this.enc = inEncoding;
- this.encoder = inEncoder;
+ enc = inEncoding;
+ encoder = inEncoder;
- this.charStart = inCharStart;
- this.chars = inCharStart;
- this.charEnd = inCharStart + inCharCount;
+ charStart = inCharStart;
+ chars = inCharStart;
+ charEnd = inCharStart + inCharCount;
- this.bytes = inByteStart;
- this.byteStart = inByteStart;
- this.byteEnd = inByteStart + inByteCount;
+ bytes = inByteStart;
+ byteStart = inByteStart;
+ byteEnd = inByteStart + inByteCount;
- if (this.encoder == null)
+ if (encoder == null)
this.fallbackBuffer = enc.EncoderFallback.CreateFallbackBuffer();
else
{
- this.fallbackBuffer = this.encoder.FallbackBuffer;
+ this.fallbackBuffer = encoder.FallbackBuffer;
// If we're not converting we must not have data in our fallback buffer
if (encoder.m_throwOnOverflow && encoder.InternalHasFallbackBuffer &&
this.fallbackBuffer.Remaining > 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EncoderFallbackNotEmpty",
- encoder.Encoding.EncodingName, encoder.Fallback.GetType()));
+ throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, encoder.Encoding.EncodingName, encoder.Fallback.GetType()));
}
fallbackBuffer.InternalInitialize(chars, charEnd, encoder, bytes != null);
}
@@ -1867,8 +1871,8 @@ namespace System.Text
fallbackBuffer.MovePrevious(); // don't use last fallback
else
{
- Debug.Assert(chars > charStart ||
- ((bThrow == true) && (bytes == byteStart)),
+ Debug.Assert(chars > charStart ||
+ ((bThrow == true) && (bytes == byteStart)),
"[EncodingByteBuffer.MovePrevious]expected previous data or throw");
if (chars > charStart)
chars--; // don't use last char
@@ -1889,7 +1893,7 @@ namespace System.Text
internal unsafe char GetNextChar()
{
- // See if there's something in our fallback buffer
+ // See if there's something in our fallback buffer
char cReturn = fallbackBuffer.InternalGetNextChar();
// Nothing in the fallback buffer, return our normal data.
@@ -1898,9 +1902,9 @@ namespace System.Text
if (chars < charEnd)
cReturn = *(chars++);
}
-
+
return cReturn;
- }
+ }
internal unsafe int CharsUsed
{
diff --git a/src/mscorlib/src/System/Text/EncodingForwarder.cs b/src/mscorlib/src/System/Text/EncodingForwarder.cs
deleted file mode 100644
index 50ccbd9333..0000000000
--- a/src/mscorlib/src/System/Text/EncodingForwarder.cs
+++ /dev/null
@@ -1,329 +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.Diagnostics;
-using System.Diagnostics.Contracts;
-using System.Security;
-
-namespace System.Text
-{
- // Shared implementations for commonly overriden Encoding methods
-
- internal static class EncodingForwarder
- {
- // We normally have to duplicate a lot of code between UTF8Encoding,
- // UTF7Encoding, EncodingNLS, etc. because we want to override many
- // of the methods in all of those classes to just forward to the unsafe
- // version. (e.g. GetBytes(char[]))
- // Ideally, everything would just derive from EncodingNLS, but that's
- // not exposed in the public API, and C# prohibits a public class from
- // inheriting from an internal one. So, we have to override each of the
- // methods in question and repeat the argument validation/logic.
-
- // These set of methods exist so instead of duplicating code, we can
- // simply have those overriden methods call here to do the actual work.
-
- // NOTE: This class should ONLY be called from Encodings that override
- // the internal methods which accept an Encoder/DecoderNLS. The reason
- // for this is that by default, those methods just call the same overload
- // except without the encoder/decoder parameter. If an overriden method
- // without that parameter calls this class, which calls the overload with
- // the parameter, it will call the same method again, which will eventually
- // lead to a StackOverflowException.
-
- public unsafe static int GetByteCount(Encoding encoding, char[] chars, int index, int count)
- {
- // Validate parameters
-
- Debug.Assert(encoding != null); // this parameter should only be affected internally, so just do a debug check here
- if (chars == null)
- {
- throw new ArgumentNullException(nameof(chars), Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (index < 0 || count < 0)
- {
- throw new ArgumentOutOfRangeException(index < 0 ? nameof(index) : nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- if (chars.Length - index < count)
- {
- throw new ArgumentOutOfRangeException(nameof(chars), Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- }
- Contract.EndContractBlock();
-
- // If no input, return 0, avoid fixed empty array problem
- if (count == 0)
- return 0;
-
- // Just call the (internal) pointer version
- fixed (char* pChars = chars)
- return encoding.GetByteCount(pChars + index, count, encoder: null);
- }
-
- public unsafe static int GetByteCount(Encoding encoding, string s)
- {
- Debug.Assert(encoding != null);
- if (s == null)
- {
- string paramName = encoding is ASCIIEncoding ? "chars" : nameof(s); // ASCIIEncoding calls the string chars
- // UTF8Encoding does this as well, but it originally threw an ArgumentNull for "s" so don't check for that
- throw new ArgumentNullException(paramName);
- }
- Contract.EndContractBlock();
-
- // NOTE: The behavior of fixed *is* defined by
- // the spec for empty strings, although not for
- // null strings/empty char arrays. See
- // http://stackoverflow.com/q/37757751/4077294
- // Regardless, we may still want to check
- // for if (s.Length == 0) in the future
- // and short-circuit as an optimization (TODO).
-
- fixed (char* pChars = s)
- return encoding.GetByteCount(pChars, s.Length, encoder: null);
- }
-
- public unsafe static int GetByteCount(Encoding encoding, char* chars, int count)
- {
- Debug.Assert(encoding != null);
- if (chars == null)
- {
- throw new ArgumentNullException(nameof(chars), Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (count < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- Contract.EndContractBlock();
-
- // Call the internal version, with an empty encoder
- return encoding.GetByteCount(chars, count, encoder: null);
- }
-
- public unsafe static int GetBytes(Encoding encoding, string s, int charIndex, int charCount, byte[] bytes, int byteIndex)
- {
- Debug.Assert(encoding != null);
- if (s == null || bytes == null)
- {
- string stringName = encoding is ASCIIEncoding ? "chars" : nameof(s); // ASCIIEncoding calls the first parameter chars
- throw new ArgumentNullException(s == null ? stringName : nameof(bytes), Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (charIndex < 0 || charCount < 0)
- {
- throw new ArgumentOutOfRangeException(charIndex < 0 ? nameof(charIndex) : nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- if (s.Length - charIndex < charCount)
- {
- string stringName = encoding is ASCIIEncoding ? "chars" : nameof(s); // ASCIIEncoding calls the first parameter chars
- // Duplicate the above check since we don't want the overhead of a type check on the general path
- throw new ArgumentOutOfRangeException(stringName, Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
- }
- if (byteIndex < 0 || byteIndex > bytes.Length)
- {
- throw new ArgumentOutOfRangeException(nameof(byteIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- Contract.EndContractBlock();
-
- int byteCount = bytes.Length - byteIndex;
-
- // Fixed doesn't like empty arrays
- if (bytes.Length == 0)
- bytes = new byte[1];
-
- fixed (char* pChars = s) fixed (byte* pBytes = &bytes[0])
- {
- return encoding.GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, encoder: null);
- }
- }
-
- public unsafe static int GetBytes(Encoding encoding, char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
- {
- Debug.Assert(encoding != null);
- if (chars == null || bytes == null)
- {
- throw new ArgumentNullException(chars == null ? nameof(chars) : nameof(bytes), Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (charIndex < 0 || charCount < 0)
- {
- throw new ArgumentOutOfRangeException(charIndex < 0 ? nameof(charIndex) : nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- if (chars.Length - charIndex < charCount)
- {
- throw new ArgumentOutOfRangeException(nameof(chars), Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- }
- if (byteIndex < 0 || byteIndex > bytes.Length)
- {
- throw new ArgumentOutOfRangeException(nameof(byteIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- Contract.EndContractBlock();
-
- // If nothing to encode return 0, avoid fixed problem
- if (charCount == 0)
- return 0;
-
- // Note that this is the # of bytes to decode,
- // not the size of the array
- int byteCount = bytes.Length - byteIndex;
-
- // Fixed doesn't like 0 length arrays.
- if (bytes.Length == 0)
- bytes = new byte[1];
-
- // Just call the (internal) pointer version
- fixed (char* pChars = chars) fixed (byte* pBytes = &bytes[0])
- {
- return encoding.GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, encoder: null);
- }
- }
-
- public unsafe static int GetBytes(Encoding encoding, char* chars, int charCount, byte* bytes, int byteCount)
- {
- Debug.Assert(encoding != null);
- if (bytes == null || chars == null)
- {
- throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars), Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (charCount < 0 || byteCount < 0)
- {
- throw new ArgumentOutOfRangeException(charCount < 0 ? nameof(charCount) : nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- Contract.EndContractBlock();
-
- return encoding.GetBytes(chars, charCount, bytes, byteCount, encoder: null);
- }
-
- public unsafe static int GetCharCount(Encoding encoding, byte[] bytes, int index, int count)
- {
- Debug.Assert(encoding != null);
- if (bytes == null)
- {
- throw new ArgumentNullException(nameof(bytes), Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (index < 0 || count < 0)
- {
- throw new ArgumentOutOfRangeException(index < 0 ? nameof(index) : nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- if (bytes.Length - index < count)
- {
- throw new ArgumentOutOfRangeException(nameof(bytes), Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- }
- Contract.EndContractBlock();
-
- // If no input just return 0, fixed doesn't like 0 length arrays.
- if (count == 0)
- return 0;
-
- // Just call pointer version
- fixed (byte* pBytes = bytes)
- return encoding.GetCharCount(pBytes + index, count, decoder: null);
- }
-
- public unsafe static int GetCharCount(Encoding encoding, byte* bytes, int count)
- {
- Debug.Assert(encoding != null);
- if (bytes == null)
- {
- throw new ArgumentNullException(nameof(bytes), Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (count < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- Contract.EndContractBlock();
-
- return encoding.GetCharCount(bytes, count, decoder: null);
- }
-
- public unsafe static int GetChars(Encoding encoding, byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
- {
- Debug.Assert(encoding != null);
- if (bytes == null || chars == null)
- {
- throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars), Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (byteIndex < 0 || byteCount < 0)
- {
- throw new ArgumentOutOfRangeException(byteIndex < 0 ? nameof(byteIndex) : nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- if (bytes.Length - byteIndex < byteCount)
- {
- throw new ArgumentOutOfRangeException(nameof(bytes), Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- }
- if (charIndex < 0 || charIndex > chars.Length)
- {
- throw new ArgumentOutOfRangeException(nameof(charIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- Contract.EndContractBlock();
-
- if (byteCount == 0)
- return 0;
-
- // NOTE: This is the # of chars we can decode,
- // not the size of the array
- int charCount = chars.Length - charIndex;
-
- // Fixed doesn't like 0 length arrays.
- if (chars.Length == 0)
- chars = new char[1];
-
- fixed (byte* pBytes = bytes) fixed (char* pChars = &chars[0])
- {
- return encoding.GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, decoder: null);
- }
- }
-
- public unsafe static int GetChars(Encoding encoding, byte* bytes, int byteCount, char* chars, int charCount)
- {
- Debug.Assert(encoding != null);
- if (bytes == null || chars == null)
- {
- throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars), Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (charCount < 0 || byteCount < 0)
- {
- throw new ArgumentOutOfRangeException(charCount < 0 ? nameof(charCount) : nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- Contract.EndContractBlock();
-
- return encoding.GetChars(bytes, byteCount, chars, charCount, decoder: null);
- }
-
- public unsafe static string GetString(Encoding encoding, byte[] bytes, int index, int count)
- {
- Debug.Assert(encoding != null);
- if (bytes == null)
- {
- throw new ArgumentNullException(nameof(bytes), Environment.GetResourceString("ArgumentNull_Array"));
- }
- if (index < 0 || count < 0)
- {
- // ASCIIEncoding has different names for its parameters here (byteIndex, byteCount)
- bool ascii = encoding is ASCIIEncoding;
- string indexName = ascii ? "byteIndex" : nameof(index);
- string countName = ascii ? "byteCount" : nameof(count);
- throw new ArgumentOutOfRangeException(index < 0 ? indexName : countName, Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- if (bytes.Length - index < count)
- {
- throw new ArgumentOutOfRangeException(nameof(bytes), Environment.GetResourceString("ArgumentOutOfRange_IndexCountBuffer"));
- }
- Contract.EndContractBlock();
-
- // Avoid problems with empty input buffer
- if (count == 0)
- return string.Empty;
-
- // Call string.CreateStringFromEncoding here, which
- // allocates a string and lets the Encoding modify
- // it in place. This way, we don't have to allocate
- // an intermediary char[] to decode into and then
- // call the string constructor; instead we decode
- // directly into the string.
-
- fixed (byte* pBytes = bytes)
- {
- return string.CreateStringFromEncoding(pBytes + index, count, encoding);
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Text/EncodingInfo.cs b/src/mscorlib/src/System/Text/EncodingInfo.cs
deleted file mode 100644
index 26ad3344c6..0000000000
--- a/src/mscorlib/src/System/Text/EncodingInfo.cs
+++ /dev/null
@@ -1,74 +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.
-
-namespace System.Text
-{
- using System;
- using System.Text;
-
-
- [Serializable]
- public sealed class EncodingInfo
- {
- int iCodePage; // Code Page #
- String strEncodingName; // Short name (web name)
- String strDisplayName; // Full localized name
-
- internal EncodingInfo(int codePage, string name, string displayName)
- {
- this.iCodePage = codePage;
- this.strEncodingName = name;
- this.strDisplayName = displayName;
- }
-
-
- public int CodePage
- {
- get
- {
- return iCodePage;
- }
- }
-
-
- public String Name
- {
- get
- {
- return strEncodingName;
- }
- }
-
-
- public String DisplayName
- {
- get
- {
- return strDisplayName;
- }
- }
-
-
- public Encoding GetEncoding()
- {
- return Encoding.GetEncoding(this.iCodePage);
- }
-
- public override bool Equals(Object value)
- {
- EncodingInfo that = value as EncodingInfo;
- if (that != null)
- {
- return (this.CodePage == that.CodePage);
- }
- return (false);
- }
-
- public override int GetHashCode()
- {
- return this.CodePage;
- }
-
- }
-}
diff --git a/src/mscorlib/src/System/Text/EncodingNLS.cs b/src/mscorlib/src/System/Text/EncodingNLS.cs
deleted file mode 100644
index cb6ed8a52c..0000000000
--- a/src/mscorlib/src/System/Text/EncodingNLS.cs
+++ /dev/null
@@ -1,125 +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.
-
-namespace System.Text
-{
-
- using System;
- using System.Diagnostics.Contracts;
- using System.Collections;
- using System.Runtime.Remoting;
- using System.Globalization;
- using System.Threading;
- using Win32Native = Microsoft.Win32.Win32Native;
-
- // This class overrides Encoding with the things we need for our NLS Encodings
-
- [Serializable]
- internal abstract class EncodingNLS : Encoding
- {
- protected EncodingNLS(int codePage) : base(codePage)
- {
- }
-
- // NOTE: Many methods in this class forward to EncodingForwarder for
- // validating arguments/wrapping the unsafe methods in this class
- // which do the actual work. That class contains
- // shared logic for doing this which is used by
- // ASCIIEncoding, EncodingNLS, UnicodeEncoding, UTF32Encoding,
- // UTF7Encoding, and UTF8Encoding.
- // The reason the code is separated out into a static class, rather
- // than a base class which overrides all of these methods for us
- // (which is what EncodingNLS is for internal Encodings) is because
- // that's really more of an implementation detail so it's internal.
- // At the same time, C# doesn't allow a public class subclassing an
- // internal/private one, so we end up having to re-override these
- // methods in all of the public Encodings + EncodingNLS.
-
- // Returns the number of bytes required to encode a range of characters in
- // a character array.
-
- public override int GetByteCount(char[] chars, int index, int count)
- {
- return EncodingForwarder.GetByteCount(this, chars, index, count);
- }
-
- public override int GetByteCount(String s)
- {
- return EncodingForwarder.GetByteCount(this, s);
- }
-
- public override unsafe int GetByteCount(char* chars, int count)
- {
- return EncodingForwarder.GetByteCount(this, chars, count);
- }
-
- public override int GetBytes(String s, int charIndex, int charCount,
- byte[] bytes, int byteIndex)
- {
- return EncodingForwarder.GetBytes(this, s, charIndex, charCount, bytes, byteIndex);
- }
-
- // Encodes a range of characters in a character array into a range of bytes
- // in a byte array. An exception occurs if the byte array is not large
- // enough to hold the complete encoding of the characters. The
- // GetByteCount method can be used to determine the exact number of
- // bytes that will be produced for a given range of characters.
- // Alternatively, the GetMaxByteCount method can be used to
- // determine the maximum number of bytes that will be produced for a given
- // number of characters, regardless of the actual character values.
-
- public override int GetBytes(char[] chars, int charIndex, int charCount,
- byte[] bytes, int byteIndex)
- {
- return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
- }
-
- public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
- {
- return EncodingForwarder.GetBytes(this, chars, charCount, bytes, byteCount);
- }
-
- // Returns the number of characters produced by decoding a range of bytes
- // in a byte array.
-
- public override int GetCharCount(byte[] bytes, int index, int count)
- {
- return EncodingForwarder.GetCharCount(this, bytes, index, count);
- }
-
- public override unsafe int GetCharCount(byte* bytes, int count)
- {
- return EncodingForwarder.GetCharCount(this, bytes, count);
- }
-
- public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
- char[] chars, int charIndex)
- {
- return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
- }
-
- public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
- {
- return EncodingForwarder.GetChars(this, bytes, byteCount, chars, charCount);
- }
-
- // Returns a string containing the decoded representation of a range of
- // bytes in a byte array.
-
- public override String GetString(byte[] bytes, int index, int count)
- {
- return EncodingForwarder.GetString(this, bytes, index, count);
- }
-
- public override Decoder GetDecoder()
- {
- return new DecoderNLS(this);
- }
-
- public override Encoder GetEncoder()
- {
- return new EncoderNLS(this);
- }
- }
-}
diff --git a/src/mscorlib/src/System/Text/EncodingProvider.cs b/src/mscorlib/src/System/Text/EncodingProvider.cs
deleted file mode 100644
index 734d1ac761..0000000000
--- a/src/mscorlib/src/System/Text/EncodingProvider.cs
+++ /dev/null
@@ -1,136 +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.
-
-namespace System.Text
-{
- using System;
- using System.Collections;
- using System.Collections.Generic;
-
- public abstract class EncodingProvider
- {
- public EncodingProvider() { }
- public abstract Encoding GetEncoding(string name);
- public abstract Encoding GetEncoding(int codepage);
-
- // GetEncoding should return either valid encoding or null. shouldn't throw any exception except on null name
- public virtual Encoding GetEncoding(string name, EncoderFallback encoderFallback, DecoderFallback decoderFallback)
- {
- Encoding enc = GetEncoding(name);
- if (enc != null)
- {
- enc = (Encoding)GetEncoding(name).Clone();
- enc.EncoderFallback = encoderFallback;
- enc.DecoderFallback = decoderFallback;
- }
-
- return enc;
- }
-
- public virtual Encoding GetEncoding(int codepage, EncoderFallback encoderFallback, DecoderFallback decoderFallback)
- {
- Encoding enc = GetEncoding(codepage);
- if (enc != null)
- {
- enc = (Encoding)GetEncoding(codepage).Clone();
- enc.EncoderFallback = encoderFallback;
- enc.DecoderFallback = decoderFallback;
- }
-
- return enc;
- }
-
- internal static void AddProvider(EncodingProvider provider)
- {
- if (provider == null)
- throw new ArgumentNullException(nameof(provider));
-
- lock (s_InternalSyncObject)
- {
- if (s_providers == null)
- {
- s_providers = new EncodingProvider[1] { provider };
- return;
- }
-
- if (Array.IndexOf(s_providers, provider) >= 0)
- {
- return;
- }
-
- var providers = new EncodingProvider[s_providers.Length + 1];
- Array.Copy(s_providers, providers, s_providers.Length);
- providers[providers.Length - 1] = provider;
- s_providers = providers;
- }
- }
-
- internal static Encoding GetEncodingFromProvider(int codepage)
- {
- if (s_providers == null)
- return null;
-
- var providers = s_providers;
- foreach (EncodingProvider provider in providers)
- {
- Encoding enc = provider.GetEncoding(codepage);
- if (enc != null)
- return enc;
- }
-
- return null;
- }
-
- internal static Encoding GetEncodingFromProvider(string encodingName)
- {
- if (s_providers == null)
- return null;
-
- var providers = s_providers;
- foreach (EncodingProvider provider in providers)
- {
- Encoding enc = provider.GetEncoding(encodingName);
- if (enc != null)
- return enc;
- }
-
- return null;
- }
-
- internal static Encoding GetEncodingFromProvider(int codepage, EncoderFallback enc, DecoderFallback dec)
- {
- if (s_providers == null)
- return null;
-
- var providers = s_providers;
- foreach (EncodingProvider provider in providers)
- {
- Encoding encing = provider.GetEncoding(codepage, enc, dec);
- if (encing != null)
- return encing;
- }
-
- return null;
- }
-
- internal static Encoding GetEncodingFromProvider(string encodingName, EncoderFallback enc, DecoderFallback dec)
- {
- if (s_providers == null)
- return null;
-
- var providers = s_providers;
- foreach (EncodingProvider provider in providers)
- {
- Encoding encoding = provider.GetEncoding(encodingName, enc, dec);
- if (encoding != null)
- return encoding;
- }
-
- return null;
- }
-
- private static Object s_InternalSyncObject = new Object();
- private static volatile EncodingProvider[] s_providers;
- }
-}
diff --git a/src/mscorlib/src/System/Text/Latin1Encoding.cs b/src/mscorlib/src/System/Text/Latin1Encoding.cs
index 26009bf6c0..e456b8533d 100644
--- a/src/mscorlib/src/System/Text/Latin1Encoding.cs
+++ b/src/mscorlib/src/System/Text/Latin1Encoding.cs
@@ -2,19 +2,18 @@
// 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.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Collections;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
+
namespace System.Text
{
- using System;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- using System.Runtime.InteropServices;
- using System.Security;
- using System.Collections;
- using System.Runtime.CompilerServices;
- using System.Runtime.Serialization;
-
-
//
// Latin1Encoding is a simple override to optimize the GetString version of Latin1Encoding.
// because of the best fit cases we can't do this when encoding the string, only when decoding
@@ -47,7 +46,7 @@ namespace System.Text
{
// Make sure to get the base stuff too This throws if info is null
SerializeEncoding(info, context);
- Debug.Assert(info!=null, "[Latin1Encoding.GetObjectData] Expected null info to throw");
+ Debug.Assert(info != null, "[Latin1Encoding.GetObjectData] Expected null info to throw");
// In Everett this is a CodePageEncoding, so it needs maxCharSize
info.AddValue("CodePageEncoding+maxCharSize", 1);
@@ -115,6 +114,7 @@ namespace System.Text
// For fallback we may need a fallback buffer, we know we aren't default fallback.
EncoderFallbackBuffer fallbackBuffer = null;
+ char* charsForFallback;
// We may have a left over character from last time, try and process it.
if (charLeftOver > 0)
@@ -128,7 +128,9 @@ namespace System.Text
// Since left over char was a surrogate, it'll have to be fallen back.
// Get Fallback
// This will fallback a pair if *chars is a low surrogate
- fallbackBuffer.InternalFallback(charLeftOver, ref chars);
+ charsForFallback = chars;
+ fallbackBuffer.InternalFallback(charLeftOver, ref charsForFallback);
+ chars = charsForFallback;
}
// Now we may have fallback char[] already from the encoder
@@ -161,7 +163,9 @@ namespace System.Text
}
// Get Fallback
- fallbackBuffer.InternalFallback(ch, ref chars);
+ charsForFallback = chars;
+ fallbackBuffer.InternalFallback(ch, ref charsForFallback);
+ chars = charsForFallback;
continue;
}
@@ -216,7 +220,7 @@ namespace System.Text
if (fallback != null && fallback.MaxCharCount == 1)
{
// Fast version
- char cReplacement=fallback.DefaultString[0];
+ char cReplacement = fallback.DefaultString[0];
// Check for replacements in range, otherwise fall back to slow version.
if (cReplacement <= (char)0xff)
@@ -262,7 +266,7 @@ namespace System.Text
if (encoder != null)
{
encoder.charLeftOver = (char)0;
- encoder.m_charsUsed = (int)(chars-charStart);
+ encoder.m_charsUsed = (int)(chars - charStart);
}
return (int)(bytes - byteStart);
}
@@ -275,6 +279,7 @@ namespace System.Text
// For fallback we may need a fallback buffer, we know we aren't default fallback, create & init it
EncoderFallbackBuffer fallbackBuffer = null;
+ char* charsForFallback;
// We may have a left over character from last time, try and process it.
if (charLeftOver > 0)
@@ -289,7 +294,10 @@ namespace System.Text
// Since left over char was a surrogate, it'll have to be fallen back.
// Get Fallback
// This will fallback a pair if *chars is a low surrogate
- fallbackBuffer.InternalFallback(charLeftOver, ref chars);
+ charsForFallback = chars;
+ fallbackBuffer.InternalFallback(charLeftOver, ref charsForFallback);
+ chars = charsForFallback;
+
if (fallbackBuffer.Remaining > byteEnd - bytes)
{
// Throw it, if we don't have enough for this we never will
@@ -327,7 +335,9 @@ namespace System.Text
}
// Get Fallback
- fallbackBuffer.InternalFallback(ch, ref chars);
+ charsForFallback = chars;
+ fallbackBuffer.InternalFallback(ch, ref charsForFallback);
+ chars = charsForFallback;
// Make sure we have enough room. Each fallback char will be 1 output char
// (or else cause a recursion exception)
@@ -335,7 +345,7 @@ namespace System.Text
{
// Didn't use this char, throw it. Chars should've advanced by now
// If we had encoder fallback data it would've thrown before the loop
- Debug.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[Latin1Encoding.GetBytes]Expected chars to have advanced (fallback case)");
chars--;
fallbackBuffer.InternalReset();
@@ -357,7 +367,7 @@ namespace System.Text
"[Latin1Encoding.GetBytes]Expected fallback to have throw initially if insufficient space");
if (fallbackBuffer == null || fallbackBuffer.bFallingBack == false)
{
- Debug.Assert(chars > charStart,
+ Debug.Assert(chars > charStart,
"[Latin1Encoding.GetBytes]Expected chars to have advanced (fallback case)");
chars--; // don't use last char
}
@@ -441,8 +451,8 @@ namespace System.Text
public override int GetMaxByteCount(int charCount)
{
if (charCount < 0)
- throw new ArgumentOutOfRangeException(nameof(charCount),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(charCount),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
// Characters would be # of characters + 1 in case high surrogate is ? * max fallback
@@ -454,15 +464,15 @@ namespace System.Text
// 1 to 1 for most characters. Only surrogates with fallbacks have less.
if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_GetByteCountOverflow);
return (int)byteCount;
}
public override int GetMaxCharCount(int byteCount)
{
if (byteCount < 0)
- throw new ArgumentOutOfRangeException(nameof(byteCount),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
// Just return length, SBCS stay the same length because they don't map to surrogate
@@ -473,7 +483,7 @@ namespace System.Text
charCount *= DecoderFallback.MaxCharCount;
if (charCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(byteCount), SR.ArgumentOutOfRange_GetCharCountOverflow);
return (int)charCount;
}
diff --git a/src/mscorlib/src/System/Text/Normalization.Unix.cs b/src/mscorlib/src/System/Text/Normalization.Unix.cs
index d49bdc6c21..2a10d062f2 100644
--- a/src/mscorlib/src/System/Text/Normalization.Unix.cs
+++ b/src/mscorlib/src/System/Text/Normalization.Unix.cs
@@ -4,6 +4,7 @@
using System.Security;
using System.Text;
+using System.Globalization;
namespace System.Text
{
@@ -13,11 +14,18 @@ namespace System.Text
{
ValidateArguments(strInput, normalizationForm);
+ if (GlobalizationMode.Invariant)
+ {
+ // In Invariant mode we assume all characters are normalized.
+ // This is because we don't support any linguistic operation on the strings
+ return true;
+ }
+
int ret = Interop.GlobalizationInterop.IsNormalized(normalizationForm, strInput, strInput.Length);
if (ret == -1)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"), nameof(strInput));
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(strInput));
}
return ret == 1;
@@ -27,6 +35,13 @@ namespace System.Text
{
ValidateArguments(strInput, normalizationForm);
+ if (GlobalizationMode.Invariant)
+ {
+ // In Invariant mode we assume all characters are normalized.
+ // This is because we don't support any linguistic operation on the strings
+ return strInput;
+ }
+
char[] buf = new char[strInput.Length];
for (int attempts = 2; attempts > 0; attempts--)
@@ -35,7 +50,7 @@ namespace System.Text
if (realLen == -1)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"), nameof(strInput));
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(strInput));
}
if (realLen <= buf.Length)
@@ -46,7 +61,7 @@ namespace System.Text
buf = new char[realLen];
}
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"), nameof(strInput));
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(strInput));
}
// -----------------------------
@@ -63,12 +78,12 @@ namespace System.Text
if (normalizationForm != NormalizationForm.FormC && normalizationForm != NormalizationForm.FormD &&
normalizationForm != NormalizationForm.FormKC && normalizationForm != NormalizationForm.FormKD)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidNormalizationForm"), nameof(normalizationForm));
+ throw new ArgumentException(SR.Argument_InvalidNormalizationForm, nameof(normalizationForm));
}
if (HasInvalidUnicodeSequence(strInput))
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"), nameof(strInput));
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(strInput));
}
}
diff --git a/src/mscorlib/src/System/Text/Normalization.Windows.cs b/src/mscorlib/src/System/Text/Normalization.Windows.cs
index 3bcba08934..389dba743d 100644
--- a/src/mscorlib/src/System/Text/Normalization.Windows.cs
+++ b/src/mscorlib/src/System/Text/Normalization.Windows.cs
@@ -2,176 +2,53 @@
// 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.Security;
+using System.Globalization;
+using System.Text;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
namespace System.Text
{
- using System;
- using System.Security;
- using System.Globalization;
- using System.Text;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
// This internal class wraps up our normalization behavior
internal class Normalization
{
- //
- // Flags that track whether given normalization form was initialized
- //
- private static volatile bool NFC;
- private static volatile bool NFD;
- private static volatile bool NFKC;
- private static volatile bool NFKD;
- private static volatile bool IDNA;
- private static volatile bool NFCDisallowUnassigned;
- private static volatile bool NFDDisallowUnassigned;
- private static volatile bool NFKCDisallowUnassigned;
- private static volatile bool NFKDDisallowUnassigned;
- private static volatile bool IDNADisallowUnassigned;
- private static volatile bool Other;
-
- // These are error codes we get back from the Normalization DLL
- private const int ERROR_SUCCESS = 0;
- private const int ERROR_NOT_ENOUGH_MEMORY = 8;
- private const int ERROR_INVALID_PARAMETER = 87;
- private const int ERROR_INSUFFICIENT_BUFFER = 122;
- private const int ERROR_NO_UNICODE_TRANSLATION = 1113;
-
- static private unsafe void InitializeForm(NormalizationForm form, String strDataFile)
+ internal static bool IsNormalized(String strInput, NormalizationForm normForm)
{
- byte* pTables = null;
-
- // Normalization uses OS on Win8
- if (!Environment.IsWindows8OrAbove)
+ if (GlobalizationMode.Invariant)
{
- if (strDataFile == null)
- {
- // They were supposed to have a form that we know about!
- throw new ArgumentException(
- Environment.GetResourceString("Argument_InvalidNormalizationForm"));
- }
-
- // Tell the DLL where to find our data
- pTables = GlobalizationAssembly.GetGlobalizationResourceBytePtr(
- typeof(Normalization).Assembly, strDataFile);
- if (pTables == null)
- {
- // Unable to load the specified normalizationForm,
- // tables not loaded from file
- throw new ArgumentException(
- Environment.GetResourceString("Argument_InvalidNormalizationForm"));
- }
+ // In Invariant mode we assume all characters are normalized.
+ // This is because we don't support any linguistic operation on the strings
+ return true;
}
- nativeNormalizationInitNormalization(form, pTables);
- }
-
- static private void EnsureInitialized(NormalizationForm form)
- {
- switch ((ExtendedNormalizationForms)form)
- {
- case ExtendedNormalizationForms.FormC:
- if (NFC) return;
- InitializeForm(form, "normnfc.nlp");
- NFC = true;
- break;
-
- case ExtendedNormalizationForms.FormD:
- if (NFD) return;
- InitializeForm(form, "normnfd.nlp");
- NFD = true;
- break;
-
- case ExtendedNormalizationForms.FormKC:
- if (NFKC) return;
- InitializeForm(form, "normnfkc.nlp");
- NFKC = true;
- break;
-
- case ExtendedNormalizationForms.FormKD:
- if (NFKD) return;
- InitializeForm(form, "normnfkd.nlp");
- NFKD = true;
- break;
-
- case ExtendedNormalizationForms.FormIdna:
- if (IDNA) return;
- InitializeForm(form, "normidna.nlp");
- IDNA = true;
- break;
-
- case ExtendedNormalizationForms.FormCDisallowUnassigned:
- if (NFCDisallowUnassigned) return;
- InitializeForm(form, "normnfc.nlp");
- NFCDisallowUnassigned = true;
- break;
+ Debug.Assert(strInput != null);
- case ExtendedNormalizationForms.FormDDisallowUnassigned:
- if (NFDDisallowUnassigned) return;
- InitializeForm(form, "normnfd.nlp");
- NFDDisallowUnassigned = true;
- break;
+ // The only way to know if IsNormalizedString failed is through checking the Win32 last error
+ // IsNormalizedString pinvoke has SetLastError attribute property which will set the last error
+ // to 0 (ERROR_SUCCESS) before executing the calls.
+ bool result = Interop.Normaliz.IsNormalizedString((int)normForm, strInput, strInput.Length);
- case ExtendedNormalizationForms.FormKCDisallowUnassigned:
- if (NFKCDisallowUnassigned) return;
- InitializeForm(form, "normnfkc.nlp");
- NFKCDisallowUnassigned = true;
+ int lastError = Marshal.GetLastWin32Error();
+ switch (lastError)
+ {
+ case Interop.Errors.ERROR_SUCCESS:
break;
- case ExtendedNormalizationForms.FormKDDisallowUnassigned:
- if (NFKDDisallowUnassigned) return;
- InitializeForm(form, "normnfkd.nlp");
- NFKDDisallowUnassigned = true;
- break;
+ case Interop.Errors.ERROR_INVALID_PARAMETER:
+ case Interop.Errors.ERROR_NO_UNICODE_TRANSLATION:
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(strInput));
- case ExtendedNormalizationForms.FormIdnaDisallowUnassigned:
- if (IDNADisallowUnassigned) return;
- InitializeForm(form, "normidna.nlp");
- IDNADisallowUnassigned = true;
- break;
+ case Interop.Errors.ERROR_NOT_ENOUGH_MEMORY:
+ throw new OutOfMemoryException();
default:
- if (Other) return;
- InitializeForm(form, null);
- Other = true;
- break;
- }
- }
-
- internal static bool IsNormalized(String strInput, NormalizationForm normForm)
- {
- Contract.Requires(strInput != null);
-
- EnsureInitialized(normForm);
-
- int iError = ERROR_SUCCESS;
- bool result = nativeNormalizationIsNormalizedString(
- normForm,
- ref iError,
- strInput,
- strInput.Length);
-
- switch(iError)
- {
- // Success doesn't need to do anything
- case ERROR_SUCCESS:
- break;
-
- // Do appropriate stuff for the individual errors:
- case ERROR_INVALID_PARAMETER:
- case ERROR_NO_UNICODE_TRANSLATION:
- throw new ArgumentException(
- Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex" ),
- nameof(strInput));
- case ERROR_NOT_ENOUGH_MEMORY:
- throw new OutOfMemoryException(
- Environment.GetResourceString("Arg_OutOfMemoryException"));
- default:
- throw new InvalidOperationException(
- Environment.GetResourceString("UnknownError_Num", iError));
+ throw new InvalidOperationException(SR.Format(SR.UnknownError_Num, lastError));
}
return result;
@@ -179,37 +56,41 @@ namespace System.Text
internal static String Normalize(String strInput, NormalizationForm normForm)
{
- Contract.Requires(strInput != null);
+ if (GlobalizationMode.Invariant)
+ {
+ // In Invariant mode we assume all characters are normalized.
+ // This is because we don't support any linguistic operation on the strings
+ return strInput;
+ }
- EnsureInitialized(normForm);
+ Debug.Assert(strInput != null);
- int iError = ERROR_SUCCESS;
+ // we depend on Win32 last error when calling NormalizeString
+ // NormalizeString pinvoke has SetLastError attribute property which will set the last error
+ // to 0 (ERROR_SUCCESS) before executing the calls.
// Guess our buffer size first
- int iLength = nativeNormalizationNormalizeString(normForm, ref iError, strInput, strInput.Length, null, 0);
+ int iLength = Interop.Normaliz.NormalizeString((int)normForm, strInput, strInput.Length, null, 0);
+ int lastError = Marshal.GetLastWin32Error();
// Could have an error (actually it'd be quite hard to have an error here)
- if (iError != ERROR_SUCCESS)
+ if ((lastError != Interop.Errors.ERROR_SUCCESS) || iLength < 0)
{
- if (iError == ERROR_INVALID_PARAMETER)
- throw new ArgumentException(
- Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex" ),
- nameof(strInput));
+ if (lastError == Interop.Errors.ERROR_INVALID_PARAMETER)
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(strInput));
// We shouldn't really be able to get here..., guessing length is
// a trivial math function...
// Can't really be Out of Memory, but just in case:
- if (iError == ERROR_NOT_ENOUGH_MEMORY)
- throw new OutOfMemoryException(
- Environment.GetResourceString("Arg_OutOfMemoryException"));
+ if (lastError == Interop.Errors.ERROR_NOT_ENOUGH_MEMORY)
+ throw new OutOfMemoryException();
// Who knows what happened? Not us!
- throw new InvalidOperationException(
- Environment.GetResourceString("UnknownError_Num", iError));
+ throw new InvalidOperationException(SR.Format(SR.UnknownError_Num, lastError));
}
// Don't break for empty strings (only possible for D & KD and not really possible at that)
- if (iLength == 0) return String.Empty;
+ if (iLength == 0) return string.Empty;
// Someplace to stick our buffer
char[] cBuffer = null;
@@ -219,60 +100,39 @@ namespace System.Text
// (re)allocation buffer and normalize string
cBuffer = new char[iLength];
- iLength = nativeNormalizationNormalizeString(
- normForm,
- ref iError,
- strInput,
- strInput.Length,
- cBuffer,
- cBuffer.Length);
-
- if (iError == ERROR_SUCCESS)
+ // NormalizeString pinvoke has SetLastError attribute property which will set the last error
+ // to 0 (ERROR_SUCCESS) before executing the calls.
+ iLength = Interop.Normaliz.NormalizeString((int)normForm, strInput, strInput.Length, cBuffer, cBuffer.Length);
+ lastError = Marshal.GetLastWin32Error();
+
+ if (lastError == Interop.Errors.ERROR_SUCCESS)
break;
// Could have an error (actually it'd be quite hard to have an error here)
- switch(iError)
+ switch (lastError)
{
// Do appropriate stuff for the individual errors:
- case ERROR_INSUFFICIENT_BUFFER:
+ case Interop.Errors.ERROR_INSUFFICIENT_BUFFER:
+ iLength = Math.Abs(iLength);
Debug.Assert(iLength > cBuffer.Length, "Buffer overflow should have iLength > cBuffer.Length");
continue;
- case ERROR_INVALID_PARAMETER:
- case ERROR_NO_UNICODE_TRANSLATION:
+ case Interop.Errors.ERROR_INVALID_PARAMETER:
+ case Interop.Errors.ERROR_NO_UNICODE_TRANSLATION:
// Illegal code point or order found. Ie: FFFE or D800 D800, etc.
- throw new ArgumentException(
- Environment.GetResourceString("Argument_InvalidCharSequence", iLength ),
- nameof(strInput));
- case ERROR_NOT_ENOUGH_MEMORY:
- throw new OutOfMemoryException(
- Environment.GetResourceString("Arg_OutOfMemoryException"));
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(strInput));
+
+ case Interop.Errors.ERROR_NOT_ENOUGH_MEMORY:
+ throw new OutOfMemoryException();
default:
// We shouldn't get here...
- throw new InvalidOperationException(
- Environment.GetResourceString("UnknownError_Num", iError));
+ throw new InvalidOperationException(SR.Format(SR.UnknownError_Num, lastError));
}
}
// Copy our buffer into our new string, which will be the appropriate size
- return new String(cBuffer, 0, iLength);
+ return new string(cBuffer, 0, iLength);
}
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe private static extern int nativeNormalizationNormalizeString(
- NormalizationForm normForm, ref int iError,
- String lpSrcString, int cwSrcLength,
- char[] lpDstString, int cwDstLength);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe private static extern bool nativeNormalizationIsNormalizedString(
- NormalizationForm normForm, ref int iError,
- String lpString, int cwLength);
-
- [SuppressUnmanagedCodeSecurity]
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- unsafe private static extern void nativeNormalizationInitNormalization(
- NormalizationForm normForm, byte* pTableData);
}
}
diff --git a/src/mscorlib/src/System/Text/Normalization.cs b/src/mscorlib/src/System/Text/Normalization.cs
deleted file mode 100644
index c81149d59a..0000000000
--- a/src/mscorlib/src/System/Text/Normalization.cs
+++ /dev/null
@@ -1,29 +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.
-
-namespace System.Text
-{
- // This is the enumeration for Normalization Forms
- public enum NormalizationForm
- {
- FormC = 1,
- FormD = 2,
- FormKC = 5,
- FormKD = 6
- }
-
- internal enum ExtendedNormalizationForms
- {
- FormC = 1,
- FormD = 2,
- FormKC = 5,
- FormKD = 6,
- FormIdna = 0xd,
- FormCDisallowUnassigned = 0x101,
- FormDDisallowUnassigned = 0x102,
- FormKCDisallowUnassigned = 0x105,
- FormKDDisallowUnassigned = 0x106,
- FormIdnaDisallowUnassigned = 0x10d
- }
-}
diff --git a/src/mscorlib/src/System/Text/StringBuilder.CoreCLR.cs b/src/mscorlib/src/System/Text/StringBuilder.CoreCLR.cs
new file mode 100644
index 0000000000..db3895f161
--- /dev/null
+++ b/src/mscorlib/src/System/Text/StringBuilder.CoreCLR.cs
@@ -0,0 +1,48 @@
+// 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.Runtime.CompilerServices;
+
+namespace System.Text
+{
+ public partial class StringBuilder
+ {
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal unsafe extern void ReplaceBufferInternal(char* newBuffer, int newLength);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal unsafe extern void ReplaceBufferAnsiInternal(sbyte* newBuffer, int newLength);
+
+ // Copies the source StringBuilder to the destination IntPtr memory allocated with len bytes.
+ internal unsafe void InternalCopy(IntPtr dest, int len)
+ {
+ if (len == 0)
+ return;
+
+ bool isLastChunk = true;
+ byte* dstPtr = (byte*)dest.ToPointer();
+ StringBuilder currentSrc = FindChunkForByte(len);
+
+ do
+ {
+ int chunkOffsetInBytes = currentSrc.m_ChunkOffset * sizeof(char);
+ int chunkLengthInBytes = currentSrc.m_ChunkLength * sizeof(char);
+ fixed (char* charPtr = &currentSrc.m_ChunkChars[0])
+ {
+ byte* srcPtr = (byte*)charPtr;
+ if (isLastChunk)
+ {
+ isLastChunk = false;
+ Buffer.Memcpy(dstPtr + chunkOffsetInBytes, srcPtr, len - chunkOffsetInBytes);
+ }
+ else
+ {
+ Buffer.Memcpy(dstPtr + chunkOffsetInBytes, srcPtr, chunkLengthInBytes);
+ }
+ }
+ currentSrc = currentSrc.m_ChunkPrevious;
+ } while (currentSrc != null);
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Text/StringBuilder.cs b/src/mscorlib/src/System/Text/StringBuilder.cs
deleted file mode 100644
index 72247c333e..0000000000
--- a/src/mscorlib/src/System/Text/StringBuilder.cs
+++ /dev/null
@@ -1,2286 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose: implementation of the StringBuilder
-** class.
-**
-===========================================================*/
-namespace System.Text {
- using System.Text;
- using System.Runtime;
- using System.Runtime.Serialization;
- using System;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Security;
- using System.Threading;
- using System.Globalization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Collections.Generic;
-
- // This class represents a mutable string. It is convenient for situations in
- // which it is desirable to modify a string, perhaps by removing, replacing, or
- // inserting characters, without creating a new String subsequent to
- // each modification.
- //
- // The methods contained within this class do not return a new StringBuilder
- // object unless specified otherwise. This class may be used in conjunction with the String
- // class to carry out modifications upon strings.
- //
- // When passing null into a constructor in VJ and VC, the null
- // should be explicitly type cast.
- // For Example:
- // StringBuilder sb1 = new StringBuilder((StringBuilder)null);
- // StringBuilder sb2 = new StringBuilder((String)null);
- // Console.WriteLine(sb1);
- // Console.WriteLine(sb2);
- //
- [Serializable]
- public sealed class StringBuilder : ISerializable
- {
- // A StringBuilder is internally represented as a linked list of blocks each of which holds
- // a chunk of the string. It turns out string as a whole can also be represented as just a chunk,
- // so that is what we do.
-
- //
- //
- // CLASS VARIABLES
- //
- //
- internal char[] m_ChunkChars; // The characters in this block
- internal StringBuilder m_ChunkPrevious; // Link to the block logically before this block
- internal int m_ChunkLength; // The index in m_ChunkChars that represent the end of the block
- internal int m_ChunkOffset; // The logical offset (sum of all characters in previous blocks)
- internal int m_MaxCapacity = 0;
-
- //
- //
- // STATIC CONSTANTS
- //
- //
- internal const int DefaultCapacity = 16;
- private const String CapacityField = "Capacity";
- private const String MaxCapacityField = "m_MaxCapacity";
- private const String StringValueField = "m_StringValue";
- private const String ThreadIDField = "m_currentThread";
- // We want to keep chunk arrays out of large object heap (< 85K bytes ~ 40K chars) to be sure.
- // Making the maximum chunk size big means less allocation code called, but also more waste
- // in unused characters and slower inserts / replaces (since you do need to slide characters over
- // within a buffer).
- internal const int MaxChunkSize = 8000;
-
- //
- //
- //CONSTRUCTORS
- //
- //
-
- // Creates a new empty string builder (i.e., it represents String.Empty)
- // with the default capacity (16 characters).
- public StringBuilder()
- {
- m_MaxCapacity = int.MaxValue;
- m_ChunkChars = new char[DefaultCapacity];
- }
-
- // Create a new empty string builder (i.e., it represents String.Empty)
- // with the specified capacity.
- public StringBuilder(int capacity)
- : this(capacity, int.MaxValue)
- {
- }
-
- // Creates a new string builder from the specified string. If value
- // is a null String (i.e., if it represents String.NullString)
- // then the new string builder will also be null (i.e., it will also represent
- // String.NullString).
- //
- public StringBuilder(String value)
- : this(value, DefaultCapacity) {
- }
-
- // Creates a new string builder from the specified string with the specified
- // capacity. If value is a null String (i.e., if it represents
- // String.NullString) then the new string builder will also be null
- // (i.e., it will also represent String.NullString).
- // The maximum number of characters this string may contain is set by capacity.
- //
- public StringBuilder(String value, int capacity)
- : this(value, 0, ((value != null) ? value.Length : 0), capacity) {
- }
-
- // Creates a new string builder from the specifed substring with the specified
- // capacity. The maximum number of characters is set by capacity.
- //
- public StringBuilder(String value, int startIndex, int length, int capacity) {
- if (capacity<0) {
- throw new ArgumentOutOfRangeException(nameof(capacity),
- Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", nameof(capacity)));
- }
- if (length<0) {
- throw new ArgumentOutOfRangeException(nameof(length),
- Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", nameof(length)));
- }
- if (startIndex<0) {
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
- }
- Contract.EndContractBlock();
-
- if (value == null) {
- value = String.Empty;
- }
- if (startIndex > value.Length - length) {
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_IndexLength"));
- }
- m_MaxCapacity = Int32.MaxValue;
- if (capacity == 0) {
- capacity = DefaultCapacity;
- }
- if (capacity < length)
- capacity = length;
-
- m_ChunkChars = new char[capacity];
- m_ChunkLength = length;
-
- unsafe {
- fixed (char* sourcePtr = value)
- ThreadSafeCopy(sourcePtr + startIndex, m_ChunkChars, 0, length);
- }
- }
-
- // Creates an empty StringBuilder with a minimum capacity of capacity
- // and a maximum capacity of maxCapacity.
- public StringBuilder(int capacity, int maxCapacity) {
- if (capacity>maxCapacity) {
- throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_Capacity"));
- }
- if (maxCapacity<1) {
- throw new ArgumentOutOfRangeException(nameof(maxCapacity), Environment.GetResourceString("ArgumentOutOfRange_SmallMaxCapacity"));
- }
- if (capacity<0) {
- throw new ArgumentOutOfRangeException(nameof(capacity),
- Environment.GetResourceString("ArgumentOutOfRange_MustBePositive", nameof(capacity)));
- }
- Contract.EndContractBlock();
-
- if (capacity == 0) {
- capacity = Math.Min(DefaultCapacity, maxCapacity);
- }
-
- m_MaxCapacity = maxCapacity;
- m_ChunkChars = new char[capacity];
- }
-
- private StringBuilder(SerializationInfo info, StreamingContext context) {
- if (info == null)
- throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- int persistedCapacity = 0;
- string persistedString = null;
- int persistedMaxCapacity = Int32.MaxValue;
- bool capacityPresent = false;
-
- // Get the data
- SerializationInfoEnumerator enumerator = info.GetEnumerator();
- while (enumerator.MoveNext()) {
- switch (enumerator.Name) {
- case MaxCapacityField:
- persistedMaxCapacity = info.GetInt32(MaxCapacityField);
- break;
- case StringValueField:
- persistedString = info.GetString(StringValueField);
- break;
- case CapacityField:
- persistedCapacity = info.GetInt32(CapacityField);
- capacityPresent = true;
- break;
- default:
- // Ignore other fields for forward compatibility.
- break;
- }
-
- }
-
- // Check values and set defaults
- if (persistedString == null) {
- persistedString = String.Empty;
- }
- if (persistedMaxCapacity < 1 || persistedString.Length > persistedMaxCapacity) {
- throw new SerializationException(Environment.GetResourceString("Serialization_StringBuilderMaxCapacity"));
- }
-
- if (!capacityPresent) {
- // StringBuilder in V1.X did not persist the Capacity, so this is a valid legacy code path.
- persistedCapacity = DefaultCapacity;
- if (persistedCapacity < persistedString.Length) {
- persistedCapacity = persistedString.Length;
- }
- if (persistedCapacity > persistedMaxCapacity) {
- persistedCapacity = persistedMaxCapacity;
- }
- }
- if (persistedCapacity < 0 || persistedCapacity < persistedString.Length || persistedCapacity > persistedMaxCapacity) {
- throw new SerializationException(Environment.GetResourceString("Serialization_StringBuilderCapacity"));
- }
-
- // Assign
- m_MaxCapacity = persistedMaxCapacity;
- m_ChunkChars = new char[persistedCapacity];
- persistedString.CopyTo(0, m_ChunkChars, 0, persistedString.Length);
- m_ChunkLength = persistedString.Length;
- m_ChunkPrevious = null;
- VerifyClassInvariant();
- }
-
- void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
- {
- if (info==null) {
- throw new ArgumentNullException(nameof(info));
- }
- Contract.EndContractBlock();
-
- VerifyClassInvariant();
- info.AddValue(MaxCapacityField, m_MaxCapacity);
- info.AddValue(CapacityField, Capacity);
- info.AddValue(StringValueField, ToString());
- // Note: persist "m_currentThread" to be compatible with old versions
- info.AddValue(ThreadIDField, 0);
- }
-
- [System.Diagnostics.Conditional("_DEBUG")]
- private void VerifyClassInvariant() {
- BCLDebug.Correctness((uint)(m_ChunkOffset + m_ChunkChars.Length) >= m_ChunkOffset, "Integer Overflow");
- StringBuilder currentBlock = this;
- int maxCapacity = this.m_MaxCapacity;
- for (; ; )
- {
- // All blocks have copy of the maxCapacity.
- Debug.Assert(currentBlock.m_MaxCapacity == maxCapacity, "Bad maxCapacity");
- Debug.Assert(currentBlock.m_ChunkChars != null, "Empty Buffer");
-
- Debug.Assert(currentBlock.m_ChunkLength <= currentBlock.m_ChunkChars.Length, "Out of range length");
- Debug.Assert(currentBlock.m_ChunkLength >= 0, "Negative length");
- Debug.Assert(currentBlock.m_ChunkOffset >= 0, "Negative offset");
-
- StringBuilder prevBlock = currentBlock.m_ChunkPrevious;
- if (prevBlock == null)
- {
- Debug.Assert(currentBlock.m_ChunkOffset == 0, "First chunk's offset is not 0");
- break;
- }
- // There are no gaps in the blocks.
- Debug.Assert(currentBlock.m_ChunkOffset == prevBlock.m_ChunkOffset + prevBlock.m_ChunkLength, "There is a gap between chunks!");
- currentBlock = prevBlock;
- }
- }
-
- public int Capacity {
- get { return m_ChunkChars.Length + m_ChunkOffset; }
- set {
- if (value < 0) {
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_NegativeCapacity"));
- }
- if (value > MaxCapacity) {
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_Capacity"));
- }
- if (value < Length) {
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
- }
- Contract.EndContractBlock();
-
- if (Capacity != value) {
- int newLen = value - m_ChunkOffset;
- char[] newArray = new char[newLen];
- Array.Copy(m_ChunkChars, newArray, m_ChunkLength);
- m_ChunkChars = newArray;
- }
- }
- }
-
- public int MaxCapacity {
- get { return m_MaxCapacity; }
- }
-
- // Read-Only Property
- // Ensures that the capacity of this string builder is at least the specified value.
- // If capacity is greater than the capacity of this string builder, then the capacity
- // is set to capacity; otherwise the capacity is unchanged.
- //
- public int EnsureCapacity(int capacity) {
- if (capacity < 0) {
- throw new ArgumentOutOfRangeException(nameof(capacity), Environment.GetResourceString("ArgumentOutOfRange_NegativeCapacity"));
- }
- Contract.EndContractBlock();
-
- if (Capacity < capacity)
- Capacity = capacity;
- return Capacity;
- }
-
- public override String ToString() {
- Contract.Ensures(Contract.Result<String>() != null);
-
- VerifyClassInvariant();
-
- if (Length == 0)
- return String.Empty;
-
- string ret = string.FastAllocateString(Length);
- StringBuilder chunk = this;
- unsafe {
- fixed (char* destinationPtr = ret)
- {
- do
- {
- if (chunk.m_ChunkLength > 0)
- {
- // Copy these into local variables so that they are stable even in the presence of race conditions
- char[] sourceArray = chunk.m_ChunkChars;
- int chunkOffset = chunk.m_ChunkOffset;
- int chunkLength = chunk.m_ChunkLength;
-
- // Check that we will not overrun our boundaries.
- if ((uint)(chunkLength + chunkOffset) <= (uint)ret.Length && (uint)chunkLength <= (uint)sourceArray.Length)
- {
- fixed (char* sourcePtr = &sourceArray[0])
- string.wstrcpy(destinationPtr + chunkOffset, sourcePtr, chunkLength);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(chunkLength), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- }
- chunk = chunk.m_ChunkPrevious;
- } while (chunk != null);
-
- return ret;
- }
- }
- }
-
-
- // Converts a substring of this string builder to a String.
- public String ToString(int startIndex, int length) {
- Contract.Ensures(Contract.Result<String>() != null);
-
- int currentLength = this.Length;
- if (startIndex < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
- }
- if (startIndex > currentLength)
- {
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndexLargerThanLength"));
- }
- if (length < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
- }
- if (startIndex > (currentLength - length))
- {
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_IndexLength"));
- }
-
- VerifyClassInvariant();
-
- StringBuilder chunk = this;
- int sourceEndIndex = startIndex + length;
-
- string ret = string.FastAllocateString(length);
- int curDestIndex = length;
- unsafe {
- fixed (char* destinationPtr = ret)
- {
- while (curDestIndex > 0)
- {
- int chunkEndIndex = sourceEndIndex - chunk.m_ChunkOffset;
- if (chunkEndIndex >= 0)
- {
- if (chunkEndIndex > chunk.m_ChunkLength)
- chunkEndIndex = chunk.m_ChunkLength;
-
- int countLeft = curDestIndex;
- int chunkCount = countLeft;
- int chunkStartIndex = chunkEndIndex - countLeft;
- if (chunkStartIndex < 0)
- {
- chunkCount += chunkStartIndex;
- chunkStartIndex = 0;
- }
- curDestIndex -= chunkCount;
-
- if (chunkCount > 0)
- {
- // work off of local variables so that they are stable even in the presence of race conditions
- char[] sourceArray = chunk.m_ChunkChars;
-
- // Check that we will not overrun our boundaries.
- if ((uint)(chunkCount + curDestIndex) <= (uint)length && (uint)(chunkCount + chunkStartIndex) <= (uint)sourceArray.Length)
- {
- fixed (char* sourcePtr = &sourceArray[chunkStartIndex])
- string.wstrcpy(destinationPtr + curDestIndex, sourcePtr, chunkCount);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(chunkCount), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- }
- }
- chunk = chunk.m_ChunkPrevious;
- }
-
- return ret;
- }
- }
- }
-
- // Convenience method for sb.Length=0;
- public StringBuilder Clear() {
- this.Length = 0;
- return this;
- }
-
- // Sets the length of the String in this buffer. If length is less than the current
- // instance, the StringBuilder is truncated. If length is greater than the current
- // instance, nulls are appended. The capacity is adjusted to be the same as the length.
-
- public int Length {
- get {
- Contract.Ensures(Contract.Result<int>() >= 0);
- return m_ChunkOffset + m_ChunkLength;
- }
- set {
- //If the new length is less than 0 or greater than our Maximum capacity, bail.
- if (value<0) {
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
- }
-
- if (value>MaxCapacity) {
- throw new ArgumentOutOfRangeException(nameof(value), Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
- }
- Contract.EndContractBlock();
-
- int originalCapacity = Capacity;
-
- if (value == 0 && m_ChunkPrevious == null)
- {
- m_ChunkLength = 0;
- m_ChunkOffset = 0;
- Debug.Assert(Capacity >= originalCapacity, "setting the Length should never decrease the Capacity");
- return;
- }
-
- int delta = value - Length;
- // if the specified length is greater than the current length
- if (delta > 0)
- {
- // the end of the string value of the current StringBuilder object is padded with the Unicode NULL character
- Append('\0', delta); // We could improve on this, but who does this anyway?
- }
- // if the specified length is less than or equal to the current length
- else
- {
- StringBuilder chunk = FindChunkForIndex(value);
- if (chunk != this)
- {
- // we crossed a chunk boundary when reducing the Length, we must replace this middle-chunk with a new
- // larger chunk to ensure the original capacity is preserved
- int newLen = originalCapacity - chunk.m_ChunkOffset;
- char[] newArray = new char[newLen];
-
- Debug.Assert(newLen > chunk.m_ChunkChars.Length, "the new chunk should be larger than the one it is replacing");
- Array.Copy(chunk.m_ChunkChars, newArray, chunk.m_ChunkLength);
-
- m_ChunkChars = newArray;
- m_ChunkPrevious = chunk.m_ChunkPrevious;
- m_ChunkOffset = chunk.m_ChunkOffset;
- }
- m_ChunkLength = value - chunk.m_ChunkOffset;
- VerifyClassInvariant();
- }
- Debug.Assert(Capacity >= originalCapacity, "setting the Length should never decrease the Capacity");
- }
- }
-
- [System.Runtime.CompilerServices.IndexerName("Chars")]
- public char this[int index] {
- get {
- StringBuilder chunk = this;
- for (; ; )
- {
- int indexInBlock = index - chunk.m_ChunkOffset;
- if (indexInBlock >= 0)
- {
- if (indexInBlock >= chunk.m_ChunkLength)
- throw new IndexOutOfRangeException();
- return chunk.m_ChunkChars[indexInBlock];
- }
- chunk = chunk.m_ChunkPrevious;
- if (chunk == null)
- throw new IndexOutOfRangeException();
- }
- }
- set {
- StringBuilder chunk = this;
- for (; ; )
- {
- int indexInBlock = index - chunk.m_ChunkOffset;
- if (indexInBlock >= 0)
- {
- if (indexInBlock >= chunk.m_ChunkLength)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- chunk.m_ChunkChars[indexInBlock] = value;
- return;
- }
- chunk = chunk.m_ChunkPrevious;
- if (chunk == null)
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- }
- }
-
- // Appends a character at the end of this string builder. The capacity is adjusted as needed.
- public StringBuilder Append(char value, int repeatCount) {
- if (repeatCount<0) {
- throw new ArgumentOutOfRangeException(nameof(repeatCount), Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
- }
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- Contract.EndContractBlock();
-
- if (repeatCount==0) {
- return this;
- }
-
- // this is where we can check if the repeatCount will put us over m_MaxCapacity
- // We are doing the check here to prevent the corruption of the StringBuilder.
- int newLength = Length + repeatCount;
- if (newLength > m_MaxCapacity || newLength < repeatCount) {
- throw new ArgumentOutOfRangeException(nameof(repeatCount), Environment.GetResourceString("ArgumentOutOfRange_LengthGreaterThanCapacity"));
- }
-
- int idx = m_ChunkLength;
- while (repeatCount > 0)
- {
- if (idx < m_ChunkChars.Length)
- {
- m_ChunkChars[idx++] = value;
- --repeatCount;
- }
- else
- {
- m_ChunkLength = idx;
- ExpandByABlock(repeatCount);
- Debug.Assert(m_ChunkLength == 0, "Expand should create a new block");
- idx = 0;
- }
- }
- m_ChunkLength = idx;
- VerifyClassInvariant();
- return this;
- }
-
- // Appends an array of characters at the end of this string builder. The capacity is adjusted as needed.
- public StringBuilder Append(char[] value, int startIndex, int charCount) {
- if (startIndex < 0) {
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
- }
- if (charCount<0) {
- throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
- }
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- Contract.EndContractBlock();
-
- if (value == null) {
- if (startIndex == 0 && charCount == 0) {
- return this;
- }
- throw new ArgumentNullException(nameof(value));
- }
- if (charCount > value.Length - startIndex) {
- throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
-
- if (charCount==0) {
- return this;
- }
- unsafe
- {
- fixed (char* valueChars = &value[startIndex])
- {
- Append(valueChars, charCount);
-
- return this;
- }
- }
- }
-
-
- // Appends a copy of this string at the end of this string builder.
- public StringBuilder Append(String value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
-
- if (value != null) {
- // This is a hand specialization of the 'AppendHelper' code below.
- // We could have just called AppendHelper.
- char[] chunkChars = m_ChunkChars;
- int chunkLength = m_ChunkLength;
- int valueLen = value.Length;
- int newCurrentIndex = chunkLength + valueLen;
- if (newCurrentIndex < chunkChars.Length) // Use strictly < to avoid issue if count == 0, newIndex == length
- {
- if (valueLen <= 2)
- {
- if (valueLen > 0)
- chunkChars[chunkLength] = value[0];
- if (valueLen > 1)
- chunkChars[chunkLength + 1] = value[1];
- }
- else
- {
- unsafe {
- fixed (char* valuePtr = value)
- fixed (char* destPtr = &chunkChars[chunkLength])
- string.wstrcpy(destPtr, valuePtr, valueLen);
- }
- }
- m_ChunkLength = newCurrentIndex;
- }
- else
- AppendHelper(value);
- }
- return this;
- }
-
-
- // We put this fixed in its own helper to avoid the cost zero initing valueChars in the
- // case we don't actually use it.
- private void AppendHelper(string value) {
- unsafe {
- fixed (char* valueChars = value)
- Append(valueChars, value.Length);
- }
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal unsafe extern void ReplaceBufferInternal(char* newBuffer, int newLength);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal unsafe extern void ReplaceBufferAnsiInternal(sbyte* newBuffer, int newLength);
-
- // Appends a copy of the characters in value from startIndex to startIndex +
- // count at the end of this string builder.
- public StringBuilder Append(String value, int startIndex, int count) {
- if (startIndex < 0) {
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
-
- if (count < 0) {
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
- }
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
-
- //If the value being added is null, eat the null
- //and return.
- if (value == null) {
- if (startIndex == 0 && count == 0) {
- return this;
- }
- throw new ArgumentNullException(nameof(value));
- }
-
- if (count == 0) {
- return this;
- }
-
- if (startIndex > value.Length - count) {
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
-
- unsafe
- {
- fixed (char* valueChars = value)
- {
- Append(valueChars + startIndex, count);
-
- return this;
- }
- }
- }
-
- public StringBuilder AppendLine() {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Append(Environment.NewLine);
- }
-
- public StringBuilder AppendLine(string value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- Append(value);
- return Append(Environment.NewLine);
- }
-
- public void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count) {
- if (destination == null) {
- throw new ArgumentNullException(nameof(destination));
- }
-
- if (count < 0) {
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("Arg_NegativeArgCount"));
- }
-
- if (destinationIndex < 0) {
- throw new ArgumentOutOfRangeException(nameof(destinationIndex),
- Environment.GetResourceString("ArgumentOutOfRange_MustBeNonNegNum", nameof(destinationIndex)));
- }
-
- if (destinationIndex > destination.Length - count) {
- throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_OffsetOut"));
- }
-
- if ((uint)sourceIndex > (uint)Length) {
- throw new ArgumentOutOfRangeException(nameof(sourceIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
-
- if (sourceIndex > Length - count) {
- throw new ArgumentException(Environment.GetResourceString("Arg_LongerThanSrcString"));
- }
- Contract.EndContractBlock();
-
- VerifyClassInvariant();
-
- StringBuilder chunk = this;
- int sourceEndIndex = sourceIndex + count;
- int curDestIndex = destinationIndex + count;
- while (count > 0)
- {
- int chunkEndIndex = sourceEndIndex - chunk.m_ChunkOffset;
- if (chunkEndIndex >= 0)
- {
- if (chunkEndIndex > chunk.m_ChunkLength)
- chunkEndIndex = chunk.m_ChunkLength;
-
- int chunkCount = count;
- int chunkStartIndex = chunkEndIndex - count;
- if (chunkStartIndex < 0)
- {
- chunkCount += chunkStartIndex;
- chunkStartIndex = 0;
- }
- curDestIndex -= chunkCount;
- count -= chunkCount;
-
- // SafeCritical: we ensure that chunkStartIndex + chunkCount are within range of m_chunkChars
- // as well as ensuring that curDestIndex + chunkCount are within range of destination
- ThreadSafeCopy(chunk.m_ChunkChars, chunkStartIndex, destination, curDestIndex, chunkCount);
- }
- chunk = chunk.m_ChunkPrevious;
- }
- }
-
- // Inserts multiple copies of a string into this string builder at the specified position.
- // Existing characters are shifted to make room for the new text.
- // The capacity is adjusted as needed. If value equals String.Empty, this
- // string builder is not changed.
- //
- public StringBuilder Insert(int index, String value, int count) {
- if (count < 0) {
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- }
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- Contract.EndContractBlock();
-
- //Range check the index.
- int currentLength = Length;
- if ((uint)index > (uint)currentLength) {
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
-
- //If value is null, empty or count is 0, do nothing. This is ECMA standard.
- if (value == null || value.Length == 0 || count == 0) {
- return this;
- }
-
- //Ensure we don't insert more chars than we can hold, and we don't
- //have any integer overflow in our inserted characters.
- long insertingChars = (long) value.Length * count;
- if (insertingChars > MaxCapacity - this.Length) {
- throw new OutOfMemoryException();
- }
- Debug.Assert(insertingChars + this.Length < Int32.MaxValue);
-
- StringBuilder chunk;
- int indexInChunk;
- MakeRoom(index, (int) insertingChars, out chunk, out indexInChunk, false);
- unsafe {
- fixed (char* valuePtr = value) {
- while (count > 0)
- {
- ReplaceInPlaceAtChunk(ref chunk, ref indexInChunk, valuePtr, value.Length);
- --count;
- }
-
- return this;
- }
- }
- }
-
- // Removes the specified characters from this string builder.
- // The length of this string builder is reduced by
- // length, but the capacity is unaffected.
- //
- public StringBuilder Remove(int startIndex, int length) {
- if (length<0) {
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
- }
-
- if (startIndex<0) {
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
- }
-
- if (length > Length - startIndex) {
- throw new ArgumentOutOfRangeException(nameof(length), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- Contract.EndContractBlock();
-
- if (Length == length && startIndex == 0) {
- // Optimization. If we are deleting everything
- Length = 0;
- return this;
- }
-
- if (length > 0)
- {
- StringBuilder chunk;
- int indexInChunk;
- Remove(startIndex, length, out chunk, out indexInChunk);
- }
- return this;
- }
-
- //
- // PUBLIC INSTANCE FUNCTIONS
- //
- //
-
- /*====================================Append====================================
- **
- ==============================================================================*/
- // Appends a boolean to the end of this string builder.
- // The capacity is adjusted as needed.
- public StringBuilder Append(bool value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Append(value.ToString());
- }
-
- // Appends an sbyte to this string builder.
- // The capacity is adjusted as needed.
- [CLSCompliant(false)]
- public StringBuilder Append(sbyte value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Append(value.ToString(CultureInfo.CurrentCulture));
- }
-
- // Appends a ubyte to this string builder.
- // The capacity is adjusted as needed.
- public StringBuilder Append(byte value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Append(value.ToString(CultureInfo.CurrentCulture));
- }
-
- // Appends a character at the end of this string builder. The capacity is adjusted as needed.
- public StringBuilder Append(char value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
-
- if (m_ChunkLength < m_ChunkChars.Length)
- m_ChunkChars[m_ChunkLength++] = value;
- else
- Append(value, 1);
- return this;
- }
-
- // Appends a short to this string builder.
- // The capacity is adjusted as needed.
- public StringBuilder Append(short value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Append(value.ToString(CultureInfo.CurrentCulture));
- }
-
- // Appends an int to this string builder.
- // The capacity is adjusted as needed.
- public StringBuilder Append(int value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Append(value.ToString(CultureInfo.CurrentCulture));
- }
-
- // Appends a long to this string builder.
- // The capacity is adjusted as needed.
- public StringBuilder Append(long value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Append(value.ToString(CultureInfo.CurrentCulture));
- }
-
- // Appends a float to this string builder.
- // The capacity is adjusted as needed.
- public StringBuilder Append(float value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Append(value.ToString(CultureInfo.CurrentCulture));
- }
-
- // Appends a double to this string builder.
- // The capacity is adjusted as needed.
- public StringBuilder Append(double value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Append(value.ToString(CultureInfo.CurrentCulture));
- }
-
- public StringBuilder Append(decimal value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Append(value.ToString(CultureInfo.CurrentCulture));
- }
-
- // Appends an ushort to this string builder.
- // The capacity is adjusted as needed.
- [CLSCompliant(false)]
- public StringBuilder Append(ushort value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Append(value.ToString(CultureInfo.CurrentCulture));
- }
-
- // Appends an uint to this string builder.
- // The capacity is adjusted as needed.
- [CLSCompliant(false)]
- public StringBuilder Append(uint value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Append(value.ToString(CultureInfo.CurrentCulture));
- }
-
- // Appends an unsigned long to this string builder.
- // The capacity is adjusted as needed.
- [CLSCompliant(false)]
- public StringBuilder Append(ulong value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Append(value.ToString(CultureInfo.CurrentCulture));
- }
-
- // Appends an Object to this string builder.
- // The capacity is adjusted as needed.
- public StringBuilder Append(Object value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
-
- if (null==value) {
- //Appending null is now a no-op.
- return this;
- }
- return Append(value.ToString());
- }
-
- // Appends all of the characters in value to the current instance.
- public StringBuilder Append(char[] value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
-
- if (null != value && value.Length > 0)
- {
- unsafe {
- fixed (char* valueChars = &value[0])
- Append(valueChars, value.Length);
- }
- }
- return this;
- }
-
- // Append joined values with a separator between each value.
- public unsafe StringBuilder AppendJoin<T>(char separator, params T[] values)
- {
- // Defer argument validation to the internal function
- return AppendJoinCore(&separator, 1, values);
- }
-
- public unsafe StringBuilder AppendJoin<T>(string separator, params T[] values)
- {
- separator = separator ?? string.Empty;
- fixed (char* pSeparator = separator)
- {
- // Defer argument validation to the internal function
- return AppendJoinCore(pSeparator, separator.Length, values);
- }
- }
-
- public unsafe StringBuilder AppendJoin<T>(char separator, IEnumerable<T> values)
- {
- // Defer argument validation to the internal function
- return AppendJoinCore(&separator, 1, values);
- }
-
- public unsafe StringBuilder AppendJoin<T>(string separator, IEnumerable<T> values)
- {
- separator = separator ?? string.Empty;
- fixed (char* pSeparator = separator)
- {
- // Defer argument validation to the internal function
- return AppendJoinCore(pSeparator, separator.Length, values);
- }
- }
-
- private unsafe StringBuilder AppendJoinCore<T>(char* separator, int separatorLength, params T[] values)
- {
- if (values == null)
- throw new ArgumentNullException(nameof(values));
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
-
- if (values.Length == 0)
- return this;
-
- var value = values[0];
- if (value != null)
- Append(value.ToString());
-
- for (var i = 1; i < values.Length; i++)
- {
- Append(separator, separatorLength);
- value = values[i];
- if (value != null)
- Append(value.ToString());
- }
- return this;
- }
-
- private unsafe StringBuilder AppendJoinCore<T>(char* separator, int separatorLength, IEnumerable<T> values)
- {
- if (values == null)
- throw new ArgumentNullException(nameof(values));
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
-
- using (var en = values.GetEnumerator())
- {
- if (!en.MoveNext())
- return this;
-
- var value = en.Current;
- if (value != null)
- Append(value.ToString());
-
- while (en.MoveNext())
- {
- Append(separator, separatorLength);
- value = en.Current;
- if (value != null)
- Append(value.ToString());
- }
- }
- return this;
- }
-
- /*====================================Insert====================================
- **
- ==============================================================================*/
-
- // Returns a reference to the StringBuilder with ; value inserted into
- // the buffer at index. Existing characters are shifted to make room for the new text.
- // The capacity is adjusted as needed. If value equals String.Empty, the
- // StringBuilder is not changed.
- //
- public StringBuilder Insert(int index, String value) {
- if ((uint)index > (uint)Length) {
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- Contract.EndContractBlock();
-
- if (value != null)
- {
- unsafe {
- fixed (char* sourcePtr = value)
- Insert(index, sourcePtr, value.Length);
- }
- }
- return this;
- }
-
- // Returns a reference to the StringBuilder with ; value inserted into
- // the buffer at index. Existing characters are shifted to make room for the new text.
- // The capacity is adjusted as needed. If value equals String.Empty, the
- // StringBuilder is not changed.
- //
- public StringBuilder Insert( int index, bool value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Insert(index, value.ToString(), 1);
- }
-
- // Returns a reference to the StringBuilder with ; value inserted into
- // the buffer at index. Existing characters are shifted to make room for the new text.
- // The capacity is adjusted as needed. If value equals String.Empty, the
- // StringBuilder is not changed.
- //
- [CLSCompliant(false)]
- public StringBuilder Insert(int index, sbyte value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
- }
-
- // Returns a reference to the StringBuilder with ; value inserted into
- // the buffer at index. Existing characters are shifted to make room for the new text.
- // The capacity is adjusted as needed. If value equals String.Empty, the
- // StringBuilder is not changed.
- //
- public StringBuilder Insert(int index, byte value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
- }
-
- // Returns a reference to the StringBuilder with ; value inserted into
- // the buffer at index. Existing characters are shifted to make room for the new text.
- // The capacity is adjusted as needed. If value equals String.Empty, the
- // StringBuilder is not changed.
- //
- public StringBuilder Insert(int index, short value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
- }
-
- // Returns a reference to the StringBuilder with ; value inserted into
- // the buffer at index. Existing characters are shifted to make room for the new text.
- // The capacity is adjusted as needed. If value equals String.Empty, the
- // StringBuilder is not changed.
- public StringBuilder Insert(int index, char value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
-
- unsafe {
- Insert(index, &value, 1);
- }
- return this;
- }
-
- // Returns a reference to the StringBuilder with ; value inserted into
- // the buffer at index. Existing characters are shifted to make room for the new text.
- // The capacity is adjusted as needed. If value equals String.Empty, the
- // StringBuilder is not changed.
- //
- public StringBuilder Insert(int index, char[] value) {
- if ((uint)index > (uint)Length) {
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- Contract.EndContractBlock();
-
- if (value != null)
- Insert(index, value, 0, value.Length);
- return this;
- }
-
- // Returns a reference to the StringBuilder with charCount characters from
- // value inserted into the buffer at index. Existing characters are shifted
- // to make room for the new text and capacity is adjusted as required. If value is null, the StringBuilder
- // is unchanged. Characters are taken from value starting at position startIndex.
- public StringBuilder Insert(int index, char[] value, int startIndex, int charCount) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
-
- int currentLength = Length;
- if ((uint)index > (uint)currentLength) {
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
-
- //If they passed in a null char array, just jump out quickly.
- if (value == null) {
- if (startIndex == 0 && charCount == 0)
- {
- return this;
- }
- throw new ArgumentNullException(nameof(value), Environment.GetResourceString("ArgumentNull_String"));
- }
-
- //Range check the array.
- if (startIndex < 0) {
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
- }
-
- if (charCount < 0) {
- throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GenericPositive"));
- }
-
- if (startIndex > value.Length - charCount) {
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
-
- if (charCount > 0)
- {
- unsafe {
- fixed (char* sourcePtr = &value[startIndex])
- Insert(index, sourcePtr, charCount);
- }
- }
- return this;
- }
-
- // Returns a reference to the StringBuilder with ; value inserted into
- // the buffer at index. Existing characters are shifted to make room for the new text.
- // The capacity is adjusted as needed. If value equals String.Empty, the
- // StringBuilder is not changed.
- //
- public StringBuilder Insert(int index, int value){
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
- }
-
- // Returns a reference to the StringBuilder with ; value inserted into
- // the buffer at index. Existing characters are shifted to make room for the new text.
- // The capacity is adjusted as needed. If value equals String.Empty, the
- // StringBuilder is not changed.
- //
- public StringBuilder Insert(int index, long value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
- }
-
- // Returns a reference to the StringBuilder with ; value inserted into
- // the buffer at index. Existing characters are shifted to make room for the new text.
- // The capacity is adjusted as needed. If value equals String.Empty, the
- // StringBuilder is not changed.
- //
- public StringBuilder Insert(int index, float value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
- }
-
- // Returns a reference to the StringBuilder with ; value inserted into
- // the buffer at index. Existing characters are shifted to make room for the new text.
- // The capacity is adjusted as needed. If value equals String.Empty, the
- // StringBuilder is not changed.
- //
- public StringBuilder Insert(int index, double value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
- }
-
- public StringBuilder Insert(int index, decimal value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
- }
-
- // Returns a reference to the StringBuilder with value inserted into
- // the buffer at index. Existing characters are shifted to make room for the new text.
- // The capacity is adjusted as needed.
- //
- [CLSCompliant(false)]
- public StringBuilder Insert(int index, ushort value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
- }
-
- // Returns a reference to the StringBuilder with value inserted into
- // the buffer at index. Existing characters are shifted to make room for the new text.
- // The capacity is adjusted as needed.
- //
- [CLSCompliant(false)]
- public StringBuilder Insert(int index, uint value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
- }
-
- // Returns a reference to the StringBuilder with value inserted into
- // the buffer at index. Existing characters are shifted to make room for the new text.
- // The capacity is adjusted as needed.
- //
- [CLSCompliant(false)]
- public StringBuilder Insert(int index, ulong value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Insert(index, value.ToString(CultureInfo.CurrentCulture), 1);
- }
-
- // Returns a reference to this string builder with value inserted into
- // the buffer at index. Existing characters are shifted to make room for the
- // new text. The capacity is adjusted as needed. If value equals String.Empty, the
- // StringBuilder is not changed. No changes are made if value is null.
- //
- public StringBuilder Insert(int index, Object value) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- if (null == value) {
- return this;
- }
- return Insert(index, value.ToString(), 1);
- }
-
- public StringBuilder AppendFormat(String format, Object arg0) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return AppendFormatHelper(null, format, new ParamsArray(arg0));
- }
-
- public StringBuilder AppendFormat(String format, Object arg0, Object arg1) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return AppendFormatHelper(null, format, new ParamsArray(arg0, arg1));
- }
-
- public StringBuilder AppendFormat(String format, Object arg0, Object arg1, Object arg2) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return AppendFormatHelper(null, format, new ParamsArray(arg0, arg1, arg2));
- }
-
- public StringBuilder AppendFormat(String format, params Object[] args) {
- if (args == null)
- {
- // To preserve the original exception behavior, throw an exception about format if both
- // args and format are null. The actual null check for format is in AppendFormatHelper.
- throw new ArgumentNullException((format == null) ? nameof(format) : nameof(args));
- }
- Contract.Ensures(Contract.Result<String>() != null);
- Contract.EndContractBlock();
-
- return AppendFormatHelper(null, format, new ParamsArray(args));
- }
-
- public StringBuilder AppendFormat(IFormatProvider provider, String format, Object arg0) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return AppendFormatHelper(provider, format, new ParamsArray(arg0));
- }
-
- public StringBuilder AppendFormat(IFormatProvider provider, String format, Object arg0, Object arg1) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return AppendFormatHelper(provider, format, new ParamsArray(arg0, arg1));
- }
-
- public StringBuilder AppendFormat(IFormatProvider provider, String format, Object arg0, Object arg1, Object arg2) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return AppendFormatHelper(provider, format, new ParamsArray(arg0, arg1, arg2));
- }
-
- public StringBuilder AppendFormat(IFormatProvider provider, String format, params Object[] args) {
- if (args == null)
- {
- // To preserve the original exception behavior, throw an exception about format if both
- // args and format are null. The actual null check for format is in AppendFormatHelper.
- throw new ArgumentNullException((format == null) ? nameof(format) : nameof(args));
- }
- Contract.Ensures(Contract.Result<String>() != null);
- Contract.EndContractBlock();
-
- return AppendFormatHelper(provider, format, new ParamsArray(args));
- }
-
- private static void FormatError() {
- throw new FormatException(Environment.GetResourceString("Format_InvalidString"));
- }
-
- // undocumented exclusive limits on the range for Argument Hole Index and Argument Hole Alignment.
- private const int Index_Limit = 1000000; // Note: 0 <= ArgIndex < Index_Limit
- private const int Width_Limit = 1000000; // Note: -Width_Limit < ArgAlign < Width_Limit
-
- internal StringBuilder AppendFormatHelper(IFormatProvider provider, String format, ParamsArray args) {
- if (format == null) {
- throw new ArgumentNullException(nameof(format));
- }
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- Contract.EndContractBlock();
-
- int pos = 0;
- int len = format.Length;
- char ch = '\x0';
- StringBuilder unescapedItemFormat = null;
-
- ICustomFormatter cf = null;
- if (provider != null) {
- cf = (ICustomFormatter)provider.GetFormat(typeof(ICustomFormatter));
- }
-
- while (true) {
- while (pos < len) {
- ch = format[pos];
-
- pos++;
- // Is it a closing brace?
- if (ch == '}')
- {
- // Check next character (if there is one) to see if it is escaped. eg }}
- if (pos < len && format[pos] == '}')
- pos++;
- else
- // Otherwise treat it as an error (Mismatched closing brace)
- FormatError();
- }
- // Is it a opening brace?
- if (ch == '{')
- {
- // Check next character (if there is one) to see if it is escaped. eg {{
- if (pos < len && format[pos] == '{')
- pos++;
- else
- {
- // Otherwise treat it as the opening brace of an Argument Hole.
- pos--;
- break;
- }
- }
- // If it neither then treat the character as just text.
- Append(ch);
- }
-
- //
- // Start of parsing of Argument Hole.
- // Argument Hole ::= { Index (, WS* Alignment WS*)? (: Formatting)? }
- //
- if (pos == len) break;
-
- //
- // Start of parsing required Index parameter.
- // Index ::= ('0'-'9')+ WS*
- //
- pos++;
- // If reached end of text then error (Unexpected end of text)
- // or character is not a digit then error (Unexpected Character)
- if (pos == len || (ch = format[pos]) < '0' || ch > '9') FormatError();
- int index = 0;
- do {
- index = index * 10 + ch - '0';
- pos++;
- // If reached end of text then error (Unexpected end of text)
- if (pos == len) FormatError();
- ch = format[pos];
- // so long as character is digit and value of the index is less than 1000000 ( index limit )
- } while (ch >= '0' && ch <= '9' && index < Index_Limit);
-
- // If value of index is not within the range of the arguments passed in then error (Index out of range)
- if (index >= args.Length) throw new FormatException(Environment.GetResourceString("Format_IndexOutOfRange"));
-
- // Consume optional whitespace.
- while (pos < len && (ch = format[pos]) == ' ') pos++;
- // End of parsing index parameter.
-
- //
- // Start of parsing of optional Alignment
- // Alignment ::= comma WS* minus? ('0'-'9')+ WS*
- //
- bool leftJustify = false;
- int width = 0;
- // Is the character a comma, which indicates the start of alignment parameter.
- if (ch == ',') {
- pos++;
-
- // Consume Optional whitespace
- while (pos < len && format[pos] == ' ') pos++;
-
- // If reached the end of the text then error (Unexpected end of text)
- if (pos == len) FormatError();
-
- // Is there a minus sign?
- ch = format[pos];
- if (ch == '-') {
- // Yes, then alignment is left justified.
- leftJustify = true;
- pos++;
- // If reached end of text then error (Unexpected end of text)
- if (pos == len) FormatError();
- ch = format[pos];
- }
-
- // If current character is not a digit then error (Unexpected character)
- if (ch < '0' || ch > '9') FormatError();
- // Parse alignment digits.
- do {
- width = width * 10 + ch - '0';
- pos++;
- // If reached end of text then error. (Unexpected end of text)
- if (pos == len) FormatError();
- ch = format[pos];
- // So long a current character is a digit and the value of width is less than 100000 ( width limit )
- } while (ch >= '0' && ch <= '9' && width < Width_Limit);
- // end of parsing Argument Alignment
- }
-
- // Consume optional whitespace
- while (pos < len && (ch = format[pos]) == ' ') pos++;
-
- //
- // Start of parsing of optional formatting parameter.
- //
- Object arg = args[index];
- String itemFormat = null;
- // Is current character a colon? which indicates start of formatting parameter.
- if (ch == ':') {
- pos++;
- int startPos = pos;
-
- while (true) {
- // If reached end of text then error. (Unexpected end of text)
- if (pos == len) FormatError();
- ch = format[pos];
- pos++;
-
- // Is character a opening or closing brace?
- if (ch == '}' || ch == '{')
- {
- if (ch == '{')
- {
- // Yes, is next character also a opening brace, then treat as escaped. eg {{
- if (pos < len && format[pos] == '{')
- pos++;
- else
- // Error Argument Holes can not be nested.
- FormatError();
- }
- else
- {
- // Yes, is next character also a closing brace, then treat as escaped. eg }}
- if (pos < len && format[pos] == '}')
- pos++;
- else
- {
- // No, then treat it as the closing brace of an Arg Hole.
- pos--;
- break;
- }
- }
-
- // Reaching here means the brace has been escaped
- // so we need to build up the format string in segments
- if (unescapedItemFormat == null)
- {
- unescapedItemFormat = new StringBuilder();
- }
- unescapedItemFormat.Append(format, startPos, pos - startPos - 1);
- startPos = pos;
- }
- }
-
- if (unescapedItemFormat == null || unescapedItemFormat.Length == 0)
- {
- if (startPos != pos)
- {
- // There was no brace escaping, extract the item format as a single string
- itemFormat = format.Substring(startPos, pos - startPos);
- }
- }
- else
- {
- unescapedItemFormat.Append(format, startPos, pos - startPos);
- itemFormat = unescapedItemFormat.ToString();
- unescapedItemFormat.Clear();
- }
- }
- // If current character is not a closing brace then error. (Unexpected Character)
- if (ch != '}') FormatError();
- // Construct the output for this arg hole.
- pos++;
- String s = null;
- if (cf != null) {
- s = cf.Format(itemFormat, arg, provider);
- }
-
- if (s == null) {
- IFormattable formattableArg = arg as IFormattable;
-
- if (formattableArg != null) {
- s = formattableArg.ToString(itemFormat, provider);
- } else if (arg != null) {
- s = arg.ToString();
- }
- }
- // Append it to the final output of the Format String.
- if (s == null) s = String.Empty;
- int pad = width - s.Length;
- if (!leftJustify && pad > 0) Append(' ', pad);
- Append(s);
- if (leftJustify && pad > 0) Append(' ', pad);
- // Continue to parse other characters.
- }
- return this;
- }
-
- // Returns a reference to the current StringBuilder with all instances of oldString
- // replaced with newString. If startIndex and count are specified,
- // we only replace strings completely contained in the range of startIndex to startIndex +
- // count. The strings to be replaced are checked on an ordinal basis (e.g. not culture aware). If
- // newValue is null, instances of oldValue are removed (e.g. replaced with nothing.).
- //
- public StringBuilder Replace(String oldValue, String newValue) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
- return Replace(oldValue, newValue, 0, Length);
- }
-
- public bool Equals(StringBuilder sb)
- {
- if (sb == null)
- return false;
- if (Capacity != sb.Capacity || MaxCapacity != sb.MaxCapacity || Length != sb.Length)
- return false;
- if (sb == this)
- return true;
-
- StringBuilder thisChunk = this;
- int thisChunkIndex = thisChunk.m_ChunkLength;
- StringBuilder sbChunk = sb;
- int sbChunkIndex = sbChunk.m_ChunkLength;
- for (; ; )
- {
- // Decrement the pointer to the 'this' StringBuilder
- --thisChunkIndex;
- --sbChunkIndex;
-
- while (thisChunkIndex < 0)
- {
- thisChunk = thisChunk.m_ChunkPrevious;
- if (thisChunk == null)
- break;
- thisChunkIndex = thisChunk.m_ChunkLength + thisChunkIndex;
- }
-
- // Decrement the pointer to the 'this' StringBuilder
- while (sbChunkIndex < 0)
- {
- sbChunk = sbChunk.m_ChunkPrevious;
- if (sbChunk == null)
- break;
- sbChunkIndex = sbChunk.m_ChunkLength + sbChunkIndex;
- }
-
- if (thisChunkIndex < 0)
- return sbChunkIndex < 0;
- if (sbChunkIndex < 0)
- return false;
- if (thisChunk.m_ChunkChars[thisChunkIndex] != sbChunk.m_ChunkChars[sbChunkIndex])
- return false;
- }
- }
-
- public StringBuilder Replace(String oldValue, String newValue, int startIndex, int count)
- {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
-
- int currentLength = Length;
- if ((uint)startIndex > (uint)currentLength)
- {
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- if (count < 0 || startIndex > currentLength - count)
- {
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- if (oldValue == null)
- {
- throw new ArgumentNullException(nameof(oldValue));
- }
- if (oldValue.Length == 0)
- {
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(oldValue));
- }
-
- if (newValue == null)
- newValue = "";
-
- int deltaLength = newValue.Length - oldValue.Length;
-
- int[] replacements = null; // A list of replacement positions in a chunk to apply
- int replacementsCount = 0;
-
- // Find the chunk, indexInChunk for the starting point
- StringBuilder chunk = FindChunkForIndex(startIndex);
- int indexInChunk = startIndex - chunk.m_ChunkOffset;
- while (count > 0)
- {
- // Look for a match in the chunk,indexInChunk pointer
- if (StartsWith(chunk, indexInChunk, count, oldValue))
- {
- // Push it on my replacements array (with growth), we will do all replacements in a
- // given chunk in one operation below (see ReplaceAllInChunk) so we don't have to slide
- // many times.
- if (replacements == null)
- replacements = new int[5];
- else if (replacementsCount >= replacements.Length)
- {
- int[] newArray = new int[replacements.Length * 3 / 2 + 4]; // grow by 1.5X but more in the begining
- Array.Copy(replacements, newArray, replacements.Length);
- replacements = newArray;
- }
- replacements[replacementsCount++] = indexInChunk;
- indexInChunk += oldValue.Length;
- count -= oldValue.Length;
- }
- else
- {
- indexInChunk++;
- --count;
- }
-
- if (indexInChunk >= chunk.m_ChunkLength || count == 0) // Have we moved out of the current chunk
- {
- // Replacing mutates the blocks, so we need to convert to logical index and back afterward.
- int index = indexInChunk + chunk.m_ChunkOffset;
- int indexBeforeAdjustment = index;
-
- // See if we accumulated any replacements, if so apply them
- ReplaceAllInChunk(replacements, replacementsCount, chunk, oldValue.Length, newValue);
- // The replacement has affected the logical index. Adjust it.
- index += ((newValue.Length - oldValue.Length) * replacementsCount);
- replacementsCount = 0;
-
- chunk = FindChunkForIndex(index);
- indexInChunk = index - chunk.m_ChunkOffset;
- Debug.Assert(chunk != null || count == 0, "Chunks ended prematurely");
- }
- }
- VerifyClassInvariant();
- return this;
- }
-
- // Returns a StringBuilder with all instances of oldChar replaced with
- // newChar. The size of the StringBuilder is unchanged because we're only
- // replacing characters. If startIndex and count are specified, we
- // only replace characters in the range from startIndex to startIndex+count
- //
- public StringBuilder Replace(char oldChar, char newChar) {
- return Replace(oldChar, newChar, 0, Length);
- }
- public StringBuilder Replace(char oldChar, char newChar, int startIndex, int count) {
- Contract.Ensures(Contract.Result<StringBuilder>() != null);
-
- int currentLength = Length;
- if ((uint)startIndex > (uint)currentLength) {
- throw new ArgumentOutOfRangeException(nameof(startIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
-
- if (count < 0 || startIndex > currentLength - count) {
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
-
- int endIndex = startIndex + count;
- StringBuilder chunk = this;
- for (; ; )
- {
- int endIndexInChunk = endIndex - chunk.m_ChunkOffset;
- int startIndexInChunk = startIndex - chunk.m_ChunkOffset;
- if (endIndexInChunk >= 0)
- {
- int curInChunk = Math.Max(startIndexInChunk, 0);
- int endInChunk = Math.Min(chunk.m_ChunkLength, endIndexInChunk);
- while (curInChunk < endInChunk)
- {
- if (chunk.m_ChunkChars[curInChunk] == oldChar)
- chunk.m_ChunkChars[curInChunk] = newChar;
- curInChunk++;
- }
- }
- if (startIndexInChunk >= 0)
- break;
- chunk = chunk.m_ChunkPrevious;
- }
- return this;
- }
-
- /// <summary>
- /// Appends 'value' of length 'count' to the stringBuilder.
- /// </summary>
- [System.CLSCompliantAttribute(false)]
- public unsafe StringBuilder Append(char* value, int valueCount)
- {
- // We don't check null value as this case will throw null reference exception anyway
- if (valueCount < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(valueCount), Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
- }
-
- // this is where we can check if the valueCount will put us over m_MaxCapacity
- // We are doing the check here to prevent the corruption of the StringBuilder.
- int newLength = Length + valueCount;
- if (newLength > m_MaxCapacity || newLength < valueCount) {
- throw new ArgumentOutOfRangeException(nameof(valueCount), Environment.GetResourceString("ArgumentOutOfRange_LengthGreaterThanCapacity"));
- }
-
- // This case is so common we want to optimize for it heavily.
- int newIndex = valueCount + m_ChunkLength;
- if (newIndex <= m_ChunkChars.Length)
- {
- ThreadSafeCopy(value, m_ChunkChars, m_ChunkLength, valueCount);
- m_ChunkLength = newIndex;
- }
- else
- {
- // Copy the first chunk
- int firstLength = m_ChunkChars.Length - m_ChunkLength;
- if (firstLength > 0)
- {
- ThreadSafeCopy(value, m_ChunkChars, m_ChunkLength, firstLength);
- m_ChunkLength = m_ChunkChars.Length;
- }
-
- // Expand the builder to add another chunk.
- int restLength = valueCount - firstLength;
- ExpandByABlock(restLength);
- Debug.Assert(m_ChunkLength == 0, "Expand did not make a new block");
-
- // Copy the second chunk
- ThreadSafeCopy(value + firstLength, m_ChunkChars, 0, restLength);
- m_ChunkLength = restLength;
- }
- VerifyClassInvariant();
- return this;
- }
-
- /// <summary>
- /// Inserts 'value' of length 'cou
- /// </summary>
- unsafe private void Insert(int index, char* value, int valueCount)
- {
- if ((uint)index > (uint)Length)
- {
- throw new ArgumentOutOfRangeException(nameof(index), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
-
- if (valueCount > 0)
- {
- StringBuilder chunk;
- int indexInChunk;
- MakeRoom(index, valueCount, out chunk, out indexInChunk, false);
- ReplaceInPlaceAtChunk(ref chunk, ref indexInChunk, value, valueCount);
- }
- }
-
- /// <summary>
- /// 'replacements' is a list of index (relative to the begining of the 'chunk' to remove
- /// 'removeCount' characters and replace them with 'value'. This routine does all those
- /// replacements in bulk (and therefore very efficiently.
- /// with the string 'value'.
- /// </summary>
- private void ReplaceAllInChunk(int[] replacements, int replacementsCount, StringBuilder sourceChunk, int removeCount, string value)
- {
- if (replacementsCount <= 0)
- return;
-
- unsafe {
- fixed (char* valuePtr = value)
- {
- // calculate the total amount of extra space or space needed for all the replacements.
- int delta = (value.Length - removeCount) * replacementsCount;
-
- StringBuilder targetChunk = sourceChunk; // the target as we copy chars down
- int targetIndexInChunk = replacements[0];
-
- // Make the room needed for all the new characters if needed.
- if (delta > 0)
- MakeRoom(targetChunk.m_ChunkOffset + targetIndexInChunk, delta, out targetChunk, out targetIndexInChunk, true);
- // We made certain that characters after the insertion point are not moved,
- int i = 0;
- for (; ; )
- {
- // Copy in the new string for the ith replacement
- ReplaceInPlaceAtChunk(ref targetChunk, ref targetIndexInChunk, valuePtr, value.Length);
- int gapStart = replacements[i] + removeCount;
- i++;
- if (i >= replacementsCount)
- break;
-
- int gapEnd = replacements[i];
- Debug.Assert(gapStart < sourceChunk.m_ChunkChars.Length, "gap starts at end of buffer. Should not happen");
- Debug.Assert(gapStart <= gapEnd, "negative gap size");
- Debug.Assert(gapEnd <= sourceChunk.m_ChunkLength, "gap too big");
- if (delta != 0) // can skip the sliding of gaps if source an target string are the same size.
- {
- // Copy the gap data between the current replacement and the the next replacement
- fixed (char* sourcePtr = &sourceChunk.m_ChunkChars[gapStart])
- ReplaceInPlaceAtChunk(ref targetChunk, ref targetIndexInChunk, sourcePtr, gapEnd - gapStart);
- }
- else
- {
- targetIndexInChunk += gapEnd - gapStart;
- Debug.Assert(targetIndexInChunk <= targetChunk.m_ChunkLength, "gap not in chunk");
- }
- }
-
- // Remove extra space if necessary.
- if (delta < 0)
- Remove(targetChunk.m_ChunkOffset + targetIndexInChunk, -delta, out targetChunk, out targetIndexInChunk);
- }
- }
- }
-
- /// <summary>
- /// Returns true if the string that is starts at 'chunk' and 'indexInChunk, and has a logical
- /// length of 'count' starts with the string 'value'.
- /// </summary>
- private bool StartsWith(StringBuilder chunk, int indexInChunk, int count, string value)
- {
- for (int i = 0; i < value.Length; i++)
- {
- if (count == 0)
- return false;
- if (indexInChunk >= chunk.m_ChunkLength)
- {
- chunk = Next(chunk);
- if (chunk == null)
- return false;
- indexInChunk = 0;
- }
-
- // See if there no match, break out of the inner for loop
- if (value[i] != chunk.m_ChunkChars[indexInChunk])
- return false;
-
- indexInChunk++;
- --count;
- }
- return true;
- }
-
- /// <summary>
- /// ReplaceInPlaceAtChunk is the logical equivalent of 'memcpy'. Given a chunk and ann index in
- /// that chunk, it copies in 'count' characters from 'value' and updates 'chunk, and indexInChunk to
- /// point at the end of the characters just copyied (thus you can splice in strings from multiple
- /// places by calling this mulitple times.
- /// </summary>
- unsafe private void ReplaceInPlaceAtChunk(ref StringBuilder chunk, ref int indexInChunk, char* value, int count)
- {
- if (count != 0)
- {
- for (; ; )
- {
- int lengthInChunk = chunk.m_ChunkLength - indexInChunk;
- Debug.Assert(lengthInChunk >= 0, "index not in chunk");
-
- int lengthToCopy = Math.Min(lengthInChunk, count);
- ThreadSafeCopy(value, chunk.m_ChunkChars, indexInChunk, lengthToCopy);
-
- // Advance the index.
- indexInChunk += lengthToCopy;
- if (indexInChunk >= chunk.m_ChunkLength)
- {
- chunk = Next(chunk);
- indexInChunk = 0;
- }
- count -= lengthToCopy;
- if (count == 0)
- break;
- value += lengthToCopy;
- }
- }
- }
-
- /// <summary>
- /// We have to prevent modification off the end of an array.
- /// The only way to do this is to copy all interesting variables out of the heap and then do the
- /// bounds check. This is what we do here.
- /// </summary>
- unsafe private static void ThreadSafeCopy(char* sourcePtr, char[] destination, int destinationIndex, int count)
- {
- if (count > 0)
- {
- if ((uint)destinationIndex <= (uint)destination.Length && (destinationIndex + count) <= destination.Length)
- {
- fixed (char* destinationPtr = &destination[destinationIndex])
- string.wstrcpy(destinationPtr, sourcePtr, count);
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(destinationIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- }
- }
- private static void ThreadSafeCopy(char[] source, int sourceIndex, char[] destination, int destinationIndex, int count)
- {
- if (count > 0)
- {
- if ((uint)sourceIndex <= (uint)source.Length && (sourceIndex + count) <= source.Length)
- {
- unsafe {
- fixed (char* sourcePtr = &source[sourceIndex])
- ThreadSafeCopy(sourcePtr, destination, destinationIndex, count);
- }
- }
- else
- {
- throw new ArgumentOutOfRangeException(nameof(sourceIndex), Environment.GetResourceString("ArgumentOutOfRange_Index"));
- }
- }
- }
-
- // Copies the source StringBuilder to the destination IntPtr memory allocated with len bytes.
- internal unsafe void InternalCopy(IntPtr dest, int len) {
- if(len ==0)
- return;
-
- bool isLastChunk = true;
- byte* dstPtr = (byte*) dest.ToPointer();
- StringBuilder currentSrc = FindChunkForByte(len);
-
- do {
- int chunkOffsetInBytes = currentSrc.m_ChunkOffset*sizeof(char);
- int chunkLengthInBytes = currentSrc.m_ChunkLength*sizeof(char);
- fixed(char* charPtr = &currentSrc.m_ChunkChars[0]) {
- byte* srcPtr = (byte*) charPtr;
- if(isLastChunk) {
- isLastChunk= false;
- Buffer.Memcpy(dstPtr + chunkOffsetInBytes, srcPtr, len - chunkOffsetInBytes);
- } else {
- Buffer.Memcpy(dstPtr + chunkOffsetInBytes, srcPtr, chunkLengthInBytes);
- }
- }
- currentSrc = currentSrc.m_ChunkPrevious;
- } while(currentSrc != null);
- }
-
- /// <summary>
- /// Finds the chunk for the logical index (number of characters in the whole stringbuilder) 'index'
- /// YOu can then get the offset in this chunk by subtracting the m_BlockOffset field from 'index'
- /// </summary>
- /// <param name="index"></param>
- /// <returns></returns>
- private StringBuilder FindChunkForIndex(int index)
- {
- Debug.Assert(0 <= index && index <= Length, "index not in string");
-
- StringBuilder ret = this;
- while (ret.m_ChunkOffset > index)
- ret = ret.m_ChunkPrevious;
-
- Debug.Assert(ret != null, "index not in string");
- return ret;
- }
-
- /// <summary>
- /// Finds the chunk for the logical byte index 'byteIndex'
- /// </summary>
- /// <param name="index"></param>
- /// <returns></returns>
- private StringBuilder FindChunkForByte(int byteIndex)
- {
- Debug.Assert(0 <= byteIndex && byteIndex <= Length*sizeof(char), "Byte Index not in string");
-
- StringBuilder ret = this;
- while (ret.m_ChunkOffset*sizeof(char) > byteIndex)
- ret = ret.m_ChunkPrevious;
-
- Debug.Assert(ret != null, "Byte Index not in string");
- return ret;
- }
-
- /// <summary>
- /// Finds the chunk that logically follows the 'chunk' chunk. Chunks only persist the pointer to
- /// the chunk that is logically before it, so this routine has to start at the this pointer (which
- /// is a assumed to point at the chunk representing the whole stringbuilder) and search
- /// until it finds the current chunk (thus is O(n)). So it is more expensive than a field fetch!
- /// </summary>
- private StringBuilder Next(StringBuilder chunk)
- {
- if (chunk == this)
- return null;
- return FindChunkForIndex(chunk.m_ChunkOffset + chunk.m_ChunkLength);
- }
-
- /// <summary>
- /// Assumes that 'this' is the last chunk in the list and that it is full. Upon return the 'this'
- /// block is updated so that it is a new block that has at least 'minBlockCharCount' characters.
- /// that can be used to copy characters into it.
- /// </summary>
- private void ExpandByABlock(int minBlockCharCount)
- {
- Contract.Requires(Capacity == Length, "Expand expect to be called only when there is no space left"); // We are currently full
- Contract.Requires(minBlockCharCount > 0, "Expansion request must be positive");
-
- VerifyClassInvariant();
-
- if ((minBlockCharCount + Length) > m_MaxCapacity || minBlockCharCount + Length < minBlockCharCount)
- throw new ArgumentOutOfRangeException("requiredLength", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
-
- // Compute the length of the new block we need
- // We make the new chunk at least big enough for the current need (minBlockCharCount)
- // But also as big as the current length (thus doubling capacity), up to a maximum
- // (so we stay in the small object heap, and never allocate really big chunks even if
- // the string gets really big.
- int newBlockLength = Math.Max(minBlockCharCount, Math.Min(Length, MaxChunkSize));
-
- // Copy the current block to the new block, and initialize this to point at the new buffer.
- m_ChunkPrevious = new StringBuilder(this);
- m_ChunkOffset += m_ChunkLength;
- m_ChunkLength = 0;
-
- // Check for integer overflow (logical buffer size > int.MaxInt)
- if (m_ChunkOffset + newBlockLength < newBlockLength)
- {
- m_ChunkChars = null;
- throw new OutOfMemoryException();
- }
- m_ChunkChars = new char[newBlockLength];
-
- VerifyClassInvariant();
- }
-
- /// <summary>
- /// Used by ExpandByABlock to create a new chunk. The new chunk is a copied from 'from'
- /// In particular the buffer is shared. It is expected that 'from' chunk (which represents
- /// the whole list, is then updated to point to point to this new chunk.
- /// </summary>
- private StringBuilder(StringBuilder from)
- {
- m_ChunkLength = from.m_ChunkLength;
- m_ChunkOffset = from.m_ChunkOffset;
- m_ChunkChars = from.m_ChunkChars;
- m_ChunkPrevious = from.m_ChunkPrevious;
- m_MaxCapacity = from.m_MaxCapacity;
- VerifyClassInvariant();
- }
-
- /// <summary>
- /// Creates a gap of size 'count' at the logical offset (count of characters in the whole string
- /// builder) 'index'. It returns the 'chunk' and 'indexInChunk' which represents a pointer to
- /// this gap that was just created. You can then use 'ReplaceInPlaceAtChunk' to fill in the
- /// chunk
- ///
- /// ReplaceAllChunks relies on the fact that indexes above 'index' are NOT moved outside 'chunk'
- /// by this process (because we make the space by creating the cap BEFORE the chunk). If we
- /// change this ReplaceAllChunks needs to be updated.
- ///
- /// If dontMoveFollowingChars is true, then the room must be made by inserting a chunk BEFORE the
- /// current chunk (this is what it does most of the time anyway)
- /// </summary>
- private void MakeRoom(int index, int count, out StringBuilder chunk, out int indexInChunk, bool doneMoveFollowingChars)
- {
- VerifyClassInvariant();
- Debug.Assert(count > 0, "Count must be strictly positive");
- Debug.Assert(index >= 0, "Index can't be negative");
- if (count + Length > m_MaxCapacity || count + Length < count)
- throw new ArgumentOutOfRangeException("requiredLength", Environment.GetResourceString("ArgumentOutOfRange_SmallCapacity"));
-
- chunk = this;
- while (chunk.m_ChunkOffset > index)
- {
- chunk.m_ChunkOffset += count;
- chunk = chunk.m_ChunkPrevious;
- }
- indexInChunk = index - chunk.m_ChunkOffset;
-
- // Cool, we have some space in this block, and you don't have to copy much to get it, go ahead
- // and use it. This happens typically when you repeatedly insert small strings at a spot
- // (typically the absolute front) of the buffer.
- if (!doneMoveFollowingChars && chunk.m_ChunkLength <= DefaultCapacity * 2 && chunk.m_ChunkChars.Length - chunk.m_ChunkLength >= count)
- {
- for (int i = chunk.m_ChunkLength; i > indexInChunk; )
- {
- --i;
- chunk.m_ChunkChars[i + count] = chunk.m_ChunkChars[i];
- }
- chunk.m_ChunkLength += count;
- return;
- }
-
- // Allocate space for the new chunk (will go before this one)
- StringBuilder newChunk = new StringBuilder(Math.Max(count, DefaultCapacity), chunk.m_MaxCapacity, chunk.m_ChunkPrevious);
- newChunk.m_ChunkLength = count;
-
- // Copy the head of the buffer to the new buffer.
- int copyCount1 = Math.Min(count, indexInChunk);
- if (copyCount1 > 0)
- {
- unsafe {
- fixed (char* chunkCharsPtr = &chunk.m_ChunkChars[0]) {
- ThreadSafeCopy(chunkCharsPtr, newChunk.m_ChunkChars, 0, copyCount1);
-
- // Slide characters in the current buffer over to make room.
- int copyCount2 = indexInChunk - copyCount1;
- if (copyCount2 >= 0)
- {
- ThreadSafeCopy(chunkCharsPtr + copyCount1, chunk.m_ChunkChars, 0, copyCount2);
- indexInChunk = copyCount2;
- }
- }
- }
- }
-
- chunk.m_ChunkPrevious = newChunk; // Wire in the new chunk
- chunk.m_ChunkOffset += count;
- if (copyCount1 < count)
- {
- chunk = newChunk;
- indexInChunk = copyCount1;
- }
-
- VerifyClassInvariant();
- }
-
- /// <summary>
- /// Used by MakeRoom to allocate another chunk.
- /// </summary>
- private StringBuilder(int size, int maxCapacity, StringBuilder previousBlock)
- {
- Debug.Assert(size > 0, "size not positive");
- Debug.Assert(maxCapacity > 0, "maxCapacity not positive");
- m_ChunkChars = new char[size];
- m_MaxCapacity = maxCapacity;
- m_ChunkPrevious = previousBlock;
- if (previousBlock != null)
- m_ChunkOffset = previousBlock.m_ChunkOffset + previousBlock.m_ChunkLength;
- VerifyClassInvariant();
- }
-
- /// <summary>
- /// Removes 'count' characters from the logical index 'startIndex' and returns the chunk and
- /// index in the chunk of that logical index in the out parameters.
- /// </summary>
- private void Remove(int startIndex, int count, out StringBuilder chunk, out int indexInChunk)
- {
- VerifyClassInvariant();
- Debug.Assert(startIndex >= 0 && startIndex < Length, "startIndex not in string");
-
- int endIndex = startIndex + count;
-
- // Find the chunks for the start and end of the block to delete.
- chunk = this;
- StringBuilder endChunk = null;
- int endIndexInChunk = 0;
- for (; ; )
- {
- if (endIndex - chunk.m_ChunkOffset >= 0)
- {
- if (endChunk == null)
- {
- endChunk = chunk;
- endIndexInChunk = endIndex - endChunk.m_ChunkOffset;
- }
- if (startIndex - chunk.m_ChunkOffset >= 0)
- {
- indexInChunk = startIndex - chunk.m_ChunkOffset;
- break;
- }
- }
- else
- {
- chunk.m_ChunkOffset -= count;
- }
- chunk = chunk.m_ChunkPrevious;
- }
- Debug.Assert(chunk != null, "fell off beginning of string!");
-
- int copyTargetIndexInChunk = indexInChunk;
- int copyCount = endChunk.m_ChunkLength - endIndexInChunk;
- if (endChunk != chunk)
- {
- copyTargetIndexInChunk = 0;
- // Remove the characters after startIndex to end of the chunk
- chunk.m_ChunkLength = indexInChunk;
-
- // Remove the characters in chunks between start and end chunk
- endChunk.m_ChunkPrevious = chunk;
- endChunk.m_ChunkOffset = chunk.m_ChunkOffset + chunk.m_ChunkLength;
-
- // If the start is 0 then we can throw away the whole start chunk
- if (indexInChunk == 0)
- {
- endChunk.m_ChunkPrevious = chunk.m_ChunkPrevious;
- chunk = endChunk;
- }
- }
- endChunk.m_ChunkLength -= (endIndexInChunk - copyTargetIndexInChunk);
-
- // SafeCritical: We ensure that endIndexInChunk + copyCount is within range of m_ChunkChars and
- // also ensure that copyTargetIndexInChunk + copyCount is within the chunk
- //
- // Remove any characters in the end chunk, by sliding the characters down.
- if (copyTargetIndexInChunk != endIndexInChunk) // Sometimes no move is necessary
- ThreadSafeCopy(endChunk.m_ChunkChars, endIndexInChunk, endChunk.m_ChunkChars, copyTargetIndexInChunk, copyCount);
-
- Debug.Assert(chunk != null, "fell off beginning of string!");
- VerifyClassInvariant();
- }
- }
-}
diff --git a/src/mscorlib/src/System/Text/StringBuilderCache.cs b/src/mscorlib/src/System/Text/StringBuilderCache.cs
index 16a786d54e..a8a5e2c7f4 100644
--- a/src/mscorlib/src/System/Text/StringBuilderCache.cs
+++ b/src/mscorlib/src/System/Text/StringBuilderCache.cs
@@ -31,6 +31,7 @@
** cache and return the resulting string
**
===========================================================*/
+
using System.Threading;
namespace System.Text
@@ -47,14 +48,14 @@ namespace System.Text
public static StringBuilder Acquire(int capacity = StringBuilder.DefaultCapacity)
{
- if(capacity <= MAX_BUILDER_SIZE)
+ if (capacity <= MAX_BUILDER_SIZE)
{
StringBuilder sb = StringBuilderCache.CachedInstance;
if (sb != null)
{
// Avoid stringbuilder block fragmentation by getting a new StringBuilder
// when the requested size is larger than the current capacity
- if(capacity <= sb.Capacity)
+ if (capacity <= sb.Capacity)
{
StringBuilderCache.CachedInstance = null;
sb.Clear();
diff --git a/src/mscorlib/src/System/Text/UTF32Encoding.cs b/src/mscorlib/src/System/Text/UTF32Encoding.cs
deleted file mode 100644
index a7ac1d8539..0000000000
--- a/src/mscorlib/src/System/Text/UTF32Encoding.cs
+++ /dev/null
@@ -1,1003 +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.
-
-//
-// Don't override IsAlwaysNormalized because it is just a Unicode Transformation and could be confused.
-//
-
-namespace System.Text
-{
-
- using System;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Globalization;
- // Encodes text into and out of UTF-32. UTF-32 is a way of writing
- // Unicode characters with a single storage unit (32 bits) per character,
- //
- // The UTF-32 byte order mark is simply the Unicode byte order mark
- // (0x00FEFF) written in UTF-32 (0x0000FEFF or 0xFFFE0000). The byte order
- // mark is used mostly to distinguish UTF-32 text from other encodings, and doesn't
- // switch the byte orderings.
-
- [Serializable]
- public sealed class UTF32Encoding : Encoding
- {
- /*
- words bits UTF-32 representation
- ----- ---- -----------------------------------
- 1 16 00000000 00000000 xxxxxxxx xxxxxxxx
- 2 21 00000000 000xxxxx hhhhhhll llllllll
- ----- ---- -----------------------------------
-
- Surrogate:
- Real Unicode value = (HighSurrogate - 0xD800) * 0x400 + (LowSurrogate - 0xDC00) + 0x10000
- */
-
- // Used by Encoding.UTF32/BigEndianUTF32 for lazy initialization
- // The initialization code will not be run until a static member of the class is referenced
- internal static readonly UTF32Encoding s_default = new UTF32Encoding(bigEndian: false, byteOrderMark: true);
- internal static readonly UTF32Encoding s_bigEndianDefault = new UTF32Encoding(bigEndian: true, byteOrderMark: true);
-
- private bool emitUTF32ByteOrderMark = false;
- private bool isThrowException = false;
- private bool bigEndian = false;
-
-
- public UTF32Encoding(): this(false, true, false)
- {
- }
-
-
- public UTF32Encoding(bool bigEndian, bool byteOrderMark):
- this(bigEndian, byteOrderMark, false)
- {
- }
-
-
- public UTF32Encoding(bool bigEndian, bool byteOrderMark, bool throwOnInvalidCharacters):
- base(bigEndian ? 12001 : 12000)
- {
- this.bigEndian = bigEndian;
- this.emitUTF32ByteOrderMark = byteOrderMark;
- this.isThrowException = throwOnInvalidCharacters;
-
- // Encoding's constructor already did this, but it'll be wrong if we're throwing exceptions
- if (this.isThrowException)
- SetDefaultFallbacks();
- }
-
- internal override void SetDefaultFallbacks()
- {
- // For UTF-X encodings, we use a replacement fallback with an empty string
- if (this.isThrowException)
- {
- this.encoderFallback = EncoderFallback.ExceptionFallback;
- this.decoderFallback = DecoderFallback.ExceptionFallback;
- }
- else
- {
- this.encoderFallback = new EncoderReplacementFallback("\xFFFD");
- this.decoderFallback = new DecoderReplacementFallback("\xFFFD");
- }
- }
-
- // NOTE: Many methods in this class forward to EncodingForwarder for
- // validating arguments/wrapping the unsafe methods in this class
- // which do the actual work. That class contains
- // shared logic for doing this which is used by
- // ASCIIEncoding, EncodingNLS, UnicodeEncoding, UTF32Encoding,
- // UTF7Encoding, and UTF8Encoding.
- // The reason the code is separated out into a static class, rather
- // than a base class which overrides all of these methods for us
- // (which is what EncodingNLS is for internal Encodings) is because
- // that's really more of an implementation detail so it's internal.
- // At the same time, C# doesn't allow a public class subclassing an
- // internal/private one, so we end up having to re-override these
- // methods in all of the public Encodings + EncodingNLS.
-
- // Returns the number of bytes required to encode a range of characters in
- // a character array.
-
- public override int GetByteCount(char[] chars, int index, int count)
- {
- return EncodingForwarder.GetByteCount(this, chars, index, count);
- }
-
- public override int GetByteCount(String s)
- {
- return EncodingForwarder.GetByteCount(this, s);
- }
-
- [CLSCompliant(false)]
- public override unsafe int GetByteCount(char* chars, int count)
- {
- return EncodingForwarder.GetByteCount(this, chars, count);
- }
-
- public override int GetBytes(String s, int charIndex, int charCount,
- byte[] bytes, int byteIndex)
- {
- return EncodingForwarder.GetBytes(this, s, charIndex, charCount, bytes, byteIndex);
- }
-
- // Encodes a range of characters in a character array into a range of bytes
- // in a byte array. An exception occurs if the byte array is not large
- // enough to hold the complete encoding of the characters. The
- // GetByteCount method can be used to determine the exact number of
- // bytes that will be produced for a given range of characters.
- // Alternatively, the GetMaxByteCount method can be used to
- // determine the maximum number of bytes that will be produced for a given
- // number of characters, regardless of the actual character values.
-
- public override int GetBytes(char[] chars, int charIndex, int charCount,
- byte[] bytes, int byteIndex)
- {
- return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
- }
-
- [CLSCompliant(false)]
- public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
- {
- return EncodingForwarder.GetBytes(this, chars, charCount, bytes, byteCount);
- }
-
- // Returns the number of characters produced by decoding a range of bytes
- // in a byte array.
-
- public override int GetCharCount(byte[] bytes, int index, int count)
- {
- return EncodingForwarder.GetCharCount(this, bytes, index, count);
- }
-
- [CLSCompliant(false)]
- public override unsafe int GetCharCount(byte* bytes, int count)
- {
- return EncodingForwarder.GetCharCount(this, bytes, count);
- }
-
- public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
- char[] chars, int charIndex)
- {
- return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
- }
-
- [CLSCompliant(false)]
- public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
- {
- return EncodingForwarder.GetChars(this, bytes, byteCount, chars, charCount);
- }
-
- // Returns a string containing the decoded representation of a range of
- // bytes in a byte array.
-
- public override String GetString(byte[] bytes, int index, int count)
- {
- return EncodingForwarder.GetString(this, bytes, index, count);
- }
-
- // End of overridden methods which use EncodingForwarder
-
- internal override unsafe int GetByteCount(char *chars, int count, EncoderNLS encoder)
- {
- Debug.Assert(chars!=null, "[UTF32Encoding.GetByteCount]chars!=null");
- Debug.Assert(count >=0, "[UTF32Encoding.GetByteCount]count >=0");
-
- char* end = chars + count;
- char* charStart = chars;
- int byteCount = 0;
-
- char highSurrogate = '\0';
-
- // For fallback we may need a fallback buffer
- EncoderFallbackBuffer fallbackBuffer = null;
- if (encoder != null)
- {
- highSurrogate = encoder.charLeftOver;
- fallbackBuffer = encoder.FallbackBuffer;
-
- // We mustn't have left over fallback data when counting
- if (fallbackBuffer.Remaining > 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EncoderFallbackNotEmpty",
- this.EncodingName, encoder.Fallback.GetType()));
- }
- else
- {
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- }
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(charStart, end, encoder, false);
-
- char ch;
- TryAgain:
-
- while (((ch = fallbackBuffer.InternalGetNextChar()) != 0) || chars < end)
- {
- // First unwind any fallback
- if (ch == 0)
- {
- // No fallback, just get next char
- ch = *chars;
- chars++;
- }
-
- // Do we need a low surrogate?
- if (highSurrogate != '\0')
- {
- //
- // In previous char, we encounter a high surrogate, so we are expecting a low surrogate here.
- //
- if (Char.IsLowSurrogate(ch))
- {
- // They're all legal
- highSurrogate = '\0';
-
- //
- // One surrogate pair will be translated into 4 bytes UTF32.
- //
-
- byteCount += 4;
- continue;
- }
-
- // We are missing our low surrogate, decrement chars and fallback the high surrogate
- // The high surrogate may have come from the encoder, but nothing else did.
- Debug.Assert(chars > charStart,
- "[UTF32Encoding.GetByteCount]Expected chars to have advanced if no low surrogate");
- chars--;
-
- // Do the fallback
- fallbackBuffer.InternalFallback(highSurrogate, ref chars);
-
- // We're going to fallback the old high surrogate.
- highSurrogate = '\0';
- continue;
-
- }
-
- // Do we have another high surrogate?
- if (Char.IsHighSurrogate(ch))
- {
- //
- // We'll have a high surrogate to check next time.
- //
- highSurrogate = ch;
- continue;
- }
-
- // Check for illegal characters
- if (Char.IsLowSurrogate(ch))
- {
- // We have a leading low surrogate, do the fallback
- fallbackBuffer.InternalFallback(ch, ref chars);
-
- // Try again with fallback buffer
- continue;
- }
-
- // We get to add the character (4 bytes UTF32)
- byteCount += 4;
- }
-
- // May have to do our last surrogate
- if ((encoder == null || encoder.MustFlush) && highSurrogate > 0)
- {
- // We have to do the fallback for the lonely high surrogate
- fallbackBuffer.InternalFallback(highSurrogate, ref chars);
- highSurrogate = (char)0;
- goto TryAgain;
- }
-
- // Check for overflows.
- if (byteCount < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString(
- "ArgumentOutOfRange_GetByteCountOverflow"));
-
- // Shouldn't have anything in fallback buffer for GetByteCount
- // (don't have to check m_throwOnOverflow for count)
- Debug.Assert(fallbackBuffer.Remaining == 0,
- "[UTF32Encoding.GetByteCount]Expected empty fallback buffer at end");
-
- // Return our count
- return byteCount;
- }
-
- internal override unsafe int GetBytes(char *chars, int charCount,
- byte* bytes, int byteCount, EncoderNLS encoder)
- {
- Debug.Assert(chars!=null, "[UTF32Encoding.GetBytes]chars!=null");
- Debug.Assert(bytes!=null, "[UTF32Encoding.GetBytes]bytes!=null");
- Debug.Assert(byteCount >=0, "[UTF32Encoding.GetBytes]byteCount >=0");
- Debug.Assert(charCount >=0, "[UTF32Encoding.GetBytes]charCount >=0");
-
- char* charStart = chars;
- char* charEnd = chars + charCount;
- byte* byteStart = bytes;
- byte* byteEnd = bytes + byteCount;
-
- char highSurrogate = '\0';
-
- // For fallback we may need a fallback buffer
- EncoderFallbackBuffer fallbackBuffer = null;
- if (encoder != null)
- {
- highSurrogate = encoder.charLeftOver;
- fallbackBuffer = encoder.FallbackBuffer;
-
- // We mustn't have left over fallback data when not converting
- if (encoder.m_throwOnOverflow && fallbackBuffer.Remaining > 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EncoderFallbackNotEmpty",
- this.EncodingName, encoder.Fallback.GetType()));
- }
- else
- {
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- }
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, true);
-
- char ch;
- TryAgain:
-
- while (((ch = fallbackBuffer.InternalGetNextChar()) != 0) || chars < charEnd)
- {
- // First unwind any fallback
- if (ch == 0)
- {
- // No fallback, just get next char
- ch = *chars;
- chars++;
- }
-
- // Do we need a low surrogate?
- if (highSurrogate != '\0')
- {
- //
- // In previous char, we encountered a high surrogate, so we are expecting a low surrogate here.
- //
- if (Char.IsLowSurrogate(ch))
- {
- // Is it a legal one?
- uint iTemp = GetSurrogate(highSurrogate, ch);
- highSurrogate = '\0';
-
- //
- // One surrogate pair will be translated into 4 bytes UTF32.
- //
- if (bytes+3 >= byteEnd)
- {
- // Don't have 4 bytes
- if (fallbackBuffer.bFallingBack)
- {
- fallbackBuffer.MovePrevious(); // Aren't using these 2 fallback chars
- fallbackBuffer.MovePrevious();
- }
- else
- {
- // If we don't have enough room, then either we should've advanced a while
- // or we should have bytes==byteStart and throw below
- Debug.Assert(chars > charStart + 1 || bytes == byteStart,
- "[UnicodeEncoding.GetBytes]Expected chars to have when no room to add surrogate pair");
- chars-=2; // Aren't using those 2 chars
- }
- ThrowBytesOverflow(encoder, bytes == byteStart); // Throw maybe (if no bytes written)
- highSurrogate = (char)0; // Nothing left over (we backed up to start of pair if supplimentary)
- break;
- }
-
- if (bigEndian)
- {
- *(bytes++) = (byte)(0x00);
- *(bytes++) = (byte)(iTemp >> 16); // Implies & 0xFF, which isn't needed cause high are all 0
- *(bytes++) = (byte)(iTemp >> 8); // Implies & 0xFF
- *(bytes++) = (byte)(iTemp); // Implies & 0xFF
- }
- else
- {
- *(bytes++) = (byte)(iTemp); // Implies & 0xFF
- *(bytes++) = (byte)(iTemp >> 8); // Implies & 0xFF
- *(bytes++) = (byte)(iTemp >> 16); // Implies & 0xFF, which isn't needed cause high are all 0
- *(bytes++) = (byte)(0x00);
- }
- continue;
- }
-
- // We are missing our low surrogate, decrement chars and fallback the high surrogate
- // The high surrogate may have come from the encoder, but nothing else did.
- Debug.Assert(chars > charStart,
- "[UTF32Encoding.GetBytes]Expected chars to have advanced if no low surrogate");
- chars--;
-
- // Do the fallback
- fallbackBuffer.InternalFallback(highSurrogate, ref chars);
-
- // We're going to fallback the old high surrogate.
- highSurrogate = '\0';
- continue;
- }
-
- // Do we have another high surrogate?, if so remember it
- if (Char.IsHighSurrogate(ch))
- {
- //
- // We'll have a high surrogate to check next time.
- //
- highSurrogate = ch;
- continue;
- }
-
- // Check for illegal characters (low surrogate)
- if (Char.IsLowSurrogate(ch))
- {
- // We have a leading low surrogate, do the fallback
- fallbackBuffer.InternalFallback(ch, ref chars);
-
- // Try again with fallback buffer
- continue;
- }
-
- // We get to add the character, yippee.
- if (bytes+3 >= byteEnd)
- {
- // Don't have 4 bytes
- if (fallbackBuffer.bFallingBack)
- fallbackBuffer.MovePrevious(); // Aren't using this fallback char
- else
- {
- // Must've advanced already
- Debug.Assert(chars > charStart,
- "[UTF32Encoding.GetBytes]Expected chars to have advanced if normal character");
- chars--; // Aren't using this char
- }
- ThrowBytesOverflow(encoder, bytes == byteStart); // Throw maybe (if no bytes written)
- break; // Didn't throw, stop
- }
-
- if (bigEndian)
- {
- *(bytes++) = (byte)(0x00);
- *(bytes++) = (byte)(0x00);
- *(bytes++) = (byte)((uint)ch >> 8); // Implies & 0xFF
- *(bytes++) = (byte)(ch); // Implies & 0xFF
- }
- else
- {
- *(bytes++) = (byte)(ch); // Implies & 0xFF
- *(bytes++) = (byte)((uint)ch >> 8); // Implies & 0xFF
- *(bytes++) = (byte)(0x00);
- *(bytes++) = (byte)(0x00);
- }
- }
-
- // May have to do our last surrogate
- if ((encoder == null || encoder.MustFlush) && highSurrogate > 0)
- {
- // We have to do the fallback for the lonely high surrogate
- fallbackBuffer.InternalFallback(highSurrogate, ref chars);
- highSurrogate = (char)0;
- goto TryAgain;
- }
-
- // Fix our encoder if we have one
- Debug.Assert(highSurrogate == 0 || (encoder != null && !encoder.MustFlush),
- "[UTF32Encoding.GetBytes]Expected encoder to be flushed.");
-
- if (encoder != null)
- {
- // Remember our left over surrogate (or 0 if flushing)
- encoder.charLeftOver = highSurrogate;
-
- // Need # chars used
- encoder.m_charsUsed = (int)(chars-charStart);
- }
-
- // return the new length
- return (int)(bytes - byteStart);
- }
-
- internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
- {
- Debug.Assert(bytes!=null, "[UTF32Encoding.GetCharCount]bytes!=null");
- Debug.Assert(count >=0, "[UTF32Encoding.GetCharCount]count >=0");
-
- UTF32Decoder decoder = (UTF32Decoder)baseDecoder;
-
- // None so far!
- int charCount = 0;
- byte* end = bytes + count;
- byte* byteStart = bytes;
-
- // Set up decoder
- int readCount = 0;
- uint iChar = 0;
-
- // For fallback we may need a fallback buffer
- DecoderFallbackBuffer fallbackBuffer = null;
-
- // See if there's anything in our decoder
- if (decoder != null)
- {
- readCount = decoder.readByteCount;
- iChar = (uint)decoder.iChar;
- fallbackBuffer = decoder.FallbackBuffer;
-
- // Shouldn't have anything in fallback buffer for GetCharCount
- // (don't have to check m_throwOnOverflow for chars or count)
- Debug.Assert(fallbackBuffer.Remaining == 0,
- "[UTF32Encoding.GetCharCount]Expected empty fallback buffer at start");
- }
- else
- {
- fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
- }
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(byteStart, null);
-
- // Loop through our input, 4 characters at a time!
- while (bytes < end && charCount >= 0)
- {
- // Get our next character
- if(bigEndian)
- {
- // Scoot left and add it to the bottom
- iChar <<= 8;
- iChar += *(bytes++);
- }
- else
- {
- // Scoot right and add it to the top
- iChar >>= 8;
- iChar += (uint)(*(bytes++)) << 24;
- }
-
- readCount++;
-
- // See if we have all the bytes yet
- if (readCount < 4)
- continue;
-
- // Have the bytes
- readCount = 0;
-
- // See if its valid to encode
- if ( iChar > 0x10FFFF || (iChar >= 0xD800 && iChar <= 0xDFFF))
- {
- // Need to fall back these 4 bytes
- byte[] fallbackBytes;
- if (this.bigEndian)
- {
- fallbackBytes = new byte[] {
- unchecked((byte)(iChar>>24)), unchecked((byte)(iChar>>16)),
- unchecked((byte)(iChar>>8)), unchecked((byte)(iChar)) };
- }
- else
- {
- fallbackBytes = new byte[] {
- unchecked((byte)(iChar)), unchecked((byte)(iChar>>8)),
- unchecked((byte)(iChar>>16)), unchecked((byte)(iChar>>24)) };
- }
-
- charCount += fallbackBuffer.InternalFallback(fallbackBytes, bytes);
-
- // Ignore the illegal character
- iChar = 0;
- continue;
- }
-
- // Ok, we have something we can add to our output
- if (iChar >= 0x10000)
- {
- // Surrogates take 2
- charCount++;
- }
-
- // Add the rest of the surrogate or our normal character
- charCount++;
-
- // iChar is back to 0
- iChar = 0;
- }
-
- // See if we have something left over that has to be decoded
- if (readCount > 0 && (decoder == null || decoder.MustFlush))
- {
- // Oops, there's something left over with no place to go.
- byte[] fallbackBytes = new byte[readCount];
- if (this.bigEndian)
- {
- while(readCount > 0)
- {
- fallbackBytes[--readCount] = unchecked((byte)iChar);
- iChar >>= 8;
- }
- }
- else
- {
- while (readCount > 0)
- {
- fallbackBytes[--readCount] = unchecked((byte)(iChar>>24));
- iChar <<= 8;
- }
- }
-
- charCount += fallbackBuffer.InternalFallback(fallbackBytes, bytes);
- }
-
- // Check for overflows.
- if (charCount < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
-
- // Shouldn't have anything in fallback buffer for GetCharCount
- // (don't have to check m_throwOnOverflow for chars or count)
- Debug.Assert(fallbackBuffer.Remaining == 0,
- "[UTF32Encoding.GetCharCount]Expected empty fallback buffer at end");
-
- // Return our count
- return charCount;
- }
-
- internal override unsafe int GetChars(byte* bytes, int byteCount,
- char* chars, int charCount, DecoderNLS baseDecoder)
- {
- Debug.Assert(chars!=null, "[UTF32Encoding.GetChars]chars!=null");
- Debug.Assert(bytes!=null, "[UTF32Encoding.GetChars]bytes!=null");
- Debug.Assert(byteCount >=0, "[UTF32Encoding.GetChars]byteCount >=0");
- Debug.Assert(charCount >=0, "[UTF32Encoding.GetChars]charCount >=0");
-
- UTF32Decoder decoder = (UTF32Decoder)baseDecoder;
-
- // None so far!
- char* charStart = chars;
- char* charEnd = chars + charCount;
-
- byte* byteStart = bytes;
- byte* byteEnd = bytes + byteCount;
-
- // See if there's anything in our decoder (but don't clear it yet)
- int readCount = 0;
- uint iChar = 0;
-
- // For fallback we may need a fallback buffer
- DecoderFallbackBuffer fallbackBuffer = null;
-
- // See if there's anything in our decoder
- if (decoder != null)
- {
- readCount = decoder.readByteCount;
- iChar = (uint)decoder.iChar;
- fallbackBuffer = baseDecoder.FallbackBuffer;
-
- // Shouldn't have anything in fallback buffer for GetChars
- // (don't have to check m_throwOnOverflow for chars)
- Debug.Assert(fallbackBuffer.Remaining == 0,
- "[UTF32Encoding.GetChars]Expected empty fallback buffer at start");
- }
- else
- {
- fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
- }
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(bytes, chars + charCount);
-
- // Loop through our input, 4 characters at a time!
- while (bytes < byteEnd)
- {
- // Get our next character
- if(bigEndian)
- {
- // Scoot left and add it to the bottom
- iChar <<= 8;
- iChar += *(bytes++);
- }
- else
- {
- // Scoot right and add it to the top
- iChar >>= 8;
- iChar += (uint)(*(bytes++)) << 24;
- }
-
- readCount++;
-
- // See if we have all the bytes yet
- if (readCount < 4)
- continue;
-
- // Have the bytes
- readCount = 0;
-
- // See if its valid to encode
- if ( iChar > 0x10FFFF || (iChar >= 0xD800 && iChar <= 0xDFFF))
- {
- // Need to fall back these 4 bytes
- byte[] fallbackBytes;
- if (this.bigEndian)
- {
- fallbackBytes = new byte[] {
- unchecked((byte)(iChar>>24)), unchecked((byte)(iChar>>16)),
- unchecked((byte)(iChar>>8)), unchecked((byte)(iChar)) };
- }
- else
- {
- fallbackBytes = new byte[] {
- unchecked((byte)(iChar)), unchecked((byte)(iChar>>8)),
- unchecked((byte)(iChar>>16)), unchecked((byte)(iChar>>24)) };
- }
-
- // Chars won't be updated unless this works.
- if (!fallbackBuffer.InternalFallback(fallbackBytes, bytes, ref chars))
- {
- // Couldn't fallback, throw or wait til next time
- // We either read enough bytes for bytes-=4 to work, or we're
- // going to throw in ThrowCharsOverflow because chars == charStart
- Debug.Assert(bytes >= byteStart + 4 || chars == charStart,
- "[UTF32Encoding.GetChars]Expected to have consumed bytes or throw (bad surrogate)");
- bytes-=4; // get back to where we were
- iChar=0; // Remembering nothing
- fallbackBuffer.InternalReset();
- ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
- break; // Stop here, didn't throw
- }
-
- // Ignore the illegal character
- iChar = 0;
- continue;
- }
-
-
- // Ok, we have something we can add to our output
- if (iChar >= 0x10000)
- {
- // Surrogates take 2
- if (chars >= charEnd - 1)
- {
- // Throwing or stopping
- // We either read enough bytes for bytes-=4 to work, or we're
- // going to throw in ThrowCharsOverflow because chars == charStart
- Debug.Assert(bytes >= byteStart + 4 || chars == charStart,
- "[UTF32Encoding.GetChars]Expected to have consumed bytes or throw (surrogate)");
- bytes-=4; // get back to where we were
- iChar=0; // Remembering nothing
- ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
- break; // Stop here, didn't throw
- }
-
- *(chars++) = GetHighSurrogate(iChar);
- iChar = GetLowSurrogate(iChar);
- }
- // Bounds check for normal character
- else if (chars >= charEnd)
- {
- // Throwing or stopping
- // We either read enough bytes for bytes-=4 to work, or we're
- // going to throw in ThrowCharsOverflow because chars == charStart
- Debug.Assert(bytes >= byteStart + 4 || chars == charStart,
- "[UTF32Encoding.GetChars]Expected to have consumed bytes or throw (normal char)");
- bytes-=4; // get back to where we were
- iChar=0; // Remembering nothing
- ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
- break; // Stop here, didn't throw
- }
-
- // Add the rest of the surrogate or our normal character
- *(chars++) = (char)iChar;
-
- // iChar is back to 0
- iChar = 0;
- }
-
- // See if we have something left over that has to be decoded
- if (readCount > 0 && (decoder == null || decoder.MustFlush))
- {
- // Oops, there's something left over with no place to go.
- byte[] fallbackBytes = new byte[readCount];
- int tempCount = readCount;
- if (this.bigEndian)
- {
- while(tempCount > 0)
- {
- fallbackBytes[--tempCount] = unchecked((byte)iChar);
- iChar >>= 8;
- }
- }
- else
- {
- while (tempCount > 0)
- {
- fallbackBytes[--tempCount] = unchecked((byte)(iChar>>24));
- iChar <<= 8;
- }
- }
-
- if (!fallbackBuffer.InternalFallback(fallbackBytes, bytes, ref chars))
- {
- // Couldn't fallback.
- fallbackBuffer.InternalReset();
- ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
- // Stop here, didn't throw, backed up, so still nothing in buffer
- }
- else
- {
- // Don't clear our decoder unless we could fall it back.
- // If we caught the if above, then we're a convert() and will catch this next time.
- readCount = 0;
- iChar = 0;
- }
- }
-
- // Remember any left over stuff, clearing buffer as well for MustFlush
- if (decoder != null)
- {
- decoder.iChar = (int)iChar;
- decoder.readByteCount = readCount;
- decoder.m_bytesUsed = (int)(bytes - byteStart);
- }
-
- // Shouldn't have anything in fallback buffer for GetChars
- // (don't have to check m_throwOnOverflow for chars)
- Debug.Assert(fallbackBuffer.Remaining == 0,
- "[UTF32Encoding.GetChars]Expected empty fallback buffer at end");
-
- // Return our count
- return (int)(chars - charStart);
- }
-
-
- private uint GetSurrogate(char cHigh, char cLow)
- {
- return (((uint)cHigh - 0xD800) * 0x400) + ((uint)cLow - 0xDC00) + 0x10000;
- }
-
- private char GetHighSurrogate(uint iChar)
- {
- return (char)((iChar - 0x10000) / 0x400 + 0xD800);
- }
-
- private char GetLowSurrogate(uint iChar)
- {
- return (char)((iChar - 0x10000) % 0x400 + 0xDC00);
- }
-
-
- public override Decoder GetDecoder()
- {
- return new UTF32Decoder(this);
- }
-
-
- public override Encoder GetEncoder()
- {
- return new EncoderNLS(this);
- }
-
-
- public override int GetMaxByteCount(int charCount)
- {
- if (charCount < 0)
- throw new ArgumentOutOfRangeException(nameof(charCount),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Characters would be # of characters + 1 in case left over high surrogate is ? * max fallback
- long byteCount = (long)charCount + 1;
-
- if (EncoderFallback.MaxCharCount > 1)
- byteCount *= EncoderFallback.MaxCharCount;
-
- // 4 bytes per char
- byteCount *= 4;
-
- if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
-
- return (int)byteCount;
- }
-
-
- public override int GetMaxCharCount(int byteCount)
- {
- if (byteCount < 0)
- throw new ArgumentOutOfRangeException(nameof(byteCount),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // A supplementary character becomes 2 surrogate characters, so 4 input bytes becomes 2 chars,
- // plus we may have 1 surrogate char left over if the decoder has 3 bytes in it already for a non-bmp char.
- // Have to add another one because 1/2 == 0, but 3 bytes left over could be 2 char surrogate pair
- int charCount = (byteCount / 2) + 2;
-
- // Also consider fallback because our input bytes could be out of range of unicode.
- // Since fallback would fallback 4 bytes at a time, we'll only fall back 1/2 of MaxCharCount.
- if (DecoderFallback.MaxCharCount > 2)
- {
- // Multiply time fallback size
- charCount *= DecoderFallback.MaxCharCount;
-
- // We were already figuring 2 chars per 4 bytes, but fallback will be different #
- charCount /= 2;
- }
-
- if (charCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
-
- return (int)charCount;
- }
-
-
- public override byte[] GetPreamble()
- {
- if (emitUTF32ByteOrderMark)
- {
- // Allocate new array to prevent users from modifying it.
- if (bigEndian)
- {
- return new byte[4] { 0x00, 0x00, 0xFE, 0xFF };
- }
- else
- {
- return new byte[4] { 0xFF, 0xFE, 0x00, 0x00 }; // 00 00 FE FF
- }
- }
- else
- return EmptyArray<Byte>.Value;
- }
-
-
- public override bool Equals(Object value)
- {
- UTF32Encoding that = value as UTF32Encoding;
- if (that != null)
- {
- return (emitUTF32ByteOrderMark == that.emitUTF32ByteOrderMark) &&
- (bigEndian == that.bigEndian) &&
-// (isThrowException == that.isThrowException) && // same as encoder/decoderfallback being exceptions
- (EncoderFallback.Equals(that.EncoderFallback)) &&
- (DecoderFallback.Equals(that.DecoderFallback));
- }
- return (false);
- }
-
-
- public override int GetHashCode()
- {
- //Not great distribution, but this is relatively unlikely to be used as the key in a hashtable.
- return this.EncoderFallback.GetHashCode() + this.DecoderFallback.GetHashCode() +
- CodePage + (emitUTF32ByteOrderMark?4:0) + (bigEndian?8:0);
- }
-
- [Serializable]
- internal class UTF32Decoder : DecoderNLS
- {
- // Need a place to store any extra bytes we may have picked up
- internal int iChar = 0;
- internal int readByteCount = 0;
-
- public UTF32Decoder(UTF32Encoding encoding) : base(encoding)
- {
- // base calls reset
- }
-
- public override void Reset()
- {
- this.iChar = 0;
- this.readByteCount = 0;
- if (m_fallbackBuffer != null)
- m_fallbackBuffer.Reset();
- }
-
- // Anything left in our decoder?
- internal override bool HasState
- {
- get
- {
- // ReadByteCount is our flag. (iChar==0 doesn't mean much).
- return (this.readByteCount != 0);
- }
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Text/UTF7Encoding.cs b/src/mscorlib/src/System/Text/UTF7Encoding.cs
index 9418d2e768..372af0da37 100644
--- a/src/mscorlib/src/System/Text/UTF7Encoding.cs
+++ b/src/mscorlib/src/System/Text/UTF7Encoding.cs
@@ -6,14 +6,13 @@
// Don't override IsAlwaysNormalized because it is just a Unicode Transformation and could be confused.
//
+using System;
+using System.Runtime.Serialization;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
namespace System.Text
{
- using System;
- using System.Runtime.Serialization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
-
[Serializable]
public class UTF7Encoding : Encoding
{
@@ -46,9 +45,9 @@ namespace System.Text
private bool[] directEncode;
[OptionalField(VersionAdded = 2)]
- private bool m_allowOptionals;
+ private bool m_allowOptionals;
- private const int UTF7_CODEPAGE=65000;
+ private const int UTF7_CODEPAGE = 65000;
public UTF7Encoding()
@@ -60,7 +59,7 @@ namespace System.Text
: base(UTF7_CODEPAGE) //Set the data item.
{
// Allowing optionals?
- this.m_allowOptionals = allowOptionals;
+ m_allowOptionals = allowOptionals;
// Make our tables
MakeTables();
@@ -81,7 +80,7 @@ namespace System.Text
directEncode[directChars[i]] = true;
}
- if (this.m_allowOptionals)
+ if (m_allowOptionals)
{
count = optionalChars.Length;
for (int i = 0; i < count; i++)
@@ -95,7 +94,7 @@ namespace System.Text
internal override void SetDefaultFallbacks()
{
// UTF7 had an odd decoderFallback behavior, and the Encoder fallback
- // is irrelevent because we encode surrogates individually and never check for unmatched ones
+ // is irrelevant because we encode surrogates individually and never check for unmatched ones
// (so nothing can fallback during encoding)
this.encoderFallback = new EncoderReplacementFallback(String.Empty);
this.decoderFallback = new DecoderUTF7Fallback();
@@ -144,43 +143,105 @@ namespace System.Text
return this.CodePage + this.EncoderFallback.GetHashCode() + this.DecoderFallback.GetHashCode();
}
- // NOTE: Many methods in this class forward to EncodingForwarder for
- // validating arguments/wrapping the unsafe methods in this class
- // which do the actual work. That class contains
- // shared logic for doing this which is used by
- // ASCIIEncoding, EncodingNLS, UnicodeEncoding, UTF32Encoding,
- // UTF7Encoding, and UTF8Encoding.
- // The reason the code is separated out into a static class, rather
- // than a base class which overrides all of these methods for us
- // (which is what EncodingNLS is for internal Encodings) is because
- // that's really more of an implementation detail so it's internal.
- // At the same time, C# doesn't allow a public class subclassing an
- // internal/private one, so we end up having to re-override these
- // methods in all of the public Encodings + EncodingNLS.
+ // The following methods are copied from EncodingNLS.cs.
+ // Unfortunately EncodingNLS.cs is internal and we're public, so we have to reimpliment them here.
+ // These should be kept in sync for the following classes:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
// Returns the number of bytes required to encode a range of characters in
// a character array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
- public override int GetByteCount(char[] chars, int index, int count)
+ public override unsafe int GetByteCount(char[] chars, int index, int count)
{
- return EncodingForwarder.GetByteCount(this, chars, index, count);
+ // Validate input parameters
+ if (chars == null)
+ throw new ArgumentNullException("chars", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (chars.Length - index < count)
+ throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // If no input, return 0, avoid fixed empty array problem
+ if (count == 0)
+ return 0;
+
+ // Just call the pointer version
+ fixed (char* pChars = chars)
+ return GetByteCount(pChars + index, count, null);
}
- public override int GetByteCount(String s)
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetByteCount(string s)
{
- return EncodingForwarder.GetByteCount(this, s);
+ // Validate input
+ if (s==null)
+ throw new ArgumentNullException("s");
+ Contract.EndContractBlock();
+
+ fixed (char* pChars = s)
+ return GetByteCount(pChars, s.Length, null);
}
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
[CLSCompliant(false)]
public override unsafe int GetByteCount(char* chars, int count)
{
- return EncodingForwarder.GetByteCount(this, chars, count);
+ // Validate Parameters
+ if (chars == null)
+ throw new ArgumentNullException("chars", SR.ArgumentNull_Array);
+
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ // Call it with empty encoder
+ return GetByteCount(chars, count, null);
}
- public override int GetBytes(String s, int charIndex, int charCount,
+ // Parent method is safe.
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
+ public override unsafe int GetBytes(string s, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- return EncodingForwarder.GetBytes(this, s, charIndex, charCount, bytes, byteIndex);
+ if (s == null || bytes == null)
+ throw new ArgumentNullException((s == null ? "s" : "bytes"), SR.ArgumentNull_Array);
+
+ if (charIndex < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? "charIndex" : "charCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (s.Length - charIndex < charCount)
+ throw new ArgumentOutOfRangeException("s", SR.ArgumentOutOfRange_IndexCount);
+
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ int byteCount = bytes.Length - byteIndex;
+
+ // Fixed doesn't like empty arrays
+ if (bytes.Length == 0)
+ bytes = new byte[1];
+
+ fixed (char* pChars = s) fixed (byte* pBytes = &bytes[0])
+ return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
}
// Encodes a range of characters in a character array into a range of bytes
@@ -191,59 +252,204 @@ namespace System.Text
// Alternatively, the GetMaxByteCount method can be used to
// determine the maximum number of bytes that will be produced for a given
// number of characters, regardless of the actual character values.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
- public override int GetBytes(char[] chars, int charIndex, int charCount,
+ public override unsafe int GetBytes(char[] chars, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
+ // Validate parameters
+ if (chars == null || bytes == null)
+ throw new ArgumentNullException((chars == null ? "chars" : "bytes"), SR.ArgumentNull_Array);
+
+ if (charIndex < 0 || charCount < 0)
+ throw new ArgumentOutOfRangeException((charIndex < 0 ? "charIndex" : "charCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (chars.Length - charIndex < charCount)
+ throw new ArgumentOutOfRangeException("chars", SR.ArgumentOutOfRange_IndexCountBuffer);
+
+ if (byteIndex < 0 || byteIndex > bytes.Length)
+ throw new ArgumentOutOfRangeException("byteIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ // If nothing to encode return 0, avoid fixed problem
+ if (charCount == 0)
+ return 0;
+
+ // Just call pointer version
+ int byteCount = bytes.Length - byteIndex;
+
+ // Fixed doesn't like empty arrays
+ if (bytes.Length == 0)
+ bytes = new byte[1];
+
+ fixed (char* pChars = chars) fixed (byte* pBytes = &bytes[0])
+ // Remember that byteCount is # to decode, not size of array.
+ return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
}
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
[CLSCompliant(false)]
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
{
- return EncodingForwarder.GetBytes(this, chars, charCount, bytes, byteCount);
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (charCount < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetBytes(chars, charCount, bytes, byteCount, null);
}
// Returns the number of characters produced by decoding a range of bytes
// in a byte array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
- public override int GetCharCount(byte[] bytes, int index, int count)
+ public override unsafe int GetCharCount(byte[] bytes, int index, int count)
{
- return EncodingForwarder.GetCharCount(this, bytes, index, count);
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (bytes.Length - index < count)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // If no input just return 0, fixed doesn't like 0 length arrays.
+ if (count == 0)
+ return 0;
+
+ // Just call pointer version
+ fixed (byte* pBytes = bytes)
+ return GetCharCount(pBytes + index, count, null);
}
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
[CLSCompliant(false)]
public override unsafe int GetCharCount(byte* bytes, int count)
{
- return EncodingForwarder.GetCharCount(this, bytes, count);
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count", SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetCharCount(bytes, count, null);
}
- public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
+
+ public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount,
char[] chars, int charIndex)
{
- return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (byteIndex < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((byteIndex < 0 ? "byteIndex" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if ( bytes.Length - byteIndex < byteCount)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+
+ if (charIndex < 0 || charIndex > chars.Length)
+ throw new ArgumentOutOfRangeException("charIndex", SR.ArgumentOutOfRange_Index);
+ Contract.EndContractBlock();
+
+ // If no input, return 0 & avoid fixed problem
+ if (byteCount == 0)
+ return 0;
+
+ // Just call pointer version
+ int charCount = chars.Length - charIndex;
+
+ // Fixed doesn't like empty arrays
+ if (chars.Length == 0)
+ chars = new char[1];
+
+ fixed (byte* pBytes = bytes) fixed (char* pChars = &chars[0])
+ // Remember that charCount is # to decode, not size of array
+ return GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, null);
}
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+
[CLSCompliant(false)]
public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
{
- return EncodingForwarder.GetChars(this, bytes, byteCount, chars, charCount);
+ // Validate Parameters
+ if (bytes == null || chars == null)
+ throw new ArgumentNullException(bytes == null ? "bytes" : "chars", SR.ArgumentNull_Array);
+
+ if (charCount < 0 || byteCount < 0)
+ throw new ArgumentOutOfRangeException((charCount < 0 ? "charCount" : "byteCount"), SR.ArgumentOutOfRange_NeedNonNegNum);
+ Contract.EndContractBlock();
+
+ return GetChars(bytes, byteCount, chars, charCount, null);
}
// Returns a string containing the decoded representation of a range of
// bytes in a byte array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
- public override String GetString(byte[] bytes, int index, int count)
+ public override unsafe String GetString(byte[] bytes, int index, int count)
{
- return EncodingForwarder.GetString(this, bytes, index, count);
+ // Validate Parameters
+ if (bytes == null)
+ throw new ArgumentNullException("bytes", SR.ArgumentNull_Array);
+
+ if (index < 0 || count < 0)
+ throw new ArgumentOutOfRangeException((index < 0 ? "index" : "count"), SR.ArgumentOutOfRange_NeedNonNegNum);
+
+ if (bytes.Length - index < count)
+ throw new ArgumentOutOfRangeException("bytes", SR.ArgumentOutOfRange_IndexCountBuffer);
+ Contract.EndContractBlock();
+
+ // Avoid problems with empty input buffer
+ if (count == 0) return String.Empty;
+
+ fixed (byte* pBytes = bytes)
+ return String.CreateStringFromEncoding(
+ pBytes + index, count, this);
}
-
- // End of overridden methods which use EncodingForwarder
+
+ //
+ // End of standard methods copied from EncodingNLS.cs
+ //
internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS baseEncoder)
{
- Debug.Assert(chars!=null, "[UTF7Encoding.GetByteCount]chars!=null");
- Debug.Assert(count >=0, "[UTF7Encoding.GetByteCount]count >=0");
+ Debug.Assert(chars != null, "[UTF7Encoding.GetByteCount]chars!=null");
+ Debug.Assert(count >= 0, "[UTF7Encoding.GetByteCount]count >=0");
// Just call GetBytes with bytes == null
return GetBytes(chars, count, null, 0, baseEncoder);
@@ -252,9 +458,9 @@ namespace System.Text
internal override unsafe int GetBytes(char* chars, int charCount,
byte* bytes, int byteCount, EncoderNLS baseEncoder)
{
- Debug.Assert(byteCount >=0, "[UTF7Encoding.GetBytes]byteCount >=0");
- Debug.Assert(chars!=null, "[UTF7Encoding.GetBytes]chars!=null");
- Debug.Assert(charCount >=0, "[UTF7Encoding.GetBytes]charCount >=0");
+ Debug.Assert(byteCount >= 0, "[UTF7Encoding.GetBytes]byteCount >=0");
+ Debug.Assert(chars != null, "[UTF7Encoding.GetBytes]chars!=null");
+ Debug.Assert(charCount >= 0, "[UTF7Encoding.GetBytes]charCount >=0");
// Get encoder info
UTF7Encoding.Encoder encoder = (UTF7Encoding.Encoder)baseEncoder;
@@ -339,7 +545,7 @@ namespace System.Text
{
bitCount += 6; // We didn't use these bits
currentChar = buffer.GetNextChar(); // We're processing this char still, but AddByte
- // --'d it when we ran out of space
+ // --'d it when we ran out of space
break; // Stop here, not enough room for bytes
}
}
@@ -391,8 +597,8 @@ namespace System.Text
internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
{
- Debug.Assert(count >=0, "[UTF7Encoding.GetCharCount]count >=0");
- Debug.Assert(bytes!=null, "[UTF7Encoding.GetCharCount]bytes!=null");
+ Debug.Assert(count >= 0, "[UTF7Encoding.GetCharCount]count >=0");
+ Debug.Assert(bytes != null, "[UTF7Encoding.GetCharCount]bytes!=null");
// Just call GetChars with null char* to do counting
return GetChars(bytes, count, null, 0, baseDecoder);
@@ -401,12 +607,12 @@ namespace System.Text
internal override unsafe int GetChars(byte* bytes, int byteCount,
char* chars, int charCount, DecoderNLS baseDecoder)
{
- Debug.Assert(byteCount >=0, "[UTF7Encoding.GetChars]byteCount >=0");
- Debug.Assert(bytes!=null, "[UTF7Encoding.GetChars]bytes!=null");
- Debug.Assert(charCount >=0, "[UTF7Encoding.GetChars]charCount >=0");
+ Debug.Assert(byteCount >= 0, "[UTF7Encoding.GetChars]byteCount >=0");
+ Debug.Assert(bytes != null, "[UTF7Encoding.GetChars]bytes!=null");
+ Debug.Assert(charCount >= 0, "[UTF7Encoding.GetChars]charCount >=0");
// Might use a decoder
- UTF7Encoding.Decoder decoder = (UTF7Encoding.Decoder) baseDecoder;
+ UTF7Encoding.Decoder decoder = (UTF7Encoding.Decoder)baseDecoder;
// Get our output buffer info.
Encoding.EncodingCharBuffer buffer = new Encoding.EncodingCharBuffer(
@@ -449,7 +655,7 @@ namespace System.Text
// Modified base 64 encoding.
//
sbyte v;
- if (currentByte < 0x80 && ((v = base64Values[currentByte]) >=0))
+ if (currentByte < 0x80 && ((v = base64Values[currentByte]) >= 0))
{
firstByte = false;
bits = (bits << 6) | ((byte)v);
@@ -581,8 +787,8 @@ namespace System.Text
public override int GetMaxByteCount(int charCount)
{
if (charCount < 0)
- throw new ArgumentOutOfRangeException(nameof(charCount),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(charCount),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
// Suppose that every char can not be direct-encoded, we know that
@@ -605,7 +811,7 @@ namespace System.Text
// check for overflow
if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
+ throw new ArgumentOutOfRangeException(nameof(charCount), SR.ArgumentOutOfRange_GetByteCountOverflow);
return (int)byteCount;
}
@@ -614,8 +820,8 @@ namespace System.Text
public override int GetMaxCharCount(int byteCount)
{
if (byteCount < 0)
- throw new ArgumentOutOfRangeException(nameof(byteCount),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(byteCount),
+ SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
// Worst case is 1 char per byte. Minimum 1 for left over bits in case decoder is being flushed
@@ -629,14 +835,16 @@ namespace System.Text
[Serializable]
// Of all the amazing things... This MUST be Decoder so that our com name
// for System.Text.Decoder doesn't change
- private class Decoder : DecoderNLS, ISerializable
+ private sealed class Decoder : DecoderNLS, ISerializable
{
/*private*/
internal int bits;
- /*private*/ internal int bitCount;
- /*private*/ internal bool firstByte;
+ /*private*/
+ internal int bitCount;
+ /*private*/
+ internal bool firstByte;
- public Decoder(UTF7Encoding encoding) : base (encoding)
+ public Decoder(UTF7Encoding encoding) : base(encoding)
{
// base calls reset
}
@@ -645,7 +853,7 @@ namespace System.Text
internal Decoder(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException(nameof(info));
+ if (info == null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// Get common info
@@ -659,7 +867,7 @@ namespace System.Text
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException(nameof(info));
+ if (info == null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// Save Whidbey data
@@ -693,11 +901,12 @@ namespace System.Text
[Serializable]
// Of all the amazing things... This MUST be Encoder so that our com name
// for System.Text.Encoder doesn't change
- private class Encoder : EncoderNLS, ISerializable
+ private sealed class Encoder : EncoderNLS, ISerializable
{
/*private*/
internal int bits;
- /*private*/ internal int bitCount;
+ /*private*/
+ internal int bitCount;
public Encoder(UTF7Encoding encoding) : base(encoding)
{
@@ -708,7 +917,7 @@ namespace System.Text
internal Encoder(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException(nameof(info));
+ if (info == null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// Get common info
@@ -721,7 +930,7 @@ namespace System.Text
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
// Any info?
- if (info==null) throw new ArgumentNullException(nameof(info));
+ if (info == null) throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
// Save Whidbey data
@@ -735,7 +944,7 @@ namespace System.Text
this.bitCount = -1;
this.bits = 0;
if (m_fallbackBuffer != null)
- m_fallbackBuffer.Reset();
+ m_fallbackBuffer.Reset();
}
// Anything left in our encoder?
@@ -751,7 +960,7 @@ namespace System.Text
// Preexisting UTF7 behavior for bad bytes was just to spit out the byte as the next char
// and turn off base64 mode if it was in that mode. We still exit the mode, but now we fallback.
[Serializable]
- internal sealed class DecoderUTF7Fallback : DecoderFallback
+ private sealed class DecoderUTF7Fallback : DecoderFallback
{
// Construction. Default replacement fallback uses no best fit and ? replacement string
public DecoderUTF7Fallback()
@@ -773,7 +982,7 @@ namespace System.Text
}
}
- public override bool Equals(Object value)
+ public override bool Equals(Object value)
{
DecoderUTF7Fallback that = value as DecoderUTF7Fallback;
if (that != null)
@@ -789,12 +998,12 @@ namespace System.Text
}
}
- internal sealed class DecoderUTF7FallbackBuffer : DecoderFallbackBuffer
+ private sealed class DecoderUTF7FallbackBuffer : DecoderFallbackBuffer
{
// Store our default string
- char cFallback = (char)0;
- int iCount = -1;
- int iSize;
+ private char cFallback = (char)0;
+ private int iCount = -1;
+ private int iSize;
// Construction
public DecoderUTF7FallbackBuffer(DecoderUTF7Fallback fallback)
@@ -855,7 +1064,7 @@ namespace System.Text
public override unsafe void Reset()
{
iCount = -1;
- byteStart = null;
+ byteStart = null;
}
// This version just counts the fallback and doesn't actually copy anything.
@@ -867,13 +1076,12 @@ namespace System.Text
Debug.Assert(iCount < 0, "[DecoderUTF7FallbackBuffer.InternalFallback] Can't have recursive fallbacks");
if (bytes.Length != 1)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"));
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex);
}
// Can't fallback a byte 0, so return for that case, 1 otherwise.
return bytes[0] == 0 ? 0 : 1;
}
}
-
}
}
diff --git a/src/mscorlib/src/System/Text/UTF8Encoding.cs b/src/mscorlib/src/System/Text/UTF8Encoding.cs
deleted file mode 100644
index 191bbfef56..0000000000
--- a/src/mscorlib/src/System/Text/UTF8Encoding.cs
+++ /dev/null
@@ -1,2286 +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.
-
-
-// The worker functions in this file was optimized for performance. If you make changes
-// you should use care to consider all of the interesting cases.
-
-// The code of all worker functions in this file is written twice: Once as as a slow loop, and the
-// second time as a fast loop. The slow loops handles all special cases, throws exceptions, etc.
-// The fast loops attempts to blaze through as fast as possible with optimistic range checks,
-// processing multiple characters at a time, and falling back to the slow loop for all special cases.
-
-// This define can be used to turn off the fast loops. Useful for finding whether
-// the problem is fastloop-specific.
-#define FASTLOOP
-
-namespace System.Text
-{
- using System;
- using System.Globalization;
- using System.Runtime.Serialization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- // Encodes text into and out of UTF-8. UTF-8 is a way of writing
- // Unicode characters with variable numbers of bytes per character,
- // optimized for the lower 127 ASCII characters. It's an efficient way
- // of encoding US English in an internationalizable way.
- //
- // Don't override IsAlwaysNormalized because it is just a Unicode Transformation and could be confused.
- //
- // The UTF-8 byte order mark is simply the Unicode byte order mark
- // (0xFEFF) written in UTF-8 (0xEF 0xBB 0xBF). The byte order mark is
- // used mostly to distinguish UTF-8 text from other encodings, and doesn't
- // switch the byte orderings.
-
- [Serializable]
- public class UTF8Encoding : Encoding
- {
- /*
- bytes bits UTF-8 representation
- ----- ---- -----------------------------------
- 1 7 0vvvvvvv
- 2 11 110vvvvv 10vvvvvv
- 3 16 1110vvvv 10vvvvvv 10vvvvvv
- 4 21 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv
- ----- ---- -----------------------------------
-
- Surrogate:
- Real Unicode value = (HighSurrogate - 0xD800) * 0x400 + (LowSurrogate - 0xDC00) + 0x10000
- */
-
- private const int UTF8_CODEPAGE=65001;
-
- // Used by Encoding.UTF8 for lazy initialization
- // The initialization code will not be run until a static member of the class is referenced
- internal static readonly UTF8Encoding s_default = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true);
-
- // Yes, the idea of emitting U+FEFF as a UTF-8 identifier has made it into
- // the standard.
- private bool emitUTF8Identifier = false;
-
- private bool isThrowException = false;
-
-
- public UTF8Encoding(): this(false)
- {
- }
-
-
- public UTF8Encoding(bool encoderShouldEmitUTF8Identifier):
- this(encoderShouldEmitUTF8Identifier, false)
- {
- }
-
-
- public UTF8Encoding(bool encoderShouldEmitUTF8Identifier, bool throwOnInvalidBytes):
- base(UTF8_CODEPAGE)
- {
- this.emitUTF8Identifier = encoderShouldEmitUTF8Identifier;
- this.isThrowException = throwOnInvalidBytes;
-
- // Encoding's constructor already did this, but it'll be wrong if we're throwing exceptions
- if (this.isThrowException)
- SetDefaultFallbacks();
- }
-
- internal override void SetDefaultFallbacks()
- {
- // For UTF-X encodings, we use a replacement fallback with an empty string
- if (this.isThrowException)
- {
- this.encoderFallback = EncoderFallback.ExceptionFallback;
- this.decoderFallback = DecoderFallback.ExceptionFallback;
- }
- else
- {
- this.encoderFallback = new EncoderReplacementFallback("\xFFFD");
- this.decoderFallback = new DecoderReplacementFallback("\xFFFD");
- }
- }
-
- // NOTE: Many methods in this class forward to EncodingForwarder for
- // validating arguments/wrapping the unsafe methods in this class
- // which do the actual work. That class contains
- // shared logic for doing this which is used by
- // ASCIIEncoding, EncodingNLS, UnicodeEncoding, UTF32Encoding,
- // UTF7Encoding, and UTF8Encoding.
- // The reason the code is separated out into a static class, rather
- // than a base class which overrides all of these methods for us
- // (which is what EncodingNLS is for internal Encodings) is because
- // that's really more of an implementation detail so it's internal.
- // At the same time, C# doesn't allow a public class subclassing an
- // internal/private one, so we end up having to re-override these
- // methods in all of the public Encodings + EncodingNLS.
-
- // Returns the number of bytes required to encode a range of characters in
- // a character array.
-
- public override int GetByteCount(char[] chars, int index, int count)
- {
- return EncodingForwarder.GetByteCount(this, chars, index, count);
- }
-
- public override int GetByteCount(String chars)
- {
- return EncodingForwarder.GetByteCount(this, chars);
- }
-
- [CLSCompliant(false)]
- public override unsafe int GetByteCount(char* chars, int count)
- {
- return EncodingForwarder.GetByteCount(this, chars, count);
- }
-
- public override int GetBytes(String s, int charIndex, int charCount,
- byte[] bytes, int byteIndex)
- {
- return EncodingForwarder.GetBytes(this, s, charIndex, charCount, bytes, byteIndex);
- }
-
- // Encodes a range of characters in a character array into a range of bytes
- // in a byte array. An exception occurs if the byte array is not large
- // enough to hold the complete encoding of the characters. The
- // GetByteCount method can be used to determine the exact number of
- // bytes that will be produced for a given range of characters.
- // Alternatively, the GetMaxByteCount method can be used to
- // determine the maximum number of bytes that will be produced for a given
- // number of characters, regardless of the actual character values.
-
- public override int GetBytes(char[] chars, int charIndex, int charCount,
- byte[] bytes, int byteIndex)
- {
- return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
- }
-
- [CLSCompliant(false)]
- public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
- {
- return EncodingForwarder.GetBytes(this, chars, charCount, bytes, byteCount);
- }
-
- // Returns the number of characters produced by decoding a range of bytes
- // in a byte array.
-
- public override int GetCharCount(byte[] bytes, int index, int count)
- {
- return EncodingForwarder.GetCharCount(this, bytes, index, count);
- }
-
- [CLSCompliant(false)]
- public override unsafe int GetCharCount(byte* bytes, int count)
- {
- return EncodingForwarder.GetCharCount(this, bytes, count);
- }
-
- public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
- char[] chars, int charIndex)
- {
- return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
- }
-
- [CLSCompliant(false)]
- public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
- {
- return EncodingForwarder.GetChars(this, bytes, byteCount, chars, charCount);
- }
-
- // Returns a string containing the decoded representation of a range of
- // bytes in a byte array.
-
- public override String GetString(byte[] bytes, int index, int count)
- {
- return EncodingForwarder.GetString(this, bytes, index, count);
- }
-
- // End of overridden methods which use EncodingForwarder
-
- // To simplify maintenance, the structure of GetByteCount and GetBytes should be
- // kept the same as much as possible
- internal override unsafe int GetByteCount(char *chars, int count, EncoderNLS baseEncoder)
- {
- // For fallback we may need a fallback buffer.
- // We wait to initialize it though in case we don't have any broken input unicode
- EncoderFallbackBuffer fallbackBuffer = null;
- char *pSrc = chars;
- char *pEnd = pSrc+count;
-
- // Start by assuming we have as many as count
- int byteCount = count;
-
- int ch = 0;
-
- if (baseEncoder != null) {
- UTF8Encoder encoder = (UTF8Encoder)baseEncoder;
- ch = encoder.surrogateChar;
-
- // We mustn't have left over fallback data when counting
- if (encoder.InternalHasFallbackBuffer)
- {
- fallbackBuffer = encoder.FallbackBuffer;
- if (fallbackBuffer.Remaining > 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EncoderFallbackNotEmpty",
- this.EncodingName, encoder.Fallback.GetType()));
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(chars, pEnd, encoder, false);
- }
- }
-
- for (;;) {
- // SLOWLOOP: does all range checks, handles all special cases, but it is slow
- if (pSrc >= pEnd) {
-
- if (ch == 0) {
- // Unroll any fallback that happens at the end
- ch = fallbackBuffer != null ? fallbackBuffer.InternalGetNextChar() : 0;
- if (ch > 0) {
- byteCount++;
- goto ProcessChar;
- }
- } else {
- // Case of surrogates in the fallback.
- if (fallbackBuffer != null && fallbackBuffer.bFallingBack) {
- Debug.Assert(ch >= 0xD800 && ch <= 0xDBFF,
- "[UTF8Encoding.GetBytes]expected high surrogate, not 0x" + ((int)ch).ToString("X4", CultureInfo.InvariantCulture));
-
- ch = fallbackBuffer.InternalGetNextChar();
- byteCount++;
-
- if (InRange(ch, CharUnicodeInfo.LOW_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END)) {
- ch = 0xfffd;
- byteCount++;
- goto EncodeChar;
- } else if (ch > 0){
- goto ProcessChar;
- } else {
- byteCount--; // ignore last one.
- break;
- }
- }
- }
-
- if (ch <= 0) {
- break;
- }
- if (baseEncoder != null && !baseEncoder.MustFlush) {
- break;
- }
-
- // attempt to encode the partial surrogate (will fallback or ignore it), it'll also subtract 1.
- byteCount++;
- goto EncodeChar;
- }
-
- if (ch > 0) {
- Debug.Assert(ch >= 0xD800 && ch <= 0xDBFF,
- "[UTF8Encoding.GetBytes]expected high surrogate, not 0x" + ((int)ch).ToString("X4", CultureInfo.InvariantCulture));
-
- // use separate helper variables for local contexts so that the jit optimizations
- // won't get confused about the variable lifetimes
- int cha = *pSrc;
-
- // count the pending surrogate
- byteCount++;
-
- // In previous byte, we encountered a high surrogate, so we are expecting a low surrogate here.
- // if (IsLowSurrogate(cha)) {
- if (InRange(cha, CharUnicodeInfo.LOW_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END)) {
- // Don't need a real # because we're just counting, anything > 0x7ff ('cept surrogate) will do.
- ch = 0xfffd;
-// ch = cha + (ch << 10) +
-// (0x10000
-// - CharUnicodeInfo.LOW_SURROGATE_START
-// - (CharUnicodeInfo.HIGH_SURROGATE_START << 10) );
-
- // Use this next char
- pSrc++;
- }
- // else ch is still high surrogate and encoding will fail (so don't add count)
-
- // attempt to encode the surrogate or partial surrogate
- goto EncodeChar;
- }
-
- // If we've used a fallback, then we have to check for it
- if (fallbackBuffer != null)
- {
- ch = fallbackBuffer.InternalGetNextChar();
- if (ch > 0)
- {
- // We have an extra byte we weren't expecting.
- byteCount++;
- goto ProcessChar;
- }
- }
-
- // read next char. The JIT optimization seems to be getting confused when
- // compiling "ch = *pSrc++;", so rather use "ch = *pSrc; pSrc++;" instead
- ch = *pSrc;
- pSrc++;
-
- ProcessChar:
- // if (IsHighSurrogate(ch)) {
- if (InRange(ch, CharUnicodeInfo.HIGH_SURROGATE_START, CharUnicodeInfo.HIGH_SURROGATE_END)) {
- // we will count this surrogate next time around
- byteCount--;
- continue;
- }
- // either good char or partial surrogate
-
- EncodeChar:
- // throw exception on partial surrogate if necessary
- // if (IsLowSurrogate(ch) || IsHighSurrogate(ch))
- if (InRange(ch, CharUnicodeInfo.HIGH_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END))
- {
- // Lone surrogates aren't allowed
- // Have to make a fallback buffer if we don't have one
- if (fallbackBuffer == null)
- {
- // wait on fallbacks if we can
- // For fallback we may need a fallback buffer
- if (baseEncoder == null)
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = baseEncoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(chars, chars + count, baseEncoder, false);
- }
-
- // Do our fallback. Actually we already know its a mixed up surrogate,
- // so the ref pSrc isn't gonna do anything.
- fallbackBuffer.InternalFallback(unchecked((char)ch), ref pSrc);
-
- // Ignore it if we don't throw (we had preallocated this ch)
- byteCount--;
- ch = 0;
- continue;
- }
-
- // Count them
- if (ch > 0x7F) {
- if (ch > 0x7FF) {
- // the extra surrogate byte was compensated by the second surrogate character
- // (2 surrogates make 4 bytes. We've already counted 2 bytes, 1 per char)
- byteCount++;
- }
- byteCount++;
- }
-
-#if BIT64
- // check for overflow
- if (byteCount < 0) {
- break;
- }
-#endif
-
-#if FASTLOOP
- // If still have fallback don't do fast loop
- if (fallbackBuffer != null && (ch = fallbackBuffer.InternalGetNextChar()) != 0)
- {
- // We're reserving 1 byte for each char by default
- byteCount++;
- goto ProcessChar;
- }
-
- int availableChars = PtrDiff(pEnd, pSrc);
-
- // don't fall into the fast decoding loop if we don't have enough characters
- if (availableChars <= 13) {
- // try to get over the remainder of the ascii characters fast though
- char* pLocalEnd = pEnd; // hint to get pLocalEnd enregistered
- while (pSrc < pLocalEnd) {
- ch = *pSrc;
- pSrc++;
- if (ch > 0x7F)
- goto ProcessChar;
- }
-
- // we are done
- break;
- }
-
-#if BIT64
- // make sure that we won't get a silent overflow inside the fast loop
- // (Fall out to slow loop if we have this many characters)
- availableChars &= 0x0FFFFFFF;
-#endif
-
- // To compute the upper bound, assume that all characters are ASCII characters at this point,
- // the boundary will be decreased for every non-ASCII character we encounter
- // Also, we need 3 + 4 chars reserve for the unrolled ansi decoding loop and for decoding of surrogates
- char *pStop = pSrc + availableChars - (3 + 4);
-
- while (pSrc < pStop) {
- ch = *pSrc;
- pSrc++;
-
- if (ch > 0x7F) // Not ASCII
- {
- if (ch > 0x7FF) // Not 2 Byte
- {
- if ((ch & 0xF800) == 0xD800) // See if its a Surrogate
- goto LongCode;
- byteCount++;
- }
- byteCount ++;
- }
-
- // get pSrc aligned
- if ((unchecked((int)pSrc) & 0x2) != 0) {
- ch = *pSrc;
- pSrc++;
- if (ch > 0x7F) // Not ASCII
- {
- if (ch > 0x7FF) // Not 2 Byte
- {
- if ((ch & 0xF800) == 0xD800) // See if its a Surrogate
- goto LongCode;
- byteCount++;
- }
- byteCount ++;
- }
- }
-
- // Run 2 * 4 characters at a time!
- while (pSrc < pStop) {
- ch = *(int*)pSrc;
- int chc = *(int*)(pSrc+2);
- if (((ch | chc) & unchecked((int)0xFF80FF80)) != 0) // See if not ASCII
- {
- if (((ch | chc) & unchecked((int)0xF800F800)) != 0) // See if not 2 Byte
- {
- goto LongCodeWithMask;
- }
-
-
- if ((ch & unchecked((int)0xFF800000)) != 0) // Actually 0x07800780 is all we care about (4 bits)
- byteCount++;
- if ((ch & unchecked((int)0xFF80)) != 0)
- byteCount++;
- if ((chc & unchecked((int)0xFF800000)) != 0)
- byteCount++;
- if ((chc & unchecked((int)0xFF80)) != 0)
- byteCount++;
- }
- pSrc += 4;
-
- ch = *(int*)pSrc;
- chc = *(int*)(pSrc+2);
- if (((ch | chc) & unchecked((int)0xFF80FF80)) != 0) // See if not ASCII
- {
- if (((ch | chc) & unchecked((int)0xF800F800)) != 0) // See if not 2 Byte
- {
- goto LongCodeWithMask;
- }
-
- if ((ch & unchecked((int)0xFF800000)) != 0)
- byteCount++;
- if ((ch & unchecked((int)0xFF80)) != 0)
- byteCount++;
- if ((chc & unchecked((int)0xFF800000)) != 0)
- byteCount++;
- if ((chc & unchecked((int)0xFF80)) != 0)
- byteCount++;
- }
- pSrc += 4;
- }
- break;
-
- LongCodeWithMask:
-#if BIGENDIAN
- // be careful about the sign extension
- ch = (int)(((uint)ch) >> 16);
-#else // BIGENDIAN
- ch = (char)ch;
-#endif // BIGENDIAN
- pSrc++;
-
- if (ch <= 0x7F) {
- continue;
- }
-
- LongCode:
- // use separate helper variables for slow and fast loop so that the jit optimizations
- // won't get confused about the variable lifetimes
- if (ch > 0x7FF) {
- // if (IsLowSurrogate(ch) || IsHighSurrogate(ch))
- if (InRange(ch, CharUnicodeInfo.HIGH_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END)) {
- // 4 byte encoding - high surrogate + low surrogate
-
- int chd = *pSrc;
- if (
- // !IsHighSurrogate(ch) // low without high -> bad
- ch > CharUnicodeInfo.HIGH_SURROGATE_END ||
- // !IsLowSurrogate(chd) // high not followed by low -> bad
- !InRange(chd, CharUnicodeInfo.LOW_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END) )
- {
- // Back up and drop out to slow loop to figure out error
- pSrc--;
- break;
- }
- pSrc++;
-
- // byteCount - this byte is compensated by the second surrogate character
- }
- byteCount++;
- }
- byteCount++;
-
- // byteCount - the last byte is already included
- }
-#endif // FASTLOOP
-
- // no pending char at this point
- ch = 0;
- }
-
-#if BIT64
- // check for overflow
- if (byteCount < 0) {
- throw new ArgumentException(
- Environment.GetResourceString("Argument_ConversionOverflow"));
- }
-#endif
-
- Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
- "[UTF8Encoding.GetByteCount]Expected Empty fallback buffer");
-
- return byteCount;
- }
-
- // diffs two char pointers using unsigned arithmetic. The unsigned arithmetic
- // is good enough for us, and it tends to generate better code than the signed
- // arithmetic generated by default
- unsafe private static int PtrDiff(char *a, char* b)
- {
- return (int)(((uint)((byte*)a - (byte*)b)) >> 1);
- }
-
- // byte* flavor just for parity
- unsafe private static int PtrDiff(byte* a, byte* b)
- {
- return (int)(a - b);
- }
-
- private static bool InRange(int ch, int start, int end)
- {
- return (uint)(ch - start) <= (uint)(end - start);
- }
-
- // Our workhorse
- // Note: We ignore mismatched surrogates, unless the exception flag is set in which case we throw
- internal override unsafe int GetBytes(char* chars, int charCount,
- byte* bytes, int byteCount, EncoderNLS baseEncoder)
- {
- Debug.Assert(chars!=null, "[UTF8Encoding.GetBytes]chars!=null");
- Debug.Assert(byteCount >=0, "[UTF8Encoding.GetBytes]byteCount >=0");
- Debug.Assert(charCount >=0, "[UTF8Encoding.GetBytes]charCount >=0");
- Debug.Assert(bytes!=null, "[UTF8Encoding.GetBytes]bytes!=null");
-
- UTF8Encoder encoder = null;
-
- // For fallback we may need a fallback buffer.
- // We wait to initialize it though in case we don't have any broken input unicode
- EncoderFallbackBuffer fallbackBuffer = null;
- char *pSrc = chars;
- byte *pTarget = bytes;
-
- char *pEnd = pSrc+charCount;
- byte *pAllocatedBufferEnd = pTarget+byteCount;
-
- int ch = 0;
-
- // assume that JIT will enregister pSrc, pTarget and ch
-
- if (baseEncoder != null) {
- encoder = (UTF8Encoder)baseEncoder;
- ch = encoder.surrogateChar;
-
- // We mustn't have left over fallback data when counting
- if (encoder.InternalHasFallbackBuffer)
- {
- // We always need the fallback buffer in get bytes so we can flush any remaining ones if necessary
- fallbackBuffer = encoder.FallbackBuffer;
- if (fallbackBuffer.Remaining > 0 && encoder.m_throwOnOverflow)
- throw new ArgumentException(Environment.GetResourceString("Argument_EncoderFallbackNotEmpty",
- this.EncodingName, encoder.Fallback.GetType()));
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(chars, pEnd, encoder, true);
- }
- }
-
- for (;;) {
- // SLOWLOOP: does all range checks, handles all special cases, but it is slow
-
- if (pSrc >= pEnd) {
-
- if (ch == 0) {
- // Check if there's anthing left to get out of the fallback buffer
- ch = fallbackBuffer != null ? fallbackBuffer.InternalGetNextChar() : 0;
- if (ch > 0) {
- goto ProcessChar;
- }
- } else {
- // Case of leftover surrogates in the fallback buffer
- if (fallbackBuffer != null && fallbackBuffer.bFallingBack) {
- Debug.Assert(ch >= 0xD800 && ch <= 0xDBFF,
- "[UTF8Encoding.GetBytes]expected high surrogate, not 0x" + ((int)ch).ToString("X4", CultureInfo.InvariantCulture));
-
- int cha = ch;
-
- ch = fallbackBuffer.InternalGetNextChar();
-
- if (InRange(ch, CharUnicodeInfo.LOW_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END)) {
- ch = ch + (cha << 10) + (0x10000 - CharUnicodeInfo.LOW_SURROGATE_START - (CharUnicodeInfo.HIGH_SURROGATE_START << 10));
- goto EncodeChar;
- } else if (ch > 0){
- goto ProcessChar;
- } else {
- break;
- }
- }
- }
-
- // attempt to encode the partial surrogate (will fail or ignore)
- if (ch > 0 && (encoder == null || encoder.MustFlush))
- goto EncodeChar;
-
- // We're done
- break;
- }
-
- if (ch > 0) {
- // We have a high surrogate left over from a previous loop.
- Debug.Assert(ch >= 0xD800 && ch <= 0xDBFF,
- "[UTF8Encoding.GetBytes]expected high surrogate, not 0x" + ((int)ch).ToString("X4", CultureInfo.InvariantCulture));
-
- // use separate helper variables for local contexts so that the jit optimizations
- // won't get confused about the variable lifetimes
- int cha = *pSrc;
-
- // In previous byte, we encountered a high surrogate, so we are expecting a low surrogate here.
- // if (IsLowSurrogate(cha)) {
- if (InRange(cha, CharUnicodeInfo.LOW_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END)) {
- ch = cha + (ch << 10) +
- (0x10000
- - CharUnicodeInfo.LOW_SURROGATE_START
- - (CharUnicodeInfo.HIGH_SURROGATE_START << 10) );
-
- pSrc++;
- }
- // else ch is still high surrogate and encoding will fail
-
- // attempt to encode the surrogate or partial surrogate
- goto EncodeChar;
- }
-
- // If we've used a fallback, then we have to check for it
- if (fallbackBuffer != null)
- {
- ch = fallbackBuffer.InternalGetNextChar();
- if (ch > 0) goto ProcessChar;
- }
-
- // read next char. The JIT optimization seems to be getting confused when
- // compiling "ch = *pSrc++;", so rather use "ch = *pSrc; pSrc++;" instead
- ch = *pSrc;
- pSrc++;
-
- ProcessChar:
- // if (IsHighSurrogate(ch)) {
- if (InRange(ch, CharUnicodeInfo.HIGH_SURROGATE_START, CharUnicodeInfo.HIGH_SURROGATE_END)) {
- continue;
- }
- // either good char or partial surrogate
-
- EncodeChar:
- // throw exception on partial surrogate if necessary
- // if (IsLowSurrogate(ch) || IsHighSurrogate(ch))
- if (InRange(ch, CharUnicodeInfo.HIGH_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END))
- {
- // Lone surrogates aren't allowed, we have to do fallback for them
- // Have to make a fallback buffer if we don't have one
- if (fallbackBuffer == null)
- {
- // wait on fallbacks if we can
- // For fallback we may need a fallback buffer
- if (baseEncoder == null)
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = baseEncoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(chars, pEnd, baseEncoder, true);
- }
-
- // Do our fallback. Actually we already know its a mixed up surrogate,
- // so the ref pSrc isn't gonna do anything.
- fallbackBuffer.InternalFallback(unchecked((char)ch), ref pSrc);
-
- // Ignore it if we don't throw
- ch = 0;
- continue;
- }
-
- // Count bytes needed
- int bytesNeeded = 1;
- if (ch > 0x7F) {
- if (ch > 0x7FF) {
- if (ch > 0xFFFF) {
- bytesNeeded++; // 4 bytes (surrogate pair)
- }
- bytesNeeded++; // 3 bytes (800-FFFF)
- }
- bytesNeeded++; // 2 bytes (80-7FF)
- }
-
- if (pTarget > pAllocatedBufferEnd - bytesNeeded) {
- // Left over surrogate from last time will cause pSrc == chars, so we'll throw
- if (fallbackBuffer != null && fallbackBuffer.bFallingBack)
- {
- fallbackBuffer.MovePrevious(); // Didn't use this fallback char
- if (ch > 0xFFFF)
- fallbackBuffer.MovePrevious(); // Was surrogate, didn't use 2nd part either
- }
- else
- {
- pSrc--; // Didn't use this char
- if (ch > 0xFFFF)
- pSrc--; // Was surrogate, didn't use 2nd part either
- }
- Debug.Assert(pSrc >= chars || pTarget == bytes,
- "[UTF8Encoding.GetBytes]Expected pSrc to be within buffer or to throw with insufficient room.");
- ThrowBytesOverflow(encoder, pTarget == bytes); // Throw if we must
- ch = 0; // Nothing left over (we backed up to start of pair if supplimentary)
- break;
- }
-
- if (ch <= 0x7F) {
- *pTarget = (byte)ch;
- }
- else {
- // use separate helper variables for local contexts so that the jit optimizations
- // won't get confused about the variable lifetimes
- int chb;
- if (ch <= 0x7FF) {
- // 2 byte encoding
- chb = (byte)(unchecked((sbyte)0xC0) | (ch >> 6));
- }
- else
- {
- if (ch <= 0xFFFF) {
- chb = (byte)(unchecked((sbyte)0xE0) | (ch >> 12));
- }
- else
- {
- *pTarget = (byte)(unchecked((sbyte)0xF0) | (ch >> 18));
- pTarget++;
-
- chb = unchecked((sbyte)0x80) | (ch >> 12) & 0x3F;
- }
- *pTarget = (byte)chb;
- pTarget++;
-
- chb = unchecked((sbyte)0x80) | (ch >> 6) & 0x3F;
- }
- *pTarget = (byte)chb;
- pTarget++;
-
- *pTarget = (byte)(unchecked((sbyte)0x80) | ch & 0x3F);
- }
- pTarget++;
-
-
-#if FASTLOOP
- // If still have fallback don't do fast loop
- if (fallbackBuffer != null && (ch = fallbackBuffer.InternalGetNextChar()) != 0)
- goto ProcessChar;
-
- int availableChars = PtrDiff(pEnd, pSrc);
- int availableBytes = PtrDiff(pAllocatedBufferEnd, pTarget);
-
- // don't fall into the fast decoding loop if we don't have enough characters
- // Note that if we don't have enough bytes, pStop will prevent us from entering the fast loop.
- if (availableChars <= 13) {
- // we are hoping for 1 byte per char
- if (availableBytes < availableChars) {
- // not enough output room. no pending bits at this point
- ch = 0;
- continue;
- }
-
- // try to get over the remainder of the ascii characters fast though
- char* pLocalEnd = pEnd; // hint to get pLocalEnd enregistered
- while (pSrc < pLocalEnd) {
- ch = *pSrc;
- pSrc++;
-
- // Not ASCII, need more than 1 byte per char
- if (ch > 0x7F)
- goto ProcessChar;
-
- *pTarget = (byte)ch;
- pTarget++;
- }
- // we are done, let ch be 0 to clear encoder
- ch = 0;
- break;
- }
-
- // we need at least 1 byte per character, but Convert might allow us to convert
- // only part of the input, so try as much as we can. Reduce charCount if necessary
- if (availableBytes < availableChars)
- {
- availableChars = availableBytes;
- }
-
- // FASTLOOP:
- // - optimistic range checks
- // - fallbacks to the slow loop for all special cases, exception throwing, etc.
-
- // To compute the upper bound, assume that all characters are ASCII characters at this point,
- // the boundary will be decreased for every non-ASCII character we encounter
- // Also, we need 5 chars reserve for the unrolled ansi decoding loop and for decoding of surrogates
- // If there aren't enough bytes for the output, then pStop will be <= pSrc and will bypass the loop.
- char *pStop = pSrc + availableChars - 5;
-
- while (pSrc < pStop) {
- ch = *pSrc;
- pSrc++;
-
- if (ch > 0x7F) {
- goto LongCode;
- }
- *pTarget = (byte)ch;
- pTarget++;
-
- // get pSrc aligned
- if ((unchecked((int)pSrc) & 0x2) != 0) {
- ch = *pSrc;
- pSrc++;
- if (ch > 0x7F) {
- goto LongCode;
- }
- *pTarget = (byte)ch;
- pTarget++;
- }
-
- // Run 4 characters at a time!
- while (pSrc < pStop) {
- ch = *(int*)pSrc;
- int chc = *(int*)(pSrc+2);
- if (((ch | chc) & unchecked((int)0xFF80FF80)) != 0) {
- goto LongCodeWithMask;
- }
-
- // Unfortunately, this is endianess sensitive
-#if BIGENDIAN
- *pTarget = (byte)(ch>>16);
- *(pTarget+1) = (byte)ch;
- pSrc += 4;
- *(pTarget+2) = (byte)(chc>>16);
- *(pTarget+3) = (byte)chc;
- pTarget += 4;
-#else // BIGENDIAN
- *pTarget = (byte)ch;
- *(pTarget+1) = (byte)(ch>>16);
- pSrc += 4;
- *(pTarget+2) = (byte)chc;
- *(pTarget+3) = (byte)(chc>>16);
- pTarget += 4;
-#endif // BIGENDIAN
- }
- continue;
-
- LongCodeWithMask:
-#if BIGENDIAN
- // be careful about the sign extension
- ch = (int)(((uint)ch) >> 16);
-#else // BIGENDIAN
- ch = (char)ch;
-#endif // BIGENDIAN
- pSrc++;
-
- if (ch > 0x7F) {
- goto LongCode;
- }
- *pTarget = (byte)ch;
- pTarget++;
- continue;
-
- LongCode:
- // use separate helper variables for slow and fast loop so that the jit optimizations
- // won't get confused about the variable lifetimes
- int chd;
- if (ch <= 0x7FF) {
- // 2 byte encoding
- chd = unchecked((sbyte)0xC0) | (ch >> 6);
- }
- else {
- // if (!IsLowSurrogate(ch) && !IsHighSurrogate(ch))
- if (!InRange(ch, CharUnicodeInfo.HIGH_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END)) {
- // 3 byte encoding
- chd = unchecked((sbyte)0xE0) | (ch >> 12);
- }
- else
- {
- // 4 byte encoding - high surrogate + low surrogate
- // if (!IsHighSurrogate(ch))
- if (ch > CharUnicodeInfo.HIGH_SURROGATE_END) {
- // low without high -> bad, try again in slow loop
- pSrc -= 1;
- break;
- }
-
- chd = *pSrc;
- pSrc++;
-
- // if (!IsLowSurrogate(chd)) {
- if (!InRange(chd, CharUnicodeInfo.LOW_SURROGATE_START, CharUnicodeInfo.LOW_SURROGATE_END)) {
- // high not followed by low -> bad, try again in slow loop
- pSrc -= 2;
- break;
- }
-
- ch = chd + (ch << 10) +
- (0x10000
- - CharUnicodeInfo.LOW_SURROGATE_START
- - (CharUnicodeInfo.HIGH_SURROGATE_START << 10) );
-
- *pTarget = (byte)(unchecked((sbyte)0xF0) | (ch >> 18));
- // pStop - this byte is compensated by the second surrogate character
- // 2 input chars require 4 output bytes. 2 have been anticipated already
- // and 2 more will be accounted for by the 2 pStop-- calls below.
- pTarget++;
-
- chd = unchecked((sbyte)0x80) | (ch >> 12) & 0x3F;
- }
- *pTarget = (byte)chd;
- pStop--; // 3 byte sequence for 1 char, so need pStop-- and the one below too.
- pTarget++;
-
- chd = unchecked((sbyte)0x80) | (ch >> 6) & 0x3F;
- }
- *pTarget = (byte)chd;
- pStop--; // 2 byte sequence for 1 char so need pStop--.
- pTarget++;
-
- *pTarget = (byte)(unchecked((sbyte)0x80) | ch & 0x3F);
- // pStop - this byte is already included
- pTarget++;
- }
-
- Debug.Assert(pTarget <= pAllocatedBufferEnd, "[UTF8Encoding.GetBytes]pTarget <= pAllocatedBufferEnd");
-
-#endif // FASTLOOP
-
- // no pending char at this point
- ch = 0;
- }
-
- // Do we have to set the encoder bytes?
- if (encoder != null)
- {
- Debug.Assert(!encoder.MustFlush || ch == 0,
- "[UTF8Encoding.GetBytes] Expected no mustflush or 0 leftover ch " + ch.ToString("X2", CultureInfo.InvariantCulture));
-
- encoder.surrogateChar = ch;
- encoder.m_charsUsed = (int)(pSrc - chars);
- }
-
- Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0 ||
- baseEncoder == null || !baseEncoder.m_throwOnOverflow,
- "[UTF8Encoding.GetBytes]Expected empty fallback buffer if not converting");
-
- return (int)(pTarget - bytes);
- }
-
-
- // These are bitmasks used to maintain the state in the decoder. They occupy the higher bits
- // while the actual character is being built in the lower bits. They are shifted together
- // with the actual bits of the character.
-
- // bits 30 & 31 are used for pending bits fixup
- private const int FinalByte = 1 << 29;
- private const int SupplimentarySeq = 1 << 28;
- private const int ThreeByteSeq = 1 << 27;
-
- // Note: We throw exceptions on individually encoded surrogates and other non-shortest forms.
- // If exceptions aren't turned on, then we drop all non-shortest &individual surrogates.
- //
- // To simplify maintenance, the structure of GetCharCount and GetChars should be
- // kept the same as much as possible
- internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
- {
- Debug.Assert(count >=0, "[UTF8Encoding.GetCharCount]count >=0");
- Debug.Assert(bytes!=null, "[UTF8Encoding.GetCharCount]bytes!=null");
-
- // Initialize stuff
- byte *pSrc = bytes;
- byte *pEnd = pSrc+count;
-
- // Start by assuming we have as many as count, charCount always includes the adjustment
- // for the character being decoded
- int charCount = count;
- int ch = 0;
- DecoderFallbackBuffer fallback = null;
-
- if (baseDecoder != null) {
- UTF8Decoder decoder = (UTF8Decoder)baseDecoder;
- ch = decoder.bits;
- charCount -= (ch >> 30); // Adjust char count for # of expected bytes and expected output chars.
-
- // Shouldn't have anything in fallback buffer for GetCharCount
- // (don't have to check m_throwOnOverflow for count)
- Debug.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
- "[UTF8Encoding.GetCharCount]Expected empty fallback buffer at start");
- }
-
- for (;;)
- {
- // SLOWLOOP: does all range checks, handles all special cases, but it is slow
-
- if (pSrc >= pEnd) {
- break;
- }
-
- if (ch == 0) {
- // no pending bits
- goto ReadChar;
- }
-
- // read next byte. The JIT optimization seems to be getting confused when
- // compiling "ch = *pSrc++;", so rather use "ch = *pSrc; pSrc++;" instead
- int cha = *pSrc;
- pSrc++;
-
- // we are expecting to see trailing bytes like 10vvvvvv
- if ((cha & unchecked((sbyte)0xC0)) != 0x80) {
- // This can be a valid starting byte for another UTF8 byte sequence, so let's put
- // the current byte back, and try to see if this is a valid byte for another UTF8 byte sequence
- pSrc--;
- charCount += (ch >> 30);
- goto InvalidByteSequence;
- }
-
- // fold in the new byte
- ch = (ch << 6) | (cha & 0x3F);
-
- if ((ch & FinalByte) == 0) {
- Debug.Assert( (ch & (SupplimentarySeq | ThreeByteSeq)) != 0,
- "[UTF8Encoding.GetChars]Invariant volation");
-
- if ((ch & SupplimentarySeq) != 0) {
- if ((ch & (FinalByte >> 6)) != 0) {
- // this is 3rd byte (of 4 byte supplimentary) - nothing to do
- continue;
- }
-
- // 2nd byte, check for non-shortest form of supplimentary char and the valid
- // supplimentary characters in range 0x010000 - 0x10FFFF at the same time
- if (!InRange(ch & 0x1F0, 0x10, 0x100)) {
- goto InvalidByteSequence;
- }
- }
- else {
- // Must be 2nd byte of a 3-byte sequence
- // check for non-shortest form of 3 byte seq
- if ((ch & (0x1F << 5)) == 0 || // non-shortest form
- (ch & (0xF800 >> 6) ) == (0xD800 >> 6)) // illegal individually encoded surrogate
- {
- goto InvalidByteSequence;
- }
- }
- continue;
- }
-
- // ready to punch
-
- // adjust for surrogates in non-shortest form
- if ((ch & (SupplimentarySeq | 0x1F0000)) == SupplimentarySeq) {
- charCount--;
- }
- goto EncodeChar;
-
- InvalidByteSequence:
- // this code fragment should be close to the gotos referencing it
- // Have to do fallback for invalid bytes
- if (fallback == null)
- {
- if (baseDecoder == null)
- fallback = this.decoderFallback.CreateFallbackBuffer();
- else
- fallback = baseDecoder.FallbackBuffer;
- fallback.InternalInitialize(bytes, null);
- }
- charCount += FallbackInvalidByteSequence(pSrc, ch, fallback);
-
- ch = 0;
- continue;
-
- ReadChar:
- ch = *pSrc;
- pSrc++;
-
- ProcessChar:
- if (ch > 0x7F) {
- // If its > 0x7F, its start of a new multi-byte sequence
-
- // Long sequence, so unreserve our char.
- charCount--;
-
- // bit 6 has to be non-zero for start of multibyte chars.
- if ((ch & 0x40) == 0) {
- // Unexpected trail byte
- goto InvalidByteSequence;
- }
-
- // start a new long code
- if ((ch & 0x20) != 0) {
- if ((ch & 0x10) != 0) {
- // 4 byte encoding - supplimentary character (2 surrogates)
-
- ch &= 0x0F;
-
- // check that bit 4 is zero and the valid supplimentary character
- // range 0x000000 - 0x10FFFF at the same time
- if (ch > 0x04) {
- ch |= 0xf0;
- goto InvalidByteSequence;
- }
-
- // Add bit flags so that when we check new characters & rotate we'll be flagged correctly.
- // Final byte flag, count fix if we don't make final byte & supplimentary sequence flag.
- ch |= (FinalByte >> 3*6) | // Final byte is 3 more bytes from now
- (1 << 30) | // If it dies on next byte we'll need an extra char
- (3 << (30-2*6)) | // If it dies on last byte we'll need to subtract a char
- (SupplimentarySeq) | (SupplimentarySeq >> 6) |
- (SupplimentarySeq >> 2*6) | (SupplimentarySeq >> 3*6);
-
- // Our character count will be 2 characters for these 4 bytes, so subtract another char
- charCount--;
- }
- else {
- // 3 byte encoding
- // Add bit flags so that when we check new characters & rotate we'll be flagged correctly.
- ch = (ch & 0x0F) | ( (FinalByte >> 2*6) | (1 << 30) |
- (ThreeByteSeq) | (ThreeByteSeq >> 6) | (ThreeByteSeq >> 2*6) );
-
- // We'll expect 1 character for these 3 bytes, so subtract another char.
- charCount--;
- }
- }
- else {
- // 2 byte encoding
-
- ch &= 0x1F;
-
- // check for non-shortest form
- if (ch <= 1) {
- ch |= 0xc0;
- goto InvalidByteSequence;
- }
-
- // Add bit flags so we'll be flagged correctly
- ch |= (FinalByte >> 6);
- }
- continue;
- }
-
- EncodeChar:
-
-#if FASTLOOP
- int availableBytes = PtrDiff(pEnd, pSrc);
-
- // don't fall into the fast decoding loop if we don't have enough bytes
- if (availableBytes <= 13) {
- // try to get over the remainder of the ascii characters fast though
- byte* pLocalEnd = pEnd; // hint to get pLocalEnd enregistered
- while (pSrc < pLocalEnd) {
- ch = *pSrc;
- pSrc++;
-
- if (ch > 0x7F)
- goto ProcessChar;
- }
- // we are done
- ch = 0;
- break;
- }
-
- // To compute the upper bound, assume that all characters are ASCII characters at this point,
- // the boundary will be decreased for every non-ASCII character we encounter
- // Also, we need 7 chars reserve for the unrolled ansi decoding loop and for decoding of multibyte sequences
- byte *pStop = pSrc + availableBytes - 7;
-
- while (pSrc < pStop) {
- ch = *pSrc;
- pSrc++;
-
- if (ch > 0x7F) {
- goto LongCode;
- }
-
- // get pSrc 2-byte aligned
- if ((unchecked((int)pSrc) & 0x1) != 0) {
- ch = *pSrc;
- pSrc++;
- if (ch > 0x7F) {
- goto LongCode;
- }
- }
-
- // get pSrc 4-byte aligned
- if ((unchecked((int)pSrc) & 0x2) != 0) {
- ch = *(ushort*)pSrc;
- if ((ch & 0x8080) != 0) {
- goto LongCodeWithMask16;
- }
- pSrc += 2;
- }
-
- // Run 8 + 8 characters at a time!
- while (pSrc < pStop) {
- ch = *(int*)pSrc;
- int chb = *(int*)(pSrc+4);
- if (((ch | chb) & unchecked((int)0x80808080)) != 0) {
- goto LongCodeWithMask32;
- }
- pSrc += 8;
-
- // This is a really small loop - unroll it
- if (pSrc >= pStop)
- break;
-
- ch = *(int*)pSrc;
- chb = *(int*)(pSrc+4);
- if (((ch | chb) & unchecked((int)0x80808080)) != 0) {
- goto LongCodeWithMask32;
- }
- pSrc += 8;
- }
- break;
-
-#if BIGENDIAN
- LongCodeWithMask32:
- // be careful about the sign extension
- ch = (int)(((uint)ch) >> 16);
- LongCodeWithMask16:
- ch = (int)(((uint)ch) >> 8);
-#else // BIGENDIAN
- LongCodeWithMask32:
- LongCodeWithMask16:
- ch &= 0xFF;
-#endif // BIGENDIAN
- pSrc++;
- if (ch <= 0x7F) {
- continue;
- }
-
- LongCode:
- int chc = *pSrc;
- pSrc++;
-
- if (
- // bit 6 has to be zero
- (ch & 0x40) == 0 ||
- // we are expecting to see trailing bytes like 10vvvvvv
- (chc & unchecked((sbyte)0xC0)) != 0x80)
- {
- goto BadLongCode;
- }
-
- chc &= 0x3F;
-
- // start a new long code
- if ((ch & 0x20) != 0) {
-
- // fold the first two bytes together
- chc |= (ch & 0x0F) << 6;
-
- if ((ch & 0x10) != 0) {
- // 4 byte encoding - surrogate
- ch = *pSrc;
- if (
- // check that bit 4 is zero, the non-shortest form of surrogate
- // and the valid surrogate range 0x000000 - 0x10FFFF at the same time
- !InRange(chc >> 4, 0x01, 0x10) ||
- // we are expecting to see trailing bytes like 10vvvvvv
- (ch & unchecked((sbyte)0xC0)) != 0x80 )
- {
- goto BadLongCode;
- }
-
- chc = (chc << 6) | (ch & 0x3F);
-
- ch = *(pSrc+1);
- // we are expecting to see trailing bytes like 10vvvvvv
- if ((ch & unchecked((sbyte)0xC0)) != 0x80) {
- goto BadLongCode;
- }
- pSrc += 2;
-
- // extra byte
- charCount--;
- }
- else {
- // 3 byte encoding
- ch = *pSrc;
- if (
- // check for non-shortest form of 3 byte seq
- (chc & (0x1F << 5)) == 0 ||
- // Can't have surrogates here.
- (chc & (0xF800 >> 6) ) == (0xD800 >> 6) ||
- // we are expecting to see trailing bytes like 10vvvvvv
- (ch & unchecked((sbyte)0xC0)) != 0x80 )
- {
- goto BadLongCode;
- }
- pSrc++;
-
- // extra byte
- charCount--;
- }
- }
- else {
- // 2 byte encoding
-
- // check for non-shortest form
- if ((ch & 0x1E) == 0) {
- goto BadLongCode;
- }
- }
-
- // extra byte
- charCount--;
- }
-#endif // FASTLOOP
-
- // no pending bits at this point
- ch = 0;
- continue;
-
- BadLongCode:
- pSrc -= 2;
- ch = 0;
- continue;
- }
-
- // May have a problem if we have to flush
- if (ch != 0)
- {
- // We were already adjusting for these, so need to unadjust
- charCount += (ch >> 30);
- if (baseDecoder == null || baseDecoder.MustFlush)
- {
- // Have to do fallback for invalid bytes
- if (fallback == null)
- {
- if (baseDecoder == null)
- fallback = this.decoderFallback.CreateFallbackBuffer();
- else
- fallback = baseDecoder.FallbackBuffer;
- fallback.InternalInitialize(bytes, null);
- }
- charCount += FallbackInvalidByteSequence(pSrc, ch, fallback);
- }
- }
-
- // Shouldn't have anything in fallback buffer for GetCharCount
- // (don't have to check m_throwOnOverflow for count)
- Debug.Assert(fallback == null || fallback.Remaining == 0,
- "[UTF8Encoding.GetCharCount]Expected empty fallback buffer at end");
-
- return charCount;
- }
-
- // WARNING: If we throw an error, then System.Resources.ResourceReader calls this method.
- // So if we're really broken, then that could also throw an error... recursively.
- // So try to make sure GetChars can at least process all uses by
- // System.Resources.ResourceReader!
- //
- // Note: We throw exceptions on individually encoded surrogates and other non-shortest forms.
- // If exceptions aren't turned on, then we drop all non-shortest &individual surrogates.
- //
- // To simplify maintenance, the structure of GetCharCount and GetChars should be
- // kept the same as much as possible
- internal override unsafe int GetChars(byte* bytes, int byteCount,
- char* chars, int charCount, DecoderNLS baseDecoder)
- {
- Debug.Assert(chars!=null, "[UTF8Encoding.GetChars]chars!=null");
- Debug.Assert(byteCount >=0, "[UTF8Encoding.GetChars]count >=0");
- Debug.Assert(charCount >=0, "[UTF8Encoding.GetChars]charCount >=0");
- Debug.Assert(bytes!=null, "[UTF8Encoding.GetChars]bytes!=null");
-
- byte *pSrc = bytes;
- char *pTarget = chars;
-
- byte *pEnd = pSrc+byteCount;
- char *pAllocatedBufferEnd = pTarget+charCount;
-
- int ch = 0;
-
- DecoderFallbackBuffer fallback = null;
- if (baseDecoder != null) {
- UTF8Decoder decoder = (UTF8Decoder)baseDecoder;
- ch = decoder.bits;
-
- // Shouldn't have anything in fallback buffer for GetChars
- // (don't have to check m_throwOnOverflow for chars, we always use all or none so always should be empty)
- Debug.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
- "[UTF8Encoding.GetChars]Expected empty fallback buffer at start");
- }
-
- for (;;)
- {
- // SLOWLOOP: does all range checks, handles all special cases, but it is slow
-
- if (pSrc >= pEnd) {
- break;
- }
-
- if (ch == 0) {
- // no pending bits
- goto ReadChar;
- }
-
- // read next byte. The JIT optimization seems to be getting confused when
- // compiling "ch = *pSrc++;", so rather use "ch = *pSrc; pSrc++;" instead
- int cha = *pSrc;
- pSrc++;
-
- // we are expecting to see trailing bytes like 10vvvvvv
- if ((cha & unchecked((sbyte)0xC0)) != 0x80) {
- // This can be a valid starting byte for another UTF8 byte sequence, so let's put
- // the current byte back, and try to see if this is a valid byte for another UTF8 byte sequence
- pSrc--;
- goto InvalidByteSequence;
- }
-
- // fold in the new byte
- ch = (ch << 6) | (cha & 0x3F);
-
- if ((ch & FinalByte) == 0) {
- // Not at last byte yet
- Debug.Assert( (ch & (SupplimentarySeq | ThreeByteSeq)) != 0,
- "[UTF8Encoding.GetChars]Invariant volation");
-
- if ((ch & SupplimentarySeq) != 0) {
- // Its a 4-byte supplimentary sequence
- if ((ch & (FinalByte >> 6)) != 0) {
- // this is 3rd byte of 4 byte sequence - nothing to do
- continue;
- }
-
- // 2nd byte of 4 bytes
- // check for non-shortest form of surrogate and the valid surrogate
- // range 0x000000 - 0x10FFFF at the same time
- if (!InRange(ch & 0x1F0, 0x10, 0x100)) {
- goto InvalidByteSequence;
- }
- }
- else {
- // Must be 2nd byte of a 3-byte sequence
- // check for non-shortest form of 3 byte seq
- if ((ch & (0x1F << 5)) == 0 || // non-shortest form
- (ch & (0xF800 >> 6) ) == (0xD800 >> 6)) // illegal individually encoded surrogate
- {
- goto InvalidByteSequence;
- }
- }
- continue;
- }
-
- // ready to punch
-
- // surrogate in shortest form?
- // Might be possible to get rid of this? Already did non-shortest check for 4-byte sequence when reading 2nd byte?
- if ((ch & (SupplimentarySeq | 0x1F0000)) > SupplimentarySeq) {
- // let the range check for the second char throw the exception
- if (pTarget < pAllocatedBufferEnd) {
- *pTarget = (char)( ((ch >> 10) & 0x7FF) +
- unchecked((short)((CharUnicodeInfo.HIGH_SURROGATE_START - (0x10000 >> 10)))) );
- pTarget++;
-
- ch = (ch & 0x3FF) +
- unchecked((int)(CharUnicodeInfo.LOW_SURROGATE_START));
- }
- }
-
- goto EncodeChar;
-
- InvalidByteSequence:
- // this code fragment should be close to the gotos referencing it
- // Have to do fallback for invalid bytes
- if (fallback == null)
- {
- if (baseDecoder == null)
- fallback = this.decoderFallback.CreateFallbackBuffer();
- else
- fallback = baseDecoder.FallbackBuffer;
- fallback.InternalInitialize(bytes, pAllocatedBufferEnd);
- }
- // This'll back us up the appropriate # of bytes if we didn't get anywhere
- if (!FallbackInvalidByteSequence(ref pSrc, ch, fallback, ref pTarget))
- {
- // Ran out of buffer space
- // Need to throw an exception?
- Debug.Assert(pSrc >= bytes || pTarget == chars,
- "[UTF8Encoding.GetChars]Expected to throw or remain in byte buffer after fallback");
- fallback.InternalReset();
- ThrowCharsOverflow(baseDecoder, pTarget == chars);
- ch = 0;
- break;
- }
- Debug.Assert(pSrc >= bytes,
- "[UTF8Encoding.GetChars]Expected invalid byte sequence to have remained within the byte array");
- ch = 0;
- continue;
-
- ReadChar:
- ch = *pSrc;
- pSrc++;
-
- ProcessChar:
- if (ch > 0x7F) {
- // If its > 0x7F, its start of a new multi-byte sequence
-
- // bit 6 has to be non-zero
- if ((ch & 0x40) == 0) {
- goto InvalidByteSequence;
- }
-
- // start a new long code
- if ((ch & 0x20) != 0) {
- if ((ch & 0x10) != 0) {
- // 4 byte encoding - supplimentary character (2 surrogates)
-
- ch &= 0x0F;
-
- // check that bit 4 is zero and the valid supplimentary character
- // range 0x000000 - 0x10FFFF at the same time
- if (ch > 0x04) {
- ch |= 0xf0;
- goto InvalidByteSequence;
- }
-
- ch |= (FinalByte >> 3*6) | (1 << 30) | (3 << (30-2*6)) |
- (SupplimentarySeq) | (SupplimentarySeq >> 6) |
- (SupplimentarySeq >> 2*6) | (SupplimentarySeq >> 3*6);
- }
- else {
- // 3 byte encoding
- ch = (ch & 0x0F) | ( (FinalByte >> 2*6) | (1 << 30) |
- (ThreeByteSeq) | (ThreeByteSeq >> 6) | (ThreeByteSeq >> 2*6) );
- }
- }
- else {
- // 2 byte encoding
-
- ch &= 0x1F;
-
- // check for non-shortest form
- if (ch <= 1) {
- ch |= 0xc0;
- goto InvalidByteSequence;
- }
-
- ch |= (FinalByte >> 6);
- }
- continue;
- }
-
- EncodeChar:
- // write the pending character
- if (pTarget >= pAllocatedBufferEnd)
- {
- // Fix chars so we make sure to throw if we didn't output anything
- ch &= 0x1fffff;
- if (ch > 0x7f)
- {
- if (ch > 0x7ff)
- {
- if (ch >= CharUnicodeInfo.LOW_SURROGATE_START &&
- ch <= CharUnicodeInfo.LOW_SURROGATE_END)
- {
- pSrc--; // It was 4 bytes
- pTarget--; // 1 was stored already, but we can't remember 1/2, so back up
- }
- else if (ch > 0xffff)
- {
- pSrc--; // It was 4 bytes, nothing was stored
- }
- pSrc--; // It was at least 3 bytes
- }
- pSrc--; // It was at least 2 bytes
- }
- pSrc--;
-
- // Throw that we don't have enough room (pSrc could be < chars if we had started to process
- // a 4 byte sequence alredy)
- Debug.Assert(pSrc >= bytes || pTarget == chars,
- "[UTF8Encoding.GetChars]Expected pSrc to be within input buffer or throw due to no output]");
- ThrowCharsOverflow(baseDecoder, pTarget == chars);
-
- // Don't store ch in decoder, we already backed up to its start
- ch = 0;
-
- // Didn't throw, just use this buffer size.
- break;
- }
- *pTarget = (char)ch;
- pTarget++;
-
-#if FASTLOOP
- int availableChars = PtrDiff(pAllocatedBufferEnd, pTarget);
- int availableBytes = PtrDiff(pEnd, pSrc);
-
- // don't fall into the fast decoding loop if we don't have enough bytes
- // Test for availableChars is done because pStop would be <= pTarget.
- if (availableBytes <= 13) {
- // we may need as many as 1 character per byte
- if (availableChars < availableBytes) {
- // not enough output room. no pending bits at this point
- ch = 0;
- continue;
- }
-
- // try to get over the remainder of the ascii characters fast though
- byte* pLocalEnd = pEnd; // hint to get pLocalEnd enregistered
- while (pSrc < pLocalEnd) {
- ch = *pSrc;
- pSrc++;
-
- if (ch > 0x7F)
- goto ProcessChar;
-
- *pTarget = (char)ch;
- pTarget++;
- }
- // we are done
- ch = 0;
- break;
- }
-
- // we may need as many as 1 character per byte, so reduce the byte count if necessary.
- // If availableChars is too small, pStop will be before pTarget and we won't do fast loop.
- if (availableChars < availableBytes) {
- availableBytes = availableChars;
- }
-
- // To compute the upper bound, assume that all characters are ASCII characters at this point,
- // the boundary will be decreased for every non-ASCII character we encounter
- // Also, we need 7 chars reserve for the unrolled ansi decoding loop and for decoding of multibyte sequences
- char *pStop = pTarget + availableBytes - 7;
-
- while (pTarget < pStop) {
- ch = *pSrc;
- pSrc++;
-
- if (ch > 0x7F) {
- goto LongCode;
- }
- *pTarget = (char)ch;
- pTarget++;
-
- // get pSrc to be 2-byte aligned
- if ((unchecked((int)pSrc) & 0x1) != 0) {
- ch = *pSrc;
- pSrc++;
- if (ch > 0x7F) {
- goto LongCode;
- }
- *pTarget = (char)ch;
- pTarget++;
- }
-
- // get pSrc to be 4-byte aligned
- if ((unchecked((int)pSrc) & 0x2) != 0) {
- ch = *(ushort*)pSrc;
- if ((ch & 0x8080) != 0) {
- goto LongCodeWithMask16;
- }
-
- // Unfortunately, this is endianess sensitive
-#if BIGENDIAN
- *pTarget = (char)((ch >> 8) & 0x7F);
- pSrc += 2;
- *(pTarget+1) = (char)(ch & 0x7F);
- pTarget += 2;
-#else // BIGENDIAN
- *pTarget = (char)(ch & 0x7F);
- pSrc += 2;
- *(pTarget+1) = (char)((ch >> 8) & 0x7F);
- pTarget += 2;
-#endif // BIGENDIAN
- }
-
- // Run 8 characters at a time!
- while (pTarget < pStop) {
- ch = *(int*)pSrc;
- int chb = *(int*)(pSrc+4);
- if (((ch | chb) & unchecked((int)0x80808080)) != 0) {
- goto LongCodeWithMask32;
- }
-
- // Unfortunately, this is endianess sensitive
-#if BIGENDIAN
- *pTarget = (char)((ch >> 24) & 0x7F);
- *(pTarget+1) = (char)((ch >> 16) & 0x7F);
- *(pTarget+2) = (char)((ch >> 8) & 0x7F);
- *(pTarget+3) = (char)(ch & 0x7F);
- pSrc += 8;
- *(pTarget+4) = (char)((chb >> 24) & 0x7F);
- *(pTarget+5) = (char)((chb >> 16) & 0x7F);
- *(pTarget+6) = (char)((chb >> 8) & 0x7F);
- *(pTarget+7) = (char)(chb & 0x7F);
- pTarget += 8;
-#else // BIGENDIAN
- *pTarget = (char)(ch & 0x7F);
- *(pTarget+1) = (char)((ch >> 8) & 0x7F);
- *(pTarget+2) = (char)((ch >> 16) & 0x7F);
- *(pTarget+3) = (char)((ch >> 24) & 0x7F);
- pSrc += 8;
- *(pTarget+4) = (char)(chb & 0x7F);
- *(pTarget+5) = (char)((chb >> 8) & 0x7F);
- *(pTarget+6) = (char)((chb >> 16) & 0x7F);
- *(pTarget+7) = (char)((chb >> 24) & 0x7F);
- pTarget += 8;
-#endif // BIGENDIAN
- }
- break;
-
-#if BIGENDIAN
- LongCodeWithMask32:
- // be careful about the sign extension
- ch = (int)(((uint)ch) >> 16);
- LongCodeWithMask16:
- ch = (int)(((uint)ch) >> 8);
-#else // BIGENDIAN
- LongCodeWithMask32:
- LongCodeWithMask16:
- ch &= 0xFF;
-#endif // BIGENDIAN
- pSrc++;
- if (ch <= 0x7F) {
- *pTarget = (char)ch;
- pTarget++;
- continue;
- }
-
- LongCode:
- int chc = *pSrc;
- pSrc++;
-
- if (
- // bit 6 has to be zero
- (ch & 0x40) == 0 ||
- // we are expecting to see trailing bytes like 10vvvvvv
- (chc & unchecked((sbyte)0xC0)) != 0x80)
- {
- goto BadLongCode;
- }
-
- chc &= 0x3F;
-
- // start a new long code
- if ((ch & 0x20) != 0) {
-
- // fold the first two bytes together
- chc |= (ch & 0x0F) << 6;
-
- if ((ch & 0x10) != 0) {
- // 4 byte encoding - surrogate
- ch = *pSrc;
- if (
- // check that bit 4 is zero, the non-shortest form of surrogate
- // and the valid surrogate range 0x000000 - 0x10FFFF at the same time
- !InRange(chc >> 4, 0x01, 0x10) ||
- // we are expecting to see trailing bytes like 10vvvvvv
- (ch & unchecked((sbyte)0xC0)) != 0x80 )
- {
- goto BadLongCode;
- }
-
- chc = (chc << 6) | (ch & 0x3F);
-
- ch = *(pSrc+1);
- // we are expecting to see trailing bytes like 10vvvvvv
- if ((ch & unchecked((sbyte)0xC0)) != 0x80) {
- goto BadLongCode;
- }
- pSrc += 2;
-
- ch = (chc << 6) | (ch & 0x3F);
-
- *pTarget = (char)( ((ch >> 10) & 0x7FF) +
- unchecked((short)(CharUnicodeInfo.HIGH_SURROGATE_START - (0x10000 >> 10))) );
- pTarget++;
-
- ch = (ch & 0x3FF) +
- unchecked((short)(CharUnicodeInfo.LOW_SURROGATE_START));
-
- // extra byte, we're already planning 2 chars for 2 of these bytes,
- // but the big loop is testing the target against pStop, so we need
- // to subtract 2 more or we risk overrunning the input. Subtract
- // one here and one below.
- pStop--;
- }
- else {
- // 3 byte encoding
- ch = *pSrc;
- if (
- // check for non-shortest form of 3 byte seq
- (chc & (0x1F << 5)) == 0 ||
- // Can't have surrogates here.
- (chc & (0xF800 >> 6) ) == (0xD800 >> 6) ||
- // we are expecting to see trailing bytes like 10vvvvvv
- (ch & unchecked((sbyte)0xC0)) != 0x80 )
- {
- goto BadLongCode;
- }
- pSrc++;
-
- ch = (chc << 6) | (ch & 0x3F);
-
- // extra byte, we're only expecting 1 char for each of these 3 bytes,
- // but the loop is testing the target (not source) against pStop, so
- // we need to subtract 2 more or we risk overrunning the input.
- // Subtract 1 here and one more below
- pStop--;
- }
- }
- else {
- // 2 byte encoding
-
- ch &= 0x1F;
-
- // check for non-shortest form
- if (ch <= 1) {
- goto BadLongCode;
- }
- ch = (ch << 6) | chc;
- }
-
- *pTarget = (char)ch;
- pTarget++;
-
- // extra byte, we're only expecting 1 char for each of these 2 bytes,
- // but the loop is testing the target (not source) against pStop.
- // subtract an extra count from pStop so that we don't overrun the input.
- pStop--;
- }
-#endif // FASTLOOP
-
- Debug.Assert(pTarget <= pAllocatedBufferEnd, "[UTF8Encoding.GetChars]pTarget <= pAllocatedBufferEnd");
-
- // no pending bits at this point
- ch = 0;
- continue;
-
- BadLongCode:
- pSrc -= 2;
- ch = 0;
- continue;
- }
-
- if (ch != 0 && (baseDecoder == null || baseDecoder.MustFlush))
- {
- // Have to do fallback for invalid bytes
- if (fallback == null)
- {
- if (baseDecoder == null)
- fallback = this.decoderFallback.CreateFallbackBuffer();
- else
- fallback = baseDecoder.FallbackBuffer;
- fallback.InternalInitialize(bytes, pAllocatedBufferEnd);
- }
-
- // This'll back us up the appropriate # of bytes if we didn't get anywhere
- if (!FallbackInvalidByteSequence(ref pSrc, ch, fallback, ref pTarget))
- {
- Debug.Assert(pSrc >= bytes || pTarget == chars,
- "[UTF8Encoding.GetChars]Expected to throw or remain in byte buffer while flushing");
-
- // Ran out of buffer space
- // Need to throw an exception?
- fallback.InternalReset();
- ThrowCharsOverflow(baseDecoder, pTarget == chars);
- }
- Debug.Assert(pSrc >= bytes,
- "[UTF8Encoding.GetChars]Expected flushing invalid byte sequence to have remained within the byte array");
- ch = 0;
- }
-
- if (baseDecoder != null)
- {
- UTF8Decoder decoder = (UTF8Decoder)baseDecoder;
-
- // If we're storing flush data we expect all bits to be used or else
- // we're stuck in the middle of a conversion
- Debug.Assert(!baseDecoder.MustFlush || ch == 0 || !baseDecoder.m_throwOnOverflow,
- "[UTF8Encoding.GetChars]Expected no must flush or no left over bits or no throw on overflow.");
-
- // Remember our leftover bits.
- decoder.bits = ch;
-
- baseDecoder.m_bytesUsed = (int)(pSrc - bytes);
- }
-
- // Shouldn't have anything in fallback buffer for GetChars
- // (don't have to check m_throwOnOverflow for chars)
- Debug.Assert(fallback == null || fallback.Remaining == 0,
- "[UTF8Encoding.GetChars]Expected empty fallback buffer at end");
-
- return PtrDiff(pTarget, chars);
- }
-
- // During GetChars we had an invalid byte sequence
- // pSrc is backed up to the start of the bad sequence if we didn't have room to
- // fall it back. Otherwise pSrc remains wher it is.
- private unsafe bool FallbackInvalidByteSequence(
- ref byte* pSrc, int ch, DecoderFallbackBuffer fallback, ref char* pTarget)
- {
- // Get our byte[]
- byte *pStart = pSrc;
- byte[] bytesUnknown = GetBytesUnknown(ref pStart, ch);
-
- // Do the actual fallback
- if (!fallback.InternalFallback(bytesUnknown, pSrc, ref pTarget))
- {
- // Oops, it failed, back up to pStart
- pSrc = pStart;
- return false;
- }
-
- // It worked
- return true;
- }
-
- // During GetCharCount we had an invalid byte sequence
- // pSrc is used to find the index that points to the invalid bytes,
- // however the byte[] contains the fallback bytes (in case the index is -1)
- private unsafe int FallbackInvalidByteSequence(
- byte* pSrc, int ch, DecoderFallbackBuffer fallback)
- {
- // Get our byte[]
- byte[] bytesUnknown = GetBytesUnknown(ref pSrc, ch);
-
- // Do the actual fallback
- int count = fallback.InternalFallback(bytesUnknown, pSrc);
-
- // # of fallback chars expected.
- // Note that we only get here for "long" sequences, and have already unreserved
- // the count that we prereserved for the input bytes
- return count;
- }
-
- // Note that some of these bytes may have come from a previous fallback, so we cannot
- // just decrement the pointer and use the values we read. In those cases we have
- // to regenerate the original values.
- private unsafe byte[] GetBytesUnknown(ref byte* pSrc, int ch)
- {
- // Get our byte[]
- byte[] bytesUnknown = null;
-
- // See if it was a plain char
- // (have to check >= 0 because we have all sorts of wierd bit flags)
- if (ch < 0x100 && ch >= 0)
- {
- pSrc--;
- bytesUnknown = new byte[] { unchecked((byte)ch) };
- }
- // See if its an unfinished 2 byte sequence
- else if ((ch & (SupplimentarySeq | ThreeByteSeq)) == 0)
- {
- pSrc--;
- bytesUnknown = new byte[] { unchecked((byte)((ch & 0x1F )| 0xc0)) };
- }
- // So now we're either 2nd byte of 3 or 4 byte sequence or
- // we hit a non-trail byte or we ran out of space for 3rd byte of 4 byte sequence
- // 1st check if its a 4 byte sequence
- else if ((ch & SupplimentarySeq) != 0)
- {
- // 3rd byte of 4 byte sequence?
- if ((ch & (FinalByte >> 6)) != 0)
- {
- // 3rd byte of 4 byte sequence
- pSrc-=3;
- bytesUnknown = new byte[] {
- unchecked((byte)(((ch >> 12) & 0x07) | 0xF0)),
- unchecked((byte)(((ch >> 6) & 0x3F) | 0x80)),
- unchecked((byte)(((ch) & 0x3F) | 0x80)) };
- }
- else if ((ch & (FinalByte >> 12)) != 0)
- {
- // 2nd byte of a 4 byte sequence
- pSrc-=2;
- bytesUnknown = new byte[] {
- unchecked((byte)(((ch >> 6) & 0x07) | 0xF0)),
- unchecked((byte)(((ch) & 0x3F) | 0x80)) };
- }
- else
- {
- // 4th byte of a 4 byte sequence
- pSrc--;
- bytesUnknown = new byte[] { unchecked((byte)(((ch) & 0x07) | 0xF0))};
- }
- }
- else
- {
- // 2nd byte of 3 byte sequence?
- if ((ch & (FinalByte >> 6)) != 0)
- {
- // So its 2nd byte of a 3 byte sequence
- pSrc-=2;
- bytesUnknown = new byte[] {
- unchecked((byte)(((ch >> 6) & 0x0F) | 0xE0)), unchecked ((byte)(((ch) & 0x3F) | 0x80)) };
- }
- else
- {
- // 1st byte of a 3 byte sequence
- pSrc--;
- bytesUnknown = new byte[] { unchecked((byte)(((ch) & 0x0F) | 0xE0))};
- }
- }
-
- return bytesUnknown;
- }
-
-
- public override Decoder GetDecoder() {
- return new UTF8Decoder(this);
- }
-
-
- public override Encoder GetEncoder() {
- return new UTF8Encoder(this);
- }
-
-
- public override int GetMaxByteCount(int charCount)
- {
- if (charCount < 0)
- throw new ArgumentOutOfRangeException(nameof(charCount),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Characters would be # of characters + 1 in case left over high surrogate is ? * max fallback
- long byteCount = (long)charCount + 1;
-
- if (EncoderFallback.MaxCharCount > 1)
- byteCount *= EncoderFallback.MaxCharCount;
-
- // Max 3 bytes per char. (4 bytes per 2 chars for surrogates)
- byteCount *= 3;
-
- if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
-
- return (int)byteCount;
- }
-
-
- public override int GetMaxCharCount(int byteCount)
- {
- if (byteCount < 0)
- throw new ArgumentOutOfRangeException(nameof(byteCount),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Figure out our length, 1 char per input byte + 1 char if 1st byte is last byte of 4 byte surrogate pair
- long charCount = ((long)byteCount + 1);
-
- // Non-shortest form would fall back, so get max count from fallback.
- // So would 11... followed by 11..., so you could fall back every byte
- if (DecoderFallback.MaxCharCount > 1)
- {
- charCount *= DecoderFallback.MaxCharCount;
- }
-
- if (charCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
-
- return (int)charCount;
- }
-
-
- public override byte[] GetPreamble()
- {
- if (emitUTF8Identifier) {
- // Allocate new array to prevent users from modifying it.
- return new byte[3] { 0xEF, 0xBB, 0xBF };
- }
- else
- return EmptyArray<Byte>.Value;
- }
-
-
- public override bool Equals(Object value) {
- UTF8Encoding that = value as UTF8Encoding;
- if (that != null) {
- return (emitUTF8Identifier == that.emitUTF8Identifier) &&
-// (isThrowException == that.isThrowException) && // Same as encoder/decoderfallbacks being exception
- (EncoderFallback.Equals(that.EncoderFallback)) &&
- (DecoderFallback.Equals(that.DecoderFallback));
- }
- return (false);
- }
-
-
- public override int GetHashCode() {
- //Not great distribution, but this is relatively unlikely to be used as the key in a hashtable.
- return this.EncoderFallback.GetHashCode() + this.DecoderFallback.GetHashCode() +
- UTF8_CODEPAGE + (emitUTF8Identifier?1:0);
- }
-
- [Serializable]
- internal class UTF8Encoder : EncoderNLS, ISerializable
- {
- // We must save a high surrogate value until the next call, looking
- // for a low surrogate value.
- internal int surrogateChar;
-
- public UTF8Encoder(UTF8Encoding encoding) : base(encoding)
- {
- // base calls reset
- }
-
- // Constructor called by serialization, have to handle deserializing from Everett
- internal UTF8Encoder(SerializationInfo info, StreamingContext context)
- {
- // Any info?
- if (info==null) throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- // Get common info
- this.m_encoding = (Encoding)info.GetValue("encoding", typeof(Encoding));
-
- // SurrogateChar happens to mean the same thing
- this.surrogateChar = (int)info.GetValue("surrogateChar", typeof(int));
-
- try
- {
- this.m_fallback = (EncoderFallback) info.GetValue("m_fallback", typeof(EncoderFallback));
- }
- catch (SerializationException)
- {
- this.m_fallback = null;
- }
- }
-
- // ISerializable implementation, get data for this object
- void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
- {
- // Any info?
- if (info==null) throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- // Save Whidbey data
- // Just need Everett maxCharSize (BaseCodePageEncoding) or m_maxByteSize (MLangBaseCodePageEncoding)
- info.AddValue("encoding", this.m_encoding);
- info.AddValue("surrogateChar", this.surrogateChar);
-
- info.AddValue("m_fallback", this.m_fallback);
-
- // Extra stuff for Everett that Whidbey doesn't use
- info.AddValue("storedSurrogate", this.surrogateChar > 0 ? true : false);
- info.AddValue("mustFlush", false); // Everett doesn't actually use this either, but it accidently serialized it!
- }
-
- public override void Reset()
-
- {
- this.surrogateChar = 0;
- if (m_fallbackBuffer != null)
- m_fallbackBuffer.Reset();
- }
-
- // Anything left in our encoder?
- internal override bool HasState
- {
- get
- {
- return (this.surrogateChar != 0);
- }
- }
- }
-
- [Serializable]
- internal class UTF8Decoder : DecoderNLS, ISerializable
- {
- // We'll need to remember the previous information. See the comments around definition
- // of FinalByte for details.
- internal int bits;
-
- public UTF8Decoder(UTF8Encoding encoding) : base(encoding)
- {
- // base calls reset
- }
-
- // Constructor called by serialization, have to handle deserializing from Everett
- internal UTF8Decoder(SerializationInfo info, StreamingContext context)
- {
- // Any info?
- if (info==null) throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- // Get common info
- this.m_encoding = (Encoding)info.GetValue("encoding", typeof(Encoding));
-
- try
- {
- // Get whidbey version of bits
- this.bits = (int)info.GetValue("wbits", typeof(int));
- this.m_fallback = (DecoderFallback) info.GetValue("m_fallback", typeof(DecoderFallback));
- }
- catch (SerializationException)
- {
- // Everett calls bits bits instead of wbits, so this is Everett
- this.bits = 0;
- this.m_fallback = null;
- }
- }
-
- // ISerializable implementation, get data for this object
- void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
- {
- // Any info?
- if (info==null) throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- // Save new Whidbey data
- info.AddValue("encoding", this.m_encoding);
- info.AddValue("wbits", this.bits); // Special whidbey bits name
- info.AddValue("m_fallback", this.m_fallback);
-
- // Everett has extra stuff, we set it all to 0 in case this deserializes in Everett
- info.AddValue("bits", (int)0);
- info.AddValue("trailCount", (int)0);
- info.AddValue("isSurrogate", false);
- info.AddValue("byteSequence", (int)0);
- }
-
- public override void Reset()
- {
- this.bits = 0;
- if (m_fallbackBuffer != null)
- m_fallbackBuffer.Reset();
- }
-
- // Anything left in our decoder?
- internal override bool HasState
- {
- get
- {
- return (this.bits != 0);
- }
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Text/UnicodeEncoding.cs b/src/mscorlib/src/System/Text/UnicodeEncoding.cs
deleted file mode 100644
index d8ef18ab05..0000000000
--- a/src/mscorlib/src/System/Text/UnicodeEncoding.cs
+++ /dev/null
@@ -1,1826 +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.
-
-//
-// Don't override IsAlwaysNormalized because it is just a Unicode Transformation and could be confused.
-//
-
-namespace System.Text
-{
- using System;
- using System.Globalization;
- using System.Runtime.Serialization;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
-
- [Serializable]
- public class UnicodeEncoding : Encoding
- {
- // Used by Encoding.BigEndianUnicode/Unicode for lazy initialization
- // The initialization code will not be run until a static member of the class is referenced
- internal static readonly UnicodeEncoding s_bigEndianDefault = new UnicodeEncoding(bigEndian: true, byteOrderMark: true);
- internal static readonly UnicodeEncoding s_littleEndianDefault = new UnicodeEncoding(bigEndian: false, byteOrderMark: true);
-
- [OptionalField(VersionAdded = 2)]
- internal bool isThrowException = false;
-
- internal bool bigEndian = false;
- internal bool byteOrderMark = true;
-
- // Unicode version 2.0 character size in bytes
- public const int CharSize = 2;
-
-
- public UnicodeEncoding()
- : this(false, true)
- {
- }
-
-
- public UnicodeEncoding(bool bigEndian, bool byteOrderMark)
- : this(bigEndian, byteOrderMark, false)
- {
- }
-
-
- public UnicodeEncoding(bool bigEndian, bool byteOrderMark, bool throwOnInvalidBytes)
- : base(bigEndian ? 1201 : 1200) //Set the data item.
- {
- this.isThrowException = throwOnInvalidBytes;
- this.bigEndian = bigEndian;
- this.byteOrderMark = byteOrderMark;
-
- // Encoding's constructor already did this, but it'll be wrong if we're throwing exceptions
- if (this.isThrowException)
- SetDefaultFallbacks();
- }
-
-#region Serialization
- [OnDeserializing]
- private void OnDeserializing(StreamingContext ctx)
- {
- // In Everett it is false. Whidbey will overwrite this value.
- isThrowException = false;
- }
-#endregion Serialization
-
- internal override void SetDefaultFallbacks()
- {
- // For UTF-X encodings, we use a replacement fallback with an empty string
- if (this.isThrowException)
- {
- this.encoderFallback = EncoderFallback.ExceptionFallback;
- this.decoderFallback = DecoderFallback.ExceptionFallback;
- }
- else
- {
- this.encoderFallback = new EncoderReplacementFallback("\xFFFD");
- this.decoderFallback = new DecoderReplacementFallback("\xFFFD");
- }
- }
-
- // NOTE: Many methods in this class forward to EncodingForwarder for
- // validating arguments/wrapping the unsafe methods in this class
- // which do the actual work. That class contains
- // shared logic for doing this which is used by
- // ASCIIEncoding, EncodingNLS, UnicodeEncoding, UTF32Encoding,
- // UTF7Encoding, and UTF8Encoding.
- // The reason the code is separated out into a static class, rather
- // than a base class which overrides all of these methods for us
- // (which is what EncodingNLS is for internal Encodings) is because
- // that's really more of an implementation detail so it's internal.
- // At the same time, C# doesn't allow a public class subclassing an
- // internal/private one, so we end up having to re-override these
- // methods in all of the public Encodings + EncodingNLS.
-
- // Returns the number of bytes required to encode a range of characters in
- // a character array.
-
- public override int GetByteCount(char[] chars, int index, int count)
- {
- return EncodingForwarder.GetByteCount(this, chars, index, count);
- }
-
- public override int GetByteCount(String s)
- {
- return EncodingForwarder.GetByteCount(this, s);
- }
-
- [CLSCompliant(false)]
- public override unsafe int GetByteCount(char* chars, int count)
- {
- return EncodingForwarder.GetByteCount(this, chars, count);
- }
-
- public override int GetBytes(String s, int charIndex, int charCount,
- byte[] bytes, int byteIndex)
- {
- return EncodingForwarder.GetBytes(this, s, charIndex, charCount, bytes, byteIndex);
- }
-
- // Encodes a range of characters in a character array into a range of bytes
- // in a byte array. An exception occurs if the byte array is not large
- // enough to hold the complete encoding of the characters. The
- // GetByteCount method can be used to determine the exact number of
- // bytes that will be produced for a given range of characters.
- // Alternatively, the GetMaxByteCount method can be used to
- // determine the maximum number of bytes that will be produced for a given
- // number of characters, regardless of the actual character values.
-
- public override int GetBytes(char[] chars, int charIndex, int charCount,
- byte[] bytes, int byteIndex)
- {
- return EncodingForwarder.GetBytes(this, chars, charIndex, charCount, bytes, byteIndex);
- }
-
- [CLSCompliant(false)]
- public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
- {
- return EncodingForwarder.GetBytes(this, chars, charCount, bytes, byteCount);
- }
-
- // Returns the number of characters produced by decoding a range of bytes
- // in a byte array.
-
- public override int GetCharCount(byte[] bytes, int index, int count)
- {
- return EncodingForwarder.GetCharCount(this, bytes, index, count);
- }
-
- [CLSCompliant(false)]
- public override unsafe int GetCharCount(byte* bytes, int count)
- {
- return EncodingForwarder.GetCharCount(this, bytes, count);
- }
-
- public override int GetChars(byte[] bytes, int byteIndex, int byteCount,
- char[] chars, int charIndex)
- {
- return EncodingForwarder.GetChars(this, bytes, byteIndex, byteCount, chars, charIndex);
- }
-
- [CLSCompliant(false)]
- public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
- {
- return EncodingForwarder.GetChars(this, bytes, byteCount, chars, charCount);
- }
-
- // Returns a string containing the decoded representation of a range of
- // bytes in a byte array.
-
- public override String GetString(byte[] bytes, int index, int count)
- {
- return EncodingForwarder.GetString(this, bytes, index, count);
- }
-
- // End of overridden methods which use EncodingForwarder
-
- internal override unsafe int GetByteCount(char* chars, int count, EncoderNLS encoder)
- {
- Debug.Assert(chars!=null, "[UnicodeEncoding.GetByteCount]chars!=null");
- Debug.Assert(count >= 0, "[UnicodeEncoding.GetByteCount]count >=0");
-
- // Start by assuming each char gets 2 bytes
- int byteCount = count << 1;
-
- // Check for overflow in byteCount
- // (If they were all invalid chars, this would actually be wrong,
- // but that's a ridiculously large # so we're not concerned about that case)
- if (byteCount < 0)
- throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
-
- char* charStart = chars;
- char* charEnd = chars + count;
- char charLeftOver = (char)0;
-
- bool wasHereBefore = false;
-
- // Need -1 to check 2 at a time. If we have an even #, longChars will go
- // from longEnd - 1/2 long to longEnd + 1/2 long. If we're odd, longChars
- // will go from longEnd - 1 long to longEnd. (Might not get to use this)
- ulong* longEnd = (ulong*)(charEnd - 3);
-
- // For fallback we may need a fallback buffer
- EncoderFallbackBuffer fallbackBuffer = null;
-
- if (encoder != null)
- {
- charLeftOver = encoder.charLeftOver;
-
- // Assume extra bytes to encode charLeftOver if it existed
- if (charLeftOver > 0)
- byteCount+=2;
-
- // We mustn't have left over fallback data when counting
- if (encoder.InternalHasFallbackBuffer)
- {
- fallbackBuffer = encoder.FallbackBuffer;
- if (fallbackBuffer.Remaining > 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EncoderFallbackNotEmpty",
- this.EncodingName, encoder.Fallback.GetType()));
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, false);
- }
- }
-
- char ch;
- TryAgain:
-
- while (((ch = (fallbackBuffer == null) ? (char)0 :fallbackBuffer.InternalGetNextChar()) != 0) || chars < charEnd)
- {
- // First unwind any fallback
- if (ch == 0)
- {
- // No fallback, maybe we can do it fast
-#if !NO_FAST_UNICODE_LOOP
-#if BIGENDIAN // If endianess is backwards then each pair of bytes would be backwards.
- if ( bigEndian &&
-#else
- if ( !bigEndian &&
-#endif // BIGENDIAN
-
-#if BIT64 // 64 bit CPU needs to be long aligned for this to work.
- charLeftOver == 0 && (unchecked((long)chars) & 7) == 0)
-#else
- charLeftOver == 0 && (unchecked((int)chars) & 3) == 0)
-#endif
- {
- // Need new char* so we can check 4 at a time
- ulong* longChars = (ulong*)chars;
-
- while (longChars < longEnd)
- {
- // See if we potentially have surrogates (0x8000 bit set)
- // (We're either big endian on a big endian machine or little endian on
- // a little endian machine so this'll work)
- if ((0x8000800080008000 & *longChars) != 0)
- {
- // See if any of these are high or low surrogates (0xd800 - 0xdfff). If the high
- // 5 bits looks like 11011, then its a high or low surrogate.
- // We do the & f800 to filter the 5 bits, then ^ d800 to ensure the 0 isn't set.
- // Note that we expect BMP characters to be more common than surrogates
- // & each char with 11111... then ^ with 11011. Zeroes then indicate surrogates
- ulong uTemp = (0xf800f800f800f800 & *longChars) ^ 0xd800d800d800d800;
-
- // Check each of the 4 chars. 0 for those 16 bits means it was a surrogate
- // but no clue if they're high or low.
- // If each of the 4 characters are non-zero, then none are surrogates.
- if ((uTemp & 0xFFFF000000000000) == 0 ||
- (uTemp & 0x0000FFFF00000000) == 0 ||
- (uTemp & 0x00000000FFFF0000) == 0 ||
- (uTemp & 0x000000000000FFFF) == 0)
- {
- // It has at least 1 surrogate, but we don't know if they're high or low surrogates,
- // or if there's 1 or 4 surrogates
-
- // If they happen to be high/low/high/low, we may as well continue. Check the next
- // bit to see if its set (low) or not (high) in the right pattern
-#if BIGENDIAN
- if (((0xfc00fc00fc00fc00 & *longChars) ^ 0xd800dc00d800dc00) != 0)
-#else
- if (((0xfc00fc00fc00fc00 & *longChars) ^ 0xdc00d800dc00d800) != 0)
-#endif
- {
- // Either there weren't 4 surrogates, or the 0x0400 bit was set when a high
- // was hoped for or the 0x0400 bit wasn't set where a low was hoped for.
-
- // Drop out to the slow loop to resolve the surrogates
- break;
- }
- // else they are all surrogates in High/Low/High/Low order, so we can use them.
- }
- // else none are surrogates, so we can use them.
- }
- // else all < 0x8000 so we can use them
-
- // We already counted these four chars, go to next long.
- longChars++;
- }
-
- chars = (char*)longChars;
-
- if (chars >= charEnd)
- break;
- }
-#endif // !NO_FAST_UNICODE_LOOP
-
- // No fallback, just get next char
- ch = *chars;
- chars++;
- }
- else
- {
- // We weren't preallocating fallback space.
- byteCount+=2;
- }
-
- // Check for high or low surrogates
- if (ch >= 0xd800 && ch <= 0xdfff)
- {
- // Was it a high surrogate?
- if (ch <= 0xdbff)
- {
- // Its a high surrogate, if we already had a high surrogate do its fallback
- if (charLeftOver > 0)
- {
- // Unwind the current character, this should be safe because we
- // don't have leftover data in the fallback, so chars must have
- // advanced already.
- Debug.Assert(chars > charStart,
- "[UnicodeEncoding.GetByteCount]Expected chars to have advanced in unexpected high surrogate");
- chars--;
-
- // If previous high surrogate deallocate 2 bytes
- byteCount -= 2;
-
- // Fallback the previous surrogate
- // Need to initialize fallback buffer?
- if (fallbackBuffer == null)
- {
- if (encoder == null)
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = encoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, false);
- }
-
- fallbackBuffer.InternalFallback(charLeftOver, ref chars);
-
- // Now no high surrogate left over
- charLeftOver = (char)0;
- continue;
- }
-
- // Remember this high surrogate
- charLeftOver = ch;
- continue;
- }
-
-
- // Its a low surrogate
- if (charLeftOver == 0)
- {
- // Expected a previous high surrogate.
- // Don't count this one (we'll count its fallback if necessary)
- byteCount -= 2;
-
- // fallback this one
- // Need to initialize fallback buffer?
- if (fallbackBuffer == null)
- {
- if (encoder == null)
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = encoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, false);
- }
- fallbackBuffer.InternalFallback(ch, ref chars);
- continue;
- }
-
- // Valid surrogate pair, add our charLeftOver
- charLeftOver = (char)0;
- continue;
- }
- else if (charLeftOver > 0)
- {
- // Expected a low surrogate, but this char is normal
-
- // Rewind the current character, fallback previous character.
- // this should be safe because we don't have leftover data in the
- // fallback, so chars must have advanced already.
- Debug.Assert(chars > charStart,
- "[UnicodeEncoding.GetByteCount]Expected chars to have advanced when expected low surrogate");
- chars--;
-
- // fallback previous chars
- // Need to initialize fallback buffer?
- if (fallbackBuffer == null)
- {
- if (encoder == null)
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = encoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, false);
- }
- fallbackBuffer.InternalFallback(charLeftOver, ref chars);
-
- // Ignore charLeftOver or throw
- byteCount-=2;
- charLeftOver = (char)0;
-
- continue;
- }
-
- // Ok we had something to add (already counted)
- }
-
- // Don't allocate space for left over char
- if (charLeftOver > 0)
- {
- byteCount -= 2;
-
- // If we have to flush, stick it in fallback and try again
- if (encoder == null || encoder.MustFlush)
- {
- if (wasHereBefore)
- {
- // Throw it, using our complete character
- throw new ArgumentException(
- Environment.GetResourceString("Argument_RecursiveFallback",
- charLeftOver), nameof(chars));
- }
- else
- {
- // Need to initialize fallback buffer?
- if (fallbackBuffer == null)
- {
- if (encoder == null)
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = encoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, false);
- }
- fallbackBuffer.InternalFallback(charLeftOver, ref chars);
- charLeftOver = (char)0;
- wasHereBefore = true;
- goto TryAgain;
- }
- }
- }
-
- // Shouldn't have anything in fallback buffer for GetByteCount
- // (don't have to check m_throwOnOverflow for count)
- Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
- "[UnicodeEncoding.GetByteCount]Expected empty fallback buffer at end");
-
- // Don't remember fallbackBuffer.encoder for counting
- return byteCount;
- }
-
- internal override unsafe int GetBytes(char* chars, int charCount,
- byte* bytes, int byteCount, EncoderNLS encoder)
- {
- Debug.Assert(chars!=null, "[UnicodeEncoding.GetBytes]chars!=null");
- Debug.Assert(byteCount >=0, "[UnicodeEncoding.GetBytes]byteCount >=0");
- Debug.Assert(charCount >=0, "[UnicodeEncoding.GetBytes]charCount >=0");
- Debug.Assert(bytes!=null, "[UnicodeEncoding.GetBytes]bytes!=null");
-
- char charLeftOver = (char)0;
- char ch;
- bool wasHereBefore = false;
-
-
- byte* byteEnd = bytes + byteCount;
- char* charEnd = chars + charCount;
- byte* byteStart = bytes;
- char* charStart = chars;
-
- // For fallback we may need a fallback buffer
- EncoderFallbackBuffer fallbackBuffer = null;
-
- // Get our encoder, but don't clear it yet.
- if (encoder != null)
- {
- charLeftOver = encoder.charLeftOver;
-
- // We mustn't have left over fallback data when counting
- if (encoder.InternalHasFallbackBuffer)
- {
- // We always need the fallback buffer in get bytes so we can flush any remaining ones if necessary
- fallbackBuffer = encoder.FallbackBuffer;
- if (fallbackBuffer.Remaining > 0 && encoder.m_throwOnOverflow)
- throw new ArgumentException(Environment.GetResourceString("Argument_EncoderFallbackNotEmpty",
- this.EncodingName, encoder.Fallback.GetType()));
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, false);
- }
- }
-
- TryAgain:
- while (((ch = (fallbackBuffer == null) ?
- (char)0 : fallbackBuffer.InternalGetNextChar()) != 0) ||
- chars < charEnd)
- {
- // First unwind any fallback
- if (ch == 0)
- {
- // No fallback, maybe we can do it fast
-#if !NO_FAST_UNICODE_LOOP
-#if BIGENDIAN // If endianess is backwards then each pair of bytes would be backwards.
- if ( bigEndian &&
-#else
- if ( !bigEndian &&
-#endif // BIGENDIAN
-#if BIT64 // 64 bit CPU needs to be long aligned for this to work, 32 bit CPU needs to be 32 bit aligned
- (unchecked((long)chars) & 7) == 0 && (unchecked((long)bytes) & 7) == 0 &&
-#else
- (unchecked((int)chars) & 3) == 0 && (unchecked((int)bytes) & 3) == 0 &&
-#endif // BIT64
- charLeftOver == 0)
- {
- // Need -1 to check 2 at a time. If we have an even #, longChars will go
- // from longEnd - 1/2 long to longEnd + 1/2 long. If we're odd, longChars
- // will go from longEnd - 1 long to longEnd. (Might not get to use this)
- // We can only go iCount units (limited by shorter of char or byte buffers.
- ulong* longEnd = (ulong*)(chars - 3 +
- (((byteEnd - bytes) >> 1 < charEnd - chars) ?
- (byteEnd - bytes) >> 1 : charEnd - chars));
-
- // Need new char* so we can check 4 at a time
- ulong* longChars = (ulong*)chars;
- ulong* longBytes = (ulong*)bytes;
-
- while (longChars < longEnd)
- {
- // See if we potentially have surrogates (0x8000 bit set)
- // (We're either big endian on a big endian machine or little endian on
- // a little endian machine so this'll work)
- if ((0x8000800080008000 & *longChars) != 0)
- {
- // See if any of these are high or low surrogates (0xd800 - 0xdfff). If the high
- // 5 bits looks like 11011, then its a high or low surrogate.
- // We do the & f800 to filter the 5 bits, then ^ d800 to ensure the 0 isn't set.
- // Note that we expect BMP characters to be more common than surrogates
- // & each char with 11111... then ^ with 11011. Zeroes then indicate surrogates
- ulong uTemp = (0xf800f800f800f800 & *longChars) ^ 0xd800d800d800d800;
-
- // Check each of the 4 chars. 0 for those 16 bits means it was a surrogate
- // but no clue if they're high or low.
- // If each of the 4 characters are non-zero, then none are surrogates.
- if ((uTemp & 0xFFFF000000000000) == 0 ||
- (uTemp & 0x0000FFFF00000000) == 0 ||
- (uTemp & 0x00000000FFFF0000) == 0 ||
- (uTemp & 0x000000000000FFFF) == 0)
- {
- // It has at least 1 surrogate, but we don't know if they're high or low surrogates,
- // or if there's 1 or 4 surrogates
-
- // If they happen to be high/low/high/low, we may as well continue. Check the next
- // bit to see if its set (low) or not (high) in the right pattern
-#if BIGENDIAN
- if (((0xfc00fc00fc00fc00 & *longChars) ^ 0xd800dc00d800dc00) != 0)
-#else
- if (((0xfc00fc00fc00fc00 & *longChars) ^ 0xdc00d800dc00d800) != 0)
-#endif
- {
- // Either there weren't 4 surrogates, or the 0x0400 bit was set when a high
- // was hoped for or the 0x0400 bit wasn't set where a low was hoped for.
-
- // Drop out to the slow loop to resolve the surrogates
- break;
- }
- // else they are all surrogates in High/Low/High/Low order, so we can use them.
- }
- // else none are surrogates, so we can use them.
- }
- // else all < 0x8000 so we can use them
-
- // We can use these 4 chars.
- *longBytes = *longChars;
- longChars++;
- longBytes++;
- }
-
- chars = (char*)longChars;
- bytes = (byte*)longBytes;
-
- if (chars >= charEnd)
- break;
- }
- // Not aligned, but maybe we can still be somewhat faster
- // Also somehow this optimizes the above loop? It seems to cause something above
- // to get enregistered, but I haven't figured out how to make that happen without this loop.
- else if ((charLeftOver == 0) &&
-#if BIGENDIAN
- bigEndian &&
-#else
- !bigEndian &&
-#endif // BIGENDIAN
-
-#if BIT64
- (unchecked((long)chars) & 7) != (unchecked((long)bytes) & 7) && // Only do this if chars & bytes are out of line, otherwise faster loop'll be faster next time
-#else
- (unchecked((int)chars) & 3) != (unchecked((int)bytes) & 3) && // Only do this if chars & bytes are out of line, otherwise faster loop'll be faster next time
-#endif // BIT64
- (unchecked((int)(bytes)) & 1) == 0 )
- {
- // # to use
- long iCount = ((byteEnd - bytes) >> 1 < charEnd - chars) ?
- (byteEnd - bytes) >> 1 : charEnd - chars;
-
- // Need new char*
- char* charOut = ((char*)bytes); // a char* for our output
- char* tempEnd = chars + iCount - 1; // Our end pointer
-
- while (chars < tempEnd)
- {
- if (*chars >= (char)0xd800 && *chars <= (char)0xdfff)
- {
- // break for fallback for low surrogate
- if (*chars >= 0xdc00)
- break;
-
- // break if next one's not a low surrogate (will do fallback)
- if (*(chars+1) < 0xdc00 || *(chars+1) > 0xdfff)
- break;
-
- // They both exist, use them
- }
- // If 2nd char is surrogate & this one isn't then only add one
- else if (*(chars+1) >= (char)0xd800 && *(chars+1) <= 0xdfff)
- {
- *charOut = *chars;
- charOut++;
- chars++;
- continue;
- }
-
- *charOut = *chars;
- *(charOut+1) = *(chars+1);
- charOut+=2;
- chars+=2;
-
- }
-
- bytes=(byte*)charOut;
-
- if (chars >= charEnd)
- break;
- }
-#endif // !NO_FAST_UNICODE_LOOP
-
- // No fallback, just get next char
- ch = *chars;
- chars++;
- }
-
- // Check for high or low surrogates
- if (ch >= 0xd800 && ch <= 0xdfff)
- {
- // Was it a high surrogate?
- if (ch <= 0xdbff)
- {
- // Its a high surrogate, see if we already had a high surrogate
- if (charLeftOver > 0)
- {
- // Unwind the current character, this should be safe because we
- // don't have leftover data in the fallback, so chars must have
- // advanced already.
- Debug.Assert(chars > charStart,
- "[UnicodeEncoding.GetBytes]Expected chars to have advanced in unexpected high surrogate");
- chars--;
-
- // Fallback the previous surrogate
- // Might need to create our fallback buffer
- if (fallbackBuffer == null)
- {
- if (encoder == null)
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = encoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, true);
- }
-
- fallbackBuffer.InternalFallback(charLeftOver, ref chars);
-
- charLeftOver = (char)0;
- continue;
- }
-
- // Remember this high surrogate
- charLeftOver = ch;
- continue;
- }
-
- // Its a low surrogate
- if (charLeftOver == 0)
- {
- // We'll fall back this one
- // Might need to create our fallback buffer
- if (fallbackBuffer == null)
- {
- if (encoder == null)
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = encoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, true);
- }
-
- fallbackBuffer.InternalFallback(ch, ref chars);
- continue;
- }
-
- // Valid surrogate pair, add our charLeftOver
- if (bytes + 3 >= byteEnd)
- {
- // Not enough room to add this surrogate pair
- if (fallbackBuffer != null && fallbackBuffer.bFallingBack)
- {
- // These must have both been from the fallbacks.
- // Both of these MUST have been from a fallback because if the 1st wasn't
- // from a fallback, then a high surrogate followed by an illegal char
- // would've caused the high surrogate to fall back. If a high surrogate
- // fell back, then it was consumed and both chars came from the fallback.
- fallbackBuffer.MovePrevious(); // Didn't use either fallback surrogate
- fallbackBuffer.MovePrevious();
- }
- else
- {
- // If we don't have enough room, then either we should've advanced a while
- // or we should have bytes==byteStart and throw below
- Debug.Assert(chars > charStart + 1 || bytes == byteStart,
- "[UnicodeEncoding.GetBytes]Expected chars to have when no room to add surrogate pair");
- chars-=2; // Didn't use either surrogate
- }
- ThrowBytesOverflow(encoder, bytes == byteStart); // Throw maybe (if no bytes written)
- charLeftOver = (char)0; // we'll retry it later
- break; // Didn't throw, but stop 'til next time.
- }
-
- if (bigEndian)
- {
- *(bytes++) = (byte)(charLeftOver >> 8);
- *(bytes++) = (byte)charLeftOver;
- }
- else
- {
- *(bytes++) = (byte)charLeftOver;
- *(bytes++) = (byte)(charLeftOver >> 8);
- }
-
- charLeftOver = (char)0;
- }
- else if (charLeftOver > 0)
- {
- // Expected a low surrogate, but this char is normal
-
- // Rewind the current character, fallback previous character.
- // this should be safe because we don't have leftover data in the
- // fallback, so chars must have advanced already.
- Debug.Assert(chars > charStart,
- "[UnicodeEncoding.GetBytes]Expected chars to have advanced after expecting low surrogate");
- chars--;
-
- // fallback previous chars
- // Might need to create our fallback buffer
- if (fallbackBuffer == null)
- {
- if (encoder == null)
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = encoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, true);
- }
-
- fallbackBuffer.InternalFallback(charLeftOver, ref chars);
-
- // Ignore charLeftOver or throw
- charLeftOver = (char)0;
- continue;
- }
-
- // Ok, we have a char to add
- if (bytes + 1 >= byteEnd)
- {
- // Couldn't add this char
- if (fallbackBuffer != null && fallbackBuffer.bFallingBack)
- fallbackBuffer.MovePrevious(); // Not using this fallback char
- else
- {
- // Lonely charLeftOver (from previous call) would've been caught up above,
- // so this must be a case where we've already read an input char.
- Debug.Assert(chars > charStart,
- "[UnicodeEncoding.GetBytes]Expected chars to have advanced for failed fallback");
- chars--; // Not using this char
- }
- ThrowBytesOverflow(encoder, bytes == byteStart); // Throw maybe (if no bytes written)
- break; // didn't throw, just stop
- }
-
- if (bigEndian)
- {
- *(bytes++) = (byte)(ch >> 8);
- *(bytes++) = (byte)ch;
- }
- else
- {
- *(bytes++) = (byte)ch;
- *(bytes++) = (byte)(ch >> 8);
- }
- }
-
- // Don't allocate space for left over char
- if (charLeftOver > 0)
- {
- // If we aren't flushing we need to fall this back
- if (encoder == null || encoder.MustFlush)
- {
- if (wasHereBefore)
- {
- // Throw it, using our complete character
- throw new ArgumentException(
- Environment.GetResourceString("Argument_RecursiveFallback",
- charLeftOver), nameof(chars));
- }
- else
- {
- // If we have to flush, stick it in fallback and try again
- // Might need to create our fallback buffer
- if (fallbackBuffer == null)
- {
- if (encoder == null)
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = encoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, true);
- }
-
- // If we're not flushing, this'll remember the left over character.
- fallbackBuffer.InternalFallback(charLeftOver, ref chars);
-
- charLeftOver = (char)0;
- wasHereBefore = true;
- goto TryAgain;
- }
- }
-
- }
-
- // Not flushing, remember it in the encoder
- if (encoder != null)
- {
- encoder.charLeftOver = charLeftOver;
- encoder.m_charsUsed = (int)(chars - charStart);
- }
-
- // Remember charLeftOver if we must, or clear it if we're flushing
- // (charLeftOver should be 0 if we're flushing)
- Debug.Assert((encoder != null && !encoder.MustFlush) || charLeftOver == (char)0,
- "[UnicodeEncoding.GetBytes] Expected no left over characters if flushing");
-
- Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0 ||
- encoder == null || !encoder.m_throwOnOverflow,
- "[UnicodeEncoding.GetBytes]Expected empty fallback buffer if not converting");
-
- // We used to copy it fast, but this doesn't check for surrogates
- // System.IO.__UnmanagedMemoryStream.memcpyimpl(bytes, (byte*)chars, usedByteCount);
-
- return (int)(bytes - byteStart);
- }
-
- internal override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS baseDecoder)
- {
- Debug.Assert(bytes!=null, "[UnicodeEncoding.GetCharCount]bytes!=null");
- Debug.Assert(count >= 0, "[UnicodeEncoding.GetCharCount]count >=0");
-
- UnicodeEncoding.Decoder decoder = (UnicodeEncoding.Decoder)baseDecoder;
-
- byte* byteEnd = bytes + count;
- byte* byteStart = bytes;
-
- // Need last vars
- int lastByte = -1;
- char lastChar = (char)0;
-
- // Start by assuming same # of chars as bytes
- int charCount = count >> 1;
-
- // Need -1 to check 2 at a time. If we have an even #, longBytes will go
- // from longEnd - 1/2 long to longEnd + 1/2 long. If we're odd, longBytes
- // will go from longEnd - 1 long to longEnd. (Might not get to use this)
- ulong* longEnd = (ulong*)(byteEnd - 7);
-
- // For fallback we may need a fallback buffer
- DecoderFallbackBuffer fallbackBuffer = null;
-
- if (decoder != null)
- {
- lastByte = decoder.lastByte;
- lastChar = decoder.lastChar;
-
- // Assume extra char if last char was around
- if (lastChar > 0)
- charCount++;
-
- // Assume extra char if extra last byte makes up odd # of input bytes
- if (lastByte >= 0 && (count & 1) == 1)
- {
- charCount++;
- }
-
- // Shouldn't have anything in fallback buffer for GetCharCount
- // (don't have to check m_throwOnOverflow for count)
- Debug.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
- "[UnicodeEncoding.GetCharCount]Expected empty fallback buffer at start");
- }
-
- while (bytes < byteEnd)
- {
- // If we're aligned then maybe we can do it fast
- // This'll hurt if we're unaligned because we'll always test but never be aligned
-#if !NO_FAST_UNICODE_LOOP
-#if BIGENDIAN
- if (bigEndian &&
-#else // BIGENDIAN
- if (!bigEndian &&
-#endif // BIGENDIAN
-#if BIT64 // win64 has to be long aligned
- (unchecked((long)bytes) & 7) == 0 &&
-#else
- (unchecked((int)bytes) & 3) == 0 &&
-#endif // BIT64
- lastByte == -1 && lastChar == 0)
- {
- // Need new char* so we can check 4 at a time
- ulong* longBytes = (ulong*)bytes;
-
- while (longBytes < longEnd)
- {
- // See if we potentially have surrogates (0x8000 bit set)
- // (We're either big endian on a big endian machine or little endian on
- // a little endian machine so this'll work)
- if ((0x8000800080008000 & *longBytes) != 0)
- {
- // See if any of these are high or low surrogates (0xd800 - 0xdfff). If the high
- // 5 bits looks like 11011, then its a high or low surrogate.
- // We do the & f800 to filter the 5 bits, then ^ d800 to ensure the 0 isn't set.
- // Note that we expect BMP characters to be more common than surrogates
- // & each char with 11111... then ^ with 11011. Zeroes then indicate surrogates
- ulong uTemp = (0xf800f800f800f800 & *longBytes) ^ 0xd800d800d800d800;
-
- // Check each of the 4 chars. 0 for those 16 bits means it was a surrogate
- // but no clue if they're high or low.
- // If each of the 4 characters are non-zero, then none are surrogates.
- if ((uTemp & 0xFFFF000000000000) == 0 ||
- (uTemp & 0x0000FFFF00000000) == 0 ||
- (uTemp & 0x00000000FFFF0000) == 0 ||
- (uTemp & 0x000000000000FFFF) == 0)
- {
- // It has at least 1 surrogate, but we don't know if they're high or low surrogates,
- // or if there's 1 or 4 surrogates
-
- // If they happen to be high/low/high/low, we may as well continue. Check the next
- // bit to see if its set (low) or not (high) in the right pattern
-#if BIGENDIAN
- if (((0xfc00fc00fc00fc00 & *longBytes) ^ 0xd800dc00d800dc00) != 0)
-#else
- if (((0xfc00fc00fc00fc00 & *longBytes) ^ 0xdc00d800dc00d800) != 0)
-#endif
- {
- // Either there weren't 4 surrogates, or the 0x0400 bit was set when a high
- // was hoped for or the 0x0400 bit wasn't set where a low was hoped for.
-
- // Drop out to the slow loop to resolve the surrogates
- break;
- }
- // else they are all surrogates in High/Low/High/Low order, so we can use them.
- }
- // else none are surrogates, so we can use them.
- }
- // else all < 0x8000 so we can use them
-
- // We can use these 4 chars.
- longBytes++;
- }
-
- bytes = (byte*)longBytes;
-
- if (bytes >= byteEnd)
- break;
- }
-#endif // !NO_FAST_UNICODE_LOOP
-
- // Get 1st byte
- if (lastByte < 0)
- {
- lastByte = *bytes++;
- if (bytes >= byteEnd) break;
- }
-
- // Get full char
- char ch;
- if (bigEndian)
- {
- ch = (char)(lastByte << 8 | *(bytes++));
- }
- else
- {
- ch = (char)(*(bytes++) << 8 | lastByte);
- }
- lastByte = -1;
-
- // See if the char's valid
- if (ch >= 0xd800 && ch <= 0xdfff)
- {
- // Was it a high surrogate?
- if (ch <= 0xdbff)
- {
- // Its a high surrogate, if we had one then do fallback for previous one
- if (lastChar > 0)
- {
- // Ignore previous bad high surrogate
- charCount--;
-
- // Get fallback for previous high surrogate
- // Note we have to reconstruct bytes because some may have been in decoder
- byte[] byteBuffer = null;
- if (bigEndian)
- {
- byteBuffer = new byte[]
- { unchecked((byte)(lastChar >> 8)), unchecked((byte)lastChar) };
- }
- else
- {
- byteBuffer = new byte[]
- { unchecked((byte)lastChar), unchecked((byte)(lastChar >> 8)) };
-
- }
-
- if (fallbackBuffer == null)
- {
- if (decoder == null)
- fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = decoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(byteStart, null);
- }
-
- // Get fallback.
- charCount += fallbackBuffer.InternalFallback(byteBuffer, bytes);
- }
-
- // Ignore the last one which fell back already,
- // and remember the new high surrogate
- lastChar = ch;
- continue;
- }
-
- // Its a low surrogate
- if (lastChar == 0)
- {
- // Expected a previous high surrogate
- charCount--;
-
- // Get fallback for this low surrogate
- // Note we have to reconstruct bytes because some may have been in decoder
- byte[] byteBuffer = null;
- if (bigEndian)
- {
- byteBuffer = new byte[]
- { unchecked((byte)(ch >> 8)), unchecked((byte)ch) };
- }
- else
- {
- byteBuffer = new byte[]
- { unchecked((byte)ch), unchecked((byte)(ch >> 8)) };
-
- }
-
- if (fallbackBuffer == null)
- {
- if (decoder == null)
- fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = decoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(byteStart, null);
- }
-
- charCount += fallbackBuffer.InternalFallback(byteBuffer, bytes);
-
- // Ignore this one (we already did its fallback)
- continue;
- }
-
- // Valid surrogate pair, already counted.
- lastChar = (char)0;
- }
- else if (lastChar > 0)
- {
- // Had a high surrogate, expected a low surrogate
- // Uncount the last high surrogate
- charCount--;
-
- // fall back the high surrogate.
- byte[] byteBuffer = null;
- if (bigEndian)
- {
- byteBuffer = new byte[]
- { unchecked((byte)(lastChar >> 8)), unchecked((byte)lastChar) };
- }
- else
- {
- byteBuffer = new byte[]
- { unchecked((byte)lastChar), unchecked((byte)(lastChar >> 8)) };
-
- }
-
- if (fallbackBuffer == null)
- {
- if (decoder == null)
- fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = decoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(byteStart, null);
- }
-
- // Already subtracted high surrogate
- charCount += fallbackBuffer.InternalFallback(byteBuffer, bytes);
-
- // Not left over now, clear previous high surrogate and continue to add current char
- lastChar = (char)0;
- }
-
- // Valid char, already counted
- }
-
- // Extra space if we can't use decoder
- if (decoder == null || decoder.MustFlush)
- {
- if (lastChar > 0)
- {
- // No hanging high surrogates allowed, do fallback and remove count for it
- charCount--;
- byte[] byteBuffer = null;
- if (bigEndian)
- {
- byteBuffer = new byte[]
- { unchecked((byte)(lastChar >> 8)), unchecked((byte)lastChar) };
- }
- else
- {
- byteBuffer = new byte[]
- { unchecked((byte)lastChar), unchecked((byte)(lastChar >> 8)) };
-
- }
-
- if (fallbackBuffer == null)
- {
- if (decoder == null)
- fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = decoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(byteStart, null);
- }
-
- charCount += fallbackBuffer.InternalFallback(byteBuffer, bytes);
-
- lastChar = (char)0;
- }
-
- if (lastByte >= 0)
- {
- if (fallbackBuffer == null)
- {
- if (decoder == null)
- fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = decoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(byteStart, null);
- }
-
- // No hanging odd bytes allowed if must flush
- charCount += fallbackBuffer.InternalFallback( new byte[] { unchecked((byte)lastByte) }, bytes);
- lastByte = -1;
- }
- }
-
- // If we had a high surrogate left over, we can't count it
- if (lastChar > 0)
- charCount--;
-
- // Shouldn't have anything in fallback buffer for GetCharCount
- // (don't have to check m_throwOnOverflow for count)
- Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
- "[UnicodeEncoding.GetCharCount]Expected empty fallback buffer at end");
-
- return charCount;
- }
-
- internal override unsafe int GetChars(byte* bytes, int byteCount,
- char* chars, int charCount, DecoderNLS baseDecoder )
- {
- Debug.Assert(chars!=null, "[UnicodeEncoding.GetChars]chars!=null");
- Debug.Assert(byteCount >=0, "[UnicodeEncoding.GetChars]byteCount >=0");
- Debug.Assert(charCount >=0, "[UnicodeEncoding.GetChars]charCount >=0");
- Debug.Assert(bytes!=null, "[UnicodeEncoding.GetChars]bytes!=null");
-
- UnicodeEncoding.Decoder decoder = (UnicodeEncoding.Decoder)baseDecoder;
-
- // Need last vars
- int lastByte = -1;
- char lastChar = (char)0;
-
- // Get our decoder (but don't clear it yet)
- if (decoder != null)
- {
- lastByte = decoder.lastByte;
- lastChar = decoder.lastChar;
-
- // Shouldn't have anything in fallback buffer for GetChars
- // (don't have to check m_throwOnOverflow for chars)
- Debug.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0,
- "[UnicodeEncoding.GetChars]Expected empty fallback buffer at start");
- }
-
- // For fallback we may need a fallback buffer
- DecoderFallbackBuffer fallbackBuffer = null;
-
- byte* byteEnd = bytes + byteCount;
- char* charEnd = chars + charCount;
- byte* byteStart = bytes;
- char* charStart = chars;
-
- while (bytes < byteEnd)
- {
- // If we're aligned then maybe we can do it fast
- // This'll hurt if we're unaligned because we'll always test but never be aligned
-#if !NO_FAST_UNICODE_LOOP
-#if BIGENDIAN
- if (bigEndian &&
-#else // BIGENDIAN
- if (!bigEndian &&
-#endif // BIGENDIAN
-#if BIT64 // win64 has to be long aligned
- (unchecked((long)chars) & 7) == 0 && (unchecked((long)bytes) & 7) == 0 &&
-#else
- (unchecked((int)chars) & 3) == 0 && (unchecked((int)bytes) & 3) == 0 &&
-#endif // BIT64
- lastByte == -1 && lastChar == 0)
- {
- // Need -1 to check 2 at a time. If we have an even #, longChars will go
- // from longEnd - 1/2 long to longEnd + 1/2 long. If we're odd, longChars
- // will go from longEnd - 1 long to longEnd. (Might not get to use this)
- // We can only go iCount units (limited by shorter of char or byte buffers.
- ulong* longEnd = (ulong*)(bytes - 7 +
- (((byteEnd - bytes) >> 1 < charEnd - chars) ?
- (byteEnd - bytes) : (charEnd - chars) << 1));
-
- // Need new char* so we can check 4 at a time
- ulong* longBytes = (ulong*)bytes;
- ulong* longChars = (ulong*)chars;
-
- while (longBytes < longEnd)
- {
- // See if we potentially have surrogates (0x8000 bit set)
- // (We're either big endian on a big endian machine or little endian on
- // a little endian machine so this'll work)
- if ((0x8000800080008000 & *longBytes) != 0)
- {
- // See if any of these are high or low surrogates (0xd800 - 0xdfff). If the high
- // 5 bits looks like 11011, then its a high or low surrogate.
- // We do the & f800 to filter the 5 bits, then ^ d800 to ensure the 0 isn't set.
- // Note that we expect BMP characters to be more common than surrogates
- // & each char with 11111... then ^ with 11011. Zeroes then indicate surrogates
- ulong uTemp = (0xf800f800f800f800 & *longBytes) ^ 0xd800d800d800d800;
-
- // Check each of the 4 chars. 0 for those 16 bits means it was a surrogate
- // but no clue if they're high or low.
- // If each of the 4 characters are non-zero, then none are surrogates.
- if ((uTemp & 0xFFFF000000000000) == 0 ||
- (uTemp & 0x0000FFFF00000000) == 0 ||
- (uTemp & 0x00000000FFFF0000) == 0 ||
- (uTemp & 0x000000000000FFFF) == 0)
- {
- // It has at least 1 surrogate, but we don't know if they're high or low surrogates,
- // or if there's 1 or 4 surrogates
-
- // If they happen to be high/low/high/low, we may as well continue. Check the next
- // bit to see if its set (low) or not (high) in the right pattern
-#if BIGENDIAN
- if (((0xfc00fc00fc00fc00 & *longBytes) ^ 0xd800dc00d800dc00) != 0)
-#else
- if (((0xfc00fc00fc00fc00 & *longBytes) ^ 0xdc00d800dc00d800) != 0)
-#endif
- {
- // Either there weren't 4 surrogates, or the 0x0400 bit was set when a high
- // was hoped for or the 0x0400 bit wasn't set where a low was hoped for.
-
- // Drop out to the slow loop to resolve the surrogates
- break;
- }
- // else they are all surrogates in High/Low/High/Low order, so we can use them.
- }
- // else none are surrogates, so we can use them.
- }
- // else all < 0x8000 so we can use them
-
- // We can use these 4 chars.
- *longChars = *longBytes;
- longBytes++;
- longChars++;
- }
-
- chars = (char*)longChars;
- bytes = (byte*)longBytes;
-
- if (bytes >= byteEnd)
- break;
- }
-#endif // !NO_FAST_UNICODE_LOOP
-
- // Get 1st byte
- if (lastByte < 0)
- {
- lastByte = *bytes++;
- continue;
- }
-
- // Get full char
- char ch;
- if (bigEndian)
- {
- ch = (char)(lastByte << 8 | *(bytes++));
- }
- else
- {
- ch = (char)(*(bytes++) << 8 | lastByte);
- }
- lastByte = -1;
-
- // See if the char's valid
- if (ch >= 0xd800 && ch <= 0xdfff)
- {
- // Was it a high surrogate?
- if (ch <= 0xdbff)
- {
- // Its a high surrogate, if we had one then do fallback for previous one
- if (lastChar > 0)
- {
- // Get fallback for previous high surrogate
- // Note we have to reconstruct bytes because some may have been in decoder
- byte[] byteBuffer = null;
- if (bigEndian)
- {
- byteBuffer = new byte[]
- { unchecked((byte)(lastChar >> 8)), unchecked((byte)lastChar) };
- }
- else
- {
- byteBuffer = new byte[]
- { unchecked((byte)lastChar), unchecked((byte)(lastChar >> 8)) };
-
- }
-
- if (fallbackBuffer == null)
- {
- if (decoder == null)
- fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = decoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(byteStart, charEnd);
- }
-
- if (!fallbackBuffer.InternalFallback(byteBuffer, bytes, ref chars))
- {
- // couldn't fall back lonely surrogate
- // We either advanced bytes or chars should == charStart and throw below
- Debug.Assert(bytes >= byteStart + 2 || chars == charStart,
- "[UnicodeEncoding.GetChars]Expected bytes to have advanced or no output (bad surrogate)");
- bytes-=2; // didn't use these 2 bytes
- fallbackBuffer.InternalReset();
- ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
- break; // couldn't fallback but didn't throw
- }
- }
-
- // Ignore the previous high surrogate which fell back already,
- // yet remember the current high surrogate for next time.
- lastChar = ch;
- continue;
- }
-
- // Its a low surrogate
- if (lastChar == 0)
- {
- // Expected a previous high surrogate
- // Get fallback for this low surrogate
- // Note we have to reconstruct bytes because some may have been in decoder
- byte[] byteBuffer = null;
- if (bigEndian)
- {
- byteBuffer = new byte[]
- { unchecked((byte)(ch >> 8)), unchecked((byte)ch) };
- }
- else
- {
- byteBuffer = new byte[]
- { unchecked((byte)ch), unchecked((byte)(ch >> 8)) };
-
- }
-
- if (fallbackBuffer == null)
- {
- if (decoder == null)
- fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = decoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(byteStart, charEnd);
- }
-
- if (!fallbackBuffer.InternalFallback(byteBuffer, bytes, ref chars))
- {
- // couldn't fall back lonely surrogate
- // We either advanced bytes or chars should == charStart and throw below
- Debug.Assert(bytes >= byteStart + 2 || chars == charStart,
- "[UnicodeEncoding.GetChars]Expected bytes to have advanced or no output (lonely surrogate)");
- bytes-=2; // didn't use these 2 bytes
- fallbackBuffer.InternalReset();
- ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
- break; // couldn't fallback but didn't throw
- }
-
- // Didn't throw, ignore this one (we already did its fallback)
- continue;
- }
-
- // Valid surrogate pair, add our lastChar (will need 2 chars)
- if (chars >= charEnd - 1)
- {
- // couldn't find room for this surrogate pair
- // We either advanced bytes or chars should == charStart and throw below
- Debug.Assert(bytes >= byteStart + 2 || chars == charStart,
- "[UnicodeEncoding.GetChars]Expected bytes to have advanced or no output (surrogate pair)");
- bytes-=2; // didn't use these 2 bytes
- ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
- // Leave lastChar for next call to Convert()
- break; // couldn't fallback but didn't throw
- }
-
- *chars++ = lastChar;
- lastChar = (char)0;
- }
- else if (lastChar > 0)
- {
- // Had a high surrogate, expected a low surrogate, fall back the high surrogate.
- byte[] byteBuffer = null;
- if (bigEndian)
- {
- byteBuffer = new byte[]
- { unchecked((byte)(lastChar >> 8)), unchecked((byte)lastChar) };
- }
- else
- {
- byteBuffer = new byte[]
- { unchecked((byte)lastChar), unchecked((byte)(lastChar >> 8)) };
-
- }
-
- if (fallbackBuffer == null)
- {
- if (decoder == null)
- fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = decoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(byteStart, charEnd);
- }
-
- if (!fallbackBuffer.InternalFallback(byteBuffer, bytes, ref chars))
- {
- // couldn't fall back high surrogate, or char that would be next
- // We either advanced bytes or chars should == charStart and throw below
- Debug.Assert(bytes >= byteStart + 2 || chars == charStart,
- "[UnicodeEncoding.GetChars]Expected bytes to have advanced or no output (no low surrogate)");
- bytes-=2; // didn't use these 2 bytes
- fallbackBuffer.InternalReset();
- ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
- break; // couldn't fallback but didn't throw
- }
-
- // Not left over now, clear previous high surrogate and continue to add current char
- lastChar = (char)0;
- }
-
- // Valid char, room for it?
- if (chars >= charEnd)
- {
- // 2 bytes couldn't fall back
- // We either advanced bytes or chars should == charStart and throw below
- Debug.Assert(bytes >= byteStart + 2 || chars == charStart,
- "[UnicodeEncoding.GetChars]Expected bytes to have advanced or no output (normal)");
- bytes-=2; // didn't use these bytes
- ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
- break; // couldn't fallback but didn't throw
- }
-
- // add it
- *chars++ = ch;
- }
-
- // Remember our decoder if we must
- if (decoder == null || decoder.MustFlush)
- {
- if (lastChar > 0)
- {
- // No hanging high surrogates allowed, do fallback and remove count for it
- byte[] byteBuffer = null;
- if (bigEndian)
- {
- byteBuffer = new byte[]
- { unchecked((byte)(lastChar >> 8)), unchecked((byte)lastChar) };
- }
- else
- {
- byteBuffer = new byte[]
- { unchecked((byte)lastChar), unchecked((byte)(lastChar >> 8)) };
-
- }
-
- if (fallbackBuffer == null)
- {
- if (decoder == null)
- fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = decoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(byteStart, charEnd);
- }
-
- if (!fallbackBuffer.InternalFallback(byteBuffer, bytes, ref chars))
- {
- // 2 bytes couldn't fall back
- // We either advanced bytes or chars should == charStart and throw below
- Debug.Assert(bytes >= byteStart + 2 || chars == charStart,
- "[UnicodeEncoding.GetChars]Expected bytes to have advanced or no output (decoder)");
- bytes-=2; // didn't use these bytes
- if (lastByte >= 0)
- bytes--; // had an extra last byte hanging around
- fallbackBuffer.InternalReset();
- ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
- // We'll remember these in our decoder though
- bytes+=2;
- if (lastByte >= 0)
- bytes++;
- goto End;
- }
-
- // done with this one
- lastChar = (char)0;
- }
-
- if (lastByte >= 0)
- {
- if (fallbackBuffer == null)
- {
- if (decoder == null)
- fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = decoder.FallbackBuffer;
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(byteStart, charEnd);
- }
-
- // No hanging odd bytes allowed if must flush
- if (!fallbackBuffer.InternalFallback( new byte[] { unchecked((byte)lastByte) }, bytes, ref chars ))
- {
- // odd byte couldn't fall back
- bytes--; // didn't use this byte
- fallbackBuffer.InternalReset();
- ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
- // didn't throw, but we'll remember it in the decoder
- bytes++;
- goto End;
- }
-
- // Didn't fail, clear buffer
- lastByte = -1;
- }
- }
-
- End:
-
- // Remember our decoder if we must
- if (decoder != null)
- {
- Debug.Assert((decoder.MustFlush == false) || ((lastChar == (char)0) && (lastByte == -1)),
- "[UnicodeEncoding.GetChars] Expected no left over chars or bytes if flushing"
-// + " " + ((int)lastChar).ToString("X4") + " " + lastByte.ToString("X2")
- );
-
- decoder.m_bytesUsed = (int)(bytes - byteStart);
- decoder.lastChar = lastChar;
- decoder.lastByte = lastByte;
- }
-
- // Used to do this the old way
- // System.IO.__UnmanagedMemoryStream.memcpyimpl((byte*)chars, bytes, byteCount);
-
- // Shouldn't have anything in fallback buffer for GetChars
- // (don't have to check m_throwOnOverflow for count or chars)
- Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
- "[UnicodeEncoding.GetChars]Expected empty fallback buffer at end");
-
- return (int)(chars - charStart);
- }
-
-
- public override System.Text.Encoder GetEncoder()
- {
- return new EncoderNLS(this);
- }
-
-
- public override System.Text.Decoder GetDecoder()
- {
- return new UnicodeEncoding.Decoder(this);
- }
-
-
- public override byte[] GetPreamble()
- {
- if (byteOrderMark)
- {
- // Note - we must allocate new byte[]'s here to prevent someone
- // from modifying a cached byte[].
- if (bigEndian)
- return new byte[2] { 0xfe, 0xff };
- else
- return new byte[2] { 0xff, 0xfe };
- }
- return EmptyArray<Byte>.Value;
- }
-
-
- public override int GetMaxByteCount(int charCount)
- {
- if (charCount < 0)
- throw new ArgumentOutOfRangeException(nameof(charCount),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // Characters would be # of characters + 1 in case left over high surrogate is ? * max fallback
- long byteCount = (long)charCount + 1;
-
- if (EncoderFallback.MaxCharCount > 1)
- byteCount *= EncoderFallback.MaxCharCount;
-
- // 2 bytes per char
- byteCount <<= 1;
-
- if (byteCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException(nameof(charCount), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
-
- return (int)byteCount;
- }
-
-
- public override int GetMaxCharCount(int byteCount)
- {
- if (byteCount < 0)
- throw new ArgumentOutOfRangeException(nameof(byteCount),
- Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
- Contract.EndContractBlock();
-
- // long because byteCount could be biggest int.
- // 1 char per 2 bytes. Round up in case 1 left over in decoder.
- // Round up using &1 in case byteCount is max size
- // Might also need an extra 1 if there's a left over high surrogate in the decoder.
- long charCount = (long)(byteCount >> 1) + (byteCount & 1) + 1;
-
- // Don't forget fallback (in case they have a bunch of lonely surrogates or something bizzare like that)
- if (DecoderFallback.MaxCharCount > 1)
- charCount *= DecoderFallback.MaxCharCount;
-
- if (charCount > 0x7fffffff)
- throw new ArgumentOutOfRangeException(nameof(byteCount), Environment.GetResourceString("ArgumentOutOfRange_GetCharCountOverflow"));
-
- return (int)charCount;
- }
-
-
- public override bool Equals(Object value)
- {
- UnicodeEncoding that = value as UnicodeEncoding;
- if (that != null)
- {
- //
- // Big Endian Unicode has different code page (1201) than small Endian one (1200),
- // so we still have to check m_codePage here.
- //
- return (CodePage == that.CodePage) &&
- byteOrderMark == that.byteOrderMark &&
-// isThrowException == that.isThrowException && // Same as Encoder/Decoder being exception fallbacks
- bigEndian == that.bigEndian &&
- (EncoderFallback.Equals(that.EncoderFallback)) &&
- (DecoderFallback.Equals(that.DecoderFallback));
- }
- return (false);
- }
-
- public override int GetHashCode()
- {
- return CodePage + this.EncoderFallback.GetHashCode() + this.DecoderFallback.GetHashCode() +
- (byteOrderMark?4:0) + (bigEndian?8:0);
- }
-
- [Serializable]
- private class Decoder : System.Text.DecoderNLS, ISerializable
- {
- internal int lastByte = -1;
- internal char lastChar = '\0';
-
- public Decoder(UnicodeEncoding encoding) : base(encoding)
- {
- // base calls reset
- }
-
- // Constructor called by serialization, have to handle deserializing from Everett
- internal Decoder(SerializationInfo info, StreamingContext context)
- {
- // Any info?
- if (info==null) throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- // Get Common Info
- this.lastByte = (int)info.GetValue("lastByte", typeof(int));
-
- try
- {
- // Try the encoding, which is only serialized in Whidbey
- this.m_encoding = (Encoding)info.GetValue("m_encoding", typeof(Encoding));
- this.lastChar = (char)info.GetValue("lastChar", typeof(char));
- this.m_fallback = (DecoderFallback)info.GetValue("m_fallback", typeof(DecoderFallback));
- }
- catch (SerializationException)
- {
- // Everett didn't serialize the UnicodeEncoding, get the default one
- bool bigEndian = (bool)info.GetValue("bigEndian", typeof(bool));
- this.m_encoding = new UnicodeEncoding(bigEndian, false);
- }
- }
-
- // ISerializable implementation, get data for this object
- void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
- {
- // Any info?
- if (info==null) throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- // Save Whidbey data
- info.AddValue("m_encoding", this.m_encoding);
- info.AddValue("m_fallback", this.m_fallback);
- info.AddValue("lastChar", this.lastChar); // Unused by everett so it'll probably get lost
- info.AddValue("lastByte", this.lastByte);
-
- // Everett Only
- info.AddValue("bigEndian", ((UnicodeEncoding)(this.m_encoding)).bigEndian);
- }
-
- public override void Reset()
- {
- lastByte = -1;
- lastChar = '\0';
- if (m_fallbackBuffer != null)
- m_fallbackBuffer.Reset();
- }
-
- // Anything left in our decoder?
- internal override bool HasState
- {
- get
- {
- return (this.lastByte != -1 || this.lastChar != '\0');
- }
- }
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/Threading/AbandonedMutexException.cs b/src/mscorlib/src/System/Threading/AbandonedMutexException.cs
deleted file mode 100644
index 6b4977fbc5..0000000000
--- a/src/mscorlib/src/System/Threading/AbandonedMutexException.cs
+++ /dev/null
@@ -1,85 +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.
-
-//
-//
-// AbandonedMutexException
-// Thrown when a wait completes because one or more mutexes was abandoned.
-// AbandonedMutexs indicate serious error in user code or machine state.
-////////////////////////////////////////////////////////////////////////////////
-
-namespace System.Threading {
-
- using System;
- using System.Runtime.Serialization;
- using System.Threading;
- using System.Runtime.InteropServices;
-
- [Serializable]
- [ComVisibleAttribute(false)]
- public class AbandonedMutexException : SystemException {
-
- private int m_MutexIndex = -1;
- private Mutex m_Mutex = null;
-
- public AbandonedMutexException()
- : base(Environment.GetResourceString("Threading.AbandonedMutexException")) {
- SetErrorCode(__HResults.COR_E_ABANDONEDMUTEX);
- }
-
- public AbandonedMutexException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_ABANDONEDMUTEX);
- }
-
- public AbandonedMutexException(String message, Exception inner )
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_ABANDONEDMUTEX);
- }
-
- public AbandonedMutexException(int location, WaitHandle handle)
- : base(Environment.GetResourceString("Threading.AbandonedMutexException")) {
- SetErrorCode(__HResults.COR_E_ABANDONEDMUTEX);
- SetupException(location,handle);
- }
-
- public AbandonedMutexException(String message,int location, WaitHandle handle)
- : base(message) {
- SetErrorCode(__HResults.COR_E_ABANDONEDMUTEX);
- SetupException(location,handle);
- }
-
- public AbandonedMutexException(String message, Exception inner,int location, WaitHandle handle )
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_ABANDONEDMUTEX);
- SetupException(location,handle);
- }
-
- private void SetupException(int location, WaitHandle handle)
- {
- m_MutexIndex = location;
- if(handle != null)
- m_Mutex = handle as Mutex;
- }
-
- protected AbandonedMutexException(SerializationInfo info, StreamingContext context) : base(info, context) {
- }
-
- public Mutex Mutex
- {
- get {
- return m_Mutex;
- }
- }
-
- public int MutexIndex
- {
- get{
- return m_MutexIndex;
- }
- }
-
- }
-}
-
diff --git a/src/mscorlib/src/System/Threading/ApartmentState.cs b/src/mscorlib/src/System/Threading/ApartmentState.cs
deleted file mode 100644
index 1edf0af98a..0000000000
--- a/src/mscorlib/src/System/Threading/ApartmentState.cs
+++ /dev/null
@@ -1,27 +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.
-
-//
-/*=============================================================================
-**
-**
-**
-** Purpose: Enum to represent the different threading models
-**
-**
-=============================================================================*/
-
-namespace System.Threading {
-
- [Serializable]
- public enum ApartmentState
- {
- /*=========================================================================
- ** Constants for thread apartment states.
- =========================================================================*/
- STA = 0,
- MTA = 1,
- Unknown = 2
- }
-}
diff --git a/src/mscorlib/src/System/Threading/AsyncLocal.cs b/src/mscorlib/src/System/Threading/AsyncLocal.cs
deleted file mode 100644
index 8c4319bd2c..0000000000
--- a/src/mscorlib/src/System/Threading/AsyncLocal.cs
+++ /dev/null
@@ -1,487 +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.Collections.Generic;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-using System.Security;
-
-namespace System.Threading
-{
- //
- // AsyncLocal<T> represents "ambient" data that is local to a given asynchronous control flow, such as an
- // async method. For example, say you want to associate a culture with a given async flow:
- //
- // static AsyncLocal<Culture> s_currentCulture = new AsyncLocal<Culture>();
- //
- // static async Task SomeOperationAsync(Culture culture)
- // {
- // s_currentCulture.Value = culture;
- //
- // await FooAsync();
- // }
- //
- // static async Task FooAsync()
- // {
- // PrintStringWithCulture(s_currentCulture.Value);
- // }
- //
- // AsyncLocal<T> also provides optional notifications when the value associated with the current thread
- // changes, either because it was explicitly changed by setting the Value property, or implicitly changed
- // when the thread encountered an "await" or other context transition. For example, we might want our
- // current culture to be communicated to the OS as well:
- //
- // static AsyncLocal<Culture> s_currentCulture = new AsyncLocal<Culture>(
- // args =>
- // {
- // NativeMethods.SetThreadCulture(args.CurrentValue.LCID);
- // });
- //
- public sealed class AsyncLocal<T> : IAsyncLocal
- {
- private readonly Action<AsyncLocalValueChangedArgs<T>> m_valueChangedHandler;
-
- //
- // Constructs an AsyncLocal<T> that does not receive change notifications.
- //
- public AsyncLocal()
- {
- }
-
- //
- // Constructs an AsyncLocal<T> with a delegate that is called whenever the current value changes
- // on any thread.
- //
- public AsyncLocal(Action<AsyncLocalValueChangedArgs<T>> valueChangedHandler)
- {
- m_valueChangedHandler = valueChangedHandler;
- }
-
- public T Value
- {
- get
- {
- object obj = ExecutionContext.GetLocalValue(this);
- return (obj == null) ? default(T) : (T)obj;
- }
- set
- {
- ExecutionContext.SetLocalValue(this, value, m_valueChangedHandler != null);
- }
- }
-
- void IAsyncLocal.OnValueChanged(object previousValueObj, object currentValueObj, bool contextChanged)
- {
- Debug.Assert(m_valueChangedHandler != null);
- T previousValue = previousValueObj == null ? default(T) : (T)previousValueObj;
- T currentValue = currentValueObj == null ? default(T) : (T)currentValueObj;
- m_valueChangedHandler(new AsyncLocalValueChangedArgs<T>(previousValue, currentValue, contextChanged));
- }
- }
-
- //
- // Interface to allow non-generic code in ExecutionContext to call into the generic AsyncLocal<T> type.
- //
- internal interface IAsyncLocal
- {
- void OnValueChanged(object previousValue, object currentValue, bool contextChanged);
- }
-
- public struct AsyncLocalValueChangedArgs<T>
- {
- public T PreviousValue { get; private set; }
- public T CurrentValue { get; private set; }
-
- //
- // If the value changed because we changed to a different ExecutionContext, this is true. If it changed
- // because someone set the Value property, this is false.
- //
- public bool ThreadContextChanged { get; private set; }
-
- internal AsyncLocalValueChangedArgs(T previousValue, T currentValue, bool contextChanged)
- : this()
- {
- PreviousValue = previousValue;
- CurrentValue = currentValue;
- ThreadContextChanged = contextChanged;
- }
- }
-
- //
- // Interface used to store an IAsyncLocal => object mapping in ExecutionContext.
- // Implementations are specialized based on the number of elements in the immutable
- // map in order to minimize memory consumption and look-up times.
- //
- interface IAsyncLocalValueMap
- {
- bool TryGetValue(IAsyncLocal key, out object value);
- IAsyncLocalValueMap Set(IAsyncLocal key, object value);
- }
-
- //
- // Utility functions for getting/creating instances of IAsyncLocalValueMap
- //
- internal static class AsyncLocalValueMap
- {
- public static IAsyncLocalValueMap Empty { get; } = new EmptyAsyncLocalValueMap();
-
- // Instance without any key/value pairs. Used as a singleton/
- private sealed class EmptyAsyncLocalValueMap : IAsyncLocalValueMap
- {
- public IAsyncLocalValueMap Set(IAsyncLocal key, object value)
- {
- // If the value isn't null, then create a new one-element map to store
- // the key/value pair. If it is null, then we're still empty.
- return value != null ?
- new OneElementAsyncLocalValueMap(key, value) :
- (IAsyncLocalValueMap)this;
- }
-
- public bool TryGetValue(IAsyncLocal key, out object value)
- {
- value = null;
- return false;
- }
- }
-
- // Instance with one key/value pair.
- private sealed class OneElementAsyncLocalValueMap : IAsyncLocalValueMap
- {
- private readonly IAsyncLocal _key1;
- private readonly object _value1;
-
- public OneElementAsyncLocalValueMap(IAsyncLocal key, object value)
- {
- _key1 = key; _value1 = value;
- }
-
- public IAsyncLocalValueMap Set(IAsyncLocal key, object value)
- {
- if (value != null)
- {
- // The value is non-null. If the key matches one already contained in this map,
- // then create a new one-element map with the updated value, otherwise create
- // a two-element map with the additional key/value.
- return ReferenceEquals(key, _key1) ?
- new OneElementAsyncLocalValueMap(key, value) :
- (IAsyncLocalValueMap)new TwoElementAsyncLocalValueMap(_key1, _value1, key, value);
- }
- else
- {
- // The value is null. If the key exists in this map, remove it by downgrading to an empty map.
- // Otherwise, there's nothing to add or remove, so just return this map.
- return ReferenceEquals(key, _key1) ?
- Empty :
- (IAsyncLocalValueMap)this;
- }
- }
-
- public bool TryGetValue(IAsyncLocal key, out object value)
- {
- if (ReferenceEquals(key, _key1))
- {
- value = _value1;
- return true;
- }
- else
- {
- value = null;
- return false;
- }
- }
- }
-
- // Instance with two key/value pairs.
- private sealed class TwoElementAsyncLocalValueMap : IAsyncLocalValueMap
- {
- private readonly IAsyncLocal _key1, _key2;
- private readonly object _value1, _value2;
-
- public TwoElementAsyncLocalValueMap(IAsyncLocal key1, object value1, IAsyncLocal key2, object value2)
- {
- _key1 = key1; _value1 = value1;
- _key2 = key2; _value2 = value2;
- }
-
- public IAsyncLocalValueMap Set(IAsyncLocal key, object value)
- {
- if (value != null)
- {
- // The value is non-null. If the key matches one already contained in this map,
- // then create a new two-element map with the updated value, otherwise create
- // a three-element map with the additional key/value.
- return
- ReferenceEquals(key, _key1) ? new TwoElementAsyncLocalValueMap(key, value, _key2, _value2) :
- ReferenceEquals(key, _key2) ? new TwoElementAsyncLocalValueMap(_key1, _value1, key, value) :
- (IAsyncLocalValueMap)new ThreeElementAsyncLocalValueMap(_key1, _value1, _key2, _value2, key, value);
- }
- else
- {
- // The value is null. If the key exists in this map, remove it by downgrading to a one-element map
- // without the key. Otherwise, there's nothing to add or remove, so just return this map.
- return
- ReferenceEquals(key, _key1) ? new OneElementAsyncLocalValueMap(_key2, _value2) :
- ReferenceEquals(key, _key2) ? new OneElementAsyncLocalValueMap(_key1, _value1) :
- (IAsyncLocalValueMap)this;
- }
- }
-
- public bool TryGetValue(IAsyncLocal key, out object value)
- {
- if (ReferenceEquals(key, _key1))
- {
- value = _value1;
- return true;
- }
- else if (ReferenceEquals(key, _key2))
- {
- value = _value2;
- return true;
- }
- else
- {
- value = null;
- return false;
- }
- }
- }
-
- // Instance with three key/value pairs.
- private sealed class ThreeElementAsyncLocalValueMap : IAsyncLocalValueMap
- {
- private readonly IAsyncLocal _key1, _key2, _key3;
- private readonly object _value1, _value2, _value3;
-
- public ThreeElementAsyncLocalValueMap(IAsyncLocal key1, object value1, IAsyncLocal key2, object value2, IAsyncLocal key3, object value3)
- {
- _key1 = key1; _value1 = value1;
- _key2 = key2; _value2 = value2;
- _key3 = key3; _value3 = value3;
- }
-
- public IAsyncLocalValueMap Set(IAsyncLocal key, object value)
- {
- if (value != null)
- {
- // The value is non-null. If the key matches one already contained in this map,
- // then create a new three-element map with the updated value.
- if (ReferenceEquals(key, _key1)) return new ThreeElementAsyncLocalValueMap(key, value, _key2, _value2, _key3, _value3);
- if (ReferenceEquals(key, _key2)) return new ThreeElementAsyncLocalValueMap(_key1, _value1, key, value, _key3, _value3);
- if (ReferenceEquals(key, _key3)) return new ThreeElementAsyncLocalValueMap(_key1, _value1, _key2, _value2, key, value);
-
- // The key doesn't exist in this map, so upgrade to a multi map that contains
- // the additional key/value pair.
- var multi = new MultiElementAsyncLocalValueMap(4);
- multi.UnsafeStore(0, _key1, _value1);
- multi.UnsafeStore(1, _key2, _value2);
- multi.UnsafeStore(2, _key3, _value3);
- multi.UnsafeStore(3, key, value);
- return multi;
- }
- else
- {
- // The value is null. If the key exists in this map, remove it by downgrading to a two-element map
- // without the key. Otherwise, there's nothing to add or remove, so just return this map.
- return
- ReferenceEquals(key, _key1) ? new TwoElementAsyncLocalValueMap(_key2, _value2, _key3, _value3) :
- ReferenceEquals(key, _key2) ? new TwoElementAsyncLocalValueMap(_key1, _value1, _key3, _value3) :
- ReferenceEquals(key, _key3) ? new TwoElementAsyncLocalValueMap(_key1, _value1, _key2, _value2) :
- (IAsyncLocalValueMap)this;
- }
- }
-
- public bool TryGetValue(IAsyncLocal key, out object value)
- {
- if (ReferenceEquals(key, _key1))
- {
- value = _value1;
- return true;
- }
- else if (ReferenceEquals(key, _key2))
- {
- value = _value2;
- return true;
- }
- else if (ReferenceEquals(key, _key3))
- {
- value = _value3;
- return true;
- }
- else
- {
- value = null;
- return false;
- }
- }
- }
-
- // Instance with up to 16 key/value pairs.
- private sealed class MultiElementAsyncLocalValueMap : IAsyncLocalValueMap
- {
- internal const int MaxMultiElements = 16;
- private readonly KeyValuePair<IAsyncLocal, object>[] _keyValues;
-
- internal MultiElementAsyncLocalValueMap(int count)
- {
- Debug.Assert(count <= MaxMultiElements);
- _keyValues = new KeyValuePair<IAsyncLocal, object>[count];
- }
-
- internal void UnsafeStore(int index, IAsyncLocal key, object value)
- {
- Debug.Assert(index < _keyValues.Length);
- _keyValues[index] = new KeyValuePair<IAsyncLocal, object>(key, value);
- }
-
- public IAsyncLocalValueMap Set(IAsyncLocal key, object value)
- {
- // Find the key in this map.
- for (int i = 0; i < _keyValues.Length; i++)
- {
- if (ReferenceEquals(key, _keyValues[i].Key))
- {
- // The key is in the map. If the value isn't null, then create a new map of the same
- // size that has all of the same pairs, with this new key/value pair overwriting the old.
- if (value != null)
- {
- var multi = new MultiElementAsyncLocalValueMap(_keyValues.Length);
- Array.Copy(_keyValues, 0, multi._keyValues, 0, _keyValues.Length);
- multi._keyValues[i] = new KeyValuePair<IAsyncLocal, object>(key, value);
- return multi;
- }
- else if (_keyValues.Length == 4)
- {
- // The value is null, and we only have four elements, one of which we're removing,
- // so downgrade to a three-element map, without the matching element.
- return
- i == 0 ? new ThreeElementAsyncLocalValueMap(_keyValues[1].Key, _keyValues[1].Value, _keyValues[2].Key, _keyValues[2].Value, _keyValues[3].Key, _keyValues[3].Value) :
- i == 1 ? new ThreeElementAsyncLocalValueMap(_keyValues[0].Key, _keyValues[0].Value, _keyValues[2].Key, _keyValues[2].Value, _keyValues[3].Key, _keyValues[3].Value) :
- i == 2 ? new ThreeElementAsyncLocalValueMap(_keyValues[0].Key, _keyValues[0].Value, _keyValues[1].Key, _keyValues[1].Value, _keyValues[3].Key, _keyValues[3].Value) :
- (IAsyncLocalValueMap)new ThreeElementAsyncLocalValueMap(_keyValues[0].Key, _keyValues[0].Value, _keyValues[1].Key, _keyValues[1].Value, _keyValues[2].Key, _keyValues[2].Value);
- }
- else
- {
- // The value is null, and we have enough elements remaining to warrant a multi map.
- // Create a new one and copy all of the elements from this one, except the one to be removed.
- var multi = new MultiElementAsyncLocalValueMap(_keyValues.Length - 1);
- if (i != 0) Array.Copy(_keyValues, 0, multi._keyValues, 0, i);
- if (i != _keyValues.Length - 1) Array.Copy(_keyValues, i + 1, multi._keyValues, i, _keyValues.Length - i - 1);
- return multi;
- }
- }
- }
-
- // The key does not already exist in this map.
-
- // If the value is null, then we can simply return this same map, as there's nothing to add or remove.
- if (value == null)
- {
- return this;
- }
-
- // We need to create a new map that has the additional key/value pair.
- // If with the addition we can still fit in a multi map, create one.
- if (_keyValues.Length < MaxMultiElements)
- {
- var multi = new MultiElementAsyncLocalValueMap(_keyValues.Length + 1);
- Array.Copy(_keyValues, 0, multi._keyValues, 0, _keyValues.Length);
- multi._keyValues[_keyValues.Length] = new KeyValuePair<IAsyncLocal, object>(key, value);
- return multi;
- }
-
- // Otherwise, upgrade to a many map.
- var many = new ManyElementAsyncLocalValueMap(MaxMultiElements + 1);
- foreach (KeyValuePair<IAsyncLocal, object> pair in _keyValues)
- {
- many[pair.Key] = pair.Value;
- }
- many[key] = value;
- return many;
- }
-
- public bool TryGetValue(IAsyncLocal key, out object value)
- {
- foreach (KeyValuePair<IAsyncLocal, object> pair in _keyValues)
- {
- if (ReferenceEquals(key, pair.Key))
- {
- value = pair.Value;
- return true;
- }
- }
- value = null;
- return false;
- }
- }
-
- // Instance with any number of key/value pairs.
- private sealed class ManyElementAsyncLocalValueMap : Dictionary<IAsyncLocal, object>, IAsyncLocalValueMap
- {
- public ManyElementAsyncLocalValueMap(int capacity) : base(capacity) { }
-
- public IAsyncLocalValueMap Set(IAsyncLocal key, object value)
- {
- int count = Count;
- bool containsKey = ContainsKey(key);
-
- // If the value being set exists, create a new many map, copy all of the elements from this one,
- // and then store the new key/value pair into it. This is the most common case.
- if (value != null)
- {
- var map = new ManyElementAsyncLocalValueMap(count + (containsKey ? 0 : 1));
- foreach (KeyValuePair<IAsyncLocal, object> pair in this)
- {
- map[pair.Key] = pair.Value;
- }
- map[key] = value;
- return map;
- }
-
- // Otherwise, the value is null, which means null is being stored into an AsyncLocal.Value.
- // Since there's no observable difference at the API level between storing null and the key
- // not existing at all, we can downgrade to a smaller map rather than storing null.
-
- // If the key is contained in this map, we're going to create a new map that's one pair smaller.
- if (containsKey)
- {
- // If the new count would be within range of a multi map instead of a many map,
- // downgrade to the many map, which uses less memory and is faster to access.
- // Otherwise, just create a new many map that's missing this key.
- if (count == MultiElementAsyncLocalValueMap.MaxMultiElements + 1)
- {
- var multi = new MultiElementAsyncLocalValueMap(MultiElementAsyncLocalValueMap.MaxMultiElements);
- int index = 0;
- foreach (KeyValuePair<IAsyncLocal, object> pair in this)
- {
- if (!ReferenceEquals(key, pair.Key))
- {
- multi.UnsafeStore(index++, pair.Key, pair.Value);
- }
- }
- Debug.Assert(index == MultiElementAsyncLocalValueMap.MaxMultiElements);
- return multi;
- }
- else
- {
- var map = new ManyElementAsyncLocalValueMap(count - 1);
- foreach (KeyValuePair<IAsyncLocal, object> pair in this)
- {
- if (!ReferenceEquals(key, pair.Key))
- {
- map[pair.Key] = pair.Value;
- }
- }
- Debug.Assert(map.Count == count - 1);
- return map;
- }
- }
-
- // We were storing null, but the key wasn't in the map, so there's nothing to change.
- // Just return this instance.
- return this;
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Threading/AutoResetEvent.cs b/src/mscorlib/src/System/Threading/AutoResetEvent.cs
deleted file mode 100644
index fc6b2301ca..0000000000
--- a/src/mscorlib/src/System/Threading/AutoResetEvent.cs
+++ /dev/null
@@ -1,24 +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.
-
-//
-/*=============================================================================
-**
-**
-**
-** Purpose: An example of a WaitHandle class
-**
-**
-=============================================================================*/
-namespace System.Threading {
-
- using System;
- using System.Runtime.InteropServices;
-
- public sealed class AutoResetEvent : EventWaitHandle
- {
- public AutoResetEvent(bool initialState) : base(initialState,EventResetMode.AutoReset){ }
- }
-}
-
diff --git a/src/mscorlib/src/System/Threading/CancellationToken.cs b/src/mscorlib/src/System/Threading/CancellationToken.cs
index b68ba4c046..8bddfc90dd 100644
--- a/src/mscorlib/src/System/Threading/CancellationToken.cs
+++ b/src/mscorlib/src/System/Threading/CancellationToken.cs
@@ -78,14 +78,14 @@ namespace System.Threading
/// particularly in situations where related objects are being canceled concurrently.
/// </para>
/// </remarks>
- public bool IsCancellationRequested
+ public bool IsCancellationRequested
{
get
{
return m_source != null && m_source.IsCancellationRequested;
}
}
-
+
/// <summary>
/// Gets whether this token is capable of being in the canceled state.
/// </summary>
@@ -153,12 +153,12 @@ namespace System.Threading
public CancellationToken(bool canceled) :
this()
{
- if(canceled)
+ if (canceled)
m_source = CancellationTokenSource.InternalGetStaticSource(canceled);
}
/* Methods */
-
+
private readonly static Action<Object> s_ActionToActionObjShunt = new Action<Object>(ActionToActionObjShunt);
private static void ActionToActionObjShunt(object obj)
@@ -190,7 +190,7 @@ namespace System.Threading
{
if (callback == null)
throw new ArgumentNullException(nameof(callback));
-
+
return Register(
s_ActionToActionObjShunt,
callback,
@@ -225,7 +225,7 @@ namespace System.Threading
{
if (callback == null)
throw new ArgumentNullException(nameof(callback));
-
+
return Register(
s_ActionToActionObjShunt,
callback,
@@ -301,7 +301,7 @@ namespace System.Threading
true // useExecutionContext=true
);
}
-
+
// helper for internal registration needs that don't require an EC capture (e.g. creating linked token sources, or registering unstarted TPL tasks)
// has a handy signature, and skips capturing execution context.
internal CancellationTokenRegistration InternalRegisterWithoutEC(Action<object> callback, Object state)
@@ -366,14 +366,14 @@ namespace System.Threading
{
return other.m_source == CancellationTokenSource.InternalGetStaticSource(false);
}
-
+
if (other.m_source == null)
{
return m_source == CancellationTokenSource.InternalGetStaticSource(false);
}
// general case, we check if the sources are identical
-
+
return m_source == other.m_source;
}
@@ -392,7 +392,7 @@ namespace System.Threading
{
if (other is CancellationToken)
{
- return Equals((CancellationToken) other);
+ return Equals((CancellationToken)other);
}
return false;
@@ -410,9 +410,9 @@ namespace System.Threading
return CancellationTokenSource.InternalGetStaticSource(false).GetHashCode();
}
- return m_source.GetHashCode();
+ return m_source.GetHashCode();
}
-
+
/// <summary>
/// Determines whether two <see cref="T:System.Threading.CancellationToken">CancellationToken</see> instances are equal.
/// </summary>
@@ -455,7 +455,7 @@ namespace System.Threading
/// cref="T:System.Threading.CancellationTokenSource">CancellationTokenSource</see> has been disposed.</exception>
public void ThrowIfCancellationRequested()
{
- if (IsCancellationRequested)
+ if (IsCancellationRequested)
ThrowOperationCanceledException();
}
@@ -469,17 +469,17 @@ namespace System.Threading
// Throws an OCE; separated out to enable better inlining of ThrowIfCancellationRequested
private void ThrowOperationCanceledException()
{
- throw new OperationCanceledException(Environment.GetResourceString("OperationCanceled"), this);
+ throw new OperationCanceledException(SR.OperationCanceled, this);
}
private static void ThrowObjectDisposedException()
{
- throw new ObjectDisposedException(null, Environment.GetResourceString("CancellationToken_SourceDisposed"));
+ throw new ObjectDisposedException(null, SR.CancellationToken_SourceDisposed);
}
// -----------------------------------
// Private helpers
-
+
private void InitializeDefaultSource()
{
// Lazy is slower, and although multiple threads may try and set m_source repeatedly, the race condition is benign.
diff --git a/src/mscorlib/src/System/Threading/CancellationTokenRegistration.cs b/src/mscorlib/src/System/Threading/CancellationTokenRegistration.cs
index 89e98fa3c8..be760fab3f 100644
--- a/src/mscorlib/src/System/Threading/CancellationTokenRegistration.cs
+++ b/src/mscorlib/src/System/Threading/CancellationTokenRegistration.cs
@@ -62,7 +62,7 @@ namespace System.Threading
// Remove the entry from the array.
// This call includes a full memory fence which prevents potential reorderings of the reads below
bool deregisterOccurred = TryDeregister();
-
+
// We guarantee that we will not return if the callback is being executed (assuming we are not currently called by the callback itself)
// We achieve this by the following rules:
// 1. if we are called in the context of an executing callback, no need to wait (determined by tracking callback-executor threadID)
@@ -124,7 +124,7 @@ namespace System.Threading
/// </returns>
public override bool Equals(object obj)
{
- return ((obj is CancellationTokenRegistration) && Equals((CancellationTokenRegistration) obj));
+ return ((obj is CancellationTokenRegistration) && Equals((CancellationTokenRegistration)obj));
}
/// <summary>
@@ -152,7 +152,7 @@ namespace System.Threading
{
if (m_registrationInfo.Source != null)
return m_registrationInfo.Source.GetHashCode() ^ m_registrationInfo.Index.GetHashCode();
-
+
return m_registrationInfo.Index.GetHashCode();
}
}
diff --git a/src/mscorlib/src/System/Threading/CancellationTokenSource.cs b/src/mscorlib/src/System/Threading/CancellationTokenSource.cs
index 1e70d6f30f..2707292ed2 100644
--- a/src/mscorlib/src/System/Threading/CancellationTokenSource.cs
+++ b/src/mscorlib/src/System/Threading/CancellationTokenSource.cs
@@ -45,18 +45,18 @@ namespace System.Threading
// the actual callback lists are only created on demand.
// Storing a registered callback costs around >60bytes, hence some overhead for the lists array is OK
// At most 24 lists seems reasonable, and caps the cost of the listsArray to 96bytes(32-bit,24-way) or 192bytes(64-bit,24-way).
- private static readonly int s_nLists = (PlatformHelper.ProcessorCount > 24) ? 24 : PlatformHelper.ProcessorCount;
+ private static readonly int s_nLists = (PlatformHelper.ProcessorCount > 24) ? 24 : PlatformHelper.ProcessorCount;
private volatile ManualResetEvent m_kernelEvent; //lazily initialized if required.
private volatile SparselyPopulatedArray<CancellationCallbackInfo>[] m_registeredCallbacksLists;
-
+
// legal values for m_state
private const int CANNOT_BE_CANCELED = 0;
private const int NOT_CANCELED = 1;
private const int NOTIFYING = 2;
private const int NOTIFYINGCOMPLETE = 3;
-
+
//m_state uses the pattern "volatile int32 reads, with cmpxch writes" which is safe for updates and cannot suffer torn reads.
private volatile int m_state;
@@ -68,13 +68,13 @@ namespace System.Threading
private volatile int m_threadIDExecutingCallbacks = -1;
private bool m_disposed;
-
+
// we track the running callback to assist ctr.Dispose() to wait for the target callback to complete.
private volatile CancellationCallbackInfo m_executingCallback;
// provided for CancelAfter and timer-related constructors
private volatile Timer m_timer;
-
+
// ----------------------
// ** public properties
@@ -168,11 +168,11 @@ namespace System.Threading
// fast path if already allocated.
if (m_kernelEvent != null)
return m_kernelEvent;
-
+
// lazy-init the mre.
ManualResetEvent mre = new ManualResetEvent(false);
if (Interlocked.CompareExchange(ref m_kernelEvent, mre, null) != null)
- {
+ {
((IDisposable)mre).Dispose();
}
@@ -211,9 +211,9 @@ namespace System.Threading
return 0;
int count = 0;
- foreach(SparselyPopulatedArray<CancellationCallbackInfo> sparseArray in callbackLists)
+ foreach (SparselyPopulatedArray<CancellationCallbackInfo> sparseArray in callbackLists)
{
- if(sparseArray != null)
+ if (sparseArray != null)
{
SparselyPopulatedArrayFragment<CancellationCallbackInfo> currCallbacks = sparseArray.Head;
while (currCallbacks != null)
@@ -379,7 +379,7 @@ namespace System.Threading
public void Cancel(bool throwOnFirstException)
{
ThrowIfDisposed();
- NotifyCancellation(throwOnFirstException);
+ NotifyCancellation(throwOnFirstException);
}
/// <summary>
@@ -476,7 +476,7 @@ namespace System.Threading
}
}
-
+
// It is possible that m_timer has already been disposed, so we must do
// the following in a try/catch block.
try
@@ -490,7 +490,6 @@ namespace System.Threading
// would not be a good way to deal with the observe/dispose
// race condition.
}
-
}
private static readonly TimerCallback s_timerCallback = new TimerCallback(TimerCallbackLogic);
@@ -601,7 +600,7 @@ namespace System.Threading
// separation enables inlining of ThrowIfDisposed
private static void ThrowObjectDisposedException()
{
- throw new ObjectDisposedException(null, Environment.GetResourceString("CancellationTokenSource_Disposed"));
+ throw new ObjectDisposedException(null, SR.CancellationTokenSource_Disposed);
}
/// <summary>
@@ -716,7 +715,7 @@ namespace System.Threading
// Record the threadID being used for running the callbacks.
ThreadIDExecutingCallbacks = Thread.CurrentThread.ManagedThreadId;
-
+
// Set the event if it's been lazily initialized and hasn't yet been disposed of. Dispose may
// be running concurrently, in which case either it'll have set m_kernelEvent back to null and
// we won't see it here, or it'll see that we've transitioned to NOTIFYING and will skip disposing it,
@@ -755,7 +754,7 @@ namespace System.Threading
Interlocked.Exchange(ref m_state, NOTIFYINGCOMPLETE);
return;
}
-
+
try
{
for (int index = 0; index < callbackLists.Length; index++)
@@ -799,13 +798,13 @@ namespace System.Threading
CancellationCallbackCoreWork(args);
}
}
- catch(Exception ex)
+ catch (Exception ex)
{
if (throwOnFirstException)
throw;
-
+
// Otherwise, log it and proceed.
- if(exceptionList == null)
+ if (exceptionList == null)
exceptionList = new List<Exception>();
exceptionList.Add(ex);
}
@@ -821,7 +820,7 @@ namespace System.Threading
{
m_state = NOTIFYINGCOMPLETE;
m_executingCallback = null;
- Thread.MemoryBarrier(); // for safety, prevent reorderings crossing this point and seeing inconsistent state.
+ Interlocked.MemoryBarrier(); // for safety, prevent reorderings crossing this point and seeing inconsistent state.
}
if (exceptionList != null)
@@ -892,7 +891,7 @@ namespace System.Threading
switch (tokens.Length)
{
case 0:
- throw new ArgumentException(Environment.GetResourceString("CancellationToken_CreateLinkedToken_TokensIsEmpty"));
+ throw new ArgumentException(SR.CancellationToken_CreateLinkedToken_TokensIsEmpty);
case 1:
return CreateLinkedTokenSource(tokens[0]);
case 2:
@@ -1004,7 +1003,7 @@ namespace System.Threading
{
internal SparselyPopulatedArrayFragment<CancellationCallbackInfo> m_currArrayFragment;
internal int m_currArrayIndex;
-
+
public CancellationCallbackCoreWorkArguments(SparselyPopulatedArrayFragment<CancellationCallbackInfo> currArrayFragment, int currArrayIndex)
{
m_currArrayFragment = currArrayFragment;
@@ -1040,7 +1039,6 @@ namespace System.Threading
{
TargetSyncContext = targetSyncContext;
}
-
}
internal CancellationCallbackInfo(
@@ -1066,7 +1064,7 @@ namespace System.Threading
// Lazily initialize the callback delegate; benign race condition
var callback = s_executionContextCallback;
if (callback == null) s_executionContextCallback = callback = new ContextCallback(ExecutionContextCallback);
-
+
ExecutionContext.Run(
TargetExecutionContext,
callback,
@@ -1176,7 +1174,7 @@ namespace System.Threading
// If the slot is null, try to CAS our element into it.
int tryIndex = (start + i) % c;
Debug.Assert(tryIndex >= 0 && tryIndex < curr.m_elements.Length, "tryIndex is outside of bounds");
-
+
if (curr.m_elements[tryIndex] == null && Interlocked.CompareExchange(ref curr.m_elements[tryIndex], element, null) == null)
{
// We adjust the free count by --. Note: if this drops to 0, we will skip
@@ -1282,7 +1280,7 @@ namespace System.Threading
internal T SafeAtomicRemove(int index, T expectedElement)
{
T prevailingValue = Interlocked.CompareExchange(ref m_elements[index], null, expectedElement);
- if (prevailingValue != null)
+ if (prevailingValue != null)
++m_freeCount;
return prevailingValue;
}
diff --git a/src/mscorlib/corefx/System/Threading/ClrThreadPoolBoundHandle.cs b/src/mscorlib/src/System/Threading/ClrThreadPoolBoundHandle.cs
index d0cc5afbae..d0cc5afbae 100644
--- a/src/mscorlib/corefx/System/Threading/ClrThreadPoolBoundHandle.cs
+++ b/src/mscorlib/src/System/Threading/ClrThreadPoolBoundHandle.cs
diff --git a/src/mscorlib/corefx/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs b/src/mscorlib/src/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs
index 1aea2a294b..1aea2a294b 100644
--- a/src/mscorlib/corefx/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs
+++ b/src/mscorlib/src/System/Threading/ClrThreadPoolBoundHandleOverlapped.cs
diff --git a/src/mscorlib/corefx/System/Threading/ClrThreadPoolPreAllocatedOverlapped.cs b/src/mscorlib/src/System/Threading/ClrThreadPoolPreAllocatedOverlapped.cs
index a42e0c7983..a42e0c7983 100644
--- a/src/mscorlib/corefx/System/Threading/ClrThreadPoolPreAllocatedOverlapped.cs
+++ b/src/mscorlib/src/System/Threading/ClrThreadPoolPreAllocatedOverlapped.cs
diff --git a/src/mscorlib/src/System/Threading/CountdownEvent.cs b/src/mscorlib/src/System/Threading/CountdownEvent.cs
deleted file mode 100644
index af055e347e..0000000000
--- a/src/mscorlib/src/System/Threading/CountdownEvent.cs
+++ /dev/null
@@ -1,589 +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.
-
-// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-//
-//
-//
-// A simple coordination data structure that we use for fork/join style parallelism.
-//
-// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-using System;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Diagnostics;
-using System.Diagnostics.Contracts;
-
-namespace System.Threading
-{
-
- /// <summary>
- /// Represents a synchronization primitive that is signaled when its count reaches zero.
- /// </summary>
- /// <remarks>
- /// All public and protected members of <see cref="CountdownEvent"/> are thread-safe and may be used
- /// concurrently from multiple threads, with the exception of Dispose, which
- /// must only be used when all other operations on the <see cref="CountdownEvent"/> have
- /// completed, and Reset, which should only be used when no other threads are
- /// accessing the event.
- /// </remarks>
- [DebuggerDisplay("Initial Count={InitialCount}, Current Count={CurrentCount}")]
- public class CountdownEvent : IDisposable
- {
- // CountdownEvent is a simple synchronization primitive used for fork/join parallelism. We create a
- // latch with a count of N; threads then signal the latch, which decrements N by 1; other threads can
- // wait on the latch at any point; when the latch count reaches 0, all threads are woken and
- // subsequent waiters return without waiting. The implementation internally lazily creates a true
- // Win32 event as needed. We also use some amount of spinning on MP machines before falling back to a
- // wait.
-
- private int m_initialCount; // The original # of signals the latch was instantiated with.
- private volatile int m_currentCount; // The # of outstanding signals before the latch transitions to a signaled state.
- private ManualResetEventSlim m_event; // An event used to manage blocking and signaling.
- private volatile bool m_disposed; // Whether the latch has been disposed.
-
- /// <summary>
- /// Initializes a new instance of <see cref="T:System.Threading.CountdownEvent"/> class with the
- /// specified count.
- /// </summary>
- /// <param name="initialCount">The number of signals required to set the <see
- /// cref="T:System.Threading.CountdownEvent"/>.</param>
- /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="initialCount"/> is less
- /// than 0.</exception>
- public CountdownEvent(int initialCount)
- {
- if (initialCount < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(initialCount));
- }
-
- m_initialCount = initialCount;
- m_currentCount = initialCount;
-
- // Allocate a thin event, which internally defers creation of an actual Win32 event.
- m_event = new ManualResetEventSlim();
-
- // If the latch was created with a count of 0, then it's already in the signaled state.
- if (initialCount == 0)
- {
- m_event.Set();
- }
- }
-
- /// <summary>
- /// Gets the number of remaining signals required to set the event.
- /// </summary>
- /// <value>
- /// The number of remaining signals required to set the event.
- /// </value>
- public int CurrentCount
- {
- get
- {
- int observedCount = m_currentCount;
- return observedCount < 0 ? 0 : observedCount;
- }
- }
-
- /// <summary>
- /// Gets the numbers of signals initially required to set the event.
- /// </summary>
- /// <value>
- /// The number of signals initially required to set the event.
- /// </value>
- public int InitialCount
- {
- get { return m_initialCount; }
- }
-
- /// <summary>
- /// Determines whether the event is set.
- /// </summary>
- /// <value>true if the event is set; otherwise, false.</value>
- public bool IsSet
- {
- get
- {
- // The latch is "completed" if its current count has reached 0. Note that this is NOT
- // the same thing is checking the event's IsCompleted property. There is a tiny window
- // of time, after the final decrement of the current count to 0 and before setting the
- // event, where the two values are out of sync.
- return (m_currentCount <= 0);
- }
- }
-
- /// <summary>
- /// Gets a <see cref="T:System.Threading.WaitHandle"/> that is used to wait for the event to be set.
- /// </summary>
- /// <value>A <see cref="T:System.Threading.WaitHandle"/> that is used to wait for the event to be set.</value>
- /// <exception cref="T:System.ObjectDisposedException">The current instance has already been disposed.</exception>
- /// <remarks>
- /// <see cref="WaitHandle"/> should only be used if it's needed for integration with code bases
- /// that rely on having a WaitHandle. If all that's needed is to wait for the <see cref="CountdownEvent"/>
- /// to be set, the <see cref="Wait()"/> method should be preferred.
- /// </remarks>
- public WaitHandle WaitHandle
- {
- get
- {
- ThrowIfDisposed();
- return m_event.WaitHandle;
- }
- }
-
- /// <summary>
- /// Releases all resources used by the current instance of <see cref="T:System.Threading.CountdownEvent"/>.
- /// </summary>
- /// <remarks>
- /// Unlike most of the members of <see cref="CountdownEvent"/>, <see cref="Dispose()"/> is not
- /// thread-safe and may not be used concurrently with other members of this instance.
- /// </remarks>
- public void Dispose()
- {
- // Gets rid of this latch's associated resources. This can consist of a Win32 event
- // which is (lazily) allocated by the underlying thin event. This method is not safe to
- // call concurrently -- i.e. a caller must coordinate to ensure only one thread is using
- // the latch at the time of the call to Dispose.
-
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- /// <summary>
- /// When overridden in a derived class, releases the unmanaged resources used by the
- /// <see cref="T:System.Threading.CountdownEvent"/>, and optionally releases the managed resources.
- /// </summary>
- /// <param name="disposing">true to release both managed and unmanaged resources; false to release
- /// only unmanaged resources.</param>
- /// <remarks>
- /// Unlike most of the members of <see cref="CountdownEvent"/>, <see cref="Dispose()"/> is not
- /// thread-safe and may not be used concurrently with other members of this instance.
- /// </remarks>
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- m_event.Dispose();
- m_disposed = true;
- }
- }
-
- /// <summary>
- /// Registers a signal with the <see cref="T:System.Threading.CountdownEvent"/>, decrementing its
- /// count.
- /// </summary>
- /// <returns>true if the signal caused the count to reach zero and the event was set; otherwise,
- /// false.</returns>
- /// <exception cref="T:System.InvalidOperationException">The current instance is already set.
- /// </exception>
- /// <exception cref="T:System.ObjectDisposedException">The current instance has already been
- /// disposed.</exception>
- public bool Signal()
- {
- ThrowIfDisposed();
- Debug.Assert(m_event != null);
-
- if (m_currentCount <= 0)
- {
- throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Decrement_BelowZero"));
- }
-#pragma warning disable 0420
- int newCount = Interlocked.Decrement(ref m_currentCount);
-#pragma warning restore 0420
- if (newCount == 0)
- {
- m_event.Set();
- return true;
- }
- else if (newCount < 0)
- {
- //if the count is decremented below zero, then throw, it's OK to keep the count negative, and we shouldn't set the event here
- //because there was a thread already which decremented it to zero and set the event
- throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Decrement_BelowZero"));
- }
-
- return false;
- }
-
- /// <summary>
- /// Registers multiple signals with the <see cref="T:System.Threading.CountdownEvent"/>,
- /// decrementing its count by the specified amount.
- /// </summary>
- /// <param name="signalCount">The number of signals to register.</param>
- /// <returns>true if the signals caused the count to reach zero and the event was set; otherwise,
- /// false.</returns>
- /// <exception cref="T:System.InvalidOperationException">
- /// The current instance is already set. -or- Or <paramref name="signalCount"/> is greater than <see
- /// cref="CurrentCount"/>.
- /// </exception>
- /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="signalCount"/> is less
- /// than 1.</exception>
- /// <exception cref="T:System.ObjectDisposedException">The current instance has already been
- /// disposed.</exception>
- public bool Signal(int signalCount)
- {
- if (signalCount <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(signalCount));
- }
-
- ThrowIfDisposed();
- Debug.Assert(m_event != null);
-
- int observedCount;
- SpinWait spin = new SpinWait();
- while (true)
- {
- observedCount = m_currentCount;
-
- // If the latch is already signaled, we will fail.
- if (observedCount < signalCount)
- {
- throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Decrement_BelowZero"));
- }
-
- // This disables the "CS0420: a reference to a volatile field will not be treated as volatile" warning
- // for this statement. This warning is clearly senseless for Interlocked operations.
-#pragma warning disable 0420
- if (Interlocked.CompareExchange(ref m_currentCount, observedCount - signalCount, observedCount) == observedCount)
-#pragma warning restore 0420
- {
- break;
- }
-
- // The CAS failed. Spin briefly and try again.
- spin.SpinOnce();
- }
-
- // If we were the last to signal, set the event.
- if (observedCount == signalCount)
- {
- m_event.Set();
- return true;
- }
-
- Debug.Assert(m_currentCount >= 0, "latch was decremented below zero");
- return false;
- }
-
- /// <summary>
- /// Increments the <see cref="T:System.Threading.CountdownEvent"/>'s current count by one.
- /// </summary>
- /// <exception cref="T:System.InvalidOperationException">The current instance is already
- /// set.</exception>
- /// <exception cref="T:System.InvalidOperationException"><see cref="CurrentCount"/> is equal to <see
- /// cref="T:System.Int32.MaxValue"/>.</exception>
- /// <exception cref="T:System.ObjectDisposedException">
- /// The current instance has already been disposed.
- /// </exception>
- public void AddCount()
- {
- AddCount(1);
- }
-
- /// <summary>
- /// Attempts to increment the <see cref="T:System.Threading.CountdownEvent"/>'s current count by one.
- /// </summary>
- /// <returns>true if the increment succeeded; otherwise, false. If <see cref="CurrentCount"/> is
- /// already at zero. this will return false.</returns>
- /// <exception cref="T:System.InvalidOperationException"><see cref="CurrentCount"/> is equal to <see
- /// cref="T:System.Int32.MaxValue"/>.</exception>
- /// <exception cref="T:System.ObjectDisposedException">The current instance has already been
- /// disposed.</exception>
- public bool TryAddCount()
- {
- return TryAddCount(1);
- }
-
- /// <summary>
- /// Increments the <see cref="T:System.Threading.CountdownEvent"/>'s current count by a specified
- /// value.
- /// </summary>
- /// <param name="signalCount">The value by which to increase <see cref="CurrentCount"/>.</param>
- /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="signalCount"/> is less than
- /// 0.</exception>
- /// <exception cref="T:System.InvalidOperationException">The current instance is already
- /// set.</exception>
- /// <exception cref="T:System.InvalidOperationException"><see cref="CurrentCount"/> is equal to <see
- /// cref="T:System.Int32.MaxValue"/>.</exception>
- /// <exception cref="T:System.ObjectDisposedException">The current instance has already been
- /// disposed.</exception>
- public void AddCount(int signalCount)
- {
- if (!TryAddCount(signalCount))
- {
- throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Increment_AlreadyZero"));
- }
- }
-
- /// <summary>
- /// Attempts to increment the <see cref="T:System.Threading.CountdownEvent"/>'s current count by a
- /// specified value.
- /// </summary>
- /// <param name="signalCount">The value by which to increase <see cref="CurrentCount"/>.</param>
- /// <returns>true if the increment succeeded; otherwise, false. If <see cref="CurrentCount"/> is
- /// already at zero this will return false.</returns>
- /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="signalCount"/> is less
- /// than 0.</exception>
- /// <exception cref="T:System.InvalidOperationException">The current instance is already
- /// set.</exception>
- /// <exception cref="T:System.InvalidOperationException"><see cref="CurrentCount"/> is equal to <see
- /// cref="T:System.Int32.MaxValue"/>.</exception>
- /// <exception cref="T:System.ObjectDisposedException">The current instance has already been
- /// disposed.</exception>
- public bool TryAddCount(int signalCount)
- {
- if (signalCount <= 0)
- {
- throw new ArgumentOutOfRangeException(nameof(signalCount));
- }
-
- ThrowIfDisposed();
-
- // Loop around until we successfully increment the count.
- int observedCount;
- SpinWait spin = new SpinWait();
- while (true)
- {
- observedCount = m_currentCount;
-
- if (observedCount <= 0)
- {
- return false;
- }
- else if (observedCount > (Int32.MaxValue - signalCount))
- {
- throw new InvalidOperationException(Environment.GetResourceString("CountdownEvent_Increment_AlreadyMax"));
- }
-
- // This disables the "CS0420: a reference to a volatile field will not be treated as volatile" warning
- // for this statement. This warning is clearly senseless for Interlocked operations.
-#pragma warning disable 0420
- if (Interlocked.CompareExchange(ref m_currentCount, observedCount + signalCount, observedCount) == observedCount)
-#pragma warning restore 0420
- {
- break;
- }
-
- // The CAS failed. Spin briefly and try again.
- spin.SpinOnce();
- }
-
- return true;
- }
-
- /// <summary>
- /// Resets the <see cref="CurrentCount"/> to the value of <see cref="InitialCount"/>.
- /// </summary>
- /// <remarks>
- /// Unlike most of the members of <see cref="CountdownEvent"/>, Reset is not
- /// thread-safe and may not be used concurrently with other members of this instance.
- /// </remarks>
- /// <exception cref="T:System.ObjectDisposedException">The current instance has already been
- /// disposed..</exception>
- public void Reset()
- {
- Reset(m_initialCount);
- }
-
- /// <summary>
- /// Resets the <see cref="CurrentCount"/> to a specified value.
- /// </summary>
- /// <param name="count">The number of signals required to set the <see
- /// cref="T:System.Threading.CountdownEvent"/>.</param>
- /// <remarks>
- /// Unlike most of the members of <see cref="CountdownEvent"/>, Reset is not
- /// thread-safe and may not be used concurrently with other members of this instance.
- /// </remarks>
- /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="count"/> is
- /// less than 0.</exception>
- /// <exception cref="T:System.ObjectDisposedException">The current instance has alread been disposed.</exception>
- public void Reset(int count)
- {
- ThrowIfDisposed();
-
- if (count < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(count));
- }
-
- m_currentCount = count;
- m_initialCount = count;
-
- if (count == 0)
- {
- m_event.Set();
- }
- else
- {
- m_event.Reset();
- }
- }
-
- /// <summary>
- /// Blocks the current thread until the <see cref="T:System.Threading.CountdownEvent"/> is set.
- /// </summary>
- /// <remarks>
- /// The caller of this method blocks indefinitely until the current instance is set. The caller will
- /// return immediately if the event is currently in a set state.
- /// </remarks>
- /// <exception cref="T:System.ObjectDisposedException">The current instance has already been
- /// disposed.</exception>
- public void Wait()
- {
- Wait(Timeout.Infinite, new CancellationToken());
- }
-
-
- /// <summary>
- /// Blocks the current thread until the <see cref="T:System.Threading.CountdownEvent"/> is set, while
- /// observing a <see cref="T:System.Threading.CancellationToken"/>.
- /// </summary>
- /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken"/> to
- /// observe.</param>
- /// <remarks>
- /// The caller of this method blocks indefinitely until the current instance is set. The caller will
- /// return immediately if the event is currently in a set state. If the
- /// <see cref="T:System.Threading.CancellationToken">CancellationToken</see> being observed
- /// is canceled during the wait operation, an <see cref="T:System.OperationCanceledException"/>
- /// will be thrown.
- /// </remarks>
- /// <exception cref="T:System.OperationCanceledException"><paramref name="cancellationToken"/> has been
- /// canceled.</exception>
- /// <exception cref="T:System.ObjectDisposedException">The current instance has already been
- /// disposed.</exception>
- public void Wait(CancellationToken cancellationToken)
- {
- Wait(Timeout.Infinite, cancellationToken);
- }
-
- /// <summary>
- /// Blocks the current thread until the <see cref="T:System.Threading.CountdownEvent"/> is set, using a
- /// <see cref="T:System.TimeSpan"/> to measure the time interval.
- /// </summary>
- /// <param name="timeout">A <see cref="T:System.TimeSpan"/> that represents the number of
- /// milliseconds to wait, or a <see cref="T:System.TimeSpan"/> that represents -1 milliseconds to
- /// wait indefinitely.</param>
- /// <returns>true if the <see cref="System.Threading.CountdownEvent"/> was set; otherwise,
- /// false.</returns>
- /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="timeout"/> is a negative
- /// number other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater
- /// than <see cref="System.Int32.MaxValue"/>.</exception>
- /// <exception cref="T:System.ObjectDisposedException">The current instance has already been
- /// disposed.</exception>
- public bool Wait(TimeSpan timeout)
- {
- long totalMilliseconds = (long)timeout.TotalMilliseconds;
- if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue)
- {
- throw new ArgumentOutOfRangeException(nameof(timeout));
- }
-
- return Wait((int)totalMilliseconds, new CancellationToken());
- }
-
- /// <summary>
- /// Blocks the current thread until the <see cref="T:System.Threading.CountdownEvent"/> is set, using
- /// a <see cref="T:System.TimeSpan"/> to measure the time interval, while observing a
- /// <see cref="T:System.Threading.CancellationToken"/>.
- /// </summary>
- /// <param name="timeout">A <see cref="T:System.TimeSpan"/> that represents the number of
- /// milliseconds to wait, or a <see cref="T:System.TimeSpan"/> that represents -1 milliseconds to
- /// wait indefinitely.</param>
- /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken"/> to
- /// observe.</param>
- /// <returns>true if the <see cref="System.Threading.CountdownEvent"/> was set; otherwise,
- /// false.</returns>
- /// <exception cref="T:System.ArgumentOutOfRangeException"><paramref name="timeout"/> is a negative
- /// number other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater
- /// than <see cref="System.Int32.MaxValue"/>.</exception>
- /// <exception cref="T:System.ObjectDisposedException">The current instance has already been
- /// disposed.</exception>
- /// <exception cref="T:System.OperationCanceledException"><paramref name="cancellationToken"/> has
- /// been canceled.</exception>
- public bool Wait(TimeSpan timeout, CancellationToken cancellationToken)
- {
- long totalMilliseconds = (long)timeout.TotalMilliseconds;
- if (totalMilliseconds < -1 || totalMilliseconds > int.MaxValue)
- {
- throw new ArgumentOutOfRangeException(nameof(timeout));
- }
-
- return Wait((int)totalMilliseconds, cancellationToken);
- }
-
- /// <summary>
- /// Blocks the current thread until the <see cref="T:System.Threading.CountdownEvent"/> is set, using a
- /// 32-bit signed integer to measure the time interval.
- /// </summary>
- /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see
- /// cref="Timeout.Infinite"/>(-1) to wait indefinitely.</param>
- /// <returns>true if the <see cref="System.Threading.CountdownEvent"/> was set; otherwise,
- /// false.</returns>
- /// <exception cref="ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a
- /// negative number other than -1, which represents an infinite time-out.</exception>
- /// <exception cref="T:System.ObjectDisposedException">The current instance has already been
- /// disposed.</exception>
- public bool Wait(int millisecondsTimeout)
- {
- return Wait(millisecondsTimeout, new CancellationToken());
- }
-
- /// <summary>
- /// Blocks the current thread until the <see cref="T:System.Threading.CountdownEvent"/> is set, using a
- /// 32-bit signed integer to measure the time interval, while observing a
- /// <see cref="T:System.Threading.CancellationToken"/>.
- /// </summary>
- /// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see
- /// cref="Timeout.Infinite"/>(-1) to wait indefinitely.</param>
- /// <param name="cancellationToken">The <see cref="T:System.Threading.CancellationToken"/> to
- /// observe.</param>
- /// <returns>true if the <see cref="System.Threading.CountdownEvent"/> was set; otherwise,
- /// false.</returns>
- /// <exception cref="ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a
- /// negative number other than -1, which represents an infinite time-out.</exception>
- /// <exception cref="T:System.ObjectDisposedException">The current instance has already been
- /// disposed.</exception>
- /// <exception cref="T:System.OperationCanceledException"><paramref name="cancellationToken"/> has
- /// been canceled.</exception>
- public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
- {
- if (millisecondsTimeout < -1)
- {
- throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout));
- }
-
- ThrowIfDisposed();
- cancellationToken.ThrowIfCancellationRequested();
-
- bool returnValue = IsSet;
-
- // If not completed yet, wait on the event.
- if (!returnValue)
- {
- // ** the actual wait
- returnValue = m_event.Wait(millisecondsTimeout, cancellationToken);
- //the Wait will throw OCE itself if the token is canceled.
- }
-
- return returnValue;
- }
-
- // --------------------------------------
- // Private methods
-
-
- /// <summary>
- /// Throws an exception if the latch has been disposed.
- /// </summary>
- private void ThrowIfDisposed()
- {
- if (m_disposed)
- {
- throw new ObjectDisposedException("CountdownEvent");
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Threading/EventResetMode.cs b/src/mscorlib/src/System/Threading/EventResetMode.cs
deleted file mode 100644
index edafab9bb5..0000000000
--- a/src/mscorlib/src/System/Threading/EventResetMode.cs
+++ /dev/null
@@ -1,26 +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.
-
-//
-/*=============================================================================
-**
-** Enum: EventResetMode
-**
-**
-** Purpose: Enum to determine the Event type to create
-**
-**
-=============================================================================*/
-
-
-namespace System.Threading
-{
- using System.Runtime.InteropServices;
- [ComVisibleAttribute(false)]
- public enum EventResetMode
- {
- AutoReset = 0,
- ManualReset = 1
- }
-}
diff --git a/src/mscorlib/src/System/Threading/EventWaitHandle.cs b/src/mscorlib/src/System/Threading/EventWaitHandle.cs
index 0268948a5c..611d9de7e7 100644
--- a/src/mscorlib/src/System/Threading/EventWaitHandle.cs
+++ b/src/mscorlib/src/System/Threading/EventWaitHandle.cs
@@ -39,25 +39,25 @@ namespace System.Threading
[ComVisibleAttribute(true)]
public class EventWaitHandle : WaitHandle
{
- public EventWaitHandle(bool initialState, EventResetMode mode) : this(initialState,mode,null) { }
+ public EventWaitHandle(bool initialState, EventResetMode mode) : this(initialState, mode, null) { }
public EventWaitHandle(bool initialState, EventResetMode mode, string name)
{
- if(name != null)
+ if (name != null)
{
#if PLATFORM_UNIX
- throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_NamedSynchronizationPrimitives"));
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives);
#else
if (System.IO.Path.MaxPath < name.Length)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name));
+ throw new ArgumentException(SR.Format(SR.Argument_WaitHandleNameTooLong, Path.MaxPath), nameof(name));
}
#endif
}
Contract.EndContractBlock();
-
+
SafeWaitHandle _handle = null;
- switch(mode)
+ switch (mode)
{
case EventResetMode.ManualReset:
_handle = Win32Native.CreateEvent(null, true, initialState, name);
@@ -67,16 +67,16 @@ namespace System.Threading
break;
default:
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag",name));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidFlag, name));
};
-
+
if (_handle.IsInvalid)
{
int errorCode = Marshal.GetLastWin32Error();
-
+
_handle.SetHandleAsInvalid();
- if(null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
- throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle",name));
+ if (null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
+ throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
__Error.WinIOError(errorCode, name);
}
@@ -90,14 +90,14 @@ namespace System.Threading
internal unsafe EventWaitHandle(bool initialState, EventResetMode mode, string name, out bool createdNew, EventWaitHandleSecurity eventSecurity)
{
- if(name != null)
+ if (name != null)
{
#if PLATFORM_UNIX
- throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_NamedSynchronizationPrimitives"));
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives);
#else
if (System.IO.Path.MaxPath < name.Length)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name));
+ throw new ArgumentException(SR.Format(SR.Argument_WaitHandleNameTooLong, Path.MaxPath), nameof(name));
}
#endif
}
@@ -106,7 +106,7 @@ namespace System.Threading
SafeWaitHandle _handle = null;
Boolean isManualReset;
- switch(mode)
+ switch (mode)
{
case EventResetMode.ManualReset:
isManualReset = true;
@@ -116,7 +116,7 @@ namespace System.Threading
break;
default:
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFlag",name));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidFlag, name));
};
_handle = Win32Native.CreateEvent(secAttrs, isManualReset, initialState, name);
@@ -124,10 +124,9 @@ namespace System.Threading
if (_handle.IsInvalid)
{
-
_handle.SetHandleAsInvalid();
- if(null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
- throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle",name));
+ if (null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
+ throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
__Error.WinIOError(errorCode, name);
}
@@ -154,7 +153,7 @@ namespace System.Threading
throw new WaitHandleCannotBeOpenedException();
case OpenExistingResult.NameInvalid:
- throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", name));
+ throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
case OpenExistingResult.PathNotFound:
__Error.WinIOError(Win32Native.ERROR_PATH_NOT_FOUND, "");
@@ -173,23 +172,23 @@ namespace System.Threading
private static OpenExistingResult OpenExistingWorker(string name, EventWaitHandleRights rights, out EventWaitHandle result)
{
#if PLATFORM_UNIX
- throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_NamedSynchronizationPrimitives"));
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives);
#else
if (name == null)
{
- throw new ArgumentNullException(nameof(name), Environment.GetResourceString("ArgumentNull_WithParamName"));
+ throw new ArgumentNullException(nameof(name), SR.ArgumentNull_WithParamName);
}
- if(name.Length == 0)
+ if (name.Length == 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
}
- if(null != name && System.IO.Path.MaxPath < name.Length)
+ if (null != name && System.IO.Path.MaxPath < name.Length)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name));
+ throw new ArgumentException(SR.Format(SR.Argument_WaitHandleNameTooLong, Path.MaxPath), nameof(name));
}
-
+
Contract.EndContractBlock();
result = null;
@@ -200,14 +199,14 @@ namespace System.Threading
{
int errorCode = Marshal.GetLastWin32Error();
- if(Win32Native.ERROR_FILE_NOT_FOUND == errorCode || Win32Native.ERROR_INVALID_NAME == errorCode)
+ if (Win32Native.ERROR_FILE_NOT_FOUND == errorCode || Win32Native.ERROR_INVALID_NAME == errorCode)
return OpenExistingResult.NameNotFound;
if (Win32Native.ERROR_PATH_NOT_FOUND == errorCode)
return OpenExistingResult.PathNotFound;
- if(null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
+ if (null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
return OpenExistingResult.NameInvalid;
//this is for passed through Win32Native Errors
- __Error.WinIOError(errorCode,"");
+ __Error.WinIOError(errorCode, "");
}
result = new EventWaitHandle(myHandle);
return OpenExistingResult.Success;
diff --git a/src/mscorlib/src/System/Threading/ExecutionContext.cs b/src/mscorlib/src/System/Threading/ExecutionContext.cs
deleted file mode 100644
index 47a55a3bb9..0000000000
--- a/src/mscorlib/src/System/Threading/ExecutionContext.cs
+++ /dev/null
@@ -1,380 +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.
-/*============================================================
-**
-**
-**
-** Purpose: Capture execution context for a thread
-**
-**
-===========================================================*/
-namespace System.Threading
-{
- using System;
- using System.Security;
- using System.Runtime.Remoting;
- using System.Collections;
- using System.Collections.Generic;
- using System.Reflection;
- using System.Runtime.ExceptionServices;
- using System.Runtime.Serialization;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Diagnostics.CodeAnalysis;
-
- public delegate void ContextCallback(Object state);
-
- internal struct ExecutionContextSwitcher
- {
- internal ExecutionContext m_ec;
- internal SynchronizationContext m_sc;
-
- internal void Undo(Thread currentThread)
- {
- Debug.Assert(currentThread == Thread.CurrentThread);
-
- // The common case is that these have not changed, so avoid the cost of a write if not needed.
- if (currentThread.SynchronizationContext != m_sc)
- {
- currentThread.SynchronizationContext = m_sc;
- }
-
- if (currentThread.ExecutionContext != m_ec)
- {
- ExecutionContext.Restore(currentThread, m_ec);
- }
- }
- }
-
- [Serializable]
- public sealed class ExecutionContext : IDisposable, ISerializable
- {
- internal static readonly ExecutionContext Default = new ExecutionContext();
-
- private readonly IAsyncLocalValueMap m_localValues;
- private readonly IAsyncLocal[] m_localChangeNotifications;
- private readonly bool m_isFlowSuppressed;
-
- private ExecutionContext()
- {
- m_localValues = AsyncLocalValueMap.Empty;
- m_localChangeNotifications = Array.Empty<IAsyncLocal>();
- }
-
- private ExecutionContext(
- IAsyncLocalValueMap localValues,
- IAsyncLocal[] localChangeNotifications,
- bool isFlowSuppressed)
- {
- m_localValues = localValues;
- m_localChangeNotifications = localChangeNotifications;
- m_isFlowSuppressed = isFlowSuppressed;
- }
-
- public void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- {
- throw new ArgumentNullException(nameof(info));
- }
- Contract.EndContractBlock();
- }
-
- private ExecutionContext(SerializationInfo info, StreamingContext context)
- {
- }
-
- public static ExecutionContext Capture()
- {
- ExecutionContext executionContext = Thread.CurrentThread.ExecutionContext;
- return
- executionContext == null ? Default :
- executionContext.m_isFlowSuppressed ? null :
- executionContext;
- }
-
- private ExecutionContext ShallowClone(bool isFlowSuppressed)
- {
- Debug.Assert(isFlowSuppressed != m_isFlowSuppressed);
-
- if (!isFlowSuppressed &&
- m_localValues == Default.m_localValues &&
- m_localChangeNotifications == Default.m_localChangeNotifications)
- {
- return null; // implies the default context
- }
- return new ExecutionContext(m_localValues, m_localChangeNotifications, isFlowSuppressed);
- }
-
- public static AsyncFlowControl SuppressFlow()
- {
- Thread currentThread = Thread.CurrentThread;
- ExecutionContext executionContext = currentThread.ExecutionContext ?? Default;
- if (executionContext.m_isFlowSuppressed)
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotSupressFlowMultipleTimes"));
- }
- Contract.EndContractBlock();
-
- executionContext = executionContext.ShallowClone(isFlowSuppressed: true);
- var asyncFlowControl = new AsyncFlowControl();
- currentThread.ExecutionContext = executionContext;
- asyncFlowControl.Initialize(currentThread);
- return asyncFlowControl;
- }
-
- public static void RestoreFlow()
- {
- Thread currentThread = Thread.CurrentThread;
- ExecutionContext executionContext = currentThread.ExecutionContext;
- if (executionContext == null || !executionContext.m_isFlowSuppressed)
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotRestoreUnsupressedFlow"));
- }
- Contract.EndContractBlock();
-
- currentThread.ExecutionContext = executionContext.ShallowClone(isFlowSuppressed: false);
- }
-
- public static bool IsFlowSuppressed()
- {
- ExecutionContext executionContext = Thread.CurrentThread.ExecutionContext;
- return executionContext != null && executionContext.m_isFlowSuppressed;
- }
-
- [HandleProcessCorruptedStateExceptions]
- public static void Run(ExecutionContext executionContext, ContextCallback callback, Object state)
- {
- if (executionContext == null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NullContext"));
-
- Thread currentThread = Thread.CurrentThread;
- ExecutionContextSwitcher ecsw = default(ExecutionContextSwitcher);
- try
- {
- EstablishCopyOnWriteScope(currentThread, ref ecsw);
- ExecutionContext.Restore(currentThread, executionContext);
- callback(state);
- }
- catch
- {
- // Note: we have a "catch" rather than a "finally" because we want
- // to stop the first pass of EH here. That way we can restore the previous
- // context before any of our callers' EH filters run. That means we need to
- // end the scope separately in the non-exceptional case below.
- ecsw.Undo(currentThread);
- throw;
- }
- ecsw.Undo(currentThread);
- }
-
- internal static void Restore(Thread currentThread, ExecutionContext executionContext)
- {
- Debug.Assert(currentThread == Thread.CurrentThread);
-
- ExecutionContext previous = currentThread.ExecutionContext ?? Default;
- currentThread.ExecutionContext = executionContext;
-
- // New EC could be null if that's what ECS.Undo saved off.
- // For the purposes of dealing with context change, treat this as the default EC
- executionContext = executionContext ?? Default;
-
- if (previous != executionContext)
- {
- OnContextChanged(previous, executionContext);
- }
- }
-
- static internal void EstablishCopyOnWriteScope(Thread currentThread, ref ExecutionContextSwitcher ecsw)
- {
- Debug.Assert(currentThread == Thread.CurrentThread);
-
- ecsw.m_ec = currentThread.ExecutionContext;
- ecsw.m_sc = currentThread.SynchronizationContext;
- }
-
- [HandleProcessCorruptedStateExceptions]
- private static void OnContextChanged(ExecutionContext previous, ExecutionContext current)
- {
- Debug.Assert(previous != null);
- Debug.Assert(current != null);
- Debug.Assert(previous != current);
-
- foreach (IAsyncLocal local in previous.m_localChangeNotifications)
- {
- object previousValue;
- object currentValue;
- previous.m_localValues.TryGetValue(local, out previousValue);
- current.m_localValues.TryGetValue(local, out currentValue);
-
- if (previousValue != currentValue)
- local.OnValueChanged(previousValue, currentValue, true);
- }
-
- if (current.m_localChangeNotifications != previous.m_localChangeNotifications)
- {
- try
- {
- foreach (IAsyncLocal local in current.m_localChangeNotifications)
- {
- // If the local has a value in the previous context, we already fired the event for that local
- // in the code above.
- object previousValue;
- if (!previous.m_localValues.TryGetValue(local, out previousValue))
- {
- object currentValue;
- current.m_localValues.TryGetValue(local, out currentValue);
-
- if (previousValue != currentValue)
- local.OnValueChanged(previousValue, currentValue, true);
- }
- }
- }
- catch (Exception ex)
- {
- Environment.FailFast(
- Environment.GetResourceString("ExecutionContext_ExceptionInAsyncLocalNotification"),
- ex);
- }
- }
- }
-
- internal static object GetLocalValue(IAsyncLocal local)
- {
- ExecutionContext current = Thread.CurrentThread.ExecutionContext;
- if (current == null)
- return null;
-
- object value;
- current.m_localValues.TryGetValue(local, out value);
- return value;
- }
-
- internal static void SetLocalValue(IAsyncLocal local, object newValue, bool needChangeNotifications)
- {
- ExecutionContext current = Thread.CurrentThread.ExecutionContext ?? ExecutionContext.Default;
-
- object previousValue;
- bool hadPreviousValue = current.m_localValues.TryGetValue(local, out previousValue);
-
- if (previousValue == newValue)
- return;
-
- IAsyncLocalValueMap newValues = current.m_localValues.Set(local, newValue);
-
- //
- // Either copy the change notification array, or create a new one, depending on whether we need to add a new item.
- //
- IAsyncLocal[] newChangeNotifications = current.m_localChangeNotifications;
- if (needChangeNotifications)
- {
- if (hadPreviousValue)
- {
- Debug.Assert(Array.IndexOf(newChangeNotifications, local) >= 0);
- }
- else
- {
- int newNotificationIndex = newChangeNotifications.Length;
- Array.Resize(ref newChangeNotifications, newNotificationIndex + 1);
- newChangeNotifications[newNotificationIndex] = local;
- }
- }
-
- Thread.CurrentThread.ExecutionContext =
- new ExecutionContext(newValues, newChangeNotifications, current.m_isFlowSuppressed);
-
- if (needChangeNotifications)
- {
- local.OnValueChanged(previousValue, newValue, false);
- }
- }
-
- public ExecutionContext CreateCopy()
- {
- return this; // since CoreCLR's ExecutionContext is immutable, we don't need to create copies.
- }
-
- public void Dispose()
- {
- // For CLR compat only
- }
- }
-
- public struct AsyncFlowControl : IDisposable
- {
- private Thread _thread;
-
- internal void Initialize(Thread currentThread)
- {
- Debug.Assert(currentThread == Thread.CurrentThread);
- _thread = currentThread;
- }
-
- public void Undo()
- {
- if (_thread == null)
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotUseAFCMultiple"));
- }
- if (Thread.CurrentThread != _thread)
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotUseAFCOtherThread"));
- }
-
- // An async flow control cannot be undone when a different execution context is applied. The desktop framework
- // mutates the execution context when its state changes, and only changes the instance when an execution context
- // is applied (for instance, through ExecutionContext.Run). The framework prevents a suppressed-flow execution
- // context from being applied by returning null from ExecutionContext.Capture, so the only type of execution
- // context that can be applied is one whose flow is not suppressed. After suppressing flow and changing an async
- // local's value, the desktop framework verifies that a different execution context has not been applied by
- // checking the execution context instance against the one saved from when flow was suppressed. In .NET Core,
- // since the execution context instance will change after changing the async local's value, it verifies that a
- // different execution context has not been applied, by instead ensuring that the current execution context's
- // flow is suppressed.
- if (!ExecutionContext.IsFlowSuppressed())
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncFlowCtrlCtxMismatch"));
- }
- Contract.EndContractBlock();
-
- _thread = null;
- ExecutionContext.RestoreFlow();
- }
-
- public void Dispose()
- {
- Undo();
- }
-
- public override bool Equals(object obj)
- {
- return obj is AsyncFlowControl && Equals((AsyncFlowControl)obj);
- }
-
- public bool Equals(AsyncFlowControl obj)
- {
- return _thread == obj._thread;
- }
-
- public override int GetHashCode()
- {
- return _thread?.GetHashCode() ?? 0;
- }
-
- public static bool operator ==(AsyncFlowControl a, AsyncFlowControl b)
- {
- return a.Equals(b);
- }
-
- public static bool operator !=(AsyncFlowControl a, AsyncFlowControl b)
- {
- return !(a == b);
- }
- }
-}
-
-
diff --git a/src/mscorlib/src/System/Threading/Interlocked.cs b/src/mscorlib/src/System/Threading/Interlocked.cs
index 131d51a65b..7e2c2aeeab 100644
--- a/src/mscorlib/src/System/Threading/Interlocked.cs
+++ b/src/mscorlib/src/System/Threading/Interlocked.cs
@@ -3,21 +3,24 @@
// See the LICENSE file in the project root for more information.
//
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.Versioning;
+using System.Runtime;
+using System.Runtime.InteropServices;
+using System.Security;
+
namespace System.Threading
{
- using System;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.Versioning;
- using System.Runtime;
-
// After much discussion, we decided the Interlocked class doesn't need
// any HPA's for synchronization or external threading. They hurt C#'s
// codegen for the yield keyword, and arguably they didn't protect much.
// Instead, they penalized people (and compilers) for writing threadsafe
// code.
public static class Interlocked
- {
+ {
/******************************
* Increment
* Implemented: int
@@ -102,16 +105,16 @@ namespace System.Threading
*****************************/
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern int CompareExchange(ref int location1, int value, int comparand);
+ public static extern int CompareExchange(ref int location1, int value, int comparand);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern long CompareExchange(ref long location1, long value, long comparand);
+ public static extern long CompareExchange(ref long location1, long value, long comparand);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern float CompareExchange(ref float location1, float value, float comparand);
+ public static extern float CompareExchange(ref float location1, float value, float comparand);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern double CompareExchange(ref double location1, double value, double comparand);
+ public static extern double CompareExchange(ref double location1, double value, double comparand);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern Object CompareExchange(ref Object location1, Object value, Object comparand);
@@ -142,7 +145,7 @@ namespace System.Threading
* See getILIntrinsicImplementationForInterlocked() in VM\JitInterface.cpp
* for details.
*****************************************************************/
-
+
public static T CompareExchange<T>(ref T location1, T value, T comparand) where T : class
{
// _CompareExchange() passes back the value read from location1 via local named 'value'
@@ -169,28 +172,34 @@ namespace System.Threading
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern long ExchangeAdd(ref long location1, long value);
- public static int Add(ref int location1, int value)
+ public static int Add(ref int location1, int value)
{
return ExchangeAdd(ref location1, value) + value;
}
- public static long Add(ref long location1, long value)
+ public static long Add(ref long location1, long value)
{
return ExchangeAdd(ref location1, value) + value;
}
-
+
/******************************
* Read
*****************************/
public static long Read(ref long location)
{
- return Interlocked.CompareExchange(ref location,0,0);
+ return Interlocked.CompareExchange(ref location, 0, 0);
}
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern void MemoryBarrier();
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ private static extern void _MemoryBarrierProcessWide();
- public static void MemoryBarrier()
+ public static void MemoryBarrierProcessWide()
{
- Thread.MemoryBarrier();
+ _MemoryBarrierProcessWide();
}
}
}
diff --git a/src/mscorlib/src/System/Threading/LazyInitializer.cs b/src/mscorlib/src/System/Threading/LazyInitializer.cs
index af32673d03..d585ba6c35 100644
--- a/src/mscorlib/src/System/Threading/LazyInitializer.cs
+++ b/src/mscorlib/src/System/Threading/LazyInitializer.cs
@@ -13,40 +13,9 @@
using System.Diagnostics;
using System.Diagnostics.Contracts;
+
namespace System.Threading
{
-
- /// <summary>
- /// Specifies how a <see cref="T:System.Threading.Lazy{T}"/> instance should synchronize access among multiple threads.
- /// </summary>
- public enum LazyThreadSafetyMode
- {
- /// <summary>
- /// This mode makes no guarantees around the thread-safety of the <see cref="T:System.Threading.Lazy{T}"/> instance. If used from multiple threads, the behavior of the <see cref="T:System.Threading.Lazy{T}"/> is undefined.
- /// This mode should be used when a <see cref="T:System.Threading.Lazy{T}"/> is guaranteed to never be initialized from more than one thread simultaneously and high performance is crucial.
- /// If valueFactory throws an exception when the <see cref="T:System.Threading.Lazy{T}"/> is initialized, the exception will be cached and returned on subsequent accesses to Value. Also, if valueFactory recursively
- /// accesses Value on this <see cref="T:System.Threading.Lazy{T}"/> instance, a <see cref="T:System.InvalidOperationException"/> will be thrown.
- /// </summary>
- None,
-
- /// <summary>
- /// When multiple threads attempt to simultaneously initialize a <see cref="T:System.Threading.Lazy{T}"/> instance, this mode allows each thread to execute the
- /// valueFactory but only the first thread to complete initialization will be allowed to set the final value of the <see cref="T:System.Threading.Lazy{T}"/>.
- /// Once initialized successfully, any future calls to Value will return the cached result. If valueFactory throws an exception on any thread, that exception will be
- /// propagated out of Value. If any thread executes valueFactory without throwing an exception and, therefore, successfully sets the value, that value will be returned on
- /// subsequent accesses to Value from any thread. If no thread succeeds in setting the value, IsValueCreated will remain false and subsequent accesses to Value will result in
- /// the valueFactory delegate re-executing. Also, if valueFactory recursively accesses Value on this <see cref="T:System.Threading.Lazy{T}"/> instance, an exception will NOT be thrown.
- /// </summary>
- PublicationOnly,
-
- /// <summary>
- /// This mode uses locks to ensure that only a single thread can initialize a <see cref="T:System.Threading.Lazy{T}"/> instance in a thread-safe manner. In general,
- /// taken if this mode is used in conjunction with a <see cref="T:System.Threading.Lazy{T}"/> valueFactory delegate that uses locks internally, a deadlock can occur if not
- /// handled carefully. If valueFactory throws an exception when the<see cref="T:System.Threading.Lazy{T}"/> is initialized, the exception will be cached and returned on
- /// subsequent accesses to Value. Also, if valueFactory recursively accesses Value on this <see cref="T:System.Threading.Lazy{T}"/> instance, a <see cref="T:System.InvalidOperationException"/> will be thrown.
- /// </summary>
- ExecutionAndPublication
- }
/// <summary>
/// Provides lazy initialization routines.
/// </summary>
@@ -82,16 +51,8 @@ namespace System.Threading
/// if an object was not used and to then dispose of the object appropriately.
/// </para>
/// </remarks>
- public static T EnsureInitialized<T>(ref T target) where T : class
- {
- // Fast path.
- if (Volatile.Read<T>(ref target) != null)
- {
- return target;
- }
-
- return EnsureInitializedCore<T>(ref target, LazyHelpers<T>.s_activatorFactorySelector);
- }
+ public static T EnsureInitialized<T>(ref T target) where T : class =>
+ Volatile.Read<T>(ref target) ?? EnsureInitializedCore<T>(ref target, LazyHelpers<T>.s_activatorFactorySelector);
/// <summary>
/// Initializes a target reference type using the specified function if it has not already been
@@ -121,16 +82,8 @@ namespace System.Threading
/// if an object was not used and to then dispose of the object appropriately.
/// </para>
/// </remarks>
- public static T EnsureInitialized<T>(ref T target, Func<T> valueFactory) where T : class
- {
- // Fast path.
- if (Volatile.Read<T>(ref target) != null)
- {
- return target;
- }
-
- return EnsureInitializedCore<T>(ref target, valueFactory);
- }
+ public static T EnsureInitialized<T>(ref T target, Func<T> valueFactory) where T : class =>
+ Volatile.Read<T>(ref target) ?? EnsureInitializedCore<T>(ref target, valueFactory);
/// <summary>
/// Initialize the target using the given delegate (slow path).
@@ -144,7 +97,7 @@ namespace System.Threading
T value = valueFactory();
if (value == null)
{
- throw new InvalidOperationException(Environment.GetResourceString("Lazy_StaticInit_InvalidOperation"));
+ throw new InvalidOperationException(SR.Lazy_StaticInit_InvalidOperation);
}
Interlocked.CompareExchange(ref target, value, null);
@@ -152,7 +105,6 @@ namespace System.Threading
return target;
}
-
/// <summary>
/// Initializes a target reference or value type with its default constructor if it has not already
/// been initialized.
@@ -198,11 +150,33 @@ namespace System.Threading
return target;
}
-
return EnsureInitializedCore<T>(ref target, ref initialized, ref syncLock, valueFactory);
}
/// <summary>
+ /// Ensure the lock object is intialized.
+ /// </summary>
+ /// <param name="syncLock">A reference to a location containing a mutual exclusive lock. If <paramref name="syncLock"/> is null,
+ /// a new object will be instantiated.</param>
+ /// <returns>Initialized lock object.</returns>
+ private static object EnsureLockInitialized(ref object syncLock) =>
+ syncLock ??
+ Interlocked.CompareExchange(ref syncLock, new object(), null) ??
+ syncLock;
+
+ /// <summary>
+ /// Initializes a target reference type with a specified function if it has not already been initialized.
+ /// </summary>
+ /// <typeparam name="T">The type of the reference to be initialized. Has to be reference type.</typeparam>
+ /// <param name="target">A reference of type <typeparamref name="T"/> to initialize if it has not already been initialized.</param>
+ /// <param name="syncLock">A reference to an object used as the mutually exclusive lock for initializing
+ /// <paramref name="target"/>. If <paramref name="syncLock"/> is null, a new object will be instantiated.</param>
+ /// <param name="valueFactory">The <see cref="T:System.Func{T}"/> invoked to initialize the reference.</param>
+ /// <returns>The initialized value of type <typeparamref name="T"/>.</returns>
+ public static T EnsureInitialized<T>(ref T target, ref object syncLock, Func<T> valueFactory) where T : class =>
+ Volatile.Read(ref target) ?? EnsureInitializedCore<T>(ref target, ref syncLock, valueFactory);
+
+ /// <summary>
/// Ensure the target is initialized and return the value (slow path). This overload permits nulls
/// and also works for value type targets. Uses the supplied function to create the value.
/// </summary>
@@ -217,35 +191,52 @@ namespace System.Threading
/// <returns>The initialized object.</returns>
private static T EnsureInitializedCore<T>(ref T target, ref bool initialized, ref object syncLock, Func<T> valueFactory)
{
- // Lazily initialize the lock if necessary.
- object slock = syncLock;
- if (slock == null)
+ // Lazily initialize the lock if necessary and, then double check if initialization is still required.
+ lock (EnsureLockInitialized(ref syncLock))
{
- object newLock = new object();
- slock = Interlocked.CompareExchange(ref syncLock, newLock, null);
- if (slock == null)
+ if (!Volatile.Read(ref initialized))
{
- slock = newLock;
+ target = valueFactory();
+ Volatile.Write(ref initialized, true);
}
}
- // Now double check that initialization is still required.
- lock (slock)
+ return target;
+ }
+
+ /// <summary>
+ /// Ensure the target is initialized and return the value (slow path). This overload works only for reference type targets.
+ /// Uses the supplied function to create the value.
+ /// </summary>
+ /// <typeparam name="T">The type of target. Has to be reference type.</typeparam>
+ /// <param name="target">A reference to the target to be initialized.</param>
+ /// <param name="syncLock">A reference to a location containing a mutual exclusive lock. If <paramref name="syncLock"/> is null,
+ /// a new object will be instantiated.</param>
+ /// <param name="valueFactory">
+ /// The <see cref="T:System.Func{T}"/> to invoke in order to produce the lazily-initialized value.
+ /// </param>
+ /// <returns>The initialized object.</returns>
+ private static T EnsureInitializedCore<T>(ref T target, ref object syncLock, Func<T> valueFactory) where T : class
+ {
+ // Lazily initialize the lock if necessary and, then double check if initialization is still required.
+ lock (EnsureLockInitialized(ref syncLock))
{
- if (!Volatile.Read(ref initialized))
+ if (Volatile.Read(ref target) == null)
{
- target = valueFactory();
- Volatile.Write(ref initialized, true);
+ Volatile.Write(ref target, valueFactory());
+ if (target == null)
+ {
+ throw new InvalidOperationException(SR.Lazy_StaticInit_InvalidOperation);
+ }
}
}
return target;
}
-
}
// Caches the activation selector function to avoid delegate allocations.
- static class LazyHelpers<T>
+ internal static class LazyHelpers<T>
{
internal static Func<T> s_activatorFactorySelector = new Func<T>(ActivatorFactorySelector);
@@ -257,7 +248,7 @@ namespace System.Threading
}
catch (MissingMethodException)
{
- throw new MissingMemberException(Environment.GetResourceString("Lazy_CreateValue_NoParameterlessCtorForT"));
+ throw new MissingMemberException(SR.Lazy_CreateValue_NoParameterlessCtorForT);
}
}
}
diff --git a/src/mscorlib/src/System/Threading/LockRecursionException.cs b/src/mscorlib/src/System/Threading/LockRecursionException.cs
deleted file mode 100644
index 40f04b00b4..0000000000
--- a/src/mscorlib/src/System/Threading/LockRecursionException.cs
+++ /dev/null
@@ -1,30 +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.
-
-/*============================================================
-//
-//
-//
-// Purpose:
-// This exception represents a failed attempt to recursively
-// acquire a lock, because the particular lock kind doesn't
-// support it in its current state.
-============================================================*/
-
-namespace System.Threading
-{
- using System;
- using System.Runtime.Serialization;
- using System.Runtime.CompilerServices;
-
- [Serializable]
- public class LockRecursionException : System.Exception
- {
- public LockRecursionException() { }
- public LockRecursionException(string message) : base(message) { }
- protected LockRecursionException(SerializationInfo info, StreamingContext context) : base(info, context) { }
- public LockRecursionException(string message, Exception innerException) : base(message, innerException) { }
- }
-
-}
diff --git a/src/mscorlib/src/System/Threading/ManualResetEvent.cs b/src/mscorlib/src/System/Threading/ManualResetEvent.cs
deleted file mode 100644
index a8e012fb43..0000000000
--- a/src/mscorlib/src/System/Threading/ManualResetEvent.cs
+++ /dev/null
@@ -1,24 +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.
-
-//
-/*=============================================================================
-**
-**
-**
-** Purpose: An example of a WaitHandle class
-**
-**
-=============================================================================*/
-namespace System.Threading {
-
- using System;
- using System.Runtime.InteropServices;
-
- public sealed class ManualResetEvent : EventWaitHandle
- {
- public ManualResetEvent(bool initialState) : base(initialState,EventResetMode.ManualReset){}
- }
-}
-
diff --git a/src/mscorlib/src/System/Threading/ManualResetEventSlim.cs b/src/mscorlib/src/System/Threading/ManualResetEventSlim.cs
index 2d57b4102b..402a76cdc7 100644
--- a/src/mscorlib/src/System/Threading/ManualResetEventSlim.cs
+++ b/src/mscorlib/src/System/Threading/ManualResetEventSlim.cs
@@ -20,7 +20,6 @@ using System.Diagnostics.Contracts;
namespace System.Threading
{
-
// ManualResetEventSlim wraps a manual-reset event internally with a little bit of
// spinning. When an event will be set imminently, it is often advantageous to avoid
// a 4k+ cycle context switch in favor of briefly spinning. Therefore we layer on to
@@ -98,7 +97,6 @@ namespace System.Threading
/// </remarks>
public WaitHandle WaitHandle
{
-
get
{
ThrowIfDisposed();
@@ -165,11 +163,10 @@ namespace System.Threading
// it is possible for the max number of waiters to be exceeded via user-code, hence we use a real exception here.
if (value >= NumWaitersState_MaxValue)
- throw new InvalidOperationException(String.Format(Environment.GetResourceString("ManualResetEventSlim_ctor_TooManyWaiters"), NumWaitersState_MaxValue));
+ throw new InvalidOperationException(String.Format(SR.ManualResetEventSlim_ctor_TooManyWaiters, NumWaitersState_MaxValue));
UpdateStateAtomically(value << NumWaitersState_ShiftCount, NumWaitersState_BitMask);
}
-
}
//-----------------------------------------------------------------------------------
@@ -184,7 +181,6 @@ namespace System.Threading
public ManualResetEventSlim()
: this(false)
{
-
}
/// <summary>
@@ -222,7 +218,7 @@ namespace System.Threading
{
throw new ArgumentOutOfRangeException(
nameof(spinCount),
- String.Format(Environment.GetResourceString("ManualResetEventSlim_ctor_SpinCountOutOfRange"), SpinCountState_MaxValue));
+ String.Format(SR.ManualResetEventSlim_ctor_SpinCountOutOfRange, SpinCountState_MaxValue));
}
// We will suppress default spin because the user specified a count.
@@ -236,14 +232,13 @@ namespace System.Threading
/// <param name="spinCount">The spin count that decides when the event will block.</param>
private void Initialize(bool initialState, int spinCount)
{
- this.m_combinedState = initialState ? (1 << SignalledState_ShiftCount) : 0;
+ m_combinedState = initialState ? (1 << SignalledState_ShiftCount) : 0;
//the spinCount argument has been validated by the ctors.
//but we now sanity check our predefined constants.
Debug.Assert(DEFAULT_SPIN_SP >= 0, "Internal error - DEFAULT_SPIN_SP is outside the legal range.");
Debug.Assert(DEFAULT_SPIN_SP <= SpinCountState_MaxValue, "Internal error - DEFAULT_SPIN_SP is outside the legal range.");
SpinCount = PlatformHelper.IsSingleProcessor ? DEFAULT_SPIN_SP : spinCount;
-
}
/// <summary>
@@ -283,7 +278,6 @@ namespace System.Threading
}
else
{
-
// Now that the event is published, verify that the state hasn't changed since
// we snapped the preInitializeState. Another thread could have done that
// between our initial observation above and here. The barrier incurred from
@@ -337,7 +331,6 @@ namespace System.Threading
Debug.Assert(m_lock != null); //if waiters>0, then m_lock has already been created.
lock (m_lock)
{
-
Monitor.PulseAll(m_lock);
}
}
@@ -665,7 +658,6 @@ namespace System.Threading
// Now just loop back around, and the right thing will happen. Either:
// 1. We had a spurious wake-up due to some other wait being canceled via a different cancellationToken (rewait)
// or 2. the wait was successful. (the loop will break)
-
}
}
}
@@ -725,7 +717,7 @@ namespace System.Threading
private void ThrowIfDisposed()
{
if ((m_combinedState & Dispose_BitMask) != 0)
- throw new ObjectDisposedException(Environment.GetResourceString("ManualResetEventSlim_Disposed"));
+ throw new ObjectDisposedException(SR.ManualResetEventSlim_Disposed);
}
/// <summary>
diff --git a/src/mscorlib/src/System/Threading/Monitor.cs b/src/mscorlib/src/System/Threading/Monitor.cs
index fdbc384243..3ace3335aa 100644
--- a/src/mscorlib/src/System/Threading/Monitor.cs
+++ b/src/mscorlib/src/System/Threading/Monitor.cs
@@ -14,19 +14,20 @@
=============================================================================*/
-namespace System.Threading {
-
- using System;
- using System.Runtime;
- using System.Runtime.Remoting;
- using System.Threading;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.Versioning;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- public static class Monitor
+
+using System;
+using System.Runtime;
+using System.Runtime.Remoting;
+using System.Threading;
+using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.Versioning;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System.Threading
+{
+ public static class Monitor
{
/*=========================================================================
** Obtain the monitor lock of obj. Will block if another thread holds the lock
@@ -56,7 +57,7 @@ namespace System.Threading {
private static void ThrowLockTakenException()
{
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeFalse"), "lockTaken");
+ throw new ArgumentException(SR.Argument_MustBeFalse, "lockTaken");
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -75,7 +76,7 @@ namespace System.Threading {
=========================================================================*/
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void Exit(Object obj);
-
+
/*=========================================================================
** Similar to Enter, but will never block. That is, if the current thread can
** acquire the monitor lock without blocking, it will do so and TRUE will
@@ -99,7 +100,7 @@ namespace System.Threading {
ReliableEnterTimeout(obj, 0, ref lockTaken);
}
-
+
/*=========================================================================
** Version of TryEnter that will block, but only up to a timeout period
** expressed in milliseconds. If timeout == Timeout.Infinite the method
@@ -121,7 +122,7 @@ namespace System.Threading {
{
long tm = (long)timeout.TotalMilliseconds;
if (tm < -1 || tm > (long)Int32.MaxValue)
- throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
return (int)tm;
}
diff --git a/src/mscorlib/src/System/Threading/Mutex.cs b/src/mscorlib/src/System/Threading/Mutex.cs
index dcb821307a..454a323f9a 100644
--- a/src/mscorlib/src/System/Threading/Mutex.cs
+++ b/src/mscorlib/src/System/Threading/Mutex.cs
@@ -11,8 +11,9 @@
**
**
=============================================================================*/
-namespace System.Threading
-{
+
+namespace System.Threading
+{
using System;
using System.Threading;
using System.Runtime.CompilerServices;
@@ -28,7 +29,7 @@ namespace System.Threading
public sealed class Mutex : WaitHandle
{
- static bool dummyBool;
+ private static bool dummyBool;
internal class MutexSecurity
{
@@ -46,12 +47,12 @@ namespace System.Threading
// Empty name is treated as an unnamed mutex. Set to null, and we will check for null from now on.
name = null;
}
-#if !PLATFORM_UNIX
+#if PLATFORM_WINDOWS
if (name != null && System.IO.Path.MaxPath < name.Length)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name));
+ throw new ArgumentException(SR.Format(SR.Argument_WaitHandleNameTooLong, Path.MaxPath), nameof(name));
}
-#endif
+#endif // PLATFORM_WINDOWS
Contract.EndContractBlock();
Win32Native.SECURITY_ATTRIBUTES secAttrs = null;
@@ -67,20 +68,20 @@ namespace System.Threading
RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(
tryCode,
cleanupCode,
- cleanupInfo);
+ cleanupInfo);
createdNew = tryCodeHelper.m_newMutex;
}
- internal class MutexTryCodeHelper
+ internal class MutexTryCodeHelper
{
- bool m_initiallyOwned;
- MutexCleanupInfo m_cleanupInfo;
+ private bool m_initiallyOwned;
+ private MutexCleanupInfo m_cleanupInfo;
internal bool m_newMutex;
- String m_name;
- Win32Native.SECURITY_ATTRIBUTES m_secAttrs;
- Mutex m_mutex;
+ private String m_name;
+ private Win32Native.SECURITY_ATTRIBUTES m_secAttrs;
+ private Mutex m_mutex;
- internal MutexTryCodeHelper(bool initiallyOwned,MutexCleanupInfo cleanupInfo, String name, Win32Native.SECURITY_ATTRIBUTES secAttrs, Mutex mutex)
+ internal MutexTryCodeHelper(bool initiallyOwned, MutexCleanupInfo cleanupInfo, String name, Win32Native.SECURITY_ATTRIBUTES secAttrs, Mutex mutex)
{
Debug.Assert(name == null || name.Length != 0);
@@ -92,16 +93,16 @@ namespace System.Threading
}
internal void MutexTryCode(object userData)
- {
+ {
SafeWaitHandle mutexHandle = null;
// try block
RuntimeHelpers.PrepareConstrainedRegions();
- try
+ try
{
}
- finally
+ finally
{
- if (m_initiallyOwned)
+ if (m_initiallyOwned)
{
m_cleanupInfo.inCriticalRegion = true;
}
@@ -109,15 +110,15 @@ namespace System.Threading
int errorCode = 0;
RuntimeHelpers.PrepareConstrainedRegions();
- try
+ try
{
}
- finally
+ finally
{
errorCode = CreateMutexHandle(m_initiallyOwned, m_name, m_secAttrs, out mutexHandle);
- }
+ }
- if (mutexHandle.IsInvalid)
+ if (mutexHandle.IsInvalid)
{
mutexHandle.SetHandleAsInvalid();
if (m_name != null)
@@ -127,11 +128,11 @@ namespace System.Threading
#if PLATFORM_UNIX
case Win32Native.ERROR_FILENAME_EXCED_RANGE:
// On Unix, length validation is done by CoreCLR's PAL after converting to utf-8
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Interop.Sys.MaxName), "name");
+ throw new ArgumentException(SR.Format(SR.Argument_WaitHandleNameTooLong, Interop.Sys.MaxName), "name");
#endif
case Win32Native.ERROR_INVALID_HANDLE:
- throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", m_name));
+ throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, m_name));
}
}
__Error.WinIOError(errorCode, m_name);
@@ -140,19 +141,21 @@ namespace System.Threading
m_mutex.SetHandleInternal(mutexHandle);
m_mutex.hasThreadAffinity = true;
-
}
}
private void MutexCleanupCode(Object userData, bool exceptionThrown)
{
- MutexCleanupInfo cleanupInfo = (MutexCleanupInfo) userData;
-
+ MutexCleanupInfo cleanupInfo = (MutexCleanupInfo)userData;
+
// If hasThreadAffinity isn't true, we've thrown an exception in the above try, and we must free the mutex
// on this OS thread before ending our thread affninity.
- if(!hasThreadAffinity) {
- if (cleanupInfo.mutexHandle != null && !cleanupInfo.mutexHandle.IsInvalid) {
- if( cleanupInfo.inCriticalRegion) {
+ if (!hasThreadAffinity)
+ {
+ if (cleanupInfo.mutexHandle != null && !cleanupInfo.mutexHandle.IsInvalid)
+ {
+ if (cleanupInfo.inCriticalRegion)
+ {
Win32Native.ReleaseMutex(cleanupInfo.mutexHandle);
}
cleanupInfo.mutexHandle.Dispose();
@@ -171,7 +174,8 @@ namespace System.Threading
}
}
- public Mutex(bool initiallyOwned, String name) : this(initiallyOwned, name, out dummyBool) {
+ public Mutex(bool initiallyOwned, String name) : this(initiallyOwned, name, out dummyBool)
+ {
}
public Mutex(bool initiallyOwned) : this(initiallyOwned, null, out dummyBool)
@@ -181,7 +185,7 @@ namespace System.Threading
public Mutex() : this(false, null, out dummyBool)
{
}
-
+
private Mutex(SafeWaitHandle handle)
{
SetHandleInternal(handle);
@@ -190,7 +194,7 @@ namespace System.Threading
public static Mutex OpenExisting(string name)
{
- return OpenExisting(name, (MutexRights) 0);
+ return OpenExisting(name, (MutexRights)0);
}
internal enum MutexRights
@@ -206,7 +210,7 @@ namespace System.Threading
throw new WaitHandleCannotBeOpenedException();
case OpenExistingResult.NameInvalid:
- throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", name));
+ throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
case OpenExistingResult.PathNotFound:
__Error.WinIOError(Win32Native.ERROR_PATH_NOT_FOUND, name);
@@ -226,17 +230,17 @@ namespace System.Threading
{
if (name == null)
{
- throw new ArgumentNullException(nameof(name), Environment.GetResourceString("ArgumentNull_WithParamName"));
+ throw new ArgumentNullException(nameof(name), SR.ArgumentNull_WithParamName);
}
- if(name.Length == 0)
+ if (name.Length == 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
}
#if !PLATFORM_UNIX
- if(System.IO.Path.MaxPath < name.Length)
+ if (System.IO.Path.MaxPath < name.Length)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name));
+ throw new ArgumentException(SR.Format(SR.Argument_WaitHandleNameTooLong, Path.MaxPath), nameof(name));
}
#endif
Contract.EndContractBlock();
@@ -258,11 +262,11 @@ namespace System.Threading
if (name != null && errorCode == Win32Native.ERROR_FILENAME_EXCED_RANGE)
{
// On Unix, length validation is done by CoreCLR's PAL after converting to utf-8
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Interop.Sys.MaxName), nameof(name));
+ throw new ArgumentException(SR.Format(SR.Argument_WaitHandleNameTooLong, Interop.Sys.MaxName), nameof(name));
}
#endif
- if(Win32Native.ERROR_FILE_NOT_FOUND == errorCode || Win32Native.ERROR_INVALID_NAME == errorCode)
+ if (Win32Native.ERROR_FILE_NOT_FOUND == errorCode || Win32Native.ERROR_INVALID_NAME == errorCode)
return OpenExistingResult.NameNotFound;
if (Win32Native.ERROR_PATH_NOT_FOUND == errorCode)
return OpenExistingResult.PathNotFound;
@@ -270,7 +274,7 @@ namespace System.Threading
return OpenExistingResult.NameInvalid;
// this is for passed through Win32Native Errors
- __Error.WinIOError(errorCode,name);
+ __Error.WinIOError(errorCode, name);
}
result = new Mutex(myHandle);
@@ -287,11 +291,11 @@ namespace System.Threading
}
else
{
- throw new ApplicationException(Environment.GetResourceString("Arg_SynchronizationLockException"));
+ throw new ApplicationException(SR.Arg_SynchronizationLockException);
}
}
- static int CreateMutexHandle(bool initiallyOwned, String name, Win32Native.SECURITY_ATTRIBUTES securityAttribute, out SafeWaitHandle mutexHandle)
+ private static int CreateMutexHandle(bool initiallyOwned, String name, Win32Native.SECURITY_ATTRIBUTES securityAttribute, out SafeWaitHandle mutexHandle)
{
int errorCode;
diff --git a/src/mscorlib/src/System/Threading/Overlapped.cs b/src/mscorlib/src/System/Threading/Overlapped.cs
index d3caff5e74..0830ee6b6c 100644
--- a/src/mscorlib/src/System/Threading/Overlapped.cs
+++ b/src/mscorlib/src/System/Threading/Overlapped.cs
@@ -24,18 +24,18 @@
=============================================================================*/
-namespace System.Threading
-{
- using System;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Security;
- using System.Runtime.ConstrainedExecution;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Collections.Concurrent;
-
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+using System.Security;
+using System.Runtime.ConstrainedExecution;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Collections.Concurrent;
+
+namespace System.Threading
+{
#region struct NativeOverlapped
// Valuetype that represents the (unmanaged) Win32 OVERLAPPED structure
@@ -45,11 +45,11 @@ namespace System.Threading
[System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public struct NativeOverlapped
{
- public IntPtr InternalLow;
- public IntPtr InternalHigh;
- public int OffsetLow;
- public int OffsetHigh;
- public IntPtr EventHandle;
+ public IntPtr InternalLow;
+ public IntPtr InternalHigh;
+ public int OffsetLow;
+ public int OffsetHigh;
+ public IntPtr EventHandle;
}
#endregion struct NativeOverlapped
@@ -59,15 +59,11 @@ namespace System.Threading
unsafe internal class _IOCompletionCallback
{
- IOCompletionCallback _ioCompletionCallback;
- ExecutionContext _executionContext;
- uint _errorCode; // Error code
- uint _numBytes; // No. of bytes transferred
- NativeOverlapped* _pOVERLAP;
-
- static _IOCompletionCallback()
- {
- }
+ private IOCompletionCallback _ioCompletionCallback;
+ private ExecutionContext _executionContext;
+ private uint _errorCode; // Error code
+ private uint _numBytes; // No. of bytes transferred
+ private NativeOverlapped* _pOVERLAP;
internal _IOCompletionCallback(IOCompletionCallback ioCompletionCallback)
{
@@ -79,12 +75,12 @@ namespace System.Threading
static internal ContextCallback _ccb = new ContextCallback(IOCompletionCallback_Context);
static internal void IOCompletionCallback_Context(Object state)
{
- _IOCompletionCallback helper = (_IOCompletionCallback)state;
- Debug.Assert(helper != null,"_IOCompletionCallback cannot be null");
+ _IOCompletionCallback helper = (_IOCompletionCallback)state;
+ Debug.Assert(helper != null, "_IOCompletionCallback cannot be null");
helper._ioCompletionCallback(helper._errorCode, helper._numBytes, helper._pOVERLAP);
}
-
+
// call back helper
static unsafe internal void PerformIOCompletionCallback(uint errorCode, // Error code
uint numBytes, // No. of bytes transferred
@@ -97,13 +93,13 @@ namespace System.Threading
do
{
overlapped = OverlappedData.GetOverlappedFromNative(pOVERLAP).m_overlapped;
- helper = overlapped.iocbHelper;
+ helper = overlapped.iocbHelper;
if (helper == null || helper._executionContext == null || helper._executionContext == ExecutionContext.Default)
{
// We got here because of UnsafePack (or) Pack with EC flow supressed
IOCompletionCallback callback = overlapped.UserCallback;
- callback( errorCode, numBytes, pOVERLAP);
+ callback(errorCode, numBytes, pOVERLAP);
}
else
{
@@ -112,12 +108,11 @@ namespace System.Threading
helper._numBytes = numBytes;
helper._pOVERLAP = pOVERLAP;
ExecutionContext.Run(helper._executionContext, _ccb, helper);
- }
+ }
//Quickly check the VM again, to see if a packet has arrived.
OverlappedData.CheckVMForIOPacket(out pOVERLAP, out errorCode, out numBytes);
} while (pOVERLAP != null);
-
}
}
@@ -147,7 +142,7 @@ namespace System.Threading
internal NativeOverlapped m_nativeOverlapped;
// Adding an empty default ctor for annotation purposes
- internal OverlappedData(){}
+ internal OverlappedData() { }
internal void ReInitialize()
{
@@ -169,8 +164,9 @@ namespace System.Threading
unsafe internal NativeOverlapped* Pack(IOCompletionCallback iocb, Object userData)
{
- if (!m_pinSelf.IsNull()) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_Overlapped_Pack"));
+ if (!m_pinSelf.IsNull())
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_Overlapped_Pack);
}
if (iocb != null)
@@ -199,9 +195,10 @@ namespace System.Threading
}
unsafe internal NativeOverlapped* UnsafePack(IOCompletionCallback iocb, Object userData)
- {
- if (!m_pinSelf.IsNull()) {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_Overlapped_Pack"));
+ {
+ if (!m_pinSelf.IsNull())
+ {
+ throw new InvalidOperationException(SR.InvalidOperation_Overlapped_Pack);
}
m_userObject = userData;
if (m_userObject != null)
@@ -225,7 +222,7 @@ namespace System.Threading
get { return m_nativeOverlapped.EventHandle; }
set { m_nativeOverlapped.EventHandle = value; }
}
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
unsafe private extern NativeOverlapped* AllocateNativeOverlapped();
@@ -233,7 +230,7 @@ namespace System.Threading
unsafe internal static extern void FreeNativeOverlapped(NativeOverlapped* nativeOverlappedPtr);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- unsafe internal static extern OverlappedData GetOverlappedFromNative(NativeOverlapped* nativeOverlappedPtr);
+ unsafe internal static extern OverlappedData GetOverlappedFromNative(NativeOverlapped* nativeOverlappedPtr);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
unsafe internal static extern void CheckVMForIOPacket(out NativeOverlapped* pOVERLAP, out uint errorCode, out uint numBytes);
@@ -244,21 +241,20 @@ namespace System.Threading
#region class Overlapped
- /// <internalonly/>
public class Overlapped
{
private OverlappedData m_overlappedData;
- private static PinnableBufferCache s_overlappedDataCache = new PinnableBufferCache("System.Threading.OverlappedData", ()=> new OverlappedData());
-
- public Overlapped()
+ private static PinnableBufferCache s_overlappedDataCache = new PinnableBufferCache("System.Threading.OverlappedData", () => new OverlappedData());
+
+ public Overlapped()
{
- m_overlappedData = (OverlappedData) s_overlappedDataCache.Allocate();
+ m_overlappedData = (OverlappedData)s_overlappedDataCache.Allocate();
m_overlappedData.m_overlapped = this;
}
public Overlapped(int offsetLo, int offsetHi, IntPtr hEvent, IAsyncResult ar)
{
- m_overlappedData = (OverlappedData) s_overlappedDataCache.Allocate();
+ m_overlappedData = (OverlappedData)s_overlappedDataCache.Allocate();
m_overlappedData.m_overlapped = this;
m_overlappedData.m_nativeOverlapped.OffsetLow = offsetLo;
m_overlappedData.m_nativeOverlapped.OffsetHigh = offsetHi;
@@ -321,7 +317,7 @@ namespace System.Threading
[CLSCompliant(false)]
unsafe public NativeOverlapped* Pack(IOCompletionCallback iocb)
{
- return Pack (iocb, null);
+ return Pack(iocb, null);
}
[CLSCompliant(false)]
@@ -334,12 +330,12 @@ namespace System.Threading
[CLSCompliant(false)]
unsafe public NativeOverlapped* UnsafePack(IOCompletionCallback iocb)
{
- return UnsafePack (iocb, null);
+ return UnsafePack(iocb, null);
}
[CLSCompliant(false)]
unsafe public NativeOverlapped* UnsafePack(IOCompletionCallback iocb, Object userData)
- {
+ {
return m_overlappedData.UnsafePack(iocb, userData);
}
@@ -355,7 +351,7 @@ namespace System.Threading
Contract.EndContractBlock();
Overlapped overlapped = OverlappedData.GetOverlappedFromNative(nativeOverlappedPtr).m_overlapped;
-
+
return overlapped;
}
@@ -373,9 +369,7 @@ namespace System.Threading
overlappedData.ReInitialize();
s_overlappedDataCache.Free(overlappedData);
}
-
}
#endregion class Overlapped
-
} // namespace
diff --git a/src/mscorlib/src/System/Threading/ParameterizedThreadStart.cs b/src/mscorlib/src/System/Threading/ParameterizedThreadStart.cs
deleted file mode 100644
index 32b63153c4..0000000000
--- a/src/mscorlib/src/System/Threading/ParameterizedThreadStart.cs
+++ /dev/null
@@ -1,23 +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.
-
-//
-/*=============================================================================
-**
-**
-**
-** Purpose: This class is a Delegate which defines the start method
-** for starting a thread. That method must match this delegate.
-**
-**
-=============================================================================*/
-
-
-namespace System.Threading {
- using System.Threading;
- using System.Runtime.InteropServices;
-
- [ComVisibleAttribute(false)]
- public delegate void ParameterizedThreadStart(object obj);
-}
diff --git a/src/mscorlib/src/System/Threading/ReaderWriterLockSlim.cs b/src/mscorlib/src/System/Threading/ReaderWriterLockSlim.cs
new file mode 100644
index 0000000000..98517ad85f
--- /dev/null
+++ b/src/mscorlib/src/System/Threading/ReaderWriterLockSlim.cs
@@ -0,0 +1,1311 @@
+// 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 Internal.Runtime.Augments;
+using System.Diagnostics; // for TraceInformation
+using System.Threading;
+using System.Runtime.CompilerServices;
+
+namespace System.Threading
+{
+ public enum LockRecursionPolicy
+ {
+ NoRecursion = 0,
+ SupportsRecursion = 1,
+ }
+
+ //
+ // ReaderWriterCount tracks how many of each kind of lock is held by each thread.
+ // We keep a linked list for each thread, attached to a ThreadStatic field.
+ // These are reused wherever possible, so that a given thread will only
+ // allocate N of these, where N is the maximum number of locks held simultaneously
+ // by that thread.
+ //
+ internal class ReaderWriterCount
+ {
+ // Which lock does this object belong to? This is a numeric ID for two reasons:
+ // 1) We don't want this field to keep the lock object alive, and a WeakReference would
+ // be too expensive.
+ // 2) Setting the value of a long is faster than setting the value of a reference.
+ // The "hot" paths in ReaderWriterLockSlim are short enough that this actually
+ // matters.
+ public long lockID;
+
+ // How many reader locks does this thread hold on this ReaderWriterLockSlim instance?
+ public int readercount;
+
+ // Ditto for writer/upgrader counts. These are only used if the lock allows recursion.
+ // But we have to have the fields on every ReaderWriterCount instance, because
+ // we reuse it for different locks.
+ public int writercount;
+ public int upgradecount;
+
+ // Next RWC in this thread's list.
+ public ReaderWriterCount next;
+ }
+
+ /// <summary>
+ /// A reader-writer lock implementation that is intended to be simple, yet very
+ /// efficient. In particular only 1 interlocked operation is taken for any lock
+ /// operation (we use spin locks to achieve this). The spin lock is never held
+ /// for more than a few instructions (in particular, we never call event APIs
+ /// or in fact any non-trivial API while holding the spin lock).
+ /// </summary>
+ public class ReaderWriterLockSlim : IDisposable
+ {
+ //Specifying if locked can be reacquired recursively.
+ private bool _fIsReentrant;
+
+ // Lock specification for myLock: This lock protects exactly the local fields associated with this
+ // instance of ReaderWriterLockSlim. It does NOT protect the memory associated with
+ // the events that hang off this lock (eg writeEvent, readEvent upgradeEvent).
+ private int _myLock;
+
+ //The variables controlling spinning behavior of Mylock(which is a spin-lock)
+
+ private const int LockSpinCycles = 20;
+ private const int LockSpinCount = 10;
+ private const int LockSleep0Count = 5;
+
+ // These variables allow use to avoid Setting events (which is expensive) if we don't have to.
+ private uint _numWriteWaiters; // maximum number of threads that can be doing a WaitOne on the writeEvent
+ private uint _numReadWaiters; // maximum number of threads that can be doing a WaitOne on the readEvent
+ private uint _numWriteUpgradeWaiters; // maximum number of threads that can be doing a WaitOne on the upgradeEvent (at most 1).
+ private uint _numUpgradeWaiters;
+
+ //Variable used for quick check when there are no waiters.
+ private bool _fNoWaiters;
+
+ private int _upgradeLockOwnerId;
+ private int _writeLockOwnerId;
+
+ // conditions we wait on.
+ private EventWaitHandle _writeEvent; // threads waiting to acquire a write lock go here.
+ private EventWaitHandle _readEvent; // threads waiting to acquire a read lock go here (will be released in bulk)
+ private EventWaitHandle _upgradeEvent; // thread waiting to acquire the upgrade lock
+ private EventWaitHandle _waitUpgradeEvent; // thread waiting to upgrade from the upgrade lock to a write lock go here (at most one)
+
+ // Every lock instance has a unique ID, which is used by ReaderWriterCount to associate itself with the lock
+ // without holding a reference to it.
+ private static long s_nextLockID;
+ private long _lockID;
+
+ // See comments on ReaderWriterCount.
+ [ThreadStatic]
+ private static ReaderWriterCount t_rwc;
+
+ private bool _fUpgradeThreadHoldingRead;
+
+ private const int MaxSpinCount = 20;
+
+ //The uint, that contains info like if the writer lock is held, num of
+ //readers etc.
+ private uint _owners;
+
+ //Various R/W masks
+ //Note:
+ //The Uint is divided as follows:
+ //
+ //Writer-Owned Waiting-Writers Waiting Upgraders Num-Readers
+ // 31 30 29 28.......0
+ //
+ //Dividing the uint, allows to vastly simplify logic for checking if a
+ //reader should go in etc. Setting the writer bit will automatically
+ //make the value of the uint much larger than the max num of readers
+ //allowed, thus causing the check for max_readers to fail.
+
+ private const uint WRITER_HELD = 0x80000000;
+ private const uint WAITING_WRITERS = 0x40000000;
+ private const uint WAITING_UPGRADER = 0x20000000;
+
+ //The max readers is actually one less then its theoretical max.
+ //This is done in order to prevent reader count overflows. If the reader
+ //count reaches max, other readers will wait.
+ private const uint MAX_READER = 0x10000000 - 2;
+
+ private const uint READER_MASK = 0x10000000 - 1;
+
+ private bool _fDisposed;
+
+ private void InitializeThreadCounts()
+ {
+ _upgradeLockOwnerId = -1;
+ _writeLockOwnerId = -1;
+ }
+
+ public ReaderWriterLockSlim()
+ : this(LockRecursionPolicy.NoRecursion)
+ {
+ }
+
+ public ReaderWriterLockSlim(LockRecursionPolicy recursionPolicy)
+ {
+ if (recursionPolicy == LockRecursionPolicy.SupportsRecursion)
+ {
+ _fIsReentrant = true;
+ }
+ InitializeThreadCounts();
+ _fNoWaiters = true;
+ _lockID = Interlocked.Increment(ref s_nextLockID);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static bool IsRWEntryEmpty(ReaderWriterCount rwc)
+ {
+ if (rwc.lockID == 0)
+ return true;
+ else if (rwc.readercount == 0 && rwc.writercount == 0 && rwc.upgradecount == 0)
+ return true;
+ else
+ return false;
+ }
+
+ private bool IsRwHashEntryChanged(ReaderWriterCount lrwc)
+ {
+ return lrwc.lockID != _lockID;
+ }
+
+ /// <summary>
+ /// This routine retrieves/sets the per-thread counts needed to enforce the
+ /// various rules related to acquiring the lock.
+ ///
+ /// DontAllocate is set to true if the caller just wants to get an existing
+ /// entry for this thread, but doesn't want to add one if an existing one
+ /// could not be found.
+ /// </summary>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private ReaderWriterCount GetThreadRWCount(bool dontAllocate)
+ {
+ ReaderWriterCount rwc = t_rwc;
+ ReaderWriterCount empty = null;
+ while (rwc != null)
+ {
+ if (rwc.lockID == _lockID)
+ return rwc;
+
+ if (!dontAllocate && empty == null && IsRWEntryEmpty(rwc))
+ empty = rwc;
+
+ rwc = rwc.next;
+ }
+
+ if (dontAllocate)
+ return null;
+
+ if (empty == null)
+ {
+ empty = new ReaderWriterCount();
+ empty.next = t_rwc;
+ t_rwc = empty;
+ }
+
+ empty.lockID = _lockID;
+ return empty;
+ }
+
+ public void EnterReadLock()
+ {
+ TryEnterReadLock(-1);
+ }
+
+ //
+ // Common timeout support
+ //
+ private struct TimeoutTracker
+ {
+ private int _total;
+ private int _start;
+
+ public TimeoutTracker(TimeSpan timeout)
+ {
+ long ltm = (long)timeout.TotalMilliseconds;
+ if (ltm < -1 || ltm > (long)Int32.MaxValue)
+ throw new ArgumentOutOfRangeException(nameof(timeout));
+ _total = (int)ltm;
+ if (_total != -1 && _total != 0)
+ _start = Environment.TickCount;
+ else
+ _start = 0;
+ }
+
+ public TimeoutTracker(int millisecondsTimeout)
+ {
+ if (millisecondsTimeout < -1)
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout));
+ _total = millisecondsTimeout;
+ if (_total != -1 && _total != 0)
+ _start = Environment.TickCount;
+ else
+ _start = 0;
+ }
+
+ public int RemainingMilliseconds
+ {
+ get
+ {
+ if (_total == -1 || _total == 0)
+ return _total;
+
+ int elapsed = Environment.TickCount - _start;
+ // elapsed may be negative if TickCount has overflowed by 2^31 milliseconds.
+ if (elapsed < 0 || elapsed >= _total)
+ return 0;
+
+ return _total - elapsed;
+ }
+ }
+
+ public bool IsExpired
+ {
+ get
+ {
+ return RemainingMilliseconds == 0;
+ }
+ }
+ }
+
+ public bool TryEnterReadLock(TimeSpan timeout)
+ {
+ return TryEnterReadLock(new TimeoutTracker(timeout));
+ }
+
+ public bool TryEnterReadLock(int millisecondsTimeout)
+ {
+ return TryEnterReadLock(new TimeoutTracker(millisecondsTimeout));
+ }
+
+ private bool TryEnterReadLock(TimeoutTracker timeout)
+ {
+ return TryEnterReadLockCore(timeout);
+ }
+
+ private bool TryEnterReadLockCore(TimeoutTracker timeout)
+ {
+ if (_fDisposed)
+ throw new ObjectDisposedException(null);
+
+ ReaderWriterCount lrwc = null;
+ int id = Environment.CurrentManagedThreadId;
+
+ if (!_fIsReentrant)
+ {
+ if (id == _writeLockOwnerId)
+ {
+ //Check for AW->AR
+ throw new LockRecursionException(SR.LockRecursionException_ReadAfterWriteNotAllowed);
+ }
+
+ EnterMyLock();
+
+ lrwc = GetThreadRWCount(false);
+
+ //Check if the reader lock is already acquired. Note, we could
+ //check the presence of a reader by not allocating rwc (But that
+ //would lead to two lookups in the common case. It's better to keep
+ //a count in the structure).
+ if (lrwc.readercount > 0)
+ {
+ ExitMyLock();
+ throw new LockRecursionException(SR.LockRecursionException_RecursiveReadNotAllowed);
+ }
+ else if (id == _upgradeLockOwnerId)
+ {
+ //The upgrade lock is already held.
+ //Update the global read counts and exit.
+
+ lrwc.readercount++;
+ _owners++;
+ ExitMyLock();
+ return true;
+ }
+ }
+ else
+ {
+ EnterMyLock();
+ lrwc = GetThreadRWCount(false);
+ if (lrwc.readercount > 0)
+ {
+ lrwc.readercount++;
+ ExitMyLock();
+ return true;
+ }
+ else if (id == _upgradeLockOwnerId)
+ {
+ //The upgrade lock is already held.
+ //Update the global read counts and exit.
+ lrwc.readercount++;
+ _owners++;
+ ExitMyLock();
+ _fUpgradeThreadHoldingRead = true;
+ return true;
+ }
+ else if (id == _writeLockOwnerId)
+ {
+ //The write lock is already held.
+ //Update global read counts here,
+ lrwc.readercount++;
+ _owners++;
+ ExitMyLock();
+ return true;
+ }
+ }
+
+ bool retVal = true;
+
+ int spincount = 0;
+
+ for (; ;)
+ {
+ // We can enter a read lock if there are only read-locks have been given out
+ // and a writer is not trying to get in.
+
+ if (_owners < MAX_READER)
+ {
+ // Good case, there is no contention, we are basically done
+ _owners++; // Indicate we have another reader
+ lrwc.readercount++;
+ break;
+ }
+
+ if (spincount < MaxSpinCount)
+ {
+ ExitMyLock();
+ if (timeout.IsExpired)
+ return false;
+ spincount++;
+ SpinWait(spincount);
+ EnterMyLock();
+ //The per-thread structure may have been recycled as the lock is acquired (due to message pumping), load again.
+ if (IsRwHashEntryChanged(lrwc))
+ lrwc = GetThreadRWCount(false);
+ continue;
+ }
+
+ // Drat, we need to wait. Mark that we have waiters and wait.
+ if (_readEvent == null) // Create the needed event
+ {
+ LazyCreateEvent(ref _readEvent, false);
+ if (IsRwHashEntryChanged(lrwc))
+ lrwc = GetThreadRWCount(false);
+ continue; // since we left the lock, start over.
+ }
+
+ retVal = WaitOnEvent(_readEvent, ref _numReadWaiters, timeout, isWriteWaiter: false);
+ if (!retVal)
+ {
+ return false;
+ }
+ if (IsRwHashEntryChanged(lrwc))
+ lrwc = GetThreadRWCount(false);
+ }
+
+ ExitMyLock();
+ return retVal;
+ }
+
+ public void EnterWriteLock()
+ {
+ TryEnterWriteLock(-1);
+ }
+
+ public bool TryEnterWriteLock(TimeSpan timeout)
+ {
+ return TryEnterWriteLock(new TimeoutTracker(timeout));
+ }
+
+ public bool TryEnterWriteLock(int millisecondsTimeout)
+ {
+ return TryEnterWriteLock(new TimeoutTracker(millisecondsTimeout));
+ }
+
+ private bool TryEnterWriteLock(TimeoutTracker timeout)
+ {
+ return TryEnterWriteLockCore(timeout);
+ }
+
+ private bool TryEnterWriteLockCore(TimeoutTracker timeout)
+ {
+ if (_fDisposed)
+ throw new ObjectDisposedException(null);
+
+ int id = Environment.CurrentManagedThreadId;
+ ReaderWriterCount lrwc;
+ bool upgradingToWrite = false;
+
+ if (!_fIsReentrant)
+ {
+ if (id == _writeLockOwnerId)
+ {
+ //Check for AW->AW
+ throw new LockRecursionException(SR.LockRecursionException_RecursiveWriteNotAllowed);
+ }
+ else if (id == _upgradeLockOwnerId)
+ {
+ //AU->AW case is allowed once.
+ upgradingToWrite = true;
+ }
+
+ EnterMyLock();
+ lrwc = GetThreadRWCount(true);
+
+ //Can't acquire write lock with reader lock held.
+ if (lrwc != null && lrwc.readercount > 0)
+ {
+ ExitMyLock();
+ throw new LockRecursionException(SR.LockRecursionException_WriteAfterReadNotAllowed);
+ }
+ }
+ else
+ {
+ EnterMyLock();
+ lrwc = GetThreadRWCount(false);
+
+ if (id == _writeLockOwnerId)
+ {
+ lrwc.writercount++;
+ ExitMyLock();
+ return true;
+ }
+ else if (id == _upgradeLockOwnerId)
+ {
+ upgradingToWrite = true;
+ }
+ else if (lrwc.readercount > 0)
+ {
+ //Write locks may not be acquired if only read locks have been
+ //acquired.
+ ExitMyLock();
+ throw new LockRecursionException(SR.LockRecursionException_WriteAfterReadNotAllowed);
+ }
+ }
+
+ int spincount = 0;
+ bool retVal = true;
+
+ for (; ;)
+ {
+ if (IsWriterAcquired())
+ {
+ // Good case, there is no contention, we are basically done
+ SetWriterAcquired();
+ break;
+ }
+
+ //Check if there is just one upgrader, and no readers.
+ //Assumption: Only one thread can have the upgrade lock, so the
+ //following check will fail for all other threads that may sneak in
+ //when the upgrading thread is waiting.
+
+ if (upgradingToWrite)
+ {
+ uint readercount = GetNumReaders();
+
+ if (readercount == 1)
+ {
+ //Good case again, there is just one upgrader, and no readers.
+ SetWriterAcquired(); // indicate we have a writer.
+ break;
+ }
+ else if (readercount == 2)
+ {
+ if (lrwc != null)
+ {
+ if (IsRwHashEntryChanged(lrwc))
+ lrwc = GetThreadRWCount(false);
+
+ if (lrwc.readercount > 0)
+ {
+ //This check is needed for EU->ER->EW case, as the owner count will be two.
+ Debug.Assert(_fIsReentrant);
+ Debug.Assert(_fUpgradeThreadHoldingRead);
+
+ //Good case again, there is just one upgrader, and no readers.
+ SetWriterAcquired(); // indicate we have a writer.
+ break;
+ }
+ }
+ }
+ }
+
+ if (spincount < MaxSpinCount)
+ {
+ ExitMyLock();
+ if (timeout.IsExpired)
+ return false;
+ spincount++;
+ SpinWait(spincount);
+ EnterMyLock();
+ continue;
+ }
+
+ if (upgradingToWrite)
+ {
+ if (_waitUpgradeEvent == null) // Create the needed event
+ {
+ LazyCreateEvent(ref _waitUpgradeEvent, true);
+ continue; // since we left the lock, start over.
+ }
+
+ Debug.Assert(_numWriteUpgradeWaiters == 0, "There can be at most one thread with the upgrade lock held.");
+
+ retVal = WaitOnEvent(_waitUpgradeEvent, ref _numWriteUpgradeWaiters, timeout, isWriteWaiter: true);
+
+ //The lock is not held in case of failure.
+ if (!retVal)
+ return false;
+ }
+ else
+ {
+ // Drat, we need to wait. Mark that we have waiters and wait.
+ if (_writeEvent == null) // create the needed event.
+ {
+ LazyCreateEvent(ref _writeEvent, true);
+ continue; // since we left the lock, start over.
+ }
+
+ retVal = WaitOnEvent(_writeEvent, ref _numWriteWaiters, timeout, isWriteWaiter: true);
+ //The lock is not held in case of failure.
+ if (!retVal)
+ return false;
+ }
+ }
+
+ Debug.Assert((_owners & WRITER_HELD) > 0);
+
+ if (_fIsReentrant)
+ {
+ if (IsRwHashEntryChanged(lrwc))
+ lrwc = GetThreadRWCount(false);
+ lrwc.writercount++;
+ }
+
+ ExitMyLock();
+
+ _writeLockOwnerId = id;
+
+ return true;
+ }
+
+ public void EnterUpgradeableReadLock()
+ {
+ TryEnterUpgradeableReadLock(-1);
+ }
+
+ public bool TryEnterUpgradeableReadLock(TimeSpan timeout)
+ {
+ return TryEnterUpgradeableReadLock(new TimeoutTracker(timeout));
+ }
+
+ public bool TryEnterUpgradeableReadLock(int millisecondsTimeout)
+ {
+ return TryEnterUpgradeableReadLock(new TimeoutTracker(millisecondsTimeout));
+ }
+
+ private bool TryEnterUpgradeableReadLock(TimeoutTracker timeout)
+ {
+ return TryEnterUpgradeableReadLockCore(timeout);
+ }
+
+ private bool TryEnterUpgradeableReadLockCore(TimeoutTracker timeout)
+ {
+ if (_fDisposed)
+ throw new ObjectDisposedException(null);
+
+ int id = Environment.CurrentManagedThreadId;
+ ReaderWriterCount lrwc;
+
+ if (!_fIsReentrant)
+ {
+ if (id == _upgradeLockOwnerId)
+ {
+ //Check for AU->AU
+ throw new LockRecursionException(SR.LockRecursionException_RecursiveUpgradeNotAllowed);
+ }
+ else if (id == _writeLockOwnerId)
+ {
+ //Check for AU->AW
+ throw new LockRecursionException(SR.LockRecursionException_UpgradeAfterWriteNotAllowed);
+ }
+
+ EnterMyLock();
+ lrwc = GetThreadRWCount(true);
+ //Can't acquire upgrade lock with reader lock held.
+ if (lrwc != null && lrwc.readercount > 0)
+ {
+ ExitMyLock();
+ throw new LockRecursionException(SR.LockRecursionException_UpgradeAfterReadNotAllowed);
+ }
+ }
+ else
+ {
+ EnterMyLock();
+ lrwc = GetThreadRWCount(false);
+
+ if (id == _upgradeLockOwnerId)
+ {
+ lrwc.upgradecount++;
+ ExitMyLock();
+ return true;
+ }
+ else if (id == _writeLockOwnerId)
+ {
+ //Write lock is already held, Just update the global state
+ //to show presence of upgrader.
+ Debug.Assert((_owners & WRITER_HELD) > 0);
+ _owners++;
+ _upgradeLockOwnerId = id;
+ lrwc.upgradecount++;
+ if (lrwc.readercount > 0)
+ _fUpgradeThreadHoldingRead = true;
+ ExitMyLock();
+ return true;
+ }
+ else if (lrwc.readercount > 0)
+ {
+ //Upgrade locks may not be acquired if only read locks have been
+ //acquired.
+ ExitMyLock();
+ throw new LockRecursionException(SR.LockRecursionException_UpgradeAfterReadNotAllowed);
+ }
+ }
+
+ bool retVal = true;
+
+ int spincount = 0;
+
+ for (; ;)
+ {
+ //Once an upgrade lock is taken, it's like having a reader lock held
+ //until upgrade or downgrade operations are performed.
+
+ if ((_upgradeLockOwnerId == -1) && (_owners < MAX_READER))
+ {
+ _owners++;
+ _upgradeLockOwnerId = id;
+ break;
+ }
+
+ if (spincount < MaxSpinCount)
+ {
+ ExitMyLock();
+ if (timeout.IsExpired)
+ return false;
+ spincount++;
+ SpinWait(spincount);
+ EnterMyLock();
+ continue;
+ }
+
+ // Drat, we need to wait. Mark that we have waiters and wait.
+ if (_upgradeEvent == null) // Create the needed event
+ {
+ LazyCreateEvent(ref _upgradeEvent, true);
+ continue; // since we left the lock, start over.
+ }
+
+ //Only one thread with the upgrade lock held can proceed.
+ retVal = WaitOnEvent(_upgradeEvent, ref _numUpgradeWaiters, timeout, isWriteWaiter: false);
+ if (!retVal)
+ return false;
+ }
+
+ if (_fIsReentrant)
+ {
+ //The lock may have been dropped getting here, so make a quick check to see whether some other
+ //thread did not grab the entry.
+ if (IsRwHashEntryChanged(lrwc))
+ lrwc = GetThreadRWCount(false);
+ lrwc.upgradecount++;
+ }
+
+ ExitMyLock();
+
+ return true;
+ }
+
+ public void ExitReadLock()
+ {
+ ReaderWriterCount lrwc = null;
+
+ EnterMyLock();
+
+ lrwc = GetThreadRWCount(true);
+
+ if (lrwc == null || lrwc.readercount < 1)
+ {
+ //You have to be holding the read lock to make this call.
+ ExitMyLock();
+ throw new SynchronizationLockException(SR.SynchronizationLockException_MisMatchedRead);
+ }
+
+ if (_fIsReentrant)
+ {
+ if (lrwc.readercount > 1)
+ {
+ lrwc.readercount--;
+ ExitMyLock();
+ return;
+ }
+
+ if (Environment.CurrentManagedThreadId == _upgradeLockOwnerId)
+ {
+ _fUpgradeThreadHoldingRead = false;
+ }
+ }
+
+ Debug.Assert(_owners > 0, "ReleasingReaderLock: releasing lock and no read lock taken");
+
+ --_owners;
+
+ Debug.Assert(lrwc.readercount == 1);
+ lrwc.readercount--;
+
+ ExitAndWakeUpAppropriateWaiters();
+ }
+
+ public void ExitWriteLock()
+ {
+ ReaderWriterCount lrwc;
+ if (!_fIsReentrant)
+ {
+ if (Environment.CurrentManagedThreadId != _writeLockOwnerId)
+ {
+ //You have to be holding the write lock to make this call.
+ throw new SynchronizationLockException(SR.SynchronizationLockException_MisMatchedWrite);
+ }
+ EnterMyLock();
+ }
+ else
+ {
+ EnterMyLock();
+ lrwc = GetThreadRWCount(false);
+
+ if (lrwc == null)
+ {
+ ExitMyLock();
+ throw new SynchronizationLockException(SR.SynchronizationLockException_MisMatchedWrite);
+ }
+
+ if (lrwc.writercount < 1)
+ {
+ ExitMyLock();
+ throw new SynchronizationLockException(SR.SynchronizationLockException_MisMatchedWrite);
+ }
+
+ lrwc.writercount--;
+
+ if (lrwc.writercount > 0)
+ {
+ ExitMyLock();
+ return;
+ }
+ }
+
+ Debug.Assert((_owners & WRITER_HELD) > 0, "Calling ReleaseWriterLock when no write lock is held");
+
+ ClearWriterAcquired();
+
+ _writeLockOwnerId = -1;
+
+ ExitAndWakeUpAppropriateWaiters();
+ }
+
+ public void ExitUpgradeableReadLock()
+ {
+ ReaderWriterCount lrwc;
+ if (!_fIsReentrant)
+ {
+ if (Environment.CurrentManagedThreadId != _upgradeLockOwnerId)
+ {
+ //You have to be holding the upgrade lock to make this call.
+ throw new SynchronizationLockException(SR.SynchronizationLockException_MisMatchedUpgrade);
+ }
+ EnterMyLock();
+ }
+ else
+ {
+ EnterMyLock();
+ lrwc = GetThreadRWCount(true);
+
+ if (lrwc == null)
+ {
+ ExitMyLock();
+ throw new SynchronizationLockException(SR.SynchronizationLockException_MisMatchedUpgrade);
+ }
+
+ if (lrwc.upgradecount < 1)
+ {
+ ExitMyLock();
+ throw new SynchronizationLockException(SR.SynchronizationLockException_MisMatchedUpgrade);
+ }
+
+ lrwc.upgradecount--;
+
+ if (lrwc.upgradecount > 0)
+ {
+ ExitMyLock();
+ return;
+ }
+
+ _fUpgradeThreadHoldingRead = false;
+ }
+
+ _owners--;
+ _upgradeLockOwnerId = -1;
+
+ ExitAndWakeUpAppropriateWaiters();
+ }
+
+ /// <summary>
+ /// A routine for lazily creating a event outside the lock (so if errors
+ /// happen they are outside the lock and that we don't do much work
+ /// while holding a spin lock). If all goes well, reenter the lock and
+ /// set 'waitEvent'
+ /// </summary>
+ private void LazyCreateEvent(ref EventWaitHandle waitEvent, bool makeAutoResetEvent)
+ {
+#if DEBUG
+ Debug.Assert(MyLockHeld);
+ Debug.Assert(waitEvent == null);
+#endif
+ ExitMyLock();
+ EventWaitHandle newEvent;
+ if (makeAutoResetEvent)
+ newEvent = new AutoResetEvent(false);
+ else
+ newEvent = new ManualResetEvent(false);
+ EnterMyLock();
+ if (waitEvent == null) // maybe someone snuck in.
+ waitEvent = newEvent;
+ else
+ newEvent.Dispose();
+ }
+
+ /// <summary>
+ /// Waits on 'waitEvent' with a timeout
+ /// Before the wait 'numWaiters' is incremented and is restored before leaving this routine.
+ /// </summary>
+ private bool WaitOnEvent(
+ EventWaitHandle waitEvent,
+ ref uint numWaiters,
+ TimeoutTracker timeout,
+ bool isWriteWaiter)
+ {
+#if DEBUG
+ Debug.Assert(MyLockHeld);
+#endif
+ waitEvent.Reset();
+ numWaiters++;
+ _fNoWaiters = false;
+
+ //Setting these bits will prevent new readers from getting in.
+ if (_numWriteWaiters == 1)
+ SetWritersWaiting();
+ if (_numWriteUpgradeWaiters == 1)
+ SetUpgraderWaiting();
+
+ bool waitSuccessful = false;
+ ExitMyLock(); // Do the wait outside of any lock
+
+ try
+ {
+ waitSuccessful = waitEvent.WaitOne(timeout.RemainingMilliseconds);
+ }
+ finally
+ {
+ EnterMyLock();
+ --numWaiters;
+
+ if (_numWriteWaiters == 0 && _numWriteUpgradeWaiters == 0 && _numUpgradeWaiters == 0 && _numReadWaiters == 0)
+ _fNoWaiters = true;
+
+ if (_numWriteWaiters == 0)
+ ClearWritersWaiting();
+ if (_numWriteUpgradeWaiters == 0)
+ ClearUpgraderWaiting();
+
+ if (!waitSuccessful) // We may also be about to throw for some reason. Exit myLock.
+ {
+ if (isWriteWaiter)
+ {
+ // Write waiters block read waiters from acquiring the lock. Since this was the last write waiter, try
+ // to wake up the appropriate read waiters.
+ ExitAndWakeUpAppropriateReadWaiters();
+ }
+ else
+ ExitMyLock();
+ }
+ }
+ return waitSuccessful;
+ }
+
+ /// <summary>
+ /// Determines the appropriate events to set, leaves the locks, and sets the events.
+ /// </summary>
+ private void ExitAndWakeUpAppropriateWaiters()
+ {
+#if DEBUG
+ Debug.Assert(MyLockHeld);
+#endif
+ if (_fNoWaiters)
+ {
+ ExitMyLock();
+ return;
+ }
+
+ ExitAndWakeUpAppropriateWaitersPreferringWriters();
+ }
+
+ private void ExitAndWakeUpAppropriateWaitersPreferringWriters()
+ {
+ uint readercount = GetNumReaders();
+
+ //We need this case for EU->ER->EW case, as the read count will be 2 in
+ //that scenario.
+ if (_fIsReentrant)
+ {
+ if (_numWriteUpgradeWaiters > 0 && _fUpgradeThreadHoldingRead && readercount == 2)
+ {
+ ExitMyLock(); // Exit before signaling to improve efficiency (wakee will need the lock)
+ _waitUpgradeEvent.Set(); // release all upgraders (however there can be at most one).
+ return;
+ }
+ }
+
+ if (readercount == 1 && _numWriteUpgradeWaiters > 0)
+ {
+ //We have to be careful now, as we are dropping the lock.
+ //No new writes should be allowed to sneak in if an upgrade
+ //was pending.
+
+ ExitMyLock(); // Exit before signaling to improve efficiency (wakee will need the lock)
+ _waitUpgradeEvent.Set(); // release all upgraders (however there can be at most one).
+ }
+ else if (readercount == 0 && _numWriteWaiters > 0)
+ {
+ ExitMyLock(); // Exit before signaling to improve efficiency (wakee will need the lock)
+ _writeEvent.Set(); // release one writer.
+ }
+ else
+ {
+ ExitAndWakeUpAppropriateReadWaiters();
+ }
+ }
+
+ private void ExitAndWakeUpAppropriateReadWaiters()
+ {
+#if DEBUG
+ Debug.Assert(MyLockHeld);
+#endif
+
+ if (_numWriteWaiters != 0 || _numWriteUpgradeWaiters != 0 || _fNoWaiters)
+ {
+ ExitMyLock();
+ return;
+ }
+
+ Debug.Assert(_numReadWaiters != 0 || _numUpgradeWaiters != 0);
+
+ bool setReadEvent = _numReadWaiters != 0;
+ bool setUpgradeEvent = _numUpgradeWaiters != 0 && _upgradeLockOwnerId == -1;
+
+ ExitMyLock(); // Exit before signaling to improve efficiency (wakee will need the lock)
+
+ if (setReadEvent)
+ _readEvent.Set(); // release all readers.
+
+ if (setUpgradeEvent)
+ _upgradeEvent.Set(); //release one upgrader.
+ }
+
+ private bool IsWriterAcquired()
+ {
+ return (_owners & ~WAITING_WRITERS) == 0;
+ }
+
+ private void SetWriterAcquired()
+ {
+ _owners |= WRITER_HELD; // indicate we have a writer.
+ }
+
+ private void ClearWriterAcquired()
+ {
+ _owners &= ~WRITER_HELD;
+ }
+
+ private void SetWritersWaiting()
+ {
+ _owners |= WAITING_WRITERS;
+ }
+
+ private void ClearWritersWaiting()
+ {
+ _owners &= ~WAITING_WRITERS;
+ }
+
+ private void SetUpgraderWaiting()
+ {
+ _owners |= WAITING_UPGRADER;
+ }
+
+ private void ClearUpgraderWaiting()
+ {
+ _owners &= ~WAITING_UPGRADER;
+ }
+
+ private uint GetNumReaders()
+ {
+ return _owners & READER_MASK;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void EnterMyLock()
+ {
+ if (Interlocked.CompareExchange(ref _myLock, 1, 0) != 0)
+ EnterMyLockSpin();
+ }
+
+ private void EnterMyLockSpin()
+ {
+ int pc = Environment.ProcessorCount;
+ for (int i = 0; ; i++)
+ {
+ if (i < LockSpinCount && pc > 1)
+ {
+ RuntimeThread.SpinWait(LockSpinCycles * (i + 1)); // Wait a few dozen instructions to let another processor release lock.
+ }
+ else if (i < (LockSpinCount + LockSleep0Count))
+ {
+ RuntimeThread.Sleep(0); // Give up my quantum.
+ }
+ else
+ {
+ RuntimeThread.Sleep(1); // Give up my quantum.
+ }
+
+ if (_myLock == 0 && Interlocked.CompareExchange(ref _myLock, 1, 0) == 0)
+ return;
+ }
+ }
+
+ private void ExitMyLock()
+ {
+ Debug.Assert(_myLock != 0, "Exiting spin lock that is not held");
+ Volatile.Write(ref _myLock, 0);
+ }
+
+#if DEBUG
+ private bool MyLockHeld { get { return _myLock != 0; } }
+#endif
+
+ private static void SpinWait(int SpinCount)
+ {
+ //Exponential back-off
+ if ((SpinCount < 5) && (Environment.ProcessorCount > 1))
+ {
+ RuntimeThread.SpinWait(LockSpinCycles * SpinCount);
+ }
+ else
+ {
+ RuntimeThread.Sleep(0);
+ }
+
+ // Don't want to Sleep(1) in this spin wait:
+ // - Don't want to spin for that long, since a proper wait will follow when the spin wait fails. The artifical
+ // delay introduced by Sleep(1) will in some cases be much longer than desired.
+ // - Sleep(1) would put the thread into a wait state, and a proper wait will follow when the spin wait fails
+ // anyway, so it's preferable to put the thread into the proper wait state
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposing && !_fDisposed)
+ {
+ if (WaitingReadCount > 0 || WaitingUpgradeCount > 0 || WaitingWriteCount > 0)
+ throw new SynchronizationLockException(SR.SynchronizationLockException_IncorrectDispose);
+
+ if (IsReadLockHeld || IsUpgradeableReadLockHeld || IsWriteLockHeld)
+ throw new SynchronizationLockException(SR.SynchronizationLockException_IncorrectDispose);
+
+ if (_writeEvent != null)
+ {
+ _writeEvent.Dispose();
+ _writeEvent = null;
+ }
+
+ if (_readEvent != null)
+ {
+ _readEvent.Dispose();
+ _readEvent = null;
+ }
+
+ if (_upgradeEvent != null)
+ {
+ _upgradeEvent.Dispose();
+ _upgradeEvent = null;
+ }
+
+ if (_waitUpgradeEvent != null)
+ {
+ _waitUpgradeEvent.Dispose();
+ _waitUpgradeEvent = null;
+ }
+
+ _fDisposed = true;
+ }
+ }
+
+ public bool IsReadLockHeld
+ {
+ get
+ {
+ if (RecursiveReadCount > 0)
+ return true;
+ else
+ return false;
+ }
+ }
+
+ public bool IsUpgradeableReadLockHeld
+ {
+ get
+ {
+ if (RecursiveUpgradeCount > 0)
+ return true;
+ else
+ return false;
+ }
+ }
+
+ public bool IsWriteLockHeld
+ {
+ get
+ {
+ if (RecursiveWriteCount > 0)
+ return true;
+ else
+ return false;
+ }
+ }
+
+ public LockRecursionPolicy RecursionPolicy
+ {
+ get
+ {
+ if (_fIsReentrant)
+ {
+ return LockRecursionPolicy.SupportsRecursion;
+ }
+ else
+ {
+ return LockRecursionPolicy.NoRecursion;
+ }
+ }
+ }
+
+ public int CurrentReadCount
+ {
+ get
+ {
+ int numreaders = (int)GetNumReaders();
+
+ if (_upgradeLockOwnerId != -1)
+ return numreaders - 1;
+ else
+ return numreaders;
+ }
+ }
+
+
+ public int RecursiveReadCount
+ {
+ get
+ {
+ int count = 0;
+ ReaderWriterCount lrwc = GetThreadRWCount(true);
+ if (lrwc != null)
+ count = lrwc.readercount;
+
+ return count;
+ }
+ }
+
+ public int RecursiveUpgradeCount
+ {
+ get
+ {
+ if (_fIsReentrant)
+ {
+ int count = 0;
+
+ ReaderWriterCount lrwc = GetThreadRWCount(true);
+ if (lrwc != null)
+ count = lrwc.upgradecount;
+
+ return count;
+ }
+ else
+ {
+ if (Environment.CurrentManagedThreadId == _upgradeLockOwnerId)
+ return 1;
+ else
+ return 0;
+ }
+ }
+ }
+
+ public int RecursiveWriteCount
+ {
+ get
+ {
+ if (_fIsReentrant)
+ {
+ int count = 0;
+
+ ReaderWriterCount lrwc = GetThreadRWCount(true);
+ if (lrwc != null)
+ count = lrwc.writercount;
+
+ return count;
+ }
+ else
+ {
+ if (Environment.CurrentManagedThreadId == _writeLockOwnerId)
+ return 1;
+ else
+ return 0;
+ }
+ }
+ }
+
+ public int WaitingReadCount
+ {
+ get
+ {
+ return (int)_numReadWaiters;
+ }
+ }
+
+ public int WaitingUpgradeCount
+ {
+ get
+ {
+ return (int)_numUpgradeWaiters;
+ }
+ }
+
+ public int WaitingWriteCount
+ {
+ get
+ {
+ return (int)_numWriteWaiters;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Threading/Semaphore.cs b/src/mscorlib/src/System/Threading/Semaphore.cs
index 1eac4aaaeb..ae353cc3e3 100644
--- a/src/mscorlib/src/System/Threading/Semaphore.cs
+++ b/src/mscorlib/src/System/Threading/Semaphore.cs
@@ -20,17 +20,17 @@ namespace System.Threading
{
if (initialCount < 0)
{
- throw new ArgumentOutOfRangeException(nameof(initialCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(initialCount), SR.ArgumentOutOfRange_NeedNonNegNum);
}
if (maximumCount < 1)
{
- throw new ArgumentOutOfRangeException(nameof(maximumCount), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
+ throw new ArgumentOutOfRangeException(nameof(maximumCount), SR.ArgumentOutOfRange_NeedPosNum);
}
if (initialCount > maximumCount)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_SemaphoreInitialMaximum"));
+ throw new ArgumentException(SR.Argument_SemaphoreInitialMaximum);
}
SafeWaitHandle myHandle = CreateSemaphone(initialCount, maximumCount, name);
@@ -41,7 +41,7 @@ namespace System.Threading
if (null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
throw new WaitHandleCannotBeOpenedException(
- Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", name));
+ SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
__Error.WinIOError();
}
@@ -52,17 +52,17 @@ namespace System.Threading
{
if (initialCount < 0)
{
- throw new ArgumentOutOfRangeException(nameof(initialCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(initialCount), SR.ArgumentOutOfRange_NeedNonNegNum);
}
if (maximumCount < 1)
{
- throw new ArgumentOutOfRangeException(nameof(maximumCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(maximumCount), SR.ArgumentOutOfRange_NeedNonNegNum);
}
if (initialCount > maximumCount)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_SemaphoreInitialMaximum"));
+ throw new ArgumentException(SR.Argument_SemaphoreInitialMaximum);
}
SafeWaitHandle myHandle = CreateSemaphone(initialCount, maximumCount, name);
@@ -72,7 +72,7 @@ namespace System.Threading
{
if (null != name && 0 != name.Length && Win32Native.ERROR_INVALID_HANDLE == errorCode)
throw new WaitHandleCannotBeOpenedException(
- Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", name));
+ SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
__Error.WinIOError();
}
createdNew = errorCode != Win32Native.ERROR_ALREADY_EXISTS;
@@ -89,10 +89,10 @@ namespace System.Threading
if (name != null)
{
#if PLATFORM_UNIX
- throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_NamedSynchronizationPrimitives"));
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives);
#else
if (name.Length > Path.MaxPath)
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name));
+ throw new ArgumentException(SR.Format(SR.Argument_WaitHandleNameTooLong, Path.MaxPath), nameof(name));
#endif
}
@@ -111,7 +111,7 @@ namespace System.Threading
case OpenExistingResult.NameNotFound:
throw new WaitHandleCannotBeOpenedException();
case OpenExistingResult.NameInvalid:
- throw new WaitHandleCannotBeOpenedException(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException_InvalidHandle", name));
+ throw new WaitHandleCannotBeOpenedException(SR.Format(SR.Threading_WaitHandleCannotBeOpenedException_InvalidHandle, name));
case OpenExistingResult.PathNotFound:
throw new IOException(Win32Native.GetMessage(Win32Native.ERROR_PATH_NOT_FOUND));
default:
@@ -127,14 +127,14 @@ namespace System.Threading
private static OpenExistingResult OpenExistingWorker(string name, out Semaphore result)
{
#if PLATFORM_UNIX
- throw new PlatformNotSupportedException(Environment.GetResourceString("PlatformNotSupported_NamedSynchronizationPrimitives"));
+ throw new PlatformNotSupportedException(SR.PlatformNotSupported_NamedSynchronizationPrimitives);
#else
if (name == null)
- throw new ArgumentNullException(nameof(name), Environment.GetResourceString("ArgumentNull_WithParamName"));
+ throw new ArgumentNullException(nameof(name), SR.ArgumentNull_WithParamName);
if (name.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), nameof(name));
+ throw new ArgumentException(SR.Argument_EmptyName, nameof(name));
if (name.Length > Path.MaxPath)
- throw new ArgumentException(Environment.GetResourceString("Argument_WaitHandleNameTooLong", Path.MaxPath), nameof(name));
+ throw new ArgumentException(SR.Format(SR.Argument_WaitHandleNameTooLong, Path.MaxPath), nameof(name));
const int SYNCHRONIZE = 0x00100000;
const int SEMAPHORE_MODIFY_STATE = 0x00000002;
@@ -173,7 +173,7 @@ namespace System.Threading
{
if (releaseCount < 1)
{
- throw new ArgumentOutOfRangeException(nameof(releaseCount), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(releaseCount), SR.ArgumentOutOfRange_NeedNonNegNum);
}
//If ReleaseSempahore returns false when the specified value would cause
diff --git a/src/mscorlib/src/System/Threading/SemaphoreFullException.cs b/src/mscorlib/src/System/Threading/SemaphoreFullException.cs
deleted file mode 100644
index 01c5040b7e..0000000000
--- a/src/mscorlib/src/System/Threading/SemaphoreFullException.cs
+++ /dev/null
@@ -1,27 +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.
-
-namespace System.Threading {
- using System;
- using System.Runtime.Serialization;
- using System.Runtime.InteropServices;
-
- [Serializable]
- [ComVisibleAttribute(false)]
- public class SemaphoreFullException : SystemException {
-
- public SemaphoreFullException() : base(Environment.GetResourceString("Threading_SemaphoreFullException")){
- }
-
- public SemaphoreFullException(String message) : base(message) {
- }
-
- public SemaphoreFullException(String message, Exception innerException) : base(message, innerException) {
- }
-
- protected SemaphoreFullException(SerializationInfo info, StreamingContext context) : base (info, context) {
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/Threading/SemaphoreSlim.cs b/src/mscorlib/src/System/Threading/SemaphoreSlim.cs
index c3b43d9585..97bbae18cc 100644
--- a/src/mscorlib/src/System/Threading/SemaphoreSlim.cs
+++ b/src/mscorlib/src/System/Threading/SemaphoreSlim.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// 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.
@@ -21,6 +21,7 @@ using System.Diagnostics.Contracts;
using System.Threading.Tasks;
// The class will be part of the current System.Threading namespace
+
namespace System.Threading
{
/// <summary>
@@ -84,7 +85,7 @@ namespace System.Threading
private sealed class TaskNode : Task<bool>, IThreadPoolWorkItem
{
internal TaskNode Prev, Next;
- internal TaskNode() : base() {}
+ internal TaskNode() : base() { }
void IThreadPoolWorkItem.ExecuteWorkItem()
{
@@ -177,13 +178,13 @@ namespace System.Threading
if (initialCount < 0 || initialCount > maxCount)
{
throw new ArgumentOutOfRangeException(
- nameof(initialCount), initialCount, GetResourceString("SemaphoreSlim_ctor_InitialCountWrong"));
+ nameof(initialCount), initialCount, SR.SemaphoreSlim_ctor_InitialCountWrong);
}
//validate input
if (maxCount <= 0)
{
- throw new ArgumentOutOfRangeException(nameof(maxCount), maxCount, GetResourceString("SemaphoreSlim_ctor_MaxCountWrong"));
+ throw new ArgumentOutOfRangeException(nameof(maxCount), maxCount, SR.SemaphoreSlim_ctor_MaxCountWrong);
}
m_maxCount = maxCount;
@@ -240,7 +241,7 @@ namespace System.Threading
if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue)
{
throw new System.ArgumentOutOfRangeException(
- nameof(timeout), timeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong"));
+ nameof(timeout), timeout, SR.SemaphoreSlim_Wait_TimeoutWrong);
}
// Call wait with the timeout milliseconds
@@ -270,7 +271,7 @@ namespace System.Threading
if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue)
{
throw new System.ArgumentOutOfRangeException(
- nameof(timeout), timeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong"));
+ nameof(timeout), timeout, SR.SemaphoreSlim_Wait_TimeoutWrong);
}
// Call wait with the timeout milliseconds
@@ -313,7 +314,7 @@ namespace System.Threading
if (millisecondsTimeout < -1)
{
throw new ArgumentOutOfRangeException(
- nameof(millisecondsTimeout), millisecondsTimeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong"));
+ nameof(millisecondsTimeout), millisecondsTimeout, SR.SemaphoreSlim_Wait_TimeoutWrong);
}
cancellationToken.ThrowIfCancellationRequested();
@@ -370,7 +371,7 @@ namespace System.Threading
Debug.Assert(m_asyncTail != null, "tail should not be null if head isn't");
asyncWaitTask = WaitAsync(millisecondsTimeout, cancellationToken);
}
- // There are no async waiters, so we can proceed with normal synchronous waiting.
+ // There are no async waiters, so we can proceed with normal synchronous waiting.
else
{
// If the count > 0 we are good to move on.
@@ -399,7 +400,7 @@ namespace System.Threading
// defer to synchronous waiters in priority, which means that if it's possible an asynchronous
// waiter didn't get released because a synchronous waiter was present, we need to ensure
// that synchronous waiter succeeds so that they have a chance to release.
- Debug.Assert(!waitSuccessful || m_currentCount > 0,
+ Debug.Assert(!waitSuccessful || m_currentCount > 0,
"If the wait was successful, there should be count available.");
if (m_currentCount > 0)
{
@@ -574,7 +575,7 @@ namespace System.Threading
if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue)
{
throw new System.ArgumentOutOfRangeException(
- nameof(timeout), timeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong"));
+ nameof(timeout), timeout, SR.SemaphoreSlim_Wait_TimeoutWrong);
}
// Call wait with the timeout milliseconds
@@ -607,7 +608,7 @@ namespace System.Threading
if (millisecondsTimeout < -1)
{
throw new ArgumentOutOfRangeException(
- nameof(millisecondsTimeout), millisecondsTimeout, GetResourceString("SemaphoreSlim_Wait_TimeoutWrong"));
+ nameof(millisecondsTimeout), millisecondsTimeout, SR.SemaphoreSlim_Wait_TimeoutWrong);
}
// Bail early for cancellation
@@ -628,9 +629,9 @@ namespace System.Threading
// No counts, if timeout is zero fail fast
return s_falseTask;
}
- // If there aren't, create and return a task to the caller.
- // The task will be completed either when they've successfully acquired
- // the semaphore or when the timeout expired or cancellation was requested.
+ // If there aren't, create and return a task to the caller.
+ // The task will be completed either when they've successfully acquired
+ // the semaphore or when the timeout expired or cancellation was requested.
else
{
Debug.Assert(m_currentCount == 0, "m_currentCount should never be negative");
@@ -771,7 +772,7 @@ namespace System.Threading
if (releaseCount < 1)
{
throw new ArgumentOutOfRangeException(
- nameof(releaseCount), releaseCount, GetResourceString("SemaphoreSlim_Release_CountWrong"));
+ nameof(releaseCount), releaseCount, SR.SemaphoreSlim_Release_CountWrong);
}
int returnCount;
@@ -882,7 +883,7 @@ namespace System.Threading
}
-
+
/// <summary>
/// Private helper method to wake up waiters when a cancellationToken gets canceled.
/// </summary>
@@ -905,7 +906,7 @@ namespace System.Threading
{
if (m_lockObj == null)
{
- throw new ObjectDisposedException(null, GetResourceString("SemaphoreSlim_Disposed"));
+ throw new ObjectDisposedException(null, SR.SemaphoreSlim_Disposed);
}
}
@@ -915,7 +916,7 @@ namespace System.Threading
/// <param name="str">The key string</param>
private static string GetResourceString(string str)
{
- return Environment.GetResourceString(str);
+ return SR.GetResourceString(str);
}
#endregion
}
diff --git a/src/mscorlib/src/System/Threading/SendOrPostCallback.cs b/src/mscorlib/src/System/Threading/SendOrPostCallback.cs
deleted file mode 100644
index b81d2bff64..0000000000
--- a/src/mscorlib/src/System/Threading/SendOrPostCallback.cs
+++ /dev/null
@@ -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.
-/*============================================================
-**
-**
-**
-** Purpose: Represents a method to be called when a message is to be dispatched to a synchronization context.
-**
-**
-===========================================================*/
-
-namespace System.Threading
-{
- public delegate void SendOrPostCallback(Object state);
-}
diff --git a/src/mscorlib/src/System/Threading/SpinWait.cs b/src/mscorlib/src/System/Threading/SpinWait.cs
index 8431f6564f..30d7aa679c 100644
--- a/src/mscorlib/src/System/Threading/SpinWait.cs
+++ b/src/mscorlib/src/System/Threading/SpinWait.cs
@@ -51,7 +51,7 @@ namespace System.Threading
/// <remarks>
/// <para>
/// <see cref="SpinWait"/> encapsulates common spinning logic. On single-processor machines, yields are
- /// always used instead of busy waits, and on computers with Intel™ processors employing Hyper-Threading™
+ /// always used instead of busy waits, and on computers with Intel processors employing Hyper-Threading
/// technology, it helps to prevent hardware thread starvation. SpinWait encapsulates a good mixture of
/// spinning and true yielding.
/// </para>
@@ -71,7 +71,6 @@ namespace System.Threading
/// </remarks>
public struct SpinWait
{
-
// These constants determine the frequency of yields versus spinning. The
// numbers may seem fairly arbitrary, but were derived with at least some
// thought in the design document. I fully expect they will need to change
@@ -188,7 +187,7 @@ namespace System.Threading
public static void SpinUntil(Func<bool> condition)
{
#if DEBUG
- bool result =
+ bool result =
#endif
SpinUntil(condition, Timeout.Infinite);
#if DEBUG
@@ -215,7 +214,7 @@ namespace System.Threading
if (totalMilliseconds < -1 || totalMilliseconds > Int32.MaxValue)
{
throw new System.ArgumentOutOfRangeException(
- nameof(timeout), timeout, Environment.GetResourceString("SpinWait_SpinUntil_TimeoutWrong"));
+ nameof(timeout), timeout, SR.SpinWait_SpinUntil_TimeoutWrong);
}
// Call wait with the timeout milliseconds
@@ -237,11 +236,11 @@ namespace System.Threading
if (millisecondsTimeout < Timeout.Infinite)
{
throw new ArgumentOutOfRangeException(
- nameof(millisecondsTimeout), millisecondsTimeout, Environment.GetResourceString("SpinWait_SpinUntil_TimeoutWrong"));
+ nameof(millisecondsTimeout), millisecondsTimeout, SR.SpinWait_SpinUntil_TimeoutWrong);
}
if (condition == null)
{
- throw new ArgumentNullException(nameof(condition), Environment.GetResourceString("SpinWait_SpinUntil_ArgumentNull"));
+ throw new ArgumentNullException(nameof(condition), SR.SpinWait_SpinUntil_ArgumentNull);
}
uint startTime = 0;
if (millisecondsTimeout != 0 && millisecondsTimeout != Timeout.Infinite)
@@ -267,7 +266,6 @@ namespace System.Threading
}
}
return true;
-
}
#endregion
@@ -314,51 +312,4 @@ namespace System.Threading
get { return ProcessorCount == 1; }
}
}
-
- /// <summary>
- /// A helper class to capture a start time using Environment.TickCout as a time in milliseconds, also updates a given timeout bu subtracting the current time from
- /// the start time
- /// </summary>
- internal static class TimeoutHelper
- {
- /// <summary>
- /// Returns the Environment.TickCount as a start time in milliseconds as a uint, TickCount tools over from postive to negative every ~ 25 days
- /// then ~25 days to back to positive again, uint is sued to ignore the sign and double the range to 50 days
- /// </summary>
- /// <returns></returns>
- public static uint GetTime()
- {
- return (uint)Environment.TickCount;
- }
-
- /// <summary>
- /// Helper function to measure and update the elapsed time
- /// </summary>
- /// <param name="startTime"> The first time (in milliseconds) observed when the wait started</param>
- /// <param name="originalWaitMillisecondsTimeout">The orginal wait timeoutout in milliseconds</param>
- /// <returns>The new wait time in milliseconds, -1 if the time expired</returns>
- public static int UpdateTimeOut(uint startTime, int originalWaitMillisecondsTimeout)
- {
- // The function must be called in case the time out is not infinite
- Debug.Assert(originalWaitMillisecondsTimeout != Timeout.Infinite);
-
- uint elapsedMilliseconds = (GetTime() - startTime);
-
- // Check the elapsed milliseconds is greater than max int because this property is uint
- if (elapsedMilliseconds > int.MaxValue)
- {
- return 0;
- }
-
- // Subtract the elapsed time from the current wait time
- int currentWaitTimeout = originalWaitMillisecondsTimeout - (int)elapsedMilliseconds; ;
- if (currentWaitTimeout <= 0)
- {
- return 0;
- }
-
- return currentWaitTimeout;
- }
- }
-
}
diff --git a/src/mscorlib/src/System/Threading/SynchronizationContext.cs b/src/mscorlib/src/System/Threading/SynchronizationContext.cs
index f4b3c79409..676a198ee7 100644
--- a/src/mscorlib/src/System/Threading/SynchronizationContext.cs
+++ b/src/mscorlib/src/System/Threading/SynchronizationContext.cs
@@ -11,7 +11,7 @@
===========================================================*/
namespace System.Threading
-{
+{
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
@@ -27,7 +27,7 @@ namespace System.Threading
[Flags]
- enum SynchronizationContextProperties
+ internal enum SynchronizationContextProperties
{
None = 0,
RequireWaitNotification = 0x1
@@ -41,27 +41,27 @@ namespace System.Threading
[FriendAccessAllowed]
internal class WinRTSynchronizationContextFactoryBase
{
- public virtual SynchronizationContext Create(object coreDispatcher) {return null;}
+ public virtual SynchronizationContext Create(object coreDispatcher) { return null; }
}
#endif //FEATURE_COMINTEROP
public class SynchronizationContext
{
- SynchronizationContextProperties _props = SynchronizationContextProperties.None;
-
+ private SynchronizationContextProperties _props = SynchronizationContextProperties.None;
+
public SynchronizationContext()
{
}
-
+
// helper delegate to statically bind to Wait method
private delegate int WaitDelegate(IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout);
- static Type s_cachedPreparedType1;
- static Type s_cachedPreparedType2;
- static Type s_cachedPreparedType3;
- static Type s_cachedPreparedType4;
- static Type s_cachedPreparedType5;
+ private static Type s_cachedPreparedType1;
+ private static Type s_cachedPreparedType2;
+ private static Type s_cachedPreparedType3;
+ private static Type s_cachedPreparedType4;
+ private static Type s_cachedPreparedType5;
// protected so that only the derived sync context class can enable these flags
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "We never dereference s_cachedPreparedType*, so ordering is unimportant")]
@@ -87,11 +87,11 @@ namespace System.Threading
{
RuntimeHelpers.PrepareDelegate(new WaitDelegate(this.Wait));
- if (s_cachedPreparedType1 == null) s_cachedPreparedType1 = type;
- else if (s_cachedPreparedType2 == null) s_cachedPreparedType2 = type;
- else if (s_cachedPreparedType3 == null) s_cachedPreparedType3 = type;
- else if (s_cachedPreparedType4 == null) s_cachedPreparedType4 = type;
- else if (s_cachedPreparedType5 == null) s_cachedPreparedType5 = type;
+ if (s_cachedPreparedType1 == null) s_cachedPreparedType1 = type;
+ else if (s_cachedPreparedType2 == null) s_cachedPreparedType2 = type;
+ else if (s_cachedPreparedType3 == null) s_cachedPreparedType3 = type;
+ else if (s_cachedPreparedType4 == null) s_cachedPreparedType4 = type;
+ else if (s_cachedPreparedType5 == null) s_cachedPreparedType5 = type;
}
_props |= SynchronizationContextProperties.RequireWaitNotification;
@@ -99,10 +99,10 @@ namespace System.Threading
public bool IsWaitNotificationRequired()
{
- return ((_props & SynchronizationContextProperties.RequireWaitNotification) != 0);
+ return ((_props & SynchronizationContextProperties.RequireWaitNotification) != 0);
}
-
+
public virtual void Send(SendOrPostCallback d, Object state)
{
d(state);
@@ -113,7 +113,7 @@ namespace System.Threading
ThreadPool.QueueUserWorkItem(new WaitCallback(d), state);
}
-
+
/// <summary>
/// Optional override for subclasses, for responding to notification that operation is starting.
/// </summary>
@@ -159,9 +159,9 @@ namespace System.Threading
Thread.CurrentThread.SynchronizationContext = syncContext;
}
- public static SynchronizationContext Current
+ public static SynchronizationContext Current
{
- get
+ get
{
SynchronizationContext context = Thread.CurrentThread.SynchronizationContext;
@@ -189,7 +189,7 @@ namespace System.Threading
{
Debug.Assert(Environment.IsWinRTSupported);
Debug.Assert(AppDomain.IsAppXModel());
-
+
//
// We call into the VM to get the dispatcher. This is because:
//
@@ -207,7 +207,7 @@ namespace System.Threading
return null;
}
- static WinRTSynchronizationContextFactoryBase s_winRTContextFactory;
+ private static WinRTSynchronizationContextFactoryBase s_winRTContextFactory;
private static WinRTSynchronizationContextFactoryBase GetWinRTSynchronizationContextFactory()
{
diff --git a/src/mscorlib/src/System/Threading/SynchronizationLockException.cs b/src/mscorlib/src/System/Threading/SynchronizationLockException.cs
deleted file mode 100644
index de42c1f232..0000000000
--- a/src/mscorlib/src/System/Threading/SynchronizationLockException.cs
+++ /dev/null
@@ -1,43 +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.
-
-//
-/*=============================================================================
-**
-**
-**
-** Purpose: Wait(), Notify() or NotifyAll() was called from an unsynchronized
-** block of code.
-**
-**
-=============================================================================*/
-
-namespace System.Threading {
-
- using System;
- using System.Runtime.Serialization;
- [Serializable]
- public class SynchronizationLockException : SystemException {
- public SynchronizationLockException()
- : base(Environment.GetResourceString("Arg_SynchronizationLockException")) {
- SetErrorCode(__HResults.COR_E_SYNCHRONIZATIONLOCK);
- }
-
- public SynchronizationLockException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_SYNCHRONIZATIONLOCK);
- }
-
- public SynchronizationLockException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(__HResults.COR_E_SYNCHRONIZATIONLOCK);
- }
-
- protected SynchronizationLockException(SerializationInfo info, StreamingContext context) : base (info, context) {
- }
- }
-
-}
-
-
diff --git a/src/mscorlib/src/System/Threading/Tasks/AsyncCausalityTracer.cs b/src/mscorlib/src/System/Threading/Tasks/AsyncCausalityTracer.cs
index ec7c5aaeea..ec154f9efb 100644
--- a/src/mscorlib/src/System/Threading/Tasks/AsyncCausalityTracer.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/AsyncCausalityTracer.cs
@@ -21,7 +21,6 @@ using WFD = Windows.Foundation.Diagnostics;
namespace System.Threading.Tasks
{
-
[FriendAccessAllowed]
internal enum CausalityTraceLevel
{
@@ -85,13 +84,13 @@ namespace System.Threading.Tasks
[FriendAccessAllowed]
internal static class AsyncCausalityTracer
{
- static internal void EnableToETW(bool enabled)
+ static internal void EnableToETW(bool enabled)
{
#if FEATURE_COMINTEROP
if (enabled)
- f_LoggingOn |= Loggers.ETW;
- else
- f_LoggingOn &= ~Loggers.ETW;
+ f_LoggingOn |= Loggers.ETW;
+ else
+ f_LoggingOn &= ~Loggers.ETW;
#endif
}
@@ -121,7 +120,8 @@ namespace System.Threading.Tasks
// The loggers that this Tracer knows about.
[Flags]
- private enum Loggers : byte {
+ private enum Loggers : byte
+ {
CausalityTracer = 1,
ETW = 2
}
@@ -148,7 +148,7 @@ namespace System.Threading.Tasks
int hresult = Microsoft.Win32.UnsafeNativeMethods.RoGetActivationFactory(ClassId, ref guid, out factory);
if (hresult < 0 || factory == null) return; //This prevents having an exception thrown in case IAsyncCausalityTracerStatics isn't registered.
-
+
s_TracerFactory = (WFD.IAsyncCausalityTracerStatics)factory;
EventRegistrationToken token = s_TracerFactory.add_TracingStatusChanged(new EventHandler<WFD.TracingStatusChangedEventArgs>(TracingStatusChangedHandler));
@@ -161,15 +161,14 @@ namespace System.Threading.Tasks
// doing here depends on internal state.
LogAndDisable(ex);
}
-
}
private static void TracingStatusChangedHandler(Object sender, WFD.TracingStatusChangedEventArgs args)
{
if (args.Enabled)
- f_LoggingOn |= Loggers.CausalityTracer;
- else
- f_LoggingOn &= ~Loggers.CausalityTracer;
+ f_LoggingOn |= Loggers.CausalityTracer;
+ else
+ f_LoggingOn &= ~Loggers.CausalityTracer;
}
#endif
@@ -185,11 +184,11 @@ namespace System.Threading.Tasks
try
{
if ((f_LoggingOn & Loggers.ETW) != 0)
- TplEtwProvider.Log.TraceOperationBegin(taskId, operationName, (long) relatedContext);
+ TplEtwProvider.Log.TraceOperationBegin(taskId, operationName, (long)relatedContext);
if ((f_LoggingOn & Loggers.CausalityTracer) != 0)
s_TracerFactory.TraceOperationCreation((WFD.CausalityTraceLevel)traceLevel, s_CausalitySource, s_PlatformId, GetOperationId((uint)taskId), operationName, relatedContext);
}
- catch(Exception ex)
+ catch (Exception ex)
{
//view function comment
LogAndDisable(ex);
@@ -209,7 +208,7 @@ namespace System.Threading.Tasks
if ((f_LoggingOn & Loggers.CausalityTracer) != 0)
s_TracerFactory.TraceOperationCompletion((WFD.CausalityTraceLevel)traceLevel, s_CausalitySource, s_PlatformId, GetOperationId((uint)taskId), (WFD.AsyncCausalityStatus)status);
}
- catch(Exception ex)
+ catch (Exception ex)
{
//view function comment
LogAndDisable(ex);
@@ -228,7 +227,7 @@ namespace System.Threading.Tasks
if ((f_LoggingOn & Loggers.CausalityTracer) != 0)
s_TracerFactory.TraceOperationRelation((WFD.CausalityTraceLevel)traceLevel, s_CausalitySource, s_PlatformId, GetOperationId((uint)taskId), (WFD.CausalityRelation)relation);
}
- catch(Exception ex)
+ catch (Exception ex)
{
//view function comment
LogAndDisable(ex);
@@ -247,7 +246,7 @@ namespace System.Threading.Tasks
if ((f_LoggingOn & Loggers.CausalityTracer) != 0)
s_TracerFactory.TraceSynchronousWorkStart((WFD.CausalityTraceLevel)traceLevel, s_CausalitySource, s_PlatformId, GetOperationId((uint)taskId), (WFD.CausalitySynchronousWork)work);
}
- catch(Exception ex)
+ catch (Exception ex)
{
//view function comment
LogAndDisable(ex);
@@ -266,7 +265,7 @@ namespace System.Threading.Tasks
if ((f_LoggingOn & Loggers.CausalityTracer) != 0)
s_TracerFactory.TraceSynchronousWorkCompletion((WFD.CausalityTraceLevel)traceLevel, s_CausalitySource, (WFD.CausalitySynchronousWork)work);
}
- catch(Exception ex)
+ catch (Exception ex)
{
//view function comment
LogAndDisable(ex);
@@ -288,6 +287,5 @@ namespace System.Threading.Tasks
{
return (((ulong)AppDomain.CurrentDomain.Id) << 32) + taskId;
}
-
}
}
diff --git a/src/mscorlib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs b/src/mscorlib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs
index a87406a493..07a673bf4e 100644
--- a/src/mscorlib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs
@@ -72,22 +72,25 @@ namespace System.Threading.Tasks
/// Initializes the ConcurrentExclusiveSchedulerPair.
/// </summary>
public ConcurrentExclusiveSchedulerPair() :
- this(TaskScheduler.Default, DefaultMaxConcurrencyLevel, DEFAULT_MAXITEMSPERTASK) { }
+ this(TaskScheduler.Default, DefaultMaxConcurrencyLevel, DEFAULT_MAXITEMSPERTASK)
+ { }
/// <summary>
/// Initializes the ConcurrentExclusiveSchedulerPair to target the specified scheduler.
/// </summary>
/// <param name="taskScheduler">The target scheduler on which this pair should execute.</param>
public ConcurrentExclusiveSchedulerPair(TaskScheduler taskScheduler) :
- this(taskScheduler, DefaultMaxConcurrencyLevel, DEFAULT_MAXITEMSPERTASK) { }
+ this(taskScheduler, DefaultMaxConcurrencyLevel, DEFAULT_MAXITEMSPERTASK)
+ { }
/// <summary>
/// Initializes the ConcurrentExclusiveSchedulerPair to target the specified scheduler with a maximum concurrency level.
/// </summary>
/// <param name="taskScheduler">The target scheduler on which this pair should execute.</param>
/// <param name="maxConcurrencyLevel">The maximum number of tasks to run concurrently.</param>
- public ConcurrentExclusiveSchedulerPair(TaskScheduler taskScheduler, int maxConcurrencyLevel) :
- this(taskScheduler, maxConcurrencyLevel, DEFAULT_MAXITEMSPERTASK) { }
+ public ConcurrentExclusiveSchedulerPair(TaskScheduler taskScheduler, int maxConcurrencyLevel) :
+ this(taskScheduler, maxConcurrencyLevel, DEFAULT_MAXITEMSPERTASK)
+ { }
/// <summary>
/// Initializes the ConcurrentExclusiveSchedulerPair to target the specified scheduler with a maximum
@@ -141,7 +144,7 @@ namespace System.Threading.Tasks
}
/// <summary>Gets a <see cref="System.Threading.Tasks.Task"/> that will complete when the scheduler has completed processing.</summary>
- public Task Completion
+ public Task Completion
{
// ValueLock not needed, but it's ok if it's held
get { return EnsureCompletionStateInitialized().Task; }
@@ -162,7 +165,7 @@ namespace System.Threading.Tasks
}
/// <summary>Sets that completion has been requested.</summary>
- private void RequestCompletion()
+ private void RequestCompletion()
{
ContractAssertMonitorStatus(ValueLock, held: true);
EnsureCompletionStateInitialized().m_completionRequested = true;
@@ -190,9 +193,9 @@ namespace System.Threading.Tasks
// Now, only allow shutdown if an exception occurred or if there are no more tasks to process.
var cs = EnsureCompletionStateInitialized();
- return
+ return
(cs.m_exceptions != null && cs.m_exceptions.Count > 0) ||
- (m_concurrentTaskScheduler.m_tasks.IsEmpty && m_exclusiveTaskScheduler.m_tasks.IsEmpty);
+ (m_concurrentTaskScheduler.m_tasks.IsEmpty && m_exclusiveTaskScheduler.m_tasks.IsEmpty);
}
}
@@ -330,7 +333,7 @@ namespace System.Threading.Tasks
}
}
}
-
+
// Check to see if all tasks have completed and if completion has been requested.
CleanupStateIfCompletingAndQuiesced();
}
@@ -370,7 +373,7 @@ namespace System.Threading.Tasks
// We're no longer processing exclusive tasks on the current thread
ProcessingMode currentMode;
m_threadProcessingMapping.TryRemove(Thread.CurrentThread.ManagedThreadId, out currentMode);
- Debug.Assert(currentMode == ProcessingMode.ProcessingExclusiveTask,
+ Debug.Assert(currentMode == ProcessingMode.ProcessingExclusiveTask,
"Somehow we ended up escaping exclusive mode.");
lock (ValueLock)
@@ -720,7 +723,7 @@ namespace System.Threading.Tasks
return mode;
}
}
-
+
/// <summary>Asserts that a given synchronization object is either held or not held.</summary>
/// <param name="syncObj">The monitor to check.</param>
/// <param name="held">Whether we want to assert that it's currently held or not held.</param>
@@ -748,7 +751,7 @@ namespace System.Threading.Tasks
Debug.Assert(Monitor.IsEntered(syncObj) == held, "The locking scheme was not correctly followed.");
#endif
}
-
+
/// <summary>Gets the options to use for tasks.</summary>
/// <param name="isReplacementReplica">If this task is being created to replace another.</param>
/// <remarks>
@@ -758,7 +761,7 @@ namespace System.Threading.Tasks
/// <returns>The options to use.</returns>
internal static TaskCreationOptions GetCreationOptionsForTask(bool isReplacementReplica = false)
{
- TaskCreationOptions options =
+ TaskCreationOptions options =
#if PRENET45
TaskCreationOptions.None;
#else
@@ -784,5 +787,4 @@ namespace System.Threading.Tasks
Completed = 0x8
}
}
-
}
diff --git a/src/mscorlib/src/System/Threading/Tasks/FutureFactory.cs b/src/mscorlib/src/System/Threading/Tasks/FutureFactory.cs
index 137afa11f5..60a7c81dcf 100644
--- a/src/mscorlib/src/System/Threading/Tasks/FutureFactory.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/FutureFactory.cs
@@ -568,8 +568,6 @@ namespace System.Threading.Tasks
promise.DangerousSetResult(result);
}
}
-
-
}
}
@@ -691,7 +689,7 @@ namespace System.Threading.Tasks
// RespectParentCancellation.
Task t = new Task(new Action<object>(delegate
{
- FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization:true);
+ FromAsyncCoreLogic(asyncResult, endFunction, endAction, promise, requiresSynchronization: true);
}),
(object)null, null,
default(CancellationToken), TaskCreationOptions.None, InternalTaskOptions.None, null);
@@ -706,7 +704,7 @@ namespace System.Threading.Tasks
if (asyncResult.IsCompleted)
{
- try { t.InternalRunSynchronously(scheduler, waitForCompletion:false); }
+ try { t.InternalRunSynchronously(scheduler, waitForCompletion: false); }
catch (Exception e) { promise.TrySetException(e); } // catch and log any scheduler exceptions
}
else
@@ -792,7 +790,7 @@ namespace System.Threading.Tasks
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.endMethod);
Contract.Requires((endFunction != null) != (endAction != null), "Both endFunction and endAction were non-null");
-
+
TaskFactory.CheckFromAsyncOptions(creationOptions, true);
Task<TResult> promise = new Task<TResult>(state, creationOptions);
@@ -943,7 +941,6 @@ namespace System.Threading.Tasks
}
catch
{
-
if (AsyncCausalityTracer.LoggingOn)
AsyncCausalityTracer.TraceOperationCompletion(CausalityTraceLevel.Required, promise.Id, AsyncCausalityStatus.Error);
@@ -1241,7 +1238,7 @@ namespace System.Threading.Tasks
internal static Task<TResult> FromAsyncTrim<TInstance, TArgs>(
TInstance thisRef, TArgs args,
Func<TInstance, TArgs, AsyncCallback, object, IAsyncResult> beginMethod,
- Func<TInstance, IAsyncResult, TResult> endMethod)
+ Func<TInstance, IAsyncResult, TResult> endMethod)
where TInstance : class
{
// Validate arguments, but only with asserts, as this is an internal only implementation.
@@ -1319,7 +1316,7 @@ namespace System.Threading.Tasks
// we'll instead complete the promise at the call site.
if (!asyncResult.CompletedSynchronously)
{
- promise.Complete(thisRef, endMethod, asyncResult, requiresSynchronization:true);
+ promise.Complete(thisRef, endMethod, asyncResult, requiresSynchronization: true);
}
}
@@ -1661,7 +1658,7 @@ namespace System.Threading.Tasks
return ContinueWhenAllImpl<TAntecedentResult>(tasks, continuationFunction, null, continuationOptions, cancellationToken, scheduler);
}
-
+
// Core implementation of ContinueWhenAll -- the generic version
// Note: if you make any changes to this method, please do the same to the non-generic version too.
internal static Task<TResult> ContinueWhenAllImpl<TAntecedentResult>(Task<TAntecedentResult>[] tasks,
@@ -1744,10 +1741,10 @@ namespace System.Threading.Tasks
//the following delegate avoids closure capture as much as possible
//completedTasks.Result == tasksCopy;
//state == continuationFunction
- (completedTasks, state) =>
+ (completedTasks, state) =>
{
completedTasks.NotifyDebuggerOfWaitCompletionIfNecessary();
- return ((Func<Task[], TResult>)state)(completedTasks.Result);
+ return ((Func<Task[], TResult>)state)(completedTasks.Result);
},
continuationFunction, scheduler, cancellationToken, continuationOptions);
}
@@ -1755,13 +1752,13 @@ namespace System.Threading.Tasks
{
Debug.Assert(continuationAction != null);
return starter.ContinueWith<TResult>(
- //the following delegate avoids closure capture as much as possible
- //completedTasks.Result == tasksCopy;
- //state == continuationAction
- (completedTasks, state) =>
+ //the following delegate avoids closure capture as much as possible
+ //completedTasks.Result == tasksCopy;
+ //state == continuationAction
+ (completedTasks, state) =>
{
completedTasks.NotifyDebuggerOfWaitCompletionIfNecessary();
- ((Action<Task[]>)state)(completedTasks.Result); return default(TResult);
+ ((Action<Task[]>)state)(completedTasks.Result); return default(TResult);
},
continuationAction, scheduler, cancellationToken, continuationOptions);
}
@@ -2054,7 +2051,7 @@ namespace System.Threading.Tasks
// check arguments
TaskFactory.CheckMultiTaskContinuationOptions(continuationOptions);
if (tasks == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.tasks);
- if(tasks.Length == 0) ThrowHelper.ThrowArgumentException( ExceptionResource.Task_MultiTaskContinuation_EmptyTaskList, ExceptionArgument.tasks);
+ if (tasks.Length == 0) ThrowHelper.ThrowArgumentException(ExceptionResource.Task_MultiTaskContinuation_EmptyTaskList, ExceptionArgument.tasks);
//ArgumentNullException of continuationFunction or continuationAction is checked by the caller
Contract.Requires((continuationFunction != null) != (continuationAction != null), "Expected exactly one of endFunction/endAction to be non-null");
@@ -2076,8 +2073,8 @@ namespace System.Threading.Tasks
if (continuationFunction != null)
{
return starter.ContinueWith(
- //the following delegate avoids closure capture as much as possible
- //completedTask.Result is the winning task; state == continuationAction
+ //the following delegate avoids closure capture as much as possible
+ //completedTask.Result is the winning task; state == continuationAction
(completedTask, state) => { return ((Func<Task, TResult>)state)(completedTask.Result); },
continuationFunction, scheduler, cancellationToken, continuationOptions);
}
@@ -2132,7 +2129,7 @@ namespace System.Threading.Tasks
Debug.Assert(continuationAction != null);
return starter.ContinueWith<TResult>(
// Use a cached delegate
- GenericDelegateCache<TAntecedentResult,TResult>.CWAnyActionDelegate,
+ GenericDelegateCache<TAntecedentResult, TResult>.CWAnyActionDelegate,
continuationAction, scheduler, cancellationToken, continuationOptions);
}
}
@@ -2180,7 +2177,5 @@ namespace System.Threading.Tasks
action(wrappedAntecedents.Result);
return default(TResult);
};
-
}
-
}
diff --git a/src/mscorlib/src/System/Threading/Tasks/IAsyncCausalityTracerStatics.cs b/src/mscorlib/src/System/Threading/Tasks/IAsyncCausalityTracerStatics.cs
index 32efd771a0..17dd1f8bde 100644
--- a/src/mscorlib/src/System/Threading/Tasks/IAsyncCausalityTracerStatics.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/IAsyncCausalityTracerStatics.cs
@@ -13,6 +13,7 @@ using System.Runtime.InteropServices.WindowsRuntime;
// Windows.Foundation.Diagnostics cannot be referenced from managed code because
// they're hidden by the metadata adapter. We redeclare the interfaces manually
// to be able to talk to native WinRT objects.
+
namespace Windows.Foundation.Diagnostics
{
[ComImport]
@@ -47,16 +48,16 @@ namespace Windows.Foundation.Diagnostics
[WindowsRuntimeImport]
internal sealed class TracingStatusChangedEventArgs : ITracingStatusChangedEventArgs
{
- public extern bool Enabled
+ public extern bool Enabled
{
[MethodImpl(MethodImplOptions.InternalCall)]
get;
}
-
- public extern CausalityTraceLevel TraceLevel
+
+ public extern CausalityTraceLevel TraceLevel
{
[MethodImpl(MethodImplOptions.InternalCall)]
- get;
+ get;
}
}
@@ -97,5 +98,4 @@ namespace Windows.Foundation.Diagnostics
Error = 3,
Started = 0
}
-
}
diff --git a/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs b/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs
index 545bf9a5e5..f9d5f89398 100644
--- a/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/ProducerConsumerQueues.cs
@@ -182,7 +182,8 @@ namespace System.Threading.Tasks
newSegment.m_state.m_last = 1;
newSegment.m_state.m_lastCopy = 1;
- try { } finally
+ try { }
+ finally
{
// Finally block to protect against corruption due to a thread abort
// between setting m_next and setting m_tail.
@@ -271,8 +272,8 @@ namespace System.Threading.Tasks
{
for (Segment segment = m_head; segment != null; segment = segment.m_next)
{
- for (int pt = segment.m_state.m_first;
- pt != segment.m_state.m_last;
+ for (int pt = segment.m_state.m_first;
+ pt != segment.m_state.m_last;
pt = (pt + 1) & (segment.m_array.Length - 1))
{
yield return segment.m_array[pt];
@@ -307,7 +308,7 @@ namespace System.Threading.Tasks
}
/// <summary>A segment in the queue containing one or more items.</summary>
- [StructLayout(LayoutKind.Sequential)]
+ [StructLayout(LayoutKind.Sequential)]
private sealed class Segment
{
/// <summary>The next segment in the linked list of segments.</summary>
@@ -367,7 +368,7 @@ namespace System.Threading.Tasks
}
/// <summary>A placeholder class for common padding constants and eventually routines.</summary>
- static class PaddingHelpers
+ internal static class PaddingHelpers
{
/// <summary>A size greater than or equal to the size of the most common CPU cache lines.</summary>
internal const int CACHE_LINE_SIZE = 128;
@@ -375,8 +376,7 @@ namespace System.Threading.Tasks
/// <summary>Padding structure used to minimize false sharing in SingleProducerSingleConsumerQueue{T}.</summary>
[StructLayout(LayoutKind.Explicit, Size = PaddingHelpers.CACHE_LINE_SIZE - sizeof(Int32))] // Based on common case of 64-byte cache lines
- struct PaddingFor32
+ internal struct PaddingFor32
{
}
-
}
diff --git a/src/mscorlib/src/System/Threading/Tasks/TPLETWProvider.cs b/src/mscorlib/src/System/Threading/Tasks/TPLETWProvider.cs
index 12cc1daa63..33bf792370 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TPLETWProvider.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/TPLETWProvider.cs
@@ -16,21 +16,21 @@ using System.Text;
using System.Security;
using System.Runtime.CompilerServices;
+using System.Diagnostics.Tracing;
+
namespace System.Threading.Tasks
{
- using System.Diagnostics.Tracing;
-
/// <summary>Provides an event source for tracing TPL information.</summary>
[EventSource(
Name = "System.Threading.Tasks.TplEventSource",
- Guid = "2e5dba47-a3d2-4d16-8ee0-6671ffdcd7b5",
- LocalizationResources = System.CoreLib.Name)]
+ Guid = "2e5dba47-a3d2-4d16-8ee0-6671ffdcd7b5",
+ LocalizationResources = "FxResources.System.Private.CoreLib.SR")]
internal sealed class TplEtwProvider : EventSource
{
/// Used to determine if tasks should generate Activity IDs for themselves
internal bool TasksSetActivityIds; // This keyword is set
internal bool Debug;
- private bool DebugActivityId;
+ private bool DebugActivityId;
/// <summary>
/// Get callbacks when the ETW sends us commands`
@@ -42,11 +42,11 @@ namespace System.Threading.Tasks
AsyncCausalityTracer.EnableToETW(true);
else if (command.Command == EventCommand.Disable)
AsyncCausalityTracer.EnableToETW(false);
-
- if (IsEnabled(EventLevel.Informational, Keywords.TasksFlowActivityIds))
+
+ if (IsEnabled(EventLevel.Informational, Keywords.TasksFlowActivityIds))
ActivityTracker.Instance.Enable();
- else
- TasksSetActivityIds = IsEnabled(EventLevel.Informational, Keywords.TasksSetActivityIds);
+ else
+ TasksSetActivityIds = IsEnabled(EventLevel.Informational, Keywords.TasksSetActivityIds);
Debug = IsEnabled(EventLevel.Informational, Keywords.Debug);
DebugActivityId = IsEnabled(EventLevel.Informational, Keywords.DebugActivityId);
@@ -99,49 +99,49 @@ namespace System.Threading.Tasks
/// This sets activity IDS and logs when tasks are schedules (or waits begin)
/// But are otherwise silent
/// </summary>
- public const EventKeywords TaskTransfer = (EventKeywords) 1;
+ public const EventKeywords TaskTransfer = (EventKeywords)1;
/// <summary>
/// TaskTranser events plus events when tasks start and stop
/// </summary>
- public const EventKeywords Tasks = (EventKeywords) 2;
+ public const EventKeywords Tasks = (EventKeywords)2;
/// <summary>
/// Events associted with the higher level parallel APIs
/// </summary>
- public const EventKeywords Parallel = (EventKeywords) 4;
+ public const EventKeywords Parallel = (EventKeywords)4;
/// <summary>
/// These are relatively verbose events that effectively just redirect
/// the windows AsyncCausalityTracer to ETW
/// </summary>
- public const EventKeywords AsyncCausalityOperation = (EventKeywords) 8;
- public const EventKeywords AsyncCausalityRelation = (EventKeywords) 0x10;
- public const EventKeywords AsyncCausalitySynchronousWork = (EventKeywords) 0x20;
+ public const EventKeywords AsyncCausalityOperation = (EventKeywords)8;
+ public const EventKeywords AsyncCausalityRelation = (EventKeywords)0x10;
+ public const EventKeywords AsyncCausalitySynchronousWork = (EventKeywords)0x20;
/// <summary>
/// Emit the stops as well as the schedule/start events
/// </summary>
- public const EventKeywords TaskStops = (EventKeywords) 0x40;
+ public const EventKeywords TaskStops = (EventKeywords)0x40;
/// <summary>
/// TasksFlowActivityIds indicate that activity ID flow from one task
/// to any task created by it.
/// </summary>
- public const EventKeywords TasksFlowActivityIds = (EventKeywords) 0x80;
+ public const EventKeywords TasksFlowActivityIds = (EventKeywords)0x80;
/// <summary>
/// TasksSetActivityIds will cause the task operations to set Activity Ids
/// This option is incompatible with TasksFlowActivityIds flow is ignored
/// if that keyword is set. This option is likley to be removed in the future
/// </summary>
- public const EventKeywords TasksSetActivityIds = (EventKeywords) 0x10000;
+ public const EventKeywords TasksSetActivityIds = (EventKeywords)0x10000;
/// <summary>
/// Relatively Verbose logging meant for debugging the Task library itself. Will probably be removed in the future
/// </summary>
- public const EventKeywords Debug = (EventKeywords) 0x20000;
+ public const EventKeywords Debug = (EventKeywords)0x20000;
/// <summary>
/// Relatively Verbose logging meant for debugging the Task library itself. Will probably be removed in the future
/// </summary>
- public const EventKeywords DebugActivityId = (EventKeywords) 0x40000;
+ public const EventKeywords DebugActivityId = (EventKeywords)0x40000;
}
/// <summary>Enabled for all keywords.</summary>
@@ -182,18 +182,18 @@ namespace System.Threading.Tasks
/// <summary>A continuation of a taskWaitEnd is complete </summary>
private const int TASKWAITCONTINUATIONSTARTED_ID = 19;
- private const int TRACEOPERATIONSTART_ID = 14;
- private const int TRACEOPERATIONSTOP_ID = 15;
- private const int TRACEOPERATIONRELATION_ID = 16;
+ private const int TRACEOPERATIONSTART_ID = 14;
+ private const int TRACEOPERATIONSTOP_ID = 15;
+ private const int TRACEOPERATIONRELATION_ID = 16;
private const int TRACESYNCHRONOUSWORKSTART_ID = 17;
- private const int TRACESYNCHRONOUSWORKSTOP_ID = 18;
+ private const int TRACESYNCHRONOUSWORKSTOP_ID = 18;
+
-
//-----------------------------------------------------------------------------------
//
// Task Events
//
-
+
// These are all verbose events, so we need to call IsEnabled(EventLevel.Verbose, ALL_KEYWORDS)
// call. However since the IsEnabled(l,k) call is more expensive than IsEnabled(), we only want
// to incur this cost when instrumentation is enabled. So the Task codepaths that call these
@@ -208,36 +208,36 @@ namespace System.Threading.Tasks
/// <param name="TaskID">The task ID.</param>
/// <param name="CreatingTaskID">The task ID</param>
/// <param name="TaskCreationOptions">The options used to create the task.</param>
- [Event(TASKSCHEDULED_ID, Task = Tasks.TaskScheduled, Version=1, Opcode = EventOpcode.Send,
- Level = EventLevel.Informational, Keywords = Keywords.TaskTransfer|Keywords.Tasks)]
+ [Event(TASKSCHEDULED_ID, Task = Tasks.TaskScheduled, Version = 1, Opcode = EventOpcode.Send,
+ Level = EventLevel.Informational, Keywords = Keywords.TaskTransfer | Keywords.Tasks)]
public void TaskScheduled(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
int TaskID, int CreatingTaskID, int TaskCreationOptions, int appDomain)
{
// IsEnabled() call is an inlined quick check that makes this very fast when provider is off
- if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.TaskTransfer|Keywords.Tasks))
+ if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.TaskTransfer | Keywords.Tasks))
{
unsafe
{
EventData* eventPayload = stackalloc EventData[6];
eventPayload[0].Size = sizeof(int);
- eventPayload[0].DataPointer = ((IntPtr) (&OriginatingTaskSchedulerID));
+ eventPayload[0].DataPointer = ((IntPtr)(&OriginatingTaskSchedulerID));
eventPayload[1].Size = sizeof(int);
- eventPayload[1].DataPointer = ((IntPtr) (&OriginatingTaskID));
+ eventPayload[1].DataPointer = ((IntPtr)(&OriginatingTaskID));
eventPayload[2].Size = sizeof(int);
- eventPayload[2].DataPointer = ((IntPtr) (&TaskID));
+ eventPayload[2].DataPointer = ((IntPtr)(&TaskID));
eventPayload[3].Size = sizeof(int);
- eventPayload[3].DataPointer = ((IntPtr) (&CreatingTaskID));
+ eventPayload[3].DataPointer = ((IntPtr)(&CreatingTaskID));
eventPayload[4].Size = sizeof(int);
- eventPayload[4].DataPointer = ((IntPtr) (&TaskCreationOptions));
+ eventPayload[4].DataPointer = ((IntPtr)(&TaskCreationOptions));
eventPayload[5].Size = sizeof(int);
- eventPayload[5].DataPointer = ((IntPtr) (&appDomain));
+ eventPayload[5].DataPointer = ((IntPtr)(&appDomain));
if (TasksSetActivityIds)
{
Guid childActivityId = CreateGuidForTaskID(TaskID);
WriteEventWithRelatedActivityIdCore(TASKSCHEDULED_ID, &childActivityId, 6, eventPayload);
}
- else
+ else
WriteEventCore(TASKSCHEDULED_ID, 6, eventPayload);
}
}
@@ -251,13 +251,13 @@ namespace System.Threading.Tasks
/// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
/// <param name="OriginatingTaskID">The task ID.</param>
/// <param name="TaskID">The task ID.</param>
- [Event(TASKSTARTED_ID,
+ [Event(TASKSTARTED_ID,
Level = EventLevel.Informational, Keywords = Keywords.Tasks)]
public void TaskStarted(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
int TaskID)
{
- if (IsEnabled(EventLevel.Informational, Keywords.Tasks))
+ if (IsEnabled(EventLevel.Informational, Keywords.Tasks))
WriteEvent(TASKSTARTED_ID, OriginatingTaskSchedulerID, OriginatingTaskID, TaskID);
}
#endregion
@@ -270,33 +270,33 @@ namespace System.Threading.Tasks
/// <param name="OriginatingTaskID">The task ID.</param>
/// <param name="TaskID">The task ID.</param>
/// <param name="IsExceptional">Whether the task completed due to an error.</param>
- [Event(TASKCOMPLETED_ID, Version=1,
+ [Event(TASKCOMPLETED_ID, Version = 1,
Level = EventLevel.Informational, Keywords = Keywords.TaskStops)]
public void TaskCompleted(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
int TaskID, bool IsExceptional)
{
- if (IsEnabled(EventLevel.Informational, Keywords.Tasks))
+ if (IsEnabled(EventLevel.Informational, Keywords.Tasks))
{
unsafe
{
EventData* eventPayload = stackalloc EventData[4];
Int32 isExceptionalInt = IsExceptional ? 1 : 0;
eventPayload[0].Size = sizeof(int);
- eventPayload[0].DataPointer = ((IntPtr) (&OriginatingTaskSchedulerID));
+ eventPayload[0].DataPointer = ((IntPtr)(&OriginatingTaskSchedulerID));
eventPayload[1].Size = sizeof(int);
- eventPayload[1].DataPointer = ((IntPtr) (&OriginatingTaskID));
+ eventPayload[1].DataPointer = ((IntPtr)(&OriginatingTaskID));
eventPayload[2].Size = sizeof(int);
- eventPayload[2].DataPointer = ((IntPtr) (&TaskID));
+ eventPayload[2].DataPointer = ((IntPtr)(&TaskID));
eventPayload[3].Size = sizeof(int);
- eventPayload[3].DataPointer = ((IntPtr) (&isExceptionalInt));
+ eventPayload[3].DataPointer = ((IntPtr)(&isExceptionalInt));
WriteEventCore(TASKCOMPLETED_ID, 4, eventPayload);
}
- }
+ }
}
#endregion
- #region TaskWaitBegin
+ #region TaskWaitBegin
/// <summary>
/// Fired when starting to wait for a taks's completion explicitly or implicitly.
/// </summary>
@@ -307,13 +307,13 @@ namespace System.Threading.Tasks
/// <param name="ContinueWithTaskID">If known, if 'TaskID' has a 'continueWith' task, mention give its ID here.
/// 0 means unknown. This allows better visualization of the common sequential chaining case.</param>
/// </summary>
- [Event(TASKWAITBEGIN_ID, Version=3, Task = TplEtwProvider.Tasks.TaskWait, Opcode = EventOpcode.Send,
- Level = EventLevel.Informational, Keywords = Keywords.TaskTransfer|Keywords.Tasks)]
+ [Event(TASKWAITBEGIN_ID, Version = 3, Task = TplEtwProvider.Tasks.TaskWait, Opcode = EventOpcode.Send,
+ Level = EventLevel.Informational, Keywords = Keywords.TaskTransfer | Keywords.Tasks)]
public void TaskWaitBegin(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
int TaskID, TaskWaitBehavior Behavior, int ContinueWithTaskID)
{
- if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.TaskTransfer|Keywords.Tasks))
+ if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.TaskTransfer | Keywords.Tasks))
{
unsafe
{
@@ -348,7 +348,7 @@ namespace System.Threading.Tasks
/// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
/// <param name="OriginatingTaskID">The task ID.</param>
/// <param name="TaskID">The task ID.</param>
- [Event(TASKWAITEND_ID,
+ [Event(TASKWAITEND_ID,
Level = EventLevel.Verbose, Keywords = Keywords.Tasks)]
public void TaskWaitEnd(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
@@ -395,23 +395,23 @@ namespace System.Threading.Tasks
/// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
/// <param name="OriginatingTaskID">The task ID.</param>
/// <param name="TaskID">The activityId for the continuation.</param>
- [Event(AWAITTASKCONTINUATIONSCHEDULED_ID, Task = Tasks.AwaitTaskContinuationScheduled, Opcode = EventOpcode.Send,
- Level = EventLevel.Informational, Keywords = Keywords.TaskTransfer|Keywords.Tasks)]
+ [Event(AWAITTASKCONTINUATIONSCHEDULED_ID, Task = Tasks.AwaitTaskContinuationScheduled, Opcode = EventOpcode.Send,
+ Level = EventLevel.Informational, Keywords = Keywords.TaskTransfer | Keywords.Tasks)]
public void AwaitTaskContinuationScheduled(
int OriginatingTaskSchedulerID, int OriginatingTaskID, // PFX_COMMON_EVENT_HEADER
int ContinuwWithTaskId)
{
- if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.TaskTransfer|Keywords.Tasks))
- {
+ if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.TaskTransfer | Keywords.Tasks))
+ {
unsafe
{
EventData* eventPayload = stackalloc EventData[3];
eventPayload[0].Size = sizeof(int);
- eventPayload[0].DataPointer = ((IntPtr) (&OriginatingTaskSchedulerID));
+ eventPayload[0].DataPointer = ((IntPtr)(&OriginatingTaskSchedulerID));
eventPayload[1].Size = sizeof(int);
- eventPayload[1].DataPointer = ((IntPtr) (&OriginatingTaskID));
+ eventPayload[1].DataPointer = ((IntPtr)(&OriginatingTaskID));
eventPayload[2].Size = sizeof(int);
- eventPayload[2].DataPointer = ((IntPtr) (&ContinuwWithTaskId));
+ eventPayload[2].DataPointer = ((IntPtr)(&ContinuwWithTaskId));
if (TasksSetActivityIds)
{
Guid continuationActivityId = CreateGuidForTaskID(ContinuwWithTaskId);
@@ -423,116 +423,116 @@ namespace System.Threading.Tasks
}
}
- [Event(TRACEOPERATIONSTART_ID, Version=1,
+ [Event(TRACEOPERATIONSTART_ID, Version = 1,
Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalityOperation)]
public void TraceOperationBegin(int TaskID, string OperationName, long RelatedContext)
{
- if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.AsyncCausalityOperation))
+ if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.AsyncCausalityOperation))
{
unsafe
{
- fixed(char* operationNamePtr = OperationName)
+ fixed (char* operationNamePtr = OperationName)
{
EventData* eventPayload = stackalloc EventData[3];
eventPayload[0].Size = sizeof(int);
- eventPayload[0].DataPointer = ((IntPtr) (&TaskID));
+ eventPayload[0].DataPointer = ((IntPtr)(&TaskID));
eventPayload[1].Size = ((OperationName.Length + 1) * 2);
- eventPayload[1].DataPointer = ((IntPtr) operationNamePtr);
+ eventPayload[1].DataPointer = ((IntPtr)operationNamePtr);
eventPayload[2].Size = sizeof(long);
- eventPayload[2].DataPointer = ((IntPtr) (&RelatedContext));
+ eventPayload[2].DataPointer = ((IntPtr)(&RelatedContext));
WriteEventCore(TRACEOPERATIONSTART_ID, 3, eventPayload);
}
}
- }
+ }
}
- [Event(TRACEOPERATIONRELATION_ID, Version=1,
+ [Event(TRACEOPERATIONRELATION_ID, Version = 1,
Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalityRelation)]
public void TraceOperationRelation(int TaskID, CausalityRelation Relation)
{
- if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.AsyncCausalityRelation))
- WriteEvent(TRACEOPERATIONRELATION_ID, TaskID,(int) Relation); // optmized overload for this exists
+ if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.AsyncCausalityRelation))
+ WriteEvent(TRACEOPERATIONRELATION_ID, TaskID, (int)Relation); // optmized overload for this exists
}
- [Event(TRACEOPERATIONSTOP_ID, Version=1,
+ [Event(TRACEOPERATIONSTOP_ID, Version = 1,
Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalityOperation)]
public void TraceOperationEnd(int TaskID, AsyncCausalityStatus Status)
{
- if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.AsyncCausalityOperation))
- WriteEvent(TRACEOPERATIONSTOP_ID, TaskID,(int) Status); // optmized overload for this exists
+ if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.AsyncCausalityOperation))
+ WriteEvent(TRACEOPERATIONSTOP_ID, TaskID, (int)Status); // optmized overload for this exists
}
- [Event(TRACESYNCHRONOUSWORKSTART_ID, Version=1,
+ [Event(TRACESYNCHRONOUSWORKSTART_ID, Version = 1,
Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalitySynchronousWork)]
public void TraceSynchronousWorkBegin(int TaskID, CausalitySynchronousWork Work)
{
- if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.AsyncCausalitySynchronousWork))
- WriteEvent(TRACESYNCHRONOUSWORKSTART_ID, TaskID,(int) Work); // optmized overload for this exists
+ if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.AsyncCausalitySynchronousWork))
+ WriteEvent(TRACESYNCHRONOUSWORKSTART_ID, TaskID, (int)Work); // optmized overload for this exists
}
- [Event(TRACESYNCHRONOUSWORKSTOP_ID, Version=1,
+ [Event(TRACESYNCHRONOUSWORKSTOP_ID, Version = 1,
Level = EventLevel.Informational, Keywords = Keywords.AsyncCausalitySynchronousWork)]
public void TraceSynchronousWorkEnd(CausalitySynchronousWork Work)
{
- if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.AsyncCausalitySynchronousWork))
+ if (IsEnabled() && IsEnabled(EventLevel.Informational, Keywords.AsyncCausalitySynchronousWork))
{
unsafe
{
EventData* eventPayload = stackalloc EventData[1];
eventPayload[0].Size = sizeof(int);
- eventPayload[0].DataPointer = ((IntPtr) (&Work));
+ eventPayload[0].DataPointer = ((IntPtr)(&Work));
WriteEventCore(TRACESYNCHRONOUSWORKSTOP_ID, 1, eventPayload);
}
- }
+ }
}
[NonEvent]
- unsafe public void RunningContinuation(int TaskID, object Object) { RunningContinuation(TaskID, (long) *((void**) JitHelpers.UnsafeCastToStackPointer(ref Object))); }
+ unsafe public void RunningContinuation(int TaskID, object Object) { RunningContinuation(TaskID, (long)*((void**)JitHelpers.UnsafeCastToStackPointer(ref Object))); }
[Event(20, Keywords = Keywords.Debug)]
- private void RunningContinuation(int TaskID, long Object)
- {
+ private void RunningContinuation(int TaskID, long Object)
+ {
if (Debug)
- WriteEvent(20, TaskID, Object);
+ WriteEvent(20, TaskID, Object);
}
[NonEvent]
- unsafe public void RunningContinuationList(int TaskID, int Index, object Object) { RunningContinuationList(TaskID, Index, (long) *((void**) JitHelpers.UnsafeCastToStackPointer(ref Object))); }
+ unsafe public void RunningContinuationList(int TaskID, int Index, object Object) { RunningContinuationList(TaskID, Index, (long)*((void**)JitHelpers.UnsafeCastToStackPointer(ref Object))); }
[Event(21, Keywords = Keywords.Debug)]
- public void RunningContinuationList(int TaskID, int Index, long Object)
- {
+ public void RunningContinuationList(int TaskID, int Index, long Object)
+ {
if (Debug)
- WriteEvent(21, TaskID, Index, Object);
- }
+ WriteEvent(21, TaskID, Index, Object);
+ }
[Event(23, Keywords = Keywords.Debug)]
- public void DebugFacilityMessage(string Facility, string Message) { WriteEvent(23, Facility, Message); }
+ public void DebugFacilityMessage(string Facility, string Message) { WriteEvent(23, Facility, Message); }
[Event(24, Keywords = Keywords.Debug)]
- public void DebugFacilityMessage1(string Facility, string Message, string Value1) { WriteEvent(24, Facility, Message, Value1); }
+ public void DebugFacilityMessage1(string Facility, string Message, string Value1) { WriteEvent(24, Facility, Message, Value1); }
[Event(25, Keywords = Keywords.DebugActivityId)]
public void SetActivityId(Guid NewId)
{
if (DebugActivityId)
- WriteEvent(25, NewId);
- }
+ WriteEvent(25, NewId);
+ }
[Event(26, Keywords = Keywords.Debug)]
- public void NewID(int TaskID)
- {
+ public void NewID(int TaskID)
+ {
if (Debug)
- WriteEvent(26, TaskID);
- }
+ WriteEvent(26, TaskID);
+ }
/// <summary>
/// Activity IDs are GUIDS but task IDS are integers (and are not unique across appdomains
/// This routine creates a process wide unique GUID given a task ID
/// </summary>
- internal static Guid CreateGuidForTaskID(int taskID)
+ internal static Guid CreateGuidForTaskID(int taskID)
{
// The thread pool generated a process wide unique GUID from a task GUID by
// using the taskGuid, the appdomain ID, and 8 bytes of 'randomization' chosen by
@@ -540,9 +540,9 @@ namespace System.Threading.Tasks
// These were generated by CreateGuid, and are reasonably random (and thus unlikley to collide
uint pid = EventSource.s_currentPid;
int appDomainID = System.Threading.Thread.GetDomainID();
- return new Guid(taskID,
- (short) appDomainID , (short) (appDomainID >> 16),
- (byte)pid, (byte)(pid >> 8), (byte)(pid >> 16), (byte)(pid >> 24),
+ return new Guid(taskID,
+ (short)appDomainID, (short)(appDomainID >> 16),
+ (byte)pid, (byte)(pid >> 8), (byte)(pid >> 16), (byte)(pid >> 24),
0xff, 0xdc, 0xd7, 0xb5);
}
}
diff --git a/src/mscorlib/src/System/Threading/Tasks/Task.cs b/src/mscorlib/src/System/Threading/Tasks/Task.cs
index 7013c5c5e0..8e2e6a4cb0 100644
--- a/src/mscorlib/src/System/Threading/Tasks/Task.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/Task.cs
@@ -29,7 +29,6 @@ using System.Diagnostics.Tracing;
namespace System.Threading.Tasks
{
-
/// <summary>
/// Utility class for allocating structs as heap variables
/// </summary>
@@ -41,7 +40,6 @@ namespace System.Threading.Tasks
{
this.Value = value;
}
-
}
/// <summary>
@@ -271,7 +269,7 @@ namespace System.Threading.Tasks
// but haven't yet been waited on by the parent, lazily initialized.
internal volatile List<Task> m_exceptionalChildren;
// A task's parent, or null if parent-less. Only set during Task construction.
- internal Task m_parent;
+ internal Task m_parent;
/// <summary>
/// Sets the internal completion event.
@@ -569,8 +567,8 @@ namespace System.Threading.Tasks
#if DEBUG
// Check the validity of internalOptions
- int illegalInternalOptions =
- (int) (internalOptions &
+ int illegalInternalOptions =
+ (int)(internalOptions &
~(InternalTaskOptions.PromiseTask |
InternalTaskOptions.ContinuationTask |
InternalTaskOptions.LazyCancellation |
@@ -581,27 +579,26 @@ namespace System.Threading.Tasks
// Assign options to m_stateAndOptionsFlag.
Debug.Assert(m_stateFlags == 0, "TaskConstructorCore: non-zero m_stateFlags");
Debug.Assert((((int)creationOptions) | OptionsMask) == OptionsMask, "TaskConstructorCore: options take too many bits");
- var tmpFlags = (int)creationOptions | (int)internalOptions;
- if ((m_action == null) || ((internalOptions & InternalTaskOptions.ContinuationTask) != 0))
- {
- // For continuation tasks or TaskCompletionSource.Tasks, begin life in the
- // WaitingForActivation state rather than the Created state.
- tmpFlags |= TASK_STATE_WAITINGFORACTIVATION;
- }
- m_stateFlags = tmpFlags; // one write to the volatile m_stateFlags instead of two when setting the above options
+ int tmpFlags = (int)creationOptions | (int)internalOptions; // one write to the volatile m_stateFlags instead of two when setting the above options
+ m_stateFlags = m_action == null || (internalOptions & InternalTaskOptions.ContinuationTask) != 0 ?
+ tmpFlags | TASK_STATE_WAITINGFORACTIVATION :
+ tmpFlags;
// Now is the time to add the new task to the children list
// of the creating task if the options call for it.
// We can safely call the creator task's AddNewChild() method to register it,
// because at this point we are already on its thread of execution.
- Task parent = m_contingentProperties?.m_parent;
- if (parent != null
- && ((creationOptions & TaskCreationOptions.AttachedToParent) != 0)
- && ((parent.CreationOptions & TaskCreationOptions.DenyChildAttach) == 0)
- )
+ ContingentProperties props = m_contingentProperties;
+ if (props != null)
{
- parent.AddNewChild();
+ Task parent = props.m_parent;
+ if (parent != null
+ && ((creationOptions & TaskCreationOptions.AttachedToParent) != 0)
+ && ((parent.CreationOptions & TaskCreationOptions.DenyChildAttach) == 0))
+ {
+ parent.AddNewChild();
+ }
}
// if we have a non-null cancellationToken, allocate the contingent properties to save it
@@ -716,14 +713,7 @@ namespace System.Threading.Tasks
}
// Internal property to process TaskCreationOptions access and mutation.
- internal TaskCreationOptions Options
- {
- get
- {
- int stateFlags = m_stateFlags; // "cast away" volatility to enable inlining of OptionsMethod
- return OptionsMethod(stateFlags);
- }
- }
+ internal TaskCreationOptions Options => OptionsMethod(m_stateFlags);
// Similar to Options property, but allows for the use of a cached flags value rather than
// a read of the volatile m_stateFlags field.
@@ -737,11 +727,16 @@ namespace System.Threading.Tasks
// no illegalBits are set. Returns true on success, false on failure.
internal bool AtomicStateUpdate(int newBits, int illegalBits)
{
- // This could be implemented in terms of:
- // internal bool AtomicStateUpdate(int newBits, int illegalBits, ref int oldFlags);
- // but for high-throughput perf, that delegation's cost is noticeable.
+ int oldFlags = m_stateFlags;
+ return
+ (oldFlags & illegalBits) == 0 &&
+ (Interlocked.CompareExchange(ref m_stateFlags, oldFlags | newBits, oldFlags) == oldFlags ||
+ AtomicStateUpdateSlow(newBits, illegalBits));
+ }
- SpinWait sw = new SpinWait();
+ private bool AtomicStateUpdateSlow(int newBits, int illegalBits)
+ {
+ var sw = new SpinWait();
do
{
int oldFlags = m_stateFlags;
@@ -900,7 +895,6 @@ namespace System.Threading.Tasks
return AtomicStateUpdate(TASK_STATE_STARTED, TASK_STATE_CANCELED | TASK_STATE_STARTED);
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal bool FireTaskScheduledIfNeeded(TaskScheduler ts)
{
var etwLog = TplEtwProvider.Log;
@@ -1789,7 +1783,7 @@ namespace System.Threading.Tasks
catch (ThreadAbortException tae)
{
AddException(tae);
- FinishThreadAbortedTask(delegateRan:false);
+ FinishThreadAbortedTask(delegateRan: false);
}
catch (Exception e)
{
@@ -2041,32 +2035,45 @@ namespace System.Threading.Tasks
/// <summary>
/// Signals completion of this particular task.
///
- /// The bUserDelegateExecuted parameter indicates whether this Finish() call comes following the
+ /// The userDelegateExecute parameter indicates whether this Finish() call comes following the
/// full execution of the user delegate.
///
- /// If bUserDelegateExecuted is false, it mean user delegate wasn't invoked at all (either due to
+ /// If userDelegateExecute is false, it mean user delegate wasn't invoked at all (either due to
/// a cancellation request, or because this task is a promise style Task). In this case, the steps
/// involving child tasks (i.e. WaitForChildren) will be skipped.
///
/// </summary>
- internal void Finish(bool bUserDelegateExecuted)
+ internal void Finish(bool userDelegateExecute)
+ {
+ if (m_contingentProperties == null)
+ {
+ FinishStageTwo();
+ }
+ else
+ {
+ FinishSlow(userDelegateExecute);
+ }
+ }
+
+ private void FinishSlow(bool userDelegateExecute)
{
- if (!bUserDelegateExecuted)
+ Debug.Assert(userDelegateExecute || m_contingentProperties != null);
+
+ if (!userDelegateExecute)
{
// delegate didn't execute => no children. We can safely call the remaining finish stages
FinishStageTwo();
}
else
{
- var props = Volatile.Read(ref m_contingentProperties);
+ ContingentProperties props = m_contingentProperties;
- if (props == null || // no contingent properties means no children, so it's safe to complete ourselves
- (props.m_completionCountdown == 1) ||
- // Count of 1 => either all children finished, or there were none. Safe to complete ourselves
- // without paying the price of an Interlocked.Decrement.
+ // Count of 1 => either all children finished, or there were none. Safe to complete ourselves
+ // without paying the price of an Interlocked.Decrement.
+ if ((props.m_completionCountdown == 1) ||
Interlocked.Decrement(ref props.m_completionCountdown) == 0) // Reaching this sub clause means there may be remaining active children,
- // and we could be racing with one of them to call FinishStageTwo().
- // So whoever does the final Interlocked.Dec is responsible to finish.
+ // and we could be racing with one of them to call FinishStageTwo().
+ // So whoever does the final Interlocked.Dec is responsible to finish.
{
FinishStageTwo();
}
@@ -2086,8 +2093,7 @@ namespace System.Threading.Tasks
// Now is the time to prune exceptional children. We'll walk the list and removes the ones whose exceptions we might have observed after they threw.
// we use a local variable for exceptional children here because some other thread may be nulling out m_contingentProperties.m_exceptionalChildren
- List<Task> exceptionalChildren = props != null ? props.m_exceptionalChildren : null;
-
+ List<Task> exceptionalChildren = props.m_exceptionalChildren;
if (exceptionalChildren != null)
{
lock (exceptionalChildren)
@@ -2106,12 +2112,17 @@ namespace System.Threading.Tasks
/// It can happen i) either on the thread that originally executed this task (if no children were spawned, or they all completed by the time this task's delegate quit)
/// ii) or on the thread that executed the last child.
/// </summary>
- internal void FinishStageTwo()
+ private void FinishStageTwo()
{
- AddExceptionsFromChildren();
-
// At this point, the task is done executing and waiting for its children,
// we can transition our task to a completion state.
+
+ ContingentProperties cp = Volatile.Read(ref m_contingentProperties);
+ if (cp != null)
+ {
+ AddExceptionsFromChildren(cp);
+ }
+
int completionState;
if (ExceptionRecorded)
{
@@ -2160,7 +2171,7 @@ namespace System.Threading.Tasks
// Set the completion event if it's been lazy allocated.
// And if we made a cancellation registration, it's now unnecessary.
- var cp = Volatile.Read(ref m_contingentProperties);
+ cp = Volatile.Read(ref m_contingentProperties); // need to re-read after updating state
if (cp != null)
{
cp.SetCompleted();
@@ -2187,6 +2198,17 @@ namespace System.Threading.Tasks
m_action = null;
// Notify parent if this was an attached task
+ if (m_contingentProperties != null)
+ {
+ NotifyParentIfPotentiallyAttachedTask();
+ }
+
+ // Activate continuations (if any).
+ FinishContinuations();
+ }
+
+ internal void NotifyParentIfPotentiallyAttachedTask()
+ {
Task parent = m_contingentProperties?.m_parent;
if (parent != null
&& ((parent.CreationOptions & TaskCreationOptions.DenyChildAttach) == 0)
@@ -2194,9 +2216,6 @@ namespace System.Threading.Tasks
{
parent.ProcessChildCompletion(this);
}
-
- // Activate continuations (if any).
- FinishContinuations();
}
/// <summary>
@@ -2232,7 +2251,6 @@ namespace System.Threading.Tasks
tmp.Add(childTask);
}
}
-
}
if (Interlocked.Decrement(ref props.m_completionCountdown) == 0)
@@ -2248,14 +2266,15 @@ namespace System.Threading.Tasks
/// This is to be called just before the task does its final state transition.
/// It traverses the list of exceptional children, and appends their aggregate exceptions into this one's exception list
/// </summary>
- internal void AddExceptionsFromChildren()
+ internal void AddExceptionsFromChildren(ContingentProperties props)
{
+ Debug.Assert(props != null);
+
// In rare occurences during AppDomainUnload() processing, it is possible for this method to be called
// simultaneously on the same task from two different contexts. This can result in m_exceptionalChildren
// being nulled out while it is being processed, which could lead to a NullReferenceException. To
// protect ourselves, we'll cache m_exceptionalChildren in a local variable.
- var props = Volatile.Read(ref m_contingentProperties);
- List<Task> exceptionalChildren = props?.m_exceptionalChildren;
+ List<Task> exceptionalChildren = props.m_exceptionalChildren;
if (exceptionalChildren != null)
{
@@ -2310,40 +2329,13 @@ namespace System.Threading.Tasks
Finish(delegateRan);
}
-
- /// <summary>
- /// Executes the task. This method will only be called once, and handles any necessary exception marshaling.
- /// </summary>
- private void Execute()
- {
- try
- {
- InnerInvoke();
- }
- catch (ThreadAbortException tae)
- {
- // Record this exception in the task's exception list
- HandleException(tae);
-
- // This is a ThreadAbortException and it will be rethrown from this catch clause, causing us to
- // skip the regular Finish codepath. In order not to leave the task unfinished, we now call
- // FinishThreadAbortedTask here.
- FinishThreadAbortedTask(delegateRan: true);
- }
- catch (Exception exn)
- {
- // Record this exception in the task's exception list
- HandleException(exn);
- }
- }
-
/// <summary>
/// IThreadPoolWorkItem override, which is the entry function for this task when the TP scheduler decides to run it.
///
/// </summary>
void IThreadPoolWorkItem.ExecuteWorkItem()
{
- ExecuteEntry(false);
+ ExecuteEntryUnsafe();
}
/// <summary>
@@ -2357,46 +2349,58 @@ namespace System.Threading.Tasks
if (!IsCompleted)
{
HandleException(tae);
- FinishThreadAbortedTask(delegateRan:false);
+ FinishThreadAbortedTask(delegateRan: false);
}
}
/// <summary>
/// Outermost entry function to execute this task. Handles all aspects of executing a task on the caller thread.
- /// Currently this is called by IThreadPoolWorkItem.ExecuteWorkItem(), and TaskManager.TryExecuteInline.
- ///
/// </summary>
- /// <param name="bPreventDoubleExecution"> Performs atomic updates to prevent double execution. Should only be set to true
- /// in codepaths servicing user provided TaskSchedulers. The ThreadPool scheduler doesn't need this. </param>
- internal bool ExecuteEntry(bool bPreventDoubleExecution)
+ internal bool ExecuteEntry()
{
- if (bPreventDoubleExecution)
+ // Do atomic state transition from queued to invoked. If we observe a task that's already invoked,
+ // we will return false so that TaskScheduler.ExecuteTask can throw an exception back to the custom scheduler.
+ // However we don't want this exception to be throw if the task was already canceled, because it's a
+ // legitimate scenario for custom schedulers to dequeue a task and mark it as canceled (example: throttling scheduler)
+ int previousState = 0;
+ if (!AtomicStateUpdate(TASK_STATE_DELEGATE_INVOKED,
+ TASK_STATE_DELEGATE_INVOKED | TASK_STATE_COMPLETED_MASK,
+ ref previousState) && (previousState & TASK_STATE_CANCELED) == 0)
{
- int previousState = 0;
+ // This task has already been invoked. Don't invoke it again.
+ return false;
+ }
- // Do atomic state transition from queued to invoked. If we observe a task that's already invoked,
- // we will return false so that TaskScheduler.ExecuteTask can throw an exception back to the custom scheduler.
- // However we don't want this exception to be throw if the task was already canceled, because it's a
- // legitimate scenario for custom schedulers to dequeue a task and mark it as canceled (example: throttling scheduler)
- if (!AtomicStateUpdate(TASK_STATE_DELEGATE_INVOKED,
- TASK_STATE_DELEGATE_INVOKED | TASK_STATE_COMPLETED_MASK,
- ref previousState) && (previousState & TASK_STATE_CANCELED) == 0)
- {
- // This task has already been invoked. Don't invoke it again.
- return false;
- }
+ if (!IsCancellationRequested & !IsCanceled)
+ {
+ ExecuteWithThreadLocal(ref t_currentTask);
}
else
{
- // Remember that we started running the task delegate.
- m_stateFlags |= TASK_STATE_DELEGATE_INVOKED;
+ ExecuteEntryCancellationRequestedOrCanceled();
}
- if (!IsCancellationRequested && !IsCanceled)
+ return true;
+ }
+
+ internal void ExecuteEntryUnsafe() // used instead of ExecuteEntry() when we don't have to worry about double-execution prevent
+ {
+ // Remember that we started running the task delegate.
+ m_stateFlags |= TASK_STATE_DELEGATE_INVOKED;
+
+ if (!IsCancellationRequested & !IsCanceled)
{
ExecuteWithThreadLocal(ref t_currentTask);
}
- else if (!IsCanceled)
+ else
+ {
+ ExecuteEntryCancellationRequestedOrCanceled();
+ }
+ }
+
+ internal void ExecuteEntryCancellationRequestedOrCanceled()
+ {
+ if (!IsCanceled)
{
int prevState = Interlocked.Exchange(ref m_stateFlags, m_stateFlags | TASK_STATE_CANCELED);
if ((prevState & TASK_STATE_CANCELED) == 0)
@@ -2404,8 +2408,6 @@ namespace System.Threading.Tasks
CancellationCleanupLogic();
}
}
-
- return true;
}
// A trick so we can refer to the TLS slot with a byref.
@@ -2429,30 +2431,44 @@ namespace System.Threading.Tasks
etwLog.TaskStarted(TaskScheduler.Current.Id, 0, this.Id);
}
- if (AsyncCausalityTracer.LoggingOn)
+ bool loggingOn = AsyncCausalityTracer.LoggingOn;
+ if (loggingOn)
AsyncCausalityTracer.TraceSynchronousWorkStart(CausalityTraceLevel.Required, this.Id, CausalitySynchronousWork.Execution);
-
try
{
// place the current task into TLS.
currentTaskSlot = this;
- ExecutionContext ec = CapturedContext;
- if (ec == null)
+ // Execute the task body
+ try
{
- // No context, just run the task directly.
- Execute();
+ ExecutionContext ec = CapturedContext;
+ if (ec == null)
+ {
+ // No context, just run the task directly.
+ InnerInvoke();
+ }
+ else
+ {
+ // Invoke it under the captured ExecutionContext
+ ExecutionContext.Run(ec, s_ecCallback, this);
+ }
}
- else
+ catch (Exception exn)
{
- // Run the task. We need a simple shim that converts the
- // object back into a Task object, so that we can Execute it.
-
- ExecutionContext.Run(ec, s_ecCallback, this);
+ // Record this exception in the task's exception list
+ HandleException(exn);
+ if (exn is ThreadAbortException)
+ {
+ // This is a ThreadAbortException and it will be rethrown from this catch clause, causing us to
+ // skip the regular Finish codepath. In order not to leave the task unfinished, we now call
+ // FinishThreadAbortedTask here.
+ FinishThreadAbortedTask(delegateRan: true);
+ }
}
- if (AsyncCausalityTracer.LoggingOn)
+ if (loggingOn)
AsyncCausalityTracer.TraceSynchronousWorkCompletion(CausalityTraceLevel.Required, CausalitySynchronousWork.Execution);
Finish(true);
@@ -2460,7 +2476,7 @@ namespace System.Threading.Tasks
finally
{
currentTaskSlot = previousTask;
-
+
// ETW event for Task Completed
if (etwIsEnabled)
{
@@ -2476,7 +2492,7 @@ namespace System.Threading.Tasks
}
}
- private static readonly ContextCallback s_ecCallback = obj => ((Task)obj).Execute();
+ private static readonly ContextCallback s_ecCallback = obj => ((Task)obj).InnerInvoke();
/// <summary>
/// The actual code which invokes the body of the task. This can be overriden in derived types.
@@ -2973,7 +2989,6 @@ namespace System.Threading.Tasks
{
Thread.SpinWait(PlatformHelper.ProcessorCount * (4 << i));
}
-
}
return IsCompleted;
@@ -3031,12 +3046,10 @@ namespace System.Threading.Tasks
// So we need to remeber whether we actually did the flip, so we can do clean up (finish continuations etc)
mustCleanup = AtomicStateUpdate(TASK_STATE_CANCELED, TASK_STATE_DELEGATE_INVOKED | TASK_STATE_CANCELED);
-
// PS: This is slightly different from the regular cancellation codepath
// since we record the cancellation request *after* doing the state transition.
// However that shouldn't matter too much because the task was never invoked, thus can't have children
}
-
}
if (!bCancelNonExecutingOnly || bPopSucceeded || mustCleanup)
@@ -3125,7 +3138,7 @@ namespace System.Threading.Tasks
oce = edi.SourceException as OperationCanceledException;
Debug.Assert(oce != null, "Expected EDI to contain an OCE");
}
- Debug.Assert(oce.CancellationToken == tokenToRecord,
+ Debug.Assert(oce.CancellationToken == tokenToRecord,
"Expected OCE's token to match the provided token.");
#endif
AddException(cancellationException, representsCancellation: true);
@@ -3191,7 +3204,18 @@ namespace System.Threading.Tasks
{
// Atomically store the fact that this task is completing. From this point on, the adding of continuations will
// result in the continuations being run/launched directly rather than being added to the continuation list.
+ // Then if we grabbed any continuations, run them.
object continuationObject = Interlocked.Exchange(ref m_continuationObject, s_taskCompletionSentinel);
+ if (continuationObject != null)
+ {
+ RunContinuations(continuationObject);
+ }
+ }
+
+ private void RunContinuations(object continuationObject) // separated out of FinishContinuations to enable it to be inlined
+ {
+ Debug.Assert(continuationObject != null);
+
TplEtwProvider etw = TplEtwProvider.Log;
bool tplEtwProviderLoggingEnabled = etw.IsEnabled();
if (tplEtwProviderLoggingEnabled)
@@ -3199,136 +3223,125 @@ namespace System.Threading.Tasks
etw.RunningContinuation(Id, continuationObject);
}
- // If continuationObject == null, then we don't have any continuations to process
- if (continuationObject != null)
- {
-
- if (AsyncCausalityTracer.LoggingOn)
- AsyncCausalityTracer.TraceSynchronousWorkStart(CausalityTraceLevel.Required, this.Id, CausalitySynchronousWork.CompletionNotification);
+ if (AsyncCausalityTracer.LoggingOn)
+ AsyncCausalityTracer.TraceSynchronousWorkStart(CausalityTraceLevel.Required, this.Id, CausalitySynchronousWork.CompletionNotification);
- // Skip synchronous execution of continuations if this task's thread was aborted
- bool bCanInlineContinuations = !(((m_stateFlags & TASK_STATE_THREAD_WAS_ABORTED) != 0) ||
- (Thread.CurrentThread.ThreadState == ThreadState.AbortRequested) ||
- ((m_stateFlags & (int)TaskCreationOptions.RunContinuationsAsynchronously) != 0));
+ // Skip synchronous execution of continuations if this task's thread was aborted
+ bool bCanInlineContinuations = !(((m_stateFlags & TASK_STATE_THREAD_WAS_ABORTED) != 0) ||
+ (Thread.CurrentThread.ThreadState == ThreadState.AbortRequested) ||
+ ((m_stateFlags & (int)TaskCreationOptions.RunContinuationsAsynchronously) != 0));
- // Handle the single-Action case
- Action singleAction = continuationObject as Action;
- if (singleAction != null)
- {
- AwaitTaskContinuation.RunOrScheduleAction(singleAction, bCanInlineContinuations, ref t_currentTask);
- LogFinishCompletionNotification();
- return;
- }
+ // Handle the single-Action case
+ Action singleAction = continuationObject as Action;
+ if (singleAction != null)
+ {
+ AwaitTaskContinuation.RunOrScheduleAction(singleAction, bCanInlineContinuations, ref t_currentTask);
+ LogFinishCompletionNotification();
+ return;
+ }
- // Handle the single-ITaskCompletionAction case
- ITaskCompletionAction singleTaskCompletionAction = continuationObject as ITaskCompletionAction;
- if (singleTaskCompletionAction != null)
+ // Handle the single-ITaskCompletionAction case
+ ITaskCompletionAction singleTaskCompletionAction = continuationObject as ITaskCompletionAction;
+ if (singleTaskCompletionAction != null)
+ {
+ if (bCanInlineContinuations || !singleTaskCompletionAction.InvokeMayRunArbitraryCode)
{
- if (bCanInlineContinuations || !singleTaskCompletionAction.InvokeMayRunArbitraryCode)
- {
- singleTaskCompletionAction.Invoke(this);
- }
- else
- {
- ThreadPool.UnsafeQueueCustomWorkItem(new CompletionActionInvoker(singleTaskCompletionAction, this), forceGlobal: false);
- }
- LogFinishCompletionNotification();
- return;
+ singleTaskCompletionAction.Invoke(this);
}
-
- // Handle the single-TaskContinuation case
- TaskContinuation singleTaskContinuation = continuationObject as TaskContinuation;
- if (singleTaskContinuation != null)
+ else
{
- singleTaskContinuation.Run(this, bCanInlineContinuations);
- LogFinishCompletionNotification();
- return;
+ ThreadPool.UnsafeQueueCustomWorkItem(new CompletionActionInvoker(singleTaskCompletionAction, this), forceGlobal: false);
}
+ LogFinishCompletionNotification();
+ return;
+ }
- // Not a single; attempt to cast as list
- List<object> continuations = continuationObject as List<object>;
+ // Handle the single-TaskContinuation case
+ TaskContinuation singleTaskContinuation = continuationObject as TaskContinuation;
+ if (singleTaskContinuation != null)
+ {
+ singleTaskContinuation.Run(this, bCanInlineContinuations);
+ LogFinishCompletionNotification();
+ return;
+ }
- if (continuations == null)
- {
- LogFinishCompletionNotification();
- return; // Not a single or a list; just return
- }
+ // Not a single; it must be a list.
+ List<object> continuations = (List<object>)continuationObject;
- //
- // Begin processing of continuation list
- //
+ //
+ // Begin processing of continuation list
+ //
- // Wait for any concurrent adds or removes to be retired
- lock (continuations) { }
- int continuationCount = continuations.Count;
+ // Wait for any concurrent adds or removes to be retired
+ lock (continuations) { }
+ int continuationCount = continuations.Count;
- // Fire the asynchronous continuations first ...
- for (int i = 0; i < continuationCount; i++)
+ // Fire the asynchronous continuations first ...
+ for (int i = 0; i < continuationCount; i++)
+ {
+ // Synchronous continuation tasks will have the ExecuteSynchronously option,
+ // and we're looking for asynchronous tasks...
+ var tc = continuations[i] as StandardTaskContinuation;
+ if (tc != null && (tc.m_options & TaskContinuationOptions.ExecuteSynchronously) == 0)
{
- // Synchronous continuation tasks will have the ExecuteSynchronously option,
- // and we're looking for asynchronous tasks...
- var tc = continuations[i] as StandardTaskContinuation;
- if (tc != null && (tc.m_options & TaskContinuationOptions.ExecuteSynchronously) == 0)
+ if (tplEtwProviderLoggingEnabled)
{
- if (tplEtwProviderLoggingEnabled)
- {
- etw.RunningContinuationList(Id, i, tc);
- }
- continuations[i] = null; // so that we can skip this later
- tc.Run(this, bCanInlineContinuations);
+ etw.RunningContinuationList(Id, i, tc);
}
+ continuations[i] = null; // so that we can skip this later
+ tc.Run(this, bCanInlineContinuations);
}
+ }
- // ... and then fire the synchronous continuations (if there are any).
- // This includes ITaskCompletionAction, AwaitTaskContinuations, and
- // Action delegates, which are all by default implicitly synchronous.
- for (int i = 0; i < continuationCount; i++)
+ // ... and then fire the synchronous continuations (if there are any).
+ // This includes ITaskCompletionAction, AwaitTaskContinuations, and
+ // Action delegates, which are all by default implicitly synchronous.
+ for (int i = 0; i < continuationCount; i++)
+ {
+ object currentContinuation = continuations[i];
+ if (currentContinuation == null) continue;
+ continuations[i] = null; // to enable free'ing up memory earlier
+ if (tplEtwProviderLoggingEnabled)
{
- object currentContinuation = continuations[i];
- if (currentContinuation == null) continue;
- continuations[i] = null; // to enable free'ing up memory earlier
- if (tplEtwProviderLoggingEnabled)
- {
- etw.RunningContinuationList(Id, i, currentContinuation);
- }
+ etw.RunningContinuationList(Id, i, currentContinuation);
+ }
- // If the continuation is an Action delegate, it came from an await continuation,
- // and we should use AwaitTaskContinuation to run it.
- Action ad = currentContinuation as Action;
- if (ad != null)
+ // If the continuation is an Action delegate, it came from an await continuation,
+ // and we should use AwaitTaskContinuation to run it.
+ Action ad = currentContinuation as Action;
+ if (ad != null)
+ {
+ AwaitTaskContinuation.RunOrScheduleAction(ad, bCanInlineContinuations, ref t_currentTask);
+ }
+ else
+ {
+ // If it's a TaskContinuation object of some kind, invoke it.
+ TaskContinuation tc = currentContinuation as TaskContinuation;
+ if (tc != null)
{
- AwaitTaskContinuation.RunOrScheduleAction(ad, bCanInlineContinuations, ref t_currentTask);
+ // We know that this is a synchronous continuation because the
+ // asynchronous ones have been weeded out
+ tc.Run(this, bCanInlineContinuations);
}
+ // Otherwise, it must be an ITaskCompletionAction, so invoke it.
else
{
- // If it's a TaskContinuation object of some kind, invoke it.
- TaskContinuation tc = currentContinuation as TaskContinuation;
- if (tc != null)
+ Debug.Assert(currentContinuation is ITaskCompletionAction, "Expected continuation element to be Action, TaskContinuation, or ITaskContinuationAction");
+ var action = (ITaskCompletionAction)currentContinuation;
+
+ if (bCanInlineContinuations || !action.InvokeMayRunArbitraryCode)
{
- // We know that this is a synchronous continuation because the
- // asynchronous ones have been weeded out
- tc.Run(this, bCanInlineContinuations);
+ action.Invoke(this);
}
- // Otherwise, it must be an ITaskCompletionAction, so invoke it.
else
{
- Debug.Assert(currentContinuation is ITaskCompletionAction, "Expected continuation element to be Action, TaskContinuation, or ITaskContinuationAction");
- var action = (ITaskCompletionAction)currentContinuation;
-
- if (bCanInlineContinuations || !action.InvokeMayRunArbitraryCode)
- {
- action.Invoke(this);
- }
- else
- {
- ThreadPool.UnsafeQueueCustomWorkItem(new CompletionActionInvoker(action, this), forceGlobal: false);
- }
+ ThreadPool.UnsafeQueueCustomWorkItem(new CompletionActionInvoker(action, this), forceGlobal: false);
}
}
}
-
- LogFinishCompletionNotification();
}
+
+ LogFinishCompletionNotification();
}
private void LogFinishCompletionNotification()
@@ -4140,29 +4153,29 @@ namespace System.Threading.Tasks
out InternalTaskOptions internalOptions)
{
// This is used a couple of times below
- TaskContinuationOptions NotOnAnything =
+ const TaskContinuationOptions NotOnAnything =
TaskContinuationOptions.NotOnCanceled |
TaskContinuationOptions.NotOnFaulted |
TaskContinuationOptions.NotOnRanToCompletion;
- TaskContinuationOptions creationOptionsMask =
+ const TaskContinuationOptions CreationOptionsMask =
TaskContinuationOptions.PreferFairness |
TaskContinuationOptions.LongRunning |
TaskContinuationOptions.DenyChildAttach |
TaskContinuationOptions.HideScheduler |
- TaskContinuationOptions.AttachedToParent|
+ TaskContinuationOptions.AttachedToParent |
TaskContinuationOptions.RunContinuationsAsynchronously;
// Check that LongRunning and ExecuteSynchronously are not specified together
- TaskContinuationOptions illegalMask = TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.LongRunning;
- if ((continuationOptions & illegalMask) == illegalMask)
+ const TaskContinuationOptions IllegalMask = TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.LongRunning;
+ if ((continuationOptions & IllegalMask) == IllegalMask)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.continuationOptions, ExceptionResource.Task_ContinueWith_ESandLR);
}
// Check that no illegal options were specified
if ((continuationOptions &
- ~(creationOptionsMask | NotOnAnything |
+ ~(CreationOptionsMask | NotOnAnything |
TaskContinuationOptions.LazyCancellation | TaskContinuationOptions.ExecuteSynchronously)) != 0)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.continuationOptions);
@@ -4175,14 +4188,12 @@ namespace System.Threading.Tasks
}
// This passes over all but LazyCancellation, which has no representation in TaskCreationOptions
- creationOptions = (TaskCreationOptions)(continuationOptions & creationOptionsMask);
-
- // internalOptions has at least ContinuationTask ...
- internalOptions = InternalTaskOptions.ContinuationTask;
+ creationOptions = (TaskCreationOptions)(continuationOptions & CreationOptionsMask);
- // ... and possibly LazyCancellation
- if ((continuationOptions & TaskContinuationOptions.LazyCancellation) != 0)
- internalOptions |= InternalTaskOptions.LazyCancellation;
+ // internalOptions has at least ContinuationTask and possibly LazyCancellation
+ internalOptions = (continuationOptions & TaskContinuationOptions.LazyCancellation) != 0 ?
+ InternalTaskOptions.ContinuationTask | InternalTaskOptions.LazyCancellation :
+ InternalTaskOptions.ContinuationTask;
}
@@ -4417,7 +4428,6 @@ namespace System.Threading.Tasks
{
// null out that TaskContinuation entry, which will be interpreted as "to be cleaned up"
continuationsLocalListRef[index] = null;
-
}
}
}
@@ -4500,7 +4510,6 @@ namespace System.Threading.Tasks
}
return WaitAll(tasks, (int)totalMilliseconds);
-
}
/// <summary>
@@ -5020,6 +5029,10 @@ namespace System.Threading.Tasks
signaledTaskIndex = Array.IndexOf(tasks, firstCompleted.Result);
Debug.Assert(signaledTaskIndex >= 0);
}
+ else
+ {
+ TaskFactory.CommonCWAnyLogicCleanup(firstCompleted);
+ }
}
// We need to prevent the tasks array from being GC'ed until we come out of the wait.
@@ -5103,7 +5116,7 @@ namespace System.Threading.Tasks
Debug.Assert(succeeded, "This should always succeed on a new task.");
return task;
}
-
+
/// <summary>Creates a <see cref="Task"/> that's completed due to cancellation with the specified token.</summary>
/// <param name="cancellationToken">The token with which to complete the task.</param>
/// <returns>The canceled task.</returns>
@@ -5112,7 +5125,7 @@ namespace System.Threading.Tasks
{
return FromCanceled(cancellationToken);
}
-
+
/// <summary>Creates a <see cref="Task{TResult}"/> that's completed due to cancellation with the specified token.</summary>
/// <typeparam name="TResult">The type of the result returned by the task.</typeparam>
/// <param name="cancellationToken">The token with which to complete the task.</param>
@@ -5122,7 +5135,7 @@ namespace System.Threading.Tasks
{
return FromCanceled<TResult>(cancellationToken);
}
-
+
#endregion
#region Run methods
@@ -6120,8 +6133,8 @@ namespace System.Threading.Tasks
internal virtual Delegate[] GetDelegateContinuationsForDebugger()
{
//Avoid an infinite loop by making sure the continuation object is not a reference to istelf.
- if (this.m_continuationObject != this)
- return GetDelegatesFromContinuationObject(this.m_continuationObject);
+ if (m_continuationObject != this)
+ return GetDelegatesFromContinuationObject(m_continuationObject);
else
return null;
}
@@ -6192,11 +6205,8 @@ namespace System.Threading.Tasks
private static Task[] GetActiveTasks()
{
-
return new List<Task>(s_currentActiveTasks.Values).ToArray();
}
-
-
}
internal sealed class CompletionActionInvoker : IThreadPoolWorkItem
@@ -6715,5 +6725,4 @@ namespace System.Threading.Tasks
public bool InvokeMayRunArbitraryCode { get { return true; } }
}
-
}
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskCanceledException.cs b/src/mscorlib/src/System/Threading/Tasks/TaskCanceledException.cs
deleted file mode 100644
index f15e3e783a..0000000000
--- a/src/mscorlib/src/System/Threading/Tasks/TaskCanceledException.cs
+++ /dev/null
@@ -1,93 +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.
-
-// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-//
-//
-//
-// An exception for task cancellations.
-//
-// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-using System;
-using System.Runtime.InteropServices;
-using System.Runtime.Serialization;
-
-namespace System.Threading.Tasks
-{
-
- /// <summary>
- /// Represents an exception used to communicate task cancellation.
- /// </summary>
- [Serializable]
- public class TaskCanceledException : OperationCanceledException
- {
-
- [NonSerialized]
- private Task m_canceledTask; // The task which has been canceled.
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskCanceledException"/> class.
- /// </summary>
- public TaskCanceledException() : base(Environment.GetResourceString("TaskCanceledException_ctor_DefaultMessage"))
- {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskCanceledException"/>
- /// class with a specified error message.
- /// </summary>
- /// <param name="message">The error message that explains the reason for the exception.</param>
- public TaskCanceledException(string message) : base(message)
- {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskCanceledException"/>
- /// class with a specified error message and a reference to the inner exception that is the cause of
- /// this exception.
- /// </summary>
- /// <param name="message">The error message that explains the reason for the exception.</param>
- /// <param name="innerException">The exception that is the cause of the current exception.</param>
- public TaskCanceledException(string message, Exception innerException) : base(message, innerException)
- {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskCanceledException"/> class
- /// with a reference to the <see cref="T:System.Threading.Tasks.Task"/> that has been canceled.
- /// </summary>
- /// <param name="task">A task that has been canceled.</param>
- public TaskCanceledException(Task task) :
- base(Environment.GetResourceString("TaskCanceledException_ctor_DefaultMessage"), task!=null ? task.CancellationToken:new CancellationToken())
- {
- m_canceledTask = task;
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskCanceledException"/>
- /// class with serialized data.
- /// </summary>
- /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
- /// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination. </param>
- protected TaskCanceledException(SerializationInfo info, StreamingContext context) : base(info, context)
- {
- }
-
- /// <summary>
- /// Gets the task associated with this exception.
- /// </summary>
- /// <remarks>
- /// It is permissible for no Task to be associated with a
- /// <see cref="T:System.Threading.Tasks.TaskCanceledException"/>, in which case
- /// this property will return null.
- /// </remarks>
- public Task Task
- {
- get { return m_canceledTask; }
- }
-
- }
-
-}
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs b/src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs
index bf9f9cbb2c..0c80afd22c 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs
@@ -131,7 +131,7 @@ namespace System.Threading.Tasks
{
// Spin wait until the completion is finalized by another thread.
var sw = new SpinWait();
- while (!m_task.IsCompleted)
+ while (!m_task.IsCompleted)
sw.SpinOnce();
}
@@ -185,7 +185,7 @@ namespace System.Threading.Tasks
public bool TrySetException(IEnumerable<Exception> exceptions)
{
if (exceptions == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.exceptions);
-
+
List<Exception> defensiveCopy = new List<Exception>();
foreach (Exception e in exceptions)
{
@@ -276,7 +276,7 @@ namespace System.Threading.Tasks
public bool TrySetResult(TResult result)
{
bool rval = m_task.TrySetResult(result);
- if (!rval && !m_task.IsCompleted) SpinUntilCompleted();
+ if (!rval) SpinUntilCompleted();
return rval;
}
@@ -346,7 +346,7 @@ namespace System.Threading.Tasks
/// <exception cref="T:System.ObjectDisposedException">The <see cref="Task"/> was disposed.</exception>
public void SetCanceled()
{
- if(!TrySetCanceled())
+ if (!TrySetCanceled())
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.TaskT_TransitionToFinal_AlreadyCompleted);
}
}
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskContinuation.cs b/src/mscorlib/src/System/Threading/Tasks/TaskContinuation.cs
index 3c6ccd8dd4..848a0ecbc2 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TaskContinuation.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/TaskContinuation.cs
@@ -32,7 +32,7 @@ namespace System.Threading.Tasks
Task antecedent, Delegate action, object state, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions) :
base(action, state, Task.InternalCurrentIfAttached(creationOptions), default(CancellationToken), creationOptions, internalOptions, null)
{
- Contract.Requires(action is Action<Task> || action is Action<Task, object>,
+ Contract.Requires(action is Action<Task> || action is Action<Task, object>,
"Invalid delegate type in ContinuationTaskFromTask");
m_antecedent = antecedent;
}
@@ -45,7 +45,7 @@ namespace System.Threading.Tasks
// Get and null out the antecedent. This is crucial to avoid a memory
// leak with long chains of continuations.
var antecedent = m_antecedent;
- Debug.Assert(antecedent != null,
+ Debug.Assert(antecedent != null,
"No antecedent was set for the ContinuationTaskFromTask.");
m_antecedent = null;
@@ -79,7 +79,7 @@ namespace System.Threading.Tasks
Task antecedent, Delegate function, object state, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions) :
base(function, state, Task.InternalCurrentIfAttached(creationOptions), default(CancellationToken), creationOptions, internalOptions, null)
{
- Contract.Requires(function is Func<Task, TResult> || function is Func<Task, object, TResult>,
+ Contract.Requires(function is Func<Task, TResult> || function is Func<Task, object, TResult>,
"Invalid delegate type in ContinuationResultTaskFromTask");
m_antecedent = antecedent;
}
@@ -92,7 +92,7 @@ namespace System.Threading.Tasks
// Get and null out the antecedent. This is crucial to avoid a memory
// leak with long chains of continuations.
var antecedent = m_antecedent;
- Debug.Assert(antecedent != null,
+ Debug.Assert(antecedent != null,
"No antecedent was set for the ContinuationResultTaskFromTask.");
m_antecedent = null;
@@ -126,7 +126,7 @@ namespace System.Threading.Tasks
Task<TAntecedentResult> antecedent, Delegate action, object state, TaskCreationOptions creationOptions, InternalTaskOptions internalOptions) :
base(action, state, Task.InternalCurrentIfAttached(creationOptions), default(CancellationToken), creationOptions, internalOptions, null)
{
- Contract.Requires(action is Action<Task<TAntecedentResult>> || action is Action<Task<TAntecedentResult>, object>,
+ Contract.Requires(action is Action<Task<TAntecedentResult>> || action is Action<Task<TAntecedentResult>, object>,
"Invalid delegate type in ContinuationTaskFromResultTask");
m_antecedent = antecedent;
}
@@ -139,7 +139,7 @@ namespace System.Threading.Tasks
// Get and null out the antecedent. This is crucial to avoid a memory
// leak with long chains of continuations.
var antecedent = m_antecedent;
- Debug.Assert(antecedent != null,
+ Debug.Assert(antecedent != null,
"No antecedent was set for the ContinuationTaskFromResultTask.");
m_antecedent = null;
@@ -186,7 +186,7 @@ namespace System.Threading.Tasks
// Get and null out the antecedent. This is crucial to avoid a memory
// leak with long chains of continuations.
var antecedent = m_antecedent;
- Debug.Assert(antecedent != null,
+ Debug.Assert(antecedent != null,
"No antecedent was set for the ContinuationResultTaskFromResultTask.");
m_antecedent = null;
@@ -276,7 +276,6 @@ namespace System.Threading.Tasks
}
internal abstract Delegate[] GetDelegateContinuationsForDebugger();
-
}
/// <summary>Provides the standard implementation of a task continuation.</summary>
@@ -505,7 +504,8 @@ namespace System.Threading.Tasks
// Create the continuation task task. If we're allowed to inline, try to do so.
// The target scheduler may still deny us from executing on this thread, in which case this'll be queued.
- var task = CreateTask(state => {
+ var task = CreateTask(state =>
+ {
try { ((Action)state)(); }
catch (Exception exc) { ThrowAsyncIfNecessary(exc); }
}, m_action, m_scheduler);
@@ -558,10 +558,10 @@ namespace System.Threading.Tasks
Contract.Requires(scheduler != null);
return new Task(
- action, state, null, default(CancellationToken),
- TaskCreationOptions.None, InternalTaskOptions.QueuedByRuntime, scheduler)
- {
- CapturedContext = m_capturedContext
+ action, state, null, default(CancellationToken),
+ TaskCreationOptions.None, InternalTaskOptions.QueuedByRuntime, scheduler)
+ {
+ CapturedContext = m_capturedContext
};
}
@@ -590,7 +590,7 @@ namespace System.Threading.Tasks
// We couldn't inline, so now we need to schedule it
ThreadPool.UnsafeQueueCustomWorkItem(this, forceGlobal: false);
- }
+ }
}
/// <summary>
@@ -626,7 +626,7 @@ namespace System.Threading.Tasks
}
/// <summary>IThreadPoolWorkItem override, which is the entry function for this when the ThreadPool scheduler decides to run it.</summary>
- void ExecuteWorkItemHelper()
+ private void ExecuteWorkItemHelper()
{
var etwLog = TplEtwProvider.Log;
Guid savedActivityId = Guid.Empty;
@@ -645,7 +645,7 @@ namespace System.Threading.Tasks
{
m_action();
}
- // If there is an execution context, get the cached delegate and run the action under the context.
+ // If there is an execution context, get the cached delegate and run the action under the context.
else
{
ExecutionContext.Run(m_capturedContext, GetInvokeActionCallback(), m_action);
@@ -815,5 +815,4 @@ namespace System.Threading.Tasks
return new Delegate[] { AsyncMethodBuilderCore.TryGetStateMachineForDebugger(m_action) };
}
}
-
}
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskExceptionHolder.cs b/src/mscorlib/src/System/Threading/Tasks/TaskExceptionHolder.cs
index ee1112a93f..1385d907e0 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TaskExceptionHolder.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/TaskExceptionHolder.cs
@@ -70,9 +70,9 @@ namespace System.Threading.Tasks
private static void EnsureADUnloadCallbackRegistered()
{
- if (s_adUnloadEventHandler == null &&
- Interlocked.CompareExchange( ref s_adUnloadEventHandler,
- AppDomainUnloadCallback,
+ if (s_adUnloadEventHandler == null &&
+ Interlocked.CompareExchange(ref s_adUnloadEventHandler,
+ AppDomainUnloadCallback,
null) == null)
{
AppDomain.CurrentDomain.DomainUnload += s_adUnloadEventHandler;
@@ -93,7 +93,7 @@ namespace System.Threading.Tasks
// We need to do this filtering because all TaskExceptionHolders will be finalized during shutdown or unload
// regardles of reachability of the task (i.e. even if the user code was about to observe the task's exception),
// which can otherwise lead to spurious crashes during shutdown.
- if (m_faultExceptions != null && !m_isHandled &&
+ if (m_faultExceptions != null && !m_isHandled &&
!Environment.HasShutdownStarted && !AppDomain.CurrentDomain.IsFinalizingForUnload() && !s_domainUnloadStarted)
{
// We don't want to crash the finalizer thread if any ThreadAbortExceptions
@@ -124,14 +124,14 @@ namespace System.Threading.Tasks
// will have been marked as handled before even getting here.
// Give users a chance to keep this exception from crashing the process
-
+
// First, publish the unobserved exception and allow users to observe it
AggregateException exceptionToThrow = new AggregateException(
- Environment.GetResourceString("TaskExceptionHolder_UnhandledException"),
+ SR.TaskExceptionHolder_UnhandledException,
m_faultExceptions);
UnobservedTaskExceptionEventArgs ueea = new UnobservedTaskExceptionEventArgs(exceptionToThrow);
TaskScheduler.PublishUnobservedTaskException(m_task, ueea);
-
+
// Now, if we are still unobserved and we're configured to crash on unobserved, throw the exception.
// We need to publish the event above even if we're not going to crash, hence
// why this check doesn't come at the beginning of the method.
@@ -164,7 +164,7 @@ namespace System.Threading.Tasks
{
Contract.Requires(exceptionObject != null, "TaskExceptionHolder.Add(): Expected a non-null exceptionObject");
Contract.Requires(
- exceptionObject is Exception || exceptionObject is IEnumerable<Exception> ||
+ exceptionObject is Exception || exceptionObject is IEnumerable<Exception> ||
exceptionObject is ExceptionDispatchInfo || exceptionObject is IEnumerable<ExceptionDispatchInfo>,
"TaskExceptionHolder.Add(): Expected Exception, IEnumerable<Exception>, ExceptionDispatchInfo, or IEnumerable<ExceptionDispatchInfo>");
@@ -180,16 +180,16 @@ namespace System.Threading.Tasks
private void SetCancellationException(object exceptionObject)
{
Contract.Requires(exceptionObject != null, "Expected exceptionObject to be non-null.");
-
- Debug.Assert(m_cancellationException == null,
+
+ Debug.Assert(m_cancellationException == null,
"Expected SetCancellationException to be called only once.");
- // Breaking this assumption will overwrite a previously OCE,
- // and implies something may be wrong elsewhere, since there should only ever be one.
+ // Breaking this assumption will overwrite a previously OCE,
+ // and implies something may be wrong elsewhere, since there should only ever be one.
- Debug.Assert(m_faultExceptions == null,
+ Debug.Assert(m_faultExceptions == null,
"Expected SetCancellationException to be called before any faults were added.");
- // Breaking this assumption shouldn't hurt anything here, but it implies something may be wrong elsewhere.
- // If this changes, make sure to only conditionally mark as handled below.
+ // Breaking this assumption shouldn't hurt anything here, but it implies something may be wrong elsewhere.
+ // If this changes, make sure to only conditionally mark as handled below.
// Store the cancellation exception
var oce = exceptionObject as OperationCanceledException;
@@ -267,21 +267,21 @@ namespace System.Threading.Tasks
exceptions.AddRange(ediColl);
#if DEBUG
Debug.Assert(exceptions.Count > 0, "There should be at least one dispatch info.");
- foreach(var tmp in exceptions)
+ foreach (var tmp in exceptions)
{
Debug.Assert(tmp != null, "No dispatch infos should be null");
}
#endif
}
- // Anything else is a programming error
+ // Anything else is a programming error
else
{
- throw new ArgumentException(Environment.GetResourceString("TaskExceptionHolder_UnknownExceptionType"), nameof(exceptionObject));
+ throw new ArgumentException(SR.TaskExceptionHolder_UnknownExceptionType, nameof(exceptionObject));
}
}
}
}
-
+
// If all of the exceptions are ThreadAbortExceptions and/or
// AppDomainUnloadExceptions, we do not want the finalization
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs b/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs
index 89ba2988ca..e193d0e4e2 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/TaskFactory.cs
@@ -40,30 +40,20 @@ namespace System.Threading.Tasks
public class TaskFactory
{
// member variables
- private CancellationToken m_defaultCancellationToken;
- private TaskScheduler m_defaultScheduler;
- private TaskCreationOptions m_defaultCreationOptions;
- private TaskContinuationOptions m_defaultContinuationOptions;
+ private readonly CancellationToken m_defaultCancellationToken;
+ private readonly TaskScheduler m_defaultScheduler;
+ private readonly TaskCreationOptions m_defaultCreationOptions;
+ private readonly TaskContinuationOptions m_defaultContinuationOptions;
-
- private TaskScheduler DefaultScheduler
- {
- get
- {
- if (m_defaultScheduler == null) return TaskScheduler.Current;
- else return m_defaultScheduler;
- }
- }
+ private TaskScheduler DefaultScheduler => m_defaultScheduler ?? TaskScheduler.Current;
// sister method to above property -- avoids a TLS lookup
private TaskScheduler GetDefaultScheduler(Task currTask)
{
- if (m_defaultScheduler != null) return m_defaultScheduler;
- else if ((currTask != null)
- && ((currTask.CreationOptions & TaskCreationOptions.HideScheduler) == 0)
- )
- return currTask.ExecutingTaskScheduler;
- else return TaskScheduler.Default;
+ return
+ m_defaultScheduler ??
+ (currTask != null && (currTask.CreationOptions & TaskCreationOptions.HideScheduler) == 0 ? currTask.ExecutingTaskScheduler :
+ TaskScheduler.Default);
}
/* Constructors */
@@ -1528,9 +1518,9 @@ namespace System.Threading.Tasks
{
// Options detected here cause exceptions in FromAsync methods that take beginMethod as a parameter
if ((creationOptions & TaskCreationOptions.LongRunning) != 0)
- throw new ArgumentOutOfRangeException(nameof(creationOptions), Environment.GetResourceString("Task_FromAsync_LongRunning"));
+ throw new ArgumentOutOfRangeException(nameof(creationOptions), SR.Task_FromAsync_LongRunning);
if ((creationOptions & TaskCreationOptions.PreferFairness) != 0)
- throw new ArgumentOutOfRangeException(nameof(creationOptions), Environment.GetResourceString("Task_FromAsync_PreferFairness"));
+ throw new ArgumentOutOfRangeException(nameof(creationOptions), SR.Task_FromAsync_PreferFairness);
}
// Check for general validity of options
@@ -2325,7 +2315,7 @@ namespace System.Threading.Tasks
{
Contract.Requires(tasks != null, "Expected non-null collection of tasks");
_tasks = tasks;
-
+
if (AsyncCausalityTracer.LoggingOn)
AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, this.Id, "TaskFactory.ContinueWhenAny", 0);
@@ -2337,7 +2327,8 @@ namespace System.Threading.Tasks
public void Invoke(Task completingTask)
{
- if (Interlocked.CompareExchange(ref m_firstTaskAlreadyCompleted, 1, 0) == 0)
+ if (m_firstTaskAlreadyCompleted == 0 &&
+ Interlocked.Exchange(ref m_firstTaskAlreadyCompleted, 1) == 0)
{
if (AsyncCausalityTracer.LoggingOn)
{
@@ -2367,7 +2358,6 @@ namespace System.Threading.Tasks
!task.IsCompleted) task.RemoveContinuation(this);
}
_tasks = null;
-
}
}
@@ -2382,17 +2372,18 @@ namespace System.Threading.Tasks
{
Contract.Requires(tasks != null);
- // Create a promise task to be returned to the user
+ // Create a promise task to be returned to the user.
+ // (If this logic ever changes, also update CommonCWAnyLogicCleanup.)
var promise = new CompleteOnInvokePromise(tasks);
// At the completion of any of the tasks, complete the promise.
bool checkArgsOnly = false;
int numTasks = tasks.Count;
- for(int i=0; i<numTasks; i++)
+ for (int i = 0; i < numTasks; i++)
{
var task = tasks[i];
- if (task == null) throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), nameof(tasks));
+ if (task == null) throw new ArgumentException(SR.Task_MultiTaskContinuation_NullTask, nameof(tasks));
if (checkArgsOnly) continue;
@@ -2430,6 +2421,17 @@ namespace System.Threading.Tasks
return promise;
}
+ /// <summary>
+ /// Cleans up the operations performed by CommonCWAnyLogic in a case where
+ /// the created continuation task is being discarded.
+ /// </summary>
+ /// <param name="continuation">The task returned from CommonCWAnyLogic.</param>
+ internal static void CommonCWAnyLogicCleanup(Task<Task> continuation)
+ {
+ // Force cleanup of the promise (e.g. removing continuations from each
+ // constituent task), by completing the promise with any value.
+ ((CompleteOnInvokePromise)continuation).Invoke(null);
+ }
/// <summary>
/// Creates a continuation <see cref="T:System.Threading.Tasks.Task">Task</see>
@@ -2663,7 +2665,7 @@ namespace System.Threading.Tasks
if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
- return TaskFactory<TResult>.ContinueWhenAnyImpl(tasks, continuationFunction, null,continuationOptions, m_defaultCancellationToken, DefaultScheduler);
+ return TaskFactory<TResult>.ContinueWhenAnyImpl(tasks, continuationFunction, null, continuationOptions, m_defaultCancellationToken, DefaultScheduler);
}
/// <summary>
@@ -2775,7 +2777,7 @@ namespace System.Threading.Tasks
if (continuationFunction == null) throw new ArgumentNullException(nameof(continuationFunction));
Contract.EndContractBlock();
- return TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, continuationFunction, null, m_defaultContinuationOptions, cancellationToken, DefaultScheduler);
+ return TaskFactory<TResult>.ContinueWhenAnyImpl<TAntecedentResult>(tasks, continuationFunction, null, m_defaultContinuationOptions, cancellationToken, DefaultScheduler);
}
/// <summary>
@@ -3018,7 +3020,7 @@ namespace System.Threading.Tasks
if (tasks == null)
throw new ArgumentNullException(nameof(tasks));
if (tasks.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), nameof(tasks));
+ throw new ArgumentException(SR.Task_MultiTaskContinuation_EmptyTaskList, nameof(tasks));
Contract.EndContractBlock();
Task[] tasksCopy = new Task[tasks.Length];
@@ -3027,7 +3029,7 @@ namespace System.Threading.Tasks
tasksCopy[i] = tasks[i];
if (tasksCopy[i] == null)
- throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), nameof(tasks));
+ throw new ArgumentException(SR.Task_MultiTaskContinuation_NullTask, nameof(tasks));
}
return tasksCopy;
@@ -3038,7 +3040,7 @@ namespace System.Threading.Tasks
if (tasks == null)
throw new ArgumentNullException(nameof(tasks));
if (tasks.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_EmptyTaskList"), nameof(tasks));
+ throw new ArgumentException(SR.Task_MultiTaskContinuation_EmptyTaskList, nameof(tasks));
Contract.EndContractBlock();
Task<TResult>[] tasksCopy = new Task<TResult>[tasks.Length];
@@ -3047,7 +3049,7 @@ namespace System.Threading.Tasks
tasksCopy[i] = tasks[i];
if (tasksCopy[i] == null)
- throw new ArgumentException(Environment.GetResourceString("Task_MultiTaskContinuation_NullTask"), nameof(tasks));
+ throw new ArgumentException(SR.Task_MultiTaskContinuation_NullTask, nameof(tasks));
}
return tasksCopy;
@@ -3066,7 +3068,7 @@ namespace System.Threading.Tasks
const TaskContinuationOptions illegalMask = TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.LongRunning;
if ((continuationOptions & illegalMask) == illegalMask)
{
- throw new ArgumentOutOfRangeException(nameof(continuationOptions), Environment.GetResourceString("Task_ContinueWith_ESandLR"));
+ throw new ArgumentOutOfRangeException(nameof(continuationOptions), SR.Task_ContinueWith_ESandLR);
}
// Check that no nonsensical options are specified.
@@ -3085,9 +3087,8 @@ namespace System.Threading.Tasks
// Check that no "fire" options are specified.
if ((continuationOptions & NotOnAny) != 0)
- throw new ArgumentOutOfRangeException(nameof(continuationOptions), Environment.GetResourceString("Task_MultiTaskContinuation_FireOptions"));
+ throw new ArgumentOutOfRangeException(nameof(continuationOptions), SR.Task_MultiTaskContinuation_FireOptions);
Contract.EndContractBlock();
}
}
-
}
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs b/src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs
index d68c3fedc4..45d398f0eb 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/TaskScheduler.cs
@@ -11,6 +11,7 @@
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
// Disable the "reference to volatile field not treated as volatile" error.
#pragma warning disable 0420
+
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -23,7 +24,6 @@ using System.Runtime.CompilerServices;
namespace System.Threading.Tasks
{
-
/// <summary>
/// Represents an abstract scheduler for tasks.
/// </summary>
@@ -46,7 +46,7 @@ namespace System.Threading.Tasks
//
// User Provided Methods and Properties
//
-
+
/// <summary>
/// Queues a <see cref="T:System.Threading.Tasks.Task">Task</see> to the scheduler.
/// </summary>
@@ -168,7 +168,7 @@ namespace System.Threading.Tasks
//
// Internal overridable methods
//
-
+
/// <summary>
/// Attempts to execute the target task synchronously.
@@ -183,14 +183,14 @@ namespace System.Threading.Tasks
// Do not inline TaskCompletionSource-style (a.k.a. "promise") tasks.
// No need to attempt inlining if the task body was already run (i.e. either TASK_STATE_DELEGATE_INVOKED or TASK_STATE_CANCELED bits set)
TaskScheduler ets = task.ExecutingTaskScheduler;
-
+
// Delegate cross-scheduler inlining requests to target scheduler
- if(ets != this && ets !=null) return ets.TryRunInline(task, taskWasPreviouslyQueued);
+ if (ets != this && ets != null) return ets.TryRunInline(task, taskWasPreviouslyQueued);
StackGuard currentStackGuard;
- if( (ets == null) ||
+ if ((ets == null) ||
(task.m_action == null) ||
- task.IsDelegateInvoked ||
+ task.IsDelegateInvoked ||
task.IsCanceled ||
(currentStackGuard = Task.CurrentStackGuard).TryBeginInliningScope() == false)
{
@@ -203,7 +203,10 @@ namespace System.Threading.Tasks
bool bInlined = false;
try
{
- task.FireTaskScheduledIfNeeded(this);
+ if (TplEtwProvider.Log.IsEnabled())
+ {
+ task.FireTaskScheduledIfNeeded(this);
+ }
bInlined = TryExecuteTaskInline(task, taskWasPreviouslyQueued);
}
finally
@@ -213,9 +216,9 @@ namespace System.Threading.Tasks
// If the custom scheduler returned true, we should either have the TASK_STATE_DELEGATE_INVOKED or TASK_STATE_CANCELED bit set
// Otherwise the scheduler is buggy
- if (bInlined && !(task.IsDelegateInvoked || task.IsCanceled))
+ if (bInlined && !(task.IsDelegateInvoked || task.IsCanceled))
{
- throw new InvalidOperationException(Environment.GetResourceString("TaskScheduler_InconsistentStateAfterTryExecuteTaskInline"));
+ throw new InvalidOperationException(SR.TaskScheduler_InconsistentStateAfterTryExecuteTaskInline);
}
return bInlined;
@@ -237,7 +240,7 @@ namespace System.Threading.Tasks
/// Notifies the scheduler that a work item has made progress.
/// </summary>
internal virtual void NotifyWorkItemProgress()
- {
+ {
}
/// <summary>
@@ -256,7 +259,10 @@ namespace System.Threading.Tasks
{
Contract.Requires(task != null);
- task.FireTaskScheduledIfNeeded(this);
+ if (TplEtwProvider.Log.IsEnabled())
+ {
+ task.FireTaskScheduledIfNeeded(this);
+ }
this.QueueTask(task);
}
@@ -269,7 +275,7 @@ namespace System.Threading.Tasks
// The global container that keeps track of TaskScheduler instances for debugging purposes.
private static ConditionalWeakTable<TaskScheduler, object> s_activeTaskSchedulers;
-
+
// An AppDomain-wide default manager.
private static readonly TaskScheduler s_defaultTaskScheduler = new ThreadPoolTaskScheduler();
@@ -316,7 +322,7 @@ namespace System.Threading.Tasks
/// <summary>
/// Gets the default <see cref="System.Threading.Tasks.TaskScheduler">TaskScheduler</see> instance.
/// </summary>
- public static TaskScheduler Default
+ public static TaskScheduler Default
{
get
{
@@ -331,7 +337,7 @@ namespace System.Threading.Tasks
/// <remarks>
/// When not called from within a task, <see cref="Current"/> will return the <see cref="Default"/> scheduler.
/// </remarks>
- public static TaskScheduler Current
+ public static TaskScheduler Current
{
get
{
@@ -352,7 +358,7 @@ namespace System.Threading.Tasks
get
{
Task currentTask = Task.InternalCurrent;
- return ( (currentTask != null)
+ return ((currentTask != null)
&& ((currentTask.CreationOptions & TaskCreationOptions.HideScheduler) == 0)
) ? currentTask.ExecutingTaskScheduler : null;
}
@@ -398,7 +404,7 @@ namespace System.Threading.Tasks
{
newId = Interlocked.Increment(ref s_taskSchedulerIdCounter);
} while (newId == 0);
-
+
Interlocked.CompareExchange(ref m_taskSchedulerId, newId, 0);
}
@@ -437,10 +443,10 @@ namespace System.Threading.Tasks
{
if (task.ExecutingTaskScheduler != this)
{
- throw new InvalidOperationException(Environment.GetResourceString("TaskScheduler_ExecuteTask_WrongTaskScheduler"));
+ throw new InvalidOperationException(SR.TaskScheduler_ExecuteTask_WrongTaskScheduler);
}
- return task.ExecuteEntry(true);
+ return task.ExecuteEntry();
}
////////////////////////////////////////////////////////////
@@ -477,12 +483,12 @@ namespace System.Threading.Tasks
lock (_unobservedTaskExceptionLockObject) _unobservedTaskException -= value;
}
}
-
-
+
+
////////////////////////////////////////////////////////////
//
// Internal methods
@@ -588,19 +594,18 @@ namespace System.Threading.Tasks
m_taskScheduler = scheduler;
}
- // returns the scheduler’s Id
+ // returns the scheduler�s Id
public Int32 Id
- {
- get { return m_taskScheduler.Id; }
+ {
+ get { return m_taskScheduler.Id; }
}
- // returns the scheduler’s GetScheduledTasks
- public IEnumerable<Task> ScheduledTasks
+ // returns the scheduler�s GetScheduledTasks
+ public IEnumerable<Task> ScheduledTasks
{
get { return m_taskScheduler.GetScheduledTasks(); }
}
}
-
}
@@ -626,11 +631,10 @@ namespace System.Threading.Tasks
// make sure we have a synccontext to work with
if (synContext == null)
{
- throw new InvalidOperationException(Environment.GetResourceString("TaskScheduler_FromCurrentSynchronizationContext_NoCurrent"));
+ throw new InvalidOperationException(SR.TaskScheduler_FromCurrentSynchronizationContext_NoCurrent);
}
m_synchronizationContext = synContext;
-
}
/// <summary>
@@ -684,16 +688,7 @@ namespace System.Threading.Tasks
}
// preallocated SendOrPostCallback delegate
- private static SendOrPostCallback s_postCallback = new SendOrPostCallback(PostCallback);
-
- // this is where the actual task invocation occures
- private static void PostCallback(object obj)
- {
- Task task = (Task) obj;
-
- // calling ExecuteEntry with double execute check enabled because a user implemented SynchronizationContext could be buggy
- task.ExecuteEntry(true);
- }
+ private static readonly SendOrPostCallback s_postCallback = s => ((Task)s).ExecuteEntry(); // with double-execute check because SC could be buggy
}
/// <summary>
@@ -728,7 +723,7 @@ namespace System.Threading.Tasks
/// Gets whether this exception has been marked as "observed."
/// </summary>
public bool Observed { get { return m_observed; } }
-
+
/// <summary>
/// The Exception that went unobserved.
/// </summary>
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskSchedulerException.cs b/src/mscorlib/src/System/Threading/Tasks/TaskSchedulerException.cs
deleted file mode 100644
index 1d85e49342..0000000000
--- a/src/mscorlib/src/System/Threading/Tasks/TaskSchedulerException.cs
+++ /dev/null
@@ -1,81 +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.
-
-// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
-//
-//
-//
-// An exception for task schedulers.
-//
-// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-using System;
-using System.Runtime.InteropServices;
-using System.Runtime.Serialization;
-
-namespace System.Threading.Tasks
-{
-
- /// <summary>
- /// Represents an exception used to communicate an invalid operation by a
- /// <see cref="T:System.Threading.Tasks.TaskScheduler"/>.
- /// </summary>
- [Serializable]
- public class TaskSchedulerException : Exception
- {
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskSchedulerException"/> class.
- /// </summary>
- public TaskSchedulerException() : base(Environment.GetResourceString("TaskSchedulerException_ctor_DefaultMessage")) //
- {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskSchedulerException"/>
- /// class with a specified error message.
- /// </summary>
- /// <param name="message">The error message that explains the reason for the exception.</param>
- public TaskSchedulerException(string message) : base(message)
- {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskSchedulerException"/>
- /// class using the default error message and a reference to the inner exception that is the cause of
- /// this exception.
- /// </summary>
- /// <param name="innerException">The exception that is the cause of the current exception.</param>
- public TaskSchedulerException(Exception innerException)
- : base(Environment.GetResourceString("TaskSchedulerException_ctor_DefaultMessage"), innerException)
- {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskSchedulerException"/>
- /// class with a specified error message and a reference to the inner exception that is the cause of
- /// this exception.
- /// </summary>
- /// <param name="message">The error message that explains the reason for the exception.</param>
- /// <param name="innerException">The exception that is the cause of the current exception.</param>
- public TaskSchedulerException(string message, Exception innerException) : base(message, innerException)
- {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="T:System.Threading.Tasks.TaskSchedulerException"/>
- /// class with serialized data.
- /// </summary>
- /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds
- /// the serialized object data about the exception being thrown.</param>
- /// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that
- /// contains contextual information about the source or destination. </param>
- protected TaskSchedulerException(SerializationInfo info, StreamingContext context)
- : base(info, context)
- {
- }
-
-
- }
-
-}
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskToApm.cs b/src/mscorlib/src/System/Threading/Tasks/TaskToApm.cs
index 90743aeec5..fdd62c95f5 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TaskToApm.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/TaskToApm.cs
@@ -60,7 +60,7 @@ namespace System.Threading.Tasks
{
// Asynchronous completion
asyncResult = task.AsyncState == state ? (IAsyncResult)task : new TaskWrapperAsyncResult(task, state, completedSynchronously: false);
- if (callback != null)
+ if (callback != null)
InvokeCallbackWhenTaskCompletes(task, callback, asyncResult);
}
return asyncResult;
@@ -129,7 +129,7 @@ namespace System.Threading.Tasks
// We use OnCompleted rather than ContinueWith in order to avoid running synchronously
// if the task has already completed by the time we get here. This is separated out into
// its own method currently so that we only pay for the closure if necessary.
- antecedent.ConfigureAwait(continueOnCapturedContext:false)
+ antecedent.ConfigureAwait(continueOnCapturedContext: false)
.GetAwaiter()
.OnCompleted(() => callback(asyncResult));
@@ -167,7 +167,7 @@ namespace System.Threading.Tasks
/// <param name="task">The Task to wrap.</param>
/// <param name="state">The new AsyncState value</param>
/// <param name="completedSynchronously">The new CompletedSynchronously value.</param>
- internal TaskWrapperAsyncResult(Task task, object state, bool completedSynchronously)
+ internal TaskWrapperAsyncResult(Task task, object state, bool completedSynchronously)
{
Contract.Requires(task != null);
Contract.Requires(!completedSynchronously || task.IsCompleted, "If completedSynchronously is true, the task must be completed.");
diff --git a/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs b/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs
index 5c6ca9bb76..e69a89fe66 100644
--- a/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs
@@ -23,7 +23,7 @@ namespace System.Threading.Tasks
/// <summary>
/// An implementation of TaskScheduler that uses the ThreadPool scheduler
/// </summary>
- internal sealed class ThreadPoolTaskScheduler: TaskScheduler
+ internal sealed class ThreadPoolTaskScheduler : TaskScheduler
{
/// <summary>
/// Constructs a new ThreadPool task scheduler object
@@ -34,15 +34,7 @@ namespace System.Threading.Tasks
}
// static delegate for threads allocated to handle LongRunning tasks.
- private static readonly ParameterizedThreadStart s_longRunningThreadWork = new ParameterizedThreadStart(LongRunningThreadWork);
-
- private static void LongRunningThreadWork(object obj)
- {
- Contract.Requires(obj != null, "TaskScheduler.LongRunningThreadWork: obj is null");
- Task t = obj as Task;
- Debug.Assert(t != null, "TaskScheduler.LongRunningThreadWork: t is null");
- t.ExecuteEntry(false);
- }
+ private static readonly ParameterizedThreadStart s_longRunningThreadWork = s => ((Task)s).ExecuteEntryUnsafe();
/// <summary>
/// Schedules a task to the ThreadPool.
@@ -64,11 +56,11 @@ namespace System.Threading.Tasks
ThreadPool.UnsafeQueueCustomWorkItem(task, forceToGlobalQueue);
}
}
-
+
/// <summary>
/// This internal function will do this:
/// (1) If the task had previously been queued, attempt to pop it and return false if that fails.
- /// (2) Propagate the return value from Task.ExecuteEntry() back to the caller.
+ /// (2) Return whether the task is executed
///
/// IMPORTANT NOTE: TryExecuteTaskInline will NOT throw task exceptions itself. Any wait code path using this function needs
/// to account for exceptions that need to be propagated, and throw themselves accordingly.
@@ -79,19 +71,17 @@ namespace System.Threading.Tasks
if (taskWasPreviouslyQueued && !ThreadPool.TryPopCustomWorkItem(task))
return false;
- // Propagate the return value of Task.ExecuteEntry()
- bool rval = false;
try
{
- rval = task.ExecuteEntry(false); // handles switching Task.Current etc.
+ task.ExecuteEntryUnsafe(); // handles switching Task.Current etc.
}
finally
{
// Only call NWIP() if task was previously queued
- if(taskWasPreviouslyQueued) NotifyWorkItemProgress();
+ if (taskWasPreviouslyQueued) NotifyWorkItemProgress();
}
- return rval;
+ return true;
}
protected internal override bool TryDequeue(Task task)
diff --git a/src/mscorlib/src/System/Threading/Tasks/future.cs b/src/mscorlib/src/System/Threading/Tasks/future.cs
index 15136f12bf..26c2388e6b 100644
--- a/src/mscorlib/src/System/Threading/Tasks/future.cs
+++ b/src/mscorlib/src/System/Threading/Tasks/future.cs
@@ -82,20 +82,20 @@ namespace System.Threading.Tasks
internal static readonly Func<Task<Task>, Task<TResult>> TaskWhenAnyCast = completed => (Task<TResult>)completed.Result;
// Construct a promise-style task without any options.
- internal Task() :
+ internal Task() :
base()
{
}
// Construct a promise-style task with state and options.
internal Task(object state, TaskCreationOptions options) :
- base(state, options, promiseStyle:true)
+ base(state, options, promiseStyle: true)
{
}
// Construct a pre-completed Task<TResult>
- internal Task(TResult result) :
+ internal Task(TResult result) :
base(false, TaskCreationOptions.None, default(CancellationToken))
{
m_result = result;
@@ -372,9 +372,9 @@ namespace System.Threading.Tasks
// Debugger support
private string DebuggerDisplayResultDescription
{
- get
+ get
{
- return IsRanToCompletion ? "" + m_result : Environment.GetResourceString("TaskT_DebuggerNoResult");
+ return IsRanToCompletion ? "" + m_result : SR.TaskT_DebuggerNoResult;
}
}
@@ -392,7 +392,6 @@ namespace System.Threading.Tasks
// internal helper function breaks out logic used by TaskCompletionSource
internal bool TrySetResult(TResult result)
{
- if (IsCompleted) return false;
Debug.Assert(m_action == null, "Task<T>.TrySetResult(): non-null m_action");
// "Reserve" the completion for this task, while making sure that: (1) No prior reservation
@@ -413,12 +412,13 @@ namespace System.Threading.Tasks
// and which can be summarized more concisely with the following snippet from
// FinishStageTwo, omitting everything that doesn't pertain to TrySetResult.
Interlocked.Exchange(ref m_stateFlags, m_stateFlags | TASK_STATE_RAN_TO_COMPLETION);
-
- var cp = m_contingentProperties;
- if (cp != null) cp.SetCompleted();
-
- FinishStageThree();
-
+ ContingentProperties props = m_contingentProperties;
+ if (props != null)
+ {
+ NotifyParentIfPotentiallyAttachedTask();
+ props.SetCompleted();
+ }
+ FinishContinuations();
return true;
}
@@ -441,7 +441,7 @@ namespace System.Threading.Tasks
bool success = TrySetResult(result);
// Nobody else has had a chance to complete this Task yet, so we should succeed.
- Debug.Assert(success);
+ Debug.Assert(success);
}
else
{
@@ -477,7 +477,7 @@ namespace System.Threading.Tasks
{
Debug.Assert(!IsWaitNotificationEnabledOrNotRanToCompletion,
"Should only be used when the task completed successfully and there's no wait notification enabled");
- return m_result;
+ return m_result;
}
}
@@ -539,7 +539,6 @@ namespace System.Threading.Tasks
}
return returnValue;
-
}
// internal helper function breaks out logic used by TaskCompletionSource and AsyncMethodBuilder
@@ -879,7 +878,7 @@ namespace System.Threading.Tasks
/// <exception cref="T:System.ObjectDisposedException">The provided <see cref="System.Threading.CancellationToken">CancellationToken</see>
/// has already been disposed.
/// </exception>
- public Task ContinueWith(Action<Task<TResult>, Object> continuationAction, Object state,CancellationToken cancellationToken)
+ public Task ContinueWith(Action<Task<TResult>, Object> continuationAction, Object state, CancellationToken cancellationToken)
{
return ContinueWith(continuationAction, state, TaskScheduler.Current, cancellationToken, TaskContinuationOptions.None);
}
@@ -942,7 +941,7 @@ namespace System.Threading.Tasks
/// The <paramref name="continuationOptions"/> argument specifies an invalid value for <see
/// cref="T:System.Threading.Tasks.TaskContinuationOptions">TaskContinuationOptions</see>.
/// </exception>
- public Task ContinueWith(Action<Task<TResult>, Object> continuationAction, Object state,TaskContinuationOptions continuationOptions)
+ public Task ContinueWith(Action<Task<TResult>, Object> continuationAction, Object state, TaskContinuationOptions continuationOptions)
{
return ContinueWith(continuationAction, state, TaskScheduler.Current, default(CancellationToken), continuationOptions);
}
@@ -1014,7 +1013,7 @@ namespace System.Threading.Tasks
out internalOptions);
Task continuationTask = new ContinuationTaskFromResultTask<TResult>(
- this, continuationAction, state,
+ this, continuationAction, state,
creationOptions, internalOptions
);
@@ -1229,7 +1228,7 @@ namespace System.Threading.Tasks
out creationOptions,
out internalOptions);
- Task<TNewResult> continuationFuture = new ContinuationResultTaskFromResultTask<TResult,TNewResult>(
+ Task<TNewResult> continuationFuture = new ContinuationResultTaskFromResultTask<TResult, TNewResult>(
this, continuationFunction, null,
creationOptions, internalOptions
);
@@ -1452,7 +1451,7 @@ namespace System.Threading.Tasks
out creationOptions,
out internalOptions);
- Task<TNewResult> continuationFuture = new ContinuationResultTaskFromResultTask<TResult,TNewResult>(
+ Task<TNewResult> continuationFuture = new ContinuationResultTaskFromResultTask<TResult, TNewResult>(
this, continuationFunction, state,
creationOptions, internalOptions
);
@@ -1467,7 +1466,7 @@ namespace System.Threading.Tasks
#endregion
#endregion
-
+
/// <summary>
/// Subscribes an <see cref="IObserver{TResult}"/> to receive notification of the final state of this <see cref="Task{TResult}"/>.
/// </summary>
@@ -1553,7 +1552,5 @@ namespace System.Threading.Tasks
public int Id { get { return m_task.Id; } }
public bool CancellationPending { get { return (m_task.Status == TaskStatus.WaitingToRun) && m_task.CancellationToken.IsCancellationRequested; } }
public TaskStatus Status { get { return m_task.Status; } }
-
-
}
}
diff --git a/src/mscorlib/src/System/Threading/Thread.cs b/src/mscorlib/src/System/Threading/Thread.cs
index d28002729a..70a5d06f7a 100644
--- a/src/mscorlib/src/System/Threading/Thread.cs
+++ b/src/mscorlib/src/System/Threading/Thread.cs
@@ -14,7 +14,8 @@
using Internal.Runtime.Augments;
-namespace System.Threading {
+namespace System.Threading
+{
using System.Threading;
using System.Runtime;
using System.Runtime.InteropServices;
@@ -33,11 +34,9 @@ namespace System.Threading {
internal class ThreadHelper
{
- static ThreadHelper() {}
-
- Delegate _start;
- Object _startArg = null;
- ExecutionContext _executionContext = null;
+ private Delegate _start;
+ private Object _startArg = null;
+ private ExecutionContext _executionContext = null;
internal ThreadHelper(Delegate start)
{
_start = start;
@@ -49,7 +48,7 @@ namespace System.Threading {
}
static internal ContextCallback _ccb = new ContextCallback(ThreadStart_Context);
-
+
static private void ThreadStart_Context(Object state)
{
ThreadHelper t = (ThreadHelper)state;
@@ -65,9 +64,9 @@ namespace System.Threading {
// call back helper
internal void ThreadStart(object obj)
- {
+ {
_startArg = obj;
- if (_executionContext != null)
+ if (_executionContext != null)
{
ExecutionContext.Run(_executionContext, _ccb, (Object)this);
}
@@ -80,7 +79,7 @@ namespace System.Threading {
// call back helper
internal void ThreadStart()
{
- if (_executionContext != null)
+ if (_executionContext != null)
{
ExecutionContext.Run(_executionContext, _ccb, (Object)this);
}
@@ -101,7 +100,7 @@ namespace System.Threading {
}
}
- public sealed class Thread : RuntimeThread
+ internal sealed class Thread : RuntimeThread
{
/*=========================================================================
** Data accessed from managed code that needs to be defined in
@@ -111,10 +110,10 @@ namespace System.Threading {
private ExecutionContext m_ExecutionContext; // this call context follows the logical thread
private SynchronizationContext m_SynchronizationContext; // On CoreCLR, this is maintained separately from ExecutionContext
- private String m_Name;
- private Delegate m_Delegate; // Delegate
+ private String m_Name;
+ private Delegate m_Delegate; // Delegate
- private Object m_ThreadStartArg;
+ private Object m_ThreadStartArg;
/*=========================================================================
** The base implementation of Thread is all native. The following fields
@@ -126,10 +125,10 @@ namespace System.Threading {
#pragma warning disable 414 // These fields are not used from managed.
// IntPtrs need to be together, and before ints, because IntPtrs are 64-bit
// fields on 64-bit platforms, where they will be sorted together.
-
- private IntPtr DONT_USE_InternalThread; // Pointer
- private int m_Priority; // INT32
- private int m_ManagedThreadId; // INT32
+
+ private IntPtr DONT_USE_InternalThread; // Pointer
+ private int m_Priority; // INT32
+ private int m_ManagedThreadId; // INT32
#pragma warning restore 414
#pragma warning restore 169
@@ -143,25 +142,12 @@ namespace System.Threading {
// with native code
// See code:#threadCultureInfo
[ThreadStatic]
- internal static CultureInfo m_CurrentCulture;
+ internal static CultureInfo m_CurrentCulture;
[ThreadStatic]
- internal static CultureInfo m_CurrentUICulture;
-
- static AsyncLocal<CultureInfo> s_asyncLocalCurrentCulture;
- static AsyncLocal<CultureInfo> s_asyncLocalCurrentUICulture;
-
- static void AsyncLocalSetCurrentCulture(AsyncLocalValueChangedArgs<CultureInfo> args)
- {
- m_CurrentCulture = args.CurrentValue;
- }
-
- static void AsyncLocalSetCurrentUICulture(AsyncLocalValueChangedArgs<CultureInfo> args)
- {
- m_CurrentUICulture = args.CurrentValue;
- }
+ internal static CultureInfo m_CurrentUICulture;
// Adding an empty default ctor for annotation purposes
- internal Thread(){}
+ internal Thread() { }
/*=========================================================================
** Creates a new Thread object which will begin execution at
@@ -169,37 +155,45 @@ namespace System.Threading {
**
** Exceptions: ArgumentNullException if start == null.
=========================================================================*/
- public Thread(ThreadStart start) {
- if (start == null) {
+ public Thread(ThreadStart start)
+ {
+ if (start == null)
+ {
throw new ArgumentNullException(nameof(start));
}
Contract.EndContractBlock();
- SetStartHelper((Delegate)start,0); //0 will setup Thread with default stackSize
+ SetStartHelper((Delegate)start, 0); //0 will setup Thread with default stackSize
}
- internal Thread(ThreadStart start, int maxStackSize) {
- if (start == null) {
+ internal Thread(ThreadStart start, int maxStackSize)
+ {
+ if (start == null)
+ {
throw new ArgumentNullException(nameof(start));
}
if (0 > maxStackSize)
- throw new ArgumentOutOfRangeException(nameof(maxStackSize),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(maxStackSize), SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
SetStartHelper((Delegate)start, maxStackSize);
}
- public Thread(ParameterizedThreadStart start) {
- if (start == null) {
+ public Thread(ParameterizedThreadStart start)
+ {
+ if (start == null)
+ {
throw new ArgumentNullException(nameof(start));
}
Contract.EndContractBlock();
SetStartHelper((Delegate)start, 0);
}
- internal Thread(ParameterizedThreadStart start, int maxStackSize) {
- if (start == null) {
+ internal Thread(ParameterizedThreadStart start, int maxStackSize)
+ {
+ if (start == null)
+ {
throw new ArgumentNullException(nameof(start));
}
if (0 > maxStackSize)
- throw new ArgumentOutOfRangeException(nameof(maxStackSize),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
+ throw new ArgumentOutOfRangeException(nameof(maxStackSize), SR.ArgumentOutOfRange_NeedNonNegNum);
Contract.EndContractBlock();
SetStartHelper((Delegate)start, maxStackSize);
}
@@ -224,7 +218,7 @@ namespace System.Threading {
// There are ways how to create an unitialized objects through remoting, etc. Avoid AVing in the EE by throwing a nice
// exception here.
if (thread.IsNull())
- throw new ArgumentException(null, Environment.GetResourceString("Argument_InvalidHandle"));
+ throw new ArgumentException(null, SR.Argument_InvalidHandle);
return new ThreadHandle(thread);
}
@@ -237,24 +231,24 @@ namespace System.Threading {
**
** Exceptions: ThreadStateException if the thread has already been started.
=========================================================================*/
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public new void Start()
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
Start(ref stackMark);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public new void Start(object parameter)
{
//In the case of a null delegate (second call to start on same thread)
// StartInternal method will take care of the error reporting
- if(m_Delegate is ThreadStart)
+ if (m_Delegate is ThreadStart)
{
//We expect the thread to be setup with a ParameterizedThreadStart
// if this constructor is called.
//If we got here then that wasn't the case
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ThreadWrongThreadStart"));
+ throw new InvalidOperationException(SR.InvalidOperation_ThreadWrongThreadStart);
}
m_ThreadStartArg = parameter;
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
@@ -285,7 +279,7 @@ namespace System.Threading {
internal ExecutionContext ExecutionContext
{
- get { return m_ExecutionContext; }
+ get { return m_ExecutionContext; }
set { m_ExecutionContext = value; }
}
@@ -320,15 +314,15 @@ namespace System.Threading {
{
SleepInternal(millisecondsTimeout);
// Ensure we don't return to app code when the pause is underway
- if(AppDomainPauseManager.IsPaused)
+ if (AppDomainPauseManager.IsPaused)
AppDomainPauseManager.ResumeEvent.WaitOneWithoutFAS();
}
public static void Sleep(TimeSpan timeout)
{
long tm = (long)timeout.TotalMilliseconds;
- if (tm < -1 || tm > (long) Int32.MaxValue)
- throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ if (tm < -1 || tm > (long)Int32.MaxValue)
+ throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
Sleep((int)tm);
}
@@ -353,9 +347,11 @@ namespace System.Threading {
{
return YieldInternal();
}
-
- public static new Thread CurrentThread {
- get {
+
+ public static new Thread CurrentThread
+ {
+ get
+ {
Contract.Ensures(Contract.Result<Thread>() != null);
return GetCurrentThreadNative();
}
@@ -368,14 +364,14 @@ namespace System.Threading {
Debug.Assert(maxStackSize >= 0);
ThreadHelper threadStartCallBack = new ThreadHelper(start);
- if(start is ThreadStart)
+ if (start is ThreadStart)
{
SetStart(new ThreadStart(threadStartCallBack.ThreadStart), maxStackSize);
}
else
{
SetStart(new ParameterizedThreadStart(threadStartCallBack.ThreadStart), maxStackSize);
- }
+ }
}
/*=========================================================================
@@ -437,72 +433,26 @@ namespace System.Threading {
// app domain get unloaded there is a code to clean up the culture from the thread
// using the code in AppDomain::ReleaseDomainStores.
- public CultureInfo CurrentUICulture {
- get {
+ public CultureInfo CurrentUICulture
+ {
+ get
+ {
Contract.Ensures(Contract.Result<CultureInfo>() != null);
-#if FEATURE_APPX && !FEATURE_COREFX_GLOBALIZATION
- if(AppDomain.IsAppXModel()) {
- return CultureInfo.GetCultureInfoForUserPreferredLanguageInAppX() ?? GetCurrentUICultureNoAppX();
- }
- else
-#endif
- {
- return GetCurrentUICultureNoAppX();
- }
+ return CultureInfo.CurrentUICulture;
}
- set {
- if (value == null) {
- throw new ArgumentNullException(nameof(value));
- }
- Contract.EndContractBlock();
-
- //If they're trying to use a Culture with a name that we can't use in resource lookup,
- //don't even let them set it on the thread.
- CultureInfo.VerifyCultureName(value, true);
-
+ set
+ {
// If you add more pre-conditions to this method, check to see if you also need to
// add them to CultureInfo.DefaultThreadCurrentUICulture.set.
if (m_CurrentUICulture == null && m_CurrentCulture == null)
nativeInitCultureAccessors();
- if (!AppContextSwitches.NoAsyncCurrentCulture)
- {
- if (s_asyncLocalCurrentUICulture == null)
- {
- Interlocked.CompareExchange(ref s_asyncLocalCurrentUICulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentUICulture), null);
- }
-
- // this one will set m_CurrentUICulture too
- s_asyncLocalCurrentUICulture.Value = value;
- }
- else
- {
- m_CurrentUICulture = value;
- }
+ CultureInfo.CurrentUICulture = value;
}
}
- internal CultureInfo GetCurrentUICultureNoAppX() {
-
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
-
-#if FEATURE_COREFX_GLOBALIZATION
- return CultureInfo.CurrentUICulture;
-#else
-
- // Fetch a local copy of m_CurrentUICulture to
- // avoid race conditions that malicious user can introduce
- if (m_CurrentUICulture == null) {
- CultureInfo appDomainDefaultUICulture = CultureInfo.DefaultThreadCurrentUICulture;
- return (appDomainDefaultUICulture != null ? appDomainDefaultUICulture : CultureInfo.UserDefaultUICulture);
- }
-
- return m_CurrentUICulture;
-#endif
- }
-
// This returns the exposed context for a given context ID.
// As the culture can be customized object then we cannot hold any
@@ -517,25 +467,16 @@ namespace System.Threading {
// app domain get unloaded there is a code to clean up the culture from the thread
// using the code in AppDomain::ReleaseDomainStores.
- public CultureInfo CurrentCulture {
- get {
+ public CultureInfo CurrentCulture
+ {
+ get
+ {
Contract.Ensures(Contract.Result<CultureInfo>() != null);
-
-#if FEATURE_APPX && !FEATURE_COREFX_GLOBALIZATION
- if(AppDomain.IsAppXModel()) {
- return CultureInfo.GetCultureInfoForUserPreferredLanguageInAppX() ?? GetCurrentCultureNoAppX();
- }
- else
-#endif
- {
- return GetCurrentCultureNoAppX();
- }
+ return CultureInfo.CurrentCulture;
}
- set {
- if (null==value) {
- throw new ArgumentNullException(nameof(value));
- }
+ set
+ {
Contract.EndContractBlock();
// If you add more pre-conditions to this method, check to see if you also need to
@@ -543,39 +484,9 @@ namespace System.Threading {
if (m_CurrentCulture == null && m_CurrentUICulture == null)
nativeInitCultureAccessors();
-
- if (!AppContextSwitches.NoAsyncCurrentCulture)
- {
- if (s_asyncLocalCurrentCulture == null)
- {
- Interlocked.CompareExchange(ref s_asyncLocalCurrentCulture, new AsyncLocal<CultureInfo>(AsyncLocalSetCurrentCulture), null);
- }
- // this one will set m_CurrentCulture too
- s_asyncLocalCurrentCulture.Value = value;
- }
- else
- {
- m_CurrentCulture = value;
- }
- }
- }
-
- private CultureInfo GetCurrentCultureNoAppX() {
-
-#if FEATURE_COREFX_GLOBALIZATION
- return CultureInfo.CurrentCulture;
-#else
- Contract.Ensures(Contract.Result<CultureInfo>() != null);
-
- // Fetch a local copy of m_CurrentCulture to
- // avoid race conditions that malicious user can introduce
- if (m_CurrentCulture == null) {
- CultureInfo appDomainDefaultCulture = CultureInfo.DefaultThreadCurrentCulture;
- return (appDomainDefaultCulture != null ? appDomainDefaultCulture : CultureInfo.UserDefaultCulture);
+
+ CultureInfo.CurrentCulture = value;
}
-
- return m_CurrentCulture;
-#endif
}
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
@@ -616,14 +527,18 @@ namespace System.Threading {
// Retrieves the name of the thread.
//
- public new String Name {
- get {
+ public new String Name
+ {
+ get
+ {
return m_Name;
}
- set {
- lock(this) {
+ set
+ {
+ lock (this)
+ {
if (m_Name != null)
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WriteOnce"));
+ throw new InvalidOperationException(SR.InvalidOperation_WriteOnce);
m_Name = value;
InformThreadNameChange(GetNativeHandle(), value, (value != null) ? value.Length : 0);
@@ -635,9 +550,6 @@ namespace System.Threading {
[SuppressUnmanagedCodeSecurity]
private static extern void InformThreadNameChange(ThreadHandle t, String name, int len);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern void MemoryBarrier();
-
} // End of class Thread
// declaring a local var of this enum type and passing it by ref into a function that needs to do a
@@ -651,5 +563,4 @@ namespace System.Threading {
LookForMyCallersCaller = 2,
LookForThread = 3
}
-
}
diff --git a/src/mscorlib/src/System/Threading/ThreadAbortException.cs b/src/mscorlib/src/System/Threading/ThreadAbortException.cs
deleted file mode 100644
index 25925048bf..0000000000
--- a/src/mscorlib/src/System/Threading/ThreadAbortException.cs
+++ /dev/null
@@ -1,39 +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.
-
-//
-/*=============================================================================
-**
-**
-**
-** Purpose: An exception class which is thrown into a thread to cause it to
-** abort. This is a special non-catchable exception and results in
-** the thread's death. This is thrown by the VM only and can NOT be
-** thrown by any user thread, and subclassing this is useless.
-**
-**
-=============================================================================*/
-
-namespace System.Threading
-{
- using System;
- using System.Runtime.Serialization;
- using System.Runtime.CompilerServices;
-
- [Serializable]
- public sealed class ThreadAbortException : SystemException
- {
- private ThreadAbortException()
- : base(GetMessageFromNativeResources(ExceptionMessageKind.ThreadAbort))
- {
- SetErrorCode(__HResults.COR_E_THREADABORTED);
- }
-
- //required for serialization
- internal ThreadAbortException(SerializationInfo info, StreamingContext context)
- : base(info, context)
- {
- }
- }
-}
diff --git a/src/mscorlib/src/System/Threading/ThreadInterruptedException.cs b/src/mscorlib/src/System/Threading/ThreadInterruptedException.cs
index 71c09649e2..9122df0d3e 100644
--- a/src/mscorlib/src/System/Threading/ThreadInterruptedException.cs
+++ b/src/mscorlib/src/System/Threading/ThreadInterruptedException.cs
@@ -12,29 +12,36 @@
**
**
=============================================================================*/
-namespace System.Threading {
- using System.Threading;
- using System;
- using System.Runtime.Serialization;
+using System.Threading;
+using System;
+using System.Runtime.Serialization;
+
+namespace System.Threading
+{
[Serializable]
- public class ThreadInterruptedException : SystemException {
- public ThreadInterruptedException()
- : base(GetMessageFromNativeResources(ExceptionMessageKind.ThreadInterrupted)) {
- SetErrorCode(__HResults.COR_E_THREADINTERRUPTED);
+ public class ThreadInterruptedException : SystemException
+ {
+ public ThreadInterruptedException()
+ : base(GetMessageFromNativeResources(ExceptionMessageKind.ThreadInterrupted))
+ {
+ HResult = __HResults.COR_E_THREADINTERRUPTED;
}
-
- public ThreadInterruptedException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_THREADINTERRUPTED);
+
+ public ThreadInterruptedException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_THREADINTERRUPTED;
}
-
- public ThreadInterruptedException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(__HResults.COR_E_THREADINTERRUPTED);
+
+ public ThreadInterruptedException(String message, Exception innerException)
+ : base(message, innerException)
+ {
+ HResult = __HResults.COR_E_THREADINTERRUPTED;
}
- protected ThreadInterruptedException(SerializationInfo info, StreamingContext context) : base (info, context) {
+ protected ThreadInterruptedException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
}
}
}
diff --git a/src/mscorlib/src/System/Threading/ThreadLocal.cs b/src/mscorlib/src/System/Threading/ThreadLocal.cs
index eedf6d0c81..64b8a60196 100644
--- a/src/mscorlib/src/System/Threading/ThreadLocal.cs
+++ b/src/mscorlib/src/System/Threading/ThreadLocal.cs
@@ -36,7 +36,6 @@ namespace System.Threading
[DebuggerDisplay("IsValueCreated={IsValueCreated}, Value={ValueForDebugDisplay}, Count={ValuesCountForDebugDisplay}")]
public class ThreadLocal<T> : IDisposable
{
-
// a delegate that returns the created value, if null the created value will be default(T)
private Func<T> m_valueFactory;
@@ -48,10 +47,10 @@ namespace System.Threading
// the ThreadLocal<T> instance.
//
[ThreadStatic]
- static LinkedSlotVolatile[] ts_slotArray;
+ private static LinkedSlotVolatile[] ts_slotArray;
[ThreadStatic]
- static FinalizationHelper ts_finalizationHelper;
+ private static FinalizationHelper ts_finalizationHelper;
// Slot ID of this ThreadLocal<> instance. We store a bitwise complement of the ID (that is ~ID), which allows us to distinguish
// between the case when ID is 0 and an incompletely initialized object, either due to a thread abort in the constructor, or
@@ -276,7 +275,7 @@ namespace System.Threading
&& id < slotArray.Length // Is the table large enough?
&& (slot = slotArray[id].Value) != null // Has a LinkedSlot object has been allocated for this ID?
&& m_initialized // Has the instance *still* not been disposed (important for a race condition with Dispose)?
- )
+ )
{
// We verified that the instance has not been disposed *after* we got a reference to the slot.
// This guarantees that we have a reference to the right slot.
@@ -324,7 +323,7 @@ namespace System.Threading
int id = ~m_idComplement;
if (id < 0)
{
- throw new ObjectDisposedException(Environment.GetResourceString("ThreadLocal_Disposed"));
+ throw new ObjectDisposedException(SR.ThreadLocal_Disposed);
}
Debugger.NotifyOfCrossThreadDependency();
@@ -341,7 +340,7 @@ namespace System.Threading
if (IsValueCreated)
{
- throw new InvalidOperationException(Environment.GetResourceString("ThreadLocal_Value_RecursiveCallsToValue"));
+ throw new InvalidOperationException(SR.ThreadLocal_Value_RecursiveCallsToValue);
}
}
@@ -357,7 +356,7 @@ namespace System.Threading
// If the object has been disposed, id will be -1.
if (id < 0)
{
- throw new ObjectDisposedException(Environment.GetResourceString("ThreadLocal_Disposed"));
+ throw new ObjectDisposedException(SR.ThreadLocal_Disposed);
}
// If a slot array has not been created on this thread yet, create it.
@@ -395,7 +394,7 @@ namespace System.Threading
if (!m_initialized)
{
- throw new ObjectDisposedException(Environment.GetResourceString("ThreadLocal_Disposed"));
+ throw new ObjectDisposedException(SR.ThreadLocal_Disposed);
}
slot.Value = value;
@@ -417,7 +416,7 @@ namespace System.Threading
// Dispose also executes under a lock.
if (!m_initialized)
{
- throw new ObjectDisposedException(Environment.GetResourceString("ThreadLocal_Disposed"));
+ throw new ObjectDisposedException(SR.ThreadLocal_Disposed);
}
LinkedSlot firstRealNode = m_linkedSlot.Next;
@@ -455,11 +454,11 @@ namespace System.Threading
{
if (!m_trackAllValues)
{
- throw new InvalidOperationException(Environment.GetResourceString("ThreadLocal_ValuesNotAvailable"));
+ throw new InvalidOperationException(SR.ThreadLocal_ValuesNotAvailable);
}
var list = GetValuesAsList(); // returns null if disposed
- if (list == null) throw new ObjectDisposedException(Environment.GetResourceString("ThreadLocal_Disposed"));
+ if (list == null) throw new ObjectDisposedException(SR.ThreadLocal_Disposed);
return list;
}
}
@@ -512,7 +511,7 @@ namespace System.Threading
int id = ~m_idComplement;
if (id < 0)
{
- throw new ObjectDisposedException(Environment.GetResourceString("ThreadLocal_Disposed"));
+ throw new ObjectDisposedException(SR.ThreadLocal_Disposed);
}
LinkedSlotVolatile[] slotArray = ts_slotArray;
diff --git a/src/mscorlib/src/System/Threading/ThreadPool.cs b/src/mscorlib/src/System/Threading/ThreadPool.cs
index adf0615819..0084050c43 100644
--- a/src/mscorlib/src/System/Threading/ThreadPool.cs
+++ b/src/mscorlib/src/System/Threading/ThreadPool.cs
@@ -33,8 +33,6 @@ namespace System.Threading
public static readonly int processorCount = Environment.ProcessorCount;
- public static readonly bool tpHosted = ThreadPool.IsThreadPoolHosted();
-
public static volatile bool vmTpInitialized;
public static bool enableWorkerTracking;
@@ -124,7 +122,7 @@ namespace System.Threading
private volatile int m_headIndex = START_INDEX;
private volatile int m_tailIndex = START_INDEX;
- private SpinLock m_foreignLock = new SpinLock(enableThreadOwnerTracking:false);
+ private SpinLock m_foreignLock = new SpinLock(enableThreadOwnerTracking: false);
public void LocalPush(IThreadPoolWorkItem obj)
{
@@ -158,7 +156,7 @@ namespace System.Threading
finally
{
if (lockTaken)
- m_foreignLock.Exit(useMemoryBarrier:true);
+ m_foreignLock.Exit(useMemoryBarrier: true);
}
}
@@ -200,7 +198,7 @@ namespace System.Threading
finally
{
if (lockTaken)
- m_foreignLock.Exit(useMemoryBarrier:false);
+ m_foreignLock.Exit(useMemoryBarrier: false);
}
}
}
@@ -254,7 +252,7 @@ namespace System.Threading
finally
{
if (lockTaken)
- m_foreignLock.Exit(useMemoryBarrier:false);
+ m_foreignLock.Exit(useMemoryBarrier: false);
}
}
}
@@ -321,7 +319,7 @@ namespace System.Threading
finally
{
if (lockTaken)
- m_foreignLock.Exit(useMemoryBarrier:false);
+ m_foreignLock.Exit(useMemoryBarrier: false);
}
}
}
@@ -366,7 +364,7 @@ namespace System.Threading
finally
{
if (taken)
- m_foreignLock.Exit(useMemoryBarrier:false);
+ m_foreignLock.Exit(useMemoryBarrier: false);
}
missedSteal = true;
@@ -381,10 +379,10 @@ namespace System.Threading
internal readonly ConcurrentQueue<IThreadPoolWorkItem> workItems = new ConcurrentQueue<IThreadPoolWorkItem>();
private volatile int numOutstandingThreadRequests = 0;
-
+
public ThreadPoolWorkQueue()
{
- loggingEnabled = FrameworkEventSource.Log.IsEnabled(EventLevel.Verbose, FrameworkEventSource.Keywords.ThreadPool|FrameworkEventSource.Keywords.ThreadTransfer);
+ loggingEnabled = FrameworkEventSource.Log.IsEnabled(EventLevel.Verbose, FrameworkEventSource.Keywords.ThreadPool | FrameworkEventSource.Keywords.ThreadTransfer);
}
public ThreadPoolWorkQueueThreadLocals EnsureCurrentThreadHasQueue() =>
@@ -401,7 +399,7 @@ namespace System.Threading
int count = numOutstandingThreadRequests;
while (count < ThreadPoolGlobals.processorCount)
{
- int prev = Interlocked.CompareExchange(ref numOutstandingThreadRequests, count+1, count);
+ int prev = Interlocked.CompareExchange(ref numOutstandingThreadRequests, count + 1, count);
if (prev == count)
{
ThreadPool.RequestWorkerThread();
@@ -439,7 +437,7 @@ namespace System.Threading
ThreadPoolWorkQueueThreadLocals tl = null;
if (!forceGlobal)
tl = ThreadPoolWorkQueueThreadLocals.threadLocals;
-
+
if (null != tl)
{
tl.workStealingQueue.LocalPush(callback);
@@ -511,7 +509,7 @@ namespace System.Threading
workQueue.MarkThreadRequestSatisfied();
// Has the desire for logging changed since the last time we entered?
- workQueue.loggingEnabled = FrameworkEventSource.Log.IsEnabled(EventLevel.Verbose, FrameworkEventSource.Keywords.ThreadPool|FrameworkEventSource.Keywords.ThreadTransfer);
+ workQueue.loggingEnabled = FrameworkEventSource.Log.IsEnabled(EventLevel.Verbose, FrameworkEventSource.Keywords.ThreadPool | FrameworkEventSource.Keywords.ThreadTransfer);
//
// Assume that we're going to need another thread if this one returns to the VM. We'll set this to
@@ -603,7 +601,7 @@ namespace System.Threading
// who waits for the task to complete.
//
workItem?.MarkAborted(tae);
-
+
//
// In this case, the VM is going to request another thread on our behalf. No need to do it twice.
//
@@ -707,7 +705,7 @@ namespace System.Threading
private volatile int m_lock = 0;
internal IntPtr GetHandle() => registeredWaitHandle;
-
+
internal void SetHandle(IntPtr handle)
{
registeredWaitHandle = handle;
@@ -731,7 +729,7 @@ namespace System.Threading
}
internal bool Unregister(
- WaitHandle waitObject // object to be notified when all callbacks to delegates have completed
+ WaitHandle waitObject // object to be notified when all callbacks to delegates have completed
)
{
bool result = false;
@@ -745,7 +743,7 @@ namespace System.Threading
// lock(this) cannot be used reliably in Cer since thin lock could be
// promoted to syncblock and that is not a guaranteed operation
bool bLockTaken = false;
- do
+ do
{
if (Interlocked.CompareExchange(ref m_lock, 1, 0) == 0)
{
@@ -807,8 +805,8 @@ namespace System.Threading
// This will result in a "leak" of sorts (since the handle will not be cleaned up)
// but the process is exiting anyway.
//
- // During AD-unload, we don’t finalize live objects until all threads have been
- // aborted out of the AD. Since these locked regions are CERs, we won’t abort them
+ // During AD-unload, we don�t finalize live objects until all threads have been
+ // aborted out of the AD. Since these locked regions are CERs, we won�t abort them
// while the lock is held. So there should be no leak on AD-unload.
//
if (Interlocked.CompareExchange(ref m_lock, 1, 0) == 0)
@@ -841,9 +839,10 @@ namespace System.Threading
private static extern bool UnregisterWaitNative(IntPtr handle, SafeHandle waitObject);
}
- public sealed class RegisteredWaitHandle : MarshalByRefObject {
+ public sealed class RegisteredWaitHandle : MarshalByRefObject
+ {
private readonly RegisteredWaitHandleSafe internalRegisteredWait;
-
+
internal RegisteredWaitHandle()
{
internalRegisteredWait = new RegisteredWaitHandleSafe();
@@ -851,23 +850,23 @@ namespace System.Threading
internal void SetHandle(IntPtr handle)
{
- internalRegisteredWait.SetHandle(handle);
+ internalRegisteredWait.SetHandle(handle);
}
internal void SetWaitObject(WaitHandle waitObject)
{
- internalRegisteredWait.SetWaitObject(waitObject);
+ internalRegisteredWait.SetWaitObject(waitObject);
}
// This is the only public method on this class
public bool Unregister(
- WaitHandle waitObject // object to be notified when all callbacks to delegates have completed
+ WaitHandle waitObject // object to be notified when all callbacks to delegates have completed
)
{
return internalRegisteredWait.Unregister(waitObject);
}
}
-
+
public delegate void WaitCallback(Object state);
public delegate void WaitOrTimerCallback(Object state, bool timedOut); // signalled or timed out
@@ -905,16 +904,16 @@ namespace System.Threading
private readonly Object state;
#if DEBUG
- volatile int executed;
+ private volatile int executed;
~QueueUserWorkItemCallback()
{
Debug.Assert(
- executed != 0 || Environment.HasShutdownStarted || AppDomain.CurrentDomain.IsFinalizingForUnload(),
+ executed != 0 || Environment.HasShutdownStarted || AppDomain.CurrentDomain.IsFinalizingForUnload(),
"A QueueUserWorkItemCallback was never called!");
}
- void MarkExecuted(bool aborted)
+ private void MarkExecuted(bool aborted)
{
GC.SuppressFinalize(this);
Debug.Assert(
@@ -933,7 +932,7 @@ namespace System.Threading
void IThreadPoolWorkItem.ExecuteWorkItem()
{
#if DEBUG
- MarkExecuted(aborted:false);
+ MarkExecuted(aborted: false);
#endif
// call directly if it is an unsafe call OR EC flow is suppressed
if (context == null)
@@ -953,7 +952,7 @@ namespace System.Threading
#if DEBUG
// this workitem didn't execute because we got a ThreadAbortException prior to the call to ExecuteWorkItem.
// This counts as being executed for our purposes.
- MarkExecuted(aborted:true);
+ MarkExecuted(aborted: true);
#endif
}
@@ -983,7 +982,7 @@ namespace System.Threading
"A QueueUserWorkItemCallbackDefaultContext was never called!");
}
- void MarkExecuted(bool aborted)
+ private void MarkExecuted(bool aborted)
{
GC.SuppressFinalize(this);
Debug.Assert(
@@ -1001,7 +1000,7 @@ namespace System.Threading
void IThreadPoolWorkItem.ExecuteWorkItem()
{
#if DEBUG
- MarkExecuted(aborted:false);
+ MarkExecuted(aborted: false);
#endif
ExecutionContext.Run(ExecutionContext.Default, ccb, this);
}
@@ -1011,7 +1010,7 @@ namespace System.Threading
#if DEBUG
// this workitem didn't execute because we got a ThreadAbortException prior to the call to ExecuteWorkItem.
// This counts as being executed for our purposes.
- MarkExecuted(aborted:true);
+ MarkExecuted(aborted: true);
#endif
}
@@ -1029,9 +1028,9 @@ namespace System.Threading
internal class _ThreadPoolWaitOrTimerCallback
{
- WaitOrTimerCallback _waitOrTimerCallback;
- ExecutionContext _executionContext;
- Object _state;
+ private WaitOrTimerCallback _waitOrTimerCallback;
+ private ExecutionContext _executionContext;
+ private Object _state;
private static readonly ContextCallback _ccbt = new ContextCallback(WaitOrTimerCallback_Context_t);
private static readonly ContextCallback _ccbf = new ContextCallback(WaitOrTimerCallback_Context_f);
@@ -1046,23 +1045,23 @@ namespace System.Threading
_executionContext = ExecutionContext.Capture();
}
}
-
+
private static void WaitOrTimerCallback_Context_t(Object state) =>
- WaitOrTimerCallback_Context(state, timedOut:true);
+ WaitOrTimerCallback_Context(state, timedOut: true);
private static void WaitOrTimerCallback_Context_f(Object state) =>
- WaitOrTimerCallback_Context(state, timedOut:false);
+ WaitOrTimerCallback_Context(state, timedOut: false);
private static void WaitOrTimerCallback_Context(Object state, bool timedOut)
{
_ThreadPoolWaitOrTimerCallback helper = (_ThreadPoolWaitOrTimerCallback)state;
helper._waitOrTimerCallback(helper._state, timedOut);
}
-
+
// call back helper
internal static void PerformWaitOrTimerCallback(Object state, bool timedOut)
{
- _ThreadPoolWaitOrTimerCallback helper = (_ThreadPoolWaitOrTimerCallback)state;
+ _ThreadPoolWaitOrTimerCallback helper = (_ThreadPoolWaitOrTimerCallback)state;
Debug.Assert(helper != null, "Null state passed to PerformWaitOrTimerCallback!");
// call directly if it is an unsafe call OR EC flow is suppressed
if (helper._executionContext == null)
@@ -1074,15 +1073,14 @@ namespace System.Threading
{
ExecutionContext.Run(helper._executionContext, timedOut ? _ccbt : _ccbf, helper);
}
- }
-
+ }
}
[CLSCompliant(false)]
unsafe public delegate void IOCompletionCallback(uint errorCode, // Error code
uint numBytes, // No. of bytes transferred
NativeOverlapped* pOVERLAP // ptr to OVERLAP structure
- );
+ );
public static class ThreadPool
{
@@ -1112,42 +1110,42 @@ namespace System.Threading
}
[CLSCompliant(false)]
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException
- WaitHandle waitObject,
- WaitOrTimerCallback callBack,
- Object state,
- uint millisecondsTimeOutInterval,
- bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC
+ WaitHandle waitObject,
+ WaitOrTimerCallback callBack,
+ Object state,
+ uint millisecondsTimeOutInterval,
+ bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC
)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RegisterWaitForSingleObject(waitObject,callBack,state,millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,true);
+ return RegisterWaitForSingleObject(waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce, ref stackMark, true);
}
[CLSCompliant(false)]
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( // throws RegisterWaitException
- WaitHandle waitObject,
- WaitOrTimerCallback callBack,
- Object state,
- uint millisecondsTimeOutInterval,
- bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC
+ WaitHandle waitObject,
+ WaitOrTimerCallback callBack,
+ Object state,
+ uint millisecondsTimeOutInterval,
+ bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC
)
{
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RegisterWaitForSingleObject(waitObject,callBack,state,millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,false);
+ return RegisterWaitForSingleObject(waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce, ref stackMark, false);
}
private static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException
- WaitHandle waitObject,
- WaitOrTimerCallback callBack,
- Object state,
- uint millisecondsTimeOutInterval,
- bool executeOnlyOnce, // NOTE: we do not allow other options that allow the callback to be queued as an APC
+ WaitHandle waitObject,
+ WaitOrTimerCallback callBack,
+ Object state,
+ uint millisecondsTimeOutInterval,
+ bool executeOnlyOnce, // NOTE: we do not allow other options that allow the callback to be queued as an APC
ref StackCrawlMark stackMark,
- bool compressStack
+ bool compressStack
)
{
RegisteredWaitHandle registeredWaitHandle = new RegisteredWaitHandle();
@@ -1160,7 +1158,7 @@ namespace System.Threading
// this could occur if callback were to fire before SetWaitObject does its addref
registeredWaitHandle.SetWaitObject(waitObject);
IntPtr nativeRegisteredWaitHandle = RegisterWaitForSingleObjectNative(waitObject,
- state,
+ state,
millisecondsTimeOutInterval,
executeOnlyOnce,
registeredWaitHandle,
@@ -1176,104 +1174,104 @@ namespace System.Threading
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException
- WaitHandle waitObject,
- WaitOrTimerCallback callBack,
- Object state,
- int millisecondsTimeOutInterval,
- bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC
+ WaitHandle waitObject,
+ WaitOrTimerCallback callBack,
+ Object state,
+ int millisecondsTimeOutInterval,
+ bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC
)
{
if (millisecondsTimeOutInterval < -1)
- throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,true);
+ return RegisterWaitForSingleObject(waitObject, callBack, state, (UInt32)millisecondsTimeOutInterval, executeOnlyOnce, ref stackMark, true);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( // throws RegisterWaitException
- WaitHandle waitObject,
- WaitOrTimerCallback callBack,
- Object state,
- int millisecondsTimeOutInterval,
- bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC
+ WaitHandle waitObject,
+ WaitOrTimerCallback callBack,
+ Object state,
+ int millisecondsTimeOutInterval,
+ bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC
)
{
if (millisecondsTimeOutInterval < -1)
- throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,false);
+ return RegisterWaitForSingleObject(waitObject, callBack, state, (UInt32)millisecondsTimeOutInterval, executeOnlyOnce, ref stackMark, false);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public static RegisteredWaitHandle RegisterWaitForSingleObject( // throws RegisterWaitException
- WaitHandle waitObject,
+ WaitHandle waitObject,
WaitOrTimerCallback callBack,
- Object state,
- long millisecondsTimeOutInterval,
- bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC
+ Object state,
+ long millisecondsTimeOutInterval,
+ bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC
)
{
if (millisecondsTimeOutInterval < -1)
- throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,true);
+ return RegisterWaitForSingleObject(waitObject, callBack, state, (UInt32)millisecondsTimeOutInterval, executeOnlyOnce, ref stackMark, true);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject( // throws RegisterWaitException
- WaitHandle waitObject,
+ WaitHandle waitObject,
WaitOrTimerCallback callBack,
- Object state,
- long millisecondsTimeOutInterval,
- bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC
+ Object state,
+ long millisecondsTimeOutInterval,
+ bool executeOnlyOnce // NOTE: we do not allow other options that allow the callback to be queued as an APC
)
{
if (millisecondsTimeOutInterval < -1)
- throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeOutInterval), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
Contract.EndContractBlock();
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)millisecondsTimeOutInterval,executeOnlyOnce,ref stackMark,false);
+ return RegisterWaitForSingleObject(waitObject, callBack, state, (UInt32)millisecondsTimeOutInterval, executeOnlyOnce, ref stackMark, false);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public static RegisteredWaitHandle RegisterWaitForSingleObject(
- WaitHandle waitObject,
- WaitOrTimerCallback callBack,
- Object state,
- TimeSpan timeout,
- bool executeOnlyOnce
+ WaitHandle waitObject,
+ WaitOrTimerCallback callBack,
+ Object state,
+ TimeSpan timeout,
+ bool executeOnlyOnce
)
{
long tm = (long)timeout.TotalMilliseconds;
if (tm < -1)
- throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
- if (tm > (long) Int32.MaxValue)
- throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_LessEqualToIntegerMaxVal"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
+ if (tm > (long)Int32.MaxValue)
+ throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal);
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)tm,executeOnlyOnce,ref stackMark,true);
+ return RegisterWaitForSingleObject(waitObject, callBack, state, (UInt32)tm, executeOnlyOnce, ref stackMark, true);
}
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject(
- WaitHandle waitObject,
- WaitOrTimerCallback callBack,
- Object state,
- TimeSpan timeout,
- bool executeOnlyOnce
+ WaitHandle waitObject,
+ WaitOrTimerCallback callBack,
+ Object state,
+ TimeSpan timeout,
+ bool executeOnlyOnce
)
{
long tm = (long)timeout.TotalMilliseconds;
if (tm < -1)
- throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
- if (tm > (long) Int32.MaxValue)
- throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_LessEqualToIntegerMaxVal"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
+ if (tm > (long)Int32.MaxValue)
+ throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_LessEqualToIntegerMaxVal);
StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RegisterWaitForSingleObject(waitObject,callBack,state,(UInt32)tm,executeOnlyOnce,ref stackMark,false);
+ return RegisterWaitForSingleObject(waitObject, callBack, state, (UInt32)tm, executeOnlyOnce, ref stackMark, false);
}
public static bool QueueUserWorkItem(WaitCallback callBack) =>
@@ -1428,7 +1426,7 @@ namespace System.Threading
EnsureVMInitializedCore(); // separate out to help with inlining
}
}
-
+
private static void EnsureVMInitializedCore()
{
ThreadPool.InitializeVMTp(ref ThreadPoolGlobals.enableWorkerTracking);
@@ -1436,7 +1434,7 @@ namespace System.Threading
}
// Native methods:
-
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool SetMinThreadsNative(int workerThreads, int completionPortThreads);
@@ -1468,22 +1466,19 @@ namespace System.Threading
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void NotifyWorkItemProgressNative();
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern bool IsThreadPoolHosted();
-
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void InitializeVMTp(ref bool enableWorkerTracking);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern IntPtr RegisterWaitForSingleObjectNative(
- WaitHandle waitHandle,
- Object state,
- uint timeOutInterval,
- bool executeOnlyOnce,
- RegisteredWaitHandle registeredWaitHandle,
- ref StackCrawlMark stackMark,
- bool compressStack
+ private static extern IntPtr RegisterWaitForSingleObjectNative(
+ WaitHandle waitHandle,
+ Object state,
+ uint timeOutInterval,
+ bool executeOnlyOnce,
+ RegisteredWaitHandle registeredWaitHandle,
+ ref StackCrawlMark stackMark,
+ bool compressStack
);
@@ -1497,15 +1492,17 @@ namespace System.Threading
{
if (osHandle == null)
throw new ArgumentNullException(nameof(osHandle));
-
+
bool ret = false;
bool mustReleaseSafeHandle = false;
RuntimeHelpers.PrepareConstrainedRegions();
- try {
+ try
+ {
osHandle.DangerousAddRef(ref mustReleaseSafeHandle);
ret = BindIOCompletionCallbackNative(osHandle.DangerousGetHandle());
}
- finally {
+ finally
+ {
if (mustReleaseSafeHandle)
osHandle.DangerousRelease();
}
diff --git a/src/mscorlib/src/System/Threading/ThreadPriority.cs b/src/mscorlib/src/System/Threading/ThreadPriority.cs
deleted file mode 100644
index 6303c2fd94..0000000000
--- a/src/mscorlib/src/System/Threading/ThreadPriority.cs
+++ /dev/null
@@ -1,31 +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.
-
-//
-/*=============================================================================
-**
-**
-**
-** Purpose: Enums for the priorities of a Thread
-**
-**
-=============================================================================*/
-
-namespace System.Threading {
- using System.Threading;
-
- [Serializable]
- public enum ThreadPriority
- {
- /*=========================================================================
- ** Constants for thread priorities.
- =========================================================================*/
- Lowest = 0,
- BelowNormal = 1,
- Normal = 2,
- AboveNormal = 3,
- Highest = 4
-
- }
-}
diff --git a/src/mscorlib/src/System/Threading/ThreadStart.cs b/src/mscorlib/src/System/Threading/ThreadStart.cs
deleted file mode 100644
index e4beddcd75..0000000000
--- a/src/mscorlib/src/System/Threading/ThreadStart.cs
+++ /dev/null
@@ -1,23 +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.
-
-//
-/*=============================================================================
-**
-**
-**
-** Purpose: This class is a Delegate which defines the start method
-** for starting a thread. That method must match this delegate.
-**
-**
-=============================================================================*/
-
-namespace System.Threading {
- using System.Threading;
-
- // Define the delegate
- // NOTE: If you change the signature here, there is code in COMSynchronization
- // that invokes this delegate in native.
- public delegate void ThreadStart();
-}
diff --git a/src/mscorlib/src/System/Threading/ThreadStartException.cs b/src/mscorlib/src/System/Threading/ThreadStartException.cs
deleted file mode 100644
index 33fb460b3d..0000000000
--- a/src/mscorlib/src/System/Threading/ThreadStartException.cs
+++ /dev/null
@@ -1,37 +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.
-
-//
-
-namespace System.Threading
-{
- using System;
- using System.Runtime.Serialization;
- using System.Runtime.InteropServices;
-
- [Serializable]
- public sealed class ThreadStartException : SystemException
- {
- private ThreadStartException()
- : base(Environment.GetResourceString("Arg_ThreadStartException"))
- {
- SetErrorCode(__HResults.COR_E_THREADSTART);
- }
-
- private ThreadStartException(Exception reason)
- : base(Environment.GetResourceString("Arg_ThreadStartException"), reason)
- {
- SetErrorCode(__HResults.COR_E_THREADSTART);
- }
-
- //required for serialization
- internal ThreadStartException(SerializationInfo info, StreamingContext context)
- : base(info, context)
- {
- }
-
- }
-}
-
-
diff --git a/src/mscorlib/src/System/Threading/ThreadState.cs b/src/mscorlib/src/System/Threading/ThreadState.cs
deleted file mode 100644
index 2d953f384a..0000000000
--- a/src/mscorlib/src/System/Threading/ThreadState.cs
+++ /dev/null
@@ -1,35 +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.
-
-//
-/*=============================================================================
-**
-**
-**
-** Purpose: Enum to represent the different thread states
-**
-**
-=============================================================================*/
-
-namespace System.Threading {
-
-[Serializable]
-[Flags]
- public enum ThreadState
- {
- /*=========================================================================
- ** Constants for thread states.
- =========================================================================*/
- Running = 0,
- StopRequested = 1,
- SuspendRequested = 2,
- Background = 4,
- Unstarted = 8,
- Stopped = 16,
- WaitSleepJoin = 32,
- Suspended = 64,
- AbortRequested = 128,
- Aborted = 256
- }
-}
diff --git a/src/mscorlib/src/System/Threading/ThreadStateException.cs b/src/mscorlib/src/System/Threading/ThreadStateException.cs
deleted file mode 100644
index 97c03ce06c..0000000000
--- a/src/mscorlib/src/System/Threading/ThreadStateException.cs
+++ /dev/null
@@ -1,40 +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.
-
-//
-/*=============================================================================
-**
-**
-**
-** Purpose: An exception class to indicate that the Thread class is in an
-** invalid state for the method.
-**
-**
-=============================================================================*/
-
-namespace System.Threading {
- using System;
- using System.Runtime.Serialization;
- [Serializable]
- public class ThreadStateException : SystemException {
- public ThreadStateException()
- : base(Environment.GetResourceString("Arg_ThreadStateException")) {
- SetErrorCode(__HResults.COR_E_THREADSTATE);
- }
-
- public ThreadStateException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_THREADSTATE);
- }
-
- public ThreadStateException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(__HResults.COR_E_THREADSTATE);
- }
-
- protected ThreadStateException(SerializationInfo info, StreamingContext context) : base (info, context) {
- }
- }
-
-}
diff --git a/src/mscorlib/src/System/Threading/Timeout.cs b/src/mscorlib/src/System/Threading/Timeout.cs
deleted file mode 100644
index 80bdbccf4e..0000000000
--- a/src/mscorlib/src/System/Threading/Timeout.cs
+++ /dev/null
@@ -1,19 +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.
-
-namespace System.Threading {
- using System.Threading;
- using System;
- // A constant used by methods that take a timeout (Object.Wait, Thread.Sleep
- // etc) to indicate that no timeout should occur.
- //
- public static class Timeout
- {
- public static readonly TimeSpan InfiniteTimeSpan = new TimeSpan(0, 0, 0, 0, Timeout.Infinite);
-
- public const int Infinite = -1;
- internal const uint UnsignedInfinite = unchecked((uint)-1);
- }
-
-}
diff --git a/src/mscorlib/src/System/Threading/Timer.cs b/src/mscorlib/src/System/Threading/Timer.cs
index 93d2922799..960f815d64 100644
--- a/src/mscorlib/src/System/Threading/Timer.cs
+++ b/src/mscorlib/src/System/Threading/Timer.cs
@@ -4,7 +4,7 @@
//
-namespace System.Threading
+namespace System.Threading
{
using System;
using System.Security;
@@ -19,7 +19,7 @@ namespace System.Threading
using Microsoft.Win32.SafeHandles;
-
+
public delegate void TimerCallback(Object state);
//
@@ -43,12 +43,12 @@ namespace System.Threading
//
// Note that all instance methods of this class require that the caller hold a lock on TimerQueue.Instance.
//
- class TimerQueue
+ internal class TimerQueue
{
#region singleton pattern implementation
// The one-and-only TimerQueue for the AppDomain.
- static TimerQueue s_queue = new TimerQueue();
+ private static TimerQueue s_queue = new TimerQueue();
public static TimerQueue Instance
{
@@ -100,7 +100,7 @@ namespace System.Threading
//
// We use a SafeHandle to ensure that the native timer is destroyed when the AppDomain is unloaded.
//
- class AppDomainTimerSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
+ private class AppDomainTimerSafeHandle : SafeHandleZeroOrMinusOneIsInvalid
{
public AppDomainTimerSafeHandle()
: base(true)
@@ -113,11 +113,11 @@ namespace System.Threading
}
}
- AppDomainTimerSafeHandle m_appDomainTimer;
+ private AppDomainTimerSafeHandle m_appDomainTimer;
- bool m_isAppDomainTimerScheduled;
- int m_currentAppDomainTimerStartTicks;
- uint m_currentAppDomainTimerDuration;
+ private bool m_isAppDomainTimerScheduled;
+ private int m_currentAppDomainTimerStartTicks;
+ private uint m_currentAppDomainTimerDuration;
private bool EnsureAppDomainTimerFiresBy(uint requestedDuration)
{
@@ -145,13 +145,13 @@ namespace System.Threading
// If Pause is underway then do not schedule the timers
// A later update during resume will re-schedule
- if(m_pauseTicks != 0)
+ if (m_pauseTicks != 0)
{
Debug.Assert(!m_isAppDomainTimerScheduled);
Debug.Assert(m_appDomainTimer == null);
return true;
}
-
+
if (m_appDomainTimer == null || m_appDomainTimer.IsInvalid)
{
Debug.Assert(!m_isAppDomainTimerScheduled);
@@ -195,15 +195,15 @@ namespace System.Threading
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
- static extern AppDomainTimerSafeHandle CreateAppDomainTimer(uint dueTime);
+ private static extern AppDomainTimerSafeHandle CreateAppDomainTimer(uint dueTime);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
- static extern bool ChangeAppDomainTimer(AppDomainTimerSafeHandle handle, uint dueTime);
+ private static extern bool ChangeAppDomainTimer(AppDomainTimerSafeHandle handle, uint dueTime);
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
- static extern bool DeleteAppDomainTimer(IntPtr handle);
+ private static extern bool DeleteAppDomainTimer(IntPtr handle);
#endregion
@@ -212,10 +212,10 @@ namespace System.Threading
//
// The list of timers
//
- TimerQueueTimer m_timers;
+ private TimerQueueTimer m_timers;
- volatile int m_pauseTicks = 0; // Time when Pause was called
+ private volatile int m_pauseTicks = 0; // Time when Pause was called
//
@@ -386,7 +386,7 @@ namespace System.Threading
//
// A timer in our TimerQueue.
//
- sealed class TimerQueueTimer
+ internal sealed class TimerQueueTimer
{
//
// All fields of this class are protected by a lock on TimerQueue.Instance.
@@ -414,9 +414,9 @@ namespace System.Threading
//
// Info about the user's callback
//
- readonly TimerCallback m_timerCallback;
- readonly Object m_state;
- readonly ExecutionContext m_executionContext;
+ private readonly TimerCallback m_timerCallback;
+ private readonly Object m_state;
+ private readonly ExecutionContext m_executionContext;
//
@@ -426,9 +426,9 @@ namespace System.Threading
// m_callbacksRunning. We set m_notifyWhenNoCallbacksRunning only when m_callbacksRunning
// reaches zero.
//
- int m_callbacksRunning;
- volatile bool m_canceled;
- volatile WaitHandle m_notifyWhenNoCallbacksRunning;
+ private int m_callbacksRunning;
+ private volatile bool m_canceled;
+ private volatile WaitHandle m_notifyWhenNoCallbacksRunning;
internal TimerQueueTimer(TimerCallback timerCallback, object state, uint dueTime, uint period)
@@ -455,7 +455,7 @@ namespace System.Threading
lock (TimerQueue.Instance)
{
if (m_canceled)
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_Generic"));
+ throw new ObjectDisposedException(null, SR.ObjectDisposed_Generic);
// prevent ThreadAbort while updating state
try { }
@@ -612,17 +612,17 @@ namespace System.Threading
// change, because any code that happened to be suppressing finalization of Timer objects would now
// unwittingly be changing the lifetime of those timers.
//
- sealed class TimerHolder
+ internal sealed class TimerHolder
{
internal TimerQueueTimer m_timer;
-
- public TimerHolder(TimerQueueTimer timer)
- {
- m_timer = timer;
+
+ public TimerHolder(TimerQueueTimer timer)
+ {
+ m_timer = timer;
}
- ~TimerHolder()
- {
+ ~TimerHolder()
+ {
//
// If shutdown has started, another thread may be suspended while holding the timer lock.
// So we can't safely close the timer.
@@ -636,7 +636,7 @@ namespace System.Threading
if (Environment.HasShutdownStarted || AppDomain.CurrentDomain.IsFinalizingForUnload())
return;
- m_timer.Close();
+ m_timer.Close();
}
public void Close()
@@ -651,7 +651,6 @@ namespace System.Threading
GC.SuppressFinalize(this);
return result;
}
-
}
@@ -661,64 +660,64 @@ namespace System.Threading
private TimerHolder m_timer;
- public Timer(TimerCallback callback,
- Object state,
- int dueTime,
- int period)
+ public Timer(TimerCallback callback,
+ Object state,
+ int dueTime,
+ int period)
{
if (dueTime < -1)
- throw new ArgumentOutOfRangeException(nameof(dueTime), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
- if (period < -1 )
- throw new ArgumentOutOfRangeException(nameof(period), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(dueTime), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
+ if (period < -1)
+ throw new ArgumentOutOfRangeException(nameof(period), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
Contract.EndContractBlock();
- TimerSetup(callback,state,(UInt32)dueTime,(UInt32)period);
+ TimerSetup(callback, state, (UInt32)dueTime, (UInt32)period);
}
- public Timer(TimerCallback callback,
- Object state,
- TimeSpan dueTime,
- TimeSpan period)
- {
+ public Timer(TimerCallback callback,
+ Object state,
+ TimeSpan dueTime,
+ TimeSpan period)
+ {
long dueTm = (long)dueTime.TotalMilliseconds;
if (dueTm < -1)
- throw new ArgumentOutOfRangeException(nameof(dueTm),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(dueTm), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
if (dueTm > MAX_SUPPORTED_TIMEOUT)
- throw new ArgumentOutOfRangeException(nameof(dueTm),Environment.GetResourceString("ArgumentOutOfRange_TimeoutTooLarge"));
+ throw new ArgumentOutOfRangeException(nameof(dueTm), SR.ArgumentOutOfRange_TimeoutTooLarge);
long periodTm = (long)period.TotalMilliseconds;
if (periodTm < -1)
- throw new ArgumentOutOfRangeException(nameof(periodTm),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(periodTm), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
if (periodTm > MAX_SUPPORTED_TIMEOUT)
- throw new ArgumentOutOfRangeException(nameof(periodTm),Environment.GetResourceString("ArgumentOutOfRange_PeriodTooLarge"));
+ throw new ArgumentOutOfRangeException(nameof(periodTm), SR.ArgumentOutOfRange_PeriodTooLarge);
- TimerSetup(callback,state,(UInt32)dueTm,(UInt32)periodTm);
+ TimerSetup(callback, state, (UInt32)dueTm, (UInt32)periodTm);
}
[CLSCompliant(false)]
- public Timer(TimerCallback callback,
- Object state,
- UInt32 dueTime,
- UInt32 period)
+ public Timer(TimerCallback callback,
+ Object state,
+ UInt32 dueTime,
+ UInt32 period)
{
- TimerSetup(callback,state,dueTime,period);
+ TimerSetup(callback, state, dueTime, period);
}
- public Timer(TimerCallback callback,
- Object state,
- long dueTime,
- long period)
+ public Timer(TimerCallback callback,
+ Object state,
+ long dueTime,
+ long period)
{
if (dueTime < -1)
- throw new ArgumentOutOfRangeException(nameof(dueTime),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(dueTime), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
if (period < -1)
- throw new ArgumentOutOfRangeException(nameof(period),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(period), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
if (dueTime > MAX_SUPPORTED_TIMEOUT)
- throw new ArgumentOutOfRangeException(nameof(dueTime),Environment.GetResourceString("ArgumentOutOfRange_TimeoutTooLarge"));
+ throw new ArgumentOutOfRangeException(nameof(dueTime), SR.ArgumentOutOfRange_TimeoutTooLarge);
if (period > MAX_SUPPORTED_TIMEOUT)
- throw new ArgumentOutOfRangeException(nameof(period),Environment.GetResourceString("ArgumentOutOfRange_PeriodTooLarge"));
+ throw new ArgumentOutOfRangeException(nameof(period), SR.ArgumentOutOfRange_PeriodTooLarge);
Contract.EndContractBlock();
- TimerSetup(callback,state,(UInt32) dueTime, (UInt32) period);
+ TimerSetup(callback, state, (UInt32)dueTime, (UInt32)period);
}
public Timer(TimerCallback callback)
@@ -727,12 +726,12 @@ namespace System.Threading
int period = -1; // Change after a timer instance is created. This is to avoid the potential
// for a timer to be fired before the returned value is assigned to the variable,
// potentially causing the callback to reference a bogus value (if passing the timer to the callback).
-
+
TimerSetup(callback, this, (UInt32)dueTime, (UInt32)period);
}
private void TimerSetup(TimerCallback callback,
- Object state,
+ Object state,
UInt32 dueTime,
UInt32 period)
{
@@ -742,13 +741,13 @@ namespace System.Threading
m_timer = new TimerHolder(new TimerQueueTimer(callback, state, dueTime, period));
}
-
+
public bool Change(int dueTime, int period)
{
- if (dueTime < -1 )
- throw new ArgumentOutOfRangeException(nameof(dueTime),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ if (dueTime < -1)
+ throw new ArgumentOutOfRangeException(nameof(dueTime), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
if (period < -1)
- throw new ArgumentOutOfRangeException(nameof(period),Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(period), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
Contract.EndContractBlock();
return m_timer.m_timer.Change((UInt32)dueTime, (UInt32)period);
@@ -756,7 +755,7 @@ namespace System.Threading
public bool Change(TimeSpan dueTime, TimeSpan period)
{
- return Change((long) dueTime.TotalMilliseconds, (long) period.TotalMilliseconds);
+ return Change((long)dueTime.TotalMilliseconds, (long)period.TotalMilliseconds);
}
[CLSCompliant(false)]
@@ -767,28 +766,28 @@ namespace System.Threading
public bool Change(long dueTime, long period)
{
- if (dueTime < -1 )
- throw new ArgumentOutOfRangeException(nameof(dueTime), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ if (dueTime < -1)
+ throw new ArgumentOutOfRangeException(nameof(dueTime), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
if (period < -1)
- throw new ArgumentOutOfRangeException(nameof(period), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(period), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
if (dueTime > MAX_SUPPORTED_TIMEOUT)
- throw new ArgumentOutOfRangeException(nameof(dueTime), Environment.GetResourceString("ArgumentOutOfRange_TimeoutTooLarge"));
+ throw new ArgumentOutOfRangeException(nameof(dueTime), SR.ArgumentOutOfRange_TimeoutTooLarge);
if (period > MAX_SUPPORTED_TIMEOUT)
- throw new ArgumentOutOfRangeException(nameof(period), Environment.GetResourceString("ArgumentOutOfRange_PeriodTooLarge"));
+ throw new ArgumentOutOfRangeException(nameof(period), SR.ArgumentOutOfRange_PeriodTooLarge);
Contract.EndContractBlock();
return m_timer.m_timer.Change((UInt32)dueTime, (UInt32)period);
}
-
+
public bool Dispose(WaitHandle notifyObject)
{
- if (notifyObject==null)
+ if (notifyObject == null)
throw new ArgumentNullException(nameof(notifyObject));
Contract.EndContractBlock();
return m_timer.Close(notifyObject);
}
-
+
public void Dispose()
{
m_timer.Close();
diff --git a/src/mscorlib/src/System/Threading/Volatile.cs b/src/mscorlib/src/System/Threading/Volatile.cs
index c94a69ab7b..6aac8d63cd 100644
--- a/src/mscorlib/src/System/Threading/Volatile.cs
+++ b/src/mscorlib/src/System/Threading/Volatile.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
//
+
using System;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
@@ -33,7 +34,7 @@ namespace System.Threading
// The VM will replace this with a more efficient implementation.
//
var value = location;
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
return value;
}
@@ -45,7 +46,7 @@ namespace System.Threading
// The VM will replace this with a more efficient implementation.
//
var value = location;
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
return value;
}
@@ -56,7 +57,7 @@ namespace System.Threading
// The VM will replace this with a more efficient implementation.
//
var value = location;
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
return value;
}
@@ -67,7 +68,7 @@ namespace System.Threading
// The VM will replace this with a more efficient implementation.
//
var value = location;
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
return value;
}
@@ -79,7 +80,7 @@ namespace System.Threading
// The VM will replace this with a more efficient implementation.
//
var value = location;
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
return value;
}
@@ -90,7 +91,7 @@ namespace System.Threading
// The VM will replace this with a more efficient implementation.
//
var value = location;
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
return value;
}
@@ -102,7 +103,7 @@ namespace System.Threading
// The VM will replace this with a more efficient implementation.
//
var value = location;
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
return value;
}
@@ -114,7 +115,7 @@ namespace System.Threading
// The VM will replace this with a more efficient implementation.
//
var value = location;
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
return value;
}
@@ -126,7 +127,7 @@ namespace System.Threading
// The VM will replace this with a more efficient implementation.
//
var value = location;
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
return value;
}
#else
@@ -165,7 +166,7 @@ namespace System.Threading
// The VM will replace this with a more efficient implementation.
//
var value = location;
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
return value;
}
@@ -177,7 +178,7 @@ namespace System.Threading
// The VM will replace this with a more efficient implementation.
//
var value = location;
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
return value;
}
@@ -188,7 +189,7 @@ namespace System.Threading
// The VM will replace this with a more efficient implementation.
//
var value = location;
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
return value;
}
@@ -211,7 +212,7 @@ namespace System.Threading
// The VM will replace this with a more efficient implementation.
//
var value = location;
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
return value;
}
@@ -224,7 +225,7 @@ namespace System.Threading
//
// The VM will replace this with a more efficient implementation.
//
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
location = value;
}
@@ -235,7 +236,7 @@ namespace System.Threading
//
// The VM will replace this with a more efficient implementation.
//
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
location = value;
}
@@ -245,7 +246,7 @@ namespace System.Threading
//
// The VM will replace this with a more efficient implementation.
//
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
location = value;
}
@@ -255,7 +256,7 @@ namespace System.Threading
//
// The VM will replace this with a more efficient implementation.
//
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
location = value;
}
@@ -266,7 +267,7 @@ namespace System.Threading
//
// The VM will replace this with a more efficient implementation.
//
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
location = value;
}
@@ -276,7 +277,7 @@ namespace System.Threading
//
// The VM will replace this with a more efficient implementation.
//
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
location = value;
}
@@ -287,7 +288,7 @@ namespace System.Threading
//
// The VM will replace this with a more efficient implementation.
//
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
location = value;
}
@@ -298,7 +299,7 @@ namespace System.Threading
//
// The VM will replace this with a more efficient implementation.
//
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
location = value;
}
@@ -309,7 +310,7 @@ namespace System.Threading
//
// The VM will replace this with a more efficient implementation.
//
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
location = value;
}
#else
@@ -353,7 +354,7 @@ namespace System.Threading
//
// The VM will replace this with a more efficient implementation.
//
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
location = value;
}
@@ -364,7 +365,7 @@ namespace System.Threading
//
// The VM will replace this with a more efficient implementation.
//
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
location = value;
}
@@ -374,7 +375,7 @@ namespace System.Threading
//
// The VM will replace this with a more efficient implementation.
//
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
location = value;
}
@@ -396,7 +397,7 @@ namespace System.Threading
//
// The VM will replace this with a more efficient implementation.
//
- Thread.MemoryBarrier();
+ Interlocked.MemoryBarrier();
location = value;
}
}
diff --git a/src/mscorlib/src/System/Threading/WaitHandle.cs b/src/mscorlib/src/System/Threading/WaitHandle.cs
index d4dcd710be..f3412d264f 100644
--- a/src/mscorlib/src/System/Threading/WaitHandle.cs
+++ b/src/mscorlib/src/System/Threading/WaitHandle.cs
@@ -26,8 +26,9 @@ namespace System.Threading
using System.Diagnostics.CodeAnalysis;
using Win32Native = Microsoft.Win32.Win32Native;
- public abstract class WaitHandle : MarshalByRefObject, IDisposable {
- public const int WaitTimeout = 0x102;
+ public abstract class WaitHandle : MarshalByRefObject, IDisposable
+ {
+ public const int WaitTimeout = 0x102;
private const int MAX_WAITHANDLES = 64;
@@ -57,7 +58,7 @@ namespace System.Threading
NameInvalid
}
- protected WaitHandle()
+ protected WaitHandle()
{
Init();
}
@@ -68,12 +69,12 @@ namespace System.Threading
waitHandle = InvalidHandle;
hasThreadAffinity = false;
}
-
-
+
+
[Obsolete("Use the SafeWaitHandle property instead.")]
- public virtual IntPtr Handle
+ public virtual IntPtr Handle
{
- get { return safeWaitHandle == null ? InvalidHandle : safeWaitHandle.DangerousGetHandle();}
+ get { return safeWaitHandle == null ? InvalidHandle : safeWaitHandle.DangerousGetHandle(); }
set
{
if (value == InvalidHandle)
@@ -92,13 +93,13 @@ namespace System.Threading
}
else
{
- safeWaitHandle = new SafeWaitHandle(value, true);
+ safeWaitHandle = new SafeWaitHandle(value, true);
}
waitHandle = value;
}
}
- public SafeWaitHandle SafeWaitHandle
+ public SafeWaitHandle SafeWaitHandle
{
get
{
@@ -111,23 +112,23 @@ namespace System.Threading
set
{
- // Set safeWaitHandle and waitHandle in a CER so we won't take
- // a thread abort between the statements and leave the wait
- // handle in an invalid state. Note this routine is not thread
- // safe however.
- RuntimeHelpers.PrepareConstrainedRegions();
+ // Set safeWaitHandle and waitHandle in a CER so we won't take
+ // a thread abort between the statements and leave the wait
+ // handle in an invalid state. Note this routine is not thread
+ // safe however.
+ RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally
{
if (value == null)
{
- safeWaitHandle = null;
- waitHandle = InvalidHandle;
+ safeWaitHandle = null;
+ waitHandle = InvalidHandle;
}
else
{
- safeWaitHandle = value;
- waitHandle = safeWaitHandle.DangerousGetHandle();
+ safeWaitHandle = value;
+ waitHandle = safeWaitHandle.DangerousGetHandle();
}
}
}
@@ -147,41 +148,41 @@ namespace System.Threading
safeWaitHandle = handle;
waitHandle = handle.DangerousGetHandle();
}
-
- public virtual bool WaitOne (int millisecondsTimeout, bool exitContext)
+
+ public virtual bool WaitOne(int millisecondsTimeout, bool exitContext)
{
if (millisecondsTimeout < -1)
{
- throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
}
Contract.EndContractBlock();
- return WaitOne((long)millisecondsTimeout,exitContext);
+ return WaitOne((long)millisecondsTimeout, exitContext);
}
- public virtual bool WaitOne (TimeSpan timeout, bool exitContext)
+ public virtual bool WaitOne(TimeSpan timeout, bool exitContext)
{
long tm = (long)timeout.TotalMilliseconds;
- if (-1 > tm || (long) Int32.MaxValue < tm)
+ if (-1 > tm || (long)Int32.MaxValue < tm)
{
- throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
}
- return WaitOne(tm,exitContext);
+ return WaitOne(tm, exitContext);
}
- public virtual bool WaitOne ()
+ public virtual bool WaitOne()
{
//Infinite Timeout
- return WaitOne(-1,false);
+ return WaitOne(-1, false);
}
public virtual bool WaitOne(int millisecondsTimeout)
{
- return WaitOne(millisecondsTimeout, false);
+ return WaitOne(millisecondsTimeout, false);
}
public virtual bool WaitOne(TimeSpan timeout)
{
- return WaitOne(timeout, false);
+ return WaitOne(timeout, false);
}
[SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "Reviewed for thread-safety.")]
@@ -194,28 +195,28 @@ namespace System.Threading
{
if (waitableSafeHandle == null)
{
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_Generic"));
+ throw new ObjectDisposedException(null, SR.ObjectDisposed_Generic);
}
Contract.EndContractBlock();
int ret = WaitOneNative(waitableSafeHandle, (uint)millisecondsTimeout, hasThreadAffinity, exitContext);
- if(AppDomainPauseManager.IsPaused)
+ if (AppDomainPauseManager.IsPaused)
AppDomainPauseManager.ResumeEvent.WaitOneWithoutFAS();
-
+
if (ret == WAIT_ABANDONED)
{
ThrowAbandonedMutexException();
}
return (ret != WaitTimeout);
}
-
+
internal bool WaitOneWithoutFAS()
{
// version of waitone without fast application switch (FAS) support
// This is required to support the Wait which FAS needs (otherwise recursive dependency comes in)
if (safeWaitHandle == null)
{
- throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_Generic"));
+ throw new ObjectDisposedException(null, SR.ObjectDisposed_Generic);
}
Contract.EndContractBlock();
@@ -226,11 +227,11 @@ namespace System.Threading
ThrowAbandonedMutexException();
}
return (ret != WaitTimeout);
- }
+ }
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int WaitOneNative(SafeHandle waitableSafeHandle, uint millisecondsTimeout, bool hasThreadAffinity, bool exitContext);
-
+
/*========================================================================
** Waits for signal from all the objects.
** timeout indicates how long to wait before the method returns.
@@ -239,17 +240,17 @@ namespace System.Threading
** If exitContext is true then the synchronization domain for the context
** (if in a synchronized context) is exited before the wait and reacquired
========================================================================*/
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern int WaitMultiple(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext, bool WaitAll);
public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
{
if (waitHandles == null)
{
- throw new ArgumentNullException(nameof(waitHandles), Environment.GetResourceString("ArgumentNull_Waithandles"));
+ throw new ArgumentNullException(nameof(waitHandles), SR.ArgumentNull_Waithandles);
}
- if(waitHandles.Length == 0)
+ if (waitHandles.Length == 0)
{
//
// Some history: in CLR 1.0 and 1.1, we threw ArgumentException in this case, which was correct.
@@ -260,24 +261,24 @@ namespace System.Threading
// in CoreCLR, and ArgumentNullException in the desktop CLR. This is ugly, but so is breaking
// user code.
//
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyWaithandleArray"));
+ throw new ArgumentException(SR.Argument_EmptyWaithandleArray);
}
if (waitHandles.Length > MAX_WAITHANDLES)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_MaxWaitHandles"));
+ throw new NotSupportedException(SR.NotSupported_MaxWaitHandles);
}
if (-1 > millisecondsTimeout)
{
- throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
}
Contract.EndContractBlock();
WaitHandle[] internalWaitHandles = new WaitHandle[waitHandles.Length];
- for (int i = 0; i < waitHandles.Length; i ++)
+ for (int i = 0; i < waitHandles.Length; i++)
{
WaitHandle waitHandle = waitHandles[i];
if (waitHandle == null)
- throw new ArgumentNullException("waitHandles[" + i + "]", Environment.GetResourceString("ArgumentNull_ArrayElement"));
+ throw new ArgumentNullException("waitHandles[" + i + "]", SR.ArgumentNull_ArrayElement);
internalWaitHandles[i] = waitHandle;
}
@@ -288,51 +289,51 @@ namespace System.Threading
int ret = WaitMultiple(internalWaitHandles, millisecondsTimeout, exitContext, true /* waitall*/ );
- if(AppDomainPauseManager.IsPaused)
+ if (AppDomainPauseManager.IsPaused)
AppDomainPauseManager.ResumeEvent.WaitOneWithoutFAS();
- if ((WAIT_ABANDONED <= ret) && (WAIT_ABANDONED+internalWaitHandles.Length > ret))
+ if ((WAIT_ABANDONED <= ret) && (WAIT_ABANDONED + internalWaitHandles.Length > ret))
{
//In the case of WaitAll the OS will only provide the
// information that mutex was abandoned.
// It won't tell us which one. So we can't set the Index or provide access to the Mutex
ThrowAbandonedMutexException();
- }
+ }
GC.KeepAlive(internalWaitHandles);
return (ret != WaitTimeout);
}
public static bool WaitAll(
- WaitHandle[] waitHandles,
+ WaitHandle[] waitHandles,
TimeSpan timeout,
bool exitContext)
{
long tm = (long)timeout.TotalMilliseconds;
- if (-1 > tm || (long) Int32.MaxValue < tm)
+ if (-1 > tm || (long)Int32.MaxValue < tm)
{
- throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
}
- return WaitAll(waitHandles,(int)tm, exitContext);
+ return WaitAll(waitHandles, (int)tm, exitContext);
}
-
+
/*========================================================================
** Shorthand for WaitAll with timeout = Timeout.Infinite and exitContext = true
========================================================================*/
public static bool WaitAll(WaitHandle[] waitHandles)
{
- return WaitAll(waitHandles, Timeout.Infinite, true);
+ return WaitAll(waitHandles, Timeout.Infinite, true);
}
public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout)
{
- return WaitAll(waitHandles, millisecondsTimeout, true);
+ return WaitAll(waitHandles, millisecondsTimeout, true);
}
public static bool WaitAll(WaitHandle[] waitHandles, TimeSpan timeout)
{
- return WaitAll(waitHandles, timeout, true);
+ return WaitAll(waitHandles, timeout, true);
}
@@ -344,33 +345,33 @@ namespace System.Threading
** If exitContext is true then the synchronization domain for the context
** (if in a synchronized context) is exited before the wait and reacquired
========================================================================*/
-
+
public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
{
- if (waitHandles==null)
+ if (waitHandles == null)
{
- throw new ArgumentNullException(nameof(waitHandles), Environment.GetResourceString("ArgumentNull_Waithandles"));
+ throw new ArgumentNullException(nameof(waitHandles), SR.ArgumentNull_Waithandles);
}
- if(waitHandles.Length == 0)
+ if (waitHandles.Length == 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_EmptyWaithandleArray"));
+ throw new ArgumentException(SR.Argument_EmptyWaithandleArray);
}
if (MAX_WAITHANDLES < waitHandles.Length)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_MaxWaitHandles"));
+ throw new NotSupportedException(SR.NotSupported_MaxWaitHandles);
}
if (-1 > millisecondsTimeout)
{
- throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
}
Contract.EndContractBlock();
WaitHandle[] internalWaitHandles = new WaitHandle[waitHandles.Length];
- for (int i = 0; i < waitHandles.Length; i ++)
+ for (int i = 0; i < waitHandles.Length; i++)
{
WaitHandle waitHandle = waitHandles[i];
if (waitHandle == null)
- throw new ArgumentNullException("waitHandles[" + i + "]", Environment.GetResourceString("ArgumentNull_ArrayElement"));
+ throw new ArgumentNullException("waitHandles[" + i + "]", SR.ArgumentNull_ArrayElement);
internalWaitHandles[i] = waitHandle;
}
@@ -380,41 +381,41 @@ namespace System.Threading
#endif
int ret = WaitMultiple(internalWaitHandles, millisecondsTimeout, exitContext, false /* waitany*/ );
- if(AppDomainPauseManager.IsPaused)
+ if (AppDomainPauseManager.IsPaused)
AppDomainPauseManager.ResumeEvent.WaitOneWithoutFAS();
- if ((WAIT_ABANDONED <= ret) && (WAIT_ABANDONED+internalWaitHandles.Length > ret))
+ if ((WAIT_ABANDONED <= ret) && (WAIT_ABANDONED + internalWaitHandles.Length > ret))
{
- int mutexIndex = ret -WAIT_ABANDONED;
- if(0 <= mutexIndex && mutexIndex < internalWaitHandles.Length)
+ int mutexIndex = ret - WAIT_ABANDONED;
+ if (0 <= mutexIndex && mutexIndex < internalWaitHandles.Length)
{
- ThrowAbandonedMutexException(mutexIndex,internalWaitHandles[mutexIndex]);
+ ThrowAbandonedMutexException(mutexIndex, internalWaitHandles[mutexIndex]);
}
else
{
ThrowAbandonedMutexException();
}
}
-
+
GC.KeepAlive(internalWaitHandles);
- return ret;
+ return ret;
}
public static int WaitAny(
- WaitHandle[] waitHandles,
+ WaitHandle[] waitHandles,
TimeSpan timeout,
bool exitContext)
{
long tm = (long)timeout.TotalMilliseconds;
- if (-1 > tm || (long) Int32.MaxValue < tm)
+ if (-1 > tm || (long)Int32.MaxValue < tm)
{
- throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
}
- return WaitAny(waitHandles,(int)tm, exitContext);
+ return WaitAny(waitHandles, (int)tm, exitContext);
}
public static int WaitAny(WaitHandle[] waitHandles, TimeSpan timeout)
{
- return WaitAny(waitHandles, timeout, true);
+ return WaitAny(waitHandles, timeout, true);
}
@@ -428,7 +429,7 @@ namespace System.Threading
public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout)
{
- return WaitAny(waitHandles, millisecondsTimeout, true);
+ return WaitAny(waitHandles, millisecondsTimeout, true);
}
/*=================================================
@@ -436,20 +437,20 @@ namespace System.Threading
== SignalAndWait
==
==================================================*/
-#if !PLATFORM_UNIX
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern int SignalAndWaitOne(SafeWaitHandle waitHandleToSignal,SafeWaitHandle waitHandleToWaitOn, int millisecondsTimeout,
- bool hasThreadAffinity, bool exitContext);
-#endif // !PLATFORM_UNIX
+#if PLATFORM_WINDOWS
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern int SignalAndWaitOne(SafeWaitHandle waitHandleToSignal, SafeWaitHandle waitHandleToWaitOn, int millisecondsTimeout,
+ bool hasThreadAffinity, bool exitContext);
+#endif // PLATFORM_WINDOWS
public static bool SignalAndWait(
WaitHandle toSignal,
WaitHandle toWaitOn)
{
#if PLATFORM_UNIX
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.Arg_PlatformNotSupported); // https://github.com/dotnet/coreclr/issues/10441
#else
- return SignalAndWait(toSignal,toWaitOn,-1,false);
+ return SignalAndWait(toSignal, toWaitOn, -1, false);
#endif
}
@@ -460,14 +461,14 @@ namespace System.Threading
bool exitContext)
{
#if PLATFORM_UNIX
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.Arg_PlatformNotSupported); // https://github.com/dotnet/coreclr/issues/10441
#else
long tm = (long)timeout.TotalMilliseconds;
- if (-1 > tm || (long) Int32.MaxValue < tm)
+ if (-1 > tm || (long)Int32.MaxValue < tm)
{
- throw new ArgumentOutOfRangeException(nameof(timeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(timeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
}
- return SignalAndWait(toSignal,toWaitOn,(int)tm,exitContext);
+ return SignalAndWait(toSignal, toWaitOn, (int)tm, exitContext);
#endif
}
@@ -479,38 +480,38 @@ namespace System.Threading
bool exitContext)
{
#if PLATFORM_UNIX
- throw new PlatformNotSupportedException();
+ throw new PlatformNotSupportedException(SR.Arg_PlatformNotSupported); // https://github.com/dotnet/coreclr/issues/10441
#else
- if(null == toSignal)
+ if (null == toSignal)
{
throw new ArgumentNullException(nameof(toSignal));
}
- if(null == toWaitOn)
+ if (null == toWaitOn)
{
throw new ArgumentNullException(nameof(toWaitOn));
}
if (-1 > millisecondsTimeout)
{
- throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
+ throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), SR.ArgumentOutOfRange_NeedNonNegOrNegative1);
}
Contract.EndContractBlock();
//NOTE: This API is not supporting Pause/Resume as it's not exposed in CoreCLR (not in WP or SL)
- int ret = SignalAndWaitOne(toSignal.safeWaitHandle,toWaitOn.safeWaitHandle,millisecondsTimeout,
- toWaitOn.hasThreadAffinity,exitContext);
+ int ret = SignalAndWaitOne(toSignal.safeWaitHandle, toWaitOn.safeWaitHandle, millisecondsTimeout,
+ toWaitOn.hasThreadAffinity, exitContext);
- if(WAIT_ABANDONED == ret)
+ if (WAIT_ABANDONED == ret)
{
ThrowAbandonedMutexException();
}
- if(ERROR_TOO_MANY_POSTS == ret)
+ if (ERROR_TOO_MANY_POSTS == ret)
{
- throw new InvalidOperationException(Environment.GetResourceString("Threading.WaitHandleTooManyPosts"));
+ throw new InvalidOperationException(SR.Threading_WaitHandleTooManyPosts);
}
//Object was signaled
- if(WAIT_OBJECT_0 == ret)
+ if (WAIT_OBJECT_0 == ret)
{
return true;
}
@@ -535,7 +536,7 @@ namespace System.Threading
Dispose(true);
GC.SuppressFinalize(this);
}
-
+
protected virtual void Dispose(bool explicitDisposing)
{
if (safeWaitHandle != null)
diff --git a/src/mscorlib/src/System/Threading/WaitHandleCannotBeOpenedException.cs b/src/mscorlib/src/System/Threading/WaitHandleCannotBeOpenedException.cs
deleted file mode 100644
index 68445a78d9..0000000000
--- a/src/mscorlib/src/System/Threading/WaitHandleCannotBeOpenedException.cs
+++ /dev/null
@@ -1,36 +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.
-
-//
-namespace System.Threading
-{
- using System;
- using System.Runtime.Serialization;
- using System.Runtime.InteropServices;
-
- [Serializable]
- [ComVisibleAttribute(false)]
-
- public class WaitHandleCannotBeOpenedException : ApplicationException {
- public WaitHandleCannotBeOpenedException() : base(Environment.GetResourceString("Threading.WaitHandleCannotBeOpenedException"))
- {
- SetErrorCode(__HResults.COR_E_WAITHANDLECANNOTBEOPENED);
- }
-
- public WaitHandleCannotBeOpenedException(String message) : base(message)
- {
- SetErrorCode(__HResults.COR_E_WAITHANDLECANNOTBEOPENED);
- }
-
- public WaitHandleCannotBeOpenedException(String message, Exception innerException) : base(message, innerException)
- {
- SetErrorCode(__HResults.COR_E_WAITHANDLECANNOTBEOPENED);
- }
-
- protected WaitHandleCannotBeOpenedException(SerializationInfo info, StreamingContext context) : base (info, context)
- {
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/ThrowHelper.cs b/src/mscorlib/src/System/ThrowHelper.cs
index 1ed8317633..4dcf8d4511 100644
--- a/src/mscorlib/src/System/ThrowHelper.cs
+++ b/src/mscorlib/src/System/ThrowHelper.cs
@@ -3,220 +3,261 @@
// See the LICENSE file in the project root for more information.
-namespace System {
- // This file defines an internal class used to throw exceptions in BCL code.
- // The main purpose is to reduce code size.
- //
- // The old way to throw an exception generates quite a lot IL code and assembly code.
- // Following is an example:
- // C# source
- // throw new ArgumentNullException(nameof(key), Environment.GetResourceString("ArgumentNull_Key"));
- // IL code:
- // IL_0003: ldstr "key"
- // IL_0008: ldstr "ArgumentNull_Key"
- // IL_000d: call string System.Environment::GetResourceString(string)
- // IL_0012: newobj instance void System.ArgumentNullException::.ctor(string,string)
- // IL_0017: throw
- // which is 21bytes in IL.
- //
- // So we want to get rid of the ldstr and call to Environment.GetResource in IL.
- // In order to do that, I created two enums: ExceptionResource, ExceptionArgument to represent the
- // argument name and resource name in a small integer. The source code will be changed to
- // ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key, ExceptionResource.ArgumentNull_Key);
- //
- // The IL code will be 7 bytes.
- // IL_0008: ldc.i4.4
- // IL_0009: ldc.i4.4
- // IL_000a: call void System.ThrowHelper::ThrowArgumentNullException(valuetype System.ExceptionArgument)
- // IL_000f: ldarg.0
- //
- // This will also reduce the Jitted code size a lot.
- //
- // It is very important we do this for generic classes because we can easily generate the same code
- // multiple times for different instantiation.
- //
-
- using Collections.Generic;
- using System.Runtime.CompilerServices;
- using System.Runtime.Serialization;
- using System.Diagnostics.Contracts;
-
+// This file defines an internal class used to throw exceptions in BCL code.
+// The main purpose is to reduce code size.
+//
+// The old way to throw an exception generates quite a lot IL code and assembly code.
+// Following is an example:
+// C# source
+// throw new ArgumentNullException(nameof(key), SR.ArgumentNull_Key);
+// IL code:
+// IL_0003: ldstr "key"
+// IL_0008: ldstr "ArgumentNull_Key"
+// IL_000d: call string System.Environment::GetResourceString(string)
+// IL_0012: newobj instance void System.ArgumentNullException::.ctor(string,string)
+// IL_0017: throw
+// which is 21bytes in IL.
+//
+// So we want to get rid of the ldstr and call to Environment.GetResource in IL.
+// In order to do that, I created two enums: ExceptionResource, ExceptionArgument to represent the
+// argument name and resource name in a small integer. The source code will be changed to
+// ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key, ExceptionResource.ArgumentNull_Key);
+//
+// The IL code will be 7 bytes.
+// IL_0008: ldc.i4.4
+// IL_0009: ldc.i4.4
+// IL_000a: call void System.ThrowHelper::ThrowArgumentNullException(valuetype System.ExceptionArgument)
+// IL_000f: ldarg.0
+//
+// This will also reduce the Jitted code size a lot.
+//
+// It is very important we do this for generic classes because we can easily generate the same code
+// multiple times for different instantiation.
+//
+
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Runtime.Serialization;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
[Pure]
- internal static class ThrowHelper {
- internal static void ThrowArrayTypeMismatchException() {
+ internal static class ThrowHelper
+ {
+ internal static void ThrowArrayTypeMismatchException()
+ {
throw new ArrayTypeMismatchException();
}
- internal static void ThrowInvalidTypeWithPointersNotSupported(Type targetType) {
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeWithPointersNotSupported", targetType));
+ internal static void ThrowInvalidTypeWithPointersNotSupported(Type targetType)
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidTypeWithPointersNotSupported, targetType));
}
- internal static void ThrowIndexOutOfRangeException() {
+ internal static void ThrowIndexOutOfRangeException()
+ {
throw new IndexOutOfRangeException();
}
- internal static void ThrowArgumentOutOfRangeException() {
+ internal static void ThrowArgumentOutOfRangeException()
+ {
throw new ArgumentOutOfRangeException();
}
- internal static void ThrowArgumentException_DestinationTooShort() {
- throw new ArgumentException(Environment.GetResourceString("Argument_DestinationTooShort"));
- }
-
- internal static void ThrowNotSupportedException_CannotCallEqualsOnSpan() {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_CannotCallEqualsOnSpan"));
- }
-
- internal static void ThrowNotSupportedException_CannotCallGetHashCodeOnSpan() {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_CannotCallGetHashCodeOnSpan"));
+ internal static void ThrowArgumentException_DestinationTooShort()
+ {
+ throw new ArgumentException(SR.Argument_DestinationTooShort);
}
- internal static void ThrowArgumentOutOfRange_IndexException() {
- throw GetArgumentOutOfRangeException(ExceptionArgument.index,
+ internal static void ThrowArgumentOutOfRange_IndexException()
+ {
+ throw GetArgumentOutOfRangeException(ExceptionArgument.index,
ExceptionResource.ArgumentOutOfRange_Index);
}
- internal static void ThrowIndexArgumentOutOfRange_NeedNonNegNumException() {
- throw GetArgumentOutOfRangeException(ExceptionArgument.index,
+ internal static void ThrowIndexArgumentOutOfRange_NeedNonNegNumException()
+ {
+ throw GetArgumentOutOfRangeException(ExceptionArgument.index,
ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
- internal static void ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum() {
+ internal static void ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum()
+ {
throw GetArgumentOutOfRangeException(ExceptionArgument.length,
ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
- internal static void ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index() {
+ internal static void ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index()
+ {
throw GetArgumentOutOfRangeException(ExceptionArgument.startIndex,
ExceptionResource.ArgumentOutOfRange_Index);
}
- internal static void ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count() {
+ internal static void ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count()
+ {
throw GetArgumentOutOfRangeException(ExceptionArgument.count,
ExceptionResource.ArgumentOutOfRange_Count);
}
- internal static void ThrowWrongKeyTypeArgumentException(object key, Type targetType) {
+ internal static void ThrowWrongKeyTypeArgumentException(object key, Type targetType)
+ {
throw GetWrongKeyTypeArgumentException(key, targetType);
}
- internal static void ThrowWrongValueTypeArgumentException(object value, Type targetType) {
+ internal static void ThrowWrongValueTypeArgumentException(object value, Type targetType)
+ {
throw GetWrongValueTypeArgumentException(value, targetType);
}
- private static ArgumentException GetAddingDuplicateWithKeyArgumentException(object key) {
- return new ArgumentException(Environment.GetResourceString("Argument_AddingDuplicateWithKey", key));
+ private static ArgumentException GetAddingDuplicateWithKeyArgumentException(object key)
+ {
+ return new ArgumentException(SR.Format(SR.Argument_AddingDuplicateWithKey, key));
}
- internal static void ThrowAddingDuplicateWithKeyArgumentException(object key) {
+ internal static void ThrowAddingDuplicateWithKeyArgumentException(object key)
+ {
throw GetAddingDuplicateWithKeyArgumentException(key);
}
- internal static void ThrowKeyNotFoundException() {
+ internal static void ThrowKeyNotFoundException()
+ {
throw new System.Collections.Generic.KeyNotFoundException();
}
-
- internal static void ThrowArgumentException(ExceptionResource resource) {
+
+ internal static void ThrowArgumentException(ExceptionResource resource)
+ {
throw GetArgumentException(resource);
}
- internal static void ThrowArgumentException(ExceptionResource resource, ExceptionArgument argument) {
+ internal static void ThrowArgumentException(ExceptionResource resource, ExceptionArgument argument)
+ {
throw GetArgumentException(resource, argument);
}
- private static ArgumentNullException GetArgumentNullException(ExceptionArgument argument) {
+ private static ArgumentNullException GetArgumentNullException(ExceptionArgument argument)
+ {
return new ArgumentNullException(GetArgumentName(argument));
}
- internal static void ThrowArgumentNullException(ExceptionArgument argument) {
+ internal static void ThrowArgumentNullException(ExceptionArgument argument)
+ {
throw GetArgumentNullException(argument);
}
- internal static void ThrowArgumentNullException(ExceptionResource resource) {
+ internal static void ThrowArgumentNullException(ExceptionResource resource)
+ {
throw new ArgumentNullException(GetResourceString(resource));
}
- internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument) {
+ internal static void ThrowArgumentNullException(ExceptionArgument argument, ExceptionResource resource)
+ {
+ throw new ArgumentNullException(GetArgumentName(argument), GetResourceString(resource));
+ }
+
+ internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument)
+ {
throw new ArgumentOutOfRangeException(GetArgumentName(argument));
}
- internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) {
+ internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
+ {
throw GetArgumentOutOfRangeException(argument, resource);
}
- internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument, int paramNumber, ExceptionResource resource) {
+ internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument, int paramNumber, ExceptionResource resource)
+ {
throw GetArgumentOutOfRangeException(argument, paramNumber, resource);
}
- internal static void ThrowInvalidOperationException(ExceptionResource resource) {
+ internal static void ThrowInvalidOperationException(ExceptionResource resource)
+ {
throw GetInvalidOperationException(resource);
}
- internal static void ThrowInvalidOperationException(ExceptionResource resource, Exception e) {
+ internal static void ThrowInvalidOperationException(ExceptionResource resource, Exception e)
+ {
throw new InvalidOperationException(GetResourceString(resource), e);
}
- internal static void ThrowSerializationException(ExceptionResource resource) {
+ internal static void ThrowSerializationException(ExceptionResource resource)
+ {
throw new SerializationException(GetResourceString(resource));
}
- internal static void ThrowSecurityException(ExceptionResource resource) {
+ internal static void ThrowSecurityException(ExceptionResource resource)
+ {
throw new System.Security.SecurityException(GetResourceString(resource));
}
- internal static void ThrowRankException(ExceptionResource resource) {
+ internal static void ThrowRankException(ExceptionResource resource)
+ {
throw new RankException(GetResourceString(resource));
}
- internal static void ThrowNotSupportedException(ExceptionResource resource) {
+ internal static void ThrowNotSupportedException(ExceptionResource resource)
+ {
throw new NotSupportedException(GetResourceString(resource));
}
- internal static void ThrowUnauthorizedAccessException(ExceptionResource resource) {
+ internal static void ThrowUnauthorizedAccessException(ExceptionResource resource)
+ {
throw new UnauthorizedAccessException(GetResourceString(resource));
}
- internal static void ThrowObjectDisposedException(string objectName, ExceptionResource resource) {
+ internal static void ThrowObjectDisposedException(string objectName, ExceptionResource resource)
+ {
throw new ObjectDisposedException(objectName, GetResourceString(resource));
}
- internal static void ThrowObjectDisposedException(ExceptionResource resource) {
+ internal static void ThrowObjectDisposedException(ExceptionResource resource)
+ {
throw new ObjectDisposedException(null, GetResourceString(resource));
}
- internal static void ThrowNotSupportedException() {
+ internal static void ThrowNotSupportedException()
+ {
throw new NotSupportedException();
}
- internal static void ThrowAggregateException(List<Exception> exceptions) {
+ internal static void ThrowAggregateException(List<Exception> exceptions)
+ {
throw new AggregateException(exceptions);
}
- internal static void ThrowArgumentException_Argument_InvalidArrayType() {
+ internal static void ThrowArgumentException_Argument_InvalidArrayType()
+ {
throw GetArgumentException(ExceptionResource.Argument_InvalidArrayType);
}
- internal static void ThrowInvalidOperationException_InvalidOperation_EnumNotStarted() {
+ internal static void ThrowInvalidOperationException_InvalidOperation_EnumNotStarted()
+ {
throw GetInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted);
}
- internal static void ThrowInvalidOperationException_InvalidOperation_EnumEnded() {
+ internal static void ThrowInvalidOperationException_InvalidOperation_EnumEnded()
+ {
throw GetInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded);
}
- internal static void ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion() {
+ internal static void ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion()
+ {
throw GetInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
}
- internal static void ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen() {
+ internal static void ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen()
+ {
throw GetInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
}
- internal static void ThrowArraySegmentCtorValidationFailedExceptions(Array array, int offset, int count) {
+ internal static void ThrowArraySegmentCtorValidationFailedExceptions(Array array, int offset, int count)
+ {
throw GetArraySegmentCtorValidationFailedException(array, offset, count);
}
- private static Exception GetArraySegmentCtorValidationFailedException(Array array, int offset, int count) {
+ private static Exception GetArraySegmentCtorValidationFailedException(Array array, int offset, int count)
+ {
if (array == null)
return GetArgumentNullException(ExceptionArgument.array);
if (offset < 0)
@@ -228,31 +269,38 @@ namespace System {
return GetArgumentException(ExceptionResource.Argument_InvalidOffLen);
}
- private static ArgumentException GetArgumentException(ExceptionResource resource) {
+ private static ArgumentException GetArgumentException(ExceptionResource resource)
+ {
return new ArgumentException(GetResourceString(resource));
}
- internal static InvalidOperationException GetInvalidOperationException(ExceptionResource resource) {
+ internal static InvalidOperationException GetInvalidOperationException(ExceptionResource resource)
+ {
return new InvalidOperationException(GetResourceString(resource));
}
- private static ArgumentException GetWrongKeyTypeArgumentException(object key, Type targetType) {
- return new ArgumentException(Environment.GetResourceString("Arg_WrongType", key, targetType), nameof(key));
+ private static ArgumentException GetWrongKeyTypeArgumentException(object key, Type targetType)
+ {
+ return new ArgumentException(SR.Format(SR.Arg_WrongType, key, targetType), nameof(key));
}
- private static ArgumentException GetWrongValueTypeArgumentException(object value, Type targetType) {
- return new ArgumentException(Environment.GetResourceString("Arg_WrongType", value, targetType), nameof(value));
+ private static ArgumentException GetWrongValueTypeArgumentException(object value, Type targetType)
+ {
+ return new ArgumentException(SR.Format(SR.Arg_WrongType, value, targetType), nameof(value));
}
- internal static ArgumentOutOfRangeException GetArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) {
+ internal static ArgumentOutOfRangeException GetArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
+ {
return new ArgumentOutOfRangeException(GetArgumentName(argument), GetResourceString(resource));
}
- private static ArgumentException GetArgumentException(ExceptionResource resource, ExceptionArgument argument) {
+ private static ArgumentException GetArgumentException(ExceptionResource resource, ExceptionArgument argument)
+ {
return new ArgumentException(GetResourceString(resource), GetArgumentName(argument));
}
- private static ArgumentOutOfRangeException GetArgumentOutOfRangeException(ExceptionArgument argument, int paramNumber, ExceptionResource resource) {
+ private static ArgumentOutOfRangeException GetArgumentOutOfRangeException(ExceptionArgument argument, int paramNumber, ExceptionResource resource)
+ {
return new ArgumentOutOfRangeException(GetArgumentName(argument) + "[" + paramNumber.ToString() + "]", GetResourceString(resource));
}
@@ -260,25 +308,17 @@ namespace System {
// Aggressively inline so the jit evaluates the if in place and either drops the call altogether
// Or just leaves null test and call to the Non-returning ThrowHelper.ThrowArgumentNullException
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static void IfNullAndNullsAreIllegalThenThrow<T>(object value, ExceptionArgument argName) {
+ internal static void IfNullAndNullsAreIllegalThenThrow<T>(object value, ExceptionArgument argName)
+ {
// Note that default(T) is not equal to null for value types except when T is Nullable<U>.
if (!(default(T) == null) && value == null)
ThrowHelper.ThrowArgumentNullException(argName);
}
// This function will convert an ExceptionArgument enum value to the argument name string.
- private static string GetArgumentName(ExceptionArgument argument) {
- // This is indirected through a second NoInlining function it has a special meaning
- // in System.Private.CoreLib of indicatating it takes a StackMark which cause
- // the caller to also be not inlined; so we can't mark it directly.
- // So is the effect of marking this function as non-inlining in a regular situation.
- return GetArgumentNameInner(argument);
- }
-
- // This function will convert an ExceptionArgument enum value to the argument name string.
- // Second function in chain so as to not propergate the non-inlining to outside caller
[MethodImpl(MethodImplOptions.NoInlining)]
- private static string GetArgumentNameInner(ExceptionArgument argument) {
+ private static string GetArgumentName(ExceptionArgument argument)
+ {
Debug.Assert(Enum.IsDefined(typeof(ExceptionArgument), argument),
"The enum value is not defined, please check the ExceptionArgument Enum.");
@@ -286,29 +326,21 @@ namespace System {
}
// This function will convert an ExceptionResource enum value to the resource string.
- private static string GetResourceString(ExceptionResource resource) {
- // This is indirected through a second NoInlining function it has a special meaning
- // in System.Private.CoreLib of indicatating it takes a StackMark which cause
- // the caller to also be not inlined; so we can't mark it directly.
- // So is the effect of marking this function as non-inlining in a regular situation.
- return GetResourceStringInner(resource);
- }
-
- // This function will convert an ExceptionResource enum value to the resource string.
- // Second function in chain so as to not propergate the non-inlining to outside caller
[MethodImpl(MethodImplOptions.NoInlining)]
- private static string GetResourceStringInner(ExceptionResource resource) {
+ private static string GetResourceString(ExceptionResource resource)
+ {
Debug.Assert(Enum.IsDefined(typeof(ExceptionResource), resource),
"The enum value is not defined, please check the ExceptionResource Enum.");
- return Environment.GetResourceString(resource.ToString());
+ return SR.GetResourceString(resource.ToString());
}
}
//
// The convention for this enum is using the argument name as the enum name
//
- internal enum ExceptionArgument {
+ internal enum ExceptionArgument
+ {
obj,
dictionary,
dictionaryCreationThreshold,
@@ -382,28 +414,31 @@ namespace System {
text,
callBack,
type,
+ stateMachine,
+ pHandle,
}
//
// The convention for this enum is using the resource name as the enum name
//
- internal enum ExceptionResource {
+ internal enum ExceptionResource
+ {
Argument_ImplementIComparable,
- Argument_InvalidType,
+ Argument_InvalidType,
Argument_InvalidArgumentForComparison,
- Argument_InvalidRegistryKeyPermissionCheck,
+ Argument_InvalidRegistryKeyPermissionCheck,
ArgumentOutOfRange_NeedNonNegNum,
-
+
Arg_ArrayPlusOffTooSmall,
- Arg_NonZeroLowerBound,
- Arg_RankMultiDimNotSupported,
+ Arg_NonZeroLowerBound,
+ Arg_RankMultiDimNotSupported,
Arg_RegKeyDelHive,
- Arg_RegKeyStrLenBug,
+ Arg_RegKeyStrLenBug,
Arg_RegSetStrArrNull,
Arg_RegSetMismatchedKind,
- Arg_RegSubKeyAbsent,
+ Arg_RegSubKeyAbsent,
Arg_RegSubKeyValueAbsent,
-
+
Argument_AddingDuplicate,
Serialization_InvalidOnDeser,
Serialization_MissingKeys,
@@ -487,6 +522,8 @@ namespace System {
ConcurrentCollection_SyncRoot_NotSupported,
ArgumentOutOfRange_Enum,
InvalidOperation_HandleIsNotInitialized,
+ AsyncMethodBuilder_InstanceNotInitialized,
+ ArgumentNull_SafeHandle,
}
}
diff --git a/src/mscorlib/src/System/TimeSpan.cs b/src/mscorlib/src/System/TimeSpan.cs
index 7b71b48fed..9166656d0f 100644
--- a/src/mscorlib/src/System/TimeSpan.cs
+++ b/src/mscorlib/src/System/TimeSpan.cs
@@ -2,15 +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.
-namespace System {
- using System.Text;
- using System;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Diagnostics.Contracts;
- using System.Globalization;
-
+using System.Text;
+using System;
+using System.Runtime;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+
+namespace System
+{
// TimeSpan represents a duration of time. A TimeSpan can be negative
// or positive.
//
@@ -28,14 +29,15 @@ namespace System {
// details of this type should change, or new fields added, we need to remember to add
// an appropriate custom ILMarshaler to keep WInRT interop scenarios enabled.
//
- [Serializable] public struct TimeSpan : IComparable
+ [Serializable]
+ public struct TimeSpan : IComparable
, IComparable<TimeSpan>, IEquatable<TimeSpan>, IFormattable
{
- public const long TicksPerMillisecond = 10000;
+ public const long TicksPerMillisecond = 10000;
private const double MillisecondsPerTick = 1.0 / TicksPerMillisecond;
public const long TicksPerSecond = TicksPerMillisecond * 1000; // 10,000,000
- private const double SecondsPerTick = 1.0 / TicksPerSecond; // 0.0001
+ private const double SecondsPerTick = 1.0 / TicksPerSecond; // 0.0001
public const long TicksPerMinute = TicksPerSecond * 60; // 600,000,000
private const double MinutesPerTick = 1.0 / TicksPerMinute; // 1.6666666666667e-9
@@ -72,16 +74,18 @@ namespace System {
// _ticks = 0;
//}
- public TimeSpan(long ticks) {
+ public TimeSpan(long ticks)
+ {
this._ticks = ticks;
}
- public TimeSpan(int hours, int minutes, int seconds) {
+ public TimeSpan(int hours, int minutes, int seconds)
+ {
_ticks = TimeToTicks(hours, minutes, seconds);
}
public TimeSpan(int days, int hours, int minutes, int seconds)
- : this(days,hours,minutes,seconds,0)
+ : this(days, hours, minutes, seconds, 0)
{
}
@@ -89,44 +93,54 @@ namespace System {
{
Int64 totalMilliSeconds = ((Int64)days * 3600 * 24 + (Int64)hours * 3600 + (Int64)minutes * 60 + seconds) * 1000 + milliseconds;
if (totalMilliSeconds > MaxMilliSeconds || totalMilliSeconds < MinMilliSeconds)
- throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("Overflow_TimeSpanTooLong"));
- _ticks = (long)totalMilliSeconds * TicksPerMillisecond;
+ throw new ArgumentOutOfRangeException(null, SR.Overflow_TimeSpanTooLong);
+ _ticks = (long)totalMilliSeconds * TicksPerMillisecond;
}
- public long Ticks {
+ public long Ticks
+ {
get { return _ticks; }
}
- public int Days {
+ public int Days
+ {
get { return (int)(_ticks / TicksPerDay); }
}
- public int Hours {
+ public int Hours
+ {
get { return (int)((_ticks / TicksPerHour) % 24); }
}
- public int Milliseconds {
+ public int Milliseconds
+ {
get { return (int)((_ticks / TicksPerMillisecond) % 1000); }
}
- public int Minutes {
+ public int Minutes
+ {
get { return (int)((_ticks / TicksPerMinute) % 60); }
}
- public int Seconds {
+ public int Seconds
+ {
get { return (int)((_ticks / TicksPerSecond) % 60); }
}
- public double TotalDays {
+ public double TotalDays
+ {
get { return ((double)_ticks) * DaysPerTick; }
}
- public double TotalHours {
+ public double TotalHours
+ {
get { return (double)_ticks * HoursPerTick; }
}
- public double TotalMilliseconds {
- get {
+ public double TotalMilliseconds
+ {
+ get
+ {
double temp = (double)_ticks * MillisecondsPerTick;
if (temp > MaxMilliSeconds)
return (double)MaxMilliSeconds;
@@ -138,21 +152,24 @@ namespace System {
}
}
- public double TotalMinutes {
+ public double TotalMinutes
+ {
get { return (double)_ticks * MinutesPerTick; }
}
- public double TotalSeconds {
+ public double TotalSeconds
+ {
get { return (double)_ticks * SecondsPerTick; }
}
- public TimeSpan Add(TimeSpan ts) {
+ public TimeSpan Add(TimeSpan ts)
+ {
long result = _ticks + ts._ticks;
// Overflow if signs of operands was identical and result's
// sign was opposite.
// >> 63 gives the sign bit (either 64 1's or 64 0's).
if ((_ticks >> 63 == ts._ticks >> 63) && (_ticks >> 63 != result >> 63))
- throw new OverflowException(Environment.GetResourceString("Overflow_TimeSpanTooLong"));
+ throw new OverflowException(SR.Overflow_TimeSpanTooLong);
return new TimeSpan(result);
}
@@ -160,43 +177,50 @@ namespace System {
// Compares two TimeSpan values, returning an integer that indicates their
// relationship.
//
- public static int Compare(TimeSpan t1, TimeSpan t2) {
+ public static int Compare(TimeSpan t1, TimeSpan t2)
+ {
if (t1._ticks > t2._ticks) return 1;
if (t1._ticks < t2._ticks) return -1;
return 0;
}
// Returns a value less than zero if this object
- public int CompareTo(Object value) {
+ public int CompareTo(Object value)
+ {
if (value == null) return 1;
if (!(value is TimeSpan))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeTimeSpan"));
+ throw new ArgumentException(SR.Arg_MustBeTimeSpan);
long t = ((TimeSpan)value)._ticks;
if (_ticks > t) return 1;
if (_ticks < t) return -1;
return 0;
}
- public int CompareTo(TimeSpan value) {
+ public int CompareTo(TimeSpan value)
+ {
long t = value._ticks;
if (_ticks > t) return 1;
if (_ticks < t) return -1;
return 0;
}
- public static TimeSpan FromDays(double value) {
+ public static TimeSpan FromDays(double value)
+ {
return Interval(value, MillisPerDay);
}
- public TimeSpan Duration() {
- if (Ticks==TimeSpan.MinValue.Ticks)
- throw new OverflowException(Environment.GetResourceString("Overflow_Duration"));
+ public TimeSpan Duration()
+ {
+ if (Ticks == TimeSpan.MinValue.Ticks)
+ throw new OverflowException(SR.Overflow_Duration);
Contract.EndContractBlock();
- return new TimeSpan(_ticks >= 0? _ticks: -_ticks);
+ return new TimeSpan(_ticks >= 0 ? _ticks : -_ticks);
}
- public override bool Equals(Object value) {
- if (value is TimeSpan) {
+ public override bool Equals(Object value)
+ {
+ if (value is TimeSpan)
+ {
return _ticks == ((TimeSpan)value)._ticks;
}
return false;
@@ -207,169 +231,255 @@ namespace System {
return _ticks == obj._ticks;
}
- public static bool Equals(TimeSpan t1, TimeSpan t2) {
+ public static bool Equals(TimeSpan t1, TimeSpan t2)
+ {
return t1._ticks == t2._ticks;
}
- public override int GetHashCode() {
+ public override int GetHashCode()
+ {
return (int)_ticks ^ (int)(_ticks >> 32);
}
- public static TimeSpan FromHours(double value) {
+ public static TimeSpan FromHours(double value)
+ {
return Interval(value, MillisPerHour);
}
- private static TimeSpan Interval(double value, int scale) {
+ private static TimeSpan Interval(double value, int scale)
+ {
if (Double.IsNaN(value))
- throw new ArgumentException(Environment.GetResourceString("Arg_CannotBeNaN"));
+ throw new ArgumentException(SR.Arg_CannotBeNaN);
Contract.EndContractBlock();
double tmp = value * scale;
- double millis = tmp + (value >= 0? 0.5: -0.5);
+ double millis = tmp + (value >= 0 ? 0.5 : -0.5);
if ((millis > Int64.MaxValue / TicksPerMillisecond) || (millis < Int64.MinValue / TicksPerMillisecond))
- throw new OverflowException(Environment.GetResourceString("Overflow_TimeSpanTooLong"));
+ throw new OverflowException(SR.Overflow_TimeSpanTooLong);
return new TimeSpan((long)millis * TicksPerMillisecond);
}
- public static TimeSpan FromMilliseconds(double value) {
+ public static TimeSpan FromMilliseconds(double value)
+ {
return Interval(value, 1);
}
- public static TimeSpan FromMinutes(double value) {
+ public static TimeSpan FromMinutes(double value)
+ {
return Interval(value, MillisPerMinute);
}
- public TimeSpan Negate() {
- if (Ticks==TimeSpan.MinValue.Ticks)
- throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum"));
+ public TimeSpan Negate()
+ {
+ if (Ticks == TimeSpan.MinValue.Ticks)
+ throw new OverflowException(SR.Overflow_NegateTwosCompNum);
Contract.EndContractBlock();
return new TimeSpan(-_ticks);
}
- public static TimeSpan FromSeconds(double value) {
+ public static TimeSpan FromSeconds(double value)
+ {
return Interval(value, MillisPerSecond);
}
- public TimeSpan Subtract(TimeSpan ts) {
+ public TimeSpan Subtract(TimeSpan ts)
+ {
long result = _ticks - ts._ticks;
// Overflow if signs of operands was different and result's
// sign was opposite from the first argument's sign.
// >> 63 gives the sign bit (either 64 1's or 64 0's).
if ((_ticks >> 63 != ts._ticks >> 63) && (_ticks >> 63 != result >> 63))
- throw new OverflowException(Environment.GetResourceString("Overflow_TimeSpanTooLong"));
+ throw new OverflowException(SR.Overflow_TimeSpanTooLong);
return new TimeSpan(result);
}
- public static TimeSpan FromTicks(long value) {
+ public TimeSpan Multiply(double factor) => this * factor;
+
+ public TimeSpan Divide(double divisor) => this / divisor;
+
+ public double Divide(TimeSpan ts) => this / ts;
+
+ public static TimeSpan FromTicks(long value)
+ {
return new TimeSpan(value);
}
- internal static long TimeToTicks(int hour, int minute, int second) {
+ internal static long TimeToTicks(int hour, int minute, int second)
+ {
// totalSeconds is bounded by 2^31 * 2^12 + 2^31 * 2^8 + 2^31,
// which is less than 2^44, meaning we won't overflow totalSeconds.
long totalSeconds = (long)hour * 3600 + (long)minute * 60 + (long)second;
if (totalSeconds > MaxSeconds || totalSeconds < MinSeconds)
- throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("Overflow_TimeSpanTooLong"));
+ throw new ArgumentOutOfRangeException(null, SR.Overflow_TimeSpanTooLong);
return totalSeconds * TicksPerSecond;
}
// See System.Globalization.TimeSpanParse and System.Globalization.TimeSpanFormat
#region ParseAndFormat
- public static TimeSpan Parse(String s) {
+ public static TimeSpan Parse(String s)
+ {
/* Constructs a TimeSpan from a string. Leading and trailing white space characters are allowed. */
return TimeSpanParse.Parse(s, null);
}
- public static TimeSpan Parse(String input, IFormatProvider formatProvider) {
+ public static TimeSpan Parse(String input, IFormatProvider formatProvider)
+ {
return TimeSpanParse.Parse(input, formatProvider);
}
- public static TimeSpan ParseExact(String input, String format, IFormatProvider formatProvider) {
+ public static TimeSpan ParseExact(String input, String format, IFormatProvider formatProvider)
+ {
return TimeSpanParse.ParseExact(input, format, formatProvider, TimeSpanStyles.None);
}
- public static TimeSpan ParseExact(String input, String[] formats, IFormatProvider formatProvider) {
+ public static TimeSpan ParseExact(String input, String[] formats, IFormatProvider formatProvider)
+ {
return TimeSpanParse.ParseExactMultiple(input, formats, formatProvider, TimeSpanStyles.None);
}
- public static TimeSpan ParseExact(String input, String format, IFormatProvider formatProvider, TimeSpanStyles styles) {
+ public static TimeSpan ParseExact(String input, String format, IFormatProvider formatProvider, TimeSpanStyles styles)
+ {
TimeSpanParse.ValidateStyles(styles, nameof(styles));
return TimeSpanParse.ParseExact(input, format, formatProvider, styles);
}
- public static TimeSpan ParseExact(String input, String[] formats, IFormatProvider formatProvider, TimeSpanStyles styles) {
+ public static TimeSpan ParseExact(String input, String[] formats, IFormatProvider formatProvider, TimeSpanStyles styles)
+ {
TimeSpanParse.ValidateStyles(styles, nameof(styles));
return TimeSpanParse.ParseExactMultiple(input, formats, formatProvider, styles);
}
- public static Boolean TryParse(String s, out TimeSpan result) {
+ public static Boolean TryParse(String s, out TimeSpan result)
+ {
return TimeSpanParse.TryParse(s, null, out result);
}
- public static Boolean TryParse(String input, IFormatProvider formatProvider, out TimeSpan result) {
+ public static Boolean TryParse(String input, IFormatProvider formatProvider, out TimeSpan result)
+ {
return TimeSpanParse.TryParse(input, formatProvider, out result);
}
- public static Boolean TryParseExact(String input, String format, IFormatProvider formatProvider, out TimeSpan result) {
+ public static Boolean TryParseExact(String input, String format, IFormatProvider formatProvider, out TimeSpan result)
+ {
return TimeSpanParse.TryParseExact(input, format, formatProvider, TimeSpanStyles.None, out result);
}
- public static Boolean TryParseExact(String input, String[] formats, IFormatProvider formatProvider, out TimeSpan result) {
+ public static Boolean TryParseExact(String input, String[] formats, IFormatProvider formatProvider, out TimeSpan result)
+ {
return TimeSpanParse.TryParseExactMultiple(input, formats, formatProvider, TimeSpanStyles.None, out result);
}
- public static Boolean TryParseExact(String input, String format, IFormatProvider formatProvider, TimeSpanStyles styles, out TimeSpan result) {
+ public static Boolean TryParseExact(String input, String format, IFormatProvider formatProvider, TimeSpanStyles styles, out TimeSpan result)
+ {
TimeSpanParse.ValidateStyles(styles, nameof(styles));
return TimeSpanParse.TryParseExact(input, format, formatProvider, styles, out result);
}
- public static Boolean TryParseExact(String input, String[] formats, IFormatProvider formatProvider, TimeSpanStyles styles, out TimeSpan result) {
+ public static Boolean TryParseExact(String input, String[] formats, IFormatProvider formatProvider, TimeSpanStyles styles, out TimeSpan result)
+ {
TimeSpanParse.ValidateStyles(styles, nameof(styles));
return TimeSpanParse.TryParseExactMultiple(input, formats, formatProvider, styles, out result);
}
- public override String ToString() {
+ public override String ToString()
+ {
return TimeSpanFormat.Format(this, null, null);
}
- public String ToString(String format) {
+ public String ToString(String format)
+ {
return TimeSpanFormat.Format(this, format, null);
}
- public String ToString(String format, IFormatProvider formatProvider) {
- if (LegacyMode) {
+ public String ToString(String format, IFormatProvider formatProvider)
+ {
+ if (LegacyMode)
+ {
return TimeSpanFormat.Format(this, null, null);
}
- else {
+ else
+ {
return TimeSpanFormat.Format(this, format, formatProvider);
}
}
#endregion
-
- public static TimeSpan operator -(TimeSpan t) {
- if (t._ticks==TimeSpan.MinValue._ticks)
- throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum"));
+
+ public static TimeSpan operator -(TimeSpan t)
+ {
+ if (t._ticks == TimeSpan.MinValue._ticks)
+ throw new OverflowException(SR.Overflow_NegateTwosCompNum);
return new TimeSpan(-t._ticks);
}
- public static TimeSpan operator -(TimeSpan t1, TimeSpan t2) {
+ public static TimeSpan operator -(TimeSpan t1, TimeSpan t2)
+ {
return t1.Subtract(t2);
}
- public static TimeSpan operator +(TimeSpan t) {
+ public static TimeSpan operator +(TimeSpan t)
+ {
return t;
}
- public static TimeSpan operator +(TimeSpan t1, TimeSpan t2) {
+ public static TimeSpan operator +(TimeSpan t1, TimeSpan t2)
+ {
return t1.Add(t2);
}
- public static bool operator ==(TimeSpan t1, TimeSpan t2) {
+ public static TimeSpan operator *(TimeSpan timeSpan, double factor)
+ {
+ if (double.IsNaN(factor))
+ {
+ throw new ArgumentException(SR.Arg_CannotBeNaN, nameof(factor));
+ }
+
+ // Rounding to the nearest tick is as close to the result we would have with unlimited
+ // precision as possible, and so likely to have the least potential to surprise.
+ double ticks = Math.Round(timeSpan.Ticks * factor);
+ if (ticks > long.MaxValue | ticks < long.MinValue)
+ {
+ throw new OverflowException(SR.Overflow_TimeSpanTooLong);
+ }
+
+ return FromTicks((long)ticks);
+ }
+
+ public static TimeSpan operator *(double factor, TimeSpan timeSpan) => timeSpan * factor;
+
+ public static TimeSpan operator /(TimeSpan timeSpan, double divisor)
+ {
+ if (double.IsNaN(divisor))
+ {
+ throw new ArgumentException(SR.Arg_CannotBeNaN, nameof(divisor));
+ }
+
+ double ticks = Math.Round(timeSpan.Ticks / divisor);
+ if (ticks > long.MaxValue | ticks < long.MinValue || double.IsNaN(ticks))
+ {
+ throw new OverflowException(SR.Overflow_TimeSpanTooLong);
+ }
+
+ return FromTicks((long)ticks);
+ }
+
+ // Using floating-point arithmetic directly means that infinities can be returned, which is reasonable
+ // if we consider TimeSpan.FromHours(1) / TimeSpan.Zero asks how many zero-second intervals there are in
+ // an hour for which ∞ is the mathematic correct answer. Having TimeSpan.Zero / TimeSpan.Zero return NaN
+ // is perhaps less useful, but no less useful than an exception.
+ public static double operator /(TimeSpan t1, TimeSpan t2) => t1.Ticks / (double)t2.Ticks;
+
+ public static bool operator ==(TimeSpan t1, TimeSpan t2)
+ {
return t1._ticks == t2._ticks;
}
- public static bool operator !=(TimeSpan t1, TimeSpan t2) {
+ public static bool operator !=(TimeSpan t1, TimeSpan t2)
+ {
return t1._ticks != t2._ticks;
}
- public static bool operator <(TimeSpan t1, TimeSpan t2) {
+ public static bool operator <(TimeSpan t1, TimeSpan t2)
+ {
return t1._ticks < t2._ticks;
}
- public static bool operator <=(TimeSpan t1, TimeSpan t2) {
+ public static bool operator <=(TimeSpan t1, TimeSpan t2)
+ {
return t1._ticks <= t2._ticks;
}
- public static bool operator >(TimeSpan t1, TimeSpan t2) {
+ public static bool operator >(TimeSpan t1, TimeSpan t2)
+ {
return t1._ticks > t2._ticks;
}
- public static bool operator >=(TimeSpan t1, TimeSpan t2) {
+ public static bool operator >=(TimeSpan t1, TimeSpan t2)
+ {
return t1._ticks >= t2._ticks;
}
@@ -405,16 +515,20 @@ namespace System {
// [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
// "TimeSpan_LegacyFormatMode"=dword:00000001
//
- private static bool GetLegacyFormatMode() {
+ private static bool GetLegacyFormatMode()
+ {
return false;
}
private static volatile bool _legacyConfigChecked;
private static volatile bool _legacyMode;
- private static bool LegacyMode {
- get {
- if (!_legacyConfigChecked) {
+ private static bool LegacyMode
+ {
+ get
+ {
+ if (!_legacyConfigChecked)
+ {
// no need to lock - idempotent
_legacyMode = GetLegacyFormatMode();
_legacyConfigChecked = true;
diff --git a/src/mscorlib/src/System/TimeZone.cs b/src/mscorlib/src/System/TimeZone.cs
deleted file mode 100644
index 8ede49293e..0000000000
--- a/src/mscorlib/src/System/TimeZone.cs
+++ /dev/null
@@ -1,246 +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.
-
-/*============================================================
-**
-** Class: TimeZone
-**
-**
-** Purpose:
-** This class is used to represent a TimeZone. It
-** has methods for converting a DateTime to UTC from local time
-** and to local time from UTC and methods for getting the
-** standard name and daylight name of the time zone.
-**
-** The only TimeZone that we support in version 1 is the
-** CurrentTimeZone as determined by the system timezone.
-**
-**
-============================================================*/
-namespace System {
- using System;
- using System.Text;
- using System.Threading;
- using System.Collections;
- using System.Globalization;
-
- [Serializable]
- [Obsolete("System.TimeZone has been deprecated. Please investigate the use of System.TimeZoneInfo instead.")]
- public abstract class TimeZone {
- private static volatile TimeZone currentTimeZone = null;
-
- // Private object for locking instead of locking on a public type for SQL reliability work.
- private static Object s_InternalSyncObject;
- private static Object InternalSyncObject {
- get {
- if (s_InternalSyncObject == null) {
- Object o = new Object();
- Interlocked.CompareExchange<Object>(ref s_InternalSyncObject, o, null);
- }
- return s_InternalSyncObject;
- }
- }
-
-
- protected TimeZone() {
- }
-
- public static TimeZone CurrentTimeZone {
- get {
- //Grabbing the cached value is required at the top of this function so that
- //we don't incur a race condition with the ResetTimeZone method below.
- TimeZone tz = currentTimeZone;
- if (tz == null) {
- lock(InternalSyncObject) {
- if (currentTimeZone == null) {
- currentTimeZone = new CurrentSystemTimeZone();
- }
- tz = currentTimeZone;
- }
- }
- return (tz);
- }
- }
-
- //This method is called by CultureInfo.ClearCachedData in response to control panel
- //change events. It must be synchronized because otherwise there is a race condition
- //with the CurrentTimeZone property above.
- internal static void ResetTimeZone() {
- if (currentTimeZone!=null) {
- lock(InternalSyncObject) {
- currentTimeZone = null;
- }
- }
- }
-
- public abstract String StandardName {
- get;
- }
-
- public abstract String DaylightName {
- get;
- }
-
- public abstract TimeSpan GetUtcOffset(DateTime time);
-
- //
- // Converts the specified datatime to the Universal time base on the current timezone
- //
- public virtual DateTime ToUniversalTime(DateTime time) {
- if (time.Kind == DateTimeKind.Utc) {
- return time;
- }
- long tickCount = time.Ticks - GetUtcOffset(time).Ticks;
- if (tickCount>DateTime.MaxTicks) {
- return new DateTime(DateTime.MaxTicks, DateTimeKind.Utc);
- }
- if (tickCount<DateTime.MinTicks) {
- return new DateTime(DateTime.MinTicks, DateTimeKind.Utc);
- }
- return new DateTime(tickCount, DateTimeKind.Utc);
- }
-
- //
- // Convert the specified datetime value from UTC to the local time based on the time zone.
- //
- public virtual DateTime ToLocalTime(DateTime time) {
- if (time.Kind == DateTimeKind.Local) {
- return time;
- }
- Boolean isAmbiguousLocalDst = false;
- Int64 offset = ((CurrentSystemTimeZone)(TimeZone.CurrentTimeZone)).GetUtcOffsetFromUniversalTime(time, ref isAmbiguousLocalDst);
- return new DateTime(time.Ticks + offset, DateTimeKind.Local, isAmbiguousLocalDst);
- }
-
- // Return an array of DaylightTime which reflects the daylight saving periods in a particular year.
- // We currently only support having one DaylightSavingTime per year.
- // If daylight saving time is not used in this timezone, null will be returned.
- public abstract DaylightTime GetDaylightChanges(int year);
-
- public virtual bool IsDaylightSavingTime(DateTime time) {
- return (IsDaylightSavingTime(time, GetDaylightChanges(time.Year)));
- }
-
- // Check if the specified time is in a daylight saving time. Allows the user to
- // specify the array of Daylight Saving Times.
- public static bool IsDaylightSavingTime(DateTime time, DaylightTime daylightTimes) {
- return CalculateUtcOffset(time, daylightTimes)!=TimeSpan.Zero;
- }
-
- //
- // NOTENOTE: Implementation detail
- // In the transition from standard time to daylight saving time,
- // if we convert local time to Universal time, we can have the
- // following (take PST as an example):
- // Local Universal UTC Offset
- // ----- --------- ----------
- // 01:00AM 09:00 -8:00
- // 02:00 (=> 03:00) 10:00 -8:00 [This time doesn't actually exist, but it can be created from DateTime]
- // 03:00 10:00 -7:00
- // 04:00 11:00 -7:00
- // 05:00 12:00 -7:00
- //
- // So from 02:00 - 02:59:59, we should return the standard offset, instead of the daylight saving offset.
- //
- // In the transition from daylight saving time to standard time,
- // if we convert local time to Universal time, we can have the
- // following (take PST as an example):
- // Local Universal UTC Offset
- // ----- --------- ----------
- // 01:00AM 08:00 -7:00
- // 02:00 (=> 01:00) 09:00 -8:00
- // 02:00 10:00 -8:00
- // 03:00 11:00 -8:00
- // 04:00 12:00 -8:00
- //
- // So in this case, the 02:00 does exist after the first 2:00 rolls back to 01:00. We don't need to special case this.
- // But note that there are two 01:00 in the local time.
-
- //
- // And imagine if the daylight saving offset is negative (although this does not exist in real life)
- // In the transition from standard time to daylight saving time,
- // if we convert local time to Universal time, we can have the
- // following (take PST as an example, but the daylight saving offset is -01:00):
- // Local Universal UTC Offset
- // ----- --------- ----------
- // 01:00AM 09:00 -8:00
- // 02:00 (=> 01:00) 10:00 -9:00
- // 02:00 11:00 -9:00
- // 03:00 12:00 -9:00
- // 04:00 13:00 -9:00
- // 05:00 14:00 -9:00
- //
- // So in this case, the 02:00 does exist after the first 2:00 rolls back to 01:00. We don't need to special case this.
- //
- // In the transition from daylight saving time to standard time,
- // if we convert local time to Universal time, we can have the
- // following (take PST as an example, daylight saving offset is -01:00):
- //
- // Local Universal UTC Offset
- // ----- --------- ----------
- // 01:00AM 10:00 -9:00
- // 02:00 (=> 03:00) 11:00 -9:00
- // 03:00 11:00 -8:00
- // 04:00 12:00 -8:00
- // 05:00 13:00 -8:00
- // 06:00 14:00 -8:00
- //
- // So from 02:00 - 02:59:59, we should return the daylight saving offset, instead of the standard offset.
- //
- internal static TimeSpan CalculateUtcOffset(DateTime time, DaylightTime daylightTimes) {
- if (daylightTimes==null) {
- return TimeSpan.Zero;
- }
- DateTimeKind kind = time.Kind;
- if (kind == DateTimeKind.Utc) {
- return TimeSpan.Zero;
- }
-
- DateTime startTime;
- DateTime endTime;
-
- // startTime and endTime represent the period from either the start of DST to the end and includes the
- // potentially overlapped times
- startTime = daylightTimes.Start + daylightTimes.Delta;
- endTime = daylightTimes.End;
-
- // For normal time zones, the ambiguous hour is the last hour of daylight saving when you wind the
- // clock back. It is theoretically possible to have a positive delta, (which would really be daylight
- // reduction time), where you would have to wind the clock back in the begnning.
- DateTime ambiguousStart;
- DateTime ambiguousEnd;
- if (daylightTimes.Delta.Ticks > 0) {
- ambiguousStart = endTime - daylightTimes.Delta;
- ambiguousEnd = endTime;
- } else {
- ambiguousStart = startTime;
- ambiguousEnd = startTime - daylightTimes.Delta;
- }
-
- Boolean isDst = false;
- if (startTime > endTime) {
- // In southern hemisphere, the daylight saving time starts later in the year, and ends in the beginning of next year.
- // Note, the summer in the southern hemisphere begins late in the year.
- if (time >= startTime || time < endTime) {
- isDst = true;
- }
- }
- else if (time>=startTime && time < endTime) {
- // In northern hemisphere, the daylight saving time starts in the middle of the year.
- isDst = true;
- }
-
- // If this date was previously converted from a UTC date and we were able to detect that the local
- // DateTime would be ambiguous, this data is stored in the DateTime to resolve this ambiguity.
- if (isDst && time >= ambiguousStart && time < ambiguousEnd) {
- isDst = time.IsAmbiguousDaylightSavingTime();
- }
-
- if (isDst) {
- return daylightTimes.Delta;
- }
- return TimeSpan.Zero;
- }
- }
-}
diff --git a/src/mscorlib/src/System/TimeZoneInfo.AdjustmentRule.cs b/src/mscorlib/src/System/TimeZoneInfo.AdjustmentRule.cs
index d27d2386e2..c0c27eeab7 100644
--- a/src/mscorlib/src/System/TimeZoneInfo.AdjustmentRule.cs
+++ b/src/mscorlib/src/System/TimeZoneInfo.AdjustmentRule.cs
@@ -144,22 +144,22 @@ namespace System
{
if (dateStart.Kind != DateTimeKind.Unspecified && dateStart.Kind != DateTimeKind.Utc)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeKindMustBeUnspecifiedOrUtc"), nameof(dateStart));
+ throw new ArgumentException(SR.Argument_DateTimeKindMustBeUnspecifiedOrUtc, nameof(dateStart));
}
if (dateEnd.Kind != DateTimeKind.Unspecified && dateEnd.Kind != DateTimeKind.Utc)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeKindMustBeUnspecifiedOrUtc"), nameof(dateEnd));
+ throw new ArgumentException(SR.Argument_DateTimeKindMustBeUnspecifiedOrUtc, nameof(dateEnd));
}
if (daylightTransitionStart.Equals(daylightTransitionEnd) && !noDaylightTransitions)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_TransitionTimesAreIdentical"), nameof(daylightTransitionEnd));
+ throw new ArgumentException(SR.Argument_TransitionTimesAreIdentical, nameof(daylightTransitionEnd));
}
if (dateStart > dateEnd)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_OutOfOrderDateTimes"), nameof(dateStart));
+ throw new ArgumentException(SR.Argument_OutOfOrderDateTimes, nameof(dateStart));
}
// This cannot use UtcOffsetOutOfRange to account for the scenario where Samoa moved across the International Date Line,
@@ -168,22 +168,22 @@ namespace System
// to be -23 (what it takes to go from UTC+13 to UTC-10)
if (daylightDelta.TotalHours < -23.0 || daylightDelta.TotalHours > 14.0)
{
- throw new ArgumentOutOfRangeException(nameof(daylightDelta), daylightDelta, Environment.GetResourceString("ArgumentOutOfRange_UtcOffset"));
+ throw new ArgumentOutOfRangeException(nameof(daylightDelta), daylightDelta, SR.ArgumentOutOfRange_UtcOffset);
}
if (daylightDelta.Ticks % TimeSpan.TicksPerMinute != 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_TimeSpanHasSeconds"), nameof(daylightDelta));
+ throw new ArgumentException(SR.Argument_TimeSpanHasSeconds, nameof(daylightDelta));
}
if (dateStart != DateTime.MinValue && dateStart.Kind == DateTimeKind.Unspecified && dateStart.TimeOfDay != TimeSpan.Zero)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeHasTimeOfDay"), nameof(dateStart));
+ throw new ArgumentException(SR.Argument_DateTimeHasTimeOfDay, nameof(dateStart));
}
if (dateEnd != DateTime.MaxValue && dateEnd.Kind == DateTimeKind.Unspecified && dateEnd.TimeOfDay != TimeSpan.Zero)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeHasTimeOfDay"), nameof(dateEnd));
+ throw new ArgumentException(SR.Argument_DateTimeHasTimeOfDay, nameof(dateEnd));
}
Contract.EndContractBlock();
}
@@ -200,7 +200,7 @@ namespace System
}
catch (ArgumentException e)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"), e);
+ throw new SerializationException(SR.Serialization_InvalidData, e);
}
}
@@ -221,7 +221,7 @@ namespace System
info.AddValue("NoDaylightTransitions", _noDaylightTransitions);
}
- AdjustmentRule(SerializationInfo info, StreamingContext context)
+ private AdjustmentRule(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
diff --git a/src/mscorlib/src/System/TimeZoneInfo.StringSerializer.cs b/src/mscorlib/src/System/TimeZoneInfo.StringSerializer.cs
index 9c1d5c3502..c52f7307d8 100644
--- a/src/mscorlib/src/System/TimeZoneInfo.StringSerializer.cs
+++ b/src/mscorlib/src/System/TimeZoneInfo.StringSerializer.cs
@@ -112,11 +112,11 @@ namespace System
}
catch (ArgumentException ex)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"), ex);
+ throw new SerializationException(SR.Serialization_InvalidData, ex);
}
catch (InvalidTimeZoneException ex)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"), ex);
+ throw new SerializationException(SR.Serialization_InvalidData, ex);
}
}
@@ -181,7 +181,7 @@ namespace System
{
if (c != Esc && c != Sep && c != Lhs && c != Rhs)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidEscapeSequence", c));
+ throw new SerializationException(SR.Format(SR.Serialization_InvalidEscapeSequence, c));
}
}
@@ -194,7 +194,7 @@ namespace System
{
if (_currentTokenStartIndex < 0 || _currentTokenStartIndex >= _serializedText.Length)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
State tokenState = State.NotEscaped;
@@ -236,7 +236,7 @@ namespace System
case '\0':
// invalid character
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
default:
break;
@@ -244,7 +244,7 @@ namespace System
}
}
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
/// <summary>
@@ -258,11 +258,11 @@ namespace System
// first verify the internal state of the object
if (_state == State.EndOfLine)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
if (_currentTokenStartIndex < 0 || _currentTokenStartIndex >= _serializedText.Length)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
State tokenState = State.NotEscaped;
StringBuilder token = StringBuilderCache.Acquire(InitialCapacityForString);
@@ -286,11 +286,11 @@ namespace System
case Lhs:
// '[' is an unexpected character
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
case Rhs:
// ']' is an unexpected character
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
case Sep:
_currentTokenStartIndex = i + 1;
@@ -306,7 +306,7 @@ namespace System
case '\0':
// invalid character
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
default:
token.Append(_serializedText[i]);
@@ -320,10 +320,10 @@ namespace System
if (tokenState == State.Escaped)
{
// we are at the end of the serialized text but we are in an escaped state
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidEscapeSequence", string.Empty));
+ throw new SerializationException(SR.Format(SR.Serialization_InvalidEscapeSequence, string.Empty));
}
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
/// <summary>
@@ -335,7 +335,7 @@ namespace System
DateTime time;
if (!DateTime.TryParseExact(token, format, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.None, out time))
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
return time;
}
@@ -352,7 +352,7 @@ namespace System
}
catch (ArgumentOutOfRangeException e)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"), e);
+ throw new SerializationException(SR.Serialization_InvalidData, e);
}
}
@@ -365,7 +365,7 @@ namespace System
int value;
if (!int.TryParse(token, NumberStyles.AllowLeadingSign /* "[sign]digits" */, CultureInfo.InvariantCulture, out value))
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
return value;
}
@@ -391,11 +391,11 @@ namespace System
// the AdjustmentRule array must end with a separator
if (_state == State.EndOfLine)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
if (_currentTokenStartIndex < 0 || _currentTokenStartIndex >= _serializedText.Length)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
return count != 0 ? rules.ToArray() : null;
@@ -414,7 +414,7 @@ namespace System
if (_currentTokenStartIndex < 0 || _currentTokenStartIndex >= _serializedText.Length)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
// check to see if the very first token we see is the separator
@@ -426,7 +426,7 @@ namespace System
// verify the current token is a left-hand-side marker ("[")
if (_serializedText[_currentTokenStartIndex] != Lhs)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
_currentTokenStartIndex++;
@@ -442,7 +442,7 @@ namespace System
if (_state == State.EndOfLine || _currentTokenStartIndex >= _serializedText.Length)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
// Check if we have baseUtcOffsetDelta in the serialized string and then deserialize it
@@ -460,7 +460,7 @@ namespace System
if (_state == State.EndOfLine || _currentTokenStartIndex >= _serializedText.Length)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
if (_serializedText[_currentTokenStartIndex] != Rhs)
@@ -486,7 +486,7 @@ namespace System
}
catch (ArgumentException e)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"), e);
+ throw new SerializationException(SR.Serialization_InvalidData, e);
}
// finally set the state to either EndOfLine or StartOfToken for the next caller
@@ -514,19 +514,19 @@ namespace System
//
// we are at the end of the line or we are starting at a "]" character
//
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
if (_currentTokenStartIndex < 0 || _currentTokenStartIndex >= _serializedText.Length)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
// verify the current token is a left-hand-side marker ("[")
if (_serializedText[_currentTokenStartIndex] != Lhs)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
_currentTokenStartIndex++;
@@ -534,7 +534,7 @@ namespace System
if (isFixedDate != 0 && isFixedDate != 1)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
TransitionTime transition;
@@ -554,7 +554,7 @@ namespace System
}
catch (ArgumentException e)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"), e);
+ throw new SerializationException(SR.Serialization_InvalidData, e);
}
}
else
@@ -568,7 +568,7 @@ namespace System
}
catch (ArgumentException e)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"), e);
+ throw new SerializationException(SR.Serialization_InvalidData, e);
}
}
@@ -576,7 +576,7 @@ namespace System
if (_state == State.EndOfLine || _currentTokenStartIndex >= _serializedText.Length)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
if (_serializedText[_currentTokenStartIndex] != Rhs)
@@ -606,7 +606,7 @@ namespace System
if (!sepFound)
{
// we MUST end on a separator
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"));
+ throw new SerializationException(SR.Serialization_InvalidData);
}
// finally set the state to either EndOfLine or StartOfToken for the next caller
diff --git a/src/mscorlib/src/System/TimeZoneInfo.TransitionTime.cs b/src/mscorlib/src/System/TimeZoneInfo.TransitionTime.cs
index dedcb880a4..1e1d9d328b 100644
--- a/src/mscorlib/src/System/TimeZoneInfo.TransitionTime.cs
+++ b/src/mscorlib/src/System/TimeZoneInfo.TransitionTime.cs
@@ -75,37 +75,37 @@ namespace System
{
if (timeOfDay.Kind != DateTimeKind.Unspecified)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeKindMustBeUnspecified"), nameof(timeOfDay));
+ throw new ArgumentException(SR.Argument_DateTimeKindMustBeUnspecified, nameof(timeOfDay));
}
// Month range 1-12
if (month < 1 || month > 12)
{
- throw new ArgumentOutOfRangeException(nameof(month), Environment.GetResourceString("ArgumentOutOfRange_MonthParam"));
+ throw new ArgumentOutOfRangeException(nameof(month), SR.ArgumentOutOfRange_MonthParam);
}
// Day range 1-31
if (day < 1 || day > 31)
{
- throw new ArgumentOutOfRangeException(nameof(day), Environment.GetResourceString("ArgumentOutOfRange_DayParam"));
+ throw new ArgumentOutOfRangeException(nameof(day), SR.ArgumentOutOfRange_DayParam);
}
// Week range 1-5
if (week < 1 || week > 5)
{
- throw new ArgumentOutOfRangeException(nameof(week), Environment.GetResourceString("ArgumentOutOfRange_Week"));
+ throw new ArgumentOutOfRangeException(nameof(week), SR.ArgumentOutOfRange_Week);
}
// DayOfWeek range 0-6
if ((int)dayOfWeek < 0 || (int)dayOfWeek > 6)
{
- throw new ArgumentOutOfRangeException(nameof(dayOfWeek), Environment.GetResourceString("ArgumentOutOfRange_DayOfWeek"));
+ throw new ArgumentOutOfRangeException(nameof(dayOfWeek), SR.ArgumentOutOfRange_DayOfWeek);
}
Contract.EndContractBlock();
if (timeOfDay.Year != 1 || timeOfDay.Month != 1 || timeOfDay.Day != 1 || (timeOfDay.Ticks % TimeSpan.TicksPerMillisecond != 0))
{
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeHasTicks"), nameof(timeOfDay));
+ throw new ArgumentException(SR.Argument_DateTimeHasTicks, nameof(timeOfDay));
}
}
@@ -120,7 +120,7 @@ namespace System
}
catch (ArgumentException e)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"), e);
+ throw new SerializationException(SR.Serialization_InvalidData, e);
}
}
@@ -140,7 +140,7 @@ namespace System
info.AddValue("IsFixedDateRule", _isFixedDateRule);
}
- TransitionTime(SerializationInfo info, StreamingContext context)
+ private TransitionTime(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
diff --git a/src/mscorlib/src/System/TimeZoneInfo.Unix.cs b/src/mscorlib/src/System/TimeZoneInfo.Unix.cs
index b94c8b71c1..02baadcfe5 100644
--- a/src/mscorlib/src/System/TimeZoneInfo.Unix.cs
+++ b/src/mscorlib/src/System/TimeZoneInfo.Unix.cs
@@ -97,6 +97,12 @@ namespace System
private void GetDisplayName(Interop.GlobalizationInterop.TimeZoneDisplayNameType nameType, ref string displayName)
{
+ if (GlobalizationMode.Invariant)
+ {
+ displayName = _standardDisplayName;
+ return;
+ }
+
string timeZoneDisplayName;
bool result = Interop.CallStringMethod(
(locale, id, type, stringBuilder) => Interop.GlobalizationInterop.GetTimeZoneDisplayName(
@@ -128,8 +134,8 @@ namespace System
return Array.Empty<AdjustmentRule>();
}
- // The rules we use in Unix cares mostly about the start and end dates but doesn’t fill the transition start and end info.
- // as the rules now is public, we should fill it properly so the caller doesn’t have to know how we use it internally
+ // The rules we use in Unix care mostly about the start and end dates but don't fill the transition start and end info.
+ // as the rules now is public, we should fill it properly so the caller doesn't have to know how we use it internally
// and can use it as it is used in Windows
AdjustmentRule[] rules = new AdjustmentRule[_adjustmentRules.Length];
@@ -138,10 +144,14 @@ namespace System
{
var rule = _adjustmentRules[i];
var start = rule.DateStart.Kind == DateTimeKind.Utc ?
- new DateTime(TimeZoneInfo.ConvertTime(rule.DateStart, this).Ticks, DateTimeKind.Unspecified) :
+ // At the daylight start we didn't start the daylight saving yet then we convert to Local time
+ // by adding the _baseUtcOffset to the UTC time
+ new DateTime(rule.DateStart.Ticks + _baseUtcOffset.Ticks, DateTimeKind.Unspecified) :
rule.DateStart;
var end = rule.DateEnd.Kind == DateTimeKind.Utc ?
- new DateTime(TimeZoneInfo.ConvertTime(rule.DateEnd, this).Ticks - 1, DateTimeKind.Unspecified) :
+ // At the daylight saving end, the UTC time is mapped to local time which is already shifted by the daylight delta
+ // we calculate the local time by adding _baseUtcOffset + DaylightDelta to the UTC time
+ new DateTime(rule.DateEnd.Ticks + _baseUtcOffset.Ticks + rule.DaylightDelta.Ticks, DateTimeKind.Unspecified) :
rule.DateEnd;
var startTransition = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, start.Hour, start.Minute, start.Second), start.Month, start.Day);
@@ -209,7 +219,7 @@ namespace System
}
catch (IOException ex)
{
- e = new InvalidTimeZoneException(Environment.GetResourceString("InvalidTimeZone_InvalidFileData", id, timeZoneFilePath), ex);
+ e = new InvalidTimeZoneException(SR.Format(SR.InvalidTimeZone_InvalidFileData, id, timeZoneFilePath), ex);
return TimeZoneInfoResult.InvalidTimeZoneException;
}
@@ -217,7 +227,7 @@ namespace System
if (value == null)
{
- e = new InvalidTimeZoneException(Environment.GetResourceString("InvalidTimeZone_InvalidFileData", id, timeZoneFilePath));
+ e = new InvalidTimeZoneException(SR.Format(SR.InvalidTimeZone_InvalidFileData, id, timeZoneFilePath));
return TimeZoneInfoResult.InvalidTimeZoneException;
}
@@ -561,7 +571,7 @@ namespace System
}
else if (id.Length == 0 || id.Contains("\0"))
{
- throw new TimeZoneNotFoundException(Environment.GetResourceString("TimeZoneNotFound_MissingData", id));
+ throw new TimeZoneNotFoundException(SR.Format(SR.TimeZoneNotFound_MissingData, id));
}
TimeZoneInfo value;
@@ -588,11 +598,11 @@ namespace System
}
else if (result == TimeZoneInfoResult.SecurityException)
{
- throw new SecurityException(Environment.GetResourceString("Security_CannotReadFileData", id), e);
+ throw new SecurityException(SR.Format(SR.Security_CannotReadFileData, id), e);
}
else
{
- throw new TimeZoneNotFoundException(Environment.GetResourceString("TimeZoneNotFound_MissingData", id), e);
+ throw new TimeZoneNotFoundException(SR.Format(SR.TimeZoneNotFound_MissingData, id), e);
}
}
@@ -916,14 +926,14 @@ namespace System
return transitionTypes[0];
}
- throw new InvalidTimeZoneException(Environment.GetResourceString("InvalidTimeZone_NoTTInfoStructures"));
+ throw new InvalidTimeZoneException(SR.InvalidTimeZone_NoTTInfoStructures);
}
/// <summary>
/// Creates an AdjustmentRule given the POSIX TZ environment variable string.
/// </summary>
/// <remarks>
- /// See http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html for the format and semantics of this POSX string.
+ /// See http://man7.org/linux/man-pages/man3/tzset.3.html for the format and semantics of this POSX string.
/// </remarks>
private static AdjustmentRule TZif_CreateAdjustmentRuleForPosixFormat(string posixFormat, DateTime startTransitionDate, TimeSpan timeZoneBaseUtcOffset)
{
@@ -1050,7 +1060,7 @@ namespace System
DayOfWeek day;
if (!TZif_ParseMDateRule(date, out month, out week, out day))
{
- throw new InvalidTimeZoneException(Environment.GetResourceString("InvalidTimeZone_UnparseablePosixMDateString", date));
+ throw new InvalidTimeZoneException(SR.Format(SR.InvalidTimeZone_UnparseablePosixMDateString, date));
}
DateTime timeOfDay;
@@ -1093,7 +1103,7 @@ namespace System
// One of them *could* be supported if we relaxed the TransitionTime validation rules, and allowed
// "IsFixedDateRule = true, Month = 0, Day = n" to mean the nth day of the year, picking one of the rules above
- throw new InvalidTimeZoneException(Environment.GetResourceString("InvalidTimeZone_JulianDayNotSupported"));
+ throw new InvalidTimeZoneException(SR.InvalidTimeZone_JulianDayNotSupported);
}
}
@@ -1185,8 +1195,32 @@ namespace System
return !string.IsNullOrEmpty(standardName) && !string.IsNullOrEmpty(standardOffset);
}
- private static string TZif_ParsePosixName(string posixFormat, ref int index) =>
- TZif_ParsePosixString(posixFormat, ref index, c => char.IsDigit(c) || c == '+' || c == '-' || c == ',');
+ private static string TZif_ParsePosixName(string posixFormat, ref int index)
+ {
+ bool isBracketEnclosed = index < posixFormat.Length && posixFormat[index] == '<';
+ if (isBracketEnclosed)
+ {
+ // move past the opening bracket
+ index++;
+
+ string result = TZif_ParsePosixString(posixFormat, ref index, c => c == '>');
+
+ // move past the closing bracket
+ if (index < posixFormat.Length && posixFormat[index] == '>')
+ {
+ index++;
+ }
+
+ return result;
+ }
+ else
+ {
+ return TZif_ParsePosixString(
+ posixFormat,
+ ref index,
+ c => char.IsDigit(c) || c == '+' || c == '-' || c == ',');
+ }
+ }
private static string TZif_ParsePosixOffset(string posixFormat, ref int index) =>
TZif_ParsePosixString(posixFormat, ref index, c => !char.IsDigit(c) && c != '+' && c != '-' && c != ':');
@@ -1391,7 +1425,7 @@ namespace System
{
if (data == null || data.Length < index + Length)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_TimeZoneInfoInvalidTZif"), nameof(data));
+ throw new ArgumentException(SR.Argument_TimeZoneInfoInvalidTZif, nameof(data));
}
Contract.EndContractBlock();
UtcOffset = new TimeSpan(0, 0, TZif_ToInt32(data, index + 00));
@@ -1427,7 +1461,7 @@ namespace System
if (Magic != 0x545A6966)
{
// 0x545A6966 = {0x54, 0x5A, 0x69, 0x66} = "TZif"
- throw new ArgumentException(Environment.GetResourceString("Argument_TimeZoneInfoBadTZif"), nameof(data));
+ throw new ArgumentException(SR.Argument_TimeZoneInfoBadTZif, nameof(data));
}
byte version = data[index + 04];
diff --git a/src/mscorlib/src/System/TimeZoneInfo.Win32.cs b/src/mscorlib/src/System/TimeZoneInfo.Win32.cs
index 79ee535505..b6585bd0a0 100644
--- a/src/mscorlib/src/System/TimeZoneInfo.Win32.cs
+++ b/src/mscorlib/src/System/TimeZoneInfo.Win32.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
+using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Security;
@@ -348,7 +349,7 @@ namespace System
}
else if (id.Length == 0 || id.Length > MaxKeyLength || id.Contains("\0"))
{
- throw new TimeZoneNotFoundException(Environment.GetResourceString("TimeZoneNotFound_MissingData", id));
+ throw new TimeZoneNotFoundException(SR.Format(SR.TimeZoneNotFound_MissingData, id));
}
TimeZoneInfo value;
@@ -369,15 +370,15 @@ namespace System
}
else if (result == TimeZoneInfoResult.InvalidTimeZoneException)
{
- throw new InvalidTimeZoneException(Environment.GetResourceString("InvalidTimeZone_InvalidRegistryData", id), e);
+ throw new InvalidTimeZoneException(SR.Format(SR.InvalidTimeZone_InvalidRegistryData, id), e);
}
else if (result == TimeZoneInfoResult.SecurityException)
{
- throw new SecurityException(Environment.GetResourceString("Security_CannotReadRegistryData", id), e);
+ throw new SecurityException(SR.Format(SR.Security_CannotReadRegistryData, id), e);
}
else
{
- throw new TimeZoneNotFoundException(Environment.GetResourceString("TimeZoneNotFound_MissingData", id), e);
+ throw new TimeZoneNotFoundException(SR.Format(SR.TimeZoneNotFound_MissingData, id), e);
}
}
@@ -575,8 +576,8 @@ namespace System
// read LastEntry {(yearN, 1, 1) - MaxValue }
// read the FirstEntry and LastEntry key values (ex: "1980", "2038")
- int first = (int)dynamicKey.GetValue(FirstEntryValue, -1, RegistryValueOptions.None);
- int last = (int)dynamicKey.GetValue(LastEntryValue, -1, RegistryValueOptions.None);
+ int first = (int)dynamicKey.GetValue(FirstEntryValue, -1);
+ int last = (int)dynamicKey.GetValue(LastEntryValue, -1);
if (first == -1 || last == -1 || first > last)
{
@@ -586,7 +587,7 @@ namespace System
// read the first year entry
Win32Native.RegistryTimeZoneInformation dtzi;
- byte[] regValue = dynamicKey.GetValue(first.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None) as byte[];
+ byte[] regValue = dynamicKey.GetValue(first.ToString(CultureInfo.InvariantCulture)) as byte[];
if (regValue == null || regValue.Length != RegByteLength)
{
rules = null;
@@ -619,7 +620,7 @@ namespace System
// read the middle year entries
for (int i = first + 1; i < last; i++)
{
- regValue = dynamicKey.GetValue(i.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None) as byte[];
+ regValue = dynamicKey.GetValue(i.ToString(CultureInfo.InvariantCulture)) as byte[];
if (regValue == null || regValue.Length != RegByteLength)
{
rules = null;
@@ -639,7 +640,7 @@ namespace System
}
// read the last year entry
- regValue = dynamicKey.GetValue(last.ToString(CultureInfo.InvariantCulture), null, RegistryValueOptions.None) as byte[];
+ regValue = dynamicKey.GetValue(last.ToString(CultureInfo.InvariantCulture)) as byte[];
dtzi = new Win32Native.RegistryTimeZoneInformation(regValue);
if (regValue == null || regValue.Length != RegByteLength)
{
@@ -718,7 +719,7 @@ namespace System
}
Win32Native.RegistryTimeZoneInformation registryTimeZoneInfo;
- byte[] regValue = key.GetValue(TimeZoneInfoValue, null, RegistryValueOptions.None) as byte[];
+ byte[] regValue = key.GetValue(TimeZoneInfoValue) as byte[];
if (regValue == null || regValue.Length != RegByteLength) return false;
registryTimeZoneInfo = new Win32Native.RegistryTimeZoneInformation(regValue);
@@ -755,7 +756,7 @@ namespace System
//
if (result)
{
- string registryStandardName = key.GetValue(StandardValue, string.Empty, RegistryValueOptions.None) as string;
+ string registryStandardName = key.GetValue(StandardValue, string.Empty) as string;
result = string.Equals(registryStandardName, timeZone.StandardName, StringComparison.Ordinal);
}
return result;
@@ -883,9 +884,9 @@ namespace System
daylightName = string.Empty;
// read the MUI_ registry keys
- string displayNameMuiResource = key.GetValue(MuiDisplayValue, string.Empty, RegistryValueOptions.None) as string;
- string standardNameMuiResource = key.GetValue(MuiStandardValue, string.Empty, RegistryValueOptions.None) as string;
- string daylightNameMuiResource = key.GetValue(MuiDaylightValue, string.Empty, RegistryValueOptions.None) as string;
+ string displayNameMuiResource = key.GetValue(MuiDisplayValue, string.Empty) as string;
+ string standardNameMuiResource = key.GetValue(MuiStandardValue, string.Empty) as string;
+ string daylightNameMuiResource = key.GetValue(MuiDaylightValue, string.Empty) as string;
// try to load the strings from the native resource DLL(s)
if (!string.IsNullOrEmpty(displayNameMuiResource))
@@ -906,15 +907,15 @@ namespace System
// fallback to using the standard registry keys
if (string.IsNullOrEmpty(displayName))
{
- displayName = key.GetValue(DisplayValue, string.Empty, RegistryValueOptions.None) as string;
+ displayName = key.GetValue(DisplayValue, string.Empty) as string;
}
if (string.IsNullOrEmpty(standardName))
{
- standardName = key.GetValue(StandardValue, string.Empty, RegistryValueOptions.None) as string;
+ standardName = key.GetValue(StandardValue, string.Empty) as string;
}
if (string.IsNullOrEmpty(daylightName))
{
- daylightName = key.GetValue(DaylightValue, string.Empty, RegistryValueOptions.None) as string;
+ daylightName = key.GetValue(DaylightValue, string.Empty) as string;
}
return true;
@@ -963,7 +964,7 @@ namespace System
}
Win32Native.RegistryTimeZoneInformation defaultTimeZoneInformation;
- byte[] regValue = key.GetValue(TimeZoneInfoValue, null, RegistryValueOptions.None) as byte[];
+ byte[] regValue = key.GetValue(TimeZoneInfoValue) as byte[];
if (regValue == null || regValue.Length != RegByteLength)
{
// the registry value could not be cast to a byte array
@@ -1016,7 +1017,6 @@ namespace System
e = ex;
return TimeZoneInfoResult.InvalidTimeZoneException;
}
-
}
}
}
diff --git a/src/mscorlib/src/System/TimeZoneInfo.cs b/src/mscorlib/src/System/TimeZoneInfo.cs
index fc5625be2e..29ea33a8ad 100644
--- a/src/mscorlib/src/System/TimeZoneInfo.cs
+++ b/src/mscorlib/src/System/TimeZoneInfo.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Runtime.Serialization;
@@ -164,7 +165,7 @@ namespace System
{
if (!SupportsDaylightSavingTime)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeOffsetIsNotAmbiguous"), nameof(dateTimeOffset));
+ throw new ArgumentException(SR.Argument_DateTimeOffsetIsNotAmbiguous, nameof(dateTimeOffset));
}
Contract.EndContractBlock();
@@ -180,7 +181,7 @@ namespace System
if (!isAmbiguous)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeOffsetIsNotAmbiguous"), nameof(dateTimeOffset));
+ throw new ArgumentException(SR.Argument_DateTimeOffsetIsNotAmbiguous, nameof(dateTimeOffset));
}
// the passed in dateTime is ambiguous in this TimeZoneInfo instance
@@ -210,7 +211,7 @@ namespace System
{
if (!SupportsDaylightSavingTime)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeIsNotAmbiguous"), nameof(dateTime));
+ throw new ArgumentException(SR.Argument_DateTimeIsNotAmbiguous, nameof(dateTime));
}
Contract.EndContractBlock();
@@ -240,7 +241,7 @@ namespace System
if (!isAmbiguous)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeIsNotAmbiguous"), nameof(dateTime));
+ throw new ArgumentException(SR.Argument_DateTimeIsNotAmbiguous, nameof(dateTime));
}
// the passed in dateTime is ambiguous in this TimeZoneInfo instance
@@ -513,7 +514,6 @@ namespace System
if ((dateTime.Kind == DateTimeKind.Unspecified) ||
(dateTime.Kind == DateTimeKind.Local && s_cachedData.GetCorrespondingKind(this) == DateTimeKind.Local))
{
-
// only check Unspecified and (Local when this TimeZoneInfo instance is Local)
AdjustmentRule rule = GetAdjustmentRuleForTime(dateTime);
@@ -650,7 +650,7 @@ namespace System
DateTimeKind sourceKind = cachedData.GetCorrespondingKind(sourceTimeZone);
if (((flags & TimeZoneInfoOptions.NoThrowOnInvalidTime) == 0) && (dateTime.Kind != DateTimeKind.Unspecified) && (dateTime.Kind != sourceKind))
{
- throw new ArgumentException(Environment.GetResourceString("Argument_ConvertMismatch"), nameof(sourceTimeZone));
+ throw new ArgumentException(SR.Argument_ConvertMismatch, nameof(sourceTimeZone));
}
//
@@ -676,7 +676,7 @@ namespace System
// period that supports DST
if (((flags & TimeZoneInfoOptions.NoThrowOnInvalidTime) == 0) && GetIsInvalidTime(dateTime, sourceRule, sourceDaylightTime))
{
- throw new ArgumentException(Environment.GetResourceString("Argument_DateTimeIsInvalid"), nameof(dateTime));
+ throw new ArgumentException(SR.Argument_DateTimeIsInvalid, nameof(dateTime));
}
sourceIsDaylightSavings = GetIsDaylightSavings(dateTime, sourceRule, sourceDaylightTime, flags);
@@ -768,7 +768,7 @@ namespace System
}
if (source.Length == 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidSerializedString", source), nameof(source));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidSerializedString, source), nameof(source));
}
Contract.EndContractBlock();
@@ -868,7 +868,6 @@ namespace System
return false;
}
}
-
}
return sameRules;
}
@@ -915,7 +914,6 @@ namespace System
AdjustmentRule[] adjustmentRules,
bool disableDaylightSavingTime)
{
-
bool adjustmentRulesSupportDst;
ValidateTimeZoneInfo(id, baseUtcOffset, adjustmentRules, out adjustmentRulesSupportDst);
@@ -1004,16 +1002,16 @@ namespace System
if (adjustmentRulesSupportDst != _supportsDaylightSavingTime)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_CorruptField", "SupportsDaylightSavingTime"));
+ throw new SerializationException(SR.Format(SR.Serialization_CorruptField, "SupportsDaylightSavingTime"));
}
}
catch (ArgumentException e)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"), e);
+ throw new SerializationException(SR.Serialization_InvalidData, e);
}
catch (InvalidTimeZoneException e)
{
- throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData"), e);
+ throw new SerializationException(SR.Serialization_InvalidData, e);
}
}
@@ -1034,7 +1032,7 @@ namespace System
info.AddValue("SupportsDaylightSavingTime", _supportsDaylightSavingTime);
}
- TimeZoneInfo(SerializationInfo info, StreamingContext context)
+ private TimeZoneInfo(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
@@ -1065,14 +1063,29 @@ namespace System
(dateTime + BaseUtcOffset).Date :
dateTime.Date;
- for (int i = 0; i < _adjustmentRules.Length; i++)
+ int low = 0;
+ int high = _adjustmentRules.Length - 1;
+
+ while (low <= high)
{
- AdjustmentRule rule = _adjustmentRules[i];
- AdjustmentRule previousRule = i > 0 ? _adjustmentRules[i - 1] : rule;
- if (IsAdjustmentRuleValid(rule, previousRule, dateTime, date, dateTimeisUtc))
+ int median = low + ((high - low) >> 1);
+
+ AdjustmentRule rule = _adjustmentRules[median];
+ AdjustmentRule previousRule = median > 0 ? _adjustmentRules[median - 1] : rule;
+
+ int compareResult = CompareAdjustmentRuleToDateTime(rule, previousRule, dateTime, date, dateTimeisUtc);
+ if (compareResult == 0)
{
return rule;
}
+ else if (compareResult < 0)
+ {
+ low = median + 1;
+ }
+ else
+ {
+ high = median - 1;
+ }
}
return null;
@@ -1081,7 +1094,12 @@ namespace System
/// <summary>
/// Determines if 'rule' is the correct AdjustmentRule for the given dateTime.
/// </summary>
- private bool IsAdjustmentRuleValid(AdjustmentRule rule, AdjustmentRule previousRule,
+ /// <returns>
+ /// A value less than zero if rule is for times before dateTime.
+ /// Zero if rule is correct for dateTime.
+ /// A value greater than zero if rule is for times after dateTime.
+ /// </returns>
+ private int CompareAdjustmentRuleToDateTime(AdjustmentRule rule, AdjustmentRule previousRule,
DateTime dateTime, DateTime dateOnly, bool dateTimeisUtc)
{
bool isAfterStart;
@@ -1103,7 +1121,7 @@ namespace System
if (!isAfterStart)
{
- return false;
+ return 1;
}
bool isBeforeEnd;
@@ -1121,7 +1139,7 @@ namespace System
isBeforeEnd = dateOnly <= rule.DateEnd;
}
- return isBeforeEnd;
+ return isBeforeEnd ? 0 : -1;
}
/// <summary>
@@ -1430,7 +1448,6 @@ namespace System
}
catch (ArgumentOutOfRangeException) { }
}
-
}
}
@@ -1884,18 +1901,17 @@ namespace System
if (id.Length == 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidId", id), nameof(id));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidId, id), nameof(id));
}
if (UtcOffsetOutOfRange(baseUtcOffset))
{
-
- throw new ArgumentOutOfRangeException(nameof(baseUtcOffset), Environment.GetResourceString("ArgumentOutOfRange_UtcOffset"));
+ throw new ArgumentOutOfRangeException(nameof(baseUtcOffset), SR.ArgumentOutOfRange_UtcOffset);
}
if (baseUtcOffset.Ticks % TimeSpan.TicksPerMinute != 0)
{
- throw new ArgumentException(Environment.GetResourceString("Argument_TimeSpanHasSeconds"), nameof(baseUtcOffset));
+ throw new ArgumentException(SR.Argument_TimeSpanHasSeconds, nameof(baseUtcOffset));
}
Contract.EndContractBlock();
@@ -1919,7 +1935,7 @@ namespace System
if (current == null)
{
- throw new InvalidTimeZoneException(Environment.GetResourceString("Argument_AdjustmentRulesNoNulls"));
+ throw new InvalidTimeZoneException(SR.Argument_AdjustmentRulesNoNulls);
}
// FUTURE: check to see if this rule supports Daylight Saving Time
@@ -1928,13 +1944,13 @@ namespace System
if (UtcOffsetOutOfRange(baseUtcOffset + current.DaylightDelta))
{
- throw new InvalidTimeZoneException(Environment.GetResourceString("ArgumentOutOfRange_UtcOffsetAndDaylightDelta"));
+ throw new InvalidTimeZoneException(SR.ArgumentOutOfRange_UtcOffsetAndDaylightDelta);
}
if (prev != null && current.DateStart <= prev.DateEnd)
{
// verify the rules are in chronological order and the DateStart/DateEnd do not overlap
- throw new InvalidTimeZoneException(Environment.GetResourceString("Argument_AdjustmentRulesOutOfOrder"));
+ throw new InvalidTimeZoneException(SR.Argument_AdjustmentRulesOutOfOrder);
}
}
}
diff --git a/src/mscorlib/src/System/Tuple.cs b/src/mscorlib/src/System/Tuple.cs
index bb0dbcad6f..a118df02bd 100644
--- a/src/mscorlib/src/System/Tuple.cs
+++ b/src/mscorlib/src/System/Tuple.cs
@@ -1,6 +1,7 @@
// 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.Text;
using System.Collections;
@@ -15,7 +16,6 @@ using System.Runtime.CompilerServices;
namespace System
{
-
/// <summary>
/// Helper so we can call some tuple methods recursively without knowing the underlying types.
/// </summary>
@@ -107,7 +107,6 @@ namespace System
[Serializable]
public class Tuple<T1> : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple
{
-
private readonly T1 m_Item1;
public T1 Item1 { get { return m_Item1; } }
@@ -149,7 +148,7 @@ namespace System
if (objTuple == null)
{
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other");
}
return comparer.Compare(m_Item1, objTuple.m_Item1);
@@ -207,7 +206,6 @@ namespace System
[Serializable]
public class Tuple<T1, T2> : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple
{
-
private readonly T1 m_Item1;
private readonly T2 m_Item2;
@@ -252,7 +250,7 @@ namespace System
if (objTuple == null)
{
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other");
}
int c = 0;
@@ -322,7 +320,6 @@ namespace System
[Serializable]
public class Tuple<T1, T2, T3> : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple
{
-
private readonly T1 m_Item1;
private readonly T2 m_Item2;
private readonly T3 m_Item3;
@@ -370,7 +367,7 @@ namespace System
if (objTuple == null)
{
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other");
}
int c = 0;
@@ -448,7 +445,6 @@ namespace System
[Serializable]
public class Tuple<T1, T2, T3, T4> : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple
{
-
private readonly T1 m_Item1;
private readonly T2 m_Item2;
private readonly T3 m_Item3;
@@ -499,7 +495,7 @@ namespace System
if (objTuple == null)
{
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other");
}
int c = 0;
@@ -585,7 +581,6 @@ namespace System
[Serializable]
public class Tuple<T1, T2, T3, T4, T5> : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple
{
-
private readonly T1 m_Item1;
private readonly T2 m_Item2;
private readonly T3 m_Item3;
@@ -639,7 +634,7 @@ namespace System
if (objTuple == null)
{
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other");
}
int c = 0;
@@ -733,7 +728,6 @@ namespace System
[Serializable]
public class Tuple<T1, T2, T3, T4, T5, T6> : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple
{
-
private readonly T1 m_Item1;
private readonly T2 m_Item2;
private readonly T3 m_Item3;
@@ -790,7 +784,7 @@ namespace System
if (objTuple == null)
{
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other");
}
int c = 0;
@@ -892,7 +886,6 @@ namespace System
[Serializable]
public class Tuple<T1, T2, T3, T4, T5, T6, T7> : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple
{
-
private readonly T1 m_Item1;
private readonly T2 m_Item2;
private readonly T3 m_Item3;
@@ -952,7 +945,7 @@ namespace System
if (objTuple == null)
{
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other");
}
int c = 0;
@@ -1062,7 +1055,6 @@ namespace System
[Serializable]
public class Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> : IStructuralEquatable, IStructuralComparable, IComparable, ITupleInternal, ITuple
{
-
private readonly T1 m_Item1;
private readonly T2 m_Item2;
private readonly T3 m_Item3;
@@ -1085,7 +1077,7 @@ namespace System
{
if (!(rest is ITupleInternal))
{
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleLastArgumentNotATuple"));
+ throw new ArgumentException(SR.ArgumentException_TupleLastArgumentNotATuple);
}
m_Item1 = item1;
@@ -1130,7 +1122,7 @@ namespace System
if (objTuple == null)
{
- throw new ArgumentException(Environment.GetResourceString("ArgumentException_TupleIncorrectType", this.GetType().ToString()), "other");
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), "other");
}
int c = 0;
diff --git a/src/mscorlib/src/System/TupleExtensions.cs b/src/mscorlib/src/System/TupleExtensions.cs
deleted file mode 100644
index b63cb41213..0000000000
--- a/src/mscorlib/src/System/TupleExtensions.cs
+++ /dev/null
@@ -1,930 +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.ComponentModel;
-using System.Runtime.CompilerServices;
-
-namespace System
-{
- /// <summary>
- /// Provides extension methods for <see cref="Tuple"/> instances to interop with C# tuples features (deconstruction syntax, converting from and to <see cref="ValueTuple"/>).
- /// </summary>
- public static class TupleExtensions
- {
- #region Deconstruct
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 1 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1>(
- this Tuple<T1> value,
- out T1 item1)
- {
- item1 = value.Item1;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 2 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2>(
- this Tuple<T1, T2> value,
- out T1 item1, out T2 item2)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 3 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3>(
- this Tuple<T1, T2, T3> value,
- out T1 item1, out T2 item2, out T3 item3)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 4 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4>(
- this Tuple<T1, T2, T3, T4> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 5 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5>(
- this Tuple<T1, T2, T3, T4, T5> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 6 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6>(
- this Tuple<T1, T2, T3, T4, T5, T6> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 7 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- item7 = value.Item7;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 8 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- item7 = value.Item7;
- item8 = value.Rest.Item1;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 9 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9>> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- item7 = value.Item7;
- item8 = value.Rest.Item1;
- item9 = value.Rest.Item2;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 10 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10>> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- item7 = value.Item7;
- item8 = value.Rest.Item1;
- item9 = value.Rest.Item2;
- item10 = value.Rest.Item3;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 11 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11>> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- item7 = value.Item7;
- item8 = value.Rest.Item1;
- item9 = value.Rest.Item2;
- item10 = value.Rest.Item3;
- item11 = value.Rest.Item4;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 12 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12>> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- item7 = value.Item7;
- item8 = value.Rest.Item1;
- item9 = value.Rest.Item2;
- item10 = value.Rest.Item3;
- item11 = value.Rest.Item4;
- item12 = value.Rest.Item5;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 13 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13>> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- item7 = value.Item7;
- item8 = value.Rest.Item1;
- item9 = value.Rest.Item2;
- item10 = value.Rest.Item3;
- item11 = value.Rest.Item4;
- item12 = value.Rest.Item5;
- item13 = value.Rest.Item6;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 14 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14>> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- item7 = value.Item7;
- item8 = value.Rest.Item1;
- item9 = value.Rest.Item2;
- item10 = value.Rest.Item3;
- item11 = value.Rest.Item4;
- item12 = value.Rest.Item5;
- item13 = value.Rest.Item6;
- item14 = value.Rest.Item7;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 15 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15>>> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- item7 = value.Item7;
- item8 = value.Rest.Item1;
- item9 = value.Rest.Item2;
- item10 = value.Rest.Item3;
- item11 = value.Rest.Item4;
- item12 = value.Rest.Item5;
- item13 = value.Rest.Item6;
- item14 = value.Rest.Item7;
- item15 = value.Rest.Rest.Item1;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 16 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16>>> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- item7 = value.Item7;
- item8 = value.Rest.Item1;
- item9 = value.Rest.Item2;
- item10 = value.Rest.Item3;
- item11 = value.Rest.Item4;
- item12 = value.Rest.Item5;
- item13 = value.Rest.Item6;
- item14 = value.Rest.Item7;
- item15 = value.Rest.Rest.Item1;
- item16 = value.Rest.Rest.Item2;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 17 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17>>> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- item7 = value.Item7;
- item8 = value.Rest.Item1;
- item9 = value.Rest.Item2;
- item10 = value.Rest.Item3;
- item11 = value.Rest.Item4;
- item12 = value.Rest.Item5;
- item13 = value.Rest.Item6;
- item14 = value.Rest.Item7;
- item15 = value.Rest.Rest.Item1;
- item16 = value.Rest.Rest.Item2;
- item17 = value.Rest.Rest.Item3;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 18 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18>>> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- item7 = value.Item7;
- item8 = value.Rest.Item1;
- item9 = value.Rest.Item2;
- item10 = value.Rest.Item3;
- item11 = value.Rest.Item4;
- item12 = value.Rest.Item5;
- item13 = value.Rest.Item6;
- item14 = value.Rest.Item7;
- item15 = value.Rest.Rest.Item1;
- item16 = value.Rest.Rest.Item2;
- item17 = value.Rest.Rest.Item3;
- item18 = value.Rest.Rest.Item4;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 19 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19>>> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- item7 = value.Item7;
- item8 = value.Rest.Item1;
- item9 = value.Rest.Item2;
- item10 = value.Rest.Item3;
- item11 = value.Rest.Item4;
- item12 = value.Rest.Item5;
- item13 = value.Rest.Item6;
- item14 = value.Rest.Item7;
- item15 = value.Rest.Rest.Item1;
- item16 = value.Rest.Rest.Item2;
- item17 = value.Rest.Rest.Item3;
- item18 = value.Rest.Rest.Item4;
- item19 = value.Rest.Rest.Item5;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 20 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20>>> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19, out T20 item20)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- item7 = value.Item7;
- item8 = value.Rest.Item1;
- item9 = value.Rest.Item2;
- item10 = value.Rest.Item3;
- item11 = value.Rest.Item4;
- item12 = value.Rest.Item5;
- item13 = value.Rest.Item6;
- item14 = value.Rest.Item7;
- item15 = value.Rest.Rest.Item1;
- item16 = value.Rest.Rest.Item2;
- item17 = value.Rest.Rest.Item3;
- item18 = value.Rest.Rest.Item4;
- item19 = value.Rest.Rest.Item5;
- item20 = value.Rest.Rest.Item6;
- }
-
- /// <summary>
- /// Deconstruct a properly nested <see cref="Tuple"/> with 21 elements.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static void Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20, T21>>> value,
- out T1 item1, out T2 item2, out T3 item3, out T4 item4, out T5 item5, out T6 item6, out T7 item7, out T8 item8, out T9 item9, out T10 item10, out T11 item11, out T12 item12, out T13 item13, out T14 item14, out T15 item15, out T16 item16, out T17 item17, out T18 item18, out T19 item19, out T20 item20, out T21 item21)
- {
- item1 = value.Item1;
- item2 = value.Item2;
- item3 = value.Item3;
- item4 = value.Item4;
- item5 = value.Item5;
- item6 = value.Item6;
- item7 = value.Item7;
- item8 = value.Rest.Item1;
- item9 = value.Rest.Item2;
- item10 = value.Rest.Item3;
- item11 = value.Rest.Item4;
- item12 = value.Rest.Item5;
- item13 = value.Rest.Item6;
- item14 = value.Rest.Item7;
- item15 = value.Rest.Rest.Item1;
- item16 = value.Rest.Rest.Item2;
- item17 = value.Rest.Rest.Item3;
- item18 = value.Rest.Rest.Item4;
- item19 = value.Rest.Rest.Item5;
- item20 = value.Rest.Rest.Item6;
- item21 = value.Rest.Rest.Item7;
- }
- #endregion
-
- #region ToValueTuple
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 1 element.
- /// </summary>
- public static ValueTuple<T1>
- ToValueTuple<T1>(
- this Tuple<T1> value)
- {
- return ValueTuple.Create(value.Item1);
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 2 elements.
- /// </summary>
- public static ValueTuple<T1, T2>
- ToValueTuple<T1, T2>(
- this Tuple<T1, T2> value)
- {
- return ValueTuple.Create(value.Item1, value.Item2);
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 3 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3>
- ToValueTuple<T1, T2, T3>(
- this Tuple<T1, T2, T3> value)
- {
- return ValueTuple.Create(value.Item1, value.Item2, value.Item3);
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 4 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4>
- ToValueTuple<T1, T2, T3, T4>(
- this Tuple<T1, T2, T3, T4> value)
- {
- return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4);
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 5 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5>
- ToValueTuple<T1, T2, T3, T4, T5>(
- this Tuple<T1, T2, T3, T4, T5> value)
- {
- return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5);
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 6 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6>
- ToValueTuple<T1, T2, T3, T4, T5, T6>(
- this Tuple<T1, T2, T3, T4, T5, T6> value)
- {
- return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6);
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 7 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7>
- ToValueTuple<T1, T2, T3, T4, T5, T6, T7>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7> value)
- {
- return ValueTuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7);
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 8 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8>>
- ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>> value)
- {
- return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- ValueTuple.Create(value.Rest.Item1));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 9 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9>>
- ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9>> value)
- {
- return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- ValueTuple.Create(value.Rest.Item1, value.Rest.Item2));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 10 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10>>
- ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10>> value)
- {
- return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 11 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11>>
- ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11>> value)
- {
- return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 12 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12>>
- ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12>> value)
- {
- return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 13 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13>>
- ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13>> value)
- {
- return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 14 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14>>
- ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14>> value)
- {
- return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- ValueTuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 15 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15>>>
- ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15>>> value)
- {
- return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
- ValueTuple.Create(value.Rest.Rest.Item1)));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 16 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16>>>
- ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16>>> value)
- {
- return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
- ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2)));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 17 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17>>>
- ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17>>> value)
- {
- return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
- ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3)));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 18 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18>>>
- ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18>>> value)
- {
- return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
- ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4)));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 19 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18, T19>>>
- ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19>>> value)
- {
- return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
- ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5)));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 20 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18, T19, T20>>>
- ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20>>> value)
- {
- return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
- ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6)));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="ValueTuple"/> from a properly nested <see cref="Tuple"/> with 21 elements.
- /// </summary>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18, T19, T20, T21>>>
- ToValueTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(
- this Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20, T21>>> value)
- {
- return CreateLong(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- CreateLong(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
- ValueTuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6, value.Rest.Rest.Item7)));
- }
- #endregion
-
- #region ToTuple
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 1 element.
- /// </summary>
- public static Tuple<T1>
- ToTuple<T1>(
- this ValueTuple<T1> value)
- {
- return Tuple.Create(value.Item1);
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 2 elements.
- /// </summary>
- public static Tuple<T1, T2>
- ToTuple<T1, T2>(
- this ValueTuple<T1, T2> value)
- {
- return Tuple.Create(value.Item1, value.Item2);
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 3 elements.
- /// </summary>
- public static Tuple<T1, T2, T3>
- ToTuple<T1, T2, T3>(
- this ValueTuple<T1, T2, T3> value)
- {
- return Tuple.Create(value.Item1, value.Item2, value.Item3);
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 4 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4>
- ToTuple<T1, T2, T3, T4>(
- this ValueTuple<T1, T2, T3, T4> value)
- {
- return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4);
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 5 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5>
- ToTuple<T1, T2, T3, T4, T5>(
- this ValueTuple<T1, T2, T3, T4, T5> value)
- {
- return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5);
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 6 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6>
- ToTuple<T1, T2, T3, T4, T5, T6>(
- this ValueTuple<T1, T2, T3, T4, T5, T6> value)
- {
- return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6);
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 7 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6, T7>
- ToTuple<T1, T2, T3, T4, T5, T6, T7>(
- this ValueTuple<T1, T2, T3, T4, T5, T6, T7> value)
- {
- return Tuple.Create(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7);
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 8 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>>
- ToTuple<T1, T2, T3, T4, T5, T6, T7, T8>(
- this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8>> value)
- {
- return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- Tuple.Create(value.Rest.Item1));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 9 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9>>
- ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
- this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9>> value)
- {
- return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- Tuple.Create(value.Rest.Item1, value.Rest.Item2));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 10 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10>>
- ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(
- this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10>> value)
- {
- return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 11 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11>>
- ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(
- this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11>> value)
- {
- return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 12 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12>>
- ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(
- this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12>> value)
- {
- return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 13 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13>>
- ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(
- this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13>> value)
- {
- return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 14 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14>>
- ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(
- this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14>> value)
- {
- return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- Tuple.Create(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 15 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15>>>
- ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(
- this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15>>> value)
- {
- return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
- Tuple.Create(value.Rest.Rest.Item1)));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 16 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16>>>
- ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(
- this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16>>> value)
- {
- return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
- Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2)));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 17 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17>>>
- ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(
- this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17>>> value)
- {
- return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
- Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3)));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 18 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18>>>
- ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(
- this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18>>> value)
- {
- return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
- Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4)));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 19 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19>>>
- ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(
- this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18, T19>>> value)
- {
- return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
- Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5)));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 20 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20>>>
- ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(
- this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18, T19, T20>>> value)
- {
- return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
- Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6)));
- }
-
- /// <summary>
- /// Make a properly nested <see cref="Tuple"/> from a properly nested <see cref="ValueTuple"/> with 21 elements.
- /// </summary>
- public static Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8, T9, T10, T11, T12, T13, T14, Tuple<T15, T16, T17, T18, T19, T20, T21>>>
- ToTuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(
- this ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8, T9, T10, T11, T12, T13, T14, ValueTuple<T15, T16, T17, T18, T19, T20, T21>>> value)
- {
- return CreateLongRef(value.Item1, value.Item2, value.Item3, value.Item4, value.Item5, value.Item6, value.Item7,
- CreateLongRef(value.Rest.Item1, value.Rest.Item2, value.Rest.Item3, value.Rest.Item4, value.Rest.Item5, value.Rest.Item6, value.Rest.Item7,
- Tuple.Create(value.Rest.Rest.Item1, value.Rest.Rest.Item2, value.Rest.Rest.Item3, value.Rest.Rest.Item4, value.Rest.Rest.Item5, value.Rest.Rest.Item6, value.Rest.Rest.Item7)));
- }
- #endregion
-
- private static ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> CreateLong<T1, T2, T3, T4, T5, T6, T7, TRest>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : struct, ITuple =>
- new ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>(item1, item2, item3, item4, item5, item6, item7, rest);
-
- private static Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> CreateLongRef<T1, T2, T3, T4, T5, T6, T7, TRest>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest) where TRest : ITuple =>
- new Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>(item1, item2, item3, item4, item5, item6, item7, rest);
- }
-} \ No newline at end of file
diff --git a/src/mscorlib/src/System/Type.CoreCLR.cs b/src/mscorlib/src/System/Type.CoreCLR.cs
new file mode 100644
index 0000000000..9c443b472a
--- /dev/null
+++ b/src/mscorlib/src/System/Type.CoreCLR.cs
@@ -0,0 +1,206 @@
+// 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Diagnostics.Contracts;
+using StackCrawlMark = System.Threading.StackCrawlMark;
+
+namespace System
+{
+ public abstract partial class Type : MemberInfo, IReflect
+ {
+ public bool IsInterface
+ {
+ get
+ {
+ RuntimeType rt = this as RuntimeType;
+ if (rt != null)
+ return RuntimeTypeHandle.IsInterface(rt);
+ return ((GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface);
+ }
+ }
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public static Type GetType(String typeName, bool throwOnError, bool ignoreCase)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return RuntimeType.GetType(typeName, throwOnError, ignoreCase, false, ref stackMark);
+ }
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public static Type GetType(String typeName, bool throwOnError)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return RuntimeType.GetType(typeName, throwOnError, false, false, ref stackMark);
+ }
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public static Type GetType(String typeName)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return RuntimeType.GetType(typeName, false, false, false, ref stackMark);
+ }
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public static Type GetType(
+ string typeName,
+ Func<AssemblyName, Assembly> assemblyResolver,
+ Func<Assembly, string, bool, Type> typeResolver)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, false, false, ref stackMark);
+ }
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public static Type GetType(
+ string typeName,
+ Func<AssemblyName, Assembly> assemblyResolver,
+ Func<Assembly, string, bool, Type> typeResolver,
+ bool throwOnError)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, throwOnError, false, ref stackMark);
+ }
+
+ [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod
+ public static Type GetType(
+ string typeName,
+ Func<AssemblyName, Assembly> assemblyResolver,
+ Func<Assembly, string, bool, Type> typeResolver,
+ bool throwOnError,
+ bool ignoreCase)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // This will return a class based upon the progID. This is provided for
+ // COM classic support. Program ID's are not used in COM+ because they
+ // have been superceded by namespace. (This routine is called this instead
+ // of getClass() because of the name conflict with the first method above.)
+ //
+ // param progID: the progID of the class to retrieve
+ // returns: the class object associated to the progID
+ ////
+ public static Type GetTypeFromProgID(String progID, String server, bool throwOnError)
+ {
+ return RuntimeType.GetTypeFromProgIDImpl(progID, server, throwOnError);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ // This will return a class based upon the CLSID. This is provided for
+ // COM classic support.
+ //
+ // param CLSID: the CLSID of the class to retrieve
+ // returns: the class object associated to the CLSID
+ ////
+ public static Type GetTypeFromCLSID(Guid clsid, String server, bool throwOnError)
+ {
+ return RuntimeType.GetTypeFromCLSIDImpl(clsid, server, throwOnError);
+ }
+
+ internal virtual RuntimeTypeHandle GetTypeHandleInternal()
+ {
+ return TypeHandle;
+ }
+
+ // Given a class handle, this will return the class for that handle.
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal static extern RuntimeType GetTypeFromHandleUnsafe(IntPtr handle);
+
+ [Pure]
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ public static extern Type GetTypeFromHandle(RuntimeTypeHandle handle);
+
+
+
+
+#if FEATURE_COMINTEROP
+ internal bool IsWindowsRuntimeObject
+ {
+ [Pure]
+ get { return IsWindowsRuntimeObjectImpl(); }
+ }
+
+ internal bool IsExportedToWindowsRuntime
+ {
+ [Pure]
+ get { return IsExportedToWindowsRuntimeImpl(); }
+ }
+
+
+ // Protected routine to determine if this class represents a Windows Runtime object
+ virtual internal bool IsWindowsRuntimeObjectImpl()
+ {
+ throw new NotImplementedException();
+ }
+
+ // Determines if this type is exported to WinRT (i.e. is an activatable class in a managed .winmd)
+ virtual internal bool IsExportedToWindowsRuntimeImpl()
+ {
+ throw new NotImplementedException();
+ }
+#endif // FEATURE_COMINTEROP
+
+ internal bool NeedsReflectionSecurityCheck
+ {
+ get
+ {
+ if (!IsVisible)
+ {
+ // Types which are not externally visible require security checks
+ return true;
+ }
+ else if (IsSecurityCritical && !IsSecuritySafeCritical)
+ {
+ // Critical types require security checks
+ return true;
+ }
+ else if (IsGenericType)
+ {
+ // If any of the generic arguments to this type require a security check, then this type
+ // also requires one.
+ foreach (Type genericArgument in GetGenericArguments())
+ {
+ if (genericArgument.NeedsReflectionSecurityCheck)
+ {
+ return true;
+ }
+ }
+ }
+ else if (IsArray || IsPointer)
+ {
+ return GetElementType().NeedsReflectionSecurityCheck;
+ }
+
+ return false;
+ }
+ }
+
+ // This is only ever called on RuntimeType objects.
+ internal string FormatTypeName()
+ {
+ return FormatTypeName(false);
+ }
+
+ internal virtual string FormatTypeName(bool serialization)
+ {
+ throw new NotImplementedException();
+ }
+
+ [Pure]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern bool operator ==(Type left, Type right);
+
+ [Pure]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern bool operator !=(Type left, Type right);
+
+ // Exists to faciliate code sharing between CoreCLR and CoreRT.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal bool IsRuntimeImplemented() => this is RuntimeType;
+ }
+}
diff --git a/src/mscorlib/src/System/Type.cs b/src/mscorlib/src/System/Type.cs
deleted file mode 100644
index 3647451445..0000000000
--- a/src/mscorlib/src/System/Type.cs
+++ /dev/null
@@ -1,1764 +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.
-
-//
-//
-//
-// Implements System.Type
-//
-// ======================================================================================
-
-namespace System
-{
- using System;
- using System.Reflection;
- using System.Threading;
- using System.Runtime;
- using System.Runtime.Remoting;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Security;
- using System.Collections;
- using System.Collections.Generic;
- using System.Runtime.Versioning;
- using System.Diagnostics.Contracts;
- using CultureInfo = System.Globalization.CultureInfo;
- using StackCrawlMark = System.Threading.StackCrawlMark;
- using DebuggerStepThroughAttribute = System.Diagnostics.DebuggerStepThroughAttribute;
-
- [Serializable]
- public abstract class Type : MemberInfo, IReflect
- {
- //
- // System.Type is appdomain agile type. Appdomain agile types cannot have precise static constructors. Make
- // sure to never introduce one here!
- //
- public static readonly MemberFilter FilterAttribute = new MemberFilter(__Filters.Instance.FilterAttribute);
- public static readonly MemberFilter FilterName = new MemberFilter(__Filters.Instance.FilterName);
- public static readonly MemberFilter FilterNameIgnoreCase = new MemberFilter(__Filters.Instance.FilterIgnoreCase);
-
- public static readonly Object Missing = System.Reflection.Missing.Value;
-
- public static readonly char Delimiter = '.';
-
- // EmptyTypes is used to indicate that we are looking for someting without any parameters.
- public readonly static Type[] EmptyTypes = EmptyArray<Type>.Value;
-
- // The Default binder. We create a single one and expose that.
- private static Binder defaultBinder;
-
-
- protected Type() {}
-
-
- // MemberInfo Methods....
- // The Member type Field.
- public override MemberTypes MemberType {
- get {return System.Reflection.MemberTypes.TypeInfo;}
- }
-
- // Return the class that declared this type.
- public override Type DeclaringType {
- get {return null;}
- }
-
- public virtual MethodBase DeclaringMethod { get { return null; } }
-
- // Return the class that was used to obtain this type.
- public override Type ReflectedType
- {
- get {return null;}
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // This is a static method that returns a Class based upon the name of the class
- // (this name needs to be fully qualified with the package name and is
- // case-sensitive by default).
- ////
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Type GetType(String typeName, bool throwOnError, bool ignoreCase) {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RuntimeType.GetType(typeName, throwOnError, ignoreCase, false, ref stackMark);
- }
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Type GetType(String typeName, bool throwOnError) {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RuntimeType.GetType(typeName, throwOnError, false, false, ref stackMark);
- }
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Type GetType(String typeName) {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return RuntimeType.GetType(typeName, false, false, false, ref stackMark);
- }
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Type GetType(
- string typeName,
- Func<AssemblyName, Assembly> assemblyResolver,
- Func<Assembly, string, bool, Type> typeResolver)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, false, false, ref stackMark);
- }
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Type GetType(
- string typeName,
- Func<AssemblyName, Assembly> assemblyResolver,
- Func<Assembly, string, bool, Type> typeResolver,
- bool throwOnError)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, throwOnError, false, ref stackMark);
- }
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Type GetType(
- string typeName,
- Func<AssemblyName, Assembly> assemblyResolver,
- Func<Assembly, string, bool, Type> typeResolver,
- bool throwOnError,
- bool ignoreCase)
- {
- StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
- return TypeNameParser.GetType(typeName, assemblyResolver, typeResolver, throwOnError, ignoreCase, ref stackMark);
- }
-
- [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
- public static Type ReflectionOnlyGetType(String typeName, bool throwIfNotFound, bool ignoreCase)
- {
- if (typeName == null)
- throw new ArgumentNullException(nameof(typeName));
- if (typeName.Length == 0 && throwIfNotFound)
- throw new TypeLoadException(Environment.GetResourceString("Arg_TypeLoadNullStr"));
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReflectionOnlyGetType"));
- }
-
- public virtual Type MakePointerType() { throw new NotSupportedException(); }
- public virtual StructLayoutAttribute StructLayoutAttribute { get { throw new NotSupportedException(); } }
- public virtual Type MakeByRefType() { throw new NotSupportedException(); }
- public virtual Type MakeArrayType() { throw new NotSupportedException(); }
- public virtual Type MakeArrayType(int rank) { throw new NotSupportedException(); }
-
- ////////////////////////////////////////////////////////////////////////////////
- // This will return a class based upon the progID. This is provided for
- // COM classic support. Program ID's are not used in COM+ because they
- // have been superceded by namespace. (This routine is called this instead
- // of getClass() because of the name conflict with the first method above.)
- //
- // param progID: the progID of the class to retrieve
- // returns: the class object associated to the progID
- ////
- public static Type GetTypeFromProgID(String progID)
- {
- return RuntimeType.GetTypeFromProgIDImpl(progID, null, false);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // This will return a class based upon the progID. This is provided for
- // COM classic support. Program ID's are not used in COM+ because they
- // have been superceded by namespace. (This routine is called this instead
- // of getClass() because of the name conflict with the first method above.)
- //
- // param progID: the progID of the class to retrieve
- // returns: the class object associated to the progID
- ////
- public static Type GetTypeFromProgID(String progID, bool throwOnError)
- {
- return RuntimeType.GetTypeFromProgIDImpl(progID, null, throwOnError);
- }
-
- public static Type GetTypeFromProgID(String progID, String server)
- {
- return RuntimeType.GetTypeFromProgIDImpl(progID, server, false);
- }
-
- public static Type GetTypeFromProgID(String progID, String server, bool throwOnError)
- {
- return RuntimeType.GetTypeFromProgIDImpl(progID, server, throwOnError);
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // This will return a class based upon the CLSID. This is provided for
- // COM classic support.
- //
- // param CLSID: the CLSID of the class to retrieve
- // returns: the class object associated to the CLSID
- ////
- public static Type GetTypeFromCLSID(Guid clsid)
- {
- return RuntimeType.GetTypeFromCLSIDImpl(clsid, null, false);
- }
-
- public static Type GetTypeFromCLSID(Guid clsid, bool throwOnError)
- {
- return RuntimeType.GetTypeFromCLSIDImpl(clsid, null, throwOnError);
- }
-
- public static Type GetTypeFromCLSID(Guid clsid, String server)
- {
- return RuntimeType.GetTypeFromCLSIDImpl(clsid, server, false);
- }
-
- public static Type GetTypeFromCLSID(Guid clsid, String server, bool throwOnError)
- {
- return RuntimeType.GetTypeFromCLSIDImpl(clsid, server, throwOnError);
- }
-
- // GetTypeCode
- // This method will return a TypeCode for the passed
- // type.
- public static TypeCode GetTypeCode(Type type)
- {
- if (type == null)
- return TypeCode.Empty;
- return type.GetTypeCodeImpl();
- }
-
- protected virtual TypeCode GetTypeCodeImpl()
- {
- // System.RuntimeType overrides GetTypeCodeInternal
- // so we can assume that this is not a runtime type
-
- // this is true for EnumBuilder but not the other System.Type subclasses in BCL
- if (this != UnderlyingSystemType && UnderlyingSystemType != null)
- return Type.GetTypeCode(UnderlyingSystemType);
-
- return TypeCode.Object;
- }
-
- // Property representing the GUID associated with a class.
- public abstract Guid GUID {
- get;
- }
-
- // Return the Default binder used by the system.
- static public Binder DefaultBinder {
- get {
- // Allocate the default binder if it hasn't been allocated yet.
- if (defaultBinder == null)
- CreateBinder();
- return defaultBinder;
- }
- }
-
- static private void CreateBinder()
- {
- if (defaultBinder == null)
- {
- DefaultBinder binder = new DefaultBinder();
- Interlocked.CompareExchange<Binder>(ref defaultBinder, binder, null);
- }
- }
-
- // Description of the Binding Process.
- // We must invoke a method that is accessable and for which the provided
- // parameters have the most specific match. A method may be called if
- // 1. The number of parameters in the method declaration equals the number of
- // arguments provided to the invocation
- // 2. The type of each argument can be converted by the binder to the
- // type of the type of the parameter.
- //
- // The binder will find all of the matching methods. These method are found based
- // upon the type of binding requested (MethodInvoke, Get/Set Properties). The set
- // of methods is filtered by the name, number of arguments and a set of search modifiers
- // defined in the Binder.
- //
- // After the method is selected, it will be invoked. Accessability is checked
- // at that point. The search may be control which set of methods are searched based
- // upon the accessibility attribute associated with the method.
- //
- // The BindToMethod method is responsible for selecting the method to be invoked.
- // For the default binder, the most specific method will be selected.
- //
- // This will invoke a specific member...
-
- abstract public Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder,Object target,
- Object[] args, ParameterModifier[] modifiers,CultureInfo culture,String[] namedParameters);
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder, Object target, Object[] args, CultureInfo culture)
- {
- return InvokeMember(name,invokeAttr,binder,target,args,null,culture,null);
- }
-
- [DebuggerStepThroughAttribute]
- [Diagnostics.DebuggerHidden]
- public Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder, Object target, Object[] args)
- {
- return InvokeMember(name,invokeAttr,binder,target,args,null,null,null);
- }
-
-
- // Module Property associated with a class.
- public new abstract Module Module { get; }
-
- // Assembly Property associated with a class.
- public abstract Assembly Assembly {
- [Pure]
- get;
- }
-
- // Assembly Property associated with a class.
- // A class handle is a unique integer value associated with
- // each class. The handle is unique during the process life time.
- public virtual RuntimeTypeHandle TypeHandle
- {
- [Pure]
- get
- {
- throw new NotSupportedException();
- }
- }
-
- internal virtual RuntimeTypeHandle GetTypeHandleInternal() {
- return TypeHandle;
- }
-
- public static RuntimeTypeHandle GetTypeHandle(Object o)
- {
- if (o == null)
- throw new ArgumentNullException(null, Environment.GetResourceString("Arg_InvalidHandle"));
- return new RuntimeTypeHandle((RuntimeType)o.GetType());
- }
-
- // Given a class handle, this will return the class for that handle.
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern RuntimeType GetTypeFromHandleUnsafe(IntPtr handle);
-
- [Pure]
- [MethodImpl(MethodImplOptions.InternalCall)]
- public static extern Type GetTypeFromHandle(RuntimeTypeHandle handle);
-
-
- // Return the fully qualified name. The name does contain the namespace.
- public abstract String FullName {
- [Pure]
- get;
- }
-
- // Return the name space of the class.
- public abstract String Namespace {
- [Pure]
- get;
- }
-
-
- public abstract String AssemblyQualifiedName {
- [Pure]
- get;
- }
-
-
- [Pure]
- public virtual int GetArrayRank() {
- Contract.Ensures(Contract.Result<int>() >= 0);
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
- }
-
- // Returns the base class for a class. If this is an interface or has
- // no base class null is returned. Object is the only Type that does not
- // have a base class.
- public abstract Type BaseType {
- [Pure]
- get;
- }
-
-
- // GetConstructor
- // This method will search for the specified constructor. For constructors,
- // unlike everything else, the default is to not look for static methods. The
- // reason is that we don't typically expose the class initializer.
- public ConstructorInfo GetConstructor(BindingFlags bindingAttr,
- Binder binder,
- CallingConventions callConvention,
- Type[] types,
- ParameterModifier[] modifiers)
- {
- // Must provide some types (Type[0] for nothing)
- if (types == null)
- throw new ArgumentNullException(nameof(types));
- Contract.EndContractBlock();
- for (int i=0;i<types.Length;i++)
- if (types[i] == null)
- throw new ArgumentNullException(nameof(types));
- return GetConstructorImpl(bindingAttr, binder, callConvention, types, modifiers);
- }
-
- public ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers)
- {
- if (types == null)
- throw new ArgumentNullException(nameof(types));
- Contract.EndContractBlock();
- for (int i=0;i<types.Length;i++)
- if (types[i] == null)
- throw new ArgumentNullException(nameof(types));
- return GetConstructorImpl(bindingAttr, binder, CallingConventions.Any, types, modifiers);
- }
-
- public ConstructorInfo GetConstructor(Type[] types)
- {
- // The arguments are checked in the called version of GetConstructor.
- return GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, types, null);
- }
-
- abstract protected ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr,
- Binder binder,
- CallingConventions callConvention,
- Type[] types,
- ParameterModifier[] modifiers);
-
- // GetConstructors()
- // This routine will return an array of all constructors supported by the class.
- // Unlike everything else, the default is to not look for static methods. The
- // reason is that we don't typically expose the class initializer.
- public ConstructorInfo[] GetConstructors() {
- return GetConstructors(BindingFlags.Public | BindingFlags.Instance);
- }
-
- abstract public ConstructorInfo[] GetConstructors(BindingFlags bindingAttr);
-
- public ConstructorInfo TypeInitializer {
- get {
- return GetConstructorImpl(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
- null,
- CallingConventions.Any,
- Type.EmptyTypes,
- null);
- }
- }
-
-
- // Return a method based upon the passed criteria. The name of the method
- // must be provided, and exception is thrown if it is not. The bindingAttr
- // parameter indicates if non-public methods should be searched. The types
- // array indicates the types of the parameters being looked for.
- public MethodInfo GetMethod(String name,
- BindingFlags bindingAttr,
- Binder binder,
- CallingConventions callConvention,
- Type[] types,
- ParameterModifier[] modifiers)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
- if (types == null)
- throw new ArgumentNullException(nameof(types));
- Contract.EndContractBlock();
- for (int i = 0; i < types.Length; i++)
- if (types[i] == null)
- throw new ArgumentNullException(nameof(types));
- return GetMethodImpl(name, bindingAttr, binder, callConvention, types, modifiers);
- }
-
- public MethodInfo GetMethod(String name,
- BindingFlags bindingAttr,
- Binder binder,
- Type[] types,
- ParameterModifier[] modifiers)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
- if (types == null)
- throw new ArgumentNullException(nameof(types));
- Contract.EndContractBlock();
- for (int i = 0; i < types.Length; i++)
- if (types[i] == null)
- throw new ArgumentNullException(nameof(types));
- return GetMethodImpl(name, bindingAttr, binder, CallingConventions.Any, types, modifiers);
- }
-
- public MethodInfo GetMethod(String name, Type[] types, ParameterModifier[] modifiers)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
- if (types == null)
- throw new ArgumentNullException(nameof(types));
- Contract.EndContractBlock();
- for (int i=0;i<types.Length;i++)
- if (types[i] == null)
- throw new ArgumentNullException(nameof(types));
- return GetMethodImpl(name, Type.DefaultLookup, null, CallingConventions.Any, types, modifiers);
- }
-
- public MethodInfo GetMethod(String name,Type[] types)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
- if (types == null)
- throw new ArgumentNullException(nameof(types));
- Contract.EndContractBlock();
- for (int i=0;i<types.Length;i++)
- if (types[i] == null)
- throw new ArgumentNullException(nameof(types));
- return GetMethodImpl(name, Type.DefaultLookup, null, CallingConventions.Any, types, null);
- }
-
- public MethodInfo GetMethod(String name, BindingFlags bindingAttr)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
- Contract.EndContractBlock();
- return GetMethodImpl(name, bindingAttr, null, CallingConventions.Any, null, null);
- }
-
- public MethodInfo GetMethod(String name)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
- Contract.EndContractBlock();
- return GetMethodImpl(name, Type.DefaultLookup, null, CallingConventions.Any, null, null);
- }
-
- abstract protected MethodInfo GetMethodImpl(String name,
- BindingFlags bindingAttr,
- Binder binder,
- CallingConventions callConvention,
- Type[] types,
- ParameterModifier[] modifiers);
-
-
- // GetMethods
- // This routine will return all the methods implemented by the class
- public MethodInfo[] GetMethods() {
- return GetMethods(Type.DefaultLookup);
- }
-
- abstract public MethodInfo[] GetMethods(BindingFlags bindingAttr);
-
- // GetField
- // Get Field will return a specific field based upon name
- abstract public FieldInfo GetField(String name, BindingFlags bindingAttr);
-
-
- public FieldInfo GetField(String name) {
- return GetField(name, Type.DefaultLookup);
- }
-
-
- // GetFields
- // Get fields will return a full array of fields implemented by a class
- public FieldInfo[] GetFields() {
- return GetFields(Type.DefaultLookup);
- }
- abstract public FieldInfo[] GetFields(BindingFlags bindingAttr);
-
- // GetInterface
- // This method will return an interface (as a class) based upon
- // the passed in name.
- public Type GetInterface(String name) {
- return GetInterface(name,false);
- }
- abstract public Type GetInterface(String name, bool ignoreCase);
-
-
- // GetInterfaces
- // This method will return all of the interfaces implemented by a class
- abstract public Type[] GetInterfaces();
-
- // FindInterfaces
- // This method will filter the interfaces supported the class
- public virtual Type[] FindInterfaces(TypeFilter filter,Object filterCriteria)
- {
- if (filter == null)
- throw new ArgumentNullException(nameof(filter));
- Contract.EndContractBlock();
- Type[] c = GetInterfaces();
- int cnt = 0;
- for (int i = 0;i<c.Length;i++) {
- if (!filter(c[i],filterCriteria))
- c[i] = null;
- else
- cnt++;
- }
- if (cnt == c.Length)
- return c;
-
- Type[] ret = new Type[cnt];
- cnt=0;
- for (int i=0;i<c.Length;i++) {
- if (c[i] != null)
- ret[cnt++] = c[i];
- }
- return ret;
- }
-
- // GetEvent
- // This method will return a event by name if it is found.
- // null is returned if the event is not found
-
-
- public EventInfo GetEvent(String name) {
- return GetEvent(name,Type.DefaultLookup);
- }
- abstract public EventInfo GetEvent(String name,BindingFlags bindingAttr);
-
- // GetEvents
- // This method will return an array of EventInfo. If there are not Events
- // an empty array will be returned.
- virtual public EventInfo[] GetEvents() {
- return GetEvents(Type.DefaultLookup);
- }
- abstract public EventInfo[] GetEvents(BindingFlags bindingAttr);
-
-
- // Return a property based upon the passed criteria. The nameof the
- // parameter must be provided.
- public PropertyInfo GetProperty(String name,BindingFlags bindingAttr,Binder binder,
- Type returnType, Type[] types, ParameterModifier[] modifiers)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
- if (types == null)
- throw new ArgumentNullException(nameof(types));
- Contract.EndContractBlock();
- return GetPropertyImpl(name,bindingAttr,binder,returnType,types,modifiers);
- }
-
- public PropertyInfo GetProperty(String name, Type returnType, Type[] types,ParameterModifier[] modifiers)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
- if (types == null)
- throw new ArgumentNullException(nameof(types));
- Contract.EndContractBlock();
- return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,types,modifiers);
- }
-
- public PropertyInfo GetProperty(String name, BindingFlags bindingAttr)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
- Contract.EndContractBlock();
- return GetPropertyImpl(name,bindingAttr,null,null,null,null);
- }
-
- public PropertyInfo GetProperty(String name, Type returnType, Type[] types)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
- if (types == null)
- throw new ArgumentNullException(nameof(types));
- Contract.EndContractBlock();
- return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,types,null);
- }
-
- public PropertyInfo GetProperty(String name, Type[] types)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
- if (types == null)
- throw new ArgumentNullException(nameof(types));
- Contract.EndContractBlock();
- return GetPropertyImpl(name,Type.DefaultLookup,null,null,types,null);
- }
-
- public PropertyInfo GetProperty(String name, Type returnType)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
- if (returnType == null)
- throw new ArgumentNullException(nameof(returnType));
- Contract.EndContractBlock();
- return GetPropertyImpl(name,Type.DefaultLookup,null,returnType,null,null);
- }
-
- public PropertyInfo GetProperty(String name)
- {
- if (name == null)
- throw new ArgumentNullException(nameof(name));
- Contract.EndContractBlock();
- return GetPropertyImpl(name,Type.DefaultLookup,null,null,null,null);
- }
-
- protected abstract PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr,Binder binder,
- Type returnType, Type[] types, ParameterModifier[] modifiers);
-
-
- // GetProperties
- // This method will return an array of all of the properties defined
- // for a Type.
- abstract public PropertyInfo[] GetProperties(BindingFlags bindingAttr);
- public PropertyInfo[] GetProperties()
- {
- return GetProperties(Type.DefaultLookup);
- }
-
- // GetNestedTypes()
- // This set of method will return any nested types that are found inside
- // of the type.
- public Type[] GetNestedTypes()
- {
- return GetNestedTypes(Type.DefaultLookup);
- }
-
- abstract public Type[] GetNestedTypes(BindingFlags bindingAttr);
-
- public Type GetNestedType(String name)
- {
- return GetNestedType(name,Type.DefaultLookup);
- }
-
- abstract public Type GetNestedType(String name, BindingFlags bindingAttr);
-
- // GetMember
- // This method will return all of the members which match the specified string
- // passed into the method
- public MemberInfo[] GetMember(String name) {
- return GetMember(name,Type.DefaultLookup);
- }
-
- virtual public MemberInfo[] GetMember(String name, BindingFlags bindingAttr)
- {
- return GetMember(name,MemberTypes.All,bindingAttr);
- }
-
- virtual public MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
- }
-
-
- // GetMembers
- // This will return a Member array of all of the members of a class
- public MemberInfo[] GetMembers() {
- return GetMembers(Type.DefaultLookup);
- }
- abstract public MemberInfo[] GetMembers(BindingFlags bindingAttr);
-
- // GetDefaultMembers
- // This will return a MemberInfo that has been marked with the
- // DefaultMemberAttribute
- public virtual MemberInfo[] GetDefaultMembers()
- {
- throw new NotImplementedException();
- }
-
- // FindMembers
- // This will return a filtered version of the member information
- public virtual MemberInfo[] FindMembers(MemberTypes memberType,BindingFlags bindingAttr,MemberFilter filter,Object filterCriteria)
- {
- // Define the work arrays
- MethodInfo[] m = null;
- ConstructorInfo[] c = null;
- FieldInfo[] f = null;
- PropertyInfo[] p = null;
- EventInfo[] e = null;
- Type[] t = null;
-
- int i = 0;
- int cnt = 0; // Total Matchs
-
- // Check the methods
- if ((memberType & System.Reflection.MemberTypes.Method) != 0) {
- m = GetMethods(bindingAttr);
- if (filter != null) {
- for (i=0;i<m.Length;i++)
- if (!filter(m[i],filterCriteria))
- m[i] = null;
- else
- cnt++;
- } else {
- cnt+=m.Length;
- }
- }
-
- // Check the constructors
- if ((memberType & System.Reflection.MemberTypes.Constructor) != 0) {
- c = GetConstructors(bindingAttr);
- if (filter != null) {
- for (i=0;i<c.Length;i++)
- if (!filter(c[i],filterCriteria))
- c[i] = null;
- else
- cnt++;
- } else {
- cnt+=c.Length;
- }
- }
-
- // Check the fields
- if ((memberType & System.Reflection.MemberTypes.Field) != 0) {
- f = GetFields(bindingAttr);
- if (filter != null) {
- for (i=0;i<f.Length;i++)
- if (!filter(f[i],filterCriteria))
- f[i] = null;
- else
- cnt++;
- } else {
- cnt+=f.Length;
- }
- }
-
- // Check the Properties
- if ((memberType & System.Reflection.MemberTypes.Property) != 0) {
- p = GetProperties(bindingAttr);
- if (filter != null) {
- for (i=0;i<p.Length;i++)
- if (!filter(p[i],filterCriteria))
- p[i] = null;
- else
- cnt++;
- } else {
- cnt+=p.Length;
- }
- }
-
- // Check the Events
- if ((memberType & System.Reflection.MemberTypes.Event) != 0) {
- e = GetEvents(bindingAttr);
- if (filter != null) {
- for (i=0;i<e.Length;i++)
- if (!filter(e[i],filterCriteria))
- e[i] = null;
- else
- cnt++;
- } else {
- cnt+=e.Length;
- }
- }
-
- // Check the Types
- if ((memberType & System.Reflection.MemberTypes.NestedType) != 0) {
- t = GetNestedTypes(bindingAttr);
- if (filter != null) {
- for (i=0;i<t.Length;i++)
- if (!filter(t[i],filterCriteria))
- t[i] = null;
- else
- cnt++;
- } else {
- cnt+=t.Length;
- }
- }
-
- // Allocate the Member Info
- MemberInfo[] ret = new MemberInfo[cnt];
-
- // Copy the Methods
- cnt = 0;
- if (m != null) {
- for (i=0;i<m.Length;i++)
- if (m[i] != null)
- ret[cnt++] = m[i];
- }
-
- // Copy the Constructors
- if (c != null) {
- for (i=0;i<c.Length;i++)
- if (c[i] != null)
- ret[cnt++] = c[i];
- }
-
- // Copy the Fields
- if (f != null) {
- for (i=0;i<f.Length;i++)
- if (f[i] != null)
- ret[cnt++] = f[i];
- }
-
- // Copy the Properties
- if (p != null) {
- for (i=0;i<p.Length;i++)
- if (p[i] != null)
- ret[cnt++] = p[i];
- }
-
- // Copy the Events
- if (e != null) {
- for (i=0;i<e.Length;i++)
- if (e[i] != null)
- ret[cnt++] = e[i];
- }
-
- // Copy the Types
- if (t != null) {
- for (i=0;i<t.Length;i++)
- if (t[i] != null)
- ret[cnt++] = t[i];
- }
-
- return ret;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Attributes
- //
- // The attributes are all treated as read-only properties on a class. Most of
- // these boolean properties have flag values defined in this class and act like
- // a bit mask of attributes. There are also a set of boolean properties that
- // relate to the classes relationship to other classes and to the state of the
- // class inside the runtime.
- //
- ////////////////////////////////////////////////////////////////////////////////
-
- public bool IsNested
- {
- [Pure]
- get
- {
- return DeclaringType != null;
- }
- }
-
- // The attribute property on the Type.
- public TypeAttributes Attributes {
- [Pure]
- get {return GetAttributeFlagsImpl();}
- }
-
- public virtual GenericParameterAttributes GenericParameterAttributes
- {
- get { throw new NotSupportedException(); }
- }
-
- public bool IsVisible
- {
- [Pure]
- get
- {
- RuntimeType rt = this as RuntimeType;
- if (rt != null)
- return RuntimeTypeHandle.IsVisible(rt);
-
- if (IsGenericParameter)
- return true;
-
- if (HasElementType)
- return GetElementType().IsVisible;
-
- Type type = this;
- while (type.IsNested)
- {
- if (!type.IsNestedPublic)
- return false;
-
- // this should be null for non-nested types.
- type = type.DeclaringType;
- }
-
- // Now "type" should be a top level type
- if (!type.IsPublic)
- return false;
-
- if (IsGenericType && !IsGenericTypeDefinition)
- {
- foreach (Type t in GetGenericArguments())
- {
- if (!t.IsVisible)
- return false;
- }
- }
-
- return true;
- }
- }
-
- public bool IsNotPublic
- {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic);}
- }
-
- public bool IsPublic {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.Public);}
- }
-
- public bool IsNestedPublic {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic);}
- }
-
- public bool IsNestedPrivate {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate);}
- }
- public bool IsNestedFamily {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily);}
- }
- public bool IsNestedAssembly {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly);}
- }
- public bool IsNestedFamANDAssem {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem);}
- }
- public bool IsNestedFamORAssem{
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem);}
- }
-
- public bool IsAutoLayout {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout);}
- }
- public bool IsLayoutSequential {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout);}
- }
- public bool IsExplicitLayout {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout);}
- }
-
- public bool IsClass {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class && !IsValueType);}
- }
-
- public bool IsInterface {
- [Pure]
- get
- {
- RuntimeType rt = this as RuntimeType;
- if (rt != null)
- return RuntimeTypeHandle.IsInterface(rt);
-
- return ((GetAttributeFlagsImpl() & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface);
- }
- }
-
- public bool IsValueType {
- [Pure]
- get {return IsValueTypeImpl();}
- }
-
- public bool IsAbstract {
- [Pure]
- get { return ((GetAttributeFlagsImpl() & TypeAttributes.Abstract) != 0); }
- }
-
- public bool IsSealed {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.Sealed) != 0);}
- }
-
- public virtual bool IsEnum {
- [Pure]
- get
- {
- // This will return false for a non-runtime Type object unless it overrides IsSubclassOf.
- return IsSubclassOf(RuntimeType.EnumType);
- }
- }
-
- public bool IsSpecialName {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.SpecialName) != 0);}
- }
-
- public bool IsImport {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.Import) != 0);}
- }
-
- public virtual bool IsSerializable
- {
- [Pure]
- get
- {
- if ((GetAttributeFlagsImpl() & TypeAttributes.Serializable) != 0)
- return true;
-
- RuntimeType rt = this.UnderlyingSystemType as RuntimeType;
-
- if (rt != null)
- return rt.IsSpecialSerializableType();
-
- return false;
- }
- }
-
- public bool IsAnsiClass {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass);}
- }
-
- public bool IsUnicodeClass {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass);}
- }
-
- public bool IsAutoClass {
- [Pure]
- get {return ((GetAttributeFlagsImpl() & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass);}
- }
-
- // These are not backed up by attributes. Instead they are implemented
- // based internally.
- public bool IsArray {
- [Pure]
- get {return IsArrayImpl();}
- }
-
- internal virtual bool IsSzArray {
- [Pure]
- get {return false;}
- }
-
- public virtual bool IsGenericType {
- [Pure]
- get { return false; }
- }
-
- public virtual bool IsGenericTypeDefinition {
- [Pure]
- get { return false; }
- }
-
- public virtual bool IsConstructedGenericType
- {
- [Pure]
- get { throw new NotImplementedException(); }
- }
-
- public virtual bool IsGenericParameter
- {
- [Pure]
- get { return false; }
- }
-
- public virtual int GenericParameterPosition {
- [Pure]
- get {throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter")); }
- }
-
- public virtual bool ContainsGenericParameters
- {
- [Pure]
- get
- {
- if (HasElementType)
- return GetRootElementType().ContainsGenericParameters;
-
- if (IsGenericParameter)
- return true;
-
- if (!IsGenericType)
- return false;
-
- Type[] genericArguments = GetGenericArguments();
- for (int i = 0; i < genericArguments.Length; i++)
- {
- if (genericArguments[i].ContainsGenericParameters)
- return true;
- }
-
- return false;
- }
- }
-
- [Pure]
- public virtual Type[] GetGenericParameterConstraints()
- {
- if (!IsGenericParameter)
- throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericParameter"));
- Contract.EndContractBlock();
-
- throw new InvalidOperationException();
- }
-
- public bool IsByRef {
- [Pure]
- get {return IsByRefImpl();}
- }
- public bool IsPointer {
- [Pure]
- get {return IsPointerImpl();}
- }
- public bool IsPrimitive {
- [Pure]
- get {return IsPrimitiveImpl();}
- }
- public bool IsCOMObject {
- [Pure]
- get {return IsCOMObjectImpl();}
- }
-
-#if FEATURE_COMINTEROP
- internal bool IsWindowsRuntimeObject {
- [Pure]
- get { return IsWindowsRuntimeObjectImpl(); }
- }
-
- internal bool IsExportedToWindowsRuntime {
- [Pure]
- get { return IsExportedToWindowsRuntimeImpl(); }
- }
-#endif // FEATURE_COMINTEROP
-
- public bool HasElementType {
- [Pure]
- get {return HasElementTypeImpl();}
- }
-
- public bool IsContextful {
- [Pure]
- get {return IsContextfulImpl();}
- }
-
- public bool IsMarshalByRef {
- [Pure]
- get {return IsMarshalByRefImpl();}
- }
-
- // Protected routine to determine if this class represents a value class
- // The default implementation of IsValueTypeImpl never returns true for non-runtime types.
- protected virtual bool IsValueTypeImpl()
- {
- // Note that typeof(Enum) and typeof(ValueType) are not themselves value types.
- // But there is no point excluding them here because customer derived System.Type
- // (non-runtime type) objects can never be equal to a runtime type, which typeof(XXX) is.
- // Ideally we should throw a NotImplementedException here or just return false because
- // customer implementations of IsSubclassOf should never return true between a non-runtime
- // type and a runtime type. There is no benefits in making that breaking change though.
-
- return IsSubclassOf(RuntimeType.ValueType);
- }
-
- // Protected routine to get the attributes.
- abstract protected TypeAttributes GetAttributeFlagsImpl();
-
- // Protected routine to determine if this class represents an Array
- abstract protected bool IsArrayImpl();
-
- // Protected routine to determine if this class is a ByRef
- abstract protected bool IsByRefImpl();
-
- // Protected routine to determine if this class is a Pointer
- abstract protected bool IsPointerImpl();
-
- // Protected routine to determine if this class represents a primitive type
- abstract protected bool IsPrimitiveImpl();
-
- // Protected routine to determine if this class represents a COM object
- abstract protected bool IsCOMObjectImpl();
-
-#if FEATURE_COMINTEROP
- // Protected routine to determine if this class represents a Windows Runtime object
- virtual internal bool IsWindowsRuntimeObjectImpl() {
- throw new NotImplementedException();
- }
-
- // Determines if this type is exported to WinRT (i.e. is an activatable class in a managed .winmd)
- virtual internal bool IsExportedToWindowsRuntimeImpl() {
- throw new NotImplementedException();
- }
-#endif // FEATURE_COMINTEROP
-
- public virtual Type MakeGenericType(params Type[] typeArguments) {
- Contract.Ensures(Contract.Result<Type>() != null);
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
- }
-
-
- // Protected routine to determine if this class is contextful
- protected virtual bool IsContextfulImpl()
- {
- return false;
- }
-
- // Protected routine to determine if this class is marshaled by ref
- protected virtual bool IsMarshalByRefImpl()
- {
- return false;
- }
-
- [Pure]
- abstract public Type GetElementType();
-
- [Pure]
- public virtual Type[] GetGenericArguments()
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
- }
-
- public virtual Type[] GenericTypeArguments{
- get{
- if(IsGenericType && !IsGenericTypeDefinition){
- return GetGenericArguments();
- }
- else{
- return Type.EmptyTypes;
- }
-
- }
- }
-
- [Pure]
- public virtual Type GetGenericTypeDefinition()
- {
- Contract.Ensures(Contract.Result<Type>() != null);
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
- }
-
- [Pure]
- abstract protected bool HasElementTypeImpl();
-
- internal Type GetRootElementType()
- {
- Type rootElementType = this;
-
- while (rootElementType.HasElementType)
- rootElementType = rootElementType.GetElementType();
-
- return rootElementType;
- }
-
-#region Enum methods
-
- // Default implementations of GetEnumNames, GetEnumValues, and GetEnumUnderlyingType
- // Subclass of types can override these methods.
-
- public virtual string[] GetEnumNames()
- {
- if (!IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
- Contract.Ensures(Contract.Result<String[]>() != null);
-
- string[] names;
- Array values;
- GetEnumData(out names, out values);
- return names;
- }
-
- // We don't support GetEnumValues in the default implementation because we cannot create an array of
- // a non-runtime type. If there is strong need we can consider returning an object or int64 array.
- public virtual Array GetEnumValues()
- {
- if (!IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
- Contract.Ensures(Contract.Result<Array>() != null);
-
- throw new NotImplementedException();
- }
-
- // Returns the enum values as an object array.
- private Array GetEnumRawConstantValues()
- {
- string[] names;
- Array values;
- GetEnumData(out names, out values);
- return values;
- }
-
- // This will return enumValues and enumNames sorted by the values.
- private void GetEnumData(out string[] enumNames, out Array enumValues)
- {
- Contract.Ensures(Contract.ValueAtReturn<String[]>(out enumNames) != null);
- Contract.Ensures(Contract.ValueAtReturn<Array>(out enumValues) != null);
-
- FieldInfo[] flds = GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
-
- object[] values = new object[flds.Length];
- string[] names = new string[flds.Length];
-
- for (int i = 0; i < flds.Length; i++)
- {
- names[i] = flds[i].Name;
- values[i] = flds[i].GetRawConstantValue();
- }
-
- // Insertion Sort these values in ascending order.
- // We use this O(n^2) algorithm, but it turns out that most of the time the elements are already in sorted order and
- // the common case performance will be faster than quick sorting this.
- IComparer comparer = Comparer.Default;
- for (int i = 1; i < values.Length; i++)
- {
- int j = i;
- string tempStr = names[i];
- object val = values[i];
- bool exchanged = false;
-
- // Since the elements are sorted we only need to do one comparision, we keep the check for j inside the loop.
- while (comparer.Compare(values[j - 1], val) > 0)
- {
- names[j] = names[j - 1];
- values[j] = values[j - 1];
- j--;
- exchanged = true;
- if (j == 0)
- break;
- }
-
- if (exchanged)
- {
- names[j] = tempStr;
- values[j] = val;
- }
- }
-
- enumNames = names;
- enumValues = values;
- }
-
- public virtual Type GetEnumUnderlyingType()
- {
- if (!IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
- Contract.Ensures(Contract.Result<Type>() != null);
-
- FieldInfo[] fields = GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
- if (fields == null || fields.Length != 1)
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidEnum"), "enumType");
-
- return fields[0].FieldType;
- }
-
- public virtual bool IsEnumDefined(object value)
- {
- if (value == null)
- throw new ArgumentNullException(nameof(value));
-
- if (!IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
- Contract.EndContractBlock();
-
- // Check if both of them are of the same type
- Type valueType = value.GetType();
-
- // If the value is an Enum then we need to extract the underlying value from it
- if (valueType.IsEnum)
- {
- if (!valueType.IsEquivalentTo(this))
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumAndObjectMustBeSameType", valueType.ToString(), this.ToString()));
-
- valueType = valueType.GetEnumUnderlyingType();
- }
-
- // If a string is passed in
- if (valueType == typeof(string))
- {
- string[] names = GetEnumNames();
- if (Array.IndexOf(names, value) >= 0)
- return true;
- else
- return false;
- }
-
- // If an enum or integer value is passed in
- if (Type.IsIntegerType(valueType))
- {
- Type underlyingType = GetEnumUnderlyingType();
- // We cannot compare the types directly because valueType is always a runtime type but underlyingType might not be.
- if (underlyingType.GetTypeCodeImpl() != valueType.GetTypeCodeImpl())
- throw new ArgumentException(Environment.GetResourceString("Arg_EnumUnderlyingTypeAndObjectMustBeSameType", valueType.ToString(), underlyingType.ToString()));
-
- Array values = GetEnumRawConstantValues();
- return (BinarySearch(values, value) >= 0);
- }
- else
- {
- throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_UnknownEnumType"));
- }
- }
-
- public virtual string GetEnumName(object value)
- {
- if (value == null)
- throw new ArgumentNullException(nameof(value));
-
- if (!IsEnum)
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
- Contract.EndContractBlock();
-
- Type valueType = value.GetType();
-
- if (!(valueType.IsEnum || Type.IsIntegerType(valueType)))
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), nameof(value));
-
- Array values = GetEnumRawConstantValues();
- int index = BinarySearch(values, value);
-
- if (index >= 0)
- {
- string[] names = GetEnumNames();
- return names[index];
- }
-
- return null;
- }
-
- // Convert everything to ulong then perform a binary search.
- private static int BinarySearch(Array array, object value)
- {
- ulong[] ulArray = new ulong[array.Length];
- for (int i = 0; i < array.Length; ++i)
- ulArray[i] = Enum.ToUInt64(array.GetValue(i));
-
- ulong ulValue = Enum.ToUInt64(value);
-
- return Array.BinarySearch(ulArray, ulValue);
- }
-
- internal static bool IsIntegerType(Type t)
- {
- return (t == typeof(int) ||
- t == typeof(short) ||
- t == typeof(ushort) ||
- t == typeof(byte) ||
- t == typeof(sbyte) ||
- t == typeof(uint) ||
- t == typeof(long) ||
- t == typeof(ulong) ||
- t == typeof(char) ||
- t == typeof(bool));
- }
-#endregion
-
- public virtual bool IsSecurityCritical { [Pure] get { throw new NotImplementedException(); } }
-
- public virtual bool IsSecuritySafeCritical { [Pure] get { throw new NotImplementedException(); } }
-
- public virtual bool IsSecurityTransparent { [Pure] get { throw new NotImplementedException(); } }
-
- internal bool NeedsReflectionSecurityCheck
- {
- get
- {
- if (!IsVisible)
- {
- // Types which are not externally visible require security checks
- return true;
- }
- else if (IsSecurityCritical && !IsSecuritySafeCritical)
- {
- // Critical types require security checks
- return true;
- }
- else if (IsGenericType)
- {
- // If any of the generic arguments to this type require a security check, then this type
- // also requires one.
- foreach (Type genericArgument in GetGenericArguments())
- {
- if (genericArgument.NeedsReflectionSecurityCheck)
- {
- return true;
- }
- }
- }
- else if (IsArray || IsPointer)
- {
- return GetElementType().NeedsReflectionSecurityCheck;
- }
-
- return false;
- }
- }
-
- // The behavior of UnderlyingSystemType varies from type to type.
- // For IReflect objects: Return the underlying Type that represents the IReflect Object.
- // For expando object: this is the (Object) IReflectInstance.GetType(). For Type object it is this.
- // It could also return the baked type or the underlying enum type in RefEmit. See the comment in
- // code:TypeBuilder.SetConstantValue.
- public abstract Type UnderlyingSystemType {
- get;
- }
-
- // Returns true of this class is a true subclass of c. Everything
- // else returns false. If this class and c are the same class false is
- // returned.
- //
- [Pure]
- public virtual bool IsSubclassOf(Type c)
- {
- Type p = this;
- if (p == c)
- return false;
- while (p != null) {
- if (p == c)
- return true;
- p = p.BaseType;
- }
- return false;
- }
-
- // Returns true if the object passed is assignable to an instance of this class.
- // Everything else returns false.
- //
- [Pure]
- public virtual bool IsInstanceOfType(Object o)
- {
- if (o == null)
- return false;
-
- // No need for transparent proxy casting check here
- // because it never returns true for a non-rutnime type.
-
- return IsAssignableFrom(o.GetType());
- }
-
- // Returns true if an instance of Type c may be assigned
- // to an instance of this class. Return false otherwise.
- //
- [Pure]
- public virtual bool IsAssignableFrom(Type c)
- {
- if (c == null)
- return false;
-
- if (this == c)
- return true;
-
- // For backward-compatibility, we need to special case for the types
- // whose UnderlyingSystemType are RuntimeType objects.
- RuntimeType toType = this.UnderlyingSystemType as RuntimeType;
- if (toType != null)
- return toType.IsAssignableFrom(c);
-
- // If c is a subclass of this class, then c can be cast to this type.
- if (c.IsSubclassOf(this))
- return true;
-
- if (this.IsInterface)
- {
- return c.ImplementInterface(this);
- }
- else if (IsGenericParameter)
- {
- Type[] constraints = GetGenericParameterConstraints();
- for (int i = 0; i < constraints.Length; i++)
- if (!constraints[i].IsAssignableFrom(c))
- return false;
-
- return true;
- }
-
- return false;
- }
-
- // Base implementation that does only ==.
- [Pure]
- public virtual bool IsEquivalentTo(Type other)
- {
- return (this == other);
- }
-
- internal bool ImplementInterface(Type ifaceType)
- {
- Contract.Requires(ifaceType != null);
- Contract.Requires(ifaceType.IsInterface, "ifaceType must be an interface type");
-
- Type t = this;
- while (t != null)
- {
- Type[] interfaces = t.GetInterfaces();
- if (interfaces != null)
- {
- for (int i = 0; i < interfaces.Length; i++)
- {
- // Interfaces don't derive from other interfaces, they implement them.
- // So instead of IsSubclassOf, we should use ImplementInterface instead.
- if (interfaces[i] == ifaceType ||
- (interfaces[i] != null && interfaces[i].ImplementInterface(ifaceType)))
- return true;
- }
- }
-
- t = t.BaseType;
- }
-
- return false;
- }
-
- // This is only ever called on RuntimeType objects.
- internal string FormatTypeName()
- {
- return FormatTypeName(false);
- }
-
- internal virtual string FormatTypeName(bool serialization)
- {
- throw new NotImplementedException();
- }
-
- // ToString
- // Print the String Representation of the Type
- public override String ToString()
- {
- // Why do we add the "Type: " prefix? RuntimeType.ToString() doesn't include it.
- return "Type: " + Name;
- }
-
- // This method will return an array of classes based upon the array of
- // types.
- public static Type[] GetTypeArray(Object[] args) {
- if (args == null)
- throw new ArgumentNullException(nameof(args));
- Contract.EndContractBlock();
- Type[] cls = new Type[args.Length];
- for (int i = 0;i < cls.Length;i++)
- {
- if (args[i] == null)
- throw new ArgumentNullException();
- cls[i] = args[i].GetType();
- }
- return cls;
- }
-
- [Pure]
- public override bool Equals(Object o)
- {
- if (o == null)
- return false;
-
- return Equals(o as Type);
- }
-
- [Pure]
- public virtual bool Equals(Type o)
- {
- if ((object)o == null)
- return false;
-
- return (Object.ReferenceEquals(this.UnderlyingSystemType, o.UnderlyingSystemType));
- }
-
- [Pure]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern bool operator ==(Type left, Type right);
-
- [Pure]
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern bool operator !=(Type left, Type right);
-
- public override int GetHashCode()
- {
- Type SystemType = UnderlyingSystemType;
- if (!Object.ReferenceEquals(SystemType, this))
- return SystemType.GetHashCode();
- return base.GetHashCode();
- }
-
-
- // GetInterfaceMap
- // This method will return an interface mapping for the interface
- // requested. It will throw an argument exception if the Type doesn't
- // implemenet the interface.
- public virtual InterfaceMapping GetInterfaceMap(Type interfaceType)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride"));
- }
-
- // this method is required so Object.GetType is not made virtual by the compiler
- public new Type GetType()
- {
- return base.GetType();
- }
-
- // private convenience data
- private const BindingFlags DefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
- internal const BindingFlags DeclaredOnlyLookup = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
-}
-}
diff --git a/src/mscorlib/src/System/TypeLoadException.cs b/src/mscorlib/src/System/TypeLoadException.cs
index 7bc3a1bcce..85e1da5920 100644
--- a/src/mscorlib/src/System/TypeLoadException.cs
+++ b/src/mscorlib/src/System/TypeLoadException.cs
@@ -10,56 +10,63 @@
**
**
=============================================================================*/
-namespace System {
-
- using System;
- using System.Globalization;
- using System.Runtime.Remoting;
- using System.Runtime.Serialization;
- using System.Runtime.InteropServices;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Security;
- using System.Diagnostics.Contracts;
- [Serializable]
- public class TypeLoadException : SystemException, ISerializable {
+using System;
+using System.Globalization;
+using System.Runtime.Remoting;
+using System.Runtime.Serialization;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+using System.Security;
+using System.Diagnostics.Contracts;
- public TypeLoadException()
- : base(Environment.GetResourceString("Arg_TypeLoadException")) {
- SetErrorCode(__HResults.COR_E_TYPELOAD);
+namespace System
+{
+ [Serializable]
+ public class TypeLoadException : SystemException, ISerializable
+ {
+ public TypeLoadException()
+ : base(SR.Arg_TypeLoadException)
+ {
+ HResult = __HResults.COR_E_TYPELOAD;
}
-
- public TypeLoadException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_TYPELOAD);
+
+ public TypeLoadException(String message)
+ : base(message)
+ {
+ HResult = __HResults.COR_E_TYPELOAD;
}
-
- public TypeLoadException(String message, Exception inner)
- : base(message, inner) {
- SetErrorCode(__HResults.COR_E_TYPELOAD);
+
+ public TypeLoadException(String message, Exception inner)
+ : base(message, inner)
+ {
+ HResult = __HResults.COR_E_TYPELOAD;
}
-
+
public override String Message
{
- get {
+ get
+ {
SetMessageField();
return _message;
}
}
-
+
private void SetMessageField()
{
- if (_message == null) {
+ if (_message == null)
+ {
if ((ClassName == null) &&
(ResourceId == 0))
- _message = Environment.GetResourceString("Arg_TypeLoadException");
+ _message = SR.Arg_TypeLoadException;
- else {
+ else
+ {
if (AssemblyName == null)
- AssemblyName = Environment.GetResourceString("IO_UnknownFileName");
+ AssemblyName = SR.IO_UnknownFileName;
if (ClassName == null)
- ClassName = Environment.GetResourceString("IO_UnknownFileName");
+ ClassName = SR.IO_UnknownFileName;
String format = null;
GetTypeLoadExceptionMessage(ResourceId, JitHelpers.GetStringHandleOnStack(ref format));
@@ -70,50 +77,53 @@ namespace System {
public String TypeName
{
- get {
+ get
+ {
if (ClassName == null)
return String.Empty;
return ClassName;
}
}
-
+
// This is called from inside the EE.
private TypeLoadException(String className,
String assemblyName,
String messageArg,
- int resourceId)
+ int resourceId)
: base(null)
{
- SetErrorCode(__HResults.COR_E_TYPELOAD);
- ClassName = className;
+ HResult = __HResults.COR_E_TYPELOAD;
+ ClassName = className;
AssemblyName = assemblyName;
MessageArg = messageArg;
ResourceId = resourceId;
// Set the _message field eagerly; debuggers look at this field to
// display error info. They don't call the Message property.
- SetMessageField();
+ SetMessageField();
}
- protected TypeLoadException(SerializationInfo info, StreamingContext context) : base(info, context) {
+ protected TypeLoadException(SerializationInfo info, StreamingContext context) : base(info, context)
+ {
if (info == null)
throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
- ClassName = info.GetString("TypeLoadClassName");
+ ClassName = info.GetString("TypeLoadClassName");
AssemblyName = info.GetString("TypeLoadAssemblyName");
MessageArg = info.GetString("TypeLoadMessageArg");
ResourceId = info.GetInt32("TypeLoadResourceID");
}
-
+
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void GetTypeLoadExceptionMessage(int resourceId, StringHandleOnStack retString);
-
+
//We can rely on the serialization mechanism on Exception to handle most of our needs, but
//we need to add a few fields of our own.
- public override void GetObjectData(SerializationInfo info, StreamingContext context) {
+ public override void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
if (info == null)
throw new ArgumentNullException(nameof(info));
Contract.EndContractBlock();
@@ -124,13 +134,13 @@ namespace System {
info.AddValue("TypeLoadMessageArg", MessageArg, typeof(String));
info.AddValue("TypeLoadResourceID", ResourceId);
}
-
+
// If ClassName != null, GetMessage will construct on the fly using it
// and ResourceId (mscorrc.dll). This allows customization of the
// class name format depending on the language environment.
- private String ClassName;
- private String AssemblyName;
- private String MessageArg;
- internal int ResourceId;
+ private String ClassName;
+ private String AssemblyName;
+ private String MessageArg;
+ internal int ResourceId;
}
}
diff --git a/src/mscorlib/src/System/TypeNameParser.cs b/src/mscorlib/src/System/TypeNameParser.cs
index 844578210f..f9d608968f 100644
--- a/src/mscorlib/src/System/TypeNameParser.cs
+++ b/src/mscorlib/src/System/TypeNameParser.cs
@@ -1,6 +1,7 @@
// 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.Diagnostics;
using System.Diagnostics.Contracts;
@@ -73,7 +74,7 @@ namespace System
if (typeName == null)
throw new ArgumentNullException(nameof(typeName));
if (typeName.Length > 0 && typeName[0] == '\0')
- throw new ArgumentException(Environment.GetResourceString("Format_StringZeroLength"));
+ throw new ArgumentException(SR.Format_StringZeroLength);
Contract.EndContractBlock();
Type ret = null;
@@ -96,7 +97,7 @@ namespace System
#region Private Data Members
private SafeTypeNameParserHandle m_NativeParser;
- private static readonly char[] SPECIAL_CHARS = {',', '[', ']', '&', '*', '+', '\\'}; /* see typeparse.h */
+ private static readonly char[] SPECIAL_CHARS = { ',', '[', ']', '&', '*', '+', '\\' }; /* see typeparse.h */
#endregion
#region Constructor and Disposer
@@ -142,7 +143,7 @@ namespace System
{
// This can only happen if the type name is an empty string or if the first char is '\0'
if (throwOnError)
- throw new TypeLoadException(Environment.GetResourceString("Arg_TypeLoadNullStr"));
+ throw new TypeLoadException(SR.Arg_TypeLoadNullStr);
return null;
}
@@ -207,7 +208,7 @@ namespace System
// Other exceptions like BadImangeFormatException should still fly.
try
{
- assembly = RuntimeAssembly.InternalLoad(asmName, null, ref stackMark, false /*forIntrospection*/);
+ assembly = RuntimeAssembly.InternalLoad(asmName, null, ref stackMark, false /*forIntrospection*/);
}
catch (FileNotFoundException)
{
@@ -220,7 +221,7 @@ namespace System
assembly = assemblyResolver(new AssemblyName(asmName));
if (assembly == null && throwOnError)
{
- throw new FileNotFoundException(Environment.GetResourceString("FileNotFound_ResolveAssembly", asmName));
+ throw new FileNotFoundException(SR.Format(SR.FileNotFound_ResolveAssembly, asmName));
}
}
@@ -244,8 +245,8 @@ namespace System
if (type == null && throwOnError)
{
string errorString = assembly == null ?
- Environment.GetResourceString("TypeLoad_ResolveType", OuterMostTypeName) :
- Environment.GetResourceString("TypeLoad_ResolveTypeFromAssembly", OuterMostTypeName, assembly.FullName);
+ SR.Format(SR.TypeLoad_ResolveType, OuterMostTypeName):
+ SR.Format(SR.TypeLoad_ResolveTypeFromAssembly, OuterMostTypeName, assembly.FullName);
throw new TypeLoadException(errorString);
}
@@ -276,7 +277,7 @@ namespace System
if (type == null)
{
if (throwOnError)
- throw new TypeLoadException(Environment.GetResourceString("TypeLoad_ResolveNestedType", names[i], names[i-1]));
+ throw new TypeLoadException(SR.Format(SR.TypeLoad_ResolveNestedType, names[i], names[i - 1]));
else
break;
}
@@ -339,7 +340,7 @@ namespace System
{
string assemblyName = null;
_GetAssemblyName(m_NativeParser, JitHelpers.GetStringHandleOnStack(ref assemblyName));
-
+
return assemblyName;
}
#endregion
diff --git a/src/mscorlib/src/System/TypeUnloadedException.cs b/src/mscorlib/src/System/TypeUnloadedException.cs
deleted file mode 100644
index f05d673a74..0000000000
--- a/src/mscorlib/src/System/TypeUnloadedException.cs
+++ /dev/null
@@ -1,42 +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.
-
-/*=============================================================================
-**
-**
-**
-** Purpose: Exception class for attempt to access an unloaded class
-**
-**
-=============================================================================*/
-
-namespace System {
-
- using System.Runtime.Serialization;
-
- [Serializable]
- public class TypeUnloadedException : SystemException {
- public TypeUnloadedException()
- : base(Environment.GetResourceString("Arg_TypeUnloadedException")) {
- SetErrorCode(__HResults.COR_E_TYPEUNLOADED);
- }
-
- public TypeUnloadedException(String message)
- : base(message) {
- SetErrorCode(__HResults.COR_E_TYPEUNLOADED);
- }
-
- public TypeUnloadedException(String message, Exception innerException)
- : base(message, innerException) {
- SetErrorCode(__HResults.COR_E_TYPEUNLOADED);
- }
-
- //
- // This constructor is required for serialization;
- //
- protected TypeUnloadedException(SerializationInfo info, StreamingContext context) : base (info, context) {
- }
- }
-}
-
diff --git a/src/mscorlib/src/System/TypedReference.cs b/src/mscorlib/src/System/TypedReference.cs
index 5e8f3c4c04..ca65082158 100644
--- a/src/mscorlib/src/System/TypedReference.cs
+++ b/src/mscorlib/src/System/TypedReference.cs
@@ -2,10 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System {
-
+namespace System
+{
// TypedReference is basically only ever seen on the call stack, and in param arrays.
// These are blob that must be dealt with by the compiler.
+
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
@@ -14,7 +15,7 @@ namespace System {
using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
- [CLSCompliant(false)]
+ [CLSCompliant(false)]
[System.Runtime.Versioning.NonVersionable] // This only applies to field layout
public struct TypedReference
{
@@ -22,14 +23,15 @@ namespace System {
private IntPtr Type;
[CLSCompliant(false)]
- public static TypedReference MakeTypedReference(Object target, FieldInfo[] flds) {
+ public static TypedReference MakeTypedReference(Object target, FieldInfo[] flds)
+ {
if (target == null)
throw new ArgumentNullException(nameof(target));
if (flds == null)
throw new ArgumentNullException(nameof(flds));
Contract.EndContractBlock();
if (flds.Length == 0)
- throw new ArgumentException(Environment.GetResourceString("Arg_ArrayZeroError"));
+ throw new ArgumentException(SR.Arg_ArrayZeroError);
IntPtr[] fields = new IntPtr[flds.Length];
// For proper handling of Nullable<T> don't change GetType() to something like 'IsAssignableFrom'
@@ -39,29 +41,29 @@ namespace System {
{
RuntimeFieldInfo field = flds[i] as RuntimeFieldInfo;
if (field == null)
- throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeFieldInfo"));
+ throw new ArgumentException(SR.Argument_MustBeRuntimeFieldInfo);
if (field.IsInitOnly || field.IsStatic)
- throw new ArgumentException(Environment.GetResourceString("Argument_TypedReferenceInvalidField"));
-
+ throw new ArgumentException(SR.Argument_TypedReferenceInvalidField);
+
if (targetType != field.GetDeclaringTypeInternal() && !targetType.IsSubclassOf(field.GetDeclaringTypeInternal()))
- throw new MissingMemberException(Environment.GetResourceString("MissingMemberTypeRef"));
+ throw new MissingMemberException(SR.MissingMemberTypeRef);
RuntimeType fieldType = (RuntimeType)field.FieldType;
if (fieldType.IsPrimitive)
- throw new ArgumentException(Environment.GetResourceString("Arg_TypeRefPrimitve"));
-
+ throw new ArgumentException(SR.Arg_TypeRefPrimitve);
+
if (i < (flds.Length - 1) && !fieldType.IsValueType)
- throw new MissingMemberException(Environment.GetResourceString("MissingMemberNestErr"));
-
+ throw new MissingMemberException(SR.MissingMemberNestErr);
+
fields[i] = field.FieldHandle.Value;
targetType = fieldType;
}
- TypedReference result = new TypedReference ();
+ TypedReference result = new TypedReference();
// reference to TypedReference is banned, so have to pass result as pointer
- unsafe
+ unsafe
{
InternalMakeTypedReference(&result, target, fields, targetType);
}
@@ -82,7 +84,7 @@ namespace System {
public override bool Equals(Object o)
{
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_NYI"));
+ throw new NotSupportedException(SR.NotSupported_NYI);
}
public unsafe static Object ToObject(TypedReference value)
@@ -91,22 +93,22 @@ namespace System {
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal unsafe extern static Object InternalToObject(void * value);
+ internal unsafe extern static Object InternalToObject(void* value);
- internal bool IsNull
- {
+ internal bool IsNull
+ {
get
{
- return Value.IsNull() && Type.IsNull();
+ return Value.IsNull() && Type.IsNull();
}
}
- public static Type GetTargetType (TypedReference value)
+ public static Type GetTargetType(TypedReference value)
{
return __reftype(value);
}
- public static RuntimeTypeHandle TargetTypeToken (TypedReference value)
+ public static RuntimeTypeHandle TargetTypeToken(TypedReference value)
{
return __reftype(value).TypeHandle;
}
@@ -119,7 +121,6 @@ namespace System {
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal unsafe extern static void InternalSetTypedReference(void * target, Object value);
+ internal unsafe extern static void InternalSetTypedReference(void* target, Object value);
}
-
}
diff --git a/src/mscorlib/src/System/UInt16.cs b/src/mscorlib/src/System/UInt16.cs
index 5cd1a65b70..e4a6837ae2 100644
--- a/src/mscorlib/src/System/UInt16.cs
+++ b/src/mscorlib/src/System/UInt16.cs
@@ -10,46 +10,54 @@
**
**
===========================================================*/
-namespace System {
- using System.Globalization;
- using System;
- using System.Runtime.InteropServices;
- using System.Diagnostics.Contracts;
+using System.Globalization;
+using System;
+using System.Runtime.InteropServices;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
// Wrapper for unsigned 16 bit integers.
-[Serializable]
-[CLSCompliant(false), System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
+ [Serializable]
+ [CLSCompliant(false), System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public struct UInt16 : IComparable, IFormattable, IConvertible
- , IComparable<UInt16>, IEquatable<UInt16>
+ , IComparable<UInt16>, IEquatable<UInt16>
{
private ushort m_value;
-
+
public const ushort MaxValue = (ushort)0xFFFF;
public const ushort MinValue = 0;
-
-
+
+
// Compares this object to another object, returning an integer that
// indicates the relationship.
// Returns a value less than zero if this object
// null is considered to be less than any instance.
// If object is not of type UInt16, this method throws an ArgumentException.
//
- public int CompareTo(Object value) {
- if (value == null) {
+ public int CompareTo(Object value)
+ {
+ if (value == null)
+ {
return 1;
}
- if (value is UInt16) {
+ if (value is UInt16)
+ {
return ((int)m_value - (int)(((UInt16)value).m_value));
}
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeUInt16"));
+ throw new ArgumentException(SR.Arg_MustBeUInt16);
}
- public int CompareTo(UInt16 value) {
+ public int CompareTo(UInt16 value)
+ {
return ((int)m_value - (int)value);
}
-
- public override bool Equals(Object obj) {
- if (!(obj is UInt16)) {
+
+ public override bool Equals(Object obj)
+ {
+ if (!(obj is UInt16))
+ {
return false;
}
return m_value == ((UInt16)obj).m_value;
@@ -62,174 +70,190 @@ namespace System {
}
// Returns a HashCode for the UInt16
- public override int GetHashCode() {
+ public override int GetHashCode()
+ {
return (int)m_value;
}
// Converts the current value to a String in base-10 with no extra padding.
- public override String ToString() {
+ public override String ToString()
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, null, NumberFormatInfo.CurrentInfo);
}
- public String ToString(IFormatProvider provider) {
+ public String ToString(IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, null, NumberFormatInfo.GetInstance(provider));
}
- public String ToString(String format) {
+ public String ToString(String format)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, format, NumberFormatInfo.CurrentInfo);
}
-
- public String ToString(String format, IFormatProvider provider) {
+
+ public String ToString(String format, IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, format, NumberFormatInfo.GetInstance(provider));
}
[CLSCompliant(false)]
- public static ushort Parse(String s) {
+ public static ushort Parse(String s)
+ {
return Parse(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
-
+
[CLSCompliant(false)]
- public static ushort Parse(String s, NumberStyles style) {
+ public static ushort Parse(String s, NumberStyles style)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Parse(s, style, NumberFormatInfo.CurrentInfo);
}
[CLSCompliant(false)]
- public static ushort Parse(String s, IFormatProvider provider) {
+ public static ushort Parse(String s, IFormatProvider provider)
+ {
return Parse(s, NumberStyles.Integer, NumberFormatInfo.GetInstance(provider));
}
-
+
[CLSCompliant(false)]
- public static ushort Parse(String s, NumberStyles style, IFormatProvider provider) {
+ public static ushort Parse(String s, NumberStyles style, IFormatProvider provider)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Parse(s, style, NumberFormatInfo.GetInstance(provider));
}
-
- private static ushort Parse(String s, NumberStyles style, NumberFormatInfo info) {
-
+
+ private static ushort Parse(String s, NumberStyles style, NumberFormatInfo info)
+ {
uint i = 0;
- try {
+ try
+ {
i = Number.ParseUInt32(s, style, info);
}
- catch(OverflowException e) {
- throw new OverflowException(Environment.GetResourceString("Overflow_UInt16"), e);
+ catch (OverflowException e)
+ {
+ throw new OverflowException(SR.Overflow_UInt16, e);
}
- if (i > MaxValue) throw new OverflowException(Environment.GetResourceString("Overflow_UInt16"));
+ if (i > MaxValue) throw new OverflowException(SR.Overflow_UInt16);
return (ushort)i;
}
[CLSCompliant(false)]
- public static bool TryParse(String s, out UInt16 result) {
+ public static bool TryParse(String s, out UInt16 result)
+ {
return TryParse(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result);
}
[CLSCompliant(false)]
- public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out UInt16 result) {
+ public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out UInt16 result)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return TryParse(s, style, NumberFormatInfo.GetInstance(provider), out result);
}
-
- private static bool TryParse(String s, NumberStyles style, NumberFormatInfo info, out UInt16 result) {
+ private static bool TryParse(String s, NumberStyles style, NumberFormatInfo info, out UInt16 result)
+ {
result = 0;
UInt32 i;
- if (!Number.TryParseUInt32(s, style, info, out i)) {
+ if (!Number.TryParseUInt32(s, style, info, out i))
+ {
return false;
}
- if (i > MaxValue) {
+ if (i > MaxValue)
+ {
return false;
}
- result = (UInt16) i;
+ result = (UInt16)i;
return true;
}
//
// IConvertible implementation
//
-
- public TypeCode GetTypeCode() {
+
+ public TypeCode GetTypeCode()
+ {
return TypeCode.UInt16;
}
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
return Convert.ToBoolean(m_value);
}
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
return Convert.ToChar(m_value);
}
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
return Convert.ToSByte(m_value);
}
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
return Convert.ToByte(m_value);
}
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
return Convert.ToInt16(m_value);
}
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
return m_value;
}
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
return Convert.ToInt32(m_value);
}
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
return Convert.ToUInt32(m_value);
}
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
return Convert.ToInt64(m_value);
}
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
return Convert.ToUInt64(m_value);
}
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
return Convert.ToSingle(m_value);
}
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
return Convert.ToDouble(m_value);
}
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider) {
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
return Convert.ToDecimal(m_value);
}
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "UInt16", "DateTime"));
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "UInt16", "DateTime"));
}
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
return Convert.DefaultToType((IConvertible)this, type, provider);
}
}
diff --git a/src/mscorlib/src/System/UInt32.cs b/src/mscorlib/src/System/UInt32.cs
index fc3f10f96f..7c27efef39 100644
--- a/src/mscorlib/src/System/UInt32.cs
+++ b/src/mscorlib/src/System/UInt32.cs
@@ -11,16 +11,18 @@
**
**
===========================================================*/
-namespace System {
- using System.Globalization;
- using System;
- using System.Runtime;
- using System.Runtime.InteropServices;
- using System.Diagnostics.Contracts;
+using System.Globalization;
+using System;
+using System.Runtime;
+using System.Runtime.InteropServices;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
// * Wrapper for unsigned 32 bit integers.
[Serializable]
- [CLSCompliant(false), System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
+ [CLSCompliant(false), System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public struct UInt32 : IComparable, IFormattable, IConvertible
, IComparable<UInt32>, IEquatable<UInt32>
{
@@ -28,19 +30,22 @@ namespace System {
public const uint MaxValue = (uint)0xffffffff;
public const uint MinValue = 0U;
-
-
+
+
// Compares this object to another object, returning an integer that
// indicates the relationship.
// Returns a value less than zero if this object
// null is considered to be less than any instance.
// If object is not of type UInt32, this method throws an ArgumentException.
//
- public int CompareTo(Object value) {
- if (value == null) {
+ public int CompareTo(Object value)
+ {
+ if (value == null)
+ {
return 1;
}
- if (value is UInt32) {
+ if (value is UInt32)
+ {
// Need to use compare because subtraction will wrap
// to positive for very large neg numbers, etc.
uint i = (uint)value;
@@ -48,19 +53,22 @@ namespace System {
if (m_value > i) return 1;
return 0;
}
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeUInt32"));
+ throw new ArgumentException(SR.Arg_MustBeUInt32);
}
- public int CompareTo(UInt32 value) {
+ public int CompareTo(UInt32 value)
+ {
// Need to use compare because subtraction will wrap
// to positive for very large neg numbers, etc.
if (m_value < value) return -1;
if (m_value > value) return 1;
return 0;
}
-
- public override bool Equals(Object obj) {
- if (!(obj is UInt32)) {
+
+ public override bool Equals(Object obj)
+ {
+ if (!(obj is UInt32))
+ {
return false;
}
return m_value == ((UInt32)obj).m_value;
@@ -73,61 +81,72 @@ namespace System {
}
// The absolute value of the int contained.
- public override int GetHashCode() {
- return ((int) m_value);
+ public override int GetHashCode()
+ {
+ return ((int)m_value);
}
-
+
// The base 10 representation of the number with no extra padding.
- public override String ToString() {
+ public override String ToString()
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, null, NumberFormatInfo.CurrentInfo);
}
- public String ToString(IFormatProvider provider) {
+ public String ToString(IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, null, NumberFormatInfo.GetInstance(provider));
}
- public String ToString(String format) {
+ public String ToString(String format)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, format, NumberFormatInfo.CurrentInfo);
}
- public String ToString(String format, IFormatProvider provider) {
+ public String ToString(String format, IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt32(m_value, format, NumberFormatInfo.GetInstance(provider));
}
[CLSCompliant(false)]
- public static uint Parse(String s) {
+ public static uint Parse(String s)
+ {
return Number.ParseUInt32(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
-
+
[CLSCompliant(false)]
- public static uint Parse(String s, NumberStyles style) {
+ public static uint Parse(String s, NumberStyles style)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Number.ParseUInt32(s, style, NumberFormatInfo.CurrentInfo);
}
[CLSCompliant(false)]
- public static uint Parse(String s, IFormatProvider provider) {
+ public static uint Parse(String s, IFormatProvider provider)
+ {
return Number.ParseUInt32(s, NumberStyles.Integer, NumberFormatInfo.GetInstance(provider));
}
[CLSCompliant(false)]
- public static uint Parse(String s, NumberStyles style, IFormatProvider provider) {
+ public static uint Parse(String s, NumberStyles style, IFormatProvider provider)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Number.ParseUInt32(s, style, NumberFormatInfo.GetInstance(provider));
}
[CLSCompliant(false)]
- public static bool TryParse(String s, out UInt32 result) {
+ public static bool TryParse(String s, out UInt32 result)
+ {
return Number.TryParseUInt32(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result);
}
[CLSCompliant(false)]
- public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out UInt32 result) {
+ public static bool TryParse(String s, NumberStyles style, IFormatProvider provider, out UInt32 result)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Number.TryParseUInt32(s, style, NumberFormatInfo.GetInstance(provider), out result);
}
@@ -135,83 +154,84 @@ namespace System {
//
// IConvertible implementation
//
-
- public TypeCode GetTypeCode() {
+
+ public TypeCode GetTypeCode()
+ {
return TypeCode.UInt32;
}
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
return Convert.ToBoolean(m_value);
}
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
return Convert.ToChar(m_value);
}
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
return Convert.ToSByte(m_value);
}
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
return Convert.ToByte(m_value);
}
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
return Convert.ToInt16(m_value);
}
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
return Convert.ToUInt16(m_value);
}
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
return Convert.ToInt32(m_value);
}
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
return m_value;
}
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
return Convert.ToInt64(m_value);
}
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
return Convert.ToUInt64(m_value);
}
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
return Convert.ToSingle(m_value);
}
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
return Convert.ToDouble(m_value);
}
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider) {
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
return Convert.ToDecimal(m_value);
}
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "UInt32", "DateTime"));
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "UInt32", "DateTime"));
}
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
return Convert.DefaultToType((IConvertible)this, type, provider);
}
}
diff --git a/src/mscorlib/src/System/UInt64.cs b/src/mscorlib/src/System/UInt64.cs
index 3b64f056e9..0b79b6a7d8 100644
--- a/src/mscorlib/src/System/UInt64.cs
+++ b/src/mscorlib/src/System/UInt64.cs
@@ -10,34 +10,39 @@
**
**
===========================================================*/
-namespace System {
- using System.Globalization;
- using System;
- using System.Runtime.InteropServices;
- using System.Diagnostics.Contracts;
+using System.Globalization;
+using System;
+using System.Runtime.InteropServices;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
// Wrapper for unsigned 64 bit integers.
-[Serializable]
-[CLSCompliant(false), System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
+ [Serializable]
+ [CLSCompliant(false), System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential)]
public struct UInt64 : IComparable, IFormattable, IConvertible
- , IComparable<UInt64>, IEquatable<UInt64>
+ , IComparable<UInt64>, IEquatable<UInt64>
{
private ulong m_value;
-
- public const ulong MaxValue = (ulong) 0xffffffffffffffffL;
+
+ public const ulong MaxValue = (ulong)0xffffffffffffffffL;
public const ulong MinValue = 0x0;
-
+
// Compares this object to another object, returning an integer that
// indicates the relationship.
// Returns a value less than zero if this object
// null is considered to be less than any instance.
// If object is not of type UInt64, this method throws an ArgumentException.
//
- public int CompareTo(Object value) {
- if (value == null) {
+ public int CompareTo(Object value)
+ {
+ if (value == null)
+ {
return 1;
}
- if (value is UInt64) {
+ if (value is UInt64)
+ {
// Need to use compare because subtraction will wrap
// to positive for very large neg numbers, etc.
ulong i = (ulong)value;
@@ -45,19 +50,22 @@ namespace System {
if (m_value > i) return 1;
return 0;
}
- throw new ArgumentException (Environment.GetResourceString("Arg_MustBeUInt64"));
+ throw new ArgumentException(SR.Arg_MustBeUInt64);
}
- public int CompareTo(UInt64 value) {
+ public int CompareTo(UInt64 value)
+ {
// Need to use compare because subtraction will wrap
// to positive for very large neg numbers, etc.
if (m_value < value) return -1;
if (m_value > value) return 1;
return 0;
}
-
- public override bool Equals(Object obj) {
- if (!(obj is UInt64)) {
+
+ public override bool Equals(Object obj)
+ {
+ if (!(obj is UInt64))
+ {
return false;
}
return m_value == ((UInt64)obj).m_value;
@@ -70,59 +78,70 @@ namespace System {
}
// The value of the lower 32 bits XORed with the uppper 32 bits.
- public override int GetHashCode() {
+ public override int GetHashCode()
+ {
return ((int)m_value) ^ (int)(m_value >> 32);
}
- public override String ToString() {
+ public override String ToString()
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt64(m_value, null, NumberFormatInfo.CurrentInfo);
}
-
- public String ToString(IFormatProvider provider) {
+
+ public String ToString(IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt64(m_value, null, NumberFormatInfo.GetInstance(provider));
- }
-
- public String ToString(String format) {
+ }
+
+ public String ToString(String format)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt64(m_value, format, NumberFormatInfo.CurrentInfo);
}
- public String ToString(String format, IFormatProvider provider) {
+ public String ToString(String format, IFormatProvider provider)
+ {
Contract.Ensures(Contract.Result<String>() != null);
return Number.FormatUInt64(m_value, format, NumberFormatInfo.GetInstance(provider));
}
[CLSCompliant(false)]
- public static ulong Parse(String s) {
+ public static ulong Parse(String s)
+ {
return Number.ParseUInt64(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
-
+
[CLSCompliant(false)]
- public static ulong Parse(String s, NumberStyles style) {
+ public static ulong Parse(String s, NumberStyles style)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Number.ParseUInt64(s, style, NumberFormatInfo.CurrentInfo);
}
[CLSCompliant(false)]
- public static ulong Parse(string s, IFormatProvider provider) {
+ public static ulong Parse(string s, IFormatProvider provider)
+ {
return Number.ParseUInt64(s, NumberStyles.Integer, NumberFormatInfo.GetInstance(provider));
}
[CLSCompliant(false)]
- public static ulong Parse(String s, NumberStyles style, IFormatProvider provider) {
+ public static ulong Parse(String s, NumberStyles style, IFormatProvider provider)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Number.ParseUInt64(s, style, NumberFormatInfo.GetInstance(provider));
}
[CLSCompliant(false)]
- public static Boolean TryParse(String s, out UInt64 result) {
+ public static Boolean TryParse(String s, out UInt64 result)
+ {
return Number.TryParseUInt64(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo, out result);
}
[CLSCompliant(false)]
- public static Boolean TryParse(String s, NumberStyles style, IFormatProvider provider, out UInt64 result) {
+ public static Boolean TryParse(String s, NumberStyles style, IFormatProvider provider, out UInt64 result)
+ {
NumberFormatInfo.ValidateParseStyleInteger(style);
return Number.TryParseUInt64(s, style, NumberFormatInfo.GetInstance(provider), out result);
}
@@ -130,84 +149,85 @@ namespace System {
//
// IConvertible implementation
//
-
- public TypeCode GetTypeCode() {
+
+ public TypeCode GetTypeCode()
+ {
return TypeCode.UInt64;
}
- /// <internalonly/>
- bool IConvertible.ToBoolean(IFormatProvider provider) {
+ bool IConvertible.ToBoolean(IFormatProvider provider)
+ {
return Convert.ToBoolean(m_value);
}
- /// <internalonly/>
- char IConvertible.ToChar(IFormatProvider provider) {
+ char IConvertible.ToChar(IFormatProvider provider)
+ {
return Convert.ToChar(m_value);
}
- /// <internalonly/>
- sbyte IConvertible.ToSByte(IFormatProvider provider) {
+ sbyte IConvertible.ToSByte(IFormatProvider provider)
+ {
return Convert.ToSByte(m_value);
}
- /// <internalonly/>
- byte IConvertible.ToByte(IFormatProvider provider) {
+ byte IConvertible.ToByte(IFormatProvider provider)
+ {
return Convert.ToByte(m_value);
}
- /// <internalonly/>
- short IConvertible.ToInt16(IFormatProvider provider) {
+ short IConvertible.ToInt16(IFormatProvider provider)
+ {
return Convert.ToInt16(m_value);
}
- /// <internalonly/>
- ushort IConvertible.ToUInt16(IFormatProvider provider) {
+ ushort IConvertible.ToUInt16(IFormatProvider provider)
+ {
return Convert.ToUInt16(m_value);
}
- /// <internalonly/>
- int IConvertible.ToInt32(IFormatProvider provider) {
+ int IConvertible.ToInt32(IFormatProvider provider)
+ {
return Convert.ToInt32(m_value);
}
- /// <internalonly/>
- uint IConvertible.ToUInt32(IFormatProvider provider) {
+ uint IConvertible.ToUInt32(IFormatProvider provider)
+ {
return Convert.ToUInt32(m_value);
}
- /// <internalonly/>
- long IConvertible.ToInt64(IFormatProvider provider) {
+ long IConvertible.ToInt64(IFormatProvider provider)
+ {
return Convert.ToInt64(m_value);
}
- /// <internalonly/>
- ulong IConvertible.ToUInt64(IFormatProvider provider) {
+ ulong IConvertible.ToUInt64(IFormatProvider provider)
+ {
return m_value;
}
- /// <internalonly/>
- float IConvertible.ToSingle(IFormatProvider provider) {
+ float IConvertible.ToSingle(IFormatProvider provider)
+ {
return Convert.ToSingle(m_value);
}
- /// <internalonly/>
- double IConvertible.ToDouble(IFormatProvider provider) {
+ double IConvertible.ToDouble(IFormatProvider provider)
+ {
return Convert.ToDouble(m_value);
}
- /// <internalonly/>
- Decimal IConvertible.ToDecimal(IFormatProvider provider) {
+ Decimal IConvertible.ToDecimal(IFormatProvider provider)
+ {
return Convert.ToDecimal(m_value);
}
- /// <internalonly/>
- DateTime IConvertible.ToDateTime(IFormatProvider provider) {
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_FromTo", "UInt64", "DateTime"));
+ DateTime IConvertible.ToDateTime(IFormatProvider provider)
+ {
+ throw new InvalidCastException(SR.Format(SR.InvalidCast_FromTo, "UInt64", "DateTime"));
}
- /// <internalonly/>
- Object IConvertible.ToType(Type type, IFormatProvider provider) {
- return Convert.DefaultToType((IConvertible)this, type, provider);
+ Object IConvertible.ToType(Type type, IFormatProvider provider)
+ {
+ return Convert.DefaultToType((IConvertible)this, type, provider);
}
}
}
diff --git a/src/mscorlib/src/System/UIntPtr.cs b/src/mscorlib/src/System/UIntPtr.cs
index d0f988dbb8..09b7e51e89 100644
--- a/src/mscorlib/src/System/UIntPtr.cs
+++ b/src/mscorlib/src/System/UIntPtr.cs
@@ -11,8 +11,8 @@
**
===========================================================*/
-namespace System {
-
+namespace System
+{
using System;
using System.Globalization;
using System.Runtime.Serialization;
@@ -20,25 +20,25 @@ namespace System {
using System.Diagnostics.Contracts;
[Serializable]
- [CLSCompliant(false)]
+ [CLSCompliant(false)]
public struct UIntPtr : IEquatable<UIntPtr>, ISerializable
{
unsafe private void* m_value;
public static readonly UIntPtr Zero;
-
+
[System.Runtime.Versioning.NonVersionable]
public unsafe UIntPtr(uint value)
{
- m_value = (void *)value;
+ m_value = (void*)value;
}
[System.Runtime.Versioning.NonVersionable]
public unsafe UIntPtr(ulong value)
{
#if BIT64
- m_value = (void *)value;
+ m_value = (void*)value;
#else // 32
m_value = (void*)checked((uint)value);
#endif
@@ -51,27 +51,32 @@ namespace System {
m_value = value;
}
- private unsafe UIntPtr(SerializationInfo info, StreamingContext context) {
+ private unsafe UIntPtr(SerializationInfo info, StreamingContext context)
+ {
ulong l = info.GetUInt64("value");
- if (Size==4 && l>UInt32.MaxValue) {
- throw new ArgumentException(Environment.GetResourceString("Serialization_InvalidPtrValue"));
+ if (Size == 4 && l > UInt32.MaxValue)
+ {
+ throw new ArgumentException(SR.Serialization_InvalidPtrValue);
}
- m_value = (void *)l;
+ m_value = (void*)l;
}
unsafe void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
- if (info==null) {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
info.AddValue("value", (ulong)m_value);
}
- public unsafe override bool Equals(Object obj) {
- if (obj is UIntPtr) {
+ public unsafe override bool Equals(Object obj)
+ {
+ if (obj is UIntPtr)
+ {
return (m_value == ((UIntPtr)obj).m_value);
}
return false;
@@ -81,8 +86,9 @@ namespace System {
{
return m_value == other.m_value;
}
-
- public unsafe override int GetHashCode() {
+
+ public unsafe override int GetHashCode()
+ {
#if BIT64
ulong l = (ulong)m_value;
return (unchecked((int)l) ^ (int)(l >> 32));
@@ -92,7 +98,8 @@ namespace System {
}
[System.Runtime.Versioning.NonVersionable]
- public unsafe uint ToUInt32() {
+ public unsafe uint ToUInt32()
+ {
#if BIT64
return checked((uint)m_value);
#else // 32
@@ -101,11 +108,13 @@ namespace System {
}
[System.Runtime.Versioning.NonVersionable]
- public unsafe ulong ToUInt64() {
+ public unsafe ulong ToUInt64()
+ {
return (ulong)m_value;
}
- public unsafe override String ToString() {
+ public unsafe override String ToString()
+ {
Contract.Ensures(Contract.Result<String>() != null);
#if BIT64
@@ -116,13 +125,13 @@ namespace System {
}
[System.Runtime.Versioning.NonVersionable]
- public static explicit operator UIntPtr (uint value)
+ public static explicit operator UIntPtr(uint value)
{
return new UIntPtr(value);
}
[System.Runtime.Versioning.NonVersionable]
- public static explicit operator UIntPtr (ulong value)
+ public static explicit operator UIntPtr(ulong value)
{
return new UIntPtr(value);
}
@@ -135,17 +144,17 @@ namespace System {
#else // 32
return (uint)value.m_value;
#endif
- }
+ }
[System.Runtime.Versioning.NonVersionable]
- public unsafe static explicit operator ulong (UIntPtr value)
+ public unsafe static explicit operator ulong(UIntPtr value)
{
return (ulong)value.m_value;
}
[CLSCompliant(false)]
[System.Runtime.Versioning.NonVersionable]
- public static unsafe explicit operator UIntPtr (void* value)
+ public static unsafe explicit operator UIntPtr(void* value)
{
return new UIntPtr(value);
}
@@ -159,41 +168,45 @@ namespace System {
[System.Runtime.Versioning.NonVersionable]
- public unsafe static bool operator == (UIntPtr value1, UIntPtr value2)
+ public unsafe static bool operator ==(UIntPtr value1, UIntPtr value2)
{
return value1.m_value == value2.m_value;
}
[System.Runtime.Versioning.NonVersionable]
- public unsafe static bool operator != (UIntPtr value1, UIntPtr value2)
+ public unsafe static bool operator !=(UIntPtr value1, UIntPtr value2)
{
return value1.m_value != value2.m_value;
}
[System.Runtime.Versioning.NonVersionable]
- public static UIntPtr Add(UIntPtr pointer, int offset) {
+ public static UIntPtr Add(UIntPtr pointer, int offset)
+ {
return pointer + offset;
}
[System.Runtime.Versioning.NonVersionable]
- public static UIntPtr operator +(UIntPtr pointer, int offset) {
+ public static UIntPtr operator +(UIntPtr pointer, int offset)
+ {
#if BIT64
- return new UIntPtr(pointer.ToUInt64() + (ulong)offset);
+ return new UIntPtr(pointer.ToUInt64() + (ulong)offset);
#else // 32
return new UIntPtr(pointer.ToUInt32() + (uint)offset);
#endif
}
[System.Runtime.Versioning.NonVersionable]
- public static UIntPtr Subtract(UIntPtr pointer, int offset) {
+ public static UIntPtr Subtract(UIntPtr pointer, int offset)
+ {
return pointer - offset;
}
[System.Runtime.Versioning.NonVersionable]
- public static UIntPtr operator -(UIntPtr pointer, int offset) {
+ public static UIntPtr operator -(UIntPtr pointer, int offset)
+ {
#if BIT64
- return new UIntPtr(pointer.ToUInt64() - (ulong)offset);
+ return new UIntPtr(pointer.ToUInt64() - (ulong)offset);
#else // 32
return new UIntPtr(pointer.ToUInt32() - (uint)offset);
#endif
@@ -211,15 +224,14 @@ namespace System {
#endif
}
}
-
+
[CLSCompliant(false)]
[System.Runtime.Versioning.NonVersionable]
public unsafe void* ToPointer()
{
return m_value;
}
-
- }
+ }
}
diff --git a/src/mscorlib/src/System/UnitySerializationHolder.cs b/src/mscorlib/src/System/UnitySerializationHolder.cs
deleted file mode 100644
index 712391a915..0000000000
--- a/src/mscorlib/src/System/UnitySerializationHolder.cs
+++ /dev/null
@@ -1,357 +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.Runtime.Remoting;
-using System.Runtime.Serialization;
-using System.Reflection;
-using System.Globalization;
-using System.Runtime.Versioning;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-
-namespace System {
-
- [Serializable]
- // Holds classes (Empty, Null, Missing) for which we guarantee that there is only ever one instance of.
- internal class UnitySerializationHolder : ISerializable, IObjectReference
- {
- #region Internal Constants
- internal const int EmptyUnity = 0x0001;
- internal const int NullUnity = 0x0002;
- internal const int MissingUnity = 0x0003;
- internal const int RuntimeTypeUnity = 0x0004;
- internal const int ModuleUnity = 0x0005;
- internal const int AssemblyUnity = 0x0006;
- internal const int GenericParameterTypeUnity = 0x0007;
- internal const int PartialInstantiationTypeUnity = 0x0008;
-
- internal const int Pointer = 0x0001;
- internal const int Array = 0x0002;
- internal const int SzArray = 0x0003;
- internal const int ByRef = 0x0004;
- #endregion
-
- #region Internal Static Members
- internal static void GetUnitySerializationInfo(SerializationInfo info, Missing missing)
- {
- info.SetType(typeof(UnitySerializationHolder));
- info.AddValue("UnityType", MissingUnity);
- }
-
- internal static RuntimeType AddElementTypes(SerializationInfo info, RuntimeType type)
- {
- List<int> elementTypes = new List<int>();
- while(type.HasElementType)
- {
- if (type.IsSzArray)
- {
- elementTypes.Add(SzArray);
- }
- else if (type.IsArray)
- {
- elementTypes.Add(type.GetArrayRank());
- elementTypes.Add(Array);
- }
- else if (type.IsPointer)
- {
- elementTypes.Add(Pointer);
- }
- else if (type.IsByRef)
- {
- elementTypes.Add(ByRef);
- }
-
- type = (RuntimeType)type.GetElementType();
- }
-
- info.AddValue("ElementTypes", elementTypes.ToArray(), typeof(int[]));
-
- return type;
- }
-
- internal Type MakeElementTypes(Type type)
- {
- for (int i = m_elementTypes.Length - 1; i >= 0; i --)
- {
- if (m_elementTypes[i] == SzArray)
- {
- type = type.MakeArrayType();
- }
- else if (m_elementTypes[i] == Array)
- {
- type = type.MakeArrayType(m_elementTypes[--i]);
- }
- else if ((m_elementTypes[i] == Pointer))
- {
- type = type.MakePointerType();
- }
- else if ((m_elementTypes[i] == ByRef))
- {
- type = type.MakeByRefType();
- }
- }
-
- return type;
- }
-
- internal static void GetUnitySerializationInfo(SerializationInfo info, RuntimeType type)
- {
- if (type.GetRootElementType().IsGenericParameter)
- {
- type = AddElementTypes(info, type);
- info.SetType(typeof(UnitySerializationHolder));
- info.AddValue("UnityType", GenericParameterTypeUnity);
- info.AddValue("GenericParameterPosition", type.GenericParameterPosition);
- info.AddValue("DeclaringMethod", type.DeclaringMethod, typeof(MethodBase));
- info.AddValue("DeclaringType", type.DeclaringType, typeof(Type));
-
- return;
- }
-
- int unityType = RuntimeTypeUnity;
-
- if (!type.IsGenericTypeDefinition && type.ContainsGenericParameters)
- {
- // Partial instantiation
- unityType = PartialInstantiationTypeUnity;
- type = AddElementTypes(info, type);
- info.AddValue("GenericArguments", type.GetGenericArguments(), typeof(Type[]));
- type = (RuntimeType)type.GetGenericTypeDefinition();
- }
-
- GetUnitySerializationInfo(info, unityType, type.FullName, type.GetRuntimeAssembly());
- }
-
- internal static void GetUnitySerializationInfo(
- SerializationInfo info, int unityType, String data, RuntimeAssembly assembly)
- {
- // A helper method that returns the SerializationInfo that a class utilizing
- // UnitySerializationHelper should return from a call to GetObjectData. It contains
- // the unityType (defined above) and any optional data (used only for the reflection
- // types.)
-
- info.SetType(typeof(UnitySerializationHolder));
- info.AddValue("Data", data, typeof(String));
- info.AddValue("UnityType", unityType);
-
- String assemName;
-
- if (assembly == null)
- {
- assemName = String.Empty;
- }
- else
- {
- assemName = assembly.FullName;
- }
-
- info.AddValue("AssemblyName", assemName);
- }
- #endregion
-
- #region Private Data Members
- private Type[] m_instantiation;
- private int[] m_elementTypes;
- private int m_genericParameterPosition;
- private Type m_declaringType;
- private MethodBase m_declaringMethod;
- private String m_data;
- private String m_assemblyName;
- private int m_unityType;
- #endregion
-
- #region Constructor
- internal UnitySerializationHolder(SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- throw new ArgumentNullException(nameof(info));
- Contract.EndContractBlock();
-
- m_unityType = info.GetInt32("UnityType");
-
- if (m_unityType == MissingUnity)
- return;
-
- if (m_unityType == GenericParameterTypeUnity)
- {
- m_declaringMethod = info.GetValue("DeclaringMethod", typeof(MethodBase)) as MethodBase;
- m_declaringType = info.GetValue("DeclaringType", typeof(Type)) as Type;
- m_genericParameterPosition = info.GetInt32("GenericParameterPosition");
- m_elementTypes = info.GetValue("ElementTypes", typeof(int[])) as int[];
-
- return;
- }
-
- if (m_unityType == PartialInstantiationTypeUnity)
- {
- m_instantiation = info.GetValue("GenericArguments", typeof(Type[])) as Type[];
- m_elementTypes = info.GetValue("ElementTypes", typeof(int[])) as int[];
- }
-
- m_data = info.GetString("Data");
- m_assemblyName = info.GetString("AssemblyName");
- }
- #endregion
-
- #region Private Methods
- private void ThrowInsufficientInformation(string field)
- {
- throw new SerializationException(
- Environment.GetResourceString("Serialization_InsufficientDeserializationState", field));
- }
- #endregion
-
- #region ISerializable
- public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
- {
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnitySerHolder"));
- }
- #endregion
-
- #region IObjectReference
- public virtual Object GetRealObject(StreamingContext context)
- {
- // GetRealObject uses the data we have in m_data and m_unityType to do a lookup on the correct
- // object to return. We have specific code here to handle the different types which we support.
- // The reflection types (Assembly, Module, and Type) have to be looked up through their static
- // accessors by name.
-
- Assembly assembly;
-
- switch (m_unityType)
- {
- case EmptyUnity:
- {
- return Empty.Value;
- }
-
- case NullUnity:
- {
- return DBNull.Value;
- }
-
- case MissingUnity:
- {
- return Missing.Value;
- }
-
- case PartialInstantiationTypeUnity:
- {
- m_unityType = RuntimeTypeUnity;
- Type definition = GetRealObject(context) as Type;
- m_unityType = PartialInstantiationTypeUnity;
-
- if (m_instantiation[0] == null)
- return null;
-
- return MakeElementTypes(definition.MakeGenericType(m_instantiation));
- }
-
- case GenericParameterTypeUnity:
- {
- if (m_declaringMethod == null && m_declaringType == null)
- ThrowInsufficientInformation("DeclaringMember");
-
- if (m_declaringMethod != null)
- return m_declaringMethod.GetGenericArguments()[m_genericParameterPosition];
-
- return MakeElementTypes(m_declaringType.GetGenericArguments()[m_genericParameterPosition]);
- }
-
- case RuntimeTypeUnity:
- {
- if (m_data == null || m_data.Length == 0)
- ThrowInsufficientInformation("Data");
-
- if (m_assemblyName == null)
- ThrowInsufficientInformation("AssemblyName");
-
- if (m_assemblyName.Length == 0)
- return Type.GetType(m_data, true, false);
-
- assembly = Assembly.Load(m_assemblyName);
-
- Type t = assembly.GetType(m_data, true, false);
-
- return t;
- }
-
- case ModuleUnity:
- {
- if (m_data == null || m_data.Length == 0)
- ThrowInsufficientInformation("Data");
-
- if (m_assemblyName == null)
- ThrowInsufficientInformation("AssemblyName");
-
- assembly = Assembly.Load(m_assemblyName);
-
- Module namedModule = assembly.GetModule(m_data);
-
- if (namedModule == null)
- throw new SerializationException(
- Environment.GetResourceString("Serialization_UnableToFindModule", m_data, m_assemblyName));
-
- return namedModule;
- }
-
- case AssemblyUnity:
- {
- if (m_data == null || m_data.Length == 0)
- ThrowInsufficientInformation("Data");
-
- if (m_assemblyName == null)
- ThrowInsufficientInformation("AssemblyName");
-
- assembly = Assembly.Load(m_assemblyName);
-
- return assembly;
- }
-
- default:
- throw new ArgumentException(Environment.GetResourceString("Argument_InvalidUnity"));
- }
- }
- #endregion
- }
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/mscorlib/src/System/ValueTuple.cs b/src/mscorlib/src/System/ValueTuple.cs
deleted file mode 100644
index 0f0863a2ed..0000000000
--- a/src/mscorlib/src/System/ValueTuple.cs
+++ /dev/null
@@ -1,2324 +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.Collections;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using System.Runtime.InteropServices;
-using System.Runtime.CompilerServices;
-using HashHelpers = System.Numerics.Hashing.HashHelpers;
-
-namespace System
-{
- /// <summary>
- /// Helper so we can call some tuple methods recursively without knowing the underlying types.
- /// </summary>
- internal interface IValueTupleInternal : ITuple
- {
- int GetHashCode(IEqualityComparer comparer);
- string ToStringEnd();
- }
-
- /// <summary>
- /// The ValueTuple types (from arity 0 to 8) comprise the runtime implementation that underlies tuples in C# and struct tuples in F#.
- /// Aside from created via language syntax, they are most easily created via the ValueTuple.Create factory methods.
- /// The System.ValueTuple types differ from the System.Tuple types in that:
- /// - they are structs rather than classes,
- /// - they are mutable rather than readonly, and
- /// - their members (such as Item1, Item2, etc) are fields rather than properties.
- /// </summary>
- [Serializable]
- public struct ValueTuple
- : IEquatable<ValueTuple>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple>, IValueTupleInternal, ITuple
- {
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple"/> instance is equal to a specified object.
- /// </summary>
- /// <param name="obj">The object to compare with this instance.</param>
- /// <returns><see langword="true"/> if <paramref name="obj"/> is a <see cref="ValueTuple"/>.</returns>
- public override bool Equals(object obj)
- {
- return obj is ValueTuple;
- }
-
- /// <summary>Returns a value indicating whether this instance is equal to a specified value.</summary>
- /// <param name="other">An instance to compare to this instance.</param>
- /// <returns>true if <paramref name="other"/> has the same value as this instance; otherwise, false.</returns>
- public bool Equals(ValueTuple other)
- {
- return true;
- }
-
- bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
- {
- return other is ValueTuple;
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- return 0;
- }
-
- /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
- /// <param name="other">An instance to compare.</param>
- /// <returns>
- /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
- /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
- /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
- /// than <paramref name="other"/>.
- /// </returns>
- public int CompareTo(ValueTuple other)
- {
- return 0;
- }
-
- int IStructuralComparable.CompareTo(object other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- return 0;
- }
-
- /// <summary>Returns the hash code for this instance.</summary>
- /// <returns>A 32-bit signed integer hash code.</returns>
- public override int GetHashCode()
- {
- return 0;
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return 0;
- }
-
- int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return 0;
- }
-
- /// <summary>
- /// Returns a string that represents the value of this <see cref="ValueTuple"/> instance.
- /// </summary>
- /// <returns>The string representation of this <see cref="ValueTuple"/> instance.</returns>
- /// <remarks>
- /// The string returned by this method takes the form <c>()</c>.
- /// </remarks>
- public override string ToString()
- {
- return "()";
- }
-
- string IValueTupleInternal.ToStringEnd()
- {
- return ")";
- }
-
- /// <summary>
- /// The number of positions in this data structure.
- /// </summary>
- int ITuple.Length => 0;
-
- /// <summary>
- /// Get the element at position <param name="index"/>.
- /// </summary>
- object ITuple.this[int index]
- {
- get
- {
- throw new IndexOutOfRangeException();
- }
- }
-
- /// <summary>Creates a new struct 0-tuple.</summary>
- /// <returns>A 0-tuple.</returns>
- public static ValueTuple Create() =>
- new ValueTuple();
-
- /// <summary>Creates a new struct 1-tuple, or singleton.</summary>
- /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
- /// <param name="item1">The value of the first component of the tuple.</param>
- /// <returns>A 1-tuple (singleton) whose value is (item1).</returns>
- public static ValueTuple<T1> Create<T1>(T1 item1) =>
- new ValueTuple<T1>(item1);
-
- /// <summary>Creates a new struct 2-tuple, or pair.</summary>
- /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
- /// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
- /// <param name="item1">The value of the first component of the tuple.</param>
- /// <param name="item2">The value of the second component of the tuple.</param>
- /// <returns>A 2-tuple (pair) whose value is (item1, item2).</returns>
- public static ValueTuple<T1, T2> Create<T1, T2>(T1 item1, T2 item2) =>
- new ValueTuple<T1, T2>(item1, item2);
-
- /// <summary>Creates a new struct 3-tuple, or triple.</summary>
- /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
- /// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
- /// <typeparam name="T3">The type of the third component of the tuple.</typeparam>
- /// <param name="item1">The value of the first component of the tuple.</param>
- /// <param name="item2">The value of the second component of the tuple.</param>
- /// <param name="item3">The value of the third component of the tuple.</param>
- /// <returns>A 3-tuple (triple) whose value is (item1, item2, item3).</returns>
- public static ValueTuple<T1, T2, T3> Create<T1, T2, T3>(T1 item1, T2 item2, T3 item3) =>
- new ValueTuple<T1, T2, T3>(item1, item2, item3);
-
- /// <summary>Creates a new struct 4-tuple, or quadruple.</summary>
- /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
- /// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
- /// <typeparam name="T3">The type of the third component of the tuple.</typeparam>
- /// <typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
- /// <param name="item1">The value of the first component of the tuple.</param>
- /// <param name="item2">The value of the second component of the tuple.</param>
- /// <param name="item3">The value of the third component of the tuple.</param>
- /// <param name="item4">The value of the fourth component of the tuple.</param>
- /// <returns>A 4-tuple (quadruple) whose value is (item1, item2, item3, item4).</returns>
- public static ValueTuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 item1, T2 item2, T3 item3, T4 item4) =>
- new ValueTuple<T1, T2, T3, T4>(item1, item2, item3, item4);
-
- /// <summary>Creates a new struct 5-tuple, or quintuple.</summary>
- /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
- /// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
- /// <typeparam name="T3">The type of the third component of the tuple.</typeparam>
- /// <typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
- /// <typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
- /// <param name="item1">The value of the first component of the tuple.</param>
- /// <param name="item2">The value of the second component of the tuple.</param>
- /// <param name="item3">The value of the third component of the tuple.</param>
- /// <param name="item4">The value of the fourth component of the tuple.</param>
- /// <param name="item5">The value of the fifth component of the tuple.</param>
- /// <returns>A 5-tuple (quintuple) whose value is (item1, item2, item3, item4, item5).</returns>
- public static ValueTuple<T1, T2, T3, T4, T5> Create<T1, T2, T3, T4, T5>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) =>
- new ValueTuple<T1, T2, T3, T4, T5>(item1, item2, item3, item4, item5);
-
- /// <summary>Creates a new struct 6-tuple, or sextuple.</summary>
- /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
- /// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
- /// <typeparam name="T3">The type of the third component of the tuple.</typeparam>
- /// <typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
- /// <typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
- /// <typeparam name="T6">The type of the sixth component of the tuple.</typeparam>
- /// <param name="item1">The value of the first component of the tuple.</param>
- /// <param name="item2">The value of the second component of the tuple.</param>
- /// <param name="item3">The value of the third component of the tuple.</param>
- /// <param name="item4">The value of the fourth component of the tuple.</param>
- /// <param name="item5">The value of the fifth component of the tuple.</param>
- /// <param name="item6">The value of the sixth component of the tuple.</param>
- /// <returns>A 6-tuple (sextuple) whose value is (item1, item2, item3, item4, item5, item6).</returns>
- public static ValueTuple<T1, T2, T3, T4, T5, T6> Create<T1, T2, T3, T4, T5, T6>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) =>
- new ValueTuple<T1, T2, T3, T4, T5, T6>(item1, item2, item3, item4, item5, item6);
-
- /// <summary>Creates a new struct 7-tuple, or septuple.</summary>
- /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
- /// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
- /// <typeparam name="T3">The type of the third component of the tuple.</typeparam>
- /// <typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
- /// <typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
- /// <typeparam name="T6">The type of the sixth component of the tuple.</typeparam>
- /// <typeparam name="T7">The type of the seventh component of the tuple.</typeparam>
- /// <param name="item1">The value of the first component of the tuple.</param>
- /// <param name="item2">The value of the second component of the tuple.</param>
- /// <param name="item3">The value of the third component of the tuple.</param>
- /// <param name="item4">The value of the fourth component of the tuple.</param>
- /// <param name="item5">The value of the fifth component of the tuple.</param>
- /// <param name="item6">The value of the sixth component of the tuple.</param>
- /// <param name="item7">The value of the seventh component of the tuple.</param>
- /// <returns>A 7-tuple (septuple) whose value is (item1, item2, item3, item4, item5, item6, item7).</returns>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7> Create<T1, T2, T3, T4, T5, T6, T7>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) =>
- new ValueTuple<T1, T2, T3, T4, T5, T6, T7>(item1, item2, item3, item4, item5, item6, item7);
-
- /// <summary>Creates a new struct 8-tuple, or octuple.</summary>
- /// <typeparam name="T1">The type of the first component of the tuple.</typeparam>
- /// <typeparam name="T2">The type of the second component of the tuple.</typeparam>
- /// <typeparam name="T3">The type of the third component of the tuple.</typeparam>
- /// <typeparam name="T4">The type of the fourth component of the tuple.</typeparam>
- /// <typeparam name="T5">The type of the fifth component of the tuple.</typeparam>
- /// <typeparam name="T6">The type of the sixth component of the tuple.</typeparam>
- /// <typeparam name="T7">The type of the seventh component of the tuple.</typeparam>
- /// <typeparam name="T8">The type of the eighth component of the tuple.</typeparam>
- /// <param name="item1">The value of the first component of the tuple.</param>
- /// <param name="item2">The value of the second component of the tuple.</param>
- /// <param name="item3">The value of the third component of the tuple.</param>
- /// <param name="item4">The value of the fourth component of the tuple.</param>
- /// <param name="item5">The value of the fifth component of the tuple.</param>
- /// <param name="item6">The value of the sixth component of the tuple.</param>
- /// <param name="item7">The value of the seventh component of the tuple.</param>
- /// <param name="item8">The value of the eighth component of the tuple.</param>
- /// <returns>An 8-tuple (octuple) whose value is (item1, item2, item3, item4, item5, item6, item7, item8).</returns>
- public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8>> Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) =>
- new ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8>>(item1, item2, item3, item4, item5, item6, item7, ValueTuple.Create(item8));
-
- internal static int CombineHashCodes(int h1, int h2)
- {
- return HashHelpers.Combine(HashHelpers.Combine(HashHelpers.RandomSeed, h1), h2);
- }
-
- internal static int CombineHashCodes(int h1, int h2, int h3)
- {
- return HashHelpers.Combine(CombineHashCodes(h1, h2), h3);
- }
-
- internal static int CombineHashCodes(int h1, int h2, int h3, int h4)
- {
- return HashHelpers.Combine(CombineHashCodes(h1, h2, h3), h4);
- }
-
- internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5)
- {
- return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4), h5);
- }
-
- internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6)
- {
- return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5), h6);
- }
-
- internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7)
- {
- return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6), h7);
- }
-
- internal static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8)
- {
- return HashHelpers.Combine(CombineHashCodes(h1, h2, h3, h4, h5, h6, h7), h8);
- }
- }
-
- /// <summary>Represents a 1-tuple, or singleton, as a value type.</summary>
- /// <typeparam name="T1">The type of the tuple's only component.</typeparam>
- [Serializable]
- public struct ValueTuple<T1>
- : IEquatable<ValueTuple<T1>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1>>, IValueTupleInternal, ITuple
- {
- /// <summary>
- /// The current <see cref="ValueTuple{T1}"/> instance's first component.
- /// </summary>
- public T1 Item1;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="ValueTuple{T1}"/> value type.
- /// </summary>
- /// <param name="item1">The value of the tuple's first component.</param>
- public ValueTuple(T1 item1)
- {
- Item1 = item1;
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1}"/> instance is equal to a specified object.
- /// </summary>
- /// <param name="obj">The object to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
- /// <remarks>
- /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
- /// <list type="bullet">
- /// <item><description>It is a <see cref="ValueTuple{T1}"/> value type.</description></item>
- /// <item><description>Its components are of the same types as those of the current instance.</description></item>
- /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
- /// </list>
- /// </remarks>
- public override bool Equals(object obj)
- {
- return obj is ValueTuple<T1> && Equals((ValueTuple<T1>)obj);
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1}"/>
- /// instance is equal to a specified <see cref="ValueTuple{T1}"/>.
- /// </summary>
- /// <param name="other">The tuple to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
- /// <remarks>
- /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its field
- /// is equal to that of the current instance, using the default comparer for that field's type.
- /// </remarks>
- public bool Equals(ValueTuple<T1> other)
- {
- return EqualityComparer<T1>.Default.Equals(Item1, other.Item1);
- }
-
- bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
- {
- if (other == null || !(other is ValueTuple<T1>)) return false;
-
- var objTuple = (ValueTuple<T1>)other;
-
- return comparer.Equals(Item1, objTuple.Item1);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- var objTuple = (ValueTuple<T1>)other;
-
- return Comparer<T1>.Default.Compare(Item1, objTuple.Item1);
- }
-
- /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
- /// <param name="other">An instance to compare.</param>
- /// <returns>
- /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
- /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
- /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
- /// than <paramref name="other"/>.
- /// </returns>
- public int CompareTo(ValueTuple<T1> other)
- {
- return Comparer<T1>.Default.Compare(Item1, other.Item1);
- }
-
- int IStructuralComparable.CompareTo(object other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- var objTuple = (ValueTuple<T1>)other;
-
- return comparer.Compare(Item1, objTuple.Item1);
- }
-
- /// <summary>
- /// Returns the hash code for the current <see cref="ValueTuple{T1}"/> instance.
- /// </summary>
- /// <returns>A 32-bit signed integer hash code.</returns>
- public override int GetHashCode()
- {
- return Item1?.GetHashCode() ?? 0;
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return comparer.GetHashCode(Item1);
- }
-
- int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return comparer.GetHashCode(Item1);
- }
-
- /// <summary>
- /// Returns a string that represents the value of this <see cref="ValueTuple{T1}"/> instance.
- /// </summary>
- /// <returns>The string representation of this <see cref="ValueTuple{T1}"/> instance.</returns>
- /// <remarks>
- /// The string returned by this method takes the form <c>(Item1)</c>,
- /// where <c>Item1</c> represents the value of <see cref="Item1"/>. If the field is <see langword="null"/>,
- /// it is represented as <see cref="string.Empty"/>.
- /// </remarks>
- public override string ToString()
- {
- return "(" + Item1?.ToString() + ")";
- }
-
- string IValueTupleInternal.ToStringEnd()
- {
- return Item1?.ToString() + ")";
- }
-
- /// <summary>
- /// The number of positions in this data structure.
- /// </summary>
- int ITuple.Length => 1;
-
- /// <summary>
- /// Get the element at position <param name="index"/>.
- /// </summary>
- object ITuple.this[int index]
- {
- get
- {
- if (index != 0)
- {
- throw new IndexOutOfRangeException();
- }
- return Item1;
- }
- }
- }
-
- /// <summary>
- /// Represents a 2-tuple, or pair, as a value type.
- /// </summary>
- /// <typeparam name="T1">The type of the tuple's first component.</typeparam>
- /// <typeparam name="T2">The type of the tuple's second component.</typeparam>
- [Serializable]
- [StructLayout(LayoutKind.Auto)]
- public struct ValueTuple<T1, T2>
- : IEquatable<ValueTuple<T1, T2>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2>>, IValueTupleInternal, ITuple
- {
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2}"/> instance's first component.
- /// </summary>
- public T1 Item1;
-
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2}"/> instance's first component.
- /// </summary>
- public T2 Item2;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="ValueTuple{T1, T2}"/> value type.
- /// </summary>
- /// <param name="item1">The value of the tuple's first component.</param>
- /// <param name="item2">The value of the tuple's second component.</param>
- public ValueTuple(T1 item1, T2 item2)
- {
- Item1 = item1;
- Item2 = item2;
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2}"/> instance is equal to a specified object.
- /// </summary>
- /// <param name="obj">The object to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
- ///
- /// <remarks>
- /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
- /// <list type="bullet">
- /// <item><description>It is a <see cref="ValueTuple{T1, T2}"/> value type.</description></item>
- /// <item><description>Its components are of the same types as those of the current instance.</description></item>
- /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
- /// </list>
- /// </remarks>
- public override bool Equals(object obj)
- {
- return obj is ValueTuple<T1, T2> && Equals((ValueTuple<T1, T2>)obj);
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2}"/> instance is equal to a specified <see cref="ValueTuple{T1, T2}"/>.
- /// </summary>
- /// <param name="other">The tuple to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
- /// <remarks>
- /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its fields
- /// are equal to that of the current instance, using the default comparer for that field's type.
- /// </remarks>
- public bool Equals(ValueTuple<T1, T2> other)
- {
- return EqualityComparer<T1>.Default.Equals(Item1, other.Item1)
- && EqualityComparer<T2>.Default.Equals(Item2, other.Item2);
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2}"/> instance is equal to a specified object based on a specified comparison method.
- /// </summary>
- /// <param name="other">The object to compare with this instance.</param>
- /// <param name="comparer">An object that defines the method to use to evaluate whether the two objects are equal.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
- ///
- /// <remarks>
- /// This member is an explicit interface member implementation. It can be used only when the
- /// <see cref="ValueTuple{T1, T2}"/> instance is cast to an <see cref="IStructuralEquatable"/> interface.
- ///
- /// The <see cref="IEqualityComparer.Equals"/> implementation is called only if <c>other</c> is not <see langword="null"/>,
- /// and if it can be successfully cast (in C#) or converted (in Visual Basic) to a <see cref="ValueTuple{T1, T2}"/>
- /// whose components are of the same types as those of the current instance. The IStructuralEquatable.Equals(Object, IEqualityComparer) method
- /// first passes the <see cref="Item1"/> values of the <see cref="ValueTuple{T1, T2}"/> objects to be compared to the
- /// <see cref="IEqualityComparer.Equals"/> implementation. If this method call returns <see langword="true"/>, the method is
- /// called again and passed the <see cref="Item2"/> values of the two <see cref="ValueTuple{T1, T2}"/> instances.
- /// </remarks>
- bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
- {
- if (other == null || !(other is ValueTuple<T1, T2>)) return false;
-
- var objTuple = (ValueTuple<T1, T2>)other;
-
- return comparer.Equals(Item1, objTuple.Item1)
- && comparer.Equals(Item2, objTuple.Item2);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1, T2>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- return CompareTo((ValueTuple<T1, T2>)other);
- }
-
- /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
- /// <param name="other">An instance to compare.</param>
- /// <returns>
- /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
- /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
- /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
- /// than <paramref name="other"/>.
- /// </returns>
- public int CompareTo(ValueTuple<T1, T2> other)
- {
- int c = Comparer<T1>.Default.Compare(Item1, other.Item1);
- if (c != 0) return c;
-
- return Comparer<T2>.Default.Compare(Item2, other.Item2);
- }
-
- int IStructuralComparable.CompareTo(object other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1, T2>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- var objTuple = (ValueTuple<T1, T2>)other;
-
- int c = comparer.Compare(Item1, objTuple.Item1);
- if (c != 0) return c;
-
- return comparer.Compare(Item2, objTuple.Item2);
- }
-
- /// <summary>
- /// Returns the hash code for the current <see cref="ValueTuple{T1, T2}"/> instance.
- /// </summary>
- /// <returns>A 32-bit signed integer hash code.</returns>
- public override int GetHashCode()
- {
- return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
- Item2?.GetHashCode() ?? 0);
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- private int GetHashCodeCore(IEqualityComparer comparer)
- {
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
- comparer.GetHashCode(Item2));
- }
-
- int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- /// <summary>
- /// Returns a string that represents the value of this <see cref="ValueTuple{T1, T2}"/> instance.
- /// </summary>
- /// <returns>The string representation of this <see cref="ValueTuple{T1, T2}"/> instance.</returns>
- /// <remarks>
- /// The string returned by this method takes the form <c>(Item1, Item2)</c>,
- /// where <c>Item1</c> and <c>Item2</c> represent the values of the <see cref="Item1"/>
- /// and <see cref="Item2"/> fields. If either field value is <see langword="null"/>,
- /// it is represented as <see cref="String.Empty"/>.
- /// </remarks>
- public override string ToString()
- {
- return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ")";
- }
-
- string IValueTupleInternal.ToStringEnd()
- {
- return Item1?.ToString() + ", " + Item2?.ToString() + ")";
- }
-
- /// <summary>
- /// The number of positions in this data structure.
- /// </summary>
- int ITuple.Length => 2;
-
- /// <summary>
- /// Get the element at position <param name="index"/>.
- /// </summary>
- object ITuple.this[int index]
- {
- get
- {
- switch (index)
- {
- case 0:
- return Item1;
- case 1:
- return Item2;
- default:
- throw new IndexOutOfRangeException();
- }
- }
- }
- }
-
- /// <summary>
- /// Represents a 3-tuple, or triple, as a value type.
- /// </summary>
- /// <typeparam name="T1">The type of the tuple's first component.</typeparam>
- /// <typeparam name="T2">The type of the tuple's second component.</typeparam>
- /// <typeparam name="T3">The type of the tuple's third component.</typeparam>
- [Serializable]
- [StructLayout(LayoutKind.Auto)]
- public struct ValueTuple<T1, T2, T3>
- : IEquatable<ValueTuple<T1, T2, T3>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2, T3>>, IValueTupleInternal, ITuple
- {
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3}"/> instance's first component.
- /// </summary>
- public T1 Item1;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3}"/> instance's second component.
- /// </summary>
- public T2 Item2;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3}"/> instance's third component.
- /// </summary>
- public T3 Item3;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="ValueTuple{T1, T2, T3}"/> value type.
- /// </summary>
- /// <param name="item1">The value of the tuple's first component.</param>
- /// <param name="item2">The value of the tuple's second component.</param>
- /// <param name="item3">The value of the tuple's third component.</param>
- public ValueTuple(T1 item1, T2 item2, T3 item3)
- {
- Item1 = item1;
- Item2 = item2;
- Item3 = item3;
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3}"/> instance is equal to a specified object.
- /// </summary>
- /// <param name="obj">The object to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
- /// <remarks>
- /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
- /// <list type="bullet">
- /// <item><description>It is a <see cref="ValueTuple{T1, T2, T3}"/> value type.</description></item>
- /// <item><description>Its components are of the same types as those of the current instance.</description></item>
- /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
- /// </list>
- /// </remarks>
- public override bool Equals(object obj)
- {
- return obj is ValueTuple<T1, T2, T3> && Equals((ValueTuple<T1, T2, T3>)obj);
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3}"/>
- /// instance is equal to a specified <see cref="ValueTuple{T1, T2, T3}"/>.
- /// </summary>
- /// <param name="other">The tuple to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
- /// <remarks>
- /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its fields
- /// are equal to that of the current instance, using the default comparer for that field's type.
- /// </remarks>
- public bool Equals(ValueTuple<T1, T2, T3> other)
- {
- return EqualityComparer<T1>.Default.Equals(Item1, other.Item1)
- && EqualityComparer<T2>.Default.Equals(Item2, other.Item2)
- && EqualityComparer<T3>.Default.Equals(Item3, other.Item3);
- }
-
- bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
- {
- if (other == null || !(other is ValueTuple<T1, T2, T3>)) return false;
-
- var objTuple = (ValueTuple<T1, T2, T3>)other;
-
- return comparer.Equals(Item1, objTuple.Item1)
- && comparer.Equals(Item2, objTuple.Item2)
- && comparer.Equals(Item3, objTuple.Item3);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1, T2, T3>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- return CompareTo((ValueTuple<T1, T2, T3>)other);
- }
-
- /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
- /// <param name="other">An instance to compare.</param>
- /// <returns>
- /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
- /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
- /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
- /// than <paramref name="other"/>.
- /// </returns>
- public int CompareTo(ValueTuple<T1, T2, T3> other)
- {
- int c = Comparer<T1>.Default.Compare(Item1, other.Item1);
- if (c != 0) return c;
-
- c = Comparer<T2>.Default.Compare(Item2, other.Item2);
- if (c != 0) return c;
-
- return Comparer<T3>.Default.Compare(Item3, other.Item3);
- }
-
- int IStructuralComparable.CompareTo(object other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1, T2, T3>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- var objTuple = (ValueTuple<T1, T2, T3>)other;
-
- int c = comparer.Compare(Item1, objTuple.Item1);
- if (c != 0) return c;
-
- c = comparer.Compare(Item2, objTuple.Item2);
- if (c != 0) return c;
-
- return comparer.Compare(Item3, objTuple.Item3);
- }
-
- /// <summary>
- /// Returns the hash code for the current <see cref="ValueTuple{T1, T2, T3}"/> instance.
- /// </summary>
- /// <returns>A 32-bit signed integer hash code.</returns>
- public override int GetHashCode()
- {
- return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
- Item2?.GetHashCode() ?? 0,
- Item3?.GetHashCode() ?? 0);
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- private int GetHashCodeCore(IEqualityComparer comparer)
- {
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
- comparer.GetHashCode(Item2),
- comparer.GetHashCode(Item3));
- }
-
- int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- /// <summary>
- /// Returns a string that represents the value of this <see cref="ValueTuple{T1, T2, T3}"/> instance.
- /// </summary>
- /// <returns>The string representation of this <see cref="ValueTuple{T1, T2, T3}"/> instance.</returns>
- /// <remarks>
- /// The string returned by this method takes the form <c>(Item1, Item2, Item3)</c>.
- /// If any field value is <see langword="null"/>, it is represented as <see cref="String.Empty"/>.
- /// </remarks>
- public override string ToString()
- {
- return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")";
- }
-
- string IValueTupleInternal.ToStringEnd()
- {
- return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ")";
- }
-
- /// <summary>
- /// The number of positions in this data structure.
- /// </summary>
- int ITuple.Length => 3;
-
- /// <summary>
- /// Get the element at position <param name="index"/>.
- /// </summary>
- object ITuple.this[int index]
- {
- get
- {
- switch (index)
- {
- case 0:
- return Item1;
- case 1:
- return Item2;
- case 2:
- return Item3;
- default:
- throw new IndexOutOfRangeException();
- }
- }
- }
- }
-
- /// <summary>
- /// Represents a 4-tuple, or quadruple, as a value type.
- /// </summary>
- /// <typeparam name="T1">The type of the tuple's first component.</typeparam>
- /// <typeparam name="T2">The type of the tuple's second component.</typeparam>
- /// <typeparam name="T3">The type of the tuple's third component.</typeparam>
- /// <typeparam name="T4">The type of the tuple's fourth component.</typeparam>
- [Serializable]
- [StructLayout(LayoutKind.Auto)]
- public struct ValueTuple<T1, T2, T3, T4>
- : IEquatable<ValueTuple<T1, T2, T3, T4>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2, T3, T4>>, IValueTupleInternal, ITuple
- {
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4}"/> instance's first component.
- /// </summary>
- public T1 Item1;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4}"/> instance's second component.
- /// </summary>
- public T2 Item2;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4}"/> instance's third component.
- /// </summary>
- public T3 Item3;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4}"/> instance's fourth component.
- /// </summary>
- public T4 Item4;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="ValueTuple{T1, T2, T3, T4}"/> value type.
- /// </summary>
- /// <param name="item1">The value of the tuple's first component.</param>
- /// <param name="item2">The value of the tuple's second component.</param>
- /// <param name="item3">The value of the tuple's third component.</param>
- /// <param name="item4">The value of the tuple's fourth component.</param>
- public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4)
- {
- Item1 = item1;
- Item2 = item2;
- Item3 = item3;
- Item4 = item4;
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4}"/> instance is equal to a specified object.
- /// </summary>
- /// <param name="obj">The object to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
- /// <remarks>
- /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
- /// <list type="bullet">
- /// <item><description>It is a <see cref="ValueTuple{T1, T2, T3, T4}"/> value type.</description></item>
- /// <item><description>Its components are of the same types as those of the current instance.</description></item>
- /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
- /// </list>
- /// </remarks>
- public override bool Equals(object obj)
- {
- return obj is ValueTuple<T1, T2, T3, T4> && Equals((ValueTuple<T1, T2, T3, T4>)obj);
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4}"/>
- /// instance is equal to a specified <see cref="ValueTuple{T1, T2, T3, T4}"/>.
- /// </summary>
- /// <param name="other">The tuple to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
- /// <remarks>
- /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its fields
- /// are equal to that of the current instance, using the default comparer for that field's type.
- /// </remarks>
- public bool Equals(ValueTuple<T1, T2, T3, T4> other)
- {
- return EqualityComparer<T1>.Default.Equals(Item1, other.Item1)
- && EqualityComparer<T2>.Default.Equals(Item2, other.Item2)
- && EqualityComparer<T3>.Default.Equals(Item3, other.Item3)
- && EqualityComparer<T4>.Default.Equals(Item4, other.Item4);
- }
-
- bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
- {
- if (other == null || !(other is ValueTuple<T1, T2, T3, T4>)) return false;
-
- var objTuple = (ValueTuple<T1, T2, T3, T4>)other;
-
- return comparer.Equals(Item1, objTuple.Item1)
- && comparer.Equals(Item2, objTuple.Item2)
- && comparer.Equals(Item3, objTuple.Item3)
- && comparer.Equals(Item4, objTuple.Item4);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1, T2, T3, T4>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- return CompareTo((ValueTuple<T1, T2, T3, T4>)other);
- }
-
- /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
- /// <param name="other">An instance to compare.</param>
- /// <returns>
- /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
- /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
- /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
- /// than <paramref name="other"/>.
- /// </returns>
- public int CompareTo(ValueTuple<T1, T2, T3, T4> other)
- {
- int c = Comparer<T1>.Default.Compare(Item1, other.Item1);
- if (c != 0) return c;
-
- c = Comparer<T2>.Default.Compare(Item2, other.Item2);
- if (c != 0) return c;
-
- c = Comparer<T3>.Default.Compare(Item3, other.Item3);
- if (c != 0) return c;
-
- return Comparer<T4>.Default.Compare(Item4, other.Item4);
- }
-
- int IStructuralComparable.CompareTo(object other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1, T2, T3, T4>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- var objTuple = (ValueTuple<T1, T2, T3, T4>)other;
-
- int c = comparer.Compare(Item1, objTuple.Item1);
- if (c != 0) return c;
-
- c = comparer.Compare(Item2, objTuple.Item2);
- if (c != 0) return c;
-
- c = comparer.Compare(Item3, objTuple.Item3);
- if (c != 0) return c;
-
- return comparer.Compare(Item4, objTuple.Item4);
- }
-
- /// <summary>
- /// Returns the hash code for the current <see cref="ValueTuple{T1, T2, T3, T4}"/> instance.
- /// </summary>
- /// <returns>A 32-bit signed integer hash code.</returns>
- public override int GetHashCode()
- {
- return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
- Item2?.GetHashCode() ?? 0,
- Item3?.GetHashCode() ?? 0,
- Item4?.GetHashCode() ?? 0);
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- private int GetHashCodeCore(IEqualityComparer comparer)
- {
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
- comparer.GetHashCode(Item2),
- comparer.GetHashCode(Item3),
- comparer.GetHashCode(Item4));
- }
-
- int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- /// <summary>
- /// Returns a string that represents the value of this <see cref="ValueTuple{T1, T2, T3, T4}"/> instance.
- /// </summary>
- /// <returns>The string representation of this <see cref="ValueTuple{T1, T2, T3, T4}"/> instance.</returns>
- /// <remarks>
- /// The string returned by this method takes the form <c>(Item1, Item2, Item3, Item4)</c>.
- /// If any field value is <see langword="null"/>, it is represented as <see cref="String.Empty"/>.
- /// </remarks>
- public override string ToString()
- {
- return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")";
- }
-
- string IValueTupleInternal.ToStringEnd()
- {
- return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ")";
- }
-
- /// <summary>
- /// The number of positions in this data structure.
- /// </summary>
- int ITuple.Length => 4;
-
- /// <summary>
- /// Get the element at position <param name="index"/>.
- /// </summary>
- object ITuple.this[int index]
- {
- get
- {
- switch (index)
- {
- case 0:
- return Item1;
- case 1:
- return Item2;
- case 2:
- return Item3;
- case 3:
- return Item4;
- default:
- throw new IndexOutOfRangeException();
- }
- }
- }
- }
-
- /// <summary>
- /// Represents a 5-tuple, or quintuple, as a value type.
- /// </summary>
- /// <typeparam name="T1">The type of the tuple's first component.</typeparam>
- /// <typeparam name="T2">The type of the tuple's second component.</typeparam>
- /// <typeparam name="T3">The type of the tuple's third component.</typeparam>
- /// <typeparam name="T4">The type of the tuple's fourth component.</typeparam>
- /// <typeparam name="T5">The type of the tuple's fifth component.</typeparam>
- [Serializable]
- [StructLayout(LayoutKind.Auto)]
- public struct ValueTuple<T1, T2, T3, T4, T5>
- : IEquatable<ValueTuple<T1, T2, T3, T4, T5>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2, T3, T4, T5>>, IValueTupleInternal, ITuple
- {
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance's first component.
- /// </summary>
- public T1 Item1;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance's second component.
- /// </summary>
- public T2 Item2;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance's third component.
- /// </summary>
- public T3 Item3;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance's fourth component.
- /// </summary>
- public T4 Item4;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance's fifth component.
- /// </summary>
- public T5 Item5;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> value type.
- /// </summary>
- /// <param name="item1">The value of the tuple's first component.</param>
- /// <param name="item2">The value of the tuple's second component.</param>
- /// <param name="item3">The value of the tuple's third component.</param>
- /// <param name="item4">The value of the tuple's fourth component.</param>
- /// <param name="item5">The value of the tuple's fifth component.</param>
- public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
- {
- Item1 = item1;
- Item2 = item2;
- Item3 = item3;
- Item4 = item4;
- Item5 = item5;
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance is equal to a specified object.
- /// </summary>
- /// <param name="obj">The object to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
- /// <remarks>
- /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
- /// <list type="bullet">
- /// <item><description>It is a <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> value type.</description></item>
- /// <item><description>Its components are of the same types as those of the current instance.</description></item>
- /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
- /// </list>
- /// </remarks>
- public override bool Equals(object obj)
- {
- return obj is ValueTuple<T1, T2, T3, T4, T5> && Equals((ValueTuple<T1, T2, T3, T4, T5>)obj);
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/>
- /// instance is equal to a specified <see cref="ValueTuple{T1, T2, T3, T4, T5}"/>.
- /// </summary>
- /// <param name="other">The tuple to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
- /// <remarks>
- /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its fields
- /// are equal to that of the current instance, using the default comparer for that field's type.
- /// </remarks>
- public bool Equals(ValueTuple<T1, T2, T3, T4, T5> other)
- {
- return EqualityComparer<T1>.Default.Equals(Item1, other.Item1)
- && EqualityComparer<T2>.Default.Equals(Item2, other.Item2)
- && EqualityComparer<T3>.Default.Equals(Item3, other.Item3)
- && EqualityComparer<T4>.Default.Equals(Item4, other.Item4)
- && EqualityComparer<T5>.Default.Equals(Item5, other.Item5);
- }
-
- bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
- {
- if (other == null || !(other is ValueTuple<T1, T2, T3, T4, T5>)) return false;
-
- var objTuple = (ValueTuple<T1, T2, T3, T4, T5>)other;
-
- return comparer.Equals(Item1, objTuple.Item1)
- && comparer.Equals(Item2, objTuple.Item2)
- && comparer.Equals(Item3, objTuple.Item3)
- && comparer.Equals(Item4, objTuple.Item4)
- && comparer.Equals(Item5, objTuple.Item5);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1, T2, T3, T4, T5>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- return CompareTo((ValueTuple<T1, T2, T3, T4, T5>)other);
- }
-
- /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
- /// <param name="other">An instance to compare.</param>
- /// <returns>
- /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
- /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
- /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
- /// than <paramref name="other"/>.
- /// </returns>
- public int CompareTo(ValueTuple<T1, T2, T3, T4, T5> other)
- {
- int c = Comparer<T1>.Default.Compare(Item1, other.Item1);
- if (c != 0) return c;
-
- c = Comparer<T2>.Default.Compare(Item2, other.Item2);
- if (c != 0) return c;
-
- c = Comparer<T3>.Default.Compare(Item3, other.Item3);
- if (c != 0) return c;
-
- c = Comparer<T4>.Default.Compare(Item4, other.Item4);
- if (c != 0) return c;
-
- return Comparer<T5>.Default.Compare(Item5, other.Item5);
- }
-
- int IStructuralComparable.CompareTo(object other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1, T2, T3, T4, T5>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- var objTuple = (ValueTuple<T1, T2, T3, T4, T5>)other;
-
- int c = comparer.Compare(Item1, objTuple.Item1);
- if (c != 0) return c;
-
- c = comparer.Compare(Item2, objTuple.Item2);
- if (c != 0) return c;
-
- c = comparer.Compare(Item3, objTuple.Item3);
- if (c != 0) return c;
-
- c = comparer.Compare(Item4, objTuple.Item4);
- if (c != 0) return c;
-
- return comparer.Compare(Item5, objTuple.Item5);
- }
-
- /// <summary>
- /// Returns the hash code for the current <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance.
- /// </summary>
- /// <returns>A 32-bit signed integer hash code.</returns>
- public override int GetHashCode()
- {
- return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
- Item2?.GetHashCode() ?? 0,
- Item3?.GetHashCode() ?? 0,
- Item4?.GetHashCode() ?? 0,
- Item5?.GetHashCode() ?? 0);
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- private int GetHashCodeCore(IEqualityComparer comparer)
- {
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
- comparer.GetHashCode(Item2),
- comparer.GetHashCode(Item3),
- comparer.GetHashCode(Item4),
- comparer.GetHashCode(Item5));
- }
-
- int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- /// <summary>
- /// Returns a string that represents the value of this <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance.
- /// </summary>
- /// <returns>The string representation of this <see cref="ValueTuple{T1, T2, T3, T4, T5}"/> instance.</returns>
- /// <remarks>
- /// The string returned by this method takes the form <c>(Item1, Item2, Item3, Item4, Item5)</c>.
- /// If any field value is <see langword="null"/>, it is represented as <see cref="String.Empty"/>.
- /// </remarks>
- public override string ToString()
- {
- return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")";
- }
-
- string IValueTupleInternal.ToStringEnd()
- {
- return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ")";
- }
-
- /// <summary>
- /// The number of positions in this data structure.
- /// </summary>
- int ITuple.Length => 5;
-
- /// <summary>
- /// Get the element at position <param name="index"/>.
- /// </summary>
- object ITuple.this[int index]
- {
- get
- {
- switch (index)
- {
- case 0:
- return Item1;
- case 1:
- return Item2;
- case 2:
- return Item3;
- case 3:
- return Item4;
- case 4:
- return Item5;
- default:
- throw new IndexOutOfRangeException();
- }
- }
- }
- }
-
- /// <summary>
- /// Represents a 6-tuple, or sixtuple, as a value type.
- /// </summary>
- /// <typeparam name="T1">The type of the tuple's first component.</typeparam>
- /// <typeparam name="T2">The type of the tuple's second component.</typeparam>
- /// <typeparam name="T3">The type of the tuple's third component.</typeparam>
- /// <typeparam name="T4">The type of the tuple's fourth component.</typeparam>
- /// <typeparam name="T5">The type of the tuple's fifth component.</typeparam>
- /// <typeparam name="T6">The type of the tuple's sixth component.</typeparam>
- [Serializable]
- [StructLayout(LayoutKind.Auto)]
- public struct ValueTuple<T1, T2, T3, T4, T5, T6>
- : IEquatable<ValueTuple<T1, T2, T3, T4, T5, T6>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2, T3, T4, T5, T6>>, IValueTupleInternal, ITuple
- {
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance's first component.
- /// </summary>
- public T1 Item1;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance's second component.
- /// </summary>
- public T2 Item2;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance's third component.
- /// </summary>
- public T3 Item3;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance's fourth component.
- /// </summary>
- public T4 Item4;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance's fifth component.
- /// </summary>
- public T5 Item5;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance's sixth component.
- /// </summary>
- public T6 Item6;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> value type.
- /// </summary>
- /// <param name="item1">The value of the tuple's first component.</param>
- /// <param name="item2">The value of the tuple's second component.</param>
- /// <param name="item3">The value of the tuple's third component.</param>
- /// <param name="item4">The value of the tuple's fourth component.</param>
- /// <param name="item5">The value of the tuple's fifth component.</param>
- /// <param name="item6">The value of the tuple's sixth component.</param>
- public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
- {
- Item1 = item1;
- Item2 = item2;
- Item3 = item3;
- Item4 = item4;
- Item5 = item5;
- Item6 = item6;
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance is equal to a specified object.
- /// </summary>
- /// <param name="obj">The object to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
- /// <remarks>
- /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
- /// <list type="bullet">
- /// <item><description>It is a <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> value type.</description></item>
- /// <item><description>Its components are of the same types as those of the current instance.</description></item>
- /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
- /// </list>
- /// </remarks>
- public override bool Equals(object obj)
- {
- return obj is ValueTuple<T1, T2, T3, T4, T5, T6> && Equals((ValueTuple<T1, T2, T3, T4, T5, T6>)obj);
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/>
- /// instance is equal to a specified <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/>.
- /// </summary>
- /// <param name="other">The tuple to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
- /// <remarks>
- /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its fields
- /// are equal to that of the current instance, using the default comparer for that field's type.
- /// </remarks>
- public bool Equals(ValueTuple<T1, T2, T3, T4, T5, T6> other)
- {
- return EqualityComparer<T1>.Default.Equals(Item1, other.Item1)
- && EqualityComparer<T2>.Default.Equals(Item2, other.Item2)
- && EqualityComparer<T3>.Default.Equals(Item3, other.Item3)
- && EqualityComparer<T4>.Default.Equals(Item4, other.Item4)
- && EqualityComparer<T5>.Default.Equals(Item5, other.Item5)
- && EqualityComparer<T6>.Default.Equals(Item6, other.Item6);
- }
-
- bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
- {
- if (other == null || !(other is ValueTuple<T1, T2, T3, T4, T5, T6>)) return false;
-
- var objTuple = (ValueTuple<T1, T2, T3, T4, T5, T6>)other;
-
- return comparer.Equals(Item1, objTuple.Item1)
- && comparer.Equals(Item2, objTuple.Item2)
- && comparer.Equals(Item3, objTuple.Item3)
- && comparer.Equals(Item4, objTuple.Item4)
- && comparer.Equals(Item5, objTuple.Item5)
- && comparer.Equals(Item6, objTuple.Item6);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- return CompareTo((ValueTuple<T1, T2, T3, T4, T5, T6>)other);
- }
-
- /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
- /// <param name="other">An instance to compare.</param>
- /// <returns>
- /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
- /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
- /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
- /// than <paramref name="other"/>.
- /// </returns>
- public int CompareTo(ValueTuple<T1, T2, T3, T4, T5, T6> other)
- {
- int c = Comparer<T1>.Default.Compare(Item1, other.Item1);
- if (c != 0) return c;
-
- c = Comparer<T2>.Default.Compare(Item2, other.Item2);
- if (c != 0) return c;
-
- c = Comparer<T3>.Default.Compare(Item3, other.Item3);
- if (c != 0) return c;
-
- c = Comparer<T4>.Default.Compare(Item4, other.Item4);
- if (c != 0) return c;
-
- c = Comparer<T5>.Default.Compare(Item5, other.Item5);
- if (c != 0) return c;
-
- return Comparer<T6>.Default.Compare(Item6, other.Item6);
- }
-
- int IStructuralComparable.CompareTo(object other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- var objTuple = (ValueTuple<T1, T2, T3, T4, T5, T6>)other;
-
- int c = comparer.Compare(Item1, objTuple.Item1);
- if (c != 0) return c;
-
- c = comparer.Compare(Item2, objTuple.Item2);
- if (c != 0) return c;
-
- c = comparer.Compare(Item3, objTuple.Item3);
- if (c != 0) return c;
-
- c = comparer.Compare(Item4, objTuple.Item4);
- if (c != 0) return c;
-
- c = comparer.Compare(Item5, objTuple.Item5);
- if (c != 0) return c;
-
- return comparer.Compare(Item6, objTuple.Item6);
- }
-
- /// <summary>
- /// Returns the hash code for the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance.
- /// </summary>
- /// <returns>A 32-bit signed integer hash code.</returns>
- public override int GetHashCode()
- {
- return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
- Item2?.GetHashCode() ?? 0,
- Item3?.GetHashCode() ?? 0,
- Item4?.GetHashCode() ?? 0,
- Item5?.GetHashCode() ?? 0,
- Item6?.GetHashCode() ?? 0);
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- private int GetHashCodeCore(IEqualityComparer comparer)
- {
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
- comparer.GetHashCode(Item2),
- comparer.GetHashCode(Item3),
- comparer.GetHashCode(Item4),
- comparer.GetHashCode(Item5),
- comparer.GetHashCode(Item6));
- }
-
- int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- /// <summary>
- /// Returns a string that represents the value of this <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance.
- /// </summary>
- /// <returns>The string representation of this <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/> instance.</returns>
- /// <remarks>
- /// The string returned by this method takes the form <c>(Item1, Item2, Item3, Item4, Item5, Item6)</c>.
- /// If any field value is <see langword="null"/>, it is represented as <see cref="String.Empty"/>.
- /// </remarks>
- public override string ToString()
- {
- return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")";
- }
-
- string IValueTupleInternal.ToStringEnd()
- {
- return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ")";
- }
-
- /// <summary>
- /// The number of positions in this data structure.
- /// </summary>
- int ITuple.Length => 6;
-
- /// <summary>
- /// Get the element at position <param name="index"/>.
- /// </summary>
- object ITuple.this[int index]
- {
- get
- {
- switch (index)
- {
- case 0:
- return Item1;
- case 1:
- return Item2;
- case 2:
- return Item3;
- case 3:
- return Item4;
- case 4:
- return Item5;
- case 5:
- return Item6;
- default:
- throw new IndexOutOfRangeException();
- }
- }
- }
- }
-
- /// <summary>
- /// Represents a 7-tuple, or sentuple, as a value type.
- /// </summary>
- /// <typeparam name="T1">The type of the tuple's first component.</typeparam>
- /// <typeparam name="T2">The type of the tuple's second component.</typeparam>
- /// <typeparam name="T3">The type of the tuple's third component.</typeparam>
- /// <typeparam name="T4">The type of the tuple's fourth component.</typeparam>
- /// <typeparam name="T5">The type of the tuple's fifth component.</typeparam>
- /// <typeparam name="T6">The type of the tuple's sixth component.</typeparam>
- /// <typeparam name="T7">The type of the tuple's seventh component.</typeparam>
- [Serializable]
- [StructLayout(LayoutKind.Auto)]
- public struct ValueTuple<T1, T2, T3, T4, T5, T6, T7>
- : IEquatable<ValueTuple<T1, T2, T3, T4, T5, T6, T7>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2, T3, T4, T5, T6, T7>>, IValueTupleInternal, ITuple
- {
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance's first component.
- /// </summary>
- public T1 Item1;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance's second component.
- /// </summary>
- public T2 Item2;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance's third component.
- /// </summary>
- public T3 Item3;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance's fourth component.
- /// </summary>
- public T4 Item4;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance's fifth component.
- /// </summary>
- public T5 Item5;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance's sixth component.
- /// </summary>
- public T6 Item6;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance's seventh component.
- /// </summary>
- public T7 Item7;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> value type.
- /// </summary>
- /// <param name="item1">The value of the tuple's first component.</param>
- /// <param name="item2">The value of the tuple's second component.</param>
- /// <param name="item3">The value of the tuple's third component.</param>
- /// <param name="item4">The value of the tuple's fourth component.</param>
- /// <param name="item5">The value of the tuple's fifth component.</param>
- /// <param name="item6">The value of the tuple's sixth component.</param>
- /// <param name="item7">The value of the tuple's seventh component.</param>
- public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
- {
- Item1 = item1;
- Item2 = item2;
- Item3 = item3;
- Item4 = item4;
- Item5 = item5;
- Item6 = item6;
- Item7 = item7;
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance is equal to a specified object.
- /// </summary>
- /// <param name="obj">The object to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
- /// <remarks>
- /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
- /// <list type="bullet">
- /// <item><description>It is a <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> value type.</description></item>
- /// <item><description>Its components are of the same types as those of the current instance.</description></item>
- /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
- /// </list>
- /// </remarks>
- public override bool Equals(object obj)
- {
- return obj is ValueTuple<T1, T2, T3, T4, T5, T6, T7> && Equals((ValueTuple<T1, T2, T3, T4, T5, T6, T7>)obj);
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/>
- /// instance is equal to a specified <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/>.
- /// </summary>
- /// <param name="other">The tuple to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
- /// <remarks>
- /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its fields
- /// are equal to that of the current instance, using the default comparer for that field's type.
- /// </remarks>
- public bool Equals(ValueTuple<T1, T2, T3, T4, T5, T6, T7> other)
- {
- return EqualityComparer<T1>.Default.Equals(Item1, other.Item1)
- && EqualityComparer<T2>.Default.Equals(Item2, other.Item2)
- && EqualityComparer<T3>.Default.Equals(Item3, other.Item3)
- && EqualityComparer<T4>.Default.Equals(Item4, other.Item4)
- && EqualityComparer<T5>.Default.Equals(Item5, other.Item5)
- && EqualityComparer<T6>.Default.Equals(Item6, other.Item6)
- && EqualityComparer<T7>.Default.Equals(Item7, other.Item7);
- }
-
- bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
- {
- if (other == null || !(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7>)) return false;
-
- var objTuple = (ValueTuple<T1, T2, T3, T4, T5, T6, T7>)other;
-
- return comparer.Equals(Item1, objTuple.Item1)
- && comparer.Equals(Item2, objTuple.Item2)
- && comparer.Equals(Item3, objTuple.Item3)
- && comparer.Equals(Item4, objTuple.Item4)
- && comparer.Equals(Item5, objTuple.Item5)
- && comparer.Equals(Item6, objTuple.Item6)
- && comparer.Equals(Item7, objTuple.Item7);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- return CompareTo((ValueTuple<T1, T2, T3, T4, T5, T6, T7>)other);
- }
-
- /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
- /// <param name="other">An instance to compare.</param>
- /// <returns>
- /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
- /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
- /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
- /// than <paramref name="other"/>.
- /// </returns>
- public int CompareTo(ValueTuple<T1, T2, T3, T4, T5, T6, T7> other)
- {
- int c = Comparer<T1>.Default.Compare(Item1, other.Item1);
- if (c != 0) return c;
-
- c = Comparer<T2>.Default.Compare(Item2, other.Item2);
- if (c != 0) return c;
-
- c = Comparer<T3>.Default.Compare(Item3, other.Item3);
- if (c != 0) return c;
-
- c = Comparer<T4>.Default.Compare(Item4, other.Item4);
- if (c != 0) return c;
-
- c = Comparer<T5>.Default.Compare(Item5, other.Item5);
- if (c != 0) return c;
-
- c = Comparer<T6>.Default.Compare(Item6, other.Item6);
- if (c != 0) return c;
-
- return Comparer<T7>.Default.Compare(Item7, other.Item7);
- }
-
- int IStructuralComparable.CompareTo(object other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- var objTuple = (ValueTuple<T1, T2, T3, T4, T5, T6, T7>)other;
-
- int c = comparer.Compare(Item1, objTuple.Item1);
- if (c != 0) return c;
-
- c = comparer.Compare(Item2, objTuple.Item2);
- if (c != 0) return c;
-
- c = comparer.Compare(Item3, objTuple.Item3);
- if (c != 0) return c;
-
- c = comparer.Compare(Item4, objTuple.Item4);
- if (c != 0) return c;
-
- c = comparer.Compare(Item5, objTuple.Item5);
- if (c != 0) return c;
-
- c = comparer.Compare(Item6, objTuple.Item6);
- if (c != 0) return c;
-
- return comparer.Compare(Item7, objTuple.Item7);
- }
-
- /// <summary>
- /// Returns the hash code for the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance.
- /// </summary>
- /// <returns>A 32-bit signed integer hash code.</returns>
- public override int GetHashCode()
- {
- return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
- Item2?.GetHashCode() ?? 0,
- Item3?.GetHashCode() ?? 0,
- Item4?.GetHashCode() ?? 0,
- Item5?.GetHashCode() ?? 0,
- Item6?.GetHashCode() ?? 0,
- Item7?.GetHashCode() ?? 0);
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- private int GetHashCodeCore(IEqualityComparer comparer)
- {
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1),
- comparer.GetHashCode(Item2),
- comparer.GetHashCode(Item3),
- comparer.GetHashCode(Item4),
- comparer.GetHashCode(Item5),
- comparer.GetHashCode(Item6),
- comparer.GetHashCode(Item7));
- }
-
- int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- /// <summary>
- /// Returns a string that represents the value of this <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance.
- /// </summary>
- /// <returns>The string representation of this <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/> instance.</returns>
- /// <remarks>
- /// The string returned by this method takes the form <c>(Item1, Item2, Item3, Item4, Item5, Item6, Item7)</c>.
- /// If any field value is <see langword="null"/>, it is represented as <see cref="String.Empty"/>.
- /// </remarks>
- public override string ToString()
- {
- return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")";
- }
-
- string IValueTupleInternal.ToStringEnd()
- {
- return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ")";
- }
-
- /// <summary>
- /// The number of positions in this data structure.
- /// </summary>
- int ITuple.Length => 7;
-
- /// <summary>
- /// Get the element at position <param name="index"/>.
- /// </summary>
- object ITuple.this[int index]
- {
- get
- {
- switch (index)
- {
- case 0:
- return Item1;
- case 1:
- return Item2;
- case 2:
- return Item3;
- case 3:
- return Item4;
- case 4:
- return Item5;
- case 5:
- return Item6;
- case 6:
- return Item7;
- default:
- throw new IndexOutOfRangeException();
- }
- }
- }
- }
-
- /// <summary>
- /// Represents an 8-tuple, or octuple, as a value type.
- /// </summary>
- /// <typeparam name="T1">The type of the tuple's first component.</typeparam>
- /// <typeparam name="T2">The type of the tuple's second component.</typeparam>
- /// <typeparam name="T3">The type of the tuple's third component.</typeparam>
- /// <typeparam name="T4">The type of the tuple's fourth component.</typeparam>
- /// <typeparam name="T5">The type of the tuple's fifth component.</typeparam>
- /// <typeparam name="T6">The type of the tuple's sixth component.</typeparam>
- /// <typeparam name="T7">The type of the tuple's seventh component.</typeparam>
- /// <typeparam name="TRest">The type of the tuple's eighth component.</typeparam>
- [Serializable]
- [StructLayout(LayoutKind.Auto)]
- public struct ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>
- : IEquatable<ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>>, IStructuralEquatable, IStructuralComparable, IComparable, IComparable<ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>>, IValueTupleInternal, ITuple
- where TRest : struct
- {
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's first component.
- /// </summary>
- public T1 Item1;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's second component.
- /// </summary>
- public T2 Item2;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's third component.
- /// </summary>
- public T3 Item3;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's fourth component.
- /// </summary>
- public T4 Item4;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's fifth component.
- /// </summary>
- public T5 Item5;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's sixth component.
- /// </summary>
- public T6 Item6;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's seventh component.
- /// </summary>
- public T7 Item7;
- /// <summary>
- /// The current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance's eighth component.
- /// </summary>
- public TRest Rest;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> value type.
- /// </summary>
- /// <param name="item1">The value of the tuple's first component.</param>
- /// <param name="item2">The value of the tuple's second component.</param>
- /// <param name="item3">The value of the tuple's third component.</param>
- /// <param name="item4">The value of the tuple's fourth component.</param>
- /// <param name="item5">The value of the tuple's fifth component.</param>
- /// <param name="item6">The value of the tuple's sixth component.</param>
- /// <param name="item7">The value of the tuple's seventh component.</param>
- /// <param name="rest">The value of the tuple's eight component.</param>
- public ValueTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, TRest rest)
- {
- if (!(rest is IValueTupleInternal))
- {
- throw new ArgumentException(SR.ArgumentException_ValueTupleLastArgumentNotATuple);
- }
-
- Item1 = item1;
- Item2 = item2;
- Item3 = item3;
- Item4 = item4;
- Item5 = item5;
- Item6 = item6;
- Item7 = item7;
- Rest = rest;
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance is equal to a specified object.
- /// </summary>
- /// <param name="obj">The object to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified object; otherwise, <see langword="false"/>.</returns>
- /// <remarks>
- /// The <paramref name="obj"/> parameter is considered to be equal to the current instance under the following conditions:
- /// <list type="bullet">
- /// <item><description>It is a <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> value type.</description></item>
- /// <item><description>Its components are of the same types as those of the current instance.</description></item>
- /// <item><description>Its components are equal to those of the current instance. Equality is determined by the default object equality comparer for each component.</description></item>
- /// </list>
- /// </remarks>
- public override bool Equals(object obj)
- {
- return obj is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> && Equals((ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)obj);
- }
-
- /// <summary>
- /// Returns a value that indicates whether the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/>
- /// instance is equal to a specified <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/>.
- /// </summary>
- /// <param name="other">The tuple to compare with this instance.</param>
- /// <returns><see langword="true"/> if the current instance is equal to the specified tuple; otherwise, <see langword="false"/>.</returns>
- /// <remarks>
- /// The <paramref name="other"/> parameter is considered to be equal to the current instance if each of its fields
- /// are equal to that of the current instance, using the default comparer for that field's type.
- /// </remarks>
- public bool Equals(ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> other)
- {
- return EqualityComparer<T1>.Default.Equals(Item1, other.Item1)
- && EqualityComparer<T2>.Default.Equals(Item2, other.Item2)
- && EqualityComparer<T3>.Default.Equals(Item3, other.Item3)
- && EqualityComparer<T4>.Default.Equals(Item4, other.Item4)
- && EqualityComparer<T5>.Default.Equals(Item5, other.Item5)
- && EqualityComparer<T6>.Default.Equals(Item6, other.Item6)
- && EqualityComparer<T7>.Default.Equals(Item7, other.Item7)
- && EqualityComparer<TRest>.Default.Equals(Rest, other.Rest);
- }
-
- bool IStructuralEquatable.Equals(object other, IEqualityComparer comparer)
- {
- if (other == null || !(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)) return false;
-
- var objTuple = (ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)other;
-
- return comparer.Equals(Item1, objTuple.Item1)
- && comparer.Equals(Item2, objTuple.Item2)
- && comparer.Equals(Item3, objTuple.Item3)
- && comparer.Equals(Item4, objTuple.Item4)
- && comparer.Equals(Item5, objTuple.Item5)
- && comparer.Equals(Item6, objTuple.Item6)
- && comparer.Equals(Item7, objTuple.Item7)
- && comparer.Equals(Rest, objTuple.Rest);
- }
-
- int IComparable.CompareTo(object other)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- return CompareTo((ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)other);
- }
-
- /// <summary>Compares this instance to a specified instance and returns an indication of their relative values.</summary>
- /// <param name="other">An instance to compare.</param>
- /// <returns>
- /// A signed number indicating the relative values of this instance and <paramref name="other"/>.
- /// Returns less than zero if this instance is less than <paramref name="other"/>, zero if this
- /// instance is equal to <paramref name="other"/>, and greater than zero if this instance is greater
- /// than <paramref name="other"/>.
- /// </returns>
- public int CompareTo(ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest> other)
- {
- int c = Comparer<T1>.Default.Compare(Item1, other.Item1);
- if (c != 0) return c;
-
- c = Comparer<T2>.Default.Compare(Item2, other.Item2);
- if (c != 0) return c;
-
- c = Comparer<T3>.Default.Compare(Item3, other.Item3);
- if (c != 0) return c;
-
- c = Comparer<T4>.Default.Compare(Item4, other.Item4);
- if (c != 0) return c;
-
- c = Comparer<T5>.Default.Compare(Item5, other.Item5);
- if (c != 0) return c;
-
- c = Comparer<T6>.Default.Compare(Item6, other.Item6);
- if (c != 0) return c;
-
- c = Comparer<T7>.Default.Compare(Item7, other.Item7);
- if (c != 0) return c;
-
- return Comparer<TRest>.Default.Compare(Rest, other.Rest);
- }
-
- int IStructuralComparable.CompareTo(object other, IComparer comparer)
- {
- if (other == null) return 1;
-
- if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>))
- {
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
- }
-
- var objTuple = (ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)other;
-
- int c = comparer.Compare(Item1, objTuple.Item1);
- if (c != 0) return c;
-
- c = comparer.Compare(Item2, objTuple.Item2);
- if (c != 0) return c;
-
- c = comparer.Compare(Item3, objTuple.Item3);
- if (c != 0) return c;
-
- c = comparer.Compare(Item4, objTuple.Item4);
- if (c != 0) return c;
-
- c = comparer.Compare(Item5, objTuple.Item5);
- if (c != 0) return c;
-
- c = comparer.Compare(Item6, objTuple.Item6);
- if (c != 0) return c;
-
- c = comparer.Compare(Item7, objTuple.Item7);
- if (c != 0) return c;
-
- return comparer.Compare(Rest, objTuple.Rest);
- }
-
- /// <summary>
- /// Returns the hash code for the current <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance.
- /// </summary>
- /// <returns>A 32-bit signed integer hash code.</returns>
- public override int GetHashCode()
- {
- // We want to have a limited hash in this case. We'll use the last 8 elements of the tuple
- IValueTupleInternal rest = Rest as IValueTupleInternal;
- if (rest == null)
- {
- return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
- Item2?.GetHashCode() ?? 0,
- Item3?.GetHashCode() ?? 0,
- Item4?.GetHashCode() ?? 0,
- Item5?.GetHashCode() ?? 0,
- Item6?.GetHashCode() ?? 0,
- Item7?.GetHashCode() ?? 0);
- }
-
- int size = rest.Length;
- if (size >= 8) { return rest.GetHashCode(); }
-
- // In this case, the rest member has less than 8 elements so we need to combine some our elements with the elements in rest
- int k = 8 - size;
- switch (k)
- {
- case 1:
- return ValueTuple.CombineHashCodes(Item7?.GetHashCode() ?? 0,
- rest.GetHashCode());
- case 2:
- return ValueTuple.CombineHashCodes(Item6?.GetHashCode() ?? 0,
- Item7?.GetHashCode() ?? 0,
- rest.GetHashCode());
- case 3:
- return ValueTuple.CombineHashCodes(Item5?.GetHashCode() ?? 0,
- Item6?.GetHashCode() ?? 0,
- Item7?.GetHashCode() ?? 0,
- rest.GetHashCode());
- case 4:
- return ValueTuple.CombineHashCodes(Item4?.GetHashCode() ?? 0,
- Item5?.GetHashCode() ?? 0,
- Item6?.GetHashCode() ?? 0,
- Item7?.GetHashCode() ?? 0,
- rest.GetHashCode());
- case 5:
- return ValueTuple.CombineHashCodes(Item3?.GetHashCode() ?? 0,
- Item4?.GetHashCode() ?? 0,
- Item5?.GetHashCode() ?? 0,
- Item6?.GetHashCode() ?? 0,
- Item7?.GetHashCode() ?? 0,
- rest.GetHashCode());
- case 6:
- return ValueTuple.CombineHashCodes(Item2?.GetHashCode() ?? 0,
- Item3?.GetHashCode() ?? 0,
- Item4?.GetHashCode() ?? 0,
- Item5?.GetHashCode() ?? 0,
- Item6?.GetHashCode() ?? 0,
- Item7?.GetHashCode() ?? 0,
- rest.GetHashCode());
- case 7:
- case 8:
- return ValueTuple.CombineHashCodes(Item1?.GetHashCode() ?? 0,
- Item2?.GetHashCode() ?? 0,
- Item3?.GetHashCode() ?? 0,
- Item4?.GetHashCode() ?? 0,
- Item5?.GetHashCode() ?? 0,
- Item6?.GetHashCode() ?? 0,
- Item7?.GetHashCode() ?? 0,
- rest.GetHashCode());
- }
-
- Contract.Assert(false, "Missed all cases for computing ValueTuple hash code");
- return -1;
- }
-
- int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- private int GetHashCodeCore(IEqualityComparer comparer)
- {
- // We want to have a limited hash in this case. We'll use the last 8 elements of the tuple
- IValueTupleInternal rest = Rest as IValueTupleInternal;
- if (rest == null)
- {
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3),
- comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6),
- comparer.GetHashCode(Item7));
- }
-
- int size = rest.Length;
- if (size >= 8) { return rest.GetHashCode(comparer); }
-
- // In this case, the rest member has less than 8 elements so we need to combine some our elements with the elements in rest
- int k = 8 - size;
- switch (k)
- {
- case 1:
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item7), rest.GetHashCode(comparer));
- case 2:
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer));
- case 3:
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7),
- rest.GetHashCode(comparer));
- case 4:
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6),
- comparer.GetHashCode(Item7), rest.GetHashCode(comparer));
- case 5:
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item3), comparer.GetHashCode(Item4), comparer.GetHashCode(Item5),
- comparer.GetHashCode(Item6), comparer.GetHashCode(Item7), rest.GetHashCode(comparer));
- case 6:
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item2), comparer.GetHashCode(Item3), comparer.GetHashCode(Item4),
- comparer.GetHashCode(Item5), comparer.GetHashCode(Item6), comparer.GetHashCode(Item7),
- rest.GetHashCode(comparer));
- case 7:
- case 8:
- return ValueTuple.CombineHashCodes(comparer.GetHashCode(Item1), comparer.GetHashCode(Item2), comparer.GetHashCode(Item3),
- comparer.GetHashCode(Item4), comparer.GetHashCode(Item5), comparer.GetHashCode(Item6),
- comparer.GetHashCode(Item7), rest.GetHashCode(comparer));
- }
-
- Contract.Assert(false, "Missed all cases for computing ValueTuple hash code");
- return -1;
- }
-
- int IValueTupleInternal.GetHashCode(IEqualityComparer comparer)
- {
- return GetHashCodeCore(comparer);
- }
-
- /// <summary>
- /// Returns a string that represents the value of this <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance.
- /// </summary>
- /// <returns>The string representation of this <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7, TRest}"/> instance.</returns>
- /// <remarks>
- /// The string returned by this method takes the form <c>(Item1, Item2, Item3, Item4, Item5, Item6, Item7, Rest)</c>.
- /// If any field value is <see langword="null"/>, it is represented as <see cref="String.Empty"/>.
- /// </remarks>
- public override string ToString()
- {
- IValueTupleInternal rest = Rest as IValueTupleInternal;
- if (rest == null)
- {
- return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")";
- }
- else
- {
- return "(" + Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd();
- }
- }
-
- string IValueTupleInternal.ToStringEnd()
- {
- IValueTupleInternal rest = Rest as IValueTupleInternal;
- if (rest == null)
- {
- return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + Rest.ToString() + ")";
- }
- else
- {
- return Item1?.ToString() + ", " + Item2?.ToString() + ", " + Item3?.ToString() + ", " + Item4?.ToString() + ", " + Item5?.ToString() + ", " + Item6?.ToString() + ", " + Item7?.ToString() + ", " + rest.ToStringEnd();
- }
- }
-
- /// <summary>
- /// The number of positions in this data structure.
- /// </summary>
- int ITuple.Length
- {
- get
- {
- IValueTupleInternal rest = Rest as IValueTupleInternal;
- return rest == null ? 8 : 7 + rest.Length;
- }
- }
-
- /// <summary>
- /// Get the element at position <param name="index"/>.
- /// </summary>
- object ITuple.this[int index]
- {
- get
- {
- switch (index)
- {
- case 0:
- return Item1;
- case 1:
- return Item2;
- case 2:
- return Item3;
- case 3:
- return Item4;
- case 4:
- return Item5;
- case 5:
- return Item6;
- case 6:
- return Item7;
- }
-
- IValueTupleInternal rest = Rest as IValueTupleInternal;
- if (rest == null)
- {
- if (index == 7)
- {
- return Rest;
- }
- throw new IndexOutOfRangeException();
- }
- return rest[index - 7];
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/ValueType.cs b/src/mscorlib/src/System/ValueType.cs
index 06a64e397c..0cd08bd26f 100644
--- a/src/mscorlib/src/System/ValueType.cs
+++ b/src/mscorlib/src/System/ValueType.cs
@@ -10,24 +10,29 @@
**
**
===========================================================*/
-namespace System {
- using System;
- using System.Reflection;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- [Serializable]
- public abstract class ValueType {
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
- public override bool Equals (Object obj) {
- BCLDebug.Perf(false, "ValueType::Equals is not fast. "+this.GetType().FullName+" should override Equals(Object)");
- if (null==obj) {
+namespace System
+{
+ [Serializable]
+ public abstract class ValueType
+ {
+ public override bool Equals(Object obj)
+ {
+ BCLDebug.Perf(false, "ValueType::Equals is not fast. " + this.GetType().FullName + " should override Equals(Object)");
+ if (null == obj)
+ {
return false;
}
RuntimeType thisType = (RuntimeType)this.GetType();
RuntimeType thatType = (RuntimeType)obj.GetType();
- if (thatType!=thisType) {
+ if (thatType != thisType)
+ {
return false;
}
@@ -41,16 +46,19 @@ namespace System {
FieldInfo[] thisFields = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
- for (int i=0; i<thisFields.Length; i++) {
+ for (int i = 0; i < thisFields.Length; i++)
+ {
thisResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(thisObj);
thatResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(obj);
-
- if (thisResult == null) {
+
+ if (thisResult == null)
+ {
if (thatResult != null)
return false;
}
else
- if (!thisResult.Equals(thatResult)) {
+ if (!thisResult.Equals(thatResult))
+ {
return false;
}
}
diff --git a/src/mscorlib/src/System/Variant.cs b/src/mscorlib/src/System/Variant.cs
index 509650b8fc..cae5bdade4 100644
--- a/src/mscorlib/src/System/Variant.cs
+++ b/src/mscorlib/src/System/Variant.cs
@@ -10,22 +10,23 @@
**
**
===========================================================*/
-namespace System {
-
- using System;
- using System.Reflection;
- using System.Threading;
- using System.Runtime.InteropServices;
- using System.Globalization;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
+using System;
+using System.Reflection;
+using System.Threading;
+using System.Runtime.InteropServices;
+using System.Globalization;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
[Serializable]
[StructLayout(LayoutKind.Sequential)]
- internal struct Variant {
-
+ internal struct Variant
+ {
//Do Not change the order of these fields.
//They are mapped to the native VariantData * data structure.
private Object m_objref;
@@ -45,48 +46,48 @@ namespace System {
// If you update this, update the corresponding stuff in OAVariantLib.cs,
// COMOAVariant.cpp (2 tables, forwards and reverse), and perhaps OleVariant.h
///////////////////////////////////////////////////////////////////////
- internal const int CV_EMPTY=0x0;
- internal const int CV_VOID=0x1;
- internal const int CV_BOOLEAN=0x2;
- internal const int CV_CHAR=0x3;
- internal const int CV_I1=0x4;
- internal const int CV_U1=0x5;
- internal const int CV_I2=0x6;
- internal const int CV_U2=0x7;
- internal const int CV_I4=0x8;
- internal const int CV_U4=0x9;
- internal const int CV_I8=0xa;
- internal const int CV_U8=0xb;
- internal const int CV_R4=0xc;
- internal const int CV_R8=0xd;
- internal const int CV_STRING=0xe;
- internal const int CV_PTR=0xf;
+ internal const int CV_EMPTY = 0x0;
+ internal const int CV_VOID = 0x1;
+ internal const int CV_BOOLEAN = 0x2;
+ internal const int CV_CHAR = 0x3;
+ internal const int CV_I1 = 0x4;
+ internal const int CV_U1 = 0x5;
+ internal const int CV_I2 = 0x6;
+ internal const int CV_U2 = 0x7;
+ internal const int CV_I4 = 0x8;
+ internal const int CV_U4 = 0x9;
+ internal const int CV_I8 = 0xa;
+ internal const int CV_U8 = 0xb;
+ internal const int CV_R4 = 0xc;
+ internal const int CV_R8 = 0xd;
+ internal const int CV_STRING = 0xe;
+ internal const int CV_PTR = 0xf;
internal const int CV_DATETIME = 0x10;
internal const int CV_TIMESPAN = 0x11;
- internal const int CV_OBJECT=0x12;
+ internal const int CV_OBJECT = 0x12;
internal const int CV_DECIMAL = 0x13;
- internal const int CV_ENUM=0x15;
- internal const int CV_MISSING=0x16;
- internal const int CV_NULL=0x17;
- internal const int CV_LAST=0x18;
+ internal const int CV_ENUM = 0x15;
+ internal const int CV_MISSING = 0x16;
+ internal const int CV_NULL = 0x17;
+ internal const int CV_LAST = 0x18;
- internal const int TypeCodeBitMask=0xffff;
- internal const int VTBitMask=unchecked((int)0xff000000);
- internal const int VTBitShift=24;
- internal const int ArrayBitMask =0x10000;
+ internal const int TypeCodeBitMask = 0xffff;
+ internal const int VTBitMask = unchecked((int)0xff000000);
+ internal const int VTBitShift = 24;
+ internal const int ArrayBitMask = 0x10000;
// Enum enum and Mask
- internal const int EnumI1 =0x100000;
- internal const int EnumU1 =0x200000;
- internal const int EnumI2 =0x300000;
- internal const int EnumU2 =0x400000;
- internal const int EnumI4 =0x500000;
- internal const int EnumU4 =0x600000;
- internal const int EnumI8 =0x700000;
- internal const int EnumU8 =0x800000;
- internal const int EnumMask =0xF00000;
-
- internal static readonly Type [] ClassTypes = {
+ internal const int EnumI1 = 0x100000;
+ internal const int EnumU1 = 0x200000;
+ internal const int EnumI2 = 0x300000;
+ internal const int EnumU2 = 0x400000;
+ internal const int EnumI4 = 0x500000;
+ internal const int EnumU4 = 0x600000;
+ internal const int EnumI8 = 0x700000;
+ internal const int EnumU8 = 0x800000;
+ internal const int EnumMask = 0xF00000;
+
+ internal static readonly Type[] ClassTypes = {
typeof(System.Empty),
typeof(void),
typeof(Boolean),
@@ -122,11 +123,11 @@ namespace System {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern double GetR8FromVar();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern float GetR4FromVar();
+ internal extern float GetR4FromVar();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern void SetFieldsR4(float val);
+ internal extern void SetFieldsR4(float val);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal extern void SetFieldsR8(double val);
+ internal extern void SetFieldsR8(double val);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal extern void SetFieldsObject(Object val);
@@ -135,159 +136,181 @@ namespace System {
// Ends up only taking about 1/8 the time of the ECALL version.
internal long GetI8FromVar()
{
- return ((long)m_data2<<32 | ((long)m_data1 & 0xFFFFFFFFL));
+ return ((long)m_data2 << 32 | ((long)m_data1 & 0xFFFFFFFFL));
}
//
// Constructors
//
- internal Variant(int flags, Object or, int data1, int data2) {
+ internal Variant(int flags, Object or, int data1, int data2)
+ {
m_flags = flags;
- m_objref=or;
- m_data1=data1;
- m_data2=data2;
+ m_objref = or;
+ m_data1 = data1;
+ m_data2 = data2;
}
- public Variant(bool val) {
- m_objref= null;
+ public Variant(bool val)
+ {
+ m_objref = null;
m_flags = CV_BOOLEAN;
- m_data1 = (val)?Boolean.True:Boolean.False;
+ m_data1 = (val) ? Boolean.True : Boolean.False;
m_data2 = 0;
}
- public Variant(sbyte val) {
- m_objref=null;
- m_flags=CV_I1;
- m_data1=(int)val;
- m_data2=(int)(((long)val)>>32);
+ public Variant(sbyte val)
+ {
+ m_objref = null;
+ m_flags = CV_I1;
+ m_data1 = (int)val;
+ m_data2 = (int)(((long)val) >> 32);
}
- public Variant(byte val) {
- m_objref=null;
- m_flags=CV_U1;
- m_data1=(int)val;
- m_data2=0;
+ public Variant(byte val)
+ {
+ m_objref = null;
+ m_flags = CV_U1;
+ m_data1 = (int)val;
+ m_data2 = 0;
}
- public Variant(short val) {
- m_objref=null;
- m_flags=CV_I2;
- m_data1=(int)val;
- m_data2=(int)(((long)val)>>32);
+ public Variant(short val)
+ {
+ m_objref = null;
+ m_flags = CV_I2;
+ m_data1 = (int)val;
+ m_data2 = (int)(((long)val) >> 32);
}
- public Variant(ushort val) {
- m_objref=null;
- m_flags=CV_U2;
- m_data1=(int)val;
- m_data2=0;
+ public Variant(ushort val)
+ {
+ m_objref = null;
+ m_flags = CV_U2;
+ m_data1 = (int)val;
+ m_data2 = 0;
}
- public Variant(char val) {
- m_objref=null;
- m_flags=CV_CHAR;
- m_data1=(int)val;
- m_data2=0;
+ public Variant(char val)
+ {
+ m_objref = null;
+ m_flags = CV_CHAR;
+ m_data1 = (int)val;
+ m_data2 = 0;
}
- public Variant(int val) {
- m_objref=null;
- m_flags=CV_I4;
- m_data1=val;
- m_data2=val >> 31;
+ public Variant(int val)
+ {
+ m_objref = null;
+ m_flags = CV_I4;
+ m_data1 = val;
+ m_data2 = val >> 31;
}
- public Variant(uint val) {
- m_objref=null;
- m_flags=CV_U4;
- m_data1=(int)val;
- m_data2=0;
+ public Variant(uint val)
+ {
+ m_objref = null;
+ m_flags = CV_U4;
+ m_data1 = (int)val;
+ m_data2 = 0;
}
- public Variant(long val) {
- m_objref=null;
- m_flags=CV_I8;
+ public Variant(long val)
+ {
+ m_objref = null;
+ m_flags = CV_I8;
m_data1 = (int)val;
m_data2 = (int)(val >> 32);
}
- public Variant(ulong val) {
- m_objref=null;
- m_flags=CV_U8;
+ public Variant(ulong val)
+ {
+ m_objref = null;
+ m_flags = CV_U8;
m_data1 = (int)val;
m_data2 = (int)(val >> 32);
}
- public Variant(float val) {
- m_objref=null;
- m_flags=CV_R4;
- m_data1=0;
- m_data2=0;
+ public Variant(float val)
+ {
+ m_objref = null;
+ m_flags = CV_R4;
+ m_data1 = 0;
+ m_data2 = 0;
SetFieldsR4(val);
}
- public Variant(double val) {
- m_objref=null;
- m_flags=CV_R8;
- m_data1=0;
- m_data2=0;
+ public Variant(double val)
+ {
+ m_objref = null;
+ m_flags = CV_R8;
+ m_data1 = 0;
+ m_data2 = 0;
SetFieldsR8(val);
}
- public Variant(DateTime val) {
- m_objref=null;
- m_flags=CV_DATETIME;
+ public Variant(DateTime val)
+ {
+ m_objref = null;
+ m_flags = CV_DATETIME;
ulong ticks = (ulong)val.Ticks;
m_data1 = (int)ticks;
- m_data2 = (int)(ticks>>32);
+ m_data2 = (int)(ticks >> 32);
}
- public Variant(Decimal val) {
+ public Variant(Decimal val)
+ {
m_objref = (Object)val;
m_flags = CV_DECIMAL;
- m_data1=0;
- m_data2=0;
+ m_data1 = 0;
+ m_data2 = 0;
}
- public Variant(Object obj) {
- m_data1=0;
- m_data2=0;
+ public Variant(Object obj)
+ {
+ m_data1 = 0;
+ m_data2 = 0;
VarEnum vt = VarEnum.VT_EMPTY;
- if (obj is DateTime) {
- m_objref=null;
- m_flags=CV_DATETIME;
+ if (obj is DateTime)
+ {
+ m_objref = null;
+ m_flags = CV_DATETIME;
ulong ticks = (ulong)((DateTime)obj).Ticks;
m_data1 = (int)ticks;
- m_data2 = (int)(ticks>>32);
+ m_data2 = (int)(ticks >> 32);
return;
}
- if (obj is String) {
- m_flags=CV_STRING;
- m_objref=obj;
+ if (obj is String)
+ {
+ m_flags = CV_STRING;
+ m_objref = obj;
return;
}
- if (obj == null) {
+ if (obj == null)
+ {
this = Empty;
return;
}
- if (obj == System.DBNull.Value) {
+ if (obj == System.DBNull.Value)
+ {
this = DBNull;
return;
}
- if (obj == Type.Missing) {
+ if (obj == Type.Missing)
+ {
this = Missing;
return;
}
- if (obj is Array) {
- m_flags=CV_OBJECT | ArrayBitMask;
- m_objref=obj;
+ if (obj is Array)
+ {
+ m_flags = CV_OBJECT | ArrayBitMask;
+ m_objref = obj;
return;
}
@@ -336,55 +359,59 @@ namespace System {
//This is a family-only accessor for the CVType.
//This is never to be exposed externally.
- internal int CVType {
- get {
- return (m_flags&TypeCodeBitMask);
+ internal int CVType
+ {
+ get
+ {
+ return (m_flags & TypeCodeBitMask);
}
}
- public Object ToObject() {
- switch (CVType) {
- case CV_EMPTY:
- return null;
- case CV_BOOLEAN:
- return (Object)(m_data1!=0);
- case CV_I1:
- return (Object)((sbyte)m_data1);
- case CV_U1:
- return (Object)((byte)m_data1);
- case CV_CHAR:
- return (Object)((char)m_data1);
- case CV_I2:
- return (Object)((short)m_data1);
- case CV_U2:
- return (Object)((ushort)m_data1);
- case CV_I4:
- return (Object)(m_data1);
- case CV_U4:
- return (Object)((uint)m_data1);
- case CV_I8:
- return (Object)(GetI8FromVar());
- case CV_U8:
- return (Object)((ulong)GetI8FromVar());
- case CV_R4:
- return (Object)(GetR4FromVar());
- case CV_R8:
- return (Object)(GetR8FromVar());
- case CV_DATETIME:
- return new DateTime(GetI8FromVar());
- case CV_TIMESPAN:
- return new TimeSpan(GetI8FromVar());
- case CV_ENUM:
- return BoxEnum();
- case CV_MISSING:
- return Type.Missing;
- case CV_NULL:
- return System.DBNull.Value;
- case CV_DECIMAL:
- case CV_STRING:
- case CV_OBJECT:
- default:
- return m_objref;
+ public Object ToObject()
+ {
+ switch (CVType)
+ {
+ case CV_EMPTY:
+ return null;
+ case CV_BOOLEAN:
+ return (Object)(m_data1 != 0);
+ case CV_I1:
+ return (Object)((sbyte)m_data1);
+ case CV_U1:
+ return (Object)((byte)m_data1);
+ case CV_CHAR:
+ return (Object)((char)m_data1);
+ case CV_I2:
+ return (Object)((short)m_data1);
+ case CV_U2:
+ return (Object)((ushort)m_data1);
+ case CV_I4:
+ return (Object)(m_data1);
+ case CV_U4:
+ return (Object)((uint)m_data1);
+ case CV_I8:
+ return (Object)(GetI8FromVar());
+ case CV_U8:
+ return (Object)((ulong)GetI8FromVar());
+ case CV_R4:
+ return (Object)(GetR4FromVar());
+ case CV_R8:
+ return (Object)(GetR8FromVar());
+ case CV_DATETIME:
+ return new DateTime(GetI8FromVar());
+ case CV_TIMESPAN:
+ return new TimeSpan(GetI8FromVar());
+ case CV_ENUM:
+ return BoxEnum();
+ case CV_MISSING:
+ return Type.Missing;
+ case CV_NULL:
+ return System.DBNull.Value;
+ case CV_DECIMAL:
+ case CV_STRING:
+ case CV_OBJECT:
+ default:
+ return m_objref;
}
}
@@ -488,7 +515,7 @@ namespace System {
break;
default:
- throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnknownTypeCode", ic.GetTypeCode()));
+ throw new NotSupportedException(SR.Format(SR.NotSupported_UnknownTypeCode, ic.GetTypeCode()));
}
}
}
@@ -534,12 +561,12 @@ namespace System {
}
else
{
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_CannotCoerceByRefVariant"));
+ throw new InvalidCastException(SR.InvalidCast_CannotCoerceByRefVariant);
}
break;
default:
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_CannotCoerceByRefVariant"));
+ throw new InvalidCastException(SR.InvalidCast_CannotCoerceByRefVariant);
}
}
else
@@ -643,7 +670,7 @@ namespace System {
break;
default:
- throw new InvalidCastException(Environment.GetResourceString("InvalidCast_CannotCoerceByRefVariant"));
+ throw new InvalidCastException(SR.InvalidCast_CannotCoerceByRefVariant);
}
}
}
diff --git a/src/mscorlib/src/System/Version.cs b/src/mscorlib/src/System/Version.cs
deleted file mode 100644
index 7c58d3c0c4..0000000000
--- a/src/mscorlib/src/System/Version.cs
+++ /dev/null
@@ -1,448 +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.
-
-/*============================================================
-**
-**
-**
-** Purpose:
-**
-**
-===========================================================*/
-namespace System {
-
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
- using System.Text;
- using CultureInfo = System.Globalization.CultureInfo;
- using NumberStyles = System.Globalization.NumberStyles;
-
- // A Version object contains four hierarchical numeric components: major, minor,
- // build and revision. Build and revision may be unspecified, which is represented
- // internally as a -1. By definition, an unspecified component matches anything
- // (both unspecified and specified), and an unspecified component is "less than" any
- // specified component.
-
- [Serializable]
- public sealed class Version : ICloneable, IComparable
- , IComparable<Version>, IEquatable<Version>
- {
- // AssemblyName depends on the order staying the same
- private readonly int _Major;
- private readonly int _Minor;
- private readonly int _Build = -1;
- private readonly int _Revision = -1;
-
- public Version(int major, int minor, int build, int revision) {
- if (major < 0)
- throw new ArgumentOutOfRangeException(nameof(major),Environment.GetResourceString("ArgumentOutOfRange_Version"));
-
- if (minor < 0)
- throw new ArgumentOutOfRangeException(nameof(minor),Environment.GetResourceString("ArgumentOutOfRange_Version"));
-
- if (build < 0)
- throw new ArgumentOutOfRangeException(nameof(build),Environment.GetResourceString("ArgumentOutOfRange_Version"));
-
- if (revision < 0)
- throw new ArgumentOutOfRangeException(nameof(revision),Environment.GetResourceString("ArgumentOutOfRange_Version"));
- Contract.EndContractBlock();
-
- _Major = major;
- _Minor = minor;
- _Build = build;
- _Revision = revision;
- }
-
- public Version(int major, int minor, int build) {
- if (major < 0)
- throw new ArgumentOutOfRangeException(nameof(major),Environment.GetResourceString("ArgumentOutOfRange_Version"));
-
- if (minor < 0)
- throw new ArgumentOutOfRangeException(nameof(minor),Environment.GetResourceString("ArgumentOutOfRange_Version"));
-
- if (build < 0)
- throw new ArgumentOutOfRangeException(nameof(build),Environment.GetResourceString("ArgumentOutOfRange_Version"));
-
- Contract.EndContractBlock();
-
- _Major = major;
- _Minor = minor;
- _Build = build;
- }
-
- public Version(int major, int minor) {
- if (major < 0)
- throw new ArgumentOutOfRangeException(nameof(major),Environment.GetResourceString("ArgumentOutOfRange_Version"));
-
- if (minor < 0)
- throw new ArgumentOutOfRangeException(nameof(minor),Environment.GetResourceString("ArgumentOutOfRange_Version"));
- Contract.EndContractBlock();
-
- _Major = major;
- _Minor = minor;
- }
-
- public Version(String version) {
- Version v = Version.Parse(version);
- _Major = v.Major;
- _Minor = v.Minor;
- _Build = v.Build;
- _Revision = v.Revision;
- }
-
- public Version()
- {
- _Major = 0;
- _Minor = 0;
- }
-
- private Version(Version version)
- {
- Debug.Assert(version != null);
-
- _Major = version._Major;
- _Minor = version._Minor;
- _Build = version._Build;
- _Revision = version._Revision;
- }
-
- // Properties for setting and getting version numbers
- public int Major {
- get { return _Major; }
- }
-
- public int Minor {
- get { return _Minor; }
- }
-
- public int Build {
- get { return _Build; }
- }
-
- public int Revision {
- get { return _Revision; }
- }
-
- public short MajorRevision {
- get { return (short)(_Revision >> 16); }
- }
-
- public short MinorRevision {
- get { return (short)(_Revision & 0xFFFF); }
- }
-
- public Object Clone() {
- return new Version(this);
- }
-
- public int CompareTo(Object version)
- {
- if (version == null)
- {
- return 1;
- }
-
- Version v = version as Version;
- if (v == null)
- {
- throw new ArgumentException(Environment.GetResourceString("Arg_MustBeVersion"));
- }
-
- return CompareTo(v);
- }
-
- public int CompareTo(Version value)
- {
- return
- object.ReferenceEquals(value, this) ? 0 :
- object.ReferenceEquals(value, null) ? 1 :
- _Major != value._Major ? (_Major > value._Major ? 1 : -1) :
- _Minor != value._Minor ? (_Minor > value._Minor ? 1 : -1) :
- _Build != value._Build ? (_Build > value._Build ? 1 : -1) :
- _Revision != value._Revision ? (_Revision > value._Revision ? 1 : -1) :
- 0;
- }
-
- public override bool Equals(Object obj) {
- return Equals(obj as Version);
- }
-
- public bool Equals(Version obj)
- {
- return object.ReferenceEquals(obj, this) ||
- (!object.ReferenceEquals(obj, null) &&
- _Major == obj._Major &&
- _Minor == obj._Minor &&
- _Build == obj._Build &&
- _Revision == obj._Revision);
- }
-
- public override int GetHashCode()
- {
- // Let's assume that most version numbers will be pretty small and just
- // OR some lower order bits together.
-
- int accumulator = 0;
-
- accumulator |= (this._Major & 0x0000000F) << 28;
- accumulator |= (this._Minor & 0x000000FF) << 20;
- accumulator |= (this._Build & 0x000000FF) << 12;
- accumulator |= (this._Revision & 0x00000FFF);
-
- return accumulator;
- }
-
- public override String ToString() {
- if (_Build == -1) return(ToString(2));
- if (_Revision == -1) return(ToString(3));
- return(ToString(4));
- }
-
- public String ToString(int fieldCount) {
- StringBuilder sb;
- switch (fieldCount) {
- case 0:
- return(String.Empty);
- case 1:
- return(_Major.ToString());
- case 2:
- sb = StringBuilderCache.Acquire();
- AppendPositiveNumber(_Major, sb);
- sb.Append('.');
- AppendPositiveNumber(_Minor, sb);
- return StringBuilderCache.GetStringAndRelease(sb);
- default:
- if (_Build == -1)
- throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper", "0", "2"), nameof(fieldCount));
-
- if (fieldCount == 3)
- {
- sb = StringBuilderCache.Acquire();
- AppendPositiveNumber(_Major, sb);
- sb.Append('.');
- AppendPositiveNumber(_Minor, sb);
- sb.Append('.');
- AppendPositiveNumber(_Build, sb);
- return StringBuilderCache.GetStringAndRelease(sb);
- }
-
- if (_Revision == -1)
- throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper", "0", "3"), nameof(fieldCount));
-
- if (fieldCount == 4)
- {
- sb = StringBuilderCache.Acquire();
- AppendPositiveNumber(_Major, sb);
- sb.Append('.');
- AppendPositiveNumber(_Minor, sb);
- sb.Append('.');
- AppendPositiveNumber(_Build, sb);
- sb.Append('.');
- AppendPositiveNumber(_Revision, sb);
- return StringBuilderCache.GetStringAndRelease(sb);
- }
-
- throw new ArgumentException(Environment.GetResourceString("ArgumentOutOfRange_Bounds_Lower_Upper", "0", "4"), nameof(fieldCount));
- }
- }
-
- //
- // AppendPositiveNumber is an optimization to append a number to a StringBuilder object without
- // doing any boxing and not even creating intermediate string.
- // Note: as we always have positive numbers then it is safe to convert the number to string
- // regardless of the current culture as we'll not have any punctuation marks in the number
- //
- private const int ZERO_CHAR_VALUE = (int) '0';
- private static void AppendPositiveNumber(int num, StringBuilder sb)
- {
- Debug.Assert(num >= 0, "AppendPositiveNumber expect positive numbers");
-
- int index = sb.Length;
- int reminder;
-
- do
- {
- reminder = num % 10;
- num = num / 10;
- sb.Insert(index, (char)(ZERO_CHAR_VALUE + reminder));
- } while (num > 0);
- }
-
- public static Version Parse(string input) {
- if (input == null) {
- throw new ArgumentNullException(nameof(input));
- }
- Contract.EndContractBlock();
-
- VersionResult r = new VersionResult();
- r.Init(nameof(input), true);
- if (!TryParseVersion(input, ref r)) {
- throw r.GetVersionParseException();
- }
- return r.m_parsedVersion;
- }
-
- public static bool TryParse(string input, out Version result) {
- VersionResult r = new VersionResult();
- r.Init(nameof(input), false);
- bool b = TryParseVersion(input, ref r);
- result = r.m_parsedVersion;
- return b;
- }
-
- private static bool TryParseVersion(string version, ref VersionResult result) {
- int major, minor, build, revision;
-
- if ((Object)version == null) {
- result.SetFailure(ParseFailureKind.ArgumentNullException);
- return false;
- }
-
- String[] parsedComponents = version.Split('.');
- int parsedComponentsLength = parsedComponents.Length;
- if ((parsedComponentsLength < 2) || (parsedComponentsLength > 4)) {
- result.SetFailure(ParseFailureKind.ArgumentException);
- return false;
- }
-
- if (!TryParseComponent(parsedComponents[0], nameof(version), ref result, out major)) {
- return false;
- }
-
- if (!TryParseComponent(parsedComponents[1], nameof(version), ref result, out minor)) {
- return false;
- }
-
- parsedComponentsLength -= 2;
-
- if (parsedComponentsLength > 0) {
- if (!TryParseComponent(parsedComponents[2], "build", ref result, out build)) {
- return false;
- }
-
- parsedComponentsLength--;
-
- if (parsedComponentsLength > 0) {
- if (!TryParseComponent(parsedComponents[3], "revision", ref result, out revision)) {
- return false;
- } else {
- result.m_parsedVersion = new Version(major, minor, build, revision);
- }
- } else {
- result.m_parsedVersion = new Version(major, minor, build);
- }
- } else {
- result.m_parsedVersion = new Version(major, minor);
- }
-
- return true;
- }
-
- private static bool TryParseComponent(string component, string componentName, ref VersionResult result, out int parsedComponent) {
- if (!Int32.TryParse(component, NumberStyles.Integer, CultureInfo.InvariantCulture, out parsedComponent)) {
- result.SetFailure(ParseFailureKind.FormatException, component);
- return false;
- }
-
- if (parsedComponent < 0) {
- result.SetFailure(ParseFailureKind.ArgumentOutOfRangeException, componentName);
- return false;
- }
-
- return true;
- }
-
- public static bool operator ==(Version v1, Version v2) {
- if (Object.ReferenceEquals(v1, null)) {
- return Object.ReferenceEquals(v2, null);
- }
-
- return v1.Equals(v2);
- }
-
- public static bool operator !=(Version v1, Version v2) {
- return !(v1 == v2);
- }
-
- public static bool operator <(Version v1, Version v2) {
- if ((Object) v1 == null)
- throw new ArgumentNullException(nameof(v1));
- Contract.EndContractBlock();
- return (v1.CompareTo(v2) < 0);
- }
-
- public static bool operator <=(Version v1, Version v2) {
- if ((Object) v1 == null)
- throw new ArgumentNullException(nameof(v1));
- Contract.EndContractBlock();
- return (v1.CompareTo(v2) <= 0);
- }
-
- public static bool operator >(Version v1, Version v2) {
- return (v2 < v1);
- }
-
- public static bool operator >=(Version v1, Version v2) {
- return (v2 <= v1);
- }
-
- internal enum ParseFailureKind {
- ArgumentNullException,
- ArgumentException,
- ArgumentOutOfRangeException,
- FormatException
- }
-
- internal struct VersionResult {
- internal Version m_parsedVersion;
- internal ParseFailureKind m_failure;
- internal string m_exceptionArgument;
- internal string m_argumentName;
- internal bool m_canThrow;
-
- internal void Init(string argumentName, bool canThrow) {
- m_canThrow = canThrow;
- m_argumentName = argumentName;
- }
-
- internal void SetFailure(ParseFailureKind failure) {
- SetFailure(failure, String.Empty);
- }
-
- internal void SetFailure(ParseFailureKind failure, string argument) {
- m_failure = failure;
- m_exceptionArgument = argument;
- if (m_canThrow) {
- throw GetVersionParseException();
- }
- }
-
- internal Exception GetVersionParseException() {
- switch (m_failure) {
- case ParseFailureKind.ArgumentNullException:
- return new ArgumentNullException(m_argumentName);
- case ParseFailureKind.ArgumentException:
- return new ArgumentException(Environment.GetResourceString("Arg_VersionString"));
- case ParseFailureKind.ArgumentOutOfRangeException:
- return new ArgumentOutOfRangeException(m_exceptionArgument, Environment.GetResourceString("ArgumentOutOfRange_Version"));
- case ParseFailureKind.FormatException:
- // Regenerate the FormatException as would be thrown by Int32.Parse()
- try {
- Int32.Parse(m_exceptionArgument, CultureInfo.InvariantCulture);
- } catch (FormatException e) {
- return e;
- } catch (OverflowException e) {
- return e;
- }
- Debug.Assert(false, "Int32.Parse() did not throw exception but TryParse failed: " + m_exceptionArgument);
- return new FormatException(Environment.GetResourceString("Format_InvalidString"));
- default:
- Debug.Assert(false, "Unmatched case in Version.GetVersionParseException() for value: " + m_failure);
- return new ArgumentException(Environment.GetResourceString("Arg_VersionString"));
- }
- }
-
- }
- }
-}
diff --git a/src/mscorlib/src/System/WeakReference.cs b/src/mscorlib/src/System/WeakReference.cs
index 6600d15855..60878b8e1c 100644
--- a/src/mscorlib/src/System/WeakReference.cs
+++ b/src/mscorlib/src/System/WeakReference.cs
@@ -8,18 +8,19 @@
** Purpose: A wrapper for establishing a WeakReference to an Object.
**
===========================================================*/
-namespace System {
-
- using System;
- using System.Runtime.Serialization;
- using System.Security;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
+using System;
+using System.Runtime.Serialization;
+using System.Security;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+
+namespace System
+{
[Serializable]
- public class WeakReference : ISerializable
+ public class WeakReference : ISerializable
{
// If you fix bugs here, please fix them in WeakReference<T> at the same time.
@@ -27,7 +28,8 @@ namespace System {
internal IntPtr m_handle;
// Migrating InheritanceDemands requires this default ctor, so we can mark it SafeCritical
- protected WeakReference() {
+ protected WeakReference()
+ {
Debug.Assert(false, "WeakReference's protected default ctor should never be used!");
throw new NotImplementedException();
}
@@ -35,40 +37,46 @@ namespace System {
// Creates a new WeakReference that keeps track of target.
// Assumes a Short Weak Reference (ie TrackResurrection is false.)
//
- public WeakReference(Object target)
- : this(target, false) {
+ public WeakReference(Object target)
+ : this(target, false)
+ {
}
-
+
//Creates a new WeakReference that keeps track of target.
//
- public WeakReference(Object target, bool trackResurrection) {
+ public WeakReference(Object target, bool trackResurrection)
+ {
Create(target, trackResurrection);
}
- protected WeakReference(SerializationInfo info, StreamingContext context) {
- if (info==null) {
+ protected WeakReference(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
- Object target = info.GetValue("TrackedObject",typeof(Object));
+ Object target = info.GetValue("TrackedObject", typeof(Object));
bool trackResurrection = info.GetBoolean("TrackResurrection");
Create(target, trackResurrection);
}
-
+
//Determines whether or not this instance of WeakReference still refers to an object
//that has not been collected.
//
- public extern virtual bool IsAlive {
+ public extern virtual bool IsAlive
+ {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
- }
-
+ }
+
//Returns a boolean indicating whether or not we're tracking objects until they're collected (true)
//or just until they're finalized (false).
//
- public virtual bool TrackResurrection {
+ public virtual bool TrackResurrection
+ {
// We need to call IsTrackResurrection non-virtually in GetObjectData, and so the virtual property cannot be FCall directly
get { return IsTrackResurrection(); }
}
@@ -76,13 +84,14 @@ namespace System {
//Gets the Object stored in the handle if it's accessible.
// Or sets it.
//
- public extern virtual Object Target {
+ public extern virtual Object Target
+ {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
get;
[MethodImplAttribute(MethodImplOptions.InternalCall)]
set;
}
-
+
// Free all system resources associated with this reference.
//
// Note: The WeakReference finalizer is not actually run, but
@@ -94,7 +103,8 @@ namespace System {
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
- if (info==null) {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
@@ -108,5 +118,4 @@ namespace System {
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern bool IsTrackResurrection();
}
-
}
diff --git a/src/mscorlib/src/System/WeakReferenceOfT.cs b/src/mscorlib/src/System/WeakReferenceOfT.cs
index 0972e5fb9e..fbb6f09098 100644
--- a/src/mscorlib/src/System/WeakReferenceOfT.cs
+++ b/src/mscorlib/src/System/WeakReferenceOfT.cs
@@ -8,19 +8,20 @@
** Purpose: A wrapper for establishing a WeakReference to a generic type.
**
===========================================================*/
+
+using System;
+using System.Runtime.Serialization;
+using System.Security;
+using System.Runtime;
+using System.Runtime.CompilerServices;
+using System.Runtime.Versioning;
+using System.Diagnostics.Contracts;
+
namespace System
{
- using System;
- using System.Runtime.Serialization;
- using System.Security;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.Runtime.Versioning;
- using System.Diagnostics.Contracts;
-
[Serializable]
// This class is sealed to mitigate security issues caused by Object::MemberwiseClone.
- public sealed class WeakReference<T> : ISerializable
+ public sealed class WeakReference<T> : ISerializable
where T : class
{
// If you fix bugs here, please fix them in WeakReference at the same time.
@@ -45,7 +46,8 @@ namespace System
internal WeakReference(SerializationInfo info, StreamingContext context)
{
- if (info == null) {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
@@ -97,7 +99,8 @@ namespace System
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
- if (info == null) {
+ if (info == null)
+ {
throw new ArgumentNullException(nameof(info));
}
Contract.EndContractBlock();
diff --git a/src/mscorlib/src/System/XmlIgnoreMemberAttribute.cs b/src/mscorlib/src/System/XmlIgnoreMemberAttribute.cs
deleted file mode 100644
index 04a8e688e6..0000000000
--- a/src/mscorlib/src/System/XmlIgnoreMemberAttribute.cs
+++ /dev/null
@@ -1,21 +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.
-
-/*=============================================================================
-**
-**
-**
-** Purpose: Attribute for properties/members that the Xml Serializer should
-** ignore.
-**
-**
-=============================================================================*/
-
-namespace System
-{
- [AttributeUsage(AttributeTargets.Property|AttributeTargets.Field)]
- internal sealed class XmlIgnoreMemberAttribute : Attribute
- {
- }
-}
diff --git a/src/mscorlib/src/System/__ComObject.cs b/src/mscorlib/src/System/__ComObject.cs
index 86800a51f8..412b763ab1 100644
--- a/src/mscorlib/src/System/__ComObject.cs
+++ b/src/mscorlib/src/System/__ComObject.cs
@@ -12,16 +12,17 @@
**
**
===========================================================*/
+
+using System;
+using System.Collections;
+using System.Threading;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.WindowsRuntime;
+using System.Runtime.CompilerServices;
+using System.Reflection;
+
namespace System
{
- using System;
- using System.Collections;
- using System.Threading;
- using System.Runtime.InteropServices;
- using System.Runtime.InteropServices.WindowsRuntime;
- using System.Runtime.CompilerServices;
- using System.Reflection;
-
internal class __ComObject : MarshalByRefObject
{
private Hashtable m_ObjectToDataMap;
@@ -30,7 +31,7 @@ namespace System
** default constructor
** can't instantiate this directly
=============================================================*/
- protected __ComObject ()
+ protected __ComObject()
{
}
@@ -52,9 +53,9 @@ namespace System
if (stringableType != null)
{
return stringableType.ToString();
- }
+ }
}
-
+
return base.ToString();
}
@@ -67,7 +68,7 @@ namespace System
Object data = null;
// Synchronize access to the map.
- lock(this)
+ lock (this)
{
// If the map hasn't been allocated, then there can be no data for the specified key.
if (m_ObjectToDataMap != null)
@@ -79,7 +80,7 @@ namespace System
return data;
}
-
+
//====================================================================
// This method sets the data for the specified key on the current
// __ComObject.
@@ -89,7 +90,7 @@ namespace System
bool bAdded = false;
// Synchronize access to the map.
- lock(this)
+ lock (this)
{
// If the map hasn't been allocated yet, allocate it.
if (m_ObjectToDataMap == null)
@@ -113,9 +114,8 @@ namespace System
internal void ReleaseAllData()
{
// Synchronize access to the map.
- lock(this)
+ lock (this)
{
-
// If the map hasn't been allocated, then there is nothing to do.
if (m_ObjectToDataMap != null)
{
@@ -123,7 +123,7 @@ namespace System
{
// Note: the value could be an object[]
// We are fine for now as object[] doesn't implement IDisposable nor derive from __ComObject
-
+
// If the object implements IDisposable, then call Dispose on it.
IDisposable DisposableObj = o as IDisposable;
if (DisposableObj != null)
@@ -170,7 +170,7 @@ namespace System
private Object CreateEventProvider(RuntimeType t)
{
// Create the event provider for the specified type.
- Object EvProvider = Activator.CreateInstance(t, Activator.ConstructorDefault | BindingFlags.NonPublic, null, new Object[]{this}, null);
+ Object EvProvider = Activator.CreateInstance(t, Activator.ConstructorDefault | BindingFlags.NonPublic, null, new Object[] { this }, null);
// Attempt to cache the wrapper on the object.
if (!SetData(t, EvProvider))
diff --git a/src/mscorlib/src/System/__Filters.cs b/src/mscorlib/src/System/__Filters.cs
deleted file mode 100644
index aabb52d803..0000000000
--- a/src/mscorlib/src/System/__Filters.cs
+++ /dev/null
@@ -1,155 +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.
-
-//
-// This class defines the delegate methods for the COM+ implemented filters.
-//
-//
-//
-
-namespace System {
- using System;
- using System.Reflection;
- using System.Globalization;
- [Serializable]
- internal class __Filters {
-
- // Filters...
- // The following are the built in filters defined for this class. These
- // should really be defined as static methods. They are used in as delegates
- // which currently doesn't support static methods. We will change this
- // once the compiler supports delegates.
- //
- // Note that it is not possible to make this class static as suggested by
- // the above comment anymore because of it got marked serializable.
-
- internal static readonly __Filters Instance = new __Filters();
-
- // FilterAttribute
- // This method will search for a member based upon the attribute passed in.
- // filterCriteria -- an Int32 representing the attribute
- internal virtual bool FilterAttribute(MemberInfo m,Object filterCriteria)
- {
- // Check that the criteria object is an Integer object
- if (filterCriteria == null)
- throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritInt"));
-
- switch (m.MemberType)
- {
- case MemberTypes.Constructor:
- case MemberTypes.Method: {
-
- MethodAttributes criteria = 0;
- try {
- int i = (int) filterCriteria;
- criteria = (MethodAttributes) i;
- }
- catch {
- throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritInt"));
- }
-
-
- MethodAttributes attr;
- if (m.MemberType == MemberTypes.Method)
- attr = ((MethodInfo) m).Attributes;
- else
- attr = ((ConstructorInfo) m).Attributes;
-
- if (((criteria & MethodAttributes.MemberAccessMask) != 0) && (attr & MethodAttributes.MemberAccessMask) != (criteria & MethodAttributes.MemberAccessMask))
- return false;
- if (((criteria & MethodAttributes.Static) != 0) && (attr & MethodAttributes.Static) == 0)
- return false;
- if (((criteria & MethodAttributes.Final) != 0) && (attr & MethodAttributes.Final) == 0)
- return false;
- if (((criteria & MethodAttributes.Virtual) != 0) && (attr & MethodAttributes.Virtual) == 0)
- return false;
- if (((criteria & MethodAttributes.Abstract) != 0) && (attr & MethodAttributes.Abstract) == 0)
- return false;
- if (((criteria & MethodAttributes.SpecialName) != 0) && (attr & MethodAttributes.SpecialName) == 0)
- return false;
- return true;
- }
- case MemberTypes.Field:
- {
- FieldAttributes criteria = 0;
- try {
- int i = (int) filterCriteria;
- criteria = (FieldAttributes) i;
- }
- catch {
- throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritInt"));
- }
-
- FieldAttributes attr = ((FieldInfo) m).Attributes;
- if (((criteria & FieldAttributes.FieldAccessMask) != 0) && (attr & FieldAttributes.FieldAccessMask) != (criteria & FieldAttributes.FieldAccessMask))
- return false;
- if (((criteria & FieldAttributes.Static) != 0) && (attr & FieldAttributes.Static) == 0)
- return false;
- if (((criteria & FieldAttributes.InitOnly) != 0) && (attr & FieldAttributes.InitOnly) == 0)
- return false;
- if (((criteria & FieldAttributes.Literal) != 0) && (attr & FieldAttributes.Literal) == 0)
- return false;
- if (((criteria & FieldAttributes.NotSerialized) != 0) && (attr & FieldAttributes.NotSerialized) == 0)
- return false;
- if (((criteria & FieldAttributes.PinvokeImpl) != 0) && (attr & FieldAttributes.PinvokeImpl) == 0)
- return false;
- return true;
- }
- }
-
- return false;
- }
- // FilterName
- // This method will filter based upon the name. A partial wildcard
- // at the end of the string is supported.
- // filterCriteria -- This is the string name
- internal virtual bool FilterName(MemberInfo m,Object filterCriteria)
- {
- // Check that the criteria object is a String object
- if(filterCriteria == null || !(filterCriteria is String))
- throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritString"));
-
- // At the moment this fails if its done on a single line....
- String str = ((String) filterCriteria);
- str = str.Trim();
-
- String name = m.Name;
- // Get the nested class name only, as opposed to the mangled one
- if (m.MemberType == MemberTypes.NestedType)
- name = name.Substring(name.LastIndexOf('+') + 1);
- // Check to see if this is a prefix or exact match requirement
- if (str.Length > 0 && str[str.Length - 1] == '*') {
- str = str.Substring(0, str.Length - 1);
- return (name.StartsWith(str, StringComparison.Ordinal));
- }
-
- return (name.Equals(str));
- }
-
- // FilterIgnoreCase
- // This delegate will do a name search but does it with the
- // ignore case specified.
- internal virtual bool FilterIgnoreCase(MemberInfo m,Object filterCriteria)
- {
- // Check that the criteria object is a String object
- if(filterCriteria == null || !(filterCriteria is String))
- throw new InvalidFilterCriteriaException(Environment.GetResourceString("RFLCT.FltCritString"));
-
- String str = (String) filterCriteria;
- str = str.Trim();
-
- String name = m.Name;
- // Get the nested class name only, as opposed to the mangled one
- if (m.MemberType == MemberTypes.NestedType)
- name = name.Substring(name.LastIndexOf('+') + 1);
- // Check to see if this is a prefix or exact match requirement
- if (str.Length > 0 && str[str.Length - 1] == '*') {
- str = str.Substring(0, str.Length - 1);
- return (String.Compare(name,0,str,0,str.Length,StringComparison.OrdinalIgnoreCase)==0);
- }
-
- return (String.Compare(str,name, StringComparison.OrdinalIgnoreCase) == 0);
- }
- }
-}
diff --git a/src/mscorlib/src/System/__HResults.cs b/src/mscorlib/src/System/__HResults.cs
index d1f21e22ae..e4183f637a 100644
--- a/src/mscorlib/src/System/__HResults.cs
+++ b/src/mscorlib/src/System/__HResults.cs
@@ -9,116 +9,117 @@
//
//
//===========================================================================*/
-namespace System {
- // Note: FACILITY_URT is defined as 0x13 (0x8013xxxx). Within that
- // range, 0x1yyy is for Runtime errors (used for Security, Metadata, etc).
- // In that subrange, 0x15zz and 0x16zz have been allocated for classlib-type
- // HResults. Also note that some of our HResults have to map to certain
- // COM HR's, etc.
-
- // Another arbitrary decision... Feel free to change this, as long as you
- // renumber the HResults yourself (and update rexcep.h).
- // Reflection will use 0x1600 -> 0x161f. IO will use 0x1620 -> 0x163f.
- // Security will use 0x1640 -> 0x165f
-
- // There are __HResults files in the IO, Remoting, Reflection &
- // Security/Util directories as well, so choose your HResults carefully.
-
- using System;
+// Note: FACILITY_URT is defined as 0x13 (0x8013xxxx). Within that
+// range, 0x1yyy is for Runtime errors (used for Security, Metadata, etc).
+// In that subrange, 0x15zz and 0x16zz have been allocated for classlib-type
+// HResults. Also note that some of our HResults have to map to certain
+// COM HR's, etc.
+
+// Another arbitrary decision... Feel free to change this, as long as you
+// renumber the HResults yourself (and update rexcep.h).
+// Reflection will use 0x1600 -> 0x161f. IO will use 0x1620 -> 0x163f.
+// Security will use 0x1640 -> 0x165f
+
+// There are __HResults files in the IO, Remoting, Reflection &
+// Security/Util directories as well, so choose your HResults carefully.
+
+using System;
+
+namespace System
+{
internal static class __HResults
{
-
internal const int RO_E_CLOSED = unchecked((int)0x80000013);
internal const int E_BOUNDS = unchecked((int)0x8000000B);
internal const int E_CHANGED_STATE = unchecked((int)0x8000000C);
- internal const int E_FAIL = unchecked((int)0x80004005);
- internal const int E_POINTER = unchecked((int)0x80004003);
+ internal const int E_FAIL = unchecked((int)0x80004005);
+ internal const int E_POINTER = unchecked((int)0x80004003);
internal const int E_NOTIMPL = unchecked((int)0x80004001);
internal const int REGDB_E_CLASSNOTREG = unchecked((int)0x80040154);
- internal const int COR_E_AMBIGUOUSMATCH = unchecked((int)0x8000211D);
- internal const int COR_E_APPDOMAINUNLOADED = unchecked((int)0x80131014);
- internal const int COR_E_APPLICATION = unchecked((int)0x80131600);
- internal const int COR_E_ARGUMENT = unchecked((int)0x80070057);
- internal const int COR_E_ARGUMENTOUTOFRANGE = unchecked((int)0x80131502);
- internal const int COR_E_ARITHMETIC = unchecked((int)0x80070216);
- internal const int COR_E_ARRAYTYPEMISMATCH = unchecked((int)0x80131503);
- internal const int COR_E_BADIMAGEFORMAT = unchecked((int)0x8007000B);
- internal const int COR_E_TYPEUNLOADED = unchecked((int)0x80131013);
- internal const int COR_E_CANNOTUNLOADAPPDOMAIN = unchecked((int)0x80131015);
- internal const int COR_E_COMEMULATE = unchecked((int)0x80131535);
- internal const int COR_E_CONTEXTMARSHAL = unchecked((int)0x80131504);
+ internal const int COR_E_AMBIGUOUSMATCH = unchecked((int)0x8000211D);
+ internal const int COR_E_APPDOMAINUNLOADED = unchecked((int)0x80131014);
+ internal const int COR_E_APPLICATION = unchecked((int)0x80131600);
+ internal const int COR_E_ARGUMENT = unchecked((int)0x80070057);
+ internal const int COR_E_ARGUMENTOUTOFRANGE = unchecked((int)0x80131502);
+ internal const int COR_E_ARITHMETIC = unchecked((int)0x80070216);
+ internal const int COR_E_ARRAYTYPEMISMATCH = unchecked((int)0x80131503);
+ internal const int COR_E_BADIMAGEFORMAT = unchecked((int)0x8007000B);
+ internal const int COR_E_TYPEUNLOADED = unchecked((int)0x80131013);
+ internal const int COR_E_CANNOTUNLOADAPPDOMAIN = unchecked((int)0x80131015);
+ internal const int COR_E_COMEMULATE = unchecked((int)0x80131535);
+ internal const int COR_E_CONTEXTMARSHAL = unchecked((int)0x80131504);
internal const int COR_E_DATAMISALIGNED = unchecked((int)0x80131541);
- internal const int COR_E_TIMEOUT = unchecked((int)0x80131505);
- internal const int COR_E_CUSTOMATTRIBUTEFORMAT = unchecked((int)0x80131605);
+ internal const int COR_E_TIMEOUT = unchecked((int)0x80131505);
+ internal const int COR_E_CUSTOMATTRIBUTEFORMAT = unchecked((int)0x80131605);
internal const int COR_E_DIVIDEBYZERO = unchecked((int)0x80020012); // DISP_E_DIVBYZERO
internal const int COR_E_DUPLICATEWAITOBJECT = unchecked((int)0x80131529);
- internal const int COR_E_EXCEPTION = unchecked((int)0x80131500);
- internal const int COR_E_EXECUTIONENGINE = unchecked((int)0x80131506);
- internal const int COR_E_FIELDACCESS = unchecked((int)0x80131507);
- internal const int COR_E_FORMAT = unchecked((int)0x80131537);
- internal const int COR_E_INDEXOUTOFRANGE = unchecked((int)0x80131508);
+ internal const int COR_E_EXCEPTION = unchecked((int)0x80131500);
+ internal const int COR_E_EXECUTIONENGINE = unchecked((int)0x80131506);
+ internal const int COR_E_FIELDACCESS = unchecked((int)0x80131507);
+ internal const int COR_E_FORMAT = unchecked((int)0x80131537);
+ internal const int COR_E_INDEXOUTOFRANGE = unchecked((int)0x80131508);
internal const int COR_E_INSUFFICIENTMEMORY = unchecked((int)0x8013153D);
internal const int COR_E_INSUFFICIENTEXECUTIONSTACK = unchecked((int)0x80131578);
- internal const int COR_E_INVALIDCAST = unchecked((int)0x80004002);
+ internal const int COR_E_INVALIDCAST = unchecked((int)0x80004002);
internal const int COR_E_INVALIDCOMOBJECT = unchecked((int)0x80131527);
- internal const int COR_E_INVALIDFILTERCRITERIA = unchecked((int)0x80131601);
- internal const int COR_E_INVALIDOLEVARIANTTYPE = unchecked((int)0x80131531);
- internal const int COR_E_INVALIDOPERATION = unchecked((int)0x80131509);
- internal const int COR_E_INVALIDPROGRAM = unchecked((int)0x8013153A);
+ internal const int COR_E_INVALIDFILTERCRITERIA = unchecked((int)0x80131601);
+ internal const int COR_E_INVALIDOLEVARIANTTYPE = unchecked((int)0x80131531);
+ internal const int COR_E_INVALIDOPERATION = unchecked((int)0x80131509);
+ internal const int COR_E_INVALIDPROGRAM = unchecked((int)0x8013153A);
internal const int COR_E_KEYNOTFOUND = unchecked((int)0x80131577);
- internal const int COR_E_MARSHALDIRECTIVE = unchecked((int)0x80131535);
- internal const int COR_E_MEMBERACCESS = unchecked((int)0x8013151A);
- internal const int COR_E_METHODACCESS = unchecked((int)0x80131510);
- internal const int COR_E_MISSINGFIELD = unchecked((int)0x80131511);
+ internal const int COR_E_MARSHALDIRECTIVE = unchecked((int)0x80131535);
+ internal const int COR_E_MEMBERACCESS = unchecked((int)0x8013151A);
+ internal const int COR_E_METHODACCESS = unchecked((int)0x80131510);
+ internal const int COR_E_MISSINGFIELD = unchecked((int)0x80131511);
internal const int COR_E_MISSINGMANIFESTRESOURCE = unchecked((int)0x80131532);
internal const int COR_E_MISSINGMEMBER = unchecked((int)0x80131512);
- internal const int COR_E_MISSINGMETHOD = unchecked((int)0x80131513);
+ internal const int COR_E_MISSINGMETHOD = unchecked((int)0x80131513);
internal const int COR_E_MISSINGSATELLITEASSEMBLY = unchecked((int)0x80131536);
- internal const int COR_E_MULTICASTNOTSUPPORTED = unchecked((int)0x80131514);
+ internal const int COR_E_MULTICASTNOTSUPPORTED = unchecked((int)0x80131514);
internal const int COR_E_NOTFINITENUMBER = unchecked((int)0x80131528);
- internal const int COR_E_PLATFORMNOTSUPPORTED = unchecked((int)0x80131539);
- internal const int COR_E_NOTSUPPORTED = unchecked((int)0x80131515);
- internal const int COR_E_NULLREFERENCE = unchecked((int)0x80004003);
+ internal const int COR_E_PLATFORMNOTSUPPORTED = unchecked((int)0x80131539);
+ internal const int COR_E_NOTSUPPORTED = unchecked((int)0x80131515);
+ internal const int COR_E_NULLREFERENCE = unchecked((int)0x80004003);
internal const int COR_E_OBJECTDISPOSED = unchecked((int)0x80131622);
internal const int COR_E_OPERATIONCANCELED = unchecked((int)0x8013153B);
- internal const int COR_E_OUTOFMEMORY = unchecked((int)0x8007000E);
- internal const int COR_E_OVERFLOW = unchecked((int)0x80131516);
- internal const int COR_E_RANK = unchecked((int)0x80131517);
- internal const int COR_E_REFLECTIONTYPELOAD = unchecked((int)0x80131602);
+ internal const int COR_E_OUTOFMEMORY = unchecked((int)0x8007000E);
+ internal const int COR_E_OVERFLOW = unchecked((int)0x80131516);
+ internal const int COR_E_RANK = unchecked((int)0x80131517);
+ internal const int COR_E_REFLECTIONTYPELOAD = unchecked((int)0x80131602);
internal const int COR_E_RUNTIMEWRAPPED = unchecked((int)0x8013153E);
- internal const int COR_E_SAFEARRAYRANKMISMATCH = unchecked((int)0x80131538);
- internal const int COR_E_SAFEARRAYTYPEMISMATCH = unchecked((int)0x80131533);
+ internal const int COR_E_SAFEARRAYRANKMISMATCH = unchecked((int)0x80131538);
+ internal const int COR_E_SAFEARRAYTYPEMISMATCH = unchecked((int)0x80131533);
internal const int COR_E_SAFEHANDLEMISSINGATTRIBUTE = unchecked((int)0x80131623);
- internal const int COR_E_SECURITY = unchecked((int)0x8013150A);
+ internal const int COR_E_SECURITY = unchecked((int)0x8013150A);
internal const int COR_E_SERIALIZATION = unchecked((int)0x8013150C);
internal const int COR_E_SEMAPHOREFULL = unchecked((int)0x8013152B);
internal const int COR_E_WAITHANDLECANNOTBEOPENED = unchecked((int)0x8013152C);
internal const int COR_E_ABANDONEDMUTEX = unchecked((int)0x8013152D);
- internal const int COR_E_STACKOVERFLOW = unchecked((int)0x800703E9);
- internal const int COR_E_SYNCHRONIZATIONLOCK = unchecked((int)0x80131518);
- internal const int COR_E_SYSTEM = unchecked((int)0x80131501);
- internal const int COR_E_TARGET = unchecked((int)0x80131603);
- internal const int COR_E_TARGETINVOCATION = unchecked((int)0x80131604);
+ internal const int COR_E_STACKOVERFLOW = unchecked((int)0x800703E9);
+ internal const int COR_E_SYNCHRONIZATIONLOCK = unchecked((int)0x80131518);
+ internal const int COR_E_SYSTEM = unchecked((int)0x80131501);
+ internal const int COR_E_TARGET = unchecked((int)0x80131603);
+ internal const int COR_E_TARGETINVOCATION = unchecked((int)0x80131604);
internal const int COR_E_TARGETPARAMCOUNT = unchecked((int)0x8002000e);
- internal const int COR_E_THREADABORTED = unchecked((int)0x80131530);
- internal const int COR_E_THREADINTERRUPTED = unchecked((int)0x80131519);
- internal const int COR_E_THREADSTATE = unchecked((int)0x80131520);
- internal const int COR_E_THREADSTOP = unchecked((int)0x80131521);
+ internal const int COR_E_THREADABORTED = unchecked((int)0x80131530);
+ internal const int COR_E_THREADINTERRUPTED = unchecked((int)0x80131519);
+ internal const int COR_E_THREADSTATE = unchecked((int)0x80131520);
+ internal const int COR_E_THREADSTOP = unchecked((int)0x80131521);
internal const int COR_E_THREADSTART = unchecked((int)0x80131525);
internal const int COR_E_TYPEACCESS = unchecked((int)0x80131543);
- internal const int COR_E_TYPEINITIALIZATION = unchecked((int)0x80131534);
- internal const int COR_E_TYPELOAD = unchecked((int)0x80131522);
- internal const int COR_E_ENTRYPOINTNOTFOUND = unchecked((int)0x80131523);
- internal const int COR_E_DLLNOTFOUND = unchecked((int)0x80131524);
- internal const int COR_E_UNAUTHORIZEDACCESS = unchecked((int)0x80070005);
- internal const int COR_E_UNSUPPORTEDFORMAT = unchecked((int)0x80131523);
- internal const int COR_E_VERIFICATION = unchecked((int)0x8013150D);
+ internal const int COR_E_TYPEINITIALIZATION = unchecked((int)0x80131534);
+ internal const int COR_E_TYPELOAD = unchecked((int)0x80131522);
+ internal const int COR_E_ENTRYPOINTNOTFOUND = unchecked((int)0x80131523);
+ internal const int COR_E_DLLNOTFOUND = unchecked((int)0x80131524);
+ internal const int COR_E_UNAUTHORIZEDACCESS = unchecked((int)0x80070005);
+ internal const int COR_E_UNSUPPORTEDFORMAT = unchecked((int)0x80131523);
+ internal const int COR_E_VERIFICATION = unchecked((int)0x8013150D);
internal const int COR_E_HOSTPROTECTION = unchecked((int)0x80131640);
internal const int CORSEC_E_MIN_GRANT_FAIL = unchecked((int)0x80131417);
internal const int CORSEC_E_NO_EXEC_PERM = unchecked((int)0x80131418);
internal const int CORSEC_E_POLICY_EXCEPTION = unchecked((int)0x80131416);
internal const int CORSEC_E_XMLSYNTAX = unchecked((int)0x80131418);
- internal const int NTE_FAIL = unchecked((int)0x80090020);
+ internal const int NTE_FAIL = unchecked((int)0x80090020);
internal const int CORSEC_E_CRYPTO = unchecked((int)0x80131430);
internal const int CORSEC_E_CRYPTO_UNEX_OPER = unchecked((int)0x80131431);
internal const int DISP_E_OVERFLOW = unchecked((int)0x8002000a);
diff --git a/src/mscorlib/src/mscorlib.Friends.cs b/src/mscorlib/src/mscorlib.Friends.cs
index 0e57812638..b02b4829d9 100644
--- a/src/mscorlib/src/mscorlib.Friends.cs
+++ b/src/mscorlib/src/mscorlib.Friends.cs
@@ -1,17 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System.Runtime.CompilerServices;
-// We need this to be able to typeforward to internal types
-[assembly: InternalsVisibleTo("mscorlib, PublicKey=00240000048000009400000006020000002400005253413100040000010001008d56c76f9e8649383049f383c44be0ec204181822a6c31cf5eb7ef486944d032188ea1d3920763712ccb12d75fb77e9811149e6148e5d32fbaab37611c1878ddc19e20ef135d0cb2cff2bfec3d115810c3d9069638fe4be215dbf795861920e5ab6f7db2e2ceef136ac23d5dd2bf031700aec232f6c6b1c785b4305c123b37ab", AllInternalsVisible=false)]
+using System.Runtime.CompilerServices;
// For now we are only moving to using this file over AssemblyAttributes.cspp in CoreSys, ideally we would move away from the centralized
// AssemblyAttributes.cspp model for the other build types at a future point in time.
// Depends on things like SuppressUnmanagedCodeAttribute and WindowsRuntimeImportAttribute
-[assembly: InternalsVisibleTo("System.Runtime.WindowsRuntime, PublicKey=00000000000000000400000000000000", AllInternalsVisible=false)]
+[assembly: InternalsVisibleTo("System.Runtime.WindowsRuntime, PublicKey=00000000000000000400000000000000", AllInternalsVisible = false)]
// Depends on WindowsRuntimeImportAttribute
-[assembly: InternalsVisibleTo("System.Runtime.WindowsRuntime.UI.Xaml, PublicKey=00000000000000000400000000000000", AllInternalsVisible=false)]
+[assembly: InternalsVisibleTo("System.Runtime.WindowsRuntime.UI.Xaml, PublicKey=00000000000000000400000000000000", AllInternalsVisible = false)]
diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h
index d0b78e942f..8430ea9899 100644
--- a/src/pal/inc/pal.h
+++ b/src/pal/inc/pal.h
@@ -538,7 +538,6 @@ PAL_ProbeMemory(
BOOL fWriteAccess);
/******************* winuser.h Entrypoints *******************************/
-
PALIMPORT
LPSTR
PALAPI
@@ -1782,6 +1781,7 @@ typedef struct _CONTEXT {
UCHAR ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
+ ULONG ResumeEsp;
} CONTEXT, *PCONTEXT, *LPCONTEXT;
// To support saving and loading xmm register context we need to know the offset in the ExtendedRegisters
@@ -1793,6 +1793,15 @@ typedef struct _CONTEXT {
// support any other values in the ExtendedRegisters) but we might as well be as accurate as we can.
#define CONTEXT_EXREG_XMM_OFFSET 160
+typedef struct _KNONVOLATILE_CONTEXT {
+
+ DWORD Edi;
+ DWORD Esi;
+ DWORD Ebx;
+ DWORD Ebp;
+
+} KNONVOLATILE_CONTEXT, *PKNONVOLATILE_CONTEXT;
+
typedef struct _KNONVOLATILE_CONTEXT_POINTERS {
// The ordering of these fields should be aligned with that
@@ -2526,6 +2535,16 @@ PAL_GetLogicalCpuCountFromOS(VOID);
PALIMPORT
size_t
PALAPI
+PAL_GetRestrictedPhysicalMemoryLimit(VOID);
+
+PALIMPORT
+BOOL
+PALAPI
+PAL_GetWorkingSetSize(size_t* val);
+
+PALIMPORT
+size_t
+PALAPI
PAL_GetLogicalProcessorCacheSizeFromOS(VOID);
typedef BOOL (*ReadMemoryWordCallback)(SIZE_T address, SIZE_T *value);
@@ -4118,6 +4137,12 @@ QueryThreadCycleTime(
IN HANDLE ThreadHandle,
OUT PULONG64 CycleTime);
+PALIMPORT
+INT
+PALAPI
+PAL_nanosleep(
+ IN long timeInNs);
+
#ifndef FEATURE_PAL_SXS
typedef LONG (PALAPI *PTOP_LEVEL_EXCEPTION_FILTER)(
@@ -4723,18 +4748,6 @@ typedef POSVERSIONINFOEXA POSVERSIONINFOEX;
typedef LPOSVERSIONINFOEXA LPOSVERSIONINFOEX;
#endif
-PALIMPORT
-BOOL
-PALAPI
-GetVersionExW(
- IN OUT LPOSVERSIONINFOW lpVersionInformation);
-
-#ifdef UNICODE
-#define GetVersionEx GetVersionExW
-#else
-#define GetVersionEx GetVersionExA
-#endif
-
#define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian
diff --git a/src/pal/inc/pal_mstypes.h b/src/pal/inc/pal_mstypes.h
index 1f5c11def4..0ca2871f2b 100644
--- a/src/pal/inc/pal_mstypes.h
+++ b/src/pal/inc/pal_mstypes.h
@@ -75,7 +75,7 @@ extern "C" {
#endif // !defined(__i386__)
-#define CALLBACK __stdcall
+#define CALLBACK __cdecl
#if !defined(_declspec)
#define _declspec(e) __declspec(e)
@@ -105,7 +105,7 @@ extern "C" {
#endif
-#define PALAPI __stdcall
+#define PALAPI __cdecl
#define PALAPIV __cdecl
////////////////////////////////////////////////////////////////////////
diff --git a/src/pal/inc/palprivate.h b/src/pal/inc/palprivate.h
index 2677dd6bdd..554a5028ad 100644
--- a/src/pal/inc/palprivate.h
+++ b/src/pal/inc/palprivate.h
@@ -293,12 +293,6 @@ FreeEnvironmentStringsA(
PALIMPORT
BOOL
PALAPI
-GetVersionExA(
- IN OUT LPOSVERSIONINFOA lpVersionInformation);
-
-PALIMPORT
-BOOL
-PALAPI
RemoveDirectoryA(
IN LPCSTR lpPathName);
diff --git a/src/pal/inc/rt/palrt.h b/src/pal/inc/rt/palrt.h
index 059d3a68a5..51f90b9163 100644
--- a/src/pal/inc/rt/palrt.h
+++ b/src/pal/inc/rt/palrt.h
@@ -205,9 +205,9 @@ inline void *__cdecl operator new(size_t, void *_P)
#endif // DEBUG
-#define NTAPI __stdcall
-#define WINAPI __stdcall
-#define CALLBACK __stdcall
+#define NTAPI __cdecl
+#define WINAPI __cdecl
+#define CALLBACK __cdecl
#define NTSYSAPI
#define _WINNT_
@@ -1083,17 +1083,6 @@ typename std::remove_reference<T>::type&& move( T&& t );
typedef DWORD OLE_COLOR;
-typedef union __m128i {
- __int8 m128i_i8[16];
- __int16 m128i_i16[8];
- __int32 m128i_i32[4];
- __int64 m128i_i64[2];
- unsigned __int8 m128i_u8[16];
- unsigned __int16 m128i_u16[8];
- unsigned __int32 m128i_u32[4];
- unsigned __int64 m128i_u64[2];
-} __m128i;
-
#define PF_COMPARE_EXCHANGE_DOUBLE 2
typedef VOID (NTAPI * WAITORTIMERCALLBACKFUNC) (PVOID, BOOLEAN );
@@ -1110,7 +1099,7 @@ typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY;
-typedef VOID (__stdcall *WAITORTIMERCALLBACK)(PVOID, BOOLEAN);
+typedef VOID (NTAPI *WAITORTIMERCALLBACK)(PVOID, BOOLEAN);
// PORTABILITY_ASSERT and PORTABILITY_WARNING macros are meant to be used to
// mark places in the code that needs attention for portability. The usual
@@ -1491,17 +1480,13 @@ typedef struct _DISPATCHER_CONTEXT {
#elif defined(_X86_)
-typedef struct _EXCEPTION_REGISTRATION_RECORD {
- struct _EXCEPTION_REGISTRATION_RECORD *Next;
- PEXCEPTION_ROUTINE Handler;
-} EXCEPTION_REGISTRATION_RECORD;
-
typedef struct _DISPATCHER_CONTEXT {
DWORD ControlPc;
DWORD ImageBase;
PRUNTIME_FUNCTION FunctionEntry;
DWORD EstablisherFrame;
DWORD TargetIp;
+ PKNONVOLATILE_CONTEXT CurrentNonVolatileContextRecord;
PCONTEXT ContextRecord;
PEXCEPTION_ROUTINE LanguageHandler;
PVOID HandlerData;
diff --git a/src/pal/inc/rt/xmmintrin.h b/src/pal/inc/rt/xmmintrin.h
index 5401fabc13..1a670bd75a 100644
--- a/src/pal/inc/rt/xmmintrin.h
+++ b/src/pal/inc/rt/xmmintrin.h
@@ -2,4 +2,115 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-#include "palrt.h"
+// From llvm-3.9/clang-3.9.1 xmmintrin.h:
+
+/*===---- xmmintrin.h - SSE intrinsics -------------------------------------===
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+*
+*===-----------------------------------------------------------------------===
+*/
+
+#ifdef __clang__
+
+typedef float __m128 __attribute__((__vector_size__(16)));
+
+/* Define the default attributes for the functions in this file. */
+#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
+
+/// \brief Loads a 128-bit floating-point vector of [4 x float] from an aligned
+/// memory location.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the \c VMOVAPS / MOVAPS instruction.
+///
+/// \param __p
+/// A pointer to a 128-bit memory location. The address of the memory
+/// location has to be 128-bit aligned.
+/// \returns A 128-bit vector of [4 x float] containing the loaded valus.
+static __inline__ __m128 __DEFAULT_FN_ATTRS
+_mm_load_ps(const float *__p)
+{
+ return *(__m128*)__p;
+}
+
+/// \brief Loads a 128-bit floating-point vector of [4 x float] from an
+/// unaligned memory location.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the \c VMOVUPS / MOVUPS instruction.
+///
+/// \param __p
+/// A pointer to a 128-bit memory location. The address of the memory
+/// location does not have to be aligned.
+/// \returns A 128-bit vector of [4 x float] containing the loaded values.
+static __inline__ __m128 __DEFAULT_FN_ATTRS
+_mm_loadu_ps(const float *__p)
+{
+ struct __loadu_ps
+ {
+ __m128 __v;
+ } __attribute__((__packed__, __may_alias__));
+ return ((struct __loadu_ps*)__p)->__v;
+}
+
+/// \brief Stores float values from a 128-bit vector of [4 x float] to an
+/// unaligned memory location.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to the \c VMOVUPS / MOVUPS instruction.
+///
+/// \param __p
+/// A pointer to a 128-bit memory location. The address of the memory
+/// location does not have to be aligned.
+/// \param __a
+/// A 128-bit vector of [4 x float] containing the values to be stored.
+static __inline__ void __DEFAULT_FN_ATTRS
+_mm_storeu_ps(float *__p, __m128 __a)
+{
+ struct __storeu_ps
+ {
+ __m128 __v;
+ } __attribute__((__packed__, __may_alias__));
+ ((struct __storeu_ps*)__p)->__v = __a;
+}
+
+/// \brief Stores the lower 32 bits of a 128-bit vector of [4 x float] into
+/// four contiguous elements in an aligned memory location.
+///
+/// \headerfile <x86intrin.h>
+///
+/// This intrinsic corresponds to \c VMOVAPS / MOVAPS + \c shuffling
+/// instruction.
+///
+/// \param __p
+/// A pointer to a 128-bit memory location.
+/// \param __a
+/// A 128-bit vector of [4 x float] whose lower 32 bits are stored to each
+/// of the four contiguous elements pointed by __p.
+static __inline__ void __DEFAULT_FN_ATTRS
+_mm_store_ps(float *__p, __m128 __a)
+{
+ *(__m128*)__p = __a;
+}
+
+#endif // __clang__
diff --git a/src/pal/inc/unixasmmacrosamd64.inc b/src/pal/inc/unixasmmacrosamd64.inc
index c3321ce598..040ade1f5c 100644
--- a/src/pal/inc/unixasmmacrosamd64.inc
+++ b/src/pal/inc/unixasmmacrosamd64.inc
@@ -55,6 +55,15 @@ C_FUNC(\Name\()_End):
LEAF_END \Name, \Section
.endm
+.macro NOP_6_BYTE
+ .byte 0x66
+ .byte 0x0F
+ .byte 0x1F
+ .byte 0x44
+ .byte 0x00
+ .byte 0x00
+.endm
+
.macro NOP_3_BYTE
nop dword ptr [rax]
.endm
diff --git a/src/pal/inc/unixasmmacrosarm64.inc b/src/pal/inc/unixasmmacrosarm64.inc
index 359f27f878..f0c4a5ebfe 100644
--- a/src/pal/inc/unixasmmacrosarm64.inc
+++ b/src/pal/inc/unixasmmacrosarm64.inc
@@ -31,8 +31,8 @@ C_FUNC(\Name):
.endm
.macro LEAF_END_MARKED Name, Section
- .global C_FUNC(\Name\()_End)
C_FUNC(\Name\()_End):
+ .global C_FUNC(\Name\()_End)
LEAF_END \Name, \Section
.endm
@@ -43,45 +43,60 @@ C_FUNC(\Name\()_End):
.macro PROLOG_STACK_ALLOC Size
sub sp, sp, \Size
- .cfi_adjust_cfa_offset \Size
.endm
.macro EPILOG_STACK_FREE Size
add sp, sp, \Size
+ .cfi_adjust_cfa_offset -\Size
.endm
.macro EPILOG_STACK_RESTORE
mov sp, fp
+ .cfi_restore sp
.endm
.macro PROLOG_SAVE_REG reg, ofs
str \reg, [sp, \ofs]
+ .cfi_rel_offset \reg, \ofs
.endm
.macro PROLOG_SAVE_REG_PAIR reg1, reg2, ofs
stp \reg1, \reg2, [sp, \ofs]
+ .cfi_rel_offset \reg1, \ofs
+ .cfi_rel_offset \reg2, \ofs + 8
.ifc \reg1, fp
mov fp, sp
+ .cfi_def_cfa_register fp
.endif
.endm
.macro PROLOG_SAVE_REG_PAIR_INDEXED reg1, reg2, ofs
stp \reg1, \reg2, [sp, \ofs]!
+ .cfi_adjust_cfa_offset -\ofs
+ .cfi_rel_offset \reg1, 0
+ .cfi_rel_offset \reg2, 8
.ifc \reg1, fp
mov fp, sp
+ .cfi_def_cfa_register fp
.endif
.endm
.macro EPILOG_RESTORE_REG reg, ofs
ldr \reg, [sp, \ofs]
+ .cfi_restore \reg1
.endm
.macro EPILOG_RESTORE_REG_PAIR reg1, reg2, ofs
ldp \reg1, \reg2, [sp, \ofs]
+ .cfi_restore \reg1
+ .cfi_restore \reg2
.endm
.macro EPILOG_RESTORE_REG_PAIR_INDEXED reg1, reg2, ofs
ldp \reg1, \reg2, [sp], \ofs
+ .cfi_restore \reg1
+ .cfi_restore \reg2
+ .cfi_adjust_cfa_offset -\ofs
.endm
.macro EPILOG_RETURN
@@ -94,14 +109,14 @@ C_FUNC(\Name\()_End):
//-----------------------------------------------------------------------------
// Define the prolog for a TransitionFrame-based method. This macro should be called first in the method and
-// comprises the entire prolog (i.e. don't modify SP after calling this).The locals must be 8 byte aligned
+// comprises the entire prolog (i.e. don't modify SP after calling this).The locals must be 8 byte aligned
//
// Stack layout:
//
// (stack parameters)
// ...
// fp
-// lr
+// lr
// CalleeSavedRegisters::x28
// CalleeSavedRegisters::x27
// CalleeSavedRegisters::x26
@@ -133,6 +148,7 @@ C_FUNC(\Name\()_End):
.macro PROLOG_WITH_TRANSITION_BLOCK extraLocals = 0, SaveFPArgs = 1
__PWTB_FloatArgumentRegisters = \extraLocals
+ __PWTB_SaveFPArgs = \SaveFPArgs
.if ((__PWTB_FloatArgumentRegisters % 16) != 0)
__PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
@@ -140,50 +156,51 @@ C_FUNC(\Name\()_End):
__PWTB_TransitionBlock = __PWTB_FloatArgumentRegisters
- .if \SaveFPArgs > 0
+ .if (__PWTB_SaveFPArgs == 1)
__PWTB_TransitionBlock = __PWTB_TransitionBlock + SIZEOF__FloatArgumentRegisters
.endif
__PWTB_StackAlloc = __PWTB_TransitionBlock
- __PWTB_ArgumentRegisters = __PWTB_StackAlloc + 96
-
- PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, #-160
- // Spill callee saved registers
- PROLOG_SAVE_REG_PAIR x19, x20, #16
- PROLOG_SAVE_REG_PAIR x21, x22, #32
- PROLOG_SAVE_REG_PAIR x23, x24, #48
- PROLOG_SAVE_REG_PAIR x25, x26, #64
- PROLOG_SAVE_REG_PAIR x27, x28, #80
-
+ __PWTB_ArgumentRegisters = __PWTB_StackAlloc + 96
+
+ PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -176
+ // Spill callee saved registers
+ PROLOG_SAVE_REG_PAIR x19, x20, 16
+ PROLOG_SAVE_REG_PAIR x21, x22, 32
+ PROLOG_SAVE_REG_PAIR x23, x24, 48
+ PROLOG_SAVE_REG_PAIR x25, x26, 64
+ PROLOG_SAVE_REG_PAIR x27, x28, 80
+
// Allocate space for the rest of the frame
PROLOG_STACK_ALLOC __PWTB_StackAlloc
-
+
// Spill argument registers.
SAVE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters
- .if \SaveFPArgs > 0
+ .if (__PWTB_SaveFPArgs == 1)
SAVE_FLOAT_ARGUMENT_REGISTERS sp, \extraLocals
.endif
.endm
//-----------------------------------------------------------------------------
-// The Following sets of SAVE_*_REGISTERS expect the memory to be reserved and
+// The Following sets of SAVE_*_REGISTERS expect the memory to be reserved and
// base address to be passed in $reg
//
// Reserve 64 bytes of memory before calling SAVE_ARGUMENT_REGISTERS
-.macro SAVE_ARGUMENT_REGISTERS reg, ofs
+.macro SAVE_ARGUMENT_REGISTERS reg, ofs
stp x0, x1, [\reg, #(\ofs)]
stp x2, x3, [\reg, #(\ofs + 16)]
stp x4, x5, [\reg, #(\ofs + 32)]
stp x6, x7, [\reg, #(\ofs + 48)]
+ str x8, [\reg, #(\ofs + 64)]
.endm
// Reserve 64 bytes of memory before calling SAVE_FLOAT_ARGUMENT_REGISTERS
-.macro SAVE_FLOAT_ARGUMENT_REGISTERS reg, ofs
+.macro SAVE_FLOAT_ARGUMENT_REGISTERS reg, ofs
stp d0, d1, [\reg, #(\ofs)]
stp d2, d3, [\reg, #(\ofs + 16)]
@@ -192,16 +209,17 @@ C_FUNC(\Name\()_End):
.endm
-.macro RESTORE_ARGUMENT_REGISTERS reg, ofs
+.macro RESTORE_ARGUMENT_REGISTERS reg, ofs
ldp x0, x1, [\reg, #(\ofs)]
ldp x2, x3, [\reg, #(\ofs + 16)]
ldp x4, x5, [\reg, #(\ofs + 32)]
ldp x6, x7, [\reg, #(\ofs + 48)]
+ ldr x8, [\reg, #(\ofs + 64)]
.endm
-.macro RESTORE_FLOAT_ARGUMENT_REGISTERS reg, ofs
+.macro RESTORE_FLOAT_ARGUMENT_REGISTERS reg, ofs
ldp d0, d1, [\reg, #(\ofs)]
ldp d2, d3, [\reg, #(\ofs + 16)]
@@ -210,46 +228,52 @@ C_FUNC(\Name\()_End):
.endm
+.macro EPILOG_BRANCH Target
+ b \Target
+.endm
+
.macro EPILOG_BRANCH_REG reg
br \reg
.endm
-//-----------------------------------------------------------------------------
-// Provides a matching epilog to PROLOG_WITH_TRANSITION_BLOCK and ends by preparing for tail-calling.
-// Since this is a tail call argument registers are restored.
-//
-.macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL extraLocals = 0, SaveFPArgs =1
- __PWTB_FloatArgumentRegisters = \extraLocals
+.macro EPILOG_WITH_TRANSITION_BLOCK_RETURN
- .if ((__PWTB_FloatArgumentRegisters % 16) != 0)
- __PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
- .endif
+ EPILOG_STACK_FREE __PWTB_StackAlloc
- __PWTB_TransitionBlock = __PWTB_FloatArgumentRegisters
+ EPILOG_RESTORE_REG_PAIR x19, x20, 16
+ EPILOG_RESTORE_REG_PAIR x21, x22, 32
+ EPILOG_RESTORE_REG_PAIR x23, x24, 48
+ EPILOG_RESTORE_REG_PAIR x25, x26, 64
+ EPILOG_RESTORE_REG_PAIR x27, x28, 80
+ EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 176
+ ret
- .if \SaveFPArgs > 0
- __PWTB_TransitionBlock = __PWTB_TransitionBlock + SIZEOF__FloatArgumentRegisters
- .endif
+.endm
- __PWTB_StackAlloc = __PWTB_TransitionBlock
- __PWTB_ArgumentRegisters = __PWTB_StackAlloc + 96
- .if \SaveFPArgs > 0
- RESTORE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters
+//-----------------------------------------------------------------------------
+// Provides a matching epilog to PROLOG_WITH_TRANSITION_BLOCK and ends by preparing for tail-calling.
+// Since this is a tail call argument registers are restored.
+//
+.macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
+
+ .if (__PWTB_SaveFPArgs == 1)
+ RESTORE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters
.endif
RESTORE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters
+
EPILOG_STACK_FREE __PWTB_StackAlloc
-
- EPILOG_RESTORE_REG_PAIR x19, x20, #16
- EPILOG_RESTORE_REG_PAIR x21, x22, #32
- EPILOG_RESTORE_REG_PAIR x23, x24, #48
- EPILOG_RESTORE_REG_PAIR x25, x26, #64
- EPILOG_RESTORE_REG_PAIR x27, x28, #80
- EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, #160
+
+ EPILOG_RESTORE_REG_PAIR x19, x20, 16
+ EPILOG_RESTORE_REG_PAIR x21, x22, 32
+ EPILOG_RESTORE_REG_PAIR x23, x24, 48
+ EPILOG_RESTORE_REG_PAIR x25, x26, 64
+ EPILOG_RESTORE_REG_PAIR x27, x28, 80
+ EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 176
.endm
@@ -273,8 +297,8 @@ __RedirectionFuncName SETS "|?RedirectedHandledJITCaseFor":CC:"$reason":CC:"@Thr
IMPORT $__RedirectionFuncName
NESTED_ENTRY $__RedirectionStubFuncName
- PROLOG_SAVE_REG_PAIR fp, lr, #-16
- sub sp, sp, #16 // stack slot for CONTEXT * and padding
+ PROLOG_SAVE_REG_PAIR fp, lr, -16
+ sub sp, sp, #16 // stack slot for CONTEXT * and padding
//REDIRECTSTUB_SP_OFFSET_CONTEXT is defined in asmconstants.h and is used in GetCONTEXTFromRedirectedStubStackFrame
//If CONTEXT is not saved at 0 offset from SP it must be changed as well.
diff --git a/src/pal/inc/unixasmmacrosx86.inc b/src/pal/inc/unixasmmacrosx86.inc
index 77b3a63484..7730505bc3 100644
--- a/src/pal/inc/unixasmmacrosx86.inc
+++ b/src/pal/inc/unixasmmacrosx86.inc
@@ -66,6 +66,37 @@ C_FUNC(\Name\()_End):
pop ebp
.endm
+.macro ESP_PROLOG_BEG
+.endm
+
+.macro ESP_PROLOG_PUSH Reg
+ PROLOG_PUSH \Reg
+.endm
+
+.macro ESP_PROLOG_ALLOC Size
+ sub esp, \Size
+ .cfi_adjust_cfa_offset \Size
+.endm
+
+.macro ESP_PROLOG_END
+ .cfi_def_cfa_register esp
+.endm
+
+.macro ESP_EPILOG_BEG
+.endm
+
+.macro ESP_EPILOG_POP Reg
+ EPILOG_POP \Reg
+.endm
+
+.macro ESP_EPILOG_FREE Size
+ add esp, \Size
+ .cfi_adjust_cfa_offset -\Size
+.endm
+
+.macro ESP_EPILOG_END
+.endm
+
.macro PREPARE_EXTERNAL_VAR Name, Reg
.att_syntax
call 0f
diff --git a/src/pal/prebuilt/inc/asm_version.h b/src/pal/prebuilt/inc/asm_version.h
index 977c8dd188..44e09c0e8e 100644
--- a/src/pal/prebuilt/inc/asm_version.h
+++ b/src/pal/prebuilt/inc/asm_version.h
@@ -1,7 +1,7 @@
// 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.
-#if defined(SILVERLIGHT) || defined(FEATURE_CORECLR)
+#if defined(SILVERLIGHT)
#if defined(FEATURE_CORESYSTEM)
#define asm_rmj 4
#define asm_rmm 0
diff --git a/src/pal/prebuilt/inc/clrinternal.h b/src/pal/prebuilt/inc/clrinternal.h
index 673ae68470..647b899615 100644
--- a/src/pal/prebuilt/inc/clrinternal.h
+++ b/src/pal/prebuilt/inc/clrinternal.h
@@ -142,7 +142,7 @@ enum __MIDL___MIDL_itf_clrinternal_0000_0000_0001
CRST_DEBUG_ONLY_CHECK_FORBID_SUSPEND_THREAD = 0x200
} CrstFlags;
-typedef VOID ( __stdcall *PTLS_CALLBACK_FUNCTION )(
+typedef VOID ( WINAPI *PTLS_CALLBACK_FUNCTION )(
PVOID __MIDL____MIDL_itf_clrinternal_0000_00000000);
diff --git a/src/pal/prebuilt/inc/fusionpriv.h b/src/pal/prebuilt/inc/fusionpriv.h
deleted file mode 100644
index b0bca9e1f4..0000000000
--- a/src/pal/prebuilt/inc/fusionpriv.h
+++ /dev/null
@@ -1,2919 +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.
-
-
-
-/* this ALWAYS GENERATED file contains the definitions for the interfaces */
-
-
- /* File created by MIDL compiler version 8.00.0603 */
-/* @@MIDL_FILE_HEADING( ) */
-
-#pragma warning( disable: 4049 ) /* more than 64k source lines */
-
-
-/* verify that the <rpcndr.h> version is high enough to compile this file*/
-#ifndef __REQUIRED_RPCNDR_H_VERSION__
-#define __REQUIRED_RPCNDR_H_VERSION__ 475
-#endif
-
-#include "rpc.h"
-#include "rpcndr.h"
-
-#ifndef __RPCNDR_H_VERSION__
-#error this stub requires an updated version of <rpcndr.h>
-#endif // __RPCNDR_H_VERSION__
-
-#ifndef COM_NO_WINDOWS_H
-#include "windows.h"
-#include "ole2.h"
-#endif /*COM_NO_WINDOWS_H*/
-
-#ifndef __fusionpriv_h__
-#define __fusionpriv_h__
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-#pragma once
-#endif
-
-/* Forward Declarations */
-
-#ifndef __IHistoryAssembly_FWD_DEFINED__
-#define __IHistoryAssembly_FWD_DEFINED__
-typedef interface IHistoryAssembly IHistoryAssembly;
-
-#endif /* __IHistoryAssembly_FWD_DEFINED__ */
-
-
-#ifndef __IHistoryReader_FWD_DEFINED__
-#define __IHistoryReader_FWD_DEFINED__
-typedef interface IHistoryReader IHistoryReader;
-
-#endif /* __IHistoryReader_FWD_DEFINED__ */
-
-
-#ifndef __IFusionBindLog_FWD_DEFINED__
-#define __IFusionBindLog_FWD_DEFINED__
-typedef interface IFusionBindLog IFusionBindLog;
-
-#endif /* __IFusionBindLog_FWD_DEFINED__ */
-
-
-#ifndef __IAssemblyManifestImport_FWD_DEFINED__
-#define __IAssemblyManifestImport_FWD_DEFINED__
-typedef interface IAssemblyManifestImport IAssemblyManifestImport;
-
-#endif /* __IAssemblyManifestImport_FWD_DEFINED__ */
-
-
-#ifndef __IApplicationContext_FWD_DEFINED__
-#define __IApplicationContext_FWD_DEFINED__
-typedef interface IApplicationContext IApplicationContext;
-
-#endif /* __IApplicationContext_FWD_DEFINED__ */
-
-
-#ifndef __IAssemblyNameBinder_FWD_DEFINED__
-#define __IAssemblyNameBinder_FWD_DEFINED__
-typedef interface IAssemblyNameBinder IAssemblyNameBinder;
-
-#endif /* __IAssemblyNameBinder_FWD_DEFINED__ */
-
-
-#ifndef __IAssembly_FWD_DEFINED__
-#define __IAssembly_FWD_DEFINED__
-typedef interface IAssembly IAssembly;
-
-#endif /* __IAssembly_FWD_DEFINED__ */
-
-
-#ifndef __IAssemblyBindingClosureEnumerator_FWD_DEFINED__
-#define __IAssemblyBindingClosureEnumerator_FWD_DEFINED__
-typedef interface IAssemblyBindingClosureEnumerator IAssemblyBindingClosureEnumerator;
-
-#endif /* __IAssemblyBindingClosureEnumerator_FWD_DEFINED__ */
-
-
-#ifndef __IAssemblyBindingClosure_FWD_DEFINED__
-#define __IAssemblyBindingClosure_FWD_DEFINED__
-typedef interface IAssemblyBindingClosure IAssemblyBindingClosure;
-
-#endif /* __IAssemblyBindingClosure_FWD_DEFINED__ */
-
-
-#ifndef __IAssemblyBindSink_FWD_DEFINED__
-#define __IAssemblyBindSink_FWD_DEFINED__
-typedef interface IAssemblyBindSink IAssemblyBindSink;
-
-#endif /* __IAssemblyBindSink_FWD_DEFINED__ */
-
-
-#ifndef __IAssemblyBinding_FWD_DEFINED__
-#define __IAssemblyBinding_FWD_DEFINED__
-typedef interface IAssemblyBinding IAssemblyBinding;
-
-#endif /* __IAssemblyBinding_FWD_DEFINED__ */
-
-
-#ifndef __IAssemblyModuleImport_FWD_DEFINED__
-#define __IAssemblyModuleImport_FWD_DEFINED__
-typedef interface IAssemblyModuleImport IAssemblyModuleImport;
-
-#endif /* __IAssemblyModuleImport_FWD_DEFINED__ */
-
-
-#ifndef __IAssemblyScavenger_FWD_DEFINED__
-#define __IAssemblyScavenger_FWD_DEFINED__
-typedef interface IAssemblyScavenger IAssemblyScavenger;
-
-#endif /* __IAssemblyScavenger_FWD_DEFINED__ */
-
-
-#ifndef __ICodebaseList_FWD_DEFINED__
-#define __ICodebaseList_FWD_DEFINED__
-typedef interface ICodebaseList ICodebaseList;
-
-#endif /* __ICodebaseList_FWD_DEFINED__ */
-
-
-#ifndef __IDownloadMgr_FWD_DEFINED__
-#define __IDownloadMgr_FWD_DEFINED__
-typedef interface IDownloadMgr IDownloadMgr;
-
-#endif /* __IDownloadMgr_FWD_DEFINED__ */
-
-
-#ifndef __IHostAssembly_FWD_DEFINED__
-#define __IHostAssembly_FWD_DEFINED__
-typedef interface IHostAssembly IHostAssembly;
-
-#endif /* __IHostAssembly_FWD_DEFINED__ */
-
-
-#ifndef __IHostAssemblyModuleImport_FWD_DEFINED__
-#define __IHostAssemblyModuleImport_FWD_DEFINED__
-typedef interface IHostAssemblyModuleImport IHostAssemblyModuleImport;
-
-#endif /* __IHostAssemblyModuleImport_FWD_DEFINED__ */
-
-
-/* header files for imported files */
-#include "objidl.h"
-#include "oleidl.h"
-#include "fusion.h"
-
-#ifdef __cplusplus
-extern "C"{
-#endif
-
-
-/* interface __MIDL_itf_fusionpriv_0000_0000 */
-/* [local] */
-
-//=--------------------------------------------------------------------------=
-// fusionpriv.h
-//=--------------------------------------------------------------------------=
-
-//
-// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
-// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
-// PARTICULAR PURPOSE.
-//=--------------------------------------------------------------------------=
-
-#ifdef _MSC_VER
-#pragma comment(lib,"uuid.lib")
-#endif
-
-//---------------------------------------------------------------------------=
-// Fusion Interfaces.
-
-#if defined(_CLR_BLD) && !defined(FEATURE_FUSION)
-#error FEATURE_FUSION is not enabled, please do not include fusionpriv.h
-#endif
-#ifdef _MSC_VER
-#pragma once
-#endif
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-struct IMetaDataAssemblyImport;
-
-EXTERN_C const IID IID_IApplicationContext;
-EXTERN_C const IID IID_IAssembly;
-EXTERN_C const IID IID_IAssemblyBindSink;
-EXTERN_C const IID IID_IAssemblyBinding;
-EXTERN_C const IID IID_IAssemblyManifestImport;
-EXTERN_C const IID IID_IAssemblyModuleImport;
-EXTERN_C const IID IID_IHistoryAssembly;
-EXTERN_C const IID IID_IHistoryReader;
-EXTERN_C const IID IID_IMetaDataAssemblyImportControl;
-EXTERN_C const IID IID_IAssemblyScavenger;
-EXTERN_C const IID IID_IHostAssembly;
-EXTERN_C const IID IID_IHostAssemblyModuleImport;
-typedef /* [public] */
-enum __MIDL___MIDL_itf_fusionpriv_0000_0000_0001
- {
- ASM_BINDF_NONE = 0,
- ASM_BINDF_FORCE_CACHE_INSTALL = 0x1,
- ASM_BINDF_RFS_INTEGRITY_CHECK = 0x2,
- ASM_BINDF_RFS_MODULE_CHECK = 0x4,
- ASM_BINDF_BINPATH_PROBE_ONLY = 0x8,
- ASM_BINDF_PARENT_ASM_HINT = 0x20,
- ASM_BINDF_DISALLOW_APPLYPUBLISHERPOLICY = 0x40,
- ASM_BINDF_DISALLOW_APPBINDINGREDIRECTS = 0x80,
- ASM_BINDF_DISABLE_FX_UNIFICATION = 0x100,
- ASM_BINDF_DO_NOT_PROBE_NATIVE_IMAGE = 0x200,
- ASM_BINDF_DISABLE_DOWNLOAD = 0x400,
- ASM_BINDF_INSPECTION_ONLY = 0x800,
- ASM_BINDF_DISALLOW_APP_BASE_PROBING = 0x1000,
- ASM_BINDF_SUPPRESS_SECURITY_CHECKS = 0x2000
- } ASM_BIND_FLAGS;
-
-typedef
-enum tagDEVOVERRIDEMODE
- {
- DEVOVERRIDE_LOCAL = 0x1,
- DEVOVERRIDE_GLOBAL = 0x2
- } DEVOVERRIDEMODE;
-
-typedef
-enum tagWALK_LEVEL
- {
- LEVEL_STARTING = 0,
- LEVEL_WINRTCHECK = ( LEVEL_STARTING + 1 ) ,
- LEVEL_GACCHECK = ( LEVEL_WINRTCHECK + 1 ) ,
- LEVEL_COMPLETE = ( LEVEL_GACCHECK + 1 ) ,
- LEVEL_FXPREDICTED = ( LEVEL_COMPLETE + 1 ) ,
- LEVEL_FXPROBED = ( LEVEL_FXPREDICTED + 1 )
- } WALK_LEVEL;
-
-
-
-extern RPC_IF_HANDLE __MIDL_itf_fusionpriv_0000_0000_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_fusionpriv_0000_0000_v0_0_s_ifspec;
-
-#ifndef __IHistoryAssembly_INTERFACE_DEFINED__
-#define __IHistoryAssembly_INTERFACE_DEFINED__
-
-/* interface IHistoryAssembly */
-/* [unique][uuid][object][local] */
-
-
-EXTERN_C const IID IID_IHistoryAssembly;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("e6096a07-e188-4a49-8d50-2a0172a0d205")
- IHistoryAssembly : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetAssemblyName(
- /* [annotation][out] */
- __out LPWSTR wzAsmName,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetPublicKeyToken(
- /* [annotation][out] */
- __out LPWSTR wzPublicKeyToken,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetCulture(
- /* [annotation][out] */
- __out LPWSTR wzCulture,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetReferenceVersion(
- /* [annotation][out] */
- __out LPWSTR wzVerRef,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetActivationDate(
- /* [annotation][out] */
- __out LPWSTR wzActivationDate,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetAppCfgVersion(
- /* [annotation][out] */
- __out LPWSTR pwzVerAppCfg,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetPublisherCfgVersion(
- /* [annotation][out] */
- __out LPWSTR pwzVerPublisherCfg,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetAdminCfgVersion(
- /* [annotation][out] */
- __out LPWSTR pwzAdminCfg,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IHistoryAssemblyVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IHistoryAssembly * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IHistoryAssembly * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IHistoryAssembly * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetAssemblyName )(
- IHistoryAssembly * This,
- /* [annotation][out] */
- __out LPWSTR wzAsmName,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize);
-
- HRESULT ( STDMETHODCALLTYPE *GetPublicKeyToken )(
- IHistoryAssembly * This,
- /* [annotation][out] */
- __out LPWSTR wzPublicKeyToken,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize);
-
- HRESULT ( STDMETHODCALLTYPE *GetCulture )(
- IHistoryAssembly * This,
- /* [annotation][out] */
- __out LPWSTR wzCulture,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize);
-
- HRESULT ( STDMETHODCALLTYPE *GetReferenceVersion )(
- IHistoryAssembly * This,
- /* [annotation][out] */
- __out LPWSTR wzVerRef,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize);
-
- HRESULT ( STDMETHODCALLTYPE *GetActivationDate )(
- IHistoryAssembly * This,
- /* [annotation][out] */
- __out LPWSTR wzActivationDate,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize);
-
- HRESULT ( STDMETHODCALLTYPE *GetAppCfgVersion )(
- IHistoryAssembly * This,
- /* [annotation][out] */
- __out LPWSTR pwzVerAppCfg,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize);
-
- HRESULT ( STDMETHODCALLTYPE *GetPublisherCfgVersion )(
- IHistoryAssembly * This,
- /* [annotation][out] */
- __out LPWSTR pwzVerPublisherCfg,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize);
-
- HRESULT ( STDMETHODCALLTYPE *GetAdminCfgVersion )(
- IHistoryAssembly * This,
- /* [annotation][out] */
- __out LPWSTR pwzAdminCfg,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize);
-
- END_INTERFACE
- } IHistoryAssemblyVtbl;
-
- interface IHistoryAssembly
- {
- CONST_VTBL struct IHistoryAssemblyVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IHistoryAssembly_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IHistoryAssembly_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IHistoryAssembly_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IHistoryAssembly_GetAssemblyName(This,wzAsmName,pdwSize) \
- ( (This)->lpVtbl -> GetAssemblyName(This,wzAsmName,pdwSize) )
-
-#define IHistoryAssembly_GetPublicKeyToken(This,wzPublicKeyToken,pdwSize) \
- ( (This)->lpVtbl -> GetPublicKeyToken(This,wzPublicKeyToken,pdwSize) )
-
-#define IHistoryAssembly_GetCulture(This,wzCulture,pdwSize) \
- ( (This)->lpVtbl -> GetCulture(This,wzCulture,pdwSize) )
-
-#define IHistoryAssembly_GetReferenceVersion(This,wzVerRef,pdwSize) \
- ( (This)->lpVtbl -> GetReferenceVersion(This,wzVerRef,pdwSize) )
-
-#define IHistoryAssembly_GetActivationDate(This,wzActivationDate,pdwSize) \
- ( (This)->lpVtbl -> GetActivationDate(This,wzActivationDate,pdwSize) )
-
-#define IHistoryAssembly_GetAppCfgVersion(This,pwzVerAppCfg,pdwSize) \
- ( (This)->lpVtbl -> GetAppCfgVersion(This,pwzVerAppCfg,pdwSize) )
-
-#define IHistoryAssembly_GetPublisherCfgVersion(This,pwzVerPublisherCfg,pdwSize) \
- ( (This)->lpVtbl -> GetPublisherCfgVersion(This,pwzVerPublisherCfg,pdwSize) )
-
-#define IHistoryAssembly_GetAdminCfgVersion(This,pwzAdminCfg,pdwSize) \
- ( (This)->lpVtbl -> GetAdminCfgVersion(This,pwzAdminCfg,pdwSize) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IHistoryAssembly_INTERFACE_DEFINED__ */
-
-
-#ifndef __IHistoryReader_INTERFACE_DEFINED__
-#define __IHistoryReader_INTERFACE_DEFINED__
-
-/* interface IHistoryReader */
-/* [unique][uuid][object][local] */
-
-
-EXTERN_C const IID IID_IHistoryReader;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("1d23df4d-a1e2-4b8b-93d6-6ea3dc285a54")
- IHistoryReader : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetFilePath(
- /* [annotation][out] */
- __out LPWSTR wzFilePath,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetApplicationName(
- /* [annotation][out] */
- __out LPWSTR wzAppName,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetEXEModulePath(
- /* [annotation][out] */
- __out LPWSTR wzExePath,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetNumActivations(
- /* [out] */ DWORD *pdwNumActivations) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetActivationDate(
- /* [in] */ DWORD dwIdx,
- /* [out] */ FILETIME *pftDate) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetRunTimeVersion(
- /* [in] */ FILETIME *pftActivationDate,
- /* [annotation][out] */
- __out LPWSTR wzRunTimeVersion,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetNumAssemblies(
- /* [in] */ FILETIME *pftActivationDate,
- /* [out] */ DWORD *pdwNumAsms) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetHistoryAssembly(
- /* [in] */ FILETIME *pftActivationDate,
- /* [in] */ DWORD dwIdx,
- /* [out] */ IHistoryAssembly **ppHistAsm) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IHistoryReaderVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IHistoryReader * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IHistoryReader * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IHistoryReader * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetFilePath )(
- IHistoryReader * This,
- /* [annotation][out] */
- __out LPWSTR wzFilePath,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize);
-
- HRESULT ( STDMETHODCALLTYPE *GetApplicationName )(
- IHistoryReader * This,
- /* [annotation][out] */
- __out LPWSTR wzAppName,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize);
-
- HRESULT ( STDMETHODCALLTYPE *GetEXEModulePath )(
- IHistoryReader * This,
- /* [annotation][out] */
- __out LPWSTR wzExePath,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize);
-
- HRESULT ( STDMETHODCALLTYPE *GetNumActivations )(
- IHistoryReader * This,
- /* [out] */ DWORD *pdwNumActivations);
-
- HRESULT ( STDMETHODCALLTYPE *GetActivationDate )(
- IHistoryReader * This,
- /* [in] */ DWORD dwIdx,
- /* [out] */ FILETIME *pftDate);
-
- HRESULT ( STDMETHODCALLTYPE *GetRunTimeVersion )(
- IHistoryReader * This,
- /* [in] */ FILETIME *pftActivationDate,
- /* [annotation][out] */
- __out LPWSTR wzRunTimeVersion,
- /* [annotation][out][in] */
- __inout DWORD *pdwSize);
-
- HRESULT ( STDMETHODCALLTYPE *GetNumAssemblies )(
- IHistoryReader * This,
- /* [in] */ FILETIME *pftActivationDate,
- /* [out] */ DWORD *pdwNumAsms);
-
- HRESULT ( STDMETHODCALLTYPE *GetHistoryAssembly )(
- IHistoryReader * This,
- /* [in] */ FILETIME *pftActivationDate,
- /* [in] */ DWORD dwIdx,
- /* [out] */ IHistoryAssembly **ppHistAsm);
-
- END_INTERFACE
- } IHistoryReaderVtbl;
-
- interface IHistoryReader
- {
- CONST_VTBL struct IHistoryReaderVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IHistoryReader_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IHistoryReader_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IHistoryReader_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IHistoryReader_GetFilePath(This,wzFilePath,pdwSize) \
- ( (This)->lpVtbl -> GetFilePath(This,wzFilePath,pdwSize) )
-
-#define IHistoryReader_GetApplicationName(This,wzAppName,pdwSize) \
- ( (This)->lpVtbl -> GetApplicationName(This,wzAppName,pdwSize) )
-
-#define IHistoryReader_GetEXEModulePath(This,wzExePath,pdwSize) \
- ( (This)->lpVtbl -> GetEXEModulePath(This,wzExePath,pdwSize) )
-
-#define IHistoryReader_GetNumActivations(This,pdwNumActivations) \
- ( (This)->lpVtbl -> GetNumActivations(This,pdwNumActivations) )
-
-#define IHistoryReader_GetActivationDate(This,dwIdx,pftDate) \
- ( (This)->lpVtbl -> GetActivationDate(This,dwIdx,pftDate) )
-
-#define IHistoryReader_GetRunTimeVersion(This,pftActivationDate,wzRunTimeVersion,pdwSize) \
- ( (This)->lpVtbl -> GetRunTimeVersion(This,pftActivationDate,wzRunTimeVersion,pdwSize) )
-
-#define IHistoryReader_GetNumAssemblies(This,pftActivationDate,pdwNumAsms) \
- ( (This)->lpVtbl -> GetNumAssemblies(This,pftActivationDate,pdwNumAsms) )
-
-#define IHistoryReader_GetHistoryAssembly(This,pftActivationDate,dwIdx,ppHistAsm) \
- ( (This)->lpVtbl -> GetHistoryAssembly(This,pftActivationDate,dwIdx,ppHistAsm) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IHistoryReader_INTERFACE_DEFINED__ */
-
-
-/* interface __MIDL_itf_fusionpriv_0000_0002 */
-/* [local] */
-
-typedef /* [public][public][public] */
-enum __MIDL___MIDL_itf_fusionpriv_0000_0002_0001
- {
- LOADCTX_TYPE_DEFAULT = 0,
- LOADCTX_TYPE_LOADFROM = ( LOADCTX_TYPE_DEFAULT + 1 ) ,
- LOADCTX_TYPE_UNKNOWN = ( LOADCTX_TYPE_LOADFROM + 1 ) ,
- LOADCTX_TYPE_HOSTED = ( LOADCTX_TYPE_UNKNOWN + 1 )
- } LOADCTX_TYPE;
-
-#define FUSION_BIND_LOG_CATEGORY_DEFAULT 0
-#define FUSION_BIND_LOG_CATEGORY_NGEN 1
-#define FUSION_BIND_LOG_CATEGORY_MAX 2
-
-
-extern RPC_IF_HANDLE __MIDL_itf_fusionpriv_0000_0002_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_fusionpriv_0000_0002_v0_0_s_ifspec;
-
-#ifndef __IFusionBindLog_INTERFACE_DEFINED__
-#define __IFusionBindLog_INTERFACE_DEFINED__
-
-/* interface IFusionBindLog */
-/* [unique][uuid][object][local] */
-
-
-EXTERN_C const IID IID_IFusionBindLog;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("67E9F87D-8B8A-4a90-9D3E-85ED5B2DCC83")
- IFusionBindLog : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE SetResultCode(
- /* [in] */ DWORD dwLogCategory,
- /* [in] */ HRESULT hr) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetResultCode(
- /* [in] */ DWORD dwLogCategory,
- /* [out] */ HRESULT *pHr) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetBindLog(
- /* [in] */ DWORD dwDetailLevel,
- /* [in] */ DWORD dwLogCategory,
- /* [annotation][out] */
- __out_opt LPWSTR pwzDebugLog,
- /* [annotation][out][in] */
- __inout DWORD *pcbDebugLog) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE LogMessage(
- /* [in] */ DWORD dwDetailLevel,
- /* [in] */ DWORD dwLogCategory,
- /* [in] */ LPCWSTR pwzDebugLog) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Flush(
- /* [in] */ DWORD dwDetailLevel,
- /* [in] */ DWORD dwLogCategory) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetBindingID(
- /* [out] */ ULONGLONG *pullBindingID) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE ETWTraceLogMessage(
- /* [in] */ DWORD dwETWLogCategory,
- /* [in] */ IAssemblyName *pAsm) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IFusionBindLogVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IFusionBindLog * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IFusionBindLog * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IFusionBindLog * This);
-
- HRESULT ( STDMETHODCALLTYPE *SetResultCode )(
- IFusionBindLog * This,
- /* [in] */ DWORD dwLogCategory,
- /* [in] */ HRESULT hr);
-
- HRESULT ( STDMETHODCALLTYPE *GetResultCode )(
- IFusionBindLog * This,
- /* [in] */ DWORD dwLogCategory,
- /* [out] */ HRESULT *pHr);
-
- HRESULT ( STDMETHODCALLTYPE *GetBindLog )(
- IFusionBindLog * This,
- /* [in] */ DWORD dwDetailLevel,
- /* [in] */ DWORD dwLogCategory,
- /* [annotation][out] */
- __out_opt LPWSTR pwzDebugLog,
- /* [annotation][out][in] */
- __inout DWORD *pcbDebugLog);
-
- HRESULT ( STDMETHODCALLTYPE *LogMessage )(
- IFusionBindLog * This,
- /* [in] */ DWORD dwDetailLevel,
- /* [in] */ DWORD dwLogCategory,
- /* [in] */ LPCWSTR pwzDebugLog);
-
- HRESULT ( STDMETHODCALLTYPE *Flush )(
- IFusionBindLog * This,
- /* [in] */ DWORD dwDetailLevel,
- /* [in] */ DWORD dwLogCategory);
-
- HRESULT ( STDMETHODCALLTYPE *GetBindingID )(
- IFusionBindLog * This,
- /* [out] */ ULONGLONG *pullBindingID);
-
- HRESULT ( STDMETHODCALLTYPE *ETWTraceLogMessage )(
- IFusionBindLog * This,
- /* [in] */ DWORD dwETWLogCategory,
- /* [in] */ IAssemblyName *pAsm);
-
- END_INTERFACE
- } IFusionBindLogVtbl;
-
- interface IFusionBindLog
- {
- CONST_VTBL struct IFusionBindLogVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IFusionBindLog_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IFusionBindLog_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IFusionBindLog_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IFusionBindLog_SetResultCode(This,dwLogCategory,hr) \
- ( (This)->lpVtbl -> SetResultCode(This,dwLogCategory,hr) )
-
-#define IFusionBindLog_GetResultCode(This,dwLogCategory,pHr) \
- ( (This)->lpVtbl -> GetResultCode(This,dwLogCategory,pHr) )
-
-#define IFusionBindLog_GetBindLog(This,dwDetailLevel,dwLogCategory,pwzDebugLog,pcbDebugLog) \
- ( (This)->lpVtbl -> GetBindLog(This,dwDetailLevel,dwLogCategory,pwzDebugLog,pcbDebugLog) )
-
-#define IFusionBindLog_LogMessage(This,dwDetailLevel,dwLogCategory,pwzDebugLog) \
- ( (This)->lpVtbl -> LogMessage(This,dwDetailLevel,dwLogCategory,pwzDebugLog) )
-
-#define IFusionBindLog_Flush(This,dwDetailLevel,dwLogCategory) \
- ( (This)->lpVtbl -> Flush(This,dwDetailLevel,dwLogCategory) )
-
-#define IFusionBindLog_GetBindingID(This,pullBindingID) \
- ( (This)->lpVtbl -> GetBindingID(This,pullBindingID) )
-
-#define IFusionBindLog_ETWTraceLogMessage(This,dwETWLogCategory,pAsm) \
- ( (This)->lpVtbl -> ETWTraceLogMessage(This,dwETWLogCategory,pAsm) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IFusionBindLog_INTERFACE_DEFINED__ */
-
-
-#ifndef __IAssemblyManifestImport_INTERFACE_DEFINED__
-#define __IAssemblyManifestImport_INTERFACE_DEFINED__
-
-/* interface IAssemblyManifestImport */
-/* [unique][uuid][object][local] */
-
-typedef /* [unique] */ IAssemblyManifestImport *LPASSEMBLY_MANIFEST_IMPORT;
-
-
-EXTERN_C const IID IID_IAssemblyManifestImport;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("de9a68ba-0fa2-11d3-94aa-00c04fc308ff")
- IAssemblyManifestImport : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetAssemblyNameDef(
- /* [out] */ IAssemblyName **ppAssemblyName) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetNextAssemblyNameRef(
- /* [in] */ DWORD nIndex,
- /* [out] */ IAssemblyName **ppAssemblyName) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetNextAssemblyModule(
- /* [in] */ DWORD nIndex,
- /* [out] */ IAssemblyModuleImport **ppImport) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetModuleByName(
- /* [in] */ LPCOLESTR szModuleName,
- /* [out] */ IAssemblyModuleImport **ppModImport) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetManifestModulePath(
- /* [annotation][size_is][out] */
- __out_ecount_full(*pccModulePath) LPOLESTR szModulePath,
- /* [out][in] */ LPDWORD pccModulePath) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetInternalMDImport(
- /* [out] */ IMetaDataAssemblyImport **ppMDImport) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE LoadDataFromMDImport(
- /* [in] */ IMetaDataAssemblyImport *ppMDImport) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IAssemblyManifestImportVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IAssemblyManifestImport * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IAssemblyManifestImport * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IAssemblyManifestImport * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetAssemblyNameDef )(
- IAssemblyManifestImport * This,
- /* [out] */ IAssemblyName **ppAssemblyName);
-
- HRESULT ( STDMETHODCALLTYPE *GetNextAssemblyNameRef )(
- IAssemblyManifestImport * This,
- /* [in] */ DWORD nIndex,
- /* [out] */ IAssemblyName **ppAssemblyName);
-
- HRESULT ( STDMETHODCALLTYPE *GetNextAssemblyModule )(
- IAssemblyManifestImport * This,
- /* [in] */ DWORD nIndex,
- /* [out] */ IAssemblyModuleImport **ppImport);
-
- HRESULT ( STDMETHODCALLTYPE *GetModuleByName )(
- IAssemblyManifestImport * This,
- /* [in] */ LPCOLESTR szModuleName,
- /* [out] */ IAssemblyModuleImport **ppModImport);
-
- HRESULT ( STDMETHODCALLTYPE *GetManifestModulePath )(
- IAssemblyManifestImport * This,
- /* [annotation][size_is][out] */
- __out_ecount_full(*pccModulePath) LPOLESTR szModulePath,
- /* [out][in] */ LPDWORD pccModulePath);
-
- HRESULT ( STDMETHODCALLTYPE *GetInternalMDImport )(
- IAssemblyManifestImport * This,
- /* [out] */ IMetaDataAssemblyImport **ppMDImport);
-
- HRESULT ( STDMETHODCALLTYPE *LoadDataFromMDImport )(
- IAssemblyManifestImport * This,
- /* [in] */ IMetaDataAssemblyImport *ppMDImport);
-
- END_INTERFACE
- } IAssemblyManifestImportVtbl;
-
- interface IAssemblyManifestImport
- {
- CONST_VTBL struct IAssemblyManifestImportVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IAssemblyManifestImport_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IAssemblyManifestImport_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IAssemblyManifestImport_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IAssemblyManifestImport_GetAssemblyNameDef(This,ppAssemblyName) \
- ( (This)->lpVtbl -> GetAssemblyNameDef(This,ppAssemblyName) )
-
-#define IAssemblyManifestImport_GetNextAssemblyNameRef(This,nIndex,ppAssemblyName) \
- ( (This)->lpVtbl -> GetNextAssemblyNameRef(This,nIndex,ppAssemblyName) )
-
-#define IAssemblyManifestImport_GetNextAssemblyModule(This,nIndex,ppImport) \
- ( (This)->lpVtbl -> GetNextAssemblyModule(This,nIndex,ppImport) )
-
-#define IAssemblyManifestImport_GetModuleByName(This,szModuleName,ppModImport) \
- ( (This)->lpVtbl -> GetModuleByName(This,szModuleName,ppModImport) )
-
-#define IAssemblyManifestImport_GetManifestModulePath(This,szModulePath,pccModulePath) \
- ( (This)->lpVtbl -> GetManifestModulePath(This,szModulePath,pccModulePath) )
-
-#define IAssemblyManifestImport_GetInternalMDImport(This,ppMDImport) \
- ( (This)->lpVtbl -> GetInternalMDImport(This,ppMDImport) )
-
-#define IAssemblyManifestImport_LoadDataFromMDImport(This,ppMDImport) \
- ( (This)->lpVtbl -> LoadDataFromMDImport(This,ppMDImport) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IAssemblyManifestImport_INTERFACE_DEFINED__ */
-
-
-#ifndef __IApplicationContext_INTERFACE_DEFINED__
-#define __IApplicationContext_INTERFACE_DEFINED__
-
-/* interface IApplicationContext */
-/* [unique][uuid][object][local] */
-
-// App context configuration variables
-#define ACTAG_APP_BASE_URL L"APPBASE"
-#define ACTAG_MACHINE_CONFIG L"MACHINE_CONFIG"
-#define ACTAG_APP_PRIVATE_BINPATH L"PRIVATE_BINPATH"
-#define ACTAG_APP_SHARED_BINPATH L"SHARED_BINPATH"
-#define ACTAG_APP_SNAPSHOT_ID L"SNAPSHOT_ID"
-#define ACTAG_APP_CONFIG_FILE L"APP_CONFIG_FILE"
-#define ACTAG_APP_ID L"APPLICATION_ID"
-#define ACTAG_APP_SHADOW_COPY_DIRS L"SHADOW_COPY_DIRS"
-#define ACTAG_APP_DYNAMIC_BASE L"DYNAMIC_BASE"
-#define ACTAG_APP_CACHE_BASE L"CACHE_BASE"
-#define ACTAG_APP_NAME L"APP_NAME"
-#define ACTAG_DEV_PATH L"DEV_PATH"
-#define ACTAG_HOST_CONFIG_FILE L"HOST_CONFIG"
-#define ACTAG_SXS_ACTIVATION_CONTEXT L"SXS"
-#define ACTAG_APP_CFG_LOCAL_FILEPATH L"APP_CFG_LOCAL_FILEPATH"
-#define ACTAG_ZAP_STRING L"ZAP_STRING"
-#define ACTAG_ZAP_CONFIG_FLAGS L"ZAP_CONFIG_FLAGS"
-#define ACTAG_APP_DOMAIN_ID L"APPDOMAIN_ID"
-#define ACTAG_APP_CONFIG_BLOB L"APP_CONFIG_BLOB"
-#define ACTAG_FX_ONLY L"FX_ONLY"
-// App context flag overrides
-#define ACTAG_FORCE_CACHE_INSTALL L"FORCE_CACHE_INSTALL"
-#define ACTAG_RFS_INTEGRITY_CHECK L"RFS_INTEGRITY_CHECK"
-#define ACTAG_RFS_MODULE_CHECK L"RFS_MODULE_CHECK"
-#define ACTAG_BINPATH_PROBE_ONLY L"BINPATH_PROBE_ONLY"
-#define ACTAG_DISALLOW_APPLYPUBLISHERPOLICY L"DISALLOW_APP"
-#define ACTAG_DISALLOW_APP_BINDING_REDIRECTS L"DISALLOW_APP_REDIRECTS"
-#define ACTAG_DISALLOW_APP_BASE_PROBING L"DISALLOW_APP_BASE_PROBING"
-#define ACTAG_CODE_DOWNLOAD_DISABLED L"CODE_DOWNLOAD_DISABLED"
-#define ACTAG_DISABLE_FX_ASM_UNIFICATION L"DISABLE_FX_ASM_UNIFICATION"
-typedef /* [unique] */ IApplicationContext *LPAPPLICATIONCONTEXT;
-
-typedef /* [public] */
-enum __MIDL_IApplicationContext_0001
- {
- APP_CTX_FLAGS_INTERFACE = 0x1
- } APP_FLAGS;
-
-
-EXTERN_C const IID IID_IApplicationContext;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("7c23ff90-33af-11d3-95da-00a024a85b51")
- IApplicationContext : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE SetContextNameObject(
- /* [in] */ LPASSEMBLYNAME pName) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetContextNameObject(
- /* [out] */ LPASSEMBLYNAME *ppName) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Set(
- /* [in] */ LPCOLESTR szName,
- /* [in] */ LPVOID pvValue,
- /* [in] */ DWORD cbValue,
- /* [in] */ DWORD dwFlags) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Get(
- /* [in] */ LPCOLESTR szName,
- /* [out] */ LPVOID pvValue,
- /* [out][in] */ LPDWORD pcbValue,
- /* [in] */ DWORD dwFlags) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetDynamicDirectory(
- /* [annotation][out] */
- __out_ecount_opt(*pdwSize) LPWSTR wzDynamicDir,
- /* [out][in] */ LPDWORD pdwSize) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetAppCacheDirectory(
- /* [annotation][out] */
- __out_ecount_opt(*pdwSize) LPWSTR wzAppCacheDir,
- /* [out][in] */ LPDWORD pdwSize) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE RegisterKnownAssembly(
- /* [in] */ IAssemblyName *pName,
- /* [in] */ LPCWSTR pwzAsmURL,
- /* [out] */ IAssembly **ppAsmOut) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE PrefetchAppConfigFile( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetAssemblyBindingClosure(
- /* [in] */ IUnknown *pUnk,
- /* [in] */ LPCWSTR pwzNativeImagePath,
- /* [out] */ IAssemblyBindingClosure **ppAsmClosure) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IApplicationContextVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IApplicationContext * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IApplicationContext * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IApplicationContext * This);
-
- HRESULT ( STDMETHODCALLTYPE *SetContextNameObject )(
- IApplicationContext * This,
- /* [in] */ LPASSEMBLYNAME pName);
-
- HRESULT ( STDMETHODCALLTYPE *GetContextNameObject )(
- IApplicationContext * This,
- /* [out] */ LPASSEMBLYNAME *ppName);
-
- HRESULT ( STDMETHODCALLTYPE *Set )(
- IApplicationContext * This,
- /* [in] */ LPCOLESTR szName,
- /* [in] */ LPVOID pvValue,
- /* [in] */ DWORD cbValue,
- /* [in] */ DWORD dwFlags);
-
- HRESULT ( STDMETHODCALLTYPE *Get )(
- IApplicationContext * This,
- /* [in] */ LPCOLESTR szName,
- /* [out] */ LPVOID pvValue,
- /* [out][in] */ LPDWORD pcbValue,
- /* [in] */ DWORD dwFlags);
-
- HRESULT ( STDMETHODCALLTYPE *GetDynamicDirectory )(
- IApplicationContext * This,
- /* [annotation][out] */
- __out_ecount_opt(*pdwSize) LPWSTR wzDynamicDir,
- /* [out][in] */ LPDWORD pdwSize);
-
- HRESULT ( STDMETHODCALLTYPE *GetAppCacheDirectory )(
- IApplicationContext * This,
- /* [annotation][out] */
- __out_ecount_opt(*pdwSize) LPWSTR wzAppCacheDir,
- /* [out][in] */ LPDWORD pdwSize);
-
- HRESULT ( STDMETHODCALLTYPE *RegisterKnownAssembly )(
- IApplicationContext * This,
- /* [in] */ IAssemblyName *pName,
- /* [in] */ LPCWSTR pwzAsmURL,
- /* [out] */ IAssembly **ppAsmOut);
-
- HRESULT ( STDMETHODCALLTYPE *PrefetchAppConfigFile )(
- IApplicationContext * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetAssemblyBindingClosure )(
- IApplicationContext * This,
- /* [in] */ IUnknown *pUnk,
- /* [in] */ LPCWSTR pwzNativeImagePath,
- /* [out] */ IAssemblyBindingClosure **ppAsmClosure);
-
- END_INTERFACE
- } IApplicationContextVtbl;
-
- interface IApplicationContext
- {
- CONST_VTBL struct IApplicationContextVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IApplicationContext_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IApplicationContext_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IApplicationContext_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IApplicationContext_SetContextNameObject(This,pName) \
- ( (This)->lpVtbl -> SetContextNameObject(This,pName) )
-
-#define IApplicationContext_GetContextNameObject(This,ppName) \
- ( (This)->lpVtbl -> GetContextNameObject(This,ppName) )
-
-#define IApplicationContext_Set(This,szName,pvValue,cbValue,dwFlags) \
- ( (This)->lpVtbl -> Set(This,szName,pvValue,cbValue,dwFlags) )
-
-#define IApplicationContext_Get(This,szName,pvValue,pcbValue,dwFlags) \
- ( (This)->lpVtbl -> Get(This,szName,pvValue,pcbValue,dwFlags) )
-
-#define IApplicationContext_GetDynamicDirectory(This,wzDynamicDir,pdwSize) \
- ( (This)->lpVtbl -> GetDynamicDirectory(This,wzDynamicDir,pdwSize) )
-
-#define IApplicationContext_GetAppCacheDirectory(This,wzAppCacheDir,pdwSize) \
- ( (This)->lpVtbl -> GetAppCacheDirectory(This,wzAppCacheDir,pdwSize) )
-
-#define IApplicationContext_RegisterKnownAssembly(This,pName,pwzAsmURL,ppAsmOut) \
- ( (This)->lpVtbl -> RegisterKnownAssembly(This,pName,pwzAsmURL,ppAsmOut) )
-
-#define IApplicationContext_PrefetchAppConfigFile(This) \
- ( (This)->lpVtbl -> PrefetchAppConfigFile(This) )
-
-#define IApplicationContext_GetAssemblyBindingClosure(This,pUnk,pwzNativeImagePath,ppAsmClosure) \
- ( (This)->lpVtbl -> GetAssemblyBindingClosure(This,pUnk,pwzNativeImagePath,ppAsmClosure) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IApplicationContext_INTERFACE_DEFINED__ */
-
-
-#ifndef __IAssemblyNameBinder_INTERFACE_DEFINED__
-#define __IAssemblyNameBinder_INTERFACE_DEFINED__
-
-/* interface IAssemblyNameBinder */
-/* [unique][uuid][object][local] */
-
-
-EXTERN_C const IID IID_IAssemblyNameBinder;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("56972d9d-0f6c-47de-a038-e82d5de3a777")
- IAssemblyNameBinder : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE BindToObject(
- /* [in] */ REFIID refIID,
- /* [in] */ IUnknown *pUnkSink,
- /* [in] */ IUnknown *pUnkContext,
- /* [in] */ LPCOLESTR szCodeBase,
- /* [in] */ LONGLONG llFlags,
- /* [in] */ LPVOID pParentAssembly,
- /* [in] */ DWORD cbReserved,
- /* [out] */ LPVOID *ppv,
- /* [out] */ LPVOID *ppvNI) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IAssemblyNameBinderVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IAssemblyNameBinder * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IAssemblyNameBinder * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IAssemblyNameBinder * This);
-
- HRESULT ( STDMETHODCALLTYPE *BindToObject )(
- IAssemblyNameBinder * This,
- /* [in] */ REFIID refIID,
- /* [in] */ IUnknown *pUnkSink,
- /* [in] */ IUnknown *pUnkContext,
- /* [in] */ LPCOLESTR szCodeBase,
- /* [in] */ LONGLONG llFlags,
- /* [in] */ LPVOID pParentAssembly,
- /* [in] */ DWORD cbReserved,
- /* [out] */ LPVOID *ppv,
- /* [out] */ LPVOID *ppvNI);
-
- END_INTERFACE
- } IAssemblyNameBinderVtbl;
-
- interface IAssemblyNameBinder
- {
- CONST_VTBL struct IAssemblyNameBinderVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IAssemblyNameBinder_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IAssemblyNameBinder_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IAssemblyNameBinder_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IAssemblyNameBinder_BindToObject(This,refIID,pUnkSink,pUnkContext,szCodeBase,llFlags,pParentAssembly,cbReserved,ppv,ppvNI) \
- ( (This)->lpVtbl -> BindToObject(This,refIID,pUnkSink,pUnkContext,szCodeBase,llFlags,pParentAssembly,cbReserved,ppv,ppvNI) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IAssemblyNameBinder_INTERFACE_DEFINED__ */
-
-
-#ifndef __IAssembly_INTERFACE_DEFINED__
-#define __IAssembly_INTERFACE_DEFINED__
-
-/* interface IAssembly */
-/* [unique][uuid][object][local] */
-
-typedef /* [unique] */ IAssembly *LPASSEMBLY;
-
-#define ASMLOC_LOCATION_MASK 0x0000001B
-#define ASMLOC_UNKNOWN 0x00000000
-#define ASMLOC_GAC 0x00000001
-#define ASMLOC_DOWNLOAD_CACHE 0x00000002
-#define ASMLOC_RUN_FROM_SOURCE 0x00000003
-#define ASMLOC_CODEBASE_HINT 0x00000004
-#define ASMLOC_ZAP 0x00000008
-#define ASMLOC_DEV_OVERRIDE 0x00000010
-
-EXTERN_C const IID IID_IAssembly;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("ff08d7d4-04c2-11d3-94aa-00c04fc308ff")
- IAssembly : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetAssemblyNameDef(
- /* [out] */ IAssemblyName **ppAssemblyName) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetNextAssemblyNameRef(
- /* [in] */ DWORD nIndex,
- /* [out] */ IAssemblyName **ppAssemblyName) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetNextAssemblyModule(
- /* [in] */ DWORD nIndex,
- /* [out] */ IAssemblyModuleImport **ppModImport) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetModuleByName(
- /* [in] */ LPCOLESTR szModuleName,
- /* [out] */ IAssemblyModuleImport **ppModImport) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetManifestModulePath(
- /* [annotation][size_is][out] */
- __out_ecount_full_opt(*pccModulePath) LPOLESTR szModulePath,
- /* [out][in] */ LPDWORD pccModulePath) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetAssemblyPath(
- /* [annotation][size_is][out] */
- __out_ecount_full_opt(*lpcwBuffer) LPOLESTR pStr,
- /* [out][in] */ LPDWORD lpcwBuffer) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetAssemblyLocation(
- /* [out] */ DWORD *pdwAsmLocation) = 0;
-
- virtual LOADCTX_TYPE STDMETHODCALLTYPE GetFusionLoadContext( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetNextHardBoundDependency(
- /* [in] */ DWORD dwIndex,
- /* [out] */ IAssembly **ppILAsm,
- /* [out] */ IAssembly **ppNIAsm) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IAssemblyVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IAssembly * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IAssembly * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IAssembly * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetAssemblyNameDef )(
- IAssembly * This,
- /* [out] */ IAssemblyName **ppAssemblyName);
-
- HRESULT ( STDMETHODCALLTYPE *GetNextAssemblyNameRef )(
- IAssembly * This,
- /* [in] */ DWORD nIndex,
- /* [out] */ IAssemblyName **ppAssemblyName);
-
- HRESULT ( STDMETHODCALLTYPE *GetNextAssemblyModule )(
- IAssembly * This,
- /* [in] */ DWORD nIndex,
- /* [out] */ IAssemblyModuleImport **ppModImport);
-
- HRESULT ( STDMETHODCALLTYPE *GetModuleByName )(
- IAssembly * This,
- /* [in] */ LPCOLESTR szModuleName,
- /* [out] */ IAssemblyModuleImport **ppModImport);
-
- HRESULT ( STDMETHODCALLTYPE *GetManifestModulePath )(
- IAssembly * This,
- /* [annotation][size_is][out] */
- __out_ecount_full_opt(*pccModulePath) LPOLESTR szModulePath,
- /* [out][in] */ LPDWORD pccModulePath);
-
- HRESULT ( STDMETHODCALLTYPE *GetAssemblyPath )(
- IAssembly * This,
- /* [annotation][size_is][out] */
- __out_ecount_full_opt(*lpcwBuffer) LPOLESTR pStr,
- /* [out][in] */ LPDWORD lpcwBuffer);
-
- HRESULT ( STDMETHODCALLTYPE *GetAssemblyLocation )(
- IAssembly * This,
- /* [out] */ DWORD *pdwAsmLocation);
-
- LOADCTX_TYPE ( STDMETHODCALLTYPE *GetFusionLoadContext )(
- IAssembly * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetNextHardBoundDependency )(
- IAssembly * This,
- /* [in] */ DWORD dwIndex,
- /* [out] */ IAssembly **ppILAsm,
- /* [out] */ IAssembly **ppNIAsm);
-
- END_INTERFACE
- } IAssemblyVtbl;
-
- interface IAssembly
- {
- CONST_VTBL struct IAssemblyVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IAssembly_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IAssembly_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IAssembly_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IAssembly_GetAssemblyNameDef(This,ppAssemblyName) \
- ( (This)->lpVtbl -> GetAssemblyNameDef(This,ppAssemblyName) )
-
-#define IAssembly_GetNextAssemblyNameRef(This,nIndex,ppAssemblyName) \
- ( (This)->lpVtbl -> GetNextAssemblyNameRef(This,nIndex,ppAssemblyName) )
-
-#define IAssembly_GetNextAssemblyModule(This,nIndex,ppModImport) \
- ( (This)->lpVtbl -> GetNextAssemblyModule(This,nIndex,ppModImport) )
-
-#define IAssembly_GetModuleByName(This,szModuleName,ppModImport) \
- ( (This)->lpVtbl -> GetModuleByName(This,szModuleName,ppModImport) )
-
-#define IAssembly_GetManifestModulePath(This,szModulePath,pccModulePath) \
- ( (This)->lpVtbl -> GetManifestModulePath(This,szModulePath,pccModulePath) )
-
-#define IAssembly_GetAssemblyPath(This,pStr,lpcwBuffer) \
- ( (This)->lpVtbl -> GetAssemblyPath(This,pStr,lpcwBuffer) )
-
-#define IAssembly_GetAssemblyLocation(This,pdwAsmLocation) \
- ( (This)->lpVtbl -> GetAssemblyLocation(This,pdwAsmLocation) )
-
-#define IAssembly_GetFusionLoadContext(This) \
- ( (This)->lpVtbl -> GetFusionLoadContext(This) )
-
-#define IAssembly_GetNextHardBoundDependency(This,dwIndex,ppILAsm,ppNIAsm) \
- ( (This)->lpVtbl -> GetNextHardBoundDependency(This,dwIndex,ppILAsm,ppNIAsm) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IAssembly_INTERFACE_DEFINED__ */
-
-
-#ifndef __IAssemblyBindingClosureEnumerator_INTERFACE_DEFINED__
-#define __IAssemblyBindingClosureEnumerator_INTERFACE_DEFINED__
-
-/* interface IAssemblyBindingClosureEnumerator */
-/* [unique][uuid][object][local] */
-
-
-EXTERN_C const IID IID_IAssemblyBindingClosureEnumerator;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("b3f1e4ed-cb09-4b85-9a1b-6809582f1ebc")
- IAssemblyBindingClosureEnumerator : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetNextAssemblyPath(
- /* [out] */ LPCOLESTR *ppPath,
- /* [out] */ LPCOLESTR *ppniPath) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IAssemblyBindingClosureEnumeratorVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IAssemblyBindingClosureEnumerator * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IAssemblyBindingClosureEnumerator * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IAssemblyBindingClosureEnumerator * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetNextAssemblyPath )(
- IAssemblyBindingClosureEnumerator * This,
- /* [out] */ LPCOLESTR *ppPath,
- /* [out] */ LPCOLESTR *ppniPath);
-
- END_INTERFACE
- } IAssemblyBindingClosureEnumeratorVtbl;
-
- interface IAssemblyBindingClosureEnumerator
- {
- CONST_VTBL struct IAssemblyBindingClosureEnumeratorVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IAssemblyBindingClosureEnumerator_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IAssemblyBindingClosureEnumerator_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IAssemblyBindingClosureEnumerator_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IAssemblyBindingClosureEnumerator_GetNextAssemblyPath(This,ppPath,ppniPath) \
- ( (This)->lpVtbl -> GetNextAssemblyPath(This,ppPath,ppniPath) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IAssemblyBindingClosureEnumerator_INTERFACE_DEFINED__ */
-
-
-#ifndef __IAssemblyBindingClosure_INTERFACE_DEFINED__
-#define __IAssemblyBindingClosure_INTERFACE_DEFINED__
-
-/* interface IAssemblyBindingClosure */
-/* [unique][uuid][object][local] */
-
-
-EXTERN_C const IID IID_IAssemblyBindingClosure;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("415c226a-e513-41ba-9651-9c48e97aa5de")
- IAssemblyBindingClosure : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE IsAllAssembliesInGAC( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE IsEqual(
- /* [in] */ IAssemblyBindingClosure *pAssemblyClosure) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetNextFailureAssembly(
- /* [in] */ DWORD dwIndex,
- /* [out] */ IAssemblyName **ppName,
- /* [out] */ HRESULT *pHResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE EnsureWalked(
- /* [in] */ IUnknown *pStartingAssembly,
- /* [in] */ IApplicationContext *pAppCtx,
- /* [in] */ WALK_LEVEL level) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE EnumerateAssemblies(
- /* [out] */ IAssemblyBindingClosureEnumerator **ppEnumerator) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE HasBeenWalked(
- /* [in] */ WALK_LEVEL level) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE MayHaveUnknownDependencies( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE AddProfilerAssemblyReference(
- /* [in] */ LPVOID pbPublicKeyOrToken,
- /* [in] */ ULONG cbPublicKeyOrToken,
- /* [in] */ LPCWSTR szName,
- /* [in] */ LPVOID pMetaData,
- /* [in] */ void *pbHashValue,
- /* [in] */ ULONG cbHashValue,
- /* [in] */ DWORD dwAssemblyRefFlags,
- /* [in] */ struct AssemblyReferenceClosureWalkContextForProfAPI *pContext) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IAssemblyBindingClosureVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IAssemblyBindingClosure * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IAssemblyBindingClosure * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IAssemblyBindingClosure * This);
-
- HRESULT ( STDMETHODCALLTYPE *IsAllAssembliesInGAC )(
- IAssemblyBindingClosure * This);
-
- HRESULT ( STDMETHODCALLTYPE *IsEqual )(
- IAssemblyBindingClosure * This,
- /* [in] */ IAssemblyBindingClosure *pAssemblyClosure);
-
- HRESULT ( STDMETHODCALLTYPE *GetNextFailureAssembly )(
- IAssemblyBindingClosure * This,
- /* [in] */ DWORD dwIndex,
- /* [out] */ IAssemblyName **ppName,
- /* [out] */ HRESULT *pHResult);
-
- HRESULT ( STDMETHODCALLTYPE *EnsureWalked )(
- IAssemblyBindingClosure * This,
- /* [in] */ IUnknown *pStartingAssembly,
- /* [in] */ IApplicationContext *pAppCtx,
- /* [in] */ WALK_LEVEL level);
-
- HRESULT ( STDMETHODCALLTYPE *EnumerateAssemblies )(
- IAssemblyBindingClosure * This,
- /* [out] */ IAssemblyBindingClosureEnumerator **ppEnumerator);
-
- HRESULT ( STDMETHODCALLTYPE *HasBeenWalked )(
- IAssemblyBindingClosure * This,
- /* [in] */ WALK_LEVEL level);
-
- HRESULT ( STDMETHODCALLTYPE *MayHaveUnknownDependencies )(
- IAssemblyBindingClosure * This);
-
- HRESULT ( STDMETHODCALLTYPE *AddProfilerAssemblyReference )(
- IAssemblyBindingClosure * This,
- /* [in] */ LPVOID pbPublicKeyOrToken,
- /* [in] */ ULONG cbPublicKeyOrToken,
- /* [in] */ LPCWSTR szName,
- /* [in] */ LPVOID pMetaData,
- /* [in] */ void *pbHashValue,
- /* [in] */ ULONG cbHashValue,
- /* [in] */ DWORD dwAssemblyRefFlags,
- /* [in] */ struct AssemblyReferenceClosureWalkContextForProfAPI *pContext);
-
- END_INTERFACE
- } IAssemblyBindingClosureVtbl;
-
- interface IAssemblyBindingClosure
- {
- CONST_VTBL struct IAssemblyBindingClosureVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IAssemblyBindingClosure_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IAssemblyBindingClosure_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IAssemblyBindingClosure_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IAssemblyBindingClosure_IsAllAssembliesInGAC(This) \
- ( (This)->lpVtbl -> IsAllAssembliesInGAC(This) )
-
-#define IAssemblyBindingClosure_IsEqual(This,pAssemblyClosure) \
- ( (This)->lpVtbl -> IsEqual(This,pAssemblyClosure) )
-
-#define IAssemblyBindingClosure_GetNextFailureAssembly(This,dwIndex,ppName,pHResult) \
- ( (This)->lpVtbl -> GetNextFailureAssembly(This,dwIndex,ppName,pHResult) )
-
-#define IAssemblyBindingClosure_EnsureWalked(This,pStartingAssembly,pAppCtx,level) \
- ( (This)->lpVtbl -> EnsureWalked(This,pStartingAssembly,pAppCtx,level) )
-
-#define IAssemblyBindingClosure_EnumerateAssemblies(This,ppEnumerator) \
- ( (This)->lpVtbl -> EnumerateAssemblies(This,ppEnumerator) )
-
-#define IAssemblyBindingClosure_HasBeenWalked(This,level) \
- ( (This)->lpVtbl -> HasBeenWalked(This,level) )
-
-#define IAssemblyBindingClosure_MayHaveUnknownDependencies(This) \
- ( (This)->lpVtbl -> MayHaveUnknownDependencies(This) )
-
-#define IAssemblyBindingClosure_AddProfilerAssemblyReference(This,pbPublicKeyOrToken,cbPublicKeyOrToken,szName,pMetaData,pbHashValue,cbHashValue,dwAssemblyRefFlags,pContext) \
- ( (This)->lpVtbl -> AddProfilerAssemblyReference(This,pbPublicKeyOrToken,cbPublicKeyOrToken,szName,pMetaData,pbHashValue,cbHashValue,dwAssemblyRefFlags,pContext) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IAssemblyBindingClosure_INTERFACE_DEFINED__ */
-
-
-#ifndef __IAssemblyBindSink_INTERFACE_DEFINED__
-#define __IAssemblyBindSink_INTERFACE_DEFINED__
-
-/* interface IAssemblyBindSink */
-/* [unique][uuid][object][local] */
-
-typedef /* [unique] */ IAssemblyBindSink *LPASSEMBLY_BIND_SINK;
-
-typedef struct _tagFusionBindInfo
- {
- IFusionBindLog *pdbglog;
- IAssemblyName *pNamePolicy;
- DWORD dwPoliciesApplied;
- } FusionBindInfo;
-
-typedef /* [public] */
-enum __MIDL_IAssemblyBindSink_0001
- {
- ASM_NOTIFICATION_START = 0,
- ASM_NOTIFICATION_PROGRESS = ( ASM_NOTIFICATION_START + 1 ) ,
- ASM_NOTIFICATION_SUSPEND = ( ASM_NOTIFICATION_PROGRESS + 1 ) ,
- ASM_NOTIFICATION_ATTEMPT_NEXT_CODEBASE = ( ASM_NOTIFICATION_SUSPEND + 1 ) ,
- ASM_NOTIFICATION_BIND_INFO = ( ASM_NOTIFICATION_ATTEMPT_NEXT_CODEBASE + 1 ) ,
- ASM_NOTIFICATION_DONE = ( ASM_NOTIFICATION_BIND_INFO + 1 ) ,
- ASM_NOTIFICATION_NATIVE_IMAGE_DONE = ( ASM_NOTIFICATION_DONE + 1 )
- } ASM_NOTIFICATION;
-
-
-EXTERN_C const IID IID_IAssemblyBindSink;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("af0bc960-0b9a-11d3-95ca-00a024a85b51")
- IAssemblyBindSink : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE OnProgress(
- /* [in] */ DWORD dwNotification,
- /* [in] */ HRESULT hrNotification,
- /* [in] */ LPCWSTR szNotification,
- /* [in] */ DWORD dwProgress,
- /* [in] */ DWORD dwProgressMax,
- /* [in] */ LPVOID pvBindInfo,
- /* [in] */ IUnknown *pUnk) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IAssemblyBindSinkVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IAssemblyBindSink * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IAssemblyBindSink * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IAssemblyBindSink * This);
-
- HRESULT ( STDMETHODCALLTYPE *OnProgress )(
- IAssemblyBindSink * This,
- /* [in] */ DWORD dwNotification,
- /* [in] */ HRESULT hrNotification,
- /* [in] */ LPCWSTR szNotification,
- /* [in] */ DWORD dwProgress,
- /* [in] */ DWORD dwProgressMax,
- /* [in] */ LPVOID pvBindInfo,
- /* [in] */ IUnknown *pUnk);
-
- END_INTERFACE
- } IAssemblyBindSinkVtbl;
-
- interface IAssemblyBindSink
- {
- CONST_VTBL struct IAssemblyBindSinkVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IAssemblyBindSink_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IAssemblyBindSink_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IAssemblyBindSink_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IAssemblyBindSink_OnProgress(This,dwNotification,hrNotification,szNotification,dwProgress,dwProgressMax,pvBindInfo,pUnk) \
- ( (This)->lpVtbl -> OnProgress(This,dwNotification,hrNotification,szNotification,dwProgress,dwProgressMax,pvBindInfo,pUnk) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IAssemblyBindSink_INTERFACE_DEFINED__ */
-
-
-#ifndef __IAssemblyBinding_INTERFACE_DEFINED__
-#define __IAssemblyBinding_INTERFACE_DEFINED__
-
-/* interface IAssemblyBinding */
-/* [unique][uuid][object][local] */
-
-typedef /* [unique] */ IAssemblyBinding *LPASSEMBLY_BINDINDING;
-
-
-EXTERN_C const IID IID_IAssemblyBinding;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("cfe52a80-12bd-11d3-95ca-00a024a85b51")
- IAssemblyBinding : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE Control(
- /* [in] */ HRESULT hrControl) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE DoDefaultUI(
- /* [in] */ HWND hWnd,
- /* [in] */ DWORD dwFlags) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IAssemblyBindingVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IAssemblyBinding * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IAssemblyBinding * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IAssemblyBinding * This);
-
- HRESULT ( STDMETHODCALLTYPE *Control )(
- IAssemblyBinding * This,
- /* [in] */ HRESULT hrControl);
-
- HRESULT ( STDMETHODCALLTYPE *DoDefaultUI )(
- IAssemblyBinding * This,
- /* [in] */ HWND hWnd,
- /* [in] */ DWORD dwFlags);
-
- END_INTERFACE
- } IAssemblyBindingVtbl;
-
- interface IAssemblyBinding
- {
- CONST_VTBL struct IAssemblyBindingVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IAssemblyBinding_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IAssemblyBinding_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IAssemblyBinding_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IAssemblyBinding_Control(This,hrControl) \
- ( (This)->lpVtbl -> Control(This,hrControl) )
-
-#define IAssemblyBinding_DoDefaultUI(This,hWnd,dwFlags) \
- ( (This)->lpVtbl -> DoDefaultUI(This,hWnd,dwFlags) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IAssemblyBinding_INTERFACE_DEFINED__ */
-
-
-#ifndef __IAssemblyModuleImport_INTERFACE_DEFINED__
-#define __IAssemblyModuleImport_INTERFACE_DEFINED__
-
-/* interface IAssemblyModuleImport */
-/* [unique][uuid][object][local] */
-
-typedef /* [unique] */ IAssemblyModuleImport *LPASSEMBLY_MODULE_IMPORT;
-
-
-EXTERN_C const IID IID_IAssemblyModuleImport;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("da0cd4b0-1117-11d3-95ca-00a024a85b51")
- IAssemblyModuleImport : public IStream
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetModuleName(
- /* [annotation][size_is][out] */
- __out_ecount_full_opt(*pccModuleName) LPOLESTR szModuleName,
- /* [out][in] */ LPDWORD pccModuleName) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetHashAlgId(
- /* [out] */ LPDWORD pdwHashAlgId) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetHashValue(
- /* [size_is][out] */ BYTE *pbHashValue,
- /* [out][in] */ LPDWORD pcbHashValue) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetFlags(
- /* [out] */ LPDWORD pdwFlags) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetModulePath(
- /* [annotation][size_is][out] */
- __out_ecount_full_opt(*pccModulePath) LPOLESTR szModulePath,
- /* [out][in] */ LPDWORD pccModulePath) = 0;
-
- virtual BOOL STDMETHODCALLTYPE IsAvailable( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE BindToObject(
- /* [in] */ IAssemblyBindSink *pBindSink,
- /* [in] */ IApplicationContext *pAppCtx,
- /* [in] */ LONGLONG llFlags,
- /* [out] */ LPVOID *ppv) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IAssemblyModuleImportVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IAssemblyModuleImport * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IAssemblyModuleImport * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IAssemblyModuleImport * This);
-
- /* [local] */ HRESULT ( STDMETHODCALLTYPE *Read )(
- IAssemblyModuleImport * This,
- /* [annotation] */
- _Out_writes_bytes_to_(cb, *pcbRead) void *pv,
- /* [annotation][in] */
- _In_ ULONG cb,
- /* [annotation] */
- _Out_opt_ ULONG *pcbRead);
-
- /* [local] */ HRESULT ( STDMETHODCALLTYPE *Write )(
- IAssemblyModuleImport * This,
- /* [annotation] */
- _In_reads_bytes_(cb) const void *pv,
- /* [annotation][in] */
- _In_ ULONG cb,
- /* [annotation] */
- _Out_opt_ ULONG *pcbWritten);
-
- /* [local] */ HRESULT ( STDMETHODCALLTYPE *Seek )(
- IAssemblyModuleImport * This,
- /* [in] */ LARGE_INTEGER dlibMove,
- /* [in] */ DWORD dwOrigin,
- /* [annotation] */
- _Out_opt_ ULARGE_INTEGER *plibNewPosition);
-
- HRESULT ( STDMETHODCALLTYPE *SetSize )(
- IAssemblyModuleImport * This,
- /* [in] */ ULARGE_INTEGER libNewSize);
-
- /* [local] */ HRESULT ( STDMETHODCALLTYPE *CopyTo )(
- IAssemblyModuleImport * This,
- /* [annotation][unique][in] */
- _In_ IStream *pstm,
- /* [in] */ ULARGE_INTEGER cb,
- /* [annotation] */
- _Out_opt_ ULARGE_INTEGER *pcbRead,
- /* [annotation] */
- _Out_opt_ ULARGE_INTEGER *pcbWritten);
-
- HRESULT ( STDMETHODCALLTYPE *Commit )(
- IAssemblyModuleImport * This,
- /* [in] */ DWORD grfCommitFlags);
-
- HRESULT ( STDMETHODCALLTYPE *Revert )(
- IAssemblyModuleImport * This);
-
- HRESULT ( STDMETHODCALLTYPE *LockRegion )(
- IAssemblyModuleImport * This,
- /* [in] */ ULARGE_INTEGER libOffset,
- /* [in] */ ULARGE_INTEGER cb,
- /* [in] */ DWORD dwLockType);
-
- HRESULT ( STDMETHODCALLTYPE *UnlockRegion )(
- IAssemblyModuleImport * This,
- /* [in] */ ULARGE_INTEGER libOffset,
- /* [in] */ ULARGE_INTEGER cb,
- /* [in] */ DWORD dwLockType);
-
- HRESULT ( STDMETHODCALLTYPE *Stat )(
- IAssemblyModuleImport * This,
- /* [out] */ STATSTG *pstatstg,
- /* [in] */ DWORD grfStatFlag);
-
- HRESULT ( STDMETHODCALLTYPE *Clone )(
- IAssemblyModuleImport * This,
- /* [out] */ IStream **ppstm);
-
- HRESULT ( STDMETHODCALLTYPE *GetModuleName )(
- IAssemblyModuleImport * This,
- /* [annotation][size_is][out] */
- __out_ecount_full_opt(*pccModuleName) LPOLESTR szModuleName,
- /* [out][in] */ LPDWORD pccModuleName);
-
- HRESULT ( STDMETHODCALLTYPE *GetHashAlgId )(
- IAssemblyModuleImport * This,
- /* [out] */ LPDWORD pdwHashAlgId);
-
- HRESULT ( STDMETHODCALLTYPE *GetHashValue )(
- IAssemblyModuleImport * This,
- /* [size_is][out] */ BYTE *pbHashValue,
- /* [out][in] */ LPDWORD pcbHashValue);
-
- HRESULT ( STDMETHODCALLTYPE *GetFlags )(
- IAssemblyModuleImport * This,
- /* [out] */ LPDWORD pdwFlags);
-
- HRESULT ( STDMETHODCALLTYPE *GetModulePath )(
- IAssemblyModuleImport * This,
- /* [annotation][size_is][out] */
- __out_ecount_full_opt(*pccModulePath) LPOLESTR szModulePath,
- /* [out][in] */ LPDWORD pccModulePath);
-
- BOOL ( STDMETHODCALLTYPE *IsAvailable )(
- IAssemblyModuleImport * This);
-
- HRESULT ( STDMETHODCALLTYPE *BindToObject )(
- IAssemblyModuleImport * This,
- /* [in] */ IAssemblyBindSink *pBindSink,
- /* [in] */ IApplicationContext *pAppCtx,
- /* [in] */ LONGLONG llFlags,
- /* [out] */ LPVOID *ppv);
-
- END_INTERFACE
- } IAssemblyModuleImportVtbl;
-
- interface IAssemblyModuleImport
- {
- CONST_VTBL struct IAssemblyModuleImportVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IAssemblyModuleImport_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IAssemblyModuleImport_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IAssemblyModuleImport_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IAssemblyModuleImport_Read(This,pv,cb,pcbRead) \
- ( (This)->lpVtbl -> Read(This,pv,cb,pcbRead) )
-
-#define IAssemblyModuleImport_Write(This,pv,cb,pcbWritten) \
- ( (This)->lpVtbl -> Write(This,pv,cb,pcbWritten) )
-
-
-#define IAssemblyModuleImport_Seek(This,dlibMove,dwOrigin,plibNewPosition) \
- ( (This)->lpVtbl -> Seek(This,dlibMove,dwOrigin,plibNewPosition) )
-
-#define IAssemblyModuleImport_SetSize(This,libNewSize) \
- ( (This)->lpVtbl -> SetSize(This,libNewSize) )
-
-#define IAssemblyModuleImport_CopyTo(This,pstm,cb,pcbRead,pcbWritten) \
- ( (This)->lpVtbl -> CopyTo(This,pstm,cb,pcbRead,pcbWritten) )
-
-#define IAssemblyModuleImport_Commit(This,grfCommitFlags) \
- ( (This)->lpVtbl -> Commit(This,grfCommitFlags) )
-
-#define IAssemblyModuleImport_Revert(This) \
- ( (This)->lpVtbl -> Revert(This) )
-
-#define IAssemblyModuleImport_LockRegion(This,libOffset,cb,dwLockType) \
- ( (This)->lpVtbl -> LockRegion(This,libOffset,cb,dwLockType) )
-
-#define IAssemblyModuleImport_UnlockRegion(This,libOffset,cb,dwLockType) \
- ( (This)->lpVtbl -> UnlockRegion(This,libOffset,cb,dwLockType) )
-
-#define IAssemblyModuleImport_Stat(This,pstatstg,grfStatFlag) \
- ( (This)->lpVtbl -> Stat(This,pstatstg,grfStatFlag) )
-
-#define IAssemblyModuleImport_Clone(This,ppstm) \
- ( (This)->lpVtbl -> Clone(This,ppstm) )
-
-
-#define IAssemblyModuleImport_GetModuleName(This,szModuleName,pccModuleName) \
- ( (This)->lpVtbl -> GetModuleName(This,szModuleName,pccModuleName) )
-
-#define IAssemblyModuleImport_GetHashAlgId(This,pdwHashAlgId) \
- ( (This)->lpVtbl -> GetHashAlgId(This,pdwHashAlgId) )
-
-#define IAssemblyModuleImport_GetHashValue(This,pbHashValue,pcbHashValue) \
- ( (This)->lpVtbl -> GetHashValue(This,pbHashValue,pcbHashValue) )
-
-#define IAssemblyModuleImport_GetFlags(This,pdwFlags) \
- ( (This)->lpVtbl -> GetFlags(This,pdwFlags) )
-
-#define IAssemblyModuleImport_GetModulePath(This,szModulePath,pccModulePath) \
- ( (This)->lpVtbl -> GetModulePath(This,szModulePath,pccModulePath) )
-
-#define IAssemblyModuleImport_IsAvailable(This) \
- ( (This)->lpVtbl -> IsAvailable(This) )
-
-#define IAssemblyModuleImport_BindToObject(This,pBindSink,pAppCtx,llFlags,ppv) \
- ( (This)->lpVtbl -> BindToObject(This,pBindSink,pAppCtx,llFlags,ppv) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IAssemblyModuleImport_INTERFACE_DEFINED__ */
-
-
-#ifndef __IAssemblyScavenger_INTERFACE_DEFINED__
-#define __IAssemblyScavenger_INTERFACE_DEFINED__
-
-/* interface IAssemblyScavenger */
-/* [unique][uuid][object][local] */
-
-
-EXTERN_C const IID IID_IAssemblyScavenger;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("21b8916c-f28e-11d2-a473-00ccff8ef448")
- IAssemblyScavenger : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE ScavengeAssemblyCache( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetCacheDiskQuotas(
- /* [out] */ DWORD *pdwZapQuotaInGAC,
- /* [out] */ DWORD *pdwDownloadQuotaAdmin,
- /* [out] */ DWORD *pdwDownloadQuotaUser) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE SetCacheDiskQuotas(
- /* [in] */ DWORD dwZapQuotaInGAC,
- /* [in] */ DWORD dwDownloadQuotaAdmin,
- /* [in] */ DWORD dwDownloadQuotaUser) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetCurrentCacheUsage(
- /* [out] */ DWORD *dwZapUsage,
- /* [out] */ DWORD *dwDownloadUsage) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IAssemblyScavengerVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IAssemblyScavenger * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IAssemblyScavenger * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IAssemblyScavenger * This);
-
- HRESULT ( STDMETHODCALLTYPE *ScavengeAssemblyCache )(
- IAssemblyScavenger * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetCacheDiskQuotas )(
- IAssemblyScavenger * This,
- /* [out] */ DWORD *pdwZapQuotaInGAC,
- /* [out] */ DWORD *pdwDownloadQuotaAdmin,
- /* [out] */ DWORD *pdwDownloadQuotaUser);
-
- HRESULT ( STDMETHODCALLTYPE *SetCacheDiskQuotas )(
- IAssemblyScavenger * This,
- /* [in] */ DWORD dwZapQuotaInGAC,
- /* [in] */ DWORD dwDownloadQuotaAdmin,
- /* [in] */ DWORD dwDownloadQuotaUser);
-
- HRESULT ( STDMETHODCALLTYPE *GetCurrentCacheUsage )(
- IAssemblyScavenger * This,
- /* [out] */ DWORD *dwZapUsage,
- /* [out] */ DWORD *dwDownloadUsage);
-
- END_INTERFACE
- } IAssemblyScavengerVtbl;
-
- interface IAssemblyScavenger
- {
- CONST_VTBL struct IAssemblyScavengerVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IAssemblyScavenger_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IAssemblyScavenger_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IAssemblyScavenger_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IAssemblyScavenger_ScavengeAssemblyCache(This) \
- ( (This)->lpVtbl -> ScavengeAssemblyCache(This) )
-
-#define IAssemblyScavenger_GetCacheDiskQuotas(This,pdwZapQuotaInGAC,pdwDownloadQuotaAdmin,pdwDownloadQuotaUser) \
- ( (This)->lpVtbl -> GetCacheDiskQuotas(This,pdwZapQuotaInGAC,pdwDownloadQuotaAdmin,pdwDownloadQuotaUser) )
-
-#define IAssemblyScavenger_SetCacheDiskQuotas(This,dwZapQuotaInGAC,dwDownloadQuotaAdmin,dwDownloadQuotaUser) \
- ( (This)->lpVtbl -> SetCacheDiskQuotas(This,dwZapQuotaInGAC,dwDownloadQuotaAdmin,dwDownloadQuotaUser) )
-
-#define IAssemblyScavenger_GetCurrentCacheUsage(This,dwZapUsage,dwDownloadUsage) \
- ( (This)->lpVtbl -> GetCurrentCacheUsage(This,dwZapUsage,dwDownloadUsage) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IAssemblyScavenger_INTERFACE_DEFINED__ */
-
-
-#ifndef __ICodebaseList_INTERFACE_DEFINED__
-#define __ICodebaseList_INTERFACE_DEFINED__
-
-/* interface ICodebaseList */
-/* [unique][uuid][object][local] */
-
-
-EXTERN_C const IID IID_ICodebaseList;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("D8FB9BD6-3969-11d3-B4AF-00C04F8ECB26")
- ICodebaseList : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE AddCodebase(
- /* [in] */ LPCWSTR wzCodebase,
- /* [in] */ DWORD dwFlags) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE RemoveCodebase(
- /* [in] */ DWORD dwIndex) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE RemoveAll( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetCount(
- /* [out] */ DWORD *pdwCount) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetCodebase(
- /* [in] */ DWORD dwIndex,
- /* [out] */ DWORD *pdwFlags,
- /* [annotation][out] */
- __out_ecount_opt(*pcbCodebase) LPWSTR wzCodebase,
- /* [out][in] */ DWORD *pcbCodebase) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct ICodebaseListVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- ICodebaseList * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- ICodebaseList * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- ICodebaseList * This);
-
- HRESULT ( STDMETHODCALLTYPE *AddCodebase )(
- ICodebaseList * This,
- /* [in] */ LPCWSTR wzCodebase,
- /* [in] */ DWORD dwFlags);
-
- HRESULT ( STDMETHODCALLTYPE *RemoveCodebase )(
- ICodebaseList * This,
- /* [in] */ DWORD dwIndex);
-
- HRESULT ( STDMETHODCALLTYPE *RemoveAll )(
- ICodebaseList * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetCount )(
- ICodebaseList * This,
- /* [out] */ DWORD *pdwCount);
-
- HRESULT ( STDMETHODCALLTYPE *GetCodebase )(
- ICodebaseList * This,
- /* [in] */ DWORD dwIndex,
- /* [out] */ DWORD *pdwFlags,
- /* [annotation][out] */
- __out_ecount_opt(*pcbCodebase) LPWSTR wzCodebase,
- /* [out][in] */ DWORD *pcbCodebase);
-
- END_INTERFACE
- } ICodebaseListVtbl;
-
- interface ICodebaseList
- {
- CONST_VTBL struct ICodebaseListVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define ICodebaseList_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define ICodebaseList_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define ICodebaseList_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define ICodebaseList_AddCodebase(This,wzCodebase,dwFlags) \
- ( (This)->lpVtbl -> AddCodebase(This,wzCodebase,dwFlags) )
-
-#define ICodebaseList_RemoveCodebase(This,dwIndex) \
- ( (This)->lpVtbl -> RemoveCodebase(This,dwIndex) )
-
-#define ICodebaseList_RemoveAll(This) \
- ( (This)->lpVtbl -> RemoveAll(This) )
-
-#define ICodebaseList_GetCount(This,pdwCount) \
- ( (This)->lpVtbl -> GetCount(This,pdwCount) )
-
-#define ICodebaseList_GetCodebase(This,dwIndex,pdwFlags,wzCodebase,pcbCodebase) \
- ( (This)->lpVtbl -> GetCodebase(This,dwIndex,pdwFlags,wzCodebase,pcbCodebase) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __ICodebaseList_INTERFACE_DEFINED__ */
-
-
-#ifndef __IDownloadMgr_INTERFACE_DEFINED__
-#define __IDownloadMgr_INTERFACE_DEFINED__
-
-/* interface IDownloadMgr */
-/* [unique][uuid][object][local] */
-
-
-EXTERN_C const IID IID_IDownloadMgr;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("0A6F16F8-ACD7-11d3-B4ED-00C04F8ECB26")
- IDownloadMgr : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE PreDownloadCheck(
- /* [out] */ void **ppv,
- /* [out] */ void **ppvNI) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE DoSetup(
- /* [in] */ LPCWSTR wzSourceUrl,
- /* [in] */ LPCWSTR wzFilePath,
- /* [in] */ const FILETIME *pftLastMod,
- /* [out] */ IUnknown **ppUnk,
- /* [out] */ IUnknown **ppAsmNI) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE ProbeFailed(
- /* [out] */ IUnknown **ppUnk) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE IsDuplicate(
- /* [out] */ IDownloadMgr *ppDLMgr) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE LogResult( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE DownloadEnabled(
- /* [out] */ BOOL *pbEnabled) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetBindInfo(
- /* [out] */ FusionBindInfo *pBindInfo) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE CacheBindingResult(
- /* [in] */ HRESULT hrResult) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IDownloadMgrVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDownloadMgr * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDownloadMgr * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDownloadMgr * This);
-
- HRESULT ( STDMETHODCALLTYPE *PreDownloadCheck )(
- IDownloadMgr * This,
- /* [out] */ void **ppv,
- /* [out] */ void **ppvNI);
-
- HRESULT ( STDMETHODCALLTYPE *DoSetup )(
- IDownloadMgr * This,
- /* [in] */ LPCWSTR wzSourceUrl,
- /* [in] */ LPCWSTR wzFilePath,
- /* [in] */ const FILETIME *pftLastMod,
- /* [out] */ IUnknown **ppUnk,
- /* [out] */ IUnknown **ppAsmNI);
-
- HRESULT ( STDMETHODCALLTYPE *ProbeFailed )(
- IDownloadMgr * This,
- /* [out] */ IUnknown **ppUnk);
-
- HRESULT ( STDMETHODCALLTYPE *IsDuplicate )(
- IDownloadMgr * This,
- /* [out] */ IDownloadMgr *ppDLMgr);
-
- HRESULT ( STDMETHODCALLTYPE *LogResult )(
- IDownloadMgr * This);
-
- HRESULT ( STDMETHODCALLTYPE *DownloadEnabled )(
- IDownloadMgr * This,
- /* [out] */ BOOL *pbEnabled);
-
- HRESULT ( STDMETHODCALLTYPE *GetBindInfo )(
- IDownloadMgr * This,
- /* [out] */ FusionBindInfo *pBindInfo);
-
- HRESULT ( STDMETHODCALLTYPE *CacheBindingResult )(
- IDownloadMgr * This,
- /* [in] */ HRESULT hrResult);
-
- END_INTERFACE
- } IDownloadMgrVtbl;
-
- interface IDownloadMgr
- {
- CONST_VTBL struct IDownloadMgrVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDownloadMgr_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDownloadMgr_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDownloadMgr_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDownloadMgr_PreDownloadCheck(This,ppv,ppvNI) \
- ( (This)->lpVtbl -> PreDownloadCheck(This,ppv,ppvNI) )
-
-#define IDownloadMgr_DoSetup(This,wzSourceUrl,wzFilePath,pftLastMod,ppUnk,ppAsmNI) \
- ( (This)->lpVtbl -> DoSetup(This,wzSourceUrl,wzFilePath,pftLastMod,ppUnk,ppAsmNI) )
-
-#define IDownloadMgr_ProbeFailed(This,ppUnk) \
- ( (This)->lpVtbl -> ProbeFailed(This,ppUnk) )
-
-#define IDownloadMgr_IsDuplicate(This,ppDLMgr) \
- ( (This)->lpVtbl -> IsDuplicate(This,ppDLMgr) )
-
-#define IDownloadMgr_LogResult(This) \
- ( (This)->lpVtbl -> LogResult(This) )
-
-#define IDownloadMgr_DownloadEnabled(This,pbEnabled) \
- ( (This)->lpVtbl -> DownloadEnabled(This,pbEnabled) )
-
-#define IDownloadMgr_GetBindInfo(This,pBindInfo) \
- ( (This)->lpVtbl -> GetBindInfo(This,pBindInfo) )
-
-#define IDownloadMgr_CacheBindingResult(This,hrResult) \
- ( (This)->lpVtbl -> CacheBindingResult(This,hrResult) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDownloadMgr_INTERFACE_DEFINED__ */
-
-
-#ifndef __IHostAssembly_INTERFACE_DEFINED__
-#define __IHostAssembly_INTERFACE_DEFINED__
-
-/* interface IHostAssembly */
-/* [unique][uuid][object][local] */
-
-typedef /* [unique] */ IHostAssembly *LPHOSTASSEMBLY;
-
-
-EXTERN_C const IID IID_IHostAssembly;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("711f7c2d-8234-4505-b02f-7554f46cbf29")
- IHostAssembly : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetAssemblyNameDef(
- /* [out] */ IAssemblyName **ppAssemblyName) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetNextAssemblyNameRef(
- /* [in] */ DWORD nIndex,
- /* [out] */ IAssemblyName **ppAssemblyName) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetNextAssemblyModule(
- /* [in] */ DWORD nIndex,
- /* [out] */ IHostAssemblyModuleImport **ppModImport) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetModuleByName(
- /* [in] */ LPCOLESTR szModuleName,
- /* [out] */ IHostAssemblyModuleImport **ppModImport) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetAssemblyStream(
- /* [out] */ IStream **ppStreamAsm) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetAssemblyId(
- /* [out] */ UINT64 *pAssemblyId) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetAssemblyDebugStream(
- /* [out] */ IStream **ppDebugStream) = 0;
-
- virtual LOADCTX_TYPE STDMETHODCALLTYPE GetFusionLoadContext( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetAssemblyContext(
- /* [out] */ UINT64 *pdwAssemblyContext) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IHostAssemblyVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IHostAssembly * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IHostAssembly * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IHostAssembly * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetAssemblyNameDef )(
- IHostAssembly * This,
- /* [out] */ IAssemblyName **ppAssemblyName);
-
- HRESULT ( STDMETHODCALLTYPE *GetNextAssemblyNameRef )(
- IHostAssembly * This,
- /* [in] */ DWORD nIndex,
- /* [out] */ IAssemblyName **ppAssemblyName);
-
- HRESULT ( STDMETHODCALLTYPE *GetNextAssemblyModule )(
- IHostAssembly * This,
- /* [in] */ DWORD nIndex,
- /* [out] */ IHostAssemblyModuleImport **ppModImport);
-
- HRESULT ( STDMETHODCALLTYPE *GetModuleByName )(
- IHostAssembly * This,
- /* [in] */ LPCOLESTR szModuleName,
- /* [out] */ IHostAssemblyModuleImport **ppModImport);
-
- HRESULT ( STDMETHODCALLTYPE *GetAssemblyStream )(
- IHostAssembly * This,
- /* [out] */ IStream **ppStreamAsm);
-
- HRESULT ( STDMETHODCALLTYPE *GetAssemblyId )(
- IHostAssembly * This,
- /* [out] */ UINT64 *pAssemblyId);
-
- HRESULT ( STDMETHODCALLTYPE *GetAssemblyDebugStream )(
- IHostAssembly * This,
- /* [out] */ IStream **ppDebugStream);
-
- LOADCTX_TYPE ( STDMETHODCALLTYPE *GetFusionLoadContext )(
- IHostAssembly * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetAssemblyContext )(
- IHostAssembly * This,
- /* [out] */ UINT64 *pdwAssemblyContext);
-
- END_INTERFACE
- } IHostAssemblyVtbl;
-
- interface IHostAssembly
- {
- CONST_VTBL struct IHostAssemblyVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IHostAssembly_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IHostAssembly_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IHostAssembly_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IHostAssembly_GetAssemblyNameDef(This,ppAssemblyName) \
- ( (This)->lpVtbl -> GetAssemblyNameDef(This,ppAssemblyName) )
-
-#define IHostAssembly_GetNextAssemblyNameRef(This,nIndex,ppAssemblyName) \
- ( (This)->lpVtbl -> GetNextAssemblyNameRef(This,nIndex,ppAssemblyName) )
-
-#define IHostAssembly_GetNextAssemblyModule(This,nIndex,ppModImport) \
- ( (This)->lpVtbl -> GetNextAssemblyModule(This,nIndex,ppModImport) )
-
-#define IHostAssembly_GetModuleByName(This,szModuleName,ppModImport) \
- ( (This)->lpVtbl -> GetModuleByName(This,szModuleName,ppModImport) )
-
-#define IHostAssembly_GetAssemblyStream(This,ppStreamAsm) \
- ( (This)->lpVtbl -> GetAssemblyStream(This,ppStreamAsm) )
-
-#define IHostAssembly_GetAssemblyId(This,pAssemblyId) \
- ( (This)->lpVtbl -> GetAssemblyId(This,pAssemblyId) )
-
-#define IHostAssembly_GetAssemblyDebugStream(This,ppDebugStream) \
- ( (This)->lpVtbl -> GetAssemblyDebugStream(This,ppDebugStream) )
-
-#define IHostAssembly_GetFusionLoadContext(This) \
- ( (This)->lpVtbl -> GetFusionLoadContext(This) )
-
-#define IHostAssembly_GetAssemblyContext(This,pdwAssemblyContext) \
- ( (This)->lpVtbl -> GetAssemblyContext(This,pdwAssemblyContext) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IHostAssembly_INTERFACE_DEFINED__ */
-
-
-#ifndef __IHostAssemblyModuleImport_INTERFACE_DEFINED__
-#define __IHostAssemblyModuleImport_INTERFACE_DEFINED__
-
-/* interface IHostAssemblyModuleImport */
-/* [unique][uuid][object][local] */
-
-typedef /* [unique] */ IHostAssemblyModuleImport *LPHOSTASSEMBLY_MODULE_IMPORT;
-
-
-EXTERN_C const IID IID_IHostAssemblyModuleImport;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("b6f2729d-6c0f-4944-b692-e5a2ce2c6e7a")
- IHostAssemblyModuleImport : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetModuleName(
- /* [annotation][size_is][out] */
- __out_ecount_full(*pccModuleName) LPOLESTR szModuleName,
- /* [out][in] */ LPDWORD pccModuleName) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetModuleStream(
- /* [out] */ IStream **ppStreamModule) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetModuleId(
- /* [out] */ DWORD *pdwModuleId) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetModuleDebugStream(
- /* [out] */ IStream **ppDebugStream) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IHostAssemblyModuleImportVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IHostAssemblyModuleImport * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IHostAssemblyModuleImport * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IHostAssemblyModuleImport * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetModuleName )(
- IHostAssemblyModuleImport * This,
- /* [annotation][size_is][out] */
- __out_ecount_full(*pccModuleName) LPOLESTR szModuleName,
- /* [out][in] */ LPDWORD pccModuleName);
-
- HRESULT ( STDMETHODCALLTYPE *GetModuleStream )(
- IHostAssemblyModuleImport * This,
- /* [out] */ IStream **ppStreamModule);
-
- HRESULT ( STDMETHODCALLTYPE *GetModuleId )(
- IHostAssemblyModuleImport * This,
- /* [out] */ DWORD *pdwModuleId);
-
- HRESULT ( STDMETHODCALLTYPE *GetModuleDebugStream )(
- IHostAssemblyModuleImport * This,
- /* [out] */ IStream **ppDebugStream);
-
- END_INTERFACE
- } IHostAssemblyModuleImportVtbl;
-
- interface IHostAssemblyModuleImport
- {
- CONST_VTBL struct IHostAssemblyModuleImportVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IHostAssemblyModuleImport_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IHostAssemblyModuleImport_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IHostAssemblyModuleImport_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IHostAssemblyModuleImport_GetModuleName(This,szModuleName,pccModuleName) \
- ( (This)->lpVtbl -> GetModuleName(This,szModuleName,pccModuleName) )
-
-#define IHostAssemblyModuleImport_GetModuleStream(This,ppStreamModule) \
- ( (This)->lpVtbl -> GetModuleStream(This,ppStreamModule) )
-
-#define IHostAssemblyModuleImport_GetModuleId(This,pdwModuleId) \
- ( (This)->lpVtbl -> GetModuleId(This,pdwModuleId) )
-
-#define IHostAssemblyModuleImport_GetModuleDebugStream(This,ppDebugStream) \
- ( (This)->lpVtbl -> GetModuleDebugStream(This,ppDebugStream) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IHostAssemblyModuleImport_INTERFACE_DEFINED__ */
-
-
-/* interface __MIDL_itf_fusionpriv_0000_0017 */
-/* [local] */
-
-STDAPI CreateHistoryReader(LPCWSTR wzFilePath, IHistoryReader **ppHistReader);
-STDAPI LookupHistoryAssembly(LPCWSTR pwzFilePath, FILETIME *pftActivationDate, LPCWSTR pwzAsmName, LPCWSTR pwzPublicKeyToken, LPCWSTR wzCulture, LPCWSTR pwzVerRef, IHistoryAssembly **pHistAsm);
-STDAPI GetHistoryFileDirectory(__out_ecount_opt(*pdwSize) LPWSTR wzDir, DWORD *pdwSize);
-STDAPI PreBindAssembly(IApplicationContext *pAppCtx, IAssemblyName *pName, IAssembly *pAsmParent, IAssemblyName **ppNamePostPolicy, LPVOID pvReserved);
-STDAPI CreateApplicationContext(IAssemblyName *pName, LPAPPLICATIONCONTEXT *ppCtx);
-STDAPI IsRetargetableAssembly(IAssemblyName *pName, BOOL *pbIsRetargetable);
-STDAPI IsOptionallyRetargetableAssembly(IAssemblyName *pName, BOOL *pbIsRetargetable);
-#define EXPLICITBIND_FLAGS_NON_BINDABLE 0x0
-#define EXPLICITBIND_FLAGS_EXE 0x1
-
-
-extern RPC_IF_HANDLE __MIDL_itf_fusionpriv_0000_0017_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_fusionpriv_0000_0017_v0_0_s_ifspec;
-
-/* Additional Prototypes for ALL interfaces */
-
-/* end of Additional Prototypes */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-
diff --git a/src/pal/prebuilt/inc/gchost.h b/src/pal/prebuilt/inc/gchost.h
index 6829b0f531..c9e4fffa18 100644
--- a/src/pal/prebuilt/inc/gchost.h
+++ b/src/pal/prebuilt/inc/gchost.h
@@ -75,7 +75,7 @@ typedef struct _COR_GC_STATS
/*
* WARNING - This is a dummy interface that should never be used.
* The code is written this way because Midl requires a CoClass, Interface, etc... that generates
- * a guid. Removing the IGCHost interface for FEATURE_INCLUDE_ALL_INTERFACES removes the only guid
+ * a guid. Removing the IGCHost interface removes the only guid
* This option was selected because ifdefs are not simple to implement for excluding files in SOURCES
*/
diff --git a/src/pal/src/CMakeLists.txt b/src/pal/src/CMakeLists.txt
index 16c9d8bd6f..5314cdf86b 100644
--- a/src/pal/src/CMakeLists.txt
+++ b/src/pal/src/CMakeLists.txt
@@ -45,6 +45,9 @@ else()
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l)
set(PAL_CMAKE_PLATFORM_ARCH_ARM 1)
add_definitions(-D_ARM_)
+ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL arm)
+ set(PAL_CMAKE_PLATFORM_ARCH_ARM 1)
+ add_definitions(-D_ARM_)
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
set(PAL_CMAKE_PLATFORM_ARCH_ARM64 1)
add_definitions(-D_ARM64_)
@@ -77,13 +80,17 @@ add_definitions(-D_FILE_OFFSET_BITS=64)
if(PAL_CMAKE_PLATFORM_ARCH_AMD64)
add_definitions(-DBIT64=1)
add_definitions(-D_WIN64=1)
+ set(PAL_ARCH_SOURCES_DIR amd64)
elseif(PAL_CMAKE_PLATFORM_ARCH_ARM)
add_definitions(-DBIT32=1)
+ set(PAL_ARCH_SOURCES_DIR arm)
elseif(PAL_CMAKE_PLATFORM_ARCH_ARM64)
add_definitions(-DBIT64=1)
add_definitions(-D_WIN64=1)
+ set(PAL_ARCH_SOURCES_DIR arm64)
elseif(PAL_CMAKE_PLATFORM_ARCH_I386)
add_definitions(-DBIT32=1)
+ set(PAL_ARCH_SOURCES_DIR i386)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL Linux AND NOT CLR_CMAKE_PLATFORM_ALPINE_LINUX)
@@ -101,35 +108,19 @@ set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -Wl,--no
add_compile_options(-fPIC)
-if(PAL_CMAKE_PLATFORM_ARCH_AMD64)
- set(ARCH_SOURCES
- arch/amd64/context2.S
- arch/amd64/debugbreak.S
- arch/amd64/exceptionhelper.S
- arch/amd64/processor.cpp
- )
-elseif(PAL_CMAKE_PLATFORM_ARCH_ARM)
- set(ARCH_SOURCES
- arch/arm/context2.S
- arch/arm/debugbreak.S
- arch/arm/exceptionhelper.S
- arch/arm/processor.cpp
- )
-elseif(PAL_CMAKE_PLATFORM_ARCH_ARM64)
- set(ARCH_SOURCES
- arch/arm64/context2.S
- arch/arm64/debugbreak.S
- arch/arm64/exceptionhelper.S
- arch/arm64/processor.cpp
- )
-elseif(PAL_CMAKE_PLATFORM_ARCH_I386)
- set(ARCH_SOURCES
- arch/i386/context2.S
- arch/i386/debugbreak.S
- arch/i386/exceptionhelper.S
- arch/i386/processor.cpp
+set(ARCH_SOURCES
+ arch/${PAL_ARCH_SOURCES_DIR}/context2.S
+ arch/${PAL_ARCH_SOURCES_DIR}/debugbreak.S
+ arch/${PAL_ARCH_SOURCES_DIR}/exceptionhelper.S
+ arch/${PAL_ARCH_SOURCES_DIR}/processor.cpp
+)
+
+if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
+ list(APPEND PLATFORM_SOURCES
+ arch/${PAL_ARCH_SOURCES_DIR}/callsignalhandlerwrapper.S
+ arch/${PAL_ARCH_SOURCES_DIR}/signalhandlerhelper.cpp
)
-endif()
+endif(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
if(PAL_CMAKE_PLATFORM_ARCH_ARM)
set_source_files_properties(exception/seh.cpp PROPERTIES COMPILE_FLAGS -Wno-error=inline-asm)
@@ -177,6 +168,7 @@ set(SOURCES
map/virtual.cpp
memory/heap.cpp
memory/local.cpp
+ misc/cgroup.cpp
misc/dbgmsg.cpp
misc/environ.cpp
misc/error.cpp
@@ -189,7 +181,6 @@ set(SOURCES
misc/sysinfo.cpp
misc/time.cpp
misc/utils.cpp
- misc/version.cpp
objmgr/palobjbase.cpp
objmgr/shmobject.cpp
objmgr/shmobjectmanager.cpp
@@ -303,21 +294,26 @@ if(CMAKE_SYSTEM_NAME STREQUAL Linux)
endif()
if(CLR_CMAKE_PLATFORM_ANDROID)
+ find_library(LZMA NAMES lzma)
+
+ if(LZMA STREQUAL LZMA-NOTFOUND)
+ message(FATAL_ERROR "Cannot find liblzma.")
+ endif(LZMA STREQUAL LZMA-NOTFOUND)
+
target_link_libraries(coreclrpal
gnustl_shared
android-support
- android-glob)
+ android-glob
+ ${LZMA})
endif()
- if(NOT CLR_CMAKE_PLATFORM_ANDROID)
- find_library(UNWIND NAMES unwind)
+ find_library(UNWIND NAMES unwind)
- if(UNWIND STREQUAL UNWIND-NOTFOUND)
- message(FATAL_ERROR "Cannot find libunwind. Try installing libunwind8-dev and libunwind8.")
- endif(UNWIND STREQUAL UNWIND-NOTFOUND)
+ if(UNWIND STREQUAL UNWIND-NOTFOUND)
+ message(FATAL_ERROR "Cannot find libunwind. Try installing libunwind8-dev and libunwind8.")
+ endif(UNWIND STREQUAL UNWIND-NOTFOUND)
- target_link_libraries(coreclrpal ${UNWIND})
- endif()
+ target_link_libraries(coreclrpal ${UNWIND})
if(CLR_MAKE_PLATFORM_ANDROID)
find_library(ANDROID_SUPPORT NAMES android-support)
diff --git a/src/pal/src/arch/amd64/callsignalhandlerwrapper.S b/src/pal/src/arch/amd64/callsignalhandlerwrapper.S
new file mode 100644
index 0000000000..8260591c30
--- /dev/null
+++ b/src/pal/src/arch/amd64/callsignalhandlerwrapper.S
@@ -0,0 +1,31 @@
+// 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.
+
+.intel_syntax noprefix
+#include "unixasmmacros.inc"
+#include "asmconstants.h"
+
+.macro CALL_SIGNAL_HANDLER_WRAPPER Alignment
+
+.globl C_FUNC(SignalHandlerWorkerReturnOffset\Alignment)
+C_FUNC(SignalHandlerWorkerReturnOffset\Alignment):
+ .int LOCAL_LABEL(SignalHandlerWorkerReturn\Alignment)-C_FUNC(CallSignalHandlerWrapper\Alignment)
+
+// This function is never called, only a fake stack frame will be setup to have a return
+// address set to SignalHandlerWorkerReturn during SIGSEGV handling.
+// It enables the unwinder to unwind stack from the handling code to the actual failure site.
+NESTED_ENTRY CallSignalHandlerWrapper\Alignment, _TEXT, NoHandler
+ .cfi_def_cfa_offset (128 + 8 + \Alignment) // red zone + return address + alignment
+ .cfi_offset rip, -(128 + 8 + \Alignment)
+ push_nonvol_reg rbp
+ call EXTERNAL_C_FUNC(signal_handler_worker)
+LOCAL_LABEL(SignalHandlerWorkerReturn\Alignment):
+ pop rbp
+ ret
+NESTED_END CallSignalHandlerWrapper\Alignment, _TEXT
+
+.endm
+
+CALL_SIGNAL_HANDLER_WRAPPER 0
+CALL_SIGNAL_HANDLER_WRAPPER 8
diff --git a/src/pal/src/arch/amd64/optimizedtls.cpp b/src/pal/src/arch/amd64/optimizedtls.cpp
deleted file mode 100644
index cd89db6b0a..0000000000
--- a/src/pal/src/arch/amd64/optimizedtls.cpp
+++ /dev/null
@@ -1,237 +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.
-
-/*++
-
-
-
-Module Name:
-
- optimizedtls.cpp
-
-Abstract:
-
- Implementation of platform-specific Thread local storage functions.
-
-
-
---*/
-
-#include "pal/thread.hpp"
-#include "pal/malloc.hpp"
-
-#include <pthread.h>
-
-#include "pal/dbgmsg.h"
-#include "pal/misc.h"
-#include "pal/debug.h"
-
-#include <stddef.h>
-
-using namespace CorUnix;
-
-SET_DEFAULT_DEBUG_CHANNEL(THREAD);
-
-#if defined(USE_OPTIMIZEDTLSGETTER)
-
-#define PAL_safe_offsetof(s,m) ((size_t)((ptrdiff_t)&(char&)(((s *)64)->m))-64)
-
-/*++
-Function:
- CorUnix::TLSMakeOptimizedGetter
-
- Creates a platform-optimized version of TlsGetValue compiled
- for a particular index.
-
- Generates the hot part of CorUnix::InternalGetCurrentThread
- as a chunk of highly optimized machine-specific code at runtime.
-
- Check the difference between CorUnix::InternalGetCurrentThread and
- CorUnix::InternalGetCurrentThreadSlow to see the C/C++ code that matches
- the code generated by this function.
---*/
-PAL_POPTIMIZEDTLSGETTER
-CorUnix::TLSMakeOptimizedGetter(
- IN CPalThread* pThread,
- IN DWORD dwTlsIndex)
-{
-#ifdef BIT64
-#pragma unused(pThread, dwTlsIndex)
- ERROR("TLSMakeOptimizedGetter not rewritten for amd64 yet.");
- return NULL;
-#else
- PAL_POPTIMIZEDTLSGETTER Ret = NULL;
- BYTE* p;
- int i = 0;
-
-#ifdef __APPLE__
-#define TLS_OPTIMIZED_GETTER_SIZE 118
-#else
-#define TLS_OPTIMIZED_GETTER_SIZE 115
-#endif
-
- p = (BYTE*)InternalMalloc(pThread, TLS_OPTIMIZED_GETTER_SIZE * sizeof(BYTE));
-
- if (p == NULL)
- {
- return Ret;
- }
-
- // Need to preserve %ecx, %edx, and %esi registers as specified in
- // GetThreadGeneric(void) in vm/amd64/asmhelpers.s
- p[i++] = 0x51; // push %ecx
- p[i++] = 0x52; // push %edx
- p[i++] = 0x89; // mov %esp,%eax // %eax = sp;
- p[i++] = 0xe0;
- p[i++] = 0xc1; // shr $0x11,%eax // sp >> 17;
- p[i++] = 0xe8;
- p[i++] = 0x11;
- p[i++] = 0x89; // mov %eax,%edx // key = sp >> 17;
- p[i++] = 0xc2;
- p[i++] = 0xc1; // sar $0x7,%edx // key >> 7;
- p[i++] = 0xfa;
- p[i++] = 0x07;
- p[i++] = 0x29; // sub %edx,%eax // key -= key >> 7;
- p[i++] = 0xd0;
- p[i++] = 0x89; // mov %eax,%edx
- p[i++] = 0xc2;
- p[i++] = 0xc1; // sar $0x5,%edx // key >> 5;
- p[i++] = 0xfa;
- p[i++] = 0x05;
- p[i++] = 0x29; // sub %edx,%eax // key -= key >> 5;
- p[i++] = 0xd0;
- p[i++] = 0x89; // mov %eax,%edx
- p[i++] = 0xc2;
- p[i++] = 0xc1; // sar $0x3,%edx // key >> 3;
- p[i++] = 0xfa;
- p[i++] = 0x03;
- p[i++] = 0x29; // sub %edx,%eax // key -= key >> 3;
- p[i++] = 0xd0;
- p[i++] = 0x25; // and $0xff,%eax // key &= 0xFF;
- p[i++] = 0xff;
- p[i++] = 0x00;
- p[i++] = 0x00;
- p[i++] = 0x00;
- p[i++] = 0x8b; // mov (flush_counter),%ecx // %ecx = counter = flush_counter;
- p[i++] = 0x0d;
- *((DWORD*) &p[i]) = (DWORD)&flush_counter;
- i += sizeof(DWORD);
- p[i++] = 0x8b; // mov (thread_hints,%eax,4),%eax // %edx = pThread = thread_hints[key];
- p[i++] = 0x14;
- p[i++] = 0x85;
- *((DWORD*) &p[i]) = (DWORD)&thread_hints;
- i += sizeof(DWORD);
- p[i++] = 0x39; // cmp %esp,offsetof(CPalThread,tlsInfo)+offsetof(CThreadTLSInfo,minStack)(%edx)
- // if ((size_t)pThread->tlsInfo.minStack <= sp)
- p[i++] = 0xa2;
- *((DWORD*) &p[i]) = (DWORD)(PAL_safe_offsetof(CPalThread,tlsInfo)+PAL_safe_offsetof(CThreadTLSInfo,minStack));
- i += sizeof(DWORD);
- p[i++] = 0x77; // ja CallInternalGetCurrentThreadSlow:
- p[i++] = 0x19;
- p[i++] = 0x3b; // cmp offsetof(CPalThread,tlsInfo)+offsetof(CThreadTLSInfo,maxStack)(%edx),%esp
- // if (sp < (size_t)pThread->tlsInfo.maxStack)
- p[i++] = 0xa2;
- *((DWORD*) &p[i]) = (DWORD)(PAL_safe_offsetof(CPalThread,tlsInfo)+PAL_safe_offsetof(CThreadTLSInfo,maxStack));
- i += sizeof(DWORD);
- p[i++] = 0x73; // jae CallInternalGetCurrentThreadSlow:
- p[i++] = 0x11;
- p[i++] = 0x39; // cmp (flush_counter),%ecx // if (counter == flush_counter)
- p[i++] = 0x0d;
- *((DWORD*) &p[i]) = (DWORD)&flush_counter;
- i += sizeof(DWORD);
- p[i++] = 0x75; // jne CallInternalGetCurrentThreadSlow:
- p[i++] = 0x09;
- if (dwTlsIndex != THREAD_OBJECT_TLS_INDEX)
- {
- p[i++] = 0x8b; // mov offsetof(pThread->tlsSlots[dwTlsIndex])(%edx),%eax // %eax = pThread->tlsSlots[dwTlsIndex];
- p[i++] = 0x82;
- *((DWORD*) &p[i]) = (DWORD)(PAL_safe_offsetof(CPalThread,tlsInfo)+PAL_safe_offsetof(CThreadTLSInfo,tlsSlots[dwTlsIndex]));
- i += sizeof(DWORD);
- }
- else
- {
- p[i++] = 0x89; // mov %edx,%eax // %eax = pThread;
- p[i++] = 0xd0;
- p[i++] = 0x90; // nop
- p[i++] = 0x90; // nop
- p[i++] = 0x90; // nop
- p[i++] = 0x90; // nop
- }
- p[i++] = 0x5a; // pop %edx
- p[i++] = 0x59; // pop %ecx
- p[i++] = 0xc3; // ret
- // CallInternalGetCurrentThreadSlow:
- p[i++] = 0x5a; // pop %edx
- p[i++] = 0x59; // pop %ecx
- p[i++] = 0x8d; // lea (thread_hints,%eax,4),%eax // %eax = &thread_hints[key];
- p[i++] = 0x04;
- p[i++] = 0x85;
- *((DWORD*) &p[i]) = (DWORD)&thread_hints;
- i += sizeof(DWORD);
- p[i++] = 0x55; // push %ebp
- p[i++] = 0x89; // mov %esp,%ebp
- p[i++] = 0xe5;
- p[i++] = 0x51; // push %ecx
- p[i++] = 0x89; // mov %esp,%ecx // this is the reference esp - need to match the reference esp used in the fast path.
- p[i++] = 0xe1;
- p[i++] = 0x52; // push %edx
-#ifdef __APPLE__
- // establish 16-byte stack alignment
- p[i++] = 0x83; // subl $8,%esp
- p[i++] = 0xec;
- p[i++] = 0x08;
-#endif
- p[i++] = 0x50; // push %eax // store &thread_hints[key] on stack as 2nd argument;
- p[i++] = 0x51; // push %ecx // reference esp - The 1st argument for call to InternalGetCurrentThreadSlow.
- p[i++] = 0xe8; // call InternalGetCurrentThreadSlow
- *((DWORD*) &p[i]) = (DWORD)&InternalGetCurrentThreadSlow - (DWORD)(&p[i+sizeof(DWORD)]);
- i += sizeof(DWORD);
-#ifdef __APPLE__
- p[i++] = 0x83; // addl $16,%esp
- p[i++] = 0xc4;
- p[i++] = 0x10;
-#else
- p[i++] = 0x83; // addl $8,%esp
- p[i++] = 0xc4;
- p[i++] = 0x08;
-#endif
- if (dwTlsIndex != THREAD_OBJECT_TLS_INDEX)
- {
- p[i++] = 0x8b; // mov offsetof(pThread->tlsSlots[dwTlsIndex])(%eax),%eax // %eax = pThread->tlsSlots[dwTlsIndex];
- p[i++] = 0x80;
- *((DWORD*) &p[i]) = (DWORD)(PAL_safe_offsetof(CPalThread,tlsInfo)+PAL_safe_offsetof(CThreadTLSInfo,tlsSlots[dwTlsIndex]));
- i += sizeof(DWORD);
- }
- p[i++] = 0x5a; // pop %edx
- p[i++] = 0x59; // pop %ecx
- p[i++] = 0xc9; // leave
- p[i++] = 0xc3; // ret
-
- if (i > TLS_OPTIMIZED_GETTER_SIZE)
- {
- ASSERT("Invalid TLS_OPTIMIZED_GETTER_SIZE %d\n", i);
- }
-
- DBG_FlushInstructionCache(p, TLS_OPTIMIZED_GETTER_SIZE * sizeof(BYTE));
-
- Ret = (PAL_POPTIMIZEDTLSGETTER)p;
-
- return Ret;
-#endif // BIT64 else
-}
-
-/*++
-Function:
- TLSFreeOptimizedGetter
-
- Frees a function created by MakeOptimizedTlsGetter().
---*/
-VOID
-CorUnix::TLSFreeOptimizedGetter(
- IN PAL_POPTIMIZEDTLSGETTER pOptimizedTlsGetter)
-{
- InternalFree(InternalGetCurrentThread(), (void *)pOptimizedTlsGetter);
-}
-
-#endif // USE_OPTIMIZEDTLSGETTER
diff --git a/src/pal/src/arch/amd64/signalhandlerhelper.cpp b/src/pal/src/arch/amd64/signalhandlerhelper.cpp
new file mode 100644
index 0000000000..8789f5a622
--- /dev/null
+++ b/src/pal/src/arch/amd64/signalhandlerhelper.cpp
@@ -0,0 +1,70 @@
+// 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 "pal/dbgmsg.h"
+SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); // some headers have code with asserts, so do this first
+
+#include "pal/palinternal.h"
+#include "pal/context.h"
+#include "pal/signal.hpp"
+#include "pal/utils.h"
+#include <sys/ucontext.h>
+
+/*++
+Function :
+ signal_handler_worker
+
+ Handles signal on the original stack where the signal occured.
+ Invoked via setcontext.
+
+Parameters :
+ POSIX signal handler parameter list ("man sigaction" for details)
+ returnPoint - context to which the function returns if the common_signal_handler returns
+
+ (no return value)
+--*/
+void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint)
+{
+ ucontext_t *ucontext = (ucontext_t *)context;
+ size_t faultSp = (size_t)MCREG_Rsp(ucontext->uc_mcontext);
+
+ _ASSERTE(IS_ALIGNED(faultSp, 8));
+
+ size_t fakeFrameReturnAddress;
+
+ if (IS_ALIGNED(faultSp, 16))
+ {
+ fakeFrameReturnAddress = (size_t)SignalHandlerWorkerReturnOffset0 + (size_t)CallSignalHandlerWrapper0;
+ }
+ else
+ {
+ fakeFrameReturnAddress = (size_t)SignalHandlerWorkerReturnOffset8 + (size_t)CallSignalHandlerWrapper8;
+ }
+
+ // preserve 128 bytes long red zone and align stack pointer
+ size_t* sp = (size_t*)ALIGN_DOWN(faultSp - 128, 16);
+
+ // Build fake stack frame to enable the stack unwinder to unwind from signal_handler_worker to the faulting instruction
+ *--sp = (size_t)MCREG_Rip(ucontext->uc_mcontext);
+ *--sp = (size_t)MCREG_Rbp(ucontext->uc_mcontext);
+ size_t fp = (size_t)sp;
+ *--sp = fakeFrameReturnAddress;
+
+ // Switch the current context to the signal_handler_worker and the original stack
+ CONTEXT context2;
+ RtlCaptureContext(&context2);
+
+ // We don't care about the other registers state since the stack unwinding restores
+ // them for the target frame directly from the signal context.
+ context2.Rsp = (size_t)sp;
+ context2.Rbx = (size_t)faultSp;
+ context2.Rbp = (size_t)fp;
+ context2.Rip = (size_t)signal_handler_worker;
+ context2.Rdi = code;
+ context2.Rsi = (size_t)siginfo;
+ context2.Rdx = (size_t)context;
+ context2.Rcx = (size_t)returnPoint;
+
+ RtlRestoreContext(&context2, NULL);
+}
diff --git a/src/pal/src/arch/arm/callsignalhandlerwrapper.S b/src/pal/src/arch/arm/callsignalhandlerwrapper.S
new file mode 100644
index 0000000000..266e4fdfe9
--- /dev/null
+++ b/src/pal/src/arch/arm/callsignalhandlerwrapper.S
@@ -0,0 +1,32 @@
+// 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 "unixasmmacros.inc"
+#include "asmconstants.h"
+
+.syntax unified
+.thumb
+
+.macro CALL_SIGNAL_HANDLER_WRAPPER Alignment
+
+.globl C_FUNC(SignalHandlerWorkerReturnOffset\Alignment)
+C_FUNC(SignalHandlerWorkerReturnOffset\Alignment):
+ .int LOCAL_LABEL(SignalHandlerWorkerReturn\Alignment)-C_FUNC(CallSignalHandlerWrapper\Alignment)
+
+// This function is never called, only a fake stack frame will be setup to have a return
+// address set to SignalHandlerWorkerReturn during SIGSEGV handling.
+// It enables the unwinder to unwind stack from the handling code to the actual failure site.
+NESTED_ENTRY CallSignalHandlerWrapper\Alignment, _TEXT, NoHandler
+ sub sp, sp, #(8 + \Alignment) // red zone + alignment
+ stmfd sp!, {r7, lr}
+ bl EXTERNAL_C_FUNC(signal_handler_worker)
+LOCAL_LABEL(SignalHandlerWorkerReturn\Alignment):
+ ldmfd sp!, {r7, lr}
+ bx lr
+NESTED_END CallSignalHandlerWrapper\Alignment, _TEXT
+
+.endm
+
+CALL_SIGNAL_HANDLER_WRAPPER 0
+CALL_SIGNAL_HANDLER_WRAPPER 4
diff --git a/src/pal/src/arch/arm/signalhandlerhelper.cpp b/src/pal/src/arch/arm/signalhandlerhelper.cpp
new file mode 100644
index 0000000000..e1ad460905
--- /dev/null
+++ b/src/pal/src/arch/arm/signalhandlerhelper.cpp
@@ -0,0 +1,70 @@
+// 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 "pal/dbgmsg.h"
+SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); // some headers have code with asserts, so do this first
+
+#include "pal/palinternal.h"
+#include "pal/context.h"
+#include "pal/signal.hpp"
+#include "pal/utils.h"
+#include <sys/ucontext.h>
+
+/*++
+Function :
+ signal_handler_worker
+
+ Handles signal on the original stack where the signal occured.
+ Invoked via setcontext.
+
+Parameters :
+ POSIX signal handler parameter list ("man sigaction" for details)
+ returnPoint - context to which the function returns if the common_signal_handler returns
+
+ (no return value)
+--*/
+void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint)
+{
+ ucontext_t *ucontext = (ucontext_t *)context;
+ size_t faultSp = (size_t)MCREG_Sp(ucontext->uc_mcontext);
+
+ _ASSERTE(IS_ALIGNED(faultSp, 4));
+
+ size_t fakeFrameReturnAddress;
+
+ if (IS_ALIGNED(faultSp, 8))
+ {
+ fakeFrameReturnAddress = (size_t)SignalHandlerWorkerReturnOffset0 + (size_t)CallSignalHandlerWrapper0;
+ }
+ else
+ {
+ fakeFrameReturnAddress = (size_t)SignalHandlerWorkerReturnOffset4 + (size_t)CallSignalHandlerWrapper4;
+ }
+
+ // preserve 8 bytes long red zone and align stack pointer
+ size_t* sp = (size_t*)ALIGN_DOWN(faultSp - 8, 8);
+
+ // Build fake stack frame to enable the stack unwinder to unwind from signal_handler_worker to the faulting instruction
+ // pushed LR
+ *--sp = (size_t)MCREG_Pc(ucontext->uc_mcontext);
+ // pushed frame pointer
+ *--sp = (size_t)MCREG_R7(ucontext->uc_mcontext);
+
+ // Switch the current context to the signal_handler_worker and the original stack
+ CONTEXT context2;
+ RtlCaptureContext(&context2);
+
+ // We don't care about the other registers state since the stack unwinding restores
+ // them for the target frame directly from the signal context.
+ context2.Sp = (size_t)sp;
+ context2.R7 = (size_t)sp; // Fp and Sp are the same
+ context2.Lr = fakeFrameReturnAddress;
+ context2.Pc = (size_t)signal_handler_worker;
+ context2.R0 = code;
+ context2.R1 = (size_t)siginfo;
+ context2.R2 = (size_t)context;
+ context2.R3 = (size_t)returnPoint;
+
+ RtlRestoreContext(&context2, NULL);
+}
diff --git a/src/pal/src/arch/arm64/asmconstants.h b/src/pal/src/arch/arm64/asmconstants.h
new file mode 100644
index 0000000000..b2bf74461f
--- /dev/null
+++ b/src/pal/src/arch/arm64/asmconstants.h
@@ -0,0 +1,95 @@
+// 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.
+
+#ifndef __PAL_ARM64_ASMCONSTANTS_H__
+#define __PAL_ARM64_ASMCONSTANTS_H__
+
+#define CONTEXT_ARM64 0x00400000L
+
+#define CONTEXT_CONTROL_BIT (0)
+#define CONTEXT_INTEGER_BIT (1)
+#define CONTEXT_FLOATING_POINT_BIT (2)
+#define CONTEXT_DEBUG_REGISTERS_BIT (3)
+
+#define CONTEXT_CONTROL (CONTEXT_ARM64 | (1L << CONTEXT_CONTROL_BIT))
+#define CONTEXT_INTEGER (CONTEXT_ARM64 | (1 << CONTEXT_INTEGER_BIT))
+#define CONTEXT_FLOATING_POINT (CONTEXT_ARM64 | (1 << CONTEXT_FLOATING_POINT_BIT))
+#define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARM64 | (1 << CONTEXT_DEBUG_REGISTERS_BIT))
+
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
+
+
+#define CONTEXT_ContextFlags 0
+#define CONTEXT_Cpsr CONTEXT_ContextFlags+4
+#define CONTEXT_X0 CONTEXT_Cpsr+4
+#define CONTEXT_X1 CONTEXT_X0+8
+#define CONTEXT_X2 CONTEXT_X1+8
+#define CONTEXT_X3 CONTEXT_X2+8
+#define CONTEXT_X4 CONTEXT_X3+8
+#define CONTEXT_X5 CONTEXT_X4+8
+#define CONTEXT_X6 CONTEXT_X5+8
+#define CONTEXT_X7 CONTEXT_X6+8
+#define CONTEXT_X8 CONTEXT_X7+8
+#define CONTEXT_X9 CONTEXT_X8+8
+#define CONTEXT_X10 CONTEXT_X9+8
+#define CONTEXT_X11 CONTEXT_X10+8
+#define CONTEXT_X12 CONTEXT_X11+8
+#define CONTEXT_X13 CONTEXT_X12+8
+#define CONTEXT_X14 CONTEXT_X13+8
+#define CONTEXT_X15 CONTEXT_X14+8
+#define CONTEXT_X16 CONTEXT_X15+8
+#define CONTEXT_X17 CONTEXT_X16+8
+#define CONTEXT_X18 CONTEXT_X17+8
+#define CONTEXT_X19 CONTEXT_X18+8
+#define CONTEXT_X20 CONTEXT_X19+8
+#define CONTEXT_X21 CONTEXT_X20+8
+#define CONTEXT_X22 CONTEXT_X21+8
+#define CONTEXT_X23 CONTEXT_X22+8
+#define CONTEXT_X24 CONTEXT_X23+8
+#define CONTEXT_X25 CONTEXT_X24+8
+#define CONTEXT_X26 CONTEXT_X25+8
+#define CONTEXT_X27 CONTEXT_X26+8
+#define CONTEXT_X28 CONTEXT_X27+8
+#define CONTEXT_Fp CONTEXT_X28+8
+#define CONTEXT_Lr CONTEXT_Fp+8
+#define CONTEXT_Sp CONTEXT_Lr+8
+#define CONTEXT_Pc CONTEXT_Sp+8
+#define CONTEXT_NEON_OFFSET CONTEXT_Pc+8
+#define CONTEXT_V0 0
+#define CONTEXT_V1 CONTEXT_V0+16
+#define CONTEXT_V2 CONTEXT_V1+16
+#define CONTEXT_V3 CONTEXT_V2+16
+#define CONTEXT_V4 CONTEXT_V3+16
+#define CONTEXT_V5 CONTEXT_V4+16
+#define CONTEXT_V6 CONTEXT_V5+16
+#define CONTEXT_V7 CONTEXT_V6+16
+#define CONTEXT_V8 CONTEXT_V7+16
+#define CONTEXT_V9 CONTEXT_V8+16
+#define CONTEXT_V10 CONTEXT_V9+16
+#define CONTEXT_V11 CONTEXT_V10+16
+#define CONTEXT_V12 CONTEXT_V11+16
+#define CONTEXT_V13 CONTEXT_V12+16
+#define CONTEXT_V14 CONTEXT_V13+16
+#define CONTEXT_V15 CONTEXT_V14+16
+#define CONTEXT_V16 CONTEXT_V15+16
+#define CONTEXT_V17 CONTEXT_V16+16
+#define CONTEXT_V18 CONTEXT_V17+16
+#define CONTEXT_V19 CONTEXT_V18+16
+#define CONTEXT_V20 CONTEXT_V19+16
+#define CONTEXT_V21 CONTEXT_V20+16
+#define CONTEXT_V22 CONTEXT_V21+16
+#define CONTEXT_V23 CONTEXT_V22+16
+#define CONTEXT_V24 CONTEXT_V23+16
+#define CONTEXT_V25 CONTEXT_V24+16
+#define CONTEXT_V26 CONTEXT_V25+16
+#define CONTEXT_V27 CONTEXT_V26+16
+#define CONTEXT_V28 CONTEXT_V27+16
+#define CONTEXT_V29 CONTEXT_V28+16
+#define CONTEXT_V30 CONTEXT_V29+16
+#define CONTEXT_V31 CONTEXT_V30+16
+#define CONTEXT_FLOAT_CONTROL_OFFSET CONTEXT_V31
+#define CONTEXT_Fpcr 0
+#define CONTEXT_Fpsr CONTEXT_Fpcr+4
+
+#endif
diff --git a/src/pal/src/arch/arm64/callsignalhandlerwrapper.S b/src/pal/src/arch/arm64/callsignalhandlerwrapper.S
new file mode 100644
index 0000000000..90fb602479
--- /dev/null
+++ b/src/pal/src/arch/arm64/callsignalhandlerwrapper.S
@@ -0,0 +1,32 @@
+// 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 "unixasmmacros.inc"
+#include "asmconstants.h"
+
+.macro CALL_SIGNAL_HANDLER_WRAPPER Alignment
+
+.globl C_FUNC(SignalHandlerWorkerReturnOffset\Alignment)
+C_FUNC(SignalHandlerWorkerReturnOffset\Alignment):
+ .int LOCAL_LABEL(SignalHandlerWorkerReturn\Alignment)-C_FUNC(CallSignalHandlerWrapper\Alignment)
+
+// This function is never called, only a fake stack frame will be setup to have a return
+// address set to SignalHandlerWorkerReturn during SIGSEGV handling.
+// It enables the unwinder to unwind stack from the handling code to the actual failure site.
+NESTED_ENTRY CallSignalHandlerWrapper\Alignment, _TEXT, NoHandler
+__StackAllocationSize = (128 + 8 + 8 + \Alignment) // red zone + fp + lr + alignment
+ PROLOG_STACK_ALLOC __StackAllocationSize
+ .cfi_adjust_cfa_offset __StackAllocationSize
+ PROLOG_SAVE_REG_PAIR fp, lr, 0
+ bl EXTERNAL_C_FUNC(signal_handler_worker)
+LOCAL_LABEL(SignalHandlerWorkerReturn\Alignment):
+ EPILOG_RESTORE_REG_PAIR fp, lr, 0
+ EPILOG_STACK_FREE __StackAllocationSize
+ ret
+NESTED_END CallSignalHandlerWrapper\Alignment, _TEXT
+
+.endm
+
+CALL_SIGNAL_HANDLER_WRAPPER 0
+CALL_SIGNAL_HANDLER_WRAPPER 8
diff --git a/src/pal/src/arch/arm64/context2.S b/src/pal/src/arch/arm64/context2.S
index a64e62c94d..e62a9ac4d9 100644
--- a/src/pal/src/arch/arm64/context2.S
+++ b/src/pal/src/arch/arm64/context2.S
@@ -8,87 +8,7 @@
//
#include "unixasmmacros.inc"
-
-#define CONTEXT_ARM64 0x00400000L
-
-#define CONTEXT_CONTROL (CONTEXT_ARM64 | 0x1L)
-#define CONTEXT_INTEGER (CONTEXT_ARM64 | 0x2L)
-#define CONTEXT_FLOATING_POINT (CONTEXT_ARM64 | 0x4L)
-#define CONTEXT_DEBUG_REGISTERS (CONTEXT_ARM64 | 0x8L)
-
-#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
-
-#define CONTEXT_ContextFlags 0
-#define CONTEXT_Cpsr CONTEXT_ContextFlags+4
-#define CONTEXT_X0 CONTEXT_Cpsr+4
-#define CONTEXT_X1 CONTEXT_X0+8
-#define CONTEXT_X2 CONTEXT_X1+8
-#define CONTEXT_X3 CONTEXT_X2+8
-#define CONTEXT_X4 CONTEXT_X3+8
-#define CONTEXT_X5 CONTEXT_X4+8
-#define CONTEXT_X6 CONTEXT_X5+8
-#define CONTEXT_X7 CONTEXT_X6+8
-#define CONTEXT_X8 CONTEXT_X7+8
-#define CONTEXT_X9 CONTEXT_X8+8
-#define CONTEXT_X10 CONTEXT_X9+8
-#define CONTEXT_X11 CONTEXT_X10+8
-#define CONTEXT_X12 CONTEXT_X11+8
-#define CONTEXT_X13 CONTEXT_X12+8
-#define CONTEXT_X14 CONTEXT_X13+8
-#define CONTEXT_X15 CONTEXT_X14+8
-#define CONTEXT_X16 CONTEXT_X15+8
-#define CONTEXT_X17 CONTEXT_X16+8
-#define CONTEXT_X18 CONTEXT_X17+8
-#define CONTEXT_X19 CONTEXT_X18+8
-#define CONTEXT_X20 CONTEXT_X19+8
-#define CONTEXT_X21 CONTEXT_X20+8
-#define CONTEXT_X22 CONTEXT_X21+8
-#define CONTEXT_X23 CONTEXT_X22+8
-#define CONTEXT_X24 CONTEXT_X23+8
-#define CONTEXT_X25 CONTEXT_X24+8
-#define CONTEXT_X26 CONTEXT_X25+8
-#define CONTEXT_X27 CONTEXT_X26+8
-#define CONTEXT_X28 CONTEXT_X27+8
-#define CONTEXT_Fp CONTEXT_X28+8
-#define CONTEXT_Lr CONTEXT_Fp+8
-#define CONTEXT_Sp CONTEXT_Lr+8
-#define CONTEXT_Pc CONTEXT_Sp+8
-#define CONTEXT_NEON_OFFSET CONTEXT_Pc+8
-#define CONTEXT_V0 0
-#define CONTEXT_V1 CONTEXT_V0+16
-#define CONTEXT_V2 CONTEXT_V1+16
-#define CONTEXT_V3 CONTEXT_V2+16
-#define CONTEXT_V4 CONTEXT_V3+16
-#define CONTEXT_V5 CONTEXT_V4+16
-#define CONTEXT_V6 CONTEXT_V5+16
-#define CONTEXT_V7 CONTEXT_V6+16
-#define CONTEXT_V8 CONTEXT_V7+16
-#define CONTEXT_V9 CONTEXT_V8+16
-#define CONTEXT_V10 CONTEXT_V9+16
-#define CONTEXT_V11 CONTEXT_V10+16
-#define CONTEXT_V12 CONTEXT_V11+16
-#define CONTEXT_V13 CONTEXT_V12+16
-#define CONTEXT_V14 CONTEXT_V13+16
-#define CONTEXT_V15 CONTEXT_V14+16
-#define CONTEXT_V16 CONTEXT_V15+16
-#define CONTEXT_V17 CONTEXT_V16+16
-#define CONTEXT_V18 CONTEXT_V17+16
-#define CONTEXT_V19 CONTEXT_V18+16
-#define CONTEXT_V20 CONTEXT_V19+16
-#define CONTEXT_V21 CONTEXT_V20+16
-#define CONTEXT_V22 CONTEXT_V21+16
-#define CONTEXT_V23 CONTEXT_V22+16
-#define CONTEXT_V24 CONTEXT_V23+16
-#define CONTEXT_V25 CONTEXT_V24+16
-#define CONTEXT_V26 CONTEXT_V25+16
-#define CONTEXT_V27 CONTEXT_V26+16
-#define CONTEXT_V28 CONTEXT_V27+16
-#define CONTEXT_V29 CONTEXT_V28+16
-#define CONTEXT_V30 CONTEXT_V29+16
-#define CONTEXT_V31 CONTEXT_V30+16
-#define CONTEXT_FLOAT_CONTROL_OFFSET CONTEXT_V31
-#define CONTEXT_Fpcr 0
-#define CONTEXT_Fpsr CONTEXT_Fpcr+4
+#include "asmconstants.h"
// Incoming:
// x0: Context*
@@ -115,10 +35,8 @@ LEAF_ENTRY CONTEXT_CaptureContext, _TEXT
ldr x2, [sp, 24]
str w2, [x0, CONTEXT_Cpsr]
stp fp, lr, [x0, CONTEXT_Fp]
- add sp, sp, #32
- mov x2, sp
+ add x2, sp, #32
stp x2, lr, [x0, CONTEXT_Sp]
- sub sp, sp, #32
LOCAL_LABEL(Done_CONTEXT_CONTROL):
// we dont clobber x1 in the CONTEXT_CONTROL case
@@ -224,14 +142,8 @@ LEAF_ENTRY RtlRestoreContext, _TEXT
// since we potentially clobber x0 below, we'll bank it in x16
mov x16, x0
- ldr w2, [x16, CONTEXT_ContextFlags]
- // clangs assembler doesn't seem to support the mov Wx, imm32 yet
- movz w3, #0x40, lsl #16
- movk w3, #0x4
- mov w4, w3
- and w3, w2, w3
- cmp w3, w4
- b.ne LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT)
+ ldr w17, [x16, CONTEXT_ContextFlags]
+ tbz w17, #CONTEXT_FLOATING_POINT_BIT, LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT)
add x16, x16, CONTEXT_NEON_OFFSET
ldp q0, q1, [x16, CONTEXT_V0]
@@ -256,12 +168,7 @@ LEAF_ENTRY RtlRestoreContext, _TEXT
sub x16, x16, CONTEXT_NEON_OFFSET
LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT):
- movz w2, #0x40, lsl #16
- movk w2, #0x2
- mov w3, w2
- and w2, w1, w2
- cmp w2, w3
- b.ne LOCAL_LABEL(No_Restore_CONTEXT_INTEGER)
+ tbz w17, #CONTEXT_INTEGER_BIT, LOCAL_LABEL(No_Restore_CONTEXT_INTEGER)
ldp x0, x1, [x16, CONTEXT_X0]
ldp x2, x3, [x16, CONTEXT_X2]
@@ -279,12 +186,7 @@ LOCAL_LABEL(No_Restore_CONTEXT_FLOATING_POINT):
ldr x28, [x16, CONTEXT_X28]
LOCAL_LABEL(No_Restore_CONTEXT_INTEGER):
- movz w2, #0x40, lsl #16
- movk w2, #0x2
- mov w3, w2
- and w2, w1, w2
- cmp w2, w3
- b.ne LOCAL_LABEL(No_Restore_CONTEXT_CONTROL)
+ tbz w17, #CONTEXT_CONTROL_BIT, LOCAL_LABEL(No_Restore_CONTEXT_CONTROL)
ldr w17, [x16, CONTEXT_Cpsr]
msr nzcv, x17
@@ -293,8 +195,8 @@ LOCAL_LABEL(No_Restore_CONTEXT_INTEGER):
mov sp, x17
ldr x17, [x16, CONTEXT_Pc]
br x17
-
+
LOCAL_LABEL(No_Restore_CONTEXT_CONTROL):
- ret
+ ret
LEAF_END RtlRestoreContext, _TEXT
diff --git a/src/pal/src/arch/arm64/exceptionhelper.S b/src/pal/src/arch/arm64/exceptionhelper.S
index 4fdcfc5eb1..480846eb61 100644
--- a/src/pal/src/arch/arm64/exceptionhelper.S
+++ b/src/pal/src/arch/arm64/exceptionhelper.S
@@ -3,7 +3,30 @@
// See the LICENSE file in the project root for more information.
#include "unixasmmacros.inc"
+#include "asmconstants.h"
+//////////////////////////////////////////////////////////////////////////
+//
+// This function creates a stack frame right below the target frame, restores all callee
+// saved registers, SP, and LR from the passed in context.
+// Then it uses the ThrowExceptionHelper to throw the passed in exception from that context.
+// EXTERN_C void ThrowExceptionFromContextInternal(CONTEXT* context, PAL_SEHException* ex);
LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT
- EMIT_BREAKPOINT
+ // Save the FP & LR to the stack so that the unwind can work at the instruction after
+ // loading the FP from the context, but before loading the SP from the context.
+ stp fp, lr, [sp, -16]!
+
+ ldp x19,x20, [x0, #(CONTEXT_X19)]
+ ldp x21,x22, [x0, #(CONTEXT_X21)]
+ ldp x23,x24, [x0, #(CONTEXT_X23)]
+ ldp x24,x25, [x0, #(CONTEXT_X24)]
+ ldp x26,x27, [x0, #(CONTEXT_X26)]
+ ldp x28,fp, [x0, #(CONTEXT_X28)]
+ ldr lr, [x0, #(CONTEXT_Pc)]
+ ldr x2, [x0, #(CONTEXT_Sp)]
+ mov sp, x2
+
+ // The PAL_SEHException pointer
+ mov x0, x1
+ b EXTERNAL_C_FUNC(ThrowExceptionHelper)
LEAF_END ThrowExceptionFromContextInternal, _TEXT
diff --git a/src/pal/src/arch/arm64/signalhandlerhelper.cpp b/src/pal/src/arch/arm64/signalhandlerhelper.cpp
new file mode 100644
index 0000000000..c35c629ab3
--- /dev/null
+++ b/src/pal/src/arch/arm64/signalhandlerhelper.cpp
@@ -0,0 +1,67 @@
+// 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 "pal/dbgmsg.h"
+SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); // some headers have code with asserts, so do this first
+
+#include "pal/palinternal.h"
+#include "pal/context.h"
+#include "pal/signal.hpp"
+#include "pal/utils.h"
+#include <sys/ucontext.h>
+
+/*++
+Function :
+ signal_handler_worker
+
+ Handles signal on the original stack where the signal occured.
+ Invoked via setcontext.
+
+Parameters :
+ POSIX signal handler parameter list ("man sigaction" for details)
+ returnPoint - context to which the function returns if the common_signal_handler returns
+
+ (no return value)
+--*/
+void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint)
+{
+ ucontext_t *ucontext = (ucontext_t *)context;
+ size_t faultSp = (size_t)MCREG_Sp(ucontext->uc_mcontext);
+ _ASSERTE(IS_ALIGNED(faultSp, 8));
+
+ size_t fakeFrameReturnAddress;
+
+ if (IS_ALIGNED(faultSp, 16))
+ {
+ fakeFrameReturnAddress = (size_t)SignalHandlerWorkerReturnOffset0 + (size_t)CallSignalHandlerWrapper0;
+ }
+ else
+ {
+ fakeFrameReturnAddress = (size_t)SignalHandlerWorkerReturnOffset8 + (size_t)CallSignalHandlerWrapper8;
+ }
+
+ // preserve 128 bytes long red zone and align stack pointer
+ size_t* sp = (size_t*)ALIGN_DOWN(faultSp - 128, 16);
+
+ // Build fake stack frame to enable the stack unwinder to unwind from signal_handler_worker to the faulting instruction
+ // pushed LR
+ *--sp = (size_t)MCREG_Pc(ucontext->uc_mcontext);
+ // pushed frame pointer
+ *--sp = (size_t)MCREG_Fp(ucontext->uc_mcontext);
+
+ // Switch the current context to the signal_handler_worker and the original stack
+ CONTEXT context2;
+ RtlCaptureContext(&context2);
+
+ context2.Sp = (size_t)sp;
+ context2.Fp = (size_t)sp;
+ context2.Lr = fakeFrameReturnAddress;
+ context2.Pc = (size_t)signal_handler_worker;
+ context2.X0 = code;
+ context2.X1 = (size_t)siginfo;
+ context2.X2 = (size_t)context;
+ context2.X3 = (size_t)returnPoint;
+
+ RtlRestoreContext(&context2, NULL);
+}
diff --git a/src/pal/src/arch/i386/asmconstants.h b/src/pal/src/arch/i386/asmconstants.h
index ff763ef16b..d947cb8bcd 100644
--- a/src/pal/src/arch/i386/asmconstants.h
+++ b/src/pal/src/arch/i386/asmconstants.h
@@ -28,3 +28,4 @@
#define CONTEXT_Xmm5 CONTEXT_Xmm4+16
#define CONTEXT_Xmm6 CONTEXT_Xmm5+16
#define CONTEXT_Xmm7 CONTEXT_Xmm6+16
+#define CONTEXT_ResumeEsp CONTEXT_ExtendedRegisters+512
diff --git a/src/pal/src/arch/i386/callsignalhandlerwrapper.S b/src/pal/src/arch/i386/callsignalhandlerwrapper.S
new file mode 100644
index 0000000000..26f06d9886
--- /dev/null
+++ b/src/pal/src/arch/i386/callsignalhandlerwrapper.S
@@ -0,0 +1,47 @@
+// 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.
+
+.intel_syntax noprefix
+#include "unixasmmacros.inc"
+#include "asmconstants.h"
+
+.macro CALL_SIGNAL_HANDLER_WRAPPER Alignment
+
+.globl C_FUNC(SignalHandlerWorkerReturnOffset\Alignment)
+C_FUNC(SignalHandlerWorkerReturnOffset\Alignment):
+ .int LOCAL_LABEL(SignalHandlerWorkerReturn\Alignment)-C_FUNC(CallSignalHandlerWrapper\Alignment)
+
+// This function is never called, only a fake stack frame will be setup to have a return
+// address set to SignalHandlerWorkerReturn during SIGSEGV handling.
+// It enables the unwinder to unwind stack from the handling code to the actual failure site.
+NESTED_ENTRY CallSignalHandlerWrapper\Alignment, _TEXT, NoHandler
+
+ .cfi_def_cfa_offset (4 + \Alignment) // return address + stack alignment
+ .cfi_offset eip, -(4 + \Alignment)
+ push ebp
+ .cfi_adjust_cfa_offset 4
+ .cfi_rel_offset ebp, 0
+ mov ebp, esp
+ .cfi_def_cfa_register ebp
+ // Align stack
+ sub esp, 8
+ // Simulate arguments pushing
+ push eax
+ push eax
+ push eax
+ push eax
+ call EXTERNAL_C_FUNC(signal_handler_worker)
+LOCAL_LABEL(SignalHandlerWorkerReturn\Alignment):
+ add esp, 4 * 4 + 8
+ pop ebp
+ ret
+
+NESTED_END CallSignalHandlerWrapper\Alignment, _TEXT
+
+.endm
+
+CALL_SIGNAL_HANDLER_WRAPPER 0
+CALL_SIGNAL_HANDLER_WRAPPER 4
+CALL_SIGNAL_HANDLER_WRAPPER 8
+CALL_SIGNAL_HANDLER_WRAPPER 12
diff --git a/src/pal/src/arch/i386/context2.S b/src/pal/src/arch/i386/context2.S
index 11aba5e647..6c31b074cc 100644
--- a/src/pal/src/arch/i386/context2.S
+++ b/src/pal/src/arch/i386/context2.S
@@ -42,6 +42,7 @@ LEAF_ENTRY CONTEXT_CaptureContext, _TEXT
mov [eax + CONTEXT_Ebp], ebp
lea ebx, [esp + 12]
mov [eax + CONTEXT_Esp], ebx
+ mov [eax + CONTEXT_ResumeEsp], ebx
mov ebx, [esp + 8]
mov [eax + CONTEXT_Eip], ebx
@@ -82,7 +83,7 @@ LOCAL_LABEL(Done_CONTEXT_EXTENDED_REGISTERS):
// Restore
pop ebx
pop eax
- ret 4
+ ret
LEAF_END CONTEXT_CaptureContext, _TEXT
LEAF_ENTRY RtlCaptureContext, _TEXT
@@ -114,7 +115,7 @@ LOCAL_LABEL(Done_Restore_CONTEXT_FLOATING_POINT):
LOCAL_LABEL(Done_Restore_CONTEXT_EXTENDED_REGISTERS):
// Restore Stack
- mov esp, [eax + CONTEXT_Esp]
+ mov esp, [eax + CONTEXT_ResumeEsp]
// Create a minimal frame
push DWORD PTR [eax + CONTEXT_Eip]
diff --git a/src/pal/src/arch/i386/exceptionhelper.S b/src/pal/src/arch/i386/exceptionhelper.S
index 2061be26f8..bf44124479 100644
--- a/src/pal/src/arch/i386/exceptionhelper.S
+++ b/src/pal/src/arch/i386/exceptionhelper.S
@@ -19,11 +19,14 @@
LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT
push ebp
- mov eax, [esp + 12] // ebx: PAL_SEHException *
- mov ebx, [esp + 8] // eax: CONTEXT *
+ mov ecx, [esp + 12] // ecx: PAL_SEHException * (first argument for ThrowExceptionHelper)
+ mov eax, [esp + 8] // ebx: CONTEXT *
- mov ebp, [ebx + CONTEXT_Ebp]
- mov esp, [ebx + CONTEXT_Esp]
+ mov ebp, [eax + CONTEXT_Ebp]
+ mov esp, [eax + CONTEXT_ResumeEsp]
+ mov ebx, [eax + CONTEXT_Ebx]
+ mov esi, [eax + CONTEXT_Esi]
+ mov edi, [eax + CONTEXT_Edi]
// The ESP is re-initialized as the target frame's value, so the current function's
// CFA is now right at the ESP.
@@ -33,11 +36,9 @@ LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT
// the EBP is no longer saved in the current stack frame.
.cfi_restore ebp
- // Store PAL_SEHException as the first argument
- push eax
-
// Store return address to the stack
- mov ebx, [ebx + CONTEXT_Eip]
- push ebx
+ mov eax, [eax + CONTEXT_Eip]
+ push eax
jmp EXTERNAL_C_FUNC(ThrowExceptionHelper)
+
LEAF_END ThrowExceptionFromContextInternal, _TEXT
diff --git a/src/pal/src/arch/i386/signalhandlerhelper.cpp b/src/pal/src/arch/i386/signalhandlerhelper.cpp
new file mode 100644
index 0000000000..3369abe093
--- /dev/null
+++ b/src/pal/src/arch/i386/signalhandlerhelper.cpp
@@ -0,0 +1,78 @@
+// 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 "pal/dbgmsg.h"
+SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); // some headers have code with asserts, so do this first
+
+#include "pal/palinternal.h"
+#include "pal/context.h"
+#include "pal/signal.hpp"
+#include "pal/utils.h"
+#include <sys/ucontext.h>
+
+/*++
+Function :
+ signal_handler_worker
+
+ Handles signal on the original stack where the signal occured.
+ Invoked via setcontext.
+
+Parameters :
+ POSIX signal handler parameter list ("man sigaction" for details)
+ returnPoint - context to which the function returns if the common_signal_handler returns
+
+ (no return value)
+--*/
+void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint)
+{
+ ucontext_t *ucontext = (ucontext_t *)context;
+ size_t faultSp = (size_t)MCREG_Esp(ucontext->uc_mcontext);
+
+ _ASSERTE(IS_ALIGNED(faultSp, 4));
+
+ size_t fakeFrameReturnAddress;
+
+ switch (faultSp & 0xc)
+ {
+ case 0x0:
+ fakeFrameReturnAddress = (size_t)SignalHandlerWorkerReturnOffset0 + (size_t)CallSignalHandlerWrapper0;
+ break;
+ case 0x4:
+ fakeFrameReturnAddress = (size_t)SignalHandlerWorkerReturnOffset4 + (size_t)CallSignalHandlerWrapper4;
+ break;
+ case 0x8:
+ fakeFrameReturnAddress = (size_t)SignalHandlerWorkerReturnOffset8 + (size_t)CallSignalHandlerWrapper8;
+ break;
+ case 0xc:
+ fakeFrameReturnAddress = (size_t)SignalHandlerWorkerReturnOffset12 + (size_t)CallSignalHandlerWrapper12;
+ break;
+ }
+
+ size_t* sp = (size_t*)ALIGN_DOWN(faultSp, 16);
+
+ // Build fake stack frame to enable the stack unwinder to unwind from signal_handler_worker to the faulting instruction
+ *--sp = (size_t)MCREG_Eip(ucontext->uc_mcontext);
+ *--sp = (size_t)MCREG_Ebp(ucontext->uc_mcontext);
+ size_t fp = (size_t)sp;
+ // Align stack
+ sp -= 2;
+ *--sp = (size_t)returnPoint;
+ *--sp = (size_t)context;
+ *--sp = (size_t)siginfo;
+ *--sp = code;
+ *--sp = fakeFrameReturnAddress;
+
+ // Switch the current context to the signal_handler_worker and the original stack
+ CONTEXT context2;
+ RtlCaptureContext(&context2);
+
+ // We don't care about the other registers state since the stack unwinding restores
+ // them for the target frame directly from the signal context.
+ context2.Esp = (size_t)sp;
+ context2.ResumeEsp = (size_t)sp;
+ context2.Ebp = (size_t)fp;
+ context2.Eip = (size_t)signal_handler_worker;
+
+ RtlRestoreContext(&context2, NULL);
+}
diff --git a/src/pal/src/config.h.in b/src/pal/src/config.h.in
index 77d7bfaf5a..ab5fa0341d 100644
--- a/src/pal/src/config.h.in
+++ b/src/pal/src/config.h.in
@@ -40,6 +40,7 @@
#cmakedefine01 HAVE_UTIMES
#cmakedefine01 HAVE_SYSCTL
#cmakedefine01 HAVE_SYSCONF
+#cmakedefine01 HAVE_SYSINFO
#cmakedefine01 HAVE_LOCALTIME_R
#cmakedefine01 HAVE_GMTIME_R
#cmakedefine01 HAVE_TIMEGM
@@ -57,6 +58,8 @@
#cmakedefine01 HAVE_TTRACE
#cmakedefine HAVE_UNW_GET_SAVE_LOC
#cmakedefine HAVE_UNW_GET_ACCESSORS
+#cmakedefine01 HAVE_XSWDEV
+#cmakedefine01 HAVE_XSW_USAGE
#cmakedefine01 HAVE_STAT_TIMESPEC
#cmakedefine01 HAVE_STAT_NSEC
diff --git a/src/pal/src/configure.cmake b/src/pal/src/configure.cmake
index 4f2bc5739b..4d78f54423 100644
--- a/src/pal/src/configure.cmake
+++ b/src/pal/src/configure.cmake
@@ -78,6 +78,7 @@ check_function_exists(fsync HAVE_FSYNC)
check_function_exists(futimes HAVE_FUTIMES)
check_function_exists(utimes HAVE_UTIMES)
check_function_exists(sysctl HAVE_SYSCTL)
+check_function_exists(sysinfo HAVE_SYSINFO)
check_function_exists(sysconf HAVE_SYSCONF)
check_function_exists(localtime_r HAVE_LOCALTIME_R)
check_function_exists(gmtime_r HAVE_GMTIME_R)
@@ -122,6 +123,7 @@ check_struct_has_member ("struct stat" st_atimensec "sys/types.h;sys/stat.h" HAV
check_struct_has_member ("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF)
check_struct_has_member ("ucontext_t" uc_mcontext.gregs[0] ucontext.h HAVE_GREGSET_T)
check_struct_has_member ("ucontext_t" uc_mcontext.__gregs[0] ucontext.h HAVE___GREGSET_T)
+check_struct_has_member ("struct sysinfo" mem_unit "sys/sysinfo.h" HAVE_SYSINFO_WITH_MEM_UNIT)
set(CMAKE_EXTRA_INCLUDE_FILES machine/reg.h)
check_type_size("struct reg" BSD_REGS_T)
@@ -728,9 +730,9 @@ check_cxx_source_runs("
int main(void) {
double infinity = 1.0 / 0.0;
if (pow(1.0, infinity) != 1.0 || pow(1.0, -infinity) != 1.0) {
- exit(1)
+ exit(1);
}
- if (!isnan(pow(-1.0, infinity)) || !isnan(pow(-1.0, -infinity))) {
+ if (pow(-1.0, infinity) != 1.0 || pow(-1.0, -infinity) != 1.0) {
exit(1);
}
if (pow(0.0, infinity) != 0.0) {
@@ -742,7 +744,7 @@ int main(void) {
if (pow(-1.1, infinity) != infinity || pow(1.1, infinity) != infinity) {
exit(1);
}
- if (pow(-1.1, -infinity) != 0.0 || pow(1.1, infinity) != 0.0) {
+ if (pow(-1.1, -infinity) != 0.0 || pow(1.1, -infinity) != 0.0) {
exit(1);
}
if (pow(-0.0, -1) != -infinity) {
@@ -982,6 +984,29 @@ int main(int argc, char **argv)
return 0;
}" UNWIND_CONTEXT_IS_UCONTEXT_T)
+check_cxx_source_compiles("
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <vm/vm_param.h>
+
+int main(int argc, char **argv)
+{
+ struct xswdev xsw;
+
+ return 0;
+}" HAVE_XSWDEV)
+
+check_cxx_source_compiles("
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+int main(int argc, char **argv)
+{
+ struct xsw_usage xsu;
+
+ return 0;
+}" HAVE_XSW_USAGE)
+
set(CMAKE_REQUIRED_LIBRARIES pthread)
check_cxx_source_compiles("
#include <errno.h>
diff --git a/src/pal/src/cruntime/math.cpp b/src/pal/src/cruntime/math.cpp
index d53dbe7982..7b5175a526 100644
--- a/src/pal/src/cruntime/math.cpp
+++ b/src/pal/src/cruntime/math.cpp
@@ -343,7 +343,7 @@ PALIMPORT double __cdecl PAL_pow(double x, double y)
}
else if (x == -1.0)
{
- ret = PAL_NAN_DBL; // NaN
+ ret = 1.0;
}
else if ((x > -1.0) && (x < 1.0))
{
@@ -362,7 +362,7 @@ PALIMPORT double __cdecl PAL_pow(double x, double y)
}
else if (x == -1.0)
{
- ret = PAL_NAN_DBL; // NaN
+ ret = 1.0;
}
else if ((x > -1.0) && (x < 1.0))
{
@@ -384,17 +384,7 @@ PALIMPORT double __cdecl PAL_pow(double x, double y)
else
#endif // !HAVE_COMPATIBLE_POW
- if ((y == 0.0) && isnan(x))
- {
- // Windows returns NaN for pow(NaN, 0), but POSIX specifies
- // a return value of 1 for that case. We need to return
- // the same result as Windows.
- ret = PAL_NAN_DBL;
- }
- else
- {
- ret = pow(x, y);
- }
+ ret = pow(x, y);
#if !HAVE_VALID_NEGATIVE_INF_POW
if ((ret == PAL_POSINF_DBL) && (x < 0) && isfinite(x) && (ceil(y / 2) != floor(y / 2)))
@@ -706,7 +696,7 @@ PALIMPORT float __cdecl PAL_powf(float x, float y)
}
else if (x == -1.0f)
{
- ret = PAL_NAN_FLT; // NaN
+ ret = 1.0f;
}
else if ((x > -1.0f) && (x < 1.0f))
{
@@ -725,7 +715,7 @@ PALIMPORT float __cdecl PAL_powf(float x, float y)
}
else if (x == -1.0f)
{
- ret = PAL_NAN_FLT; // NaN
+ ret = 1.0f;
}
else if ((x > -1.0f) && (x < 1.0f))
{
@@ -747,18 +737,8 @@ PALIMPORT float __cdecl PAL_powf(float x, float y)
else
#endif // !HAVE_COMPATIBLE_POW
- if ((y == 0.0f) && isnan(x))
- {
- // Windows returns NaN for powf(NaN, 0), but POSIX specifies
- // a return value of 1 for that case. We need to return
- // the same result as Windows.
- ret = PAL_NAN_FLT;
- }
- else
- {
- ret = powf(x, y);
- }
-
+ ret = powf(x, y);
+
#if !HAVE_VALID_NEGATIVE_INF_POW
if ((ret == PAL_POSINF_FLT) && (x < 0) && isfinite(x) && (ceilf(y / 2) != floorf(y / 2)))
{
diff --git a/src/pal/src/cruntime/misctls.cpp b/src/pal/src/cruntime/misctls.cpp
index e46582ec17..2df32fe115 100644
--- a/src/pal/src/cruntime/misctls.cpp
+++ b/src/pal/src/cruntime/misctls.cpp
@@ -128,6 +128,11 @@ done:
return retval;
}
+UINT GetExponent(double d)
+{
+ return (*((UINT*)&d + 1) >> 20) & 0x000007ff;
+}
+
/**
Function:
@@ -150,250 +155,143 @@ NOTES:
char * __cdecl
_ecvt( double value, int count, int * dec, int * sign )
{
- CONST CHAR * FORMAT_STRING = "%.348e";
- CHAR TempBuffer[ ECVT_MAX_BUFFER_SIZE ];
- CPalThread *pThread = NULL;
- LPSTR lpReturnBuffer = NULL;
- LPSTR lpStartOfReturnBuffer = NULL;
- LPSTR lpTempBuffer = NULL;
- LPSTR lpEndOfTempBuffer = NULL;
- INT nTempBufferLength = 0;
- CHAR ExponentBuffer[ 6 ];
- INT nExponentValue = 0;
- INT LoopIndex = 0;
-
PERF_ENTRY(_ecvt);
ENTRY( "_ecvt( value=%.30g, count=%d, dec=%p, sign=%p )\n",
value, count, dec, sign );
+
+ _ASSERTE(dec != nullptr && sign != nullptr);
+ CPalThread *pThread = InternalGetCurrentThread();
+ LPSTR lpStartOfReturnBuffer = pThread->crtInfo.ECVTBuffer;
- /* Get the per-thread buffer from the thread structure. */
- pThread = InternalGetCurrentThread();
-
- lpStartOfReturnBuffer = lpReturnBuffer = pThread->crtInfo.ECVTBuffer;
-
- /* Sanity checks */
- if ( !dec || !sign )
- {
- ERROR( "dec and sign have to be valid pointers.\n" );
- *lpReturnBuffer = '\0';
- goto done;
- }
- else
+ if (count > ECVT_MAX_COUNT_SIZE)
{
- *dec = *sign = 0;
+ count = ECVT_MAX_COUNT_SIZE;
}
- if ( value < 0.0 )
- {
- *sign = 1;
- }
+ // the caller of _ecvt should already checked the Infinity and NAN values
+ _ASSERTE(GetExponent(value) != 0x7ff);
- if ( count > ECVT_MAX_COUNT_SIZE )
+ CHAR TempBuffer[ECVT_MAX_BUFFER_SIZE];
+
+ *dec = *sign = 0;
+
+ if (value < 0.0)
{
- count = ECVT_MAX_COUNT_SIZE;
+ *sign = 1;
}
-
- /* Get the string to work with. */
- sprintf_s( TempBuffer, sizeof(TempBuffer), FORMAT_STRING, value );
-
- /* Check to see if value was a valid number. */
- if ( strcmp( "NaN", TempBuffer ) == 0 || strcmp( "-NaN", TempBuffer ) == 0 )
+
{
- TRACE( "value was not a number!\n" );
- if (strcpy_s( lpStartOfReturnBuffer, ECVT_MAX_BUFFER_SIZE, "1#QNAN0" ) != SAFECRT_SUCCESS)
+ // we have issue #10290 tracking fixing the sign of 0.0 across the platforms
+ if (value == 0.0)
{
- ERROR( "strcpy_s failed!\n" );
- *lpStartOfReturnBuffer = '\0';
+ for (int j = 0; j < count; j++)
+ {
+ lpStartOfReturnBuffer[j] = '0';
+ }
+ lpStartOfReturnBuffer[count] = '\0';
goto done;
+ }
+
+ int tempBufferLength = snprintf(TempBuffer, ECVT_MAX_BUFFER_SIZE, "%.40e", value);
+ _ASSERTE(tempBufferLength > 0 && ECVT_MAX_BUFFER_SIZE > tempBufferLength);
+
+ //
+ // Calculate the exponent value
+ //
+
+ int exponentIndex = strrchr(TempBuffer, 'e') - TempBuffer;
+ _ASSERTE(exponentIndex > 0 && (exponentIndex < tempBufferLength - 1));
+
+ int i = exponentIndex + 1;
+ int exponentSign = 1;
+ if (TempBuffer[i] == '-')
+ {
+ exponentSign = -1;
+ i++;
}
-
- *dec = 1;
- goto done;
- }
-
- /* Check to see if it is infinite. */
- if ( strcmp( "Inf", TempBuffer ) == 0 || strcmp( "-Inf", TempBuffer ) == 0 )
- {
- TRACE( "value is infinite!\n" );
- if (strcpy_s( lpStartOfReturnBuffer, ECVT_MAX_BUFFER_SIZE, "1#INF00" ) != SAFECRT_SUCCESS)
+ else if (TempBuffer[i] == '+')
{
- ERROR( "strcpy_s failed!\n" );
- *lpStartOfReturnBuffer = '\0';
- goto done;
+ i++;
}
- *dec = 1;
- if ( *TempBuffer == '-' )
+ int exponentValue = 0;
+ while (i < tempBufferLength)
{
- *sign = 1;
+ _ASSERTE(TempBuffer[i] >= '0' && TempBuffer[i] <= '9');
+ exponentValue = exponentValue * 10 + ((BYTE) TempBuffer[i] - (BYTE) '0');
+ i++;
}
- goto done;
- }
-
- nTempBufferLength = strlen( TempBuffer );
- lpEndOfTempBuffer = &(TempBuffer[ nTempBufferLength ]);
-
- /* Extract the exponent, and convert it to integer. */
- while ( *lpEndOfTempBuffer != 'e' && nTempBufferLength > 0 )
- {
- nTempBufferLength--;
- lpEndOfTempBuffer--;
- }
-
- ExponentBuffer[ 0 ] = '\0';
- if (strncat_s( ExponentBuffer, sizeof(ExponentBuffer), lpEndOfTempBuffer + 1, 5 ) != SAFECRT_SUCCESS)
- {
- ERROR( "strncat_s failed!\n" );
- *lpStartOfReturnBuffer = '\0';
- goto done;
- }
-
- nExponentValue = atoi( ExponentBuffer );
+ exponentValue *= exponentSign;
+
+ //
+ // Determine decimal location.
+ //
- /* End the string at the 'e' */
- *lpEndOfTempBuffer = '\0';
- nTempBufferLength--;
+ if (exponentValue == 0)
+ {
+ *dec = 1;
+ }
+ else
+ {
+ *dec = exponentValue + 1;
+ }
+
+ //
+ // Copy the string from the temp buffer upto precision characters, removing the sign, and decimal as required.
+ //
+
+ i = 0;
+ int mantissaIndex = 0;
+ while (i < count && mantissaIndex < exponentIndex)
+ {
+ if (TempBuffer[mantissaIndex] >= '0' && TempBuffer[mantissaIndex] <= '9')
+ {
+ lpStartOfReturnBuffer[i] = TempBuffer[mantissaIndex];
+ i++;
+ }
+ mantissaIndex++;
+ }
- /* Determine decimal location. */
- if ( nExponentValue == 0 )
- {
- *dec = 1;
- }
- else
- {
- *dec = nExponentValue + 1;
- }
+ while (i < count)
+ {
+ lpStartOfReturnBuffer[i] = '0'; // append zeros as needed
+ i++;
+ }
- if ( value == 0.0 )
- {
- *dec = 0;
- }
- /* Copy the string from the temp buffer upto count characters,
- removing the sign, and decimal as required. */
- lpTempBuffer = TempBuffer;
- *lpReturnBuffer = '0';
- lpReturnBuffer++;
+ lpStartOfReturnBuffer[i] = '\0';
+
+ //
+ // Round if needed
+ //
- while ( LoopIndex < ECVT_MAX_COUNT_SIZE )
- {
- if ( isdigit(*lpTempBuffer) )
+ if (mantissaIndex >= exponentIndex || TempBuffer[mantissaIndex] < '5')
{
- *lpReturnBuffer = *lpTempBuffer;
- LoopIndex++;
- lpReturnBuffer++;
+ goto done;
}
- lpTempBuffer++;
- if ( LoopIndex == count + 1 )
+ i = count - 1;
+ while (lpStartOfReturnBuffer[i] == '9' && i > 0)
{
- break;
+ lpStartOfReturnBuffer[i] = '0';
+ i--;
}
- }
- *lpReturnBuffer = '\0';
-
- /* Round if needed. If count is less then 0
- then windows does not round for some reason.*/
- nTempBufferLength = strlen( lpStartOfReturnBuffer ) - 1;
-
- /* Add one for the preceeding zero. */
- lpReturnBuffer = ( lpStartOfReturnBuffer + 1 );
-
- if ( nTempBufferLength >= count && count >= 0 )
- {
- /* Determine whether I need to round up. */
- if ( *(lpReturnBuffer + count) >= '5' )
+ if (i == 0 && lpStartOfReturnBuffer[i] == '9')
{
- CHAR cNumberToBeRounded;
- if ( count != 0 )
- {
- cNumberToBeRounded = *(lpReturnBuffer + count - 1);
- }
- else
- {
- cNumberToBeRounded = *lpReturnBuffer;
- }
-
- if ( cNumberToBeRounded < '9' )
- {
- if ( count > 0 )
- {
- /* Add one to the character. */
- (*(lpReturnBuffer + count - 1))++;
- }
- else
- {
- if ( cNumberToBeRounded >= '5' )
- {
- (*dec)++;
- }
- }
- }
- else
- {
- LPSTR lpRounding = NULL;
-
- if ( count > 0 )
- {
- lpRounding = lpReturnBuffer + count - 1;
- }
- else
- {
- lpRounding = lpReturnBuffer + count;
- }
-
- while ( cNumberToBeRounded == '9' )
- {
- cNumberToBeRounded = *lpRounding;
-
- if ( cNumberToBeRounded == '9' )
- {
- *lpRounding = '0';
- lpRounding--;
- }
- }
-
- if ( lpRounding == lpStartOfReturnBuffer )
- {
- /* Overflow. number is a whole number now. */
- *lpRounding = '1';
- memset( ++lpRounding, '0', count);
-
- /* The decimal has moved. */
- (*dec)++;
- }
- else
- {
- *lpRounding = ++cNumberToBeRounded;
- }
- }
+ lpStartOfReturnBuffer[i] = '1';
+ (*dec)++;
}
else
{
- /* Get rid of the preceding 0 */
- lpStartOfReturnBuffer++;
- }
- }
-
- if ( *lpStartOfReturnBuffer == '0' )
- {
- lpStartOfReturnBuffer++;
- }
-
- if ( count >= 0 )
- {
- *(lpStartOfReturnBuffer + count) = '\0';
- }
- else
- {
- *lpStartOfReturnBuffer = '\0';
+ lpStartOfReturnBuffer[i]++;
+ }
}
done:
LOGEXIT( "_ecvt returning %p (%s)\n", lpStartOfReturnBuffer , lpStartOfReturnBuffer );
PERF_EXIT(_ecvt);
-
+
return lpStartOfReturnBuffer;
}
diff --git a/src/pal/src/exception/seh-unwind.cpp b/src/pal/src/exception/seh-unwind.cpp
index e3fa09f7c8..1f20ee0cad 100644
--- a/src/pal/src/exception/seh-unwind.cpp
+++ b/src/pal/src/exception/seh-unwind.cpp
@@ -155,6 +155,7 @@ static void UnwindContextToWinContext(unw_cursor_t *cursor, CONTEXT *winContext)
#elif defined(_X86_)
unw_get_reg(cursor, UNW_REG_IP, (unw_word_t *) &winContext->Eip);
unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->Esp);
+ unw_get_reg(cursor, UNW_REG_SP, (unw_word_t *) &winContext->ResumeEsp);
unw_get_reg(cursor, UNW_X86_EBP, (unw_word_t *) &winContext->Ebp);
unw_get_reg(cursor, UNW_X86_EBX, (unw_word_t *) &winContext->Ebx);
unw_get_reg(cursor, UNW_X86_ESI, (unw_word_t *) &winContext->Esi);
@@ -243,6 +244,7 @@ static void GetContextPointers(unw_cursor_t *cursor, unw_context_t *unwContext,
GetContextPointer(cursor, unwContext, UNW_AARCH64_X26, &contextPointers->X26);
GetContextPointer(cursor, unwContext, UNW_AARCH64_X27, &contextPointers->X27);
GetContextPointer(cursor, unwContext, UNW_AARCH64_X28, &contextPointers->X28);
+ GetContextPointer(cursor, unwContext, UNW_AARCH64_X29, &contextPointers->Fp);
#else
#error unsupported architecture
#endif
diff --git a/src/pal/src/exception/seh.cpp b/src/pal/src/exception/seh.cpp
index ad09e02884..2d1c18218a 100644
--- a/src/pal/src/exception/seh.cpp
+++ b/src/pal/src/exception/seh.cpp
@@ -27,7 +27,7 @@ Abstract:
#include "pal/init.h"
#include "pal/process.h"
#include "pal/malloc.hpp"
-#include "signal.hpp"
+#include "pal/signal.hpp"
#if HAVE_MACH_EXCEPTIONS
#include "machexception.h"
@@ -111,14 +111,12 @@ Return value :
BOOL
SEHInitialize (CPalThread *pthrCurrent, DWORD flags)
{
-#if !HAVE_MACH_EXCEPTIONS
if (!SEHInitializeSignals(flags))
{
ERROR("SEHInitializeSignals failed!\n");
SEHCleanup();
return FALSE;
}
-#endif
return TRUE;
}
@@ -142,9 +140,8 @@ SEHCleanup()
#if HAVE_MACH_EXCEPTIONS
SEHCleanupExceptionPort();
-#else
- SEHCleanupSignals();
#endif
+ SEHCleanupSignals();
}
/*++
@@ -226,7 +223,11 @@ Parameters:
PAL_SEHException* ex - the exception to throw.
--*/
extern "C"
+#ifdef _X86_
+void __fastcall ThrowExceptionHelper(PAL_SEHException* ex)
+#else // _X86_
void ThrowExceptionHelper(PAL_SEHException* ex)
+#endif // !_X86_
{
throw std::move(*ex);
}
diff --git a/src/pal/src/exception/signal.cpp b/src/pal/src/exception/signal.cpp
index 26e2a012c5..57ae62ea21 100644
--- a/src/pal/src/exception/signal.cpp
+++ b/src/pal/src/exception/signal.cpp
@@ -27,24 +27,28 @@ SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); // some headers have code with asserts, so do
#include "pal/threadinfo.hpp"
#include "pal/threadsusp.hpp"
#include "pal/seh.hpp"
+#include "pal/signal.hpp"
#include "pal/palinternal.h"
+
+#include <errno.h>
+#include <signal.h>
+
#if !HAVE_MACH_EXCEPTIONS
#include "pal/init.h"
#include "pal/process.h"
#include "pal/debug.h"
+#include "pal/virtual.h"
+#include "pal/utils.h"
-#include <signal.h>
-#include <errno.h>
#include <string.h>
#include <sys/ucontext.h>
#include <sys/utsname.h>
#include <unistd.h>
+#include <sys/mman.h>
#include "pal/context.h"
-using namespace CorUnix;
-
#ifdef SIGRTMIN
#define INJECT_ACTIVATION_SIGNAL SIGRTMIN
#endif
@@ -52,6 +56,9 @@ using namespace CorUnix;
#if !defined(INJECT_ACTIVATION_SIGNAL) && defined(FEATURE_HIJACK)
#error FEATURE_HIJACK requires INJECT_ACTIVATION_SIGNAL to be defined
#endif
+#endif // !HAVE_MACH_EXCEPTIONS
+
+using namespace CorUnix;
/* local type definitions *****************************************************/
@@ -63,8 +70,19 @@ typedef void *siginfo_t;
#endif /* !HAVE_SIGINFO_T */
typedef void (*SIGFUNC)(int, siginfo_t *, void *);
+#if !HAVE_MACH_EXCEPTIONS
+// Return context and status for the signal_handler_worker.
+struct SignalHandlerWorkerReturnPoint
+{
+ bool returnFromHandler;
+ CONTEXT context;
+};
+#endif // !HAVE_MACH_EXCEPTIONS
+
/* internal function declarations *********************************************/
+static void sigterm_handler(int code, siginfo_t *siginfo, void *context);
+#if !HAVE_MACH_EXCEPTIONS
static void sigill_handler(int code, siginfo_t *siginfo, void *context);
static void sigfpe_handler(int code, siginfo_t *siginfo, void *context);
static void sigsegv_handler(int code, siginfo_t *siginfo, void *context);
@@ -72,19 +90,23 @@ static void sigtrap_handler(int code, siginfo_t *siginfo, void *context);
static void sigbus_handler(int code, siginfo_t *siginfo, void *context);
static void sigint_handler(int code, siginfo_t *siginfo, void *context);
static void sigquit_handler(int code, siginfo_t *siginfo, void *context);
-static void sigterm_handler(int code, siginfo_t *siginfo, void *context);
static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext, int numParams, ...);
#ifdef INJECT_ACTIVATION_SIGNAL
static void inject_activation_handler(int code, siginfo_t *siginfo, void *context);
#endif
+#endif // !HAVE_MACH_EXCEPTIONS
-static void handle_signal(int signal_id, SIGFUNC sigfunc, struct sigaction *previousAction);
+static void handle_signal(int signal_id, SIGFUNC sigfunc, struct sigaction *previousAction, int additionalFlags = 0);
static void restore_signal(int signal_id, struct sigaction *previousAction);
/* internal data declarations *********************************************/
+static bool registered_sigterm_handler = false;
+
+struct sigaction g_previous_sigterm;
+#if !HAVE_MACH_EXCEPTIONS
struct sigaction g_previous_sigill;
struct sigaction g_previous_sigtrap;
struct sigaction g_previous_sigfpe;
@@ -92,9 +114,6 @@ struct sigaction g_previous_sigbus;
struct sigaction g_previous_sigsegv;
struct sigaction g_previous_sigint;
struct sigaction g_previous_sigquit;
-struct sigaction g_previous_sigterm;
-
-static bool registered_sigterm_handler = false;
#ifdef INJECT_ACTIVATION_SIGNAL
struct sigaction g_previous_activation;
@@ -103,9 +122,94 @@ struct sigaction g_previous_activation;
// Offset of the local variable containing native context in the common_signal_handler function.
// This offset is relative to the frame pointer.
int g_common_signal_handler_context_locvar_offset = 0;
+#endif // !HAVE_MACH_EXCEPTIONS
/* public function definitions ************************************************/
+#if !HAVE_MACH_EXCEPTIONS
+/*++
+Function :
+ EnsureSignalAlternateStack
+
+ Ensure that alternate stack for signal handling is allocated for the current thread
+
+Parameters :
+ None
+
+Return :
+ TRUE in case of a success, FALSE otherwise
+--*/
+BOOL EnsureSignalAlternateStack()
+{
+ stack_t oss;
+
+ // Query the current alternate signal stack
+ int st = sigaltstack(NULL, &oss);
+
+ if ((st == 0) && (oss.ss_flags == SS_DISABLE))
+ {
+ // There is no alternate stack for SIGSEGV handling installed yet so allocate one
+
+ // We include the size of the SignalHandlerWorkerReturnPoint in the alternate stack size since the
+ // context contained in it is large and the SIGSTKSZ was not sufficient on ARM64 during testing.
+ int altStackSize = SIGSTKSZ + ALIGN_UP(sizeof(SignalHandlerWorkerReturnPoint), 16) + VIRTUAL_PAGE_SIZE;
+ void* altStack;
+ int st = posix_memalign(&altStack, VIRTUAL_PAGE_SIZE, altStackSize);
+ if (st == 0)
+ {
+ // create a guard page for the alternate stack
+ st = mprotect(altStack, VIRTUAL_PAGE_SIZE, PROT_NONE);
+ if (st == 0)
+ {
+ stack_t ss;
+ ss.ss_sp = (char*)altStack;
+ ss.ss_size = altStackSize;
+ ss.ss_flags = 0;
+ st = sigaltstack(&ss, NULL);
+ if (st != 0)
+ {
+ // Installation of the alternate stack failed, so revert the guard page protection
+ int st2 = mprotect(altStack, VIRTUAL_PAGE_SIZE, PROT_READ | PROT_WRITE);
+ _ASSERTE(st2 == 0);
+ }
+ }
+
+ if (st != 0)
+ {
+ free(altStack);
+ }
+ }
+ }
+
+ return (st == 0);
+}
+
+/*++
+Function :
+ FreeSignalAlternateStack
+
+ Free alternate stack for signal handling
+
+Parameters :
+ None
+
+Return :
+ None
+--*/
+void FreeSignalAlternateStack()
+{
+ stack_t ss, oss;
+ ss.ss_flags = SS_DISABLE;
+ int st = sigaltstack(&ss, &oss);
+ if ((st == 0) && (oss.ss_flags != SS_DISABLE))
+ {
+ int st = mprotect(oss.ss_sp, VIRTUAL_PAGE_SIZE, PROT_READ | PROT_WRITE);
+ _ASSERTE(st == 0);
+ free(oss.ss_sp);
+ }
+}
+#endif // !HAVE_MACH_EXCEPTIONS
+
/*++
Function :
SEHInitializeSignals
@@ -122,6 +226,7 @@ BOOL SEHInitializeSignals(DWORD flags)
{
TRACE("Initializing signal handlers\n");
+#if !HAVE_MACH_EXCEPTIONS
/* we call handle_signal for every possible signal, even
if we don't provide a signal handler.
@@ -139,16 +244,24 @@ BOOL SEHInitializeSignals(DWORD flags)
handle_signal(SIGTRAP, sigtrap_handler, &g_previous_sigtrap);
handle_signal(SIGFPE, sigfpe_handler, &g_previous_sigfpe);
handle_signal(SIGBUS, sigbus_handler, &g_previous_sigbus);
- handle_signal(SIGSEGV, sigsegv_handler, &g_previous_sigsegv);
+ // SIGSEGV handler runs on a separate stack so that we can handle stack overflow
+ handle_signal(SIGSEGV, sigsegv_handler, &g_previous_sigsegv, SA_ONSTACK);
handle_signal(SIGINT, sigint_handler, &g_previous_sigint);
handle_signal(SIGQUIT, sigquit_handler, &g_previous_sigquit);
+ if (!EnsureSignalAlternateStack())
+ {
+ return FALSE;
+ }
+#endif // !HAVE_MACH_EXCEPTIONS
+
if (flags & PAL_INITIALIZE_REGISTER_SIGTERM_HANDLER)
{
handle_signal(SIGTERM, sigterm_handler, &g_previous_sigterm);
registered_sigterm_handler = true;
}
+#if !HAVE_MACH_EXCEPTIONS
#ifdef INJECT_ACTIVATION_SIGNAL
handle_signal(INJECT_ACTIVATION_SIGNAL, inject_activation_handler, &g_previous_activation);
#endif
@@ -162,6 +275,7 @@ BOOL SEHInitializeSignals(DWORD flags)
issued a SIGPIPE will, instead, report an error and set errno to EPIPE.
*/
signal(SIGPIPE, SIG_IGN);
+#endif // !HAVE_MACH_EXCEPTIONS
return TRUE;
}
@@ -186,6 +300,7 @@ void SEHCleanupSignals()
{
TRACE("Restoring default signal handlers\n");
+#if !HAVE_MACH_EXCEPTIONS
restore_signal(SIGILL, &g_previous_sigill);
restore_signal(SIGTRAP, &g_previous_sigtrap);
restore_signal(SIGFPE, &g_previous_sigfpe);
@@ -193,19 +308,23 @@ void SEHCleanupSignals()
restore_signal(SIGSEGV, &g_previous_sigsegv);
restore_signal(SIGINT, &g_previous_sigint);
restore_signal(SIGQUIT, &g_previous_sigquit);
+#endif // !HAVE_MACH_EXCEPTIONS
if (registered_sigterm_handler)
{
restore_signal(SIGTERM, &g_previous_sigterm);
}
+#if !HAVE_MACH_EXCEPTIONS
#ifdef INJECT_ACTIVATION_SIGNAL
restore_signal(INJECT_ACTIVATION_SIGNAL, &g_previous_activation);
#endif
+#endif // !HAVE_MACH_EXCEPTIONS
}
/* internal function definitions **********************************************/
+#if !HAVE_MACH_EXCEPTIONS
/*++
Function :
sigill_handler
@@ -276,6 +395,28 @@ static void sigfpe_handler(int code, siginfo_t *siginfo, void *context)
/*++
Function :
+ signal_handler_worker
+
+ Handles signal on the original stack where the signal occured.
+ Invoked via setcontext.
+
+Parameters :
+ POSIX signal handler parameter list ("man sigaction" for details)
+ returnPoint - context to which the function returns if the common_signal_handler returns
+
+ (no return value)
+--*/
+extern "C" void signal_handler_worker(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint)
+{
+ // TODO: First variable parameter says whether a read (0) or write (non-0) caused the
+ // fault. We must disassemble the instruction at record.ExceptionAddress
+ // to correctly fill in this value.
+ returnPoint->returnFromHandler = common_signal_handler(code, siginfo, context, 2, (size_t)0, (size_t)siginfo->si_addr);
+ RtlRestoreContext(&returnPoint->context, NULL);
+}
+
+/*++
+Function :
sigsegv_handler
handle SIGSEGV signal (EXCEPTION_ACCESS_VIOLATION, others)
@@ -289,10 +430,38 @@ static void sigsegv_handler(int code, siginfo_t *siginfo, void *context)
{
if (PALIsInitialized())
{
- // TODO: First variable parameter says whether a read (0) or write (non-0) caused the
- // fault. We must disassemble the instruction at record.ExceptionAddress
- // to correctly fill in this value.
- if (common_signal_handler(code, siginfo, context, 2, (size_t)0, (size_t)siginfo->si_addr))
+ // First check if we have a stack overflow
+ size_t sp = (size_t)GetNativeContextSP((native_context_t *)context);
+ size_t failureAddress = (size_t)siginfo->si_addr;
+
+ // If the failure address is at most one page above or below the stack pointer,
+ // we have a stack overflow.
+ if ((failureAddress - (sp - VIRTUAL_PAGE_SIZE)) < 2 * VIRTUAL_PAGE_SIZE)
+ {
+ (void)write(STDERR_FILENO, StackOverflowMessage, sizeof(StackOverflowMessage) - 1);
+ PROCAbort();
+ }
+
+ // Now that we know the SIGSEGV didn't happen due to a stack overflow, execute the common
+ // hardware signal handler on the original stack.
+
+ // Establish a return point in case the common_signal_handler returns
+
+ volatile bool contextInitialization = true;
+
+ SignalHandlerWorkerReturnPoint returnPoint;
+ RtlCaptureContext(&returnPoint.context);
+
+ // When the signal handler worker completes, it uses setcontext to return to this point
+
+ if (contextInitialization)
+ {
+ contextInitialization = false;
+ ExecuteHandlerOnOriginalStack(code, siginfo, context, &returnPoint);
+ _ASSERTE(FALSE); // The ExecuteHandlerOnOriginalStack should never return
+ }
+
+ if (returnPoint.returnFromHandler)
{
return;
}
@@ -422,6 +591,7 @@ static void sigquit_handler(int code, siginfo_t *siginfo, void *context)
restore_signal(code, &g_previous_sigquit);
kill(gPID, code);
}
+#endif // !HAVE_MACH_EXCEPTIONS
/*++
Function :
@@ -452,6 +622,7 @@ static void sigterm_handler(int code, siginfo_t *siginfo, void *context)
}
}
+#if !HAVE_MACH_EXCEPTIONS
#ifdef INJECT_ACTIVATION_SIGNAL
/*++
Function :
@@ -650,6 +821,7 @@ static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext
return false;
}
+#endif // !HAVE_MACH_EXCEPTIONS
/*++
Function :
@@ -666,11 +838,11 @@ Parameters :
note : if sigfunc is NULL, the default signal handler is restored
--*/
-void handle_signal(int signal_id, SIGFUNC sigfunc, struct sigaction *previousAction)
+void handle_signal(int signal_id, SIGFUNC sigfunc, struct sigaction *previousAction, int additionalFlags)
{
struct sigaction newAction;
- newAction.sa_flags = SA_RESTART;
+ newAction.sa_flags = SA_RESTART | additionalFlags;
#if HAVE_SIGINFO_T
newAction.sa_handler = NULL;
newAction.sa_sigaction = sigfunc;
@@ -707,5 +879,3 @@ void restore_signal(int signal_id, struct sigaction *previousAction)
errno, strerror(errno));
}
}
-
-#endif // !HAVE_MACH_EXCEPTIONS
diff --git a/src/pal/src/exception/signal.hpp b/src/pal/src/exception/signal.hpp
deleted file mode 100644
index cd019e676b..0000000000
--- a/src/pal/src/exception/signal.hpp
+++ /dev/null
@@ -1,52 +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.
-
-/*++
-
-
-
-Module Name:
-
- exception/signal.hpp
-
-Abstract:
- Private signal handling utilities for SEH
-
-
-
---*/
-
-#ifndef _PAL_SIGNAL_HPP_
-#define _PAL_SIGNAL_HPP_
-
-#if !HAVE_MACH_EXCEPTIONS
-
-/*++
-Function :
- SEHInitializeSignals
-
- Set-up signal handlers to catch signals and translate them to exceptions
-
-Parameters :
- flags: PAL initialization flags
-
-Return :
- TRUE in case of a success, FALSE otherwise
---*/
-BOOL SEHInitializeSignals(DWORD flags);
-
-/*++
-Function :
- SEHCleanupSignals
-
- Restore default signal handlers
-
- (no parameters, no return value)
---*/
-void SEHCleanupSignals();
-
-#endif // !HAVE_MACH_EXCEPTIONS
-
-#endif /* _PAL_SIGNAL_HPP_ */
-
diff --git a/src/pal/src/file/filetime.cpp b/src/pal/src/file/filetime.cpp
index a8666b0dff..ca36e04d9d 100644
--- a/src/pal/src/file/filetime.cpp
+++ b/src/pal/src/file/filetime.cpp
@@ -81,8 +81,8 @@ SET_DEFAULT_DEBUG_CHANNEL(FILE);
Both epochs are Gregorian. 1970 - 1601 = 369. Assuming a leap
year every four years, 369 / 4 = 92. However, 1700, 1800, and 1900
were NOT leap years, so 89 leap years, 280 non-leap years.
- 89 * 366 + 280 * 365 = 134744 days between epochs. Of course
- 60 * 60 * 24 = 86400 seconds per day, so 134744 * 86400 =
+ 89 * 366 + 280 * 365 = 134774 days between epochs. Of course
+ 60 * 60 * 24 = 86400 seconds per day, so 134774 * 86400 =
11644473600 = SECS_BETWEEN_1601_AND_1970_EPOCHS.
To 2001:
@@ -504,23 +504,29 @@ PALAPI
GetSystemTimeAsFileTime(
OUT LPFILETIME lpSystemTimeAsFileTime)
{
- struct timeval Time;
-
PERF_ENTRY(GetSystemTimeAsFileTime);
ENTRY("GetSystemTimeAsFileTime(lpSystemTimeAsFileTime=%p)\n",
lpSystemTimeAsFileTime);
- if ( gettimeofday( &Time, NULL ) != 0 )
+#if HAVE_WORKING_CLOCK_GETTIME
+ struct timespec Time;
+ if (clock_gettime(CLOCK_REALTIME, &Time) == 0)
{
- ASSERT("gettimeofday() failed");
- /* no way to indicate failure, so set time to zero */
- *lpSystemTimeAsFileTime = FILEUnixTimeToFileTime( 0, 0 );
+ *lpSystemTimeAsFileTime = FILEUnixTimeToFileTime( Time.tv_sec, Time.tv_nsec );
}
- else
+#else
+ struct timeval Time;
+ if (gettimeofday(&Time, NULL) == 0)
{
/* use (tv_usec * 1000) because 2nd arg is in nanoseconds */
- *lpSystemTimeAsFileTime = FILEUnixTimeToFileTime( Time.tv_sec,
- Time.tv_usec * 1000 );
+ *lpSystemTimeAsFileTime = FILEUnixTimeToFileTime( Time.tv_sec, Time.tv_usec * 1000);
+ }
+#endif
+ else
+ {
+ /* no way to indicate failure, so set time to zero */
+ ASSERT("clock_gettime or gettimeofday failed");
+ *lpSystemTimeAsFileTime = FILEUnixTimeToFileTime( 0, 0 );
}
LOGEXIT("GetSystemTimeAsFileTime returns.\n");
diff --git a/src/pal/src/include/pal/context.h b/src/pal/src/include/pal/context.h
index 6857c130ee..db6d69579a 100644
--- a/src/pal/src/include/pal/context.h
+++ b/src/pal/src/include/pal/context.h
@@ -248,8 +248,7 @@ inline void *FPREG_Xstate_Ymmh(const ucontext_t *uc)
#define MCREG_Sp(mc) ((mc).sp)
#define MCREG_Pc(mc) ((mc).pc)
-#define MCREG_PState(mc) ((mc).pstate)
-#define MCREG_Cpsr(mc) ((mc).cpsr)
+#define MCREG_Cpsr(mc) ((mc).pstate)
#else
// For FreeBSD, as found in x86/ucontext.h
#define MCREG_Rbp(mc) ((mc).mc_rbp)
@@ -640,6 +639,21 @@ LPVOID GetNativeContextPC(const native_context_t *context);
/*++
Function :
+ GetNativeContextSP
+
+ Returns the stack pointer from the native context.
+
+Parameters :
+ const native_context_t *native : native context
+
+Return value :
+ The stack pointer from the native context.
+
+--*/
+LPVOID GetNativeContextSP(const native_context_t *context);
+
+/*++
+Function :
CONTEXTGetExceptionCodeForSignal
Translates signal and context information to a Win32 exception code.
diff --git a/src/pal/src/include/pal/module.h b/src/pal/src/include/pal/module.h
index 95fa605c21..72df268d3c 100644
--- a/src/pal/src/include/pal/module.h
+++ b/src/pal/src/include/pal/module.h
@@ -25,7 +25,7 @@ extern "C"
{
#endif // __cplusplus
-typedef BOOL (__stdcall *PDLLMAIN)(HINSTANCE, DWORD, LPVOID); /* entry point of module */
+typedef BOOL (PALAPI *PDLLMAIN)(HINSTANCE, DWORD, LPVOID); /* entry point of module */
typedef HINSTANCE (PALAPI *PREGISTER_MODULE)(LPCSTR); /* used to create the HINSTANCE for above DLLMain entry point */
typedef VOID (PALAPI *PUNREGISTER_MODULE)(HINSTANCE); /* used to cleanup the HINSTANCE for above DLLMain entry point */
diff --git a/src/pal/src/include/pal/signal.hpp b/src/pal/src/include/pal/signal.hpp
new file mode 100644
index 0000000000..dfe21f10fb
--- /dev/null
+++ b/src/pal/src/include/pal/signal.hpp
@@ -0,0 +1,140 @@
+// 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.
+
+/*++
+
+
+
+Module Name:
+
+ include/pal/signal.hpp
+
+Abstract:
+ Private signal handling utilities for SEH
+
+
+
+--*/
+
+#ifndef _PAL_SIGNAL_HPP_
+#define _PAL_SIGNAL_HPP_
+
+#if !HAVE_MACH_EXCEPTIONS
+
+struct SignalHandlerWorkerReturnPoint;
+
+/*++
+Function :
+ CallSignalHandlerWrapperX
+
+ These functions are never called, only a fake stack frame will be setup to have a return
+ address set to SignalHandlerWorkerReturnX during SIGSEGV handling.
+ It enables the unwinder to unwind stack from the handling code to the actual failure site.
+
+ There are four variants of this function based on what stack alignment needs to be done
+ to ensure properly aligned stack pointer at the call site of the signal_handler_worker.
+
+Parameters :
+ none
+
+ (no return value)
+--*/
+extern "C" void CallSignalHandlerWrapper0();
+extern "C" void CallSignalHandlerWrapper4();
+extern "C" void CallSignalHandlerWrapper8();
+extern "C" void CallSignalHandlerWrapper12();
+
+// Offset of the return address from the signal_handler_worker in the CallSignalHandlerWrapperX
+// relative to the start of the function.
+// There are four offsets matching the stack alignments as described in the function header above.
+extern "C" int SignalHandlerWorkerReturnOffset0;
+extern "C" int SignalHandlerWorkerReturnOffset4;
+extern "C" int SignalHandlerWorkerReturnOffset8;
+extern "C" int SignalHandlerWorkerReturnOffset12;
+
+/*++
+Function :
+ signal_handler_worker
+
+ Handles signal on the original stack where the signal occured.
+ Invoked via setcontext.
+
+Parameters :
+ POSIX signal handler parameter list ("man sigaction" for details)
+ returnPoint - context to which the function returns if the common_signal_handler returns
+
+ (no return value)
+--*/
+extern "C" void signal_handler_worker(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint);
+
+/*++
+Function :
+ ExecuteHandlerOnOriginalStack
+
+ Executes signal_handler_worker on the original stack where the signal occured.
+ It installs fake stack frame to enable stack unwinding to the signal source location.
+
+Parameters :
+ POSIX signal handler parameter list ("man sigaction" for details)
+ returnPoint - context to which the function returns if the common_signal_handler returns
+
+ (no return value)
+--*/
+void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context, SignalHandlerWorkerReturnPoint* returnPoint);
+
+/*++
+Function :
+ EnsureSignalAlternateStack
+
+ Ensure that alternate stack for signal handling is allocated for the current thread
+
+Parameters :
+ None
+
+Return :
+ TRUE in case of a success, FALSE otherwise
+--*/
+BOOL EnsureSignalAlternateStack();
+
+/*++
+Function :
+ FreeSignalAlternateStack
+
+ Free alternate stack for signal handling
+
+Parameters :
+ None
+
+Return :
+ None
+--*/
+void FreeSignalAlternateStack();
+
+#endif // !HAVE_MACH_EXCEPTIONS
+
+/*++
+Function :
+ SEHInitializeSignals
+
+ Set-up signal handlers to catch signals and translate them to exceptions
+
+Parameters :
+ flags: PAL initialization flags
+
+Return :
+ TRUE in case of a success, FALSE otherwise
+--*/
+BOOL SEHInitializeSignals(DWORD flags);
+
+/*++
+Function :
+ SEHCleanupSignals
+
+ Restore default signal handlers
+
+ (no parameters, no return value)
+--*/
+void SEHCleanupSignals();
+
+#endif /* _PAL_SIGNAL_HPP_ */
diff --git a/src/pal/src/init/pal.cpp b/src/pal/src/init/pal.cpp
index e6db7dca2e..fa94922325 100644
--- a/src/pal/src/init/pal.cpp
+++ b/src/pal/src/init/pal.cpp
@@ -105,7 +105,7 @@ static PCRITICAL_SECTION init_critsec = NULL;
static int Initialize(int argc, const char *const argv[], DWORD flags);
static BOOL INIT_IncreaseDescriptorLimit(void);
static LPWSTR INIT_FormatCommandLine (int argc, const char * const *argv);
-static LPWSTR INIT_FindEXEPath(LPCSTR exe_name);
+static LPWSTR INIT_ConvertEXEPath(LPCSTR exe_name);
#ifdef _DEBUG
extern void PROCDumpThreadList(void);
@@ -406,7 +406,7 @@ Initialize(
}
/* find out the application's full path */
- exe_path = INIT_FindEXEPath(argv[0]);
+ exe_path = INIT_ConvertEXEPath(argv[0]);
if (NULL == exe_path)
{
ERROR("Unable to find exe path\n");
@@ -1130,14 +1130,13 @@ static LPWSTR INIT_FormatCommandLine (int argc, const char * const *argv)
/*++
Function:
- INIT_FindEXEPath
+ INIT_ConvertEXEPath
Abstract:
- Determine the full, canonical path of the current executable by searching
- $PATH.
+ Check whether the executable path is valid, and convert its type (LPCSTR -> LPWSTR)
Parameters:
- LPCSTR exe_name : file to search for
+ LPCSTR exe_name : full path of the current executable
Return:
pointer to buffer containing the full path. This buffer must be released
@@ -1145,299 +1144,33 @@ Return:
Notes :
this function assumes that "exe_name" is in Unix style (no \)
-
-Notes 2:
- This doesn't handle the case of directories with the desired name
- (and directories are usually executable...)
--*/
-static LPWSTR INIT_FindEXEPath(LPCSTR exe_name)
+static LPWSTR INIT_ConvertEXEPath(LPCSTR exe_path)
{
-#ifndef __APPLE__
PathCharString real_path;
- LPSTR env_path;
- LPSTR path_ptr;
- LPSTR cur_dir;
- INT exe_name_length;
- BOOL need_slash;
LPWSTR return_value;
INT return_size;
struct stat theStats;
- /* if a path is specified, only search there */
- if (strchr(exe_name, '/'))
- {
- if ( -1 == stat( exe_name, &theStats ) )
- {
- ERROR( "The file does not exist\n" );
- return NULL;
- }
-
- if ( UTIL_IsExecuteBitsSet( &theStats ) )
- {
- if (!CorUnix::RealPathHelper(exe_name, real_path))
- {
- ERROR("realpath() failed!\n");
- return NULL;
- }
-
- return_size=MultiByteToWideChar(CP_ACP,0,real_path,-1,NULL,0);
- if ( 0 == return_size )
- {
- ASSERT("MultiByteToWideChar failure\n");
- return NULL;
- }
-
- return_value = reinterpret_cast<LPWSTR>(InternalMalloc((return_size*sizeof(WCHAR))));
- if ( NULL == return_value )
- {
- ERROR("Not enough memory to create full path\n");
- return NULL;
- }
- else
- {
- if (!MultiByteToWideChar(CP_ACP, 0, real_path, -1,
- return_value, return_size))
- {
- ASSERT("MultiByteToWideChar failure\n");
- free(return_value);
- return_value = NULL;
- }
- else
- {
- TRACE("full path to executable is %s\n", real_path.GetString());
- }
- }
- return return_value;
- }
- }
-
- /* no path was specified : search $PATH */
-
- env_path = EnvironGetenv("PATH");
- if (!env_path || *env_path=='\0')
- {
- WARN("$PATH isn't set.\n");
- if (env_path != NULL)
- {
- free(env_path);
- }
- goto last_resort;
- }
-
- exe_name_length=strlen(exe_name);
-
- cur_dir=env_path;
-
- while (cur_dir)
+ if (!strchr(exe_path, '/'))
{
- LPSTR full_path;
- struct stat theStats;
-
- /* skip all leading ':' */
- while (*cur_dir==':')
- {
- cur_dir++;
- }
- if (*cur_dir=='\0')
- {
- break;
- }
-
- /* cut string at next ':' */
- path_ptr = strchr(cur_dir, ':');
- if (path_ptr)
- {
- /* check if we need to add a '/' between the path and filename */
- need_slash=(*(path_ptr-1))!='/';
-
- /* NULL_terminate path element */
- *path_ptr++='\0';
- }
- else
- {
- /* check if we need to add a '/' between the path and filename */
- need_slash=(cur_dir[strlen(cur_dir)-1])!='/';
- }
-
- TRACE("looking for %s in %s\n", exe_name, cur_dir);
-
- /* build tentative full file name */
- int iLength = (strlen(cur_dir)+exe_name_length+2);
- full_path = reinterpret_cast<LPSTR>(InternalMalloc(iLength));
- if (!full_path)
- {
- ERROR("Not enough memory!\n");
- break;
- }
-
- if (strcpy_s(full_path, iLength, cur_dir) != SAFECRT_SUCCESS)
- {
- ERROR("strcpy_s failed!\n");
- free(full_path);
- free(env_path);
- return NULL;
- }
-
- if (need_slash)
- {
- if (strcat_s(full_path, iLength, "/") != SAFECRT_SUCCESS)
- {
- ERROR("strcat_s failed!\n");
- free(full_path);
- free(env_path);
- return NULL;
- }
- }
-
- if (strcat_s(full_path, iLength, exe_name) != SAFECRT_SUCCESS)
- {
- ERROR("strcat_s failed!\n");
- free(full_path);
- free(env_path);
- return NULL;
- }
-
- /* see if file exists AND is executable */
- if ( -1 != stat( full_path, &theStats ) )
- {
- if( UTIL_IsExecuteBitsSet( &theStats ) )
- {
- /* generate canonical path */
- if (!CorUnix::RealPathHelper(full_path, real_path))
- {
- ERROR("realpath() failed!\n");
- free(full_path);
- free(env_path);
- return NULL;
- }
- free(full_path);
-
- return_size = MultiByteToWideChar(CP_ACP,0,real_path,-1,NULL,0);
- if ( 0 == return_size )
- {
- ASSERT("MultiByteToWideChar failure\n");
- free(env_path);
- return NULL;
- }
-
- return_value = reinterpret_cast<LPWSTR>(InternalMalloc((return_size*sizeof(WCHAR))));
- if ( NULL == return_value )
- {
- ERROR("Not enough memory to create full path\n");
- free(env_path);
- return NULL;
- }
-
- if (!MultiByteToWideChar(CP_ACP, 0, real_path, -1, return_value,
- return_size))
- {
- ASSERT("MultiByteToWideChar failure\n");
- free(return_value);
- return_value = NULL;
- }
- else
- {
- TRACE("found %s in %s; real path is %s\n", exe_name,
- cur_dir,real_path.GetString());
- }
-
- free(env_path);
- return return_value;
- }
- }
-
- /* file doesn't exist : keep searching */
- free(full_path);
-
- /* path_ptr is NULL if there's no ':' after this directory */
- cur_dir=path_ptr;
- }
-
- free(env_path);
- TRACE("No %s found in $PATH (%s)\n", exe_name, EnvironGetenv("PATH", FALSE));
-
-last_resort:
- /* last resort : see if the executable is in the current directory. This is
- possible if it comes from a exec*() call. */
- if (0 == stat(exe_name,&theStats))
- {
- if ( UTIL_IsExecuteBitsSet( &theStats ) )
- {
- if (!CorUnix::RealPathHelper(exe_name, real_path))
- {
- ERROR("realpath() failed!\n");
- return NULL;
- }
-
- return_size = MultiByteToWideChar(CP_ACP,0,real_path,-1,NULL,0);
- if (0 == return_size)
- {
- ASSERT("MultiByteToWideChar failure\n");
- return NULL;
- }
-
- return_value = reinterpret_cast<LPWSTR>(InternalMalloc((return_size*sizeof(WCHAR))));
- if (NULL == return_value)
- {
- ERROR("Not enough memory to create full path\n");
- return NULL;
- }
- else
- {
- if (!MultiByteToWideChar(CP_ACP, 0, real_path, -1,
- return_value, return_size))
- {
- ASSERT("MultiByteToWideChar failure\n");
- free(return_value);
- return_value = NULL;
- }
- else
- {
- TRACE("full path to executable is %s\n", real_path.GetString());
- }
- }
-
- return return_value;
- }
- else
- {
- ERROR("found %s in current directory, but it isn't executable!\n",
- exe_name);
- }
- }
- else
- {
- TRACE("last resort failed : executable %s is not in the current "
- "directory\n",exe_name);
+ ERROR( "The exe path is not fully specified\n" );
+ return NULL;
}
- ERROR("executable %s not found anywhere!\n", exe_name);
- return NULL;
-#else // !__APPLE__
- // On the Mac we can just directly ask the OS for the executable path.
-
- LPWSTR return_value;
- INT return_size;
-
- PathCharString exec_pathPS;
- LPSTR exec_path = exec_pathPS.OpenStringBuffer(MAX_PATH);
- uint32_t bufsize = exec_pathPS.GetCount();
-
- if (-1 == _NSGetExecutablePath(exec_path, &bufsize))
+ if (-1 == stat(exe_path, &theStats))
{
- exec_pathPS.CloseBuffer(exec_pathPS.GetCount());
- exec_path = exec_pathPS.OpenStringBuffer(bufsize);
+ ERROR( "The file does not exist\n" );
+ return NULL;
}
- if (_NSGetExecutablePath(exec_path, &bufsize))
+ if (!CorUnix::RealPathHelper(exe_path, real_path))
{
- ASSERT("_NSGetExecutablePath failure\n");
+ ERROR("realpath() failed!\n");
return NULL;
}
- exec_pathPS.CloseBuffer(bufsize);
-
- return_size = MultiByteToWideChar(CP_ACP,0,exec_path,-1,NULL,0);
+ return_size = MultiByteToWideChar(CP_ACP, 0, real_path, -1, NULL, 0);
if (0 == return_size)
{
ASSERT("MultiByteToWideChar failure\n");
@@ -1452,7 +1185,7 @@ last_resort:
}
else
{
- if (!MultiByteToWideChar(CP_ACP, 0, exec_path, -1,
+ if (!MultiByteToWideChar(CP_ACP, 0, real_path, -1,
return_value, return_size))
{
ASSERT("MultiByteToWideChar failure\n");
@@ -1461,10 +1194,9 @@ last_resort:
}
else
{
- TRACE("full path to executable is %s\n", exec_path);
+ TRACE("full path to executable is %s\n", real_path.GetString());
}
}
return return_value;
-#endif // !__APPLE__
}
diff --git a/src/pal/src/init/sxs.cpp b/src/pal/src/init/sxs.cpp
index 225f91684b..3f323c6a6e 100644
--- a/src/pal/src/init/sxs.cpp
+++ b/src/pal/src/init/sxs.cpp
@@ -16,6 +16,7 @@
#include "pal/module.h"
#include "pal/process.h"
#include "pal/seh.hpp"
+#include "pal/signal.hpp"
using namespace CorUnix;
@@ -106,8 +107,20 @@ PAL_ERROR
AllocatePalThread(CPalThread **ppThread)
{
CPalThread *pThread = NULL;
+ PAL_ERROR palError;
- PAL_ERROR palError = CreateThreadData(&pThread);
+#if !HAVE_MACH_EXCEPTIONS
+ // Ensure alternate stack for SIGSEGV handling. Our SIGSEGV handler is set to
+ // run on an alternate stack and the stack needs to be allocated per thread.
+ if (!EnsureSignalAlternateStack())
+ {
+ ERROR("Cannot allocate alternate stack for SIGSEGV handler!\n");
+ palError = ERROR_NOT_ENOUGH_MEMORY;
+ goto exit;
+ }
+#endif // !HAVE_MACH_EXCEPTIONS
+
+ palError = CreateThreadData(&pThread);
if (NO_ERROR != palError)
{
goto exit;
diff --git a/src/pal/src/loader/module.cpp b/src/pal/src/loader/module.cpp
index 63a65ffb61..bbe8b9ddcc 100644
--- a/src/pal/src/loader/module.cpp
+++ b/src/pal/src/loader/module.cpp
@@ -280,6 +280,16 @@ GetProcAddress(
module = (MODSTRUCT *) hModule;
+ /* try to assert on attempt to locate symbol by ordinal */
+ /* this can't be an exact test for HIWORD((DWORD)lpProcName) == 0
+ because of the address range reserved for ordinals contain can
+ be a valid string address on non-Windows systems
+ */
+ if ((DWORD_PTR)lpProcName < VIRTUAL_PAGE_SIZE)
+ {
+ ASSERT("Attempt to locate symbol by ordinal?!\n");
+ }
+
/* parameter validation */
if ((lpProcName == nullptr) || (*lpProcName == '\0'))
@@ -295,16 +305,6 @@ GetProcAddress(
SetLastError(ERROR_INVALID_HANDLE);
goto done;
}
-
- /* try to assert on attempt to locate symbol by ordinal */
- /* this can't be an exact test for HIWORD((DWORD)lpProcName) == 0
- because of the address range reserved for ordinals contain can
- be a valid string address on non-Windows systems
- */
- if ((DWORD_PTR)lpProcName < VIRTUAL_PAGE_SIZE)
- {
- ASSERT("Attempt to locate symbol by ordinal?!\n");
- }
// Get the symbol's address.
diff --git a/src/pal/src/locale/unicode.cpp b/src/pal/src/locale/unicode.cpp
index 3c119744b0..69214735d1 100644
--- a/src/pal/src/locale/unicode.cpp
+++ b/src/pal/src/locale/unicode.cpp
@@ -42,7 +42,7 @@ Revision History:
#endif // __APPLE__
#include <errno.h>
#if HAVE_COREFOUNDATION
-#include <corefoundation/corefoundation.h>
+#include <CoreFoundation/CoreFoundation.h>
#endif // HAVE_COREFOUNDATION
#include <debugmacrosext.h>
diff --git a/src/pal/src/misc/cgroup.cpp b/src/pal/src/misc/cgroup.cpp
new file mode 100644
index 0000000000..40178032e3
--- /dev/null
+++ b/src/pal/src/misc/cgroup.cpp
@@ -0,0 +1,335 @@
+// 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.
+
+/*++
+
+Module Name:
+
+ cgroup.cpp
+
+Abstract:
+ Read memory limits for the current process
+--*/
+
+#include "pal/dbgmsg.h"
+SET_DEFAULT_DEBUG_CHANNEL(MISC);
+#include "pal/palinternal.h"
+#include <sys/resource.h>
+#include "pal/virtual.h"
+
+#define PROC_MOUNTINFO_FILENAME "/proc/self/mountinfo"
+#define PROC_CGROUP_FILENAME "/proc/self/cgroup"
+#define PROC_STATM_FILENAME "/proc/self/statm"
+#define MEM_LIMIT_FILENAME "/memory.limit_in_bytes"
+
+class CGroup
+{
+ char *m_memory_cgroup_path;
+public:
+ CGroup()
+ {
+ m_memory_cgroup_path = nullptr;
+ char* memoryHierarchyMount = nullptr;
+ char *cgroup_path_relative_to_mount = nullptr;
+ size_t len;
+ memoryHierarchyMount = FindMemoryHierarchyMount();
+ if (memoryHierarchyMount == nullptr)
+ goto done;
+
+ cgroup_path_relative_to_mount = FindCGroupPathForMemorySubsystem();
+ if (cgroup_path_relative_to_mount == nullptr)
+ goto done;
+
+ len = strlen(memoryHierarchyMount);
+ len += strlen(cgroup_path_relative_to_mount);
+ m_memory_cgroup_path = (char*)PAL_malloc(len+1);
+ if (m_memory_cgroup_path == nullptr)
+ goto done;
+
+ strcpy_s(m_memory_cgroup_path, len+1, memoryHierarchyMount);
+ strcat_s(m_memory_cgroup_path, len+1, cgroup_path_relative_to_mount);
+
+ done:
+ PAL_free(memoryHierarchyMount);
+ PAL_free(cgroup_path_relative_to_mount);
+ }
+ ~CGroup()
+ {
+ PAL_free(m_memory_cgroup_path);
+ }
+
+ bool GetPhysicalMemoryLimit(size_t *val)
+ {
+ char *mem_limit_filename = nullptr;
+ bool result = false;
+
+ if (m_memory_cgroup_path == nullptr)
+ return result;
+
+ size_t len = strlen(m_memory_cgroup_path);
+ len += strlen(MEM_LIMIT_FILENAME);
+ mem_limit_filename = (char*)PAL_malloc(len+1);
+ if (mem_limit_filename == nullptr)
+ return result;
+
+ strcpy_s(mem_limit_filename, len+1, m_memory_cgroup_path);
+ strcat_s(mem_limit_filename, len+1, MEM_LIMIT_FILENAME);
+ result = ReadMemoryValueFromFile(mem_limit_filename, val);
+ PAL_free(mem_limit_filename);
+ return result;
+ }
+private:
+ char* FindMemoryHierarchyMount()
+ {
+ char *line = nullptr;
+ size_t lineLen = 0, maxLineLen = 0;
+ char *filesystemType = nullptr;
+ char *options = nullptr;
+ char* mountpath = nullptr;
+
+ FILE *mountinfofile = fopen(PROC_MOUNTINFO_FILENAME, "r");
+ if (mountinfofile == nullptr)
+ goto done;
+
+ while (getline(&line, &lineLen, mountinfofile) != -1)
+ {
+ if (filesystemType == nullptr || lineLen > maxLineLen)
+ {
+ PAL_free(filesystemType);
+ PAL_free(options);
+ filesystemType = (char*)PAL_malloc(lineLen+1);
+ if (filesystemType == nullptr)
+ goto done;
+ options = (char*)PAL_malloc(lineLen+1);
+ if (options == nullptr)
+ goto done;
+ maxLineLen = lineLen;
+ }
+ char* separatorChar = strchr(line, '-');
+
+ // See man page of proc to get format for /proc/self/mountinfo file
+ int sscanfRet = sscanf_s(separatorChar,
+ "- %s %*s %s",
+ filesystemType, lineLen+1,
+ options, lineLen+1);
+ if (sscanfRet != 2)
+ {
+ _ASSERTE(!"Failed to parse mount info file contents with sscanf_s.");
+ goto done;
+ }
+
+ if (strncmp(filesystemType, "cgroup", 6) == 0)
+ {
+ char* context = nullptr;
+ char* strTok = strtok_s(options, ",", &context);
+ while (strTok != nullptr)
+ {
+ if (strncmp("memory", strTok, 6) == 0)
+ {
+ mountpath = (char*)PAL_malloc(lineLen+1);
+ if (mountpath == nullptr)
+ goto done;
+
+ sscanfRet = sscanf_s(line,
+ "%*s %*s %*s %*s %s ",
+ mountpath, lineLen+1);
+ if (sscanfRet != 1)
+ {
+ PAL_free(mountpath);
+ mountpath = nullptr;
+ _ASSERTE(!"Failed to parse mount info file contents with sscanf_s.");
+ }
+ goto done;
+ }
+ strTok = strtok_s(nullptr, ",", &context);
+ }
+ }
+ }
+ done:
+ PAL_free(filesystemType);
+ PAL_free(options);
+ free(line);
+ if (mountinfofile)
+ fclose(mountinfofile);
+ return mountpath;
+ }
+
+ char* FindCGroupPathForMemorySubsystem()
+ {
+ char *line = nullptr;
+ size_t lineLen = 0;
+ size_t maxLineLen = 0;
+ char *subsystem_list = nullptr;
+ char *cgroup_path = nullptr;
+ bool result = false;
+
+ FILE *cgroupfile = fopen(PROC_CGROUP_FILENAME, "r");
+ if (cgroupfile == nullptr)
+ goto done;
+
+ while (!result && getline(&line, &lineLen, cgroupfile) != -1)
+ {
+ if (subsystem_list == nullptr || lineLen > maxLineLen)
+ {
+ PAL_free(subsystem_list);
+ PAL_free(cgroup_path);
+ subsystem_list = (char*)PAL_malloc(lineLen+1);
+ if (subsystem_list == nullptr)
+ goto done;
+ cgroup_path = (char*)PAL_malloc(lineLen+1);
+ if (cgroup_path == nullptr)
+ goto done;
+ maxLineLen = lineLen;
+ }
+
+ // See man page of proc to get format for /proc/self/cgroup file
+ int sscanfRet = sscanf_s(line,
+ "%*[^:]:%[^:]:%s",
+ subsystem_list, lineLen+1,
+ cgroup_path, lineLen+1);
+ if (sscanfRet != 2)
+ {
+ _ASSERTE(!"Failed to parse cgroup info file contents with sscanf_s.");
+ goto done;
+ }
+
+ char* context = nullptr;
+ char* strTok = strtok_s(subsystem_list, ",", &context);
+ while (strTok != nullptr)
+ {
+ if (strncmp("memory", strTok, 6) == 0)
+ {
+ result = true;
+ break;
+ }
+ strTok = strtok_s(nullptr, ",", &context);
+ }
+ }
+ done:
+ PAL_free(subsystem_list);
+ if (!result)
+ {
+ PAL_free(cgroup_path);
+ cgroup_path = nullptr;
+ }
+ free(line);
+ if (cgroupfile)
+ fclose(cgroupfile);
+ return cgroup_path;
+ }
+
+ bool ReadMemoryValueFromFile(const char* filename, size_t* val)
+ {
+ bool result = false;
+ char *line = nullptr;
+ size_t lineLen = 0;
+ char* endptr = nullptr;
+ size_t num = 0, l, multiplier;
+
+ if (val == nullptr)
+ return false;
+
+ FILE* file = fopen(filename, "r");
+ if (file == nullptr)
+ goto done;
+
+ if (getline(&line, &lineLen, file) == -1)
+ goto done;
+
+ errno = 0;
+ num = strtoull(line, &endptr, 0);
+ if (errno != 0)
+ goto done;
+
+ multiplier = 1;
+ switch(*endptr)
+ {
+ case 'g':
+ case 'G': multiplier = 1024;
+ case 'm':
+ case 'M': multiplier = multiplier*1024;
+ case 'k':
+ case 'K': multiplier = multiplier*1024;
+ }
+
+ *val = num * multiplier;
+ result = true;
+ if (*val/multiplier != num)
+ result = false;
+ done:
+ if (file)
+ fclose(file);
+ free(line);
+ return result;
+ }
+};
+
+
+size_t
+PALAPI
+PAL_GetRestrictedPhysicalMemoryLimit()
+{
+ CGroup cgroup;
+ size_t physical_memory_limit;
+
+ if (!cgroup.GetPhysicalMemoryLimit(&physical_memory_limit))
+ physical_memory_limit = SIZE_T_MAX;
+
+ struct rlimit curr_rlimit;
+ size_t rlimit_soft_limit = (size_t)RLIM_INFINITY;
+ if (getrlimit(RLIMIT_AS, &curr_rlimit) == 0)
+ {
+ rlimit_soft_limit = curr_rlimit.rlim_cur;
+ }
+ physical_memory_limit = min(physical_memory_limit, rlimit_soft_limit);
+
+ // Ensure that limit is not greater than real memory size
+ long pages = sysconf(_SC_PHYS_PAGES);
+ if (pages != -1)
+ {
+ long pageSize = sysconf(_SC_PAGE_SIZE);
+ if (pageSize != -1)
+ {
+ physical_memory_limit = min(physical_memory_limit,
+ (size_t)pages * pageSize);
+ }
+ }
+
+ if(physical_memory_limit == SIZE_T_MAX)
+ physical_memory_limit = 0;
+ return physical_memory_limit;
+}
+
+BOOL
+PALAPI
+PAL_GetWorkingSetSize(size_t* val)
+{
+ BOOL result = false;
+ size_t linelen;
+ char* line = nullptr;
+
+ if (val == nullptr)
+ return FALSE;
+
+ FILE* file = fopen(PROC_STATM_FILENAME, "r");
+ if (file != nullptr && getline(&line, &linelen, file) != -1)
+ {
+ char* context = nullptr;
+ char* strTok = strtok_s(line, " ", &context);
+ strTok = strtok_s(nullptr, " ", &context);
+
+ errno = 0;
+ *val = strtoull(strTok, nullptr, 0);
+ if(errno == 0)
+ {
+ *val = *val * VIRTUAL_PAGE_SIZE;
+ result = true;
+ }
+ }
+
+ if (file)
+ fclose(file);
+ free(line);
+ return result;
+}
diff --git a/src/pal/src/misc/dbgmsg.cpp b/src/pal/src/misc/dbgmsg.cpp
index d6f173f160..5eb5ebf9ba 100644
--- a/src/pal/src/misc/dbgmsg.cpp
+++ b/src/pal/src/misc/dbgmsg.cpp
@@ -50,11 +50,7 @@ using namespace CorUnix;
/* append mode file I/O is safer */
#define _PAL_APPEND_DBG_OUTPUT_
-#if defined(_PAL_APPEND_DBG_OUTPUT_)
static const char FOPEN_FLAGS[] = "at";
-#else
-static const char FOPEN_FLAGS[] = "wt";
-#endif
/* number of ENTRY nesting levels to indicate with a '.' */
#define MAX_NESTING 50
diff --git a/src/pal/src/misc/environ.cpp b/src/pal/src/misc/environ.cpp
index fed7b69f38..9fc13467c5 100644
--- a/src/pal/src/misc/environ.cpp
+++ b/src/pal/src/misc/environ.cpp
@@ -218,7 +218,13 @@ GetEnvironmentVariableW(
}
else if (size == 0)
{
- // handle error in GetEnvironmentVariableA
+ // If size is 0, it either means GetEnvironmentVariableA failed, or that
+ // it succeeded and the value of the variable is empty. Check GetLastError
+ // to determine which. If the call failed, we won't touch the buffer.
+ if (GetLastError() == ERROR_SUCCESS)
+ {
+ *lpBuffer = '\0';
+ }
}
else
{
diff --git a/src/pal/src/misc/errorstrings.cpp b/src/pal/src/misc/errorstrings.cpp
index 22443114ee..2c5243945c 100644
--- a/src/pal/src/misc/errorstrings.cpp
+++ b/src/pal/src/misc/errorstrings.cpp
@@ -76,7 +76,7 @@ ErrorString palErrorStrings[] =
{ ERROR_SEM_TIMEOUT, W("The semaphore timeout period has expired.\n") },
{ ERROR_INSUFFICIENT_BUFFER, W("The data area passed to a system call is too small.\n") },
{ ERROR_INVALID_NAME, W("The filename, directory name, or volume label syntax is incorrect.\n") },
- { ERROR_MOD_NOT_FOUND, W("The specified module could not be found.\n") },
+ { ERROR_MOD_NOT_FOUND, W("The specified module or one of its dependencies could not be found.\n") },
{ ERROR_PROC_NOT_FOUND, W("The specified procedure could not be found.\n") },
{ ERROR_WAIT_NO_CHILDREN, W("There are no child processes to wait for.\n") },
{ ERROR_NEGATIVE_SEEK, W("An attempt was made to move the file pointer before the beginning of the file.\n") },
diff --git a/src/pal/src/misc/sysinfo.cpp b/src/pal/src/misc/sysinfo.cpp
index 3ccb35ab81..fff051818f 100644
--- a/src/pal/src/misc/sysinfo.cpp
+++ b/src/pal/src/misc/sysinfo.cpp
@@ -32,12 +32,20 @@ Revision History:
#error Either sysctl or sysconf is required for GetSystemInfo.
#endif
+#if HAVE_SYSINFO
+#include <sys/sysinfo.h>
+#endif
+
#include <sys/param.h>
#if HAVE_SYS_VMPARAM_H
#include <sys/vmparam.h>
#endif // HAVE_SYS_VMPARAM_H
+#if HAVE_XSWDEV
+#include <vm/vm_param.h>
+#endif // HAVE_XSWDEV
+
#if HAVE_MACH_VM_TYPES_H
#include <mach/vm_types.h>
#endif // HAVE_MACH_VM_TYPES_H
@@ -216,6 +224,8 @@ GlobalMemoryStatusEx(
lpBuffer->ullAvailExtendedVirtual = 0;
BOOL fRetVal = FALSE;
+ int mib[3];
+ int rc;
// Get the physical memory size
#if HAVE_SYSCONF && HAVE__SC_PHYS_PAGES
@@ -226,7 +236,6 @@ GlobalMemoryStatusEx(
lpBuffer->ullTotalPhys = (DWORDLONG)physical_memory;
fRetVal = TRUE;
#elif HAVE_SYSCTL
- int mib[2];
int64_t physical_memory;
size_t length;
@@ -234,7 +243,7 @@ GlobalMemoryStatusEx(
mib[0] = CTL_HW;
mib[1] = HW_MEMSIZE;
length = sizeof(INT64);
- int rc = sysctl(mib, 2, &physical_memory, &length, NULL, 0);
+ rc = sysctl(mib, 2, &physical_memory, &length, NULL, 0);
if (rc != 0)
{
ASSERT("sysctl failed for HW_MEMSIZE (%d)\n", errno);
@@ -244,11 +253,65 @@ GlobalMemoryStatusEx(
lpBuffer->ullTotalPhys = (DWORDLONG)physical_memory;
fRetVal = TRUE;
}
-#elif // HAVE_SYSINFO
- // TODO: implement getting memory details via sysinfo. On Linux, it provides swap file details that
- // we can use to fill in the xxxPageFile members.
-#endif // HAVE_SYSCONF
+#endif // HAVE_SYSCTL
+
+ // Get swap file size, consider the ability to get the values optional
+ // (don't return FALSE from the GlobalMemoryStatusEx)
+#if HAVE_XSW_USAGE
+ // This is available on OSX
+ struct xsw_usage xsu;
+ mib[0] = CTL_VM;
+ mib[1] = VM_SWAPUSAGE;
+ size_t length = sizeof(xsu);
+ rc = sysctl(mib, 2, &xsu, &length, NULL, 0);
+ if (rc == 0)
+ {
+ lpBuffer->ullTotalPageFile = xsu.xsu_total;
+ lpBuffer->ullAvailPageFile = xsu.xsu_avail;
+ }
+#elif HAVE_XSWDEV
+ // E.g. FreeBSD
+ struct xswdev xsw;
+
+ size_t length = 2;
+ rc = sysctlnametomib("vm.swap_info", mib, &length);
+ if (rc == 0)
+ {
+ int pagesize = getpagesize();
+ // Aggregate the information for all swap files on the system
+ for (mib[2] = 0; ; mib[2]++)
+ {
+ length = sizeof(xsw);
+ rc = sysctl(mib, 3, &xsw, &length, NULL, 0);
+ if ((rc < 0) || (xsw.xsw_version != XSWDEV_VERSION))
+ {
+ // All the swap files were processed or coreclr was built against
+ // a version of headers not compatible with the current XSWDEV_VERSION.
+ break;
+ }
+
+ DWORDLONG avail = xsw.xsw_nblks - xsw.xsw_used;
+ lpBuffer->ullTotalPageFile += (DWORDLONG)xsw.xsw_nblks * pagesize;
+ lpBuffer->ullAvailPageFile += (DWORDLONG)avail * pagesize;
+ }
+ }
+#elif HAVE_SYSINFO
+ // Linux
+ struct sysinfo info;
+ rc = sysinfo(&info);
+ if (rc == 0)
+ {
+ lpBuffer->ullTotalPageFile = info.totalswap;
+ lpBuffer->ullAvailPageFile = info.freeswap;
+#if HAVE_SYSINFO_WITH_MEM_UNIT
+ // A newer version of the sysinfo structure represents all the sizes
+ // in mem_unit instead of bytes
+ lpBuffer->ullTotalPageFile *= info.mem_unit;
+ lpBuffer->ullAvailPageFile *= info.mem_unit;
+#endif // HAVE_SYSINFO_WITH_MEM_UNIT
+ }
+#endif // HAVE_SYSINFO
// Get the physical memory in use - from it, we can get the physical memory available.
// We do this only when we have the total physical memory available.
diff --git a/src/pal/src/misc/time.cpp b/src/pal/src/misc/time.cpp
index 918f92a90f..d16fb587ba 100644
--- a/src/pal/src/misc/time.cpp
+++ b/src/pal/src/misc/time.cpp
@@ -394,3 +394,35 @@ EXIT:
return retval;
}
+/*++
+Function:
+ PAL_nanosleep
+
+Sleeps for the time specified in timeInNs.
+Returns 0 on successful completion of the operation.
+--*/
+PALAPI
+INT
+PAL_nanosleep(
+ IN long timeInNs
+ )
+{
+ struct timespec req;
+ struct timespec rem;
+ int result;
+
+ req.tv_sec = 0;
+ req.tv_nsec = timeInNs;
+
+ do
+ {
+ // Sleep for the requested time.
+ result = nanosleep(&req, &rem);
+
+ // Save the remaining time (used if the loop runs another iteration).
+ req = rem;
+ }
+ while(result == -1 && errno == EINTR);
+
+ return result;
+}
diff --git a/src/pal/src/misc/utils.cpp b/src/pal/src/misc/utils.cpp
index f0ff63439f..4eefd749ed 100644
--- a/src/pal/src/misc/utils.cpp
+++ b/src/pal/src/misc/utils.cpp
@@ -124,7 +124,12 @@ BOOL UTIL_IsExecuteBitsSet( struct stat * stat_data )
}
/* Check for read permissions. */
- if ( stat_data->st_uid == geteuid() )
+ if ( 0 == geteuid() )
+ {
+ /* The process owner is root */
+ bRetVal = TRUE;
+ }
+ else if ( stat_data->st_uid == geteuid() )
{
/* The process owner is the file owner as well. */
if ( ( stat_data->st_mode & S_IXUSR ) )
diff --git a/src/pal/src/misc/version.cpp b/src/pal/src/misc/version.cpp
deleted file mode 100644
index 7a9f90a320..0000000000
--- a/src/pal/src/misc/version.cpp
+++ /dev/null
@@ -1,119 +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.
-
-/*++
-
-
-
-Module Name:
-
- version.c
-
-Abstract:
-
- Implementation of functions for getting platform.OS versions.
-
-Revision History:
-
-
-
---*/
-
-#include "pal/palinternal.h"
-#include "pal/dbgmsg.h"
-
-SET_DEFAULT_DEBUG_CHANNEL(MISC);
-
-/*++
-Function:
- GetVersionExA
-
-
-
-GetVersionEx
-
-The GetVersionEx function obtains extended information about the
-version of the operating system that is currently running.
-
-Parameters
-
-lpVersionInfo
- [in/out] Pointer to an OSVERSIONINFO data structure that the
- function fills with operating system version information.
-
- Before calling the GetVersionEx function, set the
- dwOSVersionInfoSize member of the OSVERSIONINFO data structure
- to sizeof(OSVERSIONINFO).
-
-Return Values
-
-If the function succeeds, the return value is a nonzero value.
-
-If the function fails, the return value is zero. To get extended error
-information, call GetLastError. The function fails if you specify an
-invalid value for the dwOSVersionInfoSize member of the OSVERSIONINFO
-structure.
-
---*/
-BOOL
-PALAPI
-GetVersionExA(
- IN OUT LPOSVERSIONINFOA lpVersionInformation)
-{
- BOOL bRet = TRUE;
- PERF_ENTRY(GetVersionExA);
- ENTRY("GetVersionExA (lpVersionInformation=%p)\n", lpVersionInformation);
-
- if (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOA))
- {
- lpVersionInformation->dwMajorVersion = 5; /* same as WIN2000 */
- lpVersionInformation->dwMinorVersion = 0; /* same as WIN2000 */
- lpVersionInformation->dwBuildNumber = 0;
- lpVersionInformation->dwPlatformId = VER_PLATFORM_UNIX;
- lpVersionInformation->szCSDVersion[0] = '\0'; /* no service pack */
- }
- else
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- bRet = FALSE;
- }
- LOGEXIT("GetVersionExA returning BOOL %d\n", bRet);
- PERF_EXIT(GetVersionExA);
- return bRet;
-}
-
-
-/*++
-Function:
- GetVersionExW
-
-See GetVersionExA
---*/
-BOOL
-PALAPI
-GetVersionExW(
- IN OUT LPOSVERSIONINFOW lpVersionInformation)
-{
- BOOL bRet = TRUE;
-
- PERF_ENTRY(GetVersionExW);
- ENTRY("GetVersionExW (lpVersionInformation=%p)\n", lpVersionInformation);
-
- if (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOW))
- {
- lpVersionInformation->dwMajorVersion = 5; /* same as WIN2000 */
- lpVersionInformation->dwMinorVersion = 0; /* same as WIN2000 */
- lpVersionInformation->dwBuildNumber = 0;
- lpVersionInformation->dwPlatformId = VER_PLATFORM_UNIX;
- lpVersionInformation->szCSDVersion[0] = '\0'; /* no service pack */
- }
- else
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- bRet = FALSE;
- }
- LOGEXIT("GetVersionExW returning BOOL %d\n", bRet);
- PERF_EXIT(GetVersionExW);
- return bRet;
-}
diff --git a/src/pal/src/thread/context.cpp b/src/pal/src/thread/context.cpp
index 0449df568b..04a6fe5aaf 100644
--- a/src/pal/src/thread/context.cpp
+++ b/src/pal/src/thread/context.cpp
@@ -127,6 +127,8 @@ typedef int __ptrace_request;
ASSIGN_REG(R12)
#elif defined(_ARM64_)
#define ASSIGN_CONTROL_REGS \
+ ASSIGN_REG(Cpsr) \
+ ASSIGN_REG(Fp) \
ASSIGN_REG(Sp) \
ASSIGN_REG(Lr) \
ASSIGN_REG(Pc)
@@ -499,11 +501,13 @@ void CONTEXTFromNativeContext(const native_context_t *native, LPCONTEXT lpContex
if ((contextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
{
ASSIGN_CONTROL_REGS
-#ifdef _ARM_
+#if defined(_ARM_)
// WinContext assumes that the least bit of Pc is always 1 (denoting thumb)
// although the pc value retrived from native context might not have set the least bit.
// This becomes especially problematic if the context is on the JIT_WRITEBARRIER.
lpContext->Pc |= 0x1;
+#elif defined(_X86_)
+ lpContext->ResumeEsp = MCREG_Esp(native->uc_mcontext);
#endif
}
@@ -613,6 +617,35 @@ LPVOID GetNativeContextPC(const native_context_t *context)
/*++
Function :
+ GetNativeContextSP
+
+ Returns the stack pointer from the native context.
+
+Parameters :
+ const native_context_t *native : native context
+
+Return value :
+ The stack pointer from the native context.
+
+--*/
+LPVOID GetNativeContextSP(const native_context_t *context)
+{
+#ifdef _AMD64_
+ return (LPVOID)MCREG_Rsp(context->uc_mcontext);
+#elif defined(_X86_)
+ return (LPVOID) MCREG_Esp(context->uc_mcontext);
+#elif defined(_ARM_)
+ return (LPVOID) MCREG_Sp(context->uc_mcontext);
+#elif defined(_ARM64_)
+ return (LPVOID) MCREG_Sp(context->uc_mcontext);
+#else
+# error implement me for this architecture
+#endif
+}
+
+
+/*++
+Function :
CONTEXTGetExceptionCodeForSignal
Translates signal and context information to a Win32 exception code.
@@ -945,6 +978,7 @@ CONTEXT_GetThreadContextFromThreadState(
lpContext->Esi = pState->esi;
lpContext->Ebp = pState->ebp;
lpContext->Esp = pState->esp;
+ lpContext->ResumeEsp = pState->esp;
lpContext->SegSs = pState->ss;
lpContext->EFlags = pState->eflags;
lpContext->Eip = pState->eip;
diff --git a/src/pal/src/thread/process.cpp b/src/pal/src/thread/process.cpp
index ae069aec86..050665ce7c 100644
--- a/src/pal/src/thread/process.cpp
+++ b/src/pal/src/thread/process.cpp
@@ -2666,6 +2666,12 @@ CreateProcessModules(
// VM_ALLOCATE 0000000105bac000-0000000105bad000 [ 4K] r--/rw- SM=SHM
// MALLOC (admin) 0000000105bad000-0000000105bae000 [ 4K] r--/rwx SM=ZER
// MALLOC 0000000105bae000-0000000105baf000 [ 4K] rw-/rwx SM=ZER
+
+ // OS X Sierra (10.12.4 Beta)
+ // REGION TYPE START - END [ VSIZE RSDNT DIRTY SWAP] PRT/MAX SHRMOD PURGE REGION DETAIL
+ // Stack 00007fff5a930000-00007fff5b130000 [ 8192K 32K 32K 0K] rw-/rwx SM=PRV thread 0
+ // __TEXT 00007fffa4a0b000-00007fffa4a0d000 [ 8K 8K 0K 0K] r-x/r-x SM=COW /usr/lib/libSystem.B.dylib
+ // __TEXT 00007fffa4bbe000-00007fffa4c15000 [ 348K 348K 0K 0K] r-x/r-x SM=COW /usr/lib/libc++.1.dylib
char *line = NULL;
size_t lineLen = 0;
int count = 0;
@@ -2686,9 +2692,8 @@ CreateProcessModules(
{
void *startAddress, *endAddress;
char moduleName[PATH_MAX];
- int size;
- if (sscanf_s(line, "__TEXT %p-%p [ %dK] %*[-/rwxsp] SM=%*[A-Z] %s\n", &startAddress, &endAddress, &size, moduleName, _countof(moduleName)) == 4)
+ if (sscanf_s(line, "__TEXT %p-%p [ %*[0-9K ]] %*[-/rwxsp] SM=%*[A-Z] %s\n", &startAddress, &endAddress, moduleName, _countof(moduleName)) == 3)
{
bool dup = false;
for (ProcessModules *entry = listHead; entry != NULL; entry = entry->Next)
diff --git a/src/pal/src/thread/thread.cpp b/src/pal/src/thread/thread.cpp
index 53283320c5..df42ebcc96 100644
--- a/src/pal/src/thread/thread.cpp
+++ b/src/pal/src/thread/thread.cpp
@@ -28,6 +28,7 @@ SET_DEFAULT_DEBUG_CHANNEL(THREAD); // some headers have code with asserts, so do
#include "pal/handlemgr.hpp"
#include "pal/cs.hpp"
#include "pal/seh.hpp"
+#include "pal/signal.hpp"
#include "procprivate.hpp"
#include "pal/process.h"
@@ -177,6 +178,10 @@ static void InternalEndCurrentThreadWrapper(void *arg)
// in InternalEndCurrentThread.
InternalEndCurrentThread(pThread);
pthread_setspecific(thObjKey, NULL);
+
+#if !HAVE_MACH_EXCEPTIONS
+ FreeSignalAlternateStack();
+#endif // !HAVE_MACH_EXCEPTIONS
}
/*++
@@ -1659,6 +1664,14 @@ CPalThread::ThreadEntry(
goto fail;
}
+#if !HAVE_MACH_EXCEPTIONS
+ if (!EnsureSignalAlternateStack())
+ {
+ ASSERT("Cannot allocate alternate stack for SIGSEGV!\n");
+ goto fail;
+ }
+#endif // !HAVE_MACH_EXCEPTIONS
+
#if defined(FEATURE_PAL_SXS) && defined(_DEBUG)
// We cannot assert yet, as we haven't set in this thread into the TLS, and so __ASSERT_ENTER
// will fail if the assert fails and we'll crash.
diff --git a/src/pal/tests/palsuite/c_runtime/pow/test1/test1.cpp b/src/pal/tests/palsuite/c_runtime/pow/test1/test1.cpp
index 0a05cd5a47..7eea316e62 100644
--- a/src/pal/tests/palsuite/c_runtime/pow/test1/test1.cpp
+++ b/src/pal/tests/palsuite/c_runtime/pow/test1/test1.cpp
@@ -106,6 +106,9 @@ int __cdecl main(int argc, char **argv)
{ -2.7182818284590452, 1, -2.7182818284590452, PAL_EPSILON * 10 }, // x: -(e) expected: e
{ -2.7182818284590452, PAL_POSINF, PAL_POSINF, 0 }, // x: -(e)
+ { -1.0, PAL_NEGINF, 1.0, PAL_EPSILON * 10 },
+ { -1.0, PAL_POSINF, 1.0, PAL_EPSILON * 10 },
+
{ -0.0, PAL_NEGINF, PAL_POSINF, 0 },
{ -0.0, -1, PAL_NEGINF, 0 },
{ -0.0, -0.0, 1, PAL_EPSILON * 10 },
@@ -113,6 +116,9 @@ int __cdecl main(int argc, char **argv)
{ -0.0, 1, -0.0, PAL_EPSILON },
{ -0.0, PAL_POSINF, 0, PAL_EPSILON },
+ { PAL_NAN, -0.0, 1.0, PAL_EPSILON * 10 },
+ { PAL_NAN, 0, 1.0, PAL_EPSILON * 10 },
+
{ 0.0, PAL_NEGINF, PAL_POSINF, 0 },
{ 0.0, -1, PAL_POSINF, 0 },
{ 0, -0.0, 1, PAL_EPSILON * 10 },
@@ -211,12 +217,6 @@ int __cdecl main(int argc, char **argv)
validate_isnan(-2.7182818284590452, 0.78539816339744828); // x: -(e) y: pi / 4
validate_isnan(-2.7182818284590452, 1.5707963267948966); // x: -(e) y: pi / 2
- validate_isnan(-1, PAL_NEGINF);
- validate_isnan(-1, PAL_POSINF);
-
- validate_isnan(PAL_NAN, -0.0);
- validate_isnan(PAL_NAN, 0);
-
validate_isnan(PAL_NEGINF, PAL_NAN);
validate_isnan(PAL_NAN, PAL_NEGINF);
diff --git a/src/pal/tests/palsuite/c_runtime/powf/test1/test1.c b/src/pal/tests/palsuite/c_runtime/powf/test1/test1.c
index ca738e8c8d..e8933c5ce2 100644
--- a/src/pal/tests/palsuite/c_runtime/powf/test1/test1.c
+++ b/src/pal/tests/palsuite/c_runtime/powf/test1/test1.c
@@ -104,7 +104,10 @@ int __cdecl main(int argc, char **argv)
{ -2.71828183f, 0, 1, PAL_EPSILON * 10 }, // x: -(e)
{ -2.71828183f, 1, -2.71828183f, PAL_EPSILON * 10 }, // x: -(e) expected: e
{ -2.71828183f, PAL_POSINF, PAL_POSINF, 0 }, // x: -(e)
-
+
+ { -1.0, PAL_NEGINF, 1.0, PAL_EPSILON * 10 },
+ { -1.0, PAL_POSINF, 1.0, PAL_EPSILON * 10 },
+
{ -0.0, PAL_NEGINF, PAL_POSINF, 0 },
{ -0.0, -1, PAL_NEGINF, 0 },
{ -0.0f, -0.0f, 1, PAL_EPSILON * 10 },
@@ -112,6 +115,9 @@ int __cdecl main(int argc, char **argv)
{ -0.0, 1, -0.0, PAL_EPSILON },
{ -0.0, PAL_POSINF, 0, PAL_EPSILON },
+ { PAL_NAN, -0.0, 1.0, PAL_EPSILON * 10 },
+ { PAL_NAN, 0, 1.0, PAL_EPSILON * 10 },
+
{ 0.0, PAL_NEGINF, PAL_POSINF, 0 },
{ 0.0, -1, PAL_POSINF, 0 },
{ 0, -0.0f, 1, PAL_EPSILON * 10 },
@@ -210,12 +216,6 @@ int __cdecl main(int argc, char **argv)
validate_isnan(-2.71828183f, 0.785398163f); // x: -(e) y: pi / 4
validate_isnan(-2.71828183f, 1.57079633f); // x: -(e) y: pi / 2
- validate_isnan(-1, PAL_NEGINF);
- validate_isnan(-1, PAL_POSINF);
-
- validate_isnan(PAL_NAN, -0.0);
- validate_isnan(PAL_NAN, 0);
-
validate_isnan(PAL_NEGINF, PAL_NAN);
validate_isnan(PAL_NAN, PAL_NEGINF);
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/dlltest.cpp b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/dlltest.cpp
index 44f1b5a903..3e6cff292e 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/dlltest.cpp
+++ b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibrary/test1/dlltest.cpp
@@ -19,13 +19,13 @@
__declspec(dllexport)
#endif
-int __stdcall DllTest()
+int PALAPI DllTest()
{
return 1;
}
#ifdef WIN32
-int __stdcall _DllMainCRTStartup(void *hinstDLL, int reason, void * lpvReserved)
+int PALAPI _DllMainCRTStartup(void *hinstDLL, int reason, void * lpvReserved)
{
return 1;
}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/dlltest.cpp b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/dlltest.cpp
index 954c624d19..e66a9ebdbe 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/dlltest.cpp
+++ b/src/pal/tests/palsuite/filemapping_memmgt/FreeLibraryAndExitThread/test1/dlltest.cpp
@@ -19,13 +19,13 @@
__declspec(dllexport)
#endif
-int _stdcall DllTest()
+int PALAPI DllTest()
{
return 1;
}
#if WIN32
-int __stdcall _DllMainCRTStartup(void *hinstDLL, int reason, void * lpvReserved)
+int PALAPI _DllMainCRTStartup(void *hinstDLL, int reason, void * lpvReserved)
{
return 1;
}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/test1.cpp b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/test1.cpp
index f0b76c615f..5515ae4562 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/test1.cpp
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/test1.cpp
@@ -15,7 +15,7 @@
**===========================================================================*/
#include <palsuite.h>
-typedef int (__stdcall *SIMPLEFUNCTION)(int);
+typedef int (PALAPI *SIMPLEFUNCTION)(int);
/* SHLEXT is defined only for Unix variants */
#if defined(SHLEXT)
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/testlib.cpp b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/testlib.cpp
index e8fe48e05d..7b87ba7f79 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/testlib.cpp
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test1/testlib.cpp
@@ -20,13 +20,13 @@ __declspec(dllexport)
/**
* Simple function that returns i+1
*/
-int __stdcall SimpleFunction(int i)
+int PALAPI SimpleFunction(int i)
{
return i+1;
}
#if WIN32
-int __stdcall _DllMainCRTStartup(void *hinstDLL, int reason, void *lpvReserved)
+int PALAPI _DllMainCRTStartup(void *hinstDLL, int reason, void *lpvReserved)
{
return 1;
}
diff --git a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/testlib.cpp b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/testlib.cpp
index 23e58e871e..47299a1b1f 100644
--- a/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/testlib.cpp
+++ b/src/pal/tests/palsuite/filemapping_memmgt/GetProcAddress/test2/testlib.cpp
@@ -20,13 +20,13 @@ __declspec(dllexport)
/**
* Simple function that returns i+1
*/
-int __stdcall SimpleFunction(int i)
+int PALAPI SimpleFunction(int i)
{
return i+1;
}
#if WIN32
-int __stdcall _DllMainCRTStartup(void *hinstDLL, int reason, void *lpvReserved)
+int PALAPI _DllMainCRTStartup(void *hinstDLL, int reason, void *lpvReserved)
{
return 1;
}
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test6/dlltest.cpp b/src/pal/tests/palsuite/loader/LoadLibraryA/test6/dlltest.cpp
index 72380eebb5..372657605b 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test6/dlltest.cpp
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test6/dlltest.cpp
@@ -23,7 +23,7 @@
static int g_attachCount = 0;
/* standard DllMain() */
-BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved)
+BOOL PALAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved)
{
switch( reason )
{
@@ -53,7 +53,7 @@ BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved)
}
#if _WIN32
-BOOL __stdcall _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved)
+BOOL PALAPI _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved)
{
return DllMain(hinstDLL, reason, lpvReserved);
}
diff --git a/src/pal/tests/palsuite/loader/LoadLibraryA/test8/dlltest.cpp b/src/pal/tests/palsuite/loader/LoadLibraryA/test8/dlltest.cpp
index 72380eebb5..372657605b 100644
--- a/src/pal/tests/palsuite/loader/LoadLibraryA/test8/dlltest.cpp
+++ b/src/pal/tests/palsuite/loader/LoadLibraryA/test8/dlltest.cpp
@@ -23,7 +23,7 @@
static int g_attachCount = 0;
/* standard DllMain() */
-BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved)
+BOOL PALAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved)
{
switch( reason )
{
@@ -53,7 +53,7 @@ BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved)
}
#if _WIN32
-BOOL __stdcall _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved)
+BOOL PALAPI _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved)
{
return DllMain(hinstDLL, reason, lpvReserved);
}
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/CGroup/CMakeLists.txt
index f6aa0cb2d9..f6aa0cb2d9 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/CGroup/CMakeLists.txt
diff --git a/src/pal/tests/palsuite/miscellaneous/CGroup/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/CGroup/test1/CMakeLists.txt
new file mode 100644
index 0000000000..cdd7fa99d0
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/CGroup/test1/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test.cpp
+)
+
+add_executable(paltest_cgroup_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_cgroup_test1 coreclrpal)
+
+target_link_libraries(paltest_cgroup_test1
+ ${COMMON_TEST_LIBRARIES}
+)
diff --git a/src/pal/tests/palsuite/miscellaneous/CGroup/test1/test.cpp b/src/pal/tests/palsuite/miscellaneous/CGroup/test1/test.cpp
new file mode 100644
index 0000000000..44b970a233
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/CGroup/test1/test.cpp
@@ -0,0 +1,53 @@
+// 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.
+
+/*============================================================
+**
+** Source: test.c
+**
+** Purpose: Test for CGroup
+**
+**
+** Steps to run this test on ubuntu:
+** 1. sudo apt-get install cgroup-bin
+** 2. sudo vi /etc/default/grub
+** Add cgroup_enable=memory swapaccount=1 to GRUB_CMDLINE_LINUX_DEFAULT
+** 3. sudo update-grub
+** 4. reboot
+** 5. sudo cgcreate -g cpu,memory:/myGroup -a <username>:<username> -t <username>:<username>
+** 6. echo 4M > /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes
+** 7. echo 4M > /sys/fs/cgroup/memory/mygroup/memory.memsw.limit_in_bytes
+** 8. cgexe -g memory:/mygroup --sticky <application>
+**=========================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc,char *argv[])
+{
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ size_t mem_limit = PAL_GetRestrictedPhysicalMemoryLimit();
+
+ FILE* file = fopen("/sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes", "r");
+ if(file != NULL)
+ {
+ if(mem_limit != 4194304)
+ Fail("Memory limit obtained from PAL_GetRestrictedPhysicalMemory is not 4MB\n");
+ fclose(file);
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
+
+
+
diff --git a/src/pal/tests/palsuite/miscellaneous/CGroup/test1/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/CGroup/test1/testinfo.dat
new file mode 100644
index 0000000000..86da2d1515
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/CGroup/test1/testinfo.dat
@@ -0,0 +1,12 @@
+# 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.
+
+Version = 1.0
+Section = Miscellaneous
+Function = CGroup
+Name = Positive Test for CGroup
+TYPE = DEFAULT
+EXE1 = test
+Description
+= Test to see if Cgroup memory limit works properly
diff --git a/src/pal/tests/palsuite/miscellaneous/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/CMakeLists.txt
index 0fd4df8ad5..9352edef52 100644
--- a/src/pal/tests/palsuite/miscellaneous/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/CMakeLists.txt
@@ -1,5 +1,6 @@
cmake_minimum_required(VERSION 2.8.12.2)
+add_subdirectory(CGroup)
add_subdirectory(CharNextA)
add_subdirectory(CharNextExA)
add_subdirectory(CloseHandle)
@@ -14,6 +15,7 @@ add_subdirectory(GetEnvironmentVariableA)
add_subdirectory(GetEnvironmentVariableW)
add_subdirectory(GetLastError)
add_subdirectory(GetSystemInfo)
+add_subdirectory(GlobalMemoryStatusEx)
add_subdirectory(GetTickCount)
add_subdirectory(InterlockedBit)
add_subdirectory(InterlockedCompareExchange)
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/CMakeLists.txt
deleted file mode 100644
index 1e512f3c2f..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.cpp
-)
-
-add_executable(paltest_getversionexa_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_getversionexa_test1 coreclrpal)
-
-target_link_libraries(paltest_getversionexa_test1
- ${COMMON_TEST_LIBRARIES}
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/test.cpp b/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/test.cpp
deleted file mode 100644
index 5dd20c6576..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/test.cpp
+++ /dev/null
@@ -1,83 +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.
-
-/*============================================================
-**
-** Source : test.c
-**
-** Purpose: Test for GetVersionExA() function
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[]) {
-
- OSVERSIONINFO TheVersionInfo;
- OSVERSIONINFO* pVersionInfo = &TheVersionInfo;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
-
- /* This needs to be done before using GetVersionEx */
- pVersionInfo->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-
- /* If GetVersionEx fails, then the test fails */
- if(GetVersionEx(pVersionInfo) == 0)
- {
- Fail("ERROR: The GetVersionEx function returned 0, which indicates "
- "failure.");
- }
-
- /* These values are fixed, ensure they're set properly */
- if(pVersionInfo->dwMajorVersion != 5)
- {
- Fail("ERROR: The fixed value of dwMajorVersion shoud be 5, "
- "but is really %d.",pVersionInfo->dwMajorVersion);
- }
-
- /* The minor version values for Win2k and XP are different
- for Win2k minor version equals 0 and for XP minor version
- equals 1. Both values are excepted here. */
- if((pVersionInfo->dwMinorVersion != 0) &&
- (pVersionInfo->dwMinorVersion != 1))
- {
- Fail("ERROR: The fixed value of dwMinorVersion shoud be 0 or 1, "
- "but is really %d.",pVersionInfo->dwMinorVersion);
- }
- if(pVersionInfo->dwBuildNumber_PAL_Undefined < 0)
- {
- Fail("ERROR: The value of dwBuildNumber shoud be at least 0, but "
- "is really %d.",pVersionInfo->dwBuildNumber_PAL_Undefined);
- }
-
-#if !WIN32
- /* Under BSD, the PlatformID should be UNIX and the Service Pack
- version should be set to "".
- */
-
- if(pVersionInfo->dwPlatformId != VER_PLATFORM_UNIX ||
- pVersionInfo->szCSDVersion_PAL_Undefined[0] != 0)
- {
- Fail("ERROR: The dwPlatformId should be %d but is really %d. And the "
- "szCSDVerion should be NULL.",
- VER_PLATFORM_UNIX,pVersionInfo->dwPlatformId);
- }
-#endif
-
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/testinfo.dat
deleted file mode 100644
index 1e9c570c60..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/testinfo.dat
+++ /dev/null
@@ -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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = GetVersionExA
-Name = Positive Test for GetVersionExA
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test that all the values in the OSVERSION structure are set properly
-= for the current environment.
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/CMakeLists.txt
deleted file mode 100644
index 4ef820c479..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.cpp
-)
-
-add_executable(paltest_getversionexw_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_getversionexw_test1 coreclrpal)
-
-target_link_libraries(paltest_getversionexw_test1
- ${COMMON_TEST_LIBRARIES}
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/test.cpp b/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/test.cpp
deleted file mode 100644
index 69aae54bcf..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/test.cpp
+++ /dev/null
@@ -1,88 +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.
-
-/*============================================================
-**
-** Source : test.c
-**
-** Purpose: Test for GetVersionExW() function
-**
-**
-**=========================================================*/
-
-#define UNICODE
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
- OSVERSIONINFO TheVersionInfo;
- OSVERSIONINFO* pVersionInfo = &TheVersionInfo;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* This needs to be done before using GetVersionEx */
- pVersionInfo->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-
- /* If GetVersionEx fails, then the test fails */
- if(GetVersionEx(pVersionInfo) == 0)
- {
- Fail("ERROR: The GetVersionEx function returned 0, which indicates "
- "failure.");
- }
-
- /* These values are fixed, ensure they're set properly */
- if(pVersionInfo->dwMajorVersion != 5)
- {
- Fail("ERROR: The fixed value of dwMajorVersion shoud be 5, but is "
- " really %d.",pVersionInfo->dwMajorVersion);
- }
-
- /* The minor version values for Win2k and XP are different
- for Win2k minor version equals 0 and for XP minor version
- equals 1. Both values are excepted here. */
- if((pVersionInfo->dwMinorVersion != 0) &&
- (pVersionInfo->dwMinorVersion != 1))
- {
- Fail("ERROR: The fixed value of dwMinorVersion shoud be 0 or 1, "
- "but is really %d.",pVersionInfo->dwMinorVersion);
- }
-
- if(pVersionInfo->dwBuildNumber_PAL_Undefined < 0)
- {
- Fail("ERROR: The value of dwBuildNumber shoud be at least 0, but is "
- "really %d.",pVersionInfo->dwBuildNumber_PAL_Undefined);
- }
-
-#if !WIN32
-
-
- /* Under BSD, the PlatformID should be UNIX and the Service Pack
- version should be set to "".
- */
-
- if(pVersionInfo->dwPlatformId != VER_PLATFORM_UNIX ||
- pVersionInfo->szCSDVersion_PAL_Undefined[0] != 0)
- {
- Fail("ERROR: The dwPlatformId should be %d but is really %d. And the "
- "szCSDVerion should be NULL.",VER_PLATFORM_UNIX,
- pVersionInfo->dwPlatformId);
- }
-#endif
-
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/testinfo.dat
deleted file mode 100644
index 7773245b3f..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/testinfo.dat
+++ /dev/null
@@ -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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = GetVersionExW
-Name = Positive Test for GetVersionExW
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test that all the values in the OSVERSION structure are set properly
-= for the current environment.
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GlobalMemoryStatusEx/CMakeLists.txt
index f6aa0cb2d9..f6aa0cb2d9 100644
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/CMakeLists.txt
+++ b/src/pal/tests/palsuite/miscellaneous/GlobalMemoryStatusEx/CMakeLists.txt
diff --git a/src/pal/tests/palsuite/miscellaneous/GlobalMemoryStatusEx/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GlobalMemoryStatusEx/test1/CMakeLists.txt
new file mode 100644
index 0000000000..6e74f22baa
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/GlobalMemoryStatusEx/test1/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(SOURCES
+ test.cpp
+)
+
+add_executable(paltest_globalmemorystatusex_test1
+ ${SOURCES}
+)
+
+add_dependencies(paltest_globalmemorystatusex_test1 coreclrpal)
+
+target_link_libraries(paltest_globalmemorystatusex_test1
+ ${COMMON_TEST_LIBRARIES}
+)
diff --git a/src/pal/tests/palsuite/miscellaneous/GlobalMemoryStatusEx/test1/test.cpp b/src/pal/tests/palsuite/miscellaneous/GlobalMemoryStatusEx/test1/test.cpp
new file mode 100644
index 0000000000..460edade61
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/GlobalMemoryStatusEx/test1/test.cpp
@@ -0,0 +1,55 @@
+// 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.
+
+/*============================================================
+**
+** Source : test.c
+**
+** Purpose: Test for GlobalMemoryStatusEx() function
+**
+**
+**=========================================================*/
+
+#include <palsuite.h>
+
+int __cdecl main(int argc, char *argv[]) {
+
+ MEMORYSTATUSEX memoryStatus;
+
+ /*
+ * Initialize the PAL and return FAILURE if this fails
+ */
+
+ if(0 != (PAL_Initialize(argc, argv)))
+ {
+ return FAIL;
+ }
+
+ if (!GlobalMemoryStatusEx(&memoryStatus))
+ {
+ Fail("ERROR: GlobalMemoryStatusEx failed.");
+ }
+
+ printf("GlobalMemoryStatusEx:\n");
+ printf(" ullTotalPhys: %llu\n", memoryStatus.ullTotalPhys);
+ printf(" ullAvailPhys: %llu\n", memoryStatus.ullAvailPhys);
+ printf(" ullTotalVirtual: %llu\n", memoryStatus.ullTotalVirtual);
+ printf(" ullAvailVirtual: %llu\n", memoryStatus.ullAvailVirtual);
+ printf(" ullTotalPageFile: %llu\n", memoryStatus.ullTotalPageFile);
+ printf(" ullAvailPageFile: %llu\n", memoryStatus.ullAvailPageFile);
+ printf(" ullAvailExtendedVirtual: %llu\n", memoryStatus.ullAvailExtendedVirtual);
+ printf(" dwMemoryLoad: %u\n", memoryStatus.dwMemoryLoad);
+
+ if (memoryStatus.ullTotalPhys == 0 ||
+ memoryStatus.ullAvailPhys == 0 ||
+ memoryStatus.ullTotalVirtual == 0 ||
+ memoryStatus.ullAvailVirtual == 0
+ )
+ {
+ Fail("ERROR: GlobalMemoryStatusEx succeeded, but returned zero physical of virtual memory sizes.");
+ }
+
+ PAL_Terminate();
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/miscellaneous/GlobalMemoryStatusEx/test1/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/GlobalMemoryStatusEx/test1/testinfo.dat
new file mode 100644
index 0000000000..7ae3b5142a
--- /dev/null
+++ b/src/pal/tests/palsuite/miscellaneous/GlobalMemoryStatusEx/test1/testinfo.dat
@@ -0,0 +1,14 @@
+# 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.
+
+Version = 1.0
+Section = Miscellaneous
+Function = GlobalMemoryStatusEx
+Name = Positive Test for GlobalMemoryStatusEx
+TYPE = DEFAULT
+EXE1 = test
+Description
+= Ensures that invocation of GlobalMemoryStatusEx succeeds and
+= that it returns nonzero virtual and physical memory sizes
+
diff --git a/src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/palstartup.h b/src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/palstartup.h
index 862870be99..1947b59b77 100644
--- a/src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/palstartup.h
+++ b/src/pal/tests/palsuite/pal_specific/pal_entrypoint/test1/palstartup.h
@@ -27,6 +27,11 @@ static DWORD PALAPI run_main(struct _mainargs *args)
return (DWORD) PAL_startup_main(args->argc, args->argv);
}
+static void terminate(void)
+{
+ PAL_Terminate();
+}
+
int __cdecl main(int argc, char **argv) {
struct _mainargs mainargs;
@@ -34,9 +39,7 @@ int __cdecl main(int argc, char **argv) {
return FAIL;;
}
- // PAL_Terminate is a stdcall function, but it takes no parameters
- // so the difference doesn't matter.
- atexit((void (__cdecl *)(void)) PAL_Terminate);
+ atexit(terminate);
mainargs.argc = argc;
mainargs.argv = argv;
diff --git a/src/pal/tests/palsuite/paltestlist.txt b/src/pal/tests/palsuite/paltestlist.txt
index 600c2a533b..f0dfe3f9ea 100644
--- a/src/pal/tests/palsuite/paltestlist.txt
+++ b/src/pal/tests/palsuite/paltestlist.txt
@@ -668,6 +668,7 @@ miscellaneous/GetEnvironmentVariableW/test5/paltest_getenvironmentvariablew_test
miscellaneous/GetEnvironmentVariableW/test6/paltest_getenvironmentvariablew_test6
miscellaneous/GetLastError/test1/paltest_getlasterror_test1
miscellaneous/GetSystemInfo/test1/paltest_getsysteminfo_test1
+miscellaneous/GlobalMemoryStatusEx/test1/paltest_globalmemorystatusex_test1
miscellaneous/GetTickCount/test1/paltest_gettickcount_test1
miscellaneous/InterlockedCompareExchange/test1/paltest_interlockedcompareexchange_test1
miscellaneous/InterlockedCompareExchange/test2/paltest_interlockedcompareexchange_test2
@@ -687,7 +688,6 @@ miscellaneous/InterlockedIncrement64/test1/paltest_interlockedincrement64_test1
miscellaneous/InterlockedIncrement64/test2/paltest_interlockedincrement64_test2
miscellaneous/lstrlenA/test1/paltest_lstrlena_test1
miscellaneous/lstrlenW/test1/paltest_lstrlenw_test1
-miscellaneous/queryperformancecounter/test1/paltest_queryperformancecounter_test1
miscellaneous/queryperformancefrequency/test1/paltest_queryperformancefrequency_test1
miscellaneous/SetEnvironmentVariableA/test1/paltest_setenvironmentvariablea_test1
miscellaneous/SetEnvironmentVariableA/test2/paltest_setenvironmentvariablea_test2
@@ -763,9 +763,6 @@ threading/SetEvent/test1/paltest_setevent_test1
threading/SetEvent/test2/paltest_setevent_test2
threading/SetEvent/test3/paltest_setevent_test3
threading/SetEvent/test4/paltest_setevent_test4
-threading/Sleep/test1/paltest_sleep_test1
-threading/SleepEx/test1/paltest_sleepex_test1
-threading/SleepEx/test2/paltest_sleepex_test2
threading/SwitchToThread/test1/paltest_switchtothread_test1
threading/ThreadPriority/test1/paltest_threadpriority_test1
threading/TLS/test1/paltest_tls_test1
diff --git a/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt b/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt
index 0e12ccbf55..3f9469d254 100644
--- a/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt
+++ b/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt
@@ -144,8 +144,6 @@ miscellaneous/GetDateFormatW/GetDateFormatW_neg1/paltest_getdateformatw_getdatef
miscellaneous/GetDateFormatW/GetDateFormatW_neg2/paltest_getdateformatw_getdateformatw_neg2
miscellaneous/GetDateFormatW/test1/paltest_getdateformatw_test1
miscellaneous/GetUserNameW/test1/paltest_getusernamew_test1
-miscellaneous/GetVersionExA/test1/paltest_getversionexa_test1
-miscellaneous/GetVersionExW/test1/paltest_getversionexw_test1
miscellaneous/InterLockedExchangeAdd/test1/paltest_interlockedexchangeadd_test1
miscellaneous/IsBadCodePtr/test1/paltest_isbadcodeptr_test1
miscellaneous/IsBadReadPtr/test1/paltest_isbadreadptr_test1
@@ -154,6 +152,7 @@ miscellaneous/IsBadWritePtr/test2/paltest_isbadwriteptr_test2
miscellaneous/IsBadWritePtr/test3/paltest_isbadwriteptr_test3
miscellaneous/MessageBoxW/test1/paltest_messageboxw_test1
miscellaneous/MessageBoxW/test2/paltest_messageboxw_test2
+miscellaneous/queryperformancecounter/test1/paltest_queryperformancecounter_test1
miscellaneous/wsprintfW/test2/paltest_wsprintfw_test2
miscellaneous/wsprintfW/test7/paltest_wsprintfw_test7
pal_specific/PAL_GetMachineConfigurationDirectoryW/test1/paltest_pal_getmachineconfigurationdirectoryw_test1
@@ -191,6 +190,9 @@ threading/OpenEventW/test5/paltest_openeventw_test5
threading/OpenProcess/test1/paltest_openprocess_test1
threading/QueueUserAPC/test1/paltest_queueuserapc_test1
threading/setthreadcontext/test1/paltest_setthreadcontext_test1
+threading/Sleep/test1/paltest_sleep_test1
+threading/SleepEx/test1/paltest_sleepex_test1
+threading/SleepEx/test2/paltest_sleepex_test2
threading/SuspendThread/test2/paltest_suspendthread_test2
threading/SuspendThread/test3/paltest_suspendthread_test3
threading/TerminateProcess/test1/paltest_terminateprocess_test1
diff --git a/src/pal/tests/palsuite/palverify.dat b/src/pal/tests/palsuite/palverify.dat
index 1872313a94..d4cb311010 100644
--- a/src/pal/tests/palsuite/palverify.dat
+++ b/src/pal/tests/palsuite/palverify.dat
@@ -753,6 +753,7 @@ miscellaneous/getenvironmentvariablew/test3,1
miscellaneous/getenvironmentvariablew/test4,1
miscellaneous/getlasterror/test1,1
miscellaneous/getsysteminfo/test1,1
+miscellaneous/getglobalmemorystatusex/test1,1
miscellaneous/gettickcount/test1,1
miscellaneous/getversionexa/test1,1
miscellaneous/getversionexw/test1,1
diff --git a/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CreateMutexA.cpp b/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CreateMutexA.cpp
index 52bab351fb..3074fa03fc 100644
--- a/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CreateMutexA.cpp
+++ b/src/pal/tests/palsuite/threading/CreateMutexA_ReleaseMutex/test1/CreateMutexA.cpp
@@ -169,8 +169,7 @@ FillBuffer()
/*
* Producer thread function.
*/
-DWORD
-Producer(LPVOID lpParam)
+DWORD PALAPI Producer(LPVOID lpParam)
{
int n = 0;
int ret;
@@ -202,7 +201,7 @@ Producer(LPVOID lpParam)
/*
* Consumer thread function.
*/
-DWORD Consumer( LPVOID lpParam )
+DWORD PALAPI Consumer( LPVOID lpParam )
{
int n = 0;
int ret;
diff --git a/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CreateMutexW.cpp b/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CreateMutexW.cpp
index c21bfb6a50..ec8e0c66b7 100644
--- a/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CreateMutexW.cpp
+++ b/src/pal/tests/palsuite/threading/CreateMutexW_ReleaseMutex/test1/CreateMutexW.cpp
@@ -169,8 +169,7 @@ FillBuffer()
/*
* Producer thread function.
*/
-DWORD
-Producer(LPVOID lpParam)
+DWORD PALAPI Producer(LPVOID lpParam)
{
int n = 0;
int ret;
@@ -202,7 +201,7 @@ Producer(LPVOID lpParam)
/*
* Consumer thread function.
*/
-DWORD Consumer( LPVOID lpParam )
+DWORD PALAPI Consumer( LPVOID lpParam )
{
int n = 0;
int ret;
diff --git a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/test1.cpp b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/test1.cpp
index b64fd0c7d2..55251d46bf 100644
--- a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/test1.cpp
+++ b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/test1.cpp
@@ -26,7 +26,7 @@
#define GETCALLCOUNT "_GetCallCount@0"
#endif
-DWORD __stdcall ThreadFunc(LPVOID lpParam);
+DWORD PALAPI ThreadFunc(LPVOID lpParam);
int RunTest(int DisableThreadCalls);
int __cdecl main(int argc, char **argv)
@@ -78,7 +78,7 @@ int __cdecl main(int argc, char **argv)
/*
* Thread entry point. Doesn't do anything.
*/
-DWORD __stdcall ThreadFunc(LPVOID lpParam)
+DWORD PALAPI ThreadFunc(LPVOID lpParam)
{
return 0;
}
diff --git a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/testlib.cpp b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/testlib.cpp
index 53b66d1357..057dfde66d 100644
--- a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/testlib.cpp
+++ b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test1/testlib.cpp
@@ -15,7 +15,7 @@
static int Count;
-BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+BOOL PALAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
@@ -32,7 +32,7 @@ BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
}
#ifdef WIN32
-BOOL __stdcall _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+BOOL PALAPI _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
return DllMain(hinstDLL, fdwReason, lpvReserved);
}
@@ -41,7 +41,7 @@ BOOL __stdcall _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lp
#ifdef WIN32
__declspec(dllexport)
#endif
-int __stdcall GetCallCount()
+int PALAPI GetCallCount()
{
return Count;
}
diff --git a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain1.cpp b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain1.cpp
index 5010a27665..b65bb66a56 100644
--- a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain1.cpp
+++ b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain1.cpp
@@ -50,7 +50,7 @@ BOOL PALAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved)
#ifdef WIN32
-BOOL __stdcall _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+BOOL PALAPI _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
return DllMain(hinstDLL, fdwReason, lpvReserved);
}
diff --git a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain2.cpp b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain2.cpp
index 4e3f8862a4..519083bbaf 100644
--- a/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain2.cpp
+++ b/src/pal/tests/palsuite/threading/DisableThreadLibraryCalls/test2/dllmain2.cpp
@@ -50,7 +50,7 @@ BOOL PALAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved)
#ifdef WIN32
-BOOL __stdcall _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+BOOL PALAPI _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
return DllMain(hinstDLL, fdwReason, lpvReserved);
}
diff --git a/src/pal/tests/palsuite/threading/ExitThread/test3/dllmain.cpp b/src/pal/tests/palsuite/threading/ExitThread/test3/dllmain.cpp
index 923650d1d3..862aff5f00 100644
--- a/src/pal/tests/palsuite/threading/ExitThread/test3/dllmain.cpp
+++ b/src/pal/tests/palsuite/threading/ExitThread/test3/dllmain.cpp
@@ -48,7 +48,7 @@ BOOL PALAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID lpvReserved)
}
#ifdef WIN32
-BOOL __stdcall _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+BOOL PALAPI _DllMainCRTStartup(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
return DllMain(hinstDLL, fdwReason, lpvReserved);
}
diff --git a/src/pal/tools/gen-buildsys-clang.sh b/src/pal/tools/gen-buildsys-clang.sh
index db342eb2c9..762a1996b9 100755
--- a/src/pal/tools/gen-buildsys-clang.sh
+++ b/src/pal/tools/gen-buildsys-clang.sh
@@ -3,7 +3,7 @@
# This file invokes cmake and generates the build system for Clang.
#
-if [ $# -lt 4 -o $# -gt 8 ]
+if [ $# -lt 4 ]
then
echo "Usage..."
echo "gen-buildsys-clang.sh <path to top level CMakeLists.txt> <ClangMajorVersion> <ClangMinorVersion> <Architecture> [build flavor] [coverage] [ninja] [cmakeargs]"
@@ -139,15 +139,30 @@ if [[ -n "$CROSSCOMPILE" ]]; then
fi
cmake_extra_defines="$cmake_extra_defines -C $CONFIG_DIR/tryrun.cmake"
cmake_extra_defines="$cmake_extra_defines -DCMAKE_TOOLCHAIN_FILE=$CONFIG_DIR/toolchain.cmake"
+ cmake_extra_defines="$cmake_extra_defines -DCLR_UNIX_CROSS_BUILD=1"
+fi
+if [ $OS == "Linux" ]; then
+ linux_id_file="/etc/os-release"
+ if [[ -n "$CROSSCOMPILE" ]]; then
+ linux_id_file="$ROOTFS_DIR/$linux_id_file"
+ fi
+ if [[ -e $linux_id_file ]]; then
+ source $linux_id_file
+ cmake_extra_defines="$cmake_extra_defines -DCLR_CMAKE_LINUX_ID=$ID"
+ fi
fi
if [ "$build_arch" == "armel" ]; then
cmake_extra_defines="$cmake_extra_defines -DARM_SOFTFP=1"
fi
-if [ "$build_arch" == "arm" -o "$build_arch" == "armel" ]; then
- overridefile=clang-compiler-override-arm.txt
+clang_version=$(echo $CC | awk -F- '{ print $NF }')
+# Use O1 option when the clang version is smaller than 3.9
+# Otherwise use O3 option in release build
+if [[ ( ${clang_version%.*} -eq 3 && ${clang_version#*.} -lt 9 ) &&
+ ( "$build_arch" == "arm" || "$build_arch" == "armel" ) ]]; then
+ overridefile=clang-compiler-override-arm.txt
else
- overridefile=clang-compiler-override.txt
+ overridefile=clang-compiler-override.txt
fi
cmake \
diff --git a/src/pal/tools/gen-buildsys-win.bat b/src/pal/tools/gen-buildsys-win.bat
index f7f81fca33..70da41aa86 100644
--- a/src/pal/tools/gen-buildsys-win.bat
+++ b/src/pal/tools/gen-buildsys-win.bat
@@ -19,6 +19,7 @@ set __SourceDir=%1
set __VSVersion=%2
set __Arch=%3
set __CmakeGenerator=Visual Studio
+if /i "%__VSVersion%" == "vs2017" (set __CmakeGenerator=%__CmakeGenerator% 15 2017)
if /i "%__VSVersion%" == "vs2015" (set __CmakeGenerator=%__CmakeGenerator% 14 2015)
if /i "%__Arch%" == "x64" (set __CmakeGenerator=%__CmakeGenerator% Win64)
if /i "%__Arch%" == "arm64" (set __CmakeGenerator=%__CmakeGenerator% Win64)
@@ -47,7 +48,7 @@ GOTO :DONE
echo "Usage..."
echo "gen-buildsys-win.bat <path to top level CMakeLists.txt> <VSVersion>"
echo "Specify the path to the top level CMake file - <ProjectK>/src/NDP"
- echo "Specify the VSVersion to be used - VS2015"
+ echo "Specify the VSVersion to be used - VS2015 or VS2017"
EXIT /B 1
:DONE
diff --git a/src/pal/tools/probe-win.ps1 b/src/pal/tools/probe-win.ps1
index 783cb6dfe0..3d6c969d06 100644
--- a/src/pal/tools/probe-win.ps1
+++ b/src/pal/tools/probe-win.ps1
@@ -28,9 +28,13 @@ function GetCMakeInfo($regKey)
function LocateCMake
{
$errorMsg = "CMake is a pre-requisite to build this repository but it was not found on the path. Please install CMake from http://www.cmake.org/download/ and ensure it is on your path."
- $inPathPath = (get-command cmake.exe -ErrorAction SilentlyContinue).Path
+ $inPathPath = (get-command cmake.exe -ErrorAction SilentlyContinue)
if ($inPathPath -ne $null) {
- return $inPathPath
+ # Resolve the first version of CMake if multiple commands are found
+ if ($inPathPath.Length -gt 1) {
+ return $inPathPath[0].Path
+ }
+ return $inPathPath.Path
}
# Let us hope that CMake keep using their current version scheme
$validVersions = @()
diff --git a/src/strongname/api/strongname.cpp b/src/strongname/api/strongname.cpp
index 00b115698c..09c438b213 100644
--- a/src/strongname/api/strongname.cpp
+++ b/src/strongname/api/strongname.cpp
@@ -113,9 +113,6 @@ enum StrongNameCachedCsp {
// allocated lazily as needed.
struct SN_THREAD_CTX {
DWORD m_dwLastError;
-#if !defined(FEATURE_CORECLR)
- HCRYPTPROV m_hProv[CachedCspCount];
-#endif // !FEATURE_CORECLR
};
#endif // !DACCESS_COMPILE
@@ -170,8 +167,6 @@ struct SN_THREAD_CTX {
memcmp((_pk), g_rbTheKey, sizeof(g_rbTheKey)) == 0)
-#ifdef FEATURE_CORECLR
-
// Silverlight platform key
#define SN_THE_SILVERLIGHT_PLATFORM_KEYTOKEN() ((PublicKeyBlob*)g_rbTheSilverlightPlatformKeyToken)
#define SN_IS_THE_SILVERLIGHT_PLATFORM_KEY(_pk) (SN_SIZEOF_KEY((PublicKeyBlob*)(_pk)) == sizeof(g_rbTheSilverlightPlatformKey) && \
@@ -197,4480 +192,9 @@ struct SN_THREAD_CTX {
memcmp((_pk), g_rbTheMicrosoftXNAKey, sizeof(g_rbTheMicrosoftXNAKey)) == 0)
#endif // FEATURE_WINDOWSPHONE
-#endif // FEATURE_CORECLR
-
-#if !defined(FEATURE_CORECLR)
-
-#ifdef FEATURE_STRONGNAME_MIGRATION
-#include "caparser.h"
-#include "custattr.h"
-#include "cahlprinternal.h"
-#endif // FEATURE_STRONGNAME_MIGRATION
-
-// The maximum length of CSP name we support (in characters).
-#define SN_MAX_CSP_NAME 1024
-
-// If we're being built as a standalone library, then we shouldn't redirect through the hosting APIs
-#if !STRONGNAME_IN_VM
-
-#undef MapViewOfFile
-#undef UnmapViewOfFile
-
-#define CLRMapViewOfFile MapViewOfFile
-#define CLRUnmapViewOfFile UnmapViewOfFile
-
-#if FEATURE_STANDALONE_SN && !FEATURE_CORECLR
-
-// We will need to call into shim, therefore include new hosting APIs
-#include "metahost.h"
-#include "clrinternal.h"
-
-#endif //FEATURE_STANDALONE_SN && !FEATURE_CORECLR
-
-#define DONOT_DEFINE_ETW_CALLBACK
-
-#endif // !STRONGNAME_IN_VM
-#include "eventtracebase.h"
-
-#ifndef DACCESS_COMPILE
-
-// Flag indicating whether the initialization of the strong name APIs has been completed.
-BOOLEAN g_bStrongNamesInitialized = FALSE;
-
-// Flag indicating whether it's OK to cache the results of verifying an assembly
-// whose file is accessible to users.
-BOOLEAN g_fCacheVerify = TRUE;
-
-// Algorithm IDs for hashing and signing. Like the CSP name, these values are
-// read from the registry at initialization time.
-ALG_ID g_uHashAlgId;
-ALG_ID g_uSignAlgId;
-
-// Flag read from the registry at initialization time. It controls the key spec
-// to be used. AT_SIGNATURE will be the default.
-DWORD g_uKeySpec;
-
-// CSP provider type. PROV_RSA_FULL will be the default.
-DWORD g_uProvType;
-
-// Critical section used to serialize some non-thread safe crypto APIs.
-CRITSEC_COOKIE g_rStrongNameMutex = NULL;
-
-// Name of CSP to use. This is read from the registry at initialization time. If
-// not found we look up a CSP by hashing and signing algorithms (see below) or
-// use the default CSP.
-
-BOOLEAN g_bHasCSPName = FALSE;
-WCHAR g_wszCSPName[SN_MAX_CSP_NAME + 1] = {0};
-
-// Flag read from the registry at initialization time. Controls whether we use
-// machine or user based key containers.
-BOOLEAN g_bUseMachineKeyset = TRUE;
-
-#ifdef FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED
-// Verification Skip Records
-//
-// These are entries in the registry (usually set up by SN) that control whether
-// an assembly needs to pass signature verification to be considered valid (i.e.
-// return TRUE from StrongNameSignatureVerification). This is useful during
-// development when it's not feasible to fully sign each assembly on each build.
-// Assemblies to be skipped can be specified by name and public key token, all
-// assemblies with a given public key token or just all assemblies. Each entry
-// can be further qualified by a list of user names to which the records
-// applies. When matching against an entry, the most specific one wins.
-//
-// We read these entries at startup time and place them into a global, singly
-// linked, NULL terminated list.
-
-// Structure used to represent each record we find in the registry.
-struct SN_VER_REC {
- SN_VER_REC *m_pNext; // Pointer to next record (or NULL)
- WCHAR *m_wszAssembly; // Assembly name/public key token as a string
- WCHAR *m_mszUserList; // Pointer to multi-string list of valid users (or NULL)
- WCHAR *m_wszTestPublicKey; // Test public key to use during strong name verification (or NULL)
-};
-
-// Head of the list of entries we found in the registry during initialization.
-SN_VER_REC *g_pVerificationRecords = NULL;
-#endif // FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED
-
-#ifdef FEATURE_STRONGNAME_MIGRATION
-
-struct SN_REPLACEMENT_KEY_REC {
- SN_REPLACEMENT_KEY_REC *m_pNext;
- BYTE *m_pbReplacementKey;
- ULONG m_cbReplacementKey;
-};
-
-struct SN_REVOCATION_REC {
- SN_REVOCATION_REC *m_pNext;
- BYTE *m_pbRevokedKey;
- ULONG m_cbRevokedKey;
- SN_REPLACEMENT_KEY_REC *m_pReplacementKeys;
-};
-
-SN_REVOCATION_REC *g_pRevocationRecords = NULL;
-
-#endif // FEATURE_STRONGNAME_MIGRATION
-
-#endif // #ifndef DACCESS_COMPILE
-
-
-
-#ifndef DACCESS_COMPILE
-
-// The actions that can be performed upon opening a CSP with LocateCSP.
-#define SN_OPEN_CONTAINER 0
-#define SN_IGNORE_CONTAINER 1
-#define SN_CREATE_CONTAINER 2
-#define SN_DELETE_CONTAINER 3
-#define SN_HASH_SHA1_ONLY 4
-
-// Macro to aid in setting flags for CryptAcquireContext based on container
-// actions above.
-#define SN_CAC_FLAGS(_act) \
- (((_act) == SN_OPEN_CONTAINER ? 0 : \
- ((_act) == SN_HASH_SHA1_ONLY) || ((_act) == SN_IGNORE_CONTAINER) ? CRYPT_VERIFYCONTEXT : \
- (_act) == SN_CREATE_CONTAINER ? CRYPT_NEWKEYSET : \
- (_act) == SN_DELETE_CONTAINER ? CRYPT_DELETEKEYSET : \
- 0) | \
- (g_bUseMachineKeyset ? CRYPT_MACHINE_KEYSET : 0))
-
-// Substitute a strong name error if the error we're wrapping is not transient
-FORCEINLINE HRESULT SubstituteErrorIfNotTransient(HRESULT hrOriginal, HRESULT hrSubstitute)
-{
- return Exception::IsTransient(hrOriginal) ? hrOriginal : hrSubstitute;
-}
-
-// Private routine prototypes.
-SN_THREAD_CTX *GetThreadContext();
-VOID SetStrongNameErrorInfo(DWORD dwStatus);
-HCRYPTPROV LocateCSP(LPCWSTR wszKeyContainer,
- DWORD dwAction,
- ALG_ID uHashAlgId = 0,
- ALG_ID uSignAlgId = 0);
-VOID FreeCSP(HCRYPTPROV hProv);
-HCRYPTPROV LookupCachedCSP(StrongNameCachedCsp cspNumber);
-VOID CacheCSP(HCRYPTPROV hProv, StrongNameCachedCsp cspNumber);
-BOOLEAN IsCachedCSP(HCRYPTPROV hProv);
-HRESULT ReadRegistryConfig();
-BOOLEAN LoadCryptoApis();
-#ifdef FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED
-HRESULT ReadVerificationRecords();
-
-#ifdef FEATURE_STRONGNAME_MIGRATION
-HRESULT ReadRevocationRecords();
-#endif // FEATURE_STRONGNAME_MIGRATION
-SN_VER_REC *GetVerificationRecord(__in_z __deref LPWSTR wszAssemblyName, PublicKeyBlob *pPublicKey);
-#endif // FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED
-
-BOOLEAN IsValidUser(__in_z WCHAR *mszUserList);
-BOOLEAN GetKeyContainerName(LPCWSTR *pwszKeyContainer, BOOLEAN *pbTempContainer);
-VOID FreeKeyContainerName(LPCWSTR wszKeyContainer, BOOLEAN bTempContainer);
-HRESULT GetMetadataImport(__in const SN_LOAD_CTX *pLoadCtx,
- __in mdAssembly *ptkAssembly,
- __out IMDInternalImport **ppMetaDataImport);
-HRESULT FindPublicKey(const SN_LOAD_CTX *pLoadCtx,
- __out_ecount_opt(cchAssemblyName) LPWSTR wszAssemblyName,
- DWORD cchAssemblyName,
- __out PublicKeyBlob **ppPublicKey,
- DWORD *pcbPublicKey = NULL);
-PublicKeyBlob *GetPublicKeyFromHex(LPCWSTR wszPublicKeyHexString);
-BOOLEAN RehashModules(SN_LOAD_CTX *pLoadCtx, LPCWSTR szFilePath);
-HRESULT VerifySignature(SN_LOAD_CTX *pLoadCtx,
- DWORD dwInFlags,
- PublicKeyBlob *pRealEcmaPublicKey,
- DWORD *pdwOutFlags);
-HRESULT InitStrongNameCriticalSection();
-HRESULT InitStrongName();
-typedef BOOLEAN (*HashFunc)(HCRYPTHASH hHash, PBYTE start, DWORD length, DWORD flags, void* cookie);
-BOOLEAN ComputeHash(SN_LOAD_CTX *pLoadCtx, HCRYPTHASH hHash, HashFunc func, void* cookie);
-bool VerifyKeyMatchesAssembly(PublicKeyBlob * pAssemblySignaturePublicKey, __in_z LPCWSTR wszKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, DWORD dwFlags);
-
-#ifdef FEATURE_STRONGNAME_MIGRATION
-HRESULT GetVerifiedSignatureKey(__in SN_LOAD_CTX *pLoadCtx, __out PublicKeyBlob **ppPublicKey, __out DWORD *pcbPublicKey = NULL);
-#endif // FEATURE_STRONGNAME_MIGRATION
-
-#if defined(_DEBUG) && !defined(DACCESS_COMPILE)
-
-void DbgCount(__in_z WCHAR *szCounterName)
-{
-
-#ifndef FEATURE_CORECLR
- if (g_fLoggingInitialized && !(g_dwLoggingFlags & 4))
- return;
-
- DWORD dwError = GetLastError();
-
- if (!g_fLoggingInitialized) {
- g_dwLoggingFlags = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MscorsnLogging);
- g_fLoggingInitialized = TRUE;
- }
-
- if (!(g_dwLoggingFlags & 4)) {
- SetLastError(dwError);
- return;
- }
-
- HKEY hKey = NULL;
- DWORD dwCounter = 0;
- DWORD dwBytes;
-
- if (WszRegCreateKeyEx(HKEY_LOCAL_MACHINE,
- SN_CONFIG_KEY_W W("\\Counters"),
- 0,
- NULL,
- 0,
- KEY_ALL_ACCESS,
- NULL,
- &hKey,
- NULL) != ERROR_SUCCESS)
- goto End;
-
- WszRegQueryValueEx(hKey, szCounterName, NULL, NULL, (BYTE*)&dwCounter, &dwBytes);
- dwCounter++;
- WszRegSetValueEx(hKey, szCounterName, NULL, REG_DWORD, (BYTE*)&dwCounter, sizeof(DWORD));
-
- End:
- if (hKey)
- RegCloseKey(hKey);
- SetLastError(dwError);
-
-#endif //#ifndef FEATURE_CORECLR
-
-}
-
-
-void HexDump(BYTE *pbData,
- DWORD cbData)
-{
- if (g_dwLoggingFlags == 0)
- return;
-
- DWORD dwRow, dwCol;
- WCHAR wszBuffer[1024];
- WCHAR *wszPtr = wszBuffer;
-
-#define SN_PUSH0(_fmt) do { wszPtr += swprintf_s(wszPtr, COUNTOF(wszBuffer) - (wszPtr - wszBuffer), _fmt); } while (false)
-#define SN_PUSH1(_fmt, _arg1) do { wszPtr += swprintf_s(wszPtr, COUNTOF(wszBuffer) - (wszPtr - wszBuffer), _fmt, _arg1); } while (false)
-
- wszBuffer[0] = W('\0');
-
- for (dwRow = 0; dwRow < ((cbData + 15) / 16); dwRow++) {
- SN_PUSH1(W("%08p "), pbData + (16 * dwRow));
- for (dwCol = 0; dwCol < 16; dwCol++)
- if (((dwRow * 16) + dwCol) < cbData)
- SN_PUSH1(W("%02X "), pbData[(dwRow * 16) + dwCol]);
- else
- SN_PUSH0(W(" "));
- for (dwCol = 0; dwCol < 16; dwCol++)
- if (((dwRow * 16) + dwCol) < cbData) {
- unsigned char c = pbData[(dwRow * 16) + dwCol];
- if ((c >= 32) && (c <= 127))
- SN_PUSH1(W("%c"), c);
- else
- SN_PUSH0(W("."));
- } else
- SN_PUSH0(W(" "));
- SN_PUSH0(W("\n"));
- }
-#undef SN_PUSH1
-#undef SN_PUSH0
-
- _ASSERTE(wszPtr < &wszBuffer[COUNTOF(wszBuffer)]);
-
- Log(W("%s"), wszBuffer);
-}
-
-#else // _DEBUG && !DACCESS_COMPILE
-
-#define HexDump(x)
-#define DbgCount(x)
-
-#endif // _DEBUG && !DACCESS_COMPILE
-
-
-BOOLEAN CalculateSize(HCRYPTHASH hHash, PBYTE start, DWORD length, DWORD flags, void* cookie)
-{
- *(size_t*)cookie += length;
- return TRUE;
-}
-
-struct CopyDataBufferDesc
-{
- PBYTE pbData;
- DWORD cbDataSize;
-};
-
-BOOLEAN CopyData(HCRYPTHASH hHash, PBYTE start, DWORD length, DWORD flags, void* cookie)
-{
- _ASSERTE(cookie);
-
- CopyDataBufferDesc *pBuffer = reinterpret_cast<CopyDataBufferDesc *>(cookie);
- _ASSERTE(pBuffer->pbData);
-
- memcpy_s(pBuffer->pbData, pBuffer->cbDataSize, start, length);
- pBuffer->pbData += length;
-
- _ASSERTE(pBuffer->cbDataSize >= length);
- pBuffer->cbDataSize = pBuffer->cbDataSize >= length ? pBuffer->cbDataSize - length : 0;
-
- return TRUE;
-}
-
-BOOLEAN CalcHash(HCRYPTHASH hHash, PBYTE start, DWORD length, DWORD flags, void* cookie)
-{
- return CryptHashData(hHash, start, length, flags);
-}
-
-VOID
-WINAPI Fls_Callback (
- IN PVOID lpFlsData
- )
-{
- STATIC_CONTRACT_SO_TOLERANT;
- SN_THREAD_CTX *pThreadCtx = (SN_THREAD_CTX*)lpFlsData;
- if (pThreadCtx != NULL) {
- for(ULONG i = 0; i < CachedCspCount; i++)
- {
- if (pThreadCtx->m_hProv[i])
- CryptReleaseContext(pThreadCtx->m_hProv[i], 0);
- }
-
- delete pThreadCtx;
- }
-}
-
-HRESULT InitStrongNameCriticalSection()
-{
- if (g_rStrongNameMutex)
- return S_OK;
-
- CRITSEC_COOKIE pv = ClrCreateCriticalSection(CrstStrongName, CRST_DEFAULT);
- if (pv == NULL)
- return E_OUTOFMEMORY;
-
- if (InterlockedCompareExchangeT(&g_rStrongNameMutex, pv, NULL) != NULL)
- ClrDeleteCriticalSection(pv);
- return S_OK;
-}
-
-HRESULT InitStrongName()
-{
- HRESULT hr = S_OK;
- if (g_bStrongNamesInitialized)
- return hr;
-
- // Read CSP configuration info from the registry (if provided).
- hr = ReadRegistryConfig();
- if (FAILED(hr))
- return hr;
-
- // Associate a callback for freeing our TLS data.
- ClrFlsAssociateCallback(TlsIdx_StrongName, Fls_Callback);
-
- g_bStrongNamesInitialized = TRUE;
-
- return hr;
-}
-
-// Generate a new key pair for strong name use.
-SNAPI StrongNameKeyGen(LPCWSTR wszKeyContainer, // [in] desired key container name, must be a non-empty string
- DWORD dwFlags, // [in] flags (see below)
- BYTE **ppbKeyBlob, // [out] public/private key blob
- ULONG *pcbKeyBlob)
-{
- BOOLEAN retVal = FALSE;
- BEGIN_ENTRYPOINT_VOIDRET;
-
- SN_COMMON_PROLOG();
-
- if (wszKeyContainer == NULL && ppbKeyBlob == NULL)
- SN_ERROR(E_INVALIDARG);
- if (ppbKeyBlob != NULL && pcbKeyBlob == NULL)
- SN_ERROR(E_POINTER);
-
- DWORD dwKeySize;
-
- // We set a key size of 1024 if we're using the default
- // signing algorithm (RSA), otherwise we leave it at the default.
- if (g_uSignAlgId == CALG_RSA_SIGN)
- dwKeySize = 1024;
- else
- dwKeySize = 0;
-
- retVal = StrongNameKeyGenEx(wszKeyContainer, dwFlags, dwKeySize, ppbKeyBlob, pcbKeyBlob);
-
-Exit:
- END_ENTRYPOINT_VOIDRET;
- return retVal;
-}
-
-// Generate a new key pair with the specified key size for strong name use.
-SNAPI StrongNameKeyGenEx(LPCWSTR wszKeyContainer, // [in] desired key container name, must be a non-empty string
- DWORD dwFlags, // [in] flags (see below)
- DWORD dwKeySize, // [in] desired key size.
- BYTE **ppbKeyBlob, // [out] public/private key blob
- ULONG *pcbKeyBlob)
-{
- BOOLEAN retVal = FALSE;
-
- BEGIN_ENTRYPOINT_VOIDRET;
-
- HCRYPTPROV hProv = NULL;
- HCRYPTKEY hKey = NULL;
- BOOLEAN bTempContainer = FALSE;
-
- SNLOG((W("StrongNameKeyGenEx(\"%s\", %08X, %08X, %08X, %08X)\n"), wszKeyContainer, dwFlags, dwKeySize, ppbKeyBlob, pcbKeyBlob));
-
- SN_COMMON_PROLOG();
-
- if (wszKeyContainer == NULL && ppbKeyBlob == NULL)
- SN_ERROR(E_INVALIDARG);
- if (ppbKeyBlob != NULL && pcbKeyBlob == NULL)
- SN_ERROR(E_POINTER);
-
- // Check to see if a temporary container name is needed.
- _ASSERTE((wszKeyContainer != NULL) || !(dwFlags & SN_LEAVE_KEY));
- if (!GetKeyContainerName(&wszKeyContainer, &bTempContainer))
- {
- goto Exit;
- }
-
- // Open a CSP and container.
- hProv = LocateCSP(wszKeyContainer, SN_CREATE_CONTAINER);
- if (!hProv)
- goto Error;
-
-
- // Generate the new key pair, try for exportable first.
- // Note: The key size in bits is encoded in the upper
- // 16-bits of a DWORD (and OR'd together with other flags for the
- // CryptGenKey call).
- if (!CryptGenKey(hProv, g_uKeySpec, (dwKeySize << 16) | CRYPT_EXPORTABLE, &hKey)) {
- SNLOG((W("Couldn't create exportable key, trying for non-exportable: %08X\n"), GetLastError()));
- if (!CryptGenKey(hProv, g_uKeySpec, dwKeySize << 16, &hKey)) {
- SNLOG((W("Couldn't create key pair: %08X\n"), GetLastError()));
- goto Error;
- }
- }
-
-#if defined(_DEBUG) && !defined(DACCESS_COMPILE)
- if (g_bHasCSPName) {
- ALG_ID uAlgId;
- DWORD dwAlgIdLen = sizeof(uAlgId);
- // Check that signature algorithm used was the one we expected.
- if (CryptGetKeyParam(hKey, KP_ALGID, (BYTE*)&uAlgId, &dwAlgIdLen, 0)) {
- _ASSERTE(uAlgId == g_uSignAlgId);
- } else
- SNLOG((W("Failed to get key params: %08X\n"), GetLastError()));
- }
-#endif // _DEBUG
-
- // If the user wants the key pair back, attempt to export it.
- if (ppbKeyBlob) {
-
- // Calculate length of blob first;
- if (!CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, NULL, pcbKeyBlob)) {
- SNLOG((W("Couldn't export key pair: %08X\n"), GetLastError()));
- goto Error;
- }
-
- // Allocate a buffer of the right size.
- *ppbKeyBlob = new (nothrow) BYTE[*pcbKeyBlob];
- if (*ppbKeyBlob == NULL) {
- SetLastError(E_OUTOFMEMORY);
- goto Error;
- }
-
- // Export the key pair.
- if (!CryptExportKey(hKey, 0, PRIVATEKEYBLOB, 0, *ppbKeyBlob, pcbKeyBlob)) {
- SNLOG((W("Couldn't export key pair: %08X\n"), GetLastError()));
- delete[] *ppbKeyBlob;
- *ppbKeyBlob = NULL;
- goto Error;
- }
- }
-
- // Destroy the key handle (but not the key pair itself).
- CryptDestroyKey(hKey);
- hKey = NULL;
-
- // Release the CSP.
- FreeCSP(hProv);
-
- // If the user didn't explicitly want to keep the key pair around, delete the
- // key container.
- if (!(dwFlags & SN_LEAVE_KEY) || bTempContainer)
- LocateCSP(wszKeyContainer, SN_DELETE_CONTAINER);
-
- // Free temporary key container name if allocated.
- FreeKeyContainerName(wszKeyContainer, bTempContainer);
- retVal = TRUE;
- goto Exit;
-
- Error:
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- if (hKey)
- CryptDestroyKey(hKey);
- if (hProv) {
- FreeCSP(hProv);
- if (!(dwFlags & SN_LEAVE_KEY) || bTempContainer)
- LocateCSP(wszKeyContainer, SN_DELETE_CONTAINER);
- }
- FreeKeyContainerName(wszKeyContainer, bTempContainer);
-
- Exit:
- END_ENTRYPOINT_VOIDRET;
- return retVal;
-}
-
-
-// Import key pair into a key container.
-SNAPI StrongNameKeyInstall(LPCWSTR wszKeyContainer,// [in] desired key container name, must be a non-empty string
- BYTE *pbKeyBlob, // [in] public/private key pair blob
- ULONG cbKeyBlob)
-{
- BOOLEAN retVal = FALSE;
-
- BEGIN_ENTRYPOINT_VOIDRET;
-
- HCRYPTPROV hProv = NULL;
- HCRYPTKEY hKey = NULL;
-
- SNLOG((W("StrongNameKeyInstall(\"%s\", %08X, %08X)\n"), wszKeyContainer, pbKeyBlob, cbKeyBlob));
-
- SN_COMMON_PROLOG();
-
- if (wszKeyContainer == NULL)
- SN_ERROR(E_POINTER);
- if (pbKeyBlob == NULL)
- SN_ERROR(E_POINTER);
- if (cbKeyBlob == 0)
- SN_ERROR(E_INVALIDARG);
-
- // Open a CSP and container.
- hProv = LocateCSP(wszKeyContainer, SN_CREATE_CONTAINER);
- if (!hProv) {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- goto Exit;
- }
-
- // Import the key pair.
- if (!CryptImportKey(hProv,
- pbKeyBlob,
- cbKeyBlob,
- 0, 0, &hKey)) {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- FreeCSP(hProv);
- goto Exit;
- }
-
- // Release the CSP.
- FreeCSP(hProv);
- retVal = TRUE;
-Exit:
-
- END_ENTRYPOINT_VOIDRET;
- return retVal;
-}
-
-
-// Delete a key pair.
-SNAPI StrongNameKeyDelete(LPCWSTR wszKeyContainer) // [in] desired key container name
-{
- BOOLEAN retVal = FALSE;
-
- BEGIN_ENTRYPOINT_VOIDRET;
-
- HCRYPTPROV hProv;
-
- SNLOG((W("StrongNameKeyDelete(\"%s\")\n"), wszKeyContainer));
-
- SN_COMMON_PROLOG();
-
- if (wszKeyContainer == NULL)
- SN_ERROR(E_POINTER);
-
- // Open and delete the named container.
- hProv = LocateCSP(wszKeyContainer, SN_DELETE_CONTAINER);
- if (hProv) {
- // Returned handle isn't actually valid in the delete case, so we're
- // finished.
- retVal = TRUE;
- } else {
- SetStrongNameErrorInfo(CORSEC_E_CONTAINER_NOT_FOUND);
- retVal = FALSE;
- }
-Exit:
-
- END_ENTRYPOINT_VOIDRET;
- return retVal;
-
-}
-
-// Retrieve the public portion of a key pair.
-SNAPI StrongNameGetPublicKey (LPCWSTR wszKeyContainer, // [in] desired key container name
- BYTE *pbKeyBlob, // [in] public/private key blob (optional)
- ULONG cbKeyBlob,
- BYTE **ppbPublicKeyBlob, // [out] public key blob
- ULONG *pcbPublicKeyBlob)
-{
- LIMITED_METHOD_CONTRACT;
- BOOLEAN retVal = FALSE;
-
- BEGIN_ENTRYPOINT_VOIDRET;
-
- retVal = StrongNameGetPublicKeyEx(
- wszKeyContainer,
- pbKeyBlob,
- cbKeyBlob,
- ppbPublicKeyBlob,
- pcbPublicKeyBlob,
- 0,
- 0);
-
- END_ENTRYPOINT_VOIDRET;
- return retVal;
-}
-
-// Holder for any HCRYPTPROV handles allocated by the strong name APIs
-typedef Wrapper<HCRYPTPROV, DoNothing, FreeCSP, 0> HandleStrongNameCspHolder;
-
-
-SNAPI StrongNameGetPublicKeyEx (LPCWSTR wszKeyContainer, // [in] desired key container name
- BYTE *pbKeyBlob, // [in] public/private key blob (optional)
- ULONG cbKeyBlob,
- BYTE **ppbPublicKeyBlob, // [out] public key blob
- ULONG *pcbPublicKeyBlob,
- ULONG uHashAlgId,
- ULONG uReserved) // reserved for future use as uSigAlgId (signature algorithm id)
-{
- BOOLEAN retVal = FALSE;
-
- BEGIN_ENTRYPOINT_VOIDRET;
-
- HandleStrongNameCspHolder hProv(NULL);
- CapiKeyHolder hKey(NULL);
- DWORD dwKeyLen;
- PublicKeyBlob *pKeyBlob;
- DWORD dwSigAlgIdLen;
-
- SNLOG((W("StrongNameGetPublicKeyEx(\"%s\", %08X, %08X, %08X, %08X, %08X)\n"), wszKeyContainer, pbKeyBlob, cbKeyBlob, ppbPublicKeyBlob, pcbPublicKeyBlob, uHashAlgId));
-
- SN_COMMON_PROLOG();
-
- if (wszKeyContainer == NULL && pbKeyBlob == NULL)
- SN_ERROR(E_INVALIDARG);
- if (pbKeyBlob != NULL && !(StrongNameIsEcmaKey(pbKeyBlob, cbKeyBlob) || StrongNameIsValidKeyPair(pbKeyBlob, cbKeyBlob)))
- SN_ERROR(E_INVALIDARG);
- if (ppbPublicKeyBlob == NULL)
- SN_ERROR(E_POINTER);
- if (pcbPublicKeyBlob == NULL)
- SN_ERROR(E_POINTER);
- if (uReserved != 0)
- SN_ERROR(E_INVALIDARG);
-
- bool fHashAlgorithmValid;
- fHashAlgorithmValid = uHashAlgId == 0 ||
- (GET_ALG_CLASS(uHashAlgId) == ALG_CLASS_HASH && GET_ALG_SID(uHashAlgId) >= ALG_SID_SHA1 && GET_ALG_SID(uHashAlgId) <= ALG_SID_SHA_512);
- if(!fHashAlgorithmValid)
- SN_ERROR(E_INVALIDARG);
-
- if(uHashAlgId == 0)
- uHashAlgId = g_uHashAlgId;
-
- // If we're handed a platform neutral public key, just hand it right back to
- // the user. Well, hand back a copy at least.
- if (pbKeyBlob && cbKeyBlob && SN_IS_NEUTRAL_KEY(pbKeyBlob)) {
- *pcbPublicKeyBlob = sizeof(g_rbNeutralPublicKey);
- *ppbPublicKeyBlob = (BYTE*)g_rbNeutralPublicKey;
- retVal = TRUE;
- goto Exit;
- }
-
- // Open a CSP. Create a key container if a public/private key blob is
- // provided, otherwise we assume a key container already exists.
- if (pbKeyBlob)
- hProv = LocateCSP(NULL, SN_IGNORE_CONTAINER);
- else
- hProv = LocateCSP(wszKeyContainer, SN_OPEN_CONTAINER);
- if (!hProv)
- goto Error;
-
- // If a key blob was provided, import the key pair into the container.
- if (pbKeyBlob) {
- if (!CryptImportKey(hProv,
- pbKeyBlob,
- cbKeyBlob,
- 0, 0, &hKey))
- goto Error;
- } else {
-#if !defined(FEATURE_CORESYSTEM)
- // Else fetch the signature key pair from the container.
- if (!CryptGetUserKey(hProv, g_uKeySpec, &hKey))
- goto Error;
-#else // FEATURE_CORESYSTEM
- SetLastError(E_NOTIMPL);
- goto Error;
-#endif // !FEATURE_CORESYSTEM
- }
-
- // Determine the length of the public key part as a blob.
- if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, NULL, &dwKeyLen))
- goto Error;
-
-
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:22011) // Suppress this PREFast warning which gets triggered by the offset macro expansion.
-#endif
- // And then the length of the PublicKeyBlob structure we return to the
- // caller.
- *pcbPublicKeyBlob = offsetof(PublicKeyBlob, PublicKey) + dwKeyLen;
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
- // Allocate a large enough buffer.
- *ppbPublicKeyBlob = new (nothrow) BYTE[*pcbPublicKeyBlob];
- if (*ppbPublicKeyBlob == NULL) {
- SetLastError(E_OUTOFMEMORY);
- goto Error;
- }
-
- pKeyBlob = (PublicKeyBlob*)*ppbPublicKeyBlob;
-
- // Extract the public part as a blob.
- if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, pKeyBlob->PublicKey, &dwKeyLen)) {
- delete[] *ppbPublicKeyBlob;
- *ppbPublicKeyBlob = NULL;
- goto Error;
- }
-
- // Extract key's signature algorithm and store it in the key blob.
- dwSigAlgIdLen = sizeof(unsigned int);
- ALG_ID SigAlgID;
- if (!CryptGetKeyParam(hKey, KP_ALGID, (BYTE*)&SigAlgID, &dwSigAlgIdLen, 0)) {
- delete[] *ppbPublicKeyBlob;
- *ppbPublicKeyBlob = NULL;
- goto Error;
- }
- SET_UNALIGNED_VAL32(&pKeyBlob->SigAlgID, SigAlgID);
-
- // Fill in the other public key blob fields.
- SET_UNALIGNED_VAL32(&pKeyBlob->HashAlgID, uHashAlgId);
- SET_UNALIGNED_VAL32(&pKeyBlob->cbPublicKey, dwKeyLen);
-
- retVal = TRUE;
- goto Exit;
-
-Error:
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
-Exit:
- END_ENTRYPOINT_VOIDRET;
- return retVal;
-}
-
-// Hash and sign a manifest.
-SNAPI StrongNameSignatureGeneration(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly
- LPCWSTR wszKeyContainer, // [in] desired key container name
- BYTE *pbKeyBlob, // [in] public/private key blob (optional)
- ULONG cbKeyBlob,
- BYTE **ppbSignatureBlob, // [out] signature blob
- ULONG *pcbSignatureBlob)
-{
- BOOL fRetVal = FALSE;
- BEGIN_ENTRYPOINT_VOIDRET;
- fRetVal = StrongNameSignatureGenerationEx(wszFilePath, wszKeyContainer, pbKeyBlob, cbKeyBlob, ppbSignatureBlob, pcbSignatureBlob, 0);
- END_ENTRYPOINT_VOIDRET;
- return fRetVal;
-}
-
-HRESULT FindAssemblySignaturePublicKey(const SN_LOAD_CTX *pLoadCtx,
- __out PublicKeyBlob **ppPublicKey)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- HRESULT hr;
- StrongNameBufferHolder<PublicKeyBlob> result = NULL;
-
- IfFailRet(FindPublicKey(pLoadCtx, NULL, 0, &result));
-
-#ifdef FEATURE_STRONGNAME_MIGRATION
- PublicKeyBlob *pSignaturePublicKey = NULL;
- IfFailRet(GetVerifiedSignatureKey((SN_LOAD_CTX*) pLoadCtx, &pSignaturePublicKey));
-
- if(hr != S_FALSE)
- {
- result = pSignaturePublicKey;
- }
-#endif // FEATURE_STRONGNAME_MIGRATION
-
- *ppPublicKey = result.Extract();
-
- return S_OK;
-}
-
-SNAPI StrongNameSignatureGenerationEx(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly
- LPCWSTR wszKeyContainer, // [in] desired key container name
- BYTE *pbKeyBlob, // [in] public/private key blob (optional)
- ULONG cbKeyBlob,
- BYTE **ppbSignatureBlob, // [out] signature blob
- ULONG *pcbSignatureBlob,
- DWORD dwFlags) // [in] modifer flags
-{
- BOOLEAN retVal = FALSE;
-
- BEGIN_ENTRYPOINT_VOIDRET;
- HandleStrongNameCspHolder hProv(NULL);
- CapiHashHolder hHash(NULL);
- NewArrayHolder<BYTE> pbSig(NULL);
- ULONG cbSig = 0;
- SN_LOAD_CTX sLoadCtx;
- BOOLEAN bImageLoaded = FALSE;
- ALG_ID uHashAlgId;
- StrongNameBufferHolder<PublicKeyBlob> pSignatureKey = NULL;
-
- SNLOG((W("StrongNameSignatureGenerationEx(\"%s\", \"%s\", %08X, %08X, %08X, %08X, %08X)\n"), wszFilePath, wszKeyContainer, pbKeyBlob, cbKeyBlob, ppbSignatureBlob, pcbSignatureBlob, dwFlags));
-
- SN_COMMON_PROLOG();
-
- uHashAlgId = g_uHashAlgId;
-
- if (pbKeyBlob != NULL && !StrongNameIsValidKeyPair(pbKeyBlob, cbKeyBlob))
- SN_ERROR(E_INVALIDARG);
- if (ppbSignatureBlob != NULL && pcbSignatureBlob == NULL)
- SN_ERROR(E_POINTER);
-
- if (wszFilePath != NULL) {
- // Map the assembly into memory.
- sLoadCtx.m_fReadOnly = FALSE;
- if (!LoadAssembly(&sLoadCtx, wszFilePath))
- goto Error;
- bImageLoaded = TRUE;
-
- // If we've asked to recalculate the file hashes of linked modules we have
- // to load the metadata engine and search for file references.
- if (dwFlags & SN_SIGN_ALL_FILES)
- if (!RehashModules(&sLoadCtx, wszFilePath))
- goto Error;
-
- // If no key pair is provided, then we were only called to re-compute the hashes of
- // linked modules in the assembly.
- if (!wszKeyContainer && !pbKeyBlob)
- {
- retVal = TRUE;
- goto Exit;
- }
-
- HRESULT hr;
- if(FAILED(hr = FindAssemblySignaturePublicKey(&sLoadCtx, &pSignatureKey)))
- {
- SN_ERROR(hr);
- }
-
- // Ecma key has an algorithm of zero, so we ignore that case.
- ALG_ID uKeyHashAlgId = GET_UNALIGNED_VAL32(&pSignatureKey->HashAlgID);
- if(uKeyHashAlgId != 0)
- {
- uHashAlgId = uKeyHashAlgId;
- }
- }
-
- if (wszKeyContainer || pbKeyBlob) { // We have a key pair in a container, or in a blob
- // Open a CSP. If a public/private key blob is provided, use CRYPT_VERIFYCONTEXT,
- // otherwise we assume the key container already exists.
- if (pbKeyBlob)
- hProv = LocateCSP(NULL, SN_IGNORE_CONTAINER, uHashAlgId);
- else
- hProv = LocateCSP(wszKeyContainer, SN_OPEN_CONTAINER, uHashAlgId);
-
- if (hProv.GetValue() == NULL)
- goto Error;
-
- // If a key blob was provided, import the key pair into the container.
- // This might be the real key or the test-sign key. In the case of test signing,
- // there's no way to specify hash algorithm, so we use the one from the
- // assembly signature public key (in the metadata table, or the migration attribute).
- if (pbKeyBlob) {
- // The provider holds a reference to the key, so we don't need to
- // keep one around.
- CapiKeyHolder hKey(NULL);
- if (!CryptImportKey(hProv,
- pbKeyBlob,
- cbKeyBlob,
- 0,
- 0,
- &hKey))
- goto Error;
- }
-
- // Create a hash object.
- if (!CryptCreateHash(hProv, uHashAlgId, 0, 0, &hHash))
- goto Error;
-
- // Compute size of the signature blob.
- if (!CryptSignHashW(hHash, g_uKeySpec, NULL, 0, NULL, &cbSig))
- goto Error;
-
- // If the caller only wants the size of the signature, return it now and
- // exit.
- // RSA signature length is independent of the hash size, so hash algorithm
- // doesn't matter here (we don't know the algorithm if the assembly path was passed in as NULL)
- if (wszFilePath == NULL) {
- *pcbSignatureBlob = cbSig;
- retVal = TRUE;
- goto Exit;
- }
- }
-
- // Verify that the public key of the assembly being signed matches the private key we're signing with
- if ((wszKeyContainer != NULL || pbKeyBlob != NULL) && !VerifyKeyMatchesAssembly(pSignatureKey, wszKeyContainer, pbKeyBlob, cbKeyBlob, dwFlags))
- {
- SetLastError(StrongNameErrorInfo());
- goto Error;
- }
-
- // We set a bit in the header to indicate we're fully signing the assembly.
- if (!(dwFlags & SN_TEST_SIGN))
- sLoadCtx.m_pCorHeader->Flags |= VAL32(COMIMAGE_FLAGS_STRONGNAMESIGNED);
- else
- sLoadCtx.m_pCorHeader->Flags &= ~VAL32(COMIMAGE_FLAGS_STRONGNAMESIGNED);
-
- // Destroy the old hash object and create a new one
- // because CryptoAPI says you can't reuse a hash once you've signed it
- // Note that this seems to work with MS-based CSPs but breaks on
- // at least newer nCipher CSPs.
- if (!CryptCreateHash(hProv, uHashAlgId, 0, 0, &hHash))
- goto Error;
-
- // Compute a hash over the image.
- if (!ComputeHash(&sLoadCtx, hHash, CalcHash, NULL))
- goto Error;
-
- // Allocate the blob.
- pbSig = new (nothrow) BYTE[cbSig];
- if (pbSig == NULL) {
- SetLastError(E_OUTOFMEMORY);
- goto Error;
- }
-
- // Compute a signature blob over the hash of the manifest.
- if (!CryptSignHashW(hHash, g_uKeySpec, NULL, 0, pbSig, &cbSig))
- goto Error;
-
- // Check the signature size
- if (sLoadCtx.m_cbSignature != cbSig) {
- SetLastError(CORSEC_E_SIGNATURE_MISMATCH);
- goto Error;
- }
-
- // If the user hasn't asked for the signature to be returned as a pointer, write it to file.
- if (!ppbSignatureBlob)
- {
- memcpy_s(sLoadCtx.m_pbSignature, sLoadCtx.m_cbSignature, pbSig, cbSig);
-
- //
- // Memory-mapped IO in Windows doesn't guarantee that it will update
- // the file's "Modified" timestamp, so we update it ourselves.
- //
- _ASSERTE(sLoadCtx.m_hFile != INVALID_HANDLE_VALUE);
-
- FILETIME ft;
- SYSTEMTIME st;
-
- GetSystemTime(&st);
-
- // We don't care if updating the timestamp fails for any reason.
- if(SystemTimeToFileTime(&st, &ft))
- {
- SetFileTime(sLoadCtx.m_hFile, (LPFILETIME) NULL, (LPFILETIME) NULL, &ft);
- }
- }
-
- // Unmap the image (automatically recalculates and updates the image
- // checksum).
- bImageLoaded = FALSE;
- if (!UnloadAssembly(&sLoadCtx))
- goto Error;
-
- if (ppbSignatureBlob) {
- *ppbSignatureBlob = pbSig.Extract();
- *pcbSignatureBlob = cbSig;
- }
-
- retVal = TRUE;
- goto Exit;
-
-Error:
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
-Exit:
- if (bImageLoaded)
- UnloadAssembly(&sLoadCtx);
- END_ENTRYPOINT_VOIDRET;
- return retVal;
-}
-
-//
-// Generate the digest of a delay signed assembly, which can be signed with StrongNameDigestSign. The digest
-// algorithm is determined from the HashAlgID of the assembly's public key blob.
-//
-// Parameters:
-// wszFilePath - path to the delay signed assembly to generate the digest of
-// ppbDigestBlob - on success this will point to a buffer that contains the digest of the wszFilePath
-// assembly. This buffer should be freed with StrongNameFreeBuffer.
-// pcbDigestBlob - on success this will point to the size of the digest buffer in *ppbDigestBlob
-// dwFlags - flags used to control signing. This is the same set of flags used by
-// StrongNameSignatureGenerationEx
-//
-
-bool StrongNameDigestGenerate_Internal(_In_z_ LPCWSTR wszFilePath,
- _Outptr_result_bytebuffer_(*pcbDigestBlob) BYTE** ppbDigestBlob,
- _Out_ ULONG* pcbDigestBlob,
- DWORD dwFlags)
-{
- // Load up the assembly and find its public key - this tells us which hash algorithm we need to use
- // Note that it cannot be loaded read-only since we need to toggle the fully siged bit in order to
- // calculate the correct hash for the signature.
- StrongNameAssemblyLoadHolder assembly(wszFilePath, false /* read only */);
- if (!assembly.IsLoaded())
- {
- return false;
- }
-
- // If we were asked to do a full rehashing of all modules that needs to be done before calculating the digest
- if ((dwFlags & SN_SIGN_ALL_FILES) == SN_SIGN_ALL_FILES)
- {
- if (!RehashModules(assembly.GetLoadContext(), wszFilePath))
- {
- return false;
- }
- }
-
- // During signature verification, the fully signed bit will be set in the assembly's COR header.
- // Therefore, when calculating the digest of the assembly we must toggle this bit in order to make the
- // digest match what will be calculated during verificaiton. However, we do not want to persist the
- // bit flip on disk, since we're not actually signing the assembly now. We'll save the current COR
- // flags, flip the bit for digesting, and then restore the COR flags before we finish calculating the
- // digest.
- class AssemblyFlagsHolder
- {
- private:
- IMAGE_COR20_HEADER* m_pHeader;
- DWORD m_originalFlags;
-
- public:
- AssemblyFlagsHolder(_In_ IMAGE_COR20_HEADER* pHeader)
- : m_pHeader(pHeader),
- m_originalFlags(pHeader->Flags)
- {
- }
-
- ~AssemblyFlagsHolder()
- {
- m_pHeader->Flags = m_originalFlags;
- }
- } flagsHolder(assembly.GetLoadContext()->m_pCorHeader);
- assembly.GetLoadContext()->m_pCorHeader->Flags |= VAL32(COMIMAGE_FLAGS_STRONGNAMESIGNED);
-
- StrongNameBufferHolder<PublicKeyBlob> pPublicKey;
- HRESULT hrPublicKey = FindAssemblySignaturePublicKey(assembly.GetLoadContext(), &pPublicKey);
- if (FAILED(hrPublicKey))
- {
- SetStrongNameErrorInfo(hrPublicKey);
- return false;
- }
-
- // Generate the digest of the assembly
- HandleStrongNameCspHolder hProv(LocateCSP(nullptr, SN_IGNORE_CONTAINER, pPublicKey->HashAlgID));
- if (!hProv)
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
-
- CapiHashHolder hHash;
- if (!CryptCreateHash(hProv, pPublicKey->HashAlgID, NULL, 0, &hHash))
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
-
- if (!ComputeHash(assembly.GetLoadContext(), hHash, CalcHash, nullptr))
- {
- return false;
- }
-
- // Figure out how big the resulting digest is so that we can pass it back out
- DWORD hashSize = 0;
- DWORD dwordSize = sizeof(hashSize);
- if (!CryptGetHashParam(hHash, HP_HASHSIZE, reinterpret_cast<BYTE*>(&hashSize), &dwordSize, 0))
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
-
- StrongNameBufferHolder<BYTE> pbHash(new (nothrow)BYTE[hashSize]);
- if (!pbHash)
- {
- SetStrongNameErrorInfo(E_OUTOFMEMORY);
- return false;
- }
-
- if (!CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &hashSize, 0))
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
-
- *ppbDigestBlob = pbHash.Extract();
- *pcbDigestBlob = hashSize;
- return true;
-}
-
-SNAPI StrongNameDigestGenerate(_In_z_ LPCWSTR wszFilePath,
- _Outptr_result_bytebuffer_(*pcbDigestBlob) BYTE** ppbDigestBlob,
- _Out_ ULONG* pcbDigestBlob,
- DWORD dwFlags)
-{
- BOOLEAN retVal = FALSE;
- BEGIN_ENTRYPOINT_VOIDRET;
-
- SNLOG((W("StrongNameDigestGenerate(\"%s\", %08X, %08X, %04X)\n"), wszFilePath, ppbDigestBlob, pcbDigestBlob, dwFlags));
-
- SN_COMMON_PROLOG();
- if (wszFilePath == nullptr)
- SN_ERROR(E_POINTER);
- if (ppbDigestBlob == nullptr)
- SN_ERROR(E_POINTER);
- if (pcbDigestBlob == nullptr)
- SN_ERROR(E_POINTER);
-
- retVal = StrongNameDigestGenerate_Internal(wszFilePath, ppbDigestBlob, pcbDigestBlob, dwFlags);
-
- END_ENTRYPOINT_VOIDRET;
-
-Exit:
- return retVal;
-}
-
-//
-// Sign an the digest of an assembly calculated by StrongNameDigestGenerate
-//
-// Parameters:
-// wszKeyContainer - name of the key container that holds the key pair used to generate the signature. If
-// both a key container and key blob are specified, the key container name is ignored.
-// pbKeyBlob - raw key pair to be used to generate the signature. If both a key pair and a key
-// container are given, the key blob will be used.
-// cbKeyBlob - size of the key pair in pbKeyBlob
-// pbDigestBlob - digest of the assembly, calculated by StrongNameDigestGenerate
-// cbDigestBlob - size of the digest blob
-// hashAlgId - algorithm ID of the hash algorithm used to generate the digest blob
-// ppbSignatureBlob - on success this will point to a buffer that contains a signature over the blob. This
-// buffer should be freed with StrongNameFreeBuffer.
-// pcbSignatureBlob - on success this will point to the size of the signature blob in *ppbSignatureBlob
-// dwFlags - flags used to control signing. This is the same set of flags used by
-// StrongNameSignatureGenerationEx
-//
-
-bool StrongNameDigestSign_Internal(_In_opt_z_ LPCWSTR wszKeyContainer,
- _In_reads_bytes_opt_(cbKeyBlob) BYTE* pbKeyBlob,
- ULONG cbKeyBlob,
- _In_reads_bytes_(cbDigestBlob) BYTE* pbDigestBlob,
- ULONG cbDigestBlob,
- DWORD hashAlgId,
- _Outptr_result_bytebuffer_(*pcbSignatureBlob) BYTE** ppbSignatureBlob,
- _Out_ ULONG* pcbSignatureBlob,
- DWORD dwFlags)
-{
- //
- // Get the key we'll be signing with loaded into CAPI
- //
-
- HandleStrongNameCspHolder hProv;
- CapiKeyHolder hKey;
- if (pbKeyBlob != nullptr)
- {
- hProv = LocateCSP(nullptr, SN_IGNORE_CONTAINER, hashAlgId);
-
- if (hProv != NULL)
- {
- if (!CryptImportKey(hProv, pbKeyBlob, cbKeyBlob, 0, 0, &hKey))
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
- }
- }
- else
- {
- hProv = LocateCSP(wszKeyContainer, SN_OPEN_CONTAINER, hashAlgId);
- }
-
- if (!hProv)
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
-
- //
- // Get the pre-calculated digest loaded into a CAPI Hash object
- //
-
- CapiHashHolder hHash;
- if (!CryptCreateHash(hProv, hashAlgId, 0, 0, &hHash))
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
-
- DWORD hashSize = 0;
- DWORD cbHashSize = sizeof(hashSize);
- if (!CryptGetHashParam(hHash, HP_HASHSIZE, reinterpret_cast<BYTE*>(&hashSize), &cbHashSize, 0))
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
-
- if (hashSize != cbDigestBlob)
- {
- SetStrongNameErrorInfo(NTE_BAD_HASH);
- return false;
- }
-
- if (!CryptSetHashParam(hHash, HP_HASHVAL, pbDigestBlob, 0))
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
-
- //
- // Sign the hash
- //
-
- DWORD cbSignature = 0;
- if (!CryptSignHashW(hHash, g_uKeySpec, nullptr, 0, nullptr, &cbSignature))
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
-
- // CAPI has a quirk where some CSPs do not allow you to sign a hash object once you've asked for the size
- // of the signature. To work in those cases, we must create a new hash object to sign.
- if (!CryptCreateHash(hProv, hashAlgId, 0, 0, &hHash))
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
-
- if (!CryptGetHashParam(hHash, HP_HASHSIZE, reinterpret_cast<BYTE*>(&hashSize), &cbHashSize, 0))
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
-
- if (hashSize != cbDigestBlob)
- {
- SetStrongNameErrorInfo(NTE_BAD_HASH);
- return false;
- }
-
- if (!CryptSetHashParam(hHash, HP_HASHVAL, pbDigestBlob, 0))
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
-
- // Now that we've got a fresh hash object to sign, we can compute the final signature
- StrongNameBufferHolder<BYTE> pbSignature(new (nothrow)BYTE[cbSignature]);
- if (pbSignature == nullptr)
- {
- SetStrongNameErrorInfo(E_OUTOFMEMORY);
- return false;
- }
-
- if (!CryptSignHashW(hHash, g_uKeySpec, nullptr, 0, pbSignature, &cbSignature))
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
-
- *ppbSignatureBlob = pbSignature.Extract();
- *pcbSignatureBlob = cbSignature;
- return true;
-}
-
-SNAPI StrongNameDigestSign(_In_opt_z_ LPCWSTR wszKeyContainer,
- _In_reads_bytes_opt_(cbKeyBlob) BYTE* pbKeyBlob,
- ULONG cbKeyBlob,
- _In_reads_bytes_(cbDigestBlob) BYTE* pbDigestBlob,
- ULONG cbDigestBlob,
- DWORD hashAlgId,
- _Outptr_result_bytebuffer_(*pcbSignatureBlob) BYTE** ppbSignatureBlob,
- _Out_ ULONG* pcbSignatureBlob,
- DWORD dwFlags)
-{
- BOOLEAN retVal = FALSE;
-
- BEGIN_ENTRYPOINT_VOIDRET;
- SNLOG((W("StrongNameDigestSign(\"%s\", %08X, %04X, %08X, %04X, %04X, %08X, %08X, %04X)\n"), wszKeyContainer, pbKeyBlob, cbKeyBlob, pbDigestBlob, cbDigestBlob, hashAlgId, ppbSignatureBlob, pcbSignatureBlob, dwFlags));
- SN_COMMON_PROLOG();
-
- if (wszKeyContainer == nullptr && pbKeyBlob == nullptr)
- SN_ERROR(E_POINTER);
- if (pbKeyBlob != nullptr && !StrongNameIsValidKeyPair(pbKeyBlob, cbKeyBlob))
- SN_ERROR(E_INVALIDARG);
- if (pbDigestBlob == nullptr)
- SN_ERROR(E_POINTER);
- if (ppbSignatureBlob == nullptr)
- SN_ERROR(E_POINTER);
- if (pcbSignatureBlob == nullptr)
- SN_ERROR(E_POINTER);
-
- *ppbSignatureBlob = nullptr;
- *pcbSignatureBlob = 0;
-
- retVal = StrongNameDigestSign_Internal(wszKeyContainer, pbKeyBlob, cbKeyBlob, pbDigestBlob, cbDigestBlob, hashAlgId, ppbSignatureBlob, pcbSignatureBlob, dwFlags);
-
- END_ENTRYPOINT_VOIDRET;
-Exit:
- return retVal;
-}
-
-//
-// Embed a digest signature generated with StrongNameDigestSign into a delay signed assembly, completing
-// the signing process for that assembly.
-//
-// Parameters:
-// wszFilePath - path to the assembly to sign
-// pbSignatureBlob - signature blob to embed in the assembly
-// cbSignatureBlob - size of the signature blob
-//
-
-bool StrongNameDigestEmbed_Internal(_In_z_ LPCWSTR wszFilePath,
- _In_reads_bytes_(cbSignatureBlob) BYTE* pbSignatureBlob,
- ULONG cbSignatureBlob)
-{
- StrongNameAssemblyLoadHolder assembly(wszFilePath, false);
- if (!assembly.IsLoaded())
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
-
- memcpy_s(assembly.GetLoadContext()->m_pbSignature, assembly.GetLoadContext()->m_cbSignature, pbSignatureBlob, cbSignatureBlob);
- assembly.GetLoadContext()->m_pCorHeader->Flags |= VAL32(COMIMAGE_FLAGS_STRONGNAMESIGNED);
-
- FILETIME ft = { 0 };
- SYSTEMTIME st = { 0 };
- GetSystemTime(&st);
- if (SystemTimeToFileTime(&st, &ft))
- {
- SetFileTime(assembly.GetLoadContext()->m_hFile, nullptr, nullptr, &ft);
- }
-
- return true;
-}
-
-SNAPI StrongNameDigestEmbed(_In_z_ LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly to update
- _In_reads_bytes_(cbSignatureBlob) BYTE* pbSignatureBlob, // [in] signatuer blob for the assembly
- ULONG cbSignatureBlob)
-{
- BOOLEAN retVal = FALSE;
-
- BEGIN_ENTRYPOINT_VOIDRET;
- SNLOG((W("StrongNameDigestEmbed(\"%s\", %08X, %04X)\n"), wszFilePath, pbSignatureBlob, cbSignatureBlob));
- SN_COMMON_PROLOG();
-
- if (wszFilePath == nullptr)
- SN_ERROR(E_POINTER);
- if (pbSignatureBlob == nullptr)
- SN_ERROR(E_POINTER);
-
- retVal = StrongNameDigestEmbed_Internal(wszFilePath, pbSignatureBlob, cbSignatureBlob);
-
- END_ENTRYPOINT_VOIDRET;
-Exit:
- return retVal;
-}
-
-// Create a strong name token from an assembly file.
-SNAPI StrongNameTokenFromAssembly(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly
- BYTE **ppbStrongNameToken, // [out] strong name token
- ULONG *pcbStrongNameToken)
-{
- BOOL fRetValue = FALSE;
- BEGIN_ENTRYPOINT_VOIDRET;
- fRetValue = StrongNameTokenFromAssemblyEx(wszFilePath,
- ppbStrongNameToken,
- pcbStrongNameToken,
- NULL,
- NULL);
- END_ENTRYPOINT_VOIDRET;
- return fRetValue;
-}
-
-// Create a strong name token from an assembly file and additionally return the full public key.
-SNAPI StrongNameTokenFromAssemblyEx(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly
- BYTE **ppbStrongNameToken, // [out] strong name token
- ULONG *pcbStrongNameToken,
- BYTE **ppbPublicKeyBlob, // [out] public key blob
- ULONG *pcbPublicKeyBlob)
-{
- BOOLEAN retVal = FALSE;
-
- BEGIN_ENTRYPOINT_VOIDRET;
- SN_LOAD_CTX sLoadCtx;
- BOOLEAN fMapped = FALSE;
- BOOLEAN fSetErrorInfo = TRUE;
- PublicKeyBlob *pPublicKey = NULL;
- HRESULT hrKey = S_OK;
-
- SNLOG((W("StrongNameTokenFromAssemblyEx(\"%s\", %08X, %08X, %08X, %08X)\n"), wszFilePath, ppbStrongNameToken, pcbStrongNameToken, ppbPublicKeyBlob, pcbPublicKeyBlob));
-
- SN_COMMON_PROLOG();
-
- if (wszFilePath == NULL)
- SN_ERROR(E_POINTER);
- if (ppbStrongNameToken == NULL)
- SN_ERROR(E_POINTER);
- if (pcbStrongNameToken == NULL)
- SN_ERROR(E_POINTER);
-
- // Map the assembly into memory.
- sLoadCtx.m_fReadOnly = TRUE;
- if (!LoadAssembly(&sLoadCtx, wszFilePath))
- goto Error;
- fMapped = TRUE;
-
- // Read the public key used to sign the assembly from the assembly metadata.
- hrKey = FindPublicKey(&sLoadCtx, NULL, 0, &pPublicKey);
- if (FAILED(hrKey))
- {
- SetStrongNameErrorInfo(hrKey);
- fSetErrorInfo = FALSE;
- goto Error;
- }
-
- // Unload the assembly.
- fMapped = FALSE;
- if (!UnloadAssembly(&sLoadCtx))
- goto Error;
-
- // Now we have a public key blob, we can call our more direct API to do the
- // actual work.
- if (!StrongNameTokenFromPublicKey((BYTE*)pPublicKey,
- SN_SIZEOF_KEY(pPublicKey),
- ppbStrongNameToken,
- pcbStrongNameToken)) {
- fSetErrorInfo = FALSE;
- goto Error;
- }
-
- if (pcbPublicKeyBlob)
- *pcbPublicKeyBlob = SN_SIZEOF_KEY(pPublicKey);
-
- // Return public key information.
- if (ppbPublicKeyBlob)
- *ppbPublicKeyBlob = (BYTE*)pPublicKey;
- else
- delete [] (BYTE*)pPublicKey;
-
- retVal = TRUE;
- goto Exit;
-
- Error:
- if (fSetErrorInfo)
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- if (pPublicKey)
- delete [] (BYTE*)pPublicKey;
- if (fMapped)
- UnloadAssembly(&sLoadCtx);
-
-Exit:
- END_ENTRYPOINT_VOIDRET;
-
- return retVal;
-}
-
-bool StrongNameSignatureVerificationEx2_Internal(LPCWSTR wszFilePath,
- BOOLEAN fForceVerification,
- BYTE *pbEcmaPublicKey,
- DWORD cbEcmaPublicKey,
- BOOLEAN *pfWasVerified)
-{
- StrongNameAssemblyLoadHolder assembly(wszFilePath, true);
- if (!assembly.IsLoaded())
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- return false;
- }
- else
- {
- DWORD dwOutFlags = 0;
- HRESULT hrVerify = VerifySignature(assembly.GetLoadContext(),
- SN_INFLAG_INSTALL | SN_INFLAG_ALL_ACCESS | (fForceVerification ? SN_INFLAG_FORCE_VER : 0),
- reinterpret_cast<PublicKeyBlob *>(pbEcmaPublicKey),
- &dwOutFlags);
- if (FAILED(hrVerify))
- {
- SetStrongNameErrorInfo(hrVerify);
- return false;
- }
-
- if (pfWasVerified)
- {
- *pfWasVerified = (dwOutFlags & SN_OUTFLAG_WAS_VERIFIED) != 0;
- }
-
- return true;
- }
-}
-
-//
-// Verify the signature of a strongly named assembly, providing a mapping from the ECMA key to a real key
-//
-// Arguments:
-// wszFilePath - valid path to the PE file for the assembly
-// fForceVerification - verify even if settings in the registry disable it
-// pbEcmaPublicKey - mapping from the ECMA public key to the real key used for verification
-// cbEcmaPublicKey - length of the real ECMA public key
-// fWasVerified - [out] set to false if verify succeeded due to registry settings
-//
-// Return Value:
-// TRUE if the signature was successfully verified, FALSE otherwise
-//
-
-SNAPI StrongNameSignatureVerificationEx2(LPCWSTR wszFilePath,
- BOOLEAN fForceVerification,
- BYTE *pbEcmaPublicKey,
- DWORD cbEcmaPublicKey,
- BOOLEAN *pfWasVerified)
-{
- BOOLEAN retVal = FALSE;
- BEGIN_ENTRYPOINT_VOIDRET;
-
- SNLOG((W("StrongNameSignatureVerificationEx2(\"%s\", %d, %08X, %08X, %08X)\n"), wszFilePath, fForceVerification, pbEcmaPublicKey, cbEcmaPublicKey, pfWasVerified));
-
- SN_COMMON_PROLOG();
-
- if (wszFilePath == NULL)
- SN_ERROR(E_POINTER);
- if (pbEcmaPublicKey == NULL)
- SN_ERROR(E_POINTER);
- if (!StrongNameIsValidPublicKey(pbEcmaPublicKey, cbEcmaPublicKey, false))
- SN_ERROR(CORSEC_E_INVALID_PUBLICKEY);
-
- retVal = StrongNameSignatureVerificationEx2_Internal(wszFilePath, fForceVerification, pbEcmaPublicKey, cbEcmaPublicKey, pfWasVerified);
-
-Exit:
- END_ENTRYPOINT_VOIDRET;
- return retVal;
-}
-
-// Verify a strong name/manifest against a public key blob.
-SNAPI StrongNameSignatureVerificationEx(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly
- BOOLEAN fForceVerification, // [in] verify even if settings in the registry disable it
- BOOLEAN *pfWasVerified) // [out] set to false if verify succeeded due to registry settings
-{
- BOOLEAN fRet = FALSE;
- BEGIN_ENTRYPOINT_VOIDRET;
-
- fRet = StrongNameSignatureVerificationEx2(wszFilePath,
- fForceVerification,
- const_cast<BYTE *>(g_rbTheKey),
- COUNTOF(g_rbTheKey),
- pfWasVerified);
-
- END_ENTRYPOINT_VOIDRET;
- return fRet;
-}
-
-
-// Verify a strong name/manifest against a public key blob.
-SNAPI StrongNameSignatureVerification(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly
- DWORD dwInFlags, // [in] flags modifying behaviour
- DWORD *pdwOutFlags) // [out] additional output info
-{
- BOOLEAN retVal = TRUE;
-
- BEGIN_ENTRYPOINT_VOIDRET;
-
- SN_LOAD_CTX sLoadCtx;
- BOOLEAN fMapped = FALSE;
-
- SNLOG((W("StrongNameSignatureVerification(\"%s\", %08X, %08X, %08X)\n"), wszFilePath, dwInFlags, pdwOutFlags));
-
- SN_COMMON_PROLOG();
-
- if (wszFilePath == NULL)
- SN_ERROR(E_POINTER);
-
- // Map the assembly into memory.
- sLoadCtx.m_fReadOnly = TRUE;
- if (LoadAssembly(&sLoadCtx, wszFilePath))
- {
- fMapped = TRUE;
- }
- else
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- retVal = FALSE;
- }
-
- // Go to common code to process the verification.
- if (fMapped)
- {
- HRESULT hrVerify = VerifySignature(&sLoadCtx, dwInFlags, reinterpret_cast<PublicKeyBlob *>(const_cast<BYTE *>(g_rbTheKey)), pdwOutFlags);
- if (FAILED(hrVerify))
- {
- SetStrongNameErrorInfo(hrVerify);
- retVal = FALSE;
- }
-
- // Unmap the image. Only set error information if VerifySignature succeeded, since we do not want to
- // overwrite its error information with the error code from UnloadAssembly.
- if (!UnloadAssembly(&sLoadCtx))
- {
- if (retVal)
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- retVal = FALSE;
- }
- }
-
- // SN_COMMON_PROLOG requires an Exit location
-Exit:
- END_ENTRYPOINT_VOIDRET;
- return retVal;
-}
-
-
-// Verify a strong name/manifest against a public key blob when the assembly is
-// already memory mapped.
-SNAPI StrongNameSignatureVerificationFromImage(BYTE *pbBase, // [in] base address of mapped manifest file
- DWORD dwLength, // [in] length of mapped image in bytes
- DWORD dwInFlags, // [in] flags modifying behaviour
- DWORD *pdwOutFlags) // [out] additional output info
-{
- BOOLEAN retVal = TRUE;
-
- BEGIN_ENTRYPOINT_VOIDRET
-
- SN_LOAD_CTX sLoadCtx;
- BOOLEAN fMapped = FALSE;
-
- SNLOG((W("StrongNameSignatureVerificationFromImage(%08X, %08X, %08X, %08X)\n"), pbBase, dwLength, dwInFlags, pdwOutFlags));
-
- SN_COMMON_PROLOG();
-
- if (pbBase == NULL)
- SN_ERROR(E_POINTER);
-
- // We don't need to map the image, it's already in memory. But we do need to
- // set up a load context for some of the following routines. LoadAssembly
- // copes with this case for us.
- sLoadCtx.m_pbBase = pbBase;
- sLoadCtx.m_dwLength = dwLength;
- sLoadCtx.m_fReadOnly = TRUE;
- if (LoadAssembly(&sLoadCtx, NULL, dwInFlags))
- {
- fMapped = TRUE;
- }
- else
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- retVal = FALSE;
- }
-
- if (fMapped)
- {
- // Go to common code to process the verification.
- HRESULT hrVerify = VerifySignature(&sLoadCtx, dwInFlags, reinterpret_cast<PublicKeyBlob *>(const_cast<BYTE *>(g_rbTheKey)), pdwOutFlags);
- if (FAILED(hrVerify))
- {
- SetStrongNameErrorInfo(hrVerify);
- retVal = FALSE;
- }
-
- // Unmap the image.
- if (!UnloadAssembly(&sLoadCtx))
- {
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- retVal = FALSE;
- }
- }
-
- // SN_COMMON_PROLOG requires an Exit location
-Exit:
- END_ENTRYPOINT_VOIDRET;
- return retVal;
-}
-
-// Find portions of an assembly to hash.
-BOOLEAN CollectBlob(SN_LOAD_CTX *pLoadCtx, PBYTE pbBlob, DWORD* pcbBlob)
-{
- // Calculate the required size
- DWORD cbRequired = 0;
- BOOLEAN bRetval = ComputeHash(pLoadCtx, (HCRYPTHASH)INVALID_HANDLE_VALUE, CalculateSize, &cbRequired);
- if (!bRetval)
- return FALSE;
- if (*pcbBlob < cbRequired) {
- *pcbBlob = cbRequired;
- SetLastError( E_INVALIDARG );
- return FALSE;
- }
-
- CopyDataBufferDesc buffer = { pbBlob, *pcbBlob };
- if (!ComputeHash(pLoadCtx, (HCRYPTHASH)INVALID_HANDLE_VALUE, CopyData, &buffer))
- return FALSE;
-
- *pcbBlob = cbRequired;
- return TRUE;
-}
-
-// ensure that the symbol will be exported properly
-extern "C" SNAPI StrongNameGetBlob(LPCWSTR wszFilePath,
- PBYTE pbBlob,
- DWORD *cbBlob);
-
-SNAPI StrongNameGetBlob(LPCWSTR wszFilePath, // [in] valid path to the PE file for the assembly
- PBYTE pbBlob, // [in] buffer to fill with blob
- DWORD *cbBlob) // [in/out] size of buffer/number of bytes put into buffer
-{
- BOOLEAN retVal = FALSE;
-
- BEGIN_ENTRYPOINT_VOIDRET;
-
- SN_LOAD_CTX sLoadCtx;
- BOOLEAN fMapped = FALSE;
-
- SNLOG((W("StrongNameGetBlob(\"%s\", %08X, %08X)\n"), wszFilePath, pbBlob, cbBlob));
-
- SN_COMMON_PROLOG();
-
- if (wszFilePath == NULL)
- SN_ERROR(E_POINTER);
- if (pbBlob == NULL)
- SN_ERROR(E_POINTER);
- if (cbBlob == NULL)
- SN_ERROR(E_POINTER);
-
- // Map the assembly into memory.
- sLoadCtx.m_fReadOnly = TRUE;
- if (!LoadAssembly(&sLoadCtx, wszFilePath, 0, FALSE))
- goto Error;
- fMapped = TRUE;
-
- if (!CollectBlob(&sLoadCtx, pbBlob, cbBlob))
- goto Error;
-
- // Unmap the image.
- fMapped = FALSE;
- if (!UnloadAssembly(&sLoadCtx))
- goto Error;
-
- retVal = TRUE;
- goto Exit;
-
- Error:
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- if (fMapped)
- UnloadAssembly(&sLoadCtx);
-Exit:
- END_ENTRYPOINT_VOIDRET;
- return retVal;
-}
-
-// ensure that the symbol will be exported properly
-extern "C" SNAPI StrongNameGetBlobFromImage(BYTE *pbBase,
- DWORD dwLength,
- PBYTE pbBlob,
- DWORD *cbBlob);
-
-SNAPI StrongNameGetBlobFromImage(BYTE *pbBase, // [in] base address of mapped manifest file
- DWORD dwLength, // [in] length of mapped image in bytes
- PBYTE pbBlob, // [in] buffer to fill with blob
- DWORD *cbBlob) // [in/out] size of buffer/number of bytes put into buffer
-{
- BOOLEAN retVal = FALSE;
-
- BEGIN_ENTRYPOINT_VOIDRET;
-
- SN_LOAD_CTX sLoadCtx;
- BOOLEAN fMapped = FALSE;
-
-
- SNLOG((W("StrongNameGetBlobFromImage(%08X, %08X, %08X, %08X)\n"), pbBase, dwLength, pbBlob, cbBlob));
-
- SN_COMMON_PROLOG();
-
- if (pbBase == NULL)
- SN_ERROR(E_POINTER);
- if (pbBlob == NULL)
- SN_ERROR(E_POINTER);
- if (cbBlob == NULL)
- SN_ERROR(E_POINTER);
-
- // We don't need to map the image, it's already in memory. But we do need to
- // set up a load context for some of the following routines. LoadAssembly
- // copes with this case for us.
- sLoadCtx.m_pbBase = pbBase;
- sLoadCtx.m_dwLength = dwLength;
- sLoadCtx.m_fReadOnly = TRUE;
- if (!LoadAssembly(&sLoadCtx, NULL, 0, FALSE))
- goto Error;
- fMapped = TRUE;
-
- // Go to common code to process the verification.
- if (!CollectBlob(&sLoadCtx, pbBlob, cbBlob))
- goto Error;
-
- // Unmap the image.
- fMapped = FALSE;
- if (!UnloadAssembly(&sLoadCtx))
- goto Error;
-
- retVal = TRUE;
- goto Exit;
-
- Error:
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- if (fMapped)
- UnloadAssembly(&sLoadCtx);
-
-Exit:
- END_ENTRYPOINT_VOIDRET;
-
- return retVal;
-}
-
-
-// Verify that two assemblies differ only by signature blob.
-SNAPI StrongNameCompareAssemblies(LPCWSTR wszAssembly1, // [in] file name of first assembly
- LPCWSTR wszAssembly2, // [in] file name of second assembly
- DWORD *pdwResult) // [out] result of comparison
-{
- BOOLEAN retVal = FALSE;
-
- BEGIN_ENTRYPOINT_VOIDRET;
-
-
- SN_LOAD_CTX sLoadCtx1;
- SN_LOAD_CTX sLoadCtx2;
- size_t dwSkipOffsets[3];
- size_t dwSkipLengths[3];
- BOOLEAN bMappedAssem1 = FALSE;
- BOOLEAN bMappedAssem2 = FALSE;
- BOOLEAN bIdentical;
- BOOLEAN bSkipping;
- DWORD i, j;
-
-
-
- SNLOG((W("StrongNameCompareAssemblies(\"%s\", \"%s\", %08X)\n"), wszAssembly1, wszAssembly2, pdwResult));
-
- SN_COMMON_PROLOG();
-
- if (wszAssembly1 == NULL)
- SN_ERROR(E_POINTER);
- if (wszAssembly2 == NULL)
- SN_ERROR(E_POINTER);
- if (pdwResult == NULL)
- SN_ERROR(E_POINTER);
-
- // Map each assembly.
- sLoadCtx1.m_fReadOnly = TRUE;
- if (!LoadAssembly(&sLoadCtx1, wszAssembly1))
- goto Error;
- bMappedAssem1 = TRUE;
-
- sLoadCtx2.m_fReadOnly = TRUE;
- if (!LoadAssembly(&sLoadCtx2, wszAssembly2))
- goto Error;
- bMappedAssem2 = TRUE;
-
- // If the files aren't even the same length then they must be different.
- if (sLoadCtx1.m_dwLength != sLoadCtx2.m_dwLength)
- goto ImagesDiffer;
-
- // Check that the signatures are located at the same offset and are the same
- // length in each assembly.
- if (sLoadCtx1.m_pCorHeader->StrongNameSignature.VirtualAddress !=
- sLoadCtx2.m_pCorHeader->StrongNameSignature.VirtualAddress)
- goto ImagesDiffer;
- if (sLoadCtx1.m_pCorHeader->StrongNameSignature.Size !=
- sLoadCtx2.m_pCorHeader->StrongNameSignature.Size)
- goto ImagesDiffer;
-
- // Set up list of image ranges to skip in the upcoming comparison.
- // First there's the signature blob.
- dwSkipOffsets[0] = sLoadCtx1.m_pbSignature - sLoadCtx1.m_pbBase;
- dwSkipLengths[0] = sLoadCtx1.m_cbSignature;
-
- // Then there's the checksum.
- if (sLoadCtx1.m_pNtHeaders->OptionalHeader.Magic != sLoadCtx2.m_pNtHeaders->OptionalHeader.Magic)
- goto ImagesDiffer;
- if (sLoadCtx1.m_pNtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC))
- dwSkipOffsets[1] = (BYTE*)&((IMAGE_NT_HEADERS32*)sLoadCtx1.m_pNtHeaders)->OptionalHeader.CheckSum - sLoadCtx1.m_pbBase;
- else if (sLoadCtx1.m_pNtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR64_MAGIC))
- dwSkipOffsets[1] = (BYTE*)&((IMAGE_NT_HEADERS64*)sLoadCtx1.m_pNtHeaders)->OptionalHeader.CheckSum - sLoadCtx1.m_pbBase;
- else {
- SetLastError(CORSEC_E_INVALID_IMAGE_FORMAT);
- goto Error;
- }
- dwSkipLengths[1] = sizeof(DWORD);
-
- // Skip the COM+ 2.0 PE header extension flags field. It's updated by the
- // signing operation.
- dwSkipOffsets[2] = (BYTE*)&sLoadCtx1.m_pCorHeader->Flags - sLoadCtx1.m_pbBase;
- dwSkipLengths[2] = sizeof(DWORD);
-
- // Compare the two mapped images, skipping the ranges we defined above.
- bIdentical = TRUE;
- for (i = 0; i < sLoadCtx1.m_dwLength; i++) {
-
- // Determine if we're skipping the check on the current byte.
- bSkipping = FALSE;
- for (j = 0; j < (sizeof(dwSkipOffsets) / sizeof(dwSkipOffsets[0])); j++)
- if ((i >= dwSkipOffsets[j]) && (i < (dwSkipOffsets[j] + dwSkipLengths[j]))) {
- bSkipping = TRUE;
- break;
- }
-
- // Perform comparisons as desired.
- if (sLoadCtx1.m_pbBase[i] != sLoadCtx2.m_pbBase[i])
- if (bSkipping)
- bIdentical = FALSE;
- else
- goto ImagesDiffer;
- }
-
- // The assemblies are the same.
- *pdwResult = bIdentical ? SN_CMP_IDENTICAL : SN_CMP_SIGONLY;
-
- UnloadAssembly(&sLoadCtx1);
- UnloadAssembly(&sLoadCtx2);
-
- retVal = TRUE;
- goto Exit;
-
- Error:
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- if (bMappedAssem1)
- UnloadAssembly(&sLoadCtx1);
- if (bMappedAssem2)
- UnloadAssembly(&sLoadCtx2);
- goto Exit;
-
- ImagesDiffer:
- if (bMappedAssem1)
- UnloadAssembly(&sLoadCtx1);
- if (bMappedAssem2)
- UnloadAssembly(&sLoadCtx2);
- *pdwResult = SN_CMP_DIFFERENT;
- retVal = TRUE;
-
-Exit:
- END_ENTRYPOINT_VOIDRET;
-
- return retVal;
-}
-
-
-// Compute the size of buffer needed to hold a hash for a given hash algorithm.
-SNAPI StrongNameHashSize(ULONG ulHashAlg, // [in] hash algorithm
- DWORD *pcbSize) // [out] size of the hash in bytes
-{
- BOOLEAN retVal = FALSE;
-
- BEGIN_ENTRYPOINT_VOIDRET;
-
- HCRYPTPROV hProv = NULL;
- HCRYPTHASH hHash = NULL;
- DWORD dwSize;
-
-
- SNLOG((W("StrongNameHashSize(%08X, %08X)\n"), ulHashAlg, pcbSize));
-
- SN_COMMON_PROLOG();
-
- if (pcbSize == NULL)
- SN_ERROR(E_POINTER);
-
- // Default hashing algorithm ID if necessary.
- if (ulHashAlg == 0)
- ulHashAlg = CALG_SHA1;
-
- // Find a CSP supporting the required algorithm.
- hProv = LocateCSP(NULL, SN_IGNORE_CONTAINER, ulHashAlg);
- if (!hProv)
- goto Error;
-
- // Create a hash object.
- if (!CryptCreateHash(hProv, ulHashAlg, 0, 0, &hHash))
- goto Error;
-
- // And ask for the size of the hash.
- dwSize = sizeof(DWORD);
- if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)pcbSize, &dwSize, 0))
- goto Error;
-
- // Cleanup and exit.
- CryptDestroyHash(hHash);
- FreeCSP(hProv);
-
- retVal = TRUE;
- goto Exit;
-
- Error:
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- if (hHash)
- CryptDestroyHash(hHash);
- if (hProv)
- FreeCSP(hProv);
-
- Exit:
-
- END_ENTRYPOINT_VOIDRET;
-
- return retVal;
-}
-
-
-// Compute the size that needs to be allocated for a signature in an assembly.
-SNAPI StrongNameSignatureSize(BYTE *pbPublicKeyBlob, // [in] public key blob
- ULONG cbPublicKeyBlob,
- DWORD *pcbSize) // [out] size of the signature in bytes
-{
- BOOLEAN retVal = FALSE;
-
- BEGIN_ENTRYPOINT_VOIDRET;
-
- PublicKeyBlob *pPublicKey = (PublicKeyBlob*)pbPublicKeyBlob;
- ALG_ID uHashAlgId;
- ALG_ID uSignAlgId;
- HCRYPTPROV hProv = NULL;
- HCRYPTHASH hHash = NULL;
- HCRYPTKEY hKey = NULL;
- LPCWSTR wszKeyContainer = NULL;
- BOOLEAN bTempContainer = FALSE;
- DWORD dwKeyLen;
- DWORD dwBytes;
-
- SNLOG((W("StrongNameSignatureSize(%08X, %08X, %08X)\n"), pbPublicKeyBlob, cbPublicKeyBlob, pcbSize));
-
- SN_COMMON_PROLOG();
-
- if (pbPublicKeyBlob == NULL)
- SN_ERROR(E_POINTER);
- if (!StrongNameIsValidPublicKey(pbPublicKeyBlob, cbPublicKeyBlob, false))
- SN_ERROR(CORSEC_E_INVALID_PUBLICKEY);
- if (pcbSize == NULL)
- SN_ERROR(E_POINTER);
-
- // Special case neutral key.
- if (SN_IS_NEUTRAL_KEY(pPublicKey))
- pPublicKey = SN_THE_KEY();
-
- // Determine hashing/signing algorithms.
- uHashAlgId = GET_UNALIGNED_VAL32(&pPublicKey->HashAlgID);
- uSignAlgId = GET_UNALIGNED_VAL32(&pPublicKey->SigAlgID);
-
- // Default hashing and signing algorithm IDs if necessary.
- if (uHashAlgId == 0)
- uHashAlgId = CALG_SHA1;
- if (uSignAlgId == 0)
- uSignAlgId = CALG_RSA_SIGN;
-
- // Create a temporary key container name.
- if (!GetKeyContainerName(&wszKeyContainer, &bTempContainer))
- goto Exit;
-
- // Find a CSP supporting the required algorithms and create a temporary key
- // container.
- hProv = LocateCSP(wszKeyContainer, SN_CREATE_CONTAINER, uHashAlgId, uSignAlgId);
- if (!hProv)
- goto Error;
-
- // Import the public key (we need to do this in order to determine the key
- // length reliably).
- if (!CryptImportKey(hProv,
- pPublicKey->PublicKey,
- GET_UNALIGNED_VAL32(&pPublicKey->cbPublicKey),
- 0, 0, &hKey))
- goto Error;
-
- // Query the key attributes (it's the length we're interested in).
- dwBytes = sizeof(dwKeyLen);
- if (!CryptGetKeyParam(hKey, KP_KEYLEN, (BYTE*)&dwKeyLen, &dwBytes, 0))
- goto Error;
-
- // Delete the key container.
- if (LocateCSP(wszKeyContainer, SN_DELETE_CONTAINER) == NULL) {
- SetLastError(CORSEC_E_CONTAINER_NOT_FOUND);
- goto Error;
- }
-
- // Take shortcut for the typical case
- if ((uSignAlgId == CALG_RSA_SIGN) && (dwKeyLen % 8 == 0)) {
- // The signature size known for CALG_RSA_SIGN
- *pcbSize = dwKeyLen / 8;
- }
- else {
- // Recreate the container so we can create a temporary key pair.
- hProv = LocateCSP(wszKeyContainer, SN_CREATE_CONTAINER, uHashAlgId, uSignAlgId);
- if (!hProv)
- goto Error;
-
- // Create the temporary key pair.
- if (!CryptGenKey(hProv, g_uKeySpec, dwKeyLen << 16, &hKey))
- goto Error;
-
- // Create a hash.
- if (!CryptCreateHash(hProv, uHashAlgId, 0, 0, &hHash))
- goto Error;
-
- // Compute size of the signature blob.
- if (!CryptSignHashW(hHash, g_uKeySpec, NULL, 0, NULL, pcbSize))
- goto Error;
- CryptDestroyHash(hHash);
-
- if (bTempContainer)
- LocateCSP(wszKeyContainer, SN_DELETE_CONTAINER);
- }
-
- SNLOG((W("Signature size for hashalg %08X, %08X key (%08X bits) is %08X bytes\n"), uHashAlgId, uSignAlgId, dwKeyLen, *pcbSize));
-
- CryptDestroyKey(hKey);
- FreeCSP(hProv);
- FreeKeyContainerName(wszKeyContainer, bTempContainer);
-
- retVal = TRUE;
- goto Exit;
-
- Error:
- SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
- if (hHash)
- CryptDestroyHash(hHash);
- if (hKey)
- CryptDestroyKey(hKey);
- if (hProv)
- FreeCSP(hProv);
- if (bTempContainer)
- LocateCSP(wszKeyContainer, SN_DELETE_CONTAINER);
- FreeKeyContainerName(wszKeyContainer, bTempContainer);
-
- Exit:
- END_ENTRYPOINT_VOIDRET;
-
- return retVal;
-}
-
-// Locate CSP based on criteria specified in the registry (CSP name etc).
-// Optionally create or delete a named key container within that CSP.
-HCRYPTPROV LocateCSP(LPCWSTR wszKeyContainer,
- DWORD dwAction,
- ALG_ID uHashAlgId,
- ALG_ID uSignAlgId)
-{
- DWORD i;
- DWORD dwType;
- WCHAR wszName[SN_MAX_CSP_NAME + 1];
- DWORD dwNameLength;
- HCRYPTPROV hProv;
- BOOLEAN bFirstAlg;
- BOOLEAN bFoundHash;
- BOOLEAN bFoundSign;
- PROV_ENUMALGS rAlgs;
- HCRYPTPROV hRetProv;
- DWORD dwAlgsLen;
-
- DWORD dwProvType = g_uProvType;
-
- // If a CSP name has been provided (and we're not opening a CSP just to do a
- // SHA1 hash or a verification), open the CSP directly.
- if (g_bHasCSPName &&
- (dwAction != SN_HASH_SHA1_ONLY))
- {
- if (StrongNameCryptAcquireContext(&hProv,
- wszKeyContainer ? wszKeyContainer : NULL,
- g_wszCSPName,
- dwProvType,
- SN_CAC_FLAGS(dwAction)))
- return (dwAction == SN_DELETE_CONTAINER) ? (HCRYPTPROV)~0 : hProv;
- else {
- SNLOG((W("Failed to open CSP '%s': %08X\n"), g_wszCSPName, GetLastError()));
- return NULL;
- }
- }
-
- // Set up hashing and signing algorithms to look for based upon input
- // parameters. Or if these haven't been supplied use the configured defaults
- // instead.
- if (uHashAlgId == 0)
- uHashAlgId = g_uHashAlgId;
- if (uSignAlgId == 0)
- uSignAlgId = g_uSignAlgId;
-
- // If default hashing and signing algorithms have been selected (SHA1 and
- // RSA), we select the default CSP for the RSA_FULL type.
- // For SHA2 and RSA, we select the default CSP For RSA_AES.
- // Otherwise, you just get the first CSP that supports the algorithms
- // you specified (with no guarantee that the selected CSP is a default of any type).
- // This is because we have no way of forcing the enumeration to just give us default
- // CSPs.
- bool fUseDefaultCsp = false;
- StrongNameCachedCsp cachedCspNumber = None;
-
- // We know what container to use for SHA1 algorithms with RSA
- if (((uHashAlgId == CALG_SHA1) && (uSignAlgId == CALG_RSA_SIGN)) ||
- (dwAction == SN_HASH_SHA1_ONLY)) {
- fUseDefaultCsp = true;
- cachedCspNumber = Sha1CachedCsp;
- dwProvType = PROV_RSA_FULL;
-
- SNLOG((W("Attempting to open default provider\n")));
- }
-
- // We know what container to use for SHA2 algorithms with RSA
- if ((uHashAlgId == CALG_SHA_256 || uHashAlgId == CALG_SHA_384 || uHashAlgId == CALG_SHA_512)
- && uSignAlgId == CALG_RSA_SIGN) {
- fUseDefaultCsp = true;
- cachedCspNumber = Sha2CachedCsp;
- dwProvType = PROV_RSA_AES;
-
- SNLOG((W("Attempting to open default SHA2 provider\n")));
- }
-
- if (fUseDefaultCsp)
- {
- // If we're not trying to create/open/delete a key container, see if a
- // CSP is cached.
- if (wszKeyContainer == NULL && dwAction != SN_DELETE_CONTAINER) {
- hProv = LookupCachedCSP(cachedCspNumber);
- if (hProv) {
- SNLOG((W("Found provider in cache\n")));
- return hProv;
- }
- }
- if (StrongNameCryptAcquireContext(&hProv,
- wszKeyContainer ? wszKeyContainer : NULL,
- NULL,
- dwProvType,
- SN_CAC_FLAGS(dwAction))) {
- // If we're not trying to create/open/delete a key container, cache
- // the CSP returned.
- if (wszKeyContainer == NULL && dwAction != SN_DELETE_CONTAINER)
- CacheCSP(hProv, cachedCspNumber);
- return (dwAction == SN_DELETE_CONTAINER) ? (HCRYPTPROV)~0 : hProv;
- } else {
- SNLOG((W("Failed to open: %08X\n"), GetLastError()));
- return NULL;
- }
- }
-
- HRESULT hr = InitStrongNameCriticalSection();
- if (FAILED(hr)) {
- SetLastError(hr);
- return NULL;
- }
-
- // Some crypto APIs are non thread safe (e.g. enumerating CSP
- // hashing/signing algorithms). Use a mutex to serialize these operations.
- // The following usage is GC-safe and exception-safe:
- {
- CRITSEC_Holder csh(g_rStrongNameMutex);
-
- for (i = 0; ; i++) {
-
- // Enumerate all CSPs.
- dwNameLength = sizeof(wszName);
- if (CryptEnumProvidersW(i, 0, 0, &dwType, wszName, &dwNameLength)) {
-
- // Open the currently selected CSP.
- SNLOG((W("Considering CSP '%s'\n"), wszName));
- if (StrongNameCryptAcquireContext(&hProv,
- NULL,
- wszName,
- dwType,
- CRYPT_SILENT |
- CRYPT_VERIFYCONTEXT |
- (g_bUseMachineKeyset ? CRYPT_MACHINE_KEYSET : 0))) {
-
- // Enumerate all the algorithms the CSP supports.
- bFirstAlg = TRUE;
- bFoundHash = FALSE;
- bFoundSign = FALSE;
- for (;;) {
-
- dwAlgsLen = sizeof(rAlgs);
- if (CryptGetProvParam(hProv,
- PP_ENUMALGS, (BYTE*)&rAlgs, &dwAlgsLen,
- bFirstAlg ? CRYPT_FIRST : 0)) {
-
- if (rAlgs.aiAlgid == uHashAlgId)
- bFoundHash = TRUE;
- else if (rAlgs.aiAlgid == uSignAlgId)
- bFoundSign = TRUE;
-
- if (bFoundHash && bFoundSign) {
-
- // Found a CSP that supports the required
- // algorithms. Re-open the context with access to
- // the required key container.
-
- SNLOG((W("CSP matches\n")));
-
- if (StrongNameCryptAcquireContext(&hRetProv,
- wszKeyContainer ? wszKeyContainer : NULL,
- wszName,
- dwType,
- CRYPT_SILENT |
- SN_CAC_FLAGS(dwAction))) {
- CryptReleaseContext(hProv, 0);
- return (dwAction == SN_DELETE_CONTAINER) ? (HCRYPTPROV)~0 : hRetProv;
- } else {
- SNLOG((W("Failed to re-open for container: %08X\n"), GetLastError()));
- break;
- }
- }
-
- bFirstAlg = FALSE;
-
- } else {
- _ASSERTE(GetLastError() == ERROR_NO_MORE_ITEMS);
- break;
- }
-
- }
-
- CryptReleaseContext(hProv, 0);
-
- } else
- SNLOG((W("Failed to open CSP: %08X\n"), GetLastError()));
-
- } else if (GetLastError() == ERROR_NO_MORE_ITEMS)
- break;
-
- }
- // csh for g_rStrongNameMutex goes out of scope here
- }
-
- // No matching CSP found.
- SetLastError(CORSEC_E_NO_SUITABLE_CSP);
- return NULL;
-}
-
-
-// Release a CSP acquired through LocateCSP.
-VOID FreeCSP(HCRYPTPROV hProv)
-{
- // If the CSP is currently cached, don't release it yet.
- if (!IsCachedCSP(hProv))
- CryptReleaseContext(hProv, 0);
-}
-
-// Locate a cached CSP for this thread.
-HCRYPTPROV LookupCachedCSP(StrongNameCachedCsp cspNumber)
-{
- SN_THREAD_CTX *pThreadCtx = GetThreadContext();
- if (pThreadCtx == NULL)
- return NULL;
- return pThreadCtx->m_hProv[cspNumber];
-}
-
-
-// Update the CSP cache for this thread (freeing any CSP displaced).
-VOID CacheCSP(HCRYPTPROV hProv, StrongNameCachedCsp cspNumber)
-{
- SN_THREAD_CTX *pThreadCtx = GetThreadContext();
- if (pThreadCtx == NULL)
- return;
- if (pThreadCtx->m_hProv[cspNumber])
- CryptReleaseContext(pThreadCtx->m_hProv[cspNumber], 0);
- pThreadCtx->m_hProv[cspNumber] = hProv;
-}
-
-
-// Determine whether a given CSP is currently cached.
-BOOLEAN IsCachedCSP(HCRYPTPROV hProv)
-{
- SN_THREAD_CTX *pThreadCtx = GetThreadContext();
- if (pThreadCtx == NULL)
- return FALSE;
- for (ULONG i = 0; i < CachedCspCount; i++)
- {
- if(pThreadCtx->m_hProv[i] == hProv)
- {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-// rehash all files in a multi-module assembly
-BOOLEAN RehashModules (SN_LOAD_CTX *pLoadCtx, LPCWSTR wszFilePath) {
- HRESULT hr;
- ULONG ulHashAlg;
- mdAssembly tkAssembly;
- HENUMInternal hFileEnum;
- mdFile tkFile;
- LPCSTR pszFile;
- BYTE *pbFileHash;
- DWORD cbFileHash;
- NewArrayHolder<BYTE> pbNewFileHash(NULL);
- DWORD cbNewFileHash = 0;
- DWORD cchDirectory;
- DWORD cchFullFile;
- CHAR szFullFile[MAX_LONGPATH + 1];
- WCHAR wszFullFile[MAX_LONGPATH + 1];
- LPCWSTR pszSlash;
- DWORD cchFile;
- IMDInternalImport *pMetaDataImport = NULL;
-
- // Determine the directory the assembly lives in (this is where we'll
- // look for linked files).
- if (((pszSlash = wcsrchr(wszFilePath, W('\\'))) != NULL) || ((pszSlash = wcsrchr(wszFilePath, W('/'))) != NULL)) {
- cchDirectory = (DWORD) (pszSlash - wszFilePath + 1);
- cchDirectory = WszWideCharToMultiByte(CP_UTF8, 0, wszFilePath, cchDirectory, szFullFile, MAX_LONGPATH, NULL, NULL);
- if (cchDirectory >= MAX_LONGPATH) {
- SNLOG((W("Assembly directory name too long\n")));
- hr = ERROR_BUFFER_OVERFLOW;
- goto Error;
- }
- } else
- cchDirectory = 0;
-
- // Open the scope on the mapped image.
- if (FAILED(hr = GetMetadataImport(pLoadCtx, &tkAssembly, &pMetaDataImport)))
- {
- goto Error;
- }
-
- // Determine the hash algorithm used for file references.
- if (FAILED(hr = pMetaDataImport->GetAssemblyProps(
- tkAssembly, // [IN] The Assembly for which to get the properties
- NULL, // [OUT] Pointer to the Originator blob
- NULL, // [OUT] Count of bytes in the Originator Blob
- &ulHashAlg, // [OUT] Hash Algorithm
- NULL, // [OUT] Buffer to fill with name
- NULL, // [OUT] Assembly MetaData
- NULL))) // [OUT] Flags
- {
- SNLOG((W("Failed to get assembly 0x%08X info, %08X\n"), tkAssembly, hr));
- goto Error;
- }
-
- // Enumerate all file references.
- if (FAILED(hr = pMetaDataImport->EnumInit(mdtFile, mdTokenNil, &hFileEnum)))
- {
- SNLOG((W("Failed to enumerate linked files, %08X\n"), hr));
- goto Error;
- }
-
- for (; pMetaDataImport->EnumNext(&hFileEnum, &tkFile); ) {
-
- // Determine the file name and the location of the hash.
- if (FAILED(hr = pMetaDataImport->GetFileProps(
- tkFile,
- &pszFile,
- (const void **)&pbFileHash,
- &cbFileHash,
- NULL)))
- {
- SNLOG((W("Failed to get file 0x%08X info, %08X\n"), tkFile, hr));
- goto Error;
- }
-
- // Build the full filename by appending to the assembly directory we
- // calculated earlier.
- cchFile = (DWORD) strlen(pszFile);
- if ((cchFile + cchDirectory) >= COUNTOF(szFullFile)) {
- pMetaDataImport->EnumClose(&hFileEnum);
- SNLOG((W("Linked file name too long (%S)\n"), pszFile));
- hr = ERROR_BUFFER_OVERFLOW;
- goto Error;
- }
- memcpy_s(&szFullFile[cchDirectory], COUNTOF(szFullFile) - cchDirectory, pszFile, cchFile + 1);
-
- // Allocate enough buffer for the new hash.
- if (cbNewFileHash < cbFileHash) {
- pbNewFileHash = new (nothrow) BYTE[cbFileHash];
- if (pbNewFileHash == NULL) {
- hr = E_OUTOFMEMORY;
- goto Error;
- }
- cbNewFileHash = cbFileHash;
- }
-
- cchFullFile = WszMultiByteToWideChar(CP_UTF8, 0, szFullFile, -1, wszFullFile, MAX_LONGPATH);
- if (cchFullFile == 0 || cchFullFile >= MAX_LONGPATH) {
- pMetaDataImport->EnumClose(&hFileEnum);
- SNLOG((W("Assembly directory name too long\n")));
- hr = ERROR_BUFFER_OVERFLOW;
- goto Error;
- }
-
- // Compute a new hash for the file.
- if (FAILED(hr = GetHashFromFileW(wszFullFile,
- (unsigned*)&ulHashAlg,
- pbNewFileHash,
- cbNewFileHash,
- &cbNewFileHash))) {
- pMetaDataImport->EnumClose(&hFileEnum);
- SNLOG((W("Failed to get compute file hash, %08X\n"), hr));
- goto Error;
- }
-
- // The new hash has to be the same size (since we used the same
- // algorithm).
- _ASSERTE(cbNewFileHash == cbFileHash);
-
- // We make the assumption here that the pointer to the file hash
- // handed to us by the metadata is a direct pointer and not a
- // buffered copy. If this changes, we'll need a new metadata API to
- // support updates of this type.
- memcpy_s(pbFileHash, cbFileHash, pbNewFileHash, cbFileHash);
- }
-
- pMetaDataImport->EnumClose(&hFileEnum);
- pMetaDataImport->Release();
- return TRUE;
-
-Error:
- if (pMetaDataImport)
- pMetaDataImport->Release();
- if (pbNewFileHash)
- pbNewFileHash.Release();
- SetLastError(hr);
- return FALSE;
-}
-
-//
-// Check that the public key portion of an assembly's identity matches the private key that it is being
-// signed with.
-//
-// Arguments:
-// pAssemblySignaturePublicKey - Assembly signature public key blob
-// wszKeyContainer - Key container holding the key the assembly is signed with
-// dwFlags - SN_ECMA_SIGN if the assembly is being ECMA signed, SN_TEST_SIGN if it is being test signed
-//
-// Return Value:
-// true if the assembly's public key matches the private key in wszKeyContainer, otherwise false
-//
-
-bool VerifyKeyMatchesAssembly(PublicKeyBlob * pAssemblySignaturePublicKey, __in_z LPCWSTR wszKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, DWORD dwFlags)
-{
- _ASSERTE(wszKeyContainer != NULL || pbKeyBlob != NULL);
-
- // If we're test signing, then the assembly's public key will not match the private key by design.
- // Since there's nothing to check, we can quit early.
- if ((dwFlags & SN_TEST_SIGN) == SN_TEST_SIGN)
- {
- return true;
- }
-
- if (SN_IS_NEUTRAL_KEY(pAssemblySignaturePublicKey))
- {
- // If we're ECMA signing an assembly with the ECMA public key, then by definition the key matches.
- if ((dwFlags & SN_ECMA_SIGN) == SN_ECMA_SIGN)
- {
- return true;
- }
-
- // Swap the real public key in for ECMA signing
- pAssemblySignaturePublicKey = SN_THE_KEY();
- }
-
- // Otherwise, we need to check that the public key from the key container matches the public key from
- // the assembly.
- StrongNameBufferHolder<BYTE> pbSignaturePublicKey = NULL;
- DWORD cbSignaturePublicKey;
- if (!StrongNameGetPublicKeyEx(wszKeyContainer, pbKeyBlob, cbKeyBlob, &pbSignaturePublicKey, &cbSignaturePublicKey, GET_UNALIGNED_VAL32(&pAssemblySignaturePublicKey->HashAlgID), 0 /*Should be GET_UNALIGNED_VAL32(&pAssemblySignaturePublicKey->HashAlgID) once we support different signature algorithms*/))
- {
- // We failed to get the public key for the key in the given key container. StrongNameGetPublicKey
- // has already set the error information, so we can just return false here without resetting it.
- return false;
- }
- _ASSERTE(!pbSignaturePublicKey.IsNull() && pAssemblySignaturePublicKey != NULL);
-
- // Do a raw compare on the public key blobs to see if they match
- if (SN_SIZEOF_KEY(reinterpret_cast<PublicKeyBlob *>(pbSignaturePublicKey.GetValue())) == SN_SIZEOF_KEY(pAssemblySignaturePublicKey) &&
- memcmp(static_cast<void *>(pAssemblySignaturePublicKey),
- static_cast<void *>(pbSignaturePublicKey.GetValue()),
- cbSignaturePublicKey) == 0)
- {
- return true;
- }
-
- SetStrongNameErrorInfo(SN_E_PUBLICKEY_MISMATCH);
- return false;
-}
-
-// Map an assembly into memory.
-BOOLEAN LoadAssembly(SN_LOAD_CTX *pLoadCtx, LPCWSTR wszFilePath, DWORD inFlags, BOOLEAN fRequireSignature)
-{
- DWORD dwError = S_OK;
-
- // If a filename is not supplied, the image has already been mapped (and the
- // image base and length fields set up correctly).
- if (wszFilePath == NULL)
- {
- pLoadCtx->m_fPreMapped = TRUE;
- pLoadCtx->m_pedecoder = new (nothrow) PEDecoder(pLoadCtx->m_pbBase, static_cast<COUNT_T>(pLoadCtx->m_dwLength));
- if (pLoadCtx->m_pedecoder == NULL) {
- dwError = E_OUTOFMEMORY;
- goto Error;
- }
- }
- else {
-
- pLoadCtx->m_hMap = INVALID_HANDLE_VALUE;
- pLoadCtx->m_pbBase = NULL;
-
- // Open the file for reading or writing.
- pLoadCtx->m_hFile = WszCreateFile(wszFilePath,
- GENERIC_READ | (pLoadCtx->m_fReadOnly ? 0 : GENERIC_WRITE),
- pLoadCtx->m_fReadOnly ? FILE_SHARE_READ : FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
- if (pLoadCtx->m_hFile == INVALID_HANDLE_VALUE) {
- dwError = HRESULT_FROM_GetLastError();
- goto Error;
- }
-
- pLoadCtx->m_dwLength = SafeGetFileSize(pLoadCtx->m_hFile, NULL);
- if (pLoadCtx->m_dwLength == 0xffffffff) {
- dwError = HRESULT_FROM_GetLastError();
- goto Error;
- }
-
- // Create a mapping handle for the file.
- pLoadCtx->m_hMap = WszCreateFileMapping(pLoadCtx->m_hFile, NULL, pLoadCtx->m_fReadOnly ? PAGE_READONLY : PAGE_READWRITE, 0, 0, NULL);
- if (pLoadCtx->m_hMap == NULL) {
- dwError = HRESULT_FROM_GetLastError();
- goto Error;
- }
-
- // And map it into memory.
- pLoadCtx->m_pbBase = (BYTE*)CLRMapViewOfFile(pLoadCtx->m_hMap, pLoadCtx->m_fReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, 0, 0, 0);
- if (pLoadCtx->m_pbBase == NULL) {
- dwError = HRESULT_FROM_GetLastError();
- goto Error;
- }
- pLoadCtx->m_pedecoder = new (nothrow) PEDecoder(pLoadCtx->m_pbBase, static_cast<COUNT_T>(pLoadCtx->m_dwLength));
- if (pLoadCtx->m_pedecoder == NULL) {
- dwError = E_OUTOFMEMORY;
- goto Error;
- }
- }
-
- if (!pLoadCtx->m_pedecoder->HasContents() || !pLoadCtx->m_pedecoder->CheckCORFormat()) {
- dwError = CORSEC_E_INVALID_IMAGE_FORMAT;
- goto Error;
- }
-
- // Locate standard NT image header.
- pLoadCtx->m_pNtHeaders = pLoadCtx->m_pedecoder->GetNTHeaders32();
-
- if (pLoadCtx->m_pNtHeaders == NULL) {
- dwError = CORSEC_E_INVALID_IMAGE_FORMAT;
- goto Error;
- }
-
- pLoadCtx->m_pCorHeader = pLoadCtx->m_pedecoder->GetCorHeader();
-
- if (pLoadCtx->m_pCorHeader == NULL) {
- dwError = CORSEC_E_INVALID_IMAGE_FORMAT;
- goto Error;
- }
-
- // Set up signature pointer (if we require it).
- if (fRequireSignature && pLoadCtx->m_pedecoder->HasStrongNameSignature())
- {
- COUNT_T size = 0;
- BYTE* pbSignature = (BYTE*)pLoadCtx->m_pedecoder->GetStrongNameSignature(&size);
-
- // Make sure the signature doesn't point back into the header
- if (pbSignature <= reinterpret_cast<BYTE*>(pLoadCtx->m_pCorHeader) &&
- pbSignature > reinterpret_cast<BYTE*>(pLoadCtx->m_pCorHeader) - size)
- {
- dwError = CORSEC_E_INVALID_IMAGE_FORMAT;
- goto Error;
- }
- if (pbSignature >= reinterpret_cast<BYTE*>(pLoadCtx->m_pCorHeader) &&
- pbSignature - sizeof(IMAGE_COR20_HEADER) < reinterpret_cast<BYTE*>(pLoadCtx->m_pCorHeader))
- {
- dwError = CORSEC_E_INVALID_IMAGE_FORMAT;
- goto Error;
- }
-
- pLoadCtx->m_pbSignature = pbSignature;
- pLoadCtx->m_cbSignature = static_cast<DWORD>(size);
- }
-
- return TRUE;
-
- Error:
- if (!pLoadCtx->m_fPreMapped) {
- if (pLoadCtx->m_pbBase)
- CLRUnmapViewOfFile(pLoadCtx->m_pbBase);
- if (pLoadCtx->m_hMap != INVALID_HANDLE_VALUE)
- CloseHandle(pLoadCtx->m_hMap);
- if (pLoadCtx->m_hFile != INVALID_HANDLE_VALUE)
- CloseHandle(pLoadCtx->m_hFile);
- }
- SetLastError(dwError);
- return FALSE;
-}
-
-
-// Unload an assembly loaded with LoadAssembly (recomputing checksum if
-// necessary).
-BOOLEAN UnloadAssembly(SN_LOAD_CTX *pLoadCtx)
-{
- BOOLEAN bResult = TRUE;
-
- if (!pLoadCtx->m_fReadOnly) {
-
- IMAGE_NT_HEADERS *pNtHeaders = NULL;
- DWORD dwCheckSum = 0;
-
- // We late bind CheckSumMappedFile to avoid bringing in IMAGEHLP unless
- // we need to.
- HMODULE hLibrary = WszLoadLibrary(W("imagehlp.dll"));
- if (hLibrary) {
- IMAGE_NT_HEADERS *(*SN_CheckSumMappedFile)(BYTE*, DWORD, DWORD*, DWORD*);
-
- if ((*(FARPROC*)&SN_CheckSumMappedFile = GetProcAddress(hLibrary, "CheckSumMappedFile")) != NULL) {
- DWORD dwOldCheckSum;
-
- pNtHeaders = SN_CheckSumMappedFile(pLoadCtx->m_pbBase,
- pLoadCtx->m_dwLength,
- &dwOldCheckSum,
- &dwCheckSum);
- }
-
- FreeLibrary(hLibrary);
-
- }
-
- if (pNtHeaders != NULL) {
- if (pNtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC))
- ((IMAGE_NT_HEADERS32*)pNtHeaders)->OptionalHeader.CheckSum = VAL32(dwCheckSum);
- else
- if (pNtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR64_MAGIC))
- ((IMAGE_NT_HEADERS64*)pNtHeaders)->OptionalHeader.CheckSum = VAL32(dwCheckSum);
- } else
- bResult = FALSE;
-
- if (!pLoadCtx->m_fPreMapped && !FlushViewOfFile(pLoadCtx->m_pbBase, 0))
- bResult = FALSE;
- }
-
- if (!pLoadCtx->m_fPreMapped) {
- if (!CLRUnmapViewOfFile(pLoadCtx->m_pbBase))
- bResult = FALSE;
-
- if (!CloseHandle(pLoadCtx->m_hMap))
- bResult = FALSE;
-
- if (!CloseHandle(pLoadCtx->m_hFile))
- bResult = FALSE;
- }
-
- if (pLoadCtx->m_pedecoder != NULL)
- {
- delete (pLoadCtx->m_pedecoder);
- pLoadCtx->m_pedecoder = NULL;
- }
-
- return bResult;
-}
-
-template<class T>
-LONG RegQueryValueT(HKEY hKey, LPCWSTR pValueName, T * pData)
-{
- DWORD dwLength = sizeof(T);
-
- LONG status = WszRegQueryValueEx(hKey, pValueName, NULL, NULL, (BYTE*) pData, & dwLength);
-
- return status;
-}
-
-// Reads CSP configuration info (name of CSP to use, IDs of hashing/signing
-// algorithms) from the registry.
-HRESULT ReadRegistryConfig()
-{
- HKEY hKey;
- DWORD dwLength;
-
- // Initialize all settings to their default values, in case they've not been
- // specified in the registry.
- g_bHasCSPName = FALSE;
- g_bUseMachineKeyset = TRUE;
- g_uKeySpec = AT_SIGNATURE;
- g_uHashAlgId = CALG_SHA1;
- g_uSignAlgId = CALG_RSA_SIGN;
- g_uProvType = PROV_RSA_FULL;
-
-#ifdef FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED
- g_pVerificationRecords = NULL;
-#endif
-
- g_fCacheVerify = TRUE;
-
- // Open the configuration key in the registry.
- if (WszRegOpenKeyEx(HKEY_LOCAL_MACHINE, SN_CONFIG_KEY_W, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
- return S_OK;
-
- // Read the preferred CSP name.
- {
- // Working set optimization: avoid touching g_wszCSPName (2052 bytes in size) unless registry has value for it
- WCHAR tempCSPName[_countof(g_wszCSPName)];
- dwLength = sizeof(tempCSPName);
-
- tempCSPName[0] = 0;
-
- // If the registry key value is too long, that means it is invalid.
- VERIFY(WszRegQueryValueEx(hKey, SN_CONFIG_CSP_W, NULL, NULL,
- (BYTE*) tempCSPName, &dwLength) != ERROR_MORE_DATA);
- tempCSPName[COUNTOF(tempCSPName) - 1] = W('\0'); // make sure the string is NULL-terminated
- SNLOG((W("Preferred CSP name: '%s'\n"), tempCSPName));
-
- if (tempCSPName[0] != W('\0'))
- {
- memcpy(g_wszCSPName, tempCSPName, sizeof(g_wszCSPName));
- g_bHasCSPName = TRUE;
- }
- }
-
- // Read the machine vs user key container flag.
- DWORD dwUseMachineKeyset = TRUE;
- RegQueryValueT(hKey, SN_CONFIG_MACHINE_KEYSET_W, & dwUseMachineKeyset);
- SNLOG((W("Use machine keyset: %s\n"), dwUseMachineKeyset ? W("TRUE") : W("FALSE")));
- g_bUseMachineKeyset = (BOOLEAN)dwUseMachineKeyset;
-
- // Read the key spec.
- RegQueryValueT(hKey, SN_CONFIG_KEYSPEC_W, & g_uKeySpec);
- SNLOG((W("Key spec: %08X\n"), g_uKeySpec));
-
- // Read the provider type
- RegQueryValueT(hKey, SN_CONFIG_PROV_TYPE_W, & g_uProvType);
- SNLOG((W("Provider Type: %08X\n"), g_uProvType));
-
- // Read the hashing algorithm ID.
- RegQueryValueT(hKey, SN_CONFIG_HASH_ALG_W, & g_uHashAlgId);
- SNLOG((W("Hashing algorithm: %08X\n"), g_uHashAlgId));
-
- // Read the signing algorithm ID.
- RegQueryValueT(hKey, SN_CONFIG_SIGN_ALG_W, & g_uSignAlgId);
- SNLOG((W("Signing algorithm: %08X\n"), g_uSignAlgId));
-
- // Read the OK to cache verifications flag.
- DWORD dwCacheVerify = TRUE;
- RegQueryValueT(hKey, SN_CONFIG_CACHE_VERIFY_W, & dwCacheVerify);
- SNLOG((W("OK to cache verifications: %s\n"), dwCacheVerify ? W("TRUE") : W("FALSE")));
- g_fCacheVerify = (BOOLEAN)dwCacheVerify;
-
- RegCloseKey(hKey);
-
- HRESULT hr = S_OK;
-#ifdef FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED
- // Read verify disable records.
- IfFailRet(ReadVerificationRecords());
-#endif // FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED
-
-#ifdef FEATURE_STRONGNAME_MIGRATION
- IfFailRet(ReadRevocationRecords());
-#endif // FEATURE_STRONGNAME_MIGRATION
-
- return hr;
-}
-
-#ifdef FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED
-// Read verification records from the registry during startup.
-HRESULT ReadVerificationRecords()
-{
- HKEYHolder hKey;
- WCHAR wszSubKey[MAX_PATH_FNAME + 1];
- DWORD cchSubKey;
- SN_VER_REC *pVerificationRecords = NULL;
- HRESULT hr = S_OK;
-
- // Open the verification subkey in the registry.
- if (WszRegOpenKeyEx(HKEY_LOCAL_MACHINE, SN_CONFIG_KEY_W W("\\") SN_CONFIG_VERIFICATION_W, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
- return hr;
-
- // Assembly specific records are represented as subkeys of the key we've
- // just opened.
- for (DWORD i = 0; ; i++) {
- // Get the name of the next subkey.
- cchSubKey = MAX_PATH_FNAME + 1;
- FILETIME sFiletime;
- if (WszRegEnumKeyEx(hKey, i, wszSubKey, &cchSubKey, NULL, NULL, NULL, &sFiletime) != ERROR_SUCCESS)
- break;
-
- // Open the subkey.
- HKEYHolder hSubKey;
- if (WszRegOpenKeyEx(hKey, wszSubKey, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS) {
- NewArrayHolder<WCHAR> mszUserList(NULL);
- DWORD cbUserList;
- NewArrayHolder<WCHAR> wszTestPublicKey(NULL);
- DWORD cbTestPublicKey;
- NewArrayHolder<WCHAR> wszAssembly(NULL);
- SN_VER_REC *pVerRec;
-
- // Read a list of valid users, if supplied.
- if ((WszRegQueryValueEx(hSubKey, SN_CONFIG_USERLIST_W, NULL, NULL, NULL, &cbUserList) == ERROR_SUCCESS) &&
- (cbUserList > 0)) {
- mszUserList = new (nothrow) WCHAR[cbUserList / sizeof(WCHAR)];
- if (!mszUserList) {
- hr = E_OUTOFMEMORY;
- goto FreeListExit;
- }
- WszRegQueryValueEx(hSubKey, SN_CONFIG_USERLIST_W, NULL, NULL, (BYTE*)mszUserList.GetValue(), &cbUserList);
- }
-
- // Read the test public key, if supplied
- if ((WszRegQueryValueEx(hSubKey, SN_CONFIG_TESTPUBLICKEY_W, NULL, NULL, NULL, &cbTestPublicKey) == ERROR_SUCCESS) &&
- (cbTestPublicKey > 0)) {
- wszTestPublicKey = new (nothrow) WCHAR[cbTestPublicKey / sizeof(WCHAR)];
- if (!wszTestPublicKey) {
- hr = E_OUTOFMEMORY;
- goto FreeListExit;
- }
- WszRegQueryValueEx(hSubKey, SN_CONFIG_TESTPUBLICKEY_W, NULL, NULL, (BYTE*)wszTestPublicKey.GetValue(), &cbTestPublicKey);
- }
-
- size_t dwSubKeyLen = wcslen(wszSubKey);
- wszAssembly = new (nothrow) WCHAR[dwSubKeyLen+1];
- if (!wszAssembly) {
- hr = E_OUTOFMEMORY;
- goto FreeListExit;
- }
- wcsncpy_s(wszAssembly, dwSubKeyLen+1, wszSubKey, _TRUNCATE);
- wszAssembly[dwSubKeyLen] = W('\0');
-
- // We've found a valid entry, add it to the local list.
- pVerRec = new (nothrow) SN_VER_REC;
- if (!pVerRec) {
- hr = E_OUTOFMEMORY;
- goto FreeListExit;
- }
-
- pVerRec->m_mszUserList = mszUserList;
- pVerRec->m_wszTestPublicKey = wszTestPublicKey;
- pVerRec->m_wszAssembly = wszAssembly;
-
- mszUserList.SuppressRelease();
- wszTestPublicKey.SuppressRelease();
- wszAssembly.SuppressRelease();
-
- pVerRec->m_pNext = pVerificationRecords;
- pVerificationRecords = pVerRec;
- SNLOG((W("Verification record for '%s' found in registry\n"), wszSubKey));
- }
- }
-
- // Initialize the global list of verification records.
- PVOID pv = InterlockedCompareExchangeT(&g_pVerificationRecords, pVerificationRecords, NULL);
- if (pv == NULL)
- return hr;
-
-FreeListExit:
- // Iterate over local list of verification records and free allocated memory.
- SN_VER_REC *pVerRec = pVerificationRecords;
- while (pVerRec) {
- delete [] pVerRec->m_mszUserList;
- delete [] pVerRec->m_wszTestPublicKey;
- delete [] pVerRec->m_wszAssembly;
- SN_VER_REC *tmp = pVerRec->m_pNext;
- delete pVerRec;
- pVerRec = tmp;
- }
- return hr;
-}
-#endif // FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED
-
-
-#ifdef FEATURE_STRONGNAME_MIGRATION
-
-#define SN_REVOCATION_KEY_NAME_W W("RevokedKeys") // Registry revocation key name
-#define SN_REVOKEDKEY_VALUE_NAME_W W("RevokedKey") // Registry value name
-
-HRESULT ReadReplacementKeys(HKEY hKey, SN_REPLACEMENT_KEY_REC **ppReplacementRecords)
-{
- HRESULT hr = S_OK;
-
- DWORD uValueCount;
- DWORD cchMaxValueNameLen;
-
- NewArrayHolder<WCHAR> wszValueName(NULL);
-
- if(RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &uValueCount, &cchMaxValueNameLen, NULL, NULL, NULL) != ERROR_SUCCESS)
- return hr;
-
- cchMaxValueNameLen++; // Add 1 for null character
-
- DWORD cchValueName;
- wszValueName = new (nothrow) WCHAR[cchMaxValueNameLen];
- if (!wszValueName) {
- return E_OUTOFMEMORY;
- }
-
- for (DWORD j = 0; j < uValueCount; j++) {
- cchValueName = cchMaxValueNameLen;
- if (WszRegEnumValue(hKey, j, wszValueName, &cchValueName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
- break;
-
- if(SString::_wcsicmp(wszValueName, SN_REVOKEDKEY_VALUE_NAME_W) == 0) // Skip over the "RevokedKey" value
- continue;
-
- NewArrayHolder<BYTE> pbReplacementKey(NULL);
- DWORD cbReplacementKey;
- DWORD dwValType;
- if ((WszRegQueryValueEx(hKey, wszValueName, NULL, &dwValType, NULL, &cbReplacementKey) == ERROR_SUCCESS) &&
- (cbReplacementKey > 0) && (dwValType == REG_BINARY)) {
- pbReplacementKey = new (nothrow) BYTE[cbReplacementKey];
- if (!pbReplacementKey) {
- return E_OUTOFMEMORY;
- }
- if(WszRegQueryValueEx(hKey, wszValueName, NULL, NULL, (BYTE*)pbReplacementKey.GetValue(), &cbReplacementKey) == ERROR_SUCCESS)
- {
- NewHolder<SN_REPLACEMENT_KEY_REC> pReplacementRecord(new (nothrow) SN_REPLACEMENT_KEY_REC);
- if (pReplacementRecord == NULL) {
- return E_OUTOFMEMORY;
- }
-
- pReplacementRecord->m_pbReplacementKey = pbReplacementKey.Extract();
- pReplacementRecord->m_cbReplacementKey = cbReplacementKey;
- // Insert into list
- pReplacementRecord->m_pNext = *ppReplacementRecords;
- *ppReplacementRecords = pReplacementRecord.Extract();
- }
- }
- }
-
- return hr;
-}
-
-// Read revocation records from the registry during startup.
-HRESULT ReadRevocationRecordsFromKey(REGSAM samDesired, SN_REVOCATION_REC **ppRevocationRecords)
-{
- HKEYHolder hKey;
- WCHAR wszSubKey[MAX_PATH_FNAME + 1];
- DWORD cchSubKey;
- HRESULT hr = S_OK;
-
- // Open the revocation subkey in the registry.
- if (WszRegOpenKeyEx(HKEY_LOCAL_MACHINE, SN_CONFIG_KEY_W W("\\") SN_REVOCATION_KEY_NAME_W, 0, samDesired, &hKey) != ERROR_SUCCESS)
- return hr;
-
- // Assembly specific records are represented as subkeys of the key we've
- // just opened.
- for (DWORD i = 0; ; i++) {
- // Read the next subkey
- cchSubKey = MAX_PATH_FNAME + 1; // reset size of buffer, as the following call changes it
- if (WszRegEnumKeyEx(hKey, i, wszSubKey, &cchSubKey, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
- break;
-
- // Open the subkey.
- HKEYHolder hSubKey;
- if (WszRegOpenKeyEx(hKey, wszSubKey, 0, samDesired, &hSubKey) == ERROR_SUCCESS) {
- NewArrayHolder<BYTE> pbRevokedKey(NULL);
- DWORD cbRevokedKey;
- DWORD dwValType;
-
- // Read the "RevokedKey" value
- if ((WszRegQueryValueEx(hSubKey, SN_REVOKEDKEY_VALUE_NAME_W, NULL, &dwValType, NULL, &cbRevokedKey) == ERROR_SUCCESS) &&
- (cbRevokedKey > 0) && (dwValType == REG_BINARY)) {
- pbRevokedKey = new (nothrow) BYTE[cbRevokedKey];
- if (!pbRevokedKey) {
- return E_OUTOFMEMORY;
- }
-
- if(WszRegQueryValueEx(hSubKey, SN_REVOKEDKEY_VALUE_NAME_W, NULL, NULL, (BYTE*)pbRevokedKey.GetValue(), &cbRevokedKey) == ERROR_SUCCESS)
- {
- // We've found a valid entry, store it
- NewHolder<SN_REVOCATION_REC> pRevocationRecord(new (nothrow) SN_REVOCATION_REC);
- if (pRevocationRecord == NULL) {
- return E_OUTOFMEMORY;
- }
-
- pRevocationRecord->m_pbRevokedKey = pbRevokedKey.Extract();
- pRevocationRecord->m_cbRevokedKey = cbRevokedKey;
- pRevocationRecord->m_pReplacementKeys = NULL;
-
- // Insert into list
- pRevocationRecord->m_pNext = *ppRevocationRecords;
- *ppRevocationRecords = pRevocationRecord.Extract();
-
- IfFailRet(ReadReplacementKeys(hSubKey, &pRevocationRecord->m_pReplacementKeys));
-
- SNLOG((W("Revocation record '%s' found in registry\n"), wszSubKey));
- }
- }
- }
- }
-
- return hr;
-}
-
-HRESULT ReadRevocationRecords()
-{
- HRESULT hr = S_OK;
-
- SYSTEM_INFO systemInfo;
- SN_REVOCATION_REC *pRevocationRecords = NULL;
-
- GetNativeSystemInfo(&systemInfo);
- // Read both Software\ and Software\WOW6432Node\ on 64-bit systems
- if(systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
- {
- IfFailGoto(ReadRevocationRecordsFromKey(KEY_READ | KEY_WOW64_64KEY, &pRevocationRecords), FreeListExit);
- IfFailGoto(ReadRevocationRecordsFromKey(KEY_READ | KEY_WOW64_32KEY, &pRevocationRecords), FreeListExit);
- }
- else
- {
- IfFailGoto(ReadRevocationRecordsFromKey(KEY_READ, &pRevocationRecords), FreeListExit);
- }
-
- // Initialize the global list of verification records.
- PVOID pv = InterlockedCompareExchangeT(&g_pRevocationRecords, pRevocationRecords, NULL);
-
- if (pv == NULL) // Successfully inserted the list we just created
- return hr;
-
-FreeListExit:
- // Iterate over local list of verification records and free allocated memory.
- SN_REVOCATION_REC *pRevRec = pRevocationRecords;
- while (pRevRec) {
- if(pRevRec->m_pbRevokedKey)
- delete [] pRevRec->m_pbRevokedKey;
-
- SN_REPLACEMENT_KEY_REC *pKeyRec = pRevRec->m_pReplacementKeys;
- while (pKeyRec) {
- if(pKeyRec->m_pbReplacementKey)
- delete [] pKeyRec->m_pbReplacementKey;
-
- SN_REPLACEMENT_KEY_REC *tmp = pKeyRec->m_pNext;
- delete pKeyRec;
- pKeyRec = tmp;
- }
-
- SN_REVOCATION_REC *tmp2 = pRevRec->m_pNext;
- delete pRevRec;
- pRevRec = tmp2;
- }
- return hr;
-}
-
-#endif // FEATURE_STRONGNAME_MIGRATION
-
-// Check current user name against a multi-string user name list. Return true if
-// the name is found (or the list is empty).
-BOOLEAN IsValidUser(__in_z WCHAR *mszUserList)
-{
- HANDLE hToken;
- DWORD dwRetLen;
- TOKEN_USER *pUser;
- WCHAR wszUser[1024];
- WCHAR wszDomain[1024];
- DWORD cchUser;
- DWORD cchDomain;
- SID_NAME_USE eSidUse;
- WCHAR *wszUserEntry;
-
- // Empty list implies no user name checking.
- if (mszUserList == NULL)
- return TRUE;
-
- // Get current user name. Don't cache this to avoid threading/impersonation
- // problems.
- // First look to see if there's a security token on the current thread
- // (maybe we're impersonating). If not, we'll get the token from the
- // process.
- if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, FALSE, &hToken))
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken)) {
- SNLOG((W("Failed to find a security token, error %08X\n"), GetLastError()));
- return FALSE;
- }
-
- // Get the user SID. (Calculate buffer size first).
- if (!GetTokenInformation(hToken, TokenUser, NULL, 0, &dwRetLen) &&
- GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
- SNLOG((W("Failed to calculate token information buffer size, error %08X\n"), GetLastError()));
- CloseHandle(hToken);
- return FALSE;
- }
-
- NewArrayHolder<BYTE> pvBuffer = new (nothrow) BYTE[dwRetLen];
- if (pvBuffer == NULL)
- {
- SetLastError(E_OUTOFMEMORY);
- return FALSE;
- }
-
- if (!GetTokenInformation(hToken, TokenUser, reinterpret_cast<LPVOID>((BYTE*)pvBuffer), dwRetLen, &dwRetLen)) {
- SNLOG((W("Failed to acquire token information, error %08X\n"), GetLastError()));
- CloseHandle(hToken);
- return FALSE;
- }
-
- pUser = reinterpret_cast<TOKEN_USER *>(pvBuffer.GetValue());
-
- // Get the user and domain names.
- cchUser = sizeof(wszUser) / sizeof(WCHAR);
- cchDomain = sizeof(wszDomain) / sizeof(WCHAR);
- if (!WszLookupAccountSid(NULL, pUser->User.Sid,
- wszUser, &cchUser,
- wszDomain, &cchDomain,
- &eSidUse)) {
- SNLOG((W("Failed to lookup account information, error %08X\n"), GetLastError()));
- CloseHandle(hToken);
- return FALSE;
- }
-
- CloseHandle(hToken);
-
- // Concatenate user and domain name to get a fully qualified account name.
- if (((wcslen(wszUser) + wcslen(wszDomain) + 2) * sizeof(WCHAR)) > sizeof(wszDomain)) {
- SNLOG((W("Fully qualified account name was too long\n")));
- return FALSE;
- }
- wcscat_s(wszDomain, COUNTOF(wszDomain), W("\\"));
- wcscat_s(wszDomain, COUNTOF(wszDomain), wszUser);
- SNLOG((W("Current username is '%s'\n"), wszDomain));
-
- // Check current user against each name in the multi-string (packed
- // list of nul terminated strings terminated with an additional nul).
- wszUserEntry = mszUserList;
- while (*wszUserEntry) {
- if (!SString::_wcsicmp(wszDomain, wszUserEntry))
- return TRUE;
- wszUserEntry += wcslen(wszUserEntry) + 1;
- }
-
- // No user name match, fail search.
- SNLOG((W("No username match\n")));
-
- return FALSE;
-}
-
-#ifdef FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED
-// See if there's a verification records for the given assembly.
-SN_VER_REC *GetVerificationRecord(__in_z __deref LPWSTR wszAssemblyName, PublicKeyBlob *pPublicKey)
-{
- SN_VER_REC *pVerRec;
- SN_VER_REC *pWildcardVerRec = NULL;
- LPWSTR pAssembly = NULL;
- BYTE *pbToken;
- DWORD cbToken;
- WCHAR wszStrongName[(SN_SIZEOF_TOKEN * 2) + 1];
- DWORD i;
-
- // Compress the public key to make for a shorter assembly name.
- if (!StrongNameTokenFromPublicKey((BYTE*)pPublicKey,
- SN_SIZEOF_KEY(pPublicKey),
- &pbToken,
- &cbToken))
- return NULL;
-
- if (cbToken > SN_SIZEOF_TOKEN)
- return NULL;
-
- // Turn the token into hex.
- for (i = 0; i < cbToken; i++) {
- static WCHAR *wszHex = W("0123456789ABCDEF");
- wszStrongName[(i * 2) + 0] = wszHex[(pbToken[i] >> 4)];
- wszStrongName[(i * 2) + 1] = wszHex[(pbToken[i] & 0x0F)];
- }
- wszStrongName[i * 2] = W('\0');
- delete[] pbToken;
-
- // Build the full assembly name.
-
- size_t nLen = wcslen(wszAssemblyName) + wcslen(W(",")) + wcslen(wszStrongName);
- pAssembly = new (nothrow) WCHAR[nLen +1]; // +1 for NULL
- if (pAssembly == NULL)
- return NULL;
- wcscpy_s(pAssembly, nLen + 1, wszAssemblyName);
- wcscat_s(pAssembly, nLen + 1, W(","));
- wcscat_s(pAssembly, nLen + 1, wszStrongName);
-
- // Iterate over global list of verification records.
- for (pVerRec = g_pVerificationRecords; pVerRec; pVerRec = pVerRec->m_pNext) {
- // Look for matching assembly name.
- if (!SString::_wcsicmp(pAssembly, pVerRec->m_wszAssembly)) {
- delete[] pAssembly;
- // Check current user against allowed user name list.
- if (IsValidUser(pVerRec->m_mszUserList))
- return pVerRec;
- else
- return NULL;
- } else if (!wcscmp(W("*,*"), pVerRec->m_wszAssembly)) {
- // Found a wildcard record, it'll do if we don't find something more
- // specific.
- if (pWildcardVerRec == NULL)
- pWildcardVerRec = pVerRec;
- } else if (!wcsncmp(W("*,"), pVerRec->m_wszAssembly, 2)) {
- // Found a wildcard record (with a specific strong name). If the
- // strong names match it'll do unless we find something more
- // specific (it overrides "*,*" wildcards though).
- if (!SString::_wcsicmp(wszStrongName, &pVerRec->m_wszAssembly[2]))
- pWildcardVerRec = pVerRec;
- }
- }
-
- delete[] pAssembly;
-
- // No match on specific assembly name, see if there's a wildcard entry.
- if (pWildcardVerRec)
- // Check current user against allowed user name list.
- if (IsValidUser(pWildcardVerRec->m_mszUserList))
- return pWildcardVerRec;
- else
- return NULL;
-
- return NULL;
-}
-#endif // FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED
-
-HRESULT
-CallGetMetaDataInternalInterface(
- LPVOID pData,
- ULONG cbData,
- DWORD flags,
- REFIID riid,
- LPVOID *ppInterface)
-{
-#ifdef FEATURE_STRONGNAME_STANDALONE_WINRT
- return E_NOTIMPL;
-#elif STRONGNAME_IN_VM || !FEATURE_STANDALONE_SN
- // We link the GetMetaDataInternalInterface, so just call it
- return GetMetaDataInternalInterface(
- pData,
- cbData,
- flags,
- riid,
- ppInterface);
-#elif FEATURE_CORECLR
- return E_NOTIMPL;
-#else
-
- // We late bind the metadata function to avoid having a direct dependence on
- // mscoree.dll unless we absolutely need to.
-
- HRESULT hr = S_OK;
- ICLRMetaHost *pCLRMetaHost = NULL;
- ICLRRuntimeInfo *pCLRRuntimeInfo = NULL;
- ICLRRuntimeHostInternal *pCLRRuntimeHostInternal = NULL;
-
- HMODULE hLibrary = WszLoadLibrary(MSCOREE_SHIM_W);
- if (hLibrary == NULL)
- {
- hr = HRESULT_FROM_GetLastError();
- SNLOG((W("WszLoadLibrary(\"") MSCOREE_SHIM_W W("\") failed with %08x\n"), hr));
- goto ErrExit;
- }
-
- typedef HRESULT (__stdcall *PFNCLRCreateInstance)(REFCLSID clsid, REFIID riid, /*iid_is(riid)*/ LPVOID *ppInterface);
- PFNCLRCreateInstance pfnCLRCreateInstance = reinterpret_cast<PFNCLRCreateInstance>(GetProcAddress(
- hLibrary,
- "CLRCreateInstance"));
- if (pfnCLRCreateInstance == NULL)
- {
- hr = HRESULT_FROM_GetLastError();
- SNLOG((W("Couldn't find CLRCreateInstance() in ") MSCOREE_SHIM_W W(": %08x\n"), hr));
- goto ErrExit;
- }
-
- if (FAILED(hr = pfnCLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID *)&pCLRMetaHost)))
- {
- SNLOG((W("Error calling CLRCreateInstance() in ") MSCOREE_SHIM_W W(": %08x\n"), hr));
- goto ErrExit;
- }
-
- if (FAILED(hr = pCLRMetaHost->GetRuntime(
- W("v") VER_PRODUCTVERSION_NO_QFE_STR_L,
- IID_ICLRRuntimeInfo,
- (LPVOID *)&pCLRRuntimeInfo)))
- {
- SNLOG((W("Error calling ICLRMetaHost::GetRuntime() in ") MSCOREE_SHIM_W W(": %08x\n"), hr));
- goto ErrExit;
- }
-
- if (FAILED(hr = pCLRRuntimeInfo->GetInterface(
- CLSID_CLRRuntimeHostInternal,
- IID_ICLRRuntimeHostInternal,
- (LPVOID *)&pCLRRuntimeHostInternal)))
- {
- SNLOG((W("Error calling ICLRRuntimeInfo::GetInterface() in ") MSCOREE_SHIM_W W(": %08x\n"), hr));
- goto ErrExit;
- }
-
- hr = pCLRRuntimeHostInternal->GetMetaDataInternalInterface(
- (BYTE *)pData,
- cbData,
- flags,
- riid,
- ppInterface);
-
-ErrExit:
- if (pCLRMetaHost != NULL)
- {
- pCLRMetaHost->Release();
- }
- if (pCLRRuntimeInfo != NULL)
- {
- pCLRRuntimeInfo->Release();
- }
- if (pCLRRuntimeHostInternal != NULL)
- {
- pCLRRuntimeHostInternal->Release();
- }
-
- return hr;
-
-#endif
-} // CallGetMetaDataInternalInterface
-
-// Load metadata engine and return an importer.
-HRESULT
-GetMetadataImport(
- __in const SN_LOAD_CTX *pLoadCtx,
- __in mdAssembly *ptkAssembly,
- __out IMDInternalImport **ppMetaDataImport)
-{
- HRESULT hr = E_FAIL;
- BYTE *pMetaData = NULL;
-
- // Locate the COM+ meta data within the header.
- if (pLoadCtx->m_pedecoder->CheckCorHeader())
- {
- pMetaData = (BYTE *)pLoadCtx->m_pedecoder->GetMetadata();
- }
-
- if (pMetaData == NULL)
- {
- SNLOG((W("Couldn't locate the COM+ header\n")));
- return CORSEC_E_INVALID_IMAGE_FORMAT;
- }
-
- // Open a metadata scope on the memory directly.
- ReleaseHolder<IMDInternalImport> pMetaDataImportHolder;
- if (FAILED(hr = CallGetMetaDataInternalInterface(
- pMetaData,
- VAL32(pLoadCtx->m_pCorHeader->MetaData.Size),
- ofRead,
- IID_IMDInternalImport,
- &pMetaDataImportHolder)))
- {
- SNLOG((W("GetMetaDataInternalInterface() failed with %08x\n"), hr));
- return SubstituteErrorIfNotTransient(hr, CORSEC_E_INVALID_IMAGE_FORMAT);
- }
-
- // Determine the metadata token for the assembly from the scope.
- if (FAILED(hr = pMetaDataImportHolder->GetAssemblyFromScope(ptkAssembly)))
- {
- SNLOG((W("pMetaData->GetAssemblyFromScope() failed with %08x\n"), hr));
- return SubstituteErrorIfNotTransient(hr, CORSEC_E_INVALID_IMAGE_FORMAT);
- }
-
- *ppMetaDataImport = pMetaDataImportHolder.Extract();
- return S_OK;
-}
-#if STRONGNAME_IN_VM
-// Function to form the fully qualified assembly name from the load context
-BOOL FormFullyQualifiedAssemblyName(SN_LOAD_CTX *pLoadCtx, SString &assemblyName)
-{
- mdAssembly tkAssembly;
- // Open a metadata scope on the image.
- ReleaseHolder<IMDInternalImport> pMetaDataImport;
- HRESULT hr;
- if (FAILED(hr = GetMetadataImport(pLoadCtx, &tkAssembly, &pMetaDataImport)))
- return FALSE;
-
- if (pMetaDataImport != NULL)
- {
- PEAssembly::GetFullyQualifiedAssemblyName(pMetaDataImport, tkAssembly, assemblyName);
- return TRUE;
- }
- return FALSE;
-}
-#endif
-
-
-// Locate the public key blob located within the metadata of an assembly file
-// and return a copy (use delete to deallocate). Optionally get the assembly
-// name as well.
-HRESULT FindPublicKey(const SN_LOAD_CTX *pLoadCtx,
- __out_ecount_opt(cchAssemblyName) LPWSTR wszAssemblyName,
- DWORD cchAssemblyName,
- __out PublicKeyBlob **ppPublicKey,
- DWORD *pcbPublicKey)
-{
- HRESULT hr = S_OK;
- *ppPublicKey = NULL;
-
- // Open a metadata scope on the image.
- mdAssembly tkAssembly;
- ReleaseHolder<IMDInternalImport> pMetaDataImport;
- if (FAILED(hr = GetMetadataImport(pLoadCtx, &tkAssembly, &pMetaDataImport)))
- return hr;
-
- // Read the public key location from the assembly properties (it's known as
- // the originator property).
- PublicKeyBlob *pKey;
- DWORD dwKeyLen;
- LPCSTR szAssemblyName;
- if (FAILED(hr = pMetaDataImport->GetAssemblyProps(tkAssembly, // [IN] The Assembly for which to get the properties
- (const void **)&pKey, // [OUT] Pointer to the Originator blob
- &dwKeyLen, // [OUT] Count of bytes in the Originator Blob
- NULL, // [OUT] Hash Algorithm
- &szAssemblyName, // [OUT] Buffer to fill with name
- NULL, // [OUT] Assembly MetaData
- NULL))) // [OUT] Flags
- {
- SNLOG((W("Did not get public key property: %08x\n"), hr));
- return SubstituteErrorIfNotTransient(hr, CORSEC_E_MISSING_STRONGNAME);
- }
-
- if (dwKeyLen == 0)
- {
- SNLOG((W("No public key stored in metadata\n")));
- return CORSEC_E_MISSING_STRONGNAME;
- }
-
- // Make a copy of the key blob (because we're going to close the metadata scope).
- NewArrayHolder<BYTE> pKeyCopy(new (nothrow) BYTE[dwKeyLen]);
- if (pKeyCopy == NULL)
- return E_OUTOFMEMORY;
- memcpy_s(pKeyCopy, dwKeyLen, pKey, dwKeyLen);
-
- // Copy the assembly name as well (if it was asked for). We also convert
- // from UTF8 to UNICODE while we're at it.
- if (wszAssemblyName)
- WszMultiByteToWideChar(CP_UTF8, 0, szAssemblyName, -1, wszAssemblyName, cchAssemblyName);
-
- *ppPublicKey = reinterpret_cast<PublicKeyBlob *>(pKeyCopy.Extract());
- if(pcbPublicKey != NULL)
- *pcbPublicKey = dwKeyLen;
-
- return S_OK;
-}
-
-BYTE HexToByte (WCHAR wc) {
- if (!iswxdigit(wc)) return (BYTE) 0xff;
- if (iswdigit(wc)) return (BYTE) (wc - W('0'));
- if (iswupper(wc)) return (BYTE) (wc - W('A') + 10);
- return (BYTE) (wc - W('a') + 10);
-}
-
-// Read the hex string into a PublicKeyBlob structure.
-// Caller owns the blob.
-PublicKeyBlob *GetPublicKeyFromHex(LPCWSTR wszPublicKeyHexString) {
- size_t cchHex = wcslen(wszPublicKeyHexString);
- size_t cbHex = cchHex / 2;
- if (cchHex % 2 != 0)
- return NULL;
-
- BYTE *pKey = new (nothrow) BYTE[cbHex];
- if (!pKey)
- return NULL;
- for (size_t i = 0; i < cbHex; i++) {
- pKey[i] = (BYTE) ((HexToByte(*wszPublicKeyHexString) << 4) | HexToByte(*(wszPublicKeyHexString + 1)));
- wszPublicKeyHexString += 2;
- }
- return (PublicKeyBlob*) pKey;
-}
-
-// Create a temporary key container name likely to be unique to this process and
-// thread. Any existing container with the same name is deleted.
-BOOLEAN GetKeyContainerName(LPCWSTR *pwszKeyContainer, BOOLEAN *pbTempContainer)
-{
- *pbTempContainer = FALSE;
-
- if (*pwszKeyContainer != NULL)
- return TRUE;
-
- GUID guid;
- HRESULT hr = CoCreateGuid(&guid);
- if (FAILED(hr)) {
- SetStrongNameErrorInfo(hr);
- return FALSE;
- }
-
- WCHAR wszGuid[64];
- if (GuidToLPWSTR(guid, wszGuid, sizeof(wszGuid) / sizeof(WCHAR)) == 0) {
- SetStrongNameErrorInfo(E_UNEXPECTED); // this operation should never fail
- return FALSE;
- }
-
- // Name is of form '__MSCORSN__<guid>__' where <guid> is a GUID.
- const size_t cchLengthOfKeyContainer = sizeof("__MSCORSN____") + (sizeof(wszGuid) / sizeof(WCHAR)) + 1 /* null */;
- LPWSTR wszKeyContainer = new (nothrow) WCHAR[cchLengthOfKeyContainer];
- if (wszKeyContainer == NULL) {
- SetStrongNameErrorInfo(E_OUTOFMEMORY);
- return FALSE;
- }
-
- _snwprintf_s(wszKeyContainer, cchLengthOfKeyContainer - 1 /* exclude null */, _TRUNCATE,
- W("__MSCORSN__%s__"),
- wszGuid);
-
- // Delete any stale container with the same name.
- LocateCSP(wszKeyContainer, SN_DELETE_CONTAINER);
-
- SNLOG((W("Creating temporary key container name '%s'\n"), wszKeyContainer));
-
- *pwszKeyContainer = wszKeyContainer;
- *pbTempContainer = TRUE;
-
- return TRUE;
-}
-
-
-// Free resources allocated by GetKeyContainerName and delete the named
-// container.
-VOID FreeKeyContainerName(LPCWSTR wszKeyContainer, BOOLEAN bTempContainer)
-{
- if (bTempContainer) {
- // Free the name.
- delete [] (WCHAR*)wszKeyContainer;
- }
-}
-
-static DWORD GetSpecialKeyFlags(PublicKeyBlob* pKey)
-{
- if (SN_IS_THE_KEY(pKey))
- return SN_OUTFLAG_MICROSOFT_SIGNATURE;
-
- return 0;
-}
-
-#ifdef FEATURE_STRONGNAME_MIGRATION
-
-HRESULT VerifyCounterSignature(
- PublicKeyBlob *pSignaturePublicKey,
- ULONG cbSignaturePublicKey,
- PublicKeyBlob *pIdentityPublicKey,
- BYTE *pCounterSignature,
- ULONG cbCounterSignature)
-{
- LIMITED_METHOD_CONTRACT;
-
- HRESULT hr = S_OK;
-
- HandleStrongNameCspHolder hProv(NULL);
- HandleKeyHolder hKey(NULL);
- HandleHashHolder hHash(NULL);
-
- hProv = LocateCSP(NULL, SN_IGNORE_CONTAINER, GET_UNALIGNED_VAL32(&pIdentityPublicKey->HashAlgID), GET_UNALIGNED_VAL32(&pIdentityPublicKey->SigAlgID));
-
- if (!hProv)
- {
- hr = HRESULT_FROM_GetLastError();
- SNLOG((W("Failed to acquire a CSP: %08x"), hr));
- return hr;
- }
-
- if(SN_IS_NEUTRAL_KEY(pIdentityPublicKey))
- {
- pIdentityPublicKey = reinterpret_cast<PublicKeyBlob *>(const_cast<BYTE *>(g_rbTheKey));
- }
-
- BYTE *pbRealPublicKey = pIdentityPublicKey->PublicKey;
- DWORD cbRealPublicKey = GET_UNALIGNED_VAL32(&pIdentityPublicKey->cbPublicKey);
-
- if (!CryptImportKey(hProv, pbRealPublicKey, cbRealPublicKey, 0, 0, &hKey))
- {
- hr = HRESULT_FROM_GetLastError();
- SNLOG((W("Failed to import key: %08x"), hr));
- return hr;
- }
-
- // Create a hash object.
- if (!CryptCreateHash(hProv, GET_UNALIGNED_VAL32(&pIdentityPublicKey->HashAlgID), 0, 0, &hHash))
- {
- hr = HRESULT_FROM_GetLastError();
- SNLOG((W("Failed to create hash: %08x"), hr));
- return hr;
- }
-
- if (!CryptHashData(hHash, (BYTE*)pSignaturePublicKey, cbSignaturePublicKey, 0))
- {
- hr = HRESULT_FROM_GetLastError();
- SNLOG((W("Failed to compute hash: %08x"), hr));
- return hr;
- }
-
-#if defined(_DEBUG) && !defined(DACCESS_COMPILE)
- if (hHash != (HCRYPTHASH)INVALID_HANDLE_VALUE) {
- DWORD cbHash;
- DWORD dwRetLen = sizeof(cbHash);
- if (CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&cbHash, &dwRetLen, 0))
- {
- NewArrayHolder<BYTE> pbHash(new (nothrow) BYTE[cbHash]);
- if (pbHash != NULL)
- {
- if (CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &cbHash, 0))
- {
- SNLOG((W("Computed Hash Value (%u bytes):\n"), cbHash));
- HexDump(pbHash, cbHash);
- }
- else
- {
- SNLOG((W("CryptGetHashParam() failed with %08X\n"), GetLastError()));
- }
- }
- }
- else
- {
- SNLOG((W("CryptGetHashParam() failed with %08X\n"), GetLastError()));
- }
- }
-#endif // _DEBUG
-
- // Verify the hash against the signature.
- //DbgCount(dwInFlags & SN_INFLAG_RUNTIME ? W("RuntimeVerify") : W("FusionVerify"));
- if (pCounterSignature != NULL && cbCounterSignature != 0 &&
- CryptVerifySignatureW(hHash, pCounterSignature, cbCounterSignature, hKey, NULL, 0))
- {
- SNLOG((W("Counter-signature verification succeeded\n")));
- }
- else
- {
- SNLOG((W("Counter-signature verification failed\n")));
- hr = CORSEC_E_INVALID_COUNTERSIGNATURE;
- }
-
- return hr;
-}
-
-HRESULT ParseStringArgs(
- CustomAttributeParser &ca, // The Custom Attribute blob.
- CaArg* pArgs, // Array of argument descriptors.
- ULONG cArgs) // Count of argument descriptors.
-{
- LIMITED_METHOD_CONTRACT;
-
- HRESULT hr = S_OK;
-
- // For each expected arg...
- for (ULONG ix=0; ix<cArgs; ++ix)
- {
- CaArg* pArg = &pArgs[ix];
- if(pArg->type.tag != SERIALIZATION_TYPE_STRING)
- {
- return E_UNEXPECTED; // The blob shouldn't have anything other than strings
- }
- IfFailGo(ca.GetString(&pArg->val.str.pStr, &pArg->val.str.cbStr));
- }
-
-ErrExit:
- return hr;
-}
-
-HRESULT GetVerifiedSignatureKey(__in SN_LOAD_CTX *pLoadCtx, __out PublicKeyBlob **ppPublicKey, __out_opt DWORD *pcbPublicKey)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- mdAssembly tkAssembly;
- ReleaseHolder<IMDInternalImport> pMetaDataImport;
- IfFailRet(GetMetadataImport(pLoadCtx, &tkAssembly, &pMetaDataImport));
-
- HRESULT attributeHr;
- void *pAttribute;
- ULONG cbAttribute;
- hr = pMetaDataImport->GetCustomAttributeByName(tkAssembly, g_AssemblySignatureKeyAttribute, const_cast<const void**>(&pAttribute), &cbAttribute);
-
- if (SUCCEEDED(hr) && hr != S_FALSE)
- {
- CustomAttributeParser parser(pAttribute, cbAttribute);
- IfFailRet(parser.ValidateProlog());
-
- CaType caTypeString;
- caTypeString.Init(SERIALIZATION_TYPE_STRING);
-
- CaArg args[2];
-
- CaArg* argPublicKey = &args[0];
- argPublicKey->Init(caTypeString);
-
- CaArg* argCounterSignature = &args[1];
- argCounterSignature->Init(caTypeString);
-
- IfFailRet(ParseStringArgs(parser, args, lengthof(args)));
-
- StrongNameBufferHolder<PublicKeyBlob> pSignaturePublicKey;
- ULONG cbSignaturePublicKey;
- if (argPublicKey->val.str.pStr == NULL || argPublicKey->val.str.cbStr == 0 ||
- (!GetBytesFromHex(argPublicKey->val.str.pStr, argPublicKey->val.str.cbStr, (BYTE**)(pSignaturePublicKey.GetAddr()), &cbSignaturePublicKey)) ||
- !StrongNameIsValidPublicKey((BYTE*)pSignaturePublicKey.GetValue(), cbSignaturePublicKey, false))
- {
- return CORSEC_E_INVALID_SIGNATUREKEY;
- }
-
- NewArrayHolder<BYTE> pCounterSignature;
- ULONG cbCounterSignature;
- if (argCounterSignature->val.str.pStr == NULL || argCounterSignature->val.str.cbStr == 0 ||
- (!GetBytesFromHex(argCounterSignature->val.str.pStr, argCounterSignature->val.str.cbStr, &pCounterSignature, &cbCounterSignature)))
- {
- return CORSEC_E_INVALID_COUNTERSIGNATURE;
- }
-
- StrongNameBufferHolder<PublicKeyBlob> pIdentityPublicKey = NULL;
- IfFailRet(FindPublicKey(pLoadCtx, NULL, 0, &pIdentityPublicKey));
-
- IfFailRet(VerifyCounterSignature(pSignaturePublicKey, cbSignaturePublicKey, pIdentityPublicKey, pCounterSignature, cbCounterSignature));
-
- *ppPublicKey = pSignaturePublicKey.Extract();
- if (pcbPublicKey != NULL)
- *pcbPublicKey = cbSignaturePublicKey;
- }
- else
- {
- *ppPublicKey = NULL;
- if (pcbPublicKey != NULL)
- *pcbPublicKey = 0;
- }
-
- return hr;
-}
-
-// Checks revocation list against the assembly's public keys.
-// If the identity key has been revoked, then the signature key must be non-null and
-// must be in the replacement keys list to be allowed.
-bool AreKeysAllowedByRevocationList(BYTE* pbAssemblyIdentityKey, DWORD cbAssemblyIdentityKey, BYTE* pbAssemblySignatureKey, DWORD cbAssemblySignatureKey)
-{
- LIMITED_METHOD_CONTRACT;
-
- bool fRevoked = false;
-
- SN_REVOCATION_REC *pRevocationRec = g_pRevocationRecords;
- while (pRevocationRec)
- {
- if (pRevocationRec->m_cbRevokedKey == cbAssemblyIdentityKey &&
- memcmp(pRevocationRec->m_pbRevokedKey, pbAssemblyIdentityKey, cbAssemblyIdentityKey) == 0)
- {
- fRevoked = true; // Identity key can't be trusted.
-
- if (pbAssemblySignatureKey != NULL)
- {
- SN_REPLACEMENT_KEY_REC *pReplacementKeyRec = pRevocationRec->m_pReplacementKeys;
-
- while (pReplacementKeyRec)
- {
- if (pReplacementKeyRec->m_cbReplacementKey == cbAssemblySignatureKey &&
- memcmp(pReplacementKeyRec->m_pbReplacementKey, pbAssemblySignatureKey, cbAssemblySignatureKey) == 0)
- {
- // Signature key was allowed as a replacement for the revoked identity key.
- return true;
- }
-
- pReplacementKeyRec = pReplacementKeyRec->m_pNext;
- }
- }
- // We didn't find the signature key in the list of allowed replacement keys for this record.
- // However, we don't return here, because another record might have the same identity key
- // and allow the signature key as a replacement.
- }
-
- pRevocationRec = pRevocationRec->m_pNext;
- }
-
- return !fRevoked;
-}
-
-#endif // FEATURE_STRONGNAME_MIGRATION
-
-// The common code used to verify a signature (taking into account whether skip
-// verification is enabled for the given assembly).
-HRESULT VerifySignature(__in SN_LOAD_CTX *pLoadCtx, DWORD dwInFlags, PublicKeyBlob *pRealEcmaPublicKey,__out_opt DWORD *pdwOutFlags)
-{
- if (pdwOutFlags)
- *pdwOutFlags = 0;
-
- // Read the public key used to sign the assembly from the assembly metadata.
- // Also get the assembly name, we might need this if we fail the
- // verification and need to look up a verification disablement entry.
- WCHAR wszSimpleAssemblyName[MAX_PATH_FNAME + 1];
- SString strFullyQualifiedAssemblyName;
- BOOL bSuccess = FALSE;
-#if STRONGNAME_IN_VM
- BOOL bAssemblyNameFormed = FALSE;
- BOOL bVerificationBegun = FALSE;
-#endif
-
- HandleKeyHolder hKey(NULL);
- HandleHashHolder hHash(NULL);
- HandleStrongNameCspHolder hProv(NULL);
-
- StrongNameBufferHolder<PublicKeyBlob> pAssemblyIdentityKey;
- DWORD cbAssemblyIdentityKey;
- HRESULT hr = FindPublicKey(pLoadCtx,
- wszSimpleAssemblyName,
- sizeof(wszSimpleAssemblyName) / sizeof(WCHAR),
- &pAssemblyIdentityKey,
- &cbAssemblyIdentityKey);
- if (FAILED(hr))
- return hr;
-
- BOOL isEcmaKey = SN_IS_NEUTRAL_KEY(pAssemblyIdentityKey);
- // If we're handed the ECMA key, we translate it to the real key at this point.
- // Note: gcc gets confused with the complexity of StrongNameBufferHolder<> and
- // won't auto-convert pAssemblyIdentityKey to type PublicKeyBlob*, so cast it explicitly.
- PublicKeyBlob *pRealPublicKey = isEcmaKey ? pRealEcmaPublicKey : static_cast<PublicKeyBlob*>(pAssemblyIdentityKey);
-
-// An assembly can specify a signature public key in an attribute.
-// If one is present, we verify the signature using that public key.
-#ifdef FEATURE_STRONGNAME_MIGRATION
- StrongNameBufferHolder<PublicKeyBlob> pAssemblySignaturePublicKey;
- DWORD cbAssemblySignaturePublicKey;
- IfFailRet(GetVerifiedSignatureKey(pLoadCtx, &pAssemblySignaturePublicKey, &cbAssemblySignaturePublicKey));
- if(hr != S_FALSE) // Attribute was found
- {
- pRealPublicKey = pAssemblySignaturePublicKey;
- }
-
-#endif // FEATURE_STRONGNAME_MIGRATION
-
- DWORD dwSpecialKeys = GetSpecialKeyFlags(pRealPublicKey);
-
- // If this isn't the first time we've been called for this assembly and we
- // know it was fully signed and we're confident it couldn't have been
- // tampered with in the meantime, we can just skip the verification.
- if (!(dwInFlags & SN_INFLAG_FORCE_VER) &&
- !(dwInFlags & SN_INFLAG_INSTALL) &&
- (pLoadCtx->m_pCorHeader->Flags & VAL32(COMIMAGE_FLAGS_STRONGNAMESIGNED)) &&
- ((dwInFlags & SN_INFLAG_ADMIN_ACCESS) || g_fCacheVerify))
- {
- SNLOG((W("Skipping verification due to cached result\n")));
- DbgCount(dwInFlags & SN_INFLAG_RUNTIME ? W("RuntimeSkipCache") : W("FusionSkipCache"));
- return S_OK;
- }
-
-#ifdef FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED
- // If we're not forcing verification, let's see if there's a skip
- // verification entry for this assembly. If there is we can skip all the
- // hard work and just lie about the strong name now. The exception is if the
- // assembly is marked as fully signed, in which case we have to force a
- // verification to see if they're telling the truth.
- StrongNameBufferHolder<PublicKeyBlob> pTestKey = NULL;
- SN_VER_REC *pVerRec = GetVerificationRecord(wszSimpleAssemblyName, pAssemblyIdentityKey);
- if (!(dwInFlags & SN_INFLAG_FORCE_VER) && !(pLoadCtx->m_pCorHeader->Flags & VAL32(COMIMAGE_FLAGS_STRONGNAMESIGNED)))
- {
- if (pVerRec != NULL)
- {
- if (pVerRec->m_wszTestPublicKey)
- {
- // substitute the public key with the test public key.
- pTestKey = GetPublicKeyFromHex(pVerRec->m_wszTestPublicKey);
- if (pTestKey != NULL)
- {
-
- SNLOG((W("Using test public key for verification due to registry entry\n")));
- DbgCount(dwInFlags & SN_INFLAG_RUNTIME ? W("RuntimeSkipDelay") : W("FusionSkipDelay"));
-
- // If the assembly was not ECMA signed, then we need to update the key that it will be
- // verified with as well.
- if (!isEcmaKey)
- {
- // When test signing, there's no way to specify a hash algorithm.
- // So instead of defaulting to SHA1, we pick the algorithm the assembly
- // would've been signed with, if the test key wasn't present.
- // Thus we use the same algorithm when verifying the signature.
- SET_UNALIGNED_VAL32(&pTestKey->HashAlgID, GET_UNALIGNED_VAL32(&pRealPublicKey->HashAlgID));
-
- pRealPublicKey = pTestKey;
- }
- }
- }
- else
- {
- SNLOG((W("Skipping verification due to registry entry\n")));
- DbgCount(dwInFlags & SN_INFLAG_RUNTIME ? W("RuntimeSkipDelay") : W("FusionSkipDelay"));
- if (pdwOutFlags)
- {
- *pdwOutFlags |= dwSpecialKeys;
- }
- return S_OK;
- }
- }
- }
-#endif // FEATURE_STRONGNAME_DELAY_SIGNING_ALLOWED
-
-#ifdef FEATURE_STRONGNAME_MIGRATION
- if(!isEcmaKey) // We should never revoke the ecma key, as it is tied strongly to the runtime
- {
- if(!AreKeysAllowedByRevocationList((BYTE*)pAssemblyIdentityKey.GetValue(), cbAssemblyIdentityKey, (BYTE*)pAssemblySignaturePublicKey.GetValue(), cbAssemblySignaturePublicKey))
- {
- if(pAssemblySignaturePublicKey == NULL)
- {
- SNLOG((W("Verification failed. Assembly public key has been revoked\n")));
- }
- else
- {
- SNLOG((W("Verification failed. Assembly identity key has been revoked, an the assembly signature key isn't in the replacement key list\n")));
- }
-
- hr = CORSEC_E_INVALID_STRONGNAME;
- goto Error;
- }
- }
-
-#endif // FEATURE_STRONGNAME_MIGRATION
-
-#ifdef FEATURE_CORECLR
- // TritonTODO: check with security team on this
- if (pLoadCtx->m_pbSignature == NULL)
- {
- hr = CORSEC_E_MISSING_STRONGNAME;
- goto Error;
- }
-#endif //FEATURE_CORECLR
-
-#if STRONGNAME_IN_VM
- bVerificationBegun = TRUE;
- // SN verification start event
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_SECURITY_KEYWORD))
- {
- // form the fully qualified assembly name using the load context
- bAssemblyNameFormed = FormFullyQualifiedAssemblyName(pLoadCtx, strFullyQualifiedAssemblyName);
- if(bAssemblyNameFormed)
- {
- ETW::SecurityLog::StrongNameVerificationStart(dwInFlags,(LPWSTR)strFullyQualifiedAssemblyName.GetUnicode());
- }
- }
-#endif // STRONGNAME_IN_VM
-
- ALG_ID uHashAlgId = GET_UNALIGNED_VAL32(&pRealPublicKey->HashAlgID);
- ALG_ID uSignAlgId = GET_UNALIGNED_VAL32(&pRealPublicKey->SigAlgID);
-
- // Default hashing and signing algorithm IDs if necessary.
- if (uHashAlgId == 0)
- uHashAlgId = CALG_SHA1;
- if (uSignAlgId == 0)
- uSignAlgId = CALG_RSA_SIGN;
-
- // Find a CSP supporting the required algorithms.
- hProv = LocateCSP(NULL, SN_IGNORE_CONTAINER, uHashAlgId, uSignAlgId);
- if (!hProv)
- {
- hr = HRESULT_FROM_GetLastError();
- SNLOG((W("Failed to acquire a CSP: %08x"), hr));
- goto Error;
- }
-
- BYTE *pbRealPublicKey;
- pbRealPublicKey = pRealPublicKey->PublicKey;
- DWORD cbRealPublicKey;
- cbRealPublicKey = GET_UNALIGNED_VAL32(&pRealPublicKey->cbPublicKey);
-
- if (!CryptImportKey(hProv, pbRealPublicKey, cbRealPublicKey, 0, 0, &hKey))
- {
- hr = HRESULT_FROM_GetLastError();
- SNLOG((W("Failed to import key: %08x"), hr));
- goto Error;
- }
-
- // Create a hash object.
-
- if (!CryptCreateHash(hProv, uHashAlgId, 0, 0, &hHash))
- {
- hr = HRESULT_FROM_GetLastError();
- SNLOG((W("Failed to create hash: %08x"), hr));
- goto Error;
- }
-
- // Compute a hash over the image.
- if (!ComputeHash(pLoadCtx, hHash, CalcHash, NULL))
- {
- hr = HRESULT_FROM_GetLastError();
- SNLOG((W("Failed to compute hash: %08x"), hr));
- goto Error;
- }
-
- // Verify the hash against the signature.
- DbgCount(dwInFlags & SN_INFLAG_RUNTIME ? W("RuntimeVerify") : W("FusionVerify"));
- if (pLoadCtx->m_pbSignature != NULL && pLoadCtx->m_cbSignature != 0 &&
- CryptVerifySignatureW(hHash, pLoadCtx->m_pbSignature, pLoadCtx->m_cbSignature, hKey, NULL, 0))
- {
- SNLOG((W("Verification succeeded (for real)\n")));
- if (pdwOutFlags)
- {
- *pdwOutFlags |= dwSpecialKeys | SN_OUTFLAG_WAS_VERIFIED;
- }
- bSuccess = TRUE;
- }
- else
- {
- SNLOG((W("Verification failed\n")));
- hr = CORSEC_E_INVALID_STRONGNAME;
- }
-
-Error:
-
-#if STRONGNAME_IN_VM
- // SN verification end event
- if(bVerificationBegun &&
- ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, TRACE_LEVEL_VERBOSE, CLR_SECURITY_KEYWORD))
- {
- // form the fully qualified assembly name using the load context if it has not yet been formed
- if(!bAssemblyNameFormed)
- {
- strFullyQualifiedAssemblyName.Clear();
- bAssemblyNameFormed = FormFullyQualifiedAssemblyName(pLoadCtx, strFullyQualifiedAssemblyName);
- }
- if(bAssemblyNameFormed)
- {
- ETW::SecurityLog::StrongNameVerificationStop(dwInFlags,(ULONG)hr, (LPWSTR)strFullyQualifiedAssemblyName.GetUnicode());
- }
- }
-#endif // STRONGNAME_IN_VM
-
- if (bSuccess)
- return S_OK;
- else
- return hr;
-}
-
-// Compute a hash over the elements of an assembly manifest file that should
-// remain static (skip checksum, Authenticode signatures and strong name
-// signature blob).
-// This function can also be used to get the blob of bytes that would be
-// hashed without actually hashing.
-BOOLEAN ComputeHash(SN_LOAD_CTX *pLoadCtx, HCRYPTHASH hHash, HashFunc func, void* cookie)
-{
- union {
- IMAGE_NT_HEADERS32 m_32;
- IMAGE_NT_HEADERS64 m_64;
- } sHeaders;
- IMAGE_SECTION_HEADER *pSections;
- ULONG i;
- BYTE *pbSig = pLoadCtx->m_pbSignature;
- DWORD cbSig = pLoadCtx->m_cbSignature;
-
-#define LIMIT_CHECK(_start, _length, _fileStart, _fileLength) \
- do { if (((_start) < (_fileStart)) || \
- (((_start)+(_length)) < (_start)) || \
- (((_start)+(_length)) < (_fileStart)) || \
- (((_start)+(_length)) > ((_fileStart)+(_fileLength))) ) \
- { SetLastError(CORSEC_E_INVALID_IMAGE_FORMAT); return FALSE; } } while (false)
-
-#define FILE_LIMIT_CHECK(_start, _length) LIMIT_CHECK(_start, _length, pLoadCtx->m_pbBase, pLoadCtx->m_dwLength)
-
-#define SN_HASH(_start, _length) do { if (!func(hHash, (_start), (_length), 0, cookie)) return FALSE; } while (false)
-
-#define SN_CHECK_AND_HASH(_start, _length) do { FILE_LIMIT_CHECK(_start, _length); SN_HASH(_start, _length); } while (false)
-
- // Make sure the file size doesn't wrap around.
- if (pLoadCtx->m_pbBase + pLoadCtx->m_dwLength <= pLoadCtx->m_pbBase)
- {
- SetLastError(CORSEC_E_INVALID_IMAGE_FORMAT);
- return FALSE;
- }
-
- // Make sure the signature is completely contained within the file.
- FILE_LIMIT_CHECK(pbSig, cbSig);
-
- // Hash the DOS header if it exists.
- if ((BYTE*)pLoadCtx->m_pNtHeaders != pLoadCtx->m_pbBase)
- SN_CHECK_AND_HASH(pLoadCtx->m_pbBase, (DWORD)((BYTE*)pLoadCtx->m_pNtHeaders - pLoadCtx->m_pbBase));
-
- // Add image headers minus the checksum and security data directory.
- if (pLoadCtx->m_pNtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC)) {
- sHeaders.m_32 = *((IMAGE_NT_HEADERS32*)pLoadCtx->m_pNtHeaders);
- sHeaders.m_32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress = 0;
- sHeaders.m_32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size = 0;
- sHeaders.m_32.OptionalHeader.CheckSum = 0;
- SN_HASH((BYTE*)&sHeaders.m_32, sizeof(sHeaders.m_32));
- } else if (pLoadCtx->m_pNtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR64_MAGIC)) {
- sHeaders.m_64 = *((IMAGE_NT_HEADERS64*)pLoadCtx->m_pNtHeaders);
- sHeaders.m_64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress = 0;
- sHeaders.m_64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size = 0;
- sHeaders.m_64.OptionalHeader.CheckSum = 0;
- SN_HASH((BYTE*)&sHeaders.m_64, sizeof(sHeaders.m_64));
- } else {
- SetLastError(CORSEC_E_INVALID_IMAGE_FORMAT);
- return FALSE;
- }
-
- // Then the section headers.
- pSections = IMAGE_FIRST_SECTION(pLoadCtx->m_pNtHeaders);
- SN_CHECK_AND_HASH((BYTE*)pSections, VAL16(pLoadCtx->m_pNtHeaders->FileHeader.NumberOfSections) * sizeof(IMAGE_SECTION_HEADER));
-
- // Finally, add data from each section.
- for (i = 0; i < VAL16(pLoadCtx->m_pNtHeaders->FileHeader.NumberOfSections); i++) {
- BYTE *pbData = pLoadCtx->m_pbBase + VAL32(pSections[i].PointerToRawData);
- DWORD cbData = VAL32(pSections[i].SizeOfRawData);
-
- // We need to exclude the strong name signature blob from the hash. The
- // blob could intersect the section in a number of ways.
-
- if ((pbSig + cbSig) <= pbData || pbSig >= (pbData + cbData))
- // No intersection at all. Hash all data.
- SN_CHECK_AND_HASH(pbData, cbData);
- else if (pbSig == pbData && cbSig == cbData)
- // Signature consumes entire block. Hash no data.
- ;
- else if (pbSig == pbData)
- // Signature at start. Hash end.
- SN_CHECK_AND_HASH(pbData + cbSig, cbData - cbSig);
- else if ((pbSig + cbSig) == (pbData + cbData))
- // Signature at end. Hash start.
- SN_CHECK_AND_HASH(pbData, cbData - cbSig);
- else {
- // Signature in the middle. Hash head and tail.
- SN_CHECK_AND_HASH(pbData, (DWORD)(pbSig - pbData));
- SN_CHECK_AND_HASH(pbSig + cbSig, cbData - (DWORD)(pbSig + cbSig - pbData));
- }
- }
-
-#if defined(_DEBUG) && !defined(DACCESS_COMPILE)
- if (hHash != (HCRYPTHASH)INVALID_HANDLE_VALUE) {
- DWORD cbHash;
- DWORD dwRetLen = sizeof(cbHash);
- if (CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&cbHash, &dwRetLen, 0))
- {
- NewArrayHolder<BYTE> pbHash(new (nothrow) BYTE[cbHash]);
- if (pbHash != NULL)
- {
- if (CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &cbHash, 0))
- {
- SNLOG((W("Computed Hash Value (%u bytes):\n"), cbHash));
- HexDump(pbHash, cbHash);
- }
- else
- {
- SNLOG((W("CryptGetHashParam() failed with %08X\n"), GetLastError()));
- }
- }
- }
- else
- {
- SNLOG((W("CryptGetHashParam() failed with %08X\n"), GetLastError()));
- }
- }
-#endif // _DEBUG
-
- return TRUE;
-
-#undef SN_CHECK_AND_HASH
-#undef SN_HASH
-#undef FILE_LIMIT_CHECK
-#undef LIMIT_CHECK
-}
-
-
-SNAPI_(DWORD) GetHashFromAssemblyFile(LPCSTR szFilePath, // [IN] location of file to be hashed
- unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default)
- BYTE *pbHash, // [OUT] hash buffer
- DWORD cchHash, // [IN] max size of buffer
- DWORD *pchHash) // [OUT] length of hash byte array
-{
- BOOL retVal = FALSE;
-
- BEGIN_ENTRYPOINT_NOTHROW;
- // Convert filename to wide characters and call the W version of this
- // function.
-
- MAKE_WIDEPTR_FROMANSI(wszFilePath, szFilePath);
- retVal = GetHashFromAssemblyFileW(wszFilePath, piHashAlg, pbHash, cchHash, pchHash);
- END_ENTRYPOINT_NOTHROW;
- return retVal;
-}
-
-SNAPI_(DWORD) GetHashFromAssemblyFileW(LPCWSTR wszFilePath, // [IN] location of file to be hashed
- unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default)
- BYTE *pbHash, // [OUT] hash buffer
- DWORD cchHash, // [IN] max size of buffer
- DWORD *pchHash) // [OUT] length of hash byte array
-{
- HRESULT hr;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- SN_LOAD_CTX sLoadCtx;
- BYTE *pbMetaData = NULL;
- DWORD cbMetaData;
-
- sLoadCtx.m_fReadOnly = TRUE;
- if (!LoadAssembly(&sLoadCtx, wszFilePath, 0, FALSE))
- IfFailGo(HRESULT_FROM_GetLastError());
-
- if (sLoadCtx.m_pedecoder->CheckCorHeader())
- {
- pbMetaData = (BYTE *)sLoadCtx.m_pedecoder->GetMetadata();
- }
- if (pbMetaData == NULL) {
- UnloadAssembly(&sLoadCtx);
- IfFailGo(E_INVALIDARG);
- }
- cbMetaData = VAL32(sLoadCtx.m_pCorHeader->MetaData.Size);
-
- hr = GetHashFromBlob(pbMetaData, cbMetaData, piHashAlg, pbHash, cchHash, pchHash);
-
- UnloadAssembly(&sLoadCtx);
-ErrExit:
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-SNAPI_(DWORD) GetHashFromFile(LPCSTR szFilePath, // [IN] location of file to be hashed
- unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default)
- BYTE *pbHash, // [OUT] hash buffer
- DWORD cchHash, // [IN] max size of buffer
- DWORD *pchHash) // [OUT] length of hash byte array
-{
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- HANDLE hFile = CreateFileA(szFilePath,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
- NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- {
- hr = HRESULT_FROM_GetLastError();
- }
- else
- {
- hr = GetHashFromHandle(hFile, piHashAlg, pbHash, cchHash, pchHash);
- CloseHandle(hFile);
- }
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-SNAPI_(DWORD) GetHashFromFileW(LPCWSTR wszFilePath, // [IN] location of file to be hashed
- unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default)
- BYTE *pbHash, // [OUT] hash buffer
- DWORD cchHash, // [IN] max size of buffer
- DWORD *pchHash) // [OUT] length of hash byte array
-{
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- HANDLE hFile = WszCreateFile(wszFilePath,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
- NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- IfFailGo(HRESULT_FROM_GetLastError());
-
- hr = GetHashFromHandle(hFile, piHashAlg, pbHash, cchHash, pchHash);
- CloseHandle(hFile);
-ErrExit:
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-SNAPI_(DWORD) GetHashFromHandle(HANDLE hFile, // [IN] handle of file to be hashed
- unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default)
- BYTE *pbHash, // [OUT] hash buffer
- DWORD cchHash, // [IN] max size of buffer
- DWORD *pchHash) // [OUT] length of hash byte array
-{
- HRESULT hr;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- PBYTE pbBuffer = NULL;
- DWORD dwFileLen = SafeGetFileSize(hFile, 0);
- if (dwFileLen == 0xffffffff)
- IfFailGo(HRESULT_FROM_GetLastError());
-
- if (SetFilePointer(hFile, 0, NULL, FILE_BEGIN) == 0xFFFFFFFF)
- IfFailGo(HRESULT_FROM_GetLastError());
-
- DWORD dwResultLen;
- pbBuffer = new (nothrow) BYTE[dwFileLen];
- IfNullGo(pbBuffer);
-
- if (ReadFile(hFile, pbBuffer, dwFileLen, &dwResultLen, NULL))
- hr = GetHashFromBlob(pbBuffer, dwResultLen, piHashAlg, pbHash, cchHash, pchHash);
- else
- hr = HRESULT_FROM_GetLastError();
-
- delete[] pbBuffer;
-
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-SNAPI_(DWORD) GetHashFromBlob(BYTE *pbBlob, // [IN] pointer to memory block to hash
- DWORD cchBlob, // [IN] length of blob
- unsigned int *piHashAlg, // [IN/OUT] constant specifying the hash algorithm (set to 0 if you want the default)
- BYTE *pbHash, // [OUT] hash buffer
- DWORD cchHash, // [IN] max size of buffer
- DWORD *pchHash) // [OUT] length of hash byte array
-{
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- HandleStrongNameCspHolder hProv(NULL);
- CapiHashHolder hHash(NULL);
-
- if (!piHashAlg || !pbHash || !pchHash)
- IfFailGo(E_INVALIDARG);
-
- if (!(*piHashAlg))
- *piHashAlg = CALG_SHA1;
-
- *pchHash = cchHash;
-
- hProv = LocateCSP(NULL, SN_IGNORE_CONTAINER, *piHashAlg);
-
- if (!hProv ||
- (!CryptCreateHash(hProv, *piHashAlg, 0, 0, &hHash)) ||
- (!CryptHashData(hHash, pbBlob, cchBlob, 0)) ||
- (!CryptGetHashParam(hHash, HP_HASHVAL, pbHash, pchHash, 0)))
- hr = HRESULT_FROM_GetLastError();
-
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-#endif // #ifndef DACCESS_COMPILE
-
-#else // !defined(FEATURE_CORECLR)
#define InitStrongName() S_OK
-#endif // !defined(FEATURE_CORECLR)
-
// Free buffer allocated by routines below.
SNAPI_(VOID) StrongNameFreeBuffer(BYTE *pbMemory) // [in] address of memory to free
@@ -4695,12 +219,6 @@ SN_THREAD_CTX *GetThreadContext()
if (pThreadCtx == NULL)
return NULL;
pThreadCtx->m_dwLastError = S_OK;
-#if !defined(FEATURE_CORECLR)
- for (ULONG i = 0; i < CachedCspCount; i++)
- {
- pThreadCtx->m_hProv[i] = NULL;
- }
-#endif // !FEATURE_CORECLR
EX_TRY {
ClrFlsSetValue(TlsIdx_StrongName, pThreadCtx);
@@ -4760,18 +278,8 @@ SNAPI StrongNameTokenFromPublicKey(BYTE *pbPublicKeyBlob, // [in] publ
#ifndef DACCESS_COMPILE
-#ifndef FEATURE_CORECLR
- HCRYPTPROV hProv = NULL;
- HCRYPTHASH hHash = NULL;
- HCRYPTKEY hKey = NULL;
- DWORD dwHashLen;
- DWORD dwRetLen;
- NewArrayHolder<BYTE> pHash(NULL);
-#else // !FEATURE_CORECLR
SHA1Hash sha1;
BYTE *pHash = NULL;
-#endif // !FEATURE_CORECLR
-
DWORD i;
DWORD cbKeyBlob;
PublicKeyBlob *pPublicKey = NULL;
@@ -4814,7 +322,7 @@ SNAPI StrongNameTokenFromPublicKey(BYTE *pbPublicKeyBlob, // [in] publ
retVal = TRUE;
goto Exit;
}
-#ifdef FEATURE_CORECLR
+
if (SN_IS_THE_SILVERLIGHT_PLATFORM_KEY(pbPublicKeyBlob))
{
memcpy_s(*ppbStrongNameToken, *pcbStrongNameToken, SN_THE_SILVERLIGHT_PLATFORM_KEYTOKEN(), SN_SIZEOF_TOKEN);
@@ -4846,7 +354,6 @@ SNAPI StrongNameTokenFromPublicKey(BYTE *pbPublicKeyBlob, // [in] publ
}
#endif //FEATURE_WINDOWSPHONE
-#endif //FEATURE_CORECLR
// To compute the correct public key token, we need to make sure the public key blob
// was not padded with extra bytes that CAPI CryptImportKey would've ignored.
@@ -4876,79 +383,11 @@ SNAPI StrongNameTokenFromPublicKey(BYTE *pbPublicKeyBlob, // [in] publ
goto Error;
}
-#ifndef FEATURE_CORECLR
-
- // Look for a CSP to hash the public key.
- hProv = LocateCSP(NULL, SN_HASH_SHA1_ONLY);
- if (!hProv)
- goto Error;
-
- if (!CryptImportKey(hProv,
- pPublicKey->PublicKey,
- GET_UNALIGNED_VAL32(&pPublicKey->cbPublicKey),
- 0,
- 0,
- &hKey))
- goto Error;
-
- cbKeyBlob = sizeof(DWORD);
- if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, NULL, &cbKeyBlob))
- goto Error;
-
- if ((offsetof(PublicKeyBlob, PublicKey) + cbKeyBlob) != cbPublicKeyBlob) {
- SetLastError(CORSEC_E_INVALID_PUBLICKEY);
- goto Error;
- }
-
- // Create a hash object.
- if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
- goto Error;
-
- // Compute a hash over the public key.
- if (!CryptHashData(hHash, pbPublicKeyBlob, cbPublicKeyBlob, 0))
- goto Error;
-
- // Get the length of the hash.
- dwRetLen = sizeof(dwHashLen);
- if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&dwHashLen, &dwRetLen, 0))
- goto Error;
-
- // Allocate a temporary block to hold the hash.
- pHash = new (nothrow) BYTE[dwHashLen];
- if (pHash == NULL)
- {
- SetLastError(E_OUTOFMEMORY);
- goto Error;
- }
-
- // Read the hash value.
- if (!CryptGetHashParam(hHash, HP_HASHVAL, pHash, &dwHashLen, 0))
- goto Error;
-
- // We no longer need the hash object or the provider.
- CryptDestroyHash(hHash);
- CryptDestroyKey(hKey);
- FreeCSP(hProv);
-
- // Take the last few bytes of the hash value for our token. (These are the
- // low order bytes from a network byte order point of view). Reverse the
- // order of these bytes in the output buffer to get host byte order.
- _ASSERTE(dwHashLen >= SN_SIZEOF_TOKEN);
- if (!ClrSafeInt<DWORD>::subtraction(dwHashLen, SN_SIZEOF_TOKEN, dwHashLenMinusTokenSize))
- {
- SetLastError(COR_E_OVERFLOW);
- goto Error;
- }
-
-#else // !FEATURE_CORECLR
-
// Compute a hash over the public key.
sha1.AddData(pbPublicKeyBlob, cbPublicKeyBlob);
pHash = sha1.GetHash();
static_assert(SHA1_HASH_SIZE >= SN_SIZEOF_TOKEN, "SN_SIZEOF_TOKEN must be smaller or equal to the SHA1_HASH_SIZE");
dwHashLenMinusTokenSize = SHA1_HASH_SIZE - SN_SIZEOF_TOKEN;
-
-#endif // !FEATURE_CORECLR
// Take the last few bytes of the hash value for our token. (These are the
// low order bytes from a network byte order point of view). Reverse the
@@ -4961,14 +400,6 @@ SNAPI StrongNameTokenFromPublicKey(BYTE *pbPublicKeyBlob, // [in] publ
Error:
SetStrongNameErrorInfo(HRESULT_FROM_GetLastError());
-#ifndef FEATURE_CORECLR
- if (hHash)
- CryptDestroyHash(hHash);
- if (hKey)
- CryptDestroyKey(hKey);
- if (hProv)
- FreeCSP(hProv);
-#endif // !FEATURE_CORECLR
if (*ppbStrongNameToken) {
delete [] *ppbStrongNameToken;
diff --git a/src/strongname/api/strongnamecoreclr.cpp b/src/strongname/api/strongnamecoreclr.cpp
index 1ed7f0e10c..b02cde3dd9 100644
--- a/src/strongname/api/strongnamecoreclr.cpp
+++ b/src/strongname/api/strongnamecoreclr.cpp
@@ -10,8 +10,6 @@
#include "common.h"
-#if defined(FEATURE_CORECLR)
-
CoreClrCallbacks *GetCoreClrCallbacks();
//
@@ -95,4 +93,3 @@ void InitUtilcode()
InitUtilcode(*GetCoreClrCallbacks());
}
-#endif // FEATURE_CORECLR && !STRONGNAME_IN_VM
diff --git a/src/strongname/api/strongnameinternal.cpp b/src/strongname/api/strongnameinternal.cpp
index 843436772c..56b1c0e031 100644
--- a/src/strongname/api/strongnameinternal.cpp
+++ b/src/strongname/api/strongnameinternal.cpp
@@ -86,7 +86,6 @@ bool StrongNameIsTheKey(__in_ecount(cbKey) const BYTE *pbKey, DWORD cbKey)
return (memcmp(pbKey, g_rbTheKey, sizeof(g_rbTheKey)) == 0);
}
-#ifdef FEATURE_CORECLR
//---------------------------------------------------------------------------------------
//
// Check to see if a public key blob is the Silverlight Platform public key blob
@@ -135,7 +134,6 @@ bool StrongNameIsSilverlightPlatformKey(const PublicKeyBlob &keyPublicKey)
return StrongNameSizeOfPublicKey(keyPublicKey) == sizeof(g_rbTheSilverlightPlatformKey) &&
memcmp(reinterpret_cast<const BYTE *>(&keyPublicKey), g_rbTheSilverlightPlatformKey, sizeof(g_rbTheSilverlightPlatformKey)) == 0;
}
-#endif //FEATURE_CORECLR
//---------------------------------------------------------------------------------------
//
@@ -223,7 +221,7 @@ bool StrongNameIsValidPublicKey(const PublicKeyBlob &keyPublicKey, bool fImportK
return false;
}
-#if !defined(FEATURE_CORECLR) || (defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX))
+#if (defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX))
// Make sure the public key blob imports properly
if (fImportKeys)
{
@@ -239,9 +237,9 @@ bool StrongNameIsValidPublicKey(const PublicKeyBlob &keyPublicKey, bool fImportK
return false;
}
}
-#else // !FEATURE_CORECLR || (CROSSGEN_COMPILE && !PLATFORM_UNIX)
+#else // (CROSSGEN_COMPILE && !PLATFORM_UNIX)
_ASSERTE(!fImportKeys);
-#endif // !FEATURE_CORECLR || (CROSSGEN_COMPILE && !PLATFORM_UNIX)
+#endif // (CROSSGEN_COMPILE && !PLATFORM_UNIX)
return true;
}
@@ -268,7 +266,7 @@ DWORD StrongNameSizeOfPublicKey(const PublicKeyBlob &keyPublicKey)
GET_UNALIGNED_VAL32(&keyPublicKey.cbPublicKey); // the number of bytes in the key
}
-#if !defined(FEATURE_CORECLR) || (defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX))
+#if (defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX))
//---------------------------------------------------------------------------------------
//
@@ -362,10 +360,10 @@ bool StrongNameCryptAcquireContext(HCRYPTPROV *phProv, LPCWSTR pwszContainer, LP
{
dwFlags &= ~CRYPT_MACHINE_KEYSET;
}
-#endif // FEATURE_CRYPTO
+#endif // defined(CRYPT_VERIFYCONTEXT) && defined(CRYPT_MACHINE_KEYSET)
return !!WszCryptAcquireContext(phProv, pwszContainer, pwszProvider, dwProvType, dwFlags);
}
-#endif // !FEATURE_CORECLR || (CROSSGEN_COMPILE && !PLATFORM_UNIX)
+#endif // (CROSSGEN_COMPILE && !PLATFORM_UNIX)
diff --git a/src/strongname/inc/sncoreclr.h b/src/strongname/inc/sncoreclr.h
index a2f794b26a..1b84a32372 100644
--- a/src/strongname/inc/sncoreclr.h
+++ b/src/strongname/inc/sncoreclr.h
@@ -5,9 +5,6 @@
#ifndef _SNCORECLR_H
#define _SNCORECLR_H
-#if !defined(FEATURE_CORECLR)
-#error sncoreclr.h should only be used on CoreCLR builds
-#endif // !FEATURE_CORECLR
void InitUtilcode();
diff --git a/src/strongname/inc/strongnameholders.h b/src/strongname/inc/strongnameholders.h
index a439768e74..1a95c87aa7 100644
--- a/src/strongname/inc/strongnameholders.h
+++ b/src/strongname/inc/strongnameholders.h
@@ -21,7 +21,7 @@ void VoidStrongNameFreeBuffer(__in T *pBuffer)
}
NEW_WRAPPER_TEMPLATE1(StrongNameBufferHolder, VoidStrongNameFreeBuffer<_TYPE>);
-#if !defined(FEATURE_CORECLR) || (defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX))
+#if defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX)
// Holder for HCRYPTPROV handles directly allocated from CAPI
inline void ReleaseCapiProvider(HCRYPTPROV hProv)
{
@@ -40,7 +40,7 @@ inline void ReleaseCapiHash(HCRYPTHASH hHash)
CryptDestroyHash(hHash);
}
typedef Wrapper<HCRYPTHASH, DoNothing, ReleaseCapiHash, 0> CapiHashHolder;
-#endif // !FEATURE_CORECLR || CROSSGEN_COMPILE
+#endif // defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX)
#if SNAPI_INTERNAL
diff --git a/src/strongname/inc/strongnameinternal.h b/src/strongname/inc/strongnameinternal.h
index 614fdfb53a..7cbf5d87a8 100644
--- a/src/strongname/inc/strongnameinternal.h
+++ b/src/strongname/inc/strongnameinternal.h
@@ -35,7 +35,7 @@ bool StrongNameIsEcmaKey(const PublicKeyBlob &keyPublicKey);
bool StrongNameIsTheKey(__in_ecount(cbKey) const BYTE *pbKey, DWORD cbKey);
-#if !defined(FEATURE_CORECLR) || (defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX))
+#if defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX)
// Verify the format of a public key blob
bool StrongNameIsValidKeyPair(__in_ecount(cbKeyPair) const BYTE *pbKeyPair, DWORD cbKeyPair);
@@ -43,11 +43,9 @@ bool StrongNameIsValidKeyPair(__in_ecount(cbKeyPair) const BYTE *pbKeyPair, DWOR
bool GetBytesFromHex(LPCUTF8 szHexString, ULONG cchHexString, BYTE** buffer, ULONG *cbBufferSize);
bool StrongNameCryptAcquireContext(HCRYPTPROV *phProv, LPCWSTR pwszContainer, LPCWSTR pwszProvider, DWORD dwProvType, DWORD dwFlags);
-#endif // !FEATURE_CORECLR || (CROSSGEN_COMPILE && !PLATFORM_UNIX)
+#endif // (CROSSGEN_COMPILE && !PLATFORM_UNIX)
-#ifdef FEATURE_CORECLR
bool StrongNameIsSilverlightPlatformKey(__in_ecount(cbKey) const BYTE *pbKey, DWORD cbKey);
bool StrongNameIsSilverlightPlatformKey(const PublicKeyBlob &keyPublicKey);
-#endif // FEATURE_CORECLR
#endif // !_STRONGNAME_INTERNAL_H
diff --git a/src/strongname/inc/thekey.h b/src/strongname/inc/thekey.h
index 24d0375c5e..7a53f4713b 100644
--- a/src/strongname/inc/thekey.h
+++ b/src/strongname/inc/thekey.h
@@ -21,7 +21,6 @@ static const BYTE g_rbTheKey[] =
static const BYTE g_rbTheKeyToken[] = {0xb0,0x3f,0x5f,0x7f,0x11,0xd5,0x0a,0x3a};
-#ifdef FEATURE_CORECLR
static const BYTE g_rbTheSilverlightPlatformKey[] =
{
0x00,0x24,0x00,0x00,0x04,0x80,0x00,0x00,0x94,0x00,0x00,0x00,0x06,0x02,0x00,0x00,
@@ -100,5 +99,4 @@ static const BYTE g_rbTheMicrosoftXNAKeyToken[] = {0xCC,0xAC,0x92,0xED,0x87,0x3B
#endif
// for FEATURE_WINDOWSPHONE, we can add the Microsoft.Phone key and the Xna key to the list of blessed keys...
-#endif // FEATURE_CORECLR
diff --git a/src/tools/crossgen/crossgen.cpp b/src/tools/crossgen/crossgen.cpp
index a3e66e69e2..43e667bd25 100644
--- a/src/tools/crossgen/crossgen.cpp
+++ b/src/tools/crossgen/crossgen.cpp
@@ -36,9 +36,7 @@ enum ReturnValues
STDAPI CreatePDBWorker(LPCWSTR pwzAssemblyPath, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzAppNiPaths, LPCWSTR pwzPdbPath, BOOL fGeneratePDBLinesInfo, LPCWSTR pwzManagedPdbSearchPath, LPCWSTR pwzPlatformWinmdPaths, LPCWSTR pwzDiasymreaderPath);
STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzOutputFilename=NULL, LPCWSTR pwzPlatformWinmdPaths=NULL, ICorSvcLogger *pLogger = NULL, LPCWSTR pwszCLRJITPath = nullptr);
void SetSvcLogger(ICorSvcLogger *pCorSvcLogger);
-#ifdef FEATURE_CORECLR
void SetMscorlibPath(LPCWSTR wzSystemDirectory);
-#endif
/* --------------------------------------------------------------------------- *
* Console stuff
@@ -94,11 +92,7 @@ void ErrorWin32(DWORD err)
void PrintLogoHelper()
{
-#ifdef FEATURE_CORECLR
Output(W("Microsoft (R) CoreCLR Native Image "));
-#else
- Output(W("Microsoft (R) CLR Native Image "));
-#endif
Outputf(W("Generator - Version %S\n"), VER_FILEVERSION_STR);
Outputf(W("%S\n"), VER_LEGALCOPYRIGHT_LOGO_STR);
Output(W("\n"));
@@ -114,14 +108,12 @@ void PrintUsageHelper()
W("\n")
W(" /? or /help - Display this screen\n")
W(" /nologo - Prevents displaying the logo\n")
+ W(" /silent - Do not display completion message\n")
W(" @response.rsp - Process command line arguments from specified\n")
W(" response file\n")
-#ifdef FEATURE_CORECLR
W(" /partialtrust - Assembly will be run in a partial trust domain.\n")
-#endif
W(" /in <file> - Specifies input filename (optional)\n")
W(" /out <file> - Specifies output filename (optional)\n")
-#ifdef FEATURE_CORECLR
W(" /Trusted_Platform_Assemblies <path[") PATH_SEPARATOR_STR_W W("path]>\n")
W(" - List of assemblies treated as trusted platform\n")
W(" - Cannot be used with Platform_Assemblies_Paths\n")
@@ -134,15 +126,12 @@ void PrintUsageHelper()
W(" - List of paths containing user-application native images\n")
W(" - Must be used with /CreatePDB switch\n")
#endif // NO_NGENPDB
-#endif // FEATURE_CORECLR
W(" /Platform_Assemblies_Paths <path[") PATH_SEPARATOR_STR_W W("path]>\n")
W(" - List of paths containing target platform assemblies\n")
-#ifdef FEATURE_CORECLR
// If Platform_Assemblies_Paths, we will use it to build the TPA list and thus,
// TPA list cannot be explicitly specified.
W(" - Cannot be used with Trusted_Platform_Assemblies\n")
-#endif // FEATURE_CORECLR
#ifdef FEATURE_COMINTEROP
W(" /Platform_Winmd_Paths <path[") PATH_SEPARATOR_STR_W W("path]>\n")
@@ -156,10 +145,10 @@ void PrintUsageHelper()
W(" /Tuning - Generate an instrumented image to collect\n")
W(" scenario traces, which can be used with ibcmerge.exe\n")
#endif
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
W(" /JITPath <path>\n")
W(" - Specifies the absolute file path to JIT compiler to be used.\n")
-#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE)
#ifdef FEATURE_READYTORUN_COMPILER
W(" /ReadyToRun - Generate images resilient to the runtime and\n")
W(" dependency versions\n")
@@ -168,19 +157,15 @@ void PrintUsageHelper()
W(" WinMD Parameters\n")
W(" /WinMDResilient - Generate images resilient to WinMD dependency changes.\n")
#endif
-#ifdef FEATURE_CORECLR
W(" Size on Disk Parameters\n")
W(" /NoMetaData - Do not copy metadata and IL into native image.\n")
-#endif // FEATURE_CORECLR
#ifndef NO_NGENPDB
W(" Debugging Parameters\n")
W(" /CreatePDB <Dir to store PDB> [/lines [<search path for managed PDB>] ]\n")
W(" When specifying /CreatePDB, the native image should be created\n")
W(" first, and <assembly name> should be the path to the NI.\n")
-#ifdef FEATURE_CORECLR
W(" /DiasymreaderPath <Path to diasymreader.dll>\n")
W(" - Specifies the absolute file path to diasymreader.dll to be used.\n")
-#endif // FEATURE_CORECLR
#elif defined(FEATURE_PERFMAP)
W(" Debugging Parameters\n")
W(" /CreatePerfMap <Dir to store perf map>\n")
@@ -265,7 +250,6 @@ bool StringEndsWith(LPCWSTR pwzString, LPCWSTR pwzCandidate)
return !_wcsicmp(pwzStringEnd, pwzCandidate);
}
-#ifdef FEATURE_CORECLR
//
// When using the Phone binding model (TrustedPlatformAssemblies), automatically
// detect which path CoreLib.[ni.]dll lies in.
@@ -429,7 +413,6 @@ void ComputeTPAListFromPlatformAssembliesPath(LPCWSTR pwzPlatformAssembliesPaths
}
}
}
-#endif // FEATURE_CORECLR
extern HMODULE g_hThisInst;
@@ -459,9 +442,9 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
LPCWSTR pwzOutputFilename = NULL;
LPCWSTR pwzPublicKeys = nullptr;
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
LPCWSTR pwszCLRJITPath = nullptr;
-#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE)
LPCWSTR pwzDiasymreaderPath = nullptr;
@@ -501,10 +484,8 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
// By default, Crossgen will assume code-generation for fulltrust domains unless /PartialTrust switch is specified
dwFlags |= NGENWORKER_FLAGS_FULLTRUSTDOMAIN;
-#ifdef FEATURE_CORECLR
// By default, Crossgen will generate readytorun images unless /FragileNonVersionable switch is specified
dwFlags |= NGENWORKER_FLAGS_READYTORUN;
-#endif
while (argc > 0)
{
@@ -518,6 +499,10 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
{
fDisplayLogo = false;
}
+ else if (MatchParameter(*argv, W("silent")))
+ {
+ dwFlags |= NGENWORKER_FLAGS_SILENT;
+ }
else if (MatchParameter(*argv, W("Tuning")))
{
dwFlags |= NGENWORKER_FLAGS_TUNING;
@@ -526,7 +511,6 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
{
dwFlags |= NGENWORKER_FLAGS_MISSINGDEPENDENCIESOK;
}
-#ifdef FEATURE_CORECLR
else if (MatchParameter(*argv, W("PartialTrust")))
{
// Clear the /fulltrust flag
@@ -551,7 +535,6 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
argc--;
}
#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE)
-#endif
#ifdef FEATURE_WINMD_RESILIENT
else if (MatchParameter(*argv, W("WinMDResilient")))
{
@@ -568,12 +551,10 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
dwFlags &= ~NGENWORKER_FLAGS_READYTORUN;
}
#endif
-#ifdef FEATURE_CORECLR
else if (MatchParameter(*argv, W("NoMetaData")))
{
dwFlags |= NGENWORKER_FLAGS_NO_METADATA;
}
-#endif
else if (MatchParameter(*argv, W("out")))
{
if (pwzOutputFilename != NULL)
@@ -596,7 +577,6 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
argv++;
argc--;
}
-#ifdef FEATURE_CORECLR
else if (MatchParameter(*argv, W("Trusted_Platform_Assemblies")) && (argc > 1))
{
pwzTrustedPlatformAssemblies = argv[1];
@@ -631,7 +611,6 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
argc--;
}
#endif // NO_NGENPDB
-#endif // FEATURE_CORECLR
else if (MatchParameter(*argv, W("Platform_Assemblies_Paths")) && (argc > 1))
{
pwzPlatformAssembliesPaths = argv[1];
@@ -708,7 +687,6 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
argv--;
argc++;
}
-#ifdef FEATURE_CORECLR
else if (MatchParameter(*argv, W("DiasymreaderPath")) && (argc > 1))
{
pwzDiasymreaderPath = argv[1];
@@ -717,7 +695,6 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
argv++;
argc--;
}
-#endif // FEATURE_CORECLR
#endif // NO_NGENPDB
#ifdef FEATURE_PERFMAP
else if (MatchParameter(*argv, W("CreatePerfMap")) && (argc > 1))
@@ -816,23 +793,22 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
exit(FAILURE_RESULT);
}
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
if (pwszCLRJITPath != nullptr && fCreatePDB)
{
Output(W("The /JITPath switch can not be used with the /CreatePDB switch.\n"));
exit(FAILURE_RESULT);
}
-#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE)
-#if defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#if !defined(NO_NGENPDB)
if (pwzDiasymreaderPath != nullptr && !fCreatePDB)
{
Output(W("The /DiasymreaderPath switch can only be used with the /CreatePDB switch.\n"));
exit(FAILURE_RESULT);
}
-#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#endif // !defined(NO_NGENPDB)
-#if defined(FEATURE_CORECLR)
if ((pwzTrustedPlatformAssemblies != nullptr) && (pwzPlatformAssembliesPaths != nullptr))
{
Output(W("The /Trusted_Platform_Assemblies and /Platform_Assemblies_Paths switches cannot be both specified.\n"));
@@ -863,15 +839,6 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
exit(FAILURE_RESULT);
}
}
-#endif // FEATURE_CORESYSTEM
-
-#ifdef FEATURE_READYTORUN_COMPILER
- if (((dwFlags & NGENWORKER_FLAGS_TUNING) != 0) && ((dwFlags & NGENWORKER_FLAGS_READYTORUN) != 0))
- {
- Output(W("The /Tuning switch cannot be used with /ReadyToRun switch.\n"));
- exit(FAILURE_RESULT);
- }
-#endif
// All argument processing has happened by now. The only messages that should appear before here are errors
// related to argument parsing, such as the Usage message. Afterwards, other messages can appear.
@@ -888,7 +855,6 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
PathString wzTrustedPathRoot;
-#ifdef FEATURE_CORECLR
SString ssTPAList;
if (fCreatePDB)
@@ -924,7 +890,6 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
SetMscorlibPath(pwzPlatformAssembliesPaths);
}
}
-#endif // FEATURE_CORECLR
if (pwzPlatformAssembliesPaths == NULL)
{
@@ -977,11 +942,11 @@ int _cdecl wmain(int argc, __in_ecount(argc) WCHAR **argv)
pwzAppPaths,
pwzOutputFilename,
pwzPlatformWinmdPaths
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
,
NULL, // ICorSvcLogger
pwszCLRJITPath
-#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE)
);
}
diff --git a/src/tools/metainfo/mdinfo.cpp b/src/tools/metainfo/mdinfo.cpp
index 70dfa28bcf..753321fb5c 100644
--- a/src/tools/metainfo/mdinfo.cpp
+++ b/src/tools/metainfo/mdinfo.cpp
@@ -22,9 +22,6 @@
#define LEGACY_ACTIVATION_SHIM_LOAD_LIBRARY WszLoadLibrary
#define LEGACY_ACTIVATION_SHIM_DEFINE_CoInitializeEE
-#ifndef FEATURE_CORECLR
-#include "LegacyActivationShim.h"
-#endif
#define ENUM_BUFFER_SIZE 10
#define TAB_SIZE 8
@@ -760,12 +757,6 @@ void MDInfo::Error(const char* szError, HRESULT hr)
pIErr->Release();
}
-#ifndef FEATURE_CORECLR
- LegacyActivationShim::CoUninitializeCor();
-#ifndef FEATURE_PAL
- CoUninitialize();
-#endif
-#endif
exit(hr);
} // void MDInfo::Error()
@@ -1427,7 +1418,7 @@ void MDInfo::DisplayFields(mdTypeDef inTypeDef, COR_FIELD_OFFSET *rFieldOffset,
if (cFieldOffset)
{
bool found = false;
- for (ULONG iLayout = 0; i < cFieldOffset; ++iLayout)
+ for (ULONG iLayout = 0; iLayout < cFieldOffset; ++iLayout)
{
if (RidFromToken(rFieldOffset[iLayout].ridOfField) == RidFromToken(fields[i]))
{
diff --git a/src/unwinder/arm64/unwinder_arm64.cpp b/src/unwinder/arm64/unwinder_arm64.cpp
index e13c7b917d..1edb94a746 100644
--- a/src/unwinder/arm64/unwinder_arm64.cpp
+++ b/src/unwinder/arm64/unwinder_arm64.cpp
@@ -109,16 +109,37 @@ typedef struct _ARM64_VFP_STATE
typedef struct _ARM64_UNWIND_PARAMS
{
- ULONG_PTR ControlPc;
- PULONG_PTR LowLimit;
- PULONG_PTR HighLimit;
- PKNONVOLATILE_CONTEXT_POINTERS ContextPointers;
+ PT_KNONVOLATILE_CONTEXT_POINTERS ContextPointers;
} ARM64_UNWIND_PARAMS, *PARM64_UNWIND_PARAMS;
#define UNWIND_PARAMS_SET_TRAP_FRAME(Params, Address, Size)
-#define UPDATE_CONTEXT_POINTERS(Params, RegisterNumber, Address)
-#define UPDATE_FP_CONTEXT_POINTERS(Params, RegisterNumber, Address)
+#define UPDATE_CONTEXT_POINTERS(Params, RegisterNumber, Address) \
+do { \
+ if (ARGUMENT_PRESENT(Params)) { \
+ PT_KNONVOLATILE_CONTEXT_POINTERS ContextPointers = (Params)->ContextPointers; \
+ if (ARGUMENT_PRESENT(ContextPointers)) { \
+ if (RegisterNumber >= 19 && RegisterNumber <= 30) { \
+ (&ContextPointers->X19)[RegisterNumber - 19] = (PDWORD64)Address; \
+ } \
+ } \
+ } \
+} while (0)
+
+
+#define UPDATE_FP_CONTEXT_POINTERS(Params, RegisterNumber, Address) \
+do { \
+ if (ARGUMENT_PRESENT(Params)) { \
+ PT_KNONVOLATILE_CONTEXT_POINTERS ContextPointers = (Params)->ContextPointers; \
+ if (ARGUMENT_PRESENT(ContextPointers) && \
+ (RegisterNumber >= 8) && \
+ (RegisterNumber <= 15)) { \
+ \
+ (&ContextPointers->D8)[RegisterNumber - 8] = (PDWORD64)Address; \
+ } \
+ } \
+} while (0)
+
#define VALIDATE_STACK_ADDRESS_EX(Params, Context, Address, DataSize, Alignment, OutStatus)
#define VALIDATE_STACK_ADDRESS(Params, Context, DataSize, Alignment, OutStatus)
@@ -215,7 +236,7 @@ Return Value:
for (RegIndex = 0; RegIndex < 18; RegIndex++) {
UPDATE_CONTEXT_POINTERS(UnwindParams, RegIndex, SourceAddress);
#ifdef __clang__
- *(&ContextRecord->X0 + (RegIndex * sizeof(void*))) = MEMORY_READ_QWORD(UnwindParams, SourceAddress);
+ *(&ContextRecord->X0 + RegIndex) = MEMORY_READ_QWORD(UnwindParams, SourceAddress);
#else
ContextRecord->X[RegIndex] = MEMORY_READ_QWORD(UnwindParams, SourceAddress);
#endif
@@ -295,7 +316,7 @@ Return Value:
for (RegIndex = 0; RegIndex < 29; RegIndex++) {
UPDATE_CONTEXT_POINTERS(UnwindParams, RegIndex, SourceAddress);
#ifdef __clang__
- *(&ContextRecord->X0 + (RegIndex * sizeof(void*))) = MEMORY_READ_QWORD(UnwindParams, SourceAddress);
+ *(&ContextRecord->X0 + RegIndex) = MEMORY_READ_QWORD(UnwindParams, SourceAddress);
#else
ContextRecord->X[RegIndex] = MEMORY_READ_QWORD(UnwindParams, SourceAddress);
#endif
@@ -479,9 +500,9 @@ Return Value:
//
for (RegIndex = 0; RegIndex < RegisterCount; RegIndex++) {
- UPDATE_CONTEXT_POINTERS(UnwindParams, RegIndex, CurAddress);
+ UPDATE_CONTEXT_POINTERS(UnwindParams, FirstRegister + RegIndex, CurAddress);
#ifdef __clang__
- *(&ContextRecord->X0 + (RegIndex * sizeof(void*))) = MEMORY_READ_QWORD(UnwindParams, CurAddress);
+ *(&ContextRecord->X0 + FirstRegister + RegIndex) = MEMORY_READ_QWORD(UnwindParams, CurAddress);
#else
ContextRecord->X[FirstRegister + RegIndex] = MEMORY_READ_QWORD(UnwindParams, CurAddress);
#endif
@@ -555,7 +576,7 @@ Return Value:
//
for (RegIndex = 0; RegIndex < RegisterCount; RegIndex++) {
- UPDATE_FP_CONTEXT_POINTERS(UnwindParams, RegIndex, CurAddress);
+ UPDATE_FP_CONTEXT_POINTERS(UnwindParams, FirstRegister + RegIndex, CurAddress);
ContextRecord->V[FirstRegister + RegIndex].Low = MEMORY_READ_QWORD(UnwindParams, CurAddress);
CurAddress += 8;
}
@@ -1591,7 +1612,6 @@ BOOL DacUnwindStackFrame(T_CONTEXT *pContext, T_KNONVOLATILE_CONTEXT_POINTERS* p
}
#if defined(FEATURE_PAL)
-//TODO: Fix the context pointers
PEXCEPTION_ROUTINE
RtlVirtualUnwind(
IN ULONG HandlerType,
@@ -1601,7 +1621,7 @@ RtlVirtualUnwind(
IN OUT PCONTEXT ContextRecord,
OUT PVOID *HandlerData,
OUT PULONG64 EstablisherFrame,
- IN OUT PKNONVOLATILE_CONTEXT_POINTERS ContextPointers OPTIONAL
+ IN OUT PT_KNONVOLATILE_CONTEXT_POINTERS ContextPointers OPTIONAL
)
{
PEXCEPTION_ROUTINE handlerRoutine;
@@ -1615,6 +1635,9 @@ RtlVirtualUnwind(
rfe.BeginAddress = FunctionEntry->BeginAddress;
rfe.UnwindData = FunctionEntry->UnwindData;
+ ARM64_UNWIND_PARAMS unwindParams;
+ unwindParams.ContextPointers = ContextPointers;
+
if ((rfe.UnwindData & 3) != 0)
{
hr = RtlpUnwindFunctionCompact(ControlPc - ImageBase,
@@ -1623,7 +1646,7 @@ RtlVirtualUnwind(
EstablisherFrame,
&handlerRoutine,
HandlerData,
- NULL);
+ &unwindParams);
}
else
@@ -1635,7 +1658,7 @@ RtlVirtualUnwind(
EstablisherFrame,
&handlerRoutine,
HandlerData,
- NULL);
+ &unwindParams);
}
_ASSERTE(SUCCEEDED(hr));
diff --git a/src/unwinder/i386/unwinder_i386.cpp b/src/unwinder/i386/unwinder_i386.cpp
index ca9e28e44a..55f0766a7f 100644
--- a/src/unwinder/i386/unwinder_i386.cpp
+++ b/src/unwinder/i386/unwinder_i386.cpp
@@ -76,6 +76,7 @@ OOPStackUnwinderX86::VirtualUnwind(
FillRegDisplay(&rd, ContextRecord);
+ rd.SP = ContextRecord->Esp;
rd.PCTAddr = (UINT_PTR)&(ContextRecord->Eip);
if (ContextPointers)
@@ -104,7 +105,21 @@ OOPStackUnwinderX86::VirtualUnwind(
ENUM_CALLEE_SAVED_REGISTERS();
#undef CALLEE_SAVED_REGISTER
- ContextRecord->Esp = rd.SP;
+ SIZE_T paramSize = codeInfo.GetCodeManager()->GetStackParameterSize(&codeInfo);
+ SIZE_T paddingSize = 0;
+
+#ifdef UNIX_X86_ABI
+ // On UNIX_X86_ABI, function call may have stack alignment padding.
+ if (paramSize % 16 != 0)
+ {
+ paddingSize += 16 - (paramSize % 16);
+ }
+#endif // UNIX_X86_ABI
+
+ ContextRecord->Esp = rd.SP - paramSize;
+ ContextRecord->ResumeEsp = ExecutionManager::IsManagedCode((PCODE) rd.ControlPC)
+ ? rd.SP + paddingSize
+ : ContextRecord->Esp;
ContextRecord->Eip = rd.ControlPC;
// For x86, the value of Establisher Frame Pointer is Caller SP
diff --git a/src/utilcode/CMakeLists.txt b/src/utilcode/CMakeLists.txt
index 7c396732a1..dfe830d5c0 100644
--- a/src/utilcode/CMakeLists.txt
+++ b/src/utilcode/CMakeLists.txt
@@ -1,10 +1,6 @@
set(CMAKE_INCLUDE_CURRENT_DIR ON)
-if(WIN32)
- add_compile_options(/wd4996)
-endif(WIN32)
-
set(UTILCODE_COMMON_SOURCES
clrhost_nodependencies.cpp
ccomprc.cpp
@@ -28,7 +24,6 @@ set(UTILCODE_COMMON_SOURCES
peinformation.cpp
check.cpp
log.cpp
- apithreadstress.cpp
arraylist.cpp
bitvector.cpp
comex.cpp
diff --git a/src/utilcode/apithreadstress.cpp b/src/utilcode/apithreadstress.cpp
deleted file mode 100644
index 88b09fe006..0000000000
--- a/src/utilcode/apithreadstress.cpp
+++ /dev/null
@@ -1,183 +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.
-
-// ---------------------------------------------------------------------------
-// APIThreadStress.cpp (API thread stresser)
-// ---------------------------------------------------------------------------
-
-#include "stdafx.h"
-
-#ifdef STRESS_THREAD
-
-#include "apithreadstress.h"
-#include "clrhost.h"
-#include "ex.h"
-#include "log.h"
-
-
-
-// For now, thread stress is incompatible with hosting. We need a host CreateThread
-// to fix this.
-#undef SetEvent
-#undef ResetEvent
-
-int APIThreadStress::s_threadStressCount = 0;
-
-APIThreadStress::APIThreadStress()
-{
- WRAPPER_NO_CONTRACT;
-
- m_threadCount = 0;
-
- // Don't "fork" stress threads
- if (ClrFlsGetValue(TlsIdx_StressThread) == NULL)
- m_threadCount = s_threadStressCount;
-
- if (m_threadCount != 0)
- {
- m_setupOK = TRUE;
-
- m_hThreadArray = new (nothrow) HANDLE [ m_threadCount ];
- if (m_hThreadArray == NULL)
- m_setupOK = FALSE;
- else
- {
- HANDLE *p = m_hThreadArray;
- HANDLE *pEnd = p + m_threadCount;
-
- while (p < pEnd)
- {
- DWORD id;
- *p = ::CreateThread(NULL, 0, StartThread, this, 0, &id);
- if (*p == NULL)
- m_setupOK = FALSE;
- p++;
- }
- }
-
- m_syncEvent = ClrCreateManualEvent(FALSE);
- if (m_syncEvent == INVALID_HANDLE_VALUE)
- m_setupOK = FALSE;
- }
-}
-
-APIThreadStress::~APIThreadStress()
-{
- WRAPPER_NO_CONTRACT;
-
- if (m_threadCount > 0)
- {
- HANDLE *p = m_hThreadArray;
- HANDLE *pEnd = p + m_threadCount;
-
- if (p != NULL)
- {
- while (p < pEnd)
- {
- if (*p != NULL)
- {
- if (m_threadCount > 0 && m_setupOK)
- WaitForSingleObjectEx(*p, INFINITE, FALSE);
-
- ::CloseHandle(*p);
- }
- p++;
- }
- delete [] m_hThreadArray;
- }
-
- if (m_syncEvent != INVALID_HANDLE_VALUE)
- CloseHandle(m_syncEvent);
- }
-}
-
-void APIThreadStress::SetThreadStressCount(int threadCount)
-{
- LIMITED_METHOD_CONTRACT;
-
- s_threadStressCount = threadCount;
-}
-
-
-DWORD WINAPI APIThreadStress::StartThread(void *arg)
-{
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_NOT_MAINLINE; // not mainline so scenario
-
- APIThreadStress *pThis = (APIThreadStress *) arg;
-
- ClrFlsSetValue(TlsIdx_StressThread, pThis);
-
- EX_TRY
- {
- // Perform initial synchronization
- WaitForSingleObjectEx(pThis->m_syncEvent, INFINITE, FALSE);
- InterlockedIncrement(&pThis->m_runCount);
-
- LOG((LF_ALL, LL_INFO100, "Stressing operation on thread %d\n", GetCurrentThreadId()));
- ((APIThreadStress *)arg)->Invoke();
- LOG((LF_ALL, LL_INFO100, "End stress operation on thread %d\n", GetCurrentThreadId()));
-
- if (InterlockedDecrement(&pThis->m_runCount) == 0)
- ::SetEvent(pThis->m_syncEvent);
- }
- EX_CATCH
- {
- LOG((LF_ALL, LL_ERROR, "Exception during stress operation on thread %d\n", GetCurrentThreadId()));
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- return 0;
-}
-
-BOOL APIThreadStress::DoThreadStress()
-{
- WRAPPER_NO_CONTRACT;
-
- if (m_threadCount > 0 && m_setupOK)
- {
- HANDLE *p = m_hThreadArray;
- HANDLE *pEnd = p + m_threadCount;
-
- while (p < pEnd)
- {
- ::ResumeThread(*p);
- p++;
- }
-
- // Start the threads at the same time
- ::SetEvent(m_syncEvent);
-
- return TRUE;
- }
- else
- {
- SyncThreadStress();
- return FALSE;
- }
-}
-
-void APIThreadStress::SyncThreadStress()
-{
- WRAPPER_NO_CONTRACT;
-
- APIThreadStress *pThis = (APIThreadStress *) ClrFlsGetValue(TlsIdx_StressThread);
-
- if (pThis != NULL)
- {
- LOG((LF_ALL, LL_INFO1000, "Syncing stress operation on thread %d\n", GetCurrentThreadId()));
-
- ::ResetEvent(pThis->m_syncEvent);
-
- if (InterlockedDecrement(&pThis->m_runCount) == 0)
- ::SetEvent(pThis->m_syncEvent);
- else
- WaitForSingleObjectEx(pThis->m_syncEvent, INFINITE, FALSE);
- InterlockedIncrement(&pThis->m_runCount);
-
- LOG((LF_ALL, LL_INFO1000, "Resuming stress operation on thread %d\n", GetCurrentThreadId()));
- }
-}
-
-#endif // STRESS_THREAD
diff --git a/src/utilcode/appxutil.cpp b/src/utilcode/appxutil.cpp
index 759fbffcb1..5d095a4873 100644
--- a/src/utilcode/appxutil.cpp
+++ b/src/utilcode/appxutil.cpp
@@ -19,7 +19,6 @@
#include "shlwapi.h" // Path manipulation APIs
-#ifdef FEATURE_CORECLR
GVAL_IMPL(bool, g_fAppX);
INDEBUG(bool g_fIsAppXAsked;)
@@ -49,822 +48,3 @@ namespace AppX
#endif
};
-#else // FEATURE_CORECLR
-
-//---------------------------------------------------------------------------------------------
-// Convenience values
-
-#ifndef E_INSUFFICIENT_BUFFER
- #define E_INSUFFICIENT_BUFFER (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
-#endif
-
-#ifndef E_FILE_NOT_FOUND
- #define E_FILE_NOT_FOUND (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
-#endif
-
-//---------------------------------------------------------------------------------------------
-using clr::str::IsNullOrEmpty;
-
-//---------------------------------------------------------------------------------------------
-typedef decltype(GetCurrentPackageId) GetCurrentPackageId_t;
-typedef decltype(GetCurrentPackageInfo) GetCurrentPackageInfo_t;
-typedef decltype(GetCurrentPackagePath) GetCurrentPackagePath_t;
-typedef decltype(OpenPackageInfoByFullName) OpenPackageInfoByFullName_t;
-typedef decltype(ClosePackageInfo) ClosePackageInfo_t;
-typedef decltype(GetPackageInfo) GetPackageInfo_t;
-
-//---------------------------------------------------------------------------------------------
-// Caches AppX ARI API-related information.
-struct AppXRTInfo
-{
- HMODULE m_hAppXRTMod;
- bool m_fIsAppXProcess;
- bool m_fIsAppXAdaptiveApp;
- bool m_fIsAppXNGen;
-
- GetCurrentPackageId_t * m_pfnGetCurrentPackageId;
- GetCurrentPackageInfo_t * m_pfnGetCurrentPackageInfo;
- GetCurrentPackagePath_t * m_pfnGetCurrentPackagePath;
-
- NewArrayHolder<BYTE> m_pbAppContainerInfo;
- DWORD m_cbAppContainerInfo;
-
- struct CurrentPackageInfo
- {
- UINT32 m_cbCurrentPackageInfo;
- PBYTE m_pbCurrentPackageInfo;
- UINT32 m_nCount;
-
- CurrentPackageInfo(UINT32 cbPkgInfo, PBYTE pbPkgInfo, UINT32 nCount)
- : m_cbCurrentPackageInfo(cbPkgInfo)
- , m_pbCurrentPackageInfo(pbPkgInfo)
- , m_nCount(nCount)
- { LIMITED_METHOD_CONTRACT; }
-
- ~CurrentPackageInfo()
- {
- LIMITED_METHOD_CONTRACT;
- if (m_pbCurrentPackageInfo != nullptr)
- {
- delete [] m_pbCurrentPackageInfo;
- m_pbCurrentPackageInfo = nullptr;
- }
- }
- };
-
- CurrentPackageInfo * m_pCurrentPackageInfo;
-
- NewArrayHolder<WCHAR> m_AdaptiveAppWinmetadataDir;
-
- AppXRTInfo() :
- m_hAppXRTMod(nullptr),
- m_fIsAppXProcess(false),
- m_fIsAppXAdaptiveApp(false),
- m_fIsAppXNGen(false),
- m_pfnGetCurrentPackageId(nullptr),
- m_pfnGetCurrentPackageInfo(nullptr),
- m_pfnGetCurrentPackagePath(nullptr),
- m_pbAppContainerInfo(nullptr),
- m_pCurrentPackageInfo(nullptr),
- m_AdaptiveAppWinmetadataDir(nullptr)
- { LIMITED_METHOD_CONTRACT; }
-
- ~AppXRTInfo()
- {
- LIMITED_METHOD_CONTRACT;
- if (m_pCurrentPackageInfo != nullptr)
- {
- delete m_pCurrentPackageInfo;
- m_pCurrentPackageInfo = nullptr;
- }
-
- if (m_hAppXRTMod != nullptr)
- {
- FreeLibrary(m_hAppXRTMod);
- m_hAppXRTMod = nullptr;
- }
- }
-}; // struct AppXRTInfo
-
-GPTR_IMPL(AppXRTInfo, g_pAppXRTInfo); // Relies on zero init static memory.
-
-#ifndef DACCESS_COMPILE
-
-//---------------------------------------------------------------------------------------------
-static
-HRESULT GetAppContainerTokenInfoForProcess(
- DWORD pid,
- NewArrayHolder<BYTE>& pbAppContainerTokenInfo,
- DWORD* pcbAppContainerTokenInfo)
-{
- PRECONDITION(CheckPointer(pcbAppContainerTokenInfo, NULL_OK));
-
- HRESULT hr = S_OK;
-
- pbAppContainerTokenInfo = nullptr;
-
- // In order to get the AppContainer SID we need to open the process token
- HandleHolder hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
- if (hProcess == NULL)
- return HRESULT_FROM_GetLastError();
-
- HandleHolder hToken;
- if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken))
- return HRESULT_FROM_GetLastError();
-
- // Query the process to see if it's inside an AppContainer
- ULONG isAppContainer = 0;
- DWORD actualLength = 0;
- if (!GetTokenInformation(hToken, static_cast<TOKEN_INFORMATION_CLASS>(TokenIsAppContainer), &isAppContainer, sizeof(isAppContainer), &actualLength))
- return HRESULT_FROM_GetLastError();
-
- _ASSERTE(actualLength > 0);
-
- // Not an AppContainer so bail
- if (!isAppContainer)
- {
- return S_FALSE;
- }
-
- // Now we need the AppContainer SID so first get the required buffer length
- actualLength = 0;
- VERIFY(!GetTokenInformation(hToken, static_cast<TOKEN_INFORMATION_CLASS>(TokenAppContainerSid), NULL, 0, &actualLength));
- hr = HRESULT_FROM_GetLastError();
- _ASSERTE(hr == E_INSUFFICIENT_BUFFER);
-
- // Something unexpected happened
- if (hr != E_INSUFFICIENT_BUFFER)
- return hr;
-
- // Now we know the length of the AppContainer SID so create a buffer and retrieve it
- pbAppContainerTokenInfo = new (nothrow) BYTE[actualLength];
- IfNullRet(pbAppContainerTokenInfo);
-
- if (!GetTokenInformation(hToken, static_cast<TOKEN_INFORMATION_CLASS>(TokenAppContainerSid), pbAppContainerTokenInfo.GetValue(), actualLength, &actualLength))
- return HRESULT_FROM_GetLastError();
-
- if (pcbAppContainerTokenInfo != nullptr)
- *pcbAppContainerTokenInfo = actualLength;
-
- return S_OK;
-}
-
-//---------------------------------------------------------------------------------------------
-// Initializes a global AppXRTInfo structure if it has not already been initialized. Returns
-// false only in the event of OOM; otherwise caches the result of ARI information in
-// g_pAppXRTInfo. Thread safe.
-static
-HRESULT InitAppXRT()
-{
- // This will be used for catastrophic errors.
- HRESULT hr = S_OK;
-
- if (VolatileLoad(&g_pAppXRTInfo) == nullptr)
- {
- NewHolder<AppXRTInfo> pAppXRTInfo = new (nothrow) AppXRTInfo();
- IfNullRet(pAppXRTInfo); // Catastrophic error.
-
- pAppXRTInfo->m_fIsAppXProcess = false;
-
- do
- {
- if (!RunningOnWin8())
- {
- break;
- }
-
- LPCWSTR wzAppXRTDll = W("api-ms-win-appmodel-runtime-l1-1-0.dll");
- // Does not use GetLoadWithAlteredSearchPathFlag() because that would cause infinite recursion.
- pAppXRTInfo->m_hAppXRTMod = WszLoadLibraryEx(wzAppXRTDll, nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
- if (pAppXRTInfo->m_hAppXRTMod == nullptr)
- { // Error is catastrophic: can't find kernel32.dll?
- hr = HRESULT_FROM_GetLastError();
- break;
- }
-
- pAppXRTInfo->m_pfnGetCurrentPackageId = reinterpret_cast<GetCurrentPackageId_t *>(
- GetProcAddress(pAppXRTInfo->m_hAppXRTMod, "GetCurrentPackageId"));
- if (pAppXRTInfo->m_pfnGetCurrentPackageId == nullptr)
- { // Error is non-catastrophic: could be running downlevel
- break;
- }
-
- pAppXRTInfo->m_pfnGetCurrentPackageInfo = reinterpret_cast<GetCurrentPackageInfo_t *>(
- GetProcAddress(pAppXRTInfo->m_hAppXRTMod, "GetCurrentPackageInfo"));
- if (pAppXRTInfo->m_pfnGetCurrentPackageInfo == nullptr)
- { // Error is catastrophic: GetCurrentPackageId is available but not GetCurrentPackageInfo?
- hr = HRESULT_FROM_GetLastError();
- break;
- }
-
- pAppXRTInfo->m_pfnGetCurrentPackagePath = reinterpret_cast<GetCurrentPackagePath_t *>(
- GetProcAddress(pAppXRTInfo->m_hAppXRTMod, "GetCurrentPackagePath"));
- if (pAppXRTInfo->m_pfnGetCurrentPackagePath == nullptr)
- { // Error is catastrophic: GetCurrentPackageInfo is available but not GetCurrentPackagePath?
- hr = HRESULT_FROM_GetLastError();
- break;
- }
-
- // Determine if this is an AppX process
- UINT32 cbBuffer = 0;
- LONG lRes = (*pAppXRTInfo->m_pfnGetCurrentPackageId)(&cbBuffer, nullptr);
- pAppXRTInfo->m_fIsAppXProcess = (lRes == ERROR_INSUFFICIENT_BUFFER);
-
- _ASSERTE(AppX::IsAppXSupported());
-
- hr = GetAppContainerTokenInfoForProcess(
- GetCurrentProcessId(),
- pAppXRTInfo->m_pbAppContainerInfo,
- &pAppXRTInfo->m_cbAppContainerInfo);
-
- if (FAILED(hr))
- {
- if (pAppXRTInfo->m_fIsAppXProcess)
- { // Error is catastrophic: running in true immersive process but no token info?
- }
- else
- { // Error is non-catastrophic: reset HRESULT to S_OK.
- hr = S_OK;
- }
- break;
- }
- }
- while (false);
-
- if (InterlockedCompareExchangeT<AppXRTInfo>(&g_pAppXRTInfo, pAppXRTInfo, nullptr) == nullptr)
- {
- pAppXRTInfo.SuppressRelease();
- }
- }
-
- return hr;
-}
-
-//---------------------------------------------------------------------------------------------
-// Inline helper to check first an only init when required.
-static inline HRESULT CheckInitAppXRT()
-{
- return (VolatileLoad(&g_pAppXRTInfo) != nullptr) ? S_OK : InitAppXRT();
-}
-
-#endif // !DACCESS_COMPILE
-
-//---------------------------------------------------------------------------------------------
-// Contains general helper methods for interacting with AppX functionality. This code will
-// gracefully fail on downlevel OS by returning false from AppX::IsAppXProcess, so always
-// call this API first to check before calling any of the others defined in this namespace.
-//
-// See http://windows/windows8/docs/Windows%208%20Feature%20Documents/Developer%20Experience%20(DEVX)/Apps%20Experience%20(APPX)/Modern%20Client/App%20Runtime%20Improvements%20API%20Developer%20Platform%20Spec.docm
-// for more information.
-
-namespace AppX
-{
-#ifdef DACCESS_COMPILE
-
- //-----------------------------------------------------------------------------------------
- // DAC-only IsAppXProcess. Returns false if g_pAppXRTInfo has not been initialized.
- bool DacIsAppXProcess()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return (g_pAppXRTInfo != nullptr && g_pAppXRTInfo->m_fIsAppXProcess);
- }
-
-#else // DACCESS_COMPILE
-
- //---------------------------------------------------------------------------------------------
- // cleans up resources allocated in InitAppXRT()
- void ShutDown()
- {
- if (VolatileLoad(&g_pAppXRTInfo) != nullptr)
- {
- delete g_pAppXRTInfo;
- g_pAppXRTInfo = nullptr;
- }
- }
-
- //-----------------------------------------------------------------------------------------
- // Returns true if the current process is immersive.
- // NOTE: a return value of true doesn't necessarily indicate that the process is a
- // real Metro app, e.g. it could be an ngen process compiling an AppX assembly.
- bool IsAppXProcess()
- {
- LIMITED_METHOD_CONTRACT;
- HRESULT hr = S_OK;
-
- if (FAILED(hr = CheckInitAppXRT()))
- {
- SetLastError(hr); // HRESULT_FROM_WIN32 is idempotent when error value is HRESULT.
- return false;
- }
-
- return g_pAppXRTInfo->m_fIsAppXProcess;
- }
-
- //-----------------------------------------------------------------------------------------
- // Returns true if the current process is immersive.
- // Only produces reliable results after IsAppXProcess is inititalized
- bool IsAppXProcess_Initialized_NoFault()
- {
- LIMITED_METHOD_CONTRACT;
- if (VolatileLoad(&g_pAppXRTInfo) == nullptr)
- {
- return false;
- }
- return g_pAppXRTInfo->m_fIsAppXProcess;
- }
-
- bool IsAppXNGen()
- {
- LIMITED_METHOD_CONTRACT;
- return VolatileLoad(&g_pAppXRTInfo) != nullptr && g_pAppXRTInfo->m_fIsAppXNGen;
- }
-
- //-----------------------------------------------------------------------------------------
- HRESULT InitCurrentPackageInfoCache()
- {
- LIMITED_METHOD_CONTRACT;
- HRESULT hr = S_OK;
-
- UINT32 cbBuffer = 0;
- hr = HRESULT_FROM_WIN32((*g_pAppXRTInfo->m_pfnGetCurrentPackageInfo)(PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, nullptr, nullptr));
- if (hr != E_INSUFFICIENT_BUFFER)
- return hr;
-
- NewArrayHolder<BYTE> pbBuffer(new (nothrow) BYTE[cbBuffer]);
- IfNullRet(pbBuffer);
-
- UINT32 nCount = 0;
- IfFailRet(HRESULT_FROM_WIN32((*g_pAppXRTInfo->m_pfnGetCurrentPackageInfo)(PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, pbBuffer, &nCount)));
-
- NewHolder<AppXRTInfo::CurrentPackageInfo> pPkgInfo(
- new (nothrow) AppXRTInfo::CurrentPackageInfo(cbBuffer, pbBuffer.Extract(), nCount));
- IfNullRet(pPkgInfo);
-
- if (InterlockedCompareExchangeT<AppXRTInfo::CurrentPackageInfo>(
- &g_pAppXRTInfo->m_pCurrentPackageInfo, pPkgInfo, nullptr) == nullptr)
- {
- pPkgInfo.SuppressRelease();
- }
-
- return S_OK;
- }
-
- //-----------------------------------------------------------------------------------------
- FORCEINLINE HRESULT CheckInitCurrentPackageInfoCache()
- {
- WRAPPER_NO_CONTRACT;
- PRECONDITION(IsAppXProcess());
-
- if (!IsAppXProcess())
- return E_UNEXPECTED;
-
- if (g_pAppXRTInfo->m_pCurrentPackageInfo == nullptr)
- return InitCurrentPackageInfoCache();
- else
- return S_OK;
- }
-
- //-----------------------------------------------------------------------------------------
- LPCWSTR GetHeadPackageMoniker()
- {
- STANDARD_VM_CONTRACT;
-
- IfFailThrow(CheckInitCurrentPackageInfoCache());
- return reinterpret_cast<PPACKAGE_INFO>(
- g_pAppXRTInfo->m_pCurrentPackageInfo->m_pbCurrentPackageInfo)->packageFullName;
- }
-
- //-----------------------------------------------------------------------------------------
- // Returns the current process' PACKAGE_ID in the provided buffer. See the ARI spec (above)
- // for more information.
- HRESULT GetCurrentPackageId(
- PUINT32 pBufferLength,
- PBYTE pBuffer)
- {
- LIMITED_METHOD_CONTRACT;
- HRESULT hr = S_OK;
-
- IfFailRet(CheckInitAppXRT());
- IfFailRet(HRESULT_FROM_WIN32((*g_pAppXRTInfo->m_pfnGetCurrentPackageId)(pBufferLength, pBuffer)));
-
- return S_OK;
- }
-
- //-----------------------------------------------------------------------------------------
- // Returns the current process' PACKAGE_INFO in the provided buffer. See the ARI spec
- // (above) for more information.
- HRESULT GetCurrentPackageInfo(
- UINT32 uiFlags,
- PUINT32 pcbBuffer,
- PBYTE pbBuffer,
- PUINT32 pnCount)
- {
- LIMITED_METHOD_CONTRACT;
- PRECONDITION(IsAppXProcess());
- PRECONDITION(CheckPointer(pcbBuffer));
-
- HRESULT hr = S_OK;
-
- IfFailRet(CheckInitAppXRT());
-
- if (pcbBuffer == nullptr)
- return E_INVALIDARG;
-
- if (uiFlags == PACKAGE_FILTER_CLR_DEFAULT)
- {
- IfFailRet(CheckInitCurrentPackageInfoCache());
-
- DWORD cbBuffer = *pcbBuffer;
- *pcbBuffer = g_pAppXRTInfo->m_pCurrentPackageInfo->m_cbCurrentPackageInfo;
- if (pnCount != nullptr)
- {
- *pnCount = g_pAppXRTInfo->m_pCurrentPackageInfo->m_nCount;
- }
-
- if (pbBuffer == nullptr || cbBuffer < g_pAppXRTInfo->m_pCurrentPackageInfo->m_cbCurrentPackageInfo)
- {
- return E_INSUFFICIENT_BUFFER;
- }
- memcpy(pbBuffer, g_pAppXRTInfo->m_pCurrentPackageInfo->m_pbCurrentPackageInfo, g_pAppXRTInfo->m_pCurrentPackageInfo->m_cbCurrentPackageInfo);
- }
- else
- {
- IfFailRet(HRESULT_FROM_WIN32((*g_pAppXRTInfo->m_pfnGetCurrentPackageInfo)(uiFlags, pcbBuffer, pbBuffer, pnCount)));
- }
-
- return S_OK;
- }
-
- //-----------------------------------------------------------------------------------------
- bool IsAdaptiveApp()
- {
- LIMITED_METHOD_CONTRACT;
-
- HRESULT hr = S_OK;
- static bool cachedIsAdaptiveApp = false;
-
- if (!IsAppXProcess())
- {
- return false;
- }
-
- if (!cachedIsAdaptiveApp)
- {
- cachedIsAdaptiveApp = true;
- LPWSTR adaptiveAppWinmetaDataDir = NULL;
-
- if (SUCCEEDED(hr = AppX::GetWinMetadataDirForAdaptiveApps(&adaptiveAppWinmetaDataDir)))
- {
- g_pAppXRTInfo->m_fIsAppXAdaptiveApp = clr::fs::Dir::Exists(adaptiveAppWinmetaDataDir);
-
- }
- else
- {
- SetLastError(hr);
- g_pAppXRTInfo->m_fIsAppXAdaptiveApp = false;
- }
-
- }
-
- return g_pAppXRTInfo->m_fIsAppXAdaptiveApp;
- }
-
-
- //-----------------------------------------------------------------------------------------
- // length : Upon success, contains the the length of packagePath
- // [in/out]
- //
- // packageRoot : Upon success, contains the full packagePath
- // [out] [ Note: The memory has to be preallocated for the above length]
- //
- HRESULT GetCurrentPackagePath(_Inout_ UINT32* length, _Out_opt_ PWSTR packageRoot)
- {
- PRECONDITION(IsAppXProcess());
- PRECONDITION(CheckPointer(length));
-
- HRESULT hr;
- IfFailRet(CheckInitAppXRT());
-
- IfFailRet(HRESULT_FROM_WIN32((*g_pAppXRTInfo->m_pfnGetCurrentPackagePath)(length, packageRoot)));
- return S_OK;
- }
-
- //-----------------------------------------------------------------------------------------
- // winMetadDataDir : Upon success, contains the absolute path for the winmetadata directory for the adaptive app
- // [out] NOTE: The string the pointer points to is global memory and never should be modified
- //
- HRESULT GetWinMetadataDirForAdaptiveApps(_Out_ LPWSTR* winMetadDataDir)
- {
-
- PRECONDITION(IsAppXProcess());
-
- HRESULT hr;
-
- IfFailRet(CheckInitAppXRT());
-
- if (g_pAppXRTInfo->m_AdaptiveAppWinmetadataDir == nullptr)
- {
- LPCWSTR wzWinMetadataFolder=W("\\WinMetadata");
- NewArrayHolder<WCHAR> wzCompletePath;
- UINT32 length=0;
-
- hr = GetCurrentPackagePath(&length, NULL);
- if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- return hr;
-
- NewArrayHolder<WCHAR> wzPath_holder = new (nothrow) WCHAR[length];
-
- IfNullRet(wzPath_holder);
- IfFailRet(GetCurrentPackagePath(&length, wzPath_holder.GetValue()));
-
- DWORD cchFullPathBuf = length + (DWORD)wcslen(wzWinMetadataFolder) + 1;
- IfNullRet(wzCompletePath = new (nothrow) WCHAR[cchFullPathBuf]);
- IfFailRet(clr::fs::Path::Combine(wzPath_holder.GetValue(), wzWinMetadataFolder, &cchFullPathBuf, wzCompletePath.GetValue()));
- g_pAppXRTInfo->m_AdaptiveAppWinmetadataDir = wzCompletePath.Extract();
- }
-
- *winMetadDataDir = g_pAppXRTInfo->m_AdaptiveAppWinmetadataDir;
-
- return S_OK;
- }
-
-#if defined(FEATURE_APPX_BINDER)
- //-----------------------------------------------------------------------------------------
- // Iterates the current process' packages and returns the first package that contains a
- // file matching wzFileName.
- //
- // wzFileName : The file to look for in the current process' packages. If this is a
- // [in] relative path, then it appends the path to the root of each package in
- // sequence to see if the resulting path points to an existing file. If this
- // is an absolute path, then for each package it determines if the package
- // root is a prefix of wzFileName.
- // pcchPathName : Upon entry contains the length of the buffer pwzPathName, and upon return
- // [in/out] contains either the number of characters written or the buffer size
- // required.
- // pwzPathName : Upon success, contains the absolute path for the first matching file.
- // [out]
- HRESULT FindFileInCurrentPackage(
- PCWSTR wzFileName,
- PUINT32 pcchPathName,
- PWSTR pwzPathName,
- UINT32 uiFlags,
- __in PCWSTR *rgwzAltPaths,
- __in UINT32 cAltPaths,
- FindFindInPackageFlags findInCurrentPackageFlags)
- {
- LIMITED_METHOD_CONTRACT;
- PRECONDITION(IsAppXProcess());
- PRECONDITION(CheckPointer(wzFileName));
- PRECONDITION(CheckPointer(pcchPathName));
- PRECONDITION(CheckPointer(pwzPathName));
-
- HRESULT hr = S_OK;
-
- if (!IsAppXProcess())
- return E_UNEXPECTED;
-
- // PACKAGE_FILTER_ALL_LOADED is obsolete, and shouldn't be used.
- // We also don't currently handle the case where PACKAGE_FILTER_HEAD isn't set.
- _ASSERTE(uiFlags != PACKAGE_FILTER_ALL_LOADED && (uiFlags & PACKAGE_FILTER_HEAD) != 0);
- if (uiFlags == PACKAGE_FILTER_ALL_LOADED || (uiFlags & PACKAGE_FILTER_HEAD) == 0)
- return E_NOTIMPL;
-
- // File name must be non-null and relative
- if (IsNullOrEmpty(wzFileName) || pcchPathName == nullptr || pwzPathName == nullptr)
- return E_INVALIDARG;
-
- // If we've been provided a full path and the file doesn't actually exist
- // then we can immediately say that this function will fail with "file not found".
- bool fIsRelative = clr::fs::Path::IsRelative(wzFileName);
- if (!fIsRelative && !clr::fs::File::Exists(wzFileName))
- return E_FILE_NOT_FOUND;
-
- IfFailRet(CheckInitCurrentPackageInfoCache());
-
- DWORD const cchFileName = static_cast<DWORD>(wcslen(wzFileName));
- DWORD cchFullPathBuf = _MAX_PATH;
- NewArrayHolder<WCHAR> wzFullPathBuf = new (nothrow) WCHAR[cchFullPathBuf];
- IfNullRet(wzFullPathBuf);
-
- auto FindFileInCurrentPackageHelper = [&](LPCWSTR wzPath) -> HRESULT
- {
- HRESULT hr = S_OK;
-
- if (!(findInCurrentPackageFlags & FindFindInPackageFlags_AllowLongFormatPath) && clr::fs::Path::HasLongFormatPrefix(wzPath))
- return COR_E_BAD_PATHNAME; // We can't handle long format paths.
-
- // If the path is relative, concatenate the package root and the file name and see
- // if the file exists.
- if (fIsRelative)
- {
- DWORD cchFullPath = cchFullPathBuf;
- hr = clr::fs::Path::Combine(wzPath, wzFileName, &cchFullPath, wzFullPathBuf);
- if (hr == E_INSUFFICIENT_BUFFER)
- {
- IfNullRet(wzFullPathBuf = new (nothrow) WCHAR[cchFullPathBuf = (cchFullPath + 1)]);
- hr = clr::fs::Path::Combine(wzPath, wzFileName, &cchFullPath, wzFullPathBuf);
- }
- IfFailRet(hr);
-
- if (!clr::fs::Path::IsValid(wzFullPathBuf, cchFullPath, !!(findInCurrentPackageFlags & FindFindInPackageFlags_AllowLongFormatPath)))
- return COR_E_BAD_PATHNAME;
-
- if (clr::fs::File::Exists(wzFullPathBuf))
- {
- DWORD cchPathName = *pcchPathName;
- *pcchPathName = cchFullPath;
- return StringCchCopy(pwzPathName, cchPathName, wzFullPathBuf);
- }
- }
- // If the path is absolute, see if the file name contains the pacakge root as a prefix
- // and if the file exists.
- else
- {
- DWORD cchPath = static_cast<DWORD>(wcslen(wzPath));
-
- // Determine if wzPath is a path prefix of wzFileName
- if (cchPath < cchFileName &&
- _wcsnicmp(wzPath, wzFileName, cchPath) == 0 &&
- (wzFileName[cchPath] == W('\\') || wzPath[cchPath-1] == W('\\'))) // Ensure wzPath is not just a prefix, but a path prefix
- {
- if (clr::fs::File::Exists(wzFileName))
- {
- DWORD cchPathName = *pcchPathName;
- *pcchPathName = cchFileName;
- return StringCchCopy(pwzPathName, cchPathName, wzFileName);
- }
- }
- }
-
- return S_FALSE;
- }; // FindFileInCurrentPackageHelper
-
- if (!(findInCurrentPackageFlags & FindFindInPackageFlags_SkipCurrentPackageGraph))
- {
- PCPACKAGE_INFO pCurNode = reinterpret_cast<PPACKAGE_INFO>(
- g_pAppXRTInfo->m_pCurrentPackageInfo->m_pbCurrentPackageInfo);
- PCPACKAGE_INFO pEndNode = pCurNode + g_pAppXRTInfo->m_pCurrentPackageInfo->m_nCount;
- for (; pCurNode != pEndNode; ++pCurNode)
- {
- IfFailRet(FindFileInCurrentPackageHelper(pCurNode->path));
-
- if (hr == S_OK)
- {
- return hr;
- }
-
- // End search if dependent packages should not be checked.
- if ((uiFlags & PACKAGE_FILTER_DIRECT) == 0)
- {
- break;
- }
- }
- }
-
- // Process alternative paths
- for (UINT iAltPath = 0; iAltPath < cAltPaths; iAltPath++)
- {
- IfFailRet(FindFileInCurrentPackageHelper(rgwzAltPaths[iAltPath]));
-
- if (hr == S_OK)
- {
- return hr;
- }
- }
-
- return E_FILE_NOT_FOUND;
- }
-#endif // FEATURE_APPX_BINDER
-
- //-----------------------------------------------------------------------------------------
- HRESULT GetAppContainerTokenInfoForProcess(
- DWORD dwPid,
- NewArrayHolder<BYTE>& pbAppContainerTokenInfo,
- DWORD* pcbAppContainerTokenInfo)
- {
- LIMITED_METHOD_CONTRACT;
-
- HRESULT hr = S_OK;
-
- pbAppContainerTokenInfo = nullptr;
-
- if (!IsAppXSupported())
- {
- return S_FALSE;
- }
-
- if (dwPid == GetCurrentProcessId())
- {
- if (FAILED(hr = CheckInitAppXRT()))
- {
- SetLastError(hr);
- return S_FALSE;
- }
-
- if (g_pAppXRTInfo->m_pbAppContainerInfo == nullptr)
- {
- return S_FALSE;
- }
- else
- {
- pbAppContainerTokenInfo = g_pAppXRTInfo->m_pbAppContainerInfo.GetValue();
- pbAppContainerTokenInfo.SuppressRelease(); // Caller does not need to free mem.
- if (pcbAppContainerTokenInfo != nullptr)
- {
- *pcbAppContainerTokenInfo = g_pAppXRTInfo->m_cbAppContainerInfo;
- }
- return S_OK;
- }
- }
- else
- {
- return ::GetAppContainerTokenInfoForProcess(dwPid, pbAppContainerTokenInfo, pcbAppContainerTokenInfo);
- }
- }
-
- // Called during NGen to pretend that we're in a certain package. Due to Windows restriction, we can't
- // start NGen worker processes in the right package environment (only in the right AppContainer). So
- // NGen calls this function with a package name, to indicate that all AppX-related code should behave as
- // if the current process is running in that package.
- HRESULT SetCurrentPackageForNGen(__in PCWSTR pszPackageFullName)
- {
- LIMITED_METHOD_CONTRACT;
-
- HRESULT hr = S_OK;
-
- IfFailRet(CheckInitAppXRT());
-
- _ASSERTE(IsAppXSupported());
- _ASSERTE(g_pAppXRTInfo->m_hAppXRTMod != nullptr);
-
- HMODULE hAppXRTMod = g_pAppXRTInfo->m_hAppXRTMod;
- OpenPackageInfoByFullName_t *pfnOpenPackageInfoByFullName
- = reinterpret_cast<OpenPackageInfoByFullName_t*>(GetProcAddress(hAppXRTMod, "OpenPackageInfoByFullName"));
- _ASSERTE(pfnOpenPackageInfoByFullName != nullptr);
- if (pfnOpenPackageInfoByFullName == nullptr)
- return HRESULT_FROM_GetLastError();
-
- ClosePackageInfo_t *pfnClosePackageInfo
- = reinterpret_cast<ClosePackageInfo_t*>(GetProcAddress(hAppXRTMod, "ClosePackageInfo"));
- _ASSERTE(pfnClosePackageInfo != nullptr);
- if (pfnClosePackageInfo == nullptr)
- return HRESULT_FROM_GetLastError();
-
- GetPackageInfo_t *pfnGetPackageInfo
- = reinterpret_cast<GetPackageInfo_t*>(GetProcAddress(hAppXRTMod, "GetPackageInfo"));
- _ASSERTE(pfnGetPackageInfo != nullptr);
- if (pfnGetPackageInfo == nullptr)
- return HRESULT_FROM_GetLastError();
-
- PACKAGE_INFO_REFERENCE packageInfoReference;
- hr = HRESULT_FROM_WIN32(pfnOpenPackageInfoByFullName(pszPackageFullName, 0, &packageInfoReference));
- if (FAILED(hr))
- return hr;
-
- // Automatically close packageInfoReference before we return.
- class PackageInfoReferenceHolder
- {
- public:
- PackageInfoReferenceHolder(ClosePackageInfo_t *pfnClosePackageInfo, PACKAGE_INFO_REFERENCE &packageInfoReference)
- :m_pfnClosePackageInfo(pfnClosePackageInfo),
- m_packageInfoReference(packageInfoReference)
- {
- }
- ~PackageInfoReferenceHolder() { m_pfnClosePackageInfo(m_packageInfoReference); }
- private:
- ClosePackageInfo_t *m_pfnClosePackageInfo;
- PACKAGE_INFO_REFERENCE &m_packageInfoReference;
- } pirh(pfnClosePackageInfo, packageInfoReference);
-
- UINT32 cbBuffer = 0;
- hr = HRESULT_FROM_WIN32(pfnGetPackageInfo(packageInfoReference, PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, nullptr, nullptr));
- if (hr != E_INSUFFICIENT_BUFFER)
- return hr;
-
- NewArrayHolder<BYTE> pbBuffer(new (nothrow) BYTE[cbBuffer]);
- IfNullRet(pbBuffer);
-
- UINT32 nCount = 0;
- IfFailRet(HRESULT_FROM_WIN32(pfnGetPackageInfo(packageInfoReference, PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, pbBuffer, &nCount)));
-
- NewHolder<AppXRTInfo::CurrentPackageInfo> pPkgInfo(
- new (nothrow) AppXRTInfo::CurrentPackageInfo(cbBuffer, pbBuffer.Extract(), nCount));
- IfNullRet(pPkgInfo);
-
- if (InterlockedCompareExchangeT<AppXRTInfo::CurrentPackageInfo>(
- &g_pAppXRTInfo->m_pCurrentPackageInfo, pPkgInfo, nullptr) == nullptr)
- {
- pPkgInfo.SuppressRelease();
- }
-
- g_pAppXRTInfo->m_fIsAppXProcess = true;
- g_pAppXRTInfo->m_fIsAppXNGen = true;
-
- return hr;
- }
-
-#endif // DACCESS_COMPILE
-} // namespace AppX
-
-
-#endif // FEATURE_CORECLR
diff --git a/src/utilcode/ccomprc.cpp b/src/utilcode/ccomprc.cpp
index a4c79fc127..ed902dc6ca 100644
--- a/src/utilcode/ccomprc.cpp
+++ b/src/utilcode/ccomprc.cpp
@@ -261,12 +261,8 @@ HRESULT CCompRC::AddMapNode(LocaleID langId, HRESOURCEDLL hInst, BOOL fMissing)
//*****************************************************************************
// Initialize
//*****************************************************************************
-#ifndef FEATURE_CORECLR
-LPCWSTR CCompRC::m_pDefaultResource = W("mscorrc.dll");
-#else // !FEATURE_CORECLR
LPCWSTR CCompRC::m_pDefaultResource = W("mscorrc.debug.dll");
LPCWSTR CCompRC::m_pFallbackResource= W("mscorrc.dll");
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_PAL
LPCSTR CCompRC::m_pDefaultResourceDomain = "mscorrc.debug";
@@ -482,7 +478,6 @@ CCompRC* CCompRC::GetDefaultResourceDll()
return &m_DefaultResourceDll;
}
-#ifdef FEATURE_CORECLR
LONG CCompRC::m_dwFallbackInitialized = 0;
CCompRC CCompRC::m_FallbackResourceDll;
@@ -510,7 +505,6 @@ CCompRC* CCompRC::GetFallbackResourceDll()
return &m_FallbackResourceDll;
}
-#endif // FEATURE_CORECLR
//*****************************************************************************
@@ -747,7 +741,6 @@ HRESULT CCompRC::LoadString(ResourceCategory eCategory, LocaleID langId, UINT iR
// Failed to load string
if ( hr != E_OUTOFMEMORY && ShouldUseFallback())
{
-#ifdef FEATURE_CORECLR
CCompRC* pFallback=CCompRC::GetFallbackResourceDll();
if (pFallback)
{
@@ -761,13 +754,11 @@ HRESULT CCompRC::LoadString(ResourceCategory eCategory, LocaleID langId, UINT iR
if(SUCCEEDED(hr))
return hr;
}
-#endif
switch (eCategory)
{
case Optional:
hr = E_FAIL;
break;
-#ifdef FEATURE_CORECLR
case DesktopCLR:
hr = E_FAIL;
break;
@@ -837,12 +828,6 @@ HRESULT CCompRC::LoadString(ResourceCategory eCategory, LocaleID langId, UINT iR
// if we got here then we couldn't get the fallback message
// the fallback message is required so just falling through into "Required"
-#else // FEATURE_CORECLR
- // everything that's not optional goes here for Desktop
- case DesktopCLR:
- case Debugging:
- case Error:
-#endif
case Required:
if ( hr != E_OUTOFMEMORY)
@@ -1035,7 +1020,6 @@ HRESULT CCompRC::LoadLibraryThrows(HRESOURCEDLL * pHInst)
PathString rcPath; // Path to resource DLL.
// Try first in the same directory as this dll.
-#if defined(FEATURE_CORECLR)
VALIDATECORECLRCALLBACKS();
@@ -1046,73 +1030,6 @@ HRESULT CCompRC::LoadLibraryThrows(HRESOURCEDLL * pHInst)
hr = LoadLibraryHelper(pHInst, rcPath);
-#else // FEATURE_CORECLR
-
- if (!WszGetModuleFileName(GetModuleInst(), rcPath))
- return HRESULT_FROM_GetLastError();
-
- CopySystemDirectory(rcPath, rcPath);
-
- hr = LoadLibraryHelper(pHInst, rcPath);
- if (hr == E_OUTOFMEMORY)
- return hr;
-
- // In case of default rc file, also try CORSystemDirectory.
- // Note that GetRequestedRuntimeInfo is a function in ths shim. As of 12/06, this is the only
- // place where utilcode appears to take a dependency on the shim. This forces everyone that links
- // with us to also dynamically link to mscoree.dll. Perhaps this should be a delay-load to prevent
- // that static dependency and have a gracefull fallback when the shim isn't installed.
- // We don't do this in DAC builds because mscordacwks.dll cannot take a dependency on other CLR
- // dlls (eg. you must be able to examine a managed dump on a machine without any CLR installed).
-#ifndef DACCESS_COMPILE
- if (FAILED(hr) && m_pResourceFile == m_pDefaultResource)
- {
-#ifdef SELF_NO_HOST
- WCHAR rcVersion[MAX_VERSION_STRING];
- DWORD rcVersionSize;
-
- DWORD corSystemPathSize;
-
- // The reason for using GetRequestedRuntimeInfo is the ability to suppress message boxes
- // with RUNTIME_INFO_DONT_SHOW_ERROR_DIALOG.
- COUNT_T size = MAX_PATH;
- hr = LegacyActivationShim::GetRequestedRuntimeInfo(
- NULL,
- W("v")VER_PRODUCTVERSION_NO_QFE_STR_L,
- NULL,
- 0,
- RUNTIME_INFO_UPGRADE_VERSION|RUNTIME_INFO_DONT_SHOW_ERROR_DIALOG|RUNTIME_INFO_CONSIDER_POST_2_0,
- rcPath.OpenUnicodeBuffer(size-1),
- size,
- &corSystemPathSize,
- rcVersion,
- NumItems(rcVersion),
- &rcVersionSize);
-
- rcPath.CloseBuffer(corSystemPathSize);
-
- if (SUCCEEDED(hr))
- {
- if (rcVersionSize > 0)
- {
- rcPath.Append(rcVersion);
- rcPath.Append(W("\\"));
- }
- }
-#else
- // If we're hosted, we have the advantage of a CoreClrCallbacks reference.
- // More importantly, we avoid calling back to mscoree.dll.
-
- hr = GetClrCallbacks().m_pfnGetCORSystemDirectory(rcPath);
-#endif
- if (SUCCEEDED(hr))
- {
- hr = LoadLibraryHelper(pHInst, rcPath);
- }
- }
-#endif // !DACCESS_COMPILE
-
-#endif // FEATURE_CORECLR
#endif // CROSSGEN_COMPILE
diff --git a/src/utilcode/clrconfig.cpp b/src/utilcode/clrconfig.cpp
index 163974999d..7bd404b5d4 100644
--- a/src/utilcode/clrconfig.cpp
+++ b/src/utilcode/clrconfig.cpp
@@ -30,10 +30,6 @@ CLRConfig::GetConfigValueFunction CLRConfig::s_GetConfigValueCallback = NULL;
//
CLRConfig::GetPerformanceDefaultValueFunction CLRConfig::s_GetPerformanceDefaultValueCallback = NULL;
-#ifdef FEATURE_WIN_DB_APPCOMPAT
-PFN_CptQuirkIsEnabled3 CLRConfig::s_IsQuirkEnabledCallback = NULL;
-PFN_CptQuirkGetData2 CLRConfig::s_GetQuirkValueCallback = NULL;
-#endif
//
// Creating structs using the macro table in CLRConfigValues.h
@@ -100,79 +96,6 @@ PFN_CptQuirkGetData2 CLRConfig::s_GetQuirkValueCallback = NULL;
#undef CONFIG_STRING_INFO_DIRECT_ACCESS
-#ifdef FEATURE_WIN_DB_APPCOMPAT
-
-#define MAX_QUIRK_LENGTH 60
-#define WIN_DB_COMPONENT_NAME W("NETFX.")
-#define WIN_DB_COMPONENT_NAME_LENGTH 6
-
-// queries the DB if the quirk is enabled. If the quirk is enabled then it also gets the value associated with the quirk.
-// pass in quirkData as NULL if the value is not required and only enabled/disabled is needed.
-// Length of quirk cannot be greater than 60. If it is greater than 60 then this api returns E_FAIL.
-HRESULT CLRConfig::getQuirkEnabledAndValueFromWinDB(LPCWSTR wszQuirkName, BOOL* isEnabled, CPT_QUIRK_DATA* quirkData)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- PRECONDITION(CheckPointer(isEnabled, NULL_NOT_OK));
- }
- CONTRACTL_END;
-
- if(wszQuirkName == NULL)
- return E_FAIL;
-
- WCHAR wszCompleteQuirkName[MAX_QUIRK_LENGTH + WIN_DB_COMPONENT_NAME_LENGTH + 1];
- WCHAR wszComponentName[] = WIN_DB_COMPONENT_NAME;
- size_t cchCompleteQuirkName = MAX_QUIRK_LENGTH + WIN_DB_COMPONENT_NAME_LENGTH + 1;
-
- _ASSERT(wcslen(wszComponentName) == WIN_DB_COMPONENT_NAME_LENGTH);
-
- size_t cchOrig = wcslen(wszQuirkName);
- if(cchOrig > MAX_QUIRK_LENGTH)
- {
- return E_FAIL;
- }
-
- // Create comlete name of the quirk. Windows expects complete quirkName i.e. componentName.quirkName
- // eg. ETWEnabled will become NETFX.ETWEnabled
- errno_t err = wcsncpy_s(wszCompleteQuirkName, cchCompleteQuirkName, wszComponentName, WIN_DB_COMPONENT_NAME_LENGTH);
- if (err != 0)
- {
- return E_FAIL;
- }
-
- err = wcscat_s(wszCompleteQuirkName, cchCompleteQuirkName, wszQuirkName);
- if (err != 0)
- {
- return E_FAIL;
- }
-
-
- UINT32 version = 0xFFFFFFFF;
- BOOL fIsEnabled;
- //call windows api
- // Version passed must be 0xFFFFFFFF for NETFX. Passing any other version requires more
- // understanding of the windows API.
- fIsEnabled = s_IsQuirkEnabledCallback(wszCompleteQuirkName,version);
-
- if(fIsEnabled && quirkData != NULL)
- {
- quirkData->Size = sizeof(CPT_QUIRK_DATA);
- // Query for quirkData
- if(!SUCCEEDED(s_GetQuirkValueCallback(wszCompleteQuirkName, quirkData)))
- {
- return E_FAIL;
- }
- }
-
- *isEnabled = fIsEnabled;
-
- return S_OK;
-}
-
-#endif
// Return if a quirk is a enabled.
@@ -190,22 +113,6 @@ BOOL CLRConfig::IsConfigEnabled(const ConfigDWORDInfo & info)
DWORD result = info.defaultValue;
-#ifdef FEATURE_WIN_DB_APPCOMPAT
- // Windows Shim DB should be the first place to look as it applies microsoft enforced policy
- // and overrides setting at any other place like config or registry
- if(CheckLookupOption(info, IgnoreWindowsQuirkDB) == FALSE &&
- s_IsQuirkEnabledCallback != NULL )// Check that IsQuirkEnabledCallback function has been registered.
- {
- BOOL enabledInDB = FALSE;
- if(SUCCEEDED(getQuirkEnabledAndValueFromWinDB(info.name, &enabledInDB, NULL)))
- {
- if(enabledInDB)
- {
- return TRUE;
- }
- }
- }
-#endif
//
// Set up REGUTIL options.
//
@@ -328,40 +235,6 @@ DWORD CLRConfig::GetConfigValue(const ConfigDWORDInfo & info, bool acceptExplici
_ASSERTE (isDefault != nullptr);
-#ifdef FEATURE_WIN_DB_APPCOMPAT
- // Windows Shim DB should be the first place to look as it applies microsoft enforced policy
- // and overrides setting at any other place like config or registry
- if(CheckLookupOption(info, IgnoreWindowsQuirkDB) == FALSE &&
- s_IsQuirkEnabledCallback != NULL )// Check that IsQuirkEnabledCallback function has been registered.
- {
- BOOL isEnabledInDB = FALSE;
- CPT_QUIRK_DATA quirkData;
- if(SUCCEEDED(getQuirkEnabledAndValueFromWinDB(info.name, &isEnabledInDB, &quirkData)))
- {
- if(isEnabledInDB)
- {
- WCHAR *end;
- errno = 0;
- DWORD resultMaybe = wcstoul(quirkData.CommandLine, &end, 0);
-
- // errno is ERANGE if the number is out of range, and end is set to pvalue if
- // no valid conversion exists.
- if (errno != ERANGE && end != quirkData.CommandLine)
- {
- *isDefault = false;
- return resultMaybe;
- }
- else
- {
- // If an invalid value is defined we treat it as the default value.
- // i.e. we don't look further.
- *isDefault = true;
- return info.defaultValue;
- }
- }
- }
- }
-#endif // FEATURE_WIN_DB_APPCOMPAT
//
// Set up REGUTIL options.
@@ -557,30 +430,6 @@ HRESULT CLRConfig::GetConfigValue(const ConfigStringInfo & info, __deref_out_z L
LPWSTR result = NULL;
-#ifdef FEATURE_WIN_DB_APPCOMPAT
- // Windows Shim DB should be the first place to look as it applies microsoft enforced policy
- // and overrides setting at any other place like config or registry
- if(CheckLookupOption(info, IgnoreWindowsQuirkDB) == FALSE &&
- s_IsQuirkEnabledCallback != NULL )// Check that IsQuirkEnabledCallback function has been registered.
- {
-
- BOOL isEnabledInDB = FALSE;
- CPT_QUIRK_DATA quirkData;
- if(SUCCEEDED(getQuirkEnabledAndValueFromWinDB(info.name, &isEnabledInDB, &quirkData)))
- {
- if(isEnabledInDB)
- {
- size_t len = wcslen(quirkData.CommandLine) + 1;
- result = new (nothrow) WCHAR[len];
- if (result == NULL)
- {
- RETURN E_OUTOFMEMORY;
- }
- wcscpy_s(result, len, quirkData.CommandLine);
- }
- }
- }
-#endif // FEATURE_WIN_DB_APPCOMPAT
//
// Set up REGUTIL options.
@@ -808,14 +657,6 @@ void CLRConfig::RegisterGetPerformanceDefaultValueCallback(GetPerformanceDefault
s_GetPerformanceDefaultValueCallback = func;
}
-#ifdef FEATURE_WIN_DB_APPCOMPAT
-void CLRConfig::RegisterWinDbQuirkApis(PFN_CptQuirkIsEnabled3 func1, PFN_CptQuirkGetData2 func2)
-{
- LIMITED_METHOD_CONTRACT;
- s_IsQuirkEnabledCallback = func1;
- s_GetQuirkValueCallback = func2;
-}
-#endif // FEATURE_WIN_DB_APPCOMPAT
//
// Helper method to translate LookupOptions to REGUTIL::CORConfigLevel.
diff --git a/src/utilcode/clrhost.cpp b/src/utilcode/clrhost.cpp
index 8a61eee966..15678a9861 100644
--- a/src/utilcode/clrhost.cpp
+++ b/src/utilcode/clrhost.cpp
@@ -16,9 +16,7 @@
#include "contract.h"
#include "tls.h"
-#if defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE) || defined(CROSSGEN_COMPILE)
CoreClrCallbacks g_CoreClrCallbacks;
-#endif
// In some cirumstance (e.g, the thread suspecd another thread), allocation on heap
@@ -206,7 +204,6 @@ int RFS_HashStack ()
#endif // FAILPOINTS_ENABLED
-#if defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
//-----------------------------------------------------------------------------------
// This is the approved way to get a module handle to mscorwks.dll (or coreclr.dll).
@@ -264,7 +261,6 @@ HMODULE GetCLRModule ()
return g_CoreClrCallbacks.m_hmodCoreCLR;
}
-#endif // defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
#if defined(SELF_NO_HOST)
@@ -402,7 +398,6 @@ LoadsTypeHolder::~LoadsTypeHolder()
// versions in the same process.
//--------------------------------------------------------------------------
-#if defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
//--------------------------------------------------------------------------
// One-time initialized called by coreclr.dll in its dllmain.
@@ -435,7 +430,7 @@ void OnUninitializedCoreClrCallbacks()
// (other than coreclr.dll) that links to utilcode.lib, or that you're using a nohost
// variant of utilcode.lib but hitting code that assumes there is a CLR in the process.
//
- // Under FEATURE_CORECLR (and not SELF_NO_HOST), it is expected that coreclr.dll
+ // It is expected that coreclr.dll
// is the ONLY dll that links to utilcode libraries.
//
// If you must introduce a new dll that links to utilcode.lib, it is your responsibility
@@ -456,4 +451,3 @@ void OnUninitializedCoreClrCallbacks()
}
#endif // _DEBUG
-#endif // defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
diff --git a/src/utilcode/dlwrap.cpp b/src/utilcode/dlwrap.cpp
index 0c9026a421..a6771c9daa 100644
--- a/src/utilcode/dlwrap.cpp
+++ b/src/utilcode/dlwrap.cpp
@@ -77,155 +77,3 @@ VerQueryValueW_NoThrow(
}
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-// The following functions are not used in CoreCLR. Normally LINKER can remove these functions
-// from generated files. But LINKER does it in two steps:
-// 1. If no function in a source file is used, the file is ignored by LINKER
-// 2. If one function is used, LINKER will first make sure all imported functions in the file
-// is available, and then it will remove unused functions.
-// Instead of specifying all libs for imported functions needed by the following codes, we just
-// remove them from compiling phase.
-__success(return)
-BOOL
-CreateUrlCacheEntryW_NoThrow(
- IN LPCWSTR lpszUrlName,
- IN DWORD dwExpectedFileSize,
- IN LPCWSTR lpszFileExtension,
- __out_ecount(MAX_LONGPATH+1) LPWSTR lpszFileName,
- IN DWORD dwReserved
- )
-{
- WRAPPER_NO_CONTRACT;
- HRESULT hr=S_OK;
- BOOL bRet=FALSE;
- EX_TRY
- {
- bRet=CreateUrlCacheEntryW(lpszUrlName,dwExpectedFileSize,lpszFileExtension,
- lpszFileName,dwReserved);
- }
- EX_CATCH_HRESULT(hr);
- if (hr!=S_OK)
- SetLastError(hr);
- return bRet;
-
-}
-
-BOOL
-CommitUrlCacheEntryW_NoThrow(
- IN LPCWSTR lpszUrlName,
- IN LPCWSTR lpszLocalFileName,
- IN FILETIME ExpireTime,
- IN FILETIME LastModifiedTime,
- IN DWORD CacheEntryType,
- IN LPCWSTR lpHeaderInfo,
- IN DWORD dwHeaderSize,
- IN LPCWSTR lpszFileExtension,
- IN LPCWSTR lpszOriginalUrl
- )
-{
- WRAPPER_NO_CONTRACT;
- HRESULT hr=S_OK;
- BOOL bRet=FALSE;
- EX_TRY
- {
- bRet=CommitUrlCacheEntryW(lpszUrlName,lpszLocalFileName,ExpireTime,
- LastModifiedTime,CacheEntryType,(LPWSTR)lpHeaderInfo,
- dwHeaderSize,lpszFileExtension,lpszOriginalUrl);
- }
- EX_CATCH_HRESULT(hr);
- if (hr!=S_OK)
- SetLastError(hr);
- return bRet;
-
-}
-
-BOOL
-InternetTimeToSystemTimeA_NoThrow(
- IN LPCSTR lpszTime, // NULL terminated string
- OUT SYSTEMTIME *pst, // output in GMT time
- IN DWORD dwReserved
- )
-{
- WRAPPER_NO_CONTRACT;
- HRESULT hr=S_OK;
- BOOL bRet=FALSE;
- EX_TRY
- {
- bRet=InternetTimeToSystemTimeA(lpszTime,pst,dwReserved);
- }
- EX_CATCH_HRESULT(hr);
- if (hr!=S_OK)
- SetLastError(hr);
- return bRet;
-
-}
-
-HRESULT
-CoInternetCreateSecurityManager_NoThrow(
- IServiceProvider *pSP,
- IInternetSecurityManager **ppSM,
- DWORD dwReserved
- )
-{
- WRAPPER_NO_CONTRACT;
- HRESULT hr=S_OK;
- EX_TRY
- {
- hr=CoInternetCreateSecurityManager(pSP,ppSM, dwReserved);
- }
- EX_CATCH_HRESULT(hr);
- return hr;
-}
-
-HRESULT
-URLDownloadToCacheFileW_NoThrow(
- LPUNKNOWN lpUnkcaller,
- LPCWSTR szURL,
- __out_ecount(dwBufLength) LPWSTR szFileName,
- DWORD dwBufLength,
- DWORD dwReserved,
- IBindStatusCallback *pBSC
- )
-{
- WRAPPER_NO_CONTRACT;
- HRESULT hr=S_OK;
- EX_TRY
- {
- hr=URLDownloadToCacheFileW(lpUnkcaller,szURL,szFileName,dwBufLength,dwReserved,pBSC);
- }
- EX_CATCH_HRESULT(hr);
- return hr;
-}
-
-HRESULT
-CoInternetGetSession_NoThrow(
- WORD dwSessionMode,
- IInternetSession **ppIInternetSession,
- DWORD dwReserved
- )
-{
- WRAPPER_NO_CONTRACT;
- HRESULT hr=S_OK;
- EX_TRY
- {
- hr=CoInternetGetSession(dwSessionMode,ppIInternetSession,dwReserved);
- }
- EX_CATCH_HRESULT(hr);
- return hr;
-}
-
-HRESULT
-CopyBindInfo_NoThrow(
- const BINDINFO * pcbiSrc, BINDINFO * pbiDest
- )
-{
- WRAPPER_NO_CONTRACT;
- HRESULT hr=S_OK;
- EX_TRY
- {
- hr=CopyBindInfo(pcbiSrc,pbiDest );
- }
- EX_CATCH_HRESULT(hr);
- return hr;
-}
-#endif // FEATURE_CORECLR && !CROSSGEN_COMPILE
diff --git a/src/utilcode/downlevel.cpp b/src/utilcode/downlevel.cpp
index ec8d3f5a15..6ff7b82815 100644
--- a/src/utilcode/downlevel.cpp
+++ b/src/utilcode/downlevel.cpp
@@ -1924,11 +1924,11 @@ namespace DownLevel
if (dwFindNLSStringFlags & (FIND_ENDSWITH | FIND_FROMEND))
{
- retValue = NewApis::LastIndexOfString(lpLocaleName, lpStringSource, cchSource, lpStringValue, cchValue, (int) dwFindNLSStringFlags & FIND_NLS_STRING_FLAGS_NEGATION, dwFindNLSStringFlags & FIND_ENDSWITH);
+ retValue = NewApis::LastIndexOfString(lpLocaleName, lpStringSource, cchSource, lpStringValue, cchValue, (int) dwFindNLSStringFlags & FIND_NLS_STRING_FLAGS_NEGATION, dwFindNLSStringFlags & FIND_ENDSWITH, pcchFound);
}
else
{
- retValue = NewApis::IndexOfString(lpLocaleName, lpStringSource, cchSource, lpStringValue, cchValue, (int) dwFindNLSStringFlags & FIND_NLS_STRING_FLAGS_NEGATION, dwFindNLSStringFlags & FIND_STARTSWITH);
+ retValue = NewApis::IndexOfString(lpLocaleName, lpStringSource, cchSource, lpStringValue, cchValue, (int) dwFindNLSStringFlags & FIND_NLS_STRING_FLAGS_NEGATION, dwFindNLSStringFlags & FIND_STARTSWITH, pcchFound);
}
return retValue;
}
diff --git a/src/utilcode/ex.cpp b/src/utilcode/ex.cpp
index bb164571ad..92b25b0aaf 100644
--- a/src/utilcode/ex.cpp
+++ b/src/utilcode/ex.cpp
@@ -2037,9 +2037,9 @@ static DWORD MarkAsThrownByUsWorker(UINT numArgs, /*out*/ ULONG_PTR exceptionArg
exceptionArgs[0] = arg0;
-#if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) && (defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE))
+#if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES)
exceptionArgs[INSTANCE_TAGGED_SEH_PARAM_ARRAY_SIZE - 1] = (ULONG_PTR) (GetCLRModule());
-#endif // !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) && defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
+#endif // !defined(FEATURE_UTILCODE_NO_DEPENDENCIES)
return INSTANCE_TAGGED_SEH_PARAM_ARRAY_SIZE;
}
@@ -2086,15 +2086,15 @@ BOOL WasThrownByUs(const EXCEPTION_RECORD *pcER, DWORD dwExceptionCode)
{
return FALSE;
}
-#if!defined(FEATURE_UTILCODE_NO_DEPENDENCIES) && (defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE))
+#if!defined(FEATURE_UTILCODE_NO_DEPENDENCIES)
if ( ((ULONG_PTR)(GetCLRModule())) != pcER->ExceptionInformation[INSTANCE_TAGGED_SEH_PARAM_ARRAY_SIZE - 1] )
{
return FALSE;
}
return TRUE;
-#else // !(!defined(FEATURE_UTILCODE_NO_DEPENDENCIES) && (defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)))
+#else // !(!defined(FEATURE_UTILCODE_NO_DEPENDENCIES)
return FALSE;
-#endif // !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) && defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST) || defined(DACCESS_COMPILE)
+#endif // !defined(FEATURE_UTILCODE_NO_DEPENDENCIES)
}
diff --git a/src/utilcode/longfilepathwrappers.cpp b/src/utilcode/longfilepathwrappers.cpp
index 5272d35807..2e493d02b5 100644
--- a/src/utilcode/longfilepathwrappers.cpp
+++ b/src/utilcode/longfilepathwrappers.cpp
@@ -1187,7 +1187,6 @@ FindFirstFileExWrapper(
}
#endif //!FEATURE_PAL
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
#ifndef FEATURE_PAL
@@ -1247,7 +1246,6 @@ BOOL PAL_GetPALDirectoryWrapper(SString& pbuffer)
#endif // FEATURE_PAL
-#endif // FEATURE_CORECLR || CROSSGEN_COMPILE
//Implementation of LongFile Helpers
const WCHAR LongFile::DirectorySeparatorChar = W('\\');
diff --git a/src/utilcode/makepath.cpp b/src/utilcode/makepath.cpp
index 701c525cf4..6e0b56281c 100644
--- a/src/utilcode/makepath.cpp
+++ b/src/utilcode/makepath.cpp
@@ -15,158 +15,6 @@
#include "utilcode.h"
#include "ex.h"
-#ifndef FEATURE_CORECLR
-/***
-*void MakePath() - build path name from components
-*
-*Purpose:
-* create a path name from its individual components
-*
-*Entry:
-* WCHAR *path - pointer to buffer for constructed path
-* WCHAR *drive - pointer to drive component, may or may not contain
-* trailing ':'
-* WCHAR *dir - pointer to subdirectory component, may or may not include
-* leading and/or trailing '/' or '\' characters
-* WCHAR *fname - pointer to file base name component
-* WCHAR *ext - pointer to extension component, may or may not contain
-* a leading '.'.
-*
-*Exit:
-* path - pointer to constructed path name
-*
-*Exceptions:
-*
-*******************************************************************************/
-
-void MakePath (
- __out_ecount (MAX_LONGPATH) WCHAR *path,
- __in LPCWSTR drive,
- __in LPCWSTR dir,
- __in LPCWSTR fname,
- __in LPCWSTR ext
- )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- FORBID_FAULT;
- }
- CONTRACTL_END
-
- const WCHAR *p;
- DWORD count = 0;
-
- /* we assume that the arguments are in the following form (although we
- * do not diagnose invalid arguments or illegal filenames (such as
- * names longer than 8.3 or with illegal characters in them)
- *
- * drive:
- * A ; or
- * A:
- * dir:
- * \top\next\last\ ; or
- * /top/next/last/ ; or
- * either of the above forms with either/both the leading
- * and trailing / or \ removed. Mixed use of '/' and '\' is
- * also tolerated
- * fname:
- * any valid file name
- * ext:
- * any valid extension (none if empty or null )
- */
-
- /* copy drive */
-
- if (drive && *drive) {
- *path++ = *drive;
- *path++ = _T(':');
- count += 2;
- }
-
- /* copy dir */
-
- if ((p = dir)) {
- while (*p) {
- *path++ = *p++;
- count++;
-
- if (count == MAX_LONGPATH) {
- --path;
- *path = _T('\0');
- return;
- }
- }
-
-#ifdef _MBCS
- if (*(p=_mbsdec(dir,p)) != _T('/') && *p != _T('\\')) {
-#else /* _MBCS */
- // suppress warning for the following line; this is safe but would require significant code
- // delta for prefast to understand.
-#ifdef _PREFAST_
- #pragma warning( suppress: 26001 )
-#endif
- if (*(p-1) != _T('/') && *(p-1) != _T('\\')) {
-#endif /* _MBCS */
- *path++ = _T('\\');
- count++;
-
- if (count == MAX_LONGPATH) {
- --path;
- *path = _T('\0');
- return;
- }
- }
- }
-
- /* copy fname */
-
- if ((p = fname)) {
- while (*p) {
- *path++ = *p++;
- count++;
-
- if (count == MAX_LONGPATH) {
- --path;
- *path = _T('\0');
- return;
- }
- }
- }
-
- /* copy ext, including 0-terminator - check to see if a '.' needs
- * to be inserted.
- */
-
- if ((p = ext)) {
- if (*p && *p != _T('.')) {
- *path++ = _T('.');
- count++;
-
- if (count == MAX_LONGPATH) {
- --path;
- *path = _T('\0');
- return;
- }
- }
-
- while ((*path++ = *p++)) {
- count++;
-
- if (count == MAX_LONGPATH) {
- --path;
- *path = _T('\0');
- return;
- }
- }
- }
- else {
- /* better add the 0-terminator */
- *path = _T('\0');
- }
-}
-#endif // !FEATURE_CORECLR
/***
*void Makepath() - build path name from components
@@ -307,57 +155,6 @@ void MakePath (
szPath.Shrink(count + 1);
}
-#if !defined(FEATURE_CORECLR)
-static LPCWSTR g_wszProcessExePath = NULL;
-
-HRESULT GetProcessExePath(LPCWSTR *pwszProcessExePath)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- CONSISTENCY_CHECK(CheckPointer(pwszProcessExePath));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- if (g_wszProcessExePath == NULL)
- {
- DWORD cchProcName = 0;
- NewArrayHolder<WCHAR> wszProcName;
- EX_TRY
- {
- PathString wszProcNameString;
- cchProcName = WszGetModuleFileName(NULL, wszProcNameString);
- if (cchProcName == 0)
- {
- hr = HRESULT_FROM_GetLastError();
- }
- else
- {
- wszProcName = wszProcNameString.GetCopyOfUnicodeString();
- }
- }
- EX_CATCH_HRESULT(hr);
-
- if (FAILED(hr))
- {
- return hr;
- }
-
- if (InterlockedCompareExchangeT(&g_wszProcessExePath, const_cast<LPCWSTR>(wszProcName.GetValue()), NULL) == NULL)
- {
- wszProcName.SuppressRelease();
- }
- }
- _ASSERTE(g_wszProcessExePath != NULL);
- _ASSERTE(SUCCEEDED(hr));
-
- *pwszProcessExePath = g_wszProcessExePath;
- return hr;
-}
-#endif
// Returns the directory for HMODULE. So, if HMODULE was for "C:\Dir1\Dir2\Filename.DLL",
// then this would return "C:\Dir1\Dir2\" (note the trailing backslash).
diff --git a/src/utilcode/newapis.cpp b/src/utilcode/newapis.cpp
index 3717f0280d..e7d4b9f08b 100644
--- a/src/utilcode/newapis.cpp
+++ b/src/utilcode/newapis.cpp
@@ -32,27 +32,6 @@ namespace NewApis
FARPROC result = NULL;
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-
- // First try to use the function defined in the culture dll
- // if we are running on a platform prior to Win7
- if(!IsWindows7Platform())
- {
- // only need to load the culture dll's handle once then we can hold onto it
- static HMODULE hCulture = NULL;
- // if we haven't loaded the culture dll yet
- if (hCulture == NULL)
- {
- UtilCode::LoadLibraryShim(MAKEDLLNAME_W(W("culture")), NULL, 0, &hCulture);
- }
-
- // make sure we were successful before using the handle
- if (hCulture != NULL)
- {
- result=GetProcAddress(hCulture,lpProcName);
- }
- }
-#endif // !FEATURE_CORECLR && !CROSSGEN_COMPILE
// next try the kernel
if(result==NULL)
@@ -203,9 +182,6 @@ namespace NewApis
GetLocaleInfoEx (__in LPCWSTR lpLocaleName, __in LCTYPE LCType, __out_ecount_opt(cchData) LPWSTR lpLCData, __in int cchData)
{
_ASSERTE((lpLCData == NULL && cchData == 0) || (lpLCData != NULL && cchData > 0));
- // ComNlsInfo::nativeInitCultureData calls GetLocaleInfoEx with LcType LOCALE_SNAME
- // to determine if this is a valid culture. We shouldn't assert in this case, but
- // all others we should.
_ASSERTE(LCType == LOCALE_SNAME || NotLeakingFrameworkOnlyCultures(lpLocaleName));
int retVal;
@@ -775,12 +751,14 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
int IndexOfString( __in LPCWSTR lpLocaleName,
__in_ecount(cchCount1) LPCWSTR pString1, // String to search in
__in int cchCount1, // length of pString1
- __in_ecount(cchCount2) LPCWSTR pString2, // String we're looking for
+ __in_ecount(cchCount2) LPCWSTR pString2, // String we're looking for
__in int cchCount2, // length of pString2
__in DWORD dwFlags, // search flags
- __in BOOL startWith) // true if we need to check for prefix case
+ __in BOOL startWith, // true if we need to check for prefix case
+ __out_opt LPINT pcchFound) // length of the string we found in source
{
int iRetVal = -1;
+ int foundLengthInSource = 0;
//
// Check the ranges.
@@ -809,6 +787,7 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
if (dwFlags == COMPARE_OPTIONS_ORDINAL)
{
iRetVal = FastIndexOfString(pString1, cchCount1, pString2, cchCount2);
+ foundLengthInSource = cchCount2;
goto lExit;
}
//For dwFlags, 0 is the default, 1 is ignore case, we can handle both.
@@ -822,6 +801,11 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
iRetVal = FastIndexOfString(pString1, cchCount1, pString2, cchCount2);
else
iRetVal = FastIndexOfStringInsensitive(pString1, cchCount1, pString2, cchCount2);
+
+ // both are ascii strings,
+ // the length should be the same as the length of the string we are searching for.
+ foundLengthInSource = cchCount2;
+
goto lExit;
}
}
@@ -853,6 +837,7 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
if (result == CSTR_EQUAL)
{
iRetVal = iOffset;
+ foundLengthInSource = iLength;
break;
}
else if (result == 0)
@@ -869,6 +854,9 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
{
iRetVal = -1;
}
+
+ if(iRetVal != -1 && pcchFound != NULL)
+ *pcchFound = foundLengthInSource;
return iRetVal;
}
@@ -880,13 +868,16 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
int LastIndexOfString( __in LPCWSTR lpLocaleName,
__in_ecount(cchCount1) LPCWSTR pString1, // String to search in
__in int cchCount1, // length of pString1
- __in_ecount(cchCount2) LPCWSTR pString2, // String we're looking for
+ __in_ecount(cchCount2) LPCWSTR pString2, // String we're looking for
__in int cchCount2, // length of pString2
__in DWORD dwFlags,
- __in BOOL endWith) // check suffix case
+ __in BOOL endWith, // check suffix case
+ __out_opt LPINT pcchFound) // length of the string we found in source
{
INT32 iRetVal = -1;
BOOL comparedOrdinal = FALSE;
+
+ int foundLengthInSource = 0;
// Check for empty strings
if (cchCount1 == 0)
@@ -917,6 +908,7 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
{
iRetVal = FastLastIndexOfString(pString1, cchCount1, pString2, cchCount2);
comparedOrdinal = TRUE;
+ foundLengthInSource = cchCount2;
goto lExit;
}
@@ -931,6 +923,8 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
else
iRetVal = FastLastIndexOfStringInsensitive(pString1, cchCount1, pString2, cchCount2);
comparedOrdinal = TRUE;
+
+ foundLengthInSource = cchCount2;
goto lExit;
}
}
@@ -944,6 +938,7 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
if (NewApis::CompareStringEx(lpLocaleName, dwFlags, pString2, cchCount2, &pString1[cchCount1 + iOffset - iLength], iLength, NULL, NULL, 0) == CSTR_EQUAL)
{
iRetVal= cchCount1 + iOffset - iLength;
+ foundLengthInSource = iLength;
break;
}
}
@@ -961,6 +956,9 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
iRetVal = -1;
}
}
+
+ if(iRetVal != -1 && pcchFound != NULL)
+ *pcchFound = foundLengthInSource;
return iRetVal;
}
@@ -1094,9 +1092,7 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
retVal = ::LCIDToLocaleName(Locale, lpName, cchName, dwFlags | LOCALE_ALLOW_NEUTRAL_NAMES);
#else
-#ifdef FEATURE_CORECLR
retVal = DownLevel::LCIDToLocaleName(Locale, lpName,cchName,dwFlags | LOCALE_ALLOW_NEUTRAL_NAMES);
-#endif // FEATURE_CORECLR
typedef int (WINAPI *PFNLCIDToLocaleName)(LCID, LPWSTR,int ,DWORD);
static PFNLCIDToLocaleName pFNLCIDToLocaleName=NULL;
@@ -1138,9 +1134,7 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
#if !defined(ENABLE_DOWNLEVEL_FOR_NLS)
return ::LocaleNameToLCID(lpName, dwFlags | LOCALE_ALLOW_NEUTRAL_NAMES);
#else
-#ifdef FEATURE_CORECLR
retVal = DownLevel::LocaleNameToLCID(lpName, dwFlags | LOCALE_ALLOW_NEUTRAL_NAMES);
-#endif // FEATURE_CORECLR
typedef int (WINAPI *PFNLocaleNameToLCID)(LPCWSTR,DWORD);
static PFNLocaleNameToLCID pFNLocaleNameToLCID=NULL;
@@ -1278,26 +1272,6 @@ inline BOOL IsInvariantCasing(__in LPCWSTR lpLocaleName, __in DWORD dwMapFlags)
}
-#if !defined(FEATURE_CORECLR)
- BOOL GetNlsVersionEx(__in NLS_FUNCTION Function, __in LPCWSTR lpLocaleName, __inout LPNLSVERSIONINFOEX lpVersionInfo)
- {
-
- typedef BOOL (WINAPI *PFNGetNLSVersionEx)(NLS_FUNCTION, LPCWSTR, LPNLSVERSIONINFOEX);
-
- static PFNGetNLSVersionEx pFNGetNLSVersionEx=NULL;
-
- // See if we still need to find our function
- if (pFNGetNLSVersionEx == NULL)
- {
- // We only call this on Win8 and above, so this should always work.
- pFNGetNLSVersionEx = (PFNGetNLSVersionEx) GetSystemProcAddressForSortingApi("GetNLSVersionEx", NULL);
- }
-
- _ASSERTE(pFNGetNLSVersionEx != NULL);
-
- return pFNGetNLSVersionEx(Function, lpLocaleName, lpVersionInfo);
- }
-#endif
// This is a Windows 7 and above function
// This returns the "specific" locale from an input name, ie: "en" returns "en-US",
diff --git a/src/utilcode/pedecoder.cpp b/src/utilcode/pedecoder.cpp
index c437c21c35..79fe244bda 100644
--- a/src/utilcode/pedecoder.cpp
+++ b/src/utilcode/pedecoder.cpp
@@ -34,7 +34,7 @@ CHECK PEDecoder::CheckFormat() const
{
CHECK(CheckCorHeader());
-#if !defined(FEATURE_MIXEDMODE) && !defined(FEATURE_PREJIT)
+#if !defined(FEATURE_PREJIT)
CHECK(IsILOnly());
#endif
@@ -1075,8 +1075,8 @@ CHECK PEDecoder::CheckCorHeader() const
if (IsStrongNameSigned())
CHECK(HasStrongNameSignature());
- // IL library files (really a misnomer - these are native images) only
- // may have a native image header
+ // IL library files (really a misnomer - these are native images or ReadyToRun images)
+ // only they can have a native image header
if ((pCor->Flags&VAL32(COMIMAGE_FLAGS_IL_LIBRARY)) == 0)
{
CHECK(VAL32(pCor->ManagedNativeHeader.Size) == 0);
@@ -1173,12 +1173,6 @@ CHECK PEDecoder::CheckCorHeader() const
CHECK_OK;
}
-#if !defined(FEATURE_CORECLR)
-#define WHIDBEY_SP2_VERSION_MAJOR 2
-#define WHIDBEY_SP2_VERSION_MINOR 0
-#define WHIDBEY_SP2_VERSION_BUILD 50727
-#define WHIDBEY_SP2_VERSION_PRIVATE_BUILD 3053
-#endif // !defined(FEATURE_CORECLR)
// This function exists to provide compatibility between two different native image
@@ -1236,71 +1230,10 @@ IMAGE_DATA_DIRECTORY *PEDecoder::GetMetaDataHelper(METADATA_SECTION_TYPE type) c
// COR_HEADER and so the value of pDirRet is correct
if (HasNativeHeader())
{
-#ifdef FEATURE_CORECLR
if (type == METADATA_SECTION_MANIFEST)
pDirRet = &GetNativeHeader()->ManifestMetaData;
-#else // FEATURE_CORECLR
-
- IMAGE_DATA_DIRECTORY *pDirNativeHeader = &GetNativeHeader()->ManifestMetaData;
-
- // This code leverages the fact that pre-Whidbey SP2 private build numbers can never
- // be greater than Whidbey SP2 private build number, because otherwise major setup
- // issues would arise. To prevent this, it is standard to bump the private build
- // number up a significant amount for SPs, as was the case between Whidbey SP1 and
- // Whidbey SP2.
- //
- // Since we could be reading an older version of native image, we tell
- // GetNativeVersionInfoMaybeNull to skip checking the native header.
- CORCOMPILE_VERSION_INFO *pVerInfo = GetNativeVersionInfoMaybeNull(true);
- bool fIsPreWhidbeySP2 = false;
-
- // If pVerInfo is NULL, we assume that we're in an NGEN compilation domain and that
- // the information has not yet been written. Since an NGEN compilation domain running
- // in the v4.0 runtime can only complie v4.0 native images, we'll assume the default
- // fIsPreWhidbeySP2 value (false) is correct.
- if (pVerInfo != NULL && pVerInfo->wVersionMajor <= WHIDBEY_SP2_VERSION_MAJOR)
- {
- if (pVerInfo->wVersionMajor < WHIDBEY_SP2_VERSION_MAJOR)
- fIsPreWhidbeySP2 = true;
- else if (pVerInfo->wVersionMajor == WHIDBEY_SP2_VERSION_MAJOR)
- {
- // If the sp2 minor version isn't 0, we need this logic:
- // if (pVerInfo->wVersionMinor < WHIDBEY_SP2_VERSION_MINOR)
- // fIsPreWhidbeySP2 = true;
- // else
- // However, if it is zero, with that logic we get a warning about the comparison
- // of an unsigned variable to zero always being false.
- _ASSERTE(WHIDBEY_SP2_VERSION_MINOR == 0);
-
- if (pVerInfo->wVersionMinor == WHIDBEY_SP2_VERSION_MINOR)
- {
- if (pVerInfo->wVersionBuildNumber < WHIDBEY_SP2_VERSION_BUILD)
- fIsPreWhidbeySP2 = true;
- else if (pVerInfo->wVersionBuildNumber == WHIDBEY_SP2_VERSION_BUILD)
- {
- if (pVerInfo->wVersionPrivateBuildNumber < WHIDBEY_SP2_VERSION_PRIVATE_BUILD)
- fIsPreWhidbeySP2 = true;
- }
- }
- }
- }
-
- // In pre-Whidbey SP2, pDirRet points to manifest and pDirNativeHeader points to full.
- if (fIsPreWhidbeySP2)
- {
- if (type == METADATA_SECTION_FULL)
- pDirRet = pDirNativeHeader;
- }
- // In Whidbey SP2 and later, pDirRet points to full and pDirNativeHeader points to manifest.
- else
- {
- if (type == METADATA_SECTION_MANIFEST)
- pDirRet = pDirNativeHeader;
- }
-
-#endif // FEATURE_CORECLR
}
@@ -1896,7 +1829,7 @@ BOOL PEDecoder::HasNativeHeader() const
#ifdef FEATURE_PREJIT
// Pretend that ready-to-run images do not have native header
- RETURN (((GetCorHeader()->Flags & VAL32(COMIMAGE_FLAGS_IL_LIBRARY)) != 0) && !HasReadyToRunHeader());
+ RETURN (GetCorHeader() && ((GetCorHeader()->Flags & VAL32(COMIMAGE_FLAGS_IL_LIBRARY)) != 0) && !HasReadyToRunHeader());
#else
RETURN FALSE;
#endif
diff --git a/src/utilcode/peinformation.cpp b/src/utilcode/peinformation.cpp
index 948948a4da..20a9fe18b0 100644
--- a/src/utilcode/peinformation.cpp
+++ b/src/utilcode/peinformation.cpp
@@ -11,100 +11,6 @@
#include "utilcode.h"
#include "peinformation.h"
-#if defined(FEATURE_FUSION) && !defined(DACCESS_COMPILE)
-
-extern BOOL g_fWow64Process; // Wow64 Process
-
-PEKIND GetCurrentRealProcessorPEKIND()
-{
- PEKIND curProcessorPEKind = TargetNativePEKIND();
-
-#ifdef _TARGET_X86_
- if (g_fWow64Process)
- {
- SYSTEM_INFO si = {0};
-
- GetNativeSystemInfo(&si);
- switch (si.wProcessorArchitecture)
- {
- case PROCESSOR_ARCHITECTURE_AMD64:
- curProcessorPEKind = peAMD64;
- break;
- default:
- _ASSERTE(FALSE);
- curProcessorPEKind = peInvalid;
- break;
- }
- }
-#endif // _TARGET_X86_
-
- return curProcessorPEKind;
-}
-
-HRESULT RuntimeIsValidAssemblyOnThisPlatform_CheckProcessorArchitecture(PEKIND processorArchitecture, BOOL bForInstall)
-{
- LIMITED_METHOD_CONTRACT;
-
- HRESULT hr = S_OK;
-
- // MSIL / legacy images always allowed
- if (IsPEMSIL(processorArchitecture) || (processorArchitecture == peNone))
- {
- goto Exit;
- }
- else if (IsPE32(processorArchitecture))
- {
-#ifdef _TARGET_ARM_
- // ARM can use only native ones
- if (processorArchitecture != TargetNativePEKIND())
- {
- hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
- goto Exit;
- }
-
-#else //!_TARGET_ARM_
- //ARM assemblies can be installed only on ARM
- if (processorArchitecture == peARM)
- {
- hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
- goto Exit;
- }
-#endif //!_TARGET_ARM_
-
- if (bForInstall)
- {
- goto Exit;
- }
- else
- {
- // won't allow bind to x86 while in 64 bit process.
- if (!IsProcess32())
- {
- hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
- }
- goto Exit;
- }
- }
- // 64 bit images must match processor type
- else if(IsPE64(processorArchitecture))
- {
- if (!IsProcess32() && (processorArchitecture == TargetNativePEKIND()))
- {
- goto Exit;
- }
- else if (bForInstall && (GetCurrentRealProcessorPEKIND() == processorArchitecture))
- {
- goto Exit;
- }
- }
-
- // Everything else, fails match
- hr = HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
-
-Exit:
- return hr;
-}
-#endif // FEATURE_FUSION && !DACCESS_COMPILE
HRESULT TranslatePEToArchitectureType(CorPEKind CLRPeKind, DWORD dwImageType, PEKIND * pPeKind)
{
diff --git a/src/utilcode/prettyprintsig.cpp b/src/utilcode/prettyprintsig.cpp
index 7e9028ddab..fc0844ce4a 100644
--- a/src/utilcode/prettyprintsig.cpp
+++ b/src/utilcode/prettyprintsig.cpp
@@ -167,7 +167,7 @@ LPCWSTR PrettyPrintSigWorker(
//*****************************************************************************
//*****************************************************************************
-// pretty prints 'type' to the buffer 'out' returns a poitner to the next type,
+// pretty prints 'type' to the buffer 'out' returns a pointer to the next type,
// or 0 on a format failure
static PCCOR_SIGNATURE PrettyPrintType(
@@ -562,7 +562,7 @@ HRESULT PrettyPrintSigWorkerInternal(
#endif
//*****************************************************************************
//*****************************************************************************
-// pretty prints 'type' to the buffer 'out' returns a poitner to the next type,
+// pretty prints 'type' to the buffer 'out' returns a pointer to the next type,
// or 0 on a format failure
__checkReturn
diff --git a/src/utilcode/registrywrapper.cpp b/src/utilcode/registrywrapper.cpp
index f6b88db977..b3c4b42946 100644
--- a/src/utilcode/registrywrapper.cpp
+++ b/src/utilcode/registrywrapper.cpp
@@ -74,288 +74,3 @@
#include "clrconfig.h"
#include "strsafe.h"
-#if !defined(FEATURE_UTILCODE_NO_DEPENDENCIES) && !defined(FEATURE_CORECLR)
-
-static LPCWSTR kRegistryRootKey = W("SOFTWARE\\");
-static const HKEY kRegistryRootHive = HKEY_LOCAL_MACHINE;
-static LPCWSTR kWow6432Node = W("Wow6432Node\\");
-static LPCWSTR kMicrosoftDotNetFrameworkPolicy = W("Microsoft\\.NETFramework\\Policy");
-static LPCWSTR wszHKLM = W("HKLM\\");
-static WCHAR * g_registryRoot = NULL;
-static volatile bool g_initialized = false;
-static const WCHAR BACKSLASH_CHARACTER[] = W("\\");
-
-//
-// Called the first time we use ClrRegCreateKeyEx or ClrRegOpenKeyEx to determine if the registry redirection
-// config value has been set. If so, we parse it into g_registryRoot
-// If the config string is mal-formed, we don't set the global variable.
-//
-HRESULT ParseRegistryRootConfigValue()
-{
- if (!IsNgenOffline())
- {
- return ERROR_SUCCESS;
- }
-
- CLRConfigStringHolder configValue(CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_RegistryRoot));
- // Since IsNgenOffline returned true, this better not be NULL
- if (configValue == NULL)
- return ERROR_BAD_ARGUMENTS;
-
- if (_wcsnicmp(configValue, wszHKLM, wcslen(wszHKLM)) != 0)
- {
- return ERROR_BAD_ARGUMENTS;
- }
-
- // The rest of the string is the location of the redirected registry key
- LPWSTR configValueKey = (LPWSTR)configValue;
- configValueKey = _wcsninc(configValueKey, wcslen(wszHKLM));
-
- size_t len = wcslen(configValueKey) + 1;
-
- bool appendBackslash = false;
- if (configValueKey[wcslen(configValueKey) - 1] != W('\\'))
- {
- appendBackslash = true;
- len += wcslen(BACKSLASH_CHARACTER);
- }
- g_registryRoot = new (nothrow) WCHAR[len];
-
- if (g_registryRoot == NULL)
- {
- return ERROR_NOT_ENOUGH_MEMORY;
- }
-
- wcscpy_s(g_registryRoot, len, configValueKey);
- if (appendBackslash)
- {
- StringCchCat(g_registryRoot, len, BACKSLASH_CHARACTER);
- }
-
- return ERROR_SUCCESS;
-}
-
-//
-// This is our check that the target machine is 32/64bit
-// If 32bit only, there will be no Wow6432Node key
-// If 64bit, there will be a Wow6432Node key
-//
-HRESULT CheckWow6432NodeNetFxExists(bool * fResult)
-{
- static bool bInitialized = false;
- static bool bNodeExists = false;
- HRESULT hr = ERROR_SUCCESS;
-
- if (!bInitialized)
- {
- size_t redirectedLength = wcslen(g_registryRoot) + wcslen(kWow6432Node) + wcslen(kMicrosoftDotNetFrameworkPolicy) + 1;
- LPWSTR lpRedirectedKey = new (nothrow) WCHAR[redirectedLength];
-
- if (lpRedirectedKey == NULL)
- {
- return ERROR_NOT_ENOUGH_MEMORY;
- }
-
- wcscpy_s(lpRedirectedKey, redirectedLength, g_registryRoot);
- StringCchCat(lpRedirectedKey, redirectedLength, kWow6432Node);
- StringCchCat(lpRedirectedKey, redirectedLength, kMicrosoftDotNetFrameworkPolicy);
-
- HKEY hkey;
- hr = RegOpenKeyExW(HKEY_LOCAL_MACHINE, lpRedirectedKey, 0, KEY_READ, &hkey);
- bNodeExists = hr == ERROR_SUCCESS;
-
- if (hr == ERROR_FILE_NOT_FOUND)
- {
- hr = ERROR_SUCCESS;
- }
-
- if (hkey)
- {
- RegCloseKey(hkey);
- }
- bInitialized = true;
- }
- *fResult = bNodeExists;
- return hr;
-}
-
-HRESULT CheckUseWow6432Node(REGSAM samDesired, bool * fResult)
-{
- HRESULT hr = ERROR_SUCCESS;
- bool fWow6432NodeExists = false;
-
- hr = CheckWow6432NodeNetFxExists(&fWow6432NodeExists);
- if (hr == ERROR_SUCCESS)
- {
- if (!fWow6432NodeExists)
- {
- *fResult = false;
- } else
- {
-#if defined(_WIN64)
- *fResult = false;
-#else
- *fResult = true;
-#endif
- // If KEY_WOW64_64KEY or KEY_WOW64_32KEY are set, override
- // If both are set, the actual registry call will fail with ERROR_INVALID_PARAMETER
- // so no worries here
- if (samDesired & KEY_WOW64_64KEY)
- {
- *fResult = false;
- } else if (samDesired & KEY_WOW64_32KEY)
- {
- *fResult = true;
- }
- }
- }
- return hr;
-}
-
-//
-// lpRedirectedKey is allocated and returned from this method. Caller owns the new string and
-// should release
-//
-__success(return == ERROR_SUCCESS)
-HRESULT RedirectKey(REGSAM samDesired, HKEY hKey, LPCWSTR lpKey, __deref_out_z LPWSTR * lpRedirectedKey)
-{
- if (hKey != kRegistryRootHive || _wcsnicmp(lpKey, kRegistryRootKey, wcslen(kRegistryRootKey)) != 0)
- {
- *lpRedirectedKey = NULL;
- return ERROR_SUCCESS;
- }
-
- LPCWSTR lpRootStrippedKey = lpKey + wcslen(kRegistryRootKey);
- size_t redirectedLength = wcslen(g_registryRoot) + wcslen(lpRootStrippedKey) + 1;
-
- bool bUseWow = false;
- HRESULT hr = CheckUseWow6432Node(samDesired, &bUseWow);
-
- if (hr != ERROR_SUCCESS)
- {
- return hr;
- }
-
- if (bUseWow)
- {
- redirectedLength += wcslen(kWow6432Node);
- }
-
- *lpRedirectedKey = new (nothrow) WCHAR[redirectedLength];
-
- if (*lpRedirectedKey == NULL)
- {
- return ERROR_NOT_ENOUGH_MEMORY;
- }
-
- wcscpy_s(*lpRedirectedKey, redirectedLength, g_registryRoot);
- if (bUseWow)
- {
- StringCchCat(*lpRedirectedKey, redirectedLength, kWow6432Node);
- }
-
- StringCchCat(*lpRedirectedKey, redirectedLength, lpRootStrippedKey);
-
- return ERROR_SUCCESS;
-}
-
-LONG ClrRegCreateKeyEx(
- HKEY hKey,
- LPCWSTR lpSubKey,
- DWORD Reserved,
- __in_opt LPWSTR lpClass,
- DWORD dwOptions,
- REGSAM samDesired,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes,
- PHKEY phkResult,
- LPDWORD lpdwDisposition
- )
-{
- HRESULT hr;
- if (!g_initialized)
- {
- hr = ParseRegistryRootConfigValue();
- if (hr != ERROR_SUCCESS)
- return hr;
- g_initialized = true;
- }
-
- if (g_registryRoot != NULL)
- {
- NewArrayHolder<WCHAR> lpRedirectedKey(NULL);
- hr = RedirectKey(samDesired, hKey, lpSubKey, &lpRedirectedKey);
- // We don't want to touch the registry if we're low on memory and can't redirect properly. It could lead
- // to use reading and writing to two separate registries and corrupting both in the process
- if (hr != ERROR_SUCCESS)
- return hr;
- LPCWSTR lpKeyToUse = lpRedirectedKey == NULL ? lpSubKey : lpRedirectedKey;
- return RegCreateKeyExW(hKey, lpKeyToUse, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
- }
- return RegCreateKeyExW(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
-} // ClrRegCreateKeyEx
-
-LONG ClrRegOpenKeyEx(
- HKEY hKey,
- LPCWSTR lpSubKey,
- DWORD ulOptions,
- REGSAM samDesired,
- PHKEY phkResult
- )
-{
- HRESULT hr;
- if (!g_initialized)
- {
- hr = ParseRegistryRootConfigValue();
- if (hr != ERROR_SUCCESS)
- return hr;
- g_initialized = true;
- }
-
- if (g_registryRoot != NULL)
- {
- NewArrayHolder<WCHAR> lpRedirectedKey(NULL);
- hr = RedirectKey(samDesired, hKey, lpSubKey, &lpRedirectedKey);
- // We don't want to touch the registry if we're low on memory and can't redirect properly. It could lead
- // to use reading and writing to two separate registries and corrupting both in the process
- if (hr != ERROR_SUCCESS)
- return hr;
- LPCWSTR lpKeyToUse = lpRedirectedKey == NULL ? lpSubKey : lpRedirectedKey;
- return RegOpenKeyExW(hKey, lpKeyToUse, ulOptions, samDesired, phkResult);
- }
- return RegOpenKeyExW(hKey, lpSubKey, ulOptions, samDesired, phkResult);
-}
-
-//
-// Determine whether we're running Offline Ngen for Build Lab based on the settings of several Config Values.
-//
-bool IsNgenOffline()
-{
- static volatile bool fInitialized = false;
- static volatile bool fNgenOffline = false;
-
- if (!fInitialized)
- {
- REGUTIL::CORConfigLevel kCorConfigLevel = static_cast<REGUTIL::CORConfigLevel>(REGUTIL::COR_CONFIG_ENV);
- CLRConfigStringHolder pwzConfigInstallRoot = REGUTIL::GetConfigString_DontUse_(CLRConfig::INTERNAL_InstallRoot,
- TRUE /* Prepend Complus */,
- kCorConfigLevel,
- FALSE /* fUsePerfCache */);
- CLRConfigStringHolder pwzConfigNicPath(CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_NicPath));
- CLRConfigStringHolder pwzRegistryRoot(CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_RegistryRoot));
- CLRConfigStringHolder pwzConfigAssemblyPath(CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_AssemblyPath));
- CLRConfigStringHolder pwzConfigAssemblyPath2(CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_AssemblyPath2));
- if (pwzConfigInstallRoot != NULL &&
- pwzConfigNicPath != NULL &&
- pwzConfigAssemblyPath != NULL &&
- pwzConfigAssemblyPath2 != NULL &&
- pwzRegistryRoot != NULL)
- {
- fNgenOffline = true;
- }
- fInitialized = true;
- }
-
- return fNgenOffline;
-}
-
-#endif //!FEATURE_UTILCODE_NO_DEPENDENCIES && !FEATURE_CORECLR
diff --git a/src/utilcode/regutil.cpp b/src/utilcode/regutil.cpp
index d611ef965f..c38c38907a 100644
--- a/src/utilcode/regutil.cpp
+++ b/src/utilcode/regutil.cpp
@@ -111,19 +111,6 @@ LPWSTR REGUTIL::EnvGetString(LPCWSTR name, BOOL fPrependCOMPLUS)
#ifdef ALLOW_REGISTRY
-#ifndef FEATURE_CORECLR
-
-//*****************************************************************************
-// Gives the use the ability to turn on/off REGUTIL's ability to read from
-// the registry. This is useful in mscoree.dll on startup, in order to avoid
-// loading advapi32 and rpcrt4 until we're ready for them
-//*****************************************************************************
-void REGUTIL::AllowRegistryUse(BOOL fAllowUse)
-{
- s_fUseRegistry = fAllowUse;
-}// AllowRegistryUse
-
-#endif // !FEATURE_CORECLR
#endif // ALLOW_REGISTRY
@@ -522,690 +509,6 @@ DWORD REGUTIL::GetConfigFlag_DontUse_(LPCWSTR name, DWORD bitToSet, BOOL defValu
#ifdef ALLOW_REGISTRY
-#ifndef FEATURE_CORECLR
-
-//*****************************************************************************
-// Open's the given key and returns the value desired. If the key or value is
-// not found, then the default is returned.
-//*****************************************************************************
-long REGUTIL::GetLong( // Return value from registry or default.
- LPCTSTR szName, // Name of value to get.
- long iDefault, // Default value to return if not found.
- LPCTSTR szKey, // Name of key, NULL==default.
- HKEY hKeyVal) // What key to work on.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- FORBID_FAULT;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- long iValue; // The value to read.
- DWORD iType; // Type of value to get.
- DWORD iSize; // Size of buffer.
- HKEY hKey; // Key for the registry entry.
-
- _ASSERTE(UseRegistry());
-
- FAULT_NOT_FATAL(); // We don't report OOM errors here, we return a default value.
-
- // Open the key if it is there.
- if (ERROR_SUCCESS != WszRegOpenKeyEx(hKeyVal, (szKey) ? szKey : FRAMEWORK_REGISTRY_KEY_W, 0, KEY_READ, &hKey))
- return (iDefault);
-
- // Read the key value if found.
- iType = REG_DWORD;
- iSize = sizeof(long);
- if (ERROR_SUCCESS != WszRegQueryValueEx(hKey, szName, NULL,
- &iType, (LPBYTE)&iValue, &iSize) || iType != REG_DWORD)
- iValue = iDefault;
-
- // We're done with the key now.
- VERIFY(!RegCloseKey(hKey));
- return (iValue);
-}
-
-
-// Opens or creates desired reg key, then writes iValue
-//*****************************************************************************
-long REGUTIL::SetOrCreateLong( // Return value from registry or default.
- LPCTSTR szName, // Name of value to get.
- long iValue, // Value to set.
- LPCTSTR szKey, // Name of key, NULL==default.
- HKEY hKeyVal) // What key to work on.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- _ASSERTE(UseRegistry());
-
- long lRtn; // Return code.
- HKEY hKey; // Key for the registry entry.
-
-
- // Open the key if it is there, else create it
- if (WszRegCreateKeyEx(hKeyVal,
- (szKey) ? szKey : FRAMEWORK_REGISTRY_KEY_W,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_WRITE,
- NULL,
- &hKey,
- NULL) != ERROR_SUCCESS)
- {
- return (-1);
- }
-
- // Read the key value if found.
- lRtn = WszRegSetValueEx(hKey, szName, NULL, REG_DWORD, (const BYTE *) &iValue, sizeof(DWORD));
-
- // We're done with the key now.
- VERIFY(!RegCloseKey(hKey));
- return (lRtn);
-}
-
-
-//*****************************************************************************
-// Open's the given key and returns the value desired. If the key or value is
-// not found, then the default is returned.
-//*****************************************************************************
-long REGUTIL::SetLong( // Return value from registry or default.
- LPCTSTR szName, // Name of value to get.
- long iValue, // Value to set.
- LPCTSTR szKey, // Name of key, NULL==default.
- HKEY hKeyVal) // What key to work on.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- _ASSERTE(UseRegistry());
-
- long lRtn; // Return code.
- HKEY hKey; // Key for the registry entry.
-
- // Open the key if it is there.
- if (ERROR_SUCCESS != WszRegOpenKey(hKeyVal, (szKey) ? szKey : FRAMEWORK_REGISTRY_KEY_W, &hKey))
- return (-1);
-
- // Read the key value if found.
- lRtn = WszRegSetValueEx(hKey, szName, NULL, REG_DWORD, (const BYTE *) &iValue, sizeof(DWORD));
-
- // We're done with the key now.
- VERIFY(!RegCloseKey(hKey));
- return (lRtn);
-}
-
-//*****************************************************************************
-// Set an entry in the registry of the form:
-// HKEY_CLASSES_ROOT\szKey\szSubkey = szValue. If szSubkey or szValue are
-// NULL, omit them from the above expression.
-//*****************************************************************************
-BOOL REGUTIL::SetKeyAndValue( // TRUE or FALSE.
- LPCTSTR szKey, // Name of the reg key to set.
- LPCTSTR szSubkey, // Optional subkey of szKey.
- LPCTSTR szValue) // Optional value for szKey\szSubkey.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- _ASSERTE(UseRegistry());
-
- size_t nLen = _tcslen(szKey) + 1;
- if (szSubkey)
- nLen += (_tcslen(szSubkey) + 1);
-
- NewArrayHolder<TCHAR> rcKey = new (nothrow) TCHAR[nLen]; // Buffer for the full key name.
- if (rcKey == NULL)
- return FALSE;
-
- HKEY hKey = NULL; // Handle to the new reg key.
-
- // Init the key with the base key name.
- _tcscpy_s(rcKey, nLen, szKey);
-
- // Append the subkey name (if there is one).
- if (szSubkey != NULL)
- {
- _tcscat_s(rcKey, nLen, _T("\\"));
- _tcscat_s(rcKey, nLen, szSubkey);
- }
-
- // Create the registration key.
- if (WszRegCreateKeyEx(HKEY_CLASSES_ROOT, rcKey, 0, NULL,
- REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
- &hKey, NULL) != ERROR_SUCCESS)
- return(FALSE);
-
- // Set the value (if there is one).
- if (szValue != NULL)
- if( WszRegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *) szValue,
- (Wszlstrlen(szValue)+1) * sizeof(TCHAR)) != ERROR_SUCCESS ) {
- VERIFY(!RegCloseKey(hKey));
- return(FALSE);
- }
-
- VERIFY(!RegCloseKey(hKey));
- return(TRUE);
-}
-
-
-//*****************************************************************************
-// Delete an entry in the registry of the form:
-// HKEY_CLASSES_ROOT\szKey\szSubkey.
-//*****************************************************************************
-LONG REGUTIL::DeleteKey( // TRUE or FALSE.
- LPCTSTR szKey, // Name of the reg key to set.
- LPCTSTR szSubkey) // Subkey of szKey.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- _ASSERTE(UseRegistry());
-
- size_t nLen = _tcslen(szKey) + 1;
- if (szSubkey)
- nLen += (_tcslen(szSubkey) + 1);
-
- NewArrayHolder<TCHAR> rcKey = new (nothrow) TCHAR[nLen]; // Buffer for the full key name.
- if (rcKey == NULL)
- return ERROR_NOT_ENOUGH_MEMORY;
-
- // Init the key with the base key name.
- _tcscpy_s(rcKey, nLen, szKey);
-
- // Append the subkey name (if there is one).
- if (szSubkey != NULL)
- {
- _tcscat_s(rcKey, nLen, _T("\\"));
- _tcscat_s(rcKey, nLen, szSubkey);
- }
-
- // Delete the registration key.
- return WszRegDeleteKey(HKEY_CLASSES_ROOT, rcKey);
-}
-
-
-//*****************************************************************************
-// Open the key, create a new keyword and value pair under it.
-//*****************************************************************************
-BOOL REGUTIL::SetRegValue( // Return status.
- LPCTSTR szKeyName, // Name of full key.
- LPCTSTR szKeyword, // Name of keyword.
- LPCTSTR szValue) // Value of keyword.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- _ASSERTE(UseRegistry());
-
- HKEY hKey; // Handle to the new reg key.
-
- // Create the registration key.
- if (WszRegCreateKeyEx(HKEY_CLASSES_ROOT, szKeyName, 0, NULL,
- REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
- &hKey, NULL) != ERROR_SUCCESS)
- return (FALSE);
-
- // Set the value (if there is one).
- if (szValue != NULL)
- if( WszRegSetValueEx(hKey, szKeyword, 0, REG_SZ, (BYTE *)szValue,
- (Wszlstrlen(szValue)+1) * sizeof(TCHAR)) != ERROR_SUCCESS) {
- VERIFY(!RegCloseKey(hKey));
- return(FALSE);
- }
-
- VERIFY(!RegCloseKey(hKey));
- return (TRUE);
-}
-
-
-//*****************************************************************************
-// Does standard registration of a CoClass with a progid.
-//*****************************************************************************
-HRESULT REGUTIL::RegisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID.
- LPCTSTR szDesc, // Description of the class.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID, // Class progid.
- LPCTSTR szThreadingModel, // What threading model to use.
- LPCTSTR szModule, // Path to class.
- HINSTANCE hInst, // Handle to module being registered
- LPCTSTR szAssemblyName, // Optional Assembly,
- LPCTSTR szVersion, // Optional Runtime version (directory containing runtime)
- BOOL fExternal, // flag - External to mscoree.
- BOOL fRelativePath) // flag - Relative path in szModule
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- WCHAR rcCLSID[256]; // CLSID\\szID.
- WCHAR rcInproc[_MAX_PATH+64]; // CLSID\\InprocServer32
- WCHAR rcProgID[256]; // szProgIDPrefix.szClassProgID
- WCHAR rcIndProgID[256]; // rcProgID.iVersion
- WCHAR rcShim[_MAX_PATH];
- HRESULT hr;
-
- // Format the prog ID values.
- VERIFY(_snwprintf_s(rcIndProgID, _countof(rcIndProgID), _TRUNCATE, W("%s.%s"), szProgIDPrefix, szClassProgID));
-
- VERIFY(_snwprintf_s(rcProgID, _countof(rcProgID), _TRUNCATE, W("%s.%d"), rcIndProgID, iVersion));
-
- // Do the initial portion.
- if (FAILED(hr = RegisterClassBase(rclsid, szDesc, rcProgID, rcIndProgID, rcCLSID, NumItems(rcCLSID))))
- return (hr);
-
- VERIFY(_snwprintf_s(rcInproc, _countof(rcInproc), _TRUNCATE, W("%s\\%s"), rcCLSID, W("InprocServer32")));
-
- if (!fExternal){
- SetKeyAndValue(rcCLSID, W("InprocServer32"), szModule);
- }
- else{
- LPCTSTR pSep = szModule;
- if (!fRelativePath && szModule) {
- pSep = wcsrchr(szModule, W('\\'));
- if(pSep == NULL)
- pSep = szModule;
- else
- pSep++;
- }
- HMODULE hMod = WszLoadLibrary(W("mscoree.dll"));
- if (!hMod)
- return E_FAIL;
-
- DWORD ret;
- VERIFY(ret = WszGetModuleFileName(hMod, rcShim, NumItems(rcShim)));
- FreeLibrary(hMod);
- if( !ret )
- return E_FAIL;
-
- // Set the server path.
- SetKeyAndValue(rcCLSID, W("InprocServer32"), rcShim);
- if(pSep)
- SetKeyAndValue(rcCLSID, W("Server"), pSep);
-
- if(szAssemblyName) {
- SetRegValue(rcInproc, W("Assembly"), szAssemblyName);
- SetRegValue(rcInproc, W("Class"), rcIndProgID);
- }
- }
-
- // Set the runtime version, it needs to be passed in from the outside
- if(szVersion != NULL) {
- LPCTSTR pSep2 = NULL;
- LPTSTR pSep1 = const_cast<LPTSTR>(wcsrchr(szVersion, W('\\')));
- if(pSep1 != NULL) {
- *pSep1 = '\0';
- pSep2 = wcsrchr(szVersion, W('\\'));
- if (!pSep2)
- pSep2 = szVersion;
- else
- pSep2 = pSep2++; // exclude '\\'
- }
- else
- pSep2 = szVersion;
-
- size_t bufLen = wcslen(rcInproc)+wcslen(pSep2)+2;
- WCHAR* rcVersion = new (nothrow) WCHAR[bufLen];
- if(rcVersion==NULL)
- return (E_OUTOFMEMORY);
- wcscpy_s(rcVersion, bufLen, rcInproc);
- wcscat_s(rcVersion, bufLen, W("\\"));
- wcscat_s(rcVersion, bufLen, pSep2);
- SetRegValue(rcVersion, W("ImplementedInThisVersion"), W(""));
- delete[] rcVersion;
-
- if(pSep1 != NULL)
- *pSep1 = W('\\');
- }
-
- // Add the threading model information.
- SetRegValue(rcInproc, W("ThreadingModel"), szThreadingModel);
- return (S_OK);
-}
-
-
-
-//*****************************************************************************
-// Does standard registration of a CoClass with a progid.
-// NOTE: This is the non-side-by-side execution version.
-//*****************************************************************************
-HRESULT REGUTIL::RegisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID.
- LPCTSTR szDesc, // Description of the class.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID, // Class progid.
- LPCTSTR szThreadingModel, // What threading model to use.
- LPCTSTR szModule, // Path to class.
- BOOL bInprocServer) // Whether we register the server as inproc or local
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- WCHAR rcCLSID[256]; // CLSID\\szID.
- WCHAR rcInproc[_MAX_PATH+64]; // CLSID\\InprocServer32
- WCHAR rcProgID[256]; // szProgIDPrefix.szClassProgID
- WCHAR rcIndProgID[256]; // rcProgID.iVersion
- HRESULT hr;
-
- // Format the prog ID values.
- VERIFY(_snwprintf_s(rcIndProgID, _countof(rcIndProgID), _TRUNCATE, W("%s.%s"), szProgIDPrefix, szClassProgID));
-
- VERIFY(_snwprintf_s(rcProgID, _countof(rcProgID), _TRUNCATE, W("%s.%d"), rcIndProgID, iVersion));
-
- // Do the initial portion.
- if (FAILED(hr = RegisterClassBase(rclsid, szDesc, rcProgID, rcIndProgID, rcCLSID, NumItems(rcCLSID))))
- return (hr);
-
- WCHAR *szServerType = bInprocServer ? W("InprocServer32") : W("LocalServer32");
-
- // Set the server path.
- SetKeyAndValue(rcCLSID, szServerType , szModule);
-
- // Add the threading model information.
- VERIFY(_snwprintf_s(rcInproc, _countof(rcInproc), _TRUNCATE, W("%s\\%s"), rcCLSID, szServerType));
-
- SetRegValue(rcInproc, W("ThreadingModel"), szThreadingModel);
- return (S_OK);
-}
-
-
-
-//*****************************************************************************
-// Register the basics for a in proc server.
-//*****************************************************************************
-HRESULT REGUTIL::RegisterClassBase( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szDesc, // Class description.
- LPCTSTR szProgID, // Class prog ID.
- LPCTSTR szIndepProgID, // Class version independant prog ID.
- __out_ecount(cchOutCLSID) LPTSTR szOutCLSID, // CLSID formatted in character form.
- DWORD cchOutCLSID) // Out CLS ID buffer size
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- TCHAR szID[64]; // The class ID to register.
-
- // Create some base key strings.
- GuidToLPWSTR(rclsid, szID, NumItems(szID));
-
- size_t nLen = _tcslen(_T("CLSID\\")) + _tcslen( szID) + 1;
- if( cchOutCLSID < nLen )
- return E_INVALIDARG;
-
- _tcscpy_s(szOutCLSID, cchOutCLSID, W("CLSID\\"));
- _tcscat_s(szOutCLSID, cchOutCLSID, szID);
-
- // Create ProgID keys.
- SetKeyAndValue(szProgID, NULL, szDesc);
- SetKeyAndValue(szProgID, W("CLSID"), szID);
-
- // Create VersionIndependentProgID keys.
- SetKeyAndValue(szIndepProgID, NULL, szDesc);
- SetKeyAndValue(szIndepProgID, W("CurVer"), szProgID);
- SetKeyAndValue(szIndepProgID, W("CLSID"), szID);
-
- // Create entries under CLSID.
- SetKeyAndValue(szOutCLSID, NULL, szDesc);
- SetKeyAndValue(szOutCLSID, W("ProgID"), szProgID);
- SetKeyAndValue(szOutCLSID, W("VersionIndependentProgID"), szIndepProgID);
- SetKeyAndValue(szOutCLSID, W("NotInsertable"), NULL);
- return (S_OK);
-}
-
-
-
-//*****************************************************************************
-// Unregister the basic information in the system registry for a given object
-// class.
-//*****************************************************************************
-HRESULT REGUTIL::UnregisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID, // Class progid.
- BOOL fExternal) // flag - External to mscoree.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- WCHAR rcCLSID[64]; // CLSID\\szID.
- WCHAR rcProgID[128]; // szProgIDPrefix.szClassProgID
- WCHAR rcIndProgID[128]; // rcProgID.iVersion
-
- // Format the prog ID values.
- VERIFY(_snwprintf_s(rcProgID, _countof(rcProgID), _TRUNCATE, W("%s.%s"), szProgIDPrefix, szClassProgID));
-
- VERIFY(_snwprintf_s(rcIndProgID, _countof(rcIndProgID), _TRUNCATE, W("%s.%d"), rcProgID, iVersion));
-
- UnregisterClassBase(rclsid, rcProgID, rcIndProgID, rcCLSID, NumItems(rcCLSID));
- DeleteKey(rcCLSID, W("InprocServer32"));
- if (fExternal){
- DeleteKey(rcCLSID, W("Server"));
- DeleteKey(rcCLSID, W("Version"));
- }
- GuidToLPWSTR(rclsid, rcCLSID, NumItems(rcCLSID));
- DeleteKey(W("CLSID"), rcCLSID);
- return (S_OK);
-}
-
-
-//*****************************************************************************
-// Unregister the basic information in the system registry for a given object
-// class.
-// NOTE: This is the non-side-by-side execution version.
-//*****************************************************************************
-HRESULT REGUTIL::UnregisterCOMClass( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szProgIDPrefix, // Prefix for progid.
- int iVersion, // Version # for progid.
- LPCTSTR szClassProgID) // Class progid.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- WCHAR rcCLSID[64]; // CLSID\\szID.
- WCHAR rcProgID[128]; // szProgIDPrefix.szClassProgID
- WCHAR rcIndProgID[128]; // rcProgID.iVersion
-
- // Format the prog ID values.
- VERIFY(_snwprintf_s(rcProgID, _countof(rcProgID), _TRUNCATE, W("%s.%s"), szProgIDPrefix, szClassProgID));
-
- VERIFY(_snwprintf_s(rcIndProgID, _countof(rcIndProgID), _TRUNCATE, W("%s.%d"), rcProgID, iVersion));
-
- UnregisterClassBase(rclsid, rcProgID, rcIndProgID, rcCLSID, NumItems(rcCLSID));
- DeleteKey(rcCLSID, W("InprocServer32"));
- DeleteKey(rcCLSID, W("LocalServer32"));
-
- GuidToLPWSTR(rclsid, rcCLSID, NumItems(rcCLSID));
- DeleteKey(W("CLSID"), rcCLSID);
- return (S_OK);
-}
-
-
-//*****************************************************************************
-// Delete the basic settings for an inproc server.
-//*****************************************************************************
-HRESULT REGUTIL::UnregisterClassBase( // Return code.
- REFCLSID rclsid, // Class ID we are registering.
- LPCTSTR szProgID, // Class prog ID.
- LPCTSTR szIndepProgID, // Class version independant prog ID.
- __out_ecount(cchOutCLSID) LPTSTR szOutCLSID, // Return formatted class ID here.
- DWORD cchOutCLSID) // Out CLS ID buffer size
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- TCHAR szID[64]; // The class ID to register.
-
- // Create some base key strings.
- GuidToLPWSTR(rclsid, szID, NumItems(szID));
- size_t nLen = _tcslen(_T("CLSID\\")) + _tcslen( szID) + 1;
- if( cchOutCLSID < nLen )
- return E_INVALIDARG;
-
- _tcscpy_s(szOutCLSID, cchOutCLSID, W("CLSID\\"));
- _tcscat_s(szOutCLSID, cchOutCLSID, szID);
-
- // Delete the version independant prog ID settings.
- DeleteKey(szIndepProgID, W("CurVer"));
- DeleteKey(szIndepProgID, W("CLSID"));
- WszRegDeleteKey(HKEY_CLASSES_ROOT, szIndepProgID);
-
- // Delete the prog ID settings.
- DeleteKey(szProgID, W("CLSID"));
- WszRegDeleteKey(HKEY_CLASSES_ROOT, szProgID);
-
- // Delete the class ID settings.
- DeleteKey(szOutCLSID, W("ProgID"));
- DeleteKey(szOutCLSID, W("VersionIndependentProgID"));
- DeleteKey(szOutCLSID, W("NotInsertable"));
- WszRegDeleteKey(HKEY_CLASSES_ROOT, szOutCLSID);
- return (S_OK);
-}
-
-
-//*****************************************************************************
-// Register a type library.
-//*****************************************************************************
-HRESULT REGUTIL::RegisterTypeLib( // Return code.
- REFGUID rtlbid, // TypeLib ID we are registering.
- int iVersion, // Typelib version.
- LPCTSTR szDesc, // TypeLib description.
- LPCTSTR szModule) // Path to the typelib.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- WCHAR szID[64]; // The typelib ID to register.
- WCHAR szTLBID[256]; // TypeLib\\szID.
- WCHAR szHelpDir[_MAX_PATH];
- WCHAR szDrive[_MAX_DRIVE] = {0};
- WCHAR szDir[_MAX_DIR] = {0};
- WCHAR szVersion[64];
- LPWSTR szTmp;
-
- // Create some base key strings.
- GuidToLPWSTR(rtlbid, szID, NumItems(szID));
-
- _tcscpy_s(szTLBID, _countof(szTLBID), W("TypeLib\\"));
- _tcscat_s(szTLBID, _countof(szTLBID), szID);
-
- VERIFY(_snwprintf_s(szVersion, _countof(szVersion), _TRUNCATE, W("%d.0"), iVersion));
-
- // Create Typelib keys.
- SetKeyAndValue(szTLBID, NULL, NULL);
- SetKeyAndValue(szTLBID, szVersion, szDesc);
- _tcscat_s(szTLBID, _countof(szTLBID), W("\\"));
- _tcscat_s(szTLBID, _countof(szTLBID), szVersion);
- SetKeyAndValue(szTLBID, W("0"), NULL);
- SetKeyAndValue(szTLBID, W("0\\win32"), szModule);
- SetKeyAndValue(szTLBID, W("FLAGS"), W("0"));
- SplitPath(szModule, szDrive, _MAX_DRIVE, szDir, _MAX_DIR, NULL, 0, NULL, 0);
- _tcscpy_s(szHelpDir, _countof(szHelpDir), szDrive);
- if ((szTmp = CharPrev(szDir, szDir + Wszlstrlen(szDir))) != NULL)
- *szTmp = '\0';
- _tcscat_s(szHelpDir, _countof(szHelpDir), szDir);
- SetKeyAndValue(szTLBID, W("HELPDIR"), szHelpDir);
- return (S_OK);
-}
-
-
-//*****************************************************************************
-// Remove the registry keys for a type library.
-//*****************************************************************************
-HRESULT REGUTIL::UnregisterTypeLib( // Return code.
- REFGUID rtlbid, // TypeLib ID we are registering.
- int iVersion) // Typelib version.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- WCHAR szID[64]; // The typelib ID to register.
- WCHAR szTLBID[256]; // TypeLib\\szID.
- WCHAR szTLBVersion[256]; // TypeLib\\szID\\szVersion
- WCHAR szVersion[64];
-
- // Create some base key strings.
- GuidToLPWSTR(rtlbid, szID, NumItems(szID));
-
- VERIFY(_snwprintf_s(szVersion, _countof(szVersion), _TRUNCATE, W("%d.0"), iVersion));
-
- _tcscpy_s(szTLBID, _countof(szTLBID), W("TypeLib\\"));
- _tcscat_s(szTLBID, _countof(szTLBID), szID);
- _tcscpy_s(szTLBVersion, _countof(szTLBVersion), szTLBID);
- _tcscat_s(szTLBVersion, _countof(szTLBVersion), W("\\"));
- _tcscat_s(szTLBVersion, _countof(szTLBVersion), szVersion);
-
- // Delete Typelib keys.
- DeleteKey(szTLBVersion, W("HELPDIR"));
- DeleteKey(szTLBVersion, W("FLAGS"));
- DeleteKey(szTLBVersion, W("0\\win32"));
- DeleteKey(szTLBVersion, W("0"));
- DeleteKey(szTLBID, szVersion);
- WszRegDeleteKey(HKEY_CLASSES_ROOT, szTLBID);
- return (0);
-}
-
-#endif // !FEATURE_CORECLR
//
diff --git a/src/utilcode/safewrap.cpp b/src/utilcode/safewrap.cpp
index 4a6ecdb93c..294743d519 100644
--- a/src/utilcode/safewrap.cpp
+++ b/src/utilcode/safewrap.cpp
@@ -40,12 +40,9 @@ void ClrGetCurrentDirectory(SString & value)
// An actual API failure in GetCurrentDirectory failure should be very rare, so we'll throw on those.
if (len == 0)
- {
- value.CloseBuffer(0);
+ {
ThrowLastError();
}
-
- value.CloseBuffer();
}
// Nothrowing wrapper.
diff --git a/src/utilcode/sortversioning.cpp b/src/utilcode/sortversioning.cpp
index 5420947842..65781cdc1a 100644
--- a/src/utilcode/sortversioning.cpp
+++ b/src/utilcode/sortversioning.cpp
@@ -136,230 +136,6 @@ namespace SortVersioning
return i;
}
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- ////////////////////////////////////////////////////////////////////////////
- //
- // LoadSortModuleAndInvariant()
- //
- // Attempts to load the given dll. If that is successful, attempts to
- // load the invariant data. If that is successful, returns the module handle
- // and the addresses of the SortGetHandle function and SortCloseHandle function
- //
- // failure is indicated by returning NULL for the module handle and the
- // function addresses
- //
- ////////////////////////////////////////////////////////////////////////////
-
- HMODULE LoadSortModuleAndInvariant(
- __in LPCWSTR sDllName,
- __in DWORD dwVersion,
- __out SORTGETHANDLE* ppGetHandle,
- __out SORTCLOSEHANDLE* ppCloseHandle
- )
- {
- *ppGetHandle = NULL;
- *ppCloseHandle = NULL;
- HMODULE hSort;
-
- if(FAILED(UtilCode::LoadLibraryShim(sDllName, NULL, NULL, &hSort)))
- {
- return NULL;
- }
-
- SORTGETHANDLE pGetHandle = (SORTGETHANDLE)GetProcAddress(hSort, "SortGetHandle");
- SORTCLOSEHANDLE pCloseHandle = (SORTCLOSEHANDLE)GetProcAddress(hSort, "SortCloseHandle");
-
- // If we didn't load the procs, then remember that
- if (pCloseHandle == NULL || pGetHandle == NULL)
- {
- ::FreeLibrary(hSort);
- return NULL;
- }
-
- // Verify that the data file's available
- NLSVERSIONINFO sortVersion;
- sortVersion.dwNLSVersionInfoSize = sizeof(NLSVERSIONINFO);
- sortVersion.dwNLSVersion = dwVersion;
- sortVersion.dwDefinedVersion = dwVersion;
-
- // Invariant must be there and is kinda common, so we'll just get it
- PSORTHANDLE pSort = pGetHandle(W(""), &sortVersion, NULL);
- if (!pSort)
- {
- // Yikes, invariant failed, forget about it.
- ::FreeLibrary(hSort);
- return NULL;
- }
-
- // Since we found it, may as well remember it.
- const SORTHANDLE * const pSortInHash = InsertSortHashNode(pSort);
-
- // If we got a different one back then free the one we added
- if (pSortInHash != pSort && pSortInHash)
- {
- // We got a different one from the hash (someone beat us to the cache)
- // so use that and discard the new one.
- pCloseHandle(pSort);
- }
-
- *ppGetHandle = pGetHandle;
- *ppCloseHandle = pCloseHandle;
- return hSort;
- }
-
- // Attempts to load a Sort DLL. If this fails, the values of the __out parameters are unchanged.
- __success(return)
- BOOL LoadSortDllAndPublish(
- __in LPCWSTR sDllName,
- __in DWORD dwVersion,
- __out __encoded_pointer SORTGETHANDLE* ppGetHandle,
- __out __encoded_pointer SORTCLOSEHANDLE* ppCloseHandle,
- __out HMODULE* phSortDll)
- {
- HMODULE hSortDll;
- SORTGETHANDLE pGetHandle;
- SORTCLOSEHANDLE pCloseHandle;
-
- hSortDll = LoadSortModuleAndInvariant(sDllName, dwVersion, &pGetHandle, &pCloseHandle);
-
- if(hSortDll != NULL) {
- *phSortDll = hSortDll;
- *ppGetHandle = (SORTGETHANDLE)EncodePointer(pGetHandle);
- *ppCloseHandle = (SORTCLOSEHANDLE)EncodePointer(pCloseHandle);
- return TRUE;
- }
-
- return FALSE;
- }
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // GetSortGetHandle()
- //
- // Get the SortGetHandle() function for the proper dll version.
- //
- ////////////////////////////////////////////////////////////////////////////
- SORTGETHANDLE GetSortGetHandle(__in DWORD dwVersion)
- {
- if(dwVersion == SORT_VERSION_DEFAULT)
- {
- // If we haven't tried to load the module/proc before do so now
- if (g_hSortDefault == (HMODULE)-1)
- {
- LoadSortDllAndPublish(SORT_DEFAULT_DLL_NAME, SORT_VERSION_DEFAULT, &g_pDefaultGetHandle, &g_pDefaultCloseHandle, &g_hSortDefault);
- }
-
- // This check is necessary because the LoadSortDllAndPublish call may have failed since some platforms
- // won't have nlssorting.dll (e.g. Windows 8 and above).
- if (g_hSortDefault != (HMODULE)-1)
- {
- return (SORTGETHANDLE)DecodePointer(g_pDefaultGetHandle);
- }
- }
-
- HMODULE* pHSortModule;
- SORTGETHANDLE* ppGetHandle;
- SORTCLOSEHANDLE* ppCloseHandle;
-
- if(dwVersion == SORT_VERSION_V4)
- {
- ppGetHandle = &g_pV4GetHandle;
- ppCloseHandle = &g_pV4CloseHandle;
- pHSortModule = &g_hSortCompatV4;
- }
- else if(dwVersion == SORT_VERSION_WHIDBEY)
- {
- ppGetHandle = &g_pV2GetHandle;
- ppCloseHandle = &g_pV2CloseHandle;
- pHSortModule = &g_hSortCompatV2;
- }
- else
- {
- // Unsupported sorting version.
- return NULL;
- }
-
- if(*pHSortModule == (HMODULE) -1)
- {
- // get module name - the module name should be "Sort"+dwVersion.ToString("x8")+".dll"
- WCHAR moduleName[] = W("Sort00000000.dll");
- // replace the "00000000" with the hexadecimal of dwVersion
- LPCWSTR hex = W("0123456789abcdef");
- WCHAR* p = &moduleName[4+8]; // position at end of number part of dll name
-
- unsigned int value = dwVersion;
-
- while (value != 0 && p != moduleName) {
- int digit = value & 0xF;
- *--p = hex[digit];
- value >>= 4;
- }
-
- if(!LoadSortDllAndPublish(&moduleName[0], dwVersion, ppGetHandle, ppCloseHandle, pHSortModule))
- {
- // We failed to load a versioned sort dll, try to fall back to the current version.
- // If we haven't tried to load the module/proc before do so now
- if (g_hSortDefault == (HMODULE)-1)
- {
- LoadSortDllAndPublish(SORT_DEFAULT_DLL_NAME, SORT_VERSION_DEFAULT, &g_pDefaultGetHandle, &g_pDefaultCloseHandle, &g_hSortDefault);
- }
-
- *pHSortModule = g_hSortDefault;
- *ppCloseHandle = g_pDefaultCloseHandle;
- *ppGetHandle = g_pDefaultGetHandle;
- }
- }
-
- // At this point, we've either loaded a sorting dll or we've exausted all options.
- if(*pHSortModule == (HMODULE) -1)
- {
- // Couldn't find anything, give up.
- return NULL;
- }
- else
- {
- return (SORTGETHANDLE)DecodePointer(*ppGetHandle);
- }
-
- // Unknown version requested
- return NULL;
- }
-
- void DoSortCloseHandle(__in DWORD dwVersion, __in PSORTHANDLE pSort)
- {
- if (dwVersion == SORT_VERSION_DEFAULT)
- {
- SORTCLOSEHANDLE pDefaultCloseHandle = (SORTCLOSEHANDLE)DecodePointer(g_pDefaultCloseHandle);
- if(pDefaultCloseHandle != NULL)
- {
- (pDefaultCloseHandle)(pSort);
- return;
- }
- }
-
- if (dwVersion == SORT_VERSION_V4)
- {
- SORTCLOSEHANDLE pV4CloseHandle = (SORTCLOSEHANDLE)DecodePointer(g_pV4CloseHandle);
- if(pV4CloseHandle != NULL)
- {
- (pV4CloseHandle)(pSort);
- return;
- }
- }
-
-
- if (dwVersion == SORT_VERSION_WHIDBEY)
- {
- SORTCLOSEHANDLE pV2CloseHandle = (SORTCLOSEHANDLE)DecodePointer(g_pV2CloseHandle);
- if(pV2CloseHandle != NULL)
- {
- (pV2CloseHandle)(pSort);
- return;
- }
- }
- }
-
-#else // !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
SORTGETHANDLE GetSortGetHandle(__in DWORD dwVersion)
{
@@ -370,7 +146,6 @@ namespace SortVersioning
{
}
-#endif // !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
////////////////////////////////////////////////////////////////////////////
//
@@ -663,26 +438,7 @@ namespace SortVersioning
////////////////////////////////////////////////////////////////////////////
DWORD SortNLSVersion()
{
-#ifdef FEATURE_CORECLR
return SORT_VERSION_DEFAULT;
-#else
- static bool sortNLSVersionConfigChecked = false;
- static DWORD sortNLSVersion = SORT_VERSION_DEFAULT;
-
- if(!sortNLSVersionConfigChecked)
- {
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return false);
- sortNLSVersion = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CompatSortNLSVersion);
- if(sortNLSVersion == 0)
- {
- sortNLSVersion = SORT_VERSION_DEFAULT;
- }
- END_SO_INTOLERANT_CODE;
-
- sortNLSVersionConfigChecked = true;
- }
- return sortNLSVersion;
-#endif // !FEATURE_CORECLR
}
////////////////////////////////////////////////////////////////////////////
diff --git a/src/utilcode/stacktrace.cpp b/src/utilcode/stacktrace.cpp
index 858fac723e..3dee1802f4 100644
--- a/src/utilcode/stacktrace.cpp
+++ b/src/utilcode/stacktrace.cpp
@@ -949,7 +949,7 @@ void MagicDeinit(void)
}
}
-#if defined(_TARGET_X86_) && defined(FEATURE_CORECLR)
+#if defined(_TARGET_X86_)
/****************************************************************************
* ClrCaptureContext *
*-------------------*
@@ -989,4 +989,4 @@ ClrCaptureContext(__out PCONTEXT ctx)
ret 4
}
}
-#endif // _TARGET_X86_ && FEATURE_CORECLR
+#endif // _TARGET_X86
diff --git a/src/utilcode/stresslog.cpp b/src/utilcode/stresslog.cpp
index d364b06dd6..91c5c0e8ef 100644
--- a/src/utilcode/stresslog.cpp
+++ b/src/utilcode/stresslog.cpp
@@ -608,12 +608,7 @@ FORCEINLINE BOOL StressLog::InlinedETWLogOn(unsigned facility, unsigned level)
STATIC_CONTRACT_LEAF;
STATIC_CONTRACT_SUPPORTS_DAC;
-#if defined(FEATURE_EVENT_TRACE) && !defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE)
- return ((Microsoft_Windows_DotNETRuntimeStressHandle != 0) &&
- (ETW_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_STRESS_PROVIDER_Context, (UCHAR)level, facility) != 0));
-#else
return FALSE;
-#endif
}
BOOL StressLog::ETWLogOn(unsigned facility, unsigned level)
@@ -671,28 +666,6 @@ void StressLog::LogMsg (unsigned level, unsigned facility, int cArgs, const char
}
// Stress Log ETW feature available only on the desktop versions of the runtime
-#if !defined(FEATURE_CORECLR)
- // The previous LogMsg call could have modified the Args, so we need to reset it
- if(InlinedETWLogOn(facility, level))
- {
-#define MAX_STRESSLOG_DATA_ETW_LENGTH 256
- CHAR logMessage[MAX_STRESSLOG_DATA_ETW_LENGTH];
-
- va_start(Args, format);
- ULONG messageLength = (USHORT)_vsnprintf_s(logMessage, COUNTOF(logMessage), MAX_STRESSLOG_DATA_ETW_LENGTH-1, format, Args);
- va_end(Args);
-
- if(messageLength >= 0 &&
- messageLength < MAX_STRESSLOG_DATA_ETW_LENGTH) // this condition has been added to make prefast happy
- {
- logMessage[messageLength] = 0;
- }
- messageLength++;
- logMessage[MAX_STRESSLOG_DATA_ETW_LENGTH-1] = 0;
- FireEtwStressLogEvent_V1((UINT32)facility, (UCHAR)level, logMessage, GetClrInstanceId());
-#undef MAX_STRESSLOG_DATA_ETW_LENGTH
- }
-#endif // !FEATURE_CORECLR
#endif //!DACCESS_COMPILE
}
diff --git a/src/utilcode/tlbutils.cpp b/src/utilcode/tlbutils.cpp
deleted file mode 100644
index ed42c28fc8..0000000000
--- a/src/utilcode/tlbutils.cpp
+++ /dev/null
@@ -1,221 +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.
-
-//
-// Utilities used to help manipulating typelibs.
-
-#include "stdafx.h" // Precompiled header key.
-
-#include "tlbutils.h"
-#include "dispex.h"
-#include "posterror.h"
-#include "ndpversion.h"
-
-#define CUSTOM_MARSHALER_ASM ", CustomMarshalers, Version=" VER_ASSEMBLYVERSION_STR ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
-
-static const LPCWSTR DLL_EXTENSION = {W(".dll")};
-static const int DLL_EXTENSION_LEN = 4;
-static const LPCWSTR EXE_EXTENSION = {W(".exe")};
-static const int EXE_EXTENSION_LEN = 4;
-
-const StdConvertibleItfInfo aStdConvertibleInterfaces[] =
-{
- { "System.Runtime.InteropServices.Expando.IExpando", (GUID*)&IID_IDispatchEx,
- "System.Runtime.InteropServices.CustomMarshalers.ExpandoToDispatchExMarshaler" CUSTOM_MARSHALER_ASM, "IExpando" },
-
- { "System.Reflection.IReflect", (GUID*)&IID_IDispatchEx,
- "System.Runtime.InteropServices.CustomMarshalers.ExpandoToDispatchExMarshaler" CUSTOM_MARSHALER_ASM, "IReflect" },
-
- { "System.Collections.IEnumerator", (GUID*)&IID_IEnumVARIANT,
- "System.Runtime.InteropServices.CustomMarshalers.EnumeratorToEnumVariantMarshaler" CUSTOM_MARSHALER_ASM, "" },
-
- { "System.Type", (GUID*)&IID_ITypeInfo,
- "System.Runtime.InteropServices.CustomMarshalers.TypeToTypeInfoMarshaler" CUSTOM_MARSHALER_ASM, "" },
-};
-
-// This method returns the custom marshaler info to convert the native interface
-// to its managed equivalent. Or null if the interface is not a standard convertible interface.
-const StdConvertibleItfInfo *GetConvertionInfoFromNativeIID(REFGUID rGuidNativeItf)
-{
- CONTRACT (const StdConvertibleItfInfo*)
- {
- NOTHROW;
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END;
-
- // Look in the table of interfaces that have standard convertions to see if the
- // specified interface is there.
- for (int i = 0; i < sizeof(aStdConvertibleInterfaces) / sizeof(StdConvertibleItfInfo); i++)
- {
- if (IsEqualGUID(rGuidNativeItf, *(aStdConvertibleInterfaces[i].m_pNativeTypeIID)))
- RETURN &aStdConvertibleInterfaces[i];
- }
-
- // The interface is not in the table.
- RETURN NULL;
-}
-
-//*****************************************************************************
-// Given a typelib, determine the managed namespace name.
-//*****************************************************************************
-HRESULT GetNamespaceNameForTypeLib( // S_OK or error.
- ITypeLib *pITLB, // [IN] The TypeLib.
- BSTR *pwzNamespace) // [OUT] Put the namespace name here.
-{
- CONTRACTL
- {
- DISABLED(NOTHROW); // PostError goes down a throwing path right now. Revisit this when fixed.
- PRECONDITION(CheckPointer(pITLB));
- PRECONDITION(CheckPointer(pwzNamespace));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- ITypeLib2 *pITLB2=0; //For getting custom value.
- TLIBATTR *pAttr=0; // Typelib attributes.
- BSTR szPath=0; // Typelib path.
-
- // If custom attribute for namespace exists, use it.
- if (pITLB->QueryInterface(IID_ITypeLib2, (void **)&pITLB2) == S_OK)
- {
- VARIANT vt;
- VariantInit(&vt);
- if (pITLB2->GetCustData(GUID_ManagedName, &vt) == S_OK)
- {
- if (V_VT(&vt) == VT_BSTR)
- {
- // If the namespace ends with .dll then remove the extension.
- LPWSTR pDest = wcsstr(vt.bstrVal, DLL_EXTENSION);
- if (pDest && (pDest[DLL_EXTENSION_LEN] == 0 || pDest[DLL_EXTENSION_LEN] == ' '))
- *pDest = 0;
-
- if (!pDest)
- {
- // If the namespace ends with .exe then remove the extension.
- pDest = wcsstr(vt.bstrVal, EXE_EXTENSION);
- if (pDest && (pDest[EXE_EXTENSION_LEN] == 0 || pDest[EXE_EXTENSION_LEN] == ' '))
- *pDest = 0;
- }
-
- if (pDest)
- {
- // We removed the extension so re-allocate a string of the new length.
- *pwzNamespace = SysAllocString(vt.bstrVal);
- SysFreeString(vt.bstrVal);
- }
- else
- {
- // There was no extension to remove so we can use the string returned
- // by GetCustData().
- *pwzNamespace = vt.bstrVal;
- }
-
- goto ErrExit;
- }
- else
- {
- VariantClear(&vt);
- }
- }
- }
-
- // No custom attribute, use library name.
- IfFailGo(pITLB->GetDocumentation(MEMBERID_NIL, pwzNamespace, 0, 0, 0));
-
-ErrExit:
- if (szPath)
- ::SysFreeString(szPath);
- if (pAttr)
- pITLB->ReleaseTLibAttr(pAttr);
- if (pITLB2)
- pITLB2->Release();
-
- return hr;
-} // HRESULT GetNamespaceNameForTypeLib()
-
-//*****************************************************************************
-// Given an ITypeInfo, determine the managed name. Optionally supply a default
-// namespace, otherwise derive namespace from containing typelib.
-//*****************************************************************************
-HRESULT GetManagedNameForTypeInfo( // S_OK or error.
- ITypeInfo *pITI, // [IN] The TypeInfo.
- LPCWSTR wzNamespace, // [IN, OPTIONAL] Default namespace name.
- LPCWSTR wzAsmName, // [IN, OPTIONAL] Assembly name.
- BSTR *pwzName) // [OUT] Put the name here.
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- PRECONDITION(CheckPointer(pITI));
- PRECONDITION(CheckPointer(wzNamespace, NULL_OK));
- PRECONDITION(CheckPointer(wzAsmName, NULL_OK));
- PRECONDITION(CheckPointer(pwzName));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- ITypeInfo2 *pITI2=0; // For getting custom value.
- ITypeLib *pITLB=0; // Containing typelib.
-
- BSTR bstrName=0; // Typeinfo's name.
- BSTR bstrNamespace=0; // Typelib's namespace.
- int cchFullyQualifiedName; // Size of namespace + name buffer.
- int cchAsmName=0; // The size of the assembly name.
- int cchAsmQualifiedName=0; // The size of the assembly qualified name buffer.
- CQuickArray<WCHAR> qbFullyQualifiedName; // The fully qualified type name.
-
- // Check for a custom value with name.
- if (pITI->QueryInterface(IID_ITypeInfo2, (void **)&pITI2) == S_OK)
- {
- VARIANT vt; // For getting custom value.
- ::VariantInit(&vt);
- if (pITI2->GetCustData(GUID_ManagedName, &vt) == S_OK && vt.vt == VT_BSTR)
- { // There is a custom value with the name. Just believe it.
- *pwzName = vt.bstrVal;
- vt.bstrVal = 0;
- vt.vt = VT_EMPTY;
- goto ErrExit;
- }
- }
-
- // Still need name, get the namespace.
- if (wzNamespace == 0)
- {
- IfFailGo(pITI->GetContainingTypeLib(&pITLB, 0));
- IfFailGo(GetNamespaceNameForTypeLib(pITLB, &bstrNamespace));
- wzNamespace = bstrNamespace;
- }
-
- // Get the name, and combine with namespace.
- IfFailGo(pITI->GetDocumentation(MEMBERID_NIL, &bstrName, 0,0,0));
- cchFullyQualifiedName = (int)(wcslen(bstrName) + wcslen(wzNamespace) + 1);
- IfFailGo(qbFullyQualifiedName.ReSizeNoThrow(cchFullyQualifiedName + 1));
- ns::MakePath(qbFullyQualifiedName.Ptr(), cchFullyQualifiedName + 1, wzNamespace, bstrName);
-
- // If the assembly name is specified, then add it to the type name.
- if (wzAsmName)
- {
- cchAsmName = (int)wcslen(wzAsmName);
- cchAsmQualifiedName = cchFullyQualifiedName + cchAsmName + 3;
- IfNullGo(*pwzName = ::SysAllocStringLen(0, cchAsmQualifiedName));
- ns::MakeAssemblyQualifiedName(*pwzName, cchAsmQualifiedName, qbFullyQualifiedName.Ptr(), cchFullyQualifiedName, wzAsmName, cchAsmName);
- }
- else
- {
- IfNullGo(*pwzName = ::SysAllocStringLen(qbFullyQualifiedName.Ptr(), cchFullyQualifiedName));
- }
-
-ErrExit:
- if (bstrName)
- ::SysFreeString(bstrName);
- if (bstrNamespace)
- ::SysFreeString(bstrNamespace);
- if (pITLB)
- pITLB->Release();
- if (pITI2)
- pITI2->Release();
-
- return (hr);
-} // HRESULT GetManagedNameForTypeInfo()
diff --git a/src/utilcode/util.cpp b/src/utilcode/util.cpp
index 33722e5297..c215a49213 100644
--- a/src/utilcode/util.cpp
+++ b/src/utilcode/util.cpp
@@ -19,9 +19,6 @@
#include "cor.h"
#include "corinfo.h"
-#ifndef FEATURE_CORECLR
-#include "metahost.h"
-#endif // !FEATURE_CORECLR
const char g_RTMVersion[]= "v1.0.3705";
@@ -882,6 +879,27 @@ BYTE * ClrVirtualAllocWithinRange(const BYTE *pMinAddr,
#endif
}
+#if !defined(FEATURE_REDHAWK) && defined(_TARGET_AMD64_) && !defined(FEATURE_PAL)
+// Calculate greatest common divisor
+DWORD GCD(DWORD u, DWORD v)
+{
+ while (v != 0)
+ {
+ DWORD dwTemp = v;
+ v = u % v;
+ u = dwTemp;
+ }
+
+ return u;
+}
+
+// Calculate least common multiple
+DWORD LCM(DWORD u, DWORD v)
+{
+ return u / GCD(u, v) * v;
+}
+#endif
+
/*static*/ BOOL CPUGroupInfo::InitCPUGroupInfoArray()
{
CONTRACTL
@@ -943,11 +961,13 @@ BYTE * ClrVirtualAllocWithinRange(const BYTE *pMinAddr,
m_CPUGroupInfoArray[i].nr_active = (WORD)pRecord->Group.GroupInfo[i].ActiveProcessorCount;
m_CPUGroupInfoArray[i].active_mask = pRecord->Group.GroupInfo[i].ActiveProcessorMask;
m_nProcessors += m_CPUGroupInfoArray[i].nr_active;
- dwWeight *= (DWORD)m_CPUGroupInfoArray[i].nr_active;
+ dwWeight = LCM(dwWeight, (DWORD)m_CPUGroupInfoArray[i].nr_active);
}
- //NOTE: the weight setting should work fine with 4 CPU groups upto 64 LPs each. the minimum number of threads
- // per group before the weight overflow is 2^32/(2^6x2^6x2^6) = 2^14 (i.e. 16K threads)
+ // The number of threads per group that can be supported will depend on the number of CPU groups
+ // and the number of LPs within each processor group. For example, when the number of LPs in
+ // CPU groups is the same and is 64, the number of threads per group before weight overflow
+ // would be 2^32/2^6 = 2^26 (64M threads)
for (DWORD i = 0; i < m_nGroups; i++)
{
m_CPUGroupInfoArray[i].groupWeight = dwWeight / (DWORD)m_CPUGroupInfoArray[i].nr_active;
@@ -3322,114 +3342,6 @@ BOOL FileExists(LPCWSTR filename)
return TRUE;
}
-#ifndef FEATURE_CORECLR
-// Current users for FileLock are ngen and ngen service
-
-FileLockHolder::FileLockHolder()
-{
- _hLock = INVALID_HANDLE_VALUE;
-}
-
-FileLockHolder::~FileLockHolder()
-{
- Release();
-}
-
-// the amount of time we want to wait
-#define FILE_LOCK_RETRY_TIME 100
-
-void FileLockHolder::Acquire(LPCWSTR lockName, HANDLE hInterrupt, BOOL* pInterrupted)
-{
- WRAPPER_NO_CONTRACT;
-
- DWORD dwErr = 0;
- DWORD dwAccessDeniedRetry = 0;
- const DWORD MAX_ACCESS_DENIED_RETRIES = 10;
-
- if (pInterrupted)
- {
- *pInterrupted = FALSE;
- }
-
- _ASSERTE(_hLock == INVALID_HANDLE_VALUE);
-
- for (;;) {
- _hLock = WszCreateFile(lockName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
- if (_hLock != INVALID_HANDLE_VALUE) {
- return;
- }
-
- dwErr = GetLastError();
- // Logically we should only expect ERROR_SHARING_VIOLATION, but Windows can also return
- // ERROR_ACCESS_DENIED for underlying NtStatus DELETE_PENDING. That happens when another process
- // (gacutil.exe or indexer) have the file opened. Unfortunately there is no public API that would
- // allow us to detect this NtStatus and distinguish it from 'real' access denied (candidates are
- // RtlGetLastNtStatus that is not documented on MSDN and NtCreateFile that is internal and can change
- // at any time), so we retry on access denied, but only for a limited number of times.
- if (dwErr == ERROR_SHARING_VIOLATION ||
- (dwErr == ERROR_ACCESS_DENIED && ++dwAccessDeniedRetry <= MAX_ACCESS_DENIED_RETRIES))
- {
- // Somebody is holding the lock. Let's sleep, and come back again.
- if (hInterrupt)
- {
- _ASSERTE(pInterrupted &&
- "If you can be interrupted, you better want to know if you actually were interrupted");
- if (WaitForSingleObject(hInterrupt, FILE_LOCK_RETRY_TIME) == WAIT_OBJECT_0)
- {
- if (pInterrupted)
- {
- *pInterrupted = TRUE;
- }
-
- // We've been interrupted, so return without acquiring
- return;
- }
- }
- else
- {
- ClrSleepEx(FILE_LOCK_RETRY_TIME, FALSE);
- }
- }
- else {
- ThrowHR(HRESULT_FROM_WIN32(dwErr));
- }
- }
-}
-
-
-HRESULT FileLockHolder::AcquireNoThrow(LPCWSTR lockName, HANDLE hInterrupt, BOOL* pInterrupted)
-{
- HRESULT hr = S_OK;
-
- EX_TRY
- {
- Acquire(lockName, hInterrupt, pInterrupted);
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
-BOOL FileLockHolder::IsTaken(LPCWSTR lockName)
-{
-
- // We don't want to do an acquire the lock to know if its taken, so we want to see if the file
- // exists. However, in situations like unplugging a machine, a DELETE_ON_CLOSE still leaves the file
- // around. We try to delete it here. If the lock is acquired, DeleteFile will fail, as the file is
- // not opened with SHARE_DELETE.
- WszDeleteFile(lockName);
-
- return FileExists(lockName);
-}
-
-void FileLockHolder::Release()
-{
- if (_hLock != INVALID_HANDLE_VALUE) {
- CloseHandle(_hLock);
- _hLock = INVALID_HANDLE_VALUE;
- }
-}
-#endif // FEATURE_CORECLR
//======================================================================
// This function returns true, if it can determine that the instruction pointer
@@ -3587,59 +3499,6 @@ RUNTIMEVERSIONINFO RUNTIMEVERSIONINFO::notDefined;
BOOL IsV2RuntimeLoaded(void)
{
-#ifndef FEATURE_CORECLR
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- CANNOT_TAKE_LOCK;
- }
- CONTRACTL_END;
-
- ReleaseHolder<ICLRMetaHost> pMetaHost(NULL);
- ReleaseHolder<IEnumUnknown> pEnum(NULL);
- ReleaseHolder<IUnknown> pUnk(NULL);
- ReleaseHolder<ICLRRuntimeInfo> pRuntime(NULL);
- HRESULT hr;
-
- HModuleHolder hModule = WszLoadLibrary(MSCOREE_SHIM_W);
- if (hModule == NULL)
- return FALSE;
-
- CLRCreateInstanceFnPtr pfnCLRCreateInstance = (CLRCreateInstanceFnPtr)::GetProcAddress(hModule, "CLRCreateInstance");
- if (pfnCLRCreateInstance == NULL)
- return FALSE;
-
- hr = (*pfnCLRCreateInstance)(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID *)&pMetaHost);
- if (FAILED(hr))
- return FALSE;
-
- hr = pMetaHost->EnumerateLoadedRuntimes(GetCurrentProcess(), &pEnum);
- if (FAILED(hr))
- return FALSE;
-
- while (pEnum->Next(1, &pUnk, NULL) == S_OK)
- {
- hr = pUnk->QueryInterface(IID_ICLRRuntimeInfo, (void **)&pRuntime);
- if (FAILED(hr))
- continue;
-
- WCHAR wszVersion[30];
- DWORD cchVersion = _countof(wszVersion);
- hr = pRuntime->GetVersionString(wszVersion, &cchVersion);
- if (FAILED(hr))
- continue;
-
- // Is it a V2 runtime?
- if ((cchVersion < 3) ||
- ((wszVersion[0] != W('v')) && (wszVersion[0] != W('V'))) ||
- (wszVersion[1] != W('2')) ||
- (wszVersion[2] != W('.')))
- continue;
-
- return TRUE;
- }
-#endif // FEATURE_CORECLR
return FALSE;
}
@@ -3650,11 +3509,6 @@ BOOL IsClrHostedLegacyComObject(REFCLSID rclsid)
// let's simply check for all CLSIDs that are known to be runtime implemented and capped to 2.0
return (
rclsid == CLSID_ComCallUnmarshal ||
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- rclsid == CLSID_CorRuntimeHost ||
- rclsid == CLSID_CLRRuntimeHost ||
- rclsid == CLSID_CLRProfiling ||
-#endif
rclsid == CLSID_CorMetaDataDispenser ||
rclsid == CLSID_CorMetaDataDispenserRuntime ||
rclsid == CLSID_TypeNameFactory);
@@ -3663,54 +3517,6 @@ BOOL IsClrHostedLegacyComObject(REFCLSID rclsid)
-#if !defined(FEATURE_CORECLR) && !defined(SELF_NO_HOST) && !defined(FEATURE_UTILCODE_NO_DEPENDENCIES)
-
-namespace UtilCode
-{
-
-#pragma warning(push)
-#pragma warning(disable:4996) // For use of deprecated LoadLibraryShim
-
- // When a NULL version is passed to LoadLibraryShim, this told the shim to bind the already-loaded
- // runtime or to the latest runtime. In hosted environments, we already know a runtime (or two) is
- // loaded, and since we are no longer guaranteed that a call to mscoree!LoadLibraryShim with a NULL
- // version will return the correct runtime, this code uses the ClrCallbacks infrastructure
- // available to get the ICLRRuntimeInfo for the runtime in which this code is hosted, and then
- // calls ICLRRuntimeInfo::LoadLibrary to make sure that the load occurs within the context of the
- // correct runtime.
- HRESULT LoadLibraryShim(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE *phModDll)
- {
- HRESULT hr = S_OK;
-
- if (szVersion != NULL)
- { // If a version is provided, then we just fall back to the legacy function to allow
- // it to construct the explicit path and load from that location.
- //@TODO: Can we verify that all callers of LoadLibraryShim in hosted environments always pass null and eliminate this code?
- return ::LoadLibraryShim(szDllName, szVersion, pvReserved, phModDll);
- }
-
- //
- // szVersion is NULL, which means we should load the DLL from the hosted environment's directory.
- //
-
- typedef ICLRRuntimeInfo *GetCLRRuntime_t();
- GetCLRRuntime_t *pfnGetCLRRuntime =
- reinterpret_cast<GetCLRRuntime_t *>((*GetClrCallbacks().m_pfnGetCLRFunction)("GetCLRRuntime"));
- if (pfnGetCLRRuntime == NULL)
- return E_UNEXPECTED;
-
- ICLRRuntimeInfo* pRI = (*pfnGetCLRRuntime)();
- if (pRI == NULL)
- return E_UNEXPECTED;
-
- return pRI->LoadLibrary(szDllName, phModDll);
- }
-
-#pragma warning(pop)
-
-}
-
-#endif //!FEATURE_CORECLR && !SELF_NO_HOST && !FEATURE_UTILCODE_NO_DEPENDENCIES
namespace Clr
{
diff --git a/src/utilcode/utilmessagebox.cpp b/src/utilcode/utilmessagebox.cpp
index 4559d16b7f..58fd7554c2 100644
--- a/src/utilcode/utilmessagebox.cpp
+++ b/src/utilcode/utilmessagebox.cpp
@@ -24,29 +24,6 @@
#include "commctrl.h"
#endif
-#if !defined(SELF_NO_HOST) && !defined(FEATURE_CORECLR)
-
-//
-// This should be used for runtime dialog box, because we assume the resource is from mscorrc.dll
-// For tools like ildasm or Shim which uses their own resource file, you need to define IDS_RTL in
-// their resource file and define a function like this and append the style returned from the function
-// to every calls to WszMessageBox.
-//
-UINT GetCLRMBRTLStyle()
-{
- WRAPPER_NO_CONTRACT;
-
- UINT mbStyle = 0;
- WCHAR buff[MAX_LONGPATH];
- if(SUCCEEDED(UtilLoadStringRC(IDS_RTL, buff, MAX_LONGPATH, true))) {
- if(wcscmp(buff, W("RTL_True")) == 0) {
- mbStyle = 0x00080000 |0x00100000; // MB_RIGHT || MB_RTLREADING
- }
- }
- return mbStyle;
-}
-
-#endif //!defined(SELF_NO_HOST) && !defined(FEATURE_CORECLR)
BOOL ShouldDisplayMsgBoxOnCriticalFailure()
{
@@ -72,16 +49,6 @@ BOOL ShouldDisplayMsgBoxOnCriticalFailure()
}
-#if !defined(FEATURE_CORESYSTEM) && !defined(FEATURE_CORECLR)
-enum ProbedTaskDialogIndirectState
-{
- ProbedTaskDialogIndirectState_NotProbed = 0,
- ProbedTaskDialogIndirectState_NotAvailable = 1,
- ProbedTaskDialogIndirectState_Available = 2
-};
-
-static ProbedTaskDialogIndirectState siProbedTaskDialogIndirect = ProbedTaskDialogIndirectState_NotProbed;
-#endif // !FEATURE_CORESYSTEM && !FEATURE_CORECLR
// We'd like to use TaskDialogIndirect for asserts coming from managed code in particular
@@ -109,157 +76,7 @@ int MessageBoxImpl(
}
CONTRACTL_END;
-#if defined(FEATURE_CORESYSTEM) || defined (FEATURE_CORECLR)
return WszMessageBox(hWnd, message, title, uType);
-#else
- bool mustUseMessageBox = false; // Mac, Silverlight, pre-Vista? Do we support this type of message box?
- decltype(TaskDialogIndirect)* pfnTaskDialogIndirect = NULL;
- ULONG_PTR cookie = NULL; // For activation context.
- bool activatedActivationContext = false;
- HModuleHolder hmodComctl32;
- HANDLE hActCtx = INVALID_HANDLE_VALUE;
-
- // Note: TaskDialogIndirect is only in the v6 and above versions of comctl32. Windows
- // stores that library in the WinSxS directory in a directory with
- // "Microsoft.Windows.Common-Controls" in the name. Your application can only see
- // this library if the linker has added a manifest dependency on the V6 common controls
- // to your application. Or, you can create an activation context to make this work,
- // if your library also has the appropriate manifest dependency.
- // Also, I'm not going to leave comctl32.dll mapped, to ensure it can't somehow
- // interfere with older versions. Therefore, re-load comctl32.dll every time through
- // this method. We will record whether TaskDialogIndirect is available though, so
- // we can fall back to MessageBox faster.
-
- // We don't yet have a perfect mapping from all MessageBox behavior to TaskDialogIndirect behavior.
- // Use MessageBox to avoid most of this complexity.
- if (((uType & MB_ICONMASK) != MB_ICONWARNING) && (uType & MB_ICONMASK) != MB_ICONERROR ||
- (uType & MB_TYPEMASK) != MB_ABORTRETRYIGNORE ||
- (uType & MB_DEFMASK) != 0 ||
- (uType & MB_MODEMASK) != 0 ||
- (uType & MB_MISCMASK) != 0)
- mustUseMessageBox = true;
- else if (mustUseMessageBox || siProbedTaskDialogIndirect == ProbedTaskDialogIndirectState_NotAvailable)
- mustUseMessageBox = true;
- else {
- // Replace our application's ActivationContext temporarily, load comctl32
- // & look for TaskDialogIndirect. Don't cache pointer.
- // The following code was suggested by some Windows experts. We do not want
- // to add a manifest to our library saying we use comctl32 v6, because that
- // will mean loading a lot of extra libraries on startup (a significant perf hit).
- // We could either store the manifest as a resource, or more creatively since
- // we are effectively a Windows component, rely on %windir%\WindowsShell.manifest.
- ACTCTX ctx = { sizeof(ACTCTX) };
- ctx.dwFlags = 0;
- StackSString manifestPath; // Point this at %windir%\WindowsShell.manifest, for comctl32 version 6.
- UINT numChars = WszGetWindowsDirectory(manifestPath.OpenUnicodeBuffer(MAX_PATH_FNAME), MAX_PATH_FNAME);
- if (numChars == 0 || numChars >= MAX_PATH_FNAME)
- {
- _ASSERTE(0); // How did this fail?
- }
- else {
- manifestPath.CloseBuffer(numChars);
- if (manifestPath[manifestPath.GetCount() - 1] != W('\\'))
- manifestPath.Append(W('\\'));
- manifestPath.Append(W("WindowsShell.manifest")); // Other Windows components have already loaded this.
- ctx.lpSource = manifestPath.GetUnicode();
- hActCtx = CreateActCtx(&ctx);
- if (hActCtx != INVALID_HANDLE_VALUE)
- {
- if (!ActivateActCtx(hActCtx, &cookie))
- {
- cookie = NULL;
- _ASSERTE(0); // Why did ActivateActCtx fail? (We'll continue executing & cope with the failure.)
- }
- else {
- activatedActivationContext = true;
- // Activation context was replaced - now we can load comctl32 version 6.
- hmodComctl32 = WszLoadLibrary(W("comctl32.dll"));
-
- if (hmodComctl32 != INVALID_HANDLE_VALUE) {
- pfnTaskDialogIndirect = (decltype(TaskDialogIndirect)*)GetProcAddress(hmodComctl32, "TaskDialogIndirect");
- if (pfnTaskDialogIndirect == NULL) {
- hmodComctl32.Release();
- }
- }
- }
- }
- }
-
- siProbedTaskDialogIndirect = (pfnTaskDialogIndirect == NULL) ? ProbedTaskDialogIndirectState_NotAvailable : ProbedTaskDialogIndirectState_Available;
- mustUseMessageBox = (pfnTaskDialogIndirect == NULL);
- }
-
- int result = MB_OK;
- if (mustUseMessageBox) {
- result = WszMessageBox(hWnd, message, title, uType);
- }
- else {
- _ASSERTE(pfnTaskDialogIndirect != NULL);
- int nButtonPressed = 0;
- TASKDIALOGCONFIG config = {0};
- config.cbSize = sizeof(config);
- config.hwndParent = hWnd;
- config.dwCommonButtons = 0;
- config.pszWindowTitle = title;
- config.dwFlags = (uType & MB_RTLREADING) ? TDF_RTL_LAYOUT : 0;
-
- // Set the user-visible icon in the window.
- _ASSERTE(((uType & MB_ICONMASK) == MB_ICONWARNING) || ((uType & MB_ICONMASK) == MB_ICONERROR));
- config.pszMainIcon = ((uType & MB_ICONMASK) == MB_ICONWARNING) ? TD_WARNING_ICON : TD_ERROR_ICON;
-
- config.pszMainInstruction = title;
- config.pszContent = message;
- config.pszExpandedInformation = detailedText;
-
- // Set up the buttons
- // Note about button hot keys: Windows keeps track of of where the last input came from
- // (ie, mouse or keyboard). If you use the mouse to interact w/ one dialog box and then use
- // the keyboard, the next dialog will not include hot keys. This is a Windows feature to
- // minimize clutter on the screen for mouse users.
- _ASSERTE((uType & MB_TYPEMASK) == MB_ABORTRETRYIGNORE);
- StackSString abortLabel, debugLabel, ignoreLabel;
- const WCHAR *pAbortLabel, *pDebugLabel, *pIgnoreLabel;
-
- if (abortLabel.LoadResource(CCompRC::Optional, IDS_DIALOG_BOX_ABORT_BUTTON))
- pAbortLabel = abortLabel.GetUnicode();
- else
- pAbortLabel = W("&Abort");
- if (debugLabel.LoadResource(CCompRC::Optional, IDS_DIALOG_BOX_DEBUG_BUTTON))
- pDebugLabel = debugLabel.GetUnicode();
- else
- pDebugLabel = W("&Debug");
- if (ignoreLabel.LoadResource(CCompRC::Optional, IDS_DIALOG_BOX_IGNORE_BUTTON))
- pIgnoreLabel = ignoreLabel.GetUnicode();
- else
- pIgnoreLabel = W("&Ignore");
-
- const TASKDIALOG_BUTTON abortDebugIgnoreButtons[] = {
- { IDOK, pAbortLabel },
- { IDRETRY, pDebugLabel },
- { IDIGNORE, pIgnoreLabel }
- };
- config.pButtons = abortDebugIgnoreButtons;
- config.cButtons = 3;
-
- HRESULT hr = pfnTaskDialogIndirect(&config, &nButtonPressed, NULL, NULL);
- _ASSERTE(hr == S_OK);
- if (hr == S_OK) {
- result = nButtonPressed;
- }
- else {
- result = IDOK;
- }
-
- _ASSERTE(result == IDOK || result == IDRETRY || result == IDIGNORE);
- }
-
- if (activatedActivationContext) {
- DeactivateActCtx(0, cookie);
- ReleaseActCtx(hActCtx); // perf isn't important so we won't bother caching the actctx
- }
-
- return result;
-#endif
}
int UtilMessageBoxVA(
@@ -428,9 +245,6 @@ int UtilMessageBoxNonLocalizedVA(
// in use. However, outside the CLR (SELF_NO_HOST) we can't assume we have resources and
// in CORECLR we can't even necessarily expect that our CLR callbacks have been initialized.
// This code path is used for ASSERT dialogs.
-#if !defined(SELF_NO_HOST) && !defined(FEATURE_CORECLR)
- uType |= GetCLRMBRTLStyle();
-#endif
result = MessageBoxImpl(hWnd, formattedMessage, formattedTitle, details, uType);
diff --git a/src/utilcode/utsem.cpp b/src/utilcode/utsem.cpp
index 087a3aefac..4a76bbdb31 100644
--- a/src/utilcode/utsem.cpp
+++ b/src/utilcode/utsem.cpp
@@ -22,10 +22,10 @@ Revision History:
#include "contract.h"
// Consider replacing this with a #ifdef INTEROP_DEBUGGING
-#if !defined(SELF_NO_HOST) && defined(_TARGET_X86_)
+#if !defined(SELF_NO_HOST) && defined(_TARGET_X86_) && !defined(FEATURE_PAL)
// For Interop debugging, the UTSemReadWrite class must inform the debugger
// that this thread can't be suspended currently. See vm\util.hpp for the
-// implementation of these methods.
+// implementation of these methods.
void IncCantStopCount();
void DecCantStopCount();
#else
diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt
index 79bd078c45..26fcacf4af 100644
--- a/src/vm/CMakeLists.txt
+++ b/src/vm/CMakeLists.txt
@@ -7,8 +7,6 @@ include_directories(${CLR_DIR}/src/gc)
include_directories(${ARCH_SOURCES_DIR})
-add_definitions(-DFEATURE_LEAVE_RUNTIME_HOLDER=1)
-
add_definitions(-DUNICODE)
add_definitions(-D_UNICODE)
@@ -99,6 +97,7 @@ set(VM_SOURCES_DAC_AND_WKS_COMMON
securitydescriptorassembly.cpp
sigformat.cpp
siginfo.cpp
+ spinlock.cpp
stackwalk.cpp
stublink.cpp
stubmgr.cpp
@@ -139,15 +138,16 @@ set(VM_SOURCES_WKS
assemblynative.cpp
assemblyspec.cpp
cachelinealloc.cpp
+ callcounter.cpp
callhelpers.cpp
ceemain.cpp
+ clrconfignative.cpp
clrex.cpp
clrprivbinderutil.cpp
clrvarargs.cpp
comdatetime.cpp
comdependenthandle.cpp
comdynamic.cpp
- comisolatedstorage.cpp
commemoryfailpoint.cpp
commodule.cpp
compatibilityswitch.cpp
@@ -164,6 +164,8 @@ set(VM_SOURCES_WKS
eemessagebox.cpp
eepolicy.cpp
eetoprofinterfaceimpl.cpp
+ eventpipe.cpp
+ eventpipejsonfile.cpp
eventstore.cpp
fcall.cpp
fieldmarshaler.cpp
@@ -211,6 +213,7 @@ set(VM_SOURCES_WKS
reflectioninvocation.cpp
runtimehandles.cpp
safehandle.cpp
+ sampleprofiler.cpp
security.cpp
securityattributes.cpp
securitydeclarative.cpp
@@ -222,7 +225,6 @@ set(VM_SOURCES_WKS
sha1.cpp
simplerwlock.cpp
sourceline.cpp
- spinlock.cpp
stackingallocator.cpp
stringliteralmap.cpp
stubcache.cpp
@@ -232,6 +234,7 @@ set(VM_SOURCES_WKS
synch.cpp
synchronizationcontextnative.cpp
testhookmgr.cpp
+ tieredcompilation.cpp
threaddebugblockinginfo.cpp
threadsuspend.cpp
typeparse.cpp
@@ -240,12 +243,6 @@ set(VM_SOURCES_WKS
${VM_SOURCES_GDBJIT}
)
-if(FEATURE_CER)
- list(APPEND VM_SOURCES_WKS
- constrainedexecutionregion.cpp
- )
-endif(FEATURE_CER)
-
if(FEATURE_EVENT_TRACE)
list(APPEND VM_SOURCES_WKS
eventtrace.cpp
@@ -375,6 +372,7 @@ else(WIN32)
)
elseif(CLR_CMAKE_TARGET_ARCH_I386)
set(VM_SOURCES_WKS_ARCH_ASM
+ ${ARCH_SOURCES_DIR}/ehhelpers.S
${ARCH_SOURCES_DIR}/asmhelpers.S
${ARCH_SOURCES_DIR}/jithelp.S
${ARCH_SOURCES_DIR}/gmsasm.S
diff --git a/src/vm/amd64/GenericComPlusCallStubs.asm b/src/vm/amd64/GenericComPlusCallStubs.asm
index 9240ad5fa7..f7d670e6ea 100644
--- a/src/vm/amd64/GenericComPlusCallStubs.asm
+++ b/src/vm/amd64/GenericComPlusCallStubs.asm
@@ -16,101 +16,12 @@ include asmconstants.inc
CTPMethodTable__s_pThunkTable equ ?s_pThunkTable@CTPMethodTable@@0PEAVMethodTable@@EA
InstantiatedMethodDesc__IMD_GetComPlusCallInfo equ ?IMD_GetComPlusCallInfo@InstantiatedMethodDesc@@QEAAPEAUComPlusCallInfo@@XZ
-ifdef FEATURE_REMOTING
-extern CRemotingServices__DispatchInterfaceCall:proc
-extern CTPMethodTable__s_pThunkTable:qword
-extern InstantiatedMethodDesc__IMD_GetComPlusCallInfo:proc
-endif
extern CLRToCOMWorker:proc
extern ProcessCLRException:proc
-ifdef FEATURE_REMOTING
-;
-; in:
-; r10: MethodDesc*
-; rcx: 'this' object
-;
-; out:
-; METHODDESC_REGISTER (r10) = MethodDesc* (for IL stubs)
-;
-LEAF_ENTRY GenericComPlusCallStub, _TEXT
-
- ;
- ; check for a null 'this' pointer and
- ; then see if this is a TransparentProxy
- ;
-
- test rcx, rcx
- jz do_com_call
-
- mov rax, [CTPMethodTable__s_pThunkTable]
- cmp [rcx], rax
- jne do_com_call
-
- ;
- ; 'this' is a TransparentProxy
- ;
- jmp CRemotingServices__DispatchInterfaceCall
-
-do_com_call:
-
- ;
- ; Check if the call is being made on an InstantiatedMethodDesc.
- ;
-
- mov ax, [r10 + OFFSETOF__MethodDesc__m_wFlags]
- and ax, MethodDescClassification__mdcClassification
- cmp ax, MethodDescClassification__mcInstantiated
- je GenericComPlusCallWorkerInstantiated
-
- ;
- ; Check if there is an IL stub.
- ;
-
- mov rax, [r10 + OFFSETOF__ComPlusCallMethodDesc__m_pComPlusCallInfo]
- mov rax, [rax + OFFSETOF__ComPlusCallInfo__m_pILStub]
- test rax, rax
- jz GenericComPlusCallStubSlow
-
- TAILJMP_RAX
-
-LEAF_END GenericComPlusCallStub, _TEXT
-
-; We could inline IMD_GetComPlusCallInfo here but it would be ugly.
-NESTED_ENTRY GenericComPlusCallWorkerInstantiated, _TEXT, ProcessCLRException
- alloc_stack 68h
-
- save_reg_postrsp r10, 60h
-
- SAVE_ARGUMENT_REGISTERS 70h
-
- SAVE_FLOAT_ARGUMENT_REGISTERS 20h
-
- END_PROLOGUE
-
- mov rcx, r10
- call InstantiatedMethodDesc__IMD_GetComPlusCallInfo
-
- RESTORE_FLOAT_ARGUMENT_REGISTERS 20h
-
- RESTORE_ARGUMENT_REGISTERS 70h
-
- mov r10, [rsp + 60h]
-
- mov rax, [rax + OFFSETOF__ComPlusCallInfo__m_pILStub]
-
- add rsp, 68h
- TAILJMP_RAX
-NESTED_END GenericComPlusCallWorkerInstantiated, _TEXT
-endif
-
-ifdef FEATURE_REMOTING
-NESTED_ENTRY GenericComPlusCallStubSlow, _TEXT, ProcessCLRException
-else
NESTED_ENTRY GenericComPlusCallStub, _TEXT, ProcessCLRException
-endif
PROLOG_WITH_TRANSITION_BLOCK 8
@@ -137,11 +48,7 @@ endif
EPILOG_WITH_TRANSITION_BLOCK_RETURN
-ifdef FEATURE_REMOTING
-NESTED_END GenericComPlusCallStubSlow, _TEXT
-else
NESTED_END GenericComPlusCallStub, _TEXT
-endif
endif ; FEATURE_COMINTEROP
diff --git a/src/vm/amd64/JitHelpers_Slow.asm b/src/vm/amd64/JitHelpers_Slow.asm
index 7deed49d98..293e447540 100644
--- a/src/vm/amd64/JitHelpers_Slow.asm
+++ b/src/vm/amd64/JitHelpers_Slow.asm
@@ -467,13 +467,9 @@ NESTED_END JIT_NewArr1OBJ_MP, _TEXT
-; <TODO> this m_GCLock should be a size_t so we don't have a store-forwarding penalty in the code below.
-; Unfortunately, the compiler intrinsic for InterlockedExchangePointer seems to be broken and we
-; get bad code gen in gc.cpp on IA64. </TODO>
-M_GCLOCK equ ?m_GCLock@@3HC
-extern M_GCLOCK:dword
-extern generation_table:qword
+extern g_global_alloc_lock:dword
+extern g_global_alloc_context:qword
LEAF_ENTRY JIT_TrialAllocSFastSP, _TEXT
@@ -481,20 +477,20 @@ LEAF_ENTRY JIT_TrialAllocSFastSP, _TEXT
; m_BaseSize is guaranteed to be a multiple of 8.
- inc [M_GCLOCK]
+ inc [g_global_alloc_lock]
jnz JIT_NEW
- mov rax, [generation_table + 0] ; alloc_ptr
- mov r10, [generation_table + 8] ; limit_ptr
+ mov rax, [g_global_alloc_context + OFFSETOF__gc_alloc_context__alloc_ptr] ; alloc_ptr
+ mov r10, [g_global_alloc_context + OFFSETOF__gc_alloc_context__alloc_limit] ; limit_ptr
add r8, rax
cmp r8, r10
ja AllocFailed
- mov qword ptr [generation_table + 0], r8 ; update the alloc ptr
+ mov qword ptr [g_global_alloc_context + OFFSETOF__gc_alloc_context__alloc_ptr], r8 ; update the alloc ptr
mov [rax], rcx
- mov [M_GCLOCK], -1
+ mov [g_global_alloc_lock], -1
ifdef _DEBUG
call DEBUG_TrialAllocSetAppDomain_NoScratchArea
@@ -503,7 +499,7 @@ endif ; _DEBUG
ret
AllocFailed:
- mov [M_GCLOCK], -1
+ mov [g_global_alloc_lock], -1
jmp JIT_NEW
LEAF_END JIT_TrialAllocSFastSP, _TEXT
@@ -520,11 +516,11 @@ NESTED_ENTRY JIT_BoxFastUP, _TEXT
; m_BaseSize is guaranteed to be a multiple of 8.
- inc [M_GCLOCK]
+ inc [g_global_alloc_lock]
jnz JIT_Box
- mov rax, [generation_table + 0] ; alloc_ptr
- mov r10, [generation_table + 8] ; limit_ptr
+ mov rax, [g_global_alloc_context + OFFSETOF__gc_alloc_context__alloc_ptr] ; alloc_ptr
+ mov r10, [g_global_alloc_context + OFFSETOF__gc_alloc_context__alloc_limit] ; limit_ptr
add r8, rax
@@ -532,9 +528,9 @@ NESTED_ENTRY JIT_BoxFastUP, _TEXT
ja NoAlloc
- mov qword ptr [generation_table + 0], r8 ; update the alloc ptr
+ mov qword ptr [g_global_alloc_context + OFFSETOF__gc_alloc_context__alloc_ptr], r8 ; update the alloc ptr
mov [rax], rcx
- mov [M_GCLOCK], -1
+ mov [g_global_alloc_lock], -1
ifdef _DEBUG
call DEBUG_TrialAllocSetAppDomain_NoScratchArea
@@ -574,7 +570,7 @@ endif ; _DEBUG
ret
NoAlloc:
- mov [M_GCLOCK], -1
+ mov [g_global_alloc_lock], -1
jmp JIT_Box
NESTED_END JIT_BoxFastUP, _TEXT
@@ -602,20 +598,20 @@ LEAF_ENTRY AllocateStringFastUP, _TEXT
lea r8d, [r8d + ecx*2 + 7]
and r8d, -8
- inc [M_GCLOCK]
+ inc [g_global_alloc_lock]
jnz FramedAllocateString
- mov rax, [generation_table + 0] ; alloc_ptr
- mov r10, [generation_table + 8] ; limit_ptr
+ mov rax, [g_global_alloc_context + OFFSETOF__gc_alloc_context__alloc_ptr] ; alloc_ptr
+ mov r10, [g_global_alloc_context + OFFSETOF__gc_alloc_context__alloc_limit] ; limit_ptr
add r8, rax
cmp r8, r10
ja AllocFailed
- mov qword ptr [generation_table + 0], r8 ; update the alloc ptr
+ mov qword ptr [g_global_alloc_context + OFFSETOF__gc_alloc_context__alloc_ptr], r8 ; update the alloc ptr
mov [rax], r11
- mov [M_GCLOCK], -1
+ mov [g_global_alloc_lock], -1
mov [rax + OFFSETOF__StringObject__m_StringLength], ecx
@@ -626,7 +622,7 @@ endif ; _DEBUG
ret
AllocFailed:
- mov [M_GCLOCK], -1
+ mov [g_global_alloc_lock], -1
jmp FramedAllocateString
LEAF_END AllocateStringFastUP, _TEXT
@@ -668,11 +664,11 @@ LEAF_ENTRY JIT_NewArr1VC_UP, _TEXT
add r8d, 7
and r8d, -8
- inc [M_GCLOCK]
+ inc [g_global_alloc_lock]
jnz JIT_NewArr1
- mov rax, [generation_table + 0] ; alloc_ptr
- mov r10, [generation_table + 8] ; limit_ptr
+ mov rax, [g_global_alloc_context + OFFSETOF__gc_alloc_context__alloc_ptr] ; alloc_ptr
+ mov r10, [g_global_alloc_context + OFFSETOF__gc_alloc_context__alloc_limit] ; limit_ptr
add r8, rax
jc AllocFailed
@@ -680,9 +676,9 @@ LEAF_ENTRY JIT_NewArr1VC_UP, _TEXT
cmp r8, r10
ja AllocFailed
- mov qword ptr [generation_table + 0], r8 ; update the alloc ptr
+ mov qword ptr [g_global_alloc_context + OFFSETOF__gc_alloc_context__alloc_ptr], r8 ; update the alloc ptr
mov [rax], r9
- mov [M_GCLOCK], -1
+ mov [g_global_alloc_lock], -1
mov dword ptr [rax + OFFSETOF__ArrayBase__m_NumComponents], edx
@@ -693,7 +689,7 @@ endif ; _DEBUG
ret
AllocFailed:
- mov [M_GCLOCK], -1
+ mov [g_global_alloc_lock], -1
jmp JIT_NewArr1
LEAF_END JIT_NewArr1VC_UP, _TEXT
@@ -731,20 +727,20 @@ LEAF_ENTRY JIT_NewArr1OBJ_UP, _TEXT
; No need for rounding in this case - element size is 8, and m_BaseSize is guaranteed
; to be a multiple of 8.
- inc [M_GCLOCK]
+ inc [g_global_alloc_lock]
jnz JIT_NewArr1
- mov rax, [generation_table + 0] ; alloc_ptr
- mov r10, [generation_table + 8] ; limit_ptr
+ mov rax, [g_global_alloc_context + OFFSETOF__gc_alloc_context__alloc_ptr] ; alloc_ptr
+ mov r10, [g_global_alloc_context + OFFSETOF__gc_alloc_context__alloc_limit] ; limit_ptr
add r8, rax
cmp r8, r10
ja AllocFailed
- mov qword ptr [generation_table + 0], r8 ; update the alloc ptr
+ mov qword ptr [g_global_alloc_context + OFFSETOF__gc_alloc_context__alloc_ptr], r8 ; update the alloc ptr
mov [rax], r9
- mov [M_GCLOCK], -1
+ mov [g_global_alloc_lock], -1
mov dword ptr [rax + OFFSETOF__ArrayBase__m_NumComponents], edx
@@ -755,7 +751,7 @@ endif ; _DEBUG
ret
AllocFailed:
- mov [M_GCLOCK], -1
+ mov [g_global_alloc_lock], -1
OversizedArray:
jmp JIT_NewArr1
diff --git a/src/vm/amd64/PInvokeStubs.asm b/src/vm/amd64/PInvokeStubs.asm
index 43f1a4752f..4801697fee 100644
--- a/src/vm/amd64/PInvokeStubs.asm
+++ b/src/vm/amd64/PInvokeStubs.asm
@@ -14,150 +14,6 @@ include AsmConstants.inc
extern GenericPInvokeCalliStubWorker:proc
extern VarargPInvokeStubWorker:proc
-ifdef FEATURE_INCLUDE_ALL_INTERFACES
-PInvokeStubForHostWorker equ ?PInvokeStubForHostWorker@@YAXKPEAX0@Z
-extern PInvokeStubForHostWorker:proc
-
-PInvokeStubForHost_CALLEE_SCRATCH_SIZE = 20h
-
-PInvokeStubForHost_STACK_FRAME_SIZE = PInvokeStubForHost_CALLEE_SCRATCH_SIZE
-
-; 4 FP parameter registers
-PInvokeStubForHost_XMM_SAVE_OFFSET = PInvokeStubForHost_STACK_FRAME_SIZE
-PInvokeStubForHost_STACK_FRAME_SIZE = PInvokeStubForHost_STACK_FRAME_SIZE + 40h
-
-; Ensure that the new rsp will be 16-byte aligned.
-if ((PInvokeStubForHost_STACK_FRAME_SIZE + 8) MOD 16) ne 0
-PInvokeStubForHost_STACK_FRAME_SIZE = PInvokeStubForHost_STACK_FRAME_SIZE + 8
-endif
-
-; Return address is immediately above the local variables.
-PInvokeStubForHost_RETURN_ADDRESS_OFFSET = PInvokeStubForHost_STACK_FRAME_SIZE
-PInvokeStubForHost_PARAM_REGISTERS_OFFSET = PInvokeStubForHost_RETURN_ADDRESS_OFFSET + 8
-
-NESTED_ENTRY PInvokeStubForHost, _TEXT
- alloc_stack PInvokeStubForHost_STACK_FRAME_SIZE
- END_PROLOGUE
-
- ; spill args
- mov [rsp + PInvokeStubForHost_PARAM_REGISTERS_OFFSET + 0h], rcx
- mov [rsp + PInvokeStubForHost_PARAM_REGISTERS_OFFSET + 8h], rdx
- mov [rsp + PInvokeStubForHost_PARAM_REGISTERS_OFFSET + 10h], r8
- mov [rsp + PInvokeStubForHost_PARAM_REGISTERS_OFFSET + 18h], r9
- movdqa [rsp + PInvokeStubForHost_XMM_SAVE_OFFSET + 0h], xmm0
- movdqa [rsp + PInvokeStubForHost_XMM_SAVE_OFFSET + 10h], xmm1
- movdqa [rsp + PInvokeStubForHost_XMM_SAVE_OFFSET + 20h], xmm2
- movdqa [rsp + PInvokeStubForHost_XMM_SAVE_OFFSET + 30h], xmm3
-
- ; PInvokeStubForHostWorker(#stack args, stack frame, this)
- mov r8, rcx
- mov rcx, r11
- mov rdx, rsp
- call PInvokeStubForHostWorker
-
- ; unspill return value
- mov rax, [rsp + PInvokeStubForHost_XMM_SAVE_OFFSET + 0h]
- movdqa xmm0, [rsp + PInvokeStubForHost_XMM_SAVE_OFFSET + 10h]
-
- add rsp, PInvokeStubForHost_STACK_FRAME_SIZE
- ret
-NESTED_END PInvokeStubForHost, _TEXT
-
-
-PInvokeStubForHostInner_STACK_FRAME_SIZE = 0
-
-; integer registers saved in prologue
-PInvokeStubForHostInner_NUM_REG_PUSHES = 2
-PInvokeStubForHostInner_STACK_FRAME_SIZE = PInvokeStubForHostInner_STACK_FRAME_SIZE + PInvokeStubForHostInner_NUM_REG_PUSHES*8
-
-; Ensure that the new rsp will be 16-byte aligned.
-if ((PInvokeStubForHostInner_STACK_FRAME_SIZE + 8) MOD 16) ne 0
-PInvokeStubForHostInner_STACK_FRAME_SIZE = PInvokeStubForHostInner_STACK_FRAME_SIZE + 8
-endif
-
-; Return address is immediately above the local variables.
-PInvokeStubForHostInner_RETURN_ADDRESS_OFFSET = PInvokeStubForHostInner_STACK_FRAME_SIZE
-PInvokeStubForHostInner_PARAM_REGISTERS_OFFSET = PInvokeStubForHostInner_RETURN_ADDRESS_OFFSET + 8
-
-PInvokeStubForHostInner_FRAME_OFFSET = PInvokeStubForHost_CALLEE_SCRATCH_SIZE
-
-; RCX - #stack args
-; RDX - PInvokeStubForHost's stack frame
-; R8 - target address
-NESTED_ENTRY PInvokeStubForHostInner, _TEXT
-
- push_nonvol_reg rbp
- push_nonvol_reg r12
- alloc_stack PInvokeStubForHostInner_FRAME_OFFSET + PInvokeStubForHostInner_STACK_FRAME_SIZE - PInvokeStubForHostInner_NUM_REG_PUSHES*8
- set_frame rbp, PInvokeStubForHostInner_FRAME_OFFSET
- END_PROLOGUE
-
- mov r10, r8
- mov r12, rdx
-
- test rcx, rcx
- jnz HandleStackArgs
-
- ;
- ; Allocate space for scratch area if there are no stack args.
- ;
- sub rsp, PInvokeStubForHost_CALLEE_SCRATCH_SIZE
-
-DoneStackArgs:
- ; unspill args
- mov rcx, [r12 + PInvokeStubForHost_PARAM_REGISTERS_OFFSET + 0h]
- mov rdx, [r12 + PInvokeStubForHost_PARAM_REGISTERS_OFFSET + 8h]
- mov r8, [r12 + PInvokeStubForHost_PARAM_REGISTERS_OFFSET + 10h]
- mov r9, [r12 + PInvokeStubForHost_PARAM_REGISTERS_OFFSET + 18h]
- movdqa xmm0, [r12 + PInvokeStubForHost_XMM_SAVE_OFFSET + 0h]
- movdqa xmm1, [r12 + PInvokeStubForHost_XMM_SAVE_OFFSET + 10h]
- movdqa xmm2, [r12 + PInvokeStubForHost_XMM_SAVE_OFFSET + 20h]
- movdqa xmm3, [r12 + PInvokeStubForHost_XMM_SAVE_OFFSET + 30h]
-
- call r10
-
- ; spill return value
- mov [r12 + PInvokeStubForHost_XMM_SAVE_OFFSET + 0h], rax
- movdqa [r12 + PInvokeStubForHost_XMM_SAVE_OFFSET + 10h], xmm0
-
- ; epilogue
- lea rsp, [rbp + PInvokeStubForHostInner_RETURN_ADDRESS_OFFSET - PInvokeStubForHostInner_NUM_REG_PUSHES*8]
- pop r12
- pop rbp
- ret
-
-; INPUTS:
-; RDX - number of stack bytes
-; R12 - the outer method's frame pointer
-; RSP -
-; RBP -
-;
-HandleStackArgs:
- ;
- ; Allocate space for stack parameters + scratch area.
- ;
- sub rsp, rcx
- and rsp, -16
- sub rsp, PInvokeStubForHost_CALLEE_SCRATCH_SIZE
-
- ;
- ; Copy stack parameters
- ;
- shr rcx, 3 ; setup count
-
- mov r8, rdi
- mov r9, rsi
-
- lea rdi, [rsp + PInvokeStubForHost_CALLEE_SCRATCH_SIZE] ; rdi -> above callee scratch area
- lea rsi, [r12 + PInvokeStubForHost_PARAM_REGISTERS_OFFSET + PInvokeStubForHost_CALLEE_SCRATCH_SIZE]
- rep movsq
-
- mov rsi, r9 ; restore rsi
- mov rdi, r8 ; restore rdi
- jmp DoneStackArgs
-NESTED_END PInvokeStubForHostInner, _TEXT
-endif ; FEATURE_INCLUDE_ALL_INTERFACES
-
;
; in:
; PINVOKE_CALLI_TARGET_REGISTER (r10) = unmanaged target
diff --git a/src/vm/amd64/RemotingThunksAMD64.asm b/src/vm/amd64/RemotingThunksAMD64.asm
deleted file mode 100644
index 6d555e8beb..0000000000
--- a/src/vm/amd64/RemotingThunksAMD64.asm
+++ /dev/null
@@ -1,303 +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 AsmMacros.inc
-include AsmConstants.inc
-ifdef FEATURE_REMOTING
-
-extern CallDescrWorkerUnwindFrameChainHandler:proc
-
-extern TransparentProxyStubWorker:proc
-
-; Stack frame layout:
-;
-; (stack parameters)
-; ...
-; r9
-; r8
-; rdx
-; rcx <- TPSCC_PARAMS_OFFSET
-; return address <- TPSCC_STACK_FRAME_SIZE
-; r10 <- TPSCC_R10_OFFSET
-; xmm3
-; xmm2
-; xmm1
-; xmm0 <- TPSCC_XMM_SAVE_OFFSET
-; callee's r9
-; callee's r8
-; callee's rdx
-; callee's rcx
-
-TPSCC_XMM_SAVE_OFFSET = 20h
-TPSCC_R10_OFFSET = 60h
-TPSCC_STACK_FRAME_SIZE = 68h
-TPSCC_PARAMS_OFFSET = 70h
-
-TRANSPARENT_PROXY_STUB_PROLOGUE macro
- alloc_stack TPSCC_STACK_FRAME_SIZE
-
- save_reg_postrsp r10, TPSCC_R10_OFFSET
-
- SAVE_ARGUMENT_REGISTERS TPSCC_PARAMS_OFFSET
- SAVE_FLOAT_ARGUMENT_REGISTERS TPSCC_XMM_SAVE_OFFSET
-
- END_PROLOGUE
-
- endm
-
-NESTED_ENTRY TransparentProxyStub, _TEXT, CallDescrWorkerUnwindFrameChainHandler
-
- TRANSPARENT_PROXY_STUB_PROLOGUE
-
- ;; rcx: this
- ;; [rsp]: slot number
-
- mov rax, [rcx + TransparentProxyObject___stub]
- mov rcx, [rcx + TransparentProxyObject___stubData]
- call rax
-
- RESTORE_ARGUMENT_REGISTERS TPSCC_PARAMS_OFFSET
- RESTORE_FLOAT_ARGUMENT_REGISTERS TPSCC_XMM_SAVE_OFFSET
-
- mov r10, [rsp + TPSCC_R10_OFFSET]
-
- test rax, rax
- jnz CrossContext
-
- mov r11, [rcx + TransparentProxyObject___pMT]
-
- ; Convert the slot number (r10) into the code address (in rax)
- ; See MethodTable.h for details on vtable layout
- shr r10, MethodTable_VtableSlotsPerChunkLog2
- mov rax, [r11 + r10*8 + METHODTABLE_OFFSET_VTABLE]
-
- mov r10, [rsp + TPSCC_R10_OFFSET] ; Reload the slot
- and r10, MethodTable_VtableSlotsPerChunk-1
- mov rax, [rax + r10*8]
-
- add rsp, TPSCC_STACK_FRAME_SIZE
- TAILJMP_RAX
-
-CrossContext:
- add rsp, TPSCC_STACK_FRAME_SIZE
- jmp TransparentProxyStub_CrossContext
-
-NESTED_END TransparentProxyStub, _TEXT
-
-
-NESTED_ENTRY TransparentProxyStub_CrossContext, _TEXT
-
- PROLOG_WITH_TRANSITION_BLOCK 8
-
- ;
- ; Call TransparentProxyStubWorker.
- ;
- lea rcx, [rsp + __PWTB_TransitionBlock] ; pTransitionBlock
- mov rdx, r10 ; MethodDesc *
- call TransparentProxyStubWorker
-
- ; handle FP return values
-
- lea rcx, [rsp + __PWTB_FloatArgumentRegisters - 8]
- cmp rax, 4
- jne @F
- movss xmm0, real4 ptr [rcx]
-@@:
- cmp rax, 8
- jne @F
- movsd xmm0, real8 ptr [rcx]
-@@:
- ; load return value
- mov rax, [rcx]
-
- EPILOG_WITH_TRANSITION_BLOCK_RETURN
-
-NESTED_END TransparentProxyStub_CrossContext, _TEXT
-
-LEAF_ENTRY TransparentProxyStubPatch, _TEXT
- ; make sure that the basic block is unique
- test eax,12
-PATCH_LABEL TransparentProxyStubPatchLabel
- ret
-LEAF_END TransparentProxyStubPatch, _TEXT
-
-;+----------------------------------------------------------------------------
-;
-; Method: CRemotingServices::CallFieldGetter private
-;
-; Synopsis: Calls the field getter function (Object::__FieldGetter) in
-; managed code by setting up the stack and calling the target
-;
-;+----------------------------------------------------------------------------
-; extern "C"
-;void __stdcall CRemotingServices__CallFieldGetter( MethodDesc *pMD,
-; LPVOID pThis,
-; LPVOID pFirst,
-; LPVOID pSecond,
-; LPVOID pThird
-; )
-LEAF_ENTRY CRemotingServices__CallFieldGetter, _TEXT
-
-; +28 pThird
-; +20 scratch area
-; +18 scratch area
-; +10 scratch area
-; + 8 scratch area
-; rsp return address
-
- mov METHODDESC_REGISTER, rcx
- mov rcx, rdx
- mov rdx, r8
- mov r8, r9
- mov r9, [rsp + 28h]
- jmp TransparentProxyStub
-
-LEAF_END CRemotingServices__CallFieldGetter, _TEXT
-
-
-;+----------------------------------------------------------------------------
-;
-; Method: CRemotingServices::CallFieldSetter private
-;
-; Synopsis: Calls the field setter function (Object::__FieldSetter) in
-; managed code by setting up the stack and calling the target
-;
-;+----------------------------------------------------------------------------
-; extern "C"
-;void __stdcall CRemotingServices__CallFieldSetter( MethodDesc *pMD,
-; LPVOID pThis,
-; LPVOID pFirst,
-; LPVOID pSecond,
-; LPVOID pThird
-; )
-LEAF_ENTRY CRemotingServices__CallFieldSetter, _TEXT
-
-; +28 pThird
-; +20 scratch area
-; +18 scratch area
-; +10 scratch area
-; + 8 scratch area
-; rsp return address
-
- mov METHODDESC_REGISTER, rcx
- mov rcx, rdx
- mov rdx, r8
- mov r8, r9
- mov r9, [rsp + 28h]
- jmp TransparentProxyStub
-
-LEAF_END CRemotingServices__CallFieldSetter, _TEXT
-
-
-;; extern "C" ARG_SLOT __stdcall CTPMethodTable__CallTargetHelper2(const void *pTarget,
-;; LPVOID pvFirst,
-;; LPVOID pvSecond);
-NESTED_ENTRY CTPMethodTable__CallTargetHelper2, _TEXT, CallDescrWorkerUnwindFrameChainHandler
- alloc_stack 28h ;; alloc callee scratch and align the stack
- END_PROLOGUE
-
- mov rax, rcx ; rax <- call target
- mov rcx, rdx ; rcx <- first arg
- mov rdx, r8 ; rdx <- second arg
-
- call rax
- ;; It is important to have an instruction between the previous call and the epilog.
- ;; If the return address is in epilog, OS won't call personality routine because
- ;; it thinks personality routine does not help in this case.
- nop
-
- ; epilog
- add rsp, 28h
- ret
-NESTED_END CTPMethodTable__CallTargetHelper2, _TEXT
-
-;; extern "C" ARG_SLOT __stdcall CTPMethodTable__CallTargetHelper2(const void *pTarget,
-;; LPVOID pvFirst,
-;; LPVOID pvSecond,
-;; LPVOID pvThird);
-NESTED_ENTRY CTPMethodTable__CallTargetHelper3, _TEXT, CallDescrWorkerUnwindFrameChainHandler
- alloc_stack 28h ;; alloc callee scratch and align the stack
- END_PROLOGUE
-
- mov rax, rcx ; rax <- call target
- mov rcx, rdx ; rcx <- first arg
- mov rdx, r8 ; rdx <- second arg
- mov r8, r9 ; r8 <- third arg
-
- call rax
-
- ;; It is important to have an instruction between the previous call and the epilog.
- ;; If the return address is in epilog, OS won't call personality routine because
- ;; it thinks personality routine does not help in this case.
- nop
-
- ; epilog
- add rsp, 28h
- ret
-NESTED_END CTPMethodTable__CallTargetHelper3, _TEXT
-
-NESTED_ENTRY CRemotingServices__DispatchInterfaceCall, _TEXT, CallDescrWorkerUnwindFrameChainHandler
-
- TRANSPARENT_PROXY_STUB_PROLOGUE
-
- ;
- ; 'this' is a TransparentProxy. Call to stub to see if need to cross contexts.
- ;
-
- mov rax, [rcx + TransparentProxyObject___stub]
- mov rcx, [rcx + TransparentProxyObject___stubData]
- call rax
-
- test rax, rax
- jnz CrossContext
-
-extern VSD_GetTargetForTPWorkerQuick:proc
- mov rcx, [rsp + TPSCC_PARAMS_OFFSET] ; rcx <- this
- mov rdx, [rsp + TPSCC_R10_OFFSET] ; rdx <- Get the MethodDesc* or slot number
- call VSD_GetTargetForTPWorkerQuick
-
- RESTORE_ARGUMENT_REGISTERS TPSCC_PARAMS_OFFSET
- RESTORE_FLOAT_ARGUMENT_REGISTERS TPSCC_XMM_SAVE_OFFSET
-
- mov r10, [rsp + TPSCC_R10_OFFSET]
-
- test rax, rax ; Did we find a target?
- jz SlowDispatch
-
- add rsp, TPSCC_STACK_FRAME_SIZE
- TAILJMP_RAX
-
-SlowDispatch:
- add rsp, TPSCC_STACK_FRAME_SIZE
- jmp InContextTPDispatchAsmStub
-
-CrossContext:
- RESTORE_ARGUMENT_REGISTERS TPSCC_PARAMS_OFFSET
- RESTORE_FLOAT_ARGUMENT_REGISTERS TPSCC_XMM_SAVE_OFFSET
-
- mov r10, [rsp + TPSCC_R10_OFFSET]
-
- add rsp, TPSCC_STACK_FRAME_SIZE
- jmp TransparentProxyStub_CrossContext
-
-NESTED_END CRemotingServices__DispatchInterfaceCall, _TEXT
-
-NESTED_ENTRY InContextTPDispatchAsmStub, _TEXT
-
- PROLOG_WITH_TRANSITION_BLOCK
-
-extern VSD_GetTargetForTPWorker:proc
- lea rcx, [rsp + __PWTB_TransitionBlock] ; pTransitionBlock
- mov rdx, r10 ; token
- call VSD_GetTargetForTPWorker
-
- EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
- TAILJMP_RAX
-
-NESTED_END InContextTPDispatchAsmStub, _TEXT
-
-endif ; FEATURE_REMOTING
-
- end
-
diff --git a/src/vm/amd64/UMThunkStub.asm b/src/vm/amd64/UMThunkStub.asm
index ad3f17c854..dd6d4ebc3c 100644
--- a/src/vm/amd64/UMThunkStub.asm
+++ b/src/vm/amd64/UMThunkStub.asm
@@ -11,28 +11,15 @@
include <AsmMacros.inc>
include AsmConstants.inc
-ifdef FEATURE_MIXEDMODE
-IJWNOADThunk__MakeCall equ ?MakeCall@IJWNOADThunk@@KAXXZ
-IJWNOADThunk__FindThunkTarget equ ?FindThunkTarget@IJWNOADThunk@@QEAAPEBXXZ
-endif
gfHostConfig equ ?g_fHostConfig@@3KA
NDirect__IsHostHookEnabled equ ?IsHostHookEnabled@NDirect@@SAHXZ
extern CreateThreadBlockThrow:proc
extern TheUMEntryPrestubWorker:proc
-ifdef FEATURE_MIXEDMODE
-extern IJWNOADThunk__FindThunkTarget:proc
-endif
extern UMEntryPrestubUnwindFrameChainHandler:proc
extern UMThunkStubUnwindFrameChainHandler:proc
extern g_TrapReturningThreads:dword
extern UM2MDoADCallBack:proc
-extern ReverseEnterRuntimeHelper:proc
-extern ReverseLeaveRuntimeHelper:proc
-ifdef FEATURE_INCLUDE_ALL_INTERFACES
-extern gfHostConfig:dword
-extern NDirect__IsHostHookEnabled:proc
-endif
extern UMThunkStubRareDisableWorker:proc
extern ReversePInvokeBadTransition:proc
@@ -204,16 +191,6 @@ HaveThread:
InCooperativeMode:
-ifdef FEATURE_INCLUDE_ALL_INTERFACES
- test [gfHostConfig], ASM_CLRTASKHOSTED ; inlined NDirect::IsHostHookEnabled ; hosted
-ifdef _DEBUG
- call IsHostHookEnabledHelper
- test eax, eax
-endif ; _DEBUG
- jnz NotifyHost_ReverseEnterRuntime ; hosted
-Done_NotifyHost_ReverseEnterRuntime:
-endif
-
mov rax, [r12 + OFFSETOF__Thread__m_pDomain]
mov eax, [rax + OFFSETOF__AppDomain__m_dwId]
@@ -238,12 +215,6 @@ PostCall:
;
mov dword ptr [r12 + OFFSETOF__Thread__m_fPreemptiveGCDisabled], 0
-ifdef FEATURE_INCLUDE_ALL_INTERFACES
- cmp byte ptr [rbp + UMThunkStubAMD64_HOST_NOTIFY_FLAG_OFFSET], 0 ; hosted
- jnz NotifyHost_ReverseLeaveRuntime ; hosted
-Done_NotifyHost_ReverseLeaveRuntime:
-endif
-
; epilog
lea rsp, [rbp - UMThunkStubAMD64_FRAME_OFFSET + UMThunkStubAMD64_FIXED_STACK_ALLOC_SIZE]
pop rbp ; stack_args
@@ -352,58 +323,6 @@ CopyLoop:
jmp ArgumentsSetup
-ifdef FEATURE_INCLUDE_ALL_INTERFACES
-NotifyHost_ReverseEnterRuntime:
- mov [rbp + UMThunkStubAMD64_RARE_PATH_SPILL_OFFSET], METHODDESC_REGISTER
-
- mov [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 0h], rcx
- mov [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 8h], rdx
- mov [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 10h], r8
- mov [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 18h], r9
-
- ; @CONSIDER: mark UMEntryThunks that have FP params and only save/restore xmm regs on those calls
- ; initial measurements indidcate that this could be worth about a 5% savings in reverse
- ; pinvoke overhead.
- movdqa xmmword ptr [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 0h], xmm0
- movdqa xmmword ptr [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 10h], xmm1
- movdqa xmmword ptr [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 20h], xmm2
- movdqa xmmword ptr [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 30h], xmm3
-
- mov rcx, r12
- call ReverseEnterRuntimeHelper
- mov byte ptr [rbp + UMThunkStubAMD64_HOST_NOTIFY_FLAG_OFFSET], 1
-
- mov rcx, [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 0h]
- mov rdx, [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 8h]
- mov r8, [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 10h]
- mov r9, [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 18h]
-
- ; @CONSIDER: mark UMEntryThunks that have FP params and only save/restore xmm regs on those calls
- movdqa xmm0, xmmword ptr [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 0h]
- movdqa xmm1, xmmword ptr [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 10h]
- movdqa xmm2, xmmword ptr [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 20h]
- movdqa xmm3, xmmword ptr [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 30h]
-
- mov METHODDESC_REGISTER, [rbp + UMThunkStubAMD64_RARE_PATH_SPILL_OFFSET]
-
- jmp Done_NotifyHost_ReverseEnterRuntime
-
-NotifyHost_ReverseLeaveRuntime:
-
- ; save rax, xmm0
- mov [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 0h], rax
- movdqa xmmword ptr [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 0h], xmm0
-
- mov rcx, r12
- call ReverseLeaveRuntimeHelper
- mov byte ptr [rbp + UMThunkStubAMD64_HOST_NOTIFY_FLAG_OFFSET], 0
-
- ; restore rax, xmm0
- mov rax, [rbp + UMThunkStubAMD64_ARGUMENTS_STACK_HOME_OFFSET + 0h]
- movdqa xmm0, xmmword ptr [rbp + UMThunkStubAMD64_XMM_SAVE_OFFSET + 0h]
-
- jmp Done_NotifyHost_ReverseLeaveRuntime
-endif
WrongAppDomain:
;
@@ -536,83 +455,5 @@ CopyStackArgs:
NESTED_END UM2MThunk_WrapperHelper, _TEXT
-ifdef _DEBUG
-ifdef FEATURE_INCLUDE_ALL_INTERFACES
-
-NESTED_ENTRY IsHostHookEnabledHelper, _TEXT
-
- push_nonvol_reg rcx
- push_nonvol_reg rdx
- push_nonvol_reg r8
- push_nonvol_reg r9
- push_nonvol_reg r10
-
-IsHostHookEnabledHelper_FIXED_STACK_ALLOC_SIZE = 20h + 40h
-
- alloc_stack IsHostHookEnabledHelper_FIXED_STACK_ALLOC_SIZE
-
- END_PROLOGUE
-
- movdqa xmmword ptr [rsp + 20h + 0h], xmm0
- movdqa xmmword ptr [rsp + 20h + 10h], xmm1
- movdqa xmmword ptr [rsp + 20h + 20h], xmm2
- movdqa xmmword ptr [rsp + 20h + 30h], xmm3
-
- call NDirect__IsHostHookEnabled
-
- movdqa xmm0, xmmword ptr [rsp + 20h + 0h]
- movdqa xmm1, xmmword ptr [rsp + 20h + 10h]
- movdqa xmm2, xmmword ptr [rsp + 20h + 20h]
- movdqa xmm3, xmmword ptr [rsp + 20h + 30h]
-
- ; epilog
- add rsp, IsHostHookEnabledHelper_FIXED_STACK_ALLOC_SIZE
- pop r10
- pop r9
- pop r8
- pop rdx
- pop rcx
- ret
-NESTED_END IsHostHookEnabledHelper, _TEXT
-
-endif ; FEATURE_INCLUDE_ALL_INTERFACES
-endif ; _DEBUG
-
-ifdef FEATURE_MIXEDMODE
-NESTED_ENTRY IJWNOADThunk__MakeCall, _TEXT
- ; METHODDESC_REGISTER = IJWNOADThunk*
-
- alloc_stack 68h
-
- save_reg_postrsp rcx, 70h
- save_reg_postrsp rdx, 78h
- save_reg_postrsp r8, 80h
- save_reg_postrsp r9, 88h
-
- save_xmm128_postrsp xmm0, 20h
- save_xmm128_postrsp xmm1, 30h
- save_xmm128_postrsp xmm2, 40h
- save_xmm128_postrsp xmm3, 50h
- END_PROLOGUE
-
- mov rcx, METHODDESC_REGISTER
- call IJWNOADThunk__FindThunkTarget
-
- movdqa xmm0, xmmword ptr [rsp + 20h]
- movdqa xmm1, xmmword ptr [rsp + 30h]
- movdqa xmm2, xmmword ptr [rsp + 40h]
- movdqa xmm3, xmmword ptr [rsp + 50h]
-
- mov rcx, [rsp + 70h]
- mov rdx, [rsp + 78h]
- mov r8, [rsp + 80h]
- mov r9 , [rsp + 88h]
-
- ; The target is in rax
- add rsp, 68h
- TAILJMP_RAX
-NESTED_END IJWNOADThunk__MakeCall, _TEXT
-endif ; FEATURE_MIXEDMODE
-
end
diff --git a/src/vm/amd64/asmconstants.h b/src/vm/amd64/asmconstants.h
index ad90dd17ad..e4f77deb42 100644
--- a/src/vm/amd64/asmconstants.h
+++ b/src/vm/amd64/asmconstants.h
@@ -47,10 +47,6 @@ ASMCONSTANTS_C_ASSERT(ASM_ELEMENT_TYPE_R4 == ELEMENT_TYPE_R4);
#define ASM_ELEMENT_TYPE_R8 0xD
ASMCONSTANTS_C_ASSERT(ASM_ELEMENT_TYPE_R8 == ELEMENT_TYPE_R8);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-#define ASM_CLRTASKHOSTED 0x2
-ASMCONSTANTS_C_ASSERT(ASM_CLRTASKHOSTED == CLRTASKHOSTED);
-#endif
#define METHODDESC_REGNUM 10
#define METHODDESC_REGISTER r10
@@ -169,6 +165,12 @@ ASMCONSTANTS_C_ASSERT(OFFSET__Thread__m_alloc_context__alloc_ptr == offsetof(Thr
#define OFFSET__Thread__m_alloc_context__alloc_limit 0x68
ASMCONSTANTS_C_ASSERT(OFFSET__Thread__m_alloc_context__alloc_limit == offsetof(Thread, m_alloc_context) + offsetof(gc_alloc_context, alloc_limit));
+#define OFFSETOF__gc_alloc_context__alloc_ptr 0x0
+ASMCONSTANT_OFFSETOF_ASSERT(gc_alloc_context, alloc_ptr);
+
+#define OFFSETOF__gc_alloc_context__alloc_limit 0x8
+ASMCONSTANT_OFFSETOF_ASSERT(gc_alloc_context, alloc_limit);
+
#define OFFSETOF__ThreadExceptionState__m_pCurrentTracker 0x000
ASMCONSTANTS_C_ASSERT(OFFSETOF__ThreadExceptionState__m_pCurrentTracker
== offsetof(ThreadExceptionState, m_pCurrentTracker));
@@ -178,16 +180,6 @@ ASMCONSTANTS_C_ASSERT(THREAD_CATCHATSAFEPOINT_BITS == Thread::TS_CatchAtSafePoin
#endif // CROSSGEN_COMPILE
-#ifdef FEATURE_REMOTING
-#define TransparentProxyObject___stubData 0x10
-ASMCONSTANTS_C_ASSERT(TransparentProxyObject___stubData == offsetof(TransparentProxyObject, _stubData))
-
-#define TransparentProxyObject___stub 0x28
-ASMCONSTANTS_C_ASSERT(TransparentProxyObject___stub == offsetof(TransparentProxyObject, _stub))
-
-#define TransparentProxyObject___pMT 0x18
-ASMCONSTANTS_C_ASSERT(TransparentProxyObject___pMT == offsetof(TransparentProxyObject, _pMT))
-#endif // FEATURE_REMOTING
#define OFFSETOF__NDirectMethodDesc__m_pWriteableData DBG_FRE(0x48, 0x20)
ASMCONSTANTS_C_ASSERT(OFFSETOF__NDirectMethodDesc__m_pWriteableData == offsetof(NDirectMethodDesc, ndirect.m_pWriteableData));
@@ -281,7 +273,7 @@ ASMCONSTANTS_C_ASSERT(MethodTable_VtableSlotsPerChunk == VTABLE_SLOTS_PER_CHUNK)
#define MethodTable_VtableSlotsPerChunkLog2 3
ASMCONSTANTS_C_ASSERT(MethodTable_VtableSlotsPerChunkLog2 == VTABLE_SLOTS_PER_CHUNK_LOG2)
-#if defined(FEATURE_TYPEEQUIVALENCE) || defined(FEATURE_REMOTING)
+#if defined(FEATURE_TYPEEQUIVALENCE)
#define METHODTABLE_EQUIVALENCE_FLAGS 0x02000000
ASMCONSTANTS_C_ASSERT(METHODTABLE_EQUIVALENCE_FLAGS
== MethodTable::enum_flag_HasTypeEquivalence);
diff --git a/src/vm/amd64/cgenamd64.cpp b/src/vm/amd64/cgenamd64.cpp
index 51aac1ebc6..497abcd502 100644
--- a/src/vm/amd64/cgenamd64.cpp
+++ b/src/vm/amd64/cgenamd64.cpp
@@ -727,6 +727,35 @@ INT32 rel32UsingJumpStub(INT32 UNALIGNED * pRel32, PCODE target, MethodDesc *pMe
return static_cast<INT32>(offset);
}
+INT32 rel32UsingPreallocatedJumpStub(INT32 UNALIGNED * pRel32, PCODE target, PCODE jumpStubAddr)
+{
+ CONTRACTL
+ {
+ THROWS; // emitBackToBackJump may throw (see emitJump)
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ TADDR baseAddr = (TADDR)pRel32 + 4;
+ _ASSERTE(FitsInI4(jumpStubAddr - baseAddr));
+
+ INT_PTR offset = target - baseAddr;
+ if (!FitsInI4(offset) INDEBUG(|| PEDecoder::GetForceRelocs()))
+ {
+ offset = jumpStubAddr - baseAddr;
+ if (!FitsInI4(offset))
+ {
+ _ASSERTE(!"jump stub was not in expected range");
+ EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
+ }
+
+ emitBackToBackJump((LPBYTE)jumpStubAddr, (LPVOID)target);
+ }
+
+ _ASSERTE(FitsInI4(offset));
+ return static_cast<INT32>(offset);
+}
+
BOOL DoesSlotCallPrestub(PCODE pCode)
{
CONTRACTL {
diff --git a/src/vm/amd64/cgencpu.h b/src/vm/amd64/cgencpu.h
index 769f4029ee..2d4dce0e6e 100644
--- a/src/vm/amd64/cgencpu.h
+++ b/src/vm/amd64/cgencpu.h
@@ -57,6 +57,7 @@ EXTERN_C void FastCallFinalizeWorker(Object *obj, PCODE funcPtr);
//#define HAS_REMOTING_PRECODE 1 // TODO: Implement
#define HAS_FIXUP_PRECODE 1
#define HAS_FIXUP_PRECODE_CHUNKS 1
+#define FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS 1
// ThisPtrRetBufPrecode one is necessary for closed delegates over static methods with return buffer
#define HAS_THISPTR_RETBUF_PRECODE 1
@@ -381,6 +382,9 @@ void EncodeLoadAndJumpThunk (LPBYTE pBuffer, LPVOID pv, LPVOID pTarget);
// Get Rel32 destination, emit jumpStub if necessary
INT32 rel32UsingJumpStub(INT32 UNALIGNED * pRel32, PCODE target, MethodDesc *pMethod, LoaderAllocator *pLoaderAllocator = NULL);
+// Get Rel32 destination, emit jumpStub if necessary into a preallocated location
+INT32 rel32UsingPreallocatedJumpStub(INT32 UNALIGNED * pRel32, PCODE target, PCODE jumpStubAddr);
+
void emitCOMStubCall (ComCallMethodDesc *pCOMMethod, PCODE target);
void emitJump(LPBYTE pBuffer, LPVOID target);
diff --git a/src/vm/amd64/jithelpers_fast.S b/src/vm/amd64/jithelpers_fast.S
index 8076655ad9..0ec63f7c5c 100644
--- a/src/vm/amd64/jithelpers_fast.S
+++ b/src/vm/amd64/jithelpers_fast.S
@@ -119,6 +119,22 @@ LEAF_ENTRY JIT_WriteBarrier, _TEXT
UpdateCardTable:
mov byte ptr [rdi + rax], 0FFh
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ NOP_2_BYTE // padding for alignment of constant
+ shr rdi, 0x0A
+
+ movabs rax, 0xF0F0F0F0F0F0F0F0
+ cmp byte ptr [rdi + rax], 0FFh
+
+ .byte 0x75, 0x02
+ // jne UpdateCardBundle_WriteWatch_PostGrow64
+ REPRET
+
+ UpdateCardBundle_WriteWatch_PostGrow64:
+ mov byte ptr [rdi + rax], 0FFh
+#endif
+
ret
.balign 16
@@ -163,12 +179,31 @@ LEAF_ENTRY JIT_WriteBarrier, _TEXT
// Touch the card table entry, if not already dirty.
shr rdi, 0Bh
cmp byte ptr [rdi + rax], 0FFh
- // jne UpdateCardTable
.byte 0x75, 0x02
+ // jne UpdateCardTable
REPRET
UpdateCardTable:
mov byte ptr [rdi + rax], 0FFh
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ NOP_6_BYTE // padding for alignment of constant
+
+ movabs rax, 0xF0F0F0F0F0F0F0F0
+
+ // Touch the card bundle, if not already dirty.
+ // rdi is already shifted by 0xB, so shift by 0xA more
+ shr rdi, 0x0A
+ cmp byte ptr [rdi + rax], 0FFh
+
+ .byte 0x75, 0x02
+ // jne UpdateCardBundle
+ REPRET
+
+ UpdateCardBundle:
+ mov byte ptr [rdi + rax], 0FFh
+#endif
+
ret
.balign 16
@@ -303,16 +338,36 @@ LEAF_ENTRY JIT_ByRefWriteBarrier, _TEXT
// Check if we need to update the card table
// Calc pCardByte
shr rcx, 0x0B
+
PREPARE_EXTERNAL_VAR g_card_table, rax
- add rcx, [rax]
+ mov rax, [rax]
// Check if this card is dirty
- cmp byte ptr [rcx], 0FFh
+ cmp byte ptr [rcx + rax], 0FFh
+
jne UpdateCardTable_ByRefWriteBarrier
REPRET
UpdateCardTable_ByRefWriteBarrier:
+ mov byte ptr [rcx + rax], 0FFh
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ // Shift rcx by 0x0A more to get the card bundle byte (we shifted by 0x0B already)
+ shr rcx, 0x0A
+
+ PREPARE_EXTERNAL_VAR g_card_bundle_table, rax
+ add rcx, [rax]
+
+ // Check if this bundle byte is dirty
+ cmp byte ptr [rcx], 0FFh
+
+ jne UpdateCardBundle_ByRefWriteBarrier
+ REPRET
+
+ UpdateCardBundle_ByRefWriteBarrier:
mov byte ptr [rcx], 0FFh
+#endif
+
ret
.balign 16
diff --git a/src/vm/amd64/jithelpers_fastwritebarriers.S b/src/vm/amd64/jithelpers_fastwritebarriers.S
index 6d61b26c26..23c1115165 100644
--- a/src/vm/amd64/jithelpers_fastwritebarriers.S
+++ b/src/vm/amd64/jithelpers_fastwritebarriers.S
@@ -23,7 +23,12 @@ PATCH_LABEL JIT_WriteBarrier_PreGrow64_Patch_Label_Lower
// Check the lower ephemeral region bound.
cmp rsi, rax
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ .byte 0x72, 0x4B
+#else
.byte 0x72, 0x23
+#endif
// jb Exit_PreGrow64
nop // padding for alignment of constant
@@ -40,6 +45,26 @@ PATCH_LABEL JIT_WriteBarrier_PreGrow64_Patch_Label_CardTable
UpdateCardTable_PreGrow64:
mov byte ptr [rdi + rax], 0FFh
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ NOP_6_BYTE // padding for alignment of constant
+
+PATCH_LABEL JIT_WriteBarrier_PreGrow64_Patch_Label_CardBundleTable
+ movabs rax, 0xF0F0F0F0F0F0F0F0
+
+ // Touch the card bundle, if not already dirty.
+ // rdi is already shifted by 0xB, so shift by 0xA more
+ shr rdi, 0x0A
+ cmp byte ptr [rdi + rax], 0FFh
+
+ .byte 0x75, 0x02
+ // jne UpdateCardBundle_PreGrow64
+ REPRET
+
+ UpdateCardBundle_PreGrow64:
+ mov byte ptr [rdi + rax], 0FFh
+#endif
+
ret
.balign 16
@@ -69,7 +94,12 @@ PATCH_LABEL JIT_WriteBarrier_PostGrow64_Patch_Label_Lower
// Check the lower and upper ephemeral region bounds
cmp rsi, rax
- .byte 0x72,0x33
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ .byte 0x72, 0x53
+#else
+ .byte 0x72, 0x33
+#endif
// jb Exit_PostGrow64
nop // padding for alignment of constant
@@ -78,7 +108,12 @@ PATCH_LABEL JIT_WriteBarrier_PostGrow64_Patch_Label_Upper
movabs r8, 0xF0F0F0F0F0F0F0F0
cmp rsi, r8
- .byte 0x73,0x23
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ .byte 0x73, 0x43
+#else
+ .byte 0x73, 0x23
+#endif
// jae Exit_PostGrow64
nop // padding for alignment of constant
@@ -95,6 +130,26 @@ PATCH_LABEL JIT_WriteBarrier_PostGrow64_Patch_Label_CardTable
UpdateCardTable_PostGrow64:
mov byte ptr [rdi + rax], 0FFh
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ NOP_6_BYTE // padding for alignment of constant
+
+PATCH_LABEL JIT_WriteBarrier_PostGrow64_Patch_Label_CardBundleTable
+ movabs rax, 0xF0F0F0F0F0F0F0F0
+
+ // Touch the card bundle, if not already dirty.
+ // rdi is already shifted by 0xB, so shift by 0xA more
+ shr rdi, 0x0A
+ cmp byte ptr [rdi + rax], 0FFh
+
+ .byte 0x75, 0x02
+ // jne UpdateCardBundle_PostGrow64
+ REPRET
+
+ UpdateCardBundle_PostGrow64:
+ mov byte ptr [rdi + rax], 0FFh
+#endif
+
ret
.balign 16
@@ -134,7 +189,27 @@ PATCH_LABEL JIT_WriteBarrier_SVR64_PatchLabel_CardTable
UpdateCardTable_SVR64:
mov byte ptr [rdi + rax], 0FFh
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ NOP_6_BYTE // padding for alignment of constant
+
+PATCH_LABEL JIT_WriteBarrier_SVR64_PatchLabel_CardBundleTable
+ movabs rax, 0xF0F0F0F0F0F0F0F0
+
+ // Shift the address by 0xA more since already shifted by 0xB
+ shr rdi, 0x0A
+ cmp byte ptr [rdi + rax], 0FFh
+
+ .byte 0x75, 0x02
+ // jne UpdateCardBundle_SVR64
+ REPRET
+
+ UpdateCardBundle_SVR64:
+ mov byte ptr [rdi + rax], 0FFh
+#endif
+
ret
+
LEAF_END_MARKED JIT_WriteBarrier_SVR64, _TEXT
#endif
@@ -174,7 +249,13 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_PreGrow64_Patch_Label_Lower
CheckCardTable_WriteWatch_PreGrow64:
// Check the lower ephemeral region bound.
cmp rsi, r11
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ .byte 0x72, 0x40
+#else
.byte 0x72, 0x20
+#endif
+
// jb Exit_WriteWatch_PreGrow64
// Touch the card table entry, if not already dirty.
@@ -189,6 +270,23 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_PreGrow64_Patch_Label_CardTable
UpdateCardTable_WriteWatch_PreGrow64:
mov byte ptr [rdi + rax], 0FFh
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ NOP_2_BYTE // padding for alignment of constant
+PATCH_LABEL JIT_WriteBarrier_WriteWatch_PreGrow64_Patch_Label_CardBundleTable
+ movabs rax, 0xF0F0F0F0F0F0F0F0
+
+ shr rdi, 0x0A
+ cmp byte ptr [rdi + rax], 0FFh
+
+ .byte 0x75, 0x02
+ // jne UpdateCardBundle_WriteWatch_PreGrow64
+ REPRET
+
+ UpdateCardBundle_WriteWatch_PreGrow64:
+ mov byte ptr [rdi + rax], 0FFh
+#endif
+
ret
.balign 16
@@ -231,7 +329,12 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_PostGrow64_Patch_Label_Lower
// Check the lower and upper ephemeral region bounds
CheckCardTable_WriteWatch_PostGrow64:
cmp rsi, r11
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ .byte 0x72, 0x55
+#else
.byte 0x72, 0x3d
+#endif
// jb Exit_WriteWatch_PostGrow64
NOP_3_BYTE // padding for alignment of constant
@@ -240,7 +343,12 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_PostGrow64_Patch_Label_Upper
movabs r10, 0xF0F0F0F0F0F0F0F0
cmp rsi, r10
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ .byte 0x73, 0x43
+#else
.byte 0x73, 0x2b
+#endif
// jae Exit_WriteWatch_PostGrow64
nop // padding for alignment of constant
@@ -257,8 +365,24 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_PostGrow64_Patch_Label_CardTable
UpdateCardTable_WriteWatch_PostGrow64:
mov byte ptr [rdi + rax], 0FFh
- ret
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ NOP_2_BYTE // padding for alignment of constant
+ shr rdi, 0x0A
+
+PATCH_LABEL JIT_WriteBarrier_WriteWatch_PostGrow64_Patch_Label_CardBundleTable
+ movabs rax, 0xF0F0F0F0F0F0F0F0
+ cmp byte ptr [rdi + rax], 0FFh
+
+ .byte 0x75, 0x02
+ // jne UpdateCardBundle_WriteWatch_PostGrow64
+ REPRET
+
+ UpdateCardBundle_WriteWatch_PostGrow64:
+ mov byte ptr [rdi + rax], 0FFh
+#endif
+
+ ret
.balign 16
Exit_WriteWatch_PostGrow64:
REPRET
@@ -279,7 +403,7 @@ LEAF_ENTRY JIT_WriteBarrier_WriteWatch_SVR64, _TEXT
//
// SVR GC has multiple heaps, so it cannot provide one single
// ephemeral region to bounds check against, so we just skip the
- // bounds checking all together and do our card table update
+ // bounds checking altogether and do our card table update
// unconditionally.
//
@@ -312,7 +436,25 @@ PATCH_LABEL JIT_WriteBarrier_WriteWatch_SVR64_PatchLabel_CardTable
UpdateCardTable_WriteWatch_SVR64:
mov byte ptr [rdi + r11], 0FFh
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ NOP // padding for alignment of constant
+
+PATCH_LABEL JIT_WriteBarrier_WriteWatch_SVR64_PatchLabel_CardBundleTable
+ movabs r11, 0xF0F0F0F0F0F0F0F0
+
+ shr rdi, 0x0A
+ cmp byte ptr [rdi + r11], 0FFh
+ .byte 0x75, 0x02
+ // jne UpdateCardBundle_WriteWatch_SVR64
+ REPRET
+
+ UpdateCardBundle_WriteWatch_SVR64:
+ mov byte ptr [rdi + r11], 0FFh
+#endif
+
ret
+
LEAF_END_MARKED JIT_WriteBarrier_WriteWatch_SVR64, _TEXT
#endif
diff --git a/src/vm/amd64/jithelpers_slow.S b/src/vm/amd64/jithelpers_slow.S
index 0a5da69393..f61b42afc7 100644
--- a/src/vm/amd64/jithelpers_slow.S
+++ b/src/vm/amd64/jithelpers_slow.S
@@ -94,16 +94,36 @@ LEAF_ENTRY JIT_WriteBarrier_Debug, _TEXT
// Check if we need to update the card table
// Calc pCardByte
shr rdi, 0x0B
+
PREPARE_EXTERNAL_VAR g_card_table, r10
- add rdi, [r10]
+ mov r10, [r10]
// Check if this card is dirty
- cmp byte ptr [rdi], 0FFh
+ cmp byte ptr [rdi + r10], 0FFh
+
jne UpdateCardTable_Debug
REPRET
UpdateCardTable_Debug:
+ mov byte ptr [rdi + r10], 0FFh
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ // Shift rdi by 0x0A more to get the card bundle byte (we shifted by 0x0B already)
+ shr rdi, 0x0A
+
+ PREPARE_EXTERNAL_VAR g_card_bundle_table, r10
+ add rdi, [r10]
+
+ // Check if this bundle byte is dirty
+ cmp byte ptr [rdi], 0FFh
+
+ jne UpdateCardBundle_Debug
+ REPRET
+
+ UpdateCardBundle_Debug:
mov byte ptr [rdi], 0FFh
+#endif
+
ret
.balign 16
diff --git a/src/vm/amd64/jitinterfaceamd64.cpp b/src/vm/amd64/jitinterfaceamd64.cpp
index 53d8f74f1b..6a19e274e0 100644
--- a/src/vm/amd64/jitinterfaceamd64.cpp
+++ b/src/vm/amd64/jitinterfaceamd64.cpp
@@ -20,6 +20,7 @@
extern uint8_t* g_ephemeral_low;
extern uint8_t* g_ephemeral_high;
extern uint32_t* g_card_table;
+extern uint32_t* g_card_bundle_table;
// Patch Labels for the various write barriers
EXTERN_C void JIT_WriteBarrier_End();
@@ -27,17 +28,26 @@ EXTERN_C void JIT_WriteBarrier_End();
EXTERN_C void JIT_WriteBarrier_PreGrow64(Object **dst, Object *ref);
EXTERN_C void JIT_WriteBarrier_PreGrow64_Patch_Label_Lower();
EXTERN_C void JIT_WriteBarrier_PreGrow64_Patch_Label_CardTable();
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+EXTERN_C void JIT_WriteBarrier_PreGrow64_Patch_Label_CardBundleTable();
+#endif
EXTERN_C void JIT_WriteBarrier_PreGrow64_End();
EXTERN_C void JIT_WriteBarrier_PostGrow64(Object **dst, Object *ref);
EXTERN_C void JIT_WriteBarrier_PostGrow64_Patch_Label_Lower();
EXTERN_C void JIT_WriteBarrier_PostGrow64_Patch_Label_Upper();
EXTERN_C void JIT_WriteBarrier_PostGrow64_Patch_Label_CardTable();
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+EXTERN_C void JIT_WriteBarrier_PostGrow64_Patch_Label_CardBundleTable();
+#endif
EXTERN_C void JIT_WriteBarrier_PostGrow64_End();
#ifdef FEATURE_SVR_GC
EXTERN_C void JIT_WriteBarrier_SVR64(Object **dst, Object *ref);
EXTERN_C void JIT_WriteBarrier_SVR64_PatchLabel_CardTable();
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+EXTERN_C void JIT_WriteBarrier_SVR64_PatchLabel_CardBundleTable();
+#endif
EXTERN_C void JIT_WriteBarrier_SVR64_End();
#endif // FEATURE_SVR_GC
@@ -46,6 +56,9 @@ EXTERN_C void JIT_WriteBarrier_WriteWatch_PreGrow64(Object **dst, Object *ref);
EXTERN_C void JIT_WriteBarrier_WriteWatch_PreGrow64_Patch_Label_WriteWatchTable();
EXTERN_C void JIT_WriteBarrier_WriteWatch_PreGrow64_Patch_Label_Lower();
EXTERN_C void JIT_WriteBarrier_WriteWatch_PreGrow64_Patch_Label_CardTable();
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+EXTERN_C void JIT_WriteBarrier_WriteWatch_PreGrow64_Patch_Label_CardBundleTable();
+#endif
EXTERN_C void JIT_WriteBarrier_WriteWatch_PreGrow64_End();
EXTERN_C void JIT_WriteBarrier_WriteWatch_PostGrow64(Object **dst, Object *ref);
@@ -53,20 +66,26 @@ EXTERN_C void JIT_WriteBarrier_WriteWatch_PostGrow64_Patch_Label_WriteWatchTable
EXTERN_C void JIT_WriteBarrier_WriteWatch_PostGrow64_Patch_Label_Lower();
EXTERN_C void JIT_WriteBarrier_WriteWatch_PostGrow64_Patch_Label_Upper();
EXTERN_C void JIT_WriteBarrier_WriteWatch_PostGrow64_Patch_Label_CardTable();
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+EXTERN_C void JIT_WriteBarrier_WriteWatch_PostGrow64_Patch_Label_CardBundleTable();
+#endif
EXTERN_C void JIT_WriteBarrier_WriteWatch_PostGrow64_End();
#ifdef FEATURE_SVR_GC
EXTERN_C void JIT_WriteBarrier_WriteWatch_SVR64(Object **dst, Object *ref);
EXTERN_C void JIT_WriteBarrier_WriteWatch_SVR64_PatchLabel_WriteWatchTable();
EXTERN_C void JIT_WriteBarrier_WriteWatch_SVR64_PatchLabel_CardTable();
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+EXTERN_C void JIT_WriteBarrier_WriteWatch_SVR64_PatchLabel_CardBundleTable();
+#endif
EXTERN_C void JIT_WriteBarrier_WriteWatch_SVR64_End();
#endif // FEATURE_SVR_GC
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
WriteBarrierManager g_WriteBarrierManager;
-// Use this somewhat hokey macro to concantonate the function start with the patch
-// label, this allows the code below to look relatively nice, but relies on the
+// Use this somewhat hokey macro to concatenate the function start with the patch
+// label. This allows the code below to look relatively nice, but relies on the
// naming convention which we have established for these helpers.
#define CALC_PATCH_LOCATION(func,label,offset) CalculatePatchLocation((PVOID)func, (PVOID)func##_##label, offset)
@@ -76,8 +95,9 @@ WriteBarrierManager::WriteBarrierManager() :
LIMITED_METHOD_CONTRACT;
}
-#ifndef CODECOVERAGE // Deactivate alignment validation for code coverage builds
- // because the instrumentation tool will not preserve alignmant constraits and we will fail.
+#ifndef CODECOVERAGE // Deactivate alignment validation for code coverage builds
+ // because the instrumentation tool will not preserve alignment
+ // constraints and we will fail.
void WriteBarrierManager::Validate()
{
@@ -96,21 +116,41 @@ void WriteBarrierManager::Validate()
PBYTE pLowerBoundImmediate, pUpperBoundImmediate, pCardTableImmediate;
- pLowerBoundImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PreGrow64, Patch_Label_Lower, 2);
- pCardTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PreGrow64, Patch_Label_CardTable, 2);
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ PBYTE pCardBundleTableImmediate;
+#endif
+
+ pLowerBoundImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PreGrow64, Patch_Label_Lower, 2);
+ pCardTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PreGrow64, Patch_Label_CardTable, 2);
+
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pLowerBoundImmediate) & 0x7) == 0);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pCardTableImmediate) & 0x7) == 0);
- pLowerBoundImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PostGrow64, Patch_Label_Lower, 2);
- pUpperBoundImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PostGrow64, Patch_Label_Upper, 2);
- pCardTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PostGrow64, Patch_Label_CardTable, 2);
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ pCardBundleTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PreGrow64, Patch_Label_CardBundleTable, 2);
+ _ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pCardBundleTableImmediate) & 0x7) == 0);
+#endif
+
+ pLowerBoundImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PostGrow64, Patch_Label_Lower, 2);
+ pUpperBoundImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PostGrow64, Patch_Label_Upper, 2);
+ pCardTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PostGrow64, Patch_Label_CardTable, 2);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pLowerBoundImmediate) & 0x7) == 0);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pUpperBoundImmediate) & 0x7) == 0);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pCardTableImmediate) & 0x7) == 0);
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ pCardBundleTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PostGrow64, Patch_Label_CardBundleTable, 2);
+ _ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pCardBundleTableImmediate) & 0x7) == 0);
+#endif
+
#ifdef FEATURE_SVR_GC
- pCardTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_SVR64, PatchLabel_CardTable, 2);
+ pCardTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_SVR64, PatchLabel_CardTable, 2);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pCardTableImmediate) & 0x7) == 0);
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ pCardBundleTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_SVR64, PatchLabel_CardBundleTable, 2);
+ _ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pCardBundleTableImmediate) & 0x7) == 0);
+#endif // FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
#endif // FEATURE_SVR_GC
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
@@ -119,24 +159,41 @@ void WriteBarrierManager::Validate()
pWriteWatchTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_WriteWatch_PreGrow64, Patch_Label_WriteWatchTable, 2);
pLowerBoundImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_WriteWatch_PreGrow64, Patch_Label_Lower, 2);
pCardTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_WriteWatch_PreGrow64, Patch_Label_CardTable, 2);
+
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pWriteWatchTableImmediate) & 0x7) == 0);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pLowerBoundImmediate) & 0x7) == 0);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pCardTableImmediate) & 0x7) == 0);
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ pCardBundleTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_WriteWatch_PreGrow64, Patch_Label_CardBundleTable, 2);
+ _ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pCardBundleTableImmediate) & 0x7) == 0);
+#endif
+
pWriteWatchTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_WriteWatch_PostGrow64, Patch_Label_WriteWatchTable, 2);
pLowerBoundImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_WriteWatch_PostGrow64, Patch_Label_Lower, 2);
pUpperBoundImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_WriteWatch_PostGrow64, Patch_Label_Upper, 2);
pCardTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_WriteWatch_PostGrow64, Patch_Label_CardTable, 2);
+
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pWriteWatchTableImmediate) & 0x7) == 0);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pLowerBoundImmediate) & 0x7) == 0);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pUpperBoundImmediate) & 0x7) == 0);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pCardTableImmediate) & 0x7) == 0);
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ pCardBundleTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_WriteWatch_PostGrow64, Patch_Label_CardBundleTable, 2);
+ _ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pCardBundleTableImmediate) & 0x7) == 0);
+#endif
+
#ifdef FEATURE_SVR_GC
pWriteWatchTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_WriteWatch_SVR64, PatchLabel_WriteWatchTable, 2);
pCardTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_WriteWatch_SVR64, PatchLabel_CardTable, 2);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pWriteWatchTableImmediate) & 0x7) == 0);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pCardTableImmediate) & 0x7) == 0);
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ pCardBundleTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_WriteWatch_SVR64, PatchLabel_CardBundleTable, 2);
+ _ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", (reinterpret_cast<UINT64>(pCardBundleTableImmediate) & 0x7) == 0);
+#endif // FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
#endif // FEATURE_SVR_GC
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
}
@@ -242,36 +299,51 @@ void WriteBarrierManager::ChangeWriteBarrierTo(WriteBarrierType newWriteBarrier,
{
case WRITE_BARRIER_PREGROW64:
{
- m_pLowerBoundImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PreGrow64, Patch_Label_Lower, 2);
- m_pCardTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PreGrow64, Patch_Label_CardTable, 2);
+ m_pLowerBoundImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PreGrow64, Patch_Label_Lower, 2);
+ m_pCardTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PreGrow64, Patch_Label_CardTable, 2);
// Make sure that we will be bashing the right places (immediates should be hardcoded to 0x0f0f0f0f0f0f0f0f0).
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pLowerBoundImmediate);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pCardTableImmediate);
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ m_pCardBundleTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PreGrow64, Patch_Label_CardBundleTable, 2);
+ _ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pCardBundleTableImmediate);
+#endif
break;
}
case WRITE_BARRIER_POSTGROW64:
{
- m_pLowerBoundImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PostGrow64, Patch_Label_Lower, 2);
- m_pUpperBoundImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PostGrow64, Patch_Label_Upper, 2);
- m_pCardTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PostGrow64, Patch_Label_CardTable, 2);
+ m_pLowerBoundImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PostGrow64, Patch_Label_Lower, 2);
+ m_pUpperBoundImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PostGrow64, Patch_Label_Upper, 2);
+ m_pCardTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PostGrow64, Patch_Label_CardTable, 2);
// Make sure that we will be bashing the right places (immediates should be hardcoded to 0x0f0f0f0f0f0f0f0f0).
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pLowerBoundImmediate);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pCardTableImmediate);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pUpperBoundImmediate);
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ m_pCardBundleTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_PostGrow64, Patch_Label_CardBundleTable, 2);
+ _ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pCardBundleTableImmediate);
+#endif
break;
}
#ifdef FEATURE_SVR_GC
case WRITE_BARRIER_SVR64:
{
- m_pCardTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_SVR64, PatchLabel_CardTable, 2);
+ m_pCardTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_SVR64, PatchLabel_CardTable, 2);
// Make sure that we will be bashing the right places (immediates should be hardcoded to 0x0f0f0f0f0f0f0f0f0).
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pCardTableImmediate);
- break;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ m_pCardBundleTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_SVR64, PatchLabel_CardBundleTable, 2);
+ _ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pCardBundleTableImmediate);
+#endif
+ break;
}
#endif // FEATURE_SVR_GC
@@ -286,6 +358,11 @@ void WriteBarrierManager::ChangeWriteBarrierTo(WriteBarrierType newWriteBarrier,
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pWriteWatchTableImmediate);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pLowerBoundImmediate);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pCardTableImmediate);
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ m_pCardBundleTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_WriteWatch_PreGrow64, Patch_Label_CardBundleTable, 2);
+ _ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pCardBundleTableImmediate);
+#endif
break;
}
@@ -301,6 +378,11 @@ void WriteBarrierManager::ChangeWriteBarrierTo(WriteBarrierType newWriteBarrier,
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pLowerBoundImmediate);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pCardTableImmediate);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pUpperBoundImmediate);
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ m_pCardBundleTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_WriteWatch_PostGrow64, Patch_Label_CardBundleTable, 2);
+ _ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pCardBundleTableImmediate);
+#endif
break;
}
@@ -313,6 +395,11 @@ void WriteBarrierManager::ChangeWriteBarrierTo(WriteBarrierType newWriteBarrier,
// Make sure that we will be bashing the right places (immediates should be hardcoded to 0x0f0f0f0f0f0f0f0f0).
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pWriteWatchTableImmediate);
_ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pCardTableImmediate);
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ m_pCardBundleTableImmediate = CALC_PATCH_LOCATION(JIT_WriteBarrier_WriteWatch_SVR64, PatchLabel_CardBundleTable, 2);
+ _ASSERTE_ALL_BUILDS("clr/src/VM/AMD64/JITinterfaceAMD64.cpp", 0xf0f0f0f0f0f0f0f0 == *(UINT64*)m_pCardBundleTableImmediate);
+#endif
break;
}
#endif // FEATURE_SVR_GC
@@ -504,15 +591,14 @@ void WriteBarrierManager::UpdateEphemeralBounds(bool isRuntimeSuspended)
void WriteBarrierManager::UpdateWriteWatchAndCardTableLocations(bool isRuntimeSuspended, bool bReqUpperBoundsCheck)
{
- // If we are told that we require an upper bounds check (GC did some heap
- // reshuffling), we need to switch to the WriteBarrier_PostGrow function for
- // good.
+ // If we are told that we require an upper bounds check (GC did some heap reshuffling),
+ // we need to switch to the WriteBarrier_PostGrow function for good.
WriteBarrierType newType;
if (NeedDifferentWriteBarrier(bReqUpperBoundsCheck, &newType))
{
ChangeWriteBarrierTo(newType, isRuntimeSuspended);
- return;
+ return;
}
#ifdef _DEBUG
@@ -549,6 +635,14 @@ void WriteBarrierManager::UpdateWriteWatchAndCardTableLocations(bool isRuntimeSu
fFlushCache = true;
}
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ if (*(UINT64*)m_pCardBundleTableImmediate != (size_t)g_card_bundle_table)
+ {
+ *(UINT64*)m_pCardBundleTableImmediate = (size_t)g_card_bundle_table;
+ fFlushCache = true;
+ }
+#endif
+
if (fFlushCache)
{
FlushInstructionCache(GetCurrentProcess(), (LPVOID)JIT_WriteBarrier, GetCurrentWriteBarrierSize());
diff --git a/src/vm/amd64/remotingamd64.cpp b/src/vm/amd64/remotingamd64.cpp
deleted file mode 100644
index 587afae124..0000000000
--- a/src/vm/amd64/remotingamd64.cpp
+++ /dev/null
@@ -1,672 +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.
-/*===========================================================================
-**
-** File: RemotingCpu.cpp
-**
-**
-**
-** Purpose: Defines various remoting related functions for the AMD64 architecture
-**
-**
-** See code:EEStartup#TableOfContents for EE overview
-**
-=============================================================================*/
-
-#include "common.h"
-
-#ifdef FEATURE_REMOTING
-
-#include "excep.h"
-#include "comdelegate.h"
-#include "remoting.h"
-#include "field.h"
-#include "siginfo.hpp"
-#include "stackbuildersink.h"
-#include "threads.h"
-#include "method.hpp"
-
-#include "asmconstants.h"
-
-// External variables
-extern DWORD g_dwNonVirtualThunkRemotingLabelOffset;
-extern DWORD g_dwNonVirtualThunkReCheckLabelOffset;
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::CheckForContextMatch public
-//
-// Synopsis: This code generates a check to see if the current context and
-// the context of the proxy match.
-//
-//+----------------------------------------------------------------------------
-//
-// returns zero if contexts match
-// returns non-zero if contexts don't match
-//
-extern "C" UINT_PTR __stdcall CRemotingServices__CheckForContextMatch(Object* pStubData)
-{
- // This method cannot have a contract because CreateStubForNonVirtualMethod assumes
- // it won't trash XMM registers. The code generated for contracts by recent compilers
- // is trashing XMM registers.
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_NOTRIGGER;
- STATIC_CONTRACT_MODE_COOPERATIVE; // due to the Object parameter
- STATIC_CONTRACT_SO_TOLERANT;
-
- UINT_PTR contextID = *(UINT_PTR*)pStubData->UnBox();
- UINT_PTR contextCur = (UINT_PTR)GetThread()->m_Context;
- return (contextCur != contextID); // chosen to match x86 convention
-}
-
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::CreateThunkForVirtualMethod private
-//
-// Synopsis: Creates the thunk that pushes the supplied slot number and jumps
-// to TP Stub
-//
-//+----------------------------------------------------------------------------
-PCODE CTPMethodTable::CreateThunkForVirtualMethod(DWORD dwSlot, BYTE* pbCode)
-{
- LIMITED_METHOD_CONTRACT;
-
- BYTE *pbCodeStart = pbCode;
-
- // NOTE: if you change the code generated here, update
- // CVirtualThunkMgr::IsThunkByASM, CVirtualThunkMgr::GetMethodDescByASM
-
- //
- // mov r10, <dwSlot>
- // mov rax, TransparentProxyStub
- // jmp rax
- //
- *pbCode++ = 0x49;
- *pbCode++ = 0xc7;
- *pbCode++ = 0xc2;
- *((DWORD*)pbCode) = dwSlot;
- pbCode += sizeof(DWORD);
- *pbCode++ = 0x48;
- *pbCode++ = 0xB8;
- *((UINT64*)pbCode) = (UINT64)(TransparentProxyStub);
- pbCode += sizeof(UINT64);
- *pbCode++ = 0xFF;
- *pbCode++ = 0xE0;
-
- _ASSERTE(pbCode - pbCodeStart == ConstVirtualThunkSize);
- _ASSERTE(CVirtualThunkMgr::IsThunkByASM((PCODE)pbCodeStart));
-
- return (PCODE)pbCodeStart;
-}
-
-
-#ifdef HAS_REMOTING_PRECODE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::ActivatePrecodeRemotingThunk private
-//
-// Synopsis: Patch the precode remoting thunk to begin interception
-//
-//+----------------------------------------------------------------------------
-void CTPMethodTable::ActivatePrecodeRemotingThunk()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- PORTABILITY_WARNING("CTPMethodTable::ActivatePrecodeRemotingThunk");
-}
-
-#else // HAS_REMOTING_PRECODE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::CreateStubForNonVirtualMethod public
-//
-// Synopsis: Create a stub for a non virtual method
-//
-//+----------------------------------------------------------------------------
-Stub* CTPMethodTable::CreateStubForNonVirtualMethod(MethodDesc* pMD, CPUSTUBLINKER* psl,
- LPVOID pvAddrOfCode, Stub* pInnerStub)
-{
- STANDARD_VM_CONTRACT;
-
- // Sanity check
-
- Stub *pStub = NULL;
-
- // we need a hash table only for virtual methods
- _ASSERTE(!pMD->IsVirtual());
-
- // Ensure the TP MethodTable's fields have been initialized.
- EnsureFieldsInitialized();
-
- /*
- NonVirtualMethodStub<thisReg, pvAddrOfCode, pTPMethodTable, pvTPStub>
- {
- ;; thisReg: this
-
- sub rsp, 0x28
-
- test thisReg, thisReg
- je JmpAddrLabel
-
- mov rax, [thisReg]
- mov r10, <pTPMethodTable>
- cmp rax, r10
- jne JmpAddrLabel
-
- mov [rsp+0x30], rcx ;|
- mov [rsp+0x38], rdx ;|
- mov [rsp+0x40], r8 ;|
- mov [rsp+0x48], r9 ;|
- ;|
- mov rax, [thisReg + TransparentProxyObject___stubData] ;|
- call [thisReg + TransparentProxyObject___stub] ;| EmitCallToStub<pCtxMismatch>
- ;|
- mov rcx, [rsp+0x30] ;|
- mov rdx, [rsp+0x38] ;|
- mov r8, [rsp+0x40] ;|
- mov r9, [rsp+0x48] ;|
- ;|
- test rax, rax ;|
- jnz RemotingLabel ;|
-
- JmpAddrLabel:
- mov rax, <pvAddrOfCode>
- add rsp, 0x28
- jmp rax
-
- RemotingLabel:
- mov r10, <pMD>
- mov rax, <pvTPStub>
- add rsp, 0x20
- jmp rax
- }
- */
-
- X86Reg thisReg = kRCX;
- void* pvTPStub = TransparentProxyStub_CrossContext;
-
- // Generate label where a null reference exception will be thrown
- CodeLabel *pJmpAddrLabel = psl->NewCodeLabel();
- // Generate label where remoting code will execute
- CodeLabel *pRemotingLabel = psl->NewCodeLabel();
-
- // NOTE: if you change any of this code, you must update
- // CNonVirtualThunkMgr::IsThunkByASM.
-
- // Allocate callee scratch area
- // sub rsp, 0x28
- psl->X86EmitSubEsp(0x28);
-
- // test thisReg, thisReg
- psl->X86EmitR2ROp(0x85, thisReg, thisReg);
- // je JmpAddrLabel
- psl->X86EmitCondJump(pJmpAddrLabel, X86CondCode::kJE);
-
- // Emit a label here for the debugger. A breakpoint will
- // be set at the next instruction and the debugger will
- // call CNonVirtualThunkMgr::TraceManager when the
- // breakpoint is hit with the thread's context.
- CodeLabel *pRecheckLabel = psl->NewCodeLabel();
- psl->EmitLabel(pRecheckLabel);
-
- // mov rax, [thisReg]
- psl->X86EmitIndexRegLoad(kRAX, thisReg, 0);
-
- // mov r10, CTPMethodTable::GetMethodTable()
- psl->X86EmitRegLoad(kR10, (UINT_PTR)CTPMethodTable::GetMethodTable());
- // cmp rax, r10
- psl->X86EmitR2ROp(0x3B, kRAX, kR10);
-
- // jne JmpAddrLabel
- psl->X86EmitCondJump(pJmpAddrLabel, X86CondCode::kJNE);
-
- // CONSIDER: write all possible stubs in asm to ensure param registers are not trashed
-
- // mov [rsp+0x30], rcx
- // mov [rsp+0x38], rdx
- // mov [rsp+0x40], r8
- // mov [rsp+0x48], r9
- psl->X86EmitRegSave(kRCX, 0x30);
- psl->X86EmitRegSave(kRDX, 0x38);
- psl->X86EmitRegSave(kR8, 0x40);
- psl->X86EmitRegSave(kR9, 0x48);
-
- // mov rax, [thisReg + TransparentProxyObject___stub]
- psl->X86EmitIndexRegLoad(kRAX, thisReg, TransparentProxyObject___stub);
-
- // mov rcx, [thisReg + TransparentProxyObject___stubData]
- psl->X86EmitIndexRegLoad(kRCX, thisReg, TransparentProxyObject___stubData);
-
- // call rax
- psl->Emit16(0xd0ff);
-
- // mov rcx, [rsp+0x30]
- // mov rdx, [rsp+0x38]
- // mov r8, [rsp+0x40]
- // mov r9, [rsp+0x48]
- psl->X86EmitEspOffset(0x8b, kRCX, 0x30);
- psl->X86EmitEspOffset(0x8b, kRDX, 0x38);
- psl->X86EmitEspOffset(0x8b, kR8, 0x40);
- psl->X86EmitEspOffset(0x8b, kR9, 0x48);
-
- // test rax, rax
- psl->X86EmitR2ROp(0x85, kRAX, kRAX);
- // jnz RemotingLabel
- psl->X86EmitCondJump(pRemotingLabel, X86CondCode::kJNZ);
-
-// pJmpAddrLabel:
- psl->EmitLabel(pJmpAddrLabel);
-
- // Make sure that the actual code does not require MethodDesc in r10
- _ASSERTE(!pMD->RequiresMethodDescCallingConvention());
-
- // mov rax, <pvAddrOfCode>
- // add rsp, 0x28
- // REX.W jmp rax
- psl->X86EmitTailcallWithESPAdjust(psl->NewExternalCodeLabel(pvAddrOfCode), 0x28);
-
-// pRemotingLabel:
- psl->EmitLabel(pRemotingLabel);
-
- // mov r10, <pMD>
- psl->X86EmitRegLoad(kR10, (UINT_PTR)pMD);
-
- // mov rax, <pvTPStub>
- // add rsp, 0x28
- // REX.W jmp rax
- psl->X86EmitTailcallWithESPAdjust(psl->NewExternalCodeLabel(pvTPStub), 0x28);
-
- // Link and produce the stub
- pStub = psl->LinkInterceptor(pMD->GetLoaderAllocator()->GetStubHeap(),
- pInnerStub, pvAddrOfCode);
-
- return pStub;
-}
-
-
-//+----------------------------------------------------------------------------
-//
-// Synopsis: Find an existing thunk or create a new one for the given
-// method descriptor. NOTE: This is used for the methods that do
-// not go through the vtable such as constructors, private and
-// final methods.
-//
-//+----------------------------------------------------------------------------
-PCODE CTPMethodTable::CreateNonVirtualThunkForVirtualMethod(MethodDesc* pMD)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pMD));
- }
- CONTRACTL_END;
-
- CPUSTUBLINKER sl;
- CPUSTUBLINKER* psl = &sl;
-
- Stub *pStub = NULL;
-
- // The thunk has not been created yet. Go ahead and create it.
- // Compute the address of the slot
- LPVOID pvEntryPoint = (LPVOID)pMD->GetMethodEntryPoint();
-
- X86Reg thisReg = kRCX;
- void* pvStub = CRemotingServices__DispatchInterfaceCall;
-
- // Generate label where a null reference exception will be thrown
- CodeLabel *pExceptionLabel = psl->NewCodeLabel();
-
- // !!! WARNING WARNING WARNING WARNING WARNING !!!
- //
- // DO NOT CHANGE this code without changing the thunk recognition
- // code in CNonVirtualThunkMgr::IsThunkByASM
- // & CNonVirtualThunkMgr::GetMethodDescByASM
- //
- // !!! WARNING WARNING WARNING WARNING WARNING !!!
-
- // NOTE: constant mov's should use an extended register to force a REX
- // prefix and the full 64-bit immediate value, so that
- // g_dwNonVirtualThunkRemotingLabelOffset and
- // g_dwNonVirtualThunkReCheckLabelOffset are the same for all
- // generated code.
-
- // if this == NULL throw NullReferenceException
- // test rcx, rcx
- psl->X86EmitR2ROp(0x85, thisReg, thisReg);
-
- // je ExceptionLabel
- psl->X86EmitCondJump(pExceptionLabel, X86CondCode::kJE);
-
- // Generate label where remoting code will execute
- CodeLabel *pRemotingLabel = psl->NewCodeLabel();
-
- // Emit a label here for the debugger. A breakpoint will
- // be set at the next instruction and the debugger will
- // call CNonVirtualThunkMgr::TraceManager when the
- // breakpoint is hit with the thread's context.
- CodeLabel *pRecheckLabel = psl->NewCodeLabel();
- psl->EmitLabel(pRecheckLabel);
-
- // If this.MethodTable == TPMethodTable then do RemotingCall
- // mov rax, [thisReg]
- psl->X86EmitIndexRegLoad(kRAX, thisReg, 0);
- // mov r10, CTPMethodTable::GetMethodTable()
- psl->X86EmitRegLoad(kR10, (UINT_PTR)CTPMethodTable::GetMethodTable());
- // cmp rax, r10
- psl->X86EmitR2ROp(0x3B, kRAX, kR10);
- // je RemotingLabel
- psl->X86EmitCondJump(pRemotingLabel, X86CondCode::kJE);
-
- // Exception handling and non-remoting share the
- // same codepath
- psl->EmitLabel(pExceptionLabel);
-
- // Non-RemotingCode
- // Jump to the vtable slot of the method
- // mov rax, pvEntryPoint
- // Encoded the mov manually so that it always uses the 64-bit form.
- //psl->X86EmitRegLoad(kRAX, (UINT_PTR)pvEntryPoint);
- psl->Emit8(REX_PREFIX_BASE | REX_OPERAND_SIZE_64BIT);
- psl->Emit8(0xb8);
- psl->EmitBytes((BYTE*)&pvEntryPoint, 8);
- // jmp rax
- psl->Emit8(0xff);
- psl->Emit8(0xe0);
-
- // Remoting code. Note: CNonVirtualThunkMgr::TraceManager
- // relies on this label being right after the jmp pvEntryPoint
- // instruction above. If you move this label, update
- // CNonVirtualThunkMgr::DoTraceStub.
- psl->EmitLabel(pRemotingLabel);
-
- // Save the MethodDesc and goto TPStub
- // push MethodDesc
- psl->X86EmitRegLoad(kR10, (UINT_PTR)pMD);
-
- // jmp TPStub
- psl->X86EmitNearJump(psl->NewExternalCodeLabel(pvStub));
-
- // Link and produce the stub
- // FUTURE: Do we have to provide the loader heap ?
- pStub = psl->Link(SystemDomain::GetGlobalLoaderAllocator()->GetExecutableHeap());
-
- // Grab the offset of the RemotingLabel and RecheckLabel
- // for use in CNonVirtualThunkMgr::DoTraceStub and
- // TraceManager.
- DWORD dwOffset;
-
- dwOffset = psl->GetLabelOffset(pRemotingLabel);
- ASSERT(!g_dwNonVirtualThunkRemotingLabelOffset || g_dwNonVirtualThunkRemotingLabelOffset == dwOffset);
- g_dwNonVirtualThunkRemotingLabelOffset = dwOffset;
-
- dwOffset = psl->GetLabelOffset(pRecheckLabel);
- ASSERT(!g_dwNonVirtualThunkReCheckLabelOffset || g_dwNonVirtualThunkReCheckLabelOffset == dwOffset);
- g_dwNonVirtualThunkReCheckLabelOffset = dwOffset;
-
- return (pStub->GetEntryPoint());
-}
-
-#endif // HAS_REMOTING_PRECODE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CVirtualThunkMgr::DoTraceStub public
-//
-// Synopsis: Traces the stub given the starting address
-//
-//+----------------------------------------------------------------------------
-BOOL CVirtualThunkMgr::DoTraceStub(PCODE stubStartAddress, TraceDestination *trace)
-{
- LIMITED_METHOD_CONTRACT;
-
- // <TODO> implement this </TODO>
- return FALSE;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CVirtualThunkMgr::IsThunkByASM public
-//
-// Synopsis: Check assembly to see if this one of our thunks
-//
-//+----------------------------------------------------------------------------
-BOOL CVirtualThunkMgr::IsThunkByASM(PCODE startaddr)
-{
- LIMITED_METHOD_CONTRACT;
-
- PTR_BYTE pbCode = PTR_BYTE(startaddr);
-
- // NOTE: this depends on the code generated by
- // CTPMethodTable::CreateThunkForVirtualMethod.
-
- // mov r10, <dwSlot>
- return 0x49 == pbCode[0]
- && 0xc7 == pbCode[1]
- && 0xc2 == pbCode[2]
- // mov rax, TransparentProxyStub
- && 0x48 == pbCode[7]
- && 0xb8 == pbCode[8]
- && (TADDR)TransparentProxyStub == *PTR_TADDR(pbCode+9)
- // jmp rax
- && 0xff == pbCode[17]
- && 0xe0 == pbCode[18];
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CVirtualThunkMgr::GetMethodDescByASM public
-//
-// Synopsis: Parses MethodDesc out of assembly code
-//
-//+----------------------------------------------------------------------------
-MethodDesc *CVirtualThunkMgr::GetMethodDescByASM(PCODE pbThunkCode, MethodTable *pMT)
-{
- LIMITED_METHOD_CONTRACT;
-
- // NOTE: this depends on the code generated by
- // CTPMethodTable::CreateThunkForVirtualMethod.
-
- return pMT->GetMethodDescForSlot(*((DWORD *) (pbThunkCode + 3)));
-}
-
-
-#ifndef HAS_REMOTING_PRECODE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CNonVirtualThunkMgr::TraceManager public
-//
-// Synopsis: Traces the stub given the current context
-//
-//+----------------------------------------------------------------------------
-BOOL CNonVirtualThunkMgr::TraceManager(Thread* thread,
- TraceDestination* trace,
- CONTEXT* pContext,
- BYTE** pRetAddr)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(thread, NULL_OK));
- PRECONDITION(CheckPointer(trace));
- PRECONDITION(CheckPointer(pContext));
- PRECONDITION(CheckPointer(pRetAddr));
- }
- CONTRACTL_END;
-
- BOOL bRet = FALSE;
-
- MethodDesc * pMD = GetMethodDescByASM(GetIP(pContext) - g_dwNonVirtualThunkReCheckLabelOffset);
-
- LPBYTE pThis = (LPBYTE)pContext->Rcx;
-
- if ((pThis != NULL) &&
- (*(LPBYTE*)(SIZE_T)pThis == (LPBYTE)(SIZE_T)CTPMethodTable::GetMethodTable()))
- {
- // <TODO>We know that we've got a proxy
- // in the way. If the proxy is to a remote call, with no
- // managed code in between, then the debugger doesn't care and
- // we should just be able to return FALSE.
- //
- // </TODO>
- bRet = FALSE;
- }
- else
- {
- // No proxy in the way, so figure out where we're really going
- // to and let the stub manager try to pickup the trace from
- // there.
- LPBYTE stubStartAddress = (LPBYTE)GetIP(pContext) -
- g_dwNonVirtualThunkReCheckLabelOffset;
-
- // Extract the address of the destination
- BYTE* pbAddr = (BYTE *)(SIZE_T)(stubStartAddress +
- g_dwNonVirtualThunkRemotingLabelOffset - 2 - sizeof(void *));
-
- SIZE_T destAddress = *(SIZE_T *)pbAddr;
-
- // Ask the stub manager to trace the destination address
- bRet = StubManager::TraceStub((PCODE)(BYTE *)(size_t)destAddress, trace);
- }
-
- // While we may have made it this far, further tracing may reveal
- // that the debugger can't continue on. Therefore, since there is
- // no frame currently pushed, we need to tell the debugger where
- // we're returning to just in case it hits such a situtation. We
- // know that the return address is on the top of the thread's
- // stack.
- (*pRetAddr) = *((BYTE**)(size_t)(GetSP(pContext)));
-
- return bRet;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CNonVirtualThunkMgr::DoTraceStub public
-//
-// Synopsis: Traces the stub given the starting address
-//
-//+----------------------------------------------------------------------------
-BOOL CNonVirtualThunkMgr::DoTraceStub(PCODE stubStartAddress,
- TraceDestination* trace)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(stubStartAddress != NULL);
- PRECONDITION(CheckPointer(trace));
- }
- CONTRACTL_END;
-
- BOOL bRet = FALSE;
-
- if (!IsThunkByASM(stubStartAddress))
- return FALSE;
-
- CNonVirtualThunk* pThunk = FindThunk((const BYTE *)stubStartAddress);
-
- if(NULL != pThunk)
- {
- // We can either jump to
- // (1) a slot in the transparent proxy table (UNMANAGED)
- // (2) a slot in the non virtual part of the vtable
- // ... so, we need to return TRACE_MGR_PUSH with the address
- // at which we want to be called back with the thread's context
- // so we can figure out which way we're gonna go.
- if((const BYTE *)stubStartAddress == pThunk->GetThunkCode())
- {
- trace->InitForManagerPush(
- (PCODE) (stubStartAddress + g_dwNonVirtualThunkReCheckLabelOffset),
- this);
- bRet = TRUE;
- }
- }
-
- return bRet;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CNonVirtualThunkMgr::IsThunkByASM public
-//
-// Synopsis: Check assembly to see if this one of our thunks
-//
-//+----------------------------------------------------------------------------
-BOOL CNonVirtualThunkMgr::IsThunkByASM(PCODE startaddr)
-{
- LIMITED_METHOD_CONTRACT;
-
- PTR_BYTE pbCode = PTR_BYTE(startaddr);
-
- // test rcx, rcx ; 3 bytes
- return 0x48 == pbCode[0]
- && 0x85 == pbCode[1]
- && 0xc9 == pbCode[2]
- // je ... ; 2 bytes
- && 0x74 == pbCode[3]
- // mov rax, [rcx] ; 3 bytes
- // mov r10, CTPMethodTable::GetMethodTable() ; 2 bytes + MethodTable*
- && (TADDR)CTPMethodTable::GetMethodTable() == *PTR_TADDR(pbCode + 10);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CNonVirtualThunkMgr::GetMethodDescByASM public
-//
-// Synopsis: Parses MethodDesc out of assembly code
-//
-//+----------------------------------------------------------------------------
-MethodDesc* CNonVirtualThunkMgr::GetMethodDescByASM(PCODE pbThunkCode)
-{
- LIMITED_METHOD_CONTRACT;
-
- return *((MethodDesc **) (pbThunkCode + g_dwNonVirtualThunkRemotingLabelOffset + 2));
-}
-
-#endif // HAS_REMOTING_PRECODE
-
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::GenericCheckForContextMatch private
-//
-// Synopsis: Calls the stub in the TP & returns TRUE if the contexts
-// match, FALSE otherwise.
-//
-// Note: 1. Called during FieldSet/Get, used for proxy extensibility
-//
-//+----------------------------------------------------------------------------
-BOOL __stdcall CTPMethodTable__GenericCheckForContextMatch(Object* orTP)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE; // due to the Object parameter
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- Object *StubData = OBJECTREFToObject(((TransparentProxyObject*)orTP)->GetStubData());
- CTPMethodTable::CheckContextCrossingProc *pfnCheckContextCrossing =
- (CTPMethodTable::CheckContextCrossingProc*)(((TransparentProxyObject*)orTP)->GetStub());
- return pfnCheckContextCrossing(StubData) == 0;
-}
-
-#endif // FEATURE_REMOTING
-
-
diff --git a/src/vm/amd64/unixstubs.cpp b/src/vm/amd64/unixstubs.cpp
index e7f49577e4..2904149084 100644
--- a/src/vm/amd64/unixstubs.cpp
+++ b/src/vm/amd64/unixstubs.cpp
@@ -11,21 +11,6 @@ extern "C"
PORTABILITY_ASSERT("Implement for PAL");
}
- void NakedThrowHelper()
- {
- PORTABILITY_ASSERT("Implement for PAL");
- }
-
- void PInvokeStubForHost()
- {
- PORTABILITY_ASSERT("Implement for PAL");
- }
-
- void PInvokeStubForHostInner(DWORD dwStackSize, LPVOID pStackFrame, LPVOID pTarget)
- {
- PORTABILITY_ASSERT("Implement for PAL");
- }
-
void ProfileEnterNaked(FunctionIDOrClientID functionIDOrClientID)
{
PORTABILITY_ASSERT("Implement for PAL");
diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp
index 040837a8a7..5bfb12fc6b 100644
--- a/src/vm/appdomain.cpp
+++ b/src/vm/appdomain.cpp
@@ -14,12 +14,6 @@
#include "eeconfig.h"
#include "gcheaputilities.h"
#include "eventtrace.h"
-#ifdef FEATURE_FUSION
-#include "assemblysink.h"
-#include "fusion.h"
-#include "fusionbind.h"
-#include "fusionlogging.h"
-#endif
#include "perfcounters.h"
#include "assemblyname.hpp"
#include "eeprofinterfaces.h"
@@ -29,9 +23,6 @@
#endif
#include "comdynamic.h"
#include "mlinfo.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "posterror.h"
#include "assemblynative.hpp"
#include "shimload.h"
@@ -42,10 +33,6 @@
#include "eventtrace.h"
#include "comdelegate.h"
#include "siginfo.hpp"
-#ifdef FEATURE_REMOTING
-#include "appdomainhelper.h"
-#include "objectclone.h"
-#endif
#include "typekey.h"
#include "caparser.h"
@@ -75,11 +62,6 @@
#include "appdomain.inl"
#include "typeparse.h"
#include "mdaassistants.h"
-#ifdef FEATURE_REMOTING
-#include "mscorcfg.h"
-#include "appdomainconfigfactory.hpp"
-#include "crossdomaincalls.h"
-#endif
#include "threadpoolrequest.h"
#include "nativeoverlapped.h"
@@ -92,20 +74,11 @@
#include "stringarraylist.h"
-#ifdef FEATURE_VERSIONING
#include "../binder/inc/clrprivbindercoreclr.h"
-#endif
-#if defined(FEATURE_APPX_BINDER)
-#include "appxutil.h"
-#include "clrprivbinderappx.h"
-#endif
#include "clrprivtypecachewinrt.h"
-#ifndef FEATURE_CORECLR
-#include "nlsinfo.h"
-#endif
#ifdef FEATURE_RANDOMIZED_STRING_HASHING
#pragma warning(push)
@@ -739,10 +712,8 @@ OBJECTHANDLE ThreadStaticHandleTable::AllocateHandles(DWORD nRequested)
void BaseDomain::Attach()
{
#ifdef FEATURE_RANDOMIZED_STRING_HASHING
-#ifdef FEATURE_CORECLR
// Randomized string hashing is on by default for String.GetHashCode in coreclr.
COMNlsHashProvider::s_NlsHashProvider.SetUseRandomHashing((CorHost2::GetStartupFlags() & STARTUP_DISABLE_RANDOMIZED_STRING_HASHING) == 0);
-#endif // FEATURE_CORECLR
#endif // FEATURE_RANDOMIZED_STRING_HASHING
m_SpecialStaticsCrst.Init(CrstSpecialStatics);
}
@@ -763,18 +734,16 @@ BaseDomain::BaseDomain()
m_fDisableInterfaceCache = FALSE;
m_pFusionContext = NULL;
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
m_pTPABinderContext = NULL;
-#endif
// Make sure the container is set to NULL so that it gets loaded when it is used.
m_pLargeHeapHandleTable = NULL;
#ifndef CROSSGEN_COMPILE
- // Note that m_hHandleTableBucket is overridden by app domains
- m_hHandleTableBucket = g_HandleTableMap.pBuckets[0];
+ // Note that m_handleStore is overridden by app domains
+ m_handleStore = GCHandleTableUtilities::GetGCHandleTable()->GetGlobalHandleStore();
#else
- m_hHandleTableBucket = NULL;
+ m_handleStore = NULL;
#endif
m_pMarshalingData = NULL;
@@ -861,9 +830,6 @@ void BaseDomain::Init()
// Allocate the managed standard interfaces information.
m_pMngStdInterfacesInfo = new MngStdInterfacesInfo();
-#if defined(FEATURE_APPX_BINDER)
- if (!AppX::IsAppXProcess())
-#endif
{
CLRPrivBinderWinRT::NamespaceResolutionKind fNamespaceResolutionKind = CLRPrivBinderWinRT::NamespaceResolutionKind_WindowsAPI;
if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DesignerNamespaceResolutionEnabled) != FALSE)
@@ -1027,17 +993,6 @@ void BaseDomain::InitVSD()
}
#ifndef CROSSGEN_COMPILE
-BOOL BaseDomain::ContainsOBJECTHANDLE(OBJECTHANDLE handle)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- return Ref_ContainHandle(m_hHandleTableBucket,handle);
-}
DWORD BaseDomain::AllocateContextStaticsOffset(DWORD* pOffsetSlot)
{
@@ -1076,12 +1031,10 @@ void BaseDomain::ClearFusionContext()
m_pFusionContext->Release();
m_pFusionContext = NULL;
}
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
if (m_pTPABinderContext) {
m_pTPABinderContext->Release();
m_pTPABinderContext = NULL;
}
-#endif
}
#ifdef FEATURE_PREJIT
@@ -1229,7 +1182,6 @@ void AppDomain::RegisterLoaderAllocatorForDeletion(LoaderAllocator * pLoaderAllo
m_pDelayedLoaderAllocatorUnloadList = pLoaderAllocator;
}
-#ifdef FEATURE_CORECLR
void AppDomain::ShutdownNativeDllSearchDirectories()
{
LIMITED_METHOD_CONTRACT;
@@ -1243,7 +1195,6 @@ void AppDomain::ShutdownNativeDllSearchDirectories()
m_NativeDllSearchDirectories.Clear();
}
-#endif
void AppDomain::ReleaseDomainBoundInfo()
{
@@ -2129,57 +2080,7 @@ COMorRemotingFlag AppDomain::GetPreferComInsteadOfManagedRemotingFromConfigFile(
}
CONTRACTL_END;
-#ifdef FEATURE_REMOTING
- COMorRemotingFlag res = COMorRemoting_NotInitialized;
- NonVMComHolder<IXMLParser> pIXMLParser(NULL);
- NonVMComHolder<IStream> pFile(NULL);
- NonVMComHolder<AppDomainConfigFactory> factory(NULL);
-
- EX_TRY
- {
- HRESULT hr;
- CQuickBytes qb;
-
- // get config file URL which is a combination of app base and config file name
- IfFailGo(m_pFusionContext->PrefetchAppConfigFile());
-
- LPWSTR wzConfigFileUrl = (LPWSTR)qb.AllocThrows(MAX_URL_LENGTH * sizeof(WCHAR));
- DWORD dwSize = static_cast<DWORD>(qb.Size());
-
- IfFailGo(m_pFusionContext->Get(ACTAG_APP_CFG_LOCAL_FILEPATH, wzConfigFileUrl, &dwSize, 0));
-
- IfFailGo(CreateConfigStream(wzConfigFileUrl, &pFile));
-
- IfFailGo(GetXMLObjectEx(&pIXMLParser));
-
- factory = new (nothrow) AppDomainConfigFactory();
-
- if (!factory) {
- goto ErrExit;
- }
- factory->AddRef(); // RefCount = 1
-
-
- IfFailGo(pIXMLParser->SetInput(pFile)); // filestream's RefCount=2
-
- IfFailGo(pIXMLParser->SetFactory(factory)); // factory's RefCount=2
-
- IfFailGo(pIXMLParser->Run(-1));
-
- res = factory->GetCOMorRemotingFlag();
-ErrExit: ;
-
- }
- EX_CATCH
- {
- ;
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- return res;
-#else // FEATURE_REMOTING
return COMorRemoting_COM;
-#endif // FEATURE_REMOTING
}
#endif // FEATURE_COMINTEROP
@@ -2525,7 +2426,6 @@ void SystemDomain::Init()
DWORD size = 0;
-#ifdef FEATURE_VERSIONING
// Get the install directory so we can find mscorlib
hr = GetInternalSystemDirectory(NULL, &size);
@@ -2540,11 +2440,6 @@ void SystemDomain::Init()
// At this point m_SystemDirectory should already be canonicalized
-#else
-
- m_SystemDirectory = GetInternalSystemDirectory(&size);
-
-#endif // FEATURE_VERSIONING
m_BaseLibrary.Append(m_SystemDirectory);
if (!m_BaseLibrary.EndsWith(DIRECTORY_SEPARATOR_CHAR_W))
@@ -2575,10 +2470,6 @@ void SystemDomain::Init()
// Finish loading mscorlib now.
m_pSystemAssembly->GetDomainAssembly()->EnsureActive();
-#ifdef FEATURE_FUSION
- // disable fusion log for m_pSystemFile, because m_pSystemFile will get reused
- m_pSystemFile->DisableFusionLogging();
-#endif
}
#ifdef _DEBUG
@@ -2811,15 +2702,7 @@ void SystemDomain::LoadBaseSystemClasses()
ETWOnStartup(LdSysBases_V1, LdSysBasesEnd_V1);
{
-#ifdef FEATURE_FUSION
- ETWOnStartup (FusionAppCtx_V1, FusionAppCtxEnd_V1);
- // Setup fusion context for the system domain - this is used for binding mscorlib.
- IfFailThrow(FusionBind::SetupFusionContext(m_SystemDirectory, NULL, &m_pFusionContext));
-
- m_pSystemFile = PEAssembly::OpenSystem(m_pFusionContext);
-#else
m_pSystemFile = PEAssembly::OpenSystem(NULL);
-#endif // FEATURE_FUSION
}
// Only partially load the system assembly. Other parts of the code will want to access
// the globals in this function before finishing the load.
@@ -2853,10 +2736,6 @@ void SystemDomain::LoadBaseSystemClasses()
_ASSERTE(!g_pEnumClass->IsValueType());
// Load System.RuntimeType
- // We need to load this after ValueType and Enum because RuntimeType now
- // contains an enum field (m_invocationFlags). Otherwise INVOCATION_FLAGS
- // would be treated as a reference type and clr!SigPointer::GetTypeHandleThrowing
- // throws an exception.
g_pRuntimeTypeClass = MscorlibBinder::GetClass(CLASS__CLASS);
_ASSERTE(g_pRuntimeTypeClass->IsFullyLoaded());
@@ -2871,13 +2750,11 @@ void SystemDomain::LoadBaseSystemClasses()
// the SZArrayHelper class here.
g_pSZArrayHelperClass = MscorlibBinder::GetClass(CLASS__SZARRAYHELPER);
-#ifdef FEATURE_SPAN_OF_T
// Load ByReference class
//
// NOTE: ByReference<T> must be the first by-ref-like system type to be loaded,
// because MethodTable::ClassifyEightBytesWithManagedLayout depends on it.
g_pByReferenceClass = MscorlibBinder::GetClass(CLASS__BYREFERENCE);
-#endif
// Load Nullable class
g_pNullableClass = MscorlibBinder::GetClass(CLASS__NULLABLE);
@@ -2924,26 +2801,6 @@ void SystemDomain::LoadBaseSystemClasses()
#ifndef CROSSGEN_COMPILE
ECall::PopulateManagedStringConstructors();
-
- if (CLRIoCompletionHosted())
- {
- g_pOverlappedDataClass = MscorlibBinder::GetClass(CLASS__OVERLAPPEDDATA);
- _ASSERTE (g_pOverlappedDataClass);
- if (CorHost2::GetHostOverlappedExtensionSize() != 0)
- {
- // Overlapped may have an extension if a host hosts IO completion subsystem
- DWORD instanceFieldBytes = g_pOverlappedDataClass->GetNumInstanceFieldBytes() + CorHost2::GetHostOverlappedExtensionSize();
- _ASSERTE (instanceFieldBytes + ObjSizeOf(Object) >= MIN_OBJECT_SIZE);
- DWORD baseSize = (DWORD) (instanceFieldBytes + ObjSizeOf(Object));
- baseSize = (baseSize + ALLOC_ALIGN_CONSTANT) & ~ALLOC_ALIGN_CONSTANT; // m_BaseSize must be aligned
- DWORD adjustSize = baseSize - g_pOverlappedDataClass->GetBaseSize();
- CGCDesc* map = CGCDesc::GetCGCDescFromMT(g_pOverlappedDataClass);
- CGCDescSeries * cur = map->GetHighestSeries();
- _ASSERTE ((SSIZE_T)map->GetNumSeries() == 1);
- cur->SetSeriesSize(cur->GetSeriesSize() - adjustSize);
- g_pOverlappedDataClass->SetBaseSize(baseSize);
- }
- }
#endif // CROSSGEN_COMPILE
g_pExceptionClass = MscorlibBinder::GetClass(CLASS__EXCEPTION);
@@ -2952,16 +2809,6 @@ void SystemDomain::LoadBaseSystemClasses()
g_pExecutionEngineExceptionClass = MscorlibBinder::GetException(kExecutionEngineException);
g_pThreadAbortExceptionClass = MscorlibBinder::GetException(kThreadAbortException);
-#ifdef FEATURE_CER
- // Used for determining whether a class has a critical finalizer
- // To determine whether a class has a critical finalizer, we
- // currently will simply see if it's parent class has a critical
- // finalizer. To introduce a class with a critical finalizer,
- // we'll explicitly load CriticalFinalizerObject and set the bit
- // here.
- g_pCriticalFinalizerObjectClass = MscorlibBinder::GetClass(CLASS__CRITICAL_FINALIZER_OBJECT);
- _ASSERTE(g_pCriticalFinalizerObjectClass->HasCriticalFinalizer());
-#endif
// used by gc to handle predefined agility checking
g_pThreadClass = MscorlibBinder::GetClass(CLASS__THREAD);
@@ -2991,9 +2838,6 @@ void SystemDomain::LoadBaseSystemClasses()
// Load a special marker method used to detect Constrained Execution Regions
// at jit time.
-#ifdef FEATURE_CER
- g_pPrepareConstrainedRegionsMethod = MscorlibBinder::GetMethod(METHOD__RUNTIME_HELPERS__PREPARE_CONSTRAINED_REGIONS);
-#endif
g_pExecuteBackoutCodeHelperMethod = MscorlibBinder::GetMethod(METHOD__RUNTIME_HELPERS__EXECUTE_BACKOUT_CODE_HELPER);
// Make sure that FCall mapping for Monitor.Enter is initialized. We need it in case Monitor.Enter is used only as JIT helper.
@@ -3321,31 +3165,6 @@ BOOL SystemDomain::SetGlobalSharePolicyUsingAttribute(IMDInternalImport* pScope,
{
STANDARD_VM_CONTRACT;
-#ifdef FEATURE_FUSION
- HRESULT hr;
-
- //
- // Check to see if the assembly has the LoaderOptimization attribute set.
- //
-
- DWORD cbVal;
- BYTE *pVal;
- IfFailThrow(hr = pScope->GetCustomAttributeByName(mdMethod,
- DEFAULTDOMAIN_LOADEROPTIMIZATION_TYPE,
- (const void**)&pVal, &cbVal));
-
- if (hr == S_OK) {
- CustomAttributeParser cap(pVal, cbVal);
- IfFailThrow(cap.SkipProlog());
-
- UINT8 u1;
- IfFailThrow(cap.GetU1(&u1));
-
- g_dwGlobalSharePolicy = u1 & AppDomain::SHARE_POLICY_MASK;
-
- return TRUE;
- }
-#endif
return FALSE;
}
@@ -3427,49 +3246,6 @@ void SystemDomain::InitializeDefaultDomain(
ETWOnStartup (InitDefaultDomain_V1, InitDefaultDomainEnd_V1);
-#if defined(FEATURE_FUSION) // SxS
- // Determine the application base and the configuration file name
- CQuickWSTR sPathName;
- CQuickWSTR sConfigName;
-
- SIZE_T dwSize;
- HRESULT hr = GetConfigFileFromWin32Manifest(sConfigName.Ptr(),
- sConfigName.MaxSize(),
- &dwSize);
- if(FAILED(hr))
- {
- if(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- sConfigName.ReSizeThrows(dwSize);
- hr = GetConfigFileFromWin32Manifest(sConfigName.Ptr(),
- sConfigName.MaxSize(),
- &dwSize);
- }
- IfFailThrow(hr);
- }
- else
- sConfigName.ReSizeThrows(dwSize);
-
- hr = GetApplicationPathFromWin32Manifest(sPathName.Ptr(),
- sPathName.MaxSize(),
- &dwSize);
- if(FAILED(hr))
- {
- if(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- sPathName.ReSizeThrows(dwSize);
- hr = GetApplicationPathFromWin32Manifest(sPathName.Ptr(),
- sPathName.MaxSize(),
- &dwSize);
- }
- IfFailThrow(hr);
- }
- else
- sPathName.ReSizeThrows(dwSize);
-
- pwsConfig = (sConfigName.Size() > 0 ? sConfigName.Ptr() : NULL);
- pwsPath = (sPathName.Size() > 0 ? sPathName.Ptr() : NULL);
-#endif // defined(FEATURE_FUSION) // SxS
// Setup the default AppDomain.
@@ -3483,13 +3259,6 @@ void SystemDomain::InitializeDefaultDomain(
{
pDefaultDomain->SetLoadContextHostBinder(pBinder);
}
- #ifdef FEATURE_APPX_BINDER
- else if (AppX::IsAppXProcess())
- {
- CLRPrivBinderAppX * pAppXBinder = CLRPrivBinderAppX::GetOrCreateBinder();
- pDefaultDomain->SetLoadContextHostBinder(pAppXBinder);
- }
- #endif
{
GCX_COOP();
@@ -3497,10 +3266,6 @@ void SystemDomain::InitializeDefaultDomain(
#ifndef CROSSGEN_COMPILE
if (!NingenEnabled())
{
-#ifndef FEATURE_CORECLR
- pDefaultDomain->InitializeHashing(NULL);
- pDefaultDomain->InitializeSorting(NULL);
-#endif // FEATURE_CORECLR
}
#endif // CROSSGEN_COMPILE
@@ -3509,9 +3274,6 @@ void SystemDomain::InitializeDefaultDomain(
#ifndef CROSSGEN_COMPILE
if (!NingenEnabled())
{
-#ifdef FEATURE_CLICKONCE
- pDefaultDomain->InitializeDefaultClickOnceDomain();
-#endif // FEATURE_CLICKONCE
if (!IsSingleAppDomain())
{
@@ -3540,324 +3302,8 @@ void SystemDomain::InitializeDefaultDomain(
Volatile<LONG> g_fInExecuteMainMethod = 0;
#endif
-#ifndef FEATURE_CORECLR
-void SystemDomain::ExecuteMainMethod(HMODULE hMod, __in_opt LPWSTR path /*=NULL*/)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- PRECONDITION(CheckPointer(hMod, NULL_OK));
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
-#ifdef _DEBUG
- CounterHolder counter(&g_fInExecuteMainMethod);
-#endif
-
- Thread *pThread = GetThread();
- _ASSERTE(pThread);
-
- GCX_COOP();
-
- //
- // There is no EH protecting this transition!
- // This is generically ok in this method because if we throw out of here, it becomes unhandled anyway.
- //
- FrameWithCookie<ContextTransitionFrame> frame;
- pThread->EnterContextRestricted(SystemDomain::System()->DefaultDomain()->GetDefaultContext(), &frame);
- _ASSERTE(pThread->GetDomain());
-
- AppDomain *pDomain = GetAppDomain();
- _ASSERTE(pDomain);
-
- // Push this frame around loading the main assembly to ensure the
- // debugger can properly recognize any managed code that gets run
- // as "class initializaion" code.
- FrameWithCookie<DebuggerClassInitMarkFrame> __dcimf;
- {
- GCX_PREEMP();
-
- PEImageHolder pTempImage(PEImage::LoadImage(hMod));
-
- PEFileHolder pTempFile(PEFile::Open(pTempImage.Extract()));
-
- // Check for CustomAttributes - Set up the DefaultDomain and the main thread
- // Note that this has to be done before ExplicitBind() as it
- // affects the bind
- mdToken tkEntryPoint = pTempFile->GetEntryPointToken();
- // <TODO>@TODO: What if the entrypoint is in another file of the assembly?</TODO>
- ReleaseHolder<IMDInternalImport> scope(pTempFile->GetMDImportWithRef());
- // In theory, we should have a valid executable image and scope should never be NULL, but we've been
- // getting Watson failures for AVs here due to ISVs modifying image headers and some new OS loader
- // checks (see Dev10# 718530 and Windows 7# 615596)
- if (scope == NULL)
- {
- ThrowHR(COR_E_BADIMAGEFORMAT);
- }
-
-#ifdef FEATURE_COMINTEROP
- Thread::ApartmentState state = Thread::AS_Unknown;
-
- if((!IsNilToken(tkEntryPoint)) && (TypeFromToken(tkEntryPoint) == mdtMethodDef)) {
- if (scope->IsValidToken(tkEntryPoint))
- state = SystemDomain::GetEntryPointThreadAptState(scope, tkEntryPoint);
- else
- ThrowHR(COR_E_BADIMAGEFORMAT);
- }
-
- // If the entry point has an explicit thread apartment state, set it
- // before running the AppDomainManager initialization code.
- if (state == Thread::AS_InSTA || state == Thread::AS_InMTA)
- SystemDomain::SetThreadAptState(scope, state);
-#endif // FEATURE_COMINTEROP
-
- BOOL fSetGlobalSharePolicyUsingAttribute = FALSE;
-
- if((!IsNilToken(tkEntryPoint)) && (TypeFromToken(tkEntryPoint) == mdtMethodDef))
- {
- // The global share policy needs to be set before initializing default domain
- // so that it is in place for loading of appdomain manager.
- fSetGlobalSharePolicyUsingAttribute = SystemDomain::SetGlobalSharePolicyUsingAttribute(scope, tkEntryPoint);
- }
-
- // This can potentially run managed code.
- InitializeDefaultDomain(FALSE);
-
-#ifdef FEATURE_COMINTEROP
- // If we haven't set an explicit thread apartment state, set it after the
- // AppDomainManager has got a chance to go set it in InitializeNewDomain.
- if (state != Thread::AS_InSTA && state != Thread::AS_InMTA)
- SystemDomain::SetThreadAptState(scope, state);
-#endif // FEATURE_COMINTEROP
-
- if (fSetGlobalSharePolicyUsingAttribute)
- SystemDomain::System()->DefaultDomain()->SetupLoaderOptimization(g_dwGlobalSharePolicy);
-
- NewHolder<IPEFileSecurityDescriptor> pSecDesc(Security::CreatePEFileSecurityDescriptor(pDomain, pTempFile));
-
- {
- GCX_COOP();
- pSecDesc->Resolve();
- if (pSecDesc->AllowBindingRedirects())
- pDomain->TurnOnBindingRedirects();
- }
-
- PEAssemblyHolder pFile(pDomain->BindExplicitAssembly(hMod, TRUE));
-
- pDomain->m_pRootAssembly = GetAppDomain()->LoadAssembly(NULL, pFile, FILE_ACTIVE);
-
- {
- GCX_COOP();
-
- // Reuse the evidence that was generated for the PEFile for the assembly so we don't have to
- // regenerate evidence of the same type again if it is requested later.
- pDomain->m_pRootAssembly->GetSecurityDescriptor()->SetEvidenceFromPEFile(pSecDesc);
- }
-
- // If the AppDomainManager for the default domain was specified in the application config file then
- // we require that the assembly be trusted in order to set the manager
- if (pDomain->HasAppDomainManagerInfo() && pDomain->AppDomainManagerSetFromConfig())
- {
- Assembly *pEntryAssembly = pDomain->GetAppDomainManagerEntryAssembly();
- if (!pEntryAssembly->GetSecurityDescriptor()->AllowApplicationSpecifiedAppDomainManager())
- {
- COMPlusThrow(kTypeLoadException, IDS_E_UNTRUSTED_APPDOMAIN_MANAGER);
- }
- }
-
- if (CorCommandLine::m_pwszAppFullName == NULL) {
- StackSString friendlyName;
- StackSString assemblyPath = pFile->GetPath();
- SString::Iterator i = assemblyPath.End();
-
- if (PEAssembly::FindLastPathSeparator(assemblyPath, i)) {
- i++;
- friendlyName.Set(assemblyPath, i, assemblyPath.End());
- }
- else
- friendlyName.Set(assemblyPath);
-
- pDomain->SetFriendlyName(friendlyName, TRUE);
- }
- }
- __dcimf.Pop();
-
- {
- GCX_PREEMP();
-
- LOG((LF_CLASSLOADER | LF_CORDB,
- LL_INFO10,
- "Created domain for an executable at %p\n",
- (pDomain->m_pRootAssembly ? pDomain->m_pRootAssembly->Parent() : NULL)));
- TESTHOOKCALL(RuntimeStarted(RTS_CALLINGENTRYPOINT));
-
-#ifdef FEATURE_MULTICOREJIT
- pDomain->GetMulticoreJitManager().AutoStartProfile(pDomain);
-#endif
-
- pDomain->m_pRootAssembly->ExecuteMainMethod(NULL, TRUE /* waitForOtherThreads */);
- }
-
- pThread->ReturnToContext(&frame);
-
-#ifdef FEATURE_TESTHOOKS
- TESTHOOKCALL(LeftAppDomain(DefaultADID));
-#endif
-}
-#endif //!FEATURE_CORECLR
-
-#ifdef FEATURE_CLICKONCE
-void SystemDomain::ActivateApplication(int *pReturnValue)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- struct _gc {
- OBJECTREF orThis;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCX_COOP();
- GCPROTECT_BEGIN(gc);
-
- gc.orThis = SystemDomain::System()->DefaultDomain()->GetExposedObject();
-
- MethodDescCallSite activateApp(METHOD__APP_DOMAIN__ACTIVATE_APPLICATION, &gc.orThis);
-
- ARG_SLOT args[] = {
- ObjToArgSlot(gc.orThis),
- };
- int retval = activateApp.Call_RetI4(args);
- if (pReturnValue)
- *pReturnValue = retval;
-
- GCPROTECT_END();
-}
-#endif // FEATURE_CLICKONCE
-
-#ifdef FEATURE_MIXEDMODE
-static HRESULT RunDllMainHelper(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved, Thread* pThread, bool bReenablePreemptive)
-{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_MODE_COOPERATIVE;
- STATIC_CONTRACT_FAULT;
-
- MethodDesc *pMD;
- AppDomain *pDomain;
- Module *pModule;
- HRESULT hr = S_FALSE; // Assume no entry point.
-
- // Setup the thread state to cooperative to run managed code.
-
- // Get the old domain from the thread. Legacy dll entry points must always
- // be run from the default domain.
- //
- // We cannot support legacy dlls getting loaded into all domains!!
- EX_TRY
- {
- ENTER_DOMAIN_PTR(SystemDomain::System()->DefaultDomain(),ADV_DEFAULTAD)
- {
- pDomain = pThread->GetDomain();
- // The module needs to be in the current list if you are coming here.
- pModule = pDomain->GetIJWModule(hInst);
- if (!pModule)
- goto ErrExit;
- // See if there even is an entry point.
- pMD = pModule->GetDllEntryPoint();
- if (!pMD)
- goto ErrExit;
-
- // We're actually going to run some managed code. There may be a customer
- // debug probe enabled, that prevents execution in the loader lock.
- CanRunManagedCode(hInst);
-
- {
- // Enter cooperative mode
- GCX_COOP_NO_DTOR();
- }
-
- // Run through the helper which will do exception handling for us.
- hr = ::RunDllMain(pMD, hInst, dwReason, lpReserved);
-
- {
- // Update thread state for the case where we are returning to unmanaged code.
- GCX_MAYBE_PREEMP_NO_DTOR(bReenablePreemptive);
- }
-
-ErrExit: ;
- // does not throw exception
- }
- END_DOMAIN_TRANSITION;
-
- }
- EX_CATCH
- {
- hr = GetExceptionHResult(GET_THROWABLE());
- }
- EX_END_CATCH(SwallowAllExceptions)
-
- return (hr);
-}
-
-//*****************************************************************************
-// This guy will set up the proper thread state, look for the module given
-// the hinstance, and then run the entry point if there is one.
-//*****************************************************************************
-HRESULT SystemDomain::RunDllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved)
-{
-
- CONTRACTL
- {
- NOTHROW;
- if (GetThread() && !lpReserved) {MODE_PREEMPTIVE;} else {DISABLED(MODE_PREEMPTIVE);};
- if(GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);};
- }
- CONTRACTL_END;
-
-
- Thread *pThread = NULL;
- BOOL fEnterCoop = FALSE;
- HRESULT hr = S_FALSE; // Assume no entry point.
-
- pThread = GetThread();
- if ((!pThread && (dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH)) ||
- g_fEEShutDown)
- return S_OK;
-
- // ExitProcess is called while a thread is doing GC.
- if (dwReason == DLL_PROCESS_DETACH && GCHeapUtilities::IsGCInProgress())
- return S_OK;
-
- // ExitProcess is called on a thread that we don't know about
- if (dwReason == DLL_PROCESS_DETACH && GetThread() == NULL)
- return S_OK;
-
- // Need to setup the thread since this might be the first time the EE has
- // seen it if the thread was created in unmanaged code and this is a thread
- // attach event.
- if (pThread)
- fEnterCoop = pThread->PreemptiveGCDisabled();
- else {
- pThread = SetupThreadNoThrow(&hr);
- if (pThread == NULL)
- return hr;
- }
-
- return RunDllMainHelper(hInst, dwReason, lpReserved, pThread, !fEnterCoop);
-}
-#endif // FEATURE_MIXEDMODE
#endif // CROSSGEN_COMPILE
@@ -3895,7 +3341,6 @@ Assembly *AppDomain::LoadAssemblyHelper(LPCWSTR wszAssembly,
#if defined(FEATURE_CLASSIC_COMINTEROP) && !defined(CROSSGEN_COMPILE)
-#ifdef FEATURE_CORECLR
MethodTable *AppDomain::LoadCOMClass(GUID clsid,
BOOL bLoadRecord/*=FALSE*/,
BOOL* pfAssemblyInReg/*=NULL*/)
@@ -3903,135 +3348,6 @@ MethodTable *AppDomain::LoadCOMClass(GUID clsid,
// @CORESYSTODO: what to do here?
return NULL;
}
-#else // FEATURE_CORECLR
-
-static BOOL IsSameRuntimeVersion(ICLRRuntimeInfo *pInfo1, ICLRRuntimeInfo *pInfo2)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- WCHAR wszVersion1[_MAX_PATH];
- WCHAR wszVersion2[_MAX_PATH];
- DWORD cchVersion;
-
- cchVersion = COUNTOF(wszVersion1);
- IfFailThrow(pInfo1->GetVersionString(wszVersion1, &cchVersion));
-
- cchVersion = COUNTOF(wszVersion2);
- IfFailThrow(pInfo2->GetVersionString(wszVersion2, &cchVersion));
-
- return SString::_wcsicmp(wszVersion1, wszVersion2) == 0;
-}
-
-MethodTable *AppDomain::LoadCOMClass(GUID clsid,
- BOOL bLoadRecord/*=FALSE*/,
- BOOL* pfAssemblyInReg/*=NULL*/)
-{
- CONTRACT (MethodTable*)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
-
- MethodTable* pMT = NULL;
-
- NewArrayHolder<WCHAR> wszClassName = NULL;
- NewArrayHolder<WCHAR> wszAssemblyString = NULL;
- NewArrayHolder<WCHAR> wszCodeBaseString = NULL;
-
- DWORD cbAssembly = 0;
- DWORD cbCodeBase = 0;
- Assembly *pAssembly = NULL;
- BOOL fFromRegistry = FALSE;
- BOOL fRegFreePIA = FALSE;
-
- HRESULT hr = S_OK;
-
- if (pfAssemblyInReg != NULL)
- *pfAssemblyInReg = FALSE;
-
- // with sxs.dll help
- hr = FindShimInfoFromWin32(clsid, bLoadRecord, NULL, NULL, &wszClassName, &wszAssemblyString, &fRegFreePIA);
-
- if(FAILED(hr))
- {
- hr = FindShimInfoFromRegistry(clsid, bLoadRecord, VER_ASSEMBLYMAJORVERSION, VER_ASSEMBLYMINORVERSION,
- &wszClassName, &wszAssemblyString, &wszCodeBaseString);
- if (FAILED(hr))
- RETURN NULL;
-
- fFromRegistry = TRUE;
- }
-
- // Skip the GetRuntimeForManagedCOMObject check for value types since they cannot be activated and are
- // always used for wrapping existing instances coming from COM.
- if (!bLoadRecord)
- {
- // We will load the assembly only if it is a PIA or if unmanaged activation would load the currently running
- // runtime. Otherwise we return NULL which will result in using the default System.__ComObject type.
-
- // the type is a PIA type if mscoree.dll is not its inproc server dll or it was specified as <clrSurrogate> in the manifest
- BOOL fPIA = (fFromRegistry ? !Clr::Util::Com::CLSIDHasMscoreeAsInprocServer32(clsid) : fRegFreePIA);
- if (!fPIA)
- {
- // this isn't a PIA, so we must determine which runtime it would load
- ReleaseHolder<ICLRRuntimeHostInternal> pRuntimeHostInternal;
- IfFailThrow(g_pCLRRuntime->GetInterface(CLSID_CLRRuntimeHostInternal,
- IID_ICLRRuntimeHostInternal,
- &pRuntimeHostInternal));
-
- // we call the shim to see which runtime would this be activated in
- ReleaseHolder<ICLRRuntimeInfo> pRuntimeInfo;
- if (FAILED(pRuntimeHostInternal->GetRuntimeForManagedCOMObject(clsid, IID_ICLRRuntimeInfo, &pRuntimeInfo)))
- {
- // the requested runtime is not loadable - don't load the assembly
- RETURN NULL;
- }
-
- if (!IsSameRuntimeVersion(g_pCLRRuntime, pRuntimeInfo))
- {
- // the requested runtime is different from this runtime - don't load the assembly
- RETURN NULL;
- }
- }
- }
-
- if (pfAssemblyInReg != NULL)
- *pfAssemblyInReg = TRUE;
-
- if (wszAssemblyString != NULL) {
- pAssembly = LoadAssemblyHelper(wszAssemblyString, wszCodeBaseString);
- pMT = TypeName::GetTypeFromAssembly(wszClassName, pAssembly).GetMethodTable();
- if (!pMT)
- goto ErrExit;
- }
-
- if (pMT == NULL) {
- ErrExit:
- // Convert the GUID to its string representation.
- WCHAR szClsid[64];
- if (GuidToLPWSTR(clsid, szClsid, NumItems(szClsid)) == 0)
- szClsid[0] = 0;
-
- // Throw an exception indicating we failed to load the type with
- // the requested CLSID.
- COMPlusThrow(kTypeLoadException, IDS_CLASSLOAD_NOCLSIDREG, szClsid);
- }
-
- RETURN pMT;
-}
-
-#endif // FEATURE_CORECLR
#endif // FEATURE_CLASSIC_COMINTEROP && !CROSSGEN_COMPILE
@@ -4078,17 +3394,6 @@ bool SystemDomain::IsReflectionInvocationMethod(MethodDesc* pMeth)
CLASS__ASSEMBLY,
CLASS__TYPE_DELEGATOR,
CLASS__RUNTIME_HELPERS,
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
- CLASS__ITYPE,
- CLASS__IASSEMBLY,
- CLASS__IMETHODBASE,
- CLASS__IMETHODINFO,
- CLASS__ICONSTRUCTORINFO,
- CLASS__IFIELDINFO,
- CLASS__IPROPERTYINFO,
- CLASS__IEVENTINFO,
- CLASS__IAPPDOMAIN,
-#endif // FEATURE_COMINTEROP && !FEATURE_CORECLR
CLASS__LAZY_INITIALIZER,
CLASS__DYNAMICMETHOD,
CLASS__DELEGATE,
@@ -4149,9 +3454,6 @@ bool SystemDomain::IsReflectionInvocationMethod(MethodDesc* pMeth)
// unmaintainable as more changes are made to BCL types.
if ((pCaller == MscorlibBinder::GetExistingClass(CLASS__APP_DOMAIN))
&& (pMeth != MscorlibBinder::GetMethod(METHOD__APP_DOMAIN__CREATE_APP_DOMAIN_MANAGER)) // This uses reflection to create an AppDomainManager
- #ifdef FEATURE_CLICKONCE
- && (pMeth != MscorlibBinder::GetMethod(METHOD__APP_DOMAIN__ACTIVATE_APPLICATION)) // This uses reflection to create an ActivationContext
- #endif
)
{
return true;
@@ -4166,9 +3468,6 @@ struct CallersDataWithStackMark
{
StackCrawlMark* stackMark;
BOOL foundMe;
-#ifdef FEATURE_REMOTING
- BOOL skippingRemoting;
-#endif
MethodDesc* pFoundMethod;
MethodDesc* pPrevMethod;
AppDomain* pAppDomain;
@@ -4363,25 +3662,6 @@ StackWalkAction SystemDomain::CallersMethodCallbackWithStackMark(CrawlFrame* pCf
Frame* frame = pCf->GetFrame();
_ASSERTE(pCf->IsFrameless() || frame);
-#ifdef FEATURE_REMOTING
- if (pFunc == MscorlibBinder::GetMethod(METHOD__STACK_BUILDER_SINK__PRIVATE_PROCESS_MESSAGE))
- {
- _ASSERTE(!pCaller->skippingRemoting);
- pCaller->skippingRemoting = true;
- return SWA_CONTINUE;
- }
- // And we spot the client end because there's a transparent proxy transition
- // frame pushed.
- if (frame && frame->GetFrameType() == Frame::TYPE_TP_METHOD_FRAME)
- {
- pCaller->skippingRemoting = false;
- return SWA_CONTINUE;
- }
-
- // Skip any frames into between the server and client remoting endpoints.
- if (pCaller->skippingRemoting)
- return SWA_CONTINUE;
-#endif
// Skipping reflection frames. We don't need to be quite as exhaustive here
@@ -4449,7 +3729,6 @@ StackWalkAction SystemDomain::CallersMethodCallbackWithStackMark(CrawlFrame* pCf
return SWA_CONTINUE;
}
-#ifndef FEATURE_REMOTING
// If remoting is not available, we only set the caller if the crawlframe is from the same domain.
// Why? Because if the callerdomain is different from current domain,
// there have to be interop/native frames in between.
@@ -4459,7 +3738,6 @@ StackWalkAction SystemDomain::CallersMethodCallbackWithStackMark(CrawlFrame* pCf
// In general, if the caller is INTEROP, we set the caller/callerdomain to be NULL
// (To be precise: they are already NULL and we don't change them).
if (pCf->GetAppDomain() == GetAppDomain())
-#endif // FEATURE_REMOTING
// We must either be looking for the caller, or the caller's caller when
// we've already found the caller (we used a non-null value in pFoundMethod
// simply as a flag, the correct method to return in both case is the
@@ -4710,106 +3988,6 @@ HRESULT SystemDomain::NotifyProfilerShutdown()
}
#endif // PROFILING_SUPPORTED
-#ifdef FEATURE_FUSION
-static HRESULT GetVersionPath(HKEY root, __in LPWSTR key, __out LPWSTR* pDevpath, DWORD* pdwDevpath)
-{
- CONTRACTL
- {
- MODE_PREEMPTIVE;
- NOTHROW;
- GC_NOTRIGGER;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END;
-
- DWORD rtn;
- RegKeyHolder versionKey;
- rtn = WszRegOpenKeyEx(root, key, 0, KEY_READ, &versionKey);
- if(rtn == ERROR_SUCCESS) {
- DWORD type;
- DWORD cbDevpath;
- if(WszRegQueryValueEx(versionKey, W("devpath"), 0, &type, (LPBYTE) NULL, &cbDevpath) == ERROR_SUCCESS && type == REG_SZ) {
- *pDevpath = (LPWSTR) new (nothrow) BYTE[cbDevpath];
- if(*pDevpath == NULL)
- return E_OUTOFMEMORY;
- else {
- rtn = WszRegQueryValueEx(versionKey, W("devpath"), 0, &type, (LPBYTE) *pDevpath, &cbDevpath);
- if ((rtn == ERROR_SUCCESS) && (type == REG_SZ))
- *pdwDevpath = (DWORD) wcslen(*pDevpath);
- }
- }
- else
- return REGDB_E_INVALIDVALUE;
- }
-
- return HRESULT_FROM_WIN32(rtn);
-}
-
-// Get the developers path from the environment. This can only be set through the environment and
-// cannot be added through configuration files, registry etc. This would make it to easy for
-// developers to deploy apps that are not side by side. The environment variable should only
-// be used on developers machines where exact matching to versions makes build and testing to
-// difficult.
-void SystemDomain::GetDevpathW(__out_ecount_opt(1) LPWSTR* pDevpath, DWORD* pdwDevpath)
-{
- CONTRACTL
- {
- THROWS;
- MODE_ANY;
- GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- GCX_PREEMP();
-
- if(g_pConfig->DeveloperInstallation() && m_fDevpath == FALSE) {
-
- LockHolder lh;
-
- if(m_fDevpath == FALSE) {
- DWORD dwPath = 0;
- PathString m_pwDevpathholder;
- dwPath = WszGetEnvironmentVariable(APPENV_DEVPATH, m_pwDevpathholder);
- if(dwPath) {
- m_pwDevpath = m_pwDevpathholder.GetCopyOfUnicodeString();
- }
- else {
- RegKeyHolder userKey;
- RegKeyHolder machineKey;
-
- WCHAR pVersion[MAX_PATH_FNAME];
- DWORD dwVersion = MAX_PATH_FNAME;
- HRESULT hr = S_OK;
- hr = FusionBind::GetVersion(pVersion, &dwVersion);
- if(SUCCEEDED(hr)) {
- LONG rslt;
- rslt = WszRegOpenKeyEx(HKEY_CURRENT_USER, FRAMEWORK_REGISTRY_KEY_W,0,KEY_READ, &userKey);
- hr = HRESULT_FROM_WIN32(rslt);
- if (SUCCEEDED(hr)) {
- hr = GetVersionPath(userKey, pVersion, &m_pwDevpath, &m_dwDevpath);
- }
-
- if (FAILED(hr) && WszRegOpenKeyEx(HKEY_LOCAL_MACHINE, FRAMEWORK_REGISTRY_KEY_W,0,KEY_READ, &machineKey) == ERROR_SUCCESS) {
- hr = GetVersionPath(machineKey, pVersion, &m_pwDevpath, &m_dwDevpath);
- }
- }
- if (Assembly::FileNotFound(hr))
- hr = S_FALSE;
- else
- IfFailThrow(hr);
- }
-
- m_fDevpath = TRUE;
- }
- // lh out of scope here
- }
-
- if(pDevpath) *pDevpath = m_pwDevpath;
- if(pdwDevpath) *pdwDevpath = m_dwDevpath;
- return;
-}
-#endif // FEATURE_FUSION
#ifdef _DEBUG
struct AppDomain::ThreadTrackInfo {
@@ -4838,15 +4016,6 @@ AppDomain::AppDomain()
m_pUnloadRequestThread = NULL;
m_ADUnloadSink=NULL;
-#ifndef FEATURE_CORECLR
- m_bUseOsSorting = RunningOnWin8();
- m_sortVersion = DEFAULT_SORT_VERSION;
- m_pCustomSortLibrary = NULL;
-#if _DEBUG
- m_bSortingInitialized = FALSE;
-#endif // _DEBUG
- m_pNlsHashProvider = NULL;
-#endif //!FEATURE_CORECLR
// Initialize Shared state. Assemblies are loaded
// into each domain by default.
@@ -4873,7 +4042,7 @@ AppDomain::AppDomain()
m_pUMEntryThunkCache = NULL;
m_pAsyncPool = NULL;
- m_hHandleTableBucket = NULL;
+ m_handleStore = NULL;
m_ExposedObject = NULL;
m_pComIPForExposedObject = NULL;
@@ -4887,11 +4056,6 @@ AppDomain::AppDomain()
m_dwThreadEnterCount = 0;
m_dwThreadsStillInAppDomain = (ULONG)-1;
- m_pSecDesc = NULL;
- m_hHandleTableBucket=NULL;
-
- m_ExposedObject = NULL;
-
#ifdef FEATURE_COMINTEROP
m_pRefDispIDCache = NULL;
m_hndMissing = NULL;
@@ -4911,7 +4075,7 @@ AppDomain::AppDomain()
m_dwRefTakers=0;
m_dwCreationHolders=0;
#endif
-
+
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
m_ullTotalProcessorUsage = 0;
m_pullAllocBytes = NULL;
@@ -4923,10 +4087,6 @@ AppDomain::AppDomain()
#endif // FEATURE_TYPEEQUIVALENCE
#ifdef FEATURE_COMINTEROP
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
- m_pReflectionOnlyWinRtBinder = NULL;
- m_pReflectionOnlyWinRtTypeCache = NULL;
-#endif // FEATURE_REFLECTION_ONLY_LOAD
m_pNameToTypeMap = NULL;
m_vNameToTypeMapVersion = 0;
m_nEpoch = 0;
@@ -4940,9 +4100,7 @@ AppDomain::AppDomain()
m_pDomainFileWithNativeImageList = NULL;
#endif
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
m_fIsBindingModelLocked.Store(FALSE);
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
} // AppDomain::AppDomain
@@ -4979,35 +4137,10 @@ AppDomain::~AppDomain()
if(!g_fEEInit)
Terminate();
-#ifndef FEATURE_CORECLR
- if (m_pCustomSortLibrary)
- delete m_pCustomSortLibrary;
-
- if (m_pNlsHashProvider)
- delete m_pNlsHashProvider;
-#endif
-#ifdef FEATURE_REMOTING
- if (!g_fEEInit)
- {
- GCX_COOP(); // See SystemDomain::EnumAllStaticGCRefs if you are removing this
- CrossDomainTypeMap::FlushStaleEntries();
- CrossDomainFieldMap::FlushStaleEntries();
- }
-#endif // FEATURE_REMOTING
#ifdef FEATURE_COMINTEROP
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
- if (m_pReflectionOnlyWinRtBinder != NULL)
- {
- m_pReflectionOnlyWinRtBinder->Release();
- }
- if (m_pReflectionOnlyWinRtTypeCache != NULL)
- {
- m_pReflectionOnlyWinRtTypeCache->Release();
- }
-#endif // FEATURE_REFLECTION_ONLY_LOAD
if (m_pNameToTypeMap != nullptr)
{
delete m_pNameToTypeMap;
@@ -5140,18 +4273,13 @@ void AppDomain::Init()
// default domain cannot be unloaded.
if (GetId().m_dwId == DefaultADID)
{
- m_hHandleTableBucket = g_HandleTableMap.pBuckets[0];
+ m_handleStore = GCHandleTableUtilities::GetGCHandleTable()->GetGlobalHandleStore();
}
else
{
- m_hHandleTableBucket = Ref_CreateHandleTableBucket(m_dwIndex);
+ m_handleStore = GCHandleTableUtilities::GetGCHandleTable()->CreateHandleStore((void*)(uintptr_t)m_dwIndex.m_dwIndex);
}
-#ifdef _DEBUG
- if (((HandleTable *)(m_hHandleTableBucket->pTable[0]))->uADIndex != m_dwIndex)
- _ASSERTE (!"AD index mismatch");
-#endif // _DEBUG
-
#endif // CROSSGEN_COMPILE
#ifdef FEATURE_TYPEEQUIVALENCE
@@ -5181,25 +4309,13 @@ void AppDomain::Init()
#ifdef FEATURE_COMINTEROP
if (!AppX::IsAppXProcess())
{
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
- m_pReflectionOnlyWinRtTypeCache = clr::SafeAddRef(new CLRPrivTypeCacheReflectionOnlyWinRT());
- m_pReflectionOnlyWinRtBinder = clr::SafeAddRef(new CLRPrivBinderReflectionOnlyWinRT(m_pReflectionOnlyWinRtTypeCache));
-#endif
}
-#ifdef FEATURE_APPX_BINDER
- else if (g_fEEStarted && !IsDefaultDomain())
- { // Non-default domain in an AppX process. This exists only for designers and we'd better be in dev mode.
- _ASSERTE(IsCompilationProcess() || AppX::IsAppXDesignMode());
-
- // Inherit AppX binder from default domain.
- SetLoadContextHostBinder(SystemDomain::System()->DefaultDomain()->GetLoadContextHostBinder());
-
- // Note: LoadFrom, LoadFile, Load(byte[], ...), ReflectionOnlyLoad, LoadWithPartialName,
- /// etc. are not supported and are actively blocked.
- }
-#endif //FEATURE_APPX_BINDER
#endif //FEATURE_COMINTEROP
+#ifdef FEATURE_TIERED_COMPILATION
+ m_callCounter.SetTieredCompilationManager(GetTieredCompilationManager());
+ m_tieredCompilationManager.Init(GetId());
+#endif
#endif // CROSSGEN_COMPILE
} // AppDomain::Init
@@ -5405,13 +4521,6 @@ void AppDomain::Terminate()
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_FUSION
- if(m_pAsyncPool != NULL)
- {
- delete m_pAsyncPool;
- m_pAsyncPool = NULL;
- }
-#endif
if (!IsAtProcessExit())
{
@@ -5450,9 +4559,7 @@ void AppDomain::Terminate()
}
ShutdownAssemblies();
-#ifdef FEATURE_CORECLR
ShutdownNativeDllSearchDirectories();
-#endif
if (m_pRefClassFactHash)
{
@@ -5471,16 +4578,10 @@ void AppDomain::Terminate()
BaseDomain::Terminate();
-#ifdef _DEBUG
- if (m_hHandleTableBucket &&
- m_hHandleTableBucket->pTable &&
- ((HandleTable *)(m_hHandleTableBucket->pTable[0]))->uADIndex != m_dwIndex)
- _ASSERTE (!"AD index mismatch");
-#endif // _DEBUG
-
- if (m_hHandleTableBucket) {
- Ref_DestroyHandleTableBucket(m_hHandleTableBucket);
- m_hHandleTableBucket = NULL;
+ if (m_handleStore)
+ {
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleStore(m_handleStore);
+ m_handleStore = NULL;
}
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
@@ -5589,123 +4690,7 @@ OBJECTREF AppDomain::GetExposedObject()
return ref;
}
-#ifndef FEATURE_CORECLR
-void AppDomain::InitializeSorting(OBJECTREF* ppAppdomainSetup)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- THROWS;
- GC_NOTRIGGER;
- PRECONDITION(ppAppdomainSetup == NULL || IsProtectedByGCFrame(ppAppdomainSetup));
- }
- CONTRACTL_END;
-
- DWORD sortVersionFromConfig = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CompatSortNLSVersion);
-
- if(sortVersionFromConfig != 0)
- {
- m_bUseOsSorting = FALSE;
- m_sortVersion = sortVersionFromConfig;
- }
-
- if(ppAppdomainSetup != NULL)
- {
- APPDOMAINSETUPREF adSetup = (APPDOMAINSETUPREF) *ppAppdomainSetup;
- APPDOMAINSORTINGSETUPINFOREF sortingSetup = adSetup->GetAppDomainSortingSetupInfo();
- if(sortingSetup != NULL)
- {
- if(sortingSetup->UseV2LegacySorting() || sortingSetup->UseV4LegacySorting())
- {
-
- m_bUseOsSorting = FALSE;
-
- if(sortingSetup->UseV2LegacySorting())
- {
- m_sortVersion = SORT_VERSION_WHIDBEY;
- }
-
- if(sortingSetup->UseV4LegacySorting())
- {
- m_sortVersion = SORT_VERSION_V4;
- }
- }
- else if(sortingSetup->GetPFNIsNLSDefinedString() != NULL
- && sortingSetup->GetPFNCompareStringEx() != NULL
- && sortingSetup->GetPFNLCMapStringEx() != NULL
- && sortingSetup->GetPFNFindNLSStringEx() != NULL
- && sortingSetup->GetPFNCompareStringOrdinal() != NULL
- && sortingSetup->GetPFNGetNLSVersionEx() != NULL
- && sortingSetup->GetPFNFindStringOrdinal() != NULL)
- {
- m_pCustomSortLibrary = new COMNlsCustomSortLibrary;
- m_pCustomSortLibrary->pIsNLSDefinedString = (PFN_IS_NLS_DEFINED_STRING) sortingSetup->GetPFNIsNLSDefinedString();
- m_pCustomSortLibrary->pCompareStringEx = (PFN_COMPARE_STRING_EX) sortingSetup->GetPFNCompareStringEx();
- m_pCustomSortLibrary->pLCMapStringEx = (PFN_LC_MAP_STRING_EX) sortingSetup->GetPFNLCMapStringEx();
- m_pCustomSortLibrary->pFindNLSStringEx = (PFN_FIND_NLS_STRING_EX) sortingSetup->GetPFNFindNLSStringEx();
- m_pCustomSortLibrary->pCompareStringOrdinal = (PFN_COMPARE_STRING_ORDINAL) sortingSetup->GetPFNCompareStringOrdinal();
- m_pCustomSortLibrary->pGetNLSVersionEx = (PFN_GET_NLS_VERSION_EX) sortingSetup->GetPFNGetNLSVersionEx();
- m_pCustomSortLibrary->pFindStringOrdinal = (PFN_FIND_STRING_ORDINAL) sortingSetup->GetPFNFindStringOrdinal();
- }
- }
- }
-
- if(m_bUseOsSorting == FALSE && m_sortVersion == DEFAULT_SORT_VERSION)
- {
- // If we are using the legacy sorting dlls, the default version for sorting is SORT_VERSION_V4. Note that
- // we don't expect this to change in the future (even when V5 or V6 of the runtime comes out).
- m_sortVersion = SORT_VERSION_V4;
- }
-
- if(RunningOnWin8() && m_bUseOsSorting == FALSE)
- {
- // We need to ensure that the versioned sort DLL could load so we don't crash later. This ensures we have
- // the same behavior as Windows 7, where even if we couldn't load the correct versioned sort dll, we would
- // provide the default sorting behavior.
- INT_PTR sortOrigin;
- if(COMNlsInfo::InternalInitVersionedSortHandle(W(""), &sortOrigin, m_sortVersion) == NULL)
- {
- LOG((LF_APPDOMAIN, LL_WARNING, "AppDomain::InitializeSorting failed to load legacy sort DLL for AppDomain.\n"));
- // We couldn't load a sort DLL. Fall back to default sorting using the OS.
- m_bUseOsSorting = TRUE;
- m_sortVersion = DEFAULT_SORT_VERSION;
- }
- }
-
-#if _DEBUG
- m_bSortingInitialized = TRUE;
-#endif
-}
-#endif
-
-#ifndef FEATURE_CORECLR
-void AppDomain::InitializeHashing(OBJECTREF* ppAppdomainSetup)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- THROWS;
- GC_NOTRIGGER;
- PRECONDITION(ppAppdomainSetup == NULL || IsProtectedByGCFrame(ppAppdomainSetup));
- }
- CONTRACTL_END;
-
- m_pNlsHashProvider = new COMNlsHashProvider;
-
-#ifdef FEATURE_RANDOMIZED_STRING_HASHING
- BOOL fUseRandomizedHashing = (BOOL) CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_UseRandomizedStringHashAlgorithm);
-
- if(ppAppdomainSetup != NULL)
- {
- APPDOMAINSETUPREF adSetup = (APPDOMAINSETUPREF) *ppAppdomainSetup;
- fUseRandomizedHashing |= adSetup->UseRandomizedStringHashing();
- }
-
- m_pNlsHashProvider->SetUseRandomHashing(fUseRandomizedHashing);
-#endif // FEATURE_RANDOMIZED_STRING_HASHING
-}
-#endif // FEATURE_CORECLR
OBJECTREF AppDomain::DoSetup(OBJECTREF* setupInfo)
{
@@ -5733,16 +4718,7 @@ OBJECTREF AppDomain::DoSetup(OBJECTREF* setupInfo)
OBJECTREF activator;
activator=setup.Call_RetOBJECTREF(args);
-#ifdef FEATURE_REMOTING
- if (activator != NULL)
- {
- GCPROTECT_BEGIN(activator);
- retval=AppDomainHelper::CrossContextCopyTo(adid,&activator);
- GCPROTECT_END();
- }
-#else
_ASSERTE(activator==NULL);
-#endif
#if defined(FEATURE_MULTICOREJIT)
// Disable AutoStartProfile in default domain from this code path.
@@ -5949,11 +4925,7 @@ bool IsPlatformAssembly(LPCSTR szName, DomainAssembly *pDomainAssembly)
return false;
}
-#ifdef FEATURE_CORECLR
return StrongNameIsSilverlightPlatformKey(pbPublicKey, cbPublicKey);
-#else
- return StrongNameIsEcmaKey(pbPublicKey, cbPublicKey);
-#endif
}
void AppDomain::AddAssembly(DomainAssembly * assem)
@@ -6047,54 +5019,6 @@ BOOL AppDomain::HasSetSecurityPolicy()
RETURN ((APPDOMAINREF)GetExposedObject())->HasSetPolicy();
}
-#if defined (FEATURE_LOADER_OPTIMIZATION) && !defined(FEATURE_CORECLR)
-// Returns true if the user has declared the desire to load an
-// assembly domain-neutral. This is either by specifying System.LoaderOptimizationAttribute
-// on the entry routine or the host has set this loader-optimization flag.
-BOOL AppDomain::ApplySharePolicy(DomainAssembly *pFile)
-{
- CONTRACT(BOOL)
- {
- PRECONDITION(CheckPointer(pFile));
- THROWS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- if (!pFile->GetFile()->IsShareable())
- RETURN FALSE;
-
- if (ApplySharePolicyFlag(pFile))
- RETURN TRUE;
-
- RETURN FALSE;
-}
-
-BOOL AppDomain::ApplySharePolicyFlag(DomainAssembly *pFile)
-{
- CONTRACT(BOOL)
- {
- PRECONDITION(CheckPointer(pFile));
- THROWS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- switch(GetSharePolicy()) {
- case SHARE_POLICY_ALWAYS:
- RETURN (!pFile->MayHaveUnknownDependencies());
-
- case SHARE_POLICY_GAC:
- RETURN (pFile->IsClosedInGAC());
-
- case SHARE_POLICY_NEVER:
- RETURN pFile->IsSystem();
-
- default:
- UNREACHABLE_MSG("Unknown share policy");
- }
-}
-#endif // FEATURE_LOADER_OPTIMIZATION
EEClassFactoryInfoHashTable* AppDomain::SetupClassFactHash()
{
@@ -6714,7 +5638,6 @@ DomainAssembly* AppDomain::LoadDomainAssembly( AssemblySpec* pSpec,
Exception* pEx=GET_EXCEPTION();
if (!pEx->IsTransient())
{
-#if defined(FEATURE_CORECLR)
// Setup the binder reference in AssemblySpec from the PEAssembly if one is not already set.
ICLRPrivBinder* pCurrentBindingContext = pSpec->GetBindingContext();
ICLRPrivBinder* pBindingContextFromPEAssembly = pFile->GetBindingContext();
@@ -6733,7 +5656,6 @@ DomainAssembly* AppDomain::LoadDomainAssembly( AssemblySpec* pSpec,
_ASSERTE(AreSameBinderInstance(pCurrentBindingContext, pBindingContextFromPEAssembly));
}
#endif // _DEBUG
-#endif // defined(FEATURE_CORECLR)
if (!EEFileLoadException::CheckType(pEx))
{
@@ -6850,109 +5772,6 @@ DomainAssembly *AppDomain::LoadDomainAssemblyInternal(AssemblySpec* pIdentity,
RETURN result;
} // AppDomain::LoadDomainAssembly
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-
-#ifndef CROSSGEN_COMPILE
-// Thread stress
-class LoadDomainModuleStress : APIThreadStress
-{
-public:
- AppDomain *pThis;
- DomainAssembly *pAssembly;
- PEModule *pFile;
- FileLoadLevel targetLevel;
-
- LoadDomainModuleStress(AppDomain *pThis, DomainAssembly *pAssembly, PEModule *pFile, FileLoadLevel targetLevel)
- : pThis(pThis), pAssembly(pAssembly), pFile(pFile), targetLevel(targetLevel) {LIMITED_METHOD_CONTRACT;}
-
- void Invoke()
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_INTOLERANT;
- SetupThread();
- pThis->LoadDomainModule(pAssembly, pFile, targetLevel);
- }
-};
-#endif // CROSSGEN_COMPILE
-
-DomainModule *AppDomain::LoadDomainModule(DomainAssembly *pAssembly, PEModule *pFile,
- FileLoadLevel targetLevel)
-{
- CONTRACT(DomainModule *)
- {
- GC_TRIGGERS;
- THROWS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pAssembly));
- PRECONDITION(CheckPointer(pFile));
- POSTCONDITION(CheckPointer(RETVAL));
- POSTCONDITION(RETVAL->GetLoadLevel() >= GetThreadFileLoadLevel()
- || RETVAL->GetLoadLevel() >= targetLevel);
- POSTCONDITION(RETVAL->CheckNoError(targetLevel));
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- GCX_PREEMP();
-
-#ifndef CROSSGEN_COMPILE
- // Thread stress
- LoadDomainModuleStress ts (this, pAssembly, pFile, targetLevel);
-#endif
-
- // Check for existing fully loaded assembly
- DomainModule *result = pAssembly->FindModule(pFile);
- if (result == NULL)
- {
- LoadLockHolder lock(this);
-
- // Check again in case we were racing
- result = pAssembly->FindModule(pFile);
- if (result == NULL)
- {
- // Find the list lock entry
- FileLoadLock *fileLock = (FileLoadLock *) lock->FindFileLock(pFile);
- if (fileLock == NULL)
- {
- // We are the first one in - create the DomainModule
- NewHolder<DomainModule> pDomainModule(new DomainModule(this, pAssembly, pFile));
- fileLock = FileLoadLock::Create(lock, pFile, pDomainModule);
- pDomainModule.SuppressRelease();
- }
- else
- fileLock->AddRef();
-
- lock.Release();
-
- // We pass our ref on fileLock to LoadDomainFile to release.
-
- // Note that if we throw here, we will poison fileLock with an error condition,
- // so it will not be removed until app domain unload. So there is no need
- // to release our ref count.
-
- result = (DomainModule *) LoadDomainFile(fileLock, targetLevel);
- }
- else
- {
- lock.Release();
- result->EnsureLoadLevel(targetLevel);
- }
-
- }
- else
- result->EnsureLoadLevel(targetLevel);
-
- // Malformed metadata may contain an Assembly reference to what is actually
- // a Module. In this case we need to throw an exception, since returning a
- // DomainAssembly as a DomainModule is a type safety violation.
- if (result->IsAssembly())
- {
- ThrowHR(COR_E_ASSEMBLY_NOT_EXPECTED);
- }
-
- RETURN result;
-}
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
struct LoadFileArgs
{
@@ -7152,16 +5971,6 @@ void AppDomain::TryIncrementalLoad(DomainFile *pFile, FileLoadLevel workLevel, F
EX_TRY
{
-#ifndef FEATURE_CORECLR
- // Event Tracing for Windows is used to log data for performance and functional testing purposes.
- // The events below are used to measure the performance of two steps in the assembly loader, namely assembly initialization and delivering events.
- StackSString ETWAssemblySimpleName;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD))
- {
- LPCUTF8 simpleName = pFile->GetSimpleName();
- ETWAssemblySimpleName.AppendUTF8(simpleName ? simpleName : "NULL"); // Gather data used by ETW events later in this function.
- }
-#endif // FEATURE_CORECLR
// Special case: for LoadLibrary, we cannot hold the lock during the
// actual LoadLibrary call, because we might get a callback from _CorDllMain on any
@@ -7172,28 +5981,10 @@ void AppDomain::TryIncrementalLoad(DomainFile *pFile, FileLoadLevel workLevel, F
lockHolder.Release();
released = TRUE;
}
-#ifndef FEATURE_CORECLR
- else if (workLevel == FILE_LOAD_DELIVER_EVENTS)
- {
- FireEtwLoaderDeliverEventsPhaseStart(GetId().m_dwId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, NULL, ETWAssemblySimpleName, GetClrInstanceId());
- }
-#endif // FEATURE_CORECLR
// Do the work
TESTHOOKCALL(NextFileLoadLevel(GetId().m_dwId,pFile,workLevel));
-#ifndef FEATURE_CORECLR
- if (workLevel == FILE_LOAD_ALLOCATE)
- {
- FireEtwLoaderAssemblyInitPhaseStart(GetId().m_dwId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, NULL, ETWAssemblySimpleName, GetClrInstanceId());
- }
-#endif // FEATURE_CORECLR
BOOL success = pFile->DoIncrementalLoad(workLevel);
-#ifndef FEATURE_CORECLR
- if (workLevel == FILE_LOAD_ALLOCATE)
- {
- FireEtwLoaderAssemblyInitPhaseEnd(GetId().m_dwId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, NULL, ETWAssemblySimpleName, GetClrInstanceId());
- }
-#endif // FEATURE_CORECLR
TESTHOOKCALL(CompletingFileLoadLevel(GetId().m_dwId,pFile,workLevel));
if (released)
{
@@ -7216,9 +6007,6 @@ void AppDomain::TryIncrementalLoad(DomainFile *pFile, FileLoadLevel workLevel, F
lockHolder.Release();
released = TRUE;
pFile->DeliverAsyncEvents();
-#ifndef FEATURE_CORECLR
- FireEtwLoaderDeliverEventsPhaseEnd(GetId().m_dwId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, NULL, ETWAssemblySimpleName, GetClrInstanceId());
-#endif // FEATURE_CORECLR
};
}
}
@@ -7344,19 +6132,8 @@ DomainFile *AppDomain::LoadDomainNeutralModuleDependency(Module *pModule, FileLo
ThrowHR(SECURITY_E_INCOMPATIBLE_SHARE);
}
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- if (pModule == pAssembly->GetManifestModule())
- pDomainFile = pDomainAssembly;
- else
- {
- pDomainFile = LoadDomainModule(pDomainAssembly, (PEModule*) pModule->GetFile(), targetLevel);
- STRESS_LOG4(LF_CLASSLOADER, LL_INFO100,"LDNMD: DF: for %p[%p/%p] is %p",
- pModule,pDomainAssembly,pModule->GetFile(),pDomainFile);
- }
-#else
_ASSERTE (pModule == pAssembly->GetManifestModule());
pDomainFile = pDomainAssembly;
-#endif
}
else
{
@@ -7405,13 +6182,6 @@ void AppDomain::SetSharePolicy(SharePolicy policy)
#ifdef FEATURE_PREJIT
-#ifdef FEATURE_FUSION
- GCX_PREEMP();
-
- // Update the native image config flags
- FusionBind::SetApplicationContextDWORDProperty(m_pFusionContext, ACTAG_ZAP_CONFIG_FLAGS,
- PEFile::GetNativeImageConfigFlags());
-#endif //FEATURE_FUSION
#endif // FEATURE_PREJIT
@@ -7421,49 +6191,6 @@ void AppDomain::SetSharePolicy(SharePolicy policy)
return;
}
-#ifdef FEATURE_FUSION
-BOOL AppDomain::ReduceSharePolicyFromAlways()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- // We may have already committed to always sharing - this is the case if
- // we have already loaded non-GAC-bound assemblies as domain neutral.
-
- if (GetSharePolicy() == SHARE_POLICY_ALWAYS)
- {
- AppDomain::AssemblyIterator i = IterateAssembliesEx((AssemblyIterationFlags)(kIncludeLoaded | kIncludeLoading | kIncludeExecution));
- CollectibleAssemblyHolder<DomainAssembly *> pDomainAssembly;
-
- // If we have loaded any non-GAC assemblies, we cannot set app domain policy as we have
- // already committed to the process-wide policy.
-
- while (i.Next(pDomainAssembly.This()))
- {
- if (pDomainAssembly->GetAssembly() &&
- pDomainAssembly->GetAssembly()->IsDomainNeutral() &&
- !pDomainAssembly->IsClosedInGAC())
- {
- // This assembly has been loaded domain neutral because of SHARE_POLICY_ALWAYS. We
- // can't reverse that decision now, so we have to fail the sharing policy change.
- return FALSE;
- }
- }
-
- // We haven't loaded any non-GAC assemblies yet - scale back to SHARE_POLICY_GAC so
- // future non-GAC assemblies won't be loaded as domain neutral.
- SetSharePolicy(SHARE_POLICY_GAC);
- }
-
- return TRUE;
-}
-#endif // FEATURE_FUSION
AppDomain::SharePolicy AppDomain::GetSharePolicy()
{
@@ -7489,7 +6216,6 @@ AppDomain::SharePolicy AppDomain::GetSharePolicy()
#endif // FEATURE_LOADER_OPTIMIZATION
-#ifdef FEATURE_CORECLR
void AppDomain::CheckForMismatchedNativeImages(AssemblySpec * pSpec, const GUID * pGuid)
{
STANDARD_VM_CONTRACT;
@@ -7555,7 +6281,6 @@ void AppDomain::CheckForMismatchedNativeImages(AssemblySpec * pSpec, const GUID
amTracker.SuppressRelease();
}
}
-#endif // FEATURE_CORECLR
void AppDomain::SetupSharedStatics()
@@ -7671,64 +6396,6 @@ DomainAssembly * AppDomain::FindAssembly(PEAssembly * pFile, FindAssemblyOptions
static const AssemblyIterationFlags STANDARD_IJW_ITERATOR_FLAGS =
(AssemblyIterationFlags)(kIncludeLoaded | kIncludeLoading | kIncludeExecution | kExcludeCollectible);
-#ifdef FEATURE_MIXEDMODE
-Module * AppDomain::GetIJWModule(HMODULE hMod)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- AssemblyIterator i = IterateAssembliesEx(STANDARD_IJW_ITERATOR_FLAGS);
- CollectibleAssemblyHolder<DomainAssembly *> pDomainAssembly;
-
- while (i.Next(pDomainAssembly.This()))
- {
- _ASSERTE(!pDomainAssembly->IsCollectible());
- DomainFile * result = pDomainAssembly->FindIJWModule(hMod);
-
- if (result == NULL)
- continue;
- result->EnsureAllocated();
- return result->GetLoadedModule();
- }
-
- return NULL;
-}
-
-DomainFile * AppDomain::FindIJWDomainFile(HMODULE hMod, const SString & path)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- AssemblyIterator i = IterateAssembliesEx(STANDARD_IJW_ITERATOR_FLAGS);
- CollectibleAssemblyHolder<DomainAssembly *> pDomainAssembly;
-
- while (i.Next(pDomainAssembly.This()))
- {
- _ASSERTE(!pDomainAssembly->IsCollectible());
- if (pDomainAssembly->GetCurrentAssembly() == NULL)
- continue;
-
- DomainFile * result = pDomainAssembly->GetCurrentAssembly()->FindIJWDomainFile(hMod, path);
-
- if (result != NULL)
- return result;
- }
-
- return NULL;
-}
-#endif // FEATURE_MIXEDMODE
void AppDomain::SetFriendlyName(LPCWSTR pwzFriendlyName, BOOL fDebuggerCares/*=TRUE*/)
{
@@ -7928,33 +6595,6 @@ void AppDomain::CacheStringsForDAC()
// If the application base, private bin paths, and configuration file are
// available, cache them so DAC can read them out of memory
//
-#ifdef FEATURE_FUSION
- if (m_pFusionContext)
- {
- CQuickBytes qb;
- LPWSTR ssz = (LPWSTR) qb.AllocThrows(MAX_URL_LENGTH * sizeof(WCHAR));
-
- DWORD dwSize;
-
- // application base
- ssz[0] = '\0';
- dwSize = MAX_URL_LENGTH * sizeof(WCHAR);
- m_pFusionContext->Get(ACTAG_APP_BASE_URL, ssz, &dwSize, 0);
- m_applicationBase.Set(ssz);
-
- // private bin paths
- ssz[0] = '\0';
- dwSize = MAX_URL_LENGTH * sizeof(WCHAR);
- m_pFusionContext->Get(ACTAG_APP_PRIVATE_BINPATH, ssz, &dwSize, 0);
- m_privateBinPaths.Set(ssz);
-
- // configuration file
- ssz[0] = '\0';
- dwSize = MAX_URL_LENGTH * sizeof(WCHAR);
- m_pFusionContext->Get(ACTAG_APP_CONFIG_FILE, ssz, &dwSize, 0);
- m_configFile.Set(ssz);
- }
-#endif // FEATURE_FUSION
}
#ifndef DACCESS_COMPILE
@@ -8009,17 +6649,6 @@ BOOL AppDomain::AddAssemblyToCache(AssemblySpec* pSpec, DomainAssembly *pAssembl
CrstHolder holder(&m_DomainCacheCrst);
// !!! suppress exceptions
BOOL bRetVal = m_AssemblyCache.StoreAssembly(pSpec, pAssembly);
-#ifdef FEATURE_FUSION
- // check for context propagation
- if (bRetVal && pSpec->GetParentLoadContext() == LOADCTX_TYPE_LOADFROM && pAssembly->GetFile()->GetLoadContext() == LOADCTX_TYPE_DEFAULT)
- {
- // LoadFrom propagation occurred, store it in a way reachable by Load() (the "post-policy" one)
- AssemblySpec loadSpec;
- loadSpec.CopyFrom(pSpec);
- loadSpec.SetParentAssembly(NULL);
- bRetVal = m_AssemblyCache.StoreAssembly(&loadSpec, pAssembly);
- }
-#endif
return bRetVal;
}
@@ -8097,13 +6726,11 @@ BOOL AppDomain::IsCached(AssemblySpec *pSpec)
return m_AssemblyCache.Contains(pSpec);
}
-#ifdef FEATURE_CORECLR
void AppDomain::GetCacheAssemblyList(SetSHash<PTR_DomainAssembly>& assemblyList)
{
CrstHolder holder(&m_DomainCacheCrst);
m_AssemblyCache.GetAllAssemblies(assemblyList);
}
-#endif
PEAssembly* AppDomain::FindCachedFile(AssemblySpec* pSpec, BOOL fThrow /*=TRUE*/)
{
@@ -8149,26 +6776,6 @@ BOOL AppDomain::PostBindResolveAssembly(AssemblySpec *pPrePolicySpec,
BOOL fFailure = TRUE;
*ppFailedSpec = pPrePolicySpec;
-#ifdef FEATURE_FUSION
- // Fusion policy could have been applied,
- // so failed assembly could be not exactly what we ordered
-
- IAssemblyName *pIPostPolicyName = pPrePolicySpec->GetNameAfterPolicy();
-
- // Get post-policy assembly name
- if (pIPostPolicyName != NULL)
- {
- pPostPolicySpec->InitializeSpec(pIPostPolicyName,
- NULL,
- pPrePolicySpec->IsIntrospectionOnly());
- pPrePolicySpec->ReleaseNameAfterPolicy();
-
- if (!pPostPolicySpec->CompareEx(pPrePolicySpec))
- {
- *ppFailedSpec = pPostPolicySpec;
- }
- }
-#endif //FEATURE_FUSION
PEAssemblyHolder result;
@@ -8364,19 +6971,6 @@ HRESULT AppDomain::BindAssemblySpecForHostedBinder(
HRESULT hr = S_OK;
-#ifdef FEATURE_FUSION
- StackSString wszAssemblyName;
-
- if (fusion::logging::LoggingEnabled())
- { // Don't perform computation if logging is not enabled.
- FusionBind::GetAssemblyNameDisplayName(pAssemblyName, wszAssemblyName, ASM_DISPLAYF_FULL);
- }
-
- // Fire ETW Start event.
- FireEtwBindingPhaseStart(
- GetId().m_dwId, LOADCTX_TYPE_HOSTED, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable,
- pSpec->m_wszCodeBase, wszAssemblyName.GetUnicode(), GetClrInstanceId());
-#endif
// The Fusion binder can throw (to preserve compat, since it will actually perform an assembly
// load as part of it's bind), so we need to be careful here to catch any FileNotFoundException
@@ -8390,13 +6984,6 @@ HRESULT AppDomain::BindAssemblySpecForHostedBinder(
IfFailRet(BindHostedPrivAssembly(nullptr, pPrivAssembly, pAssemblyName, ppAssembly));
-#ifdef FEATURE_FUSION
- // Fire ETW End event.
- FireEtwBindingPhaseEnd(
- GetId().m_dwId, LOADCTX_TYPE_HOSTED, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable,
- pSpec->m_wszCodeBase, wszAssemblyName.GetUnicode(), GetClrInstanceId());
-
- #endif
return S_OK;
}
@@ -8468,11 +7055,6 @@ AppDomain::BindHostedPrivAssembly(
// Create a PEAssembly using the IL and NI images.
PEAssemblyHolder pPEAssembly = PEAssembly::Open(pParentAssembly, pPEImageIL, pPEImageNI, pPrivAssembly, fIsIntrospectionOnly);
-#ifdef FEATURE_FUSION
- // Ensure that the assembly found can be loaded for execution in the process.
- if (!fIsIntrospectionOnly)
- IfFailRet(RuntimeIsValidAssemblyOnThisPlatform_CheckProcessorArchitecture(pPEAssembly->GetFusionProcessorArchitecture(), FALSE));
-#endif
// Ask the binder to verify.
IfFailRet(VerifyBindHelper(pPrivAssembly, pAssemblyName, pPEAssembly));
@@ -8502,144 +7084,11 @@ PEAssembly * AppDomain::BindAssemblySpec(
BOOL fForceReThrow = FALSE;
-#if defined(FEATURE_APPX_BINDER)
- //
- // If there is a host binder available and this is an unparented bind within the
- // default load context, then the bind will be delegated to the domain-wide host
- // binder. If there is a parent assembly, then a bind will occur only if it has
- // an associated ICLRPrivAssembly to serve as the binder.
- //
- // fUseHostBinderIfAvailable can be false if this method is called by
- // CLRPrivBinderFusion::BindAssemblyByName, which explicitly indicates that it
- // wants to use the fusion binder.
- //
-
- if (AppX::IsAppXProcess() &&
- fUseHostBinderIfAvailable &&
- (
- ( pSpec->HasParentAssembly()
- ? // Parent assembly is hosted
- pSpec->GetParentAssembly()->GetFile()->HasHostAssembly()
- : // Non-parented default context bind
- ( HasLoadContextHostBinder() &&
- !pSpec->IsIntrospectionOnly()
- )
- ) ||
- (pSpec->GetHostBinder() != nullptr)
- )
- )
- {
- HRESULT hr = S_OK;
-
- if (pSpec->GetCodeBase() != nullptr)
- { // LoadFrom is not supported in AppX (we should never even get here)
- IfFailThrow(E_INVALIDARG);
- }
-
- // Get the assembly display name.
- ReleaseHolder<IAssemblyName> pAssemblyName;
- IfFailThrow(pSpec->CreateFusionName(&pAssemblyName, TRUE, TRUE));
-
- // Create new binding scope for fusion logging.
- fusion::logging::BindingScope defaultScope(pAssemblyName, FUSION_BIND_LOG_CATEGORY_DEFAULT);
-
- PEAssemblyHolder pAssembly;
- EX_TRY
- {
- // If there is a specified binder, then it is used.
- // Otherwise if there exist a parent assembly, then it provides the binding context
- // Otherwise the domain's root-level binder is used.
- ICLRPrivBinder * pBinder = nullptr;
-
- if (pSpec->GetHostBinder() != nullptr)
- {
- pBinder = pSpec->GetHostBinder();
- }
- else
- {
- PEAssembly * pParentAssembly =
- (pSpec->GetParentAssembly() == nullptr) ? nullptr : pSpec->GetParentAssembly()->GetFile();
-
- if ((pParentAssembly != nullptr) && (pParentAssembly->HasHostAssembly()))
- {
- BOOL fMustUseOriginalLoadContextBinder = FALSE;
- if (pSpec->IsContentType_WindowsRuntime())
- {
- // Ugly, but we need to handle Framework assemblies that contain WinRT type references,
- // and the Fusion binder won't resolve these in AppX processes. The shareable flag is currently
- // a reasonable proxy for these cases. (It also catches first party WinMD files, but depedencies
- // from those can also be resolved by the original load context binder).
- // TODO! Update the fusion binder to resolve WinMD references correctly.
- IfFailThrow(pParentAssembly->GetHostAssembly()->IsShareable(&fMustUseOriginalLoadContextBinder));
- }
-
- if (fMustUseOriginalLoadContextBinder)
- {
- pBinder = GetLoadContextHostBinder();
- }
- else
- {
- pBinder = pParentAssembly->GetHostAssembly();
- }
- }
- else
- {
- pBinder = GetCurrentLoadContextHostBinder();
- }
- }
- _ASSERTE(pBinder != nullptr);
-
- hr = BindAssemblySpecForHostedBinder(pSpec, pAssemblyName, pBinder, &pAssembly);
- if (FAILED(hr))
- {
- goto EndTry1;
- }
-EndTry1:;
- }
- // The combination of this conditional catch/ the following if statement which will throw reduces the count of exceptions
- // thrown in scenarios where the exception does not escape the method. We cannot get rid of the try/catch block, as
- // there are cases within some of the clrpriv binder's which throw.
- // Note: In theory, FileNotFound should always come here as HRESULT, never as exception.
- EX_CATCH_HRESULT_IF(hr,
- !fThrowOnFileNotFound && Assembly::FileNotFound(hr))
-
- if (FAILED(hr) && (fThrowOnFileNotFound || !Assembly::FileNotFound(hr)))
- {
- if (Assembly::FileNotFound(hr))
- {
- _ASSERTE(fThrowOnFileNotFound);
- // Uses defaultScope
- EEFileLoadException::Throw(pSpec, fusion::logging::GetCurrentFusionBindLog(), hr);
- }
- if ((hr == CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT) && pSpec->IsContentType_WindowsRuntime())
- { // Error returned e.g. for WinRT type name without namespace
- if (fThrowOnFileNotFound)
- { // Throw ArgumentException (with the HRESULT) wrapped by TypeLoadException to give user type name for diagnostics
- // Note: TypeLoadException is equivalent of FileNotFound in WinRT world
- EEMessageException ex(hr);
- EX_THROW_WITH_INNER(EETypeLoadException, (pSpec->GetWinRtTypeNamespace(), pSpec->GetWinRtTypeClassName(), nullptr, nullptr, IDS_EE_WINRT_LOADFAILURE), &ex);
- }
- }
- else
- {
- IfFailThrow(hr);
- }
- }
-
- _ASSERTE((pAssembly != nullptr) || (FAILED(hr) && !fThrowOnFileNotFound));
- return pAssembly.Extract();
- }
- else
-#endif // FEATURE_APPX_BINDER
#if defined(FEATURE_COMINTEROP)
// Handle WinRT assemblies in the classic/hybrid scenario. If this is an AppX process,
// then this case will be handled by the previous block as part of the full set of
// available binding hosts.
-#ifndef FEATURE_APPX_BINDER
if (pSpec->IsContentType_WindowsRuntime())
-#else
- if (!AppX::IsAppXProcess() && pSpec->IsContentType_WindowsRuntime())
-#endif
{
HRESULT hr = S_OK;
@@ -8648,10 +7097,6 @@ EndTry1:;
IfFailThrow(pSpec->CreateFusionName(&pAssemblyName, TRUE, TRUE));
-#ifdef FEATURE_FUSION
- // Create new binding scope for fusion logging.
- fusion::logging::BindingScope defaultScope(pAssemblyName, FUSION_BIND_LOG_CATEGORY_DEFAULT);
-#endif
PEAssemblyHolder pAssembly;
@@ -8675,11 +7120,7 @@ EndTry2:;
{
_ASSERTE(fThrowOnFileNotFound);
// Uses defaultScope
-#ifdef FEATURE_FUSION
- EEFileLoadException::Throw(pSpec, fusion::logging::GetCurrentFusionBindLog(), hr);
-#else
EEFileLoadException::Throw(pSpec, hr);
-#endif // FEATURE_FUSION
}
// WinRT type bind failures
@@ -8719,151 +7160,17 @@ EndTry2:;
HRESULT hrBindResult = S_OK;
PEAssemblyHolder result;
-#if defined(FEATURE_COMINTEROP) && defined(FEATURE_REFLECTION_ONLY_LOAD)
- // We want to keep this holder around to avoid closing and remapping the file again - calls to Fusion further down will open the file again
- ReleaseHolder<IMetaDataAssemblyImport> pMetaDataAssemblyImport;
-
- // Special case ReflectionOnlyLoadFrom on .winmd (WinRT) assemblies
- if (pSpec->IsIntrospectionOnly() && (pSpec->m_wszCodeBase != NULL))
- { // This is a LoadFrom request - we need to find out if it is .winmd file or classic managed assembly
- HRESULT hr = S_OK;
-
- StackSString sPath(pSpec->GetCodeBase());
- PEAssembly::UrlToPath(sPath);
-
- // Open MetaData of the file
- hr = GetAssemblyMDInternalImportEx(
- sPath,
- IID_IMetaDataAssemblyImport,
- MDInternalImport_Default,
- (IUnknown **)&pMetaDataAssemblyImport);
- if (SUCCEEDED(hr))
- {
- DWORD dwAssemblyFlags = 0;
- hr = pMetaDataAssemblyImport->GetAssemblyProps(
- TokenFromRid(1, mdtAssembly),
- nullptr, // ppbPublicKey
- nullptr, // pcbPublicKey
- nullptr, // pulHashAlgId
- nullptr, // szName
- 0, // cchName
- nullptr, // pchName
- nullptr, // pMetaData
- &dwAssemblyFlags);
- if (SUCCEEDED(hr) && IsAfContentType_WindowsRuntime(dwAssemblyFlags))
- { // It is .winmd file
- _ASSERTE(!AppX::IsAppXProcess());
-
- ReleaseHolder<ICLRPrivAssembly> pPrivAssembly;
- ReleaseHolder<PEAssembly> pAssembly;
-
- hr = m_pReflectionOnlyWinRtBinder->BindAssemblyExplicit(sPath, &pPrivAssembly);
- if (SUCCEEDED(hr))
- {
- hr = BindHostedPrivAssembly(nullptr, pPrivAssembly, nullptr, &pAssembly, TRUE);
- _ASSERTE(FAILED(hr) || (pAssembly != nullptr));
- }
- if (FAILED(hr))
- {
- if (fThrowOnFileNotFound)
- {
- ThrowHR(hr);
- }
- return nullptr;
- }
- return pAssembly.Extract();
- }
- }
- }
-#endif //FEATURE_COMINTEROP && FEATURE_REFLECTION_ONLY_LOAD
EX_TRY
{
if (!IsCached(pSpec))
{
-#ifdef FEATURE_FUSION
- if (fRaisePrebindEvents
- && (result = TryResolveAssembly(pSpec, TRUE /*fPreBind*/)) != NULL
- && result->CanUseWithBindingCache())
- {
- // Failure to add simply means someone else beat us to it. In that case
- // the FindCachedFile call below (after catch block) will update result
- // to the cached value.
- AddFileToCache(pSpec, result, TRUE /*fAllowFailure*/);
- }
- else
-#endif
{
bool fAddFileToCache = false;
BOOL fIsWellKnown = FALSE;
-#ifdef FEATURE_FUSION
- SafeComHolderPreemp<IAssembly> pIAssembly;
- SafeComHolderPreemp<IBindResult> pNativeFusionAssembly;
- SafeComHolderPreemp<IHostAssembly> pIHostAssembly;
- SafeComHolderPreemp<IFusionBindLog> pFusionLog;
-
- // Event Tracing for Windows is used to log data for performance and functional testing purposes.
- // The events below are used to measure the performance of assembly binding as a whole.
- FireEtwBindingPhaseStart(GetId().m_dwId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, pSpec->m_wszCodeBase, NULL, GetClrInstanceId());
- fIsWellKnown = pSpec->FindAssemblyFile(this,
- fThrowOnFileNotFound,
- &pIAssembly,
- &pIHostAssembly,
- &pNativeFusionAssembly,
- &pFusionLog,
- &hrBindResult,
- pCallerStackMark,
- pLoadSecurity);
- FireEtwBindingPhaseEnd(GetId().m_dwId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, pSpec->m_wszCodeBase, NULL, GetClrInstanceId());
- if (pIAssembly || pIHostAssembly)
- {
-
- if (fIsWellKnown &&
- m_pRootAssembly &&
- pIAssembly == m_pRootAssembly->GetFusionAssembly())
- {
- // This is a shortcut to avoid opening another copy of the process exe.
- // In fact, we have other similar cases where we've called
- // ExplicitBind() rather than normal binding, which aren't covered here.
-
- // <TODO>@todo: It would be nice to populate the cache with those assemblies
- // to avoid getting in this situation.</TODO>
-
- result = m_pRootAssembly->GetManifestFile();
- result.SuppressRelease(); // Didn't get a refcount
- }
- else
- {
- BOOL isSystemAssembly = pSpec->IsMscorlib(); // can use SystemDomain::m_pSystemAssembly
- BOOL isIntrospectionOnly = pSpec->IsIntrospectionOnly();
- if (pIAssembly)
- result = PEAssembly::Open(pIAssembly, pNativeFusionAssembly, pFusionLog,
- isSystemAssembly, isIntrospectionOnly);
- else
- result = PEAssembly::Open(pIHostAssembly, isSystemAssembly,
- isIntrospectionOnly);
- }
- fAddFileToCache = true;
- }
- else if (!fIsWellKnown)
- {
- // Trigger the resolve event also for non-throw situation.
- // However, this code path will behave as if the resolve handler has thrown,
- // that is, not trigger an MDA.
- _ASSERTE(fThrowOnFileNotFound == FALSE);
-
- AssemblySpec NewSpec(this);
- AssemblySpec *pFailedSpec = NULL;
-
- fForceReThrow = TRUE; // Managed resolve event handler can throw
-
- // Purposly ignore return value
- PostBindResolveAssembly(pSpec, &NewSpec, hrBindResult, &pFailedSpec);
- }
-#else //!FEATURE_FUSION
// Use CoreClr's fusion alternative
CoreBindResult bindResult;
@@ -8886,41 +7193,16 @@ EndTry2:;
}
fAddFileToCache = true;
-#if defined(FEATURE_CORECLR)
// Setup the reference to the binder, which performed the bind, into the AssemblySpec
ICLRPrivBinder* pBinder = result->GetBindingContext();
_ASSERTE(pBinder != NULL);
pSpec->SetBindingContext(pBinder);
-#endif // defined(FEATURE_CORECLR)
}
-#endif //!FEATURE_FUSION
if (fAddFileToCache)
{
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
- // <TODO> PERF: This doesn't scale... </TODO>
- if (pSpec->IsIntrospectionOnly() && (pSpec->GetCodeBase() != NULL))
- {
- IAssemblyName * pIAssemblyName = result->GetFusionAssemblyName();
-
- AppDomain::AssemblyIterator i = IterateAssembliesEx((AssemblyIterationFlags)(
- kIncludeLoaded | kIncludeIntrospection));
- CollectibleAssemblyHolder<DomainAssembly *> pCachedDomainAssembly;
- while (i.Next(pCachedDomainAssembly.This()))
- {
- IAssemblyName * pCachedAssemblyName = pCachedDomainAssembly->GetAssembly()->GetFusionAssemblyName();
- if (pCachedAssemblyName->IsEqual(pIAssemblyName, ASM_CMPF_IL_ALL) == S_OK)
- {
- if (!pCachedDomainAssembly->GetAssembly()->GetManifestModule()->GetFile()->Equals(result))
- {
- COMPlusThrow(kFileLoadException, IDS_EE_REFLECTIONONLY_LOADFROM, pSpec->GetCodeBase());
- }
- }
- }
- }
-#endif //FEATURE_REFLECTION_ONLY_LOAD
if (pSpec->CanUseWithBindingCache() && result->CanUseWithBindingCache())
{
@@ -9086,139 +7368,6 @@ EndTry2:;
} // AppDomain::BindAssemblySpec
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
-DomainAssembly *
-AppDomain::BindAssemblySpecForIntrospectionDependencies(
- AssemblySpec * pSpec)
-{
- STANDARD_VM_CONTRACT;
-
- PRECONDITION(CheckPointer(pSpec));
- PRECONDITION(pSpec->GetAppDomain() == this);
- PRECONDITION(pSpec->IsIntrospectionOnly());
- PRECONDITION(this == ::GetAppDomain());
-
- PEAssemblyHolder result;
- HRESULT hr;
-
- if (!pSpec->HasUniqueIdentity())
- {
- if (!pSpec->HasBindableIdentity())
- {
- COMPlusThrowHR(E_UNEXPECTED);
- }
-
- // In classic (non-AppX), this is initilized by AppDomain constructor
- _ASSERTE(m_pReflectionOnlyWinRtBinder != NULL);
-
- ReleaseHolder<ICLRPrivAssembly> pPrivAssembly;
- hr = m_pReflectionOnlyWinRtBinder->BindWinRtType(
- pSpec->GetWinRtTypeNamespace(),
- pSpec->GetWinRtTypeClassName(),
- pSpec->GetParentAssembly(),
- &pPrivAssembly);
- if (FAILED(hr))
- {
- if (hr == CLR_E_BIND_TYPE_NOT_FOUND)
- { // We could not find the type - throw TypeLoadException to give user type name for diagnostics
- EX_THROW(EETypeLoadException, (pSpec->GetWinRtTypeNamespace(), pSpec->GetWinRtTypeClassName(), nullptr, nullptr, IDS_EE_REFLECTIONONLY_WINRT_LOADFAILURE));
- }
- if (!Exception::IsTransient(hr))
- { // Throw the HRESULT as exception wrapped by TypeLoadException to give user type name for diagnostics
- EEMessageException ex(hr);
- EX_THROW_WITH_INNER(EETypeLoadException, (pSpec->GetWinRtTypeNamespace(), pSpec->GetWinRtTypeClassName(), nullptr, nullptr, IDS_EE_REFLECTIONONLY_WINRT_LOADFAILURE), &ex);
- }
- IfFailThrow(hr);
- }
-
- IfFailThrow(BindHostedPrivAssembly(nullptr, pPrivAssembly, nullptr, &result, TRUE));
- _ASSERTE(result != nullptr);
- return LoadDomainAssembly(pSpec, result, FILE_LOADED);
- }
-
- EX_TRY
- {
- if (!IsCached(pSpec))
- {
- result = TryResolveAssembly(pSpec, TRUE /*fPreBind*/);
- if (result != NULL && result->CanUseWithBindingCache())
- {
- // Failure to add simply means someone else beat us to it. In that case
- // the FindCachedFile call below (after catch block) will update result
- // to the cached value.
- AddFileToCache(pSpec, result, TRUE /*fAllowFailure*/);
- }
- }
- }
- EX_CATCH
- {
- Exception *ex = GET_EXCEPTION();
- AssemblySpec NewSpec(this);
- AssemblySpec *pFailedSpec = NULL;
-
- // Let transient exceptions propagate
- if (ex->IsTransient())
- {
- EX_RETHROW;
- }
-
- // Non-"file not found" exception also propagate
- BOOL fFailure = PostBindResolveAssembly(pSpec, &NewSpec, ex->GetHR(), &pFailedSpec);
- if(fFailure)
- {
- if (AddExceptionToCache(pFailedSpec, ex))
- {
- if ((pFailedSpec == pSpec) && EEFileLoadException::CheckType(ex))
- {
- EX_RETHROW; //preserve the information
- }
- else
- EEFileLoadException::Throw(pFailedSpec, ex->GetHR(), ex);
- }
- }
- }
- EX_END_CATCH(RethrowTerminalExceptions);
-
- result = FindCachedFile(pSpec);
- result.SuppressRelease();
-
-
- if (result)
- {
- // It was either already in the spec cache or the prebind event returned a result.
- return LoadDomainAssembly(pSpec, result, FILE_LOADED);
- }
-
-
- // Otherwise, look in the list of assemblies already loaded for reflectiononly.
- IAssemblyName * ptmp = NULL;
- hr = pSpec->CreateFusionName(&ptmp);
- if (FAILED(hr))
- {
- COMPlusThrowHR(hr);
- }
- SafeComHolder<IAssemblyName> pIAssemblyName(ptmp);
-
- // Note: We do not support introspection-only collectible assemblies (yet)
- AppDomain::AssemblyIterator i = IterateAssembliesEx((AssemblyIterationFlags)(
- kIncludeLoaded | kIncludeIntrospection | kExcludeCollectible));
- CollectibleAssemblyHolder<DomainAssembly *> pCachedDomainAssembly;
-
- while (i.Next(pCachedDomainAssembly.This()))
- {
- _ASSERTE(!pCachedDomainAssembly->IsCollectible());
- IAssemblyName * pCachedAssemblyName = pCachedDomainAssembly->GetAssembly()->GetFusionAssemblyName();
- if (pCachedAssemblyName->IsEqual(pIAssemblyName, ASM_CMPF_IL_ALL) == S_OK)
- {
- return pCachedDomainAssembly;
- }
- }
- // If not found in that list, it is an ERROR. Yes, this is by design.
- StackSString name;
- pSpec->GetFileOrDisplayName(0, name);
- COMPlusThrow(kFileLoadException, IDS_EE_REFLECTIONONLY_LOADFAILURE,name);
-} // AppDomain::BindAssemblySpecForIntrospectionDependencies
-#endif // FEATURE_REFLECTION_ONLY_LOAD
PEAssembly *AppDomain::TryResolveAssembly(AssemblySpec *pSpec, BOOL fPreBind)
{
@@ -9248,85 +7397,6 @@ PEAssembly *AppDomain::TryResolveAssembly(AssemblySpec *pSpec, BOOL fPreBind)
return result;
}
-#ifdef FEATURE_FUSION
-void AppDomain::GetFileFromFusion(IAssembly *pIAssembly, LPCWSTR wszModuleName,
- SString &path)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- INJECT_FAULT(COMPlusThrowOM());
- }
- CONTRACTL_END;
-
- SafeComHolder<IAssemblyModuleImport> pImport;
- IfFailThrow(pIAssembly->GetModuleByName(wszModuleName, &pImport));
-
- if (!pImport->IsAvailable()) {
- AssemblySink* pSink = AllocateAssemblySink(NULL);
- SafeComHolder<IAssemblyBindSink> sinkholder(pSink);
- SafeComHolder<IAssemblyModuleImport> pResult;
-
- IfFailThrow(FusionBind::RemoteLoadModule(GetFusionContext(),
- pImport,
- pSink,
- &pResult));
- pResult->AddRef();
- pImport.Assign(pResult);
- }
-
- DWORD dwPath = 0;
- pImport->GetModulePath(NULL, &dwPath);
-
- LPWSTR buffer = path.OpenUnicodeBuffer(dwPath-1);
- IfFailThrow(pImport->GetModulePath(buffer, &dwPath));
- path.CloseBuffer();
-}
-
-PEAssembly *AppDomain::BindExplicitAssembly(HMODULE hMod, BOOL bindable)
-{
- CONTRACT(PEAssembly *)
- {
- PRECONDITION(CheckPointer(hMod));
- GC_TRIGGERS;
- THROWS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- SafeComHolder<IAssembly> pFusionAssembly;
- SafeComHolder<IBindResult> pNativeFusionAssembly;
- SafeComHolder<IFusionBindLog> pFusionLog;
-
- StackSString path;
- PEImage::GetPathFromDll(hMod, path);
-
- HRESULT hr = ExplicitBind(path, GetFusionContext(),
- bindable ? EXPLICITBIND_FLAGS_EXE : EXPLICITBIND_FLAGS_NON_BINDABLE,
- NULL, &pFusionAssembly, &pNativeFusionAssembly,&pFusionLog);
- if (FAILED(hr))
- EEFileLoadException::Throw(path, hr);
-
- RETURN PEAssembly::OpenHMODULE(hMod, pFusionAssembly,pNativeFusionAssembly, pFusionLog, FALSE);
-}
-
-Assembly *AppDomain::LoadExplicitAssembly(HMODULE hMod, BOOL bindable)
-{
- CONTRACT(Assembly *)
- {
- PRECONDITION(CheckPointer(hMod));
- GC_TRIGGERS;
- THROWS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- PEAssemblyHolder pFile(BindExplicitAssembly(hMod, bindable));
-
- RETURN LoadAssembly(NULL, pFile, FILE_ACTIVE);
-}
-#endif // FEATURE_FUSION
ULONG AppDomain::AddRef()
{
@@ -9356,26 +7426,6 @@ ULONG AppDomain::Release()
return (cRef);
}
-#ifdef FEATURE_FUSION
-AssemblySink* AppDomain::AllocateAssemblySink(AssemblySpec* pSpec)
-{
- CONTRACT(AssemblySink *)
- {
- THROWS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- AssemblySink* ret = FastInterlockExchangePointer(&m_pAsyncPool, NULL);
-
- if(ret == NULL)
- ret = new AssemblySink(this);
- else
- ret->AddRef();
- ret->SetAssemblySpec(pSpec);
- RETURN ret;
-}
-#endif
AppDomain* AppDomain::s_pAppDomainToRaiseUnloadEvent;
BOOL AppDomain::s_fProcessUnloadDomainEvent = FALSE;
@@ -9402,7 +7452,7 @@ void AppDomain::ProcessUnloadDomainEventOnFinalizeThread()
{
CONTRACTL
{
- NOTHROW;
+ THROWS;
GC_TRIGGERS;
MODE_COOPERATIVE;
}
@@ -9439,45 +7489,37 @@ void AppDomain::RaiseUnloadDomainEvent()
{
CONTRACTL
{
- NOTHROW;
+ THROWS;
MODE_COOPERATIVE;
GC_TRIGGERS;
SO_INTOLERANT;
}
CONTRACTL_END;
- EX_TRY
+ Thread *pThread = GetThread();
+ if (this != pThread->GetDomain())
{
- Thread *pThread = GetThread();
- if (this != pThread->GetDomain())
+ pThread->DoADCallBack(this, AppDomain::RaiseUnloadDomainEvent_Wrapper, this,ADV_FINALIZER|ADV_COMPILATION);
+ }
+ else
+ {
+ struct _gc
{
- pThread->DoADCallBack(this, AppDomain::RaiseUnloadDomainEvent_Wrapper, this,ADV_FINALIZER|ADV_COMPILATION);
- }
- else
+ APPDOMAINREF Domain;
+ OBJECTREF Delegate;
+ } gc;
+ ZeroMemory(&gc, sizeof(gc));
+
+ GCPROTECT_BEGIN(gc);
+ gc.Domain = (APPDOMAINREF) GetRawExposedObject();
+ if (gc.Domain != NULL)
{
- struct _gc
- {
- APPDOMAINREF Domain;
- OBJECTREF Delegate;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- gc.Domain = (APPDOMAINREF) GetRawExposedObject();
- if (gc.Domain != NULL)
- {
- gc.Delegate = gc.Domain->m_pDomainUnloadEventHandler;
- if (gc.Delegate != NULL)
- DistributeEventReliably(&gc.Delegate, (OBJECTREF *) &gc.Domain);
- }
- GCPROTECT_END();
+ gc.Delegate = gc.Domain->m_pDomainUnloadEventHandler;
+ if (gc.Delegate != NULL)
+ DistributeEvent(&gc.Delegate, (OBJECTREF *) &gc.Domain);
}
+ GCPROTECT_END();
}
- EX_CATCH
- {
- //@TODO call a MDA here
- }
- EX_END_CATCH(SwallowAllExceptions);
}
void AppDomain::RaiseLoadingAssemblyEvent(DomainAssembly *pAssembly)
@@ -9568,13 +7610,6 @@ BOOL AppDomain::OnUnhandledException(OBJECTREF *pThrowable, BOOL isTerminating/*
orSender = pAppDomain->GetRawExposedObject();
retVal = pAppDomain->RaiseUnhandledExceptionEventNoThrow(&orSender, pThrowable, isTerminating);
-#ifndef FEATURE_CORECLR
-// CoreCLR#520:
-// To make this work correctly we need the changes for coreclr 473
- if (pAppDomain != SystemDomain::System()->DefaultDomain())
- retVal |= SystemDomain::System()->DefaultDomain()->RaiseUnhandledExceptionEventNoThrow
- (&orSender, pThrowable, isTerminating);
-#endif
GCPROTECT_END();
@@ -9603,20 +7638,15 @@ void AppDomain::RaiseOneExitProcessEvent()
} gc;
ZeroMemory(&gc, sizeof(gc));
- EX_TRY {
-
- GCPROTECT_BEGIN(gc);
- gc.Domain = (APPDOMAINREF) SystemDomain::GetCurrentDomain()->GetRawExposedObject();
- if (gc.Domain != NULL)
- {
- gc.Delegate = gc.Domain->m_pProcessExitEventHandler;
- if (gc.Delegate != NULL)
- DistributeEventReliably(&gc.Delegate, (OBJECTREF *) &gc.Domain);
- }
- GCPROTECT_END();
-
- } EX_CATCH {
- } EX_END_CATCH(SwallowAllExceptions);
+ GCPROTECT_BEGIN(gc);
+ gc.Domain = (APPDOMAINREF) SystemDomain::GetCurrentDomain()->GetRawExposedObject();
+ if (gc.Domain != NULL)
+ {
+ gc.Delegate = gc.Domain->m_pProcessExitEventHandler;
+ if (gc.Delegate != NULL)
+ DistributeEvent(&gc.Delegate, (OBJECTREF *) &gc.Domain);
+ }
+ GCPROTECT_END();
}
// Local wrapper used in AppDomain::RaiseExitProcessEvent,
@@ -9625,17 +7655,13 @@ void AppDomain::RaiseOneExitProcessEvent()
// because it calls private RaiseOneExitProcessEvent
/*static*/ void AppDomain::RaiseOneExitProcessEvent_Wrapper(AppDomainIterator* pi)
{
-
STATIC_CONTRACT_MODE_COOPERATIVE;
- STATIC_CONTRACT_NOTHROW;
+ STATIC_CONTRACT_THROWS;
STATIC_CONTRACT_GC_TRIGGERS;
- EX_TRY {
- ENTER_DOMAIN_PTR(pi->GetDomain(),ADV_ITERATOR)
- AppDomain::RaiseOneExitProcessEvent();
- END_DOMAIN_TRANSITION;
- } EX_CATCH {
- } EX_END_CATCH(SwallowAllExceptions);
+ ENTER_DOMAIN_PTR(pi->GetDomain(), ADV_ITERATOR)
+ AppDomain::RaiseOneExitProcessEvent();
+ END_DOMAIN_TRANSITION;
}
static LONG s_ProcessedExitProcessEventCount = 0;
@@ -9652,7 +7678,7 @@ void AppDomain::RaiseExitProcessEvent()
return;
STATIC_CONTRACT_MODE_COOPERATIVE;
- STATIC_CONTRACT_NOTHROW;
+ STATIC_CONTRACT_THROWS;
STATIC_CONTRACT_GC_TRIGGERS;
// Only finalizer thread during shutdown can call this function.
@@ -9670,54 +7696,6 @@ void AppDomain::RaiseExitProcessEvent()
}
}
-#ifndef FEATURE_CORECLR
-void AppDomain::RaiseUnhandledExceptionEvent_Wrapper(LPVOID ptr)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- SO_INTOLERANT;
- }
- CONTRACTL_END;
- AppDomain::RaiseUnhandled_Args *args = (AppDomain::RaiseUnhandled_Args *) ptr;
-
- struct _gc {
- OBJECTREF orThrowable;
- OBJECTREF orSender;
- } gc;
-
- ZeroMemory(&gc, sizeof(gc));
-
- _ASSERTE(args->pTargetDomain == GetAppDomain());
- GCPROTECT_BEGIN(gc);
- EX_TRY
- {
- SetObjectReference(&gc.orThrowable,
- AppDomainHelper::CrossContextCopyFrom(args->pExceptionDomain,
- args->pThrowable),
- args->pTargetDomain);
-
- SetObjectReference(&gc.orSender,
- AppDomainHelper::CrossContextCopyFrom(args->pExceptionDomain,
- args->pSender),
- args->pTargetDomain);
- }
- EX_CATCH
- {
- SetObjectReference(&gc.orThrowable, GET_THROWABLE(), args->pTargetDomain);
- SetObjectReference(&gc.orSender, GetAppDomain()->GetRawExposedObject(), args->pTargetDomain);
- }
- EX_END_CATCH(SwallowAllExceptions)
- *(args->pResult) = args->pTargetDomain->RaiseUnhandledExceptionEvent(&gc.orSender,
- &gc.orThrowable,
- args->isTerminating);
- GCPROTECT_END();
-
-}
-#endif //!FEATURE_CORECLR
BOOL
AppDomain::RaiseUnhandledExceptionEventNoThrow(OBJECTREF *pSender, OBJECTREF *pThrowable, BOOL isTerminating)
@@ -9780,18 +7758,7 @@ AppDomain::RaiseUnhandledExceptionEvent(OBJECTREF *pSender, OBJECTREF *pThrowabl
_ASSERTE(pThrowable != NULL && IsProtectedByGCFrame(pThrowable));
_ASSERTE(pSender != NULL && IsProtectedByGCFrame(pSender));
-#ifndef FEATURE_CORECLR
- Thread *pThread = GetThread();
- if (this != pThread->GetDomain())
- {
- RaiseUnhandled_Args args = {pThread->GetDomain(), this, pSender, pThrowable, isTerminating, &result};
- // call through DoCallBack with a domain transition
- pThread->DoADCallBack(this, AppDomain::RaiseUnhandledExceptionEvent_Wrapper, &args, ADV_DEFAULTAD);
- return result;
- }
-#else
_ASSERTE(this == GetThread()->GetDomain());
-#endif
OBJECTREF orDelegate = NULL;
@@ -9814,48 +7781,6 @@ AppDomain::RaiseUnhandledExceptionEvent(OBJECTREF *pSender, OBJECTREF *pThrowabl
}
-#ifndef FEATURE_CORECLR
-// Create a domain based on a string name
-AppDomain* AppDomain::CreateDomainContext(LPCWSTR fileName)
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- if(fileName == NULL) return NULL;
-
- AppDomain* pDomain = NULL;
-
- MethodDescCallSite valCreateDomain(METHOD__APP_DOMAIN__VAL_CREATE_DOMAIN);
-
- STRINGREF pFilePath = NULL;
- GCPROTECT_BEGIN(pFilePath);
- pFilePath = StringObject::NewString(fileName);
-
- ARG_SLOT args[1] =
- {
- ObjToArgSlot(pFilePath),
- };
-
- APPDOMAINREF pDom = (APPDOMAINREF) valCreateDomain.Call_RetOBJECTREF(args);
- if(pDom != NULL)
- {
- Context* pContext = Context::GetExecutionContext(pDom);
- if(pContext)
- {
- pDomain = pContext->GetDomain();
- }
- }
- GCPROTECT_END();
-
- return pDomain;
-}
-#endif // !FEATURE_CORECLR
#endif // CROSSGEN_COMPILE
@@ -9877,13 +7802,8 @@ void AppDomain::InitializeDomainContext(BOOL allowRedirects,
if (NingenEnabled())
{
-#ifdef FEATURE_FUSION
- CreateFusionContext();
-#endif // FEATURE_FUSION
-#ifdef FEATURE_VERSIONING
CreateFusionContext();
-#endif // FEATURE_VERSIONING
return;
}
@@ -9909,28 +7829,6 @@ void AppDomain::InitializeDomainContext(BOOL allowRedirects,
gc.pConfig = StringObject::NewString(pwszConfig);
}
-#ifndef FEATURE_CORECLR
- StringArrayList *pPropertyNames;
- StringArrayList *pPropertyValues;
- CorHost2::GetDefaultAppDomainProperties(&pPropertyNames, &pPropertyValues);
-
- _ASSERTE(pPropertyNames->GetCount() == pPropertyValues->GetCount());
-
- if (pPropertyNames->GetCount() > 0)
- {
- gc.propertyNames = (PTRARRAYREF)AllocateObjectArray(pPropertyNames->GetCount(), g_pStringClass);
- gc.propertyValues = (PTRARRAYREF)AllocateObjectArray(pPropertyValues->GetCount(), g_pStringClass);
-
- for (DWORD i = 0; i < pPropertyNames->GetCount(); ++i)
- {
- STRINGREF propertyName = StringObject::NewString(pPropertyNames->Get(i));
- gc.propertyNames->SetAt(i, propertyName);
-
- STRINGREF propertyValue = StringObject::NewString(pPropertyValues->Get(i));
- gc.propertyValues->SetAt(i, propertyValue);
- }
- }
-#endif // !FEATURE_CORECLR
if ((gc.ref = GetExposedObject()) != NULL)
{
@@ -9953,226 +7851,7 @@ void AppDomain::InitializeDomainContext(BOOL allowRedirects,
#endif // CROSSGEN_COMPILE
}
-#ifdef FEATURE_FUSION
-
-void AppDomain::SetupLoaderOptimization(DWORD optimization)
-{
- STANDARD_VM_CONTRACT;
- GCX_COOP();
-
- if ((GetExposedObject()) != NULL)
- {
- MethodDescCallSite setupLoaderOptimization(METHOD__APP_DOMAIN__SETUP_LOADER_OPTIMIZATION);
-
- ARG_SLOT args[2] =
- {
- ObjToArgSlot(GetExposedObject()),
- optimization
- };
- setupLoaderOptimization.Call(args);
- }
-}
-
-// The fusion context should only be null when appdomain is being setup
-// and there should be no reason to protect the creation.
-IApplicationContext *AppDomain::CreateFusionContext()
-{
- CONTRACT(IApplicationContext *)
- {
- GC_TRIGGERS;
- THROWS;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- if (m_pFusionContext == NULL)
- {
- ETWOnStartup (FusionAppCtx_V1, FusionAppCtxEnd_V1);
-
- GCX_PREEMP();
-
- SafeComHolderPreemp<IApplicationContext> pFusionContext;
-
- IfFailThrow(FusionBind::CreateFusionContext(NULL, &pFusionContext));
-
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
- CLRPrivBinderWinRT * pWinRtBinder;
- if (AppX::IsAppXProcess())
- { // Note: Fusion binder is used in AppX to bind .NET Fx assemblies - some of them depend on .winmd files (e.g. System.Runtime.WindowsRuntime.dll)
- CLRPrivBinderAppX * pAppXBinder = CLRPrivBinderAppX::GetOrCreateBinder();
- pWinRtBinder = pAppXBinder->GetWinRtBinder();
- }
- else
- {
- pWinRtBinder = m_pWinRtBinder;
- }
- _ASSERTE(pWinRtBinder != nullptr);
-
- IfFailThrow(SetApplicationContext_WinRTBinder(
- pFusionContext,
- static_cast<IBindContext *>(pWinRtBinder)));
-#endif
-
-#ifdef FEATURE_PREJIT
- if (NGENImagesAllowed())
- {
- // Set the native image settings so fusion will bind native images
- SString zapString(g_pConfig->ZapSet());
- FusionBind::SetApplicationContextStringProperty(pFusionContext, ACTAG_ZAP_STRING, zapString);
- FusionBind::SetApplicationContextDWORDProperty(pFusionContext, ACTAG_ZAP_CONFIG_FLAGS,
- PEFile::GetNativeImageConfigFlags());
- }
-#endif // FEATURE_PREJIT
-
- pFusionContext.SuppressRelease();
- m_pFusionContext = pFusionContext;
-
- DWORD dwId = m_dwId.m_dwId;
- IfFailThrow(m_pFusionContext->Set(ACTAG_APP_DOMAIN_ID, &dwId, sizeof(DWORD), 0));
-
- if (HasLoadContextHostBinder())
- FusionBind::SetApplicationContextDWORDProperty(pFusionContext, ACTAG_FX_ONLY,1);
-
- }
-
- RETURN m_pFusionContext;
-}
-
-void AppDomain::TurnOnBindingRedirects()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
-
- if ((GetExposedObject()) != NULL)
- {
- MethodDescCallSite turnOnBindingRedirects(METHOD__APP_DOMAIN__TURN_ON_BINDING_REDIRECTS);
- ARG_SLOT args[1] =
- {
- ObjToArgSlot(GetExposedObject()),
- };
- turnOnBindingRedirects.Call(args);
- }
-
- IfFailThrow(m_pFusionContext->Set(ACTAG_DISALLOW_APP_BINDING_REDIRECTS,
- NULL,
- 0,
- 0));
-}
-
-void AppDomain::SetupExecutableFusionContext(LPCWSTR exePath)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(GetAppDomain() == this);
- }
- CONTRACTL_END;
-
- GCX_COOP();
-
- struct _gc {
- STRINGREF pFilePath;
- OBJECTREF ref;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- gc.pFilePath = StringObject::NewString(exePath);
-
- if ((gc.ref = GetExposedObject()) != NULL)
- {
- MethodDescCallSite setDomainContext(METHOD__APP_DOMAIN__SET_DOMAIN_CONTEXT, &gc.ref);
- ARG_SLOT args[2] =
- {
- ObjToArgSlot(gc.ref),
- ObjToArgSlot(gc.pFilePath),
- };
- setDomainContext.Call(args);
- }
-
- GCPROTECT_END();
-
-}
-
-BOOL AppDomain::SetContextProperty(IApplicationContext* pFusionContext,
- LPCWSTR pProperty, OBJECTREF* obj)
-
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- if (GetAppDomain()->HasLoadContextHostBinder())
- COMPlusThrow(kNotSupportedException);
-
-
- if(obj) {
- if ((*obj) != NULL){
- MethodTable* pMT = (*obj)->GetMethodTable();
- DWORD lgth;
-
- if(MscorlibBinder::IsClass(pMT, CLASS__STRING)) {
-
- lgth = (ObjectToSTRINGREF(*(StringObject**)obj))->GetStringLength();
- CQuickBytes qb;
- LPWSTR wszValue = (LPWSTR) qb.AllocThrows((lgth+1)*sizeof(WCHAR));
- memcpy(wszValue, (ObjectToSTRINGREF(*(StringObject**)obj))->GetBuffer(), lgth*sizeof(WCHAR));
- if(lgth > 0 && wszValue[lgth-1] == '/')
- lgth--;
- wszValue[lgth] = W('\0');
-
- LOG((LF_LOADER,
- LL_INFO10,
- "Set: %S: *%S*.\n",
- pProperty, wszValue));
-
- IfFailThrow(pFusionContext->Set(pProperty,
- wszValue,
- (lgth+1) * sizeof(WCHAR),
- 0));
- }
- else {
- // Pin byte array for loading
- Wrapper<OBJECTHANDLE, DoNothing, DestroyPinningHandle> handle(
- GetAppDomain()->CreatePinningHandle(*obj));
-
- const BYTE *pbArray = ((U1ARRAYREF)(*obj))->GetDirectConstPointerToNonObjectElements();
- DWORD cbArray = (*obj)->GetNumComponents();
-
- IfFailThrow(pFusionContext->Set(pProperty,
- (LPVOID) pbArray,
- cbArray,
- 0));
- }
- }
- else { // Un-set the property
- IfFailThrow(pFusionContext->Set(pProperty,
- NULL,
- 0,
- 0));
- }
- }
-
- return TRUE;
-}
-#endif // FEATURE_FUSION
-
-#ifdef FEATURE_VERSIONING
IUnknown *AppDomain::CreateFusionContext()
{
CONTRACT(IUnknown *)
@@ -10196,59 +7875,14 @@ IUnknown *AppDomain::CreateFusionContext()
IfFailThrow(CCoreCLRBinderHelper::DefaultBinderSetupContext(GetId().m_dwId, &pTPABinder));
m_pFusionContext = reinterpret_cast<IUnknown *>(pTPABinder);
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
// By default, initial binding context setup for CoreCLR is also the TPABinding context
(m_pTPABinderContext = pTPABinder)->AddRef();
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
}
RETURN m_pFusionContext;
}
-#endif // FEATURE_VERSIONING
-#ifdef FEATURE_FUSION
-LPWSTR AppDomain::GetDynamicDir()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- if (m_pwDynamicDir == NULL) {
-
- BaseDomain::LockHolder lh(this);
-
- if(m_pwDynamicDir == NULL) {
- IApplicationContext* pFusionContext = GetFusionContext();
- _ASSERTE(pFusionContext);
-
- HRESULT hr = S_OK;
- DWORD dwSize = 0;
- hr = pFusionContext->GetDynamicDirectory(NULL, &dwSize);
- AllocMemHolder<WCHAR> tempDynamicDir;
-
- if(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
- tempDynamicDir = GetLowFrequencyHeap()->AllocMem(S_SIZE_T(dwSize) * S_SIZE_T(sizeof(WCHAR)));
- hr = pFusionContext->GetDynamicDirectory(tempDynamicDir, &dwSize);
- }
- if(hr==HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
- return NULL;
- IfFailThrow(hr);
-
- tempDynamicDir.SuppressRelease();
- m_pwDynamicDir = tempDynamicDir;
- }
- // lh out of scope here
- }
-
- return m_pwDynamicDir;;
-}
-#endif //FEATURE_FUSION
//---------------------------------------------------------------------------------------
@@ -10597,6 +8231,18 @@ void AppDomain::Exit(BOOL fRunFinalizers, BOOL fAsyncExit)
}
}
+ // Tell the tiered compilation manager to stop initiating any new work for background
+ // jit optimization. Its possible the standard thread unwind mechanisms would pre-emptively
+ // evacuate the jit threadpool worker threads from the domain on their own, but I see no reason
+ // to take the risk of relying on them when we can easily augment with a cooperative
+ // shutdown check. This notification only initiates the process of evacuating the threads
+ // and then the UnwindThreads() call below is where blocking will occur to ensure the threads
+ // have exited the domain.
+ //
+#ifdef FEATURE_TIERED_COMPILATION
+ m_tieredCompilationManager.OnAppDomainShutdown();
+#endif
+
//
// Set up blocks so no threads can enter except for the finalizer and the thread
// doing the unload.
@@ -10712,22 +8358,6 @@ void AppDomain::Exit(BOOL fRunFinalizers, BOOL fAsyncExit)
//
if (!NingenEnabled())
{
-#ifdef FEATURE_REMOTING
- EX_TRY
- {
- ADID domainId = GetId();
- MethodDescCallSite domainUnloaded(METHOD__REMOTING_SERVICES__DOMAIN_UNLOADED);
-
- ARG_SLOT args[1];
- args[0] = domainId.m_dwId;
- domainUnloaded.Call(args);
- }
- EX_CATCH
- {
- //we don't care if it fails
- }
- EX_END_CATCH(SwallowAllExceptions);
-#endif // FEATURE_REMOTING
}
ClearGCRoots();
@@ -11308,12 +8938,6 @@ BOOL AppDomain::StopEEAndUnwindThreads(unsigned int retryCount, BOOL *pFMarkUnlo
}
} // ThreadStoreLockHolder
- if (nThreadsNeedMoreWork && CLRTaskHosted())
- {
- // In case a thread is the domain is blocked due to its scheduler being
- // occupied by another thread.
- Thread::ThreadAbortWatchDog();
- }
m_dwThreadsStillInAppDomain=nThreadsNeedMoreWork;
return !nThreadsNeedMoreWork;
}
@@ -11574,14 +9198,7 @@ void AppDomain::ClearGCHandles()
HandleAsyncPinHandles();
// Remove our handle table as a source of GC roots
- HandleTableBucket *pBucket = m_hHandleTableBucket;
-
-#ifdef _DEBUG
- if (((HandleTable *)(pBucket->pTable[0]))->uADIndex != m_dwIndex)
- _ASSERTE (!"AD index mismatch");
-#endif // _DEBUG
-
- Ref_RemoveHandleTableBucket(pBucket);
+ GCHandleTableUtilities::GetGCHandleTable()->UprootHandleStore(m_handleStore);
}
// When an AD is unloaded, we will release all objects in this AD.
@@ -11597,13 +9214,17 @@ void AppDomain::HandleAsyncPinHandles()
}
CONTRACTL_END;
- HandleTableBucket *pBucket = m_hHandleTableBucket;
+ // TODO: Temporarily casting stuff here until Ref_RelocateAsyncPinHandles is moved to the interface.
+ HandleTableBucket *pBucket = (HandleTableBucket*)m_handleStore;
+
// IO completion port picks IO job using FIFO. Here is how we know which AsyncPinHandle can be freed.
// 1. We mark all non-pending AsyncPinHandle with READYTOCLEAN.
// 2. We queue a dump Overlapped to the IO completion as a marker.
// 3. When the Overlapped is picked up by completion port, we wait until all previous IO jobs are processed.
// 4. Then we can delete all AsyncPinHandle marked with READYTOCLEAN.
- HandleTableBucket *pBucketInDefault = SystemDomain::System()->DefaultDomain()->m_hHandleTableBucket;
+ HandleTableBucket *pBucketInDefault = (HandleTableBucket*)SystemDomain::System()->DefaultDomain()->m_handleStore;
+
+ // TODO: When this function is moved to the interface it will take void*s
Ref_RelocateAsyncPinHandles(pBucket, pBucketInDefault);
OverlappedDataObject::RequestCleanup();
@@ -11626,17 +9247,15 @@ void AppDomain::ClearGCRoots()
// this point, so only need to synchronize the preemptive mode threads.
ExecutionManager::Unload(GetLoaderAllocator());
+ IGCHandleTable* pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
+
while ((pThread = ThreadStore::GetAllThreadList(pThread, 0, 0)) != NULL)
{
// Delete the thread local static store
pThread->DeleteThreadStaticData(this);
-#ifdef FEATURE_LEAK_CULTURE_INFO
- pThread->ResetCultureForDomain(GetId());
-#endif // FEATURE_LEAK_CULTURE_INFO
-
// <TODO>@TODO: A pre-allocated AppDomainUnloaded exception might be better.</TODO>
- if (m_hHandleTableBucket->Contains(pThread->m_LastThrownObjectHandle))
+ if (pHandleTable->ContainsHandle(m_handleStore, pThread->m_LastThrownObjectHandle))
{
// Never delete a handle to a preallocated exception object.
if (!CLRException::IsPreallocatedExceptionHandle(pThread->m_LastThrownObjectHandle))
@@ -11648,7 +9267,7 @@ void AppDomain::ClearGCRoots()
}
// Clear out the exceptions objects held by a thread.
- pThread->GetExceptionState()->ClearThrowablesForUnload(m_hHandleTableBucket);
+ pThread->GetExceptionState()->ClearThrowablesForUnload(m_handleStore);
}
//delete them while we still have the runtime suspended
@@ -11798,25 +9417,6 @@ end:
}
#endif // _DEBUG
-#ifdef FEATURE_REMOTING
-OBJECTREF AppDomain::GetAppDomainProxy()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- OBJECTREF orProxy = CRemotingServices::CreateProxyForDomain(this);
-
- _ASSERTE(orProxy->IsTransparentProxy());
-
- return orProxy;
-}
-#endif
#endif // CROSSGEN_COMPILE
@@ -12534,25 +10134,6 @@ AppDomain::RaiseAssemblyResolveEvent(
StackSString ssName;
pSpec->GetFileOrDisplayName(0, ssName);
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
- if ( (!fIntrospection) && (!fPreBind) )
- {
- methodId = METHOD__APP_DOMAIN__ON_ASSEMBLY_RESOLVE; // post-bind execution event (the classic V1.0 event)
- }
- else if ((!fIntrospection) && fPreBind)
- {
- RETURN NULL; // There is currently no prebind execution resolve event
- }
- else if (fIntrospection && !fPreBind)
- {
- RETURN NULL; // There is currently no post-bind introspection resolve event
- }
- else
- {
- _ASSERTE( fIntrospection && fPreBind );
- methodId = METHOD__APP_DOMAIN__ON_REFLECTION_ONLY_ASSEMBLY_RESOLVE; // event for introspection assemblies
- }
-#else // FEATURE_REFLECTION_ONLY_LOAD
if (!fPreBind)
{
methodId = METHOD__APP_DOMAIN__ON_ASSEMBLY_RESOLVE; // post-bind execution event (the classic V1.0 event)
@@ -12562,7 +10143,6 @@ AppDomain::RaiseAssemblyResolveEvent(
RETURN NULL;
}
-#endif // FEATURE_REFLECTION_ONLY_LOAD
// Elevate threads allowed loading level. This allows the host to load an assembly even in a restricted
// condition. Note, however, that this exposes us to possible recursion failures, if the host tries to
@@ -12587,13 +10167,6 @@ AppDomain::RaiseAssemblyResolveEvent(
{
if (pSpec->GetParentAssembly() != NULL)
{
-#ifndef FEATURE_CORECLR
- if ( pSpec->IsIntrospectionOnly()
-#ifdef FEATURE_FUSION
- || pSpec->GetParentLoadContext() == LOADCTX_TYPE_UNKNOWN
-#endif
- )
-#endif // FEATURE_CORECLR
{
gc.AssemblyRef=pSpec->GetParentAssembly()->GetExposedAssemblyObject();
}
@@ -12636,68 +10209,6 @@ AppDomain::RaiseAssemblyResolveEvent(
RETURN pAssembly;
} // AppDomain::RaiseAssemblyResolveEvent
-#ifndef FEATURE_CORECLR
-
-//---------------------------------------------------------------------------------------
-//
-// Ask the AppDomainManager for the entry assembly of the application
-//
-// Note:
-// Most AppDomainManagers will fall back on the root assembly for the domain, so we need
-// to make sure this is set before we call through to the AppDomainManager itself.
-//
-
-Assembly *AppDomain::GetAppDomainManagerEntryAssembly()
-{
- CONTRACT(Assembly *)
- {
- STANDARD_VM_CHECK;
- PRECONDITION(HasAppDomainManagerInfo());
- PRECONDITION(CheckPointer(m_pRootAssembly));
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- GCX_COOP();
-
- Assembly *pEntryAssembly = NULL;
-
- struct
- {
- APPDOMAINREF orDomain;
- OBJECTREF orAppDomainManager;
- ASSEMBLYREF orEntryAssembly;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.orDomain = static_cast<APPDOMAINREF>(GetExposedObject());
- gc.orAppDomainManager = gc.orDomain->GetAppDomainManager();
- _ASSERTE(gc.orAppDomainManager != NULL);
-
- MethodDescCallSite getEntryAssembly(METHOD__APPDOMAIN_MANAGER__GET_ENTRY_ASSEMBLY, &gc.orAppDomainManager);
- ARG_SLOT argThis = ObjToArgSlot(gc.orAppDomainManager);
- gc.orEntryAssembly = static_cast<ASSEMBLYREF>(getEntryAssembly.Call_RetOBJECTREF(&argThis));
-
- if (gc.orEntryAssembly != NULL)
- {
- pEntryAssembly = gc.orEntryAssembly->GetAssembly();
- }
-
- GCPROTECT_END();
-
- // If the AppDomainManager did not return an entry assembly, we'll assume the default assembly
- if (pEntryAssembly == NULL)
- {
- pEntryAssembly = m_pRootAssembly;
- }
-
- RETURN(pEntryAssembly);
-}
-
-#endif // !FEATURE_CORECLR
//---------------------------------------------------------------------------------------
//
@@ -12740,45 +10251,6 @@ void AppDomain::InitializeDefaultDomainManager()
LOG((LF_APPDOMAIN, LL_INFO10, "Setting default AppDomainManager '%S', '%S' from hosting API.\n", GetAppDomainManagerAsm(), GetAppDomainManagerType()));
}
-#ifndef FEATURE_CORECLR
- else
- {
- CLRConfigStringHolder wszConfigAppDomainManagerAssembly(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_AppDomainManagerAsm));
- CLRConfigStringHolder wszConfigAppDomainManagerType(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_AppDomainManagerType));
-
- if (wszConfigAppDomainManagerAssembly != NULL &&
- wszConfigAppDomainManagerType != NULL)
- {
- SetAppDomainManagerInfo(wszConfigAppDomainManagerAssembly,
- wszConfigAppDomainManagerType,
- eInitializeNewDomainFlags_None);
- m_fAppDomainManagerSetInConfig = TRUE;
-
- LOG((LF_APPDOMAIN, LL_INFO10, "Setting default AppDomainManager '%S', '%S' from application config file.\n", GetAppDomainManagerAsm(), GetAppDomainManagerType()));
- }
- else
- {
- CLRConfigStringHolder wszEnvironmentAppDomainManagerAssembly(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_LEGACY_APPDOMAIN_MANAGER_ASM));
- CLRConfigStringHolder wszEnvironmentAppDomainManagerType(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_LEGACY_APPDOMAIN_MANAGER_TYPE));
-
- if (wszEnvironmentAppDomainManagerAssembly != NULL &&
- wszEnvironmentAppDomainManagerType != NULL)
- {
- SetAppDomainManagerInfo(wszEnvironmentAppDomainManagerAssembly,
- wszEnvironmentAppDomainManagerType,
- eInitializeNewDomainFlags_None);
- m_fAppDomainManagerSetInConfig = FALSE;
-
- LOG((LF_APPDOMAIN, LL_INFO10, "Setting default AppDomainManager '%S', '%S' from environment variables.\n", GetAppDomainManagerAsm(), GetAppDomainManagerType()));
-
- // Reset the environmetn variables so that child processes do not inherit our domain manager
- // by default.
- WszSetEnvironmentVariable(CLRConfig::EXTERNAL_LEGACY_APPDOMAIN_MANAGER_ASM.name, NULL);
- WszSetEnvironmentVariable(CLRConfig::EXTERNAL_LEGACY_APPDOMAIN_MANAGER_TYPE.name, NULL);
- }
- }
- }
-#endif // !FEATURE_CORECLR
// If we found an AppDomain manager to use, create and initialize it
// Otherwise, initialize the config flags.
@@ -12824,102 +10296,6 @@ void AppDomain::InitializeDefaultDomainManager()
}
}
-#ifdef FEATURE_CLICKONCE
-
-//---------------------------------------------------------------------------------------
-//
-// If we are launching a ClickOnce application, setup the default domain with the deails
-// of the application.
-//
-
-void AppDomain::InitializeDefaultClickOnceDomain()
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- PRECONDITION(GetId().m_dwId == DefaultADID);
- }
- CONTRACTL_END;
-
- //
- // If the CLR is being started to run a ClickOnce application, then capture the information about the
- // application to setup the default domain wtih.
- //
-
- if (CorCommandLine::m_pwszAppFullName != NULL)
- {
- struct
- {
- OBJECTREF orThis;
- STRINGREF orAppFullName;
- PTRARRAYREF orManifestPathsArray;
- PTRARRAYREF orActivationDataArray;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.orAppFullName = StringObject::NewString(CorCommandLine::m_pwszAppFullName);
-
- // If specific manifests have been pointed at, make a note of them
- if (CorCommandLine::m_dwManifestPaths > 0)
- {
- _ASSERTE(CorCommandLine::m_ppwszManifestPaths != NULL);
-
- gc.orManifestPathsArray = static_cast<PTRARRAYREF>(AllocateObjectArray(CorCommandLine::m_dwManifestPaths, g_pStringClass));
- for (DWORD i = 0; i < CorCommandLine::m_dwManifestPaths; ++i)
- {
- STRINGREF str = StringObject::NewString(CorCommandLine::m_ppwszManifestPaths[i]);
- gc.orManifestPathsArray->SetAt(i, str);
- }
- }
-
- // Check for any activation parameters to pass to the ClickOnce application
- if (CorCommandLine::m_dwActivationData > 0)
- {
- _ASSERTE(CorCommandLine::m_ppwszActivationData != NULL);
-
- gc.orActivationDataArray = static_cast<PTRARRAYREF>(AllocateObjectArray(CorCommandLine::m_dwActivationData, g_pStringClass));
- for (DWORD i = 0; i < CorCommandLine::m_dwActivationData; ++i)
- {
- STRINGREF str = StringObject::NewString(CorCommandLine::m_ppwszActivationData[i]);
- gc.orActivationDataArray->SetAt(i, str);
- }
- }
-
- gc.orThis = GetExposedObject();
-
- MethodDescCallSite setupDefaultClickOnceDomain(METHOD__APP_DOMAIN__SETUP_DEFAULT_CLICKONCE_DOMAIN);
- ARG_SLOT args[] =
- {
- ObjToArgSlot(gc.orThis),
- ObjToArgSlot(gc.orAppFullName),
- ObjToArgSlot(gc.orManifestPathsArray),
- ObjToArgSlot(gc.orActivationDataArray),
- };
- setupDefaultClickOnceDomain.Call(args);
-
- GCPROTECT_END();
- }
-}
-
-BOOL AppDomain::IsClickOnceAppDomain()
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END;
-
- return ((APPDOMAINREF)GetExposedObject())->HasActivationContext();
-}
-
-#endif // FEATURE_CLICKONCE
//---------------------------------------------------------------------------------------
//
@@ -12962,11 +10338,9 @@ void AppDomain::CreateADUnloadWorker()
{
STANDARD_VM_CONTRACT;
-#ifdef FEATURE_CORECLR
// Do not create adUnload thread if there is only default domain
if(IsSingleAppDomain())
return;
-#endif
Retry:
BOOL fCreator = FALSE;
@@ -13228,24 +10602,6 @@ DWORD WINAPI AppDomain::ADUnloadThreadStart(void *args)
{
GCX_MAYBE_PREEMP(fOK);
- if (fOK)
- {
- EX_TRY
- {
- if (CLRTaskHosted())
- {
- // ADUnload helper thread is critical. We do not want it to share scheduler
- // with other tasks.
- pThread->LeaveRuntime(0);
- }
- }
- EX_CATCH
- {
- fOK = false;
- }
- EX_END_CATCH(SwallowAllExceptions);
- }
-
_ASSERTE (g_fADUnloadWorkerOK == -2);
FastInterlockExchange((LONG *)&g_fADUnloadWorkerOK,fOK?1:-1);
@@ -13820,95 +11176,6 @@ PTR_MethodTable BaseDomain::LookupType(UINT32 id) {
#ifndef DACCESS_COMPILE
-#ifndef FEATURE_CORECLR
-//------------------------------------------------------------------------
-DWORD* SetupCompatibilityFlags()
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- } CONTRACTL_END;
-
- LPCWSTR buf;
- bool return_null = true;
-
- FAULT_NOT_FATAL(); // we can simply give up
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return NULL;)
- InlineSString<4> bufString;
-
- if (WszGetEnvironmentVariable(W("UnsupportedCompatSwitchesEnabled"), bufString) != 0)
- {
- buf = bufString.GetUnicode();
- if (buf[0] != '1' || buf[1] != '\0')
- {
- return_null = true;
- }
- else
- {
- return_null = false;
- }
-
- }
- END_SO_INTOLERANT_CODE
-
- if (return_null)
- return NULL;
-
- static const LPCWSTR rgFlagNames[] = {
-#define COMPATFLAGDEF(name) TEXT(#name),
-#include "compatibilityflagsdef.h"
- };
-
- int size = (compatCount+31) / 32;
- DWORD* pFlags = new (nothrow) DWORD[size];
- if (pFlags == NULL)
- return NULL;
- ZeroMemory(pFlags, size * sizeof(DWORD));
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(SetLastError(COR_E_STACKOVERFLOW); return NULL;)
- InlineSString<4> bufEnvString;
- for (int i = 0; i < COUNTOF(rgFlagNames); i++)
- {
- if (WszGetEnvironmentVariable(rgFlagNames[i], bufEnvString) == 0)
- continue;
-
- buf = bufEnvString.GetUnicode();
- if (buf[0] != '1' || buf[1] != '\0')
- continue;
-
- pFlags[i / 32] |= 1 << (i % 32);
- }
- END_SO_INTOLERANT_CODE
-
- return pFlags;
-}
-
-//------------------------------------------------------------------------
-static VolatilePtr<DWORD> g_pCompatibilityFlags = (DWORD*)(-1);
-
-DWORD* GetGlobalCompatibilityFlags()
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- } CONTRACTL_END;
-
- if (g_pCompatibilityFlags == (DWORD*)(-1))
- {
- DWORD *pCompatibilityFlags = SetupCompatibilityFlags();
-
- if (FastInterlockCompareExchangePointer(g_pCompatibilityFlags.GetPointer(), pCompatibilityFlags, reinterpret_cast<DWORD *>(-1)) != (VOID*)(-1))
- {
- delete [] pCompatibilityFlags;
- }
- }
-
- return g_pCompatibilityFlags;
-}
-#endif // !FEATURE_CORECLR
//------------------------------------------------------------------------
BOOL GetCompatibilityFlag(CompatibilityFlag flag)
@@ -13919,16 +11186,7 @@ BOOL GetCompatibilityFlag(CompatibilityFlag flag)
SO_TOLERANT;
} CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- DWORD *pFlags = GetGlobalCompatibilityFlags();
-
- if (pFlags != NULL)
- return (pFlags[flag / 32] & (1 << (flag % 32))) ? TRUE : FALSE;
- else
- return FALSE;
-#else // !FEATURE_CORECLR
return FALSE;
-#endif // !FEATURE_CORECLR
}
#endif // !DACCESS_COMPILE
@@ -14127,7 +11385,6 @@ AppDomain::AssemblyIterator::Next_UnsafeNoAddRef(
return FALSE;
} // AppDomain::AssemblyIterator::Next_UnsafeNoAddRef
-#ifdef FEATURE_CORECLR
//---------------------------------------------------------------------------------------
//
@@ -14165,11 +11422,10 @@ BOOL AppDomain::IsImageFullyTrusted(PEImage* pPEImage)
return IsImageFromTrustedPath(pPEImage);
}
-#endif //FEATURE_CORECLR
#endif //!DACCESS_COMPILE
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
// Returns a BOOL indicating if the binding model has been locked for the AppDomain
BOOL AppDomain::IsBindingModelLocked()
@@ -14411,7 +11667,7 @@ HRESULT RuntimeInvokeHostAssemblyResolver(INT_PTR pManagedAssemblyLoadContextToB
return hr;
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
//approximate size of loader data
//maintained for each assembly
@@ -14735,10 +11991,6 @@ void AppDomain::PublishHostedAssembly(
}
else
{
-#ifdef FEATURE_APPX_BINDER
- // In AppX processes, all PEAssemblies that are reach this stage should have host binders.
- _ASSERTE(!AppX::IsAppXProcess());
-#endif
}
}
@@ -14806,10 +12058,6 @@ void AppDomain::UpdatePublishHostedAssembly(
}
else
{
-#ifdef FEATURE_APPX_BINDER
- // In AppX processes, all PEAssemblies that are reach this stage should have host binders.
- _ASSERTE(!AppX::IsAppXProcess());
-#endif
pAssembly->UpdatePEFileWorker(pFile);
}
@@ -14850,7 +12098,7 @@ void AppDomain::UnPublishHostedAssembly(
}
}
-#if defined(FEATURE_CORECLR) && defined(FEATURE_COMINTEROP)
+#if defined(FEATURE_COMINTEROP)
HRESULT AppDomain::SetWinrtApplicationContext(SString &appLocalWinMD)
{
STANDARD_VM_CONTRACT;
@@ -14865,7 +12113,7 @@ HRESULT AppDomain::SetWinrtApplicationContext(SString &appLocalWinMD)
return m_pWinRtBinder->SetApplicationContext(pApplicationContext, appLocalWinMD);
}
-#endif // FEATURE_CORECLR && FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP
#endif //!DACCESS_COMPILE
@@ -14904,7 +12152,7 @@ PTR_DomainAssembly AppDomain::FindAssembly(PTR_ICLRPrivAssembly pHostAssembly)
}
}
-#if !defined(DACCESS_COMPILE) && defined(FEATURE_CORECLR) && defined(FEATURE_NATIVE_IMAGE_GENERATION)
+#if !defined(DACCESS_COMPILE) && defined(FEATURE_NATIVE_IMAGE_GENERATION)
void ZapperSetBindingPaths(ICorCompilationDomain *pDomain, SString &trustedPlatformAssemblies, SString &platformResourceRoots, SString &appPaths, SString &appNiPaths)
{
@@ -14919,7 +12167,7 @@ void ZapperSetBindingPaths(ICorCompilationDomain *pDomain, SString &trustedPlatf
#endif
-#if defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
+#if !defined(CROSSGEN_COMPILE)
bool IsSingleAppDomain()
{
STARTUP_FLAGS flags = CorHost2::GetStartupFlags();
diff --git a/src/vm/appdomain.hpp b/src/vm/appdomain.hpp
index 670f685fdc..898e50f1c2 100644
--- a/src/vm/appdomain.hpp
+++ b/src/vm/appdomain.hpp
@@ -19,9 +19,6 @@
#include "assembly.hpp"
#include "clsload.hpp"
#include "eehash.h"
-#ifdef FEATURE_FUSION
-#include "fusion.h"
-#endif
#include "arraylist.h"
#include "comreflectioncache.hpp"
#include "comutilnative.h"
@@ -31,9 +28,8 @@
#include "ilstubcache.h"
#include "testhookmgr.h"
#include "gcheaputilities.h"
-#ifdef FEATURE_VERSIONING
+#include "gchandletableutilities.h"
#include "../binder/inc/applicationcontext.hpp"
-#endif // FEATURE_VERSIONING
#include "rejit.h"
#ifdef FEATURE_MULTICOREJIT
@@ -42,16 +38,17 @@
#ifdef FEATURE_COMINTEROP
#include "clrprivbinderwinrt.h"
-#ifndef FEATURE_CORECLR
-#include "clrprivbinderreflectiononlywinrt.h"
-#include "clrprivtypecachereflectiononlywinrt.h"
-#endif
#include "..\md\winmd\inc\adapter.h"
#include "winrttypenameconverter.h"
#endif // FEATURE_COMINTEROP
#include "appxutil.h"
+#ifdef FEATURE_TIERED_COMPILATION
+#include "tieredcompilation.h"
+#include "callcounter.h"
+#endif
+
class BaseDomain;
class SystemDomain;
class SharedDomain;
@@ -1243,61 +1240,70 @@ public:
//****************************************************************************************
// Handles
-#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) // needs GetCurrentThreadHomeHeapNumber
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
OBJECTHANDLE CreateTypedHandle(OBJECTREF object, int type)
{
WRAPPER_NO_CONTRACT;
- return ::CreateTypedHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object, type);
+
+ IGCHandleTable *pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
+ return pHandleTable->CreateHandleOfType(m_handleStore, OBJECTREFToObject(object), type);
}
OBJECTHANDLE CreateHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
CONDITIONAL_CONTRACT_VIOLATION(ModeViolation, object == NULL)
- return ::CreateHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object);
+ return ::CreateHandle(m_handleStore, object);
}
OBJECTHANDLE CreateWeakHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
- return ::CreateWeakHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object);
+ return ::CreateWeakHandle(m_handleStore, object);
}
OBJECTHANDLE CreateShortWeakHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
- return ::CreateShortWeakHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object);
+ return ::CreateShortWeakHandle(m_handleStore, object);
}
OBJECTHANDLE CreateLongWeakHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
CONDITIONAL_CONTRACT_VIOLATION(ModeViolation, object == NULL)
- return ::CreateLongWeakHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object);
+ return ::CreateLongWeakHandle(m_handleStore, object);
}
OBJECTHANDLE CreateStrongHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
- return ::CreateStrongHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object);
+ return ::CreateStrongHandle(m_handleStore, object);
}
OBJECTHANDLE CreatePinningHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
-#if CHECK_APP_DOMAIN_LEAKS
+#if CHECK_APP_DOMAIN_LEAKS
if(IsAppDomain())
object->TryAssignAppDomain((AppDomain*)this,TRUE);
#endif
- return ::CreatePinningHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object);
+ return ::CreatePinningHandle(m_handleStore, object);
}
OBJECTHANDLE CreateSizedRefHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
- OBJECTHANDLE h = ::CreateSizedRefHandle(
- m_hHandleTableBucket->pTable[GCHeapUtilities::IsServerHeap() ? (m_dwSizedRefHandles % m_iNumberOfProcessors) : GetCurrentThreadHomeHeapNumber()],
- object);
+ OBJECTHANDLE h;
+ if (GCHeapUtilities::IsServerHeap())
+ {
+ h = ::CreateSizedRefHandle(m_handleStore, object, m_dwSizedRefHandles % m_iNumberOfProcessors);
+ }
+ else
+ {
+ h = ::CreateSizedRefHandle(m_handleStore, object);
+ }
+
InterlockedIncrement((LONG*)&m_dwSizedRefHandles);
return h;
}
@@ -1306,7 +1312,7 @@ public:
OBJECTHANDLE CreateRefcountedHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
- return ::CreateRefcountedHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object);
+ return ::CreateRefcountedHandle(m_handleStore, object);
}
OBJECTHANDLE CreateWinRTWeakHandle(OBJECTREF object, IWeakReference* pWinRTWeakReference)
@@ -1319,35 +1325,35 @@ public:
}
CONTRACTL_END;
- return ::CreateWinRTWeakHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object, pWinRTWeakReference);
+ return ::CreateWinRTWeakHandle(m_handleStore, object, pWinRTWeakReference);
}
#endif // FEATURE_COMINTEROP
OBJECTHANDLE CreateVariableHandle(OBJECTREF object, UINT type)
{
WRAPPER_NO_CONTRACT;
- return ::CreateVariableHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object, type);
+ return ::CreateVariableHandle(m_handleStore, object, type);
}
OBJECTHANDLE CreateDependentHandle(OBJECTREF primary, OBJECTREF secondary)
{
- WRAPPER_NO_CONTRACT;
- return ::CreateDependentHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], primary, secondary);
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_COOPERATIVE;
+ }
+ CONTRACTL_END;
+
+ IGCHandleTable *pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
+ return pHandleTable->CreateDependentHandle(m_handleStore, OBJECTREFToObject(primary), OBJECTREFToObject(secondary));
}
#endif // DACCESS_COMPILE && !CROSSGEN_COMPILE
- BOOL ContainsOBJECTHANDLE(OBJECTHANDLE handle);
-
-#ifdef FEATURE_FUSION
- IApplicationContext *GetFusionContext() {LIMITED_METHOD_CONTRACT; return m_pFusionContext; }
-#else
IUnknown *GetFusionContext() {LIMITED_METHOD_CONTRACT; return m_pFusionContext; }
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
CLRPrivBinderCoreCLR *GetTPABinderContext() {LIMITED_METHOD_CONTRACT; return m_pTPABinderContext; }
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
-#endif
CrstExplicitInit * GetLoaderAllocatorReferencesLock()
{
@@ -1392,18 +1398,11 @@ protected:
// Fusion context, used for adding assemblies to the is domain. It defines
// fusion properties for finding assemblyies such as SharedBinPath,
// PrivateBinPath, Application Directory, etc.
-#ifdef FEATURE_FUSION
- IApplicationContext* m_pFusionContext; // Binding context for the domain
-#else
IUnknown *m_pFusionContext; // Current binding context for the domain
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
CLRPrivBinderCoreCLR *m_pTPABinderContext; // Reference to the binding context that holds TPA list details
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
-#endif
-
- HandleTableBucket *m_hHandleTableBucket;
+ void* m_handleStore;
// The large heap handle table.
LargeHeapHandleTable *m_pLargeHeapHandleTable;
@@ -1417,7 +1416,7 @@ protected:
// Information regarding the managed standard interfaces.
MngStdInterfacesInfo *m_pMngStdInterfacesInfo;
- // WinRT binder (only in classic = non-AppX; AppX has the WinRT binder inside code:CLRPrivBinderAppX)
+ // WinRT binder
PTR_CLRPrivBinderWinRT m_pWinRtBinder;
#endif // FEATURE_COMINTEROP
@@ -1793,9 +1792,7 @@ public:
protected:
DWORD m_type;
LPVOID m_value;
-#if FEATURE_VERSIONING
ULONG m_uIdentityHash;
-#endif
};
#endif // FEATURE_LOADER_OPTIMIZATION
@@ -1805,9 +1802,6 @@ protected:
struct FailedAssembly {
SString displayName;
SString location;
-#ifdef FEATURE_FUSION
- LOADCTX_TYPE context;
-#endif
HRESULT error;
void Initialize(AssemblySpec *pSpec, Exception *ex)
@@ -1830,9 +1824,6 @@ struct FailedAssembly {
// If the parent hasn't been set but the code base has, use LoadFrom.
// Otherwise, use the default.
//
-#ifdef FEATURE_FUSION
- context = pSpec->GetParentIAssembly() ? pSpec->GetParentIAssembly()->GetFusionLoadContext() : LOADCTX_TYPE_LOADFROM;
-#endif // FEATURE_FUSION
}
};
@@ -1988,15 +1979,10 @@ public:
inline LPCWSTR GetAppDomainManagerType();
inline EInitializeNewDomainFlags GetAppDomainManagerInitializeNewDomainFlags();
-#ifndef FEATURE_CORECLR
- inline BOOL AppDomainManagerSetFromConfig();
- Assembly *GetAppDomainManagerEntryAssembly();
- void ComputeTargetFrameworkName();
-#endif // FEATURE_CORECLR
-#if defined(FEATURE_CORECLR) && defined(FEATURE_COMINTEROP)
+#if defined(FEATURE_COMINTEROP)
HRESULT SetWinrtApplicationContext(SString &appLocalWinMD);
-#endif // FEATURE_CORECLR && FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP
BOOL CanReversePInvokeEnter();
void SetReversePInvokeCannotEnter();
@@ -2032,10 +2018,6 @@ public:
virtual BOOL IsAppDomain() { LIMITED_METHOD_DAC_CONTRACT; return TRUE; }
virtual PTR_AppDomain AsAppDomain() { LIMITED_METHOD_CONTRACT; return dac_cast<PTR_AppDomain>(this); }
-#ifndef FEATURE_CORECLR
- void InitializeSorting(OBJECTREF* ppAppdomainSetup);
- void InitializeHashing(OBJECTREF* ppAppdomainSetup);
-#endif
OBJECTREF DoSetup(OBJECTREF* setupInfo);
@@ -2290,7 +2272,6 @@ public:
return AssemblyIterator::Create(this, assemblyIterationFlags);
}
-#ifdef FEATURE_CORECLR
private:
struct NativeImageDependenciesEntry
{
@@ -2346,7 +2327,6 @@ public:
void SetNativeDllSearchDirectories(LPCWSTR paths);
BOOL HasNativeDllSearchDirectories();
void ShutdownNativeDllSearchDirectories();
-#endif // FEATURE_CORECLR
public:
SIZE_T GetAssemblyCount()
@@ -2374,12 +2354,6 @@ public:
DomainAssembly * FindAssembly(PEAssembly * pFile, FindAssemblyOptions options = FindAssemblyOptions_None) DAC_EMPTY_RET(NULL);
-#ifdef FEATURE_MIXEDMODE
- // Finds only loaded modules, elevates level if needed
- Module* GetIJWModule(HMODULE hMod) DAC_EMPTY_RET(NULL);
- // Finds loading modules
- DomainFile* FindIJWDomainFile(HMODULE hMod, const SString &path) DAC_EMPTY_RET(NULL);
-#endif // FEATURE_MIXEDMODE
Assembly *LoadAssembly(AssemblySpec* pIdentity,
PEAssembly *pFile,
@@ -2402,23 +2376,12 @@ public:
FileLoadLevel targetLevel,
AssemblyLoadSecurity *pLoadSecurity = NULL);
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- DomainModule *LoadDomainModule(DomainAssembly *pAssembly,
- PEModule *pFile,
- FileLoadLevel targetLevel);
-#endif
CHECK CheckValidModule(Module *pModule);
#ifdef FEATURE_LOADER_OPTIMIZATION
DomainFile *LoadDomainNeutralModuleDependency(Module *pModule, FileLoadLevel targetLevel);
#endif
-#ifdef FEATURE_FUSION
- PEAssembly *BindExplicitAssembly(HMODULE hMod, BOOL bindable);
- Assembly *LoadExplicitAssembly(HMODULE hMod, BOOL bindable);
- void GetFileFromFusion(IAssembly *pIAssembly, LPCWSTR wszModuleName,
- SString &path);
-#endif
// private:
void LoadSystemAssemblies();
@@ -2485,10 +2448,6 @@ public:
//****************************************************************************************
// Determines if the image is to be loaded into the shared assembly or an individual
// appdomains.
-#ifndef FEATURE_CORECLR
- BOOL ApplySharePolicy(DomainAssembly *pFile);
- BOOL ApplySharePolicyFlag(DomainAssembly *pFile);
-#endif
#endif // FEATURE_LOADER_OPTIMIZATION
BOOL HasSetSecurityPolicy();
@@ -2546,9 +2505,6 @@ public:
PEAssembly ** ppAssembly,
BOOL fIsIntrospectionOnly = FALSE) DAC_EMPTY_RET(S_OK);
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
- virtual DomainAssembly *BindAssemblySpecForIntrospectionDependencies(AssemblySpec *pSpec) DAC_EMPTY_RET(NULL);
-#endif
PEAssembly *TryResolveAssembly(AssemblySpec *pSpec, BOOL fPreBind);
@@ -2577,19 +2533,11 @@ public:
//****************************************************************************************
//
-#ifdef FEATURE_FUSION
- static BOOL SetContextProperty(IApplicationContext* pFusionContext,
- LPCWSTR pProperty,
- OBJECTREF* obj);
-#endif
//****************************************************************************************
//
// Uses the first assembly to add an application base to the Context. This is done
// in a lazy fashion so executables do not take the perf hit unless the load other
// assemblies
-#ifdef FEATURE_FUSION
- LPWSTR GetDynamicDir();
-#endif
#ifndef DACCESS_COMPILE
void OnAssemblyLoad(Assembly *assem);
void OnAssemblyLoadUnlocked(Assembly *assem);
@@ -2764,9 +2712,6 @@ public:
//****************************************************************************************
// Get the proxy for this app domain
-#ifdef FEATURE_REMOTING
- OBJECTREF GetAppDomainProxy();
-#endif
ADIndex GetIndex()
{
@@ -2784,15 +2729,8 @@ public:
void InitializeDomainContext(BOOL allowRedirects, LPCWSTR pwszPath, LPCWSTR pwszConfig);
-#ifdef FEATURE_FUSION
- IApplicationContext *CreateFusionContext();
- void SetupLoaderOptimization(DWORD optimization);
-#endif
-#ifdef FEATURE_VERSIONING
IUnknown *CreateFusionContext();
-#endif // FEATURE_VERSIONING
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
void OverrideDefaultContextBinder(IUnknown *pOverrideBinder)
{
LIMITED_METHOD_CONTRACT;
@@ -2803,7 +2741,6 @@ public:
m_pFusionContext = pOverrideBinder;
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
#ifdef FEATURE_PREJIT
CorCompileConfigFlags GetNativeConfigFlags();
@@ -2822,9 +2759,6 @@ public:
//****************************************************************************************
// Manage a pool of asyncrhonous objects used to fetch assemblies. When a sink is released
// it places itself back on the pool list. Only one object is kept in the pool.
-#ifdef FEATURE_FUSION
- AssemblySink* AllocateAssemblySink(AssemblySpec* pSpec);
-#endif
void SetIsUserCreatedDomain()
{
LIMITED_METHOD_CONTRACT;
@@ -3421,15 +3355,9 @@ private:
void InitializeDefaultDomainManager ();
-#ifdef FEATURE_CLICKONCE
- void InitializeDefaultClickOnceDomain();
-#endif // FEATURE_CLICKONCE
void InitializeDefaultDomainSecurity();
public:
-#ifdef FEATURE_CLICKONCE
- BOOL IsClickOnceAppDomain();
-#endif // FEATURE_CLICKONCE
protected:
BOOL PostBindResolveAssembly(AssemblySpec *pPrePolicySpec,
@@ -3480,9 +3408,6 @@ private:
BOOL isTerminating;
BOOL *pResult;
};
- #ifndef FEATURE_CORECLR
- static void RaiseUnhandledExceptionEvent_Wrapper(LPVOID /* RaiseUnhandled_Args * */);
- #endif
static void AllowThreadEntrance(AppDomain *pApp);
@@ -3802,19 +3727,14 @@ private:
// Stub caches for Method stubs
//---------------------------------------------------------
-#ifdef FEATURE_FUSION
- void TurnOnBindingRedirects();
-#endif
public:
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
private:
Volatile<BOOL> m_fIsBindingModelLocked;
public:
BOOL IsHostAssemblyResolverInUse();
BOOL IsBindingModelLocked();
BOOL LockBindingModel();
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
UMEntryThunkCache *GetUMEntryThunkCache();
@@ -3843,11 +3763,9 @@ public:
ILLEGAL_VERIFICATION_DOMAIN = 0x8000, // This can't be a verification domain
IGNORE_UNHANDLED_EXCEPTIONS = 0x10000, // AppDomain was created using the APPDOMAIN_IGNORE_UNHANDLED_EXCEPTIONS flag
ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP = 0x20000, // AppDomain was created using the APPDOMAIN_ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP flag
-#ifdef FEATURE_CORECLR
ENABLE_SKIP_PLAT_CHECKS = 0x200000, // Skip various assembly checks (like platform check)
ENABLE_ASSEMBLY_LOADFILE = 0x400000, // Allow Assembly.LoadFile in CoreCLR
DISABLE_TRANSPARENCY_ENFORCEMENT= 0x800000, // Disable enforcement of security transparency rules
-#endif
};
SecurityContext *m_pSecContext;
@@ -3861,9 +3779,7 @@ public:
BOOL m_fAppDomainManagerSetInConfig;
EInitializeNewDomainFlags m_dwAppDomainManagerInitializeDomainFlags;
-#ifdef FEATURE_CORECLR
ArrayList m_NativeDllSearchDirectories;
-#endif
BOOL m_ReversePInvokeCanEnter;
bool m_ForceTrivialWaitOperations;
// Section to support AD unload due to escalation
@@ -3891,10 +3807,8 @@ public:
return (m_Stage == STAGE_UNLOAD_REQUESTED);
}
-#ifdef FEATURE_CORECLR
BOOL IsImageFromTrustedPath(PEImage* pImage);
BOOL IsImageFullyTrusted(PEImage* pImage);
-#endif
#ifdef FEATURE_TYPEEQUIVALENCE
private:
@@ -3929,27 +3843,36 @@ public:
#endif
+#if defined(FEATURE_TIERED_COMPILATION)
+
+public:
+ TieredCompilationManager * GetTieredCompilationManager()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return &m_tieredCompilationManager;
+ }
+
+private:
+ TieredCompilationManager m_tieredCompilationManager;
+
+public:
+ CallCounter * GetCallCounter()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return &m_callCounter;
+ }
+
+private:
+ CallCounter m_callCounter;
+#endif
+
#ifdef FEATURE_COMINTEROP
private:
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
- // ReflectionOnly WinRT binder and its TypeCache (only in classic = non-AppX; the scenario is not supported in AppX)
- CLRPrivBinderReflectionOnlyWinRT * m_pReflectionOnlyWinRtBinder;
- CLRPrivTypeCacheReflectionOnlyWinRT * m_pReflectionOnlyWinRtTypeCache;
-#endif // FEATURE_REFLECTION_ONLY_LOAD
#endif //FEATURE_COMINTEROP
public:
-#ifndef FEATURE_CORECLR
- BOOL m_bUseOsSorting;
- DWORD m_sortVersion;
- COMNlsCustomSortLibrary *m_pCustomSortLibrary;
-#if _DEBUG
- BOOL m_bSortingInitialized;
-#endif // _DEBUG
- COMNlsHashProvider *m_pNlsHashProvider;
-#endif // !FEATURE_CORECLR
private:
// This is the root-level default load context root binder. If null, then
@@ -4367,9 +4290,6 @@ public:
}
#endif // DACCESS_COMPILE
-#ifndef FEATURE_CORECLR
- static void ExecuteMainMethod(HMODULE hMod, __in_opt LPWSTR path = NULL);
-#endif
static void ActivateApplication(int *pReturnValue);
static void InitializeDefaultDomain(BOOL allowRedirects, ICLRPrivBinder * pBinder = NULL);
@@ -4382,9 +4302,6 @@ public:
#endif
static BOOL SetGlobalSharePolicyUsingAttribute(IMDInternalImport* pScope, mdMethodDef mdMethod);
-#ifdef FEATURE_MIXEDMODE
- static HRESULT RunDllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved);
-#endif // FEATURE_MIXEDMODE
//****************************************************************************************
//
@@ -4446,9 +4363,6 @@ public:
//****************************************************************************************
// return the dev path
-#ifdef FEATURE_FUSION
- void GetDevpathW(__out_ecount_opt(1) LPWSTR* pPath, DWORD* pSize);
-#endif
#ifndef DACCESS_COMPILE
void IncrementNumAppDomains ()
@@ -4751,15 +4665,8 @@ private:
InlineSString<100> m_BaseLibrary;
-#ifdef FEATURE_VERSIONING
-
InlineSString<100> m_SystemDirectory;
-#else
-
- LPCWSTR m_SystemDirectory;
-
-#endif
LPWSTR m_pwDevpath;
DWORD m_dwDevpath;
diff --git a/src/vm/appdomain.inl b/src/vm/appdomain.inl
index 210334c78e..2986588ddc 100644
--- a/src/vm/appdomain.inl
+++ b/src/vm/appdomain.inl
@@ -231,13 +231,6 @@ inline LPCWSTR AppDomain::GetAppDomainManagerType()
return m_AppDomainManagerType;
}
-#ifndef FEATURE_CORECLR
-inline BOOL AppDomain::AppDomainManagerSetFromConfig()
-{
- WRAPPER_NO_CONTRACT;
- return m_fAppDomainManagerSetInConfig;
-}
-#endif // !FEATURE_CORECLR
inline EInitializeNewDomainFlags AppDomain::GetAppDomainManagerInitializeNewDomainFlags()
{
@@ -245,7 +238,6 @@ inline EInitializeNewDomainFlags AppDomain::GetAppDomainManagerInitializeNewDoma
return m_dwAppDomainManagerInitializeDomainFlags;
}
-#ifdef FEATURE_CORECLR
inline AppDomain::PathIterator AppDomain::IterateNativeDllSearchDirectories()
{
WRAPPER_NO_CONTRACT;
@@ -260,7 +252,6 @@ inline BOOL AppDomain::HasNativeDllSearchDirectories()
return m_NativeDllSearchDirectories.GetCount() !=0;
}
-#endif // FEATURE_CORECLR
inline BOOL AppDomain::CanReversePInvokeEnter()
{
diff --git a/src/vm/appdomainhelper.cpp b/src/vm/appdomainhelper.cpp
deleted file mode 100644
index 2c0531648f..0000000000
--- a/src/vm/appdomainhelper.cpp
+++ /dev/null
@@ -1,546 +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 "common.h"
-
-#ifdef FEATURE_REMOTING
-
-#include "appdomainhelper.h"
-#include "appdomain.inl"
-
-void AppDomainHelper::CopyEncodingToByteArray(IN PBYTE pbData,
- IN DWORD cbData,
- OUT OBJECTREF* pArray)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(cbData==0 || pbData!=NULL);
- PRECONDITION(CheckPointer(pArray));
- }
- CONTRACTL_END;
- PREFIX_ASSUME(pArray != NULL);
-
- U1ARRAYREF pObj;
-
- if(cbData) {
- pObj = (U1ARRAYREF)AllocatePrimitiveArray(ELEMENT_TYPE_U1,cbData);
- memcpyNoGCRefs(pObj->m_Array, pbData, cbData);
- *pArray = (OBJECTREF) pObj;
- } else
- *pArray = NULL;
-
- VALIDATEOBJECTREF(*pArray);
-}
-
-
-void AppDomainHelper::CopyByteArrayToEncoding(IN U1ARRAYREF* pArray,
- OUT PBYTE* ppbData,
- OUT DWORD* pcbData)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- PRECONDITION(pArray!=NULL);
- PRECONDITION(ppbData!=NULL);
- PRECONDITION(pcbData!=NULL);
- }
- CONTRACTL_END;
-
- VALIDATEOBJECTREF(*pArray);
-
- if (*pArray == NULL) {
- *ppbData = NULL;
- *pcbData = 0;
- return;
- }
-
- DWORD size = (*pArray)->GetNumComponents();
- if(size) {
- *ppbData = new BYTE[size];
- *pcbData = size;
-
- CopyMemory(*ppbData, (*pArray)->GetDirectPointerToNonObjectElements(), size);
- }
-}
-
-
-struct MarshalObjectArgs : public CtxTransitionBaseArgs
-{
- OBJECTREF* orObject;
- U1ARRAYREF* porBlob;
-};
-
-void MarshalObjectADCallback(MarshalObjectArgs * args)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
- MethodDescCallSite marshalObject(METHOD__APP_DOMAIN__MARSHAL_OBJECT);
-
- ARG_SLOT argsCall[] = {
- ObjToArgSlot(*(args->orObject))
- };
-
- *(args->porBlob) = (U1ARRAYREF) marshalObject.Call_RetOBJECTREF(argsCall);
-}
-
-
-// Marshal a single object into a serialized blob.
-void AppDomainHelper::MarshalObject(ADID appDomain,
- IN OBJECTREF *orObject, // Object must be GC protected
- OUT U1ARRAYREF *porBlob)
-{
-
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(orObject!=NULL);
- PRECONDITION(porBlob!=NULL);
- PRECONDITION(IsProtectedByGCFrame(orObject));
- }
- CONTRACTL_END;
-
- VALIDATEOBJECTREF(*orObject);
-
- MarshalObjectArgs args;
- args.orObject = orObject;
- args.porBlob = porBlob;
-
- MakeCallWithPossibleAppDomainTransition(appDomain, (FPAPPDOMAINCALLBACK) MarshalObjectADCallback, &args);
-
- VALIDATEOBJECTREF(*porBlob);
-
-}
-
-void AppDomainHelper::MarshalObject(IN OBJECTREF *orObject, // Object must be GC protected
- OUT U1ARRAYREF *porBlob)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(orObject!=NULL);
- PRECONDITION(porBlob!=NULL);
- PRECONDITION(IsProtectedByGCFrame(orObject));
- }
- CONTRACTL_END;
-
- VALIDATEOBJECTREF(*orObject);
-
- MethodDescCallSite marshalObject(METHOD__APP_DOMAIN__MARSHAL_OBJECT);
-
- ARG_SLOT argsCall[] = {
- ObjToArgSlot(*orObject)
- };
-
- *porBlob = (U1ARRAYREF) marshalObject.Call_RetOBJECTREF(argsCall);
-
- VALIDATEOBJECTREF(*porBlob);
-}
-
-// Marshal a single object into a serialized blob.
-void AppDomainHelper::MarshalObject(IN AppDomain *pDomain,
- IN OBJECTREF *orObject, // Object must be GC protected
- OUT BYTE **ppbBlob,
- OUT DWORD *pcbBlob)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(pDomain!=NULL);
- PRECONDITION(orObject!=NULL);
- PRECONDITION(ppbBlob!=NULL);
- PRECONDITION(pcbBlob!=NULL);
- PRECONDITION(IsProtectedByGCFrame(orObject));
- }
- CONTRACTL_END;
-
- VALIDATEOBJECTREF(*orObject);
-
- U1ARRAYREF orBlob = NULL;
-
- GCPROTECT_BEGIN(orBlob);
-
- MethodDescCallSite marshalObject(METHOD__APP_DOMAIN__MARSHAL_OBJECT);
-
- ENTER_DOMAIN_PTR(pDomain,ADV_RUNNINGIN)
- {
- ARG_SLOT args[] =
- {
- ObjToArgSlot(*orObject)
- };
-
- orBlob = (U1ARRAYREF) marshalObject.Call_RetOBJECTREF(args);
- }
- END_DOMAIN_TRANSITION;
-
- if (orBlob != NULL)
- CopyByteArrayToEncoding(&orBlob,
- ppbBlob,
- pcbBlob);
- GCPROTECT_END();
-}
-
-// Marshal two objects into serialized blobs.
-void AppDomainHelper::MarshalObjects(IN AppDomain *pDomain,
- IN OBJECTREF *orObject1,
- IN OBJECTREF *orObject2,
- OUT BYTE **ppbBlob1,
- OUT DWORD *pcbBlob1,
- OUT BYTE **ppbBlob2,
- OUT DWORD *pcbBlob2)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(pDomain!=NULL);
- PRECONDITION(orObject1!=NULL);
- PRECONDITION(ppbBlob1!=NULL);
- PRECONDITION(pcbBlob1!=NULL);
- PRECONDITION(orObject2!=NULL);
- PRECONDITION(ppbBlob2!=NULL);
- PRECONDITION(pcbBlob2!=NULL);
- PRECONDITION(IsProtectedByGCFrame(orObject1));
- PRECONDITION(IsProtectedByGCFrame(orObject2));
- }
- CONTRACTL_END;
-
- VALIDATEOBJECTREF(*orObject1);
- VALIDATEOBJECTREF(*orObject2);
-
- struct _gc {
- U1ARRAYREF orBlob1;
- U1ARRAYREF orBlob2;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- MethodDescCallSite marshalObjects(METHOD__APP_DOMAIN__MARSHAL_OBJECTS);
-
- ENTER_DOMAIN_PTR(pDomain,ADV_RUNNINGIN)
- {
- ARG_SLOT args[] =
- {
- ObjToArgSlot(*orObject1),
- ObjToArgSlot(*orObject2),
- PtrToArgSlot(&gc.orBlob2),
- };
-
- gc.orBlob1 = (U1ARRAYREF) marshalObjects.Call_RetOBJECTREF(args);
- }
- END_DOMAIN_TRANSITION;
-
- if (gc.orBlob1 != NULL)
- {
- CopyByteArrayToEncoding(&gc.orBlob1,
- ppbBlob1,
- pcbBlob1);
- }
-
- if (gc.orBlob2 != NULL)
- {
- CopyByteArrayToEncoding(&gc.orBlob2,
- ppbBlob2,
- pcbBlob2);
- }
-
- GCPROTECT_END();
-}
-
-// Unmarshal a single object from a serialized blob.
-// Callers must GC protect both porBlob and porObject.
-void AppDomainHelper::UnmarshalObject(IN AppDomain *pDomain,
- IN U1ARRAYREF *porBlob, // Object must be GC protected
- OUT OBJECTREF *porObject) // Object must be GC protected
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(pDomain!=NULL);
- PRECONDITION(porBlob!=NULL);
- PRECONDITION(porObject!=NULL);
- PRECONDITION(IsProtectedByGCFrame(porBlob));
- PRECONDITION(IsProtectedByGCFrame(porObject));
- }
- CONTRACTL_END;
-
- VALIDATEOBJECTREF(*porBlob);
-
- MethodDescCallSite unmarshalObject(METHOD__APP_DOMAIN__UNMARSHAL_OBJECT);
-
- ENTER_DOMAIN_PTR(pDomain,ADV_RUNNINGIN)
- {
- ARG_SLOT args[] =
- {
- ObjToArgSlot(*porBlob)
- };
-
- *porObject = unmarshalObject.Call_RetOBJECTREF(args);
- }
- END_DOMAIN_TRANSITION;
-
- VALIDATEOBJECTREF(*porObject);
-}
-
-// Unmarshal a single object from a serialized blob.
-void AppDomainHelper::UnmarshalObject(IN AppDomain *pDomain,
- IN BYTE *pbBlob,
- IN DWORD cbBlob,
- OUT OBJECTREF *porObject)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(pDomain!=NULL);
- PRECONDITION(porObject!=NULL);
- PRECONDITION(IsProtectedByGCFrame(porObject));
- }
- CONTRACTL_END;
-
- OBJECTREF orBlob = NULL;
-
- MethodDescCallSite unmarshalObject(METHOD__APP_DOMAIN__UNMARSHAL_OBJECT);
-
- ENTER_DOMAIN_PTR(pDomain,ADV_RUNNINGIN)
- {
- GCPROTECT_BEGIN(orBlob);
-
- AppDomainHelper::CopyEncodingToByteArray(pbBlob,
- cbBlob,
- &orBlob);
-
- ARG_SLOT args[] =
- {
- ObjToArgSlot(orBlob)
- };
-
- *porObject = unmarshalObject.Call_RetOBJECTREF(args);
-
- GCPROTECT_END();
- }
- END_DOMAIN_TRANSITION;
-
- VALIDATEOBJECTREF(*porObject);
-}
-
-// Unmarshal two objects from serialized blobs.
-void AppDomainHelper::UnmarshalObjects(IN AppDomain *pDomain,
- IN BYTE *pbBlob1,
- IN DWORD cbBlob1,
- IN BYTE *pbBlob2,
- IN DWORD cbBlob2,
- OUT OBJECTREF *porObject1,
- OUT OBJECTREF *porObject2)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(pDomain!=NULL);
- PRECONDITION(porObject1!=NULL);
- PRECONDITION(porObject2!=NULL);
- PRECONDITION(IsProtectedByGCFrame(porObject1));
- PRECONDITION(IsProtectedByGCFrame(porObject2));
- }
- CONTRACTL_END;
-
- MethodDescCallSite unmarshalObjects(METHOD__APP_DOMAIN__UNMARSHAL_OBJECTS);
-
- struct _gc {
- OBJECTREF orBlob1;
- OBJECTREF orBlob2;
- OBJECTREF orObject2;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- ENTER_DOMAIN_PTR(pDomain,ADV_RUNNINGIN)
- {
-
- GCPROTECT_BEGIN(gc);
-
- AppDomainHelper::CopyEncodingToByteArray(pbBlob1,
- cbBlob1,
- &gc.orBlob1);
-
- AppDomainHelper::CopyEncodingToByteArray(pbBlob2,
- cbBlob2,
- &gc.orBlob2);
-
- ARG_SLOT args[] =
- {
- ObjToArgSlot(gc.orBlob1),
- ObjToArgSlot(gc.orBlob2),
- PtrToArgSlot(&gc.orObject2),
- };
-
- *porObject1 = unmarshalObjects.Call_RetOBJECTREF(args);
- *porObject2 = gc.orObject2;
-
- GCPROTECT_END();
- }
- END_DOMAIN_TRANSITION;
-
- VALIDATEOBJECTREF(*porObject1);
- VALIDATEOBJECTREF(*porObject2);
-}
-
-// Copy an object from the given appdomain into the current appdomain.
-OBJECTREF AppDomainHelper::CrossContextCopyFrom(IN ADID dwDomainId,
- IN OBJECTREF *orObject) // Object must be GC protected
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(orObject!=NULL);
- PRECONDITION(IsProtectedByGCFrame(orObject));
- }
- CONTRACTL_END;
-
- struct _gc
- {
- U1ARRAYREF orBlob;
- OBJECTREF pResult;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- AppDomainHelper::MarshalObject(dwDomainId, orObject, &gc.orBlob);
- AppDomainHelper::UnmarshalObject(GetAppDomain(), &gc.orBlob, &gc.pResult);
- GCPROTECT_END();
- VALIDATEOBJECTREF(gc.pResult);
- return gc.pResult;
-}
-
-// Copy an object from the given appdomain into the current appdomain.
-OBJECTREF AppDomainHelper::CrossContextCopyTo(IN ADID dwDomainId,
- IN OBJECTREF *orObject) // Object must be GC protected
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(orObject!=NULL);
- PRECONDITION(IsProtectedByGCFrame(orObject));
- }
- CONTRACTL_END;
-
-
- struct _gc
- {
- U1ARRAYREF orBlob;
- OBJECTREF pResult;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- AppDomainHelper::MarshalObject(orObject, &gc.orBlob);
- ENTER_DOMAIN_ID(dwDomainId);
- AppDomainHelper::UnmarshalObject(GetAppDomain(),&gc.orBlob, &gc.pResult);
- END_DOMAIN_TRANSITION;
- GCPROTECT_END();
- VALIDATEOBJECTREF(gc.pResult);
- return gc.pResult;
-
-}
-
-// Copy an object from the given appdomain into the current appdomain.
-OBJECTREF AppDomainHelper::CrossContextCopyFrom(IN AppDomain *pDomain,
- IN OBJECTREF *orObject) // Object must be GC protected
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(orObject!=NULL);
- PRECONDITION(IsProtectedByGCFrame(orObject));
- PRECONDITION(pDomain!=NULL);
- PRECONDITION(pDomain != GetAppDomain());
- }
- CONTRACTL_END;
-
- VALIDATEOBJECTREF(*orObject);
-
- struct _gc {
- U1ARRAYREF orBlob;
- OBJECTREF result;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- ENTER_DOMAIN_PTR(pDomain, ADV_RUNNINGIN);
- AppDomainHelper::MarshalObject(orObject, &gc.orBlob);
- END_DOMAIN_TRANSITION;
- AppDomainHelper::UnmarshalObject(GetAppDomain(),&gc.orBlob, &gc.result);
- GCPROTECT_END();
-
- VALIDATEOBJECTREF(gc.result);
-
- return gc.result;
-}
-
-// Copy an object to the given appdomain from the current appdomain.
-OBJECTREF AppDomainHelper::CrossContextCopyTo(IN AppDomain *pDomain,
- IN OBJECTREF *orObject) // Object must be GC protected
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(orObject!=NULL);
- PRECONDITION(IsProtectedByGCFrame(orObject));
- PRECONDITION(pDomain!=NULL);
- PRECONDITION(pDomain != GetAppDomain());
- }
- CONTRACTL_END;
-
- VALIDATEOBJECTREF(*orObject);
-
- struct _gc {
- U1ARRAYREF orBlob;
- OBJECTREF result;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- AppDomainHelper::MarshalObject(orObject, &gc.orBlob);
- AppDomainHelper::UnmarshalObject(pDomain, &gc.orBlob, &gc.result);
- GCPROTECT_END();
-
- VALIDATEOBJECTREF(gc.result);
-
- return gc.result;
-}
-
-#endif // FEATURE_REMOTING
-
diff --git a/src/vm/appdomainhelper.h b/src/vm/appdomainhelper.h
deleted file mode 100644
index e331555292..0000000000
--- a/src/vm/appdomainhelper.h
+++ /dev/null
@@ -1,371 +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.
-
-
-#ifndef _APPDOMAIN_HELPER_H_
-#define _APPDOMAIN_HELPER_H_
-
-#ifndef FEATURE_REMOTING
-#error FEATURE_REMOTING is not set, please do not include appdomainhelper.h
-#endif
-
-// Marshal a single object into a serialized blob.
-//
-//
-
-class AppDomainHelper {
-
- friend class MarshalCache;
-
- // A pair of helper to move serialization info between managed byte-array and
- // unmanaged blob.
- static void AppDomainHelper::CopyEncodingToByteArray(IN PBYTE pbData,
- IN DWORD cbData,
- OUT OBJECTREF* pArray);
-
- static void AppDomainHelper::CopyByteArrayToEncoding(IN U1ARRAYREF* pArray,
- OUT PBYTE* ppbData,
- OUT DWORD* pcbData);
-
-public:
- // Marshal a single object into a serialized blob.
- static void AppDomainHelper::MarshalObject(IN OBJECTREF *orObject,
- OUT U1ARRAYREF *porBlob);
-
- static void AppDomainHelper::MarshalObject(IN ADID pDomain,
- IN OBJECTREF *orObject,
- OUT U1ARRAYREF *porBlob);
- // Marshal one object into a seraialized blob.
- static void AppDomainHelper::MarshalObject(IN AppDomain *pDomain,
- IN OBJECTREF *orObject,
- OUT BYTE **ppbBlob,
- OUT DWORD *pcbBlob);
-
- // Marshal two objects into serialized blobs.
- static void AppDomainHelper::MarshalObjects(IN AppDomain *pDomain,
- IN OBJECTREF *orObject1,
- IN OBJECTREF *orObject2,
- OUT BYTE **ppbBlob1,
- OUT DWORD *pcbBlob1,
- OUT BYTE **ppbBlob2,
- OUT DWORD *pcbBlob2);
-
- // Unmarshal a single object from a serialized blob.
- static void AppDomainHelper::UnmarshalObject(IN AppDomain *pDomain,
- IN U1ARRAYREF *porBlob,
- OUT OBJECTREF *porObject);
-
- // Unmarshal a single object from a serialized blob.
- static void AppDomainHelper::UnmarshalObject(IN AppDomain *pDomain,
- IN BYTE *pbBlob,
- IN DWORD cbBlob,
- OUT OBJECTREF *porObject);
-
- // Unmarshal two objects from serialized blobs.
- static void AppDomainHelper::UnmarshalObjects(IN AppDomain *pDomain,
- IN BYTE *pbBlob1,
- IN DWORD cbBlob1,
- IN BYTE *pbBlob2,
- IN DWORD cbBlob2,
- OUT OBJECTREF *porObject1,
- OUT OBJECTREF *porObject2);
-
- // Copy an object from the given appdomain into the current appdomain.
- static OBJECTREF AppDomainHelper::CrossContextCopyFrom(IN AppDomain *pAppDomain,
- IN OBJECTREF *orObject);
- // Copy an object to the given appdomain from the current appdomain.
- static OBJECTREF AppDomainHelper::CrossContextCopyTo(IN AppDomain *pAppDomain,
- IN OBJECTREF *orObject);
- // Copy an object from the given appdomain into the current appdomain.
- static OBJECTREF AppDomainHelper::CrossContextCopyFrom(IN ADID dwDomainId,
- IN OBJECTREF *orObject);
- // Copy an object to the given appdomain from the current appdomain.
- static OBJECTREF AppDomainHelper::CrossContextCopyTo(IN ADID dwDomainId,
- IN OBJECTREF *orObject);
-
-};
-
-// Cache the bits needed to serialize/deserialize managed objects that will be
-// passed across appdomain boundaries during a stackwalk. The serialization is
-// performed lazily the first time it's needed and remains valid throughout the
-// stackwalk. The last deserialized object is cached and tagged with its
-// appdomain context. It's valid as long as we're walking frames within the same
-// appdomain.
-//
-class MarshalCache
-{
-public:
- MarshalCache()
- {
- LIMITED_METHOD_CONTRACT;
- ZeroMemory(this, sizeof(*this));
- }
-
- ~MarshalCache()
- {
- LIMITED_METHOD_CONTRACT;
- if (m_pbObj1)
- delete [] m_pbObj1;
- if (m_pbObj2)
- delete [] m_pbObj2;
- }
-
- void EnsureSerializationOK()
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
- if ((m_sGC.m_orInput1 != NULL && (m_pbObj1 == NULL || m_cbObj1 == 0)) ||
- (m_sGC.m_orInput2 != NULL && (m_pbObj2 == NULL || m_cbObj2 == 0)))
- {
- // Serialization went bad -> Throw exception indicating so.
- COMPlusThrow(kSecurityException, IDS_UNMARSHALABLE_DEMAND_OBJECT);
- }
- }
-
- void EnsureDeserializationOK()
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
- if ((m_pbObj1 != NULL && m_sGC.m_orOutput1 == NULL ) ||
- (m_pbObj2 != NULL && m_sGC.m_orOutput2 == NULL ) )
- {
- // DeSerialization went bad -> Throw exception indicating so.
- COMPlusThrow(kSecurityException, IDS_UNMARSHALABLE_DEMAND_OBJECT);
- }
- }
-
-#ifndef DACCESS_COMPILE
-
- // Set the original value of the first cached object.
- void SetObject(OBJECTREF orObject)
- {
- LIMITED_METHOD_CONTRACT;
- m_pOriginalDomain = ::GetAppDomain();
- m_sGC.m_orInput1 = orObject;
- }
-
- // Set the original values of both cached objects.
- void SetObjects(OBJECTREF orObject1, OBJECTREF orObject2)
- {
- LIMITED_METHOD_CONTRACT;
- m_pOriginalDomain = ::GetAppDomain();
- m_sGC.m_orInput1 = orObject1;
- m_sGC.m_orInput2 = orObject2;
- }
-
-#endif //!DACCESS_COMPILE
-
- // Get a copy of the first object suitable for use in the given appdomain.
- OBJECTREF GetObject(AppDomain *pDomain)
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
- CheckADValidity(pDomain, ADV_RUNNINGIN);
-
- // No transition -- just return original object.
- if (pDomain == m_pOriginalDomain) {
- if (m_fObjectUpdated)
- UpdateObjectFinish();
- return m_sGC.m_orInput1;
- }
-
- // We've already deserialized the object into the correct context.
- if (pDomain == m_pCachedDomain)
- return m_sGC.m_orOutput1;
-
- // If we've updated the object in a different appdomain from the one we
- // originally started in, the cached object will be more up to date than
- // the original. Resync the objects.
- if (m_fObjectUpdated)
- UpdateObjectFinish();
-
- // Check whether we've serialized the original input object yet.
- if (m_pbObj1 == NULL && m_sGC.m_orInput1 != NULL)
- {
- AppDomainHelper::MarshalObject(m_pOriginalDomain,
- &m_sGC.m_orInput1,
- &m_pbObj1,
- &m_cbObj1);
- EnsureSerializationOK();
- }
-
- // Deserialize into the correct context.
- if (m_pbObj1 != NULL)
- {
- AppDomainHelper::UnmarshalObject(pDomain,
- m_pbObj1,
- m_cbObj1,
- &m_sGC.m_orOutput1);
- EnsureDeserializationOK();
- }
- m_pCachedDomain = pDomain;
-
- return m_sGC.m_orOutput1;
- }
-
- // As above, but retrieve both objects.
- OBJECTREF GetObjects(AppDomain *pDomain, OBJECTREF *porObject2)
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
- CheckADValidity(pDomain, ADV_RUNNINGIN);
- // No transition -- just return original objects.
- if (pDomain == m_pOriginalDomain) {
- if (m_fObjectUpdated)
- UpdateObjectFinish();
- *porObject2 = m_sGC.m_orInput2;
- return m_sGC.m_orInput1;
- }
-
- // We've already deserialized the objects into the correct context.
- if (pDomain == m_pCachedDomain) {
- *porObject2 = m_sGC.m_orOutput2;
- return m_sGC.m_orOutput1;
- }
-
- // If we've updated the object in a different appdomain from the one we
- // originally started in, the cached object will be more up to date than
- // the original. Resync the objects.
- if (m_fObjectUpdated)
- UpdateObjectFinish();
-
- // Check whether we've serialized the original input objects yet.
- if ((m_pbObj1 == NULL && m_sGC.m_orInput1 != NULL) ||
- (m_pbObj2 == NULL && m_sGC.m_orInput2 != NULL))
- {
- AppDomainHelper::MarshalObjects(m_pOriginalDomain,
- &m_sGC.m_orInput1,
- &m_sGC.m_orInput2,
- &m_pbObj1,
- &m_cbObj1,
- &m_pbObj2,
- &m_cbObj2);
- EnsureSerializationOK();
-
- }
- if (m_pbObj1 != NULL || m_pbObj2 != NULL)
- {
- // Deserialize into the correct context.
- AppDomainHelper::UnmarshalObjects(pDomain,
- m_pbObj1,
- m_cbObj1,
- m_pbObj2,
- m_cbObj2,
- &m_sGC.m_orOutput1,
- &m_sGC.m_orOutput2);
- EnsureDeserializationOK();
- }
- m_pCachedDomain = pDomain;
-
- *porObject2 = m_sGC.m_orOutput2;
- return m_sGC.m_orOutput1;
- }
-
- // Change the first object (updating the cacheing information
- // appropriately).
- void UpdateObject(AppDomain *pDomain, OBJECTREF orObject)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // The cached serialized blob is now useless.
- CheckADValidity(pDomain, ADV_RUNNINGIN);
- if (m_pbObj1)
- delete [] m_pbObj1;
- m_pbObj1 = NULL;
- m_cbObj1 = 0;
-
- // The object we have now is valid in it's own appdomain, so place that
- // in the object cache.
- m_pCachedDomain = pDomain;
- m_sGC.m_orOutput1 = orObject;
-
- // If the object is updated in the original context, just use the new
- // value as is. In this case we have the data to re-marshal the updated
- // object as normal, so we can consider the cache fully updated and exit
- // now.
- if (pDomain == m_pOriginalDomain) {
- m_sGC.m_orInput1 = orObject;
- m_fObjectUpdated = false;
- return;
- }
-
- // We want to avoid re-marshaling the updated value as long as possible
- // (it might be updated again before we need its value in a different
- // context). So set a flag to indicate that the object must be
- // re-marshaled when the value is queried in a new context.
- m_fObjectUpdated = true;
- }
-
- // This structure is public only so that it can be GC protected. Do not
- // access the fields directly, they change in an unpredictable fashion due
- // to the lazy cacheing algorithm.
- struct _gc {
- OBJECTREF m_orInput1;
- OBJECTREF m_orInput2;
- OBJECTREF m_orOutput1;
- OBJECTREF m_orOutput2;
- } m_sGC;
-
-private:
-
- // Called after one or more calls to UpdateObject to marshal the updated
- // object back into its original context (it's assumed we're called in this
- // context).
- void UpdateObjectFinish()
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(m_fObjectUpdated && m_pbObj1 == NULL);
- }
- CONTRACTL_END;
- AppDomainHelper::MarshalObject(m_pCachedDomain,
- &m_sGC.m_orOutput1,
- &m_pbObj1,
- &m_cbObj1);
- AppDomainHelper::UnmarshalObject(m_pOriginalDomain,
- m_pbObj1,
- m_cbObj1,
- &m_sGC.m_orInput1);
- m_fObjectUpdated = false;
- }
-
- BYTE *m_pbObj1;
- DWORD m_cbObj1;
- BYTE *m_pbObj2;
- DWORD m_cbObj2;
- AppDomain *m_pCachedDomain;
- AppDomain *m_pOriginalDomain;
- bool m_fObjectUpdated;
-};
-
-#endif
diff --git a/src/vm/appdomainnative.cpp b/src/vm/appdomainnative.cpp
index 3935cb5b54..de97fc5bb7 100644
--- a/src/vm/appdomainnative.cpp
+++ b/src/vm/appdomainnative.cpp
@@ -7,28 +7,15 @@
#include "common.h"
#include "appdomain.hpp"
#include "appdomainnative.hpp"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#include "appdomainhelper.h"
-#endif
#include "security.h"
#include "vars.hpp"
#include "eeconfig.h"
#include "appdomain.inl"
#include "eventtrace.h"
-#ifndef FEATURE_CORECLR
-#include "comutilnative.h"
-#endif // !FEATURE_CORECLR
#if defined(FEATURE_APPX)
#include "appxutil.h"
#endif // FEATURE_APPX
-#if defined(FEATURE_APPX_BINDER)
-#include "clrprivbinderappx.h"
-#include "clrprivtypecachewinrt.h"
-#endif // FEATURE_APPX_BINDER
-#ifdef FEATURE_VERSIONING
#include "../binder/inc/clrprivbindercoreclr.h"
-#endif
#include "clr/fs/path.h"
using namespace clr::fs;
@@ -51,9 +38,6 @@ inline AppDomain *AppDomainNative::ValidateArg(APPDOMAINREF pThis)
// Should not get here with a Transparent proxy for the this pointer -
// should have always called through onto the real object
-#ifdef FEATURE_REMOTING
- _ASSERTE(! CRemotingServices::IsTransparentProxy(OBJECTREFToObject(pThis)));
-#endif
AppDomain* pDomain = (AppDomain*)pThis->GetDomain();
@@ -72,162 +56,6 @@ inline AppDomain *AppDomainNative::ValidateArg(APPDOMAINREF pThis)
}
-#ifdef FEATURE_REMOTING
-//************************************************************************
-FCIMPL5(Object*, AppDomainNative::CreateDomain, StringObject* strFriendlyNameUNSAFE, Object* appdomainSetupUNSAFE, Object* providedEvidenceUNSAFE, Object* creatorsEvidenceUNSAFE, void* parentSecurityDescriptor)
-{
- FCALL_CONTRACT;
-
- struct _gc
- {
- OBJECTREF retVal;
- STRINGREF strFriendlyName;
- OBJECTREF appdomainSetup;
- OBJECTREF providedEvidence;
- OBJECTREF creatorsEvidence;
- OBJECTREF entryPointProxy;
- } gc;
-
- ZeroMemory(&gc, sizeof(gc));
- gc.strFriendlyName=(STRINGREF)strFriendlyNameUNSAFE;
- gc.appdomainSetup=(OBJECTREF)appdomainSetupUNSAFE;
- gc.providedEvidence=(OBJECTREF)providedEvidenceUNSAFE;
- gc.creatorsEvidence=(OBJECTREF)creatorsEvidenceUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
-
- CreateDomainHelper(&gc.strFriendlyName, &gc.appdomainSetup, &gc.providedEvidence, &gc.creatorsEvidence, parentSecurityDescriptor, &gc.entryPointProxy, &gc.retVal);
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(gc.retVal);
-}
-FCIMPLEND
-
-FCIMPL5(Object*, AppDomainNative::CreateInstance, StringObject* strFriendlyNameUNSAFE, Object* appdomainSetupUNSAFE, Object* providedEvidenceUNSAFE, Object* creatorsEvidenceUNSAFE, void* parentSecurityDescriptor)
-{
- FCALL_CONTRACT;
-
- struct _gc
- {
- OBJECTREF retVal;
- STRINGREF strFriendlyName;
- OBJECTREF appdomainSetup;
- OBJECTREF providedEvidence;
- OBJECTREF creatorsEvidence;
- OBJECTREF entryPointProxy;
- } gc;
-
- ZeroMemory(&gc, sizeof(gc));
- gc.strFriendlyName=(STRINGREF)strFriendlyNameUNSAFE;
- gc.appdomainSetup=(OBJECTREF)appdomainSetupUNSAFE;
- gc.providedEvidence=(OBJECTREF)providedEvidenceUNSAFE;
- gc.creatorsEvidence=(OBJECTREF)creatorsEvidenceUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
-
- CreateDomainHelper(&gc.strFriendlyName, &gc.appdomainSetup, &gc.providedEvidence, &gc.creatorsEvidence, parentSecurityDescriptor, &gc.entryPointProxy, &gc.retVal);
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(gc.entryPointProxy);
-}
-FCIMPLEND
-
-void AppDomainNative::CreateDomainHelper (STRINGREF* ppFriendlyName, OBJECTREF* ppAppdomainSetup, OBJECTREF* ppProvidedEvidence, OBJECTREF* ppCreatorsEvidence, void* parentSecurityDescriptor, OBJECTREF* pEntryPointProxy, OBJECTREF* pRetVal)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- PRECONDITION(IsProtectedByGCFrame(ppFriendlyName));
- PRECONDITION(IsProtectedByGCFrame(ppAppdomainSetup));
- PRECONDITION(IsProtectedByGCFrame(ppProvidedEvidence));
- PRECONDITION(IsProtectedByGCFrame(ppCreatorsEvidence));
- PRECONDITION(IsProtectedByGCFrame(pEntryPointProxy));
- PRECONDITION(IsProtectedByGCFrame(pRetVal));
- }
- CONTRACTL_END;
-
-
- AppDomainCreationHolder<AppDomain> pDomain;
-
- // This helper will send the AppDomain creation notifications for profiler / debugger.
- // If it throws, its backout code will also send a notification.
- // If it succeeds, then we still need to send a AppDomainCreateFinished notification.
- AppDomain::CreateUnmanagedObject(pDomain);
-
-#ifdef PROFILING_SUPPORTED
- EX_TRY
-#endif
- {
- OBJECTREF setupInfo=NULL;
- GCPROTECT_BEGIN(setupInfo);
-
- MethodDescCallSite prepareDataForSetup(METHOD__APP_DOMAIN__PREPARE_DATA_FOR_SETUP);
-
- ARG_SLOT args[8];
- args[0]=ObjToArgSlot(*ppFriendlyName);
- args[1]=ObjToArgSlot(*ppAppdomainSetup);
- args[2]=ObjToArgSlot(*ppProvidedEvidence);
- args[3]=ObjToArgSlot(*ppCreatorsEvidence);
- args[4]=PtrToArgSlot(parentSecurityDescriptor);
- args[5]=PtrToArgSlot(NULL);
- args[6]=PtrToArgSlot(NULL);
- args[7]=PtrToArgSlot(NULL);
-
- setupInfo = prepareDataForSetup.Call_RetOBJECTREF(args);
-
-#ifndef FEATURE_CORECLR
- // We need to setup domain sorting before any other managed code runs in the domain, since that code
- // could end up caching data based on the sorting mode of the domain.
- pDomain->InitializeSorting(ppAppdomainSetup);
- pDomain->InitializeHashing(ppAppdomainSetup);
-#endif
-
- // We need to ensure that the AppDomainProxy is generated before we call into DoSetup, since
- // GetAppDomainProxy will ensure that remoting is correctly configured in the domain. DoSetup can
- // end up loading user assemblies into the domain, and those assemblies may require that remoting be
- // setup already. For instance, C++/CLI applications may trigger the CRT to try to marshal a
- // reference to the default domain into the current domain, which won't work correctly without this
- // setup being done.
- *pRetVal = pDomain->GetAppDomainProxy();
-
- *pEntryPointProxy=pDomain->DoSetup(&setupInfo);
-
-
- GCPROTECT_END();
-
- pDomain->CacheStringsForDAC();
- }
-
-#ifdef PROFILING_SUPPORTED
- EX_HOOK
- {
- // Need the first assembly loaded in to get any data on an app domain.
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackAppDomainLoads());
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->AppDomainCreationFinished((AppDomainID)(AppDomain *) pDomain, GET_EXCEPTION()->GetHR());
- END_PIN_PROFILER();
- }
- }
- EX_END_HOOK;
-
- // Need the first assembly loaded in to get any data on an app domain.
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackAppDomainLoads());
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->AppDomainCreationFinished((AppDomainID)(AppDomain*) pDomain, S_OK);
- END_PIN_PROFILER();
- }
-#endif // PROFILING_SUPPORTED
-
- ETW::LoaderLog::DomainLoad(pDomain, (LPWSTR)(*ppFriendlyName)->GetBuffer());
-
- // DoneCreating releases ownership of AppDomain. After this call, there should be no access to pDomain.
- pDomain.DoneCreating();
-}
-#endif // FEATURE_REMOTING
void QCALLTYPE AppDomainNative::SetupDomainSecurity(QCall::AppDomainHandle pDomain,
QCall::ObjectHandleOnStack ohEvidence,
@@ -289,38 +117,10 @@ void QCALLTYPE AppDomainNative::SetupDomainSecurity(QCall::AppDomainHandle pDoma
}
}
-#ifdef FEATURE_CAS_POLICY
- if (gc.orEvidence != NULL)
- {
- pSecDesc->SetEvidence(gc.orEvidence);
- }
-#endif // FEATURE_CAS_POLICY
// We need to downgrade sharing level if the AppDomain is homogeneous and not fully trusted, or the
// AppDomain is in legacy mode. Effectively, we need to be sure that all assemblies loaded into the
// domain must be fully trusted in order to allow non-GAC sharing.
-#ifdef FEATURE_FUSION
- if (pDomain->GetSharePolicy() == AppDomain::SHARE_POLICY_ALWAYS)
- {
- bool fSandboxedHomogenousDomain = false;
- if (pSecDesc->IsHomogeneous())
- {
- pSecDesc->Resolve();
- fSandboxedHomogenousDomain = !pSecDesc->IsFullyTrusted();
- }
-
- if (fSandboxedHomogenousDomain || pSecDesc->IsLegacyCasPolicyEnabled())
- {
- // We may not be able to reduce sharing policy at this point, if we have already loaded
- // some non-GAC assemblies as domain neutral. For this case we must regrettably fail
- // the whole operation.
- if (!pDomain->ReduceSharePolicyFromAlways())
- {
- ThrowHR(COR_E_CANNOT_SET_POLICY);
- }
- }
- }
-#endif
// Now finish the initialization.
pSecDesc->FinishInitialization();
@@ -421,25 +221,6 @@ FCIMPLEND
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_FUSION
-FCIMPL1(LPVOID, AppDomainNative::GetFusionContext, AppDomainBaseObject* refThis)
-{
- FCALL_CONTRACT;
-
- LPVOID rv = NULL;
-
- HELPER_METHOD_FRAME_BEGIN_RET_1(rv);
-
- AppDomain* pApp = ValidateArg((APPDOMAINREF)refThis);
-
- rv = pApp->CreateFusionContext();
-
- HELPER_METHOD_FRAME_END();
-
- return rv;
-}
-FCIMPLEND
-#endif
FCIMPL1(void*, AppDomainNative::GetSecurityDescriptor, AppDomainBaseObject* refThisUNSAFE)
{
@@ -474,51 +255,7 @@ FCIMPL2(void, AppDomainNative::UpdateLoaderOptimization, AppDomainBaseObject* re
FCIMPLEND
#endif // FEATURE_LOADER_OPTIMIZATION
-#ifdef FEATURE_FUSION
-FCIMPL3(void, AppDomainNative::UpdateContextProperty, LPVOID fusionContext, StringObject* keyUNSAFE, Object* valueUNSAFE)
-{
- FCALL_CONTRACT;
-
- struct _gc
- {
- STRINGREF key;
- OBJECTREF value;
- } gc;
-
- gc.key = ObjectToSTRINGREF(keyUNSAFE);
- gc.value = ObjectToOBJECTREF(valueUNSAFE);
- _ASSERTE(gc.key != NULL);
-
- HELPER_METHOD_FRAME_BEGIN_PROTECT(gc);
-
- IApplicationContext* pContext = (IApplicationContext*) fusionContext;
-
- BOOL fFXOnly;
- DWORD size = sizeof(fFXOnly);
- HRESULT hr = pContext->Get(ACTAG_FX_ONLY, &fFXOnly, &size, 0);
- if (hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
- {
- fFXOnly = FALSE;
- hr = S_FALSE;
- }
- IfFailThrow(hr);
- if (!fFXOnly)
- {
- DWORD lgth = gc.key->GetStringLength();
- CQuickBytes qb;
- LPWSTR key = (LPWSTR) qb.AllocThrows((lgth+1)*sizeof(WCHAR));
- memcpy(key, gc.key->GetBuffer(), lgth*sizeof(WCHAR));
- key[lgth] = W('\0');
-
- AppDomain::SetContextProperty(pContext, key, &gc.value);
- }
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-#endif // FEATURE_FUSION
-
-#ifdef FEATURE_VERSIONING
FCIMPL1(void,
AppDomainNative::CreateContext,
AppDomainBaseObject *refThisUNSAFE)
@@ -578,7 +315,6 @@ void QCALLTYPE AppDomainNative::SetupBindingPaths(__in_z LPCWSTR wszTrustedPlatf
END_QCALL;
}
-#endif // FEATURE_VERSIONING
FCIMPL9(Object*, AppDomainNative::CreateDynamicAssembly, AppDomainBaseObject* refThisUNSAFE, AssemblyNameBaseObject* assemblyNameUNSAFE, Object* identityUNSAFE, StackCrawlMark* stackMark, U1Array *securityRulesBlobUNSAFE, U1Array *aptcaBlobUNSAFE, INT32 access, INT32 dwFlags, SecurityContextSource securityContextSource)
{
@@ -651,12 +387,8 @@ enum
APPX_FLAGS_APPX_MODEL = 0x02,
APPX_FLAGS_APPX_DESIGN_MODE = 0x04,
- APPX_FLAGS_APPX_NGEN = 0x08,
APPX_FLAGS_APPX_MASK = APPX_FLAGS_APPX_MODEL |
- APPX_FLAGS_APPX_DESIGN_MODE |
- APPX_FLAGS_APPX_NGEN,
-
- APPX_FLAGS_API_CHECK = 0x10,
+ APPX_FLAGS_APPX_DESIGN_MODE,
};
// static
@@ -674,28 +406,6 @@ INT32 QCALLTYPE AppDomainNative::GetAppXFlags()
if (AppX::IsAppXDesignMode())
flags |= APPX_FLAGS_APPX_DESIGN_MODE;
- else
- flags |= APPX_FLAGS_API_CHECK;
-
- if (AppX::IsAppXNGen())
- flags |= APPX_FLAGS_APPX_NGEN;
- }
-
- //
- // 0: normal (only check in non-dev-mode APPX)
- // 1: always check
- // 2: never check
- //
- switch (g_pConfig->GetWindows8ProfileAPICheckFlag())
- {
- case 1:
- flags |= APPX_FLAGS_API_CHECK;
- break;
- case 2:
- flags &= ~APPX_FLAGS_API_CHECK;
- break;
- default:
- break;
}
END_QCALL;
@@ -794,53 +504,6 @@ void QCALLTYPE AppDomainNative::SetAppDomainManagerType(QCall::AppDomainHandle a
END_QCALL;
}
-#ifdef FEATURE_APPDOMAINMANAGER_INITOPTIONS
-
-FCIMPL0(FC_BOOL_RET, AppDomainNative::HasHost)
-{
- FCALL_CONTRACT;
- FC_RETURN_BOOL(CorHost2::GetHostControl() != NULL);
-}
-FCIMPLEND
-
-//
-// Callback to the CLR host to register an AppDomainManager->AppDomain ID pair with it.
-//
-// Arguments:
-// punkAppDomainManager - COM reference to the AppDomainManager being registered with the host
-//
-
-// static
-void QCALLTYPE AppDomainNative::RegisterWithHost(IUnknown *punkAppDomainManager)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(CheckPointer(punkAppDomainManager));
- PRECONDITION(CheckPointer(CorHost2::GetHostControl()));
- }
- CONTRACTL_END;
-
- BEGIN_QCALL;
-
- EnsureComStarted();
-
- IHostControl *pHostControl = CorHost2::GetHostControl();
- ADID dwDomainId = SystemDomain::GetCurrentDomain()->GetId();
- HRESULT hr = S_OK;
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pHostControl->SetAppDomainManager(dwDomainId.m_dwId, punkAppDomainManager);
- END_SO_TOLERANT_CODE_CALLING_HOST;
-
- if (FAILED(hr))
- {
- ThrowHR(hr);
- }
-
- END_QCALL;
-}
-#endif // FEATURE_APPDOMAINMANAGER_INITOPTIONS
FCIMPL1(void, AppDomainNative::SetHostSecurityManagerFlags, DWORD dwFlags);
{
@@ -868,59 +531,7 @@ void QCALLTYPE AppDomainNative::SetSecurityHomogeneousFlag(QCall::AppDomainHandl
END_QCALL;
}
-#ifdef FEATURE_CAS_POLICY
-
-// static
-void QCALLTYPE AppDomainNative::SetLegacyCasPolicyEnabled(QCall::AppDomainHandle adhTarget)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- IApplicationSecurityDescriptor *pAppSecDesc = adhTarget->GetSecurityDescriptor();
- pAppSecDesc->SetLegacyCasPolicyEnabled();
-
- END_QCALL;
-}
-
-// static
-BOOL QCALLTYPE AppDomainNative::IsLegacyCasPolicyEnabled(QCall::AppDomainHandle adhTarget)
-{
- QCALL_CONTRACT;
-
- BOOL fLegacyCasPolicy = FALSE;
-
- BEGIN_QCALL;
-
- IApplicationSecurityDescriptor *pAppSecDesc = adhTarget->GetSecurityDescriptor();
- fLegacyCasPolicy = !!pAppSecDesc->IsLegacyCasPolicyEnabled();
-
- END_QCALL;
-
- return fLegacyCasPolicy;
-}
-
-#endif // FEATURE_CAS_POLICY
-
-#ifdef FEATURE_APTCA
-
-// static
-void QCALLTYPE AppDomainNative::SetCanonicalConditionalAptcaList(QCall::AppDomainHandle adhTarget,
- LPCWSTR wszCanonicalConditionalAptcaList)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- IApplicationSecurityDescriptor *pAppSecDesc = adhTarget->GetSecurityDescriptor();
-
- GCX_COOP();
- pAppSecDesc->SetCanonicalConditionalAptcaList(wszCanonicalConditionalAptcaList);
-
- END_QCALL;
-}
-#endif // FEATURE_APTCA
FCIMPL1(Object*, AppDomainNative::GetFriendlyName, AppDomainBaseObject* refThisUNSAFE)
{
@@ -1063,25 +674,6 @@ FCIMPL1(FC_BOOL_RET, AppDomainNative::IsDomainIdValid, INT32 dwId)
}
FCIMPLEND
-#ifdef FEATURE_REMOTING
-FCIMPL0(Object*, AppDomainNative::GetDefaultDomain)
-{
- FCALL_CONTRACT;
-
- APPDOMAINREF rv = NULL;
-
- HELPER_METHOD_FRAME_BEGIN_RET_1(rv);
-
- if (GetThread()->GetDomain()->IsDefaultDomain())
- rv = (APPDOMAINREF) SystemDomain::System()->DefaultDomain()->GetExposedObject();
- else
- rv = (APPDOMAINREF) SystemDomain::System()->DefaultDomain()->GetAppDomainProxy();
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(rv);
-}
-FCIMPLEND
-#endif
FCIMPL1(INT32, AppDomainNative::GetId, AppDomainBaseObject* refThisUNSAFE)
{
@@ -1111,18 +703,6 @@ FCIMPL1(void, AppDomainNative::ChangeSecurityPolicy, AppDomainBaseObject* refThi
HELPER_METHOD_FRAME_BEGIN_1(refThis);
AppDomain* pApp = ValidateArg(refThis);
-#ifdef FEATURE_FUSION
-
- // We do not support sharing behavior of ALWAYS when using app-domain local security config
- if (pApp->GetSharePolicy() == AppDomain::SHARE_POLICY_ALWAYS)
- {
- // We may not be able to reduce sharing policy at this point, if we have already loaded
- // some non-GAC assemblies as domain neutral. For this case we must regrettably fail
- // the whole operation.
- if (!pApp->ReduceSharePolicyFromAlways())
- ThrowHR(COR_E_CANNOT_SET_POLICY);
- }
-#endif
pApp->GetSecurityDescriptor()->SetPolicyLevelFlag();
HELPER_METHOD_FRAME_END();
@@ -1188,14 +768,6 @@ FCIMPL1(Object*, AppDomainNative::GetDynamicDir, AppDomainBaseObject* refThisUNS
FCALL_CONTRACT;
STRINGREF str = NULL;
-#ifdef FEATURE_FUSION
- APPDOMAINREF refThis = (APPDOMAINREF) refThisUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_1(refThis);
-
- AppDomain *pDomain = ValidateArg(refThis);
- str = StringObject::NewString(pDomain->GetDynamicDir());
- HELPER_METHOD_FRAME_END();
-#endif
return OBJECTREFToObject(str);
}
FCIMPLEND
@@ -1292,29 +864,7 @@ FCIMPL2(StringObject*, AppDomainNative::nApplyPolicy, AppDomainBaseObject* refTh
StackSString sDisplayName;
-#ifdef FEATURE_FUSION
- {
- GCX_PREEMP();
-
- SafeComHolderPreemp<IAssemblyName> pAssemblyName(NULL);
- SafeComHolderPreemp<IAssemblyName> pBoundName(NULL);
- IfFailThrow(spec.CreateFusionName(&pAssemblyName));
- HRESULT hr = PreBindAssembly(pDomain->GetFusionContext(),
- pAssemblyName,
- NULL, // pAsmParent (only needed to see if parent is loadfrom - in this case, we always want it to load in the normal ctx)
- &pBoundName,
- NULL // pvReserved
- );
- if (FAILED(hr) && hr != FUSION_E_REF_DEF_MISMATCH)
- {
- ThrowHR(hr);
- }
-
- FusionBind::GetAssemblyNameDisplayName(pBoundName, /*modifies*/sDisplayName, 0 /*flags*/);
- }
-#else
spec.GetFileOrDisplayName(0,sDisplayName);
-#endif
gc.rv = StringObject::NewString(sDisplayName);
@@ -1360,7 +910,6 @@ FCIMPL1(void , AppDomainNative::PublishAnonymouslyHostedDynamicMethodsAssembly,
}
FCIMPLEND
-#ifdef FEATURE_CORECLR
void QCALLTYPE AppDomainNative::SetNativeDllSearchDirectories(__in_z LPCWSTR wszNativeDllSearchDirectories)
{
@@ -1417,7 +966,6 @@ void QCALLTYPE AppDomainNative::SetNativeDllSearchDirectories(__in_z LPCWSTR wsz
END_QCALL;
}
-#endif // FEATURE_CORECLR
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
FCIMPL0(void, AppDomainNative::EnableMonitoring)
@@ -1532,55 +1080,4 @@ FCIMPL0(INT64, AppDomainNative::GetLastSurvivedProcessMemorySize)
FCIMPLEND
#endif // FEATURE_APPDOMAIN_RESOURCE_MONITORING
-#if defined(FEATURE_APPX_BINDER)
-ICLRPrivBinder * QCALLTYPE AppDomainNative::CreateDesignerContext(LPCWSTR *rgPaths,
- UINT cPaths,
- BOOL fShared)
-{
- QCALL_CONTRACT;
-
- ICLRPrivBinder *pRetVal = nullptr;
-
- BEGIN_QCALL;
- ReleaseHolder<ICLRPrivBinder> pBinder;
-
- // The runtime check is done on the managed side to enable the debugger to use
- // FuncEval to create designer contexts outside of DesignMode.
- _ASSERTE(AppX::IsAppXDesignMode() || (AppX::IsAppXProcess() && CORDebuggerAttached()));
-
- AppDomain *pAppDomain = GetAppDomain();
-
- pBinder = CLRPrivBinderAppX::CreateParentedBinder(fShared ? pAppDomain->GetLoadContextHostBinder() : pAppDomain->GetSharedContextHostBinder(), CLRPrivTypeCacheWinRT::GetOrCreateTypeCache(), rgPaths, cPaths, fShared /* fCanUseNativeImages */);
-
- {
- BaseDomain::LockHolder lh(pAppDomain);
- pAppDomain->AppDomainInterfaceReleaseList.Append(pRetVal);
- }
- pBinder.SuppressRelease();
- pRetVal = pBinder;
-
- END_QCALL;
-
- return pRetVal;
-}
-
-void QCALLTYPE AppDomainNative::SetCurrentDesignerContext(BOOL fDesignerContext, ICLRPrivBinder *newContext)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- if (fDesignerContext)
- {
- GetAppDomain()->SetCurrentContextHostBinder(newContext);
- }
- else
- {
- // Managed code is responsible for ensuring this isn't called more than once per AppDomain.
- GetAppDomain()->SetSharedContextHostBinder(newContext);
- }
-
- END_QCALL;
-}
-#endif // defined(FEATURE_APPX_BINDER)
diff --git a/src/vm/appdomainnative.hpp b/src/vm/appdomainnative.hpp
index cb0c364cfa..7693e6019a 100644
--- a/src/vm/appdomainnative.hpp
+++ b/src/vm/appdomainnative.hpp
@@ -21,10 +21,6 @@ class AppDomainNative
{
public:
static AppDomain *ValidateArg(APPDOMAINREF pThis);
-#ifdef FEATURE_REMOTING
- static FCDECL5(Object*, CreateDomain, StringObject* strFriendlyNameUNSAFE, Object* appdomainSetup, Object* providedEvidenceUNSAFE, Object* creatorsEvidenceUNSAFE, void* parentSecurityDescriptor);
- static FCDECL5(Object*, CreateInstance, StringObject* strFriendlyNameUNSAFE, Object* appdomainSetup, Object* providedEvidenceUNSAFE, Object* creatorsEvidenceUNSAFE, void* parentSecurityDescriptor);
-#endif
static FCDECL2(void, SetupFriendlyName, AppDomainBaseObject* refThisUNSAFE, StringObject* strFriendlyNameUNSAFE);
#if FEATURE_COMINTEROP
static FCDECL1(void, SetDisableInterfaceCache, AppDomainBaseObject* refThisUNSAFE);
@@ -35,18 +31,13 @@ public:
#endif // FEATURE_LOADER_OPTIMIZATION
static FCDECL9(Object*, CreateDynamicAssembly, AppDomainBaseObject* refThisUNSAFE, AssemblyNameBaseObject* assemblyNameUNSAFE, Object* identityUNSAFE, StackCrawlMark* stackMark, U1Array* securityRulesBlobUNSAFE, U1Array* aptcaBlobUNSAFE, INT32 access, INT32 flags, SecurityContextSource securityContextSource);
-#ifdef FEATURE_APPDOMAINMANAGER_INITOPTIONS
- static FCDECL0(FC_BOOL_RET, HasHost);
-#endif // FEATURE_APPDOMAINMANAGER_INITOPTIONS
static FCDECL1(void, SetHostSecurityManagerFlags, DWORD dwFlags);
static FCDECL1(Object*, GetFriendlyName, AppDomainBaseObject* refThisUNSAFE);
static FCDECL1(FC_BOOL_RET, IsDefaultAppDomainForEvidence, AppDomainBaseObject* refThisUNSAFE);
static FCDECL2(Object*, GetAssemblies, AppDomainBaseObject* refThisUNSAFE, CLR_BOOL fForIntrospection);
static FCDECL2(Object*, GetOrInternString, AppDomainBaseObject* refThisUNSAFE, StringObject* pStringUNSAFE);
-#ifdef FEATURE_VERSIONING
static FCDECL1(void, CreateContext, AppDomainBaseObject *refThisUNSAFE);
static void QCALLTYPE SetupBindingPaths(__in_z LPCWSTR wszTrustedPlatformAssemblies, __in_z LPCWSTR wszPlatformResourceRoots, __in_z LPCWSTR wszAppPaths, __in_z LPCWSTR wszAppNiPaths, __in_z LPCWSTR appLocalWinMD);
-#endif // FEATURE_VERSIONING
static FCDECL1(void, Unload, INT32 dwId);
static FCDECL1(Object*, GetDynamicDir, AppDomainBaseObject* refThisUNSAFE);
static FCDECL1(INT32, GetId, AppDomainBaseObject* refThisUNSAFE);
@@ -55,9 +46,6 @@ public:
static FCDECL1(FC_BOOL_RET, IsFinalizingForUnload, AppDomainBaseObject* refThisUNSAFE);
static FCDECL1(void, ForceToSharedDomain, Object* pObjectUNSAFE);
static FCDECL1(void, ChangeSecurityPolicy, AppDomainBaseObject* refThisUNSAFE);
-#ifdef FEATURE_REMOTING
- static FCDECL0(Object*, GetDefaultDomain);
-#endif
static FCDECL1(LPVOID, GetFusionContext, AppDomainBaseObject* refThis);
static FCDECL2(Object*, IsStringInterned, AppDomainBaseObject* refThis, StringObject* pString);
static FCDECL1(FC_BOOL_RET, IsUnloadingForcedFinalize, AppDomainBaseObject* refThis);
@@ -66,9 +54,7 @@ public:
static FCDECL2(FC_BOOL_RET, IsFrameworkAssembly, AppDomainBaseObject* refThisUNSAFE, AssemblyNameBaseObject* refAssemblyNameUNSAFE);
static FCDECL1(UINT32, GetAppDomainId, AppDomainBaseObject* refThisUNSAFE);
static FCDECL1(void , PublishAnonymouslyHostedDynamicMethodsAssembly, AssemblyBaseObject * pAssemblyUNSAFE);
-#ifdef FEATURE_CORECLR
static void QCALLTYPE SetNativeDllSearchDirectories(__in_z LPCWSTR wszAssembly);
-#endif // FEATURE_CORECLR
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
static FCDECL0(void, EnableMonitoring);
@@ -83,9 +69,6 @@ private:
static INT32 ExecuteAssemblyHelper(Assembly* pAssembly,
BOOL bCreatedConsole,
PTRARRAYREF *pStringArgs);
-#ifdef FEATURE_REMOTING
- static void CreateDomainHelper (STRINGREF* ppFriendlyName, OBJECTREF* ppAppdomainSetup, OBJECTREF* ppProvidedEvidence, OBJECTREF* ppCreatorsEvidence, void* parentSecurityDescriptor, OBJECTREF* pEntryPointProxy, OBJECTREF* pRetVal);
-#endif
public:
static
@@ -121,32 +104,9 @@ public:
void QCALLTYPE SetSecurityHomogeneousFlag(QCall::AppDomainHandle adhTarget,
BOOL fRuntimeSuppliedHomgenousGrantSet);
-#ifdef FEATURE_CAS_POLICY
- static
- void QCALLTYPE SetLegacyCasPolicyEnabled(QCall::AppDomainHandle adhTarget);
-
- static
- BOOL QCALLTYPE IsLegacyCasPolicyEnabled(QCall::AppDomainHandle adhTarget);
-#endif // FEATURE_CAS_POLICY
-
-#ifdef FEATURE_APTCA
- static
- void QCALLTYPE SetCanonicalConditionalAptcaList(QCall::AppDomainHandle adhTarget,
- LPCWSTR wszCanonicalConditionalAptcaList);
-#endif // FEATURE_APTCA
-#ifdef FEATURE_APPDOMAINMANAGER_INITOPTIONS
- static
- void QCALLTYPE RegisterWithHost(IUnknown *punkAppDomainManager);
-#endif // FEATURE_APPDOMAINMANAGER_INITOPTIONS
-#if defined(FEATURE_APPX_BINDER)
- static
- ICLRPrivBinder * QCALLTYPE CreateDesignerContext(LPCWSTR *rgPaths, UINT cPaths, BOOL fShared);
- static
- void QCALLTYPE SetCurrentDesignerContext(BOOL fDesignerContext, ICLRPrivBinder *newContext);
-#endif
};
#endif
diff --git a/src/vm/appdomainstack.cpp b/src/vm/appdomainstack.cpp
index 7e55a8d597..5561b7d22c 100644
--- a/src/vm/appdomainstack.cpp
+++ b/src/vm/appdomainstack.cpp
@@ -14,11 +14,7 @@
#include "security.h"
#include "securitypolicy.h"
#include "appdomain.inl"
-#ifdef FEATURE_REMOTING
-#include "crossdomaincalls.h"
-#else
#include "callhelpers.h"
-#endif
#ifdef _DEBUG
void AppDomainStack::CheckOverridesAssertCounts()
diff --git a/src/vm/appxutil.cpp b/src/vm/appxutil.cpp
index 6bc04d74cd..0796cf9062 100644
--- a/src/vm/appxutil.cpp
+++ b/src/vm/appxutil.cpp
@@ -50,7 +50,6 @@ namespace AppX
{
GCX_PREEMP();
- LeaveRuntimeHolder lrh(::RoInitialize);
// Prefer MultiThreaded when AnyThreadedMultiPreferred is specified.
hr = ::RoInitialize((threadingModel == SingleThreaded) ? RO_INIT_SINGLETHREADED
@@ -148,48 +147,9 @@ namespace AppX
}
CONTRACTL_END
-#ifdef FEATURE_CORECLR
// CoreCLR does not have proper support for AppX design mode. Once/if it has one, it should not need
// any special casing like desktop. Avoid the expensive check completely.
return false;
-#else
- // DevMode does not change over the lifetime of a process and is expensive to compute
- // Cache the first answer and return it once computed; idempotent so races are fine
- static enum
- {
- CachedAppxMode_Unknown,
- CachedAppxMode_Normal,
- CachedAppxMode_Design
- }
- s_cachedAppxMode = CachedAppxMode_Unknown;
-
- bool result = false;
-
- switch (s_cachedAppxMode)
- {
- case CachedAppxMode_Unknown:
- if (SUCCEEDED(IsAppXDesignModeWorker(&result)))
- { // Cache the result on success; otherwise use the default value of false.
- s_cachedAppxMode = result ? CachedAppxMode_Design : CachedAppxMode_Normal;
- }
- break;
-
- case CachedAppxMode_Normal:
- result = false;
- break;
-
- case CachedAppxMode_Design:
- result = true;
- break;
- }
-
-#ifdef _DEBUG
- bool dbg_result = false;
- _ASSERTE(FAILED(IsAppXDesignModeWorker(&dbg_result)) || dbg_result == result);
-#endif
-
- return result;
-#endif // FEATURE_CORECLR
}
HRESULT GetApplicationId(LPCWSTR& rString)
diff --git a/src/vm/aptca.cpp b/src/vm/aptca.cpp
deleted file mode 100644
index e4e8f19255..0000000000
--- a/src/vm/aptca.cpp
+++ /dev/null
@@ -1,1363 +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.
-//--------------------------------------------------------------------------
-// aptca.h
-//
-// Functions for handling allow partially trusted callers assemblies
-//
-
-//
-//--------------------------------------------------------------------------
-
-
-#include "common.h"
-#include "aptca.h"
-
-//
-// Conditional APTCA cache implementation
-//
-
-ConditionalAptcaCache::ConditionalAptcaCache(AppDomain *pAppDomain)
- : m_pAppDomain(pAppDomain),
- m_canonicalListIsNull(false),
- m_domainState(kDomainStateUnknown)
-{
- WRAPPER_NO_CONTRACT;
-
- _ASSERTE(pAppDomain != NULL);
-}
-
-ConditionalAptcaCache::~ConditionalAptcaCache()
-{
- WRAPPER_NO_CONTRACT;
-}
-
-void ConditionalAptcaCache::SetCachedState(PTR_PEImage pImage, ConditionalAptcaCache::State state)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pImage));
- PRECONDITION(state != kUnknown);
- }
- CONTRACTL_END;
-
- if (state == kNotCAptca)
- {
- pImage->SetIsNotConditionalAptca();
- }
-}
-
-ConditionalAptcaCache::State ConditionalAptcaCache::GetCachedState(PTR_PEImage pImage)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pImage));
- }
- CONTRACTL_END;
-
- if (!pImage->MayBeConditionalAptca())
- {
- return kNotCAptca;
- }
-
- return kUnknown;
-}
-
-void ConditionalAptcaCache::SetCanonicalConditionalAptcaList(LPCWSTR wszCanonicalConditionalAptcaList)
-{
- WRAPPER_NO_CONTRACT;
- m_canonicalListIsNull = (wszCanonicalConditionalAptcaList == NULL);
- m_canonicalList.Set(wszCanonicalConditionalAptcaList);
-}
-
-#ifndef CROSSGEN_COMPILE
-ConditionalAptcaCache::DomainState ConditionalAptcaCache::GetConditionalAptcaDomainState()
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- THROWS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (m_domainState == kDomainStateUnknown)
- {
- IApplicationSecurityDescriptor *pASD = m_pAppDomain->GetSecurityDescriptor();
- DomainState domainState = kDomainStateUnknown;
-
- // In the full trust case we only need to look at the conditional APTCA list in the case that the host
- // has configured one on the default domain (for instance WPF). Otherwise, all full trust domains have
- // all conditional APTCA assemblies enabled.
- bool processFullTrustAptcaList = false;
- if (m_pAppDomain->IsCompilationDomain())
- {
- processFullTrustAptcaList = false;
- }
- else if (m_pAppDomain->IsDefaultDomain())
- {
- processFullTrustAptcaList = !m_canonicalListIsNull;
- }
- else
- {
- processFullTrustAptcaList = ConsiderFullTrustConditionalAptcaLists();
- }
-
- // Consider the domain to be fully trusted if it really is fully trusted, or if we're currently
- // setting the domain up, it looks like it will be fully trusted, and the AppDomainManager has
- // promised that won't change.
- bool isFullTrustDomain = !m_pAppDomain->GetSecurityDescriptor()->DomainMayContainPartialTrustCode();
- if (pASD->IsInitializationInProgress() && (m_pAppDomain->GetAppDomainManagerInitializeNewDomainFlags() & eInitializeNewDomainFlags_NoSecurityChanges))
- {
- BOOL preResolveFullTrust;
- BOOL preResolveHomogenous;
- pASD->PreResolve(&preResolveFullTrust, &preResolveHomogenous);
-
- isFullTrustDomain = preResolveFullTrust && preResolveHomogenous;
- }
-
- if (m_pAppDomain->IsCompilationDomain())
- {
- // NGEN always enables all conditional APTCA assemblies
- domainState = kAllEnabled;
- }
- else if (!isFullTrustDomain || processFullTrustAptcaList)
- {
- if (m_canonicalList.GetCount() == 0)
- {
- // A null or empty conditional APTCA list means that no assemblies are enabled in this domain
- domainState = kAllDisabled;
- }
- else
- {
- // We're in a domain that supports conditional APTCA and an interesting list is supplied. In
- // this domain, some assemblies are enabled.
- domainState = kSomeEnabled;
- }
- }
- else
- {
- domainState = kAllEnabled;
- }
-
- _ASSERTE(domainState != kDomainStateUnknown);
- InterlockedCompareExchange(reinterpret_cast<volatile LONG *>(&m_domainState), domainState, kDomainStateUnknown);
- }
-
- return m_domainState;
-}
-
-// static
-bool ConditionalAptcaCache::ConsiderFullTrustConditionalAptcaLists()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (GetAppDomain()->IsCompilationDomain())
- {
- return false;
- }
-
- IApplicationSecurityDescriptor *pASD = SystemDomain::System()->DefaultDomain()->GetSecurityDescriptor();
- ConditionalAptcaCache *pDefaultDomainCaptca = pASD->GetConditionalAptcaCache();
-
- // The only way that we use CAPTCA lists is if the host has configured the default domain to not be all
- // enabled (that is, the host has setup a CAPTCA list of any sort for the default domain)
- return pDefaultDomainCaptca->GetConditionalAptcaDomainState() != kAllEnabled;
-}
-
-// APTCA killbit list helper functions
-namespace
-{
- static const LPCWSTR wszAptcaRootKey = W("SOFTWARE\\Microsoft\\.NETFramework\\Policy\\APTCA");
-
- //--------------------------------------------------------------------------------------------------------
- //
- // The AptcaKillBitList class is responsible for holding the machine wide list of assembly name / file
- // versions which have been disabled for APTCA on the machine.
- //
-
- class AptcaKillBitList
- {
- private:
- ArrayList m_killBitList;
-
- public:
- ~AptcaKillBitList();
-
- bool AreAnyAssembliesKillBitted();
- bool IsAssemblyKillBitted(PEAssembly *pAssembly);
- bool IsAssemblyKillBitted(IAssemblyName *pAssemblyName, ULARGE_INTEGER fileVersion);
-
- static AptcaKillBitList *ReadMachineKillBitList();
-
- private:
- AptcaKillBitList();
- AptcaKillBitList(const AptcaKillBitList &other); // not implemented
-
- private:
- static const LPCWSTR wszKillBitValue;
-
- private:
- static bool FileVersionsAreEqual(ULARGE_INTEGER targetVersion, IAssemblyName *pKillBitAssemblyName);
- };
- const LPCWSTR AptcaKillBitList::wszKillBitValue = W("APTCA_FLAG");
-
- AptcaKillBitList::AptcaKillBitList()
- {
- LIMITED_METHOD_CONTRACT;
- }
-
- AptcaKillBitList::~AptcaKillBitList()
- {
- WRAPPER_NO_CONTRACT;
-
- // Release all of the IAssemblyName objects stored in this list
- for (DWORD i = 0; i < m_killBitList.GetCount(); ++i)
- {
- IAssemblyName *pKillBitAssemblyName = reinterpret_cast<IAssemblyName *>(m_killBitList.Get(i));
- if (pKillBitAssemblyName != NULL)
- {
- pKillBitAssemblyName->Release();
- }
- }
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Determine if any assemblies are on the APTCA killbit list
- //
-
- bool AptcaKillBitList::AreAnyAssembliesKillBitted()
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // We don't consider the killbit for NGEN, as ngened code always assumes that APTCA is enabled.
- if (GetAppDomain()->IsCompilationDomain())
- {
- return false;
- }
-
- return m_killBitList.GetCount() > 0;
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Compare the file versions of an assembly with the verison that is being killbitted to see if they
- // match. For compatibility with v3.5, we assume any failure means that the versions do not match.
- //
-
- // static
- bool AptcaKillBitList::FileVersionsAreEqual(ULARGE_INTEGER targetVersion, IAssemblyName *pKillBitAssemblyName)
- {
- DWORD dwKillBitMajorVersion = 0;
- DWORD dwVersionSize = sizeof(dwKillBitMajorVersion);
- if (FAILED(pKillBitAssemblyName->GetProperty(ASM_NAME_FILE_MAJOR_VERSION, &dwKillBitMajorVersion, &dwVersionSize)) ||
- dwVersionSize == 0)
- {
- return false;
- }
-
- DWORD dwKillBitMinorVersion = 0;
- dwVersionSize = sizeof(dwKillBitMinorVersion);
- if (FAILED(pKillBitAssemblyName->GetProperty(ASM_NAME_FILE_MINOR_VERSION, &dwKillBitMinorVersion, &dwVersionSize)) ||
- dwVersionSize == 0)
- {
- return false;
- }
-
- DWORD dwKillBitBuildVersion = 0;
- dwVersionSize = sizeof(dwKillBitBuildVersion);
- if (FAILED(pKillBitAssemblyName->GetProperty(ASM_NAME_FILE_BUILD_NUMBER, &dwKillBitBuildVersion, &dwVersionSize)) ||
- dwVersionSize == 0)
- {
- return false;
- }
-
- DWORD dwKillBitRevisionVersion = 0;
- dwVersionSize = sizeof(dwKillBitRevisionVersion);
- if (FAILED(pKillBitAssemblyName->GetProperty(ASM_NAME_FILE_REVISION_NUMBER, &dwKillBitRevisionVersion, &dwVersionSize)) ||
- dwVersionSize == 0)
- {
- return false;
- }
-
- DWORD dwTargetMajorVersion = (targetVersion.HighPart & 0xFFFF0000) >> 16;
- DWORD dwTargetMinorVersion = targetVersion.HighPart & 0x0000FFFF;
- DWORD dwTargetBuildVersion = (targetVersion.LowPart & 0xFFFF0000) >> 16;
- DWORD dwTargetRevisionVersion = targetVersion.LowPart & 0x0000FFFF;
-
- return dwTargetMajorVersion == dwKillBitMajorVersion &&
- dwTargetMinorVersion == dwKillBitMinorVersion &&
- dwTargetBuildVersion == dwKillBitBuildVersion &&
- dwTargetRevisionVersion == dwKillBitRevisionVersion;
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Determine if a specific assembly is on the killbit list
- //
-
- bool AptcaKillBitList::IsAssemblyKillBitted(PEAssembly *pAssembly)
- {
- STANDARD_VM_CONTRACT;
-
- IAssemblyName *pTargetAssemblyName = pAssembly->GetFusionAssemblyName();
-
- // For compat with v3.5, we use hte Win32 file version here rather than the Fusion version
- LPCWSTR pwszPath = pAssembly->GetPath().GetUnicode();
- if (pwszPath != NULL)
- {
- ULARGE_INTEGER fileVersion = { 0, 0 };
- HRESULT hr = GetFileVersion(pwszPath, &fileVersion);
- if (SUCCEEDED(hr))
- {
- return IsAssemblyKillBitted(pTargetAssemblyName, fileVersion);
- }
- }
-
- return false;
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Determine if a specific assembly is on the killbit list
- //
-
- bool AptcaKillBitList::IsAssemblyKillBitted(IAssemblyName *pTargetAssemblyName, ULARGE_INTEGER fileVersion)
- {
- STANDARD_VM_CONTRACT;
-
- // If nothing is killbitted, then this assembly cannot be killbitted
- if (!AreAnyAssembliesKillBitted())
- {
- return false;
- }
-
- for (DWORD i = 0; i < m_killBitList.GetCount(); ++i)
- {
- IAssemblyName *pKillBitAssemblyName = reinterpret_cast<IAssemblyName *>(m_killBitList.Get(i));
-
- // By default, we compare all fields of the assembly's name, however if the culture was neutral,
- // we strip that out.
- DWORD dwCmpFlags = ASM_CMPF_IL_ALL;
-
- DWORD cbCultureSize = 0;
- SString strCulture;
- HRESULT hrCulture = pKillBitAssemblyName->GetProperty(ASM_NAME_CULTURE, NULL, &cbCultureSize);
- if (hrCulture == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- DWORD cchCulture = (cbCultureSize / sizeof(WCHAR)) - 1;
- WCHAR *wszCultureBuffer = strCulture.OpenUnicodeBuffer(cchCulture);
- hrCulture = pKillBitAssemblyName->GetProperty(ASM_NAME_CULTURE, wszCultureBuffer, &cbCultureSize);
- strCulture.CloseBuffer();
- }
-
- if (SUCCEEDED(hrCulture))
- {
- if (cbCultureSize == 0 || strCulture.EqualsCaseInsensitive(W("")) || strCulture.EqualsCaseInsensitive(W("neutral")))
- {
- dwCmpFlags &= ~ASM_CMPF_CULTURE;
- }
- }
-
- // If the input assembly matches the kill bit assembly's name and file version, then we need to
- // kill it.
- if (pTargetAssemblyName->IsEqual(pKillBitAssemblyName, dwCmpFlags) == S_OK &&
- FileVersionsAreEqual(fileVersion, pKillBitAssemblyName))
- {
- return true;
- }
- }
-
- return false;
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Read the machine-wide APTCA kill bit list into a kill bit list object. For compatibility with v3.5,
- // errors during this initialization are ignored - leading to APTCA entries that may not be considered
- // for kill bitting.
- //
-
- // static
- AptcaKillBitList *AptcaKillBitList::ReadMachineKillBitList()
- {
- CONTRACT(AptcaKillBitList *)
- {
- STANDARD_VM_CHECK;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- NewHolder<AptcaKillBitList> pKillBitList(new AptcaKillBitList);
-
- HKEYHolder hKeyAptca;
-
- // Open the APTCA subkey in the registry.
- if (WszRegOpenKeyEx(HKEY_LOCAL_MACHINE, wszAptcaRootKey, 0, KEY_READ, &hKeyAptca) == ERROR_SUCCESS)
- {
-
- DWORD cchSubKeySize = 0;
- if (WszRegQueryInfoKey(hKeyAptca, NULL, NULL, NULL, NULL, &cchSubKeySize, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
- {
- cchSubKeySize = MAX_PATH_FNAME;
- }
- ++cchSubKeySize;
-
- NewArrayHolder<WCHAR> wszSubKey(new WCHAR[cchSubKeySize]);
-
- DWORD dwKey = 0;
- DWORD cchWszSubKey = cchSubKeySize;
- // Assembly specific records are represented as subkeys of the key we've just opened with names
- // equal to the strong name of the assembly being kill bitted, and a value of APTCA_FLAG = 1.
- while (WszRegEnumKeyEx(hKeyAptca, dwKey, wszSubKey, &cchWszSubKey, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
- {
- ++dwKey;
- cchWszSubKey = cchSubKeySize;
-
- // Open the subkey: the key name is the full name of the assembly to potentially kill-bit
- HKEYHolder hSubKey;
- if (WszRegOpenKeyEx(hKeyAptca, wszSubKey, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS)
- {
- continue;
- }
-
- DWORD dwKillbit = 0;
- DWORD dwType = REG_DWORD;
- DWORD dwSize = sizeof(dwKillbit);
-
- // look for the APTCA flag
- LONG queryValue = WszRegQueryValueEx(hSubKey,
- wszKillBitValue,
- NULL,
- &dwType,
- reinterpret_cast<LPBYTE>(&dwKillbit),
- &dwSize);
- if (queryValue == ERROR_SUCCESS && dwKillbit == 1)
- {
- // We have a strong named assembly with an APTCA killbit value set - parse the key into
- // an assembly name, and add it to our list
- ReleaseHolder<IAssemblyName> pKillBitAssemblyName;
- HRESULT hrAssemblyName = CreateAssemblyNameObject(&pKillBitAssemblyName, wszSubKey, CANOF_PARSE_DISPLAY_NAME, NULL);
- if (FAILED(hrAssemblyName))
- {
- continue;
- }
-
- //
- // For compatibility with v3.5, we only accept kill bit entries which have four part
- // assembly versions, names, and public key tokens.
- //
-
- // Verify the version first
- bool validVersion = true;
- for (DWORD dwVersionPartId = ASM_NAME_MAJOR_VERSION; dwVersionPartId <= ASM_NAME_REVISION_NUMBER; ++dwVersionPartId)
- {
- DWORD dwVersionPart;
- DWORD cbVersionPart = sizeof(dwVersionPart);
- HRESULT hrVersion = pKillBitAssemblyName->GetProperty(dwVersionPartId, &dwVersionPart, &cbVersionPart);
- if (FAILED(hrVersion) || cbVersionPart == 0)
- {
- validVersion = false;
- }
- }
- if (!validVersion)
- {
- continue;
- }
-
- // Make sure there is a simple name
- DWORD cbNameSize = 0;
- HRESULT hrName = pKillBitAssemblyName->GetProperty(ASM_NAME_NAME, NULL, &cbNameSize);
- if (hrName != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- continue;
- }
-
- // Verify the killbit assembly has a public key token
- DWORD cbPublicKeyTokenSize = 0;
- HRESULT hrPublicKey = pKillBitAssemblyName->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, NULL, &cbPublicKeyTokenSize);
- if (hrPublicKey != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- continue;
- }
-
- // Verify the killbit assembly has either no culture or a valid culture token
- DWORD cbCultureSize = 0;
- HRESULT hrCulture = pKillBitAssemblyName->GetProperty(ASM_NAME_CULTURE, NULL, &cbCultureSize);
- if (FAILED(hrCulture) && hrCulture != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- continue;
- }
-
- // The name checks out, so add the kill bit entry
- LOG((LF_SECURITY,
- LL_INFO10,
- "APTCA killbit added for assembly '%S'.\n",
- wszSubKey));
- pKillBitList->m_killBitList.Append(pKillBitAssemblyName.Extract());
- }
- }
- }
-
- RETURN(pKillBitList.Extract());
- }
-
- VolatilePtr<AptcaKillBitList> g_pAptcaKillBitList(NULL);
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Get the APTCA killbit list
- //
-
- AptcaKillBitList *GetKillBitList()
- {
- STANDARD_VM_CONTRACT;
-
- if (g_pAptcaKillBitList.Load() == NULL)
- {
- NewHolder<AptcaKillBitList> pAptcaKillBitList(AptcaKillBitList::ReadMachineKillBitList());
-
- LPVOID pvOldValue = InterlockedCompareExchangeT(g_pAptcaKillBitList.GetPointer(),
- pAptcaKillBitList.GetValue(),
- NULL);
- if (pvOldValue == NULL)
- {
- pAptcaKillBitList.SuppressRelease();
- }
- }
-
- _ASSERTE(g_pAptcaKillBitList.Load() != NULL);
- return g_pAptcaKillBitList.Load();
- }
-}
-
-// APTCA helper functions
-namespace
-{
- enum ConditionalAptcaSharingMode
- {
- kShareUnknown,
- kShareIfEnabled, // Share an assembly only if all conditional APTCA assemblies in its closure are enabled
- kShareIfDisabled, // Share an assembly only if all conditional APTCA assemblies in its closure are disabled
- };
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Get the name of an assembly as it would appear in the APTCA enabled list of an AppDomain
- //
-
- void GetAssemblyNameForConditionalAptca(Assembly *pAssembly, SString *pAssemblyName)
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pAssembly));
- PRECONDITION(CheckPointer(pAssemblyName));
- }
- CONTRACTL_END;
-
- GCX_COOP();
-
- // Call assembly.GetName().GetNameWithPublicKey() to get the name the user would have to add to the
- // whitelist to enable this assembly
- struct
- {
- OBJECTREF orAssembly;
- STRINGREF orAssemblyName;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.orAssembly = pAssembly->GetExposedObject();
- MethodDescCallSite getAssemblyName(METHOD__ASSEMBLY__GET_NAME_FOR_CONDITIONAL_APTCA, &gc.orAssembly);
- ARG_SLOT args[1] =
- {
- ObjToArgSlot(gc.orAssembly)
- };
- gc.orAssemblyName = getAssemblyName.Call_RetSTRINGREF(args);
-
- // Copy to assemblyName
- pAssemblyName->Set(gc.orAssemblyName->GetBuffer());
-
- GCPROTECT_END();
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Determine which types of conditional APTCA assemblies may be shared
- //
-
- ConditionalAptcaSharingMode GetConditionalAptcaSharingMode()
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- static ConditionalAptcaSharingMode sharingMode = kShareUnknown;
-
- if (sharingMode == kShareUnknown)
- {
- // If the default domain has any conditional APTCA assemblies enabled in it, then we share in the
- // enabled direction. Otherwise, the default domain has all conditional APTCA assemblies disabled
- // so we need to share in the disabled direction
- ConditionalAptcaCache *pDefaultDomainCache = SystemDomain::System()->DefaultDomain()->GetSecurityDescriptor()->GetConditionalAptcaCache();
- ConditionalAptcaCache::DomainState domainState = pDefaultDomainCache->GetConditionalAptcaDomainState();
-
- if (domainState == ConditionalAptcaCache::kAllDisabled)
- {
- sharingMode = kShareIfDisabled;
- }
- else
- {
- sharingMode = kShareIfEnabled;
- }
- }
-
- return sharingMode;
- }
-
- /* XXX Fri 7/17/2009
- * I can't call DomainAssembly::IsConditionalAPTCAVisible() here. That requires an Assembly which means
- * we have to be at FILE_LOAD_ALLOCATE. There are two problems:
- * 1) We don't want to load dependencies here if we can avoid it
- * 2) We can't load them anyway (hard bound dependencies can't get past
- * FILE_LOAD_VERIFY_NATIVE_IMAGE_DEPENDENCIES.
- *
- * We're going to do a relaxed check here. Instead of checking the public key, we're
- * only going to check the public key token. See
- * code:AppDomain::IsAssemblyOnAptcaVisibleListRaw for more information.
- *
- * pAsmName - The name of the assembly to check.
- * pDomainAssembly - The Domain Assembly used for logging.
- */
- bool IsAssemblyOnAptcaVisibleList(IAssemblyName * pAsmName, DomainAssembly *pDomainAssembly)
- {
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pAsmName));
- }
- CONTRACTL_END;
-
- ConditionalAptcaCache *pDomainCache = pDomainAssembly->GetAppDomain()->GetSecurityDescriptor()->GetConditionalAptcaCache();
- if (pDomainCache->GetConditionalAptcaDomainState() == ConditionalAptcaCache::kAllEnabled)
- {
- return true;
- }
-
- CQuickBytes qbName;
- LPWSTR pszName;
- DWORD cbName = 0;
- HRESULT hr = pAsmName->GetProperty(ASM_NAME_NAME, NULL, &cbName);
- if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- pszName = (LPWSTR)qbName.AllocThrows(cbName);
- }
- else
- {
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting native image / code sharing because there was an ")
- W("error checking for conditional APTCA: 0x%x"), hr);
- return false;
- }
- hr = pAsmName->GetProperty(ASM_NAME_NAME, (void *)pszName, &cbName);
- if (FAILED(hr))
- {
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting native image / code sharing because there was an ")
- W("error checking for conditional APTCA: 0x%x"), hr);
- return false;
- }
- BYTE rgPublicKeyToken[8];
- DWORD cbPkt = _countof(rgPublicKeyToken);
- hr = pAsmName->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN,
- (void*)rgPublicKeyToken, &cbPkt);
- if (FAILED(hr))
- {
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting native image / code sharing because there was an ")
- W("error obtaining the public key token for %s: 0x%x"),
- pszName, hr);
- return false;
- }
-
- GCX_COOP();
-
- CLR_BOOL isVisible = FALSE;
-
- struct
- {
- OBJECTREF orThis;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
- GCPROTECT_BEGIN(gc);
- gc.orThis = pDomainAssembly->GetAppDomain()->GetExposedObject();
-
- MethodDescCallSite assemblyVisible(METHOD__APP_DOMAIN__IS_ASSEMBLY_ON_APTCA_VISIBLE_LIST_RAW,
- &gc.orThis);
- ARG_SLOT args[] = {
- ObjToArgSlot(gc.orThis),
- (ARG_SLOT)pszName,
- (ARG_SLOT)wcslen(pszName),
- (ARG_SLOT)rgPublicKeyToken,
- (ARG_SLOT)cbPkt
- };
- isVisible = assemblyVisible.Call_RetBool(args);
- GCPROTECT_END();
-
- return isVisible;
- }
-
- bool IsAssemblyOnAptcaVisibleList(DomainAssembly *pAssembly)
- {
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pAssembly));
- PRECONDITION(GetAppDomain() == pAssembly->GetAppDomain());
- }
- CONTRACTL_END;
-
- ConditionalAptcaCache *pDomainCache = pAssembly->GetAppDomain()->GetSecurityDescriptor()->GetConditionalAptcaCache();
- if (pDomainCache->GetConditionalAptcaDomainState() == ConditionalAptcaCache::kAllEnabled)
- {
- return true;
- }
-
- GCX_COOP();
-
- bool foundInList = false;
-
- // Otherwise, we need to transition into the BCL code to find out if the assembly is on the list
- struct
- {
- OBJECTREF orAppDomain;
- OBJECTREF orAssembly;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- MethodDescCallSite isAssemblyOnAptcaVisibleList(METHOD__APP_DOMAIN__IS_ASSEMBLY_ON_APTCA_VISIBLE_LIST);
- gc.orAppDomain = GetAppDomain()->GetExposedObject();
- gc.orAssembly = pAssembly->GetAssembly()->GetExposedObject();
-
- ARG_SLOT args[] =
- {
- ObjToArgSlot(gc.orAppDomain),
- ObjToArgSlot(gc.orAssembly)
- };
-
- foundInList = isAssemblyOnAptcaVisibleList.Call_RetBool(args);
-
- GCPROTECT_END();
-
- return foundInList;
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Determine if an assembly is APTCA in the current domain or not
- //
- // Arguments:
- // pDomainAssembly - Assembly to check for APTCA-ness
- // tokenFlags - raw metadata security bits from the assembly
- //
- // Return Value:
- // true if the assembly is APTCA, false if it is not
- //
-
- bool IsAssemblyAptcaEnabled(DomainAssembly *pDomainAssembly, TokenSecurityDescriptorFlags tokenFlags)
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pDomainAssembly));
- }
- CONTRACTL_END;
-
-#ifdef _DEBUG
- SString strAptcaAssemblyBreak(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_Security_AptcaAssemblyBreak));
- SString strAssemblySimpleName(SString::Utf8, pDomainAssembly->GetSimpleName());
- if (strAptcaAssemblyBreak.EqualsCaseInsensitive(strAssemblySimpleName))
- {
- _ASSERTE(!"Checking APTCA-ness of an APTCA break assembly");
- }
-#endif // _DEBUG
-
- // If the assembly is not marked APTCA, then it cannot possibly be APTCA enabled
- if ((tokenFlags & TokenSecurityDescriptorFlags_APTCA) == TokenSecurityDescriptorFlags_None)
- {
- return false;
- }
-
- GCX_PREEMP();
-
- // Additionally, if the assembly is on the APTCA kill list, then no matter what it says in its metadata,
- // it should not be considered APTCA
- if (GetKillBitList()->IsAssemblyKillBitted(pDomainAssembly->GetFile()))
- {
- return false;
- }
-
- // If the assembly is conditionally APTCA, then we need to check the current AppDomain's APTCA enabled
- // list to figure out if it is APTCA in this domain.
- if (tokenFlags & TokenSecurityDescriptorFlags_ConditionalAPTCA)
- {
- return IsAssemblyOnAptcaVisibleList(pDomainAssembly);
- }
-
- // Otherwise, the assembly is APTCA
- return true;
- }
-
- //--------------------------------------------------------------------------------------------------------
- //
- // Determine if the assembly matches the conditional APTCA sharing mode. That is, if we are sharing
- // enabled conditional APTCA assemblies check that this assembly is enabled. Similarly, if we are
- // sharing disabled conditional APTCA assemblies check that this assembly is disabled.
- //
- // This method assumes that the assembly is conditionally APTCA
- //
-
- bool AssemblyMatchesShareMode(IAssemblyName *pAsmName, DomainAssembly *pDomainAssembly)
- {
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pAsmName));
- PRECONDITION(GetConditionalAptcaSharingMode() != kShareUnknown);
- }
- CONTRACTL_END;
-
- if (IsAssemblyOnAptcaVisibleList(pAsmName, pDomainAssembly))
- {
- return GetConditionalAptcaSharingMode() == kShareIfEnabled;
- }
- else
- {
- return GetConditionalAptcaSharingMode() == kShareIfDisabled;
- }
- }
-
- bool AssemblyMatchesShareMode(ConditionalAptcaCache::State state)
- {
- STANDARD_VM_CONTRACT;
-
- _ASSERTE(state == ConditionalAptcaCache::kEnabled || state == ConditionalAptcaCache::kDisabled);
-
- if (state == ConditionalAptcaCache::kEnabled)
- {
- return GetConditionalAptcaSharingMode() == kShareIfEnabled;
- }
- else
- {
- return GetConditionalAptcaSharingMode() == kShareIfDisabled;
- }
- }
-}
-
-//------------------------------------------------------------------------------------------------------------
-//
-// Determine if the AppDomain can share an assembly or if APTCA restrictions prevent sharing
-//
-
-bool DomainCanShareAptcaAssembly(DomainAssembly *pDomainAssembly)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pDomainAssembly));
- }
- CONTRACTL_END;
-
-#ifdef _DEBUG
- DWORD dwAptcaAssemblyDomainBreak = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_Security_AptcaAssemblySharingDomainBreak);
- if (dwAptcaAssemblyDomainBreak == 0 || ADID(dwAptcaAssemblyDomainBreak) == pDomainAssembly->GetAppDomain()->GetId())
- {
- SString strAptcaAssemblySharingBreak(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_Security_AptcaAssemblySharingBreak));
- SString strAssemblySimpleName(SString::Utf8, pDomainAssembly->GetSimpleName());
-
- if (strAptcaAssemblySharingBreak.EqualsCaseInsensitive(strAssemblySimpleName))
- {
- _ASSERTE(!"Checking code sharing for APTCA break assembly");
- }
- }
-#endif // _DEBUG
-
- //
- // We can only share an assembly if all conditional APTCA assemblies in its full closure of dependencies
- // are enabled.
- //
-
- // We always allow sharing of mscorlib
- if (pDomainAssembly->IsSystem())
- {
- return true;
- }
-
- IApplicationSecurityDescriptor *pDomainSecDesc = pDomainAssembly->GetAppDomain()->GetSecurityDescriptor();
- ConditionalAptcaCache *pConditionalAptcaCache = pDomainSecDesc->GetConditionalAptcaCache();
-
- // If all assemblies in the domain match the sharing mode, then we can share the assembly
- ConditionalAptcaCache::DomainState domainState = pConditionalAptcaCache->GetConditionalAptcaDomainState();
- if (GetConditionalAptcaSharingMode() == kShareIfEnabled)
- {
- if (domainState == ConditionalAptcaCache::kAllEnabled)
- {
- return true;
- }
- }
- else
- {
- if (domainState == ConditionalAptcaCache::kAllDisabled)
- {
- return true;
- }
- }
-
- // If the root assembly is conditionally APTCA, then it needs to be enabled
- ReleaseHolder<IMDInternalImport> pRootImport(pDomainAssembly->GetFile()->GetMDImportWithRef());
- TokenSecurityDescriptorFlags rootSecurityAttributes =
- TokenSecurityDescriptor::ReadSecurityAttributes(pRootImport, TokenFromRid(1, mdtAssembly));
- if (rootSecurityAttributes & TokenSecurityDescriptorFlags_ConditionalAPTCA)
- {
- if (!AssemblyMatchesShareMode(pDomainAssembly->GetFile()->GetFusionAssemblyName(), pDomainAssembly))
- {
- return false;
- }
- }
-
- // Now we need to get the full closure of assemblies that this assembly depends upon and ensure that each
- // one of those is either not conditional APTCA or is enabled in the domain. We get a new assembly
- // closure object here rather than using DomainAssembly::GetAssemblyBindingClosure because we don't want
- // to force that closure to walk the full dependency graph (and therefore not be considered equal to
- // closures which weren't fully walked).
- IUnknown *pFusionAssembly;
- if (pDomainAssembly->GetFile()->IsIStream())
- {
- pFusionAssembly = pDomainAssembly->GetFile()->GetIHostAssembly();
- }
- else
- {
- pFusionAssembly = pDomainAssembly->GetFile()->GetFusionAssembly();
- }
-
- // Get the closure and force it to do a full dependency walk, not stopping at framework assemblies
- SafeComHolder<IAssemblyBindingClosure> pClosure;
-
-
- LPCWSTR pNIPath = NULL;
- PEAssembly *pPEAsm = pDomainAssembly->GetFile();
- if (pPEAsm->HasNativeImage())
- {
- ReleaseHolder<PEImage> pNIImage = pPEAsm->GetNativeImageWithRef();
- pNIPath = pNIImage->GetPath().GetUnicode();
- }
-
- IfFailThrow(pDomainAssembly->GetAppDomain()->GetFusionContext()->GetAssemblyBindingClosure(pFusionAssembly, pNIPath, &pClosure));
- IfFailThrow(pClosure->EnsureWalked(pFusionAssembly, pDomainAssembly->GetAppDomain()->GetFusionContext(), LEVEL_FXPROBED));
-
- // Now iterate the closure looking for conditional APTCA assemblies
- SafeComHolder<IAssemblyBindingClosureEnumerator> pClosureEnumerator;
- IfFailThrow(pClosure->EnumerateAssemblies(&pClosureEnumerator));
- LPCOLESTR szDependentAssemblyPath = NULL;
- LPCOLESTR szDependentNIAssemblyPath = NULL;
-
- for (HRESULT hr = pClosureEnumerator->GetNextAssemblyPath(&szDependentAssemblyPath, &szDependentNIAssemblyPath);
- SUCCEEDED(hr);
- hr = pClosureEnumerator->GetNextAssemblyPath(&szDependentAssemblyPath, &szDependentNIAssemblyPath))
- {
- // Make sure we've succesfully enumerated an item
- if (hr != S_OK && hr != HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
- {
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting code sharing because of an error enumerating dependent assemblies: 0x%x"), hr);
- return false;
- }
- else if (szDependentAssemblyPath == NULL)
- {
- // This means we have an assembly but no way to verify the image at this point -- should we get
- // into this state, we'll be conservative and fail the share
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting code sharing because an assembly in the closure does not have a path"));
- return false;
- }
- else
- {
- // We have succesfully found a new item in the closure of assemblies - now check to ensure that
- // it is either not conditionally APTCA or is enabled in tihs domain.
- PEImageHolder pDependentImage;
-
- // Use the native image if it is loaded.
- if (szDependentNIAssemblyPath != NULL)
- {
- SString strNIAssemblyPath(szDependentNIAssemblyPath);
- pDependentImage = PEImage::OpenImage(strNIAssemblyPath, MDInternalImport_OnlyLookInCache);
- if (pDependentImage != NULL && !pDependentImage->HasLoadedLayout())
- {
- pDependentImage = NULL;
- }
- else
- {
-#if FEATURE_CORECLR
-#error Coreclr needs to check native image version here.
-#endif
- }
- }
-
- if (pDependentImage == NULL)
- {
- SString strAssemblyPath(szDependentAssemblyPath);
- pDependentImage = PEImage::OpenImage(strAssemblyPath);
- }
-
- // See if we already know if this image is enabled in the current domain or not
- ConditionalAptcaCache::State dependentState = pConditionalAptcaCache->GetCachedState(pDependentImage);
-
- // We don't know this assembly's conditional APTCA state in this domain, so we need to figure it
- // out now.
- if (dependentState == ConditionalAptcaCache::kUnknown)
- {
- // First figure out if the assembly is even conditionally APTCA to begin with
- IMDInternalImport *pDependentImport = pDependentImage->GetMDImport();
- TokenSecurityDescriptorFlags dependentSecurityAttributes =
- TokenSecurityDescriptor::ReadSecurityAttributes(pDependentImport, TokenFromRid(1, mdtAssembly));
-
- if (dependentSecurityAttributes & TokenSecurityDescriptorFlags_ConditionalAPTCA)
- {
- // The the assembly name of the dependent assembly so we can check it to the domain
- // enabled list
- ReleaseHolder<IAssemblyName> pDependentAssemblyName;
- AssemblySpec dependentAssemblySpec(pDomainAssembly->GetAppDomain());
- dependentAssemblySpec.InitializeSpec(TokenFromRid(1, mdtAssembly), pDependentImport);
- IfFailThrow(dependentAssemblySpec.CreateFusionName(&pDependentAssemblyName, FALSE));
-
- // Check the domain list to see if the assembly is on it
- if (IsAssemblyOnAptcaVisibleList(pDependentAssemblyName, pDomainAssembly))
- {
- dependentState = ConditionalAptcaCache::kEnabled;
- }
- else
- {
- dependentState = ConditionalAptcaCache::kDisabled;
- }
- }
- else
- {
- // The dependent assembly doesn't have the conditional APTCA bit set on it, so we don't
- // need to do any checking to see if it's enabled
- dependentState = ConditionalAptcaCache::kNotCAptca;
- }
-
- // Cache the result of evaluating conditional APTCA on this assembly in the domain
- pConditionalAptcaCache->SetCachedState(pDependentImage, dependentState);
- }
-
- // If the dependent assembly does not match the sharing mode, then we cannot share the
- // dependency. We can always share dependencies which are not conditionally APTCA, so don't
- // bother checking the share mode for them.
- if (dependentState != ConditionalAptcaCache::kNotCAptca)
- {
- if (!AssemblyMatchesShareMode(dependentState))
- {
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting code sharing because a dependent assembly did not match the conditional APTCA share mode"));
- return false;
- }
- }
- }
- }
-
- // The root assembly and all of its dependents were either on the conditional APTCA list or are not
- // conditional APTCA, so we can share this assembly
- return true;
-}
-
-//------------------------------------------------------------------------------------------------------------
-//
-// Get an exception string indicating how to enable a conditional APTCA assembly if it was disabled and
-// caused an exception
-//
-
-SString GetConditionalAptcaAccessExceptionContext(Assembly *pTargetAssembly)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pTargetAssembly));
- }
- CONTRACTL_END;
-
- SString exceptionContext;
-
- ModuleSecurityDescriptor *pMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pTargetAssembly);
-
- if (pMSD->GetTokenFlags() & TokenSecurityDescriptorFlags_ConditionalAPTCA)
- {
- GCX_PREEMP();
-
- if (!IsAssemblyOnAptcaVisibleList(pTargetAssembly->GetDomainAssembly()))
- {
- // We have a conditional APTCA assembly which is not on the visible list for the current
- // AppDomain, provide information on how to enable it.
- SString assemblyDisplayName;
- pTargetAssembly->GetDisplayName(assemblyDisplayName);
-
- SString assemblyConditionalAptcaName;
- GetAssemblyNameForConditionalAptca(pTargetAssembly, &assemblyConditionalAptcaName);
-
- EEException::GetResourceMessage(IDS_ACCESS_EXCEPTION_CONTEXT_CONDITIONAL_APTCA,
- exceptionContext,
- assemblyDisplayName,
- assemblyConditionalAptcaName);
- }
- }
-
- return exceptionContext;
-}
-
-//------------------------------------------------------------------------------------------------------------
-//
-// Get an exception string indicating that an assembly was on the kill bit list if it caused an exception
-//
-
-SString GetAptcaKillBitAccessExceptionContext(Assembly *pTargetAssembly)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pTargetAssembly));
- }
- CONTRACTL_END;
-
- GCX_PREEMP();
-
- SString exceptionContext;
-
- if (GetKillBitList()->IsAssemblyKillBitted(pTargetAssembly->GetDomainAssembly()->GetFile()))
- {
- SString assemblyDisplayName;
- pTargetAssembly->GetDisplayName(assemblyDisplayName);
-
- EEException::GetResourceMessage(IDS_ACCESS_EXCEPTION_CONTEXT_APTCA_KILLBIT,
- exceptionContext,
- assemblyDisplayName);
- }
-
- return exceptionContext;
-}
-
-//------------------------------------------------------------------------------------------------------------
-//
-// Determine if a native image is valid to use from the perspective of APTCA. This means that the image
-// itself and all of its dependencies must:
-// 1. Not be killbitted
-// 2. Be enabled if they are conditionally APTCA
-//
-// Arguments:
-// pNativeImage - native image to accept or reject
-// pDomainAssembly - assembly that is being loaded
-//
-// Return Value:
-// true if the native image can be accepted due to APTCA-ness, false if we need to reject it
-//
-
-bool NativeImageHasValidAptcaDependencies(PEImage *pNativeImage, DomainAssembly *pDomainAssembly)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pNativeImage));
- PRECONDITION(CheckPointer(pDomainAssembly));
- }
- CONTRACTL_END;
-
- AptcaKillBitList *pKillBitList = GetKillBitList();
-
- ConditionalAptcaCache *pDomainCache = pDomainAssembly->GetAppDomain()->GetSecurityDescriptor()->GetConditionalAptcaCache();
- // If we have any killbitted assemblies, then we need to make sure that the current assembly and its dependencies
- BOOL aptcaChecks = pKillBitList->AreAnyAssembliesKillBitted();
- BOOL conditionalAptcaChecks = pDomainCache->GetConditionalAptcaDomainState() != ConditionalAptcaCache::kAllEnabled;
- if (!aptcaChecks && !conditionalAptcaChecks)
- return true;
-
- //
- // Check to see if the NGEN image itself is APTCA and killbitted
- //
-
- ReleaseHolder<IMDInternalImport> pAssemblyMD(pDomainAssembly->GetFile()->GetMDImportWithRef());
- TokenSecurityDescriptorFlags assemblySecurityAttributes =
- TokenSecurityDescriptor::ReadSecurityAttributes(pAssemblyMD, TokenFromRid(1, mdtAssembly));
-
- if (aptcaChecks)
- {
- if ((assemblySecurityAttributes & TokenSecurityDescriptorFlags_APTCA) &&
- pKillBitList->IsAssemblyKillBitted(pDomainAssembly->GetFile()))
- {
- return false;
- }
- }
- if (conditionalAptcaChecks
- && (assemblySecurityAttributes & TokenSecurityDescriptorFlags_ConditionalAPTCA))
- {
- //
- // First check to see if we're disabled.
- //
-
- AssemblySpec spec;
- spec.InitializeSpec(pDomainAssembly->GetFile());
- ReleaseHolder<IAssemblyName> pAsmName;
- IfFailThrow(spec.CreateFusionName(&pAsmName, FALSE));
-
- if (!IsAssemblyOnAptcaVisibleList(pAsmName, pDomainAssembly))
- {
- //IsAssemblyOnAptcaVisibleList has already logged an error.
- return false;
- }
- }
-
- if (aptcaChecks || conditionalAptcaChecks)
- {
- //
- // Also check its dependencies
- //
-
- COUNT_T dependencyCount;
- PEImageLayout *pNativeLayout = pNativeImage->GetLoadedLayout();
- CORCOMPILE_DEPENDENCY *pDependencies = pNativeLayout->GetNativeDependencies(&dependencyCount);
-
- for (COUNT_T i = 0; i < dependencyCount; ++i)
- {
- CORCOMPILE_DEPENDENCY* pDependency = &(pDependencies[i]);
- // Look for any dependency which is APTCA
- if (pDependencies[i].dwAssemblyDef != mdAssemblyRefNil)
- {
- AssemblySpec name;
- name.InitializeSpec(pDependency->dwAssemblyRef,
- pNativeImage->GetNativeMDImport(),
- NULL,
- pDomainAssembly->GetFile()->IsIntrospectionOnly());
-
- ReleaseHolder<IAssemblyName> pDependencyAssemblyName;
- HRESULT hr = name.CreateFusionName(&pDependencyAssemblyName, FALSE);
-
- // If we couldn't build the assemlby name up conservatively discard the image
- if (FAILED(hr))
- {
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting native image because could not get ")
- W("name for assemblyref 0x%x for native image dependency: ")
- W("hr=0x%x"), pDependency->dwAssemblyRef, hr);
- return false;
- }
-
- if (pDependencies[i].dependencyInfo & (CORCOMPILE_DEPENDENCY_IS_APTCA))
- {
- ULARGE_INTEGER fileVersion;
-
- //This is a workaround for Dev10# 743602
- fileVersion.QuadPart = GET_UNALIGNED_VAL64(&(pDependencies[i].uliFileVersion));
- // If the dependency really is killbitted, then discard the image
- if (pKillBitList->IsAssemblyKillBitted(pDependencyAssemblyName, fileVersion))
- {
- pDomainAssembly->ExternalLog(LL_ERROR, W("Rejecting native image because dependency ")
- W("assemblyref 0x%x is killbitted."),
- pDependency->dwAssemblyRef);
- return false;
- }
- }
- if (pDependencies[i].dependencyInfo & (CORCOMPILE_DEPENDENCY_IS_CAPTCA))
- {
- if (!IsAssemblyOnAptcaVisibleList(pDependencyAssemblyName, pDomainAssembly))
- {
- //IsAssemblyOnAptcaVisibleList has already logged an error.
- return false;
- }
- }
- }
- }
- }
- return true;
-}
-#else // CROSSGEN_COMPILE
-namespace
-{
- bool IsAssemblyAptcaEnabled(DomainAssembly *pDomainAssembly, TokenSecurityDescriptorFlags tokenFlags)
- {
- // No killbits or conditional APTCA for crossgen. Just check whether the assembly is marked APTCA.
- return ((tokenFlags & TokenSecurityDescriptorFlags_APTCA) != TokenSecurityDescriptorFlags_None);
- }
-}
-#endif // CROSSGEN_COMPILE
-
-//------------------------------------------------------------------------------------------------------------
-//
-// Process an assembly's real APTCA flags to determine if the assembly should be considered
-// APTCA or not
-//
-// Arguments:
-// pDomainAssembly - Assembly to check for APTCA-ness
-// tokenFlags - raw metadata security bits from the assembly
-//
-// Return Value:
-// updated token security descriptor flags which indicate the assembly's true APTCA state
-//
-
-TokenSecurityDescriptorFlags ProcessAssemblyAptcaFlags(DomainAssembly *pDomainAssembly,
- TokenSecurityDescriptorFlags tokenFlags)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pDomainAssembly));
- }
- CONTRACTL_END;
-
- const TokenSecurityDescriptorFlags aptcaFlags = TokenSecurityDescriptorFlags_APTCA |
- TokenSecurityDescriptorFlags_ConditionalAPTCA;
-
- if (IsAssemblyAptcaEnabled(pDomainAssembly, tokenFlags))
- {
- // The assembly is APTCA - temporarially remove all of its APTCA bits, and then add back the
- // unconditionally APTCA bit
- tokenFlags = tokenFlags & ~aptcaFlags;
- return tokenFlags | TokenSecurityDescriptorFlags_APTCA;
- }
- else
- {
- // The assembly is not APTCA, so remove all of its APTCA bits from the token security descriptor
- return tokenFlags & ~aptcaFlags;
- }
-}
diff --git a/src/vm/aptca.h b/src/vm/aptca.h
deleted file mode 100644
index 3d590a093a..0000000000
--- a/src/vm/aptca.h
+++ /dev/null
@@ -1,110 +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.
-//--------------------------------------------------------------------------
-// aptca.h
-//
-// Functions for handling allow partially trusted callers assemblies
-//
-// This should be the only interface for talking about the APTCA-ness of an assembly, and even then should
-// be used only from very select areas of the CLR that absolutely need to know the information. For
-// instance:
-//
-// * the class loader (for code sharing and formatting exception messages)
-// * NGEN (for determining if a native image is valid)
-// * security attribute processing code (for obvious reasons)
-//
-// may use this interface. Nearly every other section of the code should simply be relying on the
-// ModuleSecurityDescriptor for the assembly in question. And no other sections of the code should be
-// directly asking questions like "is this assembly conditional APTCA" ... we explicitly want to hide that
-// information away behind the final assembly security attribute computation as much as possible.
-//
-// In particular, no code should be making security enforcement decisions based upon conditional APTCA, and
-// instead should rely on the existing transparency / legacy APTCA enforcement. This means that once the
-// security system, JIT, and class loader have finished setting up an assembly's APTCA attributes, there
-// should be no further questions asked about the particular APTCA attribute applied to the assembly.
-//
-// Put another way, once an assembly is loaded, the APTCA kill bit and conditional APTCA enabled / disabled
-// decision for an assembly should evaporate away, and all assemblies should look as if they either have a
-// full APTCA attribute (in the not-killbitted / conditional APTCA enabled case) or no APTCA attribute at
-// all (killbitted or conditional APTCA disabled).
-//
-
-//
-//--------------------------------------------------------------------------
-
-
-#ifndef __APTCA_H__
-#define __APTCA_H__
-
-#ifndef FEATURE_APTCA
-#error FEATURE_APTCA is required for this file
-#endif // FEATURE_APTCA
-
-#include "securitymeta.h"
-
-class ConditionalAptcaCache
-{
-public:
- typedef enum
- {
- kUnknown, // No cached state
- kEnabled, // The assembly is enabled in this domain
- kDisabled, // The assembly is disabled in this domain
- kNotCAptca, // The assembly is not conditionally APTCA
- }
- State;
-
- typedef enum
- {
- kDomainStateUnknown, // The domain state is not yet initialized
- kAllEnabled, // All assemblies in the domain are enabled
- kSomeEnabled, // Some assemblies in the domain are enabled
- kAllDisabled, // All assemblies in the domain are disabled
- }
- DomainState;
-
- ConditionalAptcaCache(AppDomain *pAppDomain);
- ~ConditionalAptcaCache();
-
- State GetCachedState(PTR_PEImage pImage);
- void SetCachedState(PTR_PEImage pImage, State state);
-
- DomainState GetConditionalAptcaDomainState();
- void SetCanonicalConditionalAptcaList(LPCWSTR wszCanonicalConditionalAptcaList);
-
- static bool ConsiderFullTrustConditionalAptcaLists();
-
-private:
- ConditionalAptcaCache(ConditionalAptcaCache &other); // not implemented - used to prevent compiler generating a copy constructor
- ConditionalAptcaCache& operator=(const ConditionalAptcaCache &other); // not implemented - used to prevent compiler generating an assignment operator
-
-private:
- AppDomain *m_pAppDomain;
-
- bool m_canonicalListIsNull;
- SString m_canonicalList;
- DomainState m_domainState;
-};
-
-// Determine if the AppDomain can share an assembly or if APTCA restrictions prevent sharing
-bool DomainCanShareAptcaAssembly(DomainAssembly *pDomainAssembly);
-
-// Get an exception string indicating how to enable a conditional APTCA assembly if it was disabled and
-// caused an exception
-SString GetConditionalAptcaAccessExceptionContext(Assembly *pTargetAssembly);
-
-// Get an exception string indicating that
-SString GetConditionalAptcaSharingExceptionContext(Assembly *pTargetAssembly);
-
-// Get an exception string indicating that an assembly was on the kill bit list if it caused an exception
-SString GetAptcaKillBitAccessExceptionContext(Assembly *pTargetAssembly);
-
-// Determine if a native image is OK to use from an APTCA perspective (it and its dependencies all have the
-// same APTCA-ness now as at NGEN time)
-bool NativeImageHasValidAptcaDependencies(PEImage *pNativeImage, DomainAssembly *pDomainAssembly);
-
-// Process an assembly's real APTCA flags to determine if the assembly should be considered APTCA or not
-TokenSecurityDescriptorFlags ProcessAssemblyAptcaFlags(DomainAssembly *pDomainAssembly, TokenSecurityDescriptorFlags tokenFlags);
-
-#endif // __APTCA_H__
diff --git a/src/vm/arm/asmconstants.h b/src/vm/arm/asmconstants.h
index 93af04734e..41597b2dbe 100644
--- a/src/vm/arm/asmconstants.h
+++ b/src/vm/arm/asmconstants.h
@@ -176,23 +176,6 @@ ASMCONSTANTS_C_ASSERT(UMThunkMarshInfo__m_pILStub == offsetof(UMThunkMarshInfo,
#define UMThunkMarshInfo__m_cbActualArgSize 0x04
ASMCONSTANTS_C_ASSERT(UMThunkMarshInfo__m_cbActualArgSize == offsetof(UMThunkMarshInfo, m_cbActualArgSize))
-#ifdef FEATURE_REMOTING
-
-#define TransparentProxyObject___stubData 0x8
-ASMCONSTANTS_C_ASSERT(TransparentProxyObject___stubData == offsetof(TransparentProxyObject, _stubData))
-
-#define TransparentProxyObject___stub 0x14
-ASMCONSTANTS_C_ASSERT(TransparentProxyObject___stub == offsetof(TransparentProxyObject, _stub))
-
-#define TransparentProxyObject___pMT 0xc
-ASMCONSTANTS_C_ASSERT(TransparentProxyObject___pMT == offsetof(TransparentProxyObject, _pMT))
-
-#define RemotingPrecode__m_pMethodDesc 0x10
-ASMCONSTANTS_C_ASSERT(RemotingPrecode__m_pMethodDesc == offsetof(RemotingPrecode, m_pMethodDesc))
-
-#define REMOTING_PRECODE_RET_OFFSET 0x06
-
-#endif // FEATURE_REMOTING
#define MethodDesc__m_wFlags DBG_FRE(0x1A, 0x06)
ASMCONSTANTS_C_ASSERT(MethodDesc__m_wFlags == offsetof(MethodDesc, m_wFlags))
diff --git a/src/vm/arm/asmhelpers.asm b/src/vm/arm/asmhelpers.asm
index 796c1d14c5..542bdc65cc 100644
--- a/src/vm/arm/asmhelpers.asm
+++ b/src/vm/arm/asmhelpers.asm
@@ -40,12 +40,6 @@
#endif // WRITE_BARRIER_CHECK
-#ifdef FEATURE_REMOTING
- IMPORT $CTPMethodTable__s_pThunkTable
- IMPORT VSD_GetTargetForTPWorker
- IMPORT VSD_GetTargetForTPWorkerQuick
- IMPORT TransparentProxyStubWorker
-#endif
#ifdef FEATURE_COMINTEROP
IMPORT CLRToCOMWorker
IMPORT ComPreStubWorker
@@ -64,11 +58,6 @@
IMPORT GetCurrentSavedRedirectContext
-#ifdef FEATURE_MIXEDMODE
- SETALIAS IJWNOADThunk__FindThunkTarget, ?FindThunkTarget@IJWNOADThunk@@QAAPBXXZ
- IMPORT $IJWNOADThunk__FindThunkTarget
-#endif
-
;; Imports to support virtual import fixup for ngen images
IMPORT VirtualMethodFixupWorker
;; Import to support cross-moodule external method invocation in ngen images
@@ -562,41 +551,6 @@ UM2MThunk_WrapperHelper_ArgumentsSetup
NESTED_END
-; ------------------------------------------------------------------
-;
-; IJWNOADThunk::MakeCall
-;
-; On entry:
-; r12 : IJWNOADThunk *
-;
-; On exit:
-; Tail calls to real managed target
-;
-
-#ifdef FEATURE_MIXEDMODE
- NESTED_ENTRY IJWNOADThunk__MakeCall
-
- ; Can't pass C++ mangled names to NESTED_ENTRY and my attempts to use EQU to define an alternate name
- ; for a symbol didn't work. Just define a label for the decorated name of the method and export it
- ; manually.
-|?MakeCall@IJWNOADThunk@@KAXXZ|
- EXPORT |?MakeCall@IJWNOADThunk@@KAXXZ|
-
- PROLOG_PUSH {r0-r4,lr}
- PROLOG_VPUSH {d0-d7}
-
- CHECK_STACK_ALIGNMENT
-
- mov r0, r12 ; IJWNOADThunk * is this pointer for IJWNOADThunk::FindThunkTarget
- bl $IJWNOADThunk__FindThunkTarget
- mov r12, r0 ; Returns real jump target in r0, save this in r12
-
- EPILOG_VPOP {d0-d7}
- EPILOG_POP {r0-r4,lr}
- EPILOG_BRANCH_REG r12
-
- NESTED_END
-#endif
; ------------------------------------------------------------------
@@ -704,7 +658,7 @@ ThePreStubPatchLabel
NESTED_END
-#if defined(FEATURE_REMOTING) || defined(FEATURE_COMINTEROP)
+#if defined(FEATURE_COMINTEROP)
; ------------------------------------------------------------------
; setStubReturnValue
@@ -753,372 +707,10 @@ NoFloatingPointRetVal
LEAF_END
-#endif // FEATURE_REMOTING || FEATURE_COMINTEROP
-
-#ifdef FEATURE_REMOTING
-
-; ------------------------------------------------------------------
-; Remoting stub used to dispatch a method invocation. This is the choke point for all remoting calls; all
-; scenarios where we determine we're not a local or a COM call, regardless of whether the dispatch is
-; interface, virtual or direct will wind up here sooner or later.
-;
-; On entry:
-; r0 : transparent proxy
-; r12 : target MethodDesc or slot number
-; plus user arguments in registers and on the stack
-;
- NESTED_ENTRY TransparentProxyStub_CrossContext
-
- PROLOG_WITH_TRANSITION_BLOCK 0x20
-
- add r0, sp, #__PWTB_TransitionBlock ; pTransitionBlock
- mov r1, r12 ; pMethodDesc
-
- bl TransparentProxyStubWorker
-
- ; r0 = fpRetSize
-
- ; return value is stored before float argument registers
- add r1, sp, #(__PWTB_FloatArgumentRegisters - 0x20)
- bl setStubReturnValue
-
- EPILOG_WITH_TRANSITION_BLOCK_RETURN
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; This method does nothing. It's just a fixed function for the debugger to put a breakpoint on.
- LEAF_ENTRY TransparentProxyStubPatch
- add r0, r1, r2
-TransparentProxyStubPatchLabel
- EXPORT TransparentProxyStubPatchLabel
- bx lr
- LEAF_END
-
-; ------------------------------------------------------------------
-; VSD helper for performing an in-context interface dispatch on a TransparentProxy. This only happens for
-; ContextBoundObjects that are invoked in the correct context, never for general remoting.
-;
-; On entry:
-; r0 : transparent proxy
-; r12 : interface MethodDesc
-; plus user arguments in registers and on the stack
-;
-; On exit:
-; Tail calls to actual target which returns as normal to the caller.
-;
- NESTED_ENTRY InContextTPQuickDispatchAsmStub
-
- ; Spill caller's volatile argument registers and some other state we wish to preserve.
- PROLOG_PUSH {r0-r3,r12,lr}
- PROLOG_VPUSH {d0-d7}
-
- CHECK_STACK_ALIGNMENT
-
- ; Set up arguments for VSD_GetTargetForTPWorkerQuick
- ; mov r0, r0 ; this
- mov r1, r12 ; Interface MethodDesc
-
- bl VSD_GetTargetForTPWorkerQuick
-
- ; If we didn't find a target head for the slow path.
- cbz r0, CacheMiss
-
- ; Save target address since we're about to restore the value of r0. Can't place it directly into r12
- ; since that's about to be restored as well. Instead we overwrite the saved version of r12 on the
- ; stack (we don't need it any more since the lookup succeeded).
- str r0, [sp, #((16 * 4) + (4 * 4))]
-
- ; Restore caller's argument registers.
- EPILOG_VPOP {d0-d7}
- EPILOG_POP {r0-r3,r12,lr}
-
- ; Tail call to the real code using the previously computed target address.
- EPILOG_BRANCH_REG r12
-
-CacheMiss
- ; Restore caller's argument registers.
- EPILOG_VPOP {d0-d7}
- EPILOG_POP {r0-r3,r12,lr}
-
- EPILOG_BRANCH InContextTPDispatchAsmStub
-
- NESTED_END
-
-; ------------------------------------------------------------------
-
- NESTED_ENTRY InContextTPDispatchAsmStub
-
- PROLOG_WITH_TRANSITION_BLOCK
-
- add r0, sp, #__PWTB_TransitionBlock ; pTransitionBlock
- mov r1, r12 ; pMethodDesc / token
-
- bl VSD_GetTargetForTPWorker
-
- mov r12, r0
-
- EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
- EPILOG_BRANCH_REG r12
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; Macro used to compare a MethodTable with that of __TransparentProxy. Sets the Z condition flag to indicate
-; the result (Z=1 for a match, Z=0 for a mismatch).
-;
- MACRO
- TP_TYPE_CHECK $methodTableReg, $scratchReg
-
- ldr $scratchReg, =$CTPMethodTable__s_pThunkTable
- ldr $scratchReg, [$scratchReg]
- cmp $scratchReg, $methodTableReg
- MEND
-
-; ------------------------------------------------------------------
-; Macro used to perform a context check.
-;
-; Calls a user customizable routine that determines whether the current execution context warrants a context
-; transition for the call. Regular remoting (as opposed to context transitioning based on ContextBoundObjects)
-; always returns a context-mismatch from this call.
-;
-; On entry:
-; r0 : this (TranparentProxy object)
-;
-; On exit:
-; r0 : check result (0 == contexts match, non-zero == contexts mismatch)
-; r1-r3,r12,lr: trashed
-;
- MACRO
- TP_CONTEXT_CHECK
-
- ldr r1, [r0, #TransparentProxyObject___stub]
- ldr r0, [r0, #TransparentProxyObject___stubData]
- blx r1
- MEND
-
-; ------------------------------------------------------------------
-; Used by the remoting precode for non-virtual dispatch to instance methods which might be remoted. Performs a
-; context and transparent proxy check and if both of these are negative (or the call has been made on a null
-; 'this') we simply return and the precode will dispatch the call locally as normal. Otherwise we redirect to
-; the remoting system and never return.
-;
-; On entry:
-; r0 : this (may or may not be a TransparentProxy)
-; r1 : trashed
-; lr : return address into RemotingPrecode (RemotingPrecode* + REMOTING_PRECODE_RET_OFFSET)
-; [sp, #0] : caller's saved r1
-; [sp, #4] : caller's saved lr (i.e. return address into caller of RemotingPrecode)
-; plus user arguments in registers and on the stack
-;
- LEAF_ENTRY PrecodeRemotingThunk
-
- ; Send null 'this' case to local dispatch case (else we'd need to handle an A/V from this stub).
- cbz r0, LocalDispatch ; predicted not taken
-
- ; Load MethodTable* in r12.
- ldr r12, [r0]
-
- ; Compare MethodTable in 'this' with that of __TransparentProxy; if they're not equal we dispatch
- ; locally.
- TP_TYPE_CHECK r12, r1 ; r1 is a scratch register
- beq TransparentProxyDispatch ; predicted not taken
-
-LocalDispatch
- ; Recover target MethodDesc pointer from the RemotingPrecode (we have the address of this +
- ; REMOTING_PRECODE_RET_OFFSET in lr). Subtract extra 1 to account for the low-bit being set in LR to
- ; indicate thumb mode.
- ; We do this here because even the local case needs r12 initialized.
- ldr r12, [lr, #(RemotingPrecode__m_pMethodDesc - REMOTING_PRECODE_RET_OFFSET - 1)]
-
- bx lr
-
- LEAF_END
-
-; ------------------------------------------------------------------
-; Handles the atypical path for the remoting precode above (typically the non-local dispatch cases). The
-; regular entry point defined by NESTED_ENTRY below is never called directly; it serves only to generate
-; prolog unwind data matching the pushes of the caller's r1 and lr done in the remoting precode so we can
-; unwind out of this frame. The real entry point is TransparentProxyDispatch called directly from
-; PrecodeRemotingThunk.
-;
- NESTED_ENTRY TransparentProxyDispatch_FakeProlog
-
- ; Match what the remoting precode has pushed.
- PROLOG_PUSH {r1,lr}
-
- ; This is where execution really starts.
-TransparentProxyDispatch
-
- ; We need some temporary registers and to preserve lr.
- PROLOG_PUSH {r0,r2-r5,lr}
-
- CHECK_STACK_ALIGNMENT
-
- ; Recover target MethodDesc pointer from the RemotingPrecode (we have the address of this +
- ; REMOTING_PRECODE_RET_OFFSET in lr). Subtract extra 1 to account for the low-bit being set in LR to
- ; indicate thumb mode. Stash the result in a non-volatile register to preserve it over the call to
- ; TP_CONTEXT_CHECK below.
- ldr r4, [lr, #(RemotingPrecode__m_pMethodDesc - REMOTING_PRECODE_RET_OFFSET - 1)]
-
- ; Check whether the TP is already in the correct context. This can happen for ContextBoundObjects
- ; only. The following macro will trash volatile registers and lr and return the result in r0 (0 ==
- ; context match, non-zero for everything else). All other registers are preserved.
- TP_CONTEXT_CHECK
-
- ; Place MethodDesc* in r12 ready for wherever we dispatch to next.
- mov r12, r4
-
- ; Check the result of TP_CONTEXT_CHECK
- cbnz r0, ContextMismatch1
-
- ; At this point we know we're being called on a transparent proxy but the source and destination
- ; contexts match. This only happens for a ContextBoundObject. For an non-interface dispatch we can
- ; just return to the local dispatch case; the precode will eventually redirect to the jitted code
- ; which knows how to handle a TP-wrapped ContextBoundObject. For interface calls we need to hand off
- ; to VSD so it can resolve to the real target method. The quickest way to determine which of these
- ; cases we need is to look at the classification of the method desc. All interface methods for which a
- ; remoting precode is used are marked as mcComInterop, which though non-intuitive is generally OK
- ; since only COM interop and remoting can dispatch directly on an interface method desc. (Generic
- ; interface methods are not classified as mcComInterop but we use a different mechanism to intercept
- ; those).
- ldrh r0, [r4, #MethodDesc__m_wFlags]
- and r0, #MethodDesc__mdcClassification
- cmp r0, #MethodDesc__mcComInterop
- bne LocalDispatch1
-
- ; Local interface dispatch case. Restore argument registers saved here and in the RemotingPrecode,
- ; discard return address into the RemotingPrecode (we're not going back there) and restore the real
- ; caller's return address to LR before tail calling into the interface dispatch helper.
- EPILOG_POP {r0,r2-r5,lr} ; Restore arg registers saved by this routine and RemotingPrecode lr
- EPILOG_POP {r1,lr} ; Restore r1 saved by RemotingPrecode and real return address
- EPILOG_BRANCH InContextTPQuickDispatchAsmStub
-
-LocalDispatch1
-
- ; Local dispatch case. Restore argument registers saved here and return to the remoting precode.
- EPILOG_POP {r0,r2-r5,pc}
-
-ContextMismatch1
- ; Context-mismatch (remoted) dispatch case. Restore argument registers saved here and in the
- ; RemotingPrecode, discard return address into the RemotingPrecode (we're not going back there) and
- ; restore the real caller's return address to LR before tail calling into the cross-context helper.
- EPILOG_POP {r0,r2-r5,lr} ; Restore arg registers saved by this routine and RemotingPrecode lr
- EPILOG_POP {r1,lr} ; Restore r1 saved by RemotingPrecode and real return address
- EPILOG_BRANCH TransparentProxyStub_CrossContext
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; Used to dispatch an interface call that is possibly be cross-context or remoted. Normally this is handled
-; by the remoting precode stub above but there is an edge case for generic interface methods that falls
-; through the cracks (it is not easy to cover since the precode stub makes use of it as a quick means
-; to differentiate between interface and non-interface calls in the non-cross context case).
-;
-; On entry:
-; r0 : this (TransparentProxy object)
-; r12 : interface MethodDesc
-; plus user arguments in registers and on the stack
-;
-; On exit:
-; Tail calls to the VSD in-context TP dispatcher or remoting system as appropriate.
-;
- NESTED_ENTRY CRemotingServices__DispatchInterfaceCall
-
- PROLOG_PUSH {r0-r3,r12,lr}
-
- CHECK_STACK_ALIGNMENT
-
- ; Check whether the TP is already in the correct context. This can happen for ContextBoundObjects
- ; only. The following macro will trash volatile registers and lr and return the result in r0 (0 ==
- ; context match, non-zero for everything else). All other registers are preserved.
- TP_CONTEXT_CHECK
- cbnz r0, ContextMismatch2
-
- ; Local interface dispatch case. Tail call to VSD helper specifically for the in-context TP dispatch
- ; scenario. Interface MethodDesc is restored to r12.
- EPILOG_POP {r0-r3,r12,lr}
- EPILOG_BRANCH InContextTPQuickDispatchAsmStub
-
-ContextMismatch2
- ; Context-mismatch (remoted) dispatch case. Tail call to the general remoting dispatch code. Interface
- ; MethodDesc is restored to r12.
- EPILOG_POP {r0-r3,r12,lr}
- EPILOG_BRANCH TransparentProxyStub_CrossContext
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; Common stub used for vtable dispatch of remoted methods. A small prestub will load the vtable slot index
-; into r12 and then jump here. This stub determines whether we're already in the correct context (which can
-; only happen for ContextBoundObjects). Depending on the answers we'll either dispatch the call locally or
-; re-direct it to the remoting system (via TransparentProxyStub_CrossContext).
-;
-; On entry:
-; r0 : this (TransparentProxy object)
-; r12 : virtual method slot number
-; plus user arguments in registers and on the stack
-;
-; On exit:
-; Tail calls to the VSD in-context TP dispatcher or remoting system as appropriate.
-;
- NESTED_ENTRY TransparentProxyStub
-
- PROLOG_PUSH {r0-r3,r12,lr}
-
- CHECK_STACK_ALIGNMENT
-
- ; Check whether the TP is already in the correct context. This can happen for ContextBoundObjects
- ; only. The following macro will trash volatile registers and lr and return the result in r0 (0 ==
- ; context match, non-zero for everything else). All other registers are preserved.
- TP_CONTEXT_CHECK
- cbnz r0, ContextMismatch3
-
- ; We need to perform a local vtable dispatch on the ContextBoundObject. Obviously this needs to be on
- ; the real type held in the proxy, not TransparentProxy's MethodTable or we'll just end up back here
- ; recursively.
-
- ; Recover 'this' pointer and slot number.
- ldr r0, [sp]
- ldr r12, [sp, #0x10]
-
- ; Extract real type from the TP.
- ldr r0, [r0, #TransparentProxyObject___pMT]
-
- ; Vtables are no longer a linear array. Instead they use a two-level indirection with the first level
- ; consisting of fixed sized chunks of function pointer arrays. R12 has our slot number.
-
- ; Calculate first level chunk index.
- lsr r1, r12, #ASM__VTABLE_SLOTS_PER_CHUNK_LOG2
-
- ; Load the address of the chunk from the MethodTable (the chunk table immediately follows the
- ; MethodTable structure).
- add r0, #SIZEOF__MethodTable
- ldr r2, [r0, r1, lsl #2]
-
- ; Calculate the slot index within the chunk.
- and r0, r12, #(ASM__VTABLE_SLOTS_PER_CHUNK - 1)
-
- ; Load the target address into r12 (we no longer need the slot number and we're about to restore the
- ; other registers).
- ldr r12, [r2, r0, lsl #2]
-
- ; Restore the stack state and tail call to the local target.
- EPILOG_POP {r0-r3}
- EPILOG_STACK_FREE 4 ; Skip restore of r12 since we've overwritten it
- EPILOG_POP {lr}
- EPILOG_BRANCH_REG r12
-
-ContextMismatch3
- ; Contexts don't match so we have to dispatch through remoting. Clean up the stack and tail call to
- ; the helper.
- EPILOG_POP {r0-r3,r12,lr}
- EPILOG_BRANCH TransparentProxyStub_CrossContext
+#endif // FEATURE_COMINTEROP
- NESTED_END
-#endif // FEATURE_REMOTING
-#if defined(FEATURE_REMOTING) || defined(FEATURE_COMINTEROP)
+#if defined(FEATURE_COMINTEROP)
; ------------------------------------------------------------------
; Function used by remoting/COM interop to get floating point return value (since it's not in the same
; register(s) as non-floating point values).
@@ -1168,116 +760,8 @@ LsetFP8
LEAF_END
-#endif defined(FEATURE_REMOTING) || defined(FEATURE_COMINTEROP)
-#ifdef FEATURE_REMOTING
-
-; ------------------------------------------------------------------
-; Tail call Object.FieldGetter remotely with the given arguments.
-;
-; On entry:
-; r0 : pMD (MethodDesc * of the Object.FieldGetter method)
-; r1 : pThis (the transparent proxy)
-; r2 : pFirst
-; r3 : pSecond
-; [sp, #0] : pThird
-;
-; On exit:
-; Tail calls to the managed method
-;
- LEAF_ENTRY CRemotingServices__CallFieldGetter
-
- mov r12, r0
- mov r0, r1
- mov r1, r2
- mov r2, r3
- ldr r3, [sp, #0]
-
- b TransparentProxyStub_CrossContext
-
- LEAF_END
-
-; ------------------------------------------------------------------
-; Tail call Object.FieldSetter remotely with the given arguments.
-;
-; On entry:
-; r0 : pMD (MethodDesc * of the Object.FieldSetter method)
-; r1 : pThis (the transparent proxy)
-; r2 : pFirst
-; r3 : pSecond
-; [sp, #0] : pThird
-;
-; On exit:
-; Tail calls to the managed method
-;
- LEAF_ENTRY CRemotingServices__CallFieldSetter
-
- mov r12, r0
- mov r0, r1
- mov r1, r2
- mov r2, r3
- ldr r3, [sp, #0]
-
- b TransparentProxyStub_CrossContext
-
- LEAF_END
-
-; ------------------------------------------------------------------
-; General purpose remoting helper used to call given target with two parameters.
-;
-; On entry:
-; r0 : pTarget
-; r1 : pFirst
-; r2 : pSecond
-;
-;
- NESTED_ENTRY CTPMethodTable__CallTargetHelper2,,CallDescrWorkerUnwindFrameChainHandler
-
- PROLOG_PUSH {r11, lr}
-
- mov r12, r0
- mov r0, r1
- mov r1, r2
-
- blx r12
-
- ; Adding a nop so that unwind does not result in the IP being in epilog.
- ; This ensures that the OS unwinder looks up the personality routine for this method.
- nop
-
- EPILOG_POP {r11, pc}
-
- NESTED_END
-
-; ------------------------------------------------------------------
-; General purpose remoting helper used to call given target with three parameters.
-;
-; On entry:
-; r0 : pTarget
-; r1 : pFirst
-; r2 : pSecond
-; r3 : pThird
-;
-;
- NESTED_ENTRY CTPMethodTable__CallTargetHelper3,,CallDescrWorkerUnwindFrameChainHandler
-
- PROLOG_PUSH {r11, lr}
-
- mov r12, r0
- mov r0, r1
- mov r1, r2
- mov r2, r3
-
- blx r12
-
- ; Adding a nop so that unwind does not result in the IP being in epilog.
- ; This ensures that the OS unwinder looks up the personality routine for this method.
- nop
-
- EPILOG_POP {r11, pc}
-
- NESTED_END
+#endif defined(FEATURE_COMINTEROP)
-#endif // FEATURE_REMOTING
#ifdef FEATURE_COMINTEROP
; ------------------------------------------------------------------
diff --git a/src/vm/arm/cgencpu.h b/src/vm/arm/cgencpu.h
index 63c578bb88..34af8187b2 100644
--- a/src/vm/arm/cgencpu.h
+++ b/src/vm/arm/cgencpu.h
@@ -63,9 +63,6 @@ EXTERN_C void checkStack(void);
#define USE_INDIRECT_CODEHEADER
-#ifdef FEATURE_REMOTING
-#define HAS_REMOTING_PRECODE 1
-#endif
EXTERN_C void getFPReturn(int fpSize, INT64 *pRetVal);
EXTERN_C void setFPReturn(int fpSize, INT64 retVal);
diff --git a/src/vm/arm/ehhelpers.S b/src/vm/arm/ehhelpers.S
index 88afc43415..27f246c607 100644
--- a/src/vm/arm/ehhelpers.S
+++ b/src/vm/arm/ehhelpers.S
@@ -75,27 +75,6 @@ OFFSET_OF_FRAME=(4 + SIZEOF__GSCookie)
.endm
// ------------------------------------------------------------------
-//
-// Helpers for async (NullRef, AccessViolation) exceptions
-//
-
- NESTED_ENTRY NakedThrowHelper2,_TEXT,FixContextHandler
- push {r0, lr}
-
- // On entry:
- //
- // R0 = Address of FaultingExceptionFrame
- bl C_FUNC(LinkFrameAndThrow)
-
- // Target should not return.
- EMIT_BREAKPOINT
-
- NESTED_END NakedThrowHelper2, _TEXT
-
-
- GenerateRedirectedStubWithFrame NakedThrowHelper, NakedThrowHelper2
-
-// ------------------------------------------------------------------
// This helper enables us to call into a funclet after applying the non-volatiles
NESTED_ENTRY CallEHFunclet, _TEXT, NoHandler
diff --git a/src/vm/arm/exceparm.cpp b/src/vm/arm/exceparm.cpp
index 6852adcc33..9b14d41c83 100644
--- a/src/vm/arm/exceparm.cpp
+++ b/src/vm/arm/exceparm.cpp
@@ -54,38 +54,6 @@ FaultingExceptionFrame *GetFrameFromRedirectedStubStackFrame (T_DISPATCHER_CONTE
return (FaultingExceptionFrame*)((TADDR)pDispatcherContext->ContextRecord->R4);
}
-//Return TRUE if pContext->Pc is in VirtualStub
-BOOL IsIPinVirtualStub(PCODE f_IP)
-{
- LIMITED_METHOD_CONTRACT;
-
- Thread * pThread = GetThread();
-
- // We may not have a managed thread object. Example is an AV on the helper thread.
- // (perhaps during StubManager::IsStub)
- if (pThread == NULL)
- {
- return FALSE;
- }
-
- VirtualCallStubManager::StubKind sk;
- VirtualCallStubManager::FindStubManager(f_IP, &sk);
-
- if (sk == VirtualCallStubManager::SK_DISPATCH)
- {
- return TRUE;
- }
- else if (sk == VirtualCallStubManager::SK_RESOLVE)
- {
- return TRUE;
- }
-
- else {
- return FALSE;
- }
-}
-
-
// Returns TRUE if caller should resume execution.
BOOL
AdjustContextForVirtualStub(
diff --git a/src/vm/arm/excepcpu.h b/src/vm/arm/excepcpu.h
index f13d81fdcb..fc0c44e5de 100644
--- a/src/vm/arm/excepcpu.h
+++ b/src/vm/arm/excepcpu.h
@@ -46,6 +46,5 @@ PCODE GetAdjustedCallAddress(PCODE returnAddress)
}
BOOL AdjustContextForVirtualStub(EXCEPTION_RECORD *pExceptionRecord, T_CONTEXT *pContext);
-BOOL IsIPinVirtualStub(PCODE f_IP);
#endif // __excepcpu_h__
diff --git a/src/vm/arm/stubs.cpp b/src/vm/arm/stubs.cpp
index 1309695f73..f1ba278ada 100644
--- a/src/vm/arm/stubs.cpp
+++ b/src/vm/arm/stubs.cpp
@@ -16,9 +16,6 @@
#include "field.h"
#include "dllimportcallback.h"
#include "dllimport.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "eeconfig.h"
#include "cgensys.h"
#include "asmconstants.h"
@@ -2484,12 +2481,6 @@ void HijackFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
}
#endif
-void PInvokeStubForHost(void)
-{
- // Hosted P/Invoke is not implemented on ARM. See ARMTODO in code:CorHost2::SetHostControl.
- UNREACHABLE();
-}
-
class UMEntryThunk * UMEntryThunk::Decode(void *pCallback)
{
_ASSERTE(offsetof(UMEntryThunkCode, m_code) == 0);
@@ -2650,7 +2641,7 @@ void InitJITHelpers1()
))
{
- _ASSERTE(GCHeapUtilities::UseAllocationContexts());
+ _ASSERTE(GCHeapUtilities::UseThreadAllocationContexts());
// If the TLS for Thread is low enough use the super-fast helpers
if (gThreadTLSIndex < TLS_MINIMUM_AVAILABLE)
{
@@ -2675,7 +2666,6 @@ void InitJITHelpers1()
}
-#ifdef FEATURE_CORECLR
if(IsSingleAppDomain())
{
SetJitHelperFunction(CORINFO_HELP_GETSHARED_GCSTATIC_BASE, JIT_GetSharedGCStaticBase_SingleAppDomain);
@@ -2684,7 +2674,6 @@ void InitJITHelpers1()
SetJitHelperFunction(CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR,JIT_GetSharedNonGCStaticBaseNoCtor_SingleAppDomain);
}
else
-#endif
if (gAppDomainTLSIndex >= TLS_MINIMUM_AVAILABLE)
{
SetJitHelperFunction(CORINFO_HELP_GETSHARED_GCSTATIC_BASE, JIT_GetSharedGCStaticBase_Portable);
@@ -3514,177 +3503,6 @@ VOID ResetCurrentContext()
}
#endif // !DACCESS_COMPILE
-#if defined(FEATURE_REMOTING) && !defined(CROSSGEN_COMPILE)
-
-#ifndef DACCESS_COMPILE
-PCODE CTPMethodTable::CreateThunkForVirtualMethod(DWORD dwSlot, BYTE *startaddr)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(startaddr));
- }
- CONTRACTL_END;
-
- WORD *pCode = (WORD*)((ULONG_PTR)startaddr);
-
- // Slot literal is split into four pieces in the mov instruction:
- // imm4:i:imm3:imm8
- _ASSERTE(FitsInU2(dwSlot));
- WORD imm4 = ((WORD)dwSlot & 0xf000) >> 12;
- WORD i = ((WORD)dwSlot & 0x0800) >> 11;
- WORD imm3 = ((WORD)dwSlot & 0x0700) >> 8;
- WORD imm8 = (WORD)dwSlot & 0x00ff;
-
- // f240 0c00 mov r12, #dwSlot
- // f8df f000 ldr pc, [pc, #0]
- // ???? ???? dcd TransparentProxyStub
-
- *pCode++ = 0xf240 | (i << 10) | imm4;
- *pCode++ = 0x0c00 | (imm3 << 12) | imm8;
- *pCode++ = 0xf8df;
- *pCode++ = 0xf000;
- *((PCODE*)pCode) = GetTPStubEntryPoint();
-
- _ASSERTE(CVirtualThunkMgr::IsThunkByASM((PCODE)startaddr));
-
- return (PCODE)(startaddr + THUMB_CODE);
-}
-#endif // DACCESS_COMPILE
-
-BOOL CVirtualThunkMgr::IsThunkByASM(PCODE startaddr)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(startaddr != NULL);
- }
- CONTRACTL_END;
-
-#ifndef DACCESS_COMPILE
- PTR_WORD pInstr = dac_cast<PTR_WORD>(PCODEToPINSTR(startaddr));
-
- return (((pInstr[0] & 0xf240) == 0xf240) &&
- ((pInstr[1] & 0x0c00) == 0x0c00) &&
- (pInstr[2] == 0xf8df) &&
- (pInstr[3] == 0xf000) &&
- (*(PCODE*)&pInstr[4] == CTPMethodTable::GetTPStubEntryPoint()));
-#else
- DacNotImpl();
- return FALSE;
-#endif
-}
-
-MethodDesc *CVirtualThunkMgr::GetMethodDescByASM(PCODE startaddr, MethodTable *pMT)
-{
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(startaddr != NULL);
- PRECONDITION(CheckPointer(pMT));
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- _ASSERTE(IsThunkByASM(startaddr));
-
- PTR_WORD pInstr = dac_cast<PTR_WORD>(PCODEToPINSTR(startaddr));
-
- WORD i = (pInstr[0] & 0x0400) >> 10;
- WORD imm4 = pInstr[0] & 0x000f;
- WORD imm3 = (pInstr[1] & 0x7000) >> 12;
- WORD imm8 = pInstr[1] & 0x00ff;
-
- WORD wSlot = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
-
- RETURN (pMT->GetMethodDescForSlot(wSlot));
-}
-
-#ifndef DACCESS_COMPILE
-
-BOOL CVirtualThunkMgr::DoTraceStub(PCODE stubStartAddress, TraceDestination *trace)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(stubStartAddress != NULL);
- PRECONDITION(CheckPointer(trace));
- }
- CONTRACTL_END;
-
- TADDR pInstr = PCODEToPINSTR(stubStartAddress);
-
- BOOL bIsStub = FALSE;
-
- // Find a thunk whose code address matching the starting address
- LPBYTE pThunk = FindThunk((LPBYTE)pInstr);
- if (pThunk)
- {
- LONG destAddress = 0;
-
- // The stub target address is stored as an absolute pointer 8 byte into the thunk.
- destAddress = *(LONG*)(pThunk + 8);
-
- // We cannot tell where the stub will end up until OnCall is reached.
- // So we tell the debugger to run till OnCall is reached and then
- // come back and ask us again for the actual destination address of
- // the call
-
- Stub *stub = Stub::RecoverStub((TADDR)destAddress);
-
- trace->InitForFramePush(stub->GetPatchAddress());
- bIsStub = TRUE;
- }
-
- return bIsStub;
-}
-
-extern "C" UINT_PTR __stdcall CRemotingServices__CheckForContextMatch(Object* pStubData)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE; // due to the Object parameter
- SO_TOLERANT;
- PRECONDITION(CheckPointer(pStubData));
- }
- CONTRACTL_END;
-
- UINT_PTR contextID = *(UINT_PTR*)pStubData->UnBox();
- UINT_PTR contextCur = (UINT_PTR)GetThread()->m_Context;
- return (contextCur != contextID); // chosen to match x86 convention
-}
-
-// Return true if the current context matches that of the transparent proxy given.
-BOOL CTPMethodTable__GenericCheckForContextMatch(Object* orTP)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE; // due to the Object parameter
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- Object *StubData = OBJECTREFToObject(((TransparentProxyObject*)orTP)->GetStubData());
- CTPMethodTable::CheckContextCrossingProc *pfnCheckContextCrossing =
- (CTPMethodTable::CheckContextCrossingProc*)(((TransparentProxyObject*)orTP)->GetStub());
- return pfnCheckContextCrossing(StubData) == 0;
-}
-
-#endif // !DACCESS_COMPILE
-
-#endif // FEATURE_REMOTING && !CROSSGEN_COMPILE
#ifdef FEATURE_COMINTEROP
void emitCOMStubCall (ComCallMethodDesc *pCOMMethod, PCODE target)
diff --git a/src/vm/arm/unixstubs.cpp b/src/vm/arm/unixstubs.cpp
index 8a68103bae..62f60473ab 100644
--- a/src/vm/arm/unixstubs.cpp
+++ b/src/vm/arm/unixstubs.cpp
@@ -11,11 +11,6 @@ extern "C"
PORTABILITY_ASSERT("Implement for PAL");
}
- void PInvokeStubForHostInner(DWORD dwStackSize, LPVOID pStackFrame, LPVOID pTarget)
- {
- PORTABILITY_ASSERT("Implement for PAL");
- }
-
void RedirectForThreadAbort()
{
PORTABILITY_ASSERT("Implement for PAL");
diff --git a/src/vm/arm/virtualcallstubcpu.hpp b/src/vm/arm/virtualcallstubcpu.hpp
index b16983f10a..a1e15d3661 100644
--- a/src/vm/arm/virtualcallstubcpu.hpp
+++ b/src/vm/arm/virtualcallstubcpu.hpp
@@ -9,9 +9,6 @@
#ifdef DECLARE_DATA
#include "asmconstants.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#ifdef FEATURE_PREJIT
#include "compile.h"
#endif
diff --git a/src/vm/arm64/asmhelpers.S b/src/vm/arm64/asmhelpers.S
index d92e91cfd7..ef6b5cfffe 100644
--- a/src/vm/arm64/asmhelpers.S
+++ b/src/vm/arm64/asmhelpers.S
@@ -107,6 +107,7 @@ LEAF_ENTRY HelperMethodFrameRestoreState, _TEXT
RestoreRegMS 26, X26
RestoreRegMS 27, X27
RestoreRegMS 28, X28
+ RestoreRegMS 29, X29
LOCAL_LABEL(Done):
// Its imperative that the return value of HelperMethodFrameRestoreState is zero
// as it is used in the state machine to loop until it becomes zero.
@@ -120,18 +121,18 @@ LEAF_END HelperMethodFrameRestoreState, _TEXT
// The call in ndirect import precode points to this function.
NESTED_ENTRY NDirectImportThunk, _TEXT, NoHandler
- PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, #-144
+ PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -160
SAVE_ARGUMENT_REGISTERS sp, 16
- SAVE_FLOAT_ARGUMENT_REGISTERS sp, 80
+ SAVE_FLOAT_ARGUMENT_REGISTERS sp, 88
mov x0, x12
bl NDirectImportWorker
mov x12, x0
// pop the stack and restore original register state
- RESTORE_FLOAT_ARGUMENT_REGISTERS sp, 80
+ RESTORE_FLOAT_ARGUMENT_REGISTERS sp, 88
RESTORE_ARGUMENT_REGISTERS sp, 16
- EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, #144
+ EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 160
// If we got back from NDirectImportWorker, the MD has been successfully
// linked. Proceed to execute the original DLL call.
@@ -140,8 +141,14 @@ NESTED_ENTRY NDirectImportThunk, _TEXT, NoHandler
NESTED_END NDirectImportThunk, _TEXT
// ------------------------------------------------------------------
-// ARM64TODO: Implement PrecodeFixupThunk when PreCode is Enabled
+// The call in fixup precode initally points to this function.
+// The pupose of this function is to load the MethodDesc and forward the call to prestub.
NESTED_ENTRY PrecodeFixupThunk, _TEXT, NoHandler
+ // x12 = FixupPrecode *
+ // On Exit
+ // x12 = MethodDesc*
+ // x13, x14 Trashed
+ // Inline computation done by FixupPrecode::GetMethodDesc()
ldrb w13, [x12, #Offset_PrecodeChunkIndex] //m_PrecodeChunkIndex
ldrb w14, [x12, #Offset_MethodDescChunkIndex] // m_MethodDescChunkIndex
@@ -181,34 +188,6 @@ C_FUNC(ThePreStubPatchLabel):
LEAF_END ThePreStubPatch, _TEXT
-// ------------------------------------------------------------------
-// void ResolveWorkerAsmStub(args in regs x0-x7 & stack, x11:IndirectionCellAndFlags, x12:DispatchToken)
-//
-// The stub dispatch thunk which transfers control to VSD_ResolveWorker.
-NESTED_ENTRY ResolveWorkerAsmStub, _TEXT, NoHandler
-
- PROLOG_WITH_TRANSITION_BLOCK
-
- add x0, sp, #__PWTB_TransitionBlock // pTransitionBlock
- and x1, x11, #-4 // Indirection cell
- mov x2, x12 // DispatchToken
- and x3, x11, #3 // flag
- bl C_FUNC(VSD_ResolveWorker)
- mov x9, x0
-
- EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
-
- EPILOG_BRANCH_REG x9
-
-NESTED_END ResolveWorkerAsmStub, _TEXT
-
-NESTED_ENTRY ResolveWorkerChainLookupAsmStub, _TEXT, NoHandler
-
- // ARMSTUB TODO: implement chained lookup
- b C_FUNC(ResolveWorkerAsmStub)
-
-NESTED_END ResolveWorkerChainLookupAsmStub, _TEXT
-
//-----------------------------------------------------------------------------
// The following Macros help in WRITE_BARRIER Implemetations
// WRITE_BARRIER_ENTRY
@@ -288,6 +267,49 @@ WRITE_BARRIER_ENTRY JIT_WriteBarrier
dmb ST
str x15, [x14]
+#ifdef WRITE_BARRIER_CHECK
+ // Update GC Shadow Heap
+
+ // need temporary registers. Save them before using.
+ stp x12, x13, [sp, #-16]!
+
+ // Compute address of shadow heap location:
+ // pShadow = g_GCShadow + (x14 - g_lowest_address)
+ PREPARE_EXTERNAL_VAR g_lowest_address, x12
+ ldr x12, [x12]
+ sub x12, x14, x12
+ PREPARE_EXTERNAL_VAR g_GCShadow, x13
+ ldr x13, [x13]
+ add x12, x13, x12
+
+ // if (pShadow >= g_GCShadowEnd) goto end
+ PREPARE_EXTERNAL_VAR g_GCShadowEnd, x13
+ ldr x13, [x13]
+ cmp x12, x13
+ bhs LOCAL_LABEL(shadowupdateend)
+
+ // *pShadow = x15
+ str x15, [x12]
+
+ // Ensure that the write to the shadow heap occurs before the read from the GC heap so that race
+ // conditions are caught by INVALIDGCVALUE.
+ dmb sy
+
+ // if ([x14] == x15) goto end
+ ldr x13, [x14]
+ cmp x13, x15
+ beq LOCAL_LABEL(shadowupdateend)
+
+ // *pShadow = INVALIDGCVALUE (0xcccccccd)
+ mov x13, #0
+ movk x13, #0xcccd
+ movk x13, #0xcccc, LSL #16
+ str x13, [x12]
+
+LOCAL_LABEL(shadowupdateend):
+ ldp x12, x13, [sp],#16
+#endif
+
// Branch to Exit if the reference is not in the Gen0 heap
//
PREPARE_EXTERNAL_VAR g_ephemeral_low, x12
@@ -347,9 +369,9 @@ LEAF_END JIT_PatchedCodeLast, _TEXT
NESTED_ENTRY VirtualMethodFixupStub, _TEXT, NoHandler
// Save arguments and return address
- PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, #-144
+ PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -160
SAVE_ARGUMENT_REGISTERS sp, 16
- SAVE_FLOAT_ARGUMENT_REGISTERS sp, 80
+ SAVE_FLOAT_ARGUMENT_REGISTERS sp, 88
// Refer to ZapImportVirtualThunk::Save
// for details on this.
@@ -366,8 +388,8 @@ NESTED_ENTRY VirtualMethodFixupStub, _TEXT, NoHandler
// pop the stack and restore original register state
RESTORE_ARGUMENT_REGISTERS sp, 16
- RESTORE_FLOAT_ARGUMENT_REGISTERS sp, 80
- EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, #144
+ RESTORE_FLOAT_ARGUMENT_REGISTERS sp, 88
+ EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 160
PATCH_LABEL VirtualMethodFixupPatchLabel
@@ -425,15 +447,161 @@ LOCAL_LABEL(LNullThis):
LEAF_END SinglecastDelegateInvokeStub, _TEXT
+#ifdef FEATURE_COMINTEROP
+
+#define ComCallPreStub_FrameSize (SIZEOF__GSCookie + SIZEOF__ComMethodFrame)
+#define ComCallPreStub_FirstStackAdjust (SIZEOF__ArgumentRegisters + 2 * 8) // reg args , fp & lr already pushed
+#define ComCallPreStub_StackAlloc0 (ComCallPreStub_FrameSize - ComCallPreStub_FirstStackAdjust)
+#define ComCallPreStub_StackAlloc1 (ComCallPreStub_StackAlloc0 + SIZEOF__FloatArgumentRegisters + 8)// 8 for ErrorReturn
+#define ComCallPreStub_StackAlloc (ComCallPreStub_StackAlloc1 + (ComCallPreStub_StackAlloc1 & 8))
+
+#define ComCallPreStub_FrameOffset (ComCallPreStub_StackAlloc - (SIZEOF__ComMethodFrame - ComCallPreStub_FirstStackAdjust))
+#define ComCallPreStub_ErrorReturnOffset0 SIZEOF__FloatArgumentRegisters
+
+#define ComCallPreStub_FirstStackAdjust (ComCallPreStub_ErrorReturnOffset0 + (ComCallPreStub_ErrorReturnOffset0 & 8))
+
+// ------------------------------------------------------------------
+// COM to CLR stub called the first time a particular method is invoked.//
+//
+// On entry:
+// x12 : ComCallMethodDesc* provided by prepad thunk
+// plus user arguments in registers and on the stack
+//
+// On exit:
+// tail calls to real method
+//
+NESTED_ENTRY ComCallPreStub, _TEXT, NoHandler
+
+ // Save arguments and return address
+ PROLOG_SAVE_REG_PAIR fp, lr, -ComCallPreStub_FirstStackAdjust!
+ PROLOG_STACK_ALLOC ComCallPreStub_StackAlloc
+
+ SAVE_ARGUMENT_REGISTERS sp, (16+ComCallPreStub_StackAlloc)
+
+ SAVE_FLOAT_ARGUMENT_REGISTERS sp, 0
+
+ str x12, [sp, #(ComCallPreStub_FrameOffset + UnmanagedToManagedFrame__m_pvDatum)]
+ add x0, sp, #(ComCallPreStub_FrameOffset)
+ add x1, sp, #(ComCallPreStub_ErrorReturnOffset)
+ bl ComPreStubWorker
+
+ cbz x0, ComCallPreStub_ErrorExit
+
+ mov x12, x0
+
+ // pop the stack and restore original register state
+ RESTORE_FLOAT_ARGUMENT_REGISTERS sp, 0
+ RESTORE_ARGUMENT_REGISTERS sp, (16+ComCallPreStub_StackAlloc)
+
+ EPILOG_STACK_FREE ComCallPreStub_StackAlloc
+ EPILOG_RESTORE_REG_PAIR fp, lr, ComCallPreStub_FirstStackAdjust!
+
+ // and tailcall to the actual method
+ EPILOG_BRANCH_REG x12
+
+ComCallPreStub_ErrorExit
+ ldr x0, [sp, #(ComCallPreStub_ErrorReturnOffset)] // ErrorReturn
+
+ // pop the stack
+ EPILOG_STACK_FREE ComCallPreStub_StackAlloc
+ EPILOG_RESTORE_REG_PAIR fp, lr, ComCallPreStub_FirstStackAdjust!
+
+ EPILOG_RETURN
+
+NESTED_END ComCallPreStub, _TEXT
+
+// ------------------------------------------------------------------
+// COM to CLR stub which sets up a ComMethodFrame and calls COMToCLRWorker.
+//
+// On entry:
+// x12 : ComCallMethodDesc* provided by prepad thunk
+// plus user arguments in registers and on the stack
+//
+// On exit:
+// Result in x0/d0 as per the real method being called
+//
+ NESTED_ENTRY GenericComCallStub, _TEXT, NoHandler
+
+ // Save arguments and return address
+ PROLOG_SAVE_REG_PAIR fp, lr, -GenericComCallStub_FirstStackAdjust!
+ PROLOG_STACK_ALLOC GenericComCallStub_StackAlloc
+
+ SAVE_ARGUMENT_REGISTERS sp, (16+GenericComCallStub_StackAlloc)
+ SAVE_FLOAT_ARGUMENT_REGISTERS sp, 0
+
+ str x12, [sp, #(GenericComCallStub_FrameOffset + UnmanagedToManagedFrame__m_pvDatum)]
+ add x1, sp, #GenericComCallStub_FrameOffset
+ bl COMToCLRWorker
+
+ // pop the stack
+ EPILOG_STACK_FREE GenericComCallStub_StackAlloc
+ EPILOG_RESTORE_REG_PAIR fp, lr, GenericComCallStub_FirstStackAdjust!
+
+ EPILOG_RETURN
+
+ NESTED_END GenericComCallStub, _TEXT
+
+// ------------------------------------------------------------------
+// COM to CLR stub called from COMToCLRWorker that actually dispatches to the real managed method.
+//
+// On entry:
+// x0 : dwStackSlots, count of argument stack slots to copy
+// x1 : pFrame, ComMethodFrame pushed by GenericComCallStub above
+// x2 : pTarget, address of code to call
+// x3 : pSecretArg, hidden argument passed to target above in x12
+// x4 : pDangerousThis, managed 'this' reference
+//
+// On exit:
+// Result in x0/d0 as per the real method being called
+//
+ NESTED_ENTRY COMToCLRDispatchHelper, _TEXT,CallDescrWorkerUnwindFrameChainHandler
+
+ PROLOG_SAVE_REG_PAIR fp, lr, -16!
+
+ cbz x0, COMToCLRDispatchHelper_RegSetup
+
+ add x9, x1, #SIZEOF__ComMethodFrame
+ add x9, x9, x0, LSL #3
+COMToCLRDispatchHelper_StackLoop
+ ldr x8, [x9, #-8]!
+ str x8, [sp, #-8]!
+ sub x0, x0, #1
+ cbnz x0, COMToCLRDispatchHelper_StackLoop
+
+COMToCLRDispatchHelper_RegSetup
+
+ RESTORE_FLOAT_ARGUMENT_REGISTERS x1, -1 * GenericComCallStub_FrameOffset
+
+ mov lr, x2
+ mov x12, x3
+
+ mov x0, x4
+
+ ldp x2, x3, [x1, #(SIZEOF__ComMethodFrame - SIZEOF__ArgumentRegisters + 16)]
+ ldp x4, x5, [x1, #(SIZEOF__ComMethodFrame - SIZEOF__ArgumentRegisters + 32)]
+ ldp x6, x7, [x1, #(SIZEOF__ComMethodFrame - SIZEOF__ArgumentRegisters + 48)]
+ ldr x8, [x1, #(SIZEOF__ComMethodFrame - SIZEOF__ArgumentRegisters + 64)]
+
+ ldr x1, [x1, #(SIZEOF__ComMethodFrame - SIZEOF__ArgumentRegisters + 8)]
+
+ blr lr
+
+ EPILOG_STACK_RESTORE
+ EPILOG_RESTORE_REG_PAIR fp, lr, 16!
+ EPILOG_RETURN
+
+ NESTED_END COMToCLRDispatchHelper, _TEXT
+
+#endif // FEATURE_COMINTEROP
//
// x12 = UMEntryThunk*
//
NESTED_ENTRY TheUMEntryPrestub, _TEXT, UnhandledExceptionHandlerUnix
// Save arguments and return address
- PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, #-144
+ PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -160
SAVE_ARGUMENT_REGISTERS sp, 16
- SAVE_FLOAT_ARGUMENT_REGISTERS sp, 80
+ SAVE_FLOAT_ARGUMENT_REGISTERS sp, 88
mov x0, x12
bl C_FUNC(TheUMEntryPrestubWorker)
@@ -443,8 +611,8 @@ NESTED_ENTRY TheUMEntryPrestub, _TEXT, UnhandledExceptionHandlerUnix
// pop the stack and restore original register state
RESTORE_ARGUMENT_REGISTERS sp, 16
- RESTORE_FLOAT_ARGUMENT_REGISTERS sp, 80
- EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, #144
+ RESTORE_FLOAT_ARGUMENT_REGISTERS sp, 88
+ EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 160
// and tailcall to the actual method
EPILOG_BRANCH_REG x12
@@ -457,14 +625,14 @@ NESTED_END TheUMEntryPrestub, _TEXT
NESTED_ENTRY UMThunkStub, _TEXT, UnhandledExceptionHandlerUnix
// Save arguments and return address
- PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, #-96 // 64 for regArgs, 8 for x19 & 8 for x12
+ PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -112 // 72 for regArgs, 8 for x19 & 8 for x12
// save callee saved reg x19. x19 is used in the method to store thread*
- PROLOG_SAVE_REG x19, #88
+ PROLOG_SAVE_REG x19, 96
SAVE_ARGUMENT_REGISTERS sp, 16
-#define UMThunkStub_HiddenArg 80 // offset of saved UMEntryThunk *
-#define UMThunkStub_StackArgs 96 // offset of original stack args (total size of UMThunkStub frame)
+#define UMThunkStub_HiddenArg 88 // offset of saved UMEntryThunk *
+#define UMThunkStub_StackArgs 112 // offset of original stack args (total size of UMThunkStub frame)
// save UMEntryThunk*
str x12, [sp, #UMThunkStub_HiddenArg]
@@ -542,8 +710,8 @@ LOCAL_LABEL(UMThunkStub_PostCall):
str w4, [x19, #Thread__m_fPreemptiveGCDisabled]
EPILOG_STACK_RESTORE
- EPILOG_RESTORE_REG x19, #88
- EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, #96
+ EPILOG_RESTORE_REG x19, 96
+ EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 112
EPILOG_RETURN
@@ -581,7 +749,7 @@ LOCAL_LABEL(UMThunkStub_WrongAppDomain):
bl C_FUNC(UM2MDoADCallBack)
// restore integral return value
- ldr x0, [fp, #16]
+ ldp x0, x1, [fp, #16]
// restore FP or HFA return value
RESTORE_FLOAT_ARGUMENT_REGISTERS sp, 0
@@ -601,8 +769,8 @@ NESTED_END UMThunkStub, _TEXT
NESTED_ENTRY UM2MThunk_WrapperHelper, _TEXT, NoHandler
- PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, #-32
- PROLOG_SAVE_REG x19, #16
+ PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -32
+ PROLOG_SAVE_REG x19, 16
// save pThunkArgs in non-volatile reg. It is required after return from call to ILStub
@@ -659,13 +827,14 @@ LOCAL_LABEL(UM2MThunk_WrapperHelper_RegArgumentsSetup):
blr x16
// save integral return value
- str x0, [x19]
+ stp x0, x1, [x19]
+
// save FP/HFA return values
SAVE_FLOAT_ARGUMENT_REGISTERS x19, -1 * (SIZEOF__FloatArgumentRegisters + 16)
EPILOG_STACK_RESTORE
- EPILOG_RESTORE_REG x19, #16
- EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, #32
+ EPILOG_RESTORE_REG x19, 16
+ EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 32
EPILOG_RETURN
NESTED_END UM2MThunk_WrapperHelper, _TEXT
@@ -675,13 +844,13 @@ NESTED_END UM2MThunk_WrapperHelper, _TEXT
// ------------------------------------------------------------------
// Hijack function for functions which return a scalar type or a struct (value type)
NESTED_ENTRY OnHijackTripThread, _TEXT, NoHandler
- PROLOG_SAVE_REG_PAIR fp, lr, #-144
- // Spill callee saved registers
- PROLOG_SAVE_REG_PAIR x19, x20, #16
- PROLOG_SAVE_REG_PAIR x21, x22, #32
- PROLOG_SAVE_REG_PAIR x23, x24, #48
- PROLOG_SAVE_REG_PAIR x25, x26, #64
- PROLOG_SAVE_REG_PAIR x27, x28, #80
+ PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -144
+ // Spill callee saved registers
+ PROLOG_SAVE_REG_PAIR x19, x20, 16
+ PROLOG_SAVE_REG_PAIR x21, x22, 32
+ PROLOG_SAVE_REG_PAIR x23, x24, 48
+ PROLOG_SAVE_REG_PAIR x25, x26, 64
+ PROLOG_SAVE_REG_PAIR x27, x28, 80
// save any integral return value(s)
stp x0, x1, [sp, #96]
@@ -692,7 +861,7 @@ NESTED_ENTRY OnHijackTripThread, _TEXT, NoHandler
mov x0, sp
bl OnHijackWorker
-
+
// restore any integral return value(s)
ldp x0, x1, [sp, #96]
@@ -700,12 +869,12 @@ NESTED_ENTRY OnHijackTripThread, _TEXT, NoHandler
ldp d0, d1, [sp, #112]
ldp d2, d3, [sp, #128]
- EPILOG_RESTORE_REG_PAIR x19, x20, #16
- EPILOG_RESTORE_REG_PAIR x21, x22, #32
- EPILOG_RESTORE_REG_PAIR x23, x24, #48
- EPILOG_RESTORE_REG_PAIR x25, x26, #64
- EPILOG_RESTORE_REG_PAIR x27, x28, #80
- EPILOG_RESTORE_REG_PAIR fp, lr, #144
+ EPILOG_RESTORE_REG_PAIR x19, x20, 16
+ EPILOG_RESTORE_REG_PAIR x21, x22, 32
+ EPILOG_RESTORE_REG_PAIR x23, x24, 48
+ EPILOG_RESTORE_REG_PAIR x25, x26, 64
+ EPILOG_RESTORE_REG_PAIR x27, x28, 80
+ EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 144
EPILOG_RETURN
NESTED_END OnHijackTripThread, _TEXT
@@ -732,16 +901,6 @@ GenerateRedirectedHandledJITCaseStub GCStress
// This helper enables us to call into a funclet after restoring Fp register
NESTED_ENTRY CallEHFunclet, _TEXT, NoHandler
-
- // Using below prolog instead of PROLOG_SAVE_REG_PAIR fp,lr, #-16
- // is intentional. Above statement would also emit instruction to save
- // sp in fp. If sp is saved in fp in prolog then it is not expected that fp can change in the body
- // of method. However, this method needs to be able to change fp before calling funclet.
- // This is required to access locals in funclet.
- PROLOG_SAVE_REG_PAIR_INDEXED x19,x20, #-16
- PROLOG_SAVE_REG fp, #0
- PROLOG_SAVE_REG lr, #8
-
// On entry:
//
// X0 = throwable
@@ -749,16 +908,42 @@ NESTED_ENTRY CallEHFunclet, _TEXT, NoHandler
// X2 = address of X19 register in CONTEXT record// used to restore the non-volatile registers of CrawlFrame
// X3 = address of the location where the SP of funclet's caller (i.e. this helper) should be saved.
//
- // Save the SP of this function
- str fp, [x3]
+ // Using below prolog instead of PROLOG_SAVE_REG_PAIR_INDEXED fp,lr, -96
+ // is intentional. Above statement would also emit instruction to save
+ // sp in fp. If sp is saved in fp in prolog then it is not expected that fp can change in the body
+ // of method. However, this method needs to be able to change fp before calling funclet.
+ // This is required to access locals in funclet.
+ PROLOG_SAVE_REG_PAIR_INDEXED x29, lr, -96
+
+ // Spill callee saved registers
+ PROLOG_SAVE_REG_PAIR x19, x20, 16
+ PROLOG_SAVE_REG_PAIR x21, x22, 32
+ PROLOG_SAVE_REG_PAIR x23, x24, 48
+ PROLOG_SAVE_REG_PAIR x25, x26, 64
+ PROLOG_SAVE_REG_PAIR x27, x28, 80
+
+ // Save the SP of this function
+ mov x4, sp
+ str x4, [x3]
+
+ ldp x19, x20, [x2, #0]
+ ldp x21, x22, [x2, #16]
+ ldp x23, x24, [x2, #32]
+ ldp x25, x26, [x2, #48]
+ ldp x27, x28, [x2, #64]
ldr fp, [x2, #80] // offset of fp in CONTEXT relative to X19
// Invoke the funclet
blr x1
nop
- EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, #16
+ EPILOG_RESTORE_REG_PAIR x19, x20, 16
+ EPILOG_RESTORE_REG_PAIR x21, x22, 32
+ EPILOG_RESTORE_REG_PAIR x23, x24, 48
+ EPILOG_RESTORE_REG_PAIR x25, x26, 64
+ EPILOG_RESTORE_REG_PAIR x27, x28, 80
+ EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 96
EPILOG_RETURN
NESTED_END CallEHFunclet, _TEXT
@@ -767,7 +952,7 @@ NESTED_END CallEHFunclet, _TEXT
// frame pointer for accessing the locals in the parent method.
NESTED_ENTRY CallEHFilterFunclet, _TEXT, NoHandler
- PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, #-16
+ PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -16
// On entry:
//
@@ -781,7 +966,7 @@ NESTED_ENTRY CallEHFilterFunclet, _TEXT, NoHandler
// Invoke the filter funclet
blr x2
- EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, #16
+ EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 16
EPILOG_RETURN
NESTED_END CallEHFilterFunclet, _TEXT
@@ -800,7 +985,7 @@ NESTED_END CallEHFilterFunclet, _TEXT
// IN: lr: original IP before redirect
//
- PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, #-16
+ PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -16
PROLOG_STACK_ALLOC FaultingExceptionFrame_StackAlloc
// At this point, the stack maybe misaligned if the thread abort was asynchronously
@@ -833,49 +1018,143 @@ NESTED_END CallEHFilterFunclet, _TEXT
// ------------------------------------------------------------------
+// ResolveWorkerChainLookupAsmStub
+//
+// This method will perform a quick chained lookup of the entry if the
+// initial cache lookup fails.
+//
+// On Entry:
+// x9 contains the pointer to the current ResolveCacheElem
+// x11 contains the address of the indirection (and the flags in the low two bits)
+// x12 contains our contract the DispatchToken
+// Must be preserved:
+// x0 contains the instance object ref that we are making an interface call on
+// x9 Must point to a ResolveCacheElem [For Sanity]
+// [x1-x7] contains any additional register arguments for the interface method
+//
+// Loaded from x0
+// x13 contains our type the MethodTable (from object ref in x0)
//
-// Helpers for async (NullRef, AccessViolation) exceptions
+// On Exit:
+// x0, [x1-x7] arguments for the interface implementation target
+//
+// On Exit (to ResolveWorkerAsmStub):
+// x11 contains the address of the indirection and the flags in the low two bits.
+// x12 contains our contract (DispatchToken)
+// x16,x17 will be trashed
//
-NESTED_ENTRY NakedThrowHelper2, _TEXT ,FixContextHandler
- PROLOG_SAVE_REG_PAIR_INDEXED fp,lr, #-16
+#define BACKPATCH_FLAG 1
+#define PROMOTE_CHAIN_FLAG 2
- // On entry:
- //
- // X0 = Address of FaultingExceptionFrame
- bl C_FUNC(LinkFrameAndThrow)
+NESTED_ENTRY ResolveWorkerChainLookupAsmStub, _TEXT, NoHandler
+
+ tst x11, #BACKPATCH_FLAG // First we check if x11 has the BACKPATCH_FLAG set
+ bne LOCAL_LABEL(Fail) // If the BACKPATCH_FLAGS is set we will go directly to the ResolveWorkerAsmStub
- // Target should not return.
- EMIT_BREAKPOINT
+ ldr x13, [x0] // retrieve the MethodTable from the object ref in x0
+LOCAL_LABEL(MainLoop):
+ ldr x9, [x9, #ResolveCacheElem__pNext] // x9 <= the next entry in the chain
+ cmp x9, #0
+ beq LOCAL_LABEL(Fail)
-NESTED_END NakedThrowHelper2, _TEXT
+ ldp x16, x17, [x9]
+ cmp x16, x13 // compare our MT with the one in the ResolveCacheElem
+ bne LOCAL_LABEL(MainLoop)
-GenerateRedirectedStubWithFrame NakedThrowHelper, NakedThrowHelper2
+ cmp x17, x12 // compare our DispatchToken with one in the ResolveCacheElem
+ bne LOCAL_LABEL(MainLoop)
+
+LOCAL_LABEL(Success):
+ PREPARE_EXTERNAL_VAR g_dispatch_cache_chain_success_counter, x13
+ ldr x16, [x13]
+ subs x16, x16, #1
+ str x16, [x13]
+ blt LOCAL_LABEL(Promote)
+
+ ldr x16, [x9, #ResolveCacheElem__target] // get the ImplTarget
+ br x16 // branch to interface implemenation target
+
+LOCAL_LABEL(Promote):
+ // Move this entry to head postion of the chain
+ mov x16, #256
+ str x16, [x13] // be quick to reset the counter so we don't get a bunch of contending threads
+ orr x11, x11, #PROMOTE_CHAIN_FLAG // set PROMOTE_CHAIN_FLAG
+
+LOCAL_LABEL(Fail):
+ b ResolveWorkerAsmStub // call the ResolveWorkerAsmStub method to transition into the VM
+
+NESTED_END ResolveWorkerChainLookupAsmStub, _TEXT
+
+// ------------------------------------------------------------------
+// void ResolveWorkerAsmStub(args in regs x0-x7 & stack and possibly retbuf arg in x8, x11:IndirectionCellAndFlags, x12:DispatchToken)
+//
+// The stub dispatch thunk which transfers control to VSD_ResolveWorker.
+NESTED_ENTRY ResolveWorkerAsmStub, _TEXT, NoHandler
+
+ PROLOG_WITH_TRANSITION_BLOCK
+
+ add x0, sp, #__PWTB_TransitionBlock // pTransitionBlock
+ and x1, x11, #-4 // Indirection cell
+ mov x2, x12 // DispatchToken
+ and x3, x11, #3 // flag
+ bl VSD_ResolveWorker
+ mov x9, x0
+
+ EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
+
+ EPILOG_BRANCH_REG x9
+
+NESTED_END ResolveWorkerAsmStub, _TEXT
#ifdef FEATURE_READYTORUN
NESTED_ENTRY DelayLoad_MethodCall_FakeProlog, _TEXT, NoHandler
DelayLoad_MethodCall:
.global DelayLoad_MethodCall
+ PROLOG_WITH_TRANSITION_BLOCK
+
+ add x0, sp, #__PWTB_TransitionBlock // pTransitionBlock
+ mov x1, x11 // Indirection cell
+ mov x2, x9 // sectionIndex
+ mov x3, x10 // Module*
+ bl ExternalMethodFixupWorker
+ mov x12, x0
+
+ EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
+ // Share patch label
+ b ExternalMethodFixupPatchLabel
- EMIT_BREAKPOINT
NESTED_END DelayLoad_MethodCall_FakeProlog, _TEXT
.macro DynamicHelper frameFlags, suffix
- NESTED_ENTRY DelayLoad_Helper\suffix\()_FakeProlog, _TEXT, NoHandler
+NESTED_ENTRY DelayLoad_Helper\suffix\()_FakeProlog, _TEXT, NoHandler
DelayLoad_Helper\suffix:
- .global DelayLoad_Helper\suffix
+ .global DelayLoad_Helper\suffix
- EMIT_BREAKPOINT
+ PROLOG_WITH_TRANSITION_BLOCK
+
+ add x0, sp, #__PWTB_TransitionBlock // pTransitionBlock
+ mov x1, x11 // Indirection cell
+ mov x2, x9 // sectionIndex
+ mov x3, x10 // Module*
+ mov x4, \frameFlags
+ bl DynamicHelperWorker
+ cbnz x0, LOCAL_LABEL(FakeProlog\suffix\()_0)
+ ldr x0, [sp, #__PWTB_ArgumentRegisters]
+ EPILOG_WITH_TRANSITION_BLOCK_RETURN
+LOCAL_LABEL(FakeProlog\suffix\()_0):
+ mov x12, x0
+ EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
+ EPILOG_BRANCH_REG x12
- NESTED_END DelayLoad_Helper\suffix\()_FakeProlog, _TEXT
+NESTED_END DelayLoad_Helper\suffix\()_FakeProlog, _TEXT
.endm
DynamicHelper DynamicHelperFrameFlags_Default
DynamicHelper DynamicHelperFrameFlags_ObjectArg, _Obj
DynamicHelper DynamicHelperFrameFlags_ObjectArg | DynamicHelperFrameFlags_ObjectArg2, _ObjObj
-
#endif
#ifdef FEATURE_PREJIT
@@ -891,7 +1170,7 @@ NESTED_ENTRY StubDispatchFixupStub, _TEXT, NoHandler
and x1, x11, #-4 // Indirection cell
mov x2, #0 // sectionIndex
mov x3, #0 // pModule
- bl StubDispatchFixupWorker
+ bl C_FUNC(StubDispatchFixupWorker)
mov x9, x0
EPILOG_WITH_TRANSITION_BLOCK_TAILCALL
@@ -900,3 +1179,36 @@ NESTED_ENTRY StubDispatchFixupStub, _TEXT, NoHandler
NESTED_END StubDispatchFixupStub, _TEXT
#endif
+
+#ifdef FEATURE_COMINTEROP
+
+// Function used by COM interop to get floating point return value (since it's not in the same
+// register(s) as non-floating point values).
+//
+// On entry//
+// x0 : size of the FP result (4 or 8 bytes)
+// x1 : pointer to 64-bit buffer to receive result
+//
+// On exit:
+// buffer pointed to by x1 on entry contains the float or double argument as appropriate
+//
+ LEAF_ENTRY getFPReturn
+ str d0, [x1]
+ LEAF_END
+
+// ------------------------------------------------------------------
+// Function used by COM interop to set floating point return value (since it's not in the same
+// register(s) as non-floating point values).
+//
+// On entry:
+// x0 : size of the FP result (4 or 8 bytes)
+// x1 : 32-bit or 64-bit FP result
+//
+// On exit:
+// s0 : float result if x0 == 4
+// d0 : double result if x0 == 8
+//
+ LEAF_ENTRY setFPReturn
+ fmov d0, x1
+ LEAF_END
+#endif
diff --git a/src/vm/arm64/asmhelpers.asm b/src/vm/arm64/asmhelpers.asm
index 2fc6a6a0c1..e8b16ded6a 100644
--- a/src/vm/arm64/asmhelpers.asm
+++ b/src/vm/arm64/asmhelpers.asm
@@ -159,6 +159,7 @@
RestoreRegMS 26, X26
RestoreRegMS 27, X27
RestoreRegMS 28, X28
+ RestoreRegMS 29, X29
Done
; Its imperative that the return value of HelperMethodFrameRestoreState is zero
@@ -991,16 +992,6 @@ UM2MThunk_WrapperHelper_RegArgumentsSetup
; This helper enables us to call into a funclet after restoring Fp register
NESTED_ENTRY CallEHFunclet
-
- ; Using below prolog instead of PROLOG_SAVE_REG_PAIR fp,lr, #-16!
- ; is intentional. Above statement would also emit instruction to save
- ; sp in fp. If sp is saved in fp in prolog then it is not expected that fp can change in the body
- ; of method. However, this method needs to be able to change fp before calling funclet.
- ; This is required to access locals in funclet.
- PROLOG_SAVE_REG_PAIR x19,x20, #-16!
- PROLOG_SAVE_REG fp, #0
- PROLOG_SAVE_REG lr, #8
-
; On entry:
;
; X0 = throwable
@@ -1008,17 +999,42 @@ UM2MThunk_WrapperHelper_RegArgumentsSetup
; X2 = address of X19 register in CONTEXT record; used to restore the non-volatile registers of CrawlFrame
; X3 = address of the location where the SP of funclet's caller (i.e. this helper) should be saved.
;
+
+ ; Using below prolog instead of PROLOG_SAVE_REG_PAIR fp,lr, #-16!
+ ; is intentional. Above statement would also emit instruction to save
+ ; sp in fp. If sp is saved in fp in prolog then it is not expected that fp can change in the body
+ ; of method. However, this method needs to be able to change fp before calling funclet.
+ ; This is required to access locals in funclet.
+ PROLOG_SAVE_REG_PAIR_NO_FP fp,lr, #-96!
+
+ ; Spill callee saved registers
+ PROLOG_SAVE_REG_PAIR x19, x20, 16
+ PROLOG_SAVE_REG_PAIR x21, x22, 32
+ PROLOG_SAVE_REG_PAIR x23, x24, 48
+ PROLOG_SAVE_REG_PAIR x25, x26, 64
+ PROLOG_SAVE_REG_PAIR x27, x28, 80
+
; Save the SP of this function. We cannot store SP directly.
mov fp, sp
str fp, [x3]
+ ldp x19, x20, [x2, #0]
+ ldp x21, x22, [x2, #16]
+ ldp x23, x24, [x2, #32]
+ ldp x25, x26, [x2, #48]
+ ldp x27, x28, [x2, #64]
ldr fp, [x2, #80] ; offset of fp in CONTEXT relative to X19
; Invoke the funclet
blr x1
nop
- EPILOG_RESTORE_REG_PAIR fp, lr, #16!
+ EPILOG_RESTORE_REG_PAIR x19, x20, 16
+ EPILOG_RESTORE_REG_PAIR x21, x22, 32
+ EPILOG_RESTORE_REG_PAIR x23, x24, 48
+ EPILOG_RESTORE_REG_PAIR x25, x26, 64
+ EPILOG_RESTORE_REG_PAIR x27, x28, 80
+ EPILOG_RESTORE_REG_PAIR fp, lr, #96!
EPILOG_RETURN
NESTED_END CallEHFunclet
@@ -1311,4 +1327,4 @@ Fail
#endif
; Must be at very end of file
- END \ No newline at end of file
+ END
diff --git a/src/vm/arm64/calldescrworkerarm64.S b/src/vm/arm64/calldescrworkerarm64.S
index 803b94998d..5bcad2f9c0 100644
--- a/src/vm/arm64/calldescrworkerarm64.S
+++ b/src/vm/arm64/calldescrworkerarm64.S
@@ -11,9 +11,9 @@
//-----------------------------------------------------------------------------
//void CallDescrWorkerInternal(CallDescrData * pCallDescrData);
-NESTED_ENTRY CallDescrWorkerInternal, _TEXT, UnhandledExceptionHandlerUnix
- PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, #-32
- PROLOG_SAVE_REG x19, #16 //the stack slot at sp+24 is empty for 16 byte alligment
+NESTED_ENTRY CallDescrWorkerInternal, _TEXT, NoHandler
+ PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -32
+ PROLOG_SAVE_REG x19, 16 //the stack slot at sp+24 is empty for 16 byte alligment
mov x19, x0 // save pCallDescrData in x19
@@ -44,29 +44,29 @@ LOCAL_LABEL(stackloop):
bne LOCAL_LABEL(stackloop)
LOCAL_LABEL(donestack):
- // If FP arguments are supplied in registers (x8 != NULL) then initialize all of them from the pointer
+ // If FP arguments are supplied in registers (x9 != NULL) then initialize all of them from the pointer
// given in x8.
- ldr x8, [x19,#CallDescrData__pFloatArgumentRegisters]
- cbz x8, LOCAL_LABEL(NoFloatingPoint)
- ldp d0, d1, [x8]
- ldp d2, d3, [x8, #16]
- ldp d4, d5, [x8, #32]
- ldp d6, d7, [x8, #48]
+ ldr x9, [x19,#CallDescrData__pFloatArgumentRegisters]
+ cbz x9, LOCAL_LABEL(NoFloatingPoint)
+ ldp d0, d1, [x9]
+ ldp d2, d3, [x9, #16]
+ ldp d4, d5, [x9, #32]
+ ldp d6, d7, [x9, #48]
LOCAL_LABEL(NoFloatingPoint):
// Copy [pArgumentRegisters, ..., pArgumentRegisters + 56]
// into x0, ..., x7
- ldr x8, [x19,#CallDescrData__pArgumentRegisters]
- ldp x0, x1, [x8]
- ldp x2, x3, [x8, #16]
- ldp x4, x5, [x8, #32]
- ldp x6, x7, [x8, #48]
+ ldr x9, [x19,#CallDescrData__pArgumentRegisters]
+ ldp x0, x1, [x9]
+ ldp x2, x3, [x9, #16]
+ ldp x4, x5, [x9, #32]
+ ldp x6, x7, [x9, #48]
+ ldr x8, [x9, #64]
- // ARM64TODO: => see if anything special needs to be done for remoting
// call pTarget
- ldr x8, [x19,#CallDescrData__pTarget]
- blr x8
+ ldr x9, [x19,#CallDescrData__pTarget]
+ blr x9
ldr w3, [x19,#CallDescrData__fpReturnSize]
@@ -110,7 +110,7 @@ LOCAL_LABEL(NoDoubleHFAReturn):
LOCAL_LABEL(IntReturn):
// Save return value into retbuf for int
- str x0, [x19, #(CallDescrData__returnValue + 0)]
+ stp x0, x1, [x19, #(CallDescrData__returnValue + 0)]
LOCAL_LABEL(ReturnDone):
@@ -122,7 +122,7 @@ LOCAL_LABEL(ReturnDone):
#endif
EPILOG_STACK_RESTORE
- EPILOG_RESTORE_REG x19, #16 //the stack slot at sp+24 is empty for 16 byte alligment
- EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, #32
+ EPILOG_RESTORE_REG x19, 16 //the stack slot at sp+24 is empty for 16 byte alligment
+ EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 32
EPILOG_RETURN
NESTED_END CallDescrWorkerInternal, _TEXT
diff --git a/src/vm/arm64/cgencpu.h b/src/vm/arm64/cgencpu.h
index be3e34d35c..d8bbcf7d1d 100644
--- a/src/vm/arm64/cgencpu.h
+++ b/src/vm/arm64/cgencpu.h
@@ -14,7 +14,9 @@
#define INSTRFMT_K64
#include <stublink.h>
+#ifndef FEATURE_PAL
#define USE_REDIRECT_FOR_GCSTRESS
+#endif // FEATURE_PAL
EXTERN_C void getFPReturn(int fpSize, INT64 *pRetVal);
EXTERN_C void setFPReturn(int fpSize, INT64 retVal);
@@ -512,6 +514,16 @@ struct HijackArgs
};
size_t ReturnValue[2];
};
+ union
+ {
+ struct {
+ DWORD64 D0;
+ DWORD64 D1;
+ DWORD64 D2;
+ DWORD64 D3;
+ };
+ size_t FPReturnValue[4];
+ };
};
EXTERN_C VOID STDCALL PrecodeFixupThunk();
diff --git a/src/vm/arm64/gmscpu.h b/src/vm/arm64/gmscpu.h
index e95ef63d7d..7785daf219 100644
--- a/src/vm/arm64/gmscpu.h
+++ b/src/vm/arm64/gmscpu.h
@@ -56,25 +56,34 @@ inline void LazyMachState::setLazyStateFromUnwind(MachState* copy)
_sp = copy->_sp;
_pc = copy->_pc;
- // Now copy the preserved register pointers. Note that some of the pointers could be
- // pointing to copy->captureX19_X29[]. If that is case then while copying to destination
- // ensure that they point to corresponding element in captureX19_X29[] of destination.
- ULONG64* srcLowerBound = &copy->captureX19_X29[0];
- ULONG64* srcUpperBound = (ULONG64*)((BYTE*)copy + offsetof(MachState, ptrX19_X29));
+ // Capture* has already been set, so there is no need to touch it
+ // loop over the nonvolatile context pointers and make
+ // sure to properly copy interior pointers into the
+ // new struct
- for (int i = 0; i<NUM_NONVOLATILE_CONTEXT_POINTERS; i++)
+ PULONG64* pSrc = (PULONG64 *)&copy->ptrX19_X29;
+ PULONG64* pDst = (PULONG64 *)&this->ptrX19_X29;
+
+ const PULONG64 LowerBoundDst = (PULONG64) this;
+ const PULONG64 LowerBoundSrc = (PULONG64) copy;
+
+ const PULONG64 UpperBoundSrc = (PULONG64) ((BYTE*)LowerBoundSrc + sizeof(*copy));
+
+ for (int i = 0; i < NUM_NONVOLATILE_CONTEXT_POINTERS; i++)
{
- if (copy->ptrX19_X29[i] >= srcLowerBound && copy->ptrX19_X29[i] < srcUpperBound)
- {
- ptrX19_X29[i] = (PTR_ULONG64)((BYTE*)copy->ptrX19_X29[i] - (BYTE*)srcLowerBound + (BYTE*)captureX19_X29);
- }
- else
+ PULONG64 valueSrc = *pSrc++;
+
+ if ((LowerBoundSrc <= valueSrc) && (valueSrc < UpperBoundSrc))
{
- ptrX19_X29[i] = copy->ptrX19_X29[i];
+ // make any pointer interior to 'src' interior to 'dst'
+ valueSrc = (PULONG64)((BYTE*)valueSrc - (BYTE*)LowerBoundSrc + (BYTE*)LowerBoundDst);
}
+
+ *pDst++ = valueSrc;
}
+
// this has to be last because we depend on write ordering to
// synchronize the race implicit in updating this struct
VolatileStore(&_isValid, TRUE);
diff --git a/src/vm/arm64/pinvokestubs.S b/src/vm/arm64/pinvokestubs.S
index f6c33ba4c2..c87e8004f0 100644
--- a/src/vm/arm64/pinvokestubs.S
+++ b/src/vm/arm64/pinvokestubs.S
@@ -21,44 +21,28 @@
// $VASigCookieReg : register which contains the VASigCookie
// $SaveFPArgs : "Yes" or "No" . For varidic functions FP Args are not present in FP regs
// So need not save FP Args registers for vararg Pinvoke
-.macro PINVOKE_STUB FuncPrefix,VASigCookieReg,HiddenArg,SaveFPArgs
+.macro PINVOKE_STUB __PInvokeStubFuncName,__PInvokeGenStubFuncName,__PInvokeStubWorkerName,VASigCookieReg,HiddenArg,SaveFPArgs
-#if NOTYET
- GBLS __PInvokeStubFuncName
- GBLS __PInvokeGenStubFuncName
- GBLS __PInvokeStubWorkerName
- IF "\FuncPrefix" == "GenericPInvokeCalli"
-__PInvokeStubFuncName SETS "\FuncPrefix":CC:"Helper"
- ELSE
-__PInvokeStubFuncName SETS "\FuncPrefix":CC:"Stub"
- ENDIF
-__PInvokeGenStubFuncName SETS "\FuncPrefix":CC:"GenILStub"
-__PInvokeStubWorkerName SETS "\FuncPrefix":CC:"StubWorker"
-
- IF "\VASigCookieReg" == "x1"
-__PInvokeStubFuncName SETS "\__PInvokeStubFuncName":CC:"_RetBuffArg"
-__PInvokeGenStubFuncName SETS "\__PInvokeGenStubFuncName":CC:"_RetBuffArg"
- ENDIF
-
- NESTED_ENTRY \__PInvokeStubFuncName
+ NESTED_ENTRY \__PInvokeStubFuncName, _TEXT, NoHandler
// get the stub
ldr x9, [\VASigCookieReg, #VASigCookie__pNDirectILStub]
// if null goto stub generation
- cbz x9, %0
+ cbz x9, LOCAL_LABEL(\__PInvokeStubFuncName\()_0)
EPILOG_BRANCH_REG x9
-0
+LOCAL_LABEL(\__PInvokeStubFuncName\()_0):
+
EPILOG_BRANCH \__PInvokeGenStubFuncName
- NESTED_END
+ NESTED_END \__PInvokeStubFuncName, _TEXT
- NESTED_ENTRY \__PInvokeGenStubFuncName
+ NESTED_ENTRY \__PInvokeGenStubFuncName, _TEXT, NoHandler
PROLOG_WITH_TRANSITION_BLOCK 0, \SaveFPArgs
@@ -66,9 +50,9 @@ __PInvokeGenStubFuncName SETS "\__PInvokeGenStubFuncName":CC:"_RetBuffArg"
mov x2, \HiddenArg
// x1 = VaSigCookie
- IF "\VASigCookieReg" != "x1"
+ .ifnc \VASigCookieReg, x1
mov x1, \VASigCookieReg
- ENDIF
+ .endif
// x0 = pTransitionBlock
add x0, sp, #__PWTB_TransitionBlock
@@ -86,10 +70,7 @@ __PInvokeGenStubFuncName SETS "\__PInvokeGenStubFuncName":CC:"_RetBuffArg"
EPILOG_BRANCH \__PInvokeStubFuncName
- NESTED_END
-#else
- EMIT_BREAKPOINT
-#endif
+ NESTED_END \__PInvokeGenStubFuncName, _TEXT
.endm
// ------------------------------------------------------------------
@@ -100,7 +81,7 @@ __PInvokeGenStubFuncName SETS "\__PInvokeGenStubFuncName":CC:"_RetBuffArg"
// x0 = VASigCookie*
// x12 = MethodDesc *
//
-PINVOKE_STUB VarargPInvoke, x0, x12, 1
+PINVOKE_STUB VarargPInvokeStub, VarargPInvokeGenILStub, VarargPInvokeStubWorker, x0, x12, 0
// ------------------------------------------------------------------
@@ -111,7 +92,7 @@ PINVOKE_STUB VarargPInvoke, x0, x12, 1
// x15 = VASigCookie*
// x14 = Unmanaged target
//
-PINVOKE_STUB GenericPInvokeCalli, x15, x14, 1
+PINVOKE_STUB GenericPInvokeCalliHelper, GenericPInvokeCalliGenILStub, GenericPInvokeCalliStubWorker, x15, x14, 1
// ------------------------------------------------------------------
// VarargPInvokeStub_RetBuffArg & VarargPInvokeGenILStub_RetBuffArg
@@ -121,4 +102,4 @@ PINVOKE_STUB GenericPInvokeCalli, x15, x14, 1
// x1 = VASigCookie*
// x12 = MethodDesc*
//
-PINVOKE_STUB VarargPInvoke, x1, x12, 0
+PINVOKE_STUB VarargPInvokeStub_RetBuffArg, VarargPInvokeGenILStub_RetBuffArg, VarargPInvokeStubWorker, x1, x12, 0
diff --git a/src/vm/arm64/stubs.cpp b/src/vm/arm64/stubs.cpp
index 9c9b6a8a68..f56f6ab625 100644
--- a/src/vm/arm64/stubs.cpp
+++ b/src/vm/arm64/stubs.cpp
@@ -268,6 +268,12 @@ static BYTE gLoadFromLabelIF[sizeof(LoadFromLabelInstructionFormat)];
#endif
+void ClearRegDisplayArgumentAndScratchRegisters(REGDISPLAY * pRD)
+{
+ for (int i=0; i < 18; i++)
+ pRD->volatileCurrContextPointers.X[i] = NULL;
+}
+
#ifndef CROSSGEN_COMPILE
void LazyMachState::unwindLazyState(LazyMachState* baseState,
MachState* unwoundstate,
@@ -371,6 +377,20 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState,
}
} while (true);
+#ifdef FEATURE_PAL
+ unwoundstate->captureX19_X29[0] = context.X19;
+ unwoundstate->captureX19_X29[1] = context.X20;
+ unwoundstate->captureX19_X29[2] = context.X21;
+ unwoundstate->captureX19_X29[3] = context.X22;
+ unwoundstate->captureX19_X29[4] = context.X23;
+ unwoundstate->captureX19_X29[5] = context.X24;
+ unwoundstate->captureX19_X29[6] = context.X25;
+ unwoundstate->captureX19_X29[7] = context.X26;
+ unwoundstate->captureX19_X29[8] = context.X27;
+ unwoundstate->captureX19_X29[9] = context.X28;
+ unwoundstate->captureX19_X29[10] = context.Fp;
+#endif
+
#ifdef DACCESS_COMPILE
// For DAC builds, we update the registers directly since we dont have context pointers
unwoundstate->captureX19_X29[0] = context.X19;
@@ -450,6 +470,20 @@ void HelperMethodFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
pRD->pCurrentContext->X28 = (DWORD64)(pUnwoundState->captureX19_X29[9]);
pRD->pCurrentContext->Fp = (DWORD64)(pUnwoundState->captureX19_X29[10]);
pRD->pCurrentContext->Lr = NULL; // Unwind again to get Caller's PC
+
+ pRD->pCurrentContextPointers->X19 = pUnwoundState->ptrX19_X29[0];
+ pRD->pCurrentContextPointers->X20 = pUnwoundState->ptrX19_X29[1];
+ pRD->pCurrentContextPointers->X21 = pUnwoundState->ptrX19_X29[2];
+ pRD->pCurrentContextPointers->X22 = pUnwoundState->ptrX19_X29[3];
+ pRD->pCurrentContextPointers->X23 = pUnwoundState->ptrX19_X29[4];
+ pRD->pCurrentContextPointers->X24 = pUnwoundState->ptrX19_X29[5];
+ pRD->pCurrentContextPointers->X25 = pUnwoundState->ptrX19_X29[6];
+ pRD->pCurrentContextPointers->X26 = pUnwoundState->ptrX19_X29[7];
+ pRD->pCurrentContextPointers->X27 = pUnwoundState->ptrX19_X29[8];
+ pRD->pCurrentContextPointers->X28 = pUnwoundState->ptrX19_X29[9];
+ pRD->pCurrentContextPointers->Fp = pUnwoundState->ptrX19_X29[10];
+ pRD->pCurrentContextPointers->Lr = NULL;
+
return;
}
#endif // DACCESS_COMPILE
@@ -462,6 +496,20 @@ void HelperMethodFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
pRD->pCurrentContext->Pc = pRD->ControlPC;
pRD->pCurrentContext->Sp = pRD->SP;
+#ifdef FEATURE_PAL
+ pRD->pCurrentContext->X19 = m_MachState.ptrX19_X29[0] ? *m_MachState.ptrX19_X29[0] : m_MachState.captureX19_X29[0];
+ pRD->pCurrentContext->X20 = m_MachState.ptrX19_X29[1] ? *m_MachState.ptrX19_X29[1] : m_MachState.captureX19_X29[1];
+ pRD->pCurrentContext->X21 = m_MachState.ptrX19_X29[2] ? *m_MachState.ptrX19_X29[2] : m_MachState.captureX19_X29[2];
+ pRD->pCurrentContext->X22 = m_MachState.ptrX19_X29[3] ? *m_MachState.ptrX19_X29[3] : m_MachState.captureX19_X29[3];
+ pRD->pCurrentContext->X23 = m_MachState.ptrX19_X29[4] ? *m_MachState.ptrX19_X29[4] : m_MachState.captureX19_X29[4];
+ pRD->pCurrentContext->X24 = m_MachState.ptrX19_X29[5] ? *m_MachState.ptrX19_X29[5] : m_MachState.captureX19_X29[5];
+ pRD->pCurrentContext->X25 = m_MachState.ptrX19_X29[6] ? *m_MachState.ptrX19_X29[6] : m_MachState.captureX19_X29[6];
+ pRD->pCurrentContext->X26 = m_MachState.ptrX19_X29[7] ? *m_MachState.ptrX19_X29[7] : m_MachState.captureX19_X29[7];
+ pRD->pCurrentContext->X27 = m_MachState.ptrX19_X29[8] ? *m_MachState.ptrX19_X29[8] : m_MachState.captureX19_X29[8];
+ pRD->pCurrentContext->X28 = m_MachState.ptrX19_X29[9] ? *m_MachState.ptrX19_X29[9] : m_MachState.captureX19_X29[9];
+ pRD->pCurrentContext->Fp = m_MachState.ptrX19_X29[10] ? *m_MachState.ptrX19_X29[10] : m_MachState.captureX19_X29[10];
+ pRD->pCurrentContext->Lr = NULL; // Unwind again to get Caller's PC
+#else // FEATURE_PAL
pRD->pCurrentContext->X19 = *m_MachState.ptrX19_X29[0];
pRD->pCurrentContext->X20 = *m_MachState.ptrX19_X29[1];
pRD->pCurrentContext->X21 = *m_MachState.ptrX19_X29[2];
@@ -474,6 +522,7 @@ void HelperMethodFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
pRD->pCurrentContext->X28 = *m_MachState.ptrX19_X29[9];
pRD->pCurrentContext->Fp = *m_MachState.ptrX19_X29[10];
pRD->pCurrentContext->Lr = NULL; // Unwind again to get Caller's PC
+#endif
#if !defined(DACCESS_COMPILE)
pRD->pCurrentContextPointers->X19 = m_MachState.ptrX19_X29[0];
@@ -489,6 +538,8 @@ void HelperMethodFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
pRD->pCurrentContextPointers->Fp = m_MachState.ptrX19_X29[10];
pRD->pCurrentContextPointers->Lr = NULL; // Unwind again to get Caller's PC
#endif
+
+ ClearRegDisplayArgumentAndScratchRegisters(pRD);
}
#endif // CROSSGEN_COMPILE
@@ -759,23 +810,15 @@ void UpdateRegDisplayFromCalleeSavedRegisters(REGDISPLAY * pRD, CalleeSavedRegis
void TransitionFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
{
-
pRD->IsCallerContextValid = FALSE;
pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary.
- // copy the argumetn registers
- ArgumentRegisters *pArgRegs = GetArgumentRegisters();
- for (int i = 0; i < ARGUMENTREGISTERS_SIZE; i++)
-#ifdef __clang__
- *(&pRD->pCurrentContext->X0 + (sizeof(void*)*i)) = pArgRegs->x[i];
-#else
- pRD->pCurrentContext->X[i] = pArgRegs->x[i];
-#endif
-
// copy the callee saved regs
CalleeSavedRegisters *pCalleeSaved = GetCalleeSavedRegisters();
UpdateRegDisplayFromCalleeSavedRegisters(pRD, pCalleeSaved);
+ ClearRegDisplayArgumentAndScratchRegisters(pRD);
+
// copy the control registers
pRD->pCurrentContext->Fp = pCalleeSaved->x29;
pRD->pCurrentContext->Lr = pCalleeSaved->x30;
@@ -786,16 +829,16 @@ void TransitionFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
SyncRegDisplayToCurrentContext(pRD);
LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK TransitionFrame::UpdateRegDisplay(pc:%p, sp:%p)\n", pRD->ControlPC, pRD->SP));
-
-
}
+
#endif
#ifndef CROSSGEN_COMPILE
void TailCallFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
{
+ LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK TailCallFrame::UpdateRegDisplay(pc:%p, sp:%p)\n", pRD->ControlPC, pRD->SP));
_ASSERTE(!"ARM64:NYI");
}
@@ -833,8 +876,12 @@ void FaultingExceptionFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
pRD->pCurrentContextPointers->Fp = (PDWORD64)&m_ctx.Fp;
pRD->pCurrentContextPointers->Lr = (PDWORD64)&m_ctx.Lr;
+ ClearRegDisplayArgumentAndScratchRegisters(pRD);
+
pRD->IsCallerContextValid = FALSE;
pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary.
+
+ LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK FaultingExceptionFrame::UpdateRegDisplay(pc:%p, sp:%p)\n", pRD->ControlPC, pRD->SP));
}
void InlinedCallFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
@@ -858,22 +905,38 @@ void InlinedCallFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
return;
}
- // reset pContext; it's only valid for active (top-most) frame
- pRD->pContext = NULL;
+ pRD->IsCallerContextValid = FALSE;
+ pRD->IsCallerSPValid = FALSE;
+
+ pRD->pCurrentContext->Pc = *(DWORD64 *)&m_pCallerReturnAddress;
+ pRD->pCurrentContext->Sp = *(DWORD64 *)&m_pCallSiteSP;
+ pRD->pCurrentContext->Fp = *(DWORD64 *)&m_pCalleeSavedFP;
+
+ pRD->pCurrentContextPointers->X19 = NULL;
+ pRD->pCurrentContextPointers->X20 = NULL;
+ pRD->pCurrentContextPointers->X21 = NULL;
+ pRD->pCurrentContextPointers->X22 = NULL;
+ pRD->pCurrentContextPointers->X23 = NULL;
+ pRD->pCurrentContextPointers->X24 = NULL;
+ pRD->pCurrentContextPointers->X25 = NULL;
+ pRD->pCurrentContextPointers->X26 = NULL;
+ pRD->pCurrentContextPointers->X27 = NULL;
+ pRD->pCurrentContextPointers->X28 = NULL;
pRD->ControlPC = m_pCallerReturnAddress;
pRD->SP = (DWORD) dac_cast<TADDR>(m_pCallSiteSP);
- pRD->IsCallerContextValid = FALSE;
- pRD->IsCallerSPValid = FALSE;
+ // reset pContext; it's only valid for active (top-most) frame
+ pRD->pContext = NULL;
+
+ ClearRegDisplayArgumentAndScratchRegisters(pRD);
- pRD->pCurrentContext->Pc = m_pCallerReturnAddress;
- pRD->pCurrentContext->Sp = pRD->SP;
// Update the frame pointer in the current context.
- pRD->pCurrentContext->Fp = m_pCalleeSavedFP;
pRD->pCurrentContextPointers->Fp = &m_pCalleeSavedFP;
+ LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK InlinedCallFrame::UpdateRegDisplay(pc:%p, sp:%p)\n", pRD->ControlPC, pRD->SP));
+
RETURN;
}
@@ -919,6 +982,8 @@ void ResumableFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
pRD->IsCallerContextValid = FALSE;
pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary.
+ LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK ResumableFrame::UpdateRegDisplay(pc:%p, sp:%p)\n", pRD->ControlPC, pRD->SP));
+
RETURN;
}
@@ -965,6 +1030,8 @@ void HijackFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
pRD->pCurrentContextPointers->Lr = NULL;
SyncRegDisplayToCurrentContext(pRD);
+
+ LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK HijackFrame::UpdateRegDisplay(pc:%p, sp:%p)\n", pRD->ControlPC, pRD->SP));
}
#endif // FEATURE_HIJACK
diff --git a/src/vm/assembly.cpp b/src/vm/assembly.cpp
index 2db3e23fff..75430644c3 100644
--- a/src/vm/assembly.cpp
+++ b/src/vm/assembly.cpp
@@ -22,16 +22,7 @@
#include "perfcounters.h"
#include "assemblyname.hpp"
-#ifdef FEATURE_FUSION
-#include "fusion.h"
-#include "assemblysink.h"
-#include "ngenoptout.h"
-#endif
-#if !defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
-#include "assemblyusagelogmanager.h"
-#include "policy.h"
-#endif
#include "eeprofinterfaces.h"
#include "reflectclasswriter.h"
@@ -53,29 +44,15 @@
#endif
#include "appdomainnative.hpp"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#include "appdomainhelper.h"
-#endif
#include "customattribute.h"
#include "winnls.h"
-#include "constrainedexecutionregion.h"
#include "caparser.h"
#include "../md/compiler/custattr.h"
#include "mdaassistants.h"
#include "peimagelayout.inl"
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-#include <shlobj.h>
-#include "eventmsg.h"
-#endif
-
-#ifdef FEATURE_TRACELOGGING
-#include "clrtracelogging.h"
-#endif // FEATURE_TRACELOGGING
-
// Define these macro's to do strict validation for jit lock and class init entry leaks.
// This defines determine if the asserts that verify for these leaks are defined or not.
@@ -129,10 +106,6 @@ enum ReasonForNotSharing
//----------------------------------------------------------------------------------------------
Assembly::Assembly(BaseDomain *pDomain, PEAssembly* pFile, DebuggerAssemblyControlFlags debuggerFlags, BOOL fIsCollectible) :
m_FreeFlag(0),
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- m_pAllowedFiles(NULL),
- m_crstAllowedFiles(CrstAllowedFiles),
-#endif
m_pDomain(pDomain),
m_pClassLoader(NULL),
m_pEntryPoint(NULL),
@@ -161,9 +134,6 @@ Assembly::Assembly(BaseDomain *pDomain, PEAssembly* pFile, DebuggerAssemblyContr
m_fIsDomainNeutral(pDomain == SharedDomain::GetDomain()),
#ifdef FEATURE_LOADER_OPTIMIZATION
m_bMissingDependenciesCheckDone(FALSE),
-#ifdef FEATURE_FUSION
- m_pBindingClosure(NULL),
-#endif
#endif // FEATURE_LOADER_OPTIMIZATION
m_debuggerFlags(debuggerFlags),
m_fTerminated(FALSE),
@@ -171,8 +141,8 @@ Assembly::Assembly(BaseDomain *pDomain, PEAssembly* pFile, DebuggerAssemblyContr
#ifdef FEATURE_COMINTEROP
, m_InteropAttributeStatus(INTEROP_ATTRIBUTE_UNSET)
#endif
-#ifndef FEATURE_CORECLR
- , m_fSupportsAutoNGen(FALSE)
+#ifdef FEATURE_PREJIT
+ , m_isInstrumentedStatus(IS_INSTRUMENTED_UNSET)
#endif
{
STANDARD_VM_CONTRACT;
@@ -183,42 +153,6 @@ Assembly::Assembly(BaseDomain *pDomain, PEAssembly* pFile, DebuggerAssemblyContr
#define REFEMIT_MANIFEST_MODULE_NAME W("RefEmit_InMemoryManifestModule")
-#ifdef FEATURE_TRACELOGGING
-//----------------------------------------------------------------------------------------------
-// Reads and logs the TargetFramework attribute for an assembly. For example: [assembly: TargetFramework(".NETFramework,Version=v4.0")]
-//----------------------------------------------------------------------------------------------
-void Assembly::TelemetryLogTargetFrameworkAttribute()
-{
- const BYTE *pbAttr; // Custom attribute data as a BYTE*.
- ULONG cbAttr; // Size of custom attribute data.
- HRESULT hr = GetManifestImport()->GetCustomAttributeByName(GetManifestToken(), TARGET_FRAMEWORK_TYPE, (const void**)&pbAttr, &cbAttr);
- bool dataLogged = false;
- if (hr == S_OK)
- {
- CustomAttributeParser cap(pbAttr, cbAttr);
- LPCUTF8 lpTargetFramework;
- ULONG cbTargetFramework;
- if (SUCCEEDED(cap.ValidateProlog()))
- {
- if (SUCCEEDED(cap.GetString(&lpTargetFramework, &cbTargetFramework)))
- {
- if ((lpTargetFramework != NULL) && (cbTargetFramework != 0))
- {
- SString s(SString::Utf8, lpTargetFramework, cbTargetFramework);
- CLRTraceLog::Logger::LogTargetFrameworkAttribute(s.GetUnicode(), GetSimpleName());
- dataLogged = true;
- }
- }
- }
- }
- if (!dataLogged)
- {
- CLRTraceLog::Logger::LogTargetFrameworkAttribute(L"", GetSimpleName());
- }
-}
-
-#endif // FEATURE_TRACELOGGING
-
//----------------------------------------------------------------------------------------------
// Does most Assembly initialization tasks. It can assume the ctor has already run
// and the assembly is safely destructable. Whether this function throws or succeeds,
@@ -264,9 +198,6 @@ void Assembly::Init(AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocat
m_pSharedSecurityDesc = Security::CreateSharedSecurityDescriptor(this);
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- m_pAllowedFiles = new EEUtf8StringHashTable();
-#endif
COUNTER_ONLY(GetPerfCounters().m_Loading.cAssemblies++);
@@ -285,20 +216,6 @@ void Assembly::Init(AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocat
if (!m_pManifest->IsReadyToRun())
CacheManifestExportedTypes(pamTracker);
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- GenerateBreadcrumbForServicing();
-
- m_fSupportsAutoNGen = SupportsAutoNGenWorker();
-
- ReportAssemblyUse();
-#endif
-
-#ifdef FEATURE_TRACELOGGING
-
- TelemetryLogTargetFrameworkAttribute();
-
-#endif // FEATURE_TRACELOGGING
-
// Check for the assemblies that contain SIMD Vector types.
// If we encounter a non-trusted assembly with these names, we will simply not recognize any of its
@@ -380,16 +297,6 @@ Assembly::~Assembly()
if (m_pwStrongNameKeyContainer && (m_FreeFlag & FREE_KEY_CONTAINER))
delete[] m_pwStrongNameKeyContainer;
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- if (m_pAllowedFiles)
- delete(m_pAllowedFiles);
-#endif
-#ifdef FEATURE_FUSION
- if (m_pBindingClosure)
- {
- m_pBindingClosure->Release();
- }
-#endif
if (IsDynamic()) {
if (m_pOnDiskManifest)
// clear the on disk manifest if it is not cleared yet.
@@ -757,7 +664,6 @@ Assembly *Assembly::CreateDynamic(AppDomain *pDomain, CreateDynamicAssemblyArgs
&ma));
pFile = PEAssembly::Create(pCallerAssembly->GetManifestFile(), pAssemblyEmit, args->access & ASSEMBLY_ACCESS_REFLECTION_ONLY);
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
// Dynamically created modules (aka RefEmit assemblies) do not have a LoadContext associated with them since they are not bound
// using an actual binder. As a result, we will assume the same binding/loadcontext information for the dynamic assembly as its
// caller/creator to ensure that any assembly loads triggered by the dynamic assembly are resolved using the intended load context.
@@ -803,90 +709,21 @@ Assembly *Assembly::CreateDynamic(AppDomain *pDomain, CreateDynamicAssemblyArgs
// Set it as the fallback load context binder for the dynamic assembly being created
pFile->SetFallbackLoadContextBinder(pFallbackLoadContextBinder);
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
}
AssemblyLoadSecurity loadSecurity;
-#ifndef FEATURE_CORECLR
- DWORD dwSpecialFlags = 0xFFFFFFFF;
-
- // Don't bother with setting up permissions if this isn't allowed to run
- // This doesn't apply in CoreCLR because you cannot specify evidence when creating a dynamic assembly
- if ((args->identity != NULL) &&
- (args->access & ASSEMBLY_ACCESS_RUN))
- {
- loadSecurity.m_pAdditionalEvidence = &args->identity;
- }
- else
- {
- if (pCallerAssembly != NULL) // can be null if caller is interop
- {
- if (args->securityContextSource == kCurrentAssembly)
- {
- IAssemblySecurityDescriptor *pCallerSecDesc = pCallerAssembly->GetSecurityDescriptor(pCallersDomain);
- gc.granted = pCallerSecDesc->GetGrantedPermissionSet(&(gc.denied));
- dwSpecialFlags = pCallerSecDesc->GetSpecialFlags();
- }
- else
- {
- IApplicationSecurityDescriptor *pCallersDomainSecDesc = pCallersDomain->GetSecurityDescriptor();
-
-#ifdef FEATURE_CAS_POLICY
- // We only want to propigate the identity of homogenous domains, since heterogenous domains tend
- // to be fully trusted even if they are housing partially trusted code - which could lead to an
- // elevation of privilege if we allow the grant set to be pushed to assemblies partially trusted
- // code is loading.
- if (!pCallersDomainSecDesc->IsHomogeneous())
- {
- COMPlusThrow(kNotSupportedException, W("NotSupported_SecurityContextSourceAppDomainInHeterogenous"));
- }
-#endif // FEATURE_CAS_POLICY
-
- gc.granted = pCallersDomainSecDesc->GetGrantedPermissionSet();
- dwSpecialFlags = pCallersDomainSecDesc->GetSpecialFlags();
- }
-
- // Caller may be in another appdomain context, in which case we'll
- // need to marshal/unmarshal the grant and deny sets across.
-#ifdef FEATURE_REMOTING // should not happen without remoting
- if (pCallersDomain != ::GetAppDomain())
- {
- gc.granted = AppDomainHelper::CrossContextCopyFrom(pCallersDomain->GetId(), &(gc.granted));
- if (gc.denied != NULL)
- {
- gc.denied = AppDomainHelper::CrossContextCopyFrom(pCallersDomain->GetId(), &(gc.denied));
- }
- }
-#else // !FEATURE_REMOTING
- _ASSERTE(pCallersDomain == ::GetAppDomain());
-#endif // FEATURE_REMOTING
- }
- }
-#else // FEATURE_CORECLR
// In SilverLight all dynamic assemblies should be transparent and partially trusted, even if they are
// created by platform assemblies. Thus they should inherit the grant sets from the appdomain not the
// parent assembly.
IApplicationSecurityDescriptor *pCurrentDomainSecDesc = ::GetAppDomain()->GetSecurityDescriptor();
gc.granted = pCurrentDomainSecDesc->GetGrantedPermissionSet();
DWORD dwSpecialFlags = pCurrentDomainSecDesc->GetSpecialFlags();
-#endif // !FEATURE_CORECLR
// If the dynamic assembly creator did not specify evidence for the newly created assembly, then it
// should inherit the grant set of the creation assembly.
if (loadSecurity.m_pAdditionalEvidence == NULL)
{
-#ifdef FEATURE_CAS_POLICY
- // If we're going to inherit the grant set of an anonymously hosted dynamic method, it will be
- // full trust/transparent. In that case, we should demand full trust.
- if(args->securityContextSource == kCurrentAssembly &&
- pCallerAssembly != NULL &&
- pCallersDomain != NULL &&
- pCallerAssembly->GetDomainAssembly(pCallersDomain) == pCallersDomain->GetAnonymouslyHostedDynamicMethodsAssembly())
- {
- loadSecurity.m_fPropagatingAnonymouslyHostedDynamicMethodGrant = true;
- }
-#endif // FEATURE_CAS_POLICY
loadSecurity.m_pGrantSet = &gc.granted;
loadSecurity.m_pRefusedSet = &gc.denied;
@@ -950,33 +787,11 @@ Assembly *Assembly::CreateDynamic(AppDomain *pDomain, CreateDynamicAssemblyArgs
pAssem->m_dwDynamicAssemblyAccess = args->access;
-#ifdef FEATURE_CAS_POLICY
- // If a legacy assembly is emitting an assembly, then we implicitly add the legacy attribute. If the legacy
- // assembly is also in partial trust, we implicitly make the emitted assembly transparent.
- ModuleSecurityDescriptor *pEmittingMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pCallerAssembly);
- if (pEmittingMSD->GetSecurityRuleSet() == SecurityRuleSet_Level1)
- {
- IAssemblySecurityDescriptor *pCallerSecDesc = pCallerAssembly->GetSecurityDescriptor(pCallersDomain);
- if (!pCallerSecDesc->IsFullyTrusted())
- {
- args->flags = kTransparentAssembly;
- }
- }
-
- // If the code emitting the dynamic assembly is transparent and it is attempting to emit a non-transparent
- // assembly, then we need to do a demand for the grant set of the emitting assembly (which should also be
- // is the grant set of the dynamic assembly).
- if (Security::IsMethodTransparent(pmdEmitter) && !(args->flags & kTransparentAssembly))
- {
- Security::DemandGrantSet(pCallerAssembly->GetSecurityDescriptor(pCallersDomain));
- }
-#else // FEATURE_CORECLR
// Making the dynamic assembly opportunistically critical in full trust CoreCLR and transparent otherwise.
if (!GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted())
{
args->flags = kTransparentAssembly;
}
-#endif //!FEATURE_CORECLR
// Fake up a module security descriptor for the assembly.
TokenSecurityDescriptorFlags tokenFlags = TokenSecurityDescriptorFlags_None;
@@ -991,42 +806,7 @@ Assembly *Assembly::CreateDynamic(AppDomain *pDomain, CreateDynamicAssemblyArgs
if (args->flags & kTreatAsSafeAssembly)
tokenFlags |= TokenSecurityDescriptorFlags_TreatAsSafe;
-#ifdef FEATURE_APTCA
- if (args->aptcaBlob != NULL)
- {
- tokenFlags |= ParseAptcaAttribute(args->aptcaBlob->GetDirectPointerToNonObjectElements(),
- args->aptcaBlob->GetNumComponents());
- }
-
-#endif // FEATURE_APTCA
-#ifndef FEATURE_CORECLR
- // Use the security rules given to us if the emitting code has selected a specific one. Otherwise,
- // inherit the security rules of the emitting assembly.
- if (args->securityRulesBlob != NULL)
- {
- tokenFlags |= ParseSecurityRulesAttribute(args->securityRulesBlob->GetDirectPointerToNonObjectElements(),
- args->securityRulesBlob->GetNumComponents());
- }
- else
- {
- // Ensure that dynamic assemblies created by mscorlib always specify a rule set, since we want to
- // make sure that creating a level 2 assembly was an explicit decision by the emitting code,
- // rather than an implicit decision because mscorlib is level 2 itself.
- //
- // If you're seeing this assert, it means that you've created a dynamic assembly from mscorlib,
- // but did not pass a CustomAttributeBuilder for the SecurityRulesAttribute to the
- // DefineDynamicAssembly call.
- _ASSERTE(!pCallerAssembly->IsSystem());
-
- // Use the creating assembly's security rule set for the emitted assembly
- SecurityRuleSet callerRuleSet =
- ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pCallerAssembly)->GetSecurityRuleSet();
- tokenFlags |= EncodeSecurityRuleSet(callerRuleSet);
-
- tokenFlags |= TokenSecurityDescriptorFlags_SecurityRules;
- }
-#endif // !FEATURE_CORECLR
_ASSERTE(pAssem->GetManifestModule()->m_pModuleSecurityDescriptor != NULL);
pAssem->GetManifestModule()->m_pModuleSecurityDescriptor->OverrideTokenFlags(tokenFlags);
@@ -1038,47 +818,6 @@ Assembly *Assembly::CreateDynamic(AppDomain *pDomain, CreateDynamicAssemblyArgs
if (publicKey.GetSize() > 0)
{
pAssem->SetStrongNameLevel(Assembly::SN_PUBLIC_KEY);
-#ifndef FEATURE_CORECLR
- gc.strongNameKeyPair = args->assemblyName->GetStrongNameKeyPair();
- // If there's a public key, there might be a strong name key pair.
- if (gc.strongNameKeyPair != NULL)
- {
- MethodDescCallSite getKeyPair(METHOD__STRONG_NAME_KEY_PAIR__GET_KEY_PAIR, &gc.strongNameKeyPair);
-
- ARG_SLOT arglist[] =
- {
- ObjToArgSlot(gc.strongNameKeyPair),
- PtrToArgSlot(&gc.orArrayOrContainer)
- };
-
- BOOL bKeyInArray;
- bKeyInArray = (BOOL)getKeyPair.Call_RetBool(arglist);
-
- if (bKeyInArray)
- {
- U1ARRAYREF orArray = (U1ARRAYREF)gc.orArrayOrContainer;
- pAssem->m_cbStrongNameKeyPair = orArray->GetNumComponents();
- pAssem->m_pbStrongNameKeyPair = new BYTE[pAssem->m_cbStrongNameKeyPair];
-
- pAssem->m_FreeFlag |= pAssem->FREE_KEY_PAIR;
- memcpy(pAssem->m_pbStrongNameKeyPair, orArray->GetDataPtr(), pAssem->m_cbStrongNameKeyPair);
- pAssem->SetStrongNameLevel(Assembly::SN_FULL_KEYPAIR_IN_ARRAY);
- }
- else
- {
- STRINGREF orContainer = (STRINGREF)gc.orArrayOrContainer;
- DWORD cchContainer = orContainer->GetStringLength();
- pAssem->m_pwStrongNameKeyContainer = new WCHAR[cchContainer + 1];
-
- pAssem->m_FreeFlag |= pAssem->FREE_KEY_CONTAINER;
- memcpy(pAssem->m_pwStrongNameKeyContainer, orContainer->GetBuffer(), cchContainer * sizeof(WCHAR));
- pAssem->m_pwStrongNameKeyContainer[cchContainer] = W('\0');
-
- pAssem->SetStrongNameLevel(Assembly::SN_FULL_KEYPAIR_IN_CONTAINER);
- }
- }
- else
-#endif // FEATURE_CORECLR
{
// Since we have no way to validate the public key of a dynamic assembly we don't allow
// partial trust code to emit a dynamic assembly with an arbitrary public key.
@@ -1147,87 +886,6 @@ Assembly *Assembly::CreateDynamic(AppDomain *pDomain, CreateDynamicAssemblyArgs
RETURN pRetVal;
} // Assembly::CreateDynamic
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-ReflectionModule *Assembly::CreateDynamicModule(LPCWSTR wszModuleName, LPCWSTR wszFileName, BOOL fIsTransient, INT32* ptkFile)
-{
- CONTRACT(ReflectionModule *)
- {
- STANDARD_VM_CHECK;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- AllocMemTracker amTracker;
-
- // Add a manifest entry for the module
- mdFile token;
- IMetaDataAssemblyEmit *pAssemblyEmit = GetManifestFile()->GetAssemblyEmitter();
- IfFailThrow(pAssemblyEmit->DefineFile(wszFileName, NULL, 0, 0, &token));
-
- if (ptkFile)
- *ptkFile = (INT32)token;
-
- GetManifestModule()->UpdateDynamicMetadataIfNeeded();
-
- // Define initial metadata for the module
- SafeComHolder<IMetaDataEmit> pEmit;
- PEFile::DefineEmitScope(IID_IMetaDataEmit, (void **)&pEmit);
-
- // the module name will be set later when we create the ReflectionModule
-
- // Create the PEFile for the module
- PEModuleHolder pFile(PEModule::Create(GetManifestFile(), token, pEmit));
-
- // Create the DomainModule
- NewHolder<DomainModule> pDomainModule(new DomainModule(::GetAppDomain(), GetDomainAssembly(), pFile));
-
- // Create the module itself
- ReflectionModuleHolder pWrite(ReflectionModule::Create(this, pFile, &amTracker, wszModuleName, fIsTransient));
-
- amTracker.SuppressRelease(); //@todo: OOM: is this the right place to commit the tracker?
- pWrite->SetIsTenured();
-
- // Modules take the DebuggerAssemblyControlFlags down from its parent Assembly initially.
- // By default, this turns on JIT optimization.
-
- pWrite->SetDebuggerInfoBits(GetDebuggerInfoBits());
-
- // Associate the two
- pDomainModule->SetModule(pWrite);
- m_pManifest->StoreFileThrowing(token, pWrite);
-
- // Simulate loading process
- pDomainModule->Begin();
- pDomainModule->DeliverSyncEvents();
- pDomainModule->DeliverAsyncEvents();
- pDomainModule->FinishLoad();
- pDomainModule->ClearLoading();
- pDomainModule->m_level = FILE_ACTIVE;
-
- pDomainModule.SuppressRelease();
- ReflectionModule *pModule = pWrite.Extract();
-
- LPCSTR szUTF8FileName;
- CQuickBytes qbLC;
-
- // Get the UTF8 file name
- IfFailThrow(m_pManifest->GetMDImport()->GetFileProps(token, &szUTF8FileName, NULL, NULL, NULL));
- UTF8_TO_LOWER_CASE(szUTF8FileName, qbLC);
- LPCSTR szUTF8FileNameLower = (LPUTF8) qbLC.Ptr();
-
- CrstHolder lock(&m_crstAllowedFiles);
-
- // insert the value into manifest's look up table.
- // Need to perform case insensitive hashing as well.
- m_pAllowedFiles->InsertValue(szUTF8FileName, (HashDatum)(size_t)token, TRUE);
- m_pAllowedFiles->InsertValue(szUTF8FileNameLower, (HashDatum)(size_t)token, TRUE);
-
- // Now make file token associate with the loaded module
- m_pManifest->StoreFileThrowing(token, pModule);
-
- RETURN pModule;
-} // Assembly::CreateDynamicModule
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
#endif // CROSSGEN_COMPILE
@@ -1409,37 +1067,7 @@ void Assembly::SetParent(BaseDomain* pParent)
mdFile Assembly::GetManifestFileToken(LPCSTR name)
{
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- FORBID_FAULT;
- MODE_ANY;
- SUPPORTS_DAC;
- }
- CONTRACTL_END;
-
- HashDatum datum;
- // Note: We're doing a case sensitive lookup
- // This is OK because the lookup string and the string we insert into the hashtable
- // are obtained from the same place.
-
- // m_pAllowedFiles only grows - entries are never deleted from it. So we do not take
- // a lock around GetValue. If the code is modified such that we delete entries from m_pAllowedFiles,
- // reconsider whether the callers that consume the mdFile should take the m_crstAllowedFiles lock.
- if (m_pAllowedFiles->GetValue(name, &datum)) {
-
- if (datum != NULL) // internal module
- return (mdFile)(size_t)PTR_TO_TADDR(datum);
- else // manifest file
- return mdFileNil;
- }
- else
- return mdTokenNil; // not found
-#else
return mdFileNil;
-#endif
}
mdFile Assembly::GetManifestFileToken(IMDInternalImport *pImport, mdFile kFile)
@@ -1772,11 +1400,6 @@ Module * Assembly::FindModuleByTypeRef(
RETURN NULL;
}
-#ifndef FEATURE_CORECLR
- // Event Tracing for Windows is used to log data for performance and functional testing purposes.
- // The events below are used to help measure the performance of assembly loading of a static reference.
- FireEtwLoaderPhaseStart((::GetAppDomain() ? ::GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable), ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderStaticLoad, NULL, NULL, GetClrInstanceId());
-#endif //!FEATURE_CORECLR
DomainAssembly * pDomainAssembly = pModule->LoadAssembly(
::GetAppDomain(),
@@ -1784,27 +1407,6 @@ Module * Assembly::FindModuleByTypeRef(
szNamespace,
szClassName);
-#ifndef FEATURE_CORECLR
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD))
- {
- StackSString assemblySimpleName;
- EX_TRY
- {
- if ((pDomainAssembly != NULL) && (pDomainAssembly->GetCurrentAssembly() != NULL))
- {
- assemblySimpleName.AppendUTF8(pDomainAssembly->GetCurrentAssembly()->GetSimpleName());
- assemblySimpleName.Normalize(); // Ensures that the later cast to LPCWSTR does not throw.
- }
- }
- EX_CATCH
- {
- assemblySimpleName.Clear();
- }
- EX_END_CATCH(RethrowTransientExceptions)
-
- FireEtwLoaderPhaseEnd(::GetAppDomain() ? ::GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderStaticLoad, NULL, assemblySimpleName.IsEmpty() ? NULL : (LPCWSTR)assemblySimpleName, GetClrInstanceId());
- }
-#endif //!FEATURE_CORECLR
if (pDomainAssembly == NULL)
RETURN NULL;
@@ -1889,105 +1491,6 @@ void Assembly::CacheManifestExportedTypes(AllocMemTracker *pamTracker)
}
void Assembly::CacheManifestFiles()
{
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- CONTRACT_VOID
- {
- THROWS;
- GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- mdToken tkFile;
- LPCSTR pszFileName;
- CQuickBytes qbLC;
-
- HENUMInternalHolder phEnum(GetManifestImport());
- phEnum.EnumInit(mdtFile,
- mdTokenNil);
-
-
- DWORD dwCount = GetManifestImport()->EnumGetCount(&phEnum);
- LockOwner lockOwner = { &m_crstAllowedFiles, IsOwnerOfCrst };
- if (!m_pAllowedFiles->Init(dwCount+1, &lockOwner))
- ThrowOutOfMemory();
-
- CrstHolder lock(&m_crstAllowedFiles);
-
- m_nextAvailableModuleIndex = dwCount+1;
-
- while (GetManifestImport()->EnumNext(&phEnum, &tkFile))
- {
- if (TypeFromToken(tkFile) == mdtFile)
- {
- IfFailThrow(GetManifestImport()->GetFileProps(
- tkFile,
- &pszFileName,
- NULL, // hash
- NULL, // hash len
- NULL)); // flags
-
- // Add to hash table
- m_pAllowedFiles->InsertValue(pszFileName, (HashDatum)(size_t)tkFile, TRUE);
-
- // Need to perform case insensitive hashing as well.
- {
- UTF8_TO_LOWER_CASE(pszFileName, qbLC);
- pszFileName = (LPUTF8) qbLC.Ptr();
- }
-
- // Add each internal module
- m_pAllowedFiles->InsertValue(pszFileName, (HashDatum)(size_t)tkFile, TRUE);
- }
- }
-
- HENUMInternalHolder phEnumModules(GetManifestImport());
- phEnumModules.EnumInit(mdtModuleRef, mdTokenNil);
- mdToken tkModuleRef;
-
- while (GetManifestImport()->EnumNext(&phEnumModules, &tkModuleRef))
- {
- LPCSTR pszModuleRefName, pszModuleRefNameLower;
-
- if (TypeFromToken(tkModuleRef) == mdtModuleRef)
- {
- IfFailThrow(GetManifestImport()->GetModuleRefProps(tkModuleRef, &pszModuleRefName));
-
- // Convert to lower case and lookup
- {
- UTF8_TO_LOWER_CASE(pszModuleRefName, qbLC);
- pszModuleRefNameLower = (LPUTF8) qbLC.Ptr();
- }
-
- HashDatum datum;
- if (m_pAllowedFiles->GetValue(pszModuleRefNameLower, &datum))
- {
- mdFile tkFileForModuleRef = (mdFile)(size_t)datum;
- m_pAllowedFiles->InsertValue(pszModuleRefName, (HashDatum)(size_t)tkFileForModuleRef);
- }
- }
- }
-
- // Add the manifest file
- if (!GetManifestImport()->IsValidToken(GetManifestImport()->GetModuleFromScope()))
- {
- ThrowHR(COR_E_BADIMAGEFORMAT);
- }
- IfFailThrow(GetManifestImport()->GetScopeProps(&pszFileName, NULL));
-
- // Add to hash table
- m_pAllowedFiles->InsertValue(pszFileName, NULL, TRUE);
-
- // Need to perform case insensitive hashing as well.
- {
- UTF8_TO_LOWER_CASE(pszFileName, qbLC);
- pszFileName = (LPUTF8) qbLC.Ptr();
- }
-
- m_pAllowedFiles->InsertValue(pszFileName, NULL, TRUE);
-
- RETURN;
-#endif
}
@@ -2042,57 +1545,7 @@ void Assembly::PublishModuleIntoAssembly(Module *module)
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-Module* Assembly::FindModule(PEFile *pFile, BOOL includeLoading)
-{
- CONTRACT(Module *)
- {
- THROWS;
- GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- DomainFile *pModule = GetDomainAssembly()->FindModule(pFile, includeLoading);
- if (pModule == NULL)
- RETURN NULL;
- else
- RETURN pModule->GetModule();
-}
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
-
-#ifdef FEATURE_MIXEDMODE
-DomainFile* Assembly::FindIJWDomainFile(HMODULE hMod, const SString &path)
-{
- CONTRACT (DomainFile*)
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(GetManifestModule()));
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END;
-
- ModuleIterator i = IterateModules();
- while (i.Next())
- {
- PEFile *pFile = i.GetModule()->GetFile();
-
- if ( !pFile->IsResource()
- && !pFile->IsDynamic()
- && !pFile->IsILOnly())
- {
- if ( (pFile->GetLoadedIL()!= NULL && pFile->GetIJWBase() == hMod)
- || PEImage::PathEquals(pFile->GetPath(), path))
- RETURN i.GetModule()->GetDomainFile();
- }
- }
- RETURN NULL;
-}
-#endif // FEATURE_MIXEDMODE
//*****************************************************************************
// Set up the list of names of any friend assemblies
@@ -2211,214 +1664,6 @@ enum CorEntryPointType
EntryCrtMain // unsigned main(void)
};
-#ifdef STRESS_THREAD
-
-struct Stress_Thread_Param
-{
- MethodDesc *pFD;
- GlobalStrongHandleHolder argHandle;
- short numSkipArgs;
- CorEntryPointType EntryType;
- Thread* pThread;
-
-public:
- Stress_Thread_Param()
- : pFD(NULL),
- argHandle(),
- numSkipArgs(0),
- EntryType(EntryManagedMain),
- pThread(NULL)
- { LIMITED_METHOD_CONTRACT; }
-
- Stress_Thread_Param* Clone ()
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- NewHolder<Stress_Thread_Param> retVal= new Stress_Thread_Param;
-
- retVal->pFD = pFD;
- if (argHandle.GetValue()!=NULL)
- {
- GCX_COOP();
- retVal->argHandle.Assign(CreateDuplicateHandle(argHandle.GetValue()));
- }
- retVal->numSkipArgs = numSkipArgs;
- retVal->EntryType = EntryType;
- retVal->pThread = pThread;
- return retVal.Extract();
- }
-};
-
-struct Stress_Thread_Worker_Param
-{
- Stress_Thread_Param *lpParameter;
- ULONG retVal;
-};
-
-static void Stress_Thread_Proc_Worker_Impl(Stress_Thread_Worker_Param * args)
-{
- STATIC_CONTRACT_THROWS;
-
- args->retVal = E_FAIL;
-
- Stress_Thread_Param* lpParam = (Stress_Thread_Param *)args->lpParameter;
-
- ARG_SLOT stackVar = 0;
-
- MethodDescCallSite threadStart(lpParam->pFD);
-
- // Build the parameter array and invoke the method.
- if (lpParam->EntryType == EntryManagedMain)
- {
- PTRARRAYREF StrArgArray = (PTRARRAYREF)ObjectFromHandle(lpParam->argHandle.GetValue());
- stackVar = ObjToArgSlot(StrArgArray);
- }
-
- if (lpParam->pFD->IsVoid())
- {
- threadStart.Call(&stackVar);
- args->retVal = GetLatchedExitCode();
- }
- else
- {
- // We are doing the same cast as in RunMain. Main is required to return INT32 if it returns.
- ARG_SLOT retVal = (INT32)threadStart.Call_RetArgSlot(&stackVar);
- args->retVal = static_cast<ULONG>(retVal);
- }
-}
-
-// wrap into EX_TRY_NOCATCH and call the real thing
-static void Stress_Thread_Proc_Worker (LPVOID ptr)
-{
- STATIC_CONTRACT_THROWS;
-
- EX_TRY_NOCATCH(Stress_Thread_Worker_Param *, args, (Stress_Thread_Worker_Param *) ptr)
- {
- Stress_Thread_Proc_Worker_Impl(args);
- //<TODO>
- // When we get mainCRTStartup from the C++ then this should be able to go away.</TODO>
- fflush(stdout);
- fflush(stderr);
- }
- EX_END_NOCATCH
-}
-
-static DWORD WINAPI __stdcall Stress_Thread_Proc (LPVOID lpParameter)
-{
- STATIC_CONTRACT_THROWS;
-
- Stress_Thread_Worker_Param args = {(Stress_Thread_Param*)lpParameter,0};
- Stress_Thread_Param *lpParam = (Stress_Thread_Param *)lpParameter;
- Thread *pThread = lpParam->pThread;
- if (!pThread->HasStarted())
- return 0;
-
- _ASSERTE(::GetAppDomain() != NULL);
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return E_FAIL);
- EX_TRY
- {
-
- ADID KickOffDomain = pThread->GetKickOffDomainId();
-
- // should always have a kickoff domain - a thread should never start in a domain that is unloaded
- // because otherwise it would have been collected because nobody can hold a reference to thread object
- // in a domain that has been unloaded. But it is possible that we started the unload, in which
- // case this thread wouldn't be allowed in or would be punted anyway.
- if (KickOffDomain != lpParam->pThread->GetDomain()->GetId())
- pThread->DoADCallBack(KickOffDomain, Stress_Thread_Proc_Worker, &args);
- else
- Stress_Thread_Proc_Worker(&args);
-
- }
- EX_CATCH
- {
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- delete (Stress_Thread_Param *) lpParameter;
- // Enable preemptive GC so a GC thread can suspend me.
- GCX_PREEMP_NO_DTOR();
- DestroyThread(pThread);
-
- END_SO_INTOLERANT_CODE;
- return args.retVal;
-}
-
-static void Stress_Thread_Start (LPVOID lpParameter)
-{
- CONTRACT_VOID
- {
- THROWS;
- GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM());
- MODE_ANY;
- }
- CONTRACT_END;
-
- Thread *pCurThread = GetThread();
- if (pCurThread->m_stressThreadCount == -1) {
- pCurThread->m_stressThreadCount = g_pConfig->GetStressThreadCount();
- }
- DWORD dwThreads = pCurThread->m_stressThreadCount;
- if (dwThreads <= 1)
- RETURN;
-
- Thread ** threads = new Thread* [dwThreads-1];
-
- DWORD n;
- for (n = 0; n < dwThreads-1; n ++)
- {
- threads[n] = SetupUnstartedThread();
-
- threads[n]->m_stressThreadCount = dwThreads/2;
- Stress_Thread_Param *param = ((Stress_Thread_Param*)lpParameter)->Clone();
- param->pThread = threads[n];
- if (!threads[n]->CreateNewThread(0, Stress_Thread_Proc, param))
- {
- delete param;
- threads[n]->DecExternalCount(FALSE);
- ThrowOutOfMemory();
- }
- threads[n]->SetThreadPriority (THREAD_PRIORITY_NORMAL);
- }
-
- for (n = 0; n < dwThreads-1; n ++)
- {
- threads[n]->StartThread();
- }
- __SwitchToThread (0, CALLER_LIMITS_SPINNING);
-
- RETURN;
-}
-
-void Stress_Thread_RunMain(MethodDesc* pFD, CorEntryPointType EntryType, short numSkipArgs, OBJECTHANDLE argHandle)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- Stress_Thread_Param Param;
- Param.pFD = pFD;
- Param.argHandle.Assign(argHandle);
- Param.numSkipArgs = numSkipArgs;
- Param.EntryType = EntryType;
- Param.pThread = NULL;
- Stress_Thread_Start (&Param);
-}
-
-
-#endif // STRESS_THREAD
-
void DECLSPEC_NORETURN ThrowMainMethodException(MethodDesc* pMD, UINT resID)
{
CONTRACTL
@@ -2547,20 +1792,7 @@ HRESULT RunMain(MethodDesc *pFD ,
if ((EntryType == EntryManagedMain) &&
(stringArgs == NULL)) {
- #ifndef FEATURE_CORECLR
- // If you look at the DIFF on this code then you will see a major change which is that we
- // no longer accept all the different types of data arguments to main. We now only accept
- // an array of strings.
-
- wzArgs = CorCommandLine::GetArgvW(&cCommandArgs);
- // In the WindowsCE case where the app has additional args the count will come back zero.
- if (cCommandArgs > 0) {
- if (!wzArgs)
- return E_INVALIDARG;
- }
-#else // !FEATURE_CORECLR
return E_INVALIDARG;
-#endif // !FEATURE_CORECLR
}
ETWFireEvent(Main_V1);
@@ -2606,11 +1838,6 @@ HRESULT RunMain(MethodDesc *pFD ,
StrArgArray = *pParam->stringArgs;
}
-#ifdef STRESS_THREAD
- OBJECTHANDLE argHandle = (StrArgArray != NULL) ? CreateGlobalStrongHandle (StrArgArray) : NULL;
- Stress_Thread_RunMain(pParam->pFD, pParam->EntryType, pParam->numSkipArgs, argHandle);
-#endif
-
ARG_SLOT stackVar = ObjToArgSlot(StrArgArray);
if (pParam->pFD->IsVoid())
@@ -2711,37 +1938,12 @@ INT32 Assembly::ExecuteMainMethod(PTRARRAYREF *stringArgs, BOOL waitForOtherThre
if (pMeth) {
RunMainPre();
-#if defined(FEATURE_APPX_BINDER) && defined(FEATURE_MULTICOREJIT)
- if (AppX::IsAppXProcess())
- {
- GCX_PREEMP();
-
- // we call this to obtain and cache the PRAID value which is used
- // by multicore JIT manager and watson bucket params generation.
-
- // NOTE: this makes a COM call into WinRT so we must do this after we've
- // set the thread's apartment state which will do CoInitializeEx().
- LPCWSTR praid;
- hr = AppX::GetApplicationId(praid);
- _ASSERTE(SUCCEEDED(hr));
-
- if (!pMeth->GetModule()->HasNativeImage())
- {
- // For Appx, multicore JIT is only needed when root assembly does not have NI image
- // When it has NI image, we can't generate profile, and do not need to playback profile
- AppDomain * pDomain = pThread->GetDomain();
- pDomain->GetMulticoreJitManager().AutoStartProfileAppx(pDomain);
- }
- }
-#endif // FEATURE_APPX_BINDER && FEATURE_MULTICOREJIT
-#ifdef FEATURE_CORECLR
// Set the root assembly as the assembly that is containing the main method
// The root assembly is used in the GetEntryAssembly method that on CoreCLR is used
// to get the TargetFrameworkMoniker for the app
AppDomain * pDomain = pThread->GetDomain();
pDomain->SetRootAssembly(pMeth->GetAssembly());
-#endif
hr = RunMain(pMeth, 1, &iRetVal, stringArgs);
}
}
@@ -2884,161 +2086,6 @@ BOOL Assembly::FileNotFound(HRESULT hr)
(hr == CLR_E_BIND_TYPE_NOT_FOUND);
}
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-PEModule * Assembly::LoadModule_AddRef(mdFile kFile, BOOL fLoadResource)
-{
- CONTRACT(PEModule *)
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL, fLoadResource ? NULL_NOT_OK : NULL_OK));
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END
-
- if (! ((TypeFromToken(kFile) == mdtFile) &&
- GetManifestImport()->IsValidToken(kFile)) )
- {
- ThrowHR(COR_E_BADIMAGEFORMAT, BFA_INVALID_FILE_TOKEN);
- }
-
- LPCSTR psModuleName;
- DWORD dwFlags;
- IfFailThrow(GetManifestImport()->GetFileProps(
- kFile,
- &psModuleName,
- NULL,
- NULL,
- &dwFlags));
-
- if (! (IsFfContainsMetaData(dwFlags) || fLoadResource) )
- RETURN NULL;
-
- SString name(SString::Utf8, psModuleName);
- PEModule * pModule = NULL;
-
- if (AssemblySpec::VerifyBindingString((LPCWSTR)name))
- {
- EX_TRY
- {
- GCX_PREEMP();
-
-#ifdef FEATURE_FUSION // specific to remote modules
- if (GetFusionAssembly()) {
- StackSString path;
- ::GetAppDomain()->GetFileFromFusion(GetFusionAssembly(),
- (LPCWSTR)name, path);
- pModule = PEModule::Open(m_pManifestFile, kFile, path);
- goto lDone;
- }
-
- if (GetIHostAssembly()) {
- pModule = PEModule::Open(m_pManifestFile, kFile, name);
- goto lDone;
- }
-#endif
- if (!m_pManifestFile->GetPath().IsEmpty()) {
- StackSString path = m_pManifestFile->GetPath();
-
- SString::Iterator i = path.End()-1;
-
- if (PEAssembly::FindLastPathSeparator(path, i)) {
- path.Truncate(++i);
- path.Insert(i, name);
- }
- pModule = PEModule::Open(m_pManifestFile, kFile, path);
- }
-#ifdef FEATURE_FUSION
- lDone: ;
-#endif
- }
- EX_CATCH
- {
- Exception *ex = GET_EXCEPTION();
- if (FileNotFound(ex->GetHR()) ||
- (ex->GetHR() == FUSION_E_INVALID_NAME))
- pModule = RaiseModuleResolveEvent_AddRef(psModuleName, kFile);
-
- if (pModule == NULL)
- {
- EEFileLoadException::Throw(name, ex->GetHR(), ex);
- }
- }
- EX_END_CATCH(SwallowAllExceptions)
- }
-
- if (pModule == NULL)
- {
- pModule = RaiseModuleResolveEvent_AddRef(psModuleName, kFile);
- if (pModule == NULL)
- {
- EEFileLoadException::Throw(name, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
- }
- }
-
- RETURN pModule;
-}
-
-PEModule * Assembly::RaiseModuleResolveEvent_AddRef(LPCSTR szName, mdFile kFile)
-{
- CONTRACT(PEModule *)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END;
-
- Module* pModule = NULL;
-
-#ifndef CROSSGEN_COMPILE
- GCX_COOP();
-
- struct _gc {
- OBJECTREF AssemblyRef;
- STRINGREF str;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- if ((gc.AssemblyRef = GetExposedObject()) != NULL)
- {
- MethodDescCallSite onModuleResolve(METHOD__ASSEMBLY__ON_MODULE_RESOLVE, &gc.AssemblyRef);
- gc.str = StringObject::NewString(szName);
- ARG_SLOT args[2] = {
- ObjToArgSlot(gc.AssemblyRef),
- ObjToArgSlot(gc.str)
- };
-
- REFLECTMODULEBASEREF ResultingModuleRef =
- (REFLECTMODULEBASEREF) onModuleResolve.Call_RetOBJECTREF(args);
-
- if (ResultingModuleRef != NULL)
- {
- pModule = ResultingModuleRef->GetModule();
- }
- }
- GCPROTECT_END();
-
- if (pModule && ( (!(pModule->IsIntrospectionOnly())) != !(IsIntrospectionOnly()) ))
- {
- COMPlusThrow(kFileLoadException, IDS_CLASSLOAD_MODULE_RESOLVE_INTROSPECTION_MISMATCH);
- }
-
- if ((pModule != NULL) &&
- (pModule == m_pManifest->LookupFile(kFile)))
- {
- RETURN clr::SafeAddRef((PEModule *)pModule->GetFile());
- }
-#endif // CROSSGEN_COMPILE
-
- RETURN NULL;
-}
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
BOOL Assembly::GetResource(LPCSTR szName, DWORD *cbResource,
PBYTE *pbInMemoryResource, Assembly** pAssemblyRef,
@@ -3072,21 +2119,37 @@ BOOL Assembly::IsInstrumented()
STATIC_CONTRACT_GC_TRIGGERS;
STATIC_CONTRACT_FAULT;
- BOOL isInstrumented = false;
-
- EX_TRY
+ // This will set the value of m_isInstrumentedStatus by calling IsInstrumentedHelper()
+ // that method performs string pattern matching using the Config value of ZapBBInstr
+ // We cache the value returned from that method in m_isInstrumentedStatus
+ //
+ if (m_isInstrumentedStatus == IS_INSTRUMENTED_UNSET)
{
- FAULT_NOT_FATAL();
+ EX_TRY
+ {
+ FAULT_NOT_FATAL();
- isInstrumented = IsInstrumentedHelper();
- }
- EX_CATCH
- {
- isInstrumented = false;
+ if (IsInstrumentedHelper())
+ {
+ m_isInstrumentedStatus = IS_INSTRUMENTED_TRUE;
+ }
+ else
+ {
+ m_isInstrumentedStatus = IS_INSTRUMENTED_FALSE;
+ }
+ }
+
+ EX_CATCH
+ {
+ m_isInstrumentedStatus = IS_INSTRUMENTED_FALSE;
+ }
+ EX_END_CATCH(RethrowTerminalExceptions);
}
- EX_END_CATCH(RethrowTerminalExceptions);
- return isInstrumented;
+ // At this point m_isInstrumentedStatus can't have the value of IS_INSTRUMENTED_UNSET
+ _ASSERTE(m_isInstrumentedStatus != IS_INSTRUMENTED_UNSET);
+
+ return (m_isInstrumentedStatus == IS_INSTRUMENTED_TRUE);
}
BOOL Assembly::IsInstrumentedHelper()
@@ -3100,7 +2163,7 @@ BOOL Assembly::IsInstrumentedHelper()
return false;
// We must have a native image in order to perform IBC instrumentation
- if (!GetManifestFile()->HasNativeImage())
+ if (!GetManifestFile()->HasNativeOrReadyToRunImage())
return false;
// @Consider using the full name instead of the short form
@@ -3173,24 +2236,13 @@ mdAssemblyRef Assembly::AddAssemblyRef(Assembly *refedAssembly, IMetaDataAssembl
GC_TRIGGERS;
INJECT_FAULT(COMPlusThrowOM(););
PRECONDITION(CheckPointer(refedAssembly));
-#ifdef FEATURE_CORECLR
PRECONDITION(CheckPointer(pAssemEmitter, NULL_NOT_OK));
-#else
- PRECONDITION(CheckPointer(pAssemEmitter, NULL_OK));
-#endif //FEATURE_CORECLR
POSTCONDITION(!IsNilToken(RETVAL));
POSTCONDITION(TypeFromToken(RETVAL) == mdtAssemblyRef);
}
CONTRACT_END;
SafeComHolder<IMetaDataAssemblyEmit> emitHolder;
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- if (pAssemEmitter == NULL)
- {
- pAssemEmitter = GetOnDiskMDAssemblyEmitter();
- emitHolder.Assign(pAssemEmitter);
- }
-#endif // FEATURE_CORECLR && !CROSSGEN_COMPILE
AssemblySpec spec;
spec.InitializeSpec(refedAssembly->GetManifestFile());
@@ -3258,476 +2310,6 @@ void Assembly::AddExportedType(mdExportedType cl)
}
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-
-//***********************************************************
-//
-// get the IMetaDataAssemblyEmit for the on disk manifest.
-// Note that the pointer returned is AddRefed. It is the caller's
-// responsibility to release the reference.
-//
-//***********************************************************
-IMetaDataAssemblyEmit *Assembly::GetOnDiskMDAssemblyEmitter()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END
-
- IMetaDataAssemblyEmit *pAssemEmitter = NULL;
- IMetaDataEmit *pEmitter;
- RefClassWriter *pRCW;
-
- _ASSERTE(m_pOnDiskManifest);
-
- pRCW = m_pOnDiskManifest->GetClassWriter();
- _ASSERTE(pRCW);
-
- // If the RefClassWriter has a on disk emitter, then use it rather than the in-memory emitter.
- pEmitter = pRCW->GetOnDiskEmitter();
-
- if (pEmitter == NULL)
- pEmitter = m_pOnDiskManifest->GetEmitter();
-
- _ASSERTE(pEmitter != NULL);
-
- IfFailThrow(pEmitter->QueryInterface(IID_IMetaDataAssemblyEmit, (void**) &pAssemEmitter));
-
- if (pAssemEmitter == NULL)
- {
- // the manifest is not writable
- _ASSERTE(!"Bad usage!");
- }
- return pAssemEmitter;
-}
-
-//***********************************************************
-//
-// prepare saving manifest to disk.
-//
-//***********************************************************
-void Assembly::PrepareSavingManifest(ReflectionModule *pAssemblyModule)
-{
- STANDARD_VM_CONTRACT;
-
- if (pAssemblyModule)
- {
- // embedded assembly
- m_pOnDiskManifest = pAssemblyModule;
- m_fEmbeddedManifest = true;
- }
- else
- {
- m_fEmbeddedManifest = false;
-
- StackSString name(SString::Utf8, GetSimpleName());
-
- // Create the module
- m_pOnDiskManifest = CreateDynamicModule(name, name, FALSE /*fIsTransient*/);
- // store the fact this on disk manifest is temporary and can be hidden from the user
- m_needsToHideManifestForEmit = TRUE;
- }
-
- NonVMComHolder<IMetaDataAssemblyEmit> pAssemblyEmit(GetOnDiskMDAssemblyEmitter());
-
- // Copy assembly metadata to emit scope
- //<TODO>@todo: add Title, Description, Alias as CA</TODO>
- // <TODO>@todo: propagate all of the information</TODO>
- // <TODO>@todo: introduce a helper in metadata to take the ansi version of string.</TODO>
-
- IMetaDataAssemblyImport *pAssemblyImport = GetManifestFile()->GetAssemblyImporter();
-
- const void *pbPublicKey;
- ULONG cbPublicKey;
- ULONG ulHashAlgId;
- LPWSTR szName;
- ULONG chName;
- ASSEMBLYMETADATA MetaData;
- DWORD dwAssemblyFlags;
-
- MetaData.cbLocale = 0;
- MetaData.ulProcessor = 0;
- MetaData.ulOS = 0;
- IfFailThrow(pAssemblyImport->GetAssemblyProps(TokenFromRid(1, mdtAssembly),
- NULL, NULL, NULL,
- NULL, 0, &chName,
- &MetaData, NULL));
- StackSString name;
- szName = name.OpenUnicodeBuffer(chName);
-
- SString locale;
- MetaData.szLocale = locale.OpenUnicodeBuffer(MetaData.cbLocale);
-
- SBuffer proc;
- MetaData.rProcessor = (DWORD *) proc.OpenRawBuffer(MetaData.ulProcessor*sizeof(*MetaData.rProcessor));
-
- SBuffer os;
- MetaData.rOS = (OSINFO *) os.OpenRawBuffer(MetaData.ulOS*sizeof(*MetaData.rOS));
-
- IfFailThrow(pAssemblyImport->GetAssemblyProps(TokenFromRid(1, mdtAssembly),
- &pbPublicKey, &cbPublicKey, &ulHashAlgId,
- szName, chName, &chName,
- &MetaData, &dwAssemblyFlags));
-
- mdAssembly ad;
- IfFailThrow(pAssemblyEmit->DefineAssembly(pbPublicKey, cbPublicKey, ulHashAlgId,
- szName, &MetaData, dwAssemblyFlags, &ad));
-
- SafeComHolder<IMetaDataImport> pImport;
- IfFailThrow(pAssemblyEmit->QueryInterface(IID_IMetaDataImport, (void**)&pImport));
- ULONG cExistingName = 0;
- if (FAILED(pImport->GetScopeProps(NULL, 0, &cExistingName, NULL)) || cExistingName == 0)
- {
- SafeComHolder<IMetaDataEmit> pEmit;
- IfFailThrow(pAssemblyEmit->QueryInterface(IID_IMetaDataEmit, (void**)&pEmit));
- IfFailThrow(pEmit->SetModuleProps(szName));
- }
-
- name.CloseBuffer();
- locale.CloseBuffer();
- proc.CloseRawBuffer();
- os.CloseRawBuffer();
-} // Assembly::PrepareSavingManifest
-
-
-//***********************************************************
-//
-// add a file name to the file list of this assembly. On disk only.
-//
-//***********************************************************
-mdFile Assembly::AddFile(LPCWSTR wszFileName)
-{
- STANDARD_VM_CONTRACT;
-
- SafeComHolder<IMetaDataAssemblyEmit> pAssemEmitter(GetOnDiskMDAssemblyEmitter());
- mdFile fl;
-
- // Define File.
- IfFailThrow( pAssemEmitter->DefineFile(
- wszFileName, // [IN] Name of the file.
- 0, // [IN] Hash Blob.
- 0, // [IN] Count of bytes in the Hash Blob.
- 0, // [IN] Flags.
- &fl) ); // [OUT] Returned File token.
-
- return fl;
-} // Assembly::AddFile
-
-
-//***********************************************************
-//
-// Set the hash value on a file table entry.
-//
-//***********************************************************
-void Assembly::SetFileHashValue(mdFile tkFile, LPCWSTR wszFullFileName)
-{
- STANDARD_VM_CONTRACT;
-
- SafeComHolder<IMetaDataAssemblyEmit> pAssemEmitter(GetOnDiskMDAssemblyEmitter());
-
- // Get the hash value.
- SBuffer buffer;
- PEImageHolder map(PEImage::OpenImage(StackSString(wszFullFileName)));
- map->ComputeHash(GetHashAlgId(), buffer);
-
- // Set the hash blob.
- IfFailThrow( pAssemEmitter->SetFileProps(
- tkFile, // [IN] File Token.
- buffer, // [IN] Hash Blob.
- buffer.GetSize(), // [IN] Count of bytes in the Hash Blob.
- (DWORD) -1)); // [IN] Flags.
-
-} // Assembly::SetHashValue
-
-//*****************************************************************************
-// Add a Type name to the ExportedType table in the on-disk assembly manifest.
-//*****************************************************************************
-mdExportedType Assembly::AddExportedTypeOnDisk(LPCWSTR wszExportedType, mdToken tkImpl, mdToken tkTypeDef, CorTypeAttr flags)
-{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE(TypeFromToken(tkTypeDef) == mdtTypeDef);
-
- // The on-disk assembly manifest
- SafeComHolder<IMetaDataAssemblyEmit> pAssemEmitter(GetOnDiskMDAssemblyEmitter());
-
- mdExportedType ct;
-
- IfFailThrow( pAssemEmitter->DefineExportedType(
- wszExportedType, // [IN] Name of the COMType.
- tkImpl, // [IN] mdFile or mdAssemblyRef that provides the ExportedType.
- tkTypeDef, // [IN] TypeDef token within the file.
- flags, // [IN] Flags.
- &ct) ); // [OUT] Returned ExportedType token.
-
- return ct;
-} // Assembly::AddExportedTypeOnDisk
-
-//*******************************************************************************
-// Add a Type name to the ExportedType table in the in-memory assembly manifest.
-//*******************************************************************************
-mdExportedType Assembly::AddExportedTypeInMemory(LPCWSTR wszExportedType, mdToken tkImpl, mdToken tkTypeDef, CorTypeAttr flags)
-{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE(TypeFromToken(tkTypeDef) == mdtTypeDef);
-
- // The in-memory assembly manifest
- IMetaDataAssemblyEmit* pAssemEmitter = GetManifestFile()->GetAssemblyEmitter();
-
- mdExportedType ct;
-
- IfFailThrow( pAssemEmitter->DefineExportedType(
- wszExportedType, // [IN] Name of the COMType.
- tkImpl, // [IN] mdFile or mdAssemblyRef that provides the ExportedType.
- tkTypeDef, // [IN] TypeDef token within the file.
- flags, // [IN] Flags.
- &ct) ); // [OUT] Returned ExportedType token.
-
- return ct;
-} // Assembly::AddExportedTypeInMemory
-
-
-//***********************************************************
-// add an entry to ManifestResource table for a stand alone managed resource. On disk only.
-//***********************************************************
-void Assembly::AddStandAloneResource(LPCWSTR wszName, LPCWSTR wszDescription, LPCWSTR wszMimeType, LPCWSTR wszFileName, LPCWSTR wszFullFileName, int iAttribute)
-{
- STANDARD_VM_CONTRACT;
-
- SafeComHolder<IMetaDataAssemblyEmit> pAssemEmitter(GetOnDiskMDAssemblyEmitter());
- mdFile tkFile;
- mdManifestResource mr;
- SBuffer hash;
-
- // Get the hash value;
- if (GetHashAlgId())
- {
- PEImageHolder pImage(PEImage::OpenImage(StackSString(wszFullFileName)));
- pImage->ComputeHash(GetHashAlgId(), hash);
- }
-
- IfFailThrow( pAssemEmitter->DefineFile(
- wszFileName, // [IN] Name of the file.
- hash, // [IN] Hash Blob.
- hash.GetSize(), // [IN] Count of bytes in the Hash Blob.
- ffContainsNoMetaData, // [IN] Flags.
- &tkFile) ); // [OUT] Returned File token.
-
-
- IfFailThrow( pAssemEmitter->DefineManifestResource(
- wszName, // [IN] Name of the resource.
- tkFile, // [IN] mdFile or mdAssemblyRef that provides the resource.
- 0, // [IN] Offset to the beginning of the resource within the file.
- iAttribute, // [IN] Flags.
- &mr) ); // [OUT] Returned ManifestResource token.
-
-} // Assembly::AddStandAloneResource
-
-
-//***********************************************************
-// Save security permission requests.
-//***********************************************************
-void Assembly::AddDeclarativeSecurity(DWORD dwAction, void const *pValue, DWORD cbValue)
-{
- STANDARD_VM_CONTRACT;
-
- mdAssembly tkAssembly = 0x20000001;
-
- SafeComHolder<IMetaDataAssemblyEmit> pAssemEmitter(GetOnDiskMDAssemblyEmitter());
- _ASSERTE( pAssemEmitter );
-
- SafeComHolder<IMetaDataEmitHelper> pEmitHelper;
- IfFailThrow( pAssemEmitter->QueryInterface(IID_IMetaDataEmitHelper, (void**)&pEmitHelper) );
-
- IfFailThrow(pEmitHelper->AddDeclarativeSecurityHelper(tkAssembly,
- dwAction,
- pValue,
- cbValue,
- NULL));
-}
-
-
-//***********************************************************
-// Allocate space for a strong name signature in the manifest
-//***********************************************************
-HRESULT Assembly::AllocateStrongNameSignature(ICeeFileGen *pCeeFileGen,
- HCEEFILE ceeFile)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END
-
- HRESULT hr;
- HCEESECTION TData;
- DWORD dwDataOffset;
- DWORD dwDataLength;
- DWORD dwDataRVA;
- VOID *pvBuffer;
- const void *pbPublicKey;
- ULONG cbPublicKey;
-
- // Determine size of signature blob.
-
- IfFailRet(GetManifestImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly),
- &pbPublicKey, &cbPublicKey, NULL,
- NULL, NULL, NULL));
-
- if (!StrongNameSignatureSize((BYTE *) pbPublicKey, cbPublicKey, &dwDataLength)) {
- hr = StrongNameErrorInfo();
- return hr;
- }
-
- // Allocate space for the signature in the text section and update the COM+
- // header to point to the space.
- IfFailRet(pCeeFileGen->GetIlSection(ceeFile, &TData));
- IfFailRet(pCeeFileGen->GetSectionDataLen(TData, &dwDataOffset));
- IfFailRet(pCeeFileGen->GetSectionBlock(TData, dwDataLength, 4, &pvBuffer));
- IfFailRet(pCeeFileGen->GetMethodRVA(ceeFile, dwDataOffset, &dwDataRVA));
- IfFailRet(pCeeFileGen->SetStrongNameEntry(ceeFile, dwDataLength, dwDataRVA));
-
- return S_OK;
-}
-
-
-//***********************************************************
-// Strong name sign a manifest already persisted to disk
-//***********************************************************
-HRESULT Assembly::SignWithStrongName(LPCWSTR wszFileName)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END
-
- HRESULT hr = S_OK;
-
- // If we're going to do a full signing we have a key pair either
- // in a key container or provided directly in a byte array.
-
- switch (m_eStrongNameLevel) {
- case SN_FULL_KEYPAIR_IN_ARRAY:
- if (!StrongNameSignatureGeneration(wszFileName, NULL, m_pbStrongNameKeyPair, m_cbStrongNameKeyPair, NULL, NULL))
- hr = StrongNameErrorInfo();
- break;
-
- case SN_FULL_KEYPAIR_IN_CONTAINER:
- if (!StrongNameSignatureGeneration(wszFileName, m_pwStrongNameKeyContainer, NULL, 0, NULL, NULL))
- hr = StrongNameErrorInfo();
- break;
-
- default:
- break;
- }
-
- return hr;
-}
-
-
-//***********************************************************
-// save the manifest to disk!
-//***********************************************************
-void Assembly::SaveManifestToDisk(LPCWSTR wszFileName, int entrypoint, int fileKind, DWORD corhFlags, DWORD peFlags)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = NOERROR;
- HCEEFILE ceeFile = NULL;
- ICeeFileGen *pCeeFileGen = NULL;
- RefClassWriter *pRCW;
- IMetaDataEmit *pEmitter;
-
- _ASSERTE( m_fEmbeddedManifest == false );
-
- pRCW = m_pOnDiskManifest->GetClassWriter();
- _ASSERTE(pRCW);
-
- IfFailGo( pRCW->EnsureCeeFileGenCreated(corhFlags, peFlags) );
-
- pCeeFileGen = pRCW->GetCeeFileGen();
- ceeFile = pRCW->GetHCEEFILE();
- _ASSERTE(ceeFile && pCeeFileGen);
-
- //Emit the MetaData
- pEmitter = m_pOnDiskManifest->GetClassWriter()->GetEmitter();
- IfFailGo( pCeeFileGen->EmitMetaDataEx(ceeFile, pEmitter) );
-
- // Allocate space for a strong name signature if a public key was supplied
- // (this doesn't strong name the assembly, but it makes it possible to do so
- // as a post processing step).
- if (IsStrongNamed())
- IfFailGo(AllocateStrongNameSignature(pCeeFileGen, ceeFile));
-
- IfFailGo( pCeeFileGen->SetOutputFileName(ceeFile, (LPWSTR)wszFileName) );
-
- // the entryPoint for an assembly is a tkFile token if exist.
- if (RidFromToken(entrypoint) != mdTokenNil)
- IfFailGo( pCeeFileGen->SetEntryPoint(ceeFile, entrypoint) );
- if (fileKind == Dll)
- {
- pCeeFileGen->SetDllSwitch(ceeFile, true);
- }
- else
- {
- // should have a valid entry point for applications
- if (fileKind == WindowApplication)
- {
- IfFailGo( pCeeFileGen->SetSubsystem(ceeFile, IMAGE_SUBSYSTEM_WINDOWS_GUI, CEE_IMAGE_SUBSYSTEM_MAJOR_VERSION, CEE_IMAGE_SUBSYSTEM_MINOR_VERSION) );
- }
- else
- {
- _ASSERTE(fileKind == ConsoleApplication);
- IfFailGo( pCeeFileGen->SetSubsystem(ceeFile, IMAGE_SUBSYSTEM_WINDOWS_CUI, CEE_IMAGE_SUBSYSTEM_MAJOR_VERSION, CEE_IMAGE_SUBSYSTEM_MINOR_VERSION) );
- }
-
- }
-
- //Generate the CeeFile
- IfFailGo(pCeeFileGen->GenerateCeeFile(ceeFile) );
-
- // Strong name sign the resulting assembly if required.
- if (IsStrongNamed())
- IfFailGo(SignWithStrongName(wszFileName));
-
- // now release the m_pOnDiskManifest
-ErrExit:
- pRCW->DestroyCeeFileGen();
-
- // we keep the on disk manifest so that the GetModules code can skip over this ad-hoc module when modules are enumerated.
- // Need to see if we can remove the creation of this module alltogether
- //m_pOnDiskManifest = NULL;
-
- if (FAILED(hr))
- {
- if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
- {
- if (IsWin32IOError(HRESULT_CODE(hr)))
- {
- COMPlusThrowHR(COR_E_IO);
- }
- else
- {
- COMPlusThrowHR(hr);
- }
- }
- if (hr == CEE_E_CVTRES_NOT_FOUND)
- COMPlusThrow(kIOException, W("Argument_cvtres_NotFound"));
- COMPlusThrowHR(hr);
- }
-} // Assembly::SaveManifestToDisk
-
-#endif // FEATURE_CORECLR && !CROSSGEN_COMPILE
HRESULT STDMETHODCALLTYPE
@@ -3757,78 +2339,7 @@ GetAssembliesByName(LPCWSTR szAppBase,
if (!(szAssemblyName && ppIUnk && pcAssemblies))
return E_POINTER;
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
hr = COR_E_NOTSUPPORTED;
-#else
- AppDomain *pDomain = NULL;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
- if(szAppBase || szPrivateBin)
- {
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
- MethodDescCallSite createDomainEx(METHOD__APP_DOMAIN__CREATE_DOMAINEX);
- struct _gc {
- STRINGREF pFriendlyName;
- STRINGREF pAppBase;
- STRINGREF pPrivateBin;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- gc.pFriendlyName = StringObject::NewString(W("GetAssembliesByName"));
-
- if(szAppBase)
- {
- gc.pAppBase = StringObject::NewString(szAppBase);
- }
-
- if(szPrivateBin)
- {
- gc.pPrivateBin = StringObject::NewString(szPrivateBin);
- }
-
- ARG_SLOT args[5] =
- {
- ObjToArgSlot(gc.pFriendlyName),
- NULL,
- ObjToArgSlot(gc.pAppBase),
- ObjToArgSlot(gc.pPrivateBin),
- BoolToArgSlot(false)
- };
- APPDOMAINREF pDom = (APPDOMAINREF) createDomainEx.Call_RetOBJECTREF(args);
- if (pDom == NULL)
- {
- hr = E_FAIL;
- }
- else
- {
- Context *pContext = CRemotingServices::GetServerContextForProxy((OBJECTREF) pDom);
- _ASSERTE(pContext);
- pDomain = pContext->GetDomain();
- }
-
- GCPROTECT_END();
- }
- else
- pDomain = SystemDomain::System()->DefaultDomain();
-
- Assembly *pFoundAssembly;
- if (SUCCEEDED(hr)) {
- pFoundAssembly = pDomain->LoadAssemblyHelper(szAssemblyName,
- NULL);
- if (SUCCEEDED(hr)) {
- if (cMax < 1)
- hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
- else {
- ppIUnk[0] = (IUnknown *)pFoundAssembly->GetManifestAssemblyImporter();
- ppIUnk[0]->AddRef();
- }
- *pcAssemblies = 1;
- }
- }
-
- END_EXTERNAL_ENTRYPOINT;
-#endif // FEATURE_CORECLR
return hr;
}// Used by the IMetadata API's to access an assemblies metadata.
@@ -3848,188 +2359,7 @@ BOOL Assembly::MissingDependenciesCheckDone()
};
-#ifdef FEATURE_FUSION
-void Assembly::SetBindingClosure(IAssemblyBindingClosure* pClosure) // Addrefs. It is assumed the caller did not addref pClosure for us.
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- _ASSERTE(m_pBindingClosure == NULL);
- _ASSERTE(pClosure != NULL);
- m_pBindingClosure = pClosure;
- pClosure->AddRef(); // It is assumed the caller did not addref pBindingClosure for us.
-}
-
-IAssemblyBindingClosure * Assembly::GetBindingClosure()
-{
- LIMITED_METHOD_CONTRACT;
- return m_pBindingClosure;
-}
-
-
-// The shared module list is effectively an extension of the shared domain assembly hash table.
-// It is the canonical list and aribiter of modules loaded from this assembly by any app domain.
-// Modules are stored here immediately on creating (to prevent duplicate creation), as opposed to
-// in the rid map, where they are only placed upon load completion.
-
-BOOL Assembly::CanBeShared(DomainAssembly *pDomainAssembly)
-{
- CONTRACTL
- {
- PRECONDITION(CheckPointer(pDomainAssembly));
- THROWS;
- GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- LOG((LF_CODESHARING,
- LL_INFO100,
- "Checking if we can share: \"%S\" in domain 0x%x.\n",
- GetDebugName(), pDomainAssembly->GetAppDomain()));
-
- STRESS_LOG2(LF_CODESHARING, LL_INFO1000,"Checking whether DomainAssembly %p is compatible with Assembly %p",
- pDomainAssembly,this);
-
- // We must always share the same system assemblies
- if (IsSystem())
- {
- STRESS_LOG0(LF_CODESHARING, LL_INFO1000,"System assembly - sharing");
- return TRUE;
- }
-
- if ((pDomainAssembly->GetDebuggerInfoBits()&~(DACF_PDBS_COPIED|DACF_IGNORE_PDBS|DACF_OBSOLETE_TRACK_JIT_INFO))
- != (m_debuggerFlags&~(DACF_PDBS_COPIED|DACF_IGNORE_PDBS|DACF_OBSOLETE_TRACK_JIT_INFO)))
- {
- LOG((LF_CODESHARING,
- LL_INFO100,
- "We can't share it, desired debugging flags %x are different than %x\n",
- pDomainAssembly->GetDebuggerInfoBits(), (m_debuggerFlags&~(DACF_PDBS_COPIED|DACF_IGNORE_PDBS|DACF_OBSOLETE_TRACK_JIT_INFO))));
- STRESS_LOG2(LF_CODESHARING, LL_INFO100,"Flags diff= %08x [%08x/%08x]",pDomainAssembly->GetDebuggerInfoBits(),
- m_debuggerFlags);
- g_dwLoaderReasonForNotSharing = ReasonForNotSharing_DebuggerFlagMismatch;
- return FALSE;
- }
-
- PEAssembly * pDomainAssemblyFile = pDomainAssembly->GetFile();
- if (pDomainAssemblyFile == NULL)
- {
- g_dwLoaderReasonForNotSharing = ReasonForNotSharing_NullPeassembly;
- return FALSE;
- }
-
- IAssemblyBindingClosure * pContext = GetBindingClosure();
- if (pContext == NULL)
- {
- STRESS_LOG1(LF_CODESHARING, LL_INFO1000,"No context 1 - status=%d",pDomainAssemblyFile->IsSystem());
- if (pDomainAssemblyFile->IsSystem())
- return TRUE;
- else
- {
- g_dwLoaderReasonForNotSharing = ReasonForNotSharing_MissingAssemblyClosure1;
- return FALSE;
- }
- }
-
- IAssemblyBindingClosure * pCurrentContext = pDomainAssembly->GetAssemblyBindingClosure(LEVEL_STARTING);
- if (pCurrentContext == NULL)
- {
- STRESS_LOG1(LF_CODESHARING, LL_INFO1000,"No context 2 - status=%d",pDomainAssemblyFile->IsSystem());
- if (pDomainAssemblyFile->IsSystem())
- return TRUE;
- else
- {
- g_dwLoaderReasonForNotSharing = ReasonForNotSharing_MissingAssemblyClosure2;
- return FALSE;
- }
- }
-
- // ensure the closures are walked
- {
- ReleaseHolder<IBindResult> pWinRTBindResult;
-
- IUnknown * pUnk;
- if (pDomainAssembly->GetFile()->IsWindowsRuntime())
- { // It is .winmd file (WinRT assembly)
- IfFailThrow(CLRPrivAssemblyWinRT::GetIBindResult(pDomainAssembly->GetFile()->GetHostAssembly(), &pWinRTBindResult));
- pUnk = pWinRTBindResult;
- }
- else
- {
- pUnk = pDomainAssembly->GetFile()->GetFusionAssembly();
- }
-
- GCX_PREEMP();
- IfFailThrow(pCurrentContext->EnsureWalked(pUnk, ::GetAppDomain()->GetFusionContext(), LEVEL_COMPLETE));
- }
-
- if ((pContext->HasBeenWalked(LEVEL_COMPLETE) != S_OK) || !MissingDependenciesCheckDone())
- {
- GCX_COOP();
-
- BOOL fMissingDependenciesResolved = FALSE;
-
- ENTER_DOMAIN_PTR(SystemDomain::System()->DefaultDomain(), ADV_DEFAULTAD);
- {
- {
- ReleaseHolder<IBindResult> pWinRTBindResult;
-
- IUnknown * pUnk;
- if (GetManifestFile()->IsWindowsRuntime())
- { // It is .winmd file (WinRT assembly)
- IfFailThrow(CLRPrivAssemblyWinRT::GetIBindResult(GetManifestFile()->GetHostAssembly(), &pWinRTBindResult));
- pUnk = pWinRTBindResult;
- }
- else
- {
- pUnk = GetManifestFile()->GetFusionAssembly();
- }
-
- GCX_PREEMP();
- IfFailThrow(pContext->EnsureWalked(pUnk, ::GetAppDomain()->GetFusionContext(), LEVEL_COMPLETE));
- }
- DomainAssembly * domainAssembly = ::GetAppDomain()->FindDomainAssembly(this);
- if (domainAssembly != NULL)
- {
- if (domainAssembly->CheckMissingDependencies() == CMD_Resolved)
- {
- //cannot share
- fMissingDependenciesResolved = TRUE;
- }
- }
- }
- END_DOMAIN_TRANSITION;
-
- if (fMissingDependenciesResolved)
- {
- STRESS_LOG0(LF_CODESHARING, LL_INFO1000,"Missing dependencies resolved - not sharing");
- g_dwLoaderReasonForNotSharing = ReasonForNotSharing_MissingDependenciesResolved;
- return FALSE;
- }
- }
-
- HRESULT hr = pContext->IsEqual(pCurrentContext);
- IfFailThrow(hr);
- if (hr != S_OK)
- {
- STRESS_LOG1(LF_CODESHARING, LL_INFO1000,"Closure comparison returned %08x - not sharing",hr);
- g_dwLoaderReasonForNotSharing = ReasonForNotSharing_ClosureComparisonFailed;
- return FALSE;
- }
-
- LOG((LF_CODESHARING, LL_INFO100, "We can share it : \"%S\"\n", GetDebugName()));
- STRESS_LOG0(LF_CODESHARING, LL_INFO1000,"Everything is fine - sharing");
- return TRUE;
-}
-#endif
-
-#ifdef FEATURE_VERSIONING
BOOL Assembly::CanBeShared(DomainAssembly *pDomainAssembly)
{
@@ -4059,11 +2389,10 @@ BOOL Assembly::CanBeShared(DomainAssembly *pDomainAssembly)
return TRUE;
}
-#endif // FEATURE_VERSIONING
#endif // FEATURE_LOADER_OPTIMIZATION
-#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_CORESYSTEM)
BOOL Assembly::AllowUntrustedCaller()
{
CONTRACTL
@@ -4076,7 +2405,7 @@ BOOL Assembly::AllowUntrustedCaller()
return ModuleSecurityDescriptor::GetModuleSecurityDescriptor(this)->IsAPTCA();
}
-#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#endif // defined(FEATURE_CORESYSTEM)
void DECLSPEC_NORETURN Assembly::ThrowTypeLoadException(LPCUTF8 pszFullName, UINT resIDWhy)
{
@@ -4306,365 +2635,6 @@ IWinMDImport *Assembly::GetManifestWinMDImport()
#endif // FEATURE_COMINTEROP
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-void Assembly::GenerateBreadcrumbForServicing()
-{
- STANDARD_VM_CONTRACT;
-
- if (AppX::IsAppXProcess() || IsIntrospectionOnly() || GetManifestFile()->IsDynamic())
- {
- return;
- }
-
- if (HasServiceableAttribute() || IsExistingOobAssembly())
- {
- StackSString ssDisplayName;
- GetDisplayName(ssDisplayName);
-
- WriteBreadcrumb(ssDisplayName);
- CheckDenyList(ssDisplayName);
- }
-}
-
-void Assembly::WriteBreadcrumb(const SString &ssDisplayName)
-{
- STANDARD_VM_CONTRACT;
-
- WCHAR path[MAX_LONGPATH];
- HRESULT hr = WszSHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, ARRAYSIZE(path), path);
- if (hr != S_OK)
- {
- return;
- }
-
- if (wcscat_s(path, W("\\Microsoft\\NetFramework\\BreadcrumbStore\\")) != 0)
- {
- return;
- }
-
- size_t dirPathLen = wcslen(path);
-
- // Validate the display name. E.g., we don't want the display name to start with "..\\".
- bool inSimpleName = true;
- for (SString::CIterator it = ssDisplayName.Begin(); it != ssDisplayName.End(); ++it)
- {
- WCHAR c = *it;
-
- // The following characters are always allowed: a-zA-Z0-9_
- if (c >= W('a') && c <= W('z') || c >= W('A') && c <= W('Z') || c >= W('0') && c <= W('9') || c == W('_')) continue;
-
- // The period is allowed except as the first char.
- if (c == W('.') && it != ssDisplayName.Begin()) continue;
-
- // A comma terminates the assembly simple name, and we are in key=value portion of the display name.
- if (c == W(','))
- {
- inSimpleName = false;
- continue;
- }
-
- // In key=value portion, space and equal sign are also allowed.
- if (!inSimpleName && (c == W(' ') || c == W('='))) continue;
-
- // If we reach here, we have an invalid assembly display name. Return without writing breadcrumb.
- return;
- }
-
- // Log a breadcrumb using full display name.
- if (wcscat_s(path, ssDisplayName.GetUnicode()) == 0)
- {
- HandleHolder hFile = WszCreateFile(path, 0, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
- }
-
- // Log another breadcrumb using display name without version.
- // First make a copy of the display name, and look for its version part.
- StackSString ssNoVersion(ssDisplayName);
- SString::Iterator itVersion = ssNoVersion.Begin();
- if (!ssNoVersion.Find(itVersion, W(", Version=")))
- {
- return;
- }
-
- // Start from the comma before Version=, advance past the comma, then look for the next comma.
- SString::Iterator itVersionEnd = itVersion;
- ++itVersionEnd;
- if (!ssNoVersion.Find(itVersionEnd, W(',')))
- {
- // Version is the last key=value pair.
- itVersionEnd = ssNoVersion.End();
- }
-
- // Erase the version.
- ssNoVersion.Delete(itVersion, itVersionEnd - itVersion);
-
- // Generate the full path string and create the file.
- path[dirPathLen] = W('\0');
- if (wcscat_s(path, ssNoVersion.GetUnicode()) == 0)
- {
- HandleHolder hFile = WszCreateFile(path, 0, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
- }
-
-}
-
-bool Assembly::HasServiceableAttribute()
-{
- STANDARD_VM_CONTRACT;
-
- IMDInternalImport *pImport = GetManifestImport();
- MDEnumHolder hEnum(pImport);
- HRESULT hr = pImport->EnumCustomAttributeByNameInit(GetManifestToken(), ASSEMBLY_METADATA_TYPE, &hEnum);
- if (hr != S_OK)
- {
- return false;
- }
-
- mdCustomAttribute tkAttribute;
- while (pImport->EnumNext(&hEnum, &tkAttribute))
- {
- // Get raw custom attribute.
- const BYTE *pbAttr = NULL; // Custom attribute data as a BYTE*.
- ULONG cbAttr = 0; // Size of custom attribute data.
- if (FAILED(pImport->GetCustomAttributeAsBlob(tkAttribute, reinterpret_cast<const void **>(&pbAttr), &cbAttr)))
- {
- THROW_BAD_FORMAT(BFA_INVALID_TOKEN, GetManifestModule());
- }
-
- CustomAttributeParser cap(pbAttr, cbAttr);
- if (FAILED(cap.ValidateProlog()))
- {
- THROW_BAD_FORMAT(BFA_BAD_CA_HEADER, GetManifestModule());
- }
-
- // Get the metadata key. It is not null terminated.
- LPCUTF8 key;
- ULONG cbKey;
- if (FAILED(cap.GetString(&key, &cbKey)))
- {
- THROW_BAD_FORMAT(BFA_BAD_CA_HEADER, GetManifestModule());
- }
-
- const LPCUTF8 szServiceable = "Serviceable";
- const ULONG cbServiceable = 11;
- if (cbKey != cbServiceable || strncmp(key, szServiceable, cbKey) != 0)
- {
- continue;
- }
-
- // Get the metadata value. It is not null terminated.
- if (FAILED(cap.GetString(&key, &cbKey)))
- {
- THROW_BAD_FORMAT(BFA_BAD_CA_HEADER, GetManifestModule());
- }
-
- const LPCUTF8 szTrue = "True";
- const ULONG cbTrue = 4;
- if (cbKey == cbTrue && strncmp(key, szTrue, cbKey) == 0)
- {
- return true;
- }
- }
-
- return false;
-}
-
-bool Assembly::IsExistingOobAssembly()
-{
- WRAPPER_NO_CONTRACT;
-
- return ExistingOobAssemblyList::Instance()->IsOnlist(this);
-}
-
-void Assembly::CheckDenyList(const SString &ssDisplayName)
-{
- STANDARD_VM_CONTRACT;
-
- StackSString ssKeyName(W("SOFTWARE\\Microsoft\\.NETFramework\\Policy\\DenyList\\"));
-
- ssKeyName.Append(ssDisplayName);
-
- RegKeyHolder hKey;
- LONG status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ssKeyName.GetUnicode(), 0, KEY_WOW64_64KEY | GENERIC_READ, &hKey);
-
- if (status != ERROR_SUCCESS)
- {
- return;
- }
-
- StackSString ssFwlink;
- HRESULT hr = Clr::Util::Reg::ReadStringValue(hKey, NULL, NULL, ssFwlink);
- if (FAILED(hr) || ssFwlink.GetCount() == 0)
- {
- ssFwlink.Set(W("http://go.microsoft.com/fwlink/?LinkID=286319"));
- }
-
- StackSString ssMessageTemplate;
- if(!ssMessageTemplate.LoadResource(CCompRC::Optional, IDS_EE_ASSEMBLY_ON_DENY_LIST))
- {
- ssMessageTemplate.Set(W("The assembly %1 that the application tried to load has a known vulnerability. Please go to %2 to find a fix for this issue."));
- }
-
- StackSString ssMessage;
- ssMessage.FormatMessage(FORMAT_MESSAGE_FROM_STRING, ssMessageTemplate.GetUnicode(), 0, 0, ssDisplayName, ssFwlink);
-
- ClrReportEvent(
- W(".NET Runtime"), // Event source
- EVENTLOG_ERROR_TYPE, // Type
- 0, // Category
- SecurityConfig, // Event ID
- NULL, // User SID
- ssMessage.GetUnicode()); // Message
-
- NewHolder<EEMessageException> pEx(new EEMessageException(kSecurityException, IDS_EE_ASSEMBLY_ON_DENY_LIST, ssDisplayName.GetUnicode(), ssFwlink.GetUnicode()));
- EEFileLoadException::Throw(m_pManifestFile, pEx->GetHR(), pEx);
-}
-
-BOOL IsReportableAssembly(PEAssembly *pPEAssembly)
-{
- STANDARD_VM_CONTRACT;
-
- // If the assembly could have used a native image, but did not, report the IL image
- BOOL fCanUseNativeImage = (pPEAssembly->HasHostAssembly() || pPEAssembly->IsContextLoad()) &&
- pPEAssembly->CanUseNativeImage() &&
- !IsNativeImageOptedOut(pPEAssembly->GetFusionAssemblyName());
-
- return fCanUseNativeImage;
-}
-
-BOOL Assembly::SupportsAutoNGenWorker()
-{
- STANDARD_VM_CONTRACT;
-
- PEAssembly *pPEAssembly = GetManifestFile();
-
- if (pPEAssembly->IsSourceGAC() && Fusion::Util::IsUnifiedAssembly(pPEAssembly->GetFusionAssemblyName()) == S_OK)
- {
- // Assemblies in the .NET Framework supports Auto NGen.
- return TRUE;
- }
-
- if (IsAfContentType_WindowsRuntime(GetFlags()))
- {
- // WinMD files support Auto NGen.
- return TRUE;
- }
-
- if (pPEAssembly->HasHostAssembly())
- {
- // Auto NGen is enabled on all Metro app assemblies.
- return TRUE;
- }
-
- if (pPEAssembly->IsSourceGAC())
- {
- // For non-framework assemblies in GAC, look for TargetFrameworkAttriute.
- const BYTE *pbAttr; // Custom attribute data as a BYTE*.
- ULONG cbAttr; // Size of custom attribute data.
- HRESULT hr = GetManifestImport()->GetCustomAttributeByName(GetManifestToken(), TARGET_FRAMEWORK_TYPE, (const void**)&pbAttr, &cbAttr);
- if (hr != S_OK)
- {
- return FALSE;
- }
-
- CustomAttributeParser cap(pbAttr, cbAttr);
- if (FAILED(cap.ValidateProlog()))
- {
- THROW_BAD_FORMAT(BFA_BAD_CA_HEADER, GetManifestModule());
- }
- LPCUTF8 lpTargetFramework;
- ULONG cbTargetFramework;
- if (FAILED(cap.GetString(&lpTargetFramework, &cbTargetFramework)))
- {
- THROW_BAD_FORMAT(BFA_BAD_CA_HEADER, GetManifestModule());
- }
-
- if (lpTargetFramework == NULL || cbTargetFramework == 0)
- {
- return FALSE;
- }
-
- SString ssTargetFramework(SString::Utf8, lpTargetFramework, cbTargetFramework);
-
- // Look for two special TargetFramework values that disables AutoNGen. To guard against future
- // variations of the string values, we do prefix matches.
- SString ssFramework40(SString::Literal, W(".NETFramework,Version=v4.0"));
- SString ssPortableLib(SString::Literal, W(".NETPortable,"));
- if (ssTargetFramework.BeginsWithCaseInsensitive(ssFramework40) || ssTargetFramework.BeginsWithCaseInsensitive(ssPortableLib))
- {
- return FALSE;
- }
-
- // If TargetFramework doesn't match one of the two special values, we enable Auto NGen.
- return TRUE;
- }
-
- return FALSE;
-}
-
-void Assembly::ReportAssemblyUse()
-{
- STANDARD_VM_CONTRACT;
-
- // Do not log if we don't have a global gac logger object
- if (g_pIAssemblyUsageLogGac != NULL)
- {
- // Only consider reporting for loads that could possibly use native images.
- PEAssembly *pPEAssembly = this->GetManifestFile();
- if (IsReportableAssembly(pPEAssembly) && !pPEAssembly->IsReportedToUsageLog())
- {
- // Do not log repeatedly
- pPEAssembly->SetReportedToUsageLog();
-
- ReleaseHolder<IAssemblyUsageLog> pRefCountedUsageLog;
- IAssemblyUsageLog *pUsageLog = NULL;
- if (SupportsAutoNGen())
- {
- if (pPEAssembly->IsSourceGAC())
- {
- pUsageLog = g_pIAssemblyUsageLogGac;
- }
- else if (pPEAssembly->HasHostAssembly())
- {
- UINT_PTR binderId;
- IfFailThrow(pPEAssembly->GetHostAssembly()->GetBinderID(&binderId));
- pRefCountedUsageLog = AssemblyUsageLogManager::GetUsageLogForBinder(binderId);
- pUsageLog = pRefCountedUsageLog;
- }
- }
-
- if (pUsageLog)
- {
- PEAssembly *pPEAssembly = GetManifestFile();
- StackSString name;
- // GAC Assemblies are reported by assembly name
- if (pUsageLog == g_pIAssemblyUsageLogGac)
- {
- this->GetDisplayName(name);
- }
- // Other assemblies (AppX...) are reported by file path
- else
- {
- name.Set(pPEAssembly->GetILimage()->GetPath().GetUnicode());
- }
-
- if (pPEAssembly->HasNativeImage())
- {
- if(!IsSystem())
- {
- // If the assembly used a native image, report it
- ReleaseHolder<PEImage> pNativeImage = pPEAssembly->GetNativeImageWithRef();
- pUsageLog->LogFile(name.GetUnicode(), pNativeImage->GetPath().GetUnicode(), ASSEMBLY_USAGE_LOG_FLAGS_NI);
- }
- }
- else
- {
- // If the assembly could have used a native image, but did not, report the IL image
- pUsageLog->LogFile(name.GetUnicode(), NULL, ASSEMBLY_USAGE_LOG_FLAGS_IL);
- }
- }
- }
- }
-}
-#endif // FEATURE_CORECLR && !CROSSGEN_COMPILE
#endif // #ifndef DACCESS_COMPILE
@@ -4750,11 +2720,7 @@ FriendAssemblyDescriptor::~FriendAssemblyDescriptor()
while (itFullAccessAssemblies.Next())
{
FriendAssemblyName_t *pFriendAssemblyName = static_cast<FriendAssemblyName_t *>(itFullAccessAssemblies.GetElement());
-#ifdef FEATURE_FUSION
- pFriendAssemblyName->Release();
-#else // FEATURE_FUSION
delete pFriendAssemblyName;
-#endif // FEATURE_FUSION
}
}
@@ -4839,9 +2805,6 @@ FriendAssemblyDescriptor *FriendAssemblyDescriptor::CreateFriendAssemblyDescript
// Create an AssemblyNameObject from the string.
FriendAssemblyNameHolder pFriendAssemblyName;
-#ifdef FEATURE_FUSION
- hr = CreateAssemblyNameObject(&pFriendAssemblyName, displayName.GetUnicode(), CANOF_PARSE_FRIEND_DISPLAY_NAME, NULL);
-#else // FEATURE_FUSION
StackScratchBuffer buffer;
pFriendAssemblyName = new FriendAssemblyName_t;
hr = pFriendAssemblyName->Init(displayName.GetUTF8(buffer));
@@ -4850,7 +2813,6 @@ FriendAssemblyDescriptor *FriendAssemblyDescriptor::CreateFriendAssemblyDescript
{
hr = pFriendAssemblyName->CheckFriendAssemblyName();
}
-#endif // FEATURE_FUSION
if (FAILED(hr))
{
@@ -4867,31 +2829,6 @@ FriendAssemblyDescriptor *FriendAssemblyDescriptor::CreateFriendAssemblyDescript
// CoreCLR does not have a valid scenario for strong-named assemblies requiring their dependencies
// to be strong-named as well.
-#if !defined(FEATURE_CORECLR)
- // If this assembly has a strong name, then its friends declarations need to have strong names too
- if (pAssembly->IsStrongNamed())
- {
-#ifdef FEATURE_FUSION
- DWORD dwSize = 0;
- if (SUCCEEDED(hr = pFriendAssemblyName->GetProperty(ASM_NAME_PUBLIC_KEY, NULL, &dwSize)))
- {
- // If this call succeeds with an empty buffer, then the supplied name doesn't have a public key.
- THROW_HR_ERROR_WITH_INFO(META_E_CA_FRIENDS_SN_REQUIRED, pAssembly);
- }
- else if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- IfFailThrow(hr);
- }
-#else // FEATURE_FUSION
- // Desktop crossgen comes here
- if (!pFriendAssemblyName->IsStrongNamed())
- {
- // If this call succeeds with an empty buffer, then the supplied name doesn't have a public key.
- THROW_HR_ERROR_WITH_INFO(META_E_CA_FRIENDS_SN_REQUIRED, pAssembly);
- }
-#endif // FEATURE_FUSION
- }
-#endif // !defined(FEATURE_CORECLR)
pFriendAssemblies->AddFriendAssembly(pFriendAssemblyName);
@@ -4954,23 +2891,14 @@ bool FriendAssemblyDescriptor::IsAssemblyOnList(PEAssembly *pAssembly, const Arr
}
CONTRACTL_END;
-#ifndef FEATURE_FUSION
AssemblySpec asmDef;
asmDef.InitializeSpec(pAssembly);
-#endif
ArrayList::ConstIterator itAssemblyNames = alAssemblyNames.Iterate();
while (itAssemblyNames.Next())
{
const FriendAssemblyName_t *pFriendAssemblyName = static_cast<const FriendAssemblyName_t *>(itAssemblyNames.GetElement());
-#ifdef FEATURE_FUSION
- // This is a const operation on the pointer, but Fusion is not const-correct.
- // @TODO - propigate const correctness through Fusion and remove this cast
- HRESULT hr = const_cast<FriendAssemblyName_t *>(pFriendAssemblyName)->IsEqual(pAssembly->GetFusionAssemblyName(), ASM_CMPF_DEFAULT);
- IfFailThrow(hr);
-#else
HRESULT hr = AssemblySpec::RefMatchesDef(pFriendAssemblyName, &asmDef) ? S_OK : S_FALSE;
-#endif
if (hr == S_OK)
{
@@ -4984,70 +2912,3 @@ bool FriendAssemblyDescriptor::IsAssemblyOnList(PEAssembly *pAssembly, const Arr
#endif // !DACCESS_COMPILE
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE) && !defined(DACCESS_COMPILE)
-
-ExistingOobAssemblyList::ExistingOobAssemblyList()
-{
- STANDARD_VM_CONTRACT;
-
- RegKeyHolder hKey;
- LONG status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, W("SOFTWARE\\Microsoft\\.NETFramework\\Policy\\Servicing"), 0, KEY_WOW64_64KEY | GENERIC_READ, &hKey);
- if (status != ERROR_SUCCESS)
- {
- return;
- }
-
- for (DWORD i = 0; ; i++)
- {
- WCHAR name[MAX_PATH_FNAME + 1];
- DWORD cchName = ARRAYSIZE(name);
- status = RegEnumKeyExW(hKey, i, name, &cchName, NULL, NULL, NULL, NULL);
-
- if (status == ERROR_NO_MORE_ITEMS)
- {
- break;
- }
-
- if (status == ERROR_SUCCESS)
- {
- NonVMComHolder<IAssemblyName> pAssemblyName;
- HRESULT hr = CreateAssemblyNameObject(&pAssemblyName, name, CANOF_PARSE_DISPLAY_NAME, NULL);
- if (SUCCEEDED(hr))
- {
- hr = m_alExistingOobAssemblies.Append(pAssemblyName.GetValue());
- if (SUCCEEDED(hr))
- {
- pAssemblyName.SuppressRelease();
- }
- }
- }
- }
-}
-
-bool ExistingOobAssemblyList::IsOnlist(Assembly *pAssembly)
-{
- STANDARD_VM_CONTRACT;
-
- ArrayList::Iterator itAssemblyNames = m_alExistingOobAssemblies.Iterate();
- while (itAssemblyNames.Next())
- {
- IAssemblyName *pAssemblyName = static_cast<IAssemblyName *>(itAssemblyNames.GetElement());
- HRESULT hr = pAssemblyName->IsEqual(pAssembly->GetFusionAssemblyName(), ASM_CMPF_DEFAULT);
- if (hr == S_OK)
- {
- return true;
- }
- }
-
- return false;
-}
-
-void ExistingOobAssemblyList::Init()
-{
- STANDARD_VM_CONTRACT;
-
- s_pInstance = new ExistingOobAssemblyList();
-}
-
-ExistingOobAssemblyList *ExistingOobAssemblyList::s_pInstance;
-#endif // !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE) && !defined(DACCESS_COMPILE)
diff --git a/src/vm/assembly.hpp b/src/vm/assembly.hpp
index 54bb03de96..0fdb9a248a 100644
--- a/src/vm/assembly.hpp
+++ b/src/vm/assembly.hpp
@@ -18,10 +18,6 @@
#include "ceeload.h"
#include "exceptmacros.h"
#include "clsload.hpp"
-#ifdef FEATURE_FUSION
-#include "fusion.h"
-#include "fusionbind.h"
-#endif
#include "eehash.h"
#include "listlock.h"
#include "iceefilegen.h"
@@ -122,10 +118,6 @@ public:
Assembly(BaseDomain *pDomain, PEAssembly *pFile, DebuggerAssemblyControlFlags debuggerFlags, BOOL fIsCollectible);
void Init(AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocator);
-#if defined(FEATURE_TRACELOGGING)
- void TelemetryLogTargetFrameworkAttribute();
-#endif // FEATURE_TRACELOGGING
-
void StartUnload();
void Terminate( BOOL signalProfiler = TRUE );
@@ -134,9 +126,6 @@ public:
BOOL IsSystem() { WRAPPER_NO_CONTRACT; return m_pManifestFile->IsSystem(); }
static Assembly *CreateDynamic(AppDomain *pDomain, CreateDynamicAssemblyArgs *args);
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- ReflectionModule *CreateDynamicModule(LPCWSTR szModuleName, LPCWSTR szFileName, BOOL fIsTransient, INT32* ptkFile = NULL);
-#endif
MethodDesc *GetEntryPoint();
@@ -241,17 +230,7 @@ public:
return ModuleIterator(this);
}
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- //****************************************************************************************
- //
- // Find the module
- Module* FindModule(PEFile *pFile, BOOL includeLoading = FALSE);
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
-#ifdef FEATURE_MIXEDMODE
- // Finds loading modules as well
- DomainFile* FindIJWDomainFile(HMODULE hMod, const SString &path);
-#endif
//****************************************************************************************
//
// Get the domain the assembly lives in.
@@ -291,9 +270,9 @@ public:
BOOL GetModuleZapFile(LPCWSTR name, SString &path);
-#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_CORESYSTEM)
BOOL AllowUntrustedCaller();
-#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#endif // defined(FEATURE_CORESYSTEM)
#ifdef LOGGING
LPCWSTR GetDebugName()
@@ -531,23 +510,7 @@ public:
void AddType(Module* pModule,
mdTypeDef cl);
void AddExportedType(mdExportedType cl);
-#ifndef FEATURE_CORECLR
- void PrepareSavingManifest(ReflectionModule *pAssemblyModule);
- mdFile AddFile(LPCWSTR wszFileName);
- void SetFileHashValue(mdFile tkFile, LPCWSTR wszFullFileName);
-#endif
mdAssemblyRef AddAssemblyRef(Assembly *refedAssembly, IMetaDataAssemblyEmit *pAssemEmitter = NULL, BOOL fUsePublicKeyToken = TRUE);
-#ifndef FEATURE_CORECLR
- mdExportedType AddExportedTypeOnDisk(LPCWSTR wszExportedType, mdToken tkImpl, mdToken tkTypeDef, CorTypeAttr flags);
- mdExportedType AddExportedTypeInMemory(LPCWSTR wszExportedType, mdToken tkImpl, mdToken tkTypeDef, CorTypeAttr flags);
- void AddStandAloneResource(LPCWSTR wszName, LPCWSTR wszDescription, LPCWSTR wszMimeType, LPCWSTR wszFileName, LPCWSTR wszFullFileName, int iAttribute);
- void SaveManifestToDisk(LPCWSTR wszFileName, int entrypoint, int fileKind, DWORD corhFlags, DWORD peFlags);
-#endif // FEATURE_CORECLR
-#ifndef FEATURE_CORECLR
- void AddDeclarativeSecurity(DWORD dwAction, void const *pValue, DWORD cbValue);
-
- IMetaDataAssemblyEmit *GetOnDiskMDAssemblyEmitter();
-#endif // FEATURE_CORECLR
//****************************************************************************************
@@ -581,10 +544,6 @@ public:
#ifdef FEATURE_LOADER_OPTIMIZATION
BOOL MissingDependenciesCheckDone();
void SetMissingDependenciesCheckDone();
-#ifdef FEATURE_FUSION
- void SetBindingClosure(IAssemblyBindingClosure* pClosure); // Addrefs. It is assumed the caller did not addref pClosure for us.
- IAssemblyBindingClosure* GetBindingClosure();
-#endif
#endif // FEATURE_LOADER_OPTIMIZATION
void SetDomainNeutral() { LIMITED_METHOD_CONTRACT; m_fIsDomainNeutral = TRUE; }
@@ -592,7 +551,7 @@ public:
BOOL IsSIMDVectorAssembly() { LIMITED_METHOD_DAC_CONTRACT; return m_fIsSIMDVectorAssembly; }
-#ifdef FEATURE_PREJIT
+#ifdef FEATURE_PREJIT
BOOL IsInstrumented();
BOOL IsInstrumentedHelper();
#endif // FEATURE_PREJIT
@@ -601,31 +560,6 @@ public:
HCEEFILE ceeFile);
HRESULT SignWithStrongName(LPCWSTR wszFileName);
-#ifdef FEATURE_FUSION
- IAssembly* GetFusionAssembly()
- {
- WRAPPER_NO_CONTRACT;
- return m_pManifestFile->GetFusionAssembly();
- }
-
- IAssemblyName* GetFusionAssemblyName()
- {
- WRAPPER_NO_CONTRACT;
- return m_pManifestFile->GetFusionAssemblyName();
- }
-
- IAssemblyName* GetFusionAssemblyNameNoCreate()
- {
- WRAPPER_NO_CONTRACT;
- return m_pManifestFile->GetFusionAssemblyNameNoCreate();
- }
-
- IHostAssembly* GetIHostAssembly()
- {
- WRAPPER_NO_CONTRACT;
- return m_pManifestFile->GetIHostAssembly();
- }
-#endif// FEATURE_FUSION
#ifdef FEATURE_COMINTEROP
// Get any cached ITypeLib* for the assembly.
@@ -672,10 +606,6 @@ public:
//****************************************************************************************
//
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- PEModule * LoadModule_AddRef(mdFile kFile, BOOL fLoadResource);
- PEModule * RaiseModuleResolveEvent_AddRef(LPCSTR szName, mdFile kFile);
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
static BOOL FileNotFound(HRESULT hr);
//****************************************************************************************
@@ -714,13 +644,6 @@ public:
IWinMDImport *GetManifestWinMDImport();
#endif
-#ifndef FEATURE_CORECLR
- BOOL SupportsAutoNGen()
- {
- WRAPPER_NO_CONTRACT;
- return m_fSupportsAutoNGen;
- }
-#endif
protected:
@@ -781,13 +704,6 @@ protected:
// Keep track of the vars that need to be freed.
short int m_FreeFlag;
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- // Hash of files in manifest by name to File token
- PTR_EEUtf8StringHashTable m_pAllowedFiles;
- // Critical section guarding m_pAllowedFiles
- Crst m_crstAllowedFiles;
-#endif
-
private:
//****************************************************************************************
@@ -797,15 +713,6 @@ private:
void CacheFriendAssemblyInfo();
-#ifndef FEATURE_CORECLR
- void GenerateBreadcrumbForServicing();
- void WriteBreadcrumb(const SString &ssDisplayName);
- bool HasServiceableAttribute();
- bool IsExistingOobAssembly();
- void CheckDenyList(const SString &ssDisplayName);
-
- BOOL SupportsAutoNGenWorker();
-#endif
PTR_BaseDomain m_pDomain; // Parent Domain
PTR_ClassLoader m_pClassLoader; // Single Loader
@@ -856,9 +763,6 @@ private:
BOOL m_fIsDomainNeutral;
#ifdef FEATURE_LOADER_OPTIMIZATION
BOOL m_bMissingDependenciesCheckDone;
-#ifdef FEATURE_FUSION
- IAssemblyBindingClosure * m_pBindingClosure;
-#endif
#endif // FEATURE_LOADER_OPTIMIZATION
DebuggerAssemblyControlFlags m_debuggerFlags;
@@ -870,9 +774,15 @@ private:
DWORD m_dwReliabilityContract;
-#ifndef FEATURE_CORECLR
- BOOL m_fSupportsAutoNGen;
-#endif
+#ifdef FEATURE_PREJIT
+ enum IsInstrumentedStatus {
+ IS_INSTRUMENTED_UNSET = 0,
+ IS_INSTRUMENTED_FALSE = 1,
+ IS_INSTRUMENTED_TRUE = 2,
+ };
+ IsInstrumentedStatus m_isInstrumentedStatus;
+#endif // FEATURE_PREJIT
+
};
typedef Assembly::ModuleIterator ModuleIterator;
@@ -923,25 +833,6 @@ public:
return IsAssemblyOnList(pAccessingAssembly, m_alFullAccessFriendAssemblies);
}
-#ifndef FEATURE_CORECLR
- //------------------------------------------------------------------------------
- // It is undesirable to reintroduce the concept of inquiring about friendship without specifying a member or type
- // but necessary for TP. In case of doubt, it's safer to return "true" as this won't affect
- // correctness (but might cause unnecessary ngen's when updating assemblies.)
- //------------------------------------------------------------------------------
- bool MightGrantFriendAccessTo(PEAssembly *pAccessingAssembly)
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- PRECONDITION(CheckPointer(pAccessingAssembly));
- }
- CONTRACTL_END;
-
- return IsAssemblyOnList(pAccessingAssembly, m_alFullAccessFriendAssemblies);
- }
-#endif // !FEATURE_CORECLR
bool IgnoresAccessChecksTo(Assembly *pAccessedAssembly)
{
@@ -949,13 +840,8 @@ public:
}
private:
-#ifdef FEATURE_FUSION
- typedef IAssemblyName FriendAssemblyName_t;
- typedef NonVMComHolder<IAssemblyName> FriendAssemblyNameHolder;
-#else // FEATURE_FUSION
typedef AssemblySpec FriendAssemblyName_t;
typedef NewHolder<AssemblySpec> FriendAssemblyNameHolder;
-#endif // FEATURE_FUSION
ArrayList m_alFullAccessFriendAssemblies; // Friend assemblies which have access to all internals
ArrayList m_subjectAssemblies; // Subject assemblies which we will not perform access checks against
@@ -977,25 +863,5 @@ private:
#endif // !DACCESS_COMPILE
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-class ExistingOobAssemblyList
-{
-public:
-#ifndef DACCESS_COMPILE
- ExistingOobAssemblyList();
-
- bool IsOnlist(Assembly *pAssembly);
-
- static void Init();
- static ExistingOobAssemblyList *Instance() { return s_pInstance; }
-#endif
-
-private:
- ArrayList m_alExistingOobAssemblies;
-
- // The single instance of this class:
- static ExistingOobAssemblyList *s_pInstance;
-};
-#endif // !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
#endif
diff --git a/src/vm/assemblyname.cpp b/src/vm/assemblyname.cpp
index d7689e8b88..90e2a467e1 100644
--- a/src/vm/assemblyname.cpp
+++ b/src/vm/assemblyname.cpp
@@ -22,9 +22,6 @@
#include "assemblyname.hpp"
#include "security.h"
#include "field.h"
-#ifdef FEATURE_FUSION
-#include "fusion.h"
-#endif
#include "strongname.h"
#include "eeconfig.h"
@@ -62,15 +59,11 @@ FCIMPL1(Object*, AssemblyNameNative::GetFileInformation, StringObject* filenameU
EX_TRY
{
-#ifdef FEATURE_CORECLR
// Allow AssemblyLoadContext.GetAssemblyName for native images on CoreCLR
if (pImage->HasNTHeaders() && pImage->HasCorHeader() && pImage->HasNativeHeader())
pImage->VerifyIsNIAssembly();
else
pImage->VerifyIsAssembly();
-#else
- pImage->VerifyIsAssembly();
-#endif
}
EX_CATCH
{
@@ -84,9 +77,6 @@ FCIMPL1(Object*, AssemblyNameNative::GetFileInformation, StringObject* filenameU
AssemblySpec spec;
spec.InitializeSpec(TokenFromRid(mdtAssembly,1),pImage->GetMDImport(),NULL,TRUE);
-#ifndef FEATURE_CORECLR
- spec.SetCodeBase(sUrl);
-#endif
spec.AssemblyNameInit(&gc.result, pImage);
HELPER_METHOD_FRAME_END();
@@ -113,14 +103,10 @@ FCIMPL1(Object*, AssemblyNameNative::ToString, Object* refThisUNSAFE)
spec.InitializeSpec(&(pThread->m_MarshalAlloc), (ASSEMBLYNAMEREF*) &pThis, FALSE, FALSE);
StackSString name;
-#ifndef FEATURE_FUSION
spec.GetFileOrDisplayName(ASM_DISPLAYF_VERSION |
ASM_DISPLAYF_CULTURE |
ASM_DISPLAYF_PUBLIC_KEY_TOKEN,
name);
-#else
- spec.GetFileOrDisplayName(0, name);
-#endif // FEATURE_FUSION
pObj = (OBJECTREF) StringObject::NewString(name);
@@ -168,52 +154,6 @@ FCIMPL1(Object*, AssemblyNameNative::GetPublicKeyToken, Object* refThisUNSAFE)
}
FCIMPLEND
-#ifndef FEATURE_CORECLR
-FCIMPL1(Object*, AssemblyNameNative::EscapeCodeBase, StringObject* filenameUNSAFE)
-{
- FCALL_CONTRACT;
-
- STRINGREF rv = NULL;
- STRINGREF filename = (STRINGREF) filenameUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_1(filename);
-
- LPWSTR pCodeBase = NULL;
- DWORD dwCodeBase = 0;
- CQuickBytes qb;
-
- if (filename != NULL) {
- WCHAR* pString;
- int iString;
- filename->RefInterpretGetStringValuesDangerousForGC(&pString, &iString);
- dwCodeBase = (DWORD) iString;
- pCodeBase = (LPWSTR) qb.AllocThrows((++dwCodeBase) * sizeof(WCHAR));
- memcpy(pCodeBase, pString, dwCodeBase*sizeof(WCHAR));
- }
-
- if(pCodeBase) {
- CQuickBytes qb2;
- DWORD dwEscaped = 1;
-
- DWORD flags = 0;
- if (RunningOnWin7())
- flags |= URL_ESCAPE_AS_UTF8;
-
- UrlEscape(pCodeBase, (LPWSTR) qb2.Ptr(), &dwEscaped, flags);
-
- LPWSTR result = (LPWSTR)qb2.AllocThrows((++dwEscaped) * sizeof(WCHAR));
- HRESULT hr = UrlEscape(pCodeBase, result, &dwEscaped, flags);
-
- if (SUCCEEDED(hr))
- rv = StringObject::NewString(result);
- else
- COMPlusThrowHR(hr);
- }
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(rv);
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
FCIMPL4(void, AssemblyNameNative::Init, Object * refThisUNSAFE, OBJECTREF * pAssemblyRef, CLR_BOOL fForIntrospection, CLR_BOOL fRaiseResolveEvent)
{
@@ -262,52 +202,4 @@ FCIMPL4(void, AssemblyNameNative::Init, Object * refThisUNSAFE, OBJECTREF * pAss
}
FCIMPLEND
-/// "parse" tells us to parse the simple name of the assembly as if it was the full name
-/// almost never the right thing to do, but needed for compat
-/* static */
-FCIMPL3(FC_BOOL_RET, AssemblyNameNative::ReferenceMatchesDefinition, AssemblyNameBaseObject* refUNSAFE, AssemblyNameBaseObject* defUNSAFE, CLR_BOOL fParse)
-{
- FCALL_CONTRACT;
- struct _gc
- {
- ASSEMBLYNAMEREF pRef;
- ASSEMBLYNAMEREF pDef;
- } gc;
- gc.pRef = (ASSEMBLYNAMEREF)ObjectToOBJECTREF (refUNSAFE);
- gc.pDef = (ASSEMBLYNAMEREF)ObjectToOBJECTREF (defUNSAFE);
-
- BOOL result = FALSE;
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
-
- Thread *pThread = GetThread();
-
- CheckPointHolder cph(pThread->m_MarshalAlloc.GetCheckpoint()); //hold checkpoint for autorelease
-
- if (gc.pRef == NULL)
- COMPlusThrow(kArgumentNullException, W("ArgumentNull_AssemblyName"));
- if (gc.pDef == NULL)
- COMPlusThrow(kArgumentNullException, W("ArgumentNull_AssemblyName"));
-
- AssemblySpec refSpec;
- refSpec.InitializeSpec(&(pThread->m_MarshalAlloc), (ASSEMBLYNAMEREF*) &gc.pRef, fParse, FALSE);
-
- AssemblySpec defSpec;
- defSpec.InitializeSpec(&(pThread->m_MarshalAlloc), (ASSEMBLYNAMEREF*) &gc.pDef, fParse, FALSE);
-
-#ifdef FEATURE_FUSION
- SafeComHolder<IAssemblyName> pRefName (NULL);
- IfFailThrow(refSpec.CreateFusionName(&pRefName, FALSE));
-
- SafeComHolder <IAssemblyName> pDefName (NULL);
- IfFailThrow(defSpec.CreateFusionName(&pDefName, FALSE));
-
- // Order matters: Ref->IsEqual(Def)
- result = (S_OK == pRefName->IsEqual(pDefName, ASM_CMPF_IL_ALL));
-#else
- result=AssemblySpec::RefMatchesDef(&refSpec,&defSpec);
-#endif
- HELPER_METHOD_FRAME_END();
- FC_RETURN_BOOL(result);
-}
-FCIMPLEND
diff --git a/src/vm/assemblyname.hpp b/src/vm/assemblyname.hpp
index 2d1db9bef4..41e085cb24 100644
--- a/src/vm/assemblyname.hpp
+++ b/src/vm/assemblyname.hpp
@@ -24,7 +24,6 @@ public:
static FCDECL1(Object*, GetPublicKeyToken, Object* refThisUNSAFE);
static FCDECL1(Object*, EscapeCodeBase, StringObject* filenameUNSAFE);
static FCDECL4(void, Init, Object * refThisUNSAFE, OBJECTREF * pAssemblyRef, CLR_BOOL fForIntrospection, CLR_BOOL fRaiseResolveEvent);
- static FCDECL3(FC_BOOL_RET, ReferenceMatchesDefinition, AssemblyNameBaseObject* refUNSAFE, AssemblyNameBaseObject* defUNSAFE, CLR_BOOL fParse);
};
#endif // _AssemblyName_H
diff --git a/src/vm/assemblynamesconfigfactory.cpp b/src/vm/assemblynamesconfigfactory.cpp
deleted file mode 100644
index ed5da9679b..0000000000
--- a/src/vm/assemblynamesconfigfactory.cpp
+++ /dev/null
@@ -1,264 +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.
-// AssemblyNamesConfigFactory.cpp
-//
-
-//
-//
-// Parses XML files and adding runtime entries to assembly list
-// Abstract, derived classes need to override AddAssemblyName
-#include "common.h"
-#include "common.h"
-#include <xmlparser.h>
-#include <objbase.h>
-#include "parse.h"
-#include "assemblynamesconfigfactory.h"
-
-
-#define ISWHITE(ch) ((ch) >= 0x09 && (ch) <= 0x0D || (ch) == 0x20)
-
-#define CONST_STRING_AND_LEN(str) str, NumItems(str)-1
-
-extern int EEXMLStringCompare(const WCHAR *pStr1,
- DWORD cchStr1,
- const WCHAR *pStr2,
- DWORD cchStr2);
-extern HRESULT VersionFromString(LPCWSTR wzVersion, WORD *pwVerMajor, WORD *pwVerMinor,
- WORD *pwVerBld, WORD *pwVerRev);
-extern HRESULT MapProcessorArchitectureToPEKIND(LPCWSTR pwzProcArch, PEKIND *pe);
-
-AssemblyNamesConfigFactory::AssemblyNamesConfigFactory()
-{
- LIMITED_METHOD_CONTRACT;
- m_pAssemblyName = NULL;
- m_bCurrentEntryInvalid = TRUE;
- m_dwCurrentElementDepth = 0;
- m_dwProperty = ASM_NAME_MAX_PARAMS;
-}
-
-AssemblyNamesConfigFactory::~AssemblyNamesConfigFactory()
-{
- LIMITED_METHOD_CONTRACT;
-}
-
-
-HRESULT STDMETHODCALLTYPE AssemblyNamesConfigFactory::NotifyEvent(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ XML_NODEFACTORY_EVENT iEvt)
-{
- LIMITED_METHOD_CONTRACT;
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE AssemblyNamesConfigFactory::BeginChildren(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ XML_NODE_INFO __RPC_FAR *pNodeInfo)
-{
- LIMITED_METHOD_CONTRACT;
- m_dwCurrentElementDepth ++;
-
- return S_OK;
-}
-
-//---------------------------------------------------------------------------
-HRESULT STDMETHODCALLTYPE AssemblyNamesConfigFactory::EndChildren(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ BOOL fEmptyNode,
- /* [in] */ XML_NODE_INFO __RPC_FAR *pNodeInfo)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- EX_TRY
- {
- if (m_dwCurrentElementDepth == 1 && m_pAssemblyName != NULL)
- {
- if (!m_bCurrentEntryInvalid)
- {
- // publish
- AddAssemblyName(m_pAssemblyName);
- };
- m_pAssemblyName->Release();
- m_pAssemblyName = NULL;
- }
-
- if (!fEmptyNode)
- m_dwCurrentElementDepth --;
- }
- EX_CATCH_HRESULT(hr);
- return hr;
-}
-
-
-
-HRESULT STDMETHODCALLTYPE AssemblyNamesConfigFactory::CreateNode(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ PVOID pNode,
- /* [in] */ USHORT cNumRecs,
- /* [in] */ XML_NODE_INFO* __RPC_FAR * __RPC_FAR apNodeInfo)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END;
-
- if(m_dwCurrentElementDepth > 1)
- return S_OK;
-
- HRESULT hr = S_OK;
-
- for(DWORD i = 0; i < cNumRecs; i++) {
- CONTRACT_VIOLATION(ThrowsViolation); // Lots of stuff in here throws!
-
- if(apNodeInfo[i]->dwType == XML_ELEMENT ||
- apNodeInfo[i]->dwType == XML_ATTRIBUTE ||
- apNodeInfo[i]->dwType == XML_PCDATA)
- {
-
- DWORD dwStringSize = apNodeInfo[i]->ulLen;
- LPWSTR pszString = (WCHAR*) apNodeInfo[i]->pwcText;
- // Trim the value
-
- // we should never decrement lgth if it's 0, because it's unsigned
-
- for(;*pszString && ISWHITE(*pszString) && dwStringSize>0; pszString++, dwStringSize--);
- while( dwStringSize > 0 && ISWHITE(pszString[dwStringSize-1]))
- dwStringSize--;
- switch(apNodeInfo[i]->dwType)
- {
- case XML_ELEMENT :
- if(EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("assemblyIdentity"))) == 0)
- {
- // new entry
- _ASSERTE(m_pAssemblyName == NULL);
- IfFailRet(CreateAssemblyNameObject(&m_pAssemblyName, NULL,0,NULL));
- m_bCurrentEntryInvalid = FALSE;
- }
- else
- {
- m_bCurrentEntryInvalid = TRUE;
- }
-
- break;
-
-
- case XML_ATTRIBUTE :
- if(m_bCurrentEntryInvalid)
- break;
-
- if(EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("name"))) == 0)
- {
- m_dwProperty = ASM_NAME_NAME;
- }
- else
- if(EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("version"))) == 0)
- {
- m_dwProperty = ASM_NAME_MAJOR_VERSION;
- }
- else
- if(EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("publicKeyToken"))) == 0)
- {
- m_dwProperty = ASM_NAME_PUBLIC_KEY_TOKEN;
- }
- else
- if(EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("processorArchitecture"))) == 0)
- {
- m_dwProperty = ASM_NAME_ARCHITECTURE;
- }
- else
- {
- m_bCurrentEntryInvalid = TRUE;
- }
- break;
-
-
- case XML_PCDATA :
- if(m_bCurrentEntryInvalid)
- break;
-
- _ASSERTE(m_pAssemblyName!= NULL); // can only be null if m_bCurrentEntryInvalid
- switch(m_dwProperty)
- {
- case ASM_NAME_NAME:
- {
- StackSString s(pszString,dwStringSize);
- // takes number of bytes, thus *2
- IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_NAME, LPCWSTR(s), (dwStringSize+1)*sizeof(WCHAR)));
- }
- break;
- case ASM_NAME_MAJOR_VERSION:
- {
- StackSString s(pszString,dwStringSize);
- WORD wVerMajor = 0;
- WORD wVerMinor = 0;
- WORD wVerBld = 0;
- WORD wVerRev = 0;
- if (SUCCEEDED(VersionFromString(s, &wVerMajor, &wVerMinor, &wVerBld, &wVerRev)))
- {
- IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_MAJOR_VERSION, &wVerMajor, sizeof(WORD)));
- IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_MINOR_VERSION, &wVerMinor, sizeof(WORD)));
- IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_BUILD_NUMBER, &wVerBld, sizeof(WORD)));
- IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_REVISION_NUMBER, &wVerRev, sizeof(WORD)));
- }
- else
- m_bCurrentEntryInvalid = TRUE;
-
- }
- break;
- case ASM_NAME_ARCHITECTURE:
- {
- StackSString s(pszString,dwStringSize);
- PEKIND PeKind = peNone;
- if(SUCCEEDED(MapProcessorArchitectureToPEKIND(s, &PeKind)))
- {
- IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_ARCHITECTURE, (LPBYTE) &PeKind, sizeof(PeKind)));
- }
- else
- {
- m_bCurrentEntryInvalid = TRUE;
- }
-
- }
- break;
- case ASM_NAME_PUBLIC_KEY_TOKEN:
- {
- if(EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("null"))) == 0)
- {
- IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_NULL_PUBLIC_KEY_TOKEN, NULL, 0));
- }
- else
- {
- if (dwStringSize % 2 != 0)
- return FUSION_E_INVALID_NAME;
-
- DWORD cbProp = dwStringSize / 2;
- NewHolder<BYTE> pbProp = new BYTE[cbProp];
- CParseUtils::UnicodeHexToBin(pszString, dwStringSize, pbProp); //????
- IfFailRet(m_pAssemblyName->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, pbProp, cbProp));
- }
- break;
- }
-
- default:
- _ASSERTE(!"Invalid format");
- m_bCurrentEntryInvalid = TRUE;
- break;
- }
- break;
- }
-
- }
- }
- return S_OK;
-}
diff --git a/src/vm/assemblynamesconfigfactory.h b/src/vm/assemblynamesconfigfactory.h
deleted file mode 100644
index 234adb9208..0000000000
--- a/src/vm/assemblynamesconfigfactory.h
+++ /dev/null
@@ -1,72 +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.
-// AssemblyNamesConfigFactory.h
-//
-
-//
-//
-// Parses XML files and adding runtime entries to assembly list
-// Abstract, derived classes need to override AddAssemblyName
-
-
-#ifndef ASSEMBLYNAMESCONFIGFACTORY_H
-#define ASSEMBLYNAMESCONFIGFACTORY_H
-
-#include "unknwn.h"
-#include "../xmlparser/_reference.h"
-#include "../xmlparser/_unknown.h"
-
-
-class AssemblyNamesConfigFactory : public _unknown<IXMLNodeFactory, &IID_IXMLNodeFactory>
-{
-
-public:
- AssemblyNamesConfigFactory ();
- ~AssemblyNamesConfigFactory ();
- HRESULT STDMETHODCALLTYPE NotifyEvent(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ XML_NODEFACTORY_EVENT iEvt);
-
- HRESULT STDMETHODCALLTYPE BeginChildren(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ XML_NODE_INFO* __RPC_FAR pNodeInfo);
-
- HRESULT STDMETHODCALLTYPE EndChildren(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ BOOL fEmptyNode,
- /* [in] */ XML_NODE_INFO* __RPC_FAR pNodeInfo);
-
- HRESULT STDMETHODCALLTYPE Error(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ HRESULT hrErrorCode,
- /* [in] */ USHORT cNumRecs,
- /* [in] */ XML_NODE_INFO* __RPC_FAR * __RPC_FAR apNodeInfo)
- {
- LIMITED_METHOD_CONTRACT;
- /*
- UNUSED(pSource);
- UNUSED(hrErrorCode);
- UNUSED(cNumRecs);
- UNUSED(apNodeInfo);
- */
- return hrErrorCode;
- }
-
- HRESULT STDMETHODCALLTYPE CreateNode(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ PVOID pNodeParent,
- /* [in] */ USHORT cNumRecs,
- /* [in] */ XML_NODE_INFO* __RPC_FAR * __RPC_FAR apNodeInfo);
-
- virtual void AddAssemblyName(IAssemblyName*) = 0;
-protected:
- IAssemblyName* m_pAssemblyName;
- BOOL m_bCurrentEntryInvalid;
- DWORD m_dwCurrentElementDepth;
- DWORD m_dwProperty;
-
-};
-
-
-#endif
diff --git a/src/vm/assemblynative.cpp b/src/vm/assemblynative.cpp
index f372bcb349..b9079ec06a 100644
--- a/src/vm/assemblynative.cpp
+++ b/src/vm/assemblynative.cpp
@@ -18,11 +18,6 @@
#include <shlwapi.h>
#include <stdlib.h>
-#ifdef FEATURE_FUSION
-#include "actasm.h"
-#include "appctx.h"
-#include "asm.h"
-#endif
#include "assemblynative.hpp"
#include "dllimport.h"
#include "field.h"
@@ -33,109 +28,12 @@
#include "interoputil.h"
#include "frames.h"
#include "typeparse.h"
-#ifdef FEATURE_REMOTING
-#include "appdomainhelper.h"
-#endif
#include "stackprobe.h"
-#ifdef FEATURE_FUSION
-#include "dbglog.h"
-#include "bindinglog.hpp"
-#include "policy.h"
-#endif
-#ifdef FEATURE_CORECLR
#include "appdomainnative.hpp"
#include "../binder/inc/clrprivbindercoreclr.h"
-#endif // FEATURE_CORECLR
-#ifndef FEATURE_CORECLR
-#include "assemblynativeresource.h"
-#endif // !FEATURE_CORECLR
-#if !defined(FEATURE_CORECLR)
-#include "clrprivbinderloadfile.h"
-#endif
-
-
-#ifdef FEATURE_FUSION
-//----------------------------------------------------------------------------------------------------
-// Allows managed code in mscorlib to find out whether an assembly name corresponds to mscorlib,
-// a .NET Framework assembly found in the unification list (see fxretarget.h), or a portable assembly (see portabilityPolicy.cpp)
-// See Fusion::Util::IsAnyFrameworkAssembly for more details.
-// The NGEN task uses this function (via System.Reflection.RuntimeAssembly.IsFrameworkAssembly)
-FCIMPL1(FC_BOOL_RET, AssemblyNative::IsFrameworkAssembly, AssemblyNameBaseObject* refAssemblyNameUNSAFE)
-{
- FCALL_CONTRACT;
-
- struct _gc
- {
- ASSEMBLYNAMEREF assemblyName;
- } gc;
- gc.assemblyName = (ASSEMBLYNAMEREF) refAssemblyNameUNSAFE;
-
- BOOL bIsFxAssembly = FALSE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
- AssemblySpec spec;
-
- Thread *pThread = GetThread();
- CheckPointHolder cph(pThread->m_MarshalAlloc.GetCheckpoint()); //hold checkpoint for autorelease
-
- spec.InitializeSpec(&(pThread->m_MarshalAlloc),
- &gc.assemblyName,
- FALSE, /*fIsStringized*/
- FALSE /*fForIntrospection*/
- );
- ReleaseHolder<IAssemblyName> pIAssemblyName;
- IfFailThrow(spec.CreateFusionName(&pIAssemblyName,FALSE));
-
- bIsFxAssembly = (IfFailThrow(Fusion::Util::IsAnyFrameworkAssembly(pIAssemblyName)) == S_OK);
- HELPER_METHOD_FRAME_END();
-
- FC_RETURN_BOOL(bIsFxAssembly);
-}
-FCIMPLEND
-#endif // FEATURE_FUSION
-
-#ifdef FEATURE_FUSION
-//----------------------------------------------------------------------------------------------------
-FCIMPL1(FC_BOOL_RET, AssemblyNative::IsNewPortableAssembly, AssemblyNameBaseObject* refAssemblyNameUNSAFE)
-{
- FCALL_CONTRACT;
-
- struct _gc
- {
- ASSEMBLYNAMEREF assemblyName;
- } gc;
- gc.assemblyName = (ASSEMBLYNAMEREF) refAssemblyNameUNSAFE;
-
- BOOL fIsPortable = FALSE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
-
- AssemblySpec spec;
-
- Thread *pThread = GetThread();
- CheckPointHolder cph(pThread->m_MarshalAlloc.GetCheckpoint()); //hold checkpoint for autorelease
-
- {
- GCX_COOP();
- spec.InitializeSpec(&(pThread->m_MarshalAlloc),
- &gc.assemblyName,
- FALSE, /*fIsStringized*/
- FALSE /*fForIntrospection*/);
- }
-
- ReleaseHolder<IAssemblyName> pIAssemblyName;
- IfFailThrow(spec.CreateFusionName(&pIAssemblyName,FALSE));
-
- fIsPortable = (IfFailThrow(Fusion::Util::IsNewPortableAssembly(pIAssemblyName)) == S_OK);
- HELPER_METHOD_FRAME_END();
-
- FC_RETURN_BOOL(fIsPortable);
-}
-FCIMPLEND
-#endif // FEATURE_FUSION
FCIMPL10(Object*, AssemblyNative::Load, AssemblyNameBaseObject* assemblyNameUNSAFE,
StringObject* codeBaseUNSAFE,
@@ -243,7 +141,6 @@ FCIMPL10(Object*, AssemblyNative::Load, AssemblyNameBaseObject* assemblyNameUNSA
if (pParentAssembly != NULL)
spec.SetParentAssembly(pParentAssembly);
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
// Have we been passed the reference to the binder against which this load should be triggered?
// If so, then use it to set the fallback load context binder.
if (ptrLoadContextBinder != NULL)
@@ -258,7 +155,6 @@ FCIMPL10(Object*, AssemblyNative::Load, AssemblyNameBaseObject* assemblyNameUNSA
PEFile *pRefAssemblyManifestFile = pRefAssembly->GetManifestFile();
spec.SetFallbackLoadContextBinderForRequestingAssembly(pRefAssemblyManifestFile->GetFallbackLoadContextBinder());
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
AssemblyLoadSecurity loadSecurity;
loadSecurity.m_pAdditionalEvidence = &gc.security;
@@ -320,12 +216,6 @@ Assembly* AssemblyNative::LoadFromBuffer(BOOL fForIntrospection, const BYTE* pAs
if (pAssemblyData == NULL)
COMPlusThrow(kArgumentNullException, W("ArgumentNull_Array"));
-#ifndef FEATURE_CORECLR
- // Event Tracing for Windows is used to log data for performance and functional testing purposes.
- // The events in this function are used to help measure the performance of assembly loading as a whole when loading from a buffer.
- FireEtwLoaderPhaseStart(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderDynamicLoad, NULL, NULL, GetClrInstanceId());
-#endif // FEATURE_CORECLR
-
if (fForIntrospection) {
if (!GetThread()->GetDomain()->IsVerificationDomain())
GetThread()->GetDomain()->SetIllegalVerificationDomain();
@@ -347,35 +237,6 @@ Assembly* AssemblyNative::LoadFromBuffer(BOOL fForIntrospection, const BYTE* pAs
if (pCallersAssembly == NULL) {
pCallersAssembly = SystemDomain::System()->SystemAssembly();
} else {
-#ifdef FEATURE_CAS_POLICY
- // If no evidence was provided to the Assembly.Load(byte[]) call,
- // we want to inherit the evidence from the security context source
- if (fPropagateIdentity) {
- ISecurityDescriptor *pSecDesc = NULL;
- if (securityContextSource == kCurrentAppDomain) {
- pSecDesc = pCallersDomain->GetSecurityDescriptor();
- }
- else {
- _ASSERTE(securityContextSource == kCurrentAssembly);
- pSecDesc = pCallersAssembly->GetSecurityDescriptor(pCallersDomain);
- }
-
- ENTER_DOMAIN_PTR(pSecDesc->GetDomain(),ADV_RUNNINGIN)
- {
- gc.orefSecurity = pSecDesc->GetEvidence();
- }
- END_DOMAIN_TRANSITION;
-
- // Caller may be in another appdomain context, in which case we'll
- // need to marshal/unmarshal the evidence across.
-#ifdef FEATURE_REMOTING // should not happenwithout remoting
- if (pCallersDomain != GetAppDomain())
- gc.orefSecurity = AppDomainHelper::CrossContextCopyFrom(pCallersDomain->GetId(), &gc.orefSecurity);
-#else
- _ASSERTE(pCallersDomain == GetAppDomain());
-#endif
- }
-#endif // FEATURE_CAS_POLICY
}
if ((COUNT_T)uAssemblyLength !=uAssemblyLength) // overflow
@@ -388,13 +249,6 @@ Assembly* AssemblyNative::LoadFromBuffer(BOOL fForIntrospection, const BYTE* pAs
CLRPrivBinderLoadFile* pBinderToUse = NULL;
-#if !defined(FEATURE_CORECLR)
- if (GetAppDomain()->HasLoadContextHostBinder())
- {
- pBinderToUse = CLRPrivBinderLoadFile::GetOrCreateBinder();
- }
-#endif // !FEATURE_CORECLR
-
pFile = PEAssembly::OpenMemory(pCallersAssembly->GetManifestFile(),
pAssemblyData, (COUNT_T)uAssemblyLength,
fForIntrospection,
@@ -409,53 +263,15 @@ Assembly* AssemblyNative::LoadFromBuffer(BOOL fForIntrospection, const BYTE* pAs
{
DWORD dwSpecialFlags = 0;
-#ifdef FEATURE_CAS_POLICY
- if (securityContextSource == kCurrentAssembly)
- {
- IAssemblySecurityDescriptor *pCallersSecDesc = pCallersAssembly->GetSecurityDescriptor(pCallersDomain);
- gc.granted = pCallersSecDesc->GetGrantedPermissionSet( &(gc.denied));
- dwSpecialFlags = pCallersSecDesc->GetSpecialFlags();
-
- // If we're going to inherit the grant set of an anonymously hosted dynamic method, it will be
- // full trust/transparent. In that case, we should demand full trust.
- if(pCallersAssembly != NULL && pCallersDomain != NULL && pCallersAssembly->GetDomainAssembly(pCallersDomain) == pCallersDomain->GetAnonymouslyHostedDynamicMethodsAssembly())
- {
- loadSecurity.m_fPropagatingAnonymouslyHostedDynamicMethodGrant = true;
- }
- }
- else
-#endif // FEATURE_CAS_POLICY
{
IApplicationSecurityDescriptor *pDomainSecDesc = pCallersDomain->GetSecurityDescriptor();
-#ifdef FEATURE_CAS_POLICY
- // We only want to propigate the identity of homogenous domains, since heterogenous domains tend
- // to be fully trusted even if they are housing partially trusted code - which could lead to an
- // elevation of privilege if we allow the grant set to be pushed to assemblies partially trusted
- // code is loading.
- if (!pDomainSecDesc->IsHomogeneous())
- {
- COMPlusThrow(kNotSupportedException, W("NotSupported_SecurityContextSourceAppDomainInHeterogenous"));
- }
-#endif // FEATURE_CAS_POLICY
gc.granted = pDomainSecDesc->GetGrantedPermissionSet();
dwSpecialFlags = pDomainSecDesc->GetSpecialFlags();
}
-#ifdef FEATURE_REMOTING
- // Caller may be in another appdomain context, in which case we'll need to marshal/unmarshal the grant
- // and deny sets across.
- if (pCallersDomain != GetAppDomain())
- {
- gc.granted = AppDomainHelper::CrossContextCopyFrom(pCallersDomain->GetId(), &(gc.granted));
- if (gc.denied != NULL)
- {
- gc.denied = AppDomainHelper::CrossContextCopyFrom(pCallersDomain->GetId(), &(gc.denied));
- }
- }
-#endif // FEATURE_REMOTING
// Instead of resolving policy, the loader should use an inherited grant set
loadSecurity.m_pGrantSet = &gc.granted;
@@ -483,30 +299,7 @@ Assembly* AssemblyNative::LoadFromBuffer(BOOL fForIntrospection, const BYTE* pAs
// This applies to both Desktop CLR and CoreCLR, with or without fusion.
BOOL fIsSameAssembly = (pAssembly->GetManifestFile()->GetILimage() == pFile->GetILimage());
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
- if (fForIntrospection)
- {
- IAssemblyName * pIAssemblyName = pAssembly->GetFusionAssemblyName();
- AppDomain::AssemblyIterator i = GetAppDomain()->IterateAssembliesEx(
- (AssemblyIterationFlags)(kIncludeLoaded | kIncludeIntrospection));
- CollectibleAssemblyHolder<DomainAssembly *> pDomainAssembly;
-
- while (i.Next(pDomainAssembly.This()))
- {
- Assembly * pCachedAssembly = pDomainAssembly->GetAssembly();
- IAssemblyName * pCachedAssemblyName = pCachedAssembly->GetFusionAssemblyName();
- if ((pAssembly != pCachedAssembly) && (S_OK == pCachedAssemblyName->IsEqual(pIAssemblyName, ASM_CMPF_IL_ALL)))
- {
- COMPlusThrow(kFileLoadException, IDS_EE_REFLECTIONONLY_LOADFROM, W("")); //@todo: need to fill in assemblyname
- }
- }
- }
-#endif // FEATURE_REFLECTION_ONLY_LOAD
-
-#ifndef FEATURE_CORECLR
- FireEtwLoaderPhaseEnd(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderDynamicLoad, NULL, NULL, GetClrInstanceId());
-#endif // FEATURE_CORECLR
LOG((LF_CLASSLOADER,
LL_INFO100,
"\tLoaded in-memory module\n"));
@@ -585,12 +378,6 @@ FCIMPL6(Object*, AssemblyNative::LoadImage, U1Array* PEByteArrayUNSAFE,
pAssembly = LoadFromBuffer(fForIntrospection, pbImage, cbImage, pbSyms, cbSyms, stackMark, OBJECTREFToObject(gc.security), securityContextSource);
}
-#ifdef FEATURE_FUSION
- if (!fForIntrospection && IsLoggingNeeded())
- {
- BinderLogging::BindingLog::LogLoadByteArray(GetAppDomain()->GetFusionContext(), pAssembly);
- }
-#endif
if (pAssembly != NULL)
gc.refRetVal = pAssembly->GetExposedObject();
@@ -626,67 +413,7 @@ FCIMPL2(Object*, AssemblyNative::LoadFile, StringObject* pathUNSAFE, Object* sec
StackSString path;
gc.strPath->GetSString(path);
-#ifdef FEATURE_FUSION // use BindResult for abstraction
- // Event Tracing for Windows is used to log data for performance and functional testing purposes.
- // The events in this function are used to help measure the performance of assembly loading as a whole when loading directly from a file,
- // of binding to an assembly, as well as of lookup scenarios such as from a host store.
- FireEtwLoaderPhaseStart(ETWAppDomainIdNotAvailable, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderDynamicLoad, path, NULL, GetClrInstanceId());
- SafeComHolder<IAssembly> pFusionAssembly;
- SafeComHolder<IBindResult> pNativeFusionAssembly;
- SafeComHolder<IFusionBindLog> pFusionLog;
-
- PEAssemblyHolder pFile;
- FireEtwBindingPhaseStart(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, path, NULL, GetClrInstanceId());
-
- if(GetAppDomain()->HasLoadContextHostBinder())
- {
- GCX_PREEMP();
- CLRPrivBinderLoadFile* pLFBinder = CLRPrivBinderLoadFile::GetOrCreateBinder();
- ReleaseHolder<PEImage> pImage(PEImage::OpenImage(path));
- ReleaseHolder<ICLRPrivAssembly> pAsm;
- ReleaseHolder<IAssemblyName> pAssemblyName;
- IfFailThrow(pLFBinder->BindAssemblyExplicit(pImage, &pAssemblyName, &pAsm));
- IfFailThrow(GetAppDomain()->BindHostedPrivAssembly(nullptr, pAsm, pAssemblyName, &pFile));
- _ASSERTE(pFile);
- }
- else
- {
- GCX_PREEMP();
- IfFailThrow(ExplicitBind(path, GetAppDomain()->GetFusionContext(),
- EXPLICITBIND_FLAGS_NON_BINDABLE,
- NULL, &pFusionAssembly, &pNativeFusionAssembly, &pFusionLog));
- pFile.Assign(PEAssembly::Open(pFusionAssembly, pNativeFusionAssembly, pFusionLog, FALSE, FALSE));
- }
-
- FireEtwBindingLookupAndProbingPhaseEnd(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, path, NULL, GetClrInstanceId());
-
- FireEtwBindingPhaseEnd(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, path, NULL, GetClrInstanceId());
-
- AssemblyLoadSecurity loadSecurity;
- loadSecurity.m_pAdditionalEvidence = &gc.refSecurity;
- loadSecurity.m_fCheckLoadFromRemoteSource = true;
-
- // If we're in an APPX domain, then all loads from the application will find themselves within the APPX package
- // graph or from a trusted location. However, assemblies within the package may have been marked by Windows as
- // not being from the MyComputer zone, which can trip the LoadFromRemoteSources check. Since we do not need to
- // defend against accidental loads from HTTP for APPX applications, we simply suppress the remote load check.
- if (AppX::IsAppXProcess())
- {
- loadSecurity.m_fCheckLoadFromRemoteSource = false;
- }
-
- Assembly *pAssembly = GetPostPolicyAssembly(pFile, FALSE, &loadSecurity);
-
- FireEtwLoaderPhaseEnd(ETWAppDomainIdNotAvailable, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderDynamicLoad, path, NULL, GetClrInstanceId());
-
- if (IsLoggingNeeded())
- {
- BinderLogging::BindingLog::LogLoadFile(GetAppDomain()->GetFusionContext(), path, pAssembly);
- }
-
-#else // FEATURE_FUSION
Assembly *pAssembly = AssemblySpec::LoadAssembly(path);
-#endif // FEATURE_FUSION
LOG((LF_CLASSLOADER,
LL_INFO100,
@@ -702,7 +429,6 @@ FCIMPL2(Object*, AssemblyNative::LoadFile, StringObject* pathUNSAFE, Object* sec
}
FCIMPLEND
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
/* static */
Assembly* AssemblyNative::LoadFromPEImage(ICLRPrivBinder* pBinderContext, PEImage *pILImage, PEImage *pNIImage)
@@ -781,9 +507,12 @@ Assembly* AssemblyNative::LoadFromPEImage(ICLRPrivBinder* pBinderContext, PEImag
spec.GetFileOrDisplayName(0, name);
COMPlusThrowHR(COR_E_FILELOAD, dwMessageID, name);
}
+
+ BINDER_SPACE::Assembly* assem;
+ assem = BINDER_SPACE::GetAssemblyFromPrivAssemblyFast(pAssembly);
- PEAssemblyHolder pPEAssembly(PEAssembly::Open(pParentAssembly, pILImage, pNIImage, pAssembly, FALSE));
-
+ PEAssemblyHolder pPEAssembly(PEAssembly::Open(pParentAssembly, assem->GetPEImage(), assem->GetNativePEImage(), pAssembly, FALSE));
+
GCX_COOP();
IApplicationSecurityDescriptor *pDomainSecDesc = pCurDomain->GetSecurityDescriptor();
@@ -982,7 +711,6 @@ void QCALLTYPE AssemblyNative::LoadFromStream(INT_PTR ptrNativeAssemblyLoadConte
END_QCALL;
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
/* static */
Assembly* AssemblyNative::GetPostPolicyAssembly(PEAssembly *pFile,
@@ -1003,60 +731,6 @@ Assembly* AssemblyNative::GetPostPolicyAssembly(PEAssembly *pFile,
GCX_PREEMP();
-#ifdef FEATURE_FUSION
- if (!fForIntrospection && !GetAppDomain()->HasLoadContextHostBinder()) {
- DWORD dwSize = 0;
- // if strongly named and not an exempt
- BOOL bOptionallyRetargetable;
-
- IfFailThrow(IsOptionallyRetargetableAssembly(pFile->GetFusionAssemblyName(), &bOptionallyRetargetable));
- if ( !bOptionallyRetargetable && pFile->GetFusionAssemblyName()->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, NULL, &dwSize) == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
-
- SafeComHolder<IAssemblyName> pPostPolicyName(NULL);
- HRESULT hr = PreBindAssembly(GetAppDomain()->GetFusionContext(),
- pFile->GetFusionAssemblyName(),
- NULL, // pAsmParent
- &pPostPolicyName,
- NULL); // pvReserved
- if (FAILED(hr)) {
- if (hr == FUSION_E_REF_DEF_MISMATCH) {
- // Policy redirects to another version
- AssemblySpec spec;
- spec.InitializeSpec(pPostPolicyName, FALSE);
- RETURN spec.LoadAssembly(FILE_LOADED, pLoadSecurity);
- }
- else
- ThrowHR(hr);
- }
- else {
- ReleaseHolder<IAssembly> pAsm;
-
- SafeComHolder<IAssemblyCache> pIAsmCache (NULL);
- IfFailThrow(CreateAssemblyCache(&pIAsmCache, 0));
-
- DWORD dwFlags = ASM_DISPLAYF_FULL;
-
- if (pFile->IsMarkedAsNoPlatform()) { // No Platform implies that the assembly is not tied to a specific machine architecture, which means we need to do full GAC probing.
- hr = CreateAssemblyFromCacheLookup(GetAppDomain()->GetFusionContext(), pFile->GetFusionAssemblyName(), TRUE, &pAsm, NULL);
- }
- else {
- SString sourceDisplay;
- FusionBind::GetAssemblyNameDisplayName(pFile->GetFusionAssemblyName(), sourceDisplay, dwFlags);
- hr = pIAsmCache->QueryAssemblyInfo(0, sourceDisplay, NULL);
- }
-
- if (SUCCEEDED(hr)) {
- // It's in the GAC
- AssemblySpec spec;
- spec.InitializeSpec(pFile->GetFusionAssemblyName(), FALSE);
- RETURN spec.LoadAssembly(FILE_LOADED, pLoadSecurity);
- }
- else if (hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
- ThrowHR(hr);
- }
- }
- }
-#else // FEATURE_FUSION
if (fIsLoadByteArray)
{
PEImage *pPEImage = pFile->GetILimage();
@@ -1081,97 +755,10 @@ Assembly* AssemblyNative::GetPostPolicyAssembly(PEAssembly *pFile,
ThrowHR(hr);
}
}
-#endif // FEATURE_FUSION
RETURN GetAppDomain()->LoadAssembly(NULL, pFile, FILE_LOADED, pLoadSecurity);
}
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-void QCALLTYPE AssemblyNative::LoadModule(QCall::AssemblyHandle pAssembly,
- LPCWSTR wszModuleName,
- LPCBYTE pRawModule, INT32 cbModule,
- LPCBYTE pRawSymbolStore, INT32 cbSymbolStore,
- QCall::ObjectHandleOnStack retModule)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- Module * pModule = NULL;
-
- if(CorHost2::IsLoadFromBlocked())
- COMPlusThrow(kFileLoadException, FUSION_E_LOADFROM_BLOCKED);
-
- if (wszModuleName == NULL)
- COMPlusThrow(kArgumentNullException, W("ArgumentNull_FileName"));
-
- if (pRawModule == NULL)
- COMPlusThrow(kArgumentNullException, W("ArgumentNull_Array"));
-
- if (*wszModuleName == '\0')
- COMPlusThrow(kArgumentException, W("Argument_EmptyFileName"));
-
- CQuickBytes qbLC;
-
- MAKE_UTF8PTR_FROMWIDE(pName, wszModuleName);
- LPCSTR psModuleName = pName;
-
- // Need to perform case insensitive lookup.
- {
- UTF8_TO_LOWER_CASE(psModuleName, qbLC);
- psModuleName = (LPUTF8) qbLC.Ptr();
- }
-
- HashDatum datum;
- mdFile kFile = NULL;
- // m_pAllowedFiles only grows - entries are never deleted from it. So we do not take
- // a lock around GetValue. If the code is modified such that we delete entries from m_pAllowedFiles,
- // reconsider whether we should take the m_crstAllowedFiles lock here (see the uses of kFile below).
- if (pAssembly->GetAssembly()->m_pAllowedFiles->GetValue(psModuleName, &datum))
- kFile = (mdFile)(size_t)datum;
-
- // If the name doesn't match one of the File def names, don't load this module.
- // If this name matches the manifest file (datum was NULL), don't load either.
- if (!kFile)
- COMPlusThrow(kArgumentException, W("Arg_InvalidFileName"));
-
-
- PEModuleHolder pFile(PEModule::OpenMemory(pAssembly->GetFile(), kFile,
- pRawModule, cbModule));
-
- DomainModule *pDomainModule = GetAppDomain()->LoadDomainModule(pAssembly->GetDomainAssembly(),
- pFile, FILE_LOADED);
- pModule = pDomainModule->GetModule();
-
- if (!pFile->Equals(pModule->GetFile()))
- COMPlusThrow(kArgumentException, W("Argument_ModuleAlreadyLoaded"));
-
- LOG((LF_CLASSLOADER,
- LL_INFO100,
- "\tLoaded in-memory module\n"));
-
-#ifdef DEBUGGING_SUPPORTED
- if (!pModule->IsResource())
- {
- // If we were given symbols, hold onto a copy
- if (pRawSymbolStore != NULL)
- {
- pModule->SetSymbolBytes(pRawSymbolStore, cbSymbolStore);
- }
- }
-#endif // DEBUGGING_SUPPORTED
-
- if (pModule != NULL)
- {
- GCX_COOP();
- retModule.Set(pModule->GetExposedObject());
- }
-
- END_QCALL;
-
- return;
-}
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
void QCALLTYPE AssemblyNative::GetLocation(QCall::AssemblyHandle pAssembly, QCall::StringHandleOnStack retString)
{
@@ -1179,15 +766,6 @@ void QCALLTYPE AssemblyNative::GetLocation(QCall::AssemblyHandle pAssembly, QCal
BEGIN_QCALL;
-#ifndef FEATURE_CORECLR
- // workaround - lie about where mscorlib is. Mscorlib is now loaded out of the GAC,
- // but some apps query its location to find the system directory. (Notably system.web)
- if (pAssembly->IsSystem())
- {
- retString.Set(SystemDomain::System()->BaseLibrary());
- }
- else
-#endif // !FEATURE_CORECLR
{
retString.Set(pAssembly->GetFile()->GetPath());
}
@@ -1284,26 +862,6 @@ void QCALLTYPE AssemblyNative::GetPublicKey(QCall::AssemblyHandle pAssembly, QCa
END_QCALL;
}
-#if !FEATURE_CORECLR
-
-BYTE QCALLTYPE AssemblyNative::GetSecurityRuleSet(QCall::AssemblyHandle pAssembly)
-{
- QCALL_CONTRACT;
-
- SecurityRuleSet ruleSet = SecurityRuleSet_Default;
-
- BEGIN_QCALL;
-
- ModuleSecurityDescriptor *pMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pAssembly->GetAssembly());
- ruleSet = pMSD->GetSecurityRuleSet();
-
- END_QCALL;
-
- return static_cast<BYTE>(ruleSet);
-}
-
-#endif // !FEATURE_CORECLR
-
void QCALLTYPE AssemblyNative::GetSimpleName(QCall::AssemblyHandle pAssembly, QCall::StringHandleOnStack retSimpleName)
{
QCALL_CONTRACT;
@@ -1336,14 +894,6 @@ void QCALLTYPE AssemblyNative::GetCodeBase(QCall::AssemblyHandle pAssembly, BOOL
StackSString codebase;
-#ifndef FEATURE_CORECLR
- if (pAssembly->IsSystem()) {
- // workaround: lie about the location of mscorlib. Some callers assume it is in the install dir.
- codebase.Set(SystemDomain::System()->BaseLibrary());
- PEAssembly::PathToUrl(codebase);
- }
- else
-#endif // !FEATURE_CORECLR
{
pAssembly->GetFile()->GetCodeBase(codebase);
}
@@ -1409,23 +959,6 @@ BYTE * QCALLTYPE AssemblyNative::GetResource(QCall::AssemblyHandle pAssembly, LP
return pbInMemoryResource;
}
-#ifndef FEATURE_CORECLR
-
-BOOL QCALLTYPE AssemblyNative::UseRelativeBindForSatellites()
-{
- QCALL_CONTRACT;
-
- BOOL retVal = TRUE;
-
- BEGIN_QCALL;
- retVal = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_RelativeBindForResources);
- END_QCALL;
-
- return retVal;
-
-}
-#endif // !FEATURE_CORECLR
-
INT32 QCALLTYPE AssemblyNative::GetManifestResourceInfo(QCall::AssemblyHandle pAssembly, LPCWSTR wszName, QCall::ObjectHandleOnStack retAssembly, QCall::StringHandleOnStack retFileName, QCall::StackCrawlMarkHandle stackMark)
{
QCALL_CONTRACT;
@@ -1572,33 +1105,6 @@ void QCALLTYPE AssemblyNative::GetModule(QCall::AssemblyHandle pAssembly, LPCWST
MAKE_UTF8PTR_FROMWIDE(szModuleName, wszFileName);
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- // Need to perform case insensitive lookup.
- {
- UTF8_TO_LOWER_CASE(szModuleName, qbLC);
- szModuleName = (LPUTF8) qbLC.Ptr();
- }
-
- HashDatum datum = NULL;
-
- // m_pAllowedFiles only grows - entries are never deleted from it. So we do not take
- // a lock around GetValue. If the code is modified such that we delete entries from m_pAllowedFiles,
- // reconsider whether we should take the m_crstAllowedFiles lock here (see the uses of datum below).
- if (pAssembly->GetAssembly()->m_pAllowedFiles->GetValue(szModuleName, &datum))
- {
- if (datum)
- {
- // internal module
- mdFile tokFile = (mdFile)(UINT_PTR)datum;
-
- pModule = pAssembly->GetModule()->LoadModule(GetAppDomain(), tokFile)->GetModule();
- }
- else
- { // manifest module
- pModule = pAssembly->GetDomainAssembly()->GetModule();
- }
- }
-#else
LPCUTF8 pModuleName = NULL;
@@ -1608,7 +1114,6 @@ void QCALLTYPE AssemblyNative::GetModule(QCall::AssemblyHandle pAssembly, LPCWST
pModule = pAssembly->GetDomainAssembly()->GetModule();
}
-#endif
if (pModule != NULL)
{
@@ -1937,121 +1442,6 @@ void QCALLTYPE AssemblyNative::GetEntryPoint(QCall::AssemblyHandle pAssembly, QC
return;
}
-#ifndef FEATURE_CORECLR
-// prepare saving manifest to disk
-void QCALLTYPE AssemblyNative::PrepareForSavingManifestToDisk(QCall::AssemblyHandle pAssembly, QCall::ModuleHandle pAssemblyModule)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- pAssembly->GetAssembly()->PrepareSavingManifest((ReflectionModule *)(Module *)pAssemblyModule);
-
- END_QCALL;
-}
-
-#endif
-
-#ifndef FEATURE_CORECLR
-// add a file name to the file list of this assembly. On disk only.
-mdFile QCALLTYPE AssemblyNative::AddFile(QCall::AssemblyHandle pAssembly, LPCWSTR wszFileName)
-{
- QCALL_CONTRACT;
-
- mdFile retVal = 0;
-
- BEGIN_QCALL;
-
- retVal = pAssembly->GetAssembly()->AddFile(wszFileName);
-
- END_QCALL;
-
- return retVal;
-}
-#endif //FEATURE_CORECLR
-
-#ifndef FEATURE_CORECLR
-// set the hash value on a file.
-void QCALLTYPE AssemblyNative::SetFileHashValue(QCall::AssemblyHandle pAssembly, INT32 tkFile, LPCWSTR wszFullFileName)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- pAssembly->GetAssembly()->SetFileHashValue(tkFile, wszFullFileName);
-
- END_QCALL;
-}
-#endif //FEATURE_CORECLR
-
-#ifndef FEATURE_CORECLR
-// Add a Type name to the ExportedType table in the on-disk assembly manifest.
-mdExportedType QCALLTYPE AssemblyNative::AddExportedTypeOnDisk(QCall::AssemblyHandle pAssembly, LPCWSTR wszCOMTypeName, INT32 tkImpl, INT32 tkTypeDef, INT32 flags)
-{
- QCALL_CONTRACT;
-
- mdExportedType retVal = 0;
-
- BEGIN_QCALL;
-
- retVal = pAssembly->GetAssembly()->AddExportedTypeOnDisk(wszCOMTypeName, tkImpl, tkTypeDef, (CorTypeAttr)flags);
-
- END_QCALL;
-
- return retVal;
-}
-
-// Add a Type name to the ExportedType table in the in-memory assembly manifest.
-mdExportedType QCALLTYPE AssemblyNative::AddExportedTypeInMemory(QCall::AssemblyHandle pAssembly, LPCWSTR wszCOMTypeName, INT32 tkImpl, INT32 tkTypeDef, INT32 flags)
-{
- QCALL_CONTRACT;
-
- mdExportedType retVal = 0;
-
- BEGIN_QCALL;
-
- retVal = pAssembly->GetAssembly()->AddExportedTypeInMemory(wszCOMTypeName, tkImpl, tkTypeDef, (CorTypeAttr)flags);
-
- END_QCALL;
-
- return retVal;
-}
-#endif //FEATURE_CORECLR
-
-#ifndef FEATURE_CORECLR
-// add a Stand alone resource to ManifestResource table
-void QCALLTYPE AssemblyNative::AddStandAloneResource(QCall::AssemblyHandle pAssembly, LPCWSTR wszName, LPCWSTR wszFileName, LPCWSTR wszFullFileName, INT32 iAttribute)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- pAssembly->GetAssembly()->AddStandAloneResource(
- wszName,
- NULL,
- NULL,
- wszFileName,
- wszFullFileName,
- iAttribute);
-
- END_QCALL;
-}
-#endif //FEATURE_CORECLR
-
-#ifndef FEATURE_CORECLR
-// Save security permission requests.
-void QCALLTYPE AssemblyNative::AddDeclarativeSecurity(QCall::AssemblyHandle pAssembly, INT32 action, PVOID blob, INT32 length)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- pAssembly->GetAssembly()->AddDeclarativeSecurity(action, blob, length);
-
- END_QCALL;
-}
-#endif //FEATURE_CORECLR
-
//---------------------------------------------------------------------------------------
//
// Get the raw bytes making up this assembly
@@ -2116,27 +1506,6 @@ extern void ManagedBitnessFlagsToUnmanagedBitnessFlags(
INT32 portableExecutableKind, INT32 imageFileMachine,
DWORD* pPeFlags, DWORD* pCorhFlags);
-#ifndef FEATURE_CORECLR
-void QCALLTYPE AssemblyNative::SaveManifestToDisk(QCall::AssemblyHandle pAssembly,
- LPCWSTR wszManifestFileName,
- INT32 entrypoint,
- INT32 fileKind,
- INT32 portableExecutableKind,
- INT32 imageFileMachine)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- DWORD peFlags = 0, corhFlags = 0;
- ManagedBitnessFlagsToUnmanagedBitnessFlags(portableExecutableKind, imageFileMachine, &peFlags, &corhFlags);
-
- pAssembly->GetAssembly()->SaveManifestToDisk(wszManifestFileName, entrypoint, fileKind, corhFlags, peFlags);
-
- END_QCALL;
-}
-#endif // !FEATURE_CORECLR
-
void QCALLTYPE AssemblyNative::GetFullName(QCall::AssemblyHandle pAssembly, QCall::StringHandleOnStack retString)
{
QCALL_CONTRACT;
@@ -2317,89 +1686,6 @@ FCIMPL1(ReflectModuleBaseObject *, AssemblyNative::GetInMemoryAssemblyModule, As
}
FCIMPLEND
-
-#ifndef FEATURE_CORECLR
-// Create a stand-alone resource file for version resource.
-void QCALLTYPE AssemblyNative::CreateVersionInfoResource(LPCWSTR pwzFilename,
- LPCWSTR pwzTitle,
- LPCWSTR pwzIconFilename,
- LPCWSTR pwzDescription,
- LPCWSTR pwzCopyright,
- LPCWSTR pwzTrademark,
- LPCWSTR pwzCompany,
- LPCWSTR pwzProduct,
- LPCWSTR pwzProductVersion,
- LPCWSTR pwzFileVersion,
- INT32 lcid,
- BOOL fIsDll,
- QCall::StringHandleOnStack retFileName)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- Win32Res res; // Resource helper object.
- const void *pvData=0; // Pointer to the resource.
- ULONG cbData; // Size of the resource data.
- ULONG cbWritten;
- PathString szFile; // File name for resource file.
- PathString szPath; // Path name for resource file.
- HandleHolder hFile;
-
- res.SetInfo(pwzFilename,
- pwzTitle,
- pwzIconFilename,
- pwzDescription,
- pwzCopyright,
- pwzTrademark,
- pwzCompany,
- pwzProduct,
- pwzProductVersion,
- pwzFileVersion,
- lcid,
- fIsDll);
-
- res.MakeResFile(&pvData, &cbData);
-
- //<TODO>Change the COMPlusThrowWin32's to exceptions with
- // messages including the path/file name</TODO>
-
- // Persist to a file.
- if (!WszGetTempPath(szPath))
- COMPlusThrowWin32();
- if (!WszGetTempFileName(szPath.GetUnicode(), W("RES"), 0, szFile))
- COMPlusThrowWin32();
-
- hFile = WszCreateFile(szFile, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- COMPlusThrowWin32();
-
- if (!WriteFile(hFile, pvData, cbData, &cbWritten, NULL))
- COMPlusThrowWin32();
-
- retFileName.Set(szFile);
-
- END_QCALL;
-}
-#endif // !FEATURE_CORECLR
-
-#ifndef FEATURE_CORECLR
-FCIMPL1(FC_BOOL_RET, AssemblyNative::IsGlobalAssemblyCache, AssemblyBaseObject* pAssemblyUNSAFE)
-{
- FCALL_CONTRACT;
-
- ASSEMBLYREF refAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pAssemblyUNSAFE);
-
- if (refAssembly == NULL)
- FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
-
- DomainAssembly *pAssembly = refAssembly->GetDomainAssembly();
-
- FC_RETURN_BOOL(pAssembly->GetFile()->IsSourceGAC());
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
-
void QCALLTYPE AssemblyNative::GetImageRuntimeVersion(QCall::AssemblyHandle pAssembly, QCall::StringHandleOnStack retString)
{
QCALL_CONTRACT;
@@ -2414,9 +1700,6 @@ void QCALLTYPE AssemblyNative::GetImageRuntimeVersion(QCall::AssemblyHandle pAss
IfFailThrow(pPEFile->GetMDImport()->GetVersionString(&pszVersion));
SString version(SString::Utf8, pszVersion);
- #ifndef FEATURE_CORECLR
- AdjustImageRuntimeVersion(&version);
-#endif // FEATURE_CORECLR
// Allocate a managed string that contains the version and return it.
retString.Set(version);
@@ -2424,44 +1707,7 @@ void QCALLTYPE AssemblyNative::GetImageRuntimeVersion(QCall::AssemblyHandle pAss
END_QCALL;
}
-#ifdef FEATURE_FUSION
-INT64 QCALLTYPE AssemblyNative::GetHostContext(QCall::AssemblyHandle pAssembly)
-{
- QCALL_CONTRACT;
-
- UINT64 Context = 0;
- BEGIN_QCALL;
-
- IHostAssembly *pIHostAssembly = pAssembly->GetFile()->GetIHostAssembly();
- if (pIHostAssembly != NULL)
- {
- IfFailThrow(pIHostAssembly->GetAssemblyContext(&Context));
- }
-
- END_QCALL;
-
- return Context;
-}
-#endif // FEATURE_FUSION
-
-#ifdef FEATURE_CAS_POLICY
-BOOL QCALLTYPE AssemblyNative::IsStrongNameVerified(QCall::AssemblyHandle pAssembly)
-{
- QCALL_CONTRACT;
-
- BOOL fStrongNameVerified = FALSE;
-
- BEGIN_QCALL;
-
- PEFile *pPEFile = pAssembly->GetFile();
- fStrongNameVerified = pPEFile->IsStrongNameVerified();
-
- END_QCALL;
-
- return fStrongNameVerified;
-}
-#endif // FEATURE_CAS_POLICY
#ifdef FEATURE_APPX
/*static*/
@@ -2482,7 +1728,6 @@ BOOL QCALLTYPE AssemblyNative::IsDesignerBindingContext(QCall::AssemblyHandle pA
}
#endif // FEATURE_APPX
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
/*static*/
INT_PTR QCALLTYPE AssemblyNative::InitializeAssemblyLoadContext(INT_PTR ptrManagedAssemblyLoadContext, BOOL fRepresentsTPALoadContext)
{
@@ -2641,7 +1886,6 @@ INT_PTR QCALLTYPE AssemblyNative::GetLoadContextForAssembly(QCall::AssemblyHandl
return ptrManagedAssemblyLoadContext;
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
// static
BOOL QCALLTYPE AssemblyNative::InternalTryGetRawMetadata(
diff --git a/src/vm/assemblynative.hpp b/src/vm/assemblynative.hpp
index 99f51e9837..ece8100e95 100644
--- a/src/vm/assemblynative.hpp
+++ b/src/vm/assemblynative.hpp
@@ -74,10 +74,6 @@ public:
static
INT32 QCALLTYPE GetHashAlgorithm(QCall::AssemblyHandle pAssembly);
-#ifndef FEATURE_CORECLR
- static
- BYTE QCALLTYPE GetSecurityRuleSet(QCall::AssemblyHandle pAssembly);
-#endif // !FEATURE_CORECLR
static
void QCALLTYPE GetSimpleName(QCall::AssemblyHandle pAssembly, QCall::StringHandleOnStack retSimpleName);
@@ -149,10 +145,6 @@ public:
static FCDECL1(ReflectModuleBaseObject *, GetOnDiskAssemblyModule, AssemblyBaseObject * pAssemblyUNSAFE);
static FCDECL1(ReflectModuleBaseObject *, GetInMemoryAssemblyModule, AssemblyBaseObject * pAssemblyUNSAFE);
-#ifndef FEATURE_CORECLR
- static
- FCDECL1(FC_BOOL_RET, IsGlobalAssemblyCache, AssemblyBaseObject* pAssemblyUNSAFE);
-#endif // !FEATURE_CORECLR
static
void QCALLTYPE GetGrantSet(QCall::AssemblyHandle pAssembly, QCall::ObjectHandleOnStack retGranted, QCall::ObjectHandleOnStack retDenied);
@@ -175,10 +167,6 @@ public:
static
INT64 QCALLTYPE GetHostContext(QCall::AssemblyHandle pAssembly);
-#ifdef FEATURE_CAS_POLICY
- static
- BOOL QCALLTYPE IsStrongNameVerified(QCall::AssemblyHandle pAssembly);
-#endif // FEATURE_CAS_POLICY
//
// AssemblyBuilder FCALLs
@@ -187,22 +175,6 @@ public:
static
void QCALLTYPE PrepareForSavingManifestToDisk(QCall::AssemblyHandle pAssembly, QCall::ModuleHandle pAssemblyModule);
-#ifndef FEATURE_CORECLR
- static
- void QCALLTYPE SaveManifestToDisk(QCall::AssemblyHandle pAssembly,
- LPCWSTR wszManifestFileName,
- INT32 entrypoint,
- INT32 fileKind,
- INT32 portableExecutableKind,
- INT32 imageFileMachine);
-
- static
- mdExportedType QCALLTYPE AddExportedTypeOnDisk(QCall::AssemblyHandle pAssembly, LPCWSTR wzzCOMTypeName, INT32 tkImpl, INT32 tkTypeDef, INT32 flags);
-
- static
- mdExportedType QCALLTYPE AddExportedTypeInMemory(QCall::AssemblyHandle pAssembly, LPCWSTR wzzCOMTypeName, INT32 tkImpl, INT32 tkTypeDef, INT32 flags);
-
-#endif // FEATURE_CORECLR
static
mdFile QCALLTYPE AddFile(QCall::AssemblyHandle pAssembly, LPCWSTR wszFileName);
@@ -216,22 +188,6 @@ public:
static
void QCALLTYPE AddDeclarativeSecurity(QCall::AssemblyHandle pAssembly, INT32 action, PVOID blob, INT32 length);
-#ifndef FEATURE_CORECLR
- static
- void QCALLTYPE CreateVersionInfoResource(LPCWSTR pwzFilename,
- LPCWSTR pwzTitle,
- LPCWSTR pwzIconFilename,
- LPCWSTR pwzDescription,
- LPCWSTR pwzCopyright,
- LPCWSTR pwzTrademark,
- LPCWSTR pwzCompany,
- LPCWSTR pwzProduct,
- LPCWSTR pwzProductVersion,
- LPCWSTR pwzFileVersion,
- INT32 lcid,
- BOOL fIsDll,
- QCall::StringHandleOnStack retFileName);
-#endif // !FEATURE_CORECLR
static
void QCALLTYPE GetRawBytes(QCall::AssemblyHandle pAssembly, QCall::ObjectHandleOnStack retRawBytes);
diff --git a/src/vm/assemblysink.cpp b/src/vm/assemblysink.cpp
deleted file mode 100644
index 8fe33f5bf4..0000000000
--- a/src/vm/assemblysink.cpp
+++ /dev/null
@@ -1,153 +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.
-
-/*============================================================
-**
-** Header: AssemblySink.cpp
-**
-** Purpose: Implements AssemblySink, event objects that block
-** the current thread waiting for an asynchronous load
-** of an assembly to succeed.
-**
-**
-
-
-**
-===========================================================*/
-
-#include "common.h"
-#ifdef FEATURE_FUSION
-#include <stdlib.h>
-#include "assemblysink.h"
-#include "assemblyspec.hpp"
-#include "corpriv.h"
-#include "appdomain.inl"
-
-AssemblySink::AssemblySink(AppDomain* pDomain)
-{
- WRAPPER_NO_CONTRACT;
- m_Domain=pDomain->GetId();
- m_pSpec=NULL;
- m_CheckCodebase = FALSE;
-}
-
-void AssemblySink::Reset()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- m_CheckCodebase = FALSE;
- FusionSink::Reset();
-}
-
-ULONG AssemblySink::Release()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- NOTHROW;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_TRIGGERS);}
- MODE_ANY;
- PRECONDITION(CheckPointer(this));
- } CONTRACTL_END;
-
-
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (!cRef) {
- Reset();
- AssemblySink* ret = this;
- // If we have a domain we keep a pool of one around. If we get an entry
- // back from the pool then we were not added to the pool and need to be deleted.
- // If we do not have a pool then we need to delete it.
-
-
-
-
- // TODO: SetupThread may throw. What do we do with Release?
- HRESULT hr = S_OK;
- SetupThreadNoThrow(&hr);
- {
- GCX_COOP();
-
- if(m_Domain.m_dwId) {
- AppDomainFromIDHolder AD(m_Domain, TRUE);
- if (!AD.IsUnloaded())
- ret = FastInterlockCompareExchangePointer(&(AD->m_pAsyncPool),
- this,
- NULL);
-
- }
- }
-
- if(ret != NULL)
- delete this;
- }
- return (cRef);
-}
-
-
-
-STDMETHODIMP AssemblySink::OnProgress(DWORD dwNotification,
- HRESULT hrNotification,
- LPCWSTR szNotification,
- DWORD dwProgress,
- DWORD dwProgressMax,
- LPVOID pvBindInfo,
- IUnknown* punk)
-{
- STATIC_CONTRACT_NOTHROW;
-
- HRESULT hr = S_OK;
-
- switch(dwNotification) {
-
- case ASM_NOTIFICATION_BIND_INFO:
- FusionBindInfo *pBindInfo;
-
- pBindInfo = (FusionBindInfo *)pvBindInfo;
-
- if (pBindInfo && pBindInfo->pNamePolicy && m_pSpec) {
- pBindInfo->pNamePolicy->AddRef();
- m_pSpec->SetNameAfterPolicy(pBindInfo->pNamePolicy);
- }
- break;
-
- default:
- break;
- }
-
- if (SUCCEEDED(hr))
- hr = FusionSink::OnProgress(dwNotification, hrNotification, szNotification,
- dwProgress, dwProgressMax, pvBindInfo, punk);
-
- return hr;
-}
-
-
-HRESULT AssemblySink::Wait()
-{
- STATIC_CONTRACT_NOTHROW;
-
- HRESULT hr = FusionSink::Wait();
-
- if (FAILED(hr)) {
- // If we get an exception then we will just release this sink. It may be the
- // case that the appdomain was terminated. Other exceptions will cause the
- // sink to be scavenged but this is ok. A new one will be generated for the
- // next bind.
- m_Domain.m_dwId = 0;
- // The AssemblySpec passed is stack allocated in some cases.
- // Remove reference to it to prevent AV in delayed fusion bind notifications.
- m_pSpec = NULL;
- }
-
- return hr;
-}
-#endif
diff --git a/src/vm/assemblysink.h b/src/vm/assemblysink.h
deleted file mode 100644
index 9293a65b11..0000000000
--- a/src/vm/assemblysink.h
+++ /dev/null
@@ -1,59 +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.
-
-/*============================================================
-**
-** Header: AssemblySink.hpp
-**
-** Purpose: Asynchronous call back for loading classes
-**
-**
-
-
-**
-===========================================================*/
-#ifndef _ASSEMBLYSINK_H
-#define _ASSEMBLYSINK_H
-
-#ifndef FEATURE_FUSION
-#error FEATURE_FUSION is not enabled, please do not include assemblysink.h
-#endif
-
-class AppDomain;
-
-class AssemblySink : public FusionSink
-{
-public:
- AssemblySink(AppDomain* pDomain);
- ~AssemblySink() { WRAPPER_NO_CONTRACT; };
-
- void Reset();
-
- ULONG STDMETHODCALLTYPE Release(void);
-
- STDMETHODIMP OnProgress(DWORD dwNotification,
- HRESULT hrNotification,
- LPCWSTR szNotification,
- DWORD dwProgress,
- DWORD dwProgressMax,
- LPVOID pvBindInfo,
- IUnknown* punk);
-
- virtual HRESULT Wait();
-
- void RequireCodebaseSecurityCheck() {LIMITED_METHOD_CONTRACT; m_CheckCodebase = TRUE;}
- BOOL DoCodebaseSecurityCheck() {LIMITED_METHOD_CONTRACT; return m_CheckCodebase;}
- void SetAssemblySpec(AssemblySpec* pSpec)
- {
- LIMITED_METHOD_CONTRACT;
- m_pSpec=pSpec;
- }
-
-private:
- ADID m_Domain; // Which domain (index) do I belong to
- AssemblySpec* m_pSpec;
- BOOL m_CheckCodebase;
-};
-
-#endif
diff --git a/src/vm/assemblyspec.cpp b/src/vm/assemblyspec.cpp
index b9e94e8a81..e278c002fc 100644
--- a/src/vm/assemblyspec.cpp
+++ b/src/vm/assemblyspec.cpp
@@ -18,21 +18,11 @@
#include <stdlib.h>
-#ifdef FEATURE_FUSION
-#include "actasm.h"
-#include "appctx.h"
-#endif
#include "assemblyspec.hpp"
#include "security.h"
#include "eeconfig.h"
#include "strongname.h"
#include "strongnameholders.h"
-#ifdef FEATURE_FUSION
-#include "assemblysink.h"
-#include "dbglog.h"
-#include "bindinglog.hpp"
-#include "assemblyfilehash.h"
-#endif
#include "mdaassistants.h"
#include "eventtrace.h"
@@ -252,13 +242,6 @@ HRESULT AssemblySpec::InitializeSpecInternal(mdToken kAssemblyToken,
if (pStaticParent != NULL)
{
// We dont validate this for CoreCLR as there is no good use-case for this scenario.
-#if !defined(FEATURE_CORECLR)
- // It is OK for signed assemblies to reference WinRT assemblies (.winmd files) that are not signed
- if (!IsContentType_WindowsRuntime() && pStaticParent->GetFile()->IsStrongNamed() && !IsStrongNamed())
- {
- ThrowHR(FUSION_E_PRIVATE_ASM_DISALLOWED);
- }
-#endif // !defined(FEATURE_CORECLR)
SetParentAssembly(pStaticParent);
}
@@ -268,82 +251,7 @@ HRESULT AssemblySpec::InitializeSpecInternal(mdToken kAssemblyToken,
return hr;
} // AssemblySpec::InitializeSpecInternal
-#ifdef FEATURE_FUSION
-void AssemblySpec::InitializeSpec(IAssemblyName *pName,
- DomainAssembly *pStaticParent /*=NULL*/ ,
- BOOL fIntrospectionOnly /*=FALSE*/ )
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- GC_TRIGGERS;
- THROWS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- // Normalize this boolean as it tends to be used for comparisons
- m_fIntrospectionOnly = !!fIntrospectionOnly;
- IfFailThrow(Init(pName));
-
- // For static binds, we cannot reference a strongly named assembly from a weakly named one.
- // (Note that this constraint doesn't apply to dynamic binds which is why this check is
- // not farther down the stack.)
-
- if (pStaticParent != NULL) {
- if (pStaticParent->GetFile()->IsStrongNamed() && !IsStrongNamed())
- {
- EEFileLoadException::Throw(this, FUSION_E_PRIVATE_ASM_DISALLOWED);
- }
- SetParentAssembly(pStaticParent);
- }
-
- // Extract embedded WinRT name, if present.
- ParseEncodedName();
-}
-#endif //FEATURE_FUSION
-#ifdef FEATURE_MIXEDMODE
-void AssemblySpec::InitializeSpec(HMODULE hMod,
- BOOL fIntrospectionOnly /*=FALSE*/)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- GC_TRIGGERS;
- THROWS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- // Normalize this boolean as it tends to be used for comparisons
- m_fIntrospectionOnly = !!fIntrospectionOnly;
-
- PEDecoder pe(hMod);
-
- if (!pe.CheckILFormat())
- {
- StackSString path;
- PEImage::GetPathFromDll(hMod, path);
- EEFileLoadException::Throw(path, COR_E_BADIMAGEFORMAT);
- }
-
- COUNT_T size;
- const void *data = pe.GetMetadata(&size);
- SafeComHolder<IMDInternalImport> pImport;
- IfFailThrow(GetMetaDataInternalInterface((void *) data, size, ofRead,
- IID_IMDInternalImport,
- (void **) &pImport));
-
- mdAssembly a;
- if (FAILED(pImport->GetAssemblyFromScope(&a)))
- ThrowHR(COR_E_ASSEMBLYEXPECTED);
-
- InitializeSpec(a, pImport, NULL, fIntrospectionOnly);
-}
-#endif //FEATURE_MIXEDMODE
void AssemblySpec::InitializeSpec(PEAssembly * pFile)
{
@@ -378,7 +286,6 @@ void AssemblySpec::InitializeSpec(PEAssembly * pFile)
}
#endif //FEATURE_COMINTEROP
-#if defined(FEATURE_CORECLR)
// Set the binding context for the AssemblySpec
ICLRPrivBinder* pCurrentBinder = GetBindingContext();
ICLRPrivBinder* pExpectedBinder = pFile->GetBindingContext();
@@ -391,152 +298,11 @@ void AssemblySpec::InitializeSpec(PEAssembly * pFile)
_ASSERTE((pExpectedBinder != NULL) || pFile->IsSystem() || pFile->IsDynamic());
SetBindingContext(pExpectedBinder);
}
-#endif // defined(FEATURE_CORECLR)
}
#ifndef CROSSGEN_COMPILE
// This uses thread storage to allocate space. Please use Checkpoint and release it.
-#ifdef FEATURE_FUSION
-HRESULT AssemblySpec::InitializeSpec(StackingAllocator* alloc, ASSEMBLYNAMEREF* pName,
- BOOL fParse /*=TRUE*/, BOOL fIntrospectionOnly /*=FALSE*/)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- PRECONDITION(CheckPointer(alloc));
- PRECONDITION(CheckPointer(pName));
- PRECONDITION(IsProtectedByGCFrame(pName));
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- // Simple name
- if ((*pName)->GetSimpleName() != NULL) {
- WCHAR* pString;
- int iString;
- ((STRINGREF) (*pName)->GetSimpleName())->RefInterpretGetStringValuesDangerousForGC(&pString, &iString);
- DWORD lgth = WszWideCharToMultiByte(CP_UTF8, 0, pString, iString, NULL, 0, NULL, NULL);
- if (lgth + 1 < lgth)
- ThrowHR(E_INVALIDARG);
- LPSTR lpName = (LPSTR) alloc->Alloc(S_UINT32(lgth) + S_UINT32(1));
- WszWideCharToMultiByte(CP_UTF8, 0, pString, iString,
- lpName, lgth+1, NULL, NULL);
- lpName[lgth] = '\0';
- m_pAssemblyName = lpName;
- }
-
- if (fParse) {
- HRESULT hr = ParseName();
- // Sometimes Fusion flags invalid characters in the name, sometimes it doesn't
- // depending on where the invalid characters are
- // We want to Raise the assembly resolve event on all invalid characters
- // but calling ParseName before checking for invalid characters gives Fusion a chance to
- // parse the rest of the name (to get a public key token, etc.)
- if ((hr == FUSION_E_INVALID_NAME) || (!IsValidAssemblyName())) {
- // This is the only case where we do not throw on an error
- // We don't want to throw so as to give the caller a chance to call RaiseAssemblyResolveEvent
- // The only caller that cares is System.Reflection.Assembly.InternalLoad which calls us through
- // AssemblyNameNative::Init
- return FUSION_E_INVALID_NAME;
- }
- else
- IfFailThrow(hr);
- }
- else {
- // Flags
- m_dwFlags = (*pName)->GetFlags();
-
- // Version
- VERSIONREF version = (VERSIONREF) (*pName)->GetVersion();
- if(version == NULL) {
- m_context.usMajorVersion = (USHORT)-1;
- m_context.usMinorVersion = (USHORT)-1;
- m_context.usBuildNumber = (USHORT)-1;
- m_context.usRevisionNumber = (USHORT)-1;
- }
- else {
- m_context.usMajorVersion = (USHORT)version->GetMajor();
- m_context.usMinorVersion = (USHORT)version->GetMinor();
- m_context.usBuildNumber = (USHORT)version->GetBuild();
- m_context.usRevisionNumber = (USHORT)version->GetRevision();
- }
-
- m_context.szLocale = 0;
-
- if ((*pName)->GetCultureInfo() != NULL)
- {
- struct _gc {
- OBJECTREF cultureinfo;
- STRINGREF pString;
- } gc;
-
- gc.cultureinfo = (*pName)->GetCultureInfo();
- gc.pString = NULL;
-
- GCPROTECT_BEGIN(gc);
-
- MethodDescCallSite getName(METHOD__CULTURE_INFO__GET_NAME, &gc.cultureinfo);
-
- ARG_SLOT args[] = {
- ObjToArgSlot(gc.cultureinfo)
- };
- gc.pString = getName.Call_RetSTRINGREF(args);
- if (gc.pString != NULL) {
- WCHAR* pString;
- int iString;
- gc.pString->RefInterpretGetStringValuesDangerousForGC(&pString, &iString);
- DWORD lgth = WszWideCharToMultiByte(CP_UTF8, 0, pString, iString, NULL, 0, NULL, NULL);
- LPSTR lpLocale = (LPSTR) alloc->Alloc(S_UINT32(lgth) + S_UINT32(1));
- WszWideCharToMultiByte(CP_UTF8, 0, pString, iString,
- lpLocale, lgth+1, NULL, NULL);
- lpLocale[lgth] = '\0';
- m_context.szLocale = lpLocale;
- }
- GCPROTECT_END();
- }
-
- // Strong name
- // Note that we prefer to take a public key token if present,
- // even if flags indicate a full public key
- if ((*pName)->GetPublicKeyToken() != NULL) {
- m_dwFlags &= ~afPublicKey;
- PBYTE pArray = NULL;
- pArray = (*pName)->GetPublicKeyToken()->GetDirectPointerToNonObjectElements();
- m_cbPublicKeyOrToken = (*pName)->GetPublicKeyToken()->GetNumComponents();
- m_pbPublicKeyOrToken = new (alloc) BYTE[m_cbPublicKeyOrToken];
- memcpy(m_pbPublicKeyOrToken, pArray, m_cbPublicKeyOrToken);
- }
- else if ((*pName)->GetPublicKey() != NULL) {
- m_dwFlags |= afPublicKey;
- PBYTE pArray = NULL;
- pArray = (*pName)->GetPublicKey()->GetDirectPointerToNonObjectElements();
- m_cbPublicKeyOrToken = (*pName)->GetPublicKey()->GetNumComponents();
- m_pbPublicKeyOrToken = new (alloc) BYTE[m_cbPublicKeyOrToken];
- memcpy(m_pbPublicKeyOrToken, pArray, m_cbPublicKeyOrToken);
- }
- }
-
- // Hash for control
- // <TODO>@TODO cts, can we use unsafe in this case!!!</TODO>
- if ((*pName)->GetHashForControl() != NULL)
- SetHashForControl((*pName)->GetHashForControl()->GetDataPtr(),
- (*pName)->GetHashForControl()->GetNumComponents(),
- (*pName)->GetHashAlgorithmForControl());
-
- // Normalize this boolean as it tends to be used for comparisons
- m_fIntrospectionOnly = !!fIntrospectionOnly;
-
- // Extract embedded WinRT name, if present.
- ParseEncodedName();
-
- return S_OK;
-}
-
-#else // FEATURE_FUSION
HRESULT AssemblySpec::InitializeSpec(StackingAllocator* alloc, ASSEMBLYNAMEREF* pName,
BOOL fParse /*=TRUE*/, BOOL fIntrospectionOnly /*=FALSE*/)
{
@@ -696,7 +462,6 @@ HRESULT AssemblySpec::InitializeSpec(StackingAllocator* alloc, ASSEMBLYNAMEREF*
return S_OK;
}
-#endif // FEATURE_FUSION
void AssemblySpec::AssemblyNameInit(ASSEMBLYNAMEREF* pAsmName, PEImage* pImageInfo)
{
@@ -860,213 +625,6 @@ void AssemblySpec::SetCodeBase(StackingAllocator* alloc, STRINGREF *pCodeBase)
#endif // CROSSGEN_COMPILE
-#ifdef FEATURE_FUSION
-
-/* static */
-void AssemblySpec::DemandFileIOPermission(PEAssembly *pFile)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pFile));
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- // should have already checked permission if the codebase is set
- if (!GetCodeBase()) {
-
- if (pFile->IsBindingCodeBase()) {
- if (pFile->IsSourceDownloadCache()) {
- StackSString check;
- pFile->GetCodeBase(check);
-
- DemandFileIOPermission(check, FALSE, FILE_WEBPERM);
- }
- else
- DemandFileIOPermission(pFile->GetPath(), TRUE, FILE_READANDPATHDISC);
- }
- }
-}
-
-STDAPI RuntimeCheckLocationAccess(LPCWSTR wszLocation)
-{
-
- if (GetThread()==NULL)
- return S_FALSE;
-
- CONTRACTL
- {
- NOTHROW;
- MODE_ANY;
- GC_TRIGGERS;
- PRECONDITION(CheckPointer(wszLocation));
- }
- CONTRACTL_END;
- OVERRIDE_LOAD_LEVEL_LIMIT(FILE_ACTIVE);
- HRESULT hr=S_OK;
- DWORD dwDemand = 0;
-
- if (SString::_wcsnicmp(wszLocation, W("file"), 4))
- dwDemand = AssemblySpec::FILE_WEBPERM;
- else
- dwDemand = AssemblySpec::FILE_READANDPATHDISC;
-
- EX_TRY
- {
- AssemblySpec::DemandFileIOPermission(wszLocation,
- FALSE,
- dwDemand);
- }
- EX_CATCH_HRESULT(hr);
- return hr;
-
-}
-
-/* static */
-void AssemblySpec::DemandFileIOPermission(LPCWSTR wszCodeBase,
- BOOL fHavePath,
- DWORD dwDemandFlag)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(wszCodeBase));
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- GCX_COOP();
-
- MethodDescCallSite demandPermission(METHOD__ASSEMBLY__DEMAND_PERMISSION);
-
- STRINGREF codeBase = NULL;
- GCPROTECT_BEGIN(codeBase);
-
- codeBase = StringObject::NewString(wszCodeBase);
- ARG_SLOT args[3] =
- {
- ObjToArgSlot(codeBase),
- BoolToArgSlot(fHavePath),
- dwDemandFlag
- };
- demandPermission.Call(args);
- GCPROTECT_END();
-}
-
-BOOL AssemblySpec::FindAssemblyFile(AppDomain* pAppDomain, BOOL fThrowOnFileNotFound,
- IAssembly** ppIAssembly, IHostAssembly **ppIHostAssembly, IBindResult** ppNativeFusionAssembly,
- IFusionBindLog** ppFusionLog, HRESULT *pHRBindResult, StackCrawlMark *pCallerStackMark /* = NULL */,
- AssemblyLoadSecurity *pLoadSecurity /* = NULL */)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pAppDomain));
- PRECONDITION(CheckPointer(pHRBindResult));
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- GCX_PREEMP();
-
- IApplicationContext *pFusionContext = pAppDomain->GetFusionContext();
-
- AssemblySink* pSink = pAppDomain->AllocateAssemblySink(this);
- SafeComHolderPreemp<IAssemblyBindSink> sinkholder(pSink);
-
- BOOL fSuppressSecurityChecks = pLoadSecurity != NULL && pLoadSecurity->m_fSuppressSecurityChecks;
-
- if (!GetCodeBase() && !fSuppressSecurityChecks)
- pSink->RequireCodebaseSecurityCheck();
-
- BOOL fIsWellKnown = FALSE;
- HRESULT hr = S_OK;
-
- IfFailGo(AssemblySpec::LoadAssembly(pFusionContext,
- pSink,
- ppIAssembly,
- ppIHostAssembly,
- ppNativeFusionAssembly,
- IsIntrospectionOnly(),
- fSuppressSecurityChecks));
-
- // Host should have already done appropriate permission demand
- if (!(*ppIHostAssembly)) {
- DWORD dwLocation;
- IfFailGo((*ppIAssembly)->GetAssemblyLocation(&dwLocation));
-
- fIsWellKnown = (dwLocation == ASMLOC_UNKNOWN);
-
- // check if it was cached, where a codebase had originally loaded it
- if (pSink->DoCodebaseSecurityCheck() &&
- !fSuppressSecurityChecks &&
- (dwLocation & ASMLOC_CODEBASE_HINT)) {
- if ((dwLocation & ASMLOC_LOCATION_MASK) == ASMLOC_DOWNLOAD_CACHE) {
- StackSString codeBase;
- SafeComHolderPreemp<IAssemblyName> pNameDef;
-
- // <TODO>We could be caching the IAssemblyName and codebase</TODO>
- IfFailGo((*ppIAssembly)->GetAssemblyNameDef(&pNameDef));
-
- FusionBind::GetAssemblyNameStringProperty(pNameDef, ASM_NAME_CODEBASE_URL, codeBase);
-
- DemandFileIOPermission(codeBase, FALSE, FILE_WEBPERM);
- }
- else if ((dwLocation & ASMLOC_LOCATION_MASK) != ASMLOC_GAC) {
- StackSString path;
- FusionBind::GetAssemblyManifestModulePath((*ppIAssembly), path);
-
- DemandFileIOPermission(path, TRUE, FILE_READANDPATHDISC);
- }
- }
-
- // Verify control hash
- if (m_HashForControl.GetSize() > 0) {
- StackSString path;
-
- FusionBind::GetAssemblyManifestModulePath((*ppIAssembly), path);
-
- AssemblyFileHash fileHash;
- IfFailGo(fileHash.SetFileName(path));
- IfFailGo(fileHash.CalculateHash(m_dwHashAlg));
-
- if (!m_HashForControl.Equals(fileHash.GetHash(), fileHash.GetHashSize()))
- IfFailGo(FUSION_E_REF_DEF_MISMATCH);
- }
- }
-
-#ifdef MDA_SUPPORTED
- MdaLoadFromContext* pProbe = MDA_GET_ASSISTANT(LoadFromContext);
- if (pProbe) {
- pProbe->NowLoading(ppIAssembly, pCallerStackMark);
- }
-#endif
-
- *ppFusionLog = pSink->m_pFusionLog;
- if (*ppFusionLog)
- (*ppFusionLog)->AddRef();
- return fIsWellKnown;
-
- ErrExit:
- {
-
- *pHRBindResult = hr;
-
- if (fThrowOnFileNotFound || (!Assembly::FileNotFound(hr)))
- EEFileLoadException::Throw(this, pSink->m_pFusionLog, hr);
- }
-
- return FALSE;
-}
-#endif // FEATURE_FUSION
void AssemblySpec::MatchRetargetedPublicKeys(Assembly *pAssembly)
{
@@ -1079,28 +637,6 @@ void AssemblySpec::MatchRetargetedPublicKeys(Assembly *pAssembly)
PRECONDITION(CheckPointer(pAssembly));
}
CONTRACTL_END;
-#ifdef FEATURE_FUSION
- GCX_PREEMP();
-
- // Manually apply fusion policy to obtain retargeted public key
- SafeComHolderPreemp<IAssemblyName> pRequestedAssemblyName(NULL);
- SafeComHolderPreemp<IAssemblyName> pPostPolicyAssemblyName(NULL);
- IfFailThrow(CreateFusionName(&pRequestedAssemblyName));
- HRESULT hr = PreBindAssembly(GetAppDomain()->GetFusionContext(),
- pRequestedAssemblyName,
- NULL, // pAsmParent
- &pPostPolicyAssemblyName,
- NULL // pvReserved
- );
- if (SUCCEEDED(hr)
- || (FAILED(hr) && (hr == FUSION_E_REF_DEF_MISMATCH))) {
- IAssemblyName *pResultAssemblyName = pAssembly->GetFusionAssemblyName();
- if (pResultAssemblyName
- && pPostPolicyAssemblyName
- && pResultAssemblyName->IsEqual(pPostPolicyAssemblyName, ASM_CMPF_PUBLIC_KEY_TOKEN) == S_OK)
- return;
- }
-#endif // FEATURE_FUSION
ThrowHR(FUSION_E_REF_DEF_MISMATCH);
}
@@ -1173,11 +709,6 @@ PEAssembly *AssemblySpec::ResolveAssemblyFile(AppDomain *pDomain, BOOL fPreBind)
Assembly *pAssembly = pDomain->RaiseAssemblyResolveEvent(this, IsIntrospectionOnly(), fPreBind);
if (pAssembly != NULL) {
-#ifdef FEATURE_FUSION
- if (!IsIntrospectionOnly() && IsLoggingNeeded()) {
- BinderLogging::BindingLog::CacheResultOfAssemblyResolveEvent(pDomain->GetFusionContext(), GetParentLoadContext(), pAssembly);
- }
-#endif
PEAssembly *pFile = pAssembly->GetManifestFile();
pFile->AddRef();
@@ -1206,7 +737,6 @@ Assembly *AssemblySpec::LoadAssembly(FileLoadLevel targetLevel, AssemblyLoadSecu
return pDomainAssembly->GetAssembly();
}
-#if defined(FEATURE_CORECLR)
// Returns a BOOL indicating if the two Binder references point to the same
// binder instance.
BOOL AreSameBinderInstance(ICLRPrivBinder *pBinderA, ICLRPrivBinder *pBinderB)
@@ -1233,7 +763,6 @@ BOOL AreSameBinderInstance(ICLRPrivBinder *pBinderA, ICLRPrivBinder *pBinderB)
return fIsSameInstance;
}
-#endif // defined(FEATURE_CORECLR)
ICLRPrivBinder* AssemblySpec::GetBindingContextFromParentAssembly(AppDomain *pDomain)
{
@@ -1267,7 +796,6 @@ ICLRPrivBinder* AssemblySpec::GetBindingContextFromParentAssembly(AppDomain *pDo
}
}
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
if (GetPreferFallbackLoadContextBinder())
{
// If we have been asked to use the fallback load context binder (currently only supported for AssemblyLoadContext.LoadFromAssemblyName),
@@ -1334,7 +862,6 @@ ICLRPrivBinder* AssemblySpec::GetBindingContextFromParentAssembly(AppDomain *pDo
// used as the parent assembly binder.
pParentAssemblyBinder = static_cast<ICLRPrivBinder*>(pDomain->GetFusionContext());
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
return pParentAssemblyBinder;
}
@@ -1360,78 +887,6 @@ DomainAssembly *AssemblySpec::LoadDomainAssembly(FileLoadLevel targetLevel,
ETWOnStartup (LoaderCatchCall_V1, LoaderCatchCallEnd_V1);
AppDomain* pDomain = GetAppDomain();
-#ifndef FEATURE_CORECLR
- // Event Tracing for Windows is used to log data for performance and functional testing purposes.
- // The events in this function are used to help measure the performance of assembly loading as a whole for dynamic loads.
-
- // Special-purpose holder structure to ensure the LoaderPhaseEnd ETW event is fired when returning from function.
- struct ETWLoaderPhaseHolder
- {
- StackSString ETWCodeBase, ETWAssemblyName;
-
- DWORD _dwAppDomainId;
- BOOL initialized;
-
- ETWLoaderPhaseHolder()
- : _dwAppDomainId(ETWAppDomainIdNotAvailable)
- , initialized(FALSE)
- { }
-
- void Init(DWORD dwAppDomainId, LPCWSTR wszCodeBase, LPCSTR szAssemblyName)
- {
- _dwAppDomainId = dwAppDomainId;
-
- EX_TRY
- {
- if (wszCodeBase != NULL)
- {
- ETWCodeBase.Append(wszCodeBase);
- ETWCodeBase.Normalize(); // Ensures that the later cast to LPCWSTR does not throw.
- }
- }
- EX_CATCH
- {
- ETWCodeBase.Clear();
- }
- EX_END_CATCH(RethrowTransientExceptions)
-
- EX_TRY
- {
- if (szAssemblyName != NULL)
- {
- ETWAssemblyName.AppendUTF8(szAssemblyName);
- ETWAssemblyName.Normalize(); // Ensures that the later cast to LPCWSTR does not throw.
- }
- }
- EX_CATCH
- {
- ETWAssemblyName.Clear();
- }
- EX_END_CATCH(RethrowTransientExceptions)
-
- FireEtwLoaderPhaseStart(_dwAppDomainId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderDynamicLoad, ETWCodeBase.IsEmpty() ? NULL : (LPCWSTR)ETWCodeBase, ETWAssemblyName.IsEmpty() ? NULL : (LPCWSTR)ETWAssemblyName, GetClrInstanceId());
-
- initialized = TRUE;
- }
-
- ~ETWLoaderPhaseHolder()
- {
- if (initialized)
- {
- FireEtwLoaderPhaseEnd(_dwAppDomainId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderDynamicLoad, ETWCodeBase.IsEmpty() ? NULL : (LPCWSTR)ETWCodeBase, ETWAssemblyName.IsEmpty() ? NULL : (LPCWSTR)ETWAssemblyName, GetClrInstanceId());
- }
- }
- };
-
- ETWLoaderPhaseHolder loaderPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
-#ifdef FEATURE_FUSION
- loaderPhaseHolder.Init(pDomain->GetId().m_dwId, m_wszCodeBase, m_pAssemblyName);
-#else
- loaderPhaseHolder.Init(pDomain->GetId().m_dwId, NULL, NULL);
-#endif
- }
-#endif // FEATURE_CORECLR
DomainAssembly *pAssembly = nullptr;
@@ -1443,13 +898,6 @@ DomainAssembly *AssemblySpec::LoadDomainAssembly(FileLoadLevel targetLevel,
pBinder = GetBindingContextFromParentAssembly(pDomain);
}
-#ifdef FEATURE_APPX_BINDER
- // If no explicit or parent binder, check domain.
- if (pBinder == nullptr && AppX::IsAppXProcess())
- {
- pBinder = pDomain->GetCurrentLoadContextHostBinder();
- }
-#endif
if (pBinder != nullptr)
{
@@ -1473,28 +921,6 @@ DomainAssembly *AssemblySpec::LoadDomainAssembly(FileLoadLevel targetLevel,
RETURN pAssembly;
}
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
- if (IsIntrospectionOnly() && (GetCodeBase() == NULL))
- {
- SafeComHolder<IAssemblyName> pIAssemblyName;
- IfFailThrow(CreateFusionName(&pIAssemblyName));
-
- // Note: We do not support introspection-only collectible assemblies (yet)
- AppDomain::AssemblyIterator i = pDomain->IterateAssembliesEx(
- (AssemblyIterationFlags)(kIncludeLoaded | kIncludeIntrospection | kExcludeCollectible));
- CollectibleAssemblyHolder<DomainAssembly *> pCachedDomainAssembly;
-
- while (i.Next(pCachedDomainAssembly.This()))
- {
- _ASSERTE(!pCachedDomainAssembly->IsCollectible());
- IAssemblyName * pCachedAssemblyName = pCachedDomainAssembly->GetAssembly()->GetFusionAssemblyName();
- if (S_OK == pCachedAssemblyName->IsEqual(pIAssemblyName, ASM_CMPF_IL_ALL))
- {
- RETURN pCachedDomainAssembly;
- }
- }
- }
-#endif // FEATURE_REFLECTION_ONLY_LOAD
PEAssemblyHolder pFile(pDomain->BindAssemblySpec(this, fThrowOnFileNotFound, fRaisePrebindEvents, pCallerStackMark, pLoadSecurity));
if (pFile == NULL)
@@ -1549,7 +975,6 @@ Assembly *AssemblySpec::LoadAssembly(LPCWSTR pFilePath)
RETURN spec.LoadAssembly(FILE_LOADED);
}
-#ifndef FEATURE_FUSION
HRESULT AssemblySpec::CheckFriendAssemblyName()
{
WRAPPER_NO_CONTRACT;
@@ -1567,7 +992,6 @@ HRESULT AssemblySpec::CheckFriendAssemblyName()
return S_OK;
}
}
-#endif //FEATURE_FUSION
HRESULT AssemblySpec::EmitToken(
IMetaDataAssemblyEmit *pEmit,
@@ -1821,7 +1245,6 @@ void AssemblySpecBindingCache::Init(CrstBase *pCrst, LoaderHeap *pHeap)
m_pHeap = pHeap;
}
-#if defined(FEATURE_CORECLR)
AssemblySpecBindingCache::AssemblyBinding* AssemblySpecBindingCache::GetAssemblyBindingEntryForAssemblySpec(AssemblySpec* pSpec, BOOL fThrow)
{
CONTRACTL
@@ -1853,7 +1276,14 @@ AssemblySpecBindingCache::AssemblyBinding* AssemblySpecBindingCache::GetAssembly
// Check if the AssemblySpec already has specified its binding context. This will be set for assemblies that are
// attempted to be explicitly bound using AssemblyLoadContext LoadFrom* methods.
- pBinderContextForLookup = pSpec->GetBindingContext();
+ if(!pSpec->IsAssemblySpecForMscorlib())
+ pBinderContextForLookup = pSpec->GetBindingContext();
+ else
+ {
+ // For System.Private.Corelib Binding context is either not set or if set then it should be TPA
+ _ASSERTE(pSpec->GetBindingContext() == NULL || pSpec->GetBindingContext() == pSpecDomain->GetFusionContext());
+ }
+
if (pBinderContextForLookup != NULL)
{
// We are working with the actual binding context in which the assembly was expected to be loaded.
@@ -1895,19 +1325,12 @@ AssemblySpecBindingCache::AssemblyBinding* AssemblySpecBindingCache::GetAssembly
return pEntry;
}
-#endif // defined(FEATURE_CORECLR)
BOOL AssemblySpecBindingCache::Contains(AssemblySpec *pSpec)
{
WRAPPER_NO_CONTRACT;
-#if !defined(FEATURE_CORECLR)
- DWORD key = pSpec->Hash();
- AssemblyBinding *entry = (AssemblyBinding *) m_map.LookupValue(key, pSpec);
- return (entry != (AssemblyBinding *) INVALIDENTRY);
-#else // defined(FEATURE_CORECLR)
return (GetAssemblyBindingEntryForAssemblySpec(pSpec, TRUE) != (AssemblyBinding *) INVALIDENTRY);
-#endif // !defined(FEATURE_CORECLR)
}
DomainAssembly *AssemblySpecBindingCache::LookupAssembly(AssemblySpec *pSpec,
@@ -1933,12 +1356,7 @@ DomainAssembly *AssemblySpecBindingCache::LookupAssembly(AssemblySpec *pSpec,
AssemblyBinding *entry = (AssemblyBinding *) INVALIDENTRY;
-#if !defined(FEATURE_CORECLR)
- DWORD key = pSpec->Hash();
- entry = (AssemblyBinding *) m_map.LookupValue(key, pSpec);
-#else // defined(FEATURE_CORECLR)
entry = GetAssemblyBindingEntryForAssemblySpec(pSpec, fThrow);
-#endif // !defined(FEATURE_CORECLR)
if (entry == (AssemblyBinding *) INVALIDENTRY)
RETURN NULL;
@@ -1976,12 +1394,7 @@ PEAssembly *AssemblySpecBindingCache::LookupFile(AssemblySpec *pSpec, BOOL fThro
AssemblyBinding *entry = (AssemblyBinding *) INVALIDENTRY;
-#if !defined(FEATURE_CORECLR)
- DWORD key = pSpec->Hash();
- entry = (AssemblyBinding *) m_map.LookupValue(key, pSpec);
-#else // defined(FEATURE_CORECLR)
entry = GetAssemblyBindingEntryForAssemblySpec(pSpec, fThrow);
-#endif // !defined(FEATURE_CORECLR)
if (entry == (AssemblyBinding *) INVALIDENTRY)
RETURN NULL;
@@ -2108,7 +1521,6 @@ BOOL AssemblySpecBindingCache::StoreAssembly(AssemblySpec *pSpec, DomainAssembly
UPTR key = (UPTR)pSpec->Hash();
-#if defined(FEATURE_CORECLR)
// On CoreCLR, we will use the BinderID as the key
ICLRPrivBinder* pBinderContextForLookup = pAssembly->GetFile()->GetBindingContext();
_ASSERTE(pBinderContextForLookup || pAssembly->GetFile()->IsSystem());
@@ -2124,7 +1536,6 @@ BOOL AssemblySpecBindingCache::StoreAssembly(AssemblySpec *pSpec, DomainAssembly
pSpec->SetBindingContext(pBinderContextForLookup);
}
}
-#endif // defined(FEATURE_CORECLR)
AssemblyBinding *entry = (AssemblyBinding *) m_map.LookupValue(key, pSpec);
@@ -2190,7 +1601,6 @@ BOOL AssemblySpecBindingCache::StoreFile(AssemblySpec *pSpec, PEAssembly *pFile)
UPTR key = (UPTR)pSpec->Hash();
-#if defined(FEATURE_CORECLR)
// On CoreCLR, we will use the BinderID as the key
ICLRPrivBinder* pBinderContextForLookup = pFile->GetBindingContext();
_ASSERTE(pBinderContextForLookup || pFile->IsSystem());
@@ -2206,7 +1616,6 @@ BOOL AssemblySpecBindingCache::StoreFile(AssemblySpec *pSpec, PEAssembly *pFile)
pSpec->SetBindingContext(pBinderContextForLookup);
}
}
-#endif // defined(FEATURE_CORECLR)
AssemblyBinding *entry = (AssemblyBinding *) m_map.LookupValue(key, pSpec);
@@ -2263,9 +1672,6 @@ BOOL AssemblySpecBindingCache::StoreException(AssemblySpec *pSpec, Exception* pE
UPTR key = (UPTR)pSpec->Hash();
-#if !defined(FEATURE_CORECLR)
- AssemblyBinding *entry = (AssemblyBinding *) m_map.LookupValue(key, pSpec);
-#else // defined(FEATURE_CORECLR)
AssemblyBinding *entry = GetAssemblyBindingEntryForAssemblySpec(pSpec, TRUE);
if (entry == (AssemblyBinding *) INVALIDENTRY)
{
@@ -2287,7 +1693,6 @@ BOOL AssemblySpecBindingCache::StoreException(AssemblySpec *pSpec, Exception* pE
}
}
}
-#endif // defined(FEATURE_CORECLR)
if (entry == (AssemblyBinding *) INVALIDENTRY) {
AssemblyBindingHolder abHolder;
@@ -2342,11 +1747,6 @@ BOOL AssemblySpecBindingCache::CompareSpecs(UPTR u1, UPTR u2)
AssemblySpec *a1 = (AssemblySpec *) (u1 << 1);
AssemblySpec *a2 = (AssemblySpec *) u2;
-#if defined(FEATURE_APPX_BINDER)
- _ASSERTE(a1->GetAppDomain() == a2->GetAppDomain());
- if (a1->GetAppDomain()->HasLoadContextHostBinder())
- return (CLRPrivBinderUtil::CompareHostBinderSpecs(a1,a2));
-#endif
if ((!a1->CompareEx(a2)) ||
(a1->IsIntrospectionOnly() != a2->IsIntrospectionOnly()))
@@ -2364,12 +1764,6 @@ BOOL DomainAssemblyCache::CompareBindingSpec(UPTR spec1, UPTR spec2)
AssemblySpec* pSpec1 = (AssemblySpec*) (spec1 << 1);
AssemblyEntry* pEntry2 = (AssemblyEntry*) spec2;
-#if defined(FEATURE_FUSION)
- AssemblySpec* pSpec2 = &pEntry2->spec;
- _ASSERTE(pSpec1->GetAppDomain() == pSpec2->GetAppDomain());
- if (pSpec1->GetAppDomain()->HasLoadContextHostBinder())
- return (CLRPrivBinderUtil::CompareHostBinderSpecs(pSpec1,pSpec2));
-#endif
if ((!pSpec1->CompareEx(&pEntry2->spec)) ||
@@ -2447,31 +1841,6 @@ VOID DomainAssemblyCache::InsertEntry(AssemblySpec* pSpec, LPVOID pData1, LPVOID
}
-#ifdef FEATURE_FUSION
-
-IAssembly * AssemblySpec::GetParentIAssembly()
-{
- LIMITED_METHOD_CONTRACT;
- if(m_pParentAssembly)
- return m_pParentAssembly->GetFile()->GetFusionAssembly();
-
- return NULL;
-}
-
-LPCVOID AssemblySpec::GetParentAssemblyPtr()
-{
- LIMITED_METHOD_CONTRACT;
- if(m_pParentAssembly)
- {
- if (m_pParentAssembly->GetFile()->HasHostAssembly())
- return m_pParentAssembly->GetFile()->GetHostAssembly();
- else
- return m_pParentAssembly->GetFile()->GetFusionAssembly();
- }
- return NULL;
-}
-
-#endif //FEATURE_FUSION
diff --git a/src/vm/assemblyspec.hpp b/src/vm/assemblyspec.hpp
index d94a847124..ae02f20ccf 100644
--- a/src/vm/assemblyspec.hpp
+++ b/src/vm/assemblyspec.hpp
@@ -17,9 +17,6 @@
#define _ASSEMBLYSPEC_H
#include "hash.h"
#include "memorypool.h"
-#ifdef FEATURE_FUSION
-#include "fusionbind.h"
-#endif
#include "assemblyspecbase.h"
#include "domainfile.h"
#include "genericstackprobe.h"
@@ -42,13 +39,11 @@ class AssemblySpec : public BaseAssemblySpec
DWORD m_dwHashAlg;
DomainAssembly *m_pParentAssembly;
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
// Contains the reference to the fallback load context associated with RefEmitted assembly requesting the load of another assembly (static or dynamic)
ICLRPrivBinder *m_pFallbackLoadContextBinder;
// Flag to indicate if we should prefer the fallback load context binder for binding or not.
bool m_fPreferFallbackLoadContextBinder;
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
BOOL IsValidAssemblyName();
@@ -76,10 +71,8 @@ class AssemblySpec : public BaseAssemblySpec
LIMITED_METHOD_CONTRACT;
m_pParentAssembly = NULL;
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
m_pFallbackLoadContextBinder = NULL;
m_fPreferFallbackLoadContextBinder = false;
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
}
#endif //!DACCESS_COMPILE
@@ -89,18 +82,11 @@ class AssemblySpec : public BaseAssemblySpec
LIMITED_METHOD_CONTRACT
m_pParentAssembly = NULL;
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
m_pFallbackLoadContextBinder = NULL;
m_fPreferFallbackLoadContextBinder = false;
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
}
-#ifdef FEATURE_FUSION
- virtual IAssembly* GetParentIAssembly();
-
- virtual LPCVOID GetParentAssemblyPtr();
-#endif
DomainAssembly* GetParentAssembly();
@@ -125,16 +111,8 @@ class AssemblySpec : public BaseAssemblySpec
HRESULT hr=InitializeSpecInternal(kAssemblyRefOrDef, pImport,pStaticParent,fIntrospectionOnly,TRUE);
if(FAILED(hr))
EEFileLoadException::Throw(this,hr);
-#ifndef FEATURE_CORECLR
- CloneFields();
-#endif
};
-#ifdef FEATURE_FUSION
- void InitializeSpec(IAssemblyName *pName,
- DomainAssembly *pStaticParent = NULL,
- BOOL fIntrospectionOnly = FALSE);
-#endif // FEATURE_FUSION
void InitializeSpec(PEAssembly *pFile);
HRESULT InitializeSpec(StackingAllocator* alloc,
@@ -144,9 +122,6 @@ class AssemblySpec : public BaseAssemblySpec
void AssemblyNameInit(ASSEMBLYNAMEREF* pName, PEImage* pImageInfo); //[in,out], [in]
-#ifdef FEATURE_MIXEDMODE
- void InitializeSpec(HINSTANCE hMod, BOOL fIntrospectionOnly = FALSE);
-#endif // FEATURE_MIXEDMODE
void SetCodeBase(LPCWSTR szCodeBase)
{
@@ -167,18 +142,8 @@ class AssemblySpec : public BaseAssemblySpec
CONTRACTL_END;
m_pParentAssembly = pAssembly;
-#ifdef FEATURE_FUSION
- if (pAssembly)
- {
- _ASSERTE(GetHostBinder() == nullptr);
- m_fParentLoadContext=pAssembly->GetFile()->GetLoadContext();
- }
- else
- m_fParentLoadContext = LOADCTX_TYPE_DEFAULT;
-#endif
}
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
void SetFallbackLoadContextBinderForRequestingAssembly(ICLRPrivBinder *pFallbackLoadContextBinder)
{
LIMITED_METHOD_CONTRACT;
@@ -206,7 +171,6 @@ class AssemblySpec : public BaseAssemblySpec
return m_fPreferFallbackLoadContextBinder;
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
// Note that this method does not clone the fields!
void CopyFrom(AssemblySpec* pSource)
@@ -224,20 +188,16 @@ class AssemblySpec : public BaseAssemblySpec
SetIntrospectionOnly(pSource->IsIntrospectionOnly());
SetParentAssembly(pSource->GetParentAssembly());
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
// Copy the details of the fallback load context binder
SetFallbackLoadContextBinderForRequestingAssembly(pSource->GetFallbackLoadContextBinderForRequestingAssembly());
m_fPreferFallbackLoadContextBinder = pSource->GetPreferFallbackLoadContextBinder();
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
m_HashForControl = pSource->m_HashForControl;
m_dwHashAlg = pSource->m_dwHashAlg;
}
-#ifndef FEATURE_FUSION
HRESULT CheckFriendAssemblyName();
-#endif // FEATURE_FUSION
HRESULT EmitToken(IMetaDataAssemblyEmit *pEmit,
@@ -253,15 +213,8 @@ class AssemblySpec : public BaseAssemblySpec
FILE_WEBPERM = 0x3
};
-#ifdef FEATURE_FUSION
- static void DemandFileIOPermission(LPCWSTR wszCodeBase,
- BOOL fHavePath,
- DWORD dwDemandFlag);
- void DemandFileIOPermission(PEAssembly *pFile);
-#endif
-#ifndef FEATURE_FUSION
VOID Bind(
AppDomain* pAppDomain,
BOOL fThrowOnFileNotFound,
@@ -269,10 +222,6 @@ class AssemblySpec : public BaseAssemblySpec
BOOL fNgenExplicitBind = FALSE,
BOOL fExplicitBindToNativeImage = FALSE,
StackCrawlMark *pCallerStackMark = NULL );
-#ifndef FEATURE_CORECLR
- static VOID BindToSystem(BINDER_SPACE::Assembly** ppAssembly);
-#endif
-#endif
Assembly *LoadAssembly(FileLoadLevel targetLevel,
AssemblyLoadSecurity *pLoadSecurity = NULL,
@@ -294,27 +243,10 @@ class AssemblySpec : public BaseAssemblySpec
DWORD cbPublicKeyOrToken,
DWORD dwFlags);
-#ifdef FEATURE_FUSION
- //****************************************************************************************
- //
- HRESULT LoadAssembly(IApplicationContext *pFusionContext,
- FusionSink *pSink,
- IAssembly** ppIAssembly,
- IHostAssembly** ppIHostAssembly,
- IBindResult **ppNativeFusionAssembly,
- BOOL fForIntrospectionOnly,
- BOOL fSuppressSecurityChecks);
-#endif
// Load an assembly based on an explicit path
static Assembly *LoadAssembly(LPCWSTR pFilePath);
-#ifdef FEATURE_FUSION
- BOOL FindAssemblyFile(AppDomain *pAppDomain, BOOL fThrowOnFileNotFound,
- IAssembly** ppIAssembly, IHostAssembly **ppIHostAssembly, IBindResult** pNativeFusionAssembly,
- IFusionBindLog **ppFusionLog, HRESULT *pHRBindResult, StackCrawlMark *pCallerStackMark = NULL,
- AssemblyLoadSecurity *pLoadSecurity = NULL);
-#endif // FEATURE_FUSION
private:
void MatchRetargetedPublicKeys(Assembly *pAssembly);
@@ -385,11 +317,7 @@ class AssemblySpec : public BaseAssemblySpec
inline BOOL CanUseWithBindingCache() const
{
STATIC_CONTRACT_LIMITED_METHOD;
-#if defined(FEATURE_APPX_BINDER)
- return (GetHostBinder() == nullptr) && HasUniqueIdentity();
-#else
return HasUniqueIdentity();
-#endif
}
inline ICLRPrivBinder *GetHostBinder() const
@@ -653,9 +581,7 @@ class AssemblySpecBindingCache
PtrHashMap m_map;
LoaderHeap *m_pHeap;
-#if defined(FEATURE_CORECLR)
AssemblySpecBindingCache::AssemblyBinding* GetAssemblyBindingEntryForAssemblySpec(AssemblySpec* pSpec, BOOL fThrow);
-#endif // defined(FEATURE_CORECLR)
public:
@@ -683,7 +609,7 @@ class AssemblySpecBindingCache
return pSpec->Hash();
}
-#if defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE)
+#if !defined(DACCESS_COMPILE)
void GetAllAssemblies(SetSHash<PTR_DomainAssembly>& assemblyList)
{
PtrHashMap::PtrIterator i = m_map.begin();
@@ -695,7 +621,7 @@ class AssemblySpecBindingCache
++i;
}
}
-#endif // defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE)
+#endif // !defined(DACCESS_COMPILE)
static BOOL CompareSpecs(UPTR u1, UPTR u2);
};
diff --git a/src/vm/assemblyspecbase.h b/src/vm/assemblyspecbase.h
index a52df06009..3442c9184e 100644
--- a/src/vm/assemblyspecbase.h
+++ b/src/vm/assemblyspecbase.h
@@ -16,11 +16,9 @@
#ifndef __ASSEMBLY_SPEC_BASE_H__
#define __ASSEMBLY_SPEC_BASE_H__
-#ifndef FEATURE_FUSION
#include "coreclr/corebindresult.h"
#include "coreclr/corebindresult.inl"
#include "../binder/inc/assembly.hpp"
-#endif // FEATURE_FUSION
#include "baseassemblyspec.h"
#include "baseassemblyspec.inl"
diff --git a/src/vm/baseassemblyspec.cpp b/src/vm/baseassemblyspec.cpp
index 806416e923..4d6ba26e40 100644
--- a/src/vm/baseassemblyspec.cpp
+++ b/src/vm/baseassemblyspec.cpp
@@ -122,7 +122,6 @@ BOOL BaseAssemblySpec::IsMscorlib()
( (iNameLen == CoreLibNameLen) || (m_pAssemblyName[CoreLibNameLen] == ',') ) ) ) );
}
-#ifdef FEATURE_CORECLR
BOOL BaseAssemblySpec::IsAssemblySpecForMscorlib()
{
CONTRACTL
@@ -150,9 +149,6 @@ BOOL BaseAssemblySpec::IsAssemblySpecForMscorlib()
}
#define MSCORLIB_PUBLICKEY g_rbTheSilverlightPlatformKey
-#else
-#define MSCORLIB_PUBLICKEY g_rbNeutralPublicKey
-#endif
// A satellite assembly for mscorlib is named "mscorlib.resources" or
@@ -232,7 +228,6 @@ VOID BaseAssemblySpec::ConvertPublicKeyToToken()
m_dwFlags &= ~afPublicKey;
}
-#ifndef FEATURE_FUSION
// Similar to BaseAssemblySpec::CompareEx, but allows the ref to be partially specified
// Returns TRUE if ref matches def, FALSE otherwise.
//
@@ -271,9 +266,9 @@ BOOL BaseAssemblySpec::CompareRefToDef(const BaseAssemblySpec *pRef, const BaseA
}
//
- // flags are non-optional, except processor architecture and content type
+ // flags are non-optional, except processor architecture, content type, and debuggable attribute bits
//
- DWORD dwFlagsMask = ~(afPA_FullMask | afContentType_Mask);
+ DWORD dwFlagsMask = ~(afPA_FullMask | afContentType_Mask | afDebuggableAttributeMask);
if ((pRef->m_dwFlags & dwFlagsMask) != (pDef->m_dwFlags & dwFlagsMask))
return FALSE;
@@ -362,7 +357,6 @@ BOOL BaseAssemblySpec::RefMatchesDef(const BaseAssemblySpec* pRef, const BaseAss
return (CompareStrings(pRef->GetName(), pDef->GetName())==0);
}
}
-#endif // FEATURE_FUSION
//===========================================================================================
// This function may embed additional information, if required.
@@ -683,21 +677,9 @@ HRESULT BaseAssemblySpec::CreateFusionName(
}
}
else {
-#ifdef FEATURE_FUSION
- IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_NULL_PUBLIC_KEY_TOKEN,
- NULL, 0));
-#endif
}
}
-#ifdef FEATURE_FUSION
- // See if the assembly[ref] is retargetable (ie, for a generic assembly).
- if (IsAfRetargetable(m_dwFlags)) {
- BOOL bTrue = TRUE;
- IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_RETARGET,
- &bTrue, sizeof(bTrue)));
- }
-#endif
// Set the Processor Architecture (if any)
{
@@ -723,15 +705,7 @@ HRESULT BaseAssemblySpec::CreateFusionName(
}
}
-#ifdef FEATURE_FUSION
- if (fIncludeCodeBase && m_wszCodeBase) {
- IfFailGo(pFusionAssemblyName->SetProperty(ASM_NAME_CODEBASE_URL,
- (void*)m_wszCodeBase,
- (DWORD)(wcslen(m_wszCodeBase)+1) * sizeof(WCHAR)));
- }
-#else
_ASSERTE(m_wszCodeBase == NULL);
-#endif
*ppName = pFusionAssemblyName;
diff --git a/src/vm/baseassemblyspec.h b/src/vm/baseassemblyspec.h
index 0a21d95ee8..9381157f7a 100644
--- a/src/vm/baseassemblyspec.h
+++ b/src/vm/baseassemblyspec.h
@@ -27,18 +27,12 @@ protected:
DWORD m_cbPublicKeyOrToken;
DWORD m_dwFlags; // CorAssemblyFlags
LPCWSTR m_wszCodeBase; // URL to the code
-#ifdef FEATURE_FUSION
- LOADCTX_TYPE m_fParentLoadContext; // m_pParentAssembly->GetFusionLoadContext()
- ReleaseHolder<IAssemblyName> m_pNameAfterPolicy;
-#endif
LPCSTR m_szWinRtTypeNamespace;
LPCSTR m_szWinRtTypeClassName;
ICLRPrivBinder *m_pHostBinder;
int m_ownedFlags;
BOOL m_fIntrospectionOnly;
-#if defined(FEATURE_CORECLR)
ICLRPrivBinder *m_pBindingContext;
-#endif // defined(FEATURE_CORECLR)
public:
enum
@@ -76,7 +70,6 @@ public:
VOID CloneFieldsToLoaderHeap(int flags, LoaderHeap *pHeap, AllocMemTracker *pamTracker);
VOID CloneFieldsToStackingAllocator(StackingAllocator* alloc);
-#if defined(FEATURE_CORECLR)
inline void SetBindingContext(ICLRPrivBinder *pBindingContext)
{
LIMITED_METHOD_CONTRACT;
@@ -92,7 +85,6 @@ public:
}
BOOL IsAssemblySpecForMscorlib();
-#endif // defined(FEATURE_CORECLR)
HRESULT ParseName();
DWORD Hash();
@@ -150,19 +142,6 @@ public:
BOOL fIncludeCodeBase = TRUE, /* Used by fusion only */
BOOL fMustBeBindable = FALSE) const;
-#ifdef FEATURE_FUSION
- // for fusion binding
- virtual IAssembly* GetParentIAssembly() =0;
-
- // for identity comparison
- virtual LPCVOID GetParentAssemblyPtr() =0;
-
- inline LOADCTX_TYPE GetParentLoadContext()
- {
- LIMITED_METHOD_CONTRACT;
- return m_fParentLoadContext;
- }
-#endif
BOOL IsIntrospectionOnly()
{
@@ -253,48 +232,6 @@ public:
return IsAfRetargetable(m_dwFlags);
}
-#ifdef FEATURE_FUSION
- inline IAssemblyName* GetNameAfterPolicy() const
- {
- LIMITED_METHOD_CONTRACT;
- return m_pNameAfterPolicy;
- }
-
- inline void ReleaseNameAfterPolicy()
- {
- LIMITED_METHOD_CONTRACT;
- m_pNameAfterPolicy=NULL;
- }
-
- inline void SetNameAfterPolicy(IAssemblyName* pName)
- {
- LIMITED_METHOD_CONTRACT;
- m_pNameAfterPolicy=pName;
- }
-
-
- void SetPEKIND(PEKIND peKind)
- {
- LIMITED_METHOD_CONTRACT;
- C_ASSERT(afPA_None == PAFlag(peNone));
- C_ASSERT(afPA_MSIL == PAFlag(peMSIL));
- C_ASSERT(afPA_x86 == PAFlag(peI386));
- C_ASSERT(afPA_IA64 == PAFlag(peIA64));
- C_ASSERT(afPA_AMD64 == PAFlag(peAMD64));
- C_ASSERT(afPA_ARM == PAFlag(peARM));
-
- _ASSERTE((peKind <= peARM) || (peKind == peInvalid));
-
- m_dwFlags &= ~afPA_FullMask;
- m_dwFlags |= PAFlag(peKind);
- }
-
- PEKIND GetPEKIND() const
- {
- LIMITED_METHOD_CONTRACT;
- return static_cast<PEKIND>(PAIndex(m_dwFlags));
- }
-#endif //FEATURE_FUSION
protected:
static BOOL CompareRefToDef(const BaseAssemblySpec *pRef, const BaseAssemblySpec *pDef);
diff --git a/src/vm/baseassemblyspec.inl b/src/vm/baseassemblyspec.inl
index 53c312f069..5205056c14 100644
--- a/src/vm/baseassemblyspec.inl
+++ b/src/vm/baseassemblyspec.inl
@@ -17,9 +17,7 @@
extern LocaleID g_lcid;
-#if defined(FEATURE_CORECLR)
BOOL AreSameBinderInstance(ICLRPrivBinder *pBinderA, ICLRPrivBinder *pBinderB);
-#endif // defined(FEATURE_CORECLR)
inline int BaseAssemblySpec::CompareStrings(LPCUTF8 string1, LPCUTF8 string2)
{
@@ -262,25 +260,13 @@ inline void BaseAssemblySpec::CopyFrom(const BaseAssemblySpec *pSpec)
m_pHostBinder = pSpec->m_pHostBinder;
-#ifdef FEATURE_CORECLR
if ((pSpec->m_ownedFlags & BAD_NAME_OWNED) != 0)
{
m_ownedFlags |= BAD_NAME_OWNED;
}
-#endif
-#ifdef FEATURE_FUSION
- IAssemblyName* pNameAfterPolicy=pSpec->GetNameAfterPolicy();
- if (pNameAfterPolicy)
- {
- pNameAfterPolicy->AddRef();
- SetNameAfterPolicy(pNameAfterPolicy);
- }
-#endif
-#if defined(FEATURE_CORECLR)
m_pBindingContext = pSpec->m_pBindingContext;
-#endif // defined(FEATURE_CORECLR)
}
@@ -294,10 +280,8 @@ inline DWORD BaseAssemblySpec::Hash()
MODE_ANY;
} CONTRACTL_END;
-#ifdef FEATURE_CORECLR
if(m_wszCodeBase)
return HashString(m_wszCodeBase);
-#endif
// Hash fields.
DWORD hash = 0;
@@ -312,11 +296,6 @@ inline DWORD BaseAssemblySpec::Hash()
hash ^= m_dwFlags;
hash = _rotl(hash, 4);
-#ifndef FEATURE_CORECLR
- if (m_wszCodeBase)
- hash ^= HashString(m_wszCodeBase);
- hash = _rotl(hash, 4);
-#endif
hash ^= m_context.usMajorVersion;
hash = _rotl(hash, 8);
@@ -352,9 +331,6 @@ inline DWORD BaseAssemblySpec::Hash()
hash = _rotl(hash, 4);
}
-#ifdef FEATURE_FUSION
- hash ^= (m_fParentLoadContext == LOADCTX_TYPE_LOADFROM);
-#endif
return hash;
}
@@ -364,50 +340,15 @@ inline BOOL BaseAssemblySpec::CompareEx(BaseAssemblySpec *pSpec, DWORD dwCompare
{
WRAPPER_NO_CONTRACT;
-#ifndef FEATURE_CORECLR
- _ASSERTE(pSpec != NULL);
- if ((m_dwFlags & afContentType_Mask) == (pSpec->m_dwFlags & afContentType_Mask))
- {
- if (IsContentType_WindowsRuntime() && pSpec->IsContentType_WindowsRuntime())
- {
- // If comparing assembly definitions, can not use bindability attributes as
- // a shortcut for equivalence, as this type of shortcut is only applicable
- // when comparing assembly references (not definitions).
- //
- // Example of why this is needed: native images still need to compare
- // assembly identities even if they are not bindable, because it needs to
- // ensure that the exact same assembly file (definition) is used at runtime
- // as was used during compilation.
- if ((dwCompareFlags & ASC_DefinitionEquality) != ASC_DefinitionEquality)
- {
- // WinRT assembly references are meaningless, they are all equal to each other
- return TRUE;
- }
- }
- }
- else
- {
- return FALSE;
- }
-#endif
-
-#ifdef FEATURE_CORECLR
if(m_wszCodeBase || pSpec->m_wszCodeBase)
{
if(!m_wszCodeBase || !pSpec->m_wszCodeBase)
return FALSE;
return wcscmp(m_wszCodeBase,(pSpec->m_wszCodeBase))==0;
}
-#endif
// Compare fields
-#ifdef FEATURE_FUSION
- BOOL fIsInLoadFromContext = (m_fParentLoadContext == LOADCTX_TYPE_LOADFROM);
- BOOL fSpecIsInLoadFromContext = (pSpec->m_fParentLoadContext == LOADCTX_TYPE_LOADFROM);
- if (fIsInLoadFromContext != fSpecIsInLoadFromContext)
- return FALSE;
-#endif
if (m_pAssemblyName != pSpec->m_pAssemblyName
&& (m_pAssemblyName == NULL || pSpec->m_pAssemblyName == NULL
@@ -418,12 +359,6 @@ inline BOOL BaseAssemblySpec::CompareEx(BaseAssemblySpec *pSpec, DWORD dwCompare
|| memcmp(m_pbPublicKeyOrToken, pSpec->m_pbPublicKeyOrToken, m_cbPublicKeyOrToken))
return FALSE;
-#ifndef FEATURE_CORECLR
- if (m_wszCodeBase != pSpec->m_wszCodeBase
- && (m_wszCodeBase == NULL || pSpec->m_wszCodeBase == NULL
- || wcscmp(m_wszCodeBase, pSpec->m_wszCodeBase)))
- return FALSE;
-#endif
if (m_dwFlags != pSpec->m_dwFlags)
return FALSE;
@@ -451,21 +386,7 @@ inline BOOL BaseAssemblySpec::CompareEx(BaseAssemblySpec *pSpec, DWORD dwCompare
|| strcmp(m_context.szLocale, pSpec->m_context.szLocale)))
return FALSE;
-#ifdef FEATURE_FUSION
- if (!IsIntrospectionOnly() && !pSpec->IsIntrospectionOnly()) {
- // Post-policy load-neither binds can be picked up by nobody
- // except their own parent assembly. This only applies to executable assemblies.
- BOOL bParentsMustMatch;
-
- // doesn't need the check if one is in load context
- bParentsMustMatch = (m_fParentLoadContext == LOADCTX_TYPE_UNKNOWN && pSpec->m_fParentLoadContext == LOADCTX_TYPE_UNKNOWN);
-
- if ( bParentsMustMatch && GetParentAssemblyPtr() != pSpec->GetParentAssemblyPtr())
- return FALSE;
- }
-#endif
-#if defined(FEATURE_CORECLR)
// If the assemblySpec contains the binding context, then check if they match.
if (!(pSpec->IsAssemblySpecForMscorlib() && IsAssemblySpecForMscorlib()))
{
@@ -474,7 +395,6 @@ inline BOOL BaseAssemblySpec::CompareEx(BaseAssemblySpec *pSpec, DWORD dwCompare
return FALSE;
}
}
-#endif // defined(FEATURE_CORECLR)
return TRUE;
diff --git a/src/vm/binder.cpp b/src/vm/binder.cpp
index a4b7572a2a..9ce1584c31 100644
--- a/src/vm/binder.cpp
+++ b/src/vm/binder.cpp
@@ -12,11 +12,7 @@
#include "field.h"
#include "excep.h"
-#ifdef FEATURE_REMOTING
-#include "message.h"
-#endif // FEATURE_REMOTING
#include "eeconfig.h"
-#include "rwlock.h"
#include "runtimehandles.h"
#include "customattribute.h"
#include "debugdebugger.h"
@@ -566,6 +562,7 @@ void MscorlibBinder::Check()
}
}
+#ifdef CHECK_FCALL_SIGNATURE
//
// check consistency of the unmanaged and managed fcall signatures
//
@@ -846,6 +843,7 @@ static void FCallCheckSignature(MethodDesc* pMD, PCODE pImpl)
}
}
}
+#endif // CHECK_FCALL_SIGNATURE
//
// extended check of consistency between mscorlib and mscorwks:
@@ -1051,10 +1049,12 @@ void MscorlibBinder::CheckExtended()
usedECallIds.Add(id);
}
+#ifdef CHECK_FCALL_SIGNATURE
if (pMD->IsFCall())
{
FCallCheckSignature(pMD, ECall::GetFCallImpl(pMD));
}
+#endif // CHECK_FCALL_SIGNATURE
}
pInternalImport->EnumClose(&hEnum);
diff --git a/src/vm/callcounter.cpp b/src/vm/callcounter.cpp
new file mode 100644
index 0000000000..90013c79fb
--- /dev/null
+++ b/src/vm/callcounter.cpp
@@ -0,0 +1,98 @@
+// 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.
+// ===========================================================================
+// File: CallCounter.CPP
+//
+// ===========================================================================
+
+
+
+#include "common.h"
+#include "excep.h"
+#include "log.h"
+#include "tieredcompilation.h"
+#include "callcounter.h"
+
+#ifdef FEATURE_TIERED_COMPILATION
+
+CallCounter::CallCounter()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ m_lock.Init(LOCK_TYPE_DEFAULT);
+}
+
+// Init our connection to the tiered compilation manager during
+// AppDomain startup. This pointer will remain valid for the lifetime
+// of the AppDomain.
+void CallCounter::SetTieredCompilationManager(TieredCompilationManager* pTieredCompilationManager)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CAN_TAKE_LOCK;
+ MODE_PREEMPTIVE;
+ }
+ CONTRACTL_END;
+
+ m_pTieredCompilationManager.Store(pTieredCompilationManager);
+}
+
+// This is called by the prestub each time the method is invoked in a particular
+// AppDomain (the AppDomain for which AppDomain.GetCallCounter() == this). These
+// calls continue until we backpatch the prestub to avoid future calls. This allows
+// us to track the number of calls to each method and use it as a trigger for tiered
+// compilation.
+//
+// Returns TRUE if no future invocations are needed (we reached the count we cared about)
+// and FALSE otherwise. It is permissible to keep calling even when TRUE was previously
+// returned and multi-threaded race conditions will surely cause this to occur.
+BOOL CallCounter::OnMethodCalled(MethodDesc* pMethodDesc)
+{
+ STANDARD_VM_CONTRACT;
+
+ _ASSERTE(pMethodDesc->IsEligibleForTieredCompilation());
+
+ // PERF: This as a simple to implement, but not so performant, call counter
+ // Currently this is only called until we reach a fixed call count and then
+ // disabled. Its likely we'll want to improve this at some point but
+ // its not as bad as you might expect. Allocating a counter inline in the
+ // MethodDesc or at some location computable from the MethodDesc should
+ // eliminate 1 pointer per-method (the MethodDesc* key) and the CPU
+ // overhead to acquire the lock/search the dictionary. Depending on where it
+ // is we may also be able to reduce it to 1 byte counter without wasting the
+ // following bytes for alignment. Further work to inline the OnMethodCalled
+ // callback directly into the jitted code would eliminate CPU overhead of
+ // leaving the prestub unpatched, but may not be good overall as it increases
+ // the size of the jitted code.
+
+
+ TieredCompilationManager* pCallCounterSink = NULL;
+ int callCount;
+ {
+ //Be careful if you convert to something fully lock/interlocked-free that
+ //you correctly handle what happens when some N simultaneous calls don't
+ //all increment the counter. The slight drift is probably neglible for tuning
+ //but TieredCompilationManager::OnMethodCalled() doesn't expect multiple calls
+ //each claiming to be exactly the threshhold call count needed to trigger
+ //optimization.
+ SpinLockHolder holder(&m_lock);
+ CallCounterEntry* pEntry = const_cast<CallCounterEntry*>(m_methodToCallCount.LookupPtr(pMethodDesc));
+ if (pEntry == NULL)
+ {
+ callCount = 1;
+ m_methodToCallCount.Add(CallCounterEntry(pMethodDesc, callCount));
+ }
+ else
+ {
+ pEntry->callCount++;
+ callCount = pEntry->callCount;
+ }
+ }
+
+ return m_pTieredCompilationManager.Load()->OnMethodCalled(pMethodDesc, callCount);
+}
+
+#endif // FEATURE_TIERED_COMPILATION
diff --git a/src/vm/callcounter.h b/src/vm/callcounter.h
new file mode 100644
index 0000000000..82d14b76d9
--- /dev/null
+++ b/src/vm/callcounter.h
@@ -0,0 +1,87 @@
+// 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.
+// ===========================================================================
+// File: CallCounter.h
+//
+// ===========================================================================
+
+
+#ifndef CALL_COUNTER_H
+#define CALL_COUNTER_H
+
+#ifdef FEATURE_TIERED_COMPILATION
+
+// One entry in our dictionary mapping methods to the number of times they
+// have been invoked
+struct CallCounterEntry
+{
+ CallCounterEntry() {}
+ CallCounterEntry(const MethodDesc* m, const int c)
+ : pMethod(m), callCount(c) {}
+
+ const MethodDesc* pMethod;
+ int callCount;
+};
+
+class CallCounterHashTraits : public DefaultSHashTraits<CallCounterEntry>
+{
+public:
+ typedef typename DefaultSHashTraits<CallCounterEntry>::element_t element_t;
+ typedef typename DefaultSHashTraits<CallCounterEntry>::count_t count_t;
+
+ typedef const MethodDesc* key_t;
+
+ static key_t GetKey(element_t e)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return e.pMethod;
+ }
+ static BOOL Equals(key_t k1, key_t k2)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return k1 == k2;
+ }
+ static count_t Hash(key_t k)
+ {
+ LIMITED_METHOD_CONTRACT;
+ return (count_t)(size_t)k;
+ }
+
+ static const element_t Null() { LIMITED_METHOD_CONTRACT; return element_t(NULL, 0); }
+ static const element_t Deleted() { LIMITED_METHOD_CONTRACT; return element_t((const MethodDesc*)-1, 0); }
+ static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e.pMethod == NULL; }
+ static bool IsDeleted(const element_t &e) { return e.pMethod == (const MethodDesc*)-1; }
+};
+
+typedef SHash<NoRemoveSHashTraits<CallCounterHashTraits>> CallCounterHash;
+
+
+// This is a per-appdomain cache of call counts for all code in that AppDomain.
+// Each method invocation should trigger a call to OnMethodCalled (until it is disabled per-method)
+// and the CallCounter will forward the call to the TieredCompilationManager including the
+// current call count.
+class CallCounter
+{
+public:
+#if defined(DACCESS_COMPILE) || defined(CROSSGEN_COMPILE)
+ CallCounter() {}
+#else
+ CallCounter();
+#endif
+
+ void SetTieredCompilationManager(TieredCompilationManager* pTieredCompilationManager);
+ BOOL OnMethodCalled(MethodDesc* pMethodDesc);
+
+private:
+
+ VolatilePtr<TieredCompilationManager> m_pTieredCompilationManager;
+
+ // fields protected by lock
+ SpinLock m_lock;
+ CallCounterHash m_methodToCallCount;
+};
+
+#endif // FEATURE_TIERED_COMPILATION
+
+#endif // CALL_COUNTER_H
diff --git a/src/vm/callhelpers.cpp b/src/vm/callhelpers.cpp
index addd5192da..c575ee615d 100644
--- a/src/vm/callhelpers.cpp
+++ b/src/vm/callhelpers.cpp
@@ -35,17 +35,6 @@ void AssertMulticoreJitAllowedModule(PCODE pTarget)
Module * pModule = pMethod->GetModule_NoLogging();
-#if defined(FEATURE_APPX_BINDER)
-
- // For Appx process, allow certain modules to load on background thread
- if (AppX::IsAppXProcess())
- {
- if (MulticoreJitManager::IsLoadOkay(pModule))
- {
- return;
- }
- }
-#endif
_ASSERTE(pModule->IsSystem());
}
@@ -445,7 +434,7 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT *
#ifdef _DEBUG
{
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
// Validate that the return value is not too big for the buffer passed
if (m_pMD->GetMethodTable()->IsRegPassedStruct())
{
@@ -455,7 +444,7 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT *
_ASSERTE(cbReturnValue >= thReturnValueType.GetSize());
}
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
// The metasig should be reset
_ASSERTE(m_methodSig.GetArgNum() == 0);
diff --git a/src/vm/callingconvention.h b/src/vm/callingconvention.h
index c9a27c2371..cde2ba465a 100644
--- a/src/vm/callingconvention.h
+++ b/src/vm/callingconvention.h
@@ -1701,6 +1701,17 @@ inline BOOL HasRetBuffArg(MetaSig * pSig)
return argit.HasRetBuffArg();
}
+#ifdef UNIX_X86_ABI
+// For UNIX_X86_ABI and unmanaged function, we always need RetBuf if the return type is VALUETYPE
+inline BOOL HasRetBuffArgUnmanagedFixup(MetaSig * pSig)
+{
+ WRAPPER_NO_CONTRACT;
+ // We cannot just pSig->GetReturnType() here since it will return ELEMENT_TYPE_VALUETYPE for enums
+ CorElementType type = pSig->GetRetTypeHandleThrowing().GetVerifierCorElementType();
+ return type == ELEMENT_TYPE_VALUETYPE;
+}
+#endif
+
inline BOOL IsRetBuffPassedAsFirstArg()
{
WRAPPER_NO_CONTRACT;
diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp
index c95fbac16e..5de7114eb1 100644
--- a/src/vm/ceeload.cpp
+++ b/src/vm/ceeload.cpp
@@ -44,11 +44,6 @@
#include "metadataexports.h"
#include "inlinetracking.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#include "crossdomaincalls.h"
-#include "objectclone.h"
-#endif
#ifdef FEATURE_PREJIT
#include "exceptionhandling.h"
@@ -78,14 +73,10 @@
#include "perflog.h"
#include "ecall.h"
#include "../md/compiler/custattr.h"
-#include "constrainedexecutionregion.h"
#include "typekey.h"
#include "peimagelayout.inl"
#include "ildbsymlib.h"
-#if defined(FEATURE_APPX_BINDER)
-#include "clrprivbinderappx.h"
-#endif // defined(FEATURE_APPX_BINDER)
#if defined(PROFILING_SUPPORTED)
#include "profilermetadataemitvalidator.h"
@@ -187,292 +178,37 @@ ARRAY_PTR_COR_IL_MAP InstrumentedILOffsetMapping::GetOffsets() const
return m_rgMap;
}
-PTR_PersistentInlineTrackingMap Module::GetNgenInlineTrackingMap()
+BOOL Module::HasInlineTrackingMap()
{
LIMITED_METHOD_DAC_CONTRACT;
- return m_persistentInlineTrackingMap;
+#ifdef FEATURE_READYTORUN
+ if (IsReadyToRun() && GetReadyToRunInfo()->GetInlineTrackingMap() != NULL)
+ {
+ return TRUE;
+ }
+#endif
+ return (m_pPersistentInlineTrackingMapNGen != NULL);
}
-
-#ifndef DACCESS_COMPILE
-
-#ifdef FEATURE_MIXEDMODE
-
-#include <pshpack1.h>
-struct MUThunk
+COUNT_T Module::GetInliners(PTR_Module inlineeOwnerMod, mdMethodDef inlineeTkn, COUNT_T inlinersSize, MethodInModule inliners[], BOOL *incompleteData)
{
- VASigCookie *m_pCookie;
- PCCOR_SIGNATURE m_pSig;
- LPVOID m_pTarget;
-#ifdef _TARGET_X86_
- LPVOID GetCode()
+ WRAPPER_NO_CONTRACT;
+#ifdef FEATURE_READYTORUN
+ if(IsReadyToRun() && GetReadyToRunInfo()->GetInlineTrackingMap() != NULL)
{
- LIMITED_METHOD_CONTRACT;
- return &m_op1;
+ return GetReadyToRunInfo()->GetInlineTrackingMap()->GetInliners(inlineeOwnerMod, inlineeTkn, inlinersSize, inliners, incompleteData);
}
-
- BYTE m_op1; //0x58 POP eax ;;pop return address
-
- BYTE m_op2; //0x68 PUSH cookie
- UINT32 m_opcookie;//
-
- BYTE m_op3; //0x50 PUSH eax ;;repush return address
-
- BYTE m_op4; //0xb8 MOV eax,target
- UINT32 m_optarget;//
- BYTE m_jmp; //0xe9 JMP PInvokeCalliStub
- UINT32 m_jmptarg;
-#else // !_TARGET_X86_
- LPVOID GetCode()
+#endif
+ if(m_pPersistentInlineTrackingMapNGen != NULL)
{
- LIMITED_METHOD_CONTRACT;
- PORTABILITY_ASSERT("MUThunk not implemented on this platform");
- return NULL;
+ return m_pPersistentInlineTrackingMapNGen->GetInliners(inlineeOwnerMod, inlineeTkn, inlinersSize, inliners, incompleteData);
}
-#endif // !_TARGET_X86_
-};
-#include <poppack.h>
-
-
-//
-// A hashtable for u->m thunks not represented in the fixup tables.
-//
-class MUThunkHash : public CClosedHashBase {
- private:
- //----------------------------------------------------
- // Hash key for CClosedHashBase
- //----------------------------------------------------
- struct UTHKey {
- LPVOID m_pTarget;
- PCCOR_SIGNATURE m_pSig;
- DWORD m_cSig;
- };
-
- //----------------------------------------------------
- // Hash entry for CClosedHashBase
- //----------------------------------------------------
- struct UTHEntry {
- UTHKey m_key;
- ELEMENTSTATUS m_status;
- MUThunk *m_pMUThunk;
- };
-
- public:
- MUThunkHash(Module *pModule) :
- CClosedHashBase(
-#ifdef _DEBUG
- 3,
-#else // !_DEBUG
- 17, // CClosedHashTable will grow as necessary
-#endif // !_DEBUG
-
- sizeof(UTHEntry),
- FALSE
- ),
- m_crst(CrstMUThunkHash)
-
- {
- WRAPPER_NO_CONTRACT;
- m_pModule = pModule;
- }
-
- ~MUThunkHash()
- {
- CONTRACT_VOID
- {
- NOTHROW;
- DESTRUCTOR_CHECK;
- GC_NOTRIGGER;
- FORBID_FAULT;
- MODE_ANY;
- }
- CONTRACT_END
-
- UTHEntry *phe = (UTHEntry*)GetFirst();
- while (phe) {
- delete (BYTE*)phe->m_pMUThunk->m_pSig;
- DeleteExecutable(phe->m_pMUThunk);
- phe = (UTHEntry*)GetNext((BYTE*)phe);
- }
-
- RETURN;
- }
-
-
-#ifdef FEATURE_MIXEDMODE
- public:
- LPVOID GetMUThunk(LPVOID pTarget, PCCOR_SIGNATURE pSig0, DWORD cSig)
- {
- STATIC_CONTRACT_THROWS;
-
- // A persistent copy of the sig
- NewArrayHolder<COR_SIGNATURE> sigHolder = new COR_SIGNATURE[cSig];
-
- memcpyNoGCRefs(sigHolder.GetValue(), pSig0, cSig);
- sigHolder[0] = IMAGE_CEE_CS_CALLCONV_STDCALL;
-
- // Have to lookup cookie eagerly because once we've added a blank
- // entry to the hashtable, it's not easy to tolerate failure.
- VASigCookie *pCookie = m_pModule->GetVASigCookie(Signature(sigHolder, cSig));
-
- if (pCookie == NULL)
- {
- return NULL;
- }
- sigHolder.SuppressRelease();
- return GetMUThunkHelper(pTarget, sigHolder, cSig, pCookie);
- }
-private:
- LPVOID GetMUThunkHelper(LPVOID pTarget, PCCOR_SIGNATURE pSig, DWORD cSig, VASigCookie *pCookie)
- {
- CONTRACT (LPVOID)
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END
-
- UTHEntry *phe;
- CrstHolder ch(&m_crst);
-
- UTHKey key;
- key.m_pTarget = pTarget;
- key.m_pSig = pSig;
- key.m_cSig = cSig;
-
- bool bNew;
- phe = (UTHEntry*)FindOrAdd((LPVOID)&key, /*modifies*/bNew);
-
- if (phe)
- {
- if (bNew)
- {
- phe->m_pMUThunk = new (executable) MUThunk;
- phe->m_pMUThunk->m_pCookie = pCookie;
- phe->m_pMUThunk->m_pSig = pSig;
- phe->m_pMUThunk->m_pTarget = pTarget;
-#ifdef _TARGET_X86_
- phe->m_pMUThunk->m_op1 = 0x58; //POP EAX
- phe->m_pMUThunk->m_op2 = 0x68; //PUSH
- phe->m_pMUThunk->m_opcookie = (UINT32)(size_t)pCookie;
- phe->m_pMUThunk->m_op3 = 0x50; //POP EAX
- phe->m_pMUThunk->m_op4 = 0xb8; //mov eax
- phe->m_pMUThunk->m_optarget = (UINT32)(size_t)pTarget;
- phe->m_pMUThunk->m_jmp = 0xe9; //jmp
- phe->m_pMUThunk->m_jmptarg = (UINT32)(GetEEFuncEntryPoint(GenericPInvokeCalliHelper) - ((size_t)( 1 + &(phe->m_pMUThunk->m_jmptarg))));
-#else // !_TARGET_X86_
- PORTABILITY_ASSERT("MUThunkHash not implemented on this platform");
-#endif // !_TARGET_X86_
-
- phe->m_key = key;
- phe->m_status = USED;
- }
- else
- {
- delete[] (BYTE*)pSig;
- }
- }
- else
- {
- delete[] (BYTE*)pSig;
- }
-
- if (phe)
- RETURN (LPVOID)(phe->m_pMUThunk->GetCode());
- else
- RETURN NULL;
- }
-#endif // FEATURE_MIXEDMODE
-
-public:
-
- // *** OVERRIDES FOR CClosedHashBase ***/
-
- //*****************************************************************************
- // Hash is called with a pointer to an element in the table. You must override
- // this method and provide a hash algorithm for your element type.
- //*****************************************************************************
- virtual unsigned int Hash( // The key value.
- void const *pData) // Raw data to hash.
- {
- LIMITED_METHOD_CONTRACT;
-
- UTHKey *pKey = (UTHKey*)pData;
- return (ULONG)(size_t)(pKey->m_pTarget);
- }
-
-
- //*****************************************************************************
- // Compare is used in the typical memcmp way, 0 is eqaulity, -1/1 indicate
- // direction of miscompare. In this system everything is always equal or not.
- //*****************************************************************************
- unsigned int Compare( // 0, -1, or 1.
- void const *pData, // Raw key data on lookup.
- BYTE *pElement) // The element to compare data against.
- {
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- UTHKey *pkey1 = (UTHKey*)pData;
- UTHKey *pkey2 = &( ((UTHEntry*)pElement)->m_key );
-
- if (pkey1->m_pTarget != pkey2->m_pTarget)
- return 1;
-
- if (S_OK != MetaSig::CompareMethodSigsNT(pkey1->m_pSig, pkey1->m_cSig, m_pModule, NULL, pkey2->m_pSig, pkey2->m_cSig, m_pModule, NULL))
- return 1;
-
- return 0;
- }
-
- //*****************************************************************************
- // Return true if the element is free to be used.
- //*****************************************************************************
- virtual ELEMENTSTATUS Status( // The status of the entry.
- BYTE *pElement) // The element to check.
- {
- LIMITED_METHOD_CONTRACT;
-
- return ((UTHEntry*)pElement)->m_status;
- }
-
- //*****************************************************************************
- // Sets the status of the given element.
- //*****************************************************************************
- virtual void SetStatus(
- BYTE *pElement, // The element to set status for.
- ELEMENTSTATUS eStatus) // New status.
- {
- LIMITED_METHOD_CONTRACT;
-
- ((UTHEntry*)pElement)->m_status = eStatus;
- }
-
- //*****************************************************************************
- // Returns the internal key value for an element.
- //*****************************************************************************
- virtual void *GetKey( // The data to hash on.
- BYTE *pElement) // The element to return data ptr for.
- {
- LIMITED_METHOD_CONTRACT;
- return (BYTE*) &(((UTHEntry*)pElement)->m_key);
- }
+ return 0;
+}
+#ifndef DACCESS_COMPILE
- Module *m_pModule;
- Crst m_crst;
-};
-#endif // FEATURE_MIXEDMODE
// ===========================================================================
@@ -701,6 +437,55 @@ Module::Module(Assembly *pAssembly, mdFile moduleRef, PEFile *file)
file->AddRef();
}
+void Module::InitializeForProfiling()
+{
+ CONTRACTL
+ {
+ INSTANCE_CHECK;
+ THROWS;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ PRECONDITION(HasNativeOrReadyToRunImage());
+ }
+ CONTRACTL_END;
+
+ COUNT_T cbProfileList = 0;
+
+ m_nativeImageProfiling = FALSE;
+
+ if (HasNativeImage())
+ {
+ PEImageLayout * pNativeImage = GetNativeImage();
+ CORCOMPILE_VERSION_INFO * pNativeVersionInfo = pNativeImage->GetNativeVersionInfoMaybeNull();
+ if ((pNativeVersionInfo != NULL) && (pNativeVersionInfo->wConfigFlags & CORCOMPILE_CONFIG_INSTRUMENTATION))
+ {
+ m_nativeImageProfiling = GetAssembly()->IsInstrumented();
+ }
+
+ // Link the module to the profile data list if available.
+ m_methodProfileList = pNativeImage->GetNativeProfileDataList(&cbProfileList);
+ }
+ else // ReadyToRun image
+ {
+ // We already setup the m_methodProfileList in the ReadyToRunInfo constructor
+ if (m_methodProfileList != nullptr)
+ {
+ ReadyToRunInfo * pInfo = GetReadyToRunInfo();
+ PEImageLayout * pImage = pInfo->GetImage();
+
+ // Enable profiling if the ZapBBInstr value says to
+ m_nativeImageProfiling = GetAssembly()->IsInstrumented();
+ }
+ }
+
+#ifdef FEATURE_LAZY_COW_PAGES
+ // When running a IBC tuning image to gather profile data
+ // we increment the block counts contained in this area.
+ //
+ if (cbProfileList)
+ EnsureWritablePages(m_methodProfileList, cbProfileList);
+#endif
+}
#ifdef FEATURE_PREJIT
@@ -725,20 +510,6 @@ void Module::InitializeNativeImage(AllocMemTracker* pamTracker)
ExecutionManager::AddNativeImageRange(dac_cast<TADDR>(pNativeImage->GetBase()), pNativeImage->GetVirtualSize(), this);
- CORCOMPILE_VERSION_INFO * pNativeVersionInfo = pNativeImage->GetNativeVersionInfoMaybeNull();
- if ((pNativeVersionInfo != NULL) && (pNativeVersionInfo->wConfigFlags & CORCOMPILE_CONFIG_INSTRUMENTATION))
- {
- m_nativeImageProfiling = GetAssembly()->IsInstrumented();
- }
-
- // Link the module to the profile data list if available.
- COUNT_T cbProfileList;
- m_methodProfileList = pNativeImage->GetNativeProfileDataList(&cbProfileList);
-#ifdef FEATURE_LAZY_COW_PAGES
- if (cbProfileList)
- EnsureWritablePages(m_methodProfileList, cbProfileList);
-#endif
-
#ifndef CROSSGEN_COMPILE
LoadTokenTables();
LoadHelperTable();
@@ -916,9 +687,15 @@ void Module::Initialize(AllocMemTracker *pamTracker, LPCWSTR szName)
#ifdef FEATURE_PREJIT
// Set up native image
if (HasNativeImage())
+ {
InitializeNativeImage(pamTracker);
+ }
#endif // FEATURE_PREJIT
+ if (HasNativeOrReadyToRunImage())
+ {
+ InitializeForProfiling();
+ }
#ifdef FEATURE_NATIVE_IMAGE_GENERATION
if (g_CorCompileVerboseLevel)
@@ -1570,24 +1347,6 @@ void Module::Destruct()
FreeClassTables();
-#if defined(FEATURE_REMOTING) && !defined(HAS_REMOTING_PRECODE)
- // Destroys thunks for all methods included in hash table.
- if (m_pInstMethodHashTable != NULL)
- {
- InstMethodHashTable::Iterator it(m_pInstMethodHashTable);
- InstMethodHashEntry *pEntry;
-
- while (m_pInstMethodHashTable->FindNext(&it, &pEntry))
- {
- MethodDesc *pMD = pEntry->GetMethod();
- if (!pMD->IsRestored())
- continue;
-
- if(pMD->GetMethodTable()->IsMarshaledByRef())
- CRemotingServices::DestroyThunk(pMD);
- }
- }
-#endif // FEATURE_REMOTING && !HAS_REMOTING_PRECODE
#ifdef DEBUGGING_SUPPORTED
if (g_pDebugInterface)
@@ -1616,10 +1375,6 @@ void Module::Destruct()
delete m_pILStubCache;
}
-#ifdef FEATURE_MIXEDMODE // IJW
- delete m_pMUThunkHash;
- delete m_pThunkHeap;
-#endif // FEATURE_MIXEDMODE // IJW
#ifdef PROFILING_SUPPORTED
@@ -1656,24 +1411,6 @@ void Module::Destruct()
m_InstMethodHashTableCrst.Destroy();
m_ISymUnmanagedReaderCrst.Destroy();
-#ifdef FEATURE_CER
- if (m_pCerPrepInfo)
- {
- _ASSERTE(m_pCerCrst != NULL);
- CrstHolder sCrstHolder(m_pCerCrst);
-
- EEHashTableIteration sIter;
- m_pCerPrepInfo->IterateStart(&sIter);
- while (m_pCerPrepInfo->IterateNext(&sIter)) {
- CerPrepInfo *pPrepInfo = (CerPrepInfo*)m_pCerPrepInfo->IterateGetValue(&sIter);
- delete pPrepInfo;
- }
-
- delete m_pCerPrepInfo;
- }
- if (m_pCerCrst)
- delete m_pCerCrst;
-#endif // FEATURE_CER
if (m_debuggerSpecificData.m_pDynamicILCrst)
{
@@ -1704,10 +1441,6 @@ void Module::Destruct()
}
#ifdef FEATURE_PREJIT
-#ifdef FEATURE_CER
- if (m_pCerNgenRootTable && (m_dwTransientFlags & M_CER_ROOT_TABLE_ON_HEAP))
- delete m_pCerNgenRootTable;
-#endif
if (HasNativeImage())
{
@@ -3158,34 +2891,6 @@ BOOL Module::IsPreV4Assembly()
return !!(m_dwPersistedFlags & IS_PRE_V4_ASSEMBLY);
}
-#ifdef FEATURE_CER
-DWORD Module::GetReliabilityContract()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END
-
- if (!(m_dwPersistedFlags & COMPUTED_RELIABILITY_CONTRACT))
- {
- // The flags should be precomputed in native images
- _ASSERTE(!HasNativeImage());
-
- // This flag applies to assembly, but it is stored on module so it can be cached in ngen image
- // Thus, we should ever need it for manifest module only.
- IMDInternalImport *mdImport = GetAssembly()->GetManifestImport();
-
- m_dwReliabilityContract = ::GetReliabilityContract(mdImport, TokenFromRid(1, mdtAssembly));
-
- FastInterlockOr(&m_dwPersistedFlags, COMPUTED_RELIABILITY_CONTRACT);
- }
-
- return m_dwReliabilityContract;
-}
-#endif // FEATURE_CER
ArrayDPTR(FixupPointer<PTR_MethodTable>) ModuleCtorInfo::GetGCStaticMTs(DWORD index)
{
@@ -3881,8 +3586,21 @@ void Module::StartUnload()
}
#endif // PROFILING_SUPPORTED
#ifdef FEATURE_PREJIT
- // Write out the method profile data
- /*hr=*/WriteMethodProfileDataLogFile(true);
+ if (g_IBCLogger.InstrEnabled())
+ {
+ Thread * pThread = GetThread();
+ ThreadLocalIBCInfo* pInfo = pThread->GetIBCInfo();
+
+ // Acquire the Crst lock before creating the IBCLoggingDisabler object.
+ // Only one thread at a time can be processing an IBC logging event.
+ CrstHolder lock(g_IBCLogger.GetSync());
+ {
+ IBCLoggingDisabler disableLogging( pInfo ); // runs IBCLoggingDisabler::DisableLogging
+
+ // Write out the method profile data
+ /*hr=*/WriteMethodProfileDataLogFile(true);
+ }
+ }
#endif // FEATURE_PREJIT
SetBeingUnloaded();
}
@@ -3896,103 +3614,6 @@ void Module::ReleaseILData(void)
}
-#ifdef FEATURE_FUSION
-
-//
-// Module::FusionCopyPDBs asks Fusion to copy PDBs for a given
-// assembly if they need to be copied. This is for the case where a PE
-// file is shadow copied to the Fusion cache. Fusion needs to be told
-// to take the time to copy the PDB, too.
-//
-STDAPI CopyPDBs(IAssembly *pAsm); // private fusion API
-void Module::FusionCopyPDBs(LPCWSTR moduleName)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- Assembly *pAssembly = GetAssembly();
-
- // Just return if we've already done this for this Module's
- // Assembly.
- if ((pAssembly->GetDebuggerInfoBits() & DACF_PDBS_COPIED) ||
- (pAssembly->GetFusionAssembly() == NULL))
- {
- LOG((LF_CORDB, LL_INFO10,
- "Don't need to copy PDB's for module %S\n",
- moduleName));
-
- return;
- }
-
- LOG((LF_CORDB, LL_INFO10,
- "Attempting to copy PDB's for module %S\n", moduleName));
-
- HRESULT hr;
- hr = CopyPDBs(pAssembly->GetFusionAssembly());
- LOG((LF_CORDB, LL_INFO10,
- "Fusion.dll!CopyPDBs returned hr=0x%08x for module 0x%08x\n",
- hr, this));
-
- // Remember that we've copied the PDBs for this assembly.
- pAssembly->SetCopiedPDBs();
-}
-
-// This function will return PDB stream if exist.
-// It is the caller responsibility to call release on *ppStream after a successful
-// result.
-// We will first check to see if we have a cached pdb stream available. If not,
-// we will ask fusion which in terms to ask host vis HostProvideAssembly. Host may
-// decide to provide one or not.
-//
-HRESULT Module::GetHostPdbStream(IStream **ppStream)
-{
- CONTRACTL
- {
- NOTHROW;
- if(GetThread()) {GC_TRIGGERS;} else {GC_NOTRIGGER;}
- }
- CONTRACTL_END
-
- HRESULT hr = NOERROR;
-
- _ASSERTE(ppStream);
-
- *ppStream = NULL;
-
- if (m_file->IsIStream() == false)
- {
- // not a host stream
- return E_FAIL;
- }
-
- // Maybe fusion can ask our host. This will give us back a PDB stream if
- // host decides to provide one.
- //
- if (m_file->IsAssembly())
- {
- GCX_PREEMP();
- hr = ((PEAssembly*)m_file)->GetIHostAssembly()->GetAssemblyDebugStream(ppStream);
- }
- else
- {
- _ASSERTE(m_file->IsModule());
- IHostAssemblyModuleImport *pIHAMI;
- MAKE_WIDEPTR_FROMUTF8_NOTHROW(pName, m_file->GetSimpleName());
- if (pName == NULL)
- return E_OUTOFMEMORY;
- IfFailRet(m_file->GetAssembly()->GetIHostAssembly()->GetModuleByName(pName, &pIHAMI));
- hr = pIHAMI->GetModuleDebugStream(ppStream);
- }
- return hr;
-}
-
-#endif
//---------------------------------------------------------------------------------------
//
@@ -4260,14 +3881,12 @@ ISymUnmanagedReader *Module::GetISymUnmanagedReader(void)
SafeComHolder<ISymUnmanagedBinder> pBinder;
-#if defined(FEATURE_CORECLR)
if (g_pDebugInterface == NULL)
{
// @TODO: this is reachable when debugging!
UNREACHABLE_MSG("About to CoCreateInstance! This code should not be "
"reachable or needs to be reimplemented for CoreCLR!");
}
-#endif // FEATURE_CORECLR
if (this->GetInMemorySymbolStreamFormat() == eSymbolFormatILDB)
{
@@ -4286,21 +3905,13 @@ ISymUnmanagedReader *Module::GetISymUnmanagedReader(void)
// On desktop, the framework installer is supposed to install diasymreader.dll as well
// and so this shouldn't happen.
hr = FakeCoCreateInstanceEx(CLSID_CorSymBinder_SxS,
-#ifdef FEATURE_CORECLR
NATIVE_SYMBOL_READER_DLL,
-#else
- GetInternalSystemDirectory(),
-#endif
IID_ISymUnmanagedBinder,
(void**)&pBinder,
NULL);
if (FAILED(hr))
{
-#ifdef FEATURE_CORECLR
RETURN (NULL);
-#else
- ThrowHR(hr);
-#endif
}
}
@@ -4337,18 +3948,6 @@ ISymUnmanagedReader *Module::GetISymUnmanagedReader(void)
pIStream->AddRef();
}
}
-#ifdef FEATURE_FUSION
- else
- {
- // Verified this above.
- _ASSERTE(m_file->IsIStream());
-
- // Case 2: get assembly from host.
- // This commonly would be cached already as GetInMemorySymbolStream() in code:Module.FetchPdbsFromHost,
- // but may not be cached if the host didn't provide the PDBs at the time.
- hr = GetHostPdbStream(&pIStream);
- }
-#endif
if (SUCCEEDED(hr))
{
hr = pBinder->GetReaderFromStream(GetRWImporter(), pIStream, &pReader);
@@ -4362,9 +3961,6 @@ ISymUnmanagedReader *Module::GetISymUnmanagedReader(void)
// Call Fusion to ensure that any PDB's are shadow copied before
// trying to get a symbol reader. This has to be done once per
// Assembly.
-#ifdef FEATURE_FUSION
- FusionCopyPDBs(path);
-#endif
// for this to work with winmds we cannot simply call GetRWImporter() as winmds are RO
// and thus don't implement the RW interface. so we call this wrapper function which knows
// how to get a IMetaDataImport interface regardless of the underlying module type.
@@ -4443,21 +4039,6 @@ BOOL Module::IsSymbolReadingEnabled()
}
#endif // DEBUGGING_SUPPORTED
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- // See if there is an explicit policy configuration overriding our default.
- // This can be set by the SymbolReadingPolicy config switch or by a host via
- // ICLRDebugManager.AllowFileLineInfo.
- ESymbolReadingPolicy policy = CCLRDebugManager::GetSymbolReadingPolicy();
- if( policy == eSymbolReadingAlways )
- {
- return TRUE;
- }
- else if( policy == eSymbolReadingNever )
- {
- return FALSE;
- }
- _ASSERTE( policy == eSymbolReadingFullTrustOnly );
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
// Default policy - only read symbols corresponding to full-trust assemblies.
// Note that there is no strong (cryptographic) connection between a symbol file and its assembly.
@@ -4752,6 +4333,16 @@ BOOL Module::IsVisibleToDebugger()
return TRUE;
}
+BOOL Module::HasNativeOrReadyToRunImage()
+{
+#ifdef FEATURE_READYTORUN
+ if (IsReadyToRun())
+ return TRUE;
+#endif
+
+ return HasNativeImage();
+}
+
PEImageLayout * Module::GetNativeOrReadyToRunImage()
{
LIMITED_METHOD_CONTRACT;
@@ -5792,14 +5383,6 @@ Module::GetAssemblyIfLoaded(
#endif //!DACCESS_COMPILE
if (pAssembly == nullptr)
{
-#if defined(FEATURE_APPX_BINDER)
- // Use WinRT binder from "global" AppX binder (there's only 1 AppDomain in non-design mode)
- CLRPrivBinderAppX * pAppXBinder = CLRPrivBinderAppX::GetBinderOrNull();
- if (pAppXBinder != nullptr)
- {
- pWinRtBinder = pAppXBinder->GetWinRtBinder();
- }
-#endif // defined(FEATURE_APPX_BINDER)
}
}
@@ -5840,7 +5423,6 @@ Module::GetAssemblyIfLoaded(
continue;
}
-#if defined(FEATURE_CORECLR)
// If we have been passed the binding context for the loaded assembly that is being looked up in the
// cache, then set it up in the AssemblySpec for the cache lookup to use it below.
if (pBindingContextForLoadedAssembly != NULL)
@@ -5848,23 +5430,8 @@ Module::GetAssemblyIfLoaded(
_ASSERTE(spec.GetBindingContext() == NULL);
spec.SetBindingContext(pBindingContextForLoadedAssembly);
}
-#endif // defined(FEATURE_CORECLR)
DomainAssembly * pDomainAssembly = nullptr;
-#ifdef FEATURE_APPX_BINDER
- if (AppX::IsAppXProcess_Initialized_NoFault() && GetAssembly()->GetManifestFile()->HasHostAssembly())
- {
- ICLRPrivAssembly * pPrivBinder = GetAssembly()->GetManifestFile()->GetHostAssembly();
- ReleaseHolder<ICLRPrivAssembly> pPrivAssembly;
- HRESULT hrCachedResult;
- if (SUCCEEDED(pPrivBinder->FindAssemblyBySpec(pAppDomainExamine, &spec, &hrCachedResult, &pPrivAssembly)) &&
- SUCCEEDED(hrCachedResult))
- {
- pDomainAssembly = pAppDomainExamine->FindAssembly(pPrivAssembly);
- }
- }
- else
-#endif // FEATURE_APPX_BINDER
{
pDomainAssembly = pAppDomainExamine->FindCachedAssembly(&spec, FALSE /*fThrow*/);
}
@@ -5901,10 +5468,6 @@ Module::GetAssemblyIfLoaded(
BOOL eligibleForAdditionalChecks = TRUE;
if (szWinRtNamespace != NULL)
eligibleForAdditionalChecks = FALSE; // WinRT binds do not support this scan
-#ifdef FEATURE_FUSION
- else if ((this->GetAssembly()->GetManifestFile()->GetLoadContext() != LOADCTX_TYPE_DEFAULT) && (this->GetAssembly()->GetManifestFile()->GetLoadContext() != LOADCTX_TYPE_HOSTED))
- eligibleForAdditionalChecks = FALSE; // Only load and hosted context binds support this kind of discovery.
-#endif // FEATURE_FUSION
else if (this->GetAssembly()->GetManifestFile()->IsDesignerBindingContext())
{
eligibleForAdditionalChecks = FALSE;
@@ -6130,22 +5693,6 @@ DomainAssembly * Module::LoadAssembly(
bool fHasBindableIdentity = HasBindableIdentity(kAssemblyRef);
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
- if (IsIntrospectionOnly())
- {
- // We will not get here on GC thread
- GCX_PREEMP();
-
- AssemblySpec spec;
- spec.InitializeSpec(kAssemblyRef, GetMDImport(), GetDomainFile(GetAppDomain())->GetDomainAssembly(), IsIntrospectionOnly());
- if (szWinRtTypeClassName != NULL)
- {
- spec.SetWindowsRuntimeType(szWinRtTypeNamespace, szWinRtTypeClassName);
- }
- pDomainAssembly = GetAppDomain()->BindAssemblySpecForIntrospectionDependencies(&spec);
- }
- else
-#endif //FEATURE_REFLECTION_ONLY_LOAD
{
PEAssemblyHolder pFile = GetDomainFile(GetAppDomain())->GetFile()->LoadAssembly(
kAssemblyRef,
@@ -6154,7 +5701,6 @@ DomainAssembly * Module::LoadAssembly(
szWinRtTypeClassName);
AssemblySpec spec;
spec.InitializeSpec(kAssemblyRef, GetMDImport(), GetDomainFile(GetAppDomain())->GetDomainAssembly(), IsIntrospectionOnly());
-#if defined(FEATURE_CORECLR)
// Set the binding context in the AssemblySpec if one is available. This can happen if the LoadAssembly ended up
// invoking the custom AssemblyLoadContext implementation that returned a reference to an assembly bound to a different
// AssemblyLoadContext implementation.
@@ -6163,7 +5709,6 @@ DomainAssembly * Module::LoadAssembly(
{
spec.SetBindingContext(pBindingContext);
}
-#endif // defined(FEATURE_CORECLR)
if (szWinRtTypeClassName != NULL)
{
spec.SetWindowsRuntimeType(szWinRtTypeNamespace, szWinRtTypeClassName);
@@ -6272,15 +5817,6 @@ Module *Module::GetModuleIfLoaded(mdFile kFile, BOOL onlyLoadedInAppDomain, BOOL
pModule = NULL;
#ifndef DACCESS_COMPILE
-#if defined(FEATURE_MULTIMODULE_ASSEMBLIES)
- // check if actually loaded, unless happens during GC (GC works only with loaded assemblies)
- if (!GCHeapUtilities::IsGCInProgress() && onlyLoadedInAppDomain && pModule && !pModule->IsManifest())
- {
- DomainModule *pDomainModule = pModule->FindDomainModule(GetAppDomain());
- if (pDomainModule == NULL || !pDomainModule->IsLoaded())
- pModule = NULL;
- }
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
#endif // !DACCESS_COMPILE
RETURN pModule;
}
@@ -6302,99 +5838,6 @@ DomainFile *Module::LoadModule(AppDomain *pDomain, mdFile kFile,
}
CONTRACT_END;
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-
- // Handle the module ref case
- if (TypeFromToken(kFile) == mdtModuleRef)
- {
- LPCSTR moduleName;
- IfFailThrow(GetMDImport()->GetModuleRefProps(kFile, &moduleName));
-
- mdFile kFileLocal = GetAssembly()->GetManifestFileToken(moduleName);
-
- if (kFileLocal == mdTokenNil)
- {
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- }
-
- RETURN GetAssembly()->GetManifestModule()->LoadModule(pDomain, kFileLocal, permitResources, bindOnly);
- }
-
- // First, make sure the assembly is loaded in our domain
-
- DomainAssembly *pDomainAssembly = GetAssembly()->FindDomainAssembly(pDomain);
- if (!bindOnly)
- {
- if (pDomainAssembly == NULL)
- pDomainAssembly = GetAssembly()->GetDomainAssembly(pDomain);
- pDomain->LoadDomainFile(pDomainAssembly, FILE_LOADED);
- }
-
- if (kFile == mdFileNil)
- RETURN pDomainAssembly;
-
- if (pDomainAssembly == NULL)
- RETURN NULL;
-
- // Now look for the module in the rid maps
-
- Module *pModule = LookupFile(kFile);
- if (pModule == NULL && !IsManifest())
- {
- // If we didn't find it there, look at the "master rid map" in the manifest file
- Assembly *pAssembly = GetAssembly();
- mdFile kMatch = pAssembly->GetManifestFileToken(GetMDImport(), kFile);
- if (IsNilToken(kMatch)) {
- if (kMatch == mdFileNil)
- pModule = pAssembly->GetManifestModule();
- else
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- }
- else
- pModule = pAssembly->GetManifestModule()->LookupFile(kMatch);
- }
-
- // Get a DomainModule for our domain
-
- DomainModule *pDomainModule = NULL;
- if (pModule)
- {
- pDomainModule = pModule->FindDomainModule(pDomain);
-
- if (!bindOnly && (permitResources || !pModule->IsResource()))
- {
- if (pDomainModule == NULL)
- pDomainModule = pDomain->LoadDomainModule(pDomainAssembly, (PEModule*) pModule->GetFile(), FILE_LOADED);
- else
- pDomain->LoadDomainFile(pDomainModule, FILE_LOADED);
- }
- }
- else if (!bindOnly)
- {
- PEModuleHolder pFile(GetAssembly()->LoadModule_AddRef(kFile, permitResources));
- if (pFile)
- pDomainModule = pDomain->LoadDomainModule(pDomainAssembly, pFile, FILE_LOADED);
- }
-
- if (pDomainModule != NULL && pDomainModule->GetCurrentModule() != NULL)
- {
- // Make sure the module we're loading isn't its own assembly
- if (pDomainModule->GetCurrentModule()->IsManifest())
- COMPlusThrowHR(COR_E_ASSEMBLY_NOT_EXPECTED);
-
- // Cache the result in the rid map
- StoreFileThrowing(kFile, pDomainModule->GetCurrentModule());
- }
-
- // Make sure we didn't load a different module than what was in the rid map
- CONSISTENCY_CHECK(pDomainModule == NULL || pModule == NULL || pDomainModule->GetModule() == pModule);
-
- // We may not want to return a resource module
- if (!permitResources && pDomainModule != NULL && pDomainModule->GetFile()->IsResource())
- pDomainModule = NULL;
-
- RETURN pDomainModule;
-#else //!FEATURE_MULTIMODULE_ASSEMBLIES
if (bindOnly)
{
RETURN NULL;
@@ -6419,7 +5862,6 @@ DomainFile *Module::LoadModule(AppDomain *pDomain, mdFile kFile,
SString name(SString::Utf8, psModuleName);
EEFileLoadException::Throw(name, COR_E_MULTIMODULEASSEMBLIESDIALLOWED, NULL);
}
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
}
#endif // !DACCESS_COMPILE
@@ -7082,7 +6524,9 @@ MethodDesc *Module::FindMethod(mdToken pMethod)
CONTRACT_VIOLATION(ThrowsViolation);
char szMethodName [MAX_CLASSNAME_LENGTH];
CEEInfo::findNameOfToken(this, pMethod, szMethodName, COUNTOF (szMethodName));
- LOG((LF_IJW, LL_INFO10, "Failed to find Method: %s for Vtable Fixup\n", szMethodName));
+ // This used to be LF_IJW, but changed to LW_INTEROP to reclaim a bit in our log facilities
+ // IJW itself is not supported in coreclr so this code should never be run.
+ LOG((LF_INTEROP, LL_INFO10, "Failed to find Method: %s for Vtable Fixup\n", szMethodName));
#endif // _DEBUG
}
EX_END_CATCH(SwallowAllExceptions)
@@ -7444,84 +6888,6 @@ void Module::UpdateDynamicMetadataIfNeeded()
#ifdef DEBUGGING_SUPPORTED
-#ifdef FEATURE_FUSION
-
-// Fetch Pdbs from the host
-//
-// Returns:
-// No explicit return value.
-// Caches the pdb stream on the module instance if available.
-// Does nothing if not hosted or if the host does not provide a stream.
-// Throws on exception if the host does provide a stream, but we can't copy it out.
-//
-// Notes:
-// This fetches PDBs from the host and caches them so that they are available for when the debugger attaches.
-// This lets Arrowhead tools run against Whidbey hosts in a compatibility mode.
-// We expect to add a hosting knob that will allow a host to disable this eager fetching and not run in
-// compat mode.
-void Module::FetchPdbsFromHost()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- HRESULT hr;
-
- ReleaseHolder<IStream> pHostStream;
-
- hr = GetHostPdbStream(&pHostStream); // addrefs, holder will release
- if (pHostStream == NULL)
- {
- // Common failure case, we're either not hosted, or the host doesn't have a stream.
- return;
- }
- // pHostStream is a stream implemented by the host, so be extra cautious about methods failing,
- // especially with E_NOTIMPL.
-
- SafeComHolder<CGrowableStream> pStream(new CGrowableStream()); // throws
-
- //
- // Copy from pHostStream (owned by host) to CGrowableStream (owned by CLR, and visible to debugger from OOP).
- //
-
- // Get number of bytes to copy.
- STATSTG SizeData = {0};
- hr = pHostStream->Stat(&SizeData, STATFLAG_NONAME);
- IfFailThrow(hr);
- ULARGE_INTEGER streamSize = SizeData.cbSize;
-
- if (streamSize.u.HighPart > 0)
- {
- // Too big. We shouldn't have a PDB larger than 4gb.
- ThrowHR(E_OUTOFMEMORY);
- }
- ULONG cbRequest = streamSize.u.LowPart;
-
-
- // Allocate
- hr = pStream->SetSize(streamSize);
- IfFailThrow(hr);
-
- _ASSERTE(pStream->GetRawBuffer().Size() == cbRequest);
-
- // Do the actual copy
- ULONG cbActualRead = 0;
- hr = pHostStream->Read(pStream->GetRawBuffer().StartAddress(), cbRequest, &cbActualRead);
- IfFailThrow(hr);
- if (cbRequest != cbActualRead)
- {
- ThrowWin32(ERROR_READ_FAULT);
- }
-
- // We now have a full copy of the PDB provided from the host.
- // This addrefs pStream, which lets it survive past the holder's scope.
- SetInMemorySymbolStream(pStream, eSymbolFormatPDB);
-}
-#endif // FEATURE_FUSION
#endif // DEBUGGING_SUPPORTED
@@ -7540,16 +6906,6 @@ BOOL Module::NotifyDebuggerLoad(AppDomain *pDomain, DomainFile * pDomainFile, in
pModule->UpdateDynamicMetadataIfNeeded();
}
-#ifdef FEATURE_FUSION
- // Eagerly fetch pdbs for hosted modules.
- // This is only needed for debugging, so errors are not fatal in normal cases.
- HRESULT hrFetchPdbs = S_OK;
- EX_TRY
- {
- FetchPdbsFromHost();
- }
- EX_CATCH_HRESULT(hrFetchPdbs);
-#endif // FEATURE_FUSION
//
// Remaining work is only needed if a debugger is attached
@@ -7615,619 +6971,6 @@ void Module::NotifyDebuggerUnload(AppDomain *pDomain)
g_pDebugInterface->UnloadModule(this, pDomain);
}
-#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE)
-
-//======================================================================================
-// These are used to call back to the shim to get the information about
-// thunks, and to set the new targets.
-typedef mdToken STDMETHODCALLTYPE GetTokenForVTableEntry_t(HINSTANCE hInst, BYTE **ppVTEntry);
-typedef void STDMETHODCALLTYPE SetTargetForVTableEntry_t(HINSTANCE hInst, BYTE **ppVTEntry, BYTE *pTarget);
-typedef BYTE * STDMETHODCALLTYPE GetTargetForVTableEntry_t(HINSTANCE hInst, BYTE **ppVTEntry);
-
-GetTokenForVTableEntry_t *g_pGetTokenForVTableEntry = NULL;
-SetTargetForVTableEntry_t *g_pSetTargetForVTableEntry = NULL;
-GetTargetForVTableEntry_t *g_pGetTargetForVTableEntry = NULL;
-
-//======================================================================================
-void InitThunkCallbackFunctions(HINSTANCE hInstShim)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- } CONTRACTL_END;
-
- typedef enum {
- e_UNINITIALIZED,
- e_INITIALIZED_SUCCESS,
- } InitState_t;
-
- static InitState_t s_state = e_UNINITIALIZED;
- if (s_state == e_UNINITIALIZED) {
- g_pGetTokenForVTableEntry = (GetTokenForVTableEntry_t *)GetProcAddress(hInstShim, "GetTokenForVTableEntry");
- if (g_pGetTokenForVTableEntry == NULL) {
- COMPlusThrow(kMissingMethodException, IDS_EE_MSCOREE_MISSING_ENTRYPOINT, W("GetTokenForVTableEntry"));
- }
- g_pSetTargetForVTableEntry = (SetTargetForVTableEntry_t *)GetProcAddress(hInstShim, "SetTargetForVTableEntry");
- if (g_pSetTargetForVTableEntry == NULL) {
- COMPlusThrow(kMissingMethodException, IDS_EE_MSCOREE_MISSING_ENTRYPOINT, W("SetTargetForVTableEntry"));
- }
- g_pGetTargetForVTableEntry = (GetTargetForVTableEntry_t *)GetProcAddress(hInstShim, "GetTargetForVTableEntry");
- if (g_pGetTargetForVTableEntry == NULL) {
- COMPlusThrow(kMissingMethodException, IDS_EE_MSCOREE_MISSING_ENTRYPOINT, W("GetTargetForVTableEntry"));
- }
- s_state = e_INITIALIZED_SUCCESS;
- }
- CONSISTENCY_CHECK(s_state != e_UNINITIALIZED);
-}
-
-//======================================================================================
-void InitShimHINSTANCE()
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- } CONTRACTL_END;
-
- if (g_hInstShim == NULL) {
- g_hInstShim = WszLoadLibrary(MSCOREE_SHIM_W);
- if (g_hInstShim == NULL) {
- InlineSString<80> ssErrorFormat;
- if(!ssErrorFormat.LoadResource(CCompRC::Optional, IDS_EE_MSCOREE_MISSING))
- {
- // Keep this in sync with the actual message
- ssErrorFormat.Set(W("MSCOREE is not loaded."));
- }
- EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_EXECUTIONENGINE, ssErrorFormat.GetUnicode());
- }
- }
-}
-
-//======================================================================================
-HINSTANCE GetShimHINSTANCE() // dead code?
-{
- WRAPPER_NO_CONTRACT;
- InitShimHINSTANCE();
- return g_hInstShim;
-}
-
-//======================================================================================
-// Fixup vtables stored in the header to contain pointers to method desc
-// prestubs rather than metadata method tokens.
-void Module::FixupVTables()
-{
- CONTRACTL {
- INSTANCE_CHECK;
- STANDARD_VM_CHECK;
- } CONTRACTL_END;
-
-
- // If we've already fixed up, or this is not an IJW module, just return.
- // NOTE: This relies on ILOnly files not having fixups. If this changes,
- // we need to change this conditional.
- if (IsIJWFixedUp() || m_file->IsILOnly() || IsIntrospectionOnly()) {
- return;
- }
-
- // An EEException will be thrown if either MSCOREE or any of the required
- // entrypoints cannot be found.
- InitShimHINSTANCE();
- InitThunkCallbackFunctions(g_hInstShim);
-
- HINSTANCE hInstThis = GetFile()->GetIJWBase();
-
- // <REVISIT_TODO>@todo: workaround!</REVISIT_TODO>
- // If we are compiling in-process, we don't want to fixup the vtables - as it
- // will have side effects on the other copy of the module!
- if (SystemDomain::GetCurrentDomain()->IsPassiveDomain()) {
- return;
- }
-
-#ifdef FEATURE_PREJIT
- // We delayed filling in this value until the LoadLibrary occurred
- if (HasTls() && HasNativeImage()) {
- CORCOMPILE_EE_INFO_TABLE *pEEInfo = GetNativeImage()->GetNativeEEInfoTable();
- pEEInfo->rvaStaticTlsIndex = GetTlsIndex();
- }
-#endif
- // Get vtable fixup data
- COUNT_T cFixupRecords;
- IMAGE_COR_VTABLEFIXUP *pFixupTable = m_file->GetVTableFixups(&cFixupRecords);
-
- // No records then return
- if (cFixupRecords == 0) {
- return;
- }
-
- // Now, we need to take a lock to serialize fixup.
- PEImage::IJWFixupData *pData = PEImage::GetIJWData(m_file->GetIJWBase());
-
- // If it's already been fixed (in some other appdomain), record the fact and return
- if (pData->IsFixedUp()) {
- SetIsIJWFixedUp();
- return;
- }
-
- //////////////////////////////////////////////////////
- //
- // This is done in three stages:
- // 1. We enumerate the types we'll need to load
- // 2. We load the types
- // 3. We create and install the thunks
- //
-
- COUNT_T cVtableThunks = 0;
- struct MethodLoadData
- {
- mdToken token;
- MethodDesc *pMD;
- };
- MethodLoadData *rgMethodsToLoad = NULL;
- COUNT_T cMethodsToLoad = 0;
-
- //
- // Stage 1
- //
-
- // Each fixup entry describes a vtable, so iterate the vtables and sum their counts
- {
- DWORD iFixup;
- for (iFixup = 0; iFixup < cFixupRecords; iFixup++)
- cVtableThunks += pFixupTable[iFixup].Count;
- }
-
- Thread *pThread = GetThread();
- StackingAllocator *pAlloc = &pThread->m_MarshalAlloc;
- CheckPointHolder cph(pAlloc->GetCheckpoint());
-
- // Allocate the working array of tokens.
- cMethodsToLoad = cVtableThunks;
-
- rgMethodsToLoad = new (pAlloc) MethodLoadData[cMethodsToLoad];
- memset(rgMethodsToLoad, 0, cMethodsToLoad*sizeof(MethodLoadData));
-
- // Now take the IJW module lock and get all the tokens
- {
- // Take the lock
- CrstHolder lockHolder(pData->GetLock());
-
- // If someone has beaten us, just return
- if (pData->IsFixedUp())
- {
- SetIsIJWFixedUp();
- return;
- }
-
- COUNT_T iCurMethod = 0;
-
- if (cFixupRecords != 0)
- {
- for (COUNT_T iFixup = 0; iFixup < cFixupRecords; iFixup++)
- {
- // Vtables can be 32 or 64 bit.
- if ((pFixupTable[iFixup].Type == (COR_VTABLE_PTRSIZED)) ||
- (pFixupTable[iFixup].Type == (COR_VTABLE_PTRSIZED|COR_VTABLE_FROM_UNMANAGED)) ||
- (pFixupTable[iFixup].Type == (COR_VTABLE_PTRSIZED|COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN)))
- {
- const BYTE** pPointers = (const BYTE **) m_file->GetVTable(pFixupTable[iFixup].RVA);
- for (int iMethod = 0; iMethod < pFixupTable[iFixup].Count; iMethod++)
- {
- if (pData->IsMethodFixedUp(iFixup,iMethod))
- continue;
- mdToken mdTok = (*g_pGetTokenForVTableEntry)(hInstThis, (BYTE **)(pPointers + iMethod));
- CONSISTENCY_CHECK(mdTok != mdTokenNil);
- rgMethodsToLoad[iCurMethod++].token = mdTok;
- }
- }
- }
- }
-
- }
-
- //
- // Stage 2 - Load the types
- //
-
- {
- for (COUNT_T iCurMethod = 0; iCurMethod < cMethodsToLoad; iCurMethod++)
- {
- mdToken curTok = rgMethodsToLoad[iCurMethod].token;
- if(!GetMDImport()->IsValidToken(curTok))
- {
- _ASSERTE(!"Invalid token in v-table fix-up table");
- ThrowHR(COR_E_BADIMAGEFORMAT);
- }
-
-
- // Find the method desc
- MethodDesc *pMD;
-
- {
- CONTRACT_VIOLATION(LoadsTypeViolation);
- pMD = FindMethodThrowing(curTok);
- }
-
- CONSISTENCY_CHECK(CheckPointer(pMD));
-
- rgMethodsToLoad[iCurMethod].pMD = pMD;
- }
- }
-
- //
- // Stage 3 - Create the thunk data
- //
- {
- // Take the lock
- CrstHolder lockHolder(pData->GetLock());
-
- // If someone has beaten us, just return
- if (pData->IsFixedUp())
- {
- SetIsIJWFixedUp();
- return;
- }
-
- // This is the app domain which all of our U->M thunks for this module will have
- // affinity with. Note that if the module is shared between multiple domains, all thunks will marshal back
- // to the original domain, so some of the thunks may cause a surprising domain switch to occur.
- // (And furthermore note that if the original domain is unloaded, all the thunks will simply throw an
- // exception.)
- //
- // (The essential problem is that these thunks are shared via the global process address space
- // rather than per domain, thus there is no context to figure out our domain from. We could
- // use the current thread's domain, but that is effectively undefined in unmanaged space.)
- //
- // The bottom line is that the IJW model just doesn't fit with multiple app domain design very well, so
- // better to have well defined limitations than flaky behavior.
- //
- //
-
- AppDomain *pAppDomain = GetAppDomain();
-
- // Used to index into rgMethodsToLoad
- COUNT_T iCurMethod = 0;
-
-
- // Each fixup entry describes a vtable (each slot contains a metadata token
- // at this stage).
- DWORD iFixup;
- for (iFixup = 0; iFixup < cFixupRecords; iFixup++)
- cVtableThunks += pFixupTable[iFixup].Count;
-
- DWORD dwIndex=0;
- DWORD dwThunkIndex = 0;
-
- // Now to fill in the thunk table.
- for (iFixup = 0; iFixup < cFixupRecords; iFixup++)
- {
- const BYTE** pPointers = (const BYTE **)
- m_file->GetVTable(pFixupTable[iFixup].RVA);
-
- // Vtables can be 32 or 64 bit.
- if (pFixupTable[iFixup].Type == COR_VTABLE_PTRSIZED)
- {
- for (int iMethod = 0; iMethod < pFixupTable[iFixup].Count; iMethod++)
- {
- if (pData->IsMethodFixedUp(iFixup,iMethod))
- continue;
-
- mdToken mdTok = rgMethodsToLoad[iCurMethod].token;
- MethodDesc *pMD = rgMethodsToLoad[iCurMethod].pMD;
- iCurMethod++;
-
-#ifdef _DEBUG
- if (pMD->IsNDirect())
- {
- LOG((LF_IJW, LL_INFO10, "[0x%lx] <-- PINV thunk for \"%s\" (target = 0x%lx)\n",
- (size_t)&(pPointers[iMethod]), pMD->m_pszDebugMethodName,
- (size_t) (((NDirectMethodDesc*)pMD)->GetNDirectTarget())));
- }
-#endif // _DEBUG
-
- CONSISTENCY_CHECK(dwThunkIndex < cVtableThunks);
-
- // Point the local vtable slot to the thunk we created
- (*g_pSetTargetForVTableEntry)(hInstThis, (BYTE **)&pPointers[iMethod], (BYTE *)pMD->GetMultiCallableAddrOfCode());
-
- pData->MarkMethodFixedUp(iFixup,iMethod);
-
- dwThunkIndex++;
- }
-
- }
- else if (pFixupTable[iFixup].Type == (COR_VTABLE_PTRSIZED|COR_VTABLE_FROM_UNMANAGED))
- {
-
- for (int iMethod = 0; iMethod < pFixupTable[iFixup].Count; iMethod++)
- {
- if (pData->IsMethodFixedUp(iFixup,iMethod))
- continue;
-
- mdToken mdTok = rgMethodsToLoad[iCurMethod].token;
- MethodDesc *pMD = rgMethodsToLoad[iCurMethod].pMD;
- iCurMethod++;
- LOG((LF_IJW, LL_INFO10, "[0x%p] <-- VTable thunk for \"%s\" (pMD = 0x%p)\n",
- (UINT_PTR)&(pPointers[iMethod]), pMD->m_pszDebugMethodName, pMD));
-
- UMEntryThunk *pUMEntryThunk = (UMEntryThunk*)(void*)(GetDllThunkHeap()->AllocAlignedMem(sizeof(UMEntryThunk), CODE_SIZE_ALIGN)); // UMEntryThunk contains code
- FillMemory(pUMEntryThunk, sizeof(*pUMEntryThunk), 0);
-
- UMThunkMarshInfo *pUMThunkMarshInfo = (UMThunkMarshInfo*)(void*)(GetThunkHeap()->AllocAlignedMem(sizeof(UMThunkMarshInfo), CODE_SIZE_ALIGN));
- FillMemory(pUMThunkMarshInfo, sizeof(*pUMThunkMarshInfo), 0);
-
- pUMThunkMarshInfo->LoadTimeInit(pMD);
- pUMEntryThunk->LoadTimeInit(NULL, NULL, pUMThunkMarshInfo, pMD, pAppDomain->GetId());
- (*g_pSetTargetForVTableEntry)(hInstThis, (BYTE **)&pPointers[iMethod], (BYTE *)pUMEntryThunk->GetCode());
-
- pData->MarkMethodFixedUp(iFixup,iMethod);
- }
- }
- else if (pFixupTable[iFixup].Type == (COR_VTABLE_PTRSIZED|COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN))
- {
-
- for (int iMethod = 0; iMethod < pFixupTable[iFixup].Count; iMethod++)
- {
- if (pData->IsMethodFixedUp(iFixup,iMethod))
- continue;
-
- mdToken mdTok = rgMethodsToLoad[iCurMethod].token;
- iCurMethod++;
-
- IJWNOADThunk* pThunkLocal = new(GetDllThunkHeap()->AllocAlignedMem(sizeof(IJWNOADThunk), CODE_SIZE_ALIGN)) IJWNOADThunk(GetFile()->GetIJWBase(),dwIndex++,mdTok);
- (*g_pSetTargetForVTableEntry)(hInstThis, (BYTE **)&pPointers[iMethod], (BYTE *)pThunkLocal->GetCode());
-
- pData->MarkMethodFixedUp(iFixup,iMethod);
- }
- }
- else if ((pFixupTable[iFixup].Type & COR_VTABLE_NOT_PTRSIZED) == COR_VTABLE_NOT_PTRSIZED)
- {
- // fixup type doesn't match the platform
- THROW_BAD_FORMAT(BFA_FIXUP_WRONG_PLATFORM, this);
- }
- else
- {
- _ASSERTE(!"Unknown vtable fixup type");
- }
- }
-
-
- if(!GetAssembly()->IsDomainNeutral())
- CreateDomainThunks();
-
- SetDomainIdOfIJWFixups(pAppDomain->GetId());
-#ifdef FEATURE_PREJIT
- if (HasNativeImage()) {
- CORCOMPILE_EE_INFO_TABLE *pEEInfo = GetNativeImage()->GetNativeEEInfoTable();
-
- if (pEEInfo->nativeEntryPointStart != 0) {
- PTR_PEImageLayout pIJWLayout = m_file->GetLoadedIL();
- SIZE_T base = (SIZE_T)pIJWLayout->GetBase();
-
- _ASSERTE(pIJWLayout->CheckRva((RVA)pEEInfo->nativeEntryPointStart));
- _ASSERTE(pIJWLayout->CheckRva((RVA)pEEInfo->nativeEntryPointEnd));
-
- pEEInfo->nativeEntryPointStart += base;
- pEEInfo->nativeEntryPointEnd += base;
- }
- else {
- _ASSERTE(pEEInfo->nativeEntryPointEnd == 0);
- }
- }
-#endif
- // Indicate that this module has been fixed before releasing the lock
- pData->SetIsFixedUp(); // On the data
- SetIsIJWFixedUp(); // On the module
- } // End of Stage 3
-}
-
-// Self-initializing accessor for m_pThunkHeap
-LoaderHeap *Module::GetDllThunkHeap()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
- return PEImage::GetDllThunkHeap(GetFile()->GetIJWBase());
-
-}
-LoaderHeap *Module::GetThunkHeap()
-{
- CONTRACT (LoaderHeap *)
- {
- INSTANCE_CHECK;
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END
-
- if (!m_pThunkHeap)
- {
- size_t * pPrivatePCLBytes = NULL;
- size_t * pGlobalPCLBytes = NULL;
-
-#ifdef PROFILING_SUPPORTED
- pPrivatePCLBytes = &(GetPerfCounters().m_Loading.cbLoaderHeapSize);
-#endif
-
- LoaderHeap *pNewHeap = new LoaderHeap(VIRTUAL_ALLOC_RESERVE_GRANULARITY, // DWORD dwReserveBlockSize
- 0, // DWORD dwCommitBlockSize
- pPrivatePCLBytes,
- ThunkHeapStubManager::g_pManager->GetRangeList(),
- TRUE); // BOOL fMakeExecutable
-
- if (FastInterlockCompareExchangePointer(&m_pThunkHeap, pNewHeap, 0) != 0)
- {
- delete pNewHeap;
- }
- }
-
- RETURN m_pThunkHeap;
-}
-
-void Module::SetADThunkTable(UMEntryThunk* pTable)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- GetDomainLocalModule()->SetADThunkTable(pTable);
-}
-
-UMEntryThunk* Module::GetADThunkTable()
-{
- CONTRACT(UMEntryThunk*)
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END
-
- DomainLocalModule* pMod=GetDomainLocalModule();
- _ASSERTE(pMod);
- UMEntryThunk * pADThunkTable = pMod->GetADThunkTable();
- if (pADThunkTable == NULL)
- {
- CreateDomainThunks();
- pADThunkTable = pMod->GetADThunkTable();
- _ASSERTE(pADThunkTable != NULL);
- }
-
- RETURN (UMEntryThunk*)pADThunkTable;
-};
-
-void Module::CreateDomainThunks()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- }
- CONTRACTL_END;
-
- AppDomain *pAppDomain = GetAppDomain();
- if(!pAppDomain)
- {
- _ASSERTE(!"No appdomain");
- return;
- }
-
- UINT32 cFixupRecords;
- IMAGE_COR_VTABLEFIXUP *pFixupTable = m_file->GetVTableFixups(&cFixupRecords);
-
- DWORD iFixup;
- DWORD cVtableThunks=0;
- for (iFixup = 0; iFixup < cFixupRecords; iFixup++)
- {
- if (pFixupTable[iFixup].Type==(COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN|COR_VTABLE_PTRSIZED))
- {
- cVtableThunks += pFixupTable[iFixup].Count;
- }
- }
-
- if (cVtableThunks==0)
- {
- return;
- }
-
- AllocMemTracker amTracker;
- AllocMemTracker *pamTracker = &amTracker;
-
- UMEntryThunk* pTable=((UMEntryThunk*)pamTracker->Track(pAppDomain->GetStubHeap()->AllocAlignedMem(sizeof(UMEntryThunk)*cVtableThunks, CODE_SIZE_ALIGN)));
- DWORD dwCurrIndex=0;
- for (iFixup = 0; iFixup < cFixupRecords; iFixup++)
- {
- if (pFixupTable[iFixup].Type == (COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN|COR_VTABLE_PTRSIZED))
- {
- const BYTE **pPointers = (const BYTE **) m_file->GetVTable(pFixupTable[iFixup].RVA);
- for (int iMethod = 0; iMethod < pFixupTable[iFixup].Count; iMethod++)
- {
- PCODE pCode = (PCODE)
- (*g_pGetTargetForVTableEntry)((HINSTANCE)GetFile()->GetIJWBase(), (BYTE **)&pPointers[iMethod]);
- IJWNOADThunk* pThnk = IJWNOADThunk::FromCode(pCode);
- mdToken tok=pThnk->GetToken(); //!!
- if(!GetMDImport()->IsValidToken(tok))
- {
- ThrowHR(COR_E_BADIMAGEFORMAT, BFA_INVALID_TOKEN);
- return;
- }
-
- MethodDesc *pMD = FindMethodThrowing(tok);
-
- // @TODO: Check for out of memory
- UMThunkMarshInfo *pUMThunkMarshInfo = (UMThunkMarshInfo*)pamTracker->Track(pAppDomain->GetStubHeap()->AllocAlignedMem(sizeof(UMThunkMarshInfo), CODE_SIZE_ALIGN));
- _ASSERTE(pUMThunkMarshInfo != NULL);
-
- pUMThunkMarshInfo->LoadTimeInit(pMD);
- pTable[dwCurrIndex].LoadTimeInit(NULL, NULL, pUMThunkMarshInfo, pMD, pAppDomain->GetId());
-
- // If we're setting up a domain that is cached, update the code pointer in the cache
- if (pThnk->IsCachedAppDomainID(pAppDomain->GetId()))
- pThnk->SetCachedInfo(pAppDomain->GetId(), (LPVOID)GetEEFuncEntryPoint((LPVOID)pTable[dwCurrIndex].GetCode()));
-
- dwCurrIndex++;
- }
- }
- }
-
- pamTracker->SuppressRelease();
- SetADThunkTable(pTable);
-}
-
-LPVOID Module::GetUMThunk(LPVOID pManagedIp, PCCOR_SIGNATURE pSig, ULONG cSig)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- CAN_TAKE_LOCK;
- }
- CONTRACTL_END;
-
- return GetDomainFile()->GetUMThunk(pManagedIp, pSig, cSig);
-}
-
-
-void *Module::GetMUThunk(LPVOID pUnmanagedIp, PCCOR_SIGNATURE pSig, ULONG cSig)
-{
- CONTRACT (void*)
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END
-
- if (m_pMUThunkHash == NULL)
- {
- MUThunkHash *pMUThunkHash = new MUThunkHash(this);
- if (FastInterlockCompareExchangePointer(&m_pMUThunkHash, pMUThunkHash, NULL) != NULL)
- delete pMUThunkHash;
- }
- RETURN m_pMUThunkHash->GetMUThunk(pUnmanagedIp, pSig, cSig);
-}
-
-#endif //FEATURE_MIXEDMODE && !CROSSGEN_COMPILE
#ifdef FEATURE_NATIVE_IMAGE_GENERATION
@@ -9773,43 +8516,6 @@ void ModuleCtorInfo::Save(DataImage *image, CorProfileData *profileData)
}
}
-#ifdef FEATURE_REMOTING
-static void IsCrossAppDomainOptimizableWrapper(MethodDesc * pMD,
- DWORD* pnumDwords)
-{
- STANDARD_VM_CONTRACT;
-
- GCX_COOP();
-
- EX_TRY
- {
- if (pMD->GetNumGenericMethodArgs() == 0 && !pMD->IsStatic())
- RemotableMethodInfo::IsCrossAppDomainOptimizable(pMD, pnumDwords);
- }
- EX_CATCH
- {
- // If there is an exception, it'll mean the info for this method will remain uninitialized.
- // Just ignore the exception. At runtime, we'll try to initialize it
- // An exception is possible during ngen if all dependencies are not available
- }
- EX_END_CATCH(SwallowAllExceptions)
-}
-
-static void PrepareRemotableMethodInfo(MethodTable * pMT)
-{
- STANDARD_VM_CONTRACT;
-
- if (!pMT->HasRemotableMethodInfo())
- return;
-
- MethodTable::MethodIterator it(pMT);
- for (; it.IsValid(); it.Next())
- {
- DWORD numDwords = 0;
- IsCrossAppDomainOptimizableWrapper(it.GetMethodDesc(), &numDwords);
- }
-}
-#endif // FEATURE_REMOTING
bool Module::AreAllClassesFullyLoaded()
{
@@ -9862,16 +8568,7 @@ void Module::PrepareTypesForSave(DataImage *image)
if (pMT == NULL || !pMT->IsFullyLoaded())
continue;
-#ifdef FEATURE_REMOTING
- PrepareRemotableMethodInfo(pMT);
-#endif // FEATURE_REMOTING
-#ifdef FEATURE_CER
- // If this module defines any CriticalFinalizerObject derived classes,
- // then we'll prepare these types for Constrained Execution Regions (CER) now.
- // (Normally they're prepared at object instantiation time, a little too late for ngen).
- PrepareCriticalType(pMT);
-#endif // FEATURE_CER
}
}
@@ -9900,16 +8597,6 @@ void Module::PrepareTypesForSave(DataImage *image)
}
}
-#ifdef FEATURE_REMOTING
- for(COUNT_T i = 0; i < pTypes.GetCount(); i ++)
- {
- MethodTable * pMT = pTypes[i].AsMethodTable();
-
- PrepareRemotableMethodInfo(pMT);
-
- // @todo: prepare critical instantiated types?
- }
-#endif // FEATURE_REMOTING
}
image->GetPreloader()->TriageForZap(FALSE, FALSE);
@@ -9955,9 +8642,6 @@ void Module::Save(DataImage *image)
// Cache values of all persisted flags computed from custom attributes
IsNoStringInterning();
IsRuntimeWrapExceptions();
-#ifdef FEATURE_CER
- GetReliabilityContract();
-#endif
IsPreV4Assembly();
HasDefaultDllImportSearchPathsAttribute();
@@ -10312,12 +8996,6 @@ void Module::Save(DataImage *image)
m_nPropertyNameSet * sizeof(BYTE),
DataImage::ITEM_PROPERTY_NAME_SET);
-#ifdef FEATURE_CER
- // Save Constrained Execution Region (CER) fixup information (used to eagerly fixup trees of methods to avoid any runtime
- // induced failures when invoking the tree).
- if (m_pCerNgenRootTable != NULL)
- m_pCerNgenRootTable->Save(image, profileData);
-#endif
// Sort the list of RVA statics in an ascending order wrt the RVA
// and save them.
@@ -10373,8 +9051,8 @@ void Module::Save(DataImage *image)
InlineTrackingMap *inlineTrackingMap = image->GetInlineTrackingMap();
if (inlineTrackingMap)
{
- m_persistentInlineTrackingMap = new (image->GetHeap()) PersistentInlineTrackingMap(this);
- m_persistentInlineTrackingMap->Save(image, inlineTrackingMap);
+ m_pPersistentInlineTrackingMapNGen = new (image->GetHeap()) PersistentInlineTrackingMapNGen(this);
+ m_pPersistentInlineTrackingMapNGen->Save(image, inlineTrackingMap);
}
if (m_pNgenStats && g_CorCompileVerboseLevel >= CORCOMPILE_STATS)
@@ -10773,18 +9451,6 @@ void Module::PlaceMethod(DataImage *image, MethodDesc *pMD, DWORD profilingFlags
image->PlaceStructureForAddress(pMD, CORCOMPILE_SECTION_WRITE);
}
-#ifdef FEATURE_CER
- if (profilingFlags & (1 << ReadCerMethodList))
- {
- // protect against stale IBC data
- // Check if the profiling data incorrectly set the ReadCerMethodList bit.
- // This is more likely to happen with incremental IBC.
- if ((m_pCerNgenRootTable != NULL) && m_pCerNgenRootTable->IsNgenRootMethod(pMD))
- {
- image->PlaceStructureForAddress(m_pCerNgenRootTable->GetList(pMD), CORCOMPILE_SECTION_HOT);
- }
- }
-#endif // FEATURE_CER
if (profilingFlags & (1 << WriteMethodPrecode))
{
@@ -11328,24 +9994,6 @@ void Module::Fixup(DataImage *image)
image->ZeroField(m_FileReferencesMap.pTable, 0,
m_FileReferencesMap.GetSize() * sizeof(void*));
-#ifdef FEATURE_CER
- //
- // Fixup Constrained Execution Regions restoration records.
- //
- if (m_pCerNgenRootTable != NULL)
- {
- image->BeginRegion(CORINFO_REGION_HOT);
- image->FixupPointerField(this, offsetof(Module, m_pCerNgenRootTable));
- m_pCerNgenRootTable->Fixup(image);
- image->EndRegion(CORINFO_REGION_HOT);
- }
- else
- image->ZeroPointerField(this, offsetof(Module, m_pCerNgenRootTable));
-
- // Zero out fields we always compute at runtime lazily.
- image->ZeroField(this, offsetof(Module, m_pCerPrepInfo), sizeof(m_pCerPrepInfo));
- image->ZeroField(this, offsetof(Module, m_pCerCrst), sizeof(m_pCerCrst));
-#endif // FEATURE_CER
image->ZeroField(this, offsetof(Module, m_debuggerSpecificData), sizeof(m_debuggerSpecificData));
@@ -11403,14 +10051,14 @@ void Module::Fixup(DataImage *image)
}
// Fix up inlining data
- if(m_persistentInlineTrackingMap)
+ if(m_pPersistentInlineTrackingMapNGen)
{
- image->FixupPointerField(this, offsetof(Module, m_persistentInlineTrackingMap));
- m_persistentInlineTrackingMap->Fixup(image);
+ image->FixupPointerField(this, offsetof(Module, m_pPersistentInlineTrackingMapNGen));
+ m_pPersistentInlineTrackingMapNGen->Fixup(image);
}
else
{
- image->ZeroPointerField(this, offsetof(Module, m_persistentInlineTrackingMap));
+ image->ZeroPointerField(this, offsetof(Module, m_pPersistentInlineTrackingMapNGen));
}
SetIsModuleSaved();
@@ -14059,13 +12707,6 @@ void Module::DeleteProfilingData()
}
#endif //FEATURE_PREJIT
-#ifdef FEATURE_MIXEDMODE
-void Module::SetIsIJWFixedUp()
-{
- LIMITED_METHOD_CONTRACT;
- FastInterlockOr(&m_dwTransientFlags, IS_IJW_FIXED_UP);
-}
-#endif
#ifdef FEATURE_PREJIT
@@ -14499,15 +13140,8 @@ ReflectionModule *ReflectionModule::Create(Assembly *pAssembly, PEFile *pFile, A
// Hoist CONTRACT into separate routine because of EX incompatibility
mdFile token;
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- if (pFile->IsAssembly())
- token = mdFileNil;
- else
- token = ((PEModule *)pFile)->GetToken();
-#else
_ASSERTE(pFile->IsAssembly());
token = mdFileNil;
-#endif
// Initial memory block for Modules must be zero-initialized (to make it harder
// to introduce Destruct crashes arising from OOM's during initialization.)
@@ -15497,12 +14131,6 @@ void Module::EnumMemoryRegions(CLRDataEnumMemoryFlags flags,
m_pStubMethodHashTable->EnumMemoryRegions(flags);
}
#endif // FEATURE_PREJIT
-#ifdef FEATURE_MIXEDMODE
- if (m_pThunkHeap.IsValid())
- {
- m_pThunkHeap->EnumMemoryRegions(flags);
- }
-#endif // FEATURE_MIXEDMODE
if (m_pBinder.IsValid())
{
m_pBinder->EnumMemoryRegions(flags);
@@ -15609,159 +14237,6 @@ FieldDesc *Module::LookupFieldDef(mdFieldDef token)
#endif // DACCESS_COMPILE
-#if !defined(DACCESS_COMPILE) && defined(FEATURE_CER)
-
-// Access to CerPrepInfo, the structure used to track CERs prepared at runtime (as opposed to ngen time). GetCerPrepInfo will
-// return the structure associated with the given method desc if it exists or NULL otherwise. CreateCerPrepInfo will get the
-// structure if it exists or allocate and return a new struct otherwise. Creation of CerPrepInfo structures is automatically
-// synchronized by the CerCrst (lazily allocated as needed).
-CerPrepInfo *Module::GetCerPrepInfo(MethodDesc *pMD)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- PRECONDITION(CheckPointer(pMD));
- }
- CONTRACTL_END;
-
- if (m_pCerPrepInfo == NULL)
- return NULL;
-
- // Don't need a crst for read only access to the hash table.
- HashDatum sDatum;
- if (m_pCerPrepInfo->GetValue(pMD, &sDatum))
- return (CerPrepInfo*)sDatum;
- else
- return NULL;
-}
-
-CerPrepInfo *Module::CreateCerPrepInfo(MethodDesc *pMD)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pMD));
- }
- CONTRACTL_END;
-
- // Lazily allocate a Crst to serialize update access to the info structure.
- // Carefully synchronize to ensure we don't leak a Crst in race conditions.
- if (m_pCerCrst == NULL)
- {
- Crst *pCrst = new Crst(CrstCer);
- if (InterlockedCompareExchangeT(&m_pCerCrst, pCrst, NULL) != NULL)
- delete pCrst;
- }
-
- CrstHolder sCrstHolder(m_pCerCrst);
-
- // Lazily allocate the info structure.
- if (m_pCerPrepInfo == NULL)
- {
- LockOwner sLock = {m_pCerCrst, IsOwnerOfCrst};
- NewHolder <EEPtrHashTable> tempCerPrepInfo (new EEPtrHashTable());
- if (!tempCerPrepInfo->Init(CER_DEFAULT_HASH_SIZE, &sLock))
- COMPlusThrowOM();
- m_pCerPrepInfo = tempCerPrepInfo.Extract ();
- }
- else
- {
- // Try getting an existing value first.
- HashDatum sDatum;
- if (m_pCerPrepInfo->GetValue(pMD, &sDatum))
- return (CerPrepInfo*)sDatum;
- }
-
- // We get here if there was no info structure or no existing method desc entry. Either way we now have an info structure and
- // need to create a new method desc entry.
- NewHolder<CerPrepInfo> pInfo(new CerPrepInfo());
-
- m_pCerPrepInfo->InsertValue(pMD, (HashDatum)pInfo);
-
- return pInfo.Extract();
-}
-
-#ifdef FEATURE_NATIVE_IMAGE_GENERATION
-// Access to CerNgenRootTable which holds holds information for all the CERs rooted at a method in this module (that were
-// discovered during an ngen).
-
-// Add a list of MethodContextElements representing a CER to the root table keyed by the MethodDesc* of the root method. Creates
-// or expands the root table as necessary. This should only be called during ngen (at runtime we only read the table).
-void Module::AddCerListToRootTable(MethodDesc *pRootMD, MethodContextElement *pList)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(IsCompilationProcess());
- }
- CONTRACTL_END;
-
- // Although this is only called during ngen we still get cases where a module comes through here already ngen'd (because of
- // ngen's habit of letting code execute during compilation). Until that's fixed we'll just back out if the module has already
- // fixed the root table into unwriteable storage.
- if (m_pCerNgenRootTable && !(m_dwTransientFlags & M_CER_ROOT_TABLE_ON_HEAP))
- return;
-
- // Lazily allocate a Crst to serialize update access to the info structure.
- // Carefully synchronize to ensure we don't leak a Crst in race conditions.
- if (m_pCerCrst == NULL)
- {
- Crst *pCrst = new Crst(CrstCer);
- if (InterlockedCompareExchangeT(&m_pCerCrst, pCrst, NULL) != NULL)
- delete pCrst;
- }
-
- CrstHolder sCrstHolder(m_pCerCrst);
-
- // Lazily allocate the root table structure.
- if (m_pCerNgenRootTable == NULL)
- {
- FastInterlockOr(&m_dwTransientFlags, M_CER_ROOT_TABLE_ON_HEAP);
- m_pCerNgenRootTable = new CerNgenRootTable();
- }
-
- _ASSERTE(m_dwTransientFlags & M_CER_ROOT_TABLE_ON_HEAP);
-
- // And add the new element.
- m_pCerNgenRootTable->AddRoot(pRootMD, pList);
-}
-#endif // FEATURE_NATIVE_IMAGE_GENERATION
-
-#ifdef FEATURE_PREJIT
-// Returns true if the given method is a CER root detected at ngen time.
-bool Module::IsNgenCerRootMethod(MethodDesc *pMD)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- MODE_ANY;
- }
- CONTRACTL_END;
- _ASSERTE(pMD->GetModule() == this);
- if (m_pCerNgenRootTable)
- return m_pCerNgenRootTable->IsNgenRootMethod(pMD);
- return false;
-}
-
-// Restores the CER rooted at this method (no-op if this method isn't a CER root).
-void Module::RestoreCer(MethodDesc *pMD)
-{
- STANDARD_VM_CONTRACT;
- _ASSERTE(pMD->GetModule() == this);
- if (m_pCerNgenRootTable)
- m_pCerNgenRootTable->Restore(pMD);
-}
-
-#endif // FEATURE_PREJIT
-
-#endif // !DACCESS_COMPILE && FEATURE_CER
@@ -15794,7 +14269,6 @@ LPCWSTR Module::GetPathForErrorMessages()
}
}
-#ifdef FEATURE_CORECLR
#ifndef DACCESS_COMPILE
BOOL IsVerifiableWrapper(MethodDesc* pMD)
{
@@ -15861,9 +14335,6 @@ void Module::VerifyAllMethods()
};
//Verify all methods in a module eagerly, forcing them to get loaded.
- /* XXX Thu 4/26/2007
- * This code is lifted mostly from Validator.cpp
- */
IMDInternalImport * pMDI = GetMDImport();
HENUMTypeDefInternalHolder hEnum(pMDI);
mdTypeDef td;
@@ -15887,7 +14358,6 @@ void Module::VerifyAllMethods()
EEFileLoadException::Throw(GetFile(), COR_E_VERIFICATION);
#endif //DACCESS_COMPILE
}
-#endif //FEATURE_CORECLR
#if defined(_DEBUG) && !defined(DACCESS_COMPILE) && !defined(CROSS_COMPILE)
@@ -16064,8 +14534,7 @@ void Module::ExpandAll()
#include "clrvarargs.h" /* for VARARG C_ASSERTs in asmconstants.h */
class CheckAsmOffsets
{
-#define ASMCONSTANTS_C_ASSERT(cond) \
- typedef char UNIQUE_LABEL(__C_ASSERT__)[(cond) ? 1 : -1];
+#define ASMCONSTANTS_C_ASSERT(cond) static_assert(cond, #cond);
#include "asmconstants.h"
};
diff --git a/src/vm/ceeload.h b/src/vm/ceeload.h
index d15bd6b3d1..2f3fe90a08 100644
--- a/src/vm/ceeload.h
+++ b/src/vm/ceeload.h
@@ -13,9 +13,6 @@
#define CEELOAD_H_
#include "common.h"
-#ifdef FEATURE_FUSION
-#include <fusion.h>
-#endif
#include "vars.hpp" // for LPCUTF8
#include "hash.h"
#include "clsload.hpp"
@@ -84,7 +81,8 @@ class TypeHandleList;
class ProfileEmitter;
class ReJitManager;
class TrackingMap;
-class PersistentInlineTrackingMap;
+struct MethodInModule;
+class PersistentInlineTrackingMapNGen;
// Hash table parameter of available classes (name -> module/class) hash
#define AVAILABLE_CLASSES_HASH_BUCKETS 1024
@@ -95,7 +93,6 @@ class PersistentInlineTrackingMap;
#define GUID_TO_TYPE_HASH_BUCKETS 16
// The native symbol reader dll name
-#ifdef FEATURE_CORECLR
#if defined(_AMD64_)
#define NATIVE_SYMBOL_READER_DLL W("Microsoft.DiaSymReader.Native.amd64.dll")
#elif defined(_X86_)
@@ -107,11 +104,8 @@ class PersistentInlineTrackingMap;
//#define NATIVE_SYMBOL_READER_DLL W("Microsoft.DiaSymReader.Native.arm64.dll")
#define NATIVE_SYMBOL_READER_DLL W("diasymreader.dll")
#endif
-#else
-#define NATIVE_SYMBOL_READER_DLL W("diasymreader.dll")
-#endif
-typedef DPTR(PersistentInlineTrackingMap) PTR_PersistentInlineTrackingMap;
+typedef DPTR(PersistentInlineTrackingMapNGen) PTR_PersistentInlineTrackingMapNGen;
extern VerboseLevel g_CorCompileVerboseLevel;
#endif // FEATURE_PREJIT
@@ -1785,40 +1779,6 @@ private:
NgenStats *m_pNgenStats;
#endif // FEATURE_PREJIT
-#ifdef FEATURE_MIXEDMODE
- // LoaderHeap for storing thunks
- PTR_LoaderHeap m_pThunkHeap;
-
- // Self-initializing accessor for thunk heap
- LoaderHeap *GetThunkHeap();
- // Self-initializing accessor for domain-independent thunk heap
- LoaderHeap *GetDllThunkHeap();
-
-
-public:
- UMEntryThunk* GetADThunkTable();
- void SetADThunkTable(UMEntryThunk* pTable);
-
-protected:
- // Domain that the IJW fixups were applied in
- ADID m_DomainIdOfIJWFixups;
-
-public:
- ADID GetDomainIdOfIJWFixups()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERT(m_DomainIdOfIJWFixups != ADID());
- return m_DomainIdOfIJWFixups;
- }
-
- void SetDomainIdOfIJWFixups(ADID id)
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERT(id != ADID());
- m_DomainIdOfIJWFixups = id;
- }
-
-#endif // FEATURE_MIXEDMODE
protected:
@@ -1830,6 +1790,7 @@ protected:
protected:
#ifndef DACCESS_COMPILE
virtual void Initialize(AllocMemTracker *pamTracker, LPCWSTR szName = NULL);
+ void InitializeForProfiling();
#ifdef FEATURE_PREJIT
void InitializeNativeImage(AllocMemTracker* pamTracker);
#endif
@@ -1868,9 +1829,6 @@ protected:
void ApplyMetaData();
-#ifdef FEATURE_MIXEDMODE
- void FixupVTables();
-#endif
void FreeClassTables();
@@ -2185,11 +2143,6 @@ protected:
virtual void ReleaseILData();
-#ifdef FEATURE_FUSION
- void FusionCopyPDBs(LPCWSTR moduleName);
- // This function will return PDB stream if exist.
- HRESULT GetHostPdbStream(IStream **ppStream);
-#endif // FEATURE_FUSION
#endif // DACCESS_COMPILE
@@ -2679,7 +2632,8 @@ public:
void NotifyProfilerLoadFinished(HRESULT hr);
#endif // PROFILING_SUPPORTED
- PTR_PersistentInlineTrackingMap GetNgenInlineTrackingMap();
+ BOOL HasInlineTrackingMap();
+ COUNT_T GetInliners(PTR_Module inlineeOwnerMod, mdMethodDef inlineeTkn, COUNT_T inlinersSize, MethodInModule inliners[], BOOL *incompleteData);
public:
void NotifyEtwLoadFinished(HRESULT hr);
@@ -2708,10 +2662,6 @@ public:
BOOL CanExecuteCode();
-#ifdef FEATURE_MIXEDMODE
- LPVOID GetUMThunk(LPVOID pManagedIp, PCCOR_SIGNATURE pSig, ULONG cSig);
- LPVOID GetMUThunk(LPVOID pUnmanagedIp, PCCOR_SIGNATURE pSig, ULONG cSig);
-#endif // FEATURE_MIXEDMODE
// This data is only valid for NGEN'd modules, and for modules we're creating at NGEN time.
ModuleCtorInfo* GetZapModuleCtorInfo()
@@ -2723,9 +2673,6 @@ public:
private:
-#ifdef FEATURE_MIXEDMODE
- class MUThunkHash *m_pMUThunkHash;
-#endif // FEATURE_MIXEDMODE
public:
#ifndef DACCESS_COMPILE
@@ -2788,6 +2735,8 @@ public:
}
#endif // FEATURE_PREJIT
+
+ BOOL HasNativeOrReadyToRunImage();
PEImageLayout * GetNativeOrReadyToRunImage();
PTR_CORCOMPILE_IMPORT_SECTION GetImportSections(COUNT_T *pCount);
PTR_CORCOMPILE_IMPORT_SECTION GetImportSectionFromIndex(COUNT_T index);
@@ -3120,6 +3069,10 @@ public:
static void ProfileDataAllocateTokenLists(ProfileEmitter * pEmitter, TokenProfileData* pTokenProfileData);
HRESULT WriteMethodProfileDataLogFile(bool cleanup);
static void WriteAllModuleProfileData(bool cleanup);
+ void SetMethodProfileList(CORCOMPILE_METHOD_PROFILE_LIST * value)
+ {
+ m_methodProfileList = value;
+ }
void CreateProfilingData();
void DeleteProfilingData();
@@ -3394,12 +3347,6 @@ public:
//-----------------------------------------------------------------------------------------
BOOL IsPreV4Assembly();
-#ifdef FEATURE_CER
- //-----------------------------------------------------------------------------------------
- // Get reliability contract info, see ConstrainedExecutionRegion.cpp for details.
- //-----------------------------------------------------------------------------------------
- DWORD GetReliabilityContract();
-#endif
//-----------------------------------------------------------------------------------------
// Parse/Return NeutralResourcesLanguageAttribute if it exists (updates Module member variables at ngen time)
@@ -3408,50 +3355,13 @@ public:
protected:
-#ifdef FEATURE_CER
- Volatile<DWORD> m_dwReliabilityContract;
-#endif
// initialize Crst controlling the Dynamic IL hashtables
void InitializeDynamicILCrst();
public:
-#if !defined(DACCESS_COMPILE) && defined(FEATURE_CER)
-
- // Support for getting and creating information about Constrained Execution Regions rooted in this module.
-
- // Access to CerPrepInfo, the structure used to track CERs prepared at runtime (as opposed to ngen time). GetCerPrepInfo will
- // return the structure associated with the given method desc if it exists or NULL otherwise. CreateCerPrepInfo will get the
- // structure if it exists or allocate and return a new struct otherwise. Creation of CerPrepInfo structures is automatically
- // synchronized by the CerCrst (lazily allocated as needed).
- CerPrepInfo *GetCerPrepInfo(MethodDesc *pMD);
- CerPrepInfo *CreateCerPrepInfo(MethodDesc *pMD);
-
-#ifdef FEATURE_PREJIT
- // Access to CerNgenRootTable which holds holds information for all the CERs rooted at a method in this module (that were
- // discovered during an ngen).
-
- // Add a list of MethodContextElements representing a CER to the root table keyed by the MethodDesc* of the root method. Creates
- // or expands the root table as necessary.
- void AddCerListToRootTable(MethodDesc *pRootMD, MethodContextElement *pList);
- // Returns true if the given method is a CER root detected at ngen time.
- bool IsNgenCerRootMethod(MethodDesc *pMD);
-
- // Restores the CER rooted at this method (no-op if this method isn't a CER root).
- void RestoreCer(MethodDesc *pMD);
-#endif // FEATURE_PREJIT
-
- Crst *GetCerCrst()
- {
- LIMITED_METHOD_CONTRACT;
- return m_pCerCrst;
- }
-#endif // !DACCESS_COMPILE && FEATURE_CER
-
-#ifdef FEATURE_CORECLR
void VerifyAllMethods();
-#endif //FEATURE_CORECLR
CrstBase *GetLookupTableCrst()
{
@@ -3460,13 +3370,6 @@ public:
}
private:
-#ifdef FEATURE_CER
- EEPtrHashTable *m_pCerPrepInfo; // Root methods prepared for Constrained Execution Regions
- Crst *m_pCerCrst; // Mutex protecting update access to both of the above hashes
-#ifdef FEATURE_PREJIT
- CerNgenRootTable *m_pCerNgenRootTable; // Root methods of CERs found during ngen and requiring runtime restoration
-#endif
-#endif
// This struct stores the data used by the managed debugging infrastructure. If it turns out that
// the debugger is increasing the size of the Module class by too much, we can consider allocating
@@ -3498,7 +3401,7 @@ private:
DebuggerSpecificData m_debuggerSpecificData;
// This is a compressed read only copy of m_inlineTrackingMap, which is being saved to NGEN image.
- PTR_PersistentInlineTrackingMap m_persistentInlineTrackingMap;
+ PTR_PersistentInlineTrackingMapNGen m_pPersistentInlineTrackingMapNGen;
LPCSTR *m_AssemblyRefByNameTable; // array that maps mdAssemblyRef tokens into their simple name
diff --git a/src/vm/ceemain.cpp b/src/vm/ceemain.cpp
index ca819ecbfd..6b0c0dfbba 100644
--- a/src/vm/ceemain.cpp
+++ b/src/vm/ceemain.cpp
@@ -39,25 +39,25 @@
//
//*************************************************************************************************
//
-// * Introduction to the rutnime file:../../doc/BookOfTheRuntime/Introduction/BOTR%20Introduction.docx
+// * Introduction to the runtime file:../../Documentation/botr/botr-faq.md
//
// #MajorDataStructures. The major data structures associated with the runtime are
// * code:Thread (see file:threads.h#ThreadClass) - the additional thread state the runtime needs.
// * code:AppDomain - The managed version of a process
-// * code:Assembly - The unit of deployment and versioing (may be several DLLs but often is only one).
-// * code:Module -represents a Module (DLL or EXE).
+// * code:Assembly - The unit of deployment and versioning (may be several DLLs but often is only one).
+// * code:Module - represents a Module (DLL or EXE).
// * code:MethodTable - represents the 'hot' part of a type (needed during normal execution)
// * code:EEClass - represents the 'cold' part of a type (used during compilation, interop, ...)
// * code:MethodDesc - represents a Method
// * code:FieldDesc - represents a Field.
-// * code:Object - represents a object on the GC heap alloated with code:Alloc
+// * code:Object - represents a object on the GC heap allocated with code:Alloc
//
// * ECMA specifications
// * Partition I Concepts
// http://download.microsoft.com/download/D/C/1/DC1B219F-3B11-4A05-9DA3-2D0F98B20917/Partition%20I%20Architecture.doc
// * Partition II Meta Data
// http://download.microsoft.com/download/D/C/1/DC1B219F-3B11-4A05-9DA3-2D0F98B20917/Partition%20II%20Metadata.doc
-// * Parition III IL
+// * Partition III IL
// http://download.microsoft.com/download/D/C/1/DC1B219F-3B11-4A05-9DA3-2D0F98B20917/Partition%20III%20CIL.doc
//
// * Serge Liden (worked on the CLR and owned ILASM / ILDASM for a long time wrote a good book on IL
@@ -76,7 +76,7 @@
// * code:ICorJitCompiler#EEToJitInterface - This is the interface from the the EE to the Just in time (JIT)
// compiler. The interface to the JIT is relatively simple (compileMethod), however the EE provides a
// rich set of callbacks so the JIT can get all the information it needs. See also
-// file:../../doc/BookOfTheRuntime/JIT/JIT%20Design.doc for general information on the JIT.
+// file:../../Documentation/botr/ryujit-overview.md for general information on the JIT.
//
// * code:VirtualCallStubManager - This is the main class that implements interface dispatch
//
@@ -85,36 +85,22 @@
// and will call the JIT compiler if the code does not yet exist.
//
// * NGEN - NGen stands for Native code GENeration and it is the runtime way of precomiling IL and IL
-// Meta-data into native code and runtime data structures. See
-// file:../../doc/BookOfTheRuntime/NGEN/NGENDesign.doc for an overview. At compilation time the most
+// Meta-data into native code and runtime data structures. At compilation time the most
// fundamental data structures is the code:ZapNode which represents something that needs to go into the
// NGEN image.
//
// * What is cooperative / preemtive mode ? file:threads.h#CooperativeMode and
-// file:threads.h#SuspendingTheRuntime
-// * Garbage collection - file:gc.cpp#Overview
+// file:threads.h#SuspendingTheRuntime and file:../../Documentation/botr/threading.md
+// * Garbage collection - file:gc.cpp#Overview and file:../../Documentation/botr/garbage-collection.md
// * code:AppDomain - The managed version of a process.
-// * Calling Into the runtime (FCALLs QCalls) file:../../doc/BookOfTheRuntime/mscorlib/mscorlibDesign.doc
-// * Exceptions - file:../../doc/BookOfTheRuntime/ManagedEH\Design.doc. The most important routine to start
-// with is code:COMPlusFrameHandler which is the routine that we hook up to get called when an unanaged
+// * Calling Into the runtime (FCALLs QCalls) file:../../Documentation/botr/mscorlib.md
+// * Exceptions - file:../../Documentation/botr/exceptions.md. The most important routine to start
+// with is code:COMPlusFrameHandler which is the routine that we hook up to get called when an unmanaged
// exception happens.
-// * Constrain Execution Regions (reliability) file:../../doc/BookOfTheRuntime/CER/CERDesign.doc)
-// * Assembly Loading file:../../doc/BookOfTheRuntime/AssemblyLoader/AssemblyLoader.doc
-// * Fusion and loading files file:../../doc/BookOfTheRuntime/AssemblyLoader/FusionDesign.doc
-// * Strings file:../../doc/BookOfTheRuntime/BCL/SystemStringDesign.doc
-// * Profiling file:../../doc/BookOfTheRuntime/DiagnosticServices/ProfilingAPIDesign.doc
-// * Remoting file:../../doc/BookOfTheRuntime/EERemotingSupport/RemotingDesign.doc
-// * Managed Debug Assitants file:../../doc/BookOfTheRuntime/MDA/MDADesign.doc
+// * Assembly Loading file:../../Documentation/botr/type-loader.md
+// * Profiling file:../../Documentation/botr/profiling.md and file:../../Documentation/botr/profilability.md
// * FCALLS QCALLS (calling into the runtime from managed code)
-// file:../../doc/BookOfTheRuntime/Mscorlib/MscorlibDesign.doc
-// * Reflection file:../../doc/BookOfTheRuntime/Reflection/ReflectionDesign.doc
-// * Security
-// * file:../../doc/BookOfTheRuntime/RuntimeSecurity/RuntimeSecurityDesign.doc
-// * file:../../doc/BookOfTheRuntime/LoadtimeSecurity/DeclarativeSecurity-Design.doc
-// * file:../../doc/BookOfTheRuntime/LoadtimeSecurity/StrongName.doc
-// * file:../../doc/BookOfTheRuntime/RuntimeSecurity/ClickOnce Activation.doc
-// * file:../../doc/BookOfTheRuntime/RuntimeSecurity/Cryptography.doc
-// * file:../../doc/BookOfTheRuntime/RuntimeSecurity/DemandEvalDesign.doc
+// file:../../Documentation/botr/mscorlib.md
// * Event Tracing for Windows
// * file:../inc/eventtrace.h#EventTracing -
// * This is the main file dealing with event tracing in CLR
@@ -158,13 +144,9 @@
#include "eedbginterfaceimpl.h"
#include "debugdebugger.h"
#include "cordbpriv.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "comdelegate.h"
#include "appdomain.hpp"
#include "perfcounters.h"
-#include "rwlock.h"
#ifdef FEATURE_IPCMAN
#include "ipcmanagerinterface.h"
#endif // FEATURE_IPCMAN
@@ -213,10 +195,6 @@
#include "bbsweep.h"
-#ifndef FEATURE_CORECLR
-#include <metahost.h>
-#include "assemblyusagelogmanager.h"
-#endif
#ifdef FEATURE_COMINTEROP
#include "runtimecallablewrapper.h"
@@ -244,19 +222,15 @@
#include "interpreter.h"
#endif // FEATURE_INTERPRETER
-#ifndef FEATURE_FUSION
#include "../binder/inc/coreclrbindercommon.h"
-#endif // !FEATURE_FUSION
-#ifdef FEATURE_UEF_CHAINMANAGER
-// This is required to register our UEF callback with the UEF chain manager
-#include <mscoruefwrapper.h>
-#endif // FEATURE_UEF_CHAINMANAGER
#ifdef FEATURE_PERFMAP
#include "perfmap.h"
#endif
+#include "eventpipe.h"
+
#ifndef FEATURE_PAL
// Included for referencing __security_cookie
#include "process.h"
@@ -275,21 +249,7 @@ static HRESULT GetThreadUICultureNames(__inout StringArrayList* pCultureNames);
#endif // !CROSSGEN_COMPILE
HRESULT EEStartup(COINITIEE fFlags);
-#ifdef FEATURE_FUSION
-extern "C" HRESULT STDMETHODCALLTYPE InitializeFusion();
-#endif
-#ifdef FEATURE_MIXEDMODE
-HRESULT PrepareExecuteDLLForThunk(HINSTANCE hInst,
- DWORD dwReason,
- LPVOID lpReserved);
-#endif // FEATURE_MIXEDMODE
-#ifndef FEATURE_CORECLR
-BOOL STDMETHODCALLTYPE ExecuteDLL(HINSTANCE hInst,
- DWORD dwReason,
- LPVOID lpReserved,
- BOOL fFromThunk);
-#endif // !FEATURE_CORECLR
BOOL STDMETHODCALLTYPE ExecuteEXE(HMODULE hMod);
BOOL STDMETHODCALLTYPE ExecuteEXE(__in LPWSTR pImageNameIn);
@@ -305,12 +265,6 @@ extern "C" HRESULT __cdecl CorDBGetInterface(DebugInterface** rcInterface);
#endif // !CROSSGEN_COMPILE
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-
-// Pointer to the activated CLR interface provided by the shim.
-ICLRRuntimeInfo *g_pCLRRuntime = NULL;
-
-#endif // !FEATURE_CORECLR && !CROSSGEN_COMPILE
extern "C" IExecutionEngine* __stdcall IEE();
@@ -391,7 +345,7 @@ HRESULT EnsureEEStarted(COINITIEE flags)
{
BEGIN_ENTRYPOINT_NOTHROW;
-#if defined(FEATURE_CORECLR) && defined(FEATURE_APPX) && !defined(CROSSGEN_COMPILE)
+#if defined(FEATURE_APPX) && !defined(CROSSGEN_COMPILE)
STARTUP_FLAGS startupFlags = CorHost2::GetStartupFlags();
// On CoreCLR, the host is in charge of determining whether the process is AppX or not.
AppX::SetIsAppXProcess(!!(startupFlags & STARTUP_APPX_APP_MODEL));
@@ -403,15 +357,6 @@ HRESULT EnsureEEStarted(COINITIEE flags)
REGUTIL::InitOptionalConfigCache();
#endif
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *pHostTaskManager = CorHost2::GetHostTaskManager();
- if (pHostTaskManager)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pHostTaskManager->BeginThreadAffinity();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
BOOL bStarted=FALSE;
@@ -442,14 +387,6 @@ HRESULT EnsureEEStarted(COINITIEE flags)
}
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (pHostTaskManager)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pHostTaskManager->EndThreadAffinity();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#ifdef FEATURE_TESTHOOKS
if(bStarted)
TESTHOOKCALL(RuntimeStarted(RTS_INITIALIZED));
@@ -528,58 +465,7 @@ static BOOL WINAPI DbgCtrlCHandler(DWORD dwCtrlType)
// A host can specify that it only wants one version of hosting interface to be used.
BOOL g_singleVersionHosting;
-#ifndef FEATURE_CORECLR
-HRESULT STDMETHODCALLTYPE
-SetRuntimeInfo(
- IUnknown * pUnk,
- STARTUP_FLAGS dwStartupFlags,
- LPCWSTR pwzHostConfig,
- const CoreClrCallbacks ** ppClrCallbacks)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- ENTRY_POINT;
- PRECONDITION(CheckPointer(pUnk));
- PRECONDITION(CheckPointer(pwzHostConfig, NULL_OK));
- } CONTRACTL_END;
-
- ICLRRuntimeInfo *pRuntime;
- HRESULT hr;
-
- IfFailGo(pUnk->QueryInterface(IID_ICLRRuntimeInfo, (LPVOID *)&pRuntime));
-
- IfFailGo(CorHost2::SetFlagsAndHostConfig(dwStartupFlags, pwzHostConfig, FALSE));
- if (InterlockedCompareExchangeT(&g_pCLRRuntime, pRuntime, NULL) != NULL)
- {
- // already set, release this one
- pRuntime->Release();
- }
- *ppClrCallbacks = &GetClrCallbacks();
-
-ErrExit:
- return hr;
-}
-#endif // !FEATURE_CORECLR
-
-#ifndef FEATURE_CORECLR
-HRESULT InitializeHostConfigFile()
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(return E_OUTOFMEMORY);
- } CONTRACTL_END;
-
- g_pszHostConfigFile = CorHost2::GetHostConfigFile();
- g_dwHostConfigFile = (g_pszHostConfigFile == NULL ? 0 : wcslen(g_pszHostConfigFile));
-
- return S_OK;
-}
-#endif // !FEATURE_CORECLR
void InitializeStartupFlags()
{
@@ -591,56 +477,15 @@ void InitializeStartupFlags()
STARTUP_FLAGS flags = CorHost2::GetStartupFlags();
-#ifndef FEATURE_CORECLR
- // If we are running under a requested performance default mode, honor any changes to startup flags
- // In the future, we could make this conditional on the host telling us which subset of flags is
- // valid to override. See file:PerfDefaults.h
- flags = PerformanceDefaults::GetModifiedStartupFlags(flags);
-#endif // !FEATURE_CORECLR
if (flags & STARTUP_CONCURRENT_GC)
g_IGCconcurrent = 1;
else
g_IGCconcurrent = 0;
-#ifndef FEATURE_CORECLR // TODO: We can remove this. Retaining it now just to be safe
- if (flags & STARTUP_SINGLE_VERSION_HOSTING_INTERFACE)
- {
- g_singleVersionHosting = TRUE;
- }
-
-#ifndef FEATURE_CORECLR
- g_pConfig->SetDisableCommitThreadStack(!CLRHosted() || (flags & STARTUP_DISABLE_COMMITTHREADSTACK));
-#else
- g_pConfig->SetDisableCommitThreadStack(true);
-#endif
-
- if(flags & STARTUP_LEGACY_IMPERSONATION)
- g_pConfig->SetLegacyImpersonationPolicy();
-
- if(flags & STARTUP_ALWAYSFLOW_IMPERSONATION)
- g_pConfig->SetAlwaysFlowImpersonationPolicy();
-
- if(flags & STARTUP_HOARD_GC_VM)
- g_IGCHoardVM = 1;
- else
- g_IGCHoardVM = 0;
-
-#ifdef GCTRIMCOMMIT
- if (flags & STARTUP_TRIM_GC_COMMIT)
- g_IGCTrimCommit = 1;
- else
- g_IGCTrimCommit = 0;
-#endif
-
- if(flags & STARTUP_ETW)
- g_fEnableETW = TRUE;
-
- if(flags & STARTUP_ARM)
- g_fEnableARM = TRUE;
-#endif // !FEATURE_CORECLR
InitializeHeapType((flags & STARTUP_SERVER_GC) != 0);
+ g_heap_type = (flags & STARTUP_SERVER_GC) == 0 ? GC_HEAP_WKS : GC_HEAP_SVR;
#ifdef FEATURE_LOADER_OPTIMIZATION
g_dwGlobalSharePolicy = (flags&STARTUP_LOADER_OPTIMIZATION_MASK)>>1;
@@ -740,37 +585,23 @@ void InitGSCookie()
}
}
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-void InitAssemblyUsageLogManager()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- g_pIAssemblyUsageLogGac = NULL;
-
- AssemblyUsageLogManager::Config config;
+Volatile<BOOL> g_bIsGarbageCollectorFullyInitialized = FALSE;
- config.wszLogDir = NULL;
- config.cLogBufferSize = 32768;
-#ifdef FEATURE_APPX
- config.uiLogRefreshInterval = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NGenAssemblyUsageLogRefreshInterval);
-#endif
+void SetGarbageCollectorFullyInitialized()
+{
+ LIMITED_METHOD_CONTRACT;
- NewArrayHolder<WCHAR> szCustomLogDir(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NGenAssemblyUsageLog));
- config.wszLogDir = szCustomLogDir;
+ g_bIsGarbageCollectorFullyInitialized = TRUE;
+}
- AssemblyUsageLogManager::Init(&config);
+// Tells whether the garbage collector is fully initialized
+// Stronger than IsGCHeapInitialized
+BOOL IsGarbageCollectorFullyInitialized()
+{
+ LIMITED_METHOD_CONTRACT;
- // Once the logger is initialized, create a log object for logging GAC loads.
- AssemblyUsageLogManager::GetUsageLogForContext(W("fusion"), W("GAC"), &g_pIAssemblyUsageLogGac);
+ return g_bIsGarbageCollectorFullyInitialized;
}
-#endif
// ---------------------------------------------------------------------------
// %%Function: EEStartupHelper
@@ -845,10 +676,6 @@ void EEStartupHelper(COINITIEE fFlags)
if (!g_pConfig)
{
IfFailGo(EEConfig::Setup());
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- IfFailGo(InitializeHostConfigFile());
- IfFailGo(g_pConfig->SetupConfiguration());
-#endif // !FEATURE_CORECLR && !CROSSGEN_COMPILE
}
#ifndef CROSSGEN_COMPILE
@@ -858,11 +685,6 @@ void EEStartupHelper(COINITIEE fFlags)
NumaNodeInfo::InitNumaNodeInfo();
CPUGroupInfo::EnsureInitialized();
-#ifndef FEATURE_CORECLR
- // Check in EEConfig whether a workload-specific set of performance defaults have been requested
- // This needs to be done before InitializeStartupFlags in case one is to be overridden
- PerformanceDefaults::InitializeForScenario(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PerformanceScenario));
-#endif
// Initialize global configuration settings based on startup flags
// This needs to be done before the EE has started
@@ -897,10 +719,6 @@ void EEStartupHelper(COINITIEE fFlags)
#endif // CROSSGEN_COMPILE
-#ifndef FEATURE_CORECLR
- // Ensure initialization of Apphacks environment variables
- GetGlobalCompatibilityFlags();
-#endif // !FEATURE_CORECLR
#ifdef STRESS_LOG
if (REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLog, g_pConfig->StressLog ()) != 0) {
@@ -935,15 +753,8 @@ void EEStartupHelper(COINITIEE fFlags)
#endif
// Fusion
-#ifdef FEATURE_FUSION
- {
- ETWOnStartup (FusionInit_V1, FusionInitEnd_V1);
- IfFailGoLog(InitializeFusion());
- }
-#else // FEATURE_FUSION
// Initialize the general Assembly Binder infrastructure
IfFailGoLog(CCoreCLRBinderHelper::Init());
-#endif // FEATURE_FUSION
if (g_pConfig != NULL)
{
@@ -988,21 +799,10 @@ void EEStartupHelper(COINITIEE fFlags)
#ifndef CROSSGEN_COMPILE
-#if defined(STRESS_HEAP) && defined(_DEBUG) && !defined(FEATURE_CORECLR)
- // TODO: is this still an issue?
- // There is a race that causes random AVs on dual proc boxes
- // that we suspect is due to memory coherancy problems (see Whidbey bug 2360)
- // Avoid the issue by making the box effectively single proc.
- if (GCStress<cfg_instr>::IsEnabled() &&
- g_SystemInfo.dwNumberOfProcessors > 1)
- SetProcessAffinityMask(GetCurrentProcess(),
- 1 << (DbgGetEXETimeStamp() % g_SystemInfo.dwNumberOfProcessors));
-#endif // STRESS_HEAP && _DEBUG && !FEATURE_CORECLR
#ifdef FEATURE_PREJIT
- // Initialize the sweeper thread. THis is violating our rules with hosting
- // so we only do it in the non-hosted case
- if (g_pConfig->GetZapBBInstr() != NULL && !CLRTaskHosted())
+ // Initialize the sweeper thread.
+ if (g_pConfig->GetZapBBInstr() != NULL)
{
DWORD threadID;
HANDLE hBBSweepThread = ::CreateThread(NULL,
@@ -1065,14 +865,14 @@ void EEStartupHelper(COINITIEE fFlags)
#ifndef CROSSGEN_COMPILE
+ InitializeGarbageCollector();
+
// Initialize remoting
-#ifdef FEATURE_REMOTING
- CRemotingServices::Initialize();
-#endif // FEATURE_REMOTING
- // weak_short, weak_long, strong; no pin
- if (!Ref_Initialize())
+ if (!GCHandleTableUtilities::GetGCHandleTable()->Initialize())
+ {
IfFailGo(E_OUTOFMEMORY);
+ }
// Initialize contexts
Context::Initialize();
@@ -1080,16 +880,6 @@ void EEStartupHelper(COINITIEE fFlags)
g_pEEShutDownEvent = new CLREvent();
g_pEEShutDownEvent->CreateManualEvent(FALSE);
-#ifdef FEATURE_RWLOCK
- // Initialize RWLocks
- CRWLock::ProcessInit();
-#endif // FEATURE_RWLOCK
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- // Initialize debugger manager
- CCLRDebugManager::ProcessInit();
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
#ifdef FEATURE_IPCMAN
// Initialize CCLRSecurityAttributeManager
CCLRSecurityAttributeManager::ProcessInit();
@@ -1099,11 +889,6 @@ void EEStartupHelper(COINITIEE fFlags)
GCInterface::m_MemoryPressureLock.Init(CrstGCMemoryPressure);
-#ifndef FEATURE_CORECLR
- // Initialize Assembly Usage Logger
- InitAssemblyUsageLogManager();
-#endif
-
#endif // CROSSGEN_COMPILE
// Setup the domains. Threads are started in a default domain.
@@ -1122,6 +907,10 @@ void EEStartupHelper(COINITIEE fFlags)
#ifndef CROSSGEN_COMPILE
+ // This isn't done as part of InitializeGarbageCollector() above because thread
+ // creation requires AppDomains to have been set up.
+ FinalizerThread::FinalizerThreadCreate();
+
#ifndef FEATURE_PAL
// Watson initialization must precede InitializeDebugger() and InstallUnhandledExceptionFilter()
// because on CoreCLR when Waston is enabled, debugging service needs to be enabled and UEF will be used.
@@ -1225,7 +1014,14 @@ void EEStartupHelper(COINITIEE fFlags)
}
#endif
- InitializeGarbageCollector();
+ // This isn't done as part of InitializeGarbageCollector() above because it
+ // requires write barriers to have been set up on x86, which happens as part
+ // of InitJITHelpers1.
+ hr = g_pGCHeap->Initialize();
+ IfFailGo(hr);
+
+ // Now we really have fully initialized the garbage collector
+ SetGarbageCollectorFullyInitialized();
InitializePinHandleTable();
@@ -1238,10 +1034,12 @@ void EEStartupHelper(COINITIEE fFlags)
SystemDomain::System()->DefaultDomain()));
SystemDomain::System()->PublishAppDomainAndInformDebugger(SystemDomain::System()->DefaultDomain());
#endif
-
-#ifndef FEATURE_CORECLR
- ExistingOobAssemblyList::Init();
-#endif
+
+#ifdef FEATURE_PERFTRACING
+ // Initialize the event pipe and start it if requested.
+ EventPipe::Initialize();
+ EventPipe::EnableOnStartup();
+#endif // FEATURE_PERFTRACING
#endif // CROSSGEN_COMPILE
@@ -1329,12 +1127,10 @@ void EEStartupHelper(COINITIEE fFlags)
}
//For a similar reason, let's not run VerifyAllOnLoad either.
-#ifdef FEATURE_CORECLR
if (g_pConfig->VerifyModulesOnLoad())
{
SystemDomain::SystemModule()->VerifyAllMethods();
}
-#endif //FEATURE_CORECLR
// Perform mscorlib consistency check if requested
g_Mscorlib.CheckExtended();
@@ -1595,11 +1391,6 @@ static void ExternalShutdownHelper(int exitCode, ShutdownCompleteAction sca)
// process exit code. This can be modified by the app via System.SetExitCode().
SetLatchedExitCode(exitCode);
-#ifndef FEATURE_CORECLR // no shim
- // Bump up the ref-count on the module
- for (int i =0; i<6; i++)
- CLRLoadLibrary(MSCOREE_SHIM_W);
-#endif // FEATURE_CORECLR
ForceEEShutdown(sca);
@@ -1671,12 +1462,6 @@ BOOL IsRuntimeStarted(DWORD *pdwStartupFlags)
if (pdwStartupFlags != NULL) // this parameter is optional
{
*pdwStartupFlags = 0;
-#ifndef FEATURE_CORECLR
- if (g_fEEStarted)
- {
- *pdwStartupFlags = CorHost2::GetStartupFlags();
- }
-#endif
}
return g_fEEStarted;
}
@@ -1791,7 +1576,7 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
ETW::EnumerationLog::ProcessShutdown();
}
-#if defined(FEATURE_CAS_POLICY) || defined(FEATURE_COMINTEROP)
+#if defined(FEATURE_COMINTEROP)
// Get the current thread.
Thread * pThisThread = GetThread();
#endif
@@ -1869,14 +1654,6 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
fFinalizeOK = FinalizerThread::FinalizerThreadWatchDog();
}
-#ifndef FEATURE_CORECLR
- if (!g_fFastExitProcess)
- {
- // Log usage data to disk. (Only do this in normal shutdown scenarios, and not involving ngen)
- if (!IsCompilationProcess())
- AssemblyUsageLogManager::GenerateLog(AssemblyUsageLogManager::GENERATE_LOG_FLAGS_NONE);
- }
-#endif
// Ok. Let's stop the EE.
if (!g_fProcessDetach)
@@ -1931,6 +1708,11 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
PerfMap::Destroy();
#endif
+#ifdef FEATURE_PERFTRACING
+ // Shutdown the event pipe.
+ EventPipe::Shutdown();
+#endif // FEATURE_PERFTRACING
+
#ifdef FEATURE_PREJIT
{
// If we're doing basic block profiling, we need to write the log files to disk.
@@ -1939,8 +1721,19 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
if (!fIBCLoggingDone)
{
if (g_IBCLogger.InstrEnabled())
- Module::WriteAllModuleProfileData(true);
+ {
+ Thread * pThread = GetThread();
+ ThreadLocalIBCInfo* pInfo = pThread->GetIBCInfo();
+ // Acquire the Crst lock before creating the IBCLoggingDisabler object.
+ // Only one thread at a time can be processing an IBC logging event.
+ CrstHolder lock(g_IBCLogger.GetSync());
+ {
+ IBCLoggingDisabler disableLogging( pInfo ); // runs IBCLoggingDisabler::DisableLogging
+
+ Module::WriteAllModuleProfileData(true);
+ }
+ }
fIBCLoggingDone = TRUE;
}
}
@@ -1990,22 +1783,6 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
}
#endif // PROFILING_SUPPORTED
-#ifndef FEATURE_CORECLR
- // CoEEShutDownCOM moved to
- // the Finalizer thread. See bug 87809
- if (!g_fProcessDetach && !g_fFastExitProcess)
- {
- g_fEEShutDown |= ShutDown_COM;
- if (fFinalizeOK)
- {
- FinalizerThread::FinalizerThreadWatchDog();
- }
- }
-#ifdef _DEBUG
- else
- g_fEEShutDown |= ShutDown_COM;
-#endif
-#endif //FEATURE_CORECLR
#ifdef _DEBUG
g_fEEShutDown |= ShutDown_SyncBlock;
@@ -2015,15 +1792,6 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
// because we are shutting down.
CONTRACT_VIOLATION(ModeViolation);
-#ifdef FEATURE_CAS_POLICY
- // Save the security policy cache as necessary.
- if (!g_fProcessDetach || pThisThread != NULL)
- {
- // If process shutdown has started, it is not safe to create Thread object which is needed
- // by the following call.
- Security::SaveCache();
- }
-#endif
#ifdef FEATURE_COMINTEROP
// We need to call CoUninitialize in part one to ensure orderly shutdown of COM dlls.
if (!g_fFastExitProcess)
@@ -2112,7 +1880,7 @@ part2:
#ifdef SHOULD_WE_CLEANUP
if (!g_fFastExitProcess)
{
- Ref_Shutdown(); // shut down the handle table
+ GCHandleTableUtilities::GetGCHandleTable()->Shutdown();
}
#endif /* SHOULD_WE_CLEANUP */
@@ -2662,774 +2430,6 @@ void STDMETHODCALLTYPE CoUninitializeEE(BOOL fIsDllUnloading)
}
-#ifndef FEATURE_CORECLR
-//*****************************************************************************
-// This entry point is called from the native DllMain of the loaded image.
-// This gives the COM+ loader the chance to dispatch the loader event. The
-// first call will cause the loader to look for the entry point in the user
-// image. Subsequent calls will dispatch to either the user's DllMain or
-// their Module derived class.
-//*****************************************************************************
-BOOL STDMETHODCALLTYPE _CorDllMain( // TRUE on success, FALSE on error.
- HINSTANCE hInst, // Instance handle of the loaded module.
- DWORD dwReason, // Reason for loading.
- LPVOID lpReserved // Unused.
- )
-{
- STATIC_CONTRACT_NOTHROW;
- //STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_ENTRY_POINT;
-
- //BEGIN_ENTRYPOINT_NOTHROW;
-
- struct Param
- {
- HINSTANCE hInst;
- DWORD dwReason;
- LPVOID lpReserved;
- BOOL retval;
- } param;
- param.hInst = hInst;
- param.dwReason = dwReason;
- param.lpReserved = lpReserved;
- param.retval = FALSE;
-
- // Can't use PAL_TRY/EX_TRY here as they access the ClrDebugState which gets blown away as part of the
- // PROCESS_DETACH path. Must use special PAL_TRY_FOR_DLLMAIN, passing the reason were in the DllMain.
- PAL_TRY_FOR_DLLMAIN(Param *, pParam, &param, pParam->dwReason)
- {
-#ifdef _DEBUG
- if (CLRTaskHosted() &&
- ((pParam->dwReason == DLL_PROCESS_ATTACH && pParam->lpReserved == NULL) || // LoadLibrary of a managed dll
- (pParam->dwReason == DLL_PROCESS_DETACH && pParam->lpReserved == NULL) // FreeLibrary of a managed dll
- )) {
- // OS loader lock is being held by the current thread. We can not allow the fiber
- // to be rescheduled here while processing DllMain for managed dll.
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTask *pTask = GetCurrentHostTask();
- if (pTask) {
- Thread *pThread = GetThread();
- _ASSERTE (pThread);
- _ASSERTE (pThread->HasThreadAffinity());
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- }
-#endif
- // Since we're in _CorDllMain, we know that we were not called because of a
- // bootstrap thunk, since they will call CorDllMainForThunk. Because of this,
- // we can pass FALSE for the fFromThunk parameter.
- pParam->retval = ExecuteDLL(pParam->hInst,pParam->dwReason,pParam->lpReserved, FALSE);
- }
- PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- }
- PAL_ENDTRY;
-
- //END_ENTRYPOINT_NOTHROW;
-
- return param.retval;
-}
-
-#endif // !FEATURE_CORECLR
-
-#ifdef FEATURE_MIXEDMODE
-//*****************************************************************************
-void STDMETHODCALLTYPE CorDllMainForThunk(HINSTANCE hInst, HINSTANCE hInstShim)
-{
-
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_GC_TRIGGERS;
-
-
- g_fEEIJWStartup = TRUE;
-
- {
-
- // If no managed thread exists, then we need to call the prepare method
- // to try and startup the runtime and/or create a managed thread object
- // so that installing an unwind and continue handler below is possible.
- // If we fail to startup or create a thread, we'll raise the basic
- // EXCEPTION_COMPLUS exception.
- if (GetThread() == NULL)
- {
- HRESULT hr;
- // Since this method is only called if a bootstrap thunk is invoked, we
- // know that passing TRUE for fFromThunk is the correct value.
- if (FAILED(hr = PrepareExecuteDLLForThunk(hInst, 0, NULL)))
- {
- RaiseComPlusException();
- }
- }
-
- }
-
- INSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
- // We're actually going to run some managed code and we're inside the loader lock.
- // There may be a customer debug probe enabled that prevents this.
- CanRunManagedCode(hInst);
-
- // Since this method is only called if a bootstrap thunk is invoked, we
- // know that passing TRUE for fFromThunk is the correct value.
- ExecuteDLL(hInst, 0, NULL, TRUE);
-
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
-}
-#endif // FEATURE_MIXEDMODE
-
-
-#ifndef FEATURE_CORECLR
-
-// This function will do some additional PE Checks to make sure everything looks good.
-// We must do these before we run any managed code (that's why we can't do them in PEVerifier, as
-// managed code is used to determine the policy settings)
-HRESULT DoAdditionalPEChecks(HINSTANCE hInst)
-{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_TRIGGERS;
-
- struct Param
- {
- HINSTANCE hInst;
- HRESULT hr;
- } param;
- param.hInst = hInst;
- param.hr = S_OK;
-
- PAL_TRY(Param *, pParam, &param)
- {
- PEDecoder pe(pParam->hInst);
-
- if (!pe.CheckWillCreateGuardPage())
- pParam->hr = COR_E_BADIMAGEFORMAT;
- }
- PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- }
- PAL_ENDTRY
-
- return param.hr;
-}
-
-//*****************************************************************************
-// This entry point is called from the native entry point of the loaded
-// executable image. This simply calls into _CorExeMainInternal, the real
-// entry point inside a filter to trigger unhandled exception processing in the
-// event an exception goes unhandled, independent of the OS UEF mechanism.
-//*****************************************************************************
-__int32 STDMETHODCALLTYPE _CorExeMain( // Executable exit code.
- )
-{
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_THROWS;
-
- // We really have nothing to share with our filter at this point.
- struct Param
- {
- PVOID pData;
- } param;
- param.pData = NULL;
-
- PAL_TRY(Param*, _pParam, &param)
- {
- // Call the real function that will invoke the managed entry point
- _CorExeMainInternal();
- }
- PAL_EXCEPT_FILTER(EntryPointFilter)
- {
- LOG((LF_STARTUP, LL_INFO10, "EntryPointFilter returned EXCEPTION_EXECUTE_HANDLER!"));
- }
- PAL_ENDTRY;
-
- return 0;
-}
-
-//*****************************************************************************
-// This entry point is called from _CorExeMain. If an exception goes unhandled
-// from here, we will trigger unhandled exception processing in _CorExeMain.
-//
-// The command line arguments and other entry point data
-// will be gathered here. The entry point for the user image will be found
-// and handled accordingly.
-//*****************************************************************************
-__int32 STDMETHODCALLTYPE _CorExeMainInternal( // Executable exit code.
- )
-{
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_ENTRY_POINT;
-
- // Yes, CorExeMain needs throws. If an exception passes through here, it will cause the
- // "The application has generated an unhandled exception" dialog and offer to debug.
-
- BEGIN_ENTRYPOINT_THROWS;
-
- // Make sure PE file looks ok
- HRESULT hr;
- {
- // We are early in the process, if we get an SO here we will just rip
- CONTRACT_VIOLATION(SOToleranceViolation);
- if (FAILED(hr = DoAdditionalPEChecks(WszGetModuleHandle(NULL))))
- {
- GCX_PREEMP();
- VMDumpCOMErrors(hr);
- SetLatchedExitCode (-1);
- goto exit;
- }
- }
-
- g_fEEManagedEXEStartup = TRUE;
- // Before we initialize the EE, make sure we've snooped for all EE-specific
- // command line arguments that might guide our startup.
- WCHAR *pCmdLine = WszGetCommandLine();
- HRESULT result = CorCommandLine::SetArgvW(pCmdLine);
-
- if (SUCCEEDED(result))
- {
- g_fWeOwnProcess = TRUE;
- result = EnsureEEStarted(COINITEE_MAIN);
- }
-
- if (FAILED(result))
- {
- g_fWeOwnProcess = FALSE;
- GCX_PREEMP();
- VMDumpCOMErrors(result);
- SetLatchedExitCode (-1);
- goto exit;
- }
-
- INSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
- // This will be called from a EXE so this is a self referential file so I am going to call
- // ExecuteEXE which will do the work to make a EXE load.
-
- BOOL bretval = 0;
-
- bretval = ExecuteEXE(WszGetModuleHandle(NULL));
- if (!bretval) {
- // The only reason I've seen this type of error in the wild is bad
- // metadata file format versions and inadequate error handling for
- // partially signed assemblies. While this may happen during
- // development, our customers should not get here. This is a back-stop
- // to catch CLR bugs. If you see this, please try to find a better way
- // to handle your error, like throwing an unhandled exception.
- EEMessageBoxCatastrophic(IDS_EE_COREXEMAIN_FAILED_TEXT, IDS_EE_COREXEMAIN_FAILED_TITLE);
- SetLatchedExitCode (-1);
- }
-
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
-exit:
- STRESS_LOG1(LF_STARTUP, LL_ALWAYS, "Program exiting: return code = %d", GetLatchedExitCode());
-
- STRESS_LOG0(LF_STARTUP, LL_INFO10, "EEShutDown invoked from _CorExeMainInternal");
-
- EEPolicy::HandleExitProcess();
-
- END_ENTRYPOINT_THROWS;
-
- return 0;
-}
-
-
-static BOOL CacheCommandLine(__in LPWSTR pCmdLine, __in_opt LPWSTR* ArgvW)
-{
- CONTRACTL {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pCmdLine));
- PRECONDITION(CheckPointer(ArgvW));
- } CONTRACTL_END;
-
- if (pCmdLine) {
- size_t len = wcslen(pCmdLine);
-
- _ASSERT(g_pCachedCommandLine== NULL);
- g_pCachedCommandLine = new WCHAR[len+1];
- wcscpy_s(g_pCachedCommandLine, len+1, pCmdLine);
- }
-
- if (ArgvW != NULL && ArgvW[0] != NULL) {
- PathString wszModuleName;
- PathString wszCurDir;
- if (!WszGetCurrentDirectory(wszCurDir))
- return FALSE;
-
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:25025)
-#endif
-
- // usage of PathCombine is safe if we ensure that buffer specified by
- // parameter1 can accomodate buffers specified by paramater2, parameter3
- // and one path separator
- COUNT_T wszModuleName_len = wszCurDir.GetCount() + lstrlenW(ArgvW[0]);
- WCHAR* wszModuleName_buf = wszModuleName.OpenUnicodeBuffer(wszModuleName_len);
-
- if (PathCombine(wszModuleName_buf, wszCurDir, ArgvW[0]) == NULL)
- return FALSE;
- wszModuleName.CloseBuffer();
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
- size_t len = wszModuleName.GetCount();
- _ASSERT(g_pCachedModuleFileName== NULL);
- g_pCachedModuleFileName = new WCHAR[len+1];
- wcscpy_s(g_pCachedModuleFileName, len+1, wszModuleName);
- }
-
- return TRUE;
-}
-
-//*****************************************************************************
-// This entry point is called from the native entry point of the loaded
-// executable image. The command line arguments and other entry point data
-// will be gathered here. The entry point for the user image will be found
-// and handled accordingly.
-//*****************************************************************************
-__int32 STDMETHODCALLTYPE _CorExeMain2( // Executable exit code.
- PBYTE pUnmappedPE, // -> memory mapped code
- DWORD cUnmappedPE, // Size of memory mapped code
- __in LPWSTR pImageNameIn, // -> Executable Name
- __in LPWSTR pLoadersFileName, // -> Loaders Name
- __in LPWSTR pCmdLine) // -> Command Line
-{
-
- // This entry point is used by clix
- BOOL bRetVal = 0;
-
- BEGIN_ENTRYPOINT_VOIDRET;
- {
- // Before we initialize the EE, make sure we've snooped for all EE-specific
- // command line arguments that might guide our startup.
- HRESULT result = CorCommandLine::SetArgvW(pCmdLine);
-
- if (!CacheCommandLine(pCmdLine, CorCommandLine::GetArgvW(NULL))) {
- LOG((LF_STARTUP, LL_INFO10, "Program exiting - CacheCommandLine failed\n"));
- bRetVal = -1;
- goto exit;
- }
-
- if (SUCCEEDED(result))
- result = InitializeEE(COINITEE_MAIN);
-
- if (FAILED(result)) {
- VMDumpCOMErrors(result);
- SetLatchedExitCode (-1);
- goto exit;
- }
-
- // Load the executable
- bRetVal = ExecuteEXE(pImageNameIn);
-
- if (!bRetVal) {
- // The only reason I've seen this type of error in the wild is bad
- // metadata file format versions and inadequate error handling for
- // partially signed assemblies. While this may happen during
- // development, our customers should not get here. This is a back-stop
- // to catch CLR bugs. If you see this, please try to find a better way
- // to handle your error, like throwing an unhandled exception.
- EEMessageBoxCatastrophic(IDS_EE_COREXEMAIN2_FAILED_TEXT, IDS_EE_COREXEMAIN2_FAILED_TITLE);
- SetLatchedExitCode (-1);
- }
-
-exit:
- STRESS_LOG1(LF_STARTUP, LL_ALWAYS, "Program exiting: return code = %d", GetLatchedExitCode());
-
- STRESS_LOG0(LF_STARTUP, LL_INFO10, "EEShutDown invoked from _CorExeMain2");
-
- EEPolicy::HandleExitProcess();
- }
- END_ENTRYPOINT_VOIDRET;
-
- return bRetVal;
-}
-
-//*****************************************************************************
-// This is the call point to wire up an EXE. In this case we have the HMODULE
-// and just need to make sure we do to correct self referantial things.
-//*****************************************************************************
-
-
-BOOL STDMETHODCALLTYPE ExecuteEXE(HMODULE hMod)
-{
- STATIC_CONTRACT_GC_TRIGGERS;
-
- _ASSERTE(hMod);
- if (!hMod)
- return FALSE;
-
- ETWFireEvent(ExecExe_V1);
-
- struct Param
- {
- HMODULE hMod;
- } param;
- param.hMod = hMod;
-
- EX_TRY_NOCATCH(Param *, pParam, &param)
- {
- // Executables are part of the system domain
- SystemDomain::ExecuteMainMethod(pParam->hMod);
- }
- EX_END_NOCATCH;
-
- ETWFireEvent(ExecExeEnd_V1);
-
- return TRUE;
-}
-
-BOOL STDMETHODCALLTYPE ExecuteEXE(__in LPWSTR pImageNameIn)
-{
- STATIC_CONTRACT_GC_TRIGGERS;
-
- EX_TRY_NOCATCH(LPWSTR, pImageNameInner, pImageNameIn)
- {
- WCHAR wzPath[MAX_LONGPATH];
- DWORD dwPathLength = 0;
-
- // get the path of executable
- dwPathLength = WszGetFullPathName(pImageNameInner, MAX_LONGPATH, wzPath, NULL);
-
- if (!dwPathLength || dwPathLength > MAX_LONGPATH)
- {
- ThrowWin32( !dwPathLength ? GetLastError() : ERROR_FILENAME_EXCED_RANGE);
- }
-
- SystemDomain::ExecuteMainMethod( NULL, (WCHAR *)wzPath );
- }
- EX_END_NOCATCH;
-
- return TRUE;
-}
-#endif // FEATURE_CORECLR
-
-#ifdef FEATURE_MIXEDMODE
-
-LONG RunDllMainFilter(EXCEPTION_POINTERS* ep, LPVOID pv)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- BOOL useLastThrownObject = UpdateCurrentThrowable(ep->ExceptionRecord);
- DefaultCatchHandler(ep, NULL, useLastThrownObject, FALSE);
-
- DefaultCatchFilterParam param(COMPLUS_EXCEPTION_EXECUTE_HANDLER);
- return DefaultCatchFilter(ep, &param);
-}
-
-// <TODO>@Todo: For M10, this only runs unmanaged native classic entry points for
-// the IJW mc++ case.</TODO>
-HRESULT RunDllMain(MethodDesc *pMD, HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved)
-{
- STATIC_CONTRACT_NOTHROW;
-
- _ASSERTE(!GetAppDomain()->IsPassiveDomain());
-
- if (!pMD) {
- _ASSERTE(!"Must have a valid function to call!");
- return E_INVALIDARG;
- }
-
- if (pMD->IsIntrospectionOnly())
- return S_OK;
-
- struct Param
- {
- MethodDesc *pMD;
- HINSTANCE hInst;
- DWORD dwReason;
- LPVOID lpReserved;
- HRESULT hr;
- }; Param param;
- param.pMD = pMD;
- param.hInst = hInst;
- param.dwReason = dwReason;
- param.lpReserved = lpReserved;
- param.hr = S_OK;
-
- PAL_TRY(Param *, pParamOuter, &param)
- {
- EX_TRY_NOCATCH(Param *, pParam, pParamOuter)
- {
- HRESULT hr;
-
- // This call is inherently unverifiable entry point.
- if (!Security::CanSkipVerification(pParam->pMD)) {
- hr = SECURITY_E_UNVERIFIABLE;
- goto Done;
- }
-
- {
- SigPointer sig(pParam->pMD->GetSigPointer());
-
- ULONG data = 0;
- CorElementType eType = ELEMENT_TYPE_END;
- CorElementType eType2 = ELEMENT_TYPE_END;
-
- IfFailGoto(sig.GetData(&data), Done);
- if (data != IMAGE_CEE_CS_CALLCONV_DEFAULT) {
- hr = COR_E_METHODACCESS;
- goto Done;
- }
-
- IfFailGoto(sig.GetData(&data), Done);
- if (data != 3) {
- hr = COR_E_METHODACCESS;
- goto Done;
- }
-
- IfFailGoto(sig.GetElemType(&eType), Done);
- if (eType != ELEMENT_TYPE_I4) { // return type = int32
- hr = COR_E_METHODACCESS;
- goto Done;
- }
-
- IfFailGoto(sig.GetElemType(&eType), Done);
- if (eType == ELEMENT_TYPE_PTR)
- IfFailGoto(sig.GetElemType(&eType2), Done);
-
- if (eType!= ELEMENT_TYPE_PTR || eType2 != ELEMENT_TYPE_VOID) { // arg1 = void*
- hr = COR_E_METHODACCESS;
- goto Done;
- }
-
- IfFailGoto(sig.GetElemType(&eType), Done);
- if (eType != ELEMENT_TYPE_U4) { // arg2 = uint32
- hr = COR_E_METHODACCESS;
- goto Done;
- }
-
- IfFailGoto(sig.GetElemType(&eType), Done);
- if (eType == ELEMENT_TYPE_PTR)
- IfFailGoto(sig.GetElemType(&eType2), Done);
-
- if (eType != ELEMENT_TYPE_PTR || eType2 != ELEMENT_TYPE_VOID) { // arg3 = void*
- hr = COR_E_METHODACCESS;
- goto Done;
- }
- }
-
- {
- MethodDescCallSite dllMain(pParam->pMD);
-
- // Set up a callstack with the values from the OS in the argument array
- ARG_SLOT stackVar[3];
- stackVar[0] = PtrToArgSlot(pParam->hInst);
- stackVar[1] = (ARG_SLOT) pParam->dwReason;
- stackVar[2] = PtrToArgSlot(pParam->lpReserved);
-
- // Call the method in question with the arguments.
- if((dllMain.Call_RetI4(&stackVar[0]) == 0)
- &&(pParam->dwReason==DLL_PROCESS_ATTACH)
- && (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_IgnoreDllMainReturn) != 1))
- {
- hr = COR_E_INVALIDPROGRAM;
-#ifdef MDA_SUPPORTED
- MdaDllMainReturnsFalse* pProbe = MDA_GET_ASSISTANT(DllMainReturnsFalse);
- if(pProbe != NULL) pProbe->ReportError();
-#endif
- }
- }
-Done:
- pParam->hr = hr;
- }
- EX_END_NOCATCH
- }
- //@TODO: Revisit why this is here, and if it's still necessary.
- PAL_EXCEPT_FILTER(RunDllMainFilter)
- {
- // switch to COOPERATIVE
- GCX_COOP_NO_DTOR();
- // don't do anything - just want to catch it
- }
- PAL_ENDTRY
-
- return param.hr;
-}
-
-//*****************************************************************************
-// fFromThunk indicates that a dependency is calling through the Import Export table,
-// and calling indirect through the IJW vtfixup slot.
-//
-// fFromThunk=FALSE means that we are running DllMain during LoadLibrary while
-// holding the loader lock.
-//
-HRESULT ExecuteDLLForAttach(HINSTANCE hInst,
- DWORD dwReason,
- LPVOID lpReserved,
- BOOL fFromThunk)
-{
- CONTRACTL{
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(lpReserved, NULL_OK));
- } CONTRACTL_END;
-
- PEDecoder pe(hInst);
-
- // Note that ILOnly DLLs can have a managed entry point. This will
- // be called when the assembly is activated by the CLR loader,
- // and it need not be run here.
-
- if (pe.IsILOnly())
- {
- _ASSERTE(!fFromThunk);
- return S_OK;
- }
-
- if (!pe.HasManagedEntryPoint() && !fFromThunk)
- return S_OK;
-
- // We need to prep the managed assembly for execution.
-
- AppDomain *pDomain = GetAppDomain();
-
- // First we must find the DomainFile associated with this HMODULE. There are basically 3
- // interesting cases:
- //
- // 1. The file is being loaded. In this case we have a DomainFile in existence but
- // (very inconveniently) it does not have its HMODULE set yet. Most likely if we
- // were to look at the state of this thread up the stack, we'd see that file is
- // currently being loaded right above us. However, we cannot rely on this because
- // A. We may be in case 2 (e.g. a static DLL dependency is being loaded first)
- // B. _CorDllMain may have been called on a different thread.
- //
- // 2. The file has never been seen before. In this case we are basically in the dark; we
- // simply attempt to load the file as an assembly. (If it is not an assembly we will
- // fail.)
- //
- // 3. The file has been loaded but we are getting called anyway in a race. (This should not
- // happen in the loader lock case, only when we are getting called from thunks).
- //
- // So, we:
- // A. Use the current thread's LoadingFile as a hint. We will rely on this only if it has
- // the same path as the HMOD.
- // B. Search the app domain for a DomainFile with a matching base address, or failing that, path.
- // C. We have no information, so assume it is a new assembly being loaded.
-
- // A: check the loading file
-
- StackSString path;
- PEImage::GetPathFromDll(hInst, path);
-
- DomainFile *pLoadingFile = GetThread()->GetLoadingFile();
- GetThread()->ClearLoadingFile();
-
- if (pLoadingFile != NULL)
- {
- if (!PEImage::PathEquals(pLoadingFile->GetFile()->GetPath(), path))
- {
- pLoadingFile = NULL;
- }
- else
- {
- pLoadingFile->GetFile()->SetLoadedHMODULE(hInst);
- }
- }
-
- // B: look for a loading IJW module
-
- if (pLoadingFile == NULL)
- {
- pLoadingFile = pDomain->FindIJWDomainFile(hInst, path);
- }
-
- // C: nothing else worked, we require it is an assembly with a manifest in this situation
- if (pLoadingFile == NULL)
- {
- pLoadingFile = pDomain->LoadExplicitAssembly(hInst, FALSE)->GetDomainAssembly();
- }
-
- // There are two cases here, loading from thunks emitted from the shim, and being called
- // inside the loader lock for the legacy IJW dll case.
-
- if (fFromThunk)
- {
- pLoadingFile->EnsureActive();
- return S_OK;
- }
-
- _ASSERTE(!pe.IsILOnly() && pe.HasManagedEntryPoint());
- // Get the entry point for the IJW module
- Module *pModule = pLoadingFile->GetCurrentModule();
- mdMethodDef tkEntry = pModule->GetEntryPointToken();
-
- BOOL hasEntryPoint = (TypeFromToken(tkEntry) == mdtMethodDef &&
- !IsNilToken(tkEntry));
-
- if (!hasEntryPoint)
- {
- return S_OK;
- }
-
- if (pDomain->IsPassiveDomain())
- {
- // Running managed code while holding the loader lock can cause deadlocks.
- // These deadlocks might happen when this assembly gets executed. However,
- // we should avoid those deadlocks if we are in a passive AppDomain.
- // Also, managed entry point is now legacy, and has should be replaced
- // with Module .cctor.
- //
- // We also rely on Module::CanExecuteCode() to prevent
- // any further code from being executed from this assembly.
- _ASSERTE(pLoadingFile && pLoadingFile->GetFile() && pLoadingFile->GetFile()->GetILimage());
- pLoadingFile->GetFile()->GetILimage()->SetPassiveDomainOnly();
- return S_OK;
- }
-
- // We're actually going to run some managed code and we're inside the loader lock.
- // There may be a customer debug probe enabled that prevents this.
- CanRunManagedCode(hInst);
-
- // If we are not being called from thunks, we are inside the loader lock
- // & have this single opportunity to run our dll main.
- // Since we are in deadlock danger anyway (note this is the problematic legacy
- // case only!) we disable our file loading and type loading reentrancy protection & allow
- // loads to fully proceed.
-
- // class level override is needed for the entire operation, not just EnsureActive
- OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED);
-
- {
- OVERRIDE_LOAD_LEVEL_LIMIT(FILE_ACTIVE);
-
- // Complete the load as necessary
- pLoadingFile->EnsureActive();
- }
-
- MethodDesc *pMD = pModule->FindMethodThrowing(tkEntry);
- CONSISTENCY_CHECK(CheckPointer(pMD));
-
- pModule->SetDllEntryPoint(pMD);
-
- GCX_COOP();
-
- // pModule may be for a different domain.
- PEFile *pPEFile = pMD->GetModule()->GetFile();
- if (!pPEFile->CheckLoaded())
- {
- pPEFile->SetLoadedHMODULE(hInst);
- }
-
- // Call the managed entry point
- HRESULT hr = RunDllMain(pMD, hInst, dwReason, lpReserved);
-
- return hr;
-}
-
-#endif // FEATURE_MIXEDMODE
-
//*****************************************************************************
BOOL ExecuteDLL_ReturnOrThrow(HRESULT hr, BOOL fFromThunk)
{
@@ -3449,252 +2449,6 @@ BOOL ExecuteDLL_ReturnOrThrow(HRESULT hr, BOOL fFromThunk)
return SUCCEEDED(hr);
}
-#if !defined(FEATURE_CORECLR) && defined(_DEBUG)
-//*****************************************************************************
-// Factor some common debug code.
-//*****************************************************************************
-static void EnsureManagedThreadExistsForHostedThread()
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- if (CLRTaskHosted()) {
- // If CLR is hosted, and this is on a thread that a host controls,
- // we must have created Thread object.
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTask *pHostTask = GetCurrentHostTask();
- if (pHostTask)
- {
- CONSISTENCY_CHECK(CheckPointer(GetThread()));
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- }
-}
-#endif // !FEATURE_CORECLR && _DEBUG
-
-#ifdef FEATURE_MIXEDMODE
-//*****************************************************************************
-// This ensure that the runtime is started and an EEThread object is created
-// for the current thread. This functionality is duplicated in ExecuteDLL,
-// except that this code will not throw.
-//*****************************************************************************
-HRESULT PrepareExecuteDLLForThunk(HINSTANCE hInst,
- DWORD dwReason,
- LPVOID lpReserved)
-{
- CONTRACTL {
- NOTHROW;
- WRAPPER(GC_TRIGGERS);
- MODE_ANY;
- PRECONDITION(CheckPointer(lpReserved, NULL_OK));
- PRECONDITION(CheckPointer(hInst));
- } CONTRACTL_END;
-
-
- HRESULT hr = S_OK;
- Thread *pThread = GetThread();
-
- INDEBUG(EnsureManagedThreadExistsForHostedThread();)
-
- if (pThread == NULL)
- {
- // If necessary, start the runtime and create a managed thread object.
- hr = EnsureEEStarted(COINITEE_DLL);
- if (FAILED(hr))
- {
- return hr;
- }
- if ((pThread = SetupThreadNoThrow(&hr)) == NULL)
- {
- return hr;
- }
- }
-
- CONSISTENCY_CHECK(CheckPointer(pThread));
-
- return S_OK;
-}
-
-#endif // FEATURE_MIXEDMODE
-
-#ifndef FEATURE_CORECLR
-//*****************************************************************************
-// This is the call point to make a DLL that is already loaded into our address
-// space run. There will be other code to actually have us load a DLL due to a
-// class reference.
-//*****************************************************************************
-BOOL STDMETHODCALLTYPE ExecuteDLL(HINSTANCE hInst,
- DWORD dwReason,
- LPVOID lpReserved,
- BOOL fFromThunk)
-{
-
- CONTRACTL{
- THROWS;
- WRAPPER(GC_TRIGGERS);
- MODE_ANY;
- ENTRY_POINT;
- PRECONDITION(CheckPointer(lpReserved, NULL_OK));
- PRECONDITION(CheckPointer(hInst));
- PRECONDITION(GetThread() != NULL || !fFromThunk);
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BOOL fRetValue = FALSE;
-
- // This needs to be before the BEGIN_ENTRYPOINT_THROWS since
- // we can't call ReportStackOverflow if we're almost done with
- // shutdown and can't run managed code.
- if (!CanRunManagedCode(LoaderLockCheck::None))
- {
- return fRetValue;
- }
-
- BEGIN_ENTRYPOINT_THROWS;
-
- Thread *pThread = GetThread();
-
- if (!hInst)
- {
- fRetValue = ExecuteDLL_ReturnOrThrow(E_FAIL, fFromThunk);
- goto Exit;
- }
-
- // Note that we always check fFromThunk before checking the dwReason value.
- // This is because the dwReason value is undefined in the case that we're
- // being invoked due to a bootstrap (because that is by definition outside
- // of the loader lock and there is no appropriate dwReason value).
- if (fFromThunk ||
- dwReason == DLL_PROCESS_ATTACH ||
- dwReason == DLL_THREAD_ATTACH)
- {
- INDEBUG(EnsureManagedThreadExistsForHostedThread();)
-
-
- // If necessary, start the runtime and create a managed thread object.
- if (fFromThunk || dwReason == DLL_PROCESS_ATTACH)
- {
- hr = EnsureEEStarted(COINITEE_DLL);
-
- if (SUCCEEDED(hr) && pThread == NULL)
- {
- pThread = SetupThreadNoThrow(&hr);
- }
-
- if(FAILED(hr))
- {
- fRetValue = ExecuteDLL_ReturnOrThrow(hr, fFromThunk);
- goto Exit;
- }
- }
-
- // IJW assemblies cause the thread doing the process attach to
- // re-enter ExecuteDLL and do a thread attach. This happens when
- // CoInitializeEE() above executed
- else if (!(pThread &&
- pThread->GetDomain() &&
- CanRunManagedCode(LoaderLockCheck::None)))
- {
- fRetValue = ExecuteDLL_ReturnOrThrow(S_OK, fFromThunk);
- goto Exit;
- }
-
- // we now have a thread setup - either the 1st if set it up, or
- // the else if ran if we didn't have a thread setup.
-
-#ifdef FEATURE_MIXEDMODE
-
- EX_TRY
- {
- hr = ExecuteDLLForAttach(hInst, dwReason, lpReserved, fFromThunk);
- }
- EX_CATCH
- {
- // We rethrow directly here instead of using ExecuteDLL_ReturnOrThrow() to
- // preserve the full exception information, rather than just the HRESULT
- if (fFromThunk)
- {
- EX_RETHROW;
- }
- else
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- if (FAILED(hr))
- {
- fRetValue = ExecuteDLL_ReturnOrThrow(hr, fFromThunk);
- goto Exit;
- }
-#endif // FEATURE_MIXEDMODE
- }
- else
- {
- PEDecoder pe(hInst);
- if (pe.HasManagedEntryPoint())
- {
- // If the EE is still intact, then run user entry points. Otherwise
- // detach was handled when the app domain was stopped.
- //
- // Checks for the loader lock will occur within RunDllMain, if that's
- FAULT_NOT_FATAL();
- if (CanRunManagedCode(LoaderLockCheck::None))
- {
- hr = SystemDomain::RunDllMain(hInst, dwReason, lpReserved);
- }
- }
- // This does need to match the attach. We will only unload dll's
- // at the end and CoUninitialize will just bounce at 0. WHEN and IF we
- // get around to unloading IL DLL's during execution prior to
- // shutdown we will need to bump the reference one to compensate
- // for this call.
- if (dwReason == DLL_PROCESS_DETACH && !g_fForbidEnterEE)
- {
-#ifdef FEATURE_MIXEDMODE
- // If we're in a decent state, we need to free the memory associated
- // with the IJW thunk fixups.
- // we are not in a decent state if the process is terminating (lpReserved!=NULL)
- if (g_fEEStarted && !g_fEEShutDown && !lpReserved)
- {
- PEImage::UnloadIJWModule(hInst);
- }
-#endif // FEATURE_MIXEDMODE
- }
- }
-
- fRetValue = ExecuteDLL_ReturnOrThrow(hr, fFromThunk);
-
-Exit:
-
- END_ENTRYPOINT_THROWS;
- return fRetValue;
-}
-#endif // !FEATURE_CORECLR
-
-
-Volatile<BOOL> g_bIsGarbageCollectorFullyInitialized = FALSE;
-
-void SetGarbageCollectorFullyInitialized()
-{
- LIMITED_METHOD_CONTRACT;
-
- g_bIsGarbageCollectorFullyInitialized = TRUE;
-}
-
-// Tells whether the garbage collector is fully initialized
-// Stronger than IsGCHeapInitialized
-BOOL IsGarbageCollectorFullyInitialized()
-{
- LIMITED_METHOD_CONTRACT;
-
- return g_bIsGarbageCollectorFullyInitialized;
-}
-
//
// Initialize the Garbage Collector
//
@@ -3729,19 +2483,24 @@ void InitializeGarbageCollector()
IGCToCLR* gcToClr = nullptr;
#endif
- IGCHeap *pGCHeap = InitializeGarbageCollector(gcToClr);
- g_pGCHeap = pGCHeap;
- if (!pGCHeap)
- ThrowOutOfMemory();
+ IGCHandleTable *pGcHandleTable;
- hr = pGCHeap->Initialize();
- IfFailThrow(hr);
+ IGCHeap *pGCHeap;
+ if (!InitializeGarbageCollector(gcToClr, &pGCHeap, &pGcHandleTable, &g_gc_dac_vars))
+ {
+ ThrowOutOfMemory();
+ }
- // Thread for running finalizers...
- FinalizerThread::FinalizerThreadCreate();
+ assert(pGCHeap != nullptr);
+ g_pGCHeap = pGCHeap;
+ g_pGCHandleTable = pGcHandleTable;
+ g_gcDacGlobals = &g_gc_dac_vars;
- // Now we really have fully initialized the garbage collector
- SetGarbageCollectorFullyInitialized();
+ // Apparently the Windows linker removes global variables if they are never
+ // read from, which is a problem for g_gcDacGlobals since it's expected that
+ // only the DAC will read from it. This forces the linker to include
+ // g_gcDacGlobals.
+ volatile void* _dummy = g_gcDacGlobals;
}
/*****************************************************************************/
@@ -3803,15 +2562,6 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
// Remember module instance
g_pMSCorEE = pParam->hInst;
-#ifndef FEATURE_CORECLR
- CoreClrCallbacks cccallbacks;
- cccallbacks.m_hmodCoreCLR = (HINSTANCE)g_pMSCorEE;
- cccallbacks.m_pfnIEE = IEE;
- cccallbacks.m_pfnGetCORSystemDirectory = GetCORSystemDirectoryInternaL;
- cccallbacks.m_pfnGetCLRFunction = GetCLRFunction;
-
- InitUtilcode(cccallbacks);
-#endif // !FEATURE_CORECLR
// Set callbacks so that LoadStringRC knows which language our
// threads are in so that it can return the proper localized string.
@@ -3920,139 +2670,11 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
if (dwReason == DLL_THREAD_DETACH || dwReason == DLL_PROCESS_DETACH)
{
- if (CLRMemoryHosted())
- {
- // A host may not support memory operation inside OS loader lock.
- // We will free these memory on finalizer thread.
- CExecutionEngine::DetachTlsInfo(param.pTlsData);
- }
- else
- {
- CExecutionEngine::ThreadDetaching(param.pTlsData);
- }
+ CExecutionEngine::ThreadDetaching(param.pTlsData);
}
return TRUE;
}
-#ifdef FEATURE_COMINTEROP_REGISTRATION
-//*****************************************************************************
-// Helper function to call the managed registration services.
-//*****************************************************************************
-enum EnumRegServicesMethods
-{
- RegServicesMethods_RegisterAssembly = 0,
- RegServicesMethods_UnregisterAssembly,
- RegServicesMethods_LastMember
-};
-
-void InvokeRegServicesMethod(EnumRegServicesMethods Method, HMODULE hMod)
-{
- CONTRACT_VOID
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(Method == RegServicesMethods_RegisterAssembly ||
- Method == RegServicesMethods_UnregisterAssembly);
- }
- CONTRACT_END;
-
- GCX_PREEMP();
- Assembly *pAssembly = GetAppDomain()->LoadExplicitAssembly(hMod, TRUE);
-
- {
- GCX_COOP();
-
- // The names of the RegistrationServices methods.
- static const BinderMethodID aMethods[] =
- {
- METHOD__REGISTRATION_SERVICES__REGISTER_ASSEMBLY,
- METHOD__REGISTRATION_SERVICES__UNREGISTER_ASSEMBLY
- };
-
- // Allocate the RegistrationServices object.
- OBJECTREF RegServicesObj = AllocateObject(MscorlibBinder::GetClass(CLASS__REGISTRATION_SERVICES));
- GCPROTECT_BEGIN(RegServicesObj)
- {
- MethodDescCallSite registrationMethod(aMethods[Method], &RegServicesObj);
-
- ARG_SLOT Args[] =
- {
- ObjToArgSlot(RegServicesObj),
- ObjToArgSlot(pAssembly->GetExposedObject()),
- 0 // unused by UnregisterAssembly
- };
-
- registrationMethod.Call(Args);
- }
- GCPROTECT_END();
- }
- RETURN;
-}
-
-//*****************************************************************************
-// This entry point is called to register the classes contained inside a
-// COM+ assembly.
-//*****************************************************************************
-STDAPI EEDllRegisterServer(HMODULE hMod)
-{
-
- CONTRACTL{
- NOTHROW;
- GC_TRIGGERS;
- ENTRY_POINT;
- MODE_PREEMPTIVE;
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // Start up the runtime since we are going to use managed code to actually
- // do the registration.
- IfFailGo(EnsureEEStarted(COINITEE_DEFAULT));
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
- {
- InvokeRegServicesMethod(RegServicesMethods_RegisterAssembly, hMod);
- }
- END_EXTERNAL_ENTRYPOINT;
-
-ErrExit:
-
-
- return hr;
-}
-
-//*****************************************************************************
-// This entry point is called to unregister the classes contained inside a
-// COM+ assembly.
-//*****************************************************************************
-STDAPI EEDllUnregisterServer(HMODULE hMod)
-{
-
- CONTRACTL{
- NOTHROW;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // Start up the runtime since we are going to use managed code to actually
- // do the registration.
- IfFailGo(EnsureEEStarted(COINITEE_DEFAULT));
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
- {
- InvokeRegServicesMethod(RegServicesMethods_UnregisterAssembly, hMod);
- }
- END_EXTERNAL_ENTRYPOINT;
-ErrExit:
-
-
- return hr;
-}
-#endif // FEATURE_COMINTEROP_REGISTRATION
#ifdef FEATURE_IPCMAN
extern CCLRSecurityAttributeManager s_CLRSecurityAttributeManager;
@@ -4124,7 +2746,6 @@ static void InitializeDebugger(void)
hr = g_pDebugInterface->Startup(); // throw on error
_ASSERTE(SUCCEEDED(hr));
-#ifdef FEATURE_CORECLR
//
// If the debug pack is not installed, Startup will return S_FALSE
// and we should cleanup and proceed without debugging support.
@@ -4133,31 +2754,8 @@ static void InitializeDebugger(void)
{
return;
}
-#endif // FEATURE_CORECLR
- }
-
-#if !defined(FEATURE_CORECLR) // simple hosting
- // If there's a DebuggerThreadControl interface, then we
- // need to update the DebuggerSpecialThread list.
- if (CorHost::GetDebuggerThreadControl())
- {
- hr = CorHost::RefreshDebuggerSpecialThreadList();
- _ASSERTE((SUCCEEDED(hr)) && (hr != S_FALSE));
-
- // So we don't think this will ever fail, but just in case...
- IfFailThrow(hr);
}
- // If there is a DebuggerThreadControl interface, then it was set before the debugger
- // was initialized and we need to provide this interface now. If debugging is already
- // initialized then the IDTC pointer is passed in when it is set through CorHost
- IDebuggerThreadControl *pDTC = CorHost::GetDebuggerThreadControl();
-
- if (pDTC != NULL)
- {
- g_pDebugInterface->SetIDbgThreadControl(pDTC);
- }
-#endif // !defined(FEATURE_CORECLR)
LOG((LF_CORDB, LL_INFO10, "Left-side debugging services setup.\n"));
@@ -4198,9 +2796,6 @@ static void TerminateDebugger(void)
g_CORDebuggerControlFlags = DBCF_NORMAL_OPERATION;
-#if !defined(FEATURE_CORECLR) // simple hosting
- CorHost::CleanupDebuggerThreadControl();
-#endif // !defined(FEATURE_CORECLR)
}
@@ -4825,247 +3420,4 @@ void ContractRegressionCheck()
#endif // ENABLE_CONTRACTS_IMPL
-#ifndef FEATURE_CORECLR
-//-------------------------------------------------------------------------
-// CorCommandLine state and methods
-//-------------------------------------------------------------------------
-// Class to encapsulate Cor Command line processing
-
-// Statics for the CorCommandLine class
-DWORD CorCommandLine::m_NumArgs = 0;
-LPWSTR *CorCommandLine::m_ArgvW = 0;
-
-LPWSTR CorCommandLine::m_pwszAppFullName = NULL;
-DWORD CorCommandLine::m_dwManifestPaths = 0;
-LPWSTR *CorCommandLine::m_ppwszManifestPaths = NULL;
-DWORD CorCommandLine::m_dwActivationData = 0;
-LPWSTR *CorCommandLine::m_ppwszActivationData = NULL;
-
-#ifdef _DEBUG
-LPCWSTR g_CommandLine;
-#endif
-
-// Set argvw from command line
-/* static */
-HRESULT CorCommandLine::SetArgvW(LPCWSTR lpCommandLine)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(return E_OUTOFMEMORY;);
-
- PRECONDITION(CheckPointer(lpCommandLine));
- }
- CONTRACTL_END
-
- HRESULT hr = S_OK;
- if(!m_ArgvW) {
- INDEBUG(g_CommandLine = lpCommandLine);
-
- InitializeLogging(); // This is so early, we may not be initialized
- LOG((LF_ALWAYS, LL_INFO10, "Executing program with command line '%S'\n", lpCommandLine));
-
- m_ArgvW = SegmentCommandLine(lpCommandLine, &m_NumArgs);
-
- if (!m_ArgvW)
- return E_OUTOFMEMORY;
-
- // Click once specific parsing
- hr = ReadClickOnceEnvVariables();
- }
-
- return hr;
-}
-
-// Retrieve the command line
-/* static */
-LPWSTR* CorCommandLine::GetArgvW(DWORD *pNumArgs)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (pNumArgs != 0)
- *pNumArgs = m_NumArgs;
-
- return m_ArgvW;
-}
-
-HRESULT CorCommandLine::ReadClickOnceEnvVariables()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
-
- EX_TRY
- {
- // Find out if this is a ClickOnce application being activated.
- PathString m_pwszAppFullNameHolder;
- DWORD cAppFullName = WszGetEnvironmentVariable(g_pwzClickOnceEnv_FullName, m_pwszAppFullNameHolder);
- if (cAppFullName > 0) {
- // get the application full name.
- m_pwszAppFullName = m_pwszAppFullNameHolder.GetCopyOfUnicodeString();
-
- // reset the variable now that we read it so child processes
- // do not think they are a clickonce app.
- WszSetEnvironmentVariable(g_pwzClickOnceEnv_FullName, NULL);
-
- // see if we have application manifest files.
- DWORD dwManifestPaths = 0;
- while (1) {
- StackSString manifestFile(g_pwzClickOnceEnv_Manifest);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(dwManifestPaths, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- manifestFile.Append(buf);
- SString temp;
- if (WszGetEnvironmentVariable(manifestFile.GetUnicode(), temp) > 0)
- dwManifestPaths++;
- else
- break;
- }
- m_ppwszManifestPaths = new LPWSTR[dwManifestPaths];
- for (DWORD i=0; i<dwManifestPaths; i++) {
- StackSString manifestFile(g_pwzClickOnceEnv_Manifest);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- manifestFile.Append(buf);
- PathString m_ppwszManifestPathsHolder;
- DWORD cManifestPath = WszGetEnvironmentVariable(manifestFile.GetUnicode(), m_ppwszManifestPathsHolder);
- if (cManifestPath > 0) {
-
- m_ppwszManifestPaths[i] = m_ppwszManifestPathsHolder.GetCopyOfUnicodeString();
- WszSetEnvironmentVariable(manifestFile.GetUnicode(), NULL); // reset the env. variable.
- }
- }
- m_dwManifestPaths = dwManifestPaths;
-
- // see if we have activation data arguments.
- DWORD dwActivationData = 0;
- while (1) {
- StackSString activationData(g_pwzClickOnceEnv_Parameter);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(dwActivationData, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- activationData.Append(buf);
- SString temp;
- if (WszGetEnvironmentVariable(activationData.GetUnicode(), temp) > 0)
- dwActivationData++;
- else
- break;
- }
- m_ppwszActivationData = new LPWSTR[dwActivationData];
- for (DWORD i=0; i<dwActivationData; i++) {
- StackSString activationData(g_pwzClickOnceEnv_Parameter);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- activationData.Append(buf);
- PathString m_ppwszActivationDataHolder;
- DWORD cActivationData = WszGetEnvironmentVariable(activationData.GetUnicode(), m_ppwszActivationDataHolder);
- if (cActivationData > 0) {
- m_ppwszActivationData[i] = m_ppwszActivationDataHolder.GetCopyOfUnicodeString();
- WszSetEnvironmentVariable(activationData.GetUnicode(), NULL); // reset the env. variable.
- }
- }
- m_dwActivationData = dwActivationData;
- }
- }
- EX_CATCH_HRESULT(hr);
-
- END_SO_INTOLERANT_CODE;
-
- return hr;
-}
-
-#endif // !FEATURE_CORECLR
-
#endif // CROSSGEN_COMPILE
-
-
-//
-// GetOSVersion - Gets the real OS version bypassing the OS compatibility shim
-// Mscoree.dll resides in System32 dir and is always excluded from compat shim.
-// This function calls mscoree!shim function via mscoreei ICLRRuntimeHostInternal interface
-// to get the OS version. We do not do this PAL or coreclr..we direclty call the OS
-// in that case.
-//
-BOOL GetOSVersion(LPOSVERSIONINFO lposVer)
-{
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
-
- //declared static to cache the version info
- static OSVERSIONINFOEX osvi = {0};
- BOOL ret = TRUE;
-
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), return FALSE);
-
- //If not yet cached get the OS version info
- if(osvi.dwMajorVersion == 0)
- {
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
-
- ReleaseHolder<ICLRRuntimeHostInternal> pRuntimeHostInternal;
- //Get the interface
- HRESULT hr = g_pCLRRuntime->GetInterface(CLSID_CLRRuntimeHostInternal,
- IID_ICLRRuntimeHostInternal,
- &pRuntimeHostInternal);
-
- _ASSERT(SUCCEEDED(hr));
-
- //Call mscoree!GetVersionExWrapper() through mscoreei interface method
- hr = pRuntimeHostInternal->GetTrueOSVersion((LPOSVERSIONINFO)&osvi);
- if(!SUCCEEDED(hr))
- {
- osvi.dwMajorVersion = 0;
- ret = FALSE;
- goto FUNCEND;
- }
- }
-
- if(lposVer->dwOSVersionInfoSize==sizeof(OSVERSIONINFOEX)||lposVer->dwOSVersionInfoSize==sizeof(OSVERSIONINFO))
- {
- //Copy the cached version info to the return memory location
- memcpy(lposVer,&osvi, lposVer->dwOSVersionInfoSize);
- }
- else
- {
- //return failure if dwOSVersionInfoSize not set properly
- ret = FALSE;
- }
-
-FUNCEND:
- END_SO_INTOLERANT_CODE;
-
- return ret;
-#else
-// Fix for warnings when building against WinBlue build 9444.0.130614-1739
-// warning C4996: 'GetVersionExW': was declared deprecated
-// externalapis\windows\winblue\sdk\inc\sysinfoapi.h(442)
-// Deprecated. Use VerifyVersionInfo* or IsWindows* macros from VersionHelpers.
-#pragma warning( disable : 4996 )
- return WszGetVersionEx(lposVer);
-#pragma warning( default : 4996 )
-#endif
-}
diff --git a/src/vm/ceemain.h b/src/vm/ceemain.h
index 37fc3dcddf..ccf763ac80 100644
--- a/src/vm/ceemain.h
+++ b/src/vm/ceemain.h
@@ -88,12 +88,6 @@ public:
static LPVOID* GetTlsData();
static BOOL SetTlsData (void** ppTlsInfo);
- static BOOL HasDetachedTlsInfo();
-
- static void CleanupDetachedTlsInfo();
-
- static void DetachTlsInfo(void **pTlsData);
-
//***************************************************************************
// private implementation:
//***************************************************************************
@@ -210,44 +204,5 @@ INT32 GetLatchedExitCode (void);
// Stronger than IsGCHeapInitialized
BOOL IsGarbageCollectorFullyInitialized();
-#ifndef FEATURE_CORECLR
-//---------------------------------------------------------------------------------------
-//
-// Class to encapsulate Cor Command line processing
-//
-class CorCommandLine
-{
-public:
-
-//********** TYPES
-
- // Note: We don't bother with interlocked operations as we manipulate these bits,
- // because we don't anticipate free-threaded access. (Most of this is used only
- // during startup / shutdown).
-
-//********** DATA
-
- // Hold the current (possibly parsed) command line here
- static DWORD m_NumArgs;
- static LPWSTR *m_ArgvW;
-
- static LPWSTR m_pwszAppFullName;
- static DWORD m_dwManifestPaths;
- static LPWSTR *m_ppwszManifestPaths;
- static DWORD m_dwActivationData;
- static LPWSTR *m_ppwszActivationData;
-
-//********** METHODS
-
- // parse the command line
- static HRESULT SetArgvW(LPCWSTR lpCommandLine);
-
- // Retrieve the parsed command line
- static LPWSTR *GetArgvW(DWORD *pNumArgs);
-
-private:
- static HRESULT ReadClickOnceEnvVariables();
-};
-#endif // !FEATURE_CORECLR
#endif
diff --git a/src/vm/class.cpp b/src/vm/class.cpp
index cff71f328f..21720909cb 100644
--- a/src/vm/class.cpp
+++ b/src/vm/class.cpp
@@ -16,7 +16,6 @@
#include "dllimport.h"
#include "dllimportcallback.h"
#include "fieldmarshaler.h"
-#include "constrainedexecutionregion.h"
#include "customattribute.h"
#include "encee.h"
#include "typestring.h"
@@ -185,15 +184,6 @@ void EEClass::Destruct(MethodTable * pOwningMT)
// default appdomain and mscorlib.dll module during shutdown
_ASSERTE(!pOwningMT->IsTransparentProxy());
-#if defined(FEATURE_REMOTING) && !defined(HAS_REMOTING_PRECODE)
- // Destruct the method descs by walking the chunks.
- MethodTable::IntroducedMethodIterator it(pOwningMT);
- for (; it.IsValid(); it.Next())
- {
- MethodDesc * pMD = it.GetMethodDesc();
- pMD->Destruct();
- }
-#endif
#ifdef FEATURE_COMINTEROP
if (GetSparseCOMInteropVTableMap() != NULL && !pOwningMT->IsZapped())
@@ -2491,14 +2481,6 @@ MethodTable::GetSubstitutionForParent(
#endif //!DACCESS_COMPILE
-#ifdef FEATURE_CER
-//*******************************************************************************
-DWORD EEClass::GetReliabilityContract()
-{
- LIMITED_METHOD_CONTRACT;
- return HasOptionalFields() ? GetOptionalFields()->m_dwReliabilityContract : RC_NULL;
-}
-#endif // FEATURE_CER
//*******************************************************************************
#ifdef FEATURE_PREJIT
diff --git a/src/vm/class.h b/src/vm/class.h
index 7517863278..6c74377012 100644
--- a/src/vm/class.h
+++ b/src/vm/class.h
@@ -416,12 +416,12 @@ class EEClassLayoutInfo
e_ZERO_SIZED = 0x04,
// The size of the struct is explicitly specified in the meta-data.
e_HAS_EXPLICIT_SIZE = 0x08,
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
-#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF defined at the same time.
+#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING defined at the same time.
#endif // FEATURE_HFA
e_NATIVE_PASS_IN_REGISTERS = 0x10, // Flag wheter a native struct is passed in registers.
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
// HFA type of the unmanaged layout
e_R4_HFA = 0x10,
@@ -510,13 +510,13 @@ class EEClassLayoutInfo
return m_cbPackingSize;
}
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
bool IsNativeStructPassedInRegisters()
{
LIMITED_METHOD_CONTRACT;
return (m_bFlags & e_NATIVE_PASS_IN_REGISTERS) != 0;
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
bool IsNativeHFA()
@@ -570,13 +570,13 @@ class EEClassLayoutInfo
m_bFlags |= (hfaType == ELEMENT_TYPE_R4) ? e_R4_HFA : e_R8_HFA;
}
#endif
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
void SetNativeStructPassedInRegisters()
{
LIMITED_METHOD_CONTRACT;
m_bFlags |= e_NATIVE_PASS_IN_REGISTERS;
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
};
@@ -703,9 +703,6 @@ class EEClassOptionalFields
#define MODULE_NON_DYNAMIC_STATICS ((DWORD)-1)
DWORD m_cbModuleDynamicID;
-#ifdef FEATURE_CER
- DWORD m_dwReliabilityContract;
-#endif
SecurityProperties m_SecProps;
@@ -1042,21 +1039,6 @@ public:
return m_pMethodTable;
}
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_REMOTING
- inline void SetMethodTableForTransparentProxy(MethodTable* pMT)
- {
- LIMITED_METHOD_CONTRACT;
- // Transparent proxy class' true method table
- // is replaced by a global thunk table
-
- _ASSERTE(pMT->IsTransparentProxy() &&
- m_pMethodTable->IsTransparentProxy());
-
- IBCLOG(LogEEClassCOWTableAccess(GetMethodTable()));
-
- m_pMethodTable = pMT;
- }
-#endif
inline void SetMethodTable(MethodTable* pMT)
{
@@ -1360,9 +1342,6 @@ public:
_ASSERTE(HasCriticalTransparentInfo());
return (m_VMFlags & VMFLAG_TRANSPARENCY_MASK) == VMFLAG_TRANSPARENCY_ALLCRITICAL_TAS ||
(m_VMFlags & VMFLAG_TRANSPARENCY_MASK) == VMFLAG_TRANSPARENCY_TAS_NOTCRITICAL
-#ifndef FEATURE_CORECLR
- || (m_VMFlags & VMFLAG_TRANSPARENCY_MASK) == VMFLAG_TRANSPARENCY_CRITICAL_TAS
-#endif // !FEATURE_CORECLR;
;
}
@@ -1388,9 +1367,6 @@ public:
}
void SetCriticalTransparentInfo(
-#ifndef FEATURE_CORECLR
- BOOL fIsCritical,
-#endif // !FEATURE_CORECLR
BOOL fIsTreatAsSafe,
BOOL fIsAllTransparent,
BOOL fIsAllCritical)
@@ -1399,9 +1375,7 @@ public:
// TAS wihtout critical doesn't make sense - although it was allowed in the v2 desktop model,
// so we need to allow it for compatibility reasons on the desktop.
-#ifdef FEATURE_CORECLR
_ASSERTE(!fIsTreatAsSafe || fIsAllCritical);
-#endif // FEATURE_CORECLR
//if nothing is set, then we're transparent.
unsigned flags = VMFLAG_TRANSPARENCY_TRANSPARENT;
@@ -1415,13 +1389,6 @@ public:
flags = fIsTreatAsSafe ? VMFLAG_TRANSPARENCY_ALLCRITICAL_TAS :
VMFLAG_TRANSPARENCY_ALLCRITICAL;
}
-#ifndef FEATURE_CORECLR
- else if (fIsCritical)
- {
- flags = fIsTreatAsSafe ? VMFLAG_TRANSPARENCY_CRITICAL_TAS :
- VMFLAG_TRANSPARENCY_CRITICAL;
- }
-#endif // !FEATURE_CORECLR
else
{
flags = fIsTreatAsSafe ? VMFLAG_TRANSPARENCY_TAS_NOTCRITICAL :
@@ -1652,23 +1619,10 @@ public:
LIMITED_METHOD_CONTRACT;
m_VMFlags |= (DWORD)VMFLAG_HAS_FIELDS_WHICH_MUST_BE_INITED;
}
-#ifdef FEATURE_REMOTING
- DWORD CannotBeBlittedByObjectCloner()
- {
- LIMITED_METHOD_CONTRACT;
- return (m_VMFlags & VMFLAG_CANNOT_BE_BLITTED_BY_OBJECT_CLONER);
- }
- void SetCannotBeBlittedByObjectCloner()
- {
- LIMITED_METHOD_CONTRACT;
- m_VMFlags |= (DWORD)VMFLAG_CANNOT_BE_BLITTED_BY_OBJECT_CLONER;
- }
-#else
void SetCannotBeBlittedByObjectCloner()
{
/* no op */
}
-#endif
DWORD HasNonPublicFields()
{
LIMITED_METHOD_CONTRACT;
@@ -1770,14 +1724,6 @@ public:
// Cached class level reliability contract info, see ConstrainedExecutionRegion.cpp for details.
DWORD GetReliabilityContract();
-#ifdef FEATURE_CER
- inline void SetReliabilityContract(DWORD dwValue)
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(HasOptionalFields());
- GetOptionalFields()->m_dwReliabilityContract = dwValue;
- }
-#endif
#if defined(UNIX_AMD64_ABI) && defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
// Get number of eightbytes used by a struct passed in registers.
@@ -2138,9 +2084,6 @@ public:
VMFLAG_FIXED_ADDRESS_VT_STATICS = 0x00000020, // Value type Statics in this class will be pinned
VMFLAG_HASLAYOUT = 0x00000040,
VMFLAG_ISNESTED = 0x00000080,
-#ifdef FEATURE_REMOTING
- VMFLAG_CANNOT_BE_BLITTED_BY_OBJECT_CLONER = 0x00000100, // This class has GC type fields, or implements ISerializable or has non-Serializable fields
-#endif
VMFLAG_IS_EQUIVALENT_TYPE = 0x00000200,
diff --git a/src/vm/class.inl b/src/vm/class.inl
index 7d5c74d586..1a7e169ed7 100644
--- a/src/vm/class.inl
+++ b/src/vm/class.inl
@@ -13,7 +13,6 @@
#ifndef _CLASS_INL_
#define _CLASS_INL_
-#include "constrainedexecutionregion.h"
//***************************************************************************************
inline PTR_MethodDescChunk EEClass::GetChunks()
{
@@ -50,9 +49,6 @@ inline void EEClassOptionalFields::Init()
m_WinRTRedirectedTypeIndex = WinMDAdapter::RedirectedTypeIndex_Invalid;
#endif // FEATURE_COMINTEROP
m_cbModuleDynamicID = MODULE_NON_DYNAMIC_STATICS;
-#ifdef FEATURE_CER
- m_dwReliabilityContract = RC_NULL;
-#endif
m_SecProps = 0;
#if defined(UNIX_AMD64_ABI) && defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
m_numberEightBytes = 0;
diff --git a/src/vm/classcompat.cpp b/src/vm/classcompat.cpp
index 50c56506a9..0bd1c2da06 100644
--- a/src/vm/classcompat.cpp
+++ b/src/vm/classcompat.cpp
@@ -36,9 +36,6 @@
#include "dbginterface.h"
#include "comdelegate.h"
#include "sigformat.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "eeprofinterfaces.h"
#include "dllimportcallback.h"
#include "listlock.h"
diff --git a/src/vm/classfactory.cpp b/src/vm/classfactory.cpp
index 9d60b5b086..3c5a97ae05 100644
--- a/src/vm/classfactory.cpp
+++ b/src/vm/classfactory.cpp
@@ -11,9 +11,6 @@
#include "frames.h"
#include "excep.h"
#include "registration.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "typeparse.h"
#include "mdaassistants.h"
diff --git a/src/vm/classnames.h b/src/vm/classnames.h
index 47f1fecdec..0c24914a56 100644
--- a/src/vm/classnames.h
+++ b/src/vm/classnames.h
@@ -16,9 +16,7 @@
#define g_ArrayClassName "System.Array"
#define g_NullableName "Nullable`1"
-#ifdef FEATURE_SPAN_OF_T
#define g_ByReferenceName "ByReference`1"
-#endif
#define g_CollectionsEnumerableItfName "System.Collections.IEnumerable"
#define g_CollectionsEnumeratorClassName "System.Collections.IEnumerator"
@@ -68,9 +66,6 @@
#define g_PropertyChangedEventHandler_WinRT_Name "System.Runtime.InteropServices.WindowsRuntime.PropertyChangedEventHandler_WinRT"
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_REMOTING
-#define g_ContextBoundObjectClassName "System.ContextBoundObject"
-#endif
#define g_DateClassName "System.DateTime"
#define g_DateTimeOffsetClassName "System.DateTimeOffset"
@@ -158,27 +153,19 @@
#define g_SecurityCriticalAttribute "System.Security.SecurityCriticalAttribute"
#define g_SecurityTransparentAttribute "System.Security.SecurityTransparentAttribute"
-#ifndef FEATURE_CORECLR
-#define g_SecurityTreatAsSafeAttribute "System.Security.SecurityTreatAsSafeAttribute"
-#define g_SecurityRulesAttribute "System.Security.SecurityRulesAttribute"
-#endif //FEATURE_CORECLR
#define g_SecuritySafeCriticalAttribute "System.Security.SecuritySafeCriticalAttribute"
-#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_CORESYSTEM)
#define g_SecurityAPTCA "System.Security.AllowPartiallyTrustedCallersAttribute"
#define g_SecurityPartialTrustVisibilityLevel "System.Security.PartialTrustVisibilityLevel"
#define g_PartialTrustVisibilityLevel "PartialTrustVisibilityLevel"
-#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#endif // defined(FEATURE_CORESYSTEM)
#define g_ReferenceAssemblyAttribute "System.Runtime.CompilerServices.ReferenceAssemblyAttribute"
#define g_CriticalFinalizerObjectName "CriticalFinalizerObject"
-#ifdef FEATURE_SERIALIZATION
-#define g_StreamingContextName "StreamingContext"
-#endif
-
#define g_AssemblySignatureKeyAttribute "System.Reflection.AssemblySignatureKeyAttribute"
#endif //!__CLASSNAMES_H__
diff --git a/src/vm/clrconfignative.cpp b/src/vm/clrconfignative.cpp
new file mode 100644
index 0000000000..11b9eb5555
--- /dev/null
+++ b/src/vm/clrconfignative.cpp
@@ -0,0 +1,21 @@
+// 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.
+//
+// File: clrconfiguration.cpp
+//
+
+#include "common.h"
+#include "clrconfignative.h"
+#include <configuration.h>
+
+BOOL QCALLTYPE ClrConfigNative::GetConfigBoolValue(LPCWSTR name)
+{
+ QCALL_CONTRACT;
+
+ BOOL retValue = FALSE;
+ BEGIN_QCALL;
+ retValue = Configuration::GetKnobBooleanValue(name, FALSE);
+ END_QCALL;
+ return(retValue);
+}
diff --git a/src/vm/clrconfignative.h b/src/vm/clrconfignative.h
new file mode 100644
index 0000000000..a60d119558
--- /dev/null
+++ b/src/vm/clrconfignative.h
@@ -0,0 +1,14 @@
+// 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.
+
+#ifndef _CLRCONFIGNATIVE_H_
+#define _CLRCONFIGNATIVE_H_
+
+class ClrConfigNative
+{
+public:
+ static BOOL QCALLTYPE GetConfigBoolValue(LPCWSTR name);
+};
+
+#endif // _CLRCONFIGNATIVE_H_
diff --git a/src/vm/clrex.cpp b/src/vm/clrex.cpp
index c8fc2f3886..1c1501e54d 100644
--- a/src/vm/clrex.cpp
+++ b/src/vm/clrex.cpp
@@ -343,9 +343,8 @@ HRESULT CLRException::SetErrorInfo()
EX_TRY
{
- LeaveRuntimeHolderNoThrow lrh((size_t)::SetErrorInfo);
- ::SetErrorInfo(0, pErrorInfo);
- pErrorInfo->Release();
+ ::SetErrorInfo(0, pErrorInfo);
+ pErrorInfo->Release();
// Success in setting the ErrorInfo on the thread
hr = S_OK;
@@ -1717,11 +1716,7 @@ OBJECTREF EETypeLoadException::CreateThrowable()
// EEFileLoadException is an EE exception subclass representing a file loading
// error
// ---------------------------------------------------------------------------
-#ifdef FEATURE_FUSION
-EEFileLoadException::EEFileLoadException(const SString &name, HRESULT hr, IFusionBindLog *pFusionLog, Exception *pInnerException/* = NULL*/)
-#else
EEFileLoadException::EEFileLoadException(const SString &name, HRESULT hr, void *pFusionLog, Exception *pInnerException/* = NULL*/)
-#endif
: EEException(GetFileLoadKind(hr)),
m_name(name),
m_pFusionLog(pFusionLog),
@@ -1753,10 +1748,6 @@ EEFileLoadException::EEFileLoadException(const SString &name, HRESULT hr, void *
m_name.Set(wszTemplate);
}
-#ifdef FEATURE_FUSION
- if (m_pFusionLog != NULL)
- m_pFusionLog->AddRef();
-#endif
}
@@ -1765,10 +1756,6 @@ EEFileLoadException::~EEFileLoadException()
STATIC_CONTRACT_NOTHROW;
STATIC_CONTRACT_GC_NOTRIGGER;
-#ifdef FEATURE_FUSION
- if (m_pFusionLog)
- m_pFusionLog->Release();
-#endif
}
@@ -1880,19 +1867,6 @@ OBJECTREF EEFileLoadException::CreateThrowable()
// Fetch any log info from the fusion log
SString logText;
-#ifdef FEATURE_FUSION
- if (m_pFusionLog != NULL)
- {
- DWORD dwSize = 0;
- HRESULT hr = m_pFusionLog->GetBindLog(0,0,NULL,&dwSize);
- if (hr==HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- WCHAR *buffer = logText.OpenUnicodeBuffer(dwSize);
- hr=m_pFusionLog->GetBindLog(0,0,buffer, &dwSize);
- logText.CloseBuffer();
- }
- }
-#endif
struct _gc {
OBJECTREF pNewException;
STRINGREF pNewFileString;
@@ -1958,33 +1932,6 @@ BOOL EEFileLoadException::CheckType(Exception* ex)
// <TODO>@todo: ideally we would use inner exceptions with these routines</TODO>
/* static */
-#ifdef FEATURE_FUSION
-void DECLSPEC_NORETURN EEFileLoadException::Throw(AssemblySpec *pSpec, IFusionBindLog *pFusionLog, HRESULT hr, Exception *pInnerException/* = NULL*/)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- THROWS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (hr == COR_E_THREADABORTED)
- COMPlusThrow(kThreadAbortException);
- if (hr == E_OUTOFMEMORY)
- COMPlusThrowOM();
-#ifdef FEATURE_COMINTEROP
- if ((hr == RO_E_METADATA_NAME_NOT_FOUND) || (hr == CLR_E_BIND_TYPE_NOT_FOUND))
- { // These error codes behave like FileNotFound, but are exposed as TypeLoadException
- EX_THROW_WITH_INNER(EETypeLoadException, (pSpec->GetWinRtTypeNamespace(), pSpec->GetWinRtTypeClassName(), nullptr, nullptr, IDS_EE_WINRT_LOADFAILURE), pInnerException);
- }
-#endif //FEATURE_COMINTEROP
-
- StackSString name;
- pSpec->GetFileOrDisplayName(0, name);
- EX_THROW_WITH_INNER(EEFileLoadException, (name, hr, pFusionLog), pInnerException);
-}
-#endif //FEATURE_FUSION
/* static */
void DECLSPEC_NORETURN EEFileLoadException::Throw(AssemblySpec *pSpec, HRESULT hr, Exception *pInnerException/* = NULL*/)
@@ -2070,41 +2017,6 @@ void DECLSPEC_NORETURN EEFileLoadException::Throw(LPCWSTR path, HRESULT hr, Exce
}
/* static */
-#ifdef FEATURE_FUSION
-void DECLSPEC_NORETURN EEFileLoadException::Throw(IAssembly *pIAssembly, IHostAssembly *pIHostAssembly, HRESULT hr, Exception *pInnerException/* = NULL*/)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- THROWS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (hr == COR_E_THREADABORTED)
- COMPlusThrow(kThreadAbortException);
- if (hr == E_OUTOFMEMORY || hr == HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY))
- COMPlusThrowOM();
-
- StackSString name;
-
- {
- SafeComHolder<IAssemblyName> pName;
-
- HRESULT newHr;
-
- if (pIAssembly)
- newHr = pIAssembly->GetAssemblyNameDef(&pName);
- else
- newHr = pIHostAssembly->GetAssemblyNameDef(&pName);
-
- if (SUCCEEDED(newHr))
- FusionBind::GetAssemblyNameDisplayName(pName, name, 0);
- }
-
- EX_THROW_WITH_INNER(EEFileLoadException, (name, hr), pInnerException);
-}
-#endif
/* static */
void DECLSPEC_NORETURN EEFileLoadException::Throw(PEAssembly *parent,
const void *memory, COUNT_T size, HRESULT hr, Exception *pInnerException/* = NULL*/)
@@ -2566,10 +2478,6 @@ CLRLastThrownObjectException* CLRLastThrownObjectException::Validate()
DWORD dwCurrentExceptionCode = GetCurrentExceptionCode();
-#if HAS_TRACK_CXX_EXCEPTION_CODE_HACK
- DWORD dwLastCxxSEHExceptionCode = pThread->m_LastCxxSEHExceptionCode;
-#endif // HAS_TRACK_CXX_EXCEPTION_CODE_HACK
-
if (dwCurrentExceptionCode == BOOTUP_EXCEPTION_COMPLUS)
{
// BOOTUP_EXCEPTION_COMPLUS can be thrown when a thread setup is failed due to reasons like
@@ -2609,75 +2517,7 @@ CLRLastThrownObjectException* CLRLastThrownObjectException::Validate()
//
// This also ensures that the handling of BOOTUP_EXCEPTION_COMPLUS is now insync between the chk and fre builds in terms of the throwable returned.
}
- else
-
-#if HAS_TRACK_CXX_EXCEPTION_CODE_HACK // ON x86, we grab the exception code.
-
- // The exception code can legitimately take several values.
- // The most obvious is EXCEPTION_COMPLUS, as when managed code does 'throw new Exception'.
- // Another case is EXCEPTION_MSVC, when we EX_RETHROW a CLRLastThrownObjectException, which will
- // throw an actual CLRLastThrownObjectException C++ exception.
- // Other values are possible, if we are wrapping an SEH exception (say, AV) in
- // a managed exception. In these other cases, the exception object should have
- // an XCode that is the same as the exception code.
- // So, if the exception code isn't EXCEPTION_COMPLUS, and isn't EXCEPTION_MSVC, then
- // we shouldn't be getting a CLRLastThrownObjectException. This indicates that
- // we are missing a "callout filter", which should have transformed the SEH
- // exception into a COMPLUS exception.
- // It also turns out that sometimes we see STATUS_UNWIND more recently than the exception
- // code. In that case, we have lost the original exception code, and so can't check.
-
- if (dwLastCxxSEHExceptionCode != EXCEPTION_COMPLUS &&
- dwLastCxxSEHExceptionCode != EXCEPTION_MSVC &&
- dwLastCxxSEHExceptionCode != STATUS_UNWIND)
- {
- // Maybe there is an exception wrapping a Win32 fault. In that case, the
- // last exception code won't be EXCEPTION_COMPLUS, but the last thrown exception
- // will have an XCode equal to the last exception code.
-
- // Get the exception code from the exception object.
- DWORD dwExceptionXCode = GetExceptionXCode(throwable);
-
- // If that code is the same as the last exception code, call it good...
- if (dwLastCxxSEHExceptionCode != dwExceptionXCode)
- {
- // For rude thread abort, we may have updated the LastThrownObject without throwing exception.
- BOOL fIsRudeThreadAbortException =
- throwable == CLRException::GetPreallocatedRudeThreadAbortException();
-
- // For stack overflow, we may have updated the LastThrownObject without throwing exception.
- BOOL fIsStackOverflowException =
- throwable == CLRException::GetPreallocatedStackOverflowException() &&
- (IsSOExceptionCode(dwLastCxxSEHExceptionCode));
-
- // ... but if not, raise an error.
- if (!fIsRudeThreadAbortException && !fIsStackOverflowException)
- {
- static int iSuppress = -1;
- if (iSuppress == -1)
- iSuppress = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_SuppressLostExceptionTypeAssert);
- if (!iSuppress)
- {
- // Raising an assert message can cause a mode violation.
- CONTRACT_VIOLATION(ModeViolation);
-
- // Use DbgAssertDialog to get the formatting right.
- DbgAssertDialog(__FILE__, __LINE__,
- "The 'current' exception is not EXCEPTION_COMPLUS, yet the runtime is\n"
- " requesting the 'LastThrownObject'.\n"
- "The runtime may have lost track of the type of an exception in flight.\n"
- " Please get a good stack trace of the exception that was thrown first\n"
- " (by re-running the app & catching first chance exceptions), find\n"
- " the caller of Validate, and file a bug against the owner.\n\n"
- "To suppress this assert 'set COMPlus_SuppressLostExceptionTypeAssert=1'");
- }
- }
- }
- }
- else
-#endif // _x86_
-
- if (throwable == NULL)
+ else if (throwable == NULL)
{ // If there isn't a LastThrownObject at all, that's a problem for GetLastThrownObject
// We've lost track of the exception's type. Raise an assert. (This is configurable to allow
// stress labs to turn off the assert.)
diff --git a/src/vm/clrex.h b/src/vm/clrex.h
index 02de452370..15d1071fb9 100644
--- a/src/vm/clrex.h
+++ b/src/vm/clrex.h
@@ -28,11 +28,9 @@ struct StackTraceElement
UINT_PTR ip;
UINT_PTR sp;
PTR_MethodDesc pFunc;
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
// TRUE if this element represents the last frame of the foreign
// exception stack trace.
BOOL fIsLastFrameFromForeignStackTrace;
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
bool operator==(StackTraceElement const & rhs) const
{
@@ -681,21 +679,13 @@ class EEFileLoadException : public EEException
private:
SString m_name;
-#ifdef FEATURE_FUSION
- IFusionBindLog *m_pFusionLog;
-#else
void *m_pFusionLog;
-#endif
HRESULT m_hr;
public:
-#ifdef FEATURE_FUSION
- EEFileLoadException(const SString &name, HRESULT hr, IFusionBindLog *pFusionLog = NULL, Exception *pInnerException = NULL);
-#else
EEFileLoadException(const SString &name, HRESULT hr, void *pFusionLog = NULL, Exception *pInnerException = NULL);
-#endif
~EEFileLoadException();
// virtual overrides
@@ -709,10 +699,6 @@ class EEFileLoadException : public EEException
OBJECTREF CreateThrowable();
static RuntimeExceptionKind GetFileLoadKind(HRESULT hr);
-#ifdef FEATURE_FUSION
- static void DECLSPEC_NORETURN Throw(AssemblySpec *pSpec, IFusionBindLog *pFusionLog, HRESULT hr, Exception *pInnerException = NULL);
- static void DECLSPEC_NORETURN Throw(IAssembly *pIAssembly, IHostAssembly *pIHostAssembly, HRESULT hr, Exception *pInnerException = NULL);
-#endif
static void DECLSPEC_NORETURN Throw(AssemblySpec *pSpec, HRESULT hr, Exception *pInnerException = NULL);
static void DECLSPEC_NORETURN Throw(PEFile *pFile, HRESULT hr, Exception *pInnerException = NULL);
static void DECLSPEC_NORETURN Throw(LPCWSTR path, HRESULT hr, Exception *pInnerException = NULL);
diff --git a/src/vm/clrprivbinderappx.cpp b/src/vm/clrprivbinderappx.cpp
deleted file mode 100644
index b55ece4556..0000000000
--- a/src/vm/clrprivbinderappx.cpp
+++ /dev/null
@@ -1,1057 +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 "common.h" // precompiled header
-#include "assemblyusagelogmanager.h"
-
-//=====================================================================================================================
-#include "clrprivbinderappx.h"
-//CLRPrivBinderAppX * CLRPrivBinderAppX::s_pSingleton = nullptr;
-SPTR_IMPL_INIT(CLRPrivBinderAppX, CLRPrivBinderAppX, s_pSingleton, nullptr);
-
-#ifndef DACCESS_COMPILE
-//=====================================================================================================================
-#include "appxutil.h"
-#include "clrprivbinderutil.h"
-#include "fusionlogging.h"
-#include "clrprivtypecachewinrt.h"
-#include "fusionp.h"
-
-using namespace CLRPrivBinderUtil;
-
-//=====================================================================================================================
-CLRPrivBinderAppX::CLRPrivBinderAppX(LPCWSTR * rgwzAltPath, UINT cAltPaths)
- : m_MapReadLock(CrstCLRPrivBinderMaps,
- static_cast<CrstFlags>(CRST_DEBUG_ONLY_CHECK_FORBID_SUSPEND_THREAD |
- CRST_GC_NOTRIGGER_WHEN_TAKEN |
- CRST_DEBUGGER_THREAD |
- // FindAssemblyBySpec complicates matters, which needs to take the m_MapReadLock.
- // But FindAssemblyBySpec cannot switch to preemptive mode, as that would trigger
- // a GC. Since this is a leaf lock, and since it does not make any calls out of
- // the runtime, this lock can be taken in cooperative mode if the locked scope is
- // also marked as ForbidSuspend (since FindAssemblyBySpec can be called by
- // the debugger and the profiler). TODO: it would be nice to be able to specify
- // this flag for just the specific places where it is necessary rather than for
- // the lock as a whole.
- CRST_UNSAFE_ANYMODE)),
- m_MapWriteLock(CrstCLRPrivBinderMapsAdd, CRST_DEFAULT),
- m_cAltPaths(cAltPaths),
- m_fCanUseNativeImages(TRUE),
- m_pParentBinder(nullptr),
- m_pFusionBinder(nullptr),
- m_pWinRTBinder(nullptr),
-
- // Note: the first CLRPrivBinderAppX object is created prior to runtime startup, so this code cannot call
- // AppX::IsAppXDesignMode; however, FindAssemblyBySpec cannot call IsAppXDesignMode either because that would
- // cause a GC_TRIGGERS violation for the GetAssemblyIfLoaded scenario. However this doesn't matter because
- // the assembly map will be empty until at least the first call to BindAssemblyByName is made, at which point
- // a call to IsAppXDesignMode can be made. Thus, we default to the most conversative setting and overwrite this
- // value in BindAssemblyByName.
- m_fusionBindingScope(CLRPrivBinderFusion::kBindingScope_FrameworkSubset)
-{
- STANDARD_VM_CONTRACT;
-
- // Copy altpaths
- if (cAltPaths > 0)
- {
- m_rgAltPathsHolder = new NewArrayHolder<WCHAR>[cAltPaths];
- m_rgAltPaths = new WCHAR *[cAltPaths];
-
- for (UINT iAltPath = 0; iAltPath < cAltPaths; iAltPath++)
- {
- size_t cchAltPath = wcslen(rgwzAltPath[iAltPath]);
- m_rgAltPathsHolder[iAltPath] = m_rgAltPaths[iAltPath] = new WCHAR[cchAltPath + 1];
- wcscpy_s(m_rgAltPaths[iAltPath], cchAltPath + 1, rgwzAltPath[iAltPath]);
- }
- }
-
-#ifdef FEATURE_FUSION
- IfFailThrow(RuntimeCreateCachingILFingerprintFactory(&m_pFingerprintFactory));
-#endif
-}
-
-//=====================================================================================================================
-CLRPrivBinderFusion::BindingScope CLRPrivBinderAppX::GetFusionBindingScope()
-{
- WRAPPER_NO_CONTRACT;
-
- m_fusionBindingScope = (AppX::IsAppXDesignMode() || (m_pParentBinder != nullptr))
- ? CLRPrivBinderFusion::kBindingScope_FrameworkAll
- : CLRPrivBinderFusion::kBindingScope_FrameworkSubset;
-
- return m_fusionBindingScope;
-}
-
-//=====================================================================================================================
-CLRPrivBinderAppX::~CLRPrivBinderAppX()
-{
- WRAPPER_NO_CONTRACT;
-
- m_NameToAssemblyMap.RemoveAll();
- AssemblyUsageLogManager::UnRegisterBinderFromUsageLog((UINT_PTR)this);
-
- clr::SafeRelease(m_pWinRTBinder);
-}
-
-//=====================================================================================================================
-CLRPrivBinderAppX *
-CLRPrivBinderAppX::GetOrCreateBinder()
-{
- STANDARD_VM_CONTRACT;
- HRESULT hr = S_OK;
-
- if (s_pSingleton == nullptr)
- {
- ReleaseHolder<IAssemblyUsageLog> pNewUsageLog;
- IfFailThrow(AssemblyUsageLogManager::GetUsageLogForContext(W("App"), AppX::GetHeadPackageMoniker(), &pNewUsageLog));
-
- ReleaseHolder<CLRPrivBinderAppX> pBinder;
- pBinder = clr::SafeAddRef(new CLRPrivBinderAppX(nullptr, 0));
-
- pBinder->m_pFusionBinder = clr::SafeAddRef(new CLRPrivBinderFusion());
-
- CLRPrivTypeCacheWinRT * pWinRtTypeCache = CLRPrivTypeCacheWinRT::GetOrCreateTypeCache();
- pBinder->m_pWinRTBinder = clr::SafeAddRef(new CLRPrivBinderWinRT(
- pBinder,
- pWinRtTypeCache,
- nullptr, // rgwzAltPath
- 0, // cAltPaths
- CLRPrivBinderWinRT::NamespaceResolutionKind_WindowsAPI,
- TRUE // fCanUseNativeImages
- ));
-
- if (InterlockedCompareExchangeT<decltype(s_pSingleton)>(&s_pSingleton, pBinder, nullptr) == nullptr)
- pBinder.SuppressRelease();
-
- // Register binder with usagelog infrastructure.
- UINT_PTR binderId;
- IfFailThrow(pBinder->GetBinderID(&binderId));
- IfFailThrow(AssemblyUsageLogManager::RegisterBinderWithUsageLog(binderId, pNewUsageLog));
-
- // Create and register WinRT usage log
- ReleaseHolder<IAssemblyUsageLog> pNewWinRTUsageLog;
- IfFailThrow(AssemblyUsageLogManager::GetUsageLogForContext(W("WinRT"), AppX::GetHeadPackageMoniker(), &pNewWinRTUsageLog));
-
- UINT_PTR winRTBinderId;
- IfFailThrow(pBinder->m_pWinRTBinder->GetBinderID(&winRTBinderId));
- IfFailThrow(AssemblyUsageLogManager::RegisterBinderWithUsageLog(winRTBinderId, pNewWinRTUsageLog));
- }
-
- return s_pSingleton;
-}
-
-//=====================================================================================================================
-// Used only for designer binding context
-CLRPrivBinderAppX * CLRPrivBinderAppX::CreateParentedBinder(
- ICLRPrivBinder * pParentBinder,
- CLRPrivTypeCacheWinRT * pWinRtTypeCache,
- LPCWSTR * rgwzAltPath,
- UINT cAltPaths,
- BOOL fCanUseNativeImages)
-{
- STANDARD_VM_CONTRACT;
- HRESULT hr = S_OK;
-
- ReleaseHolder<CLRPrivBinderAppX> pBinder;
- pBinder = clr::SafeAddRef(new CLRPrivBinderAppX(rgwzAltPath, cAltPaths));
-
- pBinder->m_pParentBinder = clr::SafeAddRef(pParentBinder);
- pBinder->m_fCanUseNativeImages = fCanUseNativeImages;
-
- // We want to share FusionBinder with pParentBinder (which bubbles up through the chain of binders to the global AppXBinder code:s_pSingleton)
- // Ideally we would get the FusionBinder from pParentBinder (via casting to a new interface). It is much easier just to fetch it from
- // the global AppX binder directly
- pBinder->m_pFusionBinder = clr::SafeAddRef(s_pSingleton->GetFusionBinder());
-
- if (cAltPaths > 0)
- {
- pBinder->m_pWinRTBinder = clr::SafeAddRef(new CLRPrivBinderWinRT(
- pBinder,
- pWinRtTypeCache,
- rgwzAltPath,
- cAltPaths,
- CLRPrivBinderWinRT::NamespaceResolutionKind_WindowsAPI,
- fCanUseNativeImages));
- }
-
- pBinder.SuppressRelease();
- return pBinder;
-}
-
-//=====================================================================================================================
-HRESULT CLRPrivBinderAppX::BindAppXAssemblyByNameWorker(
- IAssemblyName * pIAssemblyName,
- DWORD dwAppXBindFlags,
- CLRPrivAssemblyAppX ** ppAssembly)
-{
- STANDARD_VM_CONTRACT;
- HRESULT hr = S_OK;
-
- fusion::logging::StatusScope logStatus(0, ID_FUSLOG_BINDING_STATUS_IMMERSIVE, &hr);
-
- VALIDATE_ARG_RET(pIAssemblyName != nullptr);
- VALIDATE_ARG_RET((dwAppXBindFlags & ABF_BindIL) == ABF_BindIL);
- VALIDATE_ARG_RET(ppAssembly != nullptr);
-
- DWORD dwContentType = AssemblyContentType_Default;
- IfFailRet(hr = fusion::util::GetProperty(pIAssemblyName, ASM_NAME_CONTENT_TYPE, &dwContentType));
- if ((hr == S_OK) && (dwContentType != AssemblyContentType_Default))
- {
- IfFailRet(CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT);
- }
-
- ReleaseHolder<CLRPrivAssemblyAppX> pAssembly;
-
- // Get the simple name.
- WCHAR wzSimpleName[_MAX_PATH];
- DWORD cchSimpleName = _MAX_PATH;
- IfFailRet(pIAssemblyName->GetName(&cchSimpleName, wzSimpleName));
-
- { // Look for previous successful bind. Host callouts are now forbidden.
- ForbidSuspendThreadCrstHolder lock(&m_MapReadLock);
- pAssembly = clr::SafeAddRef(m_NameToAssemblyMap.Lookup(wzSimpleName));
- }
-
- if (pAssembly == nullptr)
- {
- ReleaseHolder<ICLRPrivResource> pResourceIL;
- ReleaseHolder<ICLRPrivResource> pResourceNI;
-
- // Create assembly identity using the simple name. For successful binds this will be updated
- // with the full assembly identity in the VerifyBind callback.
- NewHolder<AssemblyIdentity> pIdentity = new AssemblyIdentity();
- IfFailRet(pIdentity->Initialize(wzSimpleName));
-
- //
- // Check the head package first to see if this matches an EXE, then check
- // all packages to see if this matches a DLL.
- //
- WCHAR wzFilePath[_MAX_PATH];
- {
- hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
-
- if (FAILED(hr))
- {
- // Create simple name with .EXE extension
- WCHAR wzSimpleFileName[_MAX_PATH];
- wcscpy_s(wzSimpleFileName, NumItems(wzSimpleFileName), wzSimpleName);
- wcscat_s(wzSimpleFileName, NumItems(wzSimpleFileName), W(".EXE"));
-
- // Search for the file using AppX::FileFileInCurrentPackage helper.
- UINT32 cchFilePath = NumItems(wzFilePath);
- hr = AppX::FindFileInCurrentPackage(
- wzSimpleFileName,
- &cchFilePath,
- wzFilePath,
- PACKAGE_FILTER_CLR_DEFAULT,
- (PCWSTR *)(void *)m_rgAltPaths,
- m_cAltPaths,
- m_pParentBinder != NULL ? AppX::FindFindInPackageFlags_SkipCurrentPackageGraph : AppX::FindFindInPackageFlags_None);
- }
-
- if (FAILED(hr))
- {
- // Create simple name with .DLL extension
- WCHAR wzSimpleFileName[_MAX_PATH];
- wcscpy_s(wzSimpleFileName, NumItems(wzSimpleFileName), wzSimpleName);
- wcscat_s(wzSimpleFileName, NumItems(wzSimpleFileName), W(".DLL"));
-
- // Search for the file using AppX::FileFileInCurrentPackage helper
- UINT32 cchFilePath = NumItems(wzFilePath);
- hr = AppX::FindFileInCurrentPackage(
- wzSimpleFileName,
- &cchFilePath,
- wzFilePath,
- PACKAGE_FILTER_CLR_DEFAULT,
- (PCWSTR *)(void *)m_rgAltPaths,
- m_cAltPaths,
- m_pParentBinder != NULL ? AppX::FindFindInPackageFlags_SkipCurrentPackageGraph : AppX::FindFindInPackageFlags_None);
- }
-
- if (SUCCEEDED(hr))
- {
- fusion::logging::LogMessage(0, ID_FUSLOG_BINDING_STATUS_FOUND, wzFilePath);
- }
- else
- {
- // Cache the bind failure result before returning. Careful not to overwrite the bind result with the cache insertion result.
- HRESULT hrResult = hr;
- IfFailRet(CacheBindResult(pIdentity, hr));
- if (hr == S_OK)
- { // Cache now owns identity object lifetime.
- pIdentity.SuppressRelease();
- }
- hr = hrResult;
- }
- IfFailRet(hr);
- }
-
- NewHolder<CLRPrivResourcePathImpl> pResourcePath = new CLRPrivResourcePathImpl(wzFilePath);
- IfFailRet(pResourcePath->QueryInterface(__uuidof(ICLRPrivResource), (LPVOID*)&pResourceIL));
- pResourcePath.SuppressRelease();
-
- // Create an IBindResult and provide it to the new CLRPrivAssemblyAppX object.
- ReleaseHolder<IBindResult> pIBindResult = ToInterface<IBindResult>(
- new CLRPrivAssemblyBindResultWrapper(pIAssemblyName, wzFilePath, m_pFingerprintFactory));
-
-
- // Create the new CLRPrivAssemblyAppX object.
- NewHolder<CLRPrivAssemblyAppX> pAssemblyObj =
- new CLRPrivAssemblyAppX(pIdentity, this, pResourceIL, pIBindResult);
-
- //
- // Check cache. If someone beat us then use it instead; otherwise add new ICLRPrivAssembly.
- //
- do
- {
- // Because the read lock must be taken within a ForbidSuspend region, use AddInPhases.
- if (m_NameToAssemblyMap.CheckAddInPhases<ForbidSuspendThreadCrstHolder, CrstHolder>(
- pAssemblyObj, m_MapReadLock, m_MapWriteLock, pAssemblyObj.GetValue()))
- {
- { // Careful not to allow the cache insertion result to overwrite the bind result.
- HRESULT hrResult = hr;
- IfFailRet(CacheBindResult(pIdentity, hr));
- if (hr == S_OK)
- { // Cache now owns identity object lifetime, but ~CLRPrivBinderAssembly
- // can also remove the identity from the cache prior to cache deletion.
- pIdentity.SuppressRelease();
- }
- hr = hrResult;
- }
-
- pAssembly = pAssemblyObj.Extract();
- }
- else
- {
- ForbidSuspendThreadCrstHolder lock(&m_MapReadLock);
- pAssembly = clr::SafeAddRef(m_NameToAssemblyMap.Lookup(wzSimpleName));
- }
- }
- while (pAssembly == nullptr); // Keep looping until we find the existing one, or add a new one
- }
-
- _ASSERTE(pAssembly != nullptr);
-
- if (((dwAppXBindFlags & ABF_BindNI) == ABF_BindNI) &&
- m_fCanUseNativeImages)
- {
- //
- // Look to see if there's a native image available.
- //
-
- // Fire BindingNgenPhaseStart ETW event if enabled.
- {
- InlineSString<128> ssAssemblyName;
- FireEtwBindingNgenPhaseStart(
- (AppDomain::GetCurrentDomain()->GetId().m_dwId),
- LOADCTX_TYPE_HOSTED,
- ETWFieldUnused,
- ETWLoaderLoadTypeNotAvailable,
- NULL,
- FusionBind::GetAssemblyNameDisplayName(pIAssemblyName, ssAssemblyName, ASM_DISPLAYF_FULL).GetUnicode(),
- GetClrInstanceId());
- }
-
- ReleaseHolder<IBindResult> pIBindResultIL;
- IfFailRet(pAssembly->GetIBindResult(&pIBindResultIL));
- _ASSERTE(pIBindResultIL != nullptr);
-
- NewArrayHolder<WCHAR> wzZapSet = DuplicateStringThrowing(g_pConfig->ZapSet());
- NativeConfigData cfgData = {
- wzZapSet,
- PEFile::GetNativeImageConfigFlags()
- };
-
- IfFailRet(BindToNativeAssembly(
- pIBindResultIL, &cfgData, static_cast<IBindContext*>(this), fusion::logging::GetCurrentFusionBindLog()));
-
- // Ensure that the native image found above in BindToNativeAssembly is reported as existing in the CLRPrivAssembly object
- if (hr == S_OK)
- {
- ReleaseHolder<ICLRPrivResource> pNIImageResource;
- // This will make GetAvailableImageTypes return that a native image exists.
- IfFailRet(pAssembly->GetImageResource(ASSEMBLY_IMAGE_TYPE_NATIVE, NULL, &pNIImageResource));
-#ifdef _DEBUG
- DWORD dwImageTypes;
-
- _ASSERTE(SUCCEEDED(pAssembly->GetAvailableImageTypes(&dwImageTypes)));
- _ASSERTE((dwImageTypes & ASSEMBLY_IMAGE_TYPE_NATIVE) == ASSEMBLY_IMAGE_TYPE_NATIVE);
-#endif
- }
-
- // Fire BindingNgenPhaseEnd ETW event if enabled.
- {
- InlineSString<128> ssAssemblyName;
- FireEtwBindingNgenPhaseEnd(
- (AppDomain::GetCurrentDomain()->GetId().m_dwId),
- LOADCTX_TYPE_HOSTED,
- ETWFieldUnused,
- ETWLoaderLoadTypeNotAvailable,
- NULL,
- FusionBind::GetAssemblyNameDisplayName(pIAssemblyName, ssAssemblyName, ASM_DISPLAYF_FULL).GetUnicode(),
- GetClrInstanceId());
- }
-
- // BindToNativeAssembly can return S_FALSE, but this could be misleading.
- if (hr == S_FALSE)
- hr = S_OK;
- }
-
- if (SUCCEEDED(hr))
- {
- *ppAssembly = pAssembly.Extract();
- }
-
- return hr;
-}
-
-//=====================================================================================================================
-HRESULT CLRPrivBinderAppX::BindAppXAssemblyByName(
- IAssemblyName * pIAssemblyName,
- DWORD dwAppXBindFlags,
- ICLRPrivAssembly ** ppPrivAssembly)
-{
- STANDARD_VM_CONTRACT;
- HRESULT hr = S_OK;
-
- ReleaseHolder<CLRPrivAssemblyAppX> pAppXAssembly;
- IfFailRet(BindAppXAssemblyByNameWorker(pIAssemblyName, dwAppXBindFlags, &pAppXAssembly));
- IfFailRet(pAppXAssembly->QueryInterface(__uuidof(ICLRPrivAssembly), (LPVOID*)ppPrivAssembly));
-
- return hr;
-}
-
-//=====================================================================================================================
-HRESULT CLRPrivBinderAppX::PreBindAppXAssemblyByName(
- IAssemblyName * pIAssemblyName,
- DWORD dwAppXBindFlags,
- IBindResult ** ppIBindResult)
-{
- STANDARD_VM_CONTRACT;
- HRESULT hr = S_OK;
-
- VALIDATE_ARG_RET(pIAssemblyName != nullptr);
- VALIDATE_ARG_RET(ppIBindResult != nullptr);
-
-
- ReleaseHolder<CLRPrivAssemblyAppX> pAppXAssembly;
- IfFailRet(BindAppXAssemblyByNameWorker(pIAssemblyName, dwAppXBindFlags, &pAppXAssembly));
- IfFailRet(pAppXAssembly->GetIBindResult(ppIBindResult));
-
- return hr;
-}
-
-//=====================================================================================================================
-HRESULT CLRPrivBinderAppX::FindAssemblyBySpec(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- FORBID_FAULT;
- MODE_ANY;
- CAN_TAKE_LOCK;
- }
- CONTRACTL_END
-
- HRESULT hr = S_OK;
-
- AppDomain* pAppDomain = reinterpret_cast<AppDomain*>(pvAppDomain);
- AssemblySpec* pAssemblySpec = reinterpret_cast<AssemblySpec*>(pvAssemblySpec);
- VALIDATE_PTR_RET(pAppDomain);
- VALIDATE_PTR_RET(pAssemblySpec);
- VALIDATE_PTR_RET(pResult);
- VALIDATE_PTR_RET(ppAssembly);
-
- //
- // Follow the same order as a bind.
- //
-
- hr = CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT;
-
- if (FAILED(hr))
- {
- _ASSERTE(m_pFusionBinder != nullptr);
- hr = m_pFusionBinder->FindFusionAssemblyBySpec(pAppDomain, pAssemblySpec, m_fusionBindingScope, pResult, ppAssembly);
- }
-
- // See comment in code:CLRPrivBinderAppX::BindAssemblyByName for explanation of this conditional.
- if (hr == CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT)
- {
- if (FAILED(hr) && (m_pWinRTBinder != nullptr))
- {
- hr = m_pWinRTBinder->FindWinRTAssemblyBySpec(pAppDomain, pAssemblySpec, pResult, ppAssembly);
- }
-
- if (FAILED(hr))
- {
- AssemblyIdentity refId;
- IfFailRet(refId.Initialize(pAssemblySpec));
- bool fCheckParent = false;
-
- { // Check for a previously-recorded bind. Host callouts are now forbidden.
- ForbidSuspendThreadCrstHolder lock(&m_MapReadLock);
- BindingRecordMap::element_t const * pKeyVal = m_BindingRecordMap.LookupPtr(&refId);
-
- if (pKeyVal != nullptr)
- {
- //
- // Previous bind occurred. If a failure result is cached then the binder would
- // have tried the parent binder (if available) before returning.
- //
-
- AssemblyIdentity const & defId(*pKeyVal->Key());
- BindingRecord const & record(pKeyVal->Value());
-
- *ppAssembly = nullptr;
- *pResult = record.hr;
-
- if (SUCCEEDED(*pResult))
- {
- //
- // Previous bind succeeded. Get the corresponding ICLRPrivAssembly.
- //
-
- // Check this binder for a match. Host callouts are now forbidden.
- CLRPrivAssemblyAppX* pPrivAssembly = m_NameToAssemblyMap.Lookup(defId.Name);
-
- if (pPrivAssembly == nullptr)
- {
- _ASSERTE_MSG(false, "Should never see success value and a null CLRPrivAssemblyAppX pointer.");
- return (*pResult = E_UNEXPECTED);
- }
-
- _ASSERTE(pPrivAssembly->m_pIdentity != nullptr);
- _ASSERTE(pPrivAssembly->m_pIdentity == &defId);
-
- // Now check that the version and PKT values are compatible.
- *pResult = CLRPrivBinderUtil::VerifyBind(refId, *pPrivAssembly->m_pIdentity);
-
- if (SUCCEEDED(*pResult))
- {
- VERIFY(SUCCEEDED(pPrivAssembly->QueryInterface(__uuidof(ICLRPrivAssembly), (LPVOID*)ppAssembly)));
- }
-
- return S_OK;
- }
- else
- {
- //
- // Previous bind failed. Check the parent binder (if available), but do it outside of this binder's lock.
- //
-
- fCheckParent = true;
- }
- }
- else
- {
- //
- // No previous bind occurred. Do not check the parent binder since this could result
- // in an incorrect bind (if this binder would have bound to a different assembly).
- //
-
- return E_FAIL;
- }
- }
-
- if (fCheckParent && m_pParentBinder != nullptr)
- { // Check the parent (shared designer context) for a match.
- hr = m_pParentBinder->FindAssemblyBySpec(pAppDomain, pAssemblySpec, pResult, ppAssembly);
- }
- }
- }
-
- // There are three possibilities upon exit:
- // 1. Cache lookup failed, in which case FAILED(hr) == true
- // 2. A binding failure was cached, in which case (1) == false && FAILED(*pResult) == true
- // 3. A binding success was cached, in which case we must find an assembly:
- // (1) == false && (2) == false && *ppAssembly != nullptr
- _ASSERTE(FAILED(hr) || FAILED(*pResult) || *ppAssembly != nullptr);
- return hr;
-}
-
-//=====================================================================================================================
-// Record the binding result to support cache-based lookups (using ICLRPrivCachedBinder::FindAssemblyBySpec).
-
-HRESULT CLRPrivBinderAppX::CacheBindResult(
- AssemblyIdentity * pIdentity, // On success, will assume object lifetime ownership.
- HRESULT hrResult)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
-
- VALIDATE_PTR_RET(pIdentity);
-
- // Initialize the binding record.
- BindingRecord rec = { hrResult };
- BindingRecordMap::element_t newEntry(pIdentity, rec);
-
- // Because the read lock must be taken within a ForbidSusped region, use CheckAddInPhases.
- if (m_BindingRecordMap.CheckAddInPhases<ForbidSuspendThreadCrstHolder, CrstHolder>(
- newEntry, m_MapReadLock, m_MapWriteLock))
- {
- // Indicates that this identity object was cached.
- // Caller relinquishes object ownership.
- return S_OK;
- }
- else
- {
- // Pre-existing entry was found.
-
-#ifdef _DEBUG
- ForbidSuspendThreadCrstHolder lock(&m_MapReadLock);
- auto pExistingEntry = m_BindingRecordMap.LookupPtr(pIdentity);
- if (pExistingEntry != nullptr)
- {
- // It's possible for racing threads to try to cache their results;
- // just make sure that they got the same HRESULT.
- _ASSERTE(pExistingEntry->Value().hr == rec.hr);
- }
-#endif
-
- // Indicates that previous entry existed, and this identity object was not cached.
- // Caller retains object ownership.
- hr = S_FALSE;
- }
-
- return hr;
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivBinder::BindAssemblyByName
-
-HRESULT CLRPrivBinderAppX::BindAssemblyByName(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
-{
- STANDARD_BIND_CONTRACT;
- BinderHRESULT hr = S_OK;
- ReleaseHolder<ICLRPrivAssembly> pResult;
-
- VALIDATE_ARG_RET(pAssemblyName != nullptr && ppAssembly != nullptr);
-
- EX_TRY
- {
- hr = CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT;
-
- if (FAILED(hr))
- {
- _ASSERTE(m_pFusionBinder != nullptr);
- hr = m_pFusionBinder->BindFusionAssemblyByName(pAssemblyName, GetFusionBindingScope(), &pResult);
- }
-
- //
- // The fusion binder returns CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT only if it did not
- // recognize pAssemblyName as a FX assembly. Only then should other binders be consulted
- // (otherwise applications would be able to copy arbitrary FX assemblies into their AppX
- // package and use them directly).
- //
-
- if (hr == CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT)
- {
- if (FAILED(hr) && (m_pWinRTBinder != nullptr))
- {
- hr = m_pWinRTBinder->BindWinRTAssemblyByName(pAssemblyName, &pResult);
- }
-
- if (FAILED(hr))
- {
- hr = BindAppXAssemblyByName(pAssemblyName, ABF_Default, &pResult);
- }
-
- if (FAILED(hr) && (m_pParentBinder != nullptr))
- {
- hr = m_pParentBinder->BindAssemblyByName(pAssemblyName, &pResult);
- }
-
- _ASSERTE(FAILED(hr) || pResult != nullptr);
- }
- }
- EX_CATCH_HRESULT(hr);
-
- // Return if either the bind or the bind cache fails.
- IfFailRet(hr);
-
- // Success.
- *ppAssembly = pResult.Extract();
- return hr;
-}
-
-//=====================================================================================================================
-// Implements code:IBindContext::PreBind
-HRESULT CLRPrivBinderAppX::PreBind(
- IAssemblyName * pIAssemblyName,
- DWORD dwPreBindFlags,
- IBindResult ** ppIBindResult)
-{
- STANDARD_BIND_CONTRACT;
- BinderHRESULT hr = S_OK;
-
- VALIDATE_ARG_RET((dwPreBindFlags & ~(PRE_BIND_APPLY_POLICY)) == 0);
- VALIDATE_ARG_RET(pIAssemblyName != nullptr && ppIBindResult != nullptr);
-
- // Assert that we are only working with binder that supports Native Images context bits.
- _ASSERTE(m_fCanUseNativeImages);
-
- EX_TRY
- {
- hr = CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT;
-
- if (FAILED(hr))
- {
- hr = m_pFusionBinder->PreBindFusionAssemblyByName(pIAssemblyName, dwPreBindFlags, ppIBindResult);
- }
-
- if (FAILED(hr) && (m_pWinRTBinder != nullptr))
- {
- hr = m_pWinRTBinder->BindWinRTAssemblyByName(pIAssemblyName, ppIBindResult, TRUE);
- }
-
- if (FAILED(hr))
- {
- hr = PreBindAppXAssemblyByName(pIAssemblyName, ABF_BindIL, ppIBindResult);
- }
- }
- EX_CATCH_HRESULT(hr);
-
- if (FAILED(hr) && (m_pParentBinder != nullptr))
- {
- ReleaseHolder<IBindContext> pParentBindContext;
- hr = m_pParentBinder->QueryInterface(__uuidof(IBindContext), (LPVOID *)&pParentBindContext);
- if (SUCCEEDED(hr))
- {
- hr = pParentBindContext->PreBind(pIAssemblyName, dwPreBindFlags, ppIBindResult);
- }
- }
-
- return hr;
-}
-
-//=====================================================================================================================
-UINT_PTR CLRPrivBinderAppX::GetBinderID()
-{
- LIMITED_METHOD_CONTRACT;
- return reinterpret_cast<UINT_PTR>(this);
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivBinder::GetBinderID
-HRESULT CLRPrivBinderAppX::GetBinderID(
- UINT_PTR *pBinderId)
-{
- LIMITED_METHOD_CONTRACT;
-
- *pBinderId = GetBinderID();
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements code:IBindContext::IsDefaultContext
-HRESULT CLRPrivBinderAppX::IsDefaultContext()
-{
- LIMITED_METHOD_CONTRACT;
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivWinRtTypeBinder::FindAssemblyForWinRtTypeIfLoaded
-// Finds Assembly * for type in AppDomain * if it is loaded.
-// Returns NULL if assembly is not loaded or type is not found.
-//
-void *
-CLRPrivBinderAppX::FindAssemblyForWinRtTypeIfLoaded(
- void * pAppDomain,
- LPCUTF8 szNamespace,
- LPCUTF8 szClassName)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- FORBID_FAULT;
- MODE_ANY;
- }
- CONTRACTL_END
-
- void * pAssembly = nullptr;
- if (m_pWinRTBinder != nullptr)
- {
- pAssembly = (void *)m_pWinRTBinder->FindAssemblyForTypeIfLoaded(
- dac_cast<PTR_AppDomain>((AppDomain *)pAppDomain),
- szNamespace,
- szClassName);
- }
-
- if ((pAssembly == nullptr) && (m_pParentBinder != nullptr))
- {
- ReleaseHolder<ICLRPrivWinRtTypeBinder> pParentBinder =
- ToInterface_NoThrow<ICLRPrivWinRtTypeBinder>(m_pParentBinder.GetValue());
- // Parent binder should be another instance of code:CLRPrivBinderAppX class that implements the interface
- _ASSERTE(pParentBinder != nullptr);
-
- pAssembly = pParentBinder->FindAssemblyForWinRtTypeIfLoaded(
- pAppDomain,
- szNamespace,
- szClassName);
- }
-
- return pAssembly;
-}
-
-//=====================================================================================================================
-CLRPrivAssemblyAppX::CLRPrivAssemblyAppX(
- CLRPrivBinderUtil::AssemblyIdentity * pIdentity,
- CLRPrivBinderAppX *pBinder,
- ICLRPrivResource *pIResourceIL,
- IBindResult * pIBindResult)
- : m_pIdentity(pIdentity),
- m_pBinder(nullptr),
- m_pIResourceIL(nullptr),
- m_pIResourceNI(nullptr),
- m_pIBindResult(nullptr)
-{
- STANDARD_VM_CONTRACT;
-
- VALIDATE_PTR_THROW(pIdentity);
- VALIDATE_PTR_THROW(pBinder);
- VALIDATE_PTR_THROW(pIResourceIL);
- VALIDATE_PTR_THROW(pIBindResult);
-
- m_pBinder = clr::SafeAddRef(pBinder);
- m_pIResourceIL = clr::SafeAddRef(pIResourceIL);
- m_pIBindResult = clr::SafeAddRef(pIBindResult);
-}
-
-//=====================================================================================================================
-CLRPrivAssemblyAppX::~CLRPrivAssemblyAppX()
-{
- LIMITED_METHOD_CONTRACT;
- clr::SafeRelease(m_pIResourceNI);
-}
-
-//=====================================================================================================================
-LPCWSTR CLRPrivAssemblyAppX::GetSimpleName() const
-{
- LIMITED_METHOD_CONTRACT;
- return m_pIdentity->Name;
-}
-
-//=====================================================================================================================
-// Implements code:IUnknown::Release
-ULONG CLRPrivAssemblyAppX::Release()
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_CAN_TAKE_LOCK;
- _ASSERTE(m_cRef > 0);
-
- ULONG cRef;
-
- {
- // To achieve proper lifetime semantics, the name to assembly map elements' CLRPrivAssemblyAppX
- // instances are not ref counted. We cannot allow discovery of the object via m_NameToAssemblyMap
- // when the ref count is 0 (to prevent another thread to AddRef and Release it back to 0 in parallel).
- // All uses of the map are guarded by the map lock, so we have to decrease the ref count under that
- // lock (to avoid the chance that 2 threads are running Release to ref count 0 at once).
- // Host callouts are now forbidden.
- ForbidSuspendThreadCrstHolder lock(&m_pBinder->m_MapReadLock);
-
- cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- {
- m_pBinder->m_NameToAssemblyMap.Remove(GetSimpleName());
- m_pBinder->m_BindingRecordMap.Remove(m_pIdentity);
- }
- }
-
- if (cRef == 0)
- {
- delete this;
- }
-
- return cRef;
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivBinder::BindAssemblyByName
-HRESULT CLRPrivAssemblyAppX::BindAssemblyByName(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
-{
- WRAPPER_NO_CONTRACT;
-
- return m_pBinder->BindAssemblyByName(
- pAssemblyName,
- ppAssembly);
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivBinder::GetBinderID
-HRESULT CLRPrivAssemblyAppX::GetBinderID(
- UINT_PTR *pBinderId)
-{
- WRAPPER_NO_CONTRACT;
- return m_pBinder->GetBinderID(
- pBinderId);
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivAssembly::IsShareable
-HRESULT CLRPrivAssemblyAppX::IsShareable(
- BOOL * pbIsShareable)
-{
- LIMITED_METHOD_CONTRACT;
-
- VALIDATE_ARG_RET(pbIsShareable != nullptr);
-
- *pbIsShareable = FALSE;
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivAssembly::GetAvailableImageTypes
-HRESULT CLRPrivAssemblyAppX::GetAvailableImageTypes(
- LPDWORD pdwImageTypes)
-{
- LIMITED_METHOD_CONTRACT;
-
- VALIDATE_ARG_RET(pdwImageTypes != nullptr);
-
- *pdwImageTypes = 0;
-
- if (m_pIResourceIL != nullptr)
- *pdwImageTypes |= ASSEMBLY_IMAGE_TYPE_IL;
-
- if (m_pIResourceNI != nullptr)
- *pdwImageTypes |= ASSEMBLY_IMAGE_TYPE_NATIVE;
-
- return S_OK;
-}
-
-//=====================================================================================================================
-static ICLRPrivResource* GetResourceForBindResult(
- IBindResult * pIBindResult)
-{
- STANDARD_VM_CONTRACT;
- VALIDATE_ARG_THROW(pIBindResult != nullptr);
-
- WCHAR wzPath[_MAX_PATH];
- DWORD cchPath = NumItems(wzPath);
- ReleaseHolder<IAssemblyLocation> pIAssemLoc;
- IfFailThrow(pIBindResult->GetAssemblyLocation(&pIAssemLoc));
- IfFailThrow(pIAssemLoc->GetPath(wzPath, &cchPath));
- return ToInterface<ICLRPrivResource>(new CLRPrivResourcePathImpl(wzPath));
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivAssembly::GetImageResource
-HRESULT CLRPrivAssemblyAppX::GetImageResource(
- DWORD dwImageType,
- DWORD * pdwImageType,
- ICLRPrivResource ** ppIResource)
-{
- STANDARD_BIND_CONTRACT;
- HRESULT hr = S_OK;
-
- VALIDATE_ARG_RET(ppIResource != nullptr && m_pIBindResult != nullptr);
-
- EX_TRY
- {
- DWORD _dwImageType;
- if (pdwImageType == nullptr)
- pdwImageType = &_dwImageType;
-
- if ((dwImageType & ASSEMBLY_IMAGE_TYPE_NATIVE) == ASSEMBLY_IMAGE_TYPE_NATIVE)
- {
- ReleaseHolder<IBindResult> pIBindResultNI;
- if (m_pIResourceNI == nullptr)
- {
- if (SUCCEEDED(hr = m_pIBindResult->GetNativeImage(&pIBindResultNI, nullptr)) && pIBindResultNI != nullptr)
- {
- ReleaseHolder<ICLRPrivResource> pResourceNI = GetResourceForBindResult(pIBindResultNI);
- if (InterlockedCompareExchangeT<ICLRPrivResource *>(&m_pIResourceNI, pResourceNI, nullptr) == nullptr)
- pResourceNI.SuppressRelease();
- }
- else
- {
- IfFailGo(CLR_E_BIND_IMAGE_UNAVAILABLE);
- }
- }
-
- *ppIResource = clr::SafeAddRef(m_pIResourceNI);
- *pdwImageType = ASSEMBLY_IMAGE_TYPE_NATIVE;
- }
- else if ((dwImageType & ASSEMBLY_IMAGE_TYPE_IL) == ASSEMBLY_IMAGE_TYPE_IL)
- {
- *ppIResource = clr::SafeAddRef(m_pIResourceIL);
- *pdwImageType = ASSEMBLY_IMAGE_TYPE_IL;
- }
- else
- {
- hr = CLR_E_BIND_IMAGE_UNAVAILABLE;
- }
-
- ErrExit:
- ;
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
-
-//=====================================================================================================================
-// Implements code:ICLRPrivBinder::VerifyBind
-HRESULT CLRPrivBinderAppX::VerifyBind(
- IAssemblyName *pAssemblyName,
- ICLRPrivAssembly *pAssembly,
- ICLRPrivAssemblyInfo *pAssemblyInfo)
-{
- STANDARD_BIND_CONTRACT;
-
- HRESULT hr = S_OK;
-
- VALIDATE_ARG_RET(pAssemblyName!= nullptr && pAssemblyInfo != nullptr);
-
- UINT_PTR binderID;
- IfFailRet(pAssembly->GetBinderID(&binderID));
-
- if (binderID != GetBinderID())
- {
- return pAssembly->VerifyBind(pAssemblyName, pAssembly, pAssemblyInfo);
- }
-
- return CLRPrivBinderUtil::VerifyBind(pAssemblyName, pAssemblyInfo);
-}
-
-//=====================================================================================================================
-/*static*/
-LPCWSTR CLRPrivBinderAppX::NameToAssemblyMapTraits::GetKey(CLRPrivAssemblyAppX *pAssemblyAppX)
-{
- WRAPPER_NO_CONTRACT;
- _ASSERT(pAssemblyAppX != nullptr);
- return pAssemblyAppX->GetSimpleName();
-}
-
-//=====================================================================================================================
-HRESULT CLRPrivAssemblyAppX::GetIBindResult(
- IBindResult ** ppIBindResult)
-{
- STANDARD_VM_CONTRACT;
-
- VALIDATE_ARG_RET(ppIBindResult != nullptr);
- VALIDATE_CONDITION(m_pIBindResult != nullptr, return E_UNEXPECTED);
-
- *ppIBindResult = clr::SafeAddRef(m_pIBindResult);
-
- return S_OK;
-}
-
-#endif // !DACCESS_COMPILE
diff --git a/src/vm/clrprivbinderappx.h b/src/vm/clrprivbinderappx.h
deleted file mode 100644
index 4b241e0cc5..0000000000
--- a/src/vm/clrprivbinderappx.h
+++ /dev/null
@@ -1,364 +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.
-
-
-
-#pragma once
-
-#include "holder.h"
-#include "internalunknownimpl.h"
-#include "shash.h"
-#include "fusion.h"
-#include "clrprivbinding.h"
-#include "clrprivruntimebinders.h"
-#include "clrprivbinderfusion.h"
-#include "clrprivbinderwinrt.h"
-
-//=====================================================================================================================
-// Forward declarations
-class CLRPrivBinderAppX;
-class CLRPrivAssemblyAppX;
-
-class DomainAssembly;
-
-// Forward declaration of helper class used in native image binding.
-class CLRPrivAssemblyAppX_NIWrapper;
-
-typedef DPTR(CLRPrivBinderAppX) PTR_CLRPrivBinderAppX;
-
-//=====================================================================================================================
-class CLRPrivBinderAppX :
- public IUnknownCommon<ICLRPrivBinder, IBindContext, ICLRPrivWinRtTypeBinder>
-{
- friend class CLRPrivAssemblyAppX;
-
-public:
- //=============================================================================================
- // ICLRPrivBinder methods
-
- // Implements code:ICLRPrivBinder::BindAssemblyByName
- STDMETHOD(BindAssemblyByName)(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly);
-
- // Implements code:ICLRPrivBinder::VerifyBind
- STDMETHOD(VerifyBind)(
- IAssemblyName *pAssemblyName,
- ICLRPrivAssembly *pAssembly,
- ICLRPrivAssemblyInfo *pAssemblyInfo);
-
- // Implements code:ICLRPrivBinder::GetBinderFlags
- STDMETHOD(GetBinderFlags)(
- DWORD *pBinderFlags)
- {
- LIMITED_METHOD_CONTRACT;
-
- if (pBinderFlags == NULL)
- return E_INVALIDARG;
-
- *pBinderFlags = m_pParentBinder != NULL ? BINDER_DESIGNER_BINDING_CONTEXT : BINDER_NONE;
- return S_OK;
- }
-
- // Implements code:ICLRPrivBinder::GetBinderID
- STDMETHOD(GetBinderID)(
- UINT_PTR *pBinderId);
-
- STDMETHOD(FindAssemblyBySpec)(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly);
-
- //=============================================================================================
- // ICLRPrivWinRtTypeBinder methods
-
- // Implements code:ICLRPrivWinRtTypeBinder::FindAssemblyForWinRtTypeIfLoaded
- STDMETHOD_(void *, FindAssemblyForWinRtTypeIfLoaded)(
- void * pAppDomain,
- LPCUTF8 szNamespace,
- LPCUTF8 szClassName);
-
- //=============================================================================================
- // IBindContext methods
-
- // Implements code:IBindContext::PreBind
- STDMETHOD(PreBind)(
- IAssemblyName *pIAssemblyName,
- DWORD dwPreBindFlags,
- IBindResult **ppIBindResult);
-
- // Implements code:IBindContext::IsDefaultContext
- STDMETHOD(IsDefaultContext)();
-
- //=============================================================================================
- // Class methods
-
- //---------------------------------------------------------------------------------------------
- static
- CLRPrivBinderAppX * GetOrCreateBinder();
-
- static
- PTR_CLRPrivBinderAppX GetBinderOrNull()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return s_pSingleton;
- }
-
- static
- CLRPrivBinderAppX * CreateParentedBinder(
- ICLRPrivBinder * pParentBinder,
- CLRPrivTypeCacheWinRT * pWinRtTypeCache,
- LPCWSTR * rgwzAltPath,
- UINT cAltPaths,
- BOOL fCanUseNativeImages);
-
- //---------------------------------------------------------------------------------------------
- ~CLRPrivBinderAppX();
-
- //---------------------------------------------------------------------------------------------
- enum AppXBindFlags
- {
- ABF_BindIL = 1,
- ABF_BindNI = 2,
- ABF_Default = ABF_BindIL | ABF_BindNI,
- };
-
- //---------------------------------------------------------------------------------------------
- CLRPrivBinderFusion * GetFusionBinder()
- {
- LIMITED_METHOD_CONTRACT;
- return m_pFusionBinder;
- }
-
- PTR_CLRPrivBinderWinRT GetWinRtBinder()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return m_pWinRTBinder;
- }
-
-private:
- //---------------------------------------------------------------------------------------------
- // Binds within AppX packages only. BindAssemblyByName takes care of delegating to Fusion
- // when needed.
- HRESULT BindAppXAssemblyByNameWorker(
- IAssemblyName * pIAssemblyName,
- DWORD dwAppXBindFlags,
- CLRPrivAssemblyAppX ** ppAssembly);
-
- //---------------------------------------------------------------------------------------------
- // Binds within AppX packages only. BindAssemblyByName takes care of delegating to Fusion
- // when needed.
- HRESULT BindAppXAssemblyByName(
- IAssemblyName * pIAssemblyName,
- DWORD dwAppXBindFlags,
- ICLRPrivAssembly ** ppPrivAssembly);
-
- //---------------------------------------------------------------------------------------------
- // Binds within AppX packages only. PreBindAssemblyByName takes care of delegating to Fusion
- // when needed.
- HRESULT PreBindAppXAssemblyByName(
- IAssemblyName * pIAssemblyName,
- DWORD dwAppXBindFlags,
- IBindResult ** ppIBindResult);
-
- //---------------------------------------------------------------------------------------------
- UINT_PTR GetBinderID();
-
- //---------------------------------------------------------------------------------------------
- CLRPrivBinderAppX(LPCWSTR *rgwzAltPath, UINT cAltPaths);
-
- //---------------------------------------------------------------------------------------------
- HRESULT CheckGetAppXRT();
-
- //---------------------------------------------------------------------------------------------
- HRESULT CacheBindResult(
- CLRPrivBinderUtil::AssemblyIdentity * pIdentity,
- HRESULT hrResult);
-
- //---------------------------------------------------------------------------------------------
- CLRPrivBinderFusion::BindingScope GetFusionBindingScope();
-
- //---------------------------------------------------------------------------------------------
- Crst m_MapReadLock;
- Crst m_MapWriteLock;
-
- //---------------------------------------------------------------------------------------------
- // Identity to CLRPrivBinderAppX map
- struct NameToAssemblyMapTraits : public StringSHashTraits<CLRPrivAssemblyAppX, WCHAR, CaseInsensitiveStringCompareHash<WCHAR> >
- {
- static LPCWSTR GetKey(CLRPrivAssemblyAppX *pAssemblyAppX);
- };
- typedef SHash<NameToAssemblyMapTraits> NameToAssemblyMap;
-
- NameToAssemblyMap m_NameToAssemblyMap;
-
- //---------------------------------------------------------------------------------------------
- // Binding record map, used by cache lookup requests.
- struct BindingRecord
- {
- // This stores the result of the original bind request.
- HRESULT hr;
- };
-
- struct BindingRecordMapTraits : public MapSHashTraits<CLRPrivBinderUtil::AssemblyIdentity*, BindingRecord>
- {
- typedef MapSHashTraits<CLRPrivBinderUtil::AssemblyIdentity*, BindingRecord> base_t;
- typedef base_t::element_t element_t;
- typedef base_t::count_t count_t;
- typedef base_t::key_t;
-
- static count_t Hash(key_t k)
- {
- return HashiString(k->Name);
- }
-
- static BOOL Equals(key_t k1, key_t k2)
- {
- return SString::_wcsicmp(k1->Name, k2->Name) == 0;
- }
-
- static const bool s_DestructPerEntryCleanupAction = true;
- static inline void OnDestructPerEntryCleanupAction(element_t const & e)
- {
- delete [] e.Key();
- }
- };
- typedef SHash<BindingRecordMapTraits> BindingRecordMap;
-
- BindingRecordMap m_BindingRecordMap;
-
- //---------------------------------------------------------------------------------------------
- NewArrayHolder< NewArrayHolder<WCHAR> > m_rgAltPathsHolder;
- NewArrayHolder< WCHAR* > m_rgAltPaths;
- UINT m_cAltPaths;
-
-#ifdef FEATURE_FUSION
- BOOL m_fCanUseNativeImages;
- ReleaseHolder<IILFingerprintFactory> m_pFingerprintFactory;
-#endif
-
- //---------------------------------------------------------------------------------------------
- // ParentBinder is set only in designer binding context (forms a chain of binders)
- ReleaseHolder<ICLRPrivBinder> m_pParentBinder;
-
- ReleaseHolder<CLRPrivBinderFusion> m_pFusionBinder;
- PTR_CLRPrivBinderWinRT m_pWinRTBinder;
-
- //---------------------------------------------------------------------------------------------
- //static CLRPrivBinderAppX * s_pSingleton;
- SPTR_DECL(CLRPrivBinderAppX, s_pSingleton);
-
- //---------------------------------------------------------------------------------------------
- // Cache the binding scope in the constructor so that there is no need to call into a WinRT
- // API in a GC_NOTRIGGER scope later on.
- CLRPrivBinderFusion::BindingScope m_fusionBindingScope;
-}; // class CLRPrivBinderAppX
-
-
-//=====================================================================================================================
-class CLRPrivAssemblyAppX :
- public IUnknownCommon<ICLRPrivAssembly>
-{
- friend class CLRPrivBinderAppX;
-
-public:
- //---------------------------------------------------------------------------------------------
- CLRPrivAssemblyAppX(
- CLRPrivBinderUtil::AssemblyIdentity * pIdentity,
- CLRPrivBinderAppX *pBinder,
- ICLRPrivResource *pIResourceIL,
- IBindResult * pIBindResult);
-
- //---------------------------------------------------------------------------------------------
- ~CLRPrivAssemblyAppX();
-
- //---------------------------------------------------------------------------------------------
- // Implements code:IUnknown::Release
- STDMETHOD_(ULONG, Release)();
-
- //---------------------------------------------------------------------------------------------
- LPCWSTR GetSimpleName() const;
-
- //=============================================================================================
- // ICLRPrivBinder interface methods
-
- // Implements code:ICLRPrivBinder::BindAssemblyByName
- STDMETHOD(BindAssemblyByName)(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly);
-
- // Implements code:ICLRPrivBinder::VerifyBind
- STDMETHOD(VerifyBind)(
- IAssemblyName *pAssemblyName,
- ICLRPrivAssembly *pAssembly,
- ICLRPrivAssemblyInfo *pAssemblyInfo)
- {
- STANDARD_BIND_CONTRACT;
-
- HRESULT hr = S_OK;
-
- VALIDATE_PTR_RET(pAssemblyName);
- VALIDATE_PTR_RET(pAssembly);
- VALIDATE_PTR_RET(pAssemblyInfo);
-
- // Re-initialize the assembly identity with full identity contained in metadata.
- IfFailRet(m_pIdentity->Initialize(pAssemblyInfo));
-
- return m_pBinder->VerifyBind(pAssemblyName, pAssembly, pAssemblyInfo);
- }
-
- // Implements code:ICLRPrivBinder::GetBinderFlags
- STDMETHOD(GetBinderFlags)(
- DWORD *pBinderFlags)
- {
- LIMITED_METHOD_CONTRACT;
- return m_pBinder->GetBinderFlags(pBinderFlags);
- }
-
- // Implements code:ICLRPrivBinder::GetBinderID
- STDMETHOD(GetBinderID)(
- UINT_PTR *pBinderId);
-
- // Implements code:ICLRPrivBinder::FindAssemblyBySpec
- STDMETHOD(FindAssemblyBySpec)(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly)
- { STATIC_CONTRACT_WRAPPER; return m_pBinder->FindAssemblyBySpec(pvAppDomain, pvAssemblySpec, pResult, ppAssembly); }
-
- //=============================================================================================
- // ICLRPrivAssembly interface methods
-
- // Implements code:ICLRPrivAssembly::IsShareable
- STDMETHOD(IsShareable)(
- BOOL * pbIsShareable);
-
- // Implements code:ICLRPrivAssembly::GetAvailableImageTypes
- STDMETHOD(GetAvailableImageTypes)(
- LPDWORD pdwImageTypes);
-
- // Implements code:ICLRPrivAssembly::GetImageResource
- STDMETHOD(GetImageResource)(
- DWORD dwImageType,
- DWORD *pdwImageType,
- ICLRPrivResource ** ppIResource);
-
- //---------------------------------------------------------------------------------------------
- HRESULT GetIBindResult(
- IBindResult ** ppIBindResult);
-
-private:
- CLRPrivBinderUtil::AssemblyIdentity * m_pIdentity;
-
- ReleaseHolder<CLRPrivBinderAppX> m_pBinder;
-
- ReleaseHolder<ICLRPrivResource> m_pIResourceIL;
- // This cannot be a holder as there can be a race to assign to it.
- ICLRPrivResource * m_pIResourceNI;
-
- ReleaseHolder<IBindResult> m_pIBindResult;
-};
-
diff --git a/src/vm/clrprivbinderfusion.cpp b/src/vm/clrprivbinderfusion.cpp
deleted file mode 100644
index d31774f7b2..0000000000
--- a/src/vm/clrprivbinderfusion.cpp
+++ /dev/null
@@ -1,819 +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 "common.h" // precompiled header
-
-#ifndef DACCESS_COMPILE
-
-//=====================================================================================================================
-#include "assemblyspec.hpp"
-#include "corhdr.h"
-#include "domainfile.h"
-#include "fusion.h"
-#include "policy.h"
-#include "sstring.h"
-#include "stackingallocator.h"
-#include "threads.h"
-#include "clrprivbinderfusion.h"
-#include "clrprivbinderutil.h"
-#include "fusionlogging.h"
-
-using namespace CLRPrivBinderUtil;
-
-//=================================================================================================
-#define STDMETHOD_NOTIMPL(...) \
- STDMETHOD(__VA_ARGS__) \
- { \
- WRAPPER_NO_CONTRACT; \
- _ASSERTE_MSG(false, "Method not implemented."); \
- return E_NOTIMPL; \
- }
-
-//=================================================================================================
-static HRESULT PropagateOutStringArgument(
- __in LPCSTR pszValue,
- __out_ecount_opt(*pcchArg) LPWSTR pwzArg,
- __in DWORD cchArg,
- __out DWORD * pcchArg)
-{
- LIMITED_METHOD_CONTRACT;
-
- VALIDATE_PTR_RET(pszValue);
- VALIDATE_CONDITION((pwzArg == nullptr || cchArg > 0), return E_INVALIDARG);
-
- HRESULT hr = S_OK;
-
- if (pwzArg != nullptr)
- {
- DWORD cchWritten = WszMultiByteToWideChar(
- CP_UTF8, 0 /*flags*/, pszValue, -1, pwzArg, cchArg);
-
- if (cchWritten == 0)
- {
- hr = HRESULT_FROM_GetLastError();
- }
- else if (pcchArg != nullptr)
- {
- *pcchArg = cchWritten;
- }
- }
-
- if (pcchArg != nullptr && (pwzArg == nullptr || hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)))
- {
- *pcchArg = WszMultiByteToWideChar(
- CP_UTF8, 0 /*flags*/, pszValue, -1, nullptr, 0);
-
- if (*pcchArg == 0)
- {
- hr = HRESULT_FROM_GetLastError();
- }
- }
-
- return hr;
-}
-
-//=================================================================================================
-// This is needed to allow calls to IsAnyFrameworkAssembly in GC_NOTRIGGER/NO_FAULT regions (i.e.,
-// GC stack walking). CAssemblyName (which implements IAssemblyName in most other uses) allocates
-// during construction and so cannot be used in this scenario.
-
-class AssemblySpecAsIAssemblyName
- : public IAssemblyName
-{
-public:
- AssemblySpecAsIAssemblyName(
- AssemblySpec * pSpec)
- : m_pSpec(pSpec)
- { LIMITED_METHOD_CONTRACT; }
-
- //=============================================================================================
- // IUnknown methods
-
- // Not used by IsAnyFrameworkAssembly
- STDMETHOD_(ULONG, AddRef())
- {
- WRAPPER_NO_CONTRACT;
- _ASSERTE_MSG(false, "Method not implemented.");
- return E_NOTIMPL;
- }
-
- // Not used by IsAnyFrameworkAssembly
- STDMETHOD_(ULONG, Release())
- {
- WRAPPER_NO_CONTRACT;
- _ASSERTE_MSG(false, "Method not implemented.");
- return E_NOTIMPL;
- }
-
- // Not used by IsAnyFrameworkAssembly
- STDMETHOD_NOTIMPL(QueryInterface(
- REFIID riid,
- void **ppvObject));
-
- //=============================================================================================
- // IAssemblyName methods
-
- STDMETHOD_NOTIMPL(SetProperty(
- DWORD PropertyId,
- void const * pvProperty,
- DWORD cbProperty));
-
-#define ASSURE_SUFFICIENT_BUFFER(SRCSIZE) \
- do { \
- if ((pvProperty == nullptr) || (*pcbProperty < SRCSIZE)) { \
- *pcbProperty = SRCSIZE; \
- return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); \
- } \
- } while (false)
-
- STDMETHOD(GetProperty)(
- DWORD PropertyId,
- LPVOID pvProperty,
- LPDWORD pcbProperty)
- {
- LIMITED_METHOD_CONTRACT;
-
- VALIDATE_PTR_RET(pcbProperty);
- VALIDATE_CONDITION((pvProperty == nullptr) == (*pcbProperty == 0), return E_INVALIDARG);
-
- HRESULT hr = S_OK;
-
- switch (PropertyId)
- {
- case ASM_NAME_NAME:
- return PropagateOutStringArgument(m_pSpec->GetName(), (LPWSTR) pvProperty,
- *pcbProperty / sizeof(WCHAR), pcbProperty);
-
- case ASM_NAME_MAJOR_VERSION:
- ASSURE_SUFFICIENT_BUFFER(sizeof(USHORT));
- *reinterpret_cast<USHORT*>(pvProperty) = m_pSpec->GetContext()->usMajorVersion;
- *pcbProperty = sizeof(USHORT);
- return S_OK;
-
- case ASM_NAME_MINOR_VERSION:
- ASSURE_SUFFICIENT_BUFFER(sizeof(USHORT));
- *reinterpret_cast<USHORT*>(pvProperty) = m_pSpec->GetContext()->usMinorVersion;
- *pcbProperty = sizeof(USHORT);
- return S_OK;
-
- case ASM_NAME_BUILD_NUMBER:
- ASSURE_SUFFICIENT_BUFFER(sizeof(USHORT));
- *reinterpret_cast<USHORT*>(pvProperty) = m_pSpec->GetContext()->usBuildNumber;
- *pcbProperty = sizeof(USHORT);
- return S_OK;
-
- case ASM_NAME_REVISION_NUMBER:
- ASSURE_SUFFICIENT_BUFFER(sizeof(USHORT));
- *reinterpret_cast<USHORT*>(pvProperty) = m_pSpec->GetContext()->usRevisionNumber;
- *pcbProperty = sizeof(USHORT);
- return S_OK;
-
- case ASM_NAME_CULTURE:
- if (m_pSpec->GetContext()->szLocale == nullptr)
- {
- return FUSION_E_INVALID_NAME;
- }
- return PropagateOutStringArgument(m_pSpec->GetContext()->szLocale, (LPWSTR) pvProperty,
- *pcbProperty / sizeof(WCHAR), pcbProperty);
-
- case ASM_NAME_PUBLIC_KEY_TOKEN:
- {
- if (!m_pSpec->HasPublicKeyToken())
- {
- return FUSION_E_INVALID_NAME;
- }
-
- PBYTE pbSN;
- DWORD cbSN;
- m_pSpec->GetPublicKeyToken(&pbSN, &cbSN);
- ASSURE_SUFFICIENT_BUFFER(cbSN);
- memcpy_s(pvProperty, *pcbProperty, pbSN, cbSN);
- *pcbProperty = cbSN;
- }
- return S_OK;
-
- case ASM_NAME_RETARGET:
- ASSURE_SUFFICIENT_BUFFER(sizeof(BOOL));
- *reinterpret_cast<BOOL*>(pvProperty) = m_pSpec->IsRetargetable();
- *pcbProperty = sizeof(BOOL);
- return S_OK;
-
- default:
- _ASSERTE_MSG(false, "Unexpected property requested.");
- return E_INVALIDARG;
- }
- }
-
-#undef ASSURE_SUFFICIENT_BUFFER
-
- // Not used by IsAnyFrameworkAssembly
- STDMETHOD_NOTIMPL(Finalize());
-
- // Not used by IsAnyFrameworkAssembly
- STDMETHOD_NOTIMPL(GetDisplayName(
- __out_ecount_opt(*pccDisplayName) LPOLESTR szDisplayName,
- __inout LPDWORD pccDisplayName,
- DWORD dwDisplayFlags));
-
- // Not used by IsAnyFrameworkAssembly
- STDMETHOD_NOTIMPL(Reserved(
- REFIID refIID,
- IUnknown *pUnkReserved1,
- IUnknown *pUnkReserved2,
- LPCOLESTR szReserved,
- LONGLONG llReserved,
- LPVOID pvReserved,
- DWORD cbReserved,
- LPVOID *ppReserved));
-
-
- STDMETHOD(GetName)(
- __inout LPDWORD lpcwBuffer,
- __out_ecount_opt(*lpcwBuffer) WCHAR *pwzName)
- {
- LIMITED_METHOD_CONTRACT;
-
- VALIDATE_PTR_RET(lpcwBuffer);
- return PropagateOutStringArgument(
- m_pSpec->GetName(), pwzName, *lpcwBuffer, lpcwBuffer);
- }
-
- STDMETHOD(GetVersion)(
- LPDWORD pdwVersionHi,
- LPDWORD pdwVersionLow)
- {
- LIMITED_METHOD_CONTRACT;
-
- HRESULT hr = S_OK;
-
- VALIDATE_PTR_RET(pdwVersionHi);
- VALIDATE_PTR_RET(pdwVersionLow);
-
- AssemblyMetaDataInternal * pAMDI = m_pSpec->GetContext();
-
- *pdwVersionHi = MAKELONG(pAMDI->usMinorVersion, pAMDI->usMajorVersion);
- *pdwVersionLow = MAKELONG(pAMDI->usRevisionNumber, pAMDI->usBuildNumber);
-
- return S_OK;
- }
-
-
- // Exists exclusively to support fusion's IsSystem helper, which compares against 'mscorlib'.
- STDMETHOD(IsEqual)(
- IAssemblyName *pName,
- DWORD dwCmpFlags)
- {
- LIMITED_METHOD_CONTRACT;
-
- HRESULT hr = S_OK;
-
- VALIDATE_PTR_RET(pName);
-
- // This function is here just to support checks against the name 'mscorlib'.
- if ((dwCmpFlags & ASM_CMPF_NAME) != ASM_CMPF_NAME)
- {
- return E_NOTIMPL;
- }
-
- DWORD cchName1 = 0;
- WCHAR wzName1[_MAX_PATH];
- IfFailRet(pName->GetName(&cchName1, wzName1));
- _ASSERTE(SString::_wcsicmp(wzName1, W("mscorlib")) == 0);
-
- WCHAR wzName2[_MAX_PATH];
- DWORD cchName2 = WszMultiByteToWideChar(
- CP_UTF8, 0 /*flags*/, m_pSpec->GetName(), -1, wzName2, (int) (sizeof(wzName2) / sizeof(wzName2[0])));
-
- if (0 == cchName2)
- {
- _ASSERTE(HRESULT_FROM_GetLastError() != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
- return HRESULT_FROM_GetLastError();
- }
-
- if (cchName1 != cchName2)
- {
- return S_FALSE;
- }
-
- return SString::_wcsnicmp(wzName1, wzName2, cchName1) == 0
- ? S_OK
- : S_FALSE;
- }
-
- STDMETHOD_NOTIMPL(Clone(
- IAssemblyName **pName));
-
-private:
- AssemblySpec * m_pSpec;
-};
-
-//=====================================================================================================================
-HRESULT CLRPrivBinderFusion::FindFusionAssemblyBySpec(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- BindingScope kBindingScope,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly)
-{
- LIMITED_METHOD_CONTRACT;;
- HRESULT hr = S_OK;
-
- AppDomain* pAppDomain = reinterpret_cast<AppDomain*>(pvAppDomain);
- AssemblySpec* pAssemblySpec = reinterpret_cast<AssemblySpec*>(pvAssemblySpec);
- VALIDATE_PTR_RET(pAppDomain);
- VALIDATE_PTR_RET(pAssemblySpec);
- VALIDATE_PTR_RET(pResult);
- VALIDATE_PTR_RET(ppAssembly);
-
- if (pAssemblySpec->IsContentType_WindowsRuntime())
- {
- return CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT;
- }
-
- BOOL fIsSupportedInAppX;
- {
- AssemblySpecAsIAssemblyName asName(pAssemblySpec);
-
- if (Fusion::Util::IsAnyFrameworkAssembly(&asName, &fIsSupportedInAppX) != S_OK)
- { // Not a framework assembly identity.
- IfFailRet(CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT);
- }
- }
-
- if (kBindingScope == kBindingScope_FrameworkSubset)
- { // We should allow only some framework assemblies to load
-
- // DevMode has to allow all FX assemblies, not just a subset - see code:PreBind for more info
- {
- // Disabling for now, as it causes too many violations.
- //CONTRACT_VIOLATION(GCViolation | FaultViolation | ModeViolation);
- //_ASSERTE(!AppX::IsAppXDesignMode());
- }
-
- if (!fIsSupportedInAppX)
- { // Assembly is blocked for AppX, fail the load
- *pResult = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- *ppAssembly = nullptr;
- return S_OK;
- }
- }
-
- return FindAssemblyBySpec(pvAppDomain, pvAssemblySpec, pResult, ppAssembly);
-}
-
-//=====================================================================================================================
-static
-PEAssembly * FindCachedFile(AppDomain * pDomain, AssemblySpec * pSpec)
-{
- // Look for cached bind result. Prefer a cached DomainAssembly, as it takes priority over a
- // cached PEAssembly (which can be different from the one associated with the DomainAssembly).
- DomainAssembly * pDomainAssembly = pDomain->FindCachedAssembly(pSpec, FALSE);
- return (pDomainAssembly != nullptr)
- ? (pDomainAssembly->GetFile())
- : (pDomain->FindCachedFile(pSpec, FALSE));
-}
-
-//=====================================================================================================================
-// There is no need to create a separate binding record, since we can always just look in the AppDomain's
-// AssemblySpecBindingCache for an answer (which is precisely what this function does).
-
-HRESULT CLRPrivBinderFusion::FindAssemblyBySpec(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly)
-{
- LIMITED_METHOD_CONTRACT;;
- HRESULT hr = S_OK;
-
- AppDomain* pAppDomain = reinterpret_cast<AppDomain*>(pvAppDomain);
- AssemblySpec* pAssemblySpec = reinterpret_cast<AssemblySpec*>(pvAssemblySpec);
- VALIDATE_PTR_RET(pAppDomain);
- VALIDATE_PTR_RET(pAssemblySpec);
- VALIDATE_PTR_RET(pResult);
- VALIDATE_PTR_RET(ppAssembly);
-
- // For the Architecture property, canonicalize peMSIL to peNone (which are considered equivalent),
- // to ensure consistent lookups in the AssemblySpecBindingCache for the CLRPrivBinderFusion binder.
- if (pAssemblySpec->GetPEKIND() == peMSIL)
- {
- pAssemblySpec->SetPEKIND(peNone);
- }
-
- PEAssembly * pPEAssembly = FindCachedFile(pAppDomain, pAssemblySpec);
- if (pPEAssembly == nullptr)
- {
- return E_FAIL;
- }
-
- // Could be racing with another thread that has just added the PEAssembly to the binding cache
- // but not yet allocated and assigned a host assembly.
- if (!pPEAssembly->HasHostAssembly())
- {
- return E_FAIL;
- }
-
- *pResult = S_OK;
- *ppAssembly = clr::SafeAddRef(pPEAssembly->GetHostAssembly());
-
- return S_OK;
-}
-
-//=====================================================================================================================
-HRESULT CLRPrivBinderFusion::BindAssemblyByNameWorker(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
-{
- STANDARD_VM_CONTRACT;
- PRECONDITION(CheckPointer(pAssemblyName));
- PRECONDITION(CheckPointer(ppAssembly));
-
- HRESULT hr = S_OK;
-
- AppDomain * pCurDomain = AppDomain::GetCurrentDomain();
- if (pCurDomain == nullptr)
- ThrowHR(E_UNEXPECTED);
-
- AssemblySpec prePolicySpec;
- AssemblySpec postPolicySpec;
-
- prePolicySpec.InitializeSpec(pAssemblyName);
-
- // For the Architecture property, canonicalize peMSIL to peNone (which are considered equivalent),
- // to ensure consistent lookups in the AssemblySpecBindingCache for the CLRPrivBinderFusion binder.
- if (prePolicySpec.GetPEKIND() == peMSIL)
- {
- prePolicySpec.SetPEKIND(peNone);
- }
-
- AssemblySpec * pBindSpec = &prePolicySpec;
- PEAssemblyHolder pPEAssembly = clr::SafeAddRef(FindCachedFile(pCurDomain, pBindSpec));
-
- if (pPEAssembly == nullptr)
- {
- // Early on in domain setup there may not be a fusion context, so skip ApplyPolicy then.
- _ASSERTE(pCurDomain->GetFusionContext() != nullptr || prePolicySpec.IsMscorlib());
- if (pCurDomain->GetFusionContext() != nullptr)
- {
- ReleaseHolder<IAssemblyName> pPolicyAssemblyName;
- DWORD dwPolicyApplied = 0;
- ApplyPolicy(pAssemblyName, pCurDomain->GetFusionContext(), nullptr, &pPolicyAssemblyName, nullptr, nullptr, &dwPolicyApplied);
-
- if (dwPolicyApplied != 0)
- {
- postPolicySpec.InitializeSpec(pPolicyAssemblyName);
- pBindSpec = &postPolicySpec;
- pPEAssembly = clr::SafeAddRef(FindCachedFile(pCurDomain, pBindSpec));
- }
- }
-
- if (pPEAssembly == nullptr)
- {
- // Trigger a load.
- pPEAssembly = pCurDomain->BindAssemblySpec(
- pBindSpec, // AssemblySpec
- TRUE, // ThrowOnFileNotFound
- FALSE, // RaisePrebindEvents
- nullptr, // CallerStackMark
- nullptr, // AssemblyLoadSecurity
- FALSE); // fUseHostBinderIfAvailable - to avoid infinite recursion
- _ASSERTE(FindCachedFile(pCurDomain, pBindSpec) == pPEAssembly || pBindSpec->IsMscorlib());
- }
-
- // If a post-policy spec was used, add the pre-policy spec to the binding cache
- // so that it can be found by FindAssemblyBySpec.
- if (&prePolicySpec != pBindSpec)
- {
- // Failure to add simply means someone else beat us to it. In that case
- // the FindCachedFile call below (after catch block) will update result
- // to the cached value.
- INDEBUG(BOOL fRes =) pCurDomain->AddFileToCache(&prePolicySpec, pPEAssembly, TRUE /* fAllowFailure */);
- _ASSERTE(!fRes || prePolicySpec.IsMscorlib() || FindCachedFile(pCurDomain, &prePolicySpec) == pPEAssembly);
- }
-
- // Ensure that the assembly is discoverable through a consistent assembly name (the assembly def name of the assembly)
- AssemblySpec specAssemblyDef;
- specAssemblyDef.InitializeSpec(pPEAssembly);
-
- // It is expected that all assemlbies found here will be unified assemblies, and therefore have a public key.
- _ASSERTE(specAssemblyDef.IsStrongNamed());
-
- // Convert public key into the format that matches the garaunteed cache in the AssemblySpecBindingCache ... see the extended logic
- // in Module::GetAssemblyIfLoaded.
- if (specAssemblyDef.IsStrongNamed() && specAssemblyDef.HasPublicKey())
- {
- specAssemblyDef.ConvertPublicKeyToToken();
- }
- pCurDomain->AddFileToCache(&specAssemblyDef, pPEAssembly, TRUE);
- }
-
- if (!pPEAssembly->HasHostAssembly())
- {
- // This can happen if we just loaded the PEAssembly with BindAssemblySpec above, or if the PEAssembly
- // Was not loaded through this binder. (NGEN Case)
-
- // Note: There can be multiple PEAssembly objects for the same file, however we have to create unique
- // CLRPrivAssemblyFusion object, otherwise code:AppDomain::FindAssembly will not recognize the duplicates which
- // will lead to creation of multiple code:DomainAssembly objects for the same file in the same AppDomain.
-
- InlineSString<128> ssPEAssemblyName;
- FusionBind::GetAssemblyNameDisplayName(pPEAssembly->GetFusionAssemblyName(), ssPEAssemblyName, ASM_DISPLAYF_FULL);
- NewHolder<CLRPrivAssemblyFusion> pAssemblyObj = new CLRPrivAssemblyFusion(ssPEAssemblyName.GetUnicode(), this);
-
- {
- CrstHolder lock(&m_SetHostAssemblyLock);
- if (!pPEAssembly->HasHostAssembly())
- {
- // Add the host assembly to the PEAssembly.
- pPEAssembly->SetHostAssembly(pAssemblyObj.Extract());
- }
- }
- }
-
- // Trigger a load so that a DomainAssembly is associated with the ICLRPrivAssembly created above.
- pPEAssembly = clr::SafeAddRef(pCurDomain->LoadDomainAssembly(pBindSpec, pPEAssembly, FILE_LOADED)->GetFile());
-
- _ASSERTE(pPEAssembly != nullptr);
- _ASSERTE(pPEAssembly->HasHostAssembly());
- _ASSERTE(pCurDomain->FindAssembly(pPEAssembly->GetHostAssembly()) != nullptr);
-
- fusion::logging::LogMessage(0, ID_FUSLOG_BINDING_STATUS_FOUND, pPEAssembly->GetPath().GetUnicode());
-
- *ppAssembly = clr::SafeAddRef(pPEAssembly->GetHostAssembly());
-
- return hr;
-}
-
-//=====================================================================================================================
-void CLRPrivBinderFusion::BindMscorlib(
- PEAssembly * pPEAssembly)
-{
- STANDARD_VM_CONTRACT;
-
-#ifdef _DEBUG
- NewArrayHolder<WCHAR> dbg_wszAssemblySimpleName;
- _ASSERTE(SUCCEEDED(fusion::util::GetProperty(pPEAssembly->GetFusionAssemblyName(), ASM_NAME_NAME, &dbg_wszAssemblySimpleName)));
-
- _ASSERTE(wcscmp(dbg_wszAssemblySimpleName, W("mscorlib")) == 0);
-#endif //_DEBUG
-
- NewHolder<CLRPrivAssemblyFusion> pPrivAssembly = new CLRPrivAssemblyFusion(W("mscorlib"), this);
-
- pPEAssembly->SetHostAssembly(pPrivAssembly.Extract());
-}
-
-//=====================================================================================================================
-HRESULT CLRPrivBinderFusion::BindFusionAssemblyByName(
- IAssemblyName * pAssemblyName,
- BindingScope kBindingScope,
- ICLRPrivAssembly ** ppAssembly)
-{
- STANDARD_VM_CONTRACT;
- HRESULT hr = S_OK;
-
- fusion::logging::StatusScope logStatus(0, ID_FUSLOG_BINDING_STATUS_FRAMEWORK, &hr);
-
- DWORD dwContentType = AssemblyContentType_Default;
- IfFailRet(fusion::util::GetProperty(pAssemblyName, ASM_NAME_CONTENT_TYPE, &dwContentType));
- if ((hr == S_OK) && (dwContentType != AssemblyContentType_Default))
- { // Not a NetFX content type.
- IfFailRet(CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT);
- }
-
- BOOL fIsSupportedInAppX;
- if (Fusion::Util::IsAnyFrameworkAssembly(pAssemblyName, &fIsSupportedInAppX) != S_OK)
- { // Not a framework assembly identity.
- IfFailRet(CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT);
- }
- if (kBindingScope == kBindingScope_FrameworkSubset)
- { // We should allow only some framework assemblies to load
-
- // DevMode has to allow all FX assemblies, not just a subset - see code:PreBind for more info
- _ASSERTE(!AppX::IsAppXDesignMode());
-
- if (!fIsSupportedInAppX)
- { // Assembly is blocked for AppX, fail the load
- fusion::logging::LogMessage(0, ID_FUSLOG_BINDING_STATUS_FX_ASSEMBLY_BLOCKED);
-
- IfFailRet(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
- }
- }
-
- return (hr = BindAssemblyByNameWorker(pAssemblyName, ppAssembly));
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivBinder::BindAssemblyByName
-HRESULT CLRPrivBinderFusion::BindAssemblyByName(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
-{
- WRAPPER_NO_CONTRACT;
- return BindAssemblyByNameWorker(
- pAssemblyName,
- ppAssembly);
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivBinder::GetBinderID
-HRESULT CLRPrivBinderFusion::GetBinderID(
- UINT_PTR *pBinderId)
-{
- LIMITED_METHOD_CONTRACT;
-
- *pBinderId = (UINT_PTR)this;
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements code:IBindContext::PreBind
-HRESULT CLRPrivBinderFusion::PreBind(
- IAssemblyName * pIAssemblyName,
- DWORD dwPreBindFlags,
- IBindResult ** ppIBindResult)
-{
- STANDARD_BIND_CONTRACT;
- PRECONDITION(CheckPointer(pIAssemblyName));
- PRECONDITION(CheckPointer(ppIBindResult));
-
- HRESULT hr = S_OK;
-
- BOOL fIsSupportedInAppX;
- if (Fusion::Util::IsAnyFrameworkAssembly(pIAssemblyName, &fIsSupportedInAppX) != S_OK)
- { // Not a framework assembly identity.
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
-
- EX_TRY
- {
- // Create new IL binding scope.
- fusion::logging::BindingScope defaultScope(pIAssemblyName, FUSION_BIND_LOG_CATEGORY_DEFAULT);
-
- // Ideally the caller would give us arg kBindingContext like in code:BindFusionAssemblyByName, so we can give the same answer.
- // That is not easy, so we will make the decision here:
- // - DevMode will allow all FX assemblies (that covers designer binding context scenario for designers that need to
- // load WPF with ngen images for perf reasons).
- // We know that the real bind via code:BindFusionAssemblyByName will succeed for the assemblies (because we are in DevMode).
- // - Normal mode (non-DevMode) we will allow only subset of FX assemblies.
- // It implies that designer binding context (used by debuggers) will not use ngen images for blocked FX assemblies
- // (transitively). That is acceptable performance trade-off.
- if (!AppX::IsAppXDesignMode())
- { // We should allow only some framework assemblies to load
- if (!fIsSupportedInAppX)
- { // Assembly is blocked for AppX, fail the load
- fusion::logging::LogMessage(0, ID_FUSLOG_BINDING_STATUS_FX_ASSEMBLY_BLOCKED);
-
- hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
- }
-
- if (SUCCEEDED(hr))
- {
- AppDomain * pDomain = AppDomain::GetCurrentDomain();
- ReleaseHolder<IBindContext> pIBindContext;
- if (SUCCEEDED(hr = GetBindContextFromApplicationContext(pDomain->CreateFusionContext(), &pIBindContext)))
- {
- hr = pIBindContext->PreBind(pIAssemblyName, dwPreBindFlags, ppIBindResult);
- }
- }
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
-//=====================================================================================================================
-HRESULT CLRPrivBinderFusion::PreBindFusionAssemblyByName(
- IAssemblyName *pIAssemblyName,
- DWORD dwPreBindFlags,
- IBindResult **ppIBindResult)
-{
- STANDARD_VM_CONTRACT;
- HRESULT hr = S_OK;
-
- DWORD dwContentType = AssemblyContentType_Default;
- IfFailRet(fusion::util::GetProperty(pIAssemblyName, ASM_NAME_CONTENT_TYPE, &dwContentType));
- if ((hr == S_OK) && (dwContentType != AssemblyContentType_Default))
- { // Not a NetFX content type.
- IfFailRet(CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT);
- }
-
- IfFailRet(PreBind(pIAssemblyName, dwPreBindFlags, ppIBindResult));
- _ASSERTE(*ppIBindResult != nullptr);
-
- if (*ppIBindResult == nullptr)
- IfFailRet(E_UNEXPECTED);
-
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements code:IBindContext::IsDefaultContext
-HRESULT CLRPrivBinderFusion::IsDefaultContext()
-{
- STANDARD_BIND_CONTRACT;
- return S_OK;
-}
-
-//=====================================================================================================================
-CLRPrivBinderFusion::~CLRPrivBinderFusion()
-{
- WRAPPER_NO_CONTRACT;
-}
-
-//=====================================================================================================================
-CLRPrivAssemblyFusion::CLRPrivAssemblyFusion(
- LPCWSTR wszName,
- CLRPrivBinderFusion * pBinder)
- : m_pBinder(clr::SafeAddRef(pBinder)),
- m_wszName(DuplicateStringThrowing(wszName))
-{
- STANDARD_VM_CONTRACT;
-}
-
-//=====================================================================================================================
-LPCWSTR CLRPrivAssemblyFusion::GetName() const
-{
- LIMITED_METHOD_CONTRACT;
-
- return m_wszName;
-}
-
-//=====================================================================================================================
-// Implements code:IUnknown::Release
-ULONG CLRPrivAssemblyFusion::Release()
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_CAN_TAKE_LOCK;
- _ASSERTE(m_cRef > 0);
-
- ULONG cRef = InterlockedDecrement(&m_cRef);
-
- if (cRef == 0)
- {
- delete this;
- }
-
- return cRef;
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivBinder::BindAssemblyByName
-HRESULT CLRPrivAssemblyFusion::BindAssemblyByName(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
-{
- WRAPPER_NO_CONTRACT;
- return m_pBinder->BindAssemblyByName(
- pAssemblyName,
- ppAssembly);
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivBinder::GetBinderID
-HRESULT CLRPrivAssemblyFusion::GetBinderID(
- UINT_PTR *pBinderId)
-{
- LIMITED_METHOD_CONTRACT;
-
- *pBinderId = reinterpret_cast<UINT_PTR>(m_pBinder.GetValue());
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivAssembly::IsShareable
-HRESULT CLRPrivAssemblyFusion::IsShareable(
- BOOL * pbIsShareable)
-{
- LIMITED_METHOD_CONTRACT;
- *pbIsShareable = TRUE; // These things are only used in the AppX scenario, where all fusion assemblies are unified, shareable assemblies.
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivAssembly::GetAvailableImageTypes
-HRESULT CLRPrivAssemblyFusion::GetAvailableImageTypes(
- LPDWORD pdwImageTypes)
-{
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(!"CLRPrivAssemblyFusion::GetAvailableImageTypes");
- return E_NOTIMPL;
-}
-
-//=====================================================================================================================
-// Implements code:ICLRPrivAssembly::GetImageResource
-HRESULT CLRPrivAssemblyFusion::GetImageResource(
- DWORD dwImageType,
- DWORD *pdwImageType,
- ICLRPrivResource ** ppIResource)
-{
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(!"CLRPrivAssemblyFusion::GetImageResource");
- return E_NOTIMPL;
-}
-
-#endif // !DACCESS_COMPILE
-
diff --git a/src/vm/clrprivbinderfusion.h b/src/vm/clrprivbinderfusion.h
deleted file mode 100644
index 3cf3694e4f..0000000000
--- a/src/vm/clrprivbinderfusion.h
+++ /dev/null
@@ -1,228 +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.
-
-
-
-#pragma once
-
-#include "holder.h"
-#include "internalunknownimpl.h"
-#include "shash.h"
-#include "clrprivbinding.h"
-#include "clrprivruntimebinders.h"
-
-//=====================================================================================================================
-// Forward declarations
-class CLRPrivBinderFusion;
-class CLRPrivAssemblyFusion;
-
-class PEAssembly;
-class DomainAssembly;
-struct IMDInternalImport;
-
-//=====================================================================================================================
-class CLRPrivBinderFusion :
- public IUnknownCommon<ICLRPrivBinder, IBindContext>
-{
- friend class CLRPrivAssemblyFusion;
-
-public:
- // Scope for the bind operation
- enum BindingScope
- {
- // Binds only to subset of framework that is not on the black list (non-FX assemblies bindings are rejected)
- kBindingScope_FrameworkSubset,
- // Binds to all framework assemblies (incl. those on the black list) (non-FX assemblies bindings are rejected)
- // Used by designer binding context and in DevMode
- kBindingScope_FrameworkAll
- };
-
-public:
- //=============================================================================================
- // ICLRPrivBinder methods
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::BindAssemblyByName
- STDMETHOD(BindAssemblyByName(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly));
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::VerifyBind
- STDMETHOD(VerifyBind)(
- IAssemblyName *pAssemblyName,
- ICLRPrivAssembly *pAssembly,
- ICLRPrivAssemblyInfo *pAssemblyInfo)
- {
- LIMITED_METHOD_CONTRACT;
- if (pAssemblyName == nullptr || pAssembly == nullptr || pAssemblyInfo == nullptr)
- return E_INVALIDARG;
- return S_OK;
- }
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::GetBinderFlags
- STDMETHOD(GetBinderFlags)(
- DWORD *pBinderFlags)
- {
- LIMITED_METHOD_CONTRACT;
- *pBinderFlags = BINDER_FINDASSEMBLYBYSPEC_REQUIRES_EXACT_MATCH;
- return S_OK;
- }
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::GetBinderID
- STDMETHOD(GetBinderID)(
- UINT_PTR *pBinderId);
-
- STDMETHOD(FindAssemblyBySpec)(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly);
-
- //=============================================================================================
- // IBindContext methods
-
- // Implements code:IBindContext::PreBind
- STDMETHOD(PreBind)(
- IAssemblyName *pIAssemblyName,
- DWORD dwPreBindFlags,
- IBindResult **ppIBindResult);
-
- // Implements code:IBindContext::IsDefaultContext
- STDMETHOD(IsDefaultContext)();
-
- //=============================================================================================
- // Class methods
-
- //---------------------------------------------------------------------------------------------
- CLRPrivBinderFusion()
- : m_SetHostAssemblyLock(CrstLeafLock)
- { STANDARD_VM_CONTRACT; }
-
- //---------------------------------------------------------------------------------------------
- ~CLRPrivBinderFusion();
-
- //---------------------------------------------------------------------------------------------
- HRESULT FindFusionAssemblyBySpec(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- BindingScope kBindingScope,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly);
-
- //---------------------------------------------------------------------------------------------
- HRESULT BindFusionAssemblyByName(
- IAssemblyName * pAssemblyName,
- BindingScope kBindingScope,
- ICLRPrivAssembly ** ppAssembly);
-
- //---------------------------------------------------------------------------------------------
- HRESULT PreBindFusionAssemblyByName(
- IAssemblyName * pIAssemblyName,
- DWORD dwPreBindFlags,
- IBindResult ** ppIBindResult);
-
- //---------------------------------------------------------------------------------------------
- // Binds mscorlib.dll
- void BindMscorlib(
- PEAssembly * pPEAssembly);
-
-private:
- //---------------------------------------------------------------------------------------------
- HRESULT BindAssemblyByNameWorker(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly);
-
-private:
- //---------------------------------------------------------------------------------------------
- // This lock is used to serialize assigning ICLRPrivAssembly instances to PEAssembly objects.
- Crst m_SetHostAssemblyLock;
-
-}; // class CLRPrivBinderFusion
-
-//=====================================================================================================================
-class CLRPrivAssemblyFusion :
- public IUnknownCommon<ICLRPrivAssembly>
-{
-public:
- //---------------------------------------------------------------------------------------------
- CLRPrivAssemblyFusion(
- LPCWSTR wszName,
- CLRPrivBinderFusion * pBinder);
-
- //---------------------------------------------------------------------------------------------
- LPCWSTR GetName() const;
-
- //---------------------------------------------------------------------------------------------
- // Implements code:IUnknown::Release
- STDMETHOD_(ULONG, Release)();
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::BindAssemblyByName
- STDMETHOD(BindAssemblyByName)(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly);
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivAssembly::IsShareable
- STDMETHOD(IsShareable)(
- BOOL * pbIsShareable);
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivAssembly::GetAvailableImageTypes
- STDMETHOD(GetAvailableImageTypes)(
- LPDWORD pdwImageTypes);
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivAssembly::GetImageResource
- STDMETHOD(GetImageResource)(
- DWORD dwImageType,
- DWORD *pdwImageType,
- ICLRPrivResource ** ppIResource);
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::VerifyBind
- STDMETHOD(VerifyBind)(
- IAssemblyName *pAssemblyName,
- ICLRPrivAssembly *pAssembly,
- ICLRPrivAssemblyInfo *pAssemblyInfo)
- {
- WRAPPER_NO_CONTRACT;
- return m_pBinder->VerifyBind(pAssemblyName, pAssembly, pAssemblyInfo);
- }
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::GetBinderFlags
- STDMETHOD(GetBinderFlags)(
- DWORD *pBinderFlags)
- {
- LIMITED_METHOD_CONTRACT;
- return m_pBinder->GetBinderFlags(pBinderFlags);
- }
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::GetBinderID
- STDMETHOD(GetBinderID)(
- UINT_PTR *pBinderId);
-
- //---------------------------------------------------------------------------------------------
- // Implements code:ICLRPrivBinder::FindAssemblyBySpec
- STDMETHOD(FindAssemblyBySpec)(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly)
- { STATIC_CONTRACT_WRAPPER; return m_pBinder->FindAssemblyBySpec(pvAppDomain, pvAssemblySpec, pResult, ppAssembly); }
-
-protected:
- //---------------------------------------------------------------------------------------------
- // The fusion binder. Need to keep it around as long as this object is around.
- ReleaseHolder<CLRPrivBinderFusion> m_pBinder;
-
- // Full display name of the assembly - used to avoid duplicate CLRPrivAssemblyFusion objects
- NewArrayHolder<WCHAR> m_wszName;
-
-}; // class CLRPrivAssemblyFusion
diff --git a/src/vm/clrprivbinderloadfile.cpp b/src/vm/clrprivbinderloadfile.cpp
deleted file mode 100644
index 20d05688f9..0000000000
--- a/src/vm/clrprivbinderloadfile.cpp
+++ /dev/null
@@ -1,264 +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 "common.h" // precompiled header
-#include "clrprivbinderutil.h"
-#include "clrprivbinderloadfile.h"
-#include "clrprivbinderfusion.h"
-#include "clrprivbinderappx.h"
-#include "fusionlogging.h"
-
-using namespace CLRPrivBinderUtil;
-
-#ifndef DACCESS_COMPILE
-
-using namespace CLRPrivBinderUtil;
-using clr::SafeAddRef;
-using clr::SafeRelease;
-
-//=====================================================================================================================
-CLRPrivBinderLoadFile * CLRPrivBinderLoadFile::s_pSingleton = nullptr;
-
-
-//=====================================================================================================================
-CLRPrivBinderLoadFile * CLRPrivBinderLoadFile::GetOrCreateBinder()
-{
- STANDARD_VM_CONTRACT;
- HRESULT hr = S_OK;
-
- if (s_pSingleton == nullptr)
- {
- ReleaseHolder<CLRPrivBinderLoadFile> pBinder = SafeAddRef(new CLRPrivBinderLoadFile());
-
- CLRPrivBinderAppX * pAppXBinder = CLRPrivBinderAppX::GetOrCreateBinder();
- CLRPrivBinderFusion * pFusionBinder = pAppXBinder->GetFusionBinder();
-
- pBinder->m_pFrameworkBinder = SafeAddRef(pFusionBinder);
- _ASSERTE(pBinder->m_pFrameworkBinder != nullptr);
-
- if (InterlockedCompareExchangeT<decltype(s_pSingleton)>(&s_pSingleton, pBinder, nullptr) == nullptr)
- pBinder.SuppressRelease();
- }
-
- return s_pSingleton;
-}
-
-//=====================================================================================================================
-CLRPrivBinderLoadFile::CLRPrivBinderLoadFile()
-{
- STANDARD_VM_CONTRACT;
-}
-
-//=====================================================================================================================
-CLRPrivBinderLoadFile::~CLRPrivBinderLoadFile()
-{
- WRAPPER_NO_CONTRACT;
-}
-
-//=====================================================================================================================
-STDMETHODIMP CLRPrivBinderLoadFile::BindAssemblyExplicit(
- PEImage* pImage,
- IAssemblyName **ppAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
-{
- STANDARD_BIND_CONTRACT;
- PRECONDITION(AppDomain::GetCurrentDomain()->IsDefaultDomain());
- VALIDATE_ARG_RET(pImage != nullptr);
- VALIDATE_ARG_RET(ppAssemblyName != nullptr);
- VALIDATE_ARG_RET(ppAssembly != nullptr);
-
- HRESULT hr = S_OK;
-
- fusion::logging::StatusScope logStatus(0, ID_FUSLOG_BINDING_STATUS_LOAD_FILE, &hr);
-
- ReleaseHolder<IAssemblyName> pAssemblyName;
- ReleaseHolder<ICLRPrivAssembly> pAssembly;
-
- EX_TRY
- {
- // check if a framework assembly
- {
- AssemblySpec spec;
- mdAssembly a;
- IfFailThrow(pImage->GetMDImport()->GetAssemblyFromScope(&a));
- spec.InitializeSpec(a, pImage->GetMDImport(), NULL, false);
- IfFailThrow(spec.CreateFusionName(&pAssemblyName));
- }
-
- hr = IfTransientFailThrow(m_pFrameworkBinder->BindFusionAssemblyByName(
- pAssemblyName,
- CLRPrivBinderFusion::kBindingScope_FrameworkSubset,
- &pAssembly));
- if (FAILED(hr)) // not a Framework assembly
- {
- ReleaseHolder<CLRPrivResourcePathImpl> pPathResource =
- clr::SafeAddRef(new CLRPrivResourcePathImpl(pImage->GetPath().GetUnicode()));
- pAssembly = clr::SafeAddRef(new CLRPrivAssemblyLoadFile(this, m_pFrameworkBinder, pPathResource));
-
- hr = S_OK;
- }
- }
- EX_CATCH_HRESULT(hr);
-
- if (SUCCEEDED(hr))
- {
- *ppAssemblyName = pAssemblyName.Extract();
- *ppAssembly = pAssembly.Extract();
- }
-
- return hr;
-};
-
-//=====================================================================================================================
-STDMETHODIMP CLRPrivBinderLoadFile::BindAssemblyByName(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
-{
- WRAPPER_NO_CONTRACT;
- _ASSERTE(!"No parentless binds are allowed in NEITHER context");
- return E_NOTIMPL;
-};
-
-//=====================================================================================================================
-STDMETHODIMP CLRPrivBinderLoadFile::VerifyBind(
- IAssemblyName *pAssemblyName,
- ICLRPrivAssembly *pAssembly,
- ICLRPrivAssemblyInfo *pAssemblyInfo)
-{
- WRAPPER_NO_CONTRACT;
- // TODO: move ublic Key verification here, once we are willing to fully convert to hosted model
- _ASSERTE(!"CLRPrivAssemblyLoadFile::VerifyBind");
- return E_NOTIMPL; // we don't care about anything here...
-};
-
-//=====================================================================================================================
-HRESULT CLRPrivBinderLoadFile::GetBinderID(
- UINT_PTR *pBinderId)
-{
- LIMITED_METHOD_CONTRACT;
-
- *pBinderId = (UINT_PTR)this;
- return S_OK;
-}
-
-//==========================================================================
-CLRPrivAssemblyLoadFile::CLRPrivAssemblyLoadFile(
- CLRPrivBinderLoadFile* pBinder,
- CLRPrivBinderFusion* pFrameworkBinder,
- CLRPrivBinderUtil::CLRPrivResourcePathImpl* pPathResource)
- : m_pBinder(SafeAddRef(pBinder))
- , m_pFrameworkBinder(SafeAddRef(pFrameworkBinder))
- , m_pPathResource(SafeAddRef(pPathResource))
-{
- STANDARD_VM_CONTRACT;
- VALIDATE_ARG_THROW(pBinder != nullptr);
- VALIDATE_ARG_THROW(pFrameworkBinder != nullptr);
- VALIDATE_ARG_THROW(pPathResource != nullptr);
-}
-
-//=====================================================================================================================
-STDMETHODIMP CLRPrivAssemblyLoadFile::BindAssemblyByName(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
-{
- STANDARD_BIND_CONTRACT;
- HRESULT hr = S_OK;
-
- EX_TRY
- {
- hr = m_pFrameworkBinder->BindFusionAssemblyByName(
- pAssemblyName,
- CLRPrivBinderFusion::kBindingScope_FrameworkSubset,
- ppAssembly);
- if (FAILED(hr) && !Exception::IsTransient(hr)) // not a Framework assembly
- {
- *ppAssembly = RaiseAssemblyResolveEvent(pAssemblyName, this);
- if (*ppAssembly == NULL)
- {
- hr = COR_E_FILENOTFOUND;
- }
- else
- {
- (*ppAssembly)->AddRef();
- hr = S_OK;
- }
- }
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-};
-
-//=====================================================================================================================
-HRESULT CLRPrivAssemblyLoadFile::GetBinderID(
- UINT_PTR *pBinderId)
-{
- LIMITED_METHOD_CONTRACT;
- return m_pBinder->GetBinderID(pBinderId);
-}
-
-//=====================================================================================================================
-STDMETHODIMP CLRPrivAssemblyLoadFile::VerifyBind(
- IAssemblyName *pAssemblyName,
- ICLRPrivAssembly *pAssembly,
- ICLRPrivAssemblyInfo *pAssemblyInfo)
-{
- STANDARD_BIND_CONTRACT;
- return S_OK;
-};
-
-//=====================================================================================================================
-HRESULT CLRPrivAssemblyLoadFile::IsShareable(
- BOOL * pbIsShareable)
-{
- LIMITED_METHOD_CONTRACT;
-
- VALIDATE_ARG_RET(pbIsShareable != nullptr);
-
- *pbIsShareable = FALSE; // no sharing for loadfile
- return S_OK;
-}
-
-//=====================================================================================================================
-HRESULT CLRPrivAssemblyLoadFile::GetAvailableImageTypes(
- LPDWORD pdwImageTypes)
-{
- LIMITED_METHOD_CONTRACT;
- VALIDATE_ARG_RET(pdwImageTypes != nullptr);
- PRECONDITION(m_pPathResource != nullptr);
-
- *pdwImageTypes = ASSEMBLY_IMAGE_TYPE_IL;
-
- return S_OK;
-}
-
-
-//=====================================================================================================================
-HRESULT CLRPrivAssemblyLoadFile::GetImageResource(
- DWORD dwImageType,
- DWORD *pdwImageType,
- ICLRPrivResource ** ppIResource)
-{
- LIMITED_METHOD_CONTRACT;
- VALIDATE_ARG_RET(pdwImageType != nullptr);
- VALIDATE_ARG_RET(ppIResource != nullptr);
-
- *ppIResource = nullptr;
-
- HRESULT hr = S_OK;
- if ((dwImageType & ASSEMBLY_IMAGE_TYPE_NATIVE) == ASSEMBLY_IMAGE_TYPE_NATIVE)
- {
- return CLR_E_BIND_IMAGE_UNAVAILABLE;
- }
-
- *pdwImageType = ASSEMBLY_IMAGE_TYPE_IL;
- *ppIResource = clr::SafeAddRef(m_pPathResource);
-
- return S_OK;
-}
-
-#endif // !DACCESS_COMPILE
-
diff --git a/src/vm/clrprivbinderreflectiononlywinrt.cpp b/src/vm/clrprivbinderreflectiononlywinrt.cpp
deleted file mode 100644
index ad46511e81..0000000000
--- a/src/vm/clrprivbinderreflectiononlywinrt.cpp
+++ /dev/null
@@ -1,497 +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.
-//
-
-//
-// Contains the types that implement code:ICLRPrivBinder and code:ICLRPrivAssembly for WinRT ReflectionOnly (aka introspection) binding.
-//
-//=====================================================================================================================
-
-#include "common.h" // precompiled header
-
-#ifndef DACCESS_COMPILE
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
-
-//=====================================================================================================================
-#include "sstring.h"
-#include "policy.h"
-#include "clrprivbinderreflectiononlywinrt.h"
-#include "appxutil.h"
-#include "clrprivbinderutil.h"
-#include "imprthelpers.h" // in fusion/inc
-
-#include <winstring.h>
-#include <typeresolution.h>
-
-using namespace CLRPrivBinderUtil;
-
-//=====================================================================================================================
-
-//=====================================================================================================================
-CLRPrivBinderReflectionOnlyWinRT::CLRPrivBinderReflectionOnlyWinRT(
- CLRPrivTypeCacheReflectionOnlyWinRT * pTypeCache)
- : m_MapsLock(CrstLeafLock, CRST_REENTRANCY) // Reentracy is needed for code:CLRPrivAssemblyReflectionOnlyWinRT::Release
-{
- STANDARD_VM_CONTRACT;
-
- // This binder is not supported in AppX scenario.
- _ASSERTE(!AppX::IsAppXProcess());
-
- _ASSERTE(pTypeCache != nullptr);
- m_pTypeCache = clr::SafeAddRef(pTypeCache);
-}
-
-//=====================================================================================================================
-CLRPrivBinderReflectionOnlyWinRT::~CLRPrivBinderReflectionOnlyWinRT()
-{
- WRAPPER_NO_CONTRACT;
-
- if (m_pTypeCache != nullptr)
- {
- m_pTypeCache->Release();
- }
-}
-
-//=====================================================================================================================
-HRESULT
-CLRPrivBinderReflectionOnlyWinRT::BindWinRtType_Internal(
- LPCSTR szTypeNamespace,
- LPCSTR szTypeClassName,
- DomainAssembly * pParentAssembly,
- CLRPrivAssemblyReflectionOnlyWinRT ** ppAssembly)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
-
- VALIDATE_ARG_RET(ppAssembly != nullptr);
-
- CLRPrivBinderUtil::WStringList * pFileNameList = nullptr;
-
- StackSString ssTypeNamespace(SString::Utf8, szTypeNamespace);
-
- GetFileNameListForNamespace(ssTypeNamespace.GetUnicode(), pParentAssembly, &pFileNameList);
-
- if (pFileNameList == nullptr)
- { // There are no files associated with the namespace
- return CLR_E_BIND_TYPE_NOT_FOUND;
- }
-
- StackSString ssTypeName(ssTypeNamespace);
- ssTypeName.Append(W('.'));
- ssTypeName.AppendUTF8(szTypeClassName);
-
- CLRPrivBinderUtil::WStringListElem * pFileNameElem = pFileNameList->GetHead();
- while (pFileNameElem != nullptr)
- {
- const WCHAR * wszFileName = pFileNameElem->GetValue();
- ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT> pAssembly = FindOrCreateAssemblyByFileName(wszFileName);
- _ASSERTE(pAssembly != NULL);
-
- IfFailRet(hr = m_pTypeCache->ContainsType(pAssembly, ssTypeName.GetUnicode()));
- if (hr == S_OK)
- { // The type we are looking for has been found in this assembly
- *ppAssembly = pAssembly.Extract();
- return S_OK;
- }
- _ASSERTE(hr == S_FALSE);
-
- // Try next file name for this namespace
- pFileNameElem = CLRPrivBinderUtil::WStringList::GetNext(pFileNameElem);
- }
-
- // The type has not been found in any of the files from the type's namespace
- return CLR_E_BIND_TYPE_NOT_FOUND;
-} // CLRPrivBinderReflectionOnlyWinRT::BindWinRtType_Internal
-
-//=====================================================================================================================
-HRESULT
-CLRPrivBinderReflectionOnlyWinRT::BindWinRtType(
- LPCSTR szTypeNamespace,
- LPCSTR szTypeClassName,
- DomainAssembly * pParentAssembly,
- ICLRPrivAssembly ** ppPrivAssembly)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
-
- ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT> pWinRTAssembly;
- IfFailRet(BindWinRtType_Internal(szTypeNamespace, szTypeClassName, pParentAssembly, &pWinRTAssembly));
- IfFailRet(pWinRTAssembly->QueryInterface(__uuidof(ICLRPrivAssembly), (LPVOID *)ppPrivAssembly));
-
- return hr;
-}
-
-//=====================================================================================================================
-// Implements interface method code:ICLRPrivBinder::BindAssemblyByName.
-//
-HRESULT CLRPrivBinderReflectionOnlyWinRT::BindAssemblyByName(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
-{
- LIMITED_METHOD_CONTRACT;
-
- _ASSERTE_MSG(false, "Unexpected call to CLRPrivBinderReflectionOnlyWinRT::BindAssemblyByName");
- return E_UNEXPECTED;
-}
-
-//=====================================================================================================================
-ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT>
-CLRPrivBinderReflectionOnlyWinRT::FindAssemblyByFileName(
- LPCWSTR wszFileName)
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_CAN_TAKE_LOCK;
-
- CrstHolder lock(&m_MapsLock);
- const FileNameToAssemblyMapEntry * pEntry = m_FileNameToAssemblyMap.LookupPtr(wszFileName);
- return (pEntry == nullptr) ? nullptr : clr::SafeAddRef(pEntry->m_pAssembly);
-}
-
-//=====================================================================================================================
-// Add FileName -> CLRPrivAssemblyReflectionOnlyWinRT * mapping to the map (multi-thread safe).
-ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT>
-CLRPrivBinderReflectionOnlyWinRT::AddFileNameToAssemblyMapping(
- LPCWSTR wszFileName,
- CLRPrivAssemblyReflectionOnlyWinRT * pAssembly)
-{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE(pAssembly != nullptr);
-
- CrstHolder lock(&m_MapsLock);
-
- const FileNameToAssemblyMapEntry * pEntry = m_FileNameToAssemblyMap.LookupPtr(wszFileName);
- CLRPrivAssemblyReflectionOnlyWinRT * pResultAssembly = nullptr;
- if (pEntry != nullptr)
- {
- pResultAssembly = pEntry->m_pAssembly;
- }
- else
- {
- FileNameToAssemblyMapEntry e;
- e.m_wszFileName = wszFileName;
- e.m_pAssembly = pAssembly;
- m_FileNameToAssemblyMap.Add(e);
-
- pResultAssembly = pAssembly;
- }
- return clr::SafeAddRef(pResultAssembly);
-}
-
-//=====================================================================================================================
-void
-CLRPrivBinderReflectionOnlyWinRT::RemoveFileNameToAssemblyMapping(
- LPCWSTR wszFileName)
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_CAN_TAKE_LOCK;
-
- CrstHolder lock(&m_MapsLock);
- m_FileNameToAssemblyMap.Remove(wszFileName);
-}
-
-//=====================================================================================================================
-ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT>
-CLRPrivBinderReflectionOnlyWinRT::FindOrCreateAssemblyByFileName(
- LPCWSTR wszFileName)
-{
- STANDARD_VM_CONTRACT;
-
- ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT> pAssembly = FindAssemblyByFileName(wszFileName);
-
- if (pAssembly == nullptr)
- {
- NewHolder<CLRPrivResourcePathImpl> pResource(
- new CLRPrivResourcePathImpl(wszFileName));
-
- NewHolder<CLRPrivAssemblyReflectionOnlyWinRT> pNewAssembly(
- new CLRPrivAssemblyReflectionOnlyWinRT(wszFileName, this, pResource));
-
- // pNewAssembly holds reference to this now
- pResource.SuppressRelease();
-
- // Add the assembly into cache (multi-thread aware)
- pAssembly = AddFileNameToAssemblyMapping(pResource->GetPath(), pNewAssembly);
-
- if (pAssembly == pNewAssembly)
- { // We did not find an existing assembly in the cache and are using the newly created pNewAssembly.
- // Stop it from being deleted when we go out of scope.
- pNewAssembly.SuppressRelease();
- }
- }
- return pAssembly.Extract();
-}
-
-//=====================================================================================================================
-// Returns list of file names from code:m_NamespaceToFileNameListMap for the namespace.
-//
-void
-CLRPrivBinderReflectionOnlyWinRT::GetFileNameListForNamespace(
- LPCWSTR wszNamespace,
- DomainAssembly * pParentAssembly,
- CLRPrivBinderUtil::WStringList ** ppFileNameList)
-{
- STANDARD_VM_CONTRACT;
-
- CLRPrivBinderUtil::WStringList * pFileNameList = nullptr;
- {
- CrstHolder lock(&m_MapsLock);
-
- const NamespaceToFileNameListMapEntry * pEntry = m_NamespaceToFileNameListMap.LookupPtr(wszNamespace);
- if (pEntry != nullptr)
- {
- // Entries from the map are never removed, so we do not have to protect the file name list with a lock
- pFileNameList = pEntry->m_pFileNameList;
- }
- }
-
- if (pFileNameList != nullptr)
- {
- *ppFileNameList = pFileNameList;
- }
- else
- {
- CLRPrivBinderUtil::WStringListHolder hFileNameList;
-
- EX_TRY
- {
- m_pTypeCache->RaiseNamespaceResolveEvent(wszNamespace, pParentAssembly, &hFileNameList);
- }
- EX_CATCH
- {
- Exception * ex = GET_EXCEPTION();
- if (!ex->IsTransient())
- { // Exception was caused by user code
- // Cache empty file name list for this namespace
- (void)AddFileNameListForNamespace(wszNamespace, nullptr, ppFileNameList);
- }
- EX_RETHROW;
- }
- EX_END_CATCH_UNREACHABLE
-
- if (AddFileNameListForNamespace(wszNamespace, hFileNameList.GetValue(), ppFileNameList))
- { // The file name list was added to the cache - do not delete it
- _ASSERTE(*ppFileNameList == hFileNameList.GetValue());
- (void)hFileNameList.Extract();
- }
- }
-} // CLRPrivBinderReflectionOnlyWinRT::GetFileNameListForNamespace
-
-//=====================================================================================================================
-// Adds (thread-safe) list of file names to code:m_NamespaceToFileNameListMap for the namespace - returns the cached value.
-// Returns TRUE, if pFileNameList was added to the cache and caller should NOT delete it.
-// Returns FALSE, if pFileNameList was not added to the cache and caller should delete it.
-//
-BOOL
-CLRPrivBinderReflectionOnlyWinRT::AddFileNameListForNamespace(
- LPCWSTR wszNamespace,
- CLRPrivBinderUtil::WStringList * pFileNameList,
- CLRPrivBinderUtil::WStringList ** ppFileNameList)
-{
- STANDARD_VM_CONTRACT;
-
- NewArrayHolder<WCHAR> wszEntryNamespace = DuplicateStringThrowing(wszNamespace);
-
- NamespaceToFileNameListMapEntry entry;
- entry.m_wszNamespace = wszEntryNamespace;
- entry.m_pFileNameList = pFileNameList;
-
- {
- CrstHolder lock(&m_MapsLock);
-
- const NamespaceToFileNameListMapEntry * pEntry = m_NamespaceToFileNameListMap.LookupPtr(wszEntryNamespace);
- if (pEntry == nullptr)
- {
- m_NamespaceToFileNameListMap.Add(entry);
-
- // These values are now owned by the hash table element
- wszEntryNamespace.SuppressRelease();
- *ppFileNameList = pFileNameList;
- return TRUE;
- }
- else
- { // Another thread beat us adding this entry to the hash table
- *ppFileNameList = pEntry->m_pFileNameList;
- return FALSE;
- }
- }
-} // CLRPrivBinderReflectionOnlyWinRT::AddFileNameListForNamespace
-
-//=====================================================================================================================
-HRESULT
-CLRPrivBinderReflectionOnlyWinRT::BindAssemblyExplicit(
- const WCHAR * wszFileName,
- ICLRPrivAssembly ** ppAssembly)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- HRESULT hr;
-
- GCX_PREEMP();
-
- ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT> pAssembly = FindOrCreateAssemblyByFileName(wszFileName);
- _ASSERTE(pAssembly != NULL);
-
- IfFailRet(pAssembly->QueryInterface(__uuidof(ICLRPrivAssembly), (LPVOID *)ppAssembly));
-
- return S_OK;
-}
-
-//=====================================================================================================================
-CLRPrivAssemblyReflectionOnlyWinRT::CLRPrivAssemblyReflectionOnlyWinRT(
- LPCWSTR wzSimpleName,
- CLRPrivBinderReflectionOnlyWinRT * pBinder,
- CLRPrivResourcePathImpl * pResourceIL)
-{
- STANDARD_VM_CONTRACT;
- VALIDATE_ARG_THROW((wzSimpleName != nullptr) && (pBinder != nullptr) && (pResourceIL != nullptr));
-
- m_pBinder = clr::SafeAddRef(pBinder);
- m_pResourceIL = clr::SafeAddRef(pResourceIL);
-}
-
-//=====================================================================================================================
-ULONG CLRPrivAssemblyReflectionOnlyWinRT::Release()
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_CAN_TAKE_LOCK;
- _ASSERTE(m_cRef > 0);
-
- ULONG cRef;
-
- {
- // To achieve proper lifetime semantics, the name to assembly map elements' CLRPrivAssemblyReflectionOnlyWinRT
- // instances are not ref counted. We cannot allow discovery of the object via m_FileNameToAssemblyMap
- // when the ref count is 0 (to prevent another thread to AddRef and Release it back to 0 in parallel).
- // All uses of the map are guarded by the map lock, so we have to decrease the ref count under that
- // lock (to avoid the chance that 2 threads are running Release to ref count 0 at once).
- CrstHolder lock(&m_pBinder->m_MapsLock);
-
- cRef = InterlockedDecrement(&m_cRef);
- if (cRef == 0)
- {
- m_pBinder->RemoveFileNameToAssemblyMapping(m_pResourceIL->GetPath());
- }
- }
-
- if (cRef == 0)
- {
- delete this;
- }
- return cRef;
-}
-
-//=====================================================================================================================
-// Implements interface method code:ICLRPrivAssembly::IsShareable.
-//
-HRESULT CLRPrivAssemblyReflectionOnlyWinRT::IsShareable(
- BOOL * pbIsShareable)
-{
- LIMITED_METHOD_CONTRACT;
-
- VALIDATE_ARG_RET(pbIsShareable != nullptr);
-
- *pbIsShareable = FALSE;
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements interface method code:ICLRPrivAssembly::GetAvailableImageTypes.
-//
-HRESULT CLRPrivAssemblyReflectionOnlyWinRT::GetAvailableImageTypes(
- LPDWORD pdwImageTypes)
-{
- LIMITED_METHOD_CONTRACT;
-
- VALIDATE_ARG_RET(pdwImageTypes != nullptr);
-
- *pdwImageTypes = 0;
-
- if (m_pResourceIL != nullptr)
- *pdwImageTypes |= ASSEMBLY_IMAGE_TYPE_IL;
-
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements interface method code:ICLRPrivAssembly::GetImageResource.
-//
-HRESULT CLRPrivAssemblyReflectionOnlyWinRT::GetImageResource(
- DWORD dwImageType,
- DWORD * pdwImageType,
- ICLRPrivResource ** ppIResource)
-{
- STANDARD_BIND_CONTRACT;
- HRESULT hr = S_OK;
-
- VALIDATE_ARG_RET(ppIResource != nullptr);
-
- EX_TRY
- {
- DWORD _dwImageType;
- if (pdwImageType == nullptr)
- {
- pdwImageType = &_dwImageType;
- }
-
- if ((dwImageType & ASSEMBLY_IMAGE_TYPE_IL) == ASSEMBLY_IMAGE_TYPE_IL)
- {
- *ppIResource = clr::SafeAddRef(m_pResourceIL);
- *pdwImageType = ASSEMBLY_IMAGE_TYPE_IL;
- }
- else
- { // Native image is not supported by this binder
- hr = CLR_E_BIND_IMAGE_UNAVAILABLE;
- }
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
-//=====================================================================================================================
-// Implements interface method code:ICLRPrivBinder::VerifyBind.
-//
-HRESULT CLRPrivBinderReflectionOnlyWinRT::VerifyBind(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly * pAssembly,
- ICLRPrivAssemblyInfo * pAssemblyInfo)
-{
- STANDARD_BIND_CONTRACT;
- HRESULT hr = S_OK;
-
- UINT_PTR binderID;
- IfFailRet(pAssembly->GetBinderID(&binderID));
- if (binderID != reinterpret_cast<UINT_PTR>(this))
- {
- return pAssembly->VerifyBind(pAssemblyName, pAssembly, pAssemblyInfo);
- }
-
- // Since WinRT types are bound by type name and not assembly name, assembly-level version validation
- // does not make sense here. Just return S_OK.
- return S_OK;
-}
-
-//=====================================================================================================================
-// Implements interface method code:ICLRPrivBinder::GetBinderID.
-//
-HRESULT CLRPrivBinderReflectionOnlyWinRT::GetBinderID(
- UINT_PTR * pBinderId)
-{
- LIMITED_METHOD_CONTRACT;
-
- *pBinderId = reinterpret_cast<UINT_PTR>(this);
- return S_OK;
-}
-
-#endif //FEATURE_REFLECTION_ONLY_LOAD
-#endif //!DACCESS_COMPILE
diff --git a/src/vm/clrprivbinderreflectiononlywinrt.h b/src/vm/clrprivbinderreflectiononlywinrt.h
deleted file mode 100644
index 5f8ef46773..0000000000
--- a/src/vm/clrprivbinderreflectiononlywinrt.h
+++ /dev/null
@@ -1,295 +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.
-//
-
-//
-// Contains the types that implement code:ICLRPrivBinder and code:ICLRPrivAssembly for WinRT ReflectionOnly (aka introspection) binding.
-//
-//=====================================================================================================================
-
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
-
-#pragma once
-
-#include "holder.h"
-#include "internalunknownimpl.h"
-#include "clrprivbinding.h"
-#include "clrprivruntimebinders.h"
-#include "clrprivbinderutil.h"
-#include "clr_std/utility"
-
-//=====================================================================================================================
-// Forward declarations
-class CLRPrivBinderReflectionOnlyWinRT;
-class CLRPrivAssemblyReflectionOnlyWinRT;
-class CLRPrivTypeCacheReflectionOnlyWinRT;
-class DomainAssembly;
-
-//=====================================================================================================================
-//=====================================================================================================================
-//=====================================================================================================================
-class CLRPrivBinderReflectionOnlyWinRT :
- public IUnknownCommon<ICLRPrivBinder>
-{
- friend class CLRPrivAssemblyReflectionOnlyWinRT;
-
-private:
- //=============================================================================================
- // Data structures for Namespace -> FileNameList hash (as returned by RoResolveNamespace API)
-
- // Entry in SHash table that maps namespace to list of files
- struct NamespaceToFileNameListMapEntry
- {
- PWSTR m_wszNamespace;
- CLRPrivBinderUtil::WStringList * m_pFileNameList;
- };
-
- // SHash traits for Namespace -> FileNameList hash
- class NamespaceToFileNameListMapTraits : public NoRemoveSHashTraits< DefaultSHashTraits< NamespaceToFileNameListMapEntry > >
- {
- public:
- typedef PCWSTR key_t;
- static const NamespaceToFileNameListMapEntry Null() { NamespaceToFileNameListMapEntry e; e.m_wszNamespace = nullptr; return e; }
- static bool IsNull(const NamespaceToFileNameListMapEntry & e) { return e.m_wszNamespace == nullptr; }
- static PCWSTR GetKey(const NamespaceToFileNameListMapEntry & e) { return e.m_wszNamespace; }
- static count_t Hash(PCWSTR str) { return HashString(str); }
- static BOOL Equals(PCWSTR lhs, PCWSTR rhs) { LIMITED_METHOD_CONTRACT; return (wcscmp(lhs, rhs) == 0); }
-
- void OnDestructPerEntryCleanupAction(const NamespaceToFileNameListMapEntry & e)
- {
- delete [] e.m_wszNamespace;
- CLRPrivBinderUtil::WStringList_Delete(e.m_pFileNameList);
- }
- static const bool s_DestructPerEntryCleanupAction = true;
- };
-
- typedef SHash<NamespaceToFileNameListMapTraits> NamespaceToFileNameListMap;
-
- //=============================================================================================
- // Data structure for FileName -> CLRPrivAssemblyReflectionOnlyWinRT * map
-
- struct FileNameToAssemblyMapEntry
- {
- PCWSTR m_wszFileName; // File name (owned by m_pAssembly)
- CLRPrivAssemblyReflectionOnlyWinRT * m_pAssembly;
- };
-
- class FileNameToAssemblyMapTraits : public DefaultSHashTraits<FileNameToAssemblyMapEntry>
- {
- public:
- typedef PCWSTR key_t;
- static const FileNameToAssemblyMapEntry Null() { FileNameToAssemblyMapEntry e; e.m_wszFileName = NULL; return e; }
- static bool IsNull(const FileNameToAssemblyMapEntry &e) { return e.m_wszFileName == NULL; }
- static const FileNameToAssemblyMapEntry Deleted() { FileNameToAssemblyMapEntry e; e.m_wszFileName = (PCWSTR)-1; return e; }
- static bool IsDeleted(const FileNameToAssemblyMapEntry & e) { return e.m_wszFileName == (PCWSTR)-1; }
- static PCWSTR GetKey(const FileNameToAssemblyMapEntry & e) { return e.m_wszFileName; }
- static count_t Hash(PCWSTR str) { return HashString(str); }
- static BOOL Equals(PCWSTR lhs, PCWSTR rhs) { LIMITED_METHOD_CONTRACT; return (wcscmp(lhs, rhs) == 0); }
- };
-
- typedef SHash<FileNameToAssemblyMapTraits> FileNameToAssemblyMap;
-
-public:
- //=============================================================================================
- // ICLRPrivBinder interface methods
-
- STDMETHOD(BindAssemblyByName)(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly);
-
- // Implements interface method code:ICLRPrivBinder::VerifyBind.
- STDMETHOD(VerifyBind)(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly * pAssembly,
- ICLRPrivAssemblyInfo * pAssemblyInfo);
-
- // Implements interface method code:ICLRPrivBinder::GetBinderFlags
- STDMETHOD(GetBinderFlags)(
- DWORD *pBinderFlags)
- {
- LIMITED_METHOD_CONTRACT;
- *pBinderFlags = BINDER_NONE;
- return S_OK;
- }
-
- // Implements interface method code:ICLRPrivBinder::GetBinderID.
- STDMETHOD(GetBinderID)(
- UINT_PTR * pBinderId);
-
- // FindAssemblyBySpec is not supported by this binder.
- STDMETHOD(FindAssemblyBySpec)(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly)
- { STATIC_CONTRACT_WRAPPER; return E_FAIL; }
-
- //=============================================================================================
- // Class methods
-
- CLRPrivBinderReflectionOnlyWinRT(
- CLRPrivTypeCacheReflectionOnlyWinRT * pTypeCache);
-
- ~CLRPrivBinderReflectionOnlyWinRT();
-
- HRESULT BindAssemblyExplicit(
- const WCHAR * wszFileName,
- ICLRPrivAssembly ** ppAssembly);
-
- HRESULT BindWinRtType(
- LPCSTR szTypeNamespace,
- LPCSTR szTypeClassName,
- DomainAssembly * pParentAssembly,
- ICLRPrivAssembly ** ppPrivAssembly);
-
-private:
- //=============================================================================================
- // Accessors for FileName -> CLRPrivAssemblyReflectionOnlyWinRT * map
-
- ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT> FindAssemblyByFileName(
- LPCWSTR wzsFileName);
-
- ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT> AddFileNameToAssemblyMapping(
- LPCWSTR wszFileName,
- CLRPrivAssemblyReflectionOnlyWinRT * pAssembly);
-
- void RemoveFileNameToAssemblyMapping(
- LPCWSTR wszFileName);
-
- ReleaseHolder<CLRPrivAssemblyReflectionOnlyWinRT> FindOrCreateAssemblyByFileName(
- LPCWSTR wzsFileName);
-
- //=============================================================================================
- // Internal methods
-
- // Returns list of file names from code:m_NamespaceToFileNameListMap for the namespace.
- void GetFileNameListForNamespace(
- LPCWSTR wszNamespace,
- DomainAssembly * pParentAssembly,
- CLRPrivBinderUtil::WStringList ** ppFileNameList);
-
- // Adds (thread-safe) list of file names to code:m_NamespaceToFileNameListMap for the namespace - returns the cached value.
- BOOL AddFileNameListForNamespace(
- LPCWSTR wszNamespace,
- CLRPrivBinderUtil::WStringList * pFileNameList,
- CLRPrivBinderUtil::WStringList ** ppFileNameList);
-
- HRESULT BindWinRtType_Internal(
- LPCSTR szTypeNamespace,
- LPCSTR szTypeClassName,
- DomainAssembly * pParentAssembly,
- CLRPrivAssemblyReflectionOnlyWinRT ** ppAssembly);
-
-private:
- //=============================================================================================
-
- // Namespace -> FileName list map ... items are never removed
- NamespaceToFileNameListMap m_NamespaceToFileNameListMap;
- // FileName -> CLRPrivAssemblyReflectionOnlyWinRT * map ... items can be removed when CLRPrivAssemblyReflectionOnlyWinRT dies
- FileNameToAssemblyMap m_FileNameToAssemblyMap;
-
- // Lock for the above maps
- Crst m_MapsLock;
-
- //=============================================================================================
- CLRPrivTypeCacheReflectionOnlyWinRT * m_pTypeCache;
-
-}; // class CLRPrivBinderReflectionOnlyWinRT
-
-
-//=====================================================================================================================
-//=====================================================================================================================
-//=====================================================================================================================
-class CLRPrivAssemblyReflectionOnlyWinRT :
- public IUnknownCommon<ICLRPrivAssembly>
-{
- friend class CLRPrivBinderReflectionOnlyWinRT;
-
-public:
- //=============================================================================================
- // Class methods
-
- CLRPrivAssemblyReflectionOnlyWinRT(
- LPCWSTR wzFullTypeName,
- CLRPrivBinderReflectionOnlyWinRT * pBinder,
- CLRPrivBinderUtil::CLRPrivResourcePathImpl * pResourceIL);
-
- //=============================================================================================
- // IUnknown interface methods
-
- // Overridden to implement self-removal from assembly map code:CLRPrivBinderReflectionOnlyWinRT::m_FileNameToAssemblyMap.
- STDMETHOD_(ULONG, Release)();
-
- //=============================================================================================
- // ICLRPrivBinder interface methods
-
- STDMETHOD(BindAssemblyByName)(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly ** ppAssembly)
- {
- STATIC_CONTRACT_WRAPPER;
- return m_pBinder->BindAssemblyByName(pAssemblyName, ppAssembly);
- }
-
- // Implements interface method code:ICLRPrivBinder::VerifyBind.
- STDMETHOD(VerifyBind)(
- IAssemblyName * pAssemblyName,
- ICLRPrivAssembly * pAssembly,
- ICLRPrivAssemblyInfo * pAssemblyInfo)
- {
- STATIC_CONTRACT_WRAPPER;
- return m_pBinder->VerifyBind(pAssemblyName, pAssembly, pAssemblyInfo);
- }
-
- //---------------------------------------------------------------------------------------------
- // Implements interface method code:ICLRPrivBinder::GetBinderFlags
- STDMETHOD(GetBinderFlags)(
- DWORD *pBinderFlags)
- {
- STATIC_CONTRACT_WRAPPER;
- return m_pBinder->GetBinderFlags(pBinderFlags);
- }
-
- // Implements interface method code:ICLRPrivBinder::GetBinderID.
- STDMETHOD(GetBinderID)(
- UINT_PTR * pBinderId)
- {
- STATIC_CONTRACT_WRAPPER;
- return m_pBinder->GetBinderID(pBinderId);
- }
-
- //=============================================================================================
- // ICLRPrivAssembly interface methods
-
- // Implements interface method code:ICLRPrivAssembly::IsShareable.
- STDMETHOD(IsShareable)(
- BOOL * pbIsShareable);
-
- // Implements interface method code:ICLRPrivAssembly::GetAvailableImageTypes.
- STDMETHOD(GetAvailableImageTypes)(
- LPDWORD pdwImageTypes);
-
- // Implements interface method code:ICLRPrivAssembly::GetImageResource.
- STDMETHOD(GetImageResource)(
- DWORD dwImageType,
- DWORD * pdwImageType,
- ICLRPrivResource ** ppIResource);
-
- // Implements code:ICLRPrivBinder::FindAssemblyBySpec
- STDMETHOD(FindAssemblyBySpec)(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly)
- { STATIC_CONTRACT_WRAPPER; return m_pBinder->FindAssemblyBySpec(pvAppDomain, pvAssemblySpec, pResult, ppAssembly); }
-
-private:
- //=============================================================================================
-
- ReleaseHolder<CLRPrivBinderReflectionOnlyWinRT> m_pBinder;
- ReleaseHolder<CLRPrivBinderUtil::CLRPrivResourcePathImpl> m_pResourceIL;
-
-}; // class CLRPrivAssemblyReflectionOnlyWinRT
-
-#endif //FEATURE_REFLECTION_ONLY_LOAD
diff --git a/src/vm/clrprivbinderutil.cpp b/src/vm/clrprivbinderutil.cpp
index b6871123d9..0eccf508c5 100644
--- a/src/vm/clrprivbinderutil.cpp
+++ b/src/vm/clrprivbinderutil.cpp
@@ -39,327 +39,6 @@ LPWSTR CopyStringThrowing(
namespace CLRPrivBinderUtil
{
-#ifdef FEATURE_FUSION
- //-----------------------------------------------------------------------------------------------------------------
- CLRPrivAssemblyBindResultWrapper::CLRPrivAssemblyBindResultWrapper(
- IAssemblyName *pIAssemblyName,
- PCWSTR wzAssemblyPath,
- IILFingerprintFactory *pILFingerprintFactory
- ) :
- m_wzAssemblyPath(DuplicateStringThrowing(wzAssemblyPath)),
- m_pIAssemblyName(clr::SafeAddRef(pIAssemblyName)),
- m_bIBindResultNISet(false),
- m_pIBindResultNI(nullptr),
- m_pIILFingerprint(nullptr),
- m_pILFingerprintFactory(clr::SafeAddRef(pILFingerprintFactory)),
- m_lock(CrstLeafLock)
- {
- STANDARD_VM_CONTRACT;
- VALIDATE_ARG_THROW(pIAssemblyName != nullptr && wzAssemblyPath != nullptr);
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- CLRPrivAssemblyBindResultWrapper::~CLRPrivAssemblyBindResultWrapper()
- {
- clr::SafeRelease(m_pIAssemblyName);
- clr::SafeRelease(m_pIILFingerprint);
- clr::SafeRelease(m_pIBindResultNI);
- }
-
- //=================================================================================================================
- // IBindResult methods
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::GetAssemblyNameDef(
- /*out*/ IAssemblyName **ppIAssemblyNameDef)
- {
- LIMITED_METHOD_CONTRACT;
-
- VALIDATE_ARG_RET(ppIAssemblyNameDef != nullptr);
- *ppIAssemblyNameDef = clr::SafeAddRef(m_pIAssemblyName);
- return S_OK;
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::GetNextAssemblyModuleName(
- /*in*/ DWORD dwNIndex,
- __inout_ecount(*pdwCCModuleName) LPWSTR pwzModuleName,
- /*in, out, annotation("__inout")*/ LPDWORD pdwCCModuleName)
- {
- STANDARD_BIND_CONTRACT;
- _ASSERTE(!("E_NOTIMPL: " __FUNCTION__));
- return E_NOTIMPL;
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::GetAssemblyLocation(
- /*out*/ IAssemblyLocation **ppIAssemblyLocation)
- {
- STANDARD_BIND_CONTRACT;
- VALIDATE_ARG_RET(ppIAssemblyLocation != nullptr);
- return this->QueryInterface(ppIAssemblyLocation);
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::GetNativeImage(
- /*out*/ IBindResult **ppIBindResultNI,
- /*out*/ BOOL *pfIBindResultNIProbed)
- {
- LIMITED_METHOD_CONTRACT;
-
- // m_bIBindResultNISet must always be read *before* m_pIBindResultNI
- bool bIBindResultNISet = m_bIBindResultNISet;
-
- if (pfIBindResultNIProbed != nullptr)
- *pfIBindResultNIProbed = bIBindResultNISet;
-
- if (bIBindResultNISet && ppIBindResultNI != nullptr)
- *ppIBindResultNI = clr::SafeAddRef(m_pIBindResultNI);
-
- return S_OK;
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::SetNativeImage(
- /*in*/ IBindResult *pIBindResultNI,
- /*out*/ IBindResult **ppIBindResultNIFinal)
- {
- STANDARD_BIND_CONTRACT;
- HRESULT hr = S_OK;
-
- EX_TRY
- {
- // Native Binder needs S_FALSE returned if it loses the race.
- hr = S_FALSE;
-
- if (!m_bIBindResultNISet)
- {
- CrstHolder lock(&m_lock);
- if (!m_bIBindResultNISet)
- {
- m_pIBindResultNI = clr::SafeAddRef(pIBindResultNI);
- m_bIBindResultNISet = true;
-
- // Won the race!
- hr = S_OK;
- }
- }
- }
- EX_CATCH_HRESULT(hr);
-
- if (ppIBindResultNIFinal != nullptr)
- *ppIBindResultNIFinal = clr::SafeAddRef(m_pIBindResultNI);
-
- return hr;
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::IsEqual(
- /*in*/ IUnknown *pIUnk)
- {
- STANDARD_BIND_CONTRACT;
- HRESULT hr = S_OK;
-
- VALIDATE_ARG_RET(pIUnk != nullptr);
-
- ReleaseHolder<IBindResult> pIBindResult;
-
- hr = pIUnk->QueryInterface(__uuidof(IBindResult), (void **)&pIBindResult);
- if (SUCCEEDED(hr))
- {
- hr = pIBindResult == static_cast<IBindResult*>(this) ? S_OK : S_FALSE;
- }
- else if (hr == E_NOINTERFACE)
- {
- hr = S_FALSE;
- }
-
- return hr;
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::GetNextAssemblyNameRef(
- /*in*/ DWORD dwNIndex,
- /*out*/ IAssemblyName **ppIAssemblyNameRef)
- {
- STANDARD_BIND_CONTRACT;
- _ASSERTE(!("E_UNEXPECTED: " __FUNCTION__));
- return E_UNEXPECTED;
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::GetNextDependentAssembly(
- /*in*/ DWORD dwNIndex,
- /*out*/ IUnknown **ppIUnknownAssembly)
- {
- STANDARD_BIND_CONTRACT;
- _ASSERTE(!("E_UNEXPECTED: " __FUNCTION__));
- return E_UNEXPECTED;
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::GetAssemblyLocationOfILImage(
- /*out*/ IAssemblyLocation **ppAssemblyLocation)
- {
- LIMITED_METHOD_CONTRACT;
- return this->QueryInterface(ppAssemblyLocation);
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::GetILFingerprint(
- /*out*/ IILFingerprint **ppFingerprint)
- {
- STANDARD_BIND_CONTRACT;
- HRESULT hr = S_OK;
-
- VALIDATE_ARG_RET(ppFingerprint != nullptr);
-
- EX_TRY
- {
- *ppFingerprint = m_pIILFingerprint;
- if (*ppFingerprint == nullptr)
- {
- ReleaseHolder<IILFingerprint> pFingerprint;
- if (SUCCEEDED(hr = m_pILFingerprintFactory->GetILFingerprintForPath(GetILAssemblyPath(), &pFingerprint)))
- {
- if (InterlockedCompareExchangeT<IILFingerprint>(&m_pIILFingerprint, pFingerprint, nullptr) == nullptr)
- {
- pFingerprint.SuppressRelease();
- }
- }
- }
- *ppFingerprint = clr::SafeAddRef(m_pIILFingerprint);
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::GetSourceILTimestamp(
- /*out*/ FILETIME* pFileTime)
- {
- STANDARD_BIND_CONTRACT;
- HRESULT hr = S_OK;
-
- VALIDATE_ARG_RET(pFileTime != nullptr);
-
- EX_TRY
- {
- WIN32_FILE_ATTRIBUTE_DATA wfd;
- if (!WszGetFileAttributesEx(GetILAssemblyPath(), GetFileExInfoStandard, &wfd))
- ThrowLastError();
- *pFileTime = wfd.ftLastWriteTime;
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::GetSourceILSize(
- /*out*/ DWORD* pSize)
- {
- STANDARD_BIND_CONTRACT;
- HRESULT hr = S_OK;
-
- VALIDATE_ARG_RET(pSize != nullptr);
-
- EX_TRY
- {
- WIN32_FILE_ATTRIBUTE_DATA wfd;
- if (!WszGetFileAttributesEx(GetILAssemblyPath(), GetFileExInfoStandard, &wfd))
- ThrowLastError();
- if(wfd.nFileSizeHigh != 0)
- ThrowHR(COR_E_OVERFLOW);
- *pSize = wfd.nFileSizeLow;
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::GetNIInfo(
- /*out*/ INativeImageInstallInfo** pInfo)
- {
- STANDARD_BIND_CONTRACT;
- _ASSERTE(!("E_UNEXPECTED: " __FUNCTION__));
- return E_UNEXPECTED;
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::GetFlags(
- /*out*/ DWORD * pdwFlags)
- {
- STANDARD_BIND_CONTRACT;
- PRECONDITION(CheckPointer(pdwFlags));
- if (pdwFlags == nullptr)
- {
- return E_POINTER;
- }
-
- // Currently, no effort is made to open assemblies and build a full IAssemblyName - this currently
- // only contains the simple name. Since AppX packages cannot be in-place updated we can be confident
- // that the binding environment will remain unchanged between NGEN and runtime. As such, return the
- // flag to indicate that the native image binder should skip self assembly definition validation.
- *pdwFlags = IBindResultFlag_AssemblyNameDefIncomplete;
-
- return S_OK;
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::GetLocationType(
- /*out*/DWORD *pdwLocationType)
- {
- LIMITED_METHOD_CONTRACT;
- VALIDATE_ARG_RET(pdwLocationType != nullptr);
-
- if (pdwLocationType == nullptr)
- return E_INVALIDARG;
- *pdwLocationType = ASSEMBLY_LOCATION_PATH;
- return S_OK;
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::GetPath(
- __inout_ecount(*pdwccAssemblyPath) LPWSTR pwzAssemblyPath,
- /*in, annotation("__inout")*/ LPDWORD pdwccAssemblyPath)
- {
- STANDARD_BIND_CONTRACT;
- HRESULT hr = S_OK;
-
- VALIDATE_ARG_RET(pdwccAssemblyPath != nullptr);
-
- EX_TRY
- {
- DWORD cchILAssemblyPath = static_cast<DWORD>(wcslen(GetILAssemblyPath())) + 1;
- if (pwzAssemblyPath != nullptr && cchILAssemblyPath <= *pdwccAssemblyPath)
- {
- IfFailThrow(StringCchCopy(pwzAssemblyPath, *pdwccAssemblyPath, GetILAssemblyPath()));
- *pdwccAssemblyPath = cchILAssemblyPath;
- hr = S_OK;
- }
- else
- {
- *pdwccAssemblyPath = cchILAssemblyPath;
- hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
- }
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
- }
-
- //-----------------------------------------------------------------------------------------------------------------
- HRESULT CLRPrivAssemblyBindResultWrapper::GetHostID(
- /*out*/ UINT64 *puiHostID)
- {
- STANDARD_BIND_CONTRACT;
- _ASSERTE(!("E_UNEXPECTED: " __FUNCTION__));
- return E_UNEXPECTED;
- }
-#endif //FEATURE_FUSION
//-----------------------------------------------------------------------------------------------------------------
HRESULT VerifyBind(
@@ -661,49 +340,6 @@ namespace CLRPrivBinderUtil
return hr;
}
-#ifdef FEATURE_FUSION
- //=====================================================================================================================
- HRESULT AssemblyIdentity::Initialize(
- AssemblySpec * pSpec)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- FORBID_FAULT;
- MODE_ANY;
- CAN_TAKE_LOCK;
- }
- CONTRACTL_END
-
- HRESULT hr = S_OK;
-
- if (0 == WszMultiByteToWideChar(
- CP_UTF8, 0 /*flags*/, pSpec->GetName(), -1, Name, (int) (sizeof(Name) / sizeof(Name[0]))))
- {
- return HRESULT_FROM_GetLastError();
- }
-
- AssemblyMetaDataInternal * pAMDI = pSpec->GetContext();
- if (pAMDI != nullptr)
- {
- Version.wMajor = pAMDI->usMajorVersion;
- Version.wMinor = pAMDI->usMinorVersion;
- Version.wBuild = pAMDI->usBuildNumber;
- Version.wRevision = pAMDI->usRevisionNumber;
- }
-
- if (pSpec->HasPublicKeyToken())
- {
- PBYTE pbKey;
- DWORD cbKey;
- pSpec->GetPublicKeyToken(&pbKey, &cbKey);
- IfFailRet(KeyToken.Initialize(pbKey, cbKey));
- }
-
- return hr;
- }
-#endif
//=====================================================================================================================
@@ -731,101 +367,4 @@ namespace CLRPrivBinderUtil
////////////////////////////////////////////////////////////////////////////////////////////////////
///// ----------------------------- Direct calls to VM -------------------------------------------
////////////////////////////////////////////////////////////////////////////////////////////////////
-#if defined(FEATURE_APPX_BINDER)
- ICLRPrivAssembly* RaiseAssemblyResolveEvent(IAssemblyName *pAssemblyName, ICLRPrivAssembly* pRequestingAssembly)
- {
- CONTRACT(ICLRPrivAssembly*)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(AppX::IsAppXProcess());
- PRECONDITION(AppDomain::GetCurrentDomain()->IsDefaultDomain());
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- BinderMethodID methodId;
-
- methodId = METHOD__APP_DOMAIN__ON_ASSEMBLY_RESOLVE; // post-bind execution event (the classic V1.0 event)
-
- // Elevate threads allowed loading level. This allows the host to load an assembly even in a restricted
- // condition. Note, however, that this exposes us to possible recursion failures, if the host tries to
- // load the assemblies currently being loaded. (Such cases would then throw an exception.)
-
- OVERRIDE_LOAD_LEVEL_LIMIT(FILE_ACTIVE);
- OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED);
-
- DomainAssembly* pDomainAssembly = AppDomain::GetCurrentDomain()->FindAssembly(pRequestingAssembly);
-
- GCX_COOP();
-
- Assembly* pAssembly = NULL;
-
- struct _gc {
- OBJECTREF AppDomainRef;
- OBJECTREF AssemblyRef;
- STRINGREF str;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- SString ssAssemblyName;
- FusionBind::GetAssemblyNameDisplayName(pAssemblyName, ssAssemblyName);
-
- GCPROTECT_BEGIN(gc);
- if ((gc.AppDomainRef = GetAppDomain()->GetRawExposedObject()) != NULL)
- {
- gc.AssemblyRef = pDomainAssembly->GetExposedAssemblyObject();
-
- MethodDescCallSite onAssemblyResolve(methodId, &gc.AppDomainRef);
-
- gc.str = StringObject::NewString(ssAssemblyName.GetUnicode());
- ARG_SLOT args[3] = {
- ObjToArgSlot(gc.AppDomainRef),
- ObjToArgSlot(gc.AssemblyRef),
- ObjToArgSlot(gc.str)
- };
- ASSEMBLYREF ResultingAssemblyRef = (ASSEMBLYREF) onAssemblyResolve.Call_RetOBJECTREF(args);
- if (ResultingAssemblyRef != NULL)
- {
- pAssembly = ResultingAssemblyRef->GetAssembly();
- }
- }
- GCPROTECT_END();
-
- if (pAssembly != NULL)
- {
- if (pAssembly->IsIntrospectionOnly())
- {
- // Cannot return an introspection assembly from an execution callback or vice-versa
- COMPlusThrow(kFileLoadException, IDS_CLASSLOAD_ASSEMBLY_RESOLVE_RETURNED_INTROSPECTION );
- }
- if (pAssembly->IsCollectible())
- {
- COMPlusThrow(kNotSupportedException, W("NotSupported_CollectibleAssemblyResolve"));
- }
-
- // Check that the public key token matches the one specified in the spec
- // MatchPublicKeys throws as appropriate.
-
- StackScratchBuffer ssBuffer;
- AssemblySpec spec;
- IfFailThrow(spec.Init(ssAssemblyName.GetUTF8(ssBuffer)));
- spec.MatchPublicKeys(pAssembly);
-
- }
-
- if (pAssembly == nullptr)
- ThrowHR(COR_E_FILENOTFOUND);
-
- RETURN pAssembly->GetManifestFile()->GetHostAssembly();
- }
-
- BOOL CompareHostBinderSpecs(AssemblySpec * a1, AssemblySpec * a2)
- {
- WRAPPER_NO_CONTRACT;
- return a1->CompareEx(a2, AssemblySpec::ASC_Default);
- }
-#endif // FEATURE_APPX
} // namespace CLRPrivBinderUtil
diff --git a/src/vm/clrprivbinderwinrt.cpp b/src/vm/clrprivbinderwinrt.cpp
index b4fb45c083..f73d01a46d 100644
--- a/src/vm/clrprivbinderwinrt.cpp
+++ b/src/vm/clrprivbinderwinrt.cpp
@@ -11,9 +11,6 @@
#include "common.h" // precompiled header
-#ifndef FEATURE_CORECLR
-#include "assemblyusagelogmanager.h"
-#endif
#include "clr/fs/file.h"
#include "clrprivbinderwinrt.h"
#include "clrprivbinderutil.h"
@@ -22,25 +19,17 @@
//=====================================================================================================================
#include "sstring.h"
-#ifdef FEATURE_FUSION
-#include "fusionlogging.h"
-#include "policy.h"
-#include "imprthelpers.h" // in fusion/inc
-#include "asmimprt.h"
-#endif
#ifdef FEATURE_APPX
#include "appxutil.h"
#endif
#include <TypeResolution.h>
#include "delayloadhelpers.h"
-#ifdef FEATURE_CORECLR
#include "../binder/inc/applicationcontext.hpp"
#include "../binder/inc/assemblybinder.hpp"
#include "../binder/inc/assembly.hpp"
#include "../binder/inc/debuglog.hpp"
#include "../binder/inc/utils.hpp"
#include "../binder/inc/fusionassemblyname.hpp"
-#endif
#ifdef CROSSGEN_COMPILE
#include "crossgenroresolvenamespace.h"
@@ -134,17 +123,9 @@ CLRPrivBinderWinRT::CLRPrivBinderWinRT(
BOOL fCanUseNativeImages)
: m_pTypeCache(clr::SafeAddRef(pWinRtTypeCache))
, m_pParentBinder(pParentBinder) // Do not addref, lifetime directly tied to parent.
-#ifdef FEATURE_FUSION
- , m_fCanUseNativeImages(fCanUseNativeImages)
-#endif
, m_fNamespaceResolutionKind(fNamespaceResolutionKind)
-#ifdef FEATURE_CORECLR
, m_pApplicationContext(nullptr)
, m_appLocalWinMDPath(nullptr)
-#endif
-#ifdef FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
- , m_fCanSetLocalWinMDPath(TRUE)
-#endif // FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
{
STANDARD_VM_CONTRACT;
PRECONDITION(CheckPointer(pWinRtTypeCache));
@@ -160,9 +141,6 @@ CLRPrivBinderWinRT::CLRPrivBinderWinRT(
INDEBUG(| CRST_DEBUG_ONLY_CHECK_FORBID_SUSPEND_THREAD)));
m_MapsAddLock.Init(CrstCLRPrivBinderMapsAdd);
-#ifdef FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
- m_localWinMDPathLock.Init(CrstCrstCLRPrivBinderLocalWinMDPath);
-#endif // FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
// Copy altpaths
if (cAltPaths > 0)
@@ -177,39 +155,8 @@ CLRPrivBinderWinRT::CLRPrivBinderWinRT(
m_rgAltPaths.GetRawArray() + iAltPath));
}
}
-#if defined(FEATURE_APPX) && !defined(FEATURE_CORECLR)
- else if (AppX::IsAppXNGen())
- {
- // If this is an NGen worker process for AppX, then the process doesn't actually run in the package,
- // and RoResolveNamespace won't work without some help. AppX::GetCurrentPackageInfo can give us the
- // package graph, which we can pass to RoResolveNamespace to make it work properly.
- UINT32 cbBuffer = 0;
- UINT32 nCount = 0;
- HRESULT hr = AppX::GetCurrentPackageInfo(PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, nullptr, nullptr);
- if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- ThrowHR(hr);
-
- NewArrayHolder<BYTE> pbBuffer(new (nothrow) BYTE[cbBuffer]);
- IfNullThrow(pbBuffer);
- IfFailThrow(AppX::GetCurrentPackageInfo(PACKAGE_FILTER_CLR_DEFAULT, &cbBuffer, pbBuffer, &nCount));
-
- m_rgAltPaths.Allocate(nCount);
-
- PCPACKAGE_INFO pPackageInfo = reinterpret_cast<PCPACKAGE_INFO>(static_cast<PBYTE>(pbBuffer));
- for (UINT32 iAltPath = 0; iAltPath < nCount; iAltPath++)
- {
- IfFailThrow(WindowsCreateString(
- pPackageInfo[iAltPath].path,
- (UINT32)wcslen(pPackageInfo[iAltPath].path),
- m_rgAltPaths.GetRawArray() + iAltPath));
- }
- }
-#endif //FEATURE_APPX && !FEATURE_CORECLR
#endif //CROSSGEN_COMPILE
-#ifdef FEATURE_FUSION
- IfFailThrow(RuntimeCreateCachingILFingerprintFactory(&m_pFingerprintFactory));
-#endif
}
//=====================================================================================================================
@@ -217,9 +164,6 @@ CLRPrivBinderWinRT::~CLRPrivBinderWinRT()
{
WRAPPER_NO_CONTRACT;
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- AssemblyUsageLogManager::UnRegisterBinderFromUsageLog((UINT_PTR)this);
-#endif
if (m_pTypeCache != nullptr)
{
m_pTypeCache->Release();
@@ -235,11 +179,6 @@ CLRPrivBinderWinRT::GetOrCreateBinder(
STANDARD_VM_CONTRACT;
HRESULT hr = S_OK;
- // This should be allocated directly by CLRPrivBinderAppX in the AppX scenario.
-#ifdef FEATURE_APPX_BINDER
- _ASSERTE(!AppX::IsAppXProcess());
-#endif
-
if (s_pSingleton == nullptr)
{
ReleaseHolder<CLRPrivBinderWinRT> pBinder;
@@ -256,15 +195,6 @@ CLRPrivBinderWinRT::GetOrCreateBinder(
{
pBinder.SuppressRelease();
}
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- // Create and register WinRT usage log
- ReleaseHolder<IAssemblyUsageLog> pNewWinRTUsageLog;
- IfFailThrow(AssemblyUsageLogManager::GetUsageLogForContext(W("WinRT"), W("NotApp"), &pNewWinRTUsageLog));
-
- UINT_PTR winRTBinderId;
- IfFailThrow(pBinder->GetBinderID(&winRTBinderId));
- IfFailThrow(AssemblyUsageLogManager::RegisterBinderWithUsageLog(winRTBinderId, pNewWinRTUsageLog));
-#endif
}
_ASSERTE(s_pSingleton->m_fNamespaceResolutionKind == fNamespaceResolutionKind);
@@ -289,17 +219,10 @@ HRESULT CLRPrivBinderWinRT::BindWinRTAssemblyByName(
HRESULT hr = S_OK;
ReleaseHolder<CLRPrivAssemblyWinRT> pAssembly;
LPWSTR wszFullTypeName = nullptr;
-#ifndef FEATURE_CORECLR
- NewArrayHolder<WCHAR> wszAssemblySimpleName;
-#endif
#ifndef CROSSGEN_COMPILE
-#ifndef FEATURE_CORECLR
- fusion::logging::StatusScope logStatus(0, ID_FUSLOG_BINDING_STATUS_WINRT, &hr);
-#else
BINDER_SPACE::BINDER_LOG_ENTER(W("CLRPrivBinderWinRT_CoreCLR::BindWinRTAssemblyByName"));
#endif
-#endif
VALIDATE_ARG_RET(pAssemblyName != nullptr);
VALIDATE_ARG_RET(ppAssembly != nullptr);
@@ -316,15 +239,11 @@ HRESULT CLRPrivBinderWinRT::BindWinRTAssemblyByName(
IfFailGo(COR_E_PLATFORMNOTSUPPORTED);
}
-#ifndef FEATURE_CORECLR
- IfFailGo(fusion::util::GetProperty(pAssemblyName, ASM_NAME_NAME, &wszAssemblySimpleName));
-#else
WCHAR wszAssemblySimpleName[_MAX_PATH];
{
DWORD cchAssemblySimpleName = _MAX_PATH;
IfFailGo(pAssemblyName->GetName(&cchAssemblySimpleName, wszAssemblySimpleName));
}
-#endif
wszFullTypeName = wcschr(wszAssemblySimpleName, W('!'));
@@ -414,10 +333,6 @@ HRESULT CLRPrivBinderWinRT::BindWinRTAssemblyByName(
//
IfFailGo(pAssemblyDefName->SetProperty(ASM_NAME_NAME, wszFileNameStripped, (lstrlenW(wszFileNameStripped) + 1) * sizeof(WCHAR)));
-#ifdef FEATURE_FUSION
- NewHolder<CLRPrivAssemblyBindResultWrapper> pBindResult(
- new CLRPrivAssemblyBindResultWrapper(pAssemblyDefName, wszFileName, m_pFingerprintFactory));
-#else
NewHolder<CoreBindResult> pBindResult(new CoreBindResult());
StackSString sAssemblyPath(pResource->GetPath());
ReleaseHolder<BINDER_SPACE::Assembly> pBinderAssembly;
@@ -427,7 +342,6 @@ HRESULT CLRPrivBinderWinRT::BindWinRTAssemblyByName(
// We have set bInGac to TRUE here because the plan is full trust for WinRT. If this changes, we may need to check with
// AppDomain to verify trust based on the WinMD's path
pBindResult->Init(pBinderAssembly, TRUE);
-#endif
NewHolder<CLRPrivAssemblyWinRT> pNewAssembly(
new CLRPrivAssemblyWinRT(this, pResource, pBindResult, fIsWindowsNamespace));
@@ -445,49 +359,7 @@ HRESULT CLRPrivBinderWinRT::BindWinRTAssemblyByName(
pNewAssembly.SuppressRelease();
}
-#ifndef FEATURE_CORECLR
- if (fPreBind)
- {
- // We are pre-binding to this WinMD and do not want to open it
- // Compare the filename to the assembly simple name. This is legal to do with WinRT because at NGen time
- // we embed a WinRT dependency as assembly def name component plus a namespace and type from it.
- // At bind time, this type should still exist in the same assembly. If it doesn't, and has been moved,
- // the native image validation will fail anyway and we'll fall back to IL. This is because if the type has
- // been moved to another WinMD, it must have been removed from the first one because WinRT allows no duplicates.
- // See comment on CLRPrivBinderWinRT::PreBind for further details.
- if (!_wcsicmp(wszAssemblySimpleName, wszFileNameStripped))
- {
- *ppAssembly = pAssembly.Extract();
- return (hr = S_OK);
- }
- else
- {
- continue;
- }
- }
-#endif
- }
-#ifndef FEATURE_CORECLR
- else if (fPreBind)
- {
- // We are pre-binding to this WinMD and do not want to force it to be loaded into the runtime yet.
- // Compare the filename to the assembly simple name. This is legal to do with WinRT because at NGen time
- // we embed a WinRT dependency as assembly def name component plus a namespace and type from it.
- // At bind time, this type should still exist in the same assembly. If it doesn't, and has been moved,
- // the native image validation will fail anyway and we'll fall back to IL. This is because if the type has
- // been moved to another WinMD, it must have been removed from the first one because WinRT allows no duplicates.
- // See comment on CLRPrivBinderWinRT::PreBind for further details.
- if (!_wcsicmp(wszAssemblySimpleName, wszFileNameStripped))
- {
- *ppAssembly = pAssembly.Extract();
- return (hr = S_OK);
- }
- else
- {
- continue;
- }
}
-#endif
//
// Look to see if there's a native image available.
@@ -499,12 +371,8 @@ HRESULT CLRPrivBinderWinRT::BindWinRTAssemblyByName(
if (hr == S_OK)
{ // The type we are looking for has been found in this assembly
#ifndef CROSSGEN_COMPILE
-#ifndef FEATURE_CORECLR
- fusion::logging::LogMessage(0, ID_FUSLOG_BINDING_STATUS_FOUND, wszFileName);
-#else
BINDER_SPACE::BINDER_LOG_LEAVE_HR(W("CLRPrivBinderWinRT_CoreCLR::BindWinRTAssemblyByName"), hr);
#endif
-#endif
*ppAssembly = pAssembly.Extract();
return (hr = S_OK);
}
@@ -516,102 +384,11 @@ HRESULT CLRPrivBinderWinRT::BindWinRTAssemblyByName(
hr = CLR_E_BIND_TYPE_NOT_FOUND;
ErrExit:
-#ifdef FEATURE_CORECLR
BINDER_SPACE::BINDER_LOG_LEAVE_HR(W("CLRPrivBinderWinRT_CoreCLR::BindWinRTAssemblyByName"), hr);
-#endif
return hr;
} // CLRPrivBinderWinRT::BindWinRTAssemblyByName
-#ifdef FEATURE_FUSION
-//=====================================================================================================================
-HRESULT CLRPrivBinderWinRT::BindAssemblyToNativeAssembly(CLRPrivAssemblyWinRT *pAssembly)
-{
- HRESULT hr = S_OK;
-
- if (!m_fCanUseNativeImages)
- return hr;
- ReleaseHolder<IBindResult> pIBindResultIL;
- IfFailRet(pAssembly->GetIBindResult(&pIBindResultIL));
- _ASSERTE(pIBindResultIL != nullptr);
-
- NewArrayHolder<WCHAR> wzZapSet = DuplicateStringThrowing(g_pConfig->ZapSet());
- NativeConfigData cfgData = {
- wzZapSet,
- PEFile::GetNativeImageConfigFlags()
- };
-
- ReleaseHolder<IBindContext> pIBindContext;
- IfFailRet(GetParentIBindContext(&pIBindContext));
-
- // Fire BindingNgenPhaseStart ETW event if enabled.
- {
- InlineSString<_MAX_PATH> ssAssemblyName;
- FireEtwBindingNgenPhaseStart(
- (AppDomain::GetCurrentDomain()->GetId().m_dwId),
- LOADCTX_TYPE_HOSTED,
- ETWFieldUnused,
- ETWLoaderLoadTypeNotAvailable,
- NULL,
- pAssembly->m_pResourceIL->GetPath(),
- GetClrInstanceId());
- }
-
- IfFailRet(BindToNativeAssembly(pIBindResultIL, &cfgData, pIBindContext, fusion::logging::GetCurrentFusionBindLog()));
-
- // Fire BindingNgenPhaseEnd ETW event if enabled.
- {
- InlineSString<_MAX_PATH> ssAssemblyName;
- FireEtwBindingNgenPhaseEnd(
- (AppDomain::GetCurrentDomain()->GetId().m_dwId),
- LOADCTX_TYPE_HOSTED,
- ETWFieldUnused,
- ETWLoaderLoadTypeNotAvailable,
- NULL,
- pAssembly->m_pResourceIL->GetPath(),
- GetClrInstanceId());
- }
-
- // BindToNativeAssembly can return S_FALSE, but this could be misleading.
- if (hr == S_FALSE)
- hr = S_OK;
-
- return hr;
-}
-#endif
-
-#if defined(FEATURE_COMINTEROP_WINRT_DESKTOP_HOST) && !defined(CROSSGEN_COMPILE)
-BOOL CLRPrivBinderWinRT::SetLocalWinMDPath(HSTRING localWinMDPath)
-{
- STANDARD_VM_CONTRACT;
- STATIC_CONTRACT_CAN_TAKE_LOCK;
-
- CrstHolder lock(&m_localWinMDPathLock);
-
- // We use the empty string as a sential, so don't allow explicitly setting the binding base to empty.
- if (localWinMDPath == nullptr)
- {
- return FALSE;
- }
-
- // If we've already set a binding base, then the current base must match the exisitng one exactly
- if (!m_localWinMDPath.IsEmpty())
- {
- return m_localWinMDPath.CompareOrdinal(clr::winrt::StringReference(localWinMDPath)) == 0;
- }
-
- // If we've already done WinRT binding, we can't set the binding base because that could lead to inconsistent results when binding
- // the same name after the base is set.
- if (!m_fCanSetLocalWinMDPath)
- {
- return FALSE;
- }
-
- m_localWinMDPath.Initialize(localWinMDPath);
-
- return TRUE;
-}
-#endif // FEATURE_COMINTEROP_WINRT_DESKTOP_HOST && !CROSSGEN_COMPILE
//=====================================================================================================================
HRESULT CLRPrivBinderWinRT::BindWinRTAssemblyByName(
@@ -648,7 +425,6 @@ HRESULT CLRPrivBinderWinRT::BindWinRTAssemblyByName(
return hr;
}
-#ifndef FEATURE_FUSION
//
// This method opens the assembly using the CoreCLR Binder, which has logic supporting opening either the IL or
// even just the native image without IL present.
@@ -659,7 +435,6 @@ HRESULT CLRPrivBinderWinRT::GetAssemblyAndTryFindNativeImage(SString &sWinmdFile
{
HRESULT hr = S_OK;
-#ifdef FEATURE_CORECLR
if (!m_pApplicationContext->IsTpaListProvided())
return COR_E_FILENOTFOUND;
@@ -732,24 +507,10 @@ HRESULT CLRPrivBinderWinRT::GetAssemblyAndTryFindNativeImage(SString &sWinmdFile
FALSE, /* fIsInGAC */
FALSE /* fExplicitBindToNativeImage */,
ppAssembly);
-#else
- ReleaseHolder<BINDER_SPACE::Assembly> pAssembly;
-
- // This codepath is used for desktop crossgen
- pAssembly = new BINDER_SPACE::Assembly();
-
- pAssembly->SetPEImage(PEImage::OpenImage(sWinmdFilename, MDInternalImport_Default));
-
- pAssembly->m_assemblyPath.Set(sWinmdFilename);
-
- *ppAssembly = pAssembly.Extract();
-#endif
return hr;
}
-#endif // !FEATURE_FUSION
-#ifdef FEATURE_CORECLR
//=====================================================================================================================
HRESULT CLRPrivBinderWinRT::SetApplicationContext(BINDER_SPACE::ApplicationContext *pApplicationContext, SString &appLocalWinMD)
{
@@ -784,7 +545,6 @@ HRESULT CLRPrivBinderWinRT::SetApplicationContext(BINDER_SPACE::ApplicationConte
return hr;
}
-#endif //FEATURE_CORECLR
//=====================================================================================================================
// Implements interface method code:ICLRPrivBinder::BindAssemblyByName.
@@ -950,20 +710,7 @@ CLRPrivBinderWinRT::GetFileNameListForNamespace(
LPWSTR wszWinMDPath = nullptr;
UINT32 cchWinMDPath = 0;
-#ifdef FEATURE_CORECLR
wszWinMDPath = m_appLocalWinMDPath;
-#else
- if (AppX::IsAdaptiveApp())
- {
- IfFailRet(AppX::GetWinMetadataDirForAdaptiveApps(&wszWinMDPath));
- }
-
- else if (AppX::IsAppXDesignMode() || IsNgenOffline())
- {
- wszWinMDPathConfig = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_WinMDPath);
- wszWinMDPath = wszWinMDPathConfig;
- }
-#endif // FEATURE_CORECLR
if (wszWinMDPath != nullptr)
{
@@ -981,7 +728,6 @@ CLRPrivBinderWinRT::GetFileNameListForNamespace(
&rgFileNames,
nullptr, // pcDirectNamespaceChildren
nullptr); // rgDirectNamespaceChildren
-#ifdef FEATURE_CORECLR
// For CoreCLR, if the process is not AppX, deliver more appropriate error message
// when trying to bind to 3rd party WinMDs that is not confusing.
if (HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE) == hr)
@@ -991,57 +737,7 @@ CLRPrivBinderWinRT::GetFileNameListForNamespace(
IfFailRet(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));
}
}
-#endif
-#ifdef FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
- // If we failed to find the requested name, but we have an application local probing path setup, then
- // we can use that to try to find the name now.
- if (hr == RO_E_METADATA_NAME_NOT_FOUND || hr == HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE))
- {
- // We only want to probe the application local path for 3rd party WinMDs as these are the only ones
- // which do not have code sharing enabled. Although we currently only allow a single alternate probing
- // path per process, shutting this off now will give us easier behavior to support in the future if we
- // do need to enable per-domain local paths.
- if (!IsWindowsNamespace(wszNamespaceRoResolve))
- {
- HSTRING localWinMDPath = nullptr;
- {
- CrstHolder lock(&m_localWinMDPathLock);
-
- localWinMDPath = m_localWinMDPath.Get();
-
- // If the host has not configured the local winmd path, and we have not yet done any winmd probing
- // then see if we have config to setup a local winmd path.
- if (localWinMDPath == nullptr && m_fCanSetLocalWinMDPath)
- {
- NewArrayHolder<WCHAR> configWinMDPath(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_LocalWinMDPath));
- if (!configWinMDPath.IsNull())
- {
- m_localWinMDPath.Initialize(configWinMDPath);
- localWinMDPath = m_localWinMDPath.Get();
- }
- }
-
- // Do not allow any further setting of the application binding base at this point, since if it
- // is not currently set, setting it in the future could result in different binding results.
- m_fCanSetLocalWinMDPath = FALSE;
- }
-
- if (localWinMDPath != nullptr)
- {
- hr = RoResolveNamespace(
- WinRtStringRef(wszNamespaceRoResolve, cchNamespaceRoResolve),
- wszWinMDPath != nullptr ? (HSTRING)WinRtStringRef(wszWinMDPath, cchWinMDPath) : nullptr, // hsWindowsSdkPath
- 1, // cPackageGraph
- &localWinMDPath, // rgPackageGraph
- &cFileNames,
- &rgFileNames,
- nullptr, // pcDirectNamespaceChildren
- nullptr); // rgDirectNamespaceChildren
- }
- }
- }
-#endif // FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
IfFailRet(hr);
if (hr != S_OK)
@@ -1059,33 +755,6 @@ CLRPrivBinderWinRT::GetFileNameListForNamespace(
&cchFileName);
BOOL fSkipFilename = FALSE;
-#ifndef FEATURE_CORECLR
- // If we have a specified path list. Be certain to only find filenames in that list.
- // NGen for AppX is an exception, where the path list contains the package graph, and we can
- // accept files found elsewhere (e.g., in the Windows WinMD directory).
- // On CoreCLR, we have no concept of an AppX package, so we want the passed in app
- // paths to additively contribute to the set of WinMDs the API can find.
- if (m_rgAltPaths.GetCount() > 0 && !AppX::IsAppXNGen())
- {
- fSkipFilename = TRUE;
- for (DWORD iAltPath = 0; iAltPath < m_rgAltPaths.GetCount(); iAltPath++)
- {
- UINT32 cchAltPath = 0;
- LPCWSTR wszAltPath = WindowsGetStringRawBuffer(
- m_rgAltPaths.GetAt(iAltPath),
- &cchAltPath);
-
- if (cchAltPath >= cchFileName)
- continue;
-
- if (wcsncmp(wszAltPath, wszFileName, cchAltPath) == 0)
- {
- fSkipFilename = FALSE;
- break;
- }
- }
- }
-#endif
if (!fSkipFilename)
hFileNameList.InsertTail(wszFileName);
}
@@ -1309,60 +978,6 @@ CLRPrivBinderWinRT::FindAssemblyForTypeIfLoaded(
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_FUSION
-//=====================================================================================================================
-// Implements interface method code:IBindContext::PreBind.
-//
-// Prebinding to WinMD files follows a special contract. We want to avoid loading the actual target assembly
-// and we need to validate that all dependencies of the file remain equivalent to that which was available at ngen time
-// We do this by comparing the filename to the assembly simple name. This is legal to do with WinRT because at NGen time
-// we embed a WinRT dependency as assembly def name component plus a namespace and type from it.
-// At bind time, this type should still exist in the same assembly. If it doesn't, and has been moved,
-// the native image validation will fail anyway and we'll fall back to IL. This is because if the type has
-// been moved to another WinMD, it must have been removed from the first one because WinRT allows no duplicates.
-// This no duplicate rule is obviously not actually gauranteed by the WinRT runtime for 3rd party assemblies,
-// but violating the rule is known to cause a number of binding behavior errors that we do not attempt to protect against.
-HRESULT
-CLRPrivBinderWinRT::PreBind(
- IAssemblyName * pAssemblyName,
- DWORD dwPreBindFlags,
- IBindResult ** ppIBindResult)
-{
- STANDARD_VM_CONTRACT;
- HRESULT hr = S_OK;
-
- // Assert that we are only working with a binder that supports native images
- _ASSERTE(m_fCanUseNativeImages);
-
- ReleaseHolder<IBindContext> pIBindContext;
- IfFailRet(GetParentIBindContext(&pIBindContext));
-
- DWORD dwContentType = AssemblyContentType_Default;
- DWORD cbContentTypeSize = sizeof(dwContentType);
- IfFailRet(pAssemblyName->GetProperty(ASM_NAME_CONTENT_TYPE, &dwContentType, &cbContentTypeSize));
-
- if (dwContentType == AssemblyContentType_Default)
- {
- hr = pIBindContext->PreBind(pAssemblyName, dwPreBindFlags, ppIBindResult);
- }
- else
- {
- hr = BindWinRTAssemblyByName(pAssemblyName, ppIBindResult, TRUE);
- }
-
- return hr;
-}
-
-//=====================================================================================================================
-// Implements interface method code:IBindContext::IsDefaultContext.
-//
-HRESULT
-CLRPrivBinderWinRT::IsDefaultContext()
-{
- LIMITED_METHOD_CONTRACT;
- return S_OK;
-}
-#endif
//=====================================================================================================================
CLRPrivAssemblyWinRT::CLRPrivAssemblyWinRT(
@@ -1470,21 +1085,6 @@ HRESULT CLRPrivAssemblyWinRT::GetAvailableImageTypes(
return hr;
}
-#ifdef FEATURE_FUSION
-static ICLRPrivResource * GetResourceForBindResult(
- IBindResult * pIBindResult)
-{
- STANDARD_VM_CONTRACT;
- VALIDATE_ARG_THROW(pIBindResult != nullptr);
-
- WCHAR wzPath[_MAX_PATH];
- DWORD cchPath = NumItems(wzPath);
- ReleaseHolder<IAssemblyLocation> pIAssemLoc;
- IfFailThrow(pIBindResult->GetAssemblyLocation(&pIAssemLoc));
- IfFailThrow(pIAssemLoc->GetPath(wzPath, &cchPath));
- return ToInterface<ICLRPrivResource>(new CLRPrivResourcePathImpl(wzPath));
-}
-#endif
//=====================================================================================================================
// Implements interface method code:ICLRPrivAssembly::GetImageResource.
@@ -1573,7 +1173,6 @@ HRESULT CLRPrivBinderWinRT::GetBinderID(
return S_OK;
}
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
//=====================================================================================================================
HRESULT CLRPrivBinderWinRT::FindWinRTAssemblyBySpec(
LPVOID pvAppDomain,
@@ -1584,68 +1183,7 @@ HRESULT CLRPrivBinderWinRT::FindWinRTAssemblyBySpec(
STATIC_CONTRACT_WRAPPER;
return E_FAIL;
}
-#endif
-#ifdef FEATURE_FUSION
-//=====================================================================================================================
-HRESULT CLRPrivBinderWinRT::FindWinRTAssemblyBySpec(
- LPVOID pvAppDomain,
- LPVOID pvAssemblySpec,
- HRESULT * pResult,
- ICLRPrivAssembly ** ppAssembly)
-{
- LIMITED_METHOD_CONTRACT;;
- HRESULT hr = S_OK;
-
- AppDomain* pAppDomain = reinterpret_cast<AppDomain*>(pvAppDomain);
- AssemblySpec* pAssemblySpec = reinterpret_cast<AssemblySpec*>(pvAssemblySpec);
- VALIDATE_PTR_RET(pAppDomain);
- VALIDATE_PTR_RET(pAssemblySpec);
- VALIDATE_PTR_RET(pResult);
- VALIDATE_PTR_RET(ppAssembly);
-
- if (pAssemblySpec->IsContentType_WindowsRuntime())
- {
- // FindAssemblyBySpec is not supported by this binder.
- *pResult = CLR_E_BIND_TYPE_NOT_FOUND;
- *ppAssembly = nullptr;
- return S_OK;
- }
- else
- {
- return CLR_E_BIND_UNRECOGNIZED_IDENTITY_FORMAT;
- }
-}
-
-//=====================================================================================================================
-HRESULT CLRPrivBinderWinRT::GetParentIBindContext(
- IBindContext **ppIBindContext)
-{
- STANDARD_BIND_CONTRACT;
- VALIDATE_ARG_RET(ppIBindContext != nullptr);
-
- HRESULT hr = S_OK;
-
- if (m_pParentBinder != nullptr)
- {
- _ASSERTE(AppX::IsAppXProcess());
- IfFailRet(m_pParentBinder->QueryInterface(__uuidof(IBindContext), (void**)ppIBindContext));
- }
- else
- {
- _ASSERTE(!AppX::IsAppXProcess());
- EX_TRY
- {
- AppDomain* pDomain = AppDomain::GetCurrentDomain();
- hr = GetBindContextFromApplicationContext(pDomain->CreateFusionContext(), ppIBindContext);
- }
- EX_CATCH_HRESULT(hr);
- }
-
- _ASSERTE(FAILED(hr) || *ppIBindContext != nullptr);
- return hr;
-}
-#endif
//=====================================================================================================================
HRESULT CLRPrivAssemblyWinRT::GetIBindResult(
@@ -1672,29 +1210,14 @@ HRESULT CLRPrivAssemblyWinRT::EnsureAvailableImageTypes()
// If image types has not yet been set, attempt to bind to native assembly
if (dwImageTypesLocal == 0)
{
-#ifdef FEATURE_FUSION
- CLRPrivBinderWinRT *pBinder = m_pBinder;
- IfFailGo(pBinder->BindAssemblyToNativeAssembly(this));
-#endif
if (m_pIResourceNI == nullptr)
{
-#ifdef FEATURE_FUSION
- ReleaseHolder<IBindResult> pIBindResultNI;
-
- if (SUCCEEDED(hr = m_pIBindResult->GetNativeImage(&pIBindResultNI, nullptr)) && pIBindResultNI != nullptr)
- {
- ReleaseHolder<ICLRPrivResource> pResourceNI = GetResourceForBindResult(pIBindResultNI);
- if (InterlockedCompareExchangeT<ICLRPrivResource *>(&m_pIResourceNI, pResourceNI, nullptr) == nullptr)
- pResourceNI.SuppressRelease();
- }
-#else
if (m_pIBindResult->HasNativeImage())
{
SString sPath = m_pIBindResult->GetNativeImage()->GetPath();
m_pIResourceNI = new CLRPrivResourcePathImpl(sPath.GetUnicode());
m_pIResourceNI->AddRef();
}
-#endif
IfFailGo(hr);
}
diff --git a/src/vm/clrprivbinderwinrt.h b/src/vm/clrprivbinderwinrt.h
index caaefff6d2..14c467044b 100644
--- a/src/vm/clrprivbinderwinrt.h
+++ b/src/vm/clrprivbinderwinrt.h
@@ -21,21 +21,17 @@
#include "winrt/windowsstring.h"
#include "appxutil.h"
-#ifndef FEATURE_FUSION
#include "coreclr/corebindresult.h"
// IBindResult maps directly to its one and only implementation on CoreCLR.
typedef CoreBindResult IBindResult;
-#endif // FEATURE_FUSION
//=====================================================================================================================
// Forward declarations
class CLRPrivBinderWinRT;
class CLRPrivAssemblyWinRT;
-#ifdef FEATURE_CORECLR
class BINDER_SPACE::ApplicationContext;
class BINDER_SPACE::Assembly;
-#endif
typedef DPTR(CLRPrivBinderWinRT) PTR_CLRPrivBinderWinRT;
typedef DPTR(CLRPrivAssemblyWinRT) PTR_CLRPrivAssemblyWinRT;
@@ -48,9 +44,6 @@ IsWindowsNamespace(const char * wszNamespace);
//=====================================================================================================================
class CLRPrivBinderWinRT :
public IUnknownCommon<ICLRPrivBinder
-#ifdef FEATURE_FUSION
- , IBindContext
-#endif //FEATURE_FUSION
>
{
friend class CLRPrivAssemblyWinRT;
@@ -189,19 +182,6 @@ public:
HRESULT * pResult,
ICLRPrivAssembly ** ppAssembly);
-#ifdef FEATURE_FUSION
- //=============================================================================================
- // IBindContext interface methods
-
- // Implements interface method code:IBindContext::PreBind.
- STDMETHOD(PreBind)(
- IAssemblyName * pIAssemblyName,
- DWORD dwPreBindFlags,
- IBindResult ** ppIBindResult);
-
- // Implements interface method code:IBindContext::IsDefaultContext.
- STDMETHOD(IsDefaultContext)();
-#endif //FEATURE_FUSION
//=============================================================================================
// Class methods
@@ -239,15 +219,11 @@ public:
IBindResult ** ppIBindResult,
BOOL fPreBind = FALSE);
-#ifndef FEATURE_FUSION
HRESULT GetAssemblyAndTryFindNativeImage(SString &sWinmdFilename, LPCWSTR pwzSimpleName, BINDER_SPACE::Assembly ** ppAssembly);
-#endif
-#ifdef FEATURE_CORECLR
// On Phone the application's APP_PATH CoreCLR hosting config property is used as the app
// package graph for RoResolveNamespace to find 3rd party WinMDs. This method wires up
// the app paths so the WinRT binder will find 3rd party WinMDs.
HRESULT SetApplicationContext(BINDER_SPACE::ApplicationContext *pApplicationContext, SString &appLocalWinMD);
-#endif
// Finds assembly with WinRT type if it is already loaded
// Note: This method could implement interface code:ICLRPrivWinRtTypeBinder if it is ever needed
PTR_Assembly FindAssemblyForTypeIfLoaded(
@@ -255,9 +231,6 @@ public:
LPCUTF8 szNamespace,
LPCUTF8 szClassName);
-#if defined(FEATURE_COMINTEROP_WINRT_DESKTOP_HOST) && !defined(CROSSGEN_COMPILE)
- BOOL SetLocalWinMDPath(HSTRING localWinMDPath);
-#endif // FEATURE_COMINTEROP_WINRT_DESKTOP_HOST && !CROSSGEN_COMPILE
private:
//=============================================================================================
@@ -286,9 +259,6 @@ private:
CLRPrivBinderUtil::WStringList * pFileNameList,
CLRPrivBinderUtil::WStringList ** ppFileNameList);
-#ifdef FEATURE_FUSION
- HRESULT BindAssemblyToNativeAssembly(CLRPrivAssemblyWinRT *pAssembly);
-#endif
private:
//=============================================================================================
@@ -320,30 +290,11 @@ private:
CLRPrivBinderUtil::HSTRINGArrayHolder m_rgAltPaths;
#endif
-#ifdef FEATURE_FUSION
- // Native binder assisting logic
- BOOL m_fCanUseNativeImages;
-
- ReleaseHolder<IILFingerprintFactory> m_pFingerprintFactory;
-#endif
-#ifdef FEATURE_FUSION
- HRESULT GetParentIBindContext(IBindContext **ppIBindContext);
-#endif //FEATURE_FUSION
-#ifdef FEATURE_CORECLR
BINDER_SPACE::ApplicationContext * m_pApplicationContext;
NewArrayHolder<WCHAR> m_appLocalWinMDPath;
-#endif
-#ifdef FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
- // App-local location that can be probed for WinMD files
- BOOL m_fCanSetLocalWinMDPath;
- CrstExplicitInit m_localWinMDPathLock;
-#ifndef CROSSGEN_COMPILE
- clr::winrt::String m_localWinMDPath;
-#endif // !CROSSGEN_COMPILE
-#endif // FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
}; // class CLRPrivBinderWinRT
diff --git a/src/vm/clrprivtypecachereflectiononlywinrt.cpp b/src/vm/clrprivtypecachereflectiononlywinrt.cpp
deleted file mode 100644
index 40f90dfe3f..0000000000
--- a/src/vm/clrprivtypecachereflectiononlywinrt.cpp
+++ /dev/null
@@ -1,260 +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.
-//
-
-//
-// Contains VM implementation of WinRT type cache for code:CLRPrivBinderReflectionOnlyWinRT binder.
-//
-//=====================================================================================================================
-
-#include "common.h" // precompiled header
-
-#ifndef DACCESS_COMPILE
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
-
-#include "clrprivtypecachereflectiononlywinrt.h"
-#include <typeresolution.h>
-
-//=====================================================================================================================
-// S_OK - pAssembly contains type wszTypeName
-// S_FALSE - pAssembly does not contain type wszTypeName
-//
-HRESULT
-CLRPrivTypeCacheReflectionOnlyWinRT::ContainsType(
- ICLRPrivAssembly * pPrivAssembly,
- LPCWSTR wszTypeName)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
-
- AppDomain * pAppDomain = AppDomain::GetCurrentDomain();
-
- ReleaseHolder<PEAssembly> pPEAssembly;
- IfFailGo(pAppDomain->BindHostedPrivAssembly(nullptr, pPrivAssembly, nullptr, &pPEAssembly, TRUE));
- _ASSERTE(pPEAssembly != nullptr);
-
- {
- // Find DomainAssembly * (can be cached if this is too slow to call always)
- DomainAssembly * pDomainAssembly = pAppDomain->LoadDomainAssembly(
- nullptr, // pIdentity
- pPEAssembly,
- FILE_LOADED,
- nullptr); // pLoadSecurity
-
- // Convert the type name into namespace and type names in UTF8
- StackSString ssTypeNameWCHAR(wszTypeName);
-
- StackSString ssTypeName;
- ssTypeNameWCHAR.ConvertToUTF8(ssTypeName);
- LPUTF8 szTypeName = (LPUTF8)ssTypeName.GetUTF8NoConvert();
-
- LPCUTF8 szNamespace;
- LPCUTF8 szClassName;
- ns::SplitInline(szTypeName, szNamespace, szClassName);
-
- NameHandle typeName(szNamespace, szClassName);
-
- // Find the type in the assembly (use existing hash of all type names defined in the assembly)
- TypeHandle thType;
- mdToken tkType;
- Module * pTypeModule;
- mdToken tkExportedType;
- if (pDomainAssembly->GetAssembly()->GetLoader()->FindClassModuleThrowing(
- &typeName,
- &thType,
- &tkType,
- &pTypeModule,
- &tkExportedType,
- nullptr, // ppClassHashEntry
- nullptr, // pLookInThisModuleOnly
- Loader::DontLoad))
- { // The type is present in the assembly
- hr = S_OK;
- }
- else
- { // The type is not present in the assembly
- hr = S_FALSE;
- }
- }
-
-ErrExit:
- return hr;
-} // CLRPrivTypeCacheReflectionOnlyWinRT::ContainsType
-
-//=====================================================================================================================
-// Raises user event NamespaceResolveEvent to get a list of files for this namespace.
-//
-void
-CLRPrivTypeCacheReflectionOnlyWinRT::RaiseNamespaceResolveEvent(
- LPCWSTR wszNamespace,
- DomainAssembly * pParentAssembly,
- CLRPrivBinderUtil::WStringListHolder * pFileNameList)
-{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE(pFileNameList != nullptr);
-
- AppDomain * pAppDomain = AppDomain::GetCurrentDomain();
-
- GCX_COOP();
-
- struct _gc {
- OBJECTREF AppDomainRef;
- OBJECTREF AssemblyRef;
- STRINGREF str;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- if ((gc.AppDomainRef = pAppDomain->GetRawExposedObject()) != NULL)
- {
- if (pParentAssembly != nullptr)
- {
- gc.AssemblyRef = pParentAssembly->GetExposedAssemblyObject();
- }
-
- MethodDescCallSite onNamespaceResolve(METHOD__APP_DOMAIN__ON_REFLECTION_ONLY_NAMESPACE_RESOLVE, &gc.AppDomainRef);
- gc.str = StringObject::NewString(wszNamespace);
- ARG_SLOT args[3] =
- {
- ObjToArgSlot(gc.AppDomainRef),
- ObjToArgSlot(gc.AssemblyRef),
- ObjToArgSlot(gc.str)
- };
- PTRARRAYREF ResultingAssemblyArrayRef = (PTRARRAYREF) onNamespaceResolve.Call_RetOBJECTREF(args);
- if (ResultingAssemblyArrayRef != NULL)
- {
- for (DWORD i = 0; i < ResultingAssemblyArrayRef->GetNumComponents(); i++)
- {
- ASSEMBLYREF ResultingAssemblyRef = (ASSEMBLYREF) ResultingAssemblyArrayRef->GetAt(i);
- Assembly * pAssembly = ResultingAssemblyRef->GetAssembly();
-
- if (pAssembly->IsCollectible())
- {
- COMPlusThrow(kNotSupportedException, W("NotSupported_CollectibleAssemblyResolve"));
- }
-
- PEAssembly * pPEAssembly = pAssembly->GetManifestFile();
-
- ICLRPrivAssembly * pPrivAssembly = pPEAssembly->GetHostAssembly();
- if ((pPrivAssembly == NULL) || !IsAfContentType_WindowsRuntime(pPEAssembly->GetFlags()))
- {
- COMPlusThrow(kNotSupportedException, IDS_EE_REFLECTIONONLY_WINRT_INVALIDASSEMBLY);
- }
-
- pFileNameList->InsertTail(pPEAssembly->GetILimage()->GetPath());
- }
- }
- }
- GCPROTECT_END();
-} // CLRPrivTypeCacheReflectionOnlyWinRT::RaiseNamespaceResolveEvent
-
-//=====================================================================================================================
-// Implementation of QCall System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMetadata.nResolveNamespace
-// It's basically a PInvoke wrapper into Win8 API RoResolveNamespace
-//
-void
-QCALLTYPE
-CLRPrivTypeCacheReflectionOnlyWinRT::ResolveNamespace(
- LPCWSTR wszNamespace,
- LPCWSTR wszWindowsSdkPath,
- LPCWSTR * rgPackageGraphPaths,
- INT32 cPackageGraphPaths,
- QCall::ObjectHandleOnStack retFileNames)
-{
- QCALL_CONTRACT;
-
- _ASSERTE(wszNamespace != nullptr);
-
- BEGIN_QCALL;
-
- CoTaskMemHSTRINGArrayHolder hFileNames;
-
- if (!WinRTSupported())
- {
- IfFailThrow(COR_E_PLATFORMNOTSUPPORTED);
- }
-
- {
- CLRPrivBinderUtil::HSTRINGArrayHolder rgPackageGraph;
- rgPackageGraph.Allocate(cPackageGraphPaths);
-
- LPCWSTR wszNamespaceRoResolve = wszNamespace;
-
- for (INT32 i = 0; i < cPackageGraphPaths; i++)
- {
- _ASSERTE(rgPackageGraph.GetRawArray()[i] == nullptr);
- WinRtString hsPackageGraphPath;
- IfFailThrow(hsPackageGraphPath.Initialize(rgPackageGraphPaths[i]));
- hsPackageGraphPath.Detach(&rgPackageGraph.GetRawArray()[i]);
- }
-
- UINT32 cchNamespace, cchWindowsSdkPath;
- IfFailThrow(StringCchLength(wszNamespace, &cchNamespace));
- IfFailThrow(StringCchLength(wszWindowsSdkPath, &cchWindowsSdkPath));
-
- DWORD cFileNames = 0;
- HSTRING * rgFileNames = nullptr;
- HRESULT hr = RoResolveNamespace(
- WinRtStringRef(wszNamespace, cchNamespace),
- WinRtStringRef(wszWindowsSdkPath, cchWindowsSdkPath),
- rgPackageGraph.GetCount(),
- rgPackageGraph.GetRawArray(),
- &cFileNames,
- &rgFileNames,
- nullptr, // pcDirectNamespaceChildren
- nullptr); // rgDirectNamespaceChildren
- hFileNames.Init(rgFileNames, cFileNames);
-
- if (hr == HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE))
- { // User tried to resolve 3rd party namespace without passing package graph - throw InvalidOperationException with custom message
- _ASSERTE(cPackageGraphPaths == 0);
- COMPlusThrow(kInvalidOperationException, IDS_EE_REFLECTIONONLY_WINRT_LOADFAILURE_THIRDPARTY);
- }
- IfFailThrow(hr);
- if (hr != S_OK)
- {
- IfFailThrow(E_UNEXPECTED);
- }
- }
-
- {
- GCX_COOP();
-
- PTRARRAYREF orFileNames = NULL;
- GCPROTECT_BEGIN(orFileNames);
-
- orFileNames = (PTRARRAYREF) AllocateObjectArray(hFileNames.GetCount(), g_pStringClass);
-
- for (DWORD i = 0; i < hFileNames.GetCount(); i++)
- {
- UINT32 cchFileName = 0;
-
- HSTRING hsFileName = hFileNames.GetAt(i);
- LPCWSTR wszFileName;
-
- if (hsFileName != nullptr)
- {
- wszFileName = WindowsGetStringRawBuffer(
- hsFileName,
- &cchFileName);
-
- STRINGREF str = StringObject::NewString(wszFileName);
- orFileNames->SetAt(i, str);
- }
- }
-
- retFileNames.Set(orFileNames);
-
- GCPROTECT_END();
- }
-
- END_QCALL;
-} // CLRPrivTypeCacheReflectionOnlyWinRT::ResolveNamespace
-
-//=====================================================================================================================
-
-#endif //FEATURE_REFLECTION_ONLY_LOAD
-#endif //!DACCESS_COMPILE
diff --git a/src/vm/clrprivtypecachereflectiononlywinrt.h b/src/vm/clrprivtypecachereflectiononlywinrt.h
deleted file mode 100644
index a605c3dc2e..0000000000
--- a/src/vm/clrprivtypecachereflectiononlywinrt.h
+++ /dev/null
@@ -1,58 +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.
-//
-
-//
-// Contains VM implementation of code:ICLRPrivTypeCacheReflectionOnlyWinRT for code:CLRPrivBinderReflectionOnlyWinRT binder.
-//
-//=====================================================================================================================
-
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
-
-#pragma once
-
-#include "internalunknownimpl.h"
-#include "clrprivbinding.h"
-
-//=====================================================================================================================
-// Forward declarations
-class DomainAssembly;
-
-//=====================================================================================================================
-class CLRPrivTypeCacheReflectionOnlyWinRT :
- public IUnknownCommon<IUnknown>
-{
-public:
- //=============================================================================================
- // Class methods
-
- // S_OK - pAssembly contains type wszTypeName
- // S_FALSE - pAssembly does not contain type wszTypeName
- STDMETHOD(ContainsType)(
- ICLRPrivAssembly * pAssembly,
- LPCWSTR wszTypeName);
-
-#ifndef DACCESS_COMPILE
-
- // Raises user event NamespaceResolveEvent to get a list of files for this namespace.
- void RaiseNamespaceResolveEvent(
- LPCWSTR wszNamespace,
- DomainAssembly * pParentAssembly,
- CLRPrivBinderUtil::WStringListHolder * pFileNameList);
-
-#endif //!DACCESS_COMPILE
-
- // Implementation of QCall System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMetadata.nResolveNamespace
- // It's basically a PInvoke wrapper into Win8 API RoResolveNamespace
- static
- void QCALLTYPE ResolveNamespace(
- LPCWSTR wszNamespace,
- LPCWSTR wszWindowsSdkPath,
- LPCWSTR * rgPackageGraphPaths,
- INT32 cPackageGraphPaths,
- QCall::ObjectHandleOnStack retFileNames);
-
-}; // class CLRPrivTypeCaheReflectionOnlyWinRT
-
-#endif //FEATURE_REFLECTION_ONLY_LOAD
diff --git a/src/vm/clrtocomcall.cpp b/src/vm/clrtocomcall.cpp
index 60aae0036a..96d0722caf 100644
--- a/src/vm/clrtocomcall.cpp
+++ b/src/vm/clrtocomcall.cpp
@@ -21,9 +21,6 @@
#include "dllimport.h"
#include "mlinfo.h"
#include "eeconfig.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "corhost.h"
#include "reflectioninvocation.h"
#include "mdaassistants.h"
@@ -460,15 +457,6 @@ PCODE ComPlusCall::GetStubForILStub(MethodDesc* pMD, MethodDesc** ppStubMD)
if (*ppStubMD)
{
-#ifdef FEATURE_REMOTING
-#ifndef HAS_REMOTING_PRECODE
- if (!pMD->IsStatic())
- {
- pStub = TheGenericComplusCallStub();
- }
- else
-#endif // !HAS_REMOTING_PRECODE
-#endif
{
pStub = *pComInfo->GetAddrOfILStubField();
}
@@ -481,13 +469,6 @@ PCODE ComPlusCall::GetStubForILStub(MethodDesc* pMD, MethodDesc** ppStubMD)
return pStub;
}
-#ifdef FEATURE_REMOTING
-extern
-Signature InitMessageData(messageData *msgData,
- FramedMethodFrame *pFrame,
- Module **ppModule,
- SigTypeContext *pTypeContext);
-#endif // FEATURE_REMOTING
I4ARRAYREF SetUpWrapperInfo(MethodDesc *pMD)
{
@@ -649,213 +630,6 @@ UINT32 CLRToCOMEventCallWorker(ComPlusMethodFrame* pFrame, ComPlusCallMethodDesc
return 0;
}
-#ifdef FEATURE_REMOTING
-UINT32 CLRToCOMLateBoundWorker(ComPlusMethodFrame* pFrame, ComPlusCallMethodDesc *pMD)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pFrame));
- PRECONDITION(CheckPointer(pMD));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- DISPID DispId = DISPID_UNKNOWN;
- const unsigned cbExtraSlots = 7;
- DWORD BindingFlags = BINDER_AllLookup;
- UINT32 fpRetSize;
- mdProperty pd;
- LPCUTF8 strMemberName;
- mdToken tkMember;
- ULONG uSemantic;
-
- LOG((LF_STUBS, LL_INFO1000, "Calling CLRToCOMLateBoundWorker %s::%s \n", pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName));
-
- // Retrieve the method table and the method desc of the call.
- MethodTable *pItfMT = pMD->GetInterfaceMethodTable();
- ComPlusCallMethodDesc *pItfMD = pMD;
- IMDInternalImport *pMDImport = pItfMT->GetMDImport();
-
- // Make sure this is only called on dispath only interfaces.
- _ASSERTE(pItfMT->GetComInterfaceType() == ifDispatch);
-
- // If this is a method impl MD then we need to retrieve the actual interface MD that
- // this is a method impl for.
- // REVISIT_TODO: Stop using ComSlot to convert method impls to interface MD
- // _ASSERTE(pMD->m_pComPlusCallInfo->m_cachedComSlot == 7);
- // GopalK
- if (!pMD->GetMethodTable()->IsInterface()) {
- pItfMD = (ComPlusCallMethodDesc*)pItfMT->GetMethodDescForSlot(pMD->m_pComPlusCallInfo->m_cachedComSlot - cbExtraSlots);
- CONSISTENCY_CHECK(pMD->GetInterfaceMD() == pItfMD);
- }
-
- // See if there is property information for this member.
- hr = pItfMT->GetModule()->GetPropertyInfoForMethodDef(pItfMD->GetMemberDef(), &pd, &strMemberName, &uSemantic);
- if (hr == S_OK)
- {
- // We are dealing with a property accessor.
- tkMember = pd;
-
- // Determine which type of accessor we are dealing with.
- switch (uSemantic)
- {
- case msGetter:
- {
- // We are dealing with a INVOKE_PROPERTYGET.
- BindingFlags |= BINDER_GetProperty;
- break;
- }
-
- case msSetter:
- {
- // We are dealing with a INVOKE_PROPERTYPUT or a INVOKE_PROPERTYPUTREF.
- ULONG cAssoc;
- ASSOCIATE_RECORD* pAssoc;
- HENUMInternal henum;
- BOOL bPropHasOther = FALSE;
-
- // Retrieve all the associates.
- IfFailThrow(pMDImport->EnumAssociateInit(pd,&henum));
-
- cAssoc = pMDImport->EnumGetCount(&henum);
- _ASSERTE(cAssoc > 0);
-
- ULONG allocSize = cAssoc * sizeof(ASSOCIATE_RECORD);
- if (allocSize < cAssoc)
- COMPlusThrow(kTypeLoadException, IDS_EE_TOOMANYASSOCIATES);
-
- pAssoc = (ASSOCIATE_RECORD*) _alloca((size_t) allocSize);
- IfFailThrow(pMDImport->GetAllAssociates(&henum, pAssoc, cAssoc));
-
- pMDImport->EnumClose(&henum);
-
- // Check to see if there is both a set and an other. If this is the case
- // then the setter is a INVOKE_PROPERTYPUTREF otherwise we will make it a
- // INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF.
- for (ULONG i = 0; i < cAssoc; i++)
- {
- if (pAssoc[i].m_dwSemantics == msOther)
- {
- bPropHasOther = TRUE;
- break;
- }
- }
-
- if (bPropHasOther)
- {
- // There is both a INVOKE_PROPERTYPUT and a INVOKE_PROPERTYPUTREF for this
- // property so we need to be specific and make this invoke a INVOKE_PROPERTYPUTREF.
- BindingFlags |= BINDER_PutRefDispProperty;
- }
- else
- {
- // There is only a setter so we need to make the invoke a Set which will map to
- // INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF.
- BindingFlags = BINDER_SetProperty;
- }
- break;
- }
-
- case msOther:
- {
- // We are dealing with a INVOKE_PROPERTYPUT
- BindingFlags |= BINDER_PutDispProperty;
- break;
- }
-
- default:
- {
- _ASSERTE(!"Invalid method semantic!");
- }
- }
- }
- else
- {
- // We are dealing with a normal method.
- strMemberName = pItfMD->GetName();
- tkMember = pItfMD->GetMemberDef();
- BindingFlags |= BINDER_InvokeMethod;
- }
-
- struct _gc {
- OBJECTREF MemberNameObj;
- OBJECTREF ItfTypeObj;
- OBJECTREF WrapperTypeArr;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
- GCPROTECT_BEGIN(gc);
- {
- // Retrieve the exposed type object for the interface.
- gc.ItfTypeObj = pItfMT->GetManagedClassObject();
-
- // Retrieve the name of the member we will be invoking on. If the member
- // has a DISPID then we will use that to optimize the invoke.
- hr = pItfMD->GetMDImport()->GetDispIdOfMemberDef(tkMember, (ULONG*)&DispId);
- if (hr == S_OK)
- {
- WCHAR strTmp[64];
-
- _snwprintf_s(strTmp, COUNTOF(strTmp), _TRUNCATE, DISPID_NAME_FORMAT_STRING, DispId);
- gc.MemberNameObj = StringObject::NewString(strTmp);
- }
- else
- {
- gc.MemberNameObj = StringObject::NewString(strMemberName);
- }
-
- // MessageData struct will be used in creating the message object
- messageData msgData;
- Module *pModule = NULL;
- SigTypeContext typeContext;
- Signature signature = InitMessageData(&msgData, pFrame, &pModule, &typeContext);
-
- // If the call requires object wrapping, then set up the array
- // of wrapper types.
- if (pMD->RequiresArgumentWrapping())
- gc.WrapperTypeArr = SetUpWrapperInfo(pItfMD);
-
- _ASSERTE(!signature.IsEmpty() && pModule);
-
- // Allocate metasig on the stack
- MetaSig mSig(signature, pModule, &typeContext);
- msgData.pSig = &mSig;
-
- MethodDescCallSite forwardCallToInvoke(METHOD__CLASS__FORWARD_CALL_TO_INVOKE, &gc.ItfTypeObj);
-
- // Prepare the arguments that will be passed to the method.
- ARG_SLOT Args[] =
- {
- ObjToArgSlot(gc.ItfTypeObj),
- ObjToArgSlot(gc.MemberNameObj),
- (ARG_SLOT)BindingFlags,
- ObjToArgSlot(pFrame->GetThis()),
- ObjToArgSlot(gc.WrapperTypeArr),
- (ARG_SLOT)&msgData,
- };
-
- // Retrieve the array of members from the type object.
- forwardCallToInvoke.CallWithValueTypes(Args);
-
- // the return value is written into the Frame's neginfo, so we don't
- // need to return it directly. We can just have the stub do that work.
- // However, the stub needs to know what type of FP return this is, if
- // any, so we return the fpReturnSize info as the return value.
- {
- mSig.Reset();
-
- ArgIterator argit(&mSig);
- fpRetSize = argit.GetFPReturnSize();
- }
- }
- GCPROTECT_END();
-
- return fpRetSize;
-}
-#endif // FEATURE_REMOTING
// calls that propagate from CLR to COM
@@ -908,14 +682,6 @@ UINT32 STDCALL CLRToCOMWorker(TransitionBlock * pTransitionBlock, ComPlusCallMet
{
returnValue = CLRToCOMEventCallWorker(pFrame, pMD);
}
-#ifdef FEATURE_REMOTING
- else if (pItfMT->GetComInterfaceType() == ifDispatch)
- {
- // If the interface is a Dispatch only interface then convert the early bound
- // call to a late bound call.
- returnValue = CLRToCOMLateBoundWorker(pFrame, pMD);
- }
-#endif // FEATURE_REMOTING
else
{
LOG((LF_STUBS, LL_INFO1000, "Calling CLRToCOMWorker %s::%s \n", pMD->m_pszDebugClassName, pMD->m_pszDebugMethodName));
diff --git a/src/vm/clsload.cpp b/src/vm/clsload.cpp
index fe74bf8a6f..d1931479c3 100644
--- a/src/vm/clsload.cpp
+++ b/src/vm/clsload.cpp
@@ -52,9 +52,6 @@
#include "virtualcallstub.h"
#include "stringarraylist.h"
-#if defined(FEATURE_FUSION) && !defined(DACCESS_COMPILE)
-#include "policy.h" // For Fusion::Util::IsAnyFrameworkAssembly
-#endif
// This method determines the "loader module" for an instantiated type
// or method. The rule must ensure that any types involved in the
@@ -1364,20 +1361,7 @@ TypeHandle ClassLoader::LookupTypeKey(TypeKey *pKey,
TypeHandle th;
- // If this is the GC thread, and we're hosted, we're in a sticky situation with
- // SQL where we may have suspended another thread while doing Thread::SuspendRuntime.
- // In this case, we have the issue that a thread holding this lock could be
- // suspended, perhaps implicitly because the active thread on the SQL scheduler
- // has been suspended by the GC thread. In such a case, we need to skip taking
- // the lock. We can be sure that there will be no races in such a condition because
- // we will only be looking for types that are already loaded, or for a type that
- // is not loaded, but we will never cause the type to get loaded, and so the result
- // of the lookup will not change.
-#ifndef DACCESS_COMPILE
- if (fCheckUnderLock && !(IsGCThread() && CLRTaskHosted()))
-#else
if (fCheckUnderLock)
-#endif // DACCESS_COMPILE
{
th = LookupTypeKeyUnderLock(pKey, pTable, pLock);
}
@@ -4620,24 +4604,7 @@ VOID ClassLoader::AddAvailableClassHaveLock(
// However, this used to be allowed in 1.0/1.1, and some third-party DLLs have
// been obfuscated so that they have duplicate private typedefs.
// We must allow this for old assemblies for app compat reasons
-#ifdef FEATURE_CORECLR
pModule->GetAssembly()->ThrowBadImageException(pszNameSpace, pszName, BFA_MULT_TYPE_SAME_NAME);
-#else
- LPCSTR pszVersion = NULL;
- if (FAILED(pModule->GetMDImport()->GetVersionString(&pszVersion)))
- {
- pModule->GetAssembly()->ThrowBadImageException(pszNameSpace, pszName, BFA_MULT_TYPE_SAME_NAME);
- }
-
- SString ssVersion(SString::Utf8, pszVersion);
- SString ssV1(SString::Literal, "v1.");
-
- AdjustImageRuntimeVersion(&ssVersion);
-
- // If not "v1.*", throw an exception
- if (!ssVersion.BeginsWith(ssV1))
- pModule->GetAssembly()->ThrowBadImageException(pszNameSpace, pszName, BFA_MULT_TYPE_SAME_NAME);
-#endif
}
}
else {
@@ -4914,41 +4881,6 @@ bool StaticAccessCheckContext::IsCallerCritical()
}
-#ifndef FEATURE_CORECLR
-
-//******************************************************************************
-// This function determines whether a Type is accessible from
-// outside of the assembly it lives in.
-
-static BOOL IsTypeVisibleOutsideAssembly(MethodTable* pMT)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
- DWORD dwProtection;
- // check all types in nesting chain, while inner types are public
- while (IsTdPublic(dwProtection = pMT->GetClass()->GetProtection()) ||
- IsTdNestedPublic(dwProtection))
- {
- // if type is nested, check outer type, too
- if (IsTdNested(dwProtection))
- {
- pMT = GetEnclosingMethodTable(pMT);
- }
- // otherwise, type is visible outside of the assembly
- else
- {
- return TRUE;
- }
- }
- return FALSE;
-} // static BOOL IsTypeVisibleOutsideAssembly(MethodTable* pMT)
-
-#endif //!FEATURE_CORECLR
//******************************************************************************
@@ -5031,7 +4963,6 @@ BOOL AccessCheckOptions::DemandMemberAccess(AccessCheckContext *pContext, Method
BOOL canAccessTarget = FALSE;
#ifndef CROSSGEN_COMPILE
-#ifdef FEATURE_CORECLR
BOOL fAccessingFrameworkCode = FALSE;
@@ -5079,102 +5010,6 @@ BOOL AccessCheckOptions::DemandMemberAccess(AccessCheckContext *pContext, Method
ThrowAccessException(pContext, pTargetMT, NULL, fAccessingFrameworkCode);
}
-#else // FEATURE_CORECLR
-
- GCX_COOP();
-
- // Overriding the rules of visibility checks in Win8 immersive: no access is allowed to internal
- // code in the framework even in full trust, unless the caller is also framework code.
- if ( (m_accessCheckType == kUserCodeOnlyRestrictedMemberAccess ||
- m_accessCheckType == kUserCodeOnlyRestrictedMemberAccessNoTransparency) &&
- visibilityCheck )
- {
- IAssemblyName *pIAssemblyName = pTargetMT->GetAssembly()->GetFusionAssemblyName();
-
- HRESULT hr = Fusion::Util::IsAnyFrameworkAssembly(pIAssemblyName);
-
- // S_OK: pIAssemblyName is a framework assembly.
- // S_FALSE: pIAssemblyName is not a framework assembly.
- // Other values: pIAssemblyName is an invalid name.
- if (hr == S_OK)
- {
- if (pContext->IsCalledFromInterop())
- return TRUE;
-
- // If the caller method is NULL and we are not called from interop
- // this is not a normal method access check (e.g. a CA accessibility check)
- // The access check should fail in this case.
- hr = S_FALSE;
-
- MethodDesc* pCallerMD = pContext->GetCallerMethod();
- if (pCallerMD != NULL)
- {
- pIAssemblyName = pCallerMD->GetAssembly()->GetFusionAssemblyName();
- hr = Fusion::Util::IsAnyFrameworkAssembly(pIAssemblyName);
- }
-
- // The caller is not framework code.
- if (hr != S_OK)
- {
- if (m_fThrowIfTargetIsInaccessible)
- ThrowAccessException(pContext, pTargetMT, NULL, TRUE);
- else
- return FALSE;
- }
- }
- }
-
- EX_TRY
- {
- if (m_accessCheckType == kMemberAccess)
- {
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, REFLECTION_MEMBER_ACCESS);
- }
- else
- {
- _ASSERTE(m_accessCheckType == kRestrictedMemberAccess ||
- m_accessCheckType == kUserCodeOnlyRestrictedMemberAccess ||
- (m_accessCheckType == kUserCodeOnlyRestrictedMemberAccessNoTransparency && visibilityCheck));
-
- // JIT guarantees that pTargetMT has been fully loaded and ready to execute by this point, but reflection doesn't.
- // So GetSecurityDescriptor could AV because the DomainAssembly cannot be found.
- // For now we avoid this by calling EnsureActive aggressively. We might want to move this to the reflection code in the future:
- // ReflectionInvocation::PerformVisibilityCheck, PerformSecurityCheckHelper, COMDelegate::BindToMethodName/Info, etc.
- // We don't need to call EnsureInstanceActive because we will be doing access check on all the generic arguments any way so
- // EnsureActive will be called on everyone of them if needed.
- pTargetMT->EnsureActive();
-
- IAssemblySecurityDescriptor * pTargetSecurityDescriptor = pTargetMT->GetModule()->GetSecurityDescriptor();
- _ASSERTE(pTargetSecurityDescriptor != NULL);
-
- if (m_pAccessContext != NULL)
- {
- // If we have a context, use it to do the demand
- Security::ReflectionTargetDemand(REFLECTION_MEMBER_ACCESS,
- pTargetSecurityDescriptor,
- m_pAccessContext);
- }
- else
- {
- // Just do a normal Demand
- Security::ReflectionTargetDemand(REFLECTION_MEMBER_ACCESS, pTargetSecurityDescriptor);
- }
- }
-
- canAccessTarget = TRUE;
- }
- EX_CATCH
- {
- canAccessTarget = FALSE;
-
- if (m_fThrowIfTargetIsInaccessible)
- {
- ThrowAccessException(pContext, pTargetMT, GET_EXCEPTION());
- }
- }
- EX_END_CATCH(RethrowTerminalExceptions);
-
-#endif // FEATURE_CORECLR
#endif // CROSSGEN_COMPILE
return canAccessTarget;
@@ -5335,55 +5170,7 @@ void GetAccessExceptionAdditionalContextForSecurity(Assembly *pAccessingAssembly
pContextInformation->Append(accessingFrameworkCodeError);
}
-#ifndef FEATURE_CORECLR
- if (isTransparencyError)
- {
- ModuleSecurityDescriptor *pMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pAccessingAssembly);
-
- // If the accessing assembly is APTCA and using level 2 transparency, then transparency errors may be
- // because APTCA newly opts assemblies into being all transparent.
- if (pMSD->IsMixedTransparency() && !pAccessingAssembly->GetSecurityTransparencyBehavior()->DoesUnsignedImplyAPTCA())
- {
- SString callerDisplayName;
- pAccessingAssembly->GetDisplayName(callerDisplayName);
-
- SString level2AptcaTransparencyError;
- EEException::GetResourceMessage(IDS_ACCESS_EXCEPTION_CONTEXT_LEVEL2_APTCA, level2AptcaTransparencyError, callerDisplayName);
- pContextInformation->Append(level2AptcaTransparencyError);
- }
-
- // If the assessing assembly is fully transparent and it is partially trusted, then transparency
- // errors may be because the CLR forced the assembly to be transparent due to its trust level.
- if (pMSD->IsAllTransparentDueToPartialTrust())
- {
- _ASSERTE(pMSD->IsAllTransparent());
- SString callerDisplayName;
- pAccessingAssembly->GetDisplayName(callerDisplayName);
-
- SString partialTrustTransparencyError;
- EEException::GetResourceMessage(IDS_ACCESS_EXCEPTION_CONTEXT_PT_TRANSPARENT, partialTrustTransparencyError, callerDisplayName);
-
- pContextInformation->Append(partialTrustTransparencyError);
- }
- }
-#endif // FEATURE_CORECLR
-
-#if defined(FEATURE_APTCA) && !defined(CROSSGEN_COMPILE)
- // If the target assembly is conditionally APTCA, then it may needed to have been enabled in the domain
- SString conditionalAptcaContext = Security::GetConditionalAptcaAccessExceptionContext(pTargetAssembly);
- if (!conditionalAptcaContext.IsEmpty())
- {
- pContextInformation->Append(conditionalAptcaContext);
- }
-
- // If the target assembly is APTCA killbitted, then indicate that as well
- SString aptcaKillBitContext = Security::GetAptcaKillBitAccessExceptionContext(pTargetAssembly);
- if (!aptcaKillBitContext.IsEmpty())
- {
- pContextInformation->Append(aptcaKillBitContext);
- }
-#endif // FEATURE_APTCA && !CROSSGEN_COMPILE
}
// Generate additional context about the root cause of an access exception which may help in debugging it (for
@@ -5690,18 +5477,6 @@ static BOOL CheckTransparentAccessToCriticalCode(
(pOptionalTargetField ? 1 : 0) +
(pOptionalTargetType ? 1 : 0)));
-#ifndef FEATURE_CORECLR
- if (pTargetMT->GetAssembly()->GetSecurityTransparencyBehavior()->DoesPublicImplyTreatAsSafe())
- {
- // @ telesto: public => TAS in non-coreclr only. The intent is to remove this ifdef and remove
- // public => TAS in all flavors/branches.
- // check if the Target member accessible outside the assembly
- if (IsMdPublic(dwMemberAccess) && IsTypeVisibleOutsideAssembly(pTargetMT))
- {
- return TRUE;
- }
- }
-#endif // !FEATURE_CORECLR
// if the caller [Method] is transparent, do special security checks
// check if security disallows access to target member
@@ -5766,21 +5541,6 @@ static BOOL AssemblyOrFriendAccessAllowed(Assembly *pAccessingAssembly,
return TRUE;
}
-#if defined(FEATURE_REMOTING) && !defined(CROSSGEN_COMPILE)
- else if (pAccessingAssembly->GetDomain() != pTargetAssembly->GetDomain() &&
- pAccessingAssembly->GetFusionAssemblyName()->IsEqual(pTargetAssembly->GetFusionAssemblyName(), ASM_CMPF_NAME | ASM_CMPF_PUBLIC_KEY_TOKEN) == S_OK)
- {
- // If we're accessing an internal type across AppDomains, we'll end up saying that an assembly is
- // not allowed to access internal types in itself, since the Assembly *'s will not compare equal.
- // This ends up being confusing for users who don't have a deep understanding of the loader and type
- // system, and also creates different behavior if your assembly is shared vs unshared (if you are
- // shared, your Assembly *'s will match since they're in the shared domain).
- //
- // In order to ease the confusion, we'll consider assemblies to be friends of themselves in this
- // scenario -- if a name and public key match succeeds, we'll grant internal access across domains.
- return TRUE;
- }
-#endif // FEATURE_REMOTING && !CROSSGEN_COMPILE
else if (pOptionalTargetField != NULL)
{
return pTargetAssembly->GrantsFriendAccessTo(pAccessingAssembly, pOptionalTargetField);
diff --git a/src/vm/clsload.hpp b/src/vm/clsload.hpp
index a3a0de3cf4..2ee6524a7b 100644
--- a/src/vm/clsload.hpp
+++ b/src/vm/clsload.hpp
@@ -408,19 +408,6 @@ public:
// CoreCLR: Do RestrictedMemberAcess visibility checks but bypass transparency checks.
kRestrictedMemberAccessNoTransparency,
-#ifndef FEATURE_CORECLR
- // Used by DynamicMethod with kRestrictedMemberAccess in Win8 immersive mode.
- // Desktop: Equals kNormalAccessibilityChecks for non-framework code calling framework code,
- // kRestrictedMemberAccess otherwise.
- kUserCodeOnlyRestrictedMemberAccess,
-
- // A variation of kUserCodeOnlyRestrictedMemberAccess, but without transparency checks.
- // This is used for reflection invocation in Win8 immersive when all domains on the call stack is full trust.
- // This is an optimization to avoid stackwalks for transparency checks in full trust.
- // Note that both kUserCodeOnlyRestrictedMemberAccess and kUserCodeOnlyRestrictedMemberAccessNoTransparency
- // are needed because we restrict user code from accessing framework internals in Win8 immersive even in full trust.
- kUserCodeOnlyRestrictedMemberAccessNoTransparency
-#endif
};
AccessCheckOptions(
@@ -472,11 +459,7 @@ public:
BOOL TransparencyCheckNeeded() const
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return (m_accessCheckType != kNormalAccessNoTransparency && m_accessCheckType != kRestrictedMemberAccessNoTransparency);
-#else //FEATURE_CORECLR
- return (m_accessCheckType != kUserCodeOnlyRestrictedMemberAccessNoTransparency);
-#endif //FEATURE_CORECLR
}
static AccessCheckOptions* s_pNormalAccessChecks;
diff --git a/src/vm/clsload.inl b/src/vm/clsload.inl
index a362d5a3db..991498ec9c 100644
--- a/src/vm/clsload.inl
+++ b/src/vm/clsload.inl
@@ -80,14 +80,8 @@ inline void AccessCheckOptions::Initialize(
!throwIfTargetIsInaccessible ||
((pTargetMT ? 1 : 0) + (pTargetMethod ? 1 : 0) + (pTargetField ? 1 : 0)) == 1);
// m_pAccessContext can only be set for kRestrictedMemberAccess
-#ifdef FEATURE_CORECLR
PRECONDITION(m_pAccessContext == NULL ||
accessCheckType == AccessCheckOptions::kRestrictedMemberAccess);
-#else
- PRECONDITION(m_pAccessContext == NULL ||
- accessCheckType == AccessCheckOptions::kUserCodeOnlyRestrictedMemberAccess ||
- accessCheckType == AccessCheckOptions::kRestrictedMemberAccess);
-#endif
}
CONTRACTL_END;
diff --git a/src/vm/codeman.cpp b/src/vm/codeman.cpp
index 8fc851d86b..73b4c06565 100644
--- a/src/vm/codeman.cpp
+++ b/src/vm/codeman.cpp
@@ -31,9 +31,7 @@
#include "debuginfostore.h"
#include "strsafe.h"
-#ifdef FEATURE_CORECLR
#include "configuration.h"
-#endif
#ifdef _WIN64
#define CHECK_DUPLICATED_STRUCT_LAYOUTS
@@ -987,6 +985,13 @@ PTR_VOID GetUnwindDataBlob(TADDR moduleBase, PTR_RUNTIME_FUNCTION pRuntimeFuncti
return pUnwindInfo;
+#elif defined(_TARGET_X86_)
+ PTR_UNWIND_INFO pUnwindInfo(dac_cast<PTR_UNWIND_INFO>(moduleBase + RUNTIME_FUNCTION__GetUnwindInfoAddress(pRuntimeFunction)));
+
+ *pSize = sizeof(UNWIND_INFO);
+
+ return pUnwindInfo;
+
#elif defined(_TARGET_ARM_)
// if this function uses packed unwind data then at least one of the two least significant bits
@@ -1397,12 +1402,12 @@ struct JIT_LOAD_DATA
// Here's the global data for JIT load and initialization state.
JIT_LOAD_DATA g_JitLoadData;
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
// Global that holds the path to custom JIT location
extern "C" LPCWSTR g_CLRJITPath = nullptr;
-#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE)
// LoadAndInitializeJIT: load the JIT dll into the process, and initialize it (call the UtilCode initialization function,
@@ -1439,7 +1444,6 @@ static void LoadAndInitializeJIT(LPCWSTR pwzJitName, OUT HINSTANCE* phJit, OUT I
HRESULT hr = E_FAIL;
-#ifdef FEATURE_CORECLR
PathString CoreClrFolderHolder;
extern HINSTANCE g_hThisInst;
bool havePath = false;
@@ -1482,9 +1486,6 @@ static void LoadAndInitializeJIT(LPCWSTR pwzJitName, OUT HINSTANCE* phJit, OUT I
}
}
-#else
- hr = g_pCLRRuntime->LoadLibrary(pwzJitName, phJit);
-#endif
if (SUCCEEDED(hr))
{
@@ -1493,25 +1494,9 @@ static void LoadAndInitializeJIT(LPCWSTR pwzJitName, OUT HINSTANCE* phJit, OUT I
EX_TRY
{
bool fContinueToLoadJIT = false;
-#if !defined(FEATURE_CORECLR)
- typedef void (__stdcall* psxsJitStartup) (CoreClrCallbacks const &);
- psxsJitStartup sxsJitStartupFn = (psxsJitStartup) GetProcAddress(*phJit, "sxsJitStartup");
-
- if (sxsJitStartupFn)
- {
- pJitLoadData->jld_status = JIT_LOAD_STATUS_DONE_GET_SXSJITSTARTUP;
-
- CoreClrCallbacks cccallbacks = GetClrCallbacks();
- (*sxsJitStartupFn) (cccallbacks);
-
- pJitLoadData->jld_status = JIT_LOAD_STATUS_DONE_CALL_SXSJITSTARTUP;
- fContinueToLoadJIT = true;
- }
-#else // FEATURE_CORECLR
// For CoreCLR, we never use "sxsJitStartup" as that is Desktop utilcode initialization
// specific. Thus, assume we always got
fContinueToLoadJIT = true;
-#endif // !defined(FEATURE_CORECLR)
if (fContinueToLoadJIT)
{
@@ -1644,7 +1629,7 @@ BOOL EEJitManager::LoadJIT()
// Set as a courtesy to code:CorCompileGetRuntimeDll
s_ngenCompilerDll = m_JITCompiler;
-#if (defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)) || (defined(_TARGET_X86_) && defined(FEATURE_CORECLR))
+#if defined(_TARGET_X86_)
// If COMPlus_UseLegacyJit=1, then we fall back to compatjit.dll.
//
// This fallback mechanism was introduced for Visual Studio "14" Preview, when JIT64 (the legacy JIT) was replaced with
@@ -1670,11 +1655,7 @@ BOOL EEJitManager::LoadJIT()
// Thus, the COMPlus_useLegacyJit=1 mechanism has been enabled for x86 CoreCLR. This scenario does not have the UseRyuJIT
// registry key, nor the AppX binder mode.
-#if defined(FEATURE_CORECLR)
bool fUseRyuJit = true;
-#else
- bool fUseRyuJit = UseRyuJit();
-#endif
if ((!IsCompilationProcess() || !fUseRyuJit) && // Use RyuJIT for all NGEN, unless we're falling back to JIT64 for everything.
(newJitCompiler != nullptr)) // the main JIT must successfully load before we try loading the fallback JIT
@@ -1688,34 +1669,13 @@ BOOL EEJitManager::LoadJIT()
if (!fUsingCompatJit)
{
-#if defined(FEATURE_CORECLR)
DWORD useLegacyJit = Configuration::GetKnobBooleanValue(W("System.JIT.UseWindowsX86CoreLegacyJit"), CLRConfig::EXTERNAL_UseWindowsX86CoreLegacyJit);
-#else
- DWORD useLegacyJit = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_UseLegacyJit); // uncached access, since this code is run no more than one time
-#endif
if (useLegacyJit == 1)
{
fUsingCompatJit = TRUE;
}
}
-#if defined(FEATURE_APPX_BINDER)
- if (!fUsingCompatJit)
- {
- // AppX applications don't have a .config file for per-app configuration. So, we allow the placement of a single
- // distinguished file, "UseLegacyJit.txt" in the root of the app's package to indicate that the app should fall
- // back to JIT64. This same file is also used to prevent this app from participating in AutoNgen.
- if (AppX::IsAppXProcess())
- {
- WCHAR szPathName[MAX_LONGPATH];
- UINT32 cchPathName = MAX_LONGPATH;
- if (AppX::FindFileInCurrentPackage(L"UseLegacyJit.txt", &cchPathName, szPathName, PACKAGE_FILTER_HEAD) == S_OK)
- {
- fUsingCompatJit = TRUE;
- }
- }
- }
-#endif // FEATURE_APPX_BINDER
if (fUsingCompatJit)
{
@@ -1740,7 +1700,7 @@ BOOL EEJitManager::LoadJIT()
}
}
}
-#endif // (defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)) || (defined(_TARGET_X86_) && defined(FEATURE_CORECLR))
+#endif // (defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE)) || (defined(_TARGET_X86_) )
#endif // !FEATURE_MERGE_JIT_AND_ENGINE
@@ -4404,7 +4364,6 @@ LPCWSTR ExecutionManager::GetJitName()
LPCWSTR pwzJitName = NULL;
-#if defined(FEATURE_CORECLR)
#if !defined(CROSSGEN_COMPILE)
if (g_CLRJITPath != nullptr)
{
@@ -4419,10 +4378,6 @@ LPCWSTR ExecutionManager::GetJitName()
}
}
#endif // !defined(CROSSGEN_COMPILE)
-#else // !FEATURE_CORECLR
- // Try to obtain a name for the jit library from the env. variable
- IfFailThrow(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_JitName, const_cast<LPWSTR *>(&pwzJitName)));
-#endif // !FEATURE_CORECLR
if (NULL == pwzJitName)
{
diff --git a/src/vm/comcache.cpp b/src/vm/comcache.cpp
index a1f2416c5c..ab2e53024d 100644
--- a/src/vm/comcache.cpp
+++ b/src/vm/comcache.cpp
@@ -91,11 +91,7 @@ static IErrorInfo *CheckForFuncEvalAbortNoThrow(HRESULT hr)
else
{
// QI failed, put the IErrorInfo back
- LeaveRuntimeHolderNoThrow lrh((size_t)SetErrorInfo);
- if (SUCCEEDED(lrh.GetHR()))
- {
- SetErrorInfo(0, pErrorInfo);
- }
+ SetErrorInfo(0, pErrorInfo);
}
}
}
@@ -1512,7 +1508,6 @@ HRESULT CtxEntry::EnterContext(PFNCTXCALLBACK pCallbackFunc, LPVOID pData)
EX_TRY
{
- LeaveRuntimeHolder lrHolder(**(size_t**)(IContextCallback*)pCallback);
hr = ((IContextCallback*)pCallback)->ContextCallback(EnterContextCallback, &callBackData, IID_IEnterActivityWithNoLock, 2, NULL);
}
EX_CATCH
@@ -1531,13 +1526,7 @@ HRESULT CtxEntry::EnterContext(PFNCTXCALLBACK pCallbackFunc, LPVOID pData)
LOG((LF_INTEROP, LL_INFO100, "Entering into context 0x08X has failed since the debugger is blocking it\n", m_pCtxCookie));
// put the IErrorInfo back
- {
- LeaveRuntimeHolderNoThrow lrh((size_t)SetErrorInfo);
- if (SUCCEEDED(lrh.GetHR()))
- {
- SetErrorInfo(0, pErrorInfo);
- }
- }
+ SetErrorInfo(0, pErrorInfo);
}
else
{
diff --git a/src/vm/comcallablewrapper.cpp b/src/vm/comcallablewrapper.cpp
index 17f0fb60aa..540c708f16 100644
--- a/src/vm/comcallablewrapper.cpp
+++ b/src/vm/comcallablewrapper.cpp
@@ -16,9 +16,6 @@
#include "clrtypes.h"
#include "comcallablewrapper.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "object.h"
#include "field.h"
@@ -409,17 +406,6 @@ MethodTable* RefineProxy(OBJECTREF pServer)
MethodTable* pRefinedClass = NULL;
-#ifdef FEATURE_REMOTING
- GCPROTECT_BEGIN(pServer);
- if (pServer->IsTransparentProxy())
- {
- // if we have a transparent proxy let us refine it fully
- // before giving it out to unmanaged code
- REFLECTCLASSBASEREF refClass= CRemotingServices::GetClass(pServer);
- pRefinedClass = refClass->GetType().GetMethodTable();
- }
- GCPROTECT_END();
-#endif
RETURN pRefinedClass;
}
@@ -959,43 +945,43 @@ void SimpleComCallWrapper::BuildRefCountLogMessage(LPCWSTR wszOperation, StackSS
}
CONTRACTL_END;
- GCX_COOP();
-
- // There's no way how to get the class name if the AD is unloaded. We will just skip it if it
- // is the case. Note that we do log the AD unload event in SimpleComCallWrapper::Neuter so there
- // should still be enough useful information in the log.
- AppDomainFromIDHolder ad(GetRawDomainID(), TRUE);
- if (!ad.IsUnloaded())
- {
- LPCUTF8 pszClassName;
- LPCUTF8 pszNamespace;
- if (SUCCEEDED(m_pMT->GetMDImport()->GetNameOfTypeDef(m_pMT->GetCl(), &pszClassName, &pszNamespace)))
+ // Don't worry about domain unloading in CoreCLR
+ LPCUTF8 pszClassName;
+ LPCUTF8 pszNamespace;
+ if (SUCCEEDED(m_pMT->GetMDImport()->GetNameOfTypeDef(m_pMT->GetCl(), &pszClassName, &pszNamespace)))
+ {
+ OBJECTHANDLE handle = GetMainWrapper()->GetRawObjectHandle();
+ _UNCHECKED_OBJECTREF obj = NULL;
+
+ // Force retriving the handle without using OBJECTREF and under cooperative mode
+ // We only need the value in ETW events and it doesn't matter if it is super accurate
+ if (handle != NULL)
+ obj = *((_UNCHECKED_OBJECTREF *)(handle));
+
+ if (ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, CCWRefCountChange))
+ FireEtwCCWRefCountChange(
+ handle,
+ (Object *)obj,
+ this,
+ dwEstimatedRefCount,
+ NULL, // domain value is not interesting in CoreCLR
+ pszClassName, pszNamespace, wszOperation, GetClrInstanceId());
+
+ if (g_pConfig->ShouldLogCCWRefCountChange(pszClassName, pszNamespace))
{
- OBJECTHANDLE handle = GetMainWrapper()->GetRawObjectHandle();
- Object* obj = NULL;
- if (handle != NULL)
- obj = OBJECTREFToObject(ObjectFromHandle(handle));
-
- if (ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, CCWRefCountChange))
- FireEtwCCWRefCountChange(handle, obj, this, dwEstimatedRefCount, (LONGLONG) ad.GetAddress(),
- pszClassName, pszNamespace, wszOperation, GetClrInstanceId());
-
- if (g_pConfig->ShouldLogCCWRefCountChange(pszClassName, pszNamespace))
+ EX_TRY
{
- EX_TRY
- {
- StackSString ssClassName;
- TypeString::AppendType(ssClassName, TypeHandle(m_pMT));
+ StackSString ssClassName;
+ TypeString::AppendType(ssClassName, TypeHandle(m_pMT));
- ssMessage.Printf(W("LogCCWRefCountChange[%s]: '%s', Object=poi(%p)"),
- wszOperation, // %s operation
- ssClassName.GetUnicode(), // %s type name
- handle); // %p Object
- }
- EX_CATCH
- { }
- EX_END_CATCH(SwallowAllExceptions);
+ ssMessage.Printf(W("LogCCWRefCountChange[%s]: '%s', Object=poi(%p)"),
+ wszOperation, // %s operation
+ ssClassName.GetUnicode(), // %s type name
+ handle); // %p Object
}
+ EX_CATCH
+ { }
+ EX_END_CATCH(SwallowAllExceptions);
}
}
}
@@ -1286,10 +1272,6 @@ void SimpleComCallWrapper::InitNew(OBJECTREF oref, ComCallWrapperCache *pWrapper
MethodTable* pMT = pTemplate->GetClassType().GetMethodTable();
PREFIX_ASSUME(pMT != NULL);
-#ifdef FEATURE_REMOTING
- if (CRemotingServices::IsTransparentProxy(OBJECTREFToObject(oref)))
- m_flags |= enum_IsObjectTP;
-#endif
m_pMT = pMT;
m_pWrap = pWrap;
@@ -1774,12 +1756,10 @@ IUnknown* SimpleComCallWrapper::QIStandardInterface(Enum_StdInterfaces index)
else if (index == enum_IDispatchEx)
{
-#ifdef FEATURE_CORECLR
if (AppX::IsAppXProcess())
{
RETURN NULL;
}
-#endif // FEATURE_CORECLR
if (SupportsIReflect(m_pMT))
{
@@ -1988,9 +1968,6 @@ IUnknown* SimpleComCallWrapper::QIStandardInterface(REFIID riid)
// Keeping the Apollo behaviour also ensures that we allow SL 8.1 scenarios (which do not pass the AppX flag like the modern host)
// to use CorDispatcher for async, in the expected manner, as the OS implementation for CoreDispatcher expects objects to be Agile.
if (!IsAggregated()
-#if !defined(FEATURE_CORECLR)
- && AppX::IsAppXProcess()
-#endif // !defined(FEATURE_CORECLR)
)
{
ComCallWrapperTemplate *pTemplate = GetComCallWrapperTemplate();
@@ -2741,11 +2718,7 @@ ComCallWrapper* ComCallWrapper::CreateWrapper(OBJECTREF* ppObj, ComCallWrapperTe
pServer = *ppObj;
-#ifdef FEATURE_REMOTING
- Context *pContext = Context::GetExecutionContext(pServer);
-#else
Context *pContext = GetAppDomain()->GetDefaultContext();
-#endif
// Force Refine the object if it is a transparent proxy
RefineProxy(pServer);
@@ -3614,12 +3587,10 @@ IUnknown* ComCallWrapper::GetComIPFromCCW(ComCallWrapper *pWrap, REFIID riid, Me
}
if (IsIDispatch(riid))
{
-#ifdef FEATURE_CORECLR
if (AppX::IsAppXProcess())
{
RETURN NULL;
}
-#endif // FEATURE_CORECLR
// We don't do visibility checks on IUnknown.
RETURN pWrap->GetIDispatchIP();
@@ -4735,11 +4706,6 @@ BOOL ComMethodTable::LayOutInterfaceMethodTable(MethodTable* pClsMT)
SLOT *pComVtable;
unsigned i;
-#ifndef FEATURE_CORECLR
- // Skip this unnecessary expensive check for CoreCLR
- if (!CheckSigTypesCanBeLoaded(pItfClass))
- return FALSE;
-#endif
LOG((LF_INTEROP, LL_INFO1000, "LayOutInterfaceMethodTable: %s, this: %p\n", pItfClass->GetDebugClassName(), this));
diff --git a/src/vm/comcallablewrapper.h b/src/vm/comcallablewrapper.h
index 3424c2caf0..165179bf8d 100644
--- a/src/vm/comcallablewrapper.h
+++ b/src/vm/comcallablewrapper.h
@@ -1993,13 +1993,6 @@ private:
if (!CanRunManagedCode())
return;
SO_INTOLERANT_CODE_NOTHROW(GetThread(), return; );
- ReverseEnterRuntimeHolderNoThrow REHolder;
- if (CLRTaskHosted())
- {
- HRESULT hr = REHolder.AcquireNoThrow();
- if (FAILED(hr))
- return;
- }
m_pWrap->Cleanup();
}
diff --git a/src/vm/comdelegate.cpp b/src/vm/comdelegate.cpp
index 4c85a0216e..2682c2d32a 100644
--- a/src/vm/comdelegate.cpp
+++ b/src/vm/comdelegate.cpp
@@ -18,9 +18,6 @@
#include "field.h"
#include "dllimportcallback.h"
#include "dllimport.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "eeconfig.h"
#include "mdaassistants.h"
#include "cgensys.h"
@@ -280,7 +277,14 @@ VOID GenerateShuffleArray(MethodDesc* pInvoke, MethodDesc *pTargetMeth, SArray<S
COMPlusThrow(kVerificationException);
}
- UINT stackSizeDelta = stackSizeSrc - stackSizeDst;
+ UINT stackSizeDelta;
+
+#ifdef UNIX_X86_ABI
+ // Stack does not shrink as UNIX_X86_ABI uses CDECL (instead of STDCALL).
+ stackSizeDelta = 0;
+#else
+ stackSizeDelta = stackSizeSrc - stackSizeDst;
+#endif
INT ofsSrc, ofsDst;
@@ -919,28 +923,11 @@ void COMDelegate::BindToMethod(DELEGATEREF *pRefThis,
{
_ASSERTE(pRefFirstArg == NULL || *pRefFirstArg == NULL);
-#ifdef FEATURE_REMOTING
- if (!pTargetMethod->IsStatic())
- {
- // Open-instance delegate may have remoted target if the method is declared by
- // an interface, by a type deriving from MarshalByRefObject, or by System.Object.
- // The following condition is necessary but not sufficient as it's always possible
- // to invoke the delegate on a local instance. Precise check would require doing
- // the check at invocation time. We are secure because we demand MemberAccess when
- // there is a possibility that the invocation will be remote.
- //
- MethodTable *pMT = pTargetMethod->GetMethodTable();
- targetPossiblyRemoted = (pMT == g_pObjectClass || pMT->IsInterface() || pMT->IsMarshaledByRef());
- }
-#endif // FEATURE_REMOTING
}
else
{
// closed-static is OK and we can check the target in the closed-instance case
pInstanceMT = (*pRefFirstArg == NULL ? NULL : (*pRefFirstArg)->GetMethodTable());
-#ifdef FEATURE_REMOTING
- targetPossiblyRemoted = InvokeUtil::IsTargetRemoted(pTargetMethod, pInstanceMT);
-#endif
}
RefSecContext sCtx(InvokeUtil::GetInvocationAccessCheckType(targetPossiblyRemoted));
@@ -1098,7 +1085,6 @@ void COMDelegate::BindToMethod(DELEGATEREF *pRefThis,
GCPROTECT_END();
}
-#ifdef FEATURE_CORECLR
// On the CoreCLR, we don't allow non-fulltrust delegates to be marshaled out (or created: CorHost::CreateDelegate ensures that)
// This helper function checks if we have a full-trust delegate with AllowReversePInvokeCallsAttribute targets.
BOOL COMDelegate::IsFullTrustDelegate(DELEGATEREF pDelegate)
@@ -1218,7 +1204,6 @@ BOOL COMDelegate::IsMethodAllowedToSinkReversePInvoke(MethodDesc *pMD)
NULL));
#endif // FEATURE_WINDOWSPHONE
}
-#endif // FEATURE_CORECLR
// Marshals a managed method to an unmanaged callback provided the
// managed method is static and it's parameters require no marshalling.
@@ -1312,7 +1297,6 @@ LPVOID COMDelegate::ConvertToCallback(OBJECTREF pDelegateObj)
MethodTable* pMT = pDelegate->GetMethodTable();
DelegateEEClass* pClass = (DelegateEEClass*)(pMT->GetClass());
-#ifdef FEATURE_CORECLR
// On the CoreCLR, we only allow marshaling out delegates that we can guarantee are full-trust delegates
if (!IsFullTrustDelegate(pDelegate))
{
@@ -1320,7 +1304,6 @@ LPVOID COMDelegate::ConvertToCallback(OBJECTREF pDelegateObj)
TypeString::AppendType(strDelegateType, pMT, TypeString::FormatNamespace | TypeString::FormatAngleBrackets| TypeString::FormatSignature);
COMPlusThrow(kSecurityException, IDS_E_DELEGATE_FULLTRUST_ARPIC_1, strDelegateType.GetUnicode());
}
-#endif
if (pMT->HasInstantiation())
COMPlusThrowArgumentException(W("delegate"), W("Argument_NeedNonGenericType"));
@@ -1502,13 +1485,11 @@ OBJECTREF COMDelegate::ConvertToDelegate(LPVOID pCallback, MethodTable* pMT)
if (pUMEntryThunk->GetDomainId() != GetAppDomain()->GetId())
COMPlusThrow(kNotSupportedException, W("NotSupported_DelegateMarshalToWrongDomain"));
-#ifdef FEATURE_CORECLR
// On the CoreCLR, we only allow marshaling out delegates that we can guarantee are full-trust delegates
if (!IsFullTrustDelegate((DELEGATEREF)pDelegate))
{
COMPlusThrow(kSecurityException, IDS_E_DELEGATE_FULLTRUST_ARPIC_2);
}
-#endif
GCPROTECT_END();
return pDelegate;
@@ -1590,13 +1571,6 @@ OBJECTREF COMDelegate::ConvertToDelegate(LPVOID pCallback, MethodTable* pMT)
MethodDesc *pStubMD = pClass->m_pForwardStubMD;
_ASSERTE(pStubMD != NULL && pStubMD->IsILStub());
-#ifndef FEATURE_CORECLR
- if (pStubMD->AsDynamicMethodDesc()->HasCopyCtorArgs())
- {
- // static stub that gets its arguments in a thread-static field
- pInterceptStub = NDirect::GetStubForCopyCtor();
- }
-#endif // !FEATURE_CORECLR
#ifdef MDA_SUPPORTED
if (MDA_GET_ASSISTANT(PInvokeStackImbalance))
@@ -1605,16 +1579,6 @@ OBJECTREF COMDelegate::ConvertToDelegate(LPVOID pCallback, MethodTable* pMT)
}
#endif // MDA_SUPPORTED
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (NDirect::IsHostHookEnabled() && CallNeedsHostHook((size_t)pCallback))
- {
- pInterceptStub = GenerateStubForHost(
- pMD,
- pStubMD,
- pCallback,
- pInterceptStub);
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
@@ -1630,13 +1594,11 @@ OBJECTREF COMDelegate::ConvertToDelegate(LPVOID pCallback, MethodTable* pMT)
GCPROTECT_END();
#endif // defined(_TARGET_X86_)
-#ifdef FEATURE_CORECLR
// On the CoreCLR, we only allow marshaling out delegates that we can guarantee are full-trust delegates
if (!IsFullTrustDelegate(delObj))
{
COMPlusThrow(kSecurityException, IDS_E_DELEGATE_FULLTRUST_ARPIC_2);
}
-#endif
return delObj;
}
@@ -2182,17 +2144,6 @@ void COMDelegate::DoUnmanagedCodeAccessCheck(MethodDesc* pMeth)
{
// Check whether this is actually a SuppressUnmanagedCodePermission attribute and
// if so, don't do a demand
-#ifndef FEATURE_CORECLR
- MethodTable* pMTMeth = pMeth->GetMethodTable();
- if (pMTMeth->GetMDImport()->GetCustomAttributeByName(pMeth->GetMethodTable()->GetCl(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK ||
- pMTMeth->GetMDImport()->GetCustomAttributeByName(pMeth->GetMemberDef(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK)
-#endif
{
return;
}
@@ -2443,29 +2394,8 @@ PCODE COMDelegate::GetInvokeMethodStub(EEImplMethodDesc* pMD)
ret = COMDelegate::TheDelegateInvokeStub();
}
-#ifdef FEATURE_REMOTING
- else if (pMD == pClass->m_pBeginInvokeMethod)
- {
- CRemotingServices::EnsureRemotingStarted();
-
- if (!ValidateBeginInvoke(pClass))
- COMPlusThrow(kInvalidProgramException);
-
- ret = CTPMethodTable::GetDelegateStubEntryPoint();
- }
- else if (pMD == pClass->m_pEndInvokeMethod)
- {
- CRemotingServices::EnsureRemotingStarted();
-
- if (!ValidateEndInvoke(pClass))
- COMPlusThrow(kInvalidProgramException);
-
- ret = CTPMethodTable::GetDelegateStubEntryPoint();
- }
-#endif // FEATURE_REMOTING
else
{
-#ifndef FEATURE_REMOTING
// Since we do not support asynchronous delegates in CoreCLR, we much ensure that it was indeed a async delegate call
// and not an invalid-delegate-layout condition.
@@ -2476,7 +2406,6 @@ PCODE COMDelegate::GetInvokeMethodStub(EEImplMethodDesc* pMD)
COMPlusThrow(kPlatformNotSupportedException);
}
-#endif //FEATURE_REMOTING
_ASSERTE(!"Bad Delegate layout");
COMPlusThrow(kInvalidProgramException);
@@ -2555,38 +2484,7 @@ BOOL COMDelegate::NeedsSecureDelegate(MethodDesc* pCreatorMethod, AppDomain *pCr
}
CONTRACTL_END;
-#ifndef FEATURE_CAS_POLICY
return FALSE;
-#else
- if (pCreatorMethod)
- {
- Assembly* pTargetAssembly = pTargetMD->GetAssembly();
- Assembly* pCreatorAssembly = pCreatorMethod->GetAssembly();
- if (pCreatorAssembly != pTargetAssembly)
- {
- // We don't need secure delegate is everything in the AppDomain is full trust.
- if (!pCreatorDomain->GetSecurityDescriptor()->DomainMayContainPartialTrustCode())
- return FALSE;
-
- IAssemblySecurityDescriptor *pCreatorAsd = pCreatorAssembly->GetSecurityDescriptor(pCreatorDomain);
-
- // We should also create secure delegates for anonymously hosted dynamic methods which
- // are themselves full trust (although transparent) yet can be created from partial trust.
- if (!pCreatorAsd->IsFullyTrusted() ||
- pCreatorAssembly->GetDomainAssembly(pCreatorDomain) == pCreatorDomain->GetAnonymouslyHostedDynamicMethodsAssembly())
- {
- return TRUE;
- }
-
- // Note that if we begin to support using an NGEN image which is not fully trusted, we may need
- // to force on secure delegates as the grant set of the image may not match between NGEN time
- // and runtime.
- }
- }
-
- return FALSE;
-
-#endif // FEATURE_CAS_POLICY
}
BOOL COMDelegate::NeedsWrapperDelegate(MethodDesc* pTargetMD)
@@ -2928,9 +2826,6 @@ PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD)
}
CONTRACTL_END;
-#ifdef FEATURE_CAS_POLICY
-#error GetSecureInvoke not implemented
-#else
MethodTable * pDelegateMT = pMD->GetMethodTable();
DelegateEEClass* delegateEEClass = (DelegateEEClass*) pDelegateMT->GetClass();
Stub *pStub = delegateEEClass->m_pSecureDelegateInvokeStub;
@@ -2986,7 +2881,6 @@ PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD)
}
return pStub->GetEntryPoint();
-#endif
}
#else // FEATURE_STUBS_AS_IL
PCODE COMDelegate::GetSecureInvoke(MethodDesc* pMD)
@@ -3800,7 +3694,6 @@ BOOL COMDelegate::ValidateSecurityTransparency(MethodDesc *pFtn, MethodTable *pd
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CORECLR
if (GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted())
return TRUE;
@@ -3811,9 +3704,6 @@ BOOL COMDelegate::ValidateSecurityTransparency(MethodDesc *pFtn, MethodTable *pd
// 1. the delegate is critical and the target method is critical, or
// 2. the delegate is transparent/safecritical and the target method is transparent/safecritical
return (fCriticalDelegate == fCriticalTarget);
-#else
- return TRUE;
-#endif // !FEATURE_CORECLR
}
@@ -4029,13 +3919,7 @@ static void InvokeUnhandledSwallowing(OBJECTREF *pDelegate,
EX_TRY
{
- // We have used both the FEATURE_ defines here since without CSE feature,
- // this aspect of notification feature is pointless. And skipping
- // FEATURE_EXCEPTION_NOTIFICATIONS with only FEATURE_CORRUPTING_EXCEPTIONS
- // specified would enable this change for builds that dont support
- // FEATURE_EXCEPTION_NOTIFICATIONS, like CoreCLR. We dont want that to happen
- // as well.
-#if defined(FEATURE_CORRUPTING_EXCEPTIONS) && defined(FEATURE_EXCEPTION_NOTIFICATIONS)
+#if defined(FEATURE_CORRUPTING_EXCEPTIONS)
BOOL fCanMethodHandleException = g_pConfig->LegacyCorruptedStateExceptionsPolicy();
if (!fCanMethodHandleException)
{
@@ -4067,7 +3951,7 @@ static void InvokeUnhandledSwallowing(OBJECTREF *pDelegate,
}
if (fCanMethodHandleException)
-#endif // defined(FEATURE_CORRUPTING_EXCEPTIONS) && defined(FEATURE_EXCEPTION_NOTIFICATIONS)
+#endif // defined(FEATURE_CORRUPTING_EXCEPTIONS)
{
// We've already exercised the prestub on this delegate's COMDelegate::GetMethodDesc,
// as part of wiring up a reliable event sink. Deliver the notification.
@@ -4083,55 +3967,12 @@ static void InvokeUnhandledSwallowing(OBJECTREF *pDelegate,
}
-// cannot combine SEH & C++ exceptions in one method. Split out from InvokeNotify.
-static void InvokeNotifyInner(OBJECTREF *pDelegate, OBJECTREF *pDomain)
-{
- // static contract, since we use SEH.
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_MODE_COOPERATIVE;
-
- _ASSERTE(pDelegate != NULL && IsProtectedByGCFrame(pDelegate));
- _ASSERTE(pDomain != NULL && IsProtectedByGCFrame(pDomain));
-
- struct Param : ThreadBaseExceptionFilterParam
- {
- OBJECTREF *pDelegate;
- OBJECTREF *pDomain;
- } param;
- param.location = SystemNotification;
- param.pDelegate = pDelegate;
- param.pDomain = pDomain;
-
- PAL_TRY(Param *, pParam, &param)
- {
- PREPARE_NONVIRTUAL_CALLSITE_USING_CODE(DELEGATEREF(*pParam->pDelegate)->GetMethodPtr());
-
- DECLARE_ARGHOLDER_ARRAY(args, 3);
-
- args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(DELEGATEREF(*pParam->pDelegate)->GetTarget());
- args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(*pParam->pDomain);
- args[ARGNUM_2] = NULL;
-
- CALL_MANAGED_METHOD_NORET(args);
- }
- PAL_EXCEPT_FILTER(ThreadBaseExceptionFilter)
- {
- _ASSERTE(!"ThreadBaseExceptionFilter returned EXECUTE_HANDLER.");
- }
- PAL_ENDTRY;
-}
-
-
-
-// Helper to dispatch a single event notification. If anything goes wrong, we cause
-// an unhandled exception notification to occur out of our first pass, and then we
-// swallow and continue.
+// Helper to dispatch a single event notification.
static void InvokeNotify(OBJECTREF *pDelegate, OBJECTREF *pDomain)
{
CONTRACTL
{
- NOTHROW;
+ THROWS;
GC_TRIGGERS;
MODE_COOPERATIVE;
}
@@ -4153,19 +3994,15 @@ static void InvokeNotify(OBJECTREF *pDelegate, OBJECTREF *pDomain)
_ASSERTE(!pThread->HasCriticalRegion());
_ASSERTE(!pThread->HasThreadAffinity());
- EX_TRY
- {
- InvokeNotifyInner(pDelegate, pDomain);
- }
- EX_CATCH
- {
- // It's not even worth asserting, because these aren't our bugs. At
- // some point, a MDA may be warranted.
- // This is an early check for condition that we assert in Thread::InternalReset called from DoOneFinalization later.
- _ASSERTE(!pThread->HasCriticalRegion());
- _ASSERTE(!pThread->HasThreadAffinity());
- }
- EX_END_CATCH(SwallowAllExceptions)
+ PREPARE_NONVIRTUAL_CALLSITE_USING_CODE(DELEGATEREF(*pDelegate)->GetMethodPtr());
+
+ DECLARE_ARGHOLDER_ARRAY(args, 3);
+
+ args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(DELEGATEREF(*pDelegate)->GetTarget());
+ args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(*pDomain);
+ args[ARGNUM_2] = NULL;
+
+ CALL_MANAGED_METHOD_NORET(args);
// This is an early check for condition that we assert in Thread::InternalReset called from DoOneFinalization later.
_ASSERTE(!pThread->HasCriticalRegion());
@@ -4173,16 +4010,11 @@ static void InvokeNotify(OBJECTREF *pDelegate, OBJECTREF *pDomain)
}
-// For critical system events, ensure that each handler gets a notification --
-// even if prior handlers in the chain have thrown an exception. Also, try
-// to deliver an unhandled exception event if we ever swallow an exception
-// out of a reliable notification. Note that the add_ event handers are
-// responsible for any reliable preparation of the target, like eager JITting.
-void DistributeEventReliably(OBJECTREF *pDelegate, OBJECTREF *pDomain)
+void DistributeEvent(OBJECTREF *pDelegate, OBJECTREF *pDomain)
{
CONTRACTL
{
- NOTHROW;
+ THROWS;
GC_TRIGGERS;
MODE_COOPERATIVE;
}
@@ -4193,51 +4025,42 @@ void DistributeEventReliably(OBJECTREF *pDelegate, OBJECTREF *pDomain)
Thread *pThread = GetThread();
- EX_TRY
+ struct _gc
{
- struct _gc
- {
- PTRARRAYREF Array;
- OBJECTREF InnerDelegate;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
+ PTRARRAYREF Array;
+ OBJECTREF InnerDelegate;
+ } gc;
+ ZeroMemory(&gc, sizeof(gc));
- GCPROTECT_BEGIN(gc);
+ GCPROTECT_BEGIN(gc);
- gc.Array = (PTRARRAYREF) ((DELEGATEREF)(*pDelegate))->GetInvocationList();
- if (gc.Array == NULL || !gc.Array->GetMethodTable()->IsArray())
- {
- InvokeNotify(pDelegate, pDomain);
- }
- else
- {
- // The _invocationCount could be less than the array size, if we are sharing
- // immutable arrays cleverly.
- INT_PTR invocationCount = ((DELEGATEREF)(*pDelegate))->GetInvocationCount();
+ gc.Array = (PTRARRAYREF) ((DELEGATEREF)(*pDelegate))->GetInvocationList();
+ if (gc.Array == NULL || !gc.Array->GetMethodTable()->IsArray())
+ {
+ InvokeNotify(pDelegate, pDomain);
+ }
+ else
+ {
+ // The _invocationCount could be less than the array size, if we are sharing
+ // immutable arrays cleverly.
+ INT_PTR invocationCount = ((DELEGATEREF)(*pDelegate))->GetInvocationCount();
- _ASSERTE(FitsInU4(invocationCount));
- DWORD cnt = static_cast<DWORD>(invocationCount);
+ _ASSERTE(FitsInU4(invocationCount));
+ DWORD cnt = static_cast<DWORD>(invocationCount);
- _ASSERTE(cnt <= gc.Array->GetNumComponents());
+ _ASSERTE(cnt <= gc.Array->GetNumComponents());
- for (DWORD i=0; i<cnt; i++)
+ for (DWORD i=0; i<cnt; i++)
+ {
+ gc.InnerDelegate = gc.Array->m_Array[i];
+ InvokeNotify(&gc.InnerDelegate, pDomain);
+ if (pThread->IsAbortRequested())
{
- gc.InnerDelegate = gc.Array->m_Array[i];
- InvokeNotify(&gc.InnerDelegate, pDomain);
- if (pThread->IsAbortRequested())
- {
- pThread->UnmarkThreadForAbort(Thread::TAR_Thread);
- }
+ pThread->UnmarkThreadForAbort(Thread::TAR_Thread);
}
}
- GCPROTECT_END();
}
- EX_CATCH
- {
- // It's not even worth asserting, because these aren't our bugs. At
- // some point, a MDA may be warranted.
- }
- EX_END_CATCH(SwallowAllExceptions)
+ GCPROTECT_END();
}
// The unhandled exception event is a little easier to distribute, because
diff --git a/src/vm/comdelegate.h b/src/vm/comdelegate.h
index a562f88392..f1bed43db6 100644
--- a/src/vm/comdelegate.h
+++ b/src/vm/comdelegate.h
@@ -131,14 +131,10 @@ public:
static BOOL IsTrueMulticastDelegate(OBJECTREF delegate);
-#ifdef FEATURE_CORECLR
static BOOL IsMethodAllowedToSinkReversePInvoke(MethodDesc *pMD);
-#endif
private:
-#ifdef FEATURE_CORECLR
static BOOL IsFullTrustDelegate(DELEGATEREF pDelegate);
-#endif
static Stub* SetupShuffleThunk(MethodTable * pDelMT, MethodDesc *pTargetMeth);
public:
@@ -184,8 +180,8 @@ enum DelegateBindingFlags
DBF_RelaxedSignature = 0x00000080, // Allow relaxed signature matching (co/contra variance)
};
-void DistributeEventReliably(OBJECTREF *pDelegate,
- OBJECTREF *pDomain);
+void DistributeEvent(OBJECTREF *pDelegate,
+ OBJECTREF *pDomain);
void DistributeUnhandledExceptionReliably(OBJECTREF *pDelegate,
OBJECTREF *pDomain,
diff --git a/src/vm/comdynamic.cpp b/src/vm/comdynamic.cpp
index 835b5cab3b..97e408ac32 100644
--- a/src/vm/comdynamic.cpp
+++ b/src/vm/comdynamic.cpp
@@ -714,33 +714,6 @@ INT32 QCALLTYPE COMDynamicWrite::SetParamInfo(QCall::ModuleHandle pModule, UINT3
return (INT32)retVal;
}
-#ifndef FEATURE_CORECLR
-/*============================CWSetMarshal============================
-**Action: Helper to set marshal information
-**Returns:
-**Arguments:
-**Exceptions:
-==============================================================================*/
-void QCALLTYPE COMDynamicWrite::SetFieldMarshal(QCall::ModuleHandle pModule, UINT32 tk, LPCBYTE pMarshal, INT32 cbMarshal)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter();
- _ASSERTE(pRCW);
-
- _ASSERTE(pMarshal);
-
- // Define the signature
- IfFailThrow(pRCW->GetEmitter()->SetFieldMarshal(
- tk,
- (PCCOR_SIGNATURE)pMarshal, // marshal blob
- cbMarshal)); // blob length
-
- END_QCALL;
-}
-#endif
/*============================SetConstantValue============================
**Action: Helper to set constant value to field or parameter
@@ -1103,275 +1076,6 @@ void ManagedBitnessFlagsToUnmanagedBitnessFlags(
*pPeFlags |= ICEE_CREATE_MACHINE_ARM|ICEE_CREATE_FILE_PE32;
}
-#ifndef FEATURE_CORECLR
-//=============================PreSavePEFile=====================================*/
-// PreSave the PEFile
-//==============================================================================*/
-void QCALLTYPE COMDynamicWrite::PreSavePEFile(QCall::ModuleHandle pModule, INT32 portableExecutableKind, INT32 imageFileMachine)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- RefClassWriter *pRCW = pModule->GetReflectionModule()->GetClassWriter();
- _ASSERTE(pRCW);
-
- DWORD peFlags = 0, corhFlags = 0;
- ManagedBitnessFlagsToUnmanagedBitnessFlags(portableExecutableKind, imageFileMachine, &peFlags, &corhFlags);
- IfFailThrow(pRCW->EnsureCeeFileGenCreated(corhFlags, peFlags));
-
- ICeeFileGen *pCeeFileGen = pRCW->GetCeeFileGen();
- HCEEFILE ceeFile = pRCW->GetHCEEFILE();
- _ASSERTE(ceeFile && pCeeFileGen);
-
- // We should not have the on disk emitter yet
- if (pRCW->GetOnDiskEmitter() != NULL)
- pRCW->SetOnDiskEmitter(NULL);
-
- // Get the dispenser.
- SafeComHolderPreemp<IMetaDataDispenserEx> pDisp;
- IfFailThrow(MetaDataGetDispenser(CLSID_CorMetaDataDispenser, IID_IMetaDataDispenserEx, (void**)&pDisp));
-
- //Get the emitter and the importer
- IMetaDataImport *pImport = pRCW->GetRWImporter();
- IMetaDataEmit *pEmit = pRCW->GetEmitter();
- _ASSERTE((pEmit != NULL ) && (pImport != NULL));
-
- // Set the option on the dispenser turn on duplicate check for TypeDef and moduleRef
- VARIANT varOption;
- V_VT(&varOption) = VT_UI4;
- V_I4(&varOption) = MDDupDefault | MDDupTypeDef | MDDupModuleRef | MDDupExportedType | MDDupAssemblyRef | MDDupFile | MDDupAssembly;
- IfFailThrow(pDisp->SetOption(MetaDataCheckDuplicatesFor, &varOption));
-
- V_VT(&varOption) = VT_UI4;
- V_I4(&varOption) = MDRefToDefNone;
- IfFailThrow(pDisp->SetOption(MetaDataRefToDefCheck, &varOption));
-
- V_VT(&varOption) = VT_UI4;
- V_I4(&varOption) = MergeManifest;
- IfFailThrow(pDisp->SetOption(MetaDataMergerOptions, &varOption));
-
- //Define an empty scope
- SafeComHolderPreemp<IMetaDataEmit> pEmitNew;
- IfFailThrow(pDisp->DefineScope(CLSID_CorMetaDataRuntime, 0, IID_IMetaDataEmit, (IUnknown**)&pEmitNew));
-
- // Token can move upon merge. Get the IMapToken from the CeeFileGen that is created for save
- // and pass it to merge to receive token movement notification.
- // Note that this is not a long term fix. We are relying on the fact that those tokens embedded
- // in PE cannot move after the merge. These tokens are TypeDef, TypeRef, MethodDef, FieldDef, MemberRef,
- // TypeSpec, UserString. If this is no longer true, we can break!
- //
- // Note that we don't need to release pIMapToken because it is not AddRef'ed in the GetIMapTokenIfaceEx.
- //
- IUnknown *pUnknown = NULL;
- IfFailThrow(pCeeFileGen->GetIMapTokenIfaceEx(ceeFile, pEmit, &pUnknown));
-
- SafeComHolderPreemp<IMapToken> pIMapToken;
- IfFailThrow(SafeQueryInterfacePreemp(pUnknown, IID_IMapToken, (IUnknown**) &pIMapToken));
-
- // get the unmanaged writer.
- ISymUnmanagedWriter *pWriter = pModule->GetReflectionModule()->GetISymUnmanagedWriter();
- SafeComHolderPreemp<CSymMapToken> pSymMapToken(new CSymMapToken(pWriter, pIMapToken));
-
- //Merge the old tokens into the new (empty) scope
- //This is a copy.
- IfFailThrow(pEmitNew->Merge(pImport, pSymMapToken, NULL));
- IfFailThrow(pEmitNew->MergeEnd());
-
- // Update the Module name in the new scope.
- CQuickArray<WCHAR> cqModuleName;
- ULONG cchName;
-
- IfFailThrow(pImport->GetScopeProps(0, 0, &cchName, 0));
-
- cqModuleName.ReSizeThrows(cchName);
-
- IfFailThrow(pImport->GetScopeProps(cqModuleName.Ptr(), cchName, &cchName, 0));
- IfFailThrow(pEmitNew->SetModuleProps(cqModuleName.Ptr()));
-
- // cache the pEmitNew to RCW!!
- pRCW->SetOnDiskEmitter(pEmitNew);
-
- END_QCALL;
-} // COMDynamicWrite::PreSavePEFile
-
-//=============================SavePEFile=====================================*/
-// Save the PEFile to disk
-//==============================================================================*/
-void QCALLTYPE COMDynamicWrite::SavePEFile(QCall::ModuleHandle pModule, LPCWSTR wszPeName, UINT32 entryPoint, UINT32 fileKind, BOOL isManifestFile)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- HRESULT hr=S_OK;
- HCORENUM hTypeDefs=0;
- mdTypeDef td;
- ULONG count;
- IMetaDataImport *pImportNew = 0;
- ULONG newMethRVA;
- DWORD metaDataSize;
- BYTE *metaData;
- ULONG metaDataOffset;
- HCEESECTION pILSection;
- ISymUnmanagedWriter *pWriter = NULL;
-
- if (wszPeName==NULL)
- COMPlusThrow(kArgumentNullException, W("ArgumentNull_String"));
- if (wszPeName[0] == '\0')
- COMPlusThrow(kFormatException, W("Format_StringZeroLength"));
-
- Assembly * pAssembly = pModule->GetAssembly();
- _ASSERTE( pAssembly );
-
- RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter();
- _ASSERTE(pRCW);
-
- ICeeFileGen * pCeeFileGen = pRCW->GetCeeFileGen();
- HCEEFILE ceeFile = pRCW->GetHCEEFILE();
- _ASSERTE(ceeFile && pCeeFileGen);
-
- IMetaDataEmit * pEmitNew = pRCW->GetOnDiskEmitter();
- _ASSERTE(pEmitNew);
-
- //Get the emitter and the importer
-
- if (pAssembly->IsDynamic() && isManifestFile)
- {
- // manifest is stored in this file
-
- // Allocate space for a strong name signature if an originator was supplied
- // (this doesn't strong name the assembly, but it makes it possible to do so
- // as a post processing step).
- if (pAssembly->IsStrongNamed())
- IfFailGo(pAssembly->AllocateStrongNameSignature(pCeeFileGen, ceeFile));
- }
-
- //Set the Output FileName
- IfFailGo( pCeeFileGen->SetOutputFileName(ceeFile, (LPWSTR)wszPeName) );
-
- //Set the Entry Point or throw the dll switch if we're creating a dll.
- if (entryPoint!=0)
- {
- IfFailGo( pCeeFileGen->SetEntryPoint(ceeFile, entryPoint) );
- }
-
- switch (fileKind)
- {
- case Dll:
- {
- IfFailGo( pCeeFileGen->SetDllSwitch(ceeFile, true) );
- break;
- }
- case WindowApplication:
- {
- // window application. Set the SubSystem
- IfFailGo( pCeeFileGen->SetSubsystem(ceeFile, IMAGE_SUBSYSTEM_WINDOWS_GUI, CEE_IMAGE_SUBSYSTEM_MAJOR_VERSION, CEE_IMAGE_SUBSYSTEM_MINOR_VERSION) );
- break;
- }
- case ConsoleApplication:
- {
- // Console application. Set the SubSystem
- IfFailGo( pCeeFileGen->SetSubsystem(ceeFile, IMAGE_SUBSYSTEM_WINDOWS_CUI, CEE_IMAGE_SUBSYSTEM_MAJOR_VERSION, CEE_IMAGE_SUBSYSTEM_MINOR_VERSION) );
- break;
- }
- default:
- {
- _ASSERTE(!"Unknown file kind!");
- break;
- }
- }
-
- IfFailGo( pCeeFileGen->GetIlSection(ceeFile, &pILSection) );
- IfFailGo( pEmitNew->GetSaveSize(cssAccurate, &metaDataSize) );
- IfFailGo( pCeeFileGen->GetSectionBlock(pILSection, metaDataSize, sizeof(DWORD), (void**) &metaData) );
- IfFailGo( pCeeFileGen->GetSectionDataLen(pILSection, &metaDataOffset) );
- metaDataOffset -= metaDataSize;
-
- // get the unmanaged writer.
- pWriter = pModule->GetReflectionModule()->GetISymUnmanagedWriter();
- IfFailGo( EmitDebugInfoBegin(pModule, pCeeFileGen, ceeFile, pILSection, wszPeName, pWriter) );
-
- if (pAssembly->IsDynamic() && pRCW->m_ulResourceSize)
- {
- // There are manifest in this file
-
- IfFailGo( pCeeFileGen->GetMethodRVA(ceeFile, 0, &newMethRVA) );
-
- // Point to manifest resource
- IfFailGo( pCeeFileGen->SetManifestEntry( ceeFile, pRCW->m_ulResourceSize, newMethRVA ) );
- }
-
- IfFailGo( pCeeFileGen->LinkCeeFile(ceeFile) );
-
- // Get the import interface from the new Emit interface.
- IfFailGo( pEmitNew->QueryInterface(IID_IMetaDataImport, (void **)&pImportNew));
-
-
- //Enumerate the TypeDefs and update method RVAs.
- while ((hr = pImportNew->EnumTypeDefs( &hTypeDefs, &td, 1, &count)) == S_OK)
- {
- UpdateMethodRVAs(pEmitNew, pImportNew, pCeeFileGen, ceeFile, td, pModule->GetReflectionModule()->m_sdataSection);
- }
-
- if (hTypeDefs)
- {
- pImportNew->CloseEnum(hTypeDefs);
- }
- hTypeDefs=0;
-
- //Update Global Methods.
- UpdateMethodRVAs(pEmitNew, pImportNew, pCeeFileGen, ceeFile, 0, pModule->GetReflectionModule()->m_sdataSection);
-
-
- //Emit the MetaData
- // IfFailGo( pCeeFileGen->EmitMetaDataEx(ceeFile, pEmitNew));
- IfFailGo( pCeeFileGen->EmitMetaDataAt(ceeFile, pEmitNew, pILSection, metaDataOffset, metaData, metaDataSize) );
-
- // finish the debugging info emitting after the metadata save so that token remap will be caught correctly
- IfFailGo( EmitDebugInfoEnd(pModule, pCeeFileGen, ceeFile, pILSection, wszPeName, pWriter) );
-
- //Generate the CeeFile
- IfFailGo(pCeeFileGen->GenerateCeeFile(ceeFile) );
-
- // Strong name sign the resulting assembly if required.
- if (pAssembly->IsDynamic() && isManifestFile && pAssembly->IsStrongNamed())
- IfFailGo(pAssembly->SignWithStrongName((LPWSTR)wszPeName));
-
-ErrExit:
-
- pRCW->SetOnDiskEmitter(NULL);
-
- //Release the interfaces. This should free some of the associated resources.
- if (pImportNew)
- pImportNew->Release();
-
- //Release our interfaces if we allocated them to begin with
- pRCW->DestroyCeeFileGen();
-
- //Check all file IO errors. If so, throw IOException. Otherwise, just throw the hr.
- if (FAILED(hr))
- {
- if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
- {
- if (IsWin32IOError(HRESULT_CODE(hr)))
- {
- SString hrMessage;
- GenerateTopLevelHRExceptionMessage(hr, hrMessage);
- COMPlusThrowHR(COR_E_IO, IDS_EE_GENERIC, hrMessage.GetUnicode());
- }
- else
- {
- COMPlusThrowHR(hr);
- }
- }
- COMPlusThrowHR(hr);
- }
-
- END_QCALL;
-}
-
-#endif // FEATURE_CORECLR
//=============================EmitDebugInfoBegin============================*/
// Phase 1 of emit debugging directory and symbol file.
@@ -1592,152 +1296,6 @@ ErrExit:
}
-#ifndef FEATURE_CORECLR
-//==============================================================================
-// Define external file for native resource.
-//==============================================================================
-void QCALLTYPE COMDynamicWrite::DefineNativeResourceFile(QCall::ModuleHandle pModule, LPCWSTR pwzFileName, INT32 portableExecutableKind, INT32 imageFileMachine)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter();
- _ASSERTE(pRCW);
-
- DWORD peFlags = 0, corhFlags = 0;
- ManagedBitnessFlagsToUnmanagedBitnessFlags(portableExecutableKind, imageFileMachine, &peFlags, &corhFlags);
- IfFailThrow( pRCW->EnsureCeeFileGenCreated(corhFlags, peFlags) );
-
- ICeeFileGen * pCeeFileGen = pRCW->GetCeeFileGen();
- HCEEFILE ceeFile = pRCW->GetHCEEFILE();
- _ASSERTE(ceeFile && pCeeFileGen);
-
- // Set the resource file name.
- IfFailThrow( pCeeFileGen->SetResourceFileName(ceeFile, (LPWSTR)pwzFileName) );
-
- END_QCALL;
-} // void __stdcall COMDynamicWrite::DefineNativeResourceFile()
-
-//==============================================================================
-// Define array of bytes for native resource.
-//==============================================================================
-void QCALLTYPE COMDynamicWrite::DefineNativeResourceBytes(QCall::ModuleHandle pModule, LPCBYTE pbResource, INT32 cbResource, INT32 portableExecutableKind, INT32 imageFileMachine)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter();
- _ASSERTE(pRCW);
-
- DWORD peFlags = 0, corhFlags = 0;
- ManagedBitnessFlagsToUnmanagedBitnessFlags(portableExecutableKind, imageFileMachine, &peFlags, &corhFlags);
- IfFailThrow( pRCW->EnsureCeeFileGenCreated(corhFlags, peFlags) );
-
- ICeeFileGen * pCeeFileGen = pRCW->GetCeeFileGen();
- HCEEFILE ceeFile = pRCW->GetHCEEFILE();
- _ASSERTE(ceeFile && pCeeFileGen);
-
- // Set the resource stream.
- HCEESECTION ceeSection = NULL;
- IfFailThrow( pCeeFileGen->GetSectionCreate(ceeFile, ".rsrc", sdReadOnly, &ceeSection) );
-
- void * pvResource;
- IfFailThrow( pCeeFileGen->GetSectionBlock(ceeSection, cbResource, 1, &pvResource) );
- memcpy(pvResource, pbResource, cbResource);
-
- END_QCALL;
-} // void __stdcall COMDynamicWrite::DefineNativeResourceBytes()
-
-//=============================AddResource=====================================*/
-// ecall for adding embedded resource to this module
-//==============================================================================*/
-void QCALLTYPE COMDynamicWrite::AddResource(QCall::ModuleHandle pModule, LPCWSTR pName, LPCBYTE pResBytes, INT32 resByteCount, UINT32 uFileTk, UINT32 iAttribute, INT32 portableExecutableKind, INT32 imageFileMachine)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter();
- _ASSERTE(pRCW);
-
- DWORD peFlags = 0, corhFlags = 0;
- ManagedBitnessFlagsToUnmanagedBitnessFlags(portableExecutableKind, imageFileMachine, &peFlags, &corhFlags);
- IfFailThrow( pRCW->EnsureCeeFileGenCreated(corhFlags, peFlags) );
-
- Assembly * pAssembly = pModule->GetAssembly();
- _ASSERTE( pAssembly && pAssembly->IsDynamic() );
-
- ICeeFileGen * pCeeFileGen = pRCW->GetCeeFileGen();
- HCEEFILE ceeFile = pRCW->GetHCEEFILE();
- _ASSERTE(ceeFile && pCeeFileGen);
-
- IMetaDataEmit * pOnDiskEmit = pRCW->GetOnDiskEmitter();
-
- // First, put it into .rdata section. The only reason that we choose .rdata section at
- // this moment is because this is the first section on the PE file. We don't need to deal with
- // reloc. Actually, I don't know how to deal with the reloc with CeeFileGen given that the reloc
- // position is not in the same file!
-
- // Get the .rdata section
- HCEESECTION hSection;
- IfFailThrow( pCeeFileGen->GetRdataSection(ceeFile, &hSection) );
-
- // the current section data length is the RVA
- ULONG ulOffset;
- IfFailThrow( pCeeFileGen->GetSectionDataLen(hSection, &ulOffset) );
-
- // Allocate a block of space fromt he .rdata section
- BYTE * pbBuffer;
- IfFailThrow( pCeeFileGen->GetSectionBlock(
- hSection, // from .rdata section
- resByteCount + sizeof(DWORD), // number of bytes that we need
- 1, // alignment
- (void**) &pbBuffer) );
-
- // now copy over the resource
- memcpy( pbBuffer, &resByteCount, sizeof(DWORD) );
- memcpy( pbBuffer + sizeof(DWORD), pResBytes, resByteCount );
-
- // track the total resource size so far. The size is actually the offset into the section
- // after writing the resource out
- IfFailThrow( pCeeFileGen->GetSectionDataLen(hSection, &pRCW->m_ulResourceSize) );
-
- mdFile tkFile = RidFromToken(uFileTk) ? uFileTk : mdFileNil;
- mdManifestResource mr;
-
- if (tkFile != mdFileNil)
- {
- SafeComHolderPreemp<IMetaDataAssemblyEmit> pOnDiskAssemblyEmit;
-
- IfFailThrow( pOnDiskEmit->QueryInterface(IID_IMetaDataAssemblyEmit, (void **) &pOnDiskAssemblyEmit) );
-
- // The resource is stored in a file other than the manifest file
- IfFailThrow(pOnDiskAssemblyEmit->DefineManifestResource(
- pName,
- mdFileNil, // implementation -- should be file token of this module in the manifest
- ulOffset, // offset to this file -- need to be adjusted upon save
- iAttribute, // resource flag
- &mr)); // manifest resource token
- }
-
- // Add an entry into the ManifestResource table for this resource
- // The RVA is ulOffset
- SafeComHolderPreemp<IMetaDataAssemblyEmit> pAssemEmitter(pAssembly->GetOnDiskMDAssemblyEmitter());
- IfFailThrow(pAssemEmitter->DefineManifestResource(
- pName,
- tkFile, // implementation -- should be file token of this module in the manifest
- ulOffset, // offset to this file -- need to be adjusted upon save
- iAttribute, // resource flag
- &mr)); // manifest resource token
-
- pRCW->m_tkFile = tkFile;
-
- END_QCALL;
-}
-
-#endif // FEATURE_CORECLR
//============================AddDeclarativeSecurity============================*/
// Add a declarative security serialized blob and a security action code to a
diff --git a/src/vm/comdynamic.h b/src/vm/comdynamic.h
index 224e017330..a605fa19ba 100644
--- a/src/vm/comdynamic.h
+++ b/src/vm/comdynamic.h
@@ -90,16 +90,6 @@ public:
static
void QCALLTYPE SavePEFile(QCall::ModuleHandle pModule, LPCWSTR wszPeName, UINT32 entryPoint, UINT32 fileKind, BOOL isManifestFile);
-#ifndef FEATURE_CORECLR
- static
- void QCALLTYPE DefineNativeResourceFile(QCall::ModuleHandle pModule, LPCWSTR pwzFileName, INT32 portableExecutableKind, INT32 imageFileMachine);
-
- static
- void QCALLTYPE DefineNativeResourceBytes(QCall::ModuleHandle pModule, LPCBYTE pbResource, INT32 cbResource, INT32 portableExecutableKind, INT32 imageFileMachine);
-
- static
- void QCALLTYPE AddResource(QCall::ModuleHandle pModule, LPCWSTR pName, LPCBYTE pResBytes, INT32 resByteCount, UINT32 uFileTk, UINT32 iAttribute, INT32 portableExecutableKind, INT32 imageFileMachine);
-#endif // !FEATURE_CORECLR
// not an ecall!
static HRESULT EmitDebugInfoBegin(
@@ -160,11 +150,6 @@ public:
static
INT32 QCALLTYPE SetParamInfo(QCall::ModuleHandle pModule, UINT32 tkMethod, UINT32 iSequence, UINT32 iAttributes, LPCWSTR wszParamName);
-#ifndef FEATURE_CORECLR
- // functions to set FieldMarshal
- static
- void QCALLTYPE SetFieldMarshal(QCall::ModuleHandle pModule, UINT32 tk, LPCBYTE pMarshal, INT32 cbMarshal);
-#endif
// functions to set default value
static
void QCALLTYPE SetConstantValue(QCall::ModuleHandle pModule, UINT32 tk, DWORD valueType, LPVOID pValue);
diff --git a/src/vm/cominterfacemarshaler.cpp b/src/vm/cominterfacemarshaler.cpp
index 251beff352..2eb06b3734 100644
--- a/src/vm/cominterfacemarshaler.cpp
+++ b/src/vm/cominterfacemarshaler.cpp
@@ -18,11 +18,6 @@
#include "runtimecallablewrapper.h"
#include "cominterfacemarshaler.h"
#include "interopconverter.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#include "appdomainhelper.h"
-#include "crossdomaincalls.h"
-#endif
#include "notifyexternals.h"
#include "comdelegate.h"
#include "winrttypenameconverter.h"
@@ -389,111 +384,13 @@ OBJECTREF COMInterfaceMarshaler::HandleInProcManagedComponent()
}
else
{
-#ifdef FEATURE_CORECLR
_ASSERTE(!"NYI");
COMPlusThrowHR(COR_E_NOTSUPPORTED);
-#else // FEATURE_CORECLR
- // TODO: probably we can cache the object on a per App domain bases
- // using CCW as the key
- OBJECTREF pwrap = NULL;
- GCPROTECT_BEGIN(pwrap);
- {
- pwrap = GetCCWObject();
- oref = AppDomainHelper::CrossContextCopyFrom(m_dwServerDomainId, &pwrap);
- }
- GCPROTECT_END();
-#endif // FEATURE_CORECLR
}
return oref;
}
-#ifdef FEATURE_REMOTING
-
-OBJECTREF COMInterfaceMarshaler::GetObjectForRemoteManagedComponentNoThrow()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- OBJECTREF oref = NULL;
-
- EX_TRY
- {
- oref = GetObjectForRemoteManagedComponent();
- }
- EX_CATCH
- {
- oref = NULL;
- }
- EX_END_CATCH(RethrowTerminalExceptions);
-
- return oref;
-}
-
-
-//--------------------------------------------------------------------
-// OBJECTREF COMInterfaceMarshaler::GetObjectForRemoteManagedComponent()
-// setup managed proxy to remote object
-//--------------------------------------------------------------------
-OBJECTREF COMInterfaceMarshaler::GetObjectForRemoteManagedComponent()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(m_fIsRemote == true);
- PRECONDITION(CheckPointer(m_pIManaged));
- }
- CONTRACTL_END;
-
- OBJECTREF oref = NULL;
-
- GCPROTECT_BEGIN(oref)
- {
- BSTR bstr;
- HRESULT hr;
-
- {
- GCX_PREEMP();
- hr = m_pIManaged->GetSerializedBuffer(&bstr);
- }
-
- if (hr == S_OK)
- {
- if (bstr != NULL)
- {
- // this could throw an exception
- // also this would free up the BSTR that we pass in
- BOOL fLegacyMode = (GetAppDomain()->GetComOrRemotingFlag() == COMorRemoting_LegacyMode);
- oref = ConvertBSTRToObject(bstr, !fLegacyMode);
-
- if (oref != NULL)
- {
- // setup a COM call wrapper
- ComCallWrapper* pComCallWrap = ComCallWrapper::InlineGetWrapper(&oref);
- _ASSERTE(pComCallWrap != NULL);
-
- // InlineGetWrapper AddRef's the wrapper
- pComCallWrap->Release();
- }
- }
- }
- else
- {
- COMPlusThrowHR(hr);
- }
- }
- GCPROTECT_END();
-
- return oref;
-}
-#endif // FEATURE_REMOTING
//--------------------------------------------------------------------------------
// void COMInterfaceMarshaler::CreateObjectRef(BOOL fDuplicate, OBJECTREF *pComObj)
@@ -1059,49 +956,6 @@ OBJECTREF COMInterfaceMarshaler::HandleTPComponents()
}
CONTRACTL_END;
-#ifdef FEATURE_REMOTING
- OBJECTREF oref = NULL;
-
- if (m_fIsRemote || CRemotingServices::IsTransparentProxy(OBJECTREFToObject(GetCCWObject())))
- {
- if (!m_fIsRemote)
- {
- oref = HandleInProcManagedComponent();
- }
- else
- {
- if (!m_typeHandle.IsNull() && !m_typeHandle.IsComObjectType())
- {
- // if the user wants explicit calls,
- // we better serialize/deserialize
- oref = GetObjectForRemoteManagedComponent();
- }
- else
- {
- oref = GetObjectForRemoteManagedComponentNoThrow();
- }
- }
-
- if (oref != NULL)
- {
- OBJECTREF realProxy = ObjectToOBJECTREF(CRemotingServices::GetRealProxy(OBJECTREFToObject(oref)));
- if(realProxy != NULL)
- {
- // call setIUnknown on real proxy
- GCPROTECT_BEGIN(oref)
- {
- CRemotingServices::CallSetDCOMProxy(realProxy, m_pUnknown);
- }
- GCPROTECT_END();
- return oref;
- }
- else
- {
- return oref;
- }
- }
- }
-#endif // FEATURE_REMOTING
return NULL;
}
diff --git a/src/vm/comisolatedstorage.cpp b/src/vm/comisolatedstorage.cpp
deleted file mode 100644
index 2f4f4f69b3..0000000000
--- a/src/vm/comisolatedstorage.cpp
+++ /dev/null
@@ -1,1073 +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.
-
-//============================================================
-//
-// Class: COMIsolatedStorage
-//
-// Purpose: Native Implementation of IsolatedStorage
-//
-
-//
-
-//============================================================
-
-
-#include "common.h"
-#include "excep.h"
-#include "eeconfig.h"
-#include "qcall.h"
-#include "comisolatedstorage.h"
-
-#ifdef FEATURE_ISOSTORE
-
-#include <shlobj.h>
-
-#ifndef FEATURE_ISOSTORE_LIGHT
-#define IS_ROAMING(x) ((x) & ISS_ROAMING_STORE)
-#endif // !FEATURE_ISOSTORE_LIGHT
-
-void DECLSPEC_NORETURN COMIsolatedStorage::ThrowISS(HRESULT hr)
-{
- STANDARD_VM_CONTRACT;
-
- if ((hr >= ISS_E_ISOSTORE_START) && (hr <= ISS_E_ISOSTORE_END))
- {
- switch (hr)
- {
- case ISS_E_ISOSTORE :
- case ISS_E_OPEN_STORE_FILE :
- case ISS_E_OPEN_FILE_MAPPING :
- case ISS_E_MAP_VIEW_OF_FILE :
- case ISS_E_GET_FILE_SIZE :
- case ISS_E_CREATE_MUTEX :
- case ISS_E_LOCK_FAILED :
- case ISS_E_FILE_WRITE :
- case ISS_E_SET_FILE_POINTER :
- case ISS_E_CREATE_DIR :
- case ISS_E_CORRUPTED_STORE_FILE :
- case ISS_E_STORE_VERSION :
- case ISS_E_FILE_NOT_MAPPED :
- case ISS_E_BLOCK_SIZE_TOO_SMALL :
- case ISS_E_ALLOC_TOO_LARGE :
- case ISS_E_USAGE_WILL_EXCEED_QUOTA :
- case ISS_E_TABLE_ROW_NOT_FOUND :
- case ISS_E_DEPRECATE :
- case ISS_E_CALLER :
- case ISS_E_PATH_LENGTH :
- case ISS_E_MACHINE :
- case ISS_E_STORE_NOT_OPEN :
- case ISS_E_MACHINE_DACL :
- COMPlusThrowHR(hr);
- break;
-
- default :
- _ASSERTE(!"Unknown hr");
- }
- }
-
- COMPlusThrowHR(hr);
-}
-
-#ifndef FEATURE_ISOSTORE_LIGHT
-StackWalkAction COMIsolatedStorage::StackWalkCallBack(
- CrawlFrame* pCf, PVOID ppv)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- } CONTRACTL_END;
-
- // Get the function descriptor for this frame...
- MethodDesc *pMeth = pCf->GetFunction();
- MethodTable *pMT = pMeth->GetMethodTable();
-
- // Skip the Isolated Store and all it's sub classes..
- // <TODO>@Todo : This will work for now, but need to walk up to the base class
- // @Todo : Work out the JIT inlining issiues</TODO>
-
- if ((MscorlibBinder::IsClass(pMT, CLASS__ISS_STORE)) ||
- (MscorlibBinder::IsClass(pMT, CLASS__ISS_STORE_FILE)) ||
- (MscorlibBinder::IsClass(pMT, CLASS__ISS_STORE_FILE_STREAM)))
- {
- LOG((LF_STORE, LL_INFO10000, "StackWalk Continue %s\n",
- pMeth->m_pszDebugMethodName));
- return SWA_CONTINUE;
- }
-
- *(PVOID *)ppv = pMeth->GetModule()->GetAssembly();
-
- return SWA_ABORT;
-}
-
-void QCALLTYPE COMIsolatedStorage::GetCaller(QCall::ObjectHandleOnStack retAssembly)
-{
- QCALL_CONTRACT;
-
- DomainAssembly * pDomainAssembly = NULL;
-
- BEGIN_QCALL;
-
- Assembly * pAssembly = NULL;
- StackWalkAction result;
-
- {
- GCX_COOP();
- result = StackWalkFunctions(GetThread(), StackWalkCallBack, (VOID*)&pAssembly);
- }
-
- if (result == SWA_FAILED)
- ThrowISS(ISS_E_CALLER);
-
- if (pAssembly == NULL)
- ThrowISS(ISS_E_CALLER);
-
-#ifdef _DEBUG
- LOG((LF_STORE, LL_INFO10000, "StackWalk Found %s\n", pAssembly->GetSimpleName()));
-#endif
-
- pDomainAssembly = pAssembly->GetDomainAssembly();
-
- GCX_COOP();
- retAssembly.Set(pDomainAssembly->GetExposedAssemblyObject());
- END_QCALL;
-
- return;
-}
-#endif // !FEATURE_ISOSTORE_LIGHT
-
-// static
-UINT64 QCALLTYPE COMIsolatedStorageFile::GetUsage(__in_opt AccountingInfo * pAI)
-{
- QCALL_CONTRACT;
-
- UINT64 retVal = 0;
- BEGIN_QCALL;
-
- if (pAI == NULL)
- COMIsolatedStorage::ThrowISS(ISS_E_STORE_NOT_OPEN);
-
- PREFIX_ASSUME(pAI != NULL);
-
- HRESULT hr = pAI->GetUsage(&retVal);
-
- if (FAILED(hr))
- COMIsolatedStorage::ThrowISS(hr);
-
- END_QCALL;
- return retVal;
-}
-
-// static
-void QCALLTYPE COMIsolatedStorageFile::Close(__in_opt AccountingInfo * pAI)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- if (pAI != NULL)
- delete pAI;
-
- END_QCALL;
-}
-
-//static
-BOOL QCALLTYPE COMIsolatedStorageFile::Lock(__in AccountingInfo * pAI,
- BOOL fLock)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(pAI != NULL);
- } CONTRACTL_END;
-
- BEGIN_QCALL;
-
- if (fLock)
- AccountingInfo::AcquireLock(pAI);
- else
- AccountingInfo::ReleaseLock(pAI);
-
- END_QCALL;
-
- // AcquireLock will throw if it fails, ReleaseLock will ASSERT
- return TRUE;
-}
-
-// static
-AccountingInfo * QCALLTYPE COMIsolatedStorageFile::Open(LPCWSTR wszFileName,
- LPCWSTR wszSyncName)
-{
- CONTRACT(AccountingInfo *)
- {
- QCALL_CHECK;
- PRECONDITION(wszFileName != NULL);
- PRECONDITION(wszSyncName != NULL);
- POSTCONDITION(RETVAL != NULL);
- } CONTRACT_END;
-
- AccountingInfo * pReturn = NULL;
- BEGIN_QCALL;
-
- AccountingInfo *pAI = new AccountingInfo(wszFileName, wszSyncName);
-
- HRESULT hr = pAI->Init();
-
- if (FAILED(hr))
- COMIsolatedStorage::ThrowISS(hr);
-
- pReturn = pAI;
-
- END_QCALL;
- RETURN(pReturn);
-}
-
-// static
-void QCALLTYPE COMIsolatedStorageFile::Reserve(__in_opt AccountingInfo * pAI,
- UINT64 qwQuota,
- UINT64 qwReserve,
- BOOL fFree)
-{
- QCALL_CONTRACT;
- BEGIN_QCALL;
-
- if (pAI == NULL)
- COMIsolatedStorage::ThrowISS(ISS_E_STORE_NOT_OPEN);
-
- PREFIX_ASSUME(pAI != NULL);
- HRESULT hr = pAI->Reserve(qwQuota, qwReserve, fFree);
-
- if (FAILED(hr))
- {
-#ifdef _DEBUG
- if (fFree) {
- LOG((LF_STORE, LL_INFO10000, "free 0x%x failed\n",
- (int)(qwReserve)));
- }
- else {
- LOG((LF_STORE, LL_INFO10000, "reserve 0x%x failed\n",
- (int)(qwReserve)));
- }
-#endif
- COMIsolatedStorage::ThrowISS(hr);
- }
-
-#ifdef _DEBUG
- if (fFree) {
- LOG((LF_STORE, LL_INFO10000, "free 0x%x\n",
- (int)(qwReserve)));
- } else {
- LOG((LF_STORE, LL_INFO10000, "reserve 0x%x\n",
- (int)(qwReserve)));
- }
-#endif
-
- END_QCALL;
-}
-
-// static
-BOOL QCALLTYPE COMIsolatedStorageFile::GetQuota(__in_opt AccountingInfo * pAI,
- __out INT64 * qwQuota)
-{
- QCALL_CONTRACT;
- BOOL retVal = false;
- BEGIN_QCALL;
-
- if (pAI == NULL)
- COMIsolatedStorage::ThrowISS(ISS_E_STORE_NOT_OPEN);
-
- PREFIX_ASSUME(pAI != NULL);
-
- retVal = pAI->GetQuota(qwQuota);
-
- END_QCALL;
-
- return retVal;
-}
-
-// static
-void QCALLTYPE COMIsolatedStorageFile::SetQuota(__in_opt AccountingInfo * pAI,
- INT64 qwQuota)
-{
- QCALL_CONTRACT;
- BEGIN_QCALL;
-
- if (pAI == NULL)
- COMIsolatedStorage::ThrowISS(ISS_E_STORE_NOT_OPEN);
-
- PREFIX_ASSUME(pAI != NULL);
-
- pAI->SetQuota(qwQuota);
-
- END_QCALL;
-}
-
-// static
-void QCALLTYPE COMIsolatedStorageFile::GetRootDir(DWORD dwFlags,
- QCall::StringHandleOnStack retRootDir)
-{
- QCALL_CONTRACT;
- BEGIN_QCALL;
-
- WCHAR wszPath[MAX_LONGPATH + 1] = {0};
- GetRootDirInternal(dwFlags, wszPath, COUNTOF(wszPath));
- retRootDir.Set(wszPath);
-
- END_QCALL;
-}
-
-#ifndef FEATURE_ISOSTORE_LIGHT
-// static
-void QCALLTYPE COMIsolatedStorageFile::CreateDirectoryWithDacl(LPCWSTR wszPath)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(wszPath != NULL);
- } CONTRACTL_END;
-
- BEGIN_QCALL;
-
- SECURITY_ATTRIBUTES *pSecAttrib = NULL;
-
- SECURITY_ATTRIBUTES SecAttrib;
- SECURITY_DESCRIPTOR sd;
- NewArrayHolder<ACL> pDacl = NULL;
-
- memset(&SecAttrib, 0, sizeof(SecAttrib));
-
- BOOL ret = InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
- if (!ret)
- COMIsolatedStorage::ThrowISS(ISS_E_MACHINE_DACL);
-
- HRESULT hr = GetMachineStoreDacl(&pDacl);
- if (FAILED(hr))
- COMIsolatedStorage::ThrowISS(ISS_E_MACHINE_DACL);
-
- ret = SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE);
- if (!ret)
- COMIsolatedStorage::ThrowISS(ISS_E_MACHINE_DACL);
-
- SecAttrib.nLength = sizeof(SECURITY_ATTRIBUTES);
- SecAttrib.bInheritHandle = FALSE;
- SecAttrib.lpSecurityDescriptor = &sd;
- pSecAttrib = &SecAttrib;
-
- CreateDirectoryIfNotPresent(wszPath, pSecAttrib);
-
- END_QCALL;
-}
-
-// Get the machine location for Isolated Storage
-BOOL COMIsolatedStorageFile::GetMachineStoreDirectory (__out_ecount(cchMachineStorageRoot) WCHAR * wszMachineStorageRoot,
- DWORD cchMachineStorageRoot)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
- HRESULT hr = WszSHGetFolderPath(NULL,
- CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE,
- NULL,
- SHGFP_TYPE_CURRENT,
- cchMachineStorageRoot,
- wszMachineStorageRoot);
- LOG((LF_STORE, LL_INFO10000, "GetMachineStoreDirectory returned [%#x].\n", hr));
- return SUCCEEDED(hr);
-}
-
-// Creates a DACL for the machine store directory so that
-// everyone may create directories beneath it.
-// This method should only be called on NT platforms.
-
-HRESULT COMIsolatedStorageFile::GetMachineStoreDacl(PACL * ppAcl)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
- SID_IDENTIFIER_AUTHORITY siaWorld = SECURITY_WORLD_SID_AUTHORITY;
- SID_IDENTIFIER_AUTHORITY siaNTAuth = SECURITY_NT_AUTHORITY;
- SID_IDENTIFIER_AUTHORITY siaCreatorOwnerAuthority = SECURITY_CREATOR_SID_AUTHORITY;
- PSID pEveryoneSid = NULL;
- PSID pAdminsSid = NULL;
- PSID pCreatorOwnerSid = NULL;
-
- //
- // prepare Sids representing the world and admins
- //
-
- if (!AllocateAndInitializeSid(&siaWorld,
- 1,
- SECURITY_WORLD_RID,
- 0, 0, 0, 0, 0, 0, 0,
- &pEveryoneSid)) {
- hr = HRESULT_FROM_GetLastError();
- goto ErrorExit;
- }
-
- if (!AllocateAndInitializeSid(&siaNTAuth,
- 2,
- SECURITY_BUILTIN_DOMAIN_RID,
- DOMAIN_ALIAS_RID_ADMINS,
- 0, 0, 0, 0, 0, 0,
- &pAdminsSid)) {
- hr = HRESULT_FROM_GetLastError();
- goto ErrorExit;
- }
-
- if (!AllocateAndInitializeSid(&siaCreatorOwnerAuthority,
- 1,
- SECURITY_CREATOR_OWNER_RID,
- 0, 0, 0, 0, 0, 0, 0,
- &pCreatorOwnerSid)) {
- hr = HRESULT_FROM_GetLastError();
- goto ErrorExit;
- }
-
- //
- // compute size of new Acl
- //
-
- DWORD dwAclSize = sizeof(ACL)
- + 3 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD))
- + GetLengthSid(pEveryoneSid)
- + GetLengthSid(pAdminsSid)
- + GetLengthSid(pCreatorOwnerSid);
-
- *ppAcl = new ACL[dwAclSize / sizeof(ACL) + 1];
- if (!InitializeAcl(*ppAcl, dwAclSize, ACL_REVISION)) {
- hr = HRESULT_FROM_GetLastError();
- goto ErrorExit;
- }
-
- if (!AddAccessAllowedAce(*ppAcl,
- ACL_REVISION,
- (FILE_GENERIC_WRITE | FILE_GENERIC_READ) & (~WRITE_DAC),
- pEveryoneSid)) {
- hr = HRESULT_FROM_GetLastError();
- goto ErrorExit;
- }
-
- if (!AddAccessAllowedAce(*ppAcl,
- ACL_REVISION,
- FILE_ALL_ACCESS,
- pAdminsSid)) {
- hr = HRESULT_FROM_GetLastError();
- goto ErrorExit;
- }
-
- if (!AddAccessAllowedAce(*ppAcl,
- ACL_REVISION,
- FILE_ALL_ACCESS,
- pCreatorOwnerSid)) {
- hr = HRESULT_FROM_GetLastError();
- goto ErrorExit;
- }
-
- //
- // make ACL inheritable
- //
-
- PACCESS_ALLOWED_ACE pAce;
- for (DWORD index = 0; index < 3; index++) {
- if(!GetAce(*ppAcl, index, (void **) &pAce)) {
- hr = HRESULT_FROM_GetLastError();
- goto ErrorExit;
- }
- pAce->Header.AceFlags = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
- }
-
-ErrorExit:
- if (NULL != pEveryoneSid)
- FreeSid(pEveryoneSid);
- if (NULL != pAdminsSid)
- FreeSid(pAdminsSid);
- if (NULL != pCreatorOwnerSid)
- FreeSid(pCreatorOwnerSid);
-
- LOG((LF_STORE, LL_INFO10000, "GetMachineStoreDacl returned error code [%#x].\n", hr));
-
- return hr;
-}
-#endif // !FEATURE_ISOSTORE_LIGHT
-
-// Throws on error
-void COMIsolatedStorageFile::CreateDirectoryIfNotPresent(__in_z const WCHAR *path, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
-{
- STANDARD_VM_CONTRACT;
-
- LONG lresult;
-
- // Check if the directory is already present
- lresult = WszGetFileAttributes(path);
-
- if (lresult == -1)
- {
- if (!WszCreateDirectory(path, lpSecurityAttributes))
- {
- COMIsolatedStorage::ThrowISS(ISS_E_CREATE_DIR);
- }
- }
- else if ((lresult & FILE_ATTRIBUTE_DIRECTORY) == 0)
- {
- COMIsolatedStorage::ThrowISS(ISS_E_CREATE_DIR);
- }
-}
-
-// Synchronized by the managed caller
-
-#ifdef FEATURE_ISOSTORE_LIGHT
-
-const WCHAR* const g_relativePath[] = {
- W("\\CoreIsolatedStorage")
-};
-
-#define nRelativePathLen ( \
- sizeof("\\CoreIsolatedStorage") + 1)
-
-#else // FEATURE_ISOSTORE_LIGHT
-
-const WCHAR* const g_relativePath[] = {
- W("\\IsolatedStorage")
-};
-
-#define nRelativePathLen ( \
- sizeof("\\IsolatedStorage") + 1)
-
-#endif // FEATURE_ISOSTORE_LIGHT
-
-#define nSubDirs (sizeof(g_relativePath)/sizeof(g_relativePath[0]))
-
-void COMIsolatedStorageFile::GetRootDirInternal(
- DWORD dwFlags, __in_ecount(cPath) WCHAR *path, DWORD cPath)
-{
- CONTRACTL {
- STANDARD_VM_CHECK;
- PRECONDITION(cPath > 1);
- PRECONDITION(cPath <= MAX_LONGPATH + 1);
- } CONTRACTL_END;
-
- ULONG len;
-
- --cPath; // To be safe.
- path[cPath] = 0;
-
- // Get roaming or local App Data locations
- BOOL res;
-
-#ifdef FEATURE_ISOSTORE_LIGHT
- res = GetUserDir(path, cPath, FALSE);
-#else
- if ((dwFlags & ISS_MACHINE_STORE) == 0)
- res = GetUserDir(path, cPath, IS_ROAMING(dwFlags));
- else
- res = GetMachineStoreDirectory(path, cPath);
-#endif // !FEATURE_ISOSTORE_LIGHT
- LOG((LF_STORE, LL_INFO10000, "The isolated storage root directory location is [%S].\n", path));
-
- if (!res)
- {
- COMIsolatedStorage::ThrowISS(ISS_E_CREATE_DIR);
- }
-
- len = (ULONG)wcslen(path);
-
- if ((len + nRelativePathLen + 1) > cPath)
- COMIsolatedStorage::ThrowISS(ISS_E_PATH_LENGTH);
-
- CreateDirectoryIfNotPresent(path);
-
- // Create the store directory if necessary
- for (unsigned int i=0; i<nSubDirs; ++i)
- {
- wcscat_s(path, cPath, g_relativePath[i]);
- CreateDirectoryIfNotPresent(path);
- }
-
- wcscat_s(path, cPath, W("\\"));
-}
-
-#define WSZ_GLOBAL W("Global\\")
-
-//--------------------------------------------------------------------------
-// The file name is used to open / create the file.
-// A synchronization object will also be created using this name
-// with '\' replaced by '-'
-//--------------------------------------------------------------------------
-AccountingInfo::AccountingInfo(const WCHAR *wszFileName, const WCHAR *wszSyncName) :
- m_hFile(INVALID_HANDLE_VALUE),
- m_hMapping(NULL),
- m_hLock(NULL),
- m_pData(NULL)
-{
- STANDARD_VM_CONTRACT;
-
-#ifdef _DEBUG
- m_dwNumLocks = 0;
-#endif
-
- int buffLen;
- buffLen = (int)wcslen(wszFileName) + 1;
-
- NewArrayHolder<WCHAR> pwszFileName(new WCHAR[buffLen]);
-
- // String length is known, using a memcpy here is faster, however, this
- // makes the code here and below less readable, this is not a very frequent
- // operation. No real perf gain here. Same comment applies to the strcpy
- // following this.
-
- wcscpy_s(pwszFileName, buffLen, wszFileName);
-
- _ASSERTE(((int)wcslen(pwszFileName) + 1) <= buffLen);
-
- // Allocate the Mutex name
- buffLen = (int)wcslen(wszSyncName) + (sizeof(WSZ_GLOBAL) / sizeof(WCHAR)) + 1;
-
- NewArrayHolder<WCHAR> pwszName(new WCHAR[buffLen]);
-
- wcscpy_s(pwszName, buffLen, WSZ_GLOBAL);
- wcscat_s(pwszName, buffLen, wszSyncName);
-
- _ASSERTE(((int)wcslen(pwszName) + 1) <= buffLen);
-
- pwszFileName.SuppressRelease();
- pwszName.SuppressRelease();
-
- // Now publish the strings
- m_wszFileName = pwszFileName;
- m_wszName = pwszName;
-}
-
-//--------------------------------------------------------------------------
-// Frees memory, and open handles
-//--------------------------------------------------------------------------
-AccountingInfo::~AccountingInfo()
-{
- CONTRACTL
- {
- MODE_ANY;
- GC_NOTRIGGER;
- NOTHROW;
- }CONTRACTL_END;
-
- if (m_pData)
- CLRUnmapViewOfFile(m_pData);
-
- if (m_hMapping != NULL)
- CloseHandle(m_hMapping);
-
- if (m_hFile != INVALID_HANDLE_VALUE)
- CloseHandle(m_hFile);
-
- if (m_hLock != NULL)
- CloseHandle(m_hLock);
-
- if (m_wszFileName)
- delete [] m_wszFileName;
-
- if (m_wszName)
- delete [] m_wszName;
-
- _ASSERTE(m_dwNumLocks == 0);
-}
-
-//--------------------------------------------------------------------------
-// Init should be called before Reserve / GetUsage is called.
-// Creates the file if necessary
-//--------------------------------------------------------------------------
-HRESULT AccountingInfo::Init()
-{
- CONTRACTL {
- STANDARD_VM_CHECK;
- PRECONDITION(m_hLock == NULL); // Init was called multiple times on this object without calling Close
- } CONTRACTL_END;
-
- // Create the synchronization object
-
- HRESULT hr = S_OK;
- m_hLock = WszCreateMutex(NULL, FALSE /* Initially not owned */, m_wszName);
-
- if (m_hLock == NULL)
- IfFailGo(ISS_E_CREATE_MUTEX);
-
- // Init was called multiple times on this object without calling Close
-
- _ASSERTE(m_hFile == INVALID_HANDLE_VALUE);
-
- {
- // The default DACL is fine here since we've already set the DACL on the root
- m_hFile = WszCreateFile(m_wszFileName,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_ALWAYS,
- FILE_FLAG_RANDOM_ACCESS,
- NULL);
-
- if (m_hFile == INVALID_HANDLE_VALUE)
- IfFailGo(ISS_E_OPEN_STORE_FILE);
- }
-
- // If this file was created for the first time, then create the accounting
- // record and set to zero
- {
- AccountingInfoLockHolder pAI(this);
-
- DWORD dwLow = 0, dwHigh = 0; // For checking file size
- QWORD qwSize;
-
- dwLow = ::GetFileSize(m_hFile, &dwHigh);
-
- if ((dwLow == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
- {
- IfFailGo(ISS_E_GET_FILE_SIZE);
- }
-
- qwSize = ((QWORD)dwHigh << 32) | dwLow;
-
- if (qwSize < sizeof(ISS_RECORD))
- {
- DWORD dwWrite;
-
- // Need to create the initial file
- NewArrayHolder<BYTE> pb(new BYTE[sizeof(ISS_RECORD)]);
-
- memset(pb, 0, sizeof(ISS_RECORD));
-
- dwWrite = 0;
-
- if ((WriteFile(m_hFile, pb, sizeof(ISS_RECORD), &dwWrite, NULL)
- == 0) || (dwWrite != sizeof(ISS_RECORD)))
- {
- IfFailGo(ISS_E_FILE_WRITE);
- }
- }
-
- // Lock out of scope here will be released
- }
-ErrExit:
- ;
- return hr;
-}
-
-//--------------------------------------------------------------------------
-// Get the amount of quota saved on disk. Some hosts may allow users of
-// IsolatedStorage to increase the quota. If so, we persist this data.
-// If there is no saved quota, this method returns FALSE.
-//--------------------------------------------------------------------------
-BOOL AccountingInfo::GetQuota(
- INT64 *qwQuota)
-{
- STANDARD_VM_CONTRACT;
-
- BOOL retVal = FALSE;
- HRESULT hr = S_OK;
- {
- AccountingInfoLockHolder pAI(this);
-
- hr = Map();
-
- if (SUCCEEDED(hr))
- {
- if(m_pISSRecord->dwVersion >= 1) {
- *qwQuota = m_pISSRecord->qwQuota;
- retVal = TRUE;
- } else {
- *qwQuota = 0;
- retVal = FALSE;
- }
- Unmap();
- }
- else
- {
- *qwQuota = 0;
- retVal = FALSE;
- }
- }
- return retVal;
-}
-
-//--------------------------------------------------------------------------
-// Sets the amount of quota saved on disk. Some hosts may allow users of
-// IsolatedStorage to increase the quota. If so, we persist this data.
-//--------------------------------------------------------------------------
-void AccountingInfo::SetQuota(
- INT64 qwQuota)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
- {
- AccountingInfoLockHolder pAI(this);
-
- hr = Map();
-
- if (SUCCEEDED(hr))
- {
- m_pISSRecord->dwVersion = (m_pISSRecord->dwVersion >= 1) ? m_pISSRecord->dwVersion : 1;
- m_pISSRecord->qwQuota = qwQuota;
- Unmap();
- }
- }
-}
-
-//--------------------------------------------------------------------------
-// Reserves space (Increments qwQuota)
-// This method is synchronized. If quota + request > limit, method fails
-//--------------------------------------------------------------------------
-HRESULT AccountingInfo::Reserve(
- ISS_USAGE cLimit, // The max allowed
- ISS_USAGE cRequest, // amount of space (request / free)
- BOOL fFree) // TRUE will free, FALSE will reserve
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
- {
- AccountingInfoLockHolder pAI(this);
-
- hr = Map();
-
- if (SUCCEEDED(hr))
- {
- if (fFree)
- {
- if (m_pISSRecord->cUsage > cRequest)
- m_pISSRecord->cUsage -= cRequest;
- else
- m_pISSRecord->cUsage = 0;
- }
- else
- {
- if ((m_pISSRecord->cUsage + cRequest) > cLimit)
- hr = ISS_E_USAGE_WILL_EXCEED_QUOTA;
- else
- // Safe to increment quota.
- m_pISSRecord->cUsage += cRequest;
- }
-
- Unmap();
- }
- // Lock out of scope here will be released
- }
-
- return hr;
-}
-
-//--------------------------------------------------------------------------
-// Method is not synchronized. So the information may not be current.
-// This implies "Pass if (Request + GetUsage() < Limit)" is an Error!
-// Use Reserve() method instead.
-//--------------------------------------------------------------------------
-HRESULT AccountingInfo::GetUsage(ISS_USAGE *pcUsage) // pcUsage - [out]
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
- {
- AccountingInfoLockHolder pAI(this);
-
- hr = Map();
-
- if (! FAILED(hr))
- {
- *pcUsage = m_pISSRecord->cUsage;
-
- Unmap();
- }
- // Lock out of scope here will be released
- }
- return hr;
-}
-
-//--------------------------------------------------------------------------
-// Maps the store file into memory
-//--------------------------------------------------------------------------
-HRESULT AccountingInfo::Map()
-{
- STANDARD_VM_CONTRACT;
-
- // Mapping will fail if filesize is 0
- if (m_hMapping == NULL)
- {
- m_hMapping = WszCreateFileMapping(
- m_hFile,
- NULL,
- PAGE_READWRITE,
- 0,
- 0,
- NULL);
-
- if (m_hMapping == NULL)
- return ISS_E_OPEN_FILE_MAPPING;
- }
-
- _ASSERTE(m_pData == NULL);
-
- m_pData = (PBYTE) CLRMapViewOfFile(
- m_hMapping,
- FILE_MAP_WRITE,
- 0,
- 0,
- 0);
-
- if (m_pData == NULL)
- return ISS_E_MAP_VIEW_OF_FILE;
-
- return S_OK;
-}
-
-//--------------------------------------------------------------------------
-// Unmaps the store file from memory
-//--------------------------------------------------------------------------
-void AccountingInfo::Unmap()
-{
- CONTRACTL
- {
- MODE_ANY;
- GC_NOTRIGGER;
- NOTHROW;
- }CONTRACTL_END;
-
-
- if (m_pData)
- {
- CLRUnmapViewOfFile(m_pData);
- m_pData = NULL;
- }
-}
-
-//--------------------------------------------------------------------------
-// Close the store file, and file mapping
-//--------------------------------------------------------------------------
-void AccountingInfo::Close()
-{
- WRAPPER_NO_CONTRACT;
- Unmap();
-
- if (m_hMapping != NULL)
- {
- CloseHandle(m_hMapping);
- m_hMapping = NULL;
- }
-
- if (m_hFile != INVALID_HANDLE_VALUE)
- {
- CloseHandle(m_hFile);
- m_hFile = INVALID_HANDLE_VALUE;
- }
-
- if (m_hLock != NULL)
- {
- CloseHandle(m_hLock);
- m_hLock = NULL;
- }
-
-#ifdef _DEBUG
- _ASSERTE(m_dwNumLocks == 0);
-#endif
-}
-
-//--------------------------------------------------------------------------
-// Machine wide Lock
-//--------------------------------------------------------------------------
-HRESULT AccountingInfo::Lock()
-{
- STANDARD_VM_CONTRACT;
-
- // Lock is intented to be used for inter process/thread synchronization.
-
-#ifdef _DEBUG
- _ASSERTE(m_hLock);
-
- LOG((LF_STORE, LL_INFO10000, "Lock %S, thread 0x%x start..\n",
- m_wszName, GetCurrentThreadId()));
-#endif
-
- DWORD dwRet;
- {
- // m_hLock is a mutex
-#ifndef FEATURE_CORECLR
- Thread::BeginThreadAffinityAndCriticalRegion();
-#endif
- dwRet = WaitForSingleObject(m_hLock, INFINITE);
- }
-
-#ifdef _DEBUG
- if (dwRet == WAIT_OBJECT_0)
- InterlockedIncrement((LPLONG)&m_dwNumLocks);
-
- switch (dwRet)
- {
- case WAIT_OBJECT_0:
- LOG((LF_STORE, LL_INFO10000, "Loc %S, thread 0x%x - WAIT_OBJECT_0\n",
- m_wszName, GetCurrentThreadId()));
- break;
-
- case WAIT_ABANDONED:
- LOG((LF_STORE, LL_INFO10000, "Loc %S, thread 0x%x - WAIT_ABANDONED\n",
- m_wszName, GetCurrentThreadId()));
- break;
-
- case WAIT_FAILED:
- LOG((LF_STORE, LL_INFO10000, "Loc %S, thread 0x%x - WAIT_FAILED\n",
- m_wszName, GetCurrentThreadId()));
- break;
-
- case WAIT_TIMEOUT:
- LOG((LF_STORE, LL_INFO10000, "Loc %S, thread 0x%x - WAIT_TIMEOUT\n",
- m_wszName, GetCurrentThreadId()));
- break;
-
- default:
- LOG((LF_STORE, LL_INFO10000, "Loc %S, thread 0x%x - 0x%x\n",
- m_wszName, GetCurrentThreadId(), dwRet));
- break;
- }
-
-#endif
-
- if ((dwRet == WAIT_OBJECT_0) || (dwRet == WAIT_ABANDONED))
- return S_OK;
-
- return ISS_E_LOCK_FAILED;
-}
-
-//--------------------------------------------------------------------------
-// Unlock the store
-//--------------------------------------------------------------------------
-void AccountingInfo::Unlock()
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- } CONTRACTL_END;
-
-#ifdef _DEBUG
- _ASSERTE(m_hLock);
- _ASSERTE(m_dwNumLocks >= 1);
-
- LOG((LF_STORE, LL_INFO10000, "UnLoc %S, thread 0x%x\n",
- m_wszName, GetCurrentThreadId()));
-#endif
-
- BOOL released;
- released = ReleaseMutex(m_hLock);
- _ASSERTE(released);
-
-#ifdef _DEBUG
- InterlockedDecrement((LPLONG)&m_dwNumLocks);
-#endif
-
-#ifndef FEATURE_CORECLR
- Thread::EndThreadAffinityAndCriticalRegion();
-#endif
-}
-
-#endif
diff --git a/src/vm/comisolatedstorage.h b/src/vm/comisolatedstorage.h
deleted file mode 100644
index 7eb219975e..0000000000
--- a/src/vm/comisolatedstorage.h
+++ /dev/null
@@ -1,202 +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.
-
-//============================================================
-//
-// Class: COMIsolatedStorage
-//
-//
-// Purpose: Native Implementation of IsolatedStorage
-//
-
-//
-
-//============================================================
-
-
-#ifndef __COMISOLATEDSTORAGE_h__
-#define __COMISOLATEDSTORAGE_h__
-#ifdef FEATURE_ISOSTORE
-
-// Dependency in managed : System.IO.IsolatedStorage.IsolatedStorage.cs
-#ifndef FEATURE_ISOSTORE_LIGHT
-#define ISS_ROAMING_STORE 0x08
-#define ISS_MACHINE_STORE 0x10
-#endif // !FEATURE_ISOSTORE_LIGHT
-
-class COMIsolatedStorage
-{
-public:
-#ifndef FEATURE_ISOSTORE_LIGHT
- static
- void QCALLTYPE GetCaller(QCall::ObjectHandleOnStack retAssembly);
-#endif // !FEATURE_ISOSTORE_LIGHT
-
- static void DECLSPEC_NORETURN ThrowISS(HRESULT hr);
-
-private:
-#ifndef FEATURE_ISOSTORE_LIGHT
- static StackWalkAction StackWalkCallBack(CrawlFrame* pCf, PVOID ppv);
-#endif // !FEATURE_ISOSTORE_LIGHT
-};
-
-// --- [ Structure of data that gets persisted on disk ] -------------(Begin)
-
-// non-standard extension: 0-length arrays in struct
-#ifdef _MSC_VER
-#pragma warning(disable:4200)
-#endif
-#include <pshpack1.h>
-
-typedef unsigned __int64 QWORD;
-
-typedef QWORD ISS_USAGE;
-
-// Accounting Information
-typedef struct
-{
- ISS_USAGE cUsage; // The amount of resource used
-
- DWORD dwVersion; // Version of bookkeeping file on disk (so we know the layout)
- QWORD qwQuota; // Quota stored on disk (persisted if increased by the host)
- QWORD qwReserved[5]; // For future use, set to 0
- DWORD dwReserved; // For future use, set to 0
-
-} ISS_RECORD;
-
-#include <poppack.h>
-#ifdef _MSC_VER
-#pragma warning(default:4200)
-#endif
-
-// --- [ Structure of data that gets persisted on disk ] ---------------(End)
-
-class AccountingInfo
-{
-public:
-
- // The file name is used to open / create the file.
- // A synchronization object will also be created using the sync name
-
- AccountingInfo(const WCHAR *wszFileName, const WCHAR *wszSyncName);
-
- // Init should be called before Reserve / GetUsage is called.
-
- HRESULT Init(); // Creates the file if necessary
-
- // Reserves space (Increments qwQuota)
- // This method is synchrinized. If quota + request > limit, method fails
-
- HRESULT Reserve(
- ISS_USAGE cLimit, // The max allowed
- ISS_USAGE cRequest, // amount of space (request / free)
- BOOL fFree); // TRUE will free, FALSE will reserve
-
- // Method is not synchronized. So the information may not be current.
- // This implies "Pass if (Request + GetUsage() < Limit)" is an Error!
- // Use Reserve() method instead.
-
- HRESULT GetUsage(
- ISS_USAGE *pcUsage); // [out] The amount of space / resource used
-
- BOOL GetQuota(
- INT64 *qwQuota); // [out] The Quota stored on disk (if there is one)
-
- void SetQuota(
- INT64 qwQuota); // [out] The Quota stored on disk (if there is one)
-
- // Frees cached pointers, Closes handles
-
- ~AccountingInfo();
-
- static void AcquireLock(AccountingInfo *pAI) {
- STANDARD_VM_CONTRACT;
- HRESULT hr = pAI->Lock();
- if (FAILED(hr)) COMIsolatedStorage::ThrowISS(hr);
- }
- static void ReleaseLock(AccountingInfo *pAI) {
- WRAPPER_NO_CONTRACT;
- pAI->Unlock();
- }
- typedef Holder<AccountingInfo *, AccountingInfo::AcquireLock, AccountingInfo::ReleaseLock> AccountingInfoLockHolder;
-
-private:
- HRESULT Lock(); // Machine wide Lock
- void Unlock(); // Unlock the store
-
- HRESULT Map(); // Maps the store file into memory
- void Unmap(); // Unmaps the store file from memory
- void Close(); // Close the store file, and file mapping
-
- WCHAR *m_wszFileName; // The file name
- HANDLE m_hFile; // File handle for the file
- HANDLE m_hMapping; // File mapping for the memory mapped file
-
- // members used for synchronization
- WCHAR *m_wszName; // The name of the mutex object
- HANDLE m_hLock; // Handle to the Mutex object
-
-#ifdef _DEBUG
- ULONG m_dwNumLocks; // The number of locks owned by this object
-#endif
-
- union {
- PBYTE m_pData; // The start of file stream
- ISS_RECORD *m_pISSRecord;
- };
-};
-class COMIsolatedStorageFile
-{
-public:
- static
- void QCALLTYPE GetRootDir(DWORD dwFlags,
- QCall::StringHandleOnStack retRootDir);
-
- static
- UINT64 QCALLTYPE GetUsage(__in_opt AccountingInfo * pAI);
-
- static
- void QCALLTYPE Reserve(__in_opt AccountingInfo * pAI,
- UINT64 qwQuota,
- UINT64 qwReserve,
- BOOL fFree);
-
- static
- BOOL QCALLTYPE GetQuota(__in_opt AccountingInfo * pAI,
- __out INT64 * qwQuota);
-
- static
- void QCALLTYPE SetQuota(__in_opt AccountingInfo * pAI,
- INT64 qwQuota);
-
- static
- AccountingInfo * QCALLTYPE Open(LPCWSTR wszFileName,
- LPCWSTR wszSyncName);
-
- static
- void QCALLTYPE Close(__in_opt AccountingInfo * pAI);
-
- static
- BOOL QCALLTYPE Lock(__in AccountingInfo * handle,
- BOOL fLock);
-
-#ifndef FEATURE_ISOSTORE_LIGHT
- // create the machine store root directory and apply the correct DACL
- static
- void QCALLTYPE CreateDirectoryWithDacl(LPCWSTR wszPath);
-#endif // !FEATURE_ISOSTORE_LIGHT
-
-private:
-
- static void GetRootDirInternal(DWORD dwFlags, __in_ecount(cPath) WCHAR *path, DWORD cPath);
- static void CreateDirectoryIfNotPresent(__in_z const WCHAR *path, LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL);
-#ifndef FEATURE_ISOSTORE_LIGHT
- static BOOL GetMachineStoreDirectory(__out_ecount(cchMachineStorageRoot) WCHAR *wszMachineStorageRoot, DWORD cchMachineStorageRoot);
- static HRESULT GetMachineStoreDacl(PACL *ppAcl);
-#endif // !FEATURE_ISOSTORE_LIGHT
-};
-#endif // FEATURE_ISOSTORE
-
-#endif // __COMISOLATEDSTORAGE_h__
-
diff --git a/src/vm/commemoryfailpoint.cpp b/src/vm/commemoryfailpoint.cpp
index 4d1ed6ef64..2900409fb1 100644
--- a/src/vm/commemoryfailpoint.cpp
+++ b/src/vm/commemoryfailpoint.cpp
@@ -27,8 +27,8 @@ FCIMPL2(void, COMMemoryFailPoint::GetMemorySettings, UINT64* pMaxGCSegmentSize,
FCALL_CONTRACT;
IGCHeap * pGC = GCHeapUtilities::GetGCHeap();
- size_t segment_size = pGC->GetValidSegmentSize(FALSE);
- size_t large_segment_size = pGC->GetValidSegmentSize(TRUE);
+ size_t segment_size = pGC->GetValidSegmentSize(false);
+ size_t large_segment_size = pGC->GetValidSegmentSize(true);
_ASSERTE(segment_size < SIZE_T_MAX && large_segment_size < SIZE_T_MAX);
if (segment_size > large_segment_size)
*pMaxGCSegmentSize = (UINT64) segment_size;
diff --git a/src/vm/commethodrental.cpp b/src/vm/commethodrental.cpp
deleted file mode 100644
index 0a5c011270..0000000000
--- a/src/vm/commethodrental.cpp
+++ /dev/null
@@ -1,120 +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 "common.h"
-#include "commethodrental.h"
-#include "corerror.h"
-
-#ifdef FEATURE_METHOD_RENTAL
-// SwapMethodBody
-// This method will take the rgMethod as the new function body for a given method.
-//
-
-void QCALLTYPE COMMethodRental::SwapMethodBody(EnregisteredTypeHandle cls, INT32 tkMethod, LPVOID rgMethod, INT32 iSize, INT32 flags, QCall::StackCrawlMarkHandle stackMark)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- BYTE *pNewCode = NULL;
- MethodDesc *pMethodDesc;
- ReflectionModule *module;
- ICeeGen* pGen;
- ULONG methodRVA;
- HRESULT hr;
-
- if ( cls == NULL)
- {
- COMPlusThrowArgumentNull(W("cls"));
- }
-
- MethodTable *pMethodTable = TypeHandle::FromPtr(cls).GetMethodTable();
- PREFIX_ASSUME(pMethodTable != NULL);
- module = (ReflectionModule *) pMethodTable->GetModule();
- pGen = module->GetCeeGen();
-
- Assembly* caller = SystemDomain::GetCallersAssembly( stackMark );
-
- _ASSERTE( caller != NULL && "Unable to get calling assembly" );
- _ASSERTE( module->GetCreatingAssembly() != NULL && "ReflectionModule must have a creating assembly to be used with method rental" );
-
- if (module->GetCreatingAssembly() != caller)
- {
- COMPlusThrow(kSecurityException);
- }
-
- // Find the methoddesc given the method token
- pMethodDesc = MemberLoader::FindMethod(pMethodTable, tkMethod);
- if (pMethodDesc == NULL)
- {
- COMPlusThrowArgumentException(W("methodtoken"), NULL);
- }
- if (pMethodDesc->GetMethodTable() != pMethodTable || pMethodDesc->GetNumGenericClassArgs() != 0 || pMethodDesc->GetNumGenericMethodArgs() != 0)
- {
- COMPlusThrowArgumentException(W("methodtoken"), W("Argument_TypeDoesNotContainMethod"));
- }
- hr = pGen->AllocateMethodBuffer(iSize, &pNewCode, &methodRVA);
- if (FAILED(hr))
- COMPlusThrowHR(hr);
-
- if (pNewCode == NULL)
- {
- COMPlusThrowOM();
- }
-
- // <TODO>
- // if method desc is pointing to the post-jitted native code block,
- // we want to recycle this code block
-
- // @todo: SEH handling. Will we need to support a method that can throw exception
- // If not, add an assertion to make sure that there is no SEH contains in the method header.
-
- // @todo: figure out a way not to copy the code block.
-
- // @todo: add link time security check. This function can be executed only if fully trusted.</TODO>
-
- // copy the new function body to the buffer
- memcpy(pNewCode, (void *) rgMethod, iSize);
-
- // add the starting address of the il blob to the il blob hash table
- // we need to find this information from out of process for debugger inspection
- // APIs so we have to store this information where we can get it later
- module->SetDynamicIL(mdToken(tkMethod), TADDR(pNewCode), FALSE);
-
- // Reset the methoddesc back to unjited state
- pMethodDesc->Reset();
-
- if (flags)
- {
- // JITImmediate
-#if _DEBUG
- COR_ILMETHOD* ilHeader = pMethodDesc->GetILHeader(TRUE);
- _ASSERTE(((BYTE *)ilHeader) == pNewCode);
-#endif
- COR_ILMETHOD_DECODER header((COR_ILMETHOD *)pNewCode, pMethodDesc->GetMDImport(), NULL);
-
- // minimum validation on the correctness of method header
- if (header.GetCode() == NULL)
- COMPlusThrowHR(VLDTR_E_MD_BADHEADER);
-
-#ifdef FEATURE_INTERPRETER
- pMethodDesc->MakeJitWorker(&header, CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_MAKEFINALCODE));
-#else // !FEATURE_INTERPRETER
- pMethodDesc->MakeJitWorker(&header, CORJIT_FLAGS());
-#endif // !FEATURE_INTERPRETER
- }
-
- // add feature::
- // If SQL is generating class with inheritance hierarchy, we may need to
- // check the whole vtable to find duplicate entries.
-
- END_QCALL;
-
-} // COMMethodRental::SwapMethodBody
-
-
-#endif // FEATURE_METHOD_RENTAL
diff --git a/src/vm/commethodrental.h b/src/vm/commethodrental.h
deleted file mode 100644
index 0523af274e..0000000000
--- a/src/vm/commethodrental.h
+++ /dev/null
@@ -1,29 +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.
-////////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef _COMMETHODRENTAL_H_
-#define _COMMETHODRENTAL_H_
-
-#include "excep.h"
-#include "fcall.h"
-
-#ifdef FEATURE_METHOD_RENTAL
-// COMMethodRental
-// This class implements SwapMethodBody for our MethodRenting story
-class COMMethodRental
-{
-public:
-
- // COMMethodRental.SwapMethodBody -- this function will swap an existing method body with
- // a new method body
- //
- static
- void QCALLTYPE SwapMethodBody(EnregisteredTypeHandle cls, INT32 tkMethod, LPVOID rgMethod, INT32 iSize, INT32 flags, QCall::StackCrawlMarkHandle stackMark);
-};
-#endif // FEATURE_METHOD_RENTAL
-
-#endif //_COMMETHODRENTAL_H_
diff --git a/src/vm/commodule.cpp b/src/vm/commodule.cpp
index af6dc48d15..cb14967295 100644
--- a/src/vm/commodule.cpp
+++ b/src/vm/commodule.cpp
@@ -45,12 +45,6 @@ static ISymUnmanagedWriter **CreateISymWriterForDynamicModule(ReflectionModule *
//
ESymbolFormat symFormatToUse = eSymbolFormatILDB;
-#ifndef FEATURE_CORECLR // On desktop only we still use PDB format if the symbols are savable to disk
- if(mod->GetAssembly()->HasSaveAccess())
- {
- symFormatToUse = eSymbolFormatPDB;
- }
-#endif
static ConfigDWORD dbgForcePDBSymbols;
if(dbgForcePDBSymbols.val_DontUse_(W("DbgForcePDBSymbols"), 0) == 1)
@@ -121,46 +115,6 @@ static ISymUnmanagedWriter **CreateISymWriterForDynamicModule(ReflectionModule *
}
}
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-//****************************************
-// This function creates a dynamic module underneath the current assembly.
-//****************************************
-void QCALLTYPE COMModule::DefineDynamicModule(QCall::AssemblyHandle pContainingAssembly, BOOL emitSymbolInfo, LPCWSTR pModuleName, LPCWSTR pFilename, QCall::StackCrawlMarkHandle stackMark, LPVOID* ppInternalSymWriter, QCall::ObjectHandleOnStack retModule, BOOL fIsTransient, INT32* ptkFile)
-{
- QCALL_CONTRACT;
-
- ReflectionModule * mod = NULL;
-
- BEGIN_QCALL;
-
- Assembly * pAssembly = pContainingAssembly->GetAssembly();
- _ASSERTE(pAssembly);
-
- // always create a dynamic module. Note that the name conflict
- // checking is done in managed side.
-
- mod = pAssembly->CreateDynamicModule(pModuleName, pFilename, fIsTransient, ptkFile);
-
- mod->SetCreatingAssembly( SystemDomain::GetCallersAssembly( stackMark ) );
-
- // If we need to emit symbol info, we setup the proper symbol
- // writer for this module now.
- if (emitSymbolInfo)
- {
- ISymUnmanagedWriter **pWriter = CreateISymWriterForDynamicModule(mod, pFilename);
- if (ppInternalSymWriter)
- {
- *ppInternalSymWriter = pWriter;
- }
- }
-
- GCX_COOP();
- retModule.Set(mod->GetExposedObject());
- END_QCALL;
-
- return;
-}
-#endif //FEATURE_MULTIMODULE_ASSEMBLIES
//===============================================================================================
// Attaches an unmanaged symwriter to a newly created dynamic module.
//===============================================================================================
@@ -951,13 +905,6 @@ void QCALLTYPE COMModule::GetFullyQualifiedName(QCall::ModuleHandle pModule, QCa
{
LPCWSTR fileName = pModule->GetPath();
if (*fileName != 0) {
-#ifndef FEATURE_CORECLR
- // workaround - lie about where mscorlib is. Mscorlib is now loaded out of the GAC,
- // but some apps query its location to find the system directory. (Notably CodeDOM)
- if (pModule->IsSystem())
- retString.Set(SystemDomain::System()->BaseLibrary());
- else
-#endif // !FEATURE_CORECLR
{
#ifdef FEATURE_WINDOWSPHONE
//
@@ -1099,12 +1046,7 @@ Object* GetTypesInner(Module* pModule)
// Allocate the COM+ array
bSystemAssembly = (pModule->GetAssembly() == SystemDomain::SystemAssembly());
-#ifdef FEATURE_REMOTING
- // we skip the TransparentProxy type if this is mscorlib, so we can make the array one element smaller
- AllocSize = !bSystemAssembly ? dwNumTypeDefs : dwNumTypeDefs - 1;
-#else
AllocSize = dwNumTypeDefs;
-#endif
refArrClasses = (PTRARRAYREF) AllocateObjectArray(AllocSize, MscorlibBinder::GetClass(CLASS__CLASS));
int curPos = 0;
@@ -1182,60 +1124,6 @@ Object* GetTypesInner(Module* pModule)
RETURN(OBJECTREFToObject(refArrClasses));
}
-#if defined(FEATURE_X509) && defined(FEATURE_CAS_POLICY)
-//+--------------------------------------------------------------------------
-//
-// Member: COMModule::GetSignerCertificate()
-//
-// Synopsis: Gets the certificate with which the module was signed.
-//
-// Effects: Creates an X509Certificate and returns it.
-//
-// Arguments: None.
-//
-// Returns: OBJECTREF to an X509Certificate object containing the
-// signer certificate.
-//
-//---------------------------------------------------------------------------
-
-void QCALLTYPE COMModule::GetSignerCertificate(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retData)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- PCOR_TRUST pCorTrust = NULL;
- IAssemblySecurityDescriptor* pSecDesc = NULL;
- PBYTE pbSigner = NULL;
- DWORD cbSigner = 0;
-
- // ******** Get the security descriptor ********
-
- // Get a pointer to the module security descriptor
- pSecDesc = pModule->GetSecurityDescriptor();
- _ASSERTE(pSecDesc);
-
- // ******** Get COR_TRUST info from module security descriptor ********
- if (FAILED(pSecDesc->LoadSignature(&pCorTrust)))
- {
- COMPlusThrow(kArgumentNullException, W("InvalidOperation_MetaDataError"));
- }
-
- if( pCorTrust )
- {
- // Get a pointer to the signer certificate information in the COR_TRUST
- pbSigner = pCorTrust->pbSigner;
- cbSigner = pCorTrust->cbSigner;
-
- if( pbSigner && cbSigner )
- {
- retData.SetByteArray(pbSigner, cbSigner);
- }
- }
-
- END_QCALL;
-}
-#endif // #if defined(FEATURE_X509) && defined(FEATURE_CAS_POLICY)
FCIMPL1(FC_BOOL_RET, COMModule::IsResource, ReflectModuleBaseObject* pModuleUNSAFE)
{
@@ -1248,7 +1136,6 @@ FCIMPL1(FC_BOOL_RET, COMModule::IsResource, ReflectModuleBaseObject* pModuleUNSA
}
FCIMPLEND
-#ifdef FEATURE_CORECLR
//---------------------------------------------------------------------
// Helper code for PunkSafeHandle class. This does the Release in the
@@ -1283,6 +1170,5 @@ FCIMPL0(void*, COMPunkSafeHandle::nGetDReleaseTarget)
return (void*)DReleaseTarget;
}
FCIMPLEND
-#endif //FEATURE_CORECLR
diff --git a/src/vm/commodule.h b/src/vm/commodule.h
index 255b22dfbf..837a432b17 100644
--- a/src/vm/commodule.h
+++ b/src/vm/commodule.h
@@ -18,12 +18,6 @@ public:
// Attaches an unmanaged symwriter to a newly created dynamic module.
static FCDECL2(LPVOID, nCreateISymWriterForDynamicModule, ReflectModuleBaseObject* reflectionModuleUNSAFE, StringObject* filenameUNSAFE);
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- // DefineDynamicModule
- // This method will create a dynamic module given an assembly
- static
- void QCALLTYPE DefineDynamicModule(QCall::AssemblyHandle pContainingAssembly, BOOL emitSymbolInfo, LPCWSTR pModuleName, LPCWSTR pFilename, QCall::StackCrawlMarkHandle stackMark, LPVOID* ppInternalSymWriter, QCall::ObjectHandleOnStack retModule, BOOL fIsTransient, INT32* ptkFile);
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
// IsTransient
// Determine if a Module is transient
@@ -103,11 +97,6 @@ public:
static
mdString QCALLTYPE GetStringConstant(QCall::ModuleHandle pModule, LPCWSTR pwzValue, INT32 iLength);
-#if defined(FEATURE_X509) && defined(FEATURE_CAS_POLICY)
- /*X509Certificate*/
- static
- void QCALLTYPE GetSignerCertificate(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retData);
-#endif // #if defined(FEATURE_X509) && defined(FEATURE_CAS_POLICY)
static
void QCALLTYPE SetModuleName(QCall::ModuleHandle pModule, LPCWSTR wszModuleName);
@@ -135,9 +124,7 @@ public:
class COMPunkSafeHandle
{
public:
-#ifdef FEATURE_CORECLR
static FCDECL0(void*, nGetDReleaseTarget);
-#endif
};
#endif
diff --git a/src/vm/common.h b/src/vm/common.h
index 9de9f35141..15b97f1dfe 100644
--- a/src/vm/common.h
+++ b/src/vm/common.h
@@ -99,9 +99,6 @@
#include "compatibilityflags.h"
extern BOOL GetCompatibilityFlag(CompatibilityFlag flag);
-#ifndef FEATURE_CORECLR
-extern DWORD* GetGlobalCompatibilityFlags();
-#endif // !FEATURE_CORECLR
#include "strongname.h"
#include "stdmacros.h"
@@ -366,7 +363,6 @@ namespace Loader
#include "threads.h"
#include "clrex.inl"
#ifdef FEATURE_COMINTEROP
- // These need to be included *after* threads.h so that they can properly use LeaveRuntimeHolder
#include "windowsruntime.h"
#include "windowsstring.h"
#endif
@@ -387,7 +383,6 @@ namespace Loader
#include "interoputil.h"
#include "wrappers.h"
#include "dynamicmethod.h"
-#include "mixedmode.hpp"
#include "gcstress.h"
@@ -399,11 +394,6 @@ inline VOID UnsafeEEEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
STATIC_CONTRACT_GC_NOTRIGGER;
STATIC_CONTRACT_CAN_TAKE_LOCK;
-#ifndef FEATURE_CORECLR
- if (CLRTaskHosted()) {
- Thread::BeginThreadAffinity();
- }
-#endif // !FEATURE_CORECLR
UnsafeEnterCriticalSection(lpCriticalSection);
INCTHREADLOCKCOUNT();
}
@@ -415,11 +405,6 @@ inline VOID UnsafeEELeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
UnsafeLeaveCriticalSection(lpCriticalSection);
DECTHREADLOCKCOUNT();
-#ifndef FEATURE_CORECLR
- if (CLRTaskHosted()) {
- Thread::EndThreadAffinity();
- }
-#endif // !FEATURE_CORECLR
}
inline BOOL UnsafeEETryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
diff --git a/src/vm/compile.cpp b/src/vm/compile.cpp
index 87107151eb..09925cd219 100644
--- a/src/vm/compile.cpp
+++ b/src/vm/compile.cpp
@@ -27,14 +27,10 @@
#include "zapsig.h"
#include "gcrefmap.h"
-#ifndef FEATURE_CORECLR
-#include "corsym.h"
-#endif // FEATURE_CORECLR
#include "virtualcallstub.h"
#include "typeparse.h"
#include "typestring.h"
-#include "constrainedexecutionregion.h"
#include "dllimport.h"
#include "comdelegate.h"
#include "stringarraylist.h"
@@ -51,11 +47,6 @@
#include "cgensys.h"
#include "peimagelayout.inl"
-#if defined(FEATURE_APPX_BINDER)
-#include "appxutil.h"
-#include "clrprivbinderappx.h"
-#include "clrprivtypecachewinrt.h"
-#endif // defined(FEATURE_APPX_BINDER)
#ifdef FEATURE_COMINTEROP
#include "clrprivbinderwinrt.h"
@@ -77,6 +68,7 @@
#include "argdestination.h"
#include "versionresilienthashcode.h"
+#include "inlinetracking.h"
#ifdef CROSSGEN_COMPILE
CompilationDomain * theDomain;
@@ -163,17 +155,6 @@ HRESULT CEECompileInfo::CreateDomain(ICorCompilationDomain **ppDomain,
if (pEmitter)
pCompilationDomain->SetDependencyEmitter(pEmitter);
-#if defined(FEATURE_APPX_BINDER)
- if (AppX::IsAppXProcess())
- {
- HRESULT hr = S_OK;
- ReleaseHolder<ICLRPrivBinder> pBinderInterface;
- CLRPrivBinderAppX * pBinder = CLRPrivBinderAppX::GetOrCreateBinder();
-
- IfFailThrow(pBinder->QueryInterface(IID_ICLRPrivBinder, &pBinderInterface));
- pCompilationDomain->SetLoadContextHostBinder(pBinderInterface);
- }
-#endif // defined(FEATURE_APPX_BINDER)
#ifdef DEBUGGING_SUPPORTED
// Notify the debugger here, before the thread transitions into the
@@ -192,20 +173,14 @@ HRESULT CEECompileInfo::CreateDomain(ICorCompilationDomain **ppDomain,
ENTER_DOMAIN_PTR(pCompilationDomain,ADV_COMPILATION)
{
-#ifdef FEATURE_CORECLR
if (fForceFulltrustDomain)
((ApplicationSecurityDescriptor *)pCompilationDomain->GetSecurityDescriptor())->SetGrantedPermissionSet(NULL, NULL, 0xFFFFFFFF);
-#endif
#ifndef CROSSGEN_COMPILE
-#ifndef FEATURE_CORECLR
- pCompilationDomain->InitializeHashing(NULL);
-#endif // FEATURE_CORECLR
#endif
pCompilationDomain->InitializeDomainContext(TRUE, NULL, NULL);
#ifndef CROSSGEN_COMPILE
-#ifdef FEATURE_CORECLR
if (!NingenEnabled())
{
@@ -223,7 +198,6 @@ HRESULT CEECompileInfo::CreateDomain(ICorCompilationDomain **ppDomain,
initializeSecurity.Call(args);
GCPROTECT_END();
}
-#endif //FEATURE_CORECLR
#endif
{
@@ -231,28 +205,9 @@ HRESULT CEECompileInfo::CreateDomain(ICorCompilationDomain **ppDomain,
// We load assemblies as domain-bound (However, they're compiled as domain neutral)
#ifdef FEATURE_LOADER_OPTIMIZATION
-#ifdef FEATURE_FUSION
- if (NingenEnabled())
- {
- pCompilationDomain->SetSharePolicy(AppDomain::SHARE_POLICY_NEVER);
- }
- else
- {
- pCompilationDomain->SetupLoaderOptimization(AppDomain::SHARE_POLICY_NEVER);
- }
-#else //FEATURE_FUSION
pCompilationDomain->SetSharePolicy(AppDomain::SHARE_POLICY_NEVER);
-#endif //FEATURE_FUSION
#endif // FEATURE_LOADER_OPTIMIZATION
-#ifdef FEATURE_FUSION
- CorCompileConfigFlags flags = PEFile::GetNativeImageConfigFlags(pCompilationDomain->m_fForceDebug,
- pCompilationDomain->m_fForceProfiling,
- pCompilationDomain->m_fForceInstrument);
-
- FusionBind::SetApplicationContextDWORDProperty(GetAppDomain()->GetFusionContext(),
- ACTAG_ZAP_CONFIG_FLAGS, flags);
-#endif //FEATURE_FUSION
}
pCompilationDomain->SetFriendlyName(W("Compilation Domain"));
@@ -393,14 +348,6 @@ HRESULT CEECompileInfo::LoadAssemblyByPath(
PEImageHolder pImage;
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- // If the path is not absolute, look for the assembly on platform path list first
- if (wcschr(wzPath, '\\') == NULL || wcschr(wzPath, ':') == NULL || wcschr(wzPath, '/') == NULL)
- {
- CompilationDomain::FindImage(wzPath,
- fExplicitBindToNativeImage ? MDInternalImport_NoCache : MDInternalImport_Default, &pImage);
- }
-#endif
if (pImage == NULL)
{
@@ -477,16 +424,6 @@ HRESULT CEECompileInfo::LoadAssemblyByPath(
}
else
{
-#ifdef FEATURE_FUSION
- SafeComHolder<IBindResult> pNativeFusionAssembly;
- SafeComHolder<IFusionBindLog> pFusionLog;
- SafeComHolder<IAssembly> pFusionAssembly;
-
- IfFailThrow(ExplicitBind(wzPath, pDomain->GetFusionContext(), EXPLICITBIND_FLAGS_EXE,
- NULL, &pFusionAssembly, &pNativeFusionAssembly, &pFusionLog));
-
- pAssemblyHolder = PEAssembly::Open(pFusionAssembly, pNativeFusionAssembly, pFusionLog, FALSE, FALSE);
-#else //FEATURE_FUSION
//ExplicitBind
CoreBindResult bindResult;
spec.SetCodeBase(pImage->GetPath());
@@ -510,21 +447,14 @@ HRESULT CEECompileInfo::LoadAssemblyByPath(
fExplicitBindToNativeImage
);
pAssemblyHolder = PEAssembly::Open(&bindResult,FALSE,FALSE);
-#endif //FEATURE_FUSION
}
// Now load assembly into domain.
DomainAssembly * pDomainAssembly = pDomain->LoadDomainAssembly(&spec, pAssemblyHolder, FILE_LOAD_BEGIN);
-#ifndef FEATURE_APPX_BINDER
if (spec.CanUseWithBindingCache() && pDomainAssembly->CanUseWithBindingCache())
pDomain->AddAssemblyToCache(&spec, pDomainAssembly);
-#endif
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- if (!IsReadyToRunCompilation())
- pDomain->ToCompilationDomain()->ComputeAssemblyHardBindList(pAssemblyHolder->GetPersistentMDImport());
-#endif
{
// Mark the assembly before it gets fully loaded and NGen image dependencies are verified. This is necessary
@@ -556,156 +486,6 @@ HRESULT CEECompileInfo::LoadAssemblyByPath(
return hr;
}
-#ifdef FEATURE_FUSION
-
-// Simple helper that factors out code common to LoadAssemblyByIAssemblyName and
-// LoadAssemblyByName
-static HRESULT LoadAssemblyByIAssemblyNameWorker(
- IAssemblyName *pAssemblyName,
- CORINFO_ASSEMBLY_HANDLE *pHandle)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- SO_INTOLERANT;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- Assembly *pAssembly;
-
- AssemblySpec spec;
- spec.InitializeSpec(pAssemblyName, NULL, FALSE);
-
- if (spec.IsMscorlib())
- {
- pAssembly = SystemDomain::System()->SystemAssembly();
- }
- else
- {
-
- DomainAssembly * pDomainAssembly = spec.LoadDomainAssembly(FILE_LOAD_BEGIN);
-
- // Mark the assembly before it gets fully loaded and NGen image dependencies are verified. This is necessary
- // to allow skipping compilation if there is NGen image already.
- pDomainAssembly->GetFile()->SetSafeToHardBindTo();
-
- pAssembly = spec.LoadAssembly(FILE_LOADED);
- }
-
- //
- // Return the module handle
- //
-
- *pHandle = CORINFO_ASSEMBLY_HANDLE(pAssembly);
-
- return S_OK;
-}
-
-HRESULT CEECompileInfo::LoadAssemblyByName(
- LPCWSTR wzName,
- CORINFO_ASSEMBLY_HANDLE *pHandle)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
-
- COOPERATIVE_TRANSITION_BEGIN();
-
- EX_TRY
- {
- ReleaseHolder<IAssemblyName> pAssemblyName;
- IfFailThrow(CreateAssemblyNameObject(&pAssemblyName, wzName, CANOF_PARSE_DISPLAY_NAME, NULL));
- IfFailThrow(LoadAssemblyByIAssemblyNameWorker(pAssemblyName, pHandle));
- }
- EX_CATCH_HRESULT(hr);
-
- COOPERATIVE_TRANSITION_END();
-
- return hr;
-}
-
-HRESULT CEECompileInfo::LoadAssemblyRef(
- IMDInternalImport *pAssemblyImport,
- mdAssemblyRef ref,
- CORINFO_ASSEMBLY_HANDLE *pHandle,
- IAssemblyName **refAssemblyName /*=NULL*/)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
-
- ReleaseHolder<IAssemblyName> pAssemblyName;
-
- COOPERATIVE_TRANSITION_BEGIN();
-
- EX_TRY
- {
- Assembly *pAssembly;
-
- if (refAssemblyName)
- *refAssemblyName = NULL;
-
- AssemblySpec spec;
- spec.InitializeSpec(ref, pAssemblyImport, NULL, FALSE);
-
- if (spec.HasBindableIdentity())
- {
- if (refAssemblyName)
- {
- IfFailThrow(spec.CreateFusionName(&pAssemblyName));
- }
-
- pAssembly = spec.LoadAssembly(FILE_LOADED);
-
- //
- // Return the module handle
- //
-
- *pHandle = CORINFO_ASSEMBLY_HANDLE(pAssembly);
- }
- else
- { // Cannot load assembly refs with non-unique id.
- hr = S_FALSE;
- }
- }
- EX_CATCH_HRESULT(hr);
-
- COOPERATIVE_TRANSITION_END();
-
- if (refAssemblyName != NULL && pAssemblyName != NULL)
- {
- *refAssemblyName = pAssemblyName.Extract();
- }
-
- return hr;
-}
-
-HRESULT CEECompileInfo::LoadAssemblyByIAssemblyName(
- IAssemblyName *pAssemblyName,
- CORINFO_ASSEMBLY_HANDLE *pHandle
- )
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
-
- COOPERATIVE_TRANSITION_BEGIN();
-
- EX_TRY
- {
- IfFailThrow(LoadAssemblyByIAssemblyNameWorker(pAssemblyName, pHandle));
- }
- EX_CATCH_HRESULT(hr);
-
- COOPERATIVE_TRANSITION_END();
-
- return hr;
-}
-
-#endif //FEATURE_FUSION
#ifdef FEATURE_COMINTEROP
HRESULT CEECompileInfo::LoadTypeRefWinRT(
@@ -802,66 +582,6 @@ HRESULT CEECompileInfo::LoadAssemblyModule(
return S_OK;
}
-#ifndef FEATURE_CORECLR
-BOOL CEECompileInfo::SupportsAutoNGen(CORINFO_ASSEMBLY_HANDLE assembly)
-{
- STANDARD_VM_CONTRACT;
-
- Assembly *pAssembly = (Assembly*) assembly;
- return pAssembly->SupportsAutoNGen();
-}
-
-HRESULT CEECompileInfo::SetCachedSigningLevel(HANDLE hNI, HANDLE *pModules, COUNT_T nModules)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
-
- HMODULE hKernel32 = WszLoadLibrary(W("kernel32.dll"));
- typedef BOOL (WINAPI *SetCachedSigningLevel_t)
- (__in_ecount(Count) PHANDLE SourceFiles, __in ULONG Count, __in ULONG Flags, __in HANDLE TargetFile);
- SetCachedSigningLevel_t SetCachedSigningLevel
- = (SetCachedSigningLevel_t)GetProcAddress(hKernel32, "SetCachedSigningLevel");
- if (SetCachedSigningLevel == NULL)
- {
- return S_OK;
- }
-
- StackSArray<PEImage*> images;
- PEImage::GetAll(images);
-
- StackSArray<HANDLE> handles;
- for (StackSArray<PEImage*>::Iterator i = images.Begin(), end = images.End(); i != end; i++)
- {
- if (!(*i)->IsFile())
- {
- continue;
- }
- HANDLE hFile = (*i)->GetFileHandleLocking();
- handles.Append(hFile);
- }
-
- if (!SetCachedSigningLevel(handles.GetElements(), handles.GetCount(), 0, hNI))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FAILED(hr));
- goto ErrExit;
- }
-
- for (COUNT_T i = 0; i < nModules; i++)
- {
- if (!SetCachedSigningLevel(handles.GetElements(), handles.GetCount(), 0, pModules[i]))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FAILED(hr));
- goto ErrExit;
- }
- }
-
-ErrExit:
- return hr;
-}
-#endif
BOOL CEECompileInfo::CheckAssemblyZap(
CORINFO_ASSEMBLY_HANDLE assembly,
@@ -1045,42 +765,6 @@ CORINFO_ASSEMBLY_HANDLE
return (CORINFO_ASSEMBLY_HANDLE) GetModule(module)->GetAssembly();
}
-#ifdef FEATURE_FUSION
-HRESULT CEECompileInfo::GetAssemblyName(
- CORINFO_ASSEMBLY_HANDLE hAssembly,
- DWORD dwFlags,
- __out_z LPWSTR wzAssemblyName,
- LPDWORD pcchAssemblyName)
-{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE(hAssembly != NULL);
- if (hAssembly == NULL)
- {
- return E_INVALIDARG;
- }
-
- HRESULT hr = S_OK;
- EX_TRY
- {
- Assembly *pAssembly = (Assembly *) hAssembly;
- IAssemblyName * pAssemblyName = pAssembly->GetFusionAssemblyName();
- if (dwFlags == GANF_Default)
- {
- hr = pAssemblyName->GetDisplayName(wzAssemblyName, pcchAssemblyName, 0);
- }
- else if (dwFlags == GANF_Simple)
- {
- DWORD cbAssemblyName = *pcchAssemblyName * sizeof(WCHAR);
- hr = pAssemblyName->GetProperty(ASM_NAME_NAME, (LPVOID)wzAssemblyName, &cbAssemblyName);
- *pcchAssemblyName = cbAssemblyName / sizeof(WCHAR);
- }
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-#endif //FEATURE_FUSION
#ifdef CROSSGEN_COMPILE
//
@@ -2910,11 +2594,7 @@ public:
LIMITED_METHOD_CONTRACT;
}
-#ifdef FEATURE_CORECLR
#define WRITER_LOAD_ERROR_MESSAGE W("Unable to load ") NATIVE_SYMBOL_READER_DLL W(". Please ensure that ") NATIVE_SYMBOL_READER_DLL W(" is on the path. Error='%d'\n")
-#else
-#define WRITER_LOAD_ERROR_MESSAGE W("Unable to load diasymreader.dll. Please ensure that version 11 or greater of diasymreader.dll is on the path. You can typically find this DLL in the desktop .NET install directory for 4.5 or greater. Error='%d'\n")
-#endif
HRESULT Load(LPCWSTR wszDiasymreaderPath = nullptr)
{
@@ -2942,11 +2622,7 @@ public:
{
hr = FakeCoCreateInstanceEx(
CLSID_CorSymBinder_SxS,
-#ifdef FEATURE_CORECLR
wszDiasymreaderPath != nullptr ? wszDiasymreaderPath : (LPCWSTR)NATIVE_SYMBOL_READER_DLL,
-#else
- wszDiasymreaderPath,
-#endif
IID_ISymUnmanagedBinder,
(void**)&m_pBinder,
NULL);
@@ -4952,9 +4628,6 @@ void CEECompileInfo::SetAssemblyHardBindList(
{
STANDARD_VM_CONTRACT;
-#ifndef FEATURE_CORECLR // hardbinding
- GetAppDomain()->ToCompilationDomain()->SetAssemblyHardBindList(pHardBindList, cHardBindList);
-#endif
}
HRESULT CEECompileInfo::SetVerboseLevel(
@@ -6603,9 +6276,6 @@ void CEEPreloader::PrePrepareMethodIfNecessary(CORINFO_METHOD_HANDLE hMethod)
{
STANDARD_VM_CONTRACT;
-#ifdef FEATURE_CER
- ::PrePrepareMethodIfNecessary(hMethod);
-#endif
}
static void SetStubMethodDescOnInteropMethodDesc(MethodDesc* pInteropMD, MethodDesc* pStubMD, bool fReverseStub)
@@ -7172,6 +6842,12 @@ ULONG CEEPreloader::Release()
return 0;
}
+void CEEPreloader::GetSerializedInlineTrackingMap(SBuffer* pBuffer)
+{
+ InlineTrackingMap * pInlineTrackingMap = m_image->GetInlineTrackingMap();
+ PersistentInlineTrackingMapR2R::Save(m_image->GetHeap(), pBuffer, pInlineTrackingMap);
+}
+
void CEEPreloader::Error(mdToken token, Exception * pException)
{
STANDARD_VM_CONTRACT;
@@ -7254,11 +6930,6 @@ CompilationDomain::CompilationDomain(BOOL fForceDebug,
{
STANDARD_VM_CONTRACT;
-#ifndef FEATURE_CORECLR // hardbinding
- m_hardBoundModules.Init(FALSE, NULL);
- m_cantHardBindModules.Init(FALSE, NULL);
- m_useHardBindList = FALSE;
-#endif
}
void CompilationDomain::ReleaseDependencyEmitter()
@@ -7307,11 +6978,6 @@ void CompilationDomain::Init()
Security::SetDefaultAppDomainProperty(GetSecurityDescriptor());
SetCompilationDomain();
-#ifndef FEATURE_CORECLR
- // We need the Compilation Domain to be homogeneous. We've already forced everything to be full trust.
- // However, CheckZapSecurity needs this to be set, so set it here.
- GetSecurityDescriptor()->SetHomogeneousFlag(TRUE);
-#endif // !FEATURE_CORECLR
#ifdef _DEBUG
g_pConfig->DisableGenerateStubForHost();
@@ -7374,9 +7040,6 @@ HRESULT CompilationDomain::AddDependencyEntry(PEAssembly *pFile,
pDependency->dwAssemblyDef = def;
pDependency->signNativeImage = INVALID_NGEN_SIGNATURE;
-#ifdef FEATURE_APTCA
- pDependency->dependencyInfo = CorCompileDependencyInfo(0);
-#endif //FEATURE_APTCA
if (pFile)
{
@@ -7384,49 +7047,8 @@ HRESULT CompilationDomain::AddDependencyEntry(PEAssembly *pFile,
// Note that this can trigger an assembly load (of mscorlib)
pAssembly->GetOptimizedIdentitySignature(&pDependency->signAssemblyDef);
-#if defined(FEATURE_APTCA) || !defined(FEATURE_CORECLR)
- ReleaseHolder<IMDInternalImport> pAssemblyMD(pFile->GetMDImportWithRef());
-#endif
-
-#ifdef FEATURE_APTCA
- // determine if there's an APTCA reference, before we retrieve the target file version (for killbit)
- TokenSecurityDescriptorFlags assemblySecurityAttributes =
- TokenSecurityDescriptor::ReadSecurityAttributes(pAssemblyMD, TokenFromRid(1, mdtAssembly));
-
- pFile->AddRef();
- BOOL fIsAptca = assemblySecurityAttributes & (TokenSecurityDescriptorFlags_APTCA
- | TokenSecurityDescriptorFlags_ConditionalAPTCA);
- if (fIsAptca)
- {
- // get the file path
- LPCWSTR pwszPath = pFile->GetPath().GetUnicode();
- if (pwszPath == NULL)
- {
- return E_FAIL;
- }
- // retrieve the file version based on the file path (using Watson OS wrapper)
- if (FAILED(GetFileVersion(pwszPath, &pDependency->uliFileVersion)))
- // ignore failures (e.g. platform doesn't support file version, or version info missing
- {
- fIsAptca = FALSE;
- }
- }
- if (fIsAptca)
- {
- pDependency->dependencyInfo = CorCompileDependencyInfo(pDependency->dependencyInfo
- | CORCOMPILE_DEPENDENCY_IS_APTCA);
- }
-
- if (assemblySecurityAttributes & TokenSecurityDescriptorFlags_ConditionalAPTCA)
- {
- pDependency->dependencyInfo = CorCompileDependencyInfo(pDependency->dependencyInfo
- | CORCOMPILE_DEPENDENCY_IS_CAPTCA);
- }
-#endif //FEATURE_APTCA
-
-#ifdef FEATURE_CORECLR // hardbinding
//
// This is done in CompilationDomain::CanEagerBindToZapFile with full support for hardbinding
//
@@ -7435,59 +7057,7 @@ HRESULT CompilationDomain::AddDependencyEntry(PEAssembly *pFile,
CORCOMPILE_VERSION_INFO * pNativeVersion = pFile->GetLoadedNative()->GetNativeVersionInfo();
pDependency->signNativeImage = pNativeVersion->signature;
}
-#endif
-
-#ifndef FEATURE_CORECLR
- // Find the architecture of the dependency, using algorithm from Fusion GetRuntimeVersionForAssembly.
- // Normally, when an assembly is loaded at runtime, Fusion determines its architecture based on the
- // metadata. However, if assembly load is skipped due to presence of native image, then Fusion needs
- // to get assembly architecture from another source. For assemblies in GAC, the GAC structure provides
- // architecture data. For assemblies outside of GAC, however, no other source of info is available.
- // So we calculate the architecture now and store it in the native image, to make it available to Fusion.
- // The algorithm here must exactly match the algorithm in GetRuntimeVersionForAssembly.
- LPCSTR pszPERuntime;
- IfFailThrow(pAssemblyMD->GetVersionString(&pszPERuntime));
-
- if (SString::_strnicmp(pszPERuntime, "v1.0", 4) != 0 &&
- SString::_strnicmp(pszPERuntime, "v1.1", 4) != 0 &&
- SString::_stricmp(pszPERuntime, "Standard CLI 2002") != 0)
- {
- // Get the PE architecture of this dependency, similar to PEAssembly::GetFusionProcessorArchitecture.
- // The difference is when NI is loaded, PEAssembly::GetFusionProcessorArchitecture returns the
- // architecture of the NI (which is never processor neutral), but we want the architecture
- // associated with the IL image.
- DWORD dwPEKind, dwMachine;
- if (pFile->HasNativeImage())
- {
- // CrossGen can load an NI without loading the corresponding IL image, in which case
- // PEAssembly::GetILImage() actually returns an NI. Thus we need specific code to handle NI.
- PEImageHolder pImage(pFile->GetNativeImageWithRef());
- pImage->GetNativeILPEKindAndMachine(&dwPEKind, &dwMachine);
- }
- else
- {
- pFile->GetILimage()->GetPEKindAndMachine(&dwPEKind, &dwMachine);
- }
- DWORD dwAssemblyFlags = 0;
- IfFailThrow(pAssemblyMD->GetAssemblyProps(TokenFromRid(1, mdtAssembly),
- NULL, NULL, NULL,
- NULL, NULL, &dwAssemblyFlags));
-
- PEKIND peKind;
- if (SUCCEEDED(TranslatePEToArchitectureType(
- (CorPEKind)dwPEKind,
- dwMachine,
- dwAssemblyFlags,
- &peKind)))
- {
- CorCompileDependencyInfo peKindShifted = CorCompileDependencyInfo(peKind << CORCOMPILE_DEPENDENCY_PEKIND_SHIFT);
- _ASSERTE(peKindShifted == (peKindShifted & CORCOMPILE_DEPENDENCY_PEKIND_MASK));
- pDependency->dependencyInfo = CorCompileDependencyInfo(pDependency->dependencyInfo
- | (peKindShifted & CORCOMPILE_DEPENDENCY_PEKIND_MASK));
- }
- }
-#endif //FEATURE_FUSION
}
return S_OK;
@@ -7659,68 +7229,6 @@ AssemblySpec* CompilationDomain::FindAssemblyRefSpecForDefSpec(
return (pEntry != NULL) ? pEntry->m_pRef : NULL;
}
-#ifndef FEATURE_CORECLR // hardbinding
-//----------------------------------------------------------------------------
-// Was the assembly asked to be hard-bound to?
-
-BOOL CompilationDomain::IsInHardBindRequestList(Assembly * pAssembly)
-{
- return IsInHardBindRequestList(pAssembly->GetManifestFile());
-}
-
-BOOL CompilationDomain::IsInHardBindRequestList(PEAssembly * pAssembly)
-{
- if (!m_useHardBindList)
- return FALSE;
-
- StackSString displayName;
- pAssembly->GetDisplayName(displayName);
-
- for (COUNT_T i = 0; i < m_assemblyHardBindList.GetCount(); i++)
- {
- if (displayName.Equals(m_assemblyHardBindList[i]))
- return TRUE;
- }
-
- return FALSE;
-}
-
-BOOL CompilationDomain::IsSafeToHardBindTo(PEAssembly * pAssembly)
-{
- WRAPPER_NO_CONTRACT;
- // The dependency worker does not have m_useHardBindList set.
- // We do want to allow all possible native images to be loaded in this case.
- if (!m_useHardBindList)
- return TRUE;
-
- if (CompilationDomain::IsInHardBindRequestList(pAssembly))
- return TRUE;
-
- return FALSE;
-}
-
-PtrHashMap::PtrIterator CompilationDomain::IterateHardBoundModules()
-{
- WRAPPER_NO_CONTRACT;
- return m_hardBoundModules.begin();
-}
-
-void CompilationDomain::SetAssemblyHardBindList(
- __in_ecount( cHardBindList )
- LPWSTR *pHardBindList,
- DWORD cHardBindList)
-{
- m_assemblyHardBindList.SetCount(0);
-
- for (DWORD i = 0; i < cHardBindList; i++)
- {
- SString s(pHardBindList[i]);
- m_assemblyHardBindList.Append(s);
- }
-
- m_useHardBindList = TRUE;
-}
-#endif // FEATURE_CORECLR
//----------------------------------------------------------------------------
// Is it OK to embed direct pointers to an ngen dependency?
@@ -7743,261 +7251,13 @@ BOOL CompilationDomain::CanEagerBindToZapFile(Module *targetModule, BOOL limitTo
return TRUE;
}
-#ifdef FEATURE_CORECLR // hardbinding
//
// CoreCLR does not have attributes for fine grained eager binding control.
// We hard bind to mscorlib.dll only.
//
return targetModule->IsSystem();
-#else
- // Now, look up the hashtables to avoid doing the heavy-duty work everytime
-
- if (m_cantHardBindModules.LookupValue((UPTR)targetModule, targetModule) !=
- LPVOID(INVALIDENTRY))
- {
- return FALSE;
- }
-
- if (m_hardBoundModules.LookupValue((UPTR)targetModule, targetModule) !=
- LPVOID(INVALIDENTRY))
- {
- return TRUE;
- }
-
- const char * logMsg = NULL;
-
- EEConfig::NgenHardBindType ngenHardBindConfig = g_pConfig->NgenHardBind();
-
- if (ngenHardBindConfig == EEConfig::NGEN_HARD_BIND_NONE)
- {
- logMsg = "COMPlus_HardPrejitEnabled=0 is specified";
- goto CANNOT_HARD_BIND;
- }
-
- if (ngenHardBindConfig == EEConfig::NGEN_HARD_BIND_ALL)
- {
- // COMPlus_HardPrejitEnabled=2 is specified
- limitToHardBindList = FALSE;
- }
-
- if (!targetModule->HasNativeImage())
- {
- logMsg = "dependency does not have a native image (check FusLogVw for reason)";
- goto CANNOT_HARD_BIND;
- }
-
- // The loader/Fusion cannot currently guarantee that a non-manifest module of a
- // hardbound dependency gets eagerly loaded.
- if (!targetModule->GetFile()->IsAssembly())
- {
- logMsg = "dependency is a non-manifest module";
- goto CANNOT_HARD_BIND;
- }
-
- // Don't hard bind to modules not on the list
- if (limitToHardBindList && m_useHardBindList)
- {
- if (!IsInHardBindRequestList(targetModule->GetAssembly()))
- {
- logMsg = "dependency was not found in m_assemblyHardBindList";
- goto CANNOT_HARD_BIND;
- }
- }
-
- // Mark targetModule as a hard dependency
- //
- m_hardBoundModules.InsertValue((UPTR)targetModule, targetModule);
-
- // Update m_pDependencies for the corresponding assembly, to reflect the fact
- // that we are hard-binding to its native image
- //
- PEAssembly * pTargetAssembly;
- pTargetAssembly = targetModule->GetFile()->GetAssembly();
- UpdateDependencyEntryForHardBind(pTargetAssembly);
-
- logMsg = "new dependency";
-
- // Try to hardbind to the hardbound dependency closure as there is
- // no extra cost in doing so
- IncludeHardBindClosure(pTargetAssembly);
-
- LOG((LF_ZAP, LL_INFO100, "Success CanEagerBindToZapFile: %S (%s)\n",
- targetModule->GetDebugName(), logMsg));
-
- return TRUE;
-
-CANNOT_HARD_BIND:
-
- m_cantHardBindModules.InsertValue((UPTR)targetModule, targetModule);
-
- // If we have a hard binding list, check if this module is on the list.
- if (targetModule->GetFile()->IsAssembly() &&
- IsInHardBindRequestList(targetModule->GetAssembly()))
- {
- StackSString displayName;
- targetModule->GetAssembly()->GetDisplayName(displayName);
-
- GetSvcLogger()->Printf(LogLevel_Warning, W("WARNING: Cannot hardbind to %s because %S\n"),
- displayName.GetUnicode(), logMsg);
- }
-
- if (logMsg)
- {
- LOG((LF_ZAP, LL_INFO100, "Failure CanEagerBindToZapFile: %S (%s)\n",
- targetModule->GetDebugName(), logMsg));
- }
-
- return FALSE;
-#endif // FEATURE_CORECLR
-}
-
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
-
-SArray<LPCWSTR> * s_pPlatformAssembliesPaths;
-
-void ZapperSetPlatformAssembliesPaths(SString &platformAssembliesPaths)
-{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE(s_pPlatformAssembliesPaths == NULL);
- s_pPlatformAssembliesPaths = new SArray<LPCWSTR>();
-
- SString strPaths(platformAssembliesPaths);
- if (strPaths.IsEmpty())
- return;
-
- for (SString::Iterator i = strPaths.Begin(); i != strPaths.End(); )
- {
- // Skip any leading spaces or semicolons
- if (strPaths.Skip(i, W(';')))
- {
- continue;
- }
-
- SString::Iterator iEnd = i; // Where current assembly name ends
- SString::Iterator iNext; // Where next assembly name starts
- if (strPaths.Find(iEnd, W(';')))
- {
- iNext = iEnd + 1;
- }
- else
- {
- iNext = iEnd = strPaths.End();
- }
-
- _ASSERTE(i < iEnd);
- if(i != iEnd)
- {
- SString strPath(strPaths, i, iEnd);
-
- SString strFullPath;
- Clr::Util::Win32::GetFullPathName(strPath, strFullPath, NULL);
-
- NewArrayHolder<WCHAR> wszFullPath = DuplicateStringThrowing(strFullPath.GetUnicode());
- s_pPlatformAssembliesPaths->Append(wszFullPath);
- wszFullPath.SuppressRelease();
- }
- i = iNext;
- }
}
-BOOL CompilationDomain::FindImage(const SString& fileName, MDInternalImportFlags flags, PEImage ** ppImage)
-{
- if (s_pPlatformAssembliesPaths == NULL)
- return FALSE;
-
- for (COUNT_T i = 0; i < s_pPlatformAssembliesPaths->GetCount(); i++)
- {
- SString sPath((*s_pPlatformAssembliesPaths)[i]);
- if (sPath[sPath.GetCount() - 1] != '\\')
- sPath.Append(W("\\"));
- sPath.Append(fileName);
-
- if (!FileExists(sPath))
- continue;
-
- // Normalize the path to maintain identity
- SString sFullPath;
- Clr::Util::Win32::GetFullPathName(sPath, sFullPath, NULL);
-
- PEImageHolder image(PEImage::OpenImage(sFullPath, flags));
-
- PEImageLayoutHolder pLayout(image->GetLayout(
- (flags == MDInternalImport_NoCache) ? PEImageLayout::LAYOUT_FLAT : PEImageLayout::LAYOUT_MAPPED,
- PEImage::LAYOUT_CREATEIFNEEDED));
-
- if (!pLayout->HasNTHeaders())
- continue;
-
- if (!pLayout->IsNativeMachineFormat())
- {
- // Check for platform agnostic IL
- if (!pLayout->IsPlatformNeutral())
- continue;
- }
-
- *ppImage = image.Extract();
- return TRUE;
- }
-
- return FALSE;
-}
-
-BOOL CompilationDomain::IsInHardBindList(SString& simpleName)
-{
- for (COUNT_T i = 0; i < m_assemblyHardBindList.GetCount(); i++)
- {
- if (simpleName.Equals(m_assemblyHardBindList[i]))
- return TRUE;
- }
-
- return FALSE;
-}
-
-void CompilationDomain::ComputeAssemblyHardBindList(IMDInternalImport * pImport)
-{
- AssemblyForLoadHint assembly(pImport);
-
- HENUMInternalHolder hEnum(pImport);
- hEnum.EnumAllInit(mdtAssemblyRef);
-
- mdAssembly token;
- while (pImport->EnumNext(&hEnum, &token))
- {
- LPCSTR pszName;
- IfFailThrow(pImport->GetAssemblyRefProps(token, NULL, NULL,
- &pszName, NULL,
- NULL, NULL, NULL));
-
- SString sSimpleName(SString::Utf8, pszName);
-
- SString sFileName(sSimpleName, W(".dll"));
-
- PEImageHolder pDependencyImage;
-
- if (!FindImage(sFileName, MDInternalImport_Default, &pDependencyImage))
- continue;
-
- AssemblyForLoadHint assemblyDependency(pDependencyImage->GetMDImport());
-
- LoadHintEnum loadHint;
- ::GetLoadHint(&assembly, &assemblyDependency, &loadHint);
-
- if (loadHint == LoadAlways)
- {
- GetSvcLogger()->Printf(W("Hardbinding to %s\n"), sSimpleName.GetUnicode());
-
- if (!IsInHardBindList(sSimpleName))
- {
- m_assemblyHardBindList.Append(sSimpleName);
- }
- }
- }
-
- // Note that we are not setting m_useHardBindList to TRUE here. When we load the NGen image, we are good to hardbind.
- // m_useHardBindList = TRUE;
-}
-#endif
void CompilationDomain::SetTarget(Assembly *pAssembly, Module *pModule)
{
@@ -8017,7 +7277,6 @@ void CompilationDomain::SetTargetImage(DataImage *pImage, CEEPreloader * pPreloa
_ASSERTE(pImage->GetModule() == GetTargetModule());
}
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
void ReportMissingDependency(Exception * e)
{
// Avoid duplicate error messages
@@ -8031,7 +7290,6 @@ void ReportMissingDependency(Exception * e)
g_hrFatalError = COR_E_FILELOAD;
}
-#endif
PEAssembly *CompilationDomain::BindAssemblySpec(
AssemblySpec *pSpec,
@@ -8062,13 +7320,11 @@ PEAssembly *CompilationDomain::BindAssemblySpec(
}
EX_HOOK
{
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
if (!g_fNGenMissingDependenciesOk)
{
ReportMissingDependency(GET_EXCEPTION());
EX_RETHROW;
}
-#endif
//
// Record missing dependencies
@@ -8101,56 +7357,6 @@ HRESULT
COOPERATIVE_TRANSITION_BEGIN();
-#ifdef FEATURE_FUSION
- if (isExe)
- {
- if (NingenEnabled())
- {
- WCHAR buf[MAX_LONGPATH + sizeof(CONFIGURATION_EXTENSION)/sizeof(WCHAR) + 1];
- if (0 != wcscpy_s(buf, sizeof(buf)/sizeof(*buf), path))
- {
- COMPlusThrowHR(COR_E_PATHTOOLONG);
- }
- WCHAR *pSlash = wcsrchr(buf, W('\\'));
- if (!pSlash)
- {
- COMPlusThrowHR(COR_E_BAD_PATHNAME);
- }
-
- *(pSlash + 1) = W('\0');
- hr = m_pFusionContext->Set(ACTAG_APP_BASE_URL, buf, (DWORD)((wcslen(buf) + 1) * sizeof(WCHAR)), 0);
- if (FAILED(hr))
- {
- COMPlusThrowHR(hr);
- }
-
- if (0 != wcscpy_s(buf, sizeof(buf)/sizeof(*buf), path + (pSlash - buf) + 1))
- {
- COMPlusThrowHR(COR_E_PATHTOOLONG);
- }
-
- if (0 != wcscat_s(buf, sizeof(buf)/sizeof(*buf), CONFIGURATION_EXTENSION))
- {
- COMPlusThrowHR(COR_E_PATHTOOLONG);
- }
- hr = m_pFusionContext->Set(ACTAG_APP_CONFIG_FILE, buf, (DWORD)((wcslen(buf) + 1) * sizeof(WCHAR)), 0);
- if (FAILED(hr))
- {
- COMPlusThrowHR(hr);
- }
- }
- else
- {
- SetupExecutableFusionContext(path);
- }
- }
- else
- {
- hr = m_pFusionContext->Set(ACTAG_APP_BASE_URL,
- (void*) path, (DWORD) ((wcslen(path)+1) * sizeof(WCHAR)),
- 0);
- }
-#endif //FEATURE_FUSION
COOPERATIVE_TRANSITION_END();
@@ -8167,199 +7373,6 @@ void CompilationDomain::SetDependencyEmitter(IMetaDataAssemblyEmit *pEmit)
m_pDependencyRefSpecs = new AssemblySpecHash();
}
-#ifndef FEATURE_CORECLR // hardbinding
-/* Update m_pDependencies for the corresponding assembly, to reflect the fact
- that we are hard-binding to its native image
- */
-
-void CompilationDomain::UpdateDependencyEntryForHardBind(PEAssembly * pDependencyAssembly)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(pDependencyAssembly->HasBindableIdentity()); // Currently no hard deps on WinMD files.
- }
- CONTRACTL_END;
- AssemblySpec assemblySpec;
- assemblySpec.InitializeSpec(pDependencyAssembly);
-
- mdAssemblyRef defToken;
- IfFailThrow(assemblySpec.EmitToken(m_pEmit, &defToken));
-
- CORCOMPILE_DEPENDENCY * pDep = m_pDependencies;
-
- for (unsigned i = 0; i < m_cDependenciesCount; i++, pDep++)
- {
- if (pDep->dwAssemblyDef == defToken)
- {
- PEImage * pNativeImage = pDependencyAssembly->GetPersistentNativeImage();
- CORCOMPILE_VERSION_INFO * pNativeVersion = pNativeImage->GetLoadedLayout()->GetNativeVersionInfo();
- _ASSERTE(pDep->signNativeImage == INVALID_NGEN_SIGNATURE ||
- pDep->signNativeImage == pNativeVersion->signature);
- pDep->signNativeImage = pNativeVersion->signature;
- return;
- }
- }
-
- // We should have found and updated the corresponding dependency
- _ASSERTE(!"This should be unreachable");
-}
-
-// pAssembly is a hardbound ngen dependency of m_pTargetModule.
-// Try to hardbind to the hardbound dependency closure as there is
-// no extra cost in doing so, and it will help generate better code
-//
-
-void CompilationDomain::IncludeHardBindClosure(PEAssembly * pAssembly)
-{
- CONTRACTL {
- PRECONDITION(pAssembly->GetPersistentNativeImage() != NULL);
- } CONTRACTL_END;
-
- PEImageLayout *pNativeImage = pAssembly->GetLoadedNative();
- COUNT_T cDependencies;
- CORCOMPILE_DEPENDENCY *pDependencies = pNativeImage->GetNativeDependencies(&cDependencies);
- CORCOMPILE_DEPENDENCY *pDependenciesEnd = pDependencies + cDependencies;
-
- for (/**/; pDependencies < pDependenciesEnd; pDependencies++)
- {
- // Ignore "soft" dependencies
-
- if (pDependencies->signNativeImage == INVALID_NGEN_SIGNATURE)
- continue;
-
- // Load the manifest file for the given hardbound name-assembly-spec.
-
- AssemblySpec name;
- name.InitializeSpec(pDependencies->dwAssemblyRef,
- pAssembly->GetPersistentNativeImage()->GetNativeMDImport(),
- FindAssembly(pAssembly),
- FALSE);
-
- DomainAssembly * pDependency = name.LoadDomainAssembly(FILE_LOADED);
-
- // Since pAssembly hardbinds to pDependency, pDependency better
- // have a native image
- _ASSERTE(pDependency->GetFile()->HasNativeImage());
-
- //
- // Now add pDependency as a hard dependency of m_pTargetModule.
- // We pass in limitToHardBindList=FALSE as it is OK to hardbind even if
- // pDependency is not in the hardbound list.
- //
-
- CanEagerBindToZapFile(pDependency->GetLoadedModule(), FALSE);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Check if we were successfully able to hardbind to the requested dependency
-
-void CompilationDomain::CheckHardBindToZapFile(SString dependencyNameFromCA)
-{
- // First check if we were successfully able to hard-bind
-
- for (PtrHashMap::PtrIterator hbItr = m_hardBoundModules.begin(); !hbItr.end(); ++hbItr)
- {
- Module * pModule = (Module*) hbItr.GetValue();
-
- if (IsAssemblySpecifiedInCA(pModule->GetAssembly(), dependencyNameFromCA))
- {
- // We did successfully use "dependencyNameFromCA"
- return;
- }
- }
-
- // Next, check if we failed to hard-bind. CompilationDomain::CanEagerBindToZapFile()
- // would have logged a warning message with the cause of the soft-bind
-
- for (PtrHashMap::PtrIterator sbItr = m_cantHardBindModules.begin(); !sbItr.end(); ++sbItr)
- {
- Module * pModule = (Module*) sbItr.GetValue();
-
- if (IsAssemblySpecifiedInCA(pModule->GetAssembly(), dependencyNameFromCA))
- {
- if (!IsInHardBindRequestList(pModule->GetAssembly()))
- {
- // CompilationDomain::CanEagerBindToZapFile() does not give a warning
- // message for the cyclic dependency case, since the NGEN service
- // breaks the cycle by overriding the CA. So give a message here instead.
- GetSvcLogger()->Printf(LogLevel_Warning, W("WARNING: Dependency attribute for %s is being ignored, possibly because of cyclic dependencies.\n"),
- dependencyNameFromCA.GetUnicode());
- }
- return;
- }
- }
-
- // Finally, it looks like the assembly was either not loaded, or that
- // there was no reason to even try to hard-bind.
-
- GetSvcLogger()->Printf(LogLevel_Warning, W("WARNING: Cannot hardbind to %s because it is not loaded\n"),
- dependencyNameFromCA.GetUnicode());
-}
-
-//-----------------------------------------------------------------------------
-// Check if we were successfully able to hardbind to all the requested
-// dependencies.
-
-void CompilationDomain::CheckLoadHints()
-{
- if (!m_useHardBindList)
- return;
-
- if (g_pConfig->NgenHardBind() == EEConfig::NGEN_HARD_BIND_NONE)
- return;
-
- // Look for the binding custom attribute
-
- IMDInternalImport * pImport = m_pTargetAssembly->GetManifestImport();
- _ASSERTE(pImport);
-
- MDEnumHolder hEnum(pImport); // Enumerator for custom attributes
- if (FAILED(pImport->EnumCustomAttributeByNameInit(m_pTargetAssembly->GetManifestToken(),
- DEPENDENCY_TYPE,
- &hEnum)))
- {
- return;
- }
-
- mdCustomAttribute tkAttribute; // A custom attribute on this assembly.
- const BYTE *pbAttr; // Custom attribute data as a BYTE*.
- ULONG cbAttr; // Size of custom attribute data.
-
- while (pImport->EnumNext(&hEnum, &tkAttribute))
- { // Get raw custom attribute.
- IfFailThrow(pImport->GetCustomAttributeAsBlob(tkAttribute, (const void**)&pbAttr, &cbAttr));
-
- CustomAttributeParser cap(pbAttr, cbAttr);
- if (FAILED(cap.ValidateProlog()))
- {
- THROW_BAD_FORMAT(BFA_BAD_CA_HEADER, m_pTargetAssembly->GetManifestModule());
- }
-
- LPCUTF8 szString;
- ULONG cbString;
- if (FAILED(cap.GetNonNullString(&szString, &cbString)))
- {
- THROW_BAD_FORMAT(BFA_BAD_CA_STRING, m_pTargetAssembly->GetManifestModule());
- }
-
- UINT32 u4;
- IfFailThrow(cap.GetU4(&u4));
- LoadHintEnum loadHint = (LoadHintEnum)u4;
-
- if (loadHint != LoadAlways)
- continue;
-
- // Convert the string to Unicode.
- StackSString dependencyNameFromCA(SString::Utf8, szString, cbString);
-
- CheckHardBindToZapFile(dependencyNameFromCA);
- }
-}
-#endif // FEATURE_CORECLR
HRESULT
CompilationDomain::GetDependencies(CORCOMPILE_DEPENDENCY **ppDependencies,
@@ -8367,9 +7380,6 @@ HRESULT
{
STANDARD_VM_CONTRACT;
-#ifndef FEATURE_CORECLR // hardbinding
- CheckLoadHints();
-#endif
//
// Return the bindings.
@@ -8384,27 +7394,6 @@ HRESULT
return S_OK;
}
-#ifdef FEATURE_FUSION
-HRESULT
- CompilationDomain::GetIBindContext(IBindContext **ppBindCtx)
-{
- LIMITED_METHOD_CONTRACT;
- HRESULT hr = S_OK;
-
- ReleaseHolder<IBindContext> pBindCtx;
- if (HasLoadContextHostBinder())
- {
- IfFailRet(GetCurrentLoadContextHostBinder()->QueryInterface(__uuidof(IBindContext), &pBindCtx));
- }
- else
- {
- GetBindContextFromApplicationContext(BaseDomain::GetFusionContext(), &pBindCtx); // Can't fail
- }
-
- *ppBindCtx = pBindCtx.Extract();
- return S_OK;
-}
-#endif
#ifdef CROSSGEN_COMPILE
HRESULT CompilationDomain::SetPlatformWinmdPaths(LPCWSTR pwzPlatformWinmdPaths)
@@ -8452,16 +7441,5 @@ HRESULT CompilationDomain::SetPlatformWinmdPaths(LPCWSTR pwzPlatformWinmdPaths)
}
#endif // CROSSGEN_COMPILE
-#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR)
-bool UseRyuJit()
-{
-#ifdef CROSSGEN_COMPILE
- return true;
-#else
- static ConfigDWORD useRyuJitValue;
- return useRyuJitValue.val(CLRConfig::INTERNAL_UseRyuJit) == 1 || IsNgenOffline();
-#endif
-}
-#endif
#endif // FEATURE_PREJIT
diff --git a/src/vm/compile.h b/src/vm/compile.h
index 8ee66dbec8..8fdd383dfe 100644
--- a/src/vm/compile.h
+++ b/src/vm/compile.h
@@ -207,21 +207,6 @@ class CEECompileInfo : public ICorCompileInfo
BOOL fExplicitBindToNativeImage,
CORINFO_ASSEMBLY_HANDLE *pHandle);
-#ifdef FEATURE_FUSION
- HRESULT LoadAssemblyByName(LPCWSTR wzName,
- CORINFO_ASSEMBLY_HANDLE *pHandle);
-
- HRESULT LoadAssemblyRef(IMDInternalImport *pAssemblyImport,
- mdAssemblyRef ref,
- CORINFO_ASSEMBLY_HANDLE *pHandle,
- IAssemblyName **refAssemblyName = NULL);
-
- HRESULT LoadAssemblyByIAssemblyName(
- IAssemblyName *pAssemblyName,
- CORINFO_ASSEMBLY_HANDLE *pHandle
- );
-
-#endif //FEATURE_FUSION
#ifdef FEATURE_COMINTEROP
HRESULT LoadTypeRefWinRT(IMDInternalImport *pAssemblyImport,
@@ -235,12 +220,6 @@ class CEECompileInfo : public ICorCompileInfo
mdFile file,
CORINFO_MODULE_HANDLE *pHandle);
-#ifndef FEATURE_CORECLR
- // Check if the assembly supports automatic NGen
- BOOL SupportsAutoNGen(CORINFO_ASSEMBLY_HANDLE assembly);
-
- HRESULT SetCachedSigningLevel(HANDLE hNI, HANDLE *pModules, COUNT_T nModules);
-#endif
BOOL CheckAssemblyZap(
CORINFO_ASSEMBLY_HANDLE assembly,
@@ -343,13 +322,6 @@ class CEECompileInfo : public ICorCompileInfo
ICorCompileDataStore *pData,
CorProfileData *profileData);
-#ifdef FEATURE_FUSION
- HRESULT GetAssemblyName(
- CORINFO_ASSEMBLY_HANDLE hAssembly,
- DWORD dwFlags,
- __out_z LPWSTR wzAssemblyName,
- LPDWORD cchAssemblyName);
-#endif //FEATURE_FUSION
HRESULT GetLoadHint(CORINFO_ASSEMBLY_HANDLE hAssembly,
CORINFO_ASSEMBLY_HANDLE hAssemblyDependency,
@@ -682,6 +654,8 @@ public:
ULONG Release();
+ void GetSerializedInlineTrackingMap(SBuffer* pBuffer);
+
void Error(mdToken token, Exception * pException);
};
@@ -757,9 +731,6 @@ typedef SHash<AssemblySpecDefRefMapTraits> AssemblySpecMapDefRefMapTable;
class CompilationDomain : public AppDomain,
public ICorCompilationDomain
{
-#ifndef FEATURE_CORECLR
- VPTR_MULTI_VTABLE_CLASS(CompilationDomain, AppDomain);
-#endif
public:
BOOL m_fForceDebug;
@@ -796,14 +767,6 @@ class CompilationDomain : public AppDomain,
HRESULT AddDependencyEntry(PEAssembly *pFile, mdAssemblyRef ref,mdAssemblyRef def);
void ReleaseDependencyEmitter();
-#ifndef FEATURE_CORECLR // hardbinding
- PtrHashMap m_hardBoundModules; // Hard dependency on native image of these dependency modules
- PtrHashMap m_cantHardBindModules;
- void UpdateDependencyEntryForHardBind(PEAssembly * pDependencyAssembly);
- void IncludeHardBindClosure(PEAssembly * pDependencyAssembly);
- void CheckHardBindToZapFile(SString dependencyNameFromCustomAttribute);
- void CheckLoadHints();
-#endif
public:
@@ -831,28 +794,7 @@ class CompilationDomain : public AppDomain,
BOOL CanEagerBindToZapFile(Module *targetModule, BOOL limitToHardBindList = TRUE);
-#ifndef FEATURE_CORECLR // hardbinding
- PtrHashMap::PtrIterator IterateHardBoundModules();
-
- // List of full display names of assemblies to hard-bind to
- SArray<SString,FALSE> m_assemblyHardBindList;
- BOOL m_useHardBindList;
- BOOL IsInHardBindRequestList(Assembly * pAssembly);
- BOOL IsInHardBindRequestList(PEAssembly * pAssembly);
- BOOL IsSafeToHardBindTo(PEAssembly * pAssembly);
-
- void SetAssemblyHardBindList(
- __in_ecount( cHardBindList )
- LPWSTR *pHardBindList,
- DWORD cHardBindList);
-#endif
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- void ComputeAssemblyHardBindList(IMDInternalImport * pImport);
- BOOL IsInHardBindList(SString& simpleName);
-
- static BOOL FindImage(const SString& fileName, MDInternalImportFlags flags, PEImage ** ppImage);
-#endif
// Returns NULL on out-of-memory
RefCache *GetRefCache(Module *pModule)
@@ -898,9 +840,6 @@ class CompilationDomain : public AppDomain,
HRESULT SetContextInfo(LPCWSTR exePath, BOOL isExe) DAC_EMPTY_RET(E_FAIL);
HRESULT GetDependencies(CORCOMPILE_DEPENDENCY **ppDependencies,
DWORD *cDependencies) DAC_EMPTY_RET(E_FAIL);
-#ifdef FEATURE_FUSION
- HRESULT GetIBindContext(IBindContext **ppBindCtx) DAC_EMPTY_RET(E_FAIL);
-#endif
#ifdef CROSSGEN_COMPILE
HRESULT SetPlatformWinmdPaths(LPCWSTR pwzPlatformWinmdPaths) DAC_EMPTY_RET(E_FAIL);
diff --git a/src/vm/comsynchronizable.cpp b/src/vm/comsynchronizable.cpp
index b486687752..08b5281a42 100644
--- a/src/vm/comsynchronizable.cpp
+++ b/src/vm/comsynchronizable.cpp
@@ -24,21 +24,10 @@
#include "comsynchronizable.h"
#include "dbginterface.h"
#include "comdelegate.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "eeconfig.h"
-#ifdef FEATURE_REMOTING
-#include "appdomainhelper.h"
-#include "objectclone.h"
-#else
#include "callhelpers.h"
-#endif
#include "appdomain.hpp"
#include "appdomain.inl"
-#ifdef FEATURE_REMOTING
-#include "crossdomaincalls.h"
-#endif
#include "newapis.h"
@@ -111,15 +100,9 @@ static inline BOOL ThreadNotStarted(Thread *t)
static inline BOOL ThreadIsRunning(Thread *t)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- return (t &&
- (t->m_State & (Thread::TS_ReportDead|Thread::TS_Dead)) == 0 &&
- (CLRTaskHosted()? t->GetHostTask()!=NULL:t->HasValidThreadHandle()));
-#else // !FEATURE_INCLUDE_ALL_INTERFACES
return (t &&
(t->m_State & (Thread::TS_ReportDead|Thread::TS_Dead)) == 0 &&
(t->HasValidThreadHandle()));
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
static inline BOOL ThreadIsDead(Thread *t)
@@ -306,7 +289,7 @@ static void PulseAllHelper(Thread* pThread)
}
// When an exposed thread is started by Win32, this is where it starts.
-ULONG __stdcall ThreadNative::KickOffThread(void* pass)
+ULONG WINAPI ThreadNative::KickOffThread(void* pass)
{
CONTRACTL
@@ -607,59 +590,6 @@ FCIMPL1(void, ThreadNative::ResetAbort, ThreadBaseObject* pThis)
}
FCIMPLEND
-#ifndef FEATURE_CORECLR
-// You can only suspend a running thread.
-FCIMPL1(void, ThreadNative::Suspend, ThreadBaseObject* pThisUNSAFE)
-{
- FCALL_CONTRACT;
-
- if (pThisUNSAFE == NULL)
- FCThrowResVoid(kNullReferenceException, W("NullReference_This"));
-
- Thread *thread = pThisUNSAFE->GetInternal();
-
- HELPER_METHOD_FRAME_BEGIN_0();
-
-#ifdef MDA_SUPPORTED
- MDA_TRIGGER_ASSISTANT(DangerousThreadingAPI, ReportViolation(W("System.Threading.Thread.Suspend")));
-#endif
-
- if (!ThreadIsRunning(thread))
- COMPlusThrow(kThreadStateException, IDS_EE_THREAD_SUSPEND_NON_RUNNING);
-
- thread->UserSuspendThread();
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-// You can only resume a thread that is in the user-suspended state. (This puts a large
-// burden on the app developer, but we want him to be thinking carefully about race
-// conditions. Precise errors give him a hope of sorting out his logic).
-FCIMPL1(void, ThreadNative::Resume, ThreadBaseObject* pThisUNSAFE)
-{
- FCALL_CONTRACT;
-
- if (pThisUNSAFE == NULL)
- FCThrowResVoid(kNullReferenceException, W("NullReference_This"));
-
- Thread *thread = pThisUNSAFE->GetInternal();
-
- HELPER_METHOD_FRAME_BEGIN_0();
-
- // UserResumeThread() will return 0 if there isn't a user suspension for us to
- // clear.
- if (!ThreadIsRunning(thread))
- COMPlusThrow(kThreadStateException, IDS_EE_THREAD_RESUME_NON_RUNNING);
-
- if (thread->UserResumeThread() == 0)
- COMPlusThrow(kThreadStateException, IDS_EE_THREAD_RESUME_NON_USER_SUSPEND);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-#endif // FEATURE_CORECLR
// Note that you can manipulate the priority of a thread that hasn't started yet,
// or one that is running. But you get an exception if you manipulate the priority
@@ -996,18 +926,8 @@ FCIMPL1(INT32, ThreadNative::GetThreadState, ThreadBaseObject* pThisUNSAFE)
if (state & Thread::TS_Interruptible)
res |= ThreadWaitSleepJoin;
- // Don't report a SuspendRequested if the thread has actually Suspended.
- if ((state & Thread::TS_UserSuspendPending) &&
- (state & Thread::TS_SyncSuspended)
- )
- {
- res |= ThreadSuspended;
- }
- else
- if (state & Thread::TS_UserSuspendPending)
- {
- res |= ThreadSuspendRequested;
- }
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(state & Thread::TS_UserSuspendPending));
HELPER_METHOD_POLL();
HELPER_METHOD_FRAME_END();
@@ -1374,7 +1294,6 @@ void ThreadBaseObject::InitExisting()
}
-#ifndef FEATURE_LEAK_CULTURE_INFO
OBJECTREF ThreadBaseObject::GetManagedThreadCulture(BOOL bUICulture)
{
CONTRACTL {
@@ -1490,7 +1409,6 @@ void ThreadBaseObject::ResetManagedThreadCulture(BOOL bUICulture)
}
}
-#endif // FEATURE_LEAK_CULTURE_INFO
FCIMPL1(void, ThreadNative::Finalize, ThreadBaseObject* pThisUNSAFE)
@@ -1527,39 +1445,6 @@ FCIMPL1(void, ThreadNative::DisableComObjectEagerCleanup, ThreadBaseObject* pThi
FCIMPLEND
#endif //FEATURE_COMINTEROP
-#ifdef FEATURE_LEAK_CULTURE_INFO
-FCIMPL1(FC_BOOL_RET, ThreadNative::SetThreadUILocale, StringObject* localeNameUNSAFE)
-{
- FCALL_CONTRACT;
-
- BOOL result = TRUE;
-
- STRINGREF name = (STRINGREF) localeNameUNSAFE;
- VALIDATEOBJECTREF(name);
-
- HELPER_METHOD_FRAME_BEGIN_RET_0();
-
- LCID lcid=NewApis::LocaleNameToLCID(name->GetBuffer(),0);
- if (lcid == 0)
- {
- ThrowHR(HRESULT_FROM_WIN32(GetLastError()));
- }
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *manager = CorHost2::GetHostTaskManager();
- if (manager) {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- result = (manager->SetUILocale(lcid) == S_OK);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- HELPER_METHOD_FRAME_END();
-
- FC_RETURN_BOOL(result);
-}
-FCIMPLEND
-#endif // FEATURE_LEAK_CULTURE_INFO
FCIMPL0(Object*, ThreadNative::GetDomain)
{
@@ -1628,189 +1513,6 @@ LPVOID F_CALL_CONV ThreadNative::FastGetDomain()
}
#endif // _TARGET_X86_ && _MSC_VER
-#ifdef FEATURE_REMOTING
-// This is just a helper method that lets BCL get to the managed context
-// from the contextID.
-FCIMPL1(Object*, ThreadNative::GetContextFromContextID, LPVOID ContextID)
-{
- FCALL_CONTRACT;
-
- OBJECTREF rv = NULL;
- Context* pCtx = (Context *) ContextID;
- // Get the managed context backing this unmanaged context
- rv = pCtx->GetExposedObjectRaw();
-
- // This assert maintains the following invariant:
- // Only default unmanaged contexts can have a null managed context
- // (All non-deafult contexts are created as managed contexts first, and then
- // hooked to the unmanaged context)
- _ASSERTE((rv != NULL) || (pCtx->GetDomain()->GetDefaultContext() == pCtx));
-
- return OBJECTREFToObject(rv);
-}
-FCIMPLEND
-
-
-FCIMPL6(Object*, ThreadNative::InternalCrossContextCallback, ThreadBaseObject* refThis, ContextBaseObject* refContext, LPVOID contextID, INT32 appDomainId, Object* oDelegateUNSAFE, PtrArray* oArgsUNSAFE)
-{
- FCALL_CONTRACT;
-
- _ASSERTE(refThis != NULL);
- VALIDATEOBJECT(refThis);
- Thread *pThread = refThis->GetInternal();
- Context *pCtx = (Context *)contextID;
-
-
- _ASSERTE(pCtx && (refContext == NULL || pCtx->GetExposedObjectRaw() == NULL ||
- ObjectToOBJECTREF(refContext) == pCtx->GetExposedObjectRaw()));
- LOG((LF_APPDOMAIN, LL_INFO1000, "ThreadNative::InternalCrossContextCallback: %p, %p\n", refContext, pCtx));
- // install our frame. We have to put it here before we put the helper frame on
-
- // Set the VM conext
-
- struct _gc {
- OBJECTREF oRetVal;
- OBJECTREF oDelegate;
- OBJECTREF oArgs;
- // We need to report the managed context object because it may become unreachable in the caller,
- // however we have to keep it alive, otherwise its finalizer could free the unmanaged internal context
- OBJECTREF oContext;
- } gc;
-
- gc.oRetVal = NULL;
- gc.oDelegate = ObjectToOBJECTREF(oDelegateUNSAFE);
- gc.oArgs = ObjectToOBJECTREF(oArgsUNSAFE);
- gc.oContext = ObjectToOBJECTREF(refContext);
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
-
- if (pThread == NULL)
- COMPlusThrow(kThreadStateException, IDS_EE_THREAD_CANNOT_GET);
-
-#ifdef _DEBUG
- MethodDesc* pTargetMD = COMDelegate::GetMethodDesc(gc.oDelegate);
- _ASSERTE(pTargetMD->IsStatic());
-#endif
-
- // If we have a non-zero appDomain index, this is a x-domain call
- // We must verify that the AppDomain is not unloaded
- PREPARE_NONVIRTUAL_CALLSITE(METHOD__THREAD__COMPLETE_CROSSCONTEXTCALLBACK);
-
- AppDomainFromIDHolder ad;
- if (appDomainId != 0)
- {
- //
- // NOTE: there is a potential race between the time we retrieve the app domain pointer,
- // and the time which this thread enters the domain.
- //
- // To solve the race, we rely on the fact that there is a thread sync
- // between releasing an app domain's handle, and destroying the app domain. Thus
- // it is important that we not go into preemptive gc mode in that window.
- //
- {
- ad.Assign(ADID(appDomainId), TRUE);
-
- if (ad.IsUnloaded() || !ad->CanThreadEnter(pThread))
- COMPlusThrow(kAppDomainUnloadedException, W("Remoting_AppDomainUnloaded"));
- }
- }
-
- // Verify that the Context is valid.
- if ( !Context::ValidateContext(pCtx) )
- COMPlusThrow(kRemotingException, W("Remoting_InvalidContext"));
-
- DEBUG_ASSURE_NO_RETURN_BEGIN(COMSYNCH)
-
- FrameWithCookie<ContextTransitionFrame> frame;
-
- Context* pCurrContext = pThread->GetContext();
- bool fTransition = (pCurrContext != pCtx);
- BOOL fSameDomain = (appDomainId==0) || (pCurrContext->GetDomain()->GetId() == (ADID)appDomainId);
- _ASSERTE( fTransition || fSameDomain);
- if (fTransition)
- if (appDomainId!=0)
- ad->EnterContext(pThread,pCtx, &frame);
- else
- pThread->EnterContextRestricted(pCtx,&frame);
- ad.Release();
-
-
- LOG((LF_EH, LL_INFO100, "MSCORLIB_ENTER_CONTEXT( %s::%s ): %s\n",
- pTargetMD->m_pszDebugClassName,
- pTargetMD->m_pszDebugMethodName,
- fTransition ? "ENTERED" : "NOP"));
-
- Exception* pOriginalException=NULL;
-
- EX_TRY
- {
- DECLARE_ARGHOLDER_ARRAY(callArgs, 2);
-
-#if CHECK_APP_DOMAIN_LEAKS
- // We're passing the delegate object to another appdomain
- // without marshaling, that is OK - it's a static function delegate
- // but we should mark it as agile then.
- gc.oDelegate->SetSyncBlockAppDomainAgile();
-#endif
- callArgs[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(gc.oDelegate);
- callArgs[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(gc.oArgs);
-
- CATCH_HANDLER_FOUND_NOTIFICATION_CALLSITE;
- CALL_MANAGED_METHOD_RETREF(gc.oRetVal, OBJECTREF, callArgs);
- }
- EX_CATCH
- {
- LOG((LF_EH, LL_INFO100, "MSCORLIB_CONTEXT_TRANSITION( %s::%s ): exception in flight\n", pTargetMD->m_pszDebugClassName, pTargetMD->m_pszDebugMethodName));
-
- if (!fTransition || fSameDomain)
- {
- if (fTransition)
- {
- GCX_FORBID();
- pThread->ReturnToContext(&frame);
- }
-#ifdef FEATURE_TESTHOOKS
- if (appDomainId!=0)
- {
- TESTHOOKCALL(LeftAppDomain(appDomainId));
- }
-#endif
- EX_RETHROW;
- }
-
- pOriginalException=EXTRACT_EXCEPTION();
- CAPTURE_BUCKETS_AT_TRANSITION(pThread, CLRException::GetThrowableFromException(pOriginalException));
- goto lAfterCtxUnwind;
- }
- EX_END_CATCH_UNREACHABLE;
- if (0)
- {
-lAfterCtxUnwind:
- LOG((LF_EH, LL_INFO100, "MSCORLIB_RaiseCrossContextException( %s::%s )\n", pTargetMD->m_pszDebugClassName, pTargetMD->m_pszDebugMethodName));
- pThread->RaiseCrossContextException(pOriginalException,&frame);
- }
-
- LOG((LF_EH, LL_INFO100, "MSCORLIB_LEAVE_CONTEXT_TRANSITION( %s::%s )\n", pTargetMD->m_pszDebugClassName, pTargetMD->m_pszDebugMethodName));
-
- if (fTransition)
- {
- GCX_FORBID();
- pThread->ReturnToContext(&frame);
- }
-#ifdef FEATURE_TESTHOOKS
- if(appDomainId!=0)
- {
- TESTHOOKCALL(LeftAppDomain(appDomainId));
- }
-#endif
-
- DEBUG_ASSURE_NO_RETURN_END(COMSYNCH)
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(gc.oRetVal);
-}
-FCIMPLEND
-#endif //FEATURE_REMOTING
//
// nativeGetSafeCulture is used when the culture get requested from the thread object.
@@ -1822,31 +1524,7 @@ FCIMPLEND
// unloaded and this culture will survive although the type metadata will be unloaded
// and GC will crash first time accessing this object after the app domain unload.
//
-#ifdef FEATURE_LEAK_CULTURE_INFO
-FCIMPL4(FC_BOOL_RET, ThreadNative::nativeGetSafeCulture,
- ThreadBaseObject* threadUNSAFE,
- int appDomainId,
- CLR_BOOL isUI,
- OBJECTREF* safeCulture)
-{
- FCALL_CONTRACT;
-
- THREADBASEREF thread(threadUNSAFE);
-
- CULTUREINFOBASEREF pCulture = isUI ? thread->GetCurrentUICulture() : thread->GetCurrentUserCulture();
- if (pCulture != NULL) {
- if (pCulture->IsSafeCrossDomain() || pCulture->GetCreatedDomainID() == ADID(appDomainId)) {
- SetObjectReference(safeCulture, pCulture, pCulture->GetAppDomain());
- } else {
- FC_RETURN_BOOL(FALSE);
- }
- }
- FC_RETURN_BOOL(TRUE);
-}
-FCIMPLEND
-#endif // FEATURE_LEAK_CULTURE_INFO
-#ifndef FEATURE_LEAK_CULTURE_INFO
void QCALLTYPE ThreadNative::nativeInitCultureAccessors()
{
QCALL_CONTRACT;
@@ -1858,7 +1536,6 @@ void QCALLTYPE ThreadNative::nativeInitCultureAccessors()
END_QCALL;
}
-#endif // FEATURE_LEAK_CULTURE_INFO
void QCALLTYPE ThreadNative::InformThreadNameChange(QCall::ThreadHandle thread, LPCWSTR name, INT32 len)
@@ -1913,41 +1590,6 @@ UINT64 QCALLTYPE ThreadNative::GetProcessDefaultStackSize()
return (UINT64)reserve;
}
-#ifndef FEATURE_CORECLR
-FCIMPL0(void, ThreadNative::BeginCriticalRegion)
-{
- FCALL_CONTRACT;
- if (CLRHosted())
- {
- GetThread()->BeginCriticalRegion_NoCheck();
- }
-}
-FCIMPLEND
-
-FCIMPL0(void, ThreadNative::EndCriticalRegion)
-{
- FCALL_CONTRACT;
- if (CLRHosted())
- {
- GetThread()->EndCriticalRegion_NoCheck();
- }
-}
-FCIMPLEND
-
-FCIMPL0(void, ThreadNative::BeginThreadAffinity)
-{
- FCALL_CONTRACT;
- Thread::BeginThreadAffinity();
-}
-FCIMPLEND
-
-FCIMPL0(void, ThreadNative::EndThreadAffinity)
-{
- FCALL_CONTRACT;
- Thread::EndThreadAffinity();
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
FCIMPL1(FC_BOOL_RET, ThreadNative::IsThreadpoolThread, ThreadBaseObject* thread)
@@ -2017,61 +1659,6 @@ BOOL QCALLTYPE ThreadNative::YieldThread()
return ret;
}
-#ifdef FEATURE_COMPRESSEDSTACK
-FCIMPL2(void*, ThreadNative::SetAppDomainStack, ThreadBaseObject* pThis, SafeHandle* hcsUNSAFE)
-{
- FCALL_CONTRACT;
-
- void* pRet = NULL;
- SAFEHANDLE hcsSAFE = (SAFEHANDLE) hcsUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_1(hcsSAFE);
-
-
- void* unmanagedCompressedStack = NULL;
- if (hcsSAFE != NULL)
- {
- unmanagedCompressedStack = (void *)hcsSAFE->GetHandle();
- }
-
-
- VALIDATEOBJECT(pThis);
- Thread *pThread = pThis->GetInternal();
- if (pThread == NULL)
- COMPlusThrow(kThreadStateException, IDS_EE_THREAD_CANNOT_GET);
-
- pRet = StackCompressor::SetAppDomainStack(pThread, unmanagedCompressedStack);
- HELPER_METHOD_FRAME_END_POLL();
- return pRet;
-}
-FCIMPLEND
-
-
-FCIMPL2(void, ThreadNative::RestoreAppDomainStack, ThreadBaseObject* pThis, void* appDomainStack)
-{
- FCALL_CONTRACT;
-
- HELPER_METHOD_FRAME_BEGIN_NOPOLL();
-
- VALIDATEOBJECT(pThis);
- Thread *pThread = pThis->GetInternal();
- if (pThread == NULL)
- COMPlusThrow(kThreadStateException, IDS_EE_THREAD_CANNOT_GET);
-
- StackCompressor::RestoreAppDomainStack(pThread, appDomainStack);
- HELPER_METHOD_FRAME_END_POLL();
-}
-FCIMPLEND
-#endif //#ifdef FEATURE_COMPRESSEDSTACK
-
-FCIMPL0(void, ThreadNative::FCMemoryBarrier)
-{
- FCALL_CONTRACT;
-
- MemoryBarrier();
- FC_GC_POLL();
-}
-FCIMPLEND
-
FCIMPL2(void, ThreadNative::SetAbortReason, ThreadBaseObject* pThisUNSAFE, Object* pObject)
{
FCALL_CONTRACT;
@@ -2128,69 +1715,6 @@ FCIMPL2(void, ThreadNative::SetAbortReason, ThreadBaseObject* pThisUNSAFE, Objec
}
FCIMPLEND
-#ifndef FEATURE_CORECLR // core clr does not support abort reason
-FCIMPL1(Object*, ThreadNative::GetAbortReason, ThreadBaseObject *pThisUNSAFE)
-{
- FCALL_CONTRACT;
-
- if (pThisUNSAFE==NULL)
- FCThrowRes(kNullReferenceException, W("NullReference_This"));
-
- OBJECTREF refRetVal = NULL;
- Thread *pThread = pThisUNSAFE->GetInternal();
-
- // Set up a frame in case of GC or EH
- HELPER_METHOD_FRAME_BEGIN_RET_1(refRetVal)
-
- if (pThread == NULL)
- COMPlusThrow(kThreadStateException, IDS_EE_THREAD_CANNOT_GET);
-
- // While the ExceptionInfo probably will be *set* from a different
- // thread, it should only be *read* from the current thread.
- _ASSERTE(GetThread() == pThread);
-
- // Set cooperative mode, to avoid AD unload while we're working.
- GCX_COOP();
-
- OBJECTHANDLE oh=NULL;
- ADID adid;
- // Scope the lock to reading the two fields on the Thread object.
- { // Atomically get the OBJECTHANDLE and ADID of the object
- // NOTE: get the lock on this thread object, not on the executing thread.
- Thread::AbortRequestLockHolder lock(pThread);
- oh = pThread->m_AbortReason;
- adid = pThread->m_AbortReasonDomainID;
- }
-
- // If the OBJECTHANDLE is not 0...
- if (oh != 0)
- {
-
- AppDomain *pCurrentDomain = pThread->GetDomain();
- // See if the appdomain is equal to the appdomain of the currently running
- // thread.
-
- if (pCurrentDomain->GetId() == adid)
- { // Same appdomain; just return object from the OBJECTHANDLE
- refRetVal = ObjectFromHandle(oh);
- }
- else
- { // Otherwise, try to marshal the object from the other AppDomain
- ENTER_DOMAIN_ID(adid);
- CrossAppDomainClonerCallback cadcc;
- ObjectClone Cloner(&cadcc, CrossAppDomain, FALSE);
- refRetVal = Cloner.Clone(ObjectFromHandle(oh), GetAppDomain(), pCurrentDomain, NULL);
- Cloner.RemoveGCFrames();
- END_DOMAIN_TRANSITION;
- }
- }
-
- HELPER_METHOD_FRAME_END()
-
- return OBJECTREFToObject(refRetVal);
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
FCIMPL1(void, ThreadNative::ClearAbortReason, ThreadBaseObject* pThisUNSAFE)
{
diff --git a/src/vm/comsynchronizable.h b/src/vm/comsynchronizable.h
index d9c2defd70..00b055c960 100644
--- a/src/vm/comsynchronizable.h
+++ b/src/vm/comsynchronizable.h
@@ -69,10 +69,6 @@ public:
static FCDECL1(void, Abort, ThreadBaseObject* pThis);
static FCDECL1(void, ResetAbort, ThreadBaseObject* pThis);
static FCDECL2(void, Start, ThreadBaseObject* pThisUNSAFE, StackCrawlMark* pStackMark);
-#ifndef FEATURE_CORECLR
- static FCDECL1(void, Suspend, ThreadBaseObject* pThisUNSAFE);
- static FCDECL1(void, Resume, ThreadBaseObject* pThisUNSAFE);
-#endif // FEATURE_CORECLR
static FCDECL1(INT32, GetPriority, ThreadBaseObject* pThisUNSAFE);
static FCDECL2(void, SetPriority, ThreadBaseObject* pThisUNSAFE, INT32 iPriority);
static FCDECL1(void, Interrupt, ThreadBaseObject* pThisUNSAFE);
@@ -92,15 +88,7 @@ public:
static FCDECL1(void, StartupSetApartmentState, ThreadBaseObject* pThis);
#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
static FCDECL0(Object*, GetDomain);
-#ifdef FEATURE_REMOTING
- static FCDECL1(Object*, GetContextFromContextID, LPVOID ContextID);
- static FCDECL6(Object*, InternalCrossContextCallback, ThreadBaseObject* refThis, ContextBaseObject* refContext, LPVOID contextID, INT32 appDomainId, Object* oDelegateUNSAFE, PtrArray* oArgsUNSAFE);
-#endif
-#ifdef FEATURE_LEAK_CULTURE_INFO
- static FCDECL4(FC_BOOL_RET, nativeGetSafeCulture, ThreadBaseObject* threadUNSAFE, int appDomainId, CLR_BOOL isUI, OBJECTREF *safeCulture);
-#else
static void QCALLTYPE nativeInitCultureAccessors();
-#endif
static
void QCALLTYPE InformThreadNameChange(QCall::ThreadHandle thread, LPCWSTR name, INT32 len);
@@ -109,12 +97,6 @@ public:
UINT64 QCALLTYPE GetProcessDefaultStackSize();
static FCDECL1(INT32, GetManagedThreadId, ThreadBaseObject* th);
-#ifndef FEATURE_CORECLR
- static FCDECL0(void, BeginCriticalRegion);
- static FCDECL0(void, EndCriticalRegion);
- static FCDECL0(void, BeginThreadAffinity);
- static FCDECL0(void, EndThreadAffinity);
-#endif // !FEATURE_CORECLR
static FCDECL1(void, SpinWait, int iterations);
static BOOL QCALLTYPE YieldThread();
static FCDECL0(Object*, GetCurrentThread);
@@ -122,22 +104,11 @@ public:
#ifdef FEATURE_COMINTEROP
static FCDECL1(void, DisableComObjectEagerCleanup, ThreadBaseObject* pThis);
#endif //FEATURE_COMINTEROP
-#ifdef FEATURE_LEAK_CULTURE_INFO
- static FCDECL1(FC_BOOL_RET,SetThreadUILocale, StringObject* localeNameUNSAFE);
-#endif // FEATURE_LEAK_CULTURE_INFO
static FCDECL1(FC_BOOL_RET,IsThreadpoolThread, ThreadBaseObject* thread);
-#ifdef FEATURE_COMPRESSEDSTACK
- static FCDECL2(void*, SetAppDomainStack, ThreadBaseObject* pThis, SafeHandle* hcsUNSAFE);
- static FCDECL2(void, RestoreAppDomainStack, ThreadBaseObject* pThis, void* appDomainStack);
-#endif // #ifdef FEATURE_COMPRESSEDSTACK
- static FCDECL0(void, FCMemoryBarrier);
static FCDECL1(void, SetIsThreadStaticsArray, Object* pObject);
static FCDECL2(void, SetAbortReason, ThreadBaseObject* pThisUNSAFE, Object* pObject);
-#ifndef FEATURE_CORECLR
- static FCDECL1(Object*, GetAbortReason, ThreadBaseObject* pThisUNSAFE);
-#endif
static FCDECL1(void, ClearAbortReason, ThreadBaseObject* pThisUNSAFE);
private:
@@ -149,7 +120,7 @@ private:
};
static void KickOffThread_Worker(LPVOID /* KickOffThread_Args* */);
- static ULONG __stdcall KickOffThread(void *pass);
+ static ULONG WINAPI KickOffThread(void *pass);
static BOOL DoJoin(THREADBASEREF DyingThread, INT32 timeout);
};
diff --git a/src/vm/comthreadpool.cpp b/src/vm/comthreadpool.cpp
index a4c7e75064..554e836e6c 100644
--- a/src/vm/comthreadpool.cpp
+++ b/src/vm/comthreadpool.cpp
@@ -28,11 +28,7 @@
#include "corhost.h"
#include "nativeoverlapped.h"
#include "comsynchronizable.h"
-#ifdef FEATURE_REMOTING
-#include "crossdomaincalls.h"
-#else
#include "callhelpers.h"
-#endif
#include "appdomain.inl"
/*****************************************************************************************************/
#ifdef _DEBUG
@@ -300,17 +296,6 @@ void QCALLTYPE ThreadPoolNative::InitializeVMTp(CLR_BOOL* pEnableWorkerTracking)
END_QCALL;
}
-
-FCIMPL0(FC_BOOL_RET, ThreadPoolNative::IsThreadPoolHosted)
-{
- FCALL_CONTRACT;
-
- FCUnique(0x22);
-
- FC_RETURN_BOOL(ThreadpoolMgr::IsThreadPoolHosted());
-}
-FCIMPLEND
-
/*****************************************************************************************************/
struct RegisterWaitForSingleObjectCallback_Args
@@ -632,31 +617,6 @@ void SetAsyncResultProperties(
STATIC_CONTRACT_MODE_ANY;
STATIC_CONTRACT_SO_TOLERANT;
-#ifndef FEATURE_CORECLR
- ASYNCRESULTREF asyncResult = overlapped->m_asyncResult;
- // only filestream is expected to have a null delegate in which
- // case we do the necessary book-keeping here. However, for robustness
- // we should make sure that the asyncResult is indeed an instance of
- // FileStreamAsyncResult
- if (asyncResult->GetMethodTable() == g_pAsyncFileStream_AsyncResultClass)
- {
- // Handle reading from & writing to closed pipes. It's possible for
- // an async read on a pipe to be issued and then the pipe is closed,
- // returning this error. This may very well be necessary. -BG
- if (dwErrorCode == ERROR_BROKEN_PIPE || dwErrorCode == ERROR_NO_DATA)
- dwErrorCode = 0;
- asyncResult->SetErrorCode(dwErrorCode);
- asyncResult->SetNumBytes(dwNumBytes);
- asyncResult->SetCompletedAsynchronously();
- asyncResult->SetIsComplete();
-
- // Signal the event - the OS does not do this for us.
- WAITHANDLEREF waitHandle = asyncResult->GetWaitHandle();
- HANDLE h = waitHandle->GetWaitHandle();
- if ((h != NULL) && (h != (HANDLE) -1))
- UnsafeSetEvent(h);
- }
-#endif // !FEATURE_CORECLR
}
VOID BindIoCompletionCallBack_Worker(LPVOID args)
@@ -698,13 +658,6 @@ VOID BindIoCompletionCallBack_Worker(LPVOID args)
// no user delegate to callback
_ASSERTE((overlapped->m_iocbHelper == NULL) || !"This is benign, but should be optimized");
-#ifndef FEATURE_CORECLR
- // we cannot do this at threadpool initialization time since mscorlib may not have been loaded
- if (!g_pAsyncFileStream_AsyncResultClass)
- {
- g_pAsyncFileStream_AsyncResultClass = MscorlibBinder::GetClass(CLASS__FILESTREAM_ASYNCRESULT);
- }
-#endif // !FEATURE_CORECLR
SetAsyncResultProperties(overlapped, ErrorCode, numBytesTransferred);
}
diff --git a/src/vm/comthreadpool.h b/src/vm/comthreadpool.h
index 9964af8b64..6fd250f0ba 100644
--- a/src/vm/comthreadpool.h
+++ b/src/vm/comthreadpool.h
@@ -39,8 +39,6 @@ public:
static FCDECL1(void, ReportThreadStatus, CLR_BOOL isWorking);
- static FCDECL0(FC_BOOL_RET, IsThreadPoolHosted);
-
static FCDECL7(LPVOID, CorRegisterWaitForSingleObject,
Object* waitObjectUNSAFE,
diff --git a/src/vm/comtoclrcall.cpp b/src/vm/comtoclrcall.cpp
index b76f9852b7..b6d59a859f 100644
--- a/src/vm/comtoclrcall.cpp
+++ b/src/vm/comtoclrcall.cpp
@@ -270,24 +270,6 @@ inline static void InvokeStub(ComCallMethodDesc *pCMD, PCODE pManagedTarget, OBJ
#endif // _TARGET_X86_
-NOINLINE
-void InvokeStub_Hosted(ComCallMethodDesc *pCMD, PCODE pManagedTarget, OBJECTREF orThis, ComMethodFrame *pFrame, Thread *pThread,
- UINT64* pRetValOut)
-{
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(CLRTaskHosted());
-
- ReverseEnterRuntimeHolderNoThrow REHolder;
- HRESULT hr = REHolder.AcquireNoThrow();
- if (FAILED(hr))
- {
- *pRetValOut = hr;
- return;
- }
-
- InvokeStub(pCMD, pManagedTarget, orThis, pFrame, pThread, pRetValOut);
-}
-
#if defined(_MSC_VER) && !defined(_DEBUG)
#pragma optimize("t", on) // optimize for speed
#endif
@@ -440,15 +422,7 @@ void COMToCLRInvokeTarget(PCODE pManagedTarget, OBJECTREF pObject, ComCallMethod
}
#endif // DEBUGGING_SUPPORTED
-
- if (CLRTaskHosted())
- {
- InvokeStub_Hosted(pCMD, pManagedTarget, pObject, pFrame, pThread, pRetValOut);
- }
- else
- {
- InvokeStub(pCMD, pManagedTarget, pObject, pFrame, pThread, pRetValOut);
- }
+ InvokeStub(pCMD, pManagedTarget, pObject, pFrame, pThread, pRetValOut);
}
bool COMToCLRWorkerBody_SecurityCheck(ComCallMethodDesc * pCMD, MethodDesc * pMD, Thread * pThread, UINT64 * pRetValOut)
@@ -1109,8 +1083,6 @@ static void FieldCallWorkerBody(Thread *pThread, ComMethodFrame* pFrame)
}
CONTRACTL_END;
- ReverseEnterRuntimeHolder REHolder(TRUE);
-
IUnknown** pip = (IUnknown **)pFrame->GetPointerToArguments();
IUnknown* pUnk = (IUnknown *)*pip;
_ASSERTE(pUnk != NULL);
diff --git a/src/vm/comtypelibconverter.cpp b/src/vm/comtypelibconverter.cpp
deleted file mode 100644
index f6f0e1e405..0000000000
--- a/src/vm/comtypelibconverter.cpp
+++ /dev/null
@@ -1,791 +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.
-
-/*============================================================
-**
-** Header: COMTypeLibConverter.cpp
-**
-**
-** Purpose: Implementation of the native methods used by the
-** typelib converter.
-**
-**
-===========================================================*/
-
-#include "common.h"
-
-#include "comtypelibconverter.h"
-#include "runtimecallablewrapper.h"
-#include "assembly.hpp"
-#include "debugmacros.h"
-#include <tlbimpexp.h>
-#include "..\md\inc\imptlb.h"
-#include <tlbutils.h>
-#include "posterror.h"
-
-BOOL COMTypeLibConverter::m_bInitialized = FALSE;
-
-void COMTypeLibConverter::TypeLibImporterWrapper(
- ITypeLib *pITLB, // Typelib to import.
- LPCWSTR szFname, // Name of the typelib, if known.
- LPCWSTR szNamespace, // Optional namespace override.
- IMetaDataEmit *pEmit, // Metadata scope to which to emit.
- Assembly *pAssembly, // Assembly containing the imported module.
- Module *pModule, // Module we are emitting into.
- ITypeLibImporterNotifySink *pNotify,// Callback interface.
- TlbImporterFlags flags, // Importer flags.
- CImportTlb **ppImporter) // The importer.
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- PRECONDITION(CheckPointer(pITLB));
- PRECONDITION(CheckPointer(szFname, NULL_OK));
- PRECONDITION(CheckPointer(szNamespace, NULL_OK));
- PRECONDITION(CheckPointer(pEmit));
- PRECONDITION(CheckPointer(pAssembly));
- PRECONDITION(CheckPointer(pModule));
- PRECONDITION(CheckPointer(pNotify));
- PRECONDITION(CheckPointer(ppImporter));
- }
- CONTRACTL_END;
-
- HRESULT hr;
-
- // Retrieve flag indicating whether runtime or linktime interface
- // security checks are required.
- BOOL bUnsafeInterfaces = (BOOL)(flags & TlbImporter_UnsafeInterfaces);
-
- // Determine if we import SAFEARRAY's as System.Array's.
- BOOL bSafeArrayAsSysArray = (BOOL)(flags & TlbImporter_SafeArrayAsSystemArray);
-
- // Determine if we are doing the [out,retval] transformation on disp only interfaces.
- BOOL bTransformDispRetVals = (BOOL)(flags & TlbImporter_TransformDispRetVals);
-
- // Determine if we are adding members to classes.
- BOOL bPreventClassMembers = (BOOL)(flags & TlbImporter_PreventClassMembers);
-
- // Determine if we are marking value classes as serializable
- BOOL bSerializableValueClasses = (BOOL)(flags & TlbImporter_SerializableValueClasses);
-
- // Create and initialize a TypeLib importer.
- NewPreempHolder<CImportTlb> pImporter = CImportTlb::CreateImporter(szFname, pITLB, true, bUnsafeInterfaces, bSafeArrayAsSysArray, bTransformDispRetVals, bPreventClassMembers, bSerializableValueClasses);
- if (!pImporter)
- COMPlusThrowOM();
-
- // If a namespace is specified, use it.
- if (szNamespace)
- pImporter->SetNamespace(szNamespace);
-
- // Set the various pointers.
- hr = pImporter->SetMetaData(pEmit);
- _ASSERTE(SUCCEEDED(hr) && "Couldn't get IMetaDataEmit* from Module");
- if (FAILED(hr))
- COMPlusThrowArgumentNull(W("pEmit"));
-
- pImporter->SetNotification(pNotify);
- pImporter->SetAssembly(pAssembly);
- pImporter->SetModule(pModule);
-
- // Do the conversion.
- hr = pImporter->Import();
- if (SUCCEEDED(hr))
- {
- *ppImporter = pImporter;
- pImporter.SuppressRelease();
- }
- else
- {
- COMPlusThrowHR(hr, kGetErrorInfo);
- }
-} // HRESULT COMTypeLibConverter::TypeLibImporterWrapper()
-
-
-void COMTypeLibConverter::ConvertAssemblyToTypeLibInternal(OBJECTREF* ppAssembly,
- STRINGREF* ppTypeLibName,
- DWORD Flags,
- OBJECTREF* ppNotifySink,
- OBJECTREF* pRetObj)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION (IsProtectedByGCFrame (ppAssembly));
- PRECONDITION (IsProtectedByGCFrame (ppTypeLibName));
- PRECONDITION (IsProtectedByGCFrame (ppNotifySink));
- PRECONDITION (IsProtectedByGCFrame (pRetObj));
- INJECT_FAULT(COMPlusThrowOM());
- }
- CONTRACTL_END;
-
- Assembly *pAssembly=0; // Assembly to export.
-
- NewArrayHolder<WCHAR> szTypeLibName=0; // The name for the typelib.
- SafeComHolder<ITypeLib> pTLB=0; // The new typelib.
- SafeComHolder<ITypeLibExporterNotifySink> pINotify=0; // Callback parameter.
-
- // Make sure the COMTypeLibConverter has been initialized.
- if (!m_bInitialized)
- Init();
-
- // Validate flags
- if ((Flags & ~TlbExporter_ValidFlags) != 0)
- COMPlusThrowArgumentOutOfRange(W("flags"), W("Argument_InvalidFlag"));
-
- // Retrieve the callback.
- if (*ppNotifySink == NULL)
- COMPlusThrowArgumentNull(W("notifySink"));
-
- pINotify = (ITypeLibExporterNotifySink*)GetComIPFromObjectRef(ppNotifySink, MscorlibBinder::GetClass(CLASS__ITYPE_LIB_EXPORTER_NOTIFY_SINK));
- if (!pINotify)
- COMPlusThrow(kArgumentException, W("Arg_NoImporterCallback"));
-
- // If a name was specified then copy it to a temporary string.
- if (*ppTypeLibName != NULL)
- {
- int TypeLibNameLen = (*ppTypeLibName)->GetStringLength();
- szTypeLibName = new WCHAR[TypeLibNameLen + 1];
- memcpyNoGCRefs(szTypeLibName, (*ppTypeLibName)->GetBuffer(), TypeLibNameLen * sizeof(WCHAR));
- szTypeLibName[TypeLibNameLen] = 0;
- }
-
- // Retrieve the assembly from the AssemblyBuilder argument.
- if (*ppAssembly == NULL)
- COMPlusThrowNonLocalized(kArgumentNullException, W("assembly"));
-
- pAssembly = ((ASSEMBLYREF)*ppAssembly)->GetAssembly();
- _ASSERTE(pAssembly);
-
- if (IsAfContentType_WindowsRuntime(pAssembly->GetFlags()))
- COMPlusThrow(kArgumentException, W("Argument_AssemblyWinMD"));
-
- {
- GCX_PREEMP();
- ExportTypeLibFromLoadedAssembly(pAssembly, szTypeLibName, &pTLB, pINotify, Flags);
- }
-
- // Make sure we got a typelib back.
- _ASSERTE(pTLB);
-
- // Convert the ITypeLib interface pointer to a COM+ object.
- GetObjectRefFromComIP(pRetObj, pTLB, NULL);
-}
-
-// static
-void COMTypeLibConverter::LoadType(
- Module * pModule,
- mdTypeDef cl,
- TlbImporterFlags Flags)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM());
- }
- CONTRACTL_END;
-
- OBJECTREF pThrowable = NULL;
-
- GCPROTECT_BEGIN(pThrowable)
- {
- EX_TRY
- {
- // Load the EE class that represents the type, so that
- // the TypeDefToMethodTable rid map contains this entry
- // (They were going to be loaded, anyway, to generate comtypes)
- TypeHandle typeHnd;
- typeHnd = ClassLoader::LoadTypeDefThrowing(pModule, cl,
- ClassLoader::ThrowIfNotFound,
- ClassLoader::PermitUninstDefOrRef);
- }
- EX_CATCH
- {
- pThrowable = GET_THROWABLE();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- if (pThrowable != NULL)
- {
- // Only spit out a special message if PreventClassMembers is set.
- if ((Flags & TlbImporter_PreventClassMembers) == 0)
- {
- struct _gc
- {
- OBJECTREF pInnerException;
- OBJECTREF pThrowable;
- STRINGREF pMsg;
- } gc;
-
- gc.pInnerException = NULL;
- gc.pThrowable = NULL;
- gc.pMsg = NULL;
-
- GCPROTECT_BEGIN(gc);
- {
- MethodTable* pMT = MscorlibBinder::GetException(kSystemException);
-
- gc.pThrowable = AllocateObject(pMT);
- gc.pInnerException = pThrowable;
- ResMgrGetString(W("Arg_ImporterLoadFailure"), &gc.pMsg);
-
- MethodDescCallSite exceptionCtor(METHOD__SYSTEM_EXCEPTION__STR_EX_CTOR, &gc.pThrowable);
-
- ARG_SLOT args[] = { ObjToArgSlot(gc.pThrowable),
- ObjToArgSlot(gc.pMsg),
- ObjToArgSlot(gc.pInnerException) };
-
- exceptionCtor.Call(args);
-
- COMPlusThrow(gc.pThrowable);
- }
- GCPROTECT_END();
- }
-
- COMPlusThrow(pThrowable);
- }
- }
- GCPROTECT_END();
-}
-
-void COMTypeLibConverter::ConvertTypeLibToMetadataInternal(OBJECTREF* ppTypeLib,
- OBJECTREF* ppAsmBldr,
- OBJECTREF* ppModBldr,
- STRINGREF* ppNamespace,
- TlbImporterFlags Flags,
- OBJECTREF* ppNotifySink,
- OBJECTREF* pEventItfInfoList)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(IsProtectedByGCFrame (ppTypeLib));
- PRECONDITION(IsProtectedByGCFrame (ppAsmBldr));
- PRECONDITION(IsProtectedByGCFrame (ppModBldr));
- PRECONDITION(IsProtectedByGCFrame (ppNamespace));
- PRECONDITION(IsProtectedByGCFrame (ppNotifySink));
- PRECONDITION(IsProtectedByGCFrame (pEventItfInfoList));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- Module *pModule = NULL; // ModuleBuilder parameter.
- Assembly *pAssembly = NULL; // AssemblyBuilder parameter.
- REFLECTMODULEBASEREF pReflect = NULL; // ReflectModule passed as param.
- int cTypeDefs; // Count of imported TypeDefs.
- int i; // Loop control.
- mdTypeDef cl; // An imported TypeDef.
-
- NewArrayHolder<WCHAR> szNamespace = NULL; // The namespace to put the type in.
- NewPreempHolder<CImportTlb> pImporter = NULL; // The importer used to import the typelib.
- SafeComHolder<ITypeLib> pTLB = NULL; // TypeLib parameter.
- SafeComHolder<ITypeLibImporterNotifySink> pINotify = NULL; // Callback parameter.
-
- // Make sure the COMTypeLibConverter has been initialized.
- if (!m_bInitialized)
- Init();
-
- // Validate the flags.
- if ((Flags & ~TlbImporter_ValidFlags) != 0)
- COMPlusThrowArgumentOutOfRange(W("flags"), W("Argument_InvalidFlag"));
-
- // Retrieve the callback.
- MethodTable * pSinkMT = MscorlibBinder::GetClass(CLASS__ITYPE_LIB_IMPORTER_NOTIFY_SINK);
- pINotify = (ITypeLibImporterNotifySink*)GetComIPFromObjectRef(ppNotifySink, pSinkMT);
- if (!pINotify)
- COMPlusThrow(kArgumentException, W("Arg_NoImporterCallback"));
-
- pReflect = (REFLECTMODULEBASEREF) *ppModBldr;
- _ASSERTE(pReflect);
-
-
- pModule = pReflect->GetModule();
- _ASSERTE(pModule);
-
- // Suppress capturing while we dispatch events. This is a performance optimization to avoid
- // re-serializing metadata between each type. Instead, we suppress serialization while we bake all
- // the types and then re-enable it at the end (when this holder goes out of scope).
- _ASSERTE(pModule->IsReflection());
- ReflectionModule::SuppressMetadataCaptureHolder holderCapture(pModule->GetReflectionModule());
-
-
- // Retrieve the assembly from the AssemblyBuilder argument.
- pAssembly = ((ASSEMBLYREF)*ppAsmBldr)->GetAssembly();
- _ASSERTE(pAssembly);
-
- // Retrieve a pointer to the ITypeLib interface.
- pTLB = (ITypeLib*)GetComIPFromObjectRef(ppTypeLib, IID_ITypeLib);
- if (!pTLB)
- COMPlusThrow(kArgumentException, W("Arg_NoITypeLib"));
-
- // If a namespace was specified then copy it to a temporary string.
- if (*ppNamespace != NULL)
- {
- int NamespaceLen = (*ppNamespace)->GetStringLength();
- szNamespace = new WCHAR[NamespaceLen + 1];
- memcpyNoGCRefs(szNamespace, (*ppNamespace)->GetBuffer(), NamespaceLen * sizeof(WCHAR));
- szNamespace[NamespaceLen] = 0;
- }
-
- // Switch to preemptive GC before we call out to COM.
- {
- GCX_PREEMP();
-
- // Have to wrap the CImportTlb object in a call, because it has a destructor.
- TypeLibImporterWrapper(pTLB, NULL /*filename*/, szNamespace,
- pModule->GetEmitter(), pAssembly, pModule, pINotify,
- Flags, &pImporter);
- }
-
- // Enumerate the types imported from the typelib, and add them to the assembly's available type table.
- IMDInternalImport* pInternalImport = pModule->GetMDImport();
- HENUMTypeDefInternalHolder hEnum(pInternalImport);
-
- hEnum.EnumTypeDefInit();
- cTypeDefs = pInternalImport->EnumTypeDefGetCount(&hEnum);
-
- for (i=0; i<cTypeDefs; ++i)
- {
- BOOL success = pInternalImport->EnumTypeDefNext(&hEnum, &cl);
- _ASSERTE(success);
-
- pAssembly->AddType(pModule, cl);
- }
-
- // Allocate an empty array
- CreateItfInfoList(pEventItfInfoList);
-
-#ifdef _DEBUG
- if (!g_pConfig->TlbImpSkipLoading())
- {
-#endif // _DEBUG
- pInternalImport->EnumReset(&hEnum);
- for (i=0; i<cTypeDefs; ++i)
- {
- BOOL success = pInternalImport->EnumTypeDefNext(&hEnum, &cl);
- _ASSERTE(success);
-
- LoadType(pModule, cl, Flags);
- }
-
- // Retrieve the event interface list.
- GetEventItfInfoList(pImporter, pAssembly, pEventItfInfoList);
-#ifdef _DEBUG
- }
-#endif // _DEBUG
-}
-
-void COMTypeLibConverter::CreateItfInfoList(OBJECTREF* pEventItfInfoList)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(IsProtectedByGCFrame (pEventItfInfoList));
- }
- CONTRACTL_END;
-
- // Allocate the array list that will contain the event sources.
- SetObjectReference(pEventItfInfoList,
- AllocateObject(MscorlibBinder::GetClass(CLASS__ARRAY_LIST)),
- SystemDomain::GetCurrentDomain());
-
- MethodDescCallSite ctor(METHOD__ARRAY_LIST__CTOR, pEventItfInfoList);
-
- // Call the ArrayList constructor.
- ARG_SLOT CtorArgs[] =
- {
- ObjToArgSlot(*pEventItfInfoList)
- };
- ctor.Call(CtorArgs);
-}
-
-//*****************************************************************************
-//*****************************************************************************
-void COMTypeLibConverter::GetEventItfInfoList(CImportTlb *pImporter, Assembly *pAssembly, OBJECTREF *pEventItfInfoList)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pImporter));
- PRECONDITION(CheckPointer(pAssembly));
- PRECONDITION(IsProtectedByGCFrame (pEventItfInfoList));
- }
- CONTRACTL_END;
-
- UINT i;
- CQuickArray<ImpTlbEventInfo*> qbEvInfoList;
-
- // Retrieve the list of event interfaces.
- pImporter->GetEventInfoList(qbEvInfoList);
-
- // Iterate over TypeInfos.
- for (i = 0; i < qbEvInfoList.Size(); i++)
- {
- // Retrieve the Add method desc for the ArrayList.
- MethodDescCallSite addMeth(METHOD__ARRAY_LIST__ADD, pEventItfInfoList);
-
- // Retrieve the event interface info for the current CoClass.
- OBJECTREF EventItfInfoObj = GetEventItfInfo(pAssembly, qbEvInfoList[i]);
- _ASSERTE(EventItfInfoObj);
-
- // Add the event interface info to the list.
- ARG_SLOT AddArgs[] = {
- ObjToArgSlot(*pEventItfInfoList),
- ObjToArgSlot(EventItfInfoObj)
- };
- addMeth.Call(AddArgs);
- }
-} // LPVOID COMTypeLibConverter::GetTypeLibEventSourceList()
-
-//*****************************************************************************
-// Initialize the COMTypeLibConverter.
-//*****************************************************************************
-void COMTypeLibConverter::Init()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // Ensure COM is started up.
- EnsureComStarted();
-
- // Set the initialized flag to TRUE.
- m_bInitialized = TRUE;
-} // void COMTypeLibConverter::Init()
-
-//*****************************************************************************
-// Given an imported class in an assembly, generate a list of event sources.
-//*****************************************************************************
-OBJECTREF COMTypeLibConverter::GetEventItfInfo(Assembly *pAssembly, ImpTlbEventInfo *pImpTlbEventInfo)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pAssembly));
- PRECONDITION(CheckPointer(pImpTlbEventInfo));
- }
- CONTRACTL_END;
-
- OBJECTREF RetObj = NULL;
-
- struct _gc
- {
- OBJECTREF EventItfInfoObj;
- STRINGREF EventItfNameStrObj;
- STRINGREF SrcItfNameStrObj;
- STRINGREF EventProvNameStrObj;
- OBJECTREF AssemblyObj;
- OBJECTREF SrcItfAssemblyObj;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc)
- {
- // Create the EventSource object.
- gc.EventItfInfoObj = AllocateObject(MscorlibBinder::GetClass(CLASS__TCE_EVENT_ITF_INFO));
-
- // Retrieve the assembly object.
- gc.AssemblyObj = pAssembly->GetExposedObject();
-
- // Retrieve the source interface assembly object (may be the same assembly).
- gc.SrcItfAssemblyObj = pImpTlbEventInfo->SrcItfAssembly->GetExposedObject();
-
- // Prepare the constructor arguments.
- gc.EventItfNameStrObj = StringObject::NewString(pImpTlbEventInfo->szEventItfName);
- gc.SrcItfNameStrObj = StringObject::NewString(pImpTlbEventInfo->szSrcItfName);
- gc.EventProvNameStrObj = StringObject::NewString(pImpTlbEventInfo->szEventProviderName);
-
- MethodDescCallSite ctor(METHOD__TCE_EVENT_ITF_INFO__CTOR, &gc.EventItfInfoObj);
-
- // Call the EventItfInfo constructor.
- ARG_SLOT CtorArgs[] = {
- ObjToArgSlot(gc.EventItfInfoObj),
- ObjToArgSlot(gc.EventItfNameStrObj),
- ObjToArgSlot(gc.SrcItfNameStrObj),
- ObjToArgSlot(gc.EventProvNameStrObj),
- ObjToArgSlot(gc.AssemblyObj),
- ObjToArgSlot(gc.SrcItfAssemblyObj),
- };
- ctor.Call(CtorArgs);
-
- RetObj = gc.EventItfInfoObj;
- }
- GCPROTECT_END();
-
- return RetObj;
-} // OBJECTREF COMTypeLibConverter::GetEventSourceInfo()
-
-//*****************************************************************************
-// Given the string persisted from a TypeLib export, recreate the assembly
-// reference.
-//*****************************************************************************
-mdAssemblyRef DefineAssemblyRefForExportedAssembly(
- LPCWSTR pszFullName, // Full name of the assembly.
- IUnknown *pIMeta) // Metadata emit interface.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pszFullName));
- PRECONDITION(CheckPointer(pIMeta));
- }
- CONTRACTL_END;
-
- mdAssemblyRef ar=0;
- HRESULT hr; // A result.
- AssemblySpec spec; // "Name" of assembly.
- CQuickArray<char> rBuf;
- int iLen;
- SafeComHolder<IMetaDataAssemblyEmit> pMeta=0; // Emit interface.
-
- iLen = WszWideCharToMultiByte(CP_ACP,0, pszFullName,-1, 0,0, 0,0);
- IfFailGo(rBuf.ReSizeNoThrow(iLen+1));
- WszWideCharToMultiByte(CP_ACP,0, pszFullName,-1, rBuf.Ptr(),iLen+1, 0,0);
-
- // Restore the AssemblySpec data.
- IfFailGo(spec.Init(rBuf.Ptr()));
-
- // Make sure we have the correct pointer type.
- IfFailGo(SafeQueryInterface(pIMeta, IID_IMetaDataAssemblyEmit, (IUnknown**)&pMeta));
-
- // Create the assemblyref token.
- IfFailGo(spec.EmitToken(pMeta, &ar));
-
-ErrExit:
- return ar;
-} // mdAssemblyRef DefineAssemblyRefForExportedAssembly()
-
-//*****************************************************************************
-// Public helper function used by typelib converter to create AssemblyRef
-// for a referenced typelib.
-//*****************************************************************************
-extern mdAssemblyRef DefineAssemblyRefForImportedTypeLib(
- void *pvAssembly, // Assembly importing the typelib.
- void *pvModule, // Module importing the typelib.
- IUnknown *pIMeta, // IMetaData* from import module.
- IUnknown *pIUnk, // IUnknown to referenced Assembly.
- BSTR *pwzNamespace, // The namespace of the resolved assembly.
- BSTR *pwzAsmName, // The name of the resolved assembly.
- Assembly **ppAssemblyRef) // The resolved assembly.
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pvAssembly));
- PRECONDITION(CheckPointer(pvModule));
- PRECONDITION(CheckPointer(pIMeta));
- PRECONDITION(CheckPointer(pIUnk));
- PRECONDITION(CheckPointer(pwzNamespace));
- PRECONDITION(CheckPointer(pwzAsmName));
- PRECONDITION(CheckPointer(ppAssemblyRef, NULL_OK));
- }
- CONTRACTL_END;
-
- // This is a workaround to allow an untyped param. To really fix, move imptlb to this project,
- // and out of the metadata project. Once here, imptlb can just reference any of
- // the .h files in this project.
- Assembly* pAssembly = reinterpret_cast<Assembly*>(pvAssembly);
- Module* pTypeModule = reinterpret_cast<Module*>(pvModule);
- HRESULT hr;
- Assembly* pRefdAssembly = NULL;
- IMetaDataEmit* pEmitter = NULL;
- MethodTable* pAssemblyClass = NULL;
- mdAssemblyRef ar = mdAssemblyRefNil;
- Module* pManifestModule = NULL;
- mdTypeDef td = 0;
- LPCSTR szName = NULL;
- LPCSTR szNamespace = NULL;
- CQuickBytes qb;
- WCHAR* wszBuff = (WCHAR*) qb.AllocThrows((MAX_CLASSNAME_LENGTH+1) * sizeof(WCHAR));
- SString szRefdAssemblyName;
- IMDInternalImport* pRefdMDImport = NULL;
- SafeComHolder<IMetaDataAssemblyEmit> pAssemEmitter = NULL;
-
- GCX_COOP();
-
- // Initialize the output strings to NULL.
- *pwzNamespace = NULL;
- *pwzAsmName = NULL;
- BSTRHolder local_pwzNamespace = NULL;
- BSTRHolder local_pwzAsmName = NULL;
-
- // Get the Referenced Assembly object from the IUnknown.
- PREFIX_ASSUME(pIUnk != NULL);
- ASSEMBLYREF RefdAsmObj = NULL;
- GCPROTECT_BEGIN(RefdAsmObj);
- GetObjectRefFromComIP((OBJECTREF*)&RefdAsmObj, pIUnk, pAssemblyClass);
- PREFIX_ASSUME(RefdAsmObj != NULL);
-
- // Get the internal assembly from the assembly object.
- pRefdAssembly = RefdAsmObj->GetAssembly();
- GCPROTECT_END();
- PREFIX_ASSUME(pRefdAssembly != NULL);
-
- // Return the assembly if asked for
- if (ppAssemblyRef)
- *ppAssemblyRef = pRefdAssembly;
-
- // Get the manifest module for the importing and the referenced assembly.
- pManifestModule = pAssembly->GetManifestModule();
-
- // Define the AssemblyRef in the global assembly.
- pEmitter = pManifestModule->GetEmitter();
- _ASSERTE(pEmitter);
- IfFailGo(SafeQueryInterface(pEmitter, IID_IMetaDataAssemblyEmit, (IUnknown**) &pAssemEmitter));
- ar = pAssembly->AddAssemblyRef(pRefdAssembly, pAssemEmitter);
- pAssemEmitter.Release();
-
- // Add the assembly ref token and the manifest module it is referring to the manifest module's rid map.
- pManifestModule->StoreAssemblyRef(ar, pRefdAssembly);
-
- // Add assembly ref in module manifest.
- IfFailGo(SafeQueryInterface(pIMeta, IID_IMetaDataAssemblyEmit, (IUnknown**) &pAssemEmitter));
- ar = pAssembly->AddAssemblyRef(pRefdAssembly, pAssemEmitter);
-
- // Add the assembly ref token and the manifest module it is referring to the rid map of the module we are
- // emiting into.
- pTypeModule->StoreAssemblyRef(ar, pRefdAssembly);
-
- // Retrieve the first typedef in the assembly.
- {
- ModuleIterator i = pRefdAssembly->IterateModules();
- Module *pRefdModule = NULL;
-
- while (i.Next())
- {
- pRefdModule = i.GetModule();
- pRefdMDImport = pRefdModule->GetMDImport();
- HENUMTypeDefInternalHolder hTDEnum(pRefdMDImport);
-
- IfFailGo(hTDEnum.EnumTypeDefInitNoThrow());
-
- if (pRefdMDImport->EnumTypeDefNext(&hTDEnum, &td) == true)
- {
- IfFailGo(pRefdMDImport->GetNameOfTypeDef(td, &szName, &szNamespace));
- break;
- }
- }
- }
-
- // DefineAssemblyRefForImportedTypeLib should never be called for assemblies that
- // do not contain any types so we better have found one.
- _ASSERTE(szNamespace);
-
- // Give the namespace back to the caller.
- WszMultiByteToWideChar(CP_UTF8,0, szNamespace, -1, wszBuff, MAX_CLASSNAME_LENGTH);
- local_pwzNamespace = SysAllocString(wszBuff);
- IfNullGo(local_pwzNamespace);
-
- // Give the assembly name back to the caller.
- pRefdAssembly->GetDisplayName(szRefdAssemblyName);
- local_pwzAsmName = SysAllocString(szRefdAssemblyName);
- IfNullGo(local_pwzAsmName);
-
-ErrExit:
- if (FAILED(hr))
- {
- ar = mdAssemblyRefNil;
- }
- else
- {
- local_pwzNamespace.SuppressRelease();
- local_pwzAsmName.SuppressRelease();
- *pwzNamespace = local_pwzNamespace;
- *pwzAsmName = local_pwzAsmName;
- }
-
- return ar;
-} // mdAssemblyRef DefineAssemblyRefForImportedTypeLib()
-
-
-
-//*****************************************************************************
-// A typelib exporter.
-//*****************************************************************************
-FCIMPL4(Object*, COMTypeLibConverter::ConvertAssemblyToTypeLib, Object* AssemblyUNSAFE, StringObject* TypeLibNameUNSAFE, DWORD Flags, Object* NotifySinkUNSAFE)
-{
- FCALL_CONTRACT;
-
- OBJECTREF RetObj = NULL;
- struct _gc
- {
- OBJECTREF Assembly;
- STRINGREF TypeLibName;
- OBJECTREF NotifySink;
- OBJECTREF RetObj;
- } gc;
-
- gc.Assembly = (OBJECTREF) AssemblyUNSAFE;
- gc.TypeLibName = (STRINGREF) TypeLibNameUNSAFE;
- gc.NotifySink = (OBJECTREF) NotifySinkUNSAFE;
- gc.RetObj = NULL;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
-
- ConvertAssemblyToTypeLibInternal(&gc.Assembly, &gc.TypeLibName, Flags, &gc.NotifySink, &gc.RetObj);
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(gc.RetObj);
-} // LPVOID COMTypeLibConverter::ConvertAssemblyToTypeLib()
-FCIMPLEND
-
-//*****************************************************************************
-// Import a typelib as metadata. Doesn't add TCE adapters.
-//*****************************************************************************
-FCIMPL7(void, COMTypeLibConverter::ConvertTypeLibToMetadata, Object* TypeLibUNSAFE, Object* AsmBldrUNSAFE, Object* ModBldrUNSAFE, StringObject* NamespaceUNSAFE, TlbImporterFlags Flags, Object* NotifySinkUNSAFE, OBJECTREF* pEventItfInfoList)
-{
- FCALL_CONTRACT;
-
- struct _gc
- {
- OBJECTREF TypeLib;
- OBJECTREF AsmBldr;
- OBJECTREF ModBldr;
- STRINGREF Namespace;
- OBJECTREF NotifySink;
- } gc;
-
- gc.TypeLib = (OBJECTREF) TypeLibUNSAFE;
- gc.AsmBldr = (OBJECTREF) AsmBldrUNSAFE;
- gc.ModBldr = (OBJECTREF) ModBldrUNSAFE;
- gc.Namespace = (STRINGREF) NamespaceUNSAFE;
- gc.NotifySink = (OBJECTREF) NotifySinkUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_PROTECT(gc);
-
- ASSUME_BYREF_FROM_JIT_STACK_BEGIN(pEventItfInfoList);
- ConvertTypeLibToMetadataInternal(&gc.TypeLib, &gc.AsmBldr, &gc.ModBldr, &gc.Namespace, Flags, &gc.NotifySink, pEventItfInfoList);
- ASSUME_BYREF_FROM_JIT_STACK_END();
-
- HELPER_METHOD_FRAME_END();
-} // void COMTypeLibConverter::ConvertTypeLibToMetadata()
-FCIMPLEND
diff --git a/src/vm/comtypelibconverter.h b/src/vm/comtypelibconverter.h
deleted file mode 100644
index f835999794..0000000000
--- a/src/vm/comtypelibconverter.h
+++ /dev/null
@@ -1,107 +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.
-
-/*============================================================
-**
-** Header: COMTypeLibConverter.h
-**
-**
-** Purpose: Definition of the native methods used by the
-** typelib converter.
-**
-**
-===========================================================*/
-
-#ifndef _COMTYPELIBCONVERTER_H
-#define _COMTYPELIBCONVERTER_H
-
-#ifndef FEATURE_COMINTEROP
-#error FEATURE_COMINTEROP is required for this file
-#endif // FEATURE_COMINTEROP
-#ifndef FEATURE_COMINTEROP_TLB_SUPPORT
-#error FEATURE_COMINTEROP_TLB_SUPPORT is required for this file
-#endif // FEATURE_COMINTEROP
-
-#include "vars.hpp"
-
-struct ITypeLibImporterNotifySink;
-class ImpTlbEventInfo;
-
-
-enum TlbImporterFlags
-{
- TlbImporter_PrimaryInteropAssembly = 0x00000001, // Generate a PIA.
- TlbImporter_UnsafeInterfaces = 0x00000002, // Generate unsafe interfaces.
- TlbImporter_SafeArrayAsSystemArray = 0x00000004, // Safe array import control.
- TlbImporter_TransformDispRetVals = 0x00000008, // Disp only itf [out, retval] transformation.
- TlbImporter_PreventClassMembers = 0x00000010, // Prevent adding members to class.
- TlbImporter_SerializableValueClasses = 0x00000020, // Mark value classes as serializable.
- TlbImporter_ImportAsX86 = 0x00000100, // Import to a 32-bit assembly
- TlbImporter_ImportAsX64 = 0x00000200, // Import to an x64 assembly
- TlbImporter_ImportAsItanium = 0x00000400, // Import to an itanium assembly
- TlbImporter_ImportAsAgnostic = 0x00000800, // Import to an agnostic assembly
- TlbImporter_ReflectionOnlyLoading = 0x00001000, // Use ReflectionOnly loading.
- TlbImporter_NoDefineVersionResource = 0x00002000, // Don't call AssemblyBuilder.DefineVersionResource
- TlbImporter_ImportAsArm = 0x00004000, // Import to an ARM assembly
- TlbImporter_ValidFlags = TlbImporter_PrimaryInteropAssembly |
- TlbImporter_UnsafeInterfaces |
- TlbImporter_SafeArrayAsSystemArray |
- TlbImporter_TransformDispRetVals |
- TlbImporter_PreventClassMembers |
- TlbImporter_SerializableValueClasses |
- TlbImporter_ImportAsX86 |
- TlbImporter_ImportAsX64 |
- TlbImporter_ImportAsItanium |
- TlbImporter_ImportAsAgnostic |
- TlbImporter_ReflectionOnlyLoading |
- TlbImporter_NoDefineVersionResource |
- TlbImporter_ImportAsArm
-};
-
-// Note that the second hex digit is reserved
-enum TlbExporterFlags
-{
- TlbExporter_OnlyReferenceRegistered = 0x00000001, // Only reference an external typelib if it is registered.
- TlbExporter_CallerResolvedReferences = 0x00000002, // Always allow caller to resolve typelib references first
- TlbExporter_OldNames = 0x00000004, // Do not ignore non COM visible types when doing name decoration.
-// TlbExporter_Unused = 0x00000008, // This is currently unused - feel free to use this for another switch
- TlbExporter_ExportAs32Bit = 0x00000010, // Export the type library using 32-bit semantics
- TlbExporter_ExportAs64Bit = 0x00000020, // Export the type library using 64-bit semantics
-// TlbExporter_Reserved = 0x00000040, // Do not use this
-// TlbExporter_Reserved = 0x00000080, // Do not use this
- TlbExporter_ValidFlags = TlbExporter_OnlyReferenceRegistered |
- TlbExporter_CallerResolvedReferences |
- TlbExporter_OldNames |
- TlbExporter_ExportAs32Bit |
- TlbExporter_ExportAs64Bit
-};
-
-#define TlbExportAsMask 0x000000F0
-#define TlbExportAs32Bit(x) ((TlbExportAsMask & x) == TlbExporter_ExportAs32Bit)
-#define TlbExportAs64Bit(x) ((TlbExportAsMask & x) == TlbExporter_ExportAs64Bit)
-#define TlbExportAsDefault(x) ((!TlbExportAs32Bit(x)) && (!TlbExportAs64Bit(x)))
-
-class COMTypeLibConverter
-{
-public:
- static FCDECL4(Object*, ConvertAssemblyToTypeLib, Object* AssemblyUNSAFE, StringObject* TypeLibNameUNSAFE, DWORD Flags, Object* NotifySinkUNSAFE);
- static FCDECL7(void, ConvertTypeLibToMetadata, Object* TypeLibUNSAFE, Object* AsmBldrUNSAFE, Object* ModBldrUNSAFE, StringObject* NamespaceUNSAFE, TlbImporterFlags Flags, Object* NotifySinkUNSAFE, OBJECTREF* pEventItfInfoList);
-
-private:
- static void Init();
- static void CreateItfInfoList(OBJECTREF* pEventItfInfoList);
- static void GetEventItfInfoList(CImportTlb *pImporter, Assembly *pAssembly, OBJECTREF *pEventItfInfoList);
- static OBJECTREF GetEventItfInfo(Assembly *pAssembly, ImpTlbEventInfo *pImpTlbEventInfo);
- static void TypeLibImporterWrapper(ITypeLib *pITLB, LPCWSTR szFname, LPCWSTR szNamespace, IMetaDataEmit *pEmit, Assembly *pAssembly, Module *pModule, ITypeLibImporterNotifySink *pNotify, TlbImporterFlags flags, CImportTlb **ppImporter);
-
- static void ConvertAssemblyToTypeLibInternal(OBJECTREF* ppAssembly, STRINGREF* ppTypeLibName, DWORD Flags, OBJECTREF* ppNotifySink, OBJECTREF* pRetObj);
- static void COMTypeLibConverter::LoadType(Module * pModule,
- mdTypeDef cl,
- TlbImporterFlags Flags);
- static void ConvertTypeLibToMetadataInternal(OBJECTREF* ppTypeLib, OBJECTREF* ppAsmBldr, OBJECTREF* ppModBldr, STRINGREF* ppNamespace, TlbImporterFlags Flags, OBJECTREF* ppNotifySink, OBJECTREF* pEventItfInfoList);
-
- static BOOL m_bInitialized;
-};
-
-#endif // _COMTYPELIBCONVERTER_H
diff --git a/src/vm/comutilnative.cpp b/src/vm/comutilnative.cpp
index 41655cb5b0..b75f684992 100644
--- a/src/vm/comutilnative.cpp
+++ b/src/vm/comutilnative.cpp
@@ -40,6 +40,8 @@
#include "comcache.h"
#endif // FEATURE_COMINTEROP
+#include "arraynative.inl"
+
#define STACK_OVERFLOW_MESSAGE W("StackOverflowException")
//These are defined in System.ParseNumbers and should be kept in sync.
@@ -777,50 +779,7 @@ FCIMPL1(FC_BOOL_RET, ExceptionNative::IsTransient, INT32 hresult)
}
FCIMPLEND
-#ifndef FEATURE_CORECLR
-
-FCIMPL3(StringObject *, ExceptionNative::StripFileInfo, Object *orefExcepUNSAFE, StringObject *orefStrUNSAFE, CLR_BOOL isRemoteStackTrace)
-{
- FCALL_CONTRACT;
-
- OBJECTREF orefExcep = ObjectToOBJECTREF(orefExcepUNSAFE);
- STRINGREF orefStr = (STRINGREF)ObjectToOBJECTREF(orefStrUNSAFE);
-
- if (orefStr == NULL)
- {
- return NULL;
- }
-
- HELPER_METHOD_FRAME_BEGIN_RET_2(orefExcep, orefStr);
-
- if (isRemoteStackTrace)
- {
- if (!AppX::IsAppXProcess() && ExceptionTypeOverridesStackTraceGetter(orefExcep->GetMethodTable()))
- {
- // In classic processes, the remote stack trace could have been generated using a custom get_StackTrace
- // override which means that we would not be able to parse is - strip the whole string by returning NULL.
- orefStr = NULL;
- }
- }
-
- if (orefStr != NULL)
- {
- SString stackTrace;
- orefStr->GetSString(stackTrace);
- StripFileInfoFromStackTrace(stackTrace);
-
- orefStr = AllocateString(stackTrace);
- }
-
- HELPER_METHOD_FRAME_END();
- return (StringObject *)OBJECTREFToObject(orefStr);
-}
-FCIMPLEND
-
-#endif // !FEATURE_CORECLR
-
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
// This FCall sets a flag against the thread exception state to indicate to
// IL_Throw and the StackTraceInfo implementation to account for the fact
// that we have restored a foreign exception dispatch details.
@@ -1021,7 +980,6 @@ FCIMPL1(Object*, ExceptionNative::CopyDynamicMethods, Object* pDynamicMethodsUNS
}
FCIMPLEND
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
BSTR BStrFromString(STRINGREF s)
{
@@ -1538,11 +1496,28 @@ FCIMPL5(VOID, Buffer::InternalBlockCopy, ArrayBase *src, int srcOffset, ArrayBas
}
FCIMPLEND
+void QCALLTYPE MemoryNative::Clear(void *dst, size_t length)
+{
+ QCALL_CONTRACT;
+
+ memset(dst, 0, length);
+}
+
+FCIMPL3(VOID, MemoryNative::BulkMoveWithWriteBarrier, void *dst, void *src, size_t byteCount)
+{
+ FCALL_CONTRACT;
+
+ InlinedMemmoveGCRefsHelper(dst, src, byteCount);
+
+ FC_GC_POLL();
+}
+FCIMPLEND
+
void QCALLTYPE Buffer::MemMove(void *dst, void *src, size_t length)
{
QCALL_CONTRACT;
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_CORESYSTEM)
+#if !defined(FEATURE_CORESYSTEM)
// Callers of memcpy do expect and handle access violations in some scenarios.
// Access violations in the runtime dll are turned into fail fast by the vector exception handler by default.
// We need to supress this behavior for CoreCLR using AVInRuntimeImplOkayHolder because of memcpy is statically linked in.
@@ -1802,9 +1777,9 @@ int QCALLTYPE GCInterface::StartNoGCRegion(INT64 totalSize, BOOL lohSizeKnown, I
GCX_COOP();
retVal = GCHeapUtilities::GetGCHeap()->StartNoGCRegion((ULONGLONG)totalSize,
- lohSizeKnown,
+ !!lohSizeKnown,
(ULONGLONG)lohSize,
- disallowFullBlockingGC);
+ !!disallowFullBlockingGC);
END_QCALL;
@@ -1893,7 +1868,7 @@ void QCALLTYPE GCInterface::Collect(INT32 generation, INT32 mode)
//We don't need to check the top end because the GC will take care of that.
GCX_COOP();
- GCHeapUtilities::GetGCHeap()->GarbageCollect(generation, FALSE, mode);
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(generation, false, mode);
END_QCALL;
}
@@ -2356,7 +2331,7 @@ NOINLINE void GCInterface::GarbageCollectModeAny(int generation)
CONTRACTL_END;
GCX_COOP();
- GCHeapUtilities::GetGCHeap()->GarbageCollect(generation, FALSE, collection_non_blocking);
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(generation, false, collection_non_blocking);
}
//
@@ -2609,9 +2584,23 @@ FCIMPL2_IV(INT64,COMInterlocked::ExchangeAdd64, INT64 *location, INT64 value)
}
FCIMPLEND
+FCIMPL0(void, COMInterlocked::FCMemoryBarrier)
+{
+ FCALL_CONTRACT;
+
+ MemoryBarrier();
+ FC_GC_POLL();
+}
+FCIMPLEND
+
#include <optdefault.h>
+void QCALLTYPE COMInterlocked::MemoryBarrierProcessWide()
+{
+ QCALL_CONTRACT;
+ FlushProcessWriteBuffers();
+}
FCIMPL6(INT32, ManagedLoggingHelper::GetRegistryLoggingValues, CLR_BOOL* bLoggingEnabled, CLR_BOOL* bLogToConsole, INT32 *iLogLevel, CLR_BOOL* bPerfWarnings, CLR_BOOL* bCorrectnessWarnings, CLR_BOOL* bSafeHandleStackTraces)
{
@@ -2853,67 +2842,8 @@ FCIMPL1(INT32, ValueTypeHelper::GetHashCodeOfPtr, LPVOID ptr)
}
FCIMPLEND
-#ifndef FEATURE_CORECLR
-FCIMPL1(OBJECTHANDLE, SizedRefHandle::Initialize, Object* _obj)
-{
- FCALL_CONTRACT;
-
- OBJECTHANDLE result = 0;
- OBJECTREF obj(_obj);
-
- HELPER_METHOD_FRAME_BEGIN_RET_0();
-
- result = GetAppDomain()->CreateSizedRefHandle(obj);
-
- HELPER_METHOD_FRAME_END();
-
- return result;
-}
-FCIMPLEND
-
-FCIMPL1(VOID, SizedRefHandle::Free, OBJECTHANDLE handle)
-{
- FCALL_CONTRACT;
-
- _ASSERTE(handle != NULL);
-
- HELPER_METHOD_FRAME_BEGIN_0();
-
- DestroySizedRefHandle(handle);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-FCIMPL1(LPVOID, SizedRefHandle::GetTarget, OBJECTHANDLE handle)
-{
- FCALL_CONTRACT;
-
- _ASSERTE(handle != NULL);
-
- OBJECTREF objRef = NULL;
-
- objRef = ObjectFromHandle(handle);
-
- FCUnique(0x33);
- return *((LPVOID*)&objRef);
-}
-FCIMPLEND
-
-FCIMPL1(INT64, SizedRefHandle::GetApproximateSize, OBJECTHANDLE handle)
-{
- FCALL_CONTRACT;
-
- _ASSERTE(handle != NULL);
-
- return (INT64)HndGetHandleExtraInfo(handle);
-}
-FCIMPLEND
-#endif //!FEATURE_CORECLR
-#ifdef FEATURE_CORECLR
COMNlsHashProvider COMNlsHashProvider::s_NlsHashProvider;
-#endif // FEATURE_CORECLR
COMNlsHashProvider::COMNlsHashProvider()
diff --git a/src/vm/comutilnative.h b/src/vm/comutilnative.h
index dce7ec600b..41df265e91 100644
--- a/src/vm/comutilnative.h
+++ b/src/vm/comutilnative.h
@@ -26,9 +26,6 @@
#include "windows.h"
#undef GetCurrentTime
-#ifndef FEATURE_CORECLR
-#include <winnls.h>
-#endif
#ifdef FEATURE_RANDOMIZED_STRING_HASHING
#pragma warning(push)
@@ -98,13 +95,11 @@ public:
static FCDECL1(FC_BOOL_RET, IsTransient, INT32 hresult);
static FCDECL3(StringObject *, StripFileInfo, Object *orefExcepUNSAFE, StringObject *orefStrUNSAFE, CLR_BOOL isRemoteStackTrace);
static void QCALLTYPE GetMessageFromNativeResources(ExceptionMessageKind kind, QCall::StringHandleOnStack retMesg);
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
static FCDECL0(VOID, PrepareForForeignExceptionRaise);
static FCDECL1(Object*, CopyStackTrace, Object* pStackTraceUNSAFE);
static FCDECL1(Object*, CopyDynamicMethods, Object* pDynamicMethodsUNSAFE);
static FCDECL3(VOID, GetStackTracesDeepCopy, Object* pExceptionObjectUnsafe, Object **pStackTraceUnsafe, Object **pDynamicMethodsUnsafe);
static FCDECL3(VOID, SaveStackTracesFromDeepCopy, Object* pExceptionObjectUnsafe, Object *pStackTraceUnsafe, Object *pDynamicMethodsUnsafe);
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
// NOTE: caller cleans up any partially initialized BSTRs in pED
@@ -115,6 +110,12 @@ public:
static FCDECL0(INT32, GetExceptionCode);
};
+class MemoryNative
+{
+public:
+ static void QCALLTYPE Clear(void *dst, size_t length);
+ static FCDECL3(VOID, BulkMoveWithWriteBarrier, void *dst, void *src, size_t byteCount);
+};
//
// Buffer
@@ -233,6 +234,9 @@ public:
static FCDECL2_IV(INT64, ExchangeAdd64, INT64 *location, INT64 value);
static FCDECL2_VV(void, ExchangeGeneric, FC_TypedByRef location, FC_TypedByRef value);
static FCDECL3_VVI(void, CompareExchangeGeneric, FC_TypedByRef location, FC_TypedByRef value, LPVOID comparand);
+
+ static FCDECL0(void, FCMemoryBarrier);
+ static void QCALLTYPE MemoryBarrierProcessWide();
};
class ManagedLoggingHelper {
@@ -249,35 +253,6 @@ public:
static FCDECL1(INT32, GetHashCodeOfPtr, LPVOID ptr);
};
-#ifndef FEATURE_CORECLR
-class SizedRefHandle
-{
-public:
- static FCDECL1(OBJECTHANDLE, Initialize, Object* _obj);
- static FCDECL1(VOID, Free, OBJECTHANDLE handle);
- static FCDECL1(LPVOID, GetTarget, OBJECTHANDLE handle);
- static FCDECL1(INT64, GetApproximateSize, OBJECTHANDLE handle);
-};
-
-typedef BOOL (*PFN_IS_NLS_DEFINED_STRING)(NLS_FUNCTION, DWORD, LPNLSVERSIONINFO, LPCWSTR, INT);
-typedef INT (*PFN_COMPARE_STRING_EX)(LPCWSTR, DWORD, LPCWSTR, INT, LPCWSTR, INT, LPNLSVERSIONINFO, LPVOID, LPARAM);
-typedef INT (*PFN_LC_MAP_STRING_EX)(LPCWSTR, DWORD, LPCWSTR, INT, LPWSTR, INT, LPNLSVERSIONINFO, LPVOID, LPARAM);
-typedef INT (*PFN_FIND_NLS_STRING_EX)(LPCWSTR, DWORD, LPCWSTR, INT, LPCWSTR, INT, LPINT, LPNLSVERSIONINFO, LPVOID, LPARAM);
-typedef INT (*PFN_COMPARE_STRING_ORDINAL)(LPCWSTR, INT, LPCWSTR, INT, BOOL);
-typedef BOOL (*PFN_GET_NLS_VERSION_EX)(NLS_FUNCTION, LPCWSTR, LPNLSVERSIONINFOEX);
-typedef INT (*PFN_FIND_STRING_ORDINAL)(DWORD, LPCWSTR, INT, LPCWSTR, INT, BOOL);
-
-class COMNlsCustomSortLibrary {
-public:
- PFN_IS_NLS_DEFINED_STRING pIsNLSDefinedString;
- PFN_COMPARE_STRING_EX pCompareStringEx;
- PFN_LC_MAP_STRING_EX pLCMapStringEx;
- PFN_FIND_NLS_STRING_EX pFindNLSStringEx;
- PFN_COMPARE_STRING_ORDINAL pCompareStringOrdinal;
- PFN_GET_NLS_VERSION_EX pGetNLSVersionEx;
- PFN_FIND_STRING_ORDINAL pFindStringOrdinal;
-};
-#endif //!FEATURE_CORECLR
typedef const BYTE * PCBYTE;
@@ -289,9 +264,7 @@ public:
INT32 HashSortKey(PCBYTE pSrc, SIZE_T cbSrc, BOOL forceRandomHashing, INT64 additionalEntropy);
INT32 HashiStringKnownLower80(LPCWSTR lpszStr, INT32 strLen, BOOL forceRandomHashing, INT64 additionalEntropy);
-#ifdef FEATURE_CORECLR
static COMNlsHashProvider s_NlsHashProvider;
-#endif // FEATURE_CORECLR
#ifdef FEATURE_RANDOMIZED_STRING_HASHING
void SetUseRandomHashing(BOOL useRandomHashing) { LIMITED_METHOD_CONTRACT; bUseRandomHashing = useRandomHashing; }
diff --git a/src/vm/comwaithandle.cpp b/src/vm/comwaithandle.cpp
index 13886c3de8..50bff8b71e 100644
--- a/src/vm/comwaithandle.cpp
+++ b/src/vm/comwaithandle.cpp
@@ -181,11 +181,6 @@ FCIMPL4(INT32, WaitHandleNative::CorWaitOneNative, SafeHandle* safeWaitHandleUNS
Context* defaultContext;
defaultContext = pThread->GetDomain()->GetDefaultContext();
_ASSERTE(defaultContext);
-#ifndef FEATURE_CORECLR
- // DoAppropriateWait calls LeaveRuntime/EnterRuntime which may cause the current
- // fiber to be re-scheduled.
- ThreadAffinityAndCriticalRegionHolder affinityAndCriticalRegionHolder(hasThreadAffinity);
-#endif
SafeHandleHolder shh(&sh);
// Note that SafeHandle is a GC object, and RequestCallback and
// DoAppropriateWait work on an array of handles. Don't pass the address
@@ -193,18 +188,7 @@ FCIMPL4(INT32, WaitHandleNative::CorWaitOneNative, SafeHandle* safeWaitHandleUNS
// array.
HANDLE handles[1];
handles[0] = sh->GetHandle();
-#ifdef FEATURE_REMOTING
- if (exitContext != NULL &&
- targetContext != defaultContext)
- {
- Context::WaitArgs waitOneArgs = {1, handles, TRUE, timeout, TRUE, &res};
- Context::CallBackInfo callBackInfo = {Context::Wait_callback, (void*) &waitOneArgs};
- Context::RequestCallBack(CURRENT_APPDOMAIN_ID,defaultContext, &callBackInfo);
- }
- else
-#else
_ASSERTE(exitContext == NULL || targetContext == defaultContext);
-#endif
{
// Support for pause/resume (FXFREEZE)
while(true)
@@ -222,18 +206,6 @@ FCIMPL4(INT32, WaitHandleNative::CorWaitOneNative, SafeHandle* safeWaitHandleUNS
retVal = res;
-#ifndef FEATURE_CORECLR
- if (res == WAIT_OBJECT_0 && hasThreadAffinity) {
- affinityAndCriticalRegionHolder.SuppressRelease();
- }
- else if(res == WAIT_ABANDONED_0) {
- // WAIT_ABANDONED means the specified object is a mutex object that was not released by the thread
- // that owned the mutex object before the owning thread terminated.
- // Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.
- _ASSERTE(hasThreadAffinity);
- affinityAndCriticalRegionHolder.SuppressRelease();
- }
-#endif
HELPER_METHOD_FRAME_END();
return retVal;
@@ -259,26 +231,14 @@ FCIMPL4(INT32, WaitHandleNative::CorWaitMultipleNative, Object* waitObjectsUNSAF
// Because it's not, CoreCLR will allow WaitAll on STA threads.
// But fixing this would be a breaking change at this point, since we already shipped
// SL 2 and 3 this way.
- // We we'll also check for FEATURE_CORECLR here, so that if we enable FEATURE_COMINTEROP
- // on CoreCLR we won't break anyone.
// Perhaps in a future release we can fix this, if we aren't quite so concerned about
// compatibility....
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
- if (waitForAll && numWaiters > 1 && pThread->GetApartment() == Thread::AS_InSTA) {
- COMPlusThrow(kNotSupportedException, W("NotSupported_WaitAllSTAThread"));
- }
-#endif // FEATURE_COMINTEROP && !FEATURE_CORECLR
WaitHandleArrayHolder arrayHolder;
arrayHolder.Initialize(numWaiters, (PTRARRAYREF*) &waitObjects);
pWaitObjects = (PTRARRAYREF)waitObjects; // array of objects on which to wait
HANDLE* internalHandles = (HANDLE*) _alloca(numWaiters*sizeof(HANDLE));
-#ifndef FEATURE_CORECLR
- BOOL *hasThreadAffinity = (BOOL*) _alloca(numWaiters*sizeof(BOOL));
-
- BOOL mayRequireThreadAffinity = FALSE;
-#endif // !FEATURE_CORECLR
for (int i=0;i<numWaiters;i++)
{
WAITHANDLEREF waitObject = (WAITHANDLEREF) pWaitObjects->m_Array[i];
@@ -289,37 +249,16 @@ FCIMPL4(INT32, WaitHandleNative::CorWaitMultipleNative, Object* waitObjectsUNSAF
// this behavior seems wrong but someone explicitly coded that condition so it must have been for a reason.
internalHandles[i] = waitObject->m_handle;
-#ifndef FEATURE_CORECLR
- // m_hasThreadAffinity is set for Mutex only
- hasThreadAffinity[i] = waitObject->m_hasThreadAffinity;
- if (hasThreadAffinity[i]) {
- mayRequireThreadAffinity = TRUE;
- }
-#endif // !FEATURE_CORECLR
}
DWORD res = (DWORD) -1;
-#ifndef FEATURE_CORECLR
- ThreadAffinityHolder affinityHolder(mayRequireThreadAffinity);
-#endif // !FEATURE_CORECLR
Context* targetContext;
targetContext = pThread->GetContext();
_ASSERTE(targetContext);
Context* defaultContext;
defaultContext = pThread->GetDomain()->GetDefaultContext();
_ASSERTE(defaultContext);
-#ifdef FEATURE_REMOTING
- if (exitContext != NULL &&
- targetContext != defaultContext)
- {
- Context::WaitArgs waitMultipleArgs = {numWaiters, internalHandles, waitForAll, timeout, TRUE, &res};
- Context::CallBackInfo callBackInfo = {Context::Wait_callback, (void*) &waitMultipleArgs};
- Context::RequestCallBack(CURRENT_APPDOMAIN_ID,defaultContext, &callBackInfo);
- }
- else
-#else
_ASSERTE(exitContext == NULL || targetContext == defaultContext);
-#endif
{
// Support for pause/resume (FXFREEZE)
while(true)
@@ -335,45 +274,6 @@ FCIMPL4(INT32, WaitHandleNative::CorWaitMultipleNative, Object* waitObjectsUNSAF
}
}
-#ifndef FEATURE_CORECLR
- if (mayRequireThreadAffinity) {
- if (waitForAll) {
- if (res >= (DWORD) WAIT_OBJECT_0 && res < (DWORD) WAIT_OBJECT_0 + numWaiters) {
- for (int i = 0; i < numWaiters; i ++) {
- if (hasThreadAffinity[i]) {
- Thread::BeginThreadAffinityAndCriticalRegion();
- }
- }
- }
- // If some mutex is abandoned
- else if (res >= (DWORD) WAIT_ABANDONED_0 && res < (DWORD) WAIT_ABANDONED_0+numWaiters) {
- for (int i = 0; i < numWaiters; i ++) {
- if (hasThreadAffinity[i])
- {
- if (WaitForSingleObject(internalHandles[i],0) == WAIT_OBJECT_0)
- {
- BOOL result;
- result = ReleaseMutex(internalHandles[i]);
- _ASSERTE (result);
- Thread::BeginThreadAffinityAndCriticalRegion();
- }
- }
- }
- }
- }
- else {
- if ( res >= (DWORD)WAIT_OBJECT_0 && res < (DWORD)WAIT_OBJECT_0 + numWaiters) {
- if (hasThreadAffinity[res - WAIT_OBJECT_0]) {
- Thread::BeginThreadAffinityAndCriticalRegion();
- }
- }
- else if (res >= (DWORD)WAIT_ABANDONED_0 && res < (DWORD)WAIT_ABANDONED_0 + numWaiters) {
- _ASSERTE (hasThreadAffinity[res - WAIT_ABANDONED_0]);
- Thread::BeginThreadAffinityAndCriticalRegion();
- }
- }
- }
-#endif // !FEATURE_CORECLR
retVal = res;
@@ -415,11 +315,6 @@ FCIMPL5(INT32, WaitHandleNative::CorSignalAndWaitOneNative, SafeHandle* safeWait
Context* defaultContext = pThread->GetDomain()->GetDefaultContext();
_ASSERTE(defaultContext);
-#ifndef FEATURE_CORECLR
- // DoSignalAndWait calls LeaveRuntime/EnterRuntime which may cause the current
- // fiber to be re-scheduled.
- ThreadAffinityAndCriticalRegionHolder affinityAndCriticalRegionHolder(hasThreadAffinity);
-#endif // !FEATURE_CORECLR
SafeHandleHolder shhSignal(&shSignal);
SafeHandleHolder shhWait(&shWait);
@@ -428,31 +323,11 @@ FCIMPL5(INT32, WaitHandleNative::CorSignalAndWaitOneNative, SafeHandle* safeWait
HANDLE handles[2];
handles[0] = shSignal->GetHandle();
handles[1] = shWait->GetHandle();
-#ifdef FEATURE_REMOTING
- if (exitContext != NULL &&
- targetContext != defaultContext)
- {
- Context::SignalAndWaitArgs signalAndWaitArgs = {handles, timeout, TRUE, &res};
- Context::CallBackInfo callBackInfo = {Context::SignalAndWait_callback, (void*) &signalAndWaitArgs};
- Context::RequestCallBack(CURRENT_APPDOMAIN_ID,defaultContext, &callBackInfo);
- }
- else
-#else
_ASSERTE(exitContext == NULL || targetContext == defaultContext);
-#endif
{
res = pThread->DoSignalAndWait(handles,timeout,TRUE /*alertable*/);
}
-#ifndef FEATURE_CORECLR
- if (res == WAIT_OBJECT_0 && hasThreadAffinity) {
- affinityAndCriticalRegionHolder.SuppressRelease();
- }
- else if(res == WAIT_ABANDONED_0) {
- _ASSERTE(hasThreadAffinity);
- affinityAndCriticalRegionHolder.SuppressRelease();
- }
-#endif // !FEATURE_CORECLR
retVal = res;
diff --git a/src/vm/constrainedexecutionregion.cpp b/src/vm/constrainedexecutionregion.cpp
deleted file mode 100644
index 77b944c416..0000000000
--- a/src/vm/constrainedexecutionregion.cpp
+++ /dev/null
@@ -1,2265 +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.
-//
-// Methods to support the implementation of Constrained Execution Regions (CERs). This includes logic to walk the IL of methods to
-// determine the statically determinable call graph and prepare each submethod (jit, prepopulate generic dictionaries etc.,
-// everything needed to ensure that the runtime won't generate implicit failure points during the execution of said call graph).
-//
-
-//
-
-
-#include "common.h"
-#include <openum.h>
-#include <mdaassistants.h>
-#include <constrainedexecutionregion.h>
-#include <ecmakey.h>
-#include <typestring.h>
-#include <jitinterface.h>
-
-#ifdef FEATURE_PREJIT
-#include <compile.h>
-#endif
-
-
-// Internal debugging support. Would be nice to use the common logging code but we've run out of unique facility codes and the debug
-// info we spew out is of interest to a limited audience anyhow.
-#ifdef _DEBUG
-
-#define CER_NOISY_PREPARE 0x00000001
-#define CER_NOISY_RESTORE 0x00000002
-#define CER_NOISY_CONTRACTS 0x00000004
-#define CER_NOISY_WARNINGS 0x00000008
-#define CER_NOISY_NGEN_STATS 0x00000010
-
-DWORD g_dwCerLogActions = 0xffffffff;
-DWORD GetCerLoggingOptions()
-{
- WRAPPER_NO_CONTRACT;
- if (g_dwCerLogActions != 0xffffffff)
- return g_dwCerLogActions;
- return g_dwCerLogActions = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_CerLogging);
-}
-
-#define CER_LOG(_reason, _msg) do { if (GetCerLoggingOptions() & CER_NOISY_##_reason) printf _msg; } while (false)
-#else
-#define CER_LOG(_reason, _msg)
-#endif
-
-
-// Enumeration used to determine the number of inline data bytes included inside a given IL instruction (except for the case of a
-// SWITCH instruction, where a dynamic calculation is required).
-enum
-{
- ArgBytes_InlineNone = 0, // no inline args
- ArgBytes_InlineVar = 2, // local variable (U2 (U1 if Short on))
- ArgBytes_InlineI = 4, // an signed integer (I4 (I1 if Short on))
- ArgBytes_InlineR = 8, // a real number (R8 (R4 if Short on))
- ArgBytes_InlineBrTarget = 4, // branch target (I4 (I1 if Short on))
- ArgBytes_InlineI8 = 8,
- ArgBytes_InlineMethod = 4, // method token (U4)
- ArgBytes_InlineField = 4, // field token (U4)
- ArgBytes_InlineType = 4, // type token (U4)
- ArgBytes_InlineString = 4, // string TOKEN (U4)
- ArgBytes_InlineSig = 4, // signature tok (U4)
- ArgBytes_InlineRVA = 4, // ldptr token (U4)
- ArgBytes_InlineTok = 4, // a meta-data token of unknown type (U4)
- ArgBytes_InlineSwitch = 4, // count (U4), pcrel1 (U4) .... pcrelN (U4)
- ArgBytes_ShortInlineVar = 1,
- ArgBytes_ShortInlineI = 1,
- ArgBytes_ShortInlineR = 4,
- ArgBytes_ShortInlineBrTarget = 1
-};
-
-// Build an array of argument byte counts as described above by extracting the 'args' field of each entry in opcode.def.
-#define OPDEF(c, s, pop, push, args, type, l, s1, s2, ctrl) ArgBytes_##args,
-const BYTE g_rOpArgs[] = {
-#include <opcode.def>
-};
-#undef OPDEF
-
-
-// Global cache of methods and their reliability contract state.
-PtrHashCache *g_pMethodContractCache = NULL;
-
-
-// Private method forward references.
-bool IsPcrReference(Module *pModule, mdToken tkMethod);
-MethodContext *TokenToMethodDesc(Module *pModule, mdToken tokMethod, SigTypeContext *pTypeContext);
-TypeHandle GetTypeFromMemberDefOrRefOrSpecThrowing(Module *pModule,
- mdToken tokMethod,
- SigTypeContext *pTypeContext);
-
-bool MethodCallGraphPreparer::ShouldGatherExplicitCERCallInfo()
-{
- LIMITED_METHOD_CONTRACT;
-
- // If we're partially processing a method body (at the top of the call graph), we need to fetch exception handling
- // information to determine possible ranges of interesting IL (potentially each finally and catch clause).
- //
- // And if we are probing for stack overflow, we need to know if the explicit CER region contains any calls out, in
- // which case we want to probe in the call to PrepareConstrainedExecutionRegions. This will ensure that we don't
- // take an SO in boundary code and not be able to call the CER. When stack probing is disabled, we rip the process
- // if we take an SO anywhere but managed, or if we take an SO with a CER on the stack. For NGEN images, we need
- // to always probe because stack probing may be enabled in the runtime, but if we haven't probed in the NGEN image
- // then we could take an SO in boundary code and not be able to crawl the stack to know that we've skipped a CER and
- // need to tear the process.
- //
- // Additionally, if the MDA for illegal PrepareConstrainedRegions call positioning is enabled we gather this information for
- // all methods in the graph.
- return !m_fEntireMethod
-#ifdef MDA_SUPPORTED
- || MDA_GET_ASSISTANT(IllegalPrepareConstrainedRegion)
-#endif
-#ifdef FEATURE_NATIVE_IMAGE_GENERATION
- || m_fNgen
-#endif
- || g_pConfig->ProbeForStackOverflow();
-}
-
-MethodCallGraphPreparer::MethodCallGraphPreparer(MethodDesc *pRootMD, SigTypeContext *pRootTypeContext, bool fEntireMethod, bool fExactTypeContext, bool fIgnoreVirtualCERCallMDA)
-{
- CONTRACTL {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pRootMD));
- PRECONDITION(CheckPointer(pRootTypeContext));
- } CONTRACTL_END;
-
- // Canonicalize value type unboxing stubs into their underlying method desc.
- if (pRootMD->IsUnboxingStub())
- pRootMD = pRootMD->GetWrappedMethodDesc();
-
- m_pRootMD = pRootMD;
- m_pRootTypeContext = pRootTypeContext;
- m_fEntireMethod = fEntireMethod;
- m_fExactTypeContext = fExactTypeContext;
- m_fIgnoreVirtualCERCallMDA = fIgnoreVirtualCERCallMDA;
-
- m_pEHClauses = NULL;
- m_cEHClauses = 0;
- m_pCerPrepInfo = NULL;
- m_pMethodDecoder = NULL;
-
-#ifdef FEATURE_NATIVE_IMAGE_GENERATION
- m_fNgen = false;
-#endif
-
- m_pThread = GetThread();
- m_fPartialPreparation = false;
- m_fMethodHasCallsWithinExplicitCer = false;
-}
-
-// Walk the call graph of the method given by pRootMD (and type context in pRootTypeContext which provides instantiation information
-// for generic methods/classes).
-//
-// If fEntireMethod is true then the entire body of pRootMD is scanned for callsites, otherwise we assume that one or more CER
-// exception handlers exist in the method and only the finally and catch blocks of such handlers are scanned for graph roots.
-//
-// Each method we come across in the call graph (excluding late bound invocation destinations precipitated by virtual or interface
-// calls) is jitted and has any generic dictionary information we can determine at jit time prepopulated. This includes implicit
-// cctor invocations. If this method is called at ngen time we will attach extra fixup information to the affected method to ensure
-// that fixing up the root method of the graph will cause all methods in the graph to be fixed up at that point also.
-//
-// Some generic dictionary entries may not be prepopulated if unbound type variables exist at the root of the call tree. Such cases
-// will be ignored (as for the virtual/interface dispatch case we assume the caller will use an out-of-band mechanism to pre-prepare
-// these entries explicitly).
-bool MethodCallGraphPreparer::Run()
-{
- STANDARD_VM_CONTRACT;
-
- // Avoid recursion while jitting methods for another preparation.
- if (!m_pThread->GetCerPreparationState()->CanPreparationProceed(m_pRootMD, m_pRootTypeContext))
- return TRUE; // Assume the worst
-
-#ifdef FEATURE_NATIVE_IMAGE_GENERATION
- // Determine if we're being called in order to provide an ngen image. This impacts whether we actually prepare methods and the
- // type of tracking data we produce. Ideally we'd call GetAppDomain()->IsCompilationDomain() here, but we have to deal with the
- // problem of ngen'ing mscorlib. Mscorlib code is always shared and some of it is run before the compilation domain is fully
- // created (so we'd end up with some methods being prepared without saving any ngen metadata to that effect). So instead we
- // check to see whether this is an ngen process. This will catch those first few mscorlib methods.
- m_fNgen = IsCompilationProcess() != FALSE;
-
- // We keep a hash table of CERs we've processed on the module object of the root method. See if any work has been done on this
- // CER before. We store different data for ngen and non-ngen cases.
- if (m_fNgen) {
-
- // Pretty simple in ngen case -- if we've stored a context record for this method at all then we've already processed it.
- if (m_pRootMD->GetModule()->IsNgenCerRootMethod(m_pRootMD)) {
- m_pCerPrepInfo = m_pRootMD->GetModule()->GetCerPrepInfo(m_pRootMD);
-
- // We always store CerPrepInfo if the method has calls, so if we haven't stored
- // anything then we know it doesn't have any calls
- return (m_pCerPrepInfo && m_pCerPrepInfo->m_fMethodHasCallsWithinExplicitCer);
- }
- } else
-#endif
- {
- // The non-ngen case (normal jit, call to PrepareMethod etc).
- m_pCerPrepInfo = m_pRootMD->GetModule()->GetCerPrepInfo(m_pRootMD);
- if (m_pCerPrepInfo) {
-
- // Check for the "everything's done" case.
- if (m_pCerPrepInfo->m_fFullyPrepared)
- return m_pCerPrepInfo->m_fMethodHasCallsWithinExplicitCer;
-
- // Check for the "we can't do anything" case (see below for descriptions of that).
- if (m_pCerPrepInfo->m_fRequiresInstantiation && !m_fExactTypeContext)
- return m_pCerPrepInfo->m_fMethodHasCallsWithinExplicitCer;
-
- // Check for the "need to prepare per-instantiation, but we've already done this one" case.
- if (m_pCerPrepInfo->m_fRequiresInstantiation) {
- HashDatum sDatum;
- if (m_pCerPrepInfo->m_sIsInitAtInstHash.GetValue(m_pRootTypeContext, &sDatum))
- return m_pCerPrepInfo->m_fMethodHasCallsWithinExplicitCer;
- }
- }
- }
-
- // We can't deal with generic methods or methods on generic types that may have some representative type parameters in their
- // instantiation (i.e. some reference types indicated by Object rather than the exact type). The jit will tend to pass us these
- // since it shares code between instantiations over reference types. We can't prepare methods like these completely -- even
- // though we can jit all the method bodies the code might require generic dictionary information at the class or method level
- // that is populated at runtime and can introduce failure points. So we reject such methods immediately (they will need to be
- // prepared at non-jit time by an explicit call to PrepareMethod with a fully instantiated method).
- //
- // In the case where the type context is marked as suspect (m_fExactTypeContext == false) there are a number of possibilites for
- // bad methods the jit will pass us:
- // 1) We're passed a MethodDesc that shared between instantiations (bogus because exact method descs are never shared).
- // 2) We're passed a MethodDesc that's an instantiating stub (bogus because non-shared methods don't need this).
- // 3) We're passed a MethodDesc that has generic variables in its instantiations (I've seen this during ngen).
- //
- // Technically we could do a little better than this -- we could determine whether any of the representative type parameters are
- // actually used within the CER call graph itself. But this would require us to understand the IL at a much deeper level (i.e.
- // parse every instruction that could take a type or member spec and pull apart those specs to see if a type var is used). Plus
- // we couldn't make this determination until we've prepared the entire region and the result is rather brittle from the code
- // author's point of view (i.e. we might prepare a CER automatically one day but stop doing after some relatively subtle changes
- // in the source code).
- m_fPartialPreparation = m_pRootMD->IsSharedByGenericInstantiations() || m_pRootMD->IsInstantiatingStub() || m_pRootMD->ContainsGenericVariables();
- if (!m_fExactTypeContext && m_fPartialPreparation) {
-#ifdef MDA_SUPPORTED
- MDA_TRIGGER_ASSISTANT(OpenGenericCERCall, ReportViolation(m_pRootMD));
-#endif
- CER_LOG(WARNINGS, ("CER: %s has open type parameters and can't be pre-prepared\n", m_pRootMD->m_pszDebugMethodName));
-
-
-#ifdef FEATURE_NATIVE_IMAGE_GENERATION
- if (!m_fNgen)
-#endif
- {
- // Set up a prep info structure for this method if it's not there already (the create method takes care of races).
- if (m_pCerPrepInfo == NULL)
- m_pCerPrepInfo = m_pRootMD->GetModule()->CreateCerPrepInfo(m_pRootMD);
-
- // We may be racing to update the structure at this point but that's OK since the flag we're setting is never cleared once
- // it's set and is always guaranteed to be set before we rely on its value (setting it here is just a performance thing,
- // letting us early-out on multiple attempts to prepare this CER from the jit).
- m_pCerPrepInfo->m_fRequiresInstantiation = true;
- }
-
- if (! g_pConfig->ProbeForStackOverflow())
- {
- return FALSE;
- }
- m_pCerPrepInfo = m_pRootMD->GetModule()->GetCerPrepInfo(m_pRootMD);
-
- // We always store CerPrepInfo if the method has calls, so if we haven't stored
- // anything then we know it doesn't have any calls
- return (m_pCerPrepInfo && m_pCerPrepInfo->m_fMethodHasCallsWithinExplicitCer);
-
- }
-
-#ifdef FEATURE_NATIVE_IMAGE_GENERATION
- // If we've been called for a shared generic root method and the exact instantiation (this can happen because ngen lets code
- // execute under some circumstances) we don't currently support saving this information in the ngen image (we don't have a
- // format for the instantiation info). We just ignore the preparation in this case (it will be prepared at runtime).
- if (m_fNgen && m_fPartialPreparation)
- return TRUE;
-#endif
-
- // Prevent inlining of the root method (otherwise it's hard to tell where ThreadAbort exceptions should be delayed). Note that
- // MethodDesc::SetNotInline is thread safe.
- m_pRootMD->SetNotInline(true);
-
- // Remember the checkpoint for all of our allocations. Keep it in a holder so they'll be unwound if we throw an exception past
- // here.
- CheckPointHolder sCheckpoint(m_pThread->m_MarshalAlloc.GetCheckpoint());
-
- // Push the current method as the one and only method to process so far.
- m_sLeftToProcess.Push(MethodContext::PerThreadAllocate(m_pRootMD, m_pRootTypeContext));
-
- MethodContext *pContext = NULL; // The current MethodContext we're processing
-
- // Iterate until we run out of methods to process.
- while ((pContext = m_sLeftToProcess.Pop()) != NULL) {
-
- // Restore the MD if necessary. In particular, if this is an instantiating stub and the wrapped MethodDesc could
- // not be hard bound, then we'll need to restore that pointer before getting it.
- pContext->m_pMethodDesc->CheckRestore();
-
- // Transfer the method to the already seen stack immediately (we don't want to loop infinitely in the case of method
- // recursion).
- m_sAlreadySeen.Push(pContext);
-
- // Check if the enclosing class requires a static class constructor to be run. If so, we need to prepare that method as
- // though it were any other call.
- if (pContext->m_pMethodDesc->GetMethodTable()->HasClassConstructor()) {
-
- // Decode target method into MethodDesc and new SigTypeContext.
- // The type context is easy to derive here : .cctors never have any method type parameters and the class instantiations
- // are those of the method we're currently parsing, so can be simply copied down.
- MethodDesc *pCctor = pContext->m_pMethodDesc->GetCanonicalMethodTable()->GetClassConstructor();
- SigTypeContext sCctorTypeContext(pCctor, pContext->m_sTypeContext.m_classInst, Instantiation());
- MethodContext *pCctorContext = MethodContext::PerThreadAllocate(pCctor, &sCctorTypeContext);
-
- // Only process this cctor the first time we find it in this call graph.
- if (!m_sAlreadySeen.IsInStack(pCctorContext) && !m_sLeftToProcess.IsInStack(pCctorContext))
- m_sLeftToProcess.Push(pCctorContext);
- }
-
- // Skip further processing if this method doesn't have an IL body (note that we assume the method we entered with was IL, so
- // we don't need to bother with partial method processing).
- if (!pContext->m_pMethodDesc->IsIL()) {
- _ASSERTE(m_fEntireMethod);
- continue;
- }
-
- // Locate the IL body of the current method. May have to account for the fact that the current method desc is an
- // instantiating stub and burrow down for the real method desc.
- MethodDesc *pRealMethod = pContext->m_pMethodDesc;
- if (pRealMethod->IsInstantiatingStub()) {
- _ASSERTE(!pRealMethod->ContainsGenericVariables());
- pRealMethod = pRealMethod->GetWrappedMethodDesc();
- }
-
- COR_ILMETHOD* pILHeader = pRealMethod->GetILHeader();
-
- // Skip malformed methods. (We should always have method with IL for well-formed images here.)
- if (pILHeader == NULL) {
- continue;
- }
-
- COR_ILMETHOD_DECODER method(pILHeader);
- m_pMethodDecoder = &method;
-
- // We want to reget the EH clauses for the current method so that we can scan its handlers
- GetEHClauses();
-
- LookForInterestingCallsites(pContext);
-
- // Whatever we've done, we're definitely not processing the top-level method at this point (so we'll be processing full
- // method bodies from now on).
- m_fEntireMethod = true;
- }
-
-#ifdef FEATURE_NATIVE_IMAGE_GENERATION
- if (!m_fNgen)
-#endif
- {
- // Set up a prep info structure for this method if it's not there already (the create method takes care of races).
- // This needs to happen before we start JITing the methods as part of preparation. The JIT needs to know
- // about the CER root in CEEInfo::canTailCall.
- if (m_pCerPrepInfo == NULL)
- m_pCerPrepInfo = m_pRootMD->GetModule()->CreateCerPrepInfo(m_pRootMD);
- }
-
- // Prevent infinite recursion by recording on the thread which roots we're currently preparing.
- ThreadPreparingCerHolder sCerHolder(this);
-
- // Once we get here we've run out of methods to process and have recorded each method we visited in the m_sAlreadySeen stack. Now
- // it's time to prepare each of these methods (jit, prepopulate generic dictionaries etc.).
- PrepareMethods();
-
- return RecordResults();
-}
-
-
-// Determine whether a CER preparation for the given root method (with type context for generic instantiation
-// if necessary) can go ahead given any current preparation already being performed on the current thread.
-BOOL MethodCallGraphPreparer::CanPreparationProceed(MethodDesc * pMD, SigTypeContext * pTypeContext)
-{
- WRAPPER_NO_CONTRACT;
- MethodCallGraphPreparer * pCurrPrep = this;
- while (pCurrPrep)
- {
- // Is the prepartion request for the root method of the current preparer?
- if (pMD == pCurrPrep->m_pRootMD && SigTypeContext::Equal(pTypeContext, pCurrPrep->m_pRootTypeContext))
- {
- // We're already preparing this root, return FALSE to turn the request into a no-op and avoid
- // infinite recursion.
- return FALSE;
- }
-
- pCurrPrep = pCurrPrep->m_pNext;
- }
-
- // We found no previous preparation for the same root, so the request can proceed.
- return TRUE;
-}
-
-// Methods that push and pop thread local state used to determine if a re-entrant preparation request should
-// complete immediately as a no-op (because it would lead to an infinite recursion) or should proceed
-// recursively.
-
-//static
-void MethodCallGraphPreparer::BeginPrepareCerForHolder(MethodCallGraphPreparer * pPrepState)
-{
- LIMITED_METHOD_CONTRACT;
-
- Thread * pThread = pPrepState->m_pThread;
- pPrepState->m_pNext = pThread->GetCerPreparationState();
- pThread->SetCerPreparationState(pPrepState);
-}
-
-//static
-void MethodCallGraphPreparer::EndPrepareCerForHolder(MethodCallGraphPreparer * pPrepState)
-{
- LIMITED_METHOD_CONTRACT;
-
- Thread * pThread = pPrepState->m_pThread;
- _ASSERTE(pThread && pThread->GetCerPreparationState() == pPrepState);
- pThread->SetCerPreparationState(pPrepState->m_pNext);
-}
-
-
-void MethodCallGraphPreparer::GetEHClauses()
-{
- STANDARD_VM_CONTRACT;
-
- if (! ShouldGatherExplicitCERCallInfo())
- {
- return;
- }
-
- m_cEHClauses = 0;
- m_pEHClauses = NULL; // we use the StackingAllocator, so don't have to delete the previous storage
-
- COR_ILMETHOD_SECT_EH const * pEH = m_pMethodDecoder->EH;
- if (pEH == NULL ||pEH->EHCount() == 0)
- {
- return;
- }
-
- m_cEHClauses = pEH->EHCount();
- m_pEHClauses = new (&m_pThread->m_MarshalAlloc) EHClauseRange[m_cEHClauses];
-
- for (DWORD i = 0; i < m_cEHClauses; i++)
- {
- COR_ILMETHOD_SECT_EH_CLAUSE_FAT sEHClauseBuffer;
- const COR_ILMETHOD_SECT_EH_CLAUSE_FAT *pEHClause;
-
- pEHClause = (COR_ILMETHOD_SECT_EH_CLAUSE_FAT*)pEH->EHClause(i, &sEHClauseBuffer);
-
- // The algorithm below assumes handlers are located after their associated try blocks. If this turns out to be a
- // false assumption we need to move to a two pass technique (or defer callsite handling in some other fashion until
- // we've scanned the IL for all calls to our preparation marker method).
- if (!(pEHClause->GetTryOffset() < pEHClause->GetHandlerOffset()))
- {
- COMPlusThrowHR(COR_E_NOTSUPPORTED, IDS_EE_NOTSUPPORTED_CATCHBEFORETRY);
- }
-
- m_pEHClauses[i].m_dwTryOffset = pEHClause->GetTryOffset();
- m_pEHClauses[i].m_dwHandlerOffset = pEHClause->GetHandlerOffset();
- m_pEHClauses[i].m_dwHandlerLength = pEHClause->GetHandlerLength();
- m_pEHClauses[i].m_fActive = false;
-
- //printf("Try: %u Handler: %u -> %u\n", pEHClause->GetTryOffset(), pEHClause->GetHandlerOffset(), pEHClause->GetHandlerOffset() + pEHClause->GetHandlerLength() - 1);
- }
-
-}
-
-void MethodCallGraphPreparer::MarkEHClauseActivatedByCERCall(MethodContext *pContext, BYTE *pbIL, DWORD cbIL)
-{
- STANDARD_VM_CONTRACT;
-
- DWORD dwOffset = (DWORD)(SIZE_T)((pbIL + ArgBytes_InlineTok) - (BYTE*)m_pMethodDecoder->Code);
-
- // Additionally we need to cope with the fact that VB and C# (for debug builds) can generate NOP instructions
- // between the PCR call and the beginning of the try block. So we're potentially looking for the
- // intersection of the try with a range of instructions. Count the number of consecutive NOP instructions
- // which follow the call.
- DWORD dwLength = 0;
- BYTE *pbTmpIL = pbIL + ArgBytes_InlineTok;
- while (pbTmpIL < (pbIL + cbIL) && *pbTmpIL++ == CEE_NOP)
- {
- dwLength++;
- }
-
- bool fMatched = false;
- for (DWORD i = 0; i < m_cEHClauses; i++)
- {
- if (m_pEHClauses[i].m_dwTryOffset >= dwOffset &&
- m_pEHClauses[i].m_dwTryOffset <= (dwOffset + dwLength))
- {
- fMatched = true;
- m_pEHClauses[i].m_fActive = true;
- }
- }
- if (!fMatched)
- {
-#if defined(_DEBUG) || defined(MDA_SUPPORTED)
- DWORD dwPCROffset = (DWORD)(SIZE_T)((pbIL - 1) - (BYTE*)m_pMethodDecoder->Code);
-#endif // defined(_DEBUG) || defined(MDA_SUPPORTED)
-#ifdef MDA_SUPPORTED
- MDA_TRIGGER_ASSISTANT(IllegalPrepareConstrainedRegion, ReportViolation(pContext->m_pMethodDesc, dwPCROffset));
-#endif
- CER_LOG(WARNINGS, ("CER: %s: Invalid call to PrepareConstrainedRegions() at IL +%04X\n",
- pContext->m_pMethodDesc->m_pszDebugMethodName, dwPCROffset));
- }
-}
-
-bool MethodCallGraphPreparer::CheckIfCallsiteWithinCER(DWORD dwOffset)
-{
- STANDARD_VM_CONTRACT;
-
- //printf("Found: %s at %u\n", pCallTarget->m_pMethodDesc->m_pszDebugMethodName, dwOffset);
-
- // Search all the EH regions we know about.
- for (DWORD i = 0; i < m_cEHClauses; i++)
- {
- bool fCallsiteWithinCER = false;
- if (! m_pEHClauses[i].m_fActive)
- {
- // clause not CER-active so skip it
- continue;
- }
- if (dwOffset >= (m_pEHClauses[i].m_dwHandlerOffset + m_pEHClauses[i].m_dwHandlerLength))
- {
- // offset beyond clause, so skip it
- continue;
- }
- if (dwOffset >= m_pEHClauses[i].m_dwTryOffset)
- {
- // For stack probing optimization, we care if either the try or the handler has a call. If neither
- // does, then we can optimize the probe out.
- m_fMethodHasCallsWithinExplicitCer = true;
- if (dwOffset >= m_pEHClauses[i].m_dwHandlerOffset)
- {
- fCallsiteWithinCER = true;
- }
- }
- // Only terminate if we got a positive result (i.e. the calliste is within a hardened clause).
- // We can't terminate early in the negative case because the callsite could be nested
- // in another EH region which may be hardened.
- if (fCallsiteWithinCER == true)
- {
- return true;
- }
- }
-
- return false;
-}
-
-
-// Iterate through the body of the method looking for interesting call sites.
-void MethodCallGraphPreparer::LookForInterestingCallsites(MethodContext *pContext)
-{
- STANDARD_VM_CONTRACT;
-
- BYTE *pbIL = (BYTE*)m_pMethodDecoder->Code;
- DWORD cbIL = m_pMethodDecoder->GetCodeSize();
-
- while (cbIL) {
-
- // Read the IL op.
- DWORD dwOp = *pbIL++; cbIL--;
-
- // Handle prefix codes (only CEE_PREFIX1 is legal so far).
- if (dwOp == CEE_PREFIX1) {
- if (!cbIL)
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- dwOp = 256 + *pbIL++; cbIL--;
- } else if (dwOp >= CEE_PREFIX7)
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
-
- // We're interested in NEWOBJ, JMP, CALL and CALLVIRT (can't trace through CALLI). We include CALLVIRT becase C#
- // routinely calls non-virtual instance methods this way in order to get this pointer null checking. We prepare NEWOBJ
- // because that covers the corner case of value types which can be constructed with no failure path.
- if (dwOp == CEE_CALL || dwOp == CEE_CALLVIRT || dwOp == CEE_NEWOBJ || dwOp == CEE_JMP) {
-
- if (cbIL < sizeof(DWORD))
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
-
- // Decode target method into MethodDesc and new SigTypeContext.
- mdToken tkCallTarget = (mdToken)GET_UNALIGNED_VAL32(pbIL);
- MethodContext *pCallTarget = TokenToMethodDesc(pContext->m_pMethodDesc->GetModule(), tkCallTarget, &pContext->m_sTypeContext);
-
- // Check whether we've found a call to our own preparation marker method.
- if (pCallTarget->m_pMethodDesc == g_pPrepareConstrainedRegionsMethod) {
-
- if (ShouldGatherExplicitCERCallInfo()) {
- // If we're preparing a partial method these callsites are significant (we mark which EH clauses are now
- // 'activated' by proximity to this marker method call). Look for EH regions that are 'activated' by the call to
- // PrepareConstrainedRegions by comparing the IL offset of the start of the try to the offset immediately after
- // the callsite (remember to account for the rest of the CALLVIRT instruction we haven't skipped yet).
- MarkEHClauseActivatedByCERCall(pContext, pbIL, cbIL);
- }
-
- // Record the fact that we found a method in the CER which is the root of a sub-CER. This is important since the
- // rude thread abort protection algorithm relies on root CER methods being marked as such.
- pContext->m_fRoot = true;
- }
-
- // Determine if this was really a virtual call (we discard those since we can't reliably determine the call target).
- bool fNonVirtualCall = dwOp == CEE_CALL || !pCallTarget->m_pMethodDesc->IsVirtual() || pCallTarget->m_pMethodDesc->IsFinal();
-
- // When we're only processing qualified catch / finally handlers then we need to compute whether this call site
- // lands in one of them. The callsite is always within a cer if we are processing the full method.
- // If we have stackoverflow probing on, also call to determine if the CER try or finally makes any calls
- bool fCallsiteWithinCerInThisFunction = false;
- if (!m_fEntireMethod || g_pConfig->ProbeForStackOverflow()) {
- DWORD dwOffset = (DWORD)(SIZE_T)((pbIL - 1) - (BYTE*)m_pMethodDecoder->Code);
- fCallsiteWithinCerInThisFunction = CheckIfCallsiteWithinCER(dwOffset);
- }
- bool fCallsiteWithinCer = m_fEntireMethod || fCallsiteWithinCerInThisFunction;
-
- // Check for the presence of some sort of reliability contract (on the method, class or assembly). This will
- // determine whether we log an error, ignore the method or treat it as part of the prepared call graph.
- ReliabilityContractLevel eLevel = RCL_UNKNOWN;
- if (fNonVirtualCall && // Ignore virtual calls
- fCallsiteWithinCer && // And calls outside CERs
- !m_sAlreadySeen.IsInStack(pCallTarget) && // And methods we've seen before
- !m_sLeftToProcess.IsInStack(pCallTarget) && // And methods we've already queued for processing
- (eLevel = CheckForReliabilityContract(pCallTarget->m_pMethodDesc)) >= RCL_PREPARE_CONTRACT) // And unreliable methods
- m_sLeftToProcess.Push(pCallTarget); // Otherwise add this method to the list to process
- else if (fCallsiteWithinCer) {
-#if defined(_DEBUG) || defined(MDA_SUPPORTED)
- DWORD dwOffset = (DWORD)(SIZE_T)((pbIL - 1) - (BYTE*)m_pMethodDecoder->Code);
-#endif // defined(_DEBUG) || defined(MDA_SUPPORTED)
- if (eLevel == RCL_NO_CONTRACT) {
- // Method was sufficiently unreliable for us to warn interested users that something may be amiss. Do this
- // through MDA logging.
-#ifdef MDA_SUPPORTED
- MDA_TRIGGER_ASSISTANT(InvalidCERCall, ReportViolation(pContext->m_pMethodDesc, pCallTarget->m_pMethodDesc, dwOffset));
-#endif
- CER_LOG(WARNINGS, ("CER: %s +%04X -> %s: weak contract\n", pContext->ToString(), dwOffset, pCallTarget->ToString()));
- } else if (!fNonVirtualCall && !m_fIgnoreVirtualCERCallMDA) {
- // Warn users about virtual calls in CERs (so they can go back and consider which target methods need to be
- // prepared ahead of time).
-#ifdef MDA_SUPPORTED
- MDA_TRIGGER_ASSISTANT(VirtualCERCall, ReportViolation(pContext->m_pMethodDesc, pCallTarget->m_pMethodDesc, dwOffset));
-#endif
- CER_LOG(WARNINGS, ("CER: %s +%04X -> %s: virtual call\n", pContext->ToString(), dwOffset, pCallTarget->ToString()));
- }
- }
- }
-
- // Skip the rest of the current IL instruction. Look up the table built statically at the top of this module for most
- // instructions, but CEE_SWITCH requires special processing (the length of that instruction depends on a count DWORD
- // embedded right after the opcode).
- if (dwOp == CEE_SWITCH) {
- DWORD dwTargets = GET_UNALIGNED_VAL32(pbIL);
- if (dwTargets >= (MAXDWORD / sizeof(DWORD)))
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT); // multiplication below would overflow
- DWORD cbSwitch = (1 + dwTargets) * sizeof(DWORD);
- if (cbIL < cbSwitch)
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- pbIL += cbSwitch;
- cbIL -= cbSwitch;
- } else {
- if (dwOp >= _countof(g_rOpArgs))
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- DWORD cbOp = g_rOpArgs[dwOp];
- if (cbIL < cbOp)
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- pbIL += cbOp;
- cbIL -= cbOp;
- }
-
- } // End of IL parsing loop
-}
-
-void MethodCallGraphPreparer::PrepareMethods()
-{
- STANDARD_VM_CONTRACT;
-
-#ifdef _DEBUG
- DWORD dwCount = 0;
- if (GetCerLoggingOptions())
- {
- CER_LOG(PREPARE, ("---------------------------------------------------------------\n"));
- SString ssMethod;
- TypeString::AppendMethodInternal(ssMethod, m_pRootMD, TypeString::FormatNamespace | TypeString::FormatStubInfo);
- CER_LOG(PREPARE, ("Preparing from %S\n", ssMethod.GetUnicode()));
- }
-#endif
-
- MethodContext *pContext; // The current MethodContext we're processing
-
- while ((pContext = m_sAlreadySeen.Pop()) != NULL) {
- MethodDesc *pMD = pContext->m_pMethodDesc;
-
-#ifndef CROSSGEN_COMPILE
- // Jitting. Don't need to do this for the ngen case.
-#ifdef FEATURE_NATIVE_IMAGE_GENERATION
- if (!m_fNgen)
-#endif
- {
- // Also skip the jit for the root method in the activated from jit case (where this would result in a recursive
- // jit). We'd cope with this just fine, the main reason for this logic is to avoid unbalancing some profiler event
- // counts that upset some of our test cases. This is safe in the face of multiple instantiations of the same method
- // because in the jit activated case (where we're told the root type context is not exact) we early exit if the root
- // method desc isn't 'unique' (i.e. independent of the type context).
- if (m_fExactTypeContext || pMD != m_pRootMD) {
-
- // Jit the method we traced.
- if (pMD->IsPointingToPrestub())
- {
- pMD->EnsureActive();
- pMD->DoPrestub(NULL);
- }
-
- // If we traced an instantiating stub we need to jit the wrapped (real) method as well.
- if (pMD->IsInstantiatingStub()) {
- _ASSERTE(!pMD->ContainsGenericVariables());
- MethodDesc *pRealMD = pMD->GetWrappedMethodDesc();
- if (pRealMD->IsPointingToPrestub())
- {
- pMD->EnsureActive();
- pRealMD->DoPrestub(NULL);
- }
- }
- }
-
- // Remember sub-CER root methods for further processing in RecordResults. We need to build CerPrepInfo structures for
- // these just the same as top-level CERs since we may wander in to them by a route that doesn't include the top-level CER
- // and the thread abort deflection algorithm relies on each CER root method being marked by a CerPrepInfo. Defer this
- // processing to RecordResults since we aren't guaranteed to have prepared all the methods of the sub-graph at this
- // point.
- if (pContext->m_fRoot && pMD != m_pRootMD)
- m_sPersist.Push(pContext);
- }
-#endif // CROSSGEN_COMPILE
-
- // Prepare generic dictionaries (both class and method as needed). We do this even in the ngen scenario, trying to get
- // as many slots filled as possible. By the looks of it, it's possible that not all of these entries will make it across
- // to runtime (the fixup code seems to give up on some of the more complex entries, not sure of the details). But we'll
- // do as best we can here to hopefully minimize any real work on the other side.
-
- // Don't use the direct PrepopulateDictionary method on MethodTable here, it takes binding considerations into account
- // (which we don't care about).
- DictionaryLayout *pClassDictLayout = pMD->GetClass()->GetDictionaryLayout();
- if (pClassDictLayout) {
- // Translate the representative method table we can find from our method desc into an exact instantiation using the
- // type context we have.
- MethodTable *pMT = TypeHandle(pMD->GetMethodTable()).Instantiate(pContext->m_sTypeContext.m_classInst).AsMethodTable();
-
- pMT->GetDictionary()->PrepopulateDictionary(NULL, pMT, false);
-
- // The dictionary may have overflowed in which case we need to prepopulate the jit's lookup cache as well.
- PrepopulateGenericHandleCache(pClassDictLayout, NULL, pMT);
- }
-
- // Don't use the direct PrepopulateDictionary method on MethodDesc here, it appears to use a representative class
- // instantiation (and we have the exact one handy).
- DictionaryLayout *pMethDictLayout = pMD->GetDictionaryLayout();
- if (pMethDictLayout) {
- pMD->GetMethodDictionary()->PrepopulateDictionary(pMD, NULL, false);
-
- // The dictionary may have overflowed in which case we need to prepopulate the jit's lookup cache as well.
- PrepopulateGenericHandleCache(pMethDictLayout, pMD, NULL);
- }
-
-#ifdef FEATURE_NATIVE_IMAGE_GENERATION
- // Keep some of the method contexts around for the ngen case (the ones that might still need fixup at runtime). We'll
- // write them into a persisted data structure in the next step.
- // @todo: We use a horrible workaround here to get round the fact that while ngen'ing mscorlib we may prepare some of its
- // methods before we've had a chance to start up the compilation domain (mscorlib code is shared and used by the ngen
- // process itself). So we can't blindly call NeedsRestore() on an mscorlib method since that code asserts we're in the
- // compilation domain. Instead, if we're in the ngen process and we're outside the compilation domain we're going to
- // assume that the method doesn't need restoration. This only affects a handful of methods (six at last count, all to do
- // with security safe handles or some CERs in remoting).
- if (m_fNgen) {
- if (GetAppDomain() == NULL ||
- !GetAppDomain()->IsCompilationDomain() ||
- !(GetAppDomain()->ToCompilationDomain()->canCallNeedsRestore()) ||
- !(GetAppDomain()->ToCompilationDomain()->GetTargetImage()->CanPrerestoreEagerBindToMethodDesc(pMD, NULL))||
- pMD->HasClassOrMethodInstantiation() ||
- pMD->IsNDirect() ||
- pMD->IsComPlusCall() ||
- pMD->IsFCall() ||
- pContext->m_fRoot)
- m_sPersist.Push(pContext);
- }
-#endif
-
-#ifdef _DEBUG
- CER_LOG(PREPARE, (" %s\n", pContext->ToString()));
- dwCount++;
-#endif
- }
-
-#ifdef _DEBUG
- CER_LOG(PREPARE, ("Prepared a total of %u methods\n", dwCount));
-#ifdef FEATURE_NATIVE_IMAGE_GENERATION
- if (m_fNgen)
- CER_LOG(PREPARE, ("Saved data for %u of them in the ngen image\n", m_sPersist.GetCount()));
-#endif
- CER_LOG(PREPARE, ("---------------------------------------------------------------\n"));
-#endif
-}
-
-// Common code used in creating/looking up a CerPrepInfo and initializing/updating it.
-void InitPrepInfo(MethodDesc *pMD, SigTypeContext *pTypeContext, bool fMethodHasCallsWithinExplicitCer)
-{
- CONTRACTL {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pMD));
- } CONTRACTL_END;
-
- // Lookup or allocate the CerPrepInfo.
- CerPrepInfo *pInfo = pMD->GetModule()->CreateCerPrepInfo(pMD);
-
- pInfo->m_fMethodHasCallsWithinExplicitCer = fMethodHasCallsWithinExplicitCer;
-
- // Work out if this was a partial preparation.
- bool fPartialPreparation = pMD->IsSharedByGenericInstantiations() ||
- pMD->IsInstantiatingStub() ||
- pMD->ContainsGenericVariables();
-
- // Simple case first: if this isn't a partial preparation (no pesky unbound type vars to worry about), then the method is
- // now fully prepared.
- if (!fPartialPreparation) {
- pInfo->m_fFullyPrepared = true;
- return;
- }
-
- // Else we know we require per-instantiation initialization. We need to update a hash table to record the preparation we did
- // in this case, and that requires taking a mutex. We could check that nobody beat us to it first, but that will hardly ever
- // happen, so it's not really worth it. So just acquire the mutex right away.
- CrstHolder sHolder(pMD->GetModule()->GetCerCrst());
-
- pInfo->m_fRequiresInstantiation = true;
-
- // Add an entry to a hash that records which instantiations we've prep'd for (again, only if someone hasn't beaten us).
- HashDatum sDatum;
- if (!pInfo->m_sIsInitAtInstHash.GetValue(pTypeContext, &sDatum))
- {
- pInfo->m_sIsInitAtInstHash.InsertKeyAsValue(pTypeContext);
- }
-}
-
-bool MethodCallGraphPreparer::RecordResults()
-{
- STANDARD_VM_CONTRACT;
-
- // Preparation has been successful, record what we've done in a manner consistent with whether we're ngen'ing or running for
- // real.
-
-#ifdef FEATURE_NATIVE_IMAGE_GENERATION
- // If we're ngen'ing an image we save our progess as a list of method contexts that might need restoration at runtime (since
- // even with prejitting there are some things that need to be prepared at runtime). This list goes into a per module table (the
- // module in question being that of the root method in the CER).
- if (m_fNgen) {
-
- // We have the list of MethodContexts ready, but they're in cheap storage that will go away once we exit this method.
- // Not only do we have to copy them to heap memory, but we also know exactly how many there are. So we can allocate a
- // single array with a more compact form of MethodContext for each element. We allocate an extra sentinel value for the end
- // of the list. This means we can store just a pointer to the list without a count (the code that accesses this list cares
- // about keeping the list heads compact and densely packed and doesn't care about counting the elements in the list).
- DWORD cContexts = m_sPersist.GetCount();
- LoaderHeap *pHeap = m_pRootMD->GetAssembly()->GetLowFrequencyHeap();
- MethodContextElement *pContexts = (MethodContextElement*)(void*)pHeap->AllocMem(S_SIZE_T(sizeof(MethodContextElement)) * (S_SIZE_T(cContexts) + S_SIZE_T(1)));
- DWORD i = 0;
-
- MethodContext *pContext; // The current MethodContext we're processing
- while ((pContext = m_sPersist.Pop()) != NULL) {
- pContexts[i].m_pMethodDesc.SetValue(pContext->m_pMethodDesc);
-
- MethodTable * pExactMT = NULL;
- if (!pContext->m_sTypeContext.m_classInst.IsEmpty())
- {
- pExactMT = TypeHandle(pContext->m_pMethodDesc->GetMethodTable()).Instantiate(pContext->m_sTypeContext.m_classInst).AsMethodTable();
- _ASSERTE(pExactMT->HasInstantiation());
- }
- else
- {
- _ASSERTE(!pContext->m_pMethodDesc->GetMethodTable()->HasInstantiation());
- }
- pContexts[i].m_pExactMT.SetValue(pExactMT);
-
- i++;
-
- // Keep the context round for a little longer if the method in question was the root of a sub-CER.
- if (pContext->m_fRoot)
- m_sRootMethods.Push(pContext);
- }
-
- // Write sentinel entry terminating list.
- _ASSERTE(i == cContexts);
-
- // Add list representing this CER to the per-module table (keyed by root method desc).
- m_pRootMD->GetModule()->AddCerListToRootTable(m_pRootMD, pContexts);
-
- // If this did have an call from an explicit PCER range, create a PrepInfo for it so that we can
- // quickly grab that information later when we jit that method. This allows us to optimize the probe
- // away if there are no calls from the PCER range. This is an issue when we've prepared a method
- // as part of a CER call from another method, but haven't ngened that method yet. When we get
- // around to finally ngening that method, we want to be able to optimize the CER probe out if
- // we can, but don't want to reprepare the method.
- if (g_pConfig->ProbeForStackOverflow() && m_fMethodHasCallsWithinExplicitCer)
- {
- if (m_pCerPrepInfo == NULL)
- m_pCerPrepInfo = m_pRootMD->GetModule()->CreateCerPrepInfo(m_pRootMD);
- m_pCerPrepInfo->m_fMethodHasCallsWithinExplicitCer = TRUE;
- }
-
-
- // We need to be careful with sub-CERs in the ngen case. In the jit case they're dealt with automatically (preparing a
- // super-CER always completely prepares a sub-CER). But in the ngen case we potentially need to run further preparation
- // steps at the point that a CER root is executed for the first time. If the sub-root is encountered before the super-root
- // then the sub-CER won't have been prepared correctly.
- // We solve this simply by recursively running this routine over the methods we noted were sub-roots earlier (this list
- // doesn't include the main root). We could potentially do a little better than this given that we've calculated the
- // super-graph, but this is complicated somewhat by the fact that we don't retain the graph structure (i.e. we can't extract
- // sub-graphs easily) and the effort seems wasted just to avoid a little CPU time and stack space just for the ngen creation
- // scenario.
- while ((pContext = m_sRootMethods.Pop()) != NULL)
- {
- MethodCallGraphPreparer mgcp(pContext->m_pMethodDesc, &pContext->m_sTypeContext, false, false);
- mgcp.Run();
- }
-
- return m_fMethodHasCallsWithinExplicitCer;
- }
-#endif // FEATURE_NATIVE_IMAGE_GENERATION
-
- // This is the runtime (non-ngen case). Record our progress in an info structure placed in a hash table hung off the module
- // which owns the root method desc in the CER. The methods which create this info structure handle race conditions (to
- // ensure we don't leak memory or data), but the updates to the info structure itself might not require any serialization
- // (the values are 'latched' -- recomputation should yield the same result). The exception is any update to a more complex
- // data fields (lists and hash tables) that require serialization to prevent corruption of the basic data structure.
-
- // Process sub-CER roots first. We need to build CerPrepInfo structures for these just as same as top-level CERs since we may
- // wander in to them by a route that doesn't include the top-level CER and the thread abort deflection algorithm relies on each
- // CER root method being marked by a CerPrepInfo.
- MethodContext *pContext;
- while ((pContext = m_sPersist.Pop()) != NULL) {
- _ASSERTE(pContext->m_fRoot);
-
- // @todo: need to flow fMethodHasCallsWithinExplicitCer information through method contexts. For now just make a
- // conservative, safe choice.
- InitPrepInfo(pContext->m_pMethodDesc, &pContext->m_sTypeContext, true);
- }
-
- // Now process the top-level CER.
- InitPrepInfo(m_pRootMD, m_pRootTypeContext, m_fMethodHasCallsWithinExplicitCer);
-
- return m_fMethodHasCallsWithinExplicitCer;
-}
-
-// Determines whether the given method contains a CER root that can be pre-prepared (i.e. prepared at jit time).
-bool ContainsPrePreparableCerRoot(MethodDesc *pMD)
-{
- CONTRACTL {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pMD));
- } CONTRACTL_END;
-
- // Deal with exotic cases (non-IL methods and the like).
- if (!pMD->IsIL() || pMD->IsAbstract())
- return false;
-
- // And cases where we can't jit prepare (because the code is shared between instantiations).
- if (pMD->IsSharedByGenericInstantiations() || pMD->IsInstantiatingStub() || pMD->ContainsGenericVariables())
- return false;
-
- // Otherwise we have a trickier calculation. We don't want to force the jit of the method at this point (may cause infinite
- // recursion problems when we're called from the jit in the presence of call cycles). Instead we walk the top-level of the
- // method IL using the same algorithm as PrepareMethodCallGraph.
-
- // Locate the IL body of the current method. May have to account for the fact that the current method desc is an
- // instantiating stub and burrow down for the real method desc.
- MethodDesc *pRealMethod = pMD;
- if (pRealMethod->IsInstantiatingStub()) {
- _ASSERTE(!pRealMethod->ContainsGenericVariables());
- pRealMethod = pRealMethod->GetWrappedMethodDesc();
- }
- COR_ILMETHOD_DECODER method(pRealMethod->GetILHeader());
- BYTE *pbIL = (BYTE*)method.Code;
- DWORD cbIL = method.GetCodeSize();
-
- // Look for exception handling information for the method. If there isn't any then we know there can't be a CER rooted here.
- COR_ILMETHOD_SECT_EH const * pEH = method.EH;
- if (pEH == NULL || pEH->EHCount() == 0)
- return false;
-
- // Iterate through the body of the method looking for interesting call sites.
- while (cbIL) {
-
- // Read the IL op.
- DWORD dwOp = *pbIL++; cbIL--;
-
- // Handle prefix codes (only CEE_PREFIX1 is legal so far).
- if (dwOp == CEE_PREFIX1) {
- if (!cbIL)
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- dwOp = 256 + *pbIL++; cbIL--;
- if (dwOp >= CEE_ILLEGAL)
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- } else if (dwOp >= CEE_PREFIX7)
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
-
- // We'll only ever see CALL instructions targeting PrepareConstrainedRegions (well those are the ones we're interested in
- // anyway).
- if (dwOp == CEE_CALL)
- {
- if (cbIL < sizeof(DWORD))
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- if (IsPcrReference(pMD->GetModule(), (mdToken)GET_UNALIGNED_VAL32(pbIL)))
- return true;
- }
-
- // Skip the rest of the current IL instruction. Look up the table built statically at the top of this module for most
- // instructions, but CEE_SWITCH requires special processing (the length of that instruction depends on a count DWORD
- // embedded right after the opcode).
- if (dwOp == CEE_SWITCH) {
- if (cbIL < sizeof(DWORD))
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- DWORD dwTargets = GET_UNALIGNED_VAL32(pbIL);
- if (dwTargets >= (MAXDWORD / sizeof(DWORD)))
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT); // multiplication below would overflow
- DWORD cbSwitch = (1 + dwTargets) * sizeof(DWORD);
- if (cbIL < cbSwitch)
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- pbIL += cbSwitch;
- cbIL -= cbSwitch;
- } else {
- if (dwOp >= _countof(g_rOpArgs))
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- DWORD cbOp = g_rOpArgs[dwOp];
- if (cbIL < cbOp)
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- pbIL += cbOp;
- cbIL -= cbOp;
- }
-
- } // End of IL parsing loop
-
- // If we get here then there was no CER-root.
- return false;
-}
-
-// The name of the PrepareConstrainedRegions method, broken down into its components (the code below scans for these directly in the
-// metadata).
-#define PCR_METHOD "PrepareConstrainedRegions"
-#define PCR_TYPE "RuntimeHelpers"
-#define PCR_NAMESPACE "System.Runtime.CompilerServices"
-
-// Given a token and a module scoping it, determine if that token is a reference to PrepareConstrainedRegions. We want to do this
-// without loading any random types since we're called in a context where type loading is prohibited.
-bool IsPcrReference(Module *pModule, mdToken tkMethod)
-{
- CONTRACTL {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pModule));
- } CONTRACTL_END;
-
- IMDInternalImport *pImport = pModule->GetMDImport();
-
- // Validate that the token is one that we can handle.
- if (!pImport->IsValidToken(tkMethod) || (TypeFromToken(tkMethod) != mdtMethodDef &&
- TypeFromToken(tkMethod) != mdtMethodSpec &&
- TypeFromToken(tkMethod) != mdtMemberRef))
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_INVALID_METHOD_TOKEN);
-
- // No reason to see a method spec for a call to something as simple as PrepareConstrainedRegions.
- if (TypeFromToken(tkMethod) == mdtMethodSpec)
- return false;
-
- // If it's a method def then the module had better be mscorlib.
- if (TypeFromToken(tkMethod) == mdtMethodDef) {
- if (pModule->GetAssembly()->GetManifestModule() == SystemDomain::SystemAssembly()->GetManifestModule())
- return tkMethod == g_pPrepareConstrainedRegionsMethod->GetMemberDef();
- else
- return false;
- }
-
- // That leaves the cross module reference case.
- _ASSERTE(TypeFromToken(tkMethod) == mdtMemberRef);
-
- // First get the method name and signature and validate it.
- PCCOR_SIGNATURE pSig;
- DWORD cbSig;
- LPCSTR szMethod;
- IfFailThrow(pImport->GetNameAndSigOfMemberRef(tkMethod, &pSig, &cbSig, &szMethod));
-
- {
- SigParser sig(pSig, cbSig);
- ULONG nCallingConvention;
- ULONG nArgumentsCount;
- BYTE bReturnType;
-
- // Signature is easy: void PCR().
- // Must be a static method signature.
- if (FAILED(sig.GetCallingConvInfo(&nCallingConvention)))
- return false;
- if (nCallingConvention != IMAGE_CEE_CS_CALLCONV_DEFAULT)
- return false;
- // With no arguments.
- if (FAILED(sig.GetData(&nArgumentsCount)))
- return false;
- if (nArgumentsCount != 0)
- return false;
- // And a void return type.
- if (FAILED(sig.GetByte(&bReturnType)))
- return false;
- if (bReturnType != (BYTE)ELEMENT_TYPE_VOID)
- return false;
- }
-
- // Validate the name.
- if (strcmp(szMethod, PCR_METHOD) != 0)
- return false;
-
- // The method looks OK, move up to the type and validate that.
- mdToken tkType;
- IfFailThrow(pImport->GetParentOfMemberRef(tkMethod, &tkType));
-
- if (!pImport->IsValidToken(tkType))
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_INVALID_TOKEN);
-
- // If the parent is not a type ref then this isn't our target (we assume that mscorlib never uses a member ref to target
- // PrepareConstrainedRegions, check that with the assert below, if it ever fails we need to add some additional logic below).
- _ASSERTE(TypeFromToken(tkType) != mdtTypeDef ||
- pModule->GetAssembly()->GetManifestModule() != SystemDomain::SystemAssembly()->GetManifestModule());
- if (TypeFromToken(tkType) != mdtTypeRef)
- return false;
-
- // Get the type name and validate it.
- LPCSTR szNamespace;
- LPCSTR szType;
- IfFailThrow(pImport->GetNameOfTypeRef(tkType, &szNamespace, &szType));
-
- if (strcmp(szType, PCR_TYPE) != 0)
- return false;
- if (strcmp(szNamespace, PCR_NAMESPACE) != 0)
- return false;
-
- // Type is OK as well. Check the assembly reference.
- mdToken tkScope;
- IfFailThrow(pImport->GetResolutionScopeOfTypeRef(tkType, &tkScope));
-
- if (TypeFromToken(tkScope) != mdtAssemblyRef)
- return false;
- if (!pImport->IsValidToken(tkScope))
- {
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_INVALID_TOKEN);
- }
-
- // Fetch the name and public key or public key token.
- BYTE *pbPublicKeyOrToken;
- DWORD cbPublicKeyOrToken;
- LPCSTR szAssembly;
- DWORD dwAssemblyFlags;
- IfFailThrow(pImport->GetAssemblyRefProps(
- tkScope,
- (const void**)&pbPublicKeyOrToken,
- &cbPublicKeyOrToken,
- &szAssembly,
- NULL, // AssemblyMetaDataInternal: we don't care about version, culture etc.
- NULL, // Hash value pointer, obsolete information
- NULL, // Byte count for above
- &dwAssemblyFlags));
-
- // Validate the name.
- if (stricmpUTF8(szAssembly, g_psBaseLibraryName) != 0)
- return false;
-
- // And the public key or token, which ever was burned into the reference by the compiler. For mscorlib this is the ECMA key or
- // token.
- if (IsAfPublicKeyToken(dwAssemblyFlags)) {
- if (cbPublicKeyOrToken != sizeof(g_rbNeutralPublicKeyToken) ||
- memcmp(pbPublicKeyOrToken, g_rbNeutralPublicKeyToken, cbPublicKeyOrToken) != 0)
- return false;
- } else {
- if (cbPublicKeyOrToken != sizeof(g_rbNeutralPublicKey) ||
- memcmp(pbPublicKeyOrToken, g_rbNeutralPublicKey, cbPublicKeyOrToken) != 0)
- return false;
- }
-
- // If we get here we've finally proved the call target was indeed PrepareConstrainedRegions. Whew.
- return true;
-}
-
-// Prepares a method as a CER root. In some scenarios we set
-// fIgnoreVirtualCERCallMDA=TRUE, this happens when we want to ignore firing a
-// VirtualCERCall MDA because we know for sure that the virtual methods are
-// already prepared. A good example of this case is preparing
-// g_pExecuteBackoutCodeHelperMethod method.
-void PrepareMethodDesc(MethodDesc* pMD, Instantiation classInst, Instantiation methodInst, BOOL onlyContractedMethod, BOOL fIgnoreVirtualCERCallMDA)
-{
- CONTRACTL
- {
- THROWS;
- DISABLED(GC_TRIGGERS);
- MODE_ANY;
- }
- CONTRACTL_END;
-
- GCX_PREEMP();
-
-#ifdef FEATURE_PREJIT
- // This method may have some ngen fixup information provided, in which case we just check that it's been restored and can
- // dispense with the preparation altogether.
- Module *pModule = pMD->GetModule();
- if (pModule->IsNgenCerRootMethod(pMD))
- {
- pMD->CheckRestore();
- pModule->RestoreCer(pMD);
- return;
- }
-#endif
-
- // If we are only going to prepare contracted methods and this method does
- // not have a contract then we just return.
- if (onlyContractedMethod && CheckForReliabilityContract(pMD) < RCL_BASIC_CONTRACT)
- {
- return;
- }
-
- SigTypeContext sTypeContext(pMD, classInst, methodInst);
- MethodCallGraphPreparer mcgp(pMD, &sTypeContext, true, true, fIgnoreVirtualCERCallMDA == TRUE);
- mcgp.Run();
-}
-
-// Prepares the critical finalizer call graph for the given object type (which
-// must derive from CriticalFinalizerObject). This involves preparing at least
-// the finalizer method and possibly some others (for SafeHandle and
-// CriticalHandle derivations). If a module pointer is supplied then only the
-// critical methods introduced in that module are prepared (this is used at
-// ngen time to ensure that we're only generating ngen preparation info for the
-// targetted module).
-void PrepareCriticalFinalizerObject(MethodTable *pMT, Module *pModule)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pMT));
- } CONTRACTL_END;
-
- // Have we prepared this type before?
- if (pMT->CriticalTypeHasBeenPrepared())
- return;
-
- GCX_PREEMP();
-
- // Restore the method table if necessary.
- pMT->CheckRestore();
-
- // Determine the interesting parent class (either SafeHandle, CriticalHandle or CriticalFinalizerObject).
- MethodTable *pSafeHandleClass = MscorlibBinder::GetClass(CLASS__SAFE_HANDLE);
- MethodTable *pCriticalHandleClass = MscorlibBinder::GetClass(CLASS__CRITICAL_HANDLE);
- MethodTable *pParent = pMT;
- while (pParent) {
- if (pParent == g_pCriticalFinalizerObjectClass ||
- pParent == pSafeHandleClass ||
- pParent == pCriticalHandleClass) {
- break;
- }
- pParent = pParent->GetParentMethodTable();
- }
- _ASSERTE(pParent != NULL);
-
- BinderMethodID rgMethods[5];
- int nMethods;
-
- // Prepare the method or methods based on the parent class.
- if (pParent == pSafeHandleClass) {
- rgMethods[0] = METHOD__CRITICAL_FINALIZER_OBJECT__FINALIZE;
- rgMethods[1] = METHOD__SAFE_HANDLE__RELEASE_HANDLE;
- rgMethods[2] = METHOD__SAFE_HANDLE__GET_IS_INVALID;
- rgMethods[3] = METHOD__SAFE_HANDLE__DISPOSE;
- rgMethods[4] = METHOD__SAFE_HANDLE__DISPOSE_BOOL;
- nMethods = 5;
- } else if (pParent == pCriticalHandleClass) {
- rgMethods[0] = METHOD__CRITICAL_FINALIZER_OBJECT__FINALIZE;
- rgMethods[1] = METHOD__CRITICAL_HANDLE__RELEASE_HANDLE;
- rgMethods[2] = METHOD__CRITICAL_HANDLE__GET_IS_INVALID;
- rgMethods[3] = METHOD__CRITICAL_HANDLE__DISPOSE;
- rgMethods[4] = METHOD__CRITICAL_HANDLE__DISPOSE_BOOL;
- nMethods = 5;
- } else {
- _ASSERTE(pParent == g_pCriticalFinalizerObjectClass);
- rgMethods[0] = METHOD__CRITICAL_FINALIZER_OBJECT__FINALIZE;
- nMethods = 1;
- }
-
- for (int iMethod = 0; iMethod < nMethods; iMethod++)
- {
- // Prepare a (possibly virtual) method on an instance. The method is identified via a binder ID, so the initial
- // declaration of the method must reside within mscorlib. We might have ngen fixup information for the method and can avoid direct
- // preparation as well.
-
- MethodDesc *pPrepMethod = pMT->GetMethodDescForSlot(MscorlibBinder::GetMethod(rgMethods[iMethod])->GetSlot());
-#ifdef FEATURE_PREJIT
- if (pPrepMethod->GetModule()->IsNgenCerRootMethod(pPrepMethod)) {
- pPrepMethod->GetModule()->RestoreCer(pPrepMethod);
- }
- else
- if (IsCompilationProcess() && pPrepMethod->IsAbstract()) {
- // Skip abstract methods during NGen (we should not ever get abstract methods here at runtime)
- }
- else
-#endif
- {
- if (pModule == NULL || pPrepMethod->GetModule() == pModule) {
- SigTypeContext _sTypeContext(pPrepMethod, TypeHandle(pMT));
- MethodCallGraphPreparer mcgp(pPrepMethod, &_sTypeContext, true, true);
- mcgp.Run();
- }
- }
- }
-
- // Note the fact that we've prepared this type before to prevent repetition of the work above. (Though repetition is harmless in
- // all other respects, so there's no need to worry about the race setting this flag).
- pMT->SetCriticalTypeHasBeenPrepared();
-}
-
-#ifdef _DEBUG
-
-static const char * const g_rszContractNames[] = { "RCL_NO_CONTRACT", "RCL_BASIC_CONTRACT", "RCL_PREPARE_CONTRACT" };
-static DWORD g_dwContractChecks = 0;
-
-#define ReturnContractLevel(_level) do { \
- g_dwContractChecks++; \
- if ((g_dwContractChecks % 100) == 0 && g_pMethodContractCache) \
- g_pMethodContractCache->DbgDumpStats(); \
- ReliabilityContractLevel __level = (_level); \
- CER_LOG(CONTRACTS, ("%s -- %s\n", pMD->m_pszDebugMethodName, g_rszContractNames[__level])); \
- return __level; \
-} while (false)
-#else
-#define ReturnContractLevel(_level) return (_level)
-#endif
-
-// Look for reliability contracts at the method, class and assembly level and parse them to extract the information we're interested
-// in from a runtime preparation viewpoint. This information is abstracted in the form of the ReliabilityContractLevel enumeration.
-ReliabilityContractLevel CheckForReliabilityContract(MethodDesc *pMD)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pMD));
- } CONTRACTL_END;
-
- // We are attempting to abstract reliability contracts for the given method into three different buckets: those methods that
- // will cause an error (or a MDA report at least) during preparation (RCL_NO_CONTRACT), those we allow but don't prepare
- // (RCL_BASIC_CONTRACT) and those we allow and prepare (RCL_PREPARE_CONTRACT).
- //
- // We place methods into the first bucket below that matches:
- // RCL_NO_CONTRACT -- Methods with no consistency or whose consistency states they may corrupt the appdomain or process.
- // RCL_BASIC_CONTRACT -- Methods that state CER.None (or don't specify a CER attribute)
- // RCL_PREPARE_CONTRACT -- Methods that state CER.MayFail or CER.Success
- //
- // We look for reliability contracts at three levels: method, class and assembly. Definitions found at the method level override
- // those at the class and assembly level and those at the class level override assembly settings.
- //
- // In the interests of efficiency we cache contract information in a number of ways. Firstly we look at a hash of recently
- // queried MethodDescs. This contains authoritative answers (assembly/class/method information has already been composed so on a
- // hit we don't need to look anywhere else). This cache is allocated lazily, never grows (newer items eventually displace older
- // ones), is global, requires no locks and is never freed. The idea is to limit the amount of working set we ever occupy while
- // keeping the CPU usage as low as possible. Typical usages of this method involve querying a small number of methods in a stack
- // walk, possibly multiple times, so a small hash cache should work reasonably well here.
- //
- // On a miss we're going to have to bite the bullet and look at the assembly, class and method. The assembly and class cache
- // this information at load (ngen) time though, so they're not so expensive (class level data is cached on the EEClass, so it's
- // cold data, but the most performance sensitive scenario in which we're called here, ThreadAbort, isn't all that hot).
-
- // Check the cache first, it contains a raw contract level.
- ReliabilityContractLevel eLevel;
- if (g_pMethodContractCache && g_pMethodContractCache->Lookup(pMD, (DWORD*)&eLevel))
- ReturnContractLevel(eLevel);
-
- // Start at the method level and work up until we've found enough information to make a decision. The contract level is composed
- // in an encoded DWORD form that lets us track both parts of the state (consistency and cer) and whether each has been supplied
- // yet. See the RC_* macros for encoding details.
- DWORD dwMethodContractInfo = GetReliabilityContract(pMD->GetMDImport(), pMD->GetMemberDef());
- if (RC_INCOMPLETE(dwMethodContractInfo)) {
- DWORD dwClassContractInfo = pMD->GetClass()->GetReliabilityContract();
- dwMethodContractInfo = RC_MERGE(dwMethodContractInfo, dwClassContractInfo);
- if (RC_INCOMPLETE(dwMethodContractInfo)) {
- DWORD dwAssemblyContractInfo = pMD->GetModule()->GetReliabilityContract();
- dwMethodContractInfo = RC_MERGE(dwMethodContractInfo, dwAssemblyContractInfo);
- }
- }
-
- // We've got an answer, so attempt to cache it for the next time.
-
- // First check we have a cache (we allocate it lazily).
- if (g_pMethodContractCache == NULL) {
- PtrHashCache *pCache = new (nothrow) PtrHashCache();
- if (pCache)
- if (FastInterlockCompareExchangePointer(&g_pMethodContractCache, pCache, NULL) != NULL)
- delete pCache;
- }
-
- // We still might not have a cache in low memory situations. That's OK.
- if (g_pMethodContractCache)
- g_pMethodContractCache->Add(pMD, RC_ENCODED_TO_LEVEL(dwMethodContractInfo));
-
- ReturnContractLevel(RC_ENCODED_TO_LEVEL(dwMethodContractInfo));
-}
-
-
-// Macro used to handle failures in the routine below.
-#define IfFailRetRcNull(_hr) do { if (FAILED(_hr)) return RC_NULL; } while (false)
-
-// Look for a reliability contract attached to the given metadata token in the given scope. Return the result as an encoded DWORD
-// (see the RC_ENCODE macro).
-DWORD GetReliabilityContract(IMDInternalImport *pImport, mdToken tkParent)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pImport));
- } CONTRACTL_END;
-
- HRESULT hr;
- DWORD dwResult = RC_NULL;
-
- // Sadly we only have two unmanaged APIs available to us for looking at custom attributes. One looks up attributes by name but
- // only returns the byte blob, not the attribute ctor information (which we need to parse the blob) while the other returns
- // everything but requires us to enumerate all attributes on a given token looking for the one we're interested in. To keep the
- // cost down we probe for the existence of the attribute using the first API and then use the enumeration method if we get a
- // hit.
- hr = pImport->GetCustomAttributeByName(tkParent, RELIABILITY_CONTRACT_NAME, NULL, NULL);
- if (hr == S_FALSE)
- return RC_NULL;
-
- IfFailRetRcNull(hr);
-
- // Got at least one contract against this parent. Enumerate them all (filtering by name).
- MDEnumHolder hEnum(pImport);
- hr = pImport->SafeAndSlowEnumCustomAttributeByNameInit(tkParent, RELIABILITY_CONTRACT_NAME, &hEnum);
- _ASSERTE(hr != S_FALSE);
- IfFailRetRcNull(hr);
-
- // Enumerate over all the contracts.
- mdToken tkContract;
- while (S_OK == pImport->SafeAndSlowEnumCustomAttributeByNameNext(tkParent, RELIABILITY_CONTRACT_NAME, &hEnum, &tkContract)) {
-
- // Get the attribute type (token of the ctor used) since we need this information in order to parse the blob we'll find
- // next.
- mdToken tkAttrType;
- IfFailRetRcNull(pImport->GetCustomAttributeProps(tkContract, &tkAttrType));
- if (!pImport->IsValidToken(tkAttrType))
- continue;
-
- // The token should be a member ref or method def.
- // Get the signature of the ctor so we know which version has been called.
- PCCOR_SIGNATURE pSig;
- DWORD cbSig;
- LPCSTR szName_Ignore;
- if (TypeFromToken(tkAttrType) == mdtMemberRef)
- {
- IfFailRetRcNull(pImport->GetNameAndSigOfMemberRef(tkAttrType, &pSig, &cbSig, &szName_Ignore));
- }
- else
- {
- if (TypeFromToken(tkAttrType) != mdtMethodDef)
- continue;
- IfFailRetRcNull(pImport->GetNameAndSigOfMethodDef(tkAttrType, &pSig, &cbSig, &szName_Ignore));
- }
-
- // Only two signatures are supported: the null sig '()' and the full sig '(Consistency, CER)'.
- // Set a boolean based on which one was provided.
- bool fNullCtor;
- ULONG eCallConv;
-
- SigPointer sig(pSig, cbSig);
-
- // Check the calling convention is what we expect (default convention on an instance method).
- IfFailRetRcNull(sig.GetCallingConvInfo(&eCallConv));
- _ASSERTE(eCallConv == (IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS));
- if (eCallConv != (IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS))
- IfFailRetRcNull(COR_E_BADIMAGEFORMAT);
-
- // If so, the next datum is the count of arguments, and this is all we need to determine which ctor has been used.
- ULONG dwArgs;
- IfFailRetRcNull(sig.GetData(&dwArgs));
- _ASSERTE(dwArgs == 0 || dwArgs == 2);
- if (dwArgs != 0 && dwArgs != 2)
- IfFailRetRcNull(COR_E_BADIMAGEFORMAT);
-
- fNullCtor = dwArgs == 0;
-
- // Now we know how to parse the blob, let's fetch a pointer to it.
- BYTE const *pbData;
- DWORD cbData;
- IfFailRetRcNull(pImport->GetCustomAttributeAsBlob(tkContract, (const void **)&pbData, &cbData));
-
- // Check serialization format (we support version 1 only).
- if (cbData < sizeof(WORD) || GET_UNALIGNED_VAL16(pbData) != 1)
- IfFailRetRcNull(COR_E_BADIMAGEFORMAT);
- pbData += sizeof(WORD);
- cbData -= sizeof(WORD);
-
- // Parse ctor arguments if we have any.
- if (!fNullCtor) {
-
- // We assume the enums are based on DWORDS.
- if (cbData < (sizeof(DWORD) * 2))
- IfFailRetRcNull(COR_E_BADIMAGEFORMAT);
-
- // Consistency first.
- DWORD dwConsistency = GET_UNALIGNED_VAL32(pbData);
- pbData += sizeof(DWORD);
- cbData -= sizeof(DWORD);
- if (dwConsistency > RC_CONSISTENCY_CORRUPT_NOTHING)
- IfFailRetRcNull(COR_E_BADIMAGEFORMAT);
-
- // Followed by Cer.
- DWORD dwCer = GET_UNALIGNED_VAL32(pbData);
- pbData += sizeof(DWORD);
- cbData -= sizeof(DWORD);
- if (dwCer > RC_CER_SUCCESS)
- IfFailRetRcNull(COR_E_BADIMAGEFORMAT);
-
- dwResult = RC_MERGE(dwResult, RC_ENCODE(dwConsistency, dwCer));
- }
-
- // Get the count of field/property, value pairs.
- if (cbData < sizeof(WORD))
- IfFailRetRcNull(COR_E_BADIMAGEFORMAT);
- WORD cPairs = GET_UNALIGNED_VAL16(pbData);
- pbData += sizeof(WORD);
- cbData -= sizeof(WORD);
-
- // Iterate over any such pairs, looking for values we haven't picked up yet.
- for (DWORD i = 0 ; i < cPairs; i++) {
-
- // First is a field vs property selector. We expect only properties.
- if (cbData < sizeof(BYTE) || *(BYTE*)pbData != SERIALIZATION_TYPE_PROPERTY)
- IfFailRetRcNull(COR_E_BADIMAGEFORMAT);
- pbData += sizeof(BYTE);
- cbData -= sizeof(BYTE);
-
- // Next is the type of the property. It had better be an enum.
- if (cbData < sizeof(BYTE) || *(BYTE*)pbData != SERIALIZATION_TYPE_ENUM)
- IfFailRetRcNull(COR_E_BADIMAGEFORMAT);
- pbData += sizeof(BYTE);
- cbData -= sizeof(BYTE);
-
- // Next we have the assembly qualified enum type name. This is preceded by a metadata style packed byte length (the
- // string itself is 8-bit and not null terminated). Ignore it (just skip across) and we'll key off the property name
- // (coming up) instead.
- DWORD cbName;
- BYTE const * pbPostEncodedLength;
- IfFailRetRcNull(CPackedLen::SafeGetData(pbData, cbData, &cbName, &pbPostEncodedLength));
- DWORD cbEncodedLength = static_cast<DWORD>(pbPostEncodedLength - pbData);
- pbData += cbEncodedLength + cbName;
- cbData -= cbEncodedLength + cbName;
-
- // Now we have the name of the property (in a similar format to above).
- IfFailRetRcNull(CPackedLen::SafeGetData(pbData, cbData, &cbName, &pbPostEncodedLength));
- cbEncodedLength = static_cast<DWORD>(pbPostEncodedLength - pbData);
- pbData += cbEncodedLength;
- cbData -= cbEncodedLength;
-
- bool fConsistencyProp = false;
- if (cbName == strlen(RC_CONSISTENCY_PROP_NAME) && strncmp((const char*)pbData, RC_CONSISTENCY_PROP_NAME, cbName) == 0)
- fConsistencyProp = true;
- else if (cbName == strlen(RC_CER_PROP_NAME) && strncmp((const char*)pbData, RC_CER_PROP_NAME, cbName) == 0)
- fConsistencyProp = false;
- else
- IfFailRetRcNull(COR_E_BADIMAGEFORMAT);
- pbData += cbName;
- cbData -= cbName;
-
- // And finally the actual enum value (again, we assume the underlying type is a DWORD).
- if (cbData < sizeof(DWORD))
- IfFailRetRcNull(COR_E_BADIMAGEFORMAT);
- DWORD dwValue = GET_UNALIGNED_VAL32(pbData);
- pbData += sizeof(DWORD);
- cbData -= sizeof(DWORD);
-
- if (fConsistencyProp) {
- if (dwValue > RC_CONSISTENCY_CORRUPT_NOTHING)
- IfFailRetRcNull(COR_E_BADIMAGEFORMAT);
- dwResult = RC_MERGE(dwResult, RC_ENCODE(dwValue, RC_CER_UNDEFINED));
- } else {
- if (dwValue > RC_CER_SUCCESS)
- IfFailRetRcNull(COR_E_BADIMAGEFORMAT);
- dwResult = RC_MERGE(dwResult, RC_ENCODE(RC_CONSISTENCY_UNDEFINED, dwValue));
- }
- }
-
- // Shouldn't have any bytes left in the blob at this stage.
- _ASSERTE(cbData == 0);
- }
-
- // Return the result encoded and packed into the 2 low order bits of a DWORD.
- return dwResult;
-}
-
-// Given a metadata token, a scoping module and a type context, look up the appropriate MethodDesc (and recomputed accompanying type
-// context).
-MethodContext *TokenToMethodDesc(Module *pModule, mdToken tokMethod, SigTypeContext *pTypeContext)
-{
- STANDARD_VM_CONTRACT;
-
- // Validate that the token is one that we can handle.
- if (!pModule->GetMDImport()->IsValidToken(tokMethod) || (TypeFromToken(tokMethod) != mdtMethodDef &&
- TypeFromToken(tokMethod) != mdtMethodSpec &&
- TypeFromToken(tokMethod) != mdtMemberRef)) {
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_INVALID_METHOD_TOKEN);
- }
-
- // Look up the MethodDesc based on the token and type context.
- MethodDesc *pMD = MemberLoader::GetMethodDescFromMemberDefOrRefOrSpec(pModule,
- tokMethod,
- pTypeContext,
- TRUE,
- FALSE);
-
- // The MethodDesc we get might be shared between several types. If so we'll need to do extra work to locate the exact
- // class instantiation instead of the default representative one.
- SigTypeContext sNewTypeContext;
- if (pMD->IsSharedByGenericInstantiations()) {
- TypeHandle th = GetTypeFromMemberDefOrRefOrSpecThrowing(pModule,
- tokMethod,
- pTypeContext);
- SigTypeContext::InitTypeContext(pMD, th,&sNewTypeContext);
- } else
- SigTypeContext::InitTypeContext(pMD, pMD->GetClassInstantiation(), pMD->GetMethodInstantiation(),&sNewTypeContext);
-
- return MethodContext::PerThreadAllocate(pMD, &sNewTypeContext);
-}
-
-// Locate an exact type definition given a method token and the type context in which it can be resolved.
-TypeHandle GetTypeFromMemberDefOrRefOrSpecThrowing(Module *pModule,
- mdToken tokMethod,
- SigTypeContext *pTypeContext)
-{
- STANDARD_VM_CONTRACT;
-
- IMDInternalImport *pImport = pModule->GetMDImport();
-
- // Convert method specs into the underlying member ref.
- if (TypeFromToken(tokMethod) == mdtMethodSpec)
- {
- PCCOR_SIGNATURE pSig;
- ULONG cSig;
- mdMemberRef tkGenericMemberRef;
-
- IfFailThrow(pImport->GetMethodSpecProps(tokMethod, &tkGenericMemberRef, &pSig, &cSig));
-
- if (!pImport->IsValidToken(tkGenericMemberRef) ||
- (TypeFromToken(tkGenericMemberRef) != mdtMethodDef &&
- TypeFromToken(tkGenericMemberRef) != mdtMemberRef))
- {
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_INVALID_TOKEN_TYPE);
- }
-
- tokMethod = tkGenericMemberRef;
- }
-
- // Follow the member ref/def back up to the type def/ref/spec or module (for global methods).
- if (TypeFromToken(tokMethod) == mdtMemberRef)
- {
- IfFailThrow(pImport->GetParentOfMemberRef(tokMethod, &tokMethod));
-
- // For varargs, a memberref can point to a methodDef
- if (TypeFromToken(tokMethod) == mdtMethodDef)
- {
- if (!pImport->IsValidToken(tokMethod))
- {
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_INVALID_TOKEN);
- }
- IfFailThrow(pImport->GetParentToken(tokMethod, &tokMethod));
- }
- }
- else if (TypeFromToken(tokMethod) == mdtMethodDef)
- {
- IfFailThrow(pImport->GetParentToken(tokMethod, &tokMethod));
- }
-
- if (!pImport->IsValidToken(tokMethod) || (TypeFromToken(tokMethod) != mdtTypeDef &&
- TypeFromToken(tokMethod) != mdtTypeRef &&
- TypeFromToken(tokMethod) != mdtTypeSpec &&
- TypeFromToken(tokMethod) != mdtModuleRef))
- {
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_INVALID_TOKEN);
- }
-
- // Load the type in question, using a type context if necessary to get an exact representation.
- TypeHandle th;
- if (TypeFromToken(tokMethod) == mdtModuleRef) {
- DomainFile *pNewModule = pModule->LoadModule(GetAppDomain(), tokMethod, FALSE);
- if (pNewModule != NULL)
- th = TypeHandle(pNewModule->GetModule()->GetGlobalMethodTable());
- } else {
- th = ClassLoader::LoadTypeDefOrRefOrSpecThrowing(pModule,
- tokMethod,
- pTypeContext);
- }
-
- if (th.IsNull())
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
-
- return th;
-}
-
-// Determine whether the method given as a parameter is the root of a CER.
-// @todo: Need an x86 offset as well and logic to determine whether we're actually in a root-CER portion of the method (if the whole
-// thing isn't the root).
-bool IsCerRootMethod(MethodDesc *pMD)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pMD));
- SO_TOLERANT;
- } CONTRACTL_END;
-
- // Treat IL stubs as CER roots (marshaling code needs to string together operations without being interruped by thread aborts).
- if (pMD->IsILStub())
- return true;
-
- // There are some well defined root methods defined by the system.
- if (pMD == g_pExecuteBackoutCodeHelperMethod)
- return true;
-
- // For now we just look to see whether there is some prep or fixup info stored for this method.
- Module *pModule = pMD->GetModule();
-
- if (pModule->GetCerPrepInfo(pMD) != NULL)
- return true;
-
-#ifdef FEATURE_PREJIT
- if (pModule->IsNgenCerRootMethod(pMD))
- return true;
-#endif
-
- return false;
-}
-
-// Fill the cache of overflowed generic dictionary entries that the jit maintains with all the overflow slots stored so far in the
-// dictionary layout.
-void PrepopulateGenericHandleCache(DictionaryLayout *pDictionaryLayout,
- MethodDesc *pMD,
- MethodTable *pMT)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- } CONTRACTL_END;
-
- // Dictionary overflow entries are recorded starting in the second bucket of the dictionary layout.
- DictionaryLayout *pOverflows = pDictionaryLayout->GetNextLayout();
-
- while (pOverflows) {
- for (DWORD i = 0; i < pOverflows->GetMaxSlots(); i++) {
- DictionaryEntryLayout *pEntry = pOverflows->GetEntryLayout(i);
-
- // We've finished as soon as we find the first unused slot.
- if (!pEntry->m_signature)
- return;
-
- // We have a valid overflow entry. Determine the handle value given the type context we have and push it into the JIT's
- // cache.
- JIT_GenericHandleWorker(pMD, pMT, pEntry->m_signature);
- }
- pOverflows = pOverflows->GetNextLayout();
- }
-}
-
-#ifdef FEATURE_PREJIT
-
-// Prepare the CER rooted at the given method (it's OK to pass a MethodDesc* that doesn't root a CER, in which case the method
-// is a no-op).
-void CerNgenRootTable::Restore(MethodDesc *pRootMD)
-{
-#ifndef CROSSGEN_COMPILE
- STANDARD_VM_CONTRACT;
-
- // We don't have a restoration bitmap at ngen time. No matter, we just always claim everything is restored.
- if (m_pRestoreBitmap == NULL)
- return;
-
- // Locate the root index from the table. Failure indicates there's no work to do.
- DWORD dwIndex = FindIndex(pRootMD);
- if (dwIndex == NoSuchRoot)
- return;
-
- _ASSERTE(m_pRoots[dwIndex].m_pRootMD == pRootMD);
-
- // Check then mark the fact that we're preparing (to prevent potential recursion).
- SigTypeContext typeContext;
- if (!GetThread()->GetCerPreparationState()->CanPreparationProceed(pRootMD, &typeContext))
- return;
-
- MethodCallGraphPreparer sPrep(pRootMD, &typeContext, true, true);
- MethodCallGraphPreparer::ThreadPreparingCerHolder sCerHolder(&sPrep);
-
-#ifdef _DEBUG
- if (GetCerLoggingOptions())
- {
- CER_LOG(RESTORE, ("---------------------------------------------------------------\n"));
- SString ssRootMethod;
- TypeString::AppendMethodInternal(ssRootMethod, pRootMD, TypeString::FormatNamespace | TypeString::FormatStubInfo);
- CER_LOG(RESTORE, ("Restoring CER graph from %S\n", ssRootMethod.GetUnicode()));
- }
-#endif
-
- g_IBCLogger.LogCerMethodListReadAccess(pRootMD);
-
- // Retrieve the CerRoot structure.
- CerRoot *pRoot = &m_pRoots[dwIndex];
- _ASSERTE(pRoot->m_pRootMD == pRootMD);
-
- // Scan the list of methods in the CER (the last one is a sentinel with a NULL MethodDesc*). Restore each method as we go.
- MethodContextElement *pEntry = pRoot->m_pList;
- while (pEntry->GetMethodDesc())
- {
- // Method desc and type handle pointers may still be tokenized at this point.
- Module::RestoreMethodDescPointer(&pEntry->m_pMethodDesc);
- Module::RestoreMethodTablePointer(&pEntry->m_pExactMT);
-
- g_IBCLogger.LogCerMethodListReadAccess(pEntry->GetMethodDesc());
-
- MethodDesc * pMD = pEntry->GetMethodDesc();
-
- // Check whether there are generic dictionaries that need to be pre-populated.
-
- // Don't use the direct PrepopulateDictionary method here for MethodTable/MethodDesc
- // - MethodTable: Takes binding considerations into account (which we don't care about)
- // - MethodDesc: Appears to use a representative class instantiation (and we have the exact one handy)
- //
- // Additionally, avoid touching EE Class if we don't need to
- MethodTable * pMT = pEntry->GetExactMT();
- if (pMT != NULL)
- {
- // MethodTable
- DictionaryLayout *pClassDictLayout = pMT->GetClass()->GetDictionaryLayout();
- if (pClassDictLayout)
- {
- pMT->GetDictionary()->PrepopulateDictionary(NULL, pMT, false);
-
- // The dictionary may have overflowed in which case we need to prepopulate the jit's lookup cache as well.
- PrepopulateGenericHandleCache(pClassDictLayout, NULL, pMT);
- }
-
- // MethodDesc
- DictionaryLayout *pMethDictLayout = pMD->GetDictionaryLayout();
- if (pMethDictLayout)
- {
- pMD->GetMethodDictionary()->PrepopulateDictionary(pMD, NULL, false);
-
- // The dictionary may have overflowed in which case we need to prepopulate the jit's lookup cache as well.
- PrepopulateGenericHandleCache(pMethDictLayout, pMD, NULL);
- }
- }
-
- // Recreate stubs used by P/Invoke, COM calls, or FCalls by exercising the prestub.
- if (pMD->IsPointingToPrestub() && (pMD->IsNDirect() || pMD->IsComPlusCall() || pMD->IsFCall()))
- {
- pMD->EnsureActive();
- pMD->DoPrestub(NULL);
- }
-
-#ifdef _DEBUG
- if (GetCerLoggingOptions())
- {
- SString ssMethod;
- TypeString::AppendMethodInternal(ssMethod, pMD, TypeString::FormatNamespace | TypeString::FormatStubInfo);
- CER_LOG(RESTORE, (" %S\n", ssMethod.GetUnicode()));
- }
-#endif
-
- // Move to next entry.
- pEntry++;
- }
-
- CER_LOG(RESTORE, ("---------------------------------------------------------------\n"));
-
- // Mark this whole CER region as fixed up by setting a flag in the restore bitmap (kept separate so we can cluster all our page
- // writes).
- // Compute the DWORD offset into the flag array and then the mask for the specific bit in that DWORD.
- DWORD dwOffset = dwIndex / (sizeof(DWORD) * 8);
- DWORD dwMask = 1 << (dwIndex % (sizeof(DWORD) * 8));
- EnsureWritablePages(m_pRestoreBitmap, sizeof(DWORD) * SizeOfRestoreBitmap());
- FastInterlockOr(&m_pRestoreBitmap[dwOffset], dwMask);
-
- // If we fixed up any methods with their own CERs then we will have implicitly fixed up those too. Mark their fixup records as
- // completed as well to avoid further unecessary work.
- pEntry = pRoot->m_pList;
- while (pEntry->GetMethodDesc()) {
- dwIndex = FindIndex(pEntry->GetMethodDesc());
- if (dwIndex != NoSuchRoot) {
- dwOffset = dwIndex / (sizeof(DWORD) * 8);
- dwMask = 1 << (dwIndex % (sizeof(DWORD) * 8));
- FastInterlockOr(&m_pRestoreBitmap[dwOffset], dwMask);
- }
- pEntry++;
- }
-#endif // CROSSGEN_COMPILE
-}
-
-#ifdef FEATURE_NATIVE_IMAGE_GENERATION
-// Add a new root to the table, expanding it as necessary. Note that this method must be called with the CerCrst already held.
-void CerNgenRootTable::AddRoot(MethodDesc *pRootMD, MethodContextElement *pList)
-{
- CONTRACTL {
- STANDARD_VM_CHECK;
- PRECONDITION(IsOwnerOfCrst(pRootMD->GetModule()->GetCerCrst()));
- } CONTRACTL_END;
-
- // Ensure we have enough space first.
- if (m_cRoots == m_cSlots) {
- DWORD cNewSize = m_cSlots + 16;
- CerRoot *pNewArray = new CerRoot[cNewSize];
- memcpyNoGCRefs(pNewArray, m_pRoots, m_cRoots * sizeof(CerRoot));
- MethodContextElement **pNewRootsInCompilationOrder = new MethodContextElement*[cNewSize];
- memcpyNoGCRefs(pNewRootsInCompilationOrder, m_pRootsInCompilationOrder, m_cRoots * sizeof(MethodContextElement*) );
- m_cSlots = cNewSize;
- delete m_pRoots;
- m_pRoots = pNewArray;
- delete m_pRootsInCompilationOrder;
- m_pRootsInCompilationOrder = pNewRootsInCompilationOrder;
- }
-
- // Fill in the new entry in sorted order.
- DWORD i;
- for (i = 0; i < m_cRoots; i++)
- if ((UPTR) m_pRoots[i].m_pRootMD > (UPTR) pRootMD)
- break;
- if (i < m_cRoots)
- memmove(&m_pRoots[i + 1], &m_pRoots[i], (m_cRoots - i) * sizeof(CerRoot));
- m_pRoots[i].m_pRootMD = pRootMD;
- m_pRoots[i].m_pList = pList;
-
- m_pRootsInCompilationOrder[m_cRoots] = pList;
-
- m_cRoots++;
-}
-
-// Ngen callouts to help serialize this structure and its children to storage.
-void CerNgenRootTable::Save(DataImage *image, CorProfileData *profileData)
-{
- STANDARD_VM_CONTRACT;
-
-#ifdef _DEBUG
- DWORD dwMaxEntries = 0;
- DWORD dwTotalEntries = 0;
-#endif
-
- image->StoreStructure(this, sizeof(CerNgenRootTable), DataImage::ITEM_CER_ROOT_TABLE);
- image->StoreStructure(m_pRoots, m_cRoots * sizeof(CerRoot), DataImage::ITEM_CER_ROOT_TABLE);
-
- // Create a bitmap of boolean flags (1 bit per flag) indicating whether the CER at a given index in the array has been restored.
- // This is initially all zero and only filled in at runtime (keep all the flags together this way because they're the only
- // things we have to write at runtime and we want to keep them as dense as possible).
- _ASSERTE((SizeOfRestoreBitmap() % sizeof(DWORD)) == 0);
- m_pRestoreBitmap = new DWORD[SizeOfRestoreBitmap() / sizeof(DWORD)];
- memset(m_pRestoreBitmap, 0xff, SizeOfRestoreBitmap());
-
- image->StoreStructure(m_pRestoreBitmap,
- SizeOfRestoreBitmap(),
- DataImage::ITEM_CER_RESTORE_FLAGS);
-
- // Next save off the list of MethodContextElements associated with each root.
- for (DWORD i = 0; i < m_cRoots; i++) {
- MethodContextElement *pEntry = m_pRootsInCompilationOrder[i];
-
- // Count entries in list.
- DWORD cEntries = 0;
- while (pEntry->GetMethodDesc()) {
- cEntries++;
- pEntry++;
- }
-
- // Plus one for the sentinel value.
- cEntries++;
-
-#ifdef _DEBUG
- dwTotalEntries += cEntries;
- if (cEntries > dwMaxEntries)
- dwMaxEntries = cEntries;
-#endif
-
- // Store this list.
- image->StoreStructure(m_pRootsInCompilationOrder[i],
- cEntries * sizeof(MethodContextElement),
- DataImage::ITEM_CER_METHOD_LIST);
- }
-
-#ifdef _DEBUG
- if (m_cRoots > 0) {
- CER_LOG(NGEN_STATS, ("Saving %u CER roots in ngen image\n", m_cRoots));
- CER_LOG(NGEN_STATS, (" Max methods in CER: %u\n", dwMaxEntries));
- CER_LOG(NGEN_STATS, (" Avg methods in CER: %.1f\n", (float)((float)dwTotalEntries / (float)m_cRoots)));
- } else
- CER_LOG(NGEN_STATS, ("No CER roots in ngen image\n"));
-#endif
-}
-
-void CerNgenRootTable::Fixup(DataImage *image)
-{
- STANDARD_VM_CONTRACT;
-
- DWORD i;
-
- // We still use the point to the root array even though at runtime the two structures will be adjacent.
- image->FixupPointerField(this, offsetof(CerNgenRootTable, m_pRoots));
-
- // Restoration flags are used only at runtime and must start off zeroed.
- image->FixupPointerField(this, offsetof(CerNgenRootTable, m_pRestoreBitmap));
- image->ZeroField(m_pRestoreBitmap, 0, SizeOfRestoreBitmap());
-
- // The root list in compilation order is only used at ngen time, and is not written into native image.
- image->ZeroPointerField(this, offsetof(CerNgenRootTable, m_pRootsInCompilationOrder));
-
- // Fixup all the pointers in the individual CERs.
- for (i = 0; i < m_cRoots; i++) {
-
- // For each MethodContextElement in the list we need to fixup a pointer to a MethodDesc and two array pointers (one for any
- // class instantiation and one for any method instantiation). The actual MethodDescs and TypeHandles themselves are already
- // fixed up as are the instantiation arrays we point to (they're the ones inside the generic dictionaries of the class/method
- // concerned).
- MethodContextElement *pList = m_pRootsInCompilationOrder[i];
- MethodContextElement *pEntry = pList;
- while (pEntry->GetMethodDesc()) {
- image->FixupMethodDescPointer(pList, &pEntry->m_pMethodDesc);
- image->FixupMethodTablePointer(pList, &pEntry->m_pExactMT);
- pEntry++;
- }
- }
-}
-
-void CerNgenRootTable::FixupRVAs(DataImage *image)
-{
- STANDARD_VM_CONTRACT;
-
- DWORD i, j;
-
- // Now we go back through the root table and sort the entries based on the locations of the root method descs in the new image
- // (they may be rearranged due to IBC profiling).
- CerRoot *pNewRoots = (CerRoot*)image->GetImagePointer(m_pRoots);
- PREFIX_ASSUME(pNewRoots != NULL);
-
- // Simple insertion sort. Starting at the second element insert a candidate into its correct location in the sub-list
- // preceding it (which by definition will already be sorted).
- for (i = 1; i < m_cRoots; i++)
- {
- // Look at all of the preceding elements for the first that is larger than the candidate (i.e. should succeed the
- // candidate in sorted order). If we don't find one then the candidate is already in place and we can proceed to the
- // next candidate.
- for (j = 0; j < i; j++)
- if (image->GetRVA(pNewRoots[j].m_pRootMD) > image->GetRVA(pNewRoots[i].m_pRootMD)) {
-
- // Need to move candidate element up. Cache its value because we're about to overwrite it.
- MethodDesc *pTmpRootMD = pNewRoots[i].m_pRootMD;
- MethodContextElement *pTmpList = pNewRoots[i].m_pList;
-
- // Shuffle the sorted list one up to make room for the candidate.
- memmove(&pNewRoots[j + 1], &pNewRoots[j], (i - j) * sizeof(CerRoot));
-
- // Insert the candidate into position.
- pNewRoots[j].m_pRootMD = pTmpRootMD;
- pNewRoots[j].m_pList = pTmpList;
-
- // Sorted the candidate, move onto the next.
- break;
- }
- }
-
- // Fixup all the pointers in the individual CERs.
- for (i = 0; i < m_cRoots; i++) {
- // Fix up the pointer to the root method and the list of methods in the CER.
- image->FixupField(m_pRoots, sizeof(CerRoot) * i + offsetof(CerRoot, m_pRootMD),
- pNewRoots[i].m_pRootMD);
- image->FixupField(m_pRoots, sizeof(CerRoot) * i + offsetof(CerRoot, m_pList),
- pNewRoots[i].m_pList);
- }
-}
-#endif // FEATURE_NATIVE_IMAGE_GENERATION
-
-// Locate the index of a given CerRoot record in the array given the root method. This is used to access the array and to locate the
-// restored flag for the entry in the restored bitmap. NoSuchRoot is returned if the root cannot be found.
-DWORD CerNgenRootTable::FindIndex(MethodDesc *pRootMD)
-{
- CONTRACTL {
- NOTHROW;
- MODE_ANY;
- GC_NOTRIGGER;
- PRECONDITION(CheckPointer(pRootMD));
- SO_TOLERANT;
- } CONTRACTL_END;
-
- // The table is guaranteed to be sorted, so we can lookup our target with a binary search.
- DWORD dwLow = 0;
- DWORD dwHigh = m_cRoots - 1;
- while (true) {
-
- // Take out the simple cases first.
-
- // The range has only one entry.
- if (dwLow == dwHigh) {
- if (m_pRoots[dwLow].m_pRootMD == pRootMD)
- return dwLow;
-#ifdef _DEBUG
- for (DWORD i = 0; i < m_cRoots; i++)
- _ASSERTE(m_pRoots[i].m_pRootMD != pRootMD);
-#endif
- return NoSuchRoot;
- }
-
- // The range has only two entries.
- if (dwLow == dwHigh - 1) {
- if (m_pRoots[dwLow].m_pRootMD == pRootMD)
- return dwLow;
- if (m_pRoots[dwHigh].m_pRootMD == pRootMD)
- return dwHigh;
-#ifdef _DEBUG
- for (DWORD i = 0; i < m_cRoots; i++)
- _ASSERTE(m_pRoots[i].m_pRootMD != pRootMD);
-#endif
- return NoSuchRoot;
- }
-
- // Now we can compute a midpoint that is definitely distinct and in-between the endpoints.
- DWORD dwMid = dwLow + ((dwHigh - dwLow) / 2);
-
- // Did we nail it?
- if (m_pRoots[dwMid].m_pRootMD == pRootMD)
- return dwMid;
-
- // Otherwise adjust our range to be the bit we haven't looked at and iterate.
- if ((UPTR)m_pRoots[dwMid].m_pRootMD < (UPTR)pRootMD)
- dwLow = dwMid + 1;
- else
- dwHigh = dwMid - 1;
- }
-}
-
-// Prepare the class if it is derived from CriticalFinalizerObject. This is used at ngen time since such classes are normally
-// prepared at runtime (at instantiation) and would therefore miss the ngen image.
-void PrepareCriticalType(MethodTable * pMT)
-{
- STANDARD_VM_CONTRACT;
-
- // Prepare any class that satisfies the criteria. Pass a pointer to this module so that we'll only prepare any overrides of
- // the critical methods that were actually introduced here.
- if (pMT->HasCriticalFinalizer())
- PrepareCriticalFinalizerObject(pMT, pMT->GetLoaderModule());
-}
-
-// Prepare a method and its statically determinable call graph if a hint attribute has been applied. This is only called at ngen
-// time to save additional preparation information into the ngen image that wouldn't normally be there (and thus lower runtime
-// overheads).
-void PrePrepareMethodIfNecessary(CORINFO_METHOD_HANDLE hMethod)
-{
- STANDARD_VM_CONTRACT;
-
- EX_TRY {
-
- // Translate jit-style method handle into method desc.
- MethodDesc *pMD = GetMethod(hMethod);
-
- // Check for the existance of the attribute.
- IMDInternalImport *pImport = pMD->GetMDImport();
- mdToken tkMethod = pMD->GetMemberDef();
- HRESULT hr = pImport->GetCustomAttributeByName(tkMethod,
- "System.Runtime.ConstrainedExecution.PrePrepareMethodAttribute",
- NULL, NULL);
-
- // TODO: We should add IBC probes which indicate that methods need to be preprepared
- // which can then be reflected in the IBC data, we can add an additional check
- // here to cover that case, then we can get around this problem with profiling
- // instead of manual programmer effort.
-
- // Only prepare if we definitely saw the attribute.
- if (hr == S_OK) {
- // Prepare the method and its graph. There should never be any open type parameters (we can't do much at ngen time with these),
- // so we can pass a null type context.
- SigTypeContext sTypeContext;
- MethodCallGraphPreparer mcgp(pMD, &sTypeContext, true, true);
- mcgp.Run();
- }
-
- } EX_CATCH {
- } EX_END_CATCH(SwallowAllExceptions);
-}
-
-#endif // FEATURE_PREJIT
-
-PtrHashCache::PtrHashCache()
-{
- LIMITED_METHOD_CONTRACT;
- ZeroMemory(this, sizeof(*this));
-
- // First entry in each bucket is a chain index used to evenly distribute inserts within a bucket.
- _ASSERTE(PHC_CHAIN > 1);
-}
-
-bool PtrHashCache::Lookup(void *pKey, DWORD *pdwValue)
-{
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(((UINT_PTR)pKey & PHC_DATA_MASK) == 0);
-
- DWORD dwBucket = GetHash(pKey);
-
- // Skip first entry in bucket, it's a sequence number used for insertions.
- for (DWORD i = 1; i < PHC_CHAIN; i++) {
- UINT_PTR uipEntry = VolatileLoad<UINT_PTR>(&m_rEntries[(dwBucket * PHC_CHAIN) + i]);
- if ((uipEntry & ~PHC_DATA_MASK) == (UINT_PTR)pKey) {
-#ifdef _DEBUG
- FastInterlockIncrement((LONG*)&m_dwHits);
-#endif
- *pdwValue = uipEntry & PHC_DATA_MASK;
- return true;
- }
- }
-
-#ifdef _DEBUG
- FastInterlockIncrement((LONG*)&m_dwMisses);
-#endif
- return false;
-}
-
-void PtrHashCache::Add(void *pKey, DWORD dwValue)
-{
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(((UINT_PTR)pKey & PHC_DATA_MASK) == 0);
- _ASSERTE((dwValue & ~PHC_DATA_MASK) == 0);
-
- DWORD dwBucket = GetHash(pKey);
-
- // We keep a sequence number in the first entry of the bucket so that we distribute insertions within the bucket evenly. We're
- // racing when we update this value, but it doesn't matter if we lose an update (we're a cache after all). We don't bother being
- // careful to avoid overflowing the value here (we just keep incrementing); we'll do the modulo logic when we insert our value
- // instead.
- DWORD dwIndex = static_cast<DWORD>(m_rEntries[dwBucket * PHC_CHAIN]++);
- dwIndex = (dwIndex % (PHC_CHAIN - 1)) + 1;
- m_rEntries[(dwBucket * PHC_CHAIN) + dwIndex] = ((UINT_PTR)pKey & ~PHC_DATA_MASK) | dwValue;
-}
-
-DWORD PtrHashCache::GetHash(void *pKey)
-{
- LIMITED_METHOD_CONTRACT;
-
- return (DWORD)(((UINT_PTR)pKey >> 4) % PHC_BUCKETS);
-}
-
-#ifdef _DEBUG
-void PtrHashCache::DbgDumpStats()
-{
-#if 0
- if ((m_dwHits + m_dwMisses) == 0)
- return;
-
- printf("Dumping stats for PtrHashCache %08X\n", this);
- printf(" %u hits, %u misses (%u%% hit rate)\n", m_dwHits, m_dwMisses, (m_dwHits * 100) / (m_dwHits + m_dwMisses));
- for (DWORD i = 0; i < PHC_BUCKETS; i++)
- printf(" [%2u] : %u insertions\n", i, m_rEntries[i * PHC_CHAIN]);
- printf("\n");
-#endif
-}
-#endif
diff --git a/src/vm/constrainedexecutionregion.h b/src/vm/constrainedexecutionregion.h
deleted file mode 100644
index 4b41b2570e..0000000000
--- a/src/vm/constrainedexecutionregion.h
+++ /dev/null
@@ -1,566 +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.
-//
-// Methods to support the implementation of Constrained Execution Regions (CERs). This includes logic to walk the IL of methods to
-// determine the statically determinable call graph and prepare each submethod (jit, prepopulate generic dictionaries etc.,
-// everything needed to ensure that the runtime won't generate implicit failure points during the execution of said call graph).
-//
-
-//
-
-
-#ifndef __CONSTRAINED_EXECUTION_REGION_H
-#define __CONSTRAINED_EXECUTION_REGION_H
-
-#ifdef FEATURE_CER
-
-#include <corhlpr.h>
-#include <typestring.h>
-
-
-// An enumeration that abstracts the interesting information (from our point of view) present in a reliability contract decorating a
-// method.
-enum ReliabilityContractLevel
-{
- RCL_UNKNOWN = -1, // The contract attribute hasn't been read yet
- RCL_NO_CONTRACT = 0, // No contract (or a fairly useless one) was specified
- RCL_BASIC_CONTRACT = 1, // The contract promises enough for the method to be a legal member of a CER call graph
- RCL_PREPARE_CONTRACT = 2, // The contract promises enough to be worth preparing the method as part of a CER call graph
-};
-
-// Various definitions used to parse reliability contracts. These must be kept synchronized with the managed version in
-// BCL\System\Runtime\Reliability\ReliabilityContractAttribute.cs
-
-#define RELIABILITY_CONTRACT_NAME "System.Runtime.ConstrainedExecution.ReliabilityContractAttribute"
-#define RC_CONSISTENCY_PROP_NAME "ConsistencyGuarantee"
-#define RC_CER_PROP_NAME "Cer"
-
-enum {
- RC_CONSISTENCY_CORRUPT_PROCESS = 0,
- RC_CONSISTENCY_CORRUPT_APPDOMAIN = 1,
- RC_CONSISTENCY_CORRUPT_INSTANCE = 2,
- RC_CONSISTENCY_CORRUPT_NOTHING = 3,
- RC_CONSISTENCY_UNDEFINED = 4,
- RC_CER_NONE = 0,
- RC_CER_MAYFAIL = 1,
- RC_CER_SUCCESS = 2,
- RC_CER_UNDEFINED = 3
-};
-
-
-// We compact the reliability contract states above into a single DWORD format easy to cache at the assembly and class level
-// opaquely. We also encode in this DWORD whether a given part of the state has been defined yet (an assembly might set a
-// consistency level without specifying a cer level, for instance, and this information is vital when merging states between
-// assembly, class and method levels).
-// The macros below handle the encoding so nobody else needs to know the details.
-
-// The base state for an encoded DWORD: neither consistency or cer defined.
-#define RC_NULL RC_ENCODE(RC_CONSISTENCY_UNDEFINED, RC_CER_UNDEFINED)
-
-// Extract the raw consistency value from an encoded DWORD.
-#define RC_CONSISTENCY(_encoded) ((_encoded) >> 2)
-
-// Extract the raw cer value from an encoded DWORD.
-#define RC_CER(_encoded) ((_encoded) & 3)
-
-// Produce an encoded DWORD from a pair of raw consistency and cer values. Values must have been range validated first.
-#define RC_ENCODE(_consistency, _cer) (DWORD)(((_consistency) << 2) | (_cer))
-
-// Produce an abstracted ReliabilityContractLevel from an encoded DWORD, see CheckForReliabilityContract for details of the rules.
-#define RC_ENCODED_TO_LEVEL(_encoded) \
- ((RC_CONSISTENCY(_encoded) == RC_CONSISTENCY_UNDEFINED || \
- RC_CONSISTENCY(_encoded) < RC_CONSISTENCY_CORRUPT_INSTANCE) ? RCL_NO_CONTRACT : \
- (RC_CER(_encoded) == RC_CER_UNDEFINED || \
- RC_CER(_encoded) == RC_CER_NONE) ? RCL_BASIC_CONTRACT : \
- RCL_PREPARE_CONTRACT)
-
-// Given two DWORD encodings presumed to come from different scopes (e.g. method and class) merge them to find the effective
-// contract state. It's presumed the first encoding is the most tightly scoped (i.e. method would go first in the example above) and
-// therefore takes precedence.
-#define RC_MERGE(_old, _new) RC_ENCODE((RC_CONSISTENCY(_old) == RC_CONSISTENCY_UNDEFINED) ? \
- RC_CONSISTENCY(_new) : RC_CONSISTENCY(_old), \
- (RC_CER(_old) == RC_CER_UNDEFINED) ? \
- RC_CER(_new) : RC_CER(_old)) \
-
-// Return true if either consistency or cer has not been specified in the encoded DWORD given.
-#define RC_INCOMPLETE(_encoded) (RC_CONSISTENCY(_encoded) == RC_CONSISTENCY_UNDEFINED || RC_CER(_encoded) == RC_CER_UNDEFINED)
-
-// Look for reliability contracts at the method, class and assembly level and parse them to extract the information we're interested
-// in from a runtime preparation viewpoint. This information is abstracted in the form of the ReliabilityContractLevel enumeration.
-ReliabilityContractLevel CheckForReliabilityContract(MethodDesc *pMD);
-
-
-// Structure used to track enough information to identify a method (possibly generic or belonging to a generic class). Includes a
-// MethodDesc pointer and a SigTypeContext (values of class and method type parameters to narrow down the exact method being refered
-// to). Similar to MethodContext (see ConstrainedExecutionRegion.cpp), but without the unneeded list link field (we expect to embed
-// these in arrays, hence the name).
-struct MethodContextElement
-{
- FixupPointer<PTR_MethodDesc> m_pMethodDesc; // Pointer to a MethodDesc
- FixupPointer<PTR_MethodTable> m_pExactMT; // Exact type to disambiguate code shared by instantiations
-
- MethodDesc * GetMethodDesc()
- {
- return m_pMethodDesc.GetValue();
- }
-
- MethodTable * GetExactMT()
- {
- return m_pExactMT.GetValue();
- }
-};
-
-
-// Base structure used to track which CERs have been prepared so far.
-// These structures are looked up via a per-assembly hash table using the root method desc as a key.
-// Used to avoid extra work in both the jit and PrepareMethod calls. The latter case is more involved because we support preparing a
-// CER with generic type parameters (the instantiation is passed in along with the method in the PrepareMethod call). In that case
-// we need to track exactly which instantiations we've prepared for a given method.
-struct CerPrepInfo
-{
- CerPrepInfo() :
- m_fFullyPrepared(false),
- m_fRequiresInstantiation(false),
- m_fMethodHasCallsWithinExplicitCer(false)
- {
- CONTRACTL {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- if (!m_sIsInitAtInstHash.Init(17, NULL, NULL, FALSE))
- COMPlusThrowOM();
- }
-
- bool m_fFullyPrepared; // True implies we've prep'd this once and there are no shared instantiations
- bool m_fRequiresInstantiation; // True implies that this method is shared amongst multiple instantiations
- bool m_fMethodHasCallsWithinExplicitCer; // True if method contains calls out from within an explicit PCER range
- EEInstantiationHashTable m_sIsInitAtInstHash; // Hash of instantiations we've prepared this CER for
-};
-
-
-#ifdef FEATURE_PREJIT
-
-// Structure used to represent a CER by a root method and a list of MethodContextElements that indicate all the methods contained.
-// The MethodContextElement list is terminated with a sentinel entry (m_pMethodDesc set to NULL).
-// Keep this structure small since we'll access the whole array of them randomly at runtime; density is our best friend.
-struct CerRoot
-{
- MethodDesc *m_pRootMD; // Root method (no type context since it never has type params)
- MethodContextElement *m_pList; // List of methods in this CER
-};
-
-// Class used to track all the CERs rooted at methods defined within a given module that are discovered at ngen time. This data is
-// then used at runtime to determine when and how to perform necessary restoration work so that the CERs don't encounter any
-// unexpected failure points during execution.
-// During ngen this class keeps a dynamically expanded array of CER roots (both the class and the array are allocated from a win32
-// heap). When we save the image to storage (and thus know the final size of the table) we combine the two so that at runtime
-// they're adjacent and exactly the right size.
-class CerNgenRootTable
-{
-#ifdef DACCESS_COMPILE
- friend class NativeImageDumper;
-#endif
-
- DWORD *m_pRestoreBitmap; // Pointer to array of restored flag bits
- DWORD m_cRoots; // Count of root methods represented
- DWORD m_cSlots; // Extra empty slots at the tail of the array below (ngen time only)
- CerRoot *m_pRoots; // Pointer to array of CER roots (sorted by RootMD address)
- MethodContextElement **m_pRootsInCompilationOrder; // Pointer to array of CerRoot::m_pList (in the order AddRoot is called)
-
-public:
-
- CerNgenRootTable() :
- m_pRestoreBitmap(NULL),
- m_cRoots(0),
- m_cSlots(0),
- m_pRoots(NULL),
- m_pRootsInCompilationOrder(NULL)
- {
- }
-
- ~CerNgenRootTable()
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- MODE_ANY;
- }
- CONTRACTL_END;
- delete m_pRestoreBitmap;
- delete m_pRoots;
- delete m_pRootsInCompilationOrder;
- }
-
- // Add a new root to the table, expanding it as necessary. Note that this method must be called with the CerCrst already held.
- void AddRoot(MethodDesc *pRootMD, MethodContextElement *pList);
-
- // Retrieve the address of the list of methods for the CER rooted at the given index.
- inline MethodContextElement *GetList(DWORD dwIndex) { LIMITED_METHOD_CONTRACT; _ASSERTE(dwIndex < m_cRoots); return m_pRoots[dwIndex].m_pList; }
-
- // Retrieve the address of the list of methods for the CER rooted at the given method. (The root must exist).
- inline MethodContextElement *GetList(MethodDesc *pRootMD) { WRAPPER_NO_CONTRACT; return GetList(FindIndex(pRootMD)); }
-
- // Indicate whether the given method has ngen restoration information associated with it.
- inline bool IsNgenRootMethod(MethodDesc *pRootMD) { WRAPPER_NO_CONTRACT; return FindIndex(pRootMD) != NoSuchRoot; }
-
- // Prepare the CER rooted at the given method (it's OK to pass a MethodDesc* that doesn't root a CER, in which case the method
- // is a no-op).
- void Restore(MethodDesc *pRootMD);
-
- // Ngen callouts to help serialize this structure and its children to storage.
- void Save(DataImage *image, CorProfileData *profileData);
- void Fixup(DataImage *image);
- void FixupRVAs(DataImage *image);
-
- // Calculate (in bytes) the size of bitmap to allocate to record whether each CER has been restored at runtime. Size is
- // rounded up to DWORD alignment.
- inline DWORD SizeOfRestoreBitmap()
- {
- LIMITED_METHOD_CONTRACT;
- return ((m_cRoots + 31) / 32) * sizeof(DWORD);
- }
-
- inline DWORD GetRootCount() { LIMITED_METHOD_CONTRACT; return m_cRoots; }
- inline CerRoot *GetRoots() { LIMITED_METHOD_CONTRACT; return m_pRoots; }
- inline DWORD *GetRestoreBitmap() { LIMITED_METHOD_CONTRACT; return m_pRestoreBitmap; }
-
-private:
- enum { NoSuchRoot = 0xffffffff };
-
- // Locate the index of a given CerRoot record in the array given the root method. This is used to access the array and to locate
- // the restored flag for the entry in the restored bitmap. NoSuchRoot is returned if the root cannot be found.
- DWORD FindIndex(MethodDesc *pRootMD);
-};
-
-#endif
-
-
-// Default initial size for hash table used to track CerPrepInfo structures on a per-module basis.
-#define CER_DEFAULT_HASH_SIZE 17
-
-
-// Structure used to track a single exception handling range (catch, finally etc.). We build an array of these and then track which
-// ones have become 'activated' by virtue of having their try clause immediately preceded by a call to our preparation marker
-// method. This allows us to determine which call sites in the method body should be followed during method preparation.
-struct EHClauseRange
-{
- DWORD m_dwTryOffset;
- DWORD m_dwHandlerOffset;
- DWORD m_dwHandlerLength;
- bool m_fActive;
-};
-
-
-// Structure used to track enough information to identify a method (possibly generic or belonging to a generic class). Includes a
-// MethodDesc pointer and a SigTypeContext (values of class and method type parameters to narrow down the exact method being refered
-// to). The structure also contains a next pointer so that it can be placed in a singly linked list (see MethodContextStack below).
-struct MethodContext
-{
- MethodContext *m_pNext; // Next MethodContext in a MethodContextStack list
- MethodDesc *m_pMethodDesc; // Pointer to a MethodDesc
- SigTypeContext m_sTypeContext; // Additional type parameter information to qualify the exact method targetted
- bool m_fRoot; // Does this method contain a CER root of its own?
-
- // Allocate and initialize a MethodContext from the per-thread stacking allocator (we assume the checkpoint has already been
- // taken).
- static MethodContext* PerThreadAllocate(MethodDesc *pMD, SigTypeContext *pTypeContext)
- {
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- } CONTRACTL_END;
-
-
- MethodContext *pContext = new (&GetThread()->m_MarshalAlloc) MethodContext();
- pContext->m_pMethodDesc = pMD;
- pContext->m_sTypeContext = *pTypeContext;
- pContext->m_fRoot = false;
-
- return pContext;
- }
-
- // Determine if two MethodContexts are equivalent (same MethodDesc pointer and identical arrays of TypeHandles in the
- // TypeContext).
- bool Equals(MethodContext *pOther)
- {
- WRAPPER_NO_CONTRACT;
-
- if (pOther->m_pMethodDesc != m_pMethodDesc)
- return false;
-
- if (pOther->m_sTypeContext.m_classInst.GetNumArgs() != m_sTypeContext.m_classInst.GetNumArgs())
- return false;
-
- if (pOther->m_sTypeContext.m_methodInst.GetNumArgs() != m_sTypeContext.m_methodInst.GetNumArgs())
- return false;
-
- DWORD i;
-
- for (i = 0; i < m_sTypeContext.m_classInst.GetNumArgs(); i++)
- if (pOther->m_sTypeContext.m_classInst[i] != m_sTypeContext.m_classInst[i])
- return false;
-
- for (i = 0; i < m_sTypeContext.m_methodInst.GetNumArgs(); i++)
- if (pOther->m_sTypeContext.m_methodInst[i] != m_sTypeContext.m_methodInst[i])
- return false;
-
- return true;
- }
-
-#ifdef _DEBUG
-#define CER_DBG_MAX_OUT 4096
- char *ToString()
- {
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_MODE_ANY;
-
- // Support up to two ToString calls before we re-use a buffer and overwrite previous output.
- static char szOut1[CER_DBG_MAX_OUT];
- static char szOut2[CER_DBG_MAX_OUT];
- static char *pszOut = szOut1;
-
- StackSString ssBuffer;
- StackScratchBuffer ssScratch;
-
- TypeString::AppendMethod(ssBuffer, m_pMethodDesc, m_sTypeContext.m_classInst, TypeString::FormatNamespace | TypeString::FormatAngleBrackets);
- sprintf_s(&pszOut[0], CER_DBG_MAX_OUT, "%s", ssBuffer.GetUTF8(ssScratch));
-
- char *pszReturn = pszOut;
- pszOut = pszOut == szOut1 ? szOut2 : szOut1;
- return pszReturn;
- }
-#endif
-};
-
-// Maintains a stack of MethodContexts (implemented as a singly linked list with insert and remove operations only at the head).
-class MethodContextStack
-{
- MethodContext *m_pFirst; // The head of the linked list
- DWORD m_cElements; // Count of elements in the stack
-
-public:
-
- // Initialize to an empty list.
- MethodContextStack()
- {
- LIMITED_METHOD_CONTRACT;
-
- m_pFirst = NULL;
- m_cElements = 0;
- }
-
- // Push a MethodContext pointer on the head of the list.
- void Push(MethodContext *pContext)
- {
- LIMITED_METHOD_CONTRACT;
-
- pContext->m_pNext = m_pFirst;
- m_pFirst = pContext;
- m_cElements++;
- }
-
- // Remove and retrieve the most recently pushed MethodContext. Return NULL if no more entries exist.
- MethodContext *Pop()
- {
- LIMITED_METHOD_CONTRACT;
-
- MethodContext* pContext = m_pFirst;
- if (pContext == NULL)
- return NULL;
-
- m_pFirst = pContext->m_pNext;
- m_cElements--;
-
- return pContext;
- }
-
- // Return true if an MethodContext equivalent to the argument exists in the stack.
- bool IsInStack(MethodContext *pMatchContext)
- {
- WRAPPER_NO_CONTRACT;
-
- MethodContext* pContext = m_pFirst;
- while (pContext) {
- if (pContext->Equals(pMatchContext))
- return true;
- pContext = pContext->m_pNext;
- }
-
- return false;
- }
-
- // Get count of elements in the stack.
- DWORD GetCount()
- {
- LIMITED_METHOD_CONTRACT;
-
- return m_cElements;
- }
-};
-
-
-class MethodCallGraphPreparer
-{
- MethodDesc *m_pRootMD;
- SigTypeContext *m_pRootTypeContext;
-
- COR_ILMETHOD_DECODER *m_pMethodDecoder;
-
- MethodContextStack m_sLeftToProcess; // MethodContexts we have yet to look at in this call graph
- MethodContextStack m_sAlreadySeen; // MethodContexts we've already processed at least once
-
- EHClauseRange *m_pEHClauses; // Array of exception handling clauses in current method (only if !fEntireMethod)
- DWORD m_cEHClauses; // Number of elements in above array
- CerPrepInfo *m_pCerPrepInfo; // Context recording how much preparation this region has had
- MethodContextStack m_sPersist; // MethodContexts we need to keep around past the 'prepare' phase of preparation
-#ifdef FEATURE_NATIVE_IMAGE_GENERATION
- bool m_fNgen; // True when being called as part of an ngen
- MethodContextStack m_sRootMethods; // Methods containing a sub-CER (excludes the real root)
-#endif // FEATURE_NATIVE_IMAGE_GENERATION
- Thread *m_pThread; // Cached managed thread pointer (for allocations and the like)
- bool m_fPartialPreparation; // True if we have unbound type vars at the CER root and can only prep one instantiation at a time
-
- bool m_fEntireMethod; // True if are preparing for the entire method
- bool m_fExactTypeContext;
- bool m_fMethodHasCallsWithinExplicitCer; // True if method contains calls out from within an explicit PCER range
-
- bool m_fIgnoreVirtualCERCallMDA; // True if VirtualCER MDA is not desirable to be fired
-
- MethodCallGraphPreparer * m_pNext; // Links this instance on a per-thread stack used to detect
- // and defeat recursive preparations
-
- public:
- MethodCallGraphPreparer(MethodDesc *pRootMD, SigTypeContext *pRootTypeContext, bool fEntireMethod, bool fExactTypeContext, bool fIgnoreVirtualCERCallMDA = false);
-
- // Walk the call graph of the method given by m_pRootMD (and type context in m_pRootTypeContext which provides instantiation information
- // for generic methods/classes).
- //
- // If fEntireMethod is true then the entire body of pRootMD is scanned for callsites, otherwise we assume that one or more CER
- // exception handlers exist in the method and only the finally and catch blocks of such handlers are scanned for graph roots.
- //
- // Each method we come across in the call graph (excluding late bound invocation destinations precipitated by virtual or interface
- // calls) is jitted and has any generic dictionary information we can determine at jit time prepopulated. This includes implicit
- // cctor invocations. If this method is called at ngen time we will attach extra fixup information to the affected method to ensure
- // that fixing up the root method of the graph will cause all methods in the graph to be fixed up at that point also.
- //
- // Some generic dictionary entries may not be prepopulated if unbound type variables exist at the root of the call tree. Such cases
- // will be ignored (as for the virtual/interface dispatch case we assume the caller will use an out-of-band mechanism to pre-prepare
- // these entries explicitly).
- //
- // Returns true if the m_pRootMD contains a CER that calls outside the method.
- //
- bool Run();
-
- // Methods used to control re-entrancy on the same thread. Essentially we'd like to avoid all re-entrancy
- // (since it can lead to unbounded recursion easily) but unfortunately jitting methods during the
- // preparation phase can cause this both directly (if we spot a sub-root) or indirectly (where implicit
- // jit execution of a cctor causes a possibly unrelated CER graph to be prepared). The algorithm we use to
- // avoid this records a stack of preparations attempts on the current thread (implemented via a singly
- // linked list of the MethodCallGraphPreparer instances). Re-entrant prepare requests become noops if
- // they're for a root method we're already processing (anywhere in the stack) and run to completion
- // otherwise. This prevents infinite recursion since it removes at least one method from the intersection
- // of the CER call graphs on each iteration. Theoretically it might not be the most efficient solution
- // since there might still be a lot of overlap between graphs, but in practice the number of sub-CER roots
- // is likely to be small and we won't recurse very far. This will still allow a re-entrant preparation
- // that is the result of running a cctor to potentially early-out (and thus allow code to run before its
- // CERs have been fully prepped). But this should only happen when a CER causes (directly or indirectly) a
- // cctor to run that depends on that CER having been prepared already, which we really can't do much
- // about.
- //
- BOOL CanPreparationProceed(MethodDesc * pMD, SigTypeContext * pTypeContext);
-
- static void BeginPrepareCerForHolder(MethodCallGraphPreparer *pPrepState);
- static void EndPrepareCerForHolder(MethodCallGraphPreparer *pPrepState);
-
- typedef Holder<MethodCallGraphPreparer*, BeginPrepareCerForHolder, EndPrepareCerForHolder> ThreadPreparingCerHolder;
-
- private:
- void GetEHClauses();
- void MarkEHClauseActivatedByCERCall(MethodContext *pContext, BYTE *pbIL, DWORD cbIL);
- bool CheckIfCallsiteWithinCER(DWORD dwOffset);
- bool ShouldGatherExplicitCERCallInfo();
- void LookForInterestingCallsites(MethodContext *pContext);
- void PrepareMethods();
- bool RecordResults();
-};
-
-// Determines whether the given method contains a CER root that can be pre-prepared (i.e. prepared at jit time).
-bool ContainsPrePreparableCerRoot(MethodDesc *pMD);
-
-// Prepares the critical finalizer call graph for the given object type (which must derive from CriticalFinalizerObject). This
-// involves preparing at least the finalizer method and possibly some others (for SafeHandle and CriticalHandle derivations). If a
-// module pointer is supplied then only the critical methods introduced in that module are prepared (this is used at ngen time to
-// ensure that we're only generating ngen preparation info for the targetted module).
-void PrepareCriticalFinalizerObject(MethodTable *pMT, Module *pModule = NULL);
-
-void PrepareMethodDesc(MethodDesc* pMD, Instantiation classInst = Instantiation(), Instantiation methodInst = Instantiation(), BOOL onlyContractedMethod = FALSE, BOOL fIgnoreVirtualCERCallMDA = FALSE);
-// Determine whether the method given as a parameter is the root of a CER.
-// @todo: Need an x86 offset as well and logic to determine whether we're actually in a root-CER portion of the method (if the whole
-// thing isn't the root).
-bool IsCerRootMethod(MethodDesc *pMD);
-
-// Fill the cache of overflowed generic dictionary entries that the jit maintains with all the overflow slots stored so far in the
-// dictionary layout.
-void PrepopulateGenericHandleCache(DictionaryLayout *pDictionaryLayout,
- MethodDesc *pMD,
- MethodTable *pMT);
-
-DWORD GetReliabilityContract(IMDInternalImport *pImport, mdToken tkParent);
-
-#ifdef FEATURE_PREJIT
-
-// Prepare the class if it is derived from CriticalFinalizerObject. This is used at ngen time since such classes are normally
-// prepared at runtime (at instantiation) and would therefore miss the ngen image.
-void PrepareCriticalType(MethodTable *pMT);
-
-// Prepare a method and its statically determinable call graph if a hint attribute has been applied. This is only called at ngen
-// time to save additional preparation information into the ngen image that wouldn't normally be there (and thus lower runtime
-// overheads).
-void PrePrepareMethodIfNecessary(CORINFO_METHOD_HANDLE hMethod);
-
-#endif
-
-
-// A fixed sized hash table keyed by pointers and storing two bits worth of value for every entry. The value is stored in the low
-// order bits of the keys, so the pointers must be at least DWORD aligned. No hash table expansion occurs so new entries will sooner
-// or later overwrite old. The implementation uses no locks (all accesses are single aligned pointer sized operations and therefore
-// inherently atomic).
-// The purpose of this table is to store a smallish number of reliability contract levels for the most recently queried methods,
-// mainly for the purpose of speeding up thread abort processing (where we will walk the stack probing methods for contracts,
-// sometimes repeatedly). So we use a small fixed sized hash to speed up lookups on average but avoid impacting working set.
-#define PHC_BUCKETS 29
-#define PHC_CHAIN 5
-#define PHC_DATA_MASK 3
-
-class PtrHashCache
-{
-public:
- PtrHashCache();
- bool Lookup(void *pKey, DWORD *pdwValue);
- void Add(void *pKey, DWORD dwValue);
-
-#ifdef _DEBUG
- void DbgDumpStats();
-#endif
-
-private:
- DWORD GetHash(void *pKey);
-
- UINT_PTR m_rEntries[PHC_BUCKETS * PHC_CHAIN];
-
-#ifdef _DEBUG
- DWORD m_dwHits;
- DWORD m_dwMisses;
-#endif
-};
-
-#endif // FEATURE_CER
-
-#endif
diff --git a/src/vm/context.h b/src/vm/context.h
index 70d9456b43..3c746b647f 100644
--- a/src/vm/context.h
+++ b/src/vm/context.h
@@ -15,185 +15,8 @@ class RCWCache;
typedef DPTR(class Context) PTR_Context;
-#ifdef FEATURE_REMOTING
-class Context
-{
-public:
- enum CallbackType
- {
- Wait_callback = 0,
- MonitorWait_callback = 1,
- ADTransition_callback = 2,
- SignalAndWait_callback = 3
- };
-
- typedef struct
- {
- int numWaiters;
- HANDLE* waitHandles;
- BOOL waitAll;
- DWORD millis;
- BOOL alertable;
- DWORD* pResult;
- } WaitArgs;
-
- typedef struct
- {
- HANDLE* waitHandles;
- DWORD millis;
- BOOL alertable;
- DWORD* pResult;
- } SignalAndWaitArgs;
-
- typedef struct
- {
- INT32 millis;
- PendingSync* syncState;
- BOOL* pResult;
- } MonitorWaitArgs;
-
-
- typedef struct
- {
- enum CallbackType callbackId;
- void* callbackData;
- } CallBackInfo;
-
- typedef void (*ADCallBackFcnType)(LPVOID);
-
- struct ADCallBackArgs
- {
- ADCallBackFcnType pTarget;
- LPVOID pArguments;
- };
-
-#ifdef DACCESS_COMPILE
- void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
-#endif
-
-friend class Thread;
-friend class ThreadNative;
-friend class ContextBaseObject;
-friend class CRemotingServices;
-friend struct PendingSync;
-
- Context(AppDomain *pDomain);
- ~Context();
- static void Initialize();
- PTR_AppDomain GetDomain()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return m_pDomain;
- }
-
- // Get and Set the exposed System.Runtime.Remoting.Context
- // object which corresponds to this context.
- OBJECTREF GetExposedObject();
- OBJECTREF GetExposedObjectRaw();
- PTR_Object GetExposedObjectRawUnchecked();
- PTR_PTR_Object GetExposedObjectRawUncheckedPtr();
- void SetExposedObject(OBJECTREF exposed);
-
- // Query whether the exposed object exists
- BOOL IsExposedObjectSet();
-
- static LPVOID GetStaticFieldAddress(FieldDesc *pFD);
-
- PTR_VOID GetStaticFieldAddrNoCreate(FieldDesc *pFD);
-
- static Context* CreateNewContext(AppDomain *pDomain);
-
- static void FreeContext(Context* victim)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(victim));
- }
- CONTRACTL_END;
-
- delete victim;
- }
-
- static Context* GetExecutionContext(OBJECTREF pObj);
- static void RequestCallBack(ADID appDomain, Context* targetCtxID, void* privateData);
-
- // <TODO>Made public to get around the context GC issue </TODO>
- static BOOL ValidateContext(Context *pCtx);
-
- inline STATIC_DATA *GetSharedStaticData()
- {
- LIMITED_METHOD_CONTRACT;
- return m_pSharedStaticData;
- }
-
- inline void SetSharedStaticData(STATIC_DATA *pData)
- {
- LIMITED_METHOD_CONTRACT;
- m_pSharedStaticData = PTR_STATIC_DATA(pData);
- }
-
- inline STATIC_DATA *GetUnsharedStaticData()
- {
- LIMITED_METHOD_CONTRACT;
- return m_pUnsharedStaticData;
- }
-
- inline void SetUnsharedStaticData(STATIC_DATA *pData)
- {
- LIMITED_METHOD_CONTRACT;
- m_pUnsharedStaticData = PTR_STATIC_DATA(pData);
- }
-
- // Functions called from BCL on a managed context object
- static FCDECL2(void, SetupInternalContext, ContextBaseObject* pThisUNSAFE, CLR_BOOL bDefault);
- static FCDECL1(void, CleanupInternalContext, ContextBaseObject* pThisUNSAFE);
- static FCDECL1(void, ExecuteCallBack, LPVOID privateData);
-
-private:
- // Static helper functions:
-
- static void ExecuteWaitCallback(WaitArgs* waitArgs);
- static void ExecuteMonitorWaitCallback(MonitorWaitArgs* waitArgs);
- static void ExecuteSignalAndWaitCallback(SignalAndWaitArgs* signalAndWaitArgs);
- void GetStaticFieldAddressSpecial(FieldDesc *pFD, MethodTable *pMT, int *pSlot, LPVOID *ppvAddress);
- PTR_VOID CalculateAddressForManagedStatic(int slot);
-
- // Static Data Members:
-
- static CrstStatic s_ContextCrst;
-
-
- // Non-static Data Members:
- // Pointer to native context static data
- PTR_STATIC_DATA m_pUnsharedStaticData;
-
- // Pointer to native context static data
- PTR_STATIC_DATA m_pSharedStaticData;
-
- typedef SimpleList<OBJECTHANDLE> ObjectHandleList;
-
- ObjectHandleList m_PinnedContextStatics;
-
- // <TODO> CTS. Domains should really be policies on a context and not
- // entry in the context object. When AppDomains become an attribute of
- // a context then add the policy.</TODO>
- PTR_AppDomain m_pDomain;
-
- OBJECTHANDLE m_ExposedObjectHandle;
-
- DWORD m_Signature;
- // NOTE: please maintain the signature as the last member field!!!
-};
-
-FCDECL0(LPVOID, GetPrivateContextsPerfCountersEx);
-
-#else // FEATURE_REMOTING
-
-// if FEATURE_REMOTING is not defined there will be only the default context for each appdomain
+// there will be only the default context for each appdomain
// and contexts will not be exposed to users (so there will be no managed Context class)
class Context
@@ -225,6 +48,5 @@ public:
#endif
};
-#endif // FEATURE_REMOTING
#endif
diff --git a/src/vm/contexts.cpp b/src/vm/contexts.cpp
index eb957570ea..47cc81813f 100644
--- a/src/vm/contexts.cpp
+++ b/src/vm/contexts.cpp
@@ -11,917 +11,6 @@
#include "common.h"
-#ifdef FEATURE_REMOTING
-
-#include "context.h"
-#include "excep.h"
-#include "field.h"
-#include "remoting.h"
-#include "perfcounters.h"
-#include "specialstatics.h"
-#include "appdomain.inl"
-
-#ifdef FEATURE_COMINTEROP
-#include "runtimecallablewrapper.h"
-#endif // FEATURE_COMINTEROP
-
-#ifndef DACCESS_COMPILE
-
-#define CONTEXT_SIGNATURE (0x2b585443) // CTX+
-#define CONTEXT_DESTROYED (0x2d585443) // CTX-
-
-// Lock for safe operations
-CrstStatic Context::s_ContextCrst;
-
-
-Context::Context(AppDomain *pDomain)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pDomain));
- }
- CONTRACTL_END;
-
- m_pDomain = pDomain;
- m_Signature = CONTEXT_SIGNATURE;
-
- // This needs to be a LongWeakHandle since we want to be able
- // to run finalizers on Proxies while the Context itself
- // unreachable. When running the finalizer we will have to
- // transition into the context like a regular remote call.
- // If this is a short weak handle, it ceases being updated
- // as soon as the context is unreachable. By making it a strong
- // handle, it is updated till the context::finalize is run.
-
- m_ExposedObjectHandle = pDomain->CreateLongWeakHandle(NULL);
-
- // Set the pointers to the static data storage
- m_pUnsharedStaticData = NULL;
- m_pSharedStaticData = NULL;
-
- COUNTER_ONLY(GetPerfCounters().m_Context.cContexts++);
-}
-
-Context::~Context()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- BOOL fADUnloaded = m_pDomain->NoAccessToHandleTable();
- if (!fADUnloaded)
- {
- DestroyLongWeakHandle(m_ExposedObjectHandle);
- }
-
- m_pDomain = NULL;
- m_Signature = CONTEXT_DESTROYED;
-
- // Cleanup the static data storage
- if(m_pUnsharedStaticData)
- {
- for(WORD i = 0; i < m_pUnsharedStaticData->cElem; i++)
- {
- delete [] (BYTE *) (m_pUnsharedStaticData->dataPtr[i]);
- }
- delete [] m_pUnsharedStaticData;
- m_pUnsharedStaticData = NULL;
- }
-
- if(m_pSharedStaticData)
- {
- for(WORD i = 0; i < m_pSharedStaticData->cElem; i++)
- {
- delete [] (BYTE *) (m_pSharedStaticData->dataPtr[i]);
- }
- delete [] m_pSharedStaticData;
- m_pSharedStaticData = NULL;
- }
-
- // Destroy pinning handles associated with this context
- ObjectHandleList::NodeType* pHandleNode;
- while ((pHandleNode = m_PinnedContextStatics.UnlinkHead() ) != NULL)
- {
- if (!fADUnloaded)
- {
- DestroyPinningHandle(pHandleNode->data);
- }
- delete pHandleNode;
- }
-
- COUNTER_ONLY(GetPerfCounters().m_Context.cContexts--);
-}
-
-Context* Context::CreateNewContext(AppDomain *pDomain)
-{
- CONTRACT (Context*)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pDomain));
- }
- CONTRACT_END;
-
- Context *p = new Context(pDomain);
- RETURN p;
-}
-
-void Context::Initialize()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // Initialize the context critical section
- s_ContextCrst.Init(CrstContexts, (CrstFlags)(CRST_REENTRANCY|CRST_HOST_BREAKABLE));
-}
-
-BOOL Context::ValidateContext(Context *pCtx)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- PRECONDITION(CheckPointer(pCtx));
- }
- CONTRACTL_END;
-
- BOOL bRet = FALSE;
-
- EX_TRY
- {
- if (pCtx->m_Signature == CONTEXT_SIGNATURE)
- bRet = TRUE;
- }
- EX_CATCH
- {
- // Swallow exceptions - if not a valid ctx, just return false.
- }
- EX_END_CATCH(RethrowTerminalExceptions);
-
- return bRet;
-}
-
-// if the object we are creating is a proxy to another appdomain, want to create the wrapper for the
-// new object in the appdomain of the proxy target
-Context* Context::GetExecutionContext(OBJECTREF pObj)
-{
- CONTRACT (Context*)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(pObj != NULL);
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END;
-
- Context *pContext = NULL;
- if (pObj->IsTransparentProxy())
- pContext = CRemotingServices::GetServerContextForProxy(pObj);
- if (pContext == NULL)
- pContext = GetAppDomain()->GetDefaultContext();
-
- RETURN pContext;
-}
-
-OBJECTREF Context::GetExposedObject()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- if (ObjectFromHandle(m_ExposedObjectHandle) == NULL)
- {
- // This call should fault in the managed context for the thread
- MethodDescCallSite getCurrentContext(METHOD__THREAD__GET_CURRENT_CONTEXT);
- CONTEXTBASEREF ctx = (CONTEXTBASEREF) getCurrentContext.Call_RetOBJECTREF((ARG_SLOT*)NULL);
-
- GCPROTECT_BEGIN(ctx);
- {
- // Take a lock to make sure that only one thread creates the object.
- // This locking may be too severe!
- CrstHolder ch(&s_ContextCrst);
-
- // Check to see if another thread has not already created the exposed object.
- if (ObjectFromHandle(m_ExposedObjectHandle) == NULL)
- {
- // Keep a weak reference to the exposed object.
- StoreObjectInHandle(m_ExposedObjectHandle, (OBJECTREF) ctx);
-
- ctx->SetInternalContext(this);
- }
- }
- GCPROTECT_END();
-
- }
- return ObjectFromHandle(m_ExposedObjectHandle);
-}
-
-void Context::SetExposedObject(OBJECTREF exposed)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(exposed != NULL);
- PRECONDITION(ObjectFromHandle(m_ExposedObjectHandle) == NULL);
- }
- CONTRACTL_END;
-
- StoreObjectInHandle(m_ExposedObjectHandle, exposed);
-}
-
-// This is called by EE to transition into a context(possibly in
-// another appdomain) and execute the method Context::ExecuteCallBack
-// with the private data provided to this method
-void Context::RequestCallBack(ADID appDomainID, Context* targetCtxID, void* privateData)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(targetCtxID));
- PRECONDITION(CheckPointer(privateData));
- PRECONDITION(ValidateContext((Context*)targetCtxID));
- }
- CONTRACTL_END;
- // a warning: don't touch targetCtxID until you verified appDomainID,
- // unless the latter is CURRENT_APPDOMAIN_ID
-
- // Get the current context of the thread. This is assumed as
- // the context where the request originated
- Context *pCurrCtx;
- pCurrCtx = GetCurrentContext();
-
- // Check that the target context is not the same (presumably the caller has checked for it).
- _ASSERTE(pCurrCtx != targetCtxID);
-
- // Check if we might be going to a context in another appDomain.
- ADID targetDomainID;
-
- if (appDomainID == CURRENT_APPDOMAIN_ID)
- {
- targetDomainID = (ADID)0;
- _ASSERTE(targetCtxID->GetDomain()==::GetAppDomain());
- }
- else
- {
- targetDomainID=appDomainID;
-#ifdef _DEBUG
- AppDomainFromIDHolder ad(appDomainID, FALSE);
- if (!ad.IsUnloaded())
- _ASSERTE(targetCtxID->GetDomain()->GetId()==appDomainID);
-#endif
- }
-
- // we need to be co-operative mode for jitting
- GCX_COOP();
-
- MethodDescCallSite callback(METHOD__CONTEXT__CALLBACK);
-
- ARG_SLOT args[3];
- args[0] = PtrToArgSlot(targetCtxID);
- args[1] = PtrToArgSlot(privateData);
- args[2] = (ARG_SLOT) (size_t)targetDomainID.m_dwId;
-
- callback.Call(args);
-}
-
-/*** Definitions of callback executions for the various callbacks that are known to EE ***/
-
-// Callback for waits on waithandle
-void Context::ExecuteWaitCallback(WaitArgs* waitArgs)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(waitArgs));
- }
- CONTRACTL_END;
-
- Thread* pCurThread = GetThread();
- _ASSERTE(pCurThread != NULL);
-
- // DoAppropriateWait switches to preemptive GC before entering the wait
- *(waitArgs->pResult) = pCurThread->DoAppropriateWait( waitArgs->numWaiters,
- waitArgs->waitHandles,
- waitArgs->waitAll,
- waitArgs->millis,
- waitArgs->alertable?WaitMode_Alertable:WaitMode_None);
-}
-
-// Callback for monitor wait on objects
-void Context::ExecuteMonitorWaitCallback(MonitorWaitArgs* waitArgs)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(waitArgs));
- }
- CONTRACTL_END;
-
- Thread* pCurThread = GetThread();
- _ASSERTE(pCurThread != NULL);
-
- GCX_PREEMP();
-
- *(waitArgs->pResult) = pCurThread->Block(waitArgs->millis,
- waitArgs->syncState);
-}
-
-// Callback for signalandwait on waithandles
-void Context::ExecuteSignalAndWaitCallback(SignalAndWaitArgs* signalAndWaitArgs)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(signalAndWaitArgs));
- }
- CONTRACTL_END;
-
- Thread* pCurThread = GetThread();
- _ASSERTE(pCurThread != NULL);
-
- // DoAppropriateWait switches to preemptive GC before entering the wait
- *(signalAndWaitArgs->pResult) = pCurThread->DoSignalAndWait( signalAndWaitArgs->waitHandles,
- signalAndWaitArgs->millis,
- signalAndWaitArgs->alertable);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: Context::GetStaticFieldAddress private
-//
-// Synopsis: Get the address of the field relative to the current context.
-// If an address has not been assigned yet then create one.
-//
-
-//
-//+----------------------------------------------------------------------------
-LPVOID Context::GetStaticFieldAddress(FieldDesc *pFD)
-{
- CONTRACT (LPVOID)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pFD));
- PRECONDITION(!s_ContextCrst.OwnedByCurrentThread());
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- LPVOID pvAddress = NULL;
- Context* pCtx = NULL;
- // for static field the MethodTable is exact even for generic classes
- MethodTable* pMT = pFD->GetEnclosingMethodTable();
- BOOL fIsShared = pMT->IsDomainNeutral();
- DWORD dwClassOffset = pMT->GetContextStaticsOffset();
- DWORD currElem = 0;
- STATIC_DATA* pData;
-
- // NOTE: if you change this method, you must also change
- // GetStaticFieldAddrNoCreate below.
-
- if (dwClassOffset == (DWORD)-1)
- {
- dwClassOffset = pMT->AllocateContextStaticsOffset();
- }
-
- // Retrieve the current context
- pCtx = GetCurrentContext();
- _ASSERTE(NULL != pCtx);
-
- // Acquire the context lock before accessing the static data pointer
- {
- CrstHolder ch(&s_ContextCrst);
-
- if(!fIsShared)
- pData = pCtx->m_pUnsharedStaticData;
- else
- pData = pCtx->m_pSharedStaticData;
-
- if(NULL != pData)
- currElem = pData->cElem;
-
- // Check whether we have allocated space for storing a pointer to
- // this class' context static store
- if(dwClassOffset >= currElem)
- {
- // Allocate space for storing pointers
- DWORD dwNewElem = (currElem == 0 ? 4 : currElem*2);
-
- // Ensure that we grow to a size larger than the index we intend to use
- while (dwNewElem <= dwClassOffset)
- dwNewElem = 2*dwNewElem;
-
- STATIC_DATA *pNew = (STATIC_DATA *)new BYTE[sizeof(STATIC_DATA) + dwNewElem*sizeof(LPVOID)];
-
- // Set the new count.
- pNew->cElem = dwNewElem;
-
- if(NULL != pData)
- {
- // Copy the old data into the new data
- memcpy(&pNew->dataPtr[0], &pData->dataPtr[0], currElem*sizeof(LPVOID));
-
- // Delete the old data
- delete [] (BYTE*) pData;
- }
-
- // Zero init any new elements.
- ZeroMemory(&pNew->dataPtr[currElem], (dwNewElem - currElem)* sizeof(LPVOID));
-
- // Update the locals
- pData = pNew;
-
- // Reset the pointers in the context object to point to the
- // new memory
- if(!fIsShared)
- pCtx->m_pUnsharedStaticData = pData;
- else
- pCtx->m_pSharedStaticData = pData;
- }
-
- _ASSERTE(NULL != pData);
-
- // Check whether we have to allocate space for
- // the context local statics of this class
- if(NULL == pData->dataPtr[dwClassOffset])
- {
- DWORD dwSize = pMT->GetContextStaticsSize();
-
- // Allocate memory for context static fields
- LPBYTE pFields = new BYTE[dwSize];
-
- // Initialize the memory allocated for the fields
- ZeroMemory(pFields, dwSize);
-
- pData->dataPtr[dwClassOffset] = pFields;
- }
-
- _ASSERTE(NULL != pData->dataPtr[dwClassOffset]);
-
- pvAddress = (LPVOID)((LPBYTE)pData->dataPtr[dwClassOffset] + pFD->GetOffset());
-
- // For object and value class fields we have to allocate storage in the
- // __StaticContainer class in the managed heap
- if(pFD->IsObjRef() || pFD->IsByValue())
- {
- // in this case *pvAddress == bucket|index
- int *pSlot = (int*)pvAddress;
- pvAddress = NULL;
- pCtx->GetStaticFieldAddressSpecial(pFD, pMT, pSlot, &pvAddress);
-
- if (pFD->IsByValue())
- {
- _ASSERTE(pvAddress != NULL);
- pvAddress = (*((OBJECTREF*)pvAddress))->GetData();
- }
- // ************************************************
- // ************** WARNING *************************
- // Do not provoke GC from here to the point JIT gets
- // pvAddress back
- // ************************************************
- _ASSERTE(*pSlot > 0);
- }
- }
-
- RETURN pvAddress;
-}
-
-
-//+----------------------------------------------------------------------------
-//
-// Method: Context::GetStaticFieldAddressSpecial private
-//
-// Synopsis: Allocate an entry in the __StaticContainer class in the
-// managed heap for static objects and value classes
-//
-
-//
-//+----------------------------------------------------------------------------
-
-// NOTE: At one point we used to allocate these in the long lived handle table
-// which is per-appdomain. However, that causes them to get rooted and not
-// cleaned up until the appdomain gets unloaded. This is not very desirable
-// since a context static object may hold a reference to the context itself or
-// to a proxy in the context causing a whole lot of garbage to float around.
-// Now (2/13/01) these are allocated from a managed structure rooted in each
-// managed context.
-
-void Context::GetStaticFieldAddressSpecial(FieldDesc *pFD, MethodTable *pMT, int *pSlot, LPVOID *ppvAddress)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pFD));
- PRECONDITION(CheckPointer(pMT));
- PRECONDITION(CheckPointer(pSlot));
- PRECONDITION(CheckPointer(ppvAddress));
- }
- CONTRACTL_END;
-
- OBJECTREF *pObjRef = NULL;
- BOOL bNewSlot = (*pSlot == 0);
-
- if (bNewSlot)
- {
- // ! this line will trigger a GC, don't move it down
- // ! without protecting the args[] and other OBJECTREFS
- OBJECTREF orThis = GetExposedObject();;
- GCPROTECT_BEGIN(orThis);
-
- MethodDescCallSite reserveSlot(METHOD__CONTEXT__RESERVE_SLOT, &orThis);
-
- // We need to assign a location for this static field.
- // Call the managed helper
- ARG_SLOT args[1] =
- {
- ObjToArgSlot(orThis)
- };
-
- // The managed ReserveSlot methods counts on this!
- _ASSERTE(s_ContextCrst.OwnedByCurrentThread());
- _ASSERTE(args[0] != 0);
-
- *pSlot = reserveSlot.Call_RetI4(args);
-
- _ASSERTE(*pSlot>0);
-
- GCPROTECT_END();
-
-
- // to a boxed version of the value class.This allows the standard GC
- // algorithm to take care of internal pointers in the value class.
- if (pFD->IsByValue())
- {
- // Extract the type of the field
- TypeHandle th = pFD->GetFieldTypeHandleThrowing();
-
- OBJECTHANDLE oh;
- OBJECTREF obj = MethodTable::AllocateStaticBox(th.GetMethodTable(), pMT->HasFixedAddressVTStatics(), &oh);
- pObjRef = (OBJECTREF*)CalculateAddressForManagedStatic(*pSlot);
-
- if (oh != NULL)
- {
- ObjectHandleList::NodeType* pNewNode = new ObjectHandleList::NodeType(oh);
- m_PinnedContextStatics.LinkHead(pNewNode);
- }
-
- SetObjectReference( pObjRef, obj, GetAppDomain() );
- }
- else
- {
- pObjRef = (OBJECTREF*)CalculateAddressForManagedStatic(*pSlot);
- }
- }
- else
- {
- // If the field already has a location assigned we go through here
- pObjRef = (OBJECTREF*)CalculateAddressForManagedStatic(*pSlot);
- }
-
- *(ULONG_PTR *)ppvAddress = (ULONG_PTR)pObjRef;
-}
-
-// This is called by the managed context constructor
-FCIMPL2(void, Context::SetupInternalContext, ContextBaseObject* pThisUNSAFE, CLR_BOOL bDefault)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(pThisUNSAFE != NULL);
- PRECONDITION(pThisUNSAFE->m_internalContext == NULL);
- }
- CONTRACTL_END;
-
- CONTEXTBASEREF pThis = (CONTEXTBASEREF) pThisUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_1(pThis);
-
- Context *pCtx;
-
- if (bDefault)
- {
- // We have to hook this up with the internal default
- // context for the current appDomain
- pCtx = GetThread()->GetDomain()->GetDefaultContext();
- }
- else
- {
- // Create the unmanaged backing context object
- pCtx = Context::CreateNewContext(GetThread()->GetDomain());
- }
-
- // Set the managed & unmanaged objects to point at each other.
- pThis->SetInternalContext(pCtx);
- pCtx->SetExposedObject((OBJECTREF)pThis);
-
- // Set the AppDomain field in the Managed context object
- pThis->SetExposedDomain(GetThread()->GetDomain()->GetExposedObject());
-
- if(bDefault)
- ((APPDOMAINREF)GetThread()->GetDomain()->GetExposedObject())->SetDefaultContext(pThis);
-
- COUNTER_ONLY(GetPerfCounters().m_Context.cContexts++);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-// This is called by the managed context finalizer
-FCIMPL1(void, Context::CleanupInternalContext, ContextBaseObject* pThisUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(pThisUNSAFE != NULL);
- }
- CONTRACTL_END;
-
- CONTEXTBASEREF pThis = (CONTEXTBASEREF) pThisUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_1(pThis);
-
- CONTEXTBASEREF refCtx = pThis;
-
- Context *pCtx = refCtx->m_internalContext;
- _ASSERTE(pCtx != NULL);
-
- if (ValidateContext(pCtx))
- {
- LOG((LF_APPDOMAIN, LL_INFO1000, "Context::CleanupInternalContext: %8.8x, %8.8x\n", OBJECTREFToObject(refCtx), pCtx));
- Context::FreeContext(pCtx);
- }
-
- COUNTER_ONLY(GetPerfCounters().m_Context.cContexts--);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-
-// This is where a call back request made by EE in Context::RequestCallBack
-// actually gets "executed".
-// At this point we have done a real context transition from the threads
-// context when RequestCallBack was called to the destination context.
-FCIMPL1(void, Context::ExecuteCallBack, LPVOID privateData)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(privateData));
- }
- CONTRACTL_END;
-
- HELPER_METHOD_FRAME_BEGIN_0();
-
- switch (((CallBackInfo*) privateData)->callbackId)
- {
- case Wait_callback:
- {
- WaitArgs* waitArgs;
- waitArgs = (WaitArgs*) ((CallBackInfo*) privateData)->callbackData;
- ExecuteWaitCallback(waitArgs);
- break;
- }
-
- case MonitorWait_callback:
- {
- MonitorWaitArgs* waitArgs;
- waitArgs = (MonitorWaitArgs*) ((CallBackInfo*) privateData)->callbackData;
- ExecuteMonitorWaitCallback(waitArgs);
- break;
- }
-
- case ADTransition_callback:
- {
- ADCallBackArgs* pCallArgs = (ADCallBackArgs*)(((CallBackInfo*) privateData)->callbackData);
- pCallArgs->pTarget(pCallArgs->pArguments);
- break;
- }
-
- case SignalAndWait_callback:
- {
- SignalAndWaitArgs* signalAndWaitArgs;
- signalAndWaitArgs = (SignalAndWaitArgs*)((CallBackInfo*)privateData)->callbackData;
- ExecuteSignalAndWaitCallback(signalAndWaitArgs);
- break;
- }
- // Add other callback types here
- default:
- _ASSERTE(!"Invalid callback type");
- break;
- }
-
- // This is EE's entry point to do whatever it wanted to do in
- // the targetContext. This will return back into the managed
- // world and transition back into the original context.
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-
-
-#ifdef ENABLE_PERF_COUNTERS
-
-FCIMPL0(LPVOID, GetPrivateContextsPerfCountersEx)
-{
- FCALL_CONTRACT;
-
- return (LPVOID)GetPrivateContextsPerfCounters();
-}
-FCIMPLEND
-
-
-#else
-FCIMPL0(LPVOID, GetPrivateContextsPerfCountersEx)
-{
- FCALL_CONTRACT;
-
- return NULL;
-}
-FCIMPLEND
-
-#endif // ENABLE_PERF_COUNTERS
-
-#endif // DACCESS_COMPILE
-
-// This will NOT create the exposed object if there isn't one!
-OBJECTREF Context::GetExposedObjectRaw()
-{
- WRAPPER_NO_CONTRACT;
-
- return ObjectFromHandle(m_ExposedObjectHandle);
-}
-
-
-PTR_Object Context::GetExposedObjectRawUnchecked()
-{
- LIMITED_METHOD_CONTRACT;
-
- return *PTR_PTR_Object(m_ExposedObjectHandle);
-}
-
-PTR_PTR_Object Context::GetExposedObjectRawUncheckedPtr()
-{
- LIMITED_METHOD_CONTRACT;
-
- return PTR_PTR_Object(m_ExposedObjectHandle);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: Context::GetStaticFieldAddrNoCreate private
-//
-// Synopsis: Get the address of the field relative to the context given a thread.
-// If an address has not been assigned, return NULL.
-// No creating is allowed.
-//
-
-//
-//+----------------------------------------------------------------------------
-PTR_VOID Context::GetStaticFieldAddrNoCreate(FieldDesc *pFD)
-{
- CONTRACT (PTR_VOID)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pFD));
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- SUPPORTS_DAC;
- }
- CONTRACT_END;
-
- PTR_VOID pvAddress = NULL;
- // for static field the MethodTable is exact even for generic classes
- MethodTable* pMT = pFD->GetEnclosingMethodTable();
- BOOL fIsShared = pMT->IsDomainNeutral();
- DWORD dwClassOffset = pMT->GetContextStaticsOffset();
- DWORD currElem = 0;
- STATIC_DATA* pData;
-
- if (dwClassOffset == (DWORD)-1)
- RETURN NULL;
-
- if(!fIsShared)
- pData = m_pUnsharedStaticData;
- else
- pData = m_pSharedStaticData;
-
- if (NULL == pData)
- RETURN NULL;
-
- currElem = pData->cElem;
-
- // Check whether we have allocated space for storing a pointer to
- // this class' context static store
- if(dwClassOffset >= currElem || pData->dataPtr[dwClassOffset] == NULL)
- RETURN NULL;
-
- _ASSERTE(pData->dataPtr[dwClassOffset] != NULL);
-
- // We have allocated static storage for this data
- // Just return the address by getting the offset into the data
- pvAddress = PTR_VOID(dac_cast<PTR_BYTE>(pData->dataPtr[dwClassOffset]) + pFD->GetOffset());
-
- if(pFD->IsObjRef() || pFD->IsByValue())
- {
- if (*dac_cast<PTR_BYTE>(pvAddress) == NULL)
- {
- pvAddress = NULL;
- LOG((LF_SYNC, LL_ALWAYS, "dbgr: pvAddress = NULL"));
- }
- else
- {
- pvAddress = CalculateAddressForManagedStatic(*(PTR_int(pvAddress)));
- LOG((LF_SYNC, LL_ALWAYS, "dbgr: pvAddress = %lx", pvAddress));
- if (pFD->IsByValue())
- {
- _ASSERTE(pvAddress != NULL);
- pvAddress = (*(PTR_OBJECTREF(pvAddress)))->GetData();
- }
- }
- }
-
- RETURN pvAddress;
-}
-
-
-// This is used for context relative statics that are object refs
-// These are stored in a structure in the managed context. The first
-// time over an index and a bucket are determined and subsequently
-// remembered in the location for the field in the per-context-per-class
-// data structure.
-// Here we map back from the index to the address of the object ref.
-PTR_VOID Context::CalculateAddressForManagedStatic(int slot)
-{
- CONTRACT (PTR_VOID)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(this));
- POSTCONDITION(CheckPointer(RETVAL));
- SUPPORTS_DAC;
- }
- CONTRACT_END;
-
- PTR_OBJECTREF pObjRef;
- int bucket = (slot>>16);
- int index = (0x0000ffff&slot);
-
- // Now determine the address of the static field
- PTRARRAYREF bucketRef = NULL;
-
- bucketRef = ((CONTEXTBASEREF)GetExposedObjectRaw())->GetContextStaticsHolder();
-
- // walk the chain to our bucket
- while (bucket--)
- bucketRef = (PTRARRAYREF) bucketRef->GetAt(0);
-
- // Index 0 is used to point to the next bucket!
- _ASSERTE(index > 0);
- pObjRef = PTR_OBJECTREF(bucketRef->GetDataPtr())+index;
-
- RETURN (PTR_VOID(pObjRef));
-}
-
-#endif // FEATURE_REMOTING
#ifdef DACCESS_COMPILE
diff --git a/src/vm/coreassemblyspec.cpp b/src/vm/coreassemblyspec.cpp
index 310c663392..7cb1f56315 100644
--- a/src/vm/coreassemblyspec.cpp
+++ b/src/vm/coreassemblyspec.cpp
@@ -24,7 +24,6 @@
#include "compile.h"
#endif
-#ifndef FEATURE_FUSION
#include "../binder/inc/textualidentityparser.hpp"
#include "../binder/inc/assemblyidentity.hpp"
@@ -85,7 +84,6 @@ STDAPI BinderGetDisplayName(PEAssembly *pAssembly,
}
-#ifdef FEATURE_VERSIONING
static VOID ThrowLoadError(AssemblySpec * pSpec, HRESULT hr)
{
@@ -222,7 +220,6 @@ VOID AssemblySpec::Bind(AppDomain *pAppDomain,
}
}
-#endif // FEATURE_VERSIONING
STDAPI BinderAcquirePEImage(LPCWSTR wszAssemblyPath,
PEImage **ppPEImage,
@@ -355,13 +352,13 @@ HRESULT BaseAssemblySpec::ParseName()
if (pIUnknownBinder != NULL)
{
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
if (pDomain->GetFusionContext() != pDomain->GetTPABinderContext())
{
pAppContext = (static_cast<CLRPrivBinderAssemblyLoadContext *>(pIUnknownBinder))->GetAppContext();
}
else
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
+#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
{
pAppContext = (static_cast<CLRPrivBinderCoreCLR *>(pIUnknownBinder))->GetAppContext();
}
@@ -595,104 +592,4 @@ VOID BaseAssemblySpec::GetFileOrDisplayName(DWORD flags, SString &result) const
result));
}
-#ifndef FEATURE_CORECLR
-//
-// Trivial assembly binder for desktop crossgen
-//
-
-VOID AssemblySpec::Bind(AppDomain *pAppDomain,
- BOOL fThrowOnFileNotFound,
- CoreBindResult *pResult,
- BOOL fNgenExplicitBind /* = FALSE */,
- BOOL fExplicitBindToNativeImage /* = FALSE */,
- StackCrawlMark *pCallerStackMark /* = NULL */)
-{
- PEImageHolder pImage;
- BOOL fNativeImage = FALSE;
-
- if (GetCodeBase() != NULL)
- {
- // Normalize the path to maintain identity
- SString sFullAssemblyPath;
- Clr::Util::Win32::GetFullPathName(GetCodeBase(), sFullAssemblyPath, NULL);
-
- pImage = PEImage::OpenImage(sFullAssemblyPath, MDInternalImport_Default);
- }
- else
- {
- SString sSimpleName(SString::Utf8, m_pAssemblyName);
-
- fNativeImage = !IsReadyToRunCompilation() && pAppDomain->ToCompilationDomain()->IsInHardBindList(sSimpleName);
-
- SString sFileName(sSimpleName, fNativeImage ? W(".ni.dll") : W(".dll"));
-
- if (!CompilationDomain::FindImage(sFileName,
- fNativeImage ? MDInternalImport_TrustedNativeImage : MDInternalImport_Default,
- &pImage))
- {
- sFileName.Set(sSimpleName, fNativeImage ? W(".ni.exe") : W(".exe"));
-
- if (!CompilationDomain::FindImage(sFileName,
- fNativeImage ? MDInternalImport_TrustedNativeImage : MDInternalImport_Default,
- &pImage))
- {
- EEFileLoadException::Throw(sSimpleName, COR_E_FILENOTFOUND);
- }
- }
- }
-
- GetSvcLogger()->Printf(W("Loading %s\n"), pImage->GetPath().GetUnicode());
-
- NewHolder<BINDER_SPACE::Assembly> pAssembly;
- pAssembly = new BINDER_SPACE::Assembly();
-
- pAssembly->m_assemblyPath.Set(pImage->GetPath());
-
- if (fNativeImage)
- pAssembly->SetNativePEImage(pImage.Extract());
- else
- pAssembly->SetPEImage(pImage.Extract());
-
- pResult->Init(pAssembly.Extract(), TRUE, TRUE);
-}
-
-VOID AssemblySpec::BindToSystem(BINDER_SPACE::Assembly** ppAssembly)
-{
- PEImageHolder pImage;
- BOOL fNativeImage = FALSE;
-
- _ASSERTE(ppAssembly != nullptr);
-
- if (g_fAllowNativeImages)
- {
- if (CompilationDomain::FindImage(W("mscorlib.ni.dll"), MDInternalImport_TrustedNativeImage, &pImage))
- fNativeImage = TRUE;
- }
-
- if (!fNativeImage)
- {
- if (!CompilationDomain::FindImage(W("mscorlib.dll"), MDInternalImport_Default, &pImage))
- {
- EEFileLoadException::Throw(W("mscorlib.dll"), COR_E_FILENOTFOUND);
- }
- }
-
- GetSvcLogger()->Printf(W("Loading %s\n"), pImage->GetPath().GetUnicode());
-
- NewHolder<BINDER_SPACE::Assembly> pAssembly;
- pAssembly = new BINDER_SPACE::Assembly();
-
- pAssembly->m_assemblyPath.Set(pImage->GetPath());
-
- if (fNativeImage)
- pAssembly->SetNativePEImage(pImage.Extract());
- else
- pAssembly->SetPEImage(pImage.Extract());
-
- *ppAssembly = pAssembly.Extract();
-}
-
-#endif // !FEATURE_CORECLR
-
-#endif // FEATURE_FUSION
diff --git a/src/vm/corebindresult.cpp b/src/vm/corebindresult.cpp
index 68803e24b9..3013264ade 100644
--- a/src/vm/corebindresult.cpp
+++ b/src/vm/corebindresult.cpp
@@ -15,7 +15,6 @@
#include "../binder/inc/assembly.hpp"
-#ifndef FEATURE_FUSION
#ifndef DACCESS_COMPILE
STDMETHODIMP CoreBindResult::QueryInterface(REFIID riid,
@@ -63,4 +62,3 @@ STDMETHODIMP_(ULONG) CoreBindResult::Release()
#endif // DACCES_COMPILE
-#endif // FEATURE_FUSION
diff --git a/src/vm/corhost.cpp b/src/vm/corhost.cpp
index 369d6fcfd7..75adbada94 100644
--- a/src/vm/corhost.cpp
+++ b/src/vm/corhost.cpp
@@ -19,7 +19,6 @@
#include "eeconfig.h"
#include "dbginterface.h"
#include "ceemain.h"
-#include "rwlock.h"
#include "hosting.h"
#include "eepolicy.h"
#include "clrex.h"
@@ -27,7 +26,6 @@
#include "ipcmanagerinterface.h"
#endif // FEATURE_IPCMAN
#include "comcallablewrapper.h"
-#include "hostexecutioncontext.h"
#include "invokeutil.h"
#include "appdomain.inl"
#include "vars.hpp"
@@ -50,10 +48,6 @@
#include "winrttypenameconverter.h"
#endif
-#if defined(FEATURE_APPX_BINDER)
-#include "clrprivbinderappx.h"
-#include "clrprivtypecachewinrt.h"
-#endif
GVAL_IMPL_INIT(DWORD, g_fHostConfig, 0);
@@ -74,7 +68,7 @@ SVAL_IMPL_INIT(DWORD, CExecutionEngine, TlsIndex, TLS_OUT_OF_INDEXES);
#endif
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
+#if defined(FEATURE_WINDOWSPHONE)
SVAL_IMPL_INIT(ECustomDumpFlavor, CCLRErrorReportingManager, g_ECustomDumpFlavor, DUMP_FLAVOR_Default);
#endif
@@ -89,406 +83,17 @@ extern BOOL g_fEEHostedStartup;
INT64 g_PauseTime; // Total time in millisecond the CLR has been paused
Volatile<BOOL> g_IsPaused; // True if the runtime is paused (FAS)
CLREventStatic g_ClrResumeEvent; // Event that is fired at FAS Resuming
-#ifndef FEATURE_CORECLR
-CLREventStatic g_PauseCompletedEvent; // Set when Pause has completed its work on another thread.
-#endif
-#if defined(FEATURE_CORECLR)
extern BYTE g_rbTestKeyBuffer[];
-#endif
-
-#if !defined(FEATURE_CORECLR)
-//******************************************************************************
-// <TODO>TODO: ICorThreadpool: Move this into a separate file CorThreadpool.cpp
-// after the move to VBL </TODO>
-//******************************************************************************
-
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorRegisterWaitForSingleObject(PHANDLE phNewWaitObject,
- HANDLE hWaitObject,
- WAITORTIMERCALLBACK Callback,
- PVOID Context,
- ULONG timeout,
- BOOL executeOnlyOnce,
- BOOL* pResult)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = E_UNEXPECTED;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- ULONG flag = executeOnlyOnce ? WAIT_SINGLE_EXECUTION : 0;
- *pResult = FALSE;
- EX_TRY
- {
- *pResult = ThreadpoolMgr::RegisterWaitForSingleObject(phNewWaitObject,
- hWaitObject,
- Callback,
- Context,
- timeout,
- flag);
-
- hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError());
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorBindIoCompletionCallback(HANDLE fileHandle,
- LPOVERLAPPED_COMPLETION_ROUTINE callback)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BOOL ret = FALSE;
- DWORD errCode = 0;
-
- EX_TRY
- {
- ret = ThreadpoolMgr::BindIoCompletionCallback(fileHandle,callback,0, errCode);
- hr = (ret ? S_OK : HRESULT_FROM_WIN32(errCode));
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorUnregisterWait(HANDLE hWaitObject,
- HANDLE CompletionEvent,
- BOOL* pResult)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = E_UNEXPECTED;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pResult = FALSE;
- EX_TRY
- {
-
- *pResult = ThreadpoolMgr::UnregisterWaitEx(hWaitObject,CompletionEvent);
- hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError());
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-
-}
-
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorQueueUserWorkItem(LPTHREAD_START_ROUTINE Function,
- PVOID Context,BOOL executeOnlyOnce,
- BOOL* pResult )
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pResult = FALSE;
- EX_TRY
- {
- *pResult = ThreadpoolMgr::QueueUserWorkItem(Function,Context,QUEUE_ONLY);
- hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError());
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorCallOrQueueUserWorkItem(LPTHREAD_START_ROUTINE Function,
- PVOID Context,
- BOOL* pResult )
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
- *pResult = FALSE;
- EX_TRY
- {
- *pResult = ThreadpoolMgr::QueueUserWorkItem(Function,Context,CALL_OR_QUEUE);
- hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError());
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorCreateTimer(PHANDLE phNewTimer,
- WAITORTIMERCALLBACK Callback,
- PVOID Parameter,
- DWORD DueTime,
- DWORD Period,
- BOOL* pResult)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pResult = FALSE;
- EX_TRY
- {
- *pResult = ThreadpoolMgr::CreateTimerQueueTimer(phNewTimer,Callback,Parameter,DueTime,Period,0);
- hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError());
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorDeleteTimer(HANDLE Timer, HANDLE CompletionEvent, BOOL* pResult)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pResult = FALSE;
- EX_TRY
- {
- *pResult = ThreadpoolMgr::DeleteTimerQueueTimer(Timer,CompletionEvent);
- hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError());
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorChangeTimer(HANDLE Timer,
- ULONG DueTime,
- ULONG Period,
- BOOL* pResult)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pResult = FALSE;
- EX_TRY
- {
- //CONTRACT_VIOLATION(ThrowsViolation);
- *pResult = ThreadpoolMgr::ChangeTimerQueueTimer(Timer,DueTime,Period);
- hr = (*pResult ? S_OK : HRESULT_FROM_GetLastError());
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorSetMaxThreads(DWORD MaxWorkerThreads,
- DWORD MaxIOCompletionThreads)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BOOL result = FALSE;
- EX_TRY
- {
- result = ThreadpoolMgr::SetMaxThreads(MaxWorkerThreads, MaxIOCompletionThreads);
- hr = (result ? S_OK : E_FAIL);
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorGetMaxThreads(DWORD *MaxWorkerThreads,
- DWORD *MaxIOCompletionThreads)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BOOL result = FALSE;
- EX_TRY
- {
- result = ThreadpoolMgr::GetMaxThreads(MaxWorkerThreads, MaxIOCompletionThreads);
- hr = (result ? S_OK : E_FAIL);
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE CorThreadpool::CorGetAvailableThreads(DWORD *AvailableWorkerThreads,
- DWORD *AvailableIOCompletionThreads)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = E_UNEXPECTED;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BOOL result = FALSE;
- EX_TRY
- {
- result = ThreadpoolMgr::GetAvailableThreads(AvailableWorkerThreads, AvailableIOCompletionThreads);
- hr = (result ? S_OK : E_FAIL);
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-#endif // !defined(FEATURE_CORECLR)
//***************************************************************************
ULONG CorRuntimeHostBase::m_Version = 0;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-static CCLRDebugManager s_CLRDebugManager;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
+#if defined(FEATURE_WINDOWSPHONE)
CCLRErrorReportingManager g_CLRErrorReportingManager;
-#endif // defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
+#endif // defined(FEATURE_WINDOWSPHONE)
#ifdef FEATURE_IPCMAN
static CCLRSecurityAttributeManager s_CLRSecurityAttributeManager;
@@ -498,270 +103,16 @@ static CCLRSecurityAttributeManager s_CLRSecurityAttributeManager;
typedef DPTR(CONNID) PTR_CONNID;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-// Hash table to keep track <connection, name> for SQL fiber support
-class ConnectionNameTable : CHashTableAndData<CNewDataNoThrow>
-{
- friend class CCLRDebugManager;
-public:
-
- // Key to match is connection ID.
- // Returns true if the given HASHENTRY has the same key as the requested key.
- BOOL Cmp(SIZE_T requestedKey, const HASHENTRY * pEntry)
- {
- SUPPORTS_DAC;
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
-
- CONNID keyRequested = (CONNID)requestedKey;
- CONNID keySearch = dac_cast<PTR_ConnectionNameHashEntry>(pEntry)->m_dwConnectionId;
- return keyRequested != keySearch;
- }
-
- // Hash function
- ULONG Hash(CONNID dwConnectionId)
- {
- SUPPORTS_DAC;
- LIMITED_METHOD_CONTRACT;
-
- return (ULONG)(dwConnectionId);
- }
-
-#ifndef DACCESS_COMPILE
- // constructor
- ConnectionNameTable(
- ULONG iBuckets) : // # of chains we are hashing into.
- CHashTableAndData<CNewDataNoThrow>(iBuckets)
- {LIMITED_METHOD_CONTRACT;}
-
- // destructor
- ~ConnectionNameTable()
- {
- CONTRACTL
- {
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- NOTHROW;
- }
- CONTRACTL_END;
- HASHFIND hashFind;
- ConnectionNameHashEntry *pNameEntry;
-
- pNameEntry = (ConnectionNameHashEntry *)FindFirstEntry(&hashFind);
- while (pNameEntry != NULL)
- {
- if (pNameEntry->m_pwzName)
- {
- delete pNameEntry->m_pwzName;
- pNameEntry->m_pwzName = NULL;
- }
-
- if (pNameEntry->m_CLRTaskCount != 0)
- {
- _ASSERTE(pNameEntry->m_ppCLRTaskArray != NULL);
- for (UINT i = 0; i < pNameEntry->m_CLRTaskCount; i++)
- {
- pNameEntry->m_ppCLRTaskArray[i]->Release();
- }
- delete [] pNameEntry->m_ppCLRTaskArray;
- pNameEntry->m_ppCLRTaskArray = NULL;
- pNameEntry->m_CLRTaskCount = 0;
- }
- pNameEntry = (ConnectionNameHashEntry *)FindNextEntry(&hashFind);
- }
- }
-
- // Add a new connection into hash table.
- // This function does not throw but return NULL when memory allocation fails.
- ConnectionNameHashEntry *AddConnection(
- CONNID dwConnectionId,
- __in_z WCHAR *pwzName) // We should review this in the future. This API is
- // public and callable by a host. This SAL annotation
- // is the best we can do now.
- {
- CONTRACTL
- {
- GC_NOTRIGGER;
- NOTHROW;
- }
- CONTRACTL_END;
-
- ULONG iHash = Hash(dwConnectionId);
-
- size_t len = wcslen(pwzName) + 1;
- WCHAR *pConnName = new (nothrow) WCHAR[len];
- if (pConnName == NULL)
- return NULL;
-
- ConnectionNameHashEntry *pRecord = (ConnectionNameHashEntry *)Add(iHash);
- if (pRecord)
- {
- pRecord->m_dwConnectionId = dwConnectionId;
- pRecord->m_pwzName = pConnName;
- wcsncpy_s(pRecord->m_pwzName, len, pwzName, len);
- pRecord->m_CLRTaskCount = 0;
- pRecord->m_ppCLRTaskArray = NULL;
- }
- else
- {
- if (pConnName)
- delete [] pConnName;
- }
-
- return pRecord;
- }
-
- // Delete a hash entry given a connection id
- void DeleteConnection(CONNID dwConnectionId)
- {
- CONTRACTL
- {
- GC_NOTRIGGER;
- NOTHROW;
- }
- CONTRACTL_END;
-
- ULONG iHash;
- iHash = Hash(dwConnectionId);
- ConnectionNameHashEntry * pRecord =
- reinterpret_cast<ConnectionNameHashEntry *>(Find(iHash, (SIZE_T)dwConnectionId));
- if (pRecord == NULL)
- {
- return;
- }
-
- _ASSERTE(pRecord->m_CLRTaskCount == 0 && pRecord->m_ppCLRTaskArray == NULL);
- if (pRecord->m_pwzName)
- {
- delete pRecord->m_pwzName;
- pRecord->m_pwzName = NULL;
- }
- Delete(iHash, (HASHENTRY *)pRecord);
- }
-
- // return NULL if the given connection id cannot be found.
- ConnectionNameHashEntry *FindConnection(CONNID dwConnectionId)
- {
- CONTRACTL
- {
- GC_NOTRIGGER;
- NOTHROW;
- }
- CONTRACTL_END;
-
- ULONG iHash;
- iHash = Hash(dwConnectionId);
- return reinterpret_cast<ConnectionNameHashEntry *>(Find(iHash, (SIZE_T)dwConnectionId));
- }
-#endif // !DAC
-};
-#endif //FEATURE_INCLUDE_ALL_INTERFACES
// Keep track connection id and name
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-SPTR_IMPL(ConnectionNameTable, CCLRDebugManager, m_pConnectionNameHash);
-CrstStatic CCLRDebugManager::m_lockConnectionNameTable;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#ifndef DACCESS_COMPILE
-#if !defined(FEATURE_CORECLR) // simple hosting
-//*****************************************************************************
-// ICorRuntimeHost
-//*****************************************************************************
-extern BOOL g_singleVersionHosting;
-
-// *** ICorRuntimeHost methods ***
-// Returns an object for configuring the runtime prior to
-// it starting. If the runtime has been initialized this
-// routine returns an error. See ICorConfiguration.
-HRESULT CorHost::GetConfiguration(ICorConfiguration** pConfiguration)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
- HRESULT hr=E_FAIL;
- BEGIN_ENTRYPOINT_NOTHROW;
- if (CorHost::GetHostVersion() != 1)
- {
- hr=HOST_E_INVALIDOPERATION;
- }
- else
- if (!pConfiguration)
- hr= E_POINTER;
- else
- if (!m_Started)
- {
- *pConfiguration = (ICorConfiguration *) this;
- AddRef();
- hr=S_OK;
- }
- END_ENTRYPOINT_NOTHROW;
- // Cannot obtain configuration after the runtime is started
- return hr;
-}
-
-STDMETHODIMP CorHost::Start(void)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr;
- BEGIN_ENTRYPOINT_NOTHROW;
- hr = CorRuntimeHostBase::Start();
-
- END_ENTRYPOINT_NOTHROW;
-
- if (hr == S_FALSE)
- {
- // This is to keep v1 behavior.
- hr = S_OK;
- }
- return(hr);
-}
-#endif // !defined(FEATURE_CORECLR)
// *** ICorRuntimeHost methods ***
-#ifndef FEATURE_CORECLR
-// Returns an object for configuring the runtime prior to
-// it starting. If the runtime has been initialized this
-// routine returns an error. See ICorConfiguration.
-HRESULT CorHost2::GetConfiguration(ICorConfiguration** pConfiguration)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- if (!pConfiguration)
- return E_POINTER;
- HRESULT hr=E_FAIL;
- BEGIN_ENTRYPOINT_NOTHROW;
- if (!m_Started)
- {
- *pConfiguration = (ICorConfiguration *) this;
- AddRef();
- hr=S_OK;
- }
- END_ENTRYPOINT_NOTHROW;
- // Cannot obtain configuration after the runtime is started
- return hr;
-}
-#endif // FEATURE_CORECLR
extern BOOL g_fWeOwnProcess;
@@ -769,11 +120,9 @@ CorHost2::CorHost2()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
m_fStarted = FALSE;
m_fFirstToLoadCLR = FALSE;
m_fAppDomainCreated = FALSE;
-#endif // FEATURE_CORECLR
}
static DangerousNonHostedSpinLock lockOnlyOneToInvokeStart;
@@ -791,7 +140,6 @@ STDMETHODIMP CorHost2::Start()
BEGIN_ENTRYPOINT_NOTHROW;
-#ifdef FEATURE_CORECLR
// Ensure that only one thread at a time gets in here
DangerousNonHostedSpinLockHolder lockHolder(&lockOnlyOneToInvokeStart);
@@ -821,7 +169,6 @@ STDMETHODIMP CorHost2::Start()
}
}
else
-#endif // FEATURE_CORECLR
{
// Using managed C++ libraries, its possible that when the runtime is already running,
// MC++ will use CorBindToRuntimeEx to make callbacks into specific appdomain of its
@@ -842,7 +189,6 @@ STDMETHODIMP CorHost2::Start()
hr = CorRuntimeHostBase::Start();
if (SUCCEEDED(hr))
{
-#ifdef FEATURE_CORECLR
// Set our flag that this host invoked the Start method.
m_fStarted = TRUE;
@@ -855,7 +201,6 @@ STDMETHODIMP CorHost2::Start()
// So, if you want to do that, just make sure you are the first host to load the
// specific version of CLR in memory AND start it.
m_fFirstToLoadCLR = TRUE;
-#endif // FEATURE_CORECLR
if (FastInterlockIncrement(&m_RefCount) != 1)
{
}
@@ -901,21 +246,6 @@ HRESULT CorRuntimeHostBase::Start()
return hr;
}
-#if !defined(FEATURE_CORECLR) // simple hosting
-HRESULT CorHost::Stop()
-{
- CONTRACTL
- {
- NOTHROW;
- ENTRY_POINT;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- }
- CONTRACTL_END;
-
- // This must remain this way (that is doing nothing) for backwards compat reasons.
- return S_OK;
-}
-#endif // !defined(FEATURE_CORECLR)
HRESULT CorHost2::Stop()
{
@@ -933,7 +263,6 @@ HRESULT CorHost2::Stop()
HRESULT hr=S_OK;
BEGIN_ENTRYPOINT_NOTHROW;
-#ifdef FEATURE_CORECLR
// Is this host eligible to invoke the Stop method?
if ((!m_fStarted) && (!m_fFirstToLoadCLR))
{
@@ -944,28 +273,21 @@ HRESULT CorHost2::Stop()
hr = HOST_E_CLRNOTAVAILABLE;
}
else
-#endif // FEATURE_CORECLR
{
while (TRUE)
{
LONG refCount = m_RefCount;
if (refCount == 0)
{
- #ifdef FEATURE_CORECLR
hr = HOST_E_CLRNOTAVAILABLE;
- #else // !FEATURE_CORECLR
- hr= E_UNEXPECTED;
- #endif // FEATURE_CORECLR
break;
}
else
if (FastInterlockCompareExchange(&m_RefCount, refCount - 1, refCount) == refCount)
{
- #ifdef FEATURE_CORECLR
// Indicate that we have got a Stop for a corresponding Start call from the
// Host. Semantically, CoreCLR has stopped for them.
m_fStarted = FALSE;
- #endif // FEATURE_CORECLR
if (refCount > 1)
{
@@ -979,125 +301,12 @@ HRESULT CorHost2::Stop()
}
}
}
-#ifndef FEATURE_CORECLR
- if (hr==S_OK)
- {
- EPolicyAction action = GetEEPolicy()->GetDefaultAction(OPR_ProcessExit, NULL);
- if (action > eExitProcess)
- {
- g_fFastExitProcess = 1;
- }
- EEShutDown(FALSE);
- }
-#endif // FEATURE_CORECLR
END_ENTRYPOINT_NOTHROW;
-#ifndef FEATURE_CORECLR
- if (hr == S_OK)
- {
- if (m_HostControl)
- {
- m_HostControl->Release();
- m_HostControl = NULL;
- }
- }
-#endif // FEATURE_CORECLR
-
- return hr;
-}
-
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
-
-// Creates a domain in the runtime. The identity array is
-// a pointer to an array TYPE containing IIdentity objects defining
-// the security identity.
-HRESULT CorRuntimeHostBase::CreateDomain(LPCWSTR pwzFriendlyName,
- IUnknown* pIdentityArray, // Optional
- IUnknown ** pAppDomain)
-{
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_ENTRY_POINT;
-
- return CreateDomainEx(pwzFriendlyName,
- NULL,
- NULL,
- pAppDomain);
-}
-
-
-// Returns the default domain.
-HRESULT CorRuntimeHostBase::GetDefaultDomain(IUnknown ** pAppDomain)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- } CONTRACTL_END;
-
- HRESULT hr = E_UNEXPECTED;
- if (!g_fEEStarted)
- return hr;
-
- if( pAppDomain == NULL)
- return E_POINTER;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr);
- {
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
-
- if (SystemDomain::System()) {
- AppDomain* pCom = SystemDomain::System()->DefaultDomain();
- if(pCom)
- hr = pCom->GetComIPForExposedObject(pAppDomain);
- }
-
- }
- END_EXTERNAL_ENTRYPOINT;
- END_ENTRYPOINT_NOTHROW;
return hr;
}
-// Returns the default domain.
-HRESULT CorRuntimeHostBase::CurrentDomain(IUnknown ** pAppDomain)
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- }
- CONTRACTL_END;
-
- HRESULT hr = E_UNEXPECTED;
- if (!g_fEEStarted)
- return hr;
-
- if( pAppDomain == NULL) return E_POINTER;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr);
- {
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
-
- AppDomain* pCom = ::GetAppDomain();
- if(pCom)
- hr = pCom->GetComIPForExposedObject(pAppDomain);
-
- }
- END_EXTERNAL_ENTRYPOINT;
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-};
-
-#endif // FEATURE_COMINTEROP && !FEATURE_CORECLR
HRESULT CorHost2::GetCurrentAppDomainId(DWORD *pdwAppDomainId)
{
@@ -1113,9 +322,7 @@ HRESULT CorHost2::GetCurrentAppDomainId(DWORD *pdwAppDomainId)
// We use CanRunManagedCode() instead of IsRuntimeActive() because this allows us
// to specify test using the form that does not trigger a GC.
if (!(g_fEEStarted && CanRunManagedCode(LoaderLockCheck::None))
-#ifdef FEATURE_CORECLR
|| !m_fStarted
-#endif
)
{
return HOST_E_CLRNOTAVAILABLE;
@@ -1154,64 +361,9 @@ HRESULT CorHost2::ExecuteApplication(LPCWSTR pwzAppFullName,
LPCWSTR *ppwzActivationData,
int *pReturnValue)
{
-#ifndef FEATURE_CORECLR
- // This API should not be called when the EE has already been started.
- HRESULT hr = E_UNEXPECTED;
- if (g_fEEStarted)
- return hr;
-
- //
- // We will let unhandled exceptions in the activated application
- // propagate all the way up, so that ClickOnce semi-trusted apps
- // can participate in the Dr Watson program, etc...
- //
-
- CONTRACTL {
- THROWS;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- if (!pwzAppFullName)
- IfFailGo(E_POINTER);
-
- // Set the information about the application to execute.
- CorCommandLine::m_pwszAppFullName = (LPWSTR) pwzAppFullName;
- CorCommandLine::m_dwManifestPaths = dwManifestPaths;
- CorCommandLine::m_ppwszManifestPaths = (LPWSTR*) ppwzManifestPaths;
- CorCommandLine::m_dwActivationData = dwActivationData;
- CorCommandLine::m_ppwszActivationData = (LPWSTR*) ppwzActivationData;
-
- // Start up the EE.
- IfFailGo(Start());
-
- Thread *pThread;
- pThread = GetThread();
- if (pThread == NULL)
- pThread = SetupThreadNoThrow(&hr);
- if (pThread == NULL)
- goto ErrExit;
-
- _ASSERTE (!pThread->PreemptiveGCDisabled());
-
- hr = S_OK;
-
- BEGIN_ENTRYPOINT_THROWS_WITH_THREAD(pThread);
- ENTER_DOMAIN_PTR(SystemDomain::System()->DefaultDomain(),ADV_DEFAULTAD)
-
- SystemDomain::ActivateApplication(pReturnValue);
-
- END_DOMAIN_TRANSITION;
- END_ENTRYPOINT_THROWS_WITH_THREAD;
-
-ErrExit:
- return hr;
-#else // FEATURE_CORECLR
return E_NOTIMPL;
-#endif
}
-#ifdef FEATURE_CORECLR
/*
* This method processes the arguments sent to the host which are then used
* to invoke the main method.
@@ -1363,7 +515,6 @@ ErrExit:
return hr;
}
-#endif
HRESULT CorHost2::ExecuteInDefaultAppDomain(LPCWSTR pwzAssemblyPath,
LPCWSTR pwzTypeName,
@@ -1380,98 +531,15 @@ HRESULT CorHost2::ExecuteInDefaultAppDomain(LPCWSTR pwzAssemblyPath,
// No point going further if the runtime is not running...
if (!IsRuntimeActive()
-#ifdef FEATURE_CORECLR
|| !m_fStarted
-#endif
)
{
return HOST_E_CLRNOTAVAILABLE;
}
-#ifndef FEATURE_CORECLR
- if(! (pwzAssemblyPath && pwzTypeName && pwzMethodName) )
- return E_POINTER;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- Thread *pThread = GetThread();
- if (pThread == NULL)
- {
- pThread = SetupThreadNoThrow(&hr);
- if (pThread == NULL)
- {
- goto ErrExit;
- }
- }
-
- _ASSERTE (!pThread->PreemptiveGCDisabled());
-
- EX_TRY
- {
- ENTER_DOMAIN_PTR(SystemDomain::System()->DefaultDomain(),ADV_DEFAULTAD)
-
- INSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
- Assembly *pAssembly = AssemblySpec::LoadAssembly(pwzAssemblyPath);
-
- SString szTypeName(pwzTypeName);
- StackScratchBuffer buff1;
- const char* szTypeNameUTF8 = szTypeName.GetUTF8(buff1);
- MethodTable *pMT = ClassLoader::LoadTypeByNameThrowing(pAssembly,
- NULL,
- szTypeNameUTF8).AsMethodTable();
-
- SString szMethodName(pwzMethodName);
- StackScratchBuffer buff;
- const char* szMethodNameUTF8 = szMethodName.GetUTF8(buff);
- MethodDesc *pMethodMD = MemberLoader::FindMethod(pMT, szMethodNameUTF8, &gsig_SM_Str_RetInt);
-
- if (!pMethodMD)
- {
- hr = COR_E_MISSINGMETHOD;
- }
- else
- {
- GCX_COOP();
-
- MethodDescCallSite method(pMethodMD);
-
- STRINGREF sref = NULL;
- GCPROTECT_BEGIN(sref);
-
- if (pwzArgument)
- sref = StringObject::NewString(pwzArgument);
-
- ARG_SLOT MethodArgs[] =
- {
- ObjToArgSlot(sref)
- };
- DWORD retval = method.Call_RetI4(MethodArgs);
- if (pReturnValue)
- {
- *pReturnValue = retval;
- }
-
- GCPROTECT_END();
- }
-
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
- END_DOMAIN_TRANSITION;
- }
- EX_CATCH_HRESULT(hr);
-
-ErrExit:
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-#else // FEATURE_CORECLR
// Ensure that code is not loaded in the Default AppDomain
return HOST_E_INVALIDOPERATION;
-#endif
}
HRESULT ExecuteInAppDomainHelper(FExecuteInAppDomainCallback pCallback,
@@ -1496,22 +564,18 @@ HRESULT CorHost2::ExecuteInAppDomain(DWORD dwAppDomainId,
// No point going further if the runtime is not running...
if (!IsRuntimeActive()
-#ifdef FEATURE_CORECLR
|| !m_fStarted
-#endif // FEATURE_CORECLR
)
{
return HOST_E_CLRNOTAVAILABLE;
}
-#ifdef FEATURE_CORECLR
if(!(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN))
{
// Ensure that code is not loaded in the Default AppDomain
if (dwAppDomainId == DefaultADID)
return HOST_E_INVALIDOPERATION;
}
-#endif // FEATURE_CORECLR
// Moved this here since no point validating the pointer
// if the basic checks [above] fail
@@ -1555,9 +619,6 @@ HRESULT CorHost2::_CreateAppDomain(
int nProperties,
LPCWSTR* pPropertyNames,
LPCWSTR* pPropertyValues,
-#if !defined(FEATURE_CORECLR)
- ICLRPrivBinder* pBinder,
-#endif
DWORD* pAppDomainID)
{
CONTRACTL
@@ -1570,13 +631,11 @@ HRESULT CorHost2::_CreateAppDomain(
HRESULT hr=S_OK;
-#ifdef FEATURE_CORECLR
//cannot call the function more than once when single appDomain is allowed
if (m_fAppDomainCreated && (m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN))
{
return HOST_E_INVALIDOPERATION;
}
-#endif
//normalize empty strings
EMPTY_STRING_TO_NULL(wszFriendlyName);
@@ -1586,10 +645,8 @@ HRESULT CorHost2::_CreateAppDomain(
if(pAppDomainID==NULL)
return E_POINTER;
-#ifdef FEATURE_CORECLR
if (!m_fStarted)
return HOST_E_INVALIDOPERATION;
-#endif // FEATURE_CORECLR
if(wszFriendlyName == NULL)
return E_INVALIDARG;
@@ -1604,26 +661,22 @@ HRESULT CorHost2::_CreateAppDomain(
AppDomainCreationHolder<AppDomain> pDomain;
-#ifdef FEATURE_CORECLR
// If StartupFlag specifies single appDomain then return the default domain instead of creating new one
if(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN)
{
pDomain.Assign(SystemDomain::System()->DefaultDomain());
}
else
-#endif
{
AppDomain::CreateUnmanagedObject(pDomain);
}
ETW::LoaderLog::DomainLoad(pDomain, (LPWSTR)wszFriendlyName);
-#ifdef FEATURE_CORECLR
if (dwFlags & APPDOMAIN_IGNORE_UNHANDLED_EXCEPTIONS)
{
pDomain->SetIgnoreUnhandledExceptions();
}
-#endif // FEATURE_CORECLR
if (dwFlags & APPDOMAIN_SECURITY_FORBID_CROSSAD_REVERSE_PINVOKE)
pDomain->SetReversePInvokeCannotEnter();
@@ -1631,10 +684,6 @@ HRESULT CorHost2::_CreateAppDomain(
if (dwFlags & APPDOMAIN_FORCE_TRIVIAL_WAIT_OPERATIONS)
pDomain->SetForceTrivialWaitOperations();
-#if !defined(FEATURE_CORECLR)
- if (pBinder != NULL)
- pDomain->SetLoadContextHostBinder(pBinder);
-#endif
#ifdef PROFILING_SUPPORTED
EX_TRY
@@ -1689,12 +738,8 @@ HRESULT CorHost2::_CreateAppDomain(
args[1]=ObjToArgSlot(NULL);
args[2]=ObjToArgSlot(NULL);
args[3]=ObjToArgSlot(NULL);
-#ifdef FEATURE_CORECLR
//CoreCLR shouldn't have dependencies on parent app domain.
args[4]=ObjToArgSlot(NULL);
-#else
- args[4]=PtrToArgSlot(GetAppDomain()->GetSecurityDescriptor());
-#endif //FEATURE_CORECLR
args[5]=ObjToArgSlot(_gc.sandboxName);
args[6]=ObjToArgSlot(_gc.propertyNames);
args[7]=ObjToArgSlot(_gc.propertyValues);
@@ -1707,12 +752,6 @@ HRESULT CorHost2::_CreateAppDomain(
PTRARRAYREF handleArrayObj = (PTRARRAYREF) ObjectToOBJECTREF(_gc.setupInfo);
_gc.adSetup = ObjectToOBJECTREF(handleArrayObj->GetAt(1));
-#ifndef FEATURE_CORECLR
- // We need to setup domain sorting before any other managed code runs in the domain, since that code
- // could end up caching data based on the sorting mode of the domain.
- pDomain->InitializeSorting(&_gc.adSetup);
- pDomain->InitializeHashing(&_gc.adSetup);
-#endif
pDomain->DoSetup(&_gc.setupInfo);
@@ -1722,13 +761,11 @@ HRESULT CorHost2::_CreateAppDomain(
*pAppDomainID=pDomain->GetId().m_dwId;
-#ifdef FEATURE_CORECLR
// If StartupFlag specifies single appDomain then set the flag that appdomain has already been created
if(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN)
{
m_fAppDomainCreated = TRUE;
}
-#endif
}
#ifdef PROFILING_SUPPORTED
EX_HOOK
@@ -1798,7 +835,6 @@ HRESULT CorHost2::_CreateDelegate(
if(wszMethodName == NULL)
return E_INVALIDARG;
-#ifdef FEATURE_CORECLR
if (!m_fStarted)
return HOST_E_INVALIDOPERATION;
@@ -1808,7 +844,6 @@ HRESULT CorHost2::_CreateDelegate(
if (appDomainID == DefaultADID)
return HOST_E_INVALIDOPERATION;
}
-#endif
BEGIN_ENTRYPOINT_NOTHROW;
@@ -1856,11 +891,9 @@ HRESULT CorHost2::_CreateDelegate(
if (pMD==NULL || !pMD->IsStatic() || pMD->ContainsGenericVariables())
ThrowHR(COR_E_MISSINGMETHOD);
-#ifdef FEATURE_CORECLR
// the target method must be decorated with AllowReversePInvokeCallsAttribute
if (!COMDelegate::IsMethodAllowedToSinkReversePInvoke(pMD))
ThrowHR(COR_E_SECURITY);
-#endif
UMEntryThunk *pUMEntryThunk = GetAppDomain()->GetUMEntryThunkCache()->GetUMEntryThunk(pMD);
*fnPtr = (INT_PTR)pUMEntryThunk->GetCode();
@@ -1874,7 +907,6 @@ HRESULT CorHost2::_CreateDelegate(
return hr;
}
-#ifdef FEATURE_CORECLR
HRESULT CorHost2::CreateAppDomainWithManager(
LPCWSTR wszFriendlyName,
DWORD dwFlags,
@@ -1957,70 +989,7 @@ HRESULT CorHost2::SetStartupFlags(STARTUP_FLAGS flag)
return S_OK;
}
-#endif //FEATURE_CORECLR
-
-#ifndef FEATURE_CORECLR
-void PauseOneAppDomain(AppDomainIterator* pi)
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- EX_TRY {
- ENTER_DOMAIN_PTR(pi->GetDomain(),ADV_ITERATOR);
-
- MethodDescCallSite(METHOD__APP_DOMAIN__PAUSE).Call(NULL);
-
- END_DOMAIN_TRANSITION;
- } EX_CATCH {
- } EX_END_CATCH(SwallowAllExceptions);
-}
-
-void ResumeOneAppDomain(AppDomainIterator* pi)
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- EX_TRY {
- ENTER_DOMAIN_PTR(pi->GetDomain(),ADV_ITERATOR);
-
- MethodDescCallSite(METHOD__APP_DOMAIN__RESUME).Call(NULL);
-
- END_DOMAIN_TRANSITION;
- } EX_CATCH {
- } EX_END_CATCH(SwallowAllExceptions);
-}
-
-// see comments in SuspendEEFromPause
-DWORD WINAPI SuspendAndResumeForPause(LPVOID arg)
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_ANY;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_OTHER);
-
- g_PauseCompletedEvent.Set();
- g_ClrResumeEvent.Wait(INFINITE, FALSE);
-
- ThreadSuspend::RestartEE(FALSE, TRUE);
- return 0;
-}
-#endif // !FEATURE_CORECLR
HRESULT SuspendEEForPause()
{
@@ -2034,33 +1003,9 @@ HRESULT SuspendEEForPause()
HRESULT hr = S_OK;
-#ifdef FEATURE_CORECLR
// In CoreCLR, we always resume from the same thread that paused. So we can simply suspend the EE from this thread,
// knowing we'll restart from the same thread.
ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_OTHER);
-#else
- // In the CLR, we can resume from a different thread than the one that paused. We can't call SuspendEE directly,
- // because we can't call RestartEE from another thread. So we queue a workitem to the ThreadPool to call SuspendEE
- // and ResumeEE on our behalf.
-
- EX_TRY
- {
- if (!ThreadpoolMgr::QueueUserWorkItem(SuspendAndResumeForPause, NULL, QUEUE_ONLY))
- {
- hr = HRESULT_FROM_GetLastError();
- }
- else
- {
- // wait for SuspendEE to complete before returning.
- g_PauseCompletedEvent.Wait(INFINITE,FALSE);
- }
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-#endif
return hr;
}
@@ -2076,12 +1021,7 @@ HRESULT RestartEEFromPauseAndSetResumeEvent()
CONTRACTL_END;
// see comments in SuspendEEFromPause
-#ifdef FEATURE_CORECLR
ThreadSuspend::RestartEE(FALSE, TRUE);
-#else
- // setting the resume event below will restart the EE as well. We don't wait for the restart
- // to complete, because we'll sync with it next time we go to cooperative mode.
-#endif
_ASSERTE(g_ClrResumeEvent.IsValid());
g_ClrResumeEvent.Set();
@@ -2111,10 +1051,6 @@ HRESULT CorExecutionManager::Pause(DWORD dwAppDomainId, DWORD dwFlags)
HRESULT hr = S_OK;
-#ifndef FEATURE_CORECLR
- if (!IsRuntimeActive())
- return HOST_E_CLRNOTAVAILABLE;
-#endif
if(g_IsPaused)
return E_FAIL;
@@ -2126,12 +1062,6 @@ HRESULT CorExecutionManager::Pause(DWORD dwAppDomainId, DWORD dwFlags)
else
g_ClrResumeEvent.Reset();
-#ifndef FEATURE_CORECLR
- if (!g_PauseCompletedEvent.IsValid())
- g_PauseCompletedEvent.CreateManualEvent(FALSE);
- else
- g_PauseCompletedEvent.Reset();
-#endif
}
EX_CATCH_HRESULT(hr);
@@ -2142,20 +1072,6 @@ HRESULT CorExecutionManager::Pause(DWORD dwAppDomainId, DWORD dwFlags)
m_dwFlags = dwFlags;
-#ifndef FEATURE_CORECLR
- if ((m_dwFlags & PAUSE_APP_DOMAINS) != 0)
- {
- Thread* pThread = SetupThreadNoThrow(&hr);
- if (pThread != NULL)
- {
- GCX_COOP_THREAD_EXISTS(pThread);
-
- AppDomainIterator ai(/*bOnlyActive:*/ TRUE);
- while (ai.Next())
- PauseOneAppDomain(&ai);
- }
- }
-#endif
if (SUCCEEDED(hr))
{
@@ -2185,15 +1101,10 @@ HRESULT CorExecutionManager::Resume(DWORD dwAppDomainId)
HRESULT hr = S_OK;
-#ifndef FEATURE_CORECLR
- if (!IsRuntimeActive())
- return HOST_E_CLRNOTAVAILABLE;
-#endif
if(!g_IsPaused)
return E_FAIL;
-#ifdef FEATURE_CORECLR
// GCThread is the thread that did the Pause. Resume should also happen on that same thread
Thread *pThread = GetThread();
if(pThread != ThreadSuspend::GetSuspensionThread())
@@ -2201,7 +1112,6 @@ HRESULT CorExecutionManager::Resume(DWORD dwAppDomainId)
_ASSERTE(!"HOST BUG: The same thread that did Pause should do the Resume");
return E_FAIL;
}
-#endif
BEGIN_ENTRYPOINT_NOTHROW;
@@ -2215,23 +1125,6 @@ HRESULT CorExecutionManager::Resume(DWORD dwAppDomainId)
hr = RestartEEFromPauseAndSetResumeEvent();
-#ifndef FEATURE_CORECLR
- if (SUCCEEDED(hr))
- {
- if ((m_dwFlags & PAUSE_APP_DOMAINS) != 0)
- {
- Thread* pThread = SetupThreadNoThrow(&hr);
- if (pThread != NULL)
- {
- GCX_COOP_THREAD_EXISTS(pThread);
-
- AppDomainIterator ai(/*bOnlyActive:*/ TRUE);
- while (ai.Next())
- ResumeOneAppDomain(&ai);
- }
- }
- }
-#endif
END_ENTRYPOINT_NOTHROW;
@@ -2241,7 +1134,6 @@ HRESULT CorExecutionManager::Resume(DWORD dwAppDomainId)
#endif //!DACCESS_COMPILE
-#ifdef FEATURE_CORECLR
#ifndef DACCESS_COMPILE
SVAL_IMPL(STARTUP_FLAGS, CorHost2, m_dwStartupFlags = STARTUP_CONCURRENT_GC);
#else
@@ -2252,347 +1144,9 @@ STARTUP_FLAGS CorHost2::GetStartupFlags()
{
return m_dwStartupFlags;
}
-#endif //FEATURE_CORECLR
#ifndef DACCESS_COMPILE
-#if !defined(FEATURE_CORECLR)
-/*************************************************************************************
- ** ICLRPrivRuntime Methods
- *************************************************************************************/
-
-HRESULT CorHost2::GetInterface(
- REFCLSID rclsid,
- REFIID riid,
- LPVOID * ppUnk)
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- EX_TRY
- {
- if (rclsid == __uuidof(CLRPrivAppXBinder))
- {
- CLRPrivBinderAppX * pBinder = CLRPrivBinderAppX::GetOrCreateBinder();
- hr = pBinder->QueryInterface(riid, ppUnk);
- }
- else
- {
- hr = E_NOINTERFACE;
- }
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
-HRESULT CorHost2::CreateAppDomain(
- LPCWSTR pwzFriendlyName,
- ICLRPrivBinder * pBinder,
- LPDWORD pdwAppDomainId)
-{
- return _CreateAppDomain(
- pwzFriendlyName,
- 0 /* default security */,
- nullptr, /* domain manager */
- nullptr, /* domain manager */
- 0, /* property count */
- nullptr, /* property names */
- nullptr, /* property values */
- pBinder,
- pdwAppDomainId);
-}
-
-HRESULT CorHost2::CreateDelegate(
- DWORD appDomainID,
- LPCWSTR wszAssemblyName,
- LPCWSTR wszClassName,
- LPCWSTR wszMethodName,
- LPVOID * ppvDelegate)
-{
- return _CreateDelegate(appDomainID, wszAssemblyName, wszClassName,
- wszMethodName, reinterpret_cast<INT_PTR*>(ppvDelegate));
-}
-
-// Flag indicating if the EE was started up by an managed exe. Defined in ceemain.cpp.
-extern BOOL g_fEEManagedEXEStartup;
-
-HRESULT CorHost2::ExecuteMain(
- ICLRPrivBinder * pBinder,
- int * pRetVal)
-{
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_ENTRY_POINT;
-
- HRESULT hr = S_OK;
-
- // If an exception passes through here, it will cause the
- // "The application has generated an unhandled exception" dialog and offer to debug.
- BEGIN_ENTRYPOINT_THROWS;
-
- // Indicates that the EE was started up by a managed exe.
- g_fEEManagedEXEStartup = TRUE;
-
- IfFailGo(CorCommandLine::SetArgvW(WszGetCommandLine()));
-
- IfFailGo(EnsureEEStarted(COINITEE_MAIN));
-
- INSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
- //
- // Look for the [STAThread] or [MTAThread] attribute
- // TODO delete this code when we move to the default AppDomain
- //
- HMODULE hMod = WszGetModuleHandle(NULL);
-
- PEImageHolder pTempImage(PEImage::LoadImage(hMod));
- PEFileHolder pTempFile(PEFile::Open(pTempImage.Extract()));
-
- // Check for CustomAttributes - Set up the DefaultDomain and the main thread
- // Note that this has to be done before ExplicitBind() as it
- // affects the bind
- mdToken tkEntryPoint = pTempFile->GetEntryPointToken();
- // <TODO>@TODO: What if the entrypoint is in another file of the assembly?</TODO>
- ReleaseHolder<IMDInternalImport> scope(pTempFile->GetMDImportWithRef());
- // In theory, we should have a valid executable image and scope should never be NULL, but we've been
- // getting Watson failures for AVs here due to ISVs modifying image headers and some new OS loader
- // checks (see Dev10# 718530 and Windows 7# 615596)
- if (scope == NULL)
- {
- ThrowHR(COR_E_BADIMAGEFORMAT);
- }
-
- Thread::ApartmentState state = Thread::AS_Unknown;
-
- if((!IsNilToken(tkEntryPoint)) && (TypeFromToken(tkEntryPoint) == mdtMethodDef)) {
- if (scope->IsValidToken(tkEntryPoint))
- state = SystemDomain::GetEntryPointThreadAptState(scope, tkEntryPoint);
- else
- ThrowHR(COR_E_BADIMAGEFORMAT);
- }
-
- BOOL fSetGlobalSharePolicyUsingAttribute = FALSE;
-
- if((!IsNilToken(tkEntryPoint)) && (TypeFromToken(tkEntryPoint) == mdtMethodDef))
- {
- // The global share policy needs to be set before initializing default domain
- // so that it is in place for loading of appdomain manager.
- fSetGlobalSharePolicyUsingAttribute = SystemDomain::SetGlobalSharePolicyUsingAttribute(scope, tkEntryPoint);
- }
-
- // If the entry point has an explicit thread apartment state, set it
- // before running the AppDomainManager initialization code.
- if (state == Thread::AS_InSTA || state == Thread::AS_InMTA)
- SystemDomain::SetThreadAptState(scope, state);
-
- // This can potentially run managed code.
- SystemDomain::InitializeDefaultDomain(FALSE, pBinder);
-
- // If we haven't set an explicit thread apartment state, set it after the
- // AppDomainManager has got a chance to go set it in InitializeNewDomain.
- if (state != Thread::AS_InSTA && state != Thread::AS_InMTA)
- SystemDomain::SetThreadAptState(scope, state);
-
- if (fSetGlobalSharePolicyUsingAttribute)
- SystemDomain::System()->DefaultDomain()->SetupLoaderOptimization(g_dwGlobalSharePolicy);
-
- ADID adId(DefaultADID);
-
- GCX_COOP();
-
- ENTER_DOMAIN_ID(adId)
- TESTHOOKCALL(EnteredAppDomain(adId.m_dwId));
- {
- GCX_PREEMP();
-
- AppDomain *pDomain = GetAppDomain();
- _ASSERTE(pDomain);
-
- PathString wzExeFileName;
-
- if (WszGetModuleFileName(nullptr, wzExeFileName) == 0)
- IfFailThrow(E_UNEXPECTED);
-
- LPWSTR wzExeSimpleFileName = nullptr;
- size_t cchExeSimpleFileName = 0;
- SplitPathInterior(
- wzExeFileName,
- nullptr, nullptr, // drive
- nullptr, nullptr, // dir
- (LPCWSTR*)&wzExeSimpleFileName, &cchExeSimpleFileName, // filename
- nullptr, nullptr); // ext
-
- // Remove the extension
- wzExeSimpleFileName[cchExeSimpleFileName] = W('\0');
-
- ReleaseHolder<IAssemblyName> pAssemblyName;
- IfFailThrow(CreateAssemblyNameObject(
- &pAssemblyName, // Returned IAssemblyName
- wzExeSimpleFileName, // Name of assembly
- CANOF_PARSE_DISPLAY_NAME, // Parse as display name
- nullptr)); // Reserved
-
- AssemblySpec specExe;
- specExe.InitializeSpec(pAssemblyName, nullptr, false);
-
- PEAssemblyHolder pPEAssembly = pDomain->BindAssemblySpec(&specExe, TRUE, FALSE);
-
- pDomain->SetRootAssembly(pDomain->LoadAssembly(NULL, pPEAssembly, FILE_ACTIVE));
-
- LOG((LF_CLASSLOADER | LF_CORDB,
- LL_INFO10,
- "Created domain for an executable at %p\n",
- (pDomain->GetRootAssembly()? pDomain->GetRootAssembly()->Parent() : NULL)));
- TESTHOOKCALL(RuntimeStarted(RTS_CALLINGENTRYPOINT));
-
- // Set the friendly name to indicate that this is an immersive domain.
- pDomain->SetFriendlyName(W("Immersive Application Domain"), TRUE);
-
- // Execute the main method
- // NOTE: we call the entry point with our entry point exception filter active
- // after the AppDomain transition which is a bit different from classic apps.
- // this is so that we have the correct context when notifying the debugger
- // or invoking WER on the main thread and mimics the behavior of classic apps.
- // the assumption is that AppX entry points are always invoked post-AD transition.
- ExecuteMainInner(pDomain->GetRootAssembly());
-
- // Get the global latched exit code instead of the return value from ExecuteMainMethod
- // because in the case of a "void Main" method the return code is always 0,
- // while the latched exit code is set in either case.
- *pRetVal = GetLatchedExitCode();
- }
- END_DOMAIN_TRANSITION;
- TESTHOOKCALL(LeftAppDomain(adId.m_dwId));
-
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
-ErrExit:
- END_ENTRYPOINT_THROWS;
-
- return hr;
-}
-
-VOID CorHost2::ExecuteMainInner(Assembly* pRootAssembly)
-{
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_ENTRY_POINT;
-
- struct Param
- {
- Assembly* pRootAssembly;
- } param;
-
- param.pRootAssembly = pRootAssembly;
-
- PAL_TRY(Param*, pParam, &param)
- {
- // since this is the thread 0 entry point for AppX apps we use
- // the EntryPointFilter so that an unhandled exception here will
- // trigger the same behavior as in classic apps.
- pParam->pRootAssembly->ExecuteMainMethod(NULL, TRUE /* waitForOtherThreads */);
- }
- PAL_EXCEPT_FILTER(EntryPointFilter)
- {
- LOG((LF_STARTUP, LL_INFO10, "EntryPointFilter returned EXCEPTION_EXECUTE_HANDLER!"));
- }
- PAL_ENDTRY
-}
-
-// static
-HRESULT CorHost2::SetFlagsAndHostConfig(STARTUP_FLAGS dwStartupFlags, LPCWSTR pwzHostConfigFile, BOOL fFinalize)
-{
- WRAPPER_NO_CONTRACT;
-
- HRESULT hr = E_INVALIDARG;
-
- if (pwzHostConfigFile == NULL)
- pwzHostConfigFile = W("");
-
- DangerousNonHostedSpinLockHolder lockHolder(&m_FlagsLock);
-
- if (m_dwFlagsFinalized)
- {
- // verify that flags and config file are the same
- if (dwStartupFlags == m_dwStartupFlags &&
- _wcsicmp(pwzHostConfigFile, m_wzHostConfigFile) == 0)
- {
- hr = S_OK;
- }
- }
- else
- {
- // overwrite the flags and config with the incoming values
- if (wcslen(pwzHostConfigFile) < COUNTOF(m_wzHostConfigFile))
- {
- VERIFY(wcscpy_s(m_wzHostConfigFile, COUNTOF(m_wzHostConfigFile), pwzHostConfigFile) == 0);
-
- // If they asked for the server gc but only have one processor, deny that option.
- // Keep this in sync with shim logic in ComputeStartupFlagsAndFlavor that also switches to
- // the workstation GC on uniprocessor boxes.
- if (g_SystemInfo.dwNumberOfProcessors == 1 && (dwStartupFlags & STARTUP_SERVER_GC))
- dwStartupFlags = (STARTUP_FLAGS)(dwStartupFlags & ~(STARTUP_SERVER_GC | STARTUP_CONCURRENT_GC));
-
- m_dwStartupFlags = dwStartupFlags;
-
- if (fFinalize)
- m_dwFlagsFinalized = TRUE;
-
- hr = S_OK;
- }
- }
-
- return hr;
-}
-
-// static
-STARTUP_FLAGS CorHost2::GetStartupFlags()
-{
- WRAPPER_NO_CONTRACT;
-
- if (!m_dwFlagsFinalized) // make sure we return consistent results
- {
- DangerousNonHostedSpinLockHolder lockHolder(&m_FlagsLock);
- m_dwFlagsFinalized = TRUE;
- }
-
- return m_dwStartupFlags;
-}
-
-// static
-LPCWSTR CorHost2::GetHostConfigFile()
-{
- WRAPPER_NO_CONTRACT;
-
- if (!m_dwFlagsFinalized) // make sure we return consistent results
- {
- DangerousNonHostedSpinLockHolder lockHolder(&m_FlagsLock);
- m_dwFlagsFinalized = TRUE;
- }
-
- return m_wzHostConfigFile;
-}
-
-// static
-void CorHost2::GetDefaultAppDomainProperties(StringArrayList **pPropertyNames, StringArrayList **pPropertyValues)
-{
- LIMITED_METHOD_CONTRACT;
-
- // We should only read these after the runtime has started to ensure that the host isn't modifying them
- // still
- _ASSERTE(g_fEEStarted || HasStarted());
-
- *pPropertyNames = &s_defaultDomainPropertyNames;
- *pPropertyValues = &s_defaultDomainPropertyValues;
-}
-
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_COMINTEROP
@@ -2644,370 +1198,12 @@ HRESULT GetCLRRuntimeHost(REFIID riid, IUnknown **ppUnk)
return CorHost2::CreateObject(riid, (void**)ppUnk);
}
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
-
-HRESULT NextDomainWorker(AppDomainIterator *pEnum,
- IUnknown** pAppDomain)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW); // nothrow contract's fs:0 handler gets called before the C++ EH fs:0 handler which is pushed in the prolog
- GC_TRIGGERS;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- Thread *pThread = GetThread();
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(pThread, return COR_E_STACKOVERFLOW);
-
- EX_TRY
- {
- GCX_COOP_THREAD_EXISTS(pThread);
-
- if (pEnum->Next())
- {
- AppDomain* pDomain = pEnum->GetDomain();
- // Need to enter the AppDomain to synchronize access to the exposed
- // object properly (can't just take the system domain mutex since we
- // might need to run code that uses higher ranking crsts).
- ENTER_DOMAIN_PTR(pDomain,ADV_ITERATOR)
- {
-
- hr = pDomain->GetComIPForExposedObject(pAppDomain);
- }
- END_DOMAIN_TRANSITION;
- }
- else
- {
- hr = S_FALSE;
- }
- }
- EX_CATCH_HRESULT(hr);
-
- END_SO_INTOLERANT_CODE;
-
- return hr;
-}
-
-// Returns S_FALSE when there are no more domains. A domain
-// is passed out only when S_OK is returned.
-HRESULT CorRuntimeHostBase::NextDomain(HDOMAINENUM hEnum,
- IUnknown** pAppDomain)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- if(hEnum == NULL || pAppDomain == NULL)
- return E_POINTER;
-
- // If the runtime has not started, we have nothing to do.
- if (!g_fEEStarted)
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
-
- HRESULT hr;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- AppDomainIterator *pEnum = (AppDomainIterator *) hEnum;
-
- do
- {
- hr = NextDomainWorker(pEnum, pAppDomain);
- // Might need to look at the next appdomain if we were attempting to get at
- // the exposed appdomain object and were chucked out as the result of an
- // appdomain unload.
- } while (hr == COR_E_APPDOMAINUNLOADED);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-// Creates a domain in the runtime. The identity array is
-// a pointer to an array TYPE containing IIdentity objects defining
-// the security identity.
-HRESULT CorRuntimeHostBase::CreateDomainEx(LPCWSTR pwzFriendlyName,
- IUnknown* pSetup, // Optional
- IUnknown* pEvidence, // Optional
- IUnknown ** pAppDomain)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- if(!pwzFriendlyName) return E_POINTER;
- if(pAppDomain == NULL) return E_POINTER;
- if(!g_fEEStarted) return E_FAIL;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr);
- {
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
-
- struct _gc {
- STRINGREF pName;
- OBJECTREF pSetup;
- OBJECTREF pEvidence;
- APPDOMAINREF pDomain;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- if (FAILED(hr = EnsureComStartedNoThrow()))
- goto lDone;
-
- GCPROTECT_BEGIN(gc);
-
- gc.pName = StringObject::NewString(pwzFriendlyName);
-
- if(pSetup)
- GetObjectRefFromComIP(&gc.pSetup, pSetup);
- if(pEvidence)
- GetObjectRefFromComIP(&gc.pEvidence, pEvidence);
-
- MethodDescCallSite createDomain(METHOD__APP_DOMAIN__CREATE_DOMAIN);
-
- ARG_SLOT args[3] = {
- ObjToArgSlot(gc.pName),
- ObjToArgSlot(gc.pEvidence),
- ObjToArgSlot(gc.pSetup),
- };
-
- gc.pDomain = (APPDOMAINREF) createDomain.Call_RetOBJECTREF(args);
-
- *pAppDomain = GetComIPFromObjectRef((OBJECTREF*) &gc.pDomain);
-
- GCPROTECT_END();
-
-lDone: ;
- }
- END_EXTERNAL_ENTRYPOINT;
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-// Close the enumeration releasing resources
-HRESULT CorRuntimeHostBase::CloseEnum(HDOMAINENUM hEnum)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- if(hEnum) {
- AppDomainIterator* pEnum = (AppDomainIterator*) hEnum;
- delete pEnum;
- }
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-
-HRESULT CorRuntimeHostBase::CreateDomainSetup(IUnknown **pAppDomainSetup)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- ENTRY_POINT;
- MODE_PREEMPTIVE;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- if (!pAppDomainSetup)
- return E_POINTER;
-
- // If the runtime has not started, we have nothing to do.
- if (!g_fEEStarted)
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
-
- // Create the domain.
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr);
- {
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
-
- struct _gc {
- OBJECTREF pSetup;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
- MethodTable* pMT = NULL;
-
- hr = EnsureComStartedNoThrow();
- if (FAILED(hr))
- goto lDone;
-
- pMT = MscorlibBinder::GetClass(CLASS__APPDOMAIN_SETUP);
-
- GCPROTECT_BEGIN(gc);
- gc.pSetup = AllocateObject(pMT);
- *pAppDomainSetup = GetComIPFromObjectRef((OBJECTREF*) &gc.pSetup);
- GCPROTECT_END();
-
-lDone: ;
- }
- END_EXTERNAL_ENTRYPOINT;
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-HRESULT CorRuntimeHostBase::CreateEvidence(IUnknown **pEvidence)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- if (!pEvidence)
- return E_POINTER;
-
-#ifdef FEATURE_CAS_POLICY
-
- // If the runtime has not started, we have nothing to do.
- if (!g_fEEStarted)
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
-
- // Create the domain.
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr);
- {
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
-
- struct _gc {
- OBJECTREF pEvidence;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- MethodTable* pMT = NULL;
-
- hr = EnsureComStartedNoThrow();
- if (FAILED(hr))
- goto lDone;
-
- pMT = MscorlibBinder::GetClass(CLASS__EVIDENCE);
-
- GCPROTECT_BEGIN(gc);
- gc.pEvidence = AllocateObject(pMT);
- MethodDescCallSite ctor(METHOD__EVIDENCE__CTOR, &(gc.pEvidence));
-
- // Call the Evidence class constructor.
- ARG_SLOT CtorArgs[] =
- {
- ObjToArgSlot(gc.pEvidence)
- };
- ctor.Call(CtorArgs);
-
- *pEvidence = GetComIPFromObjectRef((OBJECTREF*) &gc.pEvidence);
- GCPROTECT_END();
-
-lDone: ;
- }
- END_EXTERNAL_ENTRYPOINT;
- END_ENTRYPOINT_NOTHROW;
-#else // !FEATURE_CAS_POLICY
- // There is no Evidence class support without CAS policy.
- return E_NOTIMPL;
-#endif // FEATURE_CAS_POLICY
-
- return hr;
-}
-
-HRESULT CorRuntimeHostBase::UnloadDomain(IUnknown *pUnkDomain)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- FORBID_FAULT;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- if (!pUnkDomain)
- return E_POINTER;
-
- // If the runtime has not started, we have nothing to do.
- if (!g_fEEStarted)
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
-
- CONTRACT_VIOLATION(FaultViolation); // This entire function is full of OOM potential: must fix.
-
- HRESULT hr = S_OK;
- DWORD dwDomainId = 0;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- _ASSERTE (g_fComStarted);
-
- {
- SystemDomain::LockHolder lh;
-
- ComCallWrapper* pWrap = GetCCWFromIUnknown(pUnkDomain, FALSE);
- if (!pWrap)
- {
- hr = COR_E_APPDOMAINUNLOADED;
- }
- if (SUCCEEDED(hr))
- {
- dwDomainId = pWrap->GetDomainID().m_dwId;
- }
- }
- if (SUCCEEDED(hr))
- {
- hr = UnloadAppDomain(dwDomainId, TRUE);
- }
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-#endif // FEATURE_COMINTEROP && !FEATURE_CORECLR
STDMETHODIMP CorHost2::UnloadAppDomain(DWORD dwDomainId, BOOL fWaitUntilDone)
{
WRAPPER_NO_CONTRACT;
STATIC_CONTRACT_SO_TOLERANT;
-#ifdef FEATURE_CORECLR
if (!m_fStarted)
return HOST_E_INVALIDOPERATION;
@@ -3056,7 +1252,6 @@ STDMETHODIMP CorHost2::UnloadAppDomain(DWORD dwDomainId, BOOL fWaitUntilDone)
return hr;
}
else
-#endif // FEATURE_CORECLR
return CorRuntimeHostBase::UnloadAppDomain(dwDomainId, fWaitUntilDone);
}
@@ -3093,9 +1288,7 @@ HRESULT CorRuntimeHostBase::UnloadAppDomain(DWORD dwDomainId, BOOL fSync)
// for this scope only.
CONTRACT_VIOLATION(FaultViolation);
if (!IsRuntimeActive()
- #ifdef FEATURE_CORECLR
|| !m_fStarted
- #endif // FEATURE_CORECLR
)
{
return HOST_E_CLRNOTAVAILABLE;
@@ -3117,126 +1310,6 @@ HRESULT CorRuntimeHostBase::UnloadAppDomain(DWORD dwDomainId, BOOL fSync)
//*****************************************************************************
// Fiber Methods
//*****************************************************************************
-#if !defined(FEATURE_CORECLR) // simple hosting
-HRESULT CorHost::CreateLogicalThreadState()
-{
- CONTRACTL
- {
- NOTHROW;
- DISABLED(GC_TRIGGERS);
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
- if (CorHost::GetHostVersion() != 1)
- {
- hr=HOST_E_INVALIDOPERATION;
- }
- else
- {
- _ASSERTE (GetThread() == 0 || GetThread()->HasRightCacheStackBase());
- /* Thread *thread = */ SetupThreadNoThrow(&hr);
-
- }
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-
-HRESULT CorHost::DeleteLogicalThreadState()
-{
- if (CorHost::GetHostVersion() != 1)
- {
- return HOST_E_INVALIDOPERATION;
- }
-
- Thread *pThread = GetThread();
- if (!pThread)
- return E_UNEXPECTED;
-
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- ENTRY_POINT;
- }
- CONTRACTL_END;
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
- // We need to reset the TrapReturningThread count that was
- // set when a thread is requested to be aborted. Otherwise
- // every stub call is going to go through a slow path.
- if (pThread->IsAbortRequested())
- pThread->UnmarkThreadForAbort(Thread::TAR_ALL);
-
- // see code:Thread::OnThreadTerminate#ReportDeadOnThreadTerminate
- pThread->SetThreadState(Thread::TS_ReportDead);
-
- pThread->OnThreadTerminate(FALSE);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-
-HRESULT CorHost::SwitchInLogicalThreadState(DWORD *pFiberCookie)
-{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_NOTRIGGER;
- STATIC_CONTRACT_MODE_ANY;
- STATIC_CONTRACT_ENTRY_POINT;
-
- if (CorHost::GetHostVersion() != 1)
- {
- return HOST_E_INVALIDOPERATION;
- }
-
- if (!pFiberCookie)
- {
- return E_POINTER;
- }
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- hr = ((Thread*)pFiberCookie)->SwitchIn(::GetCurrentThread());
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
-
-}
-
-HRESULT CorHost::SwitchOutLogicalThreadState(DWORD **pFiberCookie)
-{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_NOTRIGGER;
- STATIC_CONTRACT_MODE_ANY;
- STATIC_CONTRACT_ENTRY_POINT;
-
- if (CorHost::GetHostVersion() != 1)
- {
- return HOST_E_INVALIDOPERATION;
- }
-
- if (!pFiberCookie)
- {
- return E_POINTER;
- }
-
- Thread *pThread = GetThread();
- if (!pThread)
- {
- return E_UNEXPECTED;
- }
-
- pThread->InternalSwitchOut();
- *pFiberCookie = (DWORD*)pThread;
-
- return S_OK;
-}
-#endif // !defined(FEATURE_CORECLR)
HRESULT CorRuntimeHostBase::LocksHeldByLogicalThread(DWORD *pCount)
{
@@ -3267,242 +1340,6 @@ HRESULT CorRuntimeHostBase::LocksHeldByLogicalThread(DWORD *pCount)
//*****************************************************************************
// ICorConfiguration
//*****************************************************************************
-#if !defined(FEATURE_CORECLR)
-IGCThreadControl *CorConfiguration::m_CachedGCThreadControl = 0;
-IGCHostControl *CorConfiguration::m_CachedGCHostControl = 0;
-IDebuggerThreadControl *CorConfiguration::m_CachedDebuggerThreadControl = 0;
-DWORD *CorConfiguration::m_DSTArray = 0;
-DWORD CorConfiguration::m_DSTCount = 0;
-DWORD CorConfiguration::m_DSTArraySize = 0;
-
-// *** ICorConfiguration methods ***
-
-
-HRESULT CorConfiguration::SetGCThreadControl(IGCThreadControl *pGCThreadControl)
-{
- if (!pGCThreadControl)
- return E_POINTER;
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- if (m_CachedGCThreadControl)
- m_CachedGCThreadControl->Release();
-
- m_CachedGCThreadControl = pGCThreadControl;
-
- if (m_CachedGCThreadControl)
- m_CachedGCThreadControl->AddRef();
-
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
-}
-
-HRESULT CorConfiguration::SetGCHostControl(IGCHostControl *pGCHostControl)
-{
- if (!pGCHostControl)
- return E_POINTER;
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- if (m_CachedGCHostControl)
- m_CachedGCHostControl->Release();
-
- m_CachedGCHostControl = pGCHostControl;
-
- if (m_CachedGCHostControl)
- m_CachedGCHostControl->AddRef();
-
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
-}
-
-HRESULT CorConfiguration::SetDebuggerThreadControl(IDebuggerThreadControl *pDebuggerThreadControl)
-{
- if (!pDebuggerThreadControl)
- return E_POINTER;
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
-#ifdef DEBUGGING_SUPPORTED
- // Can't change the debugger thread control object once its been set.
- if (m_CachedDebuggerThreadControl != NULL)
- IfFailGo(E_INVALIDARG);
-
- m_CachedDebuggerThreadControl = pDebuggerThreadControl;
-
- // If debugging is already initialized then provide this interface pointer to it.
- // It will also addref the new one and release the old one.
- if (g_pDebugInterface)
- g_pDebugInterface->SetIDbgThreadControl(pDebuggerThreadControl);
-
- if (m_CachedDebuggerThreadControl)
- m_CachedDebuggerThreadControl->AddRef();
-
- hr = S_OK;
-#else // !DEBUGGING_SUPPORTED
- hr = E_NOTIMPL;
-#endif // !DEBUGGING_SUPPORTED
-
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
- return hr;
-
-}
-
-
-HRESULT CorConfiguration::AddDebuggerSpecialThread(DWORD dwSpecialThreadId)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT; // debugging not hardened for SO
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
-
-#ifdef DEBUGGING_SUPPORTED
- // If it's already in the list, don't add it again.
- if (IsDebuggerSpecialThread(dwSpecialThreadId))
- {
- hr = S_OK;
- goto ErrExit;
- }
- // Grow the array if necessary.
- if (m_DSTCount >= m_DSTArraySize)
- {
- // There's probably only ever gonna be one or two of these
- // things, so we'll start small.
- DWORD newSize = (m_DSTArraySize == 0) ? 2 : m_DSTArraySize * 2;
-
- DWORD *newArray = new (nothrow) DWORD[newSize];
- IfNullGo(newArray);
-
- // If we're growing instead of starting, then copy the old array.
- if (m_DSTArray)
- {
- memcpy(newArray, m_DSTArray, m_DSTArraySize * sizeof(DWORD));
- delete [] m_DSTArray;
- }
-
- // Update to the new array and size.
- m_DSTArray = newArray;
- m_DSTArraySize = newSize;
- }
-
- // Save the new thread ID.
- m_DSTArray[m_DSTCount++] = dwSpecialThreadId;
-
- hr = (RefreshDebuggerSpecialThreadList());
-#else // !DEBUGGING_SUPPORTED
- hr = E_NOTIMPL;
-#endif // !DEBUGGING_SUPPORTED
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
- return hr;
-
-}
-// Helper function to update the thread list in the debugger control block
-HRESULT CorConfiguration::RefreshDebuggerSpecialThreadList()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
-#ifdef DEBUGGING_SUPPORTED
- HRESULT hr = S_OK;
-
- if (g_pDebugInterface)
- {
- // Inform the debugger services that this list has changed
- hr = g_pDebugInterface->UpdateSpecialThreadList(
- m_DSTCount, m_DSTArray);
-
- _ASSERTE(SUCCEEDED(hr));
- }
-
- return (hr);
-#else // !DEBUGGING_SUPPORTED
- return E_NOTIMPL;
-#endif // !DEBUGGING_SUPPORTED
-}
-
-
-// Helper func that returns true if the thread is in the debugger special thread list
-BOOL CorConfiguration::IsDebuggerSpecialThread(DWORD dwThreadId)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- for (DWORD i = 0; i < m_DSTCount; i++)
- {
- if (m_DSTArray[i] == dwThreadId)
- return (TRUE);
- }
-
- return (FALSE);
-}
-
-
-// Clean up any debugger thread control object we may be holding, called at shutdown.
-void CorConfiguration::CleanupDebuggerThreadControl()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- if (m_CachedDebuggerThreadControl != NULL)
- {
- // Note: we don't release the IDebuggerThreadControl object if we're cleaning up from
- // our DllMain. The DLL that implements the object may already have been unloaded.
- // Leaking the object is okay... the PDM doesn't care.
- if (!IsAtProcessExit())
- m_CachedDebuggerThreadControl->Release();
-
- m_CachedDebuggerThreadControl = NULL;
- }
-}
-#endif // !defined(FEATURE_CORECLR)
//*****************************************************************************
// IUnknown
@@ -3520,20 +1357,6 @@ ULONG CorRuntimeHostBase::AddRef()
return InterlockedIncrement(&m_cRef);
}
-#if !defined(FEATURE_CORECLR) // simple hosting
-ULONG CorHost::Release()
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
-
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (!cRef) {
- delete this;
- }
-
- return (cRef);
-}
-#endif // !defined(FEATURE_CORECLR)
ULONG CorHost2::Release()
{
@@ -3541,72 +1364,12 @@ ULONG CorHost2::Release()
ULONG cRef = InterlockedDecrement(&m_cRef);
if (!cRef) {
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- // CorHost2 is allocated before host memory interface is set up.
- if (GetHostMemoryManager() == NULL)
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
delete this;
}
return (cRef);
}
-#if !defined(FEATURE_CORECLR) // simple hosting
-HRESULT CorHost::QueryInterface(REFIID riid, void **ppUnk)
-{
- if (!ppUnk)
- return E_POINTER;
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT; // no global state updates that need guarding.
- }
- CONTRACTL_END;
-
- if (ppUnk == NULL)
- {
- return E_POINTER;
- }
-
- *ppUnk = 0;
-
- // Deliberately do NOT hand out ICorConfiguration. They must explicitly call
- // GetConfiguration to obtain that interface.
- if (riid == IID_IUnknown)
- *ppUnk = (IUnknown *) (ICorRuntimeHost *) this;
- else if (riid == IID_ICorRuntimeHost)
- {
- ULONG version = 1;
- if (m_Version == 0)
- FastInterlockCompareExchange((LONG*)&m_Version, version, 0);
-
- if (m_Version != version && (g_singleVersionHosting || !g_fEEStarted))
- {
- return HOST_E_INVALIDOPERATION;
- }
-
- *ppUnk = (ICorRuntimeHost *) this;
- }
- else if (riid == IID_ICorThreadpool)
- *ppUnk = (ICorThreadpool *) this;
- else if (riid == IID_IGCHost)
- *ppUnk = (IGCHost *) this;
- else if (riid == IID_IGCHost2)
- *ppUnk = (IGCHost2 *) this;
- else if (riid == IID_IValidator)
- *ppUnk = (IValidator *) this;
- else if (riid == IID_IDebuggerInfo)
- *ppUnk = (IDebuggerInfo *) this;
- else if (riid == IID_ICLRExecutionManager)
- *ppUnk = (ICLRExecutionManager *) this;
- else
- return (E_NOINTERFACE);
- AddRef();
- return (S_OK);
-}
-#endif // !defined(FEATURE_CORECLR)
HRESULT CorHost2::QueryInterface(REFIID riid, void **ppUnk)
@@ -3633,7 +1396,6 @@ HRESULT CorHost2::QueryInterface(REFIID riid, void **ppUnk)
// GetConfiguration to obtain that interface.
if (riid == IID_IUnknown)
*ppUnk = static_cast<IUnknown *>(static_cast<ICLRRuntimeHost *>(this));
-#ifdef FEATURE_CORECLR // CoreCLR only supports IID_ICLRRuntimeHost2
else if (riid == IID_ICLRRuntimeHost2)
{
ULONG version = 2;
@@ -3642,16 +1404,6 @@ HRESULT CorHost2::QueryInterface(REFIID riid, void **ppUnk)
*ppUnk = static_cast<ICLRRuntimeHost2 *>(this);
}
-#else // DesktopCLR only supports IID_ICLRRuntimeHost
- else if (riid == IID_ICLRRuntimeHost)
- {
- ULONG version = 2;
- if (m_Version == 0)
- FastInterlockCompareExchange((LONG*)&m_Version, version, 0);
-
- *ppUnk = static_cast<ICLRRuntimeHost *>(this);
- }
-#endif // FEATURE_CORECLR
else if (riid == IID_ICLRExecutionManager)
{
ULONG version = 2;
@@ -3660,79 +1412,18 @@ HRESULT CorHost2::QueryInterface(REFIID riid, void **ppUnk)
*ppUnk = static_cast<ICLRExecutionManager *>(this);
}
-#if !defined(FEATURE_CORECLR)
- else if (riid == __uuidof(ICLRPrivRuntime))
- {
- ULONG version = 2;
- if (m_Version == 0)
- FastInterlockCompareExchange((LONG*)&m_Version, version, 0);
-
- *ppUnk = static_cast<ICLRPrivRuntime *>(this);
- }
-#endif
#ifndef FEATURE_PAL
else if (riid == IID_IPrivateManagedExceptionReporting)
{
*ppUnk = static_cast<IPrivateManagedExceptionReporting *>(this);
}
#endif // !FEATURE_PAL
-#ifndef FEATURE_CORECLR
- else if (riid == IID_ICorThreadpool)
- *ppUnk = static_cast<ICorThreadpool *>(this);
- // TODO: wwl Remove this after SQL uses new interface.
- else if (riid == IID_IGCHost &&
- GetHostVersion() == 3)
- *ppUnk = static_cast<IGCHost *>(this);
- else if (riid == IID_ICLRValidator)
- *ppUnk = static_cast<ICLRValidator *>(this);
- else if (riid == IID_IDebuggerInfo)
- *ppUnk = static_cast<IDebuggerInfo *>(this);
-#ifdef FEATURE_TESTHOOKS
- else if (riid == IID_ICLRTestHookManager)
- {
- *ppUnk=CLRTestHookManager::Start();
- if(*ppUnk==NULL)
- return E_OUTOFMEMORY;
- }
-#endif // FEATURE_TESTHOOKS
-#endif // FEATURE_CORECLR
else
return (E_NOINTERFACE);
AddRef();
return (S_OK);
}
-#ifndef FEATURE_CORECLR // CorHost isn't exposed externally
-//*****************************************************************************
-// Called by the class factory template to create a new instance of this object.
-//*****************************************************************************
-HRESULT CorHost::CreateObject(REFIID riid, void **ppUnk)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- CorHost *pCorHost = new (nothrow) CorHost();
- if (!pCorHost)
- {
- hr = E_OUTOFMEMORY;
- }
- else
- {
- hr = pCorHost->QueryInterface(riid, ppUnk);
-
- if (FAILED(hr))
- delete pCorHost;
- }
- return (hr);
-}
-#endif // FEATURE_CORECLR
#ifndef FEATURE_PAL
HRESULT CorHost2::GetBucketParametersForCurrentException(BucketParameters *pParams)
@@ -3849,34 +1540,6 @@ HRESULT CorRuntimeHostBase::MapFile(HANDLE hFile, HMODULE* phHandle)
///////////////////////////////////////////////////////////////////////////////
// IDebuggerInfo::IsDebuggerAttached
-#if !defined(FEATURE_CORECLR)
-HRESULT CorDebuggerInfo::IsDebuggerAttached(BOOL *pbAttached)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- if (pbAttached == NULL)
- hr = E_INVALIDARG;
- else
-#ifdef DEBUGGING_SUPPORTED
- *pbAttached = (CORDebuggerAttached() != 0);
-#else
- *pbAttached = FALSE;
-#endif
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-#endif // !defined(FEATURE_CORECLR)
LONG CorHost2::m_RefCount = 0;
@@ -3886,440 +1549,6 @@ LPCWSTR CorHost2::s_wszAppDomainManagerAsm = NULL;
LPCWSTR CorHost2::s_wszAppDomainManagerType = NULL;
EInitializeNewDomainFlags CorHost2::s_dwDomainManagerInitFlags = eInitializeNewDomainFlags_None;
-#ifndef FEATURE_CORECLR // not supported
-
-StringArrayList CorHost2::s_defaultDomainPropertyNames;
-StringArrayList CorHost2::s_defaultDomainPropertyValues;
-
-IHostMemoryManager *CorHost2::m_HostMemoryManager = NULL;
-IHostMalloc *CorHost2::m_HostMalloc = NULL;
-IHostTaskManager *CorHost2::m_HostTaskManager = NULL;
-IHostThreadpoolManager *CorHost2::m_HostThreadpoolManager = NULL;
-IHostIoCompletionManager *CorHost2::m_HostIoCompletionManager = NULL;
-IHostSyncManager *CorHost2::m_HostSyncManager = NULL;
-IHostAssemblyManager *CorHost2::m_HostAssemblyManager = NULL;
-IHostGCManager *CorHost2::m_HostGCManager = NULL;
-IHostSecurityManager *CorHost2::m_HostSecurityManager = NULL;
-IHostPolicyManager *CorHost2::m_HostPolicyManager = NULL;
-int CorHost2::m_HostOverlappedExtensionSize = -1;
-
-STARTUP_FLAGS CorHost2::m_dwStartupFlags = STARTUP_CONCURRENT_GC;
-WCHAR CorHost2::m_wzHostConfigFile[_MAX_PATH] = { 0 };
-
-BOOL CorHost2::m_dwFlagsFinalized = FALSE;
-DangerousNonHostedSpinLock CorHost2::m_FlagsLock;
-
-class CCLRMemoryNotificationCallback: public ICLRMemoryNotificationCallback
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE OnMemoryNotification(EMemoryAvailable eMemoryAvailable) {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- // We have not started runtime yet.
- if (!g_fEEStarted)
- return S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- switch (eMemoryAvailable)
- {
- case eMemoryAvailableLow:
- STRESS_LOG0(LF_GC, LL_INFO100, "Host delivers memory notification: Low\n");
- break;
- case eMemoryAvailableNeutral:
- STRESS_LOG0(LF_GC, LL_INFO100, "Host delivers memory notification: Neutral\n");
- break;
- case eMemoryAvailableHigh:
- STRESS_LOG0(LF_GC, LL_INFO100, "Host delivers memory notification: High\n");
- break;
- }
- static DWORD lastTime = (DWORD)-1;
- if (eMemoryAvailable == eMemoryAvailableLow)
- {
- FastInterlockIncrement ((LONG *)&g_bLowMemoryFromHost);
- DWORD curTime = GetTickCount();
- if (curTime < lastTime || curTime - lastTime >= 0x2000)
- {
- lastTime = curTime;
- FinalizerThread::EnableFinalization();
- }
- }
- else
- {
- FastInterlockExchange ((LONG *)&g_bLowMemoryFromHost, FALSE);
- }
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
- }
-
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
- {
- LIMITED_METHOD_CONTRACT;
- if (riid != IID_ICLRMemoryNotificationCallback && riid != IID_IUnknown)
- return (E_NOINTERFACE);
- *ppvObject = this;
- return S_OK;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-};
-
-static CCLRMemoryNotificationCallback s_MemoryNotification;
-
-class CLRTaskManager : public ICLRTaskManager
-{
-public:
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) {
- LIMITED_METHOD_CONTRACT;
- if (riid != IID_ICLRTaskManager && riid != IID_IUnknown)
- return (E_NOINTERFACE);
- *ppvObject = this;
- return S_OK;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- virtual HRESULT STDMETHODCALLTYPE CreateTask(ICLRTask **pTask)
- {
- CONTRACTL
- {
- NOTHROW;
- DISABLED(GC_NOTRIGGER);
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
-#ifdef _DEBUG
- _ASSERTE (!CLRTaskHosted() || GetCurrentHostTask());
-#endif
- _ASSERTE (GetThread() == NULL);
- Thread *pThread = NULL;
- pThread = SetupThreadNoThrow(&hr);
- *pTask = pThread;
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
- }
-
- virtual HRESULT STDMETHODCALLTYPE GetCurrentTask(ICLRTask **pTask)
- {
- // This function may be called due SQL SwitchIn/Out. Contract may
- // force memory allocation which is not allowed during Switch.
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_NOTRIGGER;
- STATIC_CONTRACT_SO_TOLERANT;
- STATIC_CONTRACT_ENTRY_POINT;
-
- *pTask = GetThread();
- return S_OK;
- }
-
- virtual HRESULT STDMETHODCALLTYPE SetUILocale(LCID lcid)
- {
- Thread *pThread = GetThread();
- if (pThread == NULL)
- return HOST_E_INVALIDOPERATION;
-
- CONTRACTL
- {
- GC_TRIGGERS;
- NOTHROW;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- //BEGIN_ENTRYPOINT_NOTHROW;
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
- {
- pThread->SetCultureId(lcid,TRUE);
- }
- END_EXTERNAL_ENTRYPOINT;
- //END_ENTRYPOINT_NOTHROW;
-
- return hr;
- }
-
- virtual HRESULT STDMETHODCALLTYPE SetLocale(LCID lcid)
- {
- Thread *pThread = GetThread();
- if (pThread == NULL)
- return HOST_E_INVALIDOPERATION;
-
- CONTRACTL
- {
- GC_TRIGGERS;
- NOTHROW;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- //BEGIN_ENTRYPOINT_NOTHROW;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
- {
- pThread->SetCultureId(lcid,FALSE);
- }
- END_EXTERNAL_ENTRYPOINT;
- //END_ENTRYPOINT_NOTHROW;
- return hr;
- }
-
- virtual HRESULT STDMETHODCALLTYPE GetCurrentTaskType(ETaskType *pTaskType)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- BEGIN_ENTRYPOINT_NOTHROW;
- *pTaskType = ::GetCurrentTaskType();
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
- }
-};
-
-static CLRTaskManager s_CLRTaskManager;
-
-class CLRSyncManager : public ICLRSyncManager
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE GetMonitorOwner(SIZE_T Cookie,
- IHostTask **ppOwnerHostTask)
- {
- CONTRACTL
- {
- NOTHROW;
- MODE_PREEMPTIVE;
- GC_NOTRIGGER;
- ENTRY_POINT;;
- }
- CONTRACTL_END;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- // Cookie is the SyncBlock
- // <TODO>TODO: Lifetime of Cookie?</TODO>
- AwareLock* pAwareLock = (AwareLock*)Cookie;
- IHostTask *pTask = NULL;
- Thread *pThread = pAwareLock->GetOwningThread();
- if (pThread)
- {
- ThreadStoreLockHolder tsLock;
- pThread = pAwareLock->GetOwningThread();
- if (pThread)
- {
- // See if the lock is orphaned, and the Thread object has been deleted
- Thread *pWalk = NULL;
- while ((pWalk = ThreadStore::GetAllThreadList(pWalk, 0, 0)) != NULL)
- {
- if (pWalk == pThread)
- {
- pTask = pThread->GetHostTaskWithAddRef();
- break;
- }
- }
- }
- }
-
- *ppOwnerHostTask = pTask;
-
- END_ENTRYPOINT_NOTHROW;
-
-
- return S_OK;
- }
- virtual HRESULT STDMETHODCALLTYPE CreateRWLockOwnerIterator(SIZE_T Cookie,
- SIZE_T *pIterator) {
- Thread *pThread = GetThread();
-
- // We may open a window for GC here.
- // A host should not hijack a coop thread to do deadlock detection.
- if (pThread && pThread->PreemptiveGCDisabled())
- return HOST_E_INVALIDOPERATION;
-
- CONTRACTL
- {
- NOTHROW;
- MODE_PREEMPTIVE;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = E_FAIL;
-
-#ifdef FEATURE_RWLOCK
- BEGIN_ENTRYPOINT_NOTHROW;
- ThreadStoreLockHolder tsLock;
- // Cookie is a weak handle. We need to make sure that the object is not moving.
- CRWLock *pRWLock = *(CRWLock **) Cookie;
- *pIterator = NULL;
- if (pRWLock == NULL)
- {
- hr = S_OK;
- }
- else
- {
- hr = pRWLock->CreateOwnerIterator(pIterator);
- }
- END_ENTRYPOINT_NOTHROW;
-#endif // FEATURE_RWLOCK
-
- return hr;
- }
-
- virtual HRESULT STDMETHODCALLTYPE GetRWLockOwnerNext(SIZE_T Iterator,
- IHostTask **ppOwnerHostTask)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
-#ifdef FEATURE_RWLOCK
- BEGIN_ENTRYPOINT_NOTHROW;
- CRWLock::GetNextOwner(Iterator,ppOwnerHostTask);
- END_ENTRYPOINT_NOTHROW;
-#endif // FEATURE_RWLOCK
-
- return S_OK;
- }
-
- virtual HRESULT STDMETHODCALLTYPE DeleteRWLockOwnerIterator(SIZE_T Iterator)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
-#ifdef FEATURE_RWLOCK
- BEGIN_ENTRYPOINT_NOTHROW;
- CRWLock::DeleteOwnerIterator(Iterator);
- END_ENTRYPOINT_NOTHROW;
-#endif // FEATURE_RWLOCK
-
- return S_OK;
- }
-
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
- {
- LIMITED_METHOD_CONTRACT;
- if (riid != IID_ICLRSyncManager && riid != IID_IUnknown)
- return (E_NOINTERFACE);
- *ppvObject = this;
- return S_OK;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-};
-
-static CLRSyncManager s_CLRSyncManager;
-
-extern void HostIOCompletionCallback(DWORD ErrorCode,
- DWORD numBytesTransferred,
- LPOVERLAPPED lpOverlapped);
-class CCLRIoCompletionManager :public ICLRIoCompletionManager
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE OnComplete(DWORD dwErrorCode,
- DWORD NumberOfBytesTransferred,
- void* pvOverlapped)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_ENTRY_POINT;
-
- if (pvOverlapped)
- {
- BEGIN_ENTRYPOINT_NOTHROW;
- HostIOCompletionCallback (dwErrorCode, NumberOfBytesTransferred, (LPOVERLAPPED)pvOverlapped);
- END_ENTRYPOINT_NOTHROW;
- }
-
- return S_OK;
- }
-
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- STATIC_CONTRACT_SO_TOLERANT;
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- STATIC_CONTRACT_SO_TOLERANT;
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
- BEGIN_INTERFACE HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
- {
- STATIC_CONTRACT_SO_TOLERANT;
- LIMITED_METHOD_CONTRACT;
- if (riid != IID_ICLRIoCompletionManager && riid != IID_IUnknown)
- return (E_NOINTERFACE);
- *ppvObject = this;
- return S_OK;
- }
-};
-
-static CCLRIoCompletionManager s_CLRIoCompletionManager;
-#endif // FEATURE_CORECLR
#ifdef _DEBUG
extern void ValidateHostInterface();
@@ -4327,19 +1556,11 @@ extern void ValidateHostInterface();
// fusion's global copy of host assembly manager stuff
BOOL g_bFusionHosted = FALSE;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-ICLRAssemblyReferenceList *g_pHostAsmList = NULL;
-IHostAssemblyStore *g_pHostAssemblyStore = NULL;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
/*static*/ BOOL CorHost2::IsLoadFromBlocked() // LoadFrom, LoadFile and Load(byte[]) are blocked in certain hosting scenarios
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- return (g_bFusionHosted && (g_pHostAsmList != NULL));
-#else // !FEATURE_INCLUDE_ALL_INTERFACES
return FALSE; // as g_pHostAsmList is not defined for CoreCLR; hence above expression will be FALSE.
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
static Volatile<BOOL> fOneOnly = 0;
@@ -4375,181 +1596,9 @@ HRESULT CorHost2::SetHostControl(IHostControl* pHostControl)
while (FastInterlockExchange((LONG*)&fOneOnly, 1) == 1)
{
- #ifndef FEATURE_CORECLR
- if (m_HostTaskManager != NULL)
- {
- m_HostTaskManager->SwitchToTask(0);
- }
- else
- {
- IHostTaskManager *pHostTaskManager = NULL;
- if (pHostControl->GetHostManager(IID_IHostTaskManager, (void**)&pHostTaskManager) == S_OK &&
- pHostTaskManager != NULL)
- {
- pHostTaskManager->SwitchToTask(0);
- pHostTaskManager->Release();
- }
- else
- {
- __SwitchToThread(0, ++dwSwitchCount);
- }
- }
- #else
__SwitchToThread(0, ++dwSwitchCount);
- #endif // FEATURE_CORECLR
}
-#ifndef FEATURE_CORECLR
-
-#ifdef _DEBUG
- ValidateHostInterface();
-#endif
-
-#ifdef _DEBUG
- DWORD dbg_HostManagerConfig = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_HostManagerConfig);
-#endif
-
- IHostMemoryManager *memoryManager = NULL;
- IHostTaskManager *taskManager = NULL;
- IHostThreadpoolManager *threadpoolManager = NULL;
- IHostIoCompletionManager *ioCompletionManager = NULL;
- IHostSyncManager *syncManager = NULL;
- IHostAssemblyManager *assemblyManager = NULL;
- IHostGCManager *gcManager = NULL;
- IHostSecurityManager *securityManager = NULL;
- IHostPolicyManager *policyManager = NULL;
-
- if (m_HostMemoryManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRMEMORYHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostMemoryManager,(void**)&memoryManager) == S_OK &&
- memoryManager != NULL) {
- if (m_HostMalloc == NULL)
- {
- hr = memoryManager->CreateMalloc (MALLOC_THREADSAFE, &m_HostMalloc);
- if (hr == S_OK)
- {
- memoryManager->RegisterMemoryNotificationCallback(&s_MemoryNotification);
- }
- else
- {
- memoryManager->Release();
- IfFailGo(E_UNEXPECTED);
- }
- }
- m_HostMemoryManager = memoryManager;
- g_fHostConfig |= CLRMEMORYHOSTED;
- }
-
- if (m_HostTaskManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRTASKHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostTaskManager,(void**)&taskManager) == S_OK &&
- taskManager != NULL) {
-#ifdef _TARGET_ARM_ // @ARMTODO: re-enable once we support hosted p/invokes.
- IfFailGo(E_NOTIMPL);
-#endif
- m_HostTaskManager = taskManager;
- m_HostTaskManager->SetCLRTaskManager(&s_CLRTaskManager);
- g_fHostConfig |= CLRTASKHOSTED;
- }
-
- if (m_HostThreadpoolManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRTHREADPOOLHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostThreadpoolManager,(void**)&threadpoolManager) == S_OK &&
- threadpoolManager != NULL) {
- m_HostThreadpoolManager = threadpoolManager;
- g_fHostConfig |= CLRTHREADPOOLHOSTED;
- }
-
- if (m_HostIoCompletionManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRIOCOMPLETIONHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostIoCompletionManager,(void**)&ioCompletionManager) == S_OK &&
- ioCompletionManager != NULL) {
- DWORD hostSize;
- hr = ioCompletionManager->GetHostOverlappedSize(&hostSize);
- if (FAILED(hr))
- {
- ioCompletionManager->Release();
- IfFailGo(E_UNEXPECTED);
- }
- m_HostOverlappedExtensionSize = (int)hostSize;
- m_HostIoCompletionManager = ioCompletionManager;
- m_HostIoCompletionManager->SetCLRIoCompletionManager(&s_CLRIoCompletionManager);
- g_fHostConfig |= CLRIOCOMPLETIONHOSTED;
- }
-
- if (m_HostSyncManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRSYNCHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostSyncManager,(void**)&syncManager) == S_OK &&
- syncManager != NULL) {
- m_HostSyncManager = syncManager;
- m_HostSyncManager->SetCLRSyncManager(&s_CLRSyncManager);
- g_fHostConfig |= CLRSYNCHOSTED;
- }
-
- if (m_HostAssemblyManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRASSEMBLYHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostAssemblyManager,(void**)&assemblyManager) == S_OK &&
- assemblyManager != NULL) {
-
- assemblyManager->GetAssemblyStore(&g_pHostAssemblyStore);
-
- hr = assemblyManager->GetNonHostStoreAssemblies(&g_pHostAsmList);
- if (FAILED(hr))
- {
- assemblyManager->Release();
- IfFailGo(hr);
- }
-
- if (g_pHostAssemblyStore || g_pHostAsmList)
- g_bFusionHosted = TRUE;
- m_HostAssemblyManager = assemblyManager;
- g_fHostConfig |= CLRASSEMBLYHOSTED;
- }
-
- if (m_HostGCManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRGCHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostGCManager,
- (void**)&gcManager) == S_OK &&
- gcManager != NULL) {
- m_HostGCManager = gcManager;
- g_fHostConfig |= CLRGCHOSTED;
- }
-
- if (m_HostSecurityManager == NULL &&
-#ifdef _DEBUG
- (dbg_HostManagerConfig & CLRSECURITYHOSTED) &&
-#endif
- pHostControl->GetHostManager(IID_IHostSecurityManager,
- (void**)&securityManager) == S_OK &&
- securityManager != NULL) {
- g_fHostConfig |= CLRSECURITYHOSTED;
- m_HostSecurityManager = securityManager;
-#ifdef FEATURE_CAS_POLICY
- HostExecutionContextManager::InitializeRestrictedContext();
-#endif // #ifdef FEATURE_CAS_POLICY
- }
-
- if (m_HostPolicyManager == NULL &&
- pHostControl->GetHostManager(IID_IHostPolicyManager,
- (void**)&policyManager) == S_OK &&
- policyManager != NULL) {
- m_HostPolicyManager = policyManager;
- }
-#endif //!FEATURE_CORECLR
if (m_HostControl == NULL)
{
@@ -4574,64 +1623,28 @@ public:
EPolicyAction action)
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- STATIC_CONTRACT_ENTRY_POINT;
- HRESULT hr;
- BEGIN_ENTRYPOINT_NOTHROW;
- hr = GetEEPolicy()->SetDefaultAction(operation, action);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-#else // FEATURE_CORECLR
return E_NOTIMPL;
-#endif // !FEATURE_CORECLR
}
virtual HRESULT STDMETHODCALLTYPE SetTimeout(EClrOperation operation,
DWORD dwMilliseconds)
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- STATIC_CONTRACT_ENTRY_POINT;
- HRESULT hr;
- BEGIN_ENTRYPOINT_NOTHROW;
- hr = GetEEPolicy()->SetTimeout(operation,dwMilliseconds);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-#else // FEATURE_CORECLR
return E_NOTIMPL;
-#endif // !FEATURE_CORECLR
}
virtual HRESULT STDMETHODCALLTYPE SetActionOnTimeout(EClrOperation operation,
EPolicyAction action)
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- STATIC_CONTRACT_ENTRY_POINT;
- HRESULT hr;
- BEGIN_ENTRYPOINT_NOTHROW;
- hr = GetEEPolicy()->SetActionOnTimeout(operation,action);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-#else // FEATURE_CORECLR
return E_NOTIMPL;
-#endif // !FEATURE_CORECLR
}
virtual HRESULT STDMETHODCALLTYPE SetTimeoutAndAction(EClrOperation operation, DWORD dwMilliseconds,
EPolicyAction action)
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- STATIC_CONTRACT_SO_TOLERANT;
- HRESULT hr;
- BEGIN_ENTRYPOINT_NOTHROW;
- hr = GetEEPolicy()->SetTimeoutAndAction(operation,dwMilliseconds,action);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-#else // FEATURE_CORECLR
return E_NOTIMPL;
-#endif // !FEATURE_CORECLR
}
virtual HRESULT STDMETHODCALLTYPE SetActionOnFailure(EClrFailure failure,
@@ -4642,7 +1655,6 @@ public:
STATIC_CONTRACT_ENTRY_POINT;
LIMITED_METHOD_CONTRACT;
HRESULT hr;
-#ifdef FEATURE_CORECLR
// For CoreCLR, this method just supports FAIL_AccessViolation as a valid
// failure input arg. The validation of the specified action for the failure
// will be done in EEPolicy::IsValidActionForFailure.
@@ -4650,7 +1662,6 @@ public:
{
return E_INVALIDARG;
}
-#endif // FEATURE_CORECLR
BEGIN_ENTRYPOINT_NOTHROW;
hr = GetEEPolicy()->SetActionOnFailure(failure,action);
END_ENTRYPOINT_NOTHROW;
@@ -4660,16 +1671,7 @@ public:
virtual HRESULT STDMETHODCALLTYPE SetUnhandledExceptionPolicy(EClrUnhandledException policy)
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- STATIC_CONTRACT_ENTRY_POINT;
- HRESULT hr;
- BEGIN_ENTRYPOINT_NOTHROW;
- hr = GetEEPolicy()->SetUnhandledExceptionPolicy(policy);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-#else // FEATURE_CORECLR
return E_NOTIMPL;
-#endif // !FEATURE_CORECLR
}
virtual ULONG STDMETHODCALLTYPE AddRef(void)
@@ -4705,427 +1707,22 @@ public:
static CCLRPolicyManager s_PolicyManager;
-#ifndef FEATURE_CORECLR // not supported
-class CCLROnEventManager: public ICLROnEventManager
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE RegisterActionOnEvent(EClrEvent event,
- IActionOnCLREvent *pAction)
- {
- CONTRACTL
- {
- GC_TRIGGERS;
- NOTHROW;
- ENTRY_POINT;
-
- // This function is always called from outside the Runtime. So, we assert that we either don't have a
- // managed thread, or if we do, that we're in preemptive GC mode.
- PRECONDITION((GetThread() == NULL) || !GetThread()->PreemptiveGCDisabled());
- }
- CONTRACTL_END;
-
- if (event >= MaxClrEvent || pAction == NULL || event < (EClrEvent)0)
- return E_INVALIDARG;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- // Note: its only safe to use a straight ReleaseHolder from within the VM directory when we know we're
- // called from outside the Runtime. We assert that above, just to be sure.
- ReleaseHolder<IActionOnCLREvent> actionHolder(pAction);
- pAction->AddRef();
-
- CrstHolderWithState ch(m_pLock);
-
- DWORD dwSwitchCount = 0;
- while (m_ProcessEvent != 0)
- {
- ch.Release();
- __SwitchToThread(0, ++dwSwitchCount);
- ch.Acquire();
- }
-
- if (m_pAction[event] == NULL)
- {
- m_pAction[event] = new (nothrow)ActionNode;
- if (m_pAction[event] == NULL)
- hr = E_OUTOFMEMORY;
- }
-
- if (SUCCEEDED(hr))
- {
- ActionNode *walk = m_pAction[event];
- while (TRUE)
- {
- int n = 0;
- for ( ; n < ActionNode::ActionArraySize; n ++)
- {
- if (walk->pAction[n] == NULL)
- {
- walk->pAction[n] = pAction;
- actionHolder.SuppressRelease();
- hr = S_OK;
- break;
- }
- }
- if (n < ActionNode::ActionArraySize)
- {
- break;
- }
- if (walk->pNext == NULL)
- {
- walk->pNext = new (nothrow) ActionNode;
- if (walk->pNext == NULL)
- {
- hr = E_OUTOFMEMORY;
- break;
- }
- }
- walk = walk->pNext;
- }
- }
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
- }
-
- virtual HRESULT STDMETHODCALLTYPE UnregisterActionOnEvent(EClrEvent event,
- IActionOnCLREvent *pAction)
- {
- CONTRACTL
- {
- GC_NOTRIGGER;
- NOTHROW;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- if (event == Event_StackOverflow)
- {
- // We don't want to take a lock when we process StackOverflow event, because we may
- // not have enough stack to do it.
- // So we do not release our cache of the callback in order to avoid race.
- return HOST_E_INVALIDOPERATION;
- }
-
- HRESULT hr = S_OK;
-
- ActionNode *walk = NULL;
- ActionNode *prev = NULL;
-
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- CrstHolderWithState ch(m_pLock);
-
- DWORD dwSwitchCount = 0;
- while (m_ProcessEvent != 0)
- {
- ch.Release();
- __SwitchToThread(0, ++dwSwitchCount);
- ch.Acquire();
- }
-
- if (m_pAction[event] == NULL)
- IfFailGo(HOST_E_INVALIDOPERATION);
-
- walk = m_pAction[event];
- while (walk)
- {
- BOOL fInUse = FALSE;
- for (int n = 0; n < ActionNode::ActionArraySize; n ++)
- {
- if (prev && !fInUse && walk->pAction[n])
- fInUse = TRUE;
- if (walk->pAction[n] == pAction)
- {
- walk->pAction[n] = NULL;
- ch.Release();
- pAction->Release();
- hr = S_OK;
- goto ErrExit;
- }
- }
- if (prev && !fInUse)
- {
- prev->pNext = walk->pNext;
- delete walk;
- walk = prev;
- }
- prev = walk;
- walk = walk->pNext;
- }
- hr = HOST_E_INVALIDOPERATION;
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
- }
-
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- STATIC_CONTRACT_SO_TOLERANT;
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppUnk)
- {
- STATIC_CONTRACT_SO_TOLERANT;
- LIMITED_METHOD_CONTRACT;
- if (riid != IID_ICLROnEventManager && riid != IID_IUnknown)
- return (E_NOINTERFACE);
- *ppUnk = this;
- return S_OK;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- STATIC_CONTRACT_SO_TOLERANT;
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- // This function is to work around an issue in scan.exe.
- // scan.exe is not smart to handle that if (){} else {}.
- void ProcessSOEvent(void *data)
- {
- STATIC_CONTRACT_SO_TOLERANT;
- WRAPPER_NO_CONTRACT;
-
- if (m_pLock == NULL)
- return;
-
- ActionNode *walk = m_pAction[Event_StackOverflow];
-
- while (walk)
- {
- for (int n = 0; n < ActionNode::ActionArraySize; n ++)
- {
- if (walk->pAction[n])
- {
- walk->pAction[n]->OnEvent(Event_StackOverflow,data);
- }
- }
- walk = walk->pNext;
- }
- }
-
- void ProcessEvent(EClrEvent event, void *data)
- {
- WRAPPER_NO_CONTRACT;
-
- if (m_pLock == NULL)
- {
- return;
- }
-
- _ASSERTE (event != Event_StackOverflow);
-
- {
- CrstHolder ch(m_pLock);
-
- if (event == Event_ClrDisabled)
- {
- if (m_CLRDisabled)
- {
- return;
- }
- m_CLRDisabled = TRUE;
- }
- m_ProcessEvent ++;
-
- // Release the lock around the call into the host. Is this correct?
- // It seems that we need to hold the lock except for the actual callback itself.
- }
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- {
- ActionNode *walk = m_pAction[event];
- while (walk)
- {
- for (int n = 0; n < ActionNode::ActionArraySize; n ++)
- {
- if (walk->pAction[n])
- {
- walk->pAction[n]->OnEvent(event,data);
- }
- }
- walk = walk->pNext;
- }
- }
- END_SO_TOLERANT_CODE_CALLING_HOST;
-
- {
- CrstHolder ch(m_pLock);
- m_ProcessEvent --;
- }
- }
-
- BOOL IsActionRegisteredForEvent(EClrEvent event)
- {
- WRAPPER_NO_CONTRACT;
-
- // Check to see if the event manager has been set up.
- if (m_pLock == NULL)
- return FALSE;
-
- CrstHolder ch(m_pLock);
-
- ActionNode *walk = m_pAction[event];
- while (walk)
- {
- for (int n = 0; n < ActionNode::ActionArraySize; n ++)
- {
- if (walk->pAction[n] != NULL)
- {
- // We found an action registered for this event.
- return TRUE;
- }
- }
- walk = walk->pNext;
- }
-
- // There weren't any actions registered.
- return FALSE;
- }
-
- HRESULT Init()
- {
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_NOTRIGGER;
- STATIC_CONTRACT_MODE_ANY;
- STATIC_CONTRACT_SO_TOLERANT;
-
- HRESULT hr = S_OK;
- if (m_pLock == NULL)
- {
- EX_TRY
- {
- BEGIN_SO_INTOLERANT_CODE(GetThread());
- {
- InitHelper();
- }
- END_SO_INTOLERANT_CODE;
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
- }
-
- return hr;
- }
-
-#if 0
- // We do not need this one. We have one instance of this class
- // and it is static.
- CCLROnEventManager()
- {
- LIMITED_METHOD_CONTRACT;
- for (int n = 0; n < MaxClrEvent; n ++)
- m_pAction[n] = NULL;
- }
-#endif
-
-private:
- struct ActionNode
- {
- static const int ActionArraySize = 8;
-
- IActionOnCLREvent *pAction[ActionArraySize];
- ActionNode *pNext;
-
- ActionNode ()
- : pNext(NULL)
- {
- LIMITED_METHOD_CONTRACT;
-
- for (int n = 0; n < ActionArraySize; n ++)
- pAction[n] = 0;
- }
- };
- ActionNode *m_pAction[MaxClrEvent];
-
- Crst* m_pLock;
-
- BOOL m_CLRDisabled;
-
- // We can not call out into host while holding the lock. At the same time
- // we need to make our data consistent. Therefore, m_ProcessEvent is a marker
- // to forbid touching the data structure from Register and UnRegister.
- DWORD m_ProcessEvent;
-
- void InitHelper()
- {
- CONTRACTL
- {
- GC_NOTRIGGER;
- THROWS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- m_ProcessEvent = 0;
-
- Crst* tmp = new Crst(CrstOnEventManager, CrstFlags(CRST_DEFAULT | CRST_DEBUGGER_THREAD));
- if (FastInterlockCompareExchangePointer(&m_pLock, tmp, NULL) != NULL)
- delete tmp;
- }
-};
-
-static CCLROnEventManager s_OnEventManager;
-#endif // FEATURE_CORECLR
void ProcessEventForHost(EClrEvent event, void *data)
{
-#ifndef FEATURE_CORECLR
- WRAPPER_NO_CONTRACT;
-
- _ASSERTE (event != Event_StackOverflow);
-
- GCX_PREEMP();
-
- s_OnEventManager.ProcessEvent(event,data);
-#endif // FEATURE_CORECLR
}
// We do not call ProcessEventForHost for stack overflow, since we have limit stack
// and we should avoid calling GCX_PREEMPT
void ProcessSOEventForHost(EXCEPTION_POINTERS *pExceptionInfo, BOOL fInSoTolerant)
{
-#ifndef FEATURE_CORECLR
- WRAPPER_NO_CONTRACT;
-
- StackOverflowInfo soInfo;
- if (fInSoTolerant)
- {
- soInfo.soType = SO_Managed;
- }
- else if (pExceptionInfo == NULL || IsIPInModule(g_pMSCorEE, GetIP(pExceptionInfo->ContextRecord)))
- {
- soInfo.soType = SO_ClrEngine;
- }
- else
- {
- soInfo.soType = SO_Other;
- }
-
- soInfo.pExceptionInfo = pExceptionInfo;
- s_OnEventManager.ProcessSOEvent(&soInfo);
-#endif // FEATURE_CORECLR
}
BOOL IsHostRegisteredForEvent(EClrEvent event)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CORECLR
return FALSE;
-#else // FEATURE_CORECLR
- return s_OnEventManager.IsActionRegisteredForEvent(event);
-#endif // FEATURE_CORECLR
}
inline size_t SizeInKBytes(size_t cbSize)
@@ -5154,7 +1751,7 @@ void UpdateGCSettingFromHost ()
}
}
-#if !defined(FEATURE_CORECLR) || defined(FEATURE_WINDOWSPHONE)
+#if defined(FEATURE_WINDOWSPHONE)
class CCLRGCManager: public ICLRGCManager2
{
public:
@@ -5394,7 +1991,7 @@ HRESULT CCLRGCManager::_SetGCMaxGen0Size(SIZE_T MaxGen0Size)
}
static CCLRGCManager s_GCManager;
-#endif // !FEATURE_CORECLR || FEATURE_WINDOWSPHONE
+#endif //FEATURE_WINDOWSPHONE
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
class CCLRAppDomainResourceMonitor : public ICLRAppDomainResourceMonitor
@@ -5542,92 +2139,6 @@ public:
static CCLRAppDomainResourceMonitor s_Arm;
#endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING
-#ifdef FEATURE_APTCA
-class CLRDomainManager : public ICLRDomainManager
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE SetAppDomainManagerType(__in LPCWSTR wszAppDomainManagerAssembly,
- __in LPCWSTR wszAppDomainManagerType,
- EInitializeNewDomainFlags dwInitializeDomainFlags)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- hr = CorHost2::SetAppDomainManagerType(wszAppDomainManagerAssembly,
- wszAppDomainManagerType,
- dwInitializeDomainFlags);
- END_ENTRYPOINT_NOTHROW;
- return hr;
- }
-
- virtual HRESULT STDMETHODCALLTYPE SetPropertiesForDefaultAppDomain(DWORD nProperties,
- __in_ecount(nProperties) LPCWSTR *pwszPropertyNames,
- __in_ecount(nProperties) LPCWSTR *pwszPropertyValues)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- hr = CorHost2::SetPropertiesForDefaultAppDomain(nProperties, pwszPropertyNames, pwszPropertyValues);
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
- }
-
- virtual ULONG STDMETHODCALLTYPE AddRef()
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release()
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(__in REFIID riid, __out LPVOID *ppvObject)
- {
- LIMITED_METHOD_CONTRACT;
-
- if (ppvObject == NULL)
- return E_POINTER;
-
- *ppvObject = NULL;
-
- if (riid == IID_ICLRDomainManager)
- {
- *ppvObject = this;
- }
- else if (riid == IID_IUnknown)
- {
- *ppvObject = static_cast<IUnknown *>(this);
- }
-
- if (*ppvObject == NULL)
- return E_NOINTERFACE;
-
- AddRef();
- return S_OK;
- }
-};
-
-static CLRDomainManager s_CLRDomainManager;
-#endif // FEATURE_APTCA
BOOL g_CLRPolicyRequested = FALSE;
@@ -5648,35 +2159,19 @@ public:
if (ppObject == NULL)
return E_INVALIDARG;
-#ifndef FEATURE_CORECLR
- // ErrorReportingManager is allowed, even if runtime is started, so
- // make this check first.
- // Host must call release on CLRErrorReportingManager after this call
- if (riid == IID_ICLRErrorReportingManager)
- {
- *ppObject = &g_CLRErrorReportingManager;
- return S_OK;
- }
- else
-#elif defined(FEATURE_WINDOWSPHONE)
+#if defined(FEATURE_WINDOWSPHONE)
if (riid == IID_ICLRErrorReportingManager2)
{
*ppObject = &g_CLRErrorReportingManager;
return S_OK;
}
else
-#endif // !FEATURE_CORECLR || defined(FEATURE_WINDOWSPHONE)
+#endif //defined(FEATURE_WINDOWSPHONE)
if (g_fEEStarted && !m_fFullAccess)
{
// If runtime has been started, do not allow user to obtain CLR managers.
return HOST_E_INVALIDOPERATION;
}
-#ifndef FEATURE_CORECLR
- else if (riid == IID_ICLRTaskManager) {
- *ppObject = &s_CLRTaskManager;
- return S_OK;
- }
-#endif // !FEATURE_CORECLR
// CoreCLR supports ICLRPolicyManager since it allows the host
// to specify the policy for AccessViolation.
@@ -5685,36 +2180,14 @@ public:
FastInterlockExchange((LONG*)&g_CLRPolicyRequested, TRUE);
return S_OK;
}
-#ifndef FEATURE_CORECLR
- else if (riid == IID_ICLRHostProtectionManager) {
- *ppObject = GetHostProtectionManager();
- return S_OK;
- }
-
- // Host must call release on CLRDebugManager after this call
- else if (riid == IID_ICLRDebugManager)
- {
- *ppObject = &s_CLRDebugManager;
- return S_OK;
- }
- else if (riid == IID_ICLROnEventManager)
- {
- HRESULT hr = s_OnEventManager.Init();
- if (FAILED(hr))
- return hr;
- *ppObject = &s_OnEventManager;
- return S_OK;
- }
-#endif // !FEATURE_CORECLR
-
-#if !defined(FEATURE_CORECLR) || defined(FEATURE_WINDOWSPHONE)
+#if defined(FEATURE_WINDOWSPHONE)
else if ((riid == IID_ICLRGCManager) || (riid == IID_ICLRGCManager2))
{
*ppObject = &s_GCManager;
return S_OK;
}
-#endif // !FEATURE_CORECLR || FEATURE_WINDOWSPHONE
+#endif //FEATURE_WINDOWSPHONE
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
else if (riid == IID_ICLRAppDomainResourceMonitor)
@@ -5724,13 +2197,6 @@ public:
return S_OK;
}
#endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING
-#ifdef FEATURE_APTCA
- else if (riid == IID_ICLRDomainManager)
- {
- *ppObject = &s_CLRDomainManager;
- return S_OK;
- }
-#endif // FEATURE_APTCA
else
return (E_NOINTERFACE);
}
@@ -5739,29 +2205,9 @@ public:
LPCWSTR pwzAppDomainManagerAssembly,
LPCWSTR pwzAppDomainManagerType)
{
-#ifndef FEATURE_CORECLR
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT; // no global state updates
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- hr = CorHost2::SetAppDomainManagerType(pwzAppDomainManagerAssembly,
- pwzAppDomainManagerType,
- eInitializeNewDomainFlags_None);
- END_ENTRYPOINT_NOTHROW;
- return hr;
-#else // FEATURE_CORECLR
// CoreCLR does not support this method
return E_NOTIMPL;
-#endif // !FEATURE_CORECLR
}
virtual ULONG STDMETHODCALLTYPE AddRef(void)
@@ -5806,9 +2252,6 @@ private:
// After CLR starts, we give out s_CorCLRControlLimited which allows limited access to managers.
static CCorCLRControl s_CorCLRControl;
-#ifndef FEATURE_CORECLR
-static CCorCLRControl s_CorCLRControlLimited;
-#endif // FEATURE_CORECLR
///////////////////////////////////////////////////////////////////////////////
// ICLRRuntimeHost::GetCLRControl
@@ -5833,11 +2276,6 @@ HRESULT CorHost2::GetCLRControl(ICLRControl** pCLRControl)
}
else
{
-#ifndef FEATURE_CORECLR
- // Even CLR is hosted by v1 hosting interface, we still allow part of CLRControl, like IID_ICLRErrorReportingManager.
- s_CorCLRControlLimited.SetAccess(FALSE);
- *pCLRControl = &s_CorCLRControlLimited;
-#else // FEATURE_CORECLR
// If :
// 1) request comes for interface other than ICLRControl*, OR
// 2) runtime has already started, OR
@@ -5854,647 +2292,45 @@ HRESULT CorHost2::GetCLRControl(ICLRControl** pCLRControl)
{
hr = E_NOTIMPL;
}
-#endif // !FEATURE_CORECLR
}
END_ENTRYPOINT_NOTHROW;
return hr;
}
-#ifndef FEATURE_CORECLR
-
-// static
-HRESULT CorHost2::SetPropertiesForDefaultAppDomain(DWORD nProperties,
- __in_ecount(nProperties) LPCWSTR *pwszPropertyNames,
- __in_ecount(nProperties) LPCWSTR *pwszPropertyValues)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- // Default domain properties can only be set before the CLR has started
- if (g_fEEStarted || HasStarted())
- {
- return HOST_E_INVALIDOPERATION;
- }
-
- // If the host is specifying properties, they should be there
- if (nProperties > 0 && (pwszPropertyNames == NULL || pwszPropertyValues == NULL))
- {
- return E_POINTER;
- }
-
- // v4 - since this property is being added late in the cycle to address a specific scenario, we
- // reject any attempt to set anything but a single well known property name. This restriction
- // can be removed in the future.
- for (DWORD iProperty = 0; iProperty < nProperties; ++iProperty)
- {
- if (pwszPropertyNames[iProperty] == NULL)
- {
- return E_POINTER;
- }
- if (pwszPropertyValues[iProperty] == NULL)
- {
- return E_POINTER;
- }
- if (wcscmp(PARTIAL_TRUST_VISIBLE_ASSEMBLIES_PROPERTY, pwszPropertyNames[iProperty]) != 0)
- {
- return HRESULT_FROM_WIN32(ERROR_UNKNOWN_PROPERTY);
- }
- }
-
- HRESULT hr = S_OK;
-
- EX_TRY
- {
- for (DWORD iProperty = 0; iProperty < nProperties; ++iProperty)
- {
- SString propertyName(pwszPropertyNames[iProperty]);
- s_defaultDomainPropertyNames.Append(propertyName);
-
- SString propertyValue(pwszPropertyValues[iProperty]);
- s_defaultDomainPropertyValues.Append(propertyValue);
- }
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
-// static
-HRESULT CorHost2::SetAppDomainManagerType(LPCWSTR wszAppDomainManagerAssembly,
- LPCWSTR wszAppDomainManagerType,
- EInitializeNewDomainFlags dwInitializeDomainFlags)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- // The AppDomainManger can only be set by the host before the CLR has started
- if (g_fEEStarted || HasStarted())
- {
- return HOST_E_INVALIDOPERATION;
- }
-
- // Both the type and assembly must be specified
- if (wszAppDomainManagerAssembly == NULL || wszAppDomainManagerType == NULL)
- {
- return E_INVALIDARG;
- }
-
- // Make sure we understand the incoming flags
- const EInitializeNewDomainFlags knownFlags = eInitializeNewDomainFlags_NoSecurityChanges;
- if ((dwInitializeDomainFlags & (~knownFlags)) != eInitializeNewDomainFlags_None)
- {
- return E_INVALIDARG;
- }
-
- // Get a copy of the AppDomainManager assembly
- size_t cchAsm = wcslen(wszAppDomainManagerAssembly) + 1;
- NewArrayHolder<WCHAR> wszAppDomainManagerAssemblyCopy(new (nothrow) WCHAR[cchAsm]);
- if (wszAppDomainManagerAssemblyCopy == NULL)
- {
- return E_OUTOFMEMORY;
- }
- wcsncpy_s(wszAppDomainManagerAssemblyCopy, cchAsm, wszAppDomainManagerAssembly, cchAsm - 1);
-
- // And of the AppDomainManagerType
- size_t cchType = wcslen(wszAppDomainManagerType) + 1;
- NewArrayHolder<WCHAR> wszAppDomainManagerTypeCopy(new (nothrow) WCHAR[cchType]);
- if (wszAppDomainManagerTypeCopy == NULL)
- {
- return E_OUTOFMEMORY;
- }
- wcsncpy_s(wszAppDomainManagerTypeCopy, cchType, wszAppDomainManagerType, cchType - 1);
-
- LPCWSTR wszOldAsmValue = FastInterlockCompareExchangePointer(&s_wszAppDomainManagerAsm,
- static_cast<LPCWSTR>(wszAppDomainManagerAssemblyCopy.GetValue()),
- NULL);
- if (wszOldAsmValue != NULL)
- {
- // We've tried to setup an AppDomainManager twice ... that's not allowed
- return HOST_E_INVALIDOPERATION;
- }
-
- s_wszAppDomainManagerType = wszAppDomainManagerTypeCopy;
- s_dwDomainManagerInitFlags = dwInitializeDomainFlags;
-
- wszAppDomainManagerAssemblyCopy.SuppressRelease();
- wszAppDomainManagerTypeCopy.SuppressRelease();
- return S_OK;
-}
-#endif // !FEATURE_CORECLR
LPCWSTR CorHost2::GetAppDomainManagerAsm()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- _ASSERTE (g_fEEStarted);
- return s_wszAppDomainManagerAsm;
-#endif // FEATURE_CORECLR
}
LPCWSTR CorHost2::GetAppDomainManagerType()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return NULL;
-#else // FEATURE_CORECLR
- _ASSERTE (g_fEEStarted);
- return s_wszAppDomainManagerType;
-#endif // FEATURE_CORECLR
}
// static
EInitializeNewDomainFlags CorHost2::GetAppDomainManagerInitializeNewDomainFlags()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return eInitializeNewDomainFlags_None;
-#else // FEAUTRE_CORECLR
- _ASSERTE (g_fEEStarted);
- return s_dwDomainManagerInitFlags;
-#endif // FEATURE_CORECLR
-}
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-// We do not implement the Release since our host does not control the lifetime on this object
-ULONG CCLRDebugManager::Release()
-{
- LIMITED_METHOD_CONTRACT;
- return (1);
-}
-
-HRESULT CCLRDebugManager::QueryInterface(REFIID riid, void **ppUnk)
-{
- if (!ppUnk)
- return E_POINTER;
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- if (ppUnk == NULL)
- {
- return E_POINTER;
- }
-
- *ppUnk = 0;
-
- // Deliberately do NOT hand out ICorConfiguration. They must explicitly call
- // GetConfiguration to obtain that interface.
- if (riid == IID_IUnknown)
- {
- *ppUnk = (IUnknown *) this;
- }
- else if (riid == IID_ICLRDebugManager)
- {
- *ppUnk = (ICLRDebugManager *) this;
- }
- else
- {
- hr = E_NOINTERFACE;
- }
-
- return hr;
-
-}
-
-/*
-*
-* Called once to when process start up to initialize the lock for connection name hash table
-*
-*/
-void CCLRDebugManager::ProcessInit()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- m_lockConnectionNameTable.Init(CrstConnectionNameTable, (CrstFlags) (CRST_UNSAFE_ANYMODE | CRST_DEBUGGER_THREAD));
}
-/*
-* Called once to when process shut down to destroy the lock for connection name hash table
-*
-*/
-void CCLRDebugManager::ProcessCleanup()
-{
- CONTRACTL
- {
- GC_NOTRIGGER;
- NOTHROW;
- }
- CONTRACTL_END;
-
- m_lockConnectionNameTable.Destroy();
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#endif // !DAC
#ifdef DACCESS_COMPILE
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-
-//---------------------------------------------------------------------------------------
-// Begin an iterating over connections for Debugger
-//
-// Arguments:
-// pHashfind - out: initializes cookie to pass to to future calls to code:CCLRDebugManager.FindNext
-//
-// Returns:
-// NULL if iteration is done. Else a ConnectionNameHashEntry representing the connection.
-//
-ConnectionNameHashEntry * CCLRDebugManager::FindFirst(HASHFIND * pHashfind)
-{
- SUPPORTS_DAC;
- if (m_pConnectionNameHash == NULL)
- {
- return NULL;
- }
-
- ConnectionNameHashEntry * pConnection = dac_cast<PTR_ConnectionNameHashEntry>(m_pConnectionNameHash->FindFirstEntry(pHashfind));
- return pConnection;
- }
-
-//---------------------------------------------------------------------------------------
-// Begin an iterating over connections for Debugger
-//
-// Arguments:
-// pHashfind - in/out: iterator cookie to pass to future calls to code:CCLRDebugManager.FindNext
-//
-// Returns:
-// NULL if iteration is done. Else a ConnectionNameHashEntry representing the connection.
-//
-ConnectionNameHashEntry * CCLRDebugManager::FindNext(HASHFIND * pHashfind)
- {
- SUPPORTS_DAC;
- ConnectionNameHashEntry * pConnection = dac_cast<PTR_ConnectionNameHashEntry>(m_pConnectionNameHash->FindNextEntry(pHashfind));
- return pConnection;
-}
-
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#endif //DACCESS_COMPILE
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-HRESULT CCLRDebugManager::IsDebuggerAttached(BOOL *pbAttached)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- if (pbAttached == NULL)
- return E_INVALIDARG;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
-#ifdef DEBUGGING_SUPPORTED
- *pbAttached = (CORDebuggerAttached() != 0);
-#else
- *pbAttached = FALSE;
-#endif
-
- END_ENTRYPOINT_NOTHROW;
-
-
- return S_OK;
-}
-
-// By default, we permit symbols to be read for full-trust assemblies only
-ESymbolReadingSetBy CCLRDebugManager::m_symbolReadingSetBy = eSymbolReadingSetByDefault;
-ESymbolReadingPolicy CCLRDebugManager::m_symbolReadingPolicy = eSymbolReadingFullTrustOnly;
-
-HRESULT CCLRDebugManager::SetSymbolReadingPolicy(ESymbolReadingPolicy policy)
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_ENTRY_POINT;
-
- if( policy > eSymbolReadingFullTrustOnly )
- {
- return E_INVALIDARG;
- }
-
- SetSymbolReadingPolicy( policy, eSymbolReadingSetByHost );
-
- return S_OK;
-}
-
-void CCLRDebugManager::SetSymbolReadingPolicy( ESymbolReadingPolicy policy, ESymbolReadingSetBy setBy )
-{
- LIMITED_METHOD_CONTRACT;
- _ASSERTE( policy <= eSymbolReadingFullTrustOnly ); // don't have _COUNT because it's not in convention for mscoree.idl enums
- _ASSERTE( setBy < eSymbolReadingSetBy_COUNT );
-
- // if the setter meets or exceeds the precendence of the existing setting then override the setting
- if( setBy >= m_symbolReadingSetBy )
- {
- m_symbolReadingSetBy = setBy;
- m_symbolReadingPolicy = policy;
- }
-}
-
-
-/*
-* Call by host to set the name of a connection and begin a connection.
-*
-*/
-HRESULT CCLRDebugManager::BeginConnection(
- CONNID dwConnectionId,
- __in_z wchar_t *wzConnectionName) // We should review this in the future. This API is
- // public and callable by a host. This SAL annotation
- // is the best we can do now.
-{
- CONTRACTL
- {
- GC_TRIGGERS; // I am having problem in putting either GC_TRIGGERS or GC_NOTRIGGER. It is not happy either way when debugger
- // call back event needs to enable preemptive GC.
- ENTRY_POINT;
- NOTHROW;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- ConnectionNameHashEntry *pEntry = NULL;
-
- // check input parameter
- if (dwConnectionId == INVALID_CONNECTION_ID || wzConnectionName == NULL || wzConnectionName[0] == W('\0'))
- IfFailGo(E_INVALIDARG);
-
- if (wcslen(wzConnectionName) >= MAX_CONNECTION_NAME)
- IfFailGo(E_INVALIDARG);
-
- {
- CrstHolder ch(&m_lockConnectionNameTable);
-
- if (m_pConnectionNameHash == NULL)
- {
- m_pConnectionNameHash = new (nothrow) ConnectionNameTable(50);
- IfNullGo(m_pConnectionNameHash);
- IfFailGo(m_pConnectionNameHash->NewInit(50, sizeof(ConnectionNameHashEntry), USHRT_MAX));
- }
-
- // error: Should not have an existing connection id already
- if (m_pConnectionNameHash->FindConnection(dwConnectionId))
- IfFailGo(E_INVALIDARG);
-
- // Our implementation of hashtable cannot throw out of memory exception
- pEntry = m_pConnectionNameHash->AddConnection(dwConnectionId, wzConnectionName);
- IfNullGo(pEntry);
- }
-
- // send notification to debugger
- if (CORDebuggerAttached())
- {
- g_pDebugInterface->CreateConnection(dwConnectionId, wzConnectionName);
- }
-
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-/*
-* Call by host to end a connection
-*/
-HRESULT CCLRDebugManager::EndConnection(CONNID dwConnectionId)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- NOTHROW;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- UINT CLRTaskCount = 0;
- ICLRTask **ppCLRTaskArray = NULL;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- if (dwConnectionId == INVALID_CONNECTION_ID)
- IfFailGo(E_INVALIDARG);
-
- // No connection exist at all
- if (m_pConnectionNameHash == NULL)
- IfFailGo(E_FAIL);
-
- {
- CrstHolder ch(&m_lockConnectionNameTable);
- ConnectionNameHashEntry *pEntry = NULL;
-
- if ((pEntry = m_pConnectionNameHash->FindConnection(dwConnectionId)) == NULL)
- IfFailGo(E_INVALIDARG);
-
- // Note that the Release on CLRTask chould take a ThreadStoreLock. So we need to finish our
- // business with ConnectionNameHash before hand and release our name hash lock
- //
- CLRTaskCount = pEntry->m_CLRTaskCount;
- ppCLRTaskArray = pEntry->m_ppCLRTaskArray;
- pEntry->m_ppCLRTaskArray = NULL;
- pEntry->m_CLRTaskCount = 0;
- m_pConnectionNameHash->DeleteConnection(dwConnectionId);
- }
-
- if (CLRTaskCount != 0)
- {
- _ASSERTE(ppCLRTaskArray != NULL);
- for (UINT i = 0; i < CLRTaskCount; i++)
- {
- ((Thread *)ppCLRTaskArray[i])->SetConnectionId(INVALID_CONNECTION_ID);
- ppCLRTaskArray[i]->Release();
- }
- delete [] ppCLRTaskArray;
- }
-
- // send notification to debugger
- if (CORDebuggerAttached())
- g_pDebugInterface->DestroyConnection(dwConnectionId);
-
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-/*
-* Call by host to set a set of tasks as a connection.
-*
-*/
-HRESULT CCLRDebugManager::SetConnectionTasks(
- DWORD id,
- DWORD dwCount,
- ICLRTask **ppCLRTask)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- NOTHROW;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- ICLRTask **ppCLRTaskArrayNew = NULL;
- UINT CLRTaskCountPrevious = 0;
- ICLRTask **ppCLRTaskArrayPrevious = NULL;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- DWORD index;
- Thread *pThread;
- ConnectionNameHashEntry *pEntry = NULL;
-
- if (id == INVALID_CONNECTION_ID || dwCount == 0 || ppCLRTask == NULL)
- IfFailGo(E_INVALIDARG);
-
- {
- CrstHolder ch(&m_lockConnectionNameTable);
-
- // check the BeginConnectin has been called.
- if (m_pConnectionNameHash == NULL)
- // No connection exist
- IfFailGo(E_INVALIDARG);
- // Host forget to call BeginConnection before calling SetConnectionTask!
- if ((pEntry = m_pConnectionNameHash->FindConnection(id)) == NULL)
- IfFailGo(E_INVALIDARG);
-
- for (index = 0; index < dwCount; index++)
- {
- // Check on input parameter
- pThread = (Thread *) ppCLRTask[index];
- if (pThread == NULL)
- {
- // _ASSERTE(!"Host passed in NULL ICLRTask pointer");
- IfFailGo(E_INVALIDARG);
- }
-
- // Check for Finalizer thread
- if (GCHeapUtilities::IsGCHeapInitialized() && (pThread == FinalizerThread::GetFinalizerThread()))
- {
- // _ASSERTE(!"Host should not try to schedule user code on our Finalizer Thread");
- IfFailGo(E_INVALIDARG);
-
- }
- }
-
- ppCLRTaskArrayNew = new (nothrow) ICLRTask*[dwCount];
- IfNullGo(ppCLRTaskArrayNew);
-
- CLRTaskCountPrevious = pEntry->m_CLRTaskCount;
- ppCLRTaskArrayPrevious = pEntry->m_ppCLRTaskArray;
- pEntry->m_ppCLRTaskArray = NULL;
- pEntry->m_CLRTaskCount = 0;
-
- if (CLRTaskCountPrevious != 0)
- {
- // Clear the old connection set
- _ASSERTE(ppCLRTaskArrayPrevious != NULL);
- for (UINT i = 0; i < CLRTaskCountPrevious; i++)
- ((Thread *)ppCLRTaskArrayPrevious[i])->SetConnectionId(INVALID_CONNECTION_ID);
- }
-
- // now remember the new set
- pEntry->m_ppCLRTaskArray = ppCLRTaskArrayNew;
-
- for (index = 0; index < dwCount; index++)
- {
- pThread = (Thread *) ppCLRTask[index];
- pThread->SetConnectionId( id );
- pEntry->m_ppCLRTaskArray[index] = ppCLRTask[index];
- }
- pEntry->m_CLRTaskCount = dwCount;
-
- // AddRef and Release on Thread object can call ThreadStoreLock. So we will release our
- // lock first of all.
- }
-
- // Does the addref on the new set
- for (index = 0; index < dwCount; index++)
- ppCLRTaskArrayNew[index]->AddRef();
-
- // Does the release on the old set
- if (CLRTaskCountPrevious != 0)
- {
- _ASSERTE(ppCLRTaskArrayPrevious != NULL);
- for (UINT i = 0; i < CLRTaskCountPrevious; i++)
- ppCLRTaskArrayPrevious[i]->Release();
- delete ppCLRTaskArrayPrevious;
- }
-
- // send notification to debugger
- if (CORDebuggerAttached())
- {
- g_pDebugInterface->ChangeConnection(id);
- }
-
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
- return hr;
-}
-
-HRESULT CCLRDebugManager::SetDacl(PACL pacl)
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_ENTRY_POINT;
- HRESULT hr;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- hr = E_NOTIMPL;
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
-} // SetDACL
-
-
-HRESULT CCLRDebugManager::GetDacl(PACL *pacl)
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_ENTRY_POINT;
- HRESULT hr;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- hr = E_NOTIMPL;
-
- END_ENTRYPOINT_NOTHROW;
- return hr;
-} // SetDACL
-
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
+#if defined(FEATURE_WINDOWSPHONE)
HRESULT CCLRErrorReportingManager::QueryInterface(REFIID riid, void** ppUnk)
{
@@ -6874,7 +2710,7 @@ CCLRErrorReportingManager::~CCLRErrorReportingManager()
#endif
}
-#endif // defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(FEATURE_WINDOWSPHONE)
+#endif // defined(FEATURE_WINDOWSPHONE)
#ifdef FEATURE_IPCMAN
@@ -7060,7 +2896,6 @@ HRESULT CCLRSecurityAttributeManager::GetDACL(PACL *ppacl)
BOOL bDaclPresent;
BOOL bDaclDefault;
- LeaveRuntimeHolder holder((size_t)(::GetSecurityDescriptorDacl));
::GetSecurityDescriptorDacl(pSA->lpSecurityDescriptor, &bDaclPresent, &pDefaultACL, &bDaclDefault);
}
EX_CATCH
@@ -7213,21 +3048,6 @@ void GetProcessMemoryLoad(LPMEMORYSTATUSEX pMSEX)
BOOL fRet = GlobalMemoryStatusEx(pMSEX);
_ASSERTE (fRet);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- // CoreCLR cannot be memory hosted
- if (CLRMemoryHosted())
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- DWORD memoryLoad;
- SIZE_T availableBytes;
- HRESULT hr = CorHost2::GetHostMemoryManager()->GetMemoryLoad(&memoryLoad, &availableBytes);
- if (hr == S_OK) {
- pMSEX->dwMemoryLoad = memoryLoad;
- pMSEX->ullAvailPhys = availableBytes;
- }
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
// If the machine has more RAM than virtual address limit, let us cap it.
// Our GC can never use more than virtual address limit.
@@ -7322,9 +3142,6 @@ struct ClrTlsInfo
#define DataToClrTlsInfo(a) (a)?(ClrTlsInfo*)((BYTE*)a - offsetof(ClrTlsInfo, data)):NULL
-#if !defined(FEATURE_CORECLR)
-#define HAS_FLS_SUPPORT 1
-#endif
#ifdef HAS_FLS_SUPPORT
@@ -7415,84 +3232,6 @@ BOOL CExecutionEngine::SetTlsData (void** ppTlsInfo)
#endif // FEATURE_IMPLICIT_TLS
-static VolatilePtr<ClrTlsInfo> g_pDetachedTlsInfo;
-
-BOOL CExecutionEngine::HasDetachedTlsInfo()
-{
- LIMITED_METHOD_CONTRACT;
-
- return g_pDetachedTlsInfo.Load() != NULL;
-}
-
-void CExecutionEngine::CleanupDetachedTlsInfo()
-{
- WRAPPER_NO_CONTRACT;
-
- if (g_pDetachedTlsInfo.Load() == NULL)
- {
- return;
- }
- ClrTlsInfo *head = FastInterlockExchangePointer(g_pDetachedTlsInfo.GetPointer(), NULL);
-
- while (head)
- {
- ClrTlsInfo *node = head;
- head = head->next;
- DeleteTLS(node->data);
- }
-}
-
-void CExecutionEngine::DetachTlsInfo(void **pTlsData)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (pTlsData == NULL)
- {
- return;
- }
-
- if (CExecutionEngine::GetTlsData() == pTlsData)
- {
- CExecutionEngine::SetTlsData(0);
- }
-
-#ifdef HAS_FLS_SUPPORT
- if (fHasFlsSupport && pFlsGetValue(FlsIndex) == pTlsData)
- {
- pFlsSetValue(FlsIndex, NULL);
- }
-#endif
-
- ClrTlsInfo *pTlsInfo = DataToClrTlsInfo(pTlsData);
- // PREFIX_ASSUME needs TLS. If we use it here, we may do memory allocation.
-#if defined(_PREFAST_) || defined(_PREFIX_)
- if (pTlsInfo == NULL) __UNREACHABLE();
-#else
- _ASSERTE(pTlsInfo != NULL);
-#endif // _PREFAST_ || _PREFIX_
-
- if (pTlsInfo->data[TlsIdx_StressLog])
- {
-#ifdef STRESS_LOG
- CantAllocHolder caHolder;
- StressLog::ThreadDetach ((ThreadStressLog *)pTlsInfo->data[TlsIdx_StressLog]);
- pTlsInfo->data[TlsIdx_StressLog] = NULL;
-#else
- _ASSERTE (!"Shouldn't have stress log!");
-#endif
- }
-
- while (TRUE)
- {
- ClrTlsInfo *head = g_pDetachedTlsInfo.Load();
- pTlsInfo->next = head;
- if (FastInterlockCompareExchangePointer(g_pDetachedTlsInfo.GetPointer(), pTlsInfo, head) == head)
- {
- return;
- }
- }
-}
-
//---------------------------------------------------------------------------------------
//
// Returns the current logical thread's data block (ClrTlsInfo::data).
@@ -7646,7 +3385,7 @@ void **CExecutionEngine::CheckThreadState(DWORD slot, BOOL force)
// If we have a thread object or are on a non-fiber thread, we are safe for fiber switching.
if (!fHasFlsSupport ||
GetThread() ||
- ((g_fEEStarted || g_fEEInit) && !CLRTaskHosted()) ||
+ (g_fEEStarted || g_fEEInit) ||
(((size_t)pTlsInfo->data[TlsIdx_ThreadType]) & (ThreadType_GC | ThreadType_Gate | ThreadType_Timer | ThreadType_DbgHelper)))
{
#ifdef _DEBUG
@@ -8187,7 +3926,6 @@ DWORD STDMETHODCALLTYPE CExecutionEngine::WaitForSingleObject(HANDLE handle,
{
STATIC_CONTRACT_WRAPPER;
STATIC_CONTRACT_SO_TOLERANT;
- LeaveRuntimeHolder holder((size_t)(::WaitForSingleObject));
return ::WaitForSingleObject(handle,dwMilliseconds);
}
@@ -8431,11 +4169,11 @@ SIZE_T STDMETHODCALLTYPE CExecutionEngine::ClrVirtualQuery(LPCVOID lpAddress,
}
#define ClrVirtualQuery EEVirtualQuery
-#if defined(_DEBUG) && defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if defined(_DEBUG) && !defined(FEATURE_PAL)
static VolatilePtr<BYTE> s_pStartOfUEFSection = NULL;
static VolatilePtr<BYTE> s_pEndOfUEFSectionBoundary = NULL;
static Volatile<DWORD> s_dwProtection = 0;
-#endif // _DEBUG && FEATURE_CORECLR && !FEATURE_PAL
+#endif // _DEBUG && !FEATURE_PAL
#undef ClrVirtualProtect
@@ -8481,7 +4219,7 @@ BOOL STDMETHODCALLTYPE CExecutionEngine::ClrVirtualProtect(LPVOID lpAddress,
//
// We assert if either of the two conditions above are true.
-#if defined(_DEBUG) && defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if defined(_DEBUG) && !defined(FEATURE_PAL)
// We do this check in debug/checked builds only
// Do we have the UEF details?
@@ -8551,7 +4289,7 @@ BOOL STDMETHODCALLTYPE CExecutionEngine::ClrVirtualProtect(LPVOID lpAddress,
"Do not virtual protect the section in which UEF lives!");
}
}
-#endif // _DEBUG && FEATURE_CORECLR && !FEATURE_PAL
+#endif // _DEBUG && !FEATURE_PAL
return EEVirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect);
}
@@ -8655,14 +4393,11 @@ void CExecutionEngine::GetLastThrownObjectExceptionFromThread(void **ppvExceptio
} // HRESULT CExecutionEngine::GetLastThrownObjectExceptionFromThread()
-#ifdef FEATURE_VERSIONING
LocaleID RuntimeGetFileSystemLocale()
{
return PEImage::GetFileSystemLocale();
};
-#endif
-#ifdef FEATURE_CORECLR
HRESULT CorHost2::DllGetActivationFactory(DWORD appDomainID, LPCWSTR wszTypeName, IActivationFactory ** factory)
{
#ifdef FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION
@@ -8692,7 +4427,6 @@ HRESULT CorHost2::DllGetActivationFactory(DWORD appDomainID, LPCWSTR wszTypeName
return E_NOTIMPL;
#endif
}
-#endif
#ifdef FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION
@@ -8717,16 +4451,6 @@ HRESULT STDMETHODCALLTYPE DllGetActivationFactoryImpl(LPCWSTR wszAssemblyName,
AppDomain* pDomain = SystemDomain::System()->DefaultDomain();
_ASSERTE(pDomain);
-#ifndef FEATURE_CORECLR // coreclr uses winrt binder which does not allow redirects
- {
- BaseDomain::LockHolder lh(pDomain);
- if (!pDomain->HasLoadContextHostBinder())
- {
- // don't allow redirects
- SystemDomain::InitializeDefaultDomain(FALSE);
- }
- }
-#endif
BEGIN_EXTERNAL_ENTRYPOINT(&hr);
{
@@ -8741,16 +4465,6 @@ HRESULT STDMETHODCALLTYPE DllGetActivationFactoryImpl(LPCWSTR wszAssemblyName,
} gc;
memset(&gc, 0, sizeof(gc));
-#if defined(FEATURE_MULTICOREJIT) && defined(FEATURE_APPX_BINDER)
- // For Appx, multicore JIT is only needed when root assembly does not have NI image
- // When it has NI image, we can't generate profile, and do not need to playback profile
- if (AppX::IsAppXProcess() && ! typeHandle.IsZapped())
- {
- GCX_PREEMP();
-
- pDomain->GetMulticoreJitManager().AutoStartProfileAppx(pDomain);
- }
-#endif
IActivationFactory* activationFactory;
GCPROTECT_BEGIN(gc);
@@ -8781,64 +4495,6 @@ HRESULT STDMETHODCALLTYPE DllGetActivationFactoryImpl(LPCWSTR wszAssemblyName,
#endif // !FEATURE_COMINTEROP_MANAGED_ACTIVATION
-#ifdef FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
-
-HRESULT STDMETHODCALLTYPE GetClassActivatorForApplicationImpl(HSTRING appPath, IWinRTClassActivator** ppActivator)
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
- BEGIN_EXTERNAL_ENTRYPOINT(&hr);
- {
- if (GetAppDomain()->GetWinRtBinder()->SetLocalWinMDPath(appPath))
- {
- GCX_COOP();
-
- struct
- {
- STRINGREF appbase;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
- GCPROTECT_BEGIN(gc);
-
- UINT32 appPathLength = 0;
- PCWSTR wszAppPath = WindowsGetStringRawBuffer(appPath, &appPathLength);
-
- gc.appbase = StringObject::NewString(wszAppPath, appPathLength);
-
- MethodDescCallSite getClassActivator(METHOD__WINDOWSRUNTIMEMARSHAL__GET_CLASS_ACTIVATOR_FOR_APPLICATION);
-
- ARG_SLOT args[] =
- {
- ObjToArgSlot(gc.appbase)
- };
-
- IWinRTClassActivator* pActivator = reinterpret_cast<IWinRTClassActivator *>(getClassActivator.Call_RetLPVOID(args));
- *ppActivator = pActivator;
-
- GCPROTECT_END();
- }
- else
- {
- hr = CO_E_BAD_PATH;
- }
- }
- END_EXTERNAL_ENTRYPOINT;
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-#endif // FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
#endif // !DACCESS_COMPILE
diff --git a/src/vm/crossdomaincalls.cpp b/src/vm/crossdomaincalls.cpp
deleted file mode 100644
index b528915a54..0000000000
--- a/src/vm/crossdomaincalls.cpp
+++ /dev/null
@@ -1,2587 +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.
-//
-// File: CrossDomainCalls.cpp
-//
-
-//
-// The CrossDomainCall class provides a fast path of execution for qualifying
-// cross domain calls. Asynch calls, one way calls, calls on context bound objects
-// etc dont qualify.
-//
-
-
-#include "common.h"
-
-#ifdef FEATURE_REMOTING
-
-#include "crossdomaincalls.h"
-#include "callhelpers.h"
-#include "remoting.h"
-#include "objectclone.h"
-#include "dbginterface.h"
-#include "stackprobe.h"
-#include "virtualcallstub.h"
-#include "typeparse.h"
-#include "typestring.h"
-#include "appdomain.inl"
-#include "callingconvention.h"
-
-// See explanation of flags in crossdomaincalls.h
-RemotableMethodInfo::XADOptimizationType
-RemotableMethodInfo::IsCrossAppDomainOptimizable(MethodDesc *pMeth, DWORD *pNumStackSlotsToCopy)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- // This method table might be representative, but that's OK for the kinds of analysis we're about to do.
- MethodTable *pMT = pMeth->GetMethodTable()->GetCanonicalMethodTable();
-
- _ASSERTE(pMT->HasRemotableMethodInfo());
- _ASSERTE(pMT->GetRemotableMethodInfo());
-
- if (pMT->IsContextful())
- return XAD_NOT_OPTIMIZABLE;
-
- DWORD flags;
-
- // If this method is generic then we can't used cached analysis data stored on the method table and keyed by slot -- the same
- // slot is shared by methods with very different characteristics (such as whether the return type is a GC ref etc.).
- if (pMeth->GetNumGenericMethodArgs() > 0)
- {
- flags = DoStaticAnalysis(pMeth);
- }
- else
- {
- _ASSERTE(pMeth->GetSlot() < pMeth->GetMethodTable()->GetNumVtableSlots());
- RemotableMethodInfo *pRMI = &(pMT->GetRemotableMethodInfo()->GetRemotableMethodInfo()[pMeth->GetSlot()]);
- flags = pRMI->m_OptFlags;
-
- if (!(flags & XAD_FLAGS_INITIALIZED))
- {
- flags = DoStaticAnalysis(pMeth);
- pRMI->m_OptFlags = flags;
- }
- }
-
- *pNumStackSlotsToCopy = flags & XAD_ARG_COUNT_MASK;
-
- return (XADOptimizationType) (flags & XAD_FLAG_MASK);
-}
-
-// This method is not synchronized because the operation is idempotent
-DWORD
-RemotableMethodInfo::DoStaticAnalysis(MethodDesc *pMeth)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- PRECONDITION(CheckPointer(pMeth));
- }
- CONTRACTL_END
-
- BOOL bCallArgsBlittable = TRUE;
- BOOL bRetArgBlittable = TRUE;
- BOOL bOptimizable = TRUE;
- BOOL bMethodIsVirtual = FALSE;
- BOOL bArgsHaveAFloat = FALSE;
-
- DWORD numStackBytes = 0;
- DWORD numStackSlots = 0;
- DWORD returnTypeFlags = 0;
-
- if (pMeth->ContainsGenericVariables())
- {
- bOptimizable = FALSE;
- }
- else
- {
- MetaSig mSig(pMeth);
- ArgIterator argit(&mSig);
-
- SigPointer spRet;
- CorElementType retElem;
-
- IMDInternalImport *pMDImport = pMeth->GetModule()->GetMDImport();
- MDEnumHolder ePm(pMDImport); // For enumerating params.
- mdParamDef tkPm; // A param token.
- DWORD dwFlags; // Param flags.
- USHORT usSeq; // Sequence of a parameter.
-
- if (pMeth->IsOneWay())
- {
- bOptimizable = FALSE;
- goto SetFlags;
- }
-
- if (pMeth->IsVirtual())
- {
- bMethodIsVirtual = TRUE;
- }
-
- numStackBytes = argit.SizeOfFrameArgumentArray();
-
- _ASSERTE(numStackBytes % sizeof(SIZE_T) == 0);
- numStackSlots = numStackBytes / sizeof(SIZE_T);
-
- if (numStackSlots > XAD_ARG_COUNT_MASK)
- {
- bOptimizable = FALSE;
- goto SetFlags;
- }
-
- // Check if there are any [Out] args. If there are, skip the fast path
- IfFailThrow(pMDImport->EnumInit(mdtParamDef, pMeth->GetMemberDef(), &ePm));
-
- // Enumerate through the params and check the flags.
- while (pMDImport->EnumNext(&ePm, &tkPm))
- {
- LPCSTR szParamName_Ignore;
- IfFailThrow(pMDImport->GetParamDefProps(tkPm, &usSeq, &dwFlags, &szParamName_Ignore));
- if (usSeq == 0) // Skip return type flags.
- continue;
- // If the param has Out attribute, do not use fast path for this method
- if (IsPdOut(dwFlags))
- {
- bOptimizable = FALSE;
- goto SetFlags;
- }
- }
-
- // We're getting SigPointer first because this way we can differentiate E_T_STRING and E_T_CLASS
- spRet = mSig.GetReturnProps();
- IfFailThrow(spRet.GetElemType(&retElem));
- if (retElem > ELEMENT_TYPE_PTR &&
- retElem != ELEMENT_TYPE_I &&
- retElem != ELEMENT_TYPE_U &&
- retElem != ELEMENT_TYPE_FNPTR)
- {
- bRetArgBlittable = FALSE;
- }
-
- // Now we can normalize the return type so as to get rid of any generic type variables and the like.
- retElem = mSig.GetReturnType();
-
- if (retElem == ELEMENT_TYPE_VALUETYPE)
- {
- // Make a note that we have a struct in the signature. This way we wont blit the contents
- // and end up in a situation where we have data, but the type isnt loaded yet
- bCallArgsBlittable = FALSE;
-
- // Do some further inspection
- TypeHandle retTypeHandle = mSig.GetRetTypeHandleThrowing();
-
- // Currently we don't handle the special unbox handling for ret values of Nullable<T> in MarshalAndCall
- if (Nullable::IsNullableType(retTypeHandle))
- {
- bOptimizable = FALSE;
- }
-
- retElem = retTypeHandle.GetInternalCorElementType();
- if ((retElem <= ELEMENT_TYPE_PTR || retElem == ELEMENT_TYPE_I || retElem == ELEMENT_TYPE_U) &&
- !retTypeHandle.AsMethodTable()->CannotBeBlittedByObjectCloner())
- bRetArgBlittable = TRUE;
- }
-
- // Check if the return type is a GC ref
- if (gElementTypeInfo[retElem].m_gc == TYPE_GC_REF)
- {
- returnTypeFlags = XAD_RET_GC_REF;
- }
- else
- {
- returnTypeFlags = GetRetTypeFlagsFromFPReturnSize(argit.GetFPReturnSize());
- }
-
- CorElementType currType;
- while ((currType = mSig.NextArg()) != ELEMENT_TYPE_END)
- {
- SigPointer sp = mSig.GetArgProps();
- CorElementType retTy;
- IfFailThrow(sp.GetElemType(&retTy));
- if (retTy > ELEMENT_TYPE_PTR &&
- retTy != ELEMENT_TYPE_VALUETYPE &&
- retTy != ELEMENT_TYPE_I &&
- retTy != ELEMENT_TYPE_U &&
- retTy != ELEMENT_TYPE_FNPTR)
- {
- bCallArgsBlittable = FALSE;
- }
-
- // Currently we don't handle the special unbox handling for Nullable<T> for byrefs in MarshalAndCall
- if (currType == ELEMENT_TYPE_BYREF)
- {
- TypeHandle refType;
- if (mSig.GetByRefType(&refType) == ELEMENT_TYPE_VALUETYPE)
- if (Nullable::IsNullableType(refType))
- {
- bOptimizable = FALSE;
- }
- }
- else if (currType == ELEMENT_TYPE_VALUETYPE)
- {
-#if ENREGISTERED_PARAMTYPE_MAXSIZE
- // Since we also do implict ByRef in some cases, we also have to probit the optimization there too
- TypeHandle argType = mSig.GetLastTypeHandleThrowing();
- if (Nullable::IsNullableType(argType))
- {
- if (ArgIterator::IsArgPassedByRef(argType))
- bOptimizable = FALSE;
- }
-#endif
- bCallArgsBlittable = FALSE;
- }
- else if (currType == ELEMENT_TYPE_R4 || currType == ELEMENT_TYPE_R8)
- {
- bArgsHaveAFloat = TRUE;
- }
- }
- }
-
-SetFlags:
- DWORD optimizationFlags = 0;
- if (!bOptimizable)
- {
- optimizationFlags |= XAD_NOT_OPTIMIZABLE;
- }
- else
- {
- optimizationFlags |= returnTypeFlags;
-
- if (bCallArgsBlittable)
- {
- optimizationFlags |= XAD_BLITTABLE_ARGS;
- }
- if (bRetArgBlittable)
- {
- optimizationFlags |= XAD_BLITTABLE_RET;
- }
- if (bMethodIsVirtual)
- {
- optimizationFlags |= XAD_METHOD_IS_VIRTUAL;
- }
- if (bArgsHaveAFloat)
- {
- optimizationFlags |= XAD_ARGS_HAVE_A_FLOAT;
- }
- }
- optimizationFlags |= numStackSlots;
- optimizationFlags |= XAD_FLAGS_INITIALIZED;
-
- return optimizationFlags;
-}
-
-#ifndef CROSSGEN_COMPILE
-
-BOOL RemotableMethodInfo::TypeIsConduciveToBlitting(MethodTable *pFromMT, MethodTable *pToMT)
-{
- LIMITED_METHOD_CONTRACT;
- // Presence of GC fields or certain atributes, rules out blittability
- if (pFromMT->CannotBeBlittedByObjectCloner() ||
- pToMT->CannotBeBlittedByObjectCloner())
- return FALSE;
-
- // Shared types are okay to blit
- if (pFromMT == pToMT)
- return TRUE;
-
- if (pFromMT->IsEnum() && pToMT->IsEnum()
- && pFromMT->GetBaseSize() == pToMT->GetBaseSize())
- return TRUE;
-
- return FALSE;
-}
-
-PtrHashMap *CrossDomainTypeMap::s_crossDomainMTMap = NULL;
-SimpleRWLock *CrossDomainTypeMap::s_MTMapLock = NULL;
-
-BOOL CrossDomainTypeMap::CompareMTMapEntry (UPTR val1, UPTR val2)
-{
- CONTRACTL {
- MODE_ANY;
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- CrossDomainTypeMap::MTMapEntry *entry1 = (CrossDomainTypeMap::MTMapEntry *)(val1 << 1);
- CrossDomainTypeMap::MTMapEntry *entry2 = (CrossDomainTypeMap::MTMapEntry *)val2;
-
- if (entry1->m_pFromMT == entry2->m_pFromMT &&
- entry1->m_dwFromDomain == entry2->m_dwFromDomain &&
- entry1->m_dwToDomain == entry2->m_dwToDomain)
- return TRUE;
-
- return FALSE;
-}
-
-CrossDomainTypeMap::MTMapEntry::MTMapEntry(AppDomain *pFromDomain, MethodTable *pFromMT, AppDomain *pToDomain, MethodTable *pToMT)
-{
- WRAPPER_NO_CONTRACT;
-
- m_dwFromDomain = pFromDomain->GetId();
- m_dwToDomain = pToDomain->GetId();
- m_pFromMT = pFromMT;
- m_pToMT = pToMT;
-}
-
-static BOOL IsOwnerOfRWLock(LPVOID lock)
-{
- // @TODO - SimpleRWLock does not have knowledge of which thread gets the writer
- // lock, so no way to verify
- return TRUE;
-}
-
-/*static*/
-PtrHashMap *CrossDomainTypeMap::GetTypeMap()
-{
- CONTRACTL
- {
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
-
- if (s_MTMapLock == NULL)
- {
- void *tempLockSpace = SystemDomain::GetGlobalLoaderAllocator()->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(SimpleRWLock)));
- SimpleRWLock *tempLock = new (tempLockSpace) SimpleRWLock(COOPERATIVE_OR_PREEMPTIVE, LOCK_TYPE_DEFAULT);
-
- if (FastInterlockCompareExchangePointer(&s_MTMapLock,
- tempLock,
- NULL) != NULL)
- {
- // We lost the race
- SystemDomain::GetGlobalLoaderAllocator()->GetLowFrequencyHeap()->BackoutMem(tempLockSpace, sizeof(SimpleRWLock));
- }
- }
-
- // Now we have a Crst we can use to synchronize the remainder of the init.
- if (s_crossDomainMTMap == NULL)
- {
- SimpleWriteLockHolder swlh(s_MTMapLock);
-
- if (s_crossDomainMTMap == NULL)
- {
- PtrHashMap *map = new (SystemDomain::GetGlobalLoaderAllocator()->GetLowFrequencyHeap()) PtrHashMap ();
- LockOwner lock = {s_MTMapLock, IsOwnerOfRWLock};
- map->Init (32, CompareMTMapEntry, TRUE, &lock);
- s_crossDomainMTMap = map;
- }
- }
-
- return s_crossDomainMTMap;
-}
-
-MethodTable *
-CrossDomainTypeMap::GetMethodTableForDomain(MethodTable *pMT, AppDomain *pFromDomain, AppDomain *pToDomain)
-{
- CONTRACTL
- {
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
- PtrHashMap *map = GetTypeMap();
-
- MTMapEntry admt(pFromDomain, pMT, pToDomain, NULL);
-
- SimpleReadLockHolder srlh(s_MTMapLock);
- MTMapEntry *pFound = (MTMapEntry *) map->LookupValue(admt.GetHash(), (LPVOID) &admt);
- if ((MTMapEntry *)INVALIDENTRY == pFound)
- return NULL;
-
- return pFound->m_pToMT;
-}
-
-void
-CrossDomainTypeMap::SetMethodTableForDomain(MethodTable *pFromMT, AppDomain *pFromDomain, MethodTable *pToMT, AppDomain *pToDomain)
-{
- CONTRACTL
- {
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
- PtrHashMap *map = GetTypeMap();
-
- NewHolder<MTMapEntry> admt(new MTMapEntry(pFromDomain, pFromMT, pToDomain, pToMT));
- PREFIX_ASSUME(admt != NULL);
-
- SimpleWriteLockHolder swlh(s_MTMapLock);
-
- UPTR key = admt->GetHash();
-
- MTMapEntry *pFound = (MTMapEntry *) map->LookupValue(key, (LPVOID) admt);
- if ((MTMapEntry *)INVALIDENTRY == pFound)
- {
- map->InsertValue(key, (LPVOID) admt);
- admt.SuppressRelease();
- }
-}
-
-// Remove any entries in the table that refer to an appdomain that is no longer live.
-void CrossDomainTypeMap::FlushStaleEntries()
-{
- CONTRACTL
- {
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- NOTHROW;
- }
- CONTRACTL_END
-
- if (s_MTMapLock == NULL || s_crossDomainMTMap == NULL)
- return;
-
- SimpleWriteLockHolder swlh(s_MTMapLock);
-
- bool fDeletedEntry = false;
- PtrHashMap::PtrIterator iter = s_crossDomainMTMap->begin();
- while (!iter.end())
- {
- MTMapEntry *pEntry = (MTMapEntry *)iter.GetValue();
- AppDomainFromIDHolder adFrom(pEntry->m_dwFromDomain, TRUE);
- AppDomainFromIDHolder adTo(pEntry->m_dwToDomain, TRUE);
- if (adFrom.IsUnloaded() ||
- adTo.IsUnloaded())
- {
-#ifdef _DEBUG
- LPVOID pDeletedEntry =
-#endif
- s_crossDomainMTMap->DeleteValue(pEntry->GetHash(), pEntry);
- _ASSERTE(pDeletedEntry == pEntry);
- delete pEntry;
- fDeletedEntry = true;
- }
- ++iter;
- }
-
- if (fDeletedEntry)
- s_crossDomainMTMap->Compact();
-}
-
-
-
-// Before a cross appdomain call, we read the principal on the thread and set it aside, so that it can
-// be restored when the call returns.
-// In addition, we let the principal flow thru to the called appdomain, if the principal is serializable
-OBJECTREF CrossDomainChannel::ReadPrincipal()
-{
- CONTRACTL
- {
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
-
- THREADBASEREF ref = (THREADBASEREF) GetThread()->GetExposedObjectRaw();
- _ASSERTE(ref != NULL);
-
- EXECUTIONCONTEXTREF refExecCtx = (EXECUTIONCONTEXTREF )ref->GetExecutionContext();
- if (refExecCtx == NULL)
- return NULL;
-
- LOGICALCALLCONTEXTREF refCallContext = refExecCtx->GetLogicalCallContext();
- if (refCallContext == NULL)
- return NULL;
-
- CCSECURITYDATAREF refSecurityData = refCallContext->GetSecurityData();
- if (refSecurityData == NULL)
- return NULL;
-
- OBJECTREF refPrincipal = refSecurityData->GetPrincipal();
- if (refPrincipal != NULL)
- {
- MethodTable *pPrincipalType = refPrincipal->GetMethodTable();
- if (!pPrincipalType->IsSerializable())
- {
- refSecurityData->SetPrincipal(NULL);
- }
- }
-
- return refPrincipal;
-}
-
-// Principal never flows from called appdomain back to caller domain.
-VOID CrossDomainChannel::ResetPrincipal()
-{
- CONTRACTL
- {
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
-
- THREADBASEREF ref = (THREADBASEREF) GetThread()->GetExposedObjectRaw();
- _ASSERTE(ref != NULL);
-
- EXECUTIONCONTEXTREF refExecCtx = (EXECUTIONCONTEXTREF )ref->GetExecutionContext();
- if (refExecCtx == NULL)
- return;
-
- LOGICALCALLCONTEXTREF refCallContext = refExecCtx->GetLogicalCallContext();
- if (refCallContext == NULL)
- return;
-
- CCSECURITYDATAREF refSecurityData = refCallContext->GetSecurityData();
- if (refSecurityData == NULL)
- return;
-
- refSecurityData->SetPrincipal(NULL);
-
-}
-
-// At the end of a cross-appdomain call, we restore whatever principal was on the thread at the beginning of the call
-VOID CrossDomainChannel::RestorePrincipal(OBJECTREF *prefPrincipal)
-{
- CONTRACTL
- {
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
-
- THREADBASEREF ref = (THREADBASEREF) GetThread()->GetExposedObjectRaw();
- if (ref == NULL)
- return;
-
- EXECUTIONCONTEXTREF refExecCtx = (EXECUTIONCONTEXTREF )ref->GetExecutionContext();
- _ASSERTE(*prefPrincipal == NULL || refExecCtx != NULL);
-
- if (refExecCtx == NULL)
- return;
-
- LOGICALCALLCONTEXTREF refCallContext = refExecCtx->GetLogicalCallContext();
- if (refCallContext == NULL)
- return;
-
- CCSECURITYDATAREF refSecurityData = refCallContext->GetSecurityData();
- _ASSERTE(*prefPrincipal == NULL || refSecurityData != NULL);
-
- if (refSecurityData == NULL)
- return;
-
- refSecurityData->SetPrincipal(*prefPrincipal);
-
-}
-
-// This method mimics the Lease renewal mechanism of the managed CrossDomainChannel
-// The lease object for the server can be accessed via its ServerIdentity.
-VOID CrossDomainChannel::RenewLease()
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
- // Check if lease needs to be renewed
- OBJECTREF refSrvIdentity = ObjectFromHandle(m_refSrvIdentity);
- if (refSrvIdentity == NULL)
- return;
-
- OBJECTREF refLease = ObjectToOBJECTREF((Object *)refSrvIdentity->GetPtrOffset(CRemotingServices::GetOffsetOfLeaseInIdentity()));
- if (refLease != NULL)
- {
- GCPROTECT_BEGIN(refLease);
- MethodDesc *pLeaseMeth = CRemotingServices::MDofRenewLeaseOnCall();
- PCODE pCode = (PCODE)pLeaseMeth->GetCallTarget(&refLease);
-
- PREPARE_NONVIRTUAL_CALLSITE_USING_CODE(pCode);
-
- DECLARE_ARGHOLDER_ARRAY(args, 2);
-
- args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(refLease);
- args[ARGNUM_1] = NULL;
-
- CATCH_HANDLER_FOUND_NOTIFICATION_CALLSITE;
- CALL_MANAGED_METHOD_NORET(args);
-
- GCPROTECT_END();
- }
-}
-
-// Given a client side instantiated method desc and a server side generic definition method desc extract the instantiation,
-// translate all the types involved into the server domain and return the fully instantiated server method desc. Note that the
-// client and server method descs might not represent the same type -- the client method might be from an interface, whereas the
-// server method will always be on the real class.
-MethodDesc *InstantiateMethod(MethodDesc *pClientMD, MethodDesc *pServerMD, MethodTable *pServerMT)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- PRECONDITION(CheckPointer(pClientMD));
- PRECONDITION(pClientMD->HasMethodInstantiation());
- PRECONDITION(CheckPointer(pServerMD));
- PRECONDITION(pServerMD->HasMethodInstantiation());
- PRECONDITION(pClientMD->GetNumGenericMethodArgs() == pServerMD->GetNumGenericMethodArgs());
- }
- CONTRACTL_END;
-
- Instantiation clientInst = pClientMD->GetMethodInstantiation();
-
- DWORD dwAllocaSize;
- if (!ClrSafeInt<DWORD>::multiply(clientInst.GetNumArgs(), sizeof(TypeHandle), dwAllocaSize))
- COMPlusThrowHR(COR_E_OVERFLOW);
-
- CQuickBytes qbServerInst;
- TypeHandle *pServerInst = reinterpret_cast<TypeHandle*>(qbServerInst.AllocThrows(dwAllocaSize));
-
- for (DWORD dwArgNum = 0; dwArgNum < clientInst.GetNumArgs(); dwArgNum++)
- {
- SString thName;
- TypeString::AppendType(thName, clientInst[dwArgNum], TypeString::FormatNamespace|TypeString::FormatFullInst|TypeString::FormatAssembly);
-
- pServerInst[dwArgNum] = TypeName::GetTypeFromAsmQualifiedName(thName.GetUnicode(), pClientMD->IsIntrospectionOnly());
-
- _ASSERTE(!pServerInst[dwArgNum].IsNull());
-
- // Check that the type is actually visible on the server side. This prevents a malicious client from luring a trusted server
- // into manipulating types that would be normally invisible to it.
- if (!pServerInst[dwArgNum].IsExternallyVisible())
- COMPlusThrow(kRemotingException, W("Remoting_NonPublicOrStaticCantBeCalledRemotely"));
- }
-
- // Find or create the method will the full instantiation.
- return MethodDesc::FindOrCreateAssociatedMethodDesc(pServerMD,
- pServerMT,
- FALSE,
- Instantiation(pServerInst, clientInst.GetNumArgs()),
- FALSE);
-}
-
-BOOL CrossDomainChannel::GetGenericMethodAddress(MethodTable *pServerType)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END;
-
- m_pSrvMD = InstantiateMethod(m_pCliMD, pServerType->GetMethodDescForSlot(m_pCliMD->GetSlot()), pServerType);
-
- OBJECTREF thisObj = GetServerObject();
- m_pTargetAddress = m_pSrvMD->GetCallTarget(&thisObj);
-
- return TRUE;
-}
-
-// We use this method to find the target address when we are convinced that the most derived type the proxy is cast
-// to on the client side is equivalent to the corresponding type on the server side, in the sense the method table
-// layouts are similar. This fact can be used to look up method addresses faster
-BOOL CrossDomainChannel::GetTargetAddressFast(DWORD optFlags, MethodTable *pSrvMT, BOOL bFindServerMD)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
- _ASSERTE(m_pCliMD);
- _ASSERTE(m_pSrvDomain == SystemDomain::GetCurrentDomain()->GetId());
-
- MethodTable *pCliMT = m_pCliMD->GetMethodTable();
- _ASSERTE(!pCliMT->IsInterface());
-
- m_pSrvMD = NULL;
-
- DWORD dwMethodSlot = m_pCliMD->GetSlot();
- if (!RemotableMethodInfo::IsMethodVirtual(m_xret))
- {
- // This is a non-virtual method. Find the matching MT on the
- // server side, dereference the slot and get the method address
-
- MethodTable *pSrvSideMT = pSrvMT;
-
- // We now need to walk the server type hierarchy till we find the type that
- // declared the method we're going to call
-
- // First find how far is the type declaring the called method, from System.Object
- DWORD cliDepth = 0;
- MethodTable *pCurrLevel = pCliMT;
- while (pCurrLevel != NULL)
- {
- _ASSERTE(pCurrLevel);
- pCurrLevel = pCurrLevel->GetParentMethodTable();
- cliDepth++;
- };
-
- // Next find how deep is the server type from System.Object
- DWORD srvDepth = 0;
- pCurrLevel = pSrvMT;
- while (pCurrLevel != NULL)
- {
- _ASSERTE(pCurrLevel);
- pCurrLevel = pCurrLevel->GetParentMethodTable();
- srvDepth++;
- };
-
- _ASSERTE(srvDepth >= cliDepth);
-
- while (srvDepth > cliDepth)
- {
- _ASSERTE(pSrvSideMT);
- _ASSERTE(srvDepth != 0);
- pSrvSideMT = pSrvSideMT->GetParentMethodTable();
- srvDepth--;
- };
-
- if (m_pCliMD->HasMethodInstantiation())
- {
- GetGenericMethodAddress(pSrvSideMT);
- }
- else
- {
- m_pTargetAddress = pSrvSideMT->GetRestoredSlot(dwMethodSlot);
-
-#ifndef _DEBUG
- if (bFindServerMD)
-#endif
- m_pSrvMD = pSrvSideMT->GetMethodDescForSlot(dwMethodSlot);
- }
- }
- else
- {
- if (m_pCliMD->HasMethodInstantiation())
- GetGenericMethodAddress(pSrvMT);
- else
- {
- m_pTargetAddress = pSrvMT->GetRestoredSlot(dwMethodSlot);
-
-#ifndef _DEBUG
- if (bFindServerMD)
-#endif
- m_pSrvMD = pSrvMT->GetMethodDescForSlot(dwMethodSlot);
- }
- }
-
- _ASSERTE(m_pTargetAddress);
-#ifdef _DEBUG
- _ASSERTE(!strcmp(m_pSrvMD->GetName(), m_pCliMD->GetName()));
- DefineFullyQualifiedNameForClass();
- LPCUTF8 szSrvTypeName = GetFullyQualifiedNameForClassNestedAware(pSrvMT);
- LPCUTF8 pszMethodName = m_pCliMD->GetName();
- LOG((LF_REMOTING, LL_INFO100, "GetTargetAddressFast. Address of %s::%s is 0x%x\n", &szSrvTypeName[0], pszMethodName, m_pTargetAddress));
-#endif // _DEBUG
- return TRUE;
-}
-
-BOOL
-CrossDomainChannel::GetInterfaceMethodAddressFast(DWORD optFlags, MethodTable *pSrvMT, BOOL bFindServerMD)
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- _ASSERTE(m_pCliMD);
-
- MethodTable *pCliItfMT = m_pCliMD->GetMethodTable();
- _ASSERTE(pCliItfMT->IsInterface());
-
- // Only use the fast path if the interface is shared. If the interface isnt shared, then we'll have to search the
- // interface map on server type using name as key and then deref the slot # etc. I think shared interfaces will
- // be the common pattern. If not they should be.
- // Note that it's not enough to check that the client interface is shared, it must also be loaded in the server appdomain (since
- // it's now possible to have more than one instance of a shared assembly in a process).
- _ASSERTE(pCliItfMT->IsDomainNeutral());
- AppDomain* ad = SystemDomain::GetAppDomainFromId(m_pSrvDomain,ADV_RUNNINGIN);
- if (ad->FindDomainAssembly(pCliItfMT->GetAssembly()) == NULL)
- return FALSE;
-
- m_pSrvMD = NULL;
-
- OBJECTREF thisObj = GetServerObject();
-
-#ifdef FEATURE_COMINTEROP
- // Check for a COM interop server.
- if (thisObj->GetMethodTable()->IsComObjectType())
- {
-#if 0
- // We don't have all the logic in place to deal with COM interop yet. The following code is taken from the regular remoting
- // invocation path in CStackBuilderSink::PrivateProcessMessage, but I think we still need some work on the actual invocation
- // itself (leastways we didn't end up invoking the method correctly when I tried it).
- // For now we'll just bail back to the regular remoting path for COM interop.
- m_pSrvMD = thisObj->GetMethodTable()->GetMethodDescForComInterfaceMethod(m_pCliMD, false);
- if (m_pSrvMD == NULL)
- return FALSE;
-#endif
- return FALSE;
- }
-#endif // FEATURE_COMINTEROP
-
- GCPROTECT_BEGIN(thisObj);
-
- DispatchSlot impl(pSrvMT->FindDispatchSlotForInterfaceMD(m_pCliMD));
- CONSISTENCY_CHECK(!impl.IsNull());
- m_pSrvMD = impl.GetMethodDesc();
-
- _ASSERTE(m_pSrvMD);
-
- // If the method called has a generic instantiation then the server method desc we've just received doesn't contain that
- // information (generic method slots are filled with generic definition method descs). We need to build the exact method desc by
- // copying the instantiation from the client method (translating each type into the new domain of course).
- if (m_pSrvMD->HasMethodInstantiation())
- m_pSrvMD = InstantiateMethod(m_pCliMD, m_pSrvMD, pSrvMT);
-
- m_pTargetAddress = m_pSrvMD->GetCallTarget(&thisObj);
-
- GCPROTECT_END();
-
- return TRUE;
-}
-
-
-// Here we check whether the remote call is a cross domain call, if so, does it qualify
-BOOL
-CrossDomainChannel::CheckCrossDomainCall(TPMethodFrame *pFrame)
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- m_pFrame = pFrame;
- m_pCliMD = m_pFrame->GetFunction();
-
- MethodTable *pCliMT = m_pCliMD->GetMethodTable();
-
- // Check if this is an async delegate call
- if (pCliMT->IsDelegate())
- return FALSE;
-
- // Only use the fast path if the interface is shared. If the interface isnt shared, then we'll have to search the
- // interface map on server type using name as key and then deref the slot # etc. I think shared interfaces will
- // be the common pattern.
- if (pCliMT->IsInterface() && !pCliMT->IsDomainNeutral())
- return FALSE;
-
- OBJECTREF refTP = pFrame->GetThis();
- REALPROXYREF refRP = CTPMethodTable::GetRP(refTP);
-
- // Check if this is a x-domain call
- DWORD domainID = refRP->GetDomainID();
- if (domainID == 0)
- return FALSE; // Not x-appdomain call, or proxy not initted for optimization
-
- // Check if we are in a context different from default. If so, we may need to run context
- // policies etc. Use regular path.
- if (GetThread()->GetContext() != SystemDomain::GetCurrentDomain()->GetDefaultContext())
- return FALSE;
-
- // Check if method call args can be blitted (or not optimizable at all)
- m_xret = RemotableMethodInfo::IsCrossAppDomainOptimizable(m_pCliMD, &m_numStackSlotsToCopy);
- if (RemotableMethodInfo::IsCallNotOptimizable(m_xret))
- {
-#ifdef _DEBUG
- DefineFullyQualifiedNameForClass();
- LPCUTF8 szSrvTypeName = GetFullyQualifiedNameForClassNestedAware(m_pCliMD->GetMethodTable());
- LOG((LF_REMOTING, LL_INFO100, "CheckCrossDomainCall. Call to %s::%s is not optimizable\n",
- &szSrvTypeName[0], m_pCliMD->GetName()));
-#endif // _DEBUG
- return FALSE;
- }
-
- m_pCliDomain = SystemDomain::GetCurrentDomain();
- m_pSrvDomain = ADID(domainID);
-
- return ExecuteCrossDomainCall();
-}
-
-// Dereference the server identity handle, to reach the server object
-// If the handle is null, someone either called Disconnect on the server
-// or the server's lease ran out
-OBJECTREF CrossDomainChannel::GetServerObject()
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- THROWS;
- GC_TRIGGERS;
- }
- CONTRACTL_END
-
- _ASSERTE(m_pSrvDomain == SystemDomain::GetCurrentDomain()->GetId());
-
- OBJECTREF refSrvIdentity = ObjectFromHandle(m_refSrvIdentity);
- if (refSrvIdentity == NULL)
- {
- OBJECTREF refTP = m_pFrame->GetThis();
- REALPROXYREF refRP = CTPMethodTable::GetRP(refTP);
- OBJECTREF refIdentity = ObjectToOBJECTREF((Object *)refRP->GetPtrOffset(CRemotingServices::GetOffsetOfCliIdentityInRP()));
- STRINGREF refURI = (STRINGREF)ObjectToOBJECTREF((Object *)refIdentity->GetPtrOffset(CRemotingServices::GetOffsetOfURIInIdentity()));
- SString sURI;
- refURI->GetSString(sURI);
-
- COMPlusThrow(kRemotingException,
- IDS_REMOTING_SERVER_DISCONNECTED,
- sURI.GetUnicode());
- }
- OBJECTREF srvObject = ObjectToOBJECTREF((Object *)refSrvIdentity->GetPtrOffset(CRemotingServices::GetOffsetOfTPOrObjInIdentity()));
- return srvObject;
-}
-
-// Here the we find the target method address, make a decision whether to
-// execute the call locally, if remote whether to blit the arguments or to marshal them,
-BOOL CrossDomainChannel::ExecuteCrossDomainCall()
-{
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_MODE_COOPERATIVE;
-
- BOOL bOptimizable = TRUE;
-
- {
- ProfilerRemotingClientCallbackHolder profilerHolder;
-
- // Short circuit calls to Object::GetType and run them locally
- if (m_pCliMD == CRemotingServices::MDofObjectGetType())
- {
- LOG((LF_REMOTING, LL_INFO100, "ExecuteCrossDomainCall. Short circuiting call to Object::GetType and running it locally.\n"));
- OBJECTREF refTP = m_pFrame->GetThis();
- OBJECTREF refType = CRemotingServices::GetClass(refTP);
- LPVOID pReturnValuePtr = m_pFrame->GetReturnValuePtr();
- *(Object **)pReturnValuePtr = OBJECTREFToObject(refType);
- }
- else if (RemotableMethodInfo::AreArgsBlittable(m_xret))
- {
- bOptimizable = BlitAndCall();
- }
- else
- {
- bOptimizable = MarshalAndCall();
- }
- }
-
- if (!bOptimizable)
- return FALSE;
-
- // Check for the need to trip thread
- if (GetThread()->CatchAtSafePointOpportunistic())
- {
- // There is no need to GC protect the return object as
- // TPFrame is GC protecting it
- CommonTripThread();
- }
-
-#ifdef _TARGET_X86_
- // Set the number of bytes to pop for x86
- m_pFrame->SetCbStackPop(m_numStackSlotsToCopy * sizeof(SIZE_T));
-#endif // _TARGET_X86_
-
- return TRUE;
-}
-
-BOOL
-CrossDomainChannel::InitServerInfo()
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- THROWS;
- GC_TRIGGERS;
- }
- CONTRACTL_END
-
- _ASSERTE(m_pFrame);
- _ASSERTE(m_pSrvDomain == SystemDomain::GetCurrentDomain()->GetId());
-
- // Get the server object
- OBJECTREF refTP = m_pFrame->GetThis();
- REALPROXYREF refRP = CTPMethodTable::GetRP(refTP);
- m_refSrvIdentity = (OBJECTHANDLE)refRP->GetPtrOffset(CRemotingServices::GetOffsetOfSrvIdentityInRP());
- OBJECTREF srvObject = GetServerObject();
-
- MethodTable *pSrvMT = srvObject->GetMethodTable();
-
- // Find the target address
- DWORD optFlag = refRP->GetOptFlags();
-
- // If we are cloning some arguments to server domain, we want to do a type check
- // on the cloned objects against the expected type. To find the expected type, we need to
- // know the method signature on the server side, which in turn is obtainable if we know
- // the server MethodDesc. Finding MethodDesc from a slot isnt cheap, so we do it only if we need it
- BOOL bFindServerMD = (RemotableMethodInfo::AreArgsBlittable(m_xret)) ? FALSE : TRUE;
- BOOL bResultOfAddressLookup = FALSE;
-
- if (m_pCliMD->GetMethodTable()->IsInterface())
- {
- bResultOfAddressLookup = GetInterfaceMethodAddressFast(optFlag, pSrvMT, bFindServerMD);
- }
- else if ((optFlag & OPTIMIZATION_FLAG_INITTED) && (optFlag & OPTIMIZATION_FLAG_PROXY_EQUIVALENT))
- {
- bResultOfAddressLookup = GetTargetAddressFast(optFlag, pSrvMT, bFindServerMD);
- }
- else
- {
- // If the proxy is not cast to an equivalent type, do not perform any optimizations
- bResultOfAddressLookup = FALSE;
- }
-
-#ifdef _DEBUG
- if (!bResultOfAddressLookup)
- LOG((LF_REMOTING, LL_INFO100, "InitServerInfo. Skipping fast path because failed to find target address.\n"));
-#endif // _DEBUG
-
- _ASSERTE(!bResultOfAddressLookup || !bFindServerMD || m_pSrvMD);
- return bResultOfAddressLookup;
-}
-
-// A macro used to help calculate the exact declaring type of a method (this may not be as simple as calling GetMethodTable on the
-// method desc if the type is generic and not an interface). We get the additional information from the instance (which provides an
-// exact method table, though not necessarily the one the method is actually _declared_ on). We don't compute the instance or the
-// method table from that instance in this macro since the logic varies greatly from client to server (the client has to adjust for
-// the fact that the instance is a TP).
-// We assume a variable called thDeclaringType has already been declared in the current scope.
-#define CDC_DETERMINE_DECLARING_TYPE(_pMD, _thInst) \
- if (!(_pMD)->HasClassInstantiation() || (_pMD)->IsInterface()) \
- { \
- thDeclaringType = TypeHandle((_pMD)->GetMethodTable()); \
- } \
- else \
- { \
- Instantiation inst = (_pMD)->GetExactClassInstantiation(_thInst); \
- MethodTable *pApproxDeclaringMT = (_pMD)->GetMethodTable(); \
- thDeclaringType = ClassLoader::LoadGenericInstantiationThrowing(pApproxDeclaringMT->GetModule(), \
- pApproxDeclaringMT->GetCl(), \
- inst); \
- }
-
-// We have decided the arguments are blittable. We may still need to marshal
-// call context if any.
-BOOL
-CrossDomainChannel::BlitAndCall()
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
-
- SIZE_T *pRegArgs = NULL;
- SIZE_T *pStackArgs = NULL;
-#ifdef CALLDESCR_ARGREGS
- ArgumentRegisters RegArgs = {0};
- pRegArgs = (SIZE_T*)&RegArgs;
-#endif
-#ifdef CALLDESCR_FPARGREGS
- FloatArgumentRegisters *pFloatArgumentRegisters = NULL;
-#endif
-
- BOOL bOptimizable = TRUE;
- BOOL bHasObjRefReturnVal = FALSE;
-
- Thread *pCurThread = GetThread();
-
-#ifdef _DEBUG
- LPCUTF8 pszMethodName;
- pszMethodName = m_pCliMD->GetName();
- LOG((LF_REMOTING, LL_INFO100, "BlitAndCall. Blitting arguments to method %s\n", pszMethodName));
-#endif // _DEBUG
-
- // Collect all client domain GC references together in a single GC frame.
- // refReturnValue contains the returned object.
- // It can also contain a boxed object when the return is a value type and needs marshalling
- struct _gc {
- OBJECTREF refReturnValue;
- OBJECTREF refException;
- OBJECTREF refExecutionContext;
- OBJECTREF refPrincipal;
- } ClientGC;
- ZeroMemory(&ClientGC, sizeof(ClientGC));
- GCPROTECT_BEGIN(ClientGC);
-
- _ASSERTE(RemotableMethodInfo::IsReturnBlittable(m_xret));
-
- // Check for any logical call context that contains data
- BOOL bMarshalCallContext = FALSE;
- BOOL bMarshalReturnCallContext = FALSE;
- if (pCurThread->IsExposedObjectSet())
- {
- THREADBASEREF ref = (THREADBASEREF) pCurThread->GetExposedObjectRaw();
- _ASSERTE(ref != NULL);
-
- EXECUTIONCONTEXTREF refExecCtx = (EXECUTIONCONTEXTREF) ref->GetExecutionContext();
- if (refExecCtx != NULL)
- {
- ClientGC.refExecutionContext = refExecCtx;
- ClientGC.refPrincipal = ReadPrincipal();
-
- LOGICALCALLCONTEXTREF refLogCallCtx = refExecCtx->GetLogicalCallContext();
- if (refLogCallCtx != NULL)
- {
- if (refLogCallCtx->ContainsDataForSerialization())
- {
- bMarshalCallContext = TRUE;
- }
- }
- }
- }
-
-#ifdef FEATURE_CORRUPTING_EXCEPTIONS
- // Assume that exception at server was NotCorrupting
- CorruptionSeverity severity = NotCorrupting;
-#endif // FEATURE_CORRUPTING_EXCEPTIONS
-
- // Push the frame
- ENTER_DOMAIN_ID(m_pSrvDomain);
-
- // Now create a server domain GC frame for all server side GC references.
- struct _gc {
- OBJECTREF refReturnValue;
- OBJECTREF refException;
- OBJECTREF refExecutionContext;
- } ServerGC;
- ZeroMemory(&ServerGC, sizeof(ServerGC));
- GCPROTECT_BEGIN(ServerGC);
-
- // Initialize server side info, such as method address etc
- bOptimizable = InitServerInfo();
-
- if (!bOptimizable)
- goto LeaveDomain;
-
- RenewLease();
-
- if (bMarshalCallContext)
- {
- LOG((LF_REMOTING, LL_INFO100, "BlitAndCall. Marshalling call context\n", pszMethodName));
- CrossAppDomainClonerCallback cadcc;
- ObjectClone Marshaller(&cadcc, CrossAppDomain, FALSE);
- ServerGC.refExecutionContext = Marshaller.Clone(ClientGC.refExecutionContext,
- m_pCliDomain,
- GetAppDomain(),
- ClientGC.refExecutionContext);
- THREADBASEREF ref = (THREADBASEREF) pCurThread->GetExposedObjectRaw();
- _ASSERTE(ref != NULL);
-
- ref->SetExecutionContext(ServerGC.refExecutionContext);
-
- Marshaller.RemoveGCFrames();
- }
- else if (pCurThread->IsExposedObjectSet())
- {
- THREADBASEREF ref = (THREADBASEREF) pCurThread->GetExposedObjectRaw();
- _ASSERTE(ref != NULL);
-
- ref->SetExecutionContext(NULL);
- }
-
-#ifdef PROFILING_SUPPORTED
- // If we're profiling, notify the profiler that we're about to invoke the remoting target
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackRemoting());
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->RemotingServerInvocationStarted();
- END_PIN_PROFILER();
- }
-#endif // PROFILING_SUPPORTED
-
- {
- GCX_COOP();
- UINT64 uRegTypeMap = 0;
- pStackArgs = (SIZE_T *)(m_pFrame->GetTransitionBlock() + TransitionBlock::GetOffsetOfArgs());
-
- // Get the 'this' object
- OBJECTREF srvObject = GetServerObject();
-
-#if defined(_TARGET_X86_)
- pRegArgs[0] = *((SIZE_T*)(m_pFrame->GetTransitionBlock() + TransitionBlock::GetOffsetOfArgumentRegisters()));
- pRegArgs[1] = (SIZE_T) OBJECTREFToObject(srvObject);
-#elif defined(CALLDESCR_ARGREGS)
- // Have to buffer argument registers since we're going to overwrite the this object with the server
- // version and the frame owning the registers is in the wrong domain to report that object.
- pRegArgs[0] = (SIZE_T) OBJECTREFToObject(srvObject);
- memcpy(pRegArgs + 1,
- (SIZE_T*)(m_pFrame->GetTransitionBlock() + TransitionBlock::GetOffsetOfArgumentRegisters()) + 1,
- sizeof(ArgumentRegisters) - sizeof(SIZE_T));
-
-#ifdef CALLDESCR_FPARGREGS
- // Only provide a pointer to the floating point area of the stack frame if there any any floating
- // point arguments (passing NULL optimizes the CallDescr thunk by omitting the initialization of
- // floating point argument registers).
- if (RemotableMethodInfo::DoArgsContainAFloat(m_xret))
- pFloatArgumentRegisters = (FloatArgumentRegisters*)(m_pFrame->GetTransitionBlock() + TransitionBlock::GetOffsetOfFloatArgumentRegisters());
-#endif // CALLDESCR_FPARGREGS
-
-#else // CALLDESCR_ARGREGS
-
- // It's a pity that we have to allocate a buffer for the arguments on the stack even in BlitAndCall().
- // The problem is we can't use the portion of the stack protected by m_pFrame to store the srvObject,
- // since the srvObject is in the server domain and the TPMethodFrame m_pFrame is in the client domain.
- // I don't think we need to protect the srvOjbect in this case, since it's reachable from the transparent
- // proxy, which is protected by the TPMethodFrame.
- SIZE_T* pTmpStackArgs = (SIZE_T*)_alloca(m_numStackSlotsToCopy * sizeof(SIZE_T));
- memcpy(pTmpStackArgs, pStackArgs, m_numStackSlotsToCopy * sizeof(SIZE_T));
- pStackArgs = pTmpStackArgs;
-
- pStackArgs[0] = (SIZE_T)OBJECTREFToObject(srvObject);
-#endif // CALLDESCR_ARGREGS
-
-#if defined(CALLDESCR_REGTYPEMAP) || defined(COM_STUBS_SEPARATE_FP_LOCATIONS)
- // We have to copy the floating point registers from a different stack location to the portion of
- // the stack used to save the general registers. Since this is expensive, we only do this if
- // we have some floating point arguments.
- if (RemotableMethodInfo::DoArgsContainAFloat(m_xret))
- {
- // When computing the method signature we need to take special care if the call is on a non-interface class with a
- // generic instantiation (since in that case we may have a representative method with a non-concrete signature).
- TypeHandle thDeclaringType;
- CDC_DETERMINE_DECLARING_TYPE(m_pCliMD, TypeHandle(CTPMethodTable::GetMethodTableBeingProxied(m_pFrame->GetThis())));
- MetaSig mSig(m_pCliMD, thDeclaringType);
- ArgIterator argit(&mSig);
-
- int offset;
- while (TransitionBlock::InvalidOffset != (offset = argit.GetNextOffset()))
- {
- int regArgNum = TransitionBlock::GetArgumentIndexFromOffset(offset);
-
- if (regArgNum >= NUM_ARGUMENT_REGISTERS)
- break;
-
- CorElementType argTyp = argit.GetArgType();
-
-#ifdef CALLDESCR_REGTYPEMAP
- FillInRegTypeMap(offset, argTyp, (BYTE*)&uRegTypeMap);
-#endif
-
-#ifdef COM_STUBS_SEPARATE_FP_LOCATIONS
- if (argTyp == ELEMENT_TYPE_R4 || argTyp == ELEMENT_TYPE_R8)
- {
- PVOID pSrc = (PVOID)(m_pFrame->GetTransitionBlock() + m_pFrame->GetFPArgOffset(regArgNum));
-
- ARG_SLOT val;
- if (argTyp == ELEMENT_TYPE_R4)
- val = FPSpillToR4(pSrc);
- else
- val = FPSpillToR8(pSrc);
-
- *(ARG_SLOT*)(&pStackArgs[regArgNum]) = val;
- }
-#endif
- }
- }
-#endif // CALLDESCR_REGTYPEMAP || COM_STUBS_SEPARATE_FP_LOCATIONS
-
- CallDescrData callDescrData;
-
- callDescrData.pSrc = pStackArgs;
- callDescrData.numStackSlots = m_numStackSlotsToCopy,
-#ifdef CALLDESCR_ARGREGS
- callDescrData.pArgumentRegisters = (ArgumentRegisters *)pRegArgs;
-#endif
-#ifdef CALLDESCR_FPARGREGS
- callDescrData.pFloatArgumentRegisters = pFloatArgumentRegisters;
-#endif
-#ifdef CALLDESCR_REGTYPEMAP
- callDescrData.dwRegTypeMap = uRegTypeMap;
-#endif
- callDescrData.fpReturnSize = GetFPReturnSize();
- callDescrData.pTarget = m_pTargetAddress;
-
- DispatchCall(
- &callDescrData,
- &ServerGC.refException,
- GET_CTX_TRANSITION_FRAME()
- COMMA_CORRUPTING_EXCEPTIONS_ONLY(&severity)
- );
-
- // If the return value is a GC ref, store it in a protected place
- if (ServerGC.refException != NULL)
- {
- // Return value is invalid if there was exception thrown
- }
- else
- if (RemotableMethodInfo::IsReturnGCRef(m_xret))
- {
- ServerGC.refReturnValue = ObjectToOBJECTREF(*(Object **)(&callDescrData.returnValue));
- bHasObjRefReturnVal = TRUE;
- }
- else
- {
- memcpyNoGCRefs(m_pFrame->GetReturnValuePtr(), &callDescrData.returnValue, sizeof(callDescrData.returnValue));
- }
- }
-
-#ifdef PROFILING_SUPPORTED
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackRemoting());
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->RemotingServerInvocationReturned();
- END_PIN_PROFILER();
- }
-#endif // PROFILING_SUPPORTED
-
- // Propagate any logical call context changes except those to the principal
- if (pCurThread->IsExposedObjectSet())
- {
- THREADBASEREF ref = (THREADBASEREF) pCurThread->GetExposedObjectRaw();
- _ASSERTE(ref != NULL);
-
- EXECUTIONCONTEXTREF refExecCtx = (EXECUTIONCONTEXTREF) ref->GetExecutionContext();
- if (refExecCtx != NULL)
- {
- LOGICALCALLCONTEXTREF refLogCallCtx = refExecCtx->GetLogicalCallContext();
- if (bMarshalCallContext ||
- (refLogCallCtx != NULL && refLogCallCtx->ContainsNonSecurityDataForSerialization()))
- {
- ServerGC.refExecutionContext = ref->GetExecutionContext();
- bMarshalReturnCallContext = TRUE;
- LOG((LF_REMOTING, LL_INFO100, "BlitAndCall. Marshalling return call context\n", pszMethodName));
- CrossAppDomainClonerCallback cadcc;
- ObjectClone Marshaller(&cadcc, CrossAppDomain, FALSE);
-
- ResetPrincipal();
-
- EXECUTIONCONTEXTREF ecref = (EXECUTIONCONTEXTREF)Marshaller.Clone(ServerGC.refExecutionContext,
- GetAppDomain(),
- m_pCliDomain,
- ServerGC.refExecutionContext);
- if (ClientGC.refExecutionContext != NULL)
- ((EXECUTIONCONTEXTREF)ClientGC.refExecutionContext)->SetLogicalCallContext(ecref->GetLogicalCallContext());
- else
- ClientGC.refExecutionContext = (OBJECTREF)ecref;
-
- Marshaller.RemoveGCFrames();
- }
- }
- }
-
- if (ServerGC.refException != NULL)
- {
- LOG((LF_REMOTING, LL_INFO100, "BlitAndCall. Exception thrown ! Marshalling exception. \n", pszMethodName));
-
- // Save Watson buckets before the exception object is changed
- if (GetThread() != NULL)
- {
- // Ensure that we have the buckets for the exception in question.
- // For preallocated exceptions, we capture the buckets in the
- // UE WatsonBucket Tracker in AppDomainTransitionExceptionFilter.
- //
- // When the exception is reraised in the returning AppDomain,
- // StackTraceInfo::AppendElement will copy over the buckets
- // to the EHtracker corresponding to the raised exception.
- if (!CLRException::IsPreallocatedExceptionObject(ServerGC.refException))
- {
- // For non-preallocated exception objects, the throwable
- // is expected have the buckets in it, assuming that
- // CLR's personality routine for managed code was notified
- // of the exception before returning from the AD transition.
- //
- // There are scenarios where few managed frames, post AD transition,
- // may get optimized away by the JIT. If a managed exception is
- // thrown from within the VM at a later time, the personality routine
- // for managed will not be invoked if there are no managed frames present
- // between the AD Transition frame and the frame where VM raised the managed
- // exception.
- //
- // When such an exception comes back to the calling AppDomain, we will
- // come here and look for watson buckets and may not find them. In such
- // a case, simply log it.
- if(!((EXCEPTIONREF)ServerGC.refException)->AreWatsonBucketsPresent())
- {
- LOG((LF_EH, LL_INFO100, "CrossDomainChannel::BlitAndCall: Watson buckets not found in regular exception object. Exception likely raised in native code.\n"));
- }
- }
- }
-
- CrossAppDomainClonerCallback cadcc;
- ObjectClone Marshaller(&cadcc, CrossAppDomain, FALSE);
- ClientGC.refException = Marshaller.Clone(ServerGC.refException, GetAppDomain(), m_pCliDomain, ServerGC.refExecutionContext);
-
- Marshaller.RemoveGCFrames();
-
- // We have to be in the right domain before we throw the exception
- goto LeaveDomain;
- }
-
- if (bHasObjRefReturnVal)
- {
- // Must be a domain agile GC ref. We can just copy the reference into the client GC frame.
- ClientGC.refReturnValue = ServerGC.refReturnValue;
- }
-
-LeaveDomain: ;
-
- GCPROTECT_END(); // ServerGC
-
- END_DOMAIN_TRANSITION;
-
- if (ClientGC.refException != NULL)
- {
- RestorePrincipal(&ClientGC.refPrincipal);
- COMPlusThrow(ClientGC.refException
- COMMA_CORRUPTING_EXCEPTIONS_ONLY(severity)
- );
- }
-
- if (pCurThread->IsExposedObjectSet())
- {
- THREADBASEREF ref = (THREADBASEREF) pCurThread->GetExposedObjectRaw();
- _ASSERTE(ref != NULL);
-
- ref->SetExecutionContext(ClientGC.refExecutionContext);
- }
-
- RestorePrincipal(&ClientGC.refPrincipal);
-
- // If the return type is an object, take it out of the protected ref
- if (bHasObjRefReturnVal)
- {
- *(Object **)m_pFrame->GetReturnValuePtr() = OBJECTREFToObject(ClientGC.refReturnValue);
- }
-
- GCPROTECT_END(); // ClientGC
-
- return bOptimizable;
-}
-
-// Argument attributes
-#define ARG_NEEDS_UNBOX 0x80000000
-#define ARG_GOES_IN_EDX 0x40000000
-#define ARG_IS_BYREF 0x20000000
-#define ARG_OFFSET_MASK 0x00FFFFFF
-
-// Structure to hold arguments for MarshalAndCall
-struct MarshalAndCallArgs : public CtxTransitionBaseArgs
-{
- MarshalAndCallArgs() : Marshaller(&cadcc, CrossAppDomain, FALSE)
- {
- STATIC_CONTRACT_SO_INTOLERANT;
- }
-
- CrossDomainChannel * pThis;
-
- struct _gc {
- OBJECTREF refReturnValue;
- OBJECTREF refException;
- OBJECTREF refExecutionContext;
- OBJECTREF refPrincipal;
- } ClientGC;
-
- BOOL bOptimizable;
-
- ObjectClone Marshaller;
- CrossAppDomainClonerCallback cadcc;
-
- MetaSig *mSig;
- ArgIterator *argit;
-
- DWORD dwNumArgs;
-#ifdef CALLDESCR_ARGREGS
- SIZE_T *pRegArgs;
-#endif
-#ifdef CALLDESCR_FPARGREGS
- FloatArgumentRegisters *pFloatArgumentRegisters;
-#endif
- SIZE_T *pStackArgs;
- DWORD *pArgAttribs;
-
- DWORD dwNumObjectsMarshalled;
- BOOL *bMarshalledArgs;
- OBJECTREF *pClientArgArray;
-
- BOOL bHasByRefArgsToMarshal;
- int *pByRefArgAttribs;
- TypeHandle *pThByRefs;
-
- TypeHandle retTh;
- BOOL bHasObjRefReturnVal;
- BOOL bHasRetBuffArg;
- BOOL bHasValueTypeReturnValToMarshal;
-
- BOOL bMarshalCallContext;
- BOOL bMarshalReturnCallContext;
-
-#ifdef CALLDESCR_REGTYPEMAP
- UINT64 uRegTypeMap;
-#endif
-
-#ifdef FEATURE_CORRUPTING_EXCEPTIONS
- CorruptionSeverity severity;
-#endif // FEATURE_CORRUPTING_EXCEPTIONS
-};
-
-// Simple wrapper to go from C to C++.
-void MarshalAndCall_Wrapper2(MarshalAndCallArgs * pArgs)
-{
- WRAPPER_NO_CONTRACT;
-
- pArgs->pThis->MarshalAndCall_Wrapper(pArgs);
-}
-
-void CrossDomainChannel::MarshalAndCall_Wrapper(MarshalAndCallArgs * pArgs)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END;
-
- // Set up a rip-cord that will immediately stop us reporting GC references we're keeping alive in the Marshaller that was passed
- // to us in the event that this appdomain is unloaded underneath our feet. This avoids us keeping any server objects alive after
- // their domain has unloaded.
- ReportClonerRefsHolder sHolder(&pArgs->Marshaller);
-
- Thread* pCurThread = GetThread();
- AppDomain* pCurAppDomain = GetAppDomain();
-
- // Now create a server domain GC frame for all non-arg server side GC references.
- struct _gc {
- OBJECTREF refReturnValue;
- OBJECTREF refException;
- OBJECTREF refExecutionContext;
- } ServerGC;
- ZeroMemory(&ServerGC, sizeof(ServerGC));
- GCPROTECT_BEGIN(ServerGC);
-
- // And a variable sized array and frame of marshaled arg GC references.
- OBJECTREF *pServerArgArray = NULL;
- pServerArgArray = (OBJECTREF *) _alloca(pArgs->dwNumObjectsMarshalled * sizeof(OBJECTREF));
- ZeroMemory(pServerArgArray, sizeof(OBJECTREF) * pArgs->dwNumObjectsMarshalled);
-
- TypeHandle* pServerArgTH = (TypeHandle *) _alloca(pArgs->dwNumObjectsMarshalled * sizeof(TypeHandle));
- GCPROTECT_ARRAY_BEGIN(pServerArgArray[0], pArgs->dwNumObjectsMarshalled);
-
- // Initialize server side info, such as method address etc
- pArgs->bOptimizable = InitServerInfo();
-
- if (!pArgs->bOptimizable)
- goto LeaveDomain;
-
- RenewLease();
-
- // First clone objref arguments into the called domain
- if (!RemotableMethodInfo::AreArgsBlittable(m_xret))
- {
- // When computing the method signature we need to take special care if the call is on a non-interface class with a
- // generic instantiation (since in that case we may have a representative method with a non-concrete signature).
- TypeHandle thDeclaringType;
- CDC_DETERMINE_DECLARING_TYPE(m_pSrvMD, TypeHandle(GetServerObject()->GetTypeHandle()));
- MetaSig mSrvSideSig(m_pSrvMD, thDeclaringType);
- DWORD dwMarshalledArg = 0;
- for (DWORD i = 0; i < pArgs->dwNumArgs; i++)
- {
- CorElementType cType = mSrvSideSig.NextArg();
- if (pArgs->bMarshalledArgs[i] != TRUE)
- {
- // Make sure argument type is loaded
- if (cType == ELEMENT_TYPE_VALUETYPE)
- {
- mSrvSideSig.GetLastTypeHandleThrowing();
- }
- continue;
- }
-
- TypeHandle argTh;
- if (cType == ELEMENT_TYPE_BYREF)
- mSrvSideSig.GetByRefType(&argTh);
- else
- argTh = mSrvSideSig.GetLastTypeHandleThrowing();
-
- pServerArgTH[dwMarshalledArg] = argTh;
- pServerArgArray[dwMarshalledArg] = pArgs->Marshaller.Clone(pArgs->pClientArgArray[dwMarshalledArg],
- argTh,
- m_pCliDomain,
- pCurAppDomain,
- pArgs->ClientGC.refExecutionContext);
- dwMarshalledArg++;
- }
-
- // Make sure return type is loaded
- TypeHandle thReturn = mSrvSideSig.GetRetTypeHandleThrowing();
- _ASSERTE(!thReturn.IsNull());
-
- if (pArgs->bHasValueTypeReturnValToMarshal)
- {
- // The return is a value type which could have GC ref fields. Allocate a boxed value type so that the
- // return value goes into that. During return from call we'll clone it and copy it onto the stack
- ServerGC.refReturnValue = thReturn.AsMethodTable()->Allocate();
- }
- }
-
- // Then clone the call context if any
- if (pArgs->bMarshalCallContext)
- {
-#ifdef _DEBUG
- LOG((LF_REMOTING, LL_INFO100, "MarshalAndCall. Marshalling call context\n"));
-#endif
- ServerGC.refExecutionContext = pArgs->Marshaller.Clone(pArgs->ClientGC.refExecutionContext,
- m_pCliDomain,
- pCurAppDomain,
- pArgs->ClientGC.refExecutionContext);
- THREADBASEREF ref = (THREADBASEREF) pCurThread->GetExposedObjectRaw();
- _ASSERTE(ref != NULL);
-
- ref->SetExecutionContext(ServerGC.refExecutionContext);
- }
- else if (pCurThread->IsExposedObjectSet())
- {
- THREADBASEREF ref = (THREADBASEREF) pCurThread->GetExposedObjectRaw();
- _ASSERTE(ref != NULL);
-
- ref->SetExecutionContext(NULL);
- }
-
-#ifdef PROFILING_SUPPORTED
- // If we're profiling, notify the profiler that we're about to invoke the remoting target
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackRemoting());
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->RemotingServerInvocationStarted();
- END_PIN_PROFILER();
- }
-#endif // PROFILING_SUPPORTED
-
- {
- GCX_COOP();
- if (!RemotableMethodInfo::AreArgsBlittable(m_xret))
- {
- // Next place arguments into the destination array
- // No GC should occur between now and call dispatch
- for (DWORD i = 0 ; i < pArgs->dwNumObjectsMarshalled; i++)
- {
- BOOL bNeedUnbox = pArgs->pArgAttribs[i] & ARG_NEEDS_UNBOX;
- BOOL bGoesInEDX = pArgs->pArgAttribs[i] & ARG_GOES_IN_EDX;
- BOOL bIsByRef = pArgs->pArgAttribs[i] & ARG_IS_BYREF;
- DWORD dwOffset = pArgs->pArgAttribs[i] & ARG_OFFSET_MASK;
-
- SIZE_T *pDest = NULL;
-
-#if defined(_TARGET_X86_)
- if (bGoesInEDX)
- {
- // This has to be EDX for this platform.
- pDest = pArgs->pRegArgs;
- }
- else
- {
- pDest = (SIZE_T *)((BYTE *)(pArgs->pStackArgs) + dwOffset);
- }
-#elif defined(CALLDESCR_ARGREGS)
- // To help deal with the fact that a single argument can span both registers and stack
- // we've ensured that the register and stack buffers are contiguous and encoded all offsets
- // from the beginning of the register buffer.
- pDest = (SIZE_T *)((BYTE *)(pArgs->pRegArgs) + dwOffset);
-#else
- pDest = (SIZE_T *)((BYTE *)(pArgs->pStackArgs) + dwOffset);
-#endif
-
- if (bNeedUnbox && !bIsByRef)
- {
- pServerArgTH[i].GetMethodTable()->UnBoxIntoUnchecked(pDest, pServerArgArray[i]);
- }
- else if (bIsByRef)
- {
- if (bNeedUnbox)
- {
- // We don't use the fast path for byref nullables, so UnBox() can be used
- *pDest = (SIZE_T)pServerArgArray[i]->UnBox();
- }
- else
- {
- // Point to the OBJECTREF
- *pDest = (SIZE_T)&pServerArgArray[i];
- }
- }
- else
- {
- *pDest = (SIZE_T)OBJECTREFToObject(pServerArgArray[i]);
- }
- }
- }
-
- // Get the 'this' object
- OBJECTREF srvObject = GetServerObject();
- LPVOID pvRetBuff = NULL;
-
- FrameWithCookie<ProtectValueClassFrame>* pProtectValueClassFrame = NULL;
- ValueClassInfo* pValueClasses = NULL;
-
- if (pArgs->bHasRetBuffArg)
- {
- // Need some sort of check here that retTH has been initialized?
- MethodTable* pMT = pArgs->retTh.GetMethodTable();
- _ASSERTE_MSG(pMT != NULL, "GetRetType failed?");
- if (pMT->IsStructRequiringStackAllocRetBuf())
- {
- SIZE_T sz = pMT->GetNumInstanceFieldBytes();
- pvRetBuff = _alloca(sz);
- memset(pvRetBuff, 0, sz);
- pValueClasses = new (_alloca(sizeof(ValueClassInfo))) ValueClassInfo(pvRetBuff, pMT, pValueClasses);
- }
- else
- {
- // We don't use the fast path for values that return nullables, so UnBox() can be used
- pvRetBuff = (PVOID)ServerGC.refReturnValue->UnBox();
- }
- }
-#if defined(_TARGET_X86_)
- // Check if EDX should point to a return buffer (either stack- or heap-allocated).
- if (pArgs->bHasValueTypeReturnValToMarshal && pArgs->bHasRetBuffArg)
- {
- *(pArgs->pRegArgs) = (SIZE_T)pvRetBuff;
- }
- (pArgs->pRegArgs)[1] = (SIZE_T)OBJECTREFToObject(srvObject);
-#elif defined(CALLDESCR_ARGREGS)
- // On ARM the this pointer goes in r0 and any return buffer argument pointer in r1.
- pArgs->pRegArgs[0] = (SIZE_T)OBJECTREFToObject(srvObject);
- if (pArgs->bHasRetBuffArg)
- {
- pArgs->pRegArgs[1] = (SIZE_T)pvRetBuff;
- }
-#else // CALLDESCR_ARGREGS
-
- if (pArgs->bHasRetBuffArg)
- {
- (pArgs->pStackArgs)[0] = (SIZE_T)OBJECTREFToObject(srvObject);
- (pArgs->pStackArgs)[1] = (SIZE_T)pvRetBuff;
- }
- else
- {
- (pArgs->pStackArgs)[0] = (SIZE_T)OBJECTREFToObject(srvObject);
- }
-
-#endif // CALLDESCR_ARGREGS
-
- CallDescrData callDescrData;
-
-
- callDescrData.pSrc = pArgs->pStackArgs;
- callDescrData.numStackSlots = m_numStackSlotsToCopy,
-#ifdef CALLDESCR_ARGREGS
- callDescrData.pArgumentRegisters = (ArgumentRegisters *)pArgs->pRegArgs;
-#endif
-#ifdef CALLDESCR_FPARGREGS
- callDescrData.pFloatArgumentRegisters = pArgs->pFloatArgumentRegisters;
-#endif
-#ifdef CALLDESCR_REGTYPEMAP
- callDescrData.dwRegTypeMap = pArgs->uRegTypeMap;
-#endif
- callDescrData.fpReturnSize = GetFPReturnSize();
- callDescrData.pTarget = m_pTargetAddress;
-
- if (pValueClasses != NULL)
- {
- pProtectValueClassFrame = new (_alloca (sizeof (FrameWithCookie<ProtectValueClassFrame>)))
- FrameWithCookie<ProtectValueClassFrame>(pCurThread, pValueClasses);
- }
-
- DispatchCall(&callDescrData,
- &ServerGC.refException,
- pArgs->GetCtxTransitionFrame()
- COMMA_CORRUPTING_EXCEPTIONS_ONLY(&(pArgs->severity))
- );
-
- // If the return value is a GC ref, store it in a protected place
- if (ServerGC.refException != NULL)
- {
- // Return value is invalid if there was exception thrown
- }
- else
- if (RemotableMethodInfo::IsReturnGCRef(m_xret))
- {
- ServerGC.refReturnValue = ObjectToOBJECTREF(*(Object **)(&callDescrData.returnValue));
- pArgs->bHasObjRefReturnVal = TRUE;
- }
- else
- if (pArgs->bHasValueTypeReturnValToMarshal)
- {
- if (!pArgs->bHasRetBuffArg)
- {
- //
- // The value type return value is returned by value in this case.
- // We have to copy it back into our server object.
- //
- // We don't use the fast path for values that return nullables, so UnBox() can be used
- //
- CopyValueClass(ServerGC.refReturnValue->UnBox(), &callDescrData.returnValue, ServerGC.refReturnValue->GetMethodTable(), pCurAppDomain);
- }
- else if (pValueClasses != NULL)
- {
- // We passed a stack allocated ret buff. Copy back into the allocated server object.
- // We don't use the fast path for values that return nullables, so UnBox() can be used
- CopyValueClass(ServerGC.refReturnValue->UnBox(), pvRetBuff, ServerGC.refReturnValue->GetMethodTable(), pCurAppDomain);
- }
- // In all other cases, the return value should be in the server object already.
- }
- else
- {
- memcpyNoGCRefs(m_pFrame->GetReturnValuePtr(), &callDescrData.returnValue, sizeof(callDescrData.returnValue));
- }
-
- if (pProtectValueClassFrame != NULL)
- pProtectValueClassFrame->Pop(pCurThread);
- }
-
-#ifdef PROFILING_SUPPORTED
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackRemoting());
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->RemotingServerInvocationReturned();
- END_PIN_PROFILER();
- }
-#endif // PROFILING_SUPPORTED
-
- if (pCurThread->IsExposedObjectSet())
- {
- THREADBASEREF ref = (THREADBASEREF) pCurThread->GetExposedObjectRaw();
- _ASSERTE(ref != NULL);
-
- EXECUTIONCONTEXTREF refExecCtx = (EXECUTIONCONTEXTREF) ref->GetExecutionContext();
- if (refExecCtx != NULL)
- {
- LOGICALCALLCONTEXTREF refLogCallCtx = refExecCtx->GetLogicalCallContext();
- if (pArgs->bMarshalCallContext ||
- (refLogCallCtx != NULL && refLogCallCtx->ContainsNonSecurityDataForSerialization()))
- {
- ServerGC.refExecutionContext = ref->GetExecutionContext();
- pArgs->bMarshalReturnCallContext = TRUE;
-#ifdef _DEBUG
- LOG((LF_REMOTING, LL_INFO100, "MarshalAndCall. Marshalling return call context\n"));
-#endif
- ResetPrincipal();
- EXECUTIONCONTEXTREF ecref = (EXECUTIONCONTEXTREF)pArgs->Marshaller.Clone(ServerGC.refExecutionContext,
- pCurAppDomain,
- m_pCliDomain,
- ServerGC.refExecutionContext);
- if (pArgs->ClientGC.refExecutionContext != NULL)
- {
- ((EXECUTIONCONTEXTREF)pArgs->ClientGC.refExecutionContext)->SetLogicalCallContext(ecref->GetLogicalCallContext());
- }
- else
- {
- pArgs->ClientGC.refExecutionContext = (OBJECTREF)ecref;
- }
- }
- }
- }
-
-
- if (ServerGC.refException != NULL)
- {
-#ifdef _DEBUG
- LOG((LF_REMOTING, LL_INFO100, "MarshalAndCall. Exception thrown ! Marshalling exception. \n"));
-#endif
-
- // Save Watson buckets before the exception object is changed
- if (GetThread() != NULL)
- {
- // Ensure that we have the buckets for the exception in question.
- // For preallocated exceptions, we capture the buckets in the
- // UE WatsonBucket Tracker in AppDomainTransitionExceptionFilter.
- //
- // When the exception is reraised in the returning AppDomain,
- // StackTraceInfo::AppendElement will copy over the buckets
- // to the EHtracker corresponding to the raised exception.
- if (!CLRException::IsPreallocatedExceptionObject(ServerGC.refException))
- {
- // For non-preallocated exception objects, the throwable
- // should already have the buckets in it, unless it was raised in VM native code
- // and reached here before CLR's managed code exception handler could see it.
- if(!((EXCEPTIONREF)ServerGC.refException)->AreWatsonBucketsPresent())
- {
- LOG((LF_EH, LL_INFO1000, "MarshalAndCall - Regular exception object received (%p) does not contain watson buckets.\n",
- OBJECTREFToObject(ServerGC.refException)));
- }
- }
- }
-
- pArgs->ClientGC.refException = pArgs->Marshaller.Clone(ServerGC.refException,
- pCurAppDomain,
- m_pCliDomain,
- ServerGC.refExecutionContext);
- goto LeaveDomain;
- }
-
- if (!RemotableMethodInfo::IsReturnBlittable(m_xret))
- {
- LOG((LF_REMOTING, LL_INFO100, "MarshalAndCall. Marshalling return object\n"));
- // Need to marshal the return object
-
- pArgs->ClientGC.refReturnValue = pArgs->Marshaller.Clone(ServerGC.refReturnValue,
- pArgs->retTh,
- pCurAppDomain,
- m_pCliDomain,
- ServerGC.refExecutionContext);
-
- if (pArgs->bHasValueTypeReturnValToMarshal)
- {
- // Need to copy contents from temp return buffer to the original return buffer
- void *pDest;
- if (!pArgs->bHasRetBuffArg)
- {
- pDest = m_pFrame->GetReturnValuePtr();
- }
- else
- {
- pDest = *(void **)(m_pFrame->GetTransitionBlock() + pArgs->argit->GetRetBuffArgOffset());
- }
- // We don't use the fast path for values that return nullables, so UnBox() can be used
- CopyValueClass(pDest, pArgs->ClientGC.refReturnValue->UnBox(), pArgs->ClientGC.refReturnValue->GetMethodTable(), m_pCliDomain);
- }
- }
- else if (pArgs->bHasObjRefReturnVal)
- {
- // Must be a domain agile GC ref. We can just copy the reference into the client GC frame.
- pArgs->ClientGC.refReturnValue = ServerGC.refReturnValue;
- }
-
- // Marshal any by-ref args into calling domain
- if (pArgs->bHasByRefArgsToMarshal)
- {
-#ifdef _DEBUG
- LOG((LF_REMOTING, LL_INFO100, "MarshalAndCall. Marshalling by-ref args\n"));
-#endif
- int iMarshalledArg = -1;
- // Look for by ref args
- for (DWORD i = 0; i < pArgs->dwNumArgs; i++)
- {
- if (pArgs->bMarshalledArgs[i] != TRUE)
- continue;
-
- iMarshalledArg++;
-
- BOOL bNeedUnbox = pArgs->pArgAttribs[iMarshalledArg] & ARG_NEEDS_UNBOX;
- BOOL bIsByRef = pArgs->pArgAttribs[iMarshalledArg] & ARG_IS_BYREF;
-
- if (!bIsByRef)
- continue;
-
- TypeHandle argTh = pArgs->pThByRefs[iMarshalledArg];
- int offset = pArgs->pByRefArgAttribs[iMarshalledArg];
- OBJECTREF refReturn = pServerArgArray[iMarshalledArg];
- GCPROTECT_BEGIN(refReturn);
-
- refReturn = pArgs->Marshaller.Clone(refReturn,
- argTh,
- pCurAppDomain,
- m_pCliDomain,
- ServerGC.refExecutionContext);
- if (bNeedUnbox)
- {
- // We don't use the fast path for byref nullables, so UnBox() can be used
- BYTE *pTargetAddress = *((BYTE **)(m_pFrame->GetTransitionBlock() + offset));
- CopyValueClass(pTargetAddress, refReturn->UnBox(), refReturn->GetMethodTable(), m_pCliDomain);
- }
- else
- {
- SetObjectReference(*((OBJECTREF **)(m_pFrame->GetTransitionBlock() + offset)), refReturn, m_pCliDomain);
- }
- GCPROTECT_END();
- }
- }
-
- LeaveDomain:;
-
- GCPROTECT_END(); // pServerArgArray
- GCPROTECT_END(); // ServerGC
-}
-
-
-// Arguments need to be marshalled before dispatch. We walk thru each argument,
-// inspect its type, make a list of objects that need to be marshalled, cross over to the new domain,
-// marshal the objects and dispatch the call. Upon return, we marshal the return object if any and
-// by ref objects if any. Call contexts flows either way
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
-#endif
-BOOL
-CrossDomainChannel::MarshalAndCall()
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
-
- MarshalAndCallArgs args;
-
- args.bHasByRefArgsToMarshal = FALSE;
-
- args.bHasObjRefReturnVal = FALSE;
- args.bHasRetBuffArg = FALSE;
- args.bHasValueTypeReturnValToMarshal = FALSE;
-
- DWORD dwNumArgs = 0;
- DWORD dwNumObjectsMarshalled = 0;
-
- DWORD *pArgAttribs = NULL;
- BOOL *bMarshalledArgs = NULL;
- int *pByRefArgAttribs = NULL;
- TypeHandle *pThByRefs = NULL;
-
- Thread *pCurThread = GetThread();
-
-#ifdef _DEBUG
- LPCUTF8 pszMethodName;
- pszMethodName = m_pCliMD->GetName();
- LOG((LF_REMOTING, LL_INFO100, "MarshalAndCall. Marshalling arguments to method %s\n", pszMethodName));
-#endif // _DEBUG
-
- // Collect all client domain GC references together in a single GC frame.
- // refReturnValue contains the returned object when its a value type and needs marshalling
- ZeroMemory(&args.ClientGC, sizeof(args.ClientGC));
- GCPROTECT_BEGIN(args.ClientGC);
-
- // When computing the method signature we need to take special care if the call is on a non-interface class with a
- // generic instantiation (since in that case we may have a representative method with a non-concrete signature).
- TypeHandle thDeclaringType;
- CDC_DETERMINE_DECLARING_TYPE(m_pCliMD, TypeHandle(CTPMethodTable::GetMethodTableBeingProxied(m_pFrame->GetThis())));
- MetaSig mSig(m_pCliMD, thDeclaringType);
- ArgIterator argit(&mSig);
- int ofs;
-
- // NumFixedArgs() doesn't count the "this" object, but SizeOfFrameArgumentArray() does.
- dwNumArgs = mSig.NumFixedArgs();
- m_numStackSlotsToCopy = argit.SizeOfFrameArgumentArray() / sizeof(SIZE_T);
-
- // Ensure none of the following _alloca's are subject to integer overflow problems.
- DWORD dwMaxEntries = dwNumArgs > m_numStackSlotsToCopy ? dwNumArgs : m_numStackSlotsToCopy;
- DWORD dwResult;
- if (!ClrSafeInt<DWORD>::multiply(dwMaxEntries, sizeof(SIZE_T), dwResult))
- COMPlusThrowOM();
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:26000) // "Suppress PREFast warning about integer overflow (we're doing an umbrella check)"
-#endif
-
- args.bHasRetBuffArg = argit.HasRetBuffArg();
-
-#ifdef _TARGET_X86_
- BOOL bArgumentRegisterUsed = FALSE;
- if (args.bHasRetBuffArg)
- {
- bArgumentRegisterUsed = TRUE;
- }
-#endif // _TARGET_X86_
-
- // pArgAttribs tell where the marshalled objects should go, where they need unboxing etc
- pArgAttribs = (DWORD*) _alloca(dwNumArgs * sizeof(DWORD));
- ZeroMemory(pArgAttribs, sizeof(DWORD) * dwNumArgs);
- // pThByRefs has the typehandles of the by-ref args
- pThByRefs = (TypeHandle *)_alloca(dwNumArgs * sizeof(TypeHandle));
- ZeroMemory(pThByRefs, sizeof(TypeHandle) *dwNumArgs);
- // pByRefArgAttribs tell where the by-ref args should go, after the call
- pByRefArgAttribs = (int*) _alloca(dwNumArgs * sizeof(int));
- ZeroMemory(pByRefArgAttribs, sizeof(int) * dwNumArgs);
- // bMarshalledArgs is a bunch of flags that tell which args were marshalled
- bMarshalledArgs = (BOOL*) _alloca(dwNumArgs * sizeof(BOOL));
- ZeroMemory(bMarshalledArgs, sizeof(BOOL) * dwNumArgs);
-
- // pArgArray contains marshalled objects on the client side
- OBJECTREF *pClientArgArray = NULL;
- pClientArgArray = (OBJECTREF *) _alloca(dwNumArgs * sizeof(OBJECTREF));
- ZeroMemory(pClientArgArray, sizeof(OBJECTREF) * dwNumArgs);
- GCPROTECT_ARRAY_BEGIN(pClientArgArray[0], dwNumArgs);
-
- // pStackArgs will finally contain the arguments that'll be fed to Dispatch call. The Marshalled objects
- // are not placed directly into pStackArgs because its not possible to GCPROTECT an array that can contain
- // both GC refs and primitives.
- DWORD cbStackArgs = m_numStackSlotsToCopy * sizeof (SIZE_T);
-#ifdef CALLDESCR_ARGREGS
- // Allocate enough space to put ArgumentRegisters at the front of the buffer so we can ensure
- // register and stack arguments are stored contiguously and simply the case of unboxing a value type that
- // spans registers and the stack.
- cbStackArgs += sizeof(ArgumentRegisters);
-#endif
- SIZE_T *pStackArgs = (SIZE_T*)_alloca(cbStackArgs);
- ZeroMemory(pStackArgs, cbStackArgs);
-#ifdef CALLDESCR_ARGREGS
- SIZE_T *pRegArgs = pStackArgs;
- pStackArgs += sizeof(ArgumentRegisters) / sizeof(SIZE_T);
-#endif
-#ifdef CALLDESCR_FPARGREGS
- FloatArgumentRegisters *pFloatArgumentRegisters = NULL;
-#endif
-
-#if defined(CALLDESCR_REGTYPEMAP)
- UINT64 uRegTypeMap = 0;
- BYTE* pMap = (BYTE*)&uRegTypeMap;
-#endif
-
- TADDR pTransitionBlock = m_pFrame->GetTransitionBlock();
-
- for (int argNum = 0;
- TransitionBlock::InvalidOffset != (ofs = argit.GetNextOffset());
- argNum++
- )
- {
- DWORD dwOffsetOfArg = 0;
-
-#if defined(CALLDESCR_REGTYPEMAP)
- int regArgNum = TransitionBlock::GetArgumentIndexFromOffset(ofs);
-
- FillInRegTypeMap(ofs, argit.GetArgType(), pMap);
-#endif // defined(CALLDESCR_REGTYPEMAP)
-
- SIZE_T *pDestToCopy = NULL;
-
-#if defined(_TARGET_ARM_)
-
- // On ARM there are ranges of offset that can be returned from ArgIterator::GetNextOffset() (where R
- // == TransitionBlock::GetOffsetOfArgumentRegisters() and S == sizeof(TransitionBlock)):
- //
- // * ofs < 0 : arg is in a floating point register
- // * ofs >= R && ofs < S : arg is in a general register
- // * ofs >= S : arg is on the stack at offset (ofs - X)
- //
- // Arguments can be split between general registers and the stack on ARM and as a result both
- // FramedMethodFrame and this method ensure the storage for register and stack locations is
- // contiguous.
- int iInitialRegOffset = TransitionBlock::GetOffsetOfArgumentRegisters();
- int iInitialStackOffset = sizeof(TransitionBlock);
- _ASSERTE(iInitialStackOffset == (iInitialRegOffset + sizeof(ArgumentRegisters)));
- if (ofs < 0)
- {
- // Floating point register case. Since these registers can never hold a GC reference we can just
- // pass through a pointer to the spilled FP reg area in the frame. But we don't do this unless we
- // see at least one FP arg: passing NULL for pFloatArgumentRegisters enables an optimization in
- // the call thunk.
- if (pFloatArgumentRegisters == NULL)
- pFloatArgumentRegisters = (FloatArgumentRegisters*) (pTransitionBlock + TransitionBlock::GetOffsetOfFloatArgumentRegisters());
-
- // No arg to copy in this case.
- continue;
- }
-
- _ASSERTE(ofs >= iInitialRegOffset);
-
- // We've ensured our registers and stack locations are contiguous so treat both types of arguments
- // identically (i.e. compute a destination offset from the base of the register save area and it will
- // work for arguments that span from registers to stack or live entirely on the stack).
- dwOffsetOfArg = ofs - TransitionBlock::GetOffsetOfArgumentRegisters();
- pDestToCopy = (SIZE_T*)((BYTE *)pRegArgs + dwOffsetOfArg);
-
-#else // _TARGET_ARM_
-
- dwOffsetOfArg = ofs - TransitionBlock::GetOffsetOfArgs();
-
-#ifdef _TARGET_X86_
- if (!bArgumentRegisterUsed && gElementTypeInfo[argit.GetArgType()].m_enregister)
- {
- pDestToCopy = pRegArgs;
- bArgumentRegisterUsed = TRUE;
- }
- else
-#endif // _TARGET_X86_
- {
- _ASSERTE(dwOffsetOfArg < (m_numStackSlotsToCopy * sizeof(SIZE_T)));
- pDestToCopy = (SIZE_T*)((BYTE *)pStackArgs + dwOffsetOfArg);
- }
-
-#endif // _TARGET_ARM_
-
- CorElementType origTyp = argit.GetArgType();
-
- // Get the signature type of the argument (For ex. enum will be E_T_VT, not E_T_I4 etc)
- SigPointer sp = mSig.GetArgProps();
- CorElementType typ;
- IfFailThrow(sp.GetElemType(&typ));
-
- if (typ == ELEMENT_TYPE_VAR ||
- typ == ELEMENT_TYPE_MVAR ||
- typ == ELEMENT_TYPE_GENERICINST)
- {
- typ = origTyp;
- }
-
- switch (typ)
- {
- case ELEMENT_TYPE_BOOLEAN:
- case ELEMENT_TYPE_I1:
- case ELEMENT_TYPE_U1:
- case ELEMENT_TYPE_I2:
- case ELEMENT_TYPE_U2:
- case ELEMENT_TYPE_CHAR:
- case ELEMENT_TYPE_I4:
- case ELEMENT_TYPE_U4:
-#if !defined(COM_STUBS_SEPARATE_FP_LOCATIONS)
- case ELEMENT_TYPE_R4:
-#endif
-
-#if defined(_TARGET_X86_) || defined(_TARGET_ARM_)
- *(pDestToCopy) = *((SIZE_T*) (pTransitionBlock + ofs));
-#elif defined(_WIN64)
- switch (GetSizeForCorElementType((CorElementType)typ))
- {
- case 1:
- *(BYTE*)(pDestToCopy) = *(BYTE*)(pTransitionBlock + ofs);
- break;
-
- case 2:
- *(USHORT*)(pDestToCopy) = *(USHORT*)(pTransitionBlock + ofs);
- break;
-
- case 4:
- *(UINT*)(pDestToCopy) = *(UINT*)(pTransitionBlock + ofs);
- break;
-
- case 8:
- *(SIZE_T*)(pDestToCopy) = *(SIZE_T*)(pTransitionBlock + ofs);
- break;
-
- default:
- _ASSERTE(!"MarshalAndCall() - unexpected size");
- }
-#else // !defined(_WIN64)
- PORTABILITY_ASSERT("MarshalAndCall() - NYI on this platform");
-#endif // !defined(_WIN64)
- break;
-
- case ELEMENT_TYPE_I:
- case ELEMENT_TYPE_U:
- case ELEMENT_TYPE_PTR:
- case ELEMENT_TYPE_FNPTR:
-
- *((SIZE_T*)((BYTE *)pDestToCopy)) = *((SIZE_T*)(pTransitionBlock + ofs));
- break;
-
- case ELEMENT_TYPE_I8:
- case ELEMENT_TYPE_U8:
-#if !defined(COM_STUBS_SEPARATE_FP_LOCATIONS)
- case ELEMENT_TYPE_R8:
-#endif
-
- *((INT64*)((BYTE *)pDestToCopy)) = *((INT64 *)(pTransitionBlock + ofs));
- break;
-
-#if defined(COM_STUBS_SEPARATE_FP_LOCATIONS)
- case ELEMENT_TYPE_R4:
-
- if (regArgNum < NUM_ARGUMENT_REGISTERS)
- {
- *(ARG_SLOT*)pDestToCopy = FPSpillToR4( (LPVOID)(pTransitionBlock + m_pFrame->GetFPArgOffset(regArgNum)) );
- }
- else
- {
- *(UINT*)(pDestToCopy) = *(UINT*)(pTransitionBlock + ofs);
- }
- break;
-
- case ELEMENT_TYPE_R8:
-
- if (regArgNum < NUM_ARGUMENT_REGISTERS)
- {
- *(ARG_SLOT*)pDestToCopy = FPSpillToR8( (LPVOID)(pTransitionBlock + m_pFrame->GetFPArgOffset(regArgNum)) );
- }
- else
- {
- *(SIZE_T*)(pDestToCopy) = *(SIZE_T*)(pTransitionBlock + ofs);
- }
- break;
-#endif // defined(COM_STUBS_SEPARATE_FP_LOCATIONS)
-
- case ELEMENT_TYPE_BYREF:
- {
- // Check if this is a by-ref primitive
- OBJECTREF refTmpBox = NULL;
- TypeHandle ty = TypeHandle();
- CorElementType brType = mSig.GetByRefType(&ty);
- if (CorIsPrimitiveType(brType) || ty.IsValueType())
- {
-
- // Needs marshalling
- MethodTable *pMT = NULL;
- if (CorIsPrimitiveType(brType))
- pMT = MscorlibBinder::GetElementType(brType);
- else
- pMT = ty.GetMethodTable();
- refTmpBox = pMT->Box(*((SIZE_T**)(pTransitionBlock + ofs)));
- pArgAttribs[dwNumObjectsMarshalled] |= ARG_NEEDS_UNBOX;
- }
- else
- {
- OBJECTREF *refRefObj = *((OBJECTREF **)(pTransitionBlock + ofs));
- refTmpBox = (refRefObj == NULL ? NULL : *refRefObj);
- }
-
- pByRefArgAttribs[dwNumObjectsMarshalled] = ofs;
- pThByRefs[dwNumObjectsMarshalled] = ty;
-
- // we should have stopped nullables before we got here in DoStaticAnalysis
- _ASSERTE(ty.IsNull() || !Nullable::IsNullableType(ty));
- pArgAttribs[dwNumObjectsMarshalled] |= ARG_IS_BYREF;
-
- args.bHasByRefArgsToMarshal = TRUE;
-
- pClientArgArray[dwNumObjectsMarshalled] = refTmpBox;
- bMarshalledArgs[argNum] = TRUE;
-
-#if defined(_TARGET_X86_)
- if (pDestToCopy == pRegArgs)
- {
- pArgAttribs[dwNumObjectsMarshalled] |= ARG_GOES_IN_EDX; // Indicate that this goes in EDX
- }
- else
-#endif // _TARGET_X86_
- {
- // @TODO - Use QWORD for attribs
- _ASSERTE(dwOffsetOfArg < ARG_OFFSET_MASK);
- pArgAttribs[dwNumObjectsMarshalled] |= dwOffsetOfArg;
- }
- dwNumObjectsMarshalled++;
- }
- break;
-
- case ELEMENT_TYPE_VALUETYPE:
- {
-#if defined(COM_STUBS_SEPARATE_FP_LOCATIONS)
- if (regArgNum < NUM_ARGUMENT_REGISTERS)
- {
-
- // We have to copy the floating point registers from a different stack location to the portion of
- // the stack used to save the general registers.
- if (origTyp == ELEMENT_TYPE_R4)
- {
- LPVOID pDest = (LPVOID)(pTransitionBlock + ofs);
- *(ARG_SLOT*)pDest = FPSpillToR4( (LPVOID)(pTransitionBlock + m_pFrame->GetFPArgOffset(regArgNum)) );
- }
- else if (origTyp == ELEMENT_TYPE_R8)
- {
- LPVOID pDest = (LPVOID)(pTransitionBlock + ofs);
- *(ARG_SLOT*)pDest = FPSpillToR8( (LPVOID)(pTransitionBlock + m_pFrame->GetFPArgOffset(regArgNum)) );
- }
- }
-#endif // defined(COM_STUBS_SEPARATE_FP_LOCATIONS)
-
- TypeHandle th = mSig.GetLastTypeHandleThrowing();
-
-#ifdef _DEBUG
- {
- DefineFullyQualifiedNameForClass()
- LPCUTF8 szTypeName = GetFullyQualifiedNameForClassNestedAware(th.GetMethodTable());
- LOG((LF_REMOTING, LL_INFO100, "MarshalAndCall. Boxing a value type argument of type %s.\n", &szTypeName[0]));
- }
-#endif // _DEBUG
-
- OBJECTREF refTmpBox;
-#if defined(ENREGISTERED_PARAMTYPE_MAXSIZE)
- if (argit.IsArgPassedByRef())
- {
- refTmpBox = th.GetMethodTable()->Box(*(LPVOID*)(pTransitionBlock + ofs));
-
- // we should have stopped nullables before we got here in DoStaticAnalysis
- _ASSERTE(!Nullable::IsNullableType(th));
- pArgAttribs[dwNumObjectsMarshalled] |= ARG_IS_BYREF;
-
- pByRefArgAttribs[dwNumObjectsMarshalled] = ofs;
- pThByRefs[dwNumObjectsMarshalled] = th;
- }
- else
-#endif // defined(ENREGISTERED_PARAMTYPE_MAXSIZE)
- {
- refTmpBox = th.GetMethodTable()->Box((void *)(pTransitionBlock + ofs));
- }
- pClientArgArray[dwNumObjectsMarshalled] = refTmpBox;
- bMarshalledArgs[argNum] = TRUE;
-
-#if defined(_TARGET_X86_)
- if (pDestToCopy == pRegArgs)
- {
- pArgAttribs[dwNumObjectsMarshalled] |= ARG_GOES_IN_EDX; // Indicate that this goes in EDX
- }
- else
-#endif // _TARGET_X86_
- {
- // @TODO - Use QWORD for attribs
- _ASSERTE(dwOffsetOfArg < ARG_OFFSET_MASK);
- pArgAttribs[dwNumObjectsMarshalled] |= dwOffsetOfArg;
- }
- pArgAttribs[dwNumObjectsMarshalled] |= ARG_NEEDS_UNBOX; // Indicate that an unboxing is required
- dwNumObjectsMarshalled++;
- }
- break;
-
- case ELEMENT_TYPE_SZARRAY: // Single Dim
- case ELEMENT_TYPE_ARRAY: // General Array
- case ELEMENT_TYPE_CLASS: // Class
- case ELEMENT_TYPE_OBJECT:
- case ELEMENT_TYPE_STRING: // System.String
- case ELEMENT_TYPE_VAR:
- {
- OBJECTREF *refRefObj = (OBJECTREF *)(pTransitionBlock + ofs);
- // The frame does protect this object, so mark it as such to avoid asserts
- INDEBUG(Thread::ObjectRefNew(refRefObj);)
- INDEBUG(Thread::ObjectRefProtected(refRefObj);)
-
- pClientArgArray[dwNumObjectsMarshalled] = *refRefObj;
- bMarshalledArgs[argNum] = TRUE;
-
-#ifdef _TARGET_X86_
- if (pDestToCopy == pRegArgs)
- {
- pArgAttribs[dwNumObjectsMarshalled] |= ARG_GOES_IN_EDX; // Indicate that this goes in EDX
- }
- else
-#endif // _TARGET_X86_
- {
- // @TODO - Use QWORD for attribs
- _ASSERTE(dwOffsetOfArg < ARG_OFFSET_MASK);
- pArgAttribs[dwNumObjectsMarshalled] |= dwOffsetOfArg;
- }
- dwNumObjectsMarshalled++;
- }
- break;
-
- default:
- _ASSERTE(!"Unknown Element type in MarshalAndCall" );
- }
- }
-
- if (!RemotableMethodInfo::IsReturnBlittable(m_xret))
- {
- CorElementType retType = mSig.GetReturnType();
- if (retType == ELEMENT_TYPE_VALUETYPE)
- {
- args.retTh = mSig.GetRetTypeHandleThrowing();
- args.bHasValueTypeReturnValToMarshal = TRUE;
- }
- else
- {
- args.retTh = mSig.GetRetTypeHandleThrowing();
- }
- }
-
- // Check for any call context
- BOOL bMarshalCallContext = FALSE;
- args.bMarshalReturnCallContext = FALSE;
- if (pCurThread->IsExposedObjectSet())
- {
- THREADBASEREF ref = (THREADBASEREF) pCurThread->GetExposedObjectRaw();
- _ASSERTE(ref != NULL);
-
- EXECUTIONCONTEXTREF refExecCtx = (EXECUTIONCONTEXTREF) ref->GetExecutionContext();
- if (refExecCtx != NULL)
- {
- args.ClientGC.refExecutionContext = refExecCtx;
- args.ClientGC.refPrincipal = ReadPrincipal();
-
- LOGICALCALLCONTEXTREF refLogCallCtx = refExecCtx->GetLogicalCallContext();
- if (refLogCallCtx != NULL)
- {
- if (refLogCallCtx->ContainsDataForSerialization())
- {
- bMarshalCallContext = TRUE;
- }
- }
- }
- }
-
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
- // Make the Cross-AppDomain call
- {
- args.pThis = this;
-
- args.bOptimizable = TRUE;
-
- args.mSig = &mSig;
- args.argit = &argit;
-
- args.dwNumArgs = dwNumArgs;
- args.pStackArgs = pStackArgs;
-#ifdef CALLDESCR_ARGREGS
- args.pRegArgs = pRegArgs;
-#endif
-#ifdef CALLDESCR_FPARGREGS
- args.pFloatArgumentRegisters = pFloatArgumentRegisters;
-#endif
- args.pArgAttribs = pArgAttribs;
-
- args.dwNumObjectsMarshalled = dwNumObjectsMarshalled;
- args.bMarshalledArgs = bMarshalledArgs;
- args.pClientArgArray = pClientArgArray;
-
- args.pByRefArgAttribs = pByRefArgAttribs;
- args.pThByRefs = pThByRefs;
-
- args.bMarshalCallContext = bMarshalCallContext;
-
-#ifdef CALLDESCR_REGTYPEMAP
- args.uRegTypeMap = *(UINT64*)pMap;
-#endif
-
-#ifdef FEATURE_CORRUPTING_EXCEPTIONS
- // By default assume that exception thrown across the cross-AD call is NotCorrupting.
- args.severity = NotCorrupting;
-#endif // FEATURE_CORRUPTING_EXCEPTIONS
-
- MakeCallWithPossibleAppDomainTransition(m_pSrvDomain, (FPAPPDOMAINCALLBACK) MarshalAndCall_Wrapper2, &args);
- }
-
- if (args.ClientGC.refException != NULL)
- {
- RestorePrincipal(&args.ClientGC.refPrincipal);
- COMPlusThrow(args.ClientGC.refException
- COMMA_CORRUPTING_EXCEPTIONS_ONLY(args.severity)
- );
- }
-
- if (pCurThread->IsExposedObjectSet())
- {
- THREADBASEREF ref = (THREADBASEREF) pCurThread->GetExposedObjectRaw();
- _ASSERTE(ref != NULL);
-
- ref->SetExecutionContext(args.ClientGC.refExecutionContext);
- }
-
- RestorePrincipal(&args.ClientGC.refPrincipal);
-
- // If the return type is an object, take it out of the protected ref
- if (args.bHasObjRefReturnVal)
- {
- *(Object **)m_pFrame->GetReturnValuePtr() = OBJECTREFToObject(args.ClientGC.refReturnValue);
- }
-
- GCPROTECT_END(); // pClientArgArray
- GCPROTECT_END(); // args.ClientGC
-
- args.Marshaller.RemoveGCFrames();
-
- return args.bOptimizable;
-}
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
-#endif // CROSSGEN_COMPILE
-
-#endif // FEATURE_REMOTING
diff --git a/src/vm/crossdomaincalls.h b/src/vm/crossdomaincalls.h
deleted file mode 100644
index 6a406547de..0000000000
--- a/src/vm/crossdomaincalls.h
+++ /dev/null
@@ -1,272 +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.
-//
-// File: CrossDomainCalls.h
-//
-
-//
-// Purpose: Provides a fast path for cross domain calls.
-//
-
-
-#ifndef __CROSSDOMAINCALLS_H__
-#define __CROSSDOMAINCALLS_H__
-
-#ifndef FEATURE_REMOTING
-#error FEATURE_REMOTING is not set, please do no include crossdomaincalls.h
-#endif
-
-#include "methodtable.h"
-
-class SimpleRWLock;
-
-// These are flags set inside the real proxy. Indicates what kind of type is the proxy cast to
-// whether its method table layout is equivalent to the server type etc
-#define OPTIMIZATION_FLAG_INITTED 0x01000000
-#define OPTIMIZATION_FLAG_PROXY_EQUIVALENT 0x02000000
-#define OPTIMIZATION_FLAG_PROXY_SHARED_TYPE 0x04000000
-#define OPTIMIZATION_FLAG_DEPTH_MASK 0x00FFFFFF
-
-// This struct has info about methods on MBR objects and Interfaces
-struct RemotableMethodInfo
-{
-#ifdef DACCESS_COMPILE
- friend class NativeImageDumper;
-#endif
- /*
- if XAD_BLITTABLE_ARGS is set, (m_OptFlags & XAD_ARG_COUNT_MASK) contains the number of stack dwords to copy
- */
- enum XADOptimizationType
- {
- XAD_FLAGS_INITIALIZED = 0x01000000,
- XAD_NOT_OPTIMIZABLE = 0x02000000, // Method call has to go through managed remoting path
- XAD_BLITTABLE_ARGS = 0x04000000, // Arguments blittable across domains. Could be scalars or agile gc refs
- XAD_BLITTABLE_RET = 0x08000000, // Return Value blittable across domains. Could be scalars or agile gc refs
- XAD_BLITTABLE_ALL = XAD_BLITTABLE_ARGS | XAD_BLITTABLE_RET,
-
- XAD_RET_FLOAT = 0x10000000,
- XAD_RET_DOUBLE = 0x20000000,
-#ifdef FEATURE_HFA
- XAD_RET_HFA_TYPE = 0x40000000,
-#endif
- XAD_RET_GC_REF = 0x70000000, // To differentiate agile objects like string which can be blitted across domains, but are gc refs
- XAD_RET_TYPE_MASK = 0x70000000,
-
- XAD_METHOD_IS_VIRTUAL = 0x80000000, // MethodDesc::IsVirtual is slow. Should consider fixing IsVirtual rather than have a flag here
- XAD_ARGS_HAVE_A_FLOAT = 0x00800000,
-
- XAD_FLAG_MASK = 0xFF800000,
- XAD_ARG_COUNT_MASK = 0x007FFFFF
- } ;
-
- static XADOptimizationType IsCrossAppDomainOptimizable(MethodDesc *pMeth, DWORD *pNumDwordsToCopy);
-
- static BOOL TypeIsConduciveToBlitting(MethodTable *pFromMT, MethodTable *pToMT);
-
- static BOOL AreArgsBlittable(XADOptimizationType enumVal)
- {
- LIMITED_METHOD_CONTRACT;
- return (enumVal & XAD_BLITTABLE_ARGS) && IsReturnBlittable(enumVal);
- }
- static BOOL IsReturnBlittable(XADOptimizationType enumVal)
- {
- LIMITED_METHOD_CONTRACT;
- return enumVal & XAD_BLITTABLE_RET;
- }
- static BOOL IsReturnGCRef(XADOptimizationType enumVal)
- {
- LIMITED_METHOD_CONTRACT;
- return XAD_RET_GC_REF == (enumVal & XAD_RET_TYPE_MASK);
- }
-
- static UINT GetFPReturnSize(XADOptimizationType enumVal)
- {
- WRAPPER_NO_CONTRACT;
- switch (enumVal & XAD_RET_TYPE_MASK)
- {
- case XAD_RET_FLOAT:
- return sizeof(float);
-
- case XAD_RET_DOUBLE:
- return sizeof(double);
-
-#ifdef FEATURE_HFA
- case XAD_RET_FLOAT | XAD_RET_HFA_TYPE:
- return 4 * sizeof(float);
-
- case XAD_RET_DOUBLE | XAD_RET_HFA_TYPE:
- return 4 * sizeof(double);
-#endif
-
- default:
- return 0;
- }
- }
-
- static DWORD GetRetTypeFlagsFromFPReturnSize(UINT fpRetSize)
- {
- LIMITED_METHOD_CONTRACT;
-
- DWORD flags = 0;
- switch (fpRetSize)
- {
- case 0:
- break;
-
- case sizeof(float):
- flags = XAD_RET_FLOAT;
- break;
-
- case sizeof(double):
- flags = XAD_RET_DOUBLE;
- break;
-
-#ifdef FEATURE_HFA
- case 4 * sizeof(float):
- flags = XAD_RET_FLOAT | XAD_RET_HFA_TYPE;
- break;
-
- case 4 * sizeof(double):
- flags = XAD_RET_DOUBLE | XAD_RET_HFA_TYPE;
- break;
-#endif
- default:
- _ASSERTE(false);
- break;
- }
-
- _ASSERTE(fpRetSize == GetFPReturnSize((XADOptimizationType)flags));
-
- return flags;
- }
-
- static BOOL DoArgsContainAFloat(XADOptimizationType enumVal)
- {
- LIMITED_METHOD_CONTRACT;
- return enumVal & XAD_ARGS_HAVE_A_FLOAT;
- }
-
- static BOOL IsCallNotOptimizable(XADOptimizationType enumVal)
- {
- LIMITED_METHOD_CONTRACT;
- return enumVal & XAD_NOT_OPTIMIZABLE;
- }
- static BOOL IsMethodVirtual(XADOptimizationType enumVal)
- {
- LIMITED_METHOD_CONTRACT;
- return enumVal & XAD_METHOD_IS_VIRTUAL;
- }
-
- private:
-
- static DWORD DoStaticAnalysis(MethodDesc *pMeth);
-
- DWORD m_OptFlags;
-
-} ;
-
-class CrossDomainOptimizationInfo
-{
-#ifdef DACCESS_COMPILE
- friend class NativeImageDumper;
-#endif
- RemotableMethodInfo m_rmi[0];
-
- public:
-
- static SIZE_T SizeOf(MethodTable *pMT)
- {
- WRAPPER_NO_CONTRACT;
- return SizeOf(pMT->GetNumVtableSlots());
- }
-
- static SIZE_T SizeOf(DWORD dwNumVtableSlots)
- {
- LIMITED_METHOD_CONTRACT;
- return offsetof(CrossDomainOptimizationInfo, m_rmi) + (sizeof(RemotableMethodInfo) * dwNumVtableSlots);
- }
-
- RemotableMethodInfo *GetRemotableMethodInfo()
- {
- return &(m_rmi[0]);
- }
-};
-
-class CrossDomainTypeMap
-{
- class MTMapEntry
- {
- public:
- MTMapEntry(AppDomain *pFromDomain, MethodTable *pFromMT, AppDomain *pToDomain, MethodTable *pToMT);
- UPTR GetHash()
- {
- LIMITED_METHOD_CONTRACT;
- DWORD hash = _rotl((UINT)(SIZE_T)m_pFromMT, 1) + m_dwFromDomain.m_dwId;
- hash = _rotl(hash, 1) + m_dwToDomain.m_dwId;
- return (UPTR)hash;
- }
- ADID m_dwFromDomain;
- ADID m_dwToDomain;
- MethodTable *m_pFromMT;
- MethodTable *m_pToMT;
- };
-
- static BOOL CompareMTMapEntry (UPTR val1, UPTR val2);
- static PtrHashMap *s_crossDomainMTMap; // Maps a MT to corresponding MT in another domain
- static SimpleRWLock *s_MTMapLock;
- static PtrHashMap * GetTypeMap();
-
-public:
- static MethodTable *GetMethodTableForDomain(MethodTable *pFrom, AppDomain *pFromDomain, AppDomain *pToDomain);
- static void SetMethodTableForDomain(MethodTable *pFromMT, AppDomain *pFromDomain, MethodTable *pToMT, AppDomain *pToDomain);
- static void FlushStaleEntries();
-};
-
-struct MarshalAndCallArgs;
-void MarshalAndCall_Wrapper2(MarshalAndCallArgs * pArgs);
-
-class CrossDomainChannel
-{
-private:
- friend void MarshalAndCall_Wrapper2(MarshalAndCallArgs * pArgs);
-
-
- BOOL GetTargetAddressFast(DWORD optFlags, MethodTable *pSrvMT, BOOL bFindServerMD);
- BOOL GetGenericMethodAddress(MethodTable *pSrvMT);
- BOOL GetInterfaceMethodAddressFast(DWORD optFlags, MethodTable *pSrvMT, BOOL bFindServerMD);
- BOOL BlitAndCall();
- BOOL MarshalAndCall();
- void MarshalAndCall_Wrapper(MarshalAndCallArgs * pArgs);
- BOOL ExecuteCrossDomainCall();
- VOID RenewLease();
- OBJECTREF GetServerObject();
- BOOL InitServerInfo();
- OBJECTREF ReadPrincipal();
- VOID RestorePrincipal(OBJECTREF *prefPrincipal);
- VOID ResetPrincipal();
-
-public:
-
- UINT GetFPReturnSize()
- {
- WRAPPER_NO_CONTRACT;
- return RemotableMethodInfo::GetFPReturnSize(m_xret);
- }
-
- BOOL CheckCrossDomainCall(TPMethodFrame *pFrame);
-
-private:
- MethodDesc *m_pCliMD;
- MethodDesc *m_pSrvMD;
- RemotableMethodInfo::XADOptimizationType m_xret;
- DWORD m_numStackSlotsToCopy;
- OBJECTHANDLE m_refSrvIdentity;
- AppDomain *m_pCliDomain;
- ADID m_pSrvDomain;
- PCODE m_pTargetAddress;
- TPMethodFrame *m_pFrame;
-};
-
-#endif
-
diff --git a/src/vm/crossgen/CMakeLists.txt b/src/vm/crossgen/CMakeLists.txt
index c6ef163d53..bef9f62d85 100644
--- a/src/vm/crossgen/CMakeLists.txt
+++ b/src/vm/crossgen/CMakeLists.txt
@@ -96,12 +96,6 @@ set(VM_CROSSGEN_SOURCES
../crossgencompile.cpp
)
-if(FEATURE_CER)
- list(APPEND VM_CROSSGEN_SOURCES
- ../constrainedexecutionregion.cpp
- )
-endif(FEATURE_CER)
-
if(FEATURE_READYTORUN)
list(APPEND VM_CROSSGEN_SOURCES
../readytoruninfo.cpp
diff --git a/src/vm/crossgencompile.cpp b/src/vm/crossgencompile.cpp
index ffb025adb0..b106ecc918 100644
--- a/src/vm/crossgencompile.cpp
+++ b/src/vm/crossgencompile.cpp
@@ -16,13 +16,9 @@
#include "comdelegate.h"
#include "compile.h"
-#include "constrainedexecutionregion.h"
#include "security.h"
#include "invokeutil.h"
#include "comcallablewrapper.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
//---------------------------------------------------------------------------------------
//
@@ -137,9 +133,7 @@ BOOL g_fEEComActivatedStartup=FALSE;
GVAL_IMPL_INIT(DWORD, g_fHostConfig, 0);
-#ifdef FEATURE_SVR_GC
-SVAL_IMPL_INIT(uint32_t,IGCHeap,gcHeapType,IGCHeap::GC_HEAP_WKS);
-#endif
+GVAL_IMPL_INIT(GCHeapType, g_heap_type, GC_HEAP_WKS);
void UpdateGCSettingFromHost()
{
@@ -296,15 +290,15 @@ INT32 rel32UsingJumpStub(INT32 UNALIGNED * pRel32, PCODE target, MethodDesc *pMe
// crossgen does not have jump stubs
return 0;
}
-#endif
-#if defined(FEATURE_REMOTING) && !defined(HAS_REMOTING_PRECODE)
-void CRemotingServices::DestroyThunk(MethodDesc* pMD)
+INT32 rel32UsingPreallocatedJumpStub(INT32 UNALIGNED * pRel32, PCODE target, PCODE jumpStubAddr)
{
- UNREACHABLE();
+ // crossgen does not have jump stubs
+ return 0;
}
#endif
+
CORINFO_GENERIC_HANDLE JIT_GenericHandleWorker(MethodDesc * pMD, MethodTable * pMT, LPVOID signature, DWORD dictionaryIndexAndSlot, Module* pModule)
{
UNREACHABLE();
@@ -461,12 +455,10 @@ void AppDomain::RaiseLoadingAssemblyEvent(DomainAssembly *pAssembly)
{
}
-#ifdef FEATURE_CORECLR
BOOL AppDomain::BindingByManifestFile()
{
return FALSE;
}
-#endif
ReJitManager::ReJitManager()
{
diff --git a/src/vm/crst.cpp b/src/vm/crst.cpp
index 7bf9bd65da..36447e2232 100644
--- a/src/vm/crst.cpp
+++ b/src/vm/crst.cpp
@@ -33,56 +33,14 @@ VOID CrstBase::InitWorker(INDEBUG_COMMA(CrstType crstType) CrstFlags flags)
CONTRACTL {
THROWS;
WRAPPER(GC_TRIGGERS);
- } CONTRACTL_END;
-
- // Disallow creation of Crst before EE starts. But only complain if we end up
- // being hosted, since such Crsts have escaped the hosting net and will cause
- // AVs on next use.
-#ifdef _DEBUG
- static bool fEarlyInit; // = false
-
- if (!g_fEEStarted)
- {
- if (!CLRSyncHosted())
- fEarlyInit = true;
- }
-
- // If we are now hosted, we better not have *ever* created some Crsts that are
- // not known to our host.
- _ASSERTE(!fEarlyInit || !CLRSyncHosted());
-
-#endif
+ } CONTRACTL_END;
_ASSERTE((flags & CRST_INITIALIZED) == 0);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSyncManager *pSyncManager = CorHost2::GetHostSyncManager();
- if (pSyncManager) {
- ResetOSCritSec ();
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
SetOSCritSec ();
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (!IsOSCritSec())
- {
- IHostCrst *pHostCrst;
- PREFIX_ASSUME(pSyncManager != NULL);
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pSyncManager->CreateCrst(&pHostCrst);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (hr != S_OK) {
- _ASSERTE(hr == E_OUTOFMEMORY);
- ThrowOutOfMemory();
- }
- m_pHostCrst = pHostCrst;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
UnsafeInitializeCriticalSection(&m_criticalsection);
}
@@ -118,15 +76,6 @@ void CrstBase::Destroy()
// deadlock detection is finished.
GCPreemp __gcHolder((m_dwFlags & CRST_HOST_BREAKABLE) == CRST_HOST_BREAKABLE);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (!IsOSCritSec())
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- m_pHostCrst->Release();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
UnsafeDeleteCriticalSection(&m_criticalsection);
}
@@ -202,62 +151,6 @@ void CrstBase::Enter(INDEBUG(NoLevelCheckFlag noLevelCheckFlag/* = CRST_LEVEL_CH
#else // !DACCESS_COMPILE
-#if !defined(FEATURE_CORECLR)
-// Slower spin enter path after first attemp failed
-void CrstBase::SpinEnter()
-{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_GC_NOTRIGGER;
- STATIC_CONTRACT_CAN_TAKE_LOCK;
-
- // We only reach this routine when first attemp failed, so time to fire ETW event (fyuan)
-
- // Fire an ETW event to mark the beginning of native contention
- FireEtwContentionStart_V1(ETW::ContentionLog::ContentionStructs::NativeContention, GetClrInstanceId());
-
- // Try spinning and yielding before eventually blocking.
- // The limit of dwRepetitions = 10 is largely arbitrary - feel free to tune if you have evidence
- // you're making things better.
-
- for (DWORD iter = 0; iter < g_SpinConstants.dwRepetitions; iter++)
- {
- DWORD i = g_SpinConstants.dwInitialDuration;
-
- do
- {
- if ( (m_criticalsection.LockCount == -1 ||
- (size_t)m_criticalsection.OwningThread == (size_t) GetCurrentThreadId())
- && UnsafeTryEnterCriticalSection(&m_criticalsection))
- {
- return;
- }
-
- if (g_SystemInfo.dwNumberOfProcessors <= 1)
- {
- break;
- }
-
- // Delay by approximately 2*i clock cycles (Pentium III).
- // This is brittle code - future processors may of course execute this
- // faster or slower, and future code generators may eliminate the loop altogether.
- // The precise value of the delay is not critical, however, and can't think
- // of a better way that isn't machine-dependent.
-
- for (int delayCount = i; --delayCount; )
- {
- YieldProcessor(); // indicate to the processor that we are spining
- }
-
- // exponential backoff: wait a factor longer in the next iteration
- i *= g_SpinConstants.dwBackoffFactor;
- } while (i < g_SpinConstants.dwMaximumDuration);
-
- __SwitchToThread(0, CALLER_LIMITS_SPINNING);
- }
-
- UnsafeEnterCriticalSection(& m_criticalsection);
-}
-#endif // FEATURE_CORECLR
void CrstBase::Enter(INDEBUG(NoLevelCheckFlag noLevelCheckFlag/* = CRST_LEVEL_CHECK*/))
@@ -417,84 +310,7 @@ void CrstBase::Enter(INDEBUG(NoLevelCheckFlag noLevelCheckFlag/* = CRST_LEVEL_CH
}
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (!IsOSCritSec())
- {
- DWORD option;
- if (m_dwFlags & CRST_HOST_BREAKABLE)
- {
- option = 0;
- }
- else
- {
- option = WAIT_NOTINDEADLOCK;
- }
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(pThread);
-
- // Try entering the critical section once, if we fail we contend
- // and fire the contention start ETW event
- hr = m_pHostCrst->TryEnter(option, &fIsCriticalSectionEnteredAfterFailingOnce);
-
- if (! fIsCriticalSectionEnteredAfterFailingOnce)
- {
-#ifndef FEATURE_CORECLR
- // Fire an ETW event to mark the beginning of native contention
- FireEtwContentionStart_V1(ETW::ContentionLog::ContentionStructs::NativeContention, GetClrInstanceId());
-#endif // !FEATURE_CORECLR
- fIsCriticalSectionEnteredAfterFailingOnce = TRUE;
-
- hr = m_pHostCrst->Enter(option);
- }
- END_SO_TOLERANT_CODE_CALLING_HOST;
-
- PREFIX_ASSUME (hr == S_OK || ((m_dwFlags & CRST_HOST_BREAKABLE) && hr == HOST_E_DEADLOCK));
-
- if (hr == HOST_E_DEADLOCK)
- {
- RaiseDeadLockException();
- }
-
- INCTHREADLOCKCOUNTTHREAD(pThread);
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- {
- if (CLRTaskHosted())
- {
- Thread::BeginThreadAffinity();
- }
-
-#ifdef FEATURE_CORECLR
- UnsafeEnterCriticalSection(&m_criticalsection);
-#else
- // Try entering the critical section once, if we fail we contend
- // and fire the contention start ETW event
- if ((m_criticalsection.LockCount == -1 || (size_t)m_criticalsection.OwningThread == (size_t) GetCurrentThreadId())
- && UnsafeTryEnterCriticalSection(& m_criticalsection))
- {
- }
- else
- {
- SpinEnter();
-
- fIsCriticalSectionEnteredAfterFailingOnce = TRUE;
- }
-#endif
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- INCTHREADLOCKCOUNTTHREAD(pThread);
-#endif
- }
-
-#ifndef FEATURE_CORECLR
- // Fire an ETW event to mark the end of native contention
- // This we do only when we have fired a contention start event before
- if (fIsCriticalSectionEnteredAfterFailingOnce)
- {
- FireEtwContentionStop(ETW::ContentionLog::ContentionStructs::NativeContention, GetClrInstanceId());
- }
-#endif // !FEATURE_CORECLR
+ UnsafeEnterCriticalSection(&m_criticalsection);
#ifdef _DEBUG
PostEnter();
@@ -523,32 +339,11 @@ void CrstBase::Leave()
PreLeave ();
#endif //_DEBUG
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) || defined(_DEBUG)
+#if defined(_DEBUG)
Thread * pThread = GetThread();
#endif
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (!IsOSCritSec()) {
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(pThread);
- hr = m_pHostCrst->Leave();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- _ASSERTE (hr == S_OK);
- DECTHREADLOCKCOUNT ();
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- {
- UnsafeLeaveCriticalSection(&m_criticalsection);
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- DECTHREADLOCKCOUNTTHREAD(pThread);
-#endif
-
- if (CLRTaskHosted()) {
- Thread::EndThreadAffinity();
- }
- }
+ UnsafeLeaveCriticalSection(&m_criticalsection);
// Check for both rare case using one if-check
if (m_dwFlags & (CRST_TAKEN_DURING_SHUTDOWN | CRST_DEBUGGER_THREAD))
diff --git a/src/vm/crst.h b/src/vm/crst.h
index c68f40679c..a353c6ea44 100644
--- a/src/vm/crst.h
+++ b/src/vm/crst.h
@@ -297,9 +297,6 @@ protected:
union {
CRITICAL_SECTION m_criticalsection;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostCrst *m_pHostCrst;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
};
typedef enum
diff --git a/src/vm/customattribute.cpp b/src/vm/customattribute.cpp
index a83815f8bf..5b679548db 100644
--- a/src/vm/customattribute.cpp
+++ b/src/vm/customattribute.cpp
@@ -906,93 +906,6 @@ FCIMPL5(VOID, COMCustomAttribute::ParseAttributeUsageAttribute, PVOID pData, ULO
}
FCIMPLEND
-#ifdef FEATURE_CAS_POLICY
-FCIMPL4(VOID, COMCustomAttribute::GetSecurityAttributes, ReflectModuleBaseObject *pModuleUNSAFE, DWORD tkToken, CLR_BOOL fAssembly, PTRARRAYREF* ppArray)
-{
- FCALL_CONTRACT;
-
- OBJECTREF throwable = NULL;
- REFLECTMODULEBASEREF refModule = (REFLECTMODULEBASEREF)ObjectToOBJECTREF(pModuleUNSAFE);
-
- if(refModule == NULL)
- FCThrowResVoid(kArgumentNullException, W("Arg_InvalidHandle"));
-
- Module *pModule = refModule->GetModule();
-
- HELPER_METHOD_FRAME_BEGIN_2(throwable, refModule);
- {
- IMDInternalImport* pScope = pModule->GetMDImport();
-
- DWORD action;
-
- CORSEC_ATTRSET_ARRAY aAttrset;
- DWORD dwCount = 0;
- for(action = 1; action <= dclMaximumValue; action++)
- {
- // We cannot use IsAssemblyDclAction(action) != fAssembly because CLR_BOOL is defined
- // as BYTE in PAL so it might contain a value other than 0 or 1.
- if (IsNGenOnlyDclAction(action) || IsAssemblyDclAction(action) == !fAssembly)
- continue;
-
- HENUMInternalHolder hEnum(pScope);
- if (!hEnum.EnumPermissionSetsInit(tkToken, (CorDeclSecurity)action))
- continue;
-
- mdPermission tkPerm;
- BYTE* pbBlob;
- ULONG cbBlob;
- DWORD dwAction;
-
- while (pScope->EnumNext(&hEnum, &tkPerm))
- {
- IfFailThrow(pScope->GetPermissionSetProps(
- tkPerm,
- &dwAction,
- (void const **)&pbBlob,
- &cbBlob));
-
- CORSEC_ATTRSET* pAttrSet = &*aAttrset.Append();
- IfFailThrow(BlobToAttributeSet(pbBlob, cbBlob, pAttrSet, dwAction));
-
- dwCount += pAttrSet->dwAttrCount;
- }
- }
-
- *ppArray = (PTRARRAYREF)AllocateObjectArray(dwCount, g_pObjectClass);
-
- CQuickBytes qb;
-
- COUNT_T c = 0;
- for (COUNT_T i = 0; i < aAttrset.GetCount(); i ++)
- {
- CORSEC_ATTRSET& attrset = aAttrset[i];
- OBJECTREF* attrArray = (OBJECTREF*)qb.AllocThrows(attrset.dwAttrCount * sizeof(OBJECTREF));
- memset(attrArray, 0, attrset.dwAttrCount * sizeof(OBJECTREF));
- {
- // Convert to a managed array of attribute objects
- DWORD dwErrorIndex;
- HRESULT hr = E_FAIL;
- GCPROTECT_ARRAY_BEGIN(*attrArray, attrset.dwAttrCount);
- // This is very tricky.
- // We have a GCFrame local here. The local goes out of scope beyond for loop. The stack location of the local
- // is then reused by other variables, and the content in GCFrame may be changed. But the Frame is still chained
- // on our Thread object.
- // If exception is thrown before we pop our frame chain, we will have corrupted frame chain.
- hr = SecurityAttributes::AttributeSetToManaged(attrArray, &attrset, &throwable, &dwErrorIndex, true);
- GCPROTECT_END();
- if (FAILED(hr))
- COMPlusThrowHR(hr);
-
- for (COUNT_T j = 0; j < attrset.dwAttrCount; j ++)
- (*ppArray)->SetAt(c++, attrArray[j]);
- }
-
- }
- }
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-#endif // FEATURE_CAS_POLICY
FCIMPL7(void, COMCustomAttribute::GetPropertyOrFieldData, ReflectModuleBaseObject *pModuleUNSAFE, BYTE** ppBlobStart, BYTE* pBlobEnd, STRINGREF* pName, CLR_BOOL* pbIsProperty, OBJECTREF* pType, OBJECTREF* value)
{
diff --git a/src/vm/dangerousapis.h b/src/vm/dangerousapis.h
index 13122b7e8d..51686135e8 100644
--- a/src/vm/dangerousapis.h
+++ b/src/vm/dangerousapis.h
@@ -48,20 +48,6 @@ DEFINE_DANGEROUS_API(EVENT_INFO, API_NAMES("AddEventHandler", "Re
DEFINE_DANGEROUS_API(EVENT, API_NAMES("AddEventHandler", "RemoveEventHandler", "ToString"))
DEFINE_DANGEROUS_API(RESOURCE_MANAGER, API_NAMES("GetResourceSet", "InternalGetResourceSet", ".ctor"))
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
-// The COM interfaces implemented by the reflection types.
-// The IDispatch Invoke methods are not included here because they are not implemented in mscorlib.
-DEFINE_DANGEROUS_API(ITYPE, API_NAMES("InvokeMember"))
-DEFINE_DANGEROUS_API(IASSEMBLY, API_NAMES("CreateInstance"))
-DEFINE_DANGEROUS_API(IMETHODBASE, API_NAMES("Invoke"))
-DEFINE_DANGEROUS_API(IMETHODINFO, API_NAMES("Invoke"))
-DEFINE_DANGEROUS_API(ICONSTRUCTORINFO, API_NAMES("Invoke", "Invoke_2", "Invoke_3", "Invoke_4", "Invoke_5"))
-DEFINE_DANGEROUS_API(IFIELDINFO, API_NAMES("GetValue", "SetValue"))
-DEFINE_DANGEROUS_API(IPROPERTYINFO, API_NAMES("GetValue", "SetValue"))
-DEFINE_DANGEROUS_API(IEVENTINFO, API_NAMES("AddEventHandler", "RemoveEventHandler"))
-DEFINE_DANGEROUS_API(IAPPDOMAIN, API_NAMES("CreateInstance", "CreateInstanceFrom", "DefineDynamicAssembly", "Load"))
-DEFINE_DANGEROUS_API(IREFLECT, API_NAMES("InvokeMember"))
-#endif // FEATURE_COMINTEROP && !FEATURE_CORECLR
diff --git a/src/vm/dataimage.cpp b/src/vm/dataimage.cpp
index e90c7e6a0e..fc584d7b39 100644
--- a/src/vm/dataimage.cpp
+++ b/src/vm/dataimage.cpp
@@ -12,7 +12,6 @@
#include "compile.h"
#include "field.h"
-#include "constrainedexecutionregion.h"
//
// Include Zapper infrastructure here
@@ -127,12 +126,7 @@ DataImage::DataImage(Module *module, CEEPreloader *preloader)
m_pZapImage->m_pDataImage = this;
m_pInternedStructures = new InternedStructureHashTable();
-
-#ifdef FEATURE_CORECLR
- m_inlineTrackingMap = NULL;
-#else
m_inlineTrackingMap = new InlineTrackingMap();
-#endif
}
DataImage::~DataImage()
@@ -896,10 +890,6 @@ void DataImage::FixupRVAs()
FixupModuleRVAs();
FixupRvaStructure();
-#ifdef FEATURE_CER
- if (m_module->m_pCerNgenRootTable != NULL)
- m_module->m_pCerNgenRootTable->FixupRVAs(this);
-#endif
// Dev11 bug 181494 instrumentation
if (m_Fixups.GetCount() != m_iCurrentFixup) EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
diff --git a/src/vm/debugdebugger.cpp b/src/vm/debugdebugger.cpp
index c8b76bf6dc..489c623df9 100644
--- a/src/vm/debugdebugger.cpp
+++ b/src/vm/debugdebugger.cpp
@@ -102,61 +102,6 @@ UINT_PTR FindMostRecentUserCodeOnStack(void)
return address;
}
-#ifndef FEATURE_CORECLR
-// Call into the unhandled-exception processing code to launch Watson.
-//
-// Arguments:
-// address - address to distinguish callsite of break.
-//
-// Notes:
-// Invokes a watson dialog in response to a user break (Debug.Break).
-// Assumes that caller has already enforced any policy it cares about related to whether a debugger is attached.
-void DoWatsonForUserBreak(UINT_PTR address)
-{
- CONTRACTL
- {
- MODE_ANY;
- GC_TRIGGERS;
- THROWS;
- PRECONDITION(address != NULL);
- }
- CONTRACTL_END;
-
- CONTEXT context;
- EXCEPTION_RECORD exceptionRecord;
- EXCEPTION_POINTERS exceptionPointers;
-
- ZeroMemory(&context, sizeof(context));
- ZeroMemory(&exceptionRecord, sizeof(exceptionRecord));
- ZeroMemory(&exceptionPointers, sizeof(exceptionPointers));
-
- // Try to locate the user managed code invoking System.Diagnostics.Debugger.Break
- UINT_PTR userCodeAddress = FindMostRecentUserCodeOnStack();
- if (userCodeAddress != NULL)
- {
- address = userCodeAddress;
- }
-
- LOG((LF_EH, LL_INFO10, "DoDebugBreak: break at %0p\n", address));
-
- exceptionRecord.ExceptionAddress = reinterpret_cast< PVOID >(address);
- exceptionPointers.ExceptionRecord = &exceptionRecord;
- exceptionPointers.ContextRecord = &context;
-
- Thread *pThread = GetThread();
- PTR_EHWatsonBucketTracker pUEWatsonBucketTracker = pThread->GetExceptionState()->GetUEWatsonBucketTracker();
- _ASSERTE(pUEWatsonBucketTracker != NULL);
- pUEWatsonBucketTracker->SaveIpForWatsonBucket(address);
- pUEWatsonBucketTracker->CaptureUnhandledInfoForWatson(TypeOfReportedError::UserBreakpoint, pThread, NULL);
- if (pUEWatsonBucketTracker->RetrieveWatsonBuckets() == NULL)
- {
- pUEWatsonBucketTracker->ClearWatsonBucketDetails();
- }
-
- WatsonLastChance(GetThread(), &exceptionPointers, TypeOfReportedError::UserBreakpoint);
-
-} // void DoDebugBreak()
-#endif // !FEATURE_CORECLR
// This does a user break, triggered by System.Diagnostics.Debugger.Break, or the IL opcode for break.
//
@@ -210,12 +155,6 @@ FCIMPL0(void, DebugDebugger::Break)
}
else
{
-#ifndef FEATURE_CORECLR
- // No debugger attached -- Watson up.
-
- // The HelperMethodFrame knows how to get the return address.
- DoWatsonForUserBreak(HELPER_METHOD_FRAME_GET_RETURN_ADDRESS());
-#endif //FEATURE_CORECLR
}
HELPER_METHOD_FRAME_END();
@@ -507,7 +446,6 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgiColumnNumber), (OBJECTREF)columnNumbers,
pStackFrameHelper->GetAppDomain());
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
// Allocate memory for the flag indicating if this frame represents the last one from a foreign
// exception stack trace provided we have any such frames. Otherwise, set it to null.
// When StackFrameHelper.IsLastFrameFromForeignExceptionStackTrace is invoked in managed code,
@@ -528,7 +466,6 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
SetObjectReference( (OBJECTREF *)&(pStackFrameHelper->rgiLastFrameFromForeignExceptionStackTrace), NULL,
pStackFrameHelper->GetAppDomain());
}
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
// Determine if there are any dynamic methods in the stack trace. If there are,
// allocate an ObjectArray large enough to hold an ObjRef to each one.
@@ -579,7 +516,6 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
I4 *pILI4 = (I4 *)((I4ARRAYREF)pStackFrameHelper->rgiILOffset)->GetDirectPointerToNonObjectElements();
pILI4[iNumValidFrames] = data.pElements[i].dwILOffset;
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
if (data.fDoWeHaveAnyFramesFromForeignStackTrace)
{
// Set the BOOL indicating if the frame represents the last frame from a foreign exception stack trace.
@@ -587,7 +523,6 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal,
->GetDirectPointerToNonObjectElements();
pIsLastFrameFromForeignExceptionStackTraceU1 [iNumValidFrames] = (U1) data.pElements[i].fIsLastFrameFromForeignStackTrace;
}
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
MethodDesc *pMethod = data.pElements[i].pFunc;
@@ -1002,62 +937,8 @@ void DebugStackTrace::GetStackFramesHelper(Frame *pStartFrame,
goto LSafeToTrace;
}
- if (state & Thread::TS_UserSuspendPending)
- {
- if (state & Thread::TS_SyncSuspended)
- {
- goto LSafeToTrace;
- }
-
-#ifndef DISABLE_THREADSUSPEND
- // On Mac don't perform the optimization below, but rather wait for
- // the suspendee to set the TS_SyncSuspended flag
-
- // The target thread is not actually suspended yet, but if it is
- // in preemptive mode, then it is still safe to trace. Before we
- // can look at another thread's GC mode, we have to suspend it:
- // The target thread updates its GC mode flag with non-interlocked
- // operations, and Thread::SuspendThread drains the CPU's store
- // buffer (by virtue of calling GetThreadContext).
- switch (pThread->SuspendThread())
- {
- case Thread::STR_Success:
- if (!pThread->PreemptiveGCDisabledOther())
- {
- pThread->ResumeThread();
- goto LSafeToTrace;
- }
-
- // Refuse to trace the stack.
- //
- // Note that there is a pretty large window in-between when the
- // target thread sets the GC mode to cooperative, and when it
- // actually sets the TS_SyncSuspended bit. In this window, we
- // will refuse to take a stack trace even though it would be
- // safe to do so.
- pThread->ResumeThread();
- break;
- case Thread::STR_Failure:
- case Thread::STR_NoStressLog:
- break;
- case Thread::STR_UnstartedOrDead:
- // We know the thread is not unstarted, because we checked for
- // TS_Unstarted above.
- _ASSERTE(!(state & Thread::TS_Unstarted));
-
- // Since the thread is dead, it is safe to trace.
- goto LSafeToTrace;
- case Thread::STR_SwitchedOut:
- if (!pThread->PreemptiveGCDisabledOther())
- {
- goto LSafeToTrace;
- }
- break;
- default:
- UNREACHABLE();
- }
-#endif // DISABLE_THREADSUSPEND
- }
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(state & Thread::TS_UserSuspendPending));
COMPlusThrow(kThreadStateException, IDS_EE_THREAD_BAD_STATE);
@@ -1223,10 +1104,8 @@ void DebugStackTrace::GetStackFramesFromException(OBJECTREF * e,
// The number of frame info elements in the stack trace info
pData->cElements = static_cast<int>(traceData.Size());
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
// By default, assume that we have no frames from foreign exception stack trace.
pData->fDoWeHaveAnyFramesFromForeignStackTrace = FALSE;
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
// Now we know the size, allocate the information for the data struct
if (pData->cElements != 0)
@@ -1239,7 +1118,6 @@ void DebugStackTrace::GetStackFramesFromException(OBJECTREF * e,
{
StackTraceElement const & cur = traceData[i];
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
// If we come across any frame representing foreign exception stack trace,
// then set the flag indicating so. This will be used to allocate the
// corresponding array in StackFrameHelper.
@@ -1247,7 +1125,6 @@ void DebugStackTrace::GetStackFramesFromException(OBJECTREF * e,
{
pData->fDoWeHaveAnyFramesFromForeignStackTrace = TRUE;
}
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
// Fill out the MethodDesc*
MethodDesc *pMD = cur.pFunc;
@@ -1270,9 +1147,7 @@ void DebugStackTrace::GetStackFramesFromException(OBJECTREF * e,
}
pData->pElements[i].InitPass1(dwNativeOffset, pMD, (PCODE) cur.ip
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
, cur.fIsLastFrameFromForeignStackTrace
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
);
#ifndef DACCESS_COMPILE
pData->pElements[i].InitPass2();
@@ -1294,9 +1169,7 @@ void DebugStackTrace::DebugStackTraceElement::InitPass1(
DWORD dwNativeOffset,
MethodDesc *pFunc,
PCODE ip
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
, BOOL fIsLastFrameFromForeignStackTrace /*= FALSE*/
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
)
{
LIMITED_METHOD_CONTRACT;
@@ -1308,9 +1181,7 @@ void DebugStackTrace::DebugStackTraceElement::InitPass1(
this->pFunc = pFunc;
this->dwOffset = dwNativeOffset;
this->ip = ip;
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
this->fIsLastFrameFromForeignStackTrace = fIsLastFrameFromForeignStackTrace;
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
}
#ifndef DACCESS_COMPILE
diff --git a/src/vm/debugdebugger.h b/src/vm/debugdebugger.h
index 9cf5c3c0f0..6c4d383765 100644
--- a/src/vm/debugdebugger.h
+++ b/src/vm/debugdebugger.h
@@ -92,9 +92,7 @@ public:
I4ARRAYREF rgiLineNumber;
I4ARRAYREF rgiColumnNumber;
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
BOOLARRAYREF rgiLastFrameFromForeignExceptionStackTrace;
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
OBJECTREF getSourceLineInfo;
int iFrameCount;
@@ -136,11 +134,9 @@ private:
DWORD dwILOffset;
MethodDesc *pFunc;
PCODE ip;
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
// TRUE if this element represents the last frame of the foreign
// exception stack trace.
BOOL fIsLastFrameFromForeignStackTrace;
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
// Initialization done under TSL.
// This is used when first collecting the stack frame data.
@@ -148,9 +144,7 @@ private:
DWORD dwNativeOffset,
MethodDesc *pFunc,
PCODE ip
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
, BOOL fIsLastFrameFromForeignStackTrace = FALSE
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
);
// Initialization done outside the TSL.
@@ -171,9 +165,7 @@ public:
DebugStackTraceElement* pElements;
THREADBASEREF TargetThread;
AppDomain *pDomain;
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
BOOL fDoWeHaveAnyFramesFromForeignStackTrace;
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
GetStackFramesData() : skip(0),
@@ -184,9 +176,7 @@ public:
TargetThread((THREADBASEREF)(TADDR)NULL)
{
LIMITED_METHOD_CONTRACT;
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
fDoWeHaveAnyFramesFromForeignStackTrace = FALSE;
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
}
diff --git a/src/vm/debughelp.cpp b/src/vm/debughelp.cpp
index abe45d5da0..3e66f14047 100644
--- a/src/vm/debughelp.cpp
+++ b/src/vm/debughelp.cpp
@@ -245,7 +245,7 @@ MethodDesc* IP2MD(ULONG_PTR IP)
}
/*******************************************************************/
-/* if addr is a valid method table, return a poitner to it */
+/* if addr is a valid method table, return a pointer to it */
MethodTable* AsMethodTable(size_t addr)
{
CONTRACTL
diff --git a/src/vm/disassembler.h b/src/vm/disassembler.h
index 1b3bf46e0e..5a7976a44f 100644
--- a/src/vm/disassembler.h
+++ b/src/vm/disassembler.h
@@ -10,7 +10,6 @@
#define USE_COREDISTOOLS_DISASSEMBLER 0
#define USE_MSVC_DISASSEMBLER 0
#ifdef HAVE_GCCOVER
- #if defined(FEATURE_CORECLR)
// COREDISTOOLS disassembler only supports amd64 and x86, so if this is
// CoreCLR but not amd64 and not x86, we will fall out of this check and not
// set USE_DISASSEMBLER.
@@ -18,10 +17,6 @@
#undef USE_COREDISTOOLS_DISASSEMBLER
#define USE_COREDISTOOLS_DISASSEMBLER 1
#endif
- #elif defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
- #undef USE_MSVC_DISASSEMBLER
- #define USE_MSVC_DISASSEMBLER 1
- #endif // defined(FEATURE_CORECLR) || defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
#endif // HAVE_GCCOVER
#if USE_COREDISTOOLS_DISASSEMBLER
diff --git a/src/vm/dllimport.cpp b/src/vm/dllimport.cpp
index b7989e92bc..3abe9cbf46 100644
--- a/src/vm/dllimport.cpp
+++ b/src/vm/dllimport.cpp
@@ -50,10 +50,6 @@
#include "eventtrace.h"
-#ifndef FEATURE_CORECLR
-#define NEEDDATA
-#include "fxretarget.h"
-#endif
#include "clr/fs/path.h"
using namespace clr::fs;
@@ -913,7 +909,6 @@ public:
}
#endif // MDA_SUPPORTED
-#ifdef FEATURE_CORECLR
// For CoreClr, clear the last error before calling the target that returns last error.
// There isn't always a way to know the function have failed without checking last error,
// in particular on Unix.
@@ -921,7 +916,6 @@ public:
{
pcsDispatch->EmitCALL(METHOD__STUBHELPERS__CLEAR_LAST_ERROR, 0, 0);
}
-#endif // FEATURE_CORECLR
// Invoke the target (calli, call method, call delegate, get/set field, etc.)
EmitInvokeTarget(pStubMD);
@@ -1158,178 +1152,8 @@ public:
LOG((LF_STUBS, LL_INFO1000, "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"));
#endif // LOGGING
-#ifndef FEATURE_CORECLR
- //
- // Publish ETW events for IL stubs
- //
-
- // If the category and the event is enabled...
- if (ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, ILStubGenerated))
- {
- EtwOnILStubGenerated(
- pStubMD,
- pbLocalSig,
- cbSig,
- jitFlags,
- &convertToHRTryCatch,
- &cleanupTryFinally,
- maxStack,
- (DWORD)cbCode
- );
- }
-#endif // !FEATURE_CORECLR
}
-#ifndef FEATURE_CORECLR
- //---------------------------------------------------------------------------------------
- //
- void
- EtwOnILStubGenerated(
- MethodDesc * pStubMD,
- PCCOR_SIGNATURE pbLocalSig,
- DWORD cbSig,
- CORJIT_FLAGS jitFlags,
- ILStubEHClause * pConvertToHRTryCatchBounds,
- ILStubEHClause * pCleanupTryFinallyBounds,
- DWORD maxStack,
- DWORD cbCode)
- {
- STANDARD_VM_CONTRACT;
-
- //
- // Interop Method Information
- //
- MethodDesc *pTargetMD = m_slIL.GetTargetMD();
- SString strNamespaceOrClassName, strMethodName, strMethodSignature;
- UINT64 uModuleId = 0;
-
- if (pTargetMD)
- {
- pTargetMD->GetMethodInfoWithNewSig(strNamespaceOrClassName, strMethodName, strMethodSignature);
- uModuleId = (UINT64)pTargetMD->GetModule()->GetAddrModuleID();
- }
-
- //
- // Stub Method Signature
- //
- SString stubNamespaceOrClassName, stubMethodName, stubMethodSignature;
- pStubMD->GetMethodInfoWithNewSig(stubNamespaceOrClassName, stubMethodName, stubMethodSignature);
-
- IMDInternalImport *pStubImport = pStubMD->GetModule()->GetMDImport();
-
- CQuickBytes qbLocal;
- PrettyPrintSig(pbLocalSig, (DWORD)cbSig, NULL, &qbLocal, pStubImport, NULL);
-
- SString strLocalSig(SString::Utf8, (LPCUTF8)qbLocal.Ptr());
-
- //
- // Native Signature
- //
- SString strNativeSignature(SString::Utf8);
- if (m_dwStubFlags & NDIRECTSTUB_FL_REVERSE_INTEROP)
- {
- // Reverse interop. Use StubSignature
- strNativeSignature = stubMethodSignature;
- }
- else
- {
- // Forward interop. Use StubTarget siganture
- PCCOR_SIGNATURE pCallTargetSig = GetStubTargetMethodSig();
- DWORD cCallTargetSig = GetStubTargetMethodSigLength();
-
- CQuickBytes qbCallTargetSig;
-
- PrettyPrintSig(pCallTargetSig, cCallTargetSig, "", &qbCallTargetSig, pStubImport, NULL);
-
- strNativeSignature.SetUTF8((LPCUTF8)qbCallTargetSig.Ptr());
- }
-
- //
- // Dump IL stub code
- //
- SString strILStubCode;
- strILStubCode.Preallocate(4096); // Preallocate 4K bytes to avoid unnecessary growth
-
- SString codeSizeFormat;
- codeSizeFormat.LoadResource(CCompRC::Optional, IDS_EE_INTEROP_CODE_SIZE_COMMENT);
- strILStubCode.AppendPrintf(W("// %s\t%d (0x%04x)\n"), codeSizeFormat.GetUnicode(), cbCode, cbCode);
- strILStubCode.AppendPrintf(W(".maxstack %d \n"), maxStack);
- strILStubCode.AppendPrintf(W(".locals %s\n"), strLocalSig.GetUnicode());
-
- m_slIL.LogILStub(jitFlags, &strILStubCode);
-
- if (pConvertToHRTryCatchBounds->cbTryLength != 0 && pConvertToHRTryCatchBounds->cbHandlerLength != 0)
- {
- strILStubCode.AppendPrintf(
- W(".try IL_%04x to IL_%04x catch handler IL_%04x to IL_%04x\n"),
- pConvertToHRTryCatchBounds->dwTryBeginOffset,
- pConvertToHRTryCatchBounds->dwTryBeginOffset + pConvertToHRTryCatchBounds->cbTryLength,
- pConvertToHRTryCatchBounds->dwHandlerBeginOffset,
- pConvertToHRTryCatchBounds->dwHandlerBeginOffset + pConvertToHRTryCatchBounds->cbHandlerLength);
- }
-
- if (pCleanupTryFinallyBounds->cbTryLength != 0 && pCleanupTryFinallyBounds->cbHandlerLength != 0)
- {
- strILStubCode.AppendPrintf(
- W(".try IL_%04x to IL_%04x finally handler IL_%04x to IL_%04x\n"),
- pCleanupTryFinallyBounds->dwTryBeginOffset,
- pCleanupTryFinallyBounds->dwTryBeginOffset + pCleanupTryFinallyBounds->cbTryLength,
- pCleanupTryFinallyBounds->dwHandlerBeginOffset,
- pCleanupTryFinallyBounds->dwHandlerBeginOffset + pCleanupTryFinallyBounds->cbHandlerLength);
- }
-
- //
- // Fire the event
- //
- DWORD dwFlags = 0;
- if (m_dwStubFlags & NDIRECTSTUB_FL_REVERSE_INTEROP)
- dwFlags |= ETW_IL_STUB_FLAGS_REVERSE_INTEROP;
-#ifdef FEATURE_COMINTEROP
- if (m_dwStubFlags & NDIRECTSTUB_FL_COM)
- dwFlags |= ETW_IL_STUB_FLAGS_COM_INTEROP;
-#endif // FEATURE_COMINTEROP
- if (m_dwStubFlags & NDIRECTSTUB_FL_NGENEDSTUB)
- dwFlags |= ETW_IL_STUB_FLAGS_NGENED_STUB;
- if (m_dwStubFlags & NDIRECTSTUB_FL_DELEGATE)
- dwFlags |= ETW_IL_STUB_FLAGS_DELEGATE;
- if (m_dwStubFlags & NDIRECTSTUB_FL_CONVSIGASVARARG)
- dwFlags |= ETW_IL_STUB_FLAGS_VARARG;
- if (m_dwStubFlags & NDIRECTSTUB_FL_UNMANAGED_CALLI)
- dwFlags |= ETW_IL_STUB_FLAGS_UNMANAGED_CALLI;
-
- DWORD dwToken = 0;
- if (pTargetMD)
- dwToken = pTargetMD->GetMemberDef();
-
-
- //
- // Truncate string fields. Make sure the whole event is less than 64KB
- //
- TruncateUnicodeString(strNamespaceOrClassName, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
- TruncateUnicodeString(strMethodName, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
- TruncateUnicodeString(strMethodSignature, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
- TruncateUnicodeString(strNativeSignature, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
- TruncateUnicodeString(stubMethodSignature, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
- TruncateUnicodeString(strILStubCode, ETW_IL_STUB_EVENT_CODE_STRING_FIELD_MAXSIZE);
-
- //
- // Fire ETW event
- //
- FireEtwILStubGenerated(
- GetClrInstanceId(), // ClrInstanceId
- uModuleId, // ModuleIdentifier
- (UINT64)pStubMD, // StubMethodIdentifier
- dwFlags, // StubFlags
- dwToken, // ManagedInteropMethodToken
- strNamespaceOrClassName.GetUnicode(), // ManagedInteropMethodNamespace
- strMethodName.GetUnicode(), // ManagedInteropMethodName
- strMethodSignature.GetUnicode(), // ManagedInteropMethodSignature
- strNativeSignature.GetUnicode(), // NativeSignature
- stubMethodSignature.GetUnicode(), // StubMethodSigature
- strILStubCode.GetUnicode() // StubMethodILCode
- );
- } // EtwOnILStubGenerated
-#endif // !FEATURE_CORECLR
#ifdef LOGGING
//---------------------------------------------------------------------------------------
@@ -1790,10 +1614,6 @@ NDirectStubLinker::NDirectStubLinker(
m_dwThreadLocalNum(-1),
m_dwCleanupWorkListLocalNum(-1),
m_dwRetValLocalNum(-1),
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- m_dwFirstCopyCtorCookieLocalNum(-1),
- m_dwLastCopyCtorCookieLocalNum(-1),
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
m_ErrorResID(-1),
m_ErrorParamIdx(-1),
m_iLCIDParamIdx(iLCIDParamIdx),
@@ -2218,46 +2038,6 @@ void NDirectStubLinker::LoadCleanupWorkList(ILCodeStream* pcsEmit)
pcsEmit->EmitLDLOCA(GetCleanupWorkListLocalNum());
}
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
-
-BOOL NDirectStubLinker::IsCopyCtorStubNeeded()
-{
- LIMITED_METHOD_CONTRACT;
- return (m_dwFirstCopyCtorCookieLocalNum != (DWORD)-1);
-}
-
-DWORD NDirectStubLinker::CreateCopyCtorCookie(ILCodeStream* pcsEmit)
-{
- STANDARD_VM_CONTRACT;
-
- MethodTable *pCookieMT = MscorlibBinder::GetClass(CLASS__COPYCTORSTUBCOOKIE);
-
- LocalDesc desc(pCookieMT);
- DWORD dwCookieLocalNum = pcsEmit->NewLocal(desc);
-
- // <dwCookieLocalNum> = new CopyCtorStubCookie()
- pcsEmit->EmitLDLOCA(dwCookieLocalNum);
- pcsEmit->EmitINITOBJ(pcsEmit->GetToken(pCookieMT));
-
- if (m_dwLastCopyCtorCookieLocalNum == (DWORD)-1)
- {
- // this is the first cookie in this stub
- m_dwFirstCopyCtorCookieLocalNum = dwCookieLocalNum;
- }
- else
- {
- // this is not the first cookie - build a linked list
- // <m_dwLastCopyCtorCookieLocalNum>.SetNext(&<dwCookieLocalNum>)
- pcsEmit->EmitLDLOCA(m_dwLastCopyCtorCookieLocalNum);
- pcsEmit->EmitLDLOCA(dwCookieLocalNum);
- pcsEmit->EmitCALL(METHOD__COPYCTORSTUBCOOKIE__SET_NEXT, 2, 0);
- }
-
- m_dwLastCopyCtorCookieLocalNum = dwCookieLocalNum;
- return dwCookieLocalNum;
-}
-
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
void NDirectStubLinker::Begin(DWORD dwStubFlags)
{
@@ -2292,23 +2072,6 @@ void NDirectStubLinker::Begin(DWORD dwStubFlags)
if (SF_IsForwardStub(dwStubFlags))
{
-#ifndef FEATURE_CORECLR // CAS
- // we may need to demand security permission
- if (SF_IsStubWithDemand(dwStubFlags))
- {
- if (SF_IsCOMStub(dwStubFlags) || SF_IsDelegateStub(dwStubFlags))
- {
- // pass NULL NDirectMethodDesc for COM and delegate P/Invoke
- m_pcsSetup->EmitLoadNullPtr();
- }
- else
- {
- // pass the real MD for direct P/Invoke
- EmitLoadStubContext(m_pcsSetup, dwStubFlags);
- }
- m_pcsSetup->EmitCALL(METHOD__STUBHELPERS__DEMAND_PERMISSION, 1, 0);
- }
-#endif // !FEATURE_CORECLR
if (SF_IsStubWithCctorTrigger(dwStubFlags))
{
@@ -2327,7 +2090,7 @@ void NDirectStubLinker::Begin(DWORD dwStubFlags)
if (SF_IsDelegateStub(dwStubFlags))
{
-#if defined(MDA_SUPPORTED) || (defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR))
+#if defined(MDA_SUPPORTED)
// GC was induced (gcUnmanagedToManagedMDA), arguments have been marshaled, and we are about
// to touch the UMEntryThunk and extract the delegate target from it so this is the right time
// to do the collected delegate MDA check.
@@ -2469,38 +2232,6 @@ void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth
STANDARD_VM_CONTRACT;
if (SF_IsForwardStub(dwStubFlags)) // managed-to-native
{
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- // set the copy ctor cookie chain if needed
- if (IsCopyCtorStubNeeded())
- {
- // StubHelpers.SetCopyCtorCookieChain(pStubArg, pUnmngThis, dwStubFlags, &<m_dwFirstCopyCtorCookieLocalNum>)
- if (SF_IsDelegateStub(dwStubFlags))
- {
- // for forward delegate P/Invoke load the target from 'this'
- pcsEmit->EmitLoadThis();
- pcsEmit->EmitLDFLD(pcsEmit->GetToken(MscorlibBinder::GetField(FIELD__DELEGATE__METHOD_PTR_AUX)));
- }
- else
- {
- // otherwise load the secret argument
- EmitLoadStubContext(pcsEmit, dwStubFlags);
- }
-
- if (SF_IsCOMStub(dwStubFlags))
- {
- // for forward COM load the unmanaged interface pointer
- pcsEmit->EmitLDLOC(m_dwTargetInterfacePointerLocalNum);
- }
- else
- {
- // otherwise load 0
- pcsEmit->EmitLoadNullPtr();
- }
- pcsEmit->EmitLDC(dwStubFlags);
- pcsEmit->EmitLDLOCA(m_dwFirstCopyCtorCookieLocalNum);
- pcsEmit->EmitCALL(METHOD__STUBHELPERS__SET_COPY_CTOR_COOKIE_CHAIN, 4, 0);
- }
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
if (SF_IsDelegateStub(dwStubFlags)) // delegate invocation
{
@@ -2529,44 +2260,15 @@ void NDirectStubLinker::DoNDirect(ILCodeStream *pcsEmit, DWORD dwStubFlags, Meth
#ifdef _TARGET_X86_
-#ifndef FEATURE_CORECLR
- if (IsCopyCtorStubNeeded())
- {
- // if we need to call copy ctor(s), we go to the copy ctor stub
- Stub *pCopyCtorStub = NDirect::GetStubForCopyCtor();
- pcsEmit->EmitLDC((DWORD_PTR)pCopyCtorStub->GetEntryPoint());
- }
- else
-#endif // !FEATURE_CORECLR
{
// for managed-to-unmanaged CALLI that requires marshaling, the target is passed
// as the secret argument to the stub by GenericPInvokeCalliHelper (asmhelpers.asm)
EmitLoadStubContext(pcsEmit, dwStubFlags);
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (NDirect::IsHostHookEnabled())
- {
- // we need to call to the host hook, real target is passed as the last argument
- Stub *pHostStub = NDirect::GenerateStubForHost(
- GetStubSigModule(),
- (CorUnmanagedCallingConvention)(GetStubTargetCallingConv() & IMAGE_CEE_CS_CALLCONV_MASK),
- pStubMD->AsDynamicMethodDesc()->GetNativeStackArgSize());
-
- pcsEmit->EmitLDC((DWORD_PTR)pHostStub->GetEntryPoint());
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#else // _TARGET_X86_
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (NDirect::IsHostHookEnabled())
- {
- // the stub for host will get the original target from the secret arg
- pcsEmit->EmitLDC((DWORD_PTR)GetEEFuncEntryPoint(PInvokeStubForHost));
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
// the secret arg has been shifted to left and ORed with 1 (see code:GenericPInvokeCalliHelper)
EmitLoadStubContext(pcsEmit, dwStubFlags);
@@ -3207,15 +2909,6 @@ void PInvokeStaticSigInfo::DllImportInit(MethodDesc* pMD, LPCUTF8 *ppLibName, LP
mdModuleRef modref = mdModuleRefNil;
if (FAILED(pInternalImport->GetPinvokeMap(pMD->GetMemberDef(), (DWORD*)&mappingFlags, ppEntryPointName, &modref)))
{
-#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE) // IJW
- // The guessing heuristic has been broken with NGen for a long time since we stopped loading
- // images at NGen time using full LoadLibrary. The DLL references are not resolved correctly
- // without full LoadLibrary.
- //
- // Disable the heuristic consistently during NGen so that it does not kick in by accident.
- if (!IsCompilationProcess())
- BestGuessNDirectDefaults(pMD);
-#endif
InitCallConv((CorPinvokeMap)0, pMD->IsVarArg());
return;
}
@@ -3278,238 +2971,15 @@ void PInvokeStaticSigInfo::DllImportInit(MethodDesc* pMD, LPCUTF8 *ppLibName, LP
}
}
-
-#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE) // IJW
-
-// This attempts to guess whether a target is an API call that uses SetLastError to communicate errors.
-static BOOL HeuristicDoesThisLooksLikeAnApiCallHelper(LPBYTE pTarget)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // This code is not that useful anymore since this functionality is already embedded in the VC linker.
- // The linker will emit the lasterror flag by default for functions residing in modules that are
- // a superset of the list below.
- // Look for bug VSWhidbey 241895.
-
- static struct SysDllInfo
- {
- LPCWSTR pName;
- LPBYTE pImageBase;
- DWORD dwImageSize;
- } gSysDllInfo[] = {{WINDOWS_KERNEL32_DLLNAME_W, 0, 0},
- {W("GDI32"), 0, 0},
- {W("USER32"), 0, 0},
- {W("ADVAPI32"), 0, 0}
- };
-
-
- for (int i = 0; i < sizeof(gSysDllInfo)/sizeof(*gSysDllInfo); i++)
- {
- if (gSysDllInfo[i].pImageBase == 0)
- {
- IMAGE_DOS_HEADER *pDos = (IMAGE_DOS_HEADER*)CLRGetModuleHandle(gSysDllInfo[i].pName);
- if (pDos)
- {
- if (pDos->e_magic == VAL16(IMAGE_DOS_SIGNATURE))
- {
- IMAGE_NT_HEADERS *pNT = (IMAGE_NT_HEADERS*) (((LPBYTE)pDos) + VAL32(pDos->e_lfanew));
- if (pNT->Signature == VAL32(IMAGE_NT_SIGNATURE) &&
- pNT->FileHeader.SizeOfOptionalHeader ==
-#ifdef _WIN64
- VAL16(sizeof(IMAGE_OPTIONAL_HEADER64))
-#else
- VAL16(sizeof(IMAGE_OPTIONAL_HEADER32))
-#endif
- && pNT->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR_MAGIC))
- {
- gSysDllInfo[i].dwImageSize = VAL32(pNT->OptionalHeader.SizeOfImage);
- }
- }
-
- gSysDllInfo[i].pImageBase = (LPBYTE)pDos;
- }
- }
- if (gSysDllInfo[i].pImageBase != 0 &&
- pTarget >= gSysDllInfo[i].pImageBase &&
- pTarget < gSysDllInfo[i].pImageBase + gSysDllInfo[i].dwImageSize)
- {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-LPBYTE FollowIndirect(LPBYTE pTarget)
-{
- CONTRACT (LPBYTE)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END;
-
- LPBYTE pRet = NULL;
-
- EX_TRY
- {
- AVInRuntimeImplOkayHolder AVOkay;
-
-#ifdef _TARGET_X86_
- if (pTarget != NULL && !(pTarget[0] != 0xff || pTarget[1] != 0x25))
- {
- pRet = **(LPBYTE**)(pTarget + 2);
- }
-#elif defined(_TARGET_AMD64_)
- if (pTarget != NULL && !(pTarget[0] != 0xff || pTarget[1] != 0x25))
- {
- INT64 rva = *(INT32*)(pTarget + 2);
- pRet = *(LPBYTE*)(pTarget + 6 + rva);
- }
-#endif
- }
- EX_CATCH
- {
- // Catch AVs here.
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- RETURN pRet;
-}
-
-// This attempts to guess whether a target is an API call that uses SetLastError to communicate errors.
-BOOL HeuristicDoesThisLooksLikeAnApiCall(LPBYTE pTarget)
+inline CorPinvokeMap GetDefaultCallConv(BOOL bIsVarArg)
{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (pTarget == NULL)
- return FALSE;
-
- if (HeuristicDoesThisLooksLikeAnApiCallHelper(pTarget))
- return TRUE;
-
- LPBYTE pTarget2 = FollowIndirect(pTarget);
- if (pTarget2)
- {
- // jmp [xxxx] - could be an import thunk
- return HeuristicDoesThisLooksLikeAnApiCallHelper( pTarget2 );
- }
-
- return FALSE;
-}
-
-BOOL HeuristicDoesThisLookLikeAGetLastErrorCall(LPBYTE pTarget)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- static LPBYTE pGetLastError = NULL;
- if (!pGetLastError)
- {
- // No need to use a holder here, since no cleanup is necessary.
- HMODULE hMod = CLRGetModuleHandle(WINDOWS_KERNEL32_DLLNAME_W);
- if (hMod)
- {
- pGetLastError = (LPBYTE)GetProcAddress(hMod, "GetLastError");
- if (!pGetLastError)
- {
- // This should never happen but better to be cautious.
- pGetLastError = (LPBYTE)-1;
- }
- }
- else
- {
- // We failed to get the module handle for kernel32.dll. This is almost impossible
- // however better to err on the side of caution.
- pGetLastError = (LPBYTE)-1;
- }
- }
-
- if (pTarget == pGetLastError)
- return TRUE;
-
- if (pTarget == NULL)
- return FALSE;
-
- LPBYTE pTarget2 = FollowIndirect(pTarget);
- if (pTarget2)
- {
- // jmp [xxxx] - could be an import thunk
- return pTarget2 == pGetLastError;
- }
-
- return FALSE;
-}
-
-DWORD __stdcall FalseGetLastError()
-{
- WRAPPER_NO_CONTRACT;
-
- return GetThread()->m_dwLastError;
-}
-
-void PInvokeStaticSigInfo::BestGuessNDirectDefaults(MethodDesc* pMD)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (!pMD->IsNDirect())
- return;
-
- NDirectMethodDesc* pMDD = (NDirectMethodDesc*)pMD;
-
- if (!pMDD->IsEarlyBound())
- return;
-
- LPVOID pTarget = NULL;
-
- // NOTE: If we get inside this block, and this is a call to GetLastError,
- // then InitEarlyBoundNDirectTarget has not been run yet.
- if (pMDD->NDirectTargetIsImportThunk())
- {
- // Get the unmanaged callsite.
- pTarget = (LPVOID)pMDD->GetModule()->GetInternalPInvokeTarget(pMDD->GetRVA());
-
- // If this is a call to GetLastError, then we haven't overwritten m_pNativeNDirectTarget yet.
- if (HeuristicDoesThisLookLikeAGetLastErrorCall((LPBYTE)pTarget))
- pTarget = (BYTE*) FalseGetLastError;
- }
- else
- {
- pTarget = pMDD->GetNativeNDirectTarget();
- }
-
- if (HeuristicDoesThisLooksLikeAnApiCall((LPBYTE) pTarget))
- SetLinkFlags ((CorNativeLinkFlags)(GetLinkFlags() | nlfLastError));
+#ifdef PLATFORM_UNIX
+ return pmCallConvCdecl;
+#else // PLATFORM_UNIX
+ return bIsVarArg ? pmCallConvCdecl : pmCallConvStdcall;
+#endif // !PLATFORM_UNIX
}
-#endif // FEATURE_MIXEDMODE && !CROSSGEN_COMPILE
-
-
void PInvokeStaticSigInfo::InitCallConv(CorPinvokeMap callConv, BOOL bIsVarArg)
{
CONTRACTL
@@ -3522,7 +2992,7 @@ void PInvokeStaticSigInfo::InitCallConv(CorPinvokeMap callConv, BOOL bIsVarArg)
// Convert WinAPI methods to either StdCall or CDecl based on if they are varargs or not.
if (callConv == pmCallConvWinapi)
- callConv = bIsVarArg ? pmCallConvCdecl : pmCallConvStdcall;
+ callConv = GetDefaultCallConv(bIsVarArg);
CorPinvokeMap sigCallConv = (CorPinvokeMap)0;
BOOL fSuccess = MetaSig::GetUnmanagedCallingConvention(m_pModule, m_sig.GetRawSig(), m_sig.GetRawSigLen(), &sigCallConv);
@@ -3536,13 +3006,13 @@ void PInvokeStaticSigInfo::InitCallConv(CorPinvokeMap callConv, BOOL bIsVarArg)
// to do this before we check to make sure the PInvoke map calling convention and the
// signature calling convention match for compatibility reasons.
if (sigCallConv == pmCallConvWinapi)
- sigCallConv = bIsVarArg ? pmCallConvCdecl : pmCallConvStdcall;
+ sigCallConv = GetDefaultCallConv(bIsVarArg);
if (callConv != 0 && sigCallConv != 0 && callConv != sigCallConv)
SetError(IDS_EE_NDIRECT_BADNATL_CALLCONV);
if (callConv == 0 && sigCallConv == 0)
- m_callConv = bIsVarArg ? pmCallConvCdecl : pmCallConvStdcall;
+ m_callConv = GetDefaultCallConv(bIsVarArg);
else if (callConv != 0)
m_callConv = callConv;
else
@@ -4214,19 +3684,16 @@ static void CreateNDirectStubWorker(StubState* pss,
// return buffer in correct register.
// The return structure secret arg comes first, however byvalue return is processed at
// the end because it could be the HRESULT-swapped argument which always comes last.
- fMarshalReturnValueFirst = HasRetBuffArg(&msig);
-#endif
-#if defined(_TARGET_AMD64_) && defined(_WIN64) && !defined(FEATURE_CORECLR)
- // JIT64 (which is only used on the Windows Desktop CLR) has a problem generating code
- // for the pinvoke ILStubs which do a return using a struct type. Therefore, we
- // change the signature of calli to return void and make the return buffer as first argument.
- // This matches the ABI i.e. return buffer is passed as first arg. So native target will get
- // the return buffer in correct register.
- // Ideally we only want to set it for JIT64 and not ryujit but currently there isn't a fast way
- // to determine that at runtime.
+#ifdef UNIX_X86_ABI
+ // For functions with value type class, managed and unmanaged calling convention differ
+ fMarshalReturnValueFirst = HasRetBuffArgUnmanagedFixup(&msig);
+#else // UNIX_X86_ABI
fMarshalReturnValueFirst = HasRetBuffArg(&msig);
-#endif
+#endif // UNIX_X86_ABI
+
+#endif // defined(_TARGET_X86_) || defined(_TARGET_ARM_)
+
}
if (fMarshalReturnValueFirst)
@@ -4388,12 +3855,6 @@ static void CreateNDirectStubWorker(StubState* pss,
COMPlusThrow(kMarshalDirectiveException, IDS_EE_NDIRECT_BADNATL_THISCALL);
}
-#ifndef FEATURE_CORECLR
- if (info.GetMarshalType() == MarshalInfo::MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR)
- {
- fHasCopyCtorArgs = true;
- }
-#endif // !FEATURE_CORECLR
argidx++;
}
@@ -5899,13 +5360,6 @@ PCODE NDirect::GetStubForILStub(NDirectMethodDesc* pNMD, MethodDesc** ppStubMD,
pStub = TheVarargNDirectStub(pNMD->HasRetBuffArg());
}
-#ifdef FEATURE_MIXEDMODE // IJW
- if (pNMD->IsEarlyBound())
- {
- pNMD->InitEarlyBoundNDirectTarget();
- }
- else
-#endif
{
NDirectLink(pNMD);
}
@@ -6206,15 +5660,6 @@ VOID NDirectMethodDesc::SetNDirectTarget(LPVOID pTarget)
#ifdef _TARGET_X86_
-#ifndef FEATURE_CORECLR
- if (HasCopyCtorArgs())
- {
- _ASSERTE(pInterceptStub == NULL);
-
- // static stub that gets its arguments in a thread-static field
- pInterceptStub = NDirect::GetStubForCopyCtor();
- }
-#endif // !FEATURE_CORECLR
#ifdef MDA_SUPPORTED
if (!IsQCall() && MDA_GET_ASSISTANT(PInvokeStackImbalance))
@@ -6223,12 +5668,6 @@ VOID NDirectMethodDesc::SetNDirectTarget(LPVOID pTarget)
}
#endif // MDA_SUPPORTED
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (fHook)
- {
- pInterceptStub = GenerateStubForHost(pTarget, pInterceptStub);
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#endif // _TARGET_X86_
@@ -6252,9 +5691,6 @@ VOID NDirectMethodDesc::SetNDirectTarget(LPVOID pTarget)
}
#else
_ASSERTE(pInterceptStub == NULL); // we don't intercept for anything else than host on !_TARGET_X86_
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- pWriteableData->m_pNDirectTarget = (LPVOID)GetEEFuncEntryPoint(PInvokeStubForHost);
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#endif
}
else
@@ -6263,74 +5699,7 @@ VOID NDirectMethodDesc::SetNDirectTarget(LPVOID pTarget)
}
}
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
-
-// Returns a small stub whose purpose is to record current ESP and call code:CopyCtorCallStubWorker
-// to invoke copy constructors and destructors as appropriate. This stub operates on arguments
-// already pushed to the stack by JITted IL stub and must not create a new frame, i.e. it must
-// tail call to the target for it to see the arguments that copy ctors have been called on.
-//
-// As a consequence, the stub doesn't take any extra secret arguments and the description of the
-// ctors/dtors to call is passed "out-of-band" in a thread static field. The worker returns
-// address of the real target (also passed out of band) which enables us to have only one static
-// stub in i386\asmhelpers.asm.
-
-// static
-Stub *NDirect::GetStubForCopyCtor()
-{
- STANDARD_VM_CONTRACT;
-
- static Stub *s_pStub = NULL;
-
- if (s_pStub == NULL)
- {
- Stub *pStub = Stub::NewStub(GetEEFuncEntryPoint(CopyCtorCallStub));
- if (InterlockedCompareExchangeT(&s_pStub, pStub, NULL) != NULL)
- {
- pStub->DecRef();
- }
- }
-
- s_pStub->IncRef();
- return s_pStub;
-}
-
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-BOOL NDirect::IsHostHookEnabled()
-{
- WRAPPER_NO_CONTRACT;
- //
- // WARNING: The non-debug portion of this logic is inlined into UMThunkStubAMD64!
- //
- return CLRTaskHosted() INDEBUG(|| g_pConfig->ShouldGenerateStubForHost());
-}
-
-EXTERN_C BOOL CallNeedsHostHook(size_t target)
-{
- BOOL fHook = FALSE;
- IHostTaskManager *pManager = CorHost2::GetHostTaskManager();
- if (pManager)
- {
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->CallNeedsHostHook(target,&fHook);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- _ASSERTE (hr == S_OK);
- }
-#ifdef _DEBUG
- else
- {
- if (g_pConfig->ShouldGenerateStubForHost())
- {
- fHook = TRUE;
- }
- }
-#endif
- return fHook;
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#if defined(_TARGET_X86_) && defined(MDA_SUPPORTED)
EXTERN_C VOID __stdcall PInvokeStackImbalanceWorker(StackImbalanceCookie *pSICookie, DWORD dwPostESP)
@@ -6354,147 +5723,6 @@ EXTERN_C VOID __stdcall PInvokeStackImbalanceWorker(StackImbalanceCookie *pSICoo
}
#endif // _TARGET_X86_ && MDA_SUPPORTED
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
-struct CopyCtorStubCookie // same layout as StubHelpers.CopyCtorStubCookie
-{
- LPVOID m_srcInstancePtr;
- DWORD m_dstStackOffset;
- LPVOID m_ctorPtr; // managed method ptr
- LPVOID m_dtorPtr; // managed method ptr
-
- CopyCtorStubCookie *m_pNext;
-};
-
-struct CopyCtorStubDesc // same layout as StubHelpers.CopyCtorStubDesc
-{
- CopyCtorStubCookie *m_pCookie;
- LPVOID m_pTarget;
-};
-
-// Called by CopyCtorCallStub after we have already transitioned to unmanaged. Invokes copy ctor(s)
-// and dtor(s) using reverse P/Invoke which has some perf impact but provides all the debugging and
-// profiling support. An alternative solution would be CallDescr or some optimized variant of it
-// which would probably result in confusing call stacks.
-EXTERN_C LPVOID __stdcall CopyCtorCallStubWorker(BYTE *pESP)
-{
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_MODE_PREEMPTIVE; // we've already switched to preemptive
-
- CopyCtorStubCookie *pCookie;
- LPVOID pTarget;
- {
- GCX_COOP();
- // get address of the thread-static field
- FieldDesc *pFD = MscorlibBinder::GetField(FIELD__STUBHELPERS__COPY_CTOR_STUB_DESC);
-
- CopyCtorStubDesc *pStubDesc = (CopyCtorStubDesc *)Thread::GetStaticFieldAddress(pFD);
-
- // read the fields in cooperative mode
- pCookie = pStubDesc->m_pCookie;
- pTarget = pStubDesc->m_pTarget;
-
- _ASSERTE(pCookie != NULL && pTarget != NULL);
-
- // make sure we ASSERT/AV reliably if we are called by mistake
- pStubDesc->m_pCookie = NULL;
- pStubDesc->m_pTarget = NULL;
- }
-
- while (pCookie != NULL)
- {
- if (pCookie->m_ctorPtr != NULL)
- {
- // get reverse P/Invoke to the copy ctor (cache on AD)
- MethodDesc *pMD = Entry2MethodDesc((PCODE)pCookie->m_ctorPtr, NULL);
- UMEntryThunk *pUMEntryThunk = GetAppDomain()->GetUMEntryThunkCache()->GetUMEntryThunk(pMD);
-
- // GetUMEntryThunk always returns stdcall-able function pointers for ordinary managed methods
- // but the ctor can be a P/Invoke (pre-Whidbey MC++ only)
- typedef void (__stdcall *CtorFnPtr_StdCall) (LPVOID dst, LPVOID src);
- typedef void (__thiscall *CtorFnPtr_ThisCall)(LPVOID dst, LPVOID src);
- typedef void (__cdecl *CtorFnPtr_Cdecl) (LPVOID dst, LPVOID src);
-
- // call the copy ctor using the right calling convention
- UMThunkMarshInfo *pMarshInfo = pUMEntryThunk->GetUMThunkMarshInfo();
- pMarshInfo->RunTimeInit();
-
- switch (pMarshInfo->GetCallingConvention() & pmCallConvMask)
- {
- case pmCallConvStdcall:
- case pmCallConvWinapi:
- {
- CtorFnPtr_StdCall fnPtr = (CtorFnPtr_StdCall)pUMEntryThunk->GetCode();
- fnPtr(pESP + pCookie->m_dstStackOffset, pCookie->m_srcInstancePtr);
- break;
- }
-
- case pmCallConvThiscall:
- {
- CtorFnPtr_ThisCall fnPtr = (CtorFnPtr_ThisCall)pUMEntryThunk->GetCode();
- fnPtr(pESP + pCookie->m_dstStackOffset, pCookie->m_srcInstancePtr);
- break;
- }
-
- default:
- {
- _ASSERTE((pMarshInfo->GetCallingConvention() & pmCallConvMask) == pmCallConvCdecl);
-
- CtorFnPtr_Cdecl fnPtr = (CtorFnPtr_Cdecl)pUMEntryThunk->GetCode();
- fnPtr(pESP + pCookie->m_dstStackOffset, pCookie->m_srcInstancePtr);
- break;
- }
- }
- }
- if (pCookie->m_dtorPtr != NULL)
- {
- // get reverse P/Invoke to the dtor (cache on AD)
- MethodDesc *pMD = Entry2MethodDesc((PCODE)pCookie->m_dtorPtr, NULL);
- UMEntryThunk *pUMEntryThunk = GetAppDomain()->GetUMEntryThunkCache()->GetUMEntryThunk(pMD);
-
- // GetUMEntryThunk always returns stdcall-able function pointers for ordinary managed methods
- // but the dtor can be a P/Invoke (pre-Whidbey MC++ only)
- typedef void (__stdcall *DtorFnPtr_StdCall) (LPVOID src);
- typedef void (__thiscall *DtorFnPtr_ThisCall)(LPVOID src);
- typedef void (__cdecl *DtorFnPtr_Cdecl) (LPVOID src);
-
- // call the dtor using the right calling convention
- UMThunkMarshInfo *pMarshInfo = pUMEntryThunk->GetUMThunkMarshInfo();
- pMarshInfo->RunTimeInit();
-
- switch (pMarshInfo->GetCallingConvention() & pmCallConvMask)
- {
- case pmCallConvStdcall:
- case pmCallConvWinapi:
- {
- DtorFnPtr_StdCall fnPtr = (DtorFnPtr_StdCall)pUMEntryThunk->GetCode();
- fnPtr(pCookie->m_srcInstancePtr);
- break;
- }
-
- case pmCallConvThiscall:
- {
- DtorFnPtr_ThisCall fnPtr = (DtorFnPtr_ThisCall)pUMEntryThunk->GetCode();
- fnPtr(pCookie->m_srcInstancePtr);
- break;
- }
-
- default:
- {
- _ASSERTE((pMarshInfo->GetCallingConvention() & pmCallConvMask) == pmCallConvCdecl);
-
- DtorFnPtr_Cdecl fnPtr = (DtorFnPtr_Cdecl)pUMEntryThunk->GetCode();
- fnPtr(pCookie->m_srcInstancePtr);
- break;
- }
- }
- }
- pCookie = pCookie->m_pNext;
- }
-
- return pTarget;
-}
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
// Preserving good error info from DllImport-driven LoadLibrary is tricky because we keep loading from different places
// if earlier loads fail and those later loads obliterate error codes.
@@ -6660,141 +5888,13 @@ static HMODULE LocalLoadLibraryDirectHelper(LPCWSTR name, DWORD flags, LoadLibEr
#endif // !FEATURE_PAL
}
-
-#if !defined(FEATURE_CORESYSTEM)
-
-#define NATIVE_DLL(d) L#d, L#d W(".dll")
-
-const LPCWSTR wellKnownModules[] =
-{
- NATIVE_DLL(advapi32),
- NATIVE_DLL(gdi32),
- NATIVE_DLL(gdiplus),
- NATIVE_DLL(kernel32),
- NATIVE_DLL(mscoree),
- NATIVE_DLL(ole32),
- NATIVE_DLL(shfolder),
- NATIVE_DLL(user32),
- NATIVE_DLL(version)
-};
-
-BOOL CompareLibNames (UPTR val1, UPTR val2)
-{
- CONTRACTL {
- MODE_ANY;
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- LPCWSTR wszStr1 = (LPCWSTR)(val1 << 1);
- LPCWSTR wszStr2 = (LPCWSTR)val2;
-
- if (SString::_wcsicmp(wszStr1, wszStr2) == 0)
- return TRUE;
-
- return FALSE;
-}
-
-PtrHashMap * NDirect::s_pWellKnownNativeModules = NULL;
+#if !defined(FEATURE_PAL)
bool NDirect::s_fSecureLoadLibrarySupported = false;
-
-HINSTANCE NDirect::CheckForWellKnownModules(LPCWSTR wszLibName, LoadLibErrorTracker *pErrorTracker)
-{
- STANDARD_VM_CONTRACT;
-
- ModuleHandleHolder hMod;
- ULONG hash = HashiString(wszLibName);
- LPCWSTR wszName = NULL;
- wszName = (LPCWSTR) s_pWellKnownNativeModules->LookupValue((UPTR) hash, (LPVOID)wszLibName);
-
- if (wszName != (LPCWSTR)INVALIDENTRY)
- {
- hMod = LocalLoadLibraryHelper(wszLibName, 0, pErrorTracker);
- }
-
- return hMod.Extract();
-}
-
-#endif // !FEATURE_CORESYSTEM
+#endif
#define TOLOWER(a) (((a) >= W('A') && (a) <= W('Z')) ? (W('a') + (a - W('A'))) : (a))
#define TOHEX(a) ((a)>=10 ? W('a')+(a)-10 : W('0')+(a))
-#ifndef FEATURE_CORECLR
-/*static*/
-VOID NDirect::CheckUnificationList(NDirectMethodDesc * pMD, DWORD * pDllImportSearchPathFlag, BOOL * pSearchAssemblyDirectory)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // If neither assembly and method have the attribute, check the unification list.
- Assembly *pAssembly = pMD->GetAssembly();
-
- if (!pAssembly->IsStrongNamed())
- return;
-
- const char * simpleName = pAssembly->GetSimpleName();
-
- StringHashIterator(it, g_arFxPolicy, simpleName);
-
- int pos;
-
- while ((pos = it.GetNext()) >= 0)
- {
- const FrameworkConfig & config = g_arFxPolicy[pos];
-
- FixedSizeString<char> asmName;
-
- config.GetFxAssemblyName(asmName);
-
- if (_stricmp(asmName, simpleName) == 0)
- {
- DWORD cbPublicKey = 0;
- const void *pbPublicKey = NULL;
- pbPublicKey = pAssembly->GetPublicKey(&cbPublicKey);
-
- //
- // StrongNameTokenFromPublicKey is potentially expensive operation. Do it only once we got a match on the simple name.
- //
- StrongNameBufferHolder<BYTE> pbStrongNameToken;
- DWORD cbStrongNameToken;
-
- if (StrongNameTokenFromPublicKey((BYTE*) pbPublicKey,cbPublicKey,&pbStrongNameToken,&cbStrongNameToken))
- {
- BOOL pktIsEqual = TRUE;
-
- LPCWSTR pwzPKT = config.GetPKT();
-
- for (UINT j = 0; j < cbStrongNameToken; j++)
- {
- WCHAR firstChar = TOHEX(pbStrongNameToken[j] / 16);
- WCHAR secondChar = TOHEX(pbStrongNameToken[j] % 16);
-
- if (firstChar != TOLOWER(pwzPKT[j*2]) || secondChar != TOLOWER(pwzPKT[j*2+1]))
- {
- pktIsEqual = FALSE;
- break;
- }
- }
-
- if (pktIsEqual)
- {
- *pDllImportSearchPathFlag = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS;
- *pSearchAssemblyDirectory = TRUE;
- break;
- }
- }
- }
- }
-}
-#endif // !FEATURE_CORECLR
-
// static
HMODULE NDirect::LoadLibraryFromPath(LPCWSTR libraryPath)
{
@@ -6811,7 +5911,6 @@ HMODULE NDirect::LoadLibraryFromPath(LPCWSTR libraryPath)
return systemModuleHandle;
}
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
/* static */
HMODULE NDirect::LoadLibraryModuleViaHost(NDirectMethodDesc * pMD, AppDomain* pDomain, const wchar_t* wszLibName)
{
@@ -6913,7 +6012,6 @@ HMODULE NDirect::LoadLibraryModuleViaHost(NDirectMethodDesc * pMD, AppDomain* pD
return (HMODULE)hmod;
}
-#endif //defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
// Try to load the module alongside the assembly where the PInvoke was declared.
HMODULE NDirect::LoadFromPInvokeAssemblyDirectory(Assembly *pAssembly, LPCWSTR libName, DWORD flags, LoadLibErrorTracker *pErrorTracker)
@@ -6937,7 +6035,6 @@ HMODULE NDirect::LoadFromPInvokeAssemblyDirectory(Assembly *pAssembly, LPCWSTR l
return hmod;
}
-#ifdef FEATURE_CORECLR
// Try to load the module from the native DLL search directories
HMODULE NDirect::LoadFromNativeDllSearchDirectories(AppDomain* pDomain, LPCWSTR libName, DWORD flags, LoadLibErrorTracker *pErrorTracker)
{
@@ -6961,7 +6058,6 @@ HMODULE NDirect::LoadFromNativeDllSearchDirectories(AppDomain* pDomain, LPCWSTR
return hmod;
}
-#endif // FEATURE_CORECLR
HINSTANCE NDirect::LoadLibraryModule(NDirectMethodDesc * pMD, LoadLibErrorTracker * pErrorTracker)
{
@@ -6985,7 +6081,6 @@ HINSTANCE NDirect::LoadLibraryModule(NDirectMethodDesc * pMD, LoadLibErrorTracke
AppDomain* pDomain = GetAppDomain();
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
// AssemblyLoadContext is not supported in AppX mode and thus,
// we should not perform PInvoke resolution via it when operating in
// AppX mode.
@@ -6993,7 +6088,6 @@ HINSTANCE NDirect::LoadLibraryModule(NDirectMethodDesc * pMD, LoadLibErrorTracke
{
hmod = LoadLibraryModuleViaHost(pMD, pDomain, wszLibName);
}
-#endif //FEATURE_HOST_ASSEMBLY_RESOLVER
if(hmod == NULL)
@@ -7006,10 +6100,6 @@ HINSTANCE NDirect::LoadLibraryModule(NDirectMethodDesc * pMD, LoadLibErrorTracke
return hmod.Extract();
}
-#if !defined(FEATURE_CORESYSTEM)
- hmod = CheckForWellKnownModules(wszLibName, pErrorTracker);
-#endif
-
#ifdef FEATURE_PAL
// In the PAL version of CoreCLR, the CLR module itself exports the functionality
// that the Windows version obtains from kernel32 and friends. In order to avoid
@@ -7032,13 +6122,11 @@ HINSTANCE NDirect::LoadLibraryModule(NDirectMethodDesc * pMD, LoadLibErrorTracke
}
#endif // FEATURE_CORESYSTEM && !FEATURE_PAL
-#ifdef FEATURE_CORECLR
if (hmod == NULL)
{
// NATIVE_DLL_SEARCH_DIRECTORIES set by host is considered well known path
hmod = LoadFromNativeDllSearchDirectories(pDomain, wszLibName, loadWithAlteredPathFlags, pErrorTracker);
}
-#endif // FEATURE_CORECLR
DWORD dllImportSearchPathFlag = 0;
BOOL searchAssemblyDirectory = TRUE;
@@ -7069,12 +6157,6 @@ HINSTANCE NDirect::LoadLibraryModule(NDirectMethodDesc * pMD, LoadLibErrorTracke
}
}
-#ifndef FEATURE_CORECLR
- if (!attributeIsFound)
- {
- CheckUnificationList(pMD, &dllImportSearchPathFlag, &searchAssemblyDirectory);
- }
-#endif
if (!libNameIsRelativePath)
{
@@ -7093,68 +6175,6 @@ HINSTANCE NDirect::LoadLibraryModule(NDirectMethodDesc * pMD, LoadLibErrorTracke
Assembly* pAssembly = pMD->GetMethodTable()->GetAssembly();
hmod = LoadFromPInvokeAssemblyDirectory(pAssembly, wszLibName, loadWithAlteredPathFlags | dllImportSearchPathFlag, pErrorTracker);
-#ifndef FEATURE_CORECLR
- if (hmod == NULL)
- {
- // Try to load the DLL alongside the assembly where the PInvoke was
- // declared using the codebase of the assembly. This is required for download
- // and shadow copy scenarios.
- const WCHAR* ptr;
- SString codebase;
- pAssembly->GetCodeBase(codebase);
- DWORD dwCodebaseLength = codebase.GetCount();
-
- // Strip off the protocol
- for (ptr = codebase.GetUnicode(); *ptr && *ptr != W(':'); ptr++);
-
- // If we have a code base then prepend it to the library name
- if (*ptr)
- {
- SString pathFromCodebase;
-
- // After finding the colon move forward until no more forward slashes
- for (ptr++; *ptr && *ptr == W('/'); ptr++);
- if (*ptr)
- {
- // Calculate the number of characters we are interested in
- if (dwCodebaseLength > (DWORD)(ptr - codebase.GetUnicode()) )
- {
- // Back up to the last slash (forward or backwards)
- const WCHAR* tail;
-
- for (tail = codebase.GetUnicode() + (dwCodebaseLength - 1); tail > ptr && *tail != W('/') && *tail != W('\\'); tail--);
-
- if (tail > ptr)
- {
- for (;ptr <= tail; ptr++)
- {
- if (*ptr == W('/'))
- pathFromCodebase.Append(W('\\'));
- else
- pathFromCodebase.Append(*ptr);
- }
- }
- }
- }
-
- pathFromCodebase.Append(wszLibName);
-
- SString path = pAssembly->GetManifestFile()->GetPath();
- SString::Iterator i = path.End();
- if (PEAssembly::FindLastPathSeparator(path, i))
- {
- i++;
- path.Truncate(i);
- path.Append(wszLibName);
- }
-
- if (!pathFromCodebase.EqualsCaseInsensitive(path, PEImage::GetFileSystemLocale()))
- {
- hmod = LocalLoadLibraryHelper(pathFromCodebase, loadWithAlteredPathFlags | dllImportSearchPathFlag, pErrorTracker);
- }
- }
- }
-#endif // !FEATURE_CORECLR
}
}
@@ -7353,15 +6373,7 @@ VOID NDirect::NDirectLink(NDirectMethodDesc *pMD)
}
CONTRACTL_END;
-#if !defined(FEATURE_CORECLR)
- // Generate a table of some well known native dlls
- s_pWellKnownNativeModules = ::new PtrHashMap();
- s_pWellKnownNativeModules->Init(sizeof(wellKnownModules)/sizeof(LPCWSTR), CompareLibNames, TRUE, NULL);
- for (int index = 0; index < sizeof(wellKnownModules)/sizeof(LPCWSTR); index++)
- {
- s_pWellKnownNativeModules->InsertValue((UPTR) HashiString(wellKnownModules[index]), (LPVOID)wellKnownModules[index]);
- }
-
+#if !defined(FEATURE_PAL)
// Check if the OS supports the new secure LoadLibraryEx flags introduced in KB2533623
HMODULE hMod = CLRGetModuleHandle(WINDOWS_KERNEL32_DLLNAME_W);
_ASSERTE(hMod != NULL);
@@ -7371,7 +6383,7 @@ VOID NDirect::NDirectLink(NDirectMethodDesc *pMD)
// The AddDllDirectory export was added in KB2533623 together with the new flag support
s_fSecureLoadLibrarySupported = true;
}
-#endif // !FEATURE_CORECLR
+#endif // !FEATURE_PAL
}
@@ -7406,21 +6418,6 @@ EXTERN_C LPVOID STDCALL NDirectImportWorker(NDirectMethodDesc* pMD)
// any of our internal exceptions into managed exceptions.
INSTALL_UNWIND_AND_CONTINUE_HANDLER;
-#ifdef FEATURE_MIXEDMODE // IJW
- if (pMD->IsEarlyBound())
- {
- if (!pMD->IsZapped())
- {
- // we need the MD to be populated in case we decide to build an intercept
- // stub to wrap the target in InitEarlyBoundNDirectTarget
- PInvokeStaticSigInfo sigInfo;
- NDirect::PopulateNDirectMethodDesc(pMD, &sigInfo);
- }
-
- pMD->InitEarlyBoundNDirectTarget();
- }
- else
-#endif // FEATURE_MIXEDMODE
{
//
// Otherwise we're in an inlined pinvoke late bound MD
diff --git a/src/vm/dllimport.h b/src/vm/dllimport.h
index b393bf6cdd..1dfb4423cc 100644
--- a/src/vm/dllimport.h
+++ b/src/vm/dllimport.h
@@ -80,9 +80,6 @@ public:
static HMODULE LoadLibraryFromPath(LPCWSTR libraryPath);
static HINSTANCE LoadLibraryModule(NDirectMethodDesc * pMD, LoadLibErrorTracker *pErrorTracker);
-#ifndef FEATURE_CORECLR
- static VOID CheckUnificationList(NDirectMethodDesc * pMD, DWORD * pDllImportSearchPathFlag, BOOL * pSearchAssemblyDirectory);
-#endif // !FEATURE_CORECLR
static VOID NDirectLink(NDirectMethodDesc *pMD);
@@ -121,9 +118,6 @@ public:
inline static ILStubCache* GetILStubCache(NDirectStubParameters* pParams);
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- static Stub* GetStubForCopyCtor();
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
static BOOL IsHostHookEnabled();
@@ -132,19 +126,12 @@ public:
private:
NDirect() {LIMITED_METHOD_CONTRACT;}; // prevent "new"'s on this class
-#ifdef FEATURE_CORECLR
static HMODULE LoadFromNativeDllSearchDirectories(AppDomain* pDomain, LPCWSTR libName, DWORD flags, LoadLibErrorTracker *pErrorTracker);
-#endif
static HMODULE LoadFromPInvokeAssemblyDirectory(Assembly *pAssembly, LPCWSTR libName, DWORD flags, LoadLibErrorTracker *pErrorTracker);
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
static HMODULE LoadLibraryModuleViaHost(NDirectMethodDesc * pMD, AppDomain* pDomain, const wchar_t* wszLibName);
-#endif //defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
-
-#if !defined(FEATURE_CORESYSTEM)
- static HINSTANCE CheckForWellKnownModules(LPCWSTR wszLibName, LoadLibErrorTracker *pErrorTracker);
- static PtrHashMap *s_pWellKnownNativeModules;
+#if !defined(FEATURE_PAL)
// Indicates if the OS supports the new secure LoadLibraryEx flags introduced in KB2533623
static bool s_fSecureLoadLibrarySupported;
@@ -154,7 +141,7 @@ public:
LIMITED_METHOD_CONTRACT;
return s_fSecureLoadLibrarySupported;
}
-#endif // !FEATURE_CORESYSTEM
+#endif // !FEATURE_PAL
};
//----------------------------------------------------------------
@@ -357,9 +344,6 @@ private:
void PreInit(Module* pModule, MethodTable *pClass);
void PreInit(MethodDesc* pMD);
void SetError(WORD error) { if (!m_error) m_error = error; }
-#ifdef FEATURE_MIXEDMODE
- void BestGuessNDirectDefaults(MethodDesc* pMD);
-#endif
public:
DWORD GetStubFlags()
@@ -507,9 +491,6 @@ public:
void GetCleanupFinallyOffsets(ILStubEHClause * pClause);
void AdjustTargetStackDeltaForReverseInteropHRESULTSwapping();
void AdjustTargetStackDeltaForExtraParam();
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- DWORD CreateCopyCtorCookie(ILCodeStream* pcsEmit);
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
void SetInteropParamExceptionInfo(UINT resID, UINT paramIdx);
bool HasInteropParamExceptionInfo();
@@ -549,9 +530,6 @@ protected:
void InitCleanupCode();
void InitExceptionCleanupCode();
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- BOOL IsCopyCtorStubNeeded();
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
ILCodeStream* m_pcsSetup;
@@ -583,10 +561,6 @@ protected:
DWORD m_dwCleanupWorkListLocalNum;
DWORD m_dwRetValLocalNum;
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- DWORD m_dwFirstCopyCtorCookieLocalNum; // list head passed to SetCopyCtorCookieChain
- DWORD m_dwLastCopyCtorCookieLocalNum; // used for chaining the cookies into a linked list
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
UINT m_ErrorResID;
UINT m_ErrorParamIdx;
@@ -595,18 +569,6 @@ protected:
DWORD m_dwStubFlags;
};
-#ifndef _TARGET_X86_
-// The one static host for stub used on !_TARGET_X86_
-EXTERN_C void PInvokeStubForHost(void);
-#endif
-
-#ifdef FEATURE_MIXEDMODE // IJW
-// This attempts to guess whether a target is an API call that uses SetLastError to communicate errors.
-BOOL HeuristicDoesThisLooksLikeAnApiCall(LPBYTE pTarget);
-BOOL HeuristicDoesThisLookLikeAGetLastErrorCall(LPBYTE pTarget);
-DWORD __stdcall FalseGetLastError();
-#endif // FEATURE_MIXEDMODE
-
class NDirectStubParameters
{
public:
@@ -665,7 +627,6 @@ HRESULT FindPredefinedILStubMethod(MethodDesc *pTargetMD, DWORD dwStubFlags, Met
EXTERN_C BOOL CallNeedsHostHook(size_t target);
-#ifndef FEATURE_INCLUDE_ALL_INTERFACES
//
// Inlinable implementation allows compiler to strip all code related to host hook
//
@@ -680,7 +641,6 @@ inline BOOL CallNeedsHostHook(size_t target)
LIMITED_METHOD_CONTRACT;
return FALSE;
}
-#endif
//
// Limit length of string field in IL stub ETW events so that the whole
diff --git a/src/vm/dllimportcallback.cpp b/src/vm/dllimportcallback.cpp
index 12613cb96b..c70d52d02e 100644
--- a/src/vm/dllimportcallback.cpp
+++ b/src/vm/dllimportcallback.cpp
@@ -39,45 +39,6 @@ EXTERN_C void STDCALL UM2MThunk_WrapperHelper(void *pThunkArgs,
UMEntryThunk *pEntryThunk,
Thread *pThread);
-EXTERN_C void __fastcall ReverseEnterRuntimeHelper(Thread *pThread)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- SO_TOLERANT;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // ReverseEnterRuntimeThrowComplus probes.
- //BEGIN_ENTRYPOINT_THROWS;
-
- _ASSERTE (pThread == GetThread());
-
-#ifdef FEATURE_STACK_PROBE
- // The thread is calling into managed code. If we have the following sequence on stack
- // Managed code 1 -> Unmanaged code -> Managed code 2,
- // and we hit SO in managed code 2, in order to unwind stack for managed code 1, we need
- // to make sure the thread is in cooperative gc mode. Due to unmanaged code in between,
- // when we reach managed code 1, the thread is in preemptive GC mode. In order to switch
- // to cooperative, we need to have enough stack. This means that we need to reclaim stack
- // for managed code 2. Therefore we require that we have some amount of stack before entering
- // managed code 2.
- RetailStackProbe(static_cast<UINT>(ADJUST_PROBE(BACKOUT_CODE_STACK_LIMIT)),pThread);
-#endif
- pThread->ReverseEnterRuntimeThrowComplus();
- //END_ENTRYPOINT_THROWS
-}
-
-EXTERN_C void __fastcall ReverseLeaveRuntimeHelper(Thread *pThread)
-{
- WRAPPER_NO_CONTRACT;
-
- _ASSERTE (pThread == GetThread());
- pThread->ReverseLeaveRuntime();
-}
-
#ifdef MDA_SUPPORTED
EXTERN_C void __fastcall CallbackOnCollectedDelegateHelper(UMEntryThunk *pEntryThunk)
{
@@ -378,53 +339,6 @@ VOID UMEntryThunk::CompileUMThunkWorker(UMThunkStubInfo *pInfo,
// would deadlock).
pcpusl->EmitLabel(pDoADCallBackStartLabel);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (NDirect::IsHostHookEnabled())
- {
- // We call ReverseEnterRuntimeHelper before we link a frame.
- // So we know that when exception unwinds through our ReverseEnterRuntimeFrame,
- // we need call ReverseLeaveRuntime.
-
- // save registers
- pcpusl->X86EmitPushReg(kEAXentryThunk);
- pcpusl->X86EmitPushReg(kECXthread);
-
- // ecx still has Thread
- // ReverseEnterRuntimeHelper is a fast call
- pcpusl->X86EmitCall(pcpusl->NewExternalCodeLabel((LPVOID)ReverseEnterRuntimeHelper), 0);
-
- // restore registers
- pcpusl->X86EmitPopReg(kECXthread);
- pcpusl->X86EmitPopReg(kEAXentryThunk);
-
- // push reg; leave room for m_next
- pcpusl->X86EmitPushReg(kDummyPushReg);
-
- // push IMM32 ; push Frame vptr
- pcpusl->X86EmitPushImm32((UINT32)(size_t)ReverseEnterRuntimeFrame::GetMethodFrameVPtr());
-
- // mov edx, esp ;; set EDX -> new frame
- pcpusl->X86EmitMovRegSP(kEDX);
-
- // push IMM32 ; push gsCookie
- pcpusl->X86EmitPushImmPtr((LPVOID)GetProcessGSCookie());
-
- // save UMEntryThunk
- pcpusl->X86EmitPushReg(kEAXentryThunk);
-
- // mov eax,[ecx + Thread.GetFrame()] ;; get previous frame
- pcpusl->X86EmitIndexRegLoad(kEAXentryThunk, kECXthread, Thread::GetOffsetOfCurrentFrame());
-
- // mov [edx + Frame.m_next], eax
- pcpusl->X86EmitIndexRegStore(kEDX, Frame::GetOffsetOfNextLink(), kEAX);
-
- // mov [ecx + Thread.GetFrame()], edx
- pcpusl->X86EmitIndexRegStore(kECXthread, Thread::GetOffsetOfCurrentFrame(), kEDX);
-
- // restore EAX
- pcpusl->X86EmitPopReg(kEAXentryThunk);
- }
-#endif
#ifdef MDA_SUPPORTED
if ((pInfo->m_wFlags & umtmlSkipStub) && !(pInfo->m_wFlags & umtmlIsStatic) &&
@@ -624,39 +538,6 @@ VOID UMEntryThunk::CompileUMThunkWorker(UMThunkStubInfo *pInfo,
// restore the thread pointer
pcpusl->X86EmitPopReg(kECXthread);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (NDirect::IsHostHookEnabled())
- {
-#ifdef _DEBUG
- // lea edx, [esp + sizeof(GSCookie)] ; edx <- current Frame
- pcpusl->X86EmitEspOffset(0x8d, kEDX, sizeof(GSCookie));
- pcpusl->EmitCheckGSCookie(kEDX, ReverseEnterRuntimeFrame::GetOffsetOfGSCookie());
-#endif
-
- // Remove our frame
- // Get the previous frame into EDX
- // mov edx, [esp + GSCookie + Frame.m_next]
- static const BYTE initArg1[] = { 0x8b, 0x54, 0x24, 0x08 }; // mov edx, [esp+8]
- _ASSERTE(ReverseEnterRuntimeFrame::GetNegSpaceSize() + Frame::GetOffsetOfNextLink() == 0x8);
- pcpusl->EmitBytes(initArg1, sizeof(initArg1));
-
- // mov [ecx + Thread.GetFrame()], edx
- pcpusl->X86EmitIndexRegStore(kECXthread, Thread::GetOffsetOfCurrentFrame(), kEDX);
-
- // pop off stack
- // add esp, 8
- pcpusl->X86EmitAddEsp(sizeof(GSCookie) + sizeof(ReverseEnterRuntimeFrame));
-
- // Save pThread
- pcpusl->X86EmitPushReg(kECXthread);
-
- // ReverseEnterRuntimeHelper is a fast call
- pcpusl->X86EmitCall(pcpusl->NewExternalCodeLabel((LPVOID)ReverseLeaveRuntimeHelper), 0);
-
- // Restore pThread
- pcpusl->X86EmitPopReg(kECXthread);
- }
-#endif
// Check whether we got here via the switch AD case. We can tell this by looking at whether the
// caller's arguments immediately precede our EBP frame (they will for the non-switch case but
@@ -1491,13 +1372,71 @@ VOID UMThunkMarshInfo::RunTimeInit()
pStubMD = GetILStubMethodDesc(pMD, &sigInfo, dwStubFlags);
pFinalILStub = JitILStub(pStubMD);
+
}
}
+#if defined(_TARGET_X86_)
+ MetaSig sig(pMD);
+ int numRegistersUsed = 0;
+ UINT16 cbRetPop = 0;
+
+ //
+ // m_cbStackArgSize represents the number of arg bytes for the MANAGED signature
+ //
+ m_cbStackArgSize = 0;
+
+ int offs = 0;
+
+#ifdef UNIX_X86_ABI
+ if (HasRetBuffArgUnmanagedFixup(&sig))
+ {
+ // callee should pop retbuf
+ numRegistersUsed += 1;
+ offs += STACK_ELEM_SIZE;
+ cbRetPop += STACK_ELEM_SIZE;
+ }
+#endif // UNIX_X86_ABI
+
+ for (UINT i = 0 ; i < sig.NumFixedArgs(); i++)
+ {
+ TypeHandle thValueType;
+ CorElementType type = sig.NextArgNormalized(&thValueType);
+ int cbSize = sig.GetElemSize(type, thValueType);
+ if (ArgIterator::IsArgumentInRegister(&numRegistersUsed, type))
+ {
+ offs += STACK_ELEM_SIZE;
+ }
+ else
+ {
+ offs += StackElemSize(cbSize);
+ m_cbStackArgSize += StackElemSize(cbSize);
+ }
+ }
+ m_cbActualArgSize = (pStubMD != NULL) ? pStubMD->AsDynamicMethodDesc()->GetNativeStackArgSize() : offs;
+
+ PInvokeStaticSigInfo sigInfo;
+ if (pMD != NULL)
+ new (&sigInfo) PInvokeStaticSigInfo(pMD);
+ else
+ new (&sigInfo) PInvokeStaticSigInfo(GetSignature(), GetModule());
+ if (sigInfo.GetCallConv() == pmCallConvCdecl)
+ {
+ m_cbRetPop = cbRetPop;
+ }
+ else
+ {
+ // For all the other calling convention except cdecl, callee pops the stack arguments
+ m_cbRetPop = cbRetPop + static_cast<UINT16>(m_cbActualArgSize);
+ }
+#else // _TARGET_X86_
//
// m_cbActualArgSize gets the number of arg bytes for the NATIVE signature
//
- m_cbActualArgSize = (pStubMD != NULL) ? pStubMD->AsDynamicMethodDesc()->GetNativeStackArgSize() : pMD->SizeOfArgStack();
+ m_cbActualArgSize =
+ (pStubMD != NULL) ? pStubMD->AsDynamicMethodDesc()->GetNativeStackArgSize() : pMD->SizeOfArgStack();
+
+#endif // _TARGET_X86_
#endif // _TARGET_X86_ && !FEATURE_STUBS_AS_IL
@@ -1505,6 +1444,86 @@ VOID UMThunkMarshInfo::RunTimeInit()
InterlockedCompareExchangeT<PCODE>(&m_pILStub, pFinalILStub, (PCODE)1);
}
+#if defined(_TARGET_X86_) && defined(FEATURE_STUBS_AS_IL)
+VOID UMThunkMarshInfo::SetupArguments(char *pSrc, ArgumentRegisters *pArgRegs, char *pDst)
+{
+ MethodDesc *pMD = GetMethod();
+
+ _ASSERTE(pMD);
+
+ //
+ // x86 native uses the following stack layout:
+ // | saved eip |
+ // | --------- | <- CFA
+ // | stkarg 0 |
+ // | stkarg 1 |
+ // | ... |
+ // | stkarg N |
+ //
+ // x86 managed, however, uses a bit different stack layout:
+ // | saved eip |
+ // | --------- | <- CFA
+ // | stkarg M | (NATIVE/MANAGE may have different number of stack arguments)
+ // | ... |
+ // | stkarg 1 |
+ // | stkarg 0 |
+ //
+ // This stub bridges the gap between them.
+ //
+ char *pCurSrc = pSrc;
+ char *pCurDst = pDst + m_cbStackArgSize;
+
+ MetaSig sig(pMD);
+
+ int numRegistersUsed = 0;
+
+#ifdef UNIX_X86_ABI
+ if (HasRetBuffArgUnmanagedFixup(&sig))
+ {
+ // Pass retbuf via Ecx
+ numRegistersUsed += 1;
+ pArgRegs->Ecx = *((UINT32 *)pCurSrc);
+ pCurSrc += STACK_ELEM_SIZE;
+ }
+#endif // UNIX_X86_ABI
+
+ for (UINT i = 0 ; i < sig.NumFixedArgs(); i++)
+ {
+ TypeHandle thValueType;
+ CorElementType type = sig.NextArgNormalized(&thValueType);
+ int cbSize = sig.GetElemSize(type, thValueType);
+ int elemSize = StackElemSize(cbSize);
+
+ if (ArgIterator::IsArgumentInRegister(&numRegistersUsed, type))
+ {
+ _ASSERTE(elemSize == STACK_ELEM_SIZE);
+
+ if (numRegistersUsed == 1)
+ pArgRegs->Ecx = *((UINT32 *)pCurSrc);
+ else if (numRegistersUsed == 2)
+ pArgRegs->Edx = *((UINT32 *)pCurSrc);
+ }
+ else
+ {
+ pCurDst -= elemSize;
+ memcpy(pCurDst, pCurSrc, elemSize);
+ }
+
+ pCurSrc += elemSize;
+ }
+
+ _ASSERTE(pDst == pCurDst);
+}
+
+EXTERN_C VOID STDCALL UMThunkStubSetupArgumentsWorker(UMThunkMarshInfo *pMarshInfo,
+ char *pSrc,
+ UMThunkMarshInfo::ArgumentRegisters *pArgRegs,
+ char *pDst)
+{
+ pMarshInfo->SetupArguments(pSrc, pArgRegs, pDst);
+}
+#endif // _TARGET_X86_ && FEATURE_STUBS_AS_IL
+
#ifdef _DEBUG
void STDCALL LogUMTransition(UMEntryThunk* thunk)
{
diff --git a/src/vm/dllimportcallback.h b/src/vm/dllimportcallback.h
index c2ed6d0039..af2a0b1d92 100644
--- a/src/vm/dllimportcallback.h
+++ b/src/vm/dllimportcallback.h
@@ -205,16 +205,32 @@ public:
Stub *CompileNExportThunk(LoaderHeap *pLoaderHeap, PInvokeStaticSigInfo* pSigInfo, MetaSig *pMetaSig, BOOL fNoStub);
#endif // _TARGET_X86_ && !FEATURE_STUBS_AS_IL
+#if defined(_TARGET_X86_) && defined(FEATURE_STUBS_AS_IL)
+ struct ArgumentRegisters
+ {
+ UINT32 Ecx;
+ UINT32 Edx;
+ };
+
+ VOID SetupArguments(char *pSrc, ArgumentRegisters *pArgRegs, char *pDst);
+#endif // _TARGET_X86_ && FEATURE_STUBS_AS_IL
+
private:
PCODE m_pILStub; // IL stub for marshaling
// On x86, NULL for no-marshal signatures
// On non-x86, the managed entrypoint for no-delegate no-marshal signatures
UINT32 m_cbActualArgSize; // caches m_pSig.SizeOfFrameArgumentArray()
-#if defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL)
- Stub* m_pExecStub; // UMEntryThunk jumps directly here
+ // On x86/Linux we have to augment with numRegistersUsed * STACK_ELEM_SIZE
+#if defined(_TARGET_X86_)
UINT16 m_cbRetPop; // stack bytes popped by callee (for UpdateRegDisplay)
+#if defined(FEATURE_STUBS_AS_IL)
+ UINT32 m_cbStackArgSize; // stack bytes pushed for managed code
+#else
+ Stub* m_pExecStub; // UMEntryThunk jumps directly here
UINT16 m_callConv; // unmanaged calling convention and flags (CorPinvokeMap)
-#endif
+#endif // FEATURE_STUBS_AS_IL
+#endif // _TARGET_X86_
+
MethodDesc * m_pMD; // maybe null
Module * m_pModule;
Signature m_sig;
diff --git a/src/vm/domainfile.cpp b/src/vm/domainfile.cpp
index bfb69cdd48..2193c5a28d 100644
--- a/src/vm/domainfile.cpp
+++ b/src/vm/domainfile.cpp
@@ -30,12 +30,9 @@
#include "compile.h"
#endif // FEATURE_PREJIT
-#include "umthunkhash.h"
+#include "dllimportcallback.h"
#include "peimagelayout.inl"
-#if !defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
-#include "policy.h" // for fusion::util::isanyframeworkassembly
-#endif
#include "winrthelpers.h"
#ifdef FEATURE_PERFMAP
@@ -105,10 +102,6 @@ DomainFile::~DomainFile()
m_pOriginalFile->Release();
if (m_pDynamicMethodTable)
m_pDynamicMethodTable->Destroy();
-#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE)
- if (m_pUMThunkHash)
- delete m_pUMThunkHash;
-#endif
delete m_pError;
}
@@ -414,19 +407,8 @@ DomainAssembly *DomainFile::GetDomainAssembly()
}
CONTRACTL_END;
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- if (IsAssembly())
- {
- return dac_cast<PTR_DomainAssembly>(this);
- }
- else
- {
- return dac_cast<PTR_DomainModule>(this)->GetDomainAssembly();
- }
-#else
_ASSERTE(IsAssembly());
return (DomainAssembly *) this;
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
}
BOOL DomainFile::IsIntrospectionOnly()
@@ -743,7 +725,6 @@ void DomainFile::VerifyNativeImageDependencies(bool verifyOnly)
if (pDependency->signNativeImage == INVALID_NGEN_SIGNATURE)
continue;
-#ifdef FEATURE_CORECLR // hardbinding
//
// CoreCLR hard binds to mscorlib.dll only. Avoid going through the full load.
@@ -759,51 +740,6 @@ void DomainFile::VerifyNativeImageDependencies(bool verifyOnly)
PEAssembly * pDependencyFile = SystemDomain::SystemFile();
-#else // FEATURE_CORECLR
-
- //
- // Load the manifest file for the given name assembly spec.
- //
-
- AssemblySpec name;
- name.InitializeSpec(pDependency->dwAssemblyRef,
- ((pManifestNativeImage != NULL) ? pManifestNativeImage : pNativeImage)->GetNativeMDImport(),
- GetDomainAssembly());
-
- if (this->GetAppDomain()->IsCompilationDomain())
- {
- //
- // Allow transitive closure of hardbound dependecies to be loaded during ngen.
- //
-
- DomainAssembly * pDependencyAssembly = name.LoadDomainAssembly(FILE_LOAD_FIND_NATIVE_IMAGE);
- pDependencyAssembly->GetFile()->SetSafeToHardBindTo();
- }
-
- DomainAssembly * pDependencyAssembly = NULL;
- {
- // We are about to validate the hard-bound dependencies of the assembly being loaded. The invariant of being hard-bound states
- // that each hard-bound dependency must have its NI image to be valid and available for loading and this is done recursively for each
- // hard-bound dependency.
- //
- // The validity (and presence) of the NI image happens in FILE_LOAD_ALLOCATE stage of assembly load, which is the next stage in assembly loading,
- // and not the current stage (FILE_LOAD_VERIFY_NATIVE_DEPENDENCIES). In FILE_LOAD_ALLOCATE, we do sharing checks, closure validation, redirection policy application, etc
- // before computing if a NI is available and if it is, whether it is valid or not.
- //
- // However, we need to know about validity of NI in the current(and earlier) stage. As a result, we will temporarily set the assembly load limit (defined as the maximum
- // load level till which recursive assembly load can execute) to be FILE_LOAD_ALLOCATE if we have been invoked to validate the NI dependencies for the first time.
- //
- // A valid concern at this point is that we would allow to load a dependency at a load stage higher than its dependent assembly as it could crete cycles. This concern is
- // alleviated since we are doing this override (of the load stage) only for hard-bound dependencies and NGEN is responsible for ensuring that there are no cycles.
- //
- // As a result, once the dependency load returns, we will know for sure if the dependency has a valid NI or not.
- OVERRIDE_LOAD_LEVEL_LIMIT(verifyOnly ? FILE_LOADED : FILE_LOAD_ALLOCATE);
- pDependencyAssembly = name.LoadDomainAssembly(FILE_LOADED);
- }
-
- PEAssembly * pDependencyFile = pDependencyAssembly->GetFile();
-
-#endif // FEATURE_CORECLR
ReleaseHolder<PEImage> pDependencyNativeImage = pDependencyFile->GetNativeImageWithRef();
if (pDependencyNativeImage == NULL)
@@ -815,7 +751,6 @@ void DomainFile::VerifyNativeImageDependencies(bool verifyOnly)
goto NativeImageRejected;
}
-#ifndef FEATURE_FUSION // Fusion does this verification at native binding time.
PTR_PEImageLayout pDependencyNativeLayout = pDependencyNativeImage->GetLoadedLayout();
// Assert that the native image signature is as expected
// Fusion will ensure this
@@ -825,7 +760,6 @@ void DomainFile::VerifyNativeImageDependencies(bool verifyOnly)
LoggablePEAssembly logAsm(pDependencyFile);
if (!RuntimeVerifyNativeImageDependency(pDependency, pDependencyNativeVersion, &logAsm))
goto NativeImageRejected;
-#endif
}
LOG((LF_ZAP, LL_INFO100, "ZAP: Native image dependencies for %S OK.\n",
pNativeImage->GetPath().GetUnicode()));
@@ -1175,52 +1109,9 @@ void DomainFile::AddDependencies()
#ifdef FEATURE_PREJIT
-#ifdef FEATURE_CORECLR // hardbinding
//
// CoreCLR hard binds to mscorlib.dll only. No need to track hardbound dependencies.
//
-#else
- // Add hard bindings as unconditional dependencies
- if (GetFile()->HasNativeImage() && GetCurrentModule()->HasNativeImage() && IsAssembly())
- {
- PEImage *pNativeImage = GetFile()->GetPersistentNativeImage();
- PEImageLayout *pNativeLayout = pNativeImage->GetLoadedLayout();
-
- COUNT_T cDependencies;
- CORCOMPILE_DEPENDENCY *pDependencies = pNativeLayout->GetNativeDependencies(&cDependencies);
- CORCOMPILE_DEPENDENCY *pDependenciesEnd = pDependencies + cDependencies;
-
- while (pDependencies < pDependenciesEnd)
- {
- if (pDependencies->signNativeImage != INVALID_NGEN_SIGNATURE)
- {
-
- //
- // Load the manifest file for the given name assembly spec.
- //
-
- AssemblySpec name;
- name.InitializeSpec(pDependencies->dwAssemblyRef,
- pNativeImage->GetNativeMDImport(),
- GetDomainAssembly());
-
- DomainAssembly *pDependency = name.LoadDomainAssembly(FILE_LOADED);
-
- // Right now we only support hard binding to other manifest modules so we don't
- // need to consider the other module cases
- Module *pModule = pDependency->GetModule();
-
- // Add hard binding as an unconditional active dependency
- STRESS_LOG4(LF_CODESHARING,LL_INFO100,"unconditional dependency %p %p %i %i\n",
- GetFile(),GetCurrentModule(),GetFile()->HasNativeImage(),GetCurrentModule()->HasNativeImage());
- if(!pModule->IsSystem())
- GetCurrentModule()->AddActiveDependency(pModule, TRUE);
- }
-
- pDependencies++;
- }
- }
-#endif // FEATURE_CORECLR
#endif // FEATURE_PREJIT
}
@@ -1263,10 +1154,6 @@ void DomainFile::VtableFixups()
{
WRAPPER_NO_CONTRACT;
-#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE)
- if (!GetCurrentModule()->IsResource())
- GetCurrentModule()->FixupVTables();
-#endif
}
void DomainFile::FinishLoad()
@@ -1282,27 +1169,6 @@ void DomainFile::FinishLoad()
if (m_pFile->HasNativeImage())
{
-#ifdef FEATURE_FUSION
- // <REVISIT_TODO>Because of bug 112034, we may commit to a native image even though
- // we should not have.</REVISIT_TODO>
-
-// #ifdef _DEBUG
-
- // Verify that the native image dependencies are still valid
- // Since we had already committed to using a native image, they cannot
- // be invalidated
- VerifyNativeImageDependencies(true);
- _ASSERTE(m_pFile->HasNativeImage());
-
- if (!m_pFile->HasNativeImage())
- {
- STRESS_LOG1(LF_CODESHARING, LL_FATALERROR, "Incorrectly committed to using native image for %S",
- m_pFile->GetPath().GetUnicode());
- EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
- }
-// #endif
-
-#endif // FEATURE_FUSION
LOG((LF_ZAP, LL_INFO10, "Using native image %S.\n", m_pFile->GetPersistentNativeImage()->GetPath().GetUnicode()));
ExternalLog(LL_INFO10, "Native image successfully used.");
@@ -1315,7 +1181,7 @@ void DomainFile::FinishLoad()
// Are we absolutely required to use a native image?
CheckZapRequired();
-#if defined(FEATURE_CORECLR) && defined(FEATURE_COMINTEROP)
+#if defined(FEATURE_COMINTEROP)
// If this is a winmd file, ensure that the ngen reference namespace is loadable.
// This is necessary as on the phone we don't check ngen image dependencies, and thus we can get in a situation
// where a winmd is loaded as a dependency of an ngen image, but the type used to build cross module references
@@ -1350,7 +1216,7 @@ void DomainFile::FinishLoad()
}
}
}
-#endif // defined(FEATURE_CORECLR) && defined(FEATURE_COMINTEROP)
+#endif //defined(FEATURE_COMINTEROP)
#endif // FEATURE_PREJIT
// Flush any log messages
@@ -1499,12 +1365,10 @@ void DomainFile::Activate()
m_bDisableActivationCheck=TRUE;
pMT->CheckRunClassInitThrowing();
}
-#ifdef FEATURE_CORECLR
if (g_pConfig->VerifyModulesOnLoad())
{
m_pModule->VerifyAllMethods();
}
-#endif //FEATURE_CORECLR
#ifdef _DEBUG
if (g_pConfig->ExpandModulesOnLoad())
{
@@ -1699,9 +1563,6 @@ DomainAssembly::DomainAssembly(AppDomain *pDomain, PEFile *pFile, AssemblyLoadSe
: DomainFile(pDomain, pFile),
m_pAssembly(NULL),
m_debuggerFlags(DACF_NONE),
-#ifdef FEATURE_FUSION
- m_pAssemblyBindingClosure(NULL),
-#endif
m_MissingDependenciesCheckStatus(CMD_Unknown),
m_fSkipPolicyResolution(pLoadSecurity != NULL && !pLoadSecurity->ShouldResolvePolicy()),
m_fDebuggerUnloadStarted(FALSE),
@@ -1735,76 +1596,6 @@ DomainAssembly::DomainAssembly(AppDomain *pDomain, PEFile *pFile, AssemblyLoadSe
if (pLoadSecurity != NULL)
{
-#ifdef FEATURE_CAS_POLICY
- // If this assembly had a file name specified, we aren't allowed to load from remote sources and we
- // aren't in CAS policy mode (which sandboxes remote assemblies automatically), then we need to do a
- // check on this assembly's zone of origin when creating it.
- if (pLoadSecurity->m_fCheckLoadFromRemoteSource &&
- !pLoadSecurity->m_fSuppressSecurityChecks &&
- !m_pDomain->GetSecurityDescriptor()->AllowsLoadsFromRemoteSources() &&
- !pFile->IsIntrospectionOnly())
- {
- SString strCodeBase;
- BYTE pbUniqueID[MAX_SIZE_SECURITY_ID];
- DWORD cbUniqueID = COUNTOF(pbUniqueID);
- SecZone dwZone = NoZone;
-
- GetSecurityIdentity(strCodeBase,
- &dwZone,
- 0,
- pbUniqueID,
- &cbUniqueID);
-
- // Since loads from remote sources are not enabled for this assembly, we only want to allow the
- // load if any of the following conditions apply:
- //
- // * The load is coming off the local machine
- // * The load is coming from the intranet or a trusted site, and the code base is UNC. (ie,
- // don't allow HTTP loads off the local intranet
-
- bool safeLoad = false;
- if (dwZone == LocalMachine)
- {
- safeLoad = true;
- }
- else if (dwZone == Intranet || dwZone == Trusted)
- {
- if (UrlIsFileUrl(strCodeBase.GetUnicode()))
- {
- safeLoad = true;
- }
- else if (PathIsUNC(strCodeBase.GetUnicode()))
- {
- safeLoad = true;
- }
- }
-
- if (!safeLoad)
- {
- // We've tried to load an assembly from a location where it would have been sandboxed in legacy
- // CAS situations, but the application hasn't indicated that this is a safe thing to do. In
- // order to prevent accidental security holes by silently loading assemblies in full trust that
- // an application expected to be sandboxed, we'll throw an exception instead.
- //
- // Since this exception can commonly occur with if the file is physically located on the
- // hard drive, but has the mark of the web on it we'll also try to detect this mark and
- // provide a customized error message if we find it. We do that by re-evaluating the
- // assembly's zone with the NOSAVEDFILECHECK flag, which ignores the mark of the web, and if
- // that comes back as MyComputer we flag the assembly as having the mark of the web on it.
- SecZone dwNoMotwZone = NoZone;
- GetSecurityIdentity(strCodeBase, &dwNoMotwZone, MUTZ_NOSAVEDFILECHECK, pbUniqueID, &cbUniqueID);
-
- if (dwNoMotwZone == LocalMachine)
- {
- COMPlusThrow(kNotSupportedException, IDS_E_LOADFROM_REMOTE_SOURCE_MOTW);
- }
- else
- {
- COMPlusThrow(kNotSupportedException, IDS_E_LOADFROM_REMOTE_SOURCE);
- }
- }
- }
-#endif // FEATURE_CAS_POLICY
if (GetFile()->IsSourceGAC())
{
@@ -1816,45 +1607,9 @@ DomainAssembly::DomainAssembly(AppDomain *pDomain, PEFile *pFile, AssemblyLoadSe
}
else
{
-#ifdef FEATURE_FUSION
- // We do not support sharing behavior of ALWAYS when using evidence to load assemblies
- if (pDomain->GetSharePolicy() == AppDomain::SHARE_POLICY_ALWAYS
- && ShouldLoadDomainNeutral())
- {
- // Just because we have information about the loaded assembly's security doesn't mean that
- // we're trying to override evidence, make sure we're not just trying to push a grant set
- if (((pLoadSecurity->m_pEvidence != NULL) && (*pLoadSecurity->m_pEvidence != NULL)) ||
- ((pLoadSecurity->m_pAdditionalEvidence != NULL) && (*pLoadSecurity->m_pAdditionalEvidence != NULL)))
- {
- // We may not be able to reduce sharing policy at this point, if we have already loaded
- // some non-GAC assemblies as domain neutral. For this case we must regrettably fail
- // the whole operation.
- if (!pDomain->ReduceSharePolicyFromAlways())
- {
- ThrowHR(COR_E_CANNOT_SPECIFY_EVIDENCE);
- }
- }
- }
-#endif
{
GCX_COOP();
-#ifdef FEATURE_CAS_POLICY
- if (pLoadSecurity->m_pAdditionalEvidence != NULL)
- {
- if(*pLoadSecurity->m_pAdditionalEvidence != NULL)
- {
- pSecurityDescriptorHolder->SetAdditionalEvidence(*pLoadSecurity->m_pAdditionalEvidence);
- }
- }
- else if (pLoadSecurity->m_pEvidence != NULL)
- {
- if (*pLoadSecurity->m_pEvidence != NULL)
- {
- pSecurityDescriptorHolder->SetEvidence(*pLoadSecurity->m_pEvidence);
- }
- }
-#endif // FEATURE_CAS_POLICY
// If the assembly being loaded already knows its grant set (for instnace, it's being pushed
// from the loading assembly), then we can set that up now as well
@@ -1862,15 +1617,6 @@ DomainAssembly::DomainAssembly(AppDomain *pDomain, PEFile *pFile, AssemblyLoadSe
{
_ASSERTE(pLoadSecurity->m_pGrantSet != NULL);
-#ifdef FEATURE_CAS_POLICY
- // The permissions from an anonymously hosted dynamic method are fulltrust/transparent,
- // so ensure we have full trust to pass that on to the new assembly
- if(pLoadSecurity->m_fPropagatingAnonymouslyHostedDynamicMethodGrant &&
- !CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_Security_DisableAnonymouslyHostedDynamicMethodCreatorSecurityCheck))
- {
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_FULL_TRUST);
- }
-#endif // FEATURE_CAS_POLICY
pSecurityDescriptorHolder->PropagatePermissionSet(
*pLoadSecurity->m_pGrantSet,
@@ -1928,10 +1674,6 @@ void DomainAssembly::ReleaseFiles()
if(m_pAssembly)
m_pAssembly->StartUnload();
-#ifdef FEATURE_FUSION
- // release the old closure from the holder
- m_pAssemblyBindingClosure=NULL;
-#endif
ModuleIterator i = IterateModules(kModIterIncludeLoading);
while (i.Next())
{
@@ -1954,26 +1696,6 @@ void DomainAssembly::SetAssembly(Assembly* pAssembly)
pAssembly->SetDomainAssembly(this);
}
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-void DomainAssembly::AddModule(DomainModule *pModule)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- DWORD index = RidFromToken(pModule->GetToken());
-
- while (index >= m_Modules.GetCount())
- IfFailThrow(m_Modules.Append(NULL));
-
- m_Modules.Set(index, pModule);
-}
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
#ifndef CROSSGEN_COMPILE
//---------------------------------------------------------------------------------------
@@ -2070,169 +1792,20 @@ OBJECTREF DomainAssembly::GetExposedAssemblyObject()
#ifdef FEATURE_LOADER_OPTIMIZATION
-#ifdef FEATURE_FUSION
-// This inner method exists to avoid EX_TRY calling _alloca repeatedly in the for loop below.
-DomainAssembly::CMDI_Result DomainAssembly::CheckMissingDependencyInner(IAssemblyBindingClosure* pClosure, DWORD idx)
-{
- CONTRACTL {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- } CONTRACTL_END;
-
- SafeComHolder<IAssemblyName> pAssemblyName;
- HRESULT hrBindFailure = S_OK;
- HRESULT hr = pClosure->GetNextFailureAssembly(idx, &pAssemblyName, &hrBindFailure);
- if (hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
- {
- return CMDI_End;
- }
-
- IfFailThrow(hr);
-
- CMDI_Result ret = CMDI_AssemblyResolveFailed;
- AssemblySpec spec;
- PEAssemblyHolder result;
-
- EX_TRY
- {
- spec.InitializeSpec(pAssemblyName, this, FALSE);
- result = this->GetAppDomain()->TryResolveAssembly(&spec,FALSE);
-
- if (result && result->CanUseWithBindingCache())
- {
- this->GetAppDomain()->AddFileToCache(&spec, result);
- ret = CMDI_AssemblyResolveSucceeded;
- }
- else
- {
- _ASSERTE(FAILED(hrBindFailure));
-
- StackSString name;
- spec.GetFileOrDisplayName(0, name);
- NewHolder<EEFileLoadException> pEx(new EEFileLoadException(name, hrBindFailure));
- this->GetAppDomain()->AddExceptionToCache(&spec, pEx);
- }
- }
- EX_CATCH
- {
- // For compat reasons, we don't want to throw right now but make sure that we
- // cache the exception so that it can be thrown if/when we try to load the
- // further down the road. See VSW 528532 for more details.
- }
- EX_END_CATCH(RethrowTransientExceptions);
-
- return ret;
-}
-
-
-// CheckMissingDependencies returns FALSE if any missing dependency would
-// successfully bind with an AssemblyResolve event. When this is the case, we
-// want to avoid sharing this assembly, since AssemblyResolve events are not
-// under our control, and therefore not predictable.
-CMD_State DomainAssembly::CheckMissingDependencies()
-{
- CONTRACTL {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- } CONTRACTL_END;
-
- if (MissingDependenciesCheckDone())
- return m_MissingDependenciesCheckStatus;
-
- if (this->GetAppDomain()->IsCompilationDomain())
- {
- // Compilation domains will never have resolve events. Plus, this path
- // will sidestep the compilation domain's bind override, which will make
- // us skip over some dependencies.
- m_MissingDependenciesCheckStatus = CMD_NotNeeded;
- return m_MissingDependenciesCheckStatus;
- }
-
- if (IsSystem())
- {
- m_MissingDependenciesCheckStatus = CMD_NotNeeded;
- return m_MissingDependenciesCheckStatus;
- }
-
- GCX_PREEMP();
- IAssemblyBindingClosure * pClosure = GetAssemblyBindingClosure(LEVEL_COMPLETE);
-
- if(pClosure == NULL)
- {
- // If the closure is empty, no need to iterate them.
- m_MissingDependenciesCheckStatus = CMD_NotNeeded;
- return m_MissingDependenciesCheckStatus;
- }
-
- for (DWORD idx = 0;;idx++)
- {
- switch (CheckMissingDependencyInner(pClosure, idx))
- {
- case CMDI_AssemblyResolveSucceeded:
- {
- STRESS_LOG1(LF_CODESHARING,LL_INFO100,"Missing dependencies check FAILED, DomainAssembly=%p",this);
- m_MissingDependenciesCheckStatus = CMD_Resolved;
- return m_MissingDependenciesCheckStatus;
- break;
- }
-
- case CMDI_End:
- {
- STRESS_LOG1(LF_CODESHARING,LL_INFO100,"Missing dependencies check SUCCESSFUL, DomainAssembly=%p",this);
- m_MissingDependenciesCheckStatus = CMD_IndeedMissing;
- return m_MissingDependenciesCheckStatus;
- break;
- }
-
- case CMDI_AssemblyResolveFailed:
- {
- // Don't take any action, just continue the loop.
- break;
- }
- }
- }
-}
-#endif // FEATURE_FUSION
BOOL DomainAssembly::MissingDependenciesCheckDone()
{
return m_MissingDependenciesCheckStatus != CMD_Unknown;
}
-#ifdef FEATURE_CORECLR
CMD_State DomainAssembly::CheckMissingDependencies()
{
//CoreCLR simply doesn't share if dependencies are missing
return CMD_NotNeeded;
}
-#endif // FEATURE_CORECLR
#endif // FEATURE_LOADER_OPTIMIZATION
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-DomainFile* DomainAssembly::FindModule(PEFile *pFile, BOOL includeLoading)
-{
- CONTRACT (DomainFile*)
- {
- INSTANCE_CHECK;
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END;
-
- ModuleIterator i = IterateModules(includeLoading ? kModIterIncludeLoading : kModIterIncludeLoaded);
- while (i.Next())
- {
- if (i.GetDomainFile()->Equals(pFile))
- RETURN i.GetDomainFile();
- }
- RETURN NULL;
-}
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
DomainFile* DomainAssembly::FindIJWModule(HMODULE hMod)
{
@@ -2305,34 +1878,7 @@ void DomainAssembly::FindNativeImage()
}
#endif // FEATURE_TREAT_NI_AS_MSIL_DURING_DIAGNOSTICS
-#ifndef FEATURE_CORECLR // hardbinding
- // The IsSafeToHardBindTo() check is only for use during the ngen compilation phase. It discards ngen images for
- // assemblies that aren't hard-bound to (as this would cause all such assemblies be loaded eagerly.)
- if (!IsSystem() && this->GetAppDomain()->IsCompilationDomain() && !GetFile()->IsSafeToHardBindTo())
- {
- if (!this->GetAppDomain()->ToCompilationDomain()->IsSafeToHardBindTo(GetFile()))
- {
- GetFile()->SetCannotUseNativeImage();
-
- if (GetFile()->HasNativeImage())
- GetFile()->ClearNativeImage();
-
- return;
- }
- GetFile()->SetSafeToHardBindTo();
- }
-#endif
-
-#ifdef FEATURE_FUSION
- DomainAssembly * pDomainAssembly = GetDomainAssembly();
- if (pDomainAssembly->GetSecurityDescriptor()->HasAdditionalEvidence() ||
- !(pDomainAssembly->GetFile()->IsContextLoad() ||
- pDomainAssembly->GetFile()->HasHostAssembly()))
- {
- m_pFile->SetCannotUseNativeImage();
- }
-#endif //FEATURE_FUSION
ClearNativeImageStress();
@@ -2340,7 +1886,7 @@ void DomainAssembly::FindNativeImage()
if (GetFile()->HasNativeImage())
{
-#if defined(_DEBUG) && defined(FEATURE_CORECLR)
+#if defined(_DEBUG)
if (g_pConfig->ForbidZap(GetSimpleName()))
{
SString sbuf;
@@ -2357,10 +1903,6 @@ void DomainAssembly::FindNativeImage()
m_dwReasonForRejectingNativeImage = ReasonForRejectingNativeImage_MscorlibNotNative;
STRESS_LOG2(LF_ZAP,LL_INFO100,"Rejecting native file %p, because mscolib has not NI - reason 0x%x\n",pNativeImage.GetValue(),m_dwReasonForRejectingNativeImage);
ExternalLog(LL_ERROR, "Rejecting native image because mscorlib does not have native image");
-#ifdef FEATURE_FUSION
- if(GetFile())
- GetFile()->ETWTraceLogMessage(ETW::BinderLog::BinderStructs::NGEN_BIND_SYSTEM_ASSEMBLY_NATIVEIMAGE_NOT_AVAILABLE, NULL);
-#endif
GetFile()->ClearNativeImage();
#ifdef FEATURE_WINDOWSPHONE
@@ -2377,10 +1919,6 @@ void DomainAssembly::FindNativeImage()
"The assembly's permissions must have changed since the time it was ngenned, "
"or it is running with a different security context.");
-#ifdef FEATURE_FUSION
- if(GetFile())
- GetFile()->ETWTraceLogMessage(ETW::BinderLog::BinderStructs::NGEN_BIND_ASSEMBLY_HAS_DIFFERENT_GRANT, NULL);
-#endif
GetFile()->ClearNativeImage();
#ifdef FEATURE_WINDOWSPHONE
@@ -2397,10 +1935,6 @@ void DomainAssembly::FindNativeImage()
"with one or more of its assembly dependencies. The assembly needs "
"to be ngenned again");
-#ifdef FEATURE_FUSION
- if(GetFile())
- GetFile()->ETWTraceLogMessage(ETW::BinderLog::BinderStructs::NGEN_BIND_DEPENDENCY_HAS_DIFFERENT_IDENTITY, NULL);
-#endif
GetFile()->ClearNativeImage();
#ifdef FEATURE_WINDOWSPHONE
@@ -2429,15 +1963,6 @@ void DomainAssembly::FindNativeImage()
{
GetFile()->SetNativeImageUsedExclusively();
}
-#ifdef FEATURE_FUSION
- else
- {
- if (!IsSystem())
- {
- GetFile()->SetNativeImageClosure(GetAssemblyBindingClosure(LEVEL_STARTING));
- }
- }
-#endif //FEATURE_FUSION
PEAssembly * pFile = (PEAssembly *)FastInterlockCompareExchangePointer((void **)ppNativeFile, (void *)GetFile(), (void *)NULL);
STRESS_LOG3(LF_ZAP,LL_INFO100,"Attempted to set new native file %p, old file was %p, location in the image=%p\n",GetFile(),pFile,ppNativeFile);
@@ -2446,9 +1971,6 @@ void DomainAssembly::FindNativeImage()
( !bExpectedToBeShared ||
pFile == PEFile::Dummy() ||
pFile->IsNativeImageUsedExclusively() ||
-#ifdef FEATURE_FUSION
- !pFile->HasEqualNativeClosure(this) ||
-#endif //FEATURE_FUSION
!(GetFile()->GetPath().Equals(pFile->GetPath())))
)
@@ -2465,10 +1987,6 @@ void DomainAssembly::FindNativeImage()
"- abandoning ngen image. The assembly will be JIT-compiled in "
"the second appdomain. See System.LoaderOptimization.MultiDomain "
"for information about domain-neutral loading.");
-#ifdef FEATURE_FUSION
- if(GetFile())
- GetFile()->ETWTraceLogMessage(ETW::BinderLog::BinderStructs::NGEN_BIND_ASSEMBLY_NOT_DOMAIN_NEUTRAL, NULL);
-#endif
GetFile()->ClearNativeImage();
// We only support a (non-shared) native image to be used from a single
@@ -2489,7 +2007,6 @@ void DomainAssembly::FindNativeImage()
}
}
-#if defined(FEATURE_CORECLR)
if (!GetFile()->HasNativeImage())
{
//
@@ -2504,7 +2021,6 @@ void DomainAssembly::FindNativeImage()
GetAppDomain()->CheckForMismatchedNativeImages(&spec, &mvid);
}
-#endif
CheckZapRequired();
}
@@ -2529,65 +2045,6 @@ BOOL DomainAssembly::ShouldLoadDomainNeutralHelper()
#ifdef FEATURE_LOADER_OPTIMIZATION
-#ifndef FEATURE_CORECLR
-
- BOOL fIsShareableHostAssembly = FALSE;
- if (GetFile()->HasHostAssembly())
- {
- IfFailThrow(GetFile()->GetHostAssembly()->IsShareable(&fIsShareableHostAssembly));
- }
-
-#ifdef FEATURE_FUSION
- // Only use domain neutral code for normal assembly loads
- if ((GetFile()->GetFusionAssembly() == NULL) && !fIsShareableHostAssembly)
- {
- return FALSE;
- }
-#endif
-
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
- // Introspection only does not use domain neutral code
- if (IsIntrospectionOnly())
- return FALSE;
-#endif
-
-#ifdef FEATURE_FUSION
- // use domain neutral code only for Load context, as the
- // required eager binding interferes with LoadFrom binding semantics
- if (!GetFile()->IsContextLoad() && !fIsShareableHostAssembly)
- return FALSE;
-#endif
-
- // Check app domain policy...
- if (this->GetAppDomain()->ApplySharePolicy(this))
- {
- if (IsSystem())
- return TRUE;
-
- // if not the default AD, ensure that the closure is filled in
- if (this->GetAppDomain() != SystemDomain::System()->DefaultDomain())
- GetAssemblyBindingClosure(LEVEL_COMPLETE);
-
-
- // Can be domain neutral only if we aren't binding any missing dependencies with
- // the assembly resolve event
- if ((this->GetAppDomain() != SystemDomain::System()->DefaultDomain()) &&
- (CheckMissingDependencies() == CMD_Resolved))
- {
- return FALSE;
- }
-
- // Ensure that all security conditions are met for code sharing
- if (!Security::CanShareAssembly(this))
- {
- return FALSE;
- }
-
- return TRUE;
- }
- return FALSE;
-
-#else // FEATURE_CORECLR
if (IsSystem())
return TRUE;
@@ -2620,7 +2077,6 @@ BOOL DomainAssembly::ShouldLoadDomainNeutralHelper()
return FALSE; // No meaning in doing costly closure walk for CoreCLR.
-#endif // FEATURE_CORECLR
#else // FEATURE_LOADER_OPTIMIZATION
return IsSystem();
@@ -2634,55 +2090,6 @@ BOOL DomainAssembly::ShouldSkipPolicyResolution()
}
-#if defined(FEATURE_LOADER_OPTIMIZATION) && defined(FEATURE_FUSION)
-//
-// Returns TRUE if the attempt to steal ownership of the native image succeeded, or if there are other
-// reasons for retrying load of the native image in the current appdomain.
-//
-// Returns FALSE if the native image should be rejected in the current appdomain.
-//
-static BOOL TryToStealSharedNativeImageOwnership(PEFile ** ppNativeImage, PEFile * pNativeFile, PEFile * pFile)
-{
- STANDARD_VM_CONTRACT;
-
- if (pNativeFile == PEFile::Dummy())
- {
- // Nothing to steal anymore. Loading of the native image failed elsewhere.
- return FALSE;
- }
-
- _ASSERTE(!pNativeFile->IsNativeImageUsedExclusively());
- _ASSERTE(!pFile->IsNativeImageUsedExclusively());
-
- SharedDomain * pSharedDomain = SharedDomain::GetDomain();
-
- // Take the lock so that nobody steals or creates Assembly object for this native image while we are stealing it
- SharedFileLockHolder pNativeFileLock(pSharedDomain, pNativeFile, TRUE);
-
- if (pNativeFile != VolatileLoad(ppNativeImage))
- {
- // The ownership changed before we got a chance. Retry.
- return TRUE;
- }
-
- SharedAssemblyLocator locator(pNativeFile->AsAssembly(), SharedAssemblyLocator::PEASSEMBLYEXACT);
- if (pSharedDomain->FindShareableAssembly(&locator))
- {
- // Another shared assembly (with different binding closure) uses this image, therefore we cannot use it
- return FALSE;
- }
-
- BOOL success = InterlockedCompareExchangeT(ppNativeImage, pFile, pNativeFile) == pNativeFile;
-
- // If others can reuse us, we cannot go away
- if (success)
- pFile->AddRef();
-
- STRESS_LOG3(LF_ZAP,LL_INFO100,"Attempt to steal ownership from native file %p by %p success %d\n", pNativeFile, pFile, success);
-
- return TRUE;
-}
-#endif // FEATURE_LOADER_OPTIMIZATION && FEATURE_FUSION
// This is where the decision whether an assembly is DomainNeutral (shared) nor not is made.
void DomainAssembly::Allocate()
@@ -2717,9 +2124,6 @@ void DomainAssembly::Allocate()
#ifdef FEATURE_LOADER_OPTIMIZATION
-#ifdef FEATURE_FUSION
-Retry:
-#endif
// Try to find an existing shared version of the assembly which
// is compatible with our domain.
@@ -2749,54 +2153,6 @@ Retry:
if (pAssembly == NULL)
{
-#ifdef FEATURE_FUSION
- // Final verification that we can use the ngen image.
- //
- // code:DomainAssembly::FindNativeImage checks the binding closures before declaring the native image as shareable candidate,
- // but the ultimate decisions about sharing happens inside code:Assembly::CanBeShared called from FindShareableAssembly above.
- // code:Assembly::CanBeShared checks more conditions than just binding closures. In particular, it also checks whether AssemblyResolve
- // event resolves any missing dependencies found in the binding closure - the assembly cannot be shared if it is the case.
- // The end result is that same ngen image can get here in multiple domains in parallel, but it may not be shareable between all of them.
- //
- // We reconcile this conflict by checking whether there is somebody else conflicting with us. If it is, we will try to steal
- // the ownership of the native image from the other guy and retry. The retry logic is required to prevent a perfectly valid
- // native image being dropped on the floor just because of multiple appdomains raced to load it.
- {
- ReleaseHolder<PEImage> pNativeImage = GetFile()->GetNativeImageWithRef();
- if ((pNativeImage != NULL) && (pNativeImage->GetLoadedLayout() != NULL))
- {
- Module * pNativeModule = pNativeImage->GetLoadedLayout()->GetPersistedModuleImage();
- if (pNativeModule != NULL)
- {
- // The owner of the native module was set thread-safe in code:DomainAssembly::FindNativeImage
- // However the final decision if we can share the native image is done in this function (see usage of code:FindShareableAssembly above)
- PEFile ** ppNativeFile = (PEFile **) (PBYTE(pNativeModule) + Module::GetFileOffset());
- PEFile * pNativeFile = VolatileLoad(ppNativeFile);
- if (pNativeFile != GetFile())
- {
- pFileLock.Release();
-
- // Ensures that multiple threads won't fight with each other indefinitely
- __SwitchToThread(0, ++dwSwitchCount);
-
- if (!TryToStealSharedNativeImageOwnership(ppNativeFile, pNativeFile, GetFile()))
- {
- // If a shared assembly got loaded in the mean time, retry all lookups again
- if (pSharedDomain->GetShareableAssemblyCount() != nInitialShareableAssemblyCount)
- goto Retry;
-
- m_dwReasonForRejectingNativeImage = ReasonForRejectingNativeImage_NiAlreadyUsedInAnotherSharedAssembly;
- STRESS_LOG3(LF_ZAP,LL_INFO100,"Rejecting native file %p, because it is already used by shared file %p - reason 0x%x\n",GetFile(),pNativeFile,m_dwReasonForRejectingNativeImage);
- GetFile()->ClearNativeImage();
- GetFile()->SetCannotUseNativeImage();
- }
-
- goto Retry;
- }
- }
- }
- }
-#endif // FEATURE_FUSION
// We can now rely on the fact that our MDImport will not change so we can stop refcounting it.
GetFile()->MakeMDImportPersistent();
@@ -2822,13 +2178,6 @@ Retry:
// This is because the resulting shared assembly that we will depend on
// DOES have those dependencies, but we won't be able to validly share that
// assembly unless we match all of ITS dependencies, too.
-#ifdef FEATURE_FUSION
- if ((this->GetAppDomain()->GetFusionContext() != NULL) && !IsSystem())
- {
- IAssemblyBindingClosure* pClosure = GetAssemblyBindingClosure(LEVEL_STARTING);
- pAssembly->SetBindingClosure(pClosure);
- }
-#endif // FEATURE_FUSION
// Sets the tenured bit atomically with the hash insert.
pSharedDomain->AddShareableAssembly(pAssembly);
}
@@ -2884,15 +2233,8 @@ Retry:
// Insert AssemblyDef details into AssemblySpecBindingCache if appropriate
-#ifdef FEATURE_FUSION
- fInsertIntoAssemblySpecBindingCache = GetFile()->GetLoadContext() == LOADCTX_TYPE_DEFAULT;
-#endif
-#if defined(FEATURE_APPX_BINDER)
- fInsertIntoAssemblySpecBindingCache = fInsertIntoAssemblySpecBindingCache && !GetFile()->HasHostAssembly();
-#else
fInsertIntoAssemblySpecBindingCache = fInsertIntoAssemblySpecBindingCache && GetFile()->CanUseWithBindingCache();
-#endif
if (fInsertIntoAssemblySpecBindingCache)
{
@@ -3006,138 +2348,6 @@ BOOL DomainAssembly::GetResource(LPCSTR szName, DWORD *cbResource,
this->m_pDomain );
}
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-BOOL DomainAssembly::GetModuleResource(mdFile mdResFile, LPCSTR szResName,
- DWORD *cbResource, PBYTE *pbInMemoryResource,
- LPCSTR *szFileName, DWORD *dwLocation,
- BOOL fIsPublic, StackCrawlMark *pStackMark,
- BOOL fSkipSecurityCheck)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- const char *szName;
- DWORD dwFlags;
- DomainFile *pModule = NULL;
- DWORD dwOffset = 0;
-
- if (! ((TypeFromToken(mdResFile) == mdtFile) &&
- GetMDImport()->IsValidToken(mdResFile)) )
- {
- ThrowHR(COR_E_BADIMAGEFORMAT, BFA_INVALID_FILE_TOKEN);
- }
-
- IfFailThrow(GetMDImport()->GetFileProps(
- mdResFile,
- &szName,
- NULL,
- NULL,
- &dwFlags));
-
- if (IsFfContainsMetaData(dwFlags))
- {
- // The resource is embedded in a manifest-containing file.
- mdManifestResource mdResource;
- mdToken mdLinkRef;
- DWORD dwResourceFlags;
-
- Module *pContainerModule = GetCurrentModule();
- // Use the real assembly with a rid map if possible
- if (pContainerModule != NULL)
- pModule = pContainerModule->LoadModule(m_pDomain, mdResFile, FALSE);
- else
- {
- PEModuleHolder pFile(GetAssembly()->LoadModule_AddRef(mdResFile, FALSE));
- pModule = m_pDomain->LoadDomainModule(this, pFile, FILE_LOADED);
- }
-
- if (FAILED(pModule->GetMDImport()->FindManifestResourceByName(szResName,
- &mdResource)))
- return FALSE;
-
- IfFailThrow(pModule->GetMDImport()->GetManifestResourceProps(
- mdResource,
- NULL, //&szName,
- &mdLinkRef,
- &dwOffset,
- &dwResourceFlags));
-
- if (mdLinkRef != mdFileNil)
- {
- ThrowHR(COR_E_BADIMAGEFORMAT, BFA_CANT_GET_LINKREF);
- }
- fIsPublic = IsMrPublic(dwResourceFlags);
- }
-
-#ifndef CROSSGEN_COMPILE
- if (!fIsPublic && pStackMark && !fSkipSecurityCheck)
- {
- Assembly *pCallersAssembly = SystemDomain::GetCallersAssembly(pStackMark);
- if (pCallersAssembly && // full trust for interop
- (!pCallersAssembly->GetManifestFile()->Equals(GetFile())))
- {
- RefSecContext sCtx(AccessCheckOptions::kMemberAccess);
-
- AccessCheckOptions accessCheckOptions(
- AccessCheckOptions::kMemberAccess, /*accessCheckType*/
- NULL, /*pAccessContext*/
- FALSE, /*throwIfTargetIsInaccessible*/
- (MethodTable *) NULL /*pTargetMT*/
- );
-
- // SL: return TRUE only if the caller is critical
- // Desktop: return TRUE only if demanding MemberAccess succeeds
- if (!accessCheckOptions.DemandMemberAccessOrFail(&sCtx, NULL, TRUE /*visibilityCheck*/))
- return FALSE;
- }
- }
-#endif // CROSSGEN_COMPILE
-
- if (IsFfContainsMetaData(dwFlags)) {
- if (dwLocation) {
- *dwLocation = *dwLocation | 1; // ResourceLocation.embedded
- *szFileName = szName;
- return TRUE;
- }
-
- pModule->GetFile()->GetEmbeddedResource(dwOffset, cbResource,
- pbInMemoryResource);
-
- return TRUE;
- }
-
- // The resource is linked (it's in its own file)
- if (szFileName) {
- *szFileName = szName;
- return TRUE;
- }
-
- Module *pContainerModule = GetCurrentModule();
-
- // Use the real assembly with a rid map if possible
- if (pContainerModule != NULL)
- pModule = pContainerModule->LoadModule(m_pDomain, mdResFile);
- else
- {
- PEModuleHolder pFile(GetAssembly()->LoadModule_AddRef(mdResFile, TRUE));
- pModule = m_pDomain->LoadDomainModule(this, pFile, FILE_LOADED);
- }
-
- COUNT_T size;
- const void *contents = pModule->GetFile()->GetManagedFileContents(&size);
-
- *pbInMemoryResource = (BYTE *) contents;
- *cbResource = size;
-
- return TRUE;
-}
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
#ifdef FEATURE_PREJIT
@@ -3155,52 +2365,7 @@ void GetTimeStampsForNativeImage(CORCOMPILE_VERSION_INFO * pNativeVersionInfo)
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
// Do not store runtime timestamps into NGen image for cross-platform NGen determinism
-#else
- // fill in pRuntimeDllInfo
- CORCOMPILE_RUNTIME_DLL_INFO *pRuntimeDllInfo = pNativeVersionInfo->runtimeDllInfo;
-
- for (DWORD index = 0; index < NUM_RUNTIME_DLLS; index++)
- {
-#ifdef CROSSGEN_COMPILE
- SString sFileName(SString::Utf8, CorCompileGetRuntimeDllName((CorCompileRuntimeDlls)index));
-
- PEImageHolder pImage;
- if (!GetAppDomain()->ToCompilationDomain()->FindImage(sFileName, MDInternalImport_NoCache, &pImage))
- {
- EEFileLoadException::Throw(sFileName, COR_E_FILENOTFOUND);
- }
-
- PEImageLayoutHolder pLayout(pImage->GetLayout(PEImageLayout::LAYOUT_FLAT,PEImage::LAYOUT_CREATEIFNEEDED));
- pRuntimeDllInfo[index].timeStamp = pLayout->GetTimeDateStamp();
- pRuntimeDllInfo[index].virtualSize = pLayout->GetVirtualSize();
-
-#else // CROSSGEN_COMPILE
-
- HMODULE hMod = CorCompileGetRuntimeDll((CorCompileRuntimeDlls)index);
-
- if (hMod == NULL)
- {
- _ASSERTE((CorCompileRuntimeDlls)index == NGEN_COMPILER_INFO);
-
- LPCWSTR wszDllName = CorCompileGetRuntimeDllName((CorCompileRuntimeDlls)index);
- if (FAILED(g_pCLRRuntime->LoadLibrary(wszDllName, &hMod)))
- {
- EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_EXECUTIONENGINE, W("Unable to load CLR DLL during ngen"));
- }
- }
-
- _ASSERTE(hMod != NULL);
-
- PEDecoder pe(hMod);
-
- pRuntimeDllInfo[index].timeStamp = pe.GetTimeDateStamp();
- pRuntimeDllInfo[index].virtualSize = pe.GetVirtualSize();
-#endif // CROSSGEN_COMPILE
-
- }
-#endif // FEATURE_CORECLR
}
//
@@ -3215,7 +2380,6 @@ void GetNGenCpuInfo(CORINFO_CPU * cpuInfo)
#ifdef _TARGET_X86_
-#ifdef FEATURE_CORECLR
static CORINFO_CPU ngenCpuInfo =
{
(CPU_X86_PENTIUM_PRO << 8), // dwCPUType
@@ -3225,26 +2389,6 @@ void GetNGenCpuInfo(CORINFO_CPU * cpuInfo)
// We always generate P3-compatible code on CoreCLR
*cpuInfo = ngenCpuInfo;
-#else // FEATURE_CORECLR
- static CORINFO_CPU ngenCpuInfo =
- {
- (CPU_X86_PENTIUM_4 << 8), // dwCPUType
- 0x00008001, // dwFeatures
- 0 // dwExtendedFeatures
- };
-
-#ifndef CROSSGEN_COMPILE
- GetSpecificCpuInfo(cpuInfo);
- if (!IsCompatibleCpuInfo(cpuInfo, &ngenCpuInfo))
- {
- // Use the actual cpuInfo if the platform is not compatible
- // with the "recommended" processor. We expect most platforms to be compatible
- return;
- }
-#endif
-
- *cpuInfo = ngenCpuInfo;
-#endif // FEATURE_CORECLR
#else // _TARGET_X86_
cpuInfo->dwCPUType = 0;
@@ -3274,14 +2418,11 @@ void DomainAssembly::GetCurrentVersionInfo(CORCOMPILE_VERSION_INFO *pNativeVersi
&fForceProfiling,
&fForceInstrument);
- OSVERSIONINFOW osInfo;
- osInfo.dwOSVersionInfoSize = sizeof(osInfo);
- if (!GetOSVersion(&osInfo))
- _ASSERTE(!"GetOSVersion failed");
-
- _ASSERTE(osInfo.dwMajorVersion < 999);
- _ASSERTE(osInfo.dwMinorVersion < 999);
- pNativeVersionInfo->wOSPlatformID = (WORD) osInfo.dwPlatformId;
+#ifndef FEATURE_PAL
+ pNativeVersionInfo->wOSPlatformID = VER_PLATFORM_WIN32_NT;
+#else
+ pNativeVersionInfo->wOSPlatformID = VER_PLATFORM_UNIX;
+#endif
// The native images should be OS-version agnostic. Do not store the actual OS version for determinism.
// pNativeVersionInfo->wOSMajorVersion = (WORD) osInfo.dwMajorVersion;
@@ -3373,12 +2514,6 @@ void DomainAssembly::GetCurrentVersionInfo(CORCOMPILE_VERSION_INFO *pNativeVersi
pNativeVersionInfo->wConfigFlags |= CORCOMPILE_CONFIG_INSTRUMENTATION_NONE;
}
-#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR)
- if (UseRyuJit())
- {
- pNativeVersionInfo->wCodegenFlags |= CORCOMPILE_CODEGEN_USE_RYUJIT;
- }
-#endif
GetTimeStampsForNativeImage(pNativeVersionInfo);
@@ -3449,7 +2584,6 @@ BOOL DomainAssembly::CheckZapDependencyIdentities(PEImage *pNativeImage)
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
AssemblySpec spec;
spec.InitializeSpec(this->GetFile());
@@ -3479,7 +2613,6 @@ BOOL DomainAssembly::CheckZapDependencyIdentities(PEImage *pNativeImage)
AssemblySpec name;
name.InitializeSpec(pDependencies->dwAssemblyDef, pNativeImage->GetNativeMDImport(), this);
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
if (!name.IsAssemblySpecForMscorlib())
{
// We just initialized the assembly spec for the NI dependency. This will not have binding context
@@ -3489,14 +2622,12 @@ BOOL DomainAssembly::CheckZapDependencyIdentities(PEImage *pNativeImage)
_ASSERTE(pParentAssemblyBindingContext);
name.SetBindingContext(pParentAssemblyBindingContext);
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
GetAppDomain()->CheckForMismatchedNativeImages(&name, &pDependencies->signAssemblyDef.mvid);
}
pDependencies++;
}
-#endif
return TRUE;
}
@@ -3510,250 +2641,12 @@ BOOL DomainAssembly::CheckZapSecurity(PEImage *pNativeImage)
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
return TRUE;
-#else
-
- //
- // System libraries are a special case, the security info's always OK.
- //
-
- if (IsSystem())
- return TRUE;
-
-#ifdef FEATURE_NATIVE_IMAGE_GENERATION
- //
- // If we're just loading files as part of PDB generation, we're not executing code,
- // so no need to do security checks
- //
-
- if (IsNgenPDBCompilationProcess())
- return TRUE;
-#endif
-
- ETWOnStartup (SecurityCatchCall_V1, SecurityCatchCallEnd_V1);
-
-#ifdef CROSSGEN_COMPILE
- return TRUE;
-#else
-
-#ifdef FEATURE_APTCA
- if (!Security::NativeImageHasValidAptcaDependencies(pNativeImage, this))
- {
- return FALSE;
- }
-#endif // !FEATURE_APTCA
-
- GCX_COOP();
-
- BOOL fHostProtectionOK = FALSE;
- BOOL fImageAndDependenciesAreFullTrust = FALSE;
-
- EX_TRY
- {
- // Check the HostProtection settings.
- EApiCategories eRequestedProtectedCategories = GetHostProtectionManager()->GetProtectedCategories();
- if (eRequestedProtectedCategories == eNoChecks)
- fHostProtectionOK = TRUE;
-
- // Due to native code generated for one IL image being more agressively put into another
- // assembly's native image, we're disabling partial trust NGEN images. If the current
- // domain can only have fully trusted assemblies, then we can load this image, or if the current
- // assembly and its closure are all in the GAC we can also use it. Otherwise, we'll conservatively
- // disable the use of this image.
- IApplicationSecurityDescriptor *pAppDomainSecurity = this->GetAppDomain()->GetSecurityDescriptor();
- if (pAppDomainSecurity->IsFullyTrusted() && pAppDomainSecurity->IsHomogeneous())
- {
- // A fully trusted homogenous domain can only have full trust assemblies, therefore this assembly
- // and all its dependencies must be full trust
- fImageAndDependenciesAreFullTrust = TRUE;
- }
- else if (IsClosedInGAC())
- {
- // The domain allows partial trust assemblies to be loaded into it. However, this assembly and
- // all of its dependencies came from the GAC, so we know that they must all be trusted even if
- // other code in this domain is not.
- fImageAndDependenciesAreFullTrust = TRUE;
- }
- else
- {
- // The domain allows partial trust assemblies and we cannot prove that the closure of
- // dependencies of this assembly will all be fully trusted. Conservatively throw away this NGEN
- // image.
- fImageAndDependenciesAreFullTrust = FALSE;
- }
- }
- EX_CATCH
- {
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- return fHostProtectionOK && fImageAndDependenciesAreFullTrust;
-#endif // CROSSGEN_COMPILE
-
-#endif // FEATURE_CORECLR
}
#endif // FEATURE_PREJIT
-#ifdef FEATURE_CAS_POLICY
-void DomainAssembly::InitializeSecurityManager()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_NOTRIGGER;
- MODE_PREEMPTIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- GetFile()->InitializeSecurityManager();
-}
-#endif // FEATURE_CAS_POLICY
-
-#ifdef FEATURE_CAS_POLICY
-// Returns security information for the assembly based on the codebase
-void DomainAssembly::GetSecurityIdentity(SString &codebase,
- SecZone *pdwZone,
- DWORD dwFlags,
- BYTE *pbUniqueID,
- DWORD *pcbUniqueID)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pdwZone));
- PRECONDITION(CheckPointer(pbUniqueID));
- PRECONDITION(CheckPointer(pcbUniqueID));
- }
- CONTRACTL_END;
-
- GetFile()->GetSecurityIdentity(codebase, pdwZone, dwFlags, pbUniqueID, pcbUniqueID);
-}
-#endif // FEATURE_CAS_POLICY
-#ifdef FEATURE_FUSION
-IAssemblyBindingClosure* DomainAssembly::GetAssemblyBindingClosure(WALK_LEVEL level)
-{
- CONTRACT(IAssemblyBindingClosure *)
- {
- INSTANCE_CHECK;
- POSTCONDITION(CheckPointer(RETVAL,NULL_OK));
- //we could return NULL instead of asserting but hitting code paths that call this for mscorlib is just wasting of cycles anyhow
- PRECONDITION(!IsSystem());
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
- if (m_pAssemblyBindingClosure == NULL || m_pAssemblyBindingClosure->HasBeenWalked(level) == S_FALSE)
- {
- SafeComHolder<IAssemblyBindingClosure> pClosure;
- if (this->GetAppDomain()->GetFusionContext() == NULL)
- {
- _ASSERTE(IsSystem());
- RETURN NULL;
- }
-
- GCX_PREEMP();
-
- ReleaseHolder<IBindResult> pWinRTBindResult;
- IUnknown * pUnk;
-
- if (GetFile()->IsIStream())
- {
- pUnk = GetFile()->GetIHostAssembly();
- }
- else if (GetFile()->IsWindowsRuntime())
- { // It is .winmd file (WinRT assembly)
- IfFailThrow(CLRPrivAssemblyWinRT::GetIBindResult(GetFile()->GetHostAssembly(), &pWinRTBindResult));
- pUnk = pWinRTBindResult;
- }
- else
- {
- pUnk = GetFile()->GetFusionAssembly();
- }
-
- if (m_pAssemblyBindingClosure == NULL)
- {
- IfFailThrow(this->GetAppDomain()->GetFusionContext()->GetAssemblyBindingClosure(pUnk, NULL, &pClosure));
- if (FastInterlockCompareExchangePointer<IAssemblyBindingClosure*>(&m_pAssemblyBindingClosure, pClosure.GetValue(), NULL) == NULL)
- {
- pClosure.SuppressRelease();
- }
- }
- IfFailThrow(m_pAssemblyBindingClosure->EnsureWalked(pUnk, this->GetAppDomain()->GetFusionContext(), level));
- }
- RETURN m_pAssemblyBindingClosure;
-}
-
-// This is used to determine if the binding closure of the assembly in question is in the GAC. Amongst other uses,
-// this is the MULTI_DOMAIN_HOST scenario.
-BOOL DomainAssembly::IsClosedInGAC()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- if (IsSystem())
- return TRUE;
-
- BOOL fIsWindowsRuntime = GetFile()->IsWindowsRuntime();
-
- if (!GetFile()->IsSourceGAC() && !fIsWindowsRuntime)
- return FALSE;
-
- // Do a binding closure that will help us determine if all the dependencies are in the GAC or not.
- IAssemblyBindingClosure * pClosure = GetAssemblyBindingClosure(LEVEL_GACCHECK);
- if (pClosure == NULL)
- return FALSE;
-
- // Once the closure is complete, determine if the dependencies are closed in the GAC (or not).
- HRESULT hr = pClosure->IsAllAssembliesInGAC();
- IfFailThrow(hr);
-
- return (hr == S_OK);
-}
-
-BOOL DomainAssembly::MayHaveUnknownDependencies()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- if (IsSystem())
- return FALSE;
-
- // Perform the binding closure walk to initialize state that will help us
- // determine if we have dependencies that could prevent code-sharing.
- IAssemblyBindingClosure * pClosure = GetAssemblyBindingClosure(LEVEL_WINRTCHECK);
- if (pClosure == NULL)
- return FALSE;
-
- HRESULT hr = pClosure->MayHaveUnknownDependencies();
- IfFailThrow(hr);
-
- return (hr == S_OK);
-}
-
-#endif // FEATURE_FUSION
// <TODO>@todo Find a better place for these</TODO>
@@ -4166,220 +3059,6 @@ void DomainAssembly::EnumStaticGCRefs(promote_func* fn, ScanContext* sc)
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-//--------------------------------------------------------------------------------
-// DomainModule
-//--------------------------------------------------------------------------------
-
-DomainModule::DomainModule(AppDomain *pDomain, DomainAssembly *pAssembly, PEFile *pFile)
- : DomainFile(pDomain, pFile),
- m_pDomainAssembly(pAssembly)
-{
- STANDARD_VM_CONTRACT;
-}
-
-DomainModule::~DomainModule()
-{
- WRAPPER_NO_CONTRACT;
-}
-
-void DomainModule::SetModule(Module* pModule)
-{
- STANDARD_VM_CONTRACT;
-
- UpdatePEFile(pModule->GetFile());
- pModule->SetDomainFile(this);
- // SetDomainFile can throw and will unwind to DomainModule::Allocate at which
- // point pModule->Destruct will be called in the catch handler. if we set
- // m_pModule = pModule before the call to SetDomainFile then we can end up with
- // a bad m_pModule pointer when SetDomainFile throws. so we set m_pModule IIF
- // the call to SetDomainFile succeeds.
- m_pModule = pModule;
-}
-
-void DomainModule::Begin()
-{
- STANDARD_VM_CONTRACT;
- m_pDomainAssembly->AddModule(this);
-}
-
-#ifdef FEATURE_PREJIT
-
-void DomainModule::FindNativeImage()
-{
- LIMITED_METHOD_CONTRACT;
-
- // Resource files are never prejitted.
-}
-
-#endif // FEATURE_PREJIT
-
-
-void DomainModule::Allocate()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- STANDARD_VM_CHECK;
- }
- CONTRACTL_END;
-
- // We can now rely on the fact that our MDImport will not change so we can stop refcounting it.
- GetFile()->MakeMDImportPersistent();
-
- AllocMemTracker amTracker;
- AllocMemTracker *pamTracker = &amTracker;
-
- Assembly *pAssembly = m_pDomainAssembly->GetCurrentAssembly();
- Module *pModule = NULL;
-
- if (pAssembly->IsDomainNeutral())
- {
- // For shared assemblies, the module may be already in the assembly list, even
- // though we haven't loaded it here yet.
-
- pModule = pAssembly->GetManifestModule()->GetModuleIfLoaded(GetToken(),FALSE, TRUE);
- if (pModule != NULL)
- {
- SetModule(pModule);
- return;
- }
- else
- {
-#ifdef FEATURE_LOADER_OPTIMIZATION
- SharedDomain *pSharedDomain = SharedDomain::GetDomain();
- SharedFileLockHolder pFileLock(pSharedDomain, GetFile());
-#else // FEATURE_LOADER_OPTIMIZATION
- _ASSERTE(IsSystem());
-#endif // FEATURE_LOADER_OPTIMIZATION
-
- pModule = pAssembly->GetManifestModule()->GetModuleIfLoaded(GetToken(), FALSE, TRUE);
- if (pModule != NULL)
- {
- SetModule(pModule);
- return;
- }
- else
- {
- pModule = Module::Create(pAssembly, GetToken(), m_pFile, pamTracker);
-
- EX_TRY
- {
- pAssembly->PrepareModuleForAssembly(pModule, pamTracker);
- SetModule(pModule); //@todo: This innocent-looking call looks like a mixture of allocations and publishing code - it probably needs to be split.
- }
- EX_HOOK
- {
- //! It's critical we destruct the manifest Module prior to the AllocMemTracker used to initialize it.
- //! Otherwise, we will leave dangling pointers inside the Module that Module::Destruct will attempt
- //! to dereference.
- pModule->Destruct();
- }
- EX_END_HOOK
-
- {
- CANNOTTHROWCOMPLUSEXCEPTION();
- FAULT_FORBID();
-
- //Cannot fail after this point.
- pamTracker->SuppressRelease();
- pModule->SetIsTenured();
-
- pAssembly->PublishModuleIntoAssembly(pModule);
-
-
-
- return; // Explicit return to let you know you are NOT welcome to add code after the CANNOTTHROW/FAULT_FORBID expires
- }
-
-
-
- }
- }
-
- }
- else
- {
- pModule = Module::Create(pAssembly, GetToken(), m_pFile, pamTracker);
- EX_TRY
- {
- pAssembly->PrepareModuleForAssembly(pModule, pamTracker);
- SetModule(pModule); //@todo: This innocent-looking call looks like a mixture of allocations and publishing code - it probably needs to be split.
- }
- EX_HOOK
- {
- //! It's critical we destruct the manifest Module prior to the AllocMemTracker used to initialize it.
- //! Otherwise, we will leave dangling pointers inside the Module that Module::Destruct will attempt
- //! to dereference.
- pModule->Destruct();
- }
- EX_END_HOOK
-
-
- {
- CANNOTTHROWCOMPLUSEXCEPTION();
- FAULT_FORBID();
-
- //Cannot fail after this point.
- pamTracker->SuppressRelease();
- pModule->SetIsTenured();
- pAssembly->PublishModuleIntoAssembly(pModule);
-
-
- return; // Explicit return to let you know you are NOT welcome to add code after the CANNOTTHROW/FAULT_FORBID expires
- }
-
- }
-
-
-}
-
-
-
-void DomainModule::DeliverAsyncEvents()
-{
- LIMITED_METHOD_CONTRACT;
- return;
-}
-
-void DomainModule::DeliverSyncEvents()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- SO_INTOLERANT;
- }
- CONTRACTL_END;
-
- GetCurrentModule()->NotifyEtwLoadFinished(S_OK);
-
-#ifdef PROFILING_SUPPORTED
- if (!IsProfilerNotified())
- {
- SetProfilerNotified();
- GetCurrentModule()->NotifyProfilerLoadFinished(S_OK);
- }
-#endif
-
-#ifdef DEBUGGING_SUPPORTED
- GCX_COOP();
- if(!IsDebuggerNotified())
- {
- SetShouldNotifyDebugger();
- {
- // Always give the module a chance to notify the debugger. If no debugger is attached, the
- // module can skip out on the notification.
- m_pModule->NotifyDebuggerLoad(m_pDomain, this, ATTACH_MODULE_LOAD, FALSE);
- SetDebuggerNotified();
- }
- }
-#endif
-}
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
#endif // #ifndef DACCESS_COMPILE
@@ -4430,44 +3109,6 @@ DomainAssembly::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
}
}
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-void
-DomainModule::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
-{
- SUPPORTS_DAC;
- DomainFile::EnumMemoryRegions(flags);
- if (m_pDomainAssembly.IsValid())
- {
- m_pDomainAssembly->EnumMemoryRegions(flags);
- }
-}
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
#endif // #ifdef DACCESS_COMPILE
-#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE)
-LPVOID DomainFile::GetUMThunk(LPVOID pManagedIp, PCCOR_SIGNATURE pSig, ULONG cSig)
-{
- CONTRACT (LPVOID)
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END
-
-
- if (m_pUMThunkHash == NULL)
- {
- UMThunkHash *pUMThunkHash = new UMThunkHash(GetModule(), this->GetAppDomain());
- if (FastInterlockCompareExchangePointer(&m_pUMThunkHash, pUMThunkHash, NULL) != NULL)
- {
- delete pUMThunkHash;
- }
- }
- RETURN m_pUMThunkHash->GetUMThunk(pManagedIp, pSig, cSig);
-}
-#endif // FEATURE_MIXEDMODE && !CROSSGEN_COMPILE
diff --git a/src/vm/domainfile.h b/src/vm/domainfile.h
index 55a0907a0b..a0ebbca481 100644
--- a/src/vm/domainfile.h
+++ b/src/vm/domainfile.h
@@ -143,9 +143,6 @@ class DomainFile
}
#endif
-#ifdef FEATURE_MIXEDMODE
- LPVOID GetUMThunk(LPVOID pManagedIp, PCCOR_SIGNATURE pSig, ULONG cSig);
-#endif
void ReleaseFiles() DAC_EMPTY();
@@ -521,11 +518,6 @@ public:
return PTR_PEAssembly(m_pFile);
}
-#ifdef FEATURE_FUSION
- IAssemblyBindingClosure* GetAssemblyBindingClosure(WALK_LEVEL level);
- BOOL IsClosedInGAC();
- BOOL MayHaveUnknownDependencies();
-#endif
// Returns security information for the assembly based on the codebase
void GetSecurityIdentity(SString &codebase, SecZone *pdwZone, DWORD dwFlags, BYTE *pbUniqueID, DWORD *pcbUniqueID);
@@ -537,33 +529,12 @@ public:
}
#ifdef FEATURE_LOADER_OPTIMIZATION
-#ifdef FEATURE_FUSION
-private:
- enum CMDI_Result
- {
- CMDI_End,
- CMDI_AssemblyResolveSucceeded,
- CMDI_AssemblyResolveFailed
- };
-
- CMDI_Result CheckMissingDependencyInner(IAssemblyBindingClosure* pClosure, DWORD idx);
-
-
-#endif
public:
CMD_State CheckMissingDependencies();
BOOL MissingDependenciesCheckDone();
#endif // FEATURE_LOADER_OPTIMIZATION
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- DomainFile *FindModule(PEFile *pFile, BOOL includeLoading = FALSE);
- DomainModule *FindModule(PEModule *pFile, BOOL includeLoading = FALSE)
- {
- WRAPPER_NO_CONTRACT;
- return (DomainModule *) FindModule((PEFile *) pFile, includeLoading);
- }
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
void ReleaseFiles();
#endif // DACCESS_COMPILE
@@ -694,9 +665,6 @@ public:
return pModule->GetModule();
}
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- void AddModule(DomainModule *pModule);
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
// ------------------------------------------------------------
// Resource access
@@ -708,13 +676,6 @@ public:
StackCrawlMark *pStackMark, BOOL fSkipSecurityCheck,
BOOL fSkipRaiseResolveEvent);
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- BOOL GetModuleResource(mdFile mdResFile, LPCSTR szResName,
- DWORD *cbResource, PBYTE *pbInMemoryResource,
- LPCSTR *szFileName, DWORD *dwLocation,
- BOOL fIsPublic, StackCrawlMark *pStackMark,
- BOOL fSkipSecurityCheck);
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
#ifdef FEATURE_PREJIT
// ------------------------------------------------------------
// Prejitting API
@@ -810,11 +771,6 @@ private:
ULONG HashIdentity();
private:
-#ifdef FEATURE_CAS_POLICY
- // Pulls in URLMON's security manager. It is used to translate a codebase
- // into a zone and site
- void InitializeSecurityManager();
-#endif // FEATURE_CAS_POLICY
BOOL ShouldLoadDomainNeutral();
BOOL ShouldLoadDomainNeutralHelper();
@@ -829,9 +785,6 @@ private:
PTR_IAssemblySecurityDescriptor m_pSecurityDescriptor;
PTR_Assembly m_pAssembly;
DebuggerAssemblyControlFlags m_debuggerFlags;
-#ifdef FEATURE_FUSION
- ReleaseHolder<IAssemblyBindingClosure> m_pAssemblyBindingClosure;
-#endif
CMD_State m_MissingDependenciesCheckStatus;
ArrayList m_Modules;
BOOL m_fSkipPolicyResolution;
@@ -852,95 +805,4 @@ typedef DomainAssembly::ModuleIterator DomainModuleIterator;
// --------------------------------------------------------------------------------
// DomainModule is a subclass of DomainFile which specifically represents a module.
// --------------------------------------------------------------------------------
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-
-class DomainModule : public DomainFile
-{
- VPTR_VTABLE_CLASS(DomainModule, DomainFile);
-
- private:
- PTR_DomainAssembly m_pDomainAssembly;
-
- void UpdatePEFile(PTR_PEFile pFile);
-
- public:
-
- // ------------------------------------------------------------
- // Public API
- // ------------------------------------------------------------
-
- DomainAssembly *GetDomainAssembly()
- {
- LIMITED_METHOD_CONTRACT;
- SUPPORTS_DAC;
- return m_pDomainAssembly;
- }
-
- Module *GetModule()
- {
- LIMITED_METHOD_CONTRACT;
-
- return m_pModule;
- }
-
- LPCSTR GetName()
- {
- WRAPPER_NO_CONTRACT;
- return GetFile()->GetSimpleName();
- }
-
- mdFile GetToken()
- {
- WRAPPER_NO_CONTRACT;
- return GetFile()->GetToken();
- }
-
- PEModule *GetFile()
- {
- WRAPPER_NO_CONTRACT;
- return PTR_PEModule(m_pFile);
- }
-
- BOOL IsAssembly()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return FALSE;
- }
-
- void SetModule(Module *pModule);
-
-#ifdef DACCESS_COMPILE
- virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
-#endif
-
- // ------------------------------------------------------------
- // Loader API
- // ------------------------------------------------------------
-
- friend class COMModule;
-
-#ifndef DACCESS_COMPILE
- DomainModule(AppDomain *pDomain, DomainAssembly *pAssembly, PEFile *pFile);
- ~DomainModule();
-#endif
-
- // ------------------------------------------------------------
- // Internal routines
- // ------------------------------------------------------------
-
-#ifndef DACCESS_COMPILE
- void Begin();
- void Allocate();
- void LoadSharers();
- void DeliverSyncEvents();
- void DeliverAsyncEvents();
-#endif
-
-#ifdef FEATURE_PREJIT
-#ifndef DACCESS_COMPILE
- void FindNativeImage();
-#endif
-#endif // FEATURE_PREJIT
-};
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
#endif // _DOMAINFILE_H_
diff --git a/src/vm/domainfile.inl b/src/vm/domainfile.inl
index 18ff564939..e82ee3ed70 100644
--- a/src/vm/domainfile.inl
+++ b/src/vm/domainfile.inl
@@ -108,14 +108,6 @@ inline void DomainAssembly::UpdatePEFile(PTR_PEFile pFile)
GetAppDomain()->UpdatePublishHostedAssembly(this, pFile);
}
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-inline void DomainModule::UpdatePEFile(PTR_PEFile pFile)
-{
- LIMITED_METHOD_CONTRACT;
-
- this->UpdatePEFileWorker(pFile);
-}
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
#endif // DACCESS_COMPILE
inline ULONG DomainAssembly::HashIdentity()
diff --git a/src/vm/dwbucketmanager.hpp b/src/vm/dwbucketmanager.hpp
index a3aef9b2a8..2e37e1be5e 100644
--- a/src/vm/dwbucketmanager.hpp
+++ b/src/vm/dwbucketmanager.hpp
@@ -887,27 +887,7 @@ void BaseBucketParamsManager::GetPackageMoniker(__out_ecount(maxLength) WCHAR* t
}
CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- bool success = false;
- EX_TRY
- {
- wcsncpy_s(targetParam, maxLength, AppX::GetHeadPackageMoniker(), _TRUNCATE);
- success = true;
- }
- EX_CATCH
- {
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- if (!success)
- {
- // should this ever legitimately fail??
- _ASSERTE(!"failed to get package moniker for watson");
- wcsncpy_s(targetParam, maxLength, W("missing"), _TRUNCATE);
- }
-#else
_ASSERTE(!"AppX support NYI for CoreCLR");
-#endif // FEATURE_CORECLR
}
void BaseBucketParamsManager::GetPRAID(__out_ecount(maxLength) WCHAR* targetParam, int maxLength)
@@ -920,25 +900,7 @@ void BaseBucketParamsManager::GetPRAID(__out_ecount(maxLength) WCHAR* targetPara
}
CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- LPCWSTR pPraid = NULL;
- if (SUCCEEDED(AppX::GetApplicationId(pPraid)))
- {
- _snwprintf_s(targetParam,
- maxLength,
- _TRUNCATE,
- W("praid:%s"),
- pPraid);
- }
- else
- {
- // should this ever legitimately fail??
- _ASSERTE(!"failed to get PRAID for watson");
- wcsncpy_s(targetParam, maxLength, W("missing"), _TRUNCATE);
- }
-#else
_ASSERTE(!"PRAID support NYI for CoreCLR");
-#endif
}
void BaseBucketParamsManager::GetIlRva(__out_ecount(maxLength) WCHAR* targetParam, int maxLength)
@@ -1475,11 +1437,6 @@ WatsonBucketType GetWatsonBucketType()
}
CONTRACTL_END;
-#if defined(FEATURE_APPX) && !defined(FEATURE_CORECLR)
- if (AppX::IsAppXProcess() && !AppX::IsAppXNGen())
- return MoCrash;
- else
-#endif // FEATURE_APPX
#ifdef FEATURE_WINDOWSPHONE
return WinPhoneCrash;
diff --git a/src/vm/dwreport.cpp b/src/vm/dwreport.cpp
index 5ae4f84de2..b95c59ff8d 100644
--- a/src/vm/dwreport.cpp
+++ b/src/vm/dwreport.cpp
@@ -29,10 +29,6 @@
#include "imagehlp.h"
-#ifdef FEATURE_UEF_CHAINMANAGER
-// This is required to register our UEF callback with the UEF chain manager
-#include <mscoruefwrapper.h>
-#endif // FEATURE_UEF_CHAINMANAGER
EFaultRepRetVal DoReportFault(EXCEPTION_POINTERS * pExceptionInfo);
@@ -42,9 +38,7 @@ static BOOL g_watsonErrorReportingEnabled = FALSE;
// Variables to control launching Watson only once, but making all threads wait for that single launch to finish.
LONG g_watsonAlreadyLaunched = 0; // Used to note that another thread has done Watson.
-#if !defined(FEATURE_UEF_CHAINMANAGER)
HandleHolder g_hWatsonCompletionEvent = NULL; // Used to signal that Watson has finished.
-#endif // FEATURE_UEF_CHAINMANAGER
const WCHAR kErrorReportingPoliciesKey[] = W("SOFTWARE\\Policies\\Microsoft\\PCHealth\\ErrorReporting");
const WCHAR kErrorReportingKey[] = W("SOFTWARE\\Microsoft\\PCHealth\\ErrorReporting");
@@ -177,14 +171,10 @@ BOOL InitializeWatson(COINITIEE fFlags)
return TRUE;
}
-#if defined(FEATURE_UEF_CHAINMANAGER)
- return TRUE;
-#else
// Create the event that all-but-the-first threads will wait on (the first thread
// will set the event when Watson is done.)
g_hWatsonCompletionEvent = WszCreateEvent(NULL, TRUE /*manual reset*/, FALSE /*initial state*/, NULL);
return (g_hWatsonCompletionEvent != NULL);
-#endif // FEATURE_UEF_CHAINMANAGER
} // BOOL InitializeWatson()
@@ -337,7 +327,6 @@ DWORD ClrWaitForSingleObject(HANDLE handle, DWORD timeout)
CONTRACT_VIOLATION(ThrowsViolation);
- LeaveRuntimeHolder holder(reinterpret_cast< size_t >(WaitForSingleObject));
return WaitForSingleObject(handle, timeout);
} // DWORD ClrWaitForSingleObject()
@@ -1496,19 +1485,6 @@ BOOL RunWatson(
{
- #if !defined(FEATURE_CORECLR)
- // Use the version of DW20.exe that lives in the system directory.
- DWORD ret;
-
- if (FAILED(GetCORSystemDirectoryInternaL(watsonAppName)))
- {
- hr = E_FAIL;
- break;
- }
- watsonCommandLine.Set(watsonAppName);
- watsonCommandLine.Append(kWatsonImageNameOnVista);
-
- #else // FEATURE_CORECLR
HKEYHolder hKey;
// Look for key \\HKLM\Software\Microsoft\PCHealth\ErrorReporting\DW\Installed"
DWORD ret = WszRegOpenKeyEx(HKEY_LOCAL_MACHINE,
@@ -1529,7 +1505,6 @@ BOOL RunWatson(
ClrRegReadString(hKey, kWatsonValue, watsonAppName);
- #endif // ! FEATURE_CORECLR
COUNT_T len = watsonCommandLine.GetCount();
WCHAR* buffer = watsonCommandLine.OpenUnicodeBuffer(len);
@@ -1612,7 +1587,6 @@ BOOL RunWatson(
continue;
}
- Thread::BeginThreadAffinity();
// we timed-out waiting for DW to respond.
DWORD dw = WaitForSingleObject(hMutex, DW_TIMEOUT_VALUE);
@@ -1653,7 +1627,6 @@ BOOL RunWatson(
ReleaseMutex(hMutex);
}
- Thread::EndThreadAffinity();
}
// Go ahead and bail if Watson didn't exit for some reason.
@@ -1907,14 +1880,6 @@ HRESULT GetManagedBucketParametersForIp(
}
WatsonBucketType bucketType = GetWatsonBucketType();
-#ifndef FEATURE_CORECLR
- if (bucketType == MoCrash)
- {
- MoCrashBucketParamsManager moCrashManager(pGenericModeBlock, tore, currentPC, pThread, pThrowable);
- moCrashManager.PopulateBucketParameters();
- }
- else
-#endif // !FEATURE_CORECLR
{
#ifdef FEATURE_WINDOWSPHONE
_ASSERTE(bucketType == WinPhoneCrash);
@@ -2053,11 +2018,9 @@ HRESULT RetrieveManagedBucketParameters(
#if defined(PRESERVE_WATSON_ACROSS_CONTEXTS)
GenericModeBlock *pBuckets = NULL;
-#ifdef FEATURE_CORECLR
// On CoreCLR, Watson may not be enabled. Thus, we should
// skip this.
if (IsWatsonEnabled())
-#endif // FEATURE_CORECLR
{
if (pThread != NULL)
{
@@ -2243,7 +2206,6 @@ FaultReportResult DoFaultReportWorker( // Was Watson attempted, successful?
return FaultReportResultQuit;
}
-#if !defined(FEATURE_UEF_CHAINMANAGER)
// If we've already tried to report a Watson crash once, we don't really
// want to pester the user about this exception. This can occur in certain
// pathological programs.
@@ -2259,7 +2221,6 @@ FaultReportResult DoFaultReportWorker( // Was Watson attempted, successful?
return FaultReportResultQuit;
}
}
-#endif // FEATURE_UEF_CHAINMANAGER
// Assume an unmanaged fault until we determine otherwise.
BOOL bIsManagedFault = FALSE;
@@ -2507,7 +2468,7 @@ FaultReportResult DoFaultReportWorker( // Was Watson attempted, successful?
{ // Look for final '\'
pName = wcsrchr(buf, W('\\'));
// If found, skip it; if not, point to full name.
- pName = pName ? pName+1 : buf;
+ pName = pName ? pName+1 : (LPCWSTR)buf;
}
}
@@ -3094,7 +3055,6 @@ FaultReportResult DoFaultReport( // Was Watson attempted, successful?
Thread *pThread = GetThread();
-#ifdef FEATURE_CORECLR
// If watson isn't available (eg. in Silverlight), then use a simple dialog box instead
if (!IsWatsonEnabled())
{
@@ -3133,53 +3093,7 @@ FaultReportResult DoFaultReport( // Was Watson attempted, successful?
return fri.m_faultReportResult;
}
-#endif // FEATURE_CORECLR
-#ifdef FEATURE_UEF_CHAINMANAGER
- if (g_pUEFManager && !tore.IsUserBreakpoint())
- {
- IWatsonSxSManager * pWatsonSxSManager = g_pUEFManager->GetWastonSxSManagerInstance();
-
- // Has Watson report been triggered?
- if (pWatsonSxSManager->HasWatsonBeenTriggered())
- {
- LOG((LF_EH, LL_INFO100, "DoFaultReport: Watson has been triggered."));
- LeaveRuntimeHolderNoThrow holder(reinterpret_cast< size_t >(WaitForSingleObject));
- pWatsonSxSManager->WaitForWatsonSxSCompletionEvent();
- return FaultReportResultQuit;
- }
- // The unhandled exception is thrown by the current runtime.
- else if (IsExceptionFromManagedCode(pExceptionInfo->ExceptionRecord))
- {
- // Is the current runtime allowed to report Watson?
- if (!pWatsonSxSManager->IsCurrentRuntimeAllowedToReportWatson())
- {
- LOG((LF_EH, LL_INFO100, "DoFaultReport: Watson is reported by another runtime."));
- LeaveRuntimeHolderNoThrow holder(reinterpret_cast< size_t >(WaitForSingleObject));
- pWatsonSxSManager->WaitForWatsonSxSCompletionEvent();
- return FaultReportResultQuit;
- }
- }
- // The unhandled exception is thrown by another runtime in the process.
- else if (pWatsonSxSManager->IsExceptionClaimed(pExceptionInfo->ExceptionRecord))
- {
- LOG((LF_EH, LL_INFO100, "DoFaultReport: Watson will be reported by another runtime.\n"));
- return FaultReportResultQuit;
- }
- // The unhandled exception is thrown by native code.
- else
- {
- // Is the current runtime allowed to report Watson?
- if (!pWatsonSxSManager->IsCurrentRuntimeAllowedToReportWatson())
- {
- LOG((LF_EH, LL_INFO100, "DoFaultReport: Watson is reported by another runtime."));
- LeaveRuntimeHolderNoThrow holder(reinterpret_cast< size_t >(WaitForSingleObject));
- pWatsonSxSManager->WaitForWatsonSxSCompletionEvent();
- return FaultReportResultQuit;
- }
- }
- }
-#endif // FEATURE_UEF_CHAINMANAGER
// Check if the current thread has the permission to open a process handle of the current process.
// If not, the current thread may have been impersonated, we have to launch Watson from a new thread as in SO case.
diff --git a/src/vm/dwreport.h b/src/vm/dwreport.h
index 44306689ea..77ed0fd35a 100644
--- a/src/vm/dwreport.h
+++ b/src/vm/dwreport.h
@@ -81,9 +81,7 @@ void ResetWatsonBucketsFavorWorker(void * pParam);
extern LONG g_watsonAlreadyLaunched;
-#if !defined(FEATURE_UEF_CHAINMANAGER)
extern HandleHolder g_hWatsonCompletionEvent;
-#endif // FEATURE_UEF_CHAINMANAGER
//----------------------------------------------------------------------------
// Passes data between DoFaultReport and DoFaultReportCallback
diff --git a/src/vm/ecall.h b/src/vm/ecall.h
index 768b8a9698..c4fed1ff42 100644
--- a/src/vm/ecall.h
+++ b/src/vm/ecall.h
@@ -16,16 +16,8 @@
class MethodDesc;
-#ifndef FEATURE_CORECLR
-// Every program tends to use only a subset of ~1000 FCalls. Even big apps like
-// VS do not usually hit more than 300. Pick a size of the hashtable that's sufficient
-// for the typical case. It is ok to have some colisions in the rare case. Note that
-// the size of the table should be prime.
-#define FCALL_HASH_SIZE 257
-#else
// CoreCLR defines fewer FCalls so make the hashtable even smaller.
#define FCALL_HASH_SIZE 127
-#endif
typedef DPTR(struct ECHash) PTR_ECHash;
diff --git a/src/vm/ecalllist.h b/src/vm/ecalllist.h
index ba05e99543..6ed29b8611 100644
--- a/src/vm/ecalllist.h
+++ b/src/vm/ecalllist.h
@@ -59,48 +59,6 @@
//
//
-#ifdef FEATURE_REMOTING
-FCFuncStart(gMarshalByRefFuncs)
- FCFuncElement("GetComIUnknown", RemotingNative::GetComIUnknown)
-FCFuncEnd()
-
-FCFuncStart(gRemotingFuncs)
- FCFuncElement("IsTransparentProxy", RemotingNative::FCIsTransparentProxy)
- FCFuncElement("GetRealProxy", RemotingNative::FCGetRealProxy)
- FCFuncElement("Unwrap", RemotingNative::FCUnwrap)
- FCFuncElement("AlwaysUnwrap", RemotingNative::FCAlwaysUnwrap)
- FCFuncElement("CheckCast", RemotingNative::NativeCheckCast)
- FCFuncElement("nSetRemoteActivationConfigured", RemotingNative::SetRemotingConfiguredFlag)
-
- FCFuncElement("CORProfilerTrackRemoting", ProfilingFCallHelper::FC_TrackRemoting)
- FCFuncElement("CORProfilerTrackRemotingCookie", ProfilingFCallHelper::FC_TrackRemotingCookie)
- FCFuncElement("CORProfilerTrackRemotingAsync", ProfilingFCallHelper::FC_TrackRemotingAsync)
- FCFuncElement("CORProfilerRemotingClientSendingMessage", ProfilingFCallHelper::FC_RemotingClientSendingMessage)
- FCFuncElement("CORProfilerRemotingClientReceivingReply", ProfilingFCallHelper::FC_RemotingClientReceivingReply)
- FCFuncElement("CORProfilerRemotingServerReceivingMessage", ProfilingFCallHelper::FC_RemotingServerReceivingMessage)
- FCFuncElement("CORProfilerRemotingServerSendingReply", ProfilingFCallHelper::FC_RemotingServerSendingReply)
-
- FCFuncElement("CreateTransparentProxy", RemotingNative::CreateTransparentProxy)
- FCFuncElement("AllocateUninitializedObject", RemotingNative::AllocateUninitializedObject)
- FCFuncElement("CallDefaultCtor", RemotingNative::CallDefaultCtor)
- FCFuncElement("AllocateInitializedObject", RemotingNative::AllocateInitializedObject)
- FCFuncElement("ResetInterfaceCache", RemotingNative::ResetInterfaceCache)
-FCFuncEnd()
-
-FCFuncStart(gRealProxyFuncs)
- FCFuncElement("SetStubData", CRealProxy::SetStubData)
- FCFuncElement("GetStubData", CRealProxy::GetStubData)
- FCFuncElement("GetStub", CRealProxy::GetStub)
- FCFuncElement("GetDefaultStub", CRealProxy::GetDefaultStub)
- FCFuncElement("GetProxiedType", CRealProxy::GetProxiedType)
-FCFuncEnd()
-
-FCFuncStart(gContextFuncs)
- FCFuncElement("SetupInternalContext", Context::SetupInternalContext)
- FCFuncElement("CleanupInternalContext", Context::CleanupInternalContext)
- FCFuncElement("ExecuteCallBackInEE", Context::ExecuteCallBack)
-FCFuncEnd()
-#endif
FCFuncStart(gDependentHandleFuncs)
@@ -112,55 +70,9 @@ FCFuncStart(gDependentHandleFuncs)
FCFuncElement("nSetSecondary", DependentHandle::nSetSecondary)
FCFuncEnd()
-#ifndef FEATURE_CORECLR
-FCFuncStart(gSizedRefHandleFuncs)
- FCFuncElement("CreateSizedRef", SizedRefHandle::Initialize)
- FCFuncElement("FreeSizedRef", SizedRefHandle::Free)
- FCFuncElement("GetTargetOfSizedRef", SizedRefHandle::GetTarget)
- FCFuncElement("GetApproximateSizeOfSizedRef", SizedRefHandle::GetApproximateSize)
-FCFuncEnd()
-#endif // !FEATURE_CORECLR
-
-#ifdef FEATURE_RWLOCK
-FCFuncStart(gRWLockFuncs)
- FCFuncElement("AcquireReaderLockInternal", CRWLock::StaticAcquireReaderLockPublic)
- FCFuncElement("AcquireWriterLockInternal", CRWLock::StaticAcquireWriterLockPublic)
- FCFuncElement("ReleaseReaderLockInternal", CRWLock::StaticReleaseReaderLockPublic)
- FCFuncElement("ReleaseWriterLockInternal", CRWLock::StaticReleaseWriterLockPublic)
- FCFuncElement("FCallUpgradeToWriterLock", CRWLock::StaticDoUpgradeToWriterLockPublic)
- FCFuncElement("DowngradeFromWriterLockInternal", CRWLock::StaticDowngradeFromWriterLock)
- FCFuncElement("FCallReleaseLock", CRWLock::StaticDoReleaseLock)
- FCFuncElement("RestoreLockInternal", CRWLock::StaticRestoreLockPublic)
- FCFuncElement("PrivateGetIsReaderLockHeld", CRWLock::StaticIsReaderLockHeld)
- FCFuncElement("PrivateGetIsWriterLockHeld", CRWLock::StaticIsWriterLockHeld)
- FCFuncElement("PrivateGetWriterSeqNum", CRWLock::StaticGetWriterSeqNum)
- FCFuncElement("AnyWritersSince", CRWLock::StaticAnyWritersSince)
- FCFuncElement("PrivateInitialize", CRWLock::StaticPrivateInitialize)
- FCFuncElement("PrivateDestruct", CRWLock::StaticPrivateDestruct)
-FCFuncEnd()
-#endif // FEATURE_RWLOCK
-
-#ifdef FEATURE_REMOTING
-FCFuncStart(gMessageFuncs)
- FCFuncElement("InternalGetArgCount", CMessage::GetArgCount)
- FCFuncElement("InternalHasVarArgs", CMessage::HasVarArgs)
- FCFuncElement("InternalGetArg", CMessage::GetArg)
- FCFuncElement("InternalGetArgs", CMessage::GetArgs)
- FCFuncElement("PropagateOutParameters", CMessage::PropagateOutParameters)
- FCFuncElement("GetReturnValue", CMessage::GetReturnValue)
- FCFuncElement("GetAsyncBeginInfo", CMessage::GetAsyncBeginInfo)
- FCFuncElement("GetAsyncResult", CMessage::GetAsyncResult)
- FCFuncElement("GetThisPtr", CMessage::GetAsyncObject)
- FCFuncElement("OutToUnmanagedDebugger", CMessage::DebugOut)
- FCFuncElement("Dispatch", CMessage::Dispatch)
-FCFuncEnd()
-#endif //FEATURE_REMOTING
-
-#ifdef FEATURE_REMOTING
-FCFuncStart(gChannelServicesFuncs)
- FCFuncElement("GetPrivateContextsPerfCounters", GetPrivateContextsPerfCountersEx)
-FCFuncEnd()
-#endif // FEATURE_REMOTING
+
+
+
FCFuncStart(gEnumFuncs)
FCFuncElement("InternalGetUnderlyingType", ReflectionEnum::InternalGetEnumUnderlyingType)
@@ -172,17 +84,10 @@ FCFuncStart(gEnumFuncs)
FCFuncElement("InternalHasFlag", ReflectionEnum::InternalHasFlag)
FCFuncEnd()
-#ifdef FEATURE_REMOTING
-FCFuncStart(gStackBuilderSinkFuncs)
- FCFuncElement("_PrivateProcessMessage", CStackBuilderSink::PrivateProcessMessage)
-FCFuncEnd()
-#endif
-#ifdef FEATURE_CORECLR
FCFuncStart(gSymWrapperCodePunkSafeHandleFuncs)
FCFuncElement("nGetDReleaseTarget", COMPunkSafeHandle::nGetDReleaseTarget)
FCFuncEnd()
-#endif //FEATURE_CORECLR
FCFuncStart(gParseNumbersFuncs)
FCFuncElement("IntToString", ParseNumbers::IntToString)
@@ -191,11 +96,6 @@ FCFuncStart(gParseNumbersFuncs)
FCFuncElement("StringToLong", ParseNumbers::StringToLong)
FCFuncEnd()
-#ifndef FEATURE_CORECLR // FCalls used by System.TimeSpan
-FCFuncStart(gTimeSpanFuncs)
- FCFuncElement("LegacyFormatMode", SystemNative::LegacyFormatMode)
-FCFuncEnd()
-#endif // !FEATURE_CORECLR
FCFuncStart(gObjectFuncs)
FCIntrinsic("GetType", ObjectNative::GetClass, CORINFO_INTRINSIC_Object_GetType)
@@ -267,53 +167,30 @@ FCFuncEnd()
FCFuncStart(gDateTimeFuncs)
FCFuncElement("GetSystemTimeAsFileTime", SystemNative::__GetSystemTimeAsFileTime)
-#ifndef FEATURE_CORECLR
- QCFuncElement("LegacyParseMode", SystemNative::LegacyDateTimeParseMode)
- QCFuncElement("EnableAmPmParseAdjustment", SystemNative::EnableAmPmParseAdjustment)
-#endif
FCFuncEnd()
FCFuncStart(gEnvironmentFuncs)
- FCFuncElement("GetVersion", SystemNative::GetOSVersion)
- FCFuncElement("GetVersionEx", SystemNative::GetOSVersionEx)
FCFuncElement("get_TickCount", SystemNative::GetTickCount)
QCFuncElement("_Exit", SystemNative::Exit)
FCFuncElement("set_ExitCode", SystemNative::SetExitCode)
FCFuncElement("get_ExitCode", SystemNative::GetExitCode)
FCFuncElement("get_HasShutdownStarted", SystemNative::HasShutdownStarted)
QCFuncElement("GetProcessorCount", SystemNative::GetProcessorCount)
-#ifndef FEATURE_CORECLR
- FCFuncElement("nativeGetEnvironmentVariable", SystemNative::_GetEnvironmentVariable)
- FCFuncElement("GetCompatibilityFlag", SystemNative::_GetCompatibilityFlag)
- QCFuncElement("GetCommandLine", SystemNative::_GetCommandLine)
- FCFuncElement("GetResourceFromDefault", GetResourceFromDefault)
-#endif // !FEATURE_CORECLR
FCFuncElement("GetCommandLineArgsNative", SystemNative::GetCommandLineArgs)
FCFuncElement("get_CurrentProcessorNumber", SystemNative::GetCurrentProcessorNumber)
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_COMINTEROP)
QCFuncElement("WinRTSupported", SystemNative::WinRTSupported)
#endif // FEATURE_COMINTEROP
FCFuncElementSig("FailFast", &gsig_SM_Str_RetVoid, SystemNative::FailFast)
FCFuncElementSig("FailFast", &gsig_SM_Str_Exception_RetVoid, SystemNative::FailFastWithException)
-#ifndef FEATURE_CORECLR
- QCFuncElement("GetIsCLRHosted", SystemNative::IsCLRHosted)
- QCFuncElement("TriggerCodeContractFailure", SystemNative::TriggerCodeContractFailure)
-#endif // !FEATURE_CORECLR
FCFuncEnd()
FCFuncStart(gRuntimeEnvironmentFuncs)
FCFuncElement("GetModuleFileName", SystemNative::_GetModuleFileName)
-#ifndef FEATURE_CORECLR
- QCFuncElement("_GetSystemVersion", SystemNative::_GetSystemVersion)
-#endif
FCFuncEnd()
FCFuncStart(gSerializationFuncs)
-#ifndef FEATURE_CORECLR
- FCFuncElement("GetEnableUnsafeTypeForwarders", ReflectionSerialization::GetEnableUnsafeTypeForwarders)
- FCFuncElement("nativeGetSafeUninitializedObject", ReflectionSerialization::GetSafeUninitializedObject)
-#endif
FCFuncElement("nativeGetUninitializedObject", ReflectionSerialization::GetUninitializedObject)
FCFuncEnd()
@@ -321,17 +198,12 @@ FCFuncStart(gExceptionFuncs)
FCFuncElement("IsImmutableAgileException", ExceptionNative::IsImmutableAgileException)
FCFuncElement("nIsTransient", ExceptionNative::IsTransient)
FCFuncElement("GetMethodFromStackTrace", SystemNative::GetMethodFromStackTrace)
-#ifndef FEATURE_CORECLR
- FCFuncElement("StripFileInfo", ExceptionNative::StripFileInfo)
-#endif
QCFuncElement("GetMessageFromNativeResources", ExceptionNative::GetMessageFromNativeResources)
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
FCFuncElement("PrepareForForeignExceptionRaise", ExceptionNative::PrepareForForeignExceptionRaise)
FCFuncElement("CopyStackTrace", ExceptionNative::CopyStackTrace)
FCFuncElement("CopyDynamicMethods", ExceptionNative::CopyDynamicMethods)
FCFuncElement("GetStackTracesDeepCopy", ExceptionNative::GetStackTracesDeepCopy)
FCFuncElement("SaveStackTracesFromDeepCopy", ExceptionNative::SaveStackTracesFromDeepCopy)
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
FCFuncEnd()
FCFuncStart(gSafeHandleFuncs)
@@ -351,14 +223,6 @@ FCFuncStart(gSafeBufferFuncs)
FCFuncElement("StructureToPtrNative", SafeBuffer::StructureToPtr)
FCFuncEnd()
-#ifndef FEATURE_COREFX_GLOBALIZATION
-FCFuncStart(gNormalizationFuncs)
- FCFuncElement("nativeNormalizationIsNormalizedString", COMNlsInfo::nativeNormalizationIsNormalizedString)
- FCFuncElement("nativeNormalizationNormalizeString", COMNlsInfo::nativeNormalizationNormalizeString)
- QCFuncElement("nativeNormalizationInitNormalization", COMNlsInfo::nativeNormalizationInitNormalization)
-FCFuncEnd()
-#endif // FEATURE_COREFX_GLOBALIZATION
-
FCFuncStart(gTypedReferenceFuncs)
FCFuncElement("InternalToObject", ReflectionInvocation::TypedReferenceToObject)
FCFuncElement("InternalSetTypedReference", ReflectionInvocation::SetTypedReference)
@@ -430,10 +294,6 @@ FCFuncStart(gCOMTypeHandleFuncs)
QCFuncElement("VerifyInterfaceIsImplemented", RuntimeTypeHandle::VerifyInterfaceIsImplemented)
QCFuncElement("GetInterfaceMethodImplementationSlot", RuntimeTypeHandle::GetInterfaceMethodImplementationSlot)
FCFuncElement("IsComObject", RuntimeTypeHandle::IsComObject)
-#ifdef FEATURE_REMOTING
- FCFuncElement("HasProxyAttribute", RuntimeTypeHandle::HasProxyAttribute)
- FCFuncElement("IsContextful", RuntimeTypeHandle::IsContextful)
-#endif
FCFuncElement("IsValueType", RuntimeTypeHandle::IsValueType)
FCFuncElement("IsInterface", RuntimeTypeHandle::IsInterface)
QCFuncElement("IsSecurityCritical", RuntimeTypeHandle::IsSecurityCritical)
@@ -456,10 +316,6 @@ FCFuncStart(gCOMTypeHandleFuncs)
FCFuncElement("Allocate", RuntimeTypeHandle::Allocate) //for A.CI
FCFuncElement("CompareCanonicalHandles", RuntimeTypeHandle::CompareCanonicalHandles)
FCIntrinsic("GetValueInternal", RuntimeTypeHandle::GetValueInternal, CORINFO_INTRINSIC_RTH_GetValueInternal)
-#ifndef FEATURE_CORECLR
- FCFuncElement("IsEquivalentTo", RuntimeTypeHandle::IsEquivalentTo)
- FCFuncElement("IsEquivalentType", RuntimeTypeHandle::IsEquivalentType)
-#endif // FEATURE_CORECLR
FCFuncEnd()
FCFuncStart(gMetaDataImport)
@@ -523,11 +379,6 @@ FCFuncStart(gRuntimeMethodHandle)
FCFuncElement("GetMethodFromCanonical", RuntimeMethodHandle::GetMethodFromCanonical)
FCFuncElement("IsDynamicMethod", RuntimeMethodHandle::IsDynamicMethod)
FCFuncElement("GetMethodBody", RuntimeMethodHandle::GetMethodBody)
-#ifndef FEATURE_CORECLR
- FCFuncElement("_IsTokenSecurityTransparent", RuntimeMethodHandle::IsTokenSecurityTransparent)
- QCFuncElement("_IsSecurityCritical", RuntimeMethodHandle::IsSecurityCritical)
- QCFuncElement("_IsSecuritySafeCritical", RuntimeMethodHandle::IsSecuritySafeCritical)
-#endif // FEATURE_CORECLR
QCFuncElement("_IsSecurityTransparent", RuntimeMethodHandle::IsSecurityTransparent)
FCFuncElement("CheckLinktimeDemands", RuntimeMethodHandle::CheckLinktimeDemands)
QCFuncElement("IsCAVisibleFromDecoratedType", RuntimeMethodHandle::IsCAVisibleFromDecoratedType)
@@ -536,10 +387,6 @@ FCFuncStart(gRuntimeMethodHandle)
FCFuncElement("GetResolver", RuntimeMethodHandle::GetResolver)
FCFuncElement("GetLoaderAllocator", RuntimeMethodHandle::GetLoaderAllocator)
FCFuncElement("GetSpecialSecurityFlags", ReflectionInvocation::GetSpecialSecurityFlags)
-#ifndef FEATURE_CORECLR
- QCFuncElement("GetCallerType", RuntimeMethodHandle::GetCallerType)
- FCFuncElement("PerformSecurityCheck", ReflectionInvocation::PerformSecurityCheck)
-#endif // FEATURE_CORECLR
FCFuncEnd()
FCFuncStart(gCOMDefaultBinderFuncs)
@@ -599,9 +446,6 @@ FCFuncStart(gCOMModuleHandleFuncs)
QCFuncElement("ResolveMethod", ModuleHandle::ResolveMethod)
QCFuncElement("_ContainsPropertyMatchingHash", ModuleHandle::ContainsPropertyMatchingHash)
QCFuncElement("ResolveField", ModuleHandle::ResolveField)
-#ifndef FEATURE_CORECLR
- QCFuncElement("GetAssembly", ModuleHandle::GetAssembly)
-#endif // FEATURE_CORECLR
QCFuncElement("GetPEKind", ModuleHandle::GetPEKind)
FCFuncElement("GetMDStreamVersion", ModuleHandle::GetMDStreamVersion)
FCFuncEnd()
@@ -637,16 +481,8 @@ FCFuncStart(gCOMClassWriter)
QCFuncElement("SetParamInfo", COMDynamicWrite::SetParamInfo)
QCFuncElement("SetConstantValue", COMDynamicWrite::SetConstantValue)
QCFuncElement("DefineCustomAttribute", COMDynamicWrite::DefineCustomAttribute)
-#ifndef FEATURE_CORECLR
- QCFuncElement("AddDeclarativeSecurity", COMDynamicWrite::AddDeclarativeSecurity)
-#endif // FEATURE_CORECLR
FCFuncEnd()
-#ifdef FEATURE_METHOD_RENTAL
-FCFuncStart(gCOMMethodRental)
- QCFuncElement("SwapMethodBody", COMMethodRental::SwapMethodBody)
-FCFuncEnd()
-#endif // FEATURE_METHOD_RENTAL
FCFuncStart(gCompatibilitySwitchFuncs)
FCFuncElement("GetValueInternalCall", CompatibilitySwitch::GetValue)
@@ -659,38 +495,13 @@ FCFuncEnd()
FCFuncStart(gAppDomainManagerFuncs)
QCFuncElement("GetEntryAssembly", AssemblyNative::GetEntryAssembly)
-#ifdef FEATURE_APPDOMAINMANAGER_INITOPTIONS
- FCFuncElement("HasHost", AppDomainNative::HasHost)
- QCFuncElement("RegisterWithHost", AppDomainNative::RegisterWithHost)
-#endif
FCFuncEnd()
-#ifdef FEATURE_FUSION
-FCFuncStart(gAppDomainSetupFuncs)
- FCFuncElement("UpdateContextProperty", AppDomainNative::UpdateContextProperty)
-FCFuncEnd()
-#endif // FEATURE_FUSION
-#ifndef FEATURE_CORECLR
-FCFuncStart(gWindowsRuntimeContextFuncs)
- QCFuncElement("CreateDesignerContext", AppDomainNative::CreateDesignerContext)
- QCFuncElement("SetCurrentContext", AppDomainNative::SetCurrentDesignerContext)
-FCFuncEnd()
-#endif // FEATURE_CORECLR
FCFuncStart(gAppDomainFuncs)
-#ifdef FEATURE_REMOTING
- FCFuncElement("GetDefaultDomain", AppDomainNative::GetDefaultDomain)
-#endif
-#ifdef FEATURE_FUSION
- FCFuncElement("GetFusionContext", AppDomainNative::GetFusionContext)
-#endif // FEATURE_FUSION
FCFuncElement("IsStringInterned", AppDomainNative::IsStringInterned)
FCFuncElement("IsUnloadingForcedFinalize", AppDomainNative::IsUnloadingForcedFinalize)
-#ifdef FEATURE_REMOTING
- FCFuncElement("nCreateDomain", AppDomainNative::CreateDomain)
- FCFuncElement("nCreateInstance", AppDomainNative::CreateInstance)
-#endif
#ifdef FEATURE_LOADER_OPTIMIZATION
FCFuncElement("UpdateLoaderOptimization", AppDomainNative::UpdateLoaderOptimization)
#endif // FEATURE_LOADER_OPTIMIZATION
@@ -702,39 +513,18 @@ FCFuncStart(gAppDomainFuncs)
QCFuncElement("GetAppDomainManagerType", AppDomainNative::GetAppDomainManagerType)
QCFuncElement("SetAppDomainManagerType", AppDomainNative::SetAppDomainManagerType)
FCFuncElement("nGetFriendlyName", AppDomainNative::GetFriendlyName)
-#ifndef FEATURE_CORECLR
- FCFuncElement("GetSecurityDescriptor", AppDomainNative::GetSecurityDescriptor)
- FCFuncElement("nIsDefaultAppDomainForEvidence", AppDomainNative::IsDefaultAppDomainForEvidence)
- FCFuncElement("nGetAssemblies", AppDomainNative::GetAssemblies)
-#endif
-#ifdef FEATURE_APTCA
- QCFuncElement("SetCanonicalConditionalAptcaList", AppDomainNative::SetCanonicalConditionalAptcaList)
-#endif // FEATURE_ATPCA
QCFuncElement("SetSecurityHomogeneousFlag", AppDomainNative::SetSecurityHomogeneousFlag)
QCFuncElement("SetupDomainSecurity", AppDomainNative::SetupDomainSecurity)
FCFuncElement("nSetupFriendlyName", AppDomainNative::SetupFriendlyName)
#if FEATURE_COMINTEROP
FCFuncElement("nSetDisableInterfaceCache", AppDomainNative::SetDisableInterfaceCache)
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_VERSIONING
FCFuncElement("nCreateContext", AppDomainNative::CreateContext)
-#endif // FEATURE_VERSIONING
-#ifdef FEATURE_REMOTING
- FCFuncElement("nUnload", AppDomainNative::Unload)
-#endif // FEATURE_REMOTING
FCFuncElement("GetId", AppDomainNative::GetId)
FCFuncElement("GetOrInternString", AppDomainNative::GetOrInternString)
QCFuncElement("GetGrantSet", AppDomainNative::GetGrantSet)
-#ifdef FEATURE_REMOTING
- FCFuncElement("GetDynamicDir", AppDomainNative::GetDynamicDir)
- FCFuncElement("nChangeSecurityPolicy", AppDomainNative::ChangeSecurityPolicy)
- FCFuncElement("IsDomainIdValid", AppDomainNative::IsDomainIdValid)
- FCFuncElement("nApplyPolicy", AppDomainNative::nApplyPolicy)
-#endif // FEATURE_REMOTING
-#ifdef FEATURE_CORECLR
QCFuncElement("nSetupBindingPaths", AppDomainNative::SetupBindingPaths)
QCFuncElement("nSetNativeDllSearchDirectories", AppDomainNative::SetNativeDllSearchDirectories)
-#endif
FCFuncElement("IsFinalizingForUnload", AppDomainNative::IsFinalizingForUnload)
FCFuncElement("PublishAnonymouslyHostedDynamicMethodsAssembly", AppDomainNative::PublishAnonymouslyHostedDynamicMethodsAssembly)
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
@@ -748,12 +538,6 @@ FCFuncStart(gAppDomainFuncs)
#endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING
FCFuncEnd()
-#if defined(FEATURE_MULTICOREJIT) && !defined(FEATURE_CORECLR)
-FCFuncStart(gProfileOptimizationFuncs)
- QCFuncElement("InternalSetProfileRoot", MultiCoreJITNative::InternalSetProfileRoot)
- QCFuncElement("InternalStartProfile", MultiCoreJITNative::InternalStartProfile)
-FCFuncEnd()
-#endif // defined(FEATURE_MULTICOREJIT) && !defined(FEATURE_CORECLR)
FCFuncStart(gUtf8String)
FCFuncElement("EqualsCaseSensitive", Utf8String::EqualsCaseSensitive)
@@ -805,26 +589,13 @@ FCFuncStart(gAssemblyFuncs)
QCFuncElement("GetHashAlgorithm", AssemblyNative::GetHashAlgorithm)
QCFuncElement("GetLocale", AssemblyNative::GetLocale)
QCFuncElement("GetPublicKey", AssemblyNative::GetPublicKey)
-#ifndef FEATURE_CORECLR
- QCFuncElement("GetSecurityRuleSet", AssemblyNative::GetSecurityRuleSet)
-#endif // !FEATURE_CORECLR
QCFuncElement("GetSimpleName", AssemblyNative::GetSimpleName)
QCFuncElement("GetVersion", AssemblyNative::GetVersion)
FCFuncElement("FCallIsDynamic", AssemblyNative::IsDynamic)
FCFuncElement("_nLoad", AssemblyNative::Load)
-#ifndef FEATURE_CORECLR
- FCFuncElement("IsFrameworkAssembly", AssemblyNative::IsFrameworkAssembly)
- FCFuncElement("IsNewPortableAssembly", AssemblyNative::IsNewPortableAssembly)
-#endif
FCFuncElement("nLoadImage", AssemblyNative::LoadImage)
-#ifndef FEATURE_CORECLR
- QCFuncElement("LoadModule", AssemblyNative::LoadModule)
-#endif // FEATURE_CORECLR
QCFuncElement("GetType", AssemblyNative::GetType)
QCFuncElement("GetManifestResourceInfo", AssemblyNative::GetManifestResourceInfo)
-#ifndef FEATURE_CORECLR
- QCFuncElement("UseRelativeBindForSatellites", AssemblyNative::UseRelativeBindForSatellites)
-#endif
QCFuncElement("GetModules", AssemblyNative::GetModules)
QCFuncElement("GetModule", AssemblyNative::GetModule)
FCFuncElement("GetReferencedAssemblies", AssemblyNative::GetReferencedAssemblies)
@@ -833,27 +604,16 @@ FCFuncStart(gAssemblyFuncs)
QCFuncElement("GetEntryPoint", AssemblyNative::GetEntryPoint)
QCFuncElement("IsAllSecurityTransparent", AssemblyNative::IsAllSecurityTransparent)
QCFuncElement("IsAllSecurityCritical", AssemblyNative::IsAllSecurityCritical)
-#ifndef FEATURE_CORECLR
- QCFuncElement("IsAllSecuritySafeCritical", AssemblyNative::IsAllSecuritySafeCritical)
- QCFuncElement("IsAllPublicAreaSecuritySafeCritical", AssemblyNative::IsAllPublicAreaSecuritySafeCritical)
- QCFuncElement("GetGrantSet", AssemblyNative::GetGrantSet)
-#endif // !FEATURE_CORECLR
QCFuncElement("GetImageRuntimeVersion", AssemblyNative::GetImageRuntimeVersion)
FCFuncElement("IsReflectionOnly", AssemblyNative::IsReflectionOnly)
FCFuncElement("GetManifestModule", AssemblyHandle::GetManifestModule)
FCFuncElement("GetToken", AssemblyHandle::GetToken)
-#ifdef FEATURE_APTCA
- FCFuncElement("AptcaCheck", AssemblyHandle::AptcaCheck)
-#endif // FEATURE_APTCA
FCFuncEnd()
-#ifdef FEATURE_CORECLR
FCFuncStart(gAssemblyExtensionsFuncs)
QCFuncElement("InternalTryGetRawMetadata", AssemblyNative::InternalTryGetRawMetadata)
FCFuncEnd()
-#endif
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
FCFuncStart(gAssemblyLoadContextFuncs)
QCFuncElement("InitializeAssemblyLoadContext", AssemblyNative::InitializeAssemblyLoadContext)
QCFuncElement("LoadFromPath", AssemblyNative::LoadFromPath)
@@ -861,23 +621,17 @@ FCFuncStart(gAssemblyLoadContextFuncs)
QCFuncElement("InternalLoadUnmanagedDllFromPath", AssemblyNative::InternalLoadUnmanagedDllFromPath)
QCFuncElement("CanUseAppPathAssemblyLoadContextInCurrentDomain", AssemblyNative::CanUseAppPathAssemblyLoadContextInCurrentDomain)
QCFuncElement("LoadFromStream", AssemblyNative::LoadFromStream)
- FCFuncElement("nGetFileInformation", AssemblyNameNative::GetFileInformation)
QCFuncElement("GetLoadContextForAssembly", AssemblyNative::GetLoadContextForAssembly)
#if defined(FEATURE_MULTICOREJIT)
QCFuncElement("InternalSetProfileRoot", MultiCoreJITNative::InternalSetProfileRoot)
QCFuncElement("InternalStartProfile", MultiCoreJITNative::InternalStartProfile)
#endif // defined(FEATURE_MULTICOREJIT)
FCFuncEnd()
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
FCFuncStart(gAssemblyNameFuncs)
FCFuncElement("nInit", AssemblyNameNative::Init)
FCFuncElement("nToString", AssemblyNameNative::ToString)
FCFuncElement("nGetPublicKeyToken", AssemblyNameNative::GetPublicKeyToken)
-#ifndef FEATURE_CORECLR
- FCFuncElement("EscapeCodeBase", AssemblyNameNative::EscapeCodeBase)
-#endif // !FEATURE_CORECLR
- FCFuncElement("ReferenceMatchesDefinitionInternal", AssemblyNameNative::ReferenceMatchesDefinition)
FCFuncElement("nGetFileInformation", AssemblyNameNative::GetFileInformation)
FCFuncEnd()
@@ -888,21 +642,6 @@ FCFuncEnd()
FCFuncStart(gAssemblyBuilderFuncs)
FCFuncElement("nCreateDynamicAssembly", AppDomainNative::CreateDynamicAssembly)
FCFuncElement("GetInMemoryAssemblyModule", AssemblyNative::GetInMemoryAssemblyModule)
-#ifndef FEATURE_CORECLR
- FCFuncElement("GetOnDiskAssemblyModule", AssemblyNative::GetOnDiskAssemblyModule)
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- QCFuncElement("DefineDynamicModule", COMModule::DefineDynamicModule)
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
- QCFuncElement("PrepareForSavingManifestToDisk", AssemblyNative::PrepareForSavingManifestToDisk)
- QCFuncElement("SaveManifestToDisk", AssemblyNative::SaveManifestToDisk)
- QCFuncElement("AddFile", AssemblyNative::AddFile)
- QCFuncElement("SetFileHashValue", AssemblyNative::SetFileHashValue)
- QCFuncElement("AddStandAloneResource", AssemblyNative::AddStandAloneResource)
- QCFuncElement("AddExportedTypeOnDisk", AssemblyNative::AddExportedTypeOnDisk)
- QCFuncElement("AddExportedTypeInMemory", AssemblyNative::AddExportedTypeInMemory)
- QCFuncElement("AddDeclarativeSecurity", AssemblyNative::AddDeclarativeSecurity)
- QCFuncElement("CreateVersionInfoResource", AssemblyNative::CreateVersionInfoResource)
-#endif // !FEATURE_CORECLR
FCFuncEnd()
#ifdef MDA_SUPPORTED
@@ -1006,55 +745,22 @@ FCFuncEnd()
FCFuncStart(gThreadFuncs)
FCDynamic("InternalGetCurrentThread", CORINFO_INTRINSIC_Illegal, ECall::InternalGetCurrentThread)
FCFuncElement("StartInternal", ThreadNative::Start)
-#ifndef FEATURE_CORECLR
- FCFuncElement("SuspendInternal", ThreadNative::Suspend)
- FCFuncElement("ResumeInternal", ThreadNative::Resume)
-#endif
-#ifdef FEATURE_LEAK_CULTURE_INFO
- FCFuncElement("nativeGetSafeCulture", ThreadNative::nativeGetSafeCulture)
-#else
QCFuncElement("nativeInitCultureAccessors", ThreadNative::nativeInitCultureAccessors)
-#endif
#undef Sleep
FCFuncElement("SleepInternal", ThreadNative::Sleep)
#define Sleep(a) Dont_Use_Sleep(a)
FCFuncElement("SetStart", ThreadNative::SetStart)
-#ifdef FEATURE_REMOTING
- FCFuncElement("GetContextInternal", ThreadNative::GetContextFromContextID)
-#endif
FCFuncElement("GetDomainInternal", ThreadNative::GetDomain)
FCFuncElement("GetFastDomainInternal", ThreadNative::FastGetDomain)
-#ifdef FEATURE_REMOTING
- FCFuncElement("InternalCrossContextCallback", ThreadNative::InternalCrossContextCallback)
-#endif
QCFuncElement("InformThreadNameChange", ThreadNative::InformThreadNameChange)
-#ifndef FEATURE_CORECLR
- QCFuncElement("GetProcessDefaultStackSize", ThreadNative::GetProcessDefaultStackSize)
- FCFuncElement("BeginCriticalRegion", ThreadNative::BeginCriticalRegion)
- FCFuncElement("EndCriticalRegion", ThreadNative::EndCriticalRegion)
- FCFuncElement("BeginThreadAffinity", ThreadNative::BeginThreadAffinity)
- FCFuncElement("EndThreadAffinity", ThreadNative::EndThreadAffinity)
-#endif // FEATURE_CORECLR
-#ifndef FEATURE_CORECLR
- FCFuncElement("ResetAbortNative", ThreadNative::ResetAbort)
-#endif // FEATURE_CORECLR
FCFuncElement("SpinWaitInternal", ThreadNative::SpinWait)
QCFuncElement("YieldInternal", ThreadNative::YieldThread)
FCIntrinsic("GetCurrentThreadNative", ThreadNative::GetCurrentThread, CORINFO_INTRINSIC_GetCurrentManagedThread)
FCIntrinsic("get_ManagedThreadId", ThreadNative::GetManagedThreadId, CORINFO_INTRINSIC_GetManagedThreadId)
FCFuncElement("InternalFinalize", ThreadNative::Finalize)
-#ifdef FEATURE_LEAK_CULTURE_INFO
- FCFuncElement("nativeSetThreadUILocale", ThreadNative::SetThreadUILocale)
-#endif
#ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT
FCFuncElement("StartupSetApartmentStateInternal", ThreadNative::StartupSetApartmentState)
#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
- FCIntrinsic("MemoryBarrier", ThreadNative::FCMemoryBarrier, CORINFO_INTRINSIC_MemoryBarrier)
-#ifndef FEATURE_CORECLR // coreclr does not support abort reason
- FCFuncElement("SetAbortReason", ThreadNative::SetAbortReason)
- FCFuncElement("GetAbortReason", ThreadNative::GetAbortReason)
- FCFuncElement("ClearAbortReason", ThreadNative::ClearAbortReason)
-#endif
FCFuncEnd()
FCFuncStart(gThreadPoolFuncs)
@@ -1068,7 +774,6 @@ FCFuncStart(gThreadPoolFuncs)
FCFuncElement("GetMaxThreadsNative", ThreadPoolNative::CorGetMaxThreads)
FCFuncElement("NotifyWorkItemComplete", ThreadPoolNative::NotifyRequestComplete)
FCFuncElement("NotifyWorkItemProgressNative", ThreadPoolNative::NotifyRequestProgress)
- FCFuncElement("IsThreadPoolHosted", ThreadPoolNative::IsThreadPoolHosted)
QCFuncElement("InitializeVMTp", ThreadPoolNative::InitializeVMTp)
FCFuncElement("ReportThreadStatus", ThreadPoolNative::ReportThreadStatus)
QCFuncElement("RequestWorkerThread", ThreadPoolNative::RequestWorkerThread)
@@ -1102,9 +807,6 @@ FCFuncStart(gNumberFuncs)
FCFuncElement("FormatInt64", COMNumber::FormatInt64)
FCFuncElement("FormatUInt64", COMNumber::FormatUInt64)
FCFuncElement("FormatSingle", COMNumber::FormatSingle)
-#if !defined(FEATURE_CORECLR)
- FCFuncElement("FormatNumberBuffer", COMNumber::FormatNumberBuffer)
-#endif // !FEATURE_CORECLR
FCFuncElement("NumberBufferToDecimal", COMNumber::NumberBufferToDecimal)
FCFuncElement("NumberBufferToDouble", COMNumber::NumberBufferToDouble)
FCFuncEnd()
@@ -1147,25 +849,13 @@ FCFuncStart(gCurrencyFuncs)
FCFuncElement("FCallToDecimal", COMCurrency::DoToDecimal)
FCFuncEnd()
-#ifndef FEATURE_CORECLR
-FCFuncStart(gCLRConfigFuncs)
- FCFuncElement("CheckLegacyManagedDeflateStream", SystemNative::CheckLegacyManagedDeflateStream)
- FCFuncElement("CheckThrowUnobservedTaskExceptions", SystemNative::CheckThrowUnobservedTaskExceptions)
+FCFuncStart(gClrConfig)
+ QCFuncElement("GetConfigBoolValue", ClrConfigNative::GetConfigBoolValue)
FCFuncEnd()
-#endif // ifndef FEATURE_CORECLR
#if !defined(FEATURE_COREFX_GLOBALIZATION)
FCFuncStart(gCompareInfoFuncs)
QCFuncElement("InternalGetGlobalizedHashCode", COMNlsInfo::InternalGetGlobalizedHashCode)
- QCFuncElement("InternalCompareString", COMNlsInfo::InternalCompareString)
- QCFuncElement("InternalFindNLSStringEx", COMNlsInfo::InternalFindNLSStringEx)
- QCFuncElement("NativeInternalInitSortHandle", COMNlsInfo::InternalInitSortHandle)
- QCFuncElement("InternalIsSortable", COMNlsInfo::InternalIsSortable)
- QCFuncElement("InternalGetSortKey", COMNlsInfo::InternalGetSortKey)
-#ifndef FEATURE_CORECLR
- QCFuncElement("InternalGetSortVersion", COMNlsInfo::InternalGetSortVersion)
-#endif
- QCFuncElement("InternalGetNlsVersionEx", COMNlsInfo::InternalGetNlsVersionEx)
FCFuncEnd()
FCFuncStart(gEncodingTableFuncs)
@@ -1173,44 +863,6 @@ FCFuncStart(gEncodingTableFuncs)
FCFuncElement("GetEncodingData", COMNlsInfo::nativeGetEncodingTableDataPointer)
FCFuncElement("GetCodePageData", COMNlsInfo::nativeGetCodePageTableDataPointer)
FCFuncEnd()
-
-FCFuncStart(gCalendarDataFuncs)
- FCFuncElement("nativeGetTwoDigitYearMax", CalendarData::nativeGetTwoDigitYearMax)
- FCFuncElement("nativeGetCalendarData", CalendarData::nativeGetCalendarData)
- FCFuncElement("nativeGetCalendars", CalendarData::nativeGetCalendars)
-FCFuncEnd()
-
-FCFuncStart(gCultureDataFuncs)
- FCFuncElement("nativeInitCultureData", COMNlsInfo::nativeInitCultureData)
- FCFuncElement("nativeGetNumberFormatInfoValues", COMNlsInfo::nativeGetNumberFormatInfoValues)
- FCFuncElement("nativeEnumTimeFormats", CalendarData::nativeEnumTimeFormats)
- FCFuncElement("LCIDToLocaleName", COMNlsInfo::LCIDToLocaleName)
- FCFuncElement("LocaleNameToLCID", COMNlsInfo::LocaleNameToLCID)
-
- QCFuncElement("nativeEnumCultureNames", COMNlsInfo::nativeEnumCultureNames)
-
-FCFuncEnd()
-
-FCFuncStart(gCultureInfoFuncs)
- QCFuncElement("InternalGetDefaultLocaleName", COMNlsInfo::InternalGetDefaultLocaleName)
- FCFuncElement("nativeGetLocaleInfoEx", COMNlsInfo::nativeGetLocaleInfoEx)
- FCFuncElement("nativeGetLocaleInfoExInt", COMNlsInfo::nativeGetLocaleInfoExInt)
-
- QCFuncElement("InternalGetUserDefaultUILanguage", COMNlsInfo::InternalGetUserDefaultUILanguage)
- QCFuncElement("InternalGetSystemDefaultUILanguage", COMNlsInfo::InternalGetSystemDefaultUILanguage)
-// Added but disabled from desktop in .NET 4.0, stayed disabled in .NET 4.5
-#ifdef FEATURE_CORECLR
- FCFuncElement("nativeGetResourceFallbackArray", COMNlsInfo::nativeGetResourceFallbackArray)
-#endif
-FCFuncEnd()
-
-FCFuncStart(gTextInfoFuncs)
- FCFuncElement("InternalChangeCaseChar", COMNlsInfo::InternalChangeCaseChar)
- FCFuncElement("InternalChangeCaseString", COMNlsInfo::InternalChangeCaseString)
- FCFuncElement("InternalGetCaseInsHash", COMNlsInfo::InternalGetCaseInsHash)
- QCFuncElement("InternalCompareStringOrdinalIgnoreCase", COMNlsInfo::InternalCompareStringOrdinalIgnoreCase)
- QCFuncElement("InternalTryFindStringOrdinalIgnoreCase", COMNlsInfo::InternalTryFindStringOrdinalIgnoreCase)
-FCFuncEnd()
#endif // !defined(FEATURE_COREFX_GLOBALIZATION)
#ifdef FEATURE_COREFX_GLOBALIZATION
@@ -1295,13 +947,6 @@ FCFuncStart(gInteropMarshalFuncs)
FCFuncElement("UnsafeAddrOfPinnedArrayElement", MarshalNative::FCUnsafeAddrOfPinnedArrayElement)
FCFuncElement("GetExceptionCode", ExceptionNative::GetExceptionCode)
QCFuncElement("GetHINSTANCE", COMModule::GetHINSTANCE)
-#ifndef FEATURE_CORECLR
- QCFuncElement("InternalNumParamBytes", MarshalNative::NumParamBytes)
- FCFuncElement("GetExceptionPointers", ExceptionNative::GetExceptionPointers)
- FCFuncElement("GetUnmanagedThunkForManagedMethodPtr", MarshalNative::GetUnmanagedThunkForManagedMethodPtr)
- FCFuncElement("GetManagedThunkForUnmanagedMethodPtr", MarshalNative::GetManagedThunkForUnmanagedMethodPtr)
- FCFuncElement("InternalGetThreadFromFiberCookie", MarshalNative::GetThreadFromFiberCookie)
-#endif
FCFuncElement("OffsetOfHelper", MarshalNative::OffsetOfHelper)
FCFuncElement("SizeOfType", SafeBuffer::SizeOfType)
@@ -1337,9 +982,6 @@ FCFuncStart(gInteropMarshalFuncs)
FCFuncElement("GetNativeActivationFactory", MarshalNative::GetNativeActivationFactory)
FCFuncElement("GetIUnknownForObjectNative", MarshalNative::GetIUnknownForObjectNative)
-#ifndef FEATURE_CORECLR
- FCFuncElement("GetIDispatchForObjectNative", MarshalNative::GetIDispatchForObjectNative)
-#endif // FEATURE_CORECLR
FCFuncElement("GetComInterfaceForObjectNative", MarshalNative::GetComInterfaceForObjectNative)
FCFuncElement("InternalReleaseComObject", MarshalNative::ReleaseComObject)
FCFuncElement("Release", MarshalNative::Release)
@@ -1347,26 +989,6 @@ FCFuncStart(gInteropMarshalFuncs)
FCFuncElement("GetTypedObjectForIUnknown", MarshalNative::GetTypedObjectForIUnknown)
FCFuncElement("ChangeWrapperHandleStrength", MarshalNative::ChangeWrapperHandleStrength)
FCFuncElement("CleanupUnusedObjectsInCurrentContext", MarshalNative::CleanupUnusedObjectsInCurrentContext)
-#ifndef FEATURE_CORECLR
- FCFuncElement("GetLoadedTypeForGUID", MarshalNative::GetLoadedTypeForGUID)
- FCFuncElement("GetITypeInfoForType", MarshalNative::GetITypeInfoForType)
- FCFuncElement("IsTypeVisibleFromCom", MarshalNative::IsTypeVisibleFromCom)
- FCFuncElement("FCallGenerateGuidForType", MarshalNative::DoGenerateGuidForType)
- FCFuncElement("FCallGetTypeLibGuid", MarshalNative::DoGetTypeLibGuid)
- FCFuncElement("GetTypeLibLcid", MarshalNative::GetTypeLibLcid)
- FCFuncElement("GetTypeLibVersion", MarshalNative::GetTypeLibVersion)
- FCFuncElement("FCallGetTypeInfoGuid", MarshalNative::DoGetTypeInfoGuid)
- FCFuncElement("FCallGetTypeLibGuidForAssembly", MarshalNative::DoGetTypeLibGuidForAssembly)
- FCFuncElement("_GetTypeLibVersionForAssembly", MarshalNative::GetTypeLibVersionForAssembly)
- FCFuncElement("GetEndComSlot", MarshalNative::GetEndComSlot)
- FCFuncElement("GetMethodInfoForComSlot", MarshalNative::GetMethodInfoForComSlot)
- FCFuncElement("InternalGetComSlotForMethodInfo", MarshalNative::GetComSlotForMethodInfo)
- FCFuncElement("InternalSwitchCCW", MarshalNative::SwitchCCW)
- FCFuncElement("InternalWrapIUnknownWithComObject", MarshalNative::WrapIUnknownWithComObject)
- QCFuncElement("_GetInspectableIids", MarshalNative::GetInspectableIIDs)
- QCFuncElement("_GetCachedWinRTTypes", MarshalNative::GetCachedWinRTTypes)
- QCFuncElement("_GetCachedWinRTTypeByIid", MarshalNative::GetCachedWinRTTypeByIID)
-#endif // FEATURE_CORECLR
#endif // FEATURE_COMINTEROP
FCFuncEnd()
@@ -1376,20 +998,8 @@ FCFuncEnd()
#ifdef FEATURE_COMINTEROP
-#ifndef FEATURE_CORECLR
-FCFuncStart(gExtensibleClassFactoryFuncs)
- FCFuncElement("RegisterObjectCreationCallback", RegisterObjectCreationCallback)
-FCFuncEnd()
-#endif
-#ifdef FEATURE_COMINTEROP_TLB_SUPPORT
-FCFuncStart(gTypeLibConverterFuncs)
- FCFuncElement("nConvertAssemblyToTypeLib", COMTypeLibConverter::ConvertAssemblyToTypeLib)
- FCFuncElement("nConvertTypeLibToMetadata", COMTypeLibConverter::ConvertTypeLibToMetadata)
- QCFuncElement("LoadInMemoryTypeByName", COMModule::LoadInMemoryTypeByName)
-FCFuncEnd()
-#endif // FEATURE_COMINTEROP_TLB_SUPPORT
#ifdef FEATURE_COMINTEROP_MANAGED_ACTIVATION
FCFuncStart(gRegistrationFuncs)
@@ -1432,7 +1042,9 @@ FCFuncStart(gInterlockedFuncs)
FCFuncElement("_Exchange", COMInterlocked::ExchangeGeneric)
FCFuncElement("_CompareExchange", COMInterlocked::CompareExchangeGeneric)
-
+
+ FCIntrinsic("MemoryBarrier", COMInterlocked::FCMemoryBarrier, CORINFO_INTRINSIC_MemoryBarrier)
+ QCFuncElement("_MemoryBarrierProcessWide", COMInterlocked::MemoryBarrierProcessWide)
FCFuncEnd()
FCFuncStart(gVarArgFuncs)
@@ -1467,13 +1079,7 @@ FCFuncStart(gCompilerFuncs)
FCIntrinsic("InitializeArray", ArrayNative::InitializeArray, CORINFO_INTRINSIC_InitializeArray)
FCFuncElement("_RunClassConstructor", ReflectionInvocation::RunClassConstructor)
FCFuncElement("_RunModuleConstructor", ReflectionInvocation::RunModuleConstructor)
-#ifndef FEATURE_CORECLR
- FCFuncElement("_PrepareMethod", ReflectionInvocation::PrepareMethod)
-#endif // !FEATURE_CORECLR
QCFuncElement("_CompileMethod", ReflectionInvocation::CompileMethod)
-#ifndef FEATURE_CORECLR
- FCFuncElement("PrepareDelegate", ReflectionInvocation::PrepareDelegate)
-#endif // !FEATURE_CORECLR
FCFuncElement("PrepareContractedDelegate", ReflectionInvocation::PrepareContractedDelegate)
FCFuncElement("ProbeForSufficientStack", ReflectionInvocation::ProbeForSufficientStack)
FCFuncElement("ExecuteCodeWithGuaranteedCleanup", ReflectionInvocation::ExecuteCodeWithGuaranteedCleanup)
@@ -1484,9 +1090,7 @@ FCFuncStart(gCompilerFuncs)
FCFuncEnd()
FCFuncStart(gContextSynchronizationFuncs)
-#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
FCFuncElement("WaitHelperNative", SynchronizationContextNative::WaitHelper)
-#endif // #ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
#ifdef FEATURE_APPX
QCFuncElement("GetWinRTDispatcherForCurrentThread", SynchronizationContextNative::GetWinRTDispatcherForCurrentThread)
#endif
@@ -1571,20 +1175,12 @@ FCFuncStart(gMngdRefCustomMarshalerFuncs)
FCFuncEnd()
FCFuncStart(gStubHelperFuncs)
-#ifndef FEATURE_CORECLR
-#ifndef _WIN64
- FCFuncElement("GetFinalStubTarget", StubHelpers::GetFinalStubTarget)
-#endif // !_WIN64
- FCFuncElement("DemandPermission", StubHelpers::DemandPermission)
-#endif // !FEATURE_CORECLR
FCFuncElement("IsQCall", StubHelpers::IsQCall)
FCFuncElement("InitDeclaringType", StubHelpers::InitDeclaringType)
FCIntrinsic("GetNDirectTarget", StubHelpers::GetNDirectTarget, CORINFO_INTRINSIC_StubHelpers_GetNDirectTarget)
FCFuncElement("GetDelegateTarget", StubHelpers::GetDelegateTarget)
FCFuncElement("SetLastError", StubHelpers::SetLastError)
-#ifdef FEATURE_CORECLR
FCFuncElement("ClearLastError", StubHelpers::ClearLastError)
-#endif
FCFuncElement("ThrowInteropParamException", StubHelpers::ThrowInteropParamException)
FCFuncElement("InternalGetHRExceptionObject", StubHelpers::GetHRExceptionObject)
#ifdef FEATURE_COMINTEROP
@@ -1654,11 +1250,6 @@ FCFuncStart(gGCHandleFuncs)
FCFuncElement("InternalCheckDomain", MarshalNative::GCHandleInternalCheckDomain)
FCFuncEnd()
-#ifndef FEATURE_CORECLR
-FCFuncStart(gConsoleFuncs)
- QCFuncElement("GetTitleNative", ConsoleNative::GetTitle)
-FCFuncEnd()
-#endif // ifndef FEATURE_CORECLR
FCFuncStart(gVersioningHelperFuncs)
FCFuncElement("GetRuntimeId", GetRuntimeId_Wrapper)
@@ -1669,11 +1260,6 @@ FCFuncStart(gStreamFuncs)
FCFuncElement("HasOverriddenBeginEndWrite", StreamNative::HasOverriddenBeginEndWrite)
FCFuncEnd()
-#if defined(FEATURE_COMINTEROP) && defined(FEATURE_REFLECTION_ONLY_LOAD)
-FCFuncStart(gWindowsRuntimeMetadata)
- QCFuncElement("nResolveNamespace", CLRPrivTypeCacheReflectionOnlyWinRT::ResolveNamespace)
-FCFuncEnd()
-#endif //FEATURE_COMINTEROP && FEATURE_REFLECTION_ONLY_LOAD
#ifdef FEATURE_COMINTEROP
FCFuncStart(gWindowsRuntimeBufferHelperFuncs)
@@ -1699,6 +1285,12 @@ FCFuncStart(gRuntimeClassFuncs)
FCFuncElement("RedirectEquals", ComObject::RedirectEquals)
FCFuncEnd()
#endif // ifdef FEATURE_COMINTEROP
+
+FCFuncStart(gRuntimeImportsFuncs)
+ QCFuncElement("RhZeroMemory", MemoryNative::Clear)
+ FCFuncElement("RhBulkMoveWithWriteBarrier", MemoryNative::BulkMoveWithWriteBarrier)
+FCFuncEnd()
+
FCFuncStart(gWeakReferenceFuncs)
FCFuncElement("Create", WeakReferenceNative::Create)
FCFuncElement("Finalize", WeakReferenceNative::Finalize)
@@ -1751,50 +1343,23 @@ FCFuncEnd()
FCClassElement("AppDomain", "System", gAppDomainFuncs)
FCClassElement("AppDomainManager", "System", gAppDomainManagerFuncs)
-#ifdef FEATURE_FUSION
-FCClassElement("AppDomainSetup", "System", gAppDomainSetupFuncs)
-#endif // FEATURE_FUSION
FCClassElement("ArgIterator", "System", gVarArgFuncs)
FCClassElement("Array", "System", gArrayFuncs)
FCClassElement("ArrayWithOffset", "System.Runtime.InteropServices", gArrayWithOffsetFuncs)
FCClassElement("AssemblyBuilder", "System.Reflection.Emit", gAssemblyBuilderFuncs)
-#ifdef FEATURE_CORECLR
FCClassElement("AssemblyExtensions", "System.Reflection.Metadata", gAssemblyExtensionsFuncs)
-#endif
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
FCClassElement("AssemblyLoadContext", "System.Runtime.Loader", gAssemblyLoadContextFuncs)
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
FCClassElement("AssemblyName", "System.Reflection", gAssemblyNameFuncs)
FCClassElement("Assert", "System.Diagnostics", gDiagnosticsAssert)
FCClassElement("BCLDebug", "System", gBCLDebugFuncs)
FCClassElement("Buffer", "System", gBufferFuncs)
-#ifndef FEATURE_CORECLR
-// Since the 2nd letter of the classname is capital, we need to sort this before all class names
-// that start with Cx where x is any small letter (strcmp is used for verification).
-FCClassElement("CLRConfig", "System", gCLRConfigFuncs)
-#endif // FEATURE_CORECLR
-#if !defined(FEATURE_COREFX_GLOBALIZATION)
-FCClassElement("CalendarData", "System.Globalization", gCalendarDataFuncs)
-#endif // !defined(FEATURE_COREFX_GLOBALIZATION)
-#ifndef FEATURE_CORECLR
-FCClassElement("ChannelServices", "System.Runtime.Remoting.Channels", gChannelServicesFuncs)
-#endif // FEATURE_CORECLR
+FCClassElement("CLRConfig", "System", gClrConfig)
FCClassElement("CompareInfo", "System.Globalization", gCompareInfoFuncs)
FCClassElement("CompatibilitySwitch", "System.Runtime.Versioning", gCompatibilitySwitchFuncs)
-#ifndef FEATURE_CORECLR
-FCClassElement("Console", "System", gConsoleFuncs)
-#endif // ifndef FEATURE_CORECLR
-#ifdef FEATURE_REMOTING
-FCClassElement("Context", "System.Runtime.Remoting.Contexts", gContextFuncs)
-#endif
FCClassElement("CriticalHandle", "System.Runtime.InteropServices", gCriticalHandleFuncs)
-#if !defined(FEATURE_COREFX_GLOBALIZATION)
-FCClassElement("CultureData", "System.Globalization", gCultureDataFuncs)
-FCClassElement("CultureInfo", "System.Globalization", gCultureInfoFuncs)
-#endif
FCClassElement("Currency", "System", gCurrencyFuncs)
FCClassElement("CustomAttribute", "System.Reflection", gCOMCustomAttributeFuncs)
FCClassElement("CustomAttributeEncodedArgument", "System.Reflection", gCustomAttributeEncodedArgument)
@@ -1814,9 +1379,6 @@ FCClassElement("Environment", "System", gEnvironmentFuncs)
FCClassElement("EventArgsMarshaler", "System.StubHelpers", gEventArgsMarshalerFuncs)
#endif // FEATURE_COMINTEROP
FCClassElement("Exception", "System", gExceptionFuncs)
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
-FCClassElement("ExtensibleClassFactory", "System.Runtime.InteropServices", gExtensibleClassFactoryFuncs)
-#endif
FCClassElement("FileLoadException", "System.IO", gFileLoadExceptionFuncs)
FCClassElement("FormatterServices", "System.Runtime.Serialization", gSerializationFuncs)
FCClassElement("GC", "System", gGCInterfaceFuncs)
@@ -1839,22 +1401,13 @@ FCClassElement("LoaderAllocatorScout", "System.Reflection", gLoaderAllocatorFunc
FCClassElement("Log", "System.Diagnostics", gDiagnosticsLog)
FCClassElement("ManifestBasedResourceGroveler", "System.Resources", gManifestBasedResourceGrovelerFuncs)
FCClassElement("Marshal", "System.Runtime.InteropServices", gInteropMarshalFuncs)
-#ifdef FEATURE_REMOTING
-FCClassElement("MarshalByRefObject", "System", gMarshalByRefFuncs)
-#endif
FCClassElement("Math", "System", gMathFuncs)
FCClassElement("MathF", "System", gMathFFuncs)
#ifdef MDA_SUPPORTED
FCClassElement("Mda", "System", gMda)
#endif
FCClassElement("MemoryFailPoint", "System.Runtime", gMemoryFailPointFuncs)
-#ifdef FEATURE_REMOTING
-FCClassElement("Message", "System.Runtime.Remoting.Messaging", gMessageFuncs)
-#endif
FCClassElement("MetadataImport", "System.Reflection", gMetaDataImport)
-#ifdef FEATURE_METHOD_RENTAL
-FCClassElement("MethodRental", "System.Reflection.Emit", gCOMMethodRental)
-#endif // FEATURE_METHOD_RENTAL
FCClassElement("MissingMemberException", "System", gMissingMemberExceptionFuncs)
#ifdef FEATURE_COMINTEROP
FCClassElement("MngdHiddenLengthArrayMarshaler", "System.StubHelpers", gMngdHiddenLengthArrayMarshalerFuncs)
@@ -1867,9 +1420,6 @@ FCClassElement("MngdSafeArrayMarshaler", "System.StubHelpers", gMngdSafeArrayMar
FCClassElement("ModuleBuilder", "System.Reflection.Emit", gCOMModuleBuilderFuncs)
FCClassElement("ModuleHandle", "System", gCOMModuleHandleFuncs)
FCClassElement("Monitor", "System.Threading", gMonitorFuncs)
-#ifndef FEATURE_COREFX_GLOBALIZATION
-FCClassElement("Normalization", "System.Text", gNormalizationFuncs)
-#endif // FEATURE_COREFX_GLOBALIZATION
FCClassElement("Number", "System", gNumberFuncs)
#ifdef FEATURE_COMINTEROP
FCClassElement("OAVariantLib", "Microsoft.Win32", gOAVariantFuncs)
@@ -1880,26 +1430,9 @@ FCClassElement("ObjectMarshaler", "System.StubHelpers", gObjectMarshalerFuncs)
#endif
FCClassElement("OverlappedData", "System.Threading", gOverlappedFuncs)
FCClassElement("ParseNumbers", "System", gParseNumbersFuncs)
-#ifndef FEATURE_CORECLR
-FCClassElement("PasswordDeriveBytes", "System.Security.Cryptography", gPasswordDeriveBytesFuncs)
-#endif
-#if defined(FEATURE_MULTICOREJIT) && !defined(FEATURE_CORECLR)
-FCClassElement("ProfileOptimization", "System.Runtime", gProfileOptimizationFuncs)
-#endif // defined(FEATURE_MULTICOREJIT) && !defined(FEATURE_CORECLR)
-#ifdef FEATURE_CORECLR
FCClassElement("PunkSafeHandle", "System.Reflection.Emit", gSymWrapperCodePunkSafeHandleFuncs)
-#endif
-#ifndef FEATURE_CORECLR
-FCClassElement("RNGCryptoServiceProvider", "System.Security.Cryptography", gRNGCryptoServiceProviderFuncs)
-#endif
-#ifdef FEATURE_RWLOCK
-FCClassElement("ReaderWriterLock", "System.Threading", gRWLockFuncs)
-#endif // FEATURE_RWLOCK
-#ifdef FEATURE_REMOTING
-FCClassElement("RealProxy", "System.Runtime.Remoting.Proxies", gRealProxyFuncs)
-#endif
FCClassElement("RegisteredWaitHandleSafe", "System.Threading", gRegisteredWaitHandleFuncs)
#ifdef FEATURE_COMINTEROP
#ifdef FEATURE_COMINTEROP_MANAGED_ACTIVATION
@@ -1907,9 +1440,6 @@ FCClassElement("RegistrationServices", "System.Runtime.InteropServices", gRegist
#endif // FEATURE_COMINTEROP_MANAGED_ACTIVATION
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_REMOTING
-FCClassElement("RemotingServices", "System.Runtime.Remoting", gRemotingFuncs)
-#endif
FCClassElement("RtFieldInfo", "System.Reflection", gRuntimeFieldInfoFuncs)
FCClassElement("RuntimeAssembly", "System.Reflection", gAssemblyFuncs)
#ifdef FEATURE_COMINTEROP
@@ -1918,6 +1448,7 @@ FCClassElement("RuntimeClass", "System.Runtime.InteropServices.WindowsRuntime",
FCClassElement("RuntimeEnvironment", "System.Runtime.InteropServices", gRuntimeEnvironmentFuncs)
FCClassElement("RuntimeFieldHandle", "System", gCOMFieldHandleNewFuncs)
FCClassElement("RuntimeHelpers", "System.Runtime.CompilerServices", gCompilerFuncs)
+FCClassElement("RuntimeImports", "System.Runtime", gRuntimeImportsFuncs)
FCClassElement("RuntimeMethodHandle", "System", gRuntimeMethodHandle)
FCClassElement("RuntimeModule", "System.Reflection", gCOMModuleFuncs)
FCClassElement("RuntimeThread", "Internal.Runtime.Augments", gRuntimeThreadFuncs)
@@ -1928,34 +1459,17 @@ FCClassElement("SafeHandle", "System.Runtime.InteropServices", gSafeHandleFuncs)
FCClassElement("SafeTypeNameParserHandle", "System", gSafeTypeNameParserHandle)
FCClassElement("Signature", "System", gSignatureNative)
-#ifndef FEATURE_CORECLR
-FCClassElement("SizedReference", "System", gSizedRefHandleFuncs)
-#endif // !FEATURE_CORECLR
-#ifdef FEATURE_REMOTING
-FCClassElement("StackBuilderSink", "System.Runtime.Remoting.Messaging", gStackBuilderSinkFuncs)
-#endif
FCClassElement("StackTrace", "System.Diagnostics", gDiagnosticsStackTrace)
FCClassElement("Stream", "System.IO", gStreamFuncs)
FCClassElement("String", "System", gStringFuncs)
FCClassElement("StringBuilder", "System.Text", gStringBufferFuncs)
FCClassElement("StubHelpers", "System.StubHelpers", gStubHelperFuncs)
-#if defined(FEATURE_SYNCHRONIZATIONCONTEXT_WAIT) || defined(FEATURE_APPX)
FCClassElement("SynchronizationContext", "System.Threading", gContextSynchronizationFuncs)
-#endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT || FEATURE_APPX
-#if !defined(FEATURE_COREFX_GLOBALIZATION)
-FCClassElement("TextInfo", "System.Globalization", gTextInfoFuncs)
-#endif // !defined(FEATURE_COREFX_GLOBALIZATION)
FCClassElement("Thread", "System.Threading", gThreadFuncs)
FCClassElement("ThreadPool", "System.Threading", gThreadPoolFuncs)
-#ifndef FEATURE_CORECLR
-FCClassElement("TimeSpan", "System", gTimeSpanFuncs)
-#endif // !FEATURE_CORECLR
FCClassElement("TimerQueue", "System.Threading", gTimerFuncs)
FCClassElement("Type", "System", gSystem_Type)
FCClassElement("TypeBuilder", "System.Reflection.Emit", gCOMClassWriter)
-#ifdef FEATURE_COMINTEROP_TLB_SUPPORT
-FCClassElement("TypeLibConverter", "System.Runtime.InteropServices", gTypeLibConverterFuncs)
-#endif
FCClassElement("TypeLoadException", "System", gTypeLoadExceptionFuncs)
FCClassElement("TypeNameBuilder", "System.Reflection.Emit", gTypeNameBuilder)
FCClassElement("TypeNameParser", "System", gTypeNameParser)
@@ -1982,13 +1496,7 @@ FCClassElement("WinRTTypeNameConverter", "System.StubHelpers", gWinRTTypeNameCon
FCClassElement("WindowsRuntimeBufferHelper", "System.Runtime.InteropServices.WindowsRuntime", gWindowsRuntimeBufferHelperFuncs)
#endif
-#ifndef FEATURE_CORECLR
-FCClassElement("WindowsRuntimeDesignerContext", "System.Runtime.DesignerServices", gWindowsRuntimeContextFuncs)
-#endif
-#if defined(FEATURE_COMINTEROP) && defined(FEATURE_REFLECTION_ONLY_LOAD)
-FCClassElement("WindowsRuntimeMetadata", "System.Runtime.InteropServices.WindowsRuntime", gWindowsRuntimeMetadata)
-#endif
#if defined(FEATURE_EVENTSOURCE_XPLAT)
FCClassElement("XplatEventLogger", "System.Diagnostics.Tracing", gEventLogger)
diff --git a/src/vm/eeconfig.cpp b/src/vm/eeconfig.cpp
index 91b9e64a78..812d1df671 100644
--- a/src/vm/eeconfig.cpp
+++ b/src/vm/eeconfig.cpp
@@ -16,26 +16,13 @@
#endif
#include "eeconfig.h"
#include "method.hpp"
-#ifndef FEATURE_CORECLR
-#include <xmlparser.h>
-#include <mscorcfg.h>
-#include "eeconfigfactory.h"
-#endif
-#ifdef FEATURE_FUSION
-#include "fusionsetup.h"
-#endif
#include "eventtrace.h"
#include "eehash.h"
#include "eemessagebox.h"
#include "corhost.h"
#include "regex_util.h"
#include "clr/fs/path.h"
-#ifdef FEATURE_WIN_DB_APPCOMPAT
-#include "QuirksApi.h"
-#endif
-#ifdef FEATURE_CORECLR
#include "configuration.h"
-#endif
using namespace clr;
@@ -179,28 +166,6 @@ void *EEConfig::operator new(size_t size)
RETURN g_EEConfigMemory;
}
-#ifdef FEATURE_WIN_DB_APPCOMPAT
-void InitWinAppCompatDBApis()
-{
- STANDARD_VM_CONTRACT;
-
- HMODULE hMod = WszLoadLibraryEx(QUIRKSAPI_DLL, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
-
- PFN_CptQuirkIsEnabled3 pfnIsQuirkEnabled = NULL;
- PFN_CptQuirkGetData2 pfnQuirkGetData = NULL;
-
- if(hMod != NULL)
- {
- pfnIsQuirkEnabled = (PFN_CptQuirkIsEnabled3)GetProcAddress(hMod, "QuirkIsEnabled3");
- pfnQuirkGetData = (PFN_CptQuirkGetData2)GetProcAddress(hMod, "QuirkGetData2");
- }
-
- if(pfnIsQuirkEnabled != NULL && pfnQuirkGetData != NULL)
- {
- CLRConfig::RegisterWinDbQuirkApis(pfnIsQuirkEnabled,pfnQuirkGetData);
- }
-}
-#endif // FEATURE_WIN_DB_APPCOMPAT
/**************************************************************/
HRESULT EEConfig::Init()
@@ -294,9 +259,7 @@ HRESULT EEConfig::Init()
INDEBUG(fStressLog = true;)
-#ifdef FEATURE_CORECLR
fVerifyAllOnLoad = false;
-#endif
#ifdef _DEBUG
fExpandAllOnLoad = false;
fDebuggable = false;
@@ -439,15 +402,16 @@ HRESULT EEConfig::Init()
#if defined(_DEBUG)
bDiagnosticSuspend = false;
#endif
+
+#if defined(FEATURE_TIERED_COMPILATION)
+ fTieredCompilation = false;
+#endif
// After initialization, register the code:#GetConfigValueCallback method with code:CLRConfig to let
// CLRConfig access config files. This is needed because CLRConfig lives outside the VM and can't
// statically link to EEConfig.
CLRConfig::RegisterGetConfigValueCallback(&GetConfigValueCallback);
-#ifdef FEATURE_WIN_DB_APPCOMPAT
- InitWinAppCompatDBApis();
-#endif // FEATURE_WIN_DB_APPCOMPAT
return S_OK;
}
@@ -798,14 +762,12 @@ HRESULT EEConfig::sync()
}
bool gcConcurrentWasForced = false;
-#ifdef FEATURE_CORECLR
// The CLRConfig value for UNSUPPORTED_gcConcurrent defaults to -1, and treats any
// positive value as 'forcing' concurrent GC to be on. Because the standard logic
// for mapping a DWORD CLRConfig to a boolean configuration treats -1 as true (just
// like any other nonzero value), we will explicitly check the DWORD later if this
// check returns false.
gcConcurrentWasForced = Configuration::GetKnobBooleanValue(W("System.GC.Concurrent"), false);
-#endif
int gcConcurrentConfigVal = 0;
if (!gcConcurrentWasForced)
@@ -975,21 +937,12 @@ HRESULT EEConfig::sync()
#endif
iGCForceCompact = GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_gcForceCompact, iGCForceCompact);
-#ifdef FEATURE_CORECLR
iGCNoAffinitize = Configuration::GetKnobBooleanValue(W("System.GC.NoAffinitize"),
CLRConfig::UNSUPPORTED_GCNoAffinitize);
iGCHeapCount = Configuration::GetKnobDWORDValue(W("System.GC.HeapCount"), CLRConfig::UNSUPPORTED_GCHeapCount);
-#else
- iGCNoAffinitize = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_GCNoAffinitize);
- iGCHeapCount = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_GCHeapCount);
-#endif
fStressLog = GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLog, fStressLog) != 0;
fForceEnc = GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_ForceEnc, fForceEnc) != 0;
-
-#ifdef STRESS_THREAD
- dwStressThreadCount = GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_StressThreadCount, dwStressThreadCount);
-#endif
iRequireZaps = RequireZapsType(GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_ZapRequire, iRequireZaps));
if (IsCompilationProcess() || iRequireZaps >= REQUIRE_ZAPS_COUNT)
@@ -1084,32 +1037,9 @@ HRESULT EEConfig::sync()
g_IBCLogger.DisableAllInstr();
#endif
-#ifdef FEATURE_FUSION
- IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_ZapSet, (LPWSTR*)&pZapSet));
-
- m_fFreepZapSet = true;
-
- if (pZapSet == NULL)
- {
- m_fFreepZapSet = false;
- pZapSet = W("");
- }
- if (wcslen(pZapSet) > 3)
- {
- _ASSERTE(!"Zap Set String must be less than 3 chars");
- delete[] pZapSet;
- m_fFreepZapSet = false;
- pZapSet = W("");
- }
-
- fNgenBindOptimizeNonGac = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_NgenBind_OptimizeNonGac) != 0;
-#endif
dwDisableStackwalkCache = GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_DisableStackwalkCache, dwDisableStackwalkCache);
-#ifdef FEATURE_REMOTING
- fUseNewCrossDomainRemoting = GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_UseNewCrossDomainRemoting, fUseNewCrossDomainRemoting);
-#endif
#ifdef _DEBUG
IfFailRet (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_BreakOnClassLoad, (LPWSTR*) &pszBreakOnClassLoad));
@@ -1137,59 +1067,6 @@ HRESULT EEConfig::sync()
fPInvokeRestoreEsp = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Jit_NetFx40PInvokeStackResilience);
#endif
-#ifndef FEATURE_CORECLR
- // These two values respect the Shim's policy of favoring config files over registry settings.
- fLegacyNullReferenceExceptionPolicy = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::UNSUPPORTED_legacyNullReferenceExceptionPolicy,
- fLegacyNullReferenceExceptionPolicy) != 0);
- fLegacyUnhandledExceptionPolicy = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::UNSUPPORTED_legacyUnhandledExceptionPolicy,
- fLegacyUnhandledExceptionPolicy) != 0);
-
-#ifdef FEATURE_CORRUPTING_EXCEPTIONS
- // Check if the user has overriden how Corrupted State Exceptions (CSE) will be handled. If the
- // <runtime> section of app.exe.config has "legacyCorruptedStateExceptionsPolicy" set to 1, then
- // V4 runtime will treat CSE in the same fashion as V2.
- fLegacyCorruptedStateExceptionsPolicy = (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_legacyCorruptedStateExceptionsPolicy) != 0);
-#endif // FEATURE_CORRUPTING_EXCEPTIONS
-
- fLegacyVirtualMethodCallVerification = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_legacyVirtualMethodCallVerification,
- fLegacyVirtualMethodCallVerification,
- REGUTIL::COR_CONFIG_ALL, TRUE,
- CONFIG_SYSTEMONLY) != 0);
-
- fLegacyApartmentInitPolicy = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_legacyApartmentInitPolicy,
- fLegacyApartmentInitPolicy) != 0);
-
- fLegacyComHierarchyVisibility = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_legacyComHierarchyVisibility,
- fLegacyComHierarchyVisibility) != 0);
-
- fLegacyComVTableLayout = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_legacyComVTableLayout,
- fLegacyComVTableLayout) != 0);
- fNewComVTableLayout = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_newComVTableLayout,
- fNewComVTableLayout) != 0);
-
- if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_legacyImpersonationPolicy) != 0)
- iImpersonationPolicy = IMP_NOFLOW;
- else if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_alwaysFlowImpersonationPolicy) != 0)
- iImpersonationPolicy = IMP_ALWAYSFLOW;
-
- fLegacyLoadMscorsnOnStartup = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::UNSUPPORTED_legacyLoadMscorsnOnStartup,
- fLegacyLoadMscorsnOnStartup) != 0);
- fBypassStrongNameVerification = (GetConfigDWORDFavoringConfigFile_DontUse_(W("bypassTrustedAppStrongNames"), fBypassStrongNameVerification) != 0) && // App opted in
- (GetConfigDWORD_DontUse_(SN_CONFIG_BYPASS_POLICY_W, TRUE, REGUTIL::COR_CONFIG_MACHINE) != 0); // And the machine policy allows for bypass
- fGeneratePublisherEvidence = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_generatePublisherEvidence, fGeneratePublisherEvidence) != 0);
- fEnforceFIPSPolicy = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_enforceFIPSPolicy, fEnforceFIPSPolicy) != 0);
- fLegacyHMACMode = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_legacyHMACMode, fLegacyHMACMode) != 0);
-
- fCacheBindingFailures = !(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_disableCachingBindingFailures));
- fUseLegacyIdentityFormat =
-#ifdef FEATURE_APPX
- AppX::IsAppXProcess() ||
-#endif
- (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_useLegacyIdentityFormat) != 0);
- fDisableFusionUpdatesFromADManager = (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_disableFusionUpdatesFromADManager) != 0);
- fDisableCommitThreadStack = (GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_disableCommitThreadStack, fDisableCommitThreadStack) != 0);
- fProbeForStackOverflow = !(CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_disableStackOverflowProbing));
-#endif // FEATURE_CORECLR
#ifdef _DEBUG
fDebuggable = (GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_JitDebuggable, fDebuggable) != 0);
@@ -1264,26 +1141,13 @@ HRESULT EEConfig::sync()
fEnableRCWCleanupOnSTAShutdown = (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_EnableRCWCleanupOnSTAShutdown) != 0);
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_CORECLR
//Eager verification of all assemblies.
fVerifyAllOnLoad = (GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_VerifyAllOnLoad, fVerifyAllOnLoad) != 0);
-#endif //FEATURE_CORECLR
#ifdef _DEBUG
fExpandAllOnLoad = (GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_ExpandAllOnLoad, fExpandAllOnLoad) != 0);
#endif //_DEBUG
-#ifdef FEATURE_FUSION
- if(g_pConfig) {
- LPCWSTR result = NULL;
- if(SUCCEEDED(g_pConfig->GetConfiguration_DontUse_(CLRConfig::EXTERNAL_developerInstallation, CONFIG_SYSTEM, &result)) && result)
- {
- // <TODO> CTS, add addtional checks to ensure this is an SDK installation </TODO>
- if(SString::_wcsicmp(result, W("true")) == 0)
- m_fDeveloperInstallation = true;
- }
- }
-#endif
#ifdef AD_NO_UNLOAD
fAppDomainUnload = (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_AppDomainNoUnload) == 0);
@@ -1367,12 +1231,6 @@ HRESULT EEConfig::sync()
m_fInteropLogArguments = (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_InteropLogArguments) != 0);
#ifdef FEATURE_PREJIT
-#ifndef FEATURE_CORECLR
- DWORD iNgenHardBindOverride = GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_HardPrejitEnabled, iNgenHardBind);
- _ASSERTE(iNgenHardBindOverride < NGEN_HARD_BIND_COUNT);
- if (iNgenHardBindOverride < NGEN_HARD_BIND_COUNT)
- iNgenHardBind = NgenHardBindType(iNgenHardBindOverride);
-#endif
#ifdef _DEBUG
dwNgenForceFailureMask = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NgenForceFailureMask);
dwNgenForceFailureCount = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NgenForceFailureCount);
@@ -1411,17 +1269,6 @@ HRESULT EEConfig::sync()
MethodTable::AllowParentMethodDataCopy();
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- // Get the symbol reading policy setting which is maintained by the hosting API (since it can be overridden there)
- const DWORD notSetToken = 0xFFFFFFFF;
- DWORD iSymbolReadingConfig = GetConfigDWORDFavoringConfigFile_DontUse_(CLRConfig::EXTERNAL_SymbolReadingPolicy, notSetToken );
- if( iSymbolReadingConfig != notSetToken &&
- iSymbolReadingConfig <= eSymbolReadingFullTrustOnly )
- {
- ESymbolReadingPolicy policy = ESymbolReadingPolicy(iSymbolReadingConfig);
- CCLRDebugManager::SetSymbolReadingPolicy( policy, eSymbolReadingSetByConfig );
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#if defined(_DEBUG) && defined(_TARGET_AMD64_)
m_cGenerateLongJumpDispatchStubRatio = GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_GenerateLongJumpDispatchStubRatio,
@@ -1434,8 +1281,8 @@ HRESULT EEConfig::sync()
dwSleepOnExit = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_SleepOnExit);
-#ifdef FEATURE_APPX
- dwWindows8ProfileAPICheckFlag = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_Windows8ProfileAPICheckFlag);
+#if defined(FEATURE_TIERED_COMPILATION)
+ fTieredCompilation = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TieredCompilation) != 0;
#endif
return hr;
@@ -1565,305 +1412,6 @@ SIZE_T EEConfig::GetSizeOfProcessBindingFile()
return g_dwHostConfigFile;
}
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE) // unimpactful install --> no config files
-
-/**************************************************************/
-static void MessageBoxParseError(HRESULT hr, __in_z LPCWSTR wszFile);
-
-#define IfFailParseError(FILE, ISAPPCONFIG, ...) \
- do \
- { \
- /* On error, always show an error dialog and return an error result when process is immersive; */ \
- /* otherwise show dialog (conditionally for App config) and swallow error. */ \
- if (FAILED(hr = (__VA_ARGS__)) && (!(ISAPPCONFIG) || AppX::IsAppXProcess() || GetConfigDWORDInternal_DontUse_(CLRConfig::EXTERNAL_NotifyBadAppCfg,false))) \
- { \
- MessageBoxParseError(hr, FILE); \
- if (AppX::IsAppXProcess()) \
- { /* Fail on bad config in AppX process. */ \
- return hr; \
- } \
- else \
- { \
- hr = S_FALSE; \
- } \
- } \
- } while (false)
-
-/**************************************************************/
-HRESULT EEConfig::SetupConfiguration()
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- } CONTRACTL_END;
-
- WCHAR version[_MAX_PATH];
- DWORD dwVersion = _MAX_PATH;
-
- HRESULT hr = S_OK;
- // Get the version location
- IfFailRet(GetCORVersionInternal(version, _MAX_PATH, & dwVersion));
-
- // See if the environment has specified an XML file
- NewArrayHolder<WCHAR> file(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CONFIG));
- if(file != NULL)
- {
- IfFailParseError(file, false, AppendConfigurationFile(file, version));
- }
-
- // We need to read configuration information from 3 sources... the app config file, the
- // host supplied config file, and the machine.config file. The order in which we
- // read them are very import. If the different config sources specify the same config
- // setting, we will use the setting of the first one read.
- //
- // In the pecking order, machine.config should always have the final say. The host supplied config
- // file should follow, and lastly, the app config file.
- //
- // Note: the order we read them is not the order they are published. Need to read the AppConfig
- // first so that we can decide if we should import machine.config (yes in Classic, typically no
- // in AppX). We still publish in the order required as described above.
-
- enum
- {
- MachineConfig = 0,
- HostConfig = 1,
- AppConfig = 2,
- NumConfig = 3,
- };
-
- ConfigSource * rgpSources[NumConfig] = { nullptr };
-
- // Create ConfigSource objects for all config files.
- for (size_t i = 0; i < NumConfig; ++i)
- {
- rgpSources[i] = new (nothrow) ConfigSource();
- if (rgpSources[i] == NULL)
- {
- while (i != 0)
- {
- --i;
- delete rgpSources[i];
- rgpSources[i] = nullptr;
- }
- return E_OUTOFMEMORY;
- }
- }
-
- // Publish ConfigSource objects in required order. It's ok that the file contents are imported below,
- // since we're in EEStartup and this data cannot be accessed by any other threads yet.
- for (size_t i = 0; i < NumConfig; ++i)
- {
- m_Configuration.Append(rgpSources[i]);
- }
-
- // ----------------------------------------------------
- // Import the app.config file, or in the case of an
- // AppX process check to make sure no app.config file
- // exists unless launched with AO_DESIGNMODE.
- // ----------------------------------------------------
-
- do
- {
- size_t cchProcExe=0;
- PathString wzProcExe;
- EX_TRY
- {
-
-
-
- // Get name of file used to create process
- if (g_pCachedModuleFileName)
- {
- wzProcExe.Set(g_pCachedModuleFileName);
- cchProcExe = wzProcExe.GetCount();
- }
- else
- {
- cchProcExe = WszGetModuleFileName(NULL, wzProcExe);
-
- if (cchProcExe == 0)
- {
- hr = HRESULT_FROM_GetLastError();
- break;
- }
- }
-
- if (cchProcExe != 0)
- {
- wzProcExe.Append(CONFIGURATION_EXTENSION);
-
- if (AppX::IsAppXProcess() && !AppX::IsAppXDesignMode())
- {
- if (clr::fs::Path::Exists(wzProcExe))
- {
- hr = CLR_E_APP_CONFIG_NOT_ALLOWED_IN_APPX_PROCESS;
- break;
- }
- }
- }
- }
- EX_CATCH_HRESULT(hr);
- if (cchProcExe != 0)
- {
- IfFailParseError(wzProcExe, true, AppendConfigurationFile(wzProcExe, version));
-
- // We really should return a failure hresult if the app config file is bad, but that
- // would be a breaking change. Not sure if it's worth it yet.
- hr = S_OK;
- break;
- }
- } while (false);
-
-
- if (hr != S_OK)
- return hr;
- // ----------------------------------------------------
- // Import machine.config, if needed.
- // ----------------------------------------------------
- if (!AppX::IsAppXProcess() || AppX::IsAppXDesignMode())
- {
- WCHAR wzSystemDir[_MAX_PATH];
- DWORD cchSystemDir = COUNTOF(wzSystemDir);
- IfFailRet(GetInternalSystemDirectory(wzSystemDir, &cchSystemDir));
-
- // cchSystemDir already includes the NULL
- if(cchSystemDir + StrLen(MACHINE_CONFIGURATION_FILE) <= _MAX_PATH)
- {
- IfFailRet(StringCchCat(wzSystemDir, COUNTOF(wzSystemDir), MACHINE_CONFIGURATION_FILE));
-
- // CLR_STARTUP_OPT:
- // The machine.config file can be very large. We cannot afford
- // to parse all of it at CLR startup time.
- //
- // Accordingly, we instruct the XML parser to stop parsing the
- // machine.config file when it sees the end of the
- // <runtime>...</runtime> section that holds our data (if any).
- //
- // By construction, this section is now placed near the top
- // of machine.config.
- //
- IfFailParseError(wzSystemDir, false, ImportConfigurationFile(
- rgpSources[MachineConfig]->Table(), wzSystemDir, version, stopAfterRuntimeSection));
-
- if (hr == S_FALSE) // means that we couldn't find machine.config
- hr = S_OK;
- }
- }
-
- // ----------------------------------------------------
- // Import the host supplied config file, if needed.
- // ----------------------------------------------------
- // Cannot host an AppX managed process, so no need to check devModeEnabled.
- if (!AppX::IsAppXProcess())
- {
- if (GetProcessBindingFile() != NULL && GetSizeOfProcessBindingFile() > 0)
- {
- IfFailRet(ImportConfigurationFile(
- rgpSources[HostConfig]->Table(), GetProcessBindingFile(), version));
- }
- }
-
- return hr;
-}
-
-//
-// There was an error 'hr' parsing the file 'wszFile'.
-// Pop up a MessageBox reporting the error, unless the config setting
-// 'NoGuiFromShim' is in effect.
-//
-static void MessageBoxParseError(HRESULT hr, __in_z LPCWSTR wszFile)
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(FAILED(hr));
- } CONTRACTL_END;
-
- if (!REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_NoGuiFromShim, FALSE))
- {
- EEMessageBoxCatastrophic(IDS_EE_CONFIGPARSER_ERROR, IDS_EE_CONFIGPARSER_ERROR_CAPTION, wszFile, hr);
- }
-}
-
-/**************************************************************/
-
-STDAPI GetXMLObjectEx(IXMLParser **ppv);
-
-HRESULT EEConfig::ImportConfigurationFile(
- ConfigStringHashtable* pTable,
- LPCWSTR pszFileName,
- LPCWSTR version,
- ParseCtl parseCtl)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pTable));
- PRECONDITION(CheckPointer(pszFileName));
- PRECONDITION(CheckPointer(version));
- INJECT_FAULT(return E_OUTOFMEMORY);
- } CONTRACTL_END;
-
- NonVMComHolder<IXMLParser> pIXMLParser(NULL);
- NonVMComHolder<IStream> pFile(NULL);
- NonVMComHolder<EEConfigFactory> factory(NULL);
-
- HRESULT hr = CreateConfigStreamHelper(pszFileName, &pFile);
- if(FAILED(hr)) goto Exit;
-
- hr = GetXMLObjectEx(&pIXMLParser);
- if(FAILED(hr)) goto Exit;
-
- factory = new (nothrow) EEConfigFactory(pTable, version, parseCtl);
-
- if ( ! factory) {
- hr = E_OUTOFMEMORY;
- goto Exit;
- }
- factory->AddRef(); // RefCount = 1
-
-
- hr = pIXMLParser->SetInput(pFile); // filestream's RefCount=2
- if ( ! SUCCEEDED(hr))
- goto Exit;
-
- hr = pIXMLParser->SetFactory(factory); // factory's RefCount=2
- if ( ! SUCCEEDED(hr))
- goto Exit;
-
- {
- CONTRACT_VIOLATION(ThrowsViolation); // @todo: Run() throws!
- hr = pIXMLParser->Run(-1);
- }
-
-Exit:
- if (hr == (HRESULT) XML_E_MISSINGROOT)
- hr = S_OK;
- else if (Assembly::FileNotFound(hr))
- hr = S_FALSE;
-
- return hr;
-}
-
-HRESULT EEConfig::AppendConfigurationFile(
- LPCWSTR pszFileName,
- LPCWSTR version,
- ParseCtl parseCtl)
-{
- LIMITED_METHOD_CONTRACT;
- HRESULT hr = S_OK;
-
- ConfigStringHashtable* pTable = m_Configuration.Append();
- IfNullRet(pTable);
-
- return ImportConfigurationFile(pTable, pszFileName, version, parseCtl);
-}
-
-
-#endif // FEATURE_CORECLR && !CROSSGEN_COMPILE
bool EEConfig::RequireZap(LPCUTF8 assemblyName) const
{
diff --git a/src/vm/eeconfig.h b/src/vm/eeconfig.h
index 338a97268b..e97385e3da 100644
--- a/src/vm/eeconfig.h
+++ b/src/vm/eeconfig.h
@@ -294,6 +294,11 @@ public:
bool AddRejitNops(void) const {LIMITED_METHOD_DAC_CONTRACT; return fAddRejitNops; }
bool JitMinOpts(void) const {LIMITED_METHOD_CONTRACT; return fJitMinOpts; }
+ // Tiered Compilation config
+#if defined(FEATURE_TIERED_COMPILATION)
+ bool TieredCompilation(void) const {LIMITED_METHOD_CONTRACT; return fTieredCompilation; }
+#endif
+
BOOL PInvokeRestoreEsp(BOOL fDefault) const
{
LIMITED_METHOD_CONTRACT;
@@ -510,9 +515,7 @@ public:
}
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_CORECLR
bool VerifyModulesOnLoad(void) const { LIMITED_METHOD_CONTRACT; return fVerifyAllOnLoad; }
-#endif
#ifdef _DEBUG
bool ExpandModulesOnLoad(void) const { LIMITED_METHOD_CONTRACT; return fExpandAllOnLoad; }
#endif //_DEBUG
@@ -710,12 +713,6 @@ public:
&& pSkipGCCoverageList->IsInList(assemblyName));}
#endif
-
- // thread stress: number of threads to run
-#ifdef STRESS_THREAD
- DWORD GetStressThreadCount () const {LIMITED_METHOD_CONTRACT; return dwStressThreadCount;}
-#endif
-
#ifdef _DEBUG
inline DWORD FastGCStressLevel() const
{LIMITED_METHOD_CONTRACT; return iFastGCStress;}
@@ -1008,9 +1005,7 @@ private: //----------------------------------------------------------------
bool m_fDeveloperInstallation; // We are on a developers machine
bool fAppDomainUnload; // Enable appdomain unloading
-#ifdef FEATURE_CORECLR
bool fVerifyAllOnLoad; // True if we want to verify all methods in an assembly at load time.
-#endif //FEATURE_CORECLR
DWORD dwADURetryCount;
@@ -1095,10 +1090,6 @@ private: //----------------------------------------------------------------
bool fGCBreakOnOOM;
-#ifdef STRESS_THREAD
- DWORD dwStressThreadCount;
-#endif
-
#ifdef _DEBUG
DWORD iFastGCStress;
LPUTF8 pszGcCoverageOnMethod;
@@ -1196,21 +1187,11 @@ private: //----------------------------------------------------------------
DWORD testThreadAbort;
#endif
-public:
-#ifndef FEATURE_CORECLR // unimpactful install --> no config files
- HRESULT ImportConfigurationFile(
- ConfigStringHashtable* pTable,
- LPCWSTR pszFileName,
- LPCWSTR version,
- ParseCtl parseCtl = parseAll);
-
- HRESULT AppendConfigurationFile(
- LPCWSTR pszFileName,
- LPCWSTR version,
- ParseCtl parseCtl = parseAll);
+#if defined(FEATURE_TIERED_COMPILATION)
+ bool fTieredCompilation;
+#endif
- HRESULT SetupConfiguration();
-#endif // FEATURE_CORECLR
+public:
HRESULT GetConfiguration_DontUse_(__in_z LPCWSTR pKey, ConfigSearch direction, __deref_out_opt LPCWSTR* value);
LPCWSTR GetProcessBindingFile(); // All flavors must support this method
@@ -1280,14 +1261,6 @@ private:
public:
DWORD GetSleepOnExit()
{ return dwSleepOnExit; }
-
-#if FEATURE_APPX
-private:
- DWORD dwWindows8ProfileAPICheckFlag;
-
-public:
- DWORD GetWindows8ProfileAPICheckFlag() { return dwWindows8ProfileAPICheckFlag; }
-#endif
};
diff --git a/src/vm/eeconfigfactory.cpp b/src/vm/eeconfigfactory.cpp
deleted file mode 100644
index a0eb927ce9..0000000000
--- a/src/vm/eeconfigfactory.cpp
+++ /dev/null
@@ -1,398 +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.
-// EEConfigFactory.cpp
-//
-
-//
-// Factory used to with the XML parser to read configuration files
-//
-
-#include "common.h"
-#include "ngenoptout.h"
-#include "eeconfigfactory.h"
-
-
-#define ISWHITE(ch) ((ch) >= 0x09 && (ch) <= 0x0D || (ch) == 0x20)
-
-#define CONST_STRING_AND_LEN(str) str, NumItems(str)-1
-
-
-int EEXMLStringCompare(const WCHAR *pStr1,
- DWORD cchStr1,
- const WCHAR *pStr2,
- DWORD cchStr2)
-{
- LIMITED_METHOD_CONTRACT;
- if (cchStr1 != cchStr2)
- return -1;
-
- return wcsncmp(pStr1, pStr2, cchStr1);
-}// EEXMLStringCompare
-
-
-int EEXMLStringComparei(const WCHAR *pStr1,
- DWORD cchStr1,
- const WCHAR *pStr2,
- DWORD cchStr2)
-{
- WRAPPER_NO_CONTRACT;
- if (cchStr1 != cchStr2)
- return -1;
-
- return SString::_wcsnicmp(pStr1, pStr2, cchStr1);
-}// EEXMLStringCompare
-
-
-
-EEConfigFactory::EEConfigFactory(
- ConfigStringHashtable* pTable,
- LPCWSTR pString,
- ParseCtl parseCtl)
-{
- LIMITED_METHOD_CONTRACT;
- m_pTable = pTable;
- m_pVersion = pString;
- m_dwDepth = 0;
- m_fUnderRuntimeElement = FALSE;
- m_fDeveloperSettings = FALSE;
- m_fVersionedRuntime= FALSE;
- m_fOnEnabledAttribute = FALSE;
- m_fOnValueAttribute = FALSE;
- m_pCurrentRuntimeElement = m_pBuffer;
- m_dwCurrentRuntimeElement = 0;
- m_dwSize = CONFIG_KEY_SIZE;
- m_parseCtl = parseCtl;
- m_pActiveFactory = NULL;
-}
-
-EEConfigFactory::~EEConfigFactory()
-{
- LIMITED_METHOD_CONTRACT;
- DeleteKey();
-}
-
-HRESULT STDMETHODCALLTYPE EEConfigFactory::NotifyEvent(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ XML_NODEFACTORY_EVENT iEvt)
-{
- LIMITED_METHOD_CONTRACT;
- if(iEvt == XMLNF_ENDDOCUMENT) {
- // <TODO> add error handling.</TODO>
- }
- if(m_pActiveFactory != NULL)
- return m_pActiveFactory->NotifyEvent(pSource, iEvt);
-
- return S_OK;
-}
-//---------------------------------------------------------------------------
-HRESULT STDMETHODCALLTYPE EEConfigFactory::BeginChildren(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ XML_NODE_INFO __RPC_FAR *pNodeInfo)
-{
- LIMITED_METHOD_CONTRACT;
-
- m_dwDepth++;
- if(m_pActiveFactory != NULL)
- return m_pActiveFactory->BeginChildren(pSource, pNodeInfo);
- return S_OK;
-
-}
-//---------------------------------------------------------------------------
-HRESULT STDMETHODCALLTYPE EEConfigFactory::EndChildren(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ BOOL fEmptyNode,
- /* [in] */ XML_NODE_INFO __RPC_FAR *pNodeInfo)
-{
- LIMITED_METHOD_CONTRACT;
- if ( fEmptyNode ) {
- m_fDeveloperSettings = FALSE;
- }
- else {
- m_dwDepth--;
- }
-
- if (m_pActiveFactory != NULL)
- {
- HRESULT hr = S_OK;
- IfFailRet(m_pActiveFactory->EndChildren(pSource, fEmptyNode, pNodeInfo));
-
-
- if(m_dwDepth == 2) // when generalizing: use the current active factory depth
- {
- m_pActiveFactory = NULL;
- }
-
- }
-
- if (m_fUnderRuntimeElement && wcscmp(pNodeInfo->pwcText, W("runtime")) == 0) {
- m_fUnderRuntimeElement = FALSE;
- m_fVersionedRuntime = FALSE;
- ClearKey();
- // CLR_STARTUP_OPT:
- // Early out if we only need to read <runtime> section.
- //
- if (m_parseCtl == stopAfterRuntimeSection)
- pSource->Abort(NULL/*unused*/);
- }
-
- return S_OK;
-}
-//---------------------------------------------------------------------------
-HRESULT STDMETHODCALLTYPE EEConfigFactory::CreateNode(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ PVOID pNode,
- /* [in] */ USHORT cNumRecs,
- /* [in] */ XML_NODE_INFO* __RPC_FAR * __RPC_FAR apNodeInfo)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END;
-
- if(m_pActiveFactory != NULL)
- return m_pActiveFactory->CreateNode(pSource, pNode, cNumRecs, apNodeInfo);
-
- if(m_dwDepth > 3)
- {
-
- return S_OK;
- }
-
- HRESULT hr = S_OK;
- DWORD dwStringSize = 0;
- WCHAR* pszString = NULL;
- DWORD i;
- BOOL fRuntimeKey = FALSE;
- BOOL fVersion = FALSE;
-
- for( i = 0; i < cNumRecs; i++) {
- CONTRACT_VIOLATION(ThrowsViolation); // Lots of stuff in here throws!
-
- if(apNodeInfo[i]->dwType == XML_ELEMENT ||
- apNodeInfo[i]->dwType == XML_ATTRIBUTE ||
- apNodeInfo[i]->dwType == XML_PCDATA) {
-
- dwStringSize = apNodeInfo[i]->ulLen;
- pszString = (WCHAR*) apNodeInfo[i]->pwcText;
- // Trim the value
-
- // we should never decrement lgth if it's 0, because it's unsigned
-
- for(;*pszString && ISWHITE(*pszString) && dwStringSize>0; pszString++, dwStringSize--);
- while( dwStringSize > 0 && ISWHITE(pszString[dwStringSize-1]))
- dwStringSize--;
-
- // NOTE: pszString is not guaranteed to be null terminated. Use EEXMLStringCompare to do
- // string comparisions on it
-
- switch(apNodeInfo[i]->dwType) {
- case XML_ELEMENT :
- fRuntimeKey = FALSE;
- ClearKey();
-
- if (m_dwDepth == 1 && EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("runtime"))) == 0) {
- m_fUnderRuntimeElement = TRUE;
- fRuntimeKey = TRUE;
- }
-
- if(m_dwDepth == 2 && m_fUnderRuntimeElement) {
-
- // Developer settings can look like
- // <runtime>
- // <developerSettings installationVersion="v2.0.40223.0" />
- //
- // or
- //
- // <developmentMode developerInstallation="true" />
- //
- // Neither one is your standard config setting.
- if (!EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("developerSettings"))) ||
- !EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("developmentMode"))))
- {
- m_fDeveloperSettings = TRUE;
- }
- else
- // when generalizing: use map of (string, depth) -> class
- if (!EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("disableNativeImageLoad"))))
- {
- m_pActiveFactory = new NativeImageOptOutConfigFactory();
- m_pActiveFactory->AddRef();
- }
- else
- {
- // This is a standard element under the runtime node.... it could look like this
- // <runtime>
- // <pszString enabled="1" />
-
- hr = CopyToKey(pszString, dwStringSize);
- if(FAILED(hr)) return hr;
- }
- }
- // If our depth isn't 2, and we're not under the runtime element....
- else
- ClearKey();
-
- break ;
-
- case XML_ATTRIBUTE :
- if(fRuntimeKey && EEXMLStringCompare(pszString, dwStringSize, CONST_STRING_AND_LEN(W("version"))) == 0) {
- fVersion = TRUE;
- }
- else
- {
- if (m_dwDepth == 2 && m_fUnderRuntimeElement)
- {
- if (!m_fDeveloperSettings)
- {
- _ASSERTE(m_dwCurrentRuntimeElement > 0);
-
- // The standard model for runtime config settings is as follows
- //
- // <runtime>
- // <m_pCurrentRuntimeElement enabled="true|false" />
- // or
- // <m_pCurrentRuntimeElement enabled="1|0" />
- // or
- // <m_pCurrentRuntimeElement value="string" />
-
- m_fOnEnabledAttribute = (EEXMLStringComparei(pszString, dwStringSize, CONST_STRING_AND_LEN(W("enabled"))) == 0);
- m_fOnValueAttribute = (EEXMLStringComparei(pszString, dwStringSize, CONST_STRING_AND_LEN(W("value"))) == 0);
- }
- else // We're looking at developer settings
- {
- // Developer settings look like
- // <developerSettings installationVersion="v2.0.40223.0" />
- //
- // or
- //
- // <developmentMode developerInstallation="true" />
- //
-
- // The key name will actually be the attribute name
-
- hr = CopyToKey(pszString, dwStringSize);
- if(FAILED(hr)) return hr;
- m_fOnEnabledAttribute = FALSE;
- m_fOnValueAttribute = FALSE;
- }
- }
- }
- break;
- case XML_PCDATA:
- if(fVersion) {
- // if this is not the right version
- // then we are not interested
- if(EEXMLStringCompare(pszString, dwStringSize, m_pVersion, (DWORD)wcslen(m_pVersion))) {
- m_fUnderRuntimeElement = FALSE;
- }
- else {
- // if it is the right version then overwrite
- // all entries that exist in the hash table
- m_fVersionedRuntime = TRUE;
- }
-
- fVersion = FALSE;
- }
- else if(fRuntimeKey) {
- break; // Ignore all other attributes on <runtime>
- }
-
- // m_dwCurrentRuntimeElement is set when we called CopyToKey in the XML_ELEMENT case
- // section above.
- else if(m_dwCurrentRuntimeElement > 0 && (m_fDeveloperSettings || m_fOnEnabledAttribute || m_fOnValueAttribute)) {
-
- // This means that, either we are working on attribute values for the developer settings,
- // or we've got what "enabled" is equal to, or we're reading a string for a value setting.
- //
- // <runtime>
- // <m_pwzCurrentElementUnderRuntimeElement m_pLastKey=pString />
-
- if (m_fOnEnabledAttribute) {
- // For the enabled settings, let's convert all trues to 1s and the falses to 0s
- if (EEXMLStringComparei(pszString, dwStringSize, CONST_STRING_AND_LEN(W("false"))) == 0) {
- pszString = W("0");
- dwStringSize = 1;
- }
- else if (EEXMLStringComparei(pszString, dwStringSize, CONST_STRING_AND_LEN(W("true"))) == 0) {
- pszString = W("1");
- dwStringSize = 1;
- }
-
- // <TODO> Right now, if pString isn't 0 or 1, then the XML schema is bad.
- // If we were to ever do schema validation, this would be a place to put it.
- // </TODO>
- }
-
- hr = AddKeyValuePair(pszString, dwStringSize, m_pCurrentRuntimeElement, m_dwCurrentRuntimeElement);
- if(FAILED(hr)) { return hr; }
- }
-
- break ;
- default:
- ;
- } // end of switch
- }
- }
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE EEConfigFactory::AddKeyValuePair(
- __in_ecount(dwStringSize) WCHAR * pszString,
- /* [in] */ DWORD dwStringSize,
- __in_ecount(m_dwCurrentRuntimeElement) WCHAR * m_pCurrentRuntimeElement,
- /* [in] */ DWORD m_dwCurrentRuntimeElement
- )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // verify we the size fields don't overflow
- if (dwStringSize + 1 < dwStringSize) { return E_FAIL; }
- if (m_dwCurrentRuntimeElement < m_dwCurrentRuntimeElement - 1) { return E_FAIL; }
-
- EX_TRY
- {
- // Allocate memory that can store this setting
- NewArrayHolder<WCHAR> pStringToKeep(new WCHAR[dwStringSize+1]);
- wcsncpy_s(pStringToKeep, dwStringSize + 1, pszString, dwStringSize);
-
- // See if we've already picked up a value for this setting
- ConfigStringKeyValuePair * pair = m_pTable->Lookup(m_pCurrentRuntimeElement);
- if(pair != NULL) {
- // If this is a config section for this runtime version, then it's allowed to overwrite
- // previous settings that we've picked up
- if(m_fVersionedRuntime) {
- delete[] pair->value;
- pair->value = pStringToKeep;
- pStringToKeep.SuppressRelease();
- }
- }
- else {
- // We're adding a new config item
- NewArrayHolder<WCHAR> pKeyToKeep (new WCHAR[m_dwCurrentRuntimeElement]);
- wcsncpy_s(pKeyToKeep, m_dwCurrentRuntimeElement, m_pCurrentRuntimeElement, m_dwCurrentRuntimeElement - 1);
-
- ConfigStringKeyValuePair * newPair = new ConfigStringKeyValuePair();
- newPair->key = pKeyToKeep;
- newPair->value = pStringToKeep;
- m_pTable->Add(newPair);
- pKeyToKeep.SuppressRelease();
- pStringToKeep.SuppressRelease();
- }
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
diff --git a/src/vm/eeconfigfactory.h b/src/vm/eeconfigfactory.h
deleted file mode 100644
index 2554295268..0000000000
--- a/src/vm/eeconfigfactory.h
+++ /dev/null
@@ -1,149 +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.
-// EEConfigFactory.h
-//
-
-//
-// Parses XML files and adding runtime entries to the EEConfig list
-//
-
-
-#ifndef EECONFIGFACTORY_H
-#define EECONFIGFACTORY_H
-
-#include <xmlparser.h>
-#include <objbase.h>
-#include "unknwn.h"
-#include "../xmlparser/_reference.h"
-#include "../xmlparser/_unknown.h"
-#include "eehash.h"
-#include "eeconfig.h"
-
-#define CONFIG_KEY_SIZE 128
-
-class EEConfigFactory : public _unknown<IXMLNodeFactory, &IID_IXMLNodeFactory>
-{
-
-public:
- EEConfigFactory(
- ConfigStringHashtable* pTable,
- LPCWSTR,
- ParseCtl parseCtl = parseAll);
- ~EEConfigFactory();
- HRESULT STDMETHODCALLTYPE NotifyEvent(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ XML_NODEFACTORY_EVENT iEvt);
-
- HRESULT STDMETHODCALLTYPE BeginChildren(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ XML_NODE_INFO* __RPC_FAR pNodeInfo);
-
- HRESULT STDMETHODCALLTYPE EndChildren(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ BOOL fEmptyNode,
- /* [in] */ XML_NODE_INFO* __RPC_FAR pNodeInfo);
-
- HRESULT STDMETHODCALLTYPE Error(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ HRESULT hrErrorCode,
- /* [in] */ USHORT cNumRecs,
- /* [in] */ XML_NODE_INFO* __RPC_FAR * __RPC_FAR apNodeInfo)
- {
- LIMITED_METHOD_CONTRACT;
- /*
- UNUSED(pSource);
- UNUSED(hrErrorCode);
- UNUSED(cNumRecs);
- UNUSED(apNodeInfo);
- */
- return hrErrorCode;
- }
-
- HRESULT STDMETHODCALLTYPE CreateNode(
- /* [in] */ IXMLNodeSource __RPC_FAR *pSource,
- /* [in] */ PVOID pNodeParent,
- /* [in] */ USHORT cNumRecs,
- /* [in] */ XML_NODE_INFO* __RPC_FAR * __RPC_FAR apNodeInfo);
-
-private:
-
- HRESULT GrowKey(DWORD dwSize)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- INJECT_FAULT(return E_OUTOFMEMORY);
- }
- CONTRACTL_END;
-
- if(dwSize > m_dwSize) {
- DeleteKey();
- m_pCurrentRuntimeElement = new(nothrow) WCHAR[dwSize];
- if(m_pCurrentRuntimeElement == NULL) return E_OUTOFMEMORY;
- m_dwSize = dwSize;
- }
- return S_OK;
- }
-
- void ClearKey()
- {
- LIMITED_METHOD_CONTRACT;
-
- *m_pCurrentRuntimeElement = 0;
- m_dwCurrentRuntimeElement = 0;
- }
-
- void DeleteKey()
- {
- WRAPPER_NO_CONTRACT;
- if(m_pCurrentRuntimeElement != NULL && m_pCurrentRuntimeElement != m_pBuffer)
- delete [] m_pCurrentRuntimeElement;
- m_dwSize = 0;
- m_dwCurrentRuntimeElement = 0;
- }
-
- HRESULT CopyToKey(__in_z LPCWSTR pString, DWORD dwString)
- {
- WRAPPER_NO_CONTRACT;
- dwString++; // add in the null
- HRESULT hr = GrowKey(dwString);
- if(FAILED(hr)) return hr;
- wcsncpy_s(m_pCurrentRuntimeElement, m_dwSize, pString, dwString-1);
-
- m_dwCurrentRuntimeElement = dwString;
- return S_OK;
- }
-
- HRESULT STDMETHODCALLTYPE AddKeyValuePair(
- __in_ecount(dwStringSize) WCHAR * pszString,
- /* [in] */ DWORD dwStringSize,
- __in_ecount(m_dwCurrentRuntimeElement) WCHAR * m_pCurrentRuntimeElement,
- /* [in] */ DWORD m_dwCurrentRuntimeElement);
-
- HRESULT CopyVersion(LPCWSTR version, DWORD dwVersion);
-
- ConfigStringHashtable* m_pTable;
- BOOL m_fUnderRuntimeElement;
- BOOL m_fOnEnabledAttribute;
- BOOL m_fOnValueAttribute;
- BOOL m_fVersionedRuntime;
- BOOL m_fDeveloperSettings;
-
- LPCWSTR m_pVersion;
- LPWSTR m_pCurrentRuntimeElement;
- DWORD m_dwCurrentRuntimeElement;
-
- WCHAR m_pBuffer[CONFIG_KEY_SIZE];
- DWORD m_dwSize;
-
- DWORD m_dwDepth;
-
- bool m_bSafeMode; // If true, will ignore any settings that may compromise security
- ParseCtl m_parseCtl; // usually parseAll, sometimes stopAfterRuntimeSection
-
- ReleaseHolder<IXMLNodeFactory> m_pActiveFactory; // hold a factory responsible for parsing subnode
-};
-
-#endif
diff --git a/src/vm/eedbginterfaceimpl.cpp b/src/vm/eedbginterfaceimpl.cpp
index b7a4359350..ede82c7780 100644
--- a/src/vm/eedbginterfaceimpl.cpp
+++ b/src/vm/eedbginterfaceimpl.cpp
@@ -1588,15 +1588,8 @@ CorDebugUserState EEDbgInterfaceImpl::GetPartialUserState(Thread *pThread)
ret |= (unsigned)USER_WAIT_SLEEP_JOIN;
}
- // Don't report a SuspendRequested if the thread has actually Suspended.
- if ( ((ts & Thread::TS_UserSuspendPending) && (ts & Thread::TS_SyncSuspended)))
- {
- ret |= (unsigned)USER_SUSPENDED;
- }
- else if (ts & Thread::TS_UserSuspendPending)
- {
- ret |= (unsigned)USER_SUSPEND_REQUESTED;
- }
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(ts & Thread::TS_UserSuspendPending));
LOG((LF_CORDB,LL_INFO1000, "EEDbgII::GUS: thread 0x%x (id:0x%x)"
" userThreadState is 0x%x\n", pThread, pThread->GetThreadId(), ret));
diff --git a/src/vm/eepolicy.cpp b/src/vm/eepolicy.cpp
index 236f5afd6e..be5fa00ee5 100644
--- a/src/vm/eepolicy.cpp
+++ b/src/vm/eepolicy.cpp
@@ -70,12 +70,10 @@ EEPolicy::EEPolicy ()
m_ActionOnFailure[FAIL_NonCriticalResource] = eThrowException;
m_ActionOnFailure[FAIL_OrphanedLock] = eNoAction;
m_ActionOnFailure[FAIL_FatalRuntime] = eRudeExitProcess;
-#ifdef FEATURE_CORECLR
// For CoreCLR, initialize the default action for AV processing to all
// all kind of code to catch AV exception. If the host wants, they can
// specify a different action for this.
m_ActionOnFailure[FAIL_AccessViolation] = eNoAction;
-#endif // FEATURE_CORECLR
m_ActionOnFailure[FAIL_StackOverflow] = eRudeExitProcess;
m_ActionOnFailure[FAIL_CodeContract] = eThrowException;
m_unhandledExceptionPolicy = eRuntimeDeterminedPolicy;
@@ -178,22 +176,10 @@ BOOL EEPolicy::IsValidActionForFailure(EClrFailure failure, EPolicyAction action
return action >= eUnloadAppDomain &&
action < MaxPolicyAction;
case FAIL_AccessViolation:
-#ifdef FEATURE_CORECLR
// Allowed actions on failure are:
//
// eNoAction or eRudeExitProcess.
return ((action == eNoAction) || (action == eRudeExitProcess));
-#else // !FEATURE_CORECLR
- // FAIL_AccessViolation is defined for the desktop so that
- // if any more definitions are added after it, their value
- // should remain constant irrespective of whether its the
- // desktop CLR or CoreCLR.
- //
- // That said, currently, Desktop CLR does not support
- // FAIL_AccessViolation. Thus, any calls which use
- // this failure are not allowed.
- return FALSE;
-#endif // FEATURE_CORECLR
case FAIL_StackOverflow:
return action >= eRudeUnloadAppDomain &&
action < MaxPolicyAction;
@@ -424,22 +410,6 @@ EPolicyAction EEPolicy::GetActionOnFailure(EClrFailure failure)
}
EPolicyAction finalAction = GetActionOnFailureNoHostNotification(failure);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostPolicyManager *pHostPolicyManager = CorHost2::GetHostPolicyManager();
- if (pHostPolicyManager)
- {
-#ifdef _DEBUG
- Thread* pThread = GetThread();
- if (pThread)
- {
- pThread->AddFiberInfo(Thread::ThreadTrackInfo_Escalation);
- }
-#endif
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pHostPolicyManager->OnFailure(failure, finalAction);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
return finalAction;
}
@@ -455,22 +425,6 @@ void EEPolicy::NotifyHostOnTimeout(EClrOperation operation, EPolicyAction action
}
CONTRACTL_END;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostPolicyManager *pHostPolicyManager = CorHost2::GetHostPolicyManager();
- if (pHostPolicyManager)
- {
-#ifdef _DEBUG
- Thread* pThread = GetThread();
- if (pThread)
- {
- pThread->AddFiberInfo(Thread::ThreadTrackInfo_Escalation);
- }
-#endif
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pHostPolicyManager->OnTimeout(operation, action);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
@@ -485,22 +439,6 @@ void EEPolicy::NotifyHostOnDefaultAction(EClrOperation operation, EPolicyAction
}
CONTRACTL_END;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostPolicyManager *pHostPolicyManager = CorHost2::GetHostPolicyManager();
- if (pHostPolicyManager)
- {
-#ifdef _DEBUG
- Thread* pThread = GetThread();
- if (pThread)
- {
- pThread->AddFiberInfo(Thread::ThreadTrackInfo_Escalation);
- }
-#endif
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pHostPolicyManager->OnDefaultAction(operation, action);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
void SafeExitProcess(UINT exitCode, BOOL fAbort = FALSE, ShutdownCompleteAction sca = SCA_ExitProcessWhenShutdownComplete)
@@ -602,21 +540,6 @@ void EEPolicy::ExitProcessViaShim(UINT exitCode)
// runtime in a process with many. We need to give the other runtimes a chance to exit
// cleanly. If we can't make the call, or if the call fails for some reason, then we
// simply exit the process here, which is rude to the others, but the best we can do.
-#if !defined(FEATURE_CORECLR)
- {
- ReleaseHolder<ICLRRuntimeHostInternal> pRuntimeHostInternal;
-
- HRESULT hr = g_pCLRRuntime->GetInterface(CLSID_CLRRuntimeHostInternal,
- IID_ICLRRuntimeHostInternal,
- &pRuntimeHostInternal);
-
- if (SUCCEEDED(hr))
- {
- pRuntimeHostInternal->ShutdownAllRuntimesThenExit(exitCode);
- LOG((LF_EH, LL_INFO10, "ExitProcessViaShim: shim returned... exiting now.\n"));
- }
- }
-#endif // !FEATURE_CORECLR
ExitProcess(exitCode);
}
@@ -1001,13 +924,7 @@ void EEPolicy::HandleStackOverflow(StackOverflowDetector detector, void * pLimit
switch (detector)
{
case SOD_ManagedFrameHandler:
- if (!pThread->PreemptiveGCDisabled() && !fInCLR && fInSoTolerant
- &&
- // Before we call managed code, we probe inside ReverseEnterRuntime for BACKOUT_CODE_STACK_LIMIT pages
- // If we hit hard so here, we are still in our stub
- (!CLRTaskHosted() || (UINT_PTR)pThread->m_pFrame - pThread->GetLastAllowableStackAddress() >=
- ADJUST_PROBE(BACKOUT_CODE_STACK_LIMIT) * OS_PAGE_SIZE)
- )
+ if (!pThread->PreemptiveGCDisabled() && !fInCLR && fInSoTolerant)
{
// Managed exception handler detects SO, but the thread is in preemptive GC mode,
// and the IP is outside CLR. This means we are inside a PINVOKE call.
diff --git a/src/vm/eetoprofinterfaceimpl.cpp b/src/vm/eetoprofinterfaceimpl.cpp
index e96a9e58d3..ca35717bec 100644
--- a/src/vm/eetoprofinterfaceimpl.cpp
+++ b/src/vm/eetoprofinterfaceimpl.cpp
@@ -6282,116 +6282,6 @@ HRESULT EEToProfInterfaceImpl::ProfilerDetachSucceeded()
}
}
-#ifdef FEATURE_FUSION
-
-// Minimal wrappers so that Fusion can call the GetAssemblyReferences profiler callback
-// without needing a ton of profapi includes.
-
-BOOL ShouldCallGetAssemblyReferencesProfilerCallback()
-{
- return CORProfilerAddsAssemblyReferences();
-}
-
-void CallGetAssemblyReferencesProfilerCallbackIfNecessary(LPCWSTR wszAssemblyPath, IAssemblyBindingClosure * pClosure, AssemblyReferenceClosureWalkContextForProfAPI * pContext)
-{
- BEGIN_PIN_PROFILER(CORProfilerAddsAssemblyReferences());
- g_profControlBlock.pProfInterface->GetAssemblyReferences(wszAssemblyPath, pClosure, pContext);
- END_PIN_PROFILER();
-}
-
-// Implementation of ICorProfilerAssemblyReferenceProvider, which is given to the profiler so
-// that it can call back into the CLR with extra assembly references that should be considered
-// while Fusion performs its assembly reference closure walk.
-class ProfilerAssemblyReferenceProvider : public ICorProfilerAssemblyReferenceProvider
-{
-public:
- // IUnknown functions
- virtual HRESULT __stdcall QueryInterface(REFIID id, void** pInterface)
- {
- LIMITED_METHOD_CONTRACT;
-
- if (id == IID_IUnknown)
- {
- *pInterface = static_cast<IUnknown *>(this);
- }
- else if (id == IID_ICorProfilerAssemblyReferenceProvider)
- {
- *pInterface = static_cast<ICorProfilerAssemblyReferenceProvider *>(this);
- }
- else
- {
- *pInterface = NULL;
- return E_NOINTERFACE;
- }
-
- AddRef();
- return S_OK;
- }
-
- virtual ULONG __stdcall AddRef()
- {
- LIMITED_METHOD_CONTRACT;
- return InterlockedIncrement(&m_refCount);
- }
-
- virtual ULONG __stdcall Release()
- {
- LIMITED_METHOD_CONTRACT;
-
- ULONG refCount = InterlockedDecrement(&m_refCount);
-
- if (0 == refCount)
- {
- delete this;
- }
-
- return refCount;
- }
-
- // ICorProfilerAssemblyReferenceProvider functions
-
- // This is what the profiler calls to tell us about an assembly reference we should include
- // when Fusion performs its closure walk. When this is called, the walk is already underway,
- // and is sitting on our stack already.
- virtual HRESULT __stdcall AddAssemblyReference(const COR_PRF_ASSEMBLY_REFERENCE_INFO * pAssemblyRefInfo)
- {
- _ASSERTE(m_pClosure != NULL);
-
- return m_pClosure->AddProfilerAssemblyReference(
- pAssemblyRefInfo->pbPublicKeyOrToken,
- pAssemblyRefInfo->cbPublicKeyOrToken,
- pAssemblyRefInfo->szName,
- pAssemblyRefInfo->pMetaData,
- pAssemblyRefInfo->pbHashValue,
- pAssemblyRefInfo->cbHashValue,
- pAssemblyRefInfo->dwAssemblyRefFlags,
- m_pContext);
- }
-
- // Implementation
- ProfilerAssemblyReferenceProvider(IAssemblyBindingClosure * pClosure, AssemblyReferenceClosureWalkContextForProfAPI * pContext) :
- m_refCount(1),
- m_pClosure(pClosure),
- m_pContext(pContext)
- {
- LIMITED_METHOD_CONTRACT;
- m_pClosure->AddRef();
- }
-
-protected:
- Volatile<LONG> m_refCount;
-
- // Our interface into Fusion's closure walk. We use this to inform Fusion about
- // the assembly reference the profiler gave us.
- ReleaseHolder<IAssemblyBindingClosure> m_pClosure;
-
- // Extra context built up by fusion's closure walk that we need to remember. The
- // walk is already in action by the time we're called, and this structure remembers
- // the lists that are getting built up by the walk
- AssemblyReferenceClosureWalkContextForProfAPI * m_pContext;
-};
-
-#endif // FEATURE_FUSION
HRESULT EEToProfInterfaceImpl::GetAssemblyReferences(LPCWSTR wszAssemblyPath, IAssemblyBindingClosure * pClosure, AssemblyReferenceClosureWalkContextForProfAPI * pContext)
@@ -6421,30 +6311,6 @@ HRESULT EEToProfInterfaceImpl::GetAssemblyReferences(LPCWSTR wszAssemblyPath, IA
));
HRESULT hr = S_OK;
-#ifdef FEATURE_FUSION
-
- SString sPath;
- _ASSERTE(IsCallback6Supported());
-
- // Create an instance of the class implementing the interface we pass back to the profiler,
- // feeding it the context we're currently at in Fusion's closure walk
- ReleaseHolder<ProfilerAssemblyReferenceProvider> pReferenceProvider =
- new (nothrow) ProfilerAssemblyReferenceProvider(pClosure, pContext);
- if (pReferenceProvider == NULL)
- {
- return E_OUTOFMEMORY;
- }
-
- {
- // All callbacks are really NOTHROW, but that's enforced partially by the profiler,
- // whose try/catch blocks aren't visible to the contract system
- PERMANENT_CONTRACT_VIOLATION(ThrowsViolation, ReasonProfilerCallout);
- hr = m_pCallback6->GetAssemblyReferences(
- wszAssemblyPath,
- static_cast<ICorProfilerAssemblyReferenceProvider *>(pReferenceProvider));
- }
-
-#endif // FEATURE_FUSION
return hr;
}
diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp
index 340ea85e94..2886daa8f6 100644
--- a/src/vm/eetwain.cpp
+++ b/src/vm/eetwain.cpp
@@ -2413,6 +2413,18 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
_ASSERTE(*castto(table, unsigned short *)++ == 0xBABE);
#endif
+ bool hasPartialArgInfo;
+
+#ifndef UNIX_X86_ABI
+ hasPartialArgInfo = info->ebpFrame;
+#else
+ // For x86/Linux, interruptible code always has full arg info
+ //
+ // This should be aligned with emitFullArgInfo setting at
+ // emitter::emitEndCodeGen (in JIT)
+ hasPartialArgInfo = false;
+#endif
+
/*
Encoding table for methods that are fully interruptible
@@ -2611,9 +2623,9 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
argOfs--;
}
- else if (info->ebpFrame)
+ else if (hasPartialArgInfo)
argCnt--;
- else /* !ebpFrame && not a ref */
+ else /* full arg info && not a ref */
argOfs--;
/* Continue with the next lower bit */
@@ -2622,11 +2634,11 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
}
while (argOfs);
- _ASSERTE((info->ebpFrame != 0) ||
+ _ASSERTE(!hasPartialArgInfo ||
isZero(argHigh) ||
(argHigh == CONSTRUCT_ptrArgTP(1, (argCnt-1))));
- if (info->ebpFrame)
+ if (hasPartialArgInfo)
{
while (!intersect(argHigh, ptrArgs) && (!isZero(argHigh)))
argHigh >>= 1;
@@ -2643,10 +2655,10 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
}
else
{
- /* For ESP-frames, all pushes are reported, and so
+ /* Full arg info reports all pushes, and thus
argOffs has to be consistent with argCnt */
- _ASSERTE(info->ebpFrame || argCnt == argOfs);
+ _ASSERTE(hasPartialArgInfo || argCnt == argOfs);
/* store arg count */
@@ -2692,7 +2704,7 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
}
else {
/* non-ptr arg push */
- _ASSERTE(!(info->ebpFrame));
+ _ASSERTE(!hasPartialArgInfo);
ptrOffs += (val & 0x07);
if (ptrOffs > curOffs) {
iptr = isThis = false;
@@ -2753,9 +2765,9 @@ unsigned scanArgRegTableI(PTR_CBYTE table,
}
}
- // For ebp-frames, need to find the next higest pointer for argHigh
+ // For partial arg info, need to find the next higest pointer for argHigh
- if (info->ebpFrame)
+ if (hasPartialArgInfo)
{
for(argHigh = ptrArgTP(0); !isZero(argMask); argMask >>= 1)
{
@@ -2794,7 +2806,7 @@ REPORT_REFS:
info->thisPtrResult = thisPtrReg;
_ASSERTE(thisPtrReg == REGI_NA || (regNumToMask(thisPtrReg) & info->regMaskResult));
- if (info->ebpFrame)
+ if (hasPartialArgInfo)
{
return 0;
}
@@ -3099,7 +3111,8 @@ size_t EECodeManager::GetCallerSp( PREGDISPLAY pRD )
{
EnsureCallerContextIsValid(pRD, NULL);
}
- return (size_t) (GetSP(pRD->pCallerContext));
+
+ return GetSP(pRD->pCallerContext);
}
#endif // WIN64EXCEPTIONS && !CROSSGEN_COMPILE
@@ -3785,10 +3798,13 @@ void UnwindEbpDoubleAlignFrameProlog(
/*****************************************************************************/
bool UnwindEbpDoubleAlignFrame(
- PREGDISPLAY pContext,
- hdrInfo * info,
- PTR_CBYTE methodStart,
- unsigned flags,
+ PREGDISPLAY pContext,
+ EECodeInfo *pCodeInfo,
+ hdrInfo *info,
+ PTR_CBYTE table,
+ PTR_CBYTE methodStart,
+ DWORD curOffs,
+ unsigned flags,
StackwalkCacheUnwindInfo *pUnwindInfo) // out-only, perf improvement
{
LIMITED_METHOD_CONTRACT;
@@ -3805,6 +3821,29 @@ bool UnwindEbpDoubleAlignFrame(
{
TADDR baseSP;
+#ifdef WIN64EXCEPTIONS
+ // Funclets' frame pointers(EBP) are always restored so they can access to main function's local variables.
+ // Therefore the value of EBP is invalid for unwinder so we should use ESP instead.
+ // TODO If funclet frame layout is changed from CodeGen::genFuncletProlog() and genFuncletEpilog(),
+ // we need to change here accordingly. It is likely to have changes when introducing PSPSym.
+ // TODO Currently we assume that ESP of funclet frames is always fixed but actually it could change.
+ if (pCodeInfo->IsFunclet())
+ {
+ baseSP = curESP;
+ // Set baseSP as initial SP
+ baseSP += GetPushedArgSize(info, table, curOffs);
+ // 16-byte stack alignment padding (allocated in genFuncletProlog)
+ baseSP += 12;
+
+ pContext->PCTAddr = baseSP;
+ pContext->ControlPC = *PTR_PCODE(pContext->PCTAddr);
+
+ pContext->SP = (DWORD)(baseSP + sizeof(TADDR));
+
+ return true;
+ }
+#else // WIN64EXCEPTIONS
+
FrameType frameType = GetHandlerFrameInfo(info, curEBP,
curESP, (DWORD) IGNORE_VAL,
&baseSP);
@@ -3859,6 +3898,7 @@ bool UnwindEbpDoubleAlignFrame(
return true;
}
+#endif // !WIN64EXCEPTIONS
}
//
@@ -3989,7 +4029,7 @@ bool UnwindStackFrame(PREGDISPLAY pContext,
* Now we know that have an EBP frame
*/
- if (!UnwindEbpDoubleAlignFrame(pContext, info, methodStart, flags, pUnwindInfo))
+ if (!UnwindEbpDoubleAlignFrame(pContext, pCodeInfo, info, table, methodStart, curOffs, flags, pUnwindInfo))
return false;
}
@@ -4008,6 +4048,54 @@ bool UnwindStackFrame(PREGDISPLAY pContext,
#endif // _TARGET_X86_
+#ifdef WIN64EXCEPTIONS
+#ifdef _TARGET_X86_
+size_t EECodeManager::GetResumeSp( PCONTEXT pContext )
+{
+ PCODE currentPc = PCODE(pContext->Eip);
+
+ _ASSERTE(ExecutionManager::IsManagedCode(currentPc));
+
+ EECodeInfo codeInfo(currentPc);
+
+ PTR_CBYTE methodStart = PTR_CBYTE(codeInfo.GetSavedMethodCode());
+
+ GCInfoToken gcInfoToken = codeInfo.GetGCInfoToken();
+ PTR_VOID methodInfoPtr = gcInfoToken.Info;
+ DWORD curOffs = codeInfo.GetRelOffset();
+
+ CodeManStateBuf stateBuf;
+
+ stateBuf.hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken,
+ curOffs,
+ &stateBuf.hdrInfoBody);
+
+ PTR_CBYTE table = dac_cast<PTR_CBYTE>(methodInfoPtr) + stateBuf.hdrInfoSize;
+
+ hdrInfo *info = &stateBuf.hdrInfoBody;
+
+ _ASSERTE(info->epilogOffs == hdrInfo::NOT_IN_EPILOG && info->prologOffs == hdrInfo::NOT_IN_PROLOG);
+
+ bool isESPFrame = !info->ebpFrame && !info->doubleAlign;
+
+ if (codeInfo.IsFunclet())
+ {
+ // Treat funclet's frame as ESP frame
+ isESPFrame = true;
+ }
+
+ if (isESPFrame)
+ {
+ const size_t curESP = (size_t)(pContext->Esp);
+ return curESP + GetPushedArgSize(info, table, curOffs);
+ }
+
+ const size_t curEBP = (size_t)(pContext->Ebp);
+ return GetOutermostBaseFP(curEBP, info);
+}
+#endif // _TARGET_X86_
+#endif // WIN64EXCEPTIONS
+
#ifndef CROSSGEN_COMPILE
#ifndef WIN64EXCEPTIONS
@@ -4141,6 +4229,14 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext,
GC_NOTRIGGER;
} CONTRACTL_END;
+#ifdef WIN64EXCEPTIONS
+ if (flags & ParentOfFuncletStackFrame)
+ {
+ LOG((LF_GCROOTS, LL_INFO100000, "Not reporting this frame because it was already reported via another funclet.\n"));
+ return true;
+ }
+#endif // WIN64EXCEPTIONS
+
GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
unsigned curOffs = pCodeInfo->GetRelOffset();
@@ -4730,6 +4826,18 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext,
_ASSERTE(*castto(table, unsigned short *)++ == 0xBABE);
#endif
+#ifdef WIN64EXCEPTIONS // funclets
+ //
+ // If we're in a funclet, we do not want to report the incoming varargs. This is
+ // taken care of by the parent method and the funclet should access those arguments
+ // by way of the parent method's stack frame.
+ //
+ if(pCodeInfo->IsFunclet())
+ {
+ return true;
+ }
+#endif // WIN64EXCEPTIONS
+
/* Are we a varargs function, if so we have to report all args
except 'this' (note that the GC tables created by the x86 jit
do not contain ANY arguments except 'this' (even if they
@@ -5168,7 +5276,7 @@ OBJECTREF EECodeManager::GetInstance( PREGDISPLAY pContext,
if (info.ebpFrame)
{
_ASSERTE(stackDepth == 0);
- taArgBase = *pContext->GetEbpLocation();
+ taArgBase = GetRegdisplayFP(pContext);
}
else
{
@@ -5467,13 +5575,7 @@ void * EECodeManager::GetGSCookieAddr(PREGDISPLAY pContext,
if (info->ebpFrame)
{
- DWORD curEBP;
-
-#ifdef WIN64EXCEPTIONS
- curEBP = GetCallerSp(pContext) - 2 * 4;
-#else
- curEBP = *pContext->pEbp;
-#endif
+ DWORD curEBP = GetRegdisplayFP(pContext);
return PVOID(SIZE_T(curEBP - info->gsCookieOffset));
}
@@ -5883,6 +5985,14 @@ ULONG32 EECodeManager::GetStackParameterSize(EECodeInfo * pCodeInfo)
} CONTRACTL_END;
#if defined(_TARGET_X86_)
+#if defined(WIN64EXCEPTIONS)
+ if (pCodeInfo->IsFunclet())
+ {
+ // Funclet has no stack argument
+ return 0;
+ }
+#endif // WIN64EXCEPTIONS
+
GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
unsigned dwOffset = pCodeInfo->GetRelOffset();
diff --git a/src/vm/eventpipe.cpp b/src/vm/eventpipe.cpp
new file mode 100644
index 0000000000..98d382ea17
--- /dev/null
+++ b/src/vm/eventpipe.cpp
@@ -0,0 +1,234 @@
+// 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 "common.h"
+#include "eventpipe.h"
+#include "eventpipejsonfile.h"
+#include "sampleprofiler.h"
+
+CrstStatic EventPipe::s_initCrst;
+bool EventPipe::s_tracingInitialized = false;
+bool EventPipe::s_tracingEnabled = false;
+EventPipeJsonFile* EventPipe::s_pJsonFile = NULL;
+
+void EventPipe::Initialize()
+{
+ STANDARD_VM_CONTRACT;
+
+ s_tracingInitialized = s_initCrst.InitNoThrow(
+ CrstEventPipe,
+ (CrstFlags)(CRST_TAKEN_DURING_SHUTDOWN));
+}
+
+void EventPipe::EnableOnStartup()
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ // Test COMPLUS variable to enable tracing at start-up.
+ if(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_PerformanceTracing) != 0)
+ {
+ Enable();
+ }
+}
+
+void EventPipe::Shutdown()
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ Disable();
+}
+
+void EventPipe::Enable()
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ if(!s_tracingInitialized)
+ {
+ return;
+ }
+
+ // Take the lock and enable tracing.
+ CrstHolder _crst(&s_initCrst);
+ s_tracingEnabled = true;
+ if(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_PerformanceTracing) == 2)
+ {
+ // File placed in current working directory.
+ SString outputFilePath;
+ outputFilePath.Printf("Process-%d.PerfView.json", GetCurrentProcessId());
+ s_pJsonFile = new EventPipeJsonFile(outputFilePath);
+ }
+
+ SampleProfiler::Enable();
+}
+
+void EventPipe::Disable()
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ CrstHolder _crst(&s_initCrst);
+ s_tracingEnabled = false;
+ SampleProfiler::Disable();
+
+ if(s_pJsonFile != NULL)
+ {
+ delete(s_pJsonFile);
+ s_pJsonFile = NULL;
+ }
+}
+
+bool EventPipe::EventEnabled(GUID& providerID, INT64 keyword)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ // TODO: Implement filtering.
+ return false;
+}
+
+void EventPipe::WriteEvent(GUID& providerID, INT64 eventID, BYTE *pData, size_t length, bool sampleStack)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ StackContents stackContents;
+ bool stackWalkSucceeded;
+
+ if(sampleStack)
+ {
+ stackWalkSucceeded = WalkManagedStackForCurrentThread(stackContents);
+ }
+
+ // TODO: Write the event.
+}
+
+void EventPipe::WriteSampleProfileEvent(Thread *pThread, StackContents &stackContents)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ PRECONDITION(pThread != NULL);
+ }
+ CONTRACTL_END;
+
+ EX_TRY
+ {
+ if(s_pJsonFile != NULL)
+ {
+ CommonEventFields eventFields;
+ QueryPerformanceCounter(&eventFields.TimeStamp);
+ eventFields.ThreadID = pThread->GetOSThreadId();
+
+ static SString message(W("THREAD_TIME"));
+ s_pJsonFile->WriteEvent(eventFields, message, stackContents);
+ }
+ }
+ EX_CATCH{} EX_END_CATCH(SwallowAllExceptions);
+}
+
+bool EventPipe::WalkManagedStackForCurrentThread(StackContents &stackContents)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ Thread *pThread = GetThread();
+ _ASSERTE(pThread != NULL);
+ return WalkManagedStackForThread(pThread, stackContents);
+}
+
+bool EventPipe::WalkManagedStackForThread(Thread *pThread, StackContents &stackContents)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ PRECONDITION(pThread != NULL);
+ }
+ CONTRACTL_END;
+
+ stackContents.Reset();
+
+ StackWalkAction swaRet = pThread->StackWalkFrames(
+ (PSTACKWALKFRAMESCALLBACK) &StackWalkCallback,
+ &stackContents,
+ ALLOW_ASYNC_STACK_WALK | FUNCTIONSONLY | HANDLESKIPPEDFRAMES);
+
+ return ((swaRet == SWA_DONE) || (swaRet == SWA_CONTINUE));
+}
+
+StackWalkAction EventPipe::StackWalkCallback(CrawlFrame *pCf, StackContents *pData)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_PREEMPTIVE;
+ PRECONDITION(pCf != NULL);
+ PRECONDITION(pData != NULL);
+ }
+ CONTRACTL_END;
+
+ // Get the IP.
+ UINT_PTR controlPC = (UINT_PTR)pCf->GetRegisterSet()->ControlPC;
+ if(controlPC == 0)
+ {
+ if(pData->GetLength() == 0)
+ {
+ // This happens for pinvoke stubs on the top of the stack.
+ return SWA_CONTINUE;
+ }
+ }
+
+ _ASSERTE(controlPC != 0);
+
+ // Add the IP to the captured stack.
+ pData->Append(
+ controlPC,
+ pCf->GetFunction()
+ );
+
+ // Continue the stack walk.
+ return SWA_CONTINUE;
+}
diff --git a/src/vm/eventpipe.h b/src/vm/eventpipe.h
new file mode 100644
index 0000000000..2978412325
--- /dev/null
+++ b/src/vm/eventpipe.h
@@ -0,0 +1,154 @@
+// 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.
+
+#ifndef __EVENTPIPE_H__
+#define __EVENTPIPE_H__
+
+#include "common.h"
+
+class EventPipeJsonFile;
+
+// The data fields common to every event.
+struct CommonEventFields
+{
+ // Timestamp generated by QueryPerformanceCounter.
+ LARGE_INTEGER TimeStamp;
+
+ // Thread ID.
+ DWORD ThreadID;
+};
+
+class StackContents
+{
+private:
+
+ const static unsigned int MAX_STACK_DEPTH = 100;
+
+ // Array of IP values from a stack crawl.
+ // Top of stack is at index 0.
+ UINT_PTR m_stackFrames[MAX_STACK_DEPTH];
+
+ // Parallel array of MethodDesc pointers.
+ // Used for debug-only stack printing.
+ MethodDesc* m_methods[MAX_STACK_DEPTH];
+
+ // The next available slot in StackFrames.
+ unsigned int m_nextAvailableFrame;
+
+public:
+
+ StackContents()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ Reset();
+ }
+
+ void Reset()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ m_nextAvailableFrame = 0;
+ }
+
+ bool IsEmpty()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ return (m_nextAvailableFrame == 0);
+ }
+
+ unsigned int GetLength()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ return m_nextAvailableFrame;
+ }
+
+ UINT_PTR GetIP(unsigned int frameIndex)
+ {
+ LIMITED_METHOD_CONTRACT;
+ _ASSERTE(frameIndex < MAX_STACK_DEPTH);
+
+ if (frameIndex >= MAX_STACK_DEPTH)
+ {
+ return 0;
+ }
+
+ return m_stackFrames[frameIndex];
+ }
+
+ MethodDesc* GetMethod(unsigned int frameIndex)
+ {
+ LIMITED_METHOD_CONTRACT;
+ _ASSERTE(frameIndex < MAX_STACK_DEPTH);
+
+ if (frameIndex >= MAX_STACK_DEPTH)
+ {
+ return NULL;
+ }
+
+ return m_methods[frameIndex];
+ }
+
+ void Append(UINT_PTR controlPC, MethodDesc *pMethod)
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ if(m_nextAvailableFrame < MAX_STACK_DEPTH)
+ {
+ m_stackFrames[m_nextAvailableFrame] = controlPC;
+ m_methods[m_nextAvailableFrame] = pMethod;
+ m_nextAvailableFrame++;
+ }
+ }
+};
+
+class EventPipe
+{
+ public:
+
+ // Initialize the event pipe.
+ static void Initialize();
+
+ // Shutdown the event pipe.
+ static void Shutdown();
+
+ // Enable tracing from the start-up path based on COMPLUS variable.
+ static void EnableOnStartup();
+
+ // Enable tracing via the event pipe.
+ static void Enable();
+
+ // Disable tracing via the event pipe.
+ static void Disable();
+
+ // Determine whether or not the specified provider/keyword combination is enabled.
+ static bool EventEnabled(GUID& providerID, INT64 keyword);
+
+ // Write out an event. The event is identified by the providerID/eventID pair.
+ // Data is written as a serialized blob matching the ETW serialization conventions.
+ static void WriteEvent(GUID& providerID, INT64 eventID, BYTE *pData, size_t length, bool sampleStack);
+
+ // Write out a sample profile event with the specified stack.
+ static void WriteSampleProfileEvent(Thread *pThread, StackContents &stackContents);
+
+ // Get the managed call stack for the current thread.
+ static bool WalkManagedStackForCurrentThread(StackContents &stackContents);
+
+ // Get the managed call stack for the specified thread.
+ static bool WalkManagedStackForThread(Thread *pThread, StackContents &stackContents);
+
+ private:
+
+ // Callback function for the stack walker. For each frame walked, this callback is invoked.
+ static StackWalkAction StackWalkCallback(CrawlFrame *pCf, StackContents *pData);
+
+ static CrstStatic s_initCrst;
+ static bool s_tracingInitialized;
+ static bool s_tracingEnabled;
+ static EventPipeJsonFile *s_pJsonFile;
+};
+
+#endif // __EVENTPIPE_H__
diff --git a/src/vm/eventpipejsonfile.cpp b/src/vm/eventpipejsonfile.cpp
new file mode 100644
index 0000000000..6353c917e7
--- /dev/null
+++ b/src/vm/eventpipejsonfile.cpp
@@ -0,0 +1,131 @@
+// 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 "common.h"
+#include "eventpipejsonfile.h"
+
+EventPipeJsonFile::EventPipeJsonFile(SString &outFilePath)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ m_pFileStream = new CFileStream();
+ if(FAILED(m_pFileStream->OpenForWrite(outFilePath)))
+ {
+ delete(m_pFileStream);
+ m_pFileStream = NULL;
+ return;
+ }
+
+ QueryPerformanceCounter(&m_fileOpenTimeStamp);
+
+ SString fileStart(W("{\n\"StackSource\" : {\n\"Samples\" : [\n"));
+ Write(fileStart);
+}
+
+EventPipeJsonFile::~EventPipeJsonFile()
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ if(m_pFileStream != NULL)
+ {
+ if(!m_writeErrorEncountered)
+ {
+ SString closingString(W("]}}"));
+ Write(closingString);
+ }
+
+ delete(m_pFileStream);
+ m_pFileStream = NULL;
+ }
+}
+
+void EventPipeJsonFile::WriteEvent(CommonEventFields &commonFields, SString &message, StackContents &stackContents)
+{
+ STANDARD_VM_CONTRACT;
+
+ if(m_pFileStream == NULL || m_writeErrorEncountered)
+ {
+ return;
+ }
+
+ // Format the call stack.
+ SString strCallStack;
+ FormatCallStack(stackContents, strCallStack);
+
+ // Convert the timestamp from a QPC value to a trace-relative timestamp.
+ double millisecondsSinceTraceStart = 0.0;
+ if(commonFields.TimeStamp.QuadPart != m_fileOpenTimeStamp.QuadPart)
+ {
+ LARGE_INTEGER elapsedNanoseconds;
+ elapsedNanoseconds.QuadPart = commonFields.TimeStamp.QuadPart - m_fileOpenTimeStamp.QuadPart;
+ millisecondsSinceTraceStart = elapsedNanoseconds.QuadPart / 1000000.0;
+ }
+
+ StackScratchBuffer scratch;
+ SString threadFrame;
+ threadFrame.Printf("Thread (%d)", commonFields.ThreadID);
+ SString event;
+ event.Printf("{\"Time\" : \"%f\", \"Metric\" : \"1\",\n\"Stack\": [\n\"%s\",\n%s\"%s\"]},", millisecondsSinceTraceStart, message.GetANSI(scratch), strCallStack.GetANSI(scratch), threadFrame.GetANSI(scratch));
+ Write(event);
+}
+
+void EventPipeJsonFile::Write(SString &str)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ StackScratchBuffer scratch;
+ const char * charStr = str.GetANSI(scratch);
+ ULONG inCount = str.GetCount();
+ ULONG outCount;
+ m_pFileStream->Write(charStr, inCount, &outCount);
+
+ if(inCount != outCount)
+ {
+ m_writeErrorEncountered = true;
+ }
+}
+
+void EventPipeJsonFile::FormatCallStack(StackContents &stackContents, SString &resultStr)
+{
+ STANDARD_VM_CONTRACT;
+
+ StackScratchBuffer scratch;
+ SString frameStr;
+
+ for(unsigned int i=0; i<stackContents.GetLength(); i++)
+ {
+ // Get the method declaration string.
+ MethodDesc *pMethod = stackContents.GetMethod(i);
+ _ASSERTE(pMethod != NULL);
+
+ SString mAssemblyName;
+ mAssemblyName.SetUTF8(pMethod->GetLoaderModule()->GetAssembly()->GetSimpleName());
+ SString fullName;
+ TypeString::AppendMethodInternal(
+ fullName,
+ pMethod,
+ TypeString::FormatNamespace | TypeString::FormatSignature);
+
+ frameStr.Printf("\"%s!%s\",\n", mAssemblyName.GetANSI(scratch), fullName.GetANSI(scratch));
+ resultStr.Append(frameStr);
+ }
+}
diff --git a/src/vm/eventpipejsonfile.h b/src/vm/eventpipejsonfile.h
new file mode 100644
index 0000000000..b6e42def68
--- /dev/null
+++ b/src/vm/eventpipejsonfile.h
@@ -0,0 +1,40 @@
+// 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.
+
+
+#ifndef __EVENTPIPE_JSONFILE_H__
+#define __EVENTPIPE_JSONFILE_H__
+
+#include "common.h"
+#include "eventpipe.h"
+#include "fstream.h"
+
+class EventPipeJsonFile
+{
+ public:
+ EventPipeJsonFile(SString &outFilePath);
+ ~EventPipeJsonFile();
+
+ // Write an event with the specified message and stack.
+ void WriteEvent(CommonEventFields &commonFields, SString &message, StackContents &stackContents);
+
+ private:
+
+ // Write a string to the file.
+ void Write(SString &str);
+
+ // Format the input callstack for printing.
+ void FormatCallStack(StackContents &stackContents, SString &resultStr);
+
+ // The output file stream.
+ CFileStream *m_pFileStream;
+
+ // Keep track of if an error has been encountered while writing.
+ bool m_writeErrorEncountered;
+
+ // File-open timestamp for use when calculating event timestamps.
+ LARGE_INTEGER m_fileOpenTimeStamp;
+};
+
+#endif // __EVENTPIPE_JSONFILE_H__
diff --git a/src/vm/eventreporter.cpp b/src/vm/eventreporter.cpp
index 567f4f5d51..c73af36b55 100644
--- a/src/vm/eventreporter.cpp
+++ b/src/vm/eventreporter.cpp
@@ -20,9 +20,7 @@
#include "../dlls/mscorrc/resource.h"
-#if defined(FEATURE_CORECLR)
#include "getproductversionnumber.h"
-#endif // FEATURE_CORECLR
//---------------------------------------------------------------------------------------
//
@@ -66,7 +64,7 @@ EventReporter::EventReporter(EventReporterType type)
{
// If app name has a '\', consider the part after that; otherwise consider whole name.
LPCWSTR appName = wcsrchr(appPath, W('\\'));
- appName = appName ? appName+1 : appPath;
+ appName = appName ? appName+1 : (LPCWSTR)appPath;
m_Description.Append(appName);
m_Description.Append(W("\n"));
}
@@ -84,30 +82,13 @@ EventReporter::EventReporter(EventReporterType type)
ssMessage.Clear();
if(!ssMessage.LoadResource(CCompRC::Optional, IDS_ER_FRAMEWORK_VERSION))
-#ifndef FEATURE_CORECLR
- m_Description.Append(W("Framework Version: "));
-#else // FEATURE_CORECLR
m_Description.Append(W("CoreCLR Version: "));
-#endif // !FEATURE_CORECLR
else
{
m_Description.Append(ssMessage);
}
BOOL fHasVersion = FALSE;
-#ifndef FEATURE_CORECLR
- if (GetCLRModule() != NULL)
- {
- WCHAR buffer[80];
- DWORD length;
- if (SUCCEEDED(GetCORVersionInternal(buffer, 80, &length)))
- {
- m_Description.Append(buffer);
- m_Description.Append(W("\n"));
- fHasVersion = TRUE;
- }
- }
-#else // FEATURE_CORECLR
DWORD dwMajorVersion = 0;
DWORD dwMinorVersion = 0;
DWORD dwBuild = 0;
@@ -115,7 +96,6 @@ EventReporter::EventReporter(EventReporterType type)
EventReporter::GetCoreCLRInstanceProductVersion(&dwMajorVersion, &dwMinorVersion, &dwBuild, &dwRevision);
m_Description.AppendPrintf(W("%lu.%lu.%lu.%lu\n"),dwMajorVersion, dwMinorVersion, dwBuild, dwRevision);
fHasVersion = TRUE;
-#endif // !FEATURE_CORECLR
if (!fHasVersion)
{
@@ -699,7 +679,6 @@ void DoReportForUnhandledException(PEXCEPTION_POINTERS pExceptionInfo)
gc.throwable = pThread->GetThrowable();
_ASSERTE(gc.throwable != NULL);
-#ifdef FEATURE_CORECLR
// On CoreCLR, managed code execution happens in non-default AppDomains and all threads have an AD transition
// at their base from DefaultDomain to the target Domain before they start executing managed code. Thus, when
// an exception goes unhandled in a non-default AppDomain on a reverse pinvoke thread, the original exception details are copied
@@ -741,7 +720,6 @@ void DoReportForUnhandledException(PEXCEPTION_POINTERS pExceptionInfo)
}
}
else
-#endif // FEATURE_CORECLR
{
if (IsException(gc.throwable->GetMethodTable()))
{
@@ -796,7 +774,6 @@ void DoReportForUnhandledException(PEXCEPTION_POINTERS pExceptionInfo)
}
}
-#if defined(FEATURE_CORECLR)
// This function will return the product version of CoreCLR
// instance we are executing in.
void EventReporter::GetCoreCLRInstanceProductVersion(DWORD * pdwMajor, DWORD * pdwMinor, DWORD * pdwBuild, DWORD * pdwRevision)
@@ -834,4 +811,3 @@ void EventReporter::GetCoreCLRInstanceProductVersion(DWORD * pdwMajor, DWORD * p
LOG((LF_CORDB, LL_INFO100, "GetCoreCLRInstanceVersion: Unable to get CoreCLR version.\n"));
}
}
-#endif // FEATURE_CORECLR
diff --git a/src/vm/eventreporter.h b/src/vm/eventreporter.h
index ecbc9d1382..54317133dd 100644
--- a/src/vm/eventreporter.h
+++ b/src/vm/eventreporter.h
@@ -49,9 +49,7 @@ private:
// Flag to indicate if the buffer is full
BOOL fBufferFull;
-#ifdef FEATURE_CORECLR
static void GetCoreCLRInstanceProductVersion(DWORD * pdwMajor, DWORD * pdwMinor, DWORD * pdwBuild, DWORD * pdwRevision);
-#endif // FEATURE_CORECLR
public:
// Construct
diff --git a/src/vm/eventtrace.cpp b/src/vm/eventtrace.cpp
index 2bdd441a9a..1eb89385a6 100644
--- a/src/vm/eventtrace.cpp
+++ b/src/vm/eventtrace.cpp
@@ -439,8 +439,8 @@ VOID ETW::GCLog::GCSettingsEvent()
ETW::GCLog::ETW_GC_INFO Info;
Info.GCSettings.ServerGC = GCHeapUtilities::IsServerHeap ();
- Info.GCSettings.SegmentSize = GCHeapUtilities::GetGCHeap()->GetValidSegmentSize (FALSE);
- Info.GCSettings.LargeObjectSegmentSize = GCHeapUtilities::GetGCHeap()->GetValidSegmentSize (TRUE);
+ Info.GCSettings.SegmentSize = GCHeapUtilities::GetGCHeap()->GetValidSegmentSize (false);
+ Info.GCSettings.LargeObjectSegmentSize = GCHeapUtilities::GetGCHeap()->GetValidSegmentSize (true);
FireEtwGCSettings_V1(Info.GCSettings.SegmentSize, Info.GCSettings.LargeObjectSegmentSize, Info.GCSettings.ServerGC, GetClrInstanceId());
}
GCHeapUtilities::GetGCHeap()->DiagTraceGCSegments();
@@ -1035,7 +1035,7 @@ HRESULT ETW::GCLog::ForceGCForDiagnostics()
hr = GCHeapUtilities::GetGCHeap()->GarbageCollect(
-1, // all generations should be collected
- FALSE, // low_memory_p
+ false, // low_memory_p
collection_blocking);
#ifndef FEATURE_REDHAWK
@@ -4310,42 +4310,15 @@ HRESULT ETW::CEtwTracer::Register()
{
WRAPPER_NO_CONTRACT;
-#ifndef FEATURE_CORESYSTEM
- OSVERSIONINFO osVer;
- osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-
- if (GetOSVersion(&osVer) == FALSE) {
- return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
- }
- else if (osVer.dwMajorVersion < ETW_SUPPORTED_MAJORVER) {
- return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
- }
-
- // if running on OS < Longhorn, skip registration unless reg key is set
- // since ETW reg is expensive (in both time and working set) on older OSes
- if (osVer.dwMajorVersion < ETW_ENABLED_MAJORVER && !g_fEnableETW && !CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PreVistaETWEnabled))
- return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
-
- // If running on OS >= Longhorn, skip registration if ETW is not enabled
- if (osVer.dwMajorVersion >= ETW_ENABLED_MAJORVER && !g_fEnableETW && !CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_VistaAndAboveETWEnabled))
- return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
-#endif
-
EventRegisterMicrosoft_Windows_DotNETRuntime();
EventRegisterMicrosoft_Windows_DotNETRuntimePrivate();
EventRegisterMicrosoft_Windows_DotNETRuntimeRundown();
// Stress Log ETW events are available only on the desktop version of the runtime
-#ifndef FEATURE_CORECLR
- EventRegisterMicrosoft_Windows_DotNETRuntimeStress();
-#endif // !FEATURE_CORECLR
MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context.RegistrationHandle = Microsoft_Windows_DotNETRuntimeHandle;
MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context.RegistrationHandle = Microsoft_Windows_DotNETRuntimePrivateHandle;
MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_Context.RegistrationHandle = Microsoft_Windows_DotNETRuntimeRundownHandle;
-#ifndef FEATURE_CORECLR
- MICROSOFT_WINDOWS_DOTNETRUNTIME_STRESS_PROVIDER_Context.RegistrationHandle = Microsoft_Windows_DotNETRuntimeStressHandle;
-#endif // !FEATURE_CORECLR
return S_OK;
}
@@ -4371,9 +4344,6 @@ HRESULT ETW::CEtwTracer::UnRegister()
EventUnregisterMicrosoft_Windows_DotNETRuntime();
EventUnregisterMicrosoft_Windows_DotNETRuntimePrivate();
EventUnregisterMicrosoft_Windows_DotNETRuntimeRundown();
-#ifndef FEATURE_CORECLR
- EventUnregisterMicrosoft_Windows_DotNETRuntimeStress();
-#endif // !FEATURE_CORECLR
return S_OK;
}
@@ -4923,11 +4893,7 @@ VOID ETW::InfoLog::RuntimeInformation(INT32 type)
g_fEEComActivatedStartup || //CLR started as a COM object
g_fEEOtherStartup ); //In case none of the 4 above mentioned cases are true for example ngen, ildasm then we asssume its a "other" startup
-#ifdef FEATURE_CORECLR
Sku = ETW::InfoLog::InfoStructs::CoreCLR;
-#else
- Sku = ETW::InfoLog::InfoStructs::DesktopCLR;
-#endif //FEATURE_CORECLR
//version info for clr.dll
USHORT vmMajorVersion = VER_MAJORVERSION;
@@ -4946,30 +4912,6 @@ VOID ETW::InfoLog::RuntimeInformation(INT32 type)
PCWSTR lpwszCommandLine = W("");
-#ifndef FEATURE_CORECLR
- startupFlags = CorHost2::GetStartupFlags();
-
- // Some of the options specified by the startup flags can be overwritten by config files.
- // Strictly speaking since the field in this event is called StartupFlags there's nothing
- // wrong with just showing the actual startup flags but it makes it less useful (a more
- // appropriate name for the field is StartupOptions).
- startupFlags &= ~STARTUP_CONCURRENT_GC;
- if (g_pConfig->GetGCconcurrent())
- startupFlags |= STARTUP_CONCURRENT_GC;
-
- if (g_pConfig->DefaultSharePolicy() != AppDomain::SHARE_POLICY_UNSPECIFIED)
- {
- startupFlags &= ~STARTUP_LOADER_OPTIMIZATION_MASK;
- startupFlags |= g_pConfig->DefaultSharePolicy() << 1;
- }
-
- startupFlags &= ~STARTUP_LEGACY_IMPERSONATION;
- startupFlags &= ~STARTUP_ALWAYSFLOW_IMPERSONATION;
- if (g_pConfig->ImpersonationMode() == IMP_NOFLOW)
- startupFlags |= STARTUP_LEGACY_IMPERSONATION;
- else if (g_pConfig->ImpersonationMode() == IMP_ALWAYSFLOW)
- startupFlags |= STARTUP_ALWAYSFLOW_IMPERSONATION;
-#endif //!FEATURE_CORECLR
// Determine the startupmode
if(g_fEEIJWStartup)
@@ -5454,9 +5396,6 @@ VOID ETW::MethodLog::MethodTableRestored(MethodTable *pMethodTable)
TRACE_LEVEL_INFORMATION,
CLR_STARTENUMERATION_KEYWORD))
{
-#ifdef FEATURE_REMOTING
- if(!pMethodTable->IsTransparentProxy())
-#endif
{
MethodTable::MethodIterator iter(pMethodTable);
for (; iter.IsValid(); iter.Next())
@@ -5477,9 +5416,6 @@ VOID ETW::MethodLog::MethodTableRestored(MethodTable *pMethodTable)
VOID ETW::SecurityLog::StrongNameVerificationStart(DWORD dwInFlags, __in LPWSTR strFullyQualifiedAssemblyName)
{
WRAPPER_NO_CONTRACT;
-#ifndef FEATURE_CORECLR
- FireEtwStrongNameVerificationStart_V1(dwInFlags, 0, strFullyQualifiedAssemblyName, GetClrInstanceId());
-#endif // !FEATURE_CORECLR
}
@@ -5489,9 +5425,6 @@ VOID ETW::SecurityLog::StrongNameVerificationStart(DWORD dwInFlags, __in LPWSTR
VOID ETW::SecurityLog::StrongNameVerificationStop(DWORD dwInFlags,ULONG result, __in LPWSTR strFullyQualifiedAssemblyName)
{
WRAPPER_NO_CONTRACT;
-#ifndef FEATURE_CORECLR
- FireEtwStrongNameVerificationStop_V1(dwInFlags, result, strFullyQualifiedAssemblyName, GetClrInstanceId());
-#endif // !FEATURE_CORECLR
}
/****************************************************************************/
@@ -5832,9 +5765,6 @@ VOID ETW::LoaderLog::SendAssemblyEvent(Assembly *pAssembly, DWORD dwEventOptions
ULONGLONG ullAssemblyId = (ULONGLONG)pAssembly;
ULONGLONG ullDomainId = (ULONGLONG)pAssembly->GetDomain();
ULONGLONG ullBindingID = 0;
-#if (defined FEATURE_PREJIT) && (defined FEATURE_FUSION)
- ullBindingID = pAssembly->GetManifestFile()->GetBindingID();
-#endif
ULONG ulAssemblyFlags = ((bIsDomainNeutral ? ETW::LoaderLog::LoaderStructs::DomainNeutralAssembly : 0) |
(bIsDynamicAssembly ? ETW::LoaderLog::LoaderStructs::DynamicAssembly : 0) |
(bHasNativeImage ? ETW::LoaderLog::LoaderStructs::NativeAssembly : 0) |
diff --git a/src/vm/excep.cpp b/src/vm/excep.cpp
index 78a8f0e6eb..630d3f5f37 100644
--- a/src/vm/excep.cpp
+++ b/src/vm/excep.cpp
@@ -48,20 +48,10 @@
#include <msodw.h>
#endif // FEATURE_PAL
-#ifdef FEATURE_UEF_CHAINMANAGER
-// This is required to register our UEF callback with the UEF chain manager
-#include <mscoruefwrapper.h>
-// The global UEFManager reference for use in the VM
-IUEFManager * g_pUEFManager = NULL;
-#endif // FEATURE_UEF_CHAINMANAGER
// Support for extracting MethodDesc of a delegate.
#include "comdelegate.h"
-#if defined(FEATURE_APPX_BINDER) && !defined(DACCESS_COMPILE)
-// For determining if we have a framework assembly trying to handle a corrupted state exception
-#include "policy.h"
-#endif // FEATURE_APPX && !DACCESS_COMPILE
#ifndef FEATURE_PAL
// Windows uses 64kB as the null-reference area
@@ -2287,7 +2277,6 @@ void StackTraceInfo::SaveStackTrace(BOOL bAllowAllocMem, OBJECTHANDLE hThrowable
// Do not save stacktrace to preallocated exception. These are shared.
if (CLRException::IsPreallocatedExceptionHandle(hThrowable))
{
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
// Preallocated exceptions will never have this flag set. However, its possible
// that after this flag is set for a regular exception but before we throw, we have an async
// exception like a RudeThreadAbort, which will replace the exception
@@ -2297,7 +2286,6 @@ void StackTraceInfo::SaveStackTrace(BOOL bAllowAllocMem, OBJECTHANDLE hThrowable
// preallocated exception will not have the restored (or any) stack trace.
PTR_ThreadExceptionState pCurTES = GetThread()->GetExceptionState();
pCurTES->ResetRaisingForeignException();
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
return;
}
@@ -2310,14 +2298,12 @@ void StackTraceInfo::SaveStackTrace(BOOL bAllowAllocMem, OBJECTHANDLE hThrowable
bool fSuccess = false;
MethodTable* pMT = ObjectFromHandle(hThrowable)->GetTrueMethodTable();
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
// Check if the flag indicating foreign exception raise has been setup or not,
// and then reset it so that subsequent processing of managed frames proceeds
// normally.
PTR_ThreadExceptionState pCurTES = GetThread()->GetExceptionState();
BOOL fRaisingForeignException = pCurTES->IsRaisingForeignException();
pCurTES->ResetRaisingForeignException();
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
if (bAllowAllocMem && m_dFrameCount != 0)
{
@@ -2358,19 +2344,15 @@ void StackTraceInfo::SaveStackTrace(BOOL bAllowAllocMem, OBJECTHANDLE hThrowable
struct _gc
{
StackTraceArray stackTrace;
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
StackTraceArray stackTraceTemp;
PTRARRAYREF dynamicMethodsArrayTemp;
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
PTRARRAYREF dynamicMethodsArray; // Object array of Managed Resolvers
PTRARRAYREF pOrigDynamicArray;
_gc()
: stackTrace()
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
, stackTraceTemp()
, dynamicMethodsArrayTemp(static_cast<PTRArray *>(NULL))
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
, dynamicMethodsArray(static_cast<PTRArray *>(NULL))
, pOrigDynamicArray(static_cast<PTRArray *>(NULL))
{}
@@ -2379,7 +2361,6 @@ void StackTraceInfo::SaveStackTrace(BOOL bAllowAllocMem, OBJECTHANDLE hThrowable
_gc gc;
GCPROTECT_BEGIN(gc);
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
// If the flag indicating foreign exception raise has been setup, then check
// if the exception object has stacktrace or not. If we have an async non-preallocated
// exception after setting this flag but before we throw, then the new
@@ -2394,14 +2375,11 @@ void StackTraceInfo::SaveStackTrace(BOOL bAllowAllocMem, OBJECTHANDLE hThrowable
fRaisingForeignException = FALSE;
}
}
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
// Replace stack (i.e. build a new stack trace) only if we are not raising a foreign exception.
// If we are, then we will continue to extend the existing stack trace.
if (bReplaceStack
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
&& (!fRaisingForeignException)
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
)
{
// Cleanup previous info
@@ -2435,7 +2413,6 @@ void StackTraceInfo::SaveStackTrace(BOOL bAllowAllocMem, OBJECTHANDLE hThrowable
// Fetch the stacktrace and the dynamic method array
((EXCEPTIONREF)ObjectFromHandle(hThrowable))->GetStackTrace(gc.stackTrace, &gc.pOrigDynamicArray);
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
if (fRaisingForeignException)
{
// Just before we append to the stack trace, mark the last recorded frame to be from
@@ -2450,7 +2427,6 @@ void StackTraceInfo::SaveStackTrace(BOOL bAllowAllocMem, OBJECTHANDLE hThrowable
refLastElementFromForeignStackTrace.fIsLastFrameFromForeignStackTrace = TRUE;
}
}
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
if (bSkipLastElement && gc.stackTrace.Size() != 0)
gc.stackTrace.AppendSkipLast(m_pStackTrace, m_pStackTrace + m_dFrameCount);
@@ -2472,9 +2448,7 @@ void StackTraceInfo::SaveStackTrace(BOOL bAllowAllocMem, OBJECTHANDLE hThrowable
}
if ((gc.pOrigDynamicArray != NULL)
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
|| (fRaisingForeignException)
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
)
{
// Since we have just restored the dynamic method array as well,
@@ -3768,12 +3742,10 @@ BOOL StackTraceInfo::AppendElement(BOOL bAllowAllocMem, UINT_PTR currentIP, UINT
pStackTraceElem->ip = currentIP;
pStackTraceElem->sp = currentSP;
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
// When we are building stack trace as we encounter managed frames during exception dispatch,
// then none of those frames represent a stack trace from a foreign exception (as they represent
// the current exception). Hence, set the corresponding flag to FALSE.
pStackTraceElem->fIsLastFrameFromForeignStackTrace = FALSE;
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
// This is a workaround to fix the generation of stack traces from exception objects so that
// they point to the line that actually generated the exception instead of the line
@@ -4031,6 +4003,7 @@ LONG NotifyDebuggerLastChance(Thread *pThread,
UNINSTALL_NESTED_EXCEPTION_HANDLER();
+#ifdef DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED
EX_TRY
{
// if the debugger wants to intercept the unhandled exception then we immediately unwind without returning
@@ -4050,6 +4023,7 @@ LONG NotifyDebuggerLastChance(Thread *pThread,
{
}
EX_END_CATCH(SwallowAllExceptions);
+#endif // DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED
return retval;
}
@@ -4125,32 +4099,6 @@ void DisableOSWatson(void)
SetErrorMode(lastErrorMode | SEM_NOGPFAULTERRORBOX);
LOG((LF_EH, LL_INFO100, "DisableOSWatson: SetErrorMode = 0x%x\n", lastErrorMode | SEM_NOGPFAULTERRORBOX));
-#ifndef FEATURE_CORECLR
- // CoreCLR is always hosted and so this condition is always false
- if (RunningOnWin7() && !CLRHosted())
- {
- typedef DWORD (WINAPI * GetThreadErrorModeFnPtr)(void);
- typedef BOOL (WINAPI * SetThreadErrorModeFnPtr)(DWORD, LPDWORD);
- GetThreadErrorModeFnPtr pFnGetThreadErrorMode;
- SetThreadErrorModeFnPtr pFnSetThreadErrorMode;
-
- HINSTANCE hKernel32 = WszGetModuleHandle(WINDOWS_KERNEL32_DLLNAME_W);
- if (hKernel32 != NULL)
- {
- pFnGetThreadErrorMode = (GetThreadErrorModeFnPtr)GetProcAddress(hKernel32, "GetThreadErrorMode");
- pFnSetThreadErrorMode = (SetThreadErrorModeFnPtr)GetProcAddress(hKernel32, "SetThreadErrorMode");
-
- // GetThreadErrorMode and SetThreadErrorMode should be available on Win7.
- _ASSERTE((pFnGetThreadErrorMode != NULL) && (pFnSetThreadErrorMode != NULL));
- if ((pFnGetThreadErrorMode != NULL) && (pFnSetThreadErrorMode != NULL))
- {
- DWORD dwOldMode = (*pFnGetThreadErrorMode)();
- (*pFnSetThreadErrorMode)(dwOldMode | SEM_NOGPFAULTERRORBOX, &dwOldMode);
- LOG((LF_EH, LL_INFO100, "DisableOSWatson: SetThreadErrorMode = 0x%x\n", dwOldMode | SEM_NOGPFAULTERRORBOX));
- }
- }
- }
-#endif // FEATURE_CORECLR
}
@@ -4390,14 +4338,7 @@ LONG WatsonLastChance( // EXCEPTION_CONTINUE_SEARCH, _CONTINUE_
result = DoFaultReport(pExceptionInfo, tore);
// Set the event to indicate that Watson processing is completed. Other threads can continue.
-#if defined(FEATURE_UEF_CHAINMANAGER)
- if (g_pUEFManager)
- {
- g_pUEFManager->GetWastonSxSManagerInstance()->SignalWatsonSxSCompletionEvent();
- }
-#else
UnsafeSetEvent(g_hWatsonCompletionEvent);
-#endif // FEATURE_UEF_CHAINMANAGER
}
}
@@ -4870,7 +4811,6 @@ LONG DefaultCatchNoSwallowFilter(EXCEPTION_POINTERS *ep, PVOID pv)
return EXCEPTION_CONTINUE_SEARCH;
} // LONG DefaultCatchNoSwallowFilter()
-#if defined(FEATURE_CORECLR)
// Note: This is used only for CoreCLR on WLC.
//
// We keep a pointer to the previous unhandled exception filter. After we install, we use
@@ -4883,7 +4823,6 @@ LONG DefaultCatchNoSwallowFilter(EXCEPTION_POINTERS *ep, PVOID pv)
// yet and having installed it but the original handler was NULL.
static LPTOP_LEVEL_EXCEPTION_FILTER g_pOriginalUnhandledExceptionFilter = (LPTOP_LEVEL_EXCEPTION_FILTER)-1;
#define FILTER_NOT_INSTALLED (LPTOP_LEVEL_EXCEPTION_FILTER) -1
-#endif // defined(FEATURE_CORECLR)
BOOL InstallUnhandledExceptionFilter() {
@@ -4893,88 +4832,6 @@ BOOL InstallUnhandledExceptionFilter() {
STATIC_CONTRACT_FORBID_FAULT;
#ifndef FEATURE_PAL
-#ifdef FEATURE_UEF_CHAINMANAGER
- if (g_pUEFManager == NULL) {
-
- /*CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_PREEMPTIVE;
- } CONTRACTL_END;*/
-
- static HMODULE hMSCorEE;
-
- if (!hMSCorEE) {
- hMSCorEE = WszGetModuleHandle(MSCOREE_SHIM_W);
- if (!hMSCorEE) {
-
- _ASSERTE(!"InstallUnhandledExceptionFilter failed to get MSCorEE instance!");
- STRESS_LOG0(LF_EH, LL_INFO10, "InstallUnhandledExceptionFilter failed to get MSCorEE instance!\n");
-
- // Failure to get instance of mscoree.dll is fatal since that would imply
- // that we cannot setup our UEF
- return FALSE;
- }
- }
-
- // Signature of GetCLRUEFManager exported by MSCorEE.dll
- typedef HRESULT (*pGetCLRUEFManager)(REFIID riid,
- IUnknown **ppUnk);
-
- static pGetCLRUEFManager pFuncGetCLRUEFManager;
-
- if (!pFuncGetCLRUEFManager) {
-
- // Try to get function address via ordinal
- pFuncGetCLRUEFManager = (pGetCLRUEFManager)GetProcAddress(hMSCorEE, MAKEINTRESOURCEA(24));
- if (!pFuncGetCLRUEFManager) {
- _ASSERTE(!"InstallUnhandledExceptionFilter failed to get UEFManager!");
- STRESS_LOG0(LF_EH, LL_INFO10, "InstallUnhandledExceptionFilter failed to find UEFManager!\n");
- return FALSE;
- }
- }
-
- HRESULT hr = (*pFuncGetCLRUEFManager)((REFIID)IID_IUEFManager, (IUnknown **)&g_pUEFManager);
- if (FAILED(hr))
- {
- _ASSERTE(!"InstallUnhandledExceptionFilter failed to get IUEFManager*!");
-
- STRESS_LOG0(LF_EH, LL_INFO10, "InstallUnhandledExceptionFilter failed to get IUEFManager*\n");
-
- // Ensure the reference to chain manager is NULL
- g_pUEFManager= NULL;
-
- return FALSE;
- }
-
- // Register our UEF callback with the UEF chain manager
- if (!g_pUEFManager->AddUnhandledExceptionFilter(COMUnhandledExceptionFilter, TRUE))
- {
- _ASSERTE(!"InstallUnhandledExceptionFilter failed to register the UEF callback!");
-
- // Failed to register the UEF callback
- STRESS_LOG0(LF_EH, LL_INFO10, "InstallUnhandledExceptionFilter failed to register the UEF callback!\n");
-
- g_pUEFManager->Release();
-
- // Ensure the reference to chain manager is NULL
- g_pUEFManager= NULL;
-
- return FALSE;
- }
-
- // Register our exception claiming callback with the UEF chain manager on preWin7
- if (!RunningOnWin7() && !g_pUEFManager->GetWastonSxSManagerInstance()->RegisterExceptionClaimingCallback(IsExceptionFromManagedCodeCallback))
- {
- _ASSERTE(!"RegisterExceptionClaimingCallback failed to register the exception claiming callback!");
-
- // Failed to register the exception claiming callback
- STRESS_LOG0(LF_EH, LL_INFO10, "RegisterExceptionClaimingCallback failed to register the exception claiming callback!");
-
- return FALSE;
- }
- }
-#else // !FEATURE_UEF_CHAINMANAGER
// We will be here only for CoreCLR on WLC since we dont
// register UEF for SL.
if (g_pOriginalUnhandledExceptionFilter == FILTER_NOT_INSTALLED) {
@@ -4988,7 +4845,6 @@ BOOL InstallUnhandledExceptionFilter() {
LOG((LF_EH, LL_INFO10, "InstallUnhandledExceptionFilter registered UEF with OS for CoreCLR!\n"));
}
_ASSERTE(g_pOriginalUnhandledExceptionFilter != FILTER_NOT_INSTALLED);
-#endif // FEATURE_UEF_CHAINMANAGER
#endif // !FEATURE_PAL
// All done - successfully!
@@ -5002,19 +4858,6 @@ void UninstallUnhandledExceptionFilter() {
STATIC_CONTRACT_FORBID_FAULT;
#ifndef FEATURE_PAL
-#ifdef FEATURE_UEF_CHAINMANAGER
- if (g_pUEFManager)
- {
- if (!RunningOnWin7())
- {
- g_pUEFManager->GetWastonSxSManagerInstance()->UnregisterExceptionClaimingCallback(IsExceptionFromManagedCodeCallback);
- }
-
- g_pUEFManager->RemoveUnhandledExceptionFilter(COMUnhandledExceptionFilter);
- g_pUEFManager->Release();
- g_pUEFManager = NULL;
- }
-#else // !FEATURE_UEF_CHAINMANAGER
// We will be here only for CoreCLR on WLC or on Mac SL.
if (g_pOriginalUnhandledExceptionFilter != FILTER_NOT_INSTALLED) {
@@ -5026,7 +4869,6 @@ void UninstallUnhandledExceptionFilter() {
g_pOriginalUnhandledExceptionFilter = FILTER_NOT_INSTALLED;
LOG((LF_EH, LL_INFO10, "UninstallUnhandledExceptionFilter unregistered UEF from OS for CoreCLR!\n"));
}
-#endif // FEATURE_UEF_CHAINMANAGER
#endif // !FEATURE_PAL
}
@@ -5234,7 +5076,6 @@ LONG InternalUnhandledExceptionFilter_Worker(
//
if (pThread && (pThread->HasThreadStateNC(Thread::TSNC_ProcessedUnhandledException) || pThread->HasThreadStateNC(Thread::TSNC_AppDomainContainUnhandled)))
{
-#ifdef FEATURE_CORECLR
// This assert shouldnt be hit in CoreCLR since:
//
// 1) It has no concept of managed entry point that is invoked by the shim. You can
@@ -5248,7 +5089,6 @@ LONG InternalUnhandledExceptionFilter_Worker(
{
_ASSERTE(!"How come a thread with TSNC_ProcessedUnhandledException state entered the UEF on CoreCLR?");
}
-#endif // FEATURE_CORECLR
LOG((LF_EH, LL_INFO100, "InternalUnhandledExceptionFilter_Worker: have already processed unhandled exception for this thread.\n"));
return EXCEPTION_CONTINUE_SEARCH;
@@ -5330,7 +5170,6 @@ LONG InternalUnhandledExceptionFilter_Worker(
{
BOOL fIsProcessTerminating = TRUE;
-#ifdef FEATURE_CORECLR
// In CoreCLR, we can be asked to not let an exception go unhandled on managed threads in a given AppDomain.
// If the exception reaches the top of the thread's stack, we simply deliver AppDomain's UnhandledException event and
// return back to the filter, instead of letting the process terminate because of unhandled exception.
@@ -5354,7 +5193,6 @@ LONG InternalUnhandledExceptionFilter_Worker(
fIsProcessTerminating = !(pParam->pThread->GetDomain()->IgnoreUnhandledExceptions());
else
fIsProcessTerminating = !(pParam->pThread->HasThreadStateNC(Thread::TSNC_IgnoreUnhandledExceptions));
-#endif // FEATURE_CORECLR
#ifndef FEATURE_PAL
// Setup the watson bucketing details for UE processing.
@@ -5366,14 +5204,12 @@ LONG InternalUnhandledExceptionFilter_Worker(
// Send notifications to the AppDomains.
NotifyAppDomainsOfUnhandledException(pParam->pExceptionInfo, NULL, useLastThrownObject, fIsProcessTerminating /*isTerminating*/);
-#ifdef FEATURE_CORECLR
// If the process is not terminating, then return back to the filter and ask it to execute
if (!fIsProcessTerminating)
{
pParam->retval = EXCEPTION_EXECUTE_HANDLER;
goto lDone;
}
-#endif // FEATURE_CORECLR
}
else
{
@@ -5559,7 +5395,6 @@ LONG InternalUnhandledExceptionFilter(
//
// Note: Also see the conditional UEF registration with the OS in EEStartupHelper.
-#ifdef FEATURE_CORECLR
// We would be here only on CoreCLR for WLC since we dont register
// the UEF with the OS for SL.
if (g_pOriginalUnhandledExceptionFilter != FILTER_NOT_INSTALLED
@@ -5567,7 +5402,6 @@ LONG InternalUnhandledExceptionFilter(
{
STRESS_LOG1(LF_EH, LL_INFO100, "InternalUnhandledExceptionFilter: Not chaining back to previous UEF at address %p on CoreCLR!\n", g_pOriginalUnhandledExceptionFilter);
}
-#endif // FEATURE_CORECLR
return retval;
@@ -5606,14 +5440,6 @@ LONG EntryPointFilter(PEXCEPTION_POINTERS pExceptionInfo, PVOID _pData)
pThread->SetThreadStateNC(Thread::TSNC_ProcessedUnhandledException);
}
-#ifdef FEATURE_UEF_CHAINMANAGER
- if (g_pUEFManager && (ret == EXCEPTION_CONTINUE_SEARCH))
- {
- // Since the "UEF" of this runtime instance didnt handle the exception,
- // invoke the other registered UEF callbacks as well
- ret = g_pUEFManager->InvokeUEFCallbacks(pExceptionInfo);
- }
-#endif // FEATURE_UEF_CHAINMANAGER
END_SO_INTOLERANT_CODE;
@@ -5635,9 +5461,9 @@ LONG EntryPointFilter(PEXCEPTION_POINTERS pExceptionInfo, PVOID _pData)
// Returns
// the result of calling InternalUnhandledExceptionFilter
//------------------------------------------------------------------------------
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if !defined(FEATURE_PAL)
#pragma code_seg(push, uef, CLR_UEF_SECTION_NAME)
-#endif // FEATURE_CORECLR && !FEATURE_PAL
+#endif // !FEATURE_PAL
LONG __stdcall COMUnhandledExceptionFilter( // EXCEPTION_CONTINUE_SEARCH or EXCEPTION_CONTINUE_EXECUTION
EXCEPTION_POINTERS *pExceptionInfo) // Information about the exception.
{
@@ -5665,47 +5491,6 @@ LONG __stdcall COMUnhandledExceptionFilter( // EXCEPTION_CONTINUE_SEARCH or
return retVal;
}
-#ifndef FEATURE_CORECLR
-#ifdef _DEBUG
- // V4 onwards, we will reach here in the UEF only on the following conditions:
- //
- // 1) Faulting address is in native code on a reverse pinvoke thread. An example is an exception that escaped
- // out of the reverse pinvoke thread but was caught in the native part of the thread. The native part then
- // had another exception that went unhandled. The difference between this and (3) below is that
- // we have a thread object here but not in (3).
- //
- // An exception from PInvoke, that is never caught/rethrown in managed code and goes unhandled, also falls
- // in this category.
- //
- // 2) The exception escaped out of a reverse pinvoke thread and went unhandled.
- //
- // 3) Faulting thread was never seen by the runtime. An example is a another native thread
- // which the user code created that had unhandled exception.
- //
- // 4) A corrupting exception may become unhandled.
- //
- // This is not applicable to CoreCLR, as this unhandled exception filter is always set up, and all hardware exceptions in
- // managed code, including those that are not process-corrupting, such as integer division by zero, will end up here.
-
- // Assert these conditions here - we shouldnt be here for any other unhandled exception processing.
- Thread *pThread = GetThread();
- if ((pThread != NULL) && // condition 3
- !(pThread->GetExceptionState()->IsExceptionInProgress() &&
- pThread->GetExceptionState()->GetFlags()->ReversePInvokeEscapingException()) && // condition 2
- (ExecutionManager::IsManagedCode((PCODE)pExceptionInfo->ExceptionRecord->ExceptionAddress))) // condition 1
- {
-#ifdef FEATURE_CORRUPTING_EXCEPTIONS
- if (!CEHelper::IsProcessCorruptedStateException(pExceptionInfo->ExceptionRecord->ExceptionCode)) // condition 4
- {
- GCX_COOP();
- _ASSERTE(CEHelper::IsProcessCorruptedStateException(pThread->GetThrowable())); // condition 4
- }
-#else // !FEATURE_CORRUPTING_EXCEPTIONS
- _ASSERTE(false);
-#endif // FEATURE_CORRUPTING_EXCEPTIONS
- }
-#endif // _DEBUG
-#endif // !FEATURE_CORECLR
retVal = InternalUnhandledExceptionFilter(pExceptionInfo);
@@ -5718,9 +5503,9 @@ LONG __stdcall COMUnhandledExceptionFilter( // EXCEPTION_CONTINUE_SEARCH or
return retVal;
} // LONG __stdcall COMUnhandledExceptionFilter()
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if !defined(FEATURE_PAL)
#pragma code_seg(pop, uef)
-#endif // FEATURE_CORECLR && !FEATURE_PAL
+#endif // !FEATURE_PAL
void PrintStackTraceToStdout();
@@ -6814,10 +6599,8 @@ exit:
#ifndef FEATURE_PAL
-#ifdef FEATURE_CORECLR
// Only proceed if Watson is enabled - CoreCLR may have it disabled.
if (IsWatsonEnabled())
-#endif // FEATURE_CORECLR
{
BOOL fClearUEWatsonBucketTracker = TRUE;
PTR_EHWatsonBucketTracker pUEWatsonBucketTracker = pThread->GetExceptionState()->GetUEWatsonBucketTracker();
@@ -7120,16 +6903,16 @@ bool IsInterceptableException(Thread *pThread)
// appropriate exception code, or zero if the code is not a GC marker.
DWORD GetGcMarkerExceptionCode(LPVOID ip)
{
-#if defined(HAVE_GCCOVER) && defined(FEATURE_CORECLR)
+#if defined(HAVE_GCCOVER)
WRAPPER_NO_CONTRACT;
if (GCStress<cfg_any>::IsEnabled() && IsGcCoverageInterrupt(ip))
{
return STATUS_CLR_GCCOVER_CODE;
}
-#else // !(defined(HAVE_GCCOVER) && defined(FEATURE_CORECLR))
+#else // defined(HAVE_GCCOVER)
LIMITED_METHOD_CONTRACT;
-#endif // defined(HAVE_GCCOVER) && defined(FEATURE_CORECLR)
+#endif // defined(HAVE_GCCOVER)
return 0;
}
@@ -7186,6 +6969,8 @@ bool IsGcMarker(DWORD exceptionCode, CONTEXT *pContext)
return false;
}
+#ifndef FEATURE_PAL
+
// Return true if the access violation is well formed (has two info parameters
// at the end)
static inline BOOL
@@ -7257,6 +7042,8 @@ IsDebuggerFault(EXCEPTION_RECORD *pExceptionRecord,
return false;
}
+#endif // FEATURE_PAL
+
#ifdef WIN64EXCEPTIONS
#ifndef _TARGET_X86_
@@ -7291,6 +7078,11 @@ bool IsIPInMarkedJitHelper(UINT_PTR uControlPc)
CHECK_RANGE(JIT_WriteBarrier)
CHECK_RANGE(JIT_CheckedWriteBarrier)
+#else
+#ifdef FEATURE_PAL
+ CHECK_RANGE(JIT_WriteBarrierGroup)
+ CHECK_RANGE(JIT_PatchedWriteBarrierGroup)
+#endif // FEATURE_PAL
#endif // _TARGET_X86_
#if defined(_TARGET_AMD64_) && defined(_DEBUG)
@@ -7316,8 +7108,8 @@ AdjustContextForWriteBarrier(
#if defined(_TARGET_X86_) && !defined(PLATFORM_UNIX)
void* f_IP = (void *)GetIP(pContext);
- if (((f_IP >= (void *) JIT_WriteBarrierStart) && (f_IP <= (void *) JIT_WriteBarrierLast)) ||
- ((f_IP >= (void *) JIT_PatchedWriteBarrierStart) && (f_IP <= (void *) JIT_PatchedWriteBarrierLast)))
+ if (((f_IP >= (void *) JIT_WriteBarrierGroup) && (f_IP <= (void *) JIT_WriteBarrierGroup_End)) ||
+ ((f_IP >= (void *) JIT_PatchedWriteBarrierGroup) && (f_IP <= (void *) JIT_PatchedWriteBarrierGroup_End)))
{
// set the exception IP to be the instruction that called the write barrier
void* callsite = (void *)GetAdjustedCallAddress(*dac_cast<PTR_PCODE>(GetSP(pContext)));
@@ -7400,6 +7192,8 @@ AdjustContextForWriteBarrier(
#endif // ELSE
}
+#if defined(USE_FEF) && !defined(FEATURE_PAL)
+
struct SavedExceptionInfo
{
EXCEPTION_RECORD m_ExceptionRecord;
@@ -7454,9 +7248,6 @@ struct SavedExceptionInfo
}
};
-
-#if defined(USE_FEF)
-
SavedExceptionInfo g_SavedExceptionInfo; // Globals are guaranteed zero-init;
void InitSavedExceptionInfo()
@@ -7534,13 +7325,13 @@ void HandleManagedFault(EXCEPTION_RECORD* pExceptionRecord,
SetIP(pContext, GetEEFuncEntryPoint(NakedThrowHelper));
}
-#else // USE_FEF
+#else // USE_FEF && !FEATURE_PAL
void InitSavedExceptionInfo()
{
}
-#endif // USE_FEF
+#endif // USE_FEF && !FEATURE_PAL
//
// Init a new frame
@@ -7654,6 +7445,8 @@ bool ShouldHandleManagedFault(
return true;
}
+#ifndef FEATURE_PAL
+
LONG WINAPI CLRVectoredExceptionHandlerPhase2(PEXCEPTION_POINTERS pExceptionInfo);
enum VEH_ACTION
@@ -8089,7 +7882,6 @@ VEH_ACTION WINAPI CLRVectoredExceptionHandlerPhase3(PEXCEPTION_POINTERS pExcepti
// Remember the EIP for stress debugging purposes.
g_LastAccessViolationEIP = (void*) ::GetIP(pContext);
-#ifndef FEATURE_PAL
// Note: we have a holder, called AVInRuntimeImplOkayHolder, that tells us that its okay to have an
// AV in the Runtime's implementation in certain places. So, if its okay to have an AV at this
// time, then skip the check for whether or not the AV is in our impl.
@@ -8153,7 +7945,6 @@ VEH_ACTION WINAPI CLRVectoredExceptionHandlerPhase3(PEXCEPTION_POINTERS pExcepti
EEPOLICY_HANDLE_FATAL_ERROR_USING_EXCEPTION_INFO(COR_E_EXECUTIONENGINE, pExceptionInfo);
}
}
-#endif // !FEATURE_PAL
}
}
else if (exceptionCode == BOOTUP_EXCEPTION_COMPLUS)
@@ -8165,6 +7956,8 @@ VEH_ACTION WINAPI CLRVectoredExceptionHandlerPhase3(PEXCEPTION_POINTERS pExcepti
return VEH_NO_ACTION;
}
+#endif // !FEATURE_PAL
+
BOOL IsIPInEE(void *ip)
{
WRAPPER_NO_CONTRACT;
@@ -8373,6 +8166,8 @@ public:
#endif // defined(_TARGET_X86_)
+#ifndef FEATURE_PAL
+
LONG WINAPI CLRVectoredExceptionHandlerShim(PEXCEPTION_POINTERS pExceptionInfo)
{
//
@@ -8520,7 +8315,6 @@ LONG WINAPI CLRVectoredExceptionHandlerShim(PEXCEPTION_POINTERS pExceptionInfo)
}
#ifdef _DEBUG
-#ifndef FEATURE_PAL
#ifndef WIN64EXCEPTIONS
{
CantAllocHolder caHolder;
@@ -8585,7 +8379,6 @@ LONG WINAPI CLRVectoredExceptionHandlerShim(PEXCEPTION_POINTERS pExceptionInfo)
}
}
}
-#endif // !FEATURE_PAL
#endif // _DEBUG
#ifndef WIN64EXCEPTIONS
@@ -8602,6 +8395,7 @@ LONG WINAPI CLRVectoredExceptionHandlerShim(PEXCEPTION_POINTERS pExceptionInfo)
return result;
}
+#endif // !FEATURE_PAL
// Contains the handle to the registered VEH
static PVOID g_hVectoredExceptionHandler = NULL;
@@ -9334,13 +9128,11 @@ BOOL SetupWatsonBucketsForNonPreallocatedExceptions(OBJECTREF oThrowable /* = NU
{
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CORECLR
// CoreCLR may have watson bucketing conditionally enabled.
if (!IsWatsonEnabled())
{
return FALSE;
}
-#endif // FEATURE_CORECLR
CONTRACTL
{
@@ -9453,13 +9245,11 @@ BOOL SetupWatsonBucketsForEscapingPreallocatedExceptions()
{
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CORECLR
// CoreCLR may have watson bucketing conditionally enabled.
if (!IsWatsonEnabled())
{
return FALSE;
}
-#endif // FEATURE_CORECLR
CONTRACTL
{
@@ -9584,13 +9374,11 @@ void SetupWatsonBucketsForUEF(BOOL fUseLastThrownObject)
{
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CORECLR
// CoreCLR may have watson bucketing conditionally enabled.
if (!IsWatsonEnabled())
{
return;
}
-#endif // FEATURE_CORECLR
CONTRACTL
{
@@ -10040,14 +9828,12 @@ BOOL SetupWatsonBucketsForFailFast(EXCEPTIONREF refException)
BOOL fResult = TRUE;
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CORECLR
// On CoreCLR, Watson may not be enabled. Thus, we should
// skip this.
if (!IsWatsonEnabled())
{
return fResult;
}
-#endif // FEATURE_CORECLR
CONTRACTL
{
@@ -10302,14 +10088,12 @@ void SetupInitialThrowBucketDetails(UINT_PTR adjustedIp)
{
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CORECLR
// On CoreCLR, Watson may not be enabled. Thus, we should
// skip this.
if (!IsWatsonEnabled())
{
return;
}
-#endif // FEATURE_CORECLR
CONTRACTL
{
@@ -10913,14 +10697,12 @@ void SetStateForWatsonBucketing(BOOL fIsRethrownException, OBJECTHANDLE ohOrigin
{
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CORECLR
// On CoreCLR, Watson may not be enabled. Thus, we should
// skip this.
if (!IsWatsonEnabled())
{
return;
}
-#endif // FEATURE_CORECLR
CONTRACTL
{
@@ -11376,12 +11158,12 @@ UINT_PTR EHWatsonBucketTracker::RetrieveWatsonBucketIp()
// This is *also* invoked from the DAC when buckets are requested.
PTR_VOID EHWatsonBucketTracker::RetrieveWatsonBuckets()
{
-#if defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE)
+#if !defined(DACCESS_COMPILE)
if (!IsWatsonEnabled())
{
return NULL;
}
-#endif // defined(FEATURE_CORECLR) && !defined(DACCESS_COMPILE)
+#endif //!defined(DACCESS_COMPILE)
CONTRACTL
{
@@ -11402,12 +11184,10 @@ void EHWatsonBucketTracker::ClearWatsonBucketDetails()
{
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CORECLR
if (!IsWatsonEnabled())
{
return;
}
-#endif // FEATURE_CORECLR
CONTRACTL
{
@@ -11665,25 +11445,6 @@ BOOL CEHelper::CanMethodHandleCE(PTR_MethodDesc pMethodDesc, CorruptionSeverity
}
CONTRACTL_END;
-#ifdef FEATURE_APPX_BINDER
- // In an Metro application, disallow application code to catch any corrupted state exception
- if (AppX::IsAppXProcess())
- {
- // This call to GetFusionAssemblyNameNoCreate will return a valid fusion assembly name
- // in the second pass of exception dispatch as the name would have been created in the first pass,
- // if not already existent.
- IAssemblyName *pIAssemblyName = pMethodDesc->GetAssembly()->GetFusionAssemblyNameNoCreate();
- if (!pIAssemblyName)
- {
- pIAssemblyName = pMethodDesc->GetAssembly()->GetFusionAssemblyName();
- }
-
- if (Fusion::Util::IsAnyFrameworkAssembly(pIAssemblyName) != S_OK)
- {
- return FALSE;
- }
- }
-#endif // FEATURE_APPX
if (g_pConfig->LegacyCorruptedStateExceptionsPolicy())
{
@@ -12608,9 +12369,6 @@ void ReturnToPreviousAppDomainHolder::SuppressRelease()
#ifndef DACCESS_COMPILE
// This method will deliver the actual exception notification. Its assumed that the caller has done the necessary checks, including
// checking whether the delegate can be invoked for the exception's corruption severity.
-//
-// This has been factored out of the #IFDEF FEATURE_EXCEPTION_NOTIFICATIONS so that existing ADUEN mechanism can be integrated with
-// the enhanced exception notifications.
void ExceptionNotifications::DeliverExceptionNotification(ExceptionNotificationHandlerType notificationType, OBJECTREF *pDelegate,
OBJECTREF *pAppDomain, OBJECTREF *pEventArgs)
{
@@ -12636,7 +12394,6 @@ void ExceptionNotifications::DeliverExceptionNotification(ExceptionNotificationH
CALL_MANAGED_METHOD_NORET(args);
}
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
// To include definition of COMDelegate::GetMethodDesc
#include "comdelegate.h"
@@ -13047,7 +12804,6 @@ void ExceptionNotifications::DeliverFirstChanceNotification()
}
}
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
#ifdef WIN64EXCEPTIONS
struct TAResetStateCallbackData
@@ -13867,24 +13623,6 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowSO()
// Throw an InvalidCastException
//==========================================================================
-#ifdef FEATURE_FUSION
-static const WCHAR *GetContextName(LOADCTX_TYPE kLoadContext,
- BOOL fIntrospectionOnly)
-{
- LIMITED_METHOD_CONTRACT;
-
- // Context names are treated as symbols and therefore not localized
- switch (kLoadContext)
- {
- case LOADCTX_TYPE_DEFAULT:
- return W("Default");
- case LOADCTX_TYPE_LOADFROM:
- return W("LoadFrom");
- default:
- return (fIntrospectionOnly ? W("InspectionContext") : W("LoadNeither"));
- }
-}
-#endif
VOID GetAssemblyDetailInfo(SString &sType,
SString &sAssemblyDisplayName,
@@ -13894,12 +13632,7 @@ VOID GetAssemblyDetailInfo(SString &sType,
WRAPPER_NO_CONTRACT;
InlineSString<MAX_LONGPATH> sFormat;
-#ifdef FEATURE_FUSION
- const WCHAR *pwzLoadContext = GetContextName(pPEAssembly->GetLoadContext(),
- pPEAssembly->IsIntrospectionOnly());
-#else
const WCHAR *pwzLoadContext = W("Default");
-#endif
if (pPEAssembly->GetPath().IsEmpty())
{
@@ -13999,13 +13732,6 @@ VOID RealCOMPlusThrowInvalidCastException(TypeHandle thCastFrom, TypeHandle thCa
InlineSString<MAX_CLASSNAME_LENGTH + 1> strCastToName;
thCastTo.GetName(strCastToName);
-#ifdef FEATURE_REMOTING
- if (thCastFrom.IsTransparentProxy())
- {
- COMPlusThrow(kInvalidCastException, IDS_EE_CANNOTCASTPROXY, strCastToName.GetUnicode());
- }
- else
-#endif
{
thCastFrom.GetName(strCastFromName);
// Attempt to catch the A.T != A.T case that causes so much user confusion.
diff --git a/src/vm/excep.h b/src/vm/excep.h
index 53fa20160a..4c752932fd 100644
--- a/src/vm/excep.h
+++ b/src/vm/excep.h
@@ -174,7 +174,7 @@ BOOL IsCOMPlusExceptionHandlerInstalled();
BOOL InstallUnhandledExceptionFilter();
void UninstallUnhandledExceptionFilter();
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#if !defined(FEATURE_PAL)
// Section naming is a strategy by itself. Ideally, we could have named the UEF section
// ".text$zzz" (lowercase after $ is important). What the linker does is look for the sections
// that has the same name before '$' sign. It combines them together but sorted in an alphabetical
@@ -193,7 +193,7 @@ void UninstallUnhandledExceptionFilter();
// section that comes after UEF section, it can affect the UEF section and we will
// assert about it in "CExecutionEngine::ClrVirtualProtect".
#define CLR_UEF_SECTION_NAME ".CLR_UEF"
-#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_PAL)
+#endif //!defined(FEATURE_PAL)
LONG __stdcall COMUnhandledExceptionFilter(EXCEPTION_POINTERS *pExceptionInfo);
@@ -745,9 +745,16 @@ bool IsInterceptableException(Thread *pThread);
// perform simple checking to see if the current exception is intercepted
bool CheckThreadExceptionStateForInterception();
+#ifndef FEATURE_PAL
+// Currently, only Windows supports ClrUnwindEx (used inside ClrDebuggerDoUnwindAndIntercept)
+#define DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED
+#endif // !FEATURE_PAL
+
+#ifdef DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED
// Intercept the current exception and start an unwind. This function may never return.
EXCEPTION_DISPOSITION ClrDebuggerDoUnwindAndIntercept(X86_FIRST_ARG(EXCEPTION_REGISTRATION_RECORD *pEstablisherFrame)
EXCEPTION_RECORD *pExceptionRecord);
+#endif // DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED
LONG NotifyDebuggerLastChance(Thread *pThread,
EXCEPTION_POINTERS *pExceptionInfo,
@@ -888,10 +895,8 @@ LONG EntryPointFilter(PEXCEPTION_POINTERS pExceptionInfo, PVOID _pData);
enum ExceptionNotificationHandlerType
{
UnhandledExceptionHandler = 0x1
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
,
FirstChanceExceptionHandler = 0x2
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
};
// Defined in Frames.h
@@ -900,7 +905,6 @@ enum ExceptionNotificationHandlerType
// This class contains methods to support delivering the various exception notifications.
class ExceptionNotifications
{
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
private:
void static GetEventArgsForNotification(ExceptionNotificationHandlerType notificationType,
OBJECTREF *pOutEventArgs, OBJECTREF *pThrowable);
@@ -932,7 +936,6 @@ public:
#ifdef FEATURE_CORRUPTING_EXCEPTIONS
BOOL static CanDelegateBeInvokedForException(OBJECTREF *pDelegate, CorruptionSeverity severity);
#endif // FEATURE_CORRUPTING_EXCEPTIONS
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
public:
void static DeliverExceptionNotification(ExceptionNotificationHandlerType notificationType, OBJECTREF *pDelegate,
diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp
index 262d3526eb..31b85bdb0a 100644
--- a/src/vm/exceptionhandling.cpp
+++ b/src/vm/exceptionhandling.cpp
@@ -17,6 +17,48 @@
#include "eventtrace.h"
#include "virtualcallstub.h"
+#if defined(_TARGET_X86_)
+#define USE_CURRENT_CONTEXT_IN_FILTER
+#endif // _TARGET_X86_
+
+#if defined(_TARGET_ARM_) || defined(_TARGET_X86_)
+#define VSD_STUB_CAN_THROW_AV
+#endif // _TARGET_ARM_ || _TARGET_X86_
+
+#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_) || defined(_TARGET_X86_)
+#define ADJUST_PC_UNWOUND_TO_CALL
+#define STACK_RANGE_BOUNDS_ARE_CALLER_SP
+#define USE_FUNCLET_CALL_HELPER
+#define USE_CALLER_SP_IN_FUNCLET
+// For ARM/ARM64, EstablisherFrame is Caller-SP (SP just before executing call instruction).
+// This has been confirmed by AaronGi from the kernel team for Windows.
+//
+// For x86/Linux, RtlVirtualUnwind sets EstablisherFrame as Caller-SP.
+#define ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
+#endif // _TARGET_ARM_ || _TARGET_ARM64_ || _TARGET_X86_
+
+#ifdef USE_CURRENT_CONTEXT_IN_FILTER
+inline void CaptureNonvolatileRegisters(PKNONVOLATILE_CONTEXT pNonvolatileContext, PCONTEXT pContext)
+{
+#define CALLEE_SAVED_REGISTER(reg) pNonvolatileContext->reg = pContext->reg;
+ ENUM_CALLEE_SAVED_REGISTERS();
+#undef CALLEE_SAVED_REGISTER
+}
+
+inline void RestoreNonvolatileRegisters(PCONTEXT pContext, PKNONVOLATILE_CONTEXT pNonvolatileContext)
+{
+#define CALLEE_SAVED_REGISTER(reg) pContext->reg = pNonvolatileContext->reg;
+ ENUM_CALLEE_SAVED_REGISTERS();
+#undef CALLEE_SAVED_REGISTER
+}
+
+inline void RestoreNonvolatileRegisterPointers(PT_KNONVOLATILE_CONTEXT_POINTERS pContextPointers, PKNONVOLATILE_CONTEXT pNonvolatileContext)
+{
+#define CALLEE_SAVED_REGISTER(reg) pContextPointers->reg = &pNonvolatileContext->reg;
+ ENUM_CALLEE_SAVED_REGISTERS();
+#undef CALLEE_SAVED_REGISTER
+}
+#endif
#ifndef DACCESS_COMPILE
// o Functions and funclets are tightly associated. In fact, they are laid out in contiguous memory.
@@ -75,18 +117,30 @@ static void DoEHLog(DWORD lvl, __in_z const char *fmt, ...);
TrackerAllocator g_theTrackerAllocator;
-void __declspec(noinline)
-ClrUnwindEx(EXCEPTION_RECORD* pExceptionRecord,
- UINT_PTR ReturnValue,
- UINT_PTR TargetIP,
- UINT_PTR TargetFrameSp);
-
bool FixNonvolatileRegisters(UINT_PTR uOriginalSP,
Thread* pThread,
CONTEXT* pContextRecord,
bool fAborting
);
+void FixContext(PCONTEXT pContextRecord)
+{
+#define FIXUPREG(reg, value) \
+ do { \
+ STRESS_LOG2(LF_GCROOTS, LL_INFO100, "Updating " #reg " %p to %p\n", \
+ pContextRecord->reg, \
+ (value)); \
+ pContextRecord->reg = (value); \
+ } while (0)
+
+#ifdef _TARGET_X86_
+ size_t resumeSp = EECodeManager::GetResumeSp(pContextRecord);
+ FIXUPREG(ResumeEsp, resumeSp);
+#endif // _TARGET_X86_
+
+#undef FIXUPREG
+}
+
MethodDesc * GetUserMethodForILStub(Thread * pThread, UINT_PTR uStubSP, MethodDesc * pILStubMD, Frame ** ppFrameOut);
#ifdef FEATURE_PAL
@@ -405,6 +459,7 @@ void ExceptionTracker::UpdateNonvolatileRegisters(CONTEXT *pContextRecord, REGDI
} \
} while (0)
+
#if defined(_TARGET_X86_)
UPDATEREG(Ebx);
@@ -448,14 +503,7 @@ void ExceptionTracker::UpdateNonvolatileRegisters(CONTEXT *pContextRecord, REGDI
UPDATEREG(X26);
UPDATEREG(X27);
UPDATEREG(X28);
- // Obtain value of Fp from CurrentContext instead of from CurrentContextPointers
- // It should not matter. CurrentContextPointers does not have value of FP as this will
- // require changes in MachState to also store pointer of FP which it does not do currently.
- pContextRecord->Fp = pRegDisplay->pCurrentContext->Fp;
- if (pAbortContext)
- {
- pAbortContext->Fp = pContextRecord->Fp;
- }
+ UPDATEREG(Fp);
#else
PORTABILITY_ASSERT("ExceptionTracker::UpdateNonvolatileRegisters");
@@ -583,7 +631,7 @@ UINT_PTR ExceptionTracker::CallCatchHandler(CONTEXT* pContextRecord, bool* pfAbo
if (!fIntercepted)
{
_ASSERTE(m_uCatchToCallPC != 0 && m_pClauseForCatchToken != NULL);
- uResumePC = CallHandler(m_uCatchToCallPC, sfStackFp, &m_ClauseForCatch, pMD, Catch ARM_ARG(pContextRecord) ARM64_ARG(pContextRecord));
+ uResumePC = CallHandler(m_uCatchToCallPC, sfStackFp, &m_ClauseForCatch, pMD, Catch X86_ARG(pContextRecord) ARM_ARG(pContextRecord) ARM64_ARG(pContextRecord));
}
else
{
@@ -966,7 +1014,6 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord
}
#endif // FEATURE_CORRUPTING_EXCEPTIONS
-#ifdef FEATURE_CORECLR
{
// Switch to COOP mode since we are going to work
// with throwable
@@ -1009,7 +1056,6 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord
}
}
}
-#endif // FEATURE_CORECLR
#ifndef FEATURE_PAL // Watson is on Windows only
// Setup bucketing details for nested exceptions (rethrow and non-rethrow) only if we are in the first pass
@@ -1154,6 +1200,8 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord
pThread->SetFrame(pLimitFrame);
+ FixContext(pContextRecord);
+
SetIP(pContextRecord, (PCODE)uResumePC);
}
@@ -1290,9 +1338,14 @@ void ExceptionTracker::InitializeCurrentContextForCrawlFrame(CrawlFrame* pcfThis
{
REGDISPLAY *pRD = pcfThisFrame->pRD;
+#ifndef USE_CURRENT_CONTEXT_IN_FILTER
INDEBUG(memset(pRD->pCurrentContext, 0xCC, sizeof(*(pRD->pCurrentContext))));
// Ensure that clients can tell the current context isn't valid.
SetIP(pRD->pCurrentContext, 0);
+#else // !USE_CURRENT_CONTEXT_IN_FILTER
+ RestoreNonvolatileRegisters(pRD->pCurrentContext, pDispatcherContext->CurrentNonVolatileContextRecord);
+ RestoreNonvolatileRegisterPointers(pRD->pCurrentContextPointers, pDispatcherContext->CurrentNonVolatileContextRecord);
+#endif // USE_CURRENT_CONTEXT_IN_FILTER
*(pRD->pCallerContext) = *(pDispatcherContext->ContextRecord);
pRD->IsCallerContextValid = TRUE;
@@ -1300,12 +1353,12 @@ void ExceptionTracker::InitializeCurrentContextForCrawlFrame(CrawlFrame* pcfThis
pRD->SP = sfEstablisherFrame.SP;
pRD->ControlPC = pDispatcherContext->ControlPc;
-#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
+#ifdef ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
pcfThisFrame->pRD->IsCallerSPValid = TRUE;
// Assert our first pass assumptions for the Arm/Arm64
_ASSERTE(sfEstablisherFrame.SP == GetSP(pDispatcherContext->ContextRecord));
-#endif // defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
+#endif // ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
}
@@ -1399,19 +1452,23 @@ void ExceptionTracker::InitializeCrawlFrame(CrawlFrame* pcfThisFrame, Thread* pT
{
pCurrentTracker->InitializeCurrentContextForCrawlFrame(pcfThisFrame, pDispatcherContext, sf);
}
-#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
else
{
+#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
// See the comment above the call to InitRegDisplay for this assertion.
_ASSERTE(pDispatcherContext->ControlPc == GetIP(pDispatcherContext->ContextRecord));
+#endif // _TARGET_ARM_ || _TARGET_ARM64_
+#ifdef ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
// Simply setup the callerSP during the second pass in the caller context.
// This is used in setting up the "EnclosingClauseCallerSP" in ExceptionTracker::ProcessManagedCallFrame
// when the termination handlers are invoked.
::SetSP(pcfThisFrame->pRD->pCallerContext, sf.SP);
pcfThisFrame->pRD->IsCallerSPValid = TRUE;
+#endif // ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
}
+#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
// Further below, we will adjust the ControlPC based upon whether we are at a callsite or not.
// We need to do this for "RegDisplay.ControlPC" field as well so that when data structures like
// EECodeInfo initialize themselves using this field, they will have the correct absolute value
@@ -1437,7 +1494,7 @@ void ExceptionTracker::InitializeCrawlFrame(CrawlFrame* pcfThisFrame, Thread* pT
#endif
#endif // _TARGET_ARM_ || _TARGET_ARM64_
-#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_) || defined(_TARGET_X86_)
+#ifdef ADJUST_PC_UNWOUND_TO_CALL
// If the OS indicated that the IP is a callsite, then adjust the ControlPC by decrementing it
// by two. This is done because unwinding at callsite will make ControlPC point to the
// instruction post the callsite. If a protected region ends "at" the callsite, then
@@ -1460,7 +1517,7 @@ void ExceptionTracker::InitializeCrawlFrame(CrawlFrame* pcfThisFrame, Thread* pT
pcfThisFrame->isIPadjusted = true;
}
}
-#endif // _TARGET_ARM_ || _TARGET_ARM64_ || _TARGET_X86_
+#endif // ADJUST_PC_UNWOUND_TO_CALL
pcfThisFrame->codeInfo.Init(ControlPCForEHSearch);
@@ -1617,17 +1674,11 @@ CLRUnwindStatus ExceptionTracker::ProcessOSExceptionNotification(
ExceptionTracker::InitializeCrawlFrame(&cfThisFrame, pThread, sf, &regdisp, pDispatcherContext, ControlPc, &uMethodStartPC, this);
-#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
+#ifndef ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
uCallerSP = EECodeManager::GetCallerSp(cfThisFrame.pRD);
-#elif defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
- // On ARM & ARM64, the EstablisherFrame is the value of SP at the time a function was called and before it's prolog
- // executed. Effectively, it is the SP of the caller. This has been confirmed by AaronGi from the kernel
- // team.
+#else // !ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
uCallerSP = sf.SP;
-#else
- PORTABILITY_ASSERT("ExceptionTracker::ProcessOSExceptionNotification");
- uCallerSP = NULL;
-#endif // _TARGET_AMD64_
+#endif // ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
EH_LOG((LL_INFO100, "ProcessCrawlFrame: PSP: " FMT_ADDR " EstablisherFrame: " FMT_ADDR "\n", DBG_ADDR(uCallerSP), DBG_ADDR(sf.SP)));
@@ -1928,19 +1979,16 @@ lExit:
// in ExceptionTracker::ProcessManagedCallFrame.
if (m_fResetEnclosingClauseSPForCatchFunclet)
{
-#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
+#ifdef ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
// DispatcherContext->EstablisherFrame's value
// represents the CallerSP of the current frame.
UINT_PTR EnclosingClauseCallerSP = (UINT_PTR)pDispatcherContext->EstablisherFrame;
-#elif defined(_TARGET_AMD64_)
- // Extract the CallerSP from RegDisplay on AMD64
+#else // ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
+ // Extract the CallerSP from RegDisplay
REGDISPLAY *pRD = cfThisFrame.GetRegisterSet();
_ASSERTE(pRD->IsCallerContextValid || pRD->IsCallerSPValid);
UINT_PTR EnclosingClauseCallerSP = (UINT_PTR)GetSP(pRD->pCallerContext);
-#else // !_ARM_ && !_AMD64_ && !_ARM64_
- PORTABILITY_ASSERT("ExceptionTracker::ProcessOSExceptionNotification");
- UINT_PTR EnclosingClauseCallerSP = NULL;
-#endif // defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
+#endif // !ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
m_EnclosingClauseInfo = EnclosingClauseInfo(false, cfThisFrame.GetRelOffset(), EnclosingClauseCallerSP);
}
m_fResetEnclosingClauseSPForCatchFunclet = FALSE;
@@ -2213,13 +2261,11 @@ CLRUnwindStatus ExceptionTracker::ProcessExplicitFrame(
#if defined(DEBUGGING_SUPPORTED)
if (ExceptionTracker::NotifyDebuggerOfStub(pThread, sf, pFrame))
{
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
// Deliver the FirstChanceNotification after the debugger, if not already delivered.
if (!this->DeliveredFirstChanceNotification())
{
ExceptionNotifications::DeliverFirstChanceNotification();
}
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
}
#endif // DEBUGGING_SUPPORTED
@@ -2243,7 +2289,6 @@ CLRUnwindStatus ExceptionTracker::HandleFunclets(bool* pfProcessThisFrame, bool
}
CONTRACTL_END;
-#ifdef WIN64EXCEPTIONS // funclets
BOOL fUnwindingToFindResumeFrame = m_ExceptionFlags.UnwindingToFindResumeFrame();
//
@@ -2316,7 +2361,6 @@ CLRUnwindStatus ExceptionTracker::HandleFunclets(bool* pfProcessThisFrame, bool
}
}
}
-#endif // WIN64EXCEPTIONS
return UnwindPending;
}
@@ -2356,14 +2400,9 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame(
EH_LOG((LL_INFO100, " [ ProcessManagedCallFrame this=%p, %s PASS ]\n", this, (fIsFirstPass ? "FIRST" : "SECOND")));
-#ifdef WIN64EXCEPTIONS // funclets
EH_LOG((LL_INFO100, " [ method: %s%s, %s ]\n",
(fIsFunclet ? "FUNCLET of " : ""),
pMD->m_pszDebugMethodName, pMD->m_pszDebugClassName));
-#else // !WIN64EXCEPTIONS
- EH_LOG((LL_INFO100, " [ method: %s, %s ]\n",
- pMD->m_pszDebugMethodName, pMD->m_pszDebugClassName));
-#endif // WIN64EXCEPTIONS
Thread *pThread = GetThread();
_ASSERTE (pThread);
@@ -2553,14 +2592,12 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame(
}
#endif // DEBUGGING_SUPPORTED
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
// Attempt to deliver the first chance notification to the AD only *AFTER* the debugger
// has done that, provided we have not already delivered it.
if (!this->DeliveredFirstChanceNotification())
{
ExceptionNotifications::DeliverFirstChanceNotification();
}
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
}
else
{
@@ -2686,7 +2723,7 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame(
EE_ILEXCEPTION_CLAUSE EHClause;
PTR_EXCEPTION_CLAUSE_TOKEN pEHClauseToken = pJitMan->GetNextEHClause(&EnumState, &EHClause);
- EH_LOG((LL_INFO100, " considering %s clause [%x,%x], ControlPc is %s clause (offset %x)",
+ EH_LOG((LL_INFO100, " considering %s clause [%x,%x), ControlPc is %s clause (offset %x)",
(IsFault(&EHClause) ? "fault" :
(IsFinally(&EHClause) ? "finally" :
(IsFilterHandler(&EHClause) ? "filter" :
@@ -2846,13 +2883,13 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame(
// executes.
m_dwIndexClauseForCatch = i + 1;
m_sfEstablisherOfActualHandlerFrame = sfEstablisherFrame;
-#ifdef _TARGET_AMD64_
+#ifndef ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
m_sfCallerOfActualHandlerFrame = EECodeManager::GetCallerSp(pcfThisFrame->pRD);
-#else
+#else // !ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
// On ARM & ARM64, the EstablisherFrame is the value of SP at the time a function was called and before it's prolog
// executed. Effectively, it is the SP of the caller.
m_sfCallerOfActualHandlerFrame = sfEstablisherFrame.SP;
-#endif
+#endif // ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
ReturnStatus = FirstPassComplete;
}
@@ -2894,7 +2931,7 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame(
SetEnclosingClauseInfo(fIsFunclet,
pcfThisFrame->GetRelOffset(),
GetSP(pcfThisFrame->GetRegisterSet()->pCallerContext));
-#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
+#ifdef USE_FUNCLET_CALL_HELPER
// On ARM & ARM64, the OS passes us the CallerSP for the frame for which personality routine has been invoked.
// Since IL filters are invoked in the first pass, we pass this CallerSP to the filter funclet which will
// then lookup the actual frame pointer value using it since we dont have a frame pointer to pass to it
@@ -2903,17 +2940,25 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame(
// Assert our invariants (we had set them up in InitializeCrawlFrame):
REGDISPLAY *pCurRegDisplay = pcfThisFrame->GetRegisterSet();
+ CONTEXT *pContext = NULL;
+#ifndef USE_CURRENT_CONTEXT_IN_FILTER
// 1) In first pass, we dont have a valid current context IP
- _ASSERTE(GetIP(pCurRegDisplay->pCurrentContext) == 0);
+ _ASSERTE(GetIP(pCurRegDisplay->pCurrentContext) == 0);
+ pContext = pCurRegDisplay->pCallerContext;
+#else
+ pContext = pCurRegDisplay->pCurrentContext;
+#endif // !USE_CURRENT_CONTEXT_IN_FILTER
+#ifdef USE_CALLER_SP_IN_FUNCLET
// 2) Our caller context and caller SP are valid
_ASSERTE(pCurRegDisplay->IsCallerContextValid && pCurRegDisplay->IsCallerSPValid);
// 3) CallerSP is intact
_ASSERTE(GetSP(pCurRegDisplay->pCallerContext) == GetRegdisplaySP(pCurRegDisplay));
-#endif // _TARGET_ARM_ || _TARGET_ARM64_
+#endif // USE_CALLER_SP_IN_FUNCLET
+#endif // USE_FUNCLET_CALL_HELPER
{
// CallHandler expects to be in COOP mode.
GCX_COOP();
- dwResult = CallHandler(dwFilterStartPC, sf, &EHClause, pMD, Filter ARM_ARG(pCurRegDisplay->pCallerContext) ARM64_ARG(pCurRegDisplay->pCallerContext));
+ dwResult = CallHandler(dwFilterStartPC, sf, &EHClause, pMD, Filter X86_ARG(pContext) ARM_ARG(pContext) ARM64_ARG(pContext));
}
}
EX_CATCH
@@ -3112,13 +3157,11 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame(
m_dwIndexClauseForCatch = i + 1;
m_sfEstablisherOfActualHandlerFrame = sfEstablisherFrame;
-#ifdef _TARGET_AMD64_
+#ifndef ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
m_sfCallerOfActualHandlerFrame = EECodeManager::GetCallerSp(pcfThisFrame->pRD);
-#else
- // On ARM & ARM64, the EstablisherFrame is the value of SP at the time a function was called and before it's prolog
- // executed. Effectively, it is the SP of the caller.
+#else // !ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
m_sfCallerOfActualHandlerFrame = sfEstablisherFrame.SP;
-#endif
+#endif // ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
//
// END resume frame code
//
@@ -3146,7 +3189,7 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame(
// Since we also forbid GC during second pass, disable it now since
// invocation of managed code can result in a GC.
ENDFORBIDGC();
- dwStatus = CallHandler(dwHandlerStartPC, sf, &EHClause, pMD, FaultFinally ARM_ARG(pcfThisFrame->GetRegisterSet()->pCurrentContext) ARM64_ARG(pcfThisFrame->GetRegisterSet()->pCurrentContext));
+ dwStatus = CallHandler(dwHandlerStartPC, sf, &EHClause, pMD, FaultFinally X86_ARG(pcfThisFrame->GetRegisterSet()->pCurrentContext) ARM_ARG(pcfThisFrame->GetRegisterSet()->pCurrentContext) ARM64_ARG(pcfThisFrame->GetRegisterSet()->pCurrentContext));
// Once we return from a funclet, forbid GC again (refer to comment before start of the loop for details)
BEGINFORBIDGC();
@@ -3214,20 +3257,57 @@ lExit:
#define OPTIONAL_SO_CLEANUP_UNWIND(pThread, pFrame) if (pThread->GetFrame() < pFrame) { UnwindFrameChain(pThread, pFrame); }
-#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
+#ifdef USE_FUNCLET_CALL_HELPER
// This is an assembly helper that enables us to call into EH funclets.
EXTERN_C DWORD_PTR STDCALL CallEHFunclet(Object *pThrowable, UINT_PTR pFuncletToInvoke, UINT_PTR *pFirstNonVolReg, UINT_PTR *pFuncletCallerSP);
// This is an assembly helper that enables us to call into EH filter funclets.
EXTERN_C DWORD_PTR STDCALL CallEHFilterFunclet(Object *pThrowable, TADDR CallerSP, UINT_PTR pFuncletToInvoke, UINT_PTR *pFuncletCallerSP);
-#endif // _TARGET_ARM_ || _TARGET_ARM64_
+static inline UINT_PTR CastHandlerFn(HandlerFn *pfnHandler)
+{
+#ifdef _TARGET_ARM_
+ return DataPointerToThumbCode<UINT_PTR, HandlerFn *>(pfnHandler);
+#else
+ return (UINT_PTR)pfnHandler;
+#endif
+}
+
+static inline UINT_PTR *GetFirstNonVolatileRegisterAddress(PCONTEXT pContextRecord)
+{
+#if defined(_TARGET_ARM_)
+ return (UINT_PTR*)&(pContextRecord->R4);
+#elif defined(_TARGET_ARM64_)
+ return (UINT_PTR*)&(pContextRecord->X19);
+#elif defined(_TARGET_X86_)
+ return (UINT_PTR*)&(pContextRecord->Edi);
+#else
+ PORTABILITY_ASSERT("GetFirstNonVolatileRegisterAddress");
+ return NULL;
+#endif
+}
+
+static inline TADDR GetFrameRestoreBase(PCONTEXT pContextRecord)
+{
+#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
+ return GetSP(pContextRecord);
+#elif defined(_TARGET_X86_)
+ return pContextRecord->Ebp;
+#else
+ PORTABILITY_ASSERT("GetFrameRestoreBase");
+ return NULL;
+#endif
+}
+
+#endif // USE_FUNCLET_CALL_HELPER
+
DWORD_PTR ExceptionTracker::CallHandler(
UINT_PTR uHandlerStartPC,
StackFrame sf,
EE_ILEXCEPTION_CLAUSE* pEHClause,
MethodDesc* pMD,
EHFuncletType funcletType
+ X86_ARG(PCONTEXT pContextRecord)
ARM_ARG(PCONTEXT pContextRecord)
ARM64_ARG(PCONTEXT pContextRecord)
)
@@ -3282,7 +3362,7 @@ DWORD_PTR ExceptionTracker::CallHandler(
break;
}
-#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
+#ifdef USE_FUNCLET_CALL_HELPER
// Invoke the funclet. We pass throwable only when invoking the catch block.
// Since the actual caller of the funclet is the assembly helper, pass the reference
// to the CallerStackFrame instance so that it can be updated.
@@ -3291,14 +3371,9 @@ DWORD_PTR ExceptionTracker::CallHandler(
if (funcletType != EHFuncletType::Filter)
{
dwResumePC = CallEHFunclet((funcletType == EHFuncletType::Catch)?OBJECTREFToObject(throwable):(Object *)NULL,
-#ifdef _TARGET_ARM_
- DataPointerToThumbCode<UINT_PTR, HandlerFn *>(pfnHandler),
- (UINT_PTR*)&(pContextRecord->R4),
-#else
- (UINT_PTR)pfnHandler,
- &(pContextRecord->X19),
-#endif // _TARGET_ARM_
- pFuncletCallerSP);
+ CastHandlerFn(pfnHandler),
+ GetFirstNonVolatileRegisterAddress(pContextRecord),
+ pFuncletCallerSP);
}
else
{
@@ -3306,20 +3381,16 @@ DWORD_PTR ExceptionTracker::CallHandler(
// it will retrieve the framepointer for accessing the locals in the parent
// method.
dwResumePC = CallEHFilterFunclet(OBJECTREFToObject(throwable),
- GetSP(pContextRecord),
-#ifdef _TARGET_ARM_
- DataPointerToThumbCode<UINT_PTR, HandlerFn *>(pfnHandler),
-#else
- (UINT_PTR)pfnHandler,
-#endif // _TARGET_ARM_
- pFuncletCallerSP);
+ GetFrameRestoreBase(pContextRecord),
+ CastHandlerFn(pfnHandler),
+ pFuncletCallerSP);
}
-#else // defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
+#else // USE_FUNCLET_CALL_HELPER
//
// Invoke the funclet.
//
dwResumePC = pfnHandler(sf.SP, OBJECTREFToObject(throwable));
-#endif // _TARGET_ARM_
+#endif // !USE_FUNCLET_CALL_HELPER
switch(funcletType)
{
@@ -4128,6 +4199,7 @@ void ExceptionTracker::MakeCallbacksRelatedToHandler(
}
}
+#ifdef DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED
//---------------------------------------------------------------------------------------
//
// This function is called by DefaultCatchHandler() to intercept an exception and start an unwind.
@@ -4164,6 +4236,7 @@ EXCEPTION_DISPOSITION ClrDebuggerDoUnwindAndIntercept(X86_FIRST_ARG(EXCEPTION_RE
UNREACHABLE();
}
+#endif // DEBUGGER_EXCEPTION_INTERCEPTION_SUPPORTED
#endif // DEBUGGING_SUPPORTED
#ifdef _DEBUG
@@ -4337,7 +4410,7 @@ VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartConte
dispatcherContext.FunctionEntry = codeInfo.GetFunctionEntry();
dispatcherContext.ControlPc = controlPc;
dispatcherContext.ImageBase = codeInfo.GetModuleBase();
-#if defined(_TARGET_ARM_) || defined(_TARGET_X86_)
+#ifdef ADJUST_PC_UNWOUND_TO_CALL
dispatcherContext.ControlPcIsUnwound = !!(currentFrameContext->ContextFlags & CONTEXT_UNWOUND_TO_CALL);
#endif
// Check whether we have a function table entry for the current controlPC.
@@ -4488,7 +4561,7 @@ VOID DECLSPEC_NORETURN UnwindManagedExceptionPass1(PAL_SEHException& ex, CONTEXT
dispatcherContext.FunctionEntry = codeInfo.GetFunctionEntry();
dispatcherContext.ControlPc = controlPc;
dispatcherContext.ImageBase = codeInfo.GetModuleBase();
-#if defined(_TARGET_ARM_) || defined(_TARGET_X86_)
+#ifdef ADJUST_PC_UNWOUND_TO_CALL
dispatcherContext.ControlPcIsUnwound = !!(frameContext->ContextFlags & CONTEXT_UNWOUND_TO_CALL);
#endif
@@ -4497,6 +4570,11 @@ VOID DECLSPEC_NORETURN UnwindManagedExceptionPass1(PAL_SEHException& ex, CONTEXT
// and then check whether an exception handler exists for the frame.
if (dispatcherContext.FunctionEntry != NULL)
{
+#ifdef USE_CURRENT_CONTEXT_IN_FILTER
+ KNONVOLATILE_CONTEXT currentNonVolatileContext;
+ CaptureNonvolatileRegisters(&currentNonVolatileContext, frameContext);
+#endif // USE_CURRENT_CONTEXT_IN_FILTER
+
RtlVirtualUnwind(UNW_FLAG_EHANDLER,
dispatcherContext.ImageBase,
dispatcherContext.ControlPc,
@@ -4515,6 +4593,9 @@ VOID DECLSPEC_NORETURN UnwindManagedExceptionPass1(PAL_SEHException& ex, CONTEXT
}
dispatcherContext.EstablisherFrame = establisherFrame;
+#ifdef USE_CURRENT_CONTEXT_IN_FILTER
+ dispatcherContext.CurrentNonVolatileContextRecord = &currentNonVolatileContext;
+#endif // USE_CURRENT_CONTEXT_IN_FILTER
dispatcherContext.ContextRecord = frameContext;
// Find exception handler in the current frame
@@ -4704,29 +4785,7 @@ Return value :
--*/
VOID* GetRegisterAddressByIndex(PCONTEXT pContext, UINT index)
{
-#if defined(_TARGET_AMD64_)
- _ASSERTE(index < 16);
- return &((&pContext->Rax)[index]);
-#elif defined(_TARGET_X86_)
- _ASSERTE(index < 8);
-
- static const SIZE_T OFFSET_OF_REGISTERS[] =
- {
- offsetof(CONTEXT, Eax),
- offsetof(CONTEXT, Ecx),
- offsetof(CONTEXT, Edx),
- offsetof(CONTEXT, Ebx),
- offsetof(CONTEXT, Esp),
- offsetof(CONTEXT, Ebp),
- offsetof(CONTEXT, Esi),
- offsetof(CONTEXT, Edi),
- };
-
- return (VOID*)(PBYTE(pContext) + OFFSET_OF_REGISTERS[index]);
-#else
- PORTABILITY_ASSERT("GetRegisterAddressByIndex");
- return NULL;
-#endif
+ return getRegAddr(index, pContext);
}
/*++
@@ -4858,10 +4917,15 @@ DWORD64 GetModRMOperandValue(BYTE rex, BYTE* ip, PCONTEXT pContext, bool is8Bit,
// Get the value we need from the register.
//
- // Check for RIP-relative addressing mode.
+ // Check for RIP-relative addressing mode for AMD64
+ // Check for Displacement only addressing mode for x86
if ((mod == 0) && (rm == 5))
{
+#if defined(_TARGET_AMD64_)
result = (DWORD64)ip + sizeof(INT32) + *(INT32*)ip;
+#else
+ result = (DWORD64)(*(DWORD*)ip);
+#endif // _TARGET_AMD64_
}
else
{
@@ -5048,6 +5112,39 @@ BOOL IsSafeToCallExecutionManager()
GCStress<cfg_instr_ngen>::IsEnabled();
}
+#ifdef VSD_STUB_CAN_THROW_AV
+//Return TRUE if pContext->Pc is in VirtualStub
+static BOOL IsIPinVirtualStub(PCODE f_IP)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ Thread * pThread = GetThread();
+
+ // We may not have a managed thread object. Example is an AV on the helper thread.
+ // (perhaps during StubManager::IsStub)
+ if (pThread == NULL)
+ {
+ return FALSE;
+ }
+
+ VirtualCallStubManager::StubKind sk;
+ VirtualCallStubManager::FindStubManager(f_IP, &sk);
+
+ if (sk == VirtualCallStubManager::SK_DISPATCH)
+ {
+ return TRUE;
+ }
+ else if (sk == VirtualCallStubManager::SK_RESOLVE)
+ {
+ return TRUE;
+ }
+
+ else {
+ return FALSE;
+ }
+}
+#endif // VSD_STUB_CAN_THROW_AV
+
BOOL IsSafeToHandleHardwareException(PCONTEXT contextRecord, PEXCEPTION_RECORD exceptionRecord)
{
PCODE controlPc = GetIP(contextRecord);
@@ -5055,9 +5152,9 @@ BOOL IsSafeToHandleHardwareException(PCONTEXT contextRecord, PEXCEPTION_RECORD e
exceptionRecord->ExceptionCode == STATUS_BREAKPOINT ||
exceptionRecord->ExceptionCode == STATUS_SINGLE_STEP ||
(IsSafeToCallExecutionManager() && ExecutionManager::IsManagedCode(controlPc)) ||
-#ifdef _TARGET_ARM_
+#ifdef VSD_STUB_CAN_THROW_AV
IsIPinVirtualStub(controlPc) || // access violation comes from DispatchStub of Interface call
-#endif
+#endif // VSD_STUB_CAN_THROW_AV
IsIPInMarkedJitHelper(controlPc));
}
@@ -5094,9 +5191,7 @@ BOOL HandleHardwareException(PAL_SEHException* ex)
// Create frame necessary for the exception handling
FrameWithCookie<FaultingExceptionFrame> fef;
-#if defined(WIN64EXCEPTIONS)
*((&fef)->GetGSCookiePtr()) = GetProcessGSCookie();
-#endif // WIN64EXCEPTIONS
{
GCX_COOP(); // Must be cooperative to modify frame chain.
if (IsIPInMarkedJitHelper(controlPc))
@@ -5108,12 +5203,12 @@ BOOL HandleHardwareException(PAL_SEHException* ex)
PAL_VirtualUnwind(ex->GetContextRecord(), NULL);
ex->GetExceptionRecord()->ExceptionAddress = (PVOID)GetIP(ex->GetContextRecord());
}
-#ifdef _TARGET_ARM_
+#ifdef VSD_STUB_CAN_THROW_AV
else if (IsIPinVirtualStub(controlPc))
{
AdjustContextForVirtualStub(ex->GetExceptionRecord(), ex->GetContextRecord());
}
-#endif
+#endif // VSD_STUB_CAN_THROW_AV
fef.InitAndLink(ex->GetContextRecord());
}
@@ -5151,9 +5246,9 @@ BOOL HandleHardwareException(PAL_SEHException* ex)
#endif // FEATURE_PAL
+#ifndef FEATURE_PAL
void ClrUnwindEx(EXCEPTION_RECORD* pExceptionRecord, UINT_PTR ReturnValue, UINT_PTR TargetIP, UINT_PTR TargetFrameSp)
{
-#ifndef FEATURE_PAL
PVOID TargetFrame = (PVOID)TargetFrameSp;
CONTEXT ctx;
@@ -5164,13 +5259,10 @@ void ClrUnwindEx(EXCEPTION_RECORD* pExceptionRecord, UINT_PTR ReturnValue, UINT_
&ctx,
NULL); // HistoryTable
-#else // !FEATURE_PAL
- PORTABILITY_ASSERT("UNIXTODO: Implement unwinding for PAL");
-#endif // !FEATURE_PAL
-
// doesn't return
UNREACHABLE();
}
+#endif // !FEATURE_PAL
void TrackerAllocator::Init()
{
@@ -5302,6 +5394,7 @@ void TrackerAllocator::FreeTrackerMemory(ExceptionTracker* pTracker)
FastInterlockExchangePointer(&(pTracker->m_pThread), NULL);
}
+#ifndef FEATURE_PAL
// This is Windows specific implementation as it is based upon the notion of collided unwind that is specific
// to Windows 64bit.
//
@@ -5326,7 +5419,6 @@ void TrackerAllocator::FreeTrackerMemory(ExceptionTracker* pTracker)
// nt\base\ntos\rtl\{ia64|amd64}\exdsptch.c for RtlUnwindEx().
void FixupDispatcherContext(DISPATCHER_CONTEXT* pDispatcherContext, CONTEXT* pContext, LPVOID originalControlPC, PEXCEPTION_ROUTINE pUnwindPersonalityRoutine)
{
-#ifndef FEATURE_PAL
if (pContext)
{
STRESS_LOG1(LF_EH, LL_INFO10, "FDC: pContext: %p\n", pContext);
@@ -5447,9 +5539,6 @@ void FixupDispatcherContext(DISPATCHER_CONTEXT* pDispatcherContext, CONTEXT* pCo
}
_ASSERTE(pDispatcherContext->LanguageHandler != NULL);
-#else // !FEATURE_PAL
- PORTABILITY_ASSERT("UNIXTODO: Implement the fixup for PAL");
-#endif // !FEATURE_PAL
}
@@ -5595,6 +5684,7 @@ FixContextHandler(IN PEXCEPTION_RECORD pExceptionRecord
// (which was broken when we whacked the IP to get control over the thread)
return ExceptionCollidedUnwind;
}
+#endif // !FEATURE_PAL
#ifdef _DEBUG
// IsSafeToUnwindFrameChain:
@@ -5806,30 +5896,6 @@ NOT_WIN64_ARG(IN ULONG MemoryStackFp),
}
#endif // _DEBUG
- // We need to ReverseLeaveRuntime if we are unwinding (since there is no
- // frame to do this for us...
- if (IS_UNWINDING(pExceptionRecord->ExceptionFlags))
- {
- BYTE bFlag;
-
-#ifdef _TARGET_AMD64_
- bFlag = *(BYTE*)(pDispatcherContext->ContextRecord->Rbp + UMTHUNKSTUB_HOST_NOTIFY_FLAG_RBPOFFSET);
-#elif defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
- // On ARM, we do not need to do anything here. If required, ReverseEnterRuntime should happen
- // in the VM in UMThunkStubWorker via a holder so that during an exceptional case, we will
- // automatically perform the ReverseLeaveRuntime.
- bFlag = 0;
-#else
- bFlag = 0;
- PORTABILITY_ASSERT("NYI -- UMThunkStubUnwindFrameChainHandler notify host of ReverseLeaveRuntime");
-#endif // _TARGET_AMD64_
-
- if (0 != bFlag)
- {
- GetThread()->ReverseLeaveRuntime();
- }
- }
-
EXCEPTION_DISPOSITION disposition = UMThunkUnwindFrameChainHandler(
pExceptionRecord,
MemoryStackFp,
@@ -5915,6 +5981,7 @@ ReverseComUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionRecord
}
#endif // FEATURE_COMINTEROP
+#ifndef FEATURE_PAL
EXTERN_C EXCEPTION_DISPOSITION
FixRedirectContextHandler(
IN PEXCEPTION_RECORD pExceptionRecord
@@ -5951,7 +6018,7 @@ FixRedirectContextHandler(
// (which was broken when we whacked the IP to get control over the thread)
return ExceptionCollidedUnwind;
}
-
+#endif // !FEATURE_PAL
#endif // DACCESS_COMPILE
void ExceptionTracker::StackRange::Reset()
@@ -6198,11 +6265,11 @@ bool ExceptionTracker::IsInStackRegionUnwoundBySpecifiedException(CrawlFrame * p
// Remember that sfLowerBound and sfUpperBound are in the "OS format".
// Refer to the comment for CallerStackFrame for more information.
-#if defined(_TARGET_AMD64_)
+#ifndef STACK_RANGE_BOUNDS_ARE_CALLER_SP
if ((sfLowerBound < csfToCheck) && (csfToCheck <= sfUpperBound))
-#else // _TARGET_ARM_ || _TARGET_ARM64_
+#else // !STACK_RANGE_BOUNDS_ARE_CALLER_SP
if ((sfLowerBound <= csfToCheck) && (csfToCheck < sfUpperBound))
-#endif // _TARGET_AMD64_
+#endif // STACK_RANGE_BOUNDS_ARE_CALLER_SP
{
return true;
}
@@ -6290,13 +6357,11 @@ bool ExceptionTracker::HasFrameBeenUnwoundByAnyActiveException(CrawlFrame * pCF)
// Refer to the detailed comment in ExceptionTracker::IsInStackRegionUnwoundBySpecifiedException on the nature
// of this check.
//
-#if defined(_TARGET_AMD64_)
+#ifndef STACK_RANGE_BOUNDS_ARE_CALLER_SP
if ((sfLowerBound < csfToCheck) && (csfToCheck <= sfUpperBound))
-#elif defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
+#else // !STACK_RANGE_BOUNDS_ARE_CALLER_SP
if ((sfLowerBound <= csfToCheck) && (csfToCheck < sfUpperBound))
-#else
- PORTABILITY_ASSERT("ExceptionTracker::HasFrameBeenUnwoundByAnyActiveException");
-#endif // _TARGET_AMD64_
+#endif // STACK_RANGE_BOUNDS_ARE_CALLER_SP
{
fHasFrameBeenUnwound = true;
break;
@@ -6319,7 +6384,7 @@ bool ExceptionTracker::HasFrameBeenUnwoundByAnyActiveException(CrawlFrame * pCF)
// This is applicable to managed frames only.
if (fFrameless)
{
-#if defined(_TARGET_AMD64_)
+#ifndef STACK_RANGE_BOUNDS_ARE_CALLER_SP
// On X64, if the SP of the managed frame indicates that the frame is forming the upper bound,
// then:
//
@@ -6344,7 +6409,7 @@ bool ExceptionTracker::HasFrameBeenUnwoundByAnyActiveException(CrawlFrame * pCF)
break;
}
}
-#else // _TARGET_ARM_ || _TARGET_ARM64_
+#else // !STACK_RANGE_BOUNDS_ARE_CALLER_SP
// On ARM, if the callerSP of the managed frame is the same as upper bound, then:
//
// For case (1), sfCurrentEstablisherFrame will be above the callerSP of the managed frame (since EstbalisherFrame is the caller SP for a given frame on ARM)
@@ -6364,7 +6429,7 @@ bool ExceptionTracker::HasFrameBeenUnwoundByAnyActiveException(CrawlFrame * pCF)
break;
}
}
-#endif // _TARGET_AMD64_
+#endif // STACK_RANGE_BOUNDS_ARE_CALLER_SP
}
// The frame in question does not appear in the current tracker's scanned stack range (of managed frames).
@@ -7049,10 +7114,8 @@ void ExceptionTracker::ResetThreadAbortStatus(PTR_Thread pThread, CrawlFrame *pC
GC_NOTRIGGER;
MODE_ANY;
PRECONDITION(pThread != NULL);
-#ifdef WIN64EXCEPTIONS
PRECONDITION(pCf != NULL);
PRECONDITION(!sfCurrentStackFrame.IsNull());
-#endif // WIN64EXCEPTIONS
}
CONTRACTL_END;
@@ -7063,5 +7126,5 @@ void ExceptionTracker::ResetThreadAbortStatus(PTR_Thread pThread, CrawlFrame *pC
}
#endif //!DACCESS_COMPILE
-#endif // _WIN64
+#endif // WIN64EXCEPTIONS
diff --git a/src/vm/exceptionhandling.h b/src/vm/exceptionhandling.h
index 8b675d596d..97f1526621 100644
--- a/src/vm/exceptionhandling.h
+++ b/src/vm/exceptionhandling.h
@@ -26,11 +26,13 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord
IN OUT PT_DISPATCHER_CONTEXT pDispatcherContext);
+#ifndef FEATURE_PAL
void __declspec(noinline)
ClrUnwindEx(EXCEPTION_RECORD* pExceptionRecord,
UINT_PTR ReturnValue,
UINT_PTR TargetIP,
UINT_PTR TargetFrameSp);
+#endif // !FEATURE_PAL
typedef DWORD_PTR (HandlerFn)(UINT_PTR uStackFrame, Object* pExceptionObj);
@@ -85,11 +87,9 @@ public:
m_CorruptionSeverity = NotSet;
#endif // FEATURE_CORRUPTING_EXCEPTIONS
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
// By default, mark the tracker as not having delivered the first
// chance exception notification
m_fDeliveredFirstChanceNotification = FALSE;
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
m_sfFirstPassTopmostFrame.Clear();
@@ -147,11 +147,9 @@ public:
m_CorruptionSeverity = NotSet;
#endif // FEATURE_CORRUPTING_EXCEPTIONS
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
// By default, mark the tracker as not having delivered the first
// chance exception notification
m_fDeliveredFirstChanceNotification = FALSE;
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
m_dwIndexClauseForCatch = 0;
m_sfEstablisherOfActualHandlerFrame.Clear();
@@ -389,7 +387,7 @@ public:
bool IsStackOverflowException();
-#ifdef FEATURE_PAL
+#if defined(FEATURE_PAL) && !defined(CROSS_COMPILE)
void TakeExceptionPointersOwnership(PAL_SEHException* ex)
{
_ASSERTE(ex->GetExceptionRecord() == m_ptrs.ExceptionRecord);
@@ -397,7 +395,7 @@ public:
ex->Clear();
m_fOwnsExceptionPointers = TRUE;
}
-#endif // FEATURE_PAL
+#endif // FEATURE_PAL && !CROSS_COMPILE
private:
DWORD_PTR
@@ -406,6 +404,7 @@ private:
EE_ILEXCEPTION_CLAUSE* pEHClause,
MethodDesc* pMD,
EHFuncletType funcletType
+ X86_ARG(PT_CONTEXT pContextRecord)
ARM_ARG(PT_CONTEXT pContextRecord)
ARM64_ARG(PT_CONTEXT pContextRecord)
);
@@ -428,7 +427,7 @@ private:
m_hThrowable = NULL;
}
-#endif
+#endif // !DACCESS_COMPILE
void SaveStackTrace();
@@ -616,7 +615,6 @@ public:
}
#endif // FEATURE_CORRUPTING_EXCEPTIONS
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
private:
BOOL m_fDeliveredFirstChanceNotification;
@@ -634,7 +632,6 @@ public:
m_fDeliveredFirstChanceNotification = fDelivered;
}
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
// Returns the exception tracker previous to the current
inline PTR_ExceptionTracker GetPreviousExceptionTracker()
@@ -656,6 +653,11 @@ public:
{
return !m_ExceptionFlags.UnwindHasStarted();
}
+
+ EHClauseInfo* GetEHClauseInfo()
+ {
+ return &m_EHClauseInfo;
+ }
private: ;
@@ -775,9 +777,7 @@ private: ;
EnclosingClauseInfo m_EnclosingClauseInfoOfCollapsedTracker;
};
-#if defined(WIN64EXCEPTIONS)
PTR_ExceptionTracker GetEHTrackerForPreallocatedException(OBJECTREF oPreAllocThrowable, PTR_ExceptionTracker pStartingEHTracker);
-#endif // WIN64EXCEPTIONS
class TrackerAllocator
{
diff --git a/src/vm/exinfo.cpp b/src/vm/exinfo.cpp
index 1ae011e85a..1a73e25a6e 100644
--- a/src/vm/exinfo.cpp
+++ b/src/vm/exinfo.cpp
@@ -118,11 +118,9 @@ void ExInfo::Init()
m_CorruptionSeverity = NotSet;
#endif // FEATURE_CORRUPTING_EXCEPTIONS
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
// By default, mark the tracker as not having delivered the first
// chance exception notification
m_fDeliveredFirstChanceNotification = FALSE;
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
m_pTopMostHandlerDuringSO = NULL;
diff --git a/src/vm/exinfo.h b/src/vm/exinfo.h
index 2a8030fb56..4a6c3e5dcc 100644
--- a/src/vm/exinfo.h
+++ b/src/vm/exinfo.h
@@ -109,7 +109,6 @@ public:
}
#endif // FEATURE_CORRUPTING_EXCEPTIONS
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
private:
BOOL m_fDeliveredFirstChanceNotification;
public:
@@ -126,7 +125,6 @@ public:
m_fDeliveredFirstChanceNotification = fDelivered;
}
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
// Returns the exception tracker previous to the current
inline PTR_ExInfo GetPreviousExceptionTracker()
@@ -136,7 +134,7 @@ public:
return m_pPrevNestedInfo;
}
- // Returns the throwble associated with the tracker
+ // Returns the throwable associated with the tracker
inline OBJECTREF GetThrowable()
{
LIMITED_METHOD_CONTRACT;
diff --git a/src/vm/exstate.cpp b/src/vm/exstate.cpp
index 29c7a063f5..c598412547 100644
--- a/src/vm/exstate.cpp
+++ b/src/vm/exstate.cpp
@@ -102,7 +102,7 @@ void ThreadExceptionState::FreeAllStackTraces()
}
}
-void ThreadExceptionState::ClearThrowablesForUnload(HandleTableBucket* pHndTblBucket)
+void ThreadExceptionState::ClearThrowablesForUnload(void* handleStore)
{
WRAPPER_NO_CONTRACT;
@@ -112,11 +112,13 @@ void ThreadExceptionState::ClearThrowablesForUnload(HandleTableBucket* pHndTblBu
ExInfo* pNode = &m_currentExInfo;
#endif // WIN64EXCEPTIONS
+ IGCHandleTable *pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
+
for ( ;
pNode != NULL;
pNode = pNode->m_pPrevNestedInfo)
{
- if (pHndTblBucket->Contains(pNode->m_hThrowable))
+ if (pHandleTable->ContainsHandle(handleStore, pNode->m_hThrowable))
{
pNode->DestroyExceptionHandle();
}
diff --git a/src/vm/exstate.h b/src/vm/exstate.h
index 50e71ed79b..104c76c77b 100644
--- a/src/vm/exstate.h
+++ b/src/vm/exstate.h
@@ -56,7 +56,7 @@ class ThreadExceptionState
public:
void FreeAllStackTraces();
- void ClearThrowablesForUnload(HandleTableBucket* pHndTblBucket);
+ void ClearThrowablesForUnload(void* handleStore);
#ifdef _DEBUG
typedef enum
@@ -116,16 +116,13 @@ public:
// to start a funclet-skipping stackwalk in this time window.
TEF_InconsistentExceptionState = 0x00000001,
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
TEF_ForeignExceptionRaise = 0x00000002,
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
};
void SetThreadExceptionFlag(ThreadExceptionFlag flag);
void ResetThreadExceptionFlag(ThreadExceptionFlag flag);
BOOL HasThreadExceptionFlag(ThreadExceptionFlag flag);
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
inline void SetRaisingForeignException()
{
LIMITED_METHOD_CONTRACT;
@@ -143,7 +140,6 @@ public:
LIMITED_METHOD_CONTRACT;
ResetThreadExceptionFlag(TEF_ForeignExceptionRaise);
}
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
#if defined(_DEBUG)
void AssertStackTraceInfo(StackTraceInfo *pSTI);
diff --git a/src/vm/fcall.h b/src/vm/fcall.h
index a952da1294..c3f026bccb 100644
--- a/src/vm/fcall.h
+++ b/src/vm/fcall.h
@@ -138,10 +138,13 @@
// FCThrow(). This is because FCThrow() has to generate an unexecuted
// "return" statement for the code parser.
//
-// - If first and/or second argument of your FCall is 64-bit value on x86
-// (ie INT64, UINT64 or DOUBLE), you must use "V" versions of FCDECL and
-// FCIMPL macros to enregister arguments correctly. For example, FCDECL3_IVI
-// must be used for FCalls that take 3 arguments and 2nd argument is INT64.
+// - On x86, if first and/or second argument of your FCall cannot be passed
+// in either of the __fastcall registers (ECX/EDX), you must use "V" versions
+// of FCDECL and FCIMPL macros to enregister arguments correctly. Some of the
+// most common types that fit this requirement are 64-bit values (i.e. INT64 or
+// UINT64) and floating-point values (i.e. FLOAT or DOUBLE). For example, FCDECL3_IVI
+// must be used for FCalls that take 3 arguments and 2nd argument is INT64 and
+// FDECL2_VV must be used for FCalls that take 2 arguments where both are FLOAT.
//
// - You may use structs for protecting multiple OBJECTREF's simultaneously.
// In these cases, you must use a variant of a helper method frame with PROTECT
@@ -374,16 +377,27 @@ LPVOID __FCThrowArgument(LPVOID me, enum RuntimeExceptionKind reKind, LPCWSTR ar
// Choose the appropriate calling convention for FCALL helpers on the basis of the JIT calling convention
#ifdef __GNUC__
-#define F_CALL_CONV __attribute__((stdcall, regparm(3)))
-#else
+#define F_CALL_CONV __attribute__((cdecl, regparm(3)))
+
+// GCC fastcall convention (simulated via stdcall) is different from MSVC fastcall convention. GCC can use up
+// to 3 registers to store parameters. The registers used are EAX, EDX, ECX. Dummy parameters and reordering
+// of the actual parameters in the FCALL signature is used to make the calling convention to look like in MSVC.
+#define SWIZZLE_REGARG_ORDER
+#else // __GNUC__
#define F_CALL_CONV __fastcall
-#endif
+#endif // !__GNUC__
+
+#define SWIZZLE_STKARG_ORDER
+#else // _TARGET_X86_
-#if defined(__GNUC__)
+//
+// non-x86 platforms don't have messed-up calling convention swizzling
+//
+#define F_CALL_CONV
+#endif // !_TARGET_X86_
-// GCC fastcall convention is different from MSVC fastcall convention. GCC can use up to 3 registers to
-// store parameters. The registers used are EAX, EDX, ECX. Dummy parameters and reordering of the
-// actual parameters in the FCALL signature is used to make the calling convention to look like in MSVC.
+#ifdef SWIZZLE_STKARG_ORDER
+#ifdef SWIZZLE_REGARG_ORDER
#define FCDECL0(rettype, funcname) rettype F_CALL_CONV funcname()
#define FCDECL1(rettype, funcname, a1) rettype F_CALL_CONV funcname(int /* EAX */, int /* EDX */, a1)
@@ -414,7 +428,7 @@ LPVOID __FCThrowArgument(LPVOID me, enum RuntimeExceptionKind reKind, LPCWSTR ar
#define FCDECL5_IVI(rettype, funcname, a1, a2, a3, a4, a5) rettype F_CALL_CONV funcname(int /* EAX */, a3, a1, a5, a4, a2)
#define FCDECL5_VII(rettype, funcname, a1, a2, a3, a4, a5) rettype F_CALL_CONV funcname(int /* EAX */, a3, a2, a5, a4, a1)
-#else // __GNUC__
+#else // SWIZZLE_REGARG_ORDER
#define FCDECL0(rettype, funcname) rettype F_CALL_CONV funcname()
#define FCDECL1(rettype, funcname, a1) rettype F_CALL_CONV funcname(a1)
@@ -445,7 +459,7 @@ LPVOID __FCThrowArgument(LPVOID me, enum RuntimeExceptionKind reKind, LPCWSTR ar
#define FCDECL5_IVI(rettype, funcname, a1, a2, a3, a4, a5) rettype F_CALL_CONV funcname(a1, a3, a5, a4, a2)
#define FCDECL5_VII(rettype, funcname, a1, a2, a3, a4, a5) rettype F_CALL_CONV funcname(a2, a3, a5, a4, a1)
-#endif // __GNUC__
+#endif // !SWIZZLE_REGARG_ORDER
#if 0
//
@@ -469,40 +483,38 @@ LPVOID __FCThrowArgument(LPVOID me, enum RuntimeExceptionKind reKind, LPCWSTR ar
#define FCCALL12(funcname, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) funcname(a1, a2, a12, a11, a10, a9, a8, a7, a6, a5, a4, a3)
#endif // 0
-#else // !_TARGET_X86
+#else // !SWIZZLE_STKARG_ORDER
-#define F_CALL_CONV
-
-#define FCDECL0(rettype, funcname) rettype funcname()
-#define FCDECL1(rettype, funcname, a1) rettype funcname(a1)
-#define FCDECL1_V(rettype, funcname, a1) rettype funcname(a1)
-#define FCDECL2(rettype, funcname, a1, a2) rettype funcname(a1, a2)
-#define FCDECL2VA(rettype, funcname, a1, a2) rettype funcname(a1, a2, ...)
-#define FCDECL2_VV(rettype, funcname, a1, a2) rettype funcname(a1, a2)
-#define FCDECL2_VI(rettype, funcname, a1, a2) rettype funcname(a1, a2)
-#define FCDECL2_IV(rettype, funcname, a1, a2) rettype funcname(a1, a2)
-#define FCDECL3(rettype, funcname, a1, a2, a3) rettype funcname(a1, a2, a3)
-#define FCDECL3_IIV(rettype, funcname, a1, a2, a3) rettype funcname(a1, a2, a3)
-#define FCDECL3_VII(rettype, funcname, a1, a2, a3) rettype funcname(a1, a2, a3)
-#define FCDECL3_IVV(rettype, funcname, a1, a2, a3) rettype funcname(a1, a2, a3)
-#define FCDECL3_IVI(rettype, funcname, a1, a2, a3) rettype funcname(a1, a2, a3)
-#define FCDECL3_VVI(rettype, funcname, a1, a2, a3) rettype funcname(a1, a2, a3)
-#define FCDECL4(rettype, funcname, a1, a2, a3, a4) rettype funcname(a1, a2, a3, a4)
-#define FCDECL5(rettype, funcname, a1, a2, a3, a4, a5) rettype funcname(a1, a2, a3, a4, a5)
-#define FCDECL6(rettype, funcname, a1, a2, a3, a4, a5, a6) rettype funcname(a1, a2, a3, a4, a5, a6)
-#define FCDECL7(rettype, funcname, a1, a2, a3, a4, a5, a6, a7) rettype funcname(a1, a2, a3, a4, a5, a6, a7)
-#define FCDECL8(rettype, funcname, a1, a2, a3, a4, a5, a6, a7, a8) rettype funcname(a1, a2, a3, a4, a5, a6, a7, a8)
-#define FCDECL9(rettype, funcname, a1, a2, a3, a4, a5, a6, a7, a8, a9) rettype funcname(a1, a2, a3, a4, a5, a6, a7, a8, a9)
-#define FCDECL10(rettype,funcname, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) rettype funcname(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
-#define FCDECL11(rettype,funcname, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) rettype funcname(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)
-#define FCDECL12(rettype,funcname, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) rettype funcname(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)
-#define FCDECL13(rettype,funcname, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) rettype funcname(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)
-#define FCDECL14(rettype,funcname, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) rettype funcname(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)
-
-#define FCDECL5_IVI(rettype, funcname, a1, a2, a3, a4, a5) rettype funcname(a1, a2, a3, a4, a5)
-#define FCDECL5_VII(rettype, funcname, a1, a2, a3, a4, a5) rettype funcname(a1, a2, a3, a4, a5)
-
-#endif // _TARGET_X86_
+#define FCDECL0(rettype, funcname) rettype F_CALL_CONV funcname()
+#define FCDECL1(rettype, funcname, a1) rettype F_CALL_CONV funcname(a1)
+#define FCDECL1_V(rettype, funcname, a1) rettype F_CALL_CONV funcname(a1)
+#define FCDECL2(rettype, funcname, a1, a2) rettype F_CALL_CONV funcname(a1, a2)
+#define FCDECL2VA(rettype, funcname, a1, a2) rettype F_CALL_CONV funcname(a1, a2, ...)
+#define FCDECL2_VV(rettype, funcname, a1, a2) rettype F_CALL_CONV funcname(a1, a2)
+#define FCDECL2_VI(rettype, funcname, a1, a2) rettype F_CALL_CONV funcname(a1, a2)
+#define FCDECL2_IV(rettype, funcname, a1, a2) rettype F_CALL_CONV funcname(a1, a2)
+#define FCDECL3(rettype, funcname, a1, a2, a3) rettype F_CALL_CONV funcname(a1, a2, a3)
+#define FCDECL3_IIV(rettype, funcname, a1, a2, a3) rettype F_CALL_CONV funcname(a1, a2, a3)
+#define FCDECL3_VII(rettype, funcname, a1, a2, a3) rettype F_CALL_CONV funcname(a1, a2, a3)
+#define FCDECL3_IVV(rettype, funcname, a1, a2, a3) rettype F_CALL_CONV funcname(a1, a2, a3)
+#define FCDECL3_IVI(rettype, funcname, a1, a2, a3) rettype F_CALL_CONV funcname(a1, a2, a3)
+#define FCDECL3_VVI(rettype, funcname, a1, a2, a3) rettype F_CALL_CONV funcname(a1, a2, a3)
+#define FCDECL4(rettype, funcname, a1, a2, a3, a4) rettype F_CALL_CONV funcname(a1, a2, a3, a4)
+#define FCDECL5(rettype, funcname, a1, a2, a3, a4, a5) rettype F_CALL_CONV funcname(a1, a2, a3, a4, a5)
+#define FCDECL6(rettype, funcname, a1, a2, a3, a4, a5, a6) rettype F_CALL_CONV funcname(a1, a2, a3, a4, a5, a6)
+#define FCDECL7(rettype, funcname, a1, a2, a3, a4, a5, a6, a7) rettype F_CALL_CONV funcname(a1, a2, a3, a4, a5, a6, a7)
+#define FCDECL8(rettype, funcname, a1, a2, a3, a4, a5, a6, a7, a8) rettype F_CALL_CONV funcname(a1, a2, a3, a4, a5, a6, a7, a8)
+#define FCDECL9(rettype, funcname, a1, a2, a3, a4, a5, a6, a7, a8, a9) rettype F_CALL_CONV funcname(a1, a2, a3, a4, a5, a6, a7, a8, a9)
+#define FCDECL10(rettype,funcname, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) rettype F_CALL_CONV funcname(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
+#define FCDECL11(rettype,funcname, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) rettype F_CALL_CONV funcname(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11)
+#define FCDECL12(rettype,funcname, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) rettype F_CALL_CONV funcname(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)
+#define FCDECL13(rettype,funcname, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) rettype F_CALL_CONV funcname(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13)
+#define FCDECL14(rettype,funcname, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) rettype F_CALL_CONV funcname(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14)
+
+#define FCDECL5_IVI(rettype, funcname, a1, a2, a3, a4, a5) rettype F_CALL_CONV funcname(a1, a2, a3, a4, a5)
+#define FCDECL5_VII(rettype, funcname, a1, a2, a3, a4, a5) rettype F_CALL_CONV funcname(a1, a2, a3, a4, a5)
+
+#endif // !SWIZZLE_STKARG_ORDER
#define HELPER_FRAME_DECL(x) FrameWithCookie<HelperMethodFrame_##x##OBJ> __helperframe
@@ -933,12 +945,14 @@ extern int FC_NO_TAILCALL;
FC_COMMON_PROLOG(__me, FCallAssert)
-#if defined(_DEBUG) && !defined(CROSSGEN_COMPILE)
-
+#if defined(_DEBUG) && !defined(CROSSGEN_COMPILE) && !defined(__GNUC__)
// Build the list of all fcalls signatures. It is used in binder.cpp to verify
// compatibility of managed and unmanaged fcall signatures. The check is currently done
// for x86 only.
+#define CHECK_FCALL_SIGNATURE
+#endif
+#ifdef CHECK_FCALL_SIGNATURE
struct FCSigCheck {
public:
FCSigCheck(void* fnc, char* sig)
@@ -960,16 +974,15 @@ public:
#define FCSIGCHECK(funcname, signature) \
static FCSigCheck UNIQUE_LABEL(FCSigCheck)(GetEEFuncEntryPointMacro(funcname), signature);
-#else
+#else // CHECK_FCALL_SIGNATURE
#define FCSIGCHECK(funcname, signature)
-#endif
+#endif // !CHECK_FCALL_SIGNATURE
-#ifdef _TARGET_X86_
-
-#if defined(__GNUC__)
+#ifdef SWIZZLE_STKARG_ORDER
+#ifdef SWIZZLE_REGARG_ORDER
#define FCIMPL0(rettype, funcname) rettype F_CALL_CONV funcname() { FCIMPL_PROLOG(funcname)
#define FCIMPL1(rettype, funcname, a1) rettype F_CALL_CONV funcname(int /* EAX */, int /* EDX */, a1) { FCIMPL_PROLOG(funcname)
@@ -999,7 +1012,7 @@ public:
#define FCIMPL5_IVI(rettype, funcname, a1, a2, a3, a4, a5) rettype F_CALL_CONV funcname(int /* EAX */, a3, a1, a5, a4, a2) { FCIMPL_PROLOG(funcname)
#define FCIMPL5_VII(rettype, funcname, a1, a2, a3, a4, a5) rettype F_CALL_CONV funcname(int /* EAX */, a3, a2, a5, a4, a1) { FCIMPL_PROLOG(funcname)
-#else // __GNUC__
+#else // SWIZZLE_REGARG_ORDER
#define FCIMPL0(rettype, funcname) FCSIGCHECK(funcname, #rettype) \
rettype F_CALL_CONV funcname() { FCIMPL_PROLOG(funcname)
@@ -1057,12 +1070,9 @@ public:
#define FCIMPL5_VII(rettype, funcname, a1, a2, a3, a4, a5) FCSIGCHECK(funcname, #rettype "," "V" #a1 "," #a2 "," #a3 "," #a4 "," #a5) \
rettype F_CALL_CONV funcname(a2, a3, a5, a4, a1) { FCIMPL_PROLOG(funcname)
-#endif // __GNUC__
+#endif // !SWIZZLE_REGARG_ORDER
-#else // !_TARGET_X86_
-//
-// non-x86 platforms don't have messed-up calling convention swizzling
-//
+#else // SWIZZLE_STKARG_ORDER
#define FCIMPL0(rettype, funcname) rettype funcname() { FCIMPL_PROLOG(funcname)
#define FCIMPL1(rettype, funcname, a1) rettype funcname(a1) { FCIMPL_PROLOG(funcname)
@@ -1093,7 +1103,7 @@ public:
#define FCIMPL5_IVI(rettype, funcname, a1, a2, a3, a4, a5) rettype funcname(a1, a2, a3, a4, a5) { FCIMPL_PROLOG(funcname)
#define FCIMPL5_VII(rettype, funcname, a1, a2, a3, a4, a5) rettype funcname(a1, a2, a3, a4, a5) { FCIMPL_PROLOG(funcname)
-#endif
+#endif // !SWIZZLE_STKARG_ORDER
//==============================================================================================
// Use this to terminte an FCIMPLEND.
@@ -1109,9 +1119,8 @@ public:
// they do not remember the function they come from. Thus they will not
// show up in a stack trace. This is what you want for JIT helpers and the like
-#ifdef _TARGET_X86_
-
-#if defined(__GNUC__)
+#ifdef SWIZZLE_STKARG_ORDER
+#ifdef SWIZZLE_REGARG_ORDER
#define HCIMPL0(rettype, funcname) rettype F_CALL_CONV funcname() { HCIMPL_PROLOG(funcname)
#define HCIMPL1(rettype, funcname, a1) rettype F_CALL_CONV funcname(int /* EAX */, int /* EDX */, a1) { HCIMPL_PROLOG(funcname)
@@ -1134,7 +1143,7 @@ public:
#define HCCALL5(funcname, a1, a2, a3, a4, a5) funcname(0, a2, a1, a5, a4, a3)
#define HCCALL1_PTR(rettype, funcptr, a1) rettype (F_CALL_CONV * funcptr)(int /* EAX */, int /* EDX */, a1)
#define HCCALL2_PTR(rettype, funcptr, a1, a2) rettype (F_CALL_CONV * funcptr)(int /* EAX */, a2, a1)
-#else
+#else // SWIZZLE_REGARG_ORDER
#define HCIMPL0(rettype, funcname) rettype F_CALL_CONV funcname() { HCIMPL_PROLOG(funcname)
#define HCIMPL1(rettype, funcname, a1) rettype F_CALL_CONV funcname(a1) { HCIMPL_PROLOG(funcname)
@@ -1157,13 +1166,8 @@ public:
#define HCCALL5(funcname, a1, a2, a3, a4, a5) funcname(a1, a2, a5, a4, a3)
#define HCCALL1_PTR(rettype, funcptr, a1) rettype (F_CALL_CONV * funcptr)(a1)
#define HCCALL2_PTR(rettype, funcptr, a1, a2) rettype (F_CALL_CONV * funcptr)(a1, a2)
-
-#endif
-
-#else // !_TARGET_X86_
-//
-// non-x86 platforms don't have messed-up calling convention swizzling
-//
+#endif // !SWIZZLE_REGARG_ORDER
+#else // SWIZZLE_STKARG_ORDER
#define HCIMPL0(rettype, funcname) rettype F_CALL_CONV funcname() { HCIMPL_PROLOG(funcname)
#define HCIMPL1(rettype, funcname, a1) rettype F_CALL_CONV funcname(a1) { HCIMPL_PROLOG(funcname)
@@ -1187,7 +1191,7 @@ public:
#define HCCALL1_PTR(rettype, funcptr, a1) rettype (F_CALL_CONV * funcptr)(a1)
#define HCCALL2_PTR(rettype, funcptr, a1, a2) rettype (F_CALL_CONV * funcptr)(a1, a2)
-#endif
+#endif // !SWIZZLE_STKARG_ORDER
#define HCIMPLEND_RAW }
#define HCIMPLEND FCALL_TRANSITION_END(); }
diff --git a/src/vm/field.cpp b/src/vm/field.cpp
index da424db038..9cdb16f6b9 100644
--- a/src/vm/field.cpp
+++ b/src/vm/field.cpp
@@ -15,9 +15,6 @@
#include "encee.h"
#include "field.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "generics.h"
#include "peimagelayout.inl"
@@ -60,9 +57,6 @@ VOID FieldDesc::Init(mdFieldDef mb, CorElementType FieldType, DWORD dwMemberAttr
m_isStatic = fIsStatic != 0;
m_isRVA = fIsRVA != 0;
m_isThreadLocal = fIsThreadLocal != 0;
-#ifdef FEATURE_REMOTING
- m_isContextLocal = fIsContextLocal != 0;
-#endif
#ifdef _DEBUG
m_debugName = (LPUTF8)pszFieldName;
@@ -354,54 +348,6 @@ void FieldDesc::GetInstanceField(OBJECTREF o, VOID * pOutVal)
// Check whether we are getting a field value on a proxy. If so, then ask
// remoting services to extract the value from the instance.
-#ifdef FEATURE_REMOTING
- if (o->IsTransparentProxy())
- {
-#ifndef DACCESS_COMPILE
- o = CRemotingServices::GetObjectFromProxy(o);
-
- if (o->IsTransparentProxy())
- {
-#ifdef PROFILING_SUPPORTED
-
- GCPROTECT_BEGIN(o); // protect from RemotingClientInvocationStarted
-
- // If profiling is active, notify it that remoting stuff is kicking in,
- // if AlwaysUnwrap returned an identical object pointer which means that
- // we are definitely going through remoting for this access.
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackRemoting());
- {
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->RemotingClientInvocationStarted();
- }
- END_PIN_PROFILER();
- }
-#endif // PROFILING_SUPPORTED
-
- CRemotingServices::FieldAccessor(this, o, pOutVal, TRUE);
-
-#ifdef PROFILING_SUPPORTED
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackRemoting());
- {
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->RemotingClientInvocationFinished();
- }
- END_PIN_PROFILER();
- }
-
- GCPROTECT_END(); // protect from RemotingClientInvocationStarted
-
-#endif // PROFILING_SUPPORTED
-
- return;
- }
-#else
- DacNotImpl();
-#endif // #ifndef DACCESS_COMPILE
- }
-#endif // FEATURE_REMOTING
// Unbox the value class
TADDR pFieldAddress = (TADDR)GetInstanceAddress(o);
@@ -449,50 +395,6 @@ void FieldDesc::SetInstanceField(OBJECTREF o, const VOID * pInVal)
// class. If so, then ask remoting services to set the value on the
// instance
-#ifdef FEATURE_REMOTING
- if(o->IsTransparentProxy())
- {
- o = CRemotingServices::GetObjectFromProxy(o);
-
- if (o->IsTransparentProxy())
- {
-#ifdef PROFILING_SUPPORTED
-
- GCPROTECT_BEGIN(o);
-
- // If profiling is active, notify it that remoting stuff is kicking in,
- // if AlwaysUnwrap returned an identical object pointer which means that
- // we are definitely going through remoting for this access.
-
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackRemoting());
- {
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->RemotingClientInvocationStarted();
- }
- END_PIN_PROFILER();
- }
-#endif // PROFILING_SUPPORTED
-
- CRemotingServices::FieldAccessor(this, o, (void *)pInVal, FALSE);
-
-#ifdef PROFILING_SUPPORTED
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackRemoting());
- {
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->RemotingClientInvocationFinished();
- }
- END_PIN_PROFILER();
- }
- GCPROTECT_END();
-
-#endif // PROFILING_SUPPORTED
-
- return;
- }
- }
-#endif // FEATURE_REMOTING
#ifdef _DEBUG
//
diff --git a/src/vm/field.h b/src/vm/field.h
index e3e3ccd013..8e762eb4e4 100644
--- a/src/vm/field.h
+++ b/src/vm/field.h
@@ -55,9 +55,6 @@ class FieldDesc
// 8 bits...
unsigned m_isStatic : 1;
unsigned m_isThreadLocal : 1;
-#ifdef FEATURE_REMOTING
- unsigned m_isContextLocal : 1;
-#endif
unsigned m_isRVA : 1;
unsigned m_prot : 3;
// Does this field's mb require all 24 bits
@@ -295,9 +292,6 @@ public:
LIMITED_METHOD_CONTRACT;
return m_isStatic && (m_isRVA || m_isThreadLocal
-#ifdef FEATURE_REMOTING
- || m_isContextLocal
-#endif
);
}
@@ -335,11 +329,7 @@ public:
{
LIMITED_METHOD_DAC_CONTRACT;
-#ifdef FEATURE_REMOTING
- return m_isContextLocal;
-#else
return FALSE;
-#endif
}
// Indicate that this field was added by EnC
@@ -619,11 +609,6 @@ public:
_ASSERTE(IsStatic());
-#ifdef FEATURE_REMOTING
- if (IsContextStatic())
- return Context::GetStaticFieldAddress(this);
- else
-#endif
if (IsThreadStatic())
{
return Thread::GetStaticFieldAddress(this);
diff --git a/src/vm/fieldmarshaler.h b/src/vm/fieldmarshaler.h
index 9ec7e87610..287da41a5b 100644
--- a/src/vm/fieldmarshaler.h
+++ b/src/vm/fieldmarshaler.h
@@ -85,7 +85,12 @@ enum NStructFieldType
//=======================================================================
// Magic number for default struct packing size.
//=======================================================================
+#if defined(_TARGET_X86_) && defined(UNIX_X86_ABI)
+// A double is 4-byte aligned on GCC (without -malign-dobule)
+#define DEFAULT_PACKING_SIZE 4
+#else // _TARGET_X86_ && UNIX_X86_ABI
#define DEFAULT_PACKING_SIZE 8
+#endif // !_TARGET_X86_ || !UNIX_X86_ABI
//=======================================================================
diff --git a/src/vm/finalizerthread.cpp b/src/vm/finalizerthread.cpp
index 4c0f5acbf9..0a4da165a1 100644
--- a/src/vm/finalizerthread.cpp
+++ b/src/vm/finalizerthread.cpp
@@ -12,9 +12,6 @@
#include "runtimecallablewrapper.h"
#endif
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#ifdef FEATURE_PROFAPI_ATTACH_DETACH
#include "profattach.h"
@@ -94,48 +91,6 @@ void CallFinalizer(Object* obj)
{
if (!((obj->GetHeader()->GetBits()) & BIT_SBLK_FINALIZER_RUN))
{
-#ifdef FEATURE_REMOTING
- if (pMT->IsContextful())
- {
- Object *proxy = OBJECTREFToObject(CRemotingServices::GetProxyFromObject(ObjectToOBJECTREF(obj)));
-
- _ASSERTE(proxy && "finalizing an object that was never wrapped?????");
- if (proxy == NULL)
- {
- // Quite possibly the app abruptly shutdown while a proxy
- // was being setup for a contextful object. We will skip
- // finalizing this object.
- _ASSERTE (g_fEEShutDown);
- return;
- }
- else
- {
- // This saves us from the situation where an object gets GC-ed
- // after its Context.
- OBJECTREF stub = ((TRANSPARENTPROXYREF)ObjectToOBJECTREF(proxy))->GetStubData();
- Context *pServerCtx = *((Context **)stub->UnBox());
- // Check if the context is valid
- if (!Context::ValidateContext(pServerCtx))
- {
- // Since the server context is gone (GC-ed)
- // we will associate the server with the default
- // context for a good faith attempt to run
- // the finalizer
- // We want to do this only if we are using RemotingProxy
- // and not for other types of proxies (eg. SvcCompPrxy)
- OBJECTREF orRP = ObjectToOBJECTREF(CRemotingServices::GetRealProxy(proxy));
- if(CTPMethodTable::IsInstanceOfRemotingProxy(
- orRP->GetMethodTable()))
- {
- *((Context **)stub->UnBox()) = (Context*) GetThread()->GetContext();
- }
- }
- // call Finalize on the proxy of the server object.
- obj = proxy;
- pMT = obj->GetMethodTable();
- }
- }
-#endif // FEATURE_REMOTING
_ASSERTE(obj->GetMethodTable() == pMT);
_ASSERTE(pMT->HasFinalizer() || pMT->IsTransparentProxy());
@@ -387,9 +342,7 @@ void FinalizerThread::ProcessProfilerAttachIfNecessary(ULONGLONG * pui64Timestam
STATIC_CONTRACT_GC_NOTRIGGER;
STATIC_CONTRACT_MODE_ANY;
- if (CLRMemoryHosted() ||
- CLRSyncHosted() ||
- (MHandles[kProfilingAPIAttach] == NULL))
+ if (MHandles[kProfilingAPIAttach] == NULL)
{
return;
}
@@ -442,185 +395,130 @@ void FinalizerThread::ProcessProfilerAttachIfNecessary(ULONGLONG * pui64Timestam
void FinalizerThread::WaitForFinalizerEvent (CLREvent *event)
{
- // TODO wwl: merge the following two blocks
- if (!CLRMemoryHosted() && !CLRSyncHosted()) {
- // Non-host environment
-
- // We don't want kLowMemoryNotification to starve out kFinalizer
- // (as the latter may help correct the former), and we don't want either
- // to starve out kProfilingAPIAttach, as we want decent responsiveness
- // to a user trying to attach a profiler. So check in this order:
- // kProfilingAPIAttach alone (0 wait)
- // kFinalizer alone (2s wait)
- // all events together (infinite wait)
+ // Non-host environment
+
+ // We don't want kLowMemoryNotification to starve out kFinalizer
+ // (as the latter may help correct the former), and we don't want either
+ // to starve out kProfilingAPIAttach, as we want decent responsiveness
+ // to a user trying to attach a profiler. So check in this order:
+ // kProfilingAPIAttach alone (0 wait)
+ // kFinalizer alone (2s wait)
+ // all events together (infinite wait)
#ifdef FEATURE_PROFAPI_ATTACH_DETACH
- // NULL means check attach event now, and don't worry about how long it was since
- // the last time the event was checked.
- ProcessProfilerAttachIfNecessary(NULL);
+ // NULL means check attach event now, and don't worry about how long it was since
+ // the last time the event was checked.
+ ProcessProfilerAttachIfNecessary(NULL);
#endif // FEATURE_PROFAPI_ATTACH_DETACH
- //give a chance to the finalizer event (2s)
- switch (event->Wait(2000, FALSE))
- {
- case (WAIT_OBJECT_0):
- return;
- case (WAIT_ABANDONED):
- return;
- case (WAIT_TIMEOUT):
- break;
- }
- MHandles[kFinalizer] = event->GetHandleUNHOSTED();
- while (1)
- {
- // WaitForMultipleObjects will wait on the event handles in MHandles
- // starting at this offset
- UINT uiEventIndexOffsetForWait = 0;
+ //give a chance to the finalizer event (2s)
+ switch (event->Wait(2000, FALSE))
+ {
+ case (WAIT_OBJECT_0):
+ return;
+ case (WAIT_ABANDONED):
+ return;
+ case (WAIT_TIMEOUT):
+ break;
+ }
+ MHandles[kFinalizer] = event->GetHandleUNHOSTED();
+ while (1)
+ {
+ // WaitForMultipleObjects will wait on the event handles in MHandles
+ // starting at this offset
+ UINT uiEventIndexOffsetForWait = 0;
- // WaitForMultipleObjects will wait on this number of event handles
- DWORD cEventsForWait = kHandleCount;
-
- // #MHandleTypeValues:
- // WaitForMultipleObjects will now wait on a subset of the events in the
- // MHandles array. At this point kFinalizer should have a non-NULL entry
- // in the array. Wait on the following events:
- //
- // * kLowMemoryNotification (if it's non-NULL && g_fEEStarted)
- // * kFinalizer (always)
- // * kProfilingAPIAttach (if it's non-NULL)
- //
- // The enum code:MHandleType values become important here, as
- // WaitForMultipleObjects needs to wait on a contiguous set of non-NULL
- // entries in MHandles, so we'll assert the values are contiguous as we
- // expect.
- _ASSERTE(kLowMemoryNotification == 0);
- _ASSERTE((kFinalizer == 1) && (MHandles[1] != NULL));
+ // WaitForMultipleObjects will wait on this number of event handles
+ DWORD cEventsForWait = kHandleCount;
+
+ // #MHandleTypeValues:
+ // WaitForMultipleObjects will now wait on a subset of the events in the
+ // MHandles array. At this point kFinalizer should have a non-NULL entry
+ // in the array. Wait on the following events:
+ //
+ // * kLowMemoryNotification (if it's non-NULL && g_fEEStarted)
+ // * kFinalizer (always)
+ // * kProfilingAPIAttach (if it's non-NULL)
+ //
+ // The enum code:MHandleType values become important here, as
+ // WaitForMultipleObjects needs to wait on a contiguous set of non-NULL
+ // entries in MHandles, so we'll assert the values are contiguous as we
+ // expect.
+ _ASSERTE(kLowMemoryNotification == 0);
+ _ASSERTE((kFinalizer == 1) && (MHandles[1] != NULL));
#ifdef FEATURE_PROFAPI_ATTACH_DETACH
- _ASSERTE(kProfilingAPIAttach == 2);
+ _ASSERTE(kProfilingAPIAttach == 2);
#endif //FEATURE_PROFAPI_ATTACH_DETACH
- // Exclude the low-memory notification event from the wait if the event
- // handle is NULL or the EE isn't fully started up yet.
- if ((MHandles[kLowMemoryNotification] == NULL) || !g_fEEStarted)
- {
- uiEventIndexOffsetForWait = kLowMemoryNotification + 1;
- cEventsForWait--;
- }
+ // Exclude the low-memory notification event from the wait if the event
+ // handle is NULL or the EE isn't fully started up yet.
+ if ((MHandles[kLowMemoryNotification] == NULL) || !g_fEEStarted)
+ {
+ uiEventIndexOffsetForWait = kLowMemoryNotification + 1;
+ cEventsForWait--;
+ }
#ifdef FEATURE_PROFAPI_ATTACH_DETACH
- // Exclude kProfilingAPIAttach if it's NULL
- if (MHandles[kProfilingAPIAttach] == NULL)
- {
- cEventsForWait--;
- }
+ // Exclude kProfilingAPIAttach if it's NULL
+ if (MHandles[kProfilingAPIAttach] == NULL)
+ {
+ cEventsForWait--;
+ }
#endif //FEATURE_PROFAPI_ATTACH_DETACH
- switch (WaitForMultipleObjectsEx(
- cEventsForWait, // # objects to wait on
- &(MHandles[uiEventIndexOffsetForWait]), // array of objects to wait on
- FALSE, // bWaitAll == FALSE, so wait for first signal
+ switch (WaitForMultipleObjectsEx(
+ cEventsForWait, // # objects to wait on
+ &(MHandles[uiEventIndexOffsetForWait]), // array of objects to wait on
+ FALSE, // bWaitAll == FALSE, so wait for first signal
#if defined(__linux__) && defined(FEATURE_EVENT_TRACE)
- LINUX_HEAP_DUMP_TIME_OUT,
+ LINUX_HEAP_DUMP_TIME_OUT,
#else
- INFINITE, // timeout
+ INFINITE, // timeout
#endif
- FALSE) // alertable
+ FALSE) // alertable
- // Adjust the returned array index for the offset we used, so the return
- // value is relative to entire MHandles array
- + uiEventIndexOffsetForWait)
+ // Adjust the returned array index for the offset we used, so the return
+ // value is relative to entire MHandles array
+ + uiEventIndexOffsetForWait)
+ {
+ case (WAIT_OBJECT_0 + kLowMemoryNotification):
+ //short on memory GC immediately
+ GetFinalizerThread()->DisablePreemptiveGC();
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(0, true);
+ GetFinalizerThread()->EnablePreemptiveGC();
+ //wait only on the event for 2s
+ switch (event->Wait(2000, FALSE))
{
- case (WAIT_OBJECT_0 + kLowMemoryNotification):
- //short on memory GC immediately
- GetFinalizerThread()->DisablePreemptiveGC();
- GCHeapUtilities::GetGCHeap()->GarbageCollect(0, TRUE);
- GetFinalizerThread()->EnablePreemptiveGC();
- //wait only on the event for 2s
- switch (event->Wait(2000, FALSE))
- {
- case (WAIT_OBJECT_0):
- return;
- case (WAIT_ABANDONED):
- return;
- case (WAIT_TIMEOUT):
- break;
- }
- break;
- case (WAIT_OBJECT_0 + kFinalizer):
+ case (WAIT_OBJECT_0):
return;
-#ifdef FEATURE_PROFAPI_ATTACH_DETACH
- case (WAIT_OBJECT_0 + kProfilingAPIAttach):
- // Spawn thread to perform the profiler attach, then resume our wait
- ProfilingAPIAttachDetach::ProcessSignaledAttachEvent();
+ case (WAIT_ABANDONED):
+ return;
+ case (WAIT_TIMEOUT):
break;
+ }
+ break;
+ case (WAIT_OBJECT_0 + kFinalizer):
+ return;
+#ifdef FEATURE_PROFAPI_ATTACH_DETACH
+ case (WAIT_OBJECT_0 + kProfilingAPIAttach):
+ // Spawn thread to perform the profiler attach, then resume our wait
+ ProfilingAPIAttachDetach::ProcessSignaledAttachEvent();
+ break;
#endif // FEATURE_PROFAPI_ATTACH_DETACH
#if defined(__linux__) && defined(FEATURE_EVENT_TRACE)
- case (WAIT_TIMEOUT + kLowMemoryNotification):
- case (WAIT_TIMEOUT + kFinalizer):
- if (g_TriggerHeapDump)
- {
- return;
- }
-
- break;
-#endif
- default:
- //what's wrong?
- _ASSERTE (!"Bad return code from WaitForMultipleObjects");
+ case (WAIT_TIMEOUT + kLowMemoryNotification):
+ case (WAIT_TIMEOUT + kFinalizer):
+ if (g_TriggerHeapDump)
+ {
return;
}
- }
- }
- else {
- static LONG sLastLowMemoryFromHost = 0;
- while (1) {
-#if defined(__linux__) && defined(FEATURE_EVENT_TRACE)
- DWORD timeout = LINUX_HEAP_DUMP_TIME_OUT;
-#else
- DWORD timeout = INFINITE;
-#endif
- if (!CLRMemoryHosted())
- {
- if (WaitForSingleObject(MHandles[kLowMemoryNotification], 0) == WAIT_OBJECT_0) {
- //short on memory GC immediately
- GetFinalizerThread()->DisablePreemptiveGC();
- GCHeapUtilities::GetGCHeap()->GarbageCollect(0, TRUE);
- GetFinalizerThread()->EnablePreemptiveGC();
- }
- //wait only on the event for 2s
- // The previous GC might not wake up finalizer thread if there is
- // no objects to be finalized.
- timeout = 2000;
- }
- switch (event->Wait(timeout, FALSE))
- {
- case (WAIT_OBJECT_0):
- if (CLRMemoryHosted())
- {
- if (sLastLowMemoryFromHost != g_bLowMemoryFromHost)
- {
- sLastLowMemoryFromHost = g_bLowMemoryFromHost;
- if (sLastLowMemoryFromHost != 0)
- {
- GetFinalizerThread()->DisablePreemptiveGC();
- GCHeapUtilities::GetGCHeap()->GarbageCollect(0, TRUE);
- GetFinalizerThread()->EnablePreemptiveGC();
- }
- }
- }
- return;
- case (WAIT_ABANDONED):
- return;
- case (WAIT_TIMEOUT):
-#if defined(__linux__) && defined(FEATURE_EVENT_TRACE)
- if (g_TriggerHeapDump)
- {
- return;
- }
+ break;
#endif
- break;
- }
+ default:
+ //what's wrong?
+ _ASSERTE (!"Bad return code from WaitForMultipleObjects");
+ return;
}
}
}
@@ -677,7 +575,7 @@ VOID FinalizerThread::FinalizerThreadWorker(void *args)
{
s_forcedGCInProgress = true;
GetFinalizerThread()->DisablePreemptiveGC();
- GCHeapUtilities::GetGCHeap()->GarbageCollect(2, FALSE, collection_blocking);
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(2, false, collection_blocking);
GetFinalizerThread()->EnablePreemptiveGC();
s_forcedGCInProgress = false;
@@ -747,7 +645,7 @@ VOID FinalizerThread::FinalizerThreadWorker(void *args)
}
else if (UnloadingAppDomain == NULL)
break;
- else if (!GCHeapUtilities::GetGCHeap()->FinalizeAppDomain(UnloadingAppDomain, fRunFinalizersOnUnload))
+ else if (!GCHeapUtilities::GetGCHeap()->FinalizeAppDomain(UnloadingAppDomain, !!fRunFinalizersOnUnload))
{
break;
}
@@ -807,7 +705,7 @@ void FinalizerThread::FinalizeObjectsOnShutdown(LPVOID args)
}
-DWORD __stdcall FinalizerThread::FinalizerThreadStart(void *args)
+DWORD WINAPI FinalizerThread::FinalizerThreadStart(void *args)
{
ClrFlsSetThreadType (ThreadType_Finalizer);
@@ -834,18 +732,6 @@ DWORD __stdcall FinalizerThread::FinalizerThreadStart(void *args)
_ASSERTE(s_FinalizerThreadOK);
_ASSERTE(GetThread() == GetFinalizerThread());
- // workaround wwl: avoid oom problem for finalizer thread startup.
- if (CLRTaskHosted())
- {
- SignalFinalizationDone(TRUE);
- // SQL's scheduler may give finalizer thread a very small slice of CPU if finalizer thread
- // shares a scheduler with other tasks. This can cause severe problem for finalizer thread.
- // To reduce pain here, we move finalizer thread off SQL's scheduler.
- // But SQL's scheduler does not support IHostTask::Alert on a task off scheduler, so we need
- // to return finalizer thread back to scheduler when we wait alertably.
- // GetFinalizerThread()->LeaveRuntime((size_t)SetupThreadNoThrow);
- }
-
// finalizer should always park in default domain
if (s_FinalizerThreadOK)
@@ -1003,11 +889,8 @@ void FinalizerThread::FinalizerThreadCreate()
} CONTRACTL_END;
#ifndef FEATURE_PAL
- if (!CLRMemoryHosted())
- {
- MHandles[kLowMemoryNotification] =
- CreateMemoryResourceNotification(LowMemoryResourceNotification);
- }
+ MHandles[kLowMemoryNotification] =
+ CreateMemoryResourceNotification(LowMemoryResourceNotification);
#endif // FEATURE_PAL
hEventFinalizerDone = new CLREvent();
@@ -1043,16 +926,6 @@ void FinalizerThread::FinalizerThreadCreate()
// debugger may have been detached between the time it got the notification
// and the moment we execute the test below.
_ASSERTE(dwRet == 1 || dwRet == 2);
-
- // workaround wwl: make sure finalizer is ready. This avoids OOM problem on finalizer
- // thread startup.
- if (CLRTaskHosted()) {
- FinalizerThreadWait(INFINITE);
- if (!s_FinalizerThreadOK)
- {
- ThrowOutOfMemory();
- }
- }
}
}
@@ -1408,12 +1281,10 @@ BOOL FinalizerThread::FinalizerThreadWatchDogHelper()
}
#endif // PROFILING_SUPPORTED
-#ifdef FEATURE_CORECLR
// This change was added late in Windows Phone 8, so we want to keep it minimal.
// We should consider refactoring this later, as we've got a lot of dead code here now on CoreCLR.
dwTimeout = INFINITE;
maxTotalWait = INFINITE;
-#endif // FEATURE_CORECLR
while (1) {
struct Param
@@ -1474,6 +1345,8 @@ BOOL FinalizerThread::FinalizerThreadWatchDogHelper()
}
ULONGLONG dwCurTickCount = CLRGetTickCount64();
if (pThread && pThread->m_State & (Thread::TS_UserSuspendPending | Thread::TS_DebugSuspendPending)) {
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(pThread->m_State & Thread::TS_UserSuspendPending));
dwBeginTickCount = dwCurTickCount;
}
if (dwCurTickCount - dwBeginTickCount >= maxTotalWait)
diff --git a/src/vm/finalizerthread.h b/src/vm/finalizerthread.h
index 90dd3e9ec9..be684514b5 100644
--- a/src/vm/finalizerthread.h
+++ b/src/vm/finalizerthread.h
@@ -89,7 +89,7 @@ public:
static VOID FinalizerThreadWorker(void *args);
static void FinalizeObjectsOnShutdown(LPVOID args);
- static DWORD __stdcall FinalizerThreadStart(void *args);
+ static DWORD WINAPI FinalizerThreadStart(void *args);
static void FinalizerThreadCreate();
static BOOL FinalizerThreadWatchDog();
diff --git a/src/vm/fptrstubs.cpp b/src/vm/fptrstubs.cpp
index 62f6df966b..6502a43c55 100644
--- a/src/vm/fptrstubs.cpp
+++ b/src/vm/fptrstubs.cpp
@@ -7,9 +7,6 @@
#include "common.h"
#include "fptrstubs.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
// -------------------------------------------------------
// FuncPtr stubs
@@ -93,18 +90,6 @@ PCODE FuncPtrStubs::GetFuncPtrStub(MethodDesc * pMD, PrecodeType type)
PCODE target = NULL;
-#ifdef FEATURE_REMOTING
- if (pMD->IsInterface() && !pMD->IsStatic())
- {
- // FuncPtrStubs on interface virtuals are used to transition
- // into the remoting system with the exact interface method.
-
- _ASSERTE(type == PRECODE_STUB);
-
- target = CRemotingServices::GetDispatchInterfaceHelper(pMD);
- }
- else
-#endif // FEATURE_REMOTING
if (type != GetDefaultType(pMD) &&
// Always use stable entrypoint for LCG. If the cached precode pointed directly to JITed code,
// we would not be able to reuse it when the DynamicMethodDesc got reused for a new DynamicMethod.
diff --git a/src/vm/frames.cpp b/src/vm/frames.cpp
index ae3cfdbc75..fa5c7875eb 100644
--- a/src/vm/frames.cpp
+++ b/src/vm/frames.cpp
@@ -24,9 +24,6 @@
#include "dbginterface.h"
#include "gms.h"
#include "eeconfig.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "ecall.h"
#include "clsload.hpp"
#include "cgensys.h"
@@ -1013,34 +1010,6 @@ void GCFrame::GcScanRoots(promote_func *fn, ScanContext* sc)
}
}
-#ifdef FEATURE_REMOTING
-#include "objectclone.h"
-void GCSafeCollectionFrame::GcScanRoots(promote_func *fn, ScanContext* sc)
-{
- WRAPPER_NO_CONTRACT;
-
- PTR_GCSafeCollection collection = dac_cast<PTR_GCSafeCollection>(m_pCollection);
- collection->ReportGCRefs(fn, sc);
-}
-
-#ifndef DACCESS_COMPILE
-GCSafeCollectionFrame::GCSafeCollectionFrame(void *collection)
-{
- WRAPPER_NO_CONTRACT;
-
- _ASSERTE(collection != NULL);
- m_pCollection = collection;
-
- Frame::Push();
-}
-
-VOID GCSafeCollectionFrame::Pop()
-{
- LIMITED_METHOD_CONTRACT;
- Frame::Pop();
-}
-#endif // !DACCESS_COMPILE
-#endif // FEATURE_REMOTING
#ifndef DACCESS_COMPILE
//--------------------------------------------------------------------
@@ -1537,76 +1506,6 @@ BOOL TransitionFrame::Protects(OBJECTREF * ppORef)
//
//+----------------------------------------------------------------------------
-#ifdef FEATURE_REMOTING
-
-#ifndef DACCESS_COMPILE
-TPMethodFrame::TPMethodFrame(TransitionBlock * pTransitionBlock)
- : FramedMethodFrame(pTransitionBlock, NULL)
-{
- LIMITED_METHOD_CONTRACT;
-}
-#endif // #ifndef DACCESS_COMPILE
-
-void TPMethodFrame::GcScanRoots(promote_func *fn, ScanContext* sc)
-{
- WRAPPER_NO_CONTRACT;
-
- // Delegate to FramedMethodFrame
- FramedMethodFrame::GcScanRoots(fn, sc);
- FramedMethodFrame::PromoteCallerStack(fn, sc);
-
- MetaSig::RETURNTYPE returnType = GetFunction()->ReturnsObject();
-
- // Promote the returned object
- if(returnType == MetaSig::RETOBJ)
- {
- (*fn)(GetReturnObjectPtr(), sc, CHECK_APP_DOMAIN);
- }
- else if (returnType == MetaSig::RETBYREF)
- {
- PromoteCarefully(fn, GetReturnObjectPtr(), sc, GC_CALL_INTERIOR|CHECK_APP_DOMAIN);
- }
-
- return;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: TPMethodFrame::TraceFrame public
-//
-// Synopsis: Return where the frame will execute next - the result is filled
-// into the given "trace" structure. The frame is responsible for
-// detecting where it is in its execution lifetime.
-//
-//
-
-//
-//+----------------------------------------------------------------------------
-BOOL TPMethodFrame::TraceFrame(Thread *thread, BOOL fromPatch,
- TraceDestination *trace, REGDISPLAY *regs)
-{
- WRAPPER_NO_CONTRACT;
-
- // We want to set a frame patch, unless we're already at the
- // frame patch, in which case we'll trace stable entrypoint which
- // should be set by now.
-
- if (fromPatch)
- {
- trace->InitForStub(GetFunction()->GetStableEntryPoint());
- }
- else
- {
-#ifdef DACCESS_COMPILE
- DacNotImpl();
-#else
- trace->InitForStub(GetEEFuncEntryPoint(TransparentProxyStubPatchLabel));
-#endif
- }
- return TRUE;
-
-}
-#endif // FEATURE_REMOTING
#ifdef FEATURE_COMINTEROP
@@ -2064,88 +1963,6 @@ VOID InlinedCallFrame::Init()
m_pCallerReturnAddress = NULL;
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-#if defined(_WIN64) && !defined(FEATURE_PAL)
-
-EXTERN_C void PInvokeStubForHostInner(DWORD dwStackSize, LPVOID pStackFrame, LPVOID pTarget);
-
-// C++ piece of one static stub for host on 64-bit. This is called by PInvokeStubForHost (PInvokeStubs.asm).
-void __stdcall PInvokeStubForHostWorker(DWORD dwStackSize, LPVOID pStackFrame, LPVOID pThis)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- InlinedCallFrame *pFrame = (InlinedCallFrame *)GetThread()->GetFrame();
- _ASSERTE(InlinedCallFrame::FrameHasActiveCall(pFrame));
-
- LPVOID pTarget = NULL;
- MethodDesc *pMD = pFrame->GetFunction();
-
- if (pMD == NULL)
- {
- // This is a CALLI and m_Datum is a mangled target
- pTarget = (LPVOID)((UINT_PTR)pFrame->m_Datum >> 1);
- }
- else if (pMD->IsNDirect())
- {
- pTarget = ((NDirectMethodDesc *)pMD)->ndirect.m_pNativeNDirectTarget;
- if (pMD->IsQCall())
- {
-#ifdef FEATURE_STACK_PROBE
- // We need just the stack probe for QCalls
- RetailStackProbe(ADJUST_PROBE(DEFAULT_ENTRY_PROBE_AMOUNT));
-#endif
- PInvokeStubForHostInner(dwStackSize, pStackFrame, pTarget);
- return;
- }
- }
-#ifdef FEATURE_COMINTEROP
- else if (pMD->IsComPlusCall() || pMD->IsEEImpl())
- {
- LPVOID *lpVtbl = *(LPVOID **)pThis;
- ComPlusCallInfo *pComPlusCallInfo = ComPlusCallInfo::FromMethodDesc(pMD);
- pTarget = lpVtbl[pComPlusCallInfo->m_cachedComSlot];
- }
-#endif // FEATURE_COMINTEROP
- else
- {
- UNREACHABLE_MSG("Unexpected MethodDesc kind encountered in PInvokeStubForHostWorker");
- }
-
- // We ask the host on every call. This is different from x86 but we keep this
- // behavior for maximum compatibility with previous releases.
- if (CallNeedsHostHook((size_t)pTarget))
- {
- // call LeaveRuntime
- class LeaveRuntimeHolderThrowComplus
- {
- public:
- LeaveRuntimeHolderThrowComplus(size_t target)
- {
- Thread::LeaveRuntimeThrowComplus(target);
- }
- ~LeaveRuntimeHolderThrowComplus()
- {
- Thread::EnterRuntime();
- }
- } holder((size_t)pTarget);
-
- PInvokeStubForHostInner(dwStackSize, pStackFrame, pTarget);
- // ~LeaveRuntimeHolderThrowComplus calls EnterRuntime here
- }
- else
- {
- // The host doesn't want to be notified - just call the target
- PInvokeStubForHostInner(dwStackSize, pStackFrame, pTarget);
- }
-}
-#endif // _WIN64 && !FEATURE_PAL
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
void UnmanagedToManagedFrame::ExceptionUnwind()
@@ -2178,38 +1995,6 @@ void ContextTransitionFrame::GcScanRoots(promote_func *fn, ScanContext* sc)
// The dac only cares about strong references at the moment. Since this is always
// in a weak ref, we don't report it here.
-#if defined(FEATURE_REMOTING) && !defined(DACCESS_COMPILE)
- Context *returnContext = GetReturnContext();
- PREFIX_ASSUME(returnContext != NULL);
- _ASSERTE(returnContext);
- _ASSERTE(returnContext->GetDomain()); // this will make sure is a valid pointer
-
- // In the VM we operate on a local to avoid double relocation. In the dac we actually want
- // to know the real location.
-#ifdef DACCESS_COMPILE
- PTR_PTR_Object ppRef = returnContext->GetExposedObjectRawUncheckedPtr();
-
- if (*ppRef == NULL)
- return;
-
- (*fn)(ppRef, sc, 0);
-
-#else // DACCESS_COMPILE
- // We are in the middle of the GC. OBJECTREFs can't be used here since their built-in validation
- // chokes on objects that have been relocated already
- Object *pRef = returnContext->GetExposedObjectRawUnchecked();
-
- if (pRef == NULL)
- return;
-
- LOG((LF_GC, INFO3, "ContextTransitionFrame Protection Frame Promoting" FMT_ADDR "to ", DBG_ADDR(pRef) ));
- // Don't check app domains here - the objects are in the parent frame's app domain
-
- (*fn)(&pRef, sc, 0);
- LOG((LF_GC, INFO3, FMT_ADDR "\n", DBG_ADDR(pRef)));
-#endif // !DACCESS_COMPILE
-
-#endif
}
diff --git a/src/vm/frames.h b/src/vm/frames.h
index e37f980b9f..747cbd6d68 100644
--- a/src/vm/frames.h
+++ b/src/vm/frames.h
@@ -49,11 +49,6 @@
#endif // FEATURE_HIJACK
// |
// |
-#ifdef FEATURE_REMOTING
-// +-GCSafeCollectionFrame - this handles reporting for GCSafeCollections, which are
-// | generally used during appdomain transitions
-// |
-#endif // FEATURE_REMOTING
// |
// +-InlinedCallFrame - if a call to unmanaged code is hoisted into
// | a JIT'ted caller, the calling method keeps
@@ -140,13 +135,6 @@
// +-FuncEvalFrame - frame for debugger function evaluation
#endif // DEBUGGING_SUPPORTED
// |
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) && defined(_TARGET_X86_)
-// |
-// +-ReverseEnterRuntimeFrame
-// |
-// +-LeaveRuntimeFrame
-// |
-#endif
// |
// +-ExceptionFilterFrame - this frame wraps call to exception filter
// |
@@ -231,9 +219,6 @@ FRAME_TYPE_NAME(HelperMethodFrame_1OBJ)
FRAME_TYPE_NAME(HelperMethodFrame_2OBJ)
FRAME_TYPE_NAME(HelperMethodFrame_PROTECTOBJ)
FRAME_ABSTRACT_TYPE_NAME(FramedMethodFrame)
-#ifdef FEATURE_REMOTING
-FRAME_TYPE_NAME(TPMethodFrame)
-#endif
FRAME_TYPE_NAME(SecureDelegateFrame)
FRAME_TYPE_NAME(MulticastFrame)
FRAME_ABSTRACT_TYPE_NAME(UnmanagedToManagedFrame)
@@ -261,9 +246,6 @@ FRAME_TYPE_NAME(InterpreterFrame)
#endif // FEATURE_INTERPRETER
FRAME_TYPE_NAME(ProtectByRefsFrame)
FRAME_TYPE_NAME(ProtectValueClassFrame)
-#ifdef FEATURE_REMOTING
-FRAME_TYPE_NAME(GCSafeCollectionFrame)
-#endif // FEATURE_REMOTING
FRAME_TYPE_NAME(DebuggerClassInitMarkFrame)
FRAME_TYPE_NAME(DebuggerSecurityCodeMarkFrame)
FRAME_TYPE_NAME(DebuggerExitFrame)
@@ -271,10 +253,6 @@ FRAME_TYPE_NAME(DebuggerU2MCatchHandlerFrame)
#ifdef _TARGET_X86_
FRAME_TYPE_NAME(UMThkCallFrame)
#endif
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) && defined(_TARGET_X86_)
-FRAME_TYPE_NAME(ReverseEnterRuntimeFrame)
-FRAME_TYPE_NAME(LeaveRuntimeFrame)
-#endif
FRAME_TYPE_NAME(InlinedCallFrame)
FRAME_TYPE_NAME(ContextTransitionFrame)
FRAME_TYPE_NAME(TailCallFrame)
@@ -661,9 +639,6 @@ public:
TYPE_SECURITY,
TYPE_CALL,
TYPE_FUNC_EVAL,
-#ifdef FEATURE_REMOTING
- TYPE_TP_METHOD_FRAME,
-#endif
TYPE_MULTICAST,
// HMFs and derived classes should use this so the profiling API knows it needs
@@ -1758,48 +1733,6 @@ protected:
//
//
//+----------------------------------------------------------------------------
-#ifdef FEATURE_REMOTING
-class TPMethodFrame : public FramedMethodFrame
-{
- VPTR_VTABLE_CLASS(TPMethodFrame, FramedMethodFrame)
-
-public:
- TPMethodFrame(TransitionBlock * pTransitionBlock);
-
- virtual int GetFrameType()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return TYPE_TP_METHOD_FRAME;
- }
-
- // GC protect arguments
- virtual void GcScanRoots(promote_func *fn, ScanContext* sc);
-
- // Our base class is a a M2U TransitionType; but we're not. So override and set us back to None.
- ETransitionType GetTransitionType()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return TT_NONE;
- }
-
-#if defined(_TARGET_X86_) && !defined(DACCESS_COMPILE)
- void SetCbStackPop(UINT cbStackPop)
- {
- LIMITED_METHOD_CONTRACT;
- // Number of bytes to pop for x86 is stored right before the return value
- void * pReturnValue = GetReturnValuePtr();
- *(((DWORD *)pReturnValue) - 1) = cbStackPop;
- }
-#endif
-
- // Aid the debugger in finding the actual address of callee
- virtual BOOL TraceFrame(Thread *thread, BOOL fromPatch,
- TraceDestination *trace, REGDISPLAY *regs);
-
- // Keep as last entry in class
- DEFINE_VTABLE_GETTER_AND_CTOR_AND_DTOR(TPMethodFrame)
-};
-#endif // FEATURE_REMOTING
//------------------------------------------------------------------------
// This represents a call Delegate.Invoke for secure delegate
@@ -2599,28 +2532,6 @@ public:
typedef VPTR(class InterpreterFrame) PTR_InterpreterFrame;
#endif // FEATURE_INTERPRETER
-#ifdef FEATURE_REMOTING
-class GCSafeCollectionFrame : public Frame
-{
- VPTR_VTABLE_CLASS(GCSafeCollectionFrame, Frame)
- PTR_VOID m_pCollection;
-
- public:
- //--------------------------------------------------------------------
- // This constructor pushes a new GCFrame on the frame chain.
- //--------------------------------------------------------------------
-#ifndef DACCESS_COMPILE
- GCSafeCollectionFrame() { }
- GCSafeCollectionFrame(void *collection);
-#endif
-
- virtual void GcScanRoots(promote_func *fn, ScanContext* sc);
-
- VOID Pop();
- // Keep as last entry in class
- DEFINE_VTABLE_GETTER_AND_DTOR(GCSafeCollectionFrame)
-};
-#endif // FEATURE_REMOTING
//-----------------------------------------------------------------------------
@@ -2935,7 +2846,7 @@ protected:
};
#endif // _TARGET_X86_ && !FEATURE_PAL
-#if defined(_TARGET_X86_)
+#if defined(_TARGET_X86_) && defined(FEATURE_COMINTEROP)
//-------------------------------------------------------------------------
// Exception handler for COM to managed frame
// and the layout of the exception registration record structure in the stack
@@ -2955,67 +2866,8 @@ struct ComToManagedExRecord
return &m_frame;
}
};
-#endif // _TARGET_X86_
-
-#if defined(FEATURE_INCLUDE_ALL_INTERFACES) && defined(_TARGET_X86_)
-//-----------------------------------------------------------------------------
-// ReverseEnterRuntimeFrame
-//-----------------------------------------------------------------------------
-
-class ReverseEnterRuntimeFrame : public Frame
-{
- VPTR_VTABLE_CLASS(ReverseEnterRuntimeFrame, Frame)
-
-public:
- //------------------------------------------------------------------------
- // Performs cleanup on an exception unwind
- //------------------------------------------------------------------------
-#ifndef DACCESS_COMPILE
- virtual void ExceptionUnwind()
- {
- WRAPPER_NO_CONTRACT;
- GetThread()->ReverseLeaveRuntime();
- }
-#endif
-
- //---------------------------------------------------------------
- // Expose key offsets and values for stub generation.
- //---------------------------------------------------------------
-
- static UINT32 GetNegSpaceSize()
- {
- LIMITED_METHOD_CONTRACT;
- return sizeof(GSCookie);
- }
-
- // Keep as last entry in class
- DEFINE_VTABLE_GETTER_AND_CTOR_AND_DTOR(ReverseEnterRuntimeFrame)
-};
+#endif // _TARGET_X86_ && FEATURE_COMINTEROP
-//-----------------------------------------------------------------------------
-// LeaveRuntimeFrame
-//-----------------------------------------------------------------------------
-
-class LeaveRuntimeFrame : public Frame
-{
- VPTR_VTABLE_CLASS(LeaveRuntimeFrame, Frame)
-
-public:
- //------------------------------------------------------------------------
- // Performs cleanup on an exception unwind
- //------------------------------------------------------------------------
-#ifndef DACCESS_COMPILE
- virtual void ExceptionUnwind()
- {
- WRAPPER_NO_CONTRACT;
- Thread::EnterRuntime();
- }
-#endif
-
- // Keep as last entry in class
- DEFINE_VTABLE_GETTER_AND_CTOR_AND_DTOR(LeaveRuntimeFrame)
-};
-#endif
//------------------------------------------------------------------------
// This frame is pushed by any JIT'ted method that contains one or more
@@ -3203,9 +3055,6 @@ private:
PTR_Object m_LastThrownObjectInParentContext;
ULONG_PTR m_LockCount; // Number of locks the thread takes
// before the transition.
-#ifndef FEATURE_CORECLR
- ULONG_PTR m_CriticalRegionCount;
-#endif // !FEATURE_CORECLR
VPTR_VTABLE_CLASS(ContextTransitionFrame, Frame)
public:
@@ -3244,18 +3093,6 @@ public:
return (DWORD) m_LockCount;
}
-#ifndef FEATURE_CORECLR
- void SetCriticalRegionCount(DWORD criticalRegionCount)
- {
- LIMITED_METHOD_CONTRACT;
- m_CriticalRegionCount = criticalRegionCount;
- }
- DWORD GetCriticalRegionCount()
- {
- LIMITED_METHOD_CONTRACT;
- return (DWORD) m_CriticalRegionCount;
- }
-#endif // !FEATURE_CORECLR
// Let debugger know that we're transitioning between AppDomains.
ETransitionType GetTransitionType()
@@ -3270,9 +3107,6 @@ public:
, m_ReturnExecutionContext(NULL)
, m_LastThrownObjectInParentContext(NULL)
, m_LockCount(0)
-#ifndef FEATURE_CORECLR
- , m_CriticalRegionCount(0)
-#endif // !FEATURE_CORECLR
{
LIMITED_METHOD_CONTRACT;
}
diff --git a/src/vm/fusionbind.cpp b/src/vm/fusionbind.cpp
deleted file mode 100644
index 0a337796bb..0000000000
--- a/src/vm/fusionbind.cpp
+++ /dev/null
@@ -1,661 +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.
-
-/*============================================================
-**
-** Header: FusionBind.cpp
-**
-** Purpose: Implements fusion interface
-**
-**
-
-
-===========================================================*/
-
-#include "common.h"
-
-#include <stdlib.h>
-#include "fusionbind.h"
-#include "shimload.h"
-#include "eventtrace.h"
-#include "strongnameholders.h"
-
-HRESULT BaseAssemblySpec::ParseName()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- GC_NOTRIGGER;
- NOTHROW;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- if (!m_pAssemblyName)
- return S_OK;
-
- CQuickBytes ssName;
-
- hr = ssName.ConvertUtf8_UnicodeNoThrow(m_pAssemblyName);
-
- if (SUCCEEDED(hr))
- {
- NonVMComHolder<IAssemblyName> pName;
-
- IfFailRet(CreateAssemblyNameObject(&pName, (LPCWSTR) ssName.Ptr(), CANOF_PARSE_DISPLAY_NAME, NULL));
-
- if (m_ownedFlags & NAME_OWNED)
- delete [] m_pAssemblyName;
- m_pAssemblyName = NULL;
-
- hr = Init(pName);
- }
-
- return hr;
-}
-
-void BaseAssemblySpec::GetFileOrDisplayName(DWORD flags, SString &result) const
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- INJECT_FAULT(ThrowOutOfMemory());
- PRECONDITION(CheckValue(result));
- PRECONDITION(result.IsEmpty());
- }
- CONTRACTL_END;
-
- if (m_pAssemblyName != NULL) {
- NonVMComHolder<IAssemblyName> pFusionName;
- IfFailThrow(CreateFusionName(&pFusionName));
-
- FusionBind::GetAssemblyNameDisplayName(pFusionName, result, flags);
- }
- else
- result.Set(m_wszCodeBase);
-}
-
-HRESULT AssemblySpec::LoadAssembly(IApplicationContext* pFusionContext,
- FusionSink *pSink,
- IAssembly** ppIAssembly,
- IHostAssembly** ppIHostAssembly,
- IBindResult** ppNativeFusionAssembly,
- BOOL fForIntrospectionOnly,
- BOOL fSuppressSecurityChecks)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- MODE_PREEMPTIVE;
- INJECT_FAULT(ThrowOutOfMemory());
- }
- CONTRACTL_END;
-
- HRESULT hr = E_FAIL;
-
- if (!IsAfContentType_Default(m_dwFlags))
- { // Fusion can process only Default ContentType (non-WindowsRuntime)
- IfFailThrow(COR_E_BADIMAGEFORMAT);
- }
-
- NonVMComHolder<IAssembly> pIAssembly(NULL);
- NonVMComHolder<IBindResult> pNativeFusionAssembly(NULL);
- NonVMComHolder<IHostAssembly> pIHostAssembly(NULL);
- NonVMComHolder<IAssemblyName> pSpecName;
- NonVMComHolder<IAssemblyName> pCodeBaseName;
-
-
- BOOL fFXOnly = FALSE;
- DWORD size = sizeof(fFXOnly);
-
- hr = pFusionContext->Get(ACTAG_FX_ONLY, &fFXOnly, &size, 0);
- if(FAILED(hr))
- {
- /// just in case it corrupted fFXOnly
- fFXOnly = FALSE;
- }
-
- // reset hr
- hr = E_FAIL;
-
- // Make sure we don't have malformed names
-
- if (m_pAssemblyName)
- IfFailGo(FusionBind::VerifyBindingString(m_pAssemblyName));
-
- if (m_context.szLocale)
- IfFailGo(FusionBind::VerifyBindingString(m_context.szLocale));
-
- // If we have assembly name info, first bind using that
- if (m_pAssemblyName != NULL) {
- IfFailGo(CreateFusionName(&pSpecName, FALSE));
-
- if(m_fParentLoadContext == LOADCTX_TYPE_UNKNOWN)
- {
- BOOL bOptionallyRetargetable;
- IfFailGo(IsOptionallyRetargetableAssembly(pSpecName, &bOptionallyRetargetable));
- if (bOptionallyRetargetable)
- return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); // do not propagate to load, let the event handle
- }
-
- hr = FusionBind::RemoteLoad(pFusionContext, pSink,
- pSpecName, GetParentIAssembly(), NULL,
- &pIAssembly, &pIHostAssembly, &pNativeFusionAssembly, fForIntrospectionOnly, fSuppressSecurityChecks);
- }
-
-
- // Now, bind using the codebase.
- if (FAILED(hr) && !fFXOnly && m_wszCodeBase) {
- // No resolution by code base for SQL-hosted environment, except for introspection
- if((!fForIntrospectionOnly) && CorHost2::IsLoadFromBlocked())
- {
- hr = FUSION_E_LOADFROM_BLOCKED;
- goto ErrExit;
- }
- IfFailGo(CreateAssemblyNameObject(&pCodeBaseName, NULL, 0, NULL));
-
- IfFailGo(pCodeBaseName->SetProperty(ASM_NAME_CODEBASE_URL,
- (void*)m_wszCodeBase,
- (DWORD)(wcslen(m_wszCodeBase) + 1) * sizeof(WCHAR)));
-
- // Note that we cannot bind a native image using a codebase, as it will
- // always be in the LoadFrom context which does not support native images.
-
- pSink->Reset();
- hr = FusionBind::RemoteLoad(pFusionContext, pSink,
- pCodeBaseName, NULL, m_wszCodeBase,
- &pIAssembly, &pIHostAssembly, &pNativeFusionAssembly, fForIntrospectionOnly, fSuppressSecurityChecks);
-
- // If we had both name info and codebase, make sure they are consistent.
- if (SUCCEEDED(hr) && m_pAssemblyName != NULL) {
-
- NonVMComHolder<IAssemblyName> pPolicyRefName(NULL);
- if (!fForIntrospectionOnly) {
- // Get post-policy ref, because we'll be comparing
- // it against a post-policy def
- HRESULT policyHr = PreBindAssembly(pFusionContext,
- pSpecName,
- NULL, // pAsmParent
- &pPolicyRefName,
- NULL); // pvReserved
- if (FAILED(policyHr) && (policyHr != FUSION_E_REF_DEF_MISMATCH) &&
- (policyHr != E_INVALIDARG)) // partial ref
- IfFailGo(policyHr);
- }
-
- NonVMComHolder<IAssemblyName> pBoundName;
- if (pIAssembly == NULL)
- IfFailGo(pIHostAssembly->GetAssemblyNameDef(&pBoundName));
- else
- IfFailGo(pIAssembly->GetAssemblyNameDef(&pBoundName));
-
- // Order matters: Ref->IsEqual(Def)
- HRESULT equalHr;
- if (pPolicyRefName)
- equalHr = pPolicyRefName->IsEqual(pBoundName, ASM_CMPF_DEFAULT);
- else
- equalHr = pSpecName->IsEqual(pBoundName, ASM_CMPF_DEFAULT);
- if (equalHr != S_OK)
- {
- // post-policy name is pBoundName and it's not correct for the
- // original name, so we need to clear it
- ReleaseNameAfterPolicy();
- IfFailGo(FUSION_E_REF_DEF_MISMATCH);
- }
- }
- }
-
- // We should have found an assembly by now.
- IfFailGo(hr);
-
- // <NOTE> Comment about the comment below. The work is done in fusion now.
- // But we still keep the comment here to illustrate the problem. </NOTE>
-
- // Until we can create multiple Assembly objects for a single HMODULE
- // we can only store one IAssembly* per Assembly. It is very important
- // to maintain the IAssembly* for an image that is in the load-context.
- // An Assembly in the load-from-context can bind to an assembly in the
- // load-context but not visa-versa. Therefore, if we every get an IAssembly
- // from the load-from-context we must make sure that it will never be
- // found using a load. If it did then we could end up with Assembly dependencies
- // that are wrong. For example, if I do a LoadFrom() on an assembly in the GAC
- // and it requires another Assembly that I have preloaded in the load-from-context
- // then that dependency gets burnt into the Jitted code. Later on a Load() is
- // done on the assembly in the GAC and we single instance it back to the one
- // we have gotten from the load-from-context because the HMODULES are the same.
- // Now the dependency is wrong because it would not have the preloaded assembly
- // if the order was reversed.
-
-#if 0
- if (!fForIntrospectionOnly)
- {
- NonVMComHolder<IFusionLoadContext> pLoadContext;
- if (pIAssembly == NULL)
- IfFailGo(pIHostAssembly->GetFusionLoadContext(&pLoadContext));
- else
- IfFailGo(pIAssembly->GetFusionLoadContext(&pLoadContext));
-
- if (pLoadContext->GetContextType() == LOADCTX_TYPE_LOADFROM) {
- _ASSERTE(pIAssembly != NULL);
- HRESULT hrLocal;
-
- NonVMComHolder<IAssemblyName> pBoundName;
- pIAssembly->GetAssemblyNameDef(&pBoundName);
-
- // We need to copy the bound name to modify it
- IAssemblyName *pClone;
- IfFailGo(pBoundName->Clone(&pClone));
- pBoundName.Release();
- pBoundName = pClone;
-
- // Null out the architecture for the second bind
- IfFailGo(pBoundName->SetProperty(ASM_NAME_ARCHITECTURE, NULL, 0));
-
- NonVMComHolder<IAssembly> pAliasingAssembly;
- NonVMComHolder<IHostAssembly> pIHA;
- pSink->Reset();
- hrLocal = FusionBind::RemoteLoad(pFusionContext, pSink,
- pBoundName, NULL, NULL,
- &pAliasingAssembly, &pIHA, fForIntrospectionOnly);
-
- if(SUCCEEDED(hrLocal)) {
- // If the paths are the same or the loadfrom assembly is in the GAC,
- // then use the non-LoadFrom assembly as the result.
-
- DWORD location;
- hrLocal = pIAssembly->GetAssemblyLocation(&location);
- BOOL alias = (SUCCEEDED(hrLocal) && location == ASMLOC_GAC);
-
- if (!alias) {
- SString boundPath;
- GetAssemblyManifestModulePath(pIAssembly, boundPath);
-
- SString aliasingPath;
- GetAssemblyManifestModulePath(pAliasingAssembly, aliasingPath);
-
- alias = SString::_wcsicmp(boundPath, aliasingPath) == 0;
- }
-
- // Keep the default context's IAssembly if the paths are the same
- if (alias)
- pIAssembly = pAliasingAssembly.Extract();
- }
- }
- }
-#endif
-
- if (SUCCEEDED(hr)) {
- if (pIAssembly == NULL)
- *ppIHostAssembly = pIHostAssembly.Extract();
- else
- *ppIAssembly = pIAssembly.Extract();
- if (ppNativeFusionAssembly) {
- *ppNativeFusionAssembly = pNativeFusionAssembly.Extract();
- }
- }
-
- ErrExit:
- return hr;
-}
-
-
-/* static */
-HRESULT FusionBind::RemoteLoad(IApplicationContext* pFusionContext,
- FusionSink *pSink,
- IAssemblyName *pName,
- IAssembly *pParentAssembly,
- LPCWSTR pCodeBase,
- IAssembly** ppIAssembly,
- IHostAssembly** ppIHostAssembly,
- IBindResult **ppNativeFusionAssembly,
- BOOL fForIntrospectionOnly,
- BOOL fSuppressSecurityChecks)
-{
- CONTRACTL
- {
- THROWS;
- MODE_PREEMPTIVE;
- // The resulting IP must be held so the assembly will not be scavenged.
- PRECONDITION(CheckPointer(ppIAssembly));
- PRECONDITION(CheckPointer(ppIHostAssembly));
-
- PRECONDITION(CheckPointer(pName));
- INJECT_FAULT(return E_OUTOFMEMORY;);
- } CONTRACTL_END;
-
- ETWOnStartup (FusionBinding_V1, FusionBindingEnd_V1);
-
- HRESULT hr;
- ASM_BIND_FLAGS dwFlags = ASM_BINDF_NONE;
- DWORD dwReserved = 0;
- LPVOID pReserved = NULL;
-
- // Event Tracing for Windows is used to log data for performance and functional testing purposes.
- // The events below are used to help measure the performance of the download phase of assembly binding (be it download of a remote file or accessing a local file on disk),
- // as well as of lookup scenarios such as from a host store.
- DWORD dwAppDomainId = ETWAppDomainIdNotAvailable;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
- DWORD cbValue = sizeof(dwAppDomainId);
- // Gather data used by ETW events later in this function.
- if (pFusionContext == NULL || FAILED(pFusionContext->Get(ACTAG_APP_DOMAIN_ID, &dwAppDomainId, &cbValue, 0))) {
- dwAppDomainId = ETWAppDomainIdNotAvailable;
- }
- }
-
- NonVMComHolder< IUnknown > pSinkIUnknown(NULL);
- NonVMComHolder< IAssemblyNameBinder> pBinder(NULL);
- *ppNativeFusionAssembly=NULL;
-
- if(pParentAssembly != NULL) {
- // Only use a parent assembly hint when the parent assembly has a load context.
- // Assemblies in anonymous context are not dicoverable by loader's binding rules,
- // thus loader can't find their dependencies.
- // Loader will only try to locate dependencies in default load context.
- if (pParentAssembly->GetFusionLoadContext() != LOADCTX_TYPE_UNKNOWN) {
- dwReserved = sizeof(IAssembly*);
- pReserved = (LPVOID) pParentAssembly;
- dwFlags = ASM_BINDF_PARENT_ASM_HINT;
- }
- }
-
- IfFailRet(pSink->AssemblyResetEvent());
- IfFailRet(pSink->QueryInterface(IID_IUnknown, (void**)&pSinkIUnknown));
- IUnknown *pFusionAssembly=NULL;
- IUnknown *pNativeAssembly=NULL;
- BOOL fCached = TRUE;
-
-
- if (fForIntrospectionOnly)
- {
- dwFlags = (ASM_BIND_FLAGS)(dwFlags | ASM_BINDF_INSPECTION_ONLY);
- }
-
- if (fSuppressSecurityChecks)
- {
- dwFlags = (ASM_BIND_FLAGS)(dwFlags | ASM_BINDF_SUPPRESS_SECURITY_CHECKS);
- }
-
- IfFailRet(pName->QueryInterface(IID_IAssemblyNameBinder, (void **)&pBinder));
- {
- // In SQL, this can call back into the runtime
- CONTRACT_VIOLATION(ThrowsViolation);
- hr = pBinder->BindToObject(IID_IAssembly,
- pSinkIUnknown,
- pFusionContext,
- pCodeBase,
- dwFlags,
- pReserved,
- dwReserved,
- (void**) &pFusionAssembly,
- (void**)&pNativeAssembly);
- }
-
- if(hr == E_PENDING) {
- // If there is an assembly IP then we were successful.
- hr = pSink->Wait();
- if (SUCCEEDED(hr))
- hr = pSink->LastResult();
- if(SUCCEEDED(hr)) {
- if(pSink->m_punk) {
- if (pSink->m_pNIunk)
- pNativeAssembly=pSink->m_pNIunk;
- pFusionAssembly = pSink->m_punk;
- fCached = FALSE;
- }
- else
- hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
- }
-
- FireEtwBindingDownloadPhaseEnd(dwAppDomainId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, pCodeBase, NULL, GetClrInstanceId());
-
- FireEtwBindingLookupAndProbingPhaseEnd(dwAppDomainId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, pCodeBase, NULL, GetClrInstanceId());
-
- if (SUCCEEDED(hr)) {
- // Keep a handle to ensure it does not disappear from the cache
- // and allow access to modules associated with the assembly.
- hr = pFusionAssembly->QueryInterface(IID_IAssembly,
- (void**) ppIAssembly);
- if (hr == E_NOINTERFACE) // IStream assembly
- hr = pFusionAssembly->QueryInterface(IID_IHostAssembly,
- (void**) ppIHostAssembly);
- if (SUCCEEDED(hr) && pNativeAssembly)
- hr=pNativeAssembly->QueryInterface(IID_IBindResult,
- (void**)ppNativeFusionAssembly);
-
- if (fCached)
- {
- pFusionAssembly->Release();
- if(pNativeAssembly)
- pNativeAssembly->Release();
- }
- }
-
- return hr;
-}
-
-/* static */
-HRESULT FusionBind::RemoteLoadModule(IApplicationContext * pFusionContext,
- IAssemblyModuleImport* pModule,
- FusionSink *pSink,
- IAssemblyModuleImport** pResult)
-{
-
- CONTRACTL
- {
- NOTHROW;
- PRECONDITION(CheckPointer(pFusionContext));
- PRECONDITION(CheckPointer(pModule));
- PRECONDITION(CheckPointer(pSink));
- PRECONDITION(CheckPointer(pResult));
- INJECT_FAULT(return E_OUTOFMEMORY;);
- } CONTRACTL_END;
-
- ETWOnStartup (FusionBinding_V1, FusionBindingEnd_V1);
-
- HRESULT hr;
- IfFailGo(pSink->AssemblyResetEvent());
- hr = pModule->BindToObject(pSink,
- pFusionContext,
- ASM_BINDF_NONE,
- (void**) pResult);
- if(hr == E_PENDING) {
- // If there is an assembly IP then we were successful.
- hr = pSink->Wait();
- if (SUCCEEDED(hr))
- hr = pSink->LastResult();
- if (SUCCEEDED(hr)) {
- if(pSink->m_punk)
- hr = pSink->m_punk->QueryInterface(IID_IAssemblyModuleImport,
- (void**) pResult);
- else
- hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
- }
- }
-
- ErrExit:
- return hr;
-}
-
-
-/* static */
-HRESULT FusionBind::AddEnvironmentProperty(__in LPCWSTR variable,
- __in LPCWSTR pProperty,
- IApplicationContext* pFusionContext)
-{
- CONTRACTL
- {
- NOTHROW;
- PRECONDITION(CheckPointer(pProperty));
- PRECONDITION(CheckPointer(variable));
- PRECONDITION(CheckPointer(pFusionContext));
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END;
-
- DWORD size = _MAX_PATH;
- WCHAR rcValue[_MAX_PATH]; // Buffer for the directory.
- WCHAR *pValue = &(rcValue[0]);
- size = WszGetEnvironmentVariable(variable, pValue, size);
- if(size > _MAX_PATH) {
- pValue = (WCHAR*) _alloca(size * sizeof(WCHAR));
- size = WszGetEnvironmentVariable(variable, pValue, size);
- size++; // Add in the null terminator
- }
-
- if(size)
- return pFusionContext->Set(pProperty,
- pValue,
- size * sizeof(WCHAR),
- 0);
- else
- return S_FALSE; // no variable found
-}
-
-// Fusion uses a context class to drive resolution of assemblies.
-// Each application has properties that can be pushed into the
-// fusion context (see fusionp.h). The public api is part of
-// application domains.
-/* static */
-HRESULT FusionBind::SetupFusionContext(LPCWSTR szAppBase,
- LPCWSTR szPrivateBin,
- IApplicationContext** ppFusionContext)
-{
- CONTRACTL
- {
- NOTHROW;
- PRECONDITION(CheckPointer(ppFusionContext));
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END;
-
- HRESULT hr;
- NonVMComHolder <IApplicationContext> pFusionContext;
-
- LPCWSTR pBase;
- // if the appbase is null then use the current directory
- if (szAppBase == NULL) {
- pBase = (LPCWSTR) _alloca(_MAX_PATH * sizeof(WCHAR));
- if(!WszGetCurrentDirectory(_MAX_PATH, (LPWSTR) pBase))
- IfFailGo(HRESULT_FROM_GetLastError());
- }
- else
- pBase = szAppBase;
-
-
- IfFailGo(CreateFusionContext(pBase, &pFusionContext));
-
-
- IfFailGo((pFusionContext)->Set(ACTAG_APP_BASE_URL,
- (void*) pBase,
- (DWORD)(wcslen(pBase) + 1) * sizeof(WCHAR),
- 0));
-
- if (szPrivateBin)
- IfFailGo((pFusionContext)->Set(ACTAG_APP_PRIVATE_BINPATH,
- (void*) szPrivateBin,
- (DWORD)(wcslen(szPrivateBin) + 1) * sizeof(WCHAR),
- 0));
- else
- IfFailGo(AddEnvironmentProperty(APPENV_RELATIVEPATH, ACTAG_APP_PRIVATE_BINPATH, pFusionContext));
-
- *ppFusionContext=pFusionContext;
- pFusionContext.SuppressRelease();
-
-ErrExit:
- return hr;
-}
-
-/* static */
-HRESULT FusionBind::CreateFusionContext(LPCWSTR pzName, IApplicationContext** ppFusionContext)
-{
- CONTRACTL
- {
- NOTHROW;
- PRECONDITION(CheckPointer(ppFusionContext));
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END;
-
- // This is a file name not a namespace
- LPCWSTR contextName = NULL;
-
- if(pzName) {
- contextName = wcsrchr( pzName, W('\\') );
- if(contextName)
- contextName++;
- else
- contextName = pzName;
- }
- // We go off and create a fusion context for this application domain.
- // Note, once it is made it can not be modified.
- NonVMComHolder<IAssemblyName> pFusionAssemblyName;
- HRESULT hr = CreateAssemblyNameObject(&pFusionAssemblyName, contextName, 0, NULL);
-
- if(SUCCEEDED(hr))
- hr = CreateApplicationContext(pFusionAssemblyName, ppFusionContext);
-
- return hr;
-}
-
-/* static */
-HRESULT FusionBind::GetVersion(__out_ecount(*pdwVersion) LPWSTR pVersion, __inout DWORD* pdwVersion)
-{
- CONTRACTL
- {
- NOTHROW;
- PRECONDITION(CheckPointer(pdwVersion));
- PRECONDITION(pdwVersion>0 && CheckPointer(pVersion));
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END;
-
- DWORD dwCORSystem = 0;
-
- LPCWSTR pCORSystem = GetInternalSystemDirectory(&dwCORSystem);
-
- if (dwCORSystem == 0)
- return E_FAIL;
-
- dwCORSystem--; // remove the null character
- if (dwCORSystem && pCORSystem[dwCORSystem-1] == W('\\'))
- dwCORSystem--; // and the trailing slash if it exists
-
- if (dwCORSystem==0)
- return E_FAIL;
-
- const WCHAR* pSeparator;
- const WCHAR* pTail = pCORSystem + dwCORSystem;
-
- for (pSeparator = pCORSystem+dwCORSystem-1; pSeparator > pCORSystem && *pSeparator != W('\\');pSeparator--);
-
- if (*pSeparator == W('\\'))
- pSeparator++;
-
- DWORD lgth = (DWORD)(pTail - pSeparator);
-
- if (lgth > *pdwVersion) {
- *pdwVersion = lgth+1;
- return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
- }
-
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:26000) // "Disable PREFast/espX warning about buffer overflow"
-#endif
- while(pSeparator < pTail)
- *pVersion++ = *pSeparator++;
-
- *pVersion = W('\0');
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
- return S_OK;
-} // FusionBind::GetVersion
-
diff --git a/src/vm/fusioninit.cpp b/src/vm/fusioninit.cpp
deleted file mode 100644
index eb4cba6ee4..0000000000
--- a/src/vm/fusioninit.cpp
+++ /dev/null
@@ -1,624 +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 "common.h"
-
-#include "clrhost.h"
-#include "helpers.h"
-#include "dbglog.h"
-#include "adl.h"
-#include "cacheutils.h"
-#include "installlogger.h"
-#include "actasm.h"
-#include "naming.h"
-#include "policy.h"
-#include "bindhelpers.h"
-#ifdef FEATURE_COMINTEROP
-#include "appxutil.h"
-#endif
-
-#include "msi.h"
-
-STDAPI InitializeNativeBinder();
-
-#define DEVOVERRIDE_PATH W(".local\\")
-#define REG_KEY_IMAGE_FILE_EXECUTION_OPTIONS W("Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options")
-#define REG_VAL_DEVOVERRIDE_PATH W("DevOverridePath")
-#define REG_VAL_DEVOVERRIDE_ENABLE W("DevOverrideEnable")
-#define REG_VAL_FUSION_FORCE_UNIFICATION W("OnlyUseLatestCLR")
-#define REG_VAL_USE_LEGACY_IDENTITY_FORMAT W("UseLegacyIdentityFormat")
-#define REG_VAL_ENABLE_MSI_IN_LOCAL_GAC W("FusionEnableMSIInLocalGac")
-#define REG_VAL_ENABLE_FORCED_FULL_CLOSURE_WALK W("FusionEnableForcedFullClosureWalk")
-
-// Registry / Environment variable
-#define BINDING_CONFIGURATION W("BindingConfiguration")
-
-extern HMODULE g_pMSCorEE;
-extern BOOL g_bRunningOnNT6OrHigher;
-
-WCHAR g_szWindowsDir[MAX_LONGPATH+1];
-WCHAR g_FusionDllPath[MAX_LONGPATH+1];
-HINSTANCE g_hInst = NULL;
-HMODULE g_hMSCorEE = NULL;
-DWORD g_dwLogInMemory;
-DWORD g_dwLogLevel;
-DWORD g_dwForceLog;
-DWORD g_dwLogFailures;
-DWORD g_dwLogResourceBinds;
-BOOL g_bBinderLoggingNeeded;
-DWORD g_dwDevOverrideEnable;
-WORD g_wProcessorArchitecture; // Default to 32 bit
-BOOL g_fWow64Process; // Wow64 Process
-PEKIND g_peKindProcess;
-List<CAssemblyDownload *> *g_pDownloadList;
-BOOL g_bLogToWininet;
-WCHAR g_wzCustomLogPath[MAX_LONGPATH];
-DWORD g_dwConfigForceUnification;
-DWORD g_dwFileInUseRetryAttempts;
-DWORD g_dwFileInUseMillisecondsBetweenRetries;
-DWORD g_dwUseLegacyIdentityFormat;
-DWORD g_dwConfigEnableMSIInLocalGac = 0;
-DWORD g_dwConfigEnableForcedFullClosureWalk = 0;
-
-CRITSEC_COOKIE g_csInitClb;
-CRITSEC_COOKIE g_csConfigSettings;
-CRITSEC_COOKIE g_csSingleUse;
-CRITSEC_COOKIE g_csDownload;
-CRITSEC_COOKIE g_csBindLog;
-
-// Defined in peimage.cpp
-extern LCID g_lcid;
-
-IIdentityAuthority *g_pIdentityAuthority;
-CIdentityCache *g_pIdentityCache;
-
-WCHAR g_wzEXEPath[MAX_LONGPATH+1];
-
-
-#ifdef _DEBUG
-BOOL g_bTagAssemblyNames;
-#endif //_DEBUG
-
-extern int SetOsFlag(void) ;
-
-// MSI
-DWORD g_dwDisableMSIPeek;
-typedef HRESULT (*pfnMsiProvideAssemblyW)(LPCWSTR wzAssemblyName, LPCWSTR szAppContext,
- DWORD dwInstallMode, DWORD dwUnused,
- LPWSTR lpPathBuf, DWORD *pcchPathBuf);
-typedef INSTALLUILEVEL (*pfnMsiSetInternalUI)(INSTALLUILEVEL dwUILevel, HWND *phWnd);
-typedef UINT (*pfnMsiInstallProductW)(LPCWSTR wzPackagePath, LPCWSTR wzCmdLine);
-
-pfnMsiProvideAssemblyW g_pfnMsiProvideAssemblyW;
-pfnMsiSetInternalUI g_pfnMsiSetInternalUI;
-pfnMsiInstallProductW g_pfnMsiInstallProductW;
-BOOL g_bCheckedMSIPresent;
-HMODULE g_hModMSI;
-
-WCHAR g_wzLocalDevOverridePath[MAX_LONGPATH + 1];
-WCHAR g_wzGlobalDevOverridePath[MAX_LONGPATH + 1];
-DWORD g_dwDevOverrideFlags;
-
-HRESULT GetScavengerQuotasFromReg(DWORD *pdwZapQuotaInGAC,
- DWORD *pdwDownloadQuotaAdmin,
- DWORD *pdwDownloadQuotaUser);
-
-HRESULT SetupDevOverride(LPCWSTR pwzBindingConfigDevOverridePath);
-
-static DWORD GetConfigDWORD(HKEY hkey, LPCWSTR wzName, DWORD dwDefault)
-{
- LIMITED_METHOD_CONTRACT;
- DWORD lResult;
- DWORD dwSize;
- DWORD dwType = REG_DWORD;
- DWORD dwValue;
-
- if (hkey == 0) {
- return dwDefault;
- }
-
- dwSize = sizeof(DWORD);
- lResult = WszRegQueryValueEx(hkey, wzName, NULL,
- &dwType, (LPBYTE)&dwValue, &dwSize);
- if (lResult != ERROR_SUCCESS || dwType != REG_DWORD) {
- return dwDefault;
- }
-
- return dwValue;
-}
-
-BOOL InitFusionCriticalSections()
-{
- WRAPPER_NO_CONTRACT;
- BOOL fRet = FALSE;
-
- g_csInitClb = ClrCreateCriticalSection(CrstFusionClb, CRST_REENTRANCY);
- if (!g_csInitClb) {
- goto Exit;
- }
-
- g_csDownload = ClrCreateCriticalSection(CrstFusionDownload, CRST_REENTRANCY);
- if (!g_csDownload) {
- goto Exit;
- }
-
- g_csBindLog = ClrCreateCriticalSection(CrstFusionLog, CRST_DEFAULT);
- if (!g_csBindLog) {
- goto Exit;
- }
-
- g_csSingleUse = ClrCreateCriticalSection(CrstFusionSingleUse, CRST_DEFAULT);
- if (!g_csSingleUse) {
- goto Exit;
- }
-
- // <TODO> Get rid of this critical section</TODO>
- g_csConfigSettings = ClrCreateCriticalSection(CrstFusionConfigSettings, CRST_DEFAULT);
- if (!g_csConfigSettings) {
- goto Exit;
- }
-
- fRet = TRUE;
-
-Exit:
- return fRet;
-}
-
-// ensure that the symbol will be exported properly
-extern "C" HRESULT STDMETHODCALLTYPE InitializeFusion();
-
-HRESULT STDMETHODCALLTYPE InitializeFusion()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- static BOOL bInitialized = FALSE;
- LPWSTR pwzBindingConfigAssemblyStorePath = NULL;
- LPWSTR pwzBindingConfigDevOverridePath = NULL;
- ReleaseHolder<CNodeFactory> pNodeFact;
- DWORD dwSize = 0;
- BOOL fExecutableIsKnown = FALSE;
- LPWSTR pwzFileName = NULL;
- WCHAR wzBindingConfigPath[MAX_LONGPATH + 1];
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
-
- if (bInitialized) {
- hr = S_OK;
- goto Exit;
- }
-
- g_hInst = g_pMSCorEE;
-
- SetOsFlag();
-
- g_lcid = MAKELCID(LOCALE_INVARIANT, SORT_DEFAULT);
-
- WszGetModuleFileName(g_hInst, g_FusionDllPath, MAX_LONGPATH);
-
- if (!InitFusionCriticalSections()) {
- hr = E_OUTOFMEMORY;
- goto Exit;
- }
-
- g_wProcessorArchitecture = g_SystemInfo.wProcessorArchitecture;
-
- g_fWow64Process = RunningInWow64();
-
- if (IsProcess32()) {
- g_peKindProcess = (g_wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL)?peI386:peARM;
- }
- else {
- g_peKindProcess = (g_wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64)?peIA64:peAMD64;
- }
-
- if (!g_pIdentityAuthority) {
- IIdentityAuthority *pAuth = NULL;
-
- hr = GetIdentityAuthority(&pAuth);
- if (FAILED(hr)) {
- goto Exit;
- }
-
- if (InterlockedCompareExchangeT(&g_pIdentityAuthority, pAuth, NULL) != NULL) {
- SAFE_RELEASE(pAuth);
- }
- }
-
- if (!g_pIdentityCache) {
- CIdentityCache *pIdentityCache;
-
- hr = CIdentityCache::Create(&pIdentityCache);
- if (FAILED(hr)) {
- goto Exit;
- }
-
- if (InterlockedCompareExchangeT(&g_pIdentityCache, pIdentityCache, NULL) != NULL) {
- SAFEDELETE(pIdentityCache);
- }
- }
-
- DWORD lResult;
- HKEY hKey;
-
- lResult = FusionRegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_KEY_FUSION_SETTINGS, 0, KEY_READ, &hKey);
- if (lResult != ERROR_SUCCESS) {
- hKey = 0;
- }
-
-#define _GetConfigDWORD(name, default) GetConfigDWORD(hKey, name, default)
-
- // Get this executable's filename
- fExecutableIsKnown = WszGetModuleFileName(NULL, g_wzEXEPath, MAX_LONGPATH);
- if(!fExecutableIsKnown) {
- hr = StringCbCopy(g_wzEXEPath, sizeof(g_wzEXEPath), W("Unknown"));
- if (FAILED(hr)) {
- goto Exit;
- }
- }
-
- if (g_bRunningOnNT6OrHigher) {
- //
- // BINDINGCONFIGURATION
- //
- // Obtain the path to an override xml file via the registry for
- // this executable or from the environment variable
- //
- wzBindingConfigPath[0] = W('\0');
-
- // If there is a BindingConfiguration entry for this
- // executable, then read it
- pwzFileName = PathFindFileName(g_wzEXEPath);
- if(fExecutableIsKnown && pwzFileName) {
- WCHAR wzValue[MAX_LONGPATH + 1];
- HKEY hKeyExeName = NULL;
- DWORD dwType = REG_SZ;
-
- wzValue[0] = W('\0');
-
- // key name + '\' + filename + null
- if(lstrlenW(REG_KEY_IMAGE_FILE_EXECUTION_OPTIONS) + 1 + lstrlenW(pwzFileName) + 1 > MAX_PATH_FNAME) {
- hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
- goto Exit;
- }
-
- hr = StringCchPrintf(wzValue, MAX_PATH_FNAME, W("%ws\\%ws"),
- REG_KEY_IMAGE_FILE_EXECUTION_OPTIONS, pwzFileName);
- if (FAILED(hr)) {
- goto Exit;
- }
-
- lResult = FusionRegOpenKeyEx(HKEY_LOCAL_MACHINE, wzValue, 0, KEY_READ, &hKeyExeName);
- if(lResult != ERROR_SUCCESS) {
- if(lResult != ERROR_FILE_NOT_FOUND) {
- hr = HRESULT_FROM_WIN32(lResult);
- goto Exit;
- }
- }
- else { // Success
- dwSize = MAX_LONGPATH * sizeof(WCHAR);
- wzValue[0] = W('\0');
-
- lResult = WszRegQueryValueEx(hKeyExeName, BINDING_CONFIGURATION, NULL, &dwType, (LPBYTE)wzValue, &dwSize);
- RegCloseKey(hKeyExeName);
- if(lResult != ERROR_SUCCESS) {
- if(lResult != ERROR_FILE_NOT_FOUND) {
- hr = HRESULT_FROM_WIN32(lResult);
- goto Exit;
- }
- }
- else { // Success
- if(dwType != REG_SZ) {
- hr = HRESULT_FROM_WIN32(ERROR_BADKEY);
- goto Exit;
- }
-
- if(wzValue[0]) {
- hr = StringCbCopy(wzBindingConfigPath, sizeof(wzBindingConfigPath), wzValue);
- if (FAILED(hr)) {
- goto Exit;
- }
- }
- }
- }
- }
-
- // If we didn't get a path from the registry,
- // try the ENV variable.
- if(!wzBindingConfigPath[0]) {
- dwSize = WszGetEnvironmentVariable(BINDING_CONFIGURATION, wzBindingConfigPath, MAX_LONGPATH);
- if(dwSize > MAX_LONGPATH) {
- hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
- goto Exit;
- }
- }
-
- // We have a path to XML config override file
- if(wzBindingConfigPath[0]) {
- hr = ParseXML(&pNodeFact, wzBindingConfigPath, NULL, FALSE);
- if (FAILED(hr)) {
- goto Exit;
- }
-
- // Get AssemblyStore override path
- hr = pNodeFact->GetAssemblyStorePath(&pwzBindingConfigAssemblyStorePath);
- if(FAILED(hr)) {
- goto Exit;
- }
-
- // Get DevOverride path
- hr = pNodeFact->GetDevOverridePath(&pwzBindingConfigDevOverridePath);
- if(FAILED(hr)) {
- goto Exit;
- }
- }
- }
-
- //
- // end BindingConfiguration
- //
-
- hr = SetRootCachePath(pwzBindingConfigAssemblyStorePath);
- if(FAILED(hr)) {
- goto Exit;
- }
-
- GetScavengerQuotasFromReg(NULL, NULL, NULL);
-
-#ifdef _DEBUG
- g_bTagAssemblyNames = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TagAssemblyNames);
-#endif //_DEBUG
-
- // Machine level logging settings
- g_dwLogInMemory = _GetConfigDWORD(REG_VAL_FUSION_LOG_ENABLE, 0);
- g_dwLogLevel = _GetConfigDWORD(REG_VAL_FUSION_LOG_LEVEL, 1);
- g_dwForceLog = _GetConfigDWORD(REG_VAL_FUSION_LOG_FORCE, 0);
- g_dwLogFailures = _GetConfigDWORD(REG_VAL_FUSION_LOG_FAILURES, 0);
- g_dwLogResourceBinds = _GetConfigDWORD(REG_VAL_FUSION_LOG_RESOURCE_BINDS, 0);
-
- BOOL fusionMessagesAreEnabled = ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, FusionMessageEvent);
- g_bBinderLoggingNeeded = !!(fusionMessagesAreEnabled || g_dwLogFailures || g_dwForceLog || g_dwLogResourceBinds || g_dwLogInMemory);
-
- g_dwConfigForceUnification = REGUTIL::GetConfigDWORD_DontUse_(REG_VAL_FUSION_FORCE_UNIFICATION, 0);
-
- // Settings to indicate how many times to retry opening a hard-locked file for reading, moving/renaming or deletion.
- // Used to configure CreateFileWithRetries and MoveFileWithRetries in fusion\Utils\Helpers.cpp
- // These are used mainly for GAC Installation where anti-virus and indexing programs can temporarily hard-lock files.
- // g_dwFileInUseRetryAttempts does not include the first attempt to open the file (hence set it to 0 to prevent retries).
- g_dwFileInUseRetryAttempts = _GetConfigDWORD(REG_VAL_FUSION_FILE_IN_USE_RETRY_ATTEMPTS, FILE_IN_USE_RETRY_ATTEMPTS);
- if (g_dwFileInUseRetryAttempts > MAX_FILE_IN_USE_RETRY_ATTEMPTS)
- g_dwFileInUseRetryAttempts = MAX_FILE_IN_USE_RETRY_ATTEMPTS;
- g_dwFileInUseMillisecondsBetweenRetries = _GetConfigDWORD(REG_VAL_FUSION_FILE_IN_USE_MILLISECONDS_BETWEEN_RETRIES, FILE_IN_USE_MILLISECONDS_BETWEEN_RETRIES);
- if (g_dwFileInUseMillisecondsBetweenRetries > MAX_FILE_IN_USE_MILLISECONDS_BETWEEN_RETRIES)
- g_dwFileInUseMillisecondsBetweenRetries = MAX_FILE_IN_USE_MILLISECONDS_BETWEEN_RETRIES;
-
- // This setting is only relevant in the unsupported case where we're running out of a local GAC
- // g_bUseDefaultStore is initialized in SetRootCachePath above
- if (!g_bUseDefaultStore)
- {
- g_dwConfigEnableMSIInLocalGac = REGUTIL::GetConfigDWORD_DontUse_(REG_VAL_ENABLE_MSI_IN_LOCAL_GAC, 0);
- }
- g_dwConfigEnableForcedFullClosureWalk = REGUTIL::GetConfigDWORD_DontUse_(REG_VAL_ENABLE_FORCED_FULL_CLOSURE_WALK, 0);
-
- g_dwUseLegacyIdentityFormat = AppX::IsAppXProcess() || _GetConfigDWORD(REG_VAL_USE_LEGACY_IDENTITY_FORMAT, 0);
- g_dwDisableMSIPeek = _GetConfigDWORD(W("DisableMSIPeek"), FALSE);
- g_dwDisableMSIPeek |= CLRConfig::GetConfigValue(CLRConfig::INTERNAL_DisableMSIPeek);
-
- if (hKey) {
- RegCloseKey(hKey);
- hKey = NULL;
- }
-
- {
- WCHAR wzBuf[1];
-
- wzBuf[0] = W('\0');
- dwSize = WszGetEnvironmentVariable(W("USE_LEGACY_IDENTITY_FORMAT"), wzBuf, 1);
- if (dwSize == 1 && !FusionCompareString(wzBuf, W("1"))) {
- g_dwUseLegacyIdentityFormat = 1;
- }
- }
-
- if (IsLoggingNeeded()) {
- g_bLogToWininet = TRUE;
- dwSize = MAX_LONGPATH;
- DWORD dwAttr;
- BOOL fExists;
- g_wzCustomLogPath[0] = W('\0');
- GetCustomLogPath(g_wzCustomLogPath, &dwSize);
- if (g_wzCustomLogPath[0] != W('\0')) {
- if(SUCCEEDED(CheckFileExistence(g_wzCustomLogPath, &fExists, &dwAttr)) &&
- fExists && (dwAttr & FILE_ATTRIBUTE_DIRECTORY)) {
- g_bLogToWininet = FALSE;
- }
- }
- }
-
- // make devoverride longhorn+ only
- if (g_bRunningOnNT6OrHigher) {
- hr = SetupDevOverride(pwzBindingConfigDevOverridePath);
- if (FAILED(hr)) {
- goto Exit;
- }
- }
-
- g_pDownloadList = new (nothrow) List<CAssemblyDownload *>;
- if (!g_pDownloadList) {
- hr = E_OUTOFMEMORY;
- goto Exit;
- }
-
- g_pAssemblyFingerprintCache = new (nothrow) CAssemblyFingerprintCache;
- if (!g_pAssemblyFingerprintCache) {
- hr = E_OUTOFMEMORY;
- goto Exit;
- }
-
- hr = g_pAssemblyFingerprintCache->Init();
- if (FAILED(hr))
- {
- goto Exit;
- }
-
- bInitialized = TRUE;
-
- hr = InitializeNativeBinder();
- if (FAILED(hr))
- {
- goto Exit;
- }
-
-Exit:
- SAFEDELETEARRAY(pwzBindingConfigAssemblyStorePath);
- SAFEDELETEARRAY(pwzBindingConfigDevOverridePath);
-
- END_SO_INTOLERANT_CODE;
-
- return hr;
-}
-
-HRESULT SetupDevOverride(LPCWSTR pwzBindingConfigDevOverridePath)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // g_wzLocalDevOverridePath[0] = W('\0');
- // g_wzGlobalDevOverridePath[0] = W('\0');
- g_dwDevOverrideFlags = 0;
-
- DWORD dwFileAttr;
- DWORD dwType;
- DWORD dwSize;
- LONG lResult = 0;
- HKEY hKey = 0;
-
- lResult = FusionRegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_KEY_IMAGE_FILE_EXECUTION_OPTIONS, 0, KEY_READ, &hKey);
- if (lResult != ERROR_SUCCESS) {
- hr = S_FALSE;
- goto Exit;
- }
-
- g_dwDevOverrideEnable = _GetConfigDWORD(REG_VAL_DEVOVERRIDE_ENABLE, 0);
-
- if (g_dwDevOverrideEnable != 0) {
-
- // Check local dev path
- if (!WszGetModuleFileName(NULL, g_wzLocalDevOverridePath, MAX_LONGPATH)) {
- hr = HRESULT_FROM_GetLastError();
- goto Exit;
- }
-
- if (lstrlenW(g_wzLocalDevOverridePath) + lstrlenW(DEVOVERRIDE_PATH) <= MAX_LONGPATH) {
- // Only process .devoverride if the total path length <= MAX_LONGPATH
-
- hr = StringCbCat(g_wzLocalDevOverridePath, sizeof(g_wzLocalDevOverridePath), DEVOVERRIDE_PATH);
- if (FAILED(hr)) {
- goto Exit;
- }
-
- dwFileAttr = WszGetFileAttributes(g_wzLocalDevOverridePath);
- if ((dwFileAttr != INVALID_FILE_ATTRIBUTES) && (dwFileAttr & FILE_ATTRIBUTE_DIRECTORY)) {
- g_dwDevOverrideFlags |= DEVOVERRIDE_LOCAL;
- }
- else {
- // Clear the path just for goodness sake
- g_wzLocalDevOverridePath[0] = W('\0');
- }
- }
-
- // Check global dev path
- dwSize = sizeof(g_wzGlobalDevOverridePath);
-
- lResult = WszRegQueryValueEx(hKey, REG_VAL_DEVOVERRIDE_PATH, NULL, &dwType, (LPBYTE)g_wzGlobalDevOverridePath, &dwSize);
- if (lResult == ERROR_SUCCESS && lstrlenW(g_wzGlobalDevOverridePath) && dwType == REG_SZ) {
-
- dwFileAttr = WszGetFileAttributes(g_wzGlobalDevOverridePath);
- if ((dwFileAttr != INVALID_FILE_ATTRIBUTES) && (dwFileAttr & FILE_ATTRIBUTE_DIRECTORY)) {
- g_dwDevOverrideFlags |= DEVOVERRIDE_GLOBAL;
- }
- else {
- // Clear the path just for goodness sake
- g_wzGlobalDevOverridePath[0] = W('\0');
- }
- }
-
- // BINDING_CONFIGURATION Env check
- if(pwzBindingConfigDevOverridePath && pwzBindingConfigDevOverridePath[0]) {
- WCHAR wzTempPath[MAX_LONGPATH + 1];
- BOOL fExists = FALSE;
- WIN32_FILE_ATTRIBUTE_DATA fileInfo;
-
- wzTempPath[0] = W('\0');
-
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:25025)
-#endif
- // usage of PathCanonicalize is safe if we ensure that
- // length of buffer specified by parameter1 is >= length of buffer specified by parameter2
- if(lstrlenW(pwzBindingConfigDevOverridePath) + 1 > COUNTOF(wzTempPath)) {
- hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
- goto Exit;
- }
-
- if(!PathCanonicalize(wzTempPath, pwzBindingConfigDevOverridePath)) {
- hr = E_FAIL;
- goto Exit;
- }
-
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
- if(!WszGetFileAttributesEx(wzTempPath, GetFileExInfoStandard, &fileInfo)) {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto Exit;
- }
-
- if(!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
- hr = HRESULT_FROM_WIN32(ERROR_FILE_EXISTS);
- goto Exit;
- }
-
- hr = StringCbCopy(g_wzGlobalDevOverridePath, sizeof(g_wzGlobalDevOverridePath), wzTempPath);
- if (FAILED(hr)) {
- goto Exit;
- }
-
- g_dwDevOverrideFlags |= DEVOVERRIDE_GLOBAL;
- }
-
- if(g_dwDevOverrideFlags & DEVOVERRIDE_GLOBAL) {
- PathAddBackslashWrap(g_wzGlobalDevOverridePath, MAX_LONGPATH);
- }
- }
-
-Exit:
-
- if (hKey) {
- RegCloseKey(hKey);
- }
-
- return hr;
-}
-
diff --git a/src/vm/fusionsink.cpp b/src/vm/fusionsink.cpp
deleted file mode 100644
index b40192b68a..0000000000
--- a/src/vm/fusionsink.cpp
+++ /dev/null
@@ -1,215 +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.
-
-/*============================================================
-**
-** Header: FusionSink.cpp
-**
-** Purpose: Implements FusionSink, event objects that block
-** the current thread waiting for an asynchronous load
-** of an assembly to succeed.
-**
-**
-
-
-===========================================================*/
-
-#include "common.h"
-
-#include <stdlib.h>
-#include "fusionsink.h"
-#include "ex.h"
-
-STDMETHODIMP FusionSink::QueryInterface(REFIID riid, void** ppv)
-{
- CONTRACTL
- {
- MODE_ANY;
- GC_NOTRIGGER;
- NOTHROW;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *ppv = NULL;
-
- if (riid == IID_IUnknown)
- *ppv = (IUnknown*) (IAssemblyBindSink*) this;
- else if (riid == IID_IAssemblyBindSink)
- *ppv = (IAssemblyBindSink*)this;
- else if (riid == IID_INativeImageEvaluate)
- *ppv = (INativeImageEvaluate*)this;
- if (*ppv == NULL)
- hr = E_NOINTERFACE;
- else
- AddRef();
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-STDMETHODIMP FusionSink::OnProgress(DWORD dwNotification,
- HRESULT hrNotification,
- LPCWSTR szNotification,
- DWORD dwProgress,
- DWORD dwProgressMax,
- LPVOID pvBindInfo,
- IUnknown* punk)
-{
- LIMITED_METHOD_CONTRACT;
- HRESULT hr = S_OK;
- switch(dwNotification) {
- case ASM_NOTIFICATION_DONE:
- m_LastResult = hrNotification;
- if(m_pAbortUnk) {
- m_pAbortUnk->Release();
- m_pAbortUnk = NULL;
- }
-
- if(punk && SUCCEEDED(hrNotification))
- hr = punk->QueryInterface(IID_IUnknown, (void**) &m_punk);
- m_hEvent->Set();
- break;
- case ASM_NOTIFICATION_NATIVE_IMAGE_DONE:
- if(punk && SUCCEEDED(hrNotification))
- hr = punk->QueryInterface(IID_IUnknown, (void**) &m_pNIunk);
- break;
-
- case ASM_NOTIFICATION_START:
- if(punk)
- hr = punk->QueryInterface(IID_IUnknown, (void**) &m_pAbortUnk);
- break;
-
- case ASM_NOTIFICATION_ATTEMPT_NEXT_CODEBASE:
- break;
-
- case ASM_NOTIFICATION_BIND_INFO:
- FusionBindInfo *pBindInfo;
-
- pBindInfo = (FusionBindInfo *)pvBindInfo;
-
- if (pBindInfo && m_pFusionLog == NULL) {
- m_pFusionLog = pBindInfo->pdbglog;
- if (m_pFusionLog) {
- m_pFusionLog->AddRef();
- }
- }
- break;
- default:
- break;
- }
-
- return hr;
-}
-
-ULONG FusionSink::AddRef()
-{
- LIMITED_METHOD_CONTRACT;
- ULONG cRefCount = 0;
- //BEGIN_ENTRYPOINT_VOIDRET;
-
- cRefCount = (InterlockedIncrement(&m_cRef));
- //END_ENTRYPOINT_VOIDRET;
- return cRefCount;
-}
-
-ULONG FusionSink::Release()
-{
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_ENTRY_POINT;
- BEGIN_CLEANUP_ENTRYPOINT;
-
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (!cRef) {
- Reset();
- delete this;
- }
- END_CLEANUP_ENTRYPOINT;
- return (cRef);
-}
-
-HRESULT FusionSink::AssemblyResetEvent()
-{
- WRAPPER_NO_CONTRACT;
- HRESULT hr = AssemblyCreateEvent();
- if(FAILED(hr)) return hr;
-
- if(!m_hEvent->Reset()) {
- hr = HRESULT_FROM_GetLastErrorNA();
- }
-
- return hr;
-}
-
-HRESULT FusionSink::AssemblyCreateEvent()
-{
- STATIC_CONTRACT_NOTHROW;
- HRESULT hr = S_OK;
- if(m_hEvent == NULL) {
- // Initialize the event to require manual reset
- // and to initially signaled.
- EX_TRY {
- m_hEvent = new Event();
- m_hEvent->CreateManualEvent(TRUE);
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
- }
- return hr;
-}
-
-HRESULT FusionSink::Wait()
-{
- STATIC_CONTRACT_NOTHROW;
-
-#if CHECK_INVARIANTS
- _ASSERTE(CheckPointer(this));
- _ASSERTE(CheckPointer(m_hEvent));
-#endif // CHECK_INVARIANTS
-
- HRESULT hr = S_OK;
- DWORD dwReturn = 0;
-
- // CLREvent::Wait will switch mode if needed;
-
- // Waiting for a signal from fusion - which we are guaranteed to get.
- // We do a WaitForMultipleObjects (STA and MTA) and pump messages in the STA case
- // in the call so we shouldn't freeze the system.
- EX_TRY
- {
- dwReturn = m_hEvent->Wait(INFINITE,TRUE);
- }
- EX_CATCH
- {
- // Fusion uses us via COM interface so we need to swallow exceptions
- hr = GET_EXCEPTION()->GetHR();
-
- //@todo: is it right thing to do to swallow exceptions here
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- return hr;
-}
-
-HRESULT FusionSink::Evaluate (
- IAssembly *pILAssembly,
- IAssembly *pNativeAssembly,
- BYTE * pbCachedData,
- DWORD dwDataSize
- )
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_ENTRY_POINT;
-
- return S_OK;
-}
-
diff --git a/src/vm/gccover.cpp b/src/vm/gccover.cpp
index 02bb0de5e0..3e195796b4 100644
--- a/src/vm/gccover.cpp
+++ b/src/vm/gccover.cpp
@@ -1759,7 +1759,10 @@ void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
// Do the actual stress work
//
- if (!GCHeapUtilities::GetGCHeap()->StressHeap())
+ // BUG(github #10318) - when not using allocation contexts, the alloc lock
+ // must be acquired here. Until fixed, this assert prevents random heap corruption.
+ assert(GCHeapUtilities::UseThreadAllocationContexts());
+ if (!GCHeapUtilities::GetGCHeap()->StressHeap(GetThread()->GetAllocContext()))
UpdateGCStressInstructionWithoutGC ();
// Must flush instruction cache before returning as instruction has been modified.
diff --git a/src/vm/gcenv.ee.cpp b/src/vm/gcenv.ee.cpp
index 61d06421ad..54c7991ee9 100644
--- a/src/vm/gcenv.ee.cpp
+++ b/src/vm/gcenv.ee.cpp
@@ -29,6 +29,15 @@
#include "comcallablewrapper.h"
#endif // FEATURE_COMINTEROP
+// the method table for the WeakReference class
+extern MethodTable* pWeakReferenceMT;
+
+// The canonical method table for WeakReference<T>
+extern MethodTable* pWeakReferenceOfTCanonMT;
+
+// Finalizes a weak reference directly.
+extern void FinalizeWeakReference(Object* obj);
+
void GCToEEInterface::SuspendEE(SUSPEND_REASON reason)
{
WRAPPER_NO_CONTRACT;
@@ -626,6 +635,11 @@ void GCToEEInterface::GcStartWork (int condemned, int max_gen)
//
RCWWalker::OnGCStarted(condemned);
#endif // FEATURE_COMINTEROP
+
+ if (condemned == max_gen)
+ {
+ ThreadStore::s_pThreadStore->OnMaxGenerationGCStarted();
+ }
}
void GCToEEInterface::GcDone(int condemned)
@@ -725,10 +739,17 @@ void GCToEEInterface::GcEnumAllocContexts(enum_alloc_context_func* fn, void* par
}
CONTRACTL_END;
- Thread * pThread = NULL;
- while ((pThread = ThreadStore::GetThreadList(pThread)) != NULL)
+ if (GCHeapUtilities::UseThreadAllocationContexts())
{
- fn(pThread->GetAllocContext(), param);
+ Thread * pThread = NULL;
+ while ((pThread = ThreadStore::GetThreadList(pThread)) != NULL)
+ {
+ fn(pThread->GetAllocContext(), param);
+ }
+ }
+ else
+ {
+ fn(&g_global_alloc_context, param);
}
}
@@ -759,7 +780,7 @@ struct BackgroundThreadStubArgs
bool hasStarted;
};
-DWORD BackgroundThreadStub(void* arg)
+DWORD WINAPI BackgroundThreadStub(void* arg)
{
BackgroundThreadStubArgs* stubArgs = (BackgroundThreadStubArgs*)arg;
assert (stubArgs->thread != NULL);
@@ -878,7 +899,9 @@ void ProfScanRootsHelper(Object** ppObject, ScanContext *pSC, uint32_t dwFlags)
Object *pObj = *ppObject;
if (dwFlags & GC_CALL_INTERIOR)
{
- pObj = GCHeapUtilities::GetGCHeap()->GetContainingObject(pObj);
+ pObj = GCHeapUtilities::GetGCHeap()->GetContainingObject(pObj, true);
+ if (pObj == nullptr)
+ return;
}
ScanRootsHelper(pObj, ppObject, pSC, dwFlags);
#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
@@ -941,7 +964,7 @@ void GcScanRootsForProfilerAndETW(promote_func* fn, int condemned, int max_gen,
}
}
-void ScanHandleForProfilerAndETW(Object** pRef, Object* pSec, uint32_t flags, ScanContext* context, BOOL isDependent)
+void ScanHandleForProfilerAndETW(Object** pRef, Object* pSec, uint32_t flags, ScanContext* context, bool isDependent)
{
ProfilingScanContext* pSC = (ProfilingScanContext*)context;
@@ -1002,6 +1025,7 @@ void GCProfileWalkHeapWorker(BOOL fProfilerPinned, BOOL fShouldWalkHeapRootsForE
{
{
ProfilingScanContext SC(fProfilerPinned);
+ unsigned max_generation = GCHeapUtilities::GetGCHeap()->GetMaxGeneration();
// **** Scan roots: Only scan roots if profiling API wants them or ETW wants them.
if (fProfilerPinned || fShouldWalkHeapRootsForEtw)
@@ -1054,7 +1078,7 @@ void GCProfileWalkHeapWorker(BOOL fProfilerPinned, BOOL fShouldWalkHeapRootsForE
// **** Walk objects on heap: only if profiling API wants them or ETW wants them.
if (fProfilerPinned || fShouldWalkHeapObjectsForEtw)
{
- GCHeapUtilities::GetGCHeap()->DiagWalkHeap(&HeapWalkHelper, &profilerWalkHeapContext, max_generation, TRUE /* walk the large object heap */);
+ GCHeapUtilities::GetGCHeap()->DiagWalkHeap(&HeapWalkHelper, &profilerWalkHeapContext, max_generation, true /* walk the large object heap */);
}
#ifdef FEATURE_EVENT_TRACE
@@ -1104,7 +1128,7 @@ void GCProfileWalkHeap()
#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
}
-void WalkFReachableObjects(BOOL isCritical, void* objectID)
+void WalkFReachableObjects(bool isCritical, void* objectID)
{
g_profControlBlock.pProfInterface->FinalizeableObjectQueued(isCritical, (ObjectID)objectID);
}
@@ -1122,7 +1146,7 @@ void GCToEEInterface::DiagGCStart(int gen, bool isInduced)
// When we're walking objects allocated by class, then we don't want to walk the large
// object heap because then it would count things that may have been around for a while.
- GCHeapUtilities::GetGCHeap()->DiagWalkHeap(&AllocByClassHelper, (void *)&context, 0, FALSE);
+ GCHeapUtilities::GetGCHeap()->DiagWalkHeap(&AllocByClassHelper, (void *)&context, 0, false);
// Notify that we've reached the end of the Gen 0 scan
g_profControlBlock.pProfInterface->EndAllocByClass(&context);
@@ -1169,13 +1193,13 @@ void GCToEEInterface::DiagWalkFReachableObjects(void* gcContext)
// don't get confused.
void WalkMovedReferences(uint8_t* begin, uint8_t* end,
ptrdiff_t reloc,
- size_t context,
- BOOL fCompacting,
- BOOL fBGC)
+ void* context,
+ bool fCompacting,
+ bool fBGC)
{
ETW::GCLog::MovedReference(begin, end,
(fCompacting ? reloc : 0),
- context,
+ (size_t)context,
fCompacting,
!fBGC);
}
@@ -1187,7 +1211,7 @@ void GCToEEInterface::DiagWalkSurvivors(void* gcContext)
{
size_t context = 0;
ETW::GCLog::BeginMovedReferences(&context);
- GCHeapUtilities::GetGCHeap()->DiagWalkSurvivorsWithType(gcContext, &WalkMovedReferences, context, walk_for_gc);
+ GCHeapUtilities::GetGCHeap()->DiagWalkSurvivorsWithType(gcContext, &WalkMovedReferences, (void*)context, walk_for_gc);
ETW::GCLog::EndMovedReferences(context);
}
#endif //GC_PROFILING || FEATURE_EVENT_TRACE
@@ -1200,7 +1224,7 @@ void GCToEEInterface::DiagWalkLOHSurvivors(void* gcContext)
{
size_t context = 0;
ETW::GCLog::BeginMovedReferences(&context);
- GCHeapUtilities::GetGCHeap()->DiagWalkSurvivorsWithType(gcContext, &WalkMovedReferences, context, walk_for_loh);
+ GCHeapUtilities::GetGCHeap()->DiagWalkSurvivorsWithType(gcContext, &WalkMovedReferences, (void*)context, walk_for_loh);
ETW::GCLog::EndMovedReferences(context);
}
#endif //GC_PROFILING || FEATURE_EVENT_TRACE
@@ -1213,7 +1237,7 @@ void GCToEEInterface::DiagWalkBGCSurvivors(void* gcContext)
{
size_t context = 0;
ETW::GCLog::BeginMovedReferences(&context);
- GCHeapUtilities::GetGCHeap()->DiagWalkSurvivorsWithType(gcContext, &WalkMovedReferences, context, walk_for_bgc);
+ GCHeapUtilities::GetGCHeap()->DiagWalkSurvivorsWithType(gcContext, &WalkMovedReferences, (void*)context, walk_for_bgc);
ETW::GCLog::EndMovedReferences(context);
}
#endif //GC_PROFILING || FEATURE_EVENT_TRACE
@@ -1230,7 +1254,14 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
assert(args->card_table != nullptr);
assert(args->lowest_address != nullptr);
assert(args->highest_address != nullptr);
+
g_card_table = args->card_table;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ assert(args->card_bundle_table != nullptr);
+ g_card_bundle_table = args->card_bundle_table;
+#endif
+
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
if (args->write_watch_table != nullptr)
{
@@ -1274,7 +1305,14 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
assert(!args->requires_upper_bounds_check && "the ephemeral generation must be at the top of the heap!");
g_card_table = args->card_table;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ assert(g_card_bundle_table == nullptr);
+ g_card_bundle_table = args->card_bundle_table;
+#endif
+
FlushProcessWriteBuffers();
+
g_lowest_address = args->lowest_address;
VolatileStore(&g_highest_address, args->highest_address);
::StompWriteBarrierResize(true, false);
@@ -1316,3 +1354,49 @@ void GCToEEInterface::EnableFinalization(bool foundFinalizers)
FinalizerThread::EnableFinalization();
}
}
+
+void GCToEEInterface::HandleFatalError(unsigned int exitCode)
+{
+ EEPOLICY_HANDLE_FATAL_ERROR(exitCode);
+}
+
+bool GCToEEInterface::ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj)
+{
+ // CoreCLR does not have appdomains, so this code path is dead. Other runtimes may
+ // choose to inspect the object being finalized here.
+ // [DESKTOP TODO] Desktop looks for "agile and finalizable" objects and may choose
+ // to move them to a new app domain instead of finalizing them here.
+ return true;
+}
+
+bool GCToEEInterface::ForceFullGCToBeBlocking()
+{
+ // In theory, there is nothing fundamental that requires an AppDomain unload to induce
+ // a blocking GC. In the past, this workaround was done to fix an Stress AV, but the root
+ // cause of the AV was never discovered and this workaround remains in place.
+ //
+ // It would be nice if this were not necessary. However, it's not clear if the aformentioned
+ // stress bug is still lurking and will return if this workaround is removed. We should
+ // do some experiments: remove this workaround and see if the stress bug still repros.
+ // If so, we should find the root cause instead of relying on this.
+ return !!SystemDomain::System()->RequireAppDomainCleanup();
+}
+
+bool GCToEEInterface::EagerFinalized(Object* obj)
+{
+ MethodTable* pMT = obj->GetGCSafeMethodTable();
+ if (pMT == pWeakReferenceMT ||
+ pMT->GetCanonicalMethodTable() == pWeakReferenceOfTCanonMT)
+ {
+ FinalizeWeakReference(obj);
+ return true;
+ }
+
+ return false;
+}
+
+MethodTable* GCToEEInterface::GetFreeObjectMethodTable()
+{
+ assert(g_pFreeObjectMethodTable != nullptr);
+ return g_pFreeObjectMethodTable;
+}
diff --git a/src/vm/gcenv.ee.h b/src/vm/gcenv.ee.h
index 9aa3e59e36..9f7df14d22 100644
--- a/src/vm/gcenv.ee.h
+++ b/src/vm/gcenv.ee.h
@@ -44,8 +44,13 @@ public:
void StompWriteBarrier(WriteBarrierParameters* args);
void EnableFinalization(bool foundFinalizers);
+ void HandleFatalError(unsigned int exitCode);
+ bool ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj);
+ bool ForceFullGCToBeBlocking();
+ bool EagerFinalized(Object* obj);
+ MethodTable* GetFreeObjectMethodTable();
};
#endif // FEATURE_STANDALONE_GC
-#endif // _GCENV_EE_H_ \ No newline at end of file
+#endif // _GCENV_EE_H_
diff --git a/src/vm/gcenv.h b/src/vm/gcenv.h
index 2e23b270b5..865eb288e2 100644
--- a/src/vm/gcenv.h
+++ b/src/vm/gcenv.h
@@ -35,14 +35,7 @@
#include "runtimecallablewrapper.h"
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
-
-#ifdef FEATURE_UEF_CHAINMANAGER
-// This is required to register our UEF callback with the UEF chain manager
-#include <mscoruefwrapper.h>
-#endif // FEATURE_UEF_CHAINMANAGER
+
#define GCMemoryStatus MEMORYSTATUSEX
diff --git a/src/vm/gcenv.os.cpp b/src/vm/gcenv.os.cpp
index 52789b835c..6c08558e03 100644
--- a/src/vm/gcenv.os.cpp
+++ b/src/vm/gcenv.os.cpp
@@ -360,13 +360,13 @@ size_t GCToOSInterface::GetVirtualMemoryLimit()
}
+static size_t g_RestrictedPhysicalMemoryLimit = (size_t)MAX_PTR;
+
#ifndef FEATURE_PAL
typedef BOOL (WINAPI *PGET_PROCESS_MEMORY_INFO)(HANDLE handle, PROCESS_MEMORY_COUNTERS* memCounters, uint32_t cb);
static PGET_PROCESS_MEMORY_INFO GCGetProcessMemoryInfo = 0;
-static size_t g_RestrictedPhysicalMemoryLimit = (size_t)MAX_PTR;
-
typedef BOOL (WINAPI *PIS_PROCESS_IN_JOB)(HANDLE processHandle, HANDLE jobHandle, BOOL* result);
typedef BOOL (WINAPI *PQUERY_INFORMATION_JOB_OBJECT)(HANDLE jobHandle, JOBOBJECTINFOCLASS jobObjectInfoClass, void* lpJobObjectInfo, DWORD cbJobObjectInfoLength, LPDWORD lpReturnLength);
@@ -380,11 +380,7 @@ static size_t GetRestrictedPhysicalMemoryLimit()
size_t job_physical_memory_limit = (size_t)MAX_PTR;
BOOL in_job_p = FALSE;
-#ifdef FEATURE_CORECLR
HINSTANCE hinstKernel32 = 0;
-#else
- HINSTANCE hinstPsapi = 0;
-#endif
PIS_PROCESS_IN_JOB GCIsProcessInJob = 0;
PQUERY_INFORMATION_JOB_OBJECT GCQueryInformationJobObject = 0;
@@ -396,21 +392,11 @@ static size_t GetRestrictedPhysicalMemoryLimit()
if (in_job_p)
{
-#ifdef FEATURE_CORECLR
hinstKernel32 = WszLoadLibrary(L"kernel32.dll");
if (!hinstKernel32)
goto exit;
GCGetProcessMemoryInfo = (PGET_PROCESS_MEMORY_INFO)GetProcAddress(hinstKernel32, "K32GetProcessMemoryInfo");
-#else
- // We need a way to get the working set in a job object and GetProcessMemoryInfo
- // is the way to get that. According to MSDN, we should use GetProcessMemoryInfo In order to
- // compensate for the incompatibility that psapi.dll introduced we are getting this dynamically.
- hinstPsapi = WszLoadLibrary(L"psapi.dll");
- if (!hinstPsapi)
- return 0;
- GCGetProcessMemoryInfo = (PGET_PROCESS_MEMORY_INFO)GetProcAddress(hinstPsapi, "GetProcessMemoryInfo");
-#endif
if (!GCGetProcessMemoryInfo)
goto exit;
@@ -462,17 +448,28 @@ exit:
{
job_physical_memory_limit = 0;
-#ifdef FEATURE_CORECLR
FreeLibrary(hinstKernel32);
-#else
- FreeLibrary(hinstPsapi);
-#endif
}
VolatileStore(&g_RestrictedPhysicalMemoryLimit, job_physical_memory_limit);
return g_RestrictedPhysicalMemoryLimit;
}
+#else
+
+static size_t GetRestrictedPhysicalMemoryLimit()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ // The limit was cached already
+ if (g_RestrictedPhysicalMemoryLimit != (size_t)MAX_PTR)
+ return g_RestrictedPhysicalMemoryLimit;
+
+ size_t memory_limit = PAL_GetRestrictedPhysicalMemoryLimit();
+
+ VolatileStore(&g_RestrictedPhysicalMemoryLimit, memory_limit);
+ return g_RestrictedPhysicalMemoryLimit;
+}
#endif // FEATURE_PAL
@@ -483,11 +480,9 @@ uint64_t GCToOSInterface::GetPhysicalMemoryLimit()
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_PAL
size_t restricted_limit = GetRestrictedPhysicalMemoryLimit();
if (restricted_limit != 0)
return restricted_limit;
-#endif
MEMORYSTATUSEX memStatus;
::GetProcessMemoryLoad(&memStatus);
@@ -507,17 +502,29 @@ void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_PAL
uint64_t restricted_limit = GetRestrictedPhysicalMemoryLimit();
if (restricted_limit != 0)
{
+ size_t workingSetSize;
+ BOOL status = FALSE;
+#ifndef FEATURE_PAL
PROCESS_MEMORY_COUNTERS pmc;
- if (GCGetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)))
+ status = GCGetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
+ workingSetSize = pmc.WorkingSetSize;
+#else
+ status = PAL_GetWorkingSetSize(&workingSetSize);
+#endif
+ if(status)
{
if (memory_load)
- *memory_load = (uint32_t)((float)pmc.WorkingSetSize * 100.0 / (float)restricted_limit);
+ *memory_load = (uint32_t)((float)workingSetSize * 100.0 / (float)restricted_limit);
if (available_physical)
- *available_physical = restricted_limit - pmc.WorkingSetSize;
+ {
+ if(workingSetSize > restricted_limit)
+ *available_physical = 0;
+ else
+ *available_physical = restricted_limit - workingSetSize;
+ }
// Available page file doesn't mean much when physical memory is restricted since
// we don't know how much of it is available to this process so we are not going to
// bother to make another OS call for it.
@@ -527,7 +534,6 @@ void GCToOSInterface::GetMemoryStatus(uint32_t* memory_load, uint64_t* available
return;
}
}
-#endif
MEMORYSTATUSEX ms;
::GetProcessMemoryLoad(&ms);
@@ -594,7 +600,7 @@ struct GCThreadStubParam
};
// GC thread stub to convert GC thread function to an OS specific thread function
-static DWORD __stdcall GCThreadStub(void* param)
+static DWORD WINAPI GCThreadStub(void* param)
{
WRAPPER_NO_CONTRACT;
diff --git a/src/vm/gchandletableutilities.h b/src/vm/gchandletableutilities.h
new file mode 100644
index 0000000000..6e32add8ac
--- /dev/null
+++ b/src/vm/gchandletableutilities.h
@@ -0,0 +1,354 @@
+// 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.
+
+#ifndef _GCHANDLETABLEUTILITIES_H_
+#define _GCHANDLETABLEUTILITIES_H_
+
+#include "gcinterface.h"
+
+#ifdef FEATURE_COMINTEROP
+#include <weakreference.h>
+#endif
+
+extern "C" IGCHandleTable* g_pGCHandleTable;
+
+class GCHandleTableUtilities
+{
+public:
+ // Retrieves the GC handle table.
+ static IGCHandleTable* GetGCHandleTable()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ assert(g_pGCHandleTable != nullptr);
+ return g_pGCHandleTable;
+ }
+
+private:
+ // This class should never be instantiated.
+ GCHandleTableUtilities() = delete;
+};
+
+void ValidateHandleAndAppDomain(OBJECTHANDLE handle);
+
+// Given a handle, returns an OBJECTREF for the object it refers to.
+inline OBJECTREF ObjectFromHandle(OBJECTHANDLE handle)
+{
+ _ASSERTE(handle);
+
+#ifdef _DEBUG_IMPL
+ ValidateHandleAndAppDomain(handle);
+#endif // _DEBUG_IMPL
+
+ // Wrap the raw OBJECTREF and return it
+ return UNCHECKED_OBJECTREF_TO_OBJECTREF(*PTR_UNCHECKED_OBJECTREF(handle));
+}
+
+// Quick inline check for whether a handle is null
+inline BOOL IsHandleNullUnchecked(OBJECTHANDLE handle)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ return (handle == NULL || (*(_UNCHECKED_OBJECTREF *)handle) == NULL);
+}
+
+inline BOOL ObjectHandleIsNull(OBJECTHANDLE handle)
+{
+ LIMITED_METHOD_CONTRACT;
+
+ return *(Object **)handle == NULL;
+}
+
+#ifndef DACCESS_COMPILE
+
+// Handle creation convenience functions
+
+inline OBJECTHANDLE CreateHandle(void* table, OBJECTREF object)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_DEFAULT);
+}
+
+inline OBJECTHANDLE CreateWeakHandle(void* table, OBJECTREF object)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_WEAK_DEFAULT);
+}
+
+inline OBJECTHANDLE CreateShortWeakHandle(void* table, OBJECTREF object)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_WEAK_SHORT);
+}
+
+inline OBJECTHANDLE CreateLongWeakHandle(void* table, OBJECTREF object)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_WEAK_LONG);
+}
+
+inline OBJECTHANDLE CreateStrongHandle(void* table, OBJECTREF object)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_STRONG);
+}
+
+inline OBJECTHANDLE CreatePinningHandle(void* table, OBJECTREF object)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_PINNED);
+}
+
+inline OBJECTHANDLE CreateAsyncPinningHandle(void* table, OBJECTREF object)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_ASYNCPINNED);
+}
+
+inline OBJECTHANDLE CreateRefcountedHandle(void* table, OBJECTREF object)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_REFCOUNTED);
+}
+
+inline OBJECTHANDLE CreateSizedRefHandle(void* table, OBJECTREF object)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_SIZEDREF);
+}
+
+inline OBJECTHANDLE CreateSizedRefHandle(void* table, OBJECTREF object, int heapToAffinitizeTo)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_SIZEDREF, heapToAffinitizeTo);
+}
+
+// Global handle creation convenience functions
+
+inline OBJECTHANDLE CreateGlobalHandle(OBJECTREF object)
+{
+ CONDITIONAL_CONTRACT_VIOLATION(ModeViolation, object == NULL);
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateGlobalHandleOfType(OBJECTREFToObject(object), HNDTYPE_DEFAULT);
+}
+
+inline OBJECTHANDLE CreateGlobalWeakHandle(OBJECTREF object)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateGlobalHandleOfType(OBJECTREFToObject(object), HNDTYPE_WEAK_DEFAULT);
+}
+
+inline OBJECTHANDLE CreateGlobalShortWeakHandle(OBJECTREF object)
+{
+ CONDITIONAL_CONTRACT_VIOLATION(ModeViolation, object == NULL);
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateGlobalHandleOfType(OBJECTREFToObject(object), HNDTYPE_WEAK_SHORT);
+}
+
+inline OBJECTHANDLE CreateGlobalLongWeakHandle(OBJECTREF object)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateGlobalHandleOfType(OBJECTREFToObject(object), HNDTYPE_WEAK_LONG);
+}
+
+inline OBJECTHANDLE CreateGlobalStrongHandle(OBJECTREF object)
+{
+ CONDITIONAL_CONTRACT_VIOLATION(ModeViolation, object == NULL);
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateGlobalHandleOfType(OBJECTREFToObject(object), HNDTYPE_STRONG);
+}
+
+inline OBJECTHANDLE CreateGlobalPinningHandle(OBJECTREF object)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateGlobalHandleOfType(OBJECTREFToObject(object), HNDTYPE_PINNED);
+}
+
+inline OBJECTHANDLE CreateGlobalRefcountedHandle(OBJECTREF object)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateGlobalHandleOfType(OBJECTREFToObject(object), HNDTYPE_REFCOUNTED);
+}
+
+// Special handle creation convenience functions
+
+#ifdef FEATURE_COMINTEROP
+inline OBJECTHANDLE CreateWinRTWeakHandle(void* table, OBJECTREF object, IWeakReference* pWinRTWeakReference)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleWithExtraInfo(table,
+ OBJECTREFToObject(object),
+ HNDTYPE_WEAK_WINRT,
+ (void*)pWinRTWeakReference);
+}
+#endif // FEATURE_COMINTEROP
+
+// Creates a variable-strength handle
+inline OBJECTHANDLE CreateVariableHandle(void* table, OBJECTREF object, uint32_t type)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleWithExtraInfo(table,
+ OBJECTREFToObject(object),
+ HNDTYPE_VARIABLE,
+ (void*)((uintptr_t)type));
+}
+
+// Handle destruction convenience functions
+
+inline void DestroyHandle(OBJECTHANDLE handle)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ CAN_TAKE_LOCK;
+ SO_TOLERANT;
+ }
+ CONTRACTL_END;
+
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_DEFAULT);
+}
+
+inline void DestroyWeakHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_WEAK_DEFAULT);
+}
+
+inline void DestroyShortWeakHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_WEAK_SHORT);
+}
+
+inline void DestroyLongWeakHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_WEAK_LONG);
+}
+
+inline void DestroyStrongHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_STRONG);
+}
+
+inline void DestroyPinningHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_PINNED);
+}
+
+inline void DestroyAsyncPinningHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_ASYNCPINNED);
+}
+
+inline void DestroyRefcountedHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_REFCOUNTED);
+}
+
+inline void DestroyDependentHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_DEPENDENT);
+}
+
+inline void DestroyVariableHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_VARIABLE);
+}
+
+inline void DestroyGlobalHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_DEFAULT);
+}
+
+inline void DestroyGlobalWeakHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_WEAK_DEFAULT);
+}
+
+inline void DestroyGlobalShortWeakHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_WEAK_SHORT);
+}
+
+inline void DestroyGlobalLongWeakHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_WEAK_LONG);
+}
+
+inline void DestroyGlobalStrongHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_STRONG);
+}
+
+inline void DestroyGlobalPinningHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_PINNED);
+}
+
+inline void DestroyGlobalRefcountedHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_REFCOUNTED);
+}
+
+inline void DestroyTypedHandle(OBJECTHANDLE handle)
+{
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfUnknownType(handle);
+}
+
+#ifdef FEATURE_COMINTEROP
+inline void DestroyWinRTWeakHandle(OBJECTHANDLE handle)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ CAN_TAKE_LOCK;
+ SO_TOLERANT;
+ }
+ CONTRACTL_END;
+
+ // Release the WinRT weak reference if we have one. We're assuming that this will not reenter the
+ // runtime, since if we are pointing at a managed object, we should not be using HNDTYPE_WEAK_WINRT
+ // but rather HNDTYPE_WEAK_SHORT or HNDTYPE_WEAK_LONG.
+ void* pExtraInfo = GCHandleTableUtilities::GetGCHandleTable()->GetExtraInfoFromHandle(handle);
+ IWeakReference* pWinRTWeakReference = reinterpret_cast<IWeakReference*>(pExtraInfo);
+ if (pWinRTWeakReference != nullptr)
+ {
+ pWinRTWeakReference->Release();
+ }
+
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_WEAK_WINRT);
+}
+#endif
+
+// Handle holders/wrappers
+
+#ifndef FEATURE_REDHAWK
+typedef Wrapper<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroyHandle> OHWrapper;
+typedef Wrapper<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroyPinningHandle, NULL> PinningHandleHolder;
+typedef Wrapper<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroyAsyncPinningHandle, NULL> AsyncPinningHandleHolder;
+typedef Wrapper<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroyRefcountedHandle> RefCountedOHWrapper;
+
+typedef Holder<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroyLongWeakHandle> LongWeakHandleHolder;
+typedef Holder<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroyGlobalStrongHandle> GlobalStrongHandleHolder;
+typedef Holder<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroyGlobalShortWeakHandle> GlobalShortWeakHandleHolder;
+
+class RCOBJECTHANDLEHolder : public RefCountedOHWrapper
+{
+public:
+ FORCEINLINE RCOBJECTHANDLEHolder(OBJECTHANDLE p = NULL) : RefCountedOHWrapper(p)
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+ FORCEINLINE void operator=(OBJECTHANDLE p)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ RefCountedOHWrapper::operator=(p);
+ }
+};
+
+class OBJECTHANDLEHolder : public OHWrapper
+{
+public:
+ FORCEINLINE OBJECTHANDLEHolder(OBJECTHANDLE p = NULL) : OHWrapper(p)
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+ FORCEINLINE void operator=(OBJECTHANDLE p)
+ {
+ WRAPPER_NO_CONTRACT;
+
+ OHWrapper::operator=(p);
+ }
+};
+
+#endif // !FEATURE_REDHAWK
+
+#endif // !DACCESS_COMPILE
+
+#endif // _GCHANDLETABLEUTILITIES_H_
+
diff --git a/src/vm/gcheaputilities.cpp b/src/vm/gcheaputilities.cpp
index 91f259d275..e15558335e 100644
--- a/src/vm/gcheaputilities.cpp
+++ b/src/vm/gcheaputilities.cpp
@@ -4,6 +4,8 @@
#include "common.h"
#include "gcheaputilities.h"
+#include "appdomain.hpp"
+
// These globals are variables used within the GC and maintained
// by the EE for use in write barriers. It is the responsibility
@@ -12,15 +14,61 @@
GPTR_IMPL_INIT(uint32_t, g_card_table, nullptr);
GPTR_IMPL_INIT(uint8_t, g_lowest_address, nullptr);
GPTR_IMPL_INIT(uint8_t, g_highest_address, nullptr);
+GVAL_IMPL_INIT(GCHeapType, g_heap_type, GC_HEAP_INVALID);
uint8_t* g_ephemeral_low = (uint8_t*)1;
uint8_t* g_ephemeral_high = (uint8_t*)~0;
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+uint32_t* g_card_bundle_table = nullptr;
+#endif
+
// This is the global GC heap, maintained by the VM.
GPTR_IMPL(IGCHeap, g_pGCHeap);
+IGCHandleTable* g_pGCHandleTable = nullptr;
+
+GcDacVars g_gc_dac_vars;
+GPTR_IMPL(GcDacVars, g_gcDacGlobals);
+
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
uint8_t* g_sw_ww_table = nullptr;
bool g_sw_ww_enabled_for_gc_heap = false;
-#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP \ No newline at end of file
+#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
+
+gc_alloc_context g_global_alloc_context = {};
+
+// Debug-only validation for handle.
+void ValidateHandleAndAppDomain(OBJECTHANDLE handle)
+{
+#ifdef _DEBUG_IMPL
+ OBJECTREF objRef = ObjectToOBJECTREF(*(Object**)handle);
+ VALIDATEOBJECTREF(objRef);
+
+ IGCHandleTable *pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
+
+ DWORD context = (DWORD)pHandleTable->GetHandleContext(handle);
+
+ ADIndex appDomainIndex = ADIndex(context);
+ AppDomain *domain = SystemDomain::GetAppDomainAtIndex(appDomainIndex);
+
+ // Access to a handle in an unloaded domain is not allowed
+ assert(domain != nullptr);
+ assert(!domain->NoAccessToHandleTable());
+
+#if CHECK_APP_DOMAIN_LEAKS
+ if (g_pConfig->AppDomainLeaks() && objRef != NULL)
+ {
+ if (appDomainIndex.m_dwIndex)
+ {
+ objRef->TryAssignAppDomain(domain);
+ }
+ else
+ {
+ objRef->TrySetAppDomainAgile();
+ }
+ }
+#endif // CHECK_APP_DOMAIN_LEAKS
+#endif // _DEBUG_IMPL
+}
diff --git a/src/vm/gcheaputilities.h b/src/vm/gcheaputilities.h
index e76a21173c..e4812ce8c0 100644
--- a/src/vm/gcheaputilities.h
+++ b/src/vm/gcheaputilities.h
@@ -16,10 +16,18 @@ extern "C" {
GPTR_DECL(uint8_t,g_lowest_address);
GPTR_DECL(uint8_t,g_highest_address);
GPTR_DECL(uint32_t,g_card_table);
+GVAL_DECL(GCHeapType, g_heap_type);
#ifndef DACCESS_COMPILE
}
#endif // !DACCESS_COMPILE
+// For single-proc machines, the EE will use a single, shared alloc context
+// for all allocations. In order to avoid extra indirections in assembly
+// allocation helpers, the EE owns the global allocation context and the
+// GC will update it when it needs to.
+extern "C" gc_alloc_context g_global_alloc_context;
+
+extern "C" uint32_t* g_card_bundle_table;
extern "C" uint8_t* g_ephemeral_low;
extern "C" uint8_t* g_ephemeral_high;
@@ -34,6 +42,21 @@ extern "C" bool g_sw_ww_enabled_for_gc_heap;
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
+// g_gc_dac_vars is a structure of pointers to GC globals that the
+// DAC uses. It is not exposed directly to the DAC.
+extern GcDacVars g_gc_dac_vars;
+
+// Instead of exposing g_gc_dac_vars to the DAC, a pointer to it
+// is exposed here (g_gcDacGlobals). The reason for this is to avoid
+// a problem in which a debugger attaches to a program while the program
+// is in the middle of initializing the GC DAC vars - if the "publishing"
+// of DAC vars isn't atomic, the debugger could see a partially initialized
+// GcDacVars structure.
+//
+// Instead, the debuggee "publishes" GcDacVars by assigning a pointer to g_gc_dac_vars
+// to this global, and the DAC will read this global.
+typedef DPTR(GcDacVars) PTR_GcDacVars;
+GPTR_DECL(GcDacVars, g_gcDacGlobals);
// GCHeapUtilities provides a number of static methods
// that operate on the global heap instance. It can't be
@@ -59,7 +82,7 @@ public:
// Returns true if a the heap is initialized and a garbage collection
// is in progress, false otherwise.
- inline static BOOL IsGCInProgress(BOOL bConsiderGCStart = FALSE)
+ inline static bool IsGCInProgress(bool bConsiderGCStart = false)
{
WRAPPER_NO_CONTRACT;
@@ -68,7 +91,7 @@ public:
// Returns true if we should be competing marking for statics. This
// influences the behavior of `GCToEEInterface::GcScanRoots`.
- inline static BOOL MarkShouldCompeteForStatics()
+ inline static bool MarkShouldCompeteForStatics()
{
WRAPPER_NO_CONTRACT;
@@ -76,7 +99,7 @@ public:
}
// Waits until a GC is complete, if the heap has been initialized.
- inline static void WaitForGCCompletion(BOOL bConsiderGCStart = FALSE)
+ inline static void WaitForGCCompletion(bool bConsiderGCStart = false)
{
WRAPPER_NO_CONTRACT;
@@ -84,53 +107,29 @@ public:
GetGCHeap()->WaitUntilGCComplete(bConsiderGCStart);
}
- // Returns true if we should be using allocation contexts, false otherwise.
- inline static bool UseAllocationContexts()
- {
- WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_REDHAWK
- // SIMPLIFY: only use allocation contexts
- return true;
-#else
-#if defined(_TARGET_ARM_) || defined(FEATURE_PAL)
- return true;
-#else
- return ((IsServerHeap() ? true : (g_SystemInfo.dwNumberOfProcessors >= 2)));
-#endif
-#endif
- }
-
// Returns true if the held GC heap is a Server GC heap, false otherwise.
inline static bool IsServerHeap()
{
LIMITED_METHOD_CONTRACT;
+
#ifdef FEATURE_SVR_GC
- _ASSERTE(IGCHeap::gcHeapType != IGCHeap::GC_HEAP_INVALID);
- return (IGCHeap::gcHeapType == IGCHeap::GC_HEAP_SVR);
-#else // FEATURE_SVR_GC
+ _ASSERTE(g_heap_type != GC_HEAP_INVALID);
+ return g_heap_type == GC_HEAP_SVR;
+#else
return false;
#endif // FEATURE_SVR_GC
}
- // Gets the maximum generation number by reading the static field
- // on IGCHeap. This should only be done by the DAC code paths - all other code
- // should go through IGCHeap::GetMaxGeneration.
- //
- // The reason for this is that, while we are in the early stages of
- // decoupling the GC, the GC and the DAC still remain tightly coupled
- // and, in particular, the DAC needs to know how many generations the GC
- // has. However, it is not permitted to invoke virtual methods on g_pGCHeap
- // while on a DAC code path. Therefore, we need to determine the max generation
- // non-virtually, while still in a manner consistent with the interface -
- // therefore, a static field is used.
- //
- // This is not without precedent - IGCHeap::gcHeapType is a static field used
- // for a similar reason (the DAC needs to know what kind of heap it's looking at).
- inline static unsigned GetMaxGeneration()
+ static bool UseThreadAllocationContexts()
{
- WRAPPER_NO_CONTRACT;
+ // When running on a single-proc system, it's more efficient to use a single global
+ // allocation context for SOH allocations than to use one for every thread.
+#if defined(_TARGET_ARM_) || defined(FEATURE_PAL) || defined(FEATURE_REDHAWK)
+ return true;
+#else
+ return IsServerHeap() || ::GetCurrentProcessCpuCount() != 1;
+#endif
- return IGCHeap::maxGeneration;
}
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
@@ -197,10 +196,10 @@ public:
}
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
-
private:
// This class should never be instantiated.
GCHeapUtilities() = delete;
};
-#endif // _GCHEAPUTILITIES_H_ \ No newline at end of file
+#endif // _GCHEAPUTILITIES_H_
+
diff --git a/src/vm/gchelpers.cpp b/src/vm/gchelpers.cpp
index 30f6dd0c81..9669f988d7 100644
--- a/src/vm/gchelpers.cpp
+++ b/src/vm/gchelpers.cpp
@@ -21,13 +21,13 @@
#include "threads.h"
#include "fieldmarshaler.h"
#include "interoputil.h"
-#include "constrainedexecutionregion.h"
#include "dynamicmethod.h"
#include "stubhelpers.h"
#include "eventtrace.h"
#include "excep.h"
+#include "gchelpers.inl"
#include "eeprofinterfaces.inl"
#ifdef FEATURE_COMINTEROP
@@ -54,11 +54,110 @@ inline gc_alloc_context* GetThreadAllocContext()
{
WRAPPER_NO_CONTRACT;
- assert(GCHeapUtilities::UseAllocationContexts());
+ assert(GCHeapUtilities::UseThreadAllocationContexts());
return & GetThread()->m_alloc_context;
}
+// When not using per-thread allocation contexts, we (the EE) need to take care that
+// no two threads are concurrently modifying the global allocation context. This lock
+// must be acquired before any sort of operations involving the global allocation context
+// can occur.
+//
+// This lock is acquired by all allocations when not using per-thread allocation contexts.
+// It is acquired in two kinds of places:
+// 1) JIT_TrialAllocFastSP (and related assembly alloc helpers), which attempt to
+// acquire it but move into an alloc slow path if acquiring fails
+// (but does not decrement the lock variable when doing so)
+// 2) Alloc and AllocAlign8 in gchelpers.cpp, which acquire the lock using
+// the Acquire and Release methods below.
+class GlobalAllocLock {
+ friend struct AsmOffsets;
+private:
+ // The lock variable. This field must always be first.
+ LONG m_lock;
+
+public:
+ // Creates a new GlobalAllocLock in the unlocked state.
+ GlobalAllocLock() : m_lock(-1) {}
+
+ // Copy and copy-assignment operators should never be invoked
+ // for this type
+ GlobalAllocLock(const GlobalAllocLock&) = delete;
+ GlobalAllocLock& operator=(const GlobalAllocLock&) = delete;
+
+ // Acquires the lock, spinning if necessary to do so. When this method
+ // returns, m_lock will be zero and the lock will be acquired.
+ void Acquire()
+ {
+ CONTRACTL {
+ NOTHROW;
+ GC_TRIGGERS; // switch to preemptive mode
+ MODE_COOPERATIVE;
+ } CONTRACTL_END;
+
+ DWORD spinCount = 0;
+ while(FastInterlockExchange(&m_lock, 0) != -1)
+ {
+ GCX_PREEMP();
+ __SwitchToThread(0, spinCount++);
+ }
+
+ assert(m_lock == 0);
+ }
+
+ // Releases the lock.
+ void Release()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ // the lock may not be exactly 0. This is because the
+ // assembly alloc routines increment the lock variable and
+ // jump if not zero to the slow alloc path, which eventually
+ // will try to acquire the lock again. At that point, it will
+ // spin in Acquire (since m_lock is some number that's not zero).
+ // When the thread that /does/ hold the lock releases it, the spinning
+ // thread will continue.
+ MemoryBarrier();
+ assert(m_lock >= 0);
+ m_lock = -1;
+ }
+
+ // Static helper to acquire a lock, for use with the Holder template.
+ static void AcquireLock(GlobalAllocLock *lock)
+ {
+ WRAPPER_NO_CONTRACT;
+ lock->Acquire();
+ }
+
+ // Static helper to release a lock, for use with the Holder template
+ static void ReleaseLock(GlobalAllocLock *lock)
+ {
+ WRAPPER_NO_CONTRACT;
+ lock->Release();
+ }
+
+ typedef Holder<GlobalAllocLock *, GlobalAllocLock::AcquireLock, GlobalAllocLock::ReleaseLock> Holder;
+};
+
+typedef GlobalAllocLock::Holder GlobalAllocLockHolder;
+
+struct AsmOffsets {
+ static_assert(offsetof(GlobalAllocLock, m_lock) == 0, "ASM code relies on this property");
+};
+
+// For single-proc machines, the global allocation context is protected
+// from concurrent modification by this lock.
+//
+// When not using per-thread allocation contexts, certain methods on IGCHeap
+// require that this lock be held before calling. These methods are documented
+// on the IGCHeap interface.
+extern "C"
+{
+ GlobalAllocLock g_global_alloc_lock;
+}
+
+
// Checks to see if the given allocation size exceeds the
// largest object size allowed - if it does, it throws
// an OutOfMemoryException with a message indicating that
@@ -102,12 +201,12 @@ inline void CheckObjectSize(size_t alloc_size)
// * Call code:Alloc - When the jit helpers fall back, or we do allocations within the runtime code
// itself, we ultimately call here.
// * Call code:AllocLHeap - Used very rarely to force allocation to be on the large object heap.
-//
+//
// While this is a choke point into allocating an object, it is primitive (it does not want to know about
-// MethodTable and thus does not initialize that poitner. It also does not know if the object is finalizable
+// MethodTable and thus does not initialize that pointer. It also does not know if the object is finalizable
// or contains pointers. Thus we quickly wrap this function in more user-friendly ones that know about
// MethodTables etc. (see code:FastAllocatePrimitiveArray code:AllocateArrayEx code:AllocateObject)
-//
+//
// You can get an exhaustive list of code sites that allocate GC objects by finding all calls to
// code:ProfilerObjectAllocatedCallback (since the profiler has to hook them all).
inline Object* Alloc(size_t size, BOOL bFinalize, BOOL bContainsPointers )
@@ -137,10 +236,16 @@ inline Object* Alloc(size_t size, BOOL bFinalize, BOOL bContainsPointers )
// We don't want to throw an SO during the GC, so make sure we have plenty
// of stack before calling in.
INTERIOR_STACK_PROBE_FOR(GetThread(), static_cast<unsigned>(DEFAULT_ENTRY_PROBE_AMOUNT * 1.5));
- if (GCHeapUtilities::UseAllocationContexts())
+ if (GCHeapUtilities::UseThreadAllocationContexts())
+ {
retVal = GCHeapUtilities::GetGCHeap()->Alloc(GetThreadAllocContext(), size, flags);
+ }
else
- retVal = GCHeapUtilities::GetGCHeap()->Alloc(size, flags);
+ {
+ GlobalAllocLockHolder holder(&g_global_alloc_lock);
+ retVal = GCHeapUtilities::GetGCHeap()->Alloc(&g_global_alloc_context, size, flags);
+ }
+
if (!retVal)
{
@@ -172,10 +277,15 @@ inline Object* AllocAlign8(size_t size, BOOL bFinalize, BOOL bContainsPointers,
// We don't want to throw an SO during the GC, so make sure we have plenty
// of stack before calling in.
INTERIOR_STACK_PROBE_FOR(GetThread(), static_cast<unsigned>(DEFAULT_ENTRY_PROBE_AMOUNT * 1.5));
- if (GCHeapUtilities::UseAllocationContexts())
+ if (GCHeapUtilities::UseThreadAllocationContexts())
+ {
retVal = GCHeapUtilities::GetGCHeap()->AllocAlign8(GetThreadAllocContext(), size, flags);
+ }
else
- retVal = GCHeapUtilities::GetGCHeap()->AllocAlign8(size, flags);
+ {
+ GlobalAllocLockHolder holder(&g_global_alloc_lock);
+ retVal = GCHeapUtilities::GetGCHeap()->AllocAlign8(&g_global_alloc_context, size, flags);
+ }
if (!retVal)
{
@@ -1005,10 +1115,6 @@ OBJECTREF AllocateObject(MethodTable *pMT
g_IBCLogger.LogMethodTableAccess(pMT);
SetTypeHandleOnThreadForAlloc(TypeHandle(pMT));
-#ifdef FEATURE_CER
- if (pMT->HasCriticalFinalizer())
- PrepareCriticalFinalizerObject(pMT);
-#endif
#ifdef FEATURE_COMINTEROP
#ifdef FEATURE_COMINTEROP_UNMANAGED_ACTIVATION
@@ -1105,16 +1211,21 @@ OBJECTREF AllocateObject(MethodTable *pMT
//========================================================================
-#if defined(_WIN64)
-// Card byte shift is different on 64bit.
-#define card_byte_shift 11
-#else
-#define card_byte_shift 10
-#endif
-
#define card_byte(addr) (((size_t)(addr)) >> card_byte_shift)
#define card_bit(addr) (1 << ((((size_t)(addr)) >> (card_byte_shift - 3)) & 7))
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+#define card_bundle_byte(addr) (((size_t)(addr)) >> card_bundle_byte_shift)
+
+static void SetCardBundleByte(BYTE* addr)
+{
+ BYTE* cbByte = (BYTE *)VolatileLoadWithoutBarrier(&g_card_bundle_table) + card_bundle_byte(addr);
+ if (*cbByte != 0xFF)
+ {
+ *cbByte = 0xFF;
+ }
+}
+#endif
#ifdef FEATURE_USE_ASM_GC_WRITE_BARRIERS
@@ -1266,6 +1377,10 @@ extern "C" HCIMPL2_RAW(VOID, JIT_CheckedWriteBarrier, Object **dst, Object *ref)
CheckedAfterAlreadyDirtyFilter++;
#endif
*pCardByte = 0xFF;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ SetCardBundleByte((BYTE*)dst);
+#endif
}
}
}
@@ -1321,6 +1436,11 @@ extern "C" HCIMPL2_RAW(VOID, JIT_WriteBarrier, Object **dst, Object *ref)
UncheckedAfterAlreadyDirtyFilter++;
#endif
*pCardByte = 0xFF;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ SetCardBundleByte((BYTE*)dst);
+#endif
+
}
}
}
@@ -1371,15 +1491,22 @@ void ErectWriteBarrier(OBJECTREF *dst, OBJECTREF ref)
}
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
- if((BYTE*) OBJECTREFToObject(ref) >= g_ephemeral_low && (BYTE*) OBJECTREFToObject(ref) < g_ephemeral_high)
+ if ((BYTE*) OBJECTREFToObject(ref) >= g_ephemeral_low && (BYTE*) OBJECTREFToObject(ref) < g_ephemeral_high)
{
// VolatileLoadWithoutBarrier() is used here to prevent fetch of g_card_table from being reordered
// with g_lowest/highest_address check above. See comment in code:gc_heap::grow_brick_card_tables.
BYTE* pCardByte = (BYTE *)VolatileLoadWithoutBarrier(&g_card_table) + card_byte((BYTE *)dst);
- if(*pCardByte != 0xFF)
+ if (*pCardByte != 0xFF)
+ {
*pCardByte = 0xFF;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ SetCardBundleByte((BYTE*)dst);
+#endif
+
+ }
}
-}
+}
#include <optdefault.h>
void ErectWriteBarrierForMT(MethodTable **dst, MethodTable *ref)
@@ -1413,6 +1540,11 @@ void ErectWriteBarrierForMT(MethodTable **dst, MethodTable *ref)
if( !((*pCardByte) & card_bit((BYTE *)dst)) )
{
*pCardByte = 0xFF;
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ SetCardBundleByte((BYTE*)dst);
+#endif
+
}
}
}
@@ -1442,59 +1574,13 @@ void ErectWriteBarrierForMT(MethodTable **dst, MethodTable *ref)
void
SetCardsAfterBulkCopy(Object **start, size_t len)
{
- // Check whether the writes were even into the heap. If not there's no card update required.
- // Also if the size is smaller than a pointer, no write barrier is required.
- if ((BYTE*)start < g_lowest_address || (BYTE*)start >= g_highest_address || len < sizeof(uintptr_t))
+ // If the size is smaller than a pointer, no write barrier is required.
+ if (len >= sizeof(uintptr_t))
{
- return;
+ InlinedSetCardsAfterBulkCopyHelper(start, len);
}
-
-
- // Don't optimize the Generation 0 case if we are checking for write barrier violations
- // since we need to update the shadow heap even in the generation 0 case.
-#if defined (WRITE_BARRIER_CHECK) && !defined (SERVER_GC)
- if (g_pConfig->GetHeapVerifyLevel() & EEConfig::HEAPVERIFY_BARRIERCHECK)
- {
- for(unsigned i=0; i < len / sizeof(Object*); i++)
- {
- updateGCShadow(&start[i], start[i]);
- }
- }
-#endif //WRITE_BARRIER_CHECK && !SERVER_GC
-
-#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
- if (GCHeapUtilities::SoftwareWriteWatchIsEnabled())
- {
- GCHeapUtilities::SoftwareWriteWatchSetDirtyRegion(start, len);
- }
-#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
-
- size_t startAddress = (size_t)start;
- size_t endAddress = startAddress + len;
- size_t startingClump = startAddress >> card_byte_shift;
- size_t endingClump = (endAddress + (1 << card_byte_shift) - 1) >> card_byte_shift;
-
- // calculate the number of clumps to mark (round_up(end) - start)
- size_t clumpCount = endingClump - startingClump;
- // VolatileLoadWithoutBarrier() is used here to prevent fetch of g_card_table from being reordered
- // with g_lowest/highest_address check at the beginning of this function.
- uint8_t* card = ((uint8_t*)VolatileLoadWithoutBarrier(&g_card_table)) + startingClump;
-
- // Fill the cards. To avoid cache line thrashing we check whether the cards have already been set before
- // writing.
- do
- {
- if (*card != 0xff)
- {
- *card = 0xff;
- }
-
- card++;
- clumpCount--;
- }
- while (clumpCount != 0);
}
#if defined(_MSC_VER) && defined(_TARGET_X86_)
#pragma optimize("", on) // Go back to command line default optimizations
-#endif //_MSC_VER && _TARGET_X86_ \ No newline at end of file
+#endif //_MSC_VER && _TARGET_X86_
diff --git a/src/vm/gchelpers.inl b/src/vm/gchelpers.inl
new file mode 100644
index 0000000000..1b14077e72
--- /dev/null
+++ b/src/vm/gchelpers.inl
@@ -0,0 +1,108 @@
+// 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.
+
+/*
+* GCHELPERS.INL
+*
+* GC Allocation and Write Barrier Helpers
+*
+*
+*/
+
+#ifndef _GCHELPERS_INL_
+#define _GCHELPERS_INL_
+
+//========================================================================
+//
+// WRITE BARRIER HELPERS
+//
+//========================================================================
+
+#if defined(_WIN64)
+ static const int card_byte_shift = 11;
+ static const int card_bundle_byte_shift = 21;
+#else
+ static const int card_byte_shift = 10;
+
+ #ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ #error Manually managed card bundles are currently only implemented for AMD64.
+ #endif
+#endif
+
+FORCEINLINE void InlinedSetCardsAfterBulkCopyHelper(Object **start, size_t len)
+{
+ // Check whether the writes were even into the heap. If not there's no card update required.
+ // Also if the size is smaller than a pointer, no write barrier is required.
+ _ASSERTE(len >= sizeof(uintptr_t));
+ if ((BYTE*)start < g_lowest_address || (BYTE*)start >= g_highest_address)
+ {
+ return;
+ }
+
+ // Don't optimize the Generation 0 case if we are checking for write barrier violations
+ // since we need to update the shadow heap even in the generation 0 case.
+#if defined (WRITE_BARRIER_CHECK) && !defined (SERVER_GC)
+ if (g_pConfig->GetHeapVerifyLevel() & EEConfig::HEAPVERIFY_BARRIERCHECK)
+ {
+ for(unsigned i=0; i < len / sizeof(Object*); i++)
+ {
+ updateGCShadow(&start[i], start[i]);
+ }
+ }
+#endif //WRITE_BARRIER_CHECK && !SERVER_GC
+
+#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
+ if (GCHeapUtilities::SoftwareWriteWatchIsEnabled())
+ {
+ GCHeapUtilities::SoftwareWriteWatchSetDirtyRegion(start, len);
+ }
+#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
+
+ size_t startAddress = (size_t)start;
+ size_t endAddress = startAddress + len;
+ size_t startingClump = startAddress >> card_byte_shift;
+ size_t endingClump = (endAddress + (1 << card_byte_shift) - 1) >> card_byte_shift;
+
+ // calculate the number of clumps to mark (round_up(end) - start)
+ size_t clumpCount = endingClump - startingClump;
+ // VolatileLoadWithoutBarrier() is used here to prevent fetch of g_card_table from being reordered
+ // with g_lowest/highest_address check at the beginning of this function.
+ uint8_t* card = ((uint8_t*)VolatileLoadWithoutBarrier(&g_card_table)) + startingClump;
+
+ // Fill the cards. To avoid cache line thrashing we check whether the cards have already been set before
+ // writing.
+ do
+ {
+ if (*card != 0xff)
+ {
+ *card = 0xff;
+ }
+
+ card++;
+ clumpCount--;
+ }
+ while (clumpCount != 0);
+
+#ifdef FEATURE_MANUALLY_MANAGED_CARD_BUNDLES
+ size_t startBundleByte = startAddress >> card_bundle_byte_shift;
+ size_t endBundleByte = (endAddress + (1 << card_bundle_byte_shift) - 1) >> card_bundle_byte_shift;
+ size_t bundleByteCount = endBundleByte - startBundleByte;
+
+ uint8_t* pBundleByte = ((uint8_t*)VolatileLoadWithoutBarrier(&g_card_bundle_table)) + startBundleByte;
+
+ do
+ {
+ if (*pBundleByte != 0xFF)
+ {
+ *pBundleByte = 0xFF;
+ }
+
+ pBundleByte++;
+ bundleByteCount--;
+ }
+ while (bundleByteCount != 0);
+#endif
+}
+
+#endif // !_GCHELPERS_INL_
diff --git a/src/vm/gchost.cpp b/src/vm/gchost.cpp
deleted file mode 100644
index b51f2459fd..0000000000
--- a/src/vm/gchost.cpp
+++ /dev/null
@@ -1,276 +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.
-//*****************************************************************************
-// gchost.cpp
-//
-// This module contains the implementation for the IGCController interface.
-// This interface is published through the gchost.idl file. It allows a host
-// environment to set config values for the GC.
-//
-
-//
-//*****************************************************************************
-
-//********** Includes *********************************************************
-
-#include "common.h"
-#include "vars.hpp"
-#include "eeconfig.h"
-#include "perfcounters.h"
-#include "gchost.h"
-#include "corhost.h"
-#include "excep.h"
-#include "field.h"
-#include "gcheaputilities.h"
-
-#if !defined(FEATURE_CORECLR)
-inline size_t SizeInKBytes(size_t cbSize)
-{
- LIMITED_METHOD_CONTRACT;
-
- size_t cb = (cbSize % 1024) ? 1 : 0;
- return ((cbSize / 1024) + cb);
-}
-
-// IGCController
-
-HRESULT CorGCHost::_SetGCSegmentSize(SIZE_T SegmentSize)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // Sanity check the value, it must be a power of two and big enough.
- if (!GCHeapUtilities::GetGCHeap()->IsValidSegmentSize(SegmentSize))
- {
- hr = E_INVALIDARG;
- }
- else
- {
- Host_SegmentSize = SegmentSize;
- Host_fSegmentSizeSet = TRUE;
- }
-
- return (hr);
-}
-
-HRESULT CorGCHost::_SetGCMaxGen0Size(SIZE_T MaxGen0Size)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // Sanity check the value is at least large enough.
- if (!GCHeapUtilities::GetGCHeap()->IsValidGen0MaxSize(MaxGen0Size))
- {
- hr = E_INVALIDARG;
- }
- else
- {
- Host_MaxGen0Size = MaxGen0Size;
- Host_fMaxGen0SizeSet = TRUE;
- }
-
- return (hr);
-}
-
-HRESULT CorGCHost::SetGCStartupLimits(
- DWORD SegmentSize,
- DWORD MaxGen0Size)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // Set default overrides if specified by caller.
- if (SegmentSize != (DWORD) ~0 && SegmentSize > 0)
- {
- hr = _SetGCSegmentSize(SegmentSize);
- }
-
- if (SUCCEEDED(hr) && MaxGen0Size != (DWORD) ~0 && MaxGen0Size > 0)
- {
- hr = _SetGCMaxGen0Size(MaxGen0Size);
- }
-
- return (hr);
-}
-
-HRESULT CorGCHost::SetGCStartupLimitsEx(
- SIZE_T SegmentSize,
- SIZE_T MaxGen0Size)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // Set default overrides if specified by caller.
- if (SegmentSize != (SIZE_T) ~0 && SegmentSize > 0)
- {
- hr = _SetGCSegmentSize(SegmentSize);
- }
-
- if (SUCCEEDED(hr) && MaxGen0Size != (SIZE_T) ~0 && MaxGen0Size > 0)
- {
- hr = _SetGCMaxGen0Size(MaxGen0Size);
- }
-
- return (hr);
-}
-
-// Collect the requested generation.
-HRESULT CorGCHost::Collect(
- LONG Generation)
-{
- STATIC_CONTRACT_SO_TOLERANT;
-
- HRESULT hr = E_FAIL;
-
- if (Generation > (int) GCHeapUtilities::GetGCHeap()->GetMaxGeneration())
- hr = E_INVALIDARG;
- else
- {
- // Set up a Thread object if this is called on a native thread.
- Thread *pThread;
- pThread = GetThread();
- if (pThread == NULL)
- pThread = SetupThreadNoThrow(&hr);
-
- if (pThread != NULL)
- {
- // Put thread into co-operative mode, which is how GC must run.
- GCX_COOP();
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
-
- EX_TRY
- {
- hr = GCHeapUtilities::GetGCHeap()->GarbageCollect(Generation);
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- END_SO_INTOLERANT_CODE;
- }
- }
- return (hr);
-}
-
-
-// Return GC counters in the gchost format.
-HRESULT CorGCHost::GetStats(
- COR_GC_STATS *pStats)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
-#if defined(ENABLE_PERF_COUNTERS)
-
- Perf_GC *pgc = &GetPerfCounters().m_GC;
-
- if (!pStats)
- return (E_INVALIDARG);
-
- if (pStats->Flags & COR_GC_COUNTS)
- {
- pStats->ExplicitGCCount = pgc->cInducedGCs;
- for (int idx=0; idx<3; idx++)
- {
- pStats->GenCollectionsTaken[idx] = pgc->cGenCollections[idx];
- }
- }
-
- if (pStats->Flags & COR_GC_MEMORYUSAGE)
- {
- pStats->CommittedKBytes = SizeInKBytes(pgc->cTotalCommittedBytes);
- pStats->ReservedKBytes = SizeInKBytes(pgc->cTotalReservedBytes);
- pStats->Gen0HeapSizeKBytes = SizeInKBytes(pgc->cGenHeapSize[0]);
- pStats->Gen1HeapSizeKBytes = SizeInKBytes(pgc->cGenHeapSize[1]);
- pStats->Gen2HeapSizeKBytes = SizeInKBytes(pgc->cGenHeapSize[2]);
- pStats->LargeObjectHeapSizeKBytes = SizeInKBytes(pgc->cLrgObjSize);
- pStats->KBytesPromotedFromGen0 = SizeInKBytes(pgc->cbPromotedMem[0]);
- pStats->KBytesPromotedFromGen1 = SizeInKBytes(pgc->cbPromotedMem[1]);
- }
- return (S_OK);
-#else
- return (E_NOTIMPL);
-#endif // ENABLE_PERF_COUNTERS
-}
-
-// Return per-thread allocation information.
-HRESULT CorGCHost::GetThreadStats(
- DWORD *pFiberCookie,
- COR_GC_THREAD_STATS *pStats)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- Thread *pThread;
-
- // Get the thread from the caller or the current thread.
- if (!pFiberCookie)
- pThread = GetThread();
- else
- pThread = (Thread *) pFiberCookie;
- if (!pThread)
- return (E_INVALIDARG);
-
- return pThread->GetMemStats (pStats);
-}
-
-// Return per-thread allocation information.
-HRESULT CorGCHost::SetVirtualMemLimit(
- SIZE_T sztMaxVirtualMemMB)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- GCHeapUtilities::GetGCHeap()->SetReservedVMLimit (sztMaxVirtualMemMB);
- return (S_OK);
-}
-#endif // !defined(FEATURE_CORECLR)
-
-
diff --git a/src/vm/gcinfodecoder.cpp b/src/vm/gcinfodecoder.cpp
index 89f470499e..7c0881c880 100644
--- a/src/vm/gcinfodecoder.cpp
+++ b/src/vm/gcinfodecoder.cpp
@@ -628,6 +628,8 @@ bool GcInfoDecoder::EnumerateLiveSlots(
#ifdef PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
+ bool noTrackedRefs = false;
+
if(m_SafePointIndex < m_NumSafePoints && !executionAborted)
{
// Skip interruptibility information
@@ -648,33 +650,40 @@ bool GcInfoDecoder::EnumerateLiveSlots(
//
if(!executionAborted)
{
- _ASSERTE(m_NumInterruptibleRanges);
+ if(m_NumInterruptibleRanges == 0)
+ {
+ // No ranges and no explicit safepoint - must be MinOpts with untracked refs.
+ noTrackedRefs = true;
+ }
}
- int countIntersections = 0;
- UINT32 lastNormStop = 0;
- for(UINT32 i=0; i<m_NumInterruptibleRanges; i++)
+ if(m_NumInterruptibleRanges != 0)
{
- UINT32 normStartDelta = (UINT32) m_Reader.DecodeVarLengthUnsigned( INTERRUPTIBLE_RANGE_DELTA1_ENCBASE );
- UINT32 normStopDelta = (UINT32) m_Reader.DecodeVarLengthUnsigned( INTERRUPTIBLE_RANGE_DELTA2_ENCBASE ) + 1;
+ int countIntersections = 0;
+ UINT32 lastNormStop = 0;
+ for(UINT32 i=0; i<m_NumInterruptibleRanges; i++)
+ {
+ UINT32 normStartDelta = (UINT32) m_Reader.DecodeVarLengthUnsigned( INTERRUPTIBLE_RANGE_DELTA1_ENCBASE );
+ UINT32 normStopDelta = (UINT32) m_Reader.DecodeVarLengthUnsigned( INTERRUPTIBLE_RANGE_DELTA2_ENCBASE ) + 1;
- UINT32 normStart = lastNormStop + normStartDelta;
- UINT32 normStop = normStart + normStopDelta;
- if(normBreakOffset >= normStart && normBreakOffset < normStop)
+ UINT32 normStart = lastNormStop + normStartDelta;
+ UINT32 normStop = normStart + normStopDelta;
+ if(normBreakOffset >= normStart && normBreakOffset < normStop)
+ {
+ _ASSERTE(pseudoBreakOffset == 0);
+ countIntersections++;
+ pseudoBreakOffset = numInterruptibleLength + normBreakOffset - normStart;
+ }
+ numInterruptibleLength += normStopDelta;
+ lastNormStop = normStop;
+ }
+ _ASSERTE(countIntersections <= 1);
+ if(countIntersections == 0)
{
- _ASSERTE(pseudoBreakOffset == 0);
- countIntersections++;
- pseudoBreakOffset = numInterruptibleLength + normBreakOffset - normStart;
+ _ASSERTE(executionAborted);
+ LOG((LF_GCROOTS, LL_INFO100000, "Not reporting this frame because it is aborted and not fully interruptible.\n"));
+ goto ExitSuccess;
}
- numInterruptibleLength += normStopDelta;
- lastNormStop = normStop;
- }
- _ASSERTE(countIntersections <= 1);
- if(countIntersections == 0)
- {
- _ASSERTE(executionAborted);
- LOG((LF_GCROOTS, LL_INFO100000, "Not reporting this frame because it is aborted and not fully interruptible.\n"));
- goto ExitSuccess;
}
}
#else // !PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
@@ -716,12 +725,7 @@ bool GcInfoDecoder::EnumerateLiveSlots(
// Try partially interruptible first
//------------------------------------------------------------------------------
- if(executionAborted)
- {
- _ASSERTE(m_NumSafePoints == 0);
- m_Reader.Skip(m_NumSafePoints * numSlots);
- }
- else if( m_SafePointIndex != m_NumSafePoints )
+ if( !executionAborted && m_SafePointIndex != m_NumSafePoints )
{
if (numBitsPerOffset)
{
@@ -787,6 +791,8 @@ bool GcInfoDecoder::EnumerateLiveSlots(
else
{
m_Reader.Skip(m_NumSafePoints * numSlots);
+ if(m_NumInterruptibleRanges == 0)
+ goto ReportUntracked;
}
#endif // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED
diff --git a/src/vm/gcscan.h b/src/vm/gcscan.h
deleted file mode 100644
index aba1e6b74e..0000000000
--- a/src/vm/gcscan.h
+++ /dev/null
@@ -1,5 +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 "../gc/gcscan.h"
diff --git a/src/vm/gcstress.h b/src/vm/gcstress.h
index 04487c611e..edf92a947c 100644
--- a/src/vm/gcstress.h
+++ b/src/vm/gcstress.h
@@ -286,7 +286,12 @@ namespace _GCStress
public:
FORCEINLINE
static void Trigger()
- { GCHeapUtilities::GetGCHeap()->StressHeap(); }
+ {
+ // BUG(github #10318) - when not using allocation contexts, the alloc lock
+ // must be acquired here. Until fixed, this assert prevents random heap corruption.
+ _ASSERTE(GCHeapUtilities::UseThreadAllocationContexts());
+ GCHeapUtilities::GetGCHeap()->StressHeap(GetThread()->GetAllocContext());
+ }
FORCEINLINE
static void Trigger(::gc_alloc_context* acontext)
diff --git a/src/vm/gdbjit.cpp b/src/vm/gdbjit.cpp
index 2ae7009888..fe8e211e5b 100644
--- a/src/vm/gdbjit.cpp
+++ b/src/vm/gdbjit.cpp
@@ -16,15 +16,17 @@
#include "gdbjithelpers.h"
TypeInfoBase*
-GetTypeInfoFromTypeHandle(TypeHandle typeHandle, NotifyGdb::PTK_TypeInfoMap pTypeMap)
+GetTypeInfoFromTypeHandle(TypeHandle typeHandle,
+ NotifyGdb::PTK_TypeInfoMap pTypeMap,
+ FunctionMemberPtrArrayHolder &method)
{
- TypeInfoBase *typeInfo = nullptr;
+ TypeInfoBase *foundTypeInfo = nullptr;
TypeKey key = typeHandle.GetTypeKey();
PTR_MethodTable pMT = typeHandle.GetMethodTable();
- if (pTypeMap->Lookup(&key, &typeInfo))
+ if (pTypeMap->Lookup(&key, &foundTypeInfo))
{
- return typeInfo;
+ return foundTypeInfo;
}
CorElementType corType = typeHandle.GetSignatureCorElementType();
@@ -33,11 +35,6 @@ GetTypeInfoFromTypeHandle(TypeHandle typeHandle, NotifyGdb::PTK_TypeInfoMap pTyp
case ELEMENT_TYPE_I1:
case ELEMENT_TYPE_U1:
case ELEMENT_TYPE_CHAR:
- typeInfo = new (nothrow) ByteTypeInfo(typeHandle, CorElementTypeToDWEncoding[corType]);
- if (typeInfo == nullptr)
- return nullptr;
- typeInfo->m_type_size = CorTypeInfo::Size(corType);
- break;
case ELEMENT_TYPE_VOID:
case ELEMENT_TYPE_BOOLEAN:
case ELEMENT_TYPE_I2:
@@ -50,13 +47,12 @@ GetTypeInfoFromTypeHandle(TypeHandle typeHandle, NotifyGdb::PTK_TypeInfoMap pTyp
case ELEMENT_TYPE_R8:
case ELEMENT_TYPE_U:
case ELEMENT_TYPE_I:
- typeInfo = new (nothrow) PrimitiveTypeInfo(typeHandle, CorElementTypeToDWEncoding[corType]);
- if (typeInfo == nullptr)
- return nullptr;
-
- typeInfo->m_type_size = CorTypeInfo::Size(corType);
-
- break;
+ {
+ NewHolder<PrimitiveTypeInfo> typeInfo = new PrimitiveTypeInfo(typeHandle);
+ pTypeMap->Add(typeInfo->GetTypeKey(), typeInfo);
+ typeInfo.SuppressRelease();
+ return typeInfo;
+ }
case ELEMENT_TYPE_VALUETYPE:
case ELEMENT_TYPE_CLASS:
{
@@ -64,31 +60,22 @@ GetTypeInfoFromTypeHandle(TypeHandle typeHandle, NotifyGdb::PTK_TypeInfoMap pTyp
pMT->IsString() ? ApproxFieldDescIterator::INSTANCE_FIELDS : ApproxFieldDescIterator::ALL_FIELDS);
ULONG cFields = fieldDescIterator.Count();
- typeInfo = new (nothrow) ClassTypeInfo(typeHandle, cFields);
-
- if (typeInfo == nullptr)
- return nullptr;
-
- typeInfo->m_type_size = typeHandle.AsMethodTable()->GetClass()->GetSize();
+ NewHolder<ClassTypeInfo> typeInfo = new ClassTypeInfo(typeHandle, cFields, method);
- RefTypeInfo* refTypeInfo = nullptr;
+ NewHolder<RefTypeInfo> refTypeInfo = nullptr;
if (!typeHandle.IsValueType())
{
- // name the type
- refTypeInfo = new (nothrow) RefTypeInfo(typeHandle, typeInfo);
- if (refTypeInfo == nullptr)
- {
- return nullptr;
- }
- refTypeInfo->m_type_size = sizeof(TADDR);
- refTypeInfo->m_value_type = typeInfo;
- refTypeInfo->CalculateName();
+ refTypeInfo = new NamedRefTypeInfo(typeHandle, typeInfo);
+ typeInfo.SuppressRelease();
pTypeMap->Add(refTypeInfo->GetTypeKey(), refTypeInfo);
+ refTypeInfo.SuppressRelease();
+ }
+ else
+ {
+ pTypeMap->Add(typeInfo->GetTypeKey(), typeInfo);
+ typeInfo.SuppressRelease();
}
-
- pTypeMap->Add(typeInfo->GetTypeKey(), typeInfo);
- typeInfo->CalculateName();
//
// Now fill in the array
@@ -98,16 +85,15 @@ GetTypeInfoFromTypeHandle(TypeHandle typeHandle, NotifyGdb::PTK_TypeInfoMap pTyp
for (ULONG i = 0; i < cFields; i++)
{
pField = fieldDescIterator.Next();
- ClassTypeInfo *info = static_cast<ClassTypeInfo*>(typeInfo);
LPCUTF8 szName = pField->GetName();
- info->members[i].m_member_name = new char[strlen(szName) + 1];
- strcpy(info->members[i].m_member_name, szName);
+ typeInfo->members[i].m_member_name = new char[strlen(szName) + 1];
+ strcpy(typeInfo->members[i].m_member_name, szName);
if (!pField->IsStatic())
{
- info->members[i].m_member_offset = (ULONG)pField->GetOffset();
+ typeInfo->members[i].m_member_offset = (ULONG)pField->GetOffset();
if (!typeHandle.IsValueType())
- info->members[i].m_member_offset += Object::GetOffsetOfFirstField();
+ typeInfo->members[i].m_member_offset += Object::GetOffsetOfFirstField();
}
else
{
@@ -119,30 +105,27 @@ GetTypeInfoFromTypeHandle(TypeHandle typeHandle, NotifyGdb::PTK_TypeInfoMap pTyp
if (pField->IsRVA() || !pMT->IsDynamicStatics())
{
PTR_VOID pAddress = pField->GetStaticAddressHandle((PTR_VOID)dac_cast<TADDR>(base));
- info->members[i].m_static_member_address = dac_cast<TADDR>(pAddress);
+ typeInfo->members[i].m_static_member_address = dac_cast<TADDR>(pAddress);
}
}
- info->members[i].m_member_type =
- GetTypeInfoFromTypeHandle(pField->GetExactFieldType(typeHandle), pTypeMap);
+ typeInfo->members[i].m_member_type =
+ GetTypeInfoFromTypeHandle(pField->GetExactFieldType(typeHandle), pTypeMap, method);
// handle the System.String case:
// coerce type of the second field into array type
if (pMT->IsString() && i == 1)
{
- TypeInfoBase* elemTypeInfo = info->members[1].m_member_type;
- TypeInfoBase* arrayTypeInfo = new (nothrow) ArrayTypeInfo(typeHandle.MakeSZArray(), 0, elemTypeInfo);
- if (arrayTypeInfo == nullptr)
- return nullptr;
- info->members[1].m_member_type = arrayTypeInfo;
+ TypeInfoBase* elemTypeInfo = typeInfo->members[1].m_member_type;
+ typeInfo->m_array_type = new ArrayTypeInfo(typeHandle.MakeSZArray(), 1, elemTypeInfo);
+ typeInfo->members[1].m_member_type = typeInfo->m_array_type;
}
}
// Ignore inheritance from System.Object and System.ValueType classes.
if (!typeHandle.IsValueType() &&
pMT->GetParentMethodTable() && pMT->GetParentMethodTable()->GetParentMethodTable())
{
- static_cast<ClassTypeInfo*>(typeInfo)->m_parent =
- GetTypeInfoFromTypeHandle(typeHandle.GetParent(), pTypeMap);
+ typeInfo->m_parent = GetTypeInfoFromTypeHandle(typeHandle.GetParent(), pTypeMap, method);
}
if (refTypeInfo)
@@ -153,81 +136,64 @@ GetTypeInfoFromTypeHandle(TypeHandle typeHandle, NotifyGdb::PTK_TypeInfoMap pTyp
case ELEMENT_TYPE_PTR:
case ELEMENT_TYPE_BYREF:
{
- TypeInfoBase* valTypeInfo = GetTypeInfoFromTypeHandle(typeHandle.GetTypeParam(), pTypeMap);
- typeInfo = new (nothrow) RefTypeInfo(typeHandle, valTypeInfo);
- if (typeInfo == nullptr)
- return nullptr;
- typeInfo->m_type_size = sizeof(TADDR);
+ TypeInfoBase* valTypeInfo = GetTypeInfoFromTypeHandle(typeHandle.GetTypeParam(), pTypeMap, method);
+ NewHolder<RefTypeInfo> typeInfo = new RefTypeInfo(typeHandle, valTypeInfo);
+
typeInfo->m_type_offset = valTypeInfo->m_type_offset;
- break;
+
+ pTypeMap->Add(typeInfo->GetTypeKey(), typeInfo);
+ typeInfo.SuppressRelease();
+ return typeInfo;
}
case ELEMENT_TYPE_ARRAY:
case ELEMENT_TYPE_SZARRAY:
{
- typeInfo = new (nothrow) ClassTypeInfo(typeHandle, 2);
- if (typeInfo == nullptr)
- return nullptr;
- typeInfo->m_type_size = pMT->GetClass()->GetSize();
-
- typeInfo->CalculateName();
- RefTypeInfo *refTypeInfo = new (nothrow) RefTypeInfo(typeHandle, typeInfo);
- if (refTypeInfo == nullptr)
- {
- return nullptr;
- }
- refTypeInfo->m_type_size = sizeof(TADDR);
- refTypeInfo->m_value_type = typeInfo;
- refTypeInfo->CalculateName();
+ NewHolder<ClassTypeInfo> info = new ClassTypeInfo(typeHandle, pMT->GetRank() == 1 ? 2 : 3, method);
+ NewHolder<RefTypeInfo> refTypeInfo = new NamedRefTypeInfo(typeHandle, info);
+ info.SuppressRelease();
pTypeMap->Add(refTypeInfo->GetTypeKey(), refTypeInfo);
+ refTypeInfo.SuppressRelease();
TypeInfoBase* lengthTypeInfo = GetTypeInfoFromTypeHandle(
- TypeHandle(MscorlibBinder::GetElementType(ELEMENT_TYPE_I4)), pTypeMap);
-
- TypeInfoBase* valTypeInfo = GetTypeInfoFromTypeHandle(typeHandle.GetTypeParam(), pTypeMap);
- TypeInfoBase* arrayTypeInfo = new (nothrow) ArrayTypeInfo(typeHandle, 0, valTypeInfo);
- if (arrayTypeInfo == nullptr)
- return nullptr;
+ TypeHandle(MscorlibBinder::GetElementType(ELEMENT_TYPE_I4)), pTypeMap, method);
- ClassTypeInfo *info = static_cast<ClassTypeInfo*>(typeInfo);
+ TypeInfoBase* valTypeInfo = GetTypeInfoFromTypeHandle(typeHandle.GetTypeParam(), pTypeMap, method);
+ info->m_array_type = new ArrayTypeInfo(typeHandle, 1, valTypeInfo);
- info->members[0].m_member_name = new (nothrow) char[16];
+ info->members[0].m_member_name = new char[16];
strcpy(info->members[0].m_member_name, "m_NumComponents");
info->members[0].m_member_offset = ArrayBase::GetOffsetOfNumComponents();
info->members[0].m_member_type = lengthTypeInfo;
- info->members[0].m_member_type->m_type_size = sizeof(DWORD);
- info->members[1].m_member_name = new (nothrow) char[7];
+ info->members[1].m_member_name = new char[7];
strcpy(info->members[1].m_member_name, "m_Data");
info->members[1].m_member_offset = ArrayBase::GetDataPtrOffset(pMT);
- info->members[1].m_member_type = arrayTypeInfo;
- info->members[1].m_member_type->m_type_size = sizeof(TADDR);
+ info->members[1].m_member_type = info->m_array_type;
+
+ if (pMT->GetRank() != 1)
+ {
+ TypeHandle dwordArray(MscorlibBinder::GetElementType(ELEMENT_TYPE_I4));
+ info->m_array_bounds_type = new ArrayTypeInfo(dwordArray.MakeSZArray(), pMT->GetRank(), lengthTypeInfo);
+ info->members[2].m_member_name = new char[9];
+ strcpy(info->members[2].m_member_name, "m_Bounds");
+ info->members[2].m_member_offset = ArrayBase::GetBoundsOffset(pMT);
+ info->members[2].m_member_type = info->m_array_bounds_type;
+ }
return refTypeInfo;
}
default:
- ASSERT(0 && "not implemented");
- break;
+ COMPlusThrowHR(COR_E_NOTSUPPORTED);
}
- // name the type
- if (corType == ELEMENT_TYPE_CHAR)
- {
- typeInfo->m_type_name = new char[9];
- strcpy(typeInfo->m_type_name, "char16_t");
- }
- else
- {
- typeInfo->CalculateName();
- }
- pTypeMap->Add(typeInfo->GetTypeKey(), typeInfo);
- return typeInfo;
}
-TypeInfoBase* GetArgTypeInfo(MethodDesc* MethodDescPtr,
+TypeInfoBase* GetArgTypeInfo(MethodDesc* methodDescPtr,
NotifyGdb::PTK_TypeInfoMap pTypeMap,
- unsigned ilIndex)
+ unsigned ilIndex,
+ FunctionMemberPtrArrayHolder &method)
{
- MetaSig sig(MethodDescPtr);
+ MetaSig sig(methodDescPtr);
TypeHandle th;
if (ilIndex == 0)
{
@@ -241,20 +207,21 @@ TypeInfoBase* GetArgTypeInfo(MethodDesc* MethodDescPtr,
sig.NextArg();
th = sig.GetLastTypeHandleNT();
}
- return GetTypeInfoFromTypeHandle(th, pTypeMap);
+ return GetTypeInfoFromTypeHandle(th, pTypeMap, method);
}
-TypeInfoBase* GetLocalTypeInfo(MethodDesc *MethodDescPtr,
+TypeInfoBase* GetLocalTypeInfo(MethodDesc *methodDescPtr,
NotifyGdb::PTK_TypeInfoMap pTypeMap,
- unsigned ilIndex)
+ unsigned ilIndex,
+ FunctionMemberPtrArrayHolder &funcs)
{
- COR_ILMETHOD_DECODER method(MethodDescPtr->GetILHeader());
+ COR_ILMETHOD_DECODER method(methodDescPtr->GetILHeader());
if (method.GetLocalVarSigTok())
{
DWORD cbSigLen;
PCCOR_SIGNATURE pComSig;
- if (FAILED(MethodDescPtr->GetMDImport()->GetSigFromToken(method.GetLocalVarSigTok(), &cbSigLen, &pComSig)))
+ if (FAILED(methodDescPtr->GetMDImport()->GetSigFromToken(method.GetLocalVarSigTok(), &cbSigLen, &pComSig)))
{
printf("\nInvalid record");
return nullptr;
@@ -262,8 +229,8 @@ TypeInfoBase* GetLocalTypeInfo(MethodDesc *MethodDescPtr,
_ASSERTE(*pComSig == IMAGE_CEE_CS_CALLCONV_LOCAL_SIG);
- SigTypeContext typeContext(MethodDescPtr, TypeHandle());
- MetaSig sig(pComSig, cbSigLen, MethodDescPtr->GetModule(), &typeContext, MetaSig::sigLocalVars);
+ SigTypeContext typeContext(methodDescPtr, TypeHandle());
+ MetaSig sig(pComSig, cbSigLen, methodDescPtr->GetModule(), &typeContext, MetaSig::sigLocalVars);
if (ilIndex > 0)
{
while (ilIndex--)
@@ -271,14 +238,14 @@ TypeInfoBase* GetLocalTypeInfo(MethodDesc *MethodDescPtr,
}
sig.NextArg();
TypeHandle th = sig.GetLastTypeHandleNT();
- return GetTypeInfoFromTypeHandle(th, pTypeMap);
+ return GetTypeInfoFromTypeHandle(th, pTypeMap, funcs);
}
return nullptr;
}
-HRESULT GetArgNameByILIndex(MethodDesc* MethodDescPtr, unsigned index, LPSTR &paramName)
+HRESULT GetArgNameByILIndex(MethodDesc* methodDescPtr, unsigned index, NewArrayHolder<char> &paramName)
{
- IMDInternalImport* mdImport = MethodDescPtr->GetMDImport();
+ IMDInternalImport* mdImport = methodDescPtr->GetMDImport();
mdParamDef paramToken;
USHORT seq;
DWORD attr;
@@ -287,12 +254,12 @@ HRESULT GetArgNameByILIndex(MethodDesc* MethodDescPtr, unsigned index, LPSTR &pa
// Param indexing is 1-based.
ULONG32 mdIndex = index + 1;
- MetaSig sig(MethodDescPtr);
+ MetaSig sig(methodDescPtr);
if (sig.HasThis())
{
mdIndex--;
}
- status = mdImport->FindParamOfMethod(MethodDescPtr->GetMemberDef(), mdIndex, &paramToken);
+ status = mdImport->FindParamOfMethod(methodDescPtr->GetMemberDef(), mdIndex, &paramToken);
if (status == S_OK)
{
LPCSTR name;
@@ -343,14 +310,14 @@ HRESULT FindNativeInfoInILVariable(DWORD dwIndex,
BYTE* DebugInfoStoreNew(void * pData, size_t cBytes)
{
- return new (nothrow) BYTE[cBytes];
+ return new BYTE[cBytes];
}
/* Get IL to native offsets map */
HRESULT
GetMethodNativeMap(MethodDesc* methodDesc,
ULONG32* numMap,
- DebuggerILToNativeMap** map,
+ NewArrayHolder<DebuggerILToNativeMap> &map,
ULONG32* pcVars,
ICorDebugInfo::NativeVarInfo** ppVars)
{
@@ -381,33 +348,30 @@ GetMethodNativeMap(MethodDesc* methodDesc,
// Need to convert map formats.
*numMap = countMapCopy;
- *map = new (nothrow) DebuggerILToNativeMap[countMapCopy];
- if (!*map)
- {
- return E_OUTOFMEMORY;
- }
+ map = new DebuggerILToNativeMap[countMapCopy];
ULONG32 i;
for (i = 0; i < *numMap; i++)
{
- (*map)[i].ilOffset = mapCopy[i].ilOffset;
- (*map)[i].nativeStartOffset = mapCopy[i].nativeOffset;
+ map[i].ilOffset = mapCopy[i].ilOffset;
+ map[i].nativeStartOffset = mapCopy[i].nativeOffset;
if (i > 0)
{
- (*map)[i - 1].nativeEndOffset = (*map)[i].nativeStartOffset;
+ map[i - 1].nativeEndOffset = map[i].nativeStartOffset;
}
- (*map)[i].source = mapCopy[i].source;
+ map[i].source = mapCopy[i].source;
}
if (*numMap >= 1)
{
- (*map)[i - 1].nativeEndOffset = 0;
+ map[i - 1].nativeEndOffset = 0;
}
return S_OK;
}
HRESULT FunctionMember::GetLocalsDebugInfo(NotifyGdb::PTK_TypeInfoMap pTypeMap,
LocalsInfo& locals,
- int startNativeOffset)
+ int startNativeOffset,
+ FunctionMemberPtrArrayHolder &method)
{
ICorDebugInfo::NativeVarInfo* nativeVar = NULL;
@@ -422,7 +386,7 @@ HRESULT FunctionMember::GetLocalsDebugInfo(NotifyGdb::PTK_TypeInfoMap pTypeMap,
{
if (FindNativeInfoInILVariable(i + thisOffs, startNativeOffset, &locals.pVars, locals.countVars, &nativeVar) == S_OK)
{
- vars[i + thisOffs].m_var_type = GetArgTypeInfo(md, pTypeMap, i + 1);
+ vars[i + thisOffs].m_var_type = GetArgTypeInfo(md, pTypeMap, i + 1, method);
GetArgNameByILIndex(md, i + thisOffs, vars[i + thisOffs].m_var_name);
vars[i + thisOffs].m_il_index = i;
vars[i + thisOffs].m_native_offset = nativeVar->loc.vlStk.vlsOffset;
@@ -434,7 +398,10 @@ HRESULT FunctionMember::GetLocalsDebugInfo(NotifyGdb::PTK_TypeInfoMap pTypeMap,
{
if (FindNativeInfoInILVariable(0, startNativeOffset, &locals.pVars, locals.countVars, &nativeVar) == S_OK)
{
- vars[0].m_var_type = GetTypeInfoFromTypeHandle(TypeHandle(md->GetMethodTable()), pTypeMap);
+ TypeHandle th = TypeHandle(md->GetMethodTable());
+ if (th.IsValueType())
+ th = th.MakePointer();
+ vars[0].m_var_type = GetTypeInfoFromTypeHandle(th, pTypeMap, method);
vars[0].m_var_name = new char[strlen("this") + 1];
strcpy(vars[0].m_var_name, "this");
vars[0].m_il_index = 0;
@@ -448,31 +415,84 @@ HRESULT FunctionMember::GetLocalsDebugInfo(NotifyGdb::PTK_TypeInfoMap pTypeMap,
if (FindNativeInfoInILVariable(
i, startNativeOffset, &locals.pVars, locals.countVars, &nativeVar) == S_OK)
{
- vars[i].m_var_type = GetLocalTypeInfo(md, pTypeMap, i - m_num_args);
- vars[i].m_var_name = new char[strlen(locals.localsName[i - m_num_args]) + 1];
- strcpy(vars[i].m_var_name, locals.localsName[i - m_num_args]);
- vars[i].m_il_index = i - m_num_args;
+ int ilIndex = i - m_num_args;
+ vars[i].m_var_type = GetLocalTypeInfo(md, pTypeMap, ilIndex, method);
+ vars[i].m_var_name = new char[strlen(locals.localsName[ilIndex]) + 1];
+ strcpy(vars[i].m_var_name, locals.localsName[ilIndex]);
+ vars[i].m_il_index = ilIndex;
vars[i].m_native_offset = nativeVar->loc.vlStk.vlsOffset;
vars[i].m_var_abbrev = 5;
+ TADDR nativeStart;
+ TADDR nativeEnd;
+ int ilLen = locals.localsScope[ilIndex].ilEndOffset - locals.localsScope[ilIndex].ilStartOffset;
+ if (GetBlockInNativeCode(locals.localsScope[ilIndex].ilStartOffset, ilLen, &nativeStart, &nativeEnd))
+ {
+ vars[i].m_low_pc = md->GetNativeCode() + nativeStart;
+ vars[i].m_high_pc = nativeEnd - nativeStart;
+ }
}
}
return S_OK;
}
+
+MethodDebugInfo::MethodDebugInfo(int numPoints, int numLocals)
+{
+ points = (SequencePointInfo*) CoTaskMemAlloc(sizeof(SequencePointInfo) * numPoints);
+ if (points == nullptr)
+ {
+ COMPlusThrowOM();
+ }
+ memset(points, 0, sizeof(SequencePointInfo) * numPoints);
+ size = numPoints;
+
+ if (numLocals == 0)
+ {
+ locals = nullptr;
+ localsSize = 0;
+ return;
+ }
+
+ locals = (LocalVarInfo*) CoTaskMemAlloc(sizeof(LocalVarInfo) * numLocals);
+ if (locals == nullptr)
+ {
+ CoTaskMemFree(points);
+ COMPlusThrowOM();
+ }
+ memset(locals, 0, sizeof(LocalVarInfo) * numLocals);
+ localsSize = numLocals;
+}
+
+MethodDebugInfo::~MethodDebugInfo()
+{
+ if (locals)
+ {
+ for (int i = 0; i < localsSize; i++)
+ CoTaskMemFree(locals[i].name);
+ CoTaskMemFree(locals);
+ }
+
+ for (int i = 0; i < size; i++)
+ CoTaskMemFree(points[i].fileName);
+ CoTaskMemFree(points);
+}
+
/* Get mapping of IL offsets to source line numbers */
HRESULT
-GetDebugInfoFromPDB(MethodDesc* MethodDescPtr, SymbolsInfo** symInfo, unsigned int &symInfoLen, LocalsInfo &locals)
+GetDebugInfoFromPDB(MethodDesc* methodDescPtr,
+ NewArrayHolder<SymbolsInfo> &symInfo,
+ unsigned int &symInfoLen,
+ LocalsInfo &locals)
{
- DebuggerILToNativeMap* map = NULL;
-
+ NewArrayHolder<DebuggerILToNativeMap> map;
ULONG32 numMap;
if (!getInfoForMethodDelegate)
return E_FAIL;
-
- if (GetMethodNativeMap(MethodDescPtr, &numMap, &map, &locals.countVars, &locals.pVars) != S_OK)
+
+ if (GetMethodNativeMap(methodDescPtr, &numMap, map, &locals.countVars, &locals.pVars) != S_OK)
return E_FAIL;
- const Module* mod = MethodDescPtr->GetMethodTable()->GetModule();
+ const Module* mod = methodDescPtr->GetMethodTable()->GetModule();
SString modName = mod->GetFile()->GetPath();
if (modName.IsEmpty())
return E_FAIL;
@@ -480,45 +500,39 @@ GetDebugInfoFromPDB(MethodDesc* MethodDescPtr, SymbolsInfo** symInfo, unsigned i
StackScratchBuffer scratch;
const char* szModName = modName.GetUTF8(scratch);
- MethodDebugInfo methodDebugInfo;
+ MethodDebugInfo methodDebugInfo(numMap, locals.countVars);
- methodDebugInfo.points = (SequencePointInfo*) CoTaskMemAlloc(sizeof(SequencePointInfo) * numMap);
- if (methodDebugInfo.points == nullptr)
- return E_OUTOFMEMORY;
-
- methodDebugInfo.size = numMap;
-
- if (getInfoForMethodDelegate(szModName, MethodDescPtr->GetMemberDef(), methodDebugInfo) == FALSE)
+ if (getInfoForMethodDelegate(szModName, methodDescPtr->GetMemberDef(), methodDebugInfo) == FALSE)
return E_FAIL;
symInfoLen = numMap;
- *symInfo = new (nothrow) SymbolsInfo[numMap];
- if (*symInfo == nullptr)
- return E_FAIL;
+ symInfo = new SymbolsInfo[numMap];
+
locals.size = methodDebugInfo.localsSize;
- locals.localsName = new (nothrow) char *[locals.size];
- if (locals.localsName == nullptr)
- return E_FAIL;
+ locals.localsName = new NewArrayHolder<char>[locals.size];
+ locals.localsScope = new LocalsInfo::Scope [locals.size];
for (ULONG32 i = 0; i < locals.size; i++)
{
- size_t sizeRequired = WideCharToMultiByte(CP_UTF8, 0, methodDebugInfo.locals[i], -1, NULL, 0, NULL, NULL);
- locals.localsName[i] = new (nothrow) char[sizeRequired];
+ size_t sizeRequired = WideCharToMultiByte(CP_UTF8, 0, methodDebugInfo.locals[i].name, -1, NULL, 0, NULL, NULL);
+ locals.localsName[i] = new char[sizeRequired];
int len = WideCharToMultiByte(
- CP_UTF8, 0, methodDebugInfo.locals[i], -1, locals.localsName[i], sizeRequired, NULL, NULL);
+ CP_UTF8, 0, methodDebugInfo.locals[i].name, -1, locals.localsName[i], sizeRequired, NULL, NULL);
+ locals.localsScope[i].ilStartOffset = methodDebugInfo.locals[i].startOffset;
+ locals.localsScope[i].ilEndOffset = methodDebugInfo.locals[i].endOffset;
}
for (ULONG32 j = 0; j < numMap; j++)
{
- SymbolsInfo& s = (*symInfo)[j];
+ SymbolsInfo& s = symInfo[j];
if (j == 0) {
s.fileName[0] = 0;
s.lineNumber = 0;
s.fileIndex = 0;
} else {
- s = (*symInfo)[j - 1];
+ s = symInfo[j - 1];
}
s.nativeOffset = map[j].nativeStartOffset;
s.ilOffset = map[j].ilOffset;
@@ -540,7 +554,6 @@ GetDebugInfoFromPDB(MethodDesc* MethodDescPtr, SymbolsInfo** symInfo, unsigned i
}
}
- CoTaskMemFree(methodDebugInfo.points);
return S_OK;
}
@@ -709,7 +722,7 @@ const unsigned char AbbrevTable[] = {
DW_FORM_ref4, DW_AT_location, DW_FORM_exprloc, 0, 0,
7, DW_TAG_class_type, DW_CHILDREN_yes,
- DW_AT_name, DW_FORM_strp, DW_AT_byte_size, DW_FORM_data1, 0, 0,
+ DW_AT_name, DW_FORM_strp, DW_AT_byte_size, DW_FORM_data4, 0, 0,
8, DW_TAG_member, DW_CHILDREN_no,
DW_AT_name, DW_FORM_strp, DW_AT_type, DW_FORM_ref4, DW_AT_data_member_location, DW_FORM_data4, 0, 0,
@@ -750,6 +763,13 @@ const unsigned char AbbrevTable[] = {
18, DW_TAG_inheritance, DW_CHILDREN_no, DW_AT_type, DW_FORM_ref4, DW_AT_data_member_location, DW_FORM_data1,
0, 0,
+ 19, DW_TAG_subrange_type, DW_CHILDREN_no,
+ DW_AT_upper_bound, DW_FORM_udata, 0, 0,
+
+ 20, DW_TAG_lexical_block, DW_CHILDREN_yes,
+ DW_AT_low_pc, DW_FORM_addr, DW_AT_high_pc, DW_FORM_size,
+ 0, 0,
+
0
};
@@ -799,59 +819,31 @@ struct __attribute__((packed)) DebugInfoSubMember
uint32_t m_obj_ptr;
};
+struct __attribute__((packed)) DebugInfoLexicalBlock
+{
+ uint8_t m_abbrev;
+ uintptr_t m_low_pc, m_high_pc;
+};
+
// Holder for array of pointers to FunctionMember objects
-class FunctionMemberPtrArrayHolder : public NewArrayHolder<FunctionMember*>
+class FunctionMemberPtrArrayHolder : public NewArrayHolder<NewHolder<FunctionMember>>
{
private:
int m_cElements;
- void DeleteElements()
- {
- for (int i = 0; i < m_cElements; i++)
- {
- delete this->m_value[i];
- }
- }
-
public:
- FunctionMemberPtrArrayHolder() :
- NewArrayHolder<FunctionMember*>(),
- m_cElements(0)
+ explicit FunctionMemberPtrArrayHolder(int cElements) :
+ NewArrayHolder<NewHolder<FunctionMember>>(new NewHolder<FunctionMember>[cElements]),
+ m_cElements(cElements)
{
}
- bool Alloc(int cElements)
- {
- FunctionMember** value = new (nothrow) FunctionMember*[cElements];
- if (value == nullptr)
- return false;
-
- for (int i = 0; i < cElements; i++)
- {
- value[i] = nullptr;
- }
-
- // Clean previous elements
- DeleteElements();
-
- NewArrayHolder<FunctionMember*>::operator=(value);
- m_cElements = cElements;
- return true;
- }
-
int GetCount() const
{
return m_cElements;
}
-
- ~FunctionMemberPtrArrayHolder()
- {
- DeleteElements();
- }
};
-static FunctionMemberPtrArrayHolder method;
-
struct __attribute__((packed)) DebugInfoType
{
uint8_t m_type_abbrev;
@@ -879,7 +871,7 @@ struct __attribute__((packed)) DebugInfoClassType
{
uint8_t m_type_abbrev;
uint32_t m_type_name;
- uint8_t m_byte_size;
+ uint32_t m_byte_size;
};
struct __attribute__((packed)) DebugInfoInheritance
@@ -930,11 +922,33 @@ void TypeInfoBase::CalculateName()
{
// name the type
SString sName;
- typeHandle.GetName(sName);
+
+ const TypeString::FormatFlags formatFlags = static_cast<TypeString::FormatFlags>(
+ TypeString::FormatNamespace |
+ TypeString::FormatAngleBrackets);
+
+ TypeString::AppendType(sName, typeHandle, formatFlags);
+
StackScratchBuffer buffer;
const UTF8 *utf8 = sName.GetUTF8(buffer);
- m_type_name = new char[strlen(utf8) + 1];
- strcpy(m_type_name, utf8);
+ if (typeHandle.IsValueType())
+ {
+ m_type_name = new char[strlen(utf8) + 1];
+ strcpy(m_type_name, utf8);
+ }
+ else
+ {
+ m_type_name = new char[strlen(utf8) + 1 + 2];
+ strcpy(m_type_name, "__");
+ strcpy(m_type_name + 2, utf8);
+ }
+
+ // Fix nested names
+ for (char *p = m_type_name; *p; ++p)
+ {
+ if (*p == '+')
+ *p = '.';
+ }
}
void TypeInfoBase::SetTypeHandle(TypeHandle handle)
@@ -965,6 +979,11 @@ void TypeDefInfo::DumpStrings(char *ptr, int &offset)
void TypeDefInfo::DumpDebugInfo(char *ptr, int &offset)
{
+ if (m_typedef_type_offset != 0)
+ {
+ return;
+ }
+
if (ptr != nullptr)
{
DebugInfoTypeDef buf;
@@ -981,36 +1000,65 @@ void TypeDefInfo::DumpDebugInfo(char *ptr, int &offset)
offset += sizeof(DebugInfoTypeDef);
}
-void ByteTypeInfo::DumpStrings(char* ptr, int& offset)
+static const char *GetCSharpTypeName(TypeInfoBase *typeInfo)
+{
+ switch(typeInfo->GetTypeHandle().GetSignatureCorElementType())
+ {
+ case ELEMENT_TYPE_I1: return "sbyte";
+ case ELEMENT_TYPE_U1: return "byte";
+ case ELEMENT_TYPE_CHAR: return "char";
+ case ELEMENT_TYPE_VOID: return "void";
+ case ELEMENT_TYPE_BOOLEAN: return "bool";
+ case ELEMENT_TYPE_I2: return "short";
+ case ELEMENT_TYPE_U2: return "ushort";
+ case ELEMENT_TYPE_I4: return "int";
+ case ELEMENT_TYPE_U4: return "uint";
+ case ELEMENT_TYPE_I8: return "long";
+ case ELEMENT_TYPE_U8: return "ulong";
+ case ELEMENT_TYPE_R4: return "float";
+ case ELEMENT_TYPE_R8: return "double";
+ default: return typeInfo->m_type_name;
+ }
+}
+
+PrimitiveTypeInfo::PrimitiveTypeInfo(TypeHandle typeHandle)
+ : TypeInfoBase(typeHandle),
+ m_typedef_info(new TypeDefInfo(nullptr, 0))
{
- PrimitiveTypeInfo::DumpStrings(ptr, offset);
- m_typedef_info->m_typedef_name = new (nothrow) char[strlen(m_type_name) + 1];
- if (strcmp(m_type_name, "System.Byte") == 0)
- strcpy(m_typedef_info->m_typedef_name, "byte");
- else if (strcmp(m_type_name, "System.SByte") == 0)
- strcpy(m_typedef_info->m_typedef_name, "sbyte");
- else if (strcmp(m_type_name, "char16_t") == 0)
- strcpy(m_typedef_info->m_typedef_name, "char");
+ CorElementType corType = typeHandle.GetSignatureCorElementType();
+ m_type_encoding = CorElementTypeToDWEncoding[corType];
+ m_type_size = CorTypeInfo::Size(corType);
+
+ if (corType == ELEMENT_TYPE_CHAR)
+ {
+ m_type_name = new char[9];
+ strcpy(m_type_name, "char16_t");
+ }
else
- strcpy(m_typedef_info->m_typedef_name, m_type_name);
- m_typedef_info->DumpStrings(ptr, offset);
+ {
+ CalculateName();
+ }
}
-void ByteTypeInfo::DumpDebugInfo(char *ptr, int &offset)
+void PrimitiveTypeInfo::DumpStrings(char* ptr, int& offset)
{
- m_typedef_info->DumpDebugInfo(ptr, offset);
- PrimitiveTypeInfo::DumpDebugInfo(ptr, offset);
- // Replace offset from real type to typedef
- if (ptr != nullptr)
- m_type_offset = m_typedef_info->m_typedef_type_offset;
+ TypeInfoBase::DumpStrings(ptr, offset);
+ if (!m_typedef_info->m_typedef_name)
+ {
+ const char *typeName = GetCSharpTypeName(this);
+ m_typedef_info->m_typedef_name = new char[strlen(typeName) + 1];
+ strcpy(m_typedef_info->m_typedef_name, typeName);
+ }
+ m_typedef_info->DumpStrings(ptr, offset);
}
-void PrimitiveTypeInfo::DumpDebugInfo(char* ptr, int& offset)
+void PrimitiveTypeInfo::DumpDebugInfo(char *ptr, int &offset)
{
if (m_type_offset != 0)
{
return;
}
+ m_typedef_info->DumpDebugInfo(ptr, offset);
if (ptr != nullptr)
{
@@ -1027,22 +1075,37 @@ void PrimitiveTypeInfo::DumpDebugInfo(char* ptr, int& offset)
}
offset += sizeof(DebugInfoType);
+ // Replace offset from real type to typedef
+ if (ptr != nullptr)
+ m_type_offset = m_typedef_info->m_typedef_type_offset;
}
-ClassTypeInfo::ClassTypeInfo(TypeHandle typeHandle, int num_members)
+ClassTypeInfo::ClassTypeInfo(TypeHandle typeHandle, int num_members, FunctionMemberPtrArrayHolder &method)
: TypeInfoBase(typeHandle),
m_num_members(num_members),
members(new TypeMember[num_members]),
- m_parent(nullptr)
+ m_parent(nullptr),
+ m_method(method),
+ m_array_type(nullptr)
{
-}
+ CorElementType corType = typeHandle.GetSignatureCorElementType();
+ PTR_MethodTable pMT = typeHandle.GetMethodTable();
-ClassTypeInfo::~ClassTypeInfo()
-{
- if (members != nullptr && m_num_members > 0)
+ switch (corType)
{
- delete[] members;
+ case ELEMENT_TYPE_VALUETYPE:
+ case ELEMENT_TYPE_CLASS:
+ m_type_size = pMT->IsValueType() ? typeHandle.GetSize() : typeHandle.AsMethodTable()->GetClass()->GetSize();
+ break;
+ case ELEMENT_TYPE_ARRAY:
+ case ELEMENT_TYPE_SZARRAY:
+ m_type_size = pMT->GetClass()->GetSize();
+ break;
+ default:
+ m_type_size = 0;
}
+
+ CalculateName();
}
void TypeMember::DumpStrings(char* ptr, int& offset)
@@ -1295,6 +1358,68 @@ void FunctionMember::DumpTryCatchDebugInfo(char* ptr, int& offset)
}
}
+void FunctionMember::DumpVarsWithScopes(char *ptr, int &offset)
+{
+ NewArrayHolder<DebugInfoLexicalBlock> scopeStack = new DebugInfoLexicalBlock[m_num_vars];
+
+ int scopeStackSize = 0;
+ for (int i = 0; i < m_num_vars; ++i)
+ {
+ if (vars[i].m_high_pc == 0) // no scope info
+ {
+ vars[i].DumpDebugInfo(ptr, offset);
+ continue;
+ }
+
+ // Try to step out to enclosing scope, finilizing scopes on the way
+ while (scopeStackSize > 0 &&
+ vars[i].m_low_pc >= (scopeStack[scopeStackSize - 1].m_low_pc +
+ scopeStack[scopeStackSize - 1].m_high_pc))
+ {
+ // Finalize scope
+ if (ptr != nullptr)
+ {
+ memset(ptr + offset, 0, 1);
+ }
+ offset += 1;
+
+ scopeStackSize--;
+ }
+ // Continue adding to prev scope?
+ if (scopeStackSize > 0 &&
+ scopeStack[scopeStackSize - 1].m_low_pc == vars[i].m_low_pc &&
+ scopeStack[scopeStackSize - 1].m_high_pc == vars[i].m_high_pc)
+ {
+ vars[i].DumpDebugInfo(ptr, offset);
+ continue;
+ }
+ // Start new scope
+ scopeStackSize++;
+ scopeStack[scopeStackSize - 1].m_abbrev = 20;
+ scopeStack[scopeStackSize - 1].m_low_pc = vars[i].m_low_pc;
+ scopeStack[scopeStackSize - 1].m_high_pc = vars[i].m_high_pc;
+
+ if (ptr != nullptr)
+ {
+ memcpy(ptr + offset, scopeStack + (scopeStackSize - 1), sizeof(DebugInfoLexicalBlock));
+ }
+ offset += sizeof(DebugInfoLexicalBlock);
+
+ vars[i].DumpDebugInfo(ptr, offset);
+ }
+ // Finalize any remaining scopes
+ while (scopeStackSize > 0)
+ {
+ if (ptr != nullptr)
+ {
+ memset(ptr + offset, 0, 1);
+ }
+ offset += 1;
+
+ scopeStackSize--;
+ }
+}
+
void FunctionMember::DumpDebugInfo(char* ptr, int& offset)
{
if (ptr != nullptr)
@@ -1336,10 +1461,8 @@ void FunctionMember::DumpDebugInfo(char* ptr, int& offset)
{
offset += sizeof(DebugInfoSub);
}
- for (int i = 0; i < m_num_vars; ++i)
- {
- vars[i].DumpDebugInfo(ptr, offset);
- }
+
+ DumpVarsWithScopes(ptr, offset);
DumpTryCatchDebugInfo(ptr, offset);
@@ -1408,6 +1531,37 @@ void RefTypeInfo::DumpDebugInfo(char* ptr, int& offset)
m_type_offset = 0;
}
}
+
+void NamedRefTypeInfo::DumpDebugInfo(char* ptr, int& offset)
+{
+ if (m_type_offset != 0)
+ {
+ return;
+ }
+ m_type_offset = offset;
+ offset += sizeof(DebugInfoRefType) + sizeof(DebugInfoTypeDef);
+ m_value_type->DumpDebugInfo(ptr, offset);
+ if (ptr != nullptr)
+ {
+ DebugInfoRefType refType;
+ refType.m_type_abbrev = 9;
+ refType.m_ref_type = m_value_type->m_type_offset;
+ refType.m_byte_size = m_type_size;
+ memcpy(ptr + m_type_offset, &refType, sizeof(DebugInfoRefType));
+
+ DebugInfoTypeDef bugTypeDef;
+ bugTypeDef.m_typedef_abbrev = 3;
+ bugTypeDef.m_typedef_name = m_value_type->m_type_name_offset + 2;
+ bugTypeDef.m_typedef_type = m_type_offset;
+ memcpy(ptr + m_type_offset + sizeof(DebugInfoRefType), &bugTypeDef, sizeof(DebugInfoTypeDef));
+ m_type_offset += sizeof(DebugInfoRefType);
+ }
+ else
+ {
+ m_type_offset = 0;
+ }
+}
+
void ClassTypeInfo::DumpDebugInfo(char* ptr, int& offset)
{
if (m_type_offset != 0)
@@ -1454,12 +1608,12 @@ void ClassTypeInfo::DumpDebugInfo(char* ptr, int& offset)
members[i].DumpDebugInfo(ptr, offset);
}
- for (int i = 0; i < method.GetCount(); ++i)
+ for (int i = 0; i < m_method.GetCount(); ++i)
{
- if (method[i]->md->GetMethodTable() == GetTypeHandle().GetMethodTable())
+ if (m_method[i]->md->GetMethodTable() == GetTypeHandle().GetMethodTable())
{
// our method is part of this class, we should dump it now before terminating members
- method[i]->DumpDebugInfo(ptr, offset);
+ m_method[i]->DumpDebugInfo(ptr, offset);
}
}
@@ -1516,23 +1670,13 @@ void ArrayTypeInfo::DumpDebugInfo(char* ptr, int& offset)
offset += sizeof(DebugInfoArrayType);
char tmp[16] = { 0 };
- int len = Leb128Encode(static_cast<int32_t>(m_count_offset), tmp, sizeof(tmp));
+ int len = Leb128Encode(static_cast<uint32_t>(m_count - 1), tmp + 1, sizeof(tmp) - 1);
if (ptr != nullptr)
{
- char buf[64];
- buf[0] = 11; // DW_TAG_subrange_type abbrev
- buf[1] = len + 3;
- buf[2] = DW_OP_push_object_address;
- buf[3] = DW_OP_plus_uconst;
- for (int j = 0; j < len; j++)
- {
- buf[j + 4] = tmp[j];
- }
- buf[len + 4] = DW_OP_deref;
-
- memcpy(ptr + offset, buf, len + 5);
+ tmp[0] = 19; // DW_TAG_subrange_type abbrev with const upper bound
+ memcpy(ptr + offset, tmp, len + 1);
}
- offset += (len + 5);
+ offset += len + 1;
if (ptr != nullptr)
{
@@ -1577,13 +1721,8 @@ struct Elf_Symbol {
int m_off;
TADDR m_value;
int m_section, m_size;
- bool m_releaseName;
- Elf_Symbol() : m_name(nullptr), m_off(0), m_value(0), m_section(0), m_size(0), m_releaseName(false) {}
- ~Elf_Symbol()
- {
- if (m_releaseName)
- delete [] m_name;
- }
+ NewArrayHolder<char> m_symbol_name;
+ Elf_Symbol() : m_name(nullptr), m_off(0), m_value(0), m_section(0), m_size(0) {}
};
static int countFuncs(const SymbolsInfo *lines, int nlines)
@@ -1609,14 +1748,27 @@ static int getNextPrologueIndex(int from, const SymbolsInfo *lines, int nlines)
return -1;
}
-int SymbolCount = 0;
-NewArrayHolder<Elf_Symbol> SymbolNames;
-NotifyGdb::AddrSet codeAddrs;
+static NotifyGdb::AddrSet codeAddrs;
/* Create ELF/DWARF debug info for jitted method */
-void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
+void NotifyGdb::MethodCompiled(MethodDesc* methodDescPtr)
{
- PCODE pCode = MethodDescPtr->GetNativeCode();
+ EX_TRY
+ {
+ NotifyGdb::OnMethodCompiled(methodDescPtr);
+ }
+ EX_CATCH
+ {
+ }
+ EX_END_CATCH(SwallowAllExceptions);
+}
+
+void NotifyGdb::OnMethodCompiled(MethodDesc* methodDescPtr)
+{
+ int symbolCount = 0;
+ NewArrayHolder<Elf_Symbol> symbolNames;
+
+ PCODE pCode = methodDescPtr->GetNativeCode();
if (pCode == NULL)
return;
unsigned int symInfoLen = 0;
@@ -1624,14 +1776,14 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
LocalsInfo locals;
/* Get method name & size of jitted code */
- LPCUTF8 methodName = MethodDescPtr->GetName();
+ LPCUTF8 methodName = methodDescPtr->GetName();
EECodeInfo codeInfo(pCode);
TADDR codeSize = codeInfo.GetCodeManager()->GetFunctionSize(codeInfo.GetGCInfoToken());
pCode = PCODEToPINSTR(pCode);
/* Get module name */
- const Module* mod = MethodDescPtr->GetMethodTable()->GetModule();
+ const Module* mod = methodDescPtr->GetMethodTable()->GetModule();
SString modName = mod->GetFile()->GetPath();
StackScratchBuffer scratch;
const char* szModName = modName.GetUTF8(scratch);
@@ -1642,7 +1794,7 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
int length = MultiByteToWideChar(CP_UTF8, 0, szModuleFile, -1, NULL, 0);
if (length == 0)
return;
- NewArrayHolder<WCHAR> wszModuleFile = new (nothrow) WCHAR[length+1];
+ NewArrayHolder<WCHAR> wszModuleFile = new WCHAR[length+1];
length = MultiByteToWideChar(CP_UTF8, 0, szModuleFile, -1, wszModuleFile, length);
if (length == 0)
@@ -1656,7 +1808,7 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
{
cCharsNeeded = GetEnvironmentVariableW(W("CORECLR_GDBJIT"), NULL, 0);
- if((cCharsNeeded == 0) || (cCharsNeeded >= MAX_LONGPATH))
+ if(cCharsNeeded == 0)
return;
wszModuleNames = new WCHAR[cCharsNeeded+1];
cCharsNeeded = GetEnvironmentVariableW(W("CORECLR_GDBJIT"), wszModuleNames, cCharsNeeded);
@@ -1704,33 +1856,26 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
NewHolder<TK_TypeInfoMap> pTypeMap = new TK_TypeInfoMap();
- if (pTypeMap == nullptr)
- {
- return;
- }
-
/* Get debug info for method from portable PDB */
- HRESULT hr = GetDebugInfoFromPDB(MethodDescPtr, &symInfo, symInfoLen, locals);
+ HRESULT hr = GetDebugInfoFromPDB(methodDescPtr, symInfo, symInfoLen, locals);
if (FAILED(hr) || symInfoLen == 0)
{
return;
}
int method_count = countFuncs(symInfo, symInfoLen);
- if (!method.Alloc(method_count)) {
- return;
- }
+ FunctionMemberPtrArrayHolder method(method_count);
CodeHeader* pCH = (CodeHeader*)pCode - 1;
CalledMethod* pCalledMethods = reinterpret_cast<CalledMethod*>(pCH->GetCalledMethods());
/* Collect addresses of thunks called by method */
- if (!CollectCalledMethods(pCalledMethods, (TADDR)MethodDescPtr->GetNativeCode()))
+ if (!CollectCalledMethods(pCalledMethods, (TADDR)methodDescPtr->GetNativeCode(), method, symbolNames, symbolCount))
{
return;
}
pCH->SetCalledMethods(NULL);
- MetaSig sig(MethodDescPtr);
+ MetaSig sig(methodDescPtr);
int nArgsCount = sig.NumFixedArgs();
if (sig.HasThis())
nArgsCount++;
@@ -1749,7 +1894,7 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
for (int method_index = 0; method_index < method.GetCount(); ++method_index)
{
- method[method_index] = new FunctionMember(MethodDescPtr, locals.size, nArgsCount);
+ method[method_index] = new FunctionMember(methodDescPtr, locals.size, nArgsCount);
int end_index = getNextPrologueIndex(start_index + 1, symInfo, symInfoLen);
@@ -1757,10 +1902,12 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
TADDR method_size = end_index == -1 ? codeSize - method_start : symInfo[end_index].nativeOffset - method_start;
// method return type
- method[method_index]->m_member_type = GetArgTypeInfo(MethodDescPtr, pTypeMap, 0);
- method[method_index]->GetLocalsDebugInfo(pTypeMap, locals, symInfo[firstLineIndex].nativeOffset);
+ method[method_index]->m_member_type = GetArgTypeInfo(methodDescPtr, pTypeMap, 0, method);
method[method_index]->m_sub_low_pc = pCode + method_start;
method[method_index]->m_sub_high_pc = method_size;
+ method[method_index]->lines = symInfo;
+ method[method_index]->nlines = symInfoLen;
+ method[method_index]->GetLocalsDebugInfo(pTypeMap, locals, symInfo[firstLineIndex].nativeOffset, method);
size_t methodNameSize = strlen(methodName) + 10;
method[method_index]->m_member_name = new char[methodNameSize];
if (method_index == 0)
@@ -1769,7 +1916,7 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
sprintf_s(method[method_index]->m_member_name, methodNameSize, "%s_%i", methodName, method_index);
// method's class
- GetTypeInfoFromTypeHandle(TypeHandle(method[method_index]->md->GetMethodTable()), pTypeMap);
+ GetTypeInfoFromTypeHandle(TypeHandle(method[method_index]->md->GetMethodTable()), pTypeMap, method);
start_index = end_index;
}
@@ -1792,21 +1939,23 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
DebugStrings[1] = szModuleFile;
/* Build .debug_str section */
- if (!BuildDebugStrings(dbgStr, pTypeMap))
+ if (!BuildDebugStrings(dbgStr, pTypeMap, method))
{
return;
}
/* Build .debug_info section */
- if (!BuildDebugInfo(dbgInfo, pTypeMap, symInfo, symInfoLen))
+ if (!BuildDebugInfo(dbgInfo, pTypeMap, method))
{
return;
}
- for (int i = 0; i < locals.size; i++)
+ for (int i = 0; i < method.GetCount(); ++i)
{
- delete[] locals.localsName[i];
+ method[i]->lines = nullptr;
+ method[i]->nlines = 0;
}
+
/* Build .debug_pubname section */
if (!BuildDebugPub(dbgPubname, methodName, dbgInfo.MemSize, 0x28))
{
@@ -1820,29 +1969,26 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
}
/* Build .strtab section */
- SymbolNames[0].m_name = "";
+ symbolNames[0].m_name = "";
for (int i = 0; i < method.GetCount(); ++i)
{
- SymbolNames[1 + i].m_name = method[i]->m_member_name;
- SymbolNames[1 + i].m_value = method[i]->m_sub_low_pc;
- SymbolNames[1 + i].m_section = 1;
- SymbolNames[1 + i].m_size = method[i]->m_sub_high_pc;
+ symbolNames[1 + i].m_name = method[i]->m_member_name;
+ symbolNames[1 + i].m_value = method[i]->m_sub_low_pc;
+ symbolNames[1 + i].m_section = 1;
+ symbolNames[1 + i].m_size = method[i]->m_sub_high_pc;
}
- if (!BuildStringTableSection(sectStrTab))
+ if (!BuildStringTableSection(sectStrTab, symbolNames, symbolCount))
{
return;
}
/* Build .symtab section */
- if (!BuildSymbolTableSection(sectSymTab, pCode, codeSize))
+ if (!BuildSymbolTableSection(sectSymTab, pCode, codeSize, method, symbolNames, symbolCount))
{
return;
}
/* Build section headers table and section names table */
- if (!BuildSectionTables(sectHeaders, sectStr))
- {
- return;
- }
+ BuildSectionTables(sectHeaders, sectStr, method, symbolCount);
/* Patch section offsets & sizes */
long offset = sizeof(Elf_Ehdr);
@@ -1889,10 +2035,10 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
offset += sectStrTab.MemSize;
// .thunks
- for (int i = 1 + method.GetCount(); i < SymbolCount; i++)
+ for (int i = 1 + method.GetCount(); i < symbolCount; i++)
{
++pShdr;
- pShdr->sh_addr = PCODEToPINSTR(SymbolNames[i].m_value);
+ pShdr->sh_addr = PCODEToPINSTR(symbolNames[i].m_value);
pShdr->sh_size = 8;
}
@@ -1912,7 +2058,7 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
#endif
header->e_shoff = offset;
header->e_shentsize = sizeof(Elf_Shdr);
- int thunks_count = SymbolCount - method.GetCount() - 1;
+ int thunks_count = symbolCount - method.GetCount() - 1;
header->e_shnum = SectionNamesCount + thunks_count;
header->e_shstrndx = GetSectionIndex(".shstrtab");
@@ -1920,12 +2066,8 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
elfFile.MemSize = elfHeader.MemSize + sectStr.MemSize + dbgStr.MemSize + dbgAbbrev.MemSize + dbgInfo.MemSize +
dbgPubname.MemSize + dbgPubType.MemSize + dbgLine.MemSize + sectSymTab.MemSize +
sectStrTab.MemSize + sectHeaders.MemSize;
- elfFile.MemPtr = new (nothrow) char[elfFile.MemSize];
- if (elfFile.MemPtr == nullptr)
- {
- return;
- }
-
+ elfFile.MemPtr = new char[elfFile.MemSize];
+
/* Copy section data */
offset = 0;
memcpy(elfFile.MemPtr, elfHeader.MemPtr, elfHeader.MemSize);
@@ -1958,13 +2100,8 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
#endif
/* Create GDB JIT structures */
- NewHolder<jit_code_entry> jit_symbols = new (nothrow) jit_code_entry;
-
- if (jit_symbols == nullptr)
- {
- return;
- }
-
+ NewHolder<jit_code_entry> jit_symbols = new jit_code_entry;
+
/* Fill the new entry */
jit_symbols->next_entry = jit_symbols->prev_entry = 0;
jit_symbols->symfile_addr = elfFile.MemPtr;
@@ -1987,14 +2124,14 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
__jit_debug_register_code();
}
-void NotifyGdb::MethodDropped(MethodDesc* MethodDescPtr)
+void NotifyGdb::MethodDropped(MethodDesc* methodDescPtr)
{
static const int textSectionIndex = GetSectionIndex(".text");
if (textSectionIndex < 0)
return;
- PCODE pCode = MethodDescPtr->GetNativeCode();
+ PCODE pCode = methodDescPtr->GetNativeCode();
if (pCode == NULL)
return;
@@ -2044,13 +2181,8 @@ bool NotifyGdb::BuildLineTable(MemBuf& buf, PCODE startAddr, TADDR codeSize, Sym
}
buf.MemSize = sizeof(DwarfLineNumHeader) + 1 + fileTable.MemSize + lineProg.MemSize;
- buf.MemPtr = new (nothrow) char[buf.MemSize];
-
- if (buf.MemPtr == nullptr)
- {
- return false;
- }
-
+ buf.MemPtr = new char[buf.MemSize];
+
/* Fill the line info header */
DwarfLineNumHeader* header = reinterpret_cast<DwarfLineNumHeader*>(buf.MemPtr.GetValue());
memcpy(buf.MemPtr, &LineNumHeader, sizeof(DwarfLineNumHeader));
@@ -2072,7 +2204,7 @@ bool NotifyGdb::BuildFileTable(MemBuf& buf, SymbolsInfo* lines, unsigned nlines)
unsigned nfiles = 0;
/* GetValue file names and replace them with indices in file table */
- files = new (nothrow) const char*[nlines];
+ files = new const char*[nlines];
if (files == nullptr)
return false;
for (unsigned i = 0; i < nlines; ++i)
@@ -2112,13 +2244,8 @@ bool NotifyGdb::BuildFileTable(MemBuf& buf, SymbolsInfo* lines, unsigned nlines)
totalSize += 1;
buf.MemSize = totalSize;
- buf.MemPtr = new (nothrow) char[buf.MemSize];
-
- if (buf.MemPtr == nullptr)
- {
- return false;
- }
-
+ buf.MemPtr = new char[buf.MemSize];
+
/* copy collected file names */
char *ptr = buf.MemPtr;
for (unsigned i = 0; i < nfiles; ++i)
@@ -2231,7 +2358,7 @@ bool NotifyGdb::BuildLineProg(MemBuf& buf, PCODE startAddr, TADDR codeSize, Symb
+ nlines * 1 /* copy commands */
+ 6 /* advance PC command */
+ 3; /* end of sequence command */
- buf.MemPtr = new (nothrow) char[buf.MemSize];
+ buf.MemPtr = new char[buf.MemSize];
char* ptr = buf.MemPtr;
if (buf.MemPtr == nullptr)
@@ -2289,7 +2416,7 @@ bool NotifyGdb::BuildLineProg(MemBuf& buf, PCODE startAddr, TADDR codeSize, Symb
}
/* Build the DWARF .debug_str section */
-bool NotifyGdb::BuildDebugStrings(MemBuf& buf, PTK_TypeInfoMap pTypeMap)
+bool NotifyGdb::BuildDebugStrings(MemBuf& buf, PTK_TypeInfoMap pTypeMap, FunctionMemberPtrArrayHolder &method)
{
int totalLength = 0;
@@ -2315,10 +2442,7 @@ bool NotifyGdb::BuildDebugStrings(MemBuf& buf, PTK_TypeInfoMap pTypeMap)
}
buf.MemSize = totalLength;
- buf.MemPtr = new (nothrow) char[totalLength];
-
- if (buf.MemPtr == nullptr)
- return false;
+ buf.MemPtr = new char[totalLength];
/* copy strings */
char* bufPtr = buf.MemPtr;
@@ -2350,18 +2474,15 @@ bool NotifyGdb::BuildDebugStrings(MemBuf& buf, PTK_TypeInfoMap pTypeMap)
/* Build the DWARF .debug_abbrev section */
bool NotifyGdb::BuildDebugAbbrev(MemBuf& buf)
{
- buf.MemPtr = new (nothrow) char[AbbrevTableSize];
+ buf.MemPtr = new char[AbbrevTableSize];
buf.MemSize = AbbrevTableSize;
- if (buf.MemPtr == nullptr)
- return false;
-
memcpy(buf.MemPtr, AbbrevTable, AbbrevTableSize);
return true;
}
/* Build tge DWARF .debug_info section */
-bool NotifyGdb::BuildDebugInfo(MemBuf& buf, PTK_TypeInfoMap pTypeMap, SymbolsInfo* lines, unsigned nlines)
+bool NotifyGdb::BuildDebugInfo(MemBuf& buf, PTK_TypeInfoMap pTypeMap, FunctionMemberPtrArrayHolder &method)
{
int totalTypeVarSubSize = 0;
{
@@ -2376,29 +2497,13 @@ bool NotifyGdb::BuildDebugInfo(MemBuf& buf, PTK_TypeInfoMap pTypeMap, SymbolsInf
for (int i = 0; i < method.GetCount(); ++i)
{
- method[i]->lines = lines;
- method[i]->nlines = nlines;
method[i]->DumpDebugInfo(nullptr, totalTypeVarSubSize);
}
- // Drop pointers to lines when exiting current scope
- struct DropMethodLines
- {
- ~DropMethodLines()
- {
- for (int i = 0; i < method.GetCount(); ++i)
- {
- method[i]->lines = nullptr;
- method[i]->nlines = 0;
- }
- }
- } dropMethodLines;
//int locSize = GetArgsAndLocalsLen(argsDebug, argsDebugSize, localsDebug, localsDebugSize);
buf.MemSize = sizeof(DwarfCompUnit) + sizeof(DebugInfoCU) + totalTypeVarSubSize + 2;
- buf.MemPtr = new (nothrow) char[buf.MemSize];
+ buf.MemPtr = new char[buf.MemSize];
- if (buf.MemPtr == nullptr)
- return false;
int offset = 0;
/* Compile uint header */
DwarfCompUnit* cu = reinterpret_cast<DwarfCompUnit*>(buf.MemPtr.GetValue());
@@ -2443,10 +2548,7 @@ bool NotifyGdb::BuildDebugPub(MemBuf& buf, const char* name, uint32_t size, uint
uint32_t length = sizeof(DwarfPubHeader) + sizeof(uint32_t) + strlen(name) + 1 + sizeof(uint32_t);
buf.MemSize = length;
- buf.MemPtr = new (nothrow) char[buf.MemSize];
-
- if (buf.MemPtr == nullptr)
- return false;
+ buf.MemPtr = new char[buf.MemSize];
DwarfPubHeader* header = reinterpret_cast<DwarfPubHeader*>(buf.MemPtr.GetValue());
header->m_length = length - sizeof(uint32_t);
@@ -2461,7 +2563,11 @@ bool NotifyGdb::BuildDebugPub(MemBuf& buf, const char* name, uint32_t size, uint
}
/* Store addresses and names of the called methods into symbol table */
-bool NotifyGdb::CollectCalledMethods(CalledMethod* pCalledMethods, TADDR nativeCode)
+bool NotifyGdb::CollectCalledMethods(CalledMethod* pCalledMethods,
+ TADDR nativeCode,
+ FunctionMemberPtrArrayHolder &method,
+ NewArrayHolder<Elf_Symbol> &symbolNames,
+ int &symbolCount)
{
AddrSet tmpCodeAddrs;
@@ -2480,12 +2586,12 @@ bool NotifyGdb::CollectCalledMethods(CalledMethod* pCalledMethods, TADDR nativeC
pList = pList->GetNext();
}
- SymbolCount = 1 + method.GetCount() + tmpCodeAddrs.GetCount();
- SymbolNames = new (nothrow) Elf_Symbol[SymbolCount];
+ symbolCount = 1 + method.GetCount() + tmpCodeAddrs.GetCount();
+ symbolNames = new Elf_Symbol[symbolCount];
pList = pCalledMethods;
int i = 1 + method.GetCount();
- while (i < SymbolCount && pList != NULL)
+ while (i < symbolCount && pList != NULL)
{
TADDR callAddr = (TADDR)pList->GetCallAddr();
if (!codeAddrs.Contains(callAddr))
@@ -2493,39 +2599,36 @@ bool NotifyGdb::CollectCalledMethods(CalledMethod* pCalledMethods, TADDR nativeC
MethodDesc* pMD = pList->GetMethodDesc();
LPCUTF8 methodName = pMD->GetName();
int symbolNameLength = strlen(methodName) + sizeof("__thunk_");
- SymbolNames[i].m_name = new char[symbolNameLength];
- SymbolNames[i].m_releaseName = true;
- sprintf_s((char*)SymbolNames[i].m_name, symbolNameLength, "__thunk_%s", methodName);
- SymbolNames[i].m_value = callAddr;
+ symbolNames[i].m_symbol_name = new char[symbolNameLength];
+ symbolNames[i].m_name = symbolNames[i].m_symbol_name;
+ sprintf_s((char*)symbolNames[i].m_name, symbolNameLength, "__thunk_%s", methodName);
+ symbolNames[i].m_value = callAddr;
++i;
codeAddrs.Add(callAddr);
}
- CalledMethod* ptr = pList;
pList = pList->GetNext();
- delete ptr;
}
- SymbolCount = i;
+ symbolCount = i;
return true;
}
/* Build ELF .strtab section */
-bool NotifyGdb::BuildStringTableSection(MemBuf& buf)
+bool NotifyGdb::BuildStringTableSection(MemBuf& buf, NewArrayHolder<Elf_Symbol> &symbolNames, int symbolCount)
{
int len = 0;
- for (int i = 0; i < SymbolCount; ++i)
- len += strlen(SymbolNames[i].m_name) + 1;
+ for (int i = 0; i < symbolCount; ++i)
+ len += strlen(symbolNames[i].m_name) + 1;
len++; // end table with zero-length string
buf.MemSize = len;
- buf.MemPtr = new (nothrow) char[buf.MemSize];
- if (buf.MemPtr == nullptr)
- return false;
+ buf.MemPtr = new char[buf.MemSize];
+
char* ptr = buf.MemPtr;
- for (int i = 0; i < SymbolCount; ++i)
+ for (int i = 0; i < symbolCount; ++i)
{
- SymbolNames[i].m_off = ptr - buf.MemPtr;
- strcpy(ptr, SymbolNames[i].m_name);
- ptr += strlen(SymbolNames[i].m_name) + 1;
+ symbolNames[i].m_off = ptr - buf.MemPtr;
+ strcpy(ptr, symbolNames[i].m_name);
+ ptr += strlen(symbolNames[i].m_name) + 1;
}
buf.MemPtr[buf.MemSize-1] = 0;
@@ -2533,14 +2636,13 @@ bool NotifyGdb::BuildStringTableSection(MemBuf& buf)
}
/* Build ELF .symtab section */
-bool NotifyGdb::BuildSymbolTableSection(MemBuf& buf, PCODE addr, TADDR codeSize)
+bool NotifyGdb::BuildSymbolTableSection(MemBuf& buf, PCODE addr, TADDR codeSize, FunctionMemberPtrArrayHolder &method,
+ NewArrayHolder<Elf_Symbol> &symbolNames, int symbolCount)
{
static const int textSectionIndex = GetSectionIndex(".text");
- buf.MemSize = SymbolCount * sizeof(Elf_Sym);
- buf.MemPtr = new (nothrow) char[buf.MemSize];
- if (buf.MemPtr == nullptr)
- return false;
+ buf.MemSize = symbolCount * sizeof(Elf_Sym);
+ buf.MemPtr = new char[buf.MemSize];
Elf_Sym *sym = reinterpret_cast<Elf_Sym*>(buf.MemPtr.GetValue());
@@ -2553,17 +2655,17 @@ bool NotifyGdb::BuildSymbolTableSection(MemBuf& buf, PCODE addr, TADDR codeSize)
for (int i = 1; i < 1 + method.GetCount(); ++i)
{
- sym[i].st_name = SymbolNames[i].m_off;
+ sym[i].st_name = symbolNames[i].m_off;
sym[i].setBindingAndType(STB_GLOBAL, STT_FUNC);
sym[i].st_other = 0;
- sym[i].st_value = PINSTRToPCODE(SymbolNames[i].m_value - addr);
+ sym[i].st_value = PINSTRToPCODE(symbolNames[i].m_value - addr);
sym[i].st_shndx = textSectionIndex;
- sym[i].st_size = SymbolNames[i].m_size;
+ sym[i].st_size = symbolNames[i].m_size;
}
- for (int i = 1 + method.GetCount(); i < SymbolCount; ++i)
+ for (int i = 1 + method.GetCount(); i < symbolCount; ++i)
{
- sym[i].st_name = SymbolNames[i].m_off;
+ sym[i].st_name = symbolNames[i].m_off;
sym[i].setBindingAndType(STB_GLOBAL, STT_FUNC);
sym[i].st_other = 0;
sym[i].st_shndx = SectionNamesCount + (i - (1 + method.GetCount())); // .thunks section index
@@ -2586,28 +2688,21 @@ int NotifyGdb::GetSectionIndex(const char *sectName)
}
/* Build the ELF section headers table and section names table */
-bool NotifyGdb::BuildSectionTables(MemBuf& sectBuf, MemBuf& strBuf)
+void NotifyGdb::BuildSectionTables(MemBuf& sectBuf, MemBuf& strBuf, FunctionMemberPtrArrayHolder &method,
+ int symbolCount)
{
static const int symtabSectionIndex = GetSectionIndex(".symtab");
static const int nullSectionIndex = GetSectionIndex("");
- const int thunks_count = SymbolCount - 1 - method.GetCount();
+ const int thunks_count = symbolCount - 1 - method.GetCount();
// Approximate length of single section name.
// Used only to reduce memory reallocations.
static const int SECT_NAME_LENGTH = 11;
- if (!strBuf.Resize(SECT_NAME_LENGTH * (SectionNamesCount + thunks_count)))
- {
- return false;
- }
-
- Elf_Shdr* sectionHeaders = new (nothrow) Elf_Shdr[SectionNamesCount + thunks_count];
- if (sectionHeaders == nullptr)
- {
- return false;
- }
+ strBuf.Resize(SECT_NAME_LENGTH * (SectionNamesCount + thunks_count));
+ Elf_Shdr* sectionHeaders = new Elf_Shdr[SectionNamesCount + thunks_count];
sectBuf.MemPtr = reinterpret_cast<char*>(sectionHeaders);
sectBuf.MemSize = sizeof(Elf_Shdr) * (SectionNamesCount + thunks_count);
@@ -2642,8 +2737,7 @@ bool NotifyGdb::BuildSectionTables(MemBuf& sectBuf, MemBuf& strBuf)
if (sectNameOffset > strBuf.MemSize)
{
// Allocate more memory for remaining section names
- if (!strBuf.Resize(sectNameOffset + addSize))
- return false;
+ strBuf.Resize(sectNameOffset + addSize);
addSize *= 2;
}
@@ -2665,19 +2759,12 @@ bool NotifyGdb::BuildSectionTables(MemBuf& sectBuf, MemBuf& strBuf)
// Set actual used size to avoid garbage in ELF section
strBuf.MemSize = sectNameOffset;
- return true;
}
/* Build the ELF header */
bool NotifyGdb::BuildELFHeader(MemBuf& buf)
{
- Elf_Ehdr* header = new (nothrow) Elf_Ehdr;
-
- if (header == nullptr)
- {
- return false;
- }
-
+ Elf_Ehdr* header = new Elf_Ehdr;
buf.MemPtr = reinterpret_cast<char*>(header);
buf.MemSize = sizeof(Elf_Ehdr);
return true;
diff --git a/src/vm/gdbjit.h b/src/vm/gdbjit.h
index 1bc75772b6..84b910932c 100644
--- a/src/vm/gdbjit.h
+++ b/src/vm/gdbjit.h
@@ -123,13 +123,20 @@ public:
virtual void DumpStrings(char* ptr, int& offset) = 0;
virtual void DumpDebugInfo(char* ptr, int& offset) = 0;
+
+ virtual ~DwarfDumpable() {}
};
-class LocalsInfo
+class LocalsInfo
{
public:
+ struct Scope {
+ int ilStartOffset;
+ int ilEndOffset;
+ };
int size;
- char** localsName;
+ NewArrayHolder< NewArrayHolder<char> > localsName;
+ NewArrayHolder<Scope> localsScope;
ULONG32 countVars;
ICorDebugInfo::NativeVarInfo *pVars;
};
@@ -149,21 +156,13 @@ public:
{
}
- virtual ~TypeInfoBase()
- {
- if (m_type_name != nullptr)
- {
- delete[] m_type_name;
- }
- }
-
virtual void DumpStrings(char* ptr, int& offset) override;
void CalculateName();
void SetTypeHandle(TypeHandle handle);
TypeHandle GetTypeHandle();
TypeKey* GetTypeKey();
- char* m_type_name;
+ NewArrayHolder<char> m_type_name;
int m_type_name_offset;
ULONG m_type_size;
int m_type_offset;
@@ -172,55 +171,30 @@ private:
TypeKey typeKey;
};
-class PrimitiveTypeInfo: public TypeInfoBase
-{
-public:
- PrimitiveTypeInfo(TypeHandle typeHandle, int encoding)
- : TypeInfoBase(typeHandle),
- m_type_encoding(encoding)
- {
- }
-
- void DumpDebugInfo(char* ptr, int& offset) override;
-
- int m_type_encoding;
-};
-
class TypeDefInfo : public DwarfDumpable
{
public:
TypeDefInfo(char *typedef_name,int typedef_type):
- m_typedef_name(typedef_name), m_typedef_type(typedef_type) {}
+ m_typedef_name(typedef_name), m_typedef_type(typedef_type), m_typedef_type_offset(0) {}
void DumpStrings(char* ptr, int& offset) override;
void DumpDebugInfo(char* ptr, int& offset) override;
- virtual ~TypeDefInfo()
- {
- if (m_typedef_name != nullptr)
- {
- delete [] m_typedef_name;
- }
- }
- char *m_typedef_name;
+
+ NewArrayHolder<char> m_typedef_name;
int m_typedef_type;
int m_typedef_type_offset;
int m_typedef_name_offset;
};
-class ByteTypeInfo : public PrimitiveTypeInfo
+class PrimitiveTypeInfo: public TypeInfoBase
{
public:
- ByteTypeInfo(TypeHandle typeHandle, int encoding) : PrimitiveTypeInfo(typeHandle, encoding)
- {
- m_typedef_info = new (nothrow) TypeDefInfo(nullptr, 0);
- }
- virtual ~ByteTypeInfo()
- {
- delete m_typedef_info;
- }
+ PrimitiveTypeInfo(TypeHandle typeHandle);
+
void DumpDebugInfo(char* ptr, int& offset) override;
void DumpStrings(char* ptr, int& offset) override;
- TypeDefInfo* m_typedef_info;
+ int m_type_encoding;
+ NewHolder<TypeDefInfo> m_typedef_info;
};
class RefTypeInfo: public TypeInfoBase
@@ -230,24 +204,44 @@ public:
: TypeInfoBase(typeHandle),
m_value_type(value_type)
{
+ m_type_size = sizeof(TADDR);
+ CalculateName();
}
void DumpStrings(char* ptr, int& offset) override;
void DumpDebugInfo(char* ptr, int& offset) override;
TypeInfoBase *m_value_type;
};
+class NamedRefTypeInfo: public RefTypeInfo
+{
+public:
+ NamedRefTypeInfo(TypeHandle typeHandle, TypeInfoBase *value_type)
+ : RefTypeInfo(typeHandle, value_type), m_value_type_storage(value_type)
+ {
+ }
+
+ void DumpDebugInfo(char* ptr, int& offset) override;
+
+ NewHolder<TypeInfoBase> m_value_type_storage;
+};
+
+class FunctionMemberPtrArrayHolder;
+class ArrayTypeInfo;
+
class ClassTypeInfo: public TypeInfoBase
{
public:
- ClassTypeInfo(TypeHandle typeHandle, int num_members);
- ~ClassTypeInfo();
+ ClassTypeInfo(TypeHandle typeHandle, int num_members, FunctionMemberPtrArrayHolder &method);
void DumpStrings(char* ptr, int& offset) override;
void DumpDebugInfo(char* ptr, int& offset) override;
int m_num_members;
- TypeMember* members;
+ NewArrayHolder<TypeMember> members;
TypeInfoBase* m_parent;
+ FunctionMemberPtrArrayHolder &m_method;
+ NewHolder<ArrayTypeInfo> m_array_type;
+ NewHolder<ArrayTypeInfo> m_array_bounds_type;
};
class TypeMember: public DwarfDumpable
@@ -262,19 +256,11 @@ public:
{
}
- ~TypeMember()
- {
- if (m_member_name != nullptr)
- {
- delete[] m_member_name;
- }
- }
-
void DumpStrings(char* ptr, int& offset) override;
void DumpDebugInfo(char* ptr, int& offset) override;
void DumpStaticDebugInfo(char* ptr, int& offset);
- char* m_member_name;
+ NewArrayHolder<char> m_member_name;
int m_member_name_offset;
int m_member_offset;
TADDR m_static_member_address;
@@ -284,24 +270,16 @@ public:
class ArrayTypeInfo: public TypeInfoBase
{
public:
- ArrayTypeInfo(TypeHandle typeHandle, int countOffset, TypeInfoBase* elemType)
+ ArrayTypeInfo(TypeHandle typeHandle, int count, TypeInfoBase* elemType)
: TypeInfoBase(typeHandle),
- m_count_offset(countOffset),
+ m_count(count),
m_elem_type(elemType)
{
}
- ~ArrayTypeInfo()
- {
- if (m_elem_type != nullptr)
- {
- delete m_elem_type;
- }
- }
-
void DumpDebugInfo(char* ptr, int& offset) override;
- int m_count_offset;
+ int m_count;
TypeInfoBase *m_elem_type;
};
@@ -314,7 +292,9 @@ public:
m_var_name_offset(0),
m_il_index(0),
m_native_offset(0),
- m_var_type(nullptr)
+ m_var_type(nullptr),
+ m_low_pc(0),
+ m_high_pc(0)
{
}
@@ -324,31 +304,32 @@ public:
m_var_name_offset(0),
m_il_index(0),
m_native_offset(0),
- m_var_type(nullptr)
- {
- }
-
- virtual ~VarDebugInfo()
+ m_var_type(nullptr),
+ m_low_pc(0),
+ m_high_pc(0)
{
- delete[] m_var_name;
}
void DumpStrings(char* ptr, int& offset) override;
void DumpDebugInfo(char* ptr, int& offset) override;
- char* m_var_name;
+ NewArrayHolder<char> m_var_name;
int m_var_abbrev;
int m_var_name_offset;
int m_il_index;
int m_native_offset;
TypeInfoBase *m_var_type;
+ uintptr_t m_low_pc;
+ uintptr_t m_high_pc;
};
+struct Elf_Symbol;
+
class NotifyGdb
{
public:
- static void MethodCompiled(MethodDesc* MethodDescPtr);
- static void MethodDropped(MethodDesc* MethodDescPtr);
+ static void MethodCompiled(MethodDesc* methodDescPtr);
+ static void MethodDropped(MethodDesc* methodDescPtr);
template <typename PARENT_TRAITS>
class DeleteValuesOnDestructSHashTraits : public PARENT_TRAITS
{
@@ -406,32 +387,33 @@ private:
unsigned MemSize;
MemBuf() : MemPtr(0), MemSize(0)
{}
- bool Resize(unsigned newSize)
+ void Resize(unsigned newSize)
{
if (newSize == 0)
{
MemPtr = nullptr;
MemSize = 0;
- return true;
+ return;
}
- char *tmp = new (nothrow) char [newSize];
- if (tmp == nullptr)
- return false;
+ char *tmp = new char [newSize];
memmove(tmp, MemPtr.GetValue(), newSize < MemSize ? newSize : MemSize);
MemPtr = tmp;
MemSize = newSize;
- return true;
}
};
+ static void OnMethodCompiled(MethodDesc* methodDescPtr);
+
static int GetSectionIndex(const char *sectName);
static bool BuildELFHeader(MemBuf& buf);
- static bool BuildSectionTables(MemBuf& sectBuf, MemBuf& strBuf);
- static bool BuildSymbolTableSection(MemBuf& buf, PCODE addr, TADDR codeSize);
- static bool BuildStringTableSection(MemBuf& strTab);
- static bool BuildDebugStrings(MemBuf& buf, PTK_TypeInfoMap pTypeMap);
+ static void BuildSectionTables(MemBuf& sectBuf, MemBuf& strBuf, FunctionMemberPtrArrayHolder &method,
+ int symbolCount);
+ static bool BuildSymbolTableSection(MemBuf& buf, PCODE addr, TADDR codeSize, FunctionMemberPtrArrayHolder &method,
+ NewArrayHolder<Elf_Symbol> &symbolNames, int symbolCount);
+ static bool BuildStringTableSection(MemBuf& strTab, NewArrayHolder<Elf_Symbol> &symbolNames, int symbolCount);
+ static bool BuildDebugStrings(MemBuf& buf, PTK_TypeInfoMap pTypeMap, FunctionMemberPtrArrayHolder &method);
static bool BuildDebugAbbrev(MemBuf& buf);
- static bool BuildDebugInfo(MemBuf& buf, PTK_TypeInfoMap pTypeMap, SymbolsInfo* lines, unsigned nlines);
+ static bool BuildDebugInfo(MemBuf& buf, PTK_TypeInfoMap pTypeMap, FunctionMemberPtrArrayHolder &method);
static bool BuildDebugPub(MemBuf& buf, const char* name, uint32_t size, uint32_t dieOffset);
static bool BuildLineTable(MemBuf& buf, PCODE startAddr, TADDR codeSize, SymbolsInfo* lines, unsigned nlines);
static bool BuildFileTable(MemBuf& buf, SymbolsInfo* lines, unsigned nlines);
@@ -441,7 +423,8 @@ private:
static void IssueSimpleCommand(char*& ptr, uint8_t command);
static void IssueParamCommand(char*& ptr, uint8_t command, char* param, int param_len);
static void SplitPathname(const char* path, const char*& pathName, const char*& fileName);
- static bool CollectCalledMethods(CalledMethod* pCM, TADDR nativeCode);
+ static bool CollectCalledMethods(CalledMethod* pCM, TADDR nativeCode, FunctionMemberPtrArrayHolder &method,
+ NewArrayHolder<Elf_Symbol> &symbolNames, int &symbolCount);
#ifdef _DEBUG
static void DumpElf(const char* methodName, const MemBuf& buf);
#endif
@@ -473,6 +456,8 @@ public:
m_sub_loc[1] = DW_OP_reg6;
#elif defined(_TARGET_X86_)
m_sub_loc[1] = DW_OP_reg5;
+#elif defined(_TARGET_ARM64_)
+ m_sub_loc[1] = DW_OP_reg29;
#elif defined(_TARGET_ARM_)
m_sub_loc[1] = DW_OP_reg11;
#else
@@ -480,17 +465,13 @@ public:
#endif
}
- virtual ~FunctionMember()
- {
- delete[] vars;
- }
-
void DumpStrings(char* ptr, int& offset) override;
void DumpDebugInfo(char* ptr, int& offset) override;
void DumpTryCatchDebugInfo(char* ptr, int& offset);
HRESULT GetLocalsDebugInfo(NotifyGdb::PTK_TypeInfoMap pTypeMap,
LocalsInfo& locals,
- int startNativeOffset);
+ int startNativeOffset,
+ FunctionMemberPtrArrayHolder &method);
BOOL IsDumped()
{
return dumped;
@@ -504,7 +485,7 @@ public:
uint8_t m_num_locals;
uint16_t m_num_vars;
int m_entry_offset;
- VarDebugInfo* vars;
+ NewArrayHolder<VarDebugInfo> vars;
SymbolsInfo* lines;
unsigned nlines;
int m_linkage_name_offset;
@@ -515,6 +496,7 @@ private:
void DumpLinkageName(char* ptr, int& offset);
bool GetBlockInNativeCode(int blockILOffset, int blockILLen, TADDR *startOffset, TADDR *endOffset);
void DumpTryCatchBlock(char* ptr, int& offset, int ilOffset, int ilLen, int abbrev);
+ void DumpVarsWithScopes(char* ptr, int& offset);
BOOL dumped;
};
#endif // #ifndef __GDBJIT_H__
diff --git a/src/vm/gdbjithelpers.h b/src/vm/gdbjithelpers.h
index 3a34dd179a..b5612a1b7b 100644
--- a/src/vm/gdbjithelpers.h
+++ b/src/vm/gdbjithelpers.h
@@ -19,15 +19,25 @@ struct SequencePointInfo
char16_t* fileName;
};
+struct LocalVarInfo
+{
+ int startOffset;
+ int endOffset;
+ char16_t *name;
+};
+
struct MethodDebugInfo
{
SequencePointInfo* points;
int size;
- char16_t** locals;
+ LocalVarInfo* locals;
int localsSize;
+
+ MethodDebugInfo(int numPoints, int numLocals);
+ ~MethodDebugInfo();
};
-typedef BOOL (*GetInfoForMethodDelegate)(const char*, unsigned int, MethodDebugInfo& methodDebugInfo);
+typedef BOOL (CALLBACK *GetInfoForMethodDelegate)(const char*, unsigned int, MethodDebugInfo& methodDebugInfo);
extern GetInfoForMethodDelegate getInfoForMethodDelegate;
#endif // !__GDBJITHELPERS_H__
diff --git a/src/vm/generics.cpp b/src/vm/generics.cpp
index 3ff3d5aa2e..a04bde19fd 100644
--- a/src/vm/generics.cpp
+++ b/src/vm/generics.cpp
@@ -224,13 +224,8 @@ ClassLoader::CreateTypeHandleForNonCanonicalGenericInstantiation(
// These are all copied across from the old MT, i.e. don't depend on the
// instantiation.
-#ifdef FEATURE_REMOTING
- BOOL fHasRemotingVtsInfo = pOldMT->HasRemotingVtsInfo();
- BOOL fHasContextStatics = pOldMT->HasContextStatics();
-#else
BOOL fHasRemotingVtsInfo = FALSE;
BOOL fHasContextStatics = FALSE;
-#endif
BOOL fHasGenericsStaticsInfo = pOldMT->HasGenericsStaticsInfo();
BOOL fHasThreadStatics = (pOldMT->GetNumThreadStaticFields() > 0);
@@ -479,12 +474,6 @@ ClassLoader::CreateTypeHandleForNonCanonicalGenericInstantiation(
// enum_flag_NGEN_NeedsRestore
#endif // FEATURE_PREJIT
-#if defined(_DEBUG) && defined (FEATURE_REMOTING)
- if (pOldMT->IsContextful() || pOldMT->GetClass()->HasRemotingProxyAttribute())
- {
- _ASSERTE(pOldMT->RequiresManagedActivation());
- }
-#endif // _DEBUG
if (pOldMT->RequiresManagedActivation())
{
// Will also set enum_flag_RemotingConfigChecked
@@ -497,12 +486,6 @@ ClassLoader::CreateTypeHandleForNonCanonicalGenericInstantiation(
if (fHasGenericsStaticsInfo)
pMT->SetDynamicStatics(TRUE);
-#ifdef FEATURE_REMOTING
- if (fHasRemotingVtsInfo)
- pMT->SetHasRemotingVtsInfo();
- if (fHasContextStatics)
- pMT->SetHasContextStatics();
-#endif
#ifdef FEATURE_COMINTEROP
if (fHasCCWTemplate)
@@ -621,35 +604,12 @@ ClassLoader::CreateTypeHandleForNonCanonicalGenericInstantiation(
pMT->SetupGenericsStaticsInfo(pStaticFieldDescs);
}
-#ifdef FEATURE_REMOTING
- // We do not cache the data for for non-canonical methods.
- _ASSERTE(!pMT->HasRemotableMethodInfo());
-#endif
// VTS info doesn't depend on the exact instantiation but we make a copy
// anyway since we can't currently deal with the possibility of having a
// cross module pointer to the data block. Eventually we might be able to
// tokenize this reference, but determine first whether there's enough
// performance degradation to justify the extra complexity.
-#ifdef FEATURE_REMOTING
- if (fHasRemotingVtsInfo)
- {
- RemotingVtsInfo *pOldInfo = pOldMT->GetRemotingVtsInfo();
- DWORD cbInfo = RemotingVtsInfo::GetSize(pOldMT->GetNumIntroducedInstanceFields());
- RemotingVtsInfo *pNewInfo = (RemotingVtsInfo*)pamTracker->Track(pAllocator->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(cbInfo)));
-
- memcpyNoGCRefs(pNewInfo, pOldInfo, cbInfo);
-
- *(pMT->GetRemotingVtsInfoPtr()) = pNewInfo;
- }
-
- // if there are thread or context static make room for them there is no sharing with the other MethodTable
- if (fHasContextStatics)
- {
- // this is responsible for setting the flag and allocation in the loader heap
- pMT->SetupContextStatics(pamTracker, pOldMT->GetContextStaticsSize());
- }
-#endif //FEATURE_REMOTING
pMT->SetCl(pOldMT->GetCl());
@@ -657,10 +617,6 @@ ClassLoader::CreateTypeHandleForNonCanonicalGenericInstantiation(
_ASSERTE(!fContainsGenericVariables == !pMT->ContainsGenericVariables());
_ASSERTE(!fHasGenericsStaticsInfo == !pMT->HasGenericsStaticsInfo());
_ASSERTE(!pLoaderModule->GetAssembly()->IsDomainNeutral() == !pMT->IsDomainNeutral());
-#ifdef FEATURE_REMOTING
- _ASSERTE(!fHasRemotingVtsInfo == !pMT->HasRemotingVtsInfo());
- _ASSERTE(!fHasContextStatics == !pMT->HasContextStatics());
-#endif
#ifdef FEATURE_COMINTEROP
_ASSERTE(!fHasDynamicInterfaceMap == !pMT->HasDynamicInterfaceMap());
_ASSERTE(!fHasRCWPerTypeData == !pMT->HasRCWPerTypeData());
diff --git a/src/vm/hostexecutioncontext.cpp b/src/vm/hostexecutioncontext.cpp
deleted file mode 100644
index 2d9f16a6f1..0000000000
--- a/src/vm/hostexecutioncontext.cpp
+++ /dev/null
@@ -1,230 +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 "common.h"
-#ifdef FEATURE_CAS_POLICY
-
-#include "hostexecutioncontext.h"
-#include "corhost.h"
-#include "security.h"
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-IHostSecurityContext *HostExecutionContextManager::m_pRestrictedHostContext = NULL;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
-// initialize HostRestrictedContext
-void HostExecutionContextManager::InitializeRestrictedContext()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- _ASSERTE(m_pRestrictedHostContext == NULL);
-
- IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
- if (pSM)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pSM->GetSecurityContext(eRestrictedContext, &m_pRestrictedHostContext);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-}
-// notify the Host to SetRestrictedContext
-void HostExecutionContextManager::SetHostRestrictedContext()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if(m_pRestrictedHostContext != NULL)
- {
- IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
- if (pSM)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pSM->SetSecurityContext(eRestrictedContext, m_pRestrictedHostContext);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-}
-
-FCIMPL0(FC_BOOL_RET, HostExecutionContextManager::HostPresent)
-{
- FCALL_CONTRACT;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- FC_RETURN_BOOL(CorHost2::GetHostSecurityManager() != NULL);
-#else // !FEATURE_INCLUDE_ALL_INTERFACES
- FC_RETURN_BOOL(FALSE);
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-}
-FCIMPLEND
-
-FCIMPL1(HRESULT, HostExecutionContextManager::ReleaseSecurityContext, LPVOID handle)
-{
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(handle));
- } CONTRACTL_END;
-
- HELPER_METHOD_FRAME_BEGIN_RET_NOPOLL();
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
- if (pSM)
- {
- // get the IUnknown pointer from handle
- IHostSecurityContext* pSecurityContext = (IHostSecurityContext*)handle;
- // null out the IUnknown pointer in the handle
- //hTokenSAFE->SetHandle((void*)NULL);
- // release the IUnknown pointer if it is non null
- if (pSecurityContext != NULL)
- {
- pSecurityContext->Release();
- }
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- HELPER_METHOD_FRAME_END();
- return S_OK;
-
-}
-FCIMPLEND
-
-FCIMPL1(HRESULT, HostExecutionContextManager::CaptureSecurityContext, SafeHandle* hTokenUNSAFE)
-{
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(hTokenUNSAFE));
- } CONTRACTL_END;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSecurityContext* pCurrentHostSecurityContext = NULL;
- IHostSecurityContext* pCapturedSecurityContext = NULL;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- HRESULT hr = S_OK;
- SAFEHANDLE hTokenSAFE = (SAFEHANDLE) hTokenUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_1(hTokenSAFE);
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
- if (pSM)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pSM->GetSecurityContext(eCurrentContext, &pCurrentHostSecurityContext);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (hr == S_OK)
- {
- if(pCurrentHostSecurityContext != NULL)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pCurrentHostSecurityContext->Capture(&pCapturedSecurityContext);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- hTokenSAFE->SetHandle((void*)pCapturedSecurityContext);
- SafeRelease(pCurrentHostSecurityContext);
- }
- }
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- if (FAILED(hr))
- COMPlusThrowHR(hr);
-
- HELPER_METHOD_FRAME_END();
- return hr;
-
-}
-FCIMPLEND
-
-FCIMPL2(HRESULT, HostExecutionContextManager::CloneSecurityContext, SafeHandle* hTokenUNSAFE, SafeHandle* hTokenClonedUNSAFE)
-{
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(hTokenUNSAFE));
- PRECONDITION(CheckPointer(hTokenClonedUNSAFE));
- } CONTRACTL_END;
-
- SAFEHANDLE hTokenClonedSAFE = (SAFEHANDLE) hTokenClonedUNSAFE;
- SAFEHANDLE hTokenSAFE = (SAFEHANDLE)hTokenUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_2(hTokenSAFE, hTokenClonedSAFE);
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
- if (pSM)
- {
- IHostSecurityContext* pSecurityContext = (IHostSecurityContext*)hTokenSAFE->GetHandle();
- if (pSecurityContext != NULL)
- {
- pSecurityContext->AddRef();
- hTokenClonedSAFE->SetHandle((void*)pSecurityContext);
- }
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- HELPER_METHOD_FRAME_END();
- return S_OK;
-}
-FCIMPLEND
-
-FCIMPL3(HRESULT, HostExecutionContextManager::SetSecurityContext, SafeHandle* hTokenUNSAFE, CLR_BOOL fReturnPrevious, SafeHandle* hTokenPreviousUNSAFE)
-{
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(hTokenUNSAFE));
- } CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- SAFEHANDLE hTokenPreviousSAFE = (SAFEHANDLE) hTokenPreviousUNSAFE;
- SAFEHANDLE hTokenSAFE = (SAFEHANDLE) hTokenUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_2(hTokenSAFE, hTokenPreviousSAFE);
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSecurityManager *pSM = CorHost2::GetHostSecurityManager();
- if (pSM)
- {
- if (fReturnPrevious)
- {
- IHostSecurityContext* pPreviousHostSecurityContext = NULL;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pSM->GetSecurityContext(eCurrentContext, &pPreviousHostSecurityContext);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- COMPlusThrowHR(hr);
- // store the previous host context in the safe handle
- hTokenPreviousSAFE->SetHandle((void*)pPreviousHostSecurityContext);
- }
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pSM->SetSecurityContext(eCurrentContext, (IHostSecurityContext*)hTokenSAFE->GetHandle());
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- COMPlusThrowHR(hr);
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- HELPER_METHOD_FRAME_END();
- return hr;
-}
-FCIMPLEND
-#endif // #ifdef FEATURE_CAS_POLICY
-
diff --git a/src/vm/hostexecutioncontext.h b/src/vm/hostexecutioncontext.h
deleted file mode 100644
index 721c8953ad..0000000000
--- a/src/vm/hostexecutioncontext.h
+++ /dev/null
@@ -1,29 +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.
-
-
-
-#ifndef __hostexecutioncontext_h__
-#define __hostexecutioncontext_h__
-
-#ifdef FEATURE_CAS_POLICY
-
-class HostExecutionContextManager
-{
-public:
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- static IHostSecurityContext* m_pRestrictedHostContext;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- static void InitializeRestrictedContext();
- static void SetHostRestrictedContext();
-
- static FCDECL0(FC_BOOL_RET, HostPresent);
- static FCDECL1(HRESULT, ReleaseSecurityContext, LPVOID handle);
- static FCDECL1(HRESULT, CaptureSecurityContext, SafeHandle* hTokenUNSAFE);
- static FCDECL2(HRESULT, CloneSecurityContext, SafeHandle* hTokenUNSAFE, SafeHandle* hTokenClonedUNSAFE);
- static FCDECL3(HRESULT, SetSecurityContext, SafeHandle* hTokenUNSAFE, CLR_BOOL fReturnPrevious, SafeHandle* hTokenPreviousUNSAFE);
-};
-#endif // #ifdef FEATURE_CAS_POLICY
-#endif // __hostexecutioncontext_h__
-
diff --git a/src/vm/hosting.cpp b/src/vm/hosting.cpp
index 4dd6a59729..620b9d6800 100644
--- a/src/vm/hosting.cpp
+++ b/src/vm/hosting.cpp
@@ -14,10 +14,6 @@
#include "corhost.h"
#include "threads.h"
-#if defined(FEATURE_CLICKONCE)
-#include "isolationpriv.h"
-#include "shlwapi.h"
-#endif
#define countof(x) (sizeof(x) / sizeof(x[0]))
@@ -197,15 +193,6 @@ BOOL GlobalAllocStore::m_Disabled = FALSE;
#endif
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
-// The helper thread can't call regular new / delete b/c of interop-debugging deadlocks.
-// It must use the (InteropSafe) heap from debugger.h, you also can't allocate normally
-// when we have any other thread hard-suspended.
-
-// Telesto doesn't support interop-debugging, so this won't be an issue.
-
-void AssertAllocationAllowed();
-#endif
HANDLE g_ExecutableHeapHandle = NULL;
@@ -225,9 +212,6 @@ LPVOID EEVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, D
return NULL;
#endif
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
- AssertAllocationAllowed();
-#endif
#ifdef _DEBUG
if (g_fEEStarted) {
@@ -236,44 +220,6 @@ LPVOID EEVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, D
_ASSERTE (lpAddress || (dwSize % g_SystemInfo.dwAllocationGranularity) == 0);
#endif
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostMemoryManager *pMM = CorHost2::GetHostMemoryManager();
- if (pMM) {
- LPVOID pMem;
- EMemoryCriticalLevel eLevel = eTaskCritical;
- if (!g_fEEStarted)
- {
- eLevel = eProcessCritical;
- }
- else
- {
- Thread *pThread = GetThread();
- if (pThread && pThread->HasLockInCurrentDomain())
- {
- if (GetAppDomain()->IsDefaultDomain())
- {
- eLevel = eProcessCritical;
- }
- else
- {
- eLevel = eAppDomainCritical;
- }
- }
- }
- HRESULT hr = S_OK;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pMM->VirtualAlloc (lpAddress, dwSize, flAllocationType, flProtect, eLevel, &pMem);
- END_SO_TOLERANT_CODE_CALLING_HOST;
-
- if(hr != S_OK)
- {
- STRESS_LOG_OOM_STACK(dwSize);
- }
-
- return (hr == S_OK) ? pMem : NULL;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
LPVOID p = NULL;
@@ -337,19 +283,6 @@ BOOL EEVirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType) {
BOOL retVal = FALSE;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostMemoryManager *pMM = CorHost2::GetHostMemoryManager();
- if (pMM) {
-#ifdef _DEBUG
- GlobalAllocStore::ValidateFree(lpAddress);
-#endif
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- retVal = pMM->VirtualFree (lpAddress, dwSize, dwFreeType) == S_OK;
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
#ifdef _DEBUG
GlobalAllocStore::RemoveAlloc (lpAddress);
@@ -373,20 +306,6 @@ SIZE_T EEVirtualQuery(LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZ
}
CONTRACTL_END;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostMemoryManager *pMM = CorHost2::GetHostMemoryManager();
- if (pMM) {
- SIZE_T result;
- HRESULT hr = S_OK;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pMM->VirtualQuery((void*)lpAddress, lpBuffer, dwLength, &result);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- return 0;
- return result;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
return ::VirtualQuery(lpAddress, lpBuffer, dwLength);
}
@@ -404,17 +323,6 @@ BOOL EEVirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWOR
}
CONTRACTL_END;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostMemoryManager *pMM = CorHost2::GetHostMemoryManager();
- if (pMM) {
- BOOL result = FALSE;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- result = pMM->VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect) == S_OK;
- END_SO_TOLERANT_CODE_CALLING_HOST;
- return result;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
return ::VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect);
}
@@ -429,13 +337,6 @@ HANDLE EEGetProcessHeap()
STATIC_CONTRACT_GC_NOTRIGGER;
STATIC_CONTRACT_SO_TOLERANT;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostMemoryManager *pMM = CorHost2::GetHostMemoryManager();
- if (pMM) {
- return (HANDLE)1; // pretending we return an handle is ok because handles are ignored by the hosting api
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
return GetProcessHeap();
}
@@ -455,14 +356,6 @@ HANDLE EEHeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize)
#ifndef FEATURE_PAL
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostMalloc *pHM = CorHost2::GetHostMalloc();
- if (pHM)
- {
- return NULL;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
return ::HeapCreate(flOptions, dwInitialSize, dwMaximumSize);
}
@@ -485,14 +378,6 @@ BOOL EEHeapDestroy(HANDLE hHeap)
#ifndef FEATURE_PAL
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostMalloc *pHM = CorHost2::GetHostMalloc();
- if (pHM)
- {
- return TRUE;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
return ::HeapDestroy(hHeap);
}
@@ -510,54 +395,6 @@ BOOL EEHeapDestroy(HANDLE hHeap)
#endif
#endif
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-LPVOID EEHeapAllocHosted(IHostMalloc * pHM, SIZE_T dwBytes)
-{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_SO_INTOLERANT;
-
- Thread * pThread = GetThreadNULLOk();
- EMemoryCriticalLevel eLevel = eTaskCritical;
- if (!g_fEEStarted)
- {
- eLevel = eProcessCritical;
- }
- else
- {
- if (pThread && pThread->HasLockInCurrentDomain())
- {
- if (GetAppDomain()->IsDefaultDomain())
- {
- eLevel = eProcessCritical;
- }
- else
- {
- eLevel = eAppDomainCritical;
- }
- }
- }
- LPVOID pMem = NULL;
- HRESULT hr = S_OK;
- {
- CantAllocHolder caHolder;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(pThread);
- hr = pHM->Alloc(dwBytes, eLevel, &pMem);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-
- if(hr != S_OK
- //under OOM, we might not be able to get Execution Engine and can't access stress log
- && GetExecutionEngine ()
- // If we have not created StressLog ring buffer, we should not try to use it.
- // StressLog is going to do a memory allocation. We may enter an endless loop.
- && ClrFlsGetValue(TlsIdx_StressLog) != NULL )
- {
- STRESS_LOG_OOM_STACK(dwBytes);
- }
-
- return (hr == S_OK) ? pMem : NULL;
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#undef HeapAlloc
LPVOID EEHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes)
@@ -570,20 +407,7 @@ LPVOID EEHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes)
return NULL;
#endif
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
- AssertAllocationAllowed();
-#endif
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostMalloc *pHM = CorHost2::GetHostMalloc();
-
- // TODO: implement hosted executable heap
- if (pHM && hHeap != g_ExecutableHeapHandle)
- {
- return EEHeapAllocHosted(pHM, dwBytes);
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
LPVOID p = NULL;
@@ -644,30 +468,9 @@ BOOL EEHeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)
// @todo - Need a backout validation here.
CONTRACT_VIOLATION(SOToleranceViolation);
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
- AssertAllocationAllowed();
-#endif
BOOL retVal = FALSE;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostMalloc *pHM = CorHost2::GetHostMalloc();
-
- // TODO: implement hosted executable heap
- if (pHM && hHeap != g_ExecutableHeapHandle)
- {
- if (lpMem == NULL) {
- retVal = TRUE;
- }
-#ifdef _DEBUG
- GlobalAllocStore::ValidateFree(lpMem);
-#endif
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- retVal = pHM->Free(lpMem) == S_OK;
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
#ifdef _DEBUG
GlobalAllocStore::RemoveAlloc (lpMem);
@@ -723,14 +526,6 @@ BOOL EEHeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem) {
#ifndef FEATURE_PAL
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostMalloc *pHM = CorHost2::GetHostMalloc();
- if (pHM)
- {
- return TRUE;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
return ::HeapValidate(hHeap, dwFlags, lpMem);
}
@@ -745,7 +540,6 @@ HANDLE EEGetProcessExecutableHeap() {
STATIC_CONTRACT_NOTHROW;
STATIC_CONTRACT_GC_NOTRIGGER;
-#ifdef FEATURE_CORECLR
#ifndef FEATURE_PAL
@@ -780,18 +574,6 @@ HANDLE EEGetProcessExecutableHeap() {
UNREACHABLE();
#endif // !FEATURE_PAL
-#else // FEATURE_CORECLR
-
- //
- // Use process executable heap created by the shim
- //
- if (g_ExecutableHeapHandle == NULL)
- {
- extern HANDLE GetProcessExecutableHeap();
- g_ExecutableHeapHandle = GetProcessExecutableHeap();
- }
-
-#endif // FEATURE_CORECLR
// TODO: implement hosted executable heap
return g_ExecutableHeapHandle;
@@ -813,42 +595,6 @@ DWORD EESleepEx(DWORD dwMilliseconds, BOOL bAlertable)
DWORD res;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *provider = CorHost2::GetHostTaskManager();
- if ((provider != NULL)){
- DWORD option = 0;
- if (bAlertable)
- {
- option = WAIT_ALERTABLE;
- }
-
-
- HRESULT hr;
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = provider->Sleep(dwMilliseconds, option);
- END_SO_TOLERANT_CODE_CALLING_HOST;
-
- if (hr == S_OK) {
- res = WAIT_OBJECT_0;
- }
- else if (hr == HOST_E_INTERRUPTED) {
- _ASSERTE(bAlertable);
- Thread *pThread = GetThread();
- if (pThread)
- {
- pThread->UserInterruptAPC(APC_Code);
- }
- res = WAIT_IO_COMPLETION;
- }
- else
- {
- _ASSERTE (!"Unknown return from host Sleep\n");
- res = WAIT_OBJECT_0;
- }
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
res = ::SleepEx(dwMilliseconds, bAlertable);
}
@@ -889,15 +635,6 @@ BOOL __DangerousSwitchToThread (DWORD dwSleepMSec, DWORD dwSwitchCount, BOOL goT
}
CONTRACTL_END;
- if (CLRTaskHosted())
- {
- Thread *pThread = GetThread();
- if (pThread && pThread->HasThreadState(Thread::TS_YieldRequested))
- {
- pThread->ResetThreadState(Thread::TS_YieldRequested);
- }
- }
-
if (dwSleepMSec > 0)
{
// when called with goThroughOS make sure to not call into the host. This function
@@ -940,22 +677,6 @@ BOOL __DangerousSwitchToThread (DWORD dwSleepMSec, DWORD dwSwitchCount, BOOL goT
ClrSleepEx(1, FALSE);
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *provider = CorHost2::GetHostTaskManager();
- if ((provider != NULL) && (goThroughOS == FALSE))
- {
- DWORD option = 0;
-
- HRESULT hr;
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = provider->SwitchToTask(option);
- END_SO_TOLERANT_CODE_CALLING_HOST;
-
- return hr == S_OK;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
return SwitchToThread();
}
@@ -1155,751 +876,3 @@ BOOL EEAllocationDisallowed()
#endif
}
-#ifdef FEATURE_CLICKONCE
-
-HRESULT GetApplicationManifest (LPCWSTR pwzAppFullName,
- DWORD dwManifestPaths,
- LPCWSTR *ppwzManifestPaths,
- __out_z __deref_out_opt LPWSTR *ppwzApplicationFolderPath,
- __out_z __deref_out_opt LPWSTR *ppszKeyForm,
- ICMS **ppApplicationManifest)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pwzAppFullName));
- PRECONDITION(CheckPointer(ppwzManifestPaths, NULL_OK));
- PRECONDITION(CheckPointer(ppApplicationManifest));
- } CONTRACTL_END;
-
- ReleaseHolder<IStore> pStore(NULL);
- ReleaseHolder<IAppIdAuthority> pAppIdAuth(NULL);
- ReleaseHolder<IDefinitionAppId> pDefinitionIdentity(NULL);
- ReleaseHolder<IEnumDefinitionIdentity> pEnumDefinitionIdentity(NULL);
- ReleaseHolder<IDefinitionIdentity> pDeploymentDefinitionIdentity(NULL);
- ReleaseHolder<IDefinitionIdentity> pApplicationDefinitionIdentity(NULL);
- ReleaseHolder<IDefinitionIdentity> pSubscriptionIdentity(NULL);
- ReleaseHolder<IDefinitionAppId> pSubscriptionAppId(NULL);
-
- ReleaseHolder<IUnknown> TempFetched(NULL);
- HRESULT hr = S_OK;
-
- // Maybe this is not an installed application. Grab the manifest path if specified and parse the manifest.
- if (dwManifestPaths > 0) {
- if (dwManifestPaths < 2)
- goto ErrExit;
-
- hr = ParseManifest(ppwzManifestPaths[1], NULL, __uuidof(ICMS), &TempFetched);
- if (TempFetched == NULL)
- {
- goto ErrExit;
- }
-
- IfFailGo(TempFetched->QueryInterface(__uuidof(ICMS), (void**) ppApplicationManifest));
- TempFetched.Release();
-
- // Set the application directory to be the location of the application manifest.
- if (ppwzApplicationFolderPath) {
- LPCWSTR pszSlash;
- if (((pszSlash = wcsrchr(ppwzManifestPaths[1], W('\\'))) != NULL) || ((pszSlash = wcsrchr(ppwzManifestPaths[1], W('/'))) != NULL)) {
- DWORD cchDirectory = (DWORD) (pszSlash - ppwzManifestPaths[1] + 1);
- *ppwzApplicationFolderPath = (LPWSTR) CoTaskMemAlloc(2 * (cchDirectory + 1));
-
- if (*ppwzApplicationFolderPath == NULL)
- {
- hr = E_OUTOFMEMORY;
- goto ErrExit;
- }
-
- memcpy(*ppwzApplicationFolderPath, ppwzManifestPaths[1], 2 * cchDirectory);
- (*ppwzApplicationFolderPath)[cchDirectory] = W('\0');
- }
- }
- goto ErrExit;
- }
-
- // Get the user store.
- IfFailGo(GetUserStore(0, NULL, __uuidof(IStore), &pStore));
-
- // Get the AppId authority
- IfFailGo(GetAppIdAuthority(&pAppIdAuth));
-
- // Get the IDefintionIdentity of the application full name passed in as an argument.
- IfFailGo(pAppIdAuth->TextToDefinition(0, pwzAppFullName, &pDefinitionIdentity));
-
- // Get the ICMS object representing the application manifest.
- IfFailGo(pDefinitionIdentity->EnumAppPath(&pEnumDefinitionIdentity));
- IfFailGo(pEnumDefinitionIdentity->Reset());
- ULONG numItems = 0;
- IfFailGo(pEnumDefinitionIdentity->Next(1, &pDeploymentDefinitionIdentity, &numItems));
- if (numItems < 1) {
- hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
- goto ErrExit;
- }
- IfFailGo(pEnumDefinitionIdentity->Next(1, &pApplicationDefinitionIdentity, &numItems));
- if (numItems < 1) {
- hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
- goto ErrExit;
- }
-
- if (ppszKeyForm){
- // Create subscription identity from deployment identity.
- IfFailGo(pDeploymentDefinitionIdentity->Clone(0,NULL,&pSubscriptionIdentity));
- IfFailGo(pSubscriptionIdentity->SetAttribute(NULL,W("version"),NULL));
-
- // Create the subscription app id.
- IfFailGo(pAppIdAuth->CreateDefinition(&pSubscriptionAppId));
-
- IDefinitionIdentity *defIdentityArray[1];
- defIdentityArray[0] = pSubscriptionIdentity;
-
- IfFailGo(pSubscriptionAppId->SetAppPath(1,defIdentityArray));
- IfFailGo(pAppIdAuth->GenerateDefinitionKey(0,pSubscriptionAppId,ppszKeyForm));
- }
-
- hr = pStore->GetAssemblyInformation(0, pApplicationDefinitionIdentity, __uuidof(ICMS), &TempFetched);
- if (SUCCEEDED(hr)) {
- if (ppwzApplicationFolderPath) {
- // Get the application folder path.
- LPVOID cookie = NULL;
- IfFailGo(pStore->LockApplicationPath(0, pDefinitionIdentity, &cookie, ppwzApplicationFolderPath));
- IfFailGo(pStore->ReleaseApplicationPath(cookie));
- }
- }
- IfFailGo(TempFetched->QueryInterface(__uuidof(ICMS), (void**) ppApplicationManifest));
- TempFetched.Release();
-
-ErrExit:
- pStore.Release();
- pAppIdAuth.Release();
- pDefinitionIdentity.Release();
- pEnumDefinitionIdentity.Release();
- pDeploymentDefinitionIdentity.Release();
- pApplicationDefinitionIdentity.Release();
- pSubscriptionIdentity.Release();
- pSubscriptionAppId.Release();
-
- return hr;
-}
-
-BOOL DoesMarkOfTheWebExist (LPCWSTR pwzAppFullName)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pwzAppFullName));
- } CONTRACTL_END;
-
- HANDLE alternateStreamHandle = INVALID_HANDLE_VALUE;
-
- StackSString alternateStreamPath(pwzAppFullName);
- alternateStreamPath.Append(W(":Zone.Identifier"));
-
- // Try to open alternate file stream
- alternateStreamHandle = WszCreateFile(
- alternateStreamPath.GetUnicode(),
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
-
- if (INVALID_HANDLE_VALUE != alternateStreamHandle)
- {
- CloseHandle(alternateStreamHandle);
-
- // We only check if MOTW (alternate stream) is present,
- // no matter what the zone is.
- return TRUE;
- }
-
- return FALSE;
-}
-
-HRESULT GetApplicationEntryPointInfo (LPCWSTR pwzAppFullName,
- DWORD dwManifestPaths,
- LPCWSTR *ppwzManifestPaths,
- __out_z __deref_out_opt LPWSTR *ppwzApplicationFolderPath,
- LPCWSTR *ppwzCodeBase,
- LPCWSTR *ppwzParameters,
- __out_z __deref_out_opt LPWSTR *ppwzProcessorArch,
- __out_z __deref_out_opt LPWSTR *ppwzAppIdKeyForm)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pwzAppFullName));
- PRECONDITION(CheckPointer(ppwzManifestPaths, NULL_OK));
- PRECONDITION(CheckPointer(ppwzCodeBase, NULL_OK));
- PRECONDITION(CheckPointer(ppwzParameters, NULL_OK));
- PRECONDITION(CheckPointer(ppwzProcessorArch, NULL_OK));
- } CONTRACTL_END;
-
- ReleaseHolder<ICMS> pApplicationManifest(NULL);
- ReleaseHolder<ISection> pEntrySection(NULL);
- ReleaseHolder<IEnumUnknown> pEntryEnum(NULL);
- ReleaseHolder<IEntryPointEntry> pEntry(NULL);
- ReleaseHolder<IReferenceIdentity> pReferenceId(NULL);
- ReleaseHolder<ISectionWithStringKey> pNamedRefSection(NULL);
- ReleaseHolder<ISectionWithReferenceIdentityKey> pRefSection(NULL);
- ReleaseHolder<IAssemblyReferenceEntry> pRefEntry(NULL);
- ReleaseHolder<IAssemblyReferenceDependentAssemblyEntry> pDependentAssemblyEntry(NULL);
- CoTaskMemHolder<WCHAR> pwszDependencyName = NULL;
-
- ReleaseHolder<IUnknown> TempFetched(NULL);
- ReleaseHolder<ISection> TempFetchedSection(NULL);
- HRESULT hr = S_OK;
-
- // Get the ICMS object representing the application manifest.
- IfFailGo(GetApplicationManifest(pwzAppFullName, dwManifestPaths, ppwzManifestPaths, ppwzApplicationFolderPath, ppwzAppIdKeyForm,&pApplicationManifest));
-
- // Get the app entry point section.
- IfFailGo(pApplicationManifest->get_EntryPointSection(&pEntrySection));
- if (pEntrySection == NULL) {
- hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
- goto ErrExit;
- }
-
- // Get the entry point enum.
- IfFailGo(pEntrySection->get__NewEnum(&TempFetched));
- IfFailGo(TempFetched->QueryInterface(__uuidof(IEnumUnknown), &pEntryEnum));
- TempFetched.Release();
-
- // Get the first entry point.
- ULONG numItems = 0;
- IfFailGo(pEntryEnum->Next(1, &TempFetched, &numItems));
- if (numItems < 1) {
- hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
- goto ErrExit;
- }
- IfFailGo(TempFetched->QueryInterface(__uuidof(IEntryPointEntry), &pEntry));
- TempFetched.Release();
-
- // We support both name and identity based entry points.
- IfFailGo(pEntry->get_Identity(&pReferenceId));
- if (pReferenceId == NULL) {
- hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
- goto ErrExit;
- }
-
- // Get the assembly reference section.
- IfFailGo(pApplicationManifest->get_AssemblyReferenceSection(&TempFetchedSection));
- IfFailGo(TempFetchedSection->QueryInterface(__uuidof(ISectionWithReferenceIdentityKey), &pRefSection));
- TempFetchedSection.Release();
-
-#ifdef CLICKONCE_LONGHORN_RELATED
- //
- // If a reference assembly matching entry point does not exist, use the codebase
- // of command line file.
- //
- if (FAILED(pRefSection->Lookup(pReferenceId, &TempFetched)))
- {
- if (ppwzCodeBase) {
- IfFailGo(pEntry->get_CommandLine_File(ppwzCodeBase));
- }
- }
- else
-#endif
- {
- // Lookup the assembly reference entry.
- IfFailGo(pRefSection->Lookup(pReferenceId, &TempFetched));
- IfFailGo(TempFetched->QueryInterface(__uuidof(IAssemblyReferenceEntry), &pRefEntry));
- TempFetched.Release();
-
- // Get the assembly codebase. Codebase may either come from <dependentAssembly> or <installFrom>.
- // In a valid reference there should always be a <dependentAssembly> section.
- IfFailGo(pRefEntry->get_DependentAssembly(&pDependentAssemblyEntry));
-
- if (ppwzCodeBase) {
- IfFailGo(pDependentAssemblyEntry->get_Codebase(ppwzCodeBase));
- }
- }
-
- // Get the parameters
- if (ppwzParameters)
- IfFailGo(pEntry->get_CommandLine_Parameters(ppwzParameters));
-
- // Get the processor architecture requested in the app manifest
- if (ppwzProcessorArch)
- IfFailGo(pReferenceId->GetAttribute(NULL, W("processorArchitecture"), ppwzProcessorArch));
-
-ErrExit:
- pApplicationManifest.Release();
- pEntrySection.Release();
- pEntryEnum.Release();
- pEntry.Release();
- pReferenceId.Release();
- pNamedRefSection.Release();
- pRefSection.Release();
- pRefEntry.Release();
- pDependentAssemblyEntry.Release();
- pwszDependencyName.Release();
-
- return hr;
-}
-
-//
-// Export used in the ClickOnce installer for launching manifest-based applications.
-//
-
-typedef struct _tagNameMap {
- LPWSTR pwszProcessorArch;
- DWORD dwRuntimeInfoFlag;
-} NAME_MAP;
-
-DWORD g_DfSvcSpinLock = 0;
-void EnterDfSvcSpinLock () {
- WRAPPER_NO_CONTRACT;
- while (1) {
- if (InterlockedExchange ((LPLONG)&g_DfSvcSpinLock, 1) == 1)
- ClrSleepEx (5, FALSE);
- else
- return;
- }
-}
-
-void LeaveDfSvcSpinLock () {
- InterlockedExchange ((LPLONG)&g_DfSvcSpinLock, 0);
-}
-
-//
-// ThreadProc used by SHCreateProcess call - to activate ClickOnce app with ShellExecuteEx
-// ShellExecuteEx can only be used from STA threads - we are creating our own STA thread
-//
-DWORD CorLaunchApplication_ThreadProc(void*)
-{
- return 0;
-}
-
-//
-// This callback is executed as the sync-callback on SHCreateThread.
-// SHCreateThread does not return till this callback returns.
-//
-DWORD CorLaunchApplication_Callback(void* pv)
-{
- SHELLEXECUTEINFO *pSei = static_cast<SHELLEXECUTEINFO *>(pv);
- IUnknown* pDummyUnknown;
- CreateStreamOnHGlobal(NULL, TRUE, (LPSTREAM*) &pDummyUnknown);
-
- if (RunningOnWin8())
- {
- // When SEE_MASK_FLAG_HINST_IS_SITE is specified SHELLEXECUTEINFO.hInstApp is used as an
- // _In_ parameter and specifies a IUnknown* to be used as a site pointer. The site pointer
- // is used to provide services to shell execute, the handler binding process and the verb handlers
- // once they are invoked.
- //
- // SEE_MASK_HINST_IS_SITE is available on Win8+
- // Defining it locally in Win8-conditioned code
- //
- const ULONG SEE_MASK_HINST_IS_SITE = 0x08000000;
-
- pSei->fMask = SEE_MASK_HINST_IS_SITE;
- pSei->hInstApp = reinterpret_cast<HINSTANCE>(pDummyUnknown);
- }
-
- WszShellExecuteEx(pSei);
- // We ignore all errors from ShellExecute.
- //
- // This may change with Win8:783168
-
- if (pDummyUnknown)
- {
- pDummyUnknown->Release();
- }
-
- return 0;
-}
-
-//-----------------------------------------------------------------------------
-// WszSHCreateThread
-//
-// @func calls SHCreateThread with the provided parameters
-//
-// @rdesc Result
-//-----------------------------------------------------------------------------------
-HRESULT WszSHCreateThread(
- LPTHREAD_START_ROUTINE pfnThreadProc,
- void *pData,
- SHCT_FLAGS dwFlags,
- LPTHREAD_START_ROUTINE pfnCallback
-)
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_PREEMPTIVE;
- INJECT_FAULT(return E_OUTOFMEMORY;);
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- HMODULE _hmodShlwapi = 0;
-
- typedef BOOL (*PFNSHCREATETHREAD) (
- __in LPTHREAD_START_ROUTINE pfnThreadProc,
- __in_opt void *pData,
- __in SHCT_FLAGS dwFlags,
- __in_opt LPTHREAD_START_ROUTINE pfnCallback
- );
-
- static PFNSHCREATETHREAD pfnW = NULL;
- if (NULL == pfnW)
- {
- _hmodShlwapi = CLRLoadLibrary(W("shlwapi.dll"));
-
- if (_hmodShlwapi)
- {
- pfnW = (PFNSHCREATETHREAD)GetProcAddress(_hmodShlwapi, "SHCreateThread");
- }
- }
-
- if (pfnW)
- {
- BOOL bRet = pfnW(pfnThreadProc, pData, dwFlags, pfnCallback);
-
- if (!bRet)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- }
- }
- else
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- }
-
- // NOTE: We leak the module handles and let the OS gather them at process shutdown.
-
- return hr;
-}
-
-STDAPI CorLaunchApplication (HOST_TYPE dwClickOnceHost,
- LPCWSTR pwzAppFullName,
- DWORD dwManifestPaths,
- LPCWSTR *ppwzManifestPaths,
- DWORD dwActivationData,
- LPCWSTR *ppwzActivationData,
- LPPROCESS_INFORMATION lpProcessInformation)
-{
- // HostType is encoded in the lowest 2 bits.
- unsigned hostType = dwClickOnceHost & MASK_HOSTTYPE;
-
- // NoPinnableBit is the highest bit.
- unsigned notPinnableBit = dwClickOnceHost & MASK_NOTPINNABLE;
-
- // DontShowInstallDialog bit
- unsigned dontShowInstallDialog = dwClickOnceHost & MASK_DONT_SHOW_INSTALL_DIALOG;
-
- bool bUseShellExecute = false;
-
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- ENTRY_POINT;
- PRECONDITION(CheckPointer(pwzAppFullName, NULL_OK));
- PRECONDITION(CheckPointer(ppwzManifestPaths, NULL_OK));
- PRECONDITION(CheckPointer(ppwzActivationData, NULL_OK));
- PRECONDITION(hostType == HOST_TYPE_DEFAULT || hostType == HOST_TYPE_APPLAUNCH || hostType == HOST_TYPE_CORFLAG);
- PRECONDITION(CheckPointer(lpProcessInformation));
- } CONTRACTL_END;
-
-
- if (pwzAppFullName == NULL)
- return E_POINTER;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- LPVOID lpEnvironment = NULL;
- EX_TRY
- {
- StackSString commandLine(StackSString::Ascii, "\""); // put quotes around path to the command line.
- StackSString appEntryPath(W("")); // the path to the entry point(the exe to run) of the application, initialized to empty string
- NewArrayHolder<WCHAR> wszDirectory(NULL);
- NewArrayHolder<WCHAR> wszVersion(NULL);
- CoTaskMemHolder<WCHAR> pwszApplicationFolderPath(NULL);
- CoTaskMemHolder<WCHAR> pwszAppIdKeyForm(NULL);
- CoTaskMemHolder<WCHAR> pwszCodebase(NULL);
- CoTaskMemHolder<WCHAR> pwszParameters(NULL);
- CoTaskMemHolder<WCHAR> pwszProcessorArch(NULL);
-
- hr = GetApplicationEntryPointInfo(pwzAppFullName, dwManifestPaths, ppwzManifestPaths, (LPWSTR*) (void*) &pwszApplicationFolderPath, (LPCWSTR*) (void*) &pwszCodebase, (LPCWSTR*) (void*) &pwszParameters, (LPWSTR*) (void*) &pwszProcessorArch,(LPWSTR*) (void*) &pwszAppIdKeyForm);
-
- if (SUCCEEDED(hr)) {
- // construct the application Entry Path
- if (pwszApplicationFolderPath != NULL) {
- appEntryPath.Append(pwszApplicationFolderPath);
- SString::CIterator i = appEntryPath.End()-1;
- if (i[0] != '\\')
- appEntryPath.Append(W("\\"));
- }
- appEntryPath.Append(pwszCodebase);
-
- if (hostType == HOST_TYPE_CORFLAG) {
- // construct the command line
- commandLine.Append(appEntryPath);
- commandLine.Append(W("\""));
-
- if (RunningOnWin8() &&
- DoesMarkOfTheWebExist(appEntryPath.GetUnicode()))
- {
- // We will use ShellExecute for any zone set in MOTW stream.
- // ShellExecute would call Application Reputation API if the zone is the one
- // that requires AppRep validation. At the moment, they would do this for Internet Zone only,
- // but there are talks about changing the behavior to include some of the other zones.
- // By not checking the zone here we leave to AppRep/ShellExecute to decide,
- // which is exactly what we want.
- bUseShellExecute = true;
- }
- else
- {
- if (pwszParameters != NULL) {
- commandLine.Append(W(" "));
- commandLine.Append(pwszParameters);
- }
- }
-
- // now construct the environment variables
- EnterDfSvcSpinLock();
- WszSetEnvironmentVariable(g_pwzClickOnceEnv_FullName, pwzAppFullName);
-
- if (dwManifestPaths > 0 && ppwzManifestPaths) {
- for (DWORD i=0; i<dwManifestPaths; i++) {
- StackSString manifestFile(g_pwzClickOnceEnv_Manifest);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- manifestFile.Append(buf);
- WszSetEnvironmentVariable(manifestFile.GetUnicode(), *ppwzManifestPaths++);
- }
- }
-
- if (dwActivationData > 0 && ppwzActivationData) {
- for (DWORD i=0; i<dwActivationData; i++) {
- StackSString activationData(g_pwzClickOnceEnv_Parameter);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- activationData.Append(buf);
- WszSetEnvironmentVariable(activationData.GetUnicode(), *ppwzActivationData++);
- }
- }
-
-#undef GetEnvironmentStrings
-#undef GetEnvironmentStringsW
- lpEnvironment = (LPVOID) GetEnvironmentStringsW();
-#define GetEnvironmentStringsW() Use_WszGetEnvironmentStrings()
-#define GetEnvironmentStrings() Use_WszGetEnvironmentStrings()
- } else {
- // application folder is required to determine appEntryPath for framework version selection,
- // but should not be used as working directory for partial trust apps
- pwszApplicationFolderPath.Clear();
-
- // find the architecture from manifest and required version from the application itself
- static const NAME_MAP g_NameMapArray[] = {
- {W("x86"), RUNTIME_INFO_REQUEST_X86},
- {W("ia64"), RUNTIME_INFO_REQUEST_IA64},
- {W("amd64"), RUNTIME_INFO_REQUEST_AMD64},
- };
-
- DWORD dwRuntimeInfoFlags = RUNTIME_INFO_UPGRADE_VERSION |
- RUNTIME_INFO_CONSIDER_POST_2_0 |
- RUNTIME_INFO_EMULATE_EXE_LAUNCH;
-
- // We want to control whether shim should show install dialog or not,
- // and not leave this decision to the Shim.
- if (dontShowInstallDialog > 0)
- {
- dwRuntimeInfoFlags |= RUNTIME_INFO_DONT_SHOW_ERROR_DIALOG;
- }
- else
- {
- // show even if SEM_CRITICAL is set
- dwRuntimeInfoFlags |= METAHOST_POLICY_IGNORE_ERROR_MODE;
- }
-
- if (pwszProcessorArch) {
- for (DWORD index = 0; index < sizeof(g_NameMapArray) / sizeof(NAME_MAP); index++) {
- if (SString::_wcsicmp(g_NameMapArray[index].pwszProcessorArch, pwszProcessorArch) == 0) {
- dwRuntimeInfoFlags |= g_NameMapArray[index].dwRuntimeInfoFlag;
- break;
- }
- }
- }
- wszDirectory = new WCHAR[MAX_LONGPATH + 1];
- wszVersion = new WCHAR[MAX_PATH_FNAME + 1];
- wszVersion[0] = 0; // we don't prefer any version
- DWORD cchBuffer = MAX_LONGPATH;
-
- // Use GetRequestedRuntimeInfo because MetaHost APIs do not yet support architecture arguments.
- // Calls to GetRequestedRuntimeInfo() will goes to a local copy inside clr.dll,
- // have to call mscoree::GetRequestedRuntimeInfo.
- typedef HRESULT (*PFNGetRequestedRuntimeInfo)(LPCWSTR pExe,
- LPCWSTR pwszVersion,
- LPCWSTR pConfigurationFile,
- DWORD startupFlags,
- DWORD runtimeInfoFlags,
- LPWSTR pDirectory,
- DWORD dwDirectory,
- DWORD *dwDirectoryLength,
- LPWSTR pVersion,
- DWORD cchBuffer,
- DWORD* dwlength);
- PFNGetRequestedRuntimeInfo pfnGetRequestedRuntimeInfo = NULL;
- HMODULE hMscoree = GetModuleHandleW( W("mscoree.dll") ); // mscoree.dll should have already been loaded
- if( hMscoree != NULL )
- pfnGetRequestedRuntimeInfo = (PFNGetRequestedRuntimeInfo)GetProcAddress( hMscoree, "GetRequestedRuntimeInfo" );
- if( pfnGetRequestedRuntimeInfo == NULL )
- pfnGetRequestedRuntimeInfo = GetRequestedRuntimeInfoInternal; // in case mscoree has not been loaded, use the built in function
- hr = pfnGetRequestedRuntimeInfo(appEntryPath.GetUnicode(), // Use the image path to guide all version binding
- NULL, // Do not prime with any preferred version
- NULL, // No explicit config file - pick up on one next to image if there.
- 0, // startupFlags
- dwRuntimeInfoFlags, // Will bind to post-v2 runtimes if EXE PE runtime version is post-v2
- // or EXE has config file binding to post-v2 runtime.
- wszDirectory, MAX_LONGPATH, NULL, // Retrieve bound directory
- wszVersion, MAX_PATH_FNAME, NULL); // Retrieve bound version
-
- if (SUCCEEDED(hr)) {
- commandLine.Append(wszDirectory);
- commandLine.Append(wszVersion);
- commandLine.Append(W("\\applaunch.exe"));
- commandLine.Append(W("\" /activate \""));
- commandLine.Append(pwzAppFullName);
- commandLine.Append(W("\" "));
-
- if (dwManifestPaths > 0 && ppwzManifestPaths) {
- commandLine.Append(W("/manifests "));
- for (DWORD i=0; i<dwManifestPaths; i++) {
- commandLine.Append(W("\""));
- commandLine.Append(*ppwzManifestPaths++);
- commandLine.Append(W("\" "));
- }
- }
-
- if (dwActivationData > 0 && ppwzActivationData) {
- commandLine.Append(W("/parameters "));
- for (DWORD i=0; i<dwActivationData; i++) {
- commandLine.Append(W("\""));
- commandLine.Append(*ppwzActivationData++);
- commandLine.Append(W("\" "));
- }
- }
- }
- }
- }
-
- if (SUCCEEDED(hr)) {
- // CreateProcess won't let this parameter be const
- // (it writes a NULL in the middle), so we create a writable version
- LPCWSTR wszCommandLineNonWritable = commandLine.GetUnicode();
- size_t len = wcslen(wszCommandLineNonWritable);
- NewArrayHolder<WCHAR> wszCommandLine(new WCHAR[len + 1]);
- memcpy(wszCommandLine, wszCommandLineNonWritable, len * sizeof(WCHAR));
- wszCommandLine[len] = W('\0');
-
- STARTUPINFO sui;
- memset(&sui, 0, sizeof(STARTUPINFO));
- sui.cb = sizeof(STARTUPINFO);
- sui.lpTitle = pwszAppIdKeyForm;
- sui.dwFlags = STARTF_TITLEISAPPID;
-
- if (notPinnableBit>0)
- sui.dwFlags |= STARTF_PREVENTPINNING;
-
- // ClickOnce uses ShellExecute to utilize Win8+ Application Reputation service.
- // Application Reputation validates applications coming from the Internet.
- // ClickOnce will use ShellExecute only if there is a Mark-of-the-Web file-stream for the executable.
- // In all other cases we continue to use CreateProcess. CreateProcess does not use AppRep service.
- if (bUseShellExecute)
- {
- SHELLEXECUTEINFO sei;
- memset(&sei, 0, sizeof(SHELLEXECUTEINFO));
- sei.cbSize = sizeof(SHELLEXECUTEINFO);
- sei.hwnd = NULL;
- sei.lpVerb = NULL;
- sei.lpFile = wszCommandLine;
- sei.lpParameters = pwszParameters;
- sei.lpDirectory = pwszApplicationFolderPath;
- sei.nShow = SW_SHOWDEFAULT;
- sei.hInstApp = NULL;
-
- // Application Reputation is a COM Shell Extension that requires a calling thread to be an STA
- // CorLaunchApplication_Callback calls ShellExecuteEx.
- hr = WszSHCreateThread((LPTHREAD_START_ROUTINE) CorLaunchApplication_ThreadProc, &sei, CTF_COINIT_STA,
- (LPTHREAD_START_ROUTINE) CorLaunchApplication_Callback);
- }
- else
- {
- // Launch the child process
- BOOL result = WszCreateProcess(NULL,
- wszCommandLine,
- NULL, NULL, FALSE,
- (lpEnvironment) ? NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT | CREATE_DEFAULT_ERROR_MODE : NORMAL_PRIORITY_CLASS | CREATE_DEFAULT_ERROR_MODE,
- lpEnvironment, pwszApplicationFolderPath,
- &sui, lpProcessInformation);
- if (!result)
- hr = HRESULT_FROM_GetLastError();
- }
- }
- }
- EX_CATCH_HRESULT(hr);
-
- // cleanup
- if (hostType == HOST_TYPE_CORFLAG) {
- // free the environment block
-#undef FreeEnvironmentStringsA
-#undef FreeEnvironmentStringsW
- if (NULL != lpEnvironment) {
- FreeEnvironmentStringsW((LPWSTR) lpEnvironment);
- }
-#define FreeEnvironmentStringsW(lpEnvironment) Use_WszFreeEnvironmentStrings(lpEnvironment)
-#define FreeEnvironmentStringsA(lpEnvironment) Use_WszFreeEnvironmentStrings(lpEnvironment)
- // reset the environment variables
- WszSetEnvironmentVariable(g_pwzClickOnceEnv_FullName, NULL);
- EX_TRY
- {
- if (dwManifestPaths > 0 && ppwzManifestPaths) {
- for (DWORD i=0; i<dwManifestPaths; i++) {
- StackSString manifestFile(g_pwzClickOnceEnv_Manifest);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- manifestFile.Append(buf);
- WszSetEnvironmentVariable(manifestFile.GetUnicode(), NULL);
- }
- }
- if (dwActivationData > 0 && ppwzActivationData) {
- for (DWORD i=0; i<dwActivationData; i++) {
- StackSString activationData(g_pwzClickOnceEnv_Parameter);
- StackSString buf;
- COUNT_T size = buf.GetUnicodeAllocation();
- _itow_s(i, buf.OpenUnicodeBuffer(size), size, 10);
- buf.CloseBuffer();
- activationData.Append(buf);
- WszSetEnvironmentVariable(activationData.GetUnicode(), NULL);
- }
- }
- }
- EX_CATCH_HRESULT(hr);
- // leave the spin lock so other requests can be served.
- LeaveDfSvcSpinLock();
- }
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-#endif // FEATURE_CLICKONCE
diff --git a/src/vm/i386/asmconstants.h b/src/vm/i386/asmconstants.h
index ce648518f9..0a581cffe0 100644
--- a/src/vm/i386/asmconstants.h
+++ b/src/vm/i386/asmconstants.h
@@ -33,30 +33,12 @@
#define DBG_FRE(dbg,fre) fre
#endif
-//***************************************************************************
-#if defined(_DEBUG) && defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- #define HAS_TRACK_CXX_EXCEPTION_CODE_HACK 1
- #define TRACK_CXX_EXCEPTION_CODE_HACK
-#else
- #define HAS_TRACK_CXX_EXCEPTION_CODE_HACK 0
-#endif
-
#define INITIAL_SUCCESS_COUNT 0x100
#define DynamicHelperFrameFlags_Default 0
#define DynamicHelperFrameFlags_ObjectArg 1
#define DynamicHelperFrameFlags_ObjectArg2 2
-#ifdef FEATURE_REMOTING
-#define TransparentProxyObject___stubData 0x8
-ASMCONSTANTS_C_ASSERT(TransparentProxyObject___stubData == offsetof(TransparentProxyObject, _stubData))
-
-#define TransparentProxyObject___stub 0x14
-ASMCONSTANTS_C_ASSERT(TransparentProxyObject___stub == offsetof(TransparentProxyObject, _stub))
-
-#define TransparentProxyObject___pMT 0xc
-ASMCONSTANTS_C_ASSERT(TransparentProxyObject___pMT == offsetof(TransparentProxyObject, _pMT))
-#endif // FEATURE_REMOTING
// CONTEXT from rotor_pal.h
#define CONTEXT_Edi 0x9c
@@ -210,14 +192,7 @@ ASMCONSTANTS_C_ASSERT(CORINFO_ArgumentException_ASM == CORINFO_ArgumentException
#ifndef CROSSGEN_COMPILE
// from clr/src/vm/threads.h
-#if defined(TRACK_CXX_EXCEPTION_CODE_HACK) // Is C++ exception code tracking turned on?
- #define Thread_m_LastCxxSEHExceptionCode 0x20
- ASMCONSTANTS_C_ASSERT(Thread_m_LastCxxSEHExceptionCode == offsetof(Thread, m_LastCxxSEHExceptionCode))
-
- #define Thread_m_Context 0x3C
-#else
- #define Thread_m_Context 0x38
-#endif // TRACK_CXX_EXCEPTION_CODE_HACK
+#define Thread_m_Context 0x38
ASMCONSTANTS_C_ASSERT(Thread_m_Context == offsetof(Thread, m_Context))
#define Thread_m_State 0x04
@@ -258,16 +233,6 @@ ASMCONSTANTS_C_ASSERT(Thread::TS_Hijacked == TS_Hijacked_ASM)
ASMCONSTANTS_C_ASSERT(AppDomain__m_dwId == offsetof(AppDomain, m_dwId));
// from clr/src/vm/ceeload.cpp
-#ifdef FEATURE_MIXEDMODE
-#define IJWNOADThunk__m_cache 0x1C
-ASMCONSTANTS_C_ASSERT(IJWNOADThunk__m_cache == offsetof(IJWNOADThunk, m_cache))
-
-#define IJWNOADThunk__NextCacheOffset 0x8
-ASMCONSTANTS_C_ASSERT(IJWNOADThunk__NextCacheOffset == sizeof(IJWNOADThunkStubCache))
-
-#define IJWNOADThunk__CodeAddrOffsetFromADID 0x4
-ASMCONSTANTS_C_ASSERT(IJWNOADThunk__CodeAddrOffsetFromADID == offsetof(IJWNOADThunkStubCache, m_CodeAddr))
-#endif //FEATURE_MIXEDMODE
// from clr/src/vm/syncblk.h
#define SizeOfSyncTableEntry_ASM 8
@@ -463,6 +428,11 @@ ASMCONSTANTS_C_ASSERT(UMThunkMarshInfo__m_pILStub == offsetof(UMThunkMarshInfo,
#define UMThunkMarshInfo__m_cbActualArgSize 0x04
ASMCONSTANTS_C_ASSERT(UMThunkMarshInfo__m_cbActualArgSize == offsetof(UMThunkMarshInfo, m_cbActualArgSize))
+#ifdef FEATURE_STUBS_AS_IL
+#define UMThunkMarshInfo__m_cbRetPop 0x08
+ASMCONSTANTS_C_ASSERT(UMThunkMarshInfo__m_cbRetPop == offsetof(UMThunkMarshInfo, m_cbRetPop))
+#endif //FEATURE_STUBS_AS_IL
+
#ifndef CROSSGEN_COMPILE
#define Thread__m_pDomain 0x14
ASMCONSTANTS_C_ASSERT(Thread__m_pDomain == offsetof(Thread, m_pDomain));
diff --git a/src/vm/i386/asmhelpers.S b/src/vm/i386/asmhelpers.S
index 2bb9560e09..98525aceee 100644
--- a/src/vm/i386/asmhelpers.S
+++ b/src/vm/i386/asmhelpers.S
@@ -230,6 +230,8 @@ NESTED_ENTRY StubRareEnable, _TEXT, NoHandler
push edx
push ebx
+
+ CHECK_STACK_ALIGNMENT
call C_FUNC(StubRareEnableWorker)
pop edx
@@ -242,6 +244,8 @@ NESTED_ENTRY StubRareDisableTHROW, _TEXT, NoHandler
push edx
push ebx // Thread
+
+ CHECK_STACK_ALIGNMENT
call C_FUNC(StubRareDisableTHROWWorker)
pop edx
@@ -249,46 +253,6 @@ NESTED_ENTRY StubRareDisableTHROW, _TEXT, NoHandler
ret
NESTED_END StubRareDisableTHROW, _TEXT
-LEAF_ENTRY InternalExceptionWorker, _TEXT
- pop edx // recover RETADDR
- add esp, eax // release caller's args
- push edx // restore RETADDR
- jmp C_FUNC(JIT_InternalThrow)
-LEAF_END InternalExceptionWorker, _TEXT
-
-// EAX -> number of caller arg bytes on the stack that we must remove before going
-// to the throw helper, which assumes the stack is clean.
-LEAF_ENTRY ArrayOpStubNullException, _TEXT
- // kFactorReg and kTotalReg could not have been modified, but let's pop
- // them anyway for consistency and to avoid future bugs.
- pop esi
- pop edi
- mov ecx, CORINFO_NullReferenceException_ASM
- jmp C_FUNC(InternalExceptionWorker)
-LEAF_END ArrayOpStubNullException, _TEXT
-
-// EAX -> number of caller arg bytes on the stack that we must remove before going
-// to the throw helper, which assumes the stack is clean.
-LEAF_ENTRY ArrayOpStubRangeException, _TEXT
- // kFactorReg and kTotalReg could not have been modified, but let's pop
- // them anyway for consistency and to avoid future bugs.
- pop esi
- pop edi
- mov ecx, CORINFO_IndexOutOfRangeException_ASM
- jmp C_FUNC(InternalExceptionWorker)
-LEAF_END ArrayOpStubRangeException, _TEXT
-
-// EAX -> number of caller arg bytes on the stack that we must remove before going
-// to the throw helper, which assumes the stack is clean.
-LEAF_ENTRY ArrayOpStubTypeMismatchException, _TEXT
- // kFactorReg and kTotalReg could not have been modified, but let's pop
- // them anyway for consistency and to avoid future bugs.
- pop esi
- pop edi
- mov ecx, CORINFO_ArrayTypeMismatchException_ASM
- jmp C_FUNC(InternalExceptionWorker)
-LEAF_END ArrayOpStubTypeMismatchException, _TEXT
-
// ------------------------------------------------------------------------------
// This helper routine enregisters the appropriate arguments and makes the
// actual call.
@@ -395,12 +359,30 @@ LEAF_ENTRY HelperMethodFrameRestoreState, _TEXT
#ifdef _DEBUG
jnz LOCAL_LABEL(noConfirm)
- push ebp
+
+ mov eax, ebp
+
+ // Create a minimal EBP-frame (for clean stack trace under debugger)
+ PROLOG_BEG
+ PROLOG_END
+
+ // Call HelperMethodFrameConfirmState (with stack alignment padding)
+ #define STACK_ALIGN_PADDING 4
+ sub esp, STACK_ALIGN_PADDING
+ push eax // eax = ebp
push ebx
push edi
push esi
push ecx // HelperFrame*
+ CHECK_STACK_ALIGNMENT
call C_FUNC(HelperMethodFrameConfirmState)
+ add esp, STACK_ALIGN_PADDING
+ #undef STACK_ALIGN_PADDING
+
+ // Restore EBP
+ EPILOG_BEG
+ EPILOG_END
+
// on return, eax = MachState*
cmp DWORD PTR [eax + MachState__pRetAddr], 0
LOCAL_LABEL(noConfirm):
@@ -582,7 +564,11 @@ NESTED_ENTRY UM2MThunk_WrapperHelper, _TEXT, NoHandler
mov eax, [esp + 20] // pEntryThunk
mov ecx, [esp + 24] // pThread
mov ebx, [esp + 8] // pThunkArgs
- call [esp + 16] // pAddr
+
+ sub esp, 8
+ CHECK_STACK_ALIGNMENT
+ call [esp + 16 + 8] // pAddr
+ add esp, 8
pop ebx
@@ -593,9 +579,12 @@ NESTED_ENTRY UMThunkStubRareDisable, _TEXT, NoHandler
push eax
push ecx
+ sub esp, 12
push eax // Push the UMEntryThunk
push ecx // Push thread
+ CHECK_STACK_ALIGNMENT
call C_FUNC(UMThunkStubRareDisableWorker)
+ add esp, 12
pop ecx
pop eax
@@ -614,6 +603,7 @@ LEAF_END GetCurrentIP, _TEXT
// LPVOID __stdcall GetCurrentSP(void);
LEAF_ENTRY GetCurrentSP, _TEXT
mov eax, esp
+ add eax, 4
ret
LEAF_END GetCurrentSP, _TEXT
@@ -827,16 +817,19 @@ NESTED_ENTRY DelayLoad_MethodCall, _TEXT, NoHandler
mov esi, esp
+ #define STACK_ALIGN_PADDING 4
+ sub esp, STACK_ALIGN_PADDING
+
push ecx
push edx
-
push eax
-
- // pTransitionBlock
- push esi
-
+ push esi // pTransitionBlock
+ CHECK_STACK_ALIGNMENT
call C_FUNC(ExternalMethodFixupWorker)
+ add esp, STACK_ALIGN_PADDING
+ #undef STACK_ALIGN_PADDING
+
// eax now contains replacement stub. PreStubWorker will never return
// NULL (it throws an exception if stub creation fails.)
@@ -860,8 +853,8 @@ NESTED_END DelayLoad_MethodCall, _TEXT
// to optionally patch the target of the jump so that we do not take this slow path again.
//
NESTED_ENTRY VirtualMethodFixupStub, _TEXT, NoHandler
- // Pop the return address. It points right after the call instruction in the thunk.
- pop eax
+ // Get the return address. It points right after the call instruction in the thunk.
+ mov eax, [esp]
// Calculate the address of the thunk
sub eax, 5
@@ -875,9 +868,12 @@ NESTED_ENTRY VirtualMethodFixupStub, _TEXT, NoHandler
// Set frame pointer
PROLOG_END
+ sub esp, 8
push eax // address of the thunk
push ecx // this ptr
+ CHECK_STACK_ALIGNMENT
call C_FUNC(VirtualMethodFixupWorker)
+ add esp, 8
// Restore stack pointer
EPILOG_BEG
@@ -889,6 +885,9 @@ NESTED_ENTRY VirtualMethodFixupStub, _TEXT, NoHandler
// Pop ebp frame
EPILOG_END
+ // Pop return address
+ add esp, 4
+
PATCH_LABEL VirtualMethodFixupPatchLabel
// Proceed to execute the actual method.
jmp eax
@@ -959,7 +958,9 @@ NESTED_ENTRY DelayLoad_Helper\suffix, _TEXT, NoHandler
mov esi, esp
- push \frameFlags
+.att_syntax
+ pushl $\frameFlags
+.intel_syntax noprefix
push ecx // module
push edx // section index
@@ -986,6 +987,14 @@ DYNAMICHELPER (DynamicHelperFrameFlags_ObjectArg | DynamicHelperFrameFlags_Objec
#endif // FEATURE_READYTORUN
+//
+// Entry stack:
+// dispatch token
+// siteAddrForRegisterIndirect (used only if this is a RegisterIndirect dispatch call)
+// return address of caller to stub
+//
+// Please see vm/i386/virtualcallstubcpu.hpp for details
+//
NESTED_ENTRY ResolveWorkerAsmStub, _TEXT, NoHandler
//
// The stub arguments are where we want to setup the TransitionBlock. We will
@@ -1007,32 +1016,40 @@ NESTED_ENTRY ResolveWorkerAsmStub, _TEXT, NoHandler
mov esi, esp
+ #define STACK_ALIGN_PADDING 8
+
+ sub esp, STACK_ALIGN_PADDING
push [esi + 4*4] // dispatch token
push [esi + 5*4] // siteAddrForRegisterIndirect
push esi // pTransitionBlock
// Setup up proper EBP frame now that the stub arguments can be trashed
- mov [esi + 4*4],ebx
- mov [esi + 5*4],ebp
+ mov [esi + 4*4], ebx
+ mov [esi + 5*4], ebp
lea ebp, [esi + 5*4]
// Make the call
+ CHECK_STACK_ALIGNMENT
call C_FUNC(VSD_ResolveWorker)
+ add esp, STACK_ALIGN_PADDING
+
+ #undef STACK_ALIGN_PADDING
+
// From here on, mustn't trash eax
// pop ArgumentRegisters
- pop edx
- pop ecx
+ pop edx
+ pop ecx
// pop CalleeSavedRegisters
- pop edi
- pop esi
- pop ebx
- pop ebp
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
// Now jump to the target
- jmp eax // continue on into the method
+ jmp eax // continue on into the method
NESTED_END ResolveWorkerAsmStub, _TEXT
#ifdef FEATURE_STUBS_AS_IL
@@ -1121,11 +1138,19 @@ LOCAL_LABEL(main_loop):
// be quick to reset the counter so we don't get a bunch of contending threads
mov dword ptr [edx], CALL_STUB_CACHE_INITIAL_SUCCESS_COUNT
+ #define STACK_ALIGN_PADDING 12
+ sub esp, STACK_ALIGN_PADDING
+
// promote the entry to the beginning of the chain
mov ecx, eax
+
+ CHECK_STACK_ALIGNMENT
// call C_FUNC(VirtualCallStubManager::PromoteChainEntry)
call C_FUNC(_ZN22VirtualCallStubManager17PromoteChainEntryEP16ResolveCacheElem)
+ add esp, STACK_ALIGN_PADDING
+ #undef STACK_ALIGN_PADDING
+
LOCAL_LABEL(nopromote):
pop ecx
@@ -1143,3 +1168,42 @@ LOCAL_LABEL(fail):
NESTED_END ResolveWorkerChainLookupAsmStub, _TEXT
#endif // CROSSGEN_COMPILE
+
+// backpatch a call site to point to a different stub
+NESTED_ENTRY BackPatchWorkerAsmStub, _TEXT, NoHandler
+ PROLOG_BEG
+ PROLOG_PUSH eax // it may contain siteAddrForRegisterIndirect
+ PROLOG_PUSH ecx
+ PROLOG_PUSH edx
+ PROLOG_END
+
+ // Call BackPatchWorkerStaticStub
+ //
+ // Here is expected stack layout at this point:
+ // | saved edx |
+ // | saved ecx |
+ // | saved eax |
+ // +-----------+ <- ebp
+ // | saved ebp |
+ // | saved eip |
+ // +-----------+ <- CFA of BackPatchWorkerAsmStub
+ // | saved eip |
+ // +-----------+ <- CFA of ResolveStub (16-byte aligned)
+ // (Please refer to ResolveStub in vm/i386/virtualcallstubcpu.hpp for details)
+ //
+ push eax // any indirect call address as the 2nd arg
+ push DWORD PTR [ebp + 8] // return address (of ResolveStub) as the 1st arg
+
+ CHECK_STACK_ALIGNMENT
+ call C_FUNC(BackPatchWorkerStaticStub)
+
+ // Clean up arguments and alignment padding
+ add esp, 2*4
+
+ EPILOG_BEG
+ EPILOG_POP edx
+ EPILOG_POP ecx
+ EPILOG_POP eax
+ EPILOG_END
+ ret
+NESTED_END BackPatchWorkerAsmStub, _TEXT
diff --git a/src/vm/i386/asmhelpers.asm b/src/vm/i386/asmhelpers.asm
index 0456be82db..9df33219ac 100644
--- a/src/vm/i386/asmhelpers.asm
+++ b/src/vm/i386/asmhelpers.asm
@@ -30,9 +30,6 @@ EXTERN __imp__RtlUnwind@16:DWORD
ifdef _DEBUG
EXTERN _HelperMethodFrameConfirmState@20:PROC
endif
-ifdef FEATURE_MIXEDMODE
-EXTERN _IJWNOADThunkJumpTargetHelper@4:PROC
-endif
EXTERN _StubRareEnableWorker@4:PROC
ifdef FEATURE_COMINTEROP
EXTERN _StubRareDisableHRWorker@4:PROC
@@ -64,11 +61,6 @@ endif ; FEATURE_IMPLICIT_TLS
EXTERN _VarargPInvokeStubWorker@12:PROC
EXTERN _GenericPInvokeCalliStubWorker@12:PROC
-; To debug that LastThrownObjectException really is EXCEPTION_COMPLUS
-ifdef TRACK_CXX_EXCEPTION_CODE_HACK
-EXTERN __imp____CxxFrameHandler:PROC
-endif
-
EXTERN _GetThread@0:PROC
EXTERN _GetAppDomain@0:PROC
@@ -86,10 +78,6 @@ ifdef FEATURE_COMINTEROP
EXTERN _CLRToCOMWorker@8:PROC
endif
-ifdef FEATURE_REMOTING
-EXTERN _TransparentProxyStubWorker@8:PROC
-endif
-
ifdef FEATURE_PREJIT
EXTERN _ExternalMethodFixupWorker@16:PROC
EXTERN _VirtualMethodFixupWorker@8:PROC
@@ -104,10 +92,6 @@ ifdef FEATURE_READYTORUN
EXTERN _DynamicHelperWorker@20:PROC
endif
-ifdef FEATURE_REMOTING
-EXTERN _InContextTPQuickDispatchAsmStub@0:PROC
-endif
-
EXTERN @JIT_InternalThrow@4:PROC
EXTERN @ProfileEnter@8:PROC
@@ -282,52 +266,6 @@ _RestoreFPUContext@4 PROC public
_RestoreFPUContext@4 ENDP
-ifndef FEATURE_CORECLR
-ifdef _DEBUG
-; For C++ exceptions, we desperately need to know the SEH code. This allows us to properly
-; distinguish managed exceptions from C++ exceptions from standard SEH like hard stack overflow.
-; We do this by providing our own handler that squirrels away the exception code and then
-; defers to the C++ service. Fortunately, two symbols exist for the C++ symbol.
-___CxxFrameHandler3 PROC public
-
- ; We don't know what arguments are passed to us (except for the first arg on stack)
- ; It turns out that EAX is part of the non-standard calling convention of this
- ; function.
-
- push eax
- push edx
-
- cmp dword ptr [_gThreadTLSIndex], -1
- je Chain ; CLR is not initialized yet
-
- call _GetThread@0
-
- test eax, eax ; not a managed thread
- jz Chain
-
- mov edx, [esp + 0ch] ; grab the first argument
- mov edx, [edx] ; grab the SEH exception code
-
- mov dword ptr [eax + Thread_m_LastCxxSEHExceptionCode], edx
-
-Chain:
-
- pop edx
-
- ; [esp] contains the value of EAX we must restore. We would like
- ; [esp] to contain the address of the real imported CxxFrameHandler
- ; so we can chain to it.
-
- mov eax, [__imp____CxxFrameHandler]
- mov eax, [eax]
- xchg [esp], eax
-
- ret
-
-___CxxFrameHandler3 ENDP
-endif ; _DEBUG
-endif ; FEATURE_CORECLR
-
; Register CLR exception handlers defined on the C++ side with SAFESEH.
; Note that these directives must be in a file that defines symbols that will be used during linking,
; otherwise it's possible that the resulting .obj will completly be ignored by the linker and these
@@ -608,105 +546,6 @@ _StubRareDisableTHROW proc public
_StubRareDisableTHROW endp
-ifdef FEATURE_MIXEDMODE
-; VOID __stdcall IJWNOADThunkJumpTarget(void);
-; This routine is used by the IJWNOADThunk to determine the callsite of the domain-specific stub to call.
-_IJWNOADThunkJumpTarget@0 proc public
-
- push ebp
- mov ebp, esp
-
- ; EAX contains IJWNOADThunk*
- ; Must retain ebx, ecx, edx, esi, edi.
-
- ; save ebx - holds the IJWNOADThunk*
- ; save ecx - holds the current AppDomain ID.
- ; save edx - holds the cached AppDomain ID.
- push ebx
- push ecx
-
- ; put the IJWNOADThunk into ebx for safe keeping
- mov ebx, eax
-
- ; get thread - assumes registers are preserved
- call _GetThread@0
-
- ; if thread is null, go down un-optimized path
- test eax,eax
- jz cachemiss
-
- ; get current domain - assumes registers are preserved
- call _GetAppDomain@0
-
- ; if domain is null, go down un-optimized path
- test eax,eax
- jz cachemiss
-
- ; get the current appdomain id
- mov ecx, [eax + AppDomain__m_dwId]
-
- ; test it against each cache location
- mov eax, ebx
- add eax, IJWNOADThunk__m_cache
- cmp ecx, [eax]
- je cachehit
-
- add eax, IJWNOADThunk__NextCacheOffset
- cmp ecx, [eax]
- je cachehit
-
- add eax, IJWNOADThunk__NextCacheOffset
- cmp ecx, [eax]
- je cachehit
-
- add eax, IJWNOADThunk__NextCacheOffset
- cmp ecx, [eax]
- je cachehit
-
-cachemiss:
- ; save extra registers
- push edx
- push esi
- push edi
-
- ; call unoptimized path
- push ebx ; only arg is IJWNOADThunk*
- call _IJWNOADThunkJumpTargetHelper@4
-
- ; restore extra registers
- pop edi
- pop esi
- pop edx
-
- ; jump back up to the epilog
- jmp complete
-
-cachehit:
- ; found a matching ADID, get the code addr.
- mov eax, [eax + IJWNOADThunk__CodeAddrOffsetFromADID]
-
- ; if the callsite is null, go down the un-optimized path
- test eax, eax
- jz cachemiss
-
-complete:
- ; restore regs
- pop ecx
- pop ebx
-
- mov esp, ebp
- pop ebp
-
- ; Jump to callsite
- jmp eax
-
- ; This will never be executed. It is just to help out stack-walking logic
- ; which disassembles the epilog to unwind the stack.
- ret
-_IJWNOADThunkJumpTarget@0 endp
-
-endif
-
InternalExceptionWorker proc public
pop edx ; recover RETADDR
add esp, eax ; release caller's args
@@ -1193,182 +1032,6 @@ _UMThunkStubRareDisable proc public
_UMThunkStubRareDisable endp
-;+----------------------------------------------------------------------------
-;
-; Method: CRemotingServices::CheckForContextMatch public
-;
-; Synopsis: This code generates a check to see if the current context and
-; the context of the proxy match.
-;
-;+----------------------------------------------------------------------------
-;
-; returns zero if contexts match
-; returns non-zero if contexts do not match
-;
-; UINT_PTR __stdcall CRemotingServices__CheckForContextMatch(Object* pStubData)
-ifdef FEATURE_REMOTING
-_CRemotingServices__CheckForContextMatch@4 proc public
- push ebx ; spill ebx
- mov ebx, [eax+4] ; Get the internal context id by unboxing
- ; the stub data
- call _GetThread@0 ; Get the current thread, assumes that the
- ; registers are preserved
- mov eax, [eax+Thread_m_Context] ; Get the current context from the
- ; thread
- sub eax, ebx ; Get the pointer to the context from the
- ; proxy and compare with the current context
- pop ebx ; restore the value of ebx
- retn
-_CRemotingServices__CheckForContextMatch@4 endp
-endif ; FEATURE_REMOTING
-
-;+----------------------------------------------------------------------------
-;
-; Method: CRemotingServices::DispatchInterfaceCall public
-;
-; Synopsis:
-; Push that method desc on the stack and jump to the
-; transparent proxy stub to execute the call.
-; WARNING!! This MethodDesc is not the methoddesc in the vtable
-; of the object instead it is the methoddesc in the vtable of
-; the interface class. Since we use the MethodDesc only to probe
-; the stack via the signature of the method call we are safe.
-; If we want to get any object vtable/class specific
-; information this is not safe.
-;
-;
-;+----------------------------------------------------------------------------
-; void __stdcall CRemotingServices__DispatchInterfaceCall()
-ifdef FEATURE_REMOTING
-_CRemotingServices__DispatchInterfaceCall@0 proc public
- ; push MethodDesc* passed in eax by precode and forward to the worker
- push eax
-
- ; NOTE: At this point the stack looks like
- ;
- ; esp---> saved MethodDesc of Interface method
- ; return addr of calling function
- ;
- mov eax, [ecx + TransparentProxyObject___stubData]
- call [ecx + TransparentProxyObject___stub]
-ifdef _DEBUG
- nop ; Mark this as a special call site that can directly
- ; call managed code
-endif
- test eax, eax
- jnz CtxMismatch
- jmp _InContextTPQuickDispatchAsmStub@0
-
-CtxMismatch:
- pop eax ; restore MethodDesc *
- jmp _TransparentProxyStub_CrossContext@0 ; jump to slow TP stub
-_CRemotingServices__DispatchInterfaceCall@0 endp
-endif ; FEATURE_REMOTING
-
-
-;+----------------------------------------------------------------------------
-;
-; Method: CRemotingServices::CallFieldGetter private
-;
-; Synopsis: Calls the field getter function (Object::__FieldGetter) in
-; managed code by setting up the stack and calling the target
-;
-;
-;+----------------------------------------------------------------------------
-; void __stdcall CRemotingServices__CallFieldGetter(
-; MethodDesc *pMD,
-; LPVOID pThis,
-; LPVOID pFirst,
-; LPVOID pSecond,
-; LPVOID pThird)
-ifdef FEATURE_REMOTING
-CRemotingServices__CallFieldGetter proc stdcall public,
- pMD : DWORD,
- pThis : DWORD,
- pFirst : DWORD,
- pSecond : DWORD,
- pThird : DWORD
-
- push [pSecond] ; push the second argument on the stack
- push [pThird] ; push the third argument on the stack
-
- mov ecx, [pThis] ; enregister pThis, the 'this' pointer
- mov edx, [pFirst] ; enregister pFirst, the first argument
-
- mov eax, [pMD] ; load MethodDesc of object::__FieldGetter
- call _TransparentProxyStub_CrossContext@0 ; call the TP stub
-
- ret
-CRemotingServices__CallFieldGetter endp
-endif ; FEATURE_REMOTING
-
-;+----------------------------------------------------------------------------
-;
-; Method: CRemotingServices::CallFieldSetter private
-;
-; Synopsis: Calls the field setter function (Object::__FieldSetter) in
-; managed code by setting up the stack and calling the target
-;
-;
-;+----------------------------------------------------------------------------
-; void __stdcall CRemotingServices__CallFieldSetter(
-; MethodDesc *pMD,
-; LPVOID pThis,
-; LPVOID pFirst,
-; LPVOID pSecond,
-; LPVOID pThird)
-ifdef FEATURE_REMOTING
-CRemotingServices__CallFieldSetter proc stdcall public,
- pMD : DWORD,
- pThis : DWORD,
- pFirst : DWORD,
- pSecond : DWORD,
- pThird : DWORD
-
- push [pSecond] ; push the field name (second arg)
- push [pThird] ; push the object (third arg) on the stack
-
- mov ecx, [pThis] ; enregister pThis, the 'this' pointer
- mov edx, [pFirst] ; enregister the first argument
-
- mov eax, [pMD] ; load MethodDesc of object::__FieldGetter
- call _TransparentProxyStub_CrossContext@0 ; call the TP stub
-
- ret
-CRemotingServices__CallFieldSetter endp
-endif ; FEATURE_REMOTING
-
-;+----------------------------------------------------------------------------
-;
-; Method: CTPMethodTable::GenericCheckForContextMatch private
-;
-; Synopsis: Calls the stub in the TP & returns TRUE if the contexts
-; match, FALSE otherwise.
-;
-; Note: 1. Called during FieldSet/Get, used for proxy extensibility
-;
-;+----------------------------------------------------------------------------
-; BOOL __stdcall CTPMethodTable__GenericCheckForContextMatch(Object* orTP)
-ifdef FEATURE_REMOTING
-CTPMethodTable__GenericCheckForContextMatch proc stdcall public uses ecx, tp : DWORD
-
- mov ecx, [tp]
- mov eax, [ecx + TransparentProxyObject___stubData]
- call [ecx + TransparentProxyObject___stub]
-ifdef _DEBUG
- nop ; Mark this as a special call site that can directly
- ; call managed code
-endif
- test eax, eax
- mov eax, 0
- setz al
- ; NOTE: In the CheckForXXXMatch stubs (for URT ctx/ Ole32 ctx) eax is
- ; non-zero if contexts *do not* match & zero if they do.
- ret
-CTPMethodTable__GenericCheckForContextMatch endp
-endif ; FEATURE_REMOTING
-
-
; void __stdcall JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle)
_JIT_ProfilerEnterLeaveTailcallStub@4 proc public
; this function must preserve all registers, including scratch
@@ -2155,98 +1818,6 @@ _GenericComPlusCallStub@0 proc public
_GenericComPlusCallStub@0 endp
endif ; FEATURE_COMINTEROP
-ifdef FEATURE_REMOTING
-_TransparentProxyStub@0 proc public
- ; push slot passed in eax
- push eax
-
- ; Move into eax the stub data and call the stub
- mov eax, [ecx + TransparentProxyObject___stubData]
- call [ecx + TransparentProxyObject___stub]
-ifdef _DEBUG
- nop ; Mark this as a special call site that can directly
- ; call managed code
-endif
- test eax, eax
- jnz CtxMismatch2
-
- mov eax, [ecx + TransparentProxyObject___pMT]
-
- push ebx ; spill EBX
-
- ; Convert the slot number into the code address
- ; See MethodTable.h for details on vtable layout
-
- mov ebx, [esp + 4] ; Reload the slot
- shr ebx, ASM__VTABLE_SLOTS_PER_CHUNK_LOG2 ; indirectionSlotNumber
-
- mov eax,[eax + ebx*4 + SIZEOF_MethodTable]
-
- mov ebx, [esp + 4] ; use unchanged slot from above
- and ebx, ASM__VTABLE_SLOTS_PER_CHUNK-1 ; offsetInChunk
- mov eax, [eax + ebx*4]
-
- ; At this point, eax contains the code address
-
- ; Restore EBX
- pop ebx
-
- ; Remove the slot number from the stack
- lea esp, [esp+4]
-
- jmp eax
-
- ; CONTEXT MISMATCH CASE, call out to the real proxy to dispatch
-
-CtxMismatch2:
- pop eax ; restore MethodDesc *
- jmp _TransparentProxyStub_CrossContext@0 ; jump to slow TP stub
-
-_TransparentProxyStub@0 endp
-
-_TransparentProxyStub_CrossContext@0 proc public
-
- STUB_PROLOG
-
- ; pTransitionBlock
- mov esi, esp
-
- ; return value
- sub esp, 3*4 ; 64-bit return value + cb stack pop
-
- push eax ; pMD
- push esi ; pTransitionBlock
- call _TransparentProxyStubWorker@8
-
- pop ebx ; cbStackPop
-
- push eax
- call _setFPReturn@12 ; pop & set the return value
-
- ; From here on, mustn't trash eax:edx
- mov ecx, ebx ; cbStackPop
-
- mov ebx, [esp+6*4] ; get retaddr
- mov [esp+6*4+ecx], ebx ; put it where it belongs
-
- STUB_EPILOG_RETURN
-
- add esp, ecx ; pop all the args
- ret
-
-_TransparentProxyStub_CrossContext@0 endp
-
-; This method does nothing. It's just a fixed function for the debugger to put a breakpoint
-; on so that it can trace a call target.
-_TransparentProxyStubPatch@0 proc public
- ; make sure that the basic block is unique
- test eax,12
-_TransparentProxyStubPatchLabel@0:
-public _TransparentProxyStubPatchLabel@0
- ret
-_TransparentProxyStubPatch@0 endp
-
-endif ; FEATURE_REMOTING
ifdef FEATURE_COMINTEROP
;--------------------------------------------------------------------------
diff --git a/src/vm/i386/cgencpu.h b/src/vm/i386/cgencpu.h
index 2e47a6af90..ff76d992fc 100644
--- a/src/vm/i386/cgencpu.h
+++ b/src/vm/i386/cgencpu.h
@@ -39,9 +39,6 @@ Stub * GenerateInitPInvokeFrameHelper();
EXTERN_C void STDCALL PInvokeStackImbalanceHelper(void);
#endif // MDA_SUPPORTED
-#ifndef FEATURE_CORECLR
-EXTERN_C void STDCALL CopyCtorCallStub(void);
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_STUBS_AS_IL
EXTERN_C void SinglecastDelegateInvokeStub();
@@ -95,9 +92,6 @@ BOOL Runtime_Test_For_SSE2();
// Needed for PInvoke inlining in ngened images
#define HAS_NDIRECT_IMPORT_PRECODE 1
-#ifdef FEATURE_REMOTING
-#define HAS_REMOTING_PRECODE 1
-#endif
#ifdef FEATURE_PREJIT
#define HAS_FIXUP_PRECODE 1
#define HAS_FIXUP_PRECODE_CHUNKS 1
@@ -489,10 +483,15 @@ inline BOOL IsUnmanagedValueTypeReturnedByRef(UINT sizeofvaluetype)
{
LIMITED_METHOD_CONTRACT;
+#ifndef UNIX_X86_ABI
// odd-sized small structures are not
// enregistered e.g. struct { char a,b,c; }
return (sizeofvaluetype > 8) ||
(sizeofvaluetype & (sizeofvaluetype - 1)); // check that the size is power of two
+#else
+ // For UNIX_X86_ABI, we always return the value type by reference regardless of its size
+ return true;
+#endif
}
#include <pshpack1.h>
diff --git a/src/vm/i386/cgenx86.cpp b/src/vm/i386/cgenx86.cpp
index 528629c3a2..4c83265ff4 100644
--- a/src/vm/i386/cgenx86.cpp
+++ b/src/vm/i386/cgenx86.cpp
@@ -24,9 +24,6 @@
#include "array.h"
#include "jitinterface.h"
#include "codeman.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "dbginterface.h"
#include "eeprofinterfaces.h"
#include "eeconfig.h"
@@ -301,6 +298,7 @@ void TransitionFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
MethodDesc * pFunc = GetFunction();
_ASSERTE(pFunc != NULL);
+
UpdateRegDisplayHelper(pRD, pFunc->CbStackPop());
LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK TransitionFrame::UpdateRegDisplay(ip:%p, sp:%p)\n", pRD->ControlPC, pRD->SP));
@@ -326,11 +324,14 @@ void TransitionFrame::UpdateRegDisplayHelper(const PREGDISPLAY pRD, UINT cbStack
#ifdef WIN64EXCEPTIONS
+ DWORD CallerSP = (DWORD)(pRD->PCTAddr + sizeof(TADDR));
+
pRD->IsCallerContextValid = FALSE;
pRD->IsCallerSPValid = FALSE;
pRD->pCurrentContext->Eip = *PTR_PCODE(pRD->PCTAddr);;
- pRD->pCurrentContext->Esp = GetSP();
+ pRD->pCurrentContext->Esp = CallerSP;
+ pRD->pCurrentContext->ResumeEsp = CallerSP + cbStackPop;
UpdateRegDisplayFromCalleeSavedRegisters(pRD, regs);
ClearRegDisplayArgumentAndScratchRegisters(pRD);
@@ -383,7 +384,7 @@ void HelperMethodFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
#endif // DACCESS_COMPILE
pRD->pCurrentContext->Eip = pRD->ControlPC = m_MachState.GetRetAddr();
- pRD->pCurrentContext->Esp = pRD->SP = (DWORD) m_MachState.esp();
+ pRD->pCurrentContext->Esp = pRD->pCurrentContext->ResumeEsp = pRD->SP = (DWORD) m_MachState.esp();
#define CALLEE_SAVED_REGISTER(regname) pRD->pCurrentContext->regname = *((DWORD*) m_MachState.p##regname());
ENUM_CALLEE_SAVED_REGISTERS();
@@ -522,6 +523,8 @@ void ExternalMethodFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
UpdateRegDisplayHelper(pRD, CbStackPopUsingGCRefMap(GetGCRefMap()));
+ LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK ExternalMethodFrane::UpdateRegDisplay(ip:%p, sp:%p)\n", pRD->ControlPC, pRD->SP));
+
RETURN;
}
@@ -560,6 +563,8 @@ void StubDispatchFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
pRD->ControlPC = GetAdjustedCallAddress(pRD->ControlPC);
}
+ LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK StubDispatchFrame::UpdateRegDisplay(ip:%p, sp:%p)\n", pRD->ControlPC, pRD->SP));
+
RETURN;
}
@@ -593,9 +598,6 @@ void FaultingExceptionFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
}
CONTRACT_END;
- // reset pContext; it's only valid for active (top-most) frame
- pRD->pContext = NULL;
-
pRD->PCTAddr = GetReturnAddressPtr();
#ifdef WIN64EXCEPTIONS
@@ -618,6 +620,9 @@ void FaultingExceptionFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
#else // WIN64EXCEPTIONS
+ // reset pContext; it's only valid for active (top-most) frame
+ pRD->pContext = NULL;
+
CalleeSavedRegisters* regs = GetCalleeSavedRegisters();
#define CALLEE_SAVED_REGISTER(regname) pRD->p##regname = (DWORD*) &regs->regname;
@@ -683,7 +688,8 @@ void InlinedCallFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary.
pRD->pCurrentContext->Eip = *PTR_PCODE(pRD->PCTAddr);
- pRD->pCurrentContext->Esp = (DWORD) dac_cast<TADDR>(m_pCallSiteSP) + stackArgSize;
+ pRD->pCurrentContext->Esp = (DWORD) dac_cast<TADDR>(m_pCallSiteSP);
+ pRD->pCurrentContext->ResumeEsp = (DWORD) dac_cast<TADDR>(m_pCallSiteSP) + stackArgSize;
pRD->pCurrentContext->Ebp = (DWORD) m_pCalleeSavedFP;
ClearRegDisplayArgumentAndScratchRegisters(pRD);
@@ -740,7 +746,7 @@ void ResumableFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
#ifdef WIN64EXCEPTIONS
- memcpy(pRD->pCurrentContext, &m_Regs, sizeof(CONTEXT));
+ CopyMemory(pRD->pCurrentContext, m_Regs, sizeof(T_CONTEXT));
pRD->SP = m_Regs->Esp;
pRD->ControlPC = m_Regs->Eip;
@@ -798,10 +804,13 @@ void ResumableFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
#endif // !WIN64EXCEPTIONS
+ LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK ResumableFrame::UpdateRegDisplay(ip:%p, sp:%p)\n", pRD->ControlPC, pRD->SP));
+
RETURN;
}
// The HijackFrame has to know the registers that are pushed by OnHijackTripThread
+// -> HijackFrame::UpdateRegDisplay should restore all the registers pushed by OnHijackTripThread
void HijackFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
{
CONTRACTL {
@@ -820,21 +829,17 @@ void HijackFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary.
pRD->pCurrentContext->Eip = *PTR_PCODE(pRD->PCTAddr);
- pRD->pCurrentContext->Esp = (DWORD)(pRD->PCTAddr + sizeof(TADDR));
-
-#define CALLEE_SAVED_REGISTER(reg) pRD->pCurrentContext->reg = m_Args->reg;
- ENUM_CALLEE_SAVED_REGISTERS();
-#undef CALLEE_SAVED_REGISTER
+ pRD->pCurrentContext->Esp = pRD->pCurrentContext->ResumeEsp = (DWORD)(pRD->PCTAddr + sizeof(TADDR));
-#define CALLEE_SAVED_REGISTER(reg) pRD->pCurrentContextPointers->reg = NULL;
+#define RESTORE_REG(reg) { pRD->pCurrentContext->reg = m_Args->reg; pRD->pCurrentContextPointers->reg = &m_Args->reg; }
+#define CALLEE_SAVED_REGISTER(reg) RESTORE_REG(reg)
ENUM_CALLEE_SAVED_REGISTERS();
#undef CALLEE_SAVED_REGISTER
-#define ARGUMENT_AND_SCRATCH_REGISTER(reg) pRD->pCurrentContextPointers->reg = NULL;
+#define ARGUMENT_AND_SCRATCH_REGISTER(reg) RESTORE_REG(reg)
ENUM_ARGUMENT_AND_SCRATCH_REGISTERS();
#undef ARGUMENT_AND_SCRATCH_REGISTER
-
- pRD->pCurrentContextPointers->Eax = (PDWORD) &m_Args->Eax;
+#undef RESTORE_REG
SyncRegDisplayToCurrentContext(pRD);
@@ -843,18 +848,22 @@ void HijackFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
// This only describes the top-most frame
pRD->pContext = NULL;
- pRD->pEdi = &m_Args->Edi;
- pRD->pEsi = &m_Args->Esi;
- pRD->pEbx = &m_Args->Ebx;
- pRD->pEdx = &m_Args->Edx;
- pRD->pEcx = &m_Args->Ecx;
- pRD->pEax = &m_Args->Eax;
+#define RESTORE_REG(reg) { pRD->p##reg = &m_Args->reg; }
+#define CALLEE_SAVED_REGISTER(reg) RESTORE_REG(reg)
+ ENUM_CALLEE_SAVED_REGISTERS();
+#undef CALLEE_SAVED_REGISTER
+
+#define ARGUMENT_AND_SCRATCH_REGISTER(reg) RESTORE_REG(reg)
+ ENUM_ARGUMENT_AND_SCRATCH_REGISTERS();
+#undef ARGUMENT_AND_SCRATCH_REGISTER
+#undef RESTORE_REG
- pRD->pEbp = &m_Args->Ebp;
pRD->ControlPC = *PTR_PCODE(pRD->PCTAddr);
pRD->SP = (DWORD)(pRD->PCTAddr + sizeof(TADDR));
#endif // WIN64EXCEPTIONS
+
+ LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK HijackFrame::UpdateRegDisplay(ip:%p, sp:%p)\n", pRD->ControlPC, pRD->SP));
}
#endif // FEATURE_HIJACK
@@ -874,6 +883,8 @@ void PInvokeCalliFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
VASigCookie *pVASigCookie = GetVASigCookie();
UpdateRegDisplayHelper(pRD, pVASigCookie->sizeOfArgs+sizeof(int));
+ LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK PInvokeCalliFrame::UpdateRegDisplay(ip:%p, sp:%p)\n", pRD->ControlPC, pRD->SP));
+
RETURN;
}
@@ -889,8 +900,6 @@ void TailCallFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
}
CONTRACT_END;
- // reset pContext; it's only valid for active (top-most) frame
- pRD->pContext = NULL;
pRD->PCTAddr = GetReturnAddressPtr();
#ifdef WIN64EXCEPTIONS
@@ -899,7 +908,7 @@ void TailCallFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary.
pRD->pCurrentContext->Eip = *PTR_PCODE(pRD->PCTAddr);
- pRD->pCurrentContext->Esp = (DWORD)(pRD->PCTAddr + sizeof(TADDR));
+ pRD->pCurrentContext->Esp = pRD->pCurrentContext->ResumeEsp = (DWORD)(pRD->PCTAddr + sizeof(TADDR));
UpdateRegDisplayFromCalleeSavedRegisters(pRD, &m_regs);
ClearRegDisplayArgumentAndScratchRegisters(pRD);
@@ -908,6 +917,9 @@ void TailCallFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
#else
+ // reset pContext; it's only valid for active (top-most) frame
+ pRD->pContext = NULL;
+
#define CALLEE_SAVED_REGISTER(regname) pRD->p##regname = (DWORD*) &m_regs.regname;
ENUM_CALLEE_SAVED_REGISTERS();
#undef CALLEE_SAVED_REGISTER
@@ -1068,522 +1080,6 @@ Stub *GenerateInitPInvokeFrameHelper()
RETURN psl->Link(SystemDomain::GetGlobalLoaderAllocator()->GetExecutableHeap());
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-
-static void STDCALL LeaveRuntimeHelperWithFrame (Thread *pThread, size_t target, Frame *pFrame)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- Thread::LeaveRuntimeThrowComplus(target);
- GCX_COOP_THREAD_EXISTS(pThread);
- pFrame->Push(pThread);
-
-}
-
-static void STDCALL EnterRuntimeHelperWithFrame (Thread *pThread, Frame *pFrame)
-{
- // make sure we restore the original Win32 last error before leaving this function - we are
- // called right after returning from the P/Invoke target and the error has not been saved yet
- BEGIN_PRESERVE_LAST_ERROR;
-
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- {
- HRESULT hr = Thread::EnterRuntimeNoThrow();
- GCX_COOP_THREAD_EXISTS(pThread);
- if (FAILED(hr))
- {
- INSTALL_UNWIND_AND_CONTINUE_HANDLER;
- ThrowHR (hr);
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
- }
-
- pFrame->Pop(pThread);
- }
-
- END_PRESERVE_LAST_ERROR;
-}
-
-// "ip" is the return address
-// This function disassembles the code at the return address to determine
-// how many arguments to pop off.
-// Returns the number of DWORDs that should be popped off on return.
-
-static int STDCALL GetStackSizeForVarArgCall(BYTE* ip)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- int retValue = 0;
- //BEGIN_ENTRYPOINT_VOIDRET;
-
- // The instruction immediately following the call may be a move into esp used for
- // P/Invoke stack resilience. For caller-pop calls it's always mov esp, [ebp-n].
- if (ip[0] == 0x8b)
- {
- if (ip[1] == 0x65)
- {
- // mov esp, [ebp+disp8]
- ip += 3;
- }
- else if (ip[1] == 0xa5)
- {
- // mov esp, [ebp+disp32]
- ip += 6;
- }
- }
-
- if (ip[0] == 0x81 && ip[1] == 0xc4)
- {
- // add esp, imm32
- retValue = (*(int*)&ip[2])/4;
- }
- else if (ip[0] == 0x83 && ip[1] == 0xc4)
- {
- // add esp, imm8
- retValue = ip[2]/4;
- }
- else if (ip[0] == 0x59)
- {
- // pop ecx
- retValue = 1;
- }
- else
- {
- retValue = 0;
- }
- //END_ENTRYPOINT_VOIDRET;
- return retValue;
-}
-
-void LeaveRuntimeStackProbeOnly()
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
-#ifdef FEATURE_STACK_PROBE
- RetailStackProbe(ADJUST_PROBE(DEFAULT_ENTRY_PROBE_AMOUNT));
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Hosting stub for calls from CLR code to unmanaged code
-//
-// We push a LeaveRuntimeFrame, and then re-push all the arguments.
-// Note that we have to support all the different native calling conventions
-// viz. stdcall, thiscall, cdecl, varargs
-
-#if 0
-
-This is a diagramatic description of what the stub does:
-
- (lower addresses)
-
- | |
- +----------------+ <--- ESP
- | |
- | copied |
- | arguments |
- | |
- | |
- +----------------+
- | EDX |
- | ECX |
- +----------------+
-| | | GSCookie |
-| | +----------------+ <--- ESI
-| | | vptr |
-| | +----------------+
-| | | m_Next |
-| | +----------------+
-| | | EDI | Scratch register
-| | | ESI | For LeaveRuntimeFrame*
-| | | EBX | For Thread*
-| | +----------------+ <--- EBP
-| | | EBP |
-+----------------+ <---ESP +----------------+
-| ret addr | | ret addr |
-+----------------+ +----------------+
-| | | |
-| arguments | | arguments |
-| | | |
-| | | |
-+----------------+ +----------------+
-| | | |
-| caller's frame | | caller's frame |
-| | | |
-
- (higher addresses)
-
- Stack on entry Stack before the call
- to this stub. to unmanaged code.
-
-#endif
-
-//-----------------------------------------------------------------------------
-// This the layout of the frame of the stub
-
-struct StubForHostStackFrame
-{
- LPVOID m_outgingArgs[1];
- ArgumentRegisters m_argumentRegisters;
- GSCookie m_gsCookie;
- LeaveRuntimeFrame m_LeaveRuntimeFrame;
- CalleeSavedRegisters m_calleeSavedRegisters;
- LPVOID m_retAddr;
- LPVOID m_incomingArgs[1];
-
-public:
-
- // Where does the FP/EBP point to?
- static INT32 GetFPpositionOffset()
- {
- LIMITED_METHOD_CONTRACT;
- return offsetof(StubForHostStackFrame, m_calleeSavedRegisters) +
- offsetof(CalleeSavedRegisters, Ebp);
- }
-
- static INT32 GetFPrelOffsOfArgumentRegisters()
- {
- LIMITED_METHOD_CONTRACT;
- return offsetof(StubForHostStackFrame, m_argumentRegisters) - GetFPpositionOffset();
- }
-
- static INT32 GetFPrelOffsOfCalleeSavedRegisters()
- {
- LIMITED_METHOD_CONTRACT;
- return offsetof(StubForHostStackFrame, m_calleeSavedRegisters) - GetFPpositionOffset();
- }
-
- static INT32 GetFPrelOffsOfRetAddr()
- {
- LIMITED_METHOD_CONTRACT;
- return offsetof(StubForHostStackFrame, m_retAddr) - GetFPpositionOffset();
- }
-
- static INT32 GetFPrelOffsOfIncomingArgs()
- {
- LIMITED_METHOD_CONTRACT;
- return offsetof(StubForHostStackFrame, m_incomingArgs) - GetFPpositionOffset();
- }
-};
-
-static Stub *GenerateStubForHostWorker(LoaderHeap *pHeap,
- LPVOID pNativeTarget, // NULL to fetch from the last pushed argument (COM)
- Stub *pInnerStub, // stub to call instead of pNativeTarget, or NULL
- LONG dwComSlot, // only valid if pNativeTarget is NULL
- WORD wStackArgumentSize, // -1 for varargs
- WORD wStackPopSize) // 0 for cdecl
-{
- STANDARD_VM_CONTRACT;
-
- // We need to call LeaveRuntime before the target, and EnterRuntime after the target
- CPUSTUBLINKER sl;
-
- sl.X86EmitPushEBPframe();
-
- // save EBX, ESI, EDI
- sl.X86EmitPushReg(kEBX);
- sl.X86EmitPushReg(kESI);
- sl.X86EmitPushReg(kEDI);
-
- // Frame
- sl.X86EmitPushReg(kDummyPushReg); // m_Next
- sl.X86EmitPushImm32((UINT)(size_t)LeaveRuntimeFrame::GetMethodFrameVPtr());
-
- // mov esi, esp; esi is Frame
- sl.X86EmitMovRegSP(kESI);
-
- sl.X86EmitPushImmPtr((LPVOID)GetProcessGSCookie());
-
- // Save outgoing arguments on the stack
- sl.X86EmitPushReg(kECX);
- sl.X86EmitPushReg(kEDX);
-
- INT32 offs = 0;
- if (wStackArgumentSize == (WORD)-1)
- {
- // Re-push the return address as an argument to GetStackSizeForVarArgCall()
- // This will return the number of stack arguments (in DWORDs)
- sl.X86EmitIndexPush(kEBP, StubForHostStackFrame::GetFPrelOffsOfRetAddr());
- sl.X86EmitCall(sl.NewExternalCodeLabel((LPVOID)GetStackSizeForVarArgCall), 4);
-
- // We generate the following code sequence to re-push all the arguments
- //
- // Note that we cannot use "sub ESP, EAX" as ESP might jump past the
- // stack guard-page.
- //
- // cmp EAX, 0
- // LoopTop:
- // jz LoopDone
- // push dword ptr[EBP + EAX*4 + 4]
- // sub EAX, 1
- // jmp LoopTop
- // LoopDone:
- // ...
-
- sl.X86EmitCmpRegImm32(kEAX, 0);
- CodeLabel * pLoopTop = sl.EmitNewCodeLabel();
- CodeLabel * pLoopDone = sl.NewCodeLabel();
- sl.X86EmitCondJump(pLoopDone, X86CondCode::kJZ);
- sl.X86EmitBaseIndexPush(kEBP, kEAX, 4, StubForHostStackFrame::GetFPrelOffsOfIncomingArgs() - sizeof(LPVOID));
- sl.X86EmitSubReg(kEAX, 1);
- sl.X86EmitNearJump(pLoopTop);
- sl.EmitLabel(pLoopDone);
- }
- else
- {
- offs = StubForHostStackFrame::GetFPrelOffsOfIncomingArgs() + wStackArgumentSize;
-
- int numStackSlots = wStackArgumentSize / sizeof(LPVOID);
- for (int i = 0; i < numStackSlots; i++) {
- offs -= sizeof(LPVOID);
- sl.X86EmitIndexPush(kEBP, offs);
- }
- }
-
- //-------------------------------------------------------------------------
-
- // EBX has Thread*
- // X86TLSFetch_TRASHABLE_REGS will get trashed
- sl.X86EmitCurrentThreadFetch(kEBX, 0);
-
- if (pNativeTarget != NULL)
- {
- // push Frame
- sl.X86EmitPushReg(kESI);
-
- // push target
- if (pNativeTarget == (LPVOID)-1)
- {
- // target comes right above arguments
- sl.X86EmitIndexPush(kEBP, StubForHostStackFrame::GetFPrelOffsOfIncomingArgs() + wStackArgumentSize);
- }
- else
- {
- // target is fixed
- sl.X86EmitPushImm32((UINT)(size_t)pNativeTarget);
- }
- }
- else
- {
- // mov eax, [first_arg]
- // mov eax, [eax]
- // push [eax + slot_offset]
- sl.X86EmitIndexRegLoad(kEAX, kEBP, offs);
- sl.X86EmitIndexRegLoad(kEAX, kEAX, 0);
- sl.X86EmitIndexPush(kEAX, sizeof(LPVOID) * dwComSlot);
-
- // push Frame
- sl.X86EmitPushReg(kESI);
- // push [esp + 4]
- sl.X86EmitEspOffset(0xff, (X86Reg)6, 4);
- }
-
- // push Thread
- sl.X86EmitPushReg(kEBX);
- sl.X86EmitCall(sl.NewExternalCodeLabel((LPVOID)LeaveRuntimeHelperWithFrame), 0xc);
-
- //-------------------------------------------------------------------------
- // call NDirect
- // See diagram above to see what the stack looks like at this point
-
- // Restore outgoing arguments
- unsigned offsToArgRegs = StubForHostStackFrame::GetFPrelOffsOfArgumentRegisters();
- sl.X86EmitIndexRegLoad(kECX, kEBP, offsToArgRegs + offsetof(ArgumentRegisters, ECX));
- sl.X86EmitIndexRegLoad(kEDX, kEBP, offsToArgRegs + offsetof(ArgumentRegisters, EDX));
-
- if (pNativeTarget != NULL || pInnerStub != NULL)
- {
- if (pNativeTarget == (LPVOID)-1)
- {
- // mov eax, target
- sl.X86EmitIndexRegLoad(kEAX, kEBP, StubForHostStackFrame::GetFPrelOffsOfIncomingArgs() + wStackArgumentSize);
- // call eax
- sl.Emit16(X86_INSTR_CALL_EAX);
- }
- else
- {
- if (pNativeTarget == NULL)
- {
- // pop target and discard it (we go to the inner stub)
- _ASSERTE(pInnerStub != NULL);
- sl.X86EmitPopReg(kEAX);
- }
-
- LPVOID pTarget = (pInnerStub != NULL ? (LPVOID)pInnerStub->GetEntryPoint() : pNativeTarget);
- sl.X86EmitCall(sl.NewExternalCodeLabel(pTarget), wStackPopSize / 4);
- }
- }
- else
- {
- // pop target
- sl.X86EmitPopReg(kEAX);
- // call eax
- sl.Emit16(X86_INSTR_CALL_EAX);
- }
-
- //-------------------------------------------------------------------------
- // Save return value registers and call EnterRuntimeHelperWithFrame
- //
-
- sl.X86EmitPushReg(kEAX);
- sl.X86EmitPushReg(kEDX);
-
- // push Frame
- sl.X86EmitPushReg(kESI);
- // push Thread
- sl.X86EmitPushReg(kEBX);
- // call EnterRuntime
- sl.X86EmitCall(sl.NewExternalCodeLabel((LPVOID)EnterRuntimeHelperWithFrame), 8);
-
- sl.X86EmitPopReg(kEDX);
- sl.X86EmitPopReg(kEAX);
-
- //-------------------------------------------------------------------------
- // Tear down the frame
- //
-
- sl.EmitCheckGSCookie(kESI, LeaveRuntimeFrame::GetOffsetOfGSCookie());
-
- // lea esp, [ebp - offsToCalleeSavedRegs]
- unsigned offsToCalleeSavedRegs = StubForHostStackFrame::GetFPrelOffsOfCalleeSavedRegisters();
- sl.X86EmitIndexLea((X86Reg)kESP_Unsafe, kEBP, offsToCalleeSavedRegs);
-
- sl.X86EmitPopReg(kEDI);
- sl.X86EmitPopReg(kESI);
- sl.X86EmitPopReg(kEBX);
-
- sl.X86EmitPopReg(kEBP);
-
- // ret [wStackPopSize]
- sl.X86EmitReturn(wStackPopSize);
-
- if (pInnerStub != NULL)
- {
- // this stub calls another stub
- return sl.LinkInterceptor(pHeap, pInnerStub, pNativeTarget);
- }
- else
- {
- return sl.Link(pHeap);
- }
-}
-
-
-//-----------------------------------------------------------------------------
-Stub *NDirectMethodDesc::GenerateStubForHost(LPVOID pNativeTarget, Stub *pInnerStub)
-{
- STANDARD_VM_CONTRACT;
-
- // We need to call LeaveRuntime before the target, and EnterRuntime after the target
-
- if (IsQCall())
- {
- // We need just the stack probe for QCalls
- CPUSTUBLINKER sl;
- sl.X86EmitCall(sl.NewExternalCodeLabel((LPVOID)LeaveRuntimeStackProbeOnly), 0);
-
- sl.X86EmitNearJump(sl.NewExternalCodeLabel((LPVOID)pNativeTarget));
-
- return sl.Link(GetLoaderAllocator()->GetStubHeap());
- }
-
- WORD wArgSize = (IsVarArgs() ? (WORD)-1 : GetStackArgumentSize());
- WORD wPopSize = ((IsStdCall() || IsThisCall()) ? GetStackArgumentSize() : 0);
-
- return GenerateStubForHostWorker(GetDomain()->GetLoaderAllocator()->GetStubHeap(),
- pNativeTarget,
- pInnerStub,
- 0,
- wArgSize,
- wPopSize);
-}
-
-
-#ifdef FEATURE_COMINTEROP
-
-//-----------------------------------------------------------------------------
-Stub *ComPlusCallInfo::GenerateStubForHost(LoaderHeap *pHeap, Stub *pInnerStub)
-{
- STANDARD_VM_CONTRACT;
-
- WORD wArgSize = GetStackArgumentSize();
-
- return GenerateStubForHostWorker(pHeap,
- NULL,
- pInnerStub,
- m_cachedComSlot,
- wArgSize,
- wArgSize); // always stdcall
-}
-
-#endif // FEATURE_COMINTEROP
-
-//-----------------------------------------------------------------------------
-// static
-Stub *COMDelegate::GenerateStubForHost(MethodDesc *pInvokeMD, MethodDesc *pStubMD, LPVOID pNativeTarget, Stub *pInnerStub)
-{
- STANDARD_VM_CONTRACT;
-
- // get unmanaged calling convention from pInvokeMD's metadata
- PInvokeStaticSigInfo sigInfo(pInvokeMD);
- CorPinvokeMap callConv = sigInfo.GetCallConv();
-
- WORD wArgSize = pStubMD->AsDynamicMethodDesc()->GetNativeStackArgSize();
- WORD wPopSize = (callConv == pmCallConvCdecl ? 0 : wArgSize);
-
- return GenerateStubForHostWorker(NULL, // we want to free this stub when the delegate dies
- pNativeTarget,
- pInnerStub,
- 0,
- wArgSize,
- wPopSize);
-}
-
-//-----------------------------------------------------------------------------
-// static
-Stub *NDirect::GenerateStubForHost(Module *pModule, CorUnmanagedCallingConvention callConv, WORD wArgSize)
-{
- STANDARD_VM_CONTRACT;
-
- // This one is for unmanaged CALLI where the target is passed as last argument
- // (first pushed to stack)
-
- WORD wPopSize = (callConv == IMAGE_CEE_CS_CALLCONV_C ? 0 : (wArgSize + STACK_ELEM_SIZE));
-
- return GenerateStubForHostWorker(pModule->GetDomain()->GetLoaderAllocator()->GetStubHeap(),
- (LPVOID)-1,
- NULL,
- 0,
- wArgSize,
- wPopSize);
-}
-
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#ifdef MDA_SUPPORTED
@@ -1976,7 +1472,7 @@ extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16])
" mov %%edx, 12(%[result])\n" \
: "=a"(eax) /*output in eax*/\
: "a"(arg), [result]"r"(result) /*inputs - arg in eax, result in any register*/\
- : "eax", "rbx", "ecx", "edx", "memory" /* registers that are clobbered, *result is clobbered */
+ : "eax", "ebx", "ecx", "edx", "memory" /* registers that are clobbered, *result is clobbered */
);
return eax;
}
@@ -1991,7 +1487,7 @@ extern "C" DWORD __stdcall getextcpuid(DWORD arg1, DWORD arg2, unsigned char res
" mov %%edx, 12(%[result])\n" \
: "=a"(eax) /*output in eax*/\
: "c"(arg1), "a"(arg2), [result]"r"(result) /*inputs - arg1 in ecx, arg2 in eax, result in any register*/\
- : "eax", "rbx", "ecx", "edx", "memory" /* registers that are clobbered, *result is clobbered */
+ : "eax", "ebx", "ecx", "edx", "memory" /* registers that are clobbered, *result is clobbered */
);
return eax;
}
diff --git a/src/vm/i386/ehhelpers.S b/src/vm/i386/ehhelpers.S
new file mode 100644
index 0000000000..43ef37fa24
--- /dev/null
+++ b/src/vm/i386/ehhelpers.S
@@ -0,0 +1,103 @@
+// 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.
+
+.intel_syntax noprefix
+#include "unixasmmacros.inc"
+#include "asmconstants.h"
+
+// DWORD_PTR STDCALL CallEHFunclet(Object *pThrowable, UINT_PTR pFuncletToInvoke, UINT_PTR *pFirstNonVolReg, UINT_PTR *pFuncletCallerSP);
+// ESP based frame
+NESTED_ENTRY CallEHFunclet, _TEXT, NoHandler
+
+ ESP_PROLOG_BEG
+ ESP_PROLOG_PUSH ebp
+ ESP_PROLOG_PUSH ebx
+ ESP_PROLOG_PUSH esi
+ ESP_PROLOG_PUSH edi
+ ESP_PROLOG_ALLOC 12
+ ESP_PROLOG_END
+
+ lea ebp, [esp + 3*4 + 12]
+
+ // On entry:
+ //
+ // [ebp+ 8] = throwable
+ // [ebp+12] = PC to invoke
+ // [ebp+16] = address of EDI register in CONTEXT record // used to restore the non-volatile registers of CrawlFrame
+ // [ebp+20] = address of the location where the SP of funclet's caller (i.e. this helper) should be saved.
+ //
+
+ // Save the SP of this function
+ mov eax, [ebp + 20]
+ mov [eax], esp
+ // Save the funclet PC for later call
+ mov edx, [ebp + 12]
+ // Pass throwable object to funclet
+ mov eax, [ebp + 8]
+ // Restore non-volatiles registers
+ mov ecx, [ebp + 16]
+ mov edi, [ecx]
+ mov esi, [ecx + 4]
+ mov ebx, [ecx + 8]
+ mov ebp, [ecx + 24]
+ // Invoke the funclet
+ call edx
+
+ ESP_EPILOG_BEG
+ ESP_EPILOG_FREE 12
+ ESP_EPILOG_POP edi
+ ESP_EPILOG_POP esi
+ ESP_EPILOG_POP ebx
+ ESP_EPILOG_POP ebp
+ ESP_EPILOG_END
+
+ ret 16
+
+NESTED_END CallEHFunclet, _TEXT
+
+// DWORD_PTR STDCALL CallEHFilterFunclet(Object *pThrowable, TADDR CallerSP, UINT_PTR pFuncletToInvoke, UINT_PTR *pFuncletCallerSP);
+// ESP based frame
+NESTED_ENTRY CallEHFilterFunclet, _TEXT, NoHandler
+
+ ESP_PROLOG_BEG
+ ESP_PROLOG_PUSH ebp
+ ESP_PROLOG_PUSH ebx
+ ESP_PROLOG_PUSH esi
+ ESP_PROLOG_PUSH edi
+ ESP_PROLOG_ALLOC 12
+ ESP_PROLOG_END
+
+ lea ebp, [esp + 3*4 + 12]
+
+ // On entry:
+ //
+ // [ebp+ 8] = throwable
+ // [ebp+12] = FP to restore
+ // [ebp+16] = PC to invoke
+ // [ebp+20] = address of the location where the SP of funclet's caller (i.e. this helper) should be saved.
+ //
+
+ // Save the SP of this function
+ mov eax, [ebp + 20]
+ mov [eax], esp
+ // Save the funclet PC for later call
+ mov edx, [ebp + 16]
+ // Pass throwable object to funclet
+ mov eax, [ebp + 8]
+ // Restore FP
+ mov ebp, [ebp + 12]
+ // Invoke the funclet
+ call edx
+
+ ESP_EPILOG_BEG
+ ESP_EPILOG_FREE 12
+ ESP_EPILOG_POP edi
+ ESP_EPILOG_POP esi
+ ESP_EPILOG_POP ebx
+ ESP_EPILOG_POP ebp
+ ESP_EPILOG_END
+
+ ret 16
+
+NESTED_END CallEHFunclet, _TEXT
diff --git a/src/vm/i386/excepx86.cpp b/src/vm/i386/excepx86.cpp
index b860800943..2c863b2ec3 100644
--- a/src/vm/i386/excepx86.cpp
+++ b/src/vm/i386/excepx86.cpp
@@ -27,9 +27,6 @@
#include "eedbginterfaceimpl.inl"
#include "dllimportcallback.h"
#include "threads.h"
-#ifdef FEATURE_REMOTING
-#include "appdomainhelper.h"
-#endif
#include "eeconfig.h"
#include "vars.hpp"
#include "generics.h"
@@ -1095,7 +1092,6 @@ CPFH_RealFirstPassHandler( // ExceptionContinueSearch, etc.
}
#endif // FEATURE_CORRUPTING_EXCEPTIONS
-#ifdef FEATURE_CORECLR
// Check if we are dealing with AV or not and if we are,
// ensure that this is a real AV and not managed AV exception
BOOL fIsThrownExceptionAV = FALSE;
@@ -1124,7 +1120,6 @@ CPFH_RealFirstPassHandler( // ExceptionContinueSearch, etc.
EEPOLICY_HANDLE_FATAL_ERROR(COR_E_SECURITY);
}
}
-#endif // FEATURE_CORECLR
// If we're out of memory, then we figure there's probably not memory to maintain a stack trace, so we skip it.
// If we've got a stack overflow, then we figure the stack will be so huge as to make tracking the stack trace
@@ -2433,13 +2428,11 @@ StackWalkAction COMPlusThrowCallback( // SWA value
currentSP = (SIZE_T) ((void*) pFrameStub);
currentIP = 0; // no IP.
EEToDebuggerExceptionInterfaceWrapper::FirstChanceManagedException(pThread, (SIZE_T)currentIP, (SIZE_T)currentSP);
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
// Deliver the FirstChanceNotification after the debugger, if not already delivered.
if (!pExInfo->DeliveredFirstChanceNotification())
{
ExceptionNotifications::DeliverFirstChanceNotification();
}
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
}
}
}
@@ -2488,14 +2481,12 @@ StackWalkAction COMPlusThrowCallback( // SWA value
}
#endif // DEBUGGING_SUPPORTED
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
// Attempt to deliver the first chance notification to the AD only *AFTER* the debugger
// has done that, provided we have not already done that.
if (!pExInfo->DeliveredFirstChanceNotification())
{
ExceptionNotifications::DeliverFirstChanceNotification();
}
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
}
IJitManager* pJitManager = pCf->GetJitManager();
_ASSERTE(pJitManager);
diff --git a/src/vm/i386/jithelp.S b/src/vm/i386/jithelp.S
index 9a7e3344cd..dd3f8042c5 100644
--- a/src/vm/i386/jithelp.S
+++ b/src/vm/i386/jithelp.S
@@ -371,12 +371,12 @@ NESTED_END JIT_ByRefWriteBarrier, _TEXT
.endm
-// WriteBarrierStart and WriteBarrierEnd are used to determine bounds of
-// WriteBarrier functions so can determine if got AV in them.
+// JIT_WriteBarrierGroup and JIT_WriteBarrierGroup_End are used
+// to determine bounds of WriteBarrier functions so can determine if got AV in them.
//
-LEAF_ENTRY JIT_WriteBarrierStart, _TEXT
+LEAF_ENTRY JIT_WriteBarrierGroup, _TEXT
ret
-LEAF_END JIT_WriteBarrierStart, _TEXT
+LEAF_END JIT_WriteBarrierGroup, _TEXT
#ifdef FEATURE_USE_ASM_GC_WRITE_BARRIERS
// *******************************************************************************
@@ -408,14 +408,10 @@ WriteBarrierHelper EBP
ByRefWriteBarrierHelper
-LEAF_ENTRY JIT_WriteBarrierLast, _TEXT
- ret
-LEAF_END JIT_WriteBarrierLast, _TEXT
-
// This is the first function outside the "keep together range". Used by BBT scripts.
-LEAF_ENTRY JIT_WriteBarrierEnd, _TEXT
+LEAF_ENTRY JIT_WriteBarrierGroup_End, _TEXT
ret
-LEAF_END JIT_WriteBarrierEnd, _TEXT
+LEAF_END JIT_WriteBarrierGroup_End, _TEXT
// *********************************************************************/
// In cases where we support it we have an optimized GC Poll callback.
@@ -566,7 +562,7 @@ LEAF_ENTRY JIT_Dbl2LngP4x87, _TEXT
// restore stack
add esp, 8
- ret 8
+ ret
LEAF_END JIT_Dbl2LngP4x87, _TEXT
// *********************************************************************/
@@ -592,7 +588,7 @@ LEAF_ENTRY JIT_Dbl2LngSSE3, _TEXT
// restore stack
add esp, 8
- ret 8
+ ret
LEAF_END JIT_Dbl2LngSSE3, _TEXT
// *********************************************************************/
@@ -609,7 +605,7 @@ LEAF_END JIT_Dbl2LngSSE3, _TEXT
LEAF_ENTRY JIT_Dbl2IntSSE2, _TEXT
movsd xmm0, [esp + 4]
cvttsd2si eax, xmm0
- ret 8
+ ret
LEAF_END JIT_Dbl2IntSSE2, _TEXT
// *********************************************************************/
@@ -688,9 +684,9 @@ LEAF_END JIT_PatchedCodeStart, _TEXT
// **********************************************************************
// Write barriers generated at runtime
-LEAF_ENTRY JIT_PatchedWriteBarrierStart, _TEXT
+LEAF_ENTRY JIT_PatchedWriteBarrierGroup, _TEXT
ret
-LEAF_END JIT_PatchedWriteBarrierStart, _TEXT
+LEAF_END JIT_PatchedWriteBarrierGroup, _TEXT
.macro PatchedWriteBarrierHelper rg
.align 8
@@ -708,15 +704,11 @@ PatchedWriteBarrierHelper ESI
PatchedWriteBarrierHelper EDI
PatchedWriteBarrierHelper EBP
-LEAF_ENTRY JIT_PatchedWriteBarrierLast, _TEXT
+// This is the first function outside the "keep together range". Used by BBT scripts.
+LEAF_ENTRY JIT_PatchedWriteBarrierGroup_End, _TEXT
ret
-LEAF_END JIT_PatchedWriteBarrierLast, _TEXT
+LEAF_END JIT_PatchedWriteBarrierGroup_End, _TEXT
LEAF_ENTRY JIT_PatchedCodeLast, _TEXT
ret
LEAF_END JIT_PatchedCodeLast, _TEXT
-
-// This is the first function outside the "keep together range". Used by BBT scripts.
-LEAF_ENTRY JIT_PatchedCodeEnd, _TEXT
- ret
-LEAF_END JIT_PatchedCodeEnd, _TEXT
diff --git a/src/vm/i386/jithelp.asm b/src/vm/i386/jithelp.asm
index 9d2f6b7589..e8d2f121e0 100644
--- a/src/vm/i386/jithelp.asm
+++ b/src/vm/i386/jithelp.asm
@@ -87,11 +87,6 @@ EXTERN g_GCShadowEnd:DWORD
INVALIDGCVALUE equ 0CCCCCCCDh
endif
-ifdef FEATURE_REMOTING
-EXTERN _TransparentProxyStub_CrossContext@0:PROC
-EXTERN _InContextTPQuickDispatchAsmStub@0:PROC
-endif
-
EXTERN _COMPlusEndCatch@20:PROC
.686P
@@ -439,10 +434,10 @@ ENDM
; WriteBarrierStart and WriteBarrierEnd are used to determine bounds of
; WriteBarrier functions so can determine if got AV in them.
;
-PUBLIC _JIT_WriteBarrierStart@0
-_JIT_WriteBarrierStart@0 PROC
+PUBLIC _JIT_WriteBarrierGroup@0
+_JIT_WriteBarrierGroup@0 PROC
ret
-_JIT_WriteBarrierStart@0 ENDP
+_JIT_WriteBarrierGroup@0 ENDP
ifdef FEATURE_USE_ASM_GC_WRITE_BARRIERS
; Only define these if we're using the ASM GC write barriers; if this flag is not defined,
@@ -460,16 +455,11 @@ WriteBarrierHelper <EBP>
ByRefWriteBarrierHelper
-PUBLIC _JIT_WriteBarrierLast@0
-_JIT_WriteBarrierLast@0 PROC
-ret
-_JIT_WriteBarrierLast@0 ENDP
-
; This is the first function outside the "keep together range". Used by BBT scripts.
-PUBLIC _JIT_WriteBarrierEnd@0
-_JIT_WriteBarrierEnd@0 PROC
+PUBLIC _JIT_WriteBarrierGroup_End@0
+_JIT_WriteBarrierGroup_End@0 PROC
ret
-_JIT_WriteBarrierEnd@0 ENDP
+_JIT_WriteBarrierGroup_End@0 ENDP
;*********************************************************************/
; In cases where we support it we have an optimized GC Poll callback. Normall (when we're not trying to
@@ -2350,10 +2340,10 @@ endif
;**********************************************************************
; Write barriers generated at runtime
-PUBLIC _JIT_PatchedWriteBarrierStart@0
-_JIT_PatchedWriteBarrierStart@0 PROC
+PUBLIC _JIT_PatchedWriteBarrierGroup@0
+_JIT_PatchedWriteBarrierGroup@0 PROC
ret
-_JIT_PatchedWriteBarrierStart@0 ENDP
+_JIT_PatchedWriteBarrierGroup@0 ENDP
PatchedWriteBarrierHelper MACRO rg
ALIGN 8
@@ -2372,54 +2362,10 @@ PatchedWriteBarrierHelper <ESI>
PatchedWriteBarrierHelper <EDI>
PatchedWriteBarrierHelper <EBP>
-PUBLIC _JIT_PatchedWriteBarrierLast@0
-_JIT_PatchedWriteBarrierLast@0 PROC
+PUBLIC _JIT_PatchedWriteBarrierGroup_End@0
+_JIT_PatchedWriteBarrierGroup_End@0 PROC
ret
-_JIT_PatchedWriteBarrierLast@0 ENDP
-
-;**********************************************************************
-; PrecodeRemotingThunk is patched at runtime to activate it
-ifdef FEATURE_REMOTING
- ALIGN 16
-_PrecodeRemotingThunk@0 proc public
-
- ret ; This is going to be patched to "test ecx,ecx"
- nop
-
- jz RemotingDone ; predicted not taken
-
- cmp dword ptr [ecx],11111111h ; This is going to be patched to address of the transparent proxy
- je RemotingCheck ; predicted not taken
-
-RemotingDone:
- ret
-
-RemotingCheck:
- push eax ; save method desc
- mov eax, dword ptr [ecx + TransparentProxyObject___stubData]
- call [ecx + TransparentProxyObject___stub]
- test eax, eax
- jnz RemotingCtxMismatch
- mov eax, [esp]
- mov ax, [eax + MethodDesc_m_wFlags]
- and ax, MethodDesc_mdcClassification
- cmp ax, MethodDesc_mcComInterop
- je ComPlusCall
- pop eax ; throw away method desc
- jmp RemotingDone
-
-RemotingCtxMismatch:
- pop eax ; restore method desc
- add esp, 4 ; pop return address into the precode
- jmp _TransparentProxyStub_CrossContext@0
-
-ComPlusCall:
- pop eax ; restore method desc
- mov [esp],eax ; replace return address into the precode with method desc (argument for TP stub)
- jmp _InContextTPQuickDispatchAsmStub@0
-
-_PrecodeRemotingThunk@0 endp
-endif ; FEATURE_REMOTING
+_JIT_PatchedWriteBarrierGroup_End@0 ENDP
_JIT_PatchedCodeLast@0 proc public
ret
diff --git a/src/vm/i386/jitinterfacex86.cpp b/src/vm/i386/jitinterfacex86.cpp
index a80b5e6325..18acbf0126 100644
--- a/src/vm/i386/jitinterfacex86.cpp
+++ b/src/vm/i386/jitinterfacex86.cpp
@@ -16,9 +16,6 @@
#include "eeconfig.h"
#include "excep.h"
#include "comdelegate.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h" // create context bound and remote class instances
-#endif
#include "field.h"
#include "ecall.h"
#include "asmconstants.h"
@@ -37,8 +34,7 @@
#define MON_DEBUG 1
#endif
-class generation;
-extern "C" generation generation_table[];
+extern "C" LONG g_global_alloc_lock;
extern "C" void STDCALL JIT_WriteBarrierReg_PreGrow();// JIThelp.asm/JIThelp.s
extern "C" void STDCALL JIT_WriteBarrierReg_PostGrow();// JIThelp.asm/JIThelp.s
@@ -205,7 +201,7 @@ extern "C" __declspec(naked) Object* F_CALL_CONV JIT_IsInstanceOfClass(MethodTab
STATIC_CONTRACT_THROWS;
STATIC_CONTRACT_GC_TRIGGERS;
-#if defined(FEATURE_TYPEEQUIVALENCE) || defined(FEATURE_REMOTING)
+#if defined(FEATURE_TYPEEQUIVALENCE)
enum
{
MTEquivalenceFlags = MethodTable::public_enum_flag_HasTypeEquivalence,
@@ -241,7 +237,7 @@ extern "C" __declspec(naked) Object* F_CALL_CONV JIT_IsInstanceOfClass(MethodTab
jne CheckParent
// Check if the instance is a proxy.
-#if defined(FEATURE_TYPEEQUIVALENCE) || defined(FEATURE_REMOTING)
+#if defined(FEATURE_TYPEEQUIVALENCE)
mov eax, [ARGUMENT_REG2]
test dword ptr [eax]MethodTable.m_dwFlags, MTEquivalenceFlags
jne SlowPath
@@ -251,7 +247,7 @@ extern "C" __declspec(naked) Object* F_CALL_CONV JIT_IsInstanceOfClass(MethodTab
ret
// Cast didn't match, so try the worker to check for the proxy/equivalence case.
-#if defined(FEATURE_TYPEEQUIVALENCE) || defined(FEATURE_REMOTING)
+#if defined(FEATURE_TYPEEQUIVALENCE)
SlowPath:
jmp JITutil_IsInstanceOfAny
#endif
@@ -354,37 +350,6 @@ HCIMPLEND
FCDECL1(Object*, JIT_New, CORINFO_CLASS_HANDLE typeHnd_);
-#ifdef FEATURE_REMOTING
-HCIMPL1(Object*, JIT_NewCrossContextHelper, CORINFO_CLASS_HANDLE typeHnd_)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- }
- CONTRACTL_END;
-
- TypeHandle typeHnd(typeHnd_);
-
- OBJECTREF newobj = NULL;
- HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame
-
- _ASSERTE(!typeHnd.IsTypeDesc()); // we never use this helper for arrays
- MethodTable *pMT = typeHnd.AsMethodTable();
- pMT->CheckRestore();
-
- // Remoting services determines if the current context is appropriate
- // for activation. If the current context is OK then it creates an object
- // else it creates a proxy.
- // Note: 3/20/03 Added fIsNewObj flag to indicate that CreateProxyOrObject
- // is being called from Jit_NewObj ... the fIsCom flag is FALSE by default -
- // which used to be the case before this change as well.
- newobj = CRemotingServices::CreateProxyOrObject(pMT,FALSE /*fIsCom*/,TRUE/*fIsNewObj*/);
-
- HELPER_METHOD_FRAME_END();
- return(OBJECTREFToObject(newobj));
-}
-HCIMPLEND
-#endif // FEATURE_REMOTING
HCIMPL1(Object*, AllocObjectWrapper, MethodTable *pMT)
{
@@ -408,69 +373,6 @@ HCIMPLEND
// have remote activation. If not, we use the superfast allocator to
// allocate the object. Otherwise, we take the slow path of allocating
// the object via remoting services.
-#ifdef FEATURE_REMOTING
-__declspec(naked) Object* F_CALL_CONV JIT_NewCrossContext(CORINFO_CLASS_HANDLE typeHnd_)
-{
- STATIC_CONTRACT_SO_TOLERANT;
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_GC_TRIGGERS;
-
- _asm
- {
- // Check if remoting has been configured
- push ARGUMENT_REG1 // save registers
- push ARGUMENT_REG1
- call CRemotingServices::RequiresManagedActivation
- test eax, eax
- // Jump to the slow path
- jne SpecialOrXCtxHelper
-#ifdef _DEBUG
- push LL_INFO10
- push LF_GCALLOC
- call LoggingOn
- test eax, eax
- jne AllocWithLogHelper
-#endif // _DEBUG
-
- // if the object doesn't have a finalizer and the size is small, jump to super fast asm helper
- mov ARGUMENT_REG1, [esp]
- call MethodTable::CannotUseSuperFastHelper
- test eax, eax
- jne FastHelper
-
- pop ARGUMENT_REG1
- // Jump to the super fast helper
- jmp dword ptr [hlpDynamicFuncTable + DYNAMIC_CORINFO_HELP_NEWSFAST * SIZE VMHELPDEF]VMHELPDEF.pfnHelper
-
-FastHelper:
- pop ARGUMENT_REG1
- // Jump to the helper
- jmp JIT_New
-
-SpecialOrXCtxHelper:
-#ifdef FEATURE_COMINTEROP
- test eax, ComObjectType
- jz XCtxHelper
- pop ARGUMENT_REG1
- // Jump to the helper
- jmp JIT_New
-
-XCtxHelper:
-#endif // FEATURE_COMINTEROP
-
- pop ARGUMENT_REG1
- // Jump to the helper
- jmp JIT_NewCrossContextHelper
-
-#ifdef _DEBUG
-AllocWithLogHelper:
- pop ARGUMENT_REG1
- // Jump to the helper
- jmp AllocObjectWrapper
-#endif // _DEBUG
- }
-}
-#endif // FEATURE_REMOTING
/*********************************************************************/
@@ -659,9 +561,9 @@ void JIT_TrialAlloc::EmitCore(CPUSTUBLINKER *psl, CodeLabel *noLock, CodeLabel *
else
{
// Take the GC lock (there is no lock prefix required - we will use JIT_TrialAllocSFastMP on an MP System).
- // inc dword ptr [m_GCLock]
+ // inc dword ptr [g_global_alloc_lock]
psl->Emit16(0x05ff);
- psl->Emit32((int)(size_t)&m_GCLock);
+ psl->Emit32((int)(size_t)&g_global_alloc_lock);
// jnz NoLock
psl->X86EmitCondJump(noLock, X86CondCode::kJNZ);
@@ -677,9 +579,9 @@ void JIT_TrialAlloc::EmitCore(CPUSTUBLINKER *psl, CodeLabel *noLock, CodeLabel *
psl->X86EmitIndexRegLoad(kEDX, kECX, offsetof(MethodTable, m_BaseSize));
}
- // mov eax, dword ptr [generation_table]
+ // mov eax, dword ptr [g_global_alloc_context]
psl->Emit8(0xA1);
- psl->Emit32((int)(size_t)&generation_table);
+ psl->Emit32((int)(size_t)&g_global_alloc_context);
// Try the allocation.
// add edx, eax
@@ -688,17 +590,17 @@ void JIT_TrialAlloc::EmitCore(CPUSTUBLINKER *psl, CodeLabel *noLock, CodeLabel *
if (flags & (ALIGN8 | ALIGN8OBJ))
EmitAlignmentRoundup(psl, kEAX, kEDX, flags); // bump up EDX size by 12 if EAX unaligned (so that we are aligned)
- // cmp edx, dword ptr [generation_table+4]
+ // cmp edx, dword ptr [g_global_alloc_context+4]
psl->Emit16(0x153b);
- psl->Emit32((int)(size_t)&generation_table + 4);
+ psl->Emit32((int)(size_t)&g_global_alloc_context + 4);
// ja noAlloc
psl->X86EmitCondJump(noAlloc, X86CondCode::kJA);
// Fill in the allocation and get out.
- // mov dword ptr [generation_table], edx
+ // mov dword ptr [g_global_alloc_context], edx
psl->Emit16(0x1589);
- psl->Emit32((int)(size_t)&generation_table);
+ psl->Emit32((int)(size_t)&g_global_alloc_context);
if (flags & (ALIGN8 | ALIGN8OBJ))
EmitDummyObject(psl, kEAX, flags);
@@ -706,9 +608,9 @@ void JIT_TrialAlloc::EmitCore(CPUSTUBLINKER *psl, CodeLabel *noLock, CodeLabel *
// mov dword ptr [eax], ecx
psl->X86EmitIndexRegStore(kEAX, 0, kECX);
- // mov dword ptr [m_GCLock], 0FFFFFFFFh
+ // mov dword ptr [g_global_alloc_lock], 0FFFFFFFFh
psl->Emit16(0x05C7);
- psl->Emit32((int)(size_t)&m_GCLock);
+ psl->Emit32((int)(size_t)&g_global_alloc_lock);
psl->Emit32(0xFFFFFFFF);
}
@@ -740,6 +642,12 @@ void JIT_TrialAlloc::EmitSetAppDomain(CPUSTUBLINKER *psl)
// Save ECX over function call
psl->X86EmitPushReg(kECX);
+#ifdef UNIX_X86_ABI
+#define STACK_ALIGN_PADDING 8
+ // sub esp, STACK_ALIGN_PADDING; to align the stack
+ psl->X86EmitSubEsp(STACK_ALIGN_PADDING);
+#endif // UNIX_X86_ABI
+
// mov object to ECX
// mov ecx, eax
psl->Emit16(0xc88b);
@@ -747,6 +655,12 @@ void JIT_TrialAlloc::EmitSetAppDomain(CPUSTUBLINKER *psl)
// SetObjectAppDomain pops its arg & returns object in EAX
psl->X86EmitCall(psl->NewExternalCodeLabel((LPVOID)SetObjectAppDomain), 4);
+#ifdef UNIX_X86_ABI
+ // add esp, STACK_ALIGN_PADDING
+ psl->X86EmitAddEsp(STACK_ALIGN_PADDING);
+#undef STACK_ALIGN_PADDING
+#endif // UNIX_X86_ABI
+
psl->X86EmitPopReg(kECX);
}
@@ -764,9 +678,9 @@ void JIT_TrialAlloc::EmitNoAllocCode(CPUSTUBLINKER *psl, Flags flags)
}
else
{
- // mov dword ptr [m_GCLock], 0FFFFFFFFh
+ // mov dword ptr [g_global_alloc_lock], 0FFFFFFFFh
psl->Emit16(0x05c7);
- psl->Emit32((int)(size_t)&m_GCLock);
+ psl->Emit32((int)(size_t)&g_global_alloc_lock);
psl->Emit32(0xFFFFFFFF);
}
}
@@ -1067,8 +981,10 @@ void *JIT_TrialAlloc::GenAllocArray(Flags flags)
// want to bias toward putting things in the large object heap
unsigned maxElems = 0xffff - 256;
+#ifdef FEATURE_DOUBLE_ALIGNMENT_HINT
if ((flags & ALIGN8) && g_pConfig->GetDoubleArrayToLargeObjectHeapThreshold() < maxElems)
maxElems = g_pConfig->GetDoubleArrayToLargeObjectHeapThreshold();
+#endif // FEATURE_DOUBLE_ALIGNMENT_HINT
if (flags & OBJ_ARRAY)
{
//Since we know that the array elements are sizeof(OBJECTREF), set maxElems exactly here (use the
@@ -1397,6 +1313,14 @@ void EmitFastGetSharedStaticBase(CPUSTUBLINKER *psl, CodeLabel *init, bool bCCto
// DoInit:
psl->EmitLabel(DoInit);
+ psl->X86EmitPushEBPframe();
+
+#ifdef UNIX_X86_ABI
+#define STACK_ALIGN_PADDING 4
+ // sub esp, STACK_ALIGN_PADDING; to align the stack
+ psl->X86EmitSubEsp(STACK_ALIGN_PADDING);
+#endif // UNIX_X86_ABI
+
// push edx (must be preserved)
psl->X86EmitPushReg(kEDX);
@@ -1406,6 +1330,14 @@ void EmitFastGetSharedStaticBase(CPUSTUBLINKER *psl, CodeLabel *init, bool bCCto
// pop edx
psl->X86EmitPopReg(kEDX);
+#ifdef UNIX_X86_ABI
+ // add esp, STACK_ALIGN_PADDING
+ psl->X86EmitAddEsp(STACK_ALIGN_PADDING);
+#undef STACK_ALIGN_PADDING
+#endif // UNIX_X86_ABI
+
+ psl->X86EmitPopReg(kEBP);
+
// ret
psl->X86EmitReturn(0);
}
@@ -1506,7 +1438,7 @@ void InitJITHelpers1()
_ASSERTE(g_SystemInfo.dwNumberOfProcessors != 0);
- JIT_TrialAlloc::Flags flags = GCHeapUtilities::UseAllocationContexts() ?
+ JIT_TrialAlloc::Flags flags = GCHeapUtilities::UseThreadAllocationContexts() ?
JIT_TrialAlloc::MP_ALLOCATOR : JIT_TrialAlloc::NORMAL;
// Get CPU features and check for SSE2 support.
@@ -1598,8 +1530,8 @@ void InitJITHelpers1()
// All write barrier helpers should fit into one page.
// If you hit this assert on retail build, there is most likely problem with BBT script.
- _ASSERTE_ALL_BUILDS("clr/src/VM/i386/JITinterfaceX86.cpp", (BYTE*)JIT_WriteBarrierLast - (BYTE*)JIT_WriteBarrierStart < PAGE_SIZE);
- _ASSERTE_ALL_BUILDS("clr/src/VM/i386/JITinterfaceX86.cpp", (BYTE*)JIT_PatchedWriteBarrierLast - (BYTE*)JIT_PatchedWriteBarrierStart < PAGE_SIZE);
+ _ASSERTE_ALL_BUILDS("clr/src/VM/i386/JITinterfaceX86.cpp", (BYTE*)JIT_WriteBarrierGroup_End - (BYTE*)JIT_WriteBarrierGroup < PAGE_SIZE);
+ _ASSERTE_ALL_BUILDS("clr/src/VM/i386/JITinterfaceX86.cpp", (BYTE*)JIT_PatchedWriteBarrierGroup_End - (BYTE*)JIT_PatchedWriteBarrierGroup < PAGE_SIZE);
// Copy the write barriers to their final resting place.
for (int iBarrier = 0; iBarrier < NUM_WRITE_BARRIERS; iBarrier++)
@@ -1779,8 +1711,8 @@ void StompWriteBarrierEphemeral(bool /* isRuntimeSuspended */)
}
if (flushICache)
- FlushInstructionCache(GetCurrentProcess(), (void *)JIT_PatchedWriteBarrierStart,
- (BYTE*)JIT_PatchedWriteBarrierLast - (BYTE*)JIT_PatchedWriteBarrierStart);
+ FlushInstructionCache(GetCurrentProcess(), (void *)JIT_PatchedWriteBarrierGroup,
+ (BYTE*)JIT_PatchedWriteBarrierGroup_End - (BYTE*)JIT_PatchedWriteBarrierGroup);
}
/*********************************************************************/
@@ -1916,8 +1848,8 @@ void StompWriteBarrierResize(bool isRuntimeSuspended, bool bReqUpperBoundsCheck)
}
else
{
- FlushInstructionCache(GetCurrentProcess(), (void *)JIT_PatchedWriteBarrierStart,
- (BYTE*)JIT_PatchedWriteBarrierLast - (BYTE*)JIT_PatchedWriteBarrierStart);
+ FlushInstructionCache(GetCurrentProcess(), (void *)JIT_PatchedWriteBarrierGroup,
+ (BYTE*)JIT_PatchedWriteBarrierGroup_End - (BYTE*)JIT_PatchedWriteBarrierGroup);
}
if(bEESuspendedHere)
diff --git a/src/vm/i386/remotingx86.cpp b/src/vm/i386/remotingx86.cpp
deleted file mode 100644
index 3a9e891267..0000000000
--- a/src/vm/i386/remotingx86.cpp
+++ /dev/null
@@ -1,225 +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.
-//
-//
-//
-// File: remotingx86.cpp
-//
-
-//
-//
-// Purpose: Defines various remoting related functions for the x86 architecture
-//
-
-//
-//
-
-//
-
-#include "common.h"
-
-#ifdef FEATURE_REMOTING
-
-#include "excep.h"
-#include "comdelegate.h"
-#include "remoting.h"
-#include "field.h"
-#include "siginfo.hpp"
-#include "stackbuildersink.h"
-#include "threads.h"
-#include "method.hpp"
-#include "asmconstants.h"
-#include "interoputil.h"
-#include "virtualcallstub.h"
-
-#ifdef FEATURE_COMINTEROP
-#include "comcallablewrapper.h"
-#include "comcache.h"
-#endif // FEATURE_COMINTEROP
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::CreateThunkForVirtualMethod private
-//
-// Synopsis: Creates the thunk that pushes the supplied slot number and jumps
-// to TP Stub
-//
-//+----------------------------------------------------------------------------
-PCODE CTPMethodTable::CreateThunkForVirtualMethod(DWORD dwSlot, BYTE *startaddr)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(startaddr));
- }
- CONTRACTL_END;
-
- BYTE *pCode = startaddr;
-
- // 0000 B8 67 45 23 01 MOV EAX, dwSlot
- // 0005 E9 ?? ?? ?? ?? JMP TransparentProxyStub
- *pCode++ = 0xB8;
- *((DWORD *) pCode) = dwSlot;
- pCode += sizeof(DWORD);
- *pCode++ = 0xE9;
- // self-relative call, based on the start of the next instruction.
- *((LONG *) pCode) = (LONG)((size_t)GetTPStubEntryPoint() - (size_t) (pCode + sizeof(LONG)));
-
- _ASSERTE(CVirtualThunkMgr::IsThunkByASM((PCODE)startaddr));
-
- return (PCODE)startaddr;
-}
-
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::ActivatePrecodeRemotingThunk private
-//
-// Synopsis: Patch the precode remoting thunk to begin interception
-//
-//+----------------------------------------------------------------------------
-void CTPMethodTable::ActivatePrecodeRemotingThunk()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // Before activation:
- // 0000 C3 ret
- // 0001 90 nop
-
- // After activation:
- // 0000 85 C9 test ecx,ecx
-
- // 0002 74 XX je RemotingDone
- // 0004 81 39 XX XX XX XX cmp dword ptr [ecx],11111111h
- // 000A 74 XX je RemotingCheck
-
- // Switch offset and size of patch based on the jump opcode used.
- BYTE* pCode = (BYTE*)PrecodeRemotingThunk;
-
- SIZE_T mtOffset = 0x0006;
- SIZE_T size = 0x000A;
-
- // Patch "ret + nop" to "test ecx,ecx"
- *(UINT16 *)pCode = 0xC985;
-
- // Replace placeholder value with the actual address of TP method table
- _ASSERTE(*(PVOID*)(pCode+mtOffset) == (PVOID*)0x11111111);
- *(PVOID*)(pCode+mtOffset) = GetMethodTable();
-
- FlushInstructionCache(GetCurrentProcess(), pCode, size);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CVirtualThunkMgr::DoTraceStub public
-//
-// Synopsis: Traces the stub given the starting address
-//
-//+----------------------------------------------------------------------------
-BOOL CVirtualThunkMgr::DoTraceStub(PCODE stubStartAddress, TraceDestination *trace)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(stubStartAddress != NULL);
- PRECONDITION(CheckPointer(trace));
- }
- CONTRACTL_END;
-
- BOOL bIsStub = FALSE;
-
- // Find a thunk whose code address matching the starting address
- LPBYTE pThunk = FindThunk((LPBYTE)stubStartAddress);
- if(NULL != pThunk)
- {
- LPBYTE pbAddr = NULL;
- LONG destAddress = 0;
- if((LPBYTE)stubStartAddress == pThunk)
- {
-
- // Extract the long which gives the self relative address
- // of the destination
- pbAddr = pThunk + sizeof(BYTE) + sizeof(DWORD) + sizeof(BYTE);
- destAddress = *(LONG *)pbAddr;
-
- // Calculate the absolute address by adding the offset of the next
- // instruction after the call instruction
- destAddress += (LONG)(size_t)(pbAddr + sizeof(LONG));
-
- }
-
- // We cannot tell where the stub will end up until OnCall is reached.
- // So we tell the debugger to run till OnCall is reached and then
- // come back and ask us again for the actual destination address of
- // the call
-
- Stub *stub = Stub::RecoverStub((TADDR)destAddress);
-
- trace->InitForFramePush(stub->GetPatchAddress());
- bIsStub = TRUE;
- }
-
- return bIsStub;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CVirtualThunkMgr::IsThunkByASM public
-//
-// Synopsis: Check assembly to see if this one of our thunks
-//
-//+----------------------------------------------------------------------------
-BOOL CVirtualThunkMgr::IsThunkByASM(PCODE startaddr)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(startaddr != NULL);
- }
- CONTRACTL_END;
-
- PTR_BYTE pbCode = PTR_BYTE(startaddr);
-
- return ((pbCode[0] == 0xB8) &&
- (pbCode[5] == 0xe9) &&
- (rel32Decode((TADDR)(pbCode + 6)) == CTPMethodTable::GetTPStubEntryPoint()));
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CVirtualThunkMgr::GetMethodDescByASM public
-//
-// Synopsis: Parses MethodDesc out of assembly code
-//
-//+----------------------------------------------------------------------------
-MethodDesc *CVirtualThunkMgr::GetMethodDescByASM(PCODE startaddr, MethodTable *pMT)
-{
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(startaddr != NULL);
- PRECONDITION(CheckPointer(pMT));
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN (pMT->GetMethodDescForSlot(*((DWORD *) (startaddr + 1))));
-}
-
-#endif// FEATURE_REMOTING
-
diff --git a/src/vm/i386/stublinkerx86.cpp b/src/vm/i386/stublinkerx86.cpp
index 63b9e87367..9742f9647f 100644
--- a/src/vm/i386/stublinkerx86.cpp
+++ b/src/vm/i386/stublinkerx86.cpp
@@ -26,9 +26,6 @@
#include "array.h"
#include "jitinterface.h"
#include "codeman.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "dbginterface.h"
#include "eeprofinterfaces.h"
#include "eeconfig.h"
@@ -1254,7 +1251,7 @@ VOID StubLinkerCPU::X86EmitReturn(WORD wArgBytes)
CONTRACTL
{
STANDARD_VM_CHECK;
-#ifdef _TARGET_AMD64_
+#if defined(_TARGET_AMD64_) || defined(UNIX_X86_ABI)
PRECONDITION(wArgBytes == 0);
#endif
@@ -3271,7 +3268,7 @@ VOID StubLinkerCPU::EmitMethodStubEpilog(WORD numArgBytes, int transitionBlockOf
X86EmitPopReg(kR15);
#endif
-#ifdef _TARGET_AMD64_
+#if defined(_TARGET_AMD64_) || defined(UNIX_X86_ABI)
// Caller deallocates argument space. (Bypasses ASSERT in
// X86EmitReturn.)
numArgBytes = 0;
@@ -4226,6 +4223,10 @@ VOID StubLinkerCPU::EmitShuffleThunk(ShuffleEntry *pShuffleEntryArray)
if (haveMemMemMove)
X86EmitPopReg(SCRATCH_REGISTER_X86REG);
+#ifdef UNIX_X86_ABI
+ _ASSERTE(pWalk->stacksizedelta == 0);
+#endif
+
if (pWalk->stacksizedelta)
X86EmitAddEsp(pWalk->stacksizedelta);
@@ -5720,8 +5721,12 @@ COPY_VALUE_CLASS:
X86EmitPopReg(kFactorReg);
X86EmitPopReg(kTotalReg);
+#ifndef UNIX_X86_ABI
// ret N
X86EmitReturn(pArrayOpScript->m_cbretpop);
+#else
+ X86EmitReturn(0);
+#endif
#endif // !_TARGET_AMD64_
// Exception points must clean up the stack for all those extra args.
@@ -6540,6 +6545,22 @@ TADDR FixupPrecode::GetMethodDesc()
}
#endif
+#ifdef FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
+PCODE FixupPrecode::GetDynamicMethodEntryJumpStub()
+{
+ _ASSERTE(((PTR_MethodDesc)GetMethodDesc())->IsLCGMethod());
+
+ // m_PrecodeChunkIndex has a value inverted to the order of precodes in memory (the precode at the lowest address has the
+ // highest index, and the precode at the highest address has the lowest index). To map a precode to its jump stub by memory
+ // order, invert the precode index to get the jump stub index.
+ UINT32 count = ((PTR_MethodDesc)GetMethodDesc())->GetMethodDescChunk()->GetCount();
+ _ASSERTE(m_PrecodeChunkIndex < count);
+ SIZE_T jumpStubIndex = count - 1 - m_PrecodeChunkIndex;
+
+ return GetBase() + sizeof(PTR_MethodDesc) + jumpStubIndex * BACK_TO_BACK_JUMP_ALLOCATE_SIZE;
+}
+#endif // FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
+
#ifdef DACCESS_COMPILE
void FixupPrecode::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
{
@@ -6659,10 +6680,17 @@ void FixupPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, int
_ASSERTE(GetMethodDesc() == (TADDR)pMD);
+ PCODE target = (PCODE)GetEEFuncEntryPoint(PrecodeFixupThunk);
+#ifdef FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
+ if (pMD->IsLCGMethod())
+ {
+ m_rel32 = rel32UsingPreallocatedJumpStub(&m_rel32, target, GetDynamicMethodEntryJumpStub());
+ return;
+ }
+#endif // FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
if (pLoaderAllocator != NULL)
{
- m_rel32 = rel32UsingJumpStub(&m_rel32,
- GetEEFuncEntryPoint(PrecodeFixupThunk), NULL /* pMD */, pLoaderAllocator);
+ m_rel32 = rel32UsingJumpStub(&m_rel32, target, NULL /* pMD */, pLoaderAllocator);
}
}
@@ -6678,21 +6706,40 @@ BOOL FixupPrecode::SetTargetInterlocked(TADDR target, TADDR expected)
INT64 oldValue = *(INT64*)this;
BYTE* pOldValue = (BYTE*)&oldValue;
- if (pOldValue[OFFSETOF_PRECODE_TYPE_CALL_OR_JMP] != FixupPrecode::TypePrestub)
- return FALSE;
-
MethodDesc * pMD = (MethodDesc*)GetMethodDesc();
g_IBCLogger.LogMethodPrecodeWriteAccess(pMD);
INT64 newValue = oldValue;
BYTE* pNewValue = (BYTE*)&newValue;
- pNewValue[OFFSETOF_PRECODE_TYPE_CALL_OR_JMP] = FixupPrecode::Type;
-
- pOldValue[offsetof(FixupPrecode,m_op)] = X86_INSTR_CALL_REL32;
- pNewValue[offsetof(FixupPrecode,m_op)] = X86_INSTR_JMP_REL32;
+ if (pOldValue[OFFSETOF_PRECODE_TYPE_CALL_OR_JMP] == FixupPrecode::TypePrestub)
+ {
+ pNewValue[OFFSETOF_PRECODE_TYPE_CALL_OR_JMP] = FixupPrecode::Type;
- *(INT32*)(&pNewValue[offsetof(FixupPrecode,m_rel32)]) = rel32UsingJumpStub(&m_rel32, target, pMD);
+ pOldValue[offsetof(FixupPrecode, m_op)] = X86_INSTR_CALL_REL32;
+ pNewValue[offsetof(FixupPrecode, m_op)] = X86_INSTR_JMP_REL32;
+ }
+ else if (pOldValue[OFFSETOF_PRECODE_TYPE_CALL_OR_JMP] == FixupPrecode::Type)
+ {
+#ifdef FEATURE_TIERED_COMPILATION
+ // No change needed, jmp is already in place
+#else
+ // Setting the target more than once is unexpected
+ return FALSE;
+#endif
+ }
+ else
+ {
+ // Pre-existing code doesn't conform to the expectations for a FixupPrecode
+ return FALSE;
+ }
+
+ *(INT32*)(&pNewValue[offsetof(FixupPrecode, m_rel32)]) =
+#ifdef FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
+ pMD->IsLCGMethod() ?
+ rel32UsingPreallocatedJumpStub(&m_rel32, target, GetDynamicMethodEntryJumpStub()) :
+#endif // FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
+ rel32UsingJumpStub(&m_rel32, target, pMD);
_ASSERTE(IS_ALIGNED(this, sizeof(INT64)));
EnsureWritableExecutablePages(this, sizeof(INT64));
diff --git a/src/vm/i386/stublinkerx86.h b/src/vm/i386/stublinkerx86.h
index e361833a1e..9fbc17d66c 100644
--- a/src/vm/i386/stublinkerx86.h
+++ b/src/vm/i386/stublinkerx86.h
@@ -703,6 +703,10 @@ struct FixupPrecode {
}
#endif // HAS_FIXUP_PRECODE_CHUNKS
+#ifdef FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
+ PCODE GetDynamicMethodEntryJumpStub();
+#endif // FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
+
PCODE GetTarget()
{
LIMITED_METHOD_DAC_CONTRACT;
diff --git a/src/vm/i386/umthunkstub.S b/src/vm/i386/umthunkstub.S
index 5a557d4b32..98f96ef6ec 100644
--- a/src/vm/i386/umthunkstub.S
+++ b/src/vm/i386/umthunkstub.S
@@ -10,12 +10,16 @@
// eax = UMEntryThunk*
//
NESTED_ENTRY TheUMEntryPrestub, _TEXT, UnhandledExceptionHandlerUnix
+#define STK_ALIGN_PADDING 8
+ sub esp, STK_ALIGN_PADDING
push eax // UMEntryThunk*
+ CHECK_STACK_ALIGNMENT
call C_FUNC(TheUMEntryPrestubWorker)
- add esp, 4
- // eax = PCODE
+ add esp, (4 + STK_ALIGN_PADDING)
+ // eax = PCODE
jmp eax // Tail Jmp
+#undef STK_ALIGN_PADDING
NESTED_END TheUMEntryPrestub, _TEXT
//
@@ -103,12 +107,20 @@ LOCAL_LABEL(PostCall):
mov dword ptr [ebx + Thread_m_fPreemptiveGCDisabled], 0
lea esp, [ebp - UMThunkStub_SAVEDREG] // deallocate arguments
+
+ mov ecx, dword ptr [ebp - UMThunkStub_UMENTRYTHUNK_OFFSET]
+ mov edx, dword ptr [ecx + UMEntryThunk__m_pUMThunkMarshInfo]
+ mov edx, dword ptr [edx + UMThunkMarshInfo__m_cbRetPop]
+
EPILOG_BEG
EPILOG_POP edi
EPILOG_POP esi
EPILOG_POP ebx
EPILOG_END
- ret
+
+ pop ecx // pop return address
+ add esp, edx // adjust ESP
+ jmp ecx // return to caller
LOCAL_LABEL(DoThreadSetup):
@@ -135,34 +147,35 @@ LOCAL_LABEL(DoTrapReturningThreadsTHROW):
LOCAL_LABEL(UMThunkStub_CopyStackArgs):
- // eax = m_cbActualArgSize, in bytes
- // esi = src
- // edi = dest
- // ebx = scratch
- lea esi, [ebp + 0x08]
-
- // first [esi] goes to ecx, in LTR
- add eax, -4
- mov ecx, dword ptr [esi]
- jz LOCAL_LABEL(UMThunkStub_ArgumentsSetup)
-
- // second [esi+04] goes to edx
- add eax, -4
- mov edx, dword ptr [esi + 0x04]
- jz LOCAL_LABEL(UMThunkStub_ArgumentsSetup)
+ // eax = m_cbActualArgSize (in bytes)
sub esp, eax
- and esp, -16 // align with 16 byte
- lea edi, [esp]
-
-LOCAL_LABEL(CopyLoop):
-
- // copy rest of the arguments to [esp+08+n], in RTL
- add eax, -4
- mov ebx, dword ptr [esi + 0x08 + eax]
- mov dword ptr [edi + eax], ebx
- jnz LOCAL_LABEL(CopyLoop)
-
+ and esp, -16 // align with 16 byte
+ lea edi, [esp] // edi = dest
+
+ lea esi, [ebp + 0x8] // esi = src
+
+ //
+ // EXTERN_C VOID STDCALL UMThunkStubSetupArgumentsWorker(UMThunkMarshInfo *pMarshInfo,
+ // char *pSrc,
+ // UMThunkMarshInfo::ArgumentRegisters *pArgRegs,
+ // char *pDst)
+ push edx
+ push ecx
+ lea ecx, [esp]
+
+ sub esp, 8 // Pad
+ push edi // pSrc
+ push ecx // pArgRegs
+ push esi // pSrc
+ mov ecx, dword ptr [ebp - UMThunkStub_UMENTRYTHUNK_OFFSET]
+ mov ecx, dword ptr [ecx + UMEntryThunk__m_pUMThunkMarshInfo]
+ push ecx // pMarshInfo
+ CHECK_STACK_ALIGNMENT
+ call C_FUNC(UMThunkStubSetupArgumentsWorker)
+ add esp, 8
+ pop ecx
+ pop edx
jmp LOCAL_LABEL(UMThunkStub_ArgumentsSetup)
#if _DEBUG
diff --git a/src/vm/i386/unixstubs.cpp b/src/vm/i386/unixstubs.cpp
index c0c0982e71..8441b0794e 100644
--- a/src/vm/i386/unixstubs.cpp
+++ b/src/vm/i386/unixstubs.cpp
@@ -11,21 +11,6 @@ extern "C"
PORTABILITY_ASSERT("Implement for PAL");
}
- void NakedThrowHelper()
- {
- PORTABILITY_ASSERT("Implement for PAL");
- }
-
- void PInvokeStubForHost()
- {
- PORTABILITY_ASSERT("Implement for PAL");
- }
-
- void PInvokeStubForHostInner(DWORD dwStackSize, LPVOID pStackFrame, LPVOID pTarget)
- {
- PORTABILITY_ASSERT("Implement for PAL");
- }
-
void ProfileEnterNaked(FunctionIDOrClientID functionIDOrClientID)
{
PORTABILITY_ASSERT("Implement for PAL");
@@ -44,24 +29,8 @@ extern "C"
void STDCALL JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle)
{
}
-
- BOOL CallRtlUnwind()
- {
- PORTABILITY_ASSERT("CallRtlUnwind");
- return FALSE;
- }
};
-VOID __cdecl PopSEHRecords(LPVOID pTargetSP)
-{
- PORTABILITY_ASSERT("Implement for PAL");
-}
-
-EXTERN_C VOID BackPatchWorkerAsmStub()
-{
- PORTABILITY_ASSERT("BackPatchWorkerAsmStub");
-}
-
EXTERN_C VOID JIT_TailCall()
{
PORTABILITY_ASSERT("JIT_TailCall");
diff --git a/src/vm/i386/virtualcallstubcpu.hpp b/src/vm/i386/virtualcallstubcpu.hpp
index 8c16854d22..67737a2d72 100644
--- a/src/vm/i386/virtualcallstubcpu.hpp
+++ b/src/vm/i386/virtualcallstubcpu.hpp
@@ -16,9 +16,6 @@
#ifdef DECLARE_DATA
#include "asmconstants.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#endif
#include <pshpack1.h> // Since we are placing code, we want byte packing of the structs
@@ -539,120 +536,6 @@ __declspec (naked) void ResolveWorkerAsmStub()
}
}
-#ifdef FEATURE_REMOTING
-/* For an in-context dispatch, we will find the target. This
- is the slow path, and erects a MachState structure for
- creating a HelperMethodFrame
-
- Entry stack:
- dispatch token
- return address of caller to stub
-
- Call stack:
- pointer to StubDispatchFrame
- call site
- dispatch token
- StubDispatchFrame
- GSCookie
- negspace
- vptr
- datum
- ArgumentRegisters (ecx, edx)
- CalleeSavedRegisters (ebp, ebx, esi, edi)
- return address of caller to stub
-*/
-__declspec (naked) void InContextTPDispatchAsmStub()
-{
- CANNOT_HAVE_CONTRACT;
-
- __asm {
- // Pop dispatch token
- pop eax
-
- // push ebp-frame
- push ebp
- mov ebp,esp
-
- // save CalleeSavedRegisters
- push ebx
- push esi
- push edi
-
- // push ArgumentRegisters
- push ecx
- push edx
-
- mov esi, esp
-
- push eax // token
- push esi // pTransitionContext
-
- // Make the call
- call VSD_GetTargetForTPWorker
-
- // From here on, mustn't trash eax
-
- // pop ArgumentRegisters
- pop edx
- pop ecx
-
- // pop CalleeSavedRegisters
- pop edi
- pop esi
- pop ebx
- pop ebp
-
- // Now jump to the target
- jmp eax // continue on into the method
- }
-}
-
-/* For an in-context dispatch, we will try to find the target in
- the resolve cache. If this fails, we will jump to the full
- version of InContextTPDispatchAsmStub
-
- Entry stack:
- dispatch slot number of interface MD
- caller return address
- ECX: this object
-*/
-__declspec (naked) void InContextTPQuickDispatchAsmStub()
-{
- CANNOT_HAVE_CONTRACT;
-
- __asm {
- // Spill registers
- push ecx
- push edx
-
- // Arg 2 - token
- mov eax, [esp + 8]
- push eax
-
- // Arg 1 - this
- push ecx
-
- // Make the call
- call VSD_GetTargetForTPWorkerQuick
-
- // Restore registers
- pop edx
- pop ecx
-
- // Test to see if we found a target
- test eax, eax
- jnz TargetFound
-
- // If no target, jump to the slow worker
- jmp InContextTPDispatchAsmStub
-
- TargetFound:
- // We got a target, so pop off the token and jump to it
- add esp,4
- jmp eax
- }
-}
-#endif // FEATURE_REMOTING
/* Call the callsite back patcher. The fail stub piece of the resolver is being
call too often, i.e. dispatch stubs are failing the expect MT test too often.
diff --git a/src/vm/ilmarshalers.cpp b/src/vm/ilmarshalers.cpp
index c44e561df3..a72276ef4a 100644
--- a/src/vm/ilmarshalers.cpp
+++ b/src/vm/ilmarshalers.cpp
@@ -3305,135 +3305,6 @@ ILCriticalHandleMarshaler::ReturnOverride(
return OVERRIDDEN;
} // ILCriticalHandleMarshaler::ReturnOverride
-#ifndef FEATURE_CORECLR
-//---------------------------------------------------------------------------------------
-//
-MarshalerOverrideStatus ILBlittableValueClassWithCopyCtorMarshaler::ArgumentOverride(NDirectStubLinker* psl,
- BOOL byref,
- BOOL fin,
- BOOL fout,
- BOOL fManagedToNative,
- OverrideProcArgs* pargs,
- UINT* pResID,
- UINT argidx,
- UINT nativeStackOffset)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- ILCodeStream* pslIL = psl->GetMarshalCodeStream();
- ILCodeStream* pslILDispatch = psl->GetDispatchCodeStream();
-
- if (byref)
- {
- *pResID = IDS_EE_BADMARSHAL_COPYCTORRESTRICTION;
- return DISALLOWED;
- }
-
- if (fManagedToNative)
- {
-#ifdef _TARGET_X86_
- _ASSERTE(nativeStackOffset != (UINT)-1);
-
- // get a new copy ctor cookie
- DWORD dwCookieLocalNum = psl->CreateCopyCtorCookie(pslIL);
-
- // and initialize it with our values
- pslIL->EmitLDLOCA(dwCookieLocalNum);
- pslIL->EmitLDARG(argidx);
- pslIL->EmitLDC(nativeStackOffset);
-
- // SetData takes pointers to managed methods although code:CopyCtorCallStubWorker
- // currently calls them via reverse P/Invokes
- if (pargs->mm.m_pCopyCtor)
- {
- pslIL->EmitLDFTN(pslIL->GetToken(pargs->mm.m_pCopyCtor));
- }
- else
- {
- pslIL->EmitLoadNullPtr();
- }
-
- if (pargs->mm.m_pDtor)
- {
- pslIL->EmitLDFTN(pslIL->GetToken(pargs->mm.m_pDtor));
- }
- else
- {
- pslIL->EmitLoadNullPtr();
- }
-
- // <dwCookieLocalNum>.SetData(<argidx>, <nativeStackOffset>, ctorPtr, dtorPtr)
- pslIL->EmitCALL(METHOD__COPYCTORSTUBCOOKIE__SET_DATA, 5, 0);
-
- LocalDesc locDesc(pargs->mm.m_pMT);
- pslIL->SetStubTargetArgType(&locDesc); // native type is the value type
-
- pslILDispatch->EmitLDARG(argidx); // we load the argument directly
- pslILDispatch->EmitLDOBJ(pslILDispatch->GetToken(pargs->mm.m_pMT));
-#else // _TARGET_X86_
- // On WIN64 platforms, copy-constructed arguments are actually passed by reference.
- // This is the same calling convention as used by managed code, but to maintain parity,
- // we mimic the x86 behaviour:
- //
- // 1) create new native value type local
- // 2) run new->CopyCtor(old)
- // 3) run old->Dtor()
-
- LocalDesc locDesc(pargs->mm.m_pMT);
-
- DWORD dwNewValueTypeLocal;
-
- // Step 1
- dwNewValueTypeLocal = pslIL->NewLocal(locDesc);
-
- // Step 2
- if (pargs->mm.m_pCopyCtor)
- {
- pslIL->EmitLDLOCA(dwNewValueTypeLocal);
- pslIL->EmitLDARG(argidx);
- pslIL->EmitCALL(pslIL->GetToken(pargs->mm.m_pCopyCtor), 2, 0);
- }
- else
- {
- pslIL->EmitLDARG(argidx);
- pslIL->EmitLDOBJ(pslIL->GetToken(pargs->mm.m_pMT));
- pslIL->EmitSTLOC(dwNewValueTypeLocal);
- }
-
- // Step 3
- if (pargs->mm.m_pDtor)
- {
- pslIL->EmitLDARG(argidx);
- pslIL->EmitCALL(pslIL->GetToken(pargs->mm.m_pDtor), 1, 0);
- }
-
- pslIL->SetStubTargetArgType(ELEMENT_TYPE_I); // native type is a pointer
- pslILDispatch->EmitLDLOCA(dwNewValueTypeLocal);
-#endif // _TARGET_X86_
-
- return OVERRIDDEN;
- }
- else
- {
- // nothing to do but pass the value along
- // note that on x86 the argument comes by-value but is converted to pointer by the UM thunk
- // so that we don't make copies that would not be accounted for by copy ctors
- LocalDesc locDesc(pargs->mm.m_pMT);
- locDesc.MakeCopyConstructedPointer();
-
- pslIL->SetStubTargetArgType(&locDesc); // native type is a pointer
- pslILDispatch->EmitLDARG(argidx);
-
- return OVERRIDDEN;
- }
-}
-#endif // FEATURE_CORECLR
LocalDesc ILArgIteratorMarshaler::GetNativeType()
{
diff --git a/src/vm/ilmarshalers.h b/src/vm/ilmarshalers.h
index 5337b081c6..5ac5e41242 100644
--- a/src/vm/ilmarshalers.h
+++ b/src/vm/ilmarshalers.h
@@ -600,19 +600,22 @@ public:
nativeSize = wNativeSize;
}
-#if defined(_TARGET_X86_) || (defined(_TARGET_AMD64_) && defined(_WIN64) && !defined(FEATURE_CORECLR))
+#if defined(_TARGET_X86_)
// JIT32 and JIT64 (which is only used on the Windows Desktop CLR) has a problem generating
// code for the pinvoke ILStubs which do a return using a struct type. Therefore, we
// change the signature of calli to return void and make the return buffer as first argument.
// for X86 and AMD64-Windows we bash the return type from struct to U1, U2, U4 or U8
// and use byrefNativeReturn for all other structs.
+ // for UNIX_X86_ABI, we always need a return buffer argument for any size of structs.
switch (nativeSize)
{
+#ifndef UNIX_X86_ABI
case 1: typ = ELEMENT_TYPE_U1; break;
case 2: typ = ELEMENT_TYPE_U2; break;
case 4: typ = ELEMENT_TYPE_U4; break;
case 8: typ = ELEMENT_TYPE_U8; break;
+#endif
default: byrefNativeReturn = true; break;
}
#endif
@@ -2716,42 +2719,6 @@ protected:
};
-#ifndef FEATURE_CORECLR
-class ILBlittableValueClassWithCopyCtorMarshaler : public ILMarshaler
-{
-public:
- enum
- {
- c_fInOnly = TRUE,
- c_nativeSize = VARIABLESIZE,
- c_CLRSize = sizeof(OBJECTREF),
- };
-
- LocalDesc GetManagedType()
- {
- LIMITED_METHOD_CONTRACT;
- return LocalDesc();
- }
-
- LocalDesc GetNativeType()
- {
- LIMITED_METHOD_CONTRACT;
- return LocalDesc();
- }
-
- static MarshalerOverrideStatus ArgumentOverride(NDirectStubLinker* psl,
- BOOL byref,
- BOOL fin,
- BOOL fout,
- BOOL fManagedToNative,
- OverrideProcArgs* pargs,
- UINT* pResID,
- UINT argidx,
- UINT nativeStackOffset);
-
-
-};
-#endif // !FEATURE_CORECLR
class ILArgIteratorMarshaler : public ILMarshaler
diff --git a/src/vm/ilstubcache.cpp b/src/vm/ilstubcache.cpp
index 9cd904aec7..ff6bdc0335 100644
--- a/src/vm/ilstubcache.cpp
+++ b/src/vm/ilstubcache.cpp
@@ -531,47 +531,6 @@ MethodDesc* ILStubCache::GetStubMethodDesc(
}
}
-#ifndef FEATURE_CORECLR
- //
- // Publish ETW events for IL stubs
- //
- if (bFireETWCacheHitEvent)
- {
- if (ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, ILStubCacheHit))
- {
-
- SString strNamespaceOrClassName, strMethodName, strMethodSignature;
- UINT64 uModuleId = 0;
-
- if (pTargetMD)
- {
- pTargetMD->GetMethodInfoWithNewSig(strNamespaceOrClassName, strMethodName, strMethodSignature);
- uModuleId = (UINT64)pTargetMD->GetModule()->GetAddrModuleID();
- }
-
- DWORD dwToken = 0;
- if (pTargetMD)
- dwToken = pTargetMD->GetMemberDef();
-
- //
- // Truncate string fields. Make sure the whole event is less than 64KB
- //
- TruncateUnicodeString(strNamespaceOrClassName, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
- TruncateUnicodeString(strMethodName, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
- TruncateUnicodeString(strMethodSignature, ETW_IL_STUB_EVENT_STRING_FIELD_MAXSIZE);
-
- FireEtwILStubCacheHit(
- GetClrInstanceId(), // ClrInstanceId
- uModuleId, // ModuleIdentifier
- (UINT64)pMD, // StubMethodIdentifier
- dwToken, // ManagedInteropMethodToken
- strNamespaceOrClassName.GetUnicode(), // ManagedInteropMethodNamespace
- strMethodName.GetUnicode(), // ManagedInteropMethodName
- strMethodSignature.GetUnicode() // ManagedInteropMethodSignature
- );
- }
- }
-#endif // !FEATURE_CORECLR
if (!pMD)
{
diff --git a/src/vm/inlinetracking.cpp b/src/vm/inlinetracking.cpp
index 02e2a7cea6..c4bfe0734c 100644
--- a/src/vm/inlinetracking.cpp
+++ b/src/vm/inlinetracking.cpp
@@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// =============================================================================================
-// Code for tracking method inlinings in NGen images.
+// Code for tracking method inlinings in NGen and R2R images.
// The only information stored is "who" got inlined "where", no offsets or inlining depth tracking.
// (No good for debugger yet.)
// This information is later exposed to profilers and can be useful for ReJIT.
@@ -12,6 +12,8 @@
#include "inlinetracking.h"
#include "ceeload.h"
+#ifndef DACCESS_COMPILE
+
bool MethodInModule::operator <(const MethodInModule& other) const
{
STANDARD_VM_CONTRACT;
@@ -123,9 +125,86 @@ InlineTrackingEntry & InlineTrackingEntry::operator = (const InlineTrackingEntry
return *this;
}
+void InlineTrackingEntry::Add(PTR_MethodDesc inliner)
+{
+ STANDARD_VM_CONTRACT;
-#ifndef DACCESS_COMPILE
-COUNT_T PersistentInlineTrackingMap::GetInliners(PTR_Module inlineeOwnerMod, mdMethodDef inlineeTkn, COUNT_T inlinersSize, MethodInModule inliners[], BOOL *incompleteData)
+ MethodInModule method(inliner->GetModule(), inliner->GetMemberDef());
+
+ // Going through last 10 inliners to check if a given inliner has recently been registered.
+ // It allows to filter out most duplicates without having to scan through hundreds of inliners
+ // for methods like Object.ctor or Monitor.Enter.
+ // We are OK to keep occasional duplicates in m_inliners, we'll get rid of them
+ // in SortAndDeduplicate() anyway.
+ int count = static_cast<int>(m_inliners.GetCount());
+ int start = max(0, count - 10);
+ for (int i = count - 1; i >= start; i--)
+ {
+ if (m_inliners[i] == method)
+ return;
+ }
+
+ //look like we see this inliner for the first time, add it to the collection
+ m_inliners.Append(method);
+}
+
+InlineTrackingMap::InlineTrackingMap()
+ : m_mapCrst(CrstInlineTrackingMap)
+{
+ STANDARD_VM_CONTRACT;
+}
+
+void InlineTrackingMap::AddInlining(MethodDesc *inliner, MethodDesc *inlinee)
+{
+ STANDARD_VM_CONTRACT;
+ _ASSERTE(inliner != NULL);
+ _ASSERTE(inlinee != NULL);
+
+ MethodInModule inlineeMnM(inlinee->GetModule(), inlinee->GetMemberDef());
+
+ if (RidFromToken(inlineeMnM.m_methodDef) == 0 || RidFromToken(inliner->GetMemberDef()) == 0)
+ {
+ // Sometimes we do see methods that don't have valid tokens (stubs etc)
+ // we just ignore them.
+ return;
+ }
+
+ CrstHolder lock(&m_mapCrst);
+ InlineTrackingEntry *existingEntry = const_cast<InlineTrackingEntry *>(LookupPtr(inlineeMnM));
+ if (existingEntry)
+ {
+ // We saw this inlinee before, just add one more inliner
+ existingEntry->Add(inliner);
+ }
+ else
+ {
+ // We haven't seen this inlinee before, create a new record in the hashtable
+ // and add a first inliner to it.
+ InlineTrackingEntry newEntry;
+ newEntry.m_inlinee = inlineeMnM;
+ newEntry.Add(inliner);
+ Add(newEntry);
+ }
+}
+
+#endif //!DACCESS_COMPILE
+
+void ZapInlineeRecord::InitForNGen(RID rid, LPCUTF8 simpleName)
+{
+ LIMITED_METHOD_CONTRACT;
+ //XOR of up to first 24 bytes in module name
+ DWORD hash = 0;
+ for (int i = 0; simpleName[i] && i < 24; i++)
+ hash ^= (BYTE)simpleName[i];
+
+ // This key contains 24 bits of RID and 8 bits from module name.
+ // Since RID can't be longer than 24 bits, we can't have method RID collistions,
+ // that's why PersistentInlineTrackingMap::GetInliners only deals with module collisions.
+ m_key = (hash << 24) | rid;
+}
+
+
+COUNT_T PersistentInlineTrackingMapNGen::GetInliners(PTR_Module inlineeOwnerMod, mdMethodDef inlineeTkn, COUNT_T inlinersSize, MethodInModule inliners[], BOOL *incompleteData)
{
CONTRACTL
{
@@ -149,10 +228,11 @@ COUNT_T PersistentInlineTrackingMap::GetInliners(PTR_Module inlineeOwnerMod, mdM
}
// Binary search to find all records matching (inlineeTkn/inlineeOwnerMod)
- InlineeRecord probeRecord(RidFromToken(inlineeTkn), inlineeOwnerMod->GetSimpleName());
- InlineeRecord *begin = m_inlineeIndex;
- InlineeRecord *end = m_inlineeIndex + m_inlineeIndexSize;
- InlineeRecord *foundRecord = util::lower_bound(begin, end, probeRecord);
+ ZapInlineeRecord probeRecord;
+ probeRecord.InitForNGen(RidFromToken(inlineeTkn), inlineeOwnerMod->GetSimpleName());
+ ZapInlineeRecord *begin = m_inlineeIndex;
+ ZapInlineeRecord *end = m_inlineeIndex + m_inlineeIndexSize;
+ ZapInlineeRecord *foundRecord = util::lower_bound(begin, end, probeRecord);
DWORD result = 0;
DWORD outputIndex = 0;
@@ -204,7 +284,9 @@ COUNT_T PersistentInlineTrackingMap::GetInliners(PTR_Module inlineeOwnerMod, mdM
return result;
}
-Module *PersistentInlineTrackingMap::GetModuleByIndex(DWORD index)
+
+
+Module *PersistentInlineTrackingMapNGen::GetModuleByIndex(DWORD index)
{
CONTRACTL
{
@@ -222,106 +304,42 @@ Module *PersistentInlineTrackingMap::GetModuleByIndex(DWORD index)
return m_module->GetModuleFromIndexIfLoaded(index);
}
-PersistentInlineTrackingMap::InlineeRecord::InlineeRecord(RID rid, LPCUTF8 simpleName)
-{
- LIMITED_METHOD_CONTRACT;
- //XOR of up to first 24 bytes in module name
- DWORD hash = 0;
- for (int i = 0; simpleName[i] && i < 24; i++)
- hash ^= (BYTE)simpleName[i];
-
- // This key contains 24 bits of RID and 8 bits from module name.
- // Since RID can't be longer than 24 bits, we can't have method RID collistions,
- // that's why PersistentInlineTrackingMap::GetInliners only deals with module collisions.
- m_key = (hash << 24) | rid;
-}
-InlineTrackingMap::InlineTrackingMap()
- : m_mapCrst(CrstInlineTrackingMap)
-{
- STANDARD_VM_CONTRACT;
-}
-
-void InlineTrackingMap::AddInlining(MethodDesc *inliner, MethodDesc *inlinee)
-{
- STANDARD_VM_CONTRACT;
- _ASSERTE(inliner != NULL);
- _ASSERTE(inlinee != NULL);
-
- MethodInModule inlineeMnM(inlinee->GetModule(), inlinee->GetMemberDef());
-
- if (RidFromToken(inlineeMnM.m_methodDef) == 0 || RidFromToken(inliner->GetMemberDef()) == 0)
- {
- // Sometimes we do see methods that don't have valid tokens (stubs etc)
- // we just ignore them.
- return;
- }
-
- CrstHolder lock(&m_mapCrst);
- InlineTrackingEntry *existingEntry = const_cast<InlineTrackingEntry *>(LookupPtr(inlineeMnM));
- if (existingEntry)
- {
- // We saw this inlinee before, just add one more inliner
- existingEntry->Add(inliner);
- }
- else
- {
- // We haven't seen this inlinee before, create a new record in the hashtable
- // and add a first inliner to it.
- InlineTrackingEntry newEntry;
- newEntry.m_inlinee = inlineeMnM;
- newEntry.Add(inliner);
- Add(newEntry);
- }
-}
-
-void InlineTrackingEntry::Add(PTR_MethodDesc inliner)
-{
- STANDARD_VM_CONTRACT;
-
- MethodInModule method(inliner->GetModule(), inliner->GetMemberDef());
-
- // Going through last 10 inliners to check if a given inliner has recently been registered.
- // It allows to filter out most duplicates without having to scan through hundreds of inliners
- // for methods like Object.ctor or Monitor.Enter.
- // We are OK to keep occasional duplicates in m_inliners, we'll get rid of them
- // in SortAndDeduplicate() anyway.
- int count = static_cast<int>(m_inliners.GetCount());
- int start = max(0, count - 10);
- for (int i = count - 1; i >= start; i--)
- {
- if (m_inliners[i] == method)
- return;
- }
-
- //look like we see this inliner for the first time, add it to the collection
- m_inliners.Append(method);
-}
+#ifndef DACCESS_COMPILE
#ifdef FEATURE_NATIVE_IMAGE_GENERATION
-void PersistentInlineTrackingMap::ProcessInlineTrackingEntry(DataImage *image, SBuffer *inlinersBuffer, SArray<InlineeRecord> *inlineeIndex, InlineTrackingEntry *entry)
+// This is a shared serialization routine used for both NGEN and R2R formats. If image != NULL the NGEN format is generated, otherwise the R2R format
+void SerializeInlineTrackingEntry(DataImage* image, SBuffer *inlinersBuffer, SArray<ZapInlineeRecord> *inlineeIndex, InlineTrackingEntry *entry)
{
STANDARD_VM_CONTRACT;
// This call removes duplicates from inliners and makes sure they are sorted by module
entry->SortAndDeduplicate();
MethodInModule inlinee = entry->m_inlinee;
- DWORD inlineeModuleZapIndex = image->GetModuleImportIndex(inlinee.m_module);
+ DWORD inlineeModuleZapIndex = 0;
+ if (image != NULL)
+ {
+ inlineeModuleZapIndex = image->GetModuleImportIndex(inlinee.m_module);
+ }
InlineSArray<MethodInModule, 3> &inliners = entry->m_inliners;
- COUNT_T tatalInlinersCount = inliners.GetCount();
- _ASSERTE(tatalInlinersCount > 0);
+ COUNT_T totalInlinersCount = inliners.GetCount();
+ _ASSERTE(totalInlinersCount > 0);
COUNT_T sameModuleCount;
// Going through all inliners and grouping them by their module, for each module we'll create
- // InlineeRecord and encode inliners as bytes in inlinersBuffer.
- for (COUNT_T thisModuleBegin = 0; thisModuleBegin < tatalInlinersCount; thisModuleBegin += sameModuleCount)
+ // an ZapInlineeRecord and encode inliners as bytes in inlinersBuffer.
+ for (COUNT_T thisModuleBegin = 0; thisModuleBegin < totalInlinersCount; thisModuleBegin += sameModuleCount)
{
Module *lastInlinerModule = inliners[thisModuleBegin].m_module;
- DWORD lastInlinerModuleZapIndex = image->GetModuleImportIndex(lastInlinerModule);
-
+ DWORD lastInlinerModuleZapIndex = 0;
+ if (image != NULL)
+ {
+ lastInlinerModuleZapIndex = image->GetModuleImportIndex(lastInlinerModule);
+ }
+
// Counting how many inliners belong to this module
sameModuleCount = 1;
- while (thisModuleBegin + sameModuleCount < tatalInlinersCount &&
+ while (thisModuleBegin + sameModuleCount < totalInlinersCount &&
inliners[thisModuleBegin + sameModuleCount].m_module == lastInlinerModule)
{
sameModuleCount++;
@@ -329,8 +347,11 @@ void PersistentInlineTrackingMap::ProcessInlineTrackingEntry(DataImage *image, S
// Saving module indexes and number of inliners
NibbleWriter inlinersStream;
- inlinersStream.WriteEncodedU32(inlineeModuleZapIndex);
- inlinersStream.WriteEncodedU32(lastInlinerModuleZapIndex);
+ if (image != NULL)
+ {
+ inlinersStream.WriteEncodedU32(inlineeModuleZapIndex);
+ inlinersStream.WriteEncodedU32(lastInlinerModuleZapIndex);
+ }
inlinersStream.WriteEncodedU32(sameModuleCount);
// Saving inliners RIDs, each new RID is represented as an adjustment (diff) to the previous one
@@ -343,15 +364,22 @@ void PersistentInlineTrackingMap::ProcessInlineTrackingEntry(DataImage *image, S
prevMethodRid = methodRid;
}
inlinersStream.Flush();
-
+
// Copy output of NibbleWriter into a big buffer (inlinersBuffer) for inliners from the same module
// and create an InlineeRecord with correct offset
- InlineeRecord record(RidFromToken(inlinee.m_methodDef), inlinee.m_module->GetSimpleName());
DWORD inlinersStreamSize;
const BYTE *inlinersStreamPtr = (const BYTE *)inlinersStream.GetBlob(&inlinersStreamSize);
+ ZapInlineeRecord record;
+ if (image != NULL)
+ {
+ record.InitForNGen(RidFromToken(inlinee.m_methodDef), inlinee.m_module->GetSimpleName());
+ }
+ else
+ {
+ record.InitForR2R(RidFromToken(inlinee.m_methodDef));
+ }
record.m_offset = inlinersBuffer->GetSize();
inlinersBuffer->Insert(inlinersBuffer->End(), SBuffer(SBuffer::Immutable, inlinersStreamPtr, inlinersStreamSize));
-
inlineeIndex->Append(record);
}
}
@@ -361,20 +389,16 @@ bool compare_entry(const InlineTrackingEntry* first, const InlineTrackingEntry*
return first->m_inlinee < second->m_inlinee;
}
-void PersistentInlineTrackingMap::Save(DataImage *image, InlineTrackingMap* runtimeMap)
+// This is a shared serialization routine used for both NGEN and R2R formats. If image != NULL the NGEN format is generated, otherwise the R2R format
+void SerializeTrackingMapBuffers(ZapHeap* heap, DataImage *image, SBuffer *inlinersBuffer, SArray<ZapInlineeRecord> *inlineeIndex, InlineTrackingMap* runtimeMap)
{
STANDARD_VM_CONTRACT;
- _ASSERTE(image != NULL);
_ASSERTE(runtimeMap != NULL);
- SArray<InlineeRecord> inlineeIndex;
- SBuffer inlinersBuffer;
-
// Sort records from runtimeMap, because we need to make sure
// we save everything in deterministic order. Hashtable iteration is not deterministic.
COUNT_T runtimeMapCount = runtimeMap->GetCount();
- InlineTrackingEntry **inlinees = new InlineTrackingEntry *[runtimeMapCount];
- NewArrayHolder<InlineTrackingEntry *>inlineesHolder(inlinees);
+ InlineTrackingEntry **inlinees = new (heap) InlineTrackingEntry *[runtimeMapCount];
int index = 0;
for (auto iter = runtimeMap->Begin(), end = runtimeMap->End(); iter != end; ++iter)
{
@@ -387,8 +411,22 @@ void PersistentInlineTrackingMap::Save(DataImage *image, InlineTrackingMap* runt
// and write corresponding records into inlineeIndex and inlinersBuffer
for (COUNT_T i = 0; i < runtimeMapCount; i++)
{
- ProcessInlineTrackingEntry(image, &inlinersBuffer, &inlineeIndex, inlinees[i]);
+ SerializeInlineTrackingEntry(image, inlinersBuffer, inlineeIndex, inlinees[i]);
}
+}
+
+
+
+void PersistentInlineTrackingMapNGen::Save(DataImage *image, InlineTrackingMap* runtimeMap)
+{
+ STANDARD_VM_CONTRACT;
+ _ASSERTE(image != NULL);
+ _ASSERTE(runtimeMap != NULL);
+
+ SArray<ZapInlineeRecord> inlineeIndex;
+ SBuffer inlinersBuffer;
+
+ SerializeTrackingMapBuffers(image->GetHeap(), image, &inlinersBuffer, &inlineeIndex, runtimeMap);
m_inlineeIndexSize = inlineeIndex.GetCount();
m_inlinersBufferSize = inlinersBuffer.GetSize();
@@ -398,7 +436,7 @@ void PersistentInlineTrackingMap::Save(DataImage *image, InlineTrackingMap* runt
{
// Copy everything to the class fields, we didn't use the class fields for addition
// because we want to make sure we don't waste memory for buffer's amortized growth
- m_inlineeIndex = new (image->GetHeap()) InlineeRecord[m_inlineeIndexSize];
+ m_inlineeIndex = new (image->GetHeap()) ZapInlineeRecord[m_inlineeIndexSize];
inlineeIndex.Copy(m_inlineeIndex, inlineeIndex.Begin(), m_inlineeIndexSize);
m_inlinersBuffer = new (image->GetHeap()) BYTE[m_inlinersBufferSize];
@@ -418,12 +456,146 @@ void PersistentInlineTrackingMap::Save(DataImage *image, InlineTrackingMap* runt
m_inlineeIndexSize * sizeof(m_inlineeIndex[0]), m_inlinersBufferSize));
}
-void PersistentInlineTrackingMap::Fixup(DataImage *image)
+void PersistentInlineTrackingMapNGen::Fixup(DataImage *image)
+{
+ STANDARD_VM_CONTRACT;
+ image->FixupPointerField(this, offsetof(PersistentInlineTrackingMapNGen, m_module));
+ image->FixupPointerField(this, offsetof(PersistentInlineTrackingMapNGen, m_inlineeIndex));
+ image->FixupPointerField(this, offsetof(PersistentInlineTrackingMapNGen, m_inlinersBuffer));
+}
+
+#endif //FEATURE_NATIVE_IMAGE_GENERATION
+#endif //!DACCESS_COMPILE
+
+#ifdef FEATURE_READYTORUN
+
+struct InliningHeader
+{
+ int SizeOfInlineeIndex;
+};
+
+#ifndef DACCESS_COMPILE
+#ifdef FEATURE_NATIVE_IMAGE_GENERATION
+
+
+
+void PersistentInlineTrackingMapR2R::Save(ZapHeap* pHeap, SBuffer* pSaveTarget, InlineTrackingMap* runtimeMap)
{
STANDARD_VM_CONTRACT;
- image->FixupPointerField(this, offsetof(PersistentInlineTrackingMap, m_module));
- image->FixupPointerField(this, offsetof(PersistentInlineTrackingMap, m_inlineeIndex));
- image->FixupPointerField(this, offsetof(PersistentInlineTrackingMap, m_inlinersBuffer));
+ _ASSERTE(pSaveTarget != NULL);
+ _ASSERTE(runtimeMap != NULL);
+
+ SArray<ZapInlineeRecord> inlineeIndex;
+ SBuffer inlinersBuffer;
+
+ SerializeTrackingMapBuffers(pHeap, NULL, &inlinersBuffer, &inlineeIndex, runtimeMap);
+
+ InliningHeader header;
+ header.SizeOfInlineeIndex = inlineeIndex.GetCount() * sizeof(ZapInlineeRecord);
+
+ pSaveTarget->Insert(pSaveTarget->End(), SBuffer(SBuffer::Immutable, (const BYTE*) &header, sizeof(header)));
+ DWORD unused = 0;
+ pSaveTarget->Insert(pSaveTarget->End(), SBuffer(SBuffer::Immutable, (const BYTE*) inlineeIndex.GetElements(), header.SizeOfInlineeIndex));
+ pSaveTarget->Insert(pSaveTarget->End(), SBuffer(SBuffer::Immutable, (const BYTE*) inlinersBuffer, inlinersBuffer.GetSize()));
+
+ LOG((LF_ZAP, LL_INFO100000,
+ "PersistentInlineTrackingMap saved. InlineeIndexSize: %d bytes, InlinersBufferSize: %d bytes\n",
+ header.SizeOfInlineeIndex, inlinersBuffer.GetSize()));
}
+
#endif //FEATURE_NATIVE_IMAGE_GENERATION
+
+BOOL PersistentInlineTrackingMapR2R::TryLoad(Module* pModule, const BYTE* pBuffer, DWORD cbBuffer,
+ AllocMemTracker *pamTracker, PersistentInlineTrackingMapR2R** ppLoadedMap)
+{
+ InliningHeader* pHeader = (InliningHeader*)pBuffer;
+ if (pHeader->SizeOfInlineeIndex > (int)(cbBuffer - sizeof(InliningHeader)))
+ {
+ //invalid serialized data, the index can't be larger the entire block
+ _ASSERTE(!"R2R image is invalid or there is a bug in the R2R parser");
+ return FALSE;
+ }
+
+ //NOTE: Error checking on the format is very limited at this point.
+ //We trust the image format is valid and this initial check is a cheap
+ //verification that may help catch simple bugs. It does not secure against
+ //a deliberately maliciously formed binary.
+
+ LoaderHeap *pHeap = pModule->GetLoaderAllocator()->GetHighFrequencyHeap();
+ void * pMemory = pamTracker->Track(pHeap->AllocMem((S_SIZE_T)sizeof(PersistentInlineTrackingMapR2R)));
+ PersistentInlineTrackingMapR2R* pMap = new (pMemory) PersistentInlineTrackingMapR2R();
+
+ pMap->m_module = pModule;
+ pMap->m_inlineeIndex = (PTR_ZapInlineeRecord)(pHeader + 1);
+ pMap->m_inlineeIndexSize = pHeader->SizeOfInlineeIndex / sizeof(ZapInlineeRecord);
+ pMap->m_inlinersBuffer = ((PTR_BYTE)(pHeader+1)) + pHeader->SizeOfInlineeIndex;
+ pMap->m_inlinersBufferSize = cbBuffer - sizeof(InliningHeader) - pMap->m_inlineeIndexSize;
+ *ppLoadedMap = pMap;
+ return TRUE;
+}
+
#endif //!DACCESS_COMPILE
+
+COUNT_T PersistentInlineTrackingMapR2R::GetInliners(PTR_Module inlineeOwnerMod, mdMethodDef inlineeTkn, COUNT_T inlinersSize, MethodInModule inliners[], BOOL *incompleteData)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ _ASSERTE(inlineeOwnerMod);
+ _ASSERTE(inliners);
+
+ if (incompleteData)
+ {
+ *incompleteData = FALSE;
+ }
+ if (m_inlineeIndex == NULL || m_inlinersBuffer == NULL)
+ {
+ //No inlines saved in this image.
+ return 0;
+ }
+ if(inlineeOwnerMod != m_module)
+ {
+ // no cross module inlining (yet?)
+ return 0;
+ }
+
+ // Binary search to find all records matching (inlineeTkn)
+ ZapInlineeRecord probeRecord;
+ probeRecord.InitForR2R(RidFromToken(inlineeTkn));
+ ZapInlineeRecord *begin = m_inlineeIndex;
+ ZapInlineeRecord *end = m_inlineeIndex + m_inlineeIndexSize;
+ ZapInlineeRecord *foundRecord = util::lower_bound(begin, end, probeRecord);
+ DWORD result = 0;
+ DWORD outputIndex = 0;
+
+ // Go through all matching records
+ for (; foundRecord < end && *foundRecord == probeRecord; foundRecord++)
+ {
+ DWORD offset = foundRecord->m_offset;
+ NibbleReader stream(m_inlinersBuffer + offset, m_inlinersBufferSize - offset);
+ Module *inlinerModule = m_module;
+
+ DWORD inlinersCount = stream.ReadEncodedU32();
+ _ASSERTE(inlinersCount > 0);
+
+ RID inlinerRid = 0;
+ // Reading inliner RIDs one by one, each RID is represented as an adjustment (diff) to the previous one.
+ // Adding inliners module and coping to the output buffer
+ for (DWORD i = 0; i < inlinersCount && outputIndex < inlinersSize; i++)
+ {
+ inlinerRid += stream.ReadEncodedU32();
+ mdMethodDef inlinerTkn = TokenFromRid(inlinerRid, mdtMethodDef);
+ inliners[outputIndex++] = MethodInModule(inlinerModule, inlinerTkn);
+ }
+ result += inlinersCount;
+ }
+
+ return result;
+}
+
+#endif //FEATURE_READYTORUN \ No newline at end of file
diff --git a/src/vm/inlinetracking.h b/src/vm/inlinetracking.h
index cf05027785..2cfb35bd50 100644
--- a/src/vm/inlinetracking.h
+++ b/src/vm/inlinetracking.h
@@ -2,12 +2,26 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// =============================================================================================
-// Definitions for tracking method inlinings in NGen images.
+// Definitions for tracking method inlinings in NGen and R2R images.
// The only information stored is "who" got inlined "where", no offsets or inlining depth tracking.
// (No good for debugger yet.)
// This information is later exposed to profilers and can be useful for ReJIT.
// Runtime inlining is not being tracked because profilers can deduce it via callbacks anyway.
+//
+// This file is made of two major component groups:
+// a) InlineTrackingMap - This is a compilation time datastructure that holds an uncompressed
+// version of the inline tracking information. It is appended to as methods are compiled.
+// MethodInModule, InlineTrackingEntry, InlineTrackingMapTraits are all support infratsructure
+// in this group.
+//
+// b) PersistentInlineTrackingMap[R2R/NGen] - These are the types that understand the image persistence
+// formats. At the end of image compilation one of them consumes all the data from an
+// InlineTrackingMap to encode it. At runtime an instance will be constructed to read back
+// the encoded data on demand. PersistantInlineTrackingMapR2R and PersistantInlineTrackingMapNGen
+// would nominally use a common base type or interface, but due to ngen binary serialization vtables
+// were avoided. See farther below for the different format descriptions.
// =============================================================================================
+
#ifndef INLINETRACKING_H_
#define INLINETRACKING_H_
#include "corhdr.h"
@@ -16,6 +30,10 @@
#include "crsttypes.h"
#include "daccess.h"
+
+
+// ---------------------------------- Compile time support ----------------------------------------------
+
class MethodDesc;
typedef DPTR(class MethodDesc) PTR_MethodDesc;
@@ -128,6 +146,17 @@ public:
typedef DPTR(InlineTrackingMap) PTR_InlineTrackingMap;
+
+
+
+// ------------------------------------ Persistance support ----------------------------------------------------------
+
+
+
+
+
+// NGEN format
+//
// This is a persistent map that is stored inside each NGen-ed module image and is used to track
// inlines in the NGEN-ed code inside this module.
// At runtime this map is used by profiler to track methods that inline a given method,
@@ -135,25 +164,25 @@ typedef DPTR(InlineTrackingMap) PTR_InlineTrackingMap;
// It doesn't require any load time unpacking and serves requests directly from NGEN image.
//
// It is composed of two arrays:
-// m_inlineeIndex - sorted (by InlineeRecord.key i.e. by module then token) array of InlineeRecords, given an inlinee module name hash (8 bits)
+// m_inlineeIndex - sorted (by ZapInlineeRecord.key i.e. by module then token) array of ZapInlineeRecords, given an inlinee module name hash (8 bits)
// and a method token (24 bits) we use binary search to find if this method has ever been inlined in NGen-ed code of this image.
// Each record has m_offset, which is an offset inside m_inlinersBuffer, it has more data on where the method got inlined.
//
-// It is totally possible to have more than one InlineeRecords with the same key, not only due hash collision, but also due to
+// It is totally possible to have more than one ZapInlineeRecords with the same key, not only due hash collision, but also due to
// the fact that we create one record for each (inlinee module / inliner module) pair.
// For example: we have MyModule!MyType that uses mscorlib!List<T>. Let's say List<T>.ctor got inlined into
// MyType.GetAllThinds() and into List<MyType>.FindAll. In this case we'll have two InlineeRecords for mscorlib!List<T>.ctor
// one for MyModule and another one for mscorlib.
-// PersistentInlineTrackingMap.GetInliners() always reads all InlineeRecords as long as they have the same key, few of them filtered out as hash collisions
-// others provide legitimate inlining information for methods from different modules.
+// PersistentInlineTrackingMap.GetInliners() always reads all ZapInlineeRecords as long as they have the same key, few of them filtered out
+// as hash collisions others provide legitimate inlining information for methods from different modules.
//
-// m_inlinersBuffer - byte array compressed by NibbleWriter. At any valid offset taken from InlineeRecord from m_inlineeIndex, there is a compressed chunk
+// m_inlinersBuffer - byte array compressed by NibbleWriter. At any valid offset taken from ZapInlineeRecord from m_inlineeIndex, there is a compressed chunk
// of this format:
// [InlineeModuleZapIndex][InlinerModuleZapIndex] [N - # of following inliners] [#1 inliner method RID] ... [#N inliner method RID]
// [InlineeModuleZapIndex] is used to verify that we actually found a desired inlinee module (not just a name hash collision).
// [InlinerModuleZapIndex] is an index of a module that owns following method tokens (inliners)
// [1..N inliner RID] are the sorted diff compressed method RIDs from the module specified by InlinerModuleZapIndex,
-// those methods directly or indirectly inlined code from inlinee method specified by InlineeRecord.
+// those methods directly or indirectly inlined code from inlinee method specified by ZapInlineeRecord.
// Since all the RIDs are sorted we'are actually able to save some space by using diffs instead of values, because NibbleWriter
// is good at saving small numbers.
// For example for RIDs: 5, 6, 19, 25, 30, we'll write: 5, 1 (=6-5), 13 (=19-6), 6 (=25-19), 5 (=30-25)
@@ -170,39 +199,111 @@ typedef DPTR(InlineTrackingMap) PTR_InlineTrackingMap;
// | - - - | InlineeModuleZapIndex | InlinerModuleZapIndex | SavedInlinersCount (N) | rid1 | rid2 | ...... | ridN | - - - |
// +-----------------+-----------------------+------------------------+------------------------+------+------+--------+------+-------------+
//
-class PersistentInlineTrackingMap
+
+
+
+
+
+
+
+
+
+// R2R encoding variation for the map
+//
+// It has several differences from the NGEN encoding. NGEN refers to methods outside the current assembly via module index + foreign module's token
+// but R2R can't take those fragile dependencies. Instead we refer to all methods via MethodDef tokens in the current assembly's metadata. This
+// is sufficient for everything we need to track now but in the future we may need to upgrade to a more expressive encoding. Currently NonVersionable
+// attributed methods may be inlined but will not be tracked. This shows up as a known limitation in the profiler APIs that expose this data.
+//
+// The format changes from NGEN:
+// a) The InlineIndex uses a MethodDef RID token as the key.
+// b) InlineeModuleZapIndex is omitted because the module is always the current one being compiled.
+// c) InlinerModuleZapIndex is similarly omitted.
+// d) (a), (b) and (c) together imply there is at most one entry in the inlineeIndex for any given key
+// e) A trivial header is now explicitly described
+//
+//
+// The resulting serialized format is a sequence of blobs:
+// 1) Header (4 byte aligned)
+// short MajorVersion - currently set to 1, increment on breaking change
+// short MinorVersion - currently set to 0, increment on non-breaking format addition
+// int SizeOfInlineIndex - size in bytes of the inline index
+//
+// 2) InlineIndex - Immediately following header. This is a sorted (by ZapInlineeRecord.key) array of ZapInlineeRecords, given a method token (32 bits)
+// we use binary search to find if this method has ever been inlined in R2R code of this image. Each record has m_offset, which is
+// an offset inside InlinersBuffer, it has more data on where the method got inlined. There is at most one ZapInlineeRecord with the
+// same key.
+//
+// 3) InlinersBuffer - Located immediately following the InlineIndex (Header RVA + sizeof(Header) + header.SizeOfInlineIndex)
+// This is a byte array compressed by NibbleWriter. At any valid offset taken from ZapInlineeRecord from InlineeIndex, there is a
+// compressed chunk of this format:
+// [N - # of following inliners] [#1 inliner method RID] ... [#N inliner method RID]
+// [1..N inliner RID] are the sorted diff compressed method RIDs interpreted as MethodDefs in this assembly's metadata,
+// Those methods directly or indirectly inlined code from inlinee method specified by ZapInlineeRecord.
+// Since all the RIDs are sorted we'are actually able to save some space by using diffs instead of values, because NibbleWriter
+// is good at saving small numbers.
+// For example for RIDs: 5, 6, 19, 25, 30, we'll write: 5, 1 (=6-5), 13 (=19-6), 6 (=25-19), 5 (=30-25)
+//
+// InlineeIndex
+// +-----+-----+---------------------------------------+-----+-----+
+// | - | - | m_key {MethodDefToken); m_offset | - | - |
+// +-----+-----+---------------------------------|-----+-----+-----+
+// |
+// +--------------------------+
+// |
+// InlinersBuffer \-/
+// +-----------------+------------------------+------+------+--------+------+-------------+
+// | - - - | SavedInlinersCount (N) | rid1 | rid2 | ...... | ridN | - - - |
+// +-----------------+------------------------+------+------+--------+------+-------------+
+//
+
+
+
+//A common key format for R2R and NGEN. If the formats
+//diverge further this might become irrelevant
+struct ZapInlineeRecord
{
-private:
- struct InlineeRecord
+ DWORD m_key;
+ DWORD m_offset;
+
+ ZapInlineeRecord()
+ : m_key(0)
+ {
+ LIMITED_METHOD_CONTRACT;
+ }
+
+ void InitForR2R(RID rid)
+ {
+ LIMITED_METHOD_CONTRACT;
+ m_key = rid;
+ }
+
+ void InitForNGen(RID rid, LPCUTF8 simpleName);
+
+ bool operator <(const ZapInlineeRecord& other) const
{
- DWORD m_key;
- DWORD m_offset;
-
- InlineeRecord()
- : m_key(0)
- {
- LIMITED_METHOD_CONTRACT;
- }
-
- InlineeRecord(RID rid, LPCUTF8 simpleName);
-
- bool operator <(const InlineeRecord& other) const
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return m_key < other.m_key;
- }
-
- bool operator ==(const InlineeRecord& other) const
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return m_key == other.m_key;
- }
- };
- typedef DPTR(InlineeRecord) PTR_InlineeRecord;
+ LIMITED_METHOD_DAC_CONTRACT;
+ return m_key < other.m_key;
+ }
+
+ bool operator ==(const ZapInlineeRecord& other) const
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+ return m_key == other.m_key;
+ }
+};
+typedef DPTR(ZapInlineeRecord) PTR_ZapInlineeRecord;
+
+
+// This type knows how to serialize and deserialize the inline tracking map format within an NGEN image. See
+// above for a description of the format.
+class PersistentInlineTrackingMapNGen
+{
+private:
PTR_Module m_module;
- PTR_InlineeRecord m_inlineeIndex;
+ PTR_ZapInlineeRecord m_inlineeIndex;
DWORD m_inlineeIndexSize;
PTR_BYTE m_inlinersBuffer;
@@ -210,23 +311,63 @@ private:
public:
- PersistentInlineTrackingMap(Module *module)
+ PersistentInlineTrackingMapNGen(Module *module)
: m_module(dac_cast<PTR_Module>(module))
{
LIMITED_METHOD_CONTRACT;
_ASSERTE(module != NULL);
}
+ // runtime deserialization
+ COUNT_T GetInliners(PTR_Module inlineeOwnerMod, mdMethodDef inlineeTkn, COUNT_T inlinersSize, MethodInModule inliners[], BOOL *incompleteData);
+
+ // compile-time serialization
+#ifndef DACCESS_COMPILE
void Save(DataImage *image, InlineTrackingMap* runtimeMap);
void Fixup(DataImage *image);
- COUNT_T GetInliners(PTR_Module inlineeOwnerMod, mdMethodDef inlineeTkn, COUNT_T inlinersSize, MethodInModule inliners[], BOOL *incompleteData);
-
private:
- void ProcessInlineTrackingEntry(DataImage *image, SBuffer *inlinersBuffer, SArray<InlineeRecord> *inlineeIndex, InlineTrackingEntry *entry);
+#endif
+
Module *GetModuleByIndex(DWORD index);
+
};
-typedef DPTR(PersistentInlineTrackingMap) PTR_PersistentInlineTrackingMap;
+typedef DPTR(PersistentInlineTrackingMapNGen) PTR_PersistentInlineTrackingMapNGen;
+
+
+// This type knows how to serialize and deserialize the inline tracking map format within an R2R image. See
+// above for a description of the format.
+#ifdef FEATURE_READYTORUN
+class PersistentInlineTrackingMapR2R
+{
+private:
+ PTR_Module m_module;
+
+ PTR_ZapInlineeRecord m_inlineeIndex;
+ DWORD m_inlineeIndexSize;
+
+ PTR_BYTE m_inlinersBuffer;
+ DWORD m_inlinersBufferSize;
+
+public:
+
+ // runtime deserialization
+#ifndef DACCESS_COMPILE
+ static BOOL TryLoad(Module* pModule, const BYTE* pBuffer, DWORD cbBuffer, AllocMemTracker *pamTracker, PersistentInlineTrackingMapR2R** ppLoadedMap);
+#endif
+ COUNT_T GetInliners(PTR_Module inlineeOwnerMod, mdMethodDef inlineeTkn, COUNT_T inlinersSize, MethodInModule inliners[], BOOL *incompleteData);
+
+
+ // compile time serialization
+#ifndef DACCESS_COMPILE
+ static void Save(ZapHeap* pHeap, SBuffer *saveTarget, InlineTrackingMap* runtimeMap);
+#endif
+
+};
+
+typedef DPTR(PersistentInlineTrackingMapR2R) PTR_PersistentInlineTrackingMapR2R;
+#endif //FEATURE_READYTORUN
+
#endif //INLINETRACKING_H_
diff --git a/src/vm/interopconverter.cpp b/src/vm/interopconverter.cpp
index 5e7f53ef75..cb42f9cdfe 100644
--- a/src/vm/interopconverter.cpp
+++ b/src/vm/interopconverter.cpp
@@ -8,9 +8,6 @@
#include "excep.h"
#include "interoputil.h"
#include "interopconverter.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "olevariant.h"
#include "comcallablewrapper.h"
@@ -46,12 +43,6 @@ IUnknown* GetIUnknownForMarshalByRefInServerDomain(OBJECTREF* poref)
Context *pContext = NULL;
-#ifdef FEATURE_REMOTING
- // so this is an proxy type,
- // now get it's underlying appdomain which will be null if non-local
- if ((*poref)->IsTransparentProxy())
- pContext = CRemotingServices::GetServerContextForProxy(*poref);
-#endif
if (pContext == NULL)
pContext = GetCurrentContext();
@@ -65,48 +56,6 @@ IUnknown* GetIUnknownForMarshalByRefInServerDomain(OBJECTREF* poref)
RETURN pUnk;
}
-#ifdef FEATURE_REMOTING
-//+----------------------------------------------------------------------------
-// IUnknown* GetIUnknownForTransparentProxy(OBJECTREF otp)
-//+----------------------------------------------------------------------------
-
-IUnknown* GetIUnknownForTransparentProxy(OBJECTREF* poref, BOOL fIsBeingMarshalled)
-{
- CONTRACT (IUnknown*)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(poref));
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- GCX_COOP();
-
- IUnknown* pUnk;
-
- OBJECTREF realProxy = ObjectToOBJECTREF(CRemotingServices::GetRealProxy(OBJECTREFToObject(*poref)));
- _ASSERTE(realProxy != NULL);
-
- GCPROTECT_BEGIN(realProxy);
-
- MethodDescCallSite getDCOMProxy(METHOD__REAL_PROXY__GETDCOMPROXY, &realProxy);
-
- ARG_SLOT args[] = {
- ObjToArgSlot(realProxy),
- BoolToArgSlot(fIsBeingMarshalled),
- };
-
- ARG_SLOT ret = getDCOMProxy.Call_RetArgSlot(args);
-
- pUnk = (IUnknown*)ret;
-
- GCPROTECT_END();
-
- RETURN pUnk;
-}
-#endif // FEATURE_REMOTING
//--------------------------------------------------------------------------------
// IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, ...)
@@ -133,47 +82,6 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bSecuri
if (*poref == NULL)
RETURN NULL;
-#ifdef FEATURE_REMOTING
- if ((*poref)->IsTransparentProxy())
- {
- // Retrieve the IID of the interface to QI for.
- IID iid;
- if (pMT->IsInterface())
- {
- pMT->GetGuid(&iid, TRUE);
- }
- else
- {
- ComCallWrapperTemplate *pTemplate = ComCallWrapperTemplate::GetTemplate(TypeHandle(pMT));
- if (pTemplate->SupportsIClassX())
- {
- ComMethodTable *pComMT = pTemplate->GetClassComMT();
- iid = pComMT->GetIID();
- }
- else
- {
- // if IClassX is not supported, we try the default interface of the class
- MethodTable *pDefItfMT = pMT->GetDefaultWinRTInterface();
- if (pDefItfMT != NULL)
- {
- pDefItfMT->GetGuid(&iid, TRUE);
- }
- else
- {
- // else we fail because the class has no IID associated with it
- IfFailThrow(E_NOINTERFACE);
- }
- }
- }
-
- // Retrieve an IUnknown for the TP.
- SafeComHolder<IUnknown> pProxyUnk = GetIUnknownForTransparentProxy(poref, FALSE);
-
- // QI for the requested interface.
- IfFailThrow(SafeQueryInterface(pProxyUnk, iid, &pUnk));
- goto LExit;
- }
-#endif // FEATURE_REMOTING
SyncBlock* pBlock = (*poref)->GetSyncBlock();
@@ -202,9 +110,6 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bSecuri
RCWPROTECT_END(pRCW);
}
-#ifdef FEATURE_REMOTING
-LExit:
-#endif
// If we failed to retrieve an IP then throw an exception.
if (pUnk == NULL)
COMPlusThrowHR(hr);
@@ -244,47 +149,6 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, ComIpType ReqIpType, ComIpType
RETURN NULL;
MethodTable *pMT = (*poref)->GetMethodTable();
-#ifdef FEATURE_REMOTING
- if (pMT->IsTransparentProxy())
- {
- SafeComHolder<IUnknown> pProxyUnk = GetIUnknownForTransparentProxy(poref, FALSE);
-
- if (ReqIpType & ComIpType_Dispatch)
- {
- hr = SafeQueryInterface(pProxyUnk, IID_IDispatch, &pUnk);
- if (SUCCEEDED(hr))
- {
- // In Whidbey we used to return ComIpType_Unknown here to maintain backward compatibility with
- // previous releases where we had mistakenly returned ComIpType_None (which was interpreted as
- // ComIpType_Unknown by the callers of this method).
- FetchedIpType = ComIpType_Dispatch;
- goto LExit;
- }
- }
-
- if (ReqIpType & ComIpType_Inspectable)
- {
- hr = SafeQueryInterface(pProxyUnk, IID_IInspectable, &pUnk);
- if (SUCCEEDED(hr))
- {
- FetchedIpType = ComIpType_Inspectable;
- goto LExit;
- }
- }
-
- if (ReqIpType & ComIpType_Unknown)
- {
- hr = SafeQueryInterface(pProxyUnk, IID_IUnknown, &pUnk);
- if (SUCCEEDED(hr))
- {
- FetchedIpType = ComIpType_Unknown;
- goto LExit;
- }
- }
-
- goto LExit;
- }
-#endif // FEATURE_REMOTING
SyncBlock* pBlock = (*poref)->GetSyncBlock();
@@ -507,9 +371,6 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, ComIpType ReqIpType, ComIpType
}
}
-#ifdef FEATURE_REMOTING
-LExit:
-#endif
// If we failed to retrieve an IP then throw an exception.
if (pUnk == NULL)
COMPlusThrowHR(hr);
@@ -553,14 +414,6 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, REFIID iid, bool throwIfNoComI
RETURN NULL;
MethodTable *pMT = (*poref)->GetMethodTable();
-#ifdef FEATURE_REMOTING
- if (pMT->IsTransparentProxy())
- {
- SafeComHolder<IUnknown> pProxyUnk = GetIUnknownForTransparentProxy(poref, FALSE);
- IfFailThrow(SafeQueryInterface(pProxyUnk, iid, &pUnk));
- goto LExit;
- }
-#endif
SyncBlock* pBlock = (*poref)->GetSyncBlock();
@@ -586,47 +439,12 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, REFIID iid, bool throwIfNoComI
pUnk = pUnkHolder.Extract();
}
-#ifdef FEATURE_REMOTING
-LExit:
-#endif
if (throwIfNoComIP && pUnk == NULL)
COMPlusThrowHR(hr);
RETURN pUnk;
}
-#ifdef FEATURE_REMOTING
-OBJECTREF GetObjectRefFromComIP_CrossDomain(ADID objDomainId, ComCallWrapper* pWrap)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- OBJECTREF oref = NULL;
-
- EX_TRY
- {
- // the CCW belongs to a different domain..
- // unmarshal the object to the current domain
- if (!UnMarshalObjectForCurrentDomain(objDomainId, pWrap, &oref))
- oref = NULL;
- }
- EX_CATCH
- {
- // fall back to creating an RCW if we were unable to
- // marshal the object (most commonly because the object
- // graph is not serializable)
- oref = NULL;
- }
- EX_END_CATCH(SwallowAllExceptions)
-
- return oref;
-}
-#endif //#ifdef FEATURE_REMOTING
//+----------------------------------------------------------------------------
// GetObjectRefFromComIP
@@ -692,15 +510,8 @@ void GetObjectRefFromComIP(OBJECTREF* pObjOut, IUnknown **ppUnk, MethodTable *pM
_ASSERTE(pWrap != NULL);
AppDomain* pCurrDomain = pThread->GetDomain();
ADID pObjDomain = pWrap->GetDomainID();
-#ifdef FEATURE_REMOTING
- if (pObjDomain == pCurrDomain->GetId())
- *pObjOut = pWrap->GetObjectRef();
- else
- *pObjOut = GetObjectRefFromComIP_CrossDomain(pObjDomain, pWrap);
-#else
_ASSERTE(pObjDomain == pCurrDomain->GetId());
*pObjOut = pWrap->GetObjectRef();
-#endif
}
if (*pObjOut != NULL)
@@ -812,173 +623,3 @@ void GetObjectRefFromComIP(OBJECTREF* pObjOut, IUnknown **ppUnk, MethodTable *pM
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_REMOTING
-//--------------------------------------------------------
-// ConvertObjectToBSTR
-// serializes object to a BSTR, caller needs to SysFree the Bstr
-// and GCPROTECT the oref parameter.
-//--------------------------------------------------------------------------------
-BOOL ConvertObjectToBSTR(OBJECTREF* oref, BOOL fCrossRuntime, BSTR* pBStr)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pBStr));
- PRECONDITION(IsProtectedByGCFrame (oref));
- }
- CONTRACTL_END;
-
- *pBStr = NULL;
-
- MethodTable *pMT = (*oref)->GetMethodTable();
- if (!pMT->IsTransparentProxy() && !pMT->IsMarshaledByRef() && !pMT->IsSerializable())
- {
- // The object is not serializable - don't waste time calling to managed and trying to
- // serialize it with a formatter. This is an optimization so we don't throw and catch
- // SerializationException unnecessarily.
- return FALSE;
- }
-
- // We will be using the remoting services so make sure remoting is started up.
- CRemotingServices::EnsureRemotingStarted();
-
- MethodDescCallSite marshalToBuffer(METHOD__REMOTING_SERVICES__MARSHAL_TO_BUFFER);
-
- ARG_SLOT args[] =
- {
- ObjToArgSlot(*oref),
- BoolToArgSlot(fCrossRuntime)
- };
-
- BASEARRAYREF aref = (BASEARRAYREF) marshalToBuffer.Call_RetOBJECTREF(args);
-
- if (aref != NULL)
- {
- _ASSERTE(!aref->IsMultiDimArray());
- //@todo ASSERTE that the array is a byte array
-
- ULONG cbSize = aref->GetNumComponents();
- BYTE* pBuf = (BYTE *)aref->GetDataPtr();
-
- BSTR bstr = SysAllocStringByteLen(NULL, cbSize);
- if (bstr == NULL)
- COMPlusThrowOM();
-
- CopyMemory(bstr, pBuf, cbSize);
- *pBStr = bstr;
- }
-
- return TRUE;
-}
-
-//--------------------------------------------------------------------------------
-// ConvertBSTRToObject
-// deserializes a BSTR, created using ConvertObjectToBSTR, this api SysFree's the BSTR
-//--------------------------------------------------------------------------------
-OBJECTREF ConvertBSTRToObject(BSTR bstr, BOOL fCrossRuntime)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- BSTRHolder localBstr(bstr);
-
- OBJECTREF oref = NULL;
-
- // We will be using the remoting services so make sure remoting is started up.
- CRemotingServices::EnsureRemotingStarted();
-
- MethodDescCallSite unmarshalFromBuffer(METHOD__REMOTING_SERVICES__UNMARSHAL_FROM_BUFFER);
-
- // convert BSTR to a byte array
-
- // allocate a byte array
- INT32 elementCount = SysStringByteLen(bstr);
- TypeHandle t = OleVariant::GetArrayForVarType(VT_UI1, TypeHandle((MethodTable *)NULL));
- BASEARRAYREF aref = (BASEARRAYREF) AllocateArrayEx(t, &elementCount, 1);
- // copy the bstr data into the managed byte array
- memcpyNoGCRefs(aref->GetDataPtr(), bstr, elementCount);
-
- ARG_SLOT args[] =
- {
- ObjToArgSlot((OBJECTREF)aref),
- BoolToArgSlot(fCrossRuntime)
- };
-
- oref = unmarshalFromBuffer.Call_RetOBJECTREF(args);
-
- return oref;
-}
-
-//--------------------------------------------------------------------------------
-// UnMarshalObjectForCurrentDomain
-// unmarshal the managed object for the current domain
-//--------------------------------------------------------------------------------
-struct ConvertObjectToBSTR_Args
-{
- OBJECTREF* oref;
- BOOL fCrossRuntime;
- BSTR *pBStr;
- BOOL fResult;
-};
-
-void ConvertObjectToBSTR_Wrapper(LPVOID ptr)
-{
- WRAPPER_NO_CONTRACT;
-
- ConvertObjectToBSTR_Args *args = (ConvertObjectToBSTR_Args *)ptr;
- args->fResult = ConvertObjectToBSTR(args->oref, args->fCrossRuntime, args->pBStr);
-}
-
-
-BOOL UnMarshalObjectForCurrentDomain(ADID pObjDomain, ComCallWrapper* pWrap, OBJECTREF* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pWrap));
- PRECONDITION(CheckPointer(pResult));
- }
- CONTRACTL_END;
-
- Thread* pThread = GetThread();
- _ASSERTE(pThread);
-
- _ASSERTE(pThread->GetDomain() != NULL);
- _ASSERTE(pThread->GetDomain()->GetId()!= pObjDomain);
-
- BSTR bstr = NULL;
- ConvertObjectToBSTR_Args args;
- args.fCrossRuntime = FALSE;
- args.pBStr = &bstr;
-
- OBJECTREF oref = pWrap->GetObjectRef();
-
- GCPROTECT_BEGIN(oref);
- {
- args.oref = &oref;
- pThread->DoADCallBack(pObjDomain, ConvertObjectToBSTR_Wrapper, &args);
- }
- GCPROTECT_END();
-
- if (args.fResult)
- {
- _ASSERTE(bstr != NULL);
- *pResult = ConvertBSTRToObject(bstr, FALSE);
- }
- else
- {
- *pResult = NULL;
- }
-
- return args.fResult;
-}
-#endif //FEATURE_REMOTING
diff --git a/src/vm/interopconverter.h b/src/vm/interopconverter.h
index d0e2186ba2..21368dd8a3 100644
--- a/src/vm/interopconverter.h
+++ b/src/vm/interopconverter.h
@@ -157,21 +157,6 @@ inline void GetObjectRefFromComIP(OBJECTREF* pObjOut, IUnknown *pUnk, MethodTabl
return GetObjectRefFromComIP(pObjOut, &pUnk, pMTClass, pItfMT, dwFlags);
}
-#ifdef FEATURE_REMOTING // used only by remoting
-//--------------------------------------------------------
-// managed serialization helpers
-//--------------------------------------------------------
-// ConvertObjectToBSTR
-// serializes object to a BSTR, caller needs to SysFree the Bstr
-// and GCPROTECT the oref parameter.
-BOOL ConvertObjectToBSTR(OBJECTREF* oref, BOOL fCrossRuntime, BSTR* pBStr);
-
-
-//--------------------------------------------------------------------------------
-// ConvertBSTRToObject
-// deserializes a BSTR, created using ConvertObjectToBSTR, this api SysFree's the BSTR
-OBJECTREF ConvertBSTRToObject(BSTR bstr, BOOL fCrossRuntime);
-#endif
//--------------------------------------------------------------------------------
// UnMarshalObjectForCurrentDomain
diff --git a/src/vm/interoputil.cpp b/src/vm/interoputil.cpp
index 6a0fbded12..d48163c075 100644
--- a/src/vm/interoputil.cpp
+++ b/src/vm/interoputil.cpp
@@ -14,9 +14,6 @@
#include "eeconfig.h"
#include "mlinfo.h"
#include "comdelegate.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "appdomain.hpp"
#include "prettyprintsig.h"
#include "util.hpp"
@@ -46,9 +43,6 @@
#include "clrtocomcall.h"
#include "comcache.h"
#include "commtmemberinfomap.h"
-#ifdef FEATURE_COMINTEROP_TLB_SUPPORT
-#include "comtypelibconverter.h"
-#endif
#include "olevariant.h"
#include "stdinterfaces.h"
#include "notifyexternals.h"
@@ -294,7 +288,6 @@ static const BinderMethodID s_stubsDisposableToClosable[] =
METHOD__IDISPOSABLE_TO_ICLOSABLE_ADAPTER__CLOSE
};
-#ifdef FEATURE_CORECLR
DEFINE_ASM_QUAL_TYPE_NAME(NCCWINRT_ASM_QUAL_TYPE_NAME, g_INotifyCollectionChanged_WinRTName, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
DEFINE_ASM_QUAL_TYPE_NAME(NCCMA_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedToManagedAdapterName, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
DEFINE_ASM_QUAL_TYPE_NAME(NCCWA_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedToWinRTAdapterName, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
@@ -306,20 +299,6 @@ DEFINE_ASM_QUAL_TYPE_NAME(CMDMA_ASM_QUAL_TYPE_NAME, g_ICommandToManagedAdapterNa
DEFINE_ASM_QUAL_TYPE_NAME(CMDWA_ASM_QUAL_TYPE_NAME, g_ICommandToWinRTAdapterName, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
DEFINE_ASM_QUAL_TYPE_NAME(NCCEHWINRT_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedEventHandler_WinRT, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
DEFINE_ASM_QUAL_TYPE_NAME(PCEHWINRT_ASM_QUAL_TYPE_NAME, g_PropertyChangedEventHandler_WinRT_Name, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-#else
-DEFINE_ASM_QUAL_TYPE_NAME(NCCWINRT_ASM_QUAL_TYPE_NAME, g_INotifyCollectionChanged_WinRTName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(NCCMA_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedToManagedAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(NCCWA_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedToWinRTAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(NPCWINRT_ASM_QUAL_TYPE_NAME, g_INotifyPropertyChanged_WinRTName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(NPCMA_ASM_QUAL_TYPE_NAME, g_NotifyPropertyChangedToManagedAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(NPCWA_ASM_QUAL_TYPE_NAME, g_NotifyPropertyChangedToWinRTAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(CMDWINRT_ASM_QUAL_TYPE_NAME, g_ICommand_WinRTName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(CMDMA_ASM_QUAL_TYPE_NAME, g_ICommandToManagedAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(CMDWA_ASM_QUAL_TYPE_NAME, g_ICommandToWinRTAdapterName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(NCCEHWINRT_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedEventHandler_WinRT, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-DEFINE_ASM_QUAL_TYPE_NAME(PCEHWINRT_ASM_QUAL_TYPE_NAME, g_PropertyChangedEventHandler_WinRT_Name, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-
-#endif
const WinRTInterfaceRedirector::NonMscorlibRedirectedInterfaceInfo WinRTInterfaceRedirector::s_rNonMscorlibInterfaceInfos[3] =
{
@@ -805,7 +784,6 @@ HRESULT SetupErrorInfo(OBJECTREF pThrownObject, BOOL bIsWinRTScenario /* = FALSE
pErr = (IErrorInfo *)GetComIPFromObjectRef(&pThrownObject, IID_IErrorInfo);
{
GCX_PREEMP();
- LeaveRuntimeHolder lrh((size_t)SetErrorInfo);
SetErrorInfo(0, pErr);
}
}
@@ -1479,9 +1457,6 @@ ULONG SafeReleasePreemp(IUnknown * pUnk, RCW * pRCW)
MdaReportAvOnComRelease* pProbe = MDA_GET_ASSISTANT_EX(ReportAvOnComRelease);
if (pProbe && pProbe->AllowAV())
{
- LeaveRuntimeHolderNoThrow lrh(*((*(size_t**)pUnk)+2));
- if (FAILED(lrh.GetHR()))
- return -1;
return pUnk->Release();
}
#endif // MDA_SUPPORTED
@@ -1500,15 +1475,8 @@ ULONG SafeReleasePreemp(IUnknown * pUnk, RCW * pRCW)
// down the Runtime. Mark that an AV is alright, and handled, in this scope using this holder.
AVInRuntimeImplOkayHolder AVOkay(pThread);
- if (CLRTaskHosted()) // Check hoisted out of LeaveRuntimeHolder to
- { // keep LeaveRuntimeHolder off of common path.
- LeaveRuntimeHolder lrh(*((*(size_t**)pUnk)+2));
- res = pUnk->Release();
- }
- else
- {
- res = pUnk->Release();
- }
+ res = pUnk->Release();
+
SCAN_EHMARKER_END_TRY();
}
PAL_CPP_CATCH_ALL
@@ -1569,9 +1537,6 @@ ULONG SafeRelease(IUnknown* pUnk, RCW* pRCW)
MdaReportAvOnComRelease* pProbe = MDA_GET_ASSISTANT_EX(ReportAvOnComRelease);
if (pProbe && pProbe->AllowAV())
{
- LeaveRuntimeHolderNoThrow lrh(*((*(size_t**)pUnk)+2));
- if (FAILED(lrh.GetHR()))
- return -1;
return pUnk->Release();
}
#endif // MDA_SUPPORTED
@@ -1590,15 +1555,8 @@ ULONG SafeRelease(IUnknown* pUnk, RCW* pRCW)
// down the Runtime. Mark that an AV is alright, and handled, in this scope using this holder.
AVInRuntimeImplOkayHolder AVOkay(pThread);
- if (CLRTaskHosted()) // Check hoisted out of LeaveRuntimeHolder to
- { // keep LeaveRuntimeHolder off of common path.
- LeaveRuntimeHolder lrh(*((*(size_t**)pUnk)+2));
- res = pUnk->Release();
- }
- else
- {
- res = pUnk->Release();
- }
+ res = pUnk->Release();
+
SCAN_EHMARKER_END_TRY();
}
PAL_CPP_CATCH_ALL
@@ -1906,7 +1864,6 @@ HRESULT SafeGetErrorInfo(IErrorInfo **ppIErrInfo)
HRESULT hr = S_OK;
EX_TRY
{
- LeaveRuntimeHolder lrh((size_t)GetErrorInfo);
hr = GetErrorInfo(0, ppIErrInfo);
}
EX_CATCH
@@ -1922,22 +1879,6 @@ HRESULT SafeGetErrorInfo(IErrorInfo **ppIErrInfo)
#endif
}
-HRESULT SafeQueryInterfaceHosted(IUnknown* pUnk, REFIID riid, IUnknown** pResUnk)
-{
- CONTRACTL
- {
- THROWS; // message pump could happen, so arbitrary managed code could run
- GC_TRIGGERS;
- DISABLED(MODE_PREEMPTIVE); // disabled because I couldn't figure out how to tell SCAN about my
- // manual mode change in SafeQueryInterface
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- LeaveRuntimeHolder lrh(*((*(size_t**)pUnk)+0));
- return pUnk->QueryInterface(riid, (void**) pResUnk);
-}
-
#include <optsmallperfcritical.h>
//--------------------------------------------------------------------------------
@@ -1966,14 +1907,7 @@ HRESULT SafeQueryInterface(IUnknown* pUnk, REFIID riid, IUnknown** pResUnk)
#define PAL_TRY_REFARG(argName) (pParam->argName)
PAL_TRY(Param * const, pParam, &param)
{
- if (CLRTaskHosted())
- {
- PAL_TRY_ARG(hr) = SafeQueryInterfaceHosted(PAL_TRY_ARG(pUnk), PAL_TRY_REFARG(riid), PAL_TRY_ARG(pResUnk));
- }
- else
- {
- PAL_TRY_ARG(hr) = PAL_TRY_ARG(pUnk)->QueryInterface(PAL_TRY_REFARG(riid), (void**) PAL_TRY_ARG(pResUnk));
- }
+ PAL_TRY_ARG(hr) = PAL_TRY_ARG(pUnk)->QueryInterface(PAL_TRY_REFARG(riid), (void**) PAL_TRY_ARG(pResUnk));
}
PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -2032,14 +1966,7 @@ HRESULT SafeQueryInterfacePreemp(IUnknown* pUnk, REFIID riid, IUnknown** pResUnk
#define PAL_TRY_REFARG(argName) (pParam->argName)
PAL_TRY(Param * const, pParam, &param)
{
- if (CLRTaskHosted())
- {
- PAL_TRY_ARG(hr) = SafeQueryInterfaceHosted(PAL_TRY_ARG(pUnk), PAL_TRY_REFARG(riid), PAL_TRY_ARG(pResUnk));
- }
- else
- {
- PAL_TRY_ARG(hr) = PAL_TRY_ARG(pUnk)->QueryInterface(PAL_TRY_REFARG(riid), (void**) PAL_TRY_ARG(pResUnk));
- }
+ PAL_TRY_ARG(hr) = PAL_TRY_ARG(pUnk)->QueryInterface(PAL_TRY_REFARG(riid), (void**) PAL_TRY_ARG(pResUnk));
}
PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
@@ -2340,7 +2267,6 @@ HRESULT LoadRegTypeLibWithFlags(REFGUID guid,
EX_TRY
{
- LeaveRuntimeHolder lrh((size_t)QueryPathOfRegTypeLib);
hr = QueryPathOfRegTypeLib(guid, wVerMajor, wVerMinor, LOCALE_USER_DEFAULT, &wzPath);
}
EX_CATCH
@@ -2370,48 +2296,7 @@ HRESULT LoadTypeLibExWithFlags(LPCOLESTR szFile,
}
CONTRACTL_END;
-#ifndef FEATURE_COMINTEROP_TLB_SUPPORT
return E_FAIL;
-#else //FEATURE_COMINTEROP_TLB_SUPPORT
-
- *pptlib = NULL;
-
- GCX_PREEMP();
-
- REGKIND rk = REGKIND_NONE;
-
- if ((flags & TlbExporter_ExportAs64Bit) == TlbExporter_ExportAs64Bit)
- {
- rk = (REGKIND)(REGKIND_NONE | LOAD_TLB_AS_64BIT);
- }
- else if ((flags & TlbExporter_ExportAs32Bit) == TlbExporter_ExportAs32Bit)
- {
- rk = (REGKIND)(REGKIND_NONE | LOAD_TLB_AS_32BIT);
- }
-
- HRESULT hr = S_OK;
-
- EX_TRY
- {
- LeaveRuntimeHolder lrh((size_t)LoadTypeLibEx);
-
- hr = LoadTypeLibEx(szFile, rk, pptlib);
-
- // If we fail with E_INVALIDARG, it's probably because we're on a downlevel
- // platform that doesn't support loading type libraries by bitness.
- if (hr == E_INVALIDARG)
- {
- hr = LoadTypeLibEx(szFile, REGKIND_NONE, pptlib);
- }
- }
- EX_CATCH
- {
- hr = E_OUTOFMEMORY;
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- return hr;
-#endif //FEATURE_COMINTEROP_TLB_SUPPORT
}
@@ -2536,15 +2421,6 @@ HRESULT GetCLSIDFromProgID(__in_z WCHAR *strProgId, GUID *pGuid)
HRESULT hr = S_OK;
#ifdef FEATURE_CORESYSTEM
- LeaveRuntimeHolderNoThrow lrh((size_t)CLSIDFromProgID);
-#else
- LeaveRuntimeHolderNoThrow lrh((size_t)CLSIDFromProgIDEx);
-#endif
- hr = lrh.GetHR();
- if (FAILED(hr))
- return hr;
-
-#ifdef FEATURE_CORESYSTEM
return CLSIDFromProgID(strProgId, pGuid);
#else
return CLSIDFromProgIDEx(strProgId, pGuid);
@@ -2552,24 +2428,6 @@ HRESULT GetCLSIDFromProgID(__in_z WCHAR *strProgId, GUID *pGuid)
}
#endif // FEATURE_CLASSIC_COMINTEROP
-NOINLINE ULONG SafeAddRefHosted(IUnknown* pUnk)
-{
- CONTRACTL
- {
- THROWS; // arbitrary managed code could run
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- LeaveRuntimeHolderNoThrow lrh(*((*(size_t**)pUnk)+1));
- if (FAILED(lrh.GetHR()))
- return ~0;
-
- return pUnk->AddRef();
-}
-
#include <optsmallperfcritical.h>
//--------------------------------------------------------------------------------
// AddRef helper, enables and disables GC during call-outs
@@ -2595,14 +2453,7 @@ ULONG SafeAddRef(IUnknown* pUnk)
CONTRACT_VIOLATION(ThrowsViolation); // arbitrary managed code could run
- if (CLRTaskHosted()) // Check hoisted out of LeaveRuntimeHolder to
- { // keep LeaveRuntimeHolder off of common path.
- res = SafeAddRefHosted(pUnk);
- }
- else
- {
- res = pUnk->AddRef();
- }
+ res = pUnk->AddRef();
GCX_PREEMP_NO_DTOR_END();
@@ -2632,14 +2483,7 @@ ULONG SafeAddRefPreemp(IUnknown* pUnk)
CONTRACT_VIOLATION(ThrowsViolation); // arbitrary managed code could run
- if (CLRTaskHosted()) // Check hoisted out of LeaveRuntimeHolder to
- { // keep LeaveRuntimeHolder off of common path.
- res = SafeAddRefHosted(pUnk);
- }
- else
- {
- res = pUnk->AddRef();
- }
+ res = pUnk->AddRef();
return res;
}
@@ -2725,11 +2569,7 @@ HRESULT SafeVariantChangeType(_Inout_ VARIANT* pVarRes, _In_ VARIANT* pVarSrc,
GCX_PREEMP();
EX_TRY
{
- LeaveRuntimeHolderNoThrow lrh((size_t)VariantChangeType);
- hr = lrh.GetHR();
-
- if (!FAILED(hr))
- hr = VariantChangeType(pVarRes, pVarSrc, wFlags, vt);
+ hr = VariantChangeType(pVarRes, pVarSrc, wFlags, vt);
}
EX_CATCH
{
@@ -2759,12 +2599,7 @@ HRESULT SafeVariantChangeTypeEx(_Inout_ VARIANT* pVarRes, _In_ VARIANT* pVarSrc,
_ASSERTE(GetModuleHandleA("oleaut32.dll") != NULL);
CONTRACT_VIOLATION(ThrowsViolation);
- HRESULT hr = S_OK;
- LeaveRuntimeHolderNoThrow lrh((size_t)VariantChangeTypeEx);
- hr = lrh.GetHR();
-
- if (!FAILED(hr))
- hr = VariantChangeTypeEx (pVarRes, pVarSrc,lcid,wFlags,vt);
+ HRESULT hr = VariantChangeTypeEx (pVarRes, pVarSrc,lcid,wFlags,vt);
return hr;
}
@@ -2801,14 +2636,7 @@ void SafeReleaseStream(IStream *pStream)
GCX_PREEMP();
{
- HRESULT hr = S_OK;
-
- LeaveRuntimeHolderNoThrow lrh((size_t)CoReleaseMarshalData);
- hr = lrh.GetHR();
-
- if (!FAILED(hr))
- {
- hr = CoReleaseMarshalData(pStream);
+ HRESULT hr = CoReleaseMarshalData(pStream);
#ifdef _DEBUG
wchar_t logStr[200];
@@ -2826,7 +2654,6 @@ void SafeReleaseStream(IStream *pStream)
LogInterop(logStr);
}
#endif
- }
}
ULONG cbRef = SafeReleasePreemp(pStream);
@@ -4404,13 +4231,11 @@ static void DoIUInvokeDispMethod(IDispatchEx* pDispEx, IDispatch* pDisp, DISPID
if (pDispEx)
{
- LeaveRuntimeHolder holder(**(size_t**)pDispEx);
hr = InvokeExHelper(pDispEx, MemberID, lcid, flags, pDispParams,
pVarResult, &ExcepInfo, NULL);
}
else
{
- LeaveRuntimeHolder holder(**(size_t**)pDisp);
hr = InvokeHelper( pDisp, MemberID, IID_NULL, lcid, flags,
pDispParams, pVarResult, &ExcepInfo, &iArgErr);
}
@@ -4763,13 +4588,11 @@ void IUInvokeDispMethod(REFLECTCLASSBASEREF* pRefClassObj, OBJECTREF* pTarget, O
if (!bstrTmpName)
COMPlusThrowOM();
- LeaveRuntimeHolder lrh(**(size_t**)(IUnknown*)pDispEx);
hr = pDispEx->GetDispID(bstrTmpName, fdexNameCaseSensitive, aDispID);
}
else
{
// Call GetIdsOfNames() to retrieve the DISPID's of the method and of the arguments.
- LeaveRuntimeHolder lrh(**(size_t**)(IUnknown*)pDisp);
hr = pDisp->GetIDsOfNames(
IID_NULL,
aNamesToConvert,
@@ -6850,7 +6673,6 @@ MethodTable* GetClassFromIProvideClassInfo(IUnknown* pUnk)
{
GCX_PREEMP();
- LeaveRuntimeHolder lrh(**(size_t**)(IUnknown*)pclsInfo);
hr = pclsInfo->GetClassInfo(&pTypeInfo);
}
@@ -6860,7 +6682,6 @@ MethodTable* GetClassFromIProvideClassInfo(IUnknown* pUnk)
{
{
GCX_PREEMP();
- LeaveRuntimeHolder lrh(**(size_t**)(IUnknown*)pTypeInfo);
hr = pTypeInfo->GetTypeAttr(&ptattr);
}
@@ -6934,7 +6755,6 @@ TypeHandle GetClassFromIInspectable(IUnknown* pUnk, bool *pfSupportsIInspectable
WinRtString winrtClassName;
{
GCX_PREEMP();
- LeaveRuntimeHolder lrh(**(size_t**)(IUnknown*)pInsp);
if (FAILED(pInsp->GetRuntimeClassName(winrtClassName.Address())))
{
RETURN TypeHandle();
@@ -6950,12 +6770,6 @@ TypeHandle GetClassFromIInspectable(IUnknown* pUnk, bool *pfSupportsIInspectable
LPCWSTR pwszClassName = winrtClassName.GetRawBuffer(&cchClassName);
SString ssClassName(SString::Literal, pwszClassName, cchClassName);
-#ifndef FEATURE_CORECLR
- if (ETW_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATE_DYNAMICTYPEUSAGE_KEYWORD))
- {
- FireEtwIInspectableRuntimeClassName(pwszClassName, GetClrInstanceId());
- }
-#endif
// Check a cache to see if this has already been looked up.
AppDomain *pDomain = GetAppDomain();
@@ -7093,7 +6907,6 @@ ABI::Windows::Foundation::IUriRuntimeClass *CreateWinRTUri(LPCWSTR wszUri, INT32
ABI::Windows::Foundation::IUriRuntimeClassFactory* pFactory = marshalingInfo->GetUriFactory();
SafeComHolder<ABI::Windows::Foundation::IUriRuntimeClass> pIUriRC;
- LeaveRuntimeHolder lrh(**(size_t**)(IUnknown*)pFactory);
HRESULT hrCreate = pFactory->CreateUri(WinRtStringRef(wszUri, cchUri), &pIUriRC);
if (FAILED(hrCreate))
{
diff --git a/src/vm/interpreter.cpp b/src/vm/interpreter.cpp
index b74672f4f0..010fee674b 100644
--- a/src/vm/interpreter.cpp
+++ b/src/vm/interpreter.cpp
@@ -23,9 +23,6 @@
#include "runtimehandles.h"
#include "vars.hpp"
#include "cycletimer.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
inline CORINFO_CALLINFO_FLAGS combine(CORINFO_CALLINFO_FLAGS flag1, CORINFO_CALLINFO_FLAGS flag2)
{
@@ -5993,20 +5990,6 @@ void Interpreter::NewObj()
MethodTable * pNewObjMT = GetMethodTableFromClsHnd(methTok.hClass);
switch (newHelper)
{
-#ifdef FEATURE_REMOTING
- case CORINFO_HELP_NEW_CROSSCONTEXT:
- {
- if (CRemotingServices::RequiresManagedActivation(pNewObjMT) && !pNewObjMT->IsComObjectType())
- {
- thisArgObj = CRemotingServices::CreateProxyOrObject(pNewObjMT);
- }
- else
- {
- thisArgObj = AllocateObject(pNewObjMT);
- }
- }
- break;
-#endif // FEATURE_REMOTING
case CORINFO_HELP_NEWFAST:
default:
thisArgObj = AllocateObject(pNewObjMT);
@@ -7330,12 +7313,6 @@ void Interpreter::LdFld(FieldDesc* fldIn)
{
OBJECTREF obj = OBJECTREF(OpStackGet<Object*>(stackInd));
ThrowOnInvalidPointer(OBJECTREFToObject(obj));
-#ifdef FEATURE_REMOTING
- if (obj->IsTransparentProxy())
- {
- NYI_INTERP("Thunking objects not supported");
- }
-#endif
if (valCit == CORINFO_TYPE_VALUECLASS)
{
void* srcPtr = fld->GetInstanceAddress(obj);
diff --git a/src/vm/invokeutil.cpp b/src/vm/invokeutil.cpp
index 42e5a86249..1c7173a12b 100644
--- a/src/vm/invokeutil.cpp
+++ b/src/vm/invokeutil.cpp
@@ -18,9 +18,6 @@
#include "method.hpp"
#include "threads.h"
#include "excep.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "security.h"
#include "field.h"
#include "customattribute.h"
@@ -940,13 +937,6 @@ void InvokeUtil::ValidateObjectTarget(FieldDesc *pField, TypeHandle enclosingTyp
// Give a second chance to thunking classes to do the
// correct cast
if (ty.IsNull()) {
-#ifdef FEATURE_REMOTING
- BOOL fCastOK = FALSE;
- if ((*target)->IsTransparentProxy()) {
- fCastOK = CRemotingServices::CheckCast(*target, enclosingType);
- }
- if(!fCastOK)
-#endif
{
COMPlusThrow(kArgumentException,W("Arg_ObjObj"));
}
@@ -1151,37 +1141,6 @@ void InvokeUtil::SetValidField(CorElementType fldType,
{
_ASSERTE(!fldTH.IsTypeDesc());
MethodTable *pMT = fldTH.AsMethodTable();
-#ifdef FEATURE_REMOTING
- if((*target) != NULL && (*target)->IsTransparentProxy()) {
- OBJECTREF val = *valueObj;
- GCPROTECT_BEGIN(val)
-
- void* valueData;
- if (Nullable::IsNullableType(fldTH)) {
- // Special case for Nullable<T>, we need a true nullable that is gc protected. The easiest
- // way to make one is to allocate an object on the heap
- OBJECTREF trueNullable = fldTH.AsMethodTable()->Allocate();
- BOOL typesChecked;
- typesChecked = Nullable::UnBox(trueNullable->GetData(), val, fldTH.AsMethodTable());
- _ASSERTE(typesChecked);
- val = trueNullable;
- valueData = val->GetData();
- }
- else if (val == NULL) {
- // Null is the universal null object. (Is this a good idea?)
- int size = pMT->GetNumInstanceFieldBytes();
- valueData = _alloca(size);
- memset(valueData, 0, size);
- }
- else
- valueData = val->GetData();
-
- OBJECTREF unwrapped = CRemotingServices::GetObjectFromProxy(*target);
- CRemotingServices::FieldAccessor(pField, unwrapped, valueData, FALSE);
- GCPROTECT_END();
- }
- else
-#endif
{
void* pFieldData;
if (pField->IsStatic())
@@ -1336,14 +1295,6 @@ OBJECTREF InvokeUtil::GetFieldValue(FieldDesc* pField, TypeHandle fieldType, OBJ
if (pField->IsStatic())
p = pField->GetCurrentStaticAddress();
else {
-#ifdef FEATURE_REMOTING
- OBJECTREF o = *target;
- if(o->IsTransparentProxy()) {
- OBJECTREF unwrapped = CRemotingServices::GetObjectFromProxy(o);
- CRemotingServices::FieldAccessor(pField, unwrapped, (void*)obj->GetData(), TRUE);
- }
- else
-#endif
p = (*((BYTE**)target)) + pField->GetOffset() + sizeof(Object);
}
GCPROTECT_END();
@@ -1551,14 +1502,6 @@ void InvokeUtil::CanAccessClass(RefSecContext* pCtx,
InvokeUtil::CheckAccessClass(pCtx, pClass, checkAccessForImplicitValueTypeCtor);
-#ifndef FEATURE_CORECLR
- // Reflection invocation should turn critical method access into a full demand of full trust
- // for level 2 assemblies.
- if (InvokeUtil::IsCriticalWithConversionToFullDemand(pClass))
- {
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_FULL_TRUST);
- }
-#endif //FEATURE_CORECLR
}
#ifndef DACCESS_COMPILE
@@ -1579,30 +1522,12 @@ void InvokeUtil::CanAccessMethod(MethodDesc* pMeth,
}
CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- // Security checks are expensive as they involve stack walking. Avoid them if we can.
- // In immersive we don't allow private reflection to framework code. So we need to perform
- // the access check even if all the domains on the stack are fully trusted.
- if (Security::AllDomainsOnStackFullyTrusted() && !AppX::IsAppXProcess() && !pParentMT->GetAssembly()->IsDisabledPrivateReflection())
- return;
-#endif // FEATURE_CORECLR
InvokeUtil::CheckAccessMethod(pSCtx,
pParentMT,
pInstanceMT,
pMeth);
-#ifndef FEATURE_CORECLR
- // Reflection invocation should turn critical method access into a full demand of full trust
- // for level 2 assemblies.
- if (fCriticalToFullDemand && InvokeUtil::IsCriticalWithConversionToFullDemand(pMeth, pParentMT))
- {
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_FULL_TRUST);
-
- // No need to do any more checks if a full trust full demand has succeeded.
- return;
- }
-#endif //FEATURE_CORECLR
if (pMeth->RequiresLinktimeCheck())
{
@@ -1610,25 +1535,6 @@ void InvokeUtil::CanAccessMethod(MethodDesc* pMeth,
// stack walks in order to close security holes in poorly written
// reflection users.
-#ifdef FEATURE_APTCA
- if (Security::IsUntrustedCallerCheckNeeded(pMeth))
- {
- if (pSCtx->GetCallerMT())
- {
- // Check for untrusted caller
- // It is possible that wrappers like VBHelper libraries that are
- // fully trusted, make calls to public methods that do not have
- // safe for Untrusted caller custom attribute set.
- // Like all other link demand that gets transformed to a full stack
- // walk for reflection, calls to public methods also gets
- // converted to full stack walk
-
- Security::DoUntrustedCallerChecks(
- pSCtx->GetCallerMT()->GetAssembly(), pMeth,
- TRUE);
- }
- }
-#endif // FEATURE_APTCA
struct _gc
{
@@ -1667,7 +1573,6 @@ void InvokeUtil::CanAccessMethod(MethodDesc* pMeth,
GCPROTECT_END();
-#ifdef FEATURE_CORECLR
if (pMeth->IsNDirect() ||
(pMeth->IsComPlusCall() && !pMeth->IsInterface()))
{
@@ -1683,27 +1588,6 @@ void InvokeUtil::CanAccessMethod(MethodDesc* pMeth,
}
}
-#else // FEATURE_CORECLR
- // We perform automatic linktime checks for UnmanagedCode in three cases:
- // o P/Invoke calls.
- // o Calls through an interface that have a suppress runtime check
- // attribute on them (these are almost certainly interop calls).
- // o Interop calls made through method impls.
- if (pMeth->IsNDirect() ||
- (pMeth->IsInterface() &&
- (pMeth->GetMDImport()->GetCustomAttributeByName(pParentMT->GetCl(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK ||
- pMeth->GetMDImport()->GetCustomAttributeByName(pMeth->GetMemberDef(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK) ) ||
- (pMeth->IsComPlusCall() && !pMeth->IsInterface()))
- {
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_UNMANAGED_CODE);
- }
-#endif // FEATURE_CORECLR
}
// @todo:
@@ -1731,9 +1615,6 @@ void InvokeUtil::CanAccessMethod(MethodDesc* pMeth,
}
}
-#ifndef FEATURE_CORECLR
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_SKIP_VER);
-#endif // !FEATURE_CORECLR
}
}
#endif // #ifndef DACCESS_COMPILE
@@ -1753,14 +1634,6 @@ void InvokeUtil::CanAccessField(RefSecContext* pCtx,
InvokeUtil::CheckAccessField(pCtx, pTargetMT, pInstanceMT, pTargetField);
-#ifndef FEATURE_CORECLR
- // Reflection invocation should turn critical method access into a full demand of full trust
- // for level 2 assemblies.
- if (InvokeUtil::IsCriticalWithConversionToFullDemand(pTargetField, pInstanceMT))
- {
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_FULL_TRUST);
- }
-#endif //FEATURE_CORECLR
}
//
@@ -2009,7 +1882,6 @@ AccessCheckOptions::AccessCheckType InvokeUtil::GetInvocationAccessCheckType(BOO
AppDomain * pAppDomain = GetAppDomain();
-#ifdef FEATURE_CORECLR
if (pAppDomain->GetSecurityDescriptor()->IsFullyTrusted())
// Ignore transparency so that reflection invocation is consistenct with LCG.
@@ -2018,14 +1890,6 @@ AccessCheckOptions::AccessCheckType InvokeUtil::GetInvocationAccessCheckType(BOO
return AccessCheckOptions::kMemberAccess;
-#else // !FEATURE_CORECLR
- return
- AppX::IsAppXProcess() ?
- (Security::AllDomainsOnStackFullyTrusted() ?
- AccessCheckOptions::kUserCodeOnlyRestrictedMemberAccessNoTransparency :
- AccessCheckOptions::kUserCodeOnlyRestrictedMemberAccess) :
- AccessCheckOptions::kRestrictedMemberAccess;
-#endif //FEATURE_CORECLR
}
#endif // CROSSGEN_COMPILE
@@ -2064,12 +1928,6 @@ bool InvokeUtil::IsDangerousMethod(MethodDesc *pMD)
{
// All methods on these types are considered dangerous
static const BinderClassID dangerousTypes[] = {
-#ifdef FEATURE_METHOD_RENTAL
- CLASS__METHOD_RENTAL,
-#endif // FEATURE_METHOD_RENTAL
-#ifdef FEATURE_ISOSTORE
- CLASS__ISS_STORE_FILE,
-#endif
CLASS__TYPE_HANDLE,
CLASS__METHOD_HANDLE,
CLASS__FIELD_HANDLE,
diff --git a/src/vm/invokeutil.h b/src/vm/invokeutil.h
index b991674cec..06aac9aaa3 100644
--- a/src/vm/invokeutil.h
+++ b/src/vm/invokeutil.h
@@ -55,9 +55,6 @@ public:
: m_fCheckedCaller(false),
m_fCheckedPerm(false),
m_fCallerHasPerm(false),
-#ifdef FEATURE_REMOTING
- m_fSkippingRemoting(false),
-#endif
m_pCaller(NULL),
m_pCallerDomain(NULL),
m_accessCheckType(accessCheckType)
@@ -91,9 +88,6 @@ private:
bool m_fCheckedPerm;
bool m_fCallerHasPerm;
-#ifdef FEATURE_REMOTING
- bool m_fSkippingRemoting;
-#endif
// @review GENERICS:
// These method descriptors may be shared between compatible instantiations
@@ -271,10 +265,6 @@ public:
if (pTargetMT == NULL)
return FALSE;
-#ifdef FEATURE_REMOTING
- if (pTargetMT->IsTransparentProxy())
- return TRUE;
-#endif
return FALSE;
}
diff --git a/src/vm/jithelpers.cpp b/src/vm/jithelpers.cpp
index 7b9389d5b6..aaab58963b 100644
--- a/src/vm/jithelpers.cpp
+++ b/src/vm/jithelpers.cpp
@@ -34,9 +34,6 @@
#include "process.h"
#endif // !FEATURE_PAL
-#ifdef FEATURE_REMOTING
-#include "remoting.h" // create context bound and remote class instances
-#endif
#include "perfcounters.h"
#ifdef PROFILING_SUPPORTED
#include "proftoeeinterfaceimpl.h"
@@ -50,7 +47,6 @@
#include "genericdict.h"
#include "array.h"
#include "debuginfostore.h"
-#include "constrainedexecutionregion.h"
#include "security.h"
#include "safemath.h"
#include "threadstatics.h"
@@ -63,9 +59,7 @@
#include "gccover.h"
#endif // HAVE_GCCOVER
-#ifdef FEATURE_CORECLR
#include "runtimehandles.h"
-#endif
//========================================================================
//
@@ -460,7 +454,7 @@ HCIMPL2_VV(UINT64, JIT_ULMod, UINT64 dividend, UINT64 divisor)
}
HCIMPLEND
-#if !defined(_WIN64) && !defined(_TARGET_X86_)
+#if !defined(BIT64) && !defined(_TARGET_X86_)
/*********************************************************************/
HCIMPL2_VV(UINT64, JIT_LLsh, UINT64 num, int shift)
{
@@ -484,8 +478,7 @@ HCIMPL2_VV(UINT64, JIT_LRsz, UINT64 num, int shift)
return num >> shift;
}
HCIMPLEND
-
-#endif
+#endif // !BIT64 && !_TARGET_X86_
#include <optdefault.h>
@@ -785,14 +778,6 @@ HCIMPL2(void*, JIT_GetFieldAddr_Framed, Object *obj, FieldDesc* pFD)
if (objRef == NULL)
COMPlusThrow(kNullReferenceException);
-#ifdef FEATURE_REMOTING
- if(objRef->IsTransparentProxy())
- {
- objRef = CRemotingServices::GetObjectFromProxy(objRef);
- if (objRef->IsTransparentProxy())
- COMPlusThrow(kInvalidOperationException, W("Remoting_InvalidValueTypeFieldAccess"));
- }
-#endif // FEATURE_REMOTING
fldAddr = pFD->GetAddress(OBJECTREFToObject(objRef));
@@ -1183,17 +1168,6 @@ HCIMPL4(VOID, JIT_GetFieldStruct_Framed, LPVOID retBuff, Object *obj, FieldDesc
// the server object.
BOOL fRemoted = FALSE;
-#ifdef FEATURE_REMOTING
- if (objRef->IsTransparentProxy())
- {
- objRef = CRemotingServices::GetObjectFromProxy(objRef);
- if (objRef->IsTransparentProxy())
- {
- CRemotingServices::FieldAccessor(pFD, objRef, retBuff, TRUE);
- fRemoted = TRUE;
- }
- }
-#endif
if (!fRemoted)
{
@@ -1248,18 +1222,6 @@ HCIMPL4(VOID, JIT_SetFieldStruct_Framed, Object *obj, FieldDesc *pFD, MethodTabl
// the server object.
BOOL fRemoted = FALSE;
-#ifdef FEATURE_REMOTING
- if(objRef->IsTransparentProxy())
- {
- objRef = CRemotingServices::GetObjectFromProxy(objRef);
-
- if(objRef->IsTransparentProxy())
- {
- CRemotingServices::FieldAccessor(pFD, objRef, valuePtr, FALSE);
- fRemoted = TRUE;
- }
- }
-#endif
if (!fRemoted)
{
@@ -1298,68 +1260,7 @@ HCIMPLEND
//
//========================================================================
-#ifdef FEATURE_MIXEDMODE
-HCIMPL1(void*, JIT_GetStaticFieldAddr_Tls, FieldDesc *pFD)
-{
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(pFD));
- PRECONDITION(pFD->IsStatic());
- PRECONDITION(pFD->IsRVA() && pFD->GetModule()->IsRvaFieldTls(pFD->GetOffset()));
- } CONTRACTL_END;
-
- void *addr = NULL;
-
- HELPER_METHOD_FRAME_BEGIN_RET_0();
-
- Module* pModule = pFD->GetModule();
-
- // Get the ThreadLocalStoragePointer in the TEB.
- LPVOID pTlsPtr = ClrTeb::GetLegacyThreadLocalStoragePointer();
-
- // pTlsPtr is pointing at an array of pointers, each of which points to
- // the TLS block of a dll. So here, we need to get the TLS index for
- // the dll, add that to pTlsPtr, and dereference it to get the TLS
- // block of the dll.
- DWORD tlsIndex = pModule->GetTlsIndex();
- LPVOID pDllTlsBase = (LPVOID)*((UINT_PTR*)pTlsPtr + tlsIndex);
-
- // Finally, we need to find the field offset into the TLS block.
- addr = (LPVOID)((PBYTE)pDllTlsBase + pModule->GetFieldTlsOffset(pFD->GetOffset()));
-
- HELPER_METHOD_FRAME_END();
-
- return addr;
-}
-HCIMPLEND
-#endif // FEATURE_MIXEDMODE
-
-#ifdef FEATURE_REMOTING
-HCIMPL1(void*, JIT_GetStaticFieldAddr_Context, FieldDesc *pFD)
-{
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(pFD));
- PRECONDITION(pFD->IsStatic());
- PRECONDITION(pFD->IsContextStatic());
- } CONTRACTL_END;
-
- void *addr = NULL;
-
- HELPER_METHOD_FRAME_BEGIN_RET_0();
-
- MethodTable *pMT = pFD->GetEnclosingMethodTable();
- pMT->CheckRestore();
- pMT->CheckRunClassInitThrowing();
-
- addr = Context::GetStaticFieldAddress(pFD);
-
- HELPER_METHOD_FRAME_END();
- return addr;
-}
-HCIMPLEND
-#endif
// Slow helper to tailcall from the fast one
NOINLINE HCIMPL1(void, JIT_InitClass_Framed, MethodTable* pMT)
@@ -2413,13 +2314,6 @@ BOOL ObjIsInstanceOf(Object *pObject, TypeHandle toTypeHnd, BOOL throwCastExcept
// If we are trying to cast a proxy we need to delegate to remoting
// services which will determine whether the proxy and the type are compatible.
-#ifdef FEATURE_REMOTING
- if (fromTypeHnd.IsTransparentProxy())
- {
- fCast = CRemotingServices::CheckCast(obj, toTypeHnd);
- }
- else
-#endif
// Start by doing a quick static cast check to see if the type information captured in
// the metadata indicates that the cast is legal.
if (fromTypeHnd.CanCastTo(toTypeHnd))
@@ -2858,7 +2752,7 @@ HCIMPL1(Object*, JIT_NewS_MP_FastPortable, CORINFO_CLASS_HANDLE typeHnd_)
do
{
- _ASSERTE(GCHeapUtilities::UseAllocationContexts());
+ _ASSERTE(GCHeapUtilities::UseThreadAllocationContexts());
// This is typically the only call in the fast path. Making the call early seems to be better, as it allows the compiler
// to use volatile registers for intermediate values. This reduces the number of push/pop instructions and eliminates
@@ -2931,53 +2825,6 @@ HCIMPL1(Object*, JIT_New, CORINFO_CLASS_HANDLE typeHnd_)
}
HCIMPLEND
-#ifdef FEATURE_REMOTING
-/*************************************************************/
-HCIMPL1(Object*, JIT_NewCrossContext_Portable, CORINFO_CLASS_HANDLE typeHnd_)
-{
- FCALL_CONTRACT;
-
- OBJECTREF newobj = NULL;
- HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame
-
- TypeHandle typeHnd(typeHnd_);
-
- _ASSERTE(!typeHnd.IsTypeDesc()); // we never use this helper for arrays
- MethodTable *pMT = typeHnd.AsMethodTable();
-
- // Don't bother to restore the method table; assume that the prestub of the
- // constructor will do that check.
-
-#ifdef _DEBUG
- if (g_pConfig->FastGCStressLevel()) {
- GetThread()->DisableStressHeap();
- }
-#endif // _DEBUG
-
- if (CRemotingServices::RequiresManagedActivation(typeHnd))
- {
- if (pMT->IsComObjectType())
- {
- newobj = AllocateObject(pMT);
- }
- else
- {
- // Remoting services determines if the current context is appropriate
- // for activation. If the current context is OK then it creates an object
- // else it creates a proxy.
- newobj = CRemotingServices::CreateProxyOrObject(pMT);
- }
- }
- else
- {
- newobj = AllocateObject(pMT);
- }
-
- HELPER_METHOD_FRAME_END();
- return(OBJECTREFToObject(newobj));
-}
-HCIMPLEND
-#endif // FEATURE_REMOTING
//========================================================================
@@ -2997,7 +2844,7 @@ HCIMPL1(StringObject*, AllocateString_MP_FastPortable, DWORD stringLength)
do
{
- _ASSERTE(GCHeapUtilities::UseAllocationContexts());
+ _ASSERTE(GCHeapUtilities::UseThreadAllocationContexts());
// Instead of doing elaborate overflow checks, we just limit the number of elements. This will avoid all overflow
// problems, as well as making sure big string objects are correctly allocated in the big object heap.
@@ -3161,7 +3008,7 @@ HCIMPL2(Object*, JIT_NewArr1VC_MP_FastPortable, CORINFO_CLASS_HANDLE arrayTypeHn
do
{
- _ASSERTE(GCHeapUtilities::UseAllocationContexts());
+ _ASSERTE(GCHeapUtilities::UseThreadAllocationContexts());
// Do a conservative check here. This is to avoid overflow while doing the calculations. We don't
// have to worry about "large" objects, since the allocation quantum is never big enough for
@@ -3238,7 +3085,7 @@ HCIMPL2(Object*, JIT_NewArr1OBJ_MP_FastPortable, CORINFO_CLASS_HANDLE arrayTypeH
do
{
- _ASSERTE(GCHeapUtilities::UseAllocationContexts());
+ _ASSERTE(GCHeapUtilities::UseThreadAllocationContexts());
// Make sure that the total size cannot reach LARGE_OBJECT_SIZE, which also allows us to avoid overflow checks. The
// "256" slack is to cover the array header size and round-up, using a constant value here out of laziness.
@@ -5415,7 +5262,6 @@ HCIMPL1(void, IL_Throw, Object* obj)
EEPolicy::HandleOutOfMemory();
}
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
// If the flag indicating ForeignExceptionRaise has been set,
// then do not clear the "_stackTrace" field of the exception object.
if (GetThread()->GetExceptionState()->IsRaisingForeignException())
@@ -5423,7 +5269,6 @@ HCIMPL1(void, IL_Throw, Object* obj)
((EXCEPTIONREF)oref)->SetStackTraceString(NULL);
}
else
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
{
((EXCEPTIONREF)oref)->ClearStackTracePreservingRemoteStackTrace();
}
@@ -5830,13 +5675,11 @@ HCIMPL2(void, JIT_DelegateSecurityCheck, CORINFO_CLASS_HANDLE delegateHnd, CORIN
{
FCALL_CONTRACT;
-#ifdef FEATURE_CORECLR
// If we're in full trust, then we don't enforce the delegate binding rules
if (GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted())
{
return;
}
-#endif // FEATURE_CORECLR
// Tailcall to the real implementation
ENDFORBIDGC();
@@ -6043,9 +5886,6 @@ NOINLINE HCIMPL2(void, JIT_Security_Prolog_Framed, CORINFO_METHOD_HANDLE methHnd
if ((pCurrent->IsInterceptedForDeclSecurity() &&
!(pCurrent->IsInterceptedForDeclSecurityCASDemandsOnly() &&
SecurityStackWalk::HasFlagsOrFullyTrusted(0)))
-#ifdef FEATURE_COMPRESSEDSTACK
- || SecurityStackWalk::MethodIsAnonymouslyHostedDynamicMethodWithCSToEvaluate(pCurrent)
-#endif //FEATURE_COMPRESSEDSTACK
)
{
MethodSecurityDescriptor MDSecDesc(pCurrent);
@@ -6107,16 +5947,9 @@ NOINLINE HCIMPL1(void, JIT_VerificationRuntimeCheck_Internal, CORINFO_METHOD_HAN
HELPER_METHOD_FRAME_BEGIN_NOPOLL();
{
-#ifdef FEATURE_CORECLR
// Transparent methods that contains unverifiable code is not allowed.
MethodDesc *pMethod = GetMethod(methHnd_);
SecurityTransparent::ThrowMethodAccessException(pMethod);
-#else // FEATURE_CORECLR
- //
- // inject a full-demand for unmanaged code permission at runtime
- // around methods in transparent assembly that contains unverifiable code
- Security::SpecialDemand(SSWT_DECLARATIVE_DEMAND, SECURITY_UNMANAGED_CODE);
-#endif // FEATURE_CORECLR
}
HELPER_METHOD_FRAME_END_POLL();
}
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index 5afb89bd4b..338c274014 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -32,9 +32,6 @@
#include "jitperf.h" // to track jit perf
#include "corprof.h"
#include "eeprofinterfaces.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h" // create context bound and remote class instances
-#endif
#include "perfcounters.h"
#ifdef PROFILING_SUPPORTED
#include "proftoeeinterfaceimpl.h"
@@ -51,7 +48,6 @@
#include "genericdict.h"
#include "array.h"
#include "debuginfostore.h"
-#include "constrainedexecutionregion.h"
#include "security.h"
#include "safemath.h"
#include "runtimehandles.h"
@@ -112,8 +108,6 @@ GARY_IMPL(VMHELPDEF, hlpDynamicFuncTable, DYNAMIC_CORINFO_HELP_COUNT);
LARGE_INTEGER g_lastTimeInJitCompilation;
#endif
-BOOL canReplaceMethodOnStack(MethodDesc* pReplaced, MethodDesc* pDeclaredReplacer, MethodDesc* pExactReplacer);
-
/*********************************************************************/
inline CORINFO_MODULE_HANDLE GetScopeHandle(MethodDesc* method)
@@ -162,24 +156,16 @@ BOOL ModifyCheckForDynamicMethod(DynamicResolver *pResolver,
{
*pAccessCheckType = AccessCheckOptions::kRestrictedMemberAccess;
-#ifdef FEATURE_CORECLR
// For compatibility, don't do transparency checks from dynamic methods in FT CoreCLR.
if (GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted())
*pAccessCheckType = AccessCheckOptions::kRestrictedMemberAccessNoTransparency;
-#endif // FEATURE_CORECLR
-#ifdef FEATURE_COMPRESSEDSTACK
- if (dwSecurityFlags & DynamicResolver::HasCreationContext)
- *ppAccessContext = pResolver;
-#endif // FEATURE_COMPRESSEDSTACK
}
else
{
-#ifdef FEATURE_CORECLR
// For compatibility, don't do transparency checks from dynamic methods in FT CoreCLR.
if (GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted())
*pAccessCheckType = AccessCheckOptions::kNormalAccessNoTransparency;
-#endif // FEATURE_CORECLR
}
return doAccessCheck;
@@ -539,14 +525,12 @@ CEEInfo::ConvToJitSig(
IfFailThrow(sig.GetCallingConvInfo(&data));
sigRet->callConv = (CorInfoCallConv) data;
-#if defined(FEATURE_CORECLR)
if ((isCallConv(sigRet->callConv, IMAGE_CEE_CS_CALLCONV_VARARG)) ||
(isCallConv(sigRet->callConv, IMAGE_CEE_CS_CALLCONV_NATIVEVARARG)))
{
// This signature corresponds to a method that uses varargs, which are not supported.
COMPlusThrow(kInvalidProgramException, IDS_EE_VARARG_NOT_SUPPORTED);
}
-#endif // FEATURE_CORECLR
// Skip number of type arguments
if (sigRet->callConv & IMAGE_CEE_CS_CALLCONV_GENERIC)
@@ -738,11 +722,31 @@ BOOL CEEInfo::shouldEnforceCallvirtRestriction(
// If the need arises (i.e. performance issues) we will define sets of assemblies (e.g. all app assemblies)
// The main point is that all this logic is concentrated in one place.
+// NOTICE: If you change this logic to allow multi-assembly version bubbles you
+// need to consider the impact on diagnostic tools. Currently there is an inlining
+// table which tracks inliner/inlinee relationships in R2R images but it is not
+// yet capable of encoding cross-assembly inlines. The scenario where this
+// may show are instrumenting profilers that want to instrument a given method A
+// using the ReJit APIs. If method A happens to inlined within method B in another
+// assembly then the profiler needs to know that so it can rejit B too.
+// The recommended approach is to upgrade the inlining table (vm\inlinetracking.h\.cpp)
+// now that presumably R2R images have some way to refer to methods in other
+// assemblies in their version bubble. Chat with the diagnostics team if you need more
+// details.
+//
+// There already is a case where cross-assembly inlining occurs in an
+// unreported fashion for methods marked NonVersionable. There is a specific
+// exemption called out for this on ICorProfilerInfo6::EnumNgenModuleMethodsInliningThisMethod
+// and the impact of the cut was vetted with partners. It would not be appropriate
+// to increase that unreported set without additional review.
+
+
bool IsInSameVersionBubble(Assembly * current, Assembly * target)
{
LIMITED_METHOD_CONTRACT;
// trivial case: current and target are identical
+ // DO NOT change this without reading the notice above
if (current == target)
return true;
@@ -753,6 +757,7 @@ bool IsInSameVersionBubble(Assembly * current, Assembly * target)
static bool IsInSameVersionBubble(MethodDesc* pCurMD, MethodDesc *pTargetMD)
{
LIMITED_METHOD_CONTRACT;
+ // DO NOT change this without reading the notice above
if (IsInSameVersionBubble(pCurMD->GetModule()->GetAssembly(),
pTargetMD->GetModule()->GetAssembly()))
{
@@ -1434,6 +1439,11 @@ static CORINFO_FIELD_ACCESSOR getFieldIntrinsic(FieldDesc * field)
{
return CORINFO_FIELD_INTRINSIC_ZERO;
}
+ else
+ if (MscorlibBinder::GetField(FIELD__BITCONVERTER__ISLITTLEENDIAN) == field)
+ {
+ return CORINFO_FIELD_INTRINSIC_ISLITTLEENDIAN;
+ }
return (CORINFO_FIELD_ACCESSOR)-1;
}
@@ -1720,36 +1730,6 @@ void CEEInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken,
}
else
#endif // CHECK_APP_DOMAIN_LEAKS
-#ifdef FEATURE_REMOTING
- // are we a contextful class? (approxMT is OK to use here)
- if (pFieldMT->IsContextful())
- {
- // Allow the JIT to optimize special cases
-
- // If the caller is states that we have a 'this reference'
- // and he is also willing to unwrap it himself
- // then we won't require a helper call.
- if (!(flags & CORINFO_ACCESS_THIS ) ||
- !(flags & CORINFO_ACCESS_UNWRAP))
- {
- // Normally a helper call is required.
- fInstanceHelper = TRUE;
- }
- }
- // are we a marshaled by ref class? (approxMT is OK to use here)
- else if (pFieldMT->IsMarshaledByRef())
- {
- // Allow the JIT to optimize special cases
-
- // If the caller is states that we have a 'this reference'
- // then we won't require a helper call.
- if (!(flags & CORINFO_ACCESS_THIS))
- {
- // Normally a helper call is required.
- fInstanceHelper = TRUE;
- }
- }
-#endif // FEATURE_REMOTING
if (fInstanceHelper)
{
@@ -2468,15 +2448,28 @@ bool CEEInfo::getSystemVAmd64PassStructInRegisterDescriptor(
}
_ASSERTE(methodTablePtr != nullptr);
+ // If we have full support for FEATURE_UNIX_AMD64_STRUCT_PASSING, and not just the interface,
+ // then we've cached whether this is a reg passed struct in the MethodTable, computed during
+ // MethodTable construction. Otherwise, we are just building in the interface, and we haven't
+ // computed or cached anything, so we need to compute it now.
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
bool canPassInRegisters = useNativeLayout ? methodTablePtr->GetLayoutInfo()->IsNativeStructPassedInRegisters()
- : methodTablePtr->IsRegPassedStruct();
+ : methodTablePtr->IsRegPassedStruct();
+#else // !defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+ SystemVStructRegisterPassingHelper helper((unsigned int)th.GetSize());
+ bool canPassInRegisters = methodTablePtr->ClassifyEightBytes(&helper, 0, 0, useNativeLayout);
+#endif // !defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+
if (canPassInRegisters)
{
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
SystemVStructRegisterPassingHelper helper((unsigned int)th.GetSize());
bool result = methodTablePtr->ClassifyEightBytes(&helper, 0, 0, useNativeLayout);
// The answer must be true at this point.
_ASSERTE(result);
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+
structPassInRegDescPtr->passedInRegisters = true;
structPassInRegDescPtr->eightByteCount = helper.eightByteCount;
@@ -5094,29 +5087,6 @@ void CEEInfo::getCallInfo(
}
-#ifdef FEATURE_CER
- if (pMD == g_pPrepareConstrainedRegionsMethod && !isVerifyOnly())
- {
- MethodDesc * methodFromContext = GetMethodFromContext(pResolvedToken->tokenContext);
-
- if (methodFromContext != NULL && methodFromContext->IsIL())
- {
- SigTypeContext typeContext;
- GetTypeContext(pResolvedToken->tokenContext, &typeContext);
-
- // If the method whose context we're in is attempting a call to PrepareConstrainedRegions() then we've found the root
- // method in a Constrained Execution Region (CER). Prepare the call graph of the critical parts of that method now so
- // they won't fail because of us at runtime.
- MethodCallGraphPreparer mcgp(methodFromContext, &typeContext, false, false);
- bool fMethodHasCallsWithinExplicitCer = mcgp.Run();
- if (! g_pConfig->ProbeForStackOverflow() || ! fMethodHasCallsWithinExplicitCer)
- {
- // if the method does not contain any CERs that call out, we can optimize the probe away
- pMD = MscorlibBinder::GetMethod(METHOD__RUNTIME_HELPERS__PREPARE_CONSTRAINED_REGIONS_NOOP);
- }
- }
- }
-#endif // FEATURE_CER
TypeHandle exactType = TypeHandle(pResolvedToken->hClass);
@@ -5590,11 +5560,9 @@ void CEEInfo::getCallInfo(
//This just throws.
if (pCalleeForSecurity->RequiresLinktimeCheck())
{
-#ifdef FEATURE_CORECLR
//hostProtectionAttribute(HPA) can be removed for coreclr mscorlib.dll
//So if the call to LinktimeCheckMethod() is only b'coz of HPA then skip it
if (!pCalleeForSecurity->RequiresLinkTimeCheckHostProtectionOnly())
-#endif
Security::LinktimeCheckMethod(pCallerForSecurity->GetAssembly(), pCalleeForSecurity);
}
@@ -5632,11 +5600,7 @@ void CEEInfo::getCallInfo(
pCalleeForSecurity,
NULL,
accessCheckOptions,
-#ifdef FEATURE_CORECLR
FALSE,
-#else
- TRUE,
-#endif //FEATURE_CORECLR
TRUE
);
@@ -5693,7 +5657,6 @@ void CEEInfo::getCallInfo(
{
BOOL fNeedsTransparencyCheck = TRUE;
-#ifdef FEATURE_CORECLR
// All LCG methods are transparent in CoreCLR. When we switch from PT
// to FT most user assemblies will become opportunistically critical.
// If a LCG method calls a method in such an assembly it will stop working.
@@ -5706,7 +5669,6 @@ void CEEInfo::getCallInfo(
// See also AccessCheckOptions::DemandMemberAccess.
if (GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted() && pCallerForSecurity->IsLCGMethod())
fNeedsTransparencyCheck = FALSE;
-#endif // FEATURE_CORECLR
if (fNeedsTransparencyCheck)
{
@@ -5820,9 +5782,7 @@ BOOL CEEInfo::canAccessFamily(CORINFO_METHOD_HANDLE hCaller,
doCheck = ModifyCheckForDynamicMethod(GetMethod(hCaller)->AsDynamicMethodDesc()->GetResolver(),
&accessingType, &accessCheckOptions, &pIgnored);
if (accessCheckOptions == AccessCheckOptions::kRestrictedMemberAccess
-#ifdef FEATURE_CORECLR
|| accessCheckOptions == AccessCheckOptions::kRestrictedMemberAccessNoTransparency
-#endif //FEATURE_CORECLR
)
doCheck = FALSE;
}
@@ -6032,21 +5992,10 @@ CorInfoHelpFunc CEEInfo::getNewHelperStatic(MethodTable * pMT)
{
STANDARD_VM_CONTRACT;
-#ifdef FEATURE_REMOTING
- if (pMT->MayRequireManagedActivation())
- {
- return CORINFO_HELP_NEW_CROSSCONTEXT;
- }
-#endif
// Slow helper is the default
CorInfoHelpFunc helper = CORINFO_HELP_NEWFAST;
-#ifdef FEATURE_REMOTING
- // We shouldn't get here with a COM object (they're all potentially
- // remotable, so they're covered by the case above).
- _ASSERTE(!pMT->IsComObjectType() || pMT->IsWinRTObjectType());
-#endif
if (pMT->IsComObjectType())
{
@@ -6389,7 +6338,7 @@ bool CEEInfo::getReadyToRunHelper(
void CEEInfo::getReadyToRunDelegateCtorHelper(
CORINFO_RESOLVED_TOKEN * pTargetMethod,
CORINFO_CLASS_HANDLE delegateType,
- CORINFO_CONST_LOOKUP * pLookup
+ CORINFO_LOOKUP * pLookup
)
{
LIMITED_METHOD_CONTRACT;
@@ -6664,12 +6613,6 @@ DWORD CEEInfo::getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftn)
if (pMD->IsLCGMethod())
{
#ifndef CROSSGEN_COMPILE
-#ifdef FEATURE_COMPRESSEDSTACK
- if(SecurityStackWalk::MethodIsAnonymouslyHostedDynamicMethodWithCSToEvaluate(pMD))
- {
- return CORINFO_FLG_STATIC | CORINFO_FLG_DONT_INLINE | CORINFO_FLG_SECURITYCHECK;
- }
-#endif // FEATURE_COMPRESSEDSTACK
#endif // !CROSSGEN_COMPILE
return CORINFO_FLG_STATIC | CORINFO_FLG_DONT_INLINE | CORINFO_FLG_NOSECURITYWRAP;
@@ -6734,39 +6677,27 @@ DWORD CEEInfo::getMethodAttribsInternal (CORINFO_METHOD_HANDLE ftn)
result |= CORINFO_FLG_NOSECURITYWRAP;
}
+ if (IsMdRequireSecObject(attribs))
+ {
+ // Assume all methods marked as DynamicSecurity are
+ // marked that way because they use StackCrawlMark to identify
+ // the caller.
+ // See comments in canInline or canTailCall
+ result |= CORINFO_FLG_DONT_INLINE_CALLER;
+ }
// Check for an inlining directive.
if (pMD->IsNotInline())
{
/* Function marked as not inlineable */
result |= CORINFO_FLG_DONT_INLINE;
-
- if (pMD->IsIL() && (IsMdRequireSecObject(attribs) ||
- (pMD->GetModule()->IsSystem() && IsMiNoInlining(pMD->GetImplAttrs()))))
- {
- // Assume all methods marked as NoInline inside mscorlib are
- // marked that way because they use StackCrawlMark to identify
- // the caller (not just the security info).
- // See comments in canInline or canTailCall
- result |= CORINFO_FLG_DONT_INLINE_CALLER;
- }
}
-
// AggressiveInlining only makes sense for IL methods.
else if (pMD->IsIL() && IsMiAggressiveInlining(pMD->GetImplAttrs()))
{
result |= CORINFO_FLG_FORCEINLINE;
}
-
- if (!pMD->IsRuntimeSupplied())
- {
- if (IsMdRequireSecObject(attribs))
- {
- result |= CORINFO_FLG_SECURITYCHECK;
- }
- }
-
if (pMT->IsDelegate() && ((DelegateEEClass*)(pMT->GetClass()))->m_pInvokeMethod == pMD)
{
// This is now used to emit efficient invoke code for any delegate invoke,
@@ -6990,7 +6921,6 @@ bool getILIntrinsicImplementation(MethodDesc * ftn,
return true;
}
}
-#ifdef FEATURE_SPAN_OF_T
else if (tk == MscorlibBinder::GetMethod(METHOD__JIT_HELPERS__BYREF_LESSTHAN)->GetMemberDef())
{
// Compare the two arguments
@@ -7022,39 +6952,10 @@ bool getILIntrinsicImplementation(MethodDesc * ftn,
methInfo->options = (CorInfoOptions)0;
return true;
}
- else if (tk == MscorlibBinder::GetMethod(METHOD__JIT_HELPERS__CONTAINSREFERENCES)->GetMemberDef())
- {
- _ASSERTE(ftn->HasMethodInstantiation());
- Instantiation inst = ftn->GetMethodInstantiation();
-
- _ASSERTE(ftn->GetNumGenericMethodArgs() == 1);
- TypeHandle typeHandle = inst[0];
- MethodTable * methodTable = typeHandle.GetMethodTable();
-
- static const BYTE returnTrue[] = { CEE_LDC_I4_1, CEE_RET };
- static const BYTE returnFalse[] = { CEE_LDC_I4_0, CEE_RET };
-
- if (!methodTable->IsValueType() || methodTable->ContainsPointers())
- {
- methInfo->ILCode = const_cast<BYTE*>(returnTrue);
- }
- else
- {
- methInfo->ILCode = const_cast<BYTE*>(returnFalse);
- }
-
- methInfo->ILCodeSize = sizeof(returnTrue);
- methInfo->maxStack = 1;
- methInfo->EHcount = 0;
- methInfo->options = (CorInfoOptions)0;
- return true;
- }
-#endif // FEATURE_SPAN_OF_T
return false;
}
-#ifdef FEATURE_SPAN_OF_T
bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn,
CORINFO_METHOD_INFO * methInfo)
{
@@ -7133,6 +7034,17 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn,
methInfo->options = (CorInfoOptions)0;
return true;
}
+ else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_ADD_BYTE_OFFSET)->GetMemberDef())
+ {
+ static BYTE ilcode[] = { CEE_LDARG_0, CEE_LDARG_1, CEE_ADD, CEE_RET };
+
+ methInfo->ILCode = const_cast<BYTE*>(ilcode);
+ methInfo->ILCodeSize = sizeof(ilcode);
+ methInfo->maxStack = 2;
+ methInfo->EHcount = 0;
+ methInfo->options = (CorInfoOptions)0;
+ return true;
+ }
else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_ARE_SAME)->GetMemberDef())
{
// Compare the two arguments
@@ -7154,10 +7066,56 @@ bool getILIntrinsicImplementationForUnsafe(MethodDesc * ftn,
methInfo->options = (CorInfoOptions)0;
return true;
}
+ else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_READ_UNALIGNED)->GetMemberDef() ||
+ tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__PTR_READ_UNALIGNED)->GetMemberDef())
+ {
+ _ASSERTE(ftn->HasMethodInstantiation());
+ Instantiation inst = ftn->GetMethodInstantiation();
+ _ASSERTE(ftn->GetNumGenericMethodArgs() == 1);
+ mdToken tokGenericArg = FindGenericMethodArgTypeSpec(MscorlibBinder::GetModule()->GetMDImport());
+
+ static const BYTE ilcode[]
+ {
+ CEE_LDARG_0,
+ CEE_PREFIX1, (CEE_UNALIGNED & 0xFF), 1,
+ CEE_LDOBJ, (BYTE)(tokGenericArg), (BYTE)(tokGenericArg >> 8), (BYTE)(tokGenericArg >> 16), (BYTE)(tokGenericArg >> 24),
+ CEE_RET
+ };
+
+ methInfo->ILCode = const_cast<BYTE*>(ilcode);
+ methInfo->ILCodeSize = sizeof(ilcode);
+ methInfo->maxStack = 2;
+ methInfo->EHcount = 0;
+ methInfo->options = (CorInfoOptions)0;
+ return true;
+ }
+ else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_WRITE_UNALIGNED)->GetMemberDef() ||
+ tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__PTR_WRITE_UNALIGNED)->GetMemberDef())
+ {
+ _ASSERTE(ftn->HasMethodInstantiation());
+ Instantiation inst = ftn->GetMethodInstantiation();
+ _ASSERTE(ftn->GetNumGenericMethodArgs() == 1);
+ mdToken tokGenericArg = FindGenericMethodArgTypeSpec(MscorlibBinder::GetModule()->GetMDImport());
+
+ static const BYTE ilcode[]
+ {
+ CEE_LDARG_0,
+ CEE_LDARG_1,
+ CEE_PREFIX1, (CEE_UNALIGNED & 0xFF), 1,
+ CEE_STOBJ, (BYTE)(tokGenericArg), (BYTE)(tokGenericArg >> 8), (BYTE)(tokGenericArg >> 16), (BYTE)(tokGenericArg >> 24),
+ CEE_RET
+ };
+
+ methInfo->ILCode = const_cast<BYTE*>(ilcode);
+ methInfo->ILCodeSize = sizeof(ilcode);
+ methInfo->maxStack = 2;
+ methInfo->EHcount = 0;
+ methInfo->options = (CorInfoOptions)0;
+ return true;
+ }
return false;
}
-#endif // FEATURE_SPAN_OF_T
bool getILIntrinsicImplementationForVolatile(MethodDesc * ftn,
CORINFO_METHOD_INFO * methInfo)
@@ -7302,6 +7260,47 @@ bool getILIntrinsicImplementationForInterlocked(MethodDesc * ftn,
return true;
}
+bool getILIntrinsicImplementationForRuntimeHelpers(MethodDesc * ftn,
+ CORINFO_METHOD_INFO * methInfo)
+{
+ STANDARD_VM_CONTRACT;
+
+ // Precondition: ftn is a method in mscorlib
+ _ASSERTE(ftn->GetModule()->IsSystem());
+
+ mdMethodDef tk = ftn->GetMemberDef();
+
+ if (tk == MscorlibBinder::GetMethod(METHOD__RUNTIME_HELPERS__IS_REFERENCE_OR_CONTAINS_REFERENCES)->GetMemberDef())
+ {
+ _ASSERTE(ftn->HasMethodInstantiation());
+ Instantiation inst = ftn->GetMethodInstantiation();
+
+ _ASSERTE(ftn->GetNumGenericMethodArgs() == 1);
+ TypeHandle typeHandle = inst[0];
+ MethodTable * methodTable = typeHandle.GetMethodTable();
+
+ static const BYTE returnTrue[] = { CEE_LDC_I4_1, CEE_RET };
+ static const BYTE returnFalse[] = { CEE_LDC_I4_0, CEE_RET };
+
+ if (!methodTable->IsValueType() || methodTable->ContainsPointers())
+ {
+ methInfo->ILCode = const_cast<BYTE*>(returnTrue);
+ }
+ else
+ {
+ methInfo->ILCode = const_cast<BYTE*>(returnFalse);
+ }
+
+ methInfo->ILCodeSize = sizeof(returnTrue);
+ methInfo->maxStack = 1;
+ methInfo->EHcount = 0;
+ methInfo->options = (CorInfoOptions)0;
+ return true;
+ }
+
+ return false;
+}
+
//---------------------------------------------------------------------------------------
//
//static
@@ -7339,12 +7338,10 @@ getMethodInfoHelper(
{
fILIntrinsic = getILIntrinsicImplementation(ftn, methInfo);
}
-#ifdef FEATURE_SPAN_OF_T
else if (MscorlibBinder::IsClass(pMT, CLASS__UNSAFE))
{
fILIntrinsic = getILIntrinsicImplementationForUnsafe(ftn, methInfo);
}
-#endif
else if (MscorlibBinder::IsClass(pMT, CLASS__INTERLOCKED))
{
fILIntrinsic = getILIntrinsicImplementationForInterlocked(ftn, methInfo);
@@ -7353,6 +7350,10 @@ getMethodInfoHelper(
{
fILIntrinsic = getILIntrinsicImplementationForVolatile(ftn, methInfo);
}
+ else if (MscorlibBinder::IsClass(pMT, CLASS__RUNTIME_HELPERS))
+ {
+ fILIntrinsic = getILIntrinsicImplementationForRuntimeHelpers(ftn, methInfo);
+ }
if (!fILIntrinsic)
{
@@ -7641,28 +7642,6 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller,
_ASSERTE(!(CORINFO_FLG_DONT_INLINE & getMethodAttribsInternal(hCallee)));
#endif
- // Returns TRUE: if caller and callee are from the same assembly or the callee
- // is part of the system assembly.
- //
- // If the caller and callee have the same Critical state and the same Grant (and refuse) sets, then the
- // callee may always be inlined into the caller.
- //
- // If they differ, then the callee is marked as INLINE_RESPECT_BOUNDARY. The Jit may only inline the
- // callee when any of the following are true.
- // 1) the callee is a leaf method.
- // 2) the callee does not call any Boundary Methods.
- //
- // Conceptually, a Boundary method is a method that needs to accurately find the permissions of its
- // caller. Boundary methods are:
- //
- // 1) A method that calls anything that creates a StackCrawlMark to look for its caller. In this code
- // this is approximated as "in mscorlib and is marked as NoInlining".
- // 2) A method that calls a method which calls Demand. These methods must be marked as
- // IsMdRequireSecObject.
- // 3) Calls anything that is virtual. This is because the virtual method could be #1 or #2.
- //
- // In CoreCLR, all public Critical methods of mscorlib are considered Boundary Method
-
MethodDesc* pCaller = GetMethod(hCaller);
MethodDesc* pCallee = GetMethod(hCallee);
@@ -7726,7 +7705,7 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller,
if (IsMdRequireSecObject(pCallee->GetAttrs()))
{
result = INLINE_NEVER;
- szFailReason = "Inlinee requires a security object (calls Demand/Assert/Deny)";
+ szFailReason = "Inlinee requires a security object (or contains StackCrawlMark)";
goto exit;
}
@@ -7757,7 +7736,7 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller,
#ifdef _DEBUG
//
- // Make sure that all methods with StackCrawlMark are marked as non-inlineable
+ // Make sure that all methods with StackCrawlMark are marked as IsMdRequireSecObject
//
if (pCalleeAssembly->IsSystem())
{
@@ -7800,11 +7779,6 @@ CorInfoInline CEEInfo::canInline (CORINFO_METHOD_HANDLE hCaller,
}
#endif // FEATURE_PREJIT
- if (!canReplaceMethodOnStack(pCallee, NULL, pCaller))
- {
- dwRestrictions |= INLINE_RESPECT_BOUNDARY;
- }
-
// TODO: We can probably be smarter here if the caller is jitted, as we will
// know for sure if the inlinee has really no string interning active (currently
// it's only on in the ngen case (besides requiring the attribute)), but this is getting
@@ -8183,159 +8157,6 @@ CorInfoInstantiationVerification
return result;
}
-// This function returns true if we can replace pReplaced on the stack with
-// pReplacer. In the case of inlining this means that pReplaced is the inlinee
-// and pReplacer is the inliner. In the case of tail calling, pReplacer is the
-// tail callee and pReplaced is the tail caller.
-//
-// It's possible for pReplacer to be NULL. This means that it's an unresolved
-// callvirt for a tail call. This is legal, but we make the static decision
-// based on pReplaced only (assuming that pReplacer is from a different
-// assembly that is a different partial trust).
-//
-// The general logic is this:
-// 1) You can replace anything that is full trust (since full trust doesn't
-// cause a demand to fail).
-// 2) You can coalesce all stack frames that have the same permission set
-// down to a single stack frame.
-//
-// You'll see three patterns in the code below:
-// 1) There is only one permission set per assembly
-// 2) Comparing grant sets is prohibitively expensive. Therefore we use the
-// the fact that, "a homogenous app domain has only one partial trust
-// permission set" to infer that two grant sets are equal.
-// 3) Refuse sets are rarely used and too complex to handle correctly, so
-// they generally just torpedo all of the logic in here.
-//
-BOOL canReplaceMethodOnStack(MethodDesc* pReplaced, MethodDesc* pDeclaredReplacer, MethodDesc* pExactReplacer)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_PREEMPTIVE; //Called from PREEMPTIVE functions
- } CONTRACTL_END;
-
- OBJECTREF refused = NULL;
- Assembly * pReplacedAssembly = pReplaced->GetAssembly();
-
- _ASSERTE(Security::IsResolved(pReplacedAssembly));
-
- // The goal of this code is to ensure that we never allow a unique non-full
- // trust grant set to be eliminated from the stack.
-
- Assembly * pReplacerAssembly = NULL;
- if (pExactReplacer != NULL)
- {
- pReplacerAssembly = pExactReplacer->GetAssembly();
- _ASSERTE(Security::IsResolved(pReplacerAssembly));
-
- // If two methods are from the same assembly, they must have the same grant set.
- if (pReplacerAssembly == pReplacedAssembly)
- {
- // When both methods are in the same assembly, then it is always safe to
- // coalesce them for the purposes of security.
- return TRUE;
- }
- }
-
- if ( pDeclaredReplacer != NULL &&
- pReplacedAssembly->GetDomainAssembly() == GetAppDomain()->GetAnonymouslyHostedDynamicMethodsAssembly() &&
- SystemDomain::IsReflectionInvocationMethod(pDeclaredReplacer) )
- {
- // When an anonymously hosted dynamic method invokes a method through reflection invocation,
- // the dynamic method is the true caller. If we replace it on the stack we would be doing
- // security check against its caller rather than the dynamic method itself.
- // We should do this check against pDeclaredReplacer rather than pExactReplacer because the
- // latter is NULL is the former if virtual, e.g. MethodInfo.Invoke(...).
- return FALSE;
- }
-
- // It is always safe to remove a full trust stack frame from the stack.
- IAssemblySecurityDescriptor * pReplacedDesc = pReplacedAssembly->GetSecurityDescriptor();
-
-#ifdef FEATURE_APTCA
- if (GetAppDomain()->IsCompilationDomain())
- {
- // If we're NGENing assemblies, we don't want to inline code out of a conditionally APTCA assembly,
- // since we need to ensure that the dependency is loaded and checked to ensure that it is condtional
- // APTCA. We only need to do this if the replaced caller is transparent, since a critical caller
- // will be allowed to use the conditional APTCA disabled assembly anyway.
- if (pReplacedAssembly != pReplacerAssembly && Security::IsMethodTransparent(pReplaced))
- {
- ModuleSecurityDescriptor *pReplacedMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pReplacedAssembly);
- if (pReplacedMSD->GetTokenFlags() & TokenSecurityDescriptorFlags_ConditionalAPTCA)
- {
- return FALSE;
- }
- }
- }
-#endif // FEATURE_APTCA
-
- if (pReplacedDesc->IsFullyTrusted())
- {
- GCX_COOP(); // Required for GetGrantedPermissionSet
- (void)pReplacedDesc->GetGrantedPermissionSet(&refused);
- if (refused != NULL)
- {
- // This is full trust with a Refused set. That means that it is partial
- // trust. However, even in a homogeneous app domain, it could be a
- // different partial trust from any other partial trust, and since
- // pExactReplacer is either unknown or from a different assembly, we assume
- // the worst: that is is a different partial trust.
- return FALSE;
- }
- return TRUE;
- }
-
- // pReplaced is partial trust and pExactReplacer is either unknown or from a
- // different assembly than pReplaced.
-
- if (pExactReplacer == NULL)
- {
- // This is the unresolved callvirt case. Since we're partial trust,
- // we can't tail call.
- return FALSE;
- }
-
- // We're replacing a partial trust stack frame. We can only do this with a
- // matching grant set. We know pReplaced is partial trust. Make sure both
- // pExactReplacer and pReplaced are the same partial trust.
- IAssemblySecurityDescriptor * pReplacerDesc = pReplacerAssembly->GetSecurityDescriptor();
- if (pReplacerDesc->IsFullyTrusted())
- {
- return FALSE; // Replacing partial trust with full trust.
- }
-
- // At this point both pExactReplacer and pReplaced are partial trust. We can
- // only do this if the grant sets are equal. Since comparing grant sets
- // requires calling up into managed code, we will infer that the two grant
- // sets are equal if the domain is homogeneous.
- IApplicationSecurityDescriptor * adSec = GetAppDomain()->GetSecurityDescriptor();
- if (adSec->IsHomogeneous())
- {
- // We're homogeneous, but the two descriptors could have refused sets.
- // Bail if they do.
- GCX_COOP(); // Required for GetGrantedPermissionSet
- (void)pReplacedDesc->GetGrantedPermissionSet(&refused);
- if (refused != NULL)
- {
- return FALSE;
- }
-
- (void)pReplacerDesc->GetGrantedPermissionSet(&refused);
- if (refused != NULL)
- return FALSE;
-
- return TRUE;
- }
-
- // pExactReplacer and pReplaced are from 2 different assemblies. Both are partial
- // trust, and the app domain is not homogeneous, so we just have to
- // assume that they have different grant or refuse sets, and thus cannot
- // safely be replaced.
- return FALSE;
-}
-
/*************************************************************
* Similar to above, but perform check for tail call
* eligibility. The callee can be passed as NULL if not known
@@ -8392,16 +8213,6 @@ bool CEEInfo::canTailCall (CORINFO_METHOD_HANDLE hCaller,
goto exit;
}
- // The jit already checks and doesn't allow the tail caller to use imperative security.
- _ASSERTE(pCaller->IsRuntimeSupplied() || !IsMdRequireSecObject(pCaller->GetAttrs()));
-
- if (!canReplaceMethodOnStack(pCaller, pDeclaredCallee, pExactCallee))
- {
- result = false;
- szFailReason = "Different security";
- goto exit;
- }
-
if (!fIsTailPrefix)
{
mdMethodDef callerToken = pCaller->GetMemberDef();
@@ -8433,37 +8244,18 @@ bool CEEInfo::canTailCall (CORINFO_METHOD_HANDLE hCaller,
// Methods with StackCrawlMark depend on finding their caller on the stack.
// If we tail call one of these guys, they get confused. For lack of
- // a better way of identifying them, we look for methods marked as NoInlining
- // inside mscorlib (StackCrawlMark is private), and assume it is one of these
- // methods. We have an assert in canInline that ensures all StackCrawlMark
+ // a better way of identifying them, we use DynamicSecurity attribute to identify
+ // them. We have an assert in canInline that ensures all StackCrawlMark
// methods are appropriately marked.
//
- // NOTE that this is *NOT* a security issue because we check to ensure that
- // the callee has the *SAME* security properties as the caller, it just might
- // be from a different assembly which messes up APIs like Type.GetType, which
- // for back-compat uses the assembly of it's caller to resolve unqualified
- // typenames.
- if ((pExactCallee != NULL) && pExactCallee->GetModule()->IsSystem() && pExactCallee->IsIL())
+ if ((pExactCallee != NULL) && IsMdRequireSecObject(pExactCallee->GetAttrs()))
{
- if (IsMiNoInlining(pExactCallee->GetImplAttrs()))
- {
- result = false;
- szFailReason = "Callee might have a StackCrawlMark.LookForMyCaller";
- goto exit;
- }
+ result = false;
+ szFailReason = "Callee might have a StackCrawlMark.LookForMyCaller";
+ goto exit;
}
}
-#ifdef FEATURE_CER
- // We cannot tail call from a root CER method, the thread abort algorithm to
- // detect CERs depends on seeing such methods on the stack.
- if (IsCerRootMethod(pCaller))
- {
- result = false;
- szFailReason = "Caller is a CER root";
- goto exit;
- }
-#endif // FEATURE_CER
result = true;
@@ -8922,6 +8714,163 @@ void CEEInfo::getMethodVTableOffset (CORINFO_METHOD_HANDLE methodHnd,
}
/*********************************************************************/
+CORINFO_METHOD_HANDLE CEEInfo::resolveVirtualMethodHelper(CORINFO_METHOD_HANDLE baseMethod,
+ CORINFO_CLASS_HANDLE derivedClass,
+ CORINFO_CONTEXT_HANDLE ownerType)
+{
+ CONTRACTL {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ } CONTRACTL_END;
+
+ MethodDesc* pBaseMD = GetMethod(baseMethod);
+ MethodTable* pBaseMT = pBaseMD->GetMethodTable();
+
+ // Method better be from a fully loaded class
+ _ASSERTE(pBaseMD->IsRestored() && pBaseMT->IsFullyLoaded());
+
+ //@GENERICS: shouldn't be doing this for instantiated methods as they live elsewhere
+ _ASSERTE(!pBaseMD->HasMethodInstantiation());
+
+ // Method better be virtual
+ _ASSERTE(pBaseMD->IsVirtual());
+
+ MethodDesc* pDevirtMD = nullptr;
+
+ TypeHandle DerivedClsHnd(derivedClass);
+ MethodTable* pDerivedMT = DerivedClsHnd.GetMethodTable();
+ _ASSERTE(pDerivedMT->IsRestored() && pDerivedMT->IsFullyLoaded());
+
+ // Can't devirtualize from __Canon.
+ if (DerivedClsHnd == TypeHandle(g_pCanonMethodTableClass))
+ {
+ return nullptr;
+ }
+
+ if (pBaseMT->IsInterface())
+ {
+
+#ifdef FEATURE_COMINTEROP
+ // Don't try and devirtualize com interface calls.
+ if (pDerivedMT->IsComObjectType())
+ {
+ return nullptr;
+ }
+#endif // FEATURE_COMINTEROP
+
+ // Interface call devirtualization.
+ //
+ // We must ensure that pDerivedMT actually implements the
+ // interface corresponding to pBaseMD.
+ if (!pDerivedMT->CanCastToInterface(pBaseMT))
+ {
+ return nullptr;
+ }
+
+ // For generic interface methods we must have an ownerType to
+ // safely devirtualize.
+ if (ownerType != nullptr)
+ {
+ TypeHandle OwnerClsHnd = GetTypeFromContext(ownerType);
+ MethodTable* pOwnerMT = OwnerClsHnd.GetMethodTable();
+
+ // If the derived class is a shared class, make sure the
+ // owner class is too.
+ if (pDerivedMT->IsSharedByGenericInstantiations())
+ {
+ pOwnerMT = pOwnerMT->GetCanonicalMethodTable();
+ }
+
+ pDevirtMD = pDerivedMT->GetMethodDescForInterfaceMethod(TypeHandle(pOwnerMT), pBaseMD);
+ }
+ else if (!pBaseMD->HasClassOrMethodInstantiation())
+ {
+ pDevirtMD = pDerivedMT->GetMethodDescForInterfaceMethod(pBaseMD);
+ }
+ else
+ {
+ return nullptr;
+ }
+ }
+ else
+ {
+ // Virtual call devirtualization.
+ //
+ // The derived class should be a subclass of the the base class.
+ MethodTable* pCheckMT = pDerivedMT;
+
+ while (pCheckMT != nullptr)
+ {
+ if (pCheckMT->HasSameTypeDefAs(pBaseMT))
+ {
+ break;
+ }
+
+ pCheckMT = pCheckMT->GetParentMethodTable();
+ }
+
+ if (pCheckMT == nullptr)
+ {
+ return nullptr;
+ }
+
+ // The base method should be in the base vtable
+ WORD slot = pBaseMD->GetSlot();
+ _ASSERTE(slot < pBaseMT->GetNumVirtuals());
+
+ // Fetch the method that would be invoked if the class were
+ // exactly derived class. It is up to the jit to determine whether
+ // directly calling this method is correct.
+ pDevirtMD = pDerivedMT->GetMethodDescForSlot(slot);
+ }
+
+ _ASSERTE(pDevirtMD->IsRestored());
+
+#ifdef FEATURE_READYTORUN_COMPILER
+ // Check if devirtualization is dependent upon cross-version
+ // bubble information and if so, disallow it.
+ if (IsReadyToRunCompilation())
+ {
+ MethodDesc* callerMethod = m_pMethodBeingCompiled;
+ Assembly* pCallerAssembly = callerMethod->GetModule()->GetAssembly();
+ bool allowDevirt =
+ IsInSameVersionBubble(pCallerAssembly , pDevirtMD->GetModule()->GetAssembly())
+ && IsInSameVersionBubble(pCallerAssembly , pDerivedMT->GetAssembly());
+
+ if (!allowDevirt)
+ {
+ return nullptr;
+ }
+ }
+#endif
+
+ return (CORINFO_METHOD_HANDLE) pDevirtMD;
+}
+
+CORINFO_METHOD_HANDLE CEEInfo::resolveVirtualMethod(CORINFO_METHOD_HANDLE methodHnd,
+ CORINFO_CLASS_HANDLE derivedClass,
+ CORINFO_CONTEXT_HANDLE ownerType)
+{
+ CONTRACTL {
+ SO_TOLERANT;
+ THROWS;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ } CONTRACTL_END;
+
+ CORINFO_METHOD_HANDLE result = nullptr;
+
+ JIT_TO_EE_TRANSITION();
+
+ result = resolveVirtualMethodHelper(methodHnd, derivedClass, ownerType);
+
+ EE_TO_JIT_TRANSITION();
+
+ return result;
+}
+
+/*********************************************************************/
void CEEInfo::getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftnHnd,
CORINFO_CONST_LOOKUP * pResult,
CORINFO_ACCESS_FLAGS accessFlags)
@@ -9821,27 +9770,6 @@ void* CEEInfo::getPInvokeUnmanagedTarget(CORINFO_METHOD_HANDLE method,
if (pMD->NDirectTargetIsImportThunk())
{
-#ifdef FEATURE_MIXEDMODE // IJW
- if (pMD->IsEarlyBound()
-#ifdef FEATURE_MULTICOREJIT
- // Bug 126723: Calling ClassInit in multicore JIT background thread, return NULL
- // When multicore JIT is enabled (StartProfile called), calling managed code is not allowed in the background thread
- && GetAppDomain()->GetMulticoreJitManager().AllowCCtorsToRunDuringJITing()
-#endif
- )
- {
- EX_TRY
- {
- pMD->InitEarlyBoundNDirectTarget();
- _ASSERTE(!pMD->NDirectTargetIsImportThunk());
- result = pMD->GetNDirectTarget();
- }
- EX_CATCH
- {
- }
- EX_END_CATCH(SwallowAllExceptions)
- }
-#endif // FEATURE_MIXEDMODE
}
else
{
@@ -9986,21 +9914,14 @@ void CEEInfo::getEEInfo(CORINFO_EE_INFO *pEEInfoOut)
pEEInfoOut->osPageSize = OS_PAGE_SIZE;
pEEInfoOut->maxUncheckedOffsetForNullObject = MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT;
-#if defined(FEATURE_CORECLR)
pEEInfoOut->targetAbi = CORINFO_CORECLR_ABI;
-#else
- pEEInfoOut->targetAbi = CORINFO_DESKTOP_ABI;
-#endif
-
- OSVERSIONINFO sVerInfo;
- sVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetOSVersion(&sVerInfo);
pEEInfoOut->osType = CORINFO_WINNT;
- pEEInfoOut->osMajor = sVerInfo.dwMajorVersion;
- pEEInfoOut->osMinor = sVerInfo.dwMinorVersion;
- pEEInfoOut->osBuild = sVerInfo.dwBuildNumber;
+ // hardcode OS version to 0.0.0. These fields can be removed from JITEE interface
+ pEEInfoOut->osMajor = 0;
+ pEEInfoOut->osMinor = 0;
+ pEEInfoOut->osBuild = 0;
EE_TO_JIT_TRANSITION();
}
@@ -10682,14 +10603,6 @@ BOOL CEEInfo::logMsg(unsigned level, const char* fmt, va_list args)
void CEEInfo::yieldExecution()
{
WRAPPER_NO_CONTRACT;
- // DDR: 17066 - Performance degrade
- // The JIT should not give up it's time slice when we are not hosted
- if (CLRTaskHosted())
- {
- // SwitchToTask forces the current thread to give up quantum, while a host can decide what
- // to do with Sleep if the current thread has not run out of quantum yet.
- ClrSleepEx(0, FALSE);
- }
}
@@ -12005,10 +11918,6 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
CorJitResult ret = CORJIT_SKIPPED; // Note that CORJIT_SKIPPED is an error exit status code
-#if !defined(FEATURE_CORECLR)
- // Ask the JIT to generate desktop-quirk-compatible code.
- jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DESKTOP_QUIRKS);
-#endif
comp->setJitFlags(jitFlags);
@@ -12020,14 +11929,6 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
BEGIN_SO_TOLERANT_CODE(GetThread());
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- ret = getJit()->compileMethod( comp,
- info,
- CORJIT_FLAGS::CORJIT_FLAG_CALL_GETJITFLAGS,
- nativeEntry,
- nativeSizeOfCode);
-
-#else // defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
#if defined(ALLOW_SXS_JIT) && !defined(CROSSGEN_COMPILE)
if (FAILED(ret) && jitMgr->m_alternateJit
@@ -12125,7 +12026,6 @@ CorJitResult invokeCompileMethodHelper(EEJitManager *jitMgr,
}
#endif // !defined(CROSSGEN_COMPILE)
-#endif // defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
#if defined(FEATURE_GDBJIT)
if (SUCCEEDED(ret) && *nativeEntry != NULL)
@@ -12332,12 +12232,10 @@ CORJIT_FLAGS GetDebuggerCompileFlags(Module* pModule, CORJIT_FLAGS flags)
{
STANDARD_VM_CONTRACT;
-#ifdef FEATURE_CORECLR
//Right now if we don't have a debug interface on CoreCLR, we can't generate debug info. So, in those
//cases don't attempt it.
if (!g_pDebugInterface)
return flags;
-#endif //FEATURE_CORECLR
#ifdef DEBUGGING_SUPPORTED
diff --git a/src/vm/jitinterface.h b/src/vm/jitinterface.h
index df9e1d764c..d287248d24 100644
--- a/src/vm/jitinterface.h
+++ b/src/vm/jitinterface.h
@@ -317,6 +317,7 @@ private:
PBYTE m_pWriteWatchTableImmediate; // PREGROW | POSTGROW | SVR | WRITE_WATCH |
PBYTE m_pLowerBoundImmediate; // PREGROW | POSTGROW | | WRITE_WATCH |
PBYTE m_pCardTableImmediate; // PREGROW | POSTGROW | SVR | WRITE_WATCH |
+ PBYTE m_pCardBundleTableImmediate; // PREGROW | POSTGROW | SVR | WRITE_WATCH |
PBYTE m_pUpperBoundImmediate; // | POSTGROW | | WRITE_WATCH |
};
@@ -343,20 +344,23 @@ EXTERN_C FCDECL1_V(INT32, JIT_Dbl2IntOvf, double val);
EXTERN_C FCDECL2_VV(float, JIT_FltRem, float dividend, float divisor);
EXTERN_C FCDECL2_VV(double, JIT_DblRem, double dividend, double divisor);
-#if !defined(_WIN64) && !defined(_TARGET_X86_)
+#ifndef BIT64
+#ifdef _TARGET_X86_
+// JIThelp.asm
+EXTERN_C void STDCALL JIT_LLsh();
+EXTERN_C void STDCALL JIT_LRsh();
+EXTERN_C void STDCALL JIT_LRsz();
+#else // _TARGET_X86_
EXTERN_C FCDECL2_VV(UINT64, JIT_LLsh, UINT64 num, int shift);
EXTERN_C FCDECL2_VV(INT64, JIT_LRsh, INT64 num, int shift);
EXTERN_C FCDECL2_VV(UINT64, JIT_LRsz, UINT64 num, int shift);
-#endif
+#endif // !_TARGET_X86_
+#endif // !BIT64
#ifdef _TARGET_X86_
extern "C"
{
- void STDCALL JIT_LLsh(); // JIThelp.asm
- void STDCALL JIT_LRsh(); // JIThelp.asm
- void STDCALL JIT_LRsz(); // JIThelp.asm
-
void STDCALL JIT_CheckedWriteBarrierEAX(); // JIThelp.asm/JIThelp.s
void STDCALL JIT_CheckedWriteBarrierEBX(); // JIThelp.asm/JIThelp.s
void STDCALL JIT_CheckedWriteBarrierECX(); // JIThelp.asm/JIThelp.s
@@ -378,11 +382,11 @@ extern "C"
void STDCALL JIT_WriteBarrierEDI(); // JIThelp.asm/JIThelp.s
void STDCALL JIT_WriteBarrierEBP(); // JIThelp.asm/JIThelp.s
- void STDCALL JIT_WriteBarrierStart();
- void STDCALL JIT_WriteBarrierLast();
+ void STDCALL JIT_WriteBarrierGroup();
+ void STDCALL JIT_WriteBarrierGroup_End();
- void STDCALL JIT_PatchedWriteBarrierStart();
- void STDCALL JIT_PatchedWriteBarrierLast();
+ void STDCALL JIT_PatchedWriteBarrierGroup();
+ void STDCALL JIT_PatchedWriteBarrierGroup_End();
}
void ValidateWriteBarrierHelpers();
@@ -413,59 +417,11 @@ extern "C"
void STDCALL JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle);
};
-#ifndef FEATURE_CORECLR
-//
-// Obfluscators that are hacking into the JIT expect certain methods to exist in certain places of CEEInfo vtable. Add artifical slots
-// to the vtable to avoid breaking apps by .NET 4.5 in-place update.
-//
-
-class ICorMethodInfo_Hack
-{
-public:
- virtual const char* __stdcall ICorMethodInfo_Hack_getMethodName (CORINFO_METHOD_HANDLE ftnHnd, const char** scopeName) = 0;
-};
-
-class ICorModuleInfo_Hack
-{
-public:
- virtual void ICorModuleInfo_Hack_dummy() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
-};
-
-class ICorClassInfo_Hack
-{
-public:
- virtual void ICorClassInfo_Hack_dummy1() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy2() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy3() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy4() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy5() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy6() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy7() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy8() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy9() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy10() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy11() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy12() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy13() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
- virtual void ICorClassInfo_Hack_dummy14() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
-
- virtual mdMethodDef __stdcall ICorClassInfo_Hack_getMethodDefFromMethod(CORINFO_METHOD_HANDLE hMethod) = 0;
-};
-
-class ICorStaticInfo_Hack : public virtual ICorMethodInfo_Hack, public virtual ICorModuleInfo_Hack, public virtual ICorClassInfo_Hack
-{
- virtual void ICorStaticInfo_Hack_dummy() { LIMITED_METHOD_CONTRACT; UNREACHABLE(); };
-};
-
-#endif // FEATURE_CORECLR
/*********************************************************************/
/*********************************************************************/
class CEEInfo : public ICorJitInfo
-#ifndef FEATURE_CORECLR
- , public virtual ICorStaticInfo_Hack
-#endif
{
friend class CEEDynamicCodeInfo;
@@ -564,7 +520,7 @@ public:
void getReadyToRunDelegateCtorHelper(
CORINFO_RESOLVED_TOKEN * pTargetMethod,
CORINFO_CLASS_HANDLE delegateType,
- CORINFO_CONST_LOOKUP * pLookup
+ CORINFO_LOOKUP * pLookup
);
CorInfoInitClassResult initClass(
@@ -773,6 +729,18 @@ public:
unsigned * pOffsetAfterIndirection
);
+ CORINFO_METHOD_HANDLE resolveVirtualMethod(
+ CORINFO_METHOD_HANDLE virtualMethod,
+ CORINFO_CLASS_HANDLE implementingClass,
+ CORINFO_CONTEXT_HANDLE ownerType
+ );
+
+ CORINFO_METHOD_HANDLE resolveVirtualMethodHelper(
+ CORINFO_METHOD_HANDLE virtualMethod,
+ CORINFO_CLASS_HANDLE implementingClass,
+ CORINFO_CONTEXT_HANDLE ownerType
+ );
+
CorInfoIntrinsics getIntrinsicID(CORINFO_METHOD_HANDLE method,
bool * pMustExpand = NULL);
diff --git a/src/vm/jitinterfacegen.cpp b/src/vm/jitinterfacegen.cpp
index f8a95bb759..ce4c1e90e3 100644
--- a/src/vm/jitinterfacegen.cpp
+++ b/src/vm/jitinterfacegen.cpp
@@ -20,9 +20,6 @@
#include "eeconfig.h"
#include "excep.h"
#include "comdelegate.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h" // create context bound and remote class instances
-#endif
#include "field.h"
#include "ecall.h"
@@ -221,7 +218,7 @@ void InitJITHelpers1()
))
{
// if (multi-proc || server GC)
- if (GCHeapUtilities::UseAllocationContexts())
+ if (GCHeapUtilities::UseThreadAllocationContexts())
{
#ifdef FEATURE_IMPLICIT_TLS
SetJitHelperFunction(CORINFO_HELP_NEWSFAST, JIT_NewS_MP_FastPortable);
diff --git a/src/vm/marshalnative.cpp b/src/vm/marshalnative.cpp
index 5f05fa2daf..7e1d63b7c1 100644
--- a/src/vm/marshalnative.cpp
+++ b/src/vm/marshalnative.cpp
@@ -34,9 +34,6 @@
#include "marshalnative.h"
#include "fcall.h"
#include "dllimportcallback.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "comdelegate.h"
#include "handletablepriv.h"
#include "mdaassistants.h"
@@ -186,11 +183,13 @@ FCIMPL3(VOID, MarshalNative::PtrToStructureHelper, LPVOID ptr, Object* pObjIn, C
CONTRACTL_END;
OBJECTREF pObj = ObjectToOBJECTREF(pObjIn);
+
+ HELPER_METHOD_FRAME_BEGIN_1(pObj);
if (ptr == NULL)
- FCThrowArgumentNullVoid(W("ptr"));
+ COMPlusThrowArgumentNull(W("ptr"));
if (pObj == NULL)
- FCThrowArgumentNullVoid(W("structure"));
+ COMPlusThrowArgumentNull(W("structure"));
// Code path will accept regular layout objects.
MethodTable *pMT = pObj->GetMethodTable();
@@ -198,7 +197,7 @@ FCIMPL3(VOID, MarshalNative::PtrToStructureHelper, LPVOID ptr, Object* pObjIn, C
// Validate that the object passed in is not a value class.
if (!allowValueClasses && pMT->IsValueType())
{
- FCThrowArgumentVoid(W("structure"), W("Argument_StructMustNotBeValueClass"));
+ COMPlusThrowArgumentException(W("structure"), W("Argument_StructMustNotBeValueClass"));
}
else if (pMT->IsBlittable())
{
@@ -206,14 +205,14 @@ FCIMPL3(VOID, MarshalNative::PtrToStructureHelper, LPVOID ptr, Object* pObjIn, C
}
else if (pMT->HasLayout())
{
- HELPER_METHOD_FRAME_BEGIN_1(pObj);
- LayoutUpdateCLR((LPVOID*) &(pObj), Object::GetOffsetOfFirstField(), pMT, (LPBYTE)(ptr));
- HELPER_METHOD_FRAME_END();
+ LayoutUpdateCLR((LPVOID*) &(pObj), Object::GetOffsetOfFirstField(), pMT, (LPBYTE)(ptr));
}
else
{
- FCThrowArgumentVoid(W("structure"), W("Argument_MustHaveLayoutOrBeBlittable"));
- }
+ COMPlusThrowArgumentException(W("structure"), W("Argument_MustHaveLayoutOrBeBlittable"));
+ }
+
+ HELPER_METHOD_FRAME_END();
}
FCIMPLEND
@@ -446,29 +445,6 @@ FCIMPL3(LPVOID, MarshalNative::GetUnmanagedThunkForManagedMethodPtr, LPVOID pfnM
CONTRACTL_END;
LPVOID pThunk = NULL;
-#ifdef FEATURE_MIXEDMODE
- HELPER_METHOD_FRAME_BEGIN_RET_0();
-
- if (pfnMethodToWrap == NULL)
- COMPlusThrowArgumentNull(W("pfnMethodToWrap"));
- if (pbSignature == NULL)
- COMPlusThrowArgumentNull(W("pbSignature"));
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4996) // Suppress warning on call to deprecated method
-#endif
- Module *pModule = SystemDomain::GetCallersModule(1);
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
- PREFIX_ASSUME(pModule != NULL);
- pThunk = pModule->GetUMThunk(pfnMethodToWrap, pbSignature, cbSignature);
- if (!pThunk)
- COMPlusThrowOM();
-
- HELPER_METHOD_FRAME_END();
-#endif // FEATURE_MIXEDMODE
return pThunk;
}
FCIMPLEND
@@ -488,31 +464,6 @@ FCIMPL3(LPVOID, MarshalNative::GetManagedThunkForUnmanagedMethodPtr, LPVOID pfnM
CONTRACTL_END;
LPVOID pThunk = NULL;
-#ifdef FEATURE_MIXEDMODE
- HELPER_METHOD_FRAME_BEGIN_RET_0();
-
- if (pfnMethodToWrap == NULL)
- COMPlusThrowArgumentNull(W("pfnMethodToWrap"));
- if (pbSignature == NULL)
- COMPlusThrowArgumentNull(W("pbSignature"));
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4996) // Suppress warning on call to deprecated method
-#endif
- Module *pModule = SystemDomain::GetCallersModule(1);
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
- if (!pModule)
- ThrowOutOfMemory();
-
- pThunk = pModule->GetMUThunk(pfnMethodToWrap, pbSignature, cbSignature);
- if (!pThunk)
- ThrowOutOfMemory();
-
- HELPER_METHOD_FRAME_END();
-#endif // FEATURE_MIXEDMODE
return pThunk;
}
FCIMPLEND
@@ -1538,17 +1489,6 @@ FCIMPL2(Object*, MarshalNative::InternalCreateWrapperOfType, Object* objUNSAFE,
BOOL fSet = FALSE;
// Start by checking if we can cast the obj to the wrapper type.
-#ifdef FEATURE_REMOTING
- if (pObjMT->IsTransparentProxy())
- {
- if (CRemotingServices::CheckCast(gc.obj, pNewWrapMT))
- {
- gc.refRetVal = gc.obj;
- fSet = TRUE;
- }
- }
- else
-#endif
if (TypeHandle(pObjMT).CanCastTo(TypeHandle(pNewWrapMT)))
{
gc.refRetVal = gc.obj;
@@ -2333,9 +2273,6 @@ FCIMPL2(void, MarshalNative::ChangeWrapperHandleStrength, Object* orefUNSAFE, CL
COMPlusThrowArgumentNull(W("otp"));
if (
-#ifdef FEATURE_REMOTING
- CRemotingServices::IsTransparentProxy(OBJECTREFToObject(oref)) ||
-#endif
!oref->GetMethodTable()->IsComImport())
{
CCWHolder pWrap = ComCallWrapper::InlineGetWrapper(&oref);
diff --git a/src/vm/mda.cpp b/src/vm/mda.cpp
deleted file mode 100644
index 77c26a993e..0000000000
--- a/src/vm/mda.cpp
+++ /dev/null
@@ -1,4017 +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 "common.h"
-#include "eeconfig.h"
-#include "eeconfigfactory.h"
-#include "corhlpr.h"
-#include <xmlparser.h>
-#include <mscorcfg.h>
-#include <holder.h>
-#include <dbginterface.h>
-#include "wrappers.h"
-#include "mda.h"
-#include "mdaassistants.h"
-#include "sstring.h"
-#include "util.hpp"
-#include "debugdebugger.h"
-
-#ifdef MDA_SUPPORTED
-
-//
-// MdaHashtable
-//
-
-BOOL MdaLockOwner(LPVOID) { LIMITED_METHOD_CONTRACT; return TRUE; }
-
-BOOL IsJustMyCode(MethodDesc* pMethodDesc)
-{
- CONTRACT(BOOL)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACT_END;
-
- if (!ManagedDebuggingAssistants::IsManagedDebuggerAttached())
- return TRUE;
-
- BOOL bIsJMC = FALSE;
-
- EX_TRY
- {
- if (g_pDebugInterface && g_pDebugInterface->IsJMCMethod(pMethodDesc->GetModule(), pMethodDesc->GetMemberDef()))
- bIsJMC = TRUE;
- }
- EX_CATCH
- {
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- RETURN bIsJMC;
-}
-
-
-//
-// ManagedDebuggingAssistants
-//
-
-const bool g_mdaAssistantIsSwitch[] =
-{
-#define MDA_ASSISTANT_IS_SWITCH
-#include "mdaschema.inl"
-#undef MDA_ASSISTANT_IS_SWITCH
- false
-};
-
-void ManagedDebuggingAssistants::Initialize()
-{
- CONTRACT_VOID
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACT_END;
-
- EX_TRY
- {
- //
- // Initialize
- //
- m_pSwitchActivationXml = NULL;
- m_pMdaXmlIndustry = new MdaXmlIndustry();
-
- MdaSchema::Initialize();
-
- //
- // Create AssistantSchema
- //
- m_pAssistantSchema = new MdaAssistantSchema();
-
- //
- // Create AssistantMsgSchema
- //
- m_pAssistantMsgSchema = new MdaAssistantMsgSchema();
-
- //
- // Create SchemaSchema
- //
- m_pSchemaSchema = new MdaSchemaSchema();
-
- //
- // InvalidConfigFile
- //
- g_mdaStaticHeap.m_mdaInvalidConfigFile.Enable();
-
-#ifdef _DEBUG
- StackSString sszValidateFramework(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MDAValidateFramework));
- if (!sszValidateFramework.IsEmpty() && sszValidateFramework.Equals(W("1")))
- DebugInitialize();
-#endif
- }
- EX_CATCH
- {
- // MDA State corrupted, unable to initialize, runtime still OK
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- RETURN;
-}
-
-MdaEnvironment::~MdaEnvironment()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (m_pStringFactory)
- delete m_pStringFactory;
-
- if (m_pGroups)
- delete m_pGroups;
-
- if (m_szMda)
- delete m_szMda;
-}
-
-MdaEnvironment::MdaEnvironment()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- m_bDisable = TRUE;
- m_szMda = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_MDA);
- m_pStringFactory = NULL;
- m_pGroups = NULL;
-
- if (ManagedDebuggingAssistants::IsManagedDebuggerAttached())
- {
- if (m_pStringFactory == NULL)
- m_pStringFactory = new MdaFactory<StackSString>();
-
- if (m_pGroups == NULL)
- m_pGroups = new SArray<SString*>();
-
- SString* pStr = m_pStringFactory->Create();
- pStr->Set(W("managedDebugger"));
- m_pGroups->Append(pStr);
- m_bDisable = FALSE;
- }
-
- if (ManagedDebuggingAssistants::IsUnmanagedDebuggerAttached())
- {
- if (m_pStringFactory == NULL)
- m_pStringFactory = new MdaFactory<StackSString>();
-
- if (m_pGroups == NULL)
- m_pGroups = new SArray<SString*>();
-
- SString* pStr = m_pStringFactory->Create();
- pStr->Set(W("unmanagedDebugger"));
- m_pGroups->Append(pStr);
- m_bDisable = FALSE;
- }
-
- if (m_szMda)
- {
- if (m_pStringFactory == NULL)
- m_pStringFactory = new MdaFactory<StackSString>();
-
- if (m_pGroups == NULL)
- m_pGroups = new SArray<SString*>();
-
- StackSString sszMda(m_szMda);
- SString::Iterator s = sszMda.Begin();
- SString::Iterator e = s;
-
- while (true)
- {
- if (!sszMda.Find(e, W(';')))
- e = sszMda.End();
- SString* psszGroup = m_pStringFactory->Create();
- psszGroup->Set(sszMda, s, e);
-
- if (psszGroup->Equals(W("0")))
- {
- m_pGroups->Clear();
- m_bDisable = TRUE;
- }
- else
- {
- m_pGroups->Append(psszGroup);
-
- m_bDisable = FALSE;
- }
-
- if (e == sszMda.End())
- break;
- s = ++e;
- }
- }
-
- if (m_bDisable == FALSE)
- {
- // If we get here, m_pStringFactory should already have been created.
- _ASSERTE(m_pStringFactory != NULL);
-
- WCHAR szExe[_MAX_PATH];
- if (!WszGetModuleFileName(NULL, szExe, _MAX_PATH))
- return;
-
- // Construct file name of the config file
- m_psszConfigFile = m_pStringFactory->Create();
- m_psszConfigFile->Set(szExe);
- m_psszConfigFile->Append(W(".config"));
-
- // Construct file name of mda config file
- m_psszMdaConfigFile = m_pStringFactory->Create();
- m_psszMdaConfigFile->Set(szExe);
- m_psszMdaConfigFile->Append(W(".mda.config"));
- }
-}
-
-void ManagedDebuggingAssistants::EEStartupActivation()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- //
- // Read environment variable, then registry settings
- //
- MdaEnvironment env;
-
- if (env.IsDisabled())
- return;
-
- AllocateManagedDebuggingAssistants();
-
- //
- // ConfigFile Activation
- //
- g_mdaStaticHeap.m_pMda->EnvironmentActivation(&env);
-}
-
-#ifdef _DEBUG
-void ManagedDebuggingAssistants::DebugInitialize()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- SO_INTOLERANT;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- //
- // Validate MDA output on Debug builds
- //
- m_bValidateOutput = TRUE;
-
- //
- // XmlValidationError
- //
- g_mdaStaticHeap.m_mdaXmlValidationError.Enable();
-
- MdaSchema::ValidationResult validationResult;
-
- //
- // Validate SchemaScheam
- //
- MdaXmlElement* pXmlSchemaSchema = m_pSchemaSchema->ToXml(m_pMdaXmlIndustry);
- if (m_pSchemaSchema->Validate(pXmlSchemaSchema, &validationResult)->ValidationFailed())
- {
- MDA_TRIGGER_ASSISTANT(XmlValidationError, ReportError(&validationResult));
- UNREACHABLE();
- }
-
- //
- // Validate AssistantSchema
- //
- MdaXmlElement* pXmlAssistantSchema = m_pAssistantSchema->ToXml(m_pMdaXmlIndustry);
- if (m_pSchemaSchema->Validate(pXmlAssistantSchema, &validationResult)->ValidationFailed())
- {
- MDA_TRIGGER_ASSISTANT(XmlValidationError, ReportError(&validationResult));
- ASSERT(!W("You're modifications to MdaAssistantSchema for assistant input don't conform to XSD"));
- }
-
- //
- // Validate AssistantMsgSchema
- //
- MdaXmlElement* pXmlAssistantMsgSchema = m_pAssistantMsgSchema->ToXml(m_pMdaXmlIndustry);
- if (m_pSchemaSchema->Validate(pXmlAssistantMsgSchema, &validationResult)->ValidationFailed())
- {
- MDA_TRIGGER_ASSISTANT(XmlValidationError, ReportError(&validationResult));
- ASSERT(!W("You're modifications to MdaAssistantSchema for assistant output don't conform to XSD"));
- }
-}
-#endif
-
-void ManagedDebuggingAssistants::ConfigFileActivation(LPCWSTR szConfigFile, MdaXmlIndustry* pXmlIndustry, MdaHashtable<MdaXmlElement*>* pMdaXmlPairs)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // Parse
- MdaSchema::ValidationResult validationResult;
- MdaXmlElement* pMdaConfig = MdaConfigFactory::ParseXmlStream(pXmlIndustry, szConfigFile);
- if (!pMdaConfig)
- return;
-
- // Validate
- if (m_pAssistantSchema->Validate(pMdaConfig, &validationResult)->ValidationFailed())
- {
- MDA_TRIGGER_ASSISTANT(InvalidConfigFile, ReportError(MdaElemDef(MdaConfig)));
- g_mdaStaticHeap.DisableAll();
- return;
- }
-
- // Activate
- InlineSArray<MdaXmlElement*, MdaElemDef(Max)> xmlMdaConfigs;
- MdaXPath::FindElements(pMdaConfig, W("/mdaConfig/assistants/*"), &xmlMdaConfigs);
- for(COUNT_T i = 0; i < xmlMdaConfigs.GetCount(); i ++)
- {
- MdaXmlElement* pXmlMdaConfig = xmlMdaConfigs[i];
- if (pXmlMdaConfig->GetAttribute(MdaAttrDecl(Enable))->GetValueAsBool())
- {
- pMdaXmlPairs->Set(pXmlMdaConfig->GetName(), xmlMdaConfigs[i]);
- }
- else
- {
- if (pMdaXmlPairs->HasKey(pXmlMdaConfig->GetName()))
- pMdaXmlPairs->DeleteValue(pXmlMdaConfig->GetName());
- }
- }
-}
-
-MdaXmlElement* ManagedDebuggingAssistants::GetSwitchActivationXml(MdaElemDeclDef mda)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (g_mdaAssistantIsSwitch[mda])
- {
- MdaXmlElement* pXml = m_pMdaXmlIndustry->CreateElement()->SetDeclDef(mda);
- pXml->AddAttributeBool(MdaAttrDecl(Enable), TRUE);
- return pXml;
- }
- else
- {
- if (!m_pSwitchActivationXml)
- {
- MdaXmlElement* pXmlMdaConfig = m_pMdaXmlIndustry->CreateElement()->SetDeclDef(MdaElemDef(MdaConfig));
- m_pSwitchActivationXml = pXmlMdaConfig->AddChild(MdaElemDecl(Assistants));
-
- for (COUNT_T i = 0; i < MdaElemDef(AssistantMax); i ++)
- m_pSwitchActivationXml->AddChild((MdaElemDeclDef)i);
-
- MdaSchema::ValidationResult validationResult;
-
- // Validating the schema has the side-effect of initializing the default XML attributes
- if (m_pAssistantSchema->Validate(pXmlMdaConfig, &validationResult)->ValidationFailed())
- ASSERT(!W("MDA Assistant must allow <Assistant /> form."));
- }
-
- return m_pSwitchActivationXml->GetChild(mda);
- }
-}
-
-void ManagedDebuggingAssistants::ActivateGroup(LPCWSTR groupName, SArray<MdaElemDeclDef>* pGroupMdaXmlParis, MdaHashtable<MdaXmlElement*>* pActivationMdaXmlPairs)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString sszGroupName(groupName);
- BOOL bIsManagedDebuggerSet = sszGroupName.EqualsCaseInsensitive(W("managedDebugger"));
-
- SArray<MdaElemDeclDef>& groupMdaXmlParis = *pGroupMdaXmlParis;
-
- for (COUNT_T i = 0; i < groupMdaXmlParis.GetCount(); i++)
- {
- MdaElemDeclDef mda = groupMdaXmlParis[i];
- MdaXmlElement* pSwitchActivationXml = GetSwitchActivationXml(mda);
-
- PREFIX_ASSUME(pSwitchActivationXml != NULL);
-
- pSwitchActivationXml->AddAttributeBool(MdaAttrDecl(SuppressDialog), bIsManagedDebuggerSet);
-
- pActivationMdaXmlPairs->Set(MdaSchema::g_arElementNames[mda], pSwitchActivationXml);
- }
-}
-
-LPCWSTR ToLowerFirstChar(LPCWSTR name, MdaFactory<SString>* pSstringFactory)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- ASSERT(*name >= 'A' && *name <= 'Z');
-
- SString* pOutput = pSstringFactory->Create();
- pOutput->Clear();
- pOutput->Append(*name - W('A') + W('a'));
- pOutput->Append(&name[1]);
- return pOutput->GetUnicode();
-}
-
-void ManagedDebuggingAssistants::EnvironmentActivation(MdaEnvironment* pEnvironment)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (pEnvironment->GetActivationMechanisms().GetCount() == 0)
- return;
-
- MdaFactory<StackSArray<MdaElemDeclDef> > arrayFactory;
- MdaFactory<SString> sstringFactory;
- MdaHashtable<MdaXmlElement*> mdaXmlPairs;
-
- // Activate
- SArray<SString*>& aActivationMechanisms = pEnvironment->GetActivationMechanisms();
- SArray<MdaElemDeclDef>* pGroup = NULL;
- StackSArray<SArray<MdaElemDeclDef>* > aGroups;
-
-#define MDA_DEFINE_GROUPS
-#include "mdaschema.inl"
-#undef MDA_DEFINE_GROUPS
-
- // Match COMPlus_MDA env var to group
- for (COUNT_T i = 0; i < aActivationMechanisms.GetCount(); i++)
- {
- SString& sszActivationMechanism = *aActivationMechanisms[i];
-
- if (sszActivationMechanism.EqualsCaseInsensitive(W("ConfigFile")) || sszActivationMechanism.EqualsCaseInsensitive(W("1")))
- {
- ConfigFileActivation(pEnvironment->GetMdaConfigFile(), m_pMdaXmlIndustry, &mdaXmlPairs);
- }
- else
- {
- COUNT_T cGroup = 0;
-
-#define MDA_ACTIVATE_GROUPS
-#include "mdaschema.inl"
-#undef MDA_ACTIVATE_GROUPS
-
-#define MDA_ACTIVATE_SINGLTON_GROUPS
-#include "mdaschema.inl"
-#undef MDA_ACTIVATE_SINGLTON_GROUPS
-
- }
- }
-
- if (mdaXmlPairs.GetCount() == 0)
- return;
-
- // Create
- MdaXmlElement* pXmlAssistant = NULL;
-
-#define MDA_ASSISTANT_CREATION
-#include "mdaschema.inl"
-#undef MDA_ASSISTANT_CREATION
-}
-
-typedef enum
-{
- MDA_MSGBOX_NONE = 0,
- MDA_MSGBOX_RETRY = 4,
- MDA_MSGBOX_CANCLE = 2,
-} MsgBoxResult;
-
-BOOL ManagedDebuggingAssistants::IsUnmanagedDebuggerAttached()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (IsDebuggerPresent())
- return TRUE;
-
- return FALSE;
-}
-
-BOOL ManagedDebuggingAssistants::IsManagedDebuggerAttached()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
-#if DEBUGGING_SUPPORTED
- if (CORDebuggerAttached())
- return TRUE;
-#endif
-
- return FALSE;
-}
-
-BOOL ManagedDebuggingAssistants::IsDebuggerAttached()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return IsUnmanagedDebuggerAttached() || IsManagedDebuggerAttached();
-}
-
-MdaXmlElement* ManagedDebuggingAssistants::GetRootElement(MdaXmlElement* pMdaXmlRoot)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- pMdaXmlRoot->SetDeclDef(MdaElemDef(Msg));
- pMdaXmlRoot->AddAttributeSz(MdaAttrDecl(Xmlns), MDA_TARGET_NAMESPACE)->SetNs(W("mda"));
- return pMdaXmlRoot;
-}
-
-
-
-//
-// MdaXmlMessage
-//
-BOOL IsFormatChar(WCHAR c) { LIMITED_METHOD_CONTRACT; return (c == W('\\') || c == W('!') || c == W('+') || c == W('.') || c == W(':') || c == W('-')); }
-
-// Logic copied from /fx/src/Xml/System/Xml/Core/XmlRawTextWriterGenerator.cxx::WriteAttributeTextBlock
-SString& MdaXmlEscape(SString& sszBuffer, const SString& sszXml, BOOL bEscapeComment = FALSE)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- sszBuffer.Clear();
-
- SString::CIterator itr = sszXml.Begin();
- SString::CIterator end = sszXml.End();
-
- while (itr != end)
- {
- WCHAR c = *itr;
-
- switch(c)
- {
- case W('-'):
- if (*(itr+1) == W('-') && bEscapeComment)
- sszBuffer.Append(W("- "));
- else
- sszBuffer.Append(W("-"));
- break;
- case W('&'):
- sszBuffer.Append(W("&amp;"));
- break;
- case W('<'):
- sszBuffer.Append(W("&lt;"));
- break;
- case W('>'):
- sszBuffer.Append(W("&gt;"));
- break;
- case W('"'):
- sszBuffer.Append(W("&quote;"));
- break;
- default:
- sszBuffer.Append(c);
- }
-
- itr++;
- }
-
- return sszBuffer;
-}
-
-SString* WrapString(SString& buffer, SString& sszString, SCOUNT_T cWidth, SCOUNT_T cIndent = 0, SCOUNT_T cPostIndent = 0)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString sszEscapedString;
- MdaXmlEscape(sszEscapedString, sszString, TRUE);
-
- StackSString sszIndent;
- for (SCOUNT_T i = 0; i < cIndent; i ++)
- sszIndent.Append(W(" "));
-
- StackSString sszPostIndent;
- for (SCOUNT_T i = 0; i < cPostIndent; i ++)
- sszPostIndent.Append(W(" "));
-
- buffer.Append(sszIndent);
-
- SString::CIterator itr = sszEscapedString.Begin();
- SString::CIterator lineStart = sszEscapedString.Begin();
- SString::CIterator lineEnd = sszEscapedString.Begin();
- SString::CIterator lastFormatChar = sszEscapedString.Begin();
- SString::CIterator end = sszEscapedString.End();
-
- while (itr != end)
- {
- if (*itr == W(' '))
- lineEnd = itr;
-
- // Keep track of reasonable breaks in member and file names...
- if (IsFormatChar(*itr) && itr - lineStart < cWidth)
- lastFormatChar = itr;
-
- if (itr - lineStart >= cWidth || *itr == W('\n'))
- {
- if (*itr == W('\n'))
- lineEnd = itr;
-
- // If we didn't find a space or wrapping at found space wraps less than 3/5 of the line...
- else if (lineEnd == end || itr - lineEnd > cWidth * 3 / 5)
- {
- // ...then if we found a format char, start the wrap there...
- if (lastFormatChar != end)
- lineEnd = lastFormatChar + 1;
- // ...else just do a simple wrap...
- else
- lineEnd = itr;
- }
-
- SString sszLine(sszEscapedString, lineStart, lineEnd);
- buffer.Append(sszLine);
- buffer.Append(sszPostIndent);
- buffer.Append(W("\n"));
- buffer.Append(sszIndent);
-
- lineStart = lineEnd;
-
- // If we wrapped on a space or a return than skip over that character as we already replaced it with a \n.
- if (*lineEnd == W(' ') || *lineEnd == W('\n'))
- lineStart++;
-
- lineEnd = end;
- lastFormatChar = end;
- }
-
- itr++;
- }
-
- SString sszLine(sszEscapedString, lineStart, itr);
- buffer.Append(sszLine);
-
- return &buffer;
-}
-
-LPCWSTR ToUpperFirstChar(SString& buffer, LPCWSTR name)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- ASSERT(*name >= 'a' && *name <= 'z');
-
- buffer.Clear();
- buffer.Append(*name - W('a') + W('A'));
- buffer.Append(&name[1]);
- return buffer.GetUnicode();
-}
-
-MdaXmlMessage::MdaXmlMessage(MdaAssistant* pAssistant, BOOL bBreak, MdaXmlElement** ppMdaXmlRoot)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(g_mdaStaticHeap.m_pMda));
- }
- CONTRACTL_END;
-
- m_pMdaAssistant = pAssistant;
- m_bBreak = (pAssistant->GetSuppressDialog()) ? FALSE : bBreak;
- m_pMdaXmlRoot = g_mdaStaticHeap.m_pMda->GetRootElement(m_mdaXmlIndustry.CreateElement());
- *ppMdaXmlRoot = m_pAssistantXmlRoot = pAssistant->GetRootElement(m_mdaXmlIndustry.CreateElement(), bBreak);
-}
-
-MdaXmlMessage::MdaXmlMessage(MdaXmlElement** ppMdaXmlRoot) : m_bBreak(FALSE)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(g_mdaStaticHeap.m_pMda));
- }
- CONTRACTL_END;
-
- *ppMdaXmlRoot = m_pMdaXmlRoot = g_mdaStaticHeap.m_pMda->GetRootElement(m_mdaXmlIndustry.CreateElement());
-}
-
-BOOL MdaXmlMessage::ShouldLogToManagedDebugger()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- BOOL bUnmanagedDebuggerAttached = FALSE;
- BOOL bManagedDebuggerAttached = FALSE;
- BOOL bManagedDebugLoggingEnabled = FALSE;
-
- bUnmanagedDebuggerAttached = IsUnmanagedDebuggerAttached();
-
-#if DEBUGGING_SUPPORTED
- bManagedDebuggerAttached = IsManagedDebuggerAttached();
- bManagedDebugLoggingEnabled = (g_pDebugInterface && g_pDebugInterface->IsLoggingEnabled());
-#endif
-
- return (!bUnmanagedDebuggerAttached && bManagedDebuggerAttached && bManagedDebugLoggingEnabled);
-}
-
-// Send an event for this MDA.
-void MdaXmlMessage::SendEvent()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (IsHostRegisteredForEvent(Event_MDAFired))
- {
- // A host is registered for the MDA fired event so let's start by notifying the
- // debugger is on is attached.
- if (IsManagedDebuggerAttached() || IsUnmanagedDebuggerAttached())
- {
- SendDebugEvent();
- }
-
- // Now that the debugger has been notified and continued, let's notify the host
- // so it can take any action it deems neccessary based on the MDA that fired.
- SendHostEvent();
- }
- else
- {
- // We aren't hosted or no host registered for the MDA fired event so let's simply
- // send the MDA to the debubber. Note that as opposed to the hosted case, we
- // will force a JIT attach if no debugger is present.
- SendDebugEvent();
- }
-}
-
-// Send an event for this MDA.
-void MdaXmlMessage::SendHostEvent()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- MDAInfo info;
- SString strStackTrace;
-
- EX_TRY
- {
- // Retrieve the textual representation of the managed stack trace and add it to
- // the MDA information we give the host.
- GetManagedStackTraceString(TRUE, strStackTrace);
- }
- EX_CATCH
- {
- // We failed to get the stack trace string. This isn't fatal, we will simply not be
- // able to provide this information as part of the notification.
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- // Set up the information and invoke the host to process the MDA fired event.
- info.lpMDACaption = m_pMdaAssistant->GetName();
- info.lpStackTrace = strStackTrace;
- info.lpMDAMessage = m_localizedMessage;
- ProcessEventForHost(Event_MDAFired, &info);
-
- // If the host initiated a thread abort, we want to raise it immediatly to
- // prevent any further code inside the VM from running and potentially
- // crashing the process.
- Thread *pThread = GetThread();
- TESTHOOKCALL(AppDomainCanBeUnloaded(pThread->GetDomain()->GetId().m_dwId,FALSE));
-
- if (pThread && pThread->IsAbortInitiated())
- pThread->HandleThreadAbort(TRUE);
-}
-
-// Send a managed debug event for this MDA.
-// This will block until the debugger continues us. This means the debugger could to things like run callstacks
-// and change debuggee state.
-void MdaXmlMessage::SendDebugEvent()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(g_mdaStaticHeap.m_pMda));
- }
- CONTRACTL_END;
-
- // Simple check to avoid getting XML string if we're not going to actually use it.
- if (!IsManagedDebuggerAttached() && !IsUnmanagedDebuggerAttached() && !m_bBreak)
- {
- return;
- }
-
- EX_TRY
- {
- StackSString sszXml;
- LPCWSTR ns = NULL;
-
- MdaSchema * pSchema = g_mdaStaticHeap.m_pMda->m_pAssistantSchema;
- ns = pSchema->SetRootAttributes(m_pMdaXmlRoot);
- m_pMdaXmlRoot->ToXml(&sszXml, ns);
-
- // For managed + interop cases, send a managed debug event.
- // If m_bBreak is true and no unmanaged debugger is attached trigger a jit-attach.
- if (IsManagedDebuggerAttached() || (m_bBreak && !IsUnmanagedDebuggerAttached()))
- {
- // Get MDA name (this is the type)
- StackSString sszMdaName;
- ToUpperFirstChar(sszMdaName, m_pMdaAssistant->GetName());
- // SendMDANotification needs to be called in preemptive GC mode.
- GCX_PREEMP();
-
- // This will do two things:
- // 1. If a managed debugger is attached, it will send the managed debug event for the MDA.
- // 2. If it's a m_bBreak, we'll try to do a managed jit-attach.
- // This blocks until continued. Since we're not slipping, we don't need the MDA_FLAG_SLIP flag.
- g_pDebugInterface->SendMDANotification(
- GetThread(),
- &sszMdaName,
- &m_localizedMessage,
- &sszXml,
- ((CorDebugMDAFlags) 0 ),
- RunningInteractive() ? m_bBreak : FALSE);
- }
-
- if (IsUnmanagedDebuggerAttached() && !IsManagedDebuggerAttached())
- {
- // For native case, sent native debug event for logging.
- WszOutputDebugString(sszXml.GetUnicode());
-
- if (m_bBreak)
- RetailBreak();
- }
- }
- EX_CATCH
- {
- // No global MDA state modified in TRY
- }
- EX_END_CATCH(SwallowAllExceptions);
-}
-
-void MdaXmlMessage::SendMessagef(int resourceID, ...)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString sszResourcef;
- sszResourcef.LoadResource(CCompRC::DesktopCLR, resourceID );
- ASSERT(!sszResourcef.IsEmpty());
-
- va_list argItr;
- va_start(argItr, resourceID);
- m_localizedMessage.PVPrintf(sszResourcef, argItr);
- va_end(argItr);
-
- SendMessage();
-}
-
-
-void MdaXmlMessage::SendMessage(int resourceID)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- SendMessagef(resourceID);
-}
-
-void MdaXmlMessage::SendMessage(LPCWSTR szMessage)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- m_localizedMessage.Set(szMessage);
-
- SendMessage();
-}
-
-void MdaXmlMessage::SendMessage()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(g_mdaStaticHeap.m_pMda));
- }
- CONTRACTL_END;
-
-#if _DEBUG
- if (g_mdaStaticHeap.m_pMda->m_bValidateOutput)
- {
- MdaSchema::ValidationResult validationResult;
- if (g_mdaStaticHeap.m_pMda->m_pAssistantMsgSchema->Validate(m_pAssistantXmlRoot, &validationResult)->ValidationFailed())
- {
- MDA_TRIGGER_ASSISTANT(XmlValidationError, ReportError(&validationResult));
- ASSERT(W("Your MDA assistant's output did not match its output schema."));
- }
- }
-#endif
-
- if (!m_localizedMessage.IsEmpty())
- {
- StackSString sszComment(m_localizedMessage);
- StackSString sszWrappedComment(W("\n"));
- WrapString(sszWrappedComment, sszComment, 80, 7);
- sszWrappedComment.Append(W("\n "));
- m_pMdaXmlRoot->AddChildComment(sszWrappedComment.GetUnicode());
- }
-
- m_pMdaXmlRoot->AddChild(m_pAssistantXmlRoot);
-
- // Send applicable debug event (managed, native, interop) for this MDA.
- // If this is a severe probe, it may trigger a jit-attach
- SendEvent();
-}
-
-
-//
-// MdaXPath::FindXXX
-//
-
-void MdaXPath::Find(SArray<MdaXPathVariable>& args, SString* pWildCard, va_list argItr)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- for (COUNT_T i = 0; i < GetArgCount(); i ++)
- {
- XPathVarType varType = m_argTypes[i];
-
- if (varType == XPathVarElemDeclDef)
- args[i].m_u.m_elemDeclDef = va_arg(argItr, MdaElemDeclDef);
-
- else if (varType == XPathVarAttrDeclDef)
- args[i].m_u.m_attrDeclDef = va_arg(argItr, MdaAttrDeclDef);
-
- else if (varType == XPathVarAttrBool)
- args[i].m_u.m_bool = va_arg(argItr, BOOL);
-
- else if (varType == XPathVarAttrINT32)
- args[i].m_u.m_int32 = va_arg(argItr, INT32);
-
- else if (varType == XPathVarAttrSString)
- {
- SString* pSString = va_arg(argItr, SString*);
- ASSERT(CheckPointer(pSString, NULL_OK));
- if (!pSString)
- pSString = pWildCard;
- args[i].m_u.m_pSstr = pSString;
- }
-
- else { UNREACHABLE(); }
- }
-}
-
-MdaXmlElement* MdaXPath::FindElement(MdaXmlElement* pRoot, ...)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (!pRoot)
- return NULL;
-
- va_list argItr;
- va_start(argItr, pRoot);
-
- SString wildCard;
- InlineSArray<MdaXPathVariable, 20> args;
- Find(args, &wildCard, argItr);
-
- MdaXPathResult result(&args);
- m_pCompiledQuery->Run(pRoot, &result);
-
- va_end(argItr);
- return result.GetXmlElement();
-}
-
-MdaXmlAttribute* MdaXPath::FindAttribute(MdaXmlElement* pRoot, ...)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (!pRoot)
- return NULL;
-
- va_list argItr;
- va_start(argItr, pRoot);
-
- SString wildCard;
- InlineSArray<MdaXPathVariable, 20> args;
- Find(args, &wildCard, argItr);
-
- MdaXPathResult result(&args);
- m_pCompiledQuery->Run(pRoot, &result);
-
- va_end(argItr);
- return result.GetXmlAttribute();
-}
-
-SArray<MdaXmlElement*>* MdaXPath::FindElements(MdaXmlElement* pRoot, SArray<MdaXmlElement*>* pResult, ...)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (!pRoot)
- return NULL;
-
- va_list argItr;
- va_start(argItr, pResult);
-
- SString wildCard;
- InlineSArray<MdaXPathVariable, 20> args;
- Find(args, &wildCard, argItr);
-
- MdaXPathResult result(pResult, &args);
- m_pCompiledQuery->Run(pRoot, &result);
-
- va_end(argItr);
- return pResult;
-}
-
-SArray<MdaXmlAttribute*>* MdaXPath::FindAttributes(MdaXmlElement* pRoot, SArray<MdaXmlAttribute*>* pResult, ...)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (!pRoot)
- return NULL;
-
- va_list argItr;
- va_start(argItr, pResult);
-
- SString wildCard;
- InlineSArray<MdaXPathVariable, 20> args;
- Find(args, &wildCard, argItr);
-
- MdaXPathResult result(pResult, &args);
- m_pCompiledQuery->Run(pRoot, &result);
-
- va_end(argItr);
- return pResult;
-}
-
-
-//
-// MdaXPath::MdaXPathCompiler -- Lexifier
-//
-
-#define ISWHITE(ch) (ch == W(' ') || ch == W('\t') || ch == W('\n'))
-#define ISRESERVED(ch) (wcschr(W("./()[]&|=@*?':"), ch) != NULL)
-#define ISMDAID(ch) (!ISWHITE(ch) && !ISRESERVED(ch))
-
-MdaXPath::MdaXPathCompiler::MdaXPathTokens MdaXPath::MdaXPathCompiler::LexAToken()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (*m_itr == W('\0'))
- return MdaXPathEnd;
-
- if (ISWHITE(*m_itr))
- {
- m_itr++;
- return LexAToken();
- }
-
- if (ISMDAID(*m_itr))
- {
- m_identifier.Clear();
-
- do
- {
- m_identifier.Append(*m_itr);
- m_itr++;
- }
- while(ISMDAID(*m_itr));
-
- m_identifier.Append(W("\0"));
- return MdaXPathIdentifier;
- }
-
- if (*m_itr == W('\''))
- {
- m_identifier.Clear();
-
- m_itr++;
-
- while(*m_itr != W('\''))
- {
- m_identifier.Append(*m_itr);
- m_itr++;
- }
-
- m_identifier.Append(W("\0"));
-
- m_itr++;
- return MdaXPathQuotedString;
- }
-
- WCHAR c = *m_itr;
- m_itr++;
- switch(c)
- {
- case W('.'): return MdaXPathDot;
- case W('/'): return MdaXPathSlash;
- case W('('): return MdaXPathOpenParen;
- case W(')'): return MdaXPathCloseParen;
- case W('['): return MdaXPathOpenSqBracket;
- case W(']'): return MdaXPathCloseSqBracket;
- case W('&'): return MdaXPathLogicalAnd;
- case W('|'): return MdaXPathLogicalOr;
- case W('='): return MdaXPathEquals;
- case W('@'): return MdaXPathAtSign;
- case W('*'): return MdaXPathAstrix;
- case W('?'): return MdaXPathQMark;
- }
-
- UNREACHABLE();
-}
-
-
-//
-// MdaXPath::MdaXPathCompiler -- Parser
-//
-
-// XPATH
-// '/' ELEMENT_EXPR end
-// '/' ELEMENT_EXPR XPATH
-// '/' ATTRIBUTE end
-MdaXPath::MdaXPathBase* MdaXPath::MdaXPathCompiler::XPATH()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
- PRECONDITION(TokenIs(MdaXPathXPATH));
-
- MdaXPathElement* pElementExpr = NULL;
-
- NextToken();
- if (TokenIs(MdaXPathELEMENT_EXPR))
- pElementExpr = ELEMENT_EXPR();
-
- else if (TokenIs(MdaXPathATTRIBUTE))
- {
- MdaXPathAttribute* pAttr = ATTRIBUTE();
- pAttr->MarkAsTarget();
- NextToken();
- ASSERT(TokenIs(MdaXPathEnd));
- return pAttr;
- }
-
- else { UNREACHABLE(); }
-
-
- if (TokenIs(MdaXPathEnd))
- return pElementExpr->MarkAsTarget();
-
- else if (TokenIs(MdaXPathXPATH))
- return pElementExpr->SetChild(XPATH());
-
- else { UNREACHABLE(); }
-}
-
-// ATTRIBUTE
-// '@' id
-// '@' '?'
-MdaXPath::MdaXPathAttribute* MdaXPath::MdaXPathCompiler::ATTRIBUTE()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
- PRECONDITION(TokenIs(MdaXPathATTRIBUTE));
-
- MdaXPathAttribute* pAttr = NULL;
-
- NextToken();
- if (TokenIs(MdaXPathQMark))
- {
- pAttr = m_pXPath->m_attrFactory.Create()->SetName(++m_pXPath->m_cArgs);
- *m_pXPath->m_argTypes.Append() = XPathVarAttrDeclDef;
- }
-
- else if (TokenIs(MdaXPathIdentifier))
- {
- pAttr = m_pXPath->m_attrFactory.Create()->SetName(MdaSchema::GetAttributeType(GetIdentifier()));
- }
-
- else { UNREACHABLE(); }
-
- NextToken();
- return pAttr;
-}
-
-// ELEMENT_EXPR
-// ELEMENT '[' FILTER_EXPR ']'
-// ELEMENT
-MdaXPath::MdaXPathElement* MdaXPath::MdaXPathCompiler::ELEMENT_EXPR()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
- PRECONDITION(TokenIs(MdaXPathELEMENT_EXPR));
-
- MdaXPathElement* pElement = ELEMENT();
-
- if (TokenIs(MdaXPathOpenSqBracket))
- {
- NextToken();
- pElement->SetQualifier(FILTER_EXPR());
- ASSERT(TokenIs(MdaXPathCloseSqBracket));
-
- NextToken();
- }
-
- return pElement;
-}
-
-// FILTER_EXPR
-// FILTER
-// '(' FILTER ')'
-// FILTER '&' FILTER
-// FILTER '|' FILTER
-MdaXPath::MdaXPathBase* MdaXPath::MdaXPathCompiler::FILTER_EXPR()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
- PRECONDITION(TokenIs(MdaXPathFILTER_EXPR));
-
- // '(' FILTER ')'
- if (TokenIs(MdaXPathOpenParen))
- {
- MdaXPath::MdaXPathBase* pFilter = FILTER();
- ASSERT(TokenIs(MdaXPathCloseParen));
-
- NextToken();
- return pFilter;
- }
-
- if (TokenIs(MdaXPathFILTER))
- {
- MdaXPath::MdaXPathBase* pFilter = FILTER();
-
- // FILTER '&' FILTER
- if (TokenIs(MdaXPathLogicalAnd))
- {
- NextToken();
- return m_pXPath->m_logicalOpFactory.Create()->Initialize(TRUE, pFilter, FILTER());
- }
-
- // FILTER '|' FILTER
- if (TokenIs(MdaXPathLogicalOr))
- {
- NextToken();
- return m_pXPath->m_logicalOpFactory.Create()->Initialize(FALSE, pFilter, FILTER());
- }
-
- // FILTER
- return pFilter;
- }
-
- UNREACHABLE();
-}
-
-// FILTER
-// ELEMENT_EXPR
-// ATTRIBUTE_FILTER
-// ELEMENT_EXPR ATTRIBUTE_FILTER
-MdaXPath::MdaXPathBase* MdaXPath::MdaXPathCompiler::FILTER()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
- PRECONDITION(TokenIs(MdaXPathFILTER));
-
- if (TokenIs(MdaXPathELEMENT_EXPR))
- {
- MdaXPathElement* pElementExpr = ELEMENT_EXPR();
-
- if (TokenIs(MdaXPathATTRIBUTE_FILTER))
- pElementExpr->SetQualifier(ATTRIBUTE_FILTER());
-
- return pElementExpr;
- }
-
- if (TokenIs(MdaXPathATTRIBUTE_FILTER))
- return ATTRIBUTE_FILTER();
-
- UNREACHABLE();
-}
-
-// ELEMENT
-// id
-// '*'
-// '?'
-MdaXPath::MdaXPathElement* MdaXPath::MdaXPathCompiler::ELEMENT()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
- PRECONDITION(TokenIs(MdaXPathELEMENT));
-
- MdaXPathElement* pElement = m_pXPath->m_elementFactory.Create();
-
- if (TokenIs(MdaXPathAstrix))
- pElement->Initialize();
-
- else if (TokenIs(MdaXPathIdentifier))
- pElement->Initialize(MdaSchema::GetElementType(GetIdentifier()));
-
- else if (TokenIs(MdaXPathQMark))
- {
- pElement->Initialize(++m_pXPath->m_cArgs);
- *m_pXPath->m_argTypes.Append() = XPathVarElemDeclDef;
- }
-
- else { UNREACHABLE(); }
-
- NextToken();
- return pElement;
-}
-
-// ATTRIBUTE_FILTER();
-// ATTRIBUTE
-// ATTRIBUTE '=' ''' id '''
-// ATTRIBUTE '=' '?'
-MdaXPath::MdaXPathAttribute* MdaXPath::MdaXPathCompiler::ATTRIBUTE_FILTER()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
- PRECONDITION(TokenIs(MdaXPathATTRIBUTE_FILTER));
-
- MdaXPathAttribute* pAttr = ATTRIBUTE();
-
- if (TokenIs(MdaXPathEquals))
- {
- NextToken();
-
- if (TokenIs(MdaXPathQuotedString))
- {
- NextToken();
- pAttr->SetValue(GetIdentifier());
-
- NextToken();
- ASSERT(TokenIs(MdaXPathQuotedString));
- }
- else if (TokenIs(MdaXPathQMark))
- {
- pAttr->SetValue(++m_pXPath->m_cArgs);
- *m_pXPath->m_argTypes.Append() = XPathVarAttrSString;
- }
- else { UNREACHABLE(); }
- }
-
- NextToken();
- return pAttr;
-}
-
-
-//
-// MdaXPath::Elements::Run() -- The search engine
-//
-
-BOOL MdaXPath::MdaXPathElement::Run(MdaXmlElement* pElement, MdaXPathResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- BOOL bAnyPass = FALSE;
- if (pResult->IsRoot())
- {
- bAnyPass |= RunOnChild(pElement, pResult);
- }
- else
- {
- SArray<MdaXmlElement*>& children = pElement->GetChildren();
-
- for (UINT32 i = 0; i < children.GetCount(); i ++)
- {
- bAnyPass |= RunOnChild(children[i], pResult);
- }
- }
-
- return bAnyPass;
-}
-
-BOOL MdaXPath::MdaXPathElement::RunOnChild(MdaXmlElement* pElement, MdaXPathResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- MdaElemDeclDef name = m_nameArg == NOT_VARIABLE ? m_name : pResult->GetArgs()[m_nameArg].m_u.m_elemDeclDef;
-
- if (name != MdaElemUndefined && name != pElement->GetDeclDef())
- return FALSE;
-
- if (m_pQualifier && !m_pQualifier->Run(pElement, pResult))
- return FALSE;
-
- if (m_pChild && !m_pChild->Run(pElement, pResult))
- return FALSE;
-
- if (m_bIsTarget)
- {
- ASSERT(!m_pChild);
- pResult->AddMatch(pElement);
- }
-
- return TRUE;
-}
-
-BOOL MdaXPath::MdaXPathAttribute::Run(MdaXmlElement* pElement, MdaXPathResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- MdaAttrDeclDef name = m_nameArg == NOT_VARIABLE ? m_name : pResult->GetArgs()[m_nameArg].m_u.m_attrDeclDef;
- SString& value = m_valueArg == NOT_VARIABLE ? m_value : *pResult->GetArgs()[m_valueArg].m_u.m_pSstr;
-
- MdaXmlAttribute* pAttr = pElement->GetAttribute(name);
- if (!pAttr)
- return FALSE;
-
- LPCWSTR szAttrValue = pAttr->GetValue();
- if (!value.IsEmpty() && *szAttrValue != W('*') && !value.Equals(szAttrValue))
- return FALSE;
-
- if (m_bIsTarget)
- pResult->AddMatch(pElement);
-
- return TRUE;
-}
-
-BOOL MdaXPath::MdaXPathLogicalOp::Run(MdaXmlElement* pParent, MdaXPathResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (m_andOp)
- return m_pLhs->Run(pParent, pResult) && m_pRhs->Run(pParent, pResult);
-
- return m_pLhs->Run(pParent, pResult) || m_pRhs->Run(pParent, pResult);
-}
-
-
-//
-// MdaSchema
-//
-
-MdaHashtable<MdaElemDeclDef>* MdaSchema::g_pHtElementType;
-MdaHashtable<MdaAttrDeclDef>* MdaSchema::g_pHtAttributeType;
-LPCWSTR MdaSchema::g_arElementNames[MdaElemEnd];
-LPCWSTR MdaSchema::g_arAttributeNames[MdaAttrEnd];
-MdaFactory<SString>* MdaSchema::g_pSstringFactory;
-MdaElemDeclDef MdaSchema::MdaSchemaTypeToElemDef[MdaSchema::MdaSchemaTypeEnd];
-MdaSchema::MdaSchemaMetaType MdaSchema::MdaSchemaTypeToMetaType[MdaSchema::MdaSchemaTypeEnd];
-
-LPCWSTR MdaSchema::ToLowerFirstChar(LPCWSTR name)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return ::ToLowerFirstChar(name, g_pSstringFactory);
-}
-
-void MdaSchema::Initialize()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- g_pHtElementType = new MdaHashtable<MdaElemDeclDef>();
- g_pHtAttributeType = new MdaHashtable<MdaAttrDeclDef>();
- g_pSstringFactory = new MdaFactory<SString>();
-
- COUNT_T i = 0;
- MdaSchemaTypeToElemDef[i++] = MdaElemDef(Sequence); // MdaSchemaSequenceType
- MdaSchemaTypeToElemDef[i++] = MdaElemDef(Choice); // MdaSchemaChoiceType
- MdaSchemaTypeToElemDef[i++] = MdaElemDef(Group); // MdaSchemaGroupType
- MdaSchemaTypeToElemDef[i++] = MdaElemDef(Group); // MdaSchemaGroupRefType
- MdaSchemaTypeToElemDef[i++] = MdaElemDef(Schema); // MdaSchemaRootType
- MdaSchemaTypeToElemDef[i++] = MdaElemDef(Attribute); // MdaSchemaAttributeType
- MdaSchemaTypeToElemDef[i++] = MdaElemDef(Element); // MdaSchemaElementType
- MdaSchemaTypeToElemDef[i++] = MdaElemDef(ComplexType); // MdaSchemaComplexTypeType
- MdaSchemaTypeToElemDef[i++] = MdaElemDef(ComplexType); // MdaSchemaComplexTypeDefType
- MdaSchemaTypeToElemDef[i++] = MdaElemDef(Element); // MdaSchemaElementRefTyp
- MdaSchemaTypeToElemDef[i++] = MdaElemDef(Extension); // MdaSchemaExtensionType
- MdaSchemaTypeToElemDef[i++] = MdaElemDef(Element); // MdaSchemaElementRefTypeType
- MdaSchemaTypeToElemDef[i++] = MdaElemDef(ComplexContent); // MdaSchemaComplexContentType
- MdaSchemaTypeToElemDef[i++] = MdaElemDef(Element); // MdaSchemaElementAnyType
-
- i = 0;
- MdaSchemaTypeToMetaType[i++] = MdaSchemaMataTypePattern; // MdaSchemaSequenceType
- MdaSchemaTypeToMetaType[i++] = MdaSchemaMataTypePattern; // MdaSchemaChoiceType
- MdaSchemaTypeToMetaType[i++] = (MdaSchemaMetaType)(MdaSchemaMataTypePattern | MdaSchemaMataTypeDeclDef); // MdaSchemaGroupType
- MdaSchemaTypeToMetaType[i++] = (MdaSchemaMetaType)(MdaSchemaMataTypePattern | MdaSchemaMataTypeRef); // MdaSchemaGroupRefType
- MdaSchemaTypeToMetaType[i++] = MdaSchemaMataNone; // MdaSchemaRootType
- MdaSchemaTypeToMetaType[i++] = MdaSchemaMataNone; // MdaSchemaAttributeType
- MdaSchemaTypeToMetaType[i++] = MdaSchemaMataTypeDeclDef; // MdaSchemaElementType
- MdaSchemaTypeToMetaType[i++] = (MdaSchemaMetaType)(MdaSchemaMataNone | MdaSchemaMataMayHaveAttributes); // MdaSchemaComplexTypeType
- MdaSchemaTypeToMetaType[i++] = (MdaSchemaMetaType)(MdaSchemaMataTypeDeclDef | MdaSchemaMataMayHaveAttributes); // MdaSchemaComplexTypeDefType
- MdaSchemaTypeToMetaType[i++] = MdaSchemaMataTypeRef; // MdaSchemaElementRefTyp
- MdaSchemaTypeToMetaType[i++] = (MdaSchemaMetaType)(MdaSchemaMataTypeRef | MdaSchemaMataMayHaveAttributes); // MdaSchemaExtensionType
- MdaSchemaTypeToMetaType[i++] = (MdaSchemaMetaType)(MdaSchemaMataTypeDeclDef | MdaSchemaMataTypeRef); // MdaSchemaElementRefTypeType
- MdaSchemaTypeToMetaType[i++] = MdaSchemaMataNone; // MdaSchemaComplexContentType
- MdaSchemaTypeToMetaType[i++] = MdaSchemaMataTypeDeclDef; // MdaSchemaElementAnyType
-
- i = 0;
-#define MDA_MAP_ASSISTANT_DEFINITION_TO_NAME
-#include "mdaschema.inl"
-#undef MDA_MAP_ASSISTANT_DEFINITION_TO_NAME
- g_arElementNames[i++] = NULL;
-#define MDA_MAP_ELEMENT_DEFINITION_TO_NAME
-#include "mdaschema.inl"
-#undef MDA_MAP_ELEMENT_DEFINITION_TO_NAME
- g_arElementNames[i++] = NULL;
-#define MDA_MAP_ELEMENT_DECLARATION_TO_NAME
-#include "mdaschema.inl"
-#undef MDA_MAP_ELEMENT_DECLARATION_TO_NAME
- g_arElementNames[i++] = NULL; // Max
- g_arElementNames[i++] = W("!--"); // Comment
- g_arElementNames[i++] = NULL; // Undefined
-
- i = 0;
-#define MDA_MAP_ATTRIBUTE_DECLARATION_TO_NAME
-#include "mdaschema.inl"
-#undef MDA_MAP_ATTRIBUTE_DECLARATION_TO_NAME
-
-#define MDA_MAP_ASSISTANT_NAME_TO_DEFINITION
-#include "mdaschema.inl"
-#undef MDA_MAP_ASSISTANT_NAME_TO_DEFINITION
-
-#define MDA_MAP_ELEMENT_NAME_TO_DEFINITION
-#include "mdaschema.inl"
-#undef MDA_MAP_ELEMENT_NAME_TO_DEFINITION
-
-#define MDA_MAP_ELEMENT_NAME_TO_DECLARATION
-#include "mdaschema.inl"
-#undef MDA_MAP_ELEMENT_NAME_TO_DECLARATION
-
-#define MDA_MAP_ATTRIBUTE_NAME_TO_DECLARATION
-#include "mdaschema.inl"
-#undef MDA_MAP_ATTRIBUTE_NAME_TO_DECLARATION
-}
-
-MdaElemDeclDef MdaSchema::GetElementType(LPCWSTR name, BOOL bAssertDefined)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- MdaElemDeclDef type;
-
- if (!g_pHtElementType->Get(name, &type))
- {
- ASSERT(!bAssertDefined);
- return MdaElemUndefined;
- }
-
- return type;
-}
-
-LPCWSTR MdaSchema::GetElementName(MdaElemDeclDef type)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- PRECONDITION(type >= 0 && type < MdaElemUndefined);
- return g_arElementNames[type];
-}
-
-MdaAttrDeclDef MdaSchema::GetAttributeType(LPCWSTR name, BOOL bAssertDefined)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- MdaAttrDeclDef type;
-
- if (!g_pHtAttributeType->Get(name, &type))
- {
- ASSERT(!bAssertDefined);
- return MdaAttrUndefined;
- }
-
- return type;
-}
-
-LPCWSTR MdaSchema::GetAttributeName(MdaAttrDeclDef type)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return g_arAttributeNames[type];
-}
-
-// TODO: Validation error reporting needs work
-MdaSchema::ValidationResult* MdaSchema::Validate(MdaXmlElement* pRoot, ValidationResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- pResult->Initialize(this, pRoot);
-
- MdaSchemaBase* pXsd = *GetDef(pRoot->GetDeclDef());
- ASSERT((CheckPointer(pXsd) || (pRoot->GetDeclDef() > MdaElemDecl(Max))) && W("You likley did not include a MDA_DEFINE_OUTPUT section in your schema!"));
-
- BOOL bValidationSucceeded = pXsd ? pXsd->Validate(pRoot, pResult) : FALSE;
-
- if (bValidationSucceeded)
- pResult->ResetResult();
- else
- pResult->SetError();
-
- ASSERT(pResult->ValidationFailed() == !bValidationSucceeded);
- return pResult;
-}
-
-MdaSchema::MdaSchema()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- for(COUNT_T i = 0; i < MdaElemEnd; i ++)
- m_definitions[i] = NULL;
-}
-
-
-//
-// MdaAssistantSchema
-//
-
-MdaAssistantSchema::MdaAssistantSchema()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
-#define MDA_DEFINE_ASSISTANT_SCHEMA
-#include "mdaschema.inl"
-#undef MDA_DEFINE_ASSISTANT_SCHEMA
-
-#define MDA_DEFINE_MDA_ASSISTANT_CONFIG_GROUP
-#include "mdaschema.inl"
-#undef MDA_DEFINE_MDA_ASSISTANT_CONFIG_GROUP
-}
-
-LPCWSTR MdaAssistantSchema::SetRootAttributes(MdaXmlElement* pXml)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- //pXml->AddAttribute(W("xmlns:") MDA_SCHEMA_PREFIX, MDA_TARGET_NAMESPACE);
- //pXml->AddAttribute(W("xmlns:xsi"), W("http://www.w3.org/2001/XMLSchema-instance"));
- return MDA_SCHEMA_PREFIX;
-}
-
-
-//
-// MdaAssistantMsgSchema
-//
-
-MdaAssistantMsgSchema::MdaAssistantMsgSchema()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
-#define MDA_DEFINE_ASSISTANT_MSG_SCHEMA
-#include "mdaschema.inl"
-#undef MDA_DEFINE_ASSISTANT_MSG_SCHEMA
-
-#define MDA_DEFINE_MDA_ASSISTANT_MSG_GROUP
-#include "mdaschema.inl"
-#undef MDA_DEFINE_MDA_ASSISTANT_MSG_GROUP
-}
-
-LPCWSTR MdaAssistantMsgSchema::SetRootAttributes(MdaXmlElement* pXml)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- //pXml->AddAttribute(W("xmlns:") MDA_SCHEMA_PREFIX, MDA_TARGET_NAMESPACE);
- //pXml->AddAttribute(W("xmlns:xsi"), W("http://www.w3.org/2001/XMLSchema-instance"));
- return MDA_SCHEMA_PREFIX;
-}
-
-
-//
-// MdaSchemaSchema
-//
-
-MdaSchemaSchema::MdaSchemaSchema()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
-#define MDA_DEFINE_SCHEMA_SCHEMA
-#include "mdaschema.inl"
-#undef MDA_DEFINE_SCHEMA_SCHEMA
-}
-
-LPCWSTR MdaSchemaSchema::SetRootAttributes(MdaXmlElement* pXml)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- pXml->AddAttributeSz(MdaAttrDecl(TargetNamespace), MDA_TARGET_NAMESPACE);
- pXml->AddAttributeSz(MdaAttrDecl(Xmlns), W("http://www.w3.org/2001/XMLSchema"))->SetNs(W("xs"));
- pXml->AddAttributeSz(MdaAttrDecl(Xmlns), MDA_TARGET_NAMESPACE);
- return W("xs");
-}
-
-
-//
-// MdaSchema::MdaSchemaXXX
-//
-MdaXmlElement* MdaSchema::MdaSchemaBase::ToXml(MdaXmlIndustry* pMdaXmlIndustry, MdaSchemaBase* pViolation)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return ToXml(pMdaXmlIndustry->CreateElement(), pViolation);
-}
-
-MdaXmlElement* MdaSchema::MdaSchemaBase::ToXml(MdaXmlElement* pXmlRoot, MdaSchemaBase* pViolation)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- LPCWSTR debugName = GetName();
-
- MdaXmlElement* pXml = pXmlRoot->AddChild(GetSchemaDeclDef());
- SetAttributes(pXml);
-
-// if (this == pViolation)
-// pXml->AddAttributeSz(MdaAttrDecl(Violated), W("---- THIS XSD ELEMENT VIOLATED -----"));
-
- if (m_children.GetCount() == 1 &&
- m_children[0]->GetSchemaDeclDef() == MdaElemDef(ComplexType) &&
- m_children[0]->m_children.GetCount() == 0 &&
- (!MayHaveAttr(m_children[0]) ||
- m_children[0]->GetAttributes().GetCount() == 0))
- {
- // Convert <Element><ComplexType/><Element> to <Element/>
- return pXml;
- }
-
- for(COUNT_T i = 0; i < m_children.GetCount(); i ++)
- {
- debugName = m_children[i]->GetName();
- m_children[i]->ToXml(pXml, pViolation);
- }
-
- if (MayHaveAttr(this))
- {
- SArray<MdaSchemaAttribute*>& attributes = GetAttributes();
- for(COUNT_T j = 0; j < attributes.GetCount(); j ++)
- {
- debugName = attributes[j]->GetName();
- attributes[j]->ToXml(pXml, pViolation);
- }
- }
-
- return pXml;
-}
-
-
-void MdaSchema::MdaSchemaBase::AddChild(MdaSchemaBase* pElement)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (pElement->GetSchemaDeclDef() == MdaElemDef(Attribute))
- *GetAttributes().Append() = (MdaSchemaAttribute*)pElement;
- else
- *m_children.Append() = pElement;
-}
-
-//
-// Validation
-//
-
-#define CpdXsdIfFailGo(EXPR) do { if (!(EXPR)) { goto Fail; } } while (0)
-#define CpdXsdTest(EXPR) do { if (!(EXPR)) { pResult->SetError(this, pElement); goto Fail; } } while (0)
-#define MDA_XSD_VERIFY_OK return TRUE;
-#define MDA_XSD_VERIFY_FAIL Fail: return FALSE;
-
-BOOL MdaSchema::MdaSchemaElement::Validate(MdaXmlElement* pElement, ValidationResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString buffer;
- LPCWSTR debug = pElement->DebugToString(&buffer);
-
- CpdXsdTest(pElement->GetDeclDef() == GetDeclDef());
-
- for(COUNT_T i = 0; i < m_children.GetCount(); i++)
- CpdXsdIfFailGo(m_children[i]->Validate(pElement, pResult));
-
- MDA_XSD_VERIFY_OK;
- MDA_XSD_VERIFY_FAIL;
-}
-
-BOOL MdaSchema::MdaSchemaSequence::ValidatePattern(MdaXmlElement* pElement, ValidationResult* pResult, COUNT_T* pCount)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString buffer;
- LPCWSTR debug = pElement->DebugToString(&buffer);
-
- COUNT_T cPeriod = m_children.GetCount();
- COUNT_T cChildren = pElement->GetChildren().GetCount();
- COUNT_T cCurrent = *pCount;
- COUNT_T cCount = cCurrent;
- COUNT_T cMatches = 0;
-
- if (cPeriod == 0)
- return TRUE;
-
- while(cCurrent <= cChildren)
- {
- MdaSchemaBase* pXsd = m_children[cMatches % cPeriod];
- if (pXsd->GetSchemaDeclDef() == MdaElemDef(Element))
- {
- if (cCurrent == cChildren)
- break;
-
- if (!pXsd->Validate(pElement->GetChildren()[cCurrent], pResult))
- break;
-
- cCurrent++;
- }
- else
- {
- ASSERT(IsPattern(pXsd));
- if (!pXsd->ValidatePattern(pElement, pResult, &cCurrent))
- break;
- }
-
- cMatches++;
-
- // One period matched
- if (cMatches % cPeriod == 0)
- cCount = cCurrent;
-
- // Maximum periods matcheds
- if (cMatches / cPeriod == m_max)
- break;
- }
-
- // Test if the minumum number periods have been matched
- if (cMatches / cPeriod < m_min)
- return FALSE;
-
- // Update the position past the matched elements
- *pCount = cCount;
-
- return TRUE;
-}
-
-BOOL MdaSchema::MdaSchemaChoice::ValidatePattern(MdaXmlElement* pElement, ValidationResult* pResult, COUNT_T* pCount)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString buffer;
- LPCWSTR debug = pElement->DebugToString(&buffer);
-
- BOOL bFound = FALSE;
- COUNT_T cCurrent = *pCount;
- COUNT_T cChildren = pElement->GetChildren().GetCount();
-
- for(COUNT_T cXsd = 0; cXsd < m_children.GetCount(); cXsd++)
- {
- MdaSchemaBase* pXsd = m_children[cXsd];
-
- if (IsPattern(pXsd))
- {
- COUNT_T cOldCurrent = cCurrent;
- if (pXsd->ValidatePattern(pElement, pResult, &cCurrent))
- {
- // "Empty matches" only allowed in choice pattern if there are no children to match
- if (cOldCurrent != cCurrent || cChildren == 0)
- {
- bFound = TRUE;
- break;
- }
- }
- }
- else
- {
- if (cCurrent == cChildren)
- break;
-
- if (pXsd->Validate(pElement->GetChildren()[cCurrent], pResult))
- {
- cCurrent++;
- bFound = TRUE;
- break;
- }
- }
- }
-
- CpdXsdIfFailGo(bFound);
-
- *pCount = cCurrent;
-
- MDA_XSD_VERIFY_OK;
- MDA_XSD_VERIFY_FAIL;
-}
-
-#define this pThis
-BOOL MdaSchema::Validate(MdaSchemaAttribute* pThis, MdaXmlElement* pElement, ValidationResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString sszValue;
- MdaXmlAttribute* pAttr = (MdaXmlAttribute*)pElement->GetAttribute(pThis->m_declDef);
-
- if (!pAttr && !pThis->m_szDefault.IsEmpty())
- {
- pAttr = pElement->AddDefaultAttribute(pThis->m_declDef, pThis->m_szDefault.GetUnicode());
- }
-
- if (!pAttr)
- {
- CpdXsdTest(!pThis->m_bRequired);
- return TRUE;
- }
-
-#ifdef _DEBUG
- // Only necessary for validation of assistant output
- if (pAttr->m_type != MdaSchemaPrimitiveUnknown)
- {
- CpdXsdTest(pAttr->m_type == pThis->m_type);
- return TRUE;
- }
-#endif
-
- LPCWSTR szValue = pAttr->GetValue();
- sszValue.Set(szValue);
-
- if (pThis->m_type == MdaSchemaPrimitiveSString)
- {
- /* accept all strings? */
- }
- else if (pThis->m_type == MdaSchemaPrimitiveINT32)
- {
- CpdXsdTest(!sszValue.IsEmpty() && sszValue.GetCount() != 0);
-
- for (COUNT_T i = 0; i < sszValue.GetCount(); i ++)
- {
- if (i == 0 && *szValue == W('-') && sszValue.GetCount() > 1)
- continue;
-
- CpdXsdTest(IS_DIGIT(szValue[i]));
- }
-
- pAttr->SetINT32(_wtoi(szValue));
- }
- else if (pThis->m_type == MdaSchemaPrimitiveBOOL)
- {
- CpdXsdTest(!sszValue.IsEmpty() && sszValue.GetCount() != 0);
-
- if (sszValue.Equals(W("true")))
- pAttr->SetBOOL(true);
- else if (sszValue.Equals(W("false")))
- pAttr->SetBOOL(false);
- else
- CpdXsdTest(FALSE);
- }
-
- MDA_XSD_VERIFY_OK;
- MDA_XSD_VERIFY_FAIL;
-}
-#undef this
-
-BOOL MdaSchema::MdaSchemaBase::Validate(MdaXmlElement* pElement, ValidationResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- COUNT_T count = 0;
-
- CpdXsdTest(ValidatePattern(pElement, pResult, &count));
-
- CpdXsdTest(count == pElement->GetChildren().GetCount());
-
- MDA_XSD_VERIFY_OK;
- MDA_XSD_VERIFY_FAIL;
-}
-
-BOOL MdaSchema::MdaSchemaRoot::Validate(MdaXmlElement* pElement, ValidationResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- for(COUNT_T i = 0; i < m_children.GetCount(); i++)
- CpdXsdIfFailGo(m_children[i]->Validate(pElement, pResult));
-
- MDA_XSD_VERIFY_OK;
- MDA_XSD_VERIFY_FAIL;
-}
-
-BOOL MdaSchema::MdaSchemaComplexType::Validate(MdaXmlElement* pElement, ValidationResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- for(COUNT_T i = 0; i < m_children.GetCount(); i++)
- CpdXsdIfFailGo(m_children[i]->Validate(pElement, pResult));
-
- for(COUNT_T i = 0; i < m_attributes.GetCount(); i++)
- CpdXsdIfFailGo(m_attributes[i]->Validate(pElement, pResult));
-
- MDA_XSD_VERIFY_OK;
- MDA_XSD_VERIFY_FAIL;
-}
-
-BOOL MdaSchema::MdaSchemaComplexTypeDef::Validate(MdaXmlElement* pElement, ValidationResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- for(COUNT_T i = 0; i < m_children.GetCount(); i++)
- CpdXsdIfFailGo(m_children[i]->Validate(pElement, pResult));
-
- for(COUNT_T i = 0; i < m_attributes.GetCount(); i++)
- CpdXsdIfFailGo(m_attributes[i]->Validate(pElement, pResult));
-
- MDA_XSD_VERIFY_OK;
- MDA_XSD_VERIFY_FAIL;
-}
-
-BOOL MdaSchema::MdaSchemaComplexContent::Validate(MdaXmlElement* pElement, ValidationResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- for(COUNT_T i = 0; i < m_children.GetCount(); i++)
- CpdXsdIfFailGo(m_children[i]->Validate(pElement, pResult));
-
- MDA_XSD_VERIFY_OK;
- MDA_XSD_VERIFY_FAIL;
-}
-
-BOOL MdaSchema::MdaSchemaGroup::ValidatePattern(MdaXmlElement* pElement, ValidationResult* pResult, COUNT_T* pCount)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- for(COUNT_T i = 0; i < m_children.GetCount(); i++)
- {
- ASSERT(IsPattern(m_children[i]));
- CpdXsdIfFailGo(m_children[i]->ValidatePattern(pElement, pResult, pCount));
- }
-
- MDA_XSD_VERIFY_OK;
- MDA_XSD_VERIFY_FAIL;
-}
-
-BOOL MdaSchema::MdaSchemaGroupRef::ValidatePattern(MdaXmlElement* pElement, ValidationResult* pResult, COUNT_T* pCount)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- MdaSchemaBase* pReference = GetRef();
- LPCWSTR debug = GetRefName();
- ASSERT(IsPattern(this));
- return pReference->ValidatePattern(pElement, pResult, pCount);
-}
-
-BOOL MdaSchema::MdaSchemaExtension::Validate(MdaXmlElement* pElement, ValidationResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- ASSERT(GetRef()->GetSchemaType() == MdaSchemaComplexTypeDefType);
- MdaSchemaComplexTypeDef* pReference = (MdaSchemaComplexTypeDef*)GetRef();
-
- MdaSchemaSequence sequence;
- sequence.Initialize(1, 1);
-
- MdaSchemaBase* pXsd = pReference;
- while(true)
- {
- if (MayHaveAttr(pXsd))
- {
- for(COUNT_T i = 0; i < pXsd->GetAttributes().GetCount(); i++)
- CpdXsdIfFailGo(pXsd->GetAttributes()[i]->Validate(pElement, pResult));
- }
-
- if (pXsd->GetSchemaType() == MdaSchemaExtensionType)
- {
- pXsd = ((MdaSchemaComplexTypeDef*)pXsd)->GetRef();
- continue;
- }
-
- if (pXsd->m_children.GetCount() == 0)
- break;
-
- pXsd = pXsd->m_children[0];
-
- if (IsPattern(pXsd))
- {
- sequence.AddChild(pXsd);
- break;
- }
- }
-
- if (m_children.GetCount() == 1)
- {
- ASSERT(IsPattern(m_children[0]));
- sequence.AddChild(m_children[0]);
- }
-
- CpdXsdIfFailGo(sequence.Validate(pElement, pResult));
-
- for(COUNT_T i = 0; i < m_attributes.GetCount(); i++)
- CpdXsdIfFailGo(m_attributes[i]->Validate(pElement, pResult));
-
- MDA_XSD_VERIFY_OK;
- MDA_XSD_VERIFY_FAIL;
-}
-
-BOOL MdaSchema::MdaSchemaElementRefType::Validate(MdaXmlElement* pElement, ValidationResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- CpdXsdIfFailGo(GetRef()->Validate(pElement, pResult));
-
- MDA_XSD_VERIFY_OK;
- MDA_XSD_VERIFY_FAIL;
-}
-
-BOOL MdaSchema::MdaSchemaElementAny::Validate(MdaXmlElement* pElement, ValidationResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString buffer;
- LPCWSTR debug = pElement->DebugToString(&buffer);
-
- CpdXsdTest(pElement->GetDeclDef() == GetDeclDef());
-
- MDA_XSD_VERIFY_OK;
- MDA_XSD_VERIFY_FAIL;
-}
-
-BOOL MdaSchema::MdaSchemaElementRef::Validate(MdaXmlElement* pElement, ValidationResult* pResult)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- LPCWSTR debug = GetRefName();
- CpdXsdIfFailGo(GetRef()->Validate(pElement, pResult));
-
- MDA_XSD_VERIFY_OK;
- MDA_XSD_VERIFY_FAIL;
-}
-
-
-//
-// MdaSchema::XXX::SetAttributes()
-//
-
-void MdaSchema::MdaSchemaSequence::SetAttributes(MdaXmlElement* pXml)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- SmallStackSString ssBound;
-
- ssBound.Printf(W("%d"), m_min);
- pXml->AddAttributeSz(MdaAttrDecl(MinOccurs), ssBound.GetUnicode());
-
- if (m_max == -1)
- {
- pXml->AddAttributeSz(MdaAttrDecl(MaxOccurs), W("unbounded"));
- }
- else
- {
- ssBound.Printf(W("%d"), m_max);
- pXml->AddAttributeSz(MdaAttrDecl(MaxOccurs), ssBound.GetUnicode());
- }
-}
-
-void MdaSchema::MdaSchemaAttribute::SetAttributes(MdaXmlElement* pXml)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- pXml->AddAttributeSz(MdaAttrDecl(Name), GetAttributeName(m_declDef));
-
- LPCWSTR szType = NULL;
- if (m_type == MdaSchemaPrimitiveBOOL)
- szType = W("xs:boolean");
- else if (m_type == MdaSchemaPrimitiveINT32)
- szType = W("xs:int");
- else if (m_type == MdaSchemaPrimitiveSString)
- szType = W("xs:string");
- else { UNREACHABLE(); }
-
- pXml->AddAttributeSz(MdaAttrDecl(Type), szType);
- pXml->AddAttributeSz(MdaAttrDecl(Use), m_bRequired ? W("required") : W("optional"));
-
- if (!m_szDefault.IsEmpty())
- pXml->AddAttributeSz(MdaAttrDecl(Default), m_szDefault);
-}
-
-void MdaSchema::MdaSchemaDeclDefRef::SetAttributes(MdaXmlElement* pXml)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- LPCWSTR szDeclDef = NULL;
- LPCWSTR szRef = NULL;
-
- if (IsDeclDef(this))
- szDeclDef = GetDeclDefName();
-
- if (IsRef(this))
- szRef = GetRefName();
-
- switch (GetSchemaType())
- {
- case MdaSchemaGroupRefType:
- case MdaSchemaElementRefTyp:
- pXml->AddAttributeSz(MdaAttrDecl(Ref), szRef);
- break;
-
- case MdaSchemaExtensionType:
- pXml->AddAttributeSz(MdaAttrDecl(Base), szRef);
- break;
-
- case MdaSchemaElementRefTypeType:
- pXml->AddAttributeSz(MdaAttrDecl(Name), szDeclDef);
- pXml->AddAttributeSz(MdaAttrDecl(Type), szRef);
- break;
-
- case MdaSchemaElementAnyType:
- pXml->AddAttributeSz(MdaAttrDecl(Name), szDeclDef);
- pXml->AddAttributeSz(MdaAttrDecl(Type), W("xs:anyType"));
- break;
-
- case MdaSchemaGroupType:
- case MdaSchemaElementType:
- case MdaSchemaComplexTypeDefType:
- pXml->AddAttributeSz(MdaAttrDecl(Name), szDeclDef);
- break;
-
- default:
- UNREACHABLE();
- }
-}
-
-//
-// MdaAssistant
-//
-void MdaAssistant::Initialize(MdaXmlElement* pXmlInput)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (pXmlInput->GetAttribute(MdaAttrDecl(SuppressDialog)))
- m_bSuppressDialog = !!pXmlInput->GetAttributeValueAsBool(MdaAttrDecl(SuppressDialog));
-}
-
-LPCWSTR MdaAssistant::GetName()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return MdaSchema::GetElementName(m_assistantDeclDef);
-}
-
-MdaXmlElement* MdaAssistant::GetRootElement(MdaXmlElement* pRoot, BOOL bBreak)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- MdaXmlElement* pXmlAssistant = pRoot->AddChild(GetAssistantMsgDeclDef());
-
- if (bBreak)
- pXmlAssistant->AddAttributeSz(MdaAttrDecl(Break), W("true"));
-
- return pXmlAssistant;
-}
-
-BOOL MdaAssistant::IsAssistantActive(MdaXmlElement* pXml)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return TRUE;
-}
-
-MdaXmlElement* MdaAssistant::OutputThread(Thread* pThread, MdaXmlElement* pXml)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- _ASSERTE(pThread);
- pXml->AddAttributeInt(MdaAttrDecl(OsId), pThread->GetOSThreadId());
- pXml->AddAttributeInt(MdaAttrDecl(ManagedId), pThread->GetThreadId());
-
- return pXml;
-}
-
-MdaXmlElement* MdaAssistant::OutputMethodTable(MethodTable* pMT, MdaXmlElement* pXml)
-{
- CONTRACT (MdaXmlElement*)
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pMT));
- PRECONDITION(CheckPointer(pXml));
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- static WCHAR szTemplateMsg[] = {W("Failed to QI for interface %s because it does not have a COM proxy stub registered.")};
-
- DefineFullyQualifiedNameForClassWOnStack();
- pXml->AddAttributeSz(MdaAttrDecl(Name), GetFullyQualifiedNameForClassW(pMT));
-
- RETURN pXml;
-}
-
-void MdaAssistant::ToString(TypeHandle typeHandle, SString* psszFullname, SString* psszNamespace)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString ssz;;
-
- psszFullname->Clear();
-
- LPCSTR szDeclTypeName, szNamespace;
- InlineSArray<mdTypeDef, 32> nesting;
-
- mdTypeDef tkTypeDef = typeHandle.GetCl();
- Module* pModule = typeHandle.GetModule();
- IMDInternalImport* pImport = pModule->GetMDImport();
-
- // Get tkTypeDef tokens for declaring type and its nested classes
- nesting.Append(tkTypeDef);
- while (S_OK == pImport->GetNestedClassProps(tkTypeDef, &tkTypeDef))
- nesting.Append(tkTypeDef);
-
- // Append the namespace
- COUNT_T i = nesting.GetCount() - 1;
- if (FAILED(pImport->GetNameOfTypeDef(nesting[i], &szDeclTypeName, &szNamespace)))
- {
- szNamespace = NULL;
- szDeclTypeName = NULL;
- }
- if (szNamespace && *szNamespace != W('\0'))
- {
- if (psszNamespace)
- psszNamespace->SetUTF8(szNamespace);
-
- psszFullname->SetUTF8(szNamespace);
- psszFullname->Append(W("."));
- }
-
- // Append the nested classes
- for(; i > 0; i --)
- {
- IfFailThrow(pImport->GetNameOfTypeDef(nesting[i], &szDeclTypeName, &szNamespace));
- ssz.SetUTF8(szDeclTypeName);
- psszFullname->Append(ssz);
- psszFullname->Append(W("+"));
- }
-
- // Append the declaring type name
- IfFailThrow(pImport->GetNameOfTypeDef(nesting[i], &szDeclTypeName, &szNamespace));
- ssz.SetUTF8(szDeclTypeName);
- psszFullname->Append(ssz);
-}
-
-SString& MdaAssistant::ToString(SString& sszBuffer, Module* pModule)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- sszBuffer.AppendUTF8(pModule->GetSimpleName());
- return sszBuffer;
-}
-
-SString& MdaAssistant::ToString(SString& sszBuffer, TypeHandle typeHandle)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString sszScratch;
- ToString(sszBuffer, typeHandle.GetModule()).GetUnicode();
- sszBuffer.Append(W("!"));
- ToString(typeHandle, &sszScratch, NULL);
- sszBuffer.Append(sszScratch);
- return sszBuffer;
-}
-
-SString& MdaAssistant::ToString(SString& sszBuffer, MethodDesc* pMethodDesc)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- ToString(sszBuffer, pMethodDesc->GetMethodTable()).GetUnicode();
- sszBuffer.Append(W("::"));
- StackSString ssz;
- ssz.SetUTF8(pMethodDesc->GetName());
- sszBuffer.Append(ssz);
- return sszBuffer;
-}
-
-SString& MdaAssistant::ToString(SString& sszBuffer, FieldDesc* pFieldDesc)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- ToString(sszBuffer, pFieldDesc->GetEnclosingMethodTable()).GetUnicode();
- sszBuffer.Append(W("::"));
- StackSString ssz;
- ssz.SetUTF8(pFieldDesc->GetName());
- sszBuffer.Append(ssz);
- return sszBuffer;
-}
-
-MdaXmlElement* MdaAssistant::OutputParameter(SString parameterName, USHORT sequence, MethodDesc* pMethodDesc, MdaXmlElement* pXml)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- TypeHandle declType(pMethodDesc->GetMethodTable());
- Module* pDeclModule = declType.GetModule();
-
- pXml->AddAttributeSz(MdaAttrDecl(Name), parameterName);
- pXml->AddAttributeInt(MdaAttrDecl(Index), sequence);
-
- OutputMethodDesc(pMethodDesc, pXml->AddChild(MdaElemDecl(DeclaringMethod)));
-
- return pXml;
-}
-
-MdaXmlElement* MdaAssistant::OutputMethodDesc(MethodDesc* pMethodDesc, MdaXmlElement* pXml)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- TypeHandle declType(pMethodDesc->GetMethodTable());
- Module* pDeclModule = declType.GetModule();
-
- StackSString sszMethod;
-
- pXml->AddAttributeSz(MdaAttrDecl(Name), ToString(sszMethod, pMethodDesc).GetUnicode());
-
- return pXml;
-}
-
-MdaXmlElement* MdaAssistant::OutputFieldDesc(FieldDesc* pFieldDesc, MdaXmlElement* pXml)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString sszField;
-
- pXml->AddAttributeSz(MdaAttrDecl(Name), ToString(sszField, pFieldDesc).GetUnicode());
-
- return pXml;
-}
-
-MdaXmlElement* MdaAssistant::OutputTypeHandle(TypeHandle typeHandle, MdaXmlElement* pXml)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString sszTypeName;
-
- // Set Attribute
- pXml->AddAttributeSz(MdaAttrDecl(Name), ToString(sszTypeName, typeHandle.GetMethodTable()).GetUnicode());
-
- return pXml;
-}
-
-MdaXmlElement* MdaAssistant::OutputModule(Module* pModule, MdaXmlElement* pXml)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- pXml->AddAttributeSz(MdaAttrDecl(Name), pModule->GetSimpleName());
-
- return pXml;
-}
-
-MdaXmlElement* MdaAssistant::OutputCallsite(MethodDesc *pMethodDesc, DWORD dwOffset, MdaXmlElement* pXml)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString sszMethod;
- pXml->AddAttributeSz(MdaAttrDecl(Name), ToString(sszMethod, pMethodDesc).GetUnicode());
-
- StackSString sszOffset;
- sszOffset.Printf(W("0x%04X"), dwOffset);
- pXml->AddAttributeSz(MdaAttrDecl(Offset), sszOffset.GetUnicode());
-
- return pXml;
-}
-
-MdaXmlElement* MdaAssistant::OutputException(OBJECTREF *pExceptionObj, MdaXmlElement* pXml)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- OutputTypeHandle((*pExceptionObj)->GetTypeHandle(), pXml->AddChild(MdaElemDecl(Type)));
-
- StackSString message;
- GetExceptionMessage(*pExceptionObj, message);
-
- pXml->AddAttributeSz(MdaAttrDecl(Message), message);
-
- return pXml;
-}
-
-//
-// MdaQuery::CompiledQueries
-//
-BOOL MdaQuery::CompiledQueries::Test(MethodDesc* pMethodDesc)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- for (COUNT_T i = 0; i < m_queries.GetCount(); i ++)
- {
- if (m_queries[i]->Test(pMethodDesc))
- return TRUE;
- }
-
- return FALSE;
-}
-
-BOOL MdaQuery::CompiledQueries::Test(FieldDesc* pFieldDesc)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- for (COUNT_T i = 0; i < m_queries.GetCount(); i ++)
- {
- if (m_queries[i]->Test(pFieldDesc))
- return TRUE;
- }
-
- return FALSE;
-}
-
-BOOL MdaQuery::CompiledQueries::Test(MethodTable* pMethodTable)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- for (COUNT_T i = 0; i < m_queries.GetCount(); i ++)
- {
- if (m_queries[i]->Test(pMethodTable))
- return TRUE;
- }
-
- return FALSE;
-}
-
-MdaQuery::CompiledQuery* MdaQuery::CompiledQueries::AddQuery()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- CompiledQuery* pQuery = m_factory.Create();
- m_queries.Append(pQuery);
- return pQuery;
-}
-
-
-//
-// MdaQuery::CompiledQuery
-//
-void MdaQuery::Compile(MdaXmlElement* pXmlFilters, CompiledQueries* pCompiledQueries)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- SArray<MdaXmlElement*>& children = pXmlFilters->GetChildren();
- BOOL bJmc = pXmlFilters->GetAttribute(MdaAttrDecl(JustMyCode))->GetValueAsBool();
-
- for (COUNT_T i = 0; i < children.GetCount(); i ++)
- {
- MdaXmlElement* pXmlFilter = children[i];
- SString* psszName = pXmlFilter->GetAttribute(MdaAttrDecl(Name))->GetValueAsCSString();
- MdaXmlAttribute* pJmcOptAttr = pXmlFilter->GetAttribute(MdaAttrDecl(JustMyCode));
- if (pJmcOptAttr)
- bJmc = pJmcOptAttr->GetValueAsBool();
- Compiler compiler;
- CompiledQuery* pQuery = pCompiledQueries->AddQuery();
- compiler.Compile(psszName, pQuery);
- if (bJmc)
- pQuery->SetJustMyCode();
- }
-}
-
-MdaQuery::CompiledQuery::CompiledQuery()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- m_bJustMyCode = FALSE;
- m_bAnyMember = FALSE;
- m_bAnyType = FALSE;
- m_sszFullname.Clear();
- m_sszMember.Clear();
-}
-
-BOOL StartsWith(SString* psszString, SString* psszSubstring)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString sszString(*psszString);
- if (psszString->GetCount() < psszSubstring->GetCount())
- return FALSE;
- sszString.Truncate(sszString.Begin() + psszSubstring->GetCount());
- return sszString.Equals(*psszSubstring);
-}
-
-BOOL MdaQuery::CompiledQuery::Test(MethodDesc* pMethodDesc)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString sszName(SString::Utf8, pMethodDesc->GetName());
-
- if (pMethodDesc->IsLCGMethod() || pMethodDesc->IsILStub())
- return FALSE;
-
- if (!Test(&sszName, pMethodDesc->GetMethodTable()))
- return FALSE;
-
- if (!m_bJustMyCode)
- return TRUE;
-
- if (IsJustMyCode(pMethodDesc))
- return TRUE;
-
- return FALSE;
-}
-
-BOOL MdaQuery::CompiledQuery::Test(FieldDesc* pFieldDesc)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- StackSString sszName(SString::Utf8, pFieldDesc->GetName());
- if (!Test(&sszName, pFieldDesc->GetApproxEnclosingMethodTable()))
- return FALSE;
-
- if (!m_bJustMyCode)
- return TRUE;
-
- return TRUE;
-}
-
-BOOL MdaQuery::CompiledQuery::Test(SString* psszName, MethodTable* pMethodTable)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (!m_sszMember.IsEmpty())
- {
- if (!m_sszMember.Equals(*psszName))
- return FALSE;
-
- if (m_sszMember.GetCount() == m_sszFullname.GetCount())
- return TRUE;
- }
- else if (!m_bAnyMember)
- return FALSE;
-
- return Test(pMethodTable);
-}
-
-BOOL MdaQuery::CompiledQuery::Test(MethodTable* pMethodTable)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (!pMethodTable)
- return FALSE;
-
- if (m_sszFullname.IsEmpty())
- return TRUE;
-
- StackSString sszNamespace, sszFullName;
- MdaAssistant::ToString(pMethodTable, &sszFullName, &sszNamespace);
-
- if (m_bAnyType && StartsWith(&m_sszFullname, &sszNamespace))
- return TRUE;
-
- if (m_bAnyMember && StartsWith(&m_sszFullname, &sszFullName))
- return TRUE;
-
- return m_sszFullname.Equals(sszFullName);
-}
-
-void MdaQuery::CompiledQuery::SetName(LPCWSTR name)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (!m_sszFullname.IsEmpty())
- {
- m_sszFullname.Append(W("."));
- m_sszMember.Clear();
- }
- else
- {
- m_sszMember.Set(name);
- }
-
- m_sszFullname.Append(name);
-
-}
-
-void MdaQuery::CompiledQuery::SetNestedTypeName(LPCWSTR name)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- m_sszMember.Clear();
-
- if (!m_sszFullname.IsEmpty())
- m_sszFullname.Append(W("+"));
-
- m_sszFullname.Append(name);
-}
-
-void MdaQuery::CompiledQuery::SetAnyMember()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- m_bAnyMember = TRUE;
- m_sszMember.Clear();
-}
-
-void MdaQuery::CompiledQuery::SetAnyType()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- m_bAnyType = TRUE;
- m_sszMember.Clear();
-
- if (m_sszFullname.IsEmpty())
- m_bAnyMember = TRUE;
-}
-
-
-//
-// MdaQuery::CompiledQuery
-//
-
-MdaQuery::Compiler::Token MdaQuery::Compiler::LexAToken()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (*m_itr == W('\0'))
- return MdaFilterEnd;
-
- if (ISWHITE(*m_itr))
- {
- m_itr++;
- return LexAToken();
- }
-
- if (ISMDAID(*m_itr))
- {
- m_identifier.Clear();
-
- do
- {
- m_identifier.Append(*m_itr);
- m_itr++;
- }
- while(ISMDAID(*m_itr));
-
- m_identifier.Append(W("\0"));
- return MdaFilterIdentifier;
- }
-
- WCHAR c = *m_itr;
- m_itr++;
- switch(c)
- {
- case W('.'): return MdaFilterDot;
- case W(':'): return MdaFilterColon;
- case W('*'): return MdaFilterAstrix;
- case W('+'): return MdaFilterPlus;
- }
-
- return MdaFilterEnd;
-}
-
-//
-// MdaXPath::MdaXPathCompiler -- Parser
-//
-BOOL MdaQuery::Compiler::Compile(SString* sszQuery, CompiledQuery* pAst)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- m_itr = sszQuery->Begin();
-
- NextToken();
- BOOL bResult = NAME(pAst);
-
- return bResult;
-}
-
-// NAME
-// '*'
-// id
-// id '.' NAME
-// id '+' NESTNAME
-// id ':' ':' NESTNAME
-BOOL MdaQuery::Compiler::NAME(CompiledQuery* pAst)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (TokenIs(MdaFilterIdentifier))
- {
- pAst->SetName(GetIdentifier());
-
- NextToken();
- if (TokenIs(MdaFilterDot))
- {
- NextToken();
- return NAME(pAst);
- }
- else if (TokenIs(MdaFilterPlus))
- {
- NextToken();
- return NESTNAME(pAst);
- }
- else if (TokenIs(MdaFilterColon))
- {
- NextToken();
- if (!TokenIs(MdaFilterColon))
- return FALSE;
-
- NextToken();
- return MEMBERNAME(pAst);
- }
- }
- else if (TokenIs(MdaFilterAstrix))
- {
- pAst->SetAnyType();
- NextToken();
- }
- else return FALSE;
-
- return TRUE;
-}
-
-// NESTNAME
-// id '+' NESTNAME
-// id ':' ':' NESTNAME
-BOOL MdaQuery::Compiler::NESTNAME(CompiledQuery* pAst)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (!TokenIs(MdaFilterIdentifier))
- return FALSE;
-
- pAst->SetNestedTypeName(GetIdentifier());
-
- NextToken();
-
- if (TokenIs(MdaFilterPlus))
- {
- NextToken();
- return NESTNAME(pAst);
- }
- else if (TokenIs(MdaFilterColon))
- {
- NextToken();
- if (!TokenIs(MdaFilterColon))
- return FALSE;
-
- NextToken();
- return MEMBERNAME(pAst);
- }
- else return FALSE;
-}
-
-// MEMBERNAME
-// '*'
-// id
-BOOL MdaQuery::Compiler::MEMBERNAME(CompiledQuery* pAst)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (TokenIs(MdaFilterIdentifier))
- pAst->SetMemberName(GetIdentifier());
-
- else if (TokenIs(MdaFilterAstrix))
- pAst->SetAnyMember();
-
- else return FALSE;
-
- NextToken();
- return TRUE;
-}
-
-
-//
-// MdaXmlElement
-//
-MdaXmlElement* MdaXmlElement::GetChild(MdaElemDeclDef declDef)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- for(COUNT_T i = 0; i < m_children.GetCount(); i ++)
- {
- if (m_children[i]->GetDeclDef() == declDef)
- return m_children[i];
- }
-
- return NULL;
-}
-
-SString* MdaXmlElement::ToXml(SString* pXml, LPCWSTR ns, INT32 depth)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(depth < 60); // Trap for recursion
- }
- CONTRACTL_END;
-
- // Indent
- for (INT32 i = 0; i < depth; i ++)
- pXml->Append(W(" "));
-
- pXml->Append(W("<"));
- if (ns && IsDefinition()) { pXml->Append(ns); pXml->Append(W(":")); }
- pXml->Append(GetName());
-
- if (m_attributes.GetCount() != 0)
- {
- for (COUNT_T i = 0; i < m_defaultAttrIndex && i < m_attributes.GetCount(); i ++)
- {
- pXml->Append(W(" "));
- m_attributes[i]->ToXml(pXml);
- }
- }
-
- if (m_children.GetCount() == 0)
- {
- if (GetDeclDef() == MdaElemComment)
- {
- pXml->Append(W(" "));
- pXml->Append(m_szName.GetUnicode());
- pXml->Append(W(" -->\n"));
- }
- else
- pXml->Append(W("/>\n"));
- }
- else
- {
- pXml->Append(W(">"));
-
- SArray<MdaXmlElement*>::Iterator itr = m_children.Begin();
- SArray<MdaXmlElement*>::Iterator end = m_children.End();
-
- pXml->Append(W("\n"));
- while (itr != end)
- {
- (*itr)->ToXml(pXml, ns, depth + 1);
- itr++;
- }
-
- // Indent
- for (INT32 i = 0; i < depth; i ++)
- pXml->Append(W(" "));
-
- pXml->Append(W("</"));
- if (ns && IsDefinition()) { pXml->Append(ns); pXml->Append(W(":")); }
- pXml->Append(GetName());
- pXml->Append(W(">\n"));
- }
-
-
- return pXml;
-}
-
-LPCWSTR MdaXmlElement::DebugToString(SString* pBuffer)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- pBuffer->Append(W("<"));
- pBuffer->Append(GetName());
-
- for(COUNT_T i = 0; i < GetAttributes().GetCount(); i++)
- {
- pBuffer->Append(W(" "));
- GetAttributes()[i]->ToXml(pBuffer);
- }
-
- pBuffer->Append(W("/>"));
- return pBuffer->GetUnicode();
-}
-
-MdaXmlElement* MdaXmlElement::SetName(LPCWSTR name, BOOL bAssertDefined)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- SetDeclDef(MdaSchema::GetElementType(name, bAssertDefined));
-
- if (GetDeclDef() == MdaElemUndefined)
- m_szName.Set(name);
-
- return this;
-}
-
-MdaXmlAttribute* MdaXmlElement::AddAttribute(MdaAttrDeclDef declDef)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return AddAttribute(m_pXmlIndustry->CreateAttribute()->SetDeclDef(declDef));
-}
-
-MdaXmlAttribute* MdaXmlElement::AddAttribute(LPCWSTR szName, LPCWSTR szValue)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return AddAttribute(m_pXmlIndustry->CreateAttribute()->Initialize(szName, szValue));
-}
-
-MdaXmlAttribute* MdaXmlElement::AddDefaultAttribute(MdaAttrDeclDef attrDeclDef, LPCWSTR szValue)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (m_defaultAttrIndex == -1)
- m_defaultAttrIndex = m_attributes.GetCount();
- MdaXmlAttribute* pAttr = AddAttribute(attrDeclDef)->SetSString(szValue);
- pAttr->m_type = MdaSchemaPrimitiveUnknown;
- return pAttr;
-}
-
-MdaXmlElement* MdaXmlElement::AddChild(MdaXmlElement* pChild)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- //PRECONDITION(m_elemDeclDef != MdaElemUndefined);
- PRECONDITION(CheckPointer(pChild));
- PRECONDITION(CheckPointer(pChild->m_pXmlIndustry));
-
- *m_children.Append() = pChild;
- return pChild;
-}
-
-MdaXmlElement* MdaXmlElement::AddChild(LPCWSTR name, BOOL bAssertDefined)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return AddChild(m_pXmlIndustry->CreateElement())->SetName(name, bAssertDefined);
-}
-
-MdaXmlElement* MdaXmlElement::AddChild(MdaElemDeclDef type)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return AddChild(m_pXmlIndustry->CreateElement()->SetDeclDef(type));
-}
-
-LPCWSTR MdaXmlElement::GetName()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (GetDeclDef() == MdaElemUndefined)
- return m_szName.GetUnicode();
-
- return MdaSchema::GetElementName(m_elemDeclDef);
-}
-
-MdaXmlAttribute* MdaXmlElement::GetAttribute(MdaAttrDeclDef attrDeclDef)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
-
- for(UINT32 i = 0; i < m_attributes.GetCount(); i++)
- {
- if (attrDeclDef == m_attributes[i]->GetDeclDef())
- return m_attributes[i];
- }
-
- return NULL;
-}
-
-BOOL MdaXmlElement::GetAttributeValueAsBool(MdaAttrDeclDef attrDeclDef, BOOL bDefault)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- MdaXmlAttribute* pAttr = GetAttribute(attrDeclDef);
-
- if (!pAttr)
- return bDefault;
-
- return pAttr->GetValueAsBool();
-}
-
-BOOL MdaXmlElement::GetAttributeValueAsBool(MdaAttrDeclDef attrDeclDef)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- MdaXmlAttribute* pAttr = GetAttribute(attrDeclDef);
- PREFIX_ASSUME(pAttr != NULL);
- ASSERT(pAttr);
- return pAttr->GetValueAsBool();
-}
-
-//
-// MdaXmlAttribute
-//
-
-SString* MdaXmlAttribute::ToXml(SString* xml)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- SString sszBuffer;
-
- xml->Append(GetName());
- if (!m_szNs.IsEmpty())
- {
- xml->Append(W(":"));
- xml->Append(m_szNs.GetUnicode());
- }
-
- xml->Append(W("=\""));
- if (m_type == MdaSchemaPrimitiveSString)
- xml->Append(MdaXmlEscape(sszBuffer, m_value));
- else if (m_type == MdaSchemaPrimitiveBOOL)
- xml->Append(m_bool ? W("true") : W("false"));
- else if (m_type == MdaSchemaPrimitiveINT32)
- {
- StackSString sszOutput;
- sszOutput.Printf(W("%d"), m_int);
- xml->Append(sszOutput);
- }
- xml->Append(W("\""));
- return xml;
-}
-
-LPCWSTR MdaXmlAttribute::GetName()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (m_declDef != MdaAttrUndefined)
- return MdaSchema::GetAttributeName(m_declDef);
-
- return m_szName.GetUnicode();
-}
-
-MdaXmlAttribute* MdaXmlAttribute::Initialize(LPCWSTR szName, LPCWSTR szValue)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- m_type = MdaSchemaPrimitiveUnknown;
- m_value.Set(szValue);
-
- SetDeclDef(MdaSchema::GetAttributeType(szName, FALSE));
- if (m_declDef == MdaAttrUndefined)
- m_szName.Set(szName);
-
- return this;
-}
-
-
-//
-// MdaConfigFactory
-//
-STDAPI GetXMLObjectEx(IXMLParser **ppv);
-
-MdaXmlElement* MdaConfigFactory::ParseXmlStream(MdaXmlIndustry* pXmlIndustry, LPCWSTR pszFileName)
-{
- CONTRACT(MdaXmlElement*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACT_END;
-
- HRESULT hr = S_OK;
- MdaXmlElement* pRoot = NULL;
-
- EX_TRY
- {
- {
- if (!pszFileName)
- goto Exit;
-
- NonVMComHolder<IXMLParser> pIXMLParser(NULL);
- NonVMComHolder<IStream> pFile(NULL);
-
- hr = CreateConfigStream(pszFileName, &pFile);
- if(FAILED(hr)) goto Exit;
-
- hr = GetXMLObjectEx(&pIXMLParser);
- if(FAILED(hr)) goto Exit;
-
- hr = pIXMLParser->SetInput(pFile); // filestream's RefCount=2
- if ( ! SUCCEEDED(hr))
- goto Exit;
-
- pRoot = pXmlIndustry->CreateElement()->SetDeclDef(MdaElemDef(Dummy));
- MdaConfigFactory mdaConfigFactory(pRoot);
-
- hr = pIXMLParser->SetFactory(&mdaConfigFactory); // factory's RefCount=2
- if (!SUCCEEDED(hr))
- goto Exit;
-
- hr = pIXMLParser->Run(-1);
-
- if (pRoot->GetChildren().GetCount() == 1)
- pRoot = pRoot->GetChildren()[0];
- else
- pRoot = NULL;
- }
- Exit: ;
- }
- EX_CATCH
- {
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- if (hr == (HRESULT)XML_E_MISSINGROOT)
- hr = S_OK;
- else if (Assembly::FileNotFound(hr))
- hr = S_FALSE;
-
- RETURN pRoot;
-}
-
-HRESULT STDMETHODCALLTYPE MdaConfigFactory::CreateNode(
- IXMLNodeSource* pSource,
- PVOID pNodeParent,
- USHORT cNumRecs,
- XML_NODE_INFO** apNodeInfo)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- m_pMdaXmlElement = NULL;
-
- for(INT32 i = 0; i < cNumRecs; i++)
- {
- DWORD dwType = apNodeInfo[i]->dwType;
-
- if(dwType == XML_ELEMENT || dwType == XML_ATTRIBUTE)
- {
- StackSString sszName((WCHAR*)apNodeInfo[i]->pwcText, apNodeInfo[i]->ulLen);
-
- if (dwType == XML_ELEMENT)
- {
- m_pMdaXmlElement = m_stack.Tos()->AddChild(sszName, FALSE);
- }
- else if (dwType == XML_ATTRIBUTE)
- {
- i++;
- InlineSString<MDA_BUFFER_SIZE> szValue((WCHAR*)apNodeInfo[i]->pwcText, apNodeInfo[i]->ulLen);
-
- if (m_pMdaXmlElement)
- m_pMdaXmlElement->AddAttribute(sszName.GetUnicode(), szValue);
- }
- }
- }
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE MdaConfigFactory::BeginChildren(
- IXMLNodeSource* pSource,
- XML_NODE_INFO* pNodeInfo)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- m_stack.Push(m_pMdaXmlElement);
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE MdaConfigFactory::EndChildren(
- IXMLNodeSource* pSource,
- BOOL fEmptyNode,
- XML_NODE_INFO* pNodeInfo)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
-
- if (fEmptyNode)
- return S_OK;
-
- m_stack.Pop();
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE MdaConfigFactory::NotifyEvent(
- IXMLNodeSource* pSource,
- XML_NODEFACTORY_EVENT iEvt)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE MdaConfigFactory::Error(
- IXMLNodeSource* pSource,
- HRESULT hrErrorCode,
- USHORT cNumRecs,
- XML_NODE_INFO** apNodeInfo)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return E_FAIL;
-}
-
-#endif
diff --git a/src/vm/mda.h b/src/vm/mda.h
index b52bd00d42..c711e8ae7f 100644
--- a/src/vm/mda.h
+++ b/src/vm/mda.h
@@ -295,7 +295,6 @@ private:
friend class MdaXmlMessage;
friend class MdaXmlIndustry;
friend class MdaConfigFactory;
- friend class EEConfigFactory;
friend class MdaFramework;
friend void EEStartupHelper(COINITIEE fFlags);
diff --git a/src/vm/mdaassistants.cpp b/src/vm/mdaassistants.cpp
index e52e8ff8ec..eb9a448a3a 100644
--- a/src/vm/mdaassistants.cpp
+++ b/src/vm/mdaassistants.cpp
@@ -139,7 +139,6 @@ void TriggerGCForMDAInternal()
{
GCHeapUtilities::GetGCHeap()->GarbageCollect();
-#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
//
// It is very dangerous to wait for finalizer thread here if we are inside a wait
// operation, as the wait operation might call into interop which calls this MDA
@@ -150,7 +149,6 @@ void TriggerGCForMDAInternal()
// So, if we are inside a SyncContext.Wait, don't call out to FinalizerThreadWait
//
if (!GetThread()->HasThreadStateNC(Thread::TSNC_InsideSyncContextWait))
-#endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
// It is possible that user code run as part of finalization will wait for this thread.
// To avoid deadlocks, we limit the wait time to 10 seconds (an arbitrary number).
FinalizerThread::FinalizerThreadWait(10 * 1000);
diff --git a/src/vm/mdadac.cpp b/src/vm/mdadac.cpp
deleted file mode 100644
index 95be6bff60..0000000000
--- a/src/vm/mdadac.cpp
+++ /dev/null
@@ -1,48 +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 "common.h"
-#include "mda.h"
-#include "mdaassistants.h"
-#include "sstring.h"
-#include "daccess.h"
-
-#ifdef MDA_SUPPORTED
-MdaStaticHeap g_mdaStaticHeap =
-{
- { 0 }, // m_assistants[]
- 0, // m_pMda
- { 0 }, // m_mda[]
-
-#define MDA_ASSISTANT_STATIC_INIT
-#include "mdaschema.inl"
-#undef MDA_ASSISTANT_STATIC_INIT
-};
-
-
-//
-// MdaManagedDebuggingAssistants
-//
-void ManagedDebuggingAssistants::AllocateManagedDebuggingAssistants()
-{
- WRAPPER_NO_CONTRACT;
- g_mdaStaticHeap.m_pMda = new (&g_mdaStaticHeap.m_mda) ManagedDebuggingAssistants();
-}
-
-ManagedDebuggingAssistants::ManagedDebuggingAssistants()
-{
- WRAPPER_NO_CONTRACT;
-
-#ifndef DACCESS_COMPILE
- Initialize();
-#endif
-}
-#endif // MDA_SUPPORTED
-
-
-
-
-
-
diff --git a/src/vm/memberload.cpp b/src/vm/memberload.cpp
index 1b24300a68..d19a4f6d61 100644
--- a/src/vm/memberload.cpp
+++ b/src/vm/memberload.cpp
@@ -35,9 +35,6 @@
#include "dbginterface.h"
#include "comdelegate.h"
#include "sigformat.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "eeprofinterfaces.h"
#include "dllimportcallback.h"
#include "listlock.h"
@@ -49,9 +46,6 @@
#include "virtualcallstub.h"
#include "eeconfig.h"
#include "contractimpl.h"
-#ifdef FEATURE_REMOTING
-#include "objectclone.h"
-#endif
#include "listlock.inl"
#include "generics.h"
#include "instmethhash.h"
diff --git a/src/vm/message.cpp b/src/vm/message.cpp
deleted file mode 100644
index 093f9a2629..0000000000
--- a/src/vm/message.cpp
+++ /dev/null
@@ -1,1171 +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.
-
-/*============================================================
-**
-** File: message.cpp
-**
-** Purpose: Encapsulates a function call frame into a message
-** object with an interface that can enumerate the
-** arguments of the message
-**
-**
-
-===========================================================*/
-#include "common.h"
-
-#ifdef FEATURE_REMOTING
-
-#include "comdelegate.h"
-#include "excep.h"
-#include "message.h"
-#include "remoting.h"
-#include "field.h"
-#include "eeconfig.h"
-#include "invokeutil.h"
-#include "callingconvention.h"
-
-//+----------------------------------------------------------------------------
-//
-// Method: CMessage::GetArgCount public
-//
-// Synopsis: Returns number of arguments in the method call
-//
-//+----------------------------------------------------------------------------
-FCIMPL1(INT32, CMessage::GetArgCount, MessageObject * pMessage)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(pMessage));
- }
- CONTRACTL_END;
-
- LOG((LF_REMOTING, LL_INFO10, "CMessage::GetArgCount IN pMsg:0x%x\n", pMessage));
-
- // Get the frame pointer from the object
- MetaSig *pSig = pMessage->GetResetMetaSig();
-
- // scan the sig for the argument count
- INT32 ret = pSig->NumFixedArgs();
-
- if (pMessage->GetDelegateMD())
- ret -= 2;
-
- LOG((LF_REMOTING, LL_INFO10, "CMessage::GetArgCount OUT ret:0x%x\n", ret));
- return ret;
-}
-FCIMPLEND
-
-//+----------------------------------------------------------------------------
-//
-// Method: CMessage::GetArg public
-//
-// Synopsis: Use to enumerate a call's arguments
-//
-//+----------------------------------------------------------------------------
-FCIMPL2(Object*, CMessage::GetArg, MessageObject* pMessageUNSAFE, INT32 argNum)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(pMessageUNSAFE != NULL);
- }
- CONTRACTL_END;
-
- struct _gc {
- OBJECTREF refRetVal;
- MESSAGEREF pMessage;
- } gc;
-
- gc.refRetVal = NULL;
- gc.pMessage = (MESSAGEREF) pMessageUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
-
- LOG((LF_REMOTING, LL_INFO10, "CMessage::GetArgCount IN\n"));
-
- MetaSig *pSig = gc.pMessage->GetResetMetaSig();
-
- if ((UINT)argNum >= pSig->NumFixedArgs())
- COMPlusThrow(kTargetParameterCountException);
-
- for (INT32 i = 0; i < argNum; i++)
- pSig->NextArg();
-
- BOOL fIsByRef = FALSE;
- CorElementType eType = pSig->NextArg();
- TypeHandle ty = TypeHandle();
- if (eType == ELEMENT_TYPE_BYREF)
- {
- fIsByRef = TRUE;
- TypeHandle tycopy;
- eType = pSig->GetByRefType(&tycopy);
- if (eType == ELEMENT_TYPE_VALUETYPE)
- ty = tycopy;
- }
- else
- {
- if (eType == ELEMENT_TYPE_VALUETYPE)
- {
- ty = pSig->GetLastTypeHandleThrowing();
-
-#ifdef ENREGISTERED_PARAMTYPE_MAXSIZE
- if (ArgIterator::IsArgPassedByRef(ty))
- fIsByRef = TRUE;
-#endif
- }
- }
-
- if (eType == ELEMENT_TYPE_PTR)
- COMPlusThrow(kRemotingException, W("Remoting_CantRemotePointerType"));
-
- GetObjectFromStack(&gc.refRetVal,
- GetStackPtr(argNum, gc.pMessage->GetFrame(), gc.pMessage->GetResetMetaSig()),
- eType,
- ty,
- fIsByRef,
- gc.pMessage->GetFrame());
-
- LOG((LF_REMOTING, LL_INFO10, "CMessage::GetArg OUT\n"));
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(gc.refRetVal);
-}
-FCIMPLEND
-
-FCIMPL1(Object*, CMessage::GetArgs, MessageObject* pMessageUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(pMessageUNSAFE != NULL);
- }
- CONTRACTL_END;
-
- struct _gc {
- PTRARRAYREF refRetVal;
- MESSAGEREF pMessage;
- OBJECTREF arg;
- } gc;
-
- gc.refRetVal = NULL;
- gc.pMessage = (MESSAGEREF) pMessageUNSAFE;
- gc.arg = NULL;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
-
- LOG((LF_REMOTING, LL_INFO10, "CMessage::GetArgCount IN\n"));
-
- MetaSig *pSig = gc.pMessage->GetResetMetaSig();
-
- // scan the sig for the argument count
- INT32 numArgs = pSig->NumFixedArgs();
- if (gc.pMessage->GetDelegateMD())
- numArgs -= 2;
-
- // Allocate an object array
- gc.refRetVal = (PTRARRAYREF) AllocateObjectArray(numArgs, g_pObjectClass);
-
- ArgIterator iter(pSig);
-
- for (int index = 0; index < numArgs; index++)
- {
- BOOL fIsByRef = FALSE;
- CorElementType eType;
- PVOID addr;
- eType = pSig->PeekArg();
- addr = (LPBYTE) gc.pMessage->GetFrame()->GetTransitionBlock() + GetStackOffset(gc.pMessage->GetFrame(), &iter, pSig);
-
- TypeHandle ty = TypeHandle();
- if (eType == ELEMENT_TYPE_BYREF)
- {
- fIsByRef = TRUE;
- TypeHandle tycopy;
- // If this is a by-ref arg, GetObjectFromStack() will dereference "addr" to
- // get the real argument address. Dereferencing now will open a gc hole if "addr"
- // points into the gc heap, and we trigger gc between here and the point where
- // we return the arguments.
- //addr = *((PVOID *) addr);
- eType = pSig->GetByRefType(&tycopy);
- if (eType == ELEMENT_TYPE_VALUETYPE)
- ty = tycopy;
- }
- else
- {
- if (eType == ELEMENT_TYPE_VALUETYPE)
- {
- ty = pSig->GetLastTypeHandleThrowing();
-
-#ifdef ENREGISTERED_PARAMTYPE_MAXSIZE
- if (ArgIterator::IsArgPassedByRef(ty))
- fIsByRef = TRUE;
-#endif
- }
- }
-
- if (eType == ELEMENT_TYPE_PTR)
- COMPlusThrow(kRemotingException, W("Remoting_CantRemotePointerType"));
-
- GetObjectFromStack(&gc.arg,
- addr,
- eType,
- ty,
- fIsByRef,
- gc.pMessage->GetFrame());
-
- gc.refRetVal->SetAt(index, gc.arg);
- }
-
- LOG((LF_REMOTING, LL_INFO10, "CMessage::GetArgs OUT\n"));
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(gc.refRetVal);
-}
-FCIMPLEND
-
-//static
-void CMessage::GetObjectFromStack(OBJECTREF* ppDest, PVOID val, const CorElementType eType, TypeHandle ty, BOOL fIsByRef, FramedMethodFrame *pFrame)
-{
- CONTRACT_VOID
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(ppDest));
- PRECONDITION(CheckPointer(val));
- }
- CONTRACT_END;
-
- // Value types like Nullable<T> have special unboxing semantics,
- //
- if (eType == ELEMENT_TYPE_VALUETYPE)
- {
- //
- // box the value class
- //
-
- _ASSERTE(ty.GetMethodTable()->IsValueType() || ty.GetMethodTable()->IsEnum());
-
- _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsHeapPointer((BYTE *) ppDest) ||
- !"(pDest) can not point to GC Heap");
- MethodTable* pMT = ty.GetMethodTable();
-
- if (pMT->IsByRefLike())
- COMPlusThrow(kRemotingException, W("Remoting_TypeCantBeRemoted"));
-
- PVOID* pVal;
- if (fIsByRef)
- pVal = (PVOID *)val;
- else {
- val = StackElemEndianessFixup(val, pMT->GetNumInstanceFieldBytes());
- pVal = &val;
- }
-
- *ppDest = pMT->FastBox(pVal);
- RETURN;
- }
-
- switch (CorTypeInfo::GetGCType(eType))
- {
- case TYPE_GC_NONE:
- {
- if(ELEMENT_TYPE_PTR == eType)
- {
- COMPlusThrow(kNotSupportedException);
- }
-
- MethodTable *pMT = MscorlibBinder::GetElementType(eType);
-
- OBJECTREF pObj = pMT->Allocate();
- if (fIsByRef)
- val = *((PVOID *)val);
- else
- val = StackElemEndianessFixup(val, CorTypeInfo::Size(eType));
-
- void *pDest = pObj->UnBox();
-
-#ifdef COM_STUBS_SEPARATE_FP_LOCATIONS
- if ( !fIsByRef
- && ( ELEMENT_TYPE_R4 == eType
- || ELEMENT_TYPE_R8 == eType)
- && pFrame
- && !TransitionBlock::IsStackArgumentOffset(static_cast<int>((TADDR) val - pFrame->GetTransitionBlock())))
- {
- if (ELEMENT_TYPE_R4 == eType)
- *(UINT32*)pDest = (UINT32)FPSpillToR4(val);
- else
- *(UINT64*)pDest = (UINT64)FPSpillToR8(val);
- }
- else
-#endif // COM_STUBS_SEPARATE_FP_LOCATIONS
- {
- memcpyNoGCRefs(pDest, val, CorTypeInfo::Size(eType));
- }
-
- *ppDest = pObj;
- }
- break;
- case TYPE_GC_REF:
- if (fIsByRef)
- val = *((PVOID *)val);
- *ppDest = ObjectToOBJECTREF(*(Object **)val);
- break;
- default:
- COMPlusThrow(kRemotingException, W("Remoting_TypeCantBeRemoted"));
- }
-
- RETURN;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CMessage::PropagateOutParameters private
-//
-// Synopsis: Copy back data for in/out parameters and the return value
-//
-//+----------------------------------------------------------------------------
-FCIMPL3(void, CMessage::PropagateOutParameters, MessageObject* pMessageUNSAFE, ArrayBase* pOutPrmsUNSAFE, Object* RetValUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(pMessageUNSAFE != NULL);
- }
- CONTRACTL_END;
-
- struct _gc
- {
- MESSAGEREF pMessage;
- BASEARRAYREF pOutPrms;
- OBJECTREF RetVal;
- OBJECTREF param;
- } gc;
- gc.pMessage = (MESSAGEREF) pMessageUNSAFE;
- gc.pOutPrms = (BASEARRAYREF) pOutPrmsUNSAFE;
- gc.RetVal = (OBJECTREF) RetValUNSAFE;
- gc.param = NULL;
- HELPER_METHOD_FRAME_BEGIN_PROTECT(gc);
-
- LOG((LF_REMOTING, LL_INFO10, "CMessage::PropogateOutParameters IN\n"));
-
- // Retrieve the message's flags.
- INT32 flags = gc.pMessage->GetFlags();
-
- // Construct an ArgIterator from the message's frame and sig.
- MetaSig *pSig = gc.pMessage->GetResetMetaSig();
- FramedMethodFrame *pFrame = gc.pMessage->GetFrame();
- ArgIterator argit(pSig);
-
- // move into object to return to client
-
- // Propagate the return value only if the pMsg is not a Ctor message
- // Check if the return type has a return buffer associated with it
- if ((flags& MSGFLG_CTOR) == 0 && pSig->GetReturnType() != ELEMENT_TYPE_VOID)
- {
- if (argit.HasRetBuffArg())
- {
- // Copy from RetVal into the retBuff.
- INT64 retVal = CopyOBJECTREFToStack(
- *(void**)(pFrame->GetTransitionBlock() + argit.GetRetBuffArgOffset()),
- &gc.RetVal,
- pSig->GetReturnType(),
- TypeHandle(),
- pSig,
- TRUE); // copy class contents
-
- // Copy the return value
- *(ARG_SLOT *)(gc.pMessage->GetFrame()->GetReturnValuePtr()) = retVal;
- }
- else
- {
-#ifdef ENREGISTERED_RETURNTYPE_MAXSIZE
- if (argit.HasNonStandardByvalReturn())
- {
- //
- // in these cases, we put the pointer to the return buffer into the frame's
- // return value slot
- //
- CopyOBJECTREFToStack(gc.pMessage->GetFrame()->GetReturnValuePtr(),
- &gc.RetVal,
- pSig->GetReturnType(),
- TypeHandle(),
- pSig,
- TRUE); // copy class contents
- }
- else
-#endif // ENREGISTERED_RETURNTYPE_MAXSIZE
- {
- // There is no separate return buffer, the retVal should fit in
- // an INT64.
- INT64 retVal = CopyOBJECTREFToStack(
- NULL, //no return buff
- &gc.RetVal,
- pSig->GetReturnType(),
- TypeHandle(),
- pSig,
- FALSE); //don't copy class contents
-
- // Copy the return value
- *(ARG_SLOT *)(gc.pMessage->GetFrame()->GetReturnValuePtr()) = retVal;
- }
- }
- }
-
- // Refetch all the variables as GC could have happened after call to
- // CopyOBJECTREFToStack
- UINT32 cOutParams = (gc.pOutPrms != NULL) ? gc.pOutPrms->GetNumComponents() : 0;
- if (cOutParams > 0)
- {
- PVOID *argAddr;
- UINT32 i = 0;
- MetaSig syncSig(gc.pMessage->GetMethodDesc());
- MetaSig *pSyncSig = NULL;
-
- if (flags & MSGFLG_ENDINVOKE)
- {
- pSyncSig = &syncSig;
- }
-
- for (i=0; i<cOutParams; i++)
- {
- if (pSyncSig)
- {
- CorElementType typ = pSyncSig->NextArg();
- if (typ == ELEMENT_TYPE_END)
- {
- break;
- }
-
- if (typ != ELEMENT_TYPE_BYREF)
- {
- continue;
- }
-
- argAddr = (PVOID *)(pFrame->GetTransitionBlock() + argit.GetNextOffset());
- }
- else
- {
- int ofs = argit.GetNextOffset();
- if (ofs == TransitionBlock::InvalidOffset)
- {
- break;
- }
-
- if (argit.GetArgType() != ELEMENT_TYPE_BYREF)
- {
- continue;
- }
-
- argAddr = (PVOID *)(pFrame->GetTransitionBlock() + ofs);
- }
-
- TypeHandle ty = TypeHandle();
- CorElementType brType = pSig->GetByRefType(&ty);
-
- gc.param = ((OBJECTREF *) gc.pOutPrms->GetDataPtr())[i];
-
- CopyOBJECTREFToStack(
- *argAddr,
- &gc.param,
- brType,
- ty,
- pSig,
- ty.IsNull() ? FALSE : ty.IsValueType());
- }
-
- }
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-INT64 CMessage::CopyOBJECTREFToStack(PVOID pvDest, OBJECTREF *pSrc, CorElementType typ, TypeHandle ty, MetaSig *pSig, BOOL fCopyClassContents)
-{
- INT64 ret = 0;
-
- CONTRACT(INT64)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pvDest, NULL_OK));
- PRECONDITION(CheckPointer(pSrc));
- PRECONDITION(typ != ELEMENT_TYPE_VOID);
- PRECONDITION(CheckPointer(pSig));
- }
- CONTRACT_END;
-
- if (fCopyClassContents)
- {
- // We have to copy the contents of a value class to pvDest
-
- // write unboxed version back to memory provided by the client
- if (pvDest)
- {
- if (ty.IsNull())
- ty = pSig->GetRetTypeHandleThrowing();
-
- if (*pSrc == NULL && !Nullable::IsNullableType(ty))
- COMPlusThrow(kRemotingException, W("Remoting_Message_BadRetValOrOutArg"));
-
- ty.GetMethodTable()->UnBoxIntoUnchecked(pvDest, *pSrc);
-
- // return the object so it can be stored in the frame and
- // propagated to the root set
- // pSrc may not be doubleword aligned!
- *(OBJECTREF*)&ret = *pSrc;
- }
- }
- else
- {
- // We have either a real OBJECTREF or something that does not have
- // a return buffer associated
-
- // Check if it is an ObjectRef (from the GC heap)
- if (CorTypeInfo::IsObjRef(typ))
- {
- if ((*pSrc!=NULL) && ((*pSrc)->IsTransparentProxy()))
- {
- if (ty.IsNull())
- ty = pSig->GetRetTypeHandleThrowing();
-
- // CheckCast ensures that the returned object (proxy) gets
- // refined to the level expected by the caller of the method
- if (!CRemotingServices::CheckCast(*pSrc, ty))
- COMPlusThrow(kInvalidCastException, W("Arg_ObjObj"));
- }
- if (pvDest)
- SetObjectReferenceUnchecked((OBJECTREF *)pvDest, *pSrc);
-
- // pSrc may not be double-word aligned!
- *(OBJECTREF*)&ret = *pSrc;
- }
- else
- {
- // Note: this assert includes VALUETYPE because for Enums
- // HasRetBuffArg() returns false since the normalized type is I4
- // so we end up here ... but GetReturnType() returns VALUETYPE
- // Almost all VALUETYPEs will go through the fCopyClassContents
- // codepath instead of here.
- // Also, IsPrimitiveType() does not check for IntPtr, UIntPtr etc
- // there is a note in siginfo.hpp about that ... hence we have
- // ELEMENT_TYPE_I, ELEMENT_TYPE_U.
- _ASSERTE(
- CorTypeInfo::IsPrimitiveType(typ)
- || (typ == ELEMENT_TYPE_VALUETYPE)
- || (typ == ELEMENT_TYPE_I)
- || (typ == ELEMENT_TYPE_U)
- || (typ == ELEMENT_TYPE_FNPTR)
- );
-
- // REVIEW: For a "ref int" arg, if a nasty sink replaces the boxed
- // int with a null OBJECTREF, this is where we check. We need to be
- // uniform in our policy w.r.t. this (throw v/s ignore)
- // The 'if' block above throws, CallFieldAccessor also has this
- // problem.
- if (*pSrc != NULL)
- {
- PVOID pvSrcData = (*pSrc)->GetData();
- int cbsize = gElementTypeInfo[typ].m_cbSize;
- INT64 retBuff;
-
- // ElementTypeInfo.m_cbSize can be less that zero for cases that need
- // special handling (e.g. value types) to be sure of size (see
- // siginfo.cpp). Luckily, the type handle has the actual byte count,
- // so we look there for such cases.
- if (cbsize < 0)
- {
- if (ty.IsNull())
- ty = pSig->GetRetTypeHandleThrowing();
-
- _ASSERTE(!ty.IsNull());
- cbsize = ty.GetSize();
-
- // we are returning this value class in an INT64 so it better be small enough
- _ASSERTE(cbsize <= (int) sizeof(INT64));
- // Unbox it into a local buffer, This coveres the Nullable<T> case
- // then do the endianness morph below
- ty.GetMethodTable()->UnBoxIntoUnchecked(&retBuff, *pSrc);
-
- pvSrcData = &retBuff;
- }
-
- if (pvDest)
- {
- memcpyNoGCRefs(pvDest, pvSrcData, cbsize);
- }
-
- // need to sign-extend signed types
- bool fEndianessFixup = false;
- switch (typ) {
- case ELEMENT_TYPE_I1:
- ret = *(INT8*)pvSrcData;
- fEndianessFixup = true;
- break;
- case ELEMENT_TYPE_I2:
- ret = *(INT16*)pvSrcData;
- fEndianessFixup = true;
- break;
- case ELEMENT_TYPE_I4:
- ret = *(INT32*)pvSrcData;
- fEndianessFixup = true;
- break;
- default:
- memcpyNoGCRefs(StackElemEndianessFixup(&ret, cbsize), pvSrcData, cbsize);
- break;
- }
-
-#if !defined(_WIN64) && BIGENDIAN
- if (fEndianessFixup)
- ret <<= 32;
-#endif
- }
- }
- }
-
- RETURN(ret);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CMessage::GetReturnValue
-//
-// Synopsis: Pull return value off the stack
-//
-//+----------------------------------------------------------------------------
-FCIMPL1(Object*, CMessage::GetReturnValue, MessageObject* pMessageUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(pMessageUNSAFE != NULL);
- }
- CONTRACTL_END;
-
- struct _gc {
- OBJECTREF refRetVal;
- MESSAGEREF pMessage;
- } gc;
-
- gc.refRetVal = NULL;
- gc.pMessage = (MESSAGEREF) pMessageUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
-
- MetaSig* pSig = gc.pMessage->GetResetMetaSig();
- FramedMethodFrame* pFrame = gc.pMessage->GetFrame();
-
- ArgIterator argit(pSig);
-
- PVOID pvRet;
- if (argit.HasRetBuffArg())
- {
- pvRet = *(PVOID *)(pFrame->GetTransitionBlock() + argit.GetRetBuffArgOffset());
- }
- else
- {
- pvRet = pFrame->GetReturnValuePtr();
- }
-
- CorElementType eType = pSig->GetReturnType();
- TypeHandle ty;
- if (eType == ELEMENT_TYPE_VALUETYPE)
- {
- ty = pSig->GetRetTypeHandleThrowing();
- }
- else
- {
- ty = TypeHandle();
- }
-
- GetObjectFromStack(&gc.refRetVal,
- pvRet,
- eType,
- ty);
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(gc.refRetVal);
-}
-FCIMPLEND
-
-
-
-FCIMPL2(FC_BOOL_RET, CMessage::Dispatch, MessageObject* pMessageUNSAFE, Object* pServerUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(pMessageUNSAFE != NULL);
- PRECONDITION(pServerUNSAFE != NULL);
- }
- CONTRACTL_END;
-
- BOOL fDispatched = FALSE;
- MESSAGEREF pMessage = (MESSAGEREF) pMessageUNSAFE;
- OBJECTREF pServer = (OBJECTREF) pServerUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_2(pMessage, pServer);
-
- MetaSig *pSig = pMessage->GetResetMetaSig();
-
- if (pMessage->GetFlags() & (MSGFLG_BEGININVOKE | MSGFLG_ENDINVOKE | MSGFLG_ONEWAY))
- {
- fDispatched = FALSE;
- goto lExit;
- }
-
- {
- ArgIterator argit(pSig);
-
- UINT nStackBytes;
- MethodDesc *pMD;
- PCODE pTarget;
-
- nStackBytes = argit.SizeOfFrameArgumentArray();
- pMD = pMessage->GetMethodDesc();
-
- // Get the address of the code
- pTarget = pMD->GetCallTarget(&(pServer));
-
-#ifdef PROFILING_SUPPORTED
- // If we're profiling, notify the profiler that we're about to invoke the remoting target
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackRemoting());
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->RemotingServerInvocationStarted();
- END_PIN_PROFILER();
- }
-#endif // PROFILING_SUPPORTED
-
-#ifdef CALLDESCR_FPARGREGS
- // @TODO: This code badly needs refactorization. It's largely shared with MethodDesc::CallDescr in
- // method.cpp and CallDescrWithObjectArray in stackbuildersync.cpp.
-
- FloatArgumentRegisters *pFloatArgumentRegisters = NULL;
-
- // Iterate through all the args looking for floating point values that will be passed in (FP) argument
- // registers.
- int ofs;
- while ((ofs = argit.GetNextOffset()) != TransitionBlock::InvalidOffset)
- {
- if (TransitionBlock::HasFloatRegister(ofs, argit.GetArgLocDescForStructInRegs()))
- {
- // Found a floating point argument register. The first time we find this we point
- // pFloatArgumentRegisters to the part of the frame where these values were spilled (we don't do
- // this unconditionally since the call worker can optimize out the copy of the floating point
- // registers if none are involved at all.
- pFloatArgumentRegisters = (FloatArgumentRegisters*)(pMessage->GetFrame()->GetTransitionBlock() +
- TransitionBlock::GetOffsetOfFloatArgumentRegisters());
-
- // That's all we need to do, CallDescrWorkerWithHandler will automatically pick up all the
- // floating point argument values now.
- break;
- }
- }
-#endif // CALLDESCR_FPARGREGS
-
-#if defined(CALLDESCR_REGTYPEMAP) || defined(COM_STUBS_SEPARATE_FP_LOCATIONS)
- DWORD_PTR dwRegTypeMap = 0;
-
- {
- int ofs;
- while ((ofs = argit.GetNextOffset()) != TransitionBlock::InvalidOffset)
- {
- int regArgNum = TransitionBlock::GetArgumentIndexFromOffset(ofs);
-
- if (regArgNum >= NUM_ARGUMENT_REGISTERS)
- break;
-
- CorElementType argTyp = argit.GetArgType();
-
-#ifdef CALLDESCR_REGTYPEMAP
- FillInRegTypeMap(ofs, argTyp, (BYTE*)&dwRegTypeMap);
-#endif
-
-#ifdef COM_STUBS_SEPARATE_FP_LOCATIONS
- // If this is a floating point argument, it was stored in a
- // separate area of the frame. Copy it into the argument array.
- if (ELEMENT_TYPE_R4 == argTyp || ELEMENT_TYPE_R8 == argTyp)
- {
- TADDR pTransitionBlock = pMessage->GetFrame()->GetTransitionBlock();
-
- PVOID pDest = (PVOID)(pTransitionBlock + ofs);
- PVOID pSrc = (PVOID)(pTransitionBlock + pMessage->GetFrame()->GetFPArgOffset(regArgNum));
-
- ARG_SLOT val;
- if (ELEMENT_TYPE_R4 == argTyp)
- val = FPSpillToR4(pSrc);
- else
- val = FPSpillToR8(pSrc);
-
- *(ARG_SLOT*)pDest = val;
- }
-#endif
- }
- }
-#endif // CALLDESCR_REGTYPEMAP || COM_STUBS_SEPARATE_FP_LOCATIONS
-
- CallDescrData callDescrData;
-
- callDescrData.pSrc = (BYTE*)pMessage->GetFrame()->GetTransitionBlock() + sizeof(TransitionBlock);
- callDescrData.numStackSlots = nStackBytes / STACK_ELEM_SIZE;
-#ifdef CALLDESCR_ARGREGS
- callDescrData.pArgumentRegisters = (ArgumentRegisters*)(pMessage->GetFrame()->GetTransitionBlock() + TransitionBlock::GetOffsetOfArgumentRegisters());
-#endif
-#ifdef CALLDESCR_FPARGREGS
- callDescrData.pFloatArgumentRegisters = pFloatArgumentRegisters;
-#endif
-#ifdef CALLDESCR_REGTYPEMAP
- callDescrData.dwRegTypeMap = dwRegTypeMap;
-#endif
- callDescrData.fpReturnSize = argit.GetFPReturnSize();
- callDescrData.pTarget = pTarget;
-
- CallDescrWorkerWithHandler(&callDescrData);
-
-#ifdef PROFILING_SUPPORTED
- // If we're profiling, notify the profiler that we're about to invoke the remoting target
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackRemoting());
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->RemotingServerInvocationReturned();
- END_PIN_PROFILER();
- }
-#endif // PROFILING_SUPPORTED
-
- memcpyNoGCRefs(pMessage->GetFrame()->GetReturnValuePtr(), &callDescrData.returnValue, sizeof(callDescrData.returnValue));
-
- fDispatched = TRUE;
- }
-
-lExit: ;
- HELPER_METHOD_FRAME_END();
- FC_RETURN_BOOL(fDispatched);
-}
-FCIMPLEND
-
-void CMessage::AppendAssemblyName(CQuickBytes &out, const CHAR* str)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(str));
- }
- CONTRACTL_END;
-
- SIZE_T len = strlen(str) * sizeof(CHAR);
- SIZE_T oldSize = out.Size();
- out.ReSizeThrows(oldSize + len + 2);
- CHAR * cur = (CHAR *) ((BYTE *) out.Ptr() + oldSize - 1);
- if (*cur)
- cur++;
-
- *cur = ASSEMBLY_SEPARATOR_CHAR;
- memcpy(cur + 1, str, len);
- cur += (len + 1);
- *cur = '\0';
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CMessage::GetAsyncBeginInfo
-//
-// Synopsis: Pull the AsyncBeginInfo object from an async call
-//
-//+----------------------------------------------------------------------------
-FCIMPL3(void, CMessage::GetAsyncBeginInfo, MessageObject* pMessageUNSAFE, OBJECTREF* ppACBD, OBJECTREF* ppState)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(pMessageUNSAFE != NULL);
- }
- CONTRACTL_END;
-
- MESSAGEREF pMessage = (MESSAGEREF) pMessageUNSAFE;
- _ASSERTE(pMessage->GetFlags() & MSGFLG_BEGININVOKE);
-
- HELPER_METHOD_FRAME_BEGIN_1(pMessage);
-
- LOG((LF_REMOTING, LL_INFO10, "CMessage::GetAsyncBeginInfo IN\n"));
-
- if (pMessage == NULL)
- COMPlusThrow(kNullReferenceException, W("NullReference_This"));
-
- MetaSig *pSig = pMessage->GetResetMetaSig();
-
- FramedMethodFrame * pFrame = pMessage->GetFrame();
- ArgIterator argit(pSig);
-
- if ((ppACBD != NULL) || (ppState != NULL))
- {
- int ofs;
- int last = TransitionBlock::InvalidOffset, secondtolast = TransitionBlock::InvalidOffset;
- while ((ofs = argit.GetNextOffset()) != TransitionBlock::InvalidOffset)
- {
- secondtolast = last;
- last = ofs;
- }
- _ASSERTE(secondtolast != TransitionBlock::InvalidOffset);
- if (secondtolast != TransitionBlock::InvalidOffset && ppACBD != NULL)
- SetObjectReferenceUnchecked(ppACBD, ObjectToOBJECTREF(*(Object **)(pFrame->GetTransitionBlock() + secondtolast)));
- PREFIX_ASSUME(last != TransitionBlock::InvalidOffset);
- if (ppState != NULL)
- SetObjectReferenceUnchecked(ppState, ObjectToOBJECTREF(*(Object **)(pFrame->GetTransitionBlock() + last)));
- }
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-//+----------------------------------------------------------------------------
-//
-// Method: CMessage::GetAsyncResult
-//
-// Synopsis: Pull the AsyncResult from an async call
-//
-//+----------------------------------------------------------------------------
-FCIMPL1(LPVOID, CMessage::GetAsyncResult, MessageObject* pMessageUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(pMessageUNSAFE != NULL);
- }
- CONTRACTL_END;
-
- LPVOID retVal = NULL;
- MESSAGEREF pMessage = (MESSAGEREF) pMessageUNSAFE;
- _ASSERTE(pMessage->GetFlags() & MSGFLG_ENDINVOKE);
-
- HELPER_METHOD_FRAME_BEGIN_RET_1(pMessage);
-
- LOG((LF_REMOTING, LL_INFO10, "CMessage::GetAsyncResult IN\n"));
-
- retVal = GetLastArgument(&pMessage);
-
- HELPER_METHOD_FRAME_END();
- return retVal;
-}
-FCIMPLEND
-
-//+----------------------------------------------------------------------------
-//
-// Method: CMessage::GetAsyncObject
-//
-// Synopsis: Pull the AsyncObject from an async call
-//
-//+----------------------------------------------------------------------------
-FCIMPL1(Object*, CMessage::GetAsyncObject, MessageObject* pMessageUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(pMessageUNSAFE != NULL);
- }
- CONTRACTL_END;
-
- Object* pobjRetVal = NULL;
- MESSAGEREF pMessage = (MESSAGEREF) pMessageUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_RET_1(pMessage);
-
- LOG((LF_REMOTING, LL_INFO10, "CMessage::GetAsyncObject IN\n"));
-
- FramedMethodFrame *pFrame = pMessage->GetFrame();
- MetaSig *pSig = pMessage->GetResetMetaSig();
- ArgIterator argit(pSig);
-
- pobjRetVal = *(Object**)(pFrame->GetTransitionBlock() + argit.GetThisOffset());
-
- HELPER_METHOD_FRAME_END();
- return pobjRetVal;
-}
-FCIMPLEND
-
-//+----------------------------------------------------------------------------
-//
-// Method: CMessage::GetLastArgument private
-//
-// Synopsis: Pull the last argument of 4 bytes off the stack
-//
-//+----------------------------------------------------------------------------
-LPVOID CMessage::GetLastArgument(MESSAGEREF *pMsg)
-{
- CONTRACT(LPVOID)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pMsg));
- POSTCONDITION(*pMsg != NULL); // CheckPointer doesn't seem to work here.
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END;
-
- FramedMethodFrame *pFrame = (*pMsg)->GetFrame();
- MetaSig *pSig = (*pMsg)->GetResetMetaSig();
-
- ArgIterator argit(pSig);
- int arg;
- int backadder = TransitionBlock::InvalidOffset;
- while ((arg = argit.GetNextOffset()) != TransitionBlock::InvalidOffset)
- backadder = arg;
-
- _ASSERTE(backadder != TransitionBlock::InvalidOffset);
-
- RETURN *(LPVOID *)(pFrame->GetTransitionBlock() + backadder);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CMessage::DebugOut public
-//
-// Synopsis: temp Debug out until the classlibs have one.
-//
-//+----------------------------------------------------------------------------
-FCIMPL1(void, CMessage::DebugOut, StringObject* pOutUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(pOutUNSAFE != NULL);
- }
- CONTRACTL_END;
-
-#ifdef _DEBUG
- STRINGREF pOut = (STRINGREF) pOutUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_1(pOut);
-
- static int fMessageDebugOut = 0;
-
- if (fMessageDebugOut == 0)
- fMessageDebugOut = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MessageDebugOut) ? 1 : -1;
-
- if (fMessageDebugOut == 1)
- WszOutputDebugString(pOut->GetBuffer());
-
- HELPER_METHOD_FRAME_END();
-#endif
-
- FCUnique(0x76);
-}
-FCIMPLEND
-
-//+----------------------------------------------------------------------------
-//
-// Method: CMessage::HasVarArgs public
-//
-// Synopsis: Return TRUE if the method is a VarArgs Method
-//
-//+----------------------------------------------------------------------------
-FCIMPL1(FC_BOOL_RET, CMessage::HasVarArgs, MessageObject * pMessage)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(pMessage));
- }
- CONTRACTL_END;
-
- BOOL result;
-
- // Need entire path to be SO_TOLERANT or put a Hard SO probe here as
- // no failure path.
- CONTRACT_VIOLATION(SOToleranceViolation);
-
- result = pMessage->GetMethodDesc()->IsVarArg();
-
- FC_RETURN_BOOL(result);
-}
-FCIMPLEND
-
-
-//static
-int CMessage::GetStackOffset (FramedMethodFrame *pFrame, ArgIterator *pArgIter, MetaSig *pSig)
-{
- CONTRACT(int)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pFrame));
- PRECONDITION(CheckPointer(pArgIter));
- PRECONDITION(CheckPointer(pSig));
- }
- CONTRACT_END;
-
- LOG((LF_REMOTING, LL_INFO100,
- "CMessage::GetStackOffset pFrame:0x%x, pArgIter:0x%x\n",
- pFrame, pArgIter));
-
- int ret = pArgIter->GetNextOffset();
-
-#ifdef COM_STUBS_SEPARATE_FP_LOCATIONS
- int typ = pArgIter->GetArgType();
- // REVISIT_TODO do we need to handle this?
- if ((ELEMENT_TYPE_R4 == typ || ELEMENT_TYPE_R8 == typ) &&
- TransitionBlock::IsArgumentRegisterOffset(ret))
- {
- int iFPArg = TransitionBlock::GetArgumentIndexFromOffset(ret);
-
- ret = static_cast<int>(pFrame->GetFPArgOffset(iFPArg));
- }
-#endif // COM_STUBS_SEPARATE_FP_LOCATIONS
-
- RETURN ret;
-}
-
-
-//+----------------------------------------------------------------------------
-//
-// Method: CMessage::GetStackPtr private
-//
-// Synopsis: Figure out where on the stack a parameter is stored
-//
-// Parameters: ndx - the parameter index (zero-based)
-// pFrame - stack frame pointer (FramedMethodFrame)
-// pSig - method signature, used to determine parameter sizes
-//
-//
-//<REVISIT_TODO>
-// CODEWORK: Currently we assume all parameters to be 32-bit intrinsics
-// or 32-bit pointers. Value classes are not handled correctly.
-//</REVISIT_TODO>
-//+----------------------------------------------------------------------------
-PVOID CMessage::GetStackPtr(INT32 ndx, FramedMethodFrame *pFrame, MetaSig *pSig)
-{
- CONTRACT(PVOID)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pFrame));
- PRECONDITION(CheckPointer(pSig));
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END;
-
- LOG((LF_REMOTING, LL_INFO100,
- "CMessage::GetStackPtr IN ndx:0x%x, pFrame:0x%x, pSig:0x%x\n",
- ndx, pFrame, pSig));
-
- ArgIterator iter(pSig);
- PVOID ret = NULL;
-
- // <REVISIT_TODO>CODEWORK:: detect and optimize for sequential access</REVISIT_TODO>
- _ASSERTE((UINT)ndx < pSig->NumFixedArgs());
- for (int i=0; i<=ndx; i++)
- ret = (BYTE*)pFrame->GetTransitionBlock() + GetStackOffset(pFrame, &iter, pSig);
-
- RETURN ret;
-}
-
-#endif //FEATURE_REMOTING
diff --git a/src/vm/message.h b/src/vm/message.h
deleted file mode 100644
index 06c0402067..0000000000
--- a/src/vm/message.h
+++ /dev/null
@@ -1,200 +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.
-
-/*============================================================
-**
-** File: message.h
-**
-** Purpose: Encapsulates a function call frame into a message
-** object with an interface that can enumerate the
-** arguments of the messagef
-**
-**
-
-===========================================================*/
-#ifndef ___MESSAGE_H___
-#define ___MESSAGE_H___
-
-#ifndef FEATURE_REMOTING
-#error FEATURE_REMOTING is not set, please do not include message.h
-#endif
-
-#include "fcall.h"
-
-//+----------------------------------------------------------
-//
-// Struct: MessageObject
-//
-// Synopsis: Physical mapping of the System.Runtime.Remoting.Message
-// object.
-//
-//
-//------------------------------------------------------------
-class MessageObject : public Object
-{
- friend class MscorlibBinder;
-
-public:
- MetaSig* GetResetMetaSig()
- {
- CONTRACT(MetaSig*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pMetaSigHolder));
- POSTCONDITION(CheckPointer(RETVAL));
- SO_TOLERANT;
- }
- CONTRACT_END;
-
- pMetaSigHolder->Reset();
- RETURN pMetaSigHolder;
- }
-
- FramedMethodFrame *GetFrame()
- {
- CONTRACT(FramedMethodFrame *)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN pFrame;
- }
-
- MethodDesc *GetMethodDesc()
- {
- CONTRACT(MethodDesc *)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- POSTCONDITION(CheckPointer(RETVAL));
- SO_TOLERANT;
- }
- CONTRACT_END;
-
- RETURN pMethodDesc;
- }
-
- MethodDesc *GetDelegateMD()
- {
- CONTRACT(MethodDesc *)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- SO_TOLERANT;
- }
- CONTRACT_END;
-
- RETURN pDelegateMD;
- }
-
- INT32 GetFlags()
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- return iFlags;
- }
-
-private:
- STRINGREF pMethodName; // Method name
- BASEARRAYREF pMethodSig; // Array of parameter types
- OBJECTREF pMethodBase; // Reflection method object
- OBJECTREF pHashTable; // hashtable for properties
- STRINGREF pURI; // object's URI
- STRINGREF pTypeName; // not used in VM, placeholder
- OBJECTREF pFault; // exception
-
- OBJECTREF pID; // not used in VM, placeholder
- OBJECTREF pSrvID; // not used in VM, placeholder
- OBJECTREF pArgMapper; // not used in VM, placeholder
- OBJECTREF pCallCtx; // not used in VM, placeholder
-
- FramedMethodFrame *pFrame;
- MethodDesc *pMethodDesc;
- MetaSig *pMetaSigHolder;
- MethodDesc *pDelegateMD;
- TypeHandle thGoverningType;
- INT32 iFlags;
- CLR_BOOL initDone; // called the native Init routine
-};
-
-#ifdef USE_CHECKED_OBJECTREFS
-typedef REF<MessageObject> MESSAGEREF;
-#else
-typedef MessageObject* MESSAGEREF;
-#endif
-
-// *******
-// Note: Needs to be in sync with flags in Message.cs
-// *******
-enum
-{
- MSGFLG_BEGININVOKE = 0x01,
- MSGFLG_ENDINVOKE = 0x02,
- MSGFLG_CTOR = 0x04,
- MSGFLG_ONEWAY = 0x08,
- MSGFLG_FIXEDARGS = 0x10,
- MSGFLG_VARARGS = 0x20
-};
-
-//+----------------------------------------------------------
-//
-// Class: CMessage
-//
-// Synopsis: EE counterpart to Microsoft.Runtime.Message.
-// Encapsulates code to read a function call
-// frame into an interface that can enumerate
-// the parameters.
-//
-//
-//------------------------------------------------------------
-class CMessage
-{
-public:
- // public fcalls.
- static FCDECL1(INT32, GetArgCount, MessageObject *pMsg);
- static FCDECL2(Object*, GetArg, MessageObject* pMessage, INT32 argNum);
- static FCDECL1(Object*, GetArgs, MessageObject* pMessageUNSAFE);
- static FCDECL3(void, PropagateOutParameters, MessageObject* pMessageUNSAFE, ArrayBase* pOutPrmsUNSAFE, Object* RetValUNSAFE);
- static FCDECL1(Object*, GetReturnValue, MessageObject* pMessageUNSAFE);
- static FCDECL3(void, GetAsyncBeginInfo, MessageObject* pMessageUNSAFE, OBJECTREF* ppACBD, OBJECTREF* ppState);
- static FCDECL1(LPVOID, GetAsyncResult, MessageObject* pMessageUNSAFE);
- static FCDECL1(Object*, GetAsyncObject, MessageObject* pMessageUNSAFE);
- static FCDECL1(void, DebugOut, StringObject* pOutUNSAFE);
- static FCDECL2(FC_BOOL_RET, Dispatch, MessageObject* pMessageUNSAFE, Object* pServerUNSAFE);
- static FCDECL1(FC_BOOL_RET, HasVarArgs, MessageObject * poMessage);
-
-public:
- // public helper
- static void GetObjectFromStack(OBJECTREF* ppDest, PVOID val, const CorElementType eType, TypeHandle ty, BOOL fIsByRef = FALSE, FramedMethodFrame *pFrame = NULL);
-
-private:
- // private helpers
- static PVOID GetStackPtr(INT32 ndx, FramedMethodFrame *pFrame, MetaSig *pSig);
- static int GetStackOffset (FramedMethodFrame *pFrame, ArgIterator *pArgIter, MetaSig *pSig);
- static INT64 __stdcall CallMethod(const void *pTarget,
- INT32 cArgs,
- FramedMethodFrame *pFrame,
- OBJECTREF pObj);
- static INT64 CopyOBJECTREFToStack(PVOID pvDest, OBJECTREF *pSrc, CorElementType typ, TypeHandle ty, MetaSig *pSig, BOOL fCopyClassContents);
- static LPVOID GetLastArgument(MESSAGEREF *pMsg);
- static void AppendAssemblyName(CQuickBytes &out, const CHAR* str);
-};
-
-#endif // ___MESSAGE_H___
diff --git a/src/vm/metasig.h b/src/vm/metasig.h
index 5df7038360..8e0ea0a773 100644
--- a/src/vm/metasig.h
+++ b/src/vm/metasig.h
@@ -280,13 +280,14 @@ DEFINE_METASIG(SM(RefDbl_Dbl, r(d) d, v))
DEFINE_METASIG(GM(RefT_RetT, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, r(M(0)) , M(0)))
DEFINE_METASIG(GM(RefT_T, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, r(M(0)) M(0), v))
+DEFINE_METASIG(GM(RefByte_RetT, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, r(b), M(0)))
+DEFINE_METASIG(GM(RefByte_T_RetVoid, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, r(b) M(0), v))
+DEFINE_METASIG(GM(PtrVoid_RetT, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, P(v), M(0)))
+DEFINE_METASIG(GM(PtrVoid_T_RetVoid, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, P(v) M(0), v))
DEFINE_METASIG_T(SM(SafeHandle_RefBool_RetIntPtr, C(SAFE_HANDLE) r(F), I ))
DEFINE_METASIG_T(SM(SafeHandle_RetVoid, C(SAFE_HANDLE), v ))
-#ifdef FEATURE_REMOTING
-DEFINE_METASIG_T(SM(RetContext, _, C(CONTEXT)))
-#endif
DEFINE_METASIG_T(SM(RetMethodBase, _, C(METHOD_BASE)))
DEFINE_METASIG(SM(RetVoid, _, v))
DEFINE_METASIG(SM(Str_IntPtr_Int_RetVoid, s I i, v))
@@ -301,9 +302,6 @@ DEFINE_METASIG(SM(Int_IntPtr_RetObj, i I, j))
DEFINE_METASIG(SM(IntPtr_IntPtr_Int_RetVoid, I I i, v))
DEFINE_METASIG_T(SM(Exception_RetInt, C(EXCEPTION), i))
-#ifdef FEATURE_REMOTING
-DEFINE_METASIG_T(SM(ContextBoundObject_RetObj, C(CONTEXT_BOUND_OBJECT), j))
-#endif
DEFINE_METASIG(SM(IntPtr_RetVoid, I, v))
DEFINE_METASIG(SM(IntPtr_Bool_RetVoid, I F, v))
@@ -320,9 +318,6 @@ DEFINE_METASIG(SM(Obj_RetIntPtr, j, I))
DEFINE_METASIG(SM(Obj_RetObj, j, j))
DEFINE_METASIG(SM(Obj_RetArrByte, j, a(b)))
DEFINE_METASIG(SM(Obj_Bool_RetArrByte, j F, a(b)))
-#ifdef FEATURE_REMOTING
-DEFINE_METASIG_T(SM(Obj_RefMessageData_RetVoid, j r(g(MESSAGE_DATA)), v))
-#endif
DEFINE_METASIG(SM(Obj_Obj_RefArrByte_RetArrByte, j j r(a(b)), a(b)))
#ifdef FEATURE_COMINTEROP
@@ -335,23 +330,7 @@ DEFINE_METASIG_T(SM(RefDateTimeOffset_RefDateTimeNative_RetVoid, r(g(DATE_TIME_O
#endif
-#ifdef FEATURE_REMOTING
-DEFINE_METASIG_T(SM(RealProxy_Class_RetBool, C(REAL_PROXY) C(CLASS), F))
-#endif
-#ifndef FEATURE_CORECLR
-DEFINE_METASIG_T(SM(ExecutionContext_ContextCallback_Object_Bool_RetVoid, \
- C(EXECUTIONCONTEXT) C(CONTEXTCALLBACK) j F, v))
-#endif
-#if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
-DEFINE_METASIG_T(SM(SecurityContext_ContextCallback_Object_RetVoid, \
- C(SECURITYCONTEXT) C(CONTEXTCALLBACK) j, v))
-#endif // #if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
-#ifdef FEATURE_COMPRESSEDSTACK
-DEFINE_METASIG_T(SM(CompressedStack_ContextCallback_Object_RetVoid, \
- C(COMPRESSED_STACK) C(CONTEXTCALLBACK) j, v))
-DEFINE_METASIG_T(SM(IntPtr_RetDCS, I, C(DOMAIN_COMPRESSED_STACK)))
-#endif // #ifdef FEATURE_COMPRESSEDSTACK
DEFINE_METASIG(SM(Str_RetInt, s, i))
DEFINE_METASIG_T(SM(Str_RetICustomMarshaler, s, C(ICUSTOM_MARSHALER)))
DEFINE_METASIG(SM(Int_Str_RetIntPtr, i s, I))
@@ -360,17 +339,11 @@ DEFINE_METASIG(SM(Str_IntPtr_RetIntPtr, s I, I))
DEFINE_METASIG(SM(Str_Bool_Int_RetV, s F i, v))
DEFINE_METASIG_T(SM(Type_RetInt, C(TYPE), i))
-#ifdef FEATURE_REMOTING
-DEFINE_METASIG_T(SM(Class_ArrObject_Bool_RetMarshalByRefObject, C(CLASS) a(j) F, C(MARSHAL_BY_REF_OBJECT)))
-#endif
DEFINE_METASIG(SM(ArrByte_RetObj, a(b), j))
DEFINE_METASIG(SM(ArrByte_Bool_RetObj, a(b) F, j))
DEFINE_METASIG(SM(ArrByte_ArrByte_RefObj_RetObj, a(b) a(b) r(j), j))
DEFINE_METASIG_T(SM(PtrSByt_Int_Int_Encoding_RetStr, P(B) i i C(ENCODING), s))
DEFINE_METASIG_T(SM(Evidence_RetEvidence, C(EVIDENCE), C(EVIDENCE)))
-#ifdef FEATURE_CAS_POLICY
-DEFINE_METASIG_T(SM(PEFile_Evidence_RetEvidence, C(SAFE_PEFILE_HANDLE) C(EVIDENCE), C(EVIDENCE)))
-#endif // FEATURE_CAS_POLICY
DEFINE_METASIG_T(SM(Evidence_Asm_RetEvidence, C(EVIDENCE) C(ASSEMBLY), C(EVIDENCE)))
DEFINE_METASIG_T(IM(Evidence_RetVoid, C(EVIDENCE), v))
@@ -378,9 +351,6 @@ DEFINE_METASIG_T(SM(Void_RetRuntimeTypeHandle, _, g(RT_TYPE_HANDLE)))
DEFINE_METASIG(SM(Void_RetIntPtr, _, I))
DEFINE_METASIG_T(SM(UInt_UInt_PtrNativeOverlapped_RetVoid, K K P(g(NATIVEOVERLAPPED)), v))
-#ifdef FEATURE_REMOTING
-DEFINE_METASIG_T(SM(CrossContextDelegate_ArrObj_RetObj, C(CROSS_CONTEXT_DELEGATE) a(j), j))
-#endif
DEFINE_METASIG(IM(Long_RetVoid, l, v))
DEFINE_METASIG(IM(IntPtr_Int_RetVoid, I i, v))
@@ -405,9 +375,6 @@ DEFINE_METASIG(IM(RetBool, _, F))
DEFINE_METASIG(IM(RetArrByte, _, a(b)))
DEFINE_METASIG_T(IM(RetArrParameterInfo, _, a(C(PARAMETER))))
DEFINE_METASIG_T(IM(RetCultureInfo, _, C(CULTURE_INFO)))
-#ifdef FEATURE_CAS_POLICY
-DEFINE_METASIG_T(IM(RetSecurityElement, _, C(SECURITY_ELEMENT)))
-#endif // FEATURE_CAS_POLICY
DEFINE_METASIG_T(SM(RetThread, _, C(THREAD)))
@@ -441,9 +408,6 @@ DEFINE_METASIG(IM(Int_RefIntPtr_RefIntPtr_RefIntPtr_RetVoid, i r(I) r(I) r(I), v
DEFINE_METASIG(IM(Int_RetStr, i, s))
DEFINE_METASIG(IM(Int_RetVoid, i, v))
DEFINE_METASIG(IM(Int_RetBool, i, F))
-#ifdef FEATURE_REMOTING
-DEFINE_METASIG_T(IM(RefMessageData_Int_RetVoid, r(g(MESSAGE_DATA)) i, v))
-#endif // FEATURE_REMOTING
DEFINE_METASIG(IM(Int_Int_Int_Int_RetVoid, i i i i, v))
DEFINE_METASIG_T(IM(Obj_EventArgs_RetVoid, j C(EVENT_ARGS), v))
DEFINE_METASIG_T(IM(Obj_UnhandledExceptionEventArgs_RetVoid, j C(UNHANDLED_EVENTARGS), v))
@@ -451,9 +415,6 @@ DEFINE_METASIG_T(IM(Obj_UnhandledExceptionEventArgs_RetVoid, j C(UNHANDLED_EVENT
DEFINE_METASIG_T(IM(Assembly_RetVoid, C(ASSEMBLY), v))
DEFINE_METASIG_T(IM(Assembly_RetBool, C(ASSEMBLY), F))
DEFINE_METASIG_T(IM(AssemblyBase_RetBool, C(ASSEMBLYBASE), F))
-#ifdef FEATURE_COMINTEROP_REGISTRATION
-DEFINE_METASIG_T(IM(AssemblyBase_AssemblyRegistrationFlags_RetBool, C(ASSEMBLYBASE) g(ASSEMBLY_REGISTRATION_FLAGS), F))
-#endif
DEFINE_METASIG_T(IM(Exception_RetVoid, C(EXCEPTION), v))
DEFINE_METASIG(IM(IntPtr_RetObj, I, j))
@@ -475,9 +436,6 @@ DEFINE_METASIG(IM(Obj_Bool_RetVoid, j F, v))
#ifdef FEATURE_COMINTEROP
DEFINE_METASIG(SM(Obj_RetStr, j, s))
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_REMOTING
-DEFINE_METASIG_T(IM(Str_BindingFlags_Obj_ArrInt_RefMessageData_RetObj, s g(BINDING_FLAGS) j a(i) r(g(MESSAGE_DATA)), j))
-#endif // FEATURE_REMOTING
DEFINE_METASIG_T(IM(Obj_Obj_BindingFlags_Binder_CultureInfo_RetVoid, j j g(BINDING_FLAGS) C(BINDER) C(CULTURE_INFO), v))
DEFINE_METASIG_T(IM(Obj_Obj_BindingFlags_Binder_ArrObj_CultureInfo_RetVoid, j j g(BINDING_FLAGS) C(BINDER) a(j) C(CULTURE_INFO), v))
DEFINE_METASIG_T(IM(Obj_BindingFlags_Binder_ArrObj_CultureInfo_RetObj, j g(BINDING_FLAGS) C(BINDER) a(j) C(CULTURE_INFO), j))
@@ -564,9 +522,6 @@ DEFINE_METASIG_T(SM(Str_Evidence_AppDomainSetup_RetAppDomain, s C(EVIDENCE) C(AP
DEFINE_METASIG_T(SM(Str_Evidence_Str_Str_Bool_RetAppDomain, s C(EVIDENCE) s s F, C(APP_DOMAIN)))
DEFINE_METASIG_T(SM(Str_RetAppDomain, s, C(APP_DOMAIN)))
DEFINE_METASIG_T(SM(Str_AppDomainSetup_Evidence_Evidence_IntPtr_Str_ArrStr_ArrStr_RetObj, s C(APPDOMAIN_SETUP) C(EVIDENCE) C(EVIDENCE) I s a(s) a(s), j))
-#ifdef FEATURE_APTCA
-DEFINE_METASIG(IM(PtrChar_Int_PtrByte_Int_RetBool, P(u) i P(b) i, F))
-#endif //FEATURE_APTCA
#ifdef FEATURE_COMINTEROP
// System.AppDomain.OnReflectionOnlyNamespaceResolveEvent
DEFINE_METASIG_T(IM(Assembly_Str_RetArrAssembly, C(ASSEMBLY) s, a(C(ASSEMBLY))))
@@ -575,26 +530,17 @@ DEFINE_METASIG(IM(Str_RetArrStr, s, a(s)))
#endif //FEATURE_COMINTEROP
// Object Clone
-#ifdef FEATURE_SERIALIZATION
-DEFINE_METASIG_T(IM(SerInfo_RetVoid, C(SERIALIZATION_INFO), v))
-DEFINE_METASIG_T(IM(SerInfo_StrContext_RetVoid, C(SERIALIZATION_INFO) g(STREAMING_CONTEXT), v))
-DEFINE_METASIG_T(SM(Obj_ArrStr_ArrObj_OutStreamingContext_RetSerializationInfo, j a(s) a(j) r(g(STREAMING_CONTEXT)), C(SERIALIZATION_INFO)))
-#endif // FEATURE_SERIALIZATION
DEFINE_METASIG(SM(Obj_OutStr_OutStr_OutArrStr_OutArrObj_RetObj, j r(s) r(s) r(a(s)) r(a(j)), j))
-#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
// Execution Context
DEFINE_METASIG_T(SM(SyncCtx_ArrIntPtr_Bool_Int_RetInt, C(SYNCHRONIZATION_CONTEXT) a(I) F i, i))
-#endif // #ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
#ifdef FEATURE_COMINTEROP
// The signature of the method System.Runtime.InteropServices.ICustomQueryInterface.GetInterface
DEFINE_METASIG_T(IM(RefGuid_OutIntPtr_RetCustomQueryInterfaceResult, r(g(GUID)) r(I), g(CUSTOMQUERYINTERFACERESULT)))
#endif //FEATURE_COMINTEROP
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
DEFINE_METASIG_T(SM(IntPtr_AssemblyName_RetAssemblyBase, I C(ASSEMBLY_NAME), C(ASSEMBLYBASE)))
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
// ThreadPool
DEFINE_METASIG(SM(Obj_Bool_RetVoid, j F, v))
diff --git a/src/vm/method.cpp b/src/vm/method.cpp
index 07636d6950..a72b07b404 100644
--- a/src/vm/method.cpp
+++ b/src/vm/method.cpp
@@ -12,9 +12,6 @@
#include "common.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "security.h"
#include "verifier.hpp"
#include "excep.h"
@@ -31,9 +28,6 @@
#include "jitinterface.h"
#include "runtimehandles.h"
#include "eventtrace.h"
-#ifndef FEATURE_CORECLR
-#include "fxretarget.h"
-#endif
#include "interoputil.h"
#include "prettyprintsig.h"
#include "formattype.h"
@@ -949,29 +943,6 @@ BOOL MethodDesc::IsTightlyBoundToMethodTable()
#ifndef DACCESS_COMPILE
-#if defined(FEATURE_REMOTING) && !defined(HAS_REMOTING_PRECODE)
-//*******************************************************************************
-void MethodDesc::Destruct()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- FORBID_FAULT;
- }
- CONTRACTL_END
-
- if (!IsRestored())
- return;
-
- MethodTable *pMT = GetMethodTable();
- if(pMT->IsMarshaledByRef() || (pMT == g_pObjectClass))
- {
- // Destroy the thunk generated to intercept calls for remoting
- CRemotingServices::DestroyThunk(this);
- }
-}
-#endif // FEATURE_REMOTING && !HAS_REMOTING_PRECODE
//*******************************************************************************
HRESULT MethodDesc::Verify(COR_ILMETHOD_DECODER* ILHeader,
@@ -2146,13 +2117,6 @@ PCODE MethodDesc::GetSingleCallableAddrOfVirtualizedCode(OBJECTREF *orThis, Type
// where we could end up bypassing the remoting system), but it serves
// our purpose here (basically pushes our correctly instantiated,
// resolved method desc on the stack and calls the remoting code).
-#ifdef FEATURE_REMOTING
- if (pObjMT->IsTransparentProxy())
- if (IsInterface())
- return CRemotingServices::GetStubForInterfaceMethod(pResultMD);
- else
- return CRemotingServices::GetNonVirtualEntryPointForVirtualMethod(pResultMD);
-#endif
return pResultMD->GetSingleCallableAddrOfCode();
}
@@ -2204,13 +2168,6 @@ PCODE MethodDesc::GetMultiCallableAddrOfVirtualizedCode(OBJECTREF *orThis, TypeH
// where we could end up bypassing the remoting system), but it serves
// our purpose here (basically pushes our correctly instantiated,
// resolved method desc on the stack and calls the remoting code).
-#ifdef FEATURE_REMOTING
- if (pObjMT->IsTransparentProxy())
- if (pStaticMD->IsInterface())
- RETURN(CRemotingServices::GetStubForInterfaceMethod(pTargetMD));
- else
- RETURN(CRemotingServices::GetNonVirtualEntryPointForVirtualMethod(pTargetMD));
-#endif
RETURN(pTargetMD->GetMultiCallableAddrOfCode());
}
@@ -2221,12 +2178,6 @@ PCODE MethodDesc::GetMultiCallableAddrOfVirtualizedCode(OBJECTREF *orThis, TypeH
RETURN(pTargetMD->GetMultiCallableAddrOfCode());
}
-#ifdef FEATURE_REMOTING
- if (pObjMT->IsTransparentProxy())
- {
- RETURN(pObjMT->GetRestoredSlot(pStaticMD->GetSlot()));
- }
-#endif // FEATURE_REMOTING
pTargetMD = pObjMT->GetMethodDescForSlot(pStaticMD->GetSlot());
@@ -2322,10 +2273,6 @@ PCODE MethodDesc::TryGetMultiCallableAddrOfCode(CORINFO_ACCESS_FLAGS accessFlags
if (IsWrapperStub() || IsEnCAddedMethod())
return GetStableEntryPoint();
-#ifdef FEATURE_REMOTING
- if (!(accessFlags & CORINFO_ACCESS_THIS) && IsRemotingInterceptedViaVirtualDispatch())
- return CRemotingServices::GetNonVirtualEntryPointForVirtualMethod(this);
-#endif
// For EnC always just return the stable entrypoint so we can update the code
if (IsEnCMethod())
@@ -2353,7 +2300,7 @@ PCODE MethodDesc::TryGetMultiCallableAddrOfCode(CORINFO_ACCESS_FLAGS accessFlags
}
else
{
- if (IsPointingToNativeCode())
+ if (IsPointingToStableNativeCode())
return GetNativeCode();
}
@@ -2437,19 +2384,6 @@ MethodDesc* Entry2MethodDesc(PCODE entryPoint, MethodTable *pMT)
if (pMD != NULL)
RETURN(pMD);
-#ifdef FEATURE_REMOTING
-
-#ifndef HAS_REMOTING_PRECODE
- pMD = CNonVirtualThunkMgr::Entry2MethodDesc(entryPoint, pMT);
- if (pMD != NULL)
- RETURN(pMD);
-#endif // HAS_REMOTING_PRECODE
-
- pMD = CVirtualThunkMgr::Entry2MethodDesc(entryPoint, pMT);
- if (pMD != NULL)
- RETURN(pMD);
-
-#endif // FEATURE_REMOTING
// Is it an FCALL?
pMD = ECall::MapTargetBackToMethod(entryPoint);
@@ -2470,12 +2404,10 @@ BOOL MethodDesc::IsFCallOrIntrinsic()
if (IsFCall() || IsArray())
return TRUE;
-#ifdef FEATURE_SPAN_OF_T
// Intrinsic methods on ByReference<T> or Span<T>
MethodTable * pMT = GetMethodTable();
if (pMT->IsByRefLike() && pMT->GetModule()->IsSystem())
return TRUE;
-#endif
return FALSE;
}
@@ -2772,31 +2704,6 @@ BOOL MethodDesc::RequiresMethodDescCallingConvention(BOOL fEstimateForChunk /*=F
if (IsNDirect() || IsComPlusCall() || IsGenericComPlusCall())
return TRUE;
-#ifdef FEATURE_REMOTING
- MethodTable * pMT = GetMethodTable();
-
- if (fEstimateForChunk)
- {
- // Make a best guess based on the method table of the chunk.
- if (pMT->IsInterface())
- return TRUE;
- }
- else
- {
- // CRemotingServices::GetDispatchInterfaceHelper that needs method desc
- if (pMT->IsInterface() && !IsStatic())
- return TRUE;
-
- // Asynchronous delegate methods are forwarded to shared TP stub
- if (IsEEImpl())
- {
- DelegateEEClass *pClass = (DelegateEEClass*)(pMT->GetClass());
-
- if (this != pClass->m_pInvokeMethod)
- return TRUE;
- }
- }
-#endif // FEATURE_REMOTING
return FALSE;
}
@@ -2882,60 +2789,6 @@ BOOL MethodDesc::IsClassConstructorTriggeredViaPrestub()
#endif // !DACCESS_COMPILE
-#ifdef FEATURE_REMOTING
-
-//*******************************************************************************
-BOOL MethodDesc::MayBeRemotingIntercepted()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- if (IsStatic())
- return FALSE;
-
- MethodTable *pMT = GetMethodTable();
-
- if (pMT->IsMarshaledByRef())
- return TRUE;
-
- if (g_pObjectClass == pMT)
- {
- if ((this == g_pObjectCtorMD) || (this == g_pObjectFinalizerMD))
- return FALSE;
-
- // Make sure that the above check worked well
- _ASSERTE(this->GetSlot() != g_pObjectCtorMD->GetSlot());
- _ASSERTE(this->GetSlot() != g_pObjectFinalizerMD->GetSlot());
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-//*******************************************************************************
-BOOL MethodDesc::IsRemotingInterceptedViaPrestub()
-{
- WRAPPER_NO_CONTRACT;
- // We do not insert a remoting stub around the shared code method descriptor
- // for instantiated generic methods, i.e. anything which requires a hidden
- // instantiation argument. Instead we insert it around the instantiating stubs
- // and ensure that we call the instantiating stubs directly.
- return MayBeRemotingIntercepted() && !IsVtableMethod() && !RequiresInstArg();
-}
-
-//*******************************************************************************
-BOOL MethodDesc::IsRemotingInterceptedViaVirtualDispatch()
-{
- WRAPPER_NO_CONTRACT;
- return MayBeRemotingIntercepted() && IsVtableMethod();
-}
-
-#endif // FEATURE_REMOTING
//*******************************************************************************
BOOL MethodDesc::MayHaveNativeCode()
@@ -3260,15 +3113,6 @@ bool MethodDesc::CanSkipDoPrestub (
return false;
}
-#ifdef FEATURE_CER
- // Can't hard bind to a method which contains one or more Constrained Execution Region roots (we need to force the prestub to
- // execute for such methods).
- if (ContainsPrePreparableCerRoot(this))
- {
- *pReason = CORINFO_INDIRECT_CALL_CER;
- return false;
- }
-#endif // FEATURE_CER
// Check whether our methoddesc needs restore
if (NeedsRestore(GetAppDomain()->ToCompilationDomain()->GetTargetImage(), TRUE))
@@ -5198,12 +5042,14 @@ LPVOID NDirectMethodDesc::FindEntryPoint(HINSTANCE hMod) const
FARPROC pFunc = NULL, pFuncW = NULL;
+#ifndef FEATURE_PAL
// Handle ordinals.
if (GetEntrypointName()[0] == '#')
{
long ordinal = atol(GetEntrypointName()+1);
return reinterpret_cast<LPVOID>(GetProcAddress(hMod, (LPCSTR)(size_t)((UINT16)ordinal)));
}
+#endif
// Just look for the unmangled name. If it is unicode fcn, we are going
// to need to check for the 'W' API because it takes precedence over the
@@ -5227,36 +5073,6 @@ LPVOID NDirectMethodDesc::FindEntryPoint(HINSTANCE hMod) const
DWORD nbytes = (DWORD)(strlen(GetEntrypointName()) + 1);
szAnsiEntrypointName[nbytes] = '\0'; // Add an extra '\0'.
-#if !defined(FEATURE_CORECLR) && defined(_WIN64)
- //
- // Forward {Get|Set}{Window|Class}Long to their corresponding Ptr version
- //
-
- // LONG SetWindowLong( HWND hWnd, int nIndex, LONG dwNewLong);
- // LONG_PTR SetWindowLongPtr(HWND hWnd, int nIndex, LONG_PTR dwNewLong);
- //
- // LONG GetWindowLong( HWND hWnd, int nIndex);
- // LONG_PTR GetWindowLongPtr(HWND hWnd, int nIndex);
- //
- // DWORD GetClassLong( HWND hWnd, int nIndex);
- // ULONG_PTR GetClassLongPtr( HWND hWnd, int nIndex);
- //
- // DWORD SetClassLong( HWND hWnd, int nIndex, LONG dwNewLong);
- // ULONG_PTR SetClassLongPtr( HWND hWnd, int nIndex, LONG_PTR dwNewLong);
-
- if (!SString::_stricmp(GetEntrypointName(), "SetWindowLong") ||
- !SString::_stricmp(GetEntrypointName(), "GetWindowLong") ||
- !SString::_stricmp(GetEntrypointName(), "SetClassLong") ||
- !SString::_stricmp(GetEntrypointName(), "GetClassLong"))
- {
- szAnsiEntrypointName[nbytes-1] = 'P';
- szAnsiEntrypointName[nbytes+0] = 't';
- szAnsiEntrypointName[nbytes+1] = 'r';
- szAnsiEntrypointName[nbytes+2] = '\0';
- szAnsiEntrypointName[nbytes+3] = '\0';
- nbytes += 3;
- }
-#endif // !FEATURE_CORECLR && _WIN64
// If the program wants the ANSI api or if Unicode APIs are unavailable.
if (IsNativeAnsi())
@@ -5279,25 +5095,6 @@ LPVOID NDirectMethodDesc::FindEntryPoint(HINSTANCE hMod) const
if (!pFunc)
{
-#if !defined(FEATURE_CORECLR)
- if (hMod == CLRGetModuleHandle(W("kernel32.dll")))
- {
- szAnsiEntrypointName[nbytes-1] = '\0';
- if (0==strcmp(szAnsiEntrypointName, "MoveMemory") ||
- 0==strcmp(szAnsiEntrypointName, "CopyMemory"))
- {
- pFunc = GetProcAddress(hMod, funcName = "RtlMoveMemory");
- }
- else if (0==strcmp(szAnsiEntrypointName, funcName = "FillMemory"))
- {
- pFunc = GetProcAddress(hMod, funcName = "RtlFillMemory");
- }
- else if (0==strcmp(szAnsiEntrypointName, funcName = "ZeroMemory"))
- {
- pFunc = GetProcAddress(hMod, funcName = "RtlZeroMemory");
- }
- }
-#endif // !FEATURE_CORECLR
#if defined(_TARGET_X86_)
/* try mangled names only for __stdcalls */
@@ -5322,37 +5119,6 @@ LPVOID NDirectMethodDesc::FindEntryPoint(HINSTANCE hMod) const
}
#endif // CROSSGEN_COMPILE
-#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE)
-//*******************************************************************************
-void NDirectMethodDesc::InitEarlyBoundNDirectTarget()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END
-
- _ASSERTE(IsEarlyBound());
-
- if (IsClassConstructorTriggeredAtLinkTime())
- {
- GetMethodTable()->CheckRunClassInitThrowing();
- }
-
- const void *target = GetModule()->GetInternalPInvokeTarget(GetRVA());
- _ASSERTE(target != 0);
-
- if (HeuristicDoesThisLookLikeAGetLastErrorCall((LPBYTE)target))
- target = (BYTE*) FalseGetLastError;
-
- // As long as we've set the NDirect target field we don't need to backpatch the import thunk glue.
- // All NDirect calls all through the NDirect target, so if it's updated, then we won't go into
- // NDirectImportThunk(). In fact, backpatching the import thunk glue leads to race conditions.
- SetNDirectTarget((LPVOID)target);
-}
-#endif // FEATURE_MIXEDMODE && !CROSSGEN_COMPILE
//*******************************************************************************
void MethodDesc::ComputeSuppressUnmanagedCodeAccessAttr(IMDInternalImport *pImport)
@@ -5365,29 +5131,6 @@ void MethodDesc::ComputeSuppressUnmanagedCodeAccessAttr(IMDInternalImport *pImpo
}
CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- // We only care about this bit for NDirect and ComPlusCall
- if (!IsNDirect() && !IsComPlusCall())
- return;
-
- BOOL hasAttr = FALSE;
- HRESULT hr = pImport->GetCustomAttributeByName(GetMemberDef(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL);
- IfFailThrow(hr);
- hasAttr = (hr == S_OK);
-
-
- if (IsNDirect())
- ((NDirectMethodDesc*)this)->SetSuppressUnmanagedCodeAccessAttr(hasAttr);
-
-#ifdef FEATURE_COMINTEROP
- if (IsComPlusCall())
- ((ComPlusCallMethodDesc*)this)->SetSuppressUnmanagedCodeAccessAttr(hasAttr);
-#endif
-
-#endif // FEATURE_COMINTEROP
}
//*******************************************************************************
@@ -5402,7 +5145,6 @@ BOOL MethodDesc::HasNativeCallableAttribute()
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
HRESULT hr = GetMDImport()->GetCustomAttributeByName(GetMemberDef(),
g_NativeCallableAttribute,
NULL,
@@ -5411,7 +5153,6 @@ BOOL MethodDesc::HasNativeCallableAttribute()
{
return TRUE;
}
-#endif //FEATURE_CORECLR
return FALSE;
}
@@ -5421,27 +5162,7 @@ BOOL MethodDesc::HasSuppressUnmanagedCodeAccessAttr()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return TRUE;
-#else // FEATURE_CORECLR
-
- // In AppX processes, there is only one full trust AppDomain, so there is never any need to do a security
- // callout on interop stubs
- if (AppX::IsAppXProcess())
- {
- return TRUE;
- }
-
- if (IsNDirect())
- return ((NDirectMethodDesc*)this)->HasSuppressUnmanagedCodeAccessAttr();
-#ifdef FEATURE_COMINTEROP
- else if (IsComPlusCall())
- return ((ComPlusCallMethodDesc*)this)->HasSuppressUnmanagedCodeAccessAttr();
-#endif // FEATURE_COMINTEROP
- else
- return FALSE;
-
-#endif // FEATURE_CORECLR
}
#ifdef FEATURE_COMINTEROP
diff --git a/src/vm/method.hpp b/src/vm/method.hpp
index 499112d149..9545da2248 100644
--- a/src/vm/method.hpp
+++ b/src/vm/method.hpp
@@ -797,24 +797,6 @@ public:
//================================================================
// Does it represent a one way method call with no out/return parameters?
-#ifdef FEATURE_REMOTING
- inline BOOL IsOneWay()
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END
-
- return (S_OK == GetMDImport()->GetCustomAttributeByName(GetMemberDef(),
- "System.Runtime.Remoting.Messaging.OneWayAttribute",
- NULL,
- NULL));
-
- }
-#endif // FEATURE_REMOTING
//================================================================
// FCalls.
@@ -1308,6 +1290,58 @@ public:
public:
+#ifdef FEATURE_TIERED_COMPILATION
+ // Is this method allowed to be recompiled and the entrypoint redirected so that we
+ // can optimize its performance? Eligibility is invariant for the lifetime of a method.
+ BOOL IsEligibleForTieredCompilation()
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ // This policy will need to change some more before tiered compilation feature
+ // can be properly supported across a broad range of scenarios. For instance it
+ // wouldn't interact correctly debugging or profiling at the moment because we
+ // enable it too aggresively and it conflicts with the operations of those features.
+
+ //Keep in-sync with MethodTableBuilder::NeedsNativeCodeSlot(bmtMDMethod * pMDMethod)
+ //In the future we might want mutable vtable slots too, but that would require
+ //more work around the runtime to prevent those mutable pointers from leaking
+ return g_pConfig->TieredCompilation() &&
+ !GetModule()->HasNativeOrReadyToRunImage() &&
+ !IsEnCMethod() &&
+ HasNativeCodeSlot();
+
+ }
+#endif
+
+ // Does this method force the NativeCodeSlot to stay fixed after it
+ // is first initialized to native code? Consumers of the native code
+ // pointer need to be very careful about if and when they cache it
+ // if it is not stable.
+ //
+ // The stability of the native code pointer is separate from the
+ // stability of the entrypoint. A stable entrypoint can be a precode
+ // which dispatches to an unstable native code pointer.
+ BOOL IsNativeCodeStableAfterInit()
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+ return
+#ifdef FEATURE_TIERED_COMPILATION
+ !IsEligibleForTieredCompilation() &&
+#endif
+ !IsEnCMethod();
+ }
+
+ //Is this method currently pointing to native code that will never change?
+ BOOL IsPointingToStableNativeCode()
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+
+ if (!IsNativeCodeStableAfterInit())
+ return FALSE;
+
+ return IsPointingToNativeCode();
+ }
+
// Note: We are skipping the prestub based on addition information from the JIT.
// (e.g. that the call is on same this ptr or that the this ptr is not null).
// Thus we can end up with a running NGENed method for which IsPointingToNativeCode is false!
@@ -2645,19 +2679,6 @@ public:
// Atomically set specified flags. Only setting of the bits is supported.
void InterlockedSetNDirectFlags(WORD wFlags);
-#ifdef FEATURE_MIXEDMODE // IJW
- void SetIsEarlyBound()
- {
- LIMITED_METHOD_CONTRACT;
- ndirect.m_wFlags |= kEarlyBound;
- }
-
- BOOL IsEarlyBound()
- {
- LIMITED_METHOD_CONTRACT;
- return (ndirect.m_wFlags & kEarlyBound) != 0;
- }
-#endif // FEATURE_MIXEDMODE
BOOL IsNativeAnsi() const
{
@@ -2673,22 +2694,6 @@ public:
return (ndirect.m_wFlags & kNativeNoMangle) != 0;
}
-#ifndef FEATURE_CORECLR
- BOOL HasSuppressUnmanagedCodeAccessAttr() const
- {
- LIMITED_METHOD_CONTRACT;
-
- return (ndirect.m_wFlags & kHasSuppressUnmanagedCodeAccess) != 0;
- }
-
- void SetSuppressUnmanagedCodeAccessAttr(BOOL value)
- {
- LIMITED_METHOD_CONTRACT;
-
- if (value)
- ndirect.m_wFlags |= kHasSuppressUnmanagedCodeAccess;
- }
-#endif
DWORD GetECallID() const
{
@@ -2896,9 +2901,6 @@ public:
}
#endif // defined(_TARGET_X86_)
-#ifdef FEATURE_MIXEDMODE // IJW
- VOID InitEarlyBoundNDirectTarget();
-#endif
// In AppDomains, we can trigger declarer's cctor when we link the P/Invoke,
// which takes care of inlined calls as well. See code:NDirect.NDirectLink.
@@ -2962,12 +2964,7 @@ struct ComPlusCallInfo
kHasCopyCtorArgs = 0x4,
};
-#if defined(FEATURE_REMOTING) && !defined(HAS_REMOTING_PRECODE)
- // These two fields cannot overlap in this case because of AMD64 GenericComPlusCallStub uses m_pILStub on the COM event provider path
- struct
-#else
union
-#endif
{
// IL stub for CLR to COM call
PCODE m_pILStub;
@@ -3101,32 +3098,6 @@ public:
return m_pComPlusCallInfo->m_pEventProviderMD;
}
-#ifndef FEATURE_CORECLR
-
- BOOL HasSuppressUnmanagedCodeAccessAttr()
- {
- LIMITED_METHOD_CONTRACT;
-
- if (m_pComPlusCallInfo != NULL)
- {
- return (m_pComPlusCallInfo->m_flags & ComPlusCallInfo::kHasSuppressUnmanagedCodeAccess) != 0;
- }
-
- // it is possible that somebody will call this before we initialized m_pComPlusCallInfo
- return (GetMDImport()->GetCustomAttributeByName(GetMemberDef(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK);
- }
-
- void SetSuppressUnmanagedCodeAccessAttr(BOOL value)
- {
- LIMITED_METHOD_CONTRACT;
-
- if (value)
- FastInterlockOr(reinterpret_cast<DWORD *>(&m_pComPlusCallInfo->m_flags), ComPlusCallInfo::kHasSuppressUnmanagedCodeAccess);
- }
-#endif // FEATURE_CORECLR
BOOL RequiresArgumentWrapping()
{
diff --git a/src/vm/method.inl b/src/vm/method.inl
index d668216243..cdd137b84b 100644
--- a/src/vm/method.inl
+++ b/src/vm/method.inl
@@ -152,7 +152,6 @@ inline void MethodDesc::SetupGenericComPlusCall()
}
#endif // FEATURE_COMINTEROP
-#ifndef FEATURE_REMOTING
inline BOOL MethodDesc::MayBeRemotingIntercepted()
{
@@ -172,7 +171,6 @@ inline BOOL MethodDesc::IsRemotingInterceptedViaVirtualDispatch()
return FALSE;
}
-#endif // FEATURE_REMOTING
#ifdef FEATURE_COMINTEROP
diff --git a/src/vm/methodtable.cpp b/src/vm/methodtable.cpp
index 6fee50b9b1..21fab720f2 100644
--- a/src/vm/methodtable.cpp
+++ b/src/vm/methodtable.cpp
@@ -40,9 +40,6 @@
#include "eventtrace.h"
#include "fieldmarshaler.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "eeprofinterfaces.h"
#include "dllimportcallback.h"
@@ -60,8 +57,6 @@
#include "zapsig.h"
#endif //FEATURE_PREJIT
-#include "hostexecutioncontext.h"
-
#ifdef FEATURE_COMINTEROP
#include "comcallablewrapper.h"
#include "clrtocomcall.h"
@@ -78,9 +73,6 @@
#include "genericdict.h"
#include "typestring.h"
#include "typedesc.h"
-#ifdef FEATURE_REMOTING
-#include "crossdomaincalls.h"
-#endif
#include "array.h"
#ifdef FEATURE_INTERPRETER
@@ -625,7 +617,7 @@ void MethodTable::SetComObjectType()
#endif // FEATURE_COMINTEROP
-#if defined(FEATURE_TYPEEQUIVALENCE) || defined(FEATURE_REMOTING)
+#if defined(FEATURE_TYPEEQUIVALENCE)
void MethodTable::SetHasTypeEquivalence()
{
LIMITED_METHOD_CONTRACT;
@@ -969,56 +961,6 @@ MethodTable* CreateMinimalMethodTable(Module* pContainingModule,
return pMT;
}
-#ifdef FEATURE_REMOTING
-//==========================================================================================
-void MethodTable::SetupRemotableMethodInfo(AllocMemTracker *pamTracker)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
- // Make RMI for a method table.
- CrossDomainOptimizationInfo *pRMIBegin = NULL;
- if (GetNumMethods() > 0)
- {
- SIZE_T requiredSize = CrossDomainOptimizationInfo::SizeOf(GetNumVtableSlots());
- pRMIBegin = (CrossDomainOptimizationInfo*) pamTracker->Track(GetLoaderAllocator()->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(requiredSize)));
- _ASSERTE(IS_ALIGNED(pRMIBegin, sizeof(void*)));
- }
- *(GetRemotableMethodInfoPtr()) = pRMIBegin;
-}
-
-//==========================================================================================
-PTR_RemotingVtsInfo MethodTable::AllocateRemotingVtsInfo(AllocMemTracker *pamTracker, DWORD dwNumFields)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // Size the data structure to contain enough bit flags for all the
- // instance fields.
- DWORD cbInfo = RemotingVtsInfo::GetSize(dwNumFields);
- RemotingVtsInfo *pInfo = (RemotingVtsInfo*)pamTracker->Track(GetLoaderAllocator()->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(cbInfo)));
-
- // Note: Memory allocated on loader heap is zero filled
- // ZeroMemory(pInfo, cbInfo);
-
-#ifdef _DEBUG
- pInfo->m_dwNumFields = dwNumFields;
-#endif
-
- *(GetRemotingVtsInfoPtr()) = pInfo;
-
- return pInfo;
-}
-#endif // FEATURE_REMOTING
#ifdef FEATURE_COMINTEROP
#ifndef CROSSGEN_COMPILE
@@ -3038,7 +2980,7 @@ bool MethodTable::ClassifyEightBytesWithNativeLayout(SystemVStructRegisterPassin
}
// Assigns the classification types to the array with eightbyte types.
-void MethodTable::AssignClassifiedEightByteTypes(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel)
+void MethodTable::AssignClassifiedEightByteTypes(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel) const
{
static const size_t CLR_SYSTEMV_MAX_BYTES_TO_PASS_IN_REGISTERS = CLR_SYSTEMV_MAX_EIGHTBYTES_COUNT_TO_PASS_IN_REGISTERS * SYSTEMV_EIGHT_BYTE_SIZE_IN_BYTES;
static_assert_no_msg(CLR_SYSTEMV_MAX_BYTES_TO_PASS_IN_REGISTERS == SYSTEMV_MAX_NUM_FIELDS_IN_REGISTER_PASSED_STRUCT);
@@ -3965,10 +3907,6 @@ void MethodTable::CallFinalizer(Object *obj)
return;
}
-#ifdef FEATURE_CAS_POLICY
- // Notify the host to setup the restricted context before finalizing each object
- HostExecutionContextManager::SetHostRestrictedContext();
-#endif // FEATURE_CAS_POLICY
// Determine if the object has a critical or normal finalizer.
BOOL fCriticalFinalizer = pMT->HasCriticalFinalizer();
@@ -4293,25 +4231,6 @@ void MethodTable::Save(DataImage *image, DWORD profilingFlags)
}
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_REMOTING
- if (HasRemotableMethodInfo())
- {
- if (GetNumMethods() > 0)
- {
- // The CrossDomainOptimizationInfo was populated earlier in Module::PrepareTypesForSave
- CrossDomainOptimizationInfo* pRMI = GetRemotableMethodInfo();
- SIZE_T sizeToBeSaved = CrossDomainOptimizationInfo::SizeOf(this);
- image->StoreStructure(pRMI, sizeToBeSaved,
- DataImage::ITEM_CROSS_DOMAIN_INFO);
- }
- }
-
- // Store any optional VTS (Version Tolerant Serialization) info.
- if (HasRemotingVtsInfo())
- image->StoreStructure(GetRemotingVtsInfo(),
- RemotingVtsInfo::GetSize(GetNumIntroducedInstanceFields()),
- DataImage::ITEM_VTS_INFO);
-#endif //FEATURE_REMOTING
#ifdef _DEBUG
if (GetDebugClassName() != NULL && !image->IsStored(GetDebugClassName()))
@@ -4457,19 +4376,6 @@ void MethodTable::Save(DataImage *image, DWORD profilingFlags)
// MethodTable WriteableData
-#ifdef FEATURE_REMOTING
- // Store any context static info.
- if (HasContextStatics())
- {
- DataImage::ItemKind kindWriteable = DataImage::ITEM_METHOD_TABLE_DATA_COLD_WRITEABLE;
- if ((profilingFlags & (1 << WriteMethodTableWriteableData)) != 0)
- kindWriteable = DataImage::ITEM_METHOD_TABLE_DATA_HOT_WRITEABLE;
-
- image->StoreStructure(GetContextStaticsBucket(),
- sizeof(ContextStaticsBucket),
- kindWriteable);
- }
-#endif // FEATURE_REMOTING
PTR_Const_MethodTableWriteableData pWriteableData = GetWriteableData_NoLogging();
_ASSERTE(pWriteableData != NULL);
@@ -4709,11 +4615,6 @@ BOOL MethodTable::IsWriteable()
{
STANDARD_VM_CONTRACT;
- // Overlapped method table is written into in hosted scenarios
- // (see code:CorHost2::GetHostOverlappedExtensionSize)
- if (MscorlibBinder::IsClass(this, CLASS__OVERLAPPEDDATA))
- return TRUE;
-
#ifdef FEATURE_COMINTEROP
// Dynamic expansion of interface map writes into method table
// (see code:MethodTable::AddDynamicInterface)
@@ -4933,27 +4834,6 @@ void MethodTable::Fixup(DataImage *image)
}
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_REMOTING
- if (HasRemotableMethodInfo())
- {
- CrossDomainOptimizationInfo **pRMI = GetRemotableMethodInfoPtr();
- if (*pRMI != NULL)
- {
- image->FixupPointerField(this, (BYTE *)pRMI - (BYTE *)this);
- }
- }
-
- // Optional VTS (Version Tolerant Serialization) fixups.
- if (HasRemotingVtsInfo())
- {
- RemotingVtsInfo **ppVtsInfo = GetRemotingVtsInfoPtr();
- image->FixupPointerField(this, (BYTE *)ppVtsInfo - (BYTE *)this);
-
- RemotingVtsInfo *pVtsInfo = *ppVtsInfo;
- for (DWORD i = 0; i < RemotingVtsInfo::VTS_NUM_CALLBACK_TYPES; i++)
- image->FixupMethodDescPointer(pVtsInfo, &pVtsInfo->m_pCallbacks[i]);
- }
-#endif //FEATURE_REMOTING
//
// Fix flags
@@ -5180,16 +5060,6 @@ void MethodTable::Fixup(DataImage *image)
_ASSERTE(!NeedsCrossModuleGenericsStaticsInfo());
}
-#ifdef FEATURE_REMOTING
- if (HasContextStatics())
- {
- ContextStaticsBucket **ppInfo = GetContextStaticsBucketPtr();
- image->FixupPointerField(this, (BYTE *)ppInfo - (BYTE *)this);
-
- ContextStaticsBucket *pNewInfo = (ContextStaticsBucket*)image->GetImagePointer(*ppInfo);
- pNewInfo->m_dwContextStaticsOffset = (DWORD)-1;
- }
-#endif // FEATURE_REMOTING
LOG((LF_ZAP, LL_INFO10000, "MethodTable::Fixup %s (%p) complete\n", GetDebugClassName(), this));
@@ -6259,9 +6129,6 @@ MethodTable* MethodTable::GetComPlusParentMethodTable()
// Skip over System.__ComObject, expect System.MarshalByRefObject
pParent=pParent->GetParentMethodTable();
_ASSERTE(pParent != NULL);
-#ifdef FEATURE_REMOTING
- _ASSERTE(pParent->IsMarshaledByRef());
-#endif
_ASSERTE(pParent->GetParentMethodTable() != NULL);
_ASSERTE(pParent->GetParentMethodTable() == g_pObjectClass);
}
@@ -9742,66 +9609,12 @@ LPCWSTR MethodTable::GetPathForErrorMessages()
}
}
-#ifdef FEATURE_REMOTING
-//==========================================================================================
-// context static functions
-void MethodTable::SetupContextStatics(AllocMemTracker *pamTracker, WORD wContextStaticsSize)
-{
- STANDARD_VM_CONTRACT;
-
- ContextStaticsBucket* pCSInfo = (ContextStaticsBucket*) pamTracker->Track(GetLoaderAllocator()->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(ContextStaticsBucket))));
- *(GetContextStaticsBucketPtr()) = pCSInfo;
-
- pCSInfo->m_dwContextStaticsOffset = (DWORD)-1; // Initialized lazily
- pCSInfo->m_wContextStaticsSize = wContextStaticsSize;
-}
-
-#ifndef CROSSGEN_COMPILE
-//==========================================================================================
-DWORD MethodTable::AllocateContextStaticsOffset()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- g_IBCLogger.LogMethodTableWriteableDataWriteAccess(this);
-
- BaseDomain* pDomain = IsDomainNeutral() ? SystemDomain::System() : GetDomain();
-
- ContextStaticsBucket* pCSInfo = GetContextStaticsBucket();
- DWORD* pOffsetSlot = &pCSInfo->m_dwContextStaticsOffset;
-
- return pDomain->AllocateContextStaticsOffset(pOffsetSlot);
-}
-#endif // CROSSGEN_COMPILE
-
-#endif // FEATURE_REMOTING
bool MethodTable::ClassRequiresUnmanagedCodeCheck()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
return false;
-#else
- // all WinRT types have an imaginary [SuppressUnmanagedCodeSecurity] attribute on them
- if (IsProjectedFromWinRT())
- return false;
-
- // In AppX processes, there is only one full trust AppDomain, so there is never any need to do a security
- // callout on interop stubs
- if (AppX::IsAppXProcess())
- return false;
-
- return GetMDImport()->GetCustomAttributeByName(GetCl(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_FALSE;
-#endif // FEATURE_CORECLR
}
#endif // !DACCESS_COMPILE
diff --git a/src/vm/methodtable.h b/src/vm/methodtable.h
index 529145a726..d5cb5ba866 100644
--- a/src/vm/methodtable.h
+++ b/src/vm/methodtable.h
@@ -59,10 +59,6 @@ class Object;
class Stub;
class Substitution;
class TypeHandle;
-#ifdef FEATURE_REMOTING
-class CrossDomainOptimizationInfo;
-typedef DPTR(CrossDomainOptimizationInfo) PTR_CrossDomainOptimizationInfo;
-#endif
class Dictionary;
class AllocMemTracker;
class SimpleRWLock;
@@ -878,7 +874,7 @@ public:
// mark the class type as COM object class
void SetComObjectType();
-#if defined(FEATURE_TYPEEQUIVALENCE) || defined(FEATURE_REMOTING)
+#if defined(FEATURE_TYPEEQUIVALENCE)
// mark the type as opted into type equivalence
void SetHasTypeEquivalence();
#endif
@@ -1074,7 +1070,7 @@ public:
private:
#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
- void AssignClassifiedEightByteTypes(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel);
+ void AssignClassifiedEightByteTypes(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel) const;
// Builds the internal data structures and classifies struct eightbytes for Amd System V calling convention.
bool ClassifyEightBytesWithManagedLayout(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel, unsigned int startOffsetOfStruct, bool isNativeStruct);
bool ClassifyEightBytesWithNativeLayout(SystemVStructRegisterPassingHelperPtr helperPtr, unsigned int nestingLevel, unsigned int startOffsetOfStruct, bool isNativeStruct);
@@ -1963,43 +1959,6 @@ public:
// The following service adjusts a MethodTable based on the supplied instance. As
// we add new thunking layers, we just need to teach this service how to navigate
// through them.
-#ifdef FEATURE_REMOTING
- inline BOOL IsTransparentProxy()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return GetFlag(enum_flag_Category_Mask) == enum_flag_Category_TransparentProxy;
- }
- inline void SetTransparentProxy()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(GetFlag(enum_flag_Category_Mask) == 0);
- SetFlag(enum_flag_Category_TransparentProxy);
- }
-
- inline BOOL IsMarshaledByRef()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return GetFlag(enum_flag_Category_MarshalByRef_Mask) == enum_flag_Category_MarshalByRef;
- }
- inline void SetMarshaledByRef()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(GetFlag(enum_flag_Category_Mask) == 0);
- SetFlag(enum_flag_Category_MarshalByRef);
- }
-
- inline BOOL IsContextful()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- return GetFlag(enum_flag_Category_Mask) == enum_flag_Category_Contextful;
- }
- inline void SetIsContextful()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(GetFlag(enum_flag_Category_Mask) == 0);
- SetFlag(enum_flag_Category_Contextful);
- }
-#else // FEATURE_REMOTING
inline BOOL IsTransparentProxy()
{
return FALSE;
@@ -2014,7 +1973,6 @@ public:
{
return FALSE;
}
-#endif // FEATURE_REMOTING
inline bool RequiresFatDispatchTokens()
{
@@ -2054,7 +2012,7 @@ public:
}
#endif // FEATURE_HFA
-#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
inline bool IsRegPassedStruct()
{
LIMITED_METHOD_CONTRACT;
@@ -2066,7 +2024,7 @@ public:
LIMITED_METHOD_CONTRACT;
SetFlag(enum_flag_IsRegStructPassed);
}
-#endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
+#endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
#ifdef FEATURE_HFA
@@ -2974,39 +2932,6 @@ public:
//-------------------------------------------------------------------
// REMOTEABLE METHOD INFO
//
-#ifdef FEATURE_REMOTING
- BOOL HasRemotableMethodInfo();
-
- PTR_CrossDomainOptimizationInfo GetRemotableMethodInfo()
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- MODE_ANY;
- }
- CONTRACTL_END;
- _ASSERTE(HasRemotableMethodInfo());
- return *GetRemotableMethodInfoPtr();
- }
- void SetupRemotableMethodInfo(AllocMemTracker *pamTracker);
-
- //-------------------------------------------------------------------
- // REMOTING VTS INFO
- //
- // This optional addition to MethodTables allows us to locate VTS (Version
- // Tolerant Serialization) event callback methods and optionally
- // serializable fields quickly. We also store the NotSerialized field
- // information in here so remoting can avoid one more touch of the metadata
- // during cross appdomain cloning.
- //
-
- void SetHasRemotingVtsInfo();
- BOOL HasRemotingVtsInfo();
- PTR_RemotingVtsInfo GetRemotingVtsInfo();
- PTR_RemotingVtsInfo AllocateRemotingVtsInfo( AllocMemTracker *pamTracker, DWORD dwNumFields);
-#endif // FEATURE_REMOTING
#ifdef FEATURE_COMINTEROP
void SetHasGuidInfo();
@@ -3150,9 +3075,6 @@ public:
inline DWORD GetAttrClass();
inline BOOL IsSerializable();
-#ifdef FEATURE_REMOTING
- inline BOOL CannotBeBlittedByObjectCloner();
-#endif
inline BOOL HasFieldsWhichMustBeInited();
inline BOOL SupportsAutoNGen();
inline BOOL RunCCTorAsIfNGenImageExists();
@@ -3871,9 +3793,6 @@ private:
enum_flag_GenericsMask_SharedInst = 0x00000020, // shared instantiation, e.g. List<__Canon> or List<MyValueType<__Canon>>
enum_flag_GenericsMask_TypicalInst = 0x00000030, // the type instantiated at its formal parameters, e.g. List<T>
-#ifdef FEATURE_REMOTING
- enum_flag_ContextStatic = 0x00000040,
-#endif
enum_flag_HasRemotingVtsInfo = 0x00000080, // Optional data present indicating VTS methods and optional fields
enum_flag_HasVariance = 0x00000100, // This is an instantiated type some of whose type parameters are co or contra-variant
@@ -3882,18 +3801,18 @@ private:
enum_flag_HasPreciseInitCctors = 0x00000400, // Do we need to run class constructors at allocation time? (Not perf important, could be moved to EEClass
#if defined(FEATURE_HFA)
-#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
-#error Can't define both FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
+#error Can't define both FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING
#endif
enum_flag_IsHFA = 0x00000800, // This type is an HFA (Homogenous Floating-point Aggregate)
#endif // FEATURE_HFA
-#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF)
+#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
#if defined(FEATURE_HFA)
-#error Can't define both FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#error Can't define both FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING
#endif
enum_flag_IsRegStructPassed = 0x00000800, // This type is a System V register passed struct.
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
enum_flag_IsByRefLike = 0x00001000,
@@ -3914,9 +3833,6 @@ private:
enum_flag_StringArrayValues = SET_TRUE(enum_flag_StaticsMask_NonDynamic) |
SET_FALSE(enum_flag_NotInPZM) |
SET_TRUE(enum_flag_GenericsMask_NonGeneric) |
-#ifdef FEATURE_REMOTING
- SET_FALSE(enum_flag_ContextStatic) |
-#endif
SET_FALSE(enum_flag_HasVariance) |
SET_FALSE(enum_flag_HasDefaultCtor) |
SET_FALSE(enum_flag_HasPreciseInitCctors),
@@ -4249,14 +4165,7 @@ private:
#define METHODTABLE_COMINTEROP_OPTIONAL_MEMBERS()
#endif
-#ifdef FEATURE_REMOTING
-#define METHODTABLE_REMOTING_OPTIONAL_MEMBERS() \
- METHODTABLE_OPTIONAL_MEMBER(RemotingVtsInfo, PTR_RemotingVtsInfo, GetRemotingVtsInfoPtr ) \
- METHODTABLE_OPTIONAL_MEMBER(RemotableMethodInfo, PTR_CrossDomainOptimizationInfo,GetRemotableMethodInfoPtr ) \
- METHODTABLE_OPTIONAL_MEMBER(ContextStatics, PTR_ContextStaticsBucket, GetContextStaticsBucketPtr )
-#else
#define METHODTABLE_REMOTING_OPTIONAL_MEMBERS()
-#endif
enum OptionalMemberId
{
@@ -4368,25 +4277,6 @@ private:
************************************/
public:
-#ifdef FEATURE_REMOTING
- inline BOOL HasContextStatics();
- inline void SetHasContextStatics();
-
- inline PTR_ContextStaticsBucket GetContextStaticsBucket()
- {
- LIMITED_METHOD_DAC_CONTRACT;
- _ASSERTE(HasContextStatics());
- PTR_ContextStaticsBucket pBucket = *GetContextStaticsBucketPtr();
- _ASSERTE(pBucket != NULL);
- return pBucket;
- }
-
- inline DWORD GetContextStaticsOffset();
- inline WORD GetContextStaticsSize();
-
- void SetupContextStatics(AllocMemTracker *pamTracker, WORD dwContextStaticsSize);
- DWORD AllocateContextStaticsOffset();
-#endif
BOOL Validate ();
diff --git a/src/vm/methodtable.inl b/src/vm/methodtable.inl
index d91d52ca6e..c762512bf1 100644
--- a/src/vm/methodtable.inl
+++ b/src/vm/methodtable.inl
@@ -346,14 +346,6 @@ inline BOOL MethodTable::SupportsGenericInterop(TypeHandle::InteropKind interopK
#endif // FEATURE_COMINTEROP
}
-#ifdef FEATURE_REMOTING
-//==========================================================================================
-inline BOOL MethodTable::CannotBeBlittedByObjectCloner()
-{
- WRAPPER_NO_CONTRACT;
- return GetClass()->CannotBeBlittedByObjectCloner();
-}
-#endif
//==========================================================================================
inline BOOL MethodTable::IsNotTightlyPacked()
@@ -373,26 +365,18 @@ inline BOOL MethodTable::HasFieldsWhichMustBeInited()
inline BOOL MethodTable::SupportsAutoNGen()
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- return GetAssembly()->SupportsAutoNGen();
-#else
return FALSE;
-#endif
}
//==========================================================================================
inline BOOL MethodTable::RunCCTorAsIfNGenImageExists()
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- return this->SupportsAutoNGen();
-#else
#ifdef FEATURE_CORESYSTEM
return TRUE; // On our coresystem builds we will always be using triton in the customer scenario.
#else
return FALSE;
#endif
-#endif
}
//==========================================================================================
@@ -403,35 +387,6 @@ inline BOOL MethodTable::IsAbstract()
}
//==========================================================================================
-#ifdef FEATURE_REMOTING
-inline BOOL MethodTable::HasRemotableMethodInfo()
-{
- WRAPPER_NO_CONTRACT;
- return (IsMarshaledByRef() || IsInterface() || this == g_pObjectClass || g_pObjectClass == NULL) && IsCanonicalMethodTable();
-}
-
-//==========================================================================================
-inline void MethodTable::SetHasRemotingVtsInfo()
-{
- LIMITED_METHOD_CONTRACT;
- SetFlag(enum_flag_HasRemotingVtsInfo);
-}
-
-//==========================================================================================
-inline BOOL MethodTable::HasRemotingVtsInfo()
-{
- LIMITED_METHOD_DAC_CONTRACT;
- return GetFlag(enum_flag_HasRemotingVtsInfo);
-}
-
-//==========================================================================================
-inline PTR_RemotingVtsInfo MethodTable::GetRemotingVtsInfo()
-{
- WRAPPER_NO_CONTRACT;
- _ASSERTE(HasRemotingVtsInfo());
- return *GetRemotingVtsInfoPtr();
-}
-#endif // FEATURE_REMOTING
#ifdef FEATURE_COMINTEROP
//==========================================================================================
@@ -537,14 +492,7 @@ inline BOOL MethodTable::IsFieldNotSerialized(DWORD dwFieldIndex)
{
LIMITED_METHOD_CONTRACT;
_ASSERTE(IsSerializable());
-#ifdef FEATURE_REMOTING
- if (!HasRemotingVtsInfo())
- return FALSE;
-
- return GetRemotingVtsInfo()->IsNotSerialized(dwFieldIndex);
-#else
return FALSE;
-#endif
}
//==========================================================================================
@@ -552,14 +500,7 @@ inline BOOL MethodTable::IsFieldOptionallySerialized(DWORD dwFieldIndex)
{
LIMITED_METHOD_CONTRACT;
_ASSERTE(IsSerializable());
-#ifdef FEATURE_REMOTING
- if (!HasRemotingVtsInfo())
- return FALSE;
-
- return GetRemotingVtsInfo()->IsOptionallySerialized(dwFieldIndex);
-#else
return FALSE;
-#endif
}
//==========================================================================================
@@ -1641,35 +1582,6 @@ inline OBJECTREF MethodTable::AllocateNoChecks()
return AllocateObject(this);
}
-#ifdef FEATURE_REMOTING
-//==========================================================================================
-inline BOOL MethodTable::HasContextStatics()
-{
- LIMITED_METHOD_DAC_CONTRACT;
- return GetFlag(enum_flag_ContextStatic);
-}
-
-//==========================================================================================
-inline void MethodTable::SetHasContextStatics()
-{
- LIMITED_METHOD_CONTRACT;
- SetFlag(enum_flag_ContextStatic);
-}
-
-//==========================================================================================
-inline DWORD MethodTable::GetContextStaticsOffset()
-{
- LIMITED_METHOD_DAC_CONTRACT;
- return GetContextStaticsBucket()->m_dwContextStaticsOffset;
-}
-
-//==========================================================================================
-inline WORD MethodTable::GetContextStaticsSize()
-{
- LIMITED_METHOD_DAC_CONTRACT;
- return GetContextStaticsBucket()->m_wContextStaticsSize;
-}
-#endif // FEATURE_REMOTING
//==========================================================================================
inline DWORD MethodTable::GetClassIndex()
diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp
index 303edc4683..503c13af5b 100644
--- a/src/vm/methodtablebuilder.cpp
+++ b/src/vm/methodtablebuilder.cpp
@@ -15,7 +15,6 @@
#include "methodtablebuilder.h"
-#include "constrainedexecutionregion.h"
#include "sigbuilder.h"
#include "dllimport.h"
#include "fieldmarshaler.h"
@@ -25,14 +24,8 @@
#include "security.h"
#include "customattribute.h"
-#ifdef FEATURE_REMOTING
-#include "objectclone.h"
-#endif
#ifdef FEATURE_COMINTEROP
-#ifdef FEATURE_FUSION
-#include "policy.h"
-#endif
#endif
//*******************************************************************************
@@ -191,18 +184,6 @@ MethodTableBuilder::CreateClass( Module *pModule,
pEEClass->GetSecurityProperties()->SetFlags(dwSecFlags, dwNullDeclFlags);
}
-#ifdef FEATURE_CER
- // Cache class level reliability contract info.
- DWORD dwReliabilityContract = ::GetReliabilityContract(pInternalImport, cl);
- if (dwReliabilityContract != RC_NULL)
- {
- // Reliability contract is an optional field. If we have a non-default value we need to ensure the
- // optional field descriptor has been allocated.
- EnsureOptionalFieldsAreAllocated(pEEClass, pamTracker, pAllocator->GetLowFrequencyHeap());
-
- pEEClass->SetReliabilityContract(dwReliabilityContract);
- }
-#endif // FEATURE_CER
if (fHasLayout)
pEEClass->SetHasLayout();
@@ -217,13 +198,6 @@ MethodTableBuilder::CreateClass( Module *pModule,
// On CoreCLR, however, we do allow non-FX assemblies to have this attribute. This enables scenarios where we can
// activate 3rd-party WinRT components outside AppContainer - 1st party WinRT components are already allowed
// to be activated outside AppContainer (on both Desktop and CoreCLR).
-#ifdef FEATURE_FUSION
- if (!pAssembly->IsWinMD() &&
- Fusion::Util::IsAnyFrameworkAssembly(pAssembly->GetFusionAssemblyName()) != S_OK)
- {
- pAssembly->ThrowTypeLoadException(pModule->GetMDImport(), cl, IDS_EE_WINRT_TYPE_IN_ORDINARY_ASSEMBLY);
- }
-#endif
pEEClass->SetProjectedFromWinRT();
}
@@ -1819,16 +1793,6 @@ MethodTableBuilder::BuildMethodTableThrowing(
VerifySelfReferencingStaticValueTypeFields_WithRVA(pByValueClassCache);
}
-#ifdef FEATURE_REMOTING
- // If the class is serializable we scan it for VTS (Version Tolerant
- // Serialization) event methods or NotSerialized or OptionalField
- // fields. Any such info found will be attached to the method as
- // optional data later.
- if (IsTdSerializable(GetAttrClass()))
- {
- ScanTypeForVtsInfo();
- }
-#endif // FEATURE_REMOTING
// Now setup the method table
@@ -1875,23 +1839,23 @@ MethodTableBuilder::BuildMethodTableThrowing(
#ifdef FEATURE_HFA
CheckForHFA(pByValueClassCache);
#endif
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
-#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF defined at the same time.
+#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING defined at the same time.
#endif // FEATURE_HFA
SystemVAmd64CheckForPassStructInRegister();
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
}
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
-#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF defined at the same time.
+#error Can't have FEATURE_HFA and FEATURE_UNIX_AMD64_STRUCT_PASSING defined at the same time.
#endif // FEATURE_HFA
if (HasLayout())
{
SystemVAmd64CheckForPassNativeStructInRegister();
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
if (HasLayout())
{
@@ -1962,19 +1926,6 @@ MethodTableBuilder::BuildMethodTableThrowing(
//
// if there are context or thread static set the info in the method table optional members
//
-#ifdef FEATURE_REMOTING
- DWORD contextStaticsSize = bmtCSInfo->dwContextStaticsSize;
- if (contextStaticsSize != 0)
- {
- if (!FitsIn<WORD>(contextStaticsSize))
- {
- BuildMethodTableThrowException(IDS_EE_TOOMANYFIELDS);
- }
-
- // this is responsible for setting the flag and allocation in the loader heap
- pMT->SetupContextStatics(GetMemTracker(), (WORD)contextStaticsSize);
- }
-#endif // !FEATURE_REMOTING
if (!bmtProp->fNoSanityChecks)
{
@@ -1991,28 +1942,7 @@ MethodTableBuilder::BuildMethodTableThrowing(
}
// Check for the RemotingProxy Attribute
-#ifdef FEATURE_REMOTING
- if (IsContextful())
- {
- PREFIX_ASSUME(g_pObjectClass != NULL);
- // Skip mscorlib marshal-by-ref classes since they all
- // are assumed to have the default proxy attribute
- if (pModule != g_pObjectClass->GetModule())
- {
- CONTRACT_VIOLATION(LoadsTypeViolation); // This api can cause the ProxyAttribute class to be loaded.
- CheckForRemotingProxyAttrib();
- }
- }
-
- if (IsContextful() || HasRemotingProxyAttribute())
- {
- // Contextful and classes that have a remoting proxy attribute
- // (whether they are MarshalByRef or ContextFul) always take the slow
- // path of managed activation
- pMT->SetRequiresManagedActivation();
- }
-#endif // FEATURE_REMOTING
- // structs with GC poitners MUST be pointer sized aligned because the GC assumes it
+ // structs with GC pointers MUST be pointer sized aligned because the GC assumes it
if (IsValueClass() && pMT->ContainsPointers() && (bmtFP->NumInstanceFieldBytes % sizeof(void*) != 0))
{
BuildMethodTableThrowException(IDS_CLASSLOAD_BADFORMAT);
@@ -2066,11 +1996,6 @@ MethodTableBuilder::BuildMethodTableThrowing(
}
#endif // _DEBUG
-#ifdef FEATURE_REMOTING
- // Make sure the object cloner won't attempt to blit types that aren't serializable.
- if (!IsTdSerializable(GetAttrClass()) && !IsEnum())
- SetCannotBeBlittedByObjectCloner();
-#endif
//If this is a value type, then propagate the UnsafeValueTypeAttribute from
//its instance members to this type.
@@ -2174,22 +2099,6 @@ MethodTableBuilder::BuildMethodTableThrowing(
#pragma warning(pop)
#endif
-#ifdef FEATURE_REMOTING
-BOOL
-IsSerializerRelatedInterface(MethodTable *pItfMT)
-{
- STANDARD_VM_CONTRACT;
-
- if (MscorlibBinder::IsClass(pItfMT, CLASS__ISERIALIZABLE))
- return TRUE;
- if (MscorlibBinder::IsClass(pItfMT, CLASS__IOBJECTREFERENCE))
- return TRUE;
- if (MscorlibBinder::IsClass(pItfMT, CLASS__IDESERIALIZATIONCB))
- return TRUE;
-
- return FALSE;
-}
-#endif
//---------------------------------------------------------------------------------------
//
@@ -2213,15 +2122,6 @@ MethodTableBuilder::ResolveInterfaces(
// resolve unresolved interfaces and determine the size of the largest interface (in # slots)
-#ifdef FEATURE_REMOTING // code for objectcloner
- // First look through the interfaces explicitly declared by this class
- for (DWORD i = 0; i < cBuildingInterfaceList; i++)
- {
- MethodTable *pInterface = pBuildingInterfaceList[i].m_pMethodTable;
- if (IsSerializerRelatedInterface(pInterface))
- SetCannotBeBlittedByObjectCloner();
- }
-#endif // FEATURE_REMOTING // code for objectcloner
LoadApproxInterfaceMap();
@@ -2239,12 +2139,6 @@ MethodTableBuilder::ResolveInterfaces(
{
SetHasFieldsWhichMustBeInited();
}
-#ifdef FEATURE_REMOTING
- if (pParentClass->CannotBeBlittedByObjectCloner())
- {
- SetCannotBeBlittedByObjectCloner();
- }
-#endif
#ifdef FEATURE_READYTORUN
if (!(IsValueClass() || (pParentClass == g_pObjectClass)))
{
@@ -2808,12 +2702,6 @@ MethodTableBuilder::EnumerateClassMethods()
numGenericMethodArgs = hEnumTyPars.EnumGetCount();
// We do not want to support context-bound objects with generic methods.
-#ifdef FEATURE_REMOTING
- if (IsContextful() && numGenericMethodArgs > 0)
- {
- BuildMethodTableThrowException(IDS_CLASSLOAD_CONTEXT_BOUND_GENERIC_METHOD);
- }
-#endif // FEATURE_REMOTING
if (numGenericMethodArgs != 0)
{
@@ -3864,9 +3752,6 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList,
DWORD dwCurrentStaticField = 0;
DWORD dwCurrentThreadStaticField = 0;
-#ifdef FEATURE_REMOTING
- DWORD dwContextStaticsOffset = 0;
-#endif
DWORD dwR8Fields = 0; // Number of R8's the class has
@@ -3906,11 +3791,7 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList,
MethodTable * pByValueClass = NULL;
BOOL fIsByValue = FALSE;
BOOL fIsThreadStatic = FALSE;
-#ifdef FEATURE_REMOTING
- BOOL fIsContextStatic = FALSE;
-#else
static const BOOL fIsContextStatic = FALSE;
-#endif
BOOL fHasRVA = FALSE;
MetaSig fsig(pMemberSignature,
@@ -3947,16 +3828,6 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList,
fIsThreadStatic = TRUE;
}
-#ifdef FEATURE_REMOTING
- hr = pInternalImport->GetCustomAttributeByName(bmtMetaData->pFields[i],
- g_ContextStaticAttributeClassName,
- NULL, NULL);
- IfFailThrow(hr);
- if (hr == S_OK)
- {
- fIsContextStatic = TRUE;
- }
-#endif // FEATURE_REMOTING
if (ElementType == ELEMENT_TYPE_VALUETYPE)
{
@@ -3973,12 +3844,6 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList,
// Do some sanity checks that we are not mixing context and thread
// relative statics.
-#ifdef FEATURE_REMOTING
- if (fIsThreadStatic && fIsContextStatic)
- {
- IfFailThrow(COR_E_TYPELOAD);
- }
-#endif
if (fHasRVA && (fIsThreadStatic || fIsContextStatic))
{
IfFailThrow(COR_E_TYPELOAD);
@@ -4259,10 +4124,6 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList,
SetHasNonPublicFields();
if (pFieldClass->HasFieldsWhichMustBeInited())
SetHasFieldsWhichMustBeInited();
-#ifdef FEATURE_REMOTING
- if (pFieldClass->CannotBeBlittedByObjectCloner())
- SetCannotBeBlittedByObjectCloner();
-#endif
#ifdef FEATURE_READYTORUN
if (!(pByValueClass->IsTruePrimitive() || pByValueClass->IsEnum()))
@@ -4554,18 +4415,6 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList,
if (fIsByValue)
bmtFP->NumThreadStaticGCBoxedFields++;
}
-#ifdef FEATURE_REMOTING
- else if (fIsContextStatic)
- {
- DWORD size = 1 << dwLog2FieldSize;
-
- dwContextStaticsOffset = (DWORD)ALIGN_UP(dwContextStaticsOffset, size);
-
- IfFailThrow(pFD->SetOffset(dwContextStaticsOffset)); // offset is the bucket index
-
- dwContextStaticsOffset += size;
- }
-#endif // FEATURE_REMOTING
else
{
bmtFP->NumRegularStaticFieldsOfSize[dwLog2FieldSize]++;
@@ -4646,12 +4495,6 @@ VOID MethodTableBuilder::InitializeFieldDescs(FieldDesc *pFieldDescList,
}
#endif // FEATURE_DOUBLE_ALIGNMENT_HINT
-#ifdef FEATURE_REMOTING
- if (pbmtCSInfo)
- {
- pbmtCSInfo->dwContextStaticsSize = dwContextStaticsOffset;
- }
-#endif
//========================================================================
// END:
@@ -5154,25 +4997,13 @@ void MethodTableBuilder::SetSecurityFlagsOnMethod(bmtRTMethod* pParentMethod,
// for linktime checks on these.
// Also place linktime checks on all P/Invoke calls.
if (
-#ifndef FEATURE_CORECLR
- (IsInterface() &&
- (GetMDImport()->GetCustomAttributeByName(GetCl(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK ||
- GetMDImport()->GetCustomAttributeByName(pNewMD->GetMemberDef(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK) ) ||
-
-#endif // !FEATURE_CORECLR
pNewMD->IsNDirect() ||
(pNewMD->IsComPlusCall() && !IsInterface()))
{
pNewMD->SetRequiresLinktimeCheck();
}
-#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_CORESYSTEM)
// All public methods on public types will do a link demand of
// full trust, unless AllowUntrustedCaller attribute is set
if (
@@ -5200,7 +5031,7 @@ void MethodTableBuilder::SetSecurityFlagsOnMethod(bmtRTMethod* pParentMethod,
pNewMD->SetRequiresLinktimeCheck();
}
}
-#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#endif // defined(FEATURE_CORESYSTEM)
// If it's a delegate BeginInvoke, we need to do a HostProtection check for synchronization
if(!pNewMD->RequiresLinktimeCheck() && IsDelegate())
@@ -6304,14 +6135,6 @@ MethodTableBuilder::InitMethodDesc(
pNewNMD->ndirect.m_cbStackArgumentSize = 0xFFFF;
#endif // defined(_TARGET_X86_)
-#ifdef FEATURE_MIXEDMODE // IJW
- if (RVA != 0 && IsMiUnmanaged(dwImplFlags) && IsMiNative(dwImplFlags))
- {
- // Note that we cannot initialize the stub directly now in the general case,
- // as LoadLibrary may not have been performed yet.
- pNewNMD->SetIsEarlyBound();
- }
-#endif // FEATURE_MIXEDMODE
pNewNMD->GetWriteableData()->m_pNDirectTarget = pNewNMD->GetNDirectImportThunkGlue()->GetEntrypoint();
}
@@ -7208,9 +7031,12 @@ MethodTableBuilder::NeedsNativeCodeSlot(bmtMDMethod * pMDMethod)
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_REMOTING
- // Approximation of code:MethodDesc::IsRemotingInterceptedViaPrestub
- if (MayBeRemotingIntercepted(pMDMethod) && !IsMdVirtual(pMDMethod->GetDeclAttrs()))
+
+#ifdef FEATURE_TIERED_COMPILATION
+ // Keep in-sync with MethodDesc::IsEligibleForTieredCompilation()
+ if (g_pConfig->TieredCompilation() &&
+ !GetModule()->HasNativeOrReadyToRunImage() &&
+ (pMDMethod->GetMethodType() == METHOD_TYPE_NORMAL || pMDMethod->GetMethodType() == METHOD_TYPE_INSTANTIATED))
{
return TRUE;
}
@@ -7225,11 +7051,7 @@ MethodTableBuilder::MayBeRemotingIntercepted(bmtMDMethod * pMDMethod)
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_REMOTING
- return (IsMarshaledByRef() || g_pObjectClass == NULL) && !IsMdStatic(pMDMethod->GetDeclAttrs());
-#else
return FALSE;
-#endif
}
//*******************************************************************************
@@ -8412,7 +8234,7 @@ DWORD MethodTableBuilder::GetFieldSize(FieldDesc *pFD)
return (1 << (DWORD)(DWORD_PTR&)(pFD->m_pMTOfEnclosingClass));
}
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
// checks whether the struct is enregisterable.
void MethodTableBuilder::SystemVAmd64CheckForPassStructInRegister()
{
@@ -8497,7 +8319,7 @@ void MethodTableBuilder::StoreEightByteClassification(SystemVStructRegisterPassi
eeClass->SetEightByteClassification(helper->eightByteCount, helper->eightByteClassifications, helper->eightByteSizes);
}
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
#ifdef FEATURE_HFA
//---------------------------------------------------------------------------------------
@@ -9947,267 +9769,6 @@ void MethodTableBuilder::InterfaceAmbiguityCheck(bmtInterfaceAmbiguityCheckInfo
InterfacesAmbiguityCheck(bmtCheckInfo,pIntf->GetModule(),pIntf->GetCl(),pItfSubstChain);
}
-#ifdef FEATURE_REMOTING // affects only remoting-related info
-//*******************************************************************************
-// Private helper method used by the code below to check whether the given
-// method is annotated to be a VTS event callback.
-BOOL MethodTableBuilder::CheckForVtsEventMethod(IMDInternalImport *pImport,
- MethodDesc *pMD,
- DWORD dwAttrs,
- LPCUTF8 szAttrName,
- MethodDesc **ppMethodDesc)
-{
- STANDARD_VM_CONTRACT;
-
- // For each method with an attriubte we need to check that:
- // o The method is not static, virtual, abstract or generic.
- // o The signature is correct.
- // o No other method on the same type is marked with the same
- // attribute.
-
- if (pImport->GetCustomAttributeByName(pMD->GetMemberDef(),
- szAttrName,
- NULL,
- NULL) == S_OK)
- {
- if (IsMdStatic(dwAttrs) ||
- IsMdVirtual(dwAttrs) ||
- IsMdAbstract(dwAttrs) ||
- pMD->IsGenericMethodDefinition())
- {
- BuildMethodTableThrowException(IDS_CLASSLOAD_INVALID_VTS_METHOD, pMD->GetMemberDef());
- }
-
- // Check whether we've seen one of these methods before.
- if (*ppMethodDesc != NULL)
- {
- BuildMethodTableThrowException(IDS_CLASSLOAD_TOO_MANY_VTS_METHODS, szAttrName);
- }
-
- // Check the signature, it should be "void M(StreamingContext)".
- DWORD cbSig;
- PCCOR_SIGNATURE pSig;
- if (FAILED(pImport->GetSigOfMethodDef(pMD->GetMemberDef(), &cbSig, &pSig)))
- {
- BuildMethodTableThrowException(IDS_CLASSLOAD_BADFORMAT);
- }
-
- // Should be an instance method with no generic type parameters.
- if (CorSigUncompressCallingConv(pSig) != IMAGE_CEE_CS_CALLCONV_HASTHIS)
- goto BadSignature;
-
- // Should have one argument.
- if (CorSigUncompressData(pSig) != 1)
- goto BadSignature;
-
- // And a return type of void.
- if (*pSig++ != (BYTE)ELEMENT_TYPE_VOID)
- goto BadSignature;
-
- // The argument should be a value type.
- if (*pSig++ != (BYTE)ELEMENT_TYPE_VALUETYPE)
- goto BadSignature;
-
- // Now the tricky bit: we want to verify the value type is
- // StreamingContext, but we don't want to simply load the type since it
- // might be any other arbitrary type and cause recursive loading
- // problems. SO we manually check the type via the metadata APIs
- // instead.
- mdToken tkType = CorSigUncompressToken(pSig);
- LPCUTF8 szType;
- LPCUTF8 szNamespace;
-
- // Compute type name and namespace.
- if (TypeFromToken(tkType) == mdtTypeDef)
- {
- if (FAILED(pImport->GetNameOfTypeDef(tkType, &szType, &szNamespace)))
- {
- goto BadSignature;
- }
- }
- else
- {
- _ASSERTE(TypeFromToken(tkType) == mdtTypeRef);
- if (FAILED(pImport->GetNameOfTypeRef(tkType, &szNamespace, &szType)))
- {
- goto BadSignature;
- }
- }
-
- // Do the names match?
- if (strcmp(szType, g_StreamingContextName) != 0 ||
- strcmp(szNamespace, g_SerializationNS))
- goto BadSignature;
-
- // For typedefs we can directly check whether the current module is
- // part of mscorlib. For refs we have to dig deeper (into the token
- // resolution scope).
- if (TypeFromToken(tkType) == mdtTypeDef)
- {
- if (bmtError->pModule->GetAssembly()->GetManifestModule() != SystemDomain::SystemAssembly()->GetManifestModule())
- goto BadSignature;
- }
- else
- {
- // The scope needs to be an assembly ref.
- mdToken tkScope;
- if (FAILED(pImport->GetResolutionScopeOfTypeRef(tkType, &tkScope)))
- {
- goto BadSignature;
- }
- if (TypeFromToken(tkScope) != mdtAssemblyRef)
- goto BadSignature;
-
- // Fetch the name and public key or public key token.
- BYTE *pbPublicKeyOrToken;
- DWORD cbPublicKeyOrToken;
- LPCSTR szAssembly;
- DWORD dwAssemblyFlags;
- if (FAILED(pImport->GetAssemblyRefProps(
- tkScope,
- (const void**)&pbPublicKeyOrToken,
- &cbPublicKeyOrToken,
- &szAssembly,
- NULL, // AssemblyMetaDataInternal: we don't care about version, culture etc.
- NULL, // Hash value pointer, obsolete information
- NULL, // Byte count for above
- &dwAssemblyFlags)))
- {
- goto BadSignature;
- }
-
- // Validate the name.
- if (stricmpUTF8(szAssembly, g_psBaseLibraryName) != 0)
- goto BadSignature;
-
- // And the public key or token, whichever was burned into the reference by the compiler. For mscorlib this is the ECMA key or
- // token.
- if (IsAfPublicKeyToken(dwAssemblyFlags))
- {
- if (cbPublicKeyOrToken != sizeof(g_rbNeutralPublicKeyToken) ||
- memcmp(pbPublicKeyOrToken, g_rbNeutralPublicKeyToken, cbPublicKeyOrToken) != 0)
- goto BadSignature;
- }
- else
- {
- if (cbPublicKeyOrToken != sizeof(g_rbNeutralPublicKey) ||
- memcmp(pbPublicKeyOrToken, g_rbNeutralPublicKey, cbPublicKeyOrToken) != 0)
- goto BadSignature;
- }
- }
-
- // We managed to pass all tests; record this method.
- *ppMethodDesc = pMD;
-
- return TRUE;
- }
-
- return FALSE;
-
- BadSignature:
- BuildMethodTableThrowException(IDS_CLASSLOAD_INVALID_VTS_SIG, pMD->GetMemberDef());
-}
-
-//*******************************************************************************
-// Names of the various VTS custom attributes
-#define VTS_ON_SERIALIZING_ATTRIBUTE "System.Runtime.Serialization.OnSerializingAttribute"
-#define VTS_ON_SERIALIZED_ATTRIBUTE "System.Runtime.Serialization.OnSerializedAttribute"
-#define VTS_ON_DESERIALIZING_ATTRIBUTE "System.Runtime.Serialization.OnDeserializingAttribute"
-#define VTS_ON_DESERIALIZED_ATTRIBUTE "System.Runtime.Serialization.OnDeserializedAttribute"
-#define VTS_OPTIONAL_FIELD_ATTRIBUTE "System.Runtime.Serialization.OptionalFieldAttribute"
-
-//*******************************************************************************
-// Look for VTS event methods or fields with interesting serialization
-// attributes on this type (only called for serializable types).
-
-VOID MethodTableBuilder::ScanTypeForVtsInfo()
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(IsTdSerializable(GetAttrClass()));
- }
- CONTRACTL_END;
-
- //
- // Do not mark System.String as needing vts info. The MethodTable bit used for VtsInfo
- // is used for other purpose on System.String, and System.String does need VtsInfo anyway
- // because of it is special-cased by the object cloner.
- //
- if (g_pStringClass == NULL)
- {
- LPCUTF8 name, nameSpace;
-
- if (FAILED(GetMDImport()->GetNameOfTypeDef(GetCl(), &name, &nameSpace)))
- {
- BuildMethodTableThrowException(IDS_CLASSLOAD_BADFORMAT);
- }
-
- if (strcmp(name, g_StringName) == 0 && strcmp(nameSpace, g_SystemNS) == 0)
- {
- return;
- }
- }
-
- DWORD i;
- // Scan all the non-virtual, non-abstract, non-generic instance methods for
- // one of the special custom attributes indicating a VTS event method.
- DeclaredMethodIterator it(*this);
- while (it.Next())
- {
- if (CheckForVtsEventMethod(GetMDImport(),
- it->GetMethodDesc(),
- it.Attrs(),
- VTS_ON_SERIALIZING_ATTRIBUTE,
- &bmtMFDescs->pOnSerializingMethod))
- bmtMFDescs->fNeedsRemotingVtsInfo = true;
-
- if (CheckForVtsEventMethod(GetMDImport(),
- it->GetMethodDesc(),
- it.Attrs(),
- VTS_ON_SERIALIZED_ATTRIBUTE,
- &bmtMFDescs->pOnSerializedMethod))
- bmtMFDescs->fNeedsRemotingVtsInfo = true;
-
- if (CheckForVtsEventMethod(GetMDImport(),
- it->GetMethodDesc(),
- it.Attrs(),
- VTS_ON_DESERIALIZING_ATTRIBUTE,
- &bmtMFDescs->pOnDeserializingMethod))
- bmtMFDescs->fNeedsRemotingVtsInfo = true;
-
- if (CheckForVtsEventMethod(GetMDImport(),
- it->GetMethodDesc(),
- it.Attrs(),
- VTS_ON_DESERIALIZED_ATTRIBUTE,
- &bmtMFDescs->pOnDeserializedMethod))
- bmtMFDescs->fNeedsRemotingVtsInfo = true;
- }
-
- // Scan all the instance fields introduced on this type for NotSerialized or
- // OptionalField attributes.
- DWORD dwNumIntroducedInstanceFields = bmtEnumFields->dwNumInstanceFields;
- FieldDesc *pFieldDescList = GetApproxFieldDescListRaw();
- for (i = 0; i < dwNumIntroducedInstanceFields; i++)
- {
- FieldDesc *pFD = &pFieldDescList[i];
- DWORD dwFlags;
-
- if (FAILED(GetMDImport()->GetFieldDefProps(pFD->GetMemberDef(), &dwFlags)))
- {
- BuildMethodTableThrowException(IDS_CLASSLOAD_BADFORMAT);
- }
- if (IsFdNotSerialized(dwFlags))
- bmtMFDescs->SetFieldNotSerialized(i, dwNumIntroducedInstanceFields);
-
- if (GetMDImport()->GetCustomAttributeByName(pFD->GetMemberDef(),
- VTS_OPTIONAL_FIELD_ATTRIBUTE,
- NULL,
- NULL) == S_OK)
- bmtMFDescs->SetFieldOptionallySerialized(i, dwNumIntroducedInstanceFields);
- }
-}
-#endif // FEATURE_REMOTING
//*******************************************************************************
void MethodTableBuilder::CheckForSystemTypes()
@@ -10220,7 +9781,6 @@ void MethodTableBuilder::CheckForSystemTypes()
// We can exit early for generic types - there are just a few cases to check for.
if (bmtGenerics->HasInstantiation() && g_pNullableClass != NULL)
{
-#ifdef FEATURE_SPAN_OF_T
_ASSERTE(g_pByReferenceClass != NULL);
_ASSERTE(g_pByReferenceClass->IsByRefLike());
@@ -10237,7 +9797,6 @@ void MethodTableBuilder::CheckForSystemTypes()
#endif
return;
}
-#endif
_ASSERTE(g_pNullableClass->IsNullable());
@@ -10293,7 +9852,6 @@ void MethodTableBuilder::CheckForSystemTypes()
{
pMT->SetIsNullable();
}
-#ifdef FEATURE_SPAN_OF_T
else if (strcmp(name, g_ByReferenceName) == 0)
{
pMT->SetIsByRefLike();
@@ -10306,10 +9864,9 @@ void MethodTableBuilder::CheckForSystemTypes()
pMT->SetInternalCorElementType(ELEMENT_TYPE_VALUETYPE);
#endif
}
-#endif
else if (strcmp(name, g_ArgIteratorName) == 0)
{
- // Mark the special types that have embeded stack poitners in them
+ // Mark the special types that have embeded stack pointers in them
pMT->SetIsByRefLike();
}
else if (strcmp(name, g_RuntimeArgumentHandleName) == 0)
@@ -10366,15 +9923,6 @@ void MethodTableBuilder::CheckForSystemTypes()
// we'll set the bit here.
pMT->SetHasCriticalFinalizer();
}
-#ifdef FEATURE_REMOTING
- else if (strcmp(name, g_TransparentProxyName) == 0 && strcmp(nameSpace, g_ProxiesNS) == 0)
- {
- pMT->SetTransparentProxy();
-
- // This ensures that we take the slow path in JIT_IsInstanceOfClass
- pMT->SetHasTypeEquivalence();
- }
-#endif // FEATURE_REMOTING
#ifdef FEATURE_COMINTEROP
else
{
@@ -10729,15 +10277,9 @@ MethodTableBuilder::SetupMethodTable2(
: 0;
-#ifdef FEATURE_REMOTING
- BOOL fHasContextStatics = (bmtCSInfo) ? (bmtCSInfo->dwContextStaticsSize) : FALSE;
- BOOL fNeedsRemotableMethodInfo = (IsMarshaledByRef() || IsInterface() || g_pObjectClass == NULL);
- BOOL fNeedsRemotingVtsInfo = bmtMFDescs->fNeedsRemotingVtsInfo;
-#else // !FEATURE_REMOTING
BOOL fHasContextStatics = FALSE;
BOOL fNeedsRemotableMethodInfo=FALSE;
BOOL fNeedsRemotingVtsInfo = FALSE;
-#endif // !FEATURE_REMOTING
#ifdef FEATURE_COLLECTIBLE_TYPES
BOOL fCollectible = pLoaderModule->IsCollectible();
@@ -10802,26 +10344,6 @@ MethodTableBuilder::SetupMethodTable2(
pMT->SetHasRCWPerTypeData();
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_REMOTING
- if (bmtMFDescs->fNeedsRemotingVtsInfo)
- pMT->SetHasRemotingVtsInfo();
-
- if (fHasContextStatics)
- pMT->SetHasContextStatics();
-
- if (IsMarshaledByRef())
- {
- if (IsContextful())
- {
- COUNTER_ONLY(GetPerfCounters().m_Context.cClasses++);
- pMT->SetIsContextful();
- }
- else
- {
- pMT->SetMarshaledByRef();
- }
- }
-#endif // FEATURE_REMOTING
if (IsInterface())
pMT->SetIsInterface();
@@ -11435,59 +10957,6 @@ MethodTableBuilder::SetupMethodTable2(
// (event callbacks or OptionalField attributes) we've previously cached the
// additional information in the bmtMFDescs structure. Now it's time to add
// this information as an optional extension to the MethodTable.
-#ifdef FEATURE_REMOTING
- if (bmtMFDescs->fNeedsRemotingVtsInfo)
- {
- DWORD dwNumIntroducedInstanceFields = bmtEnumFields->dwNumInstanceFields;
- _ASSERTE(bmtAllocator == pMT->GetLoaderAllocator());
- PTR_RemotingVtsInfo pInfo = pMT->AllocateRemotingVtsInfo(GetMemTracker(), dwNumIntroducedInstanceFields);
-
- pInfo->m_pCallbacks[RemotingVtsInfo::VTS_CALLBACK_ON_SERIALIZING].SetValue(bmtMFDescs->pOnSerializingMethod);
- pInfo->m_pCallbacks[RemotingVtsInfo::VTS_CALLBACK_ON_SERIALIZED].SetValue(bmtMFDescs->pOnSerializedMethod);
- pInfo->m_pCallbacks[RemotingVtsInfo::VTS_CALLBACK_ON_DESERIALIZING].SetValue(bmtMFDescs->pOnDeserializingMethod);
- pInfo->m_pCallbacks[RemotingVtsInfo::VTS_CALLBACK_ON_DESERIALIZED].SetValue(bmtMFDescs->pOnDeserializedMethod);
-
- for (i = 0; i < dwNumIntroducedInstanceFields; i++)
- {
- if (bmtMFDescs->prfNotSerializedFields && bmtMFDescs->prfNotSerializedFields[i])
- pInfo->SetIsNotSerialized(i);
- if (bmtMFDescs->prfOptionallySerializedFields && bmtMFDescs->prfOptionallySerializedFields[i])
- pInfo->SetIsOptionallySerialized(i);
- }
-
-#if 0
- printf("%s has VTS info:\n", pMT->GetDebugClassName());
- if (bmtMFDescs->pOnSerializingMethod)
- printf(" OnSerializing: %s\n", bmtMFDescs->pOnSerializingMethod->m_pszDebugMethodName);
- if (bmtMFDescs->pOnSerializedMethod)
- printf(" OnSerialized: %s\n", bmtMFDescs->pOnSerializedMethod->m_pszDebugMethodName);
- if (bmtMFDescs->pOnDeserializingMethod)
- printf(" OnDeserializing: %s\n", bmtMFDescs->pOnDeserializingMethod->m_pszDebugMethodName);
- if (bmtMFDescs->pOnDeserializedMethod)
- printf(" OnDeserialized: %s\n", bmtMFDescs->pOnDeserializedMethod->m_pszDebugMethodName);
- for (i = 0; i < dwNumIntroducedInstanceFields; i++)
- {
- if (bmtMFDescs->prfNotSerializedFields && bmtMFDescs->prfNotSerializedFields[i])
- {
- printf(" [NotSerialized] %s\n", GetApproxFieldDescListRaw()[i].m_debugName);
- _ASSERTE(pInfo->IsNotSerialized(i));
- }
- else
- _ASSERTE(!pInfo->IsNotSerialized(i));
- if (bmtMFDescs->prfOptionallySerializedFields && bmtMFDescs->prfOptionallySerializedFields[i])
- {
- printf(" [OptionalField] %s\n", GetApproxFieldDescListRaw()[i].m_debugName);
- _ASSERTE(pInfo->IsOptionallySerialized(i));
- }
- else
- _ASSERTE(!pInfo->IsOptionallySerialized(i));
- }
- printf("------------\n\n");
-#endif // 0
- }
- if (fNeedsRemotableMethodInfo)
- pMT->SetupRemotableMethodInfo(GetMemTracker());
-#endif // FEATURE_REMOTING
}
#ifdef _PREFAST_
#pragma warning(pop)
@@ -11670,30 +11139,6 @@ VOID MethodTableBuilder::CheckForRemotingProxyAttrib()
{
STANDARD_VM_CONTRACT;
-#ifdef FEATURE_REMOTING
- // See if our parent class has a proxy attribute
- _ASSERTE(g_pObjectClass != NULL);
-
- if (!GetParentMethodTable()->GetClass()->HasRemotingProxyAttribute())
- {
- // Call the metadata api to look for a proxy attribute on this type
- // Note: the api does not check for inherited attributes
-
- // Set the flag is the type has a non-default proxy attribute
- if(IsDefined(
- GetModule(),
- bmtInternal->pType->GetTypeDefToken(),
- TypeHandle(MscorlibBinder::GetClass(CLASS__PROXY_ATTRIBUTE))))
- {
- SetHasRemotingProxyAttribute();
- }
- }
- else
- {
- // parent has proxyAttribute ... mark this class as having one too!
- SetHasRemotingProxyAttribute();
- }
-#endif // FEATURE_REMOTING
}
@@ -11948,70 +11393,6 @@ VOID MethodTableBuilder::SetContextfulOrByRef()
}
CONTRACTL_END;
-#ifdef FEATURE_REMOTING
-
- if (GetModule()->IsSystem())
- {
- // Check whether these classes are the root classes of contextful
- // and marshalbyref classes i.e. System.ContextBoundObject and
- // System.MarshalByRefObject respectively.
-
- // Extract the class name
- LPCUTF8 pszClassName = NULL;
- LPCUTF8 pszNameSpace = NULL;
- if (FAILED(GetMDImport()->GetNameOfTypeDef(GetCl(), &pszClassName, &pszNameSpace)))
- {
- BuildMethodTableThrowException(IDS_CLASSLOAD_BADFORMAT);
- }
-
- StackSString ssFullyQualifiedName;
- ns::MakePath(ssFullyQualifiedName,
- StackSString(SString::Utf8, pszNameSpace),
- StackSString(SString::Utf8, pszClassName));
-
- if(ssFullyQualifiedName.Equals(SL(g_ContextBoundObjectClassName)))
- { // Set the contextful and marshalbyref flag
- bmtProp->fIsContextful = true;
- bmtProp->fMarshaledByRef = true;
- return;
- }
-
- if(ssFullyQualifiedName.Equals(SL(g_MarshalByRefObjectClassName)))
- { // Set the marshalbyref flag
- bmtProp->fMarshaledByRef = true;
- return;
- }
- }
-
- // First check whether the parent class is contextful or
- // marshalbyref
- if(HasParent())
- {
- MethodTable * pParent = GetParentMethodTable();
- if(pParent->IsContextful())
- { // Set the contextful and marshalbyref flag
- bmtProp->fIsContextful = true;
- bmtProp->fMarshaledByRef = true;
-
- if (bmtGenerics->GetNumGenericArgs() > 0)
- { // While these could work with a bit of work in the JIT,
- // we will not support generic context-bound objects in V2.0.
- BuildMethodTableThrowException(IDS_CLASSLOAD_GENERIC_CONTEXT_BOUND_OBJECT);
- }
-
- if (GetAssembly()->IsCollectible())
- {
- // Collectible assemblies do not support ContextBoundObject
- BuildMethodTableThrowException(IDS_CLASSLOAD_COLLECTIBLE_CONTEXT_BOUND_OBJECT);
- }
- }
-
- else if (pParent->IsMarshaledByRef())
- { // Set the marshalbyref flag
- bmtProp->fMarshaledByRef = true;
- }
- }
-#endif // FEATURE_REMOTING
}
//*******************************************************************************
@@ -12194,19 +11575,6 @@ VOID MethodTableBuilder::VerifyClassInheritanceSecurityHelper(
// This method throws on failure.
Security::ClassInheritanceCheck(pChildMT, pParentMT);
-#ifndef FEATURE_CORECLR
- // Check the entire parent chain for inheritance permission demands.
- while (pParentMT != NULL)
- {
- if (pParentMT->GetClass()->RequiresInheritanceCheck())
- {
- // This method throws on failure.
- Security::ClassInheritanceCheck(pChildMT, pParentMT);
- }
-
- pParentMT = pParentMT->GetParentMethodTable();
- }
-#endif // !FEATURE_CORECLR
}
//*******************************************************************************
@@ -12225,74 +11593,6 @@ VOID MethodTableBuilder::VerifyMethodInheritanceSecurityHelper(
Security::MethodInheritanceCheck(pChildMD, pParentMD);
-#ifndef FEATURE_CORECLR
-
- // If no inheritance checks are required, just return.
- if (!pParentMD->RequiresInheritanceCheck() &&
- !pParentMD->ParentRequiresInheritanceCheck())
- {
- return;
- }
-
- DWORD dwSlot = pParentMD->GetSlot();
-
-#ifdef _DEBUG
- // Get the name and signature for the method so we can find the new parent method desc.
- // We use the parent MethodDesc for this because the child could actually have a very
- // different name in the case that the child is MethodImpling the parent.
-
- // Get the name.
- LPCUTF8 szName;
- szName = pParentMD->GetName();
-
- // Get the signature.
- PCCOR_SIGNATURE pSignature;
- DWORD cSignature;
- pParentMD->GetSig(&pSignature, &cSignature);
- Module *pModule = pParentMD->GetModule();
-#endif // _DEBUG
-
- do
- {
- if (pParentMD->RequiresInheritanceCheck())
- {
- Security::MethodInheritanceCheck(pChildMD, pParentMD);
- }
-
- if (pParentMD->ParentRequiresInheritanceCheck())
- {
- MethodTable *pGrandParentMT = pParentMD->GetMethodTable()->GetParentMethodTable();
- CONSISTENCY_CHECK(CheckPointer(pGrandParentMT));
-
- // Find this method in the parent.
- // If it does exist in the parent, it would be at the same vtable slot.
- if (dwSlot >= pGrandParentMT->GetNumVirtuals())
- {
- // Parent does not have this many vtable slots, so it doesn't exist there
- pParentMD = NULL;
- }
- else
- {
- // It is in the vtable of the parent
- pParentMD = pGrandParentMT->GetMethodDescForSlot(dwSlot);
- _ASSERTE(pParentMD != NULL);
-
-#ifdef _DEBUG
- _ASSERTE(pParentMD == MemberLoader::FindMethod(pGrandParentMT,
- szName,
- pSignature,
- cSignature,
- pModule));
-#endif // _DEBUG
- }
- }
- else
- {
- pParentMD = NULL;
- }
- } while (pParentMD != NULL);
-
-#endif // !FEATURE_CORECLR
}
//*******************************************************************************
@@ -12537,7 +11837,6 @@ void MethodTableBuilder::VerifyInheritanceSecurity()
// permission demands on the current class. If these first checks
// succeeded, then the cached declared method list is scanned for
// methods that have inheritance permission demands.
-#ifdef FEATURE_CORECLR
//
// If we are transparent, and every class up the inheritence chain is also entirely transparent,
// that means that no inheritence rules could be broken. If that's the case, we don't need to check
@@ -12568,12 +11867,9 @@ void MethodTableBuilder::VerifyInheritanceSecurity()
}
}
-#endif // FEATURE_CORECLR
if (GetParentMethodTable() != NULL
-#if FEATURE_CORECLR
&& !fInheritenceChainTransparent
-#endif // FEATURE_CORECLR
)
{
// Check the parent for inheritance permission demands.
@@ -12658,18 +11954,10 @@ void MethodTableBuilder::VerifyInheritanceSecurity()
MethodTable *pCurItfMT = itfIt.GetInterface();
CONSISTENCY_CHECK(CheckPointer(pCurItfMT));
-#ifdef FEATURE_CORECLR
if (fNeedTransparencyInheritanceCheck &&
!(Security::IsTypeAllTransparent(itfIt.GetInterface()) &&
fCurrentTypeAllTransparent)
)
-#else // FEATURE_CORECLR
- EEClass * pCurItfCls = pCurItfMT->GetClass();
- if (fNeedTransparencyInheritanceCheck ||
- fNeedPartialTrustInterfaceMappingCheck ||
- pCurItfCls->RequiresInheritanceCheck() ||
- pCurItfCls->SomeMethodsRequireInheritanceCheck())
-#endif // !FEATURE_CORECLR
{
// An interface is introduced by this type either if it is explicitly declared on the
// type's interface list or if one of the type's explicit interfaces requires the
diff --git a/src/vm/methodtablebuilder.h b/src/vm/methodtablebuilder.h
index 1cf71499e6..2aa36836e7 100644
--- a/src/vm/methodtablebuilder.h
+++ b/src/vm/methodtablebuilder.h
@@ -84,10 +84,6 @@ public:
// setting up a MethodTable
struct bmtContextStaticInfo
{
-#ifdef FEATURE_REMOTING
- // size of context statics
- DWORD dwContextStaticsSize;
-#endif
inline bmtContextStaticInfo() { LIMITED_METHOD_CONTRACT; memset((void *)this, NULL, sizeof(*this)); }
};
@@ -225,10 +221,6 @@ private:
BOOL IsAbstract() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->IsAbstract(); }
BOOL HasLayout() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->HasLayout(); }
BOOL IsDelegate() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->IsDelegate(); }
-#ifdef FEATURE_REMOTING
- BOOL IsMarshaledByRef() { WRAPPER_NO_CONTRACT; return bmtProp->fMarshaledByRef; }
- BOOL IsContextful() { WRAPPER_NO_CONTRACT; return bmtProp->fIsContextful; }
-#endif
BOOL IsNested() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->IsNested(); }
BOOL HasFieldsWhichMustBeInited() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->HasFieldsWhichMustBeInited(); }
BOOL HasRemotingProxyAttribute() { WRAPPER_NO_CONTRACT; return GetHalfBakedClass()->HasRemotingProxyAttribute(); }
@@ -1328,10 +1320,6 @@ private:
bool fIsEnum;
bool fNoSanityChecks;
bool fSparse; // Set to true if a sparse interface is being used.
-#ifdef FEATURE_REMOTING
- bool fMarshaledByRef;
- bool fIsContextful;
-#endif
#ifdef FEATURE_COMINTEROP
// Com Interop, ComWrapper classes extend from ComObject
@@ -2024,44 +2012,6 @@ private:
//-----------------------------------------------------------------------------------------
FieldDesc **ppFieldDescList; // FieldDesc pointer (or NULL if field not preserved) for each field
-#ifdef FEATURE_REMOTING
- //-----------------------------------------------------------------------------------------
- // Tracking info for VTS (Version Tolerant Serialization)
- MethodDesc *pOnSerializingMethod;
- MethodDesc *pOnSerializedMethod;
- MethodDesc *pOnDeserializingMethod;
- MethodDesc *pOnDeserializedMethod;
- bool *prfNotSerializedFields;
- bool *prfOptionallySerializedFields;
- bool fNeedsRemotingVtsInfo;
-
- //-----------------------------------------------------------------------------------------
- inline void SetFieldNotSerialized(DWORD dwIndex, DWORD dwNumInstanceFields)
- {
- WRAPPER_NO_CONTRACT;
- if (prfNotSerializedFields == NULL)
- {
- DWORD cbSize = sizeof(bool) * dwNumInstanceFields;
- prfNotSerializedFields = new (&GetThread()->m_MarshalAlloc) bool[dwNumInstanceFields];
- ZeroMemory(prfNotSerializedFields, cbSize);
- }
- prfNotSerializedFields[dwIndex] = true;
- fNeedsRemotingVtsInfo = true;
- }
-
- //-----------------------------------------------------------------------------------------
- inline void SetFieldOptionallySerialized(DWORD dwIndex, DWORD dwNumInstanceFields)
- {
- WRAPPER_NO_CONTRACT;
- if (prfOptionallySerializedFields == NULL)
- {
- prfOptionallySerializedFields = new (&GetThread()->m_MarshalAlloc) bool[dwNumInstanceFields];
- ZeroMemory(prfOptionallySerializedFields, sizeof(bool) * dwNumInstanceFields);
- }
- prfOptionallySerializedFields[dwIndex] = true;
- fNeedsRemotingVtsInfo = true;
- }
-#endif // FEATURE_REMOTING
//-----------------------------------------------------------------------------------------
inline bmtMethAndFieldDescs() { LIMITED_METHOD_CONTRACT; memset((void *)this, NULL, sizeof(*this)); }
@@ -2897,9 +2847,6 @@ private:
LPCUTF8 szAttrName,
MethodDesc **ppMethodDesc);
-#ifdef FEATURE_REMOTING // affects only remoting-related info
- VOID ScanTypeForVtsInfo();
-#endif // FEATURE_REMOTING
VOID
CheckForSystemTypes();
@@ -2978,14 +2925,14 @@ private:
VOID CheckForNativeHFA();
-#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
// checks whether the struct is enregisterable.
void SystemVAmd64CheckForPassStructInRegister();
void SystemVAmd64CheckForPassNativeStructInRegister();
// Store the eightbyte classification into the EEClass
void StoreEightByteClassification(SystemVStructRegisterPassingHelper* helper);
-#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING_ITF
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
// this accesses the field size which is temporarily stored in m_pMTOfEnclosingClass
// during class loading. Don't use any other time
diff --git a/src/vm/mixedmode.cpp b/src/vm/mixedmode.cpp
deleted file mode 100644
index 32d4368363..0000000000
--- a/src/vm/mixedmode.cpp
+++ /dev/null
@@ -1,236 +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.
-// ===========================================================================
-// File: MIXEDMODE.CPP
-//
-
-//
-
-// MIXEDMODE deals with mixed-mode binaries support
-// ===========================================================================
-
-
-
-#include "common.h"
-
-#include "mixedmode.hpp"
-
-#include "dllimportcallback.h"
-
-#ifdef FEATURE_MIXEDMODE
-
-
-IJWNOADThunk::IJWNOADThunk(HMODULE pModulebase, DWORD dwIndex, mdToken Token)
-{
- LIMITED_METHOD_CONTRACT;
- m_pModulebase=pModulebase;
- m_dwIndex=dwIndex;
- m_Token=Token;
- m_fAccessingCache = 0;
-
- for (int i=0; i < IJWNOADThunkStubCacheSize; i++)
- {
- m_cache[i].m_AppDomainID = (ADID)-1;
- m_cache[i].m_CodeAddr = 0;
- }
-
-#ifdef _TARGET_X86_
- m_code.Encode((BYTE*)GetEEFuncEntryPoint(IJWNOADThunkJumpTarget), this);
-#else // !_TARGET_X86_
- m_code.Encode((BYTE*)GetEEFuncEntryPoint(MakeCall), this);
-#endif // !_TARGET_X86_
-};
-
-#define E_PROCESS_SHUTDOWN_REENTRY HRESULT_FROM_WIN32(ERROR_PROCESS_ABORTED)
-
-
-#ifdef _TARGET_X86_
-// Slow path lookup...called from stub
-extern "C" LPCVOID __stdcall IJWNOADThunkJumpTargetHelper(IJWNOADThunk* pThunk)
-{
- WRAPPER_NO_CONTRACT;
-
- return pThunk->FindThunkTarget();
-}
-#endif // _TARGET_X86_
-
-LPCVOID IJWNOADThunk::FindThunkTarget()
-{
- CONTRACT(LPCVOID)
- {
- INSTANCE_CHECK;
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- SO_TOLERANT;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- // We don't plan on fixing this in Whidbey...the IJW scenario has always assumed throwing is "ok" here.
- CONTRACT_VIOLATION(ThrowsViolation);
-
- LPCVOID pvTargetCode = NULL;
-
- AppDomain* pDomain;
-
- Thread* pThread = SetupThread();
-
- // Ensure that we're in preemptive mode.
- // We only need this check for a newly created
- // CLR thread - it defaults to COOP mode from here.
- GCX_PREEMP_NO_DTOR();
-
- pDomain = GetAppDomain();
-
- if (NULL == pDomain)
- {
- _ASSERTE(!"Appdomain should've been set up by SetupThread");
- pDomain = SystemDomain::System()->DefaultDomain();
- }
-
-
- if (NULL != pDomain)
- {
- // Get a local copy so we don't have to deal with a race condition.
- LPCVOID pCacheTarget = NULL;
- GetCachedInfo(pDomain->GetId(), &pvTargetCode);
-
- // Cache miss.
- if (pvTargetCode==NULL)
- {
- INSTALL_UNWIND_AND_CONTINUE_HANDLER;
- BEGIN_SO_INTOLERANT_CODE(pThread);
- {
- Module* pModule;
-
- pModule = pDomain->GetIJWModule(m_pModulebase);
- if (NULL == pModule)
- {
- // New for Whidbey: In V1.1, we just gave up and raised an exception if the target assembly wasn't already loaded
- // into the current appdomain. We now force-inject the assembly.
-
- PEAssemblyHolder pFile(pDomain->BindExplicitAssembly(m_pModulebase, FALSE));
- pDomain->LoadAssembly(NULL, pFile, FILE_ACTIVE);
-
- // Now, try the lookup again. The LoadAssembly() either worked or it didn't. If it didn't, it is probably
- // due to lack of memory and all we can do is raise an exception and hope the IJW caller does something reasonable.
- // Otherwise, we should now succeed in finding the current domain's instantiation of the target module.
- pModule = pDomain->GetIJWModule(m_pModulebase);
- }
-
- if (NULL != pModule)
- {
- pModule->EnsureActive();
-
- UMEntryThunk* pThunkTable;
-
- pThunkTable = pModule->GetADThunkTable();
- pvTargetCode = (LPVOID)GetEEFuncEntryPoint((LPVOID)pThunkTable[m_dwIndex].GetCode());
-
- // Populate the cache with our latest info.
- SetCachedInfo(pDomain->GetId(), pvTargetCode);
- }
- }
- END_SO_INTOLERANT_CODE;
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
- }
- }
-
- if(pvTargetCode==NULL)
- pvTargetCode=(LPVOID)GetEEFuncEntryPoint(SafeNoModule);
-
- RETURN (LPCVOID)pvTargetCode;
-}
-
-#ifdef _TARGET_X86_
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning (disable : 4740) // There is inline asm code in this function, which disables
- // global optimizations.
-#endif // _MSC_VER
-
-__declspec(naked) void _cdecl IJWNOADThunk::MakeCall()
-{
- WRAPPER_NO_CONTRACT;
- struct
- {
- LPVOID This;
- LPCVOID RetAddr;
- } Vars;
- #define LocalsSize 8
-
- _asm enter LocalsSize+4,0;
- _asm push ebx;
- _asm push ecx;
- _asm push edx;
- _asm push esi;
- _asm push edi;
-
- _asm mov Vars.This, eax;
-
- //careful above this point
- _ASSERTE(sizeof(Vars)<=LocalsSize);
-
- Vars.RetAddr = ((IJWNOADThunk*)Vars.This)->FindThunkTarget();
-
- _ASSERTE(NULL != Vars.RetAddr);
-
- _asm pop edi;
- _asm pop esi;
- _asm pop edx;
- _asm pop ecx;
- _asm pop ebx;
- _asm mov eax,Vars.RetAddr;
- _asm leave;
- _asm jmp eax;
-};
-
-#if defined(_MSC_VER)
-#pragma warning(pop)
-#endif
-
-#elif defined(_TARGET_AMD64_)
-// Implemented in AMD64\UMThunkStub.asm
-#elif defined(_TARGET_ARM_)
-// Implemented in Arm\asmhelpers.asm
-#else
-void __cdecl IJWNOADThunk::MakeCall()
-{
- LIMITED_METHOD_CONTRACT;
- PORTABILITY_ASSERT("IJWNOADThunk::MakeCall");
-}
-#endif
-
-void IJWNOADThunk::SafeNoModule()
-{
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_GC_TRIGGERS;
-
- if (!CanRunManagedCode())
- {
- Thread* pThread=GetThread();
-
- // DO NOT IMPROVE THIS EXCEPTION! It cannot be a managed exception. It
- // cannot be a real exception object because we cannot execute any managed
- // code here.
- if(pThread)
- pThread->m_fPreemptiveGCDisabled = 0;
- COMPlusThrowBoot(E_PROCESS_SHUTDOWN_REENTRY);
- }
- NoModule();
-}
-
-void IJWNOADThunk::NoModule()
-{
- WRAPPER_NO_CONTRACT;
- INSTALL_UNWIND_AND_CONTINUE_HANDLER;
- //<TODO>This should give the file name as part of the exception message!</TODO>
- COMPlusThrowHR(COR_E_DLLNOTFOUND);
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
-}
-
-#endif // FEATURE_MIXEDMODE
-
diff --git a/src/vm/mixedmode.hpp b/src/vm/mixedmode.hpp
deleted file mode 100644
index 9d5037af8d..0000000000
--- a/src/vm/mixedmode.hpp
+++ /dev/null
@@ -1,139 +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.
-// ===========================================================================
-// File: mixedmode.H
-//
-
-//
-// MIXEDMODE.H defines classes to support mixed mode dlls
-// ===========================================================================
-
-
-#ifndef _MIXEDMODE_H_
-#define _MIXEDMODE_H_
-
-#ifdef FEATURE_MIXEDMODE
-
-#ifdef _TARGET_X86_
-extern "C" VOID __stdcall IJWNOADThunkJumpTarget(void);
-#endif
-
-
-#define IJWNOADThunkStubCacheSize 4
-
-struct IJWNOADThunkStubCache
-{
- ADID m_AppDomainID; // Must be the first member of the struct.
- LPCVOID m_CodeAddr;
-};
-
-
-
-// Be sure to keep this structure and the assembly view in sync
-class IJWNOADThunk
-{
- UMEntryThunkCode m_code;
-
-protected:
- static void __cdecl MakeCall();
- static void SafeNoModule();
- static void NoModule();
-
- HMODULE m_pModulebase;
- DWORD m_dwIndex;
- mdToken m_Token;
-
- DWORD m_fAccessingCache;
-
-public:
- IJWNOADThunkStubCache m_cache[IJWNOADThunkStubCacheSize];
-
- BOOL IsCachedAppDomainID(ADID pID)
- {
- LIMITED_METHOD_CONTRACT;
-
- for (int i=0; i < IJWNOADThunkStubCacheSize; i++)
- {
- if (m_cache[i].m_AppDomainID == pID)
- return TRUE;
- }
-
- return FALSE;
- };
-
- void GetCachedInfo(ADID pID, LPCVOID* pCode)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- INSTANCE_CHECK;
- SO_TOLERANT;
- PRECONDITION(CheckPointer(pCode));
- }
- CONTRACTL_END;
-
- *pCode = NULL;
-
- for (int i=0; i < IJWNOADThunkStubCacheSize; i++)
- {
- if (m_cache[i].m_AppDomainID == pID)
- *pCode = m_cache[i].m_CodeAddr;
- }
- }
-
- void SetCachedInfo(ADID pID, LPCVOID pCode)
- {
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- INSTANCE_CHECK;
- SO_INTOLERANT;
- }
- CONTRACTL_END;
-
- YIELD_WHILE (FastInterlockCompareExchange((LONG*)&m_fAccessingCache, 1, 0) != 0);
-
- // Don't cache if the cache is already full.
- for (int i=0; i < IJWNOADThunkStubCacheSize; i++)
- {
- if (m_cache[i].m_AppDomainID == (ADID)-1)
- {
- m_cache[i].m_CodeAddr = pCode;
- MemoryBarrier();
- m_cache[i].m_AppDomainID = pID;
- }
- }
-
- m_fAccessingCache = 0;
- }
-
- static IJWNOADThunk* FromCode(PCODE pCodeAddr)
- {
- LIMITED_METHOD_CONTRACT;
- return (IJWNOADThunk*)(PCODEToPINSTR(pCodeAddr) - offsetof(IJWNOADThunk, m_code) - UMEntryThunkCode::GetEntryPointOffset());
- };
- mdToken GetToken()
- {
- LIMITED_METHOD_CONTRACT;
- return m_Token;
- }
-
- IJWNOADThunk(HMODULE pModulebase, DWORD dwIndex, mdToken Token);
-
- LPCBYTE GetCode()
- {
- WRAPPER_NO_CONTRACT;
- return m_code.GetEntryPoint();
- }
-
- LPCVOID IJWNOADThunk::FindThunkTarget();
-};
-
-#endif //FEATURE_MIXEDMODE
-
-#endif // _MIXEDMODE_H_
diff --git a/src/vm/mlinfo.cpp b/src/vm/mlinfo.cpp
index 74bd536969..e5138db97f 100644
--- a/src/vm/mlinfo.cpp
+++ b/src/vm/mlinfo.cpp
@@ -52,19 +52,11 @@
DEFINE_ASM_QUAL_TYPE_NAME(URI_ASM_QUAL_TYPE_NAME, g_SystemUriClassName, g_SystemRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_FXKeyToken);
DEFINE_ASM_QUAL_TYPE_NAME(NCCEVENTARGS_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedEventArgsName, g_ObjectModelAsmName, VER_ASSEMBLYVERSION_STR, g_FXKeyToken);
-#ifdef FEATURE_CORECLR
DEFINE_ASM_QUAL_TYPE_NAME(NCCEVENTARGS_MARSHALER_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedEventArgsMarshalerName, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-#else
- DEFINE_ASM_QUAL_TYPE_NAME(NCCEVENTARGS_MARSHALER_ASM_QUAL_TYPE_NAME, g_NotifyCollectionChangedEventArgsMarshalerName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-#endif
DEFINE_ASM_QUAL_TYPE_NAME(PCEVENTARGS_ASM_QUAL_TYPE_NAME, g_PropertyChangedEventArgsName, g_ObjectModelAsmName, VER_ASSEMBLYVERSION_STR, g_FXKeyToken);
-#ifdef FEATURE_CORECLR
DEFINE_ASM_QUAL_TYPE_NAME(PCEVENTARGS_MARSHALER_ASM_QUAL_TYPE_NAME, g_PropertyChangedEventArgsMarshalerName, g_SystemRuntimeWindowsRuntimeAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-#else
- DEFINE_ASM_QUAL_TYPE_NAME(PCEVENTARGS_MARSHALER_ASM_QUAL_TYPE_NAME, g_PropertyChangedEventArgsMarshalerName, g_SystemAsmName, VER_ASSEMBLYVERSION_STR, g_ECMAKeyToken);
-#endif
#define OLECOLOR_TO_SYSTEMCOLOR_METH_NAME "FromOle"
@@ -1523,9 +1515,6 @@ MarshalInfo::MarshalInfo(Module* pModule,
CorNativeType nativeType = NATIVE_TYPE_DEFAULT;
Assembly *pAssembly = pModule->GetAssembly();
-#ifndef FEATURE_CORECLR
- BOOL fNeedsCopyCtor = FALSE;
-#endif // !FEATURE_CORECLR
m_BestFit = BestFit;
m_ThrowOnUnmappableChar = ThrowOnUnmappableChar;
m_ms = ms;
@@ -1636,23 +1625,6 @@ MarshalInfo::MarshalInfo(Module* pModule,
IfFailGoto(sig.GetElemType(NULL), lFail);
mtype = sig.PeekElemTypeNormalized(pModule, pTypeContext);
-#ifndef FEATURE_CORECLR // no copy ctor support in CoreCLR
- // Check for Copy Constructor Modifier - peek closed elem type here to prevent ELEMENT_TYPE_VALUETYPE
- // turning into a primitive.
- if (sig.PeekElemTypeClosed(pModule, pTypeContext) == ELEMENT_TYPE_VALUETYPE)
- {
- // Skip ET_BYREF
- IfFailGoto(sigtmp.GetByte(NULL), lFail);
-
- if (sigtmp.HasCustomModifier(pModule, "Microsoft.VisualC.NeedsCopyConstructorModifier", ELEMENT_TYPE_CMOD_REQD) ||
- sigtmp.HasCustomModifier(pModule, "System.Runtime.CompilerServices.IsCopyConstructed", ELEMENT_TYPE_CMOD_REQD) )
- {
- mtype = ELEMENT_TYPE_VALUETYPE;
- fNeedsCopyCtor = TRUE;
- m_byref = FALSE;
- }
- }
-#endif // !FEATURE_CORECLR
}
else
{
@@ -1695,21 +1667,6 @@ MarshalInfo::MarshalInfo(Module* pModule,
IfFailGoto(E_FAIL, lFail);
}
-#ifndef FEATURE_CORECLR
- // Check for Copy Constructor Modifier
- if (sigtmp.HasCustomModifier(pModule, "Microsoft.VisualC.NeedsCopyConstructorModifier", ELEMENT_TYPE_CMOD_REQD) ||
- sigtmp.HasCustomModifier(pModule, "System.Runtime.CompilerServices.IsCopyConstructed", ELEMENT_TYPE_CMOD_REQD) )
- {
- mtype = mtype2;
-
- // Keep the sig pointer in sync with mtype (skip ELEMENT_TYPE_PTR) because for the rest
- // of this method we are pretending that the parameter is a value type passed by-value.
- IfFailGoto(sig.GetElemType(NULL), lFail);
-
- fNeedsCopyCtor = TRUE;
- m_byref = FALSE;
- }
-#endif // !FEATURE_CORECLR
}
}
else
@@ -2804,29 +2761,6 @@ MarshalInfo::MarshalInfo(Module* pModule,
}
else
{
-#ifndef FEATURE_CORECLR
- if (fNeedsCopyCtor)
- {
- if (m_ms == MARSHAL_SCENARIO_WINRT)
- {
- // our WinRT-optimized GetCOMIPFromRCW helpers don't support copy
- // constructor stubs so make sure that this marshaler will not be used
- m_resID = IDS_EE_BADMARSHAL_WINRT_COPYCTOR;
- IfFailGoto(E_FAIL, lFail);
- }
-
- MethodDesc *pCopyCtor;
- MethodDesc *pDtor;
- FindCopyCtor(pModule, m_pMT, &pCopyCtor);
- FindDtor(pModule, m_pMT, &pDtor);
-
- m_args.mm.m_pMT = m_pMT;
- m_args.mm.m_pCopyCtor = pCopyCtor;
- m_args.mm.m_pDtor = pDtor;
- m_type = MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR;
- }
- else
-#endif // !FEATURE_CORECLR
#ifdef _TARGET_X86_
// JIT64 is not aware of normalized value types and this optimization
// (returning small value types by value in registers) is already done in JIT64.
@@ -2908,7 +2842,6 @@ MarshalInfo::MarshalInfo(Module* pModule,
lExit:
#ifdef FEATURE_COMINTEROP
-#ifdef FEATURE_CORECLR
//Field scenario is not blocked here because we don't want to block loading structs that
//have the types which we are blocking, but never pass it to Interop.
@@ -2948,7 +2881,6 @@ lExit:
COMPlusThrow(kPlatformNotSupportedException, m_resID);
}
-#endif // FEATURE_CORECLR
if (IsWinRTScenario() && !IsSupportedForWinRT(m_type))
{
@@ -3559,9 +3491,6 @@ UINT16 MarshalInfo::GetNativeSize(MarshalType mtype, MarshalScenario ms)
{
case MARSHAL_TYPE_BLITTABLEVALUECLASS:
case MARSHAL_TYPE_VALUECLASS:
-#ifndef FEATURE_CORECLR
- case MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR:
-#endif // !FEATURE_CORECLR
return (UINT16) m_pMT->GetNativeSize();
default:
@@ -4213,9 +4142,6 @@ DispParamMarshaler *MarshalInfo::GenerateDispParamMarshaler()
case MARSHAL_TYPE_BLITTABLEVALUECLASS:
case MARSHAL_TYPE_BLITTABLEPTR:
case MARSHAL_TYPE_LAYOUTCLASSPTR:
-#ifndef FEATURE_CORECLR
- case MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR:
-#endif
pDispParamMarshaler = new DispParamRecordMarshaler(m_pMT);
break;
@@ -4519,11 +4445,6 @@ VOID MarshalInfo::MarshalTypeToString(SString& strMarshalType, BOOL fSizeIsSpeci
case MARSHAL_TYPE_ARGITERATOR:
strRetVal = W("ArgIterator");
break;
-#ifndef FEATURE_CORECLR
- case MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR:
- strRetVal = W("blittable value class with copy constructor");
- break;
-#endif // FEATURE_CORECLR
#ifdef FEATURE_COMINTEROP
case MARSHAL_TYPE_OBJECT:
strRetVal = W("VARIANT");
@@ -5269,7 +5190,6 @@ void ArrayMarshalInfo::InitElementInfo(CorNativeType arrayNativeType, MarshalInf
}
}
-#ifdef FEATURE_CORECLR
// Avoid throwing exceptions for any managed structs that have layouts and have types of fields that gets default to those banned types by default
// We don't know if they will be passed to native code anyway, and the right place to make the check is in the marshallers
if (AppX::IsAppXProcess() && ms != MarshalInfo::MARSHAL_SCENARIO_FIELD)
@@ -5286,7 +5206,6 @@ void ArrayMarshalInfo::InitElementInfo(CorNativeType arrayNativeType, MarshalInf
if (set_error)
COMPlusThrow(kPlatformNotSupportedException, m_resID);
}
-#endif // FEATURE_CORECLR
// If we are exporting, we need to substitute the VTHACK_* VARTYPE with the actual
// types as expressed in the type library.
diff --git a/src/vm/mlinfo.h b/src/vm/mlinfo.h
index f66c9c6bd8..d1b46065e4 100644
--- a/src/vm/mlinfo.h
+++ b/src/vm/mlinfo.h
@@ -301,14 +301,6 @@ public:
return m_pWinRTPCEventArgsToSystemPCEventArgsMD;
}
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
- BOOL IsEventArgsHelperMethod(MethodDesc *pMD)
- {
- LIMITED_METHOD_CONTRACT;
- return (pMD == m_pSystemNCCEventArgsToWinRTNCCEventArgsMD || pMD == m_pWinRTNCCEventArgsToSystemNCCEventArgsMD ||
- pMD == m_pSystemPCEventArgsToWinRTPCEventArgsMD || pMD == m_pWinRTPCEventArgsToSystemPCEventArgsMD);
- }
-#endif // #if defined(_DEBUG) && !defined(FEATURE_CORECLR)
private:
TypeHandle m_hndSystemNCCEventArgsType;
@@ -384,13 +376,6 @@ public:
return m_SystemUriOriginalStringGetterMD;
}
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
- BOOL IsUriHelperMethod(MethodDesc *pMD)
- {
- LIMITED_METHOD_CONTRACT;
- return pMD == m_SystemUriCtorMD || pMD == m_SystemUriOriginalStringGetterMD;
- }
-#endif // #if defined(_DEBUG) && !defined(FEATURE_CORECLR)
private:
TypeHandle m_hndSystemUriType;
@@ -429,13 +414,6 @@ public:
return m_SystemColorToOleColorMD;
}
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
- BOOL IsOleColorHelperMethod(MethodDesc *pMD)
- {
- LIMITED_METHOD_CONTRACT;
- return pMD == m_OleColorToSystemColorMD || pMD == m_SystemColorToOleColorMD;
- }
-#endif // #if defined(_DEBUG) && !defined(FEATURE_CORECLR)
private:
TypeHandle m_hndColorType;
@@ -470,25 +448,6 @@ public:
UriMarshalingInfo *GetUriMarshalingInfo();
EventArgsMarshalingInfo *GetEventArgsMarshalingInfo();
-#if defined(_DEBUG) && !defined(FEATURE_CORECLR)
- BOOL IsOleColorHelperMethod(MethodDesc *pMD)
- {
- LIMITED_METHOD_CONTRACT;
- return m_pOleColorInfo != NULL && m_pOleColorInfo->IsOleColorHelperMethod(pMD);
- }
-
- BOOL IsUriHelperMethod(MethodDesc *pMD)
- {
- LIMITED_METHOD_CONTRACT;
- return m_pUriInfo != NULL && m_pUriInfo->IsUriHelperMethod(pMD);
- }
-
- BOOL IsEventArgsHelperMethod(MethodDesc *pMD)
- {
- LIMITED_METHOD_CONTRACT;
- return m_pEventArgsInfo != NULL && m_pEventArgsInfo->IsEventArgsHelperMethod(pMD);
- }
-#endif // #if defined(_DEBUG) && !defined(FEATURE_CORECLR)
#endif // FEATURE_COMINTEROP
diff --git a/src/vm/mngstdinterfaces.cpp b/src/vm/mngstdinterfaces.cpp
index ade3fbd483..ec1475dec6 100644
--- a/src/vm/mngstdinterfaces.cpp
+++ b/src/vm/mngstdinterfaces.cpp
@@ -24,9 +24,6 @@
#include "excep.h"
#include "security.h"
#include "typeparse.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
//
// Declare the static field int the ManagedStdInterfaceMap class.
@@ -215,28 +212,7 @@ LPVOID MngStdItfBase::ForwardCallToManagedView(
_ASSERTE(Lr.Obj != NULL);
MethodTable *pTargetMT = Lr.Obj->GetMethodTable();
-#ifdef FEATURE_REMOTING
- if (pTargetMT->IsTransparentProxy())
- {
- // If we get here with a transparent proxy instead of a COM object we need to re-dispatch the call to the TP stub.
- // This can be tricky since the stack is no longer in the right state to make the call directly. Instead we build a
- // small thunk that directly transitions into the remoting system. That way we can use the existing
- // MethodDesc::CallTarget routine to dispatch the call and get the extra argument on the stack (the method desc
- // pointer for the interface method needed by the TP stub) without re-routing ourselves through the fcall stub that
- // would just get us back to here.
-
- MethodDescCallSite mngItf(pMngItfMD, CRemotingServices::GetStubForInterfaceMethod(pMngItfMD));
-
- // Call the stub with the args we were passed originally.
- Result = (Object*)mngItf.Call_RetArgSlot(pArgs);
- if (mngItf.GetMetaSig()->IsObjectRefReturnType())
- {
- Lr.Result = ObjectToOBJECTREF(Result);
- RetValIsProtected = TRUE;
- }
- }
- else
-#endif // FEATURE_REMOTING
+
{
// The target isn't a TP so it better be a COM object.
_ASSERTE(Lr.Obj->GetMethodTable()->IsComObjectType());
diff --git a/src/vm/mscorlib.cpp b/src/vm/mscorlib.cpp
index 6fb2663795..5deaaefa90 100644
--- a/src/vm/mscorlib.cpp
+++ b/src/vm/mscorlib.cpp
@@ -31,9 +31,10 @@
#include "comdelegate.h"
#include "customattribute.h"
#include "comdynamic.h"
-#include "commethodrental.h"
+#include "excep.h"
+#include "fcall.h"
#include "nlsinfo.h"
-#include "calendardata.h"
+#include "clrconfignative.h"
#include "commodule.h"
#include "marshalnative.h"
#include "system.h"
@@ -44,19 +45,11 @@
#include "decimal.h"
#include "currency.h"
#include "comdatetime.h"
-#include "comisolatedstorage.h"
-#include "securityconfig.h"
#include "number.h"
#include "compatibilityswitch.h"
-#ifdef FEATURE_REMOTING
-#include "remotingnative.h"
-#include "message.h"
-#include "stackbuildersink.h"
-#endif
#include "debugdebugger.h"
#include "assemblyname.hpp"
#include "assemblynative.hpp"
-#include "rwlock.h"
#include "comthreadpool.h"
#include "comwaithandle.h"
#include "nativeoverlapped.h"
@@ -83,9 +76,6 @@
#ifdef FEATURE_COMINTEROP
#include "variant.h"
-#ifdef FEATURE_COMINTEROP_TLB_SUPPORT
-#include "comtypelibconverter.h"
-#endif
#include "oavariant.h"
#include "registration.h"
#include "mngstdinterfaces.h"
@@ -95,17 +85,11 @@
#include "stubhelpers.h"
#include "ilmarshalers.h"
-#include "hostexecutioncontext.h"
-
#ifdef FEATURE_MULTICOREJIT
#include "multicorejit.h"
#endif
#ifdef FEATURE_COMINTEROP
-#include "clrprivtypecachereflectiononlywinrt.h"
-#endif
-
-#ifdef FEATURE_COMINTEROP
#include "windowsruntimebufferhelper.h"
#endif
diff --git a/src/vm/mscorlib.h b/src/vm/mscorlib.h
index 78eab6c7d3..244b6900ba 100644
--- a/src/vm/mscorlib.h
+++ b/src/vm/mscorlib.h
@@ -76,26 +76,12 @@ DEFINE_FIELD_U(AssemblyLoad, AppDomainBaseObject, m_pAssemblyEvent
DEFINE_FIELD_U(_TypeResolve, AppDomainBaseObject, m_pTypeEventHandler)
DEFINE_FIELD_U(_ResourceResolve, AppDomainBaseObject, m_pResourceEventHandler)
DEFINE_FIELD_U(_AssemblyResolve, AppDomainBaseObject, m_pAsmResolveEventHandler)
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
-DEFINE_FIELD_U(ReflectionOnlyAssemblyResolve, AppDomainBaseObject, m_pReflectionAsmResolveEventHandler)
-#endif
-#ifdef FEATURE_REMOTING
-DEFINE_FIELD_U(_DefaultContext, AppDomainBaseObject, m_pDefaultContext)
-#endif
DEFINE_FIELD_U(_applicationTrust, AppDomainBaseObject, m_pApplicationTrust)
-#ifdef FEATURE_REMOTING
-DEFINE_FIELD_U(_RemotingData, AppDomainBaseObject, m_pURITable)
-#endif
DEFINE_FIELD_U(_processExit, AppDomainBaseObject, m_pProcessExitEventHandler)
DEFINE_FIELD_U(_domainUnload, AppDomainBaseObject, m_pDomainUnloadEventHandler)
DEFINE_FIELD_U(_unhandledException, AppDomainBaseObject, m_pUnhandledExceptionEventHandler)
-#ifdef FEATURE_APTCA
-DEFINE_FIELD_U(_aptcaVisibleAssemblies, AppDomainBaseObject, m_aptcaVisibleAssemblies)
-#endif
DEFINE_FIELD_U(_compatFlags, AppDomainBaseObject, m_compatFlags)
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
DEFINE_FIELD_U(_firstChanceException, AppDomainBaseObject, m_pFirstChanceExceptionHandler)
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
DEFINE_FIELD_U(_pDomain, AppDomainBaseObject, m_pDomain)
DEFINE_FIELD_U(_HasSetPolicy, AppDomainBaseObject, m_bHasSetPolicy)
DEFINE_FIELD_U(_IsFastFullTrustDomain, AppDomainBaseObject, m_bIsFastFullTrustDomain)
@@ -108,47 +94,13 @@ DEFINE_METHOD(APP_DOMAIN, ON_ASSEMBLY_LOAD, OnAssemblyLoadEvent,
DEFINE_METHOD(APP_DOMAIN, ON_RESOURCE_RESOLVE, OnResourceResolveEvent, IM_Assembly_Str_RetAssembly)
DEFINE_METHOD(APP_DOMAIN, ON_TYPE_RESOLVE, OnTypeResolveEvent, IM_Assembly_Str_RetAssembly)
DEFINE_METHOD(APP_DOMAIN, ON_ASSEMBLY_RESOLVE, OnAssemblyResolveEvent, IM_Assembly_Str_RetAssembly)
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
-DEFINE_METHOD(APP_DOMAIN, ON_REFLECTION_ONLY_ASSEMBLY_RESOLVE, OnReflectionOnlyAssemblyResolveEvent, IM_Assembly_Str_RetAssembly)
-#ifdef FEATURE_COMINTEROP
-DEFINE_METHOD(APP_DOMAIN, ON_REFLECTION_ONLY_NAMESPACE_RESOLVE, OnReflectionOnlyNamespaceResolveEvent, IM_Assembly_Str_RetArrAssembly)
-#endif //FEATURE_COMINTEROP
-DEFINE_METHOD(APP_DOMAIN, ENABLE_RESOLVE_ASSEMBLIES_FOR_INTROSPECTION, EnableResolveAssembliesForIntrospection, IM_Str_RetVoid)
-#endif //FEATURE_REFLECTION_ONLY_LOAD
#ifdef FEATURE_COMINTEROP
DEFINE_METHOD(APP_DOMAIN, ON_DESIGNER_NAMESPACE_RESOLVE, OnDesignerNamespaceResolveEvent, IM_Str_RetArrStr)
#endif //FEATURE_COMINTEROP
DEFINE_METHOD(APP_DOMAIN, SETUP_DOMAIN, SetupDomain, IM_Bool_Str_Str_ArrStr_ArrStr_RetVoid)
-#ifdef FEATURE_FUSION
-DEFINE_METHOD(APP_DOMAIN, SETUP_LOADER_OPTIMIZATION,SetupLoaderOptimization, IM_LoaderOptimization_RetVoid)
-DEFINE_METHOD(APP_DOMAIN, SET_DOMAIN_CONTEXT, InternalSetDomainContext, IM_Str_RetVoid)
-#endif // FEATURE_FUSION
-#ifdef FEATURE_REMOTING
-DEFINE_METHOD(APP_DOMAIN, CREATE_DOMAIN, CreateDomain, SM_Str_Evidence_AppDomainSetup_RetAppDomain)
-DEFINE_METHOD(APP_DOMAIN, VAL_CREATE_DOMAIN, InternalCreateDomain, SM_Str_RetAppDomain)
-#endif
-#ifdef FEATURE_REMOTING
-DEFINE_METHOD(APP_DOMAIN, MARSHAL_OBJECT, MarshalObject, SM_Obj_RetArrByte)
-DEFINE_METHOD(APP_DOMAIN, MARSHAL_OBJECTS, MarshalObjects, SM_Obj_Obj_RefArrByte_RetArrByte)
-DEFINE_METHOD(APP_DOMAIN, UNMARSHAL_OBJECT, UnmarshalObject, SM_ArrByte_RetObj)
-DEFINE_METHOD(APP_DOMAIN, UNMARSHAL_OBJECTS, UnmarshalObjects, SM_ArrByte_ArrByte_RefObj_RetObj)
-#endif
-#ifdef FEATURE_FUSION
-DEFINE_METHOD(APP_DOMAIN, TURN_ON_BINDING_REDIRECTS, TurnOnBindingRedirects, IM_RetVoid)
-#endif // FEATURE_FUSION
DEFINE_METHOD(APP_DOMAIN, CREATE_APP_DOMAIN_MANAGER, CreateAppDomainManager, IM_RetVoid)
DEFINE_METHOD(APP_DOMAIN, INITIALIZE_COMPATIBILITY_FLAGS, InitializeCompatibilityFlags, IM_RetVoid)
DEFINE_METHOD(APP_DOMAIN, INITIALIZE_DOMAIN_SECURITY, InitializeDomainSecurity, IM_Evidence_Evidence_Bool_IntPtr_Bool_RetVoid)
-#ifdef FEATURE_APTCA
-DEFINE_METHOD(APP_DOMAIN, IS_ASSEMBLY_ON_APTCA_VISIBLE_LIST, IsAssemblyOnAptcaVisibleList, IM_Assembly_RetBool)
-DEFINE_METHOD(APP_DOMAIN, IS_ASSEMBLY_ON_APTCA_VISIBLE_LIST_RAW, IsAssemblyOnAptcaVisibleListRaw, IM_PtrChar_Int_PtrByte_Int_RetBool)
-#endif // FEATURE_APTCA
-#ifndef FEATURE_CORECLR
-DEFINE_METHOD(APP_DOMAIN, PAUSE, Pause, SM_RetVoid)
-DEFINE_METHOD(APP_DOMAIN, RESUME, Resume, SM_RetVoid)
-DEFINE_CLASS(APPDOMAIN_MANAGER, System, AppDomainManager)
-DEFINE_PROPERTY(APPDOMAIN_MANAGER, ENTRY_ASSEMBLY, EntryAssembly, AssemblyBase)
-#endif // FEATURE_CORECLR
DEFINE_CLASS(CLEANUP_WORK_LIST, StubHelpers, CleanupWorkList)
@@ -173,15 +125,9 @@ DEFINE_FIELD_U(_ApplicationTrust, AppDomainSetupObject, m_App
DEFINE_FIELD_U(_ConfigurationBytes, AppDomainSetupObject, m_ConfigurationBytes)
DEFINE_FIELD_U(_AppDomainManagerAssembly, AppDomainSetupObject, m_AppDomainManagerAssembly)
DEFINE_FIELD_U(_AppDomainManagerType, AppDomainSetupObject, m_AppDomainManagerType)
-#if FEATURE_APTCA
-DEFINE_FIELD_U(_AptcaVisibleAssemblies, AppDomainSetupObject, m_AptcaVisibleAssemblies)
-#endif
DEFINE_FIELD_U(_CompatFlags, AppDomainSetupObject, m_CompatFlags)
DEFINE_FIELD_U(_TargetFrameworkName, AppDomainSetupObject, m_TargetFrameworkName)
DEFINE_FIELD_U(_LoaderOptimization, AppDomainSetupObject, m_LoaderOptimization)
-#ifndef FEATURE_CORECLR
-DEFINE_FIELD_U(_AppDomainSortingSetupInfo, AppDomainSetupObject, m_AppDomainSortingSetupInfo)
-#endif // FEATURE_CORECLR
#ifdef FEATURE_COMINTEROP
DEFINE_FIELD_U(_DisableInterfaceCache, AppDomainSetupObject, m_DisableInterfaceCache)
#endif // FEATURE_COMINTEROP
@@ -235,9 +181,6 @@ DEFINE_FIELD_U(_Flags, AssemblyNameBaseObject, m_Flags)
DEFINE_CLASS(ASSEMBLY_NAME, Reflection, AssemblyName)
DEFINE_METHOD(ASSEMBLY_NAME, INIT, Init, IM_Str_ArrB_ArrB_Ver_CI_AHA_AVC_Str_ANF_SNKP_RetV)
DEFINE_METHOD(ASSEMBLY_NAME, SET_PROC_ARCH_INDEX, SetProcArchIndex, IM_PEK_IFM_RetV)
-#ifdef FEATURE_APTCA
-DEFINE_METHOD(ASSEMBLY_NAME, GET_NAME_WITH_PUBLIC_KEY, GetNameWithPublicKey, IM_RetStr)
-#endif // FEATURE_APTCA
DEFINE_CLASS_U(System, Version, VersionBaseObject)
DEFINE_FIELD_U(_Major, VersionBaseObject, m_Major)
@@ -260,36 +203,11 @@ DEFINE_FIELD_U(_ModuleResolve, AssemblyBaseObject, m_pModuleEven
DEFINE_FIELD_U(m_fullname, AssemblyBaseObject, m_fullname)
DEFINE_FIELD_U(m_syncRoot, AssemblyBaseObject, m_pSyncRoot)
DEFINE_FIELD_U(m_assembly, AssemblyBaseObject, m_pAssembly)
-#ifndef FEATURE_CORECLR
-DEFINE_FIELD_U(m_flags, AssemblyBaseObject, m_flags)
-#endif
DEFINE_CLASS(ASSEMBLY, Reflection, RuntimeAssembly)
DEFINE_FIELD(ASSEMBLY, HANDLE, m_assembly)
DEFINE_METHOD(ASSEMBLY, GET_NAME, GetName, IM_RetAssemblyName)
-#ifdef FEATURE_APTCA
-DEFINE_METHOD(ASSEMBLY, GET_NAME_FOR_CONDITIONAL_APTCA, GetNameForConditionalAptca, IM_RetStr)
-#endif // FEATURE_APTCA
-#ifdef FEATURE_FUSION
-DEFINE_METHOD(ASSEMBLY, LOAD_WITH_PARTIAL_NAME_HACK, LoadWithPartialNameHack, SM_Str_Bool_RetAssembly)
-#endif // FEATURE_FUSION
DEFINE_METHOD(ASSEMBLY, ON_MODULE_RESOLVE, OnModuleResolveEvent, IM_Str_RetModule)
-#ifdef FEATURE_FUSION
-DEFINE_METHOD(ASSEMBLY, DEMAND_PERMISSION, DemandPermission, SM_Str_Bool_Int_RetV)
-#endif
-
-#ifdef FEATURE_COMINTEROP_REGISTRATION
-DEFINE_CLASS(ASSEMBLY_REGISTRATION_FLAGS, Interop, AssemblyRegistrationFlags)
-#endif // FEATURE_COMINTEROP_REGISTRATION
-#ifdef FEATURE_REMOTING
-DEFINE_CLASS(ACTIVATION_SERVICES, Activation, ActivationServices)
-DEFINE_METHOD(ACTIVATION_SERVICES, IS_CURRENT_CONTEXT_OK, IsCurrentContextOK, SM_Class_ArrObject_Bool_RetMarshalByRefObject)
-
-#ifdef FEATURE_CLASSIC_COMINTEROP
-DEFINE_METHOD(ACTIVATION_SERVICES, CREATE_OBJECT_FOR_COM, CreateObjectForCom, SM_Class_ArrObject_Bool_RetMarshalByRefObject)
-
-#endif // FEATURE_CLASSIC_COMINTEROP
-#endif // FEATURE_REMOTING
DEFINE_CLASS(ASYNCCALLBACK, System, AsyncCallback)
DEFINE_CLASS(ATTRIBUTE, System, Attribute)
@@ -308,18 +226,12 @@ DEFINE_CLASS_U(System, RuntimeType, ReflectClassBaseO
DEFINE_FIELD_U(m_cache, ReflectClassBaseObject, m_cache)
DEFINE_FIELD_U(m_handle, ReflectClassBaseObject, m_typeHandle)
DEFINE_FIELD_U(m_keepalive, ReflectClassBaseObject, m_keepalive)
-#ifdef FEATURE_APPX
-DEFINE_FIELD_U(m_invocationFlags, ReflectClassBaseObject, m_invocationFlags)
-#endif
DEFINE_CLASS(CLASS, System, RuntimeType)
DEFINE_FIELD(CLASS, TYPEHANDLE, m_handle)
DEFINE_METHOD(CLASS, GET_PROPERTIES, GetProperties, IM_BindingFlags_RetArrPropertyInfo)
DEFINE_METHOD(CLASS, GET_FIELDS, GetFields, IM_BindingFlags_RetArrFieldInfo)
DEFINE_METHOD(CLASS, GET_METHODS, GetMethods, IM_BindingFlags_RetArrMethodInfo)
DEFINE_METHOD(CLASS, INVOKE_MEMBER, InvokeMember, IM_Str_BindingFlags_Binder_Obj_ArrObj_ArrParameterModifier_CultureInfo_ArrStr_RetObj)
-#if defined(FEATURE_CLASSIC_COMINTEROP) && defined(FEATURE_REMOTING)
-DEFINE_METHOD(CLASS, FORWARD_CALL_TO_INVOKE, ForwardCallToInvokeMember, IM_Str_BindingFlags_Obj_ArrInt_RefMessageData_RetObj)
-#endif
DEFINE_METHOD(CLASS, GET_METHOD_BASE, GetMethodBase, SM_RuntimeType_RuntimeMethodHandleInternal_RetMethodBase)
DEFINE_METHOD(CLASS, GET_FIELD_INFO, GetFieldInfo, SM_RuntimeType_IRuntimeFieldInfo_RetFieldInfo)
DEFINE_METHOD(CLASS, GET_PROPERTY_INFO, GetPropertyInfo, SM_RuntimeType_Int_RetPropertyInfo)
@@ -335,11 +247,6 @@ DEFINE_METHOD(COM_OBJECT, GET_EVENT_PROVIDER, GetEventProvider,
DEFINE_CLASS(RUNTIME_CLASS, WinRT, RuntimeClass)
-#ifdef FEATURE_COMINTEROP_TLB_SUPPORT
-DEFINE_CLASS(ITYPE_LIB_IMPORTER_NOTIFY_SINK, Interop, ITypeLibImporterNotifySink)
-DEFINE_CLASS(ITYPE_LIB_EXPORTER_NOTIFY_SINK, Interop, ITypeLibExporterNotifySink)
-#endif //FEATURE_COMINTEROP_TLB_SUPPORT
-
#endif // FEATURE_COMINTEROP
DEFINE_CLASS_U(Interop, CriticalHandle, CriticalHandle)
@@ -394,159 +301,20 @@ DEFINE_FIELD_U(m_encodedEnumType, CustomAttributeType, m_enumType)
DEFINE_FIELD_U(m_encodedArrayType, CustomAttributeType, m_arrayType)
DEFINE_FIELD_U(m_padding, CustomAttributeType, m_padding)
-#ifdef FEATURE_REMOTING
-DEFINE_CLASS_U(Contexts, Context, ContextBaseObject)
-DEFINE_FIELD_U(_ctxProps, ContextBaseObject, m_ctxProps)
-DEFINE_FIELD_U(_dphCtx, ContextBaseObject, m_dphCtx)
-DEFINE_FIELD_U(_localDataStore, ContextBaseObject, m_localDataStore)
-DEFINE_FIELD_U(_serverContextChain, ContextBaseObject, m_serverContextChain)
-DEFINE_FIELD_U(_clientContextChain, ContextBaseObject, m_clientContextChain)
-DEFINE_FIELD_U(_appDomain, ContextBaseObject, m_exposedAppDomain)
-DEFINE_FIELD_U(_ctxStatics, ContextBaseObject, m_ctxStatics)
-DEFINE_FIELD_U(_internalContext, ContextBaseObject, m_internalContext)
-DEFINE_FIELD_U(_ctxID, ContextBaseObject, _ctxID)
-DEFINE_FIELD_U(_ctxFlags, ContextBaseObject, _ctxFlags)
-DEFINE_FIELD_U(_numCtxProps, ContextBaseObject, _numCtxProps)
-DEFINE_FIELD_U(_ctxStaticsCurrentBucket, ContextBaseObject, _ctxStaticsCurrentBucket)
-DEFINE_FIELD_U(_ctxStaticsFreeIndex, ContextBaseObject, _ctxStaticsFreeIndex)
-DEFINE_CLASS(CONTEXT, Contexts, Context)
-DEFINE_METHOD(CONTEXT, CALLBACK, DoCallBackFromEE, SM_IntPtr_IntPtr_Int_RetVoid)
-DEFINE_METHOD(CONTEXT, RESERVE_SLOT, ReserveSlot, IM_RetInt)
-#endif
-
-#ifdef FEATURE_REMOTING
-DEFINE_CLASS(CONTEXT_BOUND_OBJECT, System, ContextBoundObject)
-#endif
-
-#ifndef FEATURE_CORECLR
-DEFINE_CLASS_U(Globalization, AppDomainSortingSetupInfo, AppDomainSortingSetupInfoObject)
-DEFINE_FIELD_U(_pfnIsNLSDefinedString, AppDomainSortingSetupInfoObject, m_pfnIsNLSDefinedString)
-DEFINE_FIELD_U(_pfnCompareStringEx, AppDomainSortingSetupInfoObject, m_pfnCompareStringEx)
-DEFINE_FIELD_U(_pfnLCMapStringEx, AppDomainSortingSetupInfoObject, m_pfnLCMapStringEx)
-DEFINE_FIELD_U(_pfnFindNLSStringEx, AppDomainSortingSetupInfoObject, m_pfnFindNLSStringEx)
-DEFINE_FIELD_U(_pfnCompareStringOrdinal, AppDomainSortingSetupInfoObject, m_pfnCompareStringOrdinal)
-DEFINE_FIELD_U(_pfnGetNLSVersionEx, AppDomainSortingSetupInfoObject, m_pfnGetNLSVersionEx)
-DEFINE_FIELD_U(_pfnFindStringOrdinal, AppDomainSortingSetupInfoObject, m_pfnFindStringOrdinal)
-DEFINE_FIELD_U(_useV2LegacySorting, AppDomainSortingSetupInfoObject, m_useV2LegacySorting)
-DEFINE_FIELD_U(_useV4LegacySorting, AppDomainSortingSetupInfoObject, m_useV4LegacySorting)
-#endif // FEATURE_CORECLR
-
-#ifndef FEATURE_COREFX_GLOBALIZATION
-DEFINE_CLASS_U(Globalization, CultureData, CultureDataBaseObject)
-DEFINE_FIELD_U(sRealName, CultureDataBaseObject, sRealName)
-DEFINE_FIELD_U(sWindowsName, CultureDataBaseObject, sWindowsName)
-DEFINE_FIELD_U(sName, CultureDataBaseObject, sName)
-DEFINE_FIELD_U(sParent, CultureDataBaseObject, sParent)
-DEFINE_FIELD_U(sLocalizedDisplayName, CultureDataBaseObject, sLocalizedDisplayName)
-DEFINE_FIELD_U(sEnglishDisplayName, CultureDataBaseObject, sEnglishDisplayName)
-DEFINE_FIELD_U(sNativeDisplayName, CultureDataBaseObject, sNativeDisplayName)
-DEFINE_FIELD_U(sSpecificCulture, CultureDataBaseObject, sSpecificCulture)
-DEFINE_FIELD_U(sISO639Language, CultureDataBaseObject, sISO639Language)
-DEFINE_FIELD_U(sLocalizedLanguage, CultureDataBaseObject, sLocalizedLanguage)
-DEFINE_FIELD_U(sEnglishLanguage, CultureDataBaseObject, sEnglishLanguage)
-DEFINE_FIELD_U(sNativeLanguage, CultureDataBaseObject, sNativeLanguage)
-DEFINE_FIELD_U(sRegionName, CultureDataBaseObject, sRegionName)
-//DEFINE_FIELD_U(iCountry, CultureDataBaseObject, iCountry)
-DEFINE_FIELD_U(iGeoId, CultureDataBaseObject, iGeoId)
-DEFINE_FIELD_U(sLocalizedCountry, CultureDataBaseObject, sLocalizedCountry)
-DEFINE_FIELD_U(sEnglishCountry, CultureDataBaseObject, sEnglishCountry)
-DEFINE_FIELD_U(sNativeCountry, CultureDataBaseObject, sNativeCountry)
-DEFINE_FIELD_U(sISO3166CountryName, CultureDataBaseObject, sISO3166CountryName)
-DEFINE_FIELD_U(sPositiveSign, CultureDataBaseObject, sPositiveSign)
-DEFINE_FIELD_U(sNegativeSign, CultureDataBaseObject, sNegativeSign)
-DEFINE_FIELD_U(saNativeDigits, CultureDataBaseObject, saNativeDigits)
-DEFINE_FIELD_U(iDigitSubstitution, CultureDataBaseObject, iDigitSubstitution)
-DEFINE_FIELD_U(iLeadingZeros, CultureDataBaseObject, iLeadingZeros)
-DEFINE_FIELD_U(iDigits, CultureDataBaseObject, iDigits)
-DEFINE_FIELD_U(iNegativeNumber, CultureDataBaseObject, iNegativeNumber)
-DEFINE_FIELD_U(waGrouping, CultureDataBaseObject, waGrouping)
-DEFINE_FIELD_U(sDecimalSeparator, CultureDataBaseObject, sDecimalSeparator)
-DEFINE_FIELD_U(sThousandSeparator, CultureDataBaseObject, sThousandSeparator)
-DEFINE_FIELD_U(sNaN, CultureDataBaseObject, sNaN)
-DEFINE_FIELD_U(sPositiveInfinity, CultureDataBaseObject, sPositiveInfinity)
-DEFINE_FIELD_U(sNegativeInfinity, CultureDataBaseObject, sNegativeInfinity)
-DEFINE_FIELD_U(iNegativePercent, CultureDataBaseObject, iNegativePercent)
-DEFINE_FIELD_U(iPositivePercent, CultureDataBaseObject, iPositivePercent)
-DEFINE_FIELD_U(sPercent, CultureDataBaseObject, sPercent)
-DEFINE_FIELD_U(sPerMille, CultureDataBaseObject, sPerMille)
-DEFINE_FIELD_U(sCurrency, CultureDataBaseObject, sCurrency)
-DEFINE_FIELD_U(sIntlMonetarySymbol, CultureDataBaseObject, sIntlMonetarySymbol)
-DEFINE_FIELD_U(sEnglishCurrency, CultureDataBaseObject, sEnglishCurrency)
-DEFINE_FIELD_U(sNativeCurrency, CultureDataBaseObject, sNativeCurrency)
-DEFINE_FIELD_U(iCurrencyDigits, CultureDataBaseObject, iCurrencyDigits)
-DEFINE_FIELD_U(iCurrency, CultureDataBaseObject, iCurrency)
-DEFINE_FIELD_U(iNegativeCurrency, CultureDataBaseObject, iNegativeCurrency)
-DEFINE_FIELD_U(waMonetaryGrouping, CultureDataBaseObject, waMonetaryGrouping)
-DEFINE_FIELD_U(sMonetaryDecimal, CultureDataBaseObject, sMonetaryDecimal)
-DEFINE_FIELD_U(sMonetaryThousand, CultureDataBaseObject, sMonetaryThousand)
-DEFINE_FIELD_U(iMeasure, CultureDataBaseObject, iMeasure)
-DEFINE_FIELD_U(sListSeparator, CultureDataBaseObject, sListSeparator)
-//DEFINE_FIELD_U(iPaperSize, CultureDataBaseObject, iPaperSize)
-//DEFINE_FIELD_U(waFontSignature, CultureDataBaseObject, waFontSignature)
-DEFINE_FIELD_U(sAM1159, CultureDataBaseObject, sAM1159)
-DEFINE_FIELD_U(sPM2359, CultureDataBaseObject, sPM2359)
-DEFINE_FIELD_U(sTimeSeparator, CultureDataBaseObject, sTimeSeparator)
-DEFINE_FIELD_U(saLongTimes, CultureDataBaseObject, saLongTimes)
-DEFINE_FIELD_U(saShortTimes, CultureDataBaseObject, saShortTimes)
-DEFINE_FIELD_U(saDurationFormats, CultureDataBaseObject, saDurationFormats)
-DEFINE_FIELD_U(iFirstDayOfWeek, CultureDataBaseObject, iFirstDayOfWeek)
-DEFINE_FIELD_U(iFirstWeekOfYear, CultureDataBaseObject, iFirstWeekOfYear)
-DEFINE_FIELD_U(waCalendars, CultureDataBaseObject, waCalendars)
-DEFINE_FIELD_U(calendars, CultureDataBaseObject, calendars)
-DEFINE_FIELD_U(iReadingLayout, CultureDataBaseObject, iReadingLayout)
-DEFINE_FIELD_U(sTextInfo, CultureDataBaseObject, sTextInfo)
-DEFINE_FIELD_U(sCompareInfo, CultureDataBaseObject, sCompareInfo)
-DEFINE_FIELD_U(sScripts, CultureDataBaseObject, sScripts)
-DEFINE_FIELD_U(bUseOverrides, CultureDataBaseObject, bUseOverrides)
-DEFINE_FIELD_U(bNeutral, CultureDataBaseObject, bNeutral)
-DEFINE_FIELD_U(bWin32Installed, CultureDataBaseObject, bWin32Installed)
-DEFINE_FIELD_U(bFramework, CultureDataBaseObject, bFramework)
-#endif
-#ifndef FEATURE_COREFX_GLOBALIZATION
-DEFINE_CLASS_U(Globalization, CalendarData, CalendarDataBaseObject)
-DEFINE_FIELD_U(sNativeName, CalendarDataBaseObject, sNativeName)
-DEFINE_FIELD_U(saShortDates, CalendarDataBaseObject, saShortDates)
-DEFINE_FIELD_U(saYearMonths, CalendarDataBaseObject, saYearMonths)
-DEFINE_FIELD_U(saLongDates, CalendarDataBaseObject, saLongDates)
-DEFINE_FIELD_U(sMonthDay, CalendarDataBaseObject, sMonthDay)
-DEFINE_FIELD_U(saEraNames, CalendarDataBaseObject, saEraNames)
-DEFINE_FIELD_U(saAbbrevEraNames, CalendarDataBaseObject, saAbbrevEraNames)
-DEFINE_FIELD_U(saAbbrevEnglishEraNames,CalendarDataBaseObject, saAbbrevEnglishEraNames)
-DEFINE_FIELD_U(saDayNames, CalendarDataBaseObject, saDayNames)
-DEFINE_FIELD_U(saAbbrevDayNames, CalendarDataBaseObject, saAbbrevDayNames)
-DEFINE_FIELD_U(saSuperShortDayNames, CalendarDataBaseObject, saSuperShortDayNames)
-DEFINE_FIELD_U(saMonthNames, CalendarDataBaseObject, saMonthNames)
-DEFINE_FIELD_U(saAbbrevMonthNames, CalendarDataBaseObject, saAbbrevMonthNames)
-DEFINE_FIELD_U(saMonthGenitiveNames, CalendarDataBaseObject, saMonthGenitiveNames)
-DEFINE_FIELD_U(saAbbrevMonthGenitiveNames, CalendarDataBaseObject, saAbbrevMonthGenitiveNames)
-DEFINE_FIELD_U(saLeapYearMonthNames, CalendarDataBaseObject, saLeapYearMonthNames)
-DEFINE_FIELD_U(iTwoDigitYearMax, CalendarDataBaseObject, iTwoDigitYearMax)
-DEFINE_FIELD_U(iCurrentEra, CalendarDataBaseObject, iCurrentEra)
-DEFINE_FIELD_U(bUseUserOverrides, CalendarDataBaseObject, bUseUserOverrides)
-#endif
-
DEFINE_CLASS_U(Globalization, CultureInfo, CultureInfoBaseObject)
DEFINE_FIELD_U(compareInfo, CultureInfoBaseObject, compareInfo)
DEFINE_FIELD_U(textInfo, CultureInfoBaseObject, textInfo)
DEFINE_FIELD_U(numInfo, CultureInfoBaseObject, numInfo)
DEFINE_FIELD_U(dateTimeInfo, CultureInfoBaseObject, dateTimeInfo)
DEFINE_FIELD_U(calendar, CultureInfoBaseObject, calendar)
-DEFINE_FIELD_U(m_consoleFallbackCulture, CultureInfoBaseObject, m_consoleFallbackCulture)
-DEFINE_FIELD_U(m_name, CultureInfoBaseObject, m_name)
-DEFINE_FIELD_U(m_nonSortName, CultureInfoBaseObject, m_nonSortName)
-DEFINE_FIELD_U(m_sortName, CultureInfoBaseObject, m_sortName)
-DEFINE_FIELD_U(m_parent, CultureInfoBaseObject, m_parent)
-#ifdef FEATURE_LEAK_CULTURE_INFO
-DEFINE_FIELD_U(m_createdDomainID, CultureInfoBaseObject, m_createdDomainID)
-#endif // FEATURE_LEAK_CULTURE_INFO
-DEFINE_FIELD_U(m_isReadOnly, CultureInfoBaseObject, m_isReadOnly)
-DEFINE_FIELD_U(m_isInherited, CultureInfoBaseObject, m_isInherited)
-#ifdef FEATURE_LEAK_CULTURE_INFO
-DEFINE_FIELD_U(m_isSafeCrossDomain, CultureInfoBaseObject, m_isSafeCrossDomain)
-#endif // FEATURE_LEAK_CULTURE_INFO
-#ifndef FEATURE_COREFX_GLOBALIZATION
-DEFINE_FIELD_U(m_useUserOverride, CultureInfoBaseObject, m_useUserOverride)
-#endif
+DEFINE_FIELD_U(_consoleFallbackCulture, CultureInfoBaseObject, _consoleFallbackCulture)
+DEFINE_FIELD_U(_name, CultureInfoBaseObject, _name)
+DEFINE_FIELD_U(_nonSortName, CultureInfoBaseObject, _nonSortName)
+DEFINE_FIELD_U(_sortName, CultureInfoBaseObject, _sortName)
+DEFINE_FIELD_U(_parent, CultureInfoBaseObject, _parent)
+DEFINE_FIELD_U(_isReadOnly, CultureInfoBaseObject, _isReadOnly)
+DEFINE_FIELD_U(_isInherited, CultureInfoBaseObject, _isInherited)
+DEFINE_FIELD_U(_useUserOverride, CultureInfoBaseObject, _useUserOverride)
DEFINE_CLASS(CULTURE_INFO, Globalization, CultureInfo)
DEFINE_METHOD(CULTURE_INFO, STR_CTOR, .ctor, IM_Str_RetVoid)
DEFINE_FIELD(CULTURE_INFO, CURRENT_CULTURE, s_userDefaultCulture)
@@ -606,9 +374,7 @@ DEFINE_CLASS(ENUM, System, Enum)
DEFINE_CLASS(ENVIRONMENT, System, Environment)
DEFINE_METHOD(ENVIRONMENT, GET_RESOURCE_STRING_LOCAL, GetResourceStringLocal, SM_Str_RetStr)
-#ifdef FEATURE_CORECLR
DEFINE_METHOD(ENVIRONMENT, SET_COMMAND_LINE_ARGS, SetCommandLineArgs, SM_ArrStr_RetVoid)
-#endif
#ifdef FEATURE_COMINTEROP
DEFINE_CLASS(ERROR_WRAPPER, Interop, ErrorWrapper)
@@ -639,9 +405,6 @@ DEFINE_FIELD_U(_stackTraceString, ExceptionObject, _stackTraceString)
DEFINE_FIELD_U(_remoteStackTraceString, ExceptionObject, _remoteStackTraceString)
DEFINE_FIELD_U(_dynamicMethods, ExceptionObject, _dynamicMethods)
DEFINE_FIELD_U(_xptrs, ExceptionObject, _xptrs)
-#ifdef FEATURE_SERIALIZATION
-DEFINE_FIELD_U(_safeSerializationManager, ExceptionObject, _safeSerializationManager)
-#endif // FEATURE_SERIALIZATION
DEFINE_FIELD_U(_HResult, ExceptionObject, _HResult)
DEFINE_FIELD_U(_xcode, ExceptionObject, _xcode)
DEFINE_FIELD_U(_remoteStackIndex, ExceptionObject, _remoteStackIndex)
@@ -659,12 +422,10 @@ DEFINE_METHOD(EXCEPTION, ADD_EXCEPTION_DATA_FOR_RESTRICTED_ERROR_INFO
DEFINE_METHOD(EXCEPTION, TRY_GET_RESTRICTED_LANGUAGE_ERROR_OBJECT, TryGetRestrictedLanguageErrorObject, IM_RefObject_RetBool)
#endif // FEATURE_COMINTEROP
-#ifdef FEATURE_CORECLR
DEFINE_CLASS(CROSSAPPDOMAINMARSHALEDEXCEPTION, System, CrossAppDomainMarshaledException)
DEFINE_METHOD(CROSSAPPDOMAINMARSHALEDEXCEPTION, STR_INT_CTOR, .ctor, IM_Str_Int_RetVoid)
-#endif //FEATURE_CORECLR
DEFINE_CLASS(SYSTEM_EXCEPTION, System, SystemException)
@@ -704,22 +465,6 @@ DEFINE_CLASS(I_RT_FIELD_INFO, System, IRuntimeFieldInfo)
DEFINE_CLASS(FIELD_INFO, Reflection, FieldInfo)
-#ifndef FEATURE_CORECLR
-DEFINE_CLASS_U(IO, FileStreamAsyncResult, AsyncResultBase)
-DEFINE_FIELD_U(_userCallback, AsyncResultBase, _userCallback)
-DEFINE_FIELD_U(_userStateObject, AsyncResultBase, _userStateObject)
-DEFINE_FIELD_U(_waitHandle, AsyncResultBase, _waitHandle)
-DEFINE_FIELD_U(_handle, AsyncResultBase, _fileHandle)
-DEFINE_FIELD_U(_overlapped, AsyncResultBase, _overlapped)
-DEFINE_FIELD_U(_EndXxxCalled, AsyncResultBase, _EndXxxCalled)
-DEFINE_FIELD_U(_numBytes, AsyncResultBase, _numBytes)
-DEFINE_FIELD_U(_errorCode, AsyncResultBase, _errorCode)
-DEFINE_FIELD_U(_numBufferedBytes, AsyncResultBase, _numBufferedBytes)
-DEFINE_FIELD_U(_isWrite, AsyncResultBase, _isWrite)
-DEFINE_FIELD_U(_isComplete, AsyncResultBase, _isComplete)
-DEFINE_FIELD_U(_completedSynchronously, AsyncResultBase, _completedSynchronously)
-DEFINE_CLASS(FILESTREAM_ASYNCRESULT, IO, FileStreamAsyncResult)
-#endif // !FEATURE_CORECLR
DEFINE_CLASS(GUID, System, Guid)
@@ -771,12 +516,6 @@ DEFINE_METHOD(ICUSTOM_QUERYINTERFACE, GET_INTERFACE, GetInterface,
DEFINE_CLASS(CUSTOMQUERYINTERFACERESULT, Interop, CustomQueryInterfaceResult)
#endif //FEATURE_COMINTEROP
-#ifdef FEATURE_REMOTING
-DEFINE_CLASS(IDENTITY, Remoting, Identity)
-DEFINE_FIELD(IDENTITY, TP_OR_OBJECT, _tpOrObject)
-DEFINE_FIELD(IDENTITY, LEASE, _lease)
-DEFINE_FIELD(IDENTITY, OBJURI, _ObjURI)
-#endif
DEFINE_CLASS(ISERIALIZABLE, Serialization, ISerializable)
DEFINE_CLASS(IOBJECTREFERENCE, Serialization, IObjectReference)
@@ -784,11 +523,6 @@ DEFINE_CLASS(IDESERIALIZATIONCB, Serialization, IDeserializationCall
DEFINE_CLASS(STREAMING_CONTEXT, Serialization, StreamingContext)
DEFINE_CLASS(SERIALIZATION_INFO, Serialization, SerializationInfo)
-#ifdef FEATURE_REMOTING
-DEFINE_CLASS(OBJECTCLONEHELPER, Serialization, ObjectCloneHelper)
-DEFINE_METHOD(OBJECTCLONEHELPER, GET_OBJECT_DATA, GetObjectData, SM_Obj_OutStr_OutStr_OutArrStr_OutArrObj_RetObj)
-DEFINE_METHOD(OBJECTCLONEHELPER, PREPARE_DATA, PrepareConstructorArgs, SM_Obj_ArrStr_ArrObj_OutStreamingContext_RetSerializationInfo)
-#endif
DEFINE_CLASS(IENUMERATOR, Collections, IEnumerator)
@@ -808,13 +542,6 @@ DEFINE_METHOD(IREFLECT, GET_FIELDS, GetFields,
DEFINE_METHOD(IREFLECT, GET_METHODS, GetMethods, IM_BindingFlags_RetArrMethodInfo)
DEFINE_METHOD(IREFLECT, INVOKE_MEMBER, InvokeMember, IM_Str_BindingFlags_Binder_Obj_ArrObj_ArrParameterModifier_CultureInfo_ArrStr_RetObj)
-#ifdef FEATURE_ISOSTORE
-#ifndef FEATURE_ISOSTORE_LIGHT
-DEFINE_CLASS(ISS_STORE, IsolatedStorage, IsolatedStorage)
-#endif // !FEATURE_ISOSTORE_LIGHT
-DEFINE_CLASS(ISS_STORE_FILE, IsolatedStorage, IsolatedStorageFile)
-DEFINE_CLASS(ISS_STORE_FILE_STREAM, IsolatedStorage, IsolatedStorageFileStream)
-#endif
#ifdef FEATURE_COMINTEROP
DEFINE_CLASS(LCID_CONVERSION_TYPE, Interop, LCIDConversionAttribute)
@@ -822,16 +549,6 @@ DEFINE_CLASS(LCID_CONVERSION_TYPE, Interop, LCIDConversionAttrib
DEFINE_CLASS(LOADER_OPTIMIZATION, System, LoaderOptimization)
-#ifdef FEATURE_REMOTING
-DEFINE_CLASS_U(Messaging, LogicalCallContext, LogicalCallContextObject)
-DEFINE_FIELD_U(m_Datastore, LogicalCallContextObject, m_Datastore)
-DEFINE_FIELD_U(m_RemotingData, LogicalCallContextObject, m_RemotingData)
-DEFINE_FIELD_U(m_SecurityData, LogicalCallContextObject, m_SecurityData)
-DEFINE_FIELD_U(m_HostContext, LogicalCallContextObject, m_HostContext)
-DEFINE_FIELD_U(m_IsCorrelationMgr, LogicalCallContextObject, m_IsCorrelationMgr)
-DEFINE_FIELD_U(_sendHeaders, LogicalCallContextObject, _sendHeaders)
-DEFINE_FIELD_U(_recvHeaders, LogicalCallContextObject, _recvHeaders)
-#endif
DEFINE_CLASS(MARSHAL, Interop, Marshal)
#ifdef FEATURE_COMINTEROP
@@ -845,37 +562,9 @@ DEFINE_METHOD(MARSHAL, GET_DELEGATE_FOR_FUNCTION_POINTER, GetDelega
DEFINE_METHOD(MARSHAL, ALLOC_CO_TASK_MEM, AllocCoTaskMem, SM_Int_RetIntPtr)
DEFINE_FIELD(MARSHAL, SYSTEM_MAX_DBCS_CHAR_SIZE, SystemMaxDBCSCharSize)
-#ifdef FEATURE_REMOTING
-DEFINE_CLASS_U(System, MarshalByRefObject, MarshalByRefObjectBaseObject)
-DEFINE_FIELD_U(__identity, MarshalByRefObjectBaseObject, m_ServerIdentity)
-DEFINE_CLASS(MARSHAL_BY_REF_OBJECT, System, MarshalByRefObject)
-#endif
DEFINE_CLASS(MEMBER, Reflection, MemberInfo)
-#ifdef FEATURE_REMOTING
-DEFINE_CLASS_U(Messaging, Message, MessageObject)
-DEFINE_FIELD_U(_MethodName, MessageObject, pMethodName)
-DEFINE_FIELD_U(_MethodSignature, MessageObject, pMethodSig)
-DEFINE_FIELD_U(_MethodBase, MessageObject, pMethodBase)
-DEFINE_FIELD_U(_properties, MessageObject, pHashTable)
-DEFINE_FIELD_U(_URI, MessageObject, pURI)
-DEFINE_FIELD_U(_typeName, MessageObject, pTypeName)
-DEFINE_FIELD_U(_Fault, MessageObject, pFault)
-DEFINE_FIELD_U(_ID, MessageObject, pID)
-DEFINE_FIELD_U(_srvID, MessageObject, pSrvID)
-DEFINE_FIELD_U(_argMapper, MessageObject, pArgMapper)
-DEFINE_FIELD_U(_callContext, MessageObject, pCallCtx)
-DEFINE_FIELD_U(_frame, MessageObject, pFrame)
-DEFINE_FIELD_U(_methodDesc, MessageObject, pMethodDesc)
-DEFINE_FIELD_U(_metaSigHolder, MessageObject, pMetaSigHolder)
-DEFINE_FIELD_U(_delegateMD, MessageObject, pDelegateMD)
-DEFINE_FIELD_U(_governingType, MessageObject, thGoverningType)
-DEFINE_FIELD_U(_flags, MessageObject, iFlags)
-DEFINE_FIELD_U(_initDone, MessageObject, initDone)
-
-DEFINE_CLASS(MESSAGE_DATA, Proxies, MessageData)
-#endif // FEATURE_REMOTING
DEFINE_CLASS_U(Reflection, RuntimeMethodInfo, NoClass)
DEFINE_FIELD_U(m_handle, ReflectMethodObject, m_pMD)
@@ -921,10 +610,6 @@ DEFINE_CLASS(METHOD_HANDLE, System, RuntimeMethodHandle)
DEFINE_FIELD(METHOD_HANDLE, METHOD, m_value)
DEFINE_METHOD(METHOD_HANDLE, GETVALUEINTERNAL, GetValueInternal, SM_RuntimeMethodHandle_RetIntPtr)
-#ifdef FEATURE_METHOD_RENTAL
-DEFINE_CLASS(METHOD_RENTAL, ReflectionEmit, MethodRental)
-#endif // FEATURE_METHOD_RENTAL
-
DEFINE_CLASS(MISSING, Reflection, Missing)
DEFINE_FIELD(MISSING, VALUE, Value)
@@ -966,11 +651,9 @@ DEFINE_FIELD(NULL, VALUE, Value)
DEFINE_CLASS(NULLABLE, System, Nullable`1)
-#ifdef FEATURE_SPAN_OF_T
DEFINE_CLASS(BYREFERENCE, System, ByReference`1)
DEFINE_CLASS(SPAN, System, Span`1)
DEFINE_CLASS(READONLY_SPAN, System, ReadOnlySpan`1)
-#endif
// Keep this in sync with System.Globalization.NumberFormatInfo
DEFINE_CLASS_U(Globalization, NumberFormatInfo, NumberFormatInfo)
@@ -984,9 +667,6 @@ DEFINE_FIELD_U(numberGroupSeparator, NumberFormatInfo, sNumberGroup)
DEFINE_FIELD_U(currencyGroupSeparator, NumberFormatInfo, sCurrencyGroup)
DEFINE_FIELD_U(currencyDecimalSeparator,NumberFormatInfo, sCurrencyDecimal)
DEFINE_FIELD_U(currencySymbol, NumberFormatInfo, sCurrency)
-#ifndef FEATURE_COREFX_GLOBALIZATION
-DEFINE_FIELD_U(ansiCurrencySymbol, NumberFormatInfo, sAnsiCurrency)
-#endif
DEFINE_FIELD_U(nanSymbol, NumberFormatInfo, sNaN)
DEFINE_FIELD_U(positiveInfinitySymbol, NumberFormatInfo, sPositiveInfinity)
DEFINE_FIELD_U(negativeInfinitySymbol, NumberFormatInfo, sNegativeInfinity)
@@ -995,9 +675,6 @@ DEFINE_FIELD_U(percentGroupSeparator, NumberFormatInfo, sPercentGroup)
DEFINE_FIELD_U(percentSymbol, NumberFormatInfo, sPercent)
DEFINE_FIELD_U(perMilleSymbol, NumberFormatInfo, sPerMille)
DEFINE_FIELD_U(nativeDigits, NumberFormatInfo, sNativeDigits)
-#ifndef FEATURE_COREFX_GLOBALIZATION
-DEFINE_FIELD_U(m_dataItem, NumberFormatInfo, iDataItem)
-#endif
DEFINE_FIELD_U(numberDecimalDigits, NumberFormatInfo, cNumberDecimals)
DEFINE_FIELD_U(currencyDecimalDigits, NumberFormatInfo, cCurrencyDecimals)
DEFINE_FIELD_U(currencyPositivePattern,NumberFormatInfo, cPosCurrencyFormat)
@@ -1008,14 +685,7 @@ DEFINE_FIELD_U(percentNegativePattern, NumberFormatInfo, cNegativePercentForma
DEFINE_FIELD_U(percentDecimalDigits, NumberFormatInfo, cPercentDecimals)
DEFINE_FIELD_U(digitSubstitution, NumberFormatInfo, iDigitSubstitution)
DEFINE_FIELD_U(isReadOnly, NumberFormatInfo, bIsReadOnly)
-#ifndef FEATURE_COREFX_GLOBALIZATION
-DEFINE_FIELD_U(m_useUserOverride, NumberFormatInfo, bUseUserOverride)
-#endif
DEFINE_FIELD_U(m_isInvariant, NumberFormatInfo, bIsInvariant)
-#ifndef FEATURE_COREFX_GLOBALIZATION
-DEFINE_FIELD_U(validForParseAsNumber, NumberFormatInfo, bvalidForParseAsNumber)
-DEFINE_FIELD_U(validForParseAsCurrency,NumberFormatInfo, bvalidForParseAsCurrency)
-#endif
// Defined as element type alias
// DEFINE_CLASS(OBJECT, System, Object)
@@ -1097,64 +767,6 @@ DEFINE_METHOD(PROPERTY, GET_GETTER, GetGetMethod,
DEFINE_CLASS(PROPERTY_INFO, Reflection, PropertyInfo)
-#ifdef FEATURE_REMOTING
-DEFINE_CLASS(PROXY_ATTRIBUTE, Proxies, ProxyAttribute)
-
-DEFINE_CLASS_U(Proxies, RealProxy, RealProxyObject)
-DEFINE_FIELD_U(_tp, RealProxyObject, _tp)
-DEFINE_FIELD_U(_identity, RealProxyObject, _identity)
-DEFINE_FIELD_U(_serverObject, RealProxyObject, _serverObject)
-DEFINE_FIELD_U(_flags, RealProxyObject, _flags)
-DEFINE_FIELD_U(_optFlags, RealProxyObject, _optFlags)
-DEFINE_FIELD_U(_domainID, RealProxyObject, _domainID)
-DEFINE_FIELD_U(_srvIdentity, RealProxyObject, _srvIdentity)
-DEFINE_CLASS(REAL_PROXY, Proxies, RealProxy)
-DEFINE_METHOD(REAL_PROXY, PRIVATE_INVOKE, PrivateInvoke, IM_RefMessageData_Int_RetVoid)
-#ifdef FEATURE_COMINTEROP
-DEFINE_METHOD(REAL_PROXY, GETDCOMPROXY, GetCOMIUnknown, IM_Bool_RetIntPtr)
-DEFINE_METHOD(REAL_PROXY, SETDCOMPROXY, SetCOMIUnknown, IM_IntPtr_RetVoid)
-DEFINE_METHOD(REAL_PROXY, SUPPORTSINTERFACE, SupportsInterface, IM_RefGuid_RetIntPtr)
-
-#endif // FEATURE_COMINTEROP
-#endif // FEATURE_REMOTING
-
-#ifdef FEATURE_COMINTEROP_REGISTRATION
-DEFINE_CLASS(REGISTRATION_SERVICES, Interop, RegistrationServices)
-DEFINE_METHOD(REGISTRATION_SERVICES,REGISTER_ASSEMBLY, RegisterAssembly, IM_AssemblyBase_AssemblyRegistrationFlags_RetBool)
-DEFINE_METHOD(REGISTRATION_SERVICES,UNREGISTER_ASSEMBLY, UnregisterAssembly, IM_AssemblyBase_RetBool)
-#endif // FEATURE_COMINTEROP_REGISTRATION
-
-#ifdef FEATURE_RWLOCK
-DEFINE_CLASS_U(Threading, ReaderWriterLock, CRWLock)
-DEFINE_FIELD_U(_hWriterEvent, CRWLock, _hWriterEvent)
-DEFINE_FIELD_U(_hReaderEvent, CRWLock, _hReaderEvent)
-DEFINE_FIELD_U(_hObjectHandle, CRWLock, _hObjectHandle)
-DEFINE_FIELD_U(_dwState, CRWLock, _dwState)
-DEFINE_FIELD_U(_dwULockID, CRWLock, _dwULockID)
-DEFINE_FIELD_U(_dwLLockID, CRWLock, _dwLLockID)
-DEFINE_FIELD_U(_dwWriterID, CRWLock, _dwWriterID)
-DEFINE_FIELD_U(_dwWriterSeqNum, CRWLock, _dwWriterSeqNum)
-DEFINE_FIELD_U(_wWriterLevel, CRWLock, _wWriterLevel)
-#endif // FEATURE_RWLOCK
-
-#ifdef FEATURE_REMOTING
-DEFINE_CLASS(LEASE, Lifetime, Lease)
-DEFINE_METHOD(LEASE, RENEW_ON_CALL, RenewOnCall, IM_RetVoid)
-
-DEFINE_CLASS(REMOTING_PROXY, Proxies, RemotingProxy)
-DEFINE_METHOD(REMOTING_PROXY, INVOKE, Invoke, SM_Obj_RefMessageData_RetVoid)
-
-DEFINE_CLASS(REMOTING_SERVICES, Remoting, RemotingServices)
-DEFINE_METHOD(REMOTING_SERVICES, CHECK_CAST, CheckCast, SM_RealProxy_Class_RetBool)
-DEFINE_METHOD(REMOTING_SERVICES, GET_TYPE, GetType, SM_Obj_RetObj)
-DEFINE_METHOD(REMOTING_SERVICES, WRAP, Wrap, SM_ContextBoundObject_RetObj)
-DEFINE_METHOD(REMOTING_SERVICES, CREATE_PROXY_FOR_DOMAIN,CreateProxyForDomain, SM_Int_IntPtr_RetObj)
-DEFINE_METHOD(REMOTING_SERVICES, GET_SERVER_CONTEXT_FOR_PROXY,GetServerContextForProxy, SM_Obj_RetIntPtr)
-DEFINE_METHOD(REMOTING_SERVICES, GET_SERVER_DOMAIN_ID_FOR_PROXY,GetServerDomainIdForProxy, SM_Obj_RetInt)
-DEFINE_METHOD(REMOTING_SERVICES, MARSHAL_TO_BUFFER, MarshalToBuffer, SM_Obj_Bool_RetArrByte)
-DEFINE_METHOD(REMOTING_SERVICES, UNMARSHAL_FROM_BUFFER, UnmarshalFromBuffer, SM_ArrByte_Bool_RetObj)
-DEFINE_METHOD(REMOTING_SERVICES, DOMAIN_UNLOADED, DomainUnloaded, SM_Int_RetVoid)
-#endif // FEATURE_REMOTING
DEFINE_CLASS(METADATA_IMPORT, Reflection, MetadataImport)
@@ -1179,6 +791,7 @@ DEFINE_CLASS(RUNTIME_HELPERS, CompilerServices, RuntimeHelpers)
DEFINE_METHOD(RUNTIME_HELPERS, PREPARE_CONSTRAINED_REGIONS, PrepareConstrainedRegions, SM_RetVoid)
DEFINE_METHOD(RUNTIME_HELPERS, PREPARE_CONSTRAINED_REGIONS_NOOP, PrepareConstrainedRegionsNoOP, SM_RetVoid)
DEFINE_METHOD(RUNTIME_HELPERS, EXECUTE_BACKOUT_CODE_HELPER, ExecuteBackoutCodeHelper, SM_Obj_Obj_Bool_RetVoid)
+DEFINE_METHOD(RUNTIME_HELPERS, IS_REFERENCE_OR_CONTAINS_REFERENCES, IsReferenceOrContainsReferences, NoSig)
DEFINE_CLASS(JIT_HELPERS, CompilerServices, JitHelpers)
#ifdef _DEBUG
@@ -1192,21 +805,21 @@ DEFINE_METHOD(JIT_HELPERS, UNSAFE_ENUM_CAST, UnsafeEnumCast, NoSi
DEFINE_METHOD(JIT_HELPERS, UNSAFE_ENUM_CAST_LONG, UnsafeEnumCastLong, NoSig)
DEFINE_METHOD(JIT_HELPERS, UNSAFE_CAST_TO_STACKPTR,UnsafeCastToStackPointer, NoSig)
#endif // _DEBUG
-#ifdef FEATURE_SPAN_OF_T
DEFINE_METHOD(JIT_HELPERS, BYREF_LESSTHAN, ByRefLessThan, NoSig)
DEFINE_METHOD(JIT_HELPERS, GET_ARRAY_DATA, GetArrayData, NoSig)
-DEFINE_METHOD(JIT_HELPERS, CONTAINSREFERENCES, ContainsReferences, NoSig)
-#endif
-#ifdef FEATURE_SPAN_OF_T
DEFINE_CLASS(UNSAFE, CompilerServices, Unsafe)
DEFINE_METHOD(UNSAFE, AS_POINTER, AsPointer, NoSig)
DEFINE_METHOD(UNSAFE, SIZEOF, SizeOf, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_AS, As, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_ADD, Add, NoSig)
+DEFINE_METHOD(UNSAFE, BYREF_ADD_BYTE_OFFSET, AddByteOffset, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_ARE_SAME, AreSame, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_INIT_BLOCK_UNALIGNED, InitBlockUnaligned, NoSig)
-#endif
+DEFINE_METHOD(UNSAFE, BYREF_READ_UNALIGNED, ReadUnaligned, GM_RefByte_RetT)
+DEFINE_METHOD(UNSAFE, BYREF_WRITE_UNALIGNED, WriteUnaligned, GM_RefByte_T_RetVoid)
+DEFINE_METHOD(UNSAFE, PTR_READ_UNALIGNED, ReadUnaligned, GM_PtrVoid_RetT)
+DEFINE_METHOD(UNSAFE, PTR_WRITE_UNALIGNED, WriteUnaligned, GM_PtrVoid_T_RetVoid)
DEFINE_CLASS(INTERLOCKED, Threading, Interlocked)
DEFINE_METHOD(INTERLOCKED, COMPARE_EXCHANGE_T, CompareExchange, GM_RefT_T_T_RetT)
@@ -1215,10 +828,8 @@ DEFINE_METHOD(INTERLOCKED, COMPARE_EXCHANGE_OBJECT,CompareExchange, SM_
DEFINE_CLASS(PINNING_HELPER, CompilerServices, PinningHelper)
DEFINE_FIELD(PINNING_HELPER, M_DATA, m_data)
-#ifdef FEATURE_SPAN_OF_T
DEFINE_CLASS(ARRAY_PINNING_HELPER, CompilerServices, ArrayPinningHelper)
DEFINE_FIELD(ARRAY_PINNING_HELPER, M_ARRAY_DATA, m_arrayData)
-#endif
DEFINE_CLASS(RUNTIME_WRAPPED_EXCEPTION, CompilerServices, RuntimeWrappedException)
DEFINE_METHOD(RUNTIME_WRAPPED_EXCEPTION, OBJ_CTOR, .ctor, IM_Obj_RetVoid)
@@ -1236,26 +847,15 @@ DEFINE_METHOD(SAFE_HANDLE, RELEASE_HANDLE, ReleaseHandle,
DEFINE_METHOD(SAFE_HANDLE, DISPOSE, Dispose, IM_RetVoid)
DEFINE_METHOD(SAFE_HANDLE, DISPOSE_BOOL, Dispose, IM_Bool_RetVoid)
-#ifndef FEATURE_CORECLR
-DEFINE_CLASS(SAFE_TOKENHANDLE, SafeHandles, SafeAccessTokenHandle)
-#endif
DEFINE_CLASS(SAFE_TYPENAMEPARSER_HANDLE, System, SafeTypeNameParserHandle)
DEFINE_CLASS(SECURITY_EXCEPTION, Security, SecurityException)
-#ifdef FEATURE_REMOTING
-DEFINE_CLASS(SERVER_IDENTITY, Remoting, ServerIdentity)
-DEFINE_FIELD(SERVER_IDENTITY, SERVER_CONTEXT, _srvCtx)
-#endif // FEATURE_REMOTING
DEFINE_CLASS(SHARED_STATICS, System, SharedStatics)
DEFINE_FIELD(SHARED_STATICS, SHARED_STATICS, _sharedStatics)
-#ifdef FEATURE_REMOTING
-DEFINE_CLASS(STACK_BUILDER_SINK, Messaging, StackBuilderSink)
-DEFINE_METHOD(STACK_BUILDER_SINK, PRIVATE_PROCESS_MESSAGE,_PrivateProcessMessage, IM_IntPtr_ArrObj_Obj_RefArrObj_RetObj)
-#endif
DEFINE_CLASS_U(Diagnostics, StackFrameHelper, StackFrameHelper)
DEFINE_FIELD_U(targetThread, StackFrameHelper, targetThread)
@@ -1273,9 +873,7 @@ DEFINE_FIELD_U(rgiMethodToken, StackFrameHelper, rgiMethodToken)
DEFINE_FIELD_U(rgFilename, StackFrameHelper, rgFilename)
DEFINE_FIELD_U(rgiLineNumber, StackFrameHelper, rgiLineNumber)
DEFINE_FIELD_U(rgiColumnNumber, StackFrameHelper, rgiColumnNumber)
-#if defined(FEATURE_EXCEPTIONDISPATCHINFO)
DEFINE_FIELD_U(rgiLastFrameFromForeignExceptionStackTrace, StackFrameHelper, rgiLastFrameFromForeignExceptionStackTrace)
-#endif // defined(FEATURE_EXCEPTIONDISPATCHINFO)
DEFINE_FIELD_U(getSourceLineInfo, StackFrameHelper, getSourceLineInfo)
DEFINE_FIELD_U(iFrameCount, StackFrameHelper, iFrameCount)
@@ -1296,6 +894,8 @@ DEFINE_FIELD(INTPTR, ZERO, Zero)
// DEFINE_CLASS(UINTPTR, System, UIntPtr)
DEFINE_FIELD(UINTPTR, ZERO, Zero)
+DEFINE_CLASS(BITCONVERTER, System, BitConverter)
+DEFINE_FIELD(BITCONVERTER, ISLITTLEENDIAN, IsLittleEndian)
// Defined as element type alias
// DEFINE_CLASS(STRING, System, String)
DEFINE_FIELD(STRING, M_FIRST_CHAR, m_firstChar)
@@ -1326,21 +926,11 @@ DEFINE_METHOD(STRING_BUILDER, REPLACE_BUFFER_INTERNAL,ReplaceBufferInterna
DEFINE_METHOD(STRING_BUILDER, REPLACE_BUFFER_ANSI_INTERNAL,ReplaceBufferAnsiInternal, IM_PtrSByt_Int_RetVoid)
DEFINE_CLASS(STRONG_NAME_KEY_PAIR, Reflection, StrongNameKeyPair)
-#ifndef FEATURE_CORECLR
-DEFINE_METHOD(STRONG_NAME_KEY_PAIR, GET_KEY_PAIR, GetKeyPair, IM_RefObject_RetBool)
-#endif
-#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
DEFINE_CLASS_U(Threading, SynchronizationContext, SynchronizationContextObject)
DEFINE_FIELD_U(_props, SynchronizationContextObject, _props)
DEFINE_CLASS(SYNCHRONIZATION_CONTEXT, Threading, SynchronizationContext)
DEFINE_METHOD(SYNCHRONIZATION_CONTEXT, INVOKE_WAIT_METHOD_HELPER, InvokeWaitMethodHelper, SM_SyncCtx_ArrIntPtr_Bool_Int_RetInt)
-#endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
-
-#ifdef FEATURE_COMINTEROP_TLB_SUPPORT
-DEFINE_CLASS(TCE_EVENT_ITF_INFO, InteropTCE, EventItfInfo)
-DEFINE_METHOD(TCE_EVENT_ITF_INFO, CTOR, .ctor, IM_Str_Str_Str_Assembly_Assembly_RetVoid)
-#endif // FEATURE_COMINTEROP_TLB_SUPPORT
DEFINE_CLASS(CONTEXTCALLBACK, Threading, ContextCallback)
@@ -1351,35 +941,17 @@ DEFINE_CLASS(STACKCRAWMARK, Threading, StackCrawlMark)
DEFINE_CLASS(CROSS_CONTEXT_DELEGATE, Threading, InternalCrossContextDelegate)
DEFINE_CLASS_U(Threading, Thread, ThreadBaseObject)
-#ifdef FEATURE_REMOTING
-DEFINE_FIELD_U(m_Context, ThreadBaseObject, m_ExposedContext)
-#endif
-#ifndef FEATURE_CORECLR
-DEFINE_FIELD_U(m_ExecutionContext, ThreadBaseObject, m_ExecutionContext)
-#endif
DEFINE_FIELD_U(m_Name, ThreadBaseObject, m_Name)
DEFINE_FIELD_U(m_Delegate, ThreadBaseObject, m_Delegate)
-#ifdef FEATURE_LEAK_CULTURE_INFO
-DEFINE_FIELD_U(m_CurrentCulture, ThreadBaseObject, m_CurrentUserCulture)
-DEFINE_FIELD_U(m_CurrentUICulture, ThreadBaseObject, m_CurrentUICulture)
-#endif
DEFINE_FIELD_U(m_ThreadStartArg, ThreadBaseObject, m_ThreadStartArg)
DEFINE_FIELD_U(DONT_USE_InternalThread, ThreadBaseObject, m_InternalThread)
DEFINE_FIELD_U(m_Priority, ThreadBaseObject, m_Priority)
DEFINE_CLASS(THREAD, Threading, Thread)
-#ifndef FEATURE_LEAK_CULTURE_INFO
DEFINE_FIELD(THREAD, CULTURE, m_CurrentCulture)
DEFINE_FIELD(THREAD, UI_CULTURE, m_CurrentUICulture)
-#endif
-#ifdef FEATURE_REMOTING
-DEFINE_STATIC_PROPERTY(THREAD, CURRENT_CONTEXT, CurrentContext, Context)
-#endif
DEFINE_SET_PROPERTY(THREAD, CULTURE, CurrentCulture, CultureInfo)
DEFINE_SET_PROPERTY(THREAD, UI_CULTURE, CurrentUICulture, CultureInfo)
DEFINE_STATIC_PROPERTY(THREAD, CURRENT_THREAD, CurrentThread, Thread)
-#ifdef FEATURE_REMOTING
-DEFINE_METHOD(THREAD, COMPLETE_CROSSCONTEXTCALLBACK, CompleteCrossContextCallback, SM_CrossContextDelegate_ArrObj_RetObj)
-#endif
DEFINE_METHOD(THREAD, INTERNAL_GET_CURRENT_THREAD, InternalGetCurrentThread, SM_RetIntPtr)
DEFINE_CLASS(PARAMETERIZEDTHREADSTART, Threading, ParameterizedThreadStart)
@@ -1398,15 +970,6 @@ DEFINE_METHOD(TIMER_QUEUE, APPDOMAIN_TIMER_CALLBACK, AppDomainTimerCall
DEFINE_CLASS(TIMESPAN, System, TimeSpan)
-#ifdef FEATURE_REMOTING
-DEFINE_CLASS_U(Proxies, __TransparentProxy, TransparentProxyObject)
-DEFINE_FIELD_U(_rp, TransparentProxyObject, _rp)
-DEFINE_FIELD_U(_pMT, TransparentProxyObject, _pMT)
-DEFINE_FIELD_U(_pInterfaceMT, TransparentProxyObject, _pInterfaceMT)
-DEFINE_FIELD_U(_stub, TransparentProxyObject, _stub)
-DEFINE_FIELD_U(_stubData, TransparentProxyObject, _stubData)
-DEFINE_CLASS(TRANSPARENT_PROXY, Proxies, __TransparentProxy)
-#endif
DEFINE_CLASS(TYPE, System, Type)
DEFINE_METHOD(TYPE, GET_TYPE_FROM_HANDLE, GetTypeFromHandle, SM_RuntimeTypeHandle_RetType)
@@ -1417,20 +980,14 @@ DEFINE_CLASS(TYPE_DELEGATOR, Reflection, TypeDelegator)
DEFINE_CLASS(UNHANDLED_EVENTARGS, System, UnhandledExceptionEventArgs)
DEFINE_METHOD(UNHANDLED_EVENTARGS, CTOR, .ctor, IM_Obj_Bool_RetVoid)
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
DEFINE_CLASS(FIRSTCHANCE_EVENTARGS, ExceptionServices, FirstChanceExceptionEventArgs)
DEFINE_METHOD(FIRSTCHANCE_EVENTARGS, CTOR, .ctor, IM_Exception_RetVoid)
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
-
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
DEFINE_CLASS(ASSEMBLYLOADCONTEXT, Loader, AssemblyLoadContext)
DEFINE_METHOD(ASSEMBLYLOADCONTEXT, RESOLVE, Resolve, SM_IntPtr_AssemblyName_RetAssemblyBase)
DEFINE_METHOD(ASSEMBLYLOADCONTEXT, RESOLVEUNMANAGEDDLL, ResolveUnmanagedDll, SM_Str_IntPtr_RetIntPtr)
DEFINE_METHOD(ASSEMBLYLOADCONTEXT, RESOLVEUSINGEVENT, ResolveUsingResolvingEvent, SM_IntPtr_AssemblyName_RetAssemblyBase)
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
-
DEFINE_CLASS(LAZY, System, Lazy`1)
DEFINE_CLASS(LAZY_INITIALIZER, Threading, LazyInitializer)
@@ -1471,9 +1028,6 @@ DEFINE_METHOD(BUFFER, MEMCPY, Memcpy,
DEFINE_CLASS(WINDOWSRUNTIMEMARSHAL, WinRT, WindowsRuntimeMarshal)
#ifdef FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION
DEFINE_METHOD(WINDOWSRUNTIMEMARSHAL, GET_ACTIVATION_FACTORY_FOR_TYPE, GetActivationFactoryForType, SM_Type_RetIntPtr)
-#ifdef FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
-DEFINE_METHOD(WINDOWSRUNTIMEMARSHAL, GET_CLASS_ACTIVATOR_FOR_APPLICATION, GetClassActivatorForApplication, SM_Str_RetIntPtr)
-#endif // FEATURE_COMINTEROP_WINRT_DESKTOP_HOST
#endif // FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION
DEFINE_CLASS(IACTIVATIONFACTORY, WinRT, IActivationFactory)
@@ -1487,13 +1041,6 @@ DEFINE_METHOD(STUBHELPERS, IS_QCALL, IsQCall,
DEFINE_METHOD(STUBHELPERS, INIT_DECLARING_TYPE, InitDeclaringType, SM_IntPtr_RetVoid)
DEFINE_METHOD(STUBHELPERS, GET_NDIRECT_TARGET, GetNDirectTarget, SM_IntPtr_RetIntPtr)
DEFINE_METHOD(STUBHELPERS, GET_DELEGATE_TARGET, GetDelegateTarget, SM_Delegate_RefIntPtr_RetIntPtr)
-#ifndef FEATURE_CORECLR // CAS
-DEFINE_METHOD(STUBHELPERS, DEMAND_PERMISSION, DemandPermission, SM_IntPtr_RetVoid)
-#ifdef _TARGET_X86_
-DEFINE_METHOD(STUBHELPERS, SET_COPY_CTOR_COOKIE_CHAIN, SetCopyCtorCookieChain, SM_IntPtr_IntPtr_Int_IntPtr_RetVoid)
-DEFINE_FIELD(STUBHELPERS, COPY_CTOR_STUB_DESC, s_copyCtorStubDesc)
-#endif // _TARGET_X86_
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_COMINTEROP
DEFINE_METHOD(STUBHELPERS, GET_COM_HR_EXCEPTION_OBJECT, GetCOMHRExceptionObject, SM_Int_IntPtr_Obj_RetException)
DEFINE_METHOD(STUBHELPERS, GET_COM_HR_EXCEPTION_OBJECT_WINRT, GetCOMHRExceptionObject_WinRT, SM_Int_IntPtr_Obj_RetException)
@@ -1512,13 +1059,11 @@ DEFINE_METHOD(STUBHELPERS, GET_OUTER_INSPECTABLE, Ge
DEFINE_METHOD(STUBHELPERS, TRIGGER_EXCEPTION_SWALLOWED_MDA, TriggerExceptionSwallowedMDA, SM_Exception_IntPtr_RetException)
#endif // MDA_SUPPORTED
#endif // FEATURE_COMINTEROP
-#if defined(MDA_SUPPORTED) || (defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR))
+#if defined(MDA_SUPPORTED)
DEFINE_METHOD(STUBHELPERS, CHECK_COLLECTED_DELEGATE_MDA, CheckCollectedDelegateMDA, SM_IntPtr_RetVoid)
#endif // MDA_SUPPORTED
DEFINE_METHOD(STUBHELPERS, SET_LAST_ERROR, SetLastError, SM_RetVoid)
-#ifdef FEATURE_CORECLR
DEFINE_METHOD(STUBHELPERS, CLEAR_LAST_ERROR, ClearLastError, SM_RetVoid)
-#endif
DEFINE_METHOD(STUBHELPERS, THROW_INTEROP_PARAM_EXCEPTION, ThrowInteropParamException, SM_Int_Int_RetVoid)
DEFINE_METHOD(STUBHELPERS, ADD_TO_CLEANUP_LIST, AddToCleanupList, SM_RefCleanupWorkList_SafeHandle_RetIntPtr)
@@ -1563,12 +1108,6 @@ DEFINE_METHOD(STUBHELPERS, ARRAY_TYPE_CHECK, ArrayTypeCheck,
DEFINE_METHOD(STUBHELPERS, MULTICAST_DEBUGGER_TRACE_HELPER, MulticastDebuggerTraceHelper, SM_Obj_Int_RetVoid)
#endif
-#if defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
-DEFINE_CLASS(COPYCTORSTUBCOOKIE, StubHelpers, CopyCtorStubCookie)
-DEFINE_METHOD(COPYCTORSTUBCOOKIE, SET_DATA, SetData, IM_IntPtr_UInt_IntPtr_IntPtr_RetVoid)
-DEFINE_METHOD(COPYCTORSTUBCOOKIE, SET_NEXT, SetNext, IM_IntPtr_RetVoid)
-#endif // _TARGET_X86_ && !FEATURE_CORECLR
-
DEFINE_CLASS(ANSICHARMARSHALER, StubHelpers, AnsiCharMarshaler)
DEFINE_METHOD(ANSICHARMARSHALER, CONVERT_TO_NATIVE, ConvertToNative, SM_Char_Bool_Bool_RetByte)
DEFINE_METHOD(ANSICHARMARSHALER, CONVERT_TO_MANAGED, ConvertToManaged, SM_Byte_RetChar)
diff --git a/src/vm/mscoruefwrapper.h b/src/vm/mscoruefwrapper.h
deleted file mode 100644
index 75b540c97f..0000000000
--- a/src/vm/mscoruefwrapper.h
+++ /dev/null
@@ -1,19 +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.
-//
-
-//
-//*****************************************************************************
-// MSCorUEFWrapper.h - Wrapper for including the UEF chain manager definition
-// and the global that references it for VM usage.
-//*****************************************************************************
-
-#ifdef FEATURE_UEF_CHAINMANAGER
-
-// This is required to register our UEF callback with the UEF chain manager
-#include <mscoruef.h>
-// Global reference to IUEFManager that will be used in the VM
-extern IUEFManager * g_pUEFManager;
-
-#endif // FEATURE_UEF_CHAINMANAGER
diff --git a/src/vm/mtypes.h b/src/vm/mtypes.h
index 603409b3dc..1a14760372 100644
--- a/src/vm/mtypes.h
+++ b/src/vm/mtypes.h
@@ -56,11 +56,11 @@ DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_LPWSTR_BUFFER, WSTRBufferMarshaler,
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_LPSTR_BUFFER, CSTRBufferMarshaler, false)
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_UTF8_BUFFER, UTF8BufferMarshaler, false)
-#if defined(FEATURE_COMINTEROP) || !defined(FEATURE_CORECLR)
+#if defined(FEATURE_COMINTEROP)
// CoreCLR doesn't have any support for marshalling interface pointers.
// Not even support for fake CCWs.
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_INTERFACE, InterfaceMarshaler, true)
-#endif // defined(FEATURE_COMINTEROP) || !defined(FEATURE_CORECLR)
+#endif // defined(FEATURE_COMINTEROP)
#ifdef FEATURE_COMINTEROP
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_SAFEARRAY, SafeArrayMarshaler, false)
@@ -89,9 +89,6 @@ DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_VALUECLASS, ValueClassMa
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_REFERENCECUSTOMMARSHALER, ReferenceCustomMarshaler, false)
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_ARGITERATOR, ArgIteratorMarshaler, false)
-#ifndef FEATURE_CORECLR
-DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_BLITTABLEVALUECLASSWITHCOPYCTOR, BlittableValueClassWithCopyCtorMarshaler, false)
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_COMINTEROP
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_OBJECT, ObjectMarshaler, false)
diff --git a/src/vm/multicorejit.cpp b/src/vm/multicorejit.cpp
index 7660fd1895..4ad5447950 100644
--- a/src/vm/multicorejit.cpp
+++ b/src/vm/multicorejit.cpp
@@ -33,49 +33,6 @@
const wchar_t * AppxProfile = W("Application.Profile");
-#if defined(FEATURE_APPX_BINDER)
-
-//static
-bool MulticoreJitManager::IsLoadOkay(Module * pModule)
-{
- CONTRACTL
- {
- THROWS;
- SO_INTOLERANT;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (pModule->GetAssembly()->GetManifestFile()->IsWindowsRuntime())
- {
- PEFile * pFile = pModule->GetFile();
-
- ICLRPrivAssembly * pHostAsm = pFile->GetHostAssembly();
-
- // Allow first party WinMD to load in multicore JIT background thread
- if (pHostAsm != NULL)
- {
- BOOL shared = FALSE;
-
- if (SUCCEEDED(pHostAsm->IsShareable(& shared)))
- {
- if (shared)
- {
- LPCUTF8 simpleName = pModule->GetSimpleName();
-
- if (IsWindowsNamespace(simpleName))
- {
- return true;
- }
- }
- }
- }
- }
-
- return false;
-}
-
-#endif
void MulticoreJitFireEtw(const wchar_t * pAction, const wchar_t * pTarget, int p1, int p2, int p3)
@@ -327,14 +284,6 @@ bool ModuleVersion::GetModuleVersion(Module * pModule)
}
// If the load context is LOADFROM, store it in the flags.
-#ifdef FEATURE_FUSION
- Assembly * pAssembly = pModule->GetAssembly();
- LOADCTX_TYPE loadCtx = pAssembly->GetManifestFile()->GetLoadContext();
- if(LOADCTX_TYPE_LOADFROM == loadCtx)
- {
- versionFlags |= VERSIONFLAG_LOADCTX_LOADFROM;
- }
-#endif
}
EX_CATCH
{
@@ -356,12 +305,8 @@ ModuleRecord::ModuleRecord(unsigned lenName, unsigned lenAsmName)
wLoadLevel = 0;
// Extra data
lenModuleName = (unsigned short) lenName;
-#if defined(FEATURE_CORECLR)
lenAssemblyName = (unsigned short) lenAsmName;
recordID += RoundUp(lenModuleName) + RoundUp(lenAssemblyName);
-#else
- recordID += RoundUp(lenModuleName);
-#endif
}
@@ -375,7 +320,6 @@ bool RecorderModuleInfo::SetModule(Module * pMod)
unsigned lenModuleName = (unsigned) strlen(pModuleName);
simpleName.Set((const BYTE *) pModuleName, lenModuleName); // SBuffer::Set copies over name
-#if defined(FEATURE_CORECLR)
SString sAssemblyName;
StackScratchBuffer scratch;
pMod->GetAssembly()->GetManifestFile()->GetDisplayName(sAssemblyName);
@@ -383,17 +327,7 @@ bool RecorderModuleInfo::SetModule(Module * pMod)
LPCUTF8 pAssemblyName = sAssemblyName.GetUTF8(scratch);
unsigned lenAssemblyName = sAssemblyName.GetCount();
assemblyName.Set((const BYTE *) pAssemblyName, lenAssemblyName);
-#endif
-
-#if defined(FEATURE_APPX_BINDER)
-
- // Allow certain modules to load on background thread
- if (AppX::IsAppXProcess() && MulticoreJitManager::IsLoadOkay(pMod))
- {
- flags |= FLAG_LOADOKAY;
- }
-#endif
return moduleVersion.GetModuleVersion(pMod);
}
@@ -422,12 +356,8 @@ HRESULT MulticoreJitRecorder::WriteModuleRecord(IStream * pStream, const Recorde
const void * pModuleName = module.simpleName;
unsigned lenModuleName = module.simpleName.GetSize();
-#if defined(FEATURE_CORECLR)
const void * pAssemblyName = module.assemblyName;
unsigned lenAssemblyName = module.assemblyName.GetSize();
-#else
- unsigned lenAssemblyName = 0;
-#endif
ModuleRecord mod(lenModuleName, lenAssemblyName);
@@ -442,12 +372,10 @@ HRESULT MulticoreJitRecorder::WriteModuleRecord(IStream * pStream, const Recorde
{
hr = WriteString(pModuleName, lenModuleName, pStream);
-#if defined(FEATURE_CORECLR)
if (SUCCEEDED(hr))
{
hr = WriteString(pAssemblyName, lenAssemblyName, pStream);
}
-#endif
}
return hr;
@@ -719,9 +647,6 @@ HRESULT MulticoreJitModuleEnumerator::EnumerateLoadedModules(AppDomain * pDomain
while (appIt.Next(pDomainAssembly.This()) && SUCCEEDED(hr))
{
-#if !defined(FEATURE_CORECLR)
- if (! pDomainAssembly->IsSystem())
-#endif
{
hr = HandleAssembly(pDomainAssembly);
}
@@ -731,60 +656,6 @@ HRESULT MulticoreJitModuleEnumerator::EnumerateLoadedModules(AppDomain * pDomain
}
-#if defined(FEATURE_APPX_BINDER)
-// ProfileName = ProcessName_CoreAppId.Profile ; for server process, always use it for output
-// ProcessName.Profile
-
-void AppendAppxProfileName(SString & name)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- } CONTRACTL_END;
-
- {
- WCHAR wszProcessName[_MAX_PATH];
-
- if (WszGetModuleFileName(NULL, wszProcessName, _MAX_PATH) != 0)
- {
- WCHAR * pNameOnly = wcsrchr(wszProcessName, W('\\'));
-
- if (pNameOnly == NULL)
- {
- pNameOnly = wszProcessName;
- }
- else
- {
- pNameOnly ++;
- }
-
- WCHAR * pExt = wcsrchr(pNameOnly, W('.')); // last .
-
- if (pExt != NULL)
- {
- * pExt = 0;
- }
-
- // Use process name only
- name.Append(pNameOnly);
- name.Append(W("_"));
- }
- }
-
- LPCWSTR pAppId = NULL;
- if (SUCCEEDED(AppX::GetApplicationId(pAppId)))
- {
- name.Append(pAppId);
- name.Append(W(".Profile"));
-
- return;
- }
-
- // default name
- name.Append(AppxProfile);
-}
-#endif
// static: single instace within a process
@@ -811,25 +682,6 @@ MulticoreJitRecorder::WriteMulticoreJitProfiler(PTP_CALLBACK_INSTANCE pInstance,
if (pRecorder != NULL)
{
-#if defined(FEATURE_APPX_BINDER)
- if (pRecorder->m_fAppxMode)
- {
- const wchar_t * pOutputDir = NULL;
-
- HRESULT hr = Clr::Util::GetLocalAppDataDirectory(&pOutputDir);
-
- if (SUCCEEDED(hr))
- {
- pRecorder->m_fullFileName = pOutputDir;
- pRecorder->m_fullFileName.Append(W("\\"));
-
- AppendAppxProfileName(pRecorder->m_fullFileName);
-
- pRecorder->StopProfile(false);
- }
- }
- else
-#endif
{
pRecorder->StopProfile(false);
}
@@ -854,9 +706,6 @@ void MulticoreJitRecorder::PreRecordFirstMethod()
// When running under Appx or CoreCLR for K, AppDomain is normally not shut down properly (CLR in hybrid case, or Alt-F4 shutdown),
// So we only allow writing out after profileWriteTimeout seconds
-#if !defined(FEATURE_CORECLR)
- if (m_fAppxMode)
-#endif
{
// Get the timeout in seconds.
int profileWriteTimeout = (int)CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MultiCoreJitProfileWriteDelay);
@@ -1061,11 +910,7 @@ HRESULT MulticoreJitRecorder::StartProfile(const wchar_t * pRoot, const wchar_t
NewHolder<MulticoreJitProfilePlayer> player(new (nothrow) MulticoreJitProfilePlayer(
m_pDomain,
-#if defined(FEATURE_CORECLR)
m_pBinderContext,
-#else
- NULL,
-#endif
nSession,
m_fAppxMode));
@@ -1235,11 +1080,7 @@ void MulticoreJitManager::StartProfile(AppDomain * pDomain, ICLRPrivBinder *pBin
{
MulticoreJitRecorder * pRecorder = new (nothrow) MulticoreJitRecorder(
pDomain,
-#if defined(FEATURE_CORECLR)
pBinderContext,
-#else
- NULL,
-#endif
m_fAppxMode);
if (pRecorder != NULL)
@@ -1386,48 +1227,6 @@ void MulticoreJitManager::AutoStartProfile(AppDomain * pDomain)
}
}
-#if defined(FEATURE_APPX_BINDER)
-
-// Called from CorHost2::ExecuteMain
-void MulticoreJitManager::AutoStartProfileAppx(AppDomain * pDomain)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- if (InterlockedCompareExchange(& m_fAutoStartCalled, SETPROFILEROOTCALLED, 0) == 0) // Only allow the first call
- {
- WCHAR wzFilePath[_MAX_PATH];
-
- UINT32 cchFilePath = NumItems(wzFilePath);
-
- SString profileName;
-
- // Try to find ProcessName_AppId.Profile
- AppendAppxProfileName(profileName);
-
- // Search for Application.Profile within the package
- HRESULT hr = AppX::FindFileInCurrentPackage(profileName, &cchFilePath, wzFilePath);
-
- if (SUCCEEDED(hr))
- {
- m_fAppxMode = true;
- SetProfileRoot(pDomain, W("")); // Fake a SetProfileRoot call
- StartProfile(pDomain, NULL, wzFilePath);
- }
- else
- {
- _FireEtwMulticoreJit(W("AUTOSTARTPROFILEAPPX"), profileName, hr, 0, 0);
- }
- }
-}
-
-#endif
// Constructor
@@ -1473,17 +1272,6 @@ void MulticoreJitManager::RecordModuleLoad(Module * pModule, FileLoadLevel loadL
STANDARD_VM_CONTRACT;
-#if defined(FEATURE_APPX_BINDER) && !defined(FEATURE_CORECLR)
- // When running under Appx, allow framework assembly / first party winmd to load
- // load-level change not allowed in the background thread, unless for resource DLL (loaded for exception throwing), but this could still happen.
- _ASSERTE(! GetThread()->HasThreadStateNC(Thread::TSNC_CallingManagedCodeDisabled) || ModuleHasNoCode(pModule)
- || m_fAppxMode && IsLoadOkay(pModule));
-
-#elif !defined(FEATURE_CORECLR)
-
- _ASSERTE(! GetThread()->HasThreadStateNC(Thread::TSNC_CallingManagedCodeDisabled) || ModuleHasNoCode(pModule));
-
-#endif
if (m_fRecorderActive)
{
diff --git a/src/vm/multicorejit.h b/src/vm/multicorejit.h
index 19458944bb..b7a0951ee1 100644
--- a/src/vm/multicorejit.h
+++ b/src/vm/multicorejit.h
@@ -200,12 +200,6 @@ public:
return m_fSetProfileRootCalled == 0;
}
-#if defined(FEATURE_APPX_BINDER)
-
- // Check for file appx.prof to automatically start multicore JIT
- void AutoStartProfileAppx(AppDomain * pDomain);
-
-#endif
// Check for environment variable to automatically start multicore JIT
void AutoStartProfile(AppDomain * pDomain);
@@ -255,11 +249,6 @@ public:
static bool ModuleHasNoCode(Module * pModule);
-#if defined(FEATURE_APPX_BINDER)
-
- static bool IsLoadOkay(Module * pModule);
-
-#endif
};
diff --git a/src/vm/multicorejitimpl.h b/src/vm/multicorejitimpl.h
index 58a9df7827..9d20adceef 100644
--- a/src/vm/multicorejitimpl.h
+++ b/src/vm/multicorejitimpl.h
@@ -179,9 +179,7 @@ public:
unsigned short flags;
unsigned short wLoadLevel;
unsigned short lenModuleName;
-#if defined(FEATURE_CORECLR)
unsigned short lenAssemblyName;
-#endif
ModuleRecord(unsigned lenName = 0, unsigned lenAssemblyName = 0);
@@ -201,7 +199,6 @@ public:
return (const char *) (this + 1); // after this record
}
-#if defined(FEATURE_CORECLR)
unsigned AssemblyNameLen() const
{
LIMITED_METHOD_CONTRACT;
@@ -213,7 +210,6 @@ public:
{
return GetModuleName() + RoundUp(lenModuleName); // after the module name
}
-#endif
void SetLoadLevel(FileLoadLevel loadLevel)
{
@@ -250,9 +246,7 @@ friend class MulticoreJitRecorder;
private:
ADID m_DomainID;
-#if defined(FEATURE_CORECLR)
ICLRPrivBinder * m_pBinderContext;
-#endif
LONG m_nMySession;
unsigned m_nStartTime;
BYTE * m_pFileBuffer;
@@ -300,9 +294,7 @@ private:
HRESULT ReadCheckFile(const wchar_t * pFileName);
-#if defined(FEATURE_CORECLR)
DomainAssembly * LoadAssembly(SString & assemblyName);
-#endif
public:
@@ -344,9 +336,7 @@ class MulticoreJitRecorder
{
private:
AppDomain * m_pDomain; // AutoStartProfile could be called from SystemDomain
-#if defined(FEATURE_CORECLR)
ICLRPrivBinder * m_pBinderContext;
-#endif
SString m_fullFileName;
MulticoreJitPlayerStat & m_stats;
@@ -393,9 +383,7 @@ public:
LIMITED_METHOD_CONTRACT;
m_pDomain = pDomain;
-#if defined(FEATURE_CORECLR)
m_pBinderContext = pBinderContext;
-#endif
m_JitInfoCount = 0;
m_ModuleCount = 0;
m_ModuleDepCount = 0;
@@ -404,10 +392,6 @@ public:
m_fAborted = false;
m_fAppxMode = fAppxMode;
-#if defined(FEATURE_APPX_BINDER)
-
- s_delayedWriteTimer = NULL;
-#endif
m_stats.Clear();
}
diff --git a/src/vm/multicorejitplayer.cpp b/src/vm/multicorejitplayer.cpp
index 7d13bbc462..69868578d9 100644
--- a/src/vm/multicorejitplayer.cpp
+++ b/src/vm/multicorejitplayer.cpp
@@ -373,9 +373,7 @@ MulticoreJitProfilePlayer::MulticoreJitProfilePlayer(AppDomain * pDomain, ICLRPr
LIMITED_METHOD_CONTRACT;
m_DomainID = pDomain->GetId();
-#if defined(FEATURE_CORECLR)
m_pBinderContext = pBinderContext;
-#endif
m_nMySession = nSession;
m_moduleCount = 0;
m_headerModuleCount = 0;
@@ -464,12 +462,10 @@ bool MulticoreJitManager::IsSupportedModule(Module * pModule, bool fMethodJit, b
return false;
}
-#if defined(FEATURE_CORECLR)
if (pFile->GetPath().IsEmpty()) // Ignore in-memory modules
{
return false;
}
-#endif
if (! fMethodJit)
@@ -482,29 +478,9 @@ bool MulticoreJitManager::IsSupportedModule(Module * pModule, bool fMethodJit, b
Assembly * pAssembly = pModule->GetAssembly();
-#ifdef FEATURE_FUSION
-
- LOADCTX_TYPE context = pAssembly->GetManifestFile()->GetLoadContext();
-
-#if defined(FEATURE_APPX_BINDER)
-
- if (fAppx)
- {
- if (context == LOADCTX_TYPE_HOSTED)
- {
- return true;
- }
- }
-
-#endif
-
- return ((context == LOADCTX_TYPE_DEFAULT) || (context == LOADCTX_TYPE_LOADFROM));
-
-#else
return true;
-#endif
}
@@ -550,10 +526,8 @@ bool MulticoreJitProfilePlayer::CompileMethodDesc(Module * pModule, MethodDesc *
m_stats.m_nTryCompiling ++;
-#if defined(FEATURE_CORECLR)
// Reset the flag to allow managed code to be called in multicore JIT background thread from this routine
ThreadStateNCStackHolder holder(-1, Thread::TSNC_CallingManagedCodeDisabled);
-#endif
// MakeJitWorker calls back to MulticoreJitCodeStorage::StoreMethodCode under MethodDesc lock
pMD->MakeJitWorker(& header, CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_MCJIT_BACKGROUND));
@@ -886,7 +860,6 @@ bool MulticoreJitProfilePlayer::HandleModuleDependency(unsigned jitInfo)
PlayerModuleInfo & mod = m_pModules[moduleTo];
-#if defined(FEATURE_CORECLR)
// Load the module if necessary.
if (!mod.m_pModule)
{
@@ -927,7 +900,6 @@ bool MulticoreJitProfilePlayer::HandleModuleDependency(unsigned jitInfo)
}
}
}
-#endif
if (mod.UpdateNeedLevel((FileLoadLevel) level))
{
@@ -941,7 +913,6 @@ bool MulticoreJitProfilePlayer::HandleModuleDependency(unsigned jitInfo)
return true;
}
-#if defined(FEATURE_CORECLR)
DomainAssembly * MulticoreJitProfilePlayer::LoadAssembly(SString & assemblyName)
{
STANDARD_VM_CONTRACT;
@@ -992,7 +963,6 @@ DomainAssembly * MulticoreJitProfilePlayer::LoadAssembly(SString & assemblyName)
return pDomainAssembly;
}
-#endif
inline bool MethodJifInfo(unsigned inst)
@@ -1052,17 +1022,6 @@ HRESULT MulticoreJitProfilePlayer::HandleMethodRecord(unsigned * buffer, int cou
}
else
{
-#if !defined(FEATURE_CORECLR)
- if (m_nBlockingCount != 0)
- {
- if (! GroupWaitForModuleLoad(m_stats.m_nTotalMethod + pos)) // wait for blocking modules
- {
- goto Abort;
- }
-
- _ASSERTE(m_nBlockingCount == 0);
- }
-#endif
// To reduce contention with foreground thread, walk backward within the group of methods Jittable methods, not broken apart by dependency
{
@@ -1093,11 +1052,7 @@ HRESULT MulticoreJitProfilePlayer::HandleMethodRecord(unsigned * buffer, int cou
PlayerModuleInfo & mod = m_pModules[inst >> 24];
-#if defined(FEATURE_CORECLR)
_ASSERTE(mod.IsModuleLoaded());
-#else
- _ASSERTE(mod.IsModuleLoaded() && ! mod.IsLowerLevel());
-#endif
if (mod.m_enableJit)
{
@@ -1313,9 +1268,7 @@ HRESULT MulticoreJitProfilePlayer::PlayProfile()
const ModuleRecord * pRec = (const ModuleRecord * ) pBuffer;
if (((unsigned)(pRec->lenModuleName
-#if defined(FEATURE_CORECLR)
+ pRec->lenAssemblyName
-#endif
) > (rcdLen - sizeof(ModuleRecord))) ||
(m_moduleCount >= m_headerModuleCount))
{
diff --git a/src/vm/namespace.h b/src/vm/namespace.h
index e679fb5fe4..eff1cc04a2 100644
--- a/src/vm/namespace.h
+++ b/src/vm/namespace.h
@@ -43,10 +43,8 @@
#define g_PermissionsNS g_SecurityNS ".Permissions"
#define g_PrincipalNS g_SecurityNS ".Principal"
#define g_PolicyNS g_SecurityNS ".Policy"
-#ifdef FEATURE_X509
#define g_CryptographyNS g_SecurityNS ".Cryptography"
#define g_X509NS g_CryptographyNS ".X509Certificates"
-#endif // FEATURE_X509
#define g_SerializationNS g_RuntimeNS ".Serialization"
#define g_RemotingNS g_RuntimeNS ".Remoting"
@@ -74,10 +72,6 @@
#define g_WindowsFoundationDiagNS "Windows.Foundation.Diagnostics"
-#if defined(FEATURE_CORRUPTING_EXCEPTIONS) || defined(FEATURE_EXCEPTION_NOTIFICATIONS)
#define g_ExceptionServicesNS g_RuntimeNS ".ExceptionServices"
-#endif // defined(FEATURE_CORRUPTING_EXCEPTION) || defined(FEATURE_EXCEPTION_NOTIFICATIONS)
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
#define g_LoaderNS g_RuntimeNS ".Loader"
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
diff --git a/src/vm/nativeoverlapped.cpp b/src/vm/nativeoverlapped.cpp
index d0afbb648a..3a77c52dae 100644
--- a/src/vm/nativeoverlapped.cpp
+++ b/src/vm/nativeoverlapped.cpp
@@ -54,20 +54,12 @@ FCIMPL3(void, CheckVMForIOPacket, LPOVERLAPPED* lpOverlapped, DWORD* errorCode,
OVERLAPPEDDATAREF overlapped = ObjectToOVERLAPPEDDATAREF(OverlappedDataObject::GetOverlapped(*lpOverlapped));
_ASSERTE(overlapped->GetAppDomainId() == adid);
- _ASSERTE(CLRIoCompletionHosted() == FALSE);
if(overlapped->m_iocb == NULL)
{
// no user delegate to callback
_ASSERTE((overlapped->m_iocbHelper == NULL) || !"This is benign, but should be optimized");
-#ifndef FEATURE_CORECLR
- if (g_pAsyncFileStream_AsyncResultClass)
- {
- SetAsyncResultProperties(overlapped, *errorCode, *numBytes);
- }
- else
-#endif // !FEATURE_CORECLR
{
//We're not initialized yet, go back to the Vm, and process the packet there.
ThreadpoolMgr::StoreOverlappedInfoInThread(pThread, *errorCode, *numBytes, key, *lpOverlapped);
@@ -163,21 +155,6 @@ FCIMPL1(void*, AllocateNativeOverlapped, OverlappedDataObject* overlappedUNSAFE)
handle = GetAppDomain()->CreateTypedHandle(overlapped, HNDTYPE_ASYNCPINNED);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- // CoreCLR does not have IO completion hosted
- if (CLRIoCompletionHosted())
- {
- _ASSERTE(CorHost2::GetHostIoCompletionManager());
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = CorHost2::GetHostIoCompletionManager()->InitializeHostOverlapped(&overlapped->Internal);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- {
- COMPlusThrowHR(hr);
- }
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
handle.SuppressRelease();
overlapped->m_pinSelf = handle;
diff --git a/src/vm/ngenoptout.cpp b/src/vm/ngenoptout.cpp
deleted file mode 100644
index b192c4a5f0..0000000000
--- a/src/vm/ngenoptout.cpp
+++ /dev/null
@@ -1,37 +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.
-// ngenoptout.cpp
-//
-
-//
-//
-// Contains functionality to reject native images at runtime
-
-
-#include "common.h"
-#ifndef FEATURE_CORECLR
-#include "ngenoptout.h"
-#include "assemblynamelist.h"
-
-AssemblyNameList g_NgenOptoutList;
-
-BOOL IsNativeImageOptedOut(IAssemblyName* pName)
-{
- WRAPPER_NO_CONTRACT
- return g_NgenOptoutList.Lookup(pName) != NULL;
-}
-
-void AddNativeImageOptOut(IAssemblyName* pName)
-{
- WRAPPER_NO_CONTRACT
- pName->AddRef();
- g_NgenOptoutList.Add(pName);
-}
-// HRESULT
-HRESULT RuntimeIsNativeImageOptedOut(IAssemblyName* pName)
-{
- WRAPPER_NO_CONTRACT
- return IsNativeImageOptedOut(pName) ? S_OK :S_FALSE;
-}
-#endif // FEATURE_CORECLR
diff --git a/src/vm/ngenoptout.h b/src/vm/ngenoptout.h
deleted file mode 100644
index dbcc9b1f90..0000000000
--- a/src/vm/ngenoptout.h
+++ /dev/null
@@ -1,34 +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.
-// ngenoptout.h
-//
-
-//
-//
-// Contains functionality to reject native images at runtime
-
-
-#ifndef NGENOPTOUT_H
-#define NGENOPTOUT_H
-
-#include "assemblynamesconfigfactory.h"
-
-// throwing
-BOOL IsNativeImageOptedOut(IAssemblyName* pName);
-void AddNativeImageOptOut(IAssemblyName* pName);
-
-// HRESULT
-HRESULT RuntimeIsNativeImageOptedOut(IAssemblyName* pName);
-
-
-class NativeImageOptOutConfigFactory : public AssemblyNamesConfigFactory
-{
- virtual void AddAssemblyName(IAssemblyName* pName)
- {
- WRAPPER_NO_CONTRACT;
- AddNativeImageOptOut(pName);
- }
-};
-
-#endif // NGENOPTOUT_H
diff --git a/src/vm/object.cpp b/src/vm/object.cpp
index b219eb9e50..1725ef7db4 100644
--- a/src/vm/object.cpp
+++ b/src/vm/object.cpp
@@ -18,20 +18,9 @@
#include "excep.h"
#include "eeconfig.h"
#include "gcheaputilities.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "field.h"
-#include "gcscan.h"
#include "argdestination.h"
-#ifdef FEATURE_COMPRESSEDSTACK
-void* CompressedStackObject::GetUnmanagedCompressedStack()
-{
- LIMITED_METHOD_CONTRACT;
- return ((m_compressedStackHandle != NULL)?m_compressedStackHandle->GetHandle():NULL);
-}
-#endif // FEATURE_COMPRESSEDSTACK
SVAL_IMPL(INT32, ArrayBase, s_arrayBoundsZero);
@@ -165,13 +154,6 @@ MethodTable *Object::GetTrueMethodTable()
MethodTable *mt = GetMethodTable();
-#ifdef FEATURE_REMOTING
- if(mt->IsTransparentProxy())
- {
- mt = ((TransparentProxyObject *)this)->GetMethodTableBeingProxied();
- }
- _ASSERTE(!mt->IsTransparentProxy());
-#endif
RETURN mt;
}
@@ -1390,12 +1372,6 @@ void Object::ValidateHeap(Object *from, BOOL bDeep)
//special case:thread object is allowed to hold a context belonging to current domain
if (from->GetGCSafeMethodTable() == g_pThreadClass &&
(
-#ifdef FEATURE_REMOTING
- this == OBJECTREFToObject(((ThreadBaseObject *)from)->m_ExposedContext) ||
-#endif
-#ifndef FEATURE_CORECLR
- this == OBJECTREFToObject(((ThreadBaseObject *)from)->m_ExecutionContext) ||
-#endif
false))
{
if (((ThreadBaseObject *)from)->m_InternalThread)
@@ -1737,9 +1713,10 @@ VOID Object::ValidateInner(BOOL bDeep, BOOL bVerifyNextHeader, BOOL bVerifySyncB
AVInRuntimeImplOkayHolder avOk;
MethodTable *pMT = GetGCSafeMethodTable();
+
lastTest = 1;
- CHECK_AND_TEAR_DOWN(pMT->Validate());
+ CHECK_AND_TEAR_DOWN(pMT && pMT->Validate());
lastTest = 2;
bool noRangeChecks =
@@ -1749,7 +1726,7 @@ VOID Object::ValidateInner(BOOL bDeep, BOOL bVerifyNextHeader, BOOL bVerifySyncB
BOOL bSmallObjectHeapPtr = FALSE, bLargeObjectHeapPtr = FALSE;
if (!noRangeChecks)
{
- bSmallObjectHeapPtr = GCHeapUtilities::GetGCHeap()->IsHeapPointer(this, TRUE);
+ bSmallObjectHeapPtr = GCHeapUtilities::GetGCHeap()->IsHeapPointer(this, true);
if (!bSmallObjectHeapPtr)
bLargeObjectHeapPtr = GCHeapUtilities::GetGCHeap()->IsHeapPointer(this);
@@ -1795,12 +1772,13 @@ VOID Object::ValidateInner(BOOL bDeep, BOOL bVerifyNextHeader, BOOL bVerifySyncB
lastTest = 7;
+ _ASSERTE(GCHeapUtilities::IsGCHeapInitialized());
// try to validate next object's header
if (bDeep
&& bVerifyNextHeader
- && GCScan::GetGcRuntimeStructuresValid ()
+ && GCHeapUtilities::GetGCHeap()->RuntimeStructuresValid()
//NextObj could be very slow if concurrent GC is going on
- && !(GCHeapUtilities::IsGCHeapInitialized() && GCHeapUtilities::GetGCHeap ()->IsConcurrentGCInProgress ()))
+ && !GCHeapUtilities::GetGCHeap ()->IsConcurrentGCInProgress ())
{
Object * nextObj = GCHeapUtilities::GetGCHeap ()->NextObj (this);
if ((nextObj != NULL) &&
diff --git a/src/vm/object.h b/src/vm/object.h
index cb117898a1..fad5f74f39 100644
--- a/src/vm/object.h
+++ b/src/vm/object.h
@@ -226,13 +226,8 @@ class Object
// advance to the true method table or class.
BOOL IsTransparentProxy()
{
-#ifdef FEATURE_REMOTING
- WRAPPER_NO_CONTRACT;
- return( GetMethodTable()->IsTransparentProxy() );
-#else
LIMITED_METHOD_CONTRACT;
return FALSE;
-#endif
}
#define MARKED_BIT 0x1
@@ -1273,10 +1268,6 @@ inline STRINGREF* StringObject::GetEmptyStringRefPtr() {
// RuntimeMethodInfo, and RtFieldInfo.
class BaseObjectWithCachedData : public Object
{
-#ifdef FEATURE_REMOTING
- protected:
- OBJECTREF m_CachedData;
-#endif //FEATURE_REMOTING
};
// This is the Class version of the Reflection object.
@@ -1293,9 +1284,6 @@ protected:
OBJECTREF m_keepalive;
OBJECTREF m_cache;
TypeHandle m_typeHandle;
-#ifdef FEATURE_APPX
- UINT32 m_invocationFlags;
-#endif
#ifdef _DEBUG
void TypeCheck()
@@ -1508,10 +1496,6 @@ class PermissionListSetObject: public Object
private:
OBJECTREF _firstPermSetTriple;
OBJECTREF _permSetTriples;
-#ifdef FEATURE_COMPRESSEDSTACK
- OBJECTREF _zoneList;
- OBJECTREF _originList;
-#endif // FEATURE_COMPRESSEDSTACK
public:
BOOL IsEmpty()
@@ -1519,10 +1503,6 @@ public:
LIMITED_METHOD_CONTRACT;
return (_firstPermSetTriple == NULL &&
_permSetTriples == NULL
-#ifdef FEATURE_COMPRESSEDSTACK
- && _zoneList == NULL &&
- _originList == NULL
-#endif // FEATURE_COMPRESSEDSTACK
);
}
};
@@ -1532,74 +1512,8 @@ typedef REF<PermissionListSetObject> PERMISSIONLISTSETREF;
#else
typedef PermissionListSetObject* PERMISSIONLISTSETREF;
#endif
-#ifdef FEATURE_COMPRESSEDSTACK
-class CompressedStackObject: public Object
-{
- friend class MscorlibBinder;
-
-private:
- // These field are also defined in the managed representation. (CompressedStack.cs)If you
- // add or change these field you must also change the managed code so that
- // it matches these. This is necessary so that the object is the proper
- // size.
- PERMISSIONLISTSETREF m_pls;
- SAFEHANDLEREF m_compressedStackHandle;
-
-public:
- void* GetUnmanagedCompressedStack();
- BOOL IsEmptyPLS()
- {
- LIMITED_METHOD_CONTRACT;
- return (m_pls == NULL || m_pls->IsEmpty());
- }
-};
-
-#ifdef USE_CHECKED_OBJECTREFS
-typedef REF<CompressedStackObject> COMPRESSEDSTACKREF;
-#else
-typedef CompressedStackObject* COMPRESSEDSTACKREF;
-#endif
-#endif // #ifdef FEATURE_COMPRESSEDSTACK
-#if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
-class SecurityContextObject: public Object
-{
- friend class MscorlibBinder;
-
-private:
-
- // These field are also defined in the managed representation. (SecurityContext.cs)If you
- // add or change these field you must also change the managed code so that
- // it matches these. This is necessary so that the object is the proper
- // size.
-
- OBJECTREF _executionContext;
-#ifdef FEATURE_IMPERSONATION
- OBJECTREF _windowsIdentity;
-#endif // FEATURE_IMPERSONATION
-#ifdef FEATURE_COMPRESSEDSTACK
- COMPRESSEDSTACKREF _compressedStack;
-#endif // FEATURE_COMPRESSEDSTACK
- INT32 _disableFlow;
- CLR_BOOL _isNewCapture;
-public:
-#ifdef FEATURE_COMPRESSEDSTACK
- COMPRESSEDSTACKREF GetCompressedStack()
- {
- LIMITED_METHOD_CONTRACT;
- return _compressedStack;
- }
-#endif // #ifdef FEATURE_COMPRESSEDSTACK
-};
-#ifdef USE_CHECKED_OBJECTREFS
-typedef REF<SecurityContextObject> SECURITYCONTEXTREF;
-#else
-typedef SecurityContextObject* SECURITYCONTEXTREF;
-#endif
-#endif // #if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
-
-#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
#define SYNCCTXPROPS_REQUIRESWAITNOTIFICATION 0x1 // Keep in sync with SynchronizationContext.cs SynchronizationContextFlags
class ThreadBaseObject;
class SynchronizationContextObject: public Object
@@ -1620,210 +1534,21 @@ public:
return FALSE;
}
};
-#endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
-#ifdef FEATURE_REMOTING
-class CallContextRemotingDataObject : public Object
-{
-private:
- // These field are also defined in the managed representation. (SecurityContext.cs)If you
- // add or change these field you must also change the managed code so that
- // it matches these. This is necessary so that the object is the proper
- // size.
- OBJECTREF _logicalCallID;
-public:
- OBJECTREF GetLogicalCallID()
- {
- LIMITED_METHOD_CONTRACT;
- return _logicalCallID;
- }
-};
-class CallContextSecurityDataObject : public Object
-{
-private:
- // These field are also defined in the managed representation. (SecurityContext.cs)If you
- // add or change these field you must also change the managed code so that
- // it matches these. This is necessary so that the object is the proper
- // size.
- OBJECTREF _principal;
-public:
- OBJECTREF GetPrincipal()
- {
- LIMITED_METHOD_CONTRACT;
- return _principal;
- }
-
- void SetPrincipal(OBJECTREF ref)
- {
- WRAPPER_NO_CONTRACT;
- SetObjectReferenceUnchecked(&_principal, ref);
- }
-};
-
-#ifdef USE_CHECKED_OBJECTREFS
-typedef REF<CallContextSecurityDataObject> CCSECURITYDATAREF;
-typedef REF<CallContextRemotingDataObject> CCREMOTINGDATAREF;
-#else
-typedef CallContextSecurityDataObject* CCSECURITYDATAREF;
-typedef CallContextRemotingDataObject* CCREMOTINGDATAREF;
-#endif
-
-class LogicalCallContextObject : public Object
-{
- friend class MscorlibBinder;
-
- // These field are also defined in the managed representation. (CallContext.cs) If you
- // add or change these field you must also change the managed code so that
- // it matches these. This is necessary so that the object is the proper
- // size.
-private :
- OBJECTREF m_Datastore;
- CCREMOTINGDATAREF m_RemotingData;
- CCSECURITYDATAREF m_SecurityData;
- OBJECTREF m_HostContext;
- OBJECTREF _sendHeaders;
- OBJECTREF _recvHeaders;
- CLR_BOOL m_IsCorrelationMgr;
-
-public:
- CCSECURITYDATAREF GetSecurityData()
- {
- LIMITED_METHOD_CONTRACT;
- return m_SecurityData;
- }
-
- // This is an unmanaged equivalent of System.Runtime.Remoting.Messaging.LogicalCallContext.HasInfo
- BOOL ContainsDataForSerialization()
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
- return (ContainsNonSecurityDataForSerialization() ||
- (m_SecurityData != NULL && m_SecurityData->GetPrincipal() != NULL));
- }
-
- BOOL ContainsNonSecurityDataForSerialization()
- {
- LIMITED_METHOD_CONTRACT;
-
- // m_Datastore may contain 0 items even if it's non-NULL in which case it does
- // not really contain any useful data for serialization and this function could
- // return FALSE. However we don't waste time trying to detect this case - it will
- // be reset to NULL the first time a call is made due to how LogicalCallContext's
- // ISerializable implementation works.
- return (m_Datastore != NULL ||
- (m_RemotingData != NULL && m_RemotingData->GetLogicalCallID() != NULL) ||
- m_HostContext != NULL);
- }
-};
-
-#ifdef USE_CHECKED_OBJECTREFS
-typedef REF<LogicalCallContextObject> LOGICALCALLCONTEXTREF;
-#else
-typedef LogicalCallContextObject* LOGICALCALLCONTEXTREF;
-#endif
-
-#endif // FEATURE_REMOTING
-
-#ifndef FEATURE_CORECLR
-class ExecutionContextObject : public Object
-{
- friend class MscorlibBinder;
-
- // These fields are also defined in the managed representation. (ExecutionContext.cs) If you
- // add or change these fields you must also change the managed code so that
- // it matches these. This is necessary so that the object is the proper
- // size.
-private :
-#ifdef FEATURE_CAS_POLICY
- OBJECTREF _hostExecutionContext;
-#endif // FEATURE_CAS_POLICY
- OBJECTREF _syncContext;
- OBJECTREF _syncContextNoFlow;
-#if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
- SECURITYCONTEXTREF _securityContext;
-#endif // #if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
-#ifdef FEATURE_REMOTING
- LOGICALCALLCONTEXTREF _logicalCallContext;
- OBJECTREF _illogicalCallContext;
-#endif // #ifdef FEATURE_REMOTING
- INT32 _flags;
- OBJECTREF _localValues;
- OBJECTREF _localChangeNotifications;
-
-public:
- OBJECTREF GetSynchronizationContext()
- {
- LIMITED_METHOD_CONTRACT;
- return _syncContext;
- }
-#if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
- SECURITYCONTEXTREF GetSecurityContext()
- {
- LIMITED_METHOD_CONTRACT;
- return _securityContext;
- }
-#endif // #if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
-#ifdef FEATURE_REMOTING
- LOGICALCALLCONTEXTREF GetLogicalCallContext()
- {
- LIMITED_METHOD_CONTRACT;
- return _logicalCallContext;
- }
- void SetLogicalCallContext(LOGICALCALLCONTEXTREF ref)
- {
- WRAPPER_NO_CONTRACT;
- SetObjectReferenceUnchecked((OBJECTREF*)&_logicalCallContext, (OBJECTREF)ref);
- }
- OBJECTREF GetIllogicalCallContext()
- {
- LIMITED_METHOD_CONTRACT;
- return _illogicalCallContext;
- }
- void SetIllogicalCallContext(OBJECTREF ref)
- {
- WRAPPER_NO_CONTRACT;
- SetObjectReferenceUnchecked((OBJECTREF*)&_illogicalCallContext, ref);
- }
-#endif //#ifdef FEATURE_REMOTING
-#ifdef FEATURE_COMPRESSEDSTACK
- COMPRESSEDSTACKREF GetCompressedStack()
- {
- WRAPPER_NO_CONTRACT;
- if (_securityContext != NULL)
- return _securityContext->GetCompressedStack();
- return NULL;
- }
-#endif // #ifdef FEATURE_COMPRESSEDSTACK
-
-};
-#endif //FEATURE_CORECLR
typedef DPTR(class CultureInfoBaseObject) PTR_CultureInfoBaseObject;
#ifdef USE_CHECKED_OBJECTREFS
-#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
typedef REF<SynchronizationContextObject> SYNCHRONIZATIONCONTEXTREF;
-#endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
typedef REF<ExecutionContextObject> EXECUTIONCONTEXTREF;
typedef REF<CultureInfoBaseObject> CULTUREINFOBASEREF;
typedef REF<ArrayBase> ARRAYBASEREF;
#else
-#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
typedef SynchronizationContextObject* SYNCHRONIZATIONCONTEXTREF;
-#endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
-#ifndef FEATURE_CORECLR
-typedef ExecutionContextObject* EXECUTIONCONTEXTREF;
-#endif
typedef CultureInfoBaseObject* CULTUREINFOBASEREF;
typedef PTR_ArrayBase ARRAYBASEREF;
#endif
@@ -1849,202 +1574,35 @@ class CultureInfoBaseObject : public Object
private:
OBJECTREF compareInfo;
OBJECTREF textInfo;
-#ifndef FEATURE_CORECLR
- OBJECTREF regionInfo;
-#endif // !FEATURE_CORECLR
OBJECTREF numInfo;
OBJECTREF dateTimeInfo;
OBJECTREF calendar;
- OBJECTREF m_cultureData;
- OBJECTREF m_consoleFallbackCulture;
- STRINGREF m_name; // "real" name - en-US, de-DE_phoneb or fj-FJ
- STRINGREF m_nonSortName; // name w/o sort info (de-DE for de-DE_phoneb)
- STRINGREF m_sortName; // Sort only name (de-DE_phoneb, en-us for fj-fj (w/us sort)
- CULTUREINFOBASEREF m_parent;
-#ifndef FEATURE_COREFX_GLOBALIZATION
- INT32 iDataItem; // NEVER USED, DO NOT USE THIS! (Serialized in Whidbey/Everett)
- INT32 iCultureID; // NEVER USED, DO NOT USE THIS! (Serialized in Whidbey/Everett)
-#endif // !FEATURE_COREFX_GLOBALIZATION
-#ifdef FEATURE_LEAK_CULTURE_INFO
- INT32 m_createdDomainID;
-#endif // FEATURE_LEAK_CULTURE_INFO
- CLR_BOOL m_isReadOnly;
- CLR_BOOL m_isInherited;
-#ifdef FEATURE_LEAK_CULTURE_INFO
- CLR_BOOL m_isSafeCrossDomain;
-#endif // FEATURE_LEAK_CULTURE_INFO
- CLR_BOOL m_useUserOverride;
+ OBJECTREF _cultureData;
+ OBJECTREF _consoleFallbackCulture;
+ STRINGREF _name; // "real" name - en-US, de-DE_phoneb or fj-FJ
+ STRINGREF _nonSortName; // name w/o sort info (de-DE for de-DE_phoneb)
+ STRINGREF _sortName; // Sort only name (de-DE_phoneb, en-us for fj-fj (w/us sort)
+ CULTUREINFOBASEREF _parent;
+ CLR_BOOL _isReadOnly;
+ CLR_BOOL _isInherited;
+ CLR_BOOL _useUserOverride;
public:
CULTUREINFOBASEREF GetParent()
{
LIMITED_METHOD_CONTRACT;
- return m_parent;
+ return _parent;
}// GetParent
STRINGREF GetName()
{
LIMITED_METHOD_CONTRACT;
- return m_name;
+ return _name;
}// GetName
-#ifdef FEATURE_LEAK_CULTURE_INFO
- BOOL IsSafeCrossDomain()
- {
- return m_isSafeCrossDomain;
- }// IsSafeCrossDomain
-
- ADID GetCreatedDomainID()
- {
- return ADID(m_createdDomainID);
- }// GetCreatedDomain
-#endif // FEATURE_LEAK_CULTURE_INFO
-
}; // class CultureInfoBaseObject
-
-#ifndef FEATURE_COREFX_GLOBALIZATION
-typedef DPTR(class CultureDataBaseObject) PTR_CultureDataBaseObject;
-class CultureDataBaseObject : public Object
-{
-public:
- // offsets are for Silverlight
- /* 0x000 */ STRINGREF sRealName ; // Name you passed in (ie: en-US, en, or de-DE_phoneb)
- /* 0x008 */ STRINGREF sWindowsName ; // Name OS thinks the object is (ie: de-DE_phoneb, or en-US (even if en was passed in))
- /* 0x010 */ STRINGREF sName ; // locale name (ie: en-us, NO sort info, but could be neutral)
- /* 0x012 */ STRINGREF sParent ; // Parent name (which may be a custom locale/culture)
- /* 0x020 */ STRINGREF sLocalizedDisplayName ; // Localized pretty name for this locale
- /* 0x028 */ STRINGREF sEnglishDisplayName ; // English pretty name for this locale
- /* 0x030 */ STRINGREF sNativeDisplayName ; // Native pretty name for this locale
- /* 0x038 */ STRINGREF sSpecificCulture ; // The culture name to be used in CultureInfo.CreateSpecificCulture(), en-US form if neutral, sort name if sort
- /* 0x040 */ STRINGREF sISO639Language ; // ISO 639 Language Name
- /* 0x048 */ STRINGREF sLocalizedLanguage ; // Localized name for this language
- /* 0x050 */ STRINGREF sEnglishLanguage ; // English name for this language
- /* 0x058 */ STRINGREF sNativeLanguage ; // Native name of this language
- /* 0x060 */ STRINGREF sRegionName ; // (RegionInfo)
- /* 0x068 */ STRINGREF sLocalizedCountry ; // localized country name
- /* 0x070 */ STRINGREF sEnglishCountry ; // english country name (RegionInfo)
- /* 0x078 */ STRINGREF sNativeCountry ; // native country name
- /* 0x080 */ STRINGREF sISO3166CountryName ; // (RegionInfo), ie: US
- /* 0x088 */ STRINGREF sPositiveSign ; // (user can override) positive sign
- /* 0x090 */ STRINGREF sNegativeSign ; // (user can override) negative sign
-
- /* 0x098 */ PTRARRAYREF saNativeDigits ; // (user can override) native characters for digits 0-9
- /* 0x0a0 */ I4ARRAYREF waGrouping ; // (user can override) grouping of digits
-
- /* 0x0a8 */ STRINGREF sDecimalSeparator ; // (user can override) decimal separator
- /* 0x0b0 */ STRINGREF sThousandSeparator ; // (user can override) thousands separator
- /* 0x0b8 */ STRINGREF sNaN ; // Not a Number
- /* 0x0c0 */ STRINGREF sPositiveInfinity ; // + Infinity
- /* 0x0c8 */ STRINGREF sNegativeInfinity ; // - Infinity
- /* 0x0d0 */ STRINGREF sPercent ; // Percent (%) symbol
- /* 0x0d8 */ STRINGREF sPerMille ; // PerMille (U+2030) symbol
- /* 0x0e0 */ STRINGREF sCurrency ; // (user can override) local monetary symbol
- /* 0x0e8 */ STRINGREF sIntlMonetarySymbol ; // international monetary symbol (RegionInfo)
- /* 0x0f0 */ STRINGREF sEnglishCurrency ; // English name for this currency
- /* 0x0f8 */ STRINGREF sNativeCurrency ; // Native name for this currency
-
- /* 0x100 */ I4ARRAYREF waMonetaryGrouping ; // (user can override) monetary grouping of digits
-
- /* 0x108 */ STRINGREF sMonetaryDecimal ; // (user can override) monetary decimal separator
- /* 0x110 */ STRINGREF sMonetaryThousand ; // (user can override) monetary thousands separator
- /* 0x118 */ STRINGREF sListSeparator ; // (user can override) list separator
- /* 0x120 */ STRINGREF sAM1159 ; // (user can override) AM designator
- /* 0x128 */ STRINGREF sPM2359 ; // (user can override) PM designator
- STRINGREF sTimeSeparator ; // Time Separator
-
- /* 0x130 */ PTRARRAYREF saLongTimes ; // (user can override) time format
- /* 0x138 */ PTRARRAYREF saShortTimes ; // short time format
- /* 0x140 */ PTRARRAYREF saDurationFormats ; // time duration format
-
- /* 0x148 */ I4ARRAYREF waCalendars ; // all available calendar type(s). The first one is the default calendar
-
- /* 0x150 */ PTRARRAYREF calendars ; // Store for specific calendar data
-
- /* 0x158 */ STRINGREF sTextInfo ; // Text info name to use for custom
- /* 0x160 */ STRINGREF sCompareInfo ; // Compare info name (including sorting key) to use if custom
- /* 0x168 */ STRINGREF sScripts ; // Typical Scripts for this locale (latn;cyrl; etc)
-
- // these are ordered correctly
- /* ????? */ STRINGREF sAbbrevLang ; // abbreviated language name (Windows Language Name) ex: ENU
- /* ????? */ STRINGREF sAbbrevCountry ; // abbreviated country name (RegionInfo) (Windows Region Name) ex: USA
- /* ????? */ STRINGREF sISO639Language2 ; // 3 char ISO 639 lang name 2 ex: eng
- /* ????? */ STRINGREF sISO3166CountryName2 ; // 3 char ISO 639 country name 2 2(RegionInfo) ex: USA (ISO)
- /* ????? */ STRINGREF sConsoleFallbackName ; // The culture name for the console fallback UI culture
- /* ????? */ STRINGREF sKeyboardsToInstall ; // Keyboard installation string.
- /* ????? */ STRINGREF fontSignature ; // Font signature (16 WORDS)
-
-// Unused for now: /* ????? */ INT32 iCountry ; // (user can override) country code (RegionInfo)
- /* 0x170 */ INT32 iGeoId ; // GeoId
- /* 0x174 */ INT32 iDigitSubstitution ; // (user can override) Digit substitution 0=context, 1=none/arabic, 2=Native/national (2 seems to be unused)
- /* 0x178 */ INT32 iLeadingZeros ; // (user can override) leading zeros 0 = no leading zeros, 1 = leading zeros
- /* 0x17c */ INT32 iDigits ; // (user can override) number of fractional digits
- /* 0x180 */ INT32 iNegativeNumber ; // (user can override) negative number format
- /* 0x184 */ INT32 iNegativePercent ; // Negative Percent (0-3)
- /* 0x188 */ INT32 iPositivePercent ; // Positive Percent (0-11)
- /* 0x18c */ INT32 iCurrencyDigits ; // (user can override) # local monetary fractional digits
- /* 0x190 */ INT32 iCurrency ; // (user can override) positive currency format
- /* 0x194 */ INT32 iNegativeCurrency ; // (user can override) negative currency format
- /* 0x198 */ INT32 iMeasure ; // (user can override) system of measurement 0=metric, 1=US (RegionInfo)
-// Unused for now /* ????? */ INT32 iPaperSize ; // default paper size (RegionInfo)
- /* 0x19c */ INT32 iFirstDayOfWeek ; // (user can override) first day of week (gregorian really)
- /* 0x1a0 */ INT32 iFirstWeekOfYear ; // (user can override) first week of year (gregorian really)
-
- /* ????? */ INT32 iReadingLayout; // Reading Layout Data (0-3)
-
- // these are ordered correctly
- /* ????? */ INT32 iDefaultAnsiCodePage ; // default ansi code page ID (ACP)
- /* ????? */ INT32 iDefaultOemCodePage ; // default oem code page ID (OCP or OEM)
- /* ????? */ INT32 iDefaultMacCodePage ; // default macintosh code page
- /* ????? */ INT32 iDefaultEbcdicCodePage ; // default EBCDIC code page
- /* ????? */ INT32 iLanguage ; // locale ID (0409) - NO sort information
- /* ????? */ INT32 iInputLanguageHandle ; // input language handle
- /* 0x1a4 */ CLR_BOOL bUseOverrides ; // use user overrides?
- /* 0x1a5 */ CLR_BOOL bNeutral ; // Flags for the culture (ie: neutral or not right now)
- /* ????? */ CLR_BOOL bWin32Installed ; // Flags indicate if the culture is Win32 installed
- /* ????? */ CLR_BOOL bFramework ; // Flags for indicate if the culture is one of Whidbey cultures
-
-}; // class CultureDataBaseObject
-
-
-
-typedef DPTR(class CalendarDataBaseObject) PTR_CalendarDataBaseObject;
-class CalendarDataBaseObject : public Object
-{
-public:
- /* 0x000 */ STRINGREF sNativeName ; // Calendar Name for the locale
-
- // Formats
-
- /* 0x008 */ PTRARRAYREF saShortDates ; // Short Data format, default first
- /* 0x010 */ PTRARRAYREF saYearMonths ; // Year/Month Data format, default first
- /* 0x018 */ PTRARRAYREF saLongDates ; // Long Data format, default first
- /* 0x020 */ STRINGREF sMonthDay ; // Month/Day format
-
- // Calendar Parts Names
- /* 0x028 */ PTRARRAYREF saEraNames ; // Names of Eras
- /* 0x030 */ PTRARRAYREF saAbbrevEraNames ; // Abbreviated Era Names
- /* 0x038 */ PTRARRAYREF saAbbrevEnglishEraNames ; // Abbreviated Era Names in English
- /* 0x040 */ PTRARRAYREF saDayNames ; // Day Names, null to use locale data, starts on Sunday
- /* 0x048 */ PTRARRAYREF saAbbrevDayNames ; // Abbrev Day Names, null to use locale data, starts on Sunday
- /* 0x050 */ PTRARRAYREF saSuperShortDayNames ; // Super short Day of week names
- /* 0x058 */ PTRARRAYREF saMonthNames ; // Month Names (13)
- /* 0x060 */ PTRARRAYREF saAbbrevMonthNames ; // Abbrev Month Names (13)
- /* 0x068 */ PTRARRAYREF saMonthGenitiveNames ; // Genitive Month Names (13)
- /* 0x070 */ PTRARRAYREF saAbbrevMonthGenitiveNames ; // Genitive Abbrev Month Names (13)
- /* 0x078 */ PTRARRAYREF saLeapYearMonthNames ; // Multiple strings for the month names in a leap year.
-
- // Integers at end to make marshaller happier
- /* 0x080 */ INT32 iTwoDigitYearMax ; // Max 2 digit year (for Y2K bug data entry)
- /* 0x084 */ INT32 iCurrentEra ; // current era # (usually 1)
-
- // Use overrides?
- /* 0x088 */ CLR_BOOL bUseUserOverrides ; // True if we want user overrides.
-}; // class CalendarDataBaseObject
-#endif
-
-
typedef DPTR(class ThreadBaseObject) PTR_ThreadBaseObject;
class ThreadBaseObject : public Object
{
@@ -2061,21 +1619,10 @@ private:
// size. The order here must match that order which the loader will choose
// when laying out the managed class. Note that the layouts are checked
// at run time, not compile time.
-#ifdef FEATURE_REMOTING
- OBJECTREF m_ExposedContext;
-#endif
-#ifdef FEATURE_CORECLR
OBJECTREF m_ExecutionContext;
OBJECTREF m_SynchronizationContext;
-#else
- EXECUTIONCONTEXTREF m_ExecutionContext;
-#endif
OBJECTREF m_Name;
OBJECTREF m_Delegate;
-#ifdef FEATURE_LEAK_CULTURE_INFO
- CULTUREINFOBASEREF m_CurrentUserCulture;
- CULTUREINFOBASEREF m_CurrentUICulture;
-#endif
#ifdef IO_CANCELLATION_ENABLED
OBJECTREF m_CancellationSignals;
#endif
@@ -2139,100 +1686,21 @@ public:
OBJECTREF GetDelegate() { LIMITED_METHOD_CONTRACT; return m_Delegate; }
void SetDelegate(OBJECTREF delegate);
-#ifndef FEATURE_LEAK_CULTURE_INFO
CULTUREINFOBASEREF GetCurrentUserCulture();
CULTUREINFOBASEREF GetCurrentUICulture();
OBJECTREF GetManagedThreadCulture(BOOL bUICulture);
void ResetManagedThreadCulture(BOOL bUICulture);
void ResetCurrentUserCulture();
void ResetCurrentUICulture();
-#endif
-#ifdef FEATURE_REMOTING
- // These expose the remoting context (System\Remoting\Context)
- OBJECTREF GetExposedContext() { LIMITED_METHOD_CONTRACT; return m_ExposedContext; }
- OBJECTREF SetExposedContext(OBJECTREF newContext)
- {
- WRAPPER_NO_CONTRACT;
- OBJECTREF oldContext = m_ExposedContext;
- // Note: this is a very dangerous unchecked assignment. We are taking
- // responsibilty here for cleaning out the ExposedContext field when
- // an app domain is unloaded.
- SetObjectReferenceUnchecked( (OBJECTREF *)&m_ExposedContext, newContext );
-
- return oldContext;
- }
-#endif
-
-#ifdef FEATURE_LEAK_CULTURE_INFO
- CULTUREINFOBASEREF GetCurrentUserCulture()
- {
- LIMITED_METHOD_CONTRACT;
- return m_CurrentUserCulture;
- }
-
- void ResetCurrentUserCulture()
- {
- WRAPPER_NO_CONTRACT;
- ClearObjectReference((OBJECTREF *)&m_CurrentUserCulture);
- }
-
- CULTUREINFOBASEREF GetCurrentUICulture()
- {
- LIMITED_METHOD_CONTRACT;
- return m_CurrentUICulture;
- }
-
- void ResetCurrentUICulture()
- {
- WRAPPER_NO_CONTRACT;
- ClearObjectReference((OBJECTREF *)&m_CurrentUICulture);
- }
-#endif // FEATURE_LEAK_CULTURE_INFO
-
-#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
-#ifdef FEATURE_CORECLR
OBJECTREF GetSynchronizationContext()
{
LIMITED_METHOD_CONTRACT;
return m_SynchronizationContext;
}
-#else // !FEATURE_CORECLR
- OBJECTREF GetSynchronizationContext()
- {
- LIMITED_METHOD_CONTRACT;
- if (m_ExecutionContext != NULL)
- {
- return m_ExecutionContext->GetSynchronizationContext();
- }
- return NULL;
- }
-#endif // FEATURE_CORECLR
-#endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
-#ifndef FEATURE_CORECLR
- OBJECTREF GetExecutionContext()
- {
- LIMITED_METHOD_CONTRACT;
- return (OBJECTREF)m_ExecutionContext;
- }
- void SetExecutionContext(OBJECTREF ref)
- {
- LIMITED_METHOD_CONTRACT;
- SetObjectReferenceUnchecked((OBJECTREF*)&m_ExecutionContext, ref);
- }
-#endif //!FEATURE_CORECLR
-#ifdef FEATURE_COMPRESSEDSTACK
- COMPRESSEDSTACKREF GetCompressedStack()
- {
- WRAPPER_NO_CONTRACT;
- if (m_ExecutionContext != NULL)
- return m_ExecutionContext->GetCompressedStack();
- return NULL;
- }
-#endif // #ifdef FEATURE_COMPRESSEDSTACK
// SetDelegate is our "constructor" for the pathway where the exposed object is
// created first. InitExisting is our "constructor" for the pathway where an
// existing physical thread is later exposed.
@@ -2269,22 +1737,6 @@ public:
//
class MarshalByRefObjectBaseObject : public Object
{
-#ifdef FEATURE_REMOTING
- friend class MscorlibBinder;
-
- public:
- static int GetOffsetOfServerIdentity() { LIMITED_METHOD_CONTRACT; return offsetof(MarshalByRefObjectBaseObject, m_ServerIdentity); }
-
- protected:
- // READ ME:
- // Modifying the order or fields of this object may require other changes to the
- // classlib class definition of this object.
- OBJECTREF m_ServerIdentity;
-
- protected:
- MarshalByRefObjectBaseObject() {LIMITED_METHOD_CONTRACT;}
- ~MarshalByRefObjectBaseObject() {LIMITED_METHOD_CONTRACT;}
-#endif
};
@@ -2382,40 +1834,16 @@ class AppDomainBaseObject : public MarshalByRefObjectBaseObject
OBJECTREF m_pTypeEventHandler; // Delegate for 'resolve type' event
OBJECTREF m_pResourceEventHandler; // Delegate for 'resolve resource' event
OBJECTREF m_pAsmResolveEventHandler; // Delegate for 'resolve assembly' event
-#ifdef FEATURE_REFLECTION_ONLY_LOAD
- OBJECTREF m_pReflectionAsmResolveEventHandler; //Delegate for 'reflection resolve assembly' event
-#endif
-#ifdef FEATURE_REMOTING
- OBJECTREF m_pDefaultContext; // Default managed context for this AD.
-#endif
-#ifdef FEATURE_CLICKONCE
- OBJECTREF m_pActivationContext; // ClickOnce ActivationContext.
- OBJECTREF m_pApplicationIdentity; // App ApplicationIdentity.
-#endif
OBJECTREF m_pApplicationTrust; // App ApplicationTrust.
-#ifdef FEATURE_IMPERSONATION
- OBJECTREF m_pDefaultPrincipal; // Lazily computed default principle object used by threads
-#endif // FEATURE_IMPERSONATION
-#ifdef FEATURE_REMOTING
- OBJECTREF m_pURITable; // Identity table for remoting
-#endif
OBJECTREF m_pProcessExitEventHandler; // Delegate for 'process exit' event. Only used in Default appdomain.
OBJECTREF m_pDomainUnloadEventHandler; // Delegate for 'about to unload domain' event
OBJECTREF m_pUnhandledExceptionEventHandler; // Delegate for 'unhandled exception' event
-#ifdef FEATURE_APTCA
- OBJECTREF m_aptcaVisibleAssemblies; // array of conditional APTCA assembly names that should be APTCA visible
-#endif
OBJECTREF m_compatFlags;
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
OBJECTREF m_pFirstChanceExceptionHandler; // Delegate for 'FirstChance Exception' event
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
AppDomain* m_pDomain; // Pointer to the BaseDomain Structure
-#ifdef FEATURE_CAS_POLICY
- INT32 m_iPrincipalPolicy; // Type of principal to create by default
-#endif
CLR_BOOL m_bHasSetPolicy; // SetDomainPolicy has been called for this domain
CLR_BOOL m_bIsFastFullTrustDomain; // We know for sure that this is a homogeneous full trust domain.
CLR_BOOL m_compatFlagsInitialized;
@@ -2461,13 +1889,6 @@ class AppDomainBaseObject : public MarshalByRefObjectBaseObject
return !!m_bIsFastFullTrustDomain;
}
-#ifdef FEATURE_APTCA
- OBJECTREF GetPartialTrustVisibleAssemblies()
- {
- LIMITED_METHOD_CONTRACT
- return m_aptcaVisibleAssemblies;
- }
-#endif // FEATURE_APTCA
// Ref needs to be a PTRARRAYREF
void SetPolicies(OBJECTREF ref)
@@ -2475,28 +1896,13 @@ class AppDomainBaseObject : public MarshalByRefObjectBaseObject
WRAPPER_NO_CONTRACT;
SetObjectReference(&m_pPolicies, ref, m_pDomain );
}
-#ifdef FEATURE_REMOTING
- void SetDefaultContext(OBJECTREF ref)
- {
- WRAPPER_NO_CONTRACT;
- SetObjectReference(&m_pDefaultContext,ref,m_pDomain);
- }
-#endif
BOOL HasSetPolicy()
{
LIMITED_METHOD_CONTRACT;
return m_bHasSetPolicy;
}
-#ifdef FEATURE_CLICKONCE
- BOOL HasActivationContext()
- {
- LIMITED_METHOD_CONTRACT;
- return m_pActivationContext != NULL;
- }
-#endif // FEATURE_CLICKONCE
-#ifdef FEATURE_EXCEPTION_NOTIFICATIONS
// Returns the reference to the delegate of the first chance exception notification handler
OBJECTREF GetFirstChanceExceptionNotificationHandler()
{
@@ -2504,49 +1910,8 @@ class AppDomainBaseObject : public MarshalByRefObjectBaseObject
return m_pFirstChanceExceptionHandler;
}
-#endif // FEATURE_EXCEPTION_NOTIFICATIONS
};
-#ifndef FEATURE_CORECLR
-// The managed definition of AppDomainSortingSetupInfo is in BCL\System\Globalization\AppDomainSortingSetupInfo.cs
-class AppDomainSortingSetupInfoObject : public Object
-{
- friend class MscorlibBinder;
-
- protected:
- INT_PTR m_pfnIsNLSDefinedString;
- INT_PTR m_pfnCompareStringEx;
- INT_PTR m_pfnLCMapStringEx;
- INT_PTR m_pfnFindNLSStringEx;
- INT_PTR m_pfnCompareStringOrdinal;
- INT_PTR m_pfnGetNLSVersionEx;
- INT_PTR m_pfnFindStringOrdinal;
- CLR_BOOL m_useV2LegacySorting;
- CLR_BOOL m_useV4LegacySorting;
-
- protected:
- AppDomainSortingSetupInfoObject() { LIMITED_METHOD_CONTRACT; }
- ~AppDomainSortingSetupInfoObject() { LIMITED_METHOD_CONTRACT; }
-
- public:
- CLR_BOOL UseV2LegacySorting() { LIMITED_METHOD_CONTRACT; return m_useV2LegacySorting; }
- CLR_BOOL UseV4LegacySorting() { LIMITED_METHOD_CONTRACT; return m_useV4LegacySorting; }
-
- INT_PTR GetPFNIsNLSDefinedString() { LIMITED_METHOD_CONTRACT; return m_pfnIsNLSDefinedString; }
- INT_PTR GetPFNCompareStringEx() { LIMITED_METHOD_CONTRACT; return m_pfnCompareStringEx; }
- INT_PTR GetPFNLCMapStringEx() { LIMITED_METHOD_CONTRACT; return m_pfnLCMapStringEx; }
- INT_PTR GetPFNFindNLSStringEx() { LIMITED_METHOD_CONTRACT; return m_pfnFindNLSStringEx; }
- INT_PTR GetPFNCompareStringOrdinal() { LIMITED_METHOD_CONTRACT; return m_pfnCompareStringOrdinal; }
- INT_PTR GetPFNGetNLSVersionEx() { LIMITED_METHOD_CONTRACT; return m_pfnGetNLSVersionEx; }
- INT_PTR GetPFNFindStringOrdinal() { LIMITED_METHOD_CONTRACT; return m_pfnFindStringOrdinal; }
-};
-typedef DPTR(AppDomainSortingSetupInfoObject) PTR_AppDomainSortingSetupInfoObject;
-#ifdef USE_CHECKED_OBJECTREFS
-typedef REF<AppDomainSortingSetupInfoObject> APPDOMAINSORTINGSETUPINFOREF;
-#else
-typedef AppDomainSortingSetupInfoObject* APPDOMAINSORTINGSETUPINFOREF;
-#endif // USE_CHECKED_OBJECTREFS
-#endif // FEATURE_CORECLR
// The managed definition of AppDomainSetup is in BCL\System\AppDomainSetup.cs
class AppDomainSetupObject : public Object
@@ -2558,21 +1923,12 @@ class AppDomainSetupObject : public Object
STRINGREF m_AppBase;
OBJECTREF m_AppDomainInitializer;
PTRARRAYREF m_AppDomainInitializerArguments;
-#ifdef FEATURE_CLICKONCE
- OBJECTREF m_ActivationArguments;
-#endif // FEATURE_CLICKONCE
STRINGREF m_ApplicationTrust;
I1ARRAYREF m_ConfigurationBytes;
STRINGREF m_AppDomainManagerAssembly;
STRINGREF m_AppDomainManagerType;
-#if FEATURE_APTCA
- PTRARRAYREF m_AptcaVisibleAssemblies;
-#endif
OBJECTREF m_CompatFlags;
STRINGREF m_TargetFrameworkName;
-#ifndef FEATURE_CORECLR
- APPDOMAINSORTINGSETUPINFOREF m_AppDomainSortingSetupInfo;
-#endif // FEATURE_CORECLR
INT32 m_LoaderOptimization;
#ifdef FEATURE_COMINTEROP
CLR_BOOL m_DisableInterfaceCache;
@@ -2588,9 +1944,6 @@ class AppDomainSetupObject : public Object
~AppDomainSetupObject() { LIMITED_METHOD_CONTRACT; }
public:
-#ifndef FEATURE_CORECLR
- APPDOMAINSORTINGSETUPINFOREF GetAppDomainSortingSetupInfo() { LIMITED_METHOD_CONTRACT; return m_AppDomainSortingSetupInfo; }
-#endif // FEATURE_CORECLR
#ifdef FEATURE_RANDOMIZED_STRING_HASHING
BOOL UseRandomizedStringHashing() { LIMITED_METHOD_CONTRACT; return (BOOL) m_UseRandomizedStringHashing; }
#endif // FEATURE_RANDOMIZED_STRING_HASHING
@@ -2878,20 +2231,6 @@ class FrameSecurityDescriptorBaseObject : public Object
}
};
-#ifdef FEATURE_COMPRESSEDSTACK
-class FrameSecurityDescriptorWithResolverBaseObject : public FrameSecurityDescriptorBaseObject
-{
-public:
- OBJECTREF m_resolver;
-
-public:
- void SetDynamicMethodResolver(OBJECTREF resolver)
- {
- LIMITED_METHOD_CONTRACT;
- SetObjectReference(&m_resolver, resolver, this->GetAppDomain());
- }
-};
-#endif // FEATURE_COMPRESSEDSTACK
class WeakReferenceObject : public Object
{
@@ -2925,9 +2264,6 @@ typedef REF<VersionBaseObject> VERSIONREF;
typedef REF<FrameSecurityDescriptorBaseObject> FRAMESECDESCREF;
-#ifdef FEATURE_COMPRESSEDSTACK
-typedef REF<FrameSecurityDescriptorWithResolverBaseObject> FRAMESECDESWITHRESOLVERCREF;
-#endif // FEATURE_COMPRESSEDSTACK
typedef REF<WeakReferenceObject> WEAKREFERENCEREF;
@@ -2980,9 +2316,6 @@ typedef MarshalByRefObjectBaseObject* MARSHALBYREFOBJECTBASEREF;
typedef VersionBaseObject* VERSIONREF;
typedef FrameSecurityDescriptorBaseObject* FRAMESECDESCREF;
-#ifdef FEATURE_COMPRESSEDSTACK
-typedef FrameSecurityDescriptorWithResolverBaseObject* FRAMESECDESWITHRESOLVERCREF;
-#endif // FEATURE_COMPRESSEDSTACK
typedef WeakReferenceObject* WEAKREFERENCEREF;
#endif // #ifndef DACCESS_COMPILE
@@ -4265,9 +3598,7 @@ private:
STRINGREF _remoteStackTraceString;
PTRARRAYREF _dynamicMethods;
STRINGREF _source; // Mainly used by VB.
-#ifdef FEATURE_SERIALIZATION
- OBJECTREF _safeSerializationManager;
-#endif // FEATURE_SERIALIZATION
+
IN_WIN64(void* _xptrs;)
IN_WIN64(UINT_PTR _ipForWatsonBuckets;) // Contains the IP of exception for watson bucketing
INT32 _remoteStackIndex;
@@ -4333,9 +3664,6 @@ public:
STRINGREF sCurrencyGroup; // currencyDecimalSeparator
STRINGREF sCurrencyDecimal; // currencyGroupSeparator
STRINGREF sCurrency; // currencySymbol
-#ifndef FEATURE_COREFX_GLOBALIZATION
- STRINGREF sAnsiCurrency; // ansiCurrencySymbol
-#endif
STRINGREF sNaN; // nanSymbol
STRINGREF sPositiveInfinity; // positiveInfinitySymbol
STRINGREF sNegativeInfinity; // negativeInfinitySymbol
@@ -4346,9 +3674,6 @@ public:
PTRARRAYREF sNativeDigits; // nativeDigits (a string array)
-#ifndef FEATURE_COREFX_GLOBALIZATION
- INT32 iDataItem; // Index into the CultureInfo Table. Only used from managed code.
-#endif
INT32 cNumberDecimals; // numberDecimalDigits
INT32 cCurrencyDecimals; // currencyDecimalDigits
INT32 cPosCurrencyFormat; // positiveCurrencyFormat
@@ -4360,14 +3685,7 @@ public:
INT32 iDigitSubstitution; // digitSubstitution
CLR_BOOL bIsReadOnly; // Is this NumberFormatInfo ReadOnly?
-#ifndef FEATURE_COREFX_GLOBALIZATION
- CLR_BOOL bUseUserOverride; // Flag to use user override. Only used from managed code.
-#endif
CLR_BOOL bIsInvariant; // Is this the NumberFormatInfo for the Invariant Culture?
-#ifndef FEATURE_COREFX_GLOBALIZATION
- CLR_BOOL bvalidForParseAsNumber; // NEVER USED, DO NOT USE THIS! (Serialized in Whidbey/Everett)
- CLR_BOOL bvalidForParseAsCurrency; // NEVER USED, DO NOT USE THIS! (Serialized in Whidbey/Everett)
-#endif
};
typedef NumberFormatInfo * NUMFMTREF;
diff --git a/src/vm/objectclone.cpp b/src/vm/objectclone.cpp
deleted file mode 100644
index b4ad314165..0000000000
--- a/src/vm/objectclone.cpp
+++ /dev/null
@@ -1,3865 +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.
-//
-// File: ObjectClone.cpp
-//
-
-//
-
-
-#include "common.h"
-
-#ifdef FEATURE_REMOTING
-#include "objectclone.h"
-#include "frames.h"
-#include "assembly.hpp"
-#include "field.h"
-#include "security.h"
-#include "virtualcallstub.h"
-#include "crossdomaincalls.h"
-#include "callhelpers.h"
-#include "jitinterface.h"
-#include "typestring.h"
-#include "typeparse.h"
-#include "runtimehandles.h"
-#include "appdomain.inl"
-
-// Define the following to re-enable object cloner strict mode (where we require source fields for non-optional destination fields
-// and don't attempt to load assemblies we can't find via display via partial names instead).
-//#define OBJECT_CLONER_STRICT_MODE
-
-void MakeIDeserializationCallback(OBJECTREF refTarget);
-
-MethodDesc *GetInterfaceMethodImpl(MethodTable *pMT, MethodTable *pItfMT, WORD wSlot)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- } CONTRACTL_END;
-
- MethodDesc *pMeth = NULL;
- DispatchSlot slot(pMT->FindDispatchSlot(pItfMT->GetTypeID(), (UINT32)wSlot));
- CONSISTENCY_CHECK(!slot.IsNull());
- pMeth = slot.GetMethodDesc();
- return pMeth;
-}
-
-// Given a FieldDesc which may be representative and an object which contains said field, return the actual type of the field. This
-// works even when called from a different appdomain from which the type was loaded (though naturally it is the caller's
-// responsbility to ensure such an appdomain cannot be unloaded during the processing of this method).
-TypeHandle LoadExactFieldType(FieldDesc *pFD, OBJECTREF orefParent, AppDomain *pDomain)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- } CONTRACTL_END;
-
- MethodTable *pEnclosingMT = orefParent->GetMethodTable();
-
- // Set up a field signature with the owning type providing a type context for any type variables.
- MetaSig sig(pFD, TypeHandle(pEnclosingMT));
- sig.NextArg();
-
- // If the enclosing type is resident to this domain or domain neutral and loaded in this domain then we can simply go get it.
- // The logic is trickier (and more expensive to calculate) for generic types, so skip the optimization there.
- if (pEnclosingMT->GetDomain() == GetAppDomain() ||
- (pEnclosingMT->IsDomainNeutral() &&
- !pEnclosingMT->HasInstantiation() &&
- pEnclosingMT->GetAssembly()->FindDomainAssembly(GetAppDomain())))
- return sig.GetLastTypeHandleThrowing();
-
- TypeHandle retTH;
-
- // Otherwise we have to do this the expensive way -- switch to the home domain for the type lookup.
- ENTER_DOMAIN_PTR(pDomain, ADV_RUNNINGIN);
- retTH = sig.GetLastTypeHandleThrowing();
- END_DOMAIN_TRANSITION;
-
- return retTH;
-}
-
-extern TypeHandle GetTypeByName( _In_opt_z_ LPUTF8 szFullClassName,
- BOOL bThrowOnError,
- BOOL bIgnoreCase,
- StackCrawlMark *stackMark,
- BOOL *pbAssemblyIsLoading);
-
-#ifndef DACCESS_COMPILE
-#define CUSTOM_GCPROTECT_BEGIN(context) do { \
- FrameWithCookie<GCSafeCollectionFrame> __gcframe(context); \
- /* work around unreachable code warning */ \
- if (true) { DEBUG_ASSURE_NO_RETURN_BEGIN(GCPROTECT)
-
-#define CUSTOM_GCPROTECT_END() \
- DEBUG_ASSURE_NO_RETURN_END(GCPROTECT) } \
- __gcframe.Pop(); } while(0)
-
-#else // #ifndef DACCESS_COMPILE
-
-#define CUSTOM_GCPROTECT_BEGIN(context)
-#define CUSTOM_GCPROTECT_END()
-
-#endif // #ifndef DACCESS_COMPILE
-
-int GCSafeObjectHashTable::HasID(OBJECTREF refObj, OBJECTREF *newObj)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- THROWS;
- GC_NOTRIGGER;
- }
- CONTRACTL_END
-
- BOOL seenBefore = FALSE;
- *newObj = NULL;
- int index = FindElement(refObj, seenBefore);
-
- if (seenBefore)
- {
- _ASSERTE(index < (int)m_currArraySize);
- *newObj = m_newObjects[index];
- return m_ids[index];
- }
-
- return -1;
-}
-
-// returns the object id
-int GCSafeObjectHashTable::AddObject(OBJECTREF refObj, OBJECTREF newObj)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- THROWS;
- GC_NOTRIGGER;
- }
- CONTRACTL_END
-
- int index = -1;
- GCPROTECT_BEGIN(refObj);
- GCPROTECT_BEGIN(newObj);
-
- if (m_count > m_currArraySize / 2)
- {
- Resize();
- }
-
- BOOL seenBefore = FALSE;
- index = FindElement(refObj, seenBefore);
-
- _ASSERTE(index >= 0 && index < (int)m_currArraySize);
- if (seenBefore)
- {
- _ASSERTE(!"Adding an object thats already present");
- }
- else
- {
- m_objects[index] = refObj;
- m_newObjects[index] = newObj;
- m_ids[index] = ++m_count;
- }
-
- GCPROTECT_END();
- GCPROTECT_END();
-
- return m_ids[index];
-}
-
-// returns the object id
-int GCSafeObjectHashTable::UpdateObject(OBJECTREF refObj, OBJECTREF newObj)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- THROWS;
- GC_NOTRIGGER;
- }
- CONTRACTL_END
-
- int index = -1;
- GCPROTECT_BEGIN(refObj);
- GCPROTECT_BEGIN(newObj);
-
- BOOL seenBefore = FALSE;
- index = FindElement(refObj, seenBefore);
-
- _ASSERTE(index >= 0 && index < (int)m_currArraySize);
- if (!seenBefore)
- {
- _ASSERTE(!"An object has to exist in the table, to update it");
- }
- else
- {
- _ASSERTE(m_objects[index] == refObj);
- m_newObjects[index] = newObj;
- }
-
- GCPROTECT_END();
- GCPROTECT_END();
-
- return m_ids[index];
-}
-
-// returns index into array where obj was found or will fit in
-int GCSafeObjectHashTable::FindElement(OBJECTREF refObj, BOOL &seenBefore)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- THROWS;
- GC_NOTRIGGER;
- }
- CONTRACTL_END
-
- int currentNumBuckets = m_currArraySize / NUM_SLOTS_PER_BUCKET;
- int hashcode = 0;
- GCPROTECT_BEGIN(refObj);
- hashcode = refObj->GetHashCodeEx();
- GCPROTECT_END();
-
- hashcode &= 0x7FFFFFFF; // ignore sign bit
- int hashIncrement = (1+((hashcode)%(currentNumBuckets-2)));
-#ifdef _DEBUG
- int numLoops = 0;
-#endif
-
- do
- {
- int index = ((unsigned)hashcode % currentNumBuckets) * NUM_SLOTS_PER_BUCKET;
- _ASSERTE(index >= 0 && index < (int)m_currArraySize);
- for (int i = index; i < index + NUM_SLOTS_PER_BUCKET; i++)
- {
- if (m_objects[i] == refObj)
- {
- seenBefore = TRUE;
- return i;
- }
-
- if (m_objects[i] == NULL)
- {
- seenBefore = FALSE;
- return i;
- }
- }
- hashcode += hashIncrement;
-#ifdef _DEBUG
- if (++numLoops > currentNumBuckets)
- _ASSERTE(!"Looped too many times, trying to find object in hashtable. If hitting ignore doesnt seem to help, then contact Ashok");
-#endif
- }while (true);
-
- _ASSERTE(!"Not expected to reach here in GCSafeObjectHashTable::FindElement");
- return -1;
-}
-
-void GCSafeObjectHashTable::Resize()
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- THROWS;
- GC_NOTRIGGER;
- }
- CONTRACTL_END
- // Allocate new space
- DWORD newSize = m_currArraySize * 2;
- for (int i = 0; (DWORD) i < sizeof(g_rgPrimes)/sizeof(DWORD); i++)
- {
- if (g_rgPrimes[i] > newSize)
- {
- newSize = g_rgPrimes[i];
- break;
- }
- }
-
- newSize *= NUM_SLOTS_PER_BUCKET;
- NewArrayHolder<OBJECTREF> refTemp (new OBJECTREF[newSize]);
- ZeroMemory((void *)refTemp, sizeof(OBJECTREF) * newSize);
-
- NewArrayHolder<OBJECTREF> refTempNewObj (new OBJECTREF[newSize]);
-#ifdef USE_CHECKED_OBJECTREFS
- ZeroMemory((void *)refTempNewObj, sizeof(OBJECTREF) * newSize);
-#endif
-
- NewArrayHolder<int> bTemp (new int[newSize]);
- ZeroMemory((void *)bTemp, sizeof(int) * newSize);
-
- // Copy over objects and data
- NewArrayHolder<OBJECTREF> refOldObj (m_objects);
- NewArrayHolder<OBJECTREF> refOldNewObj (m_newObjects);
- NewArrayHolder<int> oldIds (m_ids);
- DWORD oldArrSize = m_currArraySize;
-
- if (oldIds == (int *)&m_dataOnStack[0])
- {
- refOldObj.SuppressRelease();
- refOldNewObj.SuppressRelease();
- oldIds.SuppressRelease();
- }
-
- refTemp.SuppressRelease();
- refTempNewObj.SuppressRelease();
- bTemp.SuppressRelease();
-
- m_ids = bTemp;
- m_objects = refTemp;
- m_newObjects = refTempNewObj;
- m_currArraySize = newSize;
-
- for (DWORD i = 0; i < oldArrSize; i++)
- {
- if (refOldObj[i] == NULL)
- continue;
-
- BOOL seenBefore = FALSE;
- int newIndex = FindElement(refOldObj[i], seenBefore);
-
- if (!seenBefore)
- {
- _ASSERTE(newIndex < (int)m_currArraySize);
- m_objects[newIndex] = refOldObj[i];
- m_newObjects[newIndex] = refOldNewObj[i];
- m_ids[newIndex] = oldIds[i];
- }
- else
- _ASSERTE(!"Object seen twice while rehashing");
- }
-
-#ifdef USE_CHECKED_OBJECTREFS
- for(DWORD i = 0; i < m_currArraySize; i++)
- Thread::ObjectRefProtected(&m_objects[i]);
- for(DWORD i = 0; i < m_currArraySize; i++)
- Thread::ObjectRefProtected(&m_newObjects[i]);
-#endif
-
-}
-
-void GCSafeObjectTable::Push(OBJECTREF refObj, OBJECTREF refParent, OBJECTREF refAux, QueuedObjectInfo * pQOI)
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_NOTRIGGER;
- }
- CONTRACTL_END
- _ASSERTE(refObj != NULL);
- _ASSERTE(m_QueueType == LIFO_QUEUE);
- _ASSERTE(m_head == 0 && m_dataHead == 0);
-
- // First find the size of the object info
- DWORD size = pQOI->GetSize();
-
- // Check if resize is needed
- EnsureSize(size);
-
- // Push on the stack, first the objects
- DWORD index = m_count;
- if (m_Objects1)
- m_Objects1[index] = refObj;
-#ifdef _DEBUG
- else
- _ASSERTE(refObj == NULL);
-#endif
- if (m_Objects2)
- m_Objects2[index] = refParent;
-#ifdef _DEBUG
- else
- _ASSERTE(refParent == NULL);
-#endif
- if (m_Objects3)
- m_Objects3[index] = refAux;
-#ifdef _DEBUG
- else
- _ASSERTE(refAux == NULL);
-#endif
-
- // then the info
- if (m_dataIndices)
- m_dataIndices[index] = m_numDataBytes;
- BYTE *pData = &m_data[m_numDataBytes];
- memcpy(pData, (VOID*)pQOI, size);
-
- m_numDataBytes += size;
- m_count++;
-}
-
-OBJECTREF GCSafeObjectTable::Pop(OBJECTREF *refParent, OBJECTREF *refAux, QueuedObjectInfo ** pQOI)
-{
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(m_QueueType == LIFO_QUEUE);
- _ASSERTE(m_head == 0 && m_dataHead == 0);
- _ASSERTE(m_dataIndices != NULL);
-
- *pQOI = NULL;
- OBJECTREF refRet = NULL;
- *refParent = NULL;
- *refAux = NULL;
- if (m_count == 0)
- return NULL;
-
- m_count--;
- refRet = m_Objects1[m_count];
- if (m_Objects2)
- *refParent = m_Objects2[m_count];
- if (m_Objects3)
- *refAux = m_Objects3[m_count];
- *pQOI = (QueuedObjectInfo *) &m_data[m_dataIndices[m_count]];
-
- m_numDataBytes -= (*pQOI)->GetSize();
- return refRet;
-}
-
-void GCSafeObjectTable::SetAt(DWORD index, OBJECTREF refObj, OBJECTREF refParent, OBJECTREF refAux, QueuedObjectInfo * pQOI)
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_NOTRIGGER;
- }
- CONTRACTL_END
- _ASSERTE(refObj != NULL);
-#ifdef _DEBUG
- if (m_QueueType == LIFO_QUEUE)
- _ASSERTE(index >= 0 && index < m_count);
- else
- _ASSERTE(index < m_currArraySize);
-#endif
-
- // First find the size of the object info
- DWORD size = pQOI->GetSize();
-
- // Push on the stack, first the objects
- m_Objects1[index] = refObj;
- if (m_Objects2)
- m_Objects2[index] = refParent;
- if (m_Objects3)
- m_Objects3[index] = refAux;
-
- // then the info
- _ASSERTE(m_dataIndices != NULL);
-
- QueuedObjectInfo *pData = (QueuedObjectInfo *)&m_data[m_dataIndices[index]];
- _ASSERTE(pData->GetSize() == size);
-
- memcpy(pData, (VOID*)pQOI, size);
-}
-
-OBJECTREF GCSafeObjectTable::GetAt(DWORD index, OBJECTREF *refParent, OBJECTREF *refAux, QueuedObjectInfo ** pQOI)
-{
- LIMITED_METHOD_CONTRACT;
-#ifdef _DEBUG
- if (m_QueueType == LIFO_QUEUE)
- _ASSERTE(index >= 0 && index < m_count);
- else
- _ASSERTE(index < m_currArraySize);
-#endif
-
- OBJECTREF refRet = m_Objects1[index];
- if (m_Objects2)
- *refParent = m_Objects2[index];
- else
- *refParent = NULL;
- if (m_Objects3)
- *refAux = m_Objects3[index];
- else
- *refAux = NULL;
-
- _ASSERTE(m_dataIndices != NULL);
-
- *pQOI = (QueuedObjectInfo *) &m_data[m_dataIndices[index]];
-
- return refRet;
-}
-
-void GCSafeObjectTable::Enqueue(OBJECTREF refObj, OBJECTREF refParent, OBJECTREF refAux, QueuedObjectInfo *pQOI)
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_NOTRIGGER;
- }
- CONTRACTL_END
-
- _ASSERTE(refObj != NULL);
- _ASSERTE(m_QueueType == FIFO_QUEUE);
-
- // First find the size of the object info
- DWORD size = pQOI ? pQOI->GetSize() : 0;
-
- // Check if resize is needed
- EnsureSize(size);
-
- // Append to queue, first the objects
- DWORD index = (m_head + m_count) % m_currArraySize;
- m_Objects1[index] = refObj;
- if (m_Objects2)
- m_Objects2[index] = refParent;
- if (m_Objects3)
- m_Objects3[index] = refAux;
-
- // then the info
- if (pQOI)
- {
- DWORD dataIndex = (m_dataHead + m_numDataBytes) % (m_currArraySize * MAGIC_FACTOR);
- BYTE *pData = &m_data[dataIndex];
- memcpy(pData, (VOID*)pQOI, size);
-
- if (m_dataIndices)
- m_dataIndices[index] = dataIndex;
- m_numDataBytes += size;
- }
-
- m_count++;
-}
-
-OBJECTREF GCSafeObjectTable::Dequeue(OBJECTREF *refParent, OBJECTREF *refAux, QueuedObjectInfo ** pQOI)
-{
- LIMITED_METHOD_CONTRACT;
-
- _ASSERTE(m_QueueType == FIFO_QUEUE);
-
- if (pQOI)
- *pQOI = NULL;
- OBJECTREF refRet = NULL;
- *refParent = NULL;
- *refAux = NULL;
- if (m_count == 0)
- return NULL;
-
- refRet = m_Objects1[m_head];
- if (m_Objects2)
- *refParent = m_Objects2[m_head];
- if (m_Objects3)
- *refAux = m_Objects3[m_head];
-
- if (pQOI)
- {
- *pQOI = (QueuedObjectInfo *) &m_data[m_dataHead];
-
- m_dataHead = (m_dataHead + (*pQOI)->GetSize()) % (m_currArraySize * MAGIC_FACTOR);
-
- m_numDataBytes -= (*pQOI)->GetSize();
- }
-
- m_head = (m_head + 1) % m_currArraySize;
- m_count--;
- return refRet;
-}
-
-OBJECTREF GCSafeObjectTable::Peek(OBJECTREF *refParent, OBJECTREF *refAux, QueuedObjectInfo **pQOI)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- *pQOI = NULL;
- *refParent = NULL;
- *refAux = NULL;
- if (m_count == 0)
- return NULL;
-
- DWORD indexToPeek;
- if (m_QueueType == LIFO_QUEUE)
- {
- indexToPeek = m_count;
- return GetAt(indexToPeek, refParent, refAux, pQOI);
- }
- else
- {
- indexToPeek = m_head;
- if (m_Objects2)
- *refParent = m_Objects2[m_head];
- if (m_Objects3)
- *refParent = m_Objects3[m_head];
- *pQOI = (QueuedObjectInfo *) &m_data[m_dataHead];
- return m_Objects1[m_head];
- }
-
-}
-
-void GCSafeObjectTable::EnsureSize(DWORD requiredDataSize)
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_NOTRIGGER;
- }
- CONTRACTL_END
- // Check if the object queue is sized enough
- if (m_count == m_currArraySize)
- {
- Resize();
- return;
- }
-
- // Check if the data array size is enough
- if (m_numDataBytes + requiredDataSize > m_currArraySize * MAGIC_FACTOR)
- {
- Resize();
- return;
- }
-
- if (m_QueueType == FIFO_QUEUE)
- {
- // Will current QueuedObjectInfo go beyond the edge of the array ?
- if (m_dataHead + m_numDataBytes + requiredDataSize > m_currArraySize * MAGIC_FACTOR)
- {
- Resize();
- return;
- }
- }
-}
-
-void GCSafeObjectTable::Resize()
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_NOTRIGGER;
- }
- CONTRACTL_END
- // Allocate new space
- DWORD newSize = m_currArraySize * 2;
- NewArrayHolder<OBJECTREF> refTemp (NULL);
- NewArrayHolder<OBJECTREF> refParentTemp (NULL);
- NewArrayHolder<OBJECTREF> refAuxTemp (NULL);
-
- refTemp = new OBJECTREF[newSize];
- if (m_Objects2)
- refParentTemp = new OBJECTREF[newSize];
- if (m_Objects3)
- refAuxTemp = new OBJECTREF[newSize];
-
-#ifdef USE_CHECKED_OBJECTREFS
- ZeroMemory((void *)refTemp, sizeof(OBJECTREF) * newSize);
- if (m_Objects2)
- ZeroMemory((void *)refParentTemp, sizeof(OBJECTREF) * newSize);
- if (m_Objects3)
- ZeroMemory((void *)refAuxTemp, sizeof(OBJECTREF) * newSize);
-#endif
-
- NewArrayHolder<BYTE> bTemp (NULL);
- NewArrayHolder<DWORD> dwIndicesTemp (NULL);
-
- bTemp = new BYTE[newSize * MAGIC_FACTOR];
- if (m_dataIndices)
- dwIndicesTemp = new DWORD[newSize];
-
- // Copy over objects and data
- if (m_QueueType == LIFO_QUEUE || (m_QueueType == FIFO_QUEUE && m_head == 0))
- {
- void *pSrc = (void *)&m_Objects1[0];
- void *pDest = (void *)&refTemp[0];
- memcpyUnsafe(pDest, pSrc, m_count * sizeof(OBJECTREF));
-
- if (m_Objects2)
- {
- pSrc = (void *)&m_Objects2[0];
- pDest = (void *)&refParentTemp[0];
- memcpyUnsafe(pDest, pSrc, m_count * sizeof(OBJECTREF));
- }
-
- if (m_Objects3)
- {
- pSrc = (void *)&m_Objects3[0];
- pDest = (void *)&refAuxTemp[0];
- memcpyUnsafe(pDest, pSrc, m_count * sizeof(OBJECTREF));
- }
-
- pSrc = (void *)&m_data[0];
- pDest = (void *)&bTemp[0];
- memcpyNoGCRefs(pDest, pSrc, m_numDataBytes);
-
- if (m_dataIndices)
- {
- pSrc = (void *)&m_dataIndices[0];
- pDest = (void *)&dwIndicesTemp[0];
- memcpyNoGCRefs(pDest, pSrc, m_count * sizeof(DWORD));
- }
-
- }
- else
- {
- _ASSERTE(m_QueueType == FIFO_QUEUE && m_head != 0);
- _ASSERTE(m_currArraySize > m_head);
- DWORD numObjRefsToCopy = (m_count > m_currArraySize - m_head ? m_currArraySize - m_head : m_count);
-
- void *pSrc = (void *)&m_Objects1[m_head];
- void *pDest = (void *)&refTemp[0];
- memcpyUnsafe(pDest, pSrc, numObjRefsToCopy * sizeof(OBJECTREF));
- pSrc = (void *)&m_Objects1[0];
- pDest = (void *)&refTemp[numObjRefsToCopy];
- memcpyUnsafe(pDest, pSrc, (m_count - numObjRefsToCopy) * sizeof(OBJECTREF));
-
- if (m_Objects2)
- {
- pSrc = (void *)&m_Objects2[m_head];
- pDest = (void *)&refParentTemp[0];
- memcpyUnsafe(pDest, pSrc, numObjRefsToCopy * sizeof(OBJECTREF));
- pSrc = (void *)&m_Objects2[0];
- pDest = (void *)&refParentTemp[numObjRefsToCopy];
- memcpyUnsafe(pDest, pSrc, (m_count - numObjRefsToCopy) * sizeof(OBJECTREF));
- }
-
- if (m_Objects3)
- {
- pSrc = (void *)&m_Objects3[m_head];
- pDest = (void *)&refAuxTemp[0];
- memcpyUnsafe(pDest, pSrc, numObjRefsToCopy * sizeof(OBJECTREF));
- pSrc = (void *)&m_Objects3[0];
- pDest = (void *)&refAuxTemp[numObjRefsToCopy];
- memcpyUnsafe(pDest, pSrc, (m_count - numObjRefsToCopy) * sizeof(OBJECTREF));
- }
-
- if (m_dataIndices)
- {
- pSrc = (void *)&m_dataIndices[m_head];
- pDest = (void *)&dwIndicesTemp[0];
- memcpyUnsafe(pDest, pSrc, numObjRefsToCopy * sizeof(DWORD));
- pSrc = (void *)&m_dataIndices[0];
- pDest = (void *)&dwIndicesTemp[numObjRefsToCopy];
- memcpyUnsafe(pDest, pSrc, (m_count - numObjRefsToCopy) * sizeof(DWORD));
- }
-
- DWORD numBytesToCopy = (m_numDataBytes > ((m_currArraySize * MAGIC_FACTOR) - m_dataHead) ? ((m_currArraySize * MAGIC_FACTOR) - m_dataHead) : m_numDataBytes);//(m_currArraySize * MAGIC_FACTOR) - m_dataHead;
- memcpyNoGCRefs((void *)bTemp, (void *) &m_data[m_dataHead], numBytesToCopy);
- memcpyNoGCRefs((void *) &bTemp[numBytesToCopy], (void *)m_data, (m_numDataBytes - numBytesToCopy));
- }
-
- // Delete old allocation
- if (m_usingHeap)
- {
- delete[] m_data;
- delete[] m_Objects1;
- delete[] m_Objects2;
- delete[] m_Objects3;
- delete[] m_dataIndices;
- }
-
- refTemp.SuppressRelease();
- refParentTemp.SuppressRelease();
- refAuxTemp.SuppressRelease();
- dwIndicesTemp.SuppressRelease();
- bTemp.SuppressRelease();
-
- m_currArraySize = newSize;
- m_Objects1 = refTemp;
- m_Objects2 = refParentTemp;
- m_Objects3 = refAuxTemp;
- m_dataIndices = dwIndicesTemp;
- m_data = bTemp;
- m_head = 0;
- m_dataHead = 0;
-
- m_usingHeap = TRUE;
-#ifdef USE_CHECKED_OBJECTREFS
- for(DWORD i = 0; i < m_currArraySize; i++)
- {
- Thread::ObjectRefProtected(&m_Objects1[i]);
- if (m_Objects2)
- Thread::ObjectRefProtected(&m_Objects2[i]);
- if (m_Objects3)
- Thread::ObjectRefProtected(&m_Objects3[i]);
- }
-#endif
-}
-
-
-VOID GCScanRootsInCollection(promote_func *fn, ScanContext* sc, void *context)
-{
- STATIC_CONTRACT_SO_TOLERANT;
- GCSafeCollection *pObjCollection = (GCSafeCollection *)context;
- pObjCollection->ReportGCRefs(fn, sc);
-}
-
-VOID
-BeginCloning(ObjectClone *pOC)
-{
- pOC->Init(FALSE);
-}
-
-VOID
-EndCloning(ObjectClone *pOC)
-{
- pOC->Cleanup(FALSE);
-}
-
-typedef Holder<ObjectClone*, BeginCloning, EndCloning> ObjectCloneHolder;
-
-
-OBJECTREF ObjectClone::Clone(OBJECTREF refObj, TypeHandle expectedType, AppDomain* fromDomain, AppDomain* toDomain, OBJECTREF refExecutionContext)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- THROWS;
- GC_TRIGGERS;
- }
- CONTRACTL_END
-
- if (refObj == NULL)
- return NULL;
-
- if (m_context != ObjectFreezer && refObj->GetMethodTable() == g_pStringClass)
- return refObj;
-
- ObjectCloneHolder ocHolder(this);
-
- m_fromDomain = fromDomain;
- m_toDomain = toDomain;
-
- m_currObject = refObj;
- GCPROTECT_BEGIN(m_currObject);
- m_topObject = NULL;
- GCPROTECT_BEGIN(m_topObject);
- m_fromExecutionContext = refExecutionContext;
- GCPROTECT_BEGIN(m_fromExecutionContext);
-
- // Enter the domain we're cloning into, if we're not already there
- ENTER_DOMAIN_PTR(toDomain,ADV_RUNNINGIN);
-
- if (!m_securityChecked)
- {
- Security::SpecialDemand(SSWT_DEMAND_FROM_NATIVE, SECURITY_SERIALIZATION);
- m_securityChecked = TRUE;
- }
-
-#ifdef _DEBUG
- DefineFullyQualifiedNameForClass();
- LOG((LF_REMOTING, LL_INFO100, "Clone. Cloning instance of type %s.\n",
- GetFullyQualifiedNameForClassNestedAware(m_currObject->GetMethodTable())));
-#endif
-
- m_newObject = NULL;
- GCPROTECT_BEGIN(m_newObject);
- PTRARRAYREF refValues = NULL;
- GCPROTECT_BEGIN(refValues);
- OBJECTREF refParent = NULL;
- GCPROTECT_BEGIN(refParent);
-
- QueuedObjectInfo *currObjFixupInfo = NULL;
- // For some dynamically sized stack objects
- void *pTempStackSpace = NULL;
- DWORD dwCurrStackSpaceSize = 0;
-
- // Initialize QOM
- QueuedObjectInfo topObj;
- OBJECTREF dummy1, dummy2;
- QOM.Enqueue(m_currObject, NULL, NULL, (QueuedObjectInfo *)&topObj);
-
- while ((m_currObject = QOM.Dequeue(&dummy1, &dummy2, &currObjFixupInfo)) != NULL)
- {
- m_newObject = NULL;
- MethodTable *newMT = NULL;
-
- BOOL repeatObject = FALSE;
- BOOL isISerializable = FALSE, isIObjRef = FALSE, isBoxed = FALSE;
- DWORD ISerializableTSOIndex = (DWORD) -1;
- DWORD IObjRefTSOIndex = (DWORD) -1;
- DWORD BoxedValTSOIndex = (DWORD) -1;
- m_skipFieldScan = FALSE;
-
- // ALLOCATE PHASE
-
- // Was currObject seen before ?
- int currID = TOS.HasID(m_currObject, &m_newObject);
- if (currID != -1)
- {
- // Yes
- repeatObject = TRUE;
- m_skipFieldScan = TRUE;
- newMT = m_newObject->GetMethodTable();
-
- if (m_cbInterface->IsISerializableType(newMT))
- {
- currObjFixupInfo->SetIsISerializableInstance();
- isISerializable = TRUE;
- ISerializableTSOIndex = FindObjectInTSO(currID, ISerializable);
- }
-
-#ifdef _DEBUG
- LOG((LF_REMOTING, LL_INFO1000, "Clone. Object of type %s with id %d seen before.\n",
- GetFullyQualifiedNameForClassNestedAware(m_currObject->GetMethodTable()), currID));
-#endif
- }
- else
- {
-#ifdef _DEBUG
- LOG((LF_REMOTING, LL_INFO1000, "Clone. Object of type %s not seen before.\n",
- GetFullyQualifiedNameForClassNestedAware(m_currObject->GetMethodTable())));
-#endif
- // No
- MethodTable *currMT = m_currObject->GetMethodTable();
-
- // Check whether object is serializable
- m_cbInterface->ValidateFromType(currMT);
-
- // Add current object to table of seen objects and get an id
- currID = TOS.AddObject(m_currObject, m_newObject);
- LOG((LF_REMOTING, LL_INFO1000, "Clone. Current object added to Table of Objects Seen. Given id %d.\n", currID));
-
- if ( m_cbInterface->IsRemotedType(currMT, m_fromDomain, m_toDomain))
- {
- refValues = AllocateISerializable(currID, TRUE);
- isISerializable = TRUE;
- ISerializableTSOIndex = TSO.GetCount() - 1;
- currObjFixupInfo->SetIsISerializableInstance();
- if (refValues == NULL)
- {
- // We found a smugglable objref. No field scanning needed
- m_skipFieldScan = TRUE;
- }
- }
- else if( m_cbInterface->IsISerializableType(currMT))
- {
- InvokeVtsCallbacks(m_currObject, RemotingVtsInfo::VTS_CALLBACK_ON_SERIALIZING, fromDomain);
- if (HasVtsCallbacks(m_currObject->GetMethodTable(), RemotingVtsInfo::VTS_CALLBACK_ON_SERIALIZED))
- VSC.Enqueue(m_currObject, NULL, NULL, NULL);
-
- refValues = AllocateISerializable(currID, FALSE);
- isISerializable = TRUE;
- ISerializableTSOIndex = TSO.GetCount() - 1;
- currObjFixupInfo->SetIsISerializableInstance();
- }
- else if (currMT->IsArray())
- {
- AllocateArray();
- }
- else
- {
- // This is a regular object
- InvokeVtsCallbacks(m_currObject, RemotingVtsInfo::VTS_CALLBACK_ON_SERIALIZING, fromDomain);
- if (HasVtsCallbacks(m_currObject->GetMethodTable(), RemotingVtsInfo::VTS_CALLBACK_ON_SERIALIZED))
- VSC.Enqueue(m_currObject, NULL, NULL, NULL);
-
- AllocateObject();
-
- if (m_cbInterface->IsISerializableType(m_newObject->GetMethodTable()))
- {
- // We have a situation where the serialized instnce was not ISerializable,
- // but the target instance is. So we make the from object look like a ISerializable
- refValues = MakeObjectLookLikeISerializable(currID);
- isISerializable = TRUE;
- ISerializableTSOIndex = TSO.GetCount() - 1;
- currObjFixupInfo->SetIsISerializableInstance();
- }
- }
-
- _ASSERTE(m_newObject != NULL);
- newMT = m_newObject->GetMethodTable();
-
- // Check whether new object is serializable
- m_cbInterface->ValidateToType(newMT);
-
- // Update the TOS, to include the new object
- int retId;
- retId = TOS.UpdateObject(m_currObject, m_newObject);
- _ASSERTE(retId == currID);
- }
- _ASSERTE(m_newObject != NULL);
-
- // FIXUP PHASE
- // Get parent to be fixed up
- ParentInfo *parentInfo;
- refParent = QOF.Peek(&dummy1, &dummy2, (QueuedObjectInfo **)&parentInfo);
- MethodTable *pParentMT = NULL;
-
- if (refParent == NULL)
- {
- LOG((LF_REMOTING, LL_INFO1000, "Clone. No parent found. This is the top object.\n"));
- // This is the top object
- _ASSERTE(m_topObject == NULL);
- m_topObject = m_newObject;
- }
- else
- {
-#ifdef _DEBUG
- LOG((LF_REMOTING, LL_INFO1000, "Clone. Parent is of type %s.\n",
- GetFullyQualifiedNameForClassNestedAware(m_currObject->GetMethodTable())));
-#endif
- pParentMT = refParent->GetMethodTable();
- }
-
- if (IsDelayedFixup(newMT, currObjFixupInfo))
- {
- // New object is IObjRef or a boxed object
- if (m_cbInterface->IsIObjectReferenceType(newMT))
- {
- LOG((LF_REMOTING, LL_INFO1000, "Clone. This is an IObjectReference. Delaying fixup.\n"));
- DWORD size = sizeof(IObjRefInstanceInfo) + (currObjFixupInfo ? currObjFixupInfo->GetSize() : 0);
- if (size > dwCurrStackSpaceSize)
- {
- pTempStackSpace = _alloca(size);
- dwCurrStackSpaceSize = size;
- }
- IObjRefInstanceInfo *pIORInfo = new (pTempStackSpace) IObjRefInstanceInfo(currID, 0, 0);
- if (currObjFixupInfo)
- pIORInfo->SetFixupInfo(currObjFixupInfo);
- // Check if this instance is ISerializable also
- if (isISerializable)
- {
- LOG((LF_REMOTING, LL_INFO1000, "Clone. This is also an ISerializable type at index %d in TSO.\n", ISerializableTSOIndex));
- _ASSERTE(ISerializableTSOIndex != (DWORD) -1);
- pIORInfo->SetISerTSOIndex(ISerializableTSOIndex);
- }
-
- if (repeatObject)
- pIORInfo->SetIsRepeatObject();
-
- // Add to TSO
- TSO.Push(m_newObject, m_currObject, refParent, pIORInfo);
-
- isIObjRef = TRUE;
- IObjRefTSOIndex = TSO.GetCount() - 1;
-
- LOG((LF_REMOTING, LL_INFO1000, "Clone. Added to TSO at index %d.\n", IObjRefTSOIndex));
- // Any special object parent, would wait till the current object is resolved
- if (parentInfo)
- {
- parentInfo->IncrementSpecialMembers();
- TMappings.Add(IObjRefTSOIndex);
- }
-
- }
- if (currObjFixupInfo->NeedsUnboxing())
- {
- LOG((LF_REMOTING, LL_INFO1000, "Clone. This is a boxed value type. Delaying fixup.\n"));
- DWORD size = sizeof(ValueTypeInfo) + currObjFixupInfo->GetSize();
- if (size > dwCurrStackSpaceSize)
- {
- pTempStackSpace = _alloca(size);
- dwCurrStackSpaceSize = size;
- }
- ValueTypeInfo *valInfo = new (pTempStackSpace) ValueTypeInfo(currID, currObjFixupInfo);
- // If the value type is also ISer or IObj, then it has to wait till those interfaces are addressed
- if (isISerializable)
- {
- LOG((LF_REMOTING, LL_INFO1000, "Clone. This is also an ISerializable type at index %d in TSO.\n", ISerializableTSOIndex));
- valInfo->SetISerTSOIndex(ISerializableTSOIndex);
- }
- if (isIObjRef)
- {
- LOG((LF_REMOTING, LL_INFO1000, "Clone. This is also an IObjectReference type at index %d in TSO.\n", IObjRefTSOIndex));
- valInfo->SetIObjRefTSOIndex(IObjRefTSOIndex);
- }
-
- // Add to TSO
- TSO.Push(m_newObject, refParent, NULL, valInfo);
-
- isBoxed = TRUE;
- BoxedValTSOIndex = TSO.GetCount() - 1;
-
- LOG((LF_REMOTING, LL_INFO1000, "Clone. Added to TSO at index %d.\n", BoxedValTSOIndex));
- // An IObjRef parent, or a parent itself boxed, would wait till the current object is resolved
- if (parentInfo && (parentInfo->NeedsUnboxing() || parentInfo->IsIObjRefInstance()))
- {
- parentInfo->IncrementSpecialMembers();
- TMappings.Add(BoxedValTSOIndex);
- }
- }
- }
-
- if (refParent != NULL)
- {
- if (!IsDelayedFixup(newMT, currObjFixupInfo))
- Fixup(m_newObject, refParent, currObjFixupInfo);
-
- // If currObj is ISer, then an IObjRef parent would wait till the current object is resolved
- if (currObjFixupInfo->IsISerializableInstance() &&
- parentInfo->IsIObjRefInstance())
- {
- parentInfo->IncrementSpecialMembers();
- TMappings.Add(ISerializableTSOIndex);
- }
- }
-
- // If we are done with this parent, remove it from QOF
- if (parentInfo && parentInfo->DecrementFixupCount() == 0)
- {
- LOG((LF_REMOTING, LL_INFO1000, "Clone. All children fixed up. Removing parent from QOF.\n", BoxedValTSOIndex));
- LOG((LF_REMOTING, LL_INFO1000, "Clone. Parent has %d special member objects.\n", parentInfo->GetNumSpecialMembers()));
- OBJECTREF refTemp;
- ParentInfo *pFITemp;
- refTemp = QOF.Dequeue(&dummy1, &dummy2, (QueuedObjectInfo **)&pFITemp);
- _ASSERTE(refTemp == refParent);
- _ASSERTE(pFITemp == parentInfo);
-
- // If parent is a special object, then we need to know how many special members it has
- if ((parentInfo->IsIObjRefInstance() ||
- parentInfo->IsISerializableInstance() ||
- parentInfo->NeedsUnboxing())
- && parentInfo->GetNumSpecialMembers() > 0)
- {
- // Make a note in TSO that this parent has non-zero special members
- DWORD index[3];
- index[0] = parentInfo->GetIObjRefIndexIntoTSO();
- index[1] = parentInfo->GetISerIndexIntoTSO();
- index[2] = parentInfo->GetBoxedValIndexIntoTSO();
-
- for (DWORD count = 0; count < 3; count++)
- {
- OBJECTREF refIser, refNames, refValuesTemp;
- SpecialObjectInfo *pISerInfo;
-
- if (index[count] == (DWORD) -1)
- continue;
-
- refIser = TSO.GetAt(index[count], &refNames, &refValuesTemp, (QueuedObjectInfo **)&pISerInfo);
- _ASSERTE(refIser == refParent);
-
- DWORD numSpecialObjects = parentInfo->GetNumSpecialMembers();
- pISerInfo->SetNumSpecialMembers(numSpecialObjects);
-
- _ASSERTE(TMappings.GetCount() >= numSpecialObjects);
- pISerInfo->SetMappingTableIndex(TMappings.GetCount() - numSpecialObjects);
- }
- }
- }
-
- // FIELD SCAN PHASE
- if (!m_skipFieldScan)
- {
- if (m_currObject->GetMethodTable()->IsArray())
- ScanArrayMembers();
- else if (isISerializable)
- ScanISerializableMembers(IObjRefTSOIndex, ISerializableTSOIndex, BoxedValTSOIndex, refValues);
- else
- ScanMemberFields(IObjRefTSOIndex, BoxedValTSOIndex);
- }
-
- } // While there are objects in QOM
-
- // OBJECT COMPLETION PHASE
- CompleteSpecialObjects();
-
- // Deliver VTS OnDeserialized callbacks.
- CompleteVtsOnDeserializedCallbacks();
-
- CompleteIDeserializationCallbacks();
-
- _ASSERTE(m_topObject != NULL);
- // If a type check was requested, see if the returned object is of the expected type
- if (!expectedType.IsNull()
- && !ObjIsInstanceOf(OBJECTREFToObject(m_topObject), expectedType))
- COMPlusThrow(kArgumentException,W("Arg_ObjObj"));
-
- GCPROTECT_END(); // refParent
- GCPROTECT_END(); // refValues
-
- GCPROTECT_END(); // m_newObject
-
- END_DOMAIN_TRANSITION;
-
- // Deliver VTS OnSerialized callbacks.
- CompleteVtsOnSerializedCallbacks();
-
- GCPROTECT_END(); // m_fromExecutionContext
- GCPROTECT_END(); // m_topObject
- GCPROTECT_END(); // m_currObject
-
- return m_topObject;
-}
-
-// IObjRef and value types boxed by us, need to be fixed up towards the end
-BOOL ObjectClone::IsDelayedFixup(MethodTable *newMT, QueuedObjectInfo *pCurrInfo)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
- if (m_cbInterface->IsIObjectReferenceType(newMT) ||
- pCurrInfo->NeedsUnboxing())
- return TRUE;
- else
- return FALSE;
-}
-
-void ObjectClone::Fixup(OBJECTREF newObj, OBJECTREF refParent, QueuedObjectInfo *pFixupInfo)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
- MethodTable *pParentMT = refParent->GetMethodTable();
-
- if (pFixupInfo->IsISerializableMember())
- {
- HandleISerializableFixup(refParent, pFixupInfo);
- }
- else if (pParentMT->IsArray())
- {
- HandleArrayFixup(refParent, pFixupInfo);
- }
- else
- {
- HandleObjectFixup(refParent, pFixupInfo);
- }
-}
-
-PTRARRAYREF ObjectClone::MakeObjectLookLikeISerializable(int objectId)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- THROWS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END
-
- _ASSERTE(m_context != ObjectFreezer);
-
- LOG((LF_REMOTING, LL_INFO1000, "MakeObjectLookLikeISerializable. Target object is ISerializable, so making from object look ISerializable\n"));
- MethodTable *pCurrMT = m_currObject->GetMethodTable();
- DWORD numFields = pCurrMT->GetNumInstanceFields();
-
- PTRARRAYREF fieldNames = NULL;
- PTRARRAYREF fieldValues = NULL;
-
- GCPROTECT_BEGIN(fieldNames);
- GCPROTECT_BEGIN(fieldValues);
-
- // Go back to from domain
- ENTER_DOMAIN_PTR(m_fromDomain,ADV_RUNNINGIN);
-
- // Reset the execution context to the original state it was in when we first
- // left the from domain (this will automatically be popped once we return
- // from this domain again).
- Thread *pThread = GetThread();
- if (pThread->IsExposedObjectSet())
- {
- THREADBASEREF refThread = (THREADBASEREF)pThread->GetExposedObjectRaw();
- refThread->SetExecutionContext(m_fromExecutionContext);
- }
-
- fieldNames = (PTRARRAYREF)AllocateObjectArray(numFields, g_pStringClass, FALSE);
- fieldValues = (PTRARRAYREF)AllocateObjectArray(numFields, g_pObjectClass, FALSE);
-
- DWORD fieldIndex = 0;
- while (pCurrMT)
- {
-
- DWORD numInstanceFields = pCurrMT->GetNumIntroducedInstanceFields();
-
- FieldDesc *pFields = pCurrMT->GetApproxFieldDescListRaw();
-
- for (DWORD i = 0; i < numInstanceFields; i++)
- {
- if (pFields[i].IsNotSerialized())
- {
- LOG((LF_REMOTING, LL_INFO1000, "MakeObjectLookLikeISerializable. Field %s is marked NonSerialized. Skipping.\n", pFields[i].GetName()));
- continue;
- }
-
- CorElementType typ = pFields[i].GetFieldType();
- DWORD offset = pFields[i].GetOffset();
-
- LPCUTF8 szFieldName = pFields[i].GetName();
- STRINGREF refName = StringObject::NewString(szFieldName);
- _ASSERTE(refName != NULL);
-
- fieldNames->SetAt(fieldIndex, refName);
-
- switch (typ)
- {
- case ELEMENT_TYPE_BOOLEAN:
- case ELEMENT_TYPE_I1:
- case ELEMENT_TYPE_U1:
- case ELEMENT_TYPE_I2:
- case ELEMENT_TYPE_U2:
- case ELEMENT_TYPE_CHAR:
- case ELEMENT_TYPE_I4:
- case ELEMENT_TYPE_U4:
- case ELEMENT_TYPE_I8:
- case ELEMENT_TYPE_U8:
- case ELEMENT_TYPE_I:
- case ELEMENT_TYPE_U:
- case ELEMENT_TYPE_R4:
- case ELEMENT_TYPE_R8:
- {
- MethodTable *pFldMT = MscorlibBinder::GetElementType(typ);
- void *pData = m_currObject->GetData() + offset;
- OBJECTREF refBoxed = pFldMT->Box(pData);
-
- fieldValues->SetAt(fieldIndex, refBoxed);
- break;
- }
- case ELEMENT_TYPE_VALUETYPE:
- case ELEMENT_TYPE_PTR:
- case ELEMENT_TYPE_FNPTR:
- {
- TypeHandle th = LoadExactFieldType(&pFields[i], m_currObject, m_fromDomain);
- _ASSERTE(!th.AsMethodTable()->IsByRefLike() && "Field types cannot contain stack pointers.");
-
- OBJECTREF refBoxed = BoxValueTypeInWrongDomain(m_currObject, offset, th.AsMethodTable());
-
- fieldValues->SetAt(fieldIndex, refBoxed);
- break;
- }
- case ELEMENT_TYPE_SZARRAY: // Single Dim
- case ELEMENT_TYPE_ARRAY: // General Array
- case ELEMENT_TYPE_CLASS: // Class
- case ELEMENT_TYPE_OBJECT:
- case ELEMENT_TYPE_STRING: // System.String
- case ELEMENT_TYPE_VAR:
- {
- OBJECTREF refField = *((OBJECTREF *) m_currObject->GetData() + offset);
- fieldValues->SetAt(fieldIndex, refField);
- break;
- }
- default:
- _ASSERTE(!"Unknown element type in MakeObjectLookLikeISerializalbe");
- }
-
- fieldIndex++;
- }
-
- pCurrMT = pCurrMT->GetParentMethodTable();
- }
-
- // Back to original domain
- END_DOMAIN_TRANSITION;
-
- // Add object to TSO
- ISerializableInstanceInfo iserInfo(objectId, 0);
- TSO.Push(m_newObject, fieldNames, NULL, (QueuedObjectInfo *)&iserInfo);
-
- LOG((LF_REMOTING, LL_INFO1000, "MakeObjectLookLikeISerializable. Added to TSO at index %d.\n", TSO.GetCount() - 1));
- GCPROTECT_END();
- GCPROTECT_END();
-
- return fieldValues;
-}
-
-PTRARRAYREF ObjectClone::AllocateISerializable(int objectId, BOOL bIsRemotingObject)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- THROWS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END
-
- _ASSERTE(m_context != ObjectFreezer);
-
- // Go back to from domain
- StackSString ssAssemName;
- StackSString ssTypeName;
-
- struct _gc {
- STRINGREF typeName;
- STRINGREF assemblyName;
- PTRARRAYREF fieldNames;
- PTRARRAYREF fieldValues;
- OBJECTREF refObjRef;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- ENTER_DOMAIN_PTR(m_fromDomain,ADV_RUNNINGIN);
-
- // Reset the execution context to the original state it was in when we first
- // left the from domain (this will automatically be popped once we return
- // from this domain again).
- Thread *pThread = GetThread();
- if (pThread->IsExposedObjectSet())
- {
- THREADBASEREF refThread = (THREADBASEREF)pThread->GetExposedObjectRaw();
- refThread->SetExecutionContext(m_fromExecutionContext);
- }
-
- // Call GetObjectData on the interface
-
- LOG((LF_REMOTING, LL_INFO1000, "AllocateISerializable. Instance is ISerializable type. Calling GetObjectData.\n"));
-
- PREPARE_NONVIRTUAL_CALLSITE(METHOD__OBJECTCLONEHELPER__GET_OBJECT_DATA);
-
- DECLARE_ARGHOLDER_ARRAY(args, 5);
-
- args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(m_currObject);
- args[ARGNUM_1] = PTR_TO_ARGHOLDER(&gc.typeName);
- args[ARGNUM_2] = PTR_TO_ARGHOLDER(&gc.assemblyName);
- args[ARGNUM_3] = PTR_TO_ARGHOLDER(&gc.fieldNames);
- args[ARGNUM_4] = PTR_TO_ARGHOLDER(&gc.fieldValues);
-
- CATCH_HANDLER_FOUND_NOTIFICATION_CALLSITE;
- CALL_MANAGED_METHOD_RETREF(gc.refObjRef, OBJECTREF, args);
-
- if (!bIsRemotingObject || gc.refObjRef == NULL)
- {
- ssAssemName.Set(gc.assemblyName->GetBuffer());
- ssTypeName.Set(gc.typeName->GetBuffer());
- }
-
- // Back to original domain
- END_DOMAIN_TRANSITION;
-
- // if its a remoting object we are dealing with, we may already have the smugglable objref
- if (bIsRemotingObject && gc.refObjRef != NULL)
- {
- m_newObject = gc.refObjRef;
- // Add object to TSO. We dont need a ISerializable record, because we are smuggling the ObjRef
- // and so, technically the ISerializable ctor can be considered already called. But we still make an entry in
- // TSO and mark it "processed", so repeat references to the same remoting object work correctly
- ISerializableInstanceInfo iserInfo(objectId, 0);
- iserInfo.SetHasBeenProcessed();
- TSO.Push(m_newObject, NULL, NULL, (QueuedObjectInfo *)&iserInfo);
-
- LOG((LF_REMOTING, LL_INFO1000, "AllocateISerializable. GetObjectData returned smugglable ObjRef. Added dummy record to TSO at index %d.\n", TSO.GetCount() - 1));
- }
- else
- {
- // Find the type (and choke on any exotics such as arrays, function pointers or generic type definitions).
- TypeHandle th = GetType(ssTypeName, ssAssemName);
- if (th.IsTypeDesc() || th.ContainsGenericVariables())
- {
- StackSString ssBeforeTypeName, ssAfterTypeName;
- TypeString::AppendType(ssBeforeTypeName, m_currObject->GetTypeHandle(), TypeString::FormatNamespace | TypeString::FormatFullInst);
- TypeString::AppendType(ssAfterTypeName, th, TypeString::FormatNamespace | TypeString::FormatFullInst);
- COMPlusThrow(kSerializationException, IDS_SERIALIZATION_BAD_ISER_TYPE, ssBeforeTypeName.GetUnicode(), ssAfterTypeName.GetUnicode());
- }
- MethodTable *pSrvMT = th.AsMethodTable();
- _ASSERTE(pSrvMT);
-
-#ifdef _DEBUG
- {
- DefineFullyQualifiedNameForClass();
- LPCUTF8 __szTypeName = GetFullyQualifiedNameForClassNestedAware(pSrvMT);
- LOG((LF_REMOTING, LL_INFO1000, "AllocateISerializable. Allocating instance of type %s.\n", &__szTypeName[0]));
- }
-#endif
- // Allocate the object
- m_newObject = m_cbInterface->AllocateObject(m_currObject, pSrvMT);
-
- // Add object to TSO
- ISerializableInstanceInfo iserInfo(objectId, 0);
-
- // Check if the target object is ISerializable. If not, we need to treat construction of this object differently
- if (!m_cbInterface->IsISerializableType(pSrvMT))
- {
- iserInfo.SetTargetNotISerializable();
- }
- TSO.Push(m_newObject, gc.fieldNames, NULL, (QueuedObjectInfo *)&iserInfo);
-
- LOG((LF_REMOTING, LL_INFO1000, "AllocateISerializable. Added to TSO at index %d.\n", TSO.GetCount() - 1));
- }
- GCPROTECT_END();
-
- return gc.fieldValues;
-}
-
-void ObjectClone::AllocateArray()
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END
-
- LOG((LF_REMOTING, LL_INFO1000, "AllocateArray. Instance is an array type.\n"));
- MethodTable *pCurrMT = m_currObject->GetMethodTable();
- _ASSERTE(pCurrMT->IsArray());
-
- BASEARRAYREF refArray = (BASEARRAYREF)m_currObject;
- GCPROTECT_BEGIN(refArray);
-
- TypeHandle elemTh = refArray->GetArrayElementTypeHandle();
- CorElementType elemType = refArray->GetArrayElementType();
- DWORD numComponents = refArray->GetNumComponents();
-
- TypeHandle __elemTh = GetCorrespondingTypeForTargetDomain(elemTh);
- _ASSERTE(!__elemTh.IsNull());
-
- unsigned __rank = pCurrMT->GetRank();
- TypeHandle __arrayTh = ClassLoader::LoadArrayTypeThrowing(__elemTh, __rank == 1 ? ELEMENT_TYPE_SZARRAY : ELEMENT_TYPE_ARRAY, __rank);
-
- DWORD __numArgs = __rank*2;
- INT32* __args = (INT32*) _alloca(sizeof(INT32)*__numArgs);
-
- if (__arrayTh.AsArray()->GetInternalCorElementType() == ELEMENT_TYPE_ARRAY)
- {
- const INT32* bounds = refArray->GetBoundsPtr();
- const INT32* lowerBounds = refArray->GetLowerBoundsPtr();
- for(unsigned int i=0; i < __rank; i++)
- {
- __args[2*i] = lowerBounds[i];
- __args[2*i+1] = bounds[i];
- }
- }
- else
- {
- __numArgs = 1;
- __args[0] = numComponents;
- }
- m_newObject = m_cbInterface->AllocateArray(m_currObject, __arrayTh, __args, __numArgs, FALSE);
-
- // Treat pointer as a primitive type (we shallow copy the bits).
- if (CorTypeInfo::IsPrimitiveType(elemType) || elemType == ELEMENT_TYPE_PTR)
- {
- LOG((LF_REMOTING, LL_INFO1000, "AllocateArray. Instance is an array of primitive type. Copying contents.\n"));
- // Copy contents.
- SIZE_T numBytesToCopy = refArray->GetComponentSize() * numComponents;
- I1ARRAYREF refI1Arr = (I1ARRAYREF)m_newObject;
- BYTE *pDest = (BYTE *)refI1Arr->GetDirectPointerToNonObjectElements();
- I1ARRAYREF refFromArr = (I1ARRAYREF)refArray;
- BYTE *pSrc = (BYTE *)refFromArr->GetDirectPointerToNonObjectElements();
-
- memcpyNoGCRefs(pDest, pSrc, numBytesToCopy);
- m_skipFieldScan = TRUE;
- }
- else if (elemType == ELEMENT_TYPE_VALUETYPE)
- {
- if (!__elemTh.GetMethodTable()->HasFieldsWhichMustBeInited() && RemotableMethodInfo::TypeIsConduciveToBlitting(elemTh.AsMethodTable(), __elemTh.GetMethodTable()))
- {
- LOG((LF_REMOTING, LL_INFO1000, "AllocateArray. Instance is an array of value type with no embedded GC type. Copying contents.\n"));
- // Copy contents.
- SIZE_T numBytesToCopy = refArray->GetComponentSize() * numComponents;
- I1ARRAYREF refI1Arr = (I1ARRAYREF)m_newObject;
- BYTE *pDest = (BYTE *)refI1Arr->GetDirectPointerToNonObjectElements();
- I1ARRAYREF refFromArr = (I1ARRAYREF)refArray;
- BYTE *pSrc = (BYTE *)refFromArr->GetDirectPointerToNonObjectElements();
-
- memcpyNoGCRefs(pDest, pSrc, numBytesToCopy);
- m_skipFieldScan = TRUE;
- }
- }
- GCPROTECT_END();
-}
-
-void ObjectClone::AllocateObject()
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END
-
- LOG((LF_REMOTING, LL_INFO1000, "AllocateObject. Instance is a regular object.\n"));
- MethodTable *pCurrMT = m_currObject->GetMethodTable();
- _ASSERTE(!pCurrMT->IsArray());
- _ASSERTE(!pCurrMT->IsMarshaledByRef() && !pCurrMT->IsTransparentProxy());
- _ASSERTE(!m_cbInterface->IsISerializableType(pCurrMT));
-
- MethodTable *pCorrespondingMT = GetCorrespondingTypeForTargetDomain(pCurrMT);
- _ASSERTE(pCorrespondingMT);
-
- pCorrespondingMT->EnsureInstanceActive();
-
- m_newObject = m_cbInterface->AllocateObject(m_currObject, pCorrespondingMT);
-
- InvokeVtsCallbacks(m_newObject, RemotingVtsInfo::VTS_CALLBACK_ON_DESERIALIZING, m_toDomain);
-}
-
-// Use this wrapper when the type handle can't be represented as a raw MethodTable (i.e. it's a pointer or array type).
-TypeHandle ObjectClone::GetCorrespondingTypeForTargetDomain(TypeHandle thCli)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END
-
- TypeHandle thBaseType = thCli;
- TypeHandle thSrvType;
-
- // Strip off any pointer information (and record the depth). We'll put this back later (when we've translated the base type).
- DWORD dwPointerDepth = 0;
- while (thBaseType.IsPointer())
- {
- dwPointerDepth++;
- thBaseType = thBaseType.AsTypeDesc()->GetTypeParam();
- }
-
- // If we hit an array then we'll recursively translate the element type then build an array type out of it.
- if (thBaseType.IsArray())
- {
- ArrayTypeDesc *atd = (ArrayTypeDesc *)thBaseType.AsTypeDesc();
- thSrvType = GetCorrespondingTypeForTargetDomain(atd->GetArrayElementTypeHandle());
-
- thSrvType = ClassLoader::LoadArrayTypeThrowing(thSrvType, atd->GetInternalCorElementType(), atd->GetRank());
- }
- else
- {
- // We should have only unshared types if we get here.
- _ASSERTE(!thBaseType.IsTypeDesc());
- thSrvType = GetCorrespondingTypeForTargetDomain(thBaseType.AsMethodTable());
- }
-
- // Match the level of pointer indirection from the original client type.
- while (dwPointerDepth--)
- {
- thSrvType = thSrvType.MakePointer();
- }
-
- return thSrvType;
-}
-
-MethodTable * ObjectClone::GetCorrespondingTypeForTargetDomain(MethodTable *pCliMT)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END
-
- MethodTable *pSrvMT = NULL;
- if (m_fromDomain == m_toDomain)
- return pCliMT;
-
- _ASSERTE(m_context != ObjectFreezer);
-#ifdef _DEBUG
- SString __ssTypeName;
- StackScratchBuffer __scratchBuf;
- if (pCliMT->IsArray())
- pCliMT->_GetFullyQualifiedNameForClass(__ssTypeName);
- else
- pCliMT->_GetFullyQualifiedNameForClassNestedAware(__ssTypeName);
-#endif
-
- // Take benefit of shared types. If a type is shared, and its assembly has been loaded
- // in the target domain, go ahead and use the same MT ptr.
- // The logic is trickier (and more expensive to calculate) for generic types, so skip the optimization there.
- if (pCliMT->IsDomainNeutral() && !pCliMT->HasInstantiation())
- {
- if (pCliMT->GetAssembly()->FindDomainAssembly(m_toDomain))
- {
- LOG((LF_REMOTING, LL_INFO1000,
- "GetCorrespondingTypeForTargetDomain. Type %s is shared. Using same MethodTable.\n", __ssTypeName.GetUTF8(__scratchBuf)));
- return pCliMT;
- }
- }
-
- pSrvMT = CrossDomainTypeMap::GetMethodTableForDomain(pCliMT, m_fromDomain, m_toDomain);
- if (pSrvMT)
- {
- LOG((LF_REMOTING, LL_INFO1000,
- "GetCorrespondingTypeForTargetDomain. Found matching type for %s in domain %d from cache.\n", __ssTypeName.GetUTF8(__scratchBuf), m_toDomain));
- return pSrvMT;
- }
-
- // Need to find the name and lookup in target domain
- SString ssCliTypeName;
- if (pCliMT->IsArray())
- {
- pCliMT->_GetFullyQualifiedNameForClass(ssCliTypeName);
- }
- else if (pCliMT->HasInstantiation())
- {
- TypeString::AppendType(ssCliTypeName, TypeHandle(pCliMT), TypeString::FormatNamespace | TypeString::FormatFullInst);
- }
- else
- {
- pCliMT->_GetFullyQualifiedNameForClassNestedAware(ssCliTypeName);
- }
-
-
- SString ssAssemblyName;
- pCliMT->GetAssembly()->GetDisplayName(ssAssemblyName);
-
- // Get the assembly
- TypeHandle th = GetType(ssCliTypeName, ssAssemblyName);
-
- if (!pCliMT->IsArray())
- {
- pSrvMT = th.AsMethodTable();
- }
- else
- {
- _ASSERTE(th.IsArray());
- TypeDesc *td = th.AsTypeDesc();
- pSrvMT = td->GetMethodTable();
- }
- CrossDomainTypeMap::SetMethodTableForDomain(pCliMT, m_fromDomain, pSrvMT, m_toDomain);
- LOG((LF_REMOTING, LL_INFO1000,
- "GetCorrespondingTypeForTargetDomain. Loaded matching type for %s in domain %d. Added to cache.\n", __ssTypeName.GetUTF8(__scratchBuf), m_toDomain));
- return pSrvMT;
-}
-
-TypeHandle ObjectClone::GetType(const SString &ssTypeName, const SString &ssAssemName)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END;
-
- Assembly *pAssembly = NULL;
-
-#ifndef OBJECT_CLONER_STRICT_MODE
- EX_TRY
-#endif
- {
- AssemblySpec spec;
- StackScratchBuffer scratchBuf;
- HRESULT hr = spec.Init(ssAssemName.GetUTF8(scratchBuf));
- if (SUCCEEDED(hr))
- {
- pAssembly = spec.LoadAssembly(FILE_ACTIVE);
- }
- else
- {
- COMPlusThrowHR(hr);
- }
- }
-#ifndef OBJECT_CLONER_STRICT_MODE
- EX_CATCH
- {
- if (GET_EXCEPTION()->IsTransient())
- {
- EX_RETHROW;
- }
-
- DomainAssembly *pDomainAssembly = NULL;
-#ifdef FEATURE_FUSION
- // If the normal load fails then try loading from a partial assembly name (relaxed serializer rules).
- pDomainAssembly = LoadAssemblyFromPartialNameHack((SString*)&ssAssemName, TRUE);
-#endif // FEATURE_FUSION
- if (pDomainAssembly == NULL)
- COMPlusThrow(kSerializationException, IDS_SERIALIZATION_UNRESOLVED_TYPE,
- ssTypeName.GetUnicode(), ssAssemName.GetUnicode());
- else
- pAssembly = pDomainAssembly->GetAssembly();
- }
- EX_END_CATCH(SwallowAllExceptions);
-#endif
-
- _ASSERTE(pAssembly);
-
- TypeHandle th = TypeName::GetTypeFromAssembly(ssTypeName.GetUnicode(), pAssembly);
-
- if (th.IsNull())
- {
- COMPlusThrow(kSerializationException, IDS_SERIALIZATION_UNRESOLVED_TYPE,
- ssTypeName.GetUnicode(), ssAssemName.GetUnicode());
- }
-
- LOG((LF_REMOTING, LL_INFO1000, "GetType. Loaded type %S from assembly %S in domain %d. \n",
- ssTypeName.GetUnicode(), ssAssemName.GetUnicode(), m_toDomain->GetId().m_dwId));
-
- return th;
-}
-
-void ObjectClone::HandleISerializableFixup(OBJECTREF refParent, QueuedObjectInfo *currObjFixupInfo)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- _ASSERTE(m_context != ObjectFreezer);
-
- ISerializableMemberInfo *pIsInfo = (ISerializableMemberInfo *)currObjFixupInfo;
- OBJECTREF refNames, refValues;
- ISerializableInstanceInfo *dummy;
- OBJECTREF parent;
- parent = TSO.GetAt(pIsInfo->GetTableIndex(), &refNames, &refValues, (QueuedObjectInfo **)&dummy);
- _ASSERTE(parent == refParent);
- _ASSERTE(dummy->IsISerializableInstance());
-
- PTRARRAYREF refFields = (PTRARRAYREF)refValues;
- _ASSERTE(pIsInfo->GetFieldIndex() < refFields->GetNumComponents());
- refFields->SetAt(pIsInfo->GetFieldIndex(), m_newObject);
-
- LOG((LF_REMOTING, LL_INFO1000, "HandleISerializableFixup. Parent is ISerializable. Added field #%d to TSO record at index %d\n", pIsInfo->GetFieldIndex(), pIsInfo->GetTableIndex()));
-}
-
-void ObjectClone::HandleArrayFixup(OBJECTREF refParent, QueuedObjectInfo *currObjFixupInfo)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- THROWS;
- GC_TRIGGERS;
- }
- CONTRACTL_END
-
- _ASSERTE(refParent->GetMethodTable()->IsArray());
- BASEARRAYREF refParentArray = (BASEARRAYREF) refParent;
- GCPROTECT_BEGIN(refParentArray);
-
- NDimArrayMemberInfo *pArrInfo = (NDimArrayMemberInfo *)currObjFixupInfo;
- DWORD *pIndices = pArrInfo->GetIndices();
-
- TypeHandle arrayElementType = refParentArray->GetArrayElementTypeHandle();
- MethodTable *pArrayMT = refParentArray->GetMethodTable();
-
- DWORD Rank = pArrayMT->GetRank();
- SIZE_T Offset = 0;
- SIZE_T Multiplier = 1;
-
- _ASSERTE(Rank == pArrInfo->GetNumDimensions());
-
- for (int i = Rank-1; i >= 0; i--) {
- INT32 curIndex = pIndices[i];
- const INT32 *pBoundsPtr = refParentArray->GetBoundsPtr();
-
- // Bounds check each index
- // Casting to unsigned allows us to use one compare for [0..limit-1]
- _ASSERTE((UINT32) curIndex < (UINT32) pBoundsPtr[i]);
-
- Offset += curIndex * Multiplier;
- Multiplier *= pBoundsPtr[i];
- }
-
- // The follwing code is loosely based on COMArrayInfo::SetValue
-
- if (!arrayElementType.IsValueType())
- {
- if (!ObjIsInstanceOf(OBJECTREFToObject(m_newObject), arrayElementType))
- COMPlusThrow(kInvalidCastException,W("InvalidCast_StoreArrayElement"));
-
- OBJECTREF* pElem = (OBJECTREF*)(refParentArray->GetDataPtr() + (Offset * pArrayMT->GetComponentSize()));
- SetObjectReference(pElem,m_newObject,GetAppDomain());
- }
- else
- {
- // value class or primitive type
- OBJECTREF* pElem = (OBJECTREF*)(refParentArray->GetDataPtr() + (Offset * pArrayMT->GetComponentSize()));
- if (!arrayElementType.GetMethodTable()->UnBoxInto(pElem, m_newObject))
- COMPlusThrow(kInvalidCastException, W("InvalidCast_StoreArrayElement"));
- }
-
- LOG((LF_REMOTING, LL_INFO1000, "HandleArrayFixup. Parent is an array. Added element at offset %d\n", Offset));
- GCPROTECT_END();
-}
-
-void ObjectClone::HandleObjectFixup(OBJECTREF refParent, QueuedObjectInfo *currObjFixupInfo)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END
- ObjectMemberInfo *pObjInfo = (ObjectMemberInfo *)currObjFixupInfo;
- FieldDesc *pTargetField = pObjInfo->GetFieldDesc();
- DWORD offset = pTargetField->GetOffset();
-
-#ifdef _DEBUG
- MethodTable *pTemp = refParent->GetMethodTable();
- _ASSERTE(offset < pTemp->GetBaseSize());
-#endif
-
- GCPROTECT_BEGIN(refParent);
-
- TypeHandle fldType = LoadExactFieldType(pTargetField, refParent, m_toDomain);
-
- if (!ObjIsInstanceOf(OBJECTREFToObject(m_newObject), fldType))
- COMPlusThrow(kArgumentException,W("Arg_ObjObj"));
-
- OBJECTREF *pDest = (OBJECTREF *) (refParent->GetData() + offset);
- _ASSERTE(GetAppDomain()==m_toDomain);
- SetObjectReference(pDest, m_newObject, GetAppDomain());
-
- GCPROTECT_END();
-
- LOG((LF_REMOTING, LL_INFO1000, "HandleObjectFixup. Parent is a regular object. Added field at offset %d\n", offset));
-}
-
-#ifdef OBJECT_CLONER_STRICT_MODE
-static void DECLSPEC_NORETURN ThrowMissingFieldException(FieldDesc *pFD)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END;
-
- StackSString szField(SString::Utf8, pFD->GetName());
-
- StackSString szType;
- TypeString::AppendType(szType, TypeHandle(pFD->GetApproxEnclosingMethodTable()));
-
- COMPlusThrow(kSerializationException,
- IDS_SERIALIZATION_MISSING_FIELD,
- szField.GetUnicode(),
- szType.GetUnicode());
-}
-#endif
-
-void ObjectClone::ScanMemberFields(DWORD IObjRefTSOIndex, DWORD BoxedValTSOIndex)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END
- _ASSERTE(m_currObject != NULL);
- _ASSERTE(m_newObject != NULL);
-
- MethodTable *pMT = m_currObject->GetMethodTable();
- _ASSERTE(!pMT->IsMarshaledByRef() && !pMT->IsTransparentProxy());
- _ASSERTE(!pMT->IsArray());
- MethodTable *pTargetMT = m_newObject->GetMethodTable();
-
- DWORD numFixupsNeeded = 0;
-
- if (RemotableMethodInfo::TypeIsConduciveToBlitting(pMT, pTargetMT))
- {
- _ASSERTE(pMT->GetAlignedNumInstanceFieldBytes() == pTargetMT->GetAlignedNumInstanceFieldBytes());
- DWORD numBytes = pMT->GetNumInstanceFieldBytes();
- BYTE *pFrom = m_currObject->GetData();
- BYTE *pTo = m_newObject->GetData();
- memcpyNoGCRefs(pTo, pFrom, numBytes);
- LOG((LF_REMOTING, LL_INFO1000, "ScanMemberFields. Object has no reference type fields. Blitting contents.\n"));
- }
- else if (AreTypesEmittedIdentically(pMT, pTargetMT))
- {
- LOG((LF_REMOTING, LL_INFO1000, "ScanMemberFields. Object not blittable but types are layed out for easy cloning .\n"));
- MethodTable *pCurrMT = pMT;
- MethodTable *pCurrTargetMT = pTargetMT;
- while (pCurrMT)
- {
- DWORD numInstanceFields = pCurrMT->GetNumIntroducedInstanceFields();
- _ASSERTE(pCurrTargetMT->GetNumIntroducedInstanceFields() == numInstanceFields);
-
- FieldDesc *pFields = pCurrMT->GetApproxFieldDescListRaw();
- FieldDesc *pTargetFields = pCurrTargetMT->GetApproxFieldDescListRaw();
-
- for (DWORD i = 0; i < numInstanceFields; i++)
- {
- if (pFields[i].IsNotSerialized())
- {
- LOG((LF_REMOTING, LL_INFO1000, "ScanMemberFields. Field %s is marked NonSerialized. Skipping.\n", pFields[i].GetName()));
- continue;
- }
-
- numFixupsNeeded += CloneField(&pFields[i], &pTargetFields[i]);
- }
-
- pCurrMT = pCurrMT->GetParentMethodTable();
- pCurrTargetMT = pCurrTargetMT->GetParentMethodTable();
- }
- }
- else
- {
- LOG((LF_REMOTING, LL_INFO1000, "ScanMemberFields. Object type layout is different.\n"));
-
- // The object types between source and destination have significant differences (some fields may be added, removed or
- // re-ordered, the type hierarchy may have had layers added or removed). We can still clone the object if every non-optional
- // field in the destination object can be found and serialized in a type with the same name in the source object. We ignore
- // fields and entire type layers that have been added in the source object and also any fields or layers that have been
- // removed as long as they don't include any fields that are mandatory in the destination object. We allow the fields within
- // a type layer to move around (we key the field by name only, the latter stage of cloning will check type equivalency and
- // as above we will widen primitive types if necessary). Since it requires significant effort to calculate whether the
- // objects can be cloned (and then locate corresponding fields in order to do so) we cache a mapping of source object fields
- // to destination object fields.
-
- // The following call will return such a mapping (it's an array where each entry is a pointer to a source object field desc
- // and the entries are in destination field index order, most derived type first, followed by second most derived type
- // etc.). If a mapping is impossible the method will throw.
- FieldDesc **pFieldMap = CrossDomainFieldMap::LookupOrCreateFieldMapping(pTargetMT, pMT);
- DWORD dwMapIndex = 0;
-
- MethodTable *pDstMT = pTargetMT;
- while (pDstMT)
- {
- FieldDesc *pDstFields = pDstMT->GetApproxFieldDescListRaw();
- DWORD numInstanceFields = pDstMT->GetNumIntroducedInstanceFields();
-
- for (DWORD i = 0; i < numInstanceFields; i++)
- {
- FieldDesc *pSrcField = pFieldMap[dwMapIndex++];
-
- // Non-serialized fields in the destination type (or optional fields where the source type doesn't have an
- // equivalent) don't have a source field desc.
- if (pSrcField == NULL)
- continue;
-
- numFixupsNeeded += CloneField(pSrcField, &pDstFields[i]);
- }
-
- pDstMT = pDstMT->GetParentMethodTable();
- }
-
- _ASSERTE(dwMapIndex == pTargetMT->GetNumInstanceFields());
- }
-
- if (numFixupsNeeded > 0)
- {
- ParentInfo fxInfo(numFixupsNeeded);
- if (IObjRefTSOIndex != (DWORD) -1)
- {
- _ASSERTE(m_cbInterface->IsIObjectReferenceType(pMT));
- fxInfo.SetIsIObjRefInstance();
- fxInfo.SetIObjRefIndexIntoTSO(IObjRefTSOIndex);
- }
- if (BoxedValTSOIndex != (DWORD) -1)
- {
- _ASSERTE(pMT->IsValueType());
- fxInfo.SetNeedsUnboxing();
- fxInfo.SetBoxedValIndexIntoTSO(BoxedValTSOIndex);
- }
- QOF.Enqueue(m_newObject, NULL, NULL, (QueuedObjectInfo *)&fxInfo);
- LOG((LF_REMOTING, LL_INFO1000, "ScanMemberFields. Current object had total of %d reference type fields. Adding to QOF.\n", numFixupsNeeded));
- // Delay calling any OnDeserialized callbacks until the end of the cloning operation (it's difficult to tell when all the
- // children have been deserialized).
- if (HasVtsCallbacks(m_newObject->GetMethodTable(), RemotingVtsInfo::VTS_CALLBACK_ON_DESERIALIZED))
- VDC.Enqueue(m_newObject, NULL, NULL, NULL);
- if (m_cbInterface->RequiresDeserializationCallback(m_newObject->GetMethodTable()))
- {
- LOG((LF_REMOTING, LL_INFO1000, "ScanMemberFields. Adding object to Table of IDeserialization Callbacks\n"));
- QueuedObjectInfo noInfo;
- TDC.Enqueue(m_newObject, NULL, NULL, &noInfo);
- }
- }
- else
- {
- // This is effectively a leaf node (no complex children) so if the type has a callback for OnDeserialized we'll deliver it
- // now. This fixes callback ordering for a few more edge cases (e.g. VSW 415611) and is reasonably cheap. We can never do a
- // perfect job (in the presence of object graph cycles) and a near perfect job (intuitively ordered callbacks for acyclic
- // object graphs) is prohibitively expensive; so we're stuck with workarounds like this.
- InvokeVtsCallbacks(m_newObject, RemotingVtsInfo::VTS_CALLBACK_ON_DESERIALIZED, m_toDomain);
- if (m_cbInterface->RequiresDeserializationCallback(m_newObject->GetMethodTable()))
- MakeIDeserializationCallback(m_newObject);
- }
-}
-
-DWORD ObjectClone::CloneField(FieldDesc *pSrcField, FieldDesc *pDstField)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END;
-
- BOOL bFixupNeeded = FALSE;
-
- CorElementType srcType = pSrcField->GetFieldType();
- CorElementType dstType = pDstField->GetFieldType();
- DWORD srcOffset = pSrcField->GetOffset();
- DWORD dstOffset = pDstField->GetOffset();
-
- BOOL bUseWidenedValue = FALSE;
- ARG_SLOT fieldData = 0;
- if (srcType != dstType)
- {
- void *pData = m_currObject->GetData() + srcOffset;
-
- MethodTable *pSrcFieldMT = NULL;
- if (CorTypeInfo::IsPrimitiveType(srcType))
- pSrcFieldMT = MscorlibBinder::GetElementType(srcType);
- else
- pSrcFieldMT = LoadExactFieldType(pSrcField, m_currObject, m_fromDomain).AsMethodTable();
-
- LOG((LF_REMOTING, LL_INFO1000, "ScanMemberFields. Field %s has differing types at source and destination. Will try to convert.\n", pSrcField->GetName()));
- fieldData = HandleFieldTypeMismatch(dstType, srcType, pData, pSrcFieldMT);
- bUseWidenedValue = TRUE;
- }
-
- switch (dstType)
- {
- case ELEMENT_TYPE_I1:
- case ELEMENT_TYPE_U1:
- case ELEMENT_TYPE_BOOLEAN:
- {
- BYTE *pDest = m_newObject->GetData() + dstOffset;
- if (bUseWidenedValue)
- *pDest = (unsigned char) fieldData;
- else
- {
- BYTE *pByte = m_currObject->GetData() + srcOffset;
- *pDest = *pByte;
- }
- }
- break;
- case ELEMENT_TYPE_I2:
- case ELEMENT_TYPE_U2:
- case ELEMENT_TYPE_CHAR:
- {
- WORD *pDest = (WORD*)(m_newObject->GetData() + dstOffset);
- if (bUseWidenedValue)
- *pDest = (short) fieldData;
- else
- {
- WORD *pWord = (WORD*)(m_currObject->GetData() + srcOffset);
- *(pDest) = *pWord;
- }
- }
- break;
- case ELEMENT_TYPE_I4:
- case ELEMENT_TYPE_U4:
- case ELEMENT_TYPE_R4:
- IN_WIN32(case ELEMENT_TYPE_FNPTR:)
- IN_WIN32(case ELEMENT_TYPE_I:)
- IN_WIN32(case ELEMENT_TYPE_U:)
- {
- DWORD *pDest = (DWORD*)(m_newObject->GetData() + dstOffset);
- if (bUseWidenedValue)
- *pDest = (int) fieldData;
- else
- {
- DWORD *pDword = (DWORD*)(m_currObject->GetData() + srcOffset);
- *(pDest) = *pDword;
- }
- }
- break;
- case ELEMENT_TYPE_R8:
- case ELEMENT_TYPE_I8:
- case ELEMENT_TYPE_U8:
- IN_WIN64(case ELEMENT_TYPE_FNPTR:)
- IN_WIN64(case ELEMENT_TYPE_I:)
- IN_WIN64(case ELEMENT_TYPE_U:)
- {
- INT64 *pDest = (INT64*)(m_newObject->GetData() + dstOffset);
- if (bUseWidenedValue)
- *pDest = fieldData;
- else
- {
- INT64 *pLong = (INT64*)(m_currObject->GetData() + srcOffset);
- *(pDest) = *pLong;
- }
- }
- break;
- case ELEMENT_TYPE_PTR:
- {
- void **pDest = (void**)(m_newObject->GetData() + dstOffset);
- void **pPtr = (void**)(m_currObject->GetData() + srcOffset);
- *(pDest) = *pPtr;
- }
- break;
- case ELEMENT_TYPE_STRING:
- case ELEMENT_TYPE_CLASS: // objectrefs
- case ELEMENT_TYPE_OBJECT:
- case ELEMENT_TYPE_SZARRAY: // single dim, zero
- case ELEMENT_TYPE_ARRAY: // all other arrays
- {
- OBJECTREF *pSrc = (OBJECTREF *)(m_currObject->GetData() + srcOffset);
- OBJECTREF *pDest = (OBJECTREF *)(m_newObject->GetData() + dstOffset);
-
- if ((*pSrc) == NULL)
- break;
-
- // If no deep copy is required, just copy the reference
- if (!m_cbInterface->RequiresDeepCopy(*pSrc))
- {
- _ASSERTE(GetAppDomain()==m_toDomain);
- SetObjectReference(pDest, *pSrc, GetAppDomain());
- break;
- }
-
- // Special case String
- if ((*pSrc)->GetMethodTable() == g_pStringClass)
- {
- // Better check the destination really expects a string (or maybe an object).
- TypeHandle thDstField = LoadExactFieldType(pDstField, m_newObject, m_toDomain);
- if (thDstField != TypeHandle(g_pStringClass) && thDstField != TypeHandle(g_pObjectClass))
- COMPlusThrow(kArgumentException, W("Arg_ObjObj"));
-
- STRINGREF refStr = (STRINGREF) *pSrc;
- refStr = m_cbInterface->AllocateString(refStr);
- // Get dest addr again, as a GC might have occurred
- pDest = (OBJECTREF *)(m_newObject->GetData() + dstOffset);
- _ASSERTE(GetAppDomain()==m_toDomain);
- SetObjectReference(pDest, refStr, GetAppDomain());
-
- break;
- }
-
- // Add the object to QOM
- LOG((LF_REMOTING, LL_INFO1000, "ScanMemberFields. Adding object in field %s to Queue of Objects to be Marshalled.\n", pSrcField->GetName()));
- ObjectMemberInfo objInfo(pDstField);
- bFixupNeeded = TRUE;
- QOM.Enqueue(*pSrc, NULL, NULL, (QueuedObjectInfo *)&objInfo);
- }
- break;
-
- case ELEMENT_TYPE_VALUETYPE:
- {
- TypeHandle th = LoadExactFieldType(pSrcField, m_currObject, m_fromDomain);
- _ASSERTE(!th.AsMethodTable()->IsByRefLike() && "Field types cannot contain stack pointers.");
-
- TypeHandle thTarget = LoadExactFieldType(pDstField, m_newObject, m_toDomain);
-
- MethodTable *pValueClassMT = th.AsMethodTable();
- MethodTable *pValueClassTargetMT = thTarget.AsMethodTable();
- if (!RemotableMethodInfo::TypeIsConduciveToBlitting(pValueClassMT, pValueClassTargetMT))
- {
- // Needs marshalling
- // We're allocating an object in the "to" domain
- // using a type from the "from" domain.
- OBJECTREF refTmpBox = BoxValueTypeInWrongDomain(m_currObject, srcOffset, pValueClassMT);
-
- // Nullable<T> might return null here. In that case we don't need to do anything
- // and the null value otherwise confuxes the fixup queue.
- if (refTmpBox != NULL)
- {
- // Add the object to QOM
- ObjectMemberInfo objInfo(pDstField);
- objInfo.SetNeedsUnboxing();
- bFixupNeeded = TRUE;
- QOM.Enqueue(refTmpBox, NULL, NULL, (QueuedObjectInfo *)&objInfo);
- LOG((LF_REMOTING, LL_INFO1000, "ScanMemberFields. Value type field %s has reference type contents. Boxing and adding to QOM.\n", pSrcField->GetName()));
- }
- }
- else
- {
- DWORD numBytesToCopy = th.AsMethodTable()->GetNumInstanceFieldBytes();
- BYTE *pByte = m_currObject->GetData() + srcOffset;
- BYTE *pDest = m_newObject->GetData() + dstOffset;
- memcpyNoGCRefs(pDest, pByte, numBytesToCopy);
- LOG((LF_REMOTING, LL_INFO1000, "ScanMemberFields. Value type field %s has no reference type contents. Blitting.\n", pSrcField->GetName()));
- }
- }
- break;
- default:
- _ASSERTE(!"Unknown element type seen in ObjectClone::ScanMemberFields");
- break;
- }
-
- return bFixupNeeded ? 1 : 0;
-}
-
-BOOL ObjectClone::AreTypesEmittedIdentically(MethodTable *pMT1, MethodTable *pMT2)
-{
- LIMITED_METHOD_CONTRACT;
-
- // Identical here means that both types have the same hierarchy (depth and names match) and that each level of the hierarchy has
- // the same fields (by name) at the same index.
- // We're going to be called quite frequently (once per call to ScanMemberFields) so until we're convinced that caching this
- // information is worth it we'll just compute the fast cases here and let the rest fall through to the slower technique. The
- // fast check is that the types are shared and identical or that they're loaded from the same file (in which case we have to be
- // a little more paranoid and check up the hierarchy).
- if (pMT1 == pMT2)
- return TRUE;
-
- // While the current level of the type is loaded from the same file...
- // Note that we used to check that the assemblies were the same; now we're more paranoid and check the actual modules scoping
- // the type are identical. This closes a security hole where identically named types in different modules of the same assembly
- // could cause the wrong type to be loaded in the server context allowing violation of the type system.
- while (pMT1->GetModule()->GetFile()->Equals(pMT2->GetModule()->GetFile()))
- {
- // Inspect the parents.
- pMT1 = pMT1->GetParentMethodTable();
- pMT2 = pMT2->GetParentMethodTable();
-
- // If the parents are the same shared type (e.g. Object), then we've found a match.
- if (pMT1 == pMT2)
- return TRUE;
-
- // Else check if one of the hierarchies has run out before the other (and therefore can't be equivalent).
- if (pMT1 == NULL || pMT2 == NULL)
- return FALSE;
- }
-
- return FALSE;
-}
-
-BOOL AreTypesEquivalent(MethodTable *pMT1, MethodTable *pMT2)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END;
-
- // Equivalent here is quite a weak predicate. All it means is that the types have the same (fully assembly qualified) name. The
- // derivation hierarchy is not inspected at all.
- StackSString szType1;
- StackSString szType2;
-
- TypeString::AppendType(szType1, TypeHandle(pMT1), TypeString::FormatNamespace |
- TypeString::FormatFullInst |
- TypeString::FormatAssembly |
- TypeString::FormatNoVersion);
- TypeString::AppendType(szType2, TypeHandle(pMT2), TypeString::FormatNamespace |
- TypeString::FormatFullInst |
- TypeString::FormatAssembly |
- TypeString::FormatNoVersion);
-
- return szType1.Equals(szType2);
-}
-
-PtrHashMap *CrossDomainFieldMap::s_pFieldMap = NULL;
-SimpleRWLock *CrossDomainFieldMap::s_pFieldMapLock = NULL;
-
-BOOL CrossDomainFieldMap::CompareFieldMapEntry(UPTR val1, UPTR val2)
-{
- CONTRACTL {
- MODE_ANY;
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- CrossDomainFieldMap::FieldMapEntry *pEntry1 = (CrossDomainFieldMap::FieldMapEntry *)(val1 << 1);
- CrossDomainFieldMap::FieldMapEntry *pEntry2 = (CrossDomainFieldMap::FieldMapEntry *)val2;
-
- if (pEntry1->m_pSrcMT == pEntry2->m_pSrcMT &&
- pEntry1->m_pDstMT == pEntry2->m_pDstMT)
- return TRUE;
-
- return FALSE;
-}
-
-CrossDomainFieldMap::FieldMapEntry::FieldMapEntry(MethodTable *pSrcMT, MethodTable *pDstMT, FieldDesc **pFieldMap)
-{
- WRAPPER_NO_CONTRACT;
-
- m_pSrcMT = pSrcMT;
- m_pDstMT = pDstMT;
- m_pFieldMap = pFieldMap;
- BaseDomain *pSrcDomain = pSrcMT->GetDomain();
- m_dwSrcDomain = pSrcDomain->IsAppDomain() ? ((AppDomain*)pSrcDomain)->GetId() : ADID(0);
- BaseDomain *pDstDomain = pDstMT->GetDomain();
- m_dwDstDomain = pDstDomain->IsAppDomain() ? ((AppDomain*)pDstDomain)->GetId() : ADID(0);
-}
-
-static BOOL IsOwnerOfRWLock(LPVOID lock)
-{
- // @TODO - SimpleRWLock does not have knowledge of which thread gets the writer
- // lock, so no way to verify
- return TRUE;
-}
-
-// Remove any entries in the table that refer to an appdomain that is no longer live.
-void CrossDomainFieldMap::FlushStaleEntries()
-{
- if (s_pFieldMapLock == NULL || s_pFieldMap == NULL)
- return;
-
- SimpleWriteLockHolder swlh(s_pFieldMapLock);
-
- bool fDeletedEntry = false;
- PtrHashMap::PtrIterator iter = s_pFieldMap->begin();
- while (!iter.end())
- {
- FieldMapEntry *pEntry = (FieldMapEntry *)iter.GetValue();
- AppDomainFromIDHolder adFrom(pEntry->m_dwSrcDomain, TRUE);
- AppDomainFromIDHolder adTo(pEntry->m_dwDstDomain, TRUE);
- if (adFrom.IsUnloaded() ||
- adTo.IsUnloaded()) //we do not use ptr for anything
- {
-#ifdef _DEBUG
- LPVOID pDeletedEntry =
-#endif
- s_pFieldMap->DeleteValue(pEntry->GetHash(), pEntry);
- _ASSERTE(pDeletedEntry == pEntry);
- delete pEntry;
- fDeletedEntry = true;
- }
- ++iter;
- }
-
- if (fDeletedEntry)
- s_pFieldMap->Compact();
-}
-
-FieldDesc **CrossDomainFieldMap::LookupOrCreateFieldMapping(MethodTable *pDstMT, MethodTable *pSrcMT)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END;
-
- // We lazily allocate the reader/writer lock we synchronize access to the hash with.
- if (s_pFieldMapLock == NULL)
- {
- void *pLockSpace = SystemDomain::GetGlobalLoaderAllocator()->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(SimpleRWLock)));
- SimpleRWLock *pLock = new (pLockSpace) SimpleRWLock(COOPERATIVE_OR_PREEMPTIVE, LOCK_TYPE_DEFAULT);
-
- if (FastInterlockCompareExchangePointer(&s_pFieldMapLock, pLock, NULL) != NULL)
- // We lost the race, give up our copy.
- SystemDomain::GetGlobalLoaderAllocator()->GetLowFrequencyHeap()->BackoutMem(pLockSpace, sizeof(SimpleRWLock));
- }
-
- // Now we have a lock we can use to synchronize the remainder of the init.
- if (s_pFieldMap == NULL)
- {
- SimpleWriteLockHolder swlh(s_pFieldMapLock);
-
- if (s_pFieldMap == NULL)
- {
- PtrHashMap *pMap = new (SystemDomain::GetGlobalLoaderAllocator()->GetLowFrequencyHeap()) PtrHashMap();
- LockOwner lock = {s_pFieldMapLock, IsOwnerOfRWLock};
- pMap->Init(32, CompareFieldMapEntry, TRUE, &lock);
- s_pFieldMap = pMap;
- }
- }
- else
- {
- // Try getting an existing value first.
-
- FieldMapEntry sEntry(pSrcMT, pDstMT, NULL);
-
- SimpleReadLockHolder srlh(s_pFieldMapLock);
- FieldMapEntry *pFound = (FieldMapEntry *)s_pFieldMap->LookupValue(sEntry.GetHash(), (LPVOID)&sEntry);
- if (pFound != (FieldMapEntry *)INVALIDENTRY)
- return pFound->m_pFieldMap;
- }
-
- // We couldn't find an existing entry in the hash. Now we must go through the painstaking process of matching fields in the
- // destination object to their counterparts in the source object. We build an array of pointers to source field descs ordered by
- // destination type field index (all the fields for the most derived type first, then all the fields for the second most derived
- // type etc.).
- NewArrayHolder<FieldDesc*> pFieldMap(new FieldDesc*[pDstMT->GetNumInstanceFields()]);
- DWORD dwMapIndex = 0;
-
- // We start with the source and destination types for the object (which we know are equivalent at least in type name). For each
- // layer of the type hierarchy for the destination object (from the instance type through to Object) we attempt to locate the
- // corresponding source type in the hierarchy. This is non-trivial since either source or destination type hierarchies may have
- // added or removed layers. We ignore extra type layers in the source hierarchy and just concentrate on destination type layers
- // that introduce instance fields that are not marked NotSerializable. For each such layer we first locate the corresponding
- // source layer (via fully qualified type name) and then map each serialized (and possibly optional) destination field to the
- // corresponding source field (again by name). We don't allow a field to move around the type hierarchy (i.e. a field defined in
- // the base class in one version can't move to a derived type in later versions and be recognized as the original field).
- // Allowing this would introduce all sorts of ambiguity problems (consider the case of private fields all with the same name
- // implemented at every layer of the type hierarchy).
-
- bool fFirstPass = true;
- MethodTable *pCurrDstMT = pDstMT;
- MethodTable *pCurrSrcMT = pSrcMT;
- while (pCurrDstMT)
- {
- DWORD numInstanceFields = pCurrDstMT->GetNumIntroducedInstanceFields();
-
- // Skip destination types with no instance fields to clone.
- if (numInstanceFields == 0)
- {
- pCurrDstMT = pCurrDstMT->GetParentMethodTable();
- // Only safe to skip the source type as well on the first pass (the source version may have eliminated this level of
- // the type hierarchy).
- if (fFirstPass)
- pCurrSrcMT = pCurrSrcMT->GetParentMethodTable();
- fFirstPass = false;
- continue;
- }
-
- // We need to synchronize the source type with the destination type. This means skipping any source types in the
- // hierarchy that the destination doesn't know about.
- MethodTable *pCandidateMT = pCurrSrcMT;
- while (pCandidateMT)
- {
- if (fFirstPass || pCandidateMT == pCurrDstMT || AreTypesEquivalent(pCandidateMT, pCurrDstMT))
- {
- // Skip intermediate source types (the destination type didn't know anything about them, so they're surplus
- // to requirements).
- pCurrSrcMT = pCandidateMT;
- break;
- }
-
- pCandidateMT = pCandidateMT->GetParentMethodTable();
- }
-
-#ifdef OBJECT_CLONER_STRICT_MODE
- // If there's no candidate source type equivalent to the current destination type we need to prove that the destination
- // type has no mandatory instance fields or throw an exception (since there's no place to fetch the field values from).
- if (pCandidateMT == NULL)
- {
- FieldDesc *pFields = pCurrDstMT->GetApproxFieldDescListRaw();
-
- for (DWORD i = 0; i < numInstanceFields; i++)
- {
- if (pFields[i].IsNotSerialized() || pFields[i].IsOptionallySerialized())
- {
- pFieldMap[dwMapIndex++] = NULL;
- continue;
- }
-
- // We've found a field that must be cloned but have no corresponding source-side type to clone it from. Raise an
- // exception.
- ThrowMissingFieldException(&pFields[i]);
- }
-
- // If we get here we know the current destination type level was effectively a no-op. Move onto the next level.
- pCurrDstMT = pCurrDstMT->GetParentMethodTable();
- fFirstPass = false;
- continue;
- }
-#else
- // In lax matching mode we can ignore all fields, even those not marked optional. So the lack of an equivalent type in the
- // source hierarchy doesn't bother us. Mark all fields as having a default value and then move onto the next level in the
- // type hierarchy.
- if (pCandidateMT == NULL)
- {
- for (DWORD i = 0; i < numInstanceFields; i++)
- pFieldMap[dwMapIndex++] = NULL;
-
- pCurrDstMT = pCurrDstMT->GetParentMethodTable();
- fFirstPass = false;
- continue;
- }
-#endif
-
- // If we get here we have equivalent types in pCurrDstMT and pCurrSrcMT. Now we need to locate the source field desc
- // corresponding to every mandatory (and possibly optional) field in the destination type and record it in the field map.
- DWORD numSrcFields = pCurrSrcMT->GetNumIntroducedInstanceFields();
- DWORD numDstFields = pCurrDstMT->GetNumIntroducedInstanceFields();
-
- FieldDesc *pDstFields = pCurrDstMT->GetApproxFieldDescListRaw();
- FieldDesc *pSrcFields = pCurrSrcMT->GetApproxFieldDescListRaw();
-
- for (DWORD i = 0; i < numDstFields; i++)
- {
- // Non-serialized destination fields aren't filled in from source types.
- if (pDstFields[i].IsNotSerialized())
- {
- pFieldMap[dwMapIndex++] = NULL;
- continue;
- }
-
- // Go look for a field in the source type with the same name.
- LPCUTF8 szDstFieldName = pDstFields[i].GetName();
- DWORD j;
- for (j = 0; j < numSrcFields; j++)
- {
- LPCUTF8 szSrcFieldName = pSrcFields[j].GetName();
- if (strcmp(szDstFieldName, szSrcFieldName) == 0)
- {
- // Check that the field isn't marked NotSerialized (if it is then it's invisible to the cloner).
- if (pSrcFields[j].IsNotSerialized())
- j = numSrcFields;
- break;
- }
- }
-
-#ifdef OBJECT_CLONER_STRICT_MODE
- // If we didn't find a corresponding field it might not be fatal; the field could be optionally serializable from the
- // destination type's point of view.
- if (j == numSrcFields)
- {
- if (pDstFields[i].IsOptionallySerialized())
- {
- pFieldMap[dwMapIndex++] = NULL;
- continue;
- }
- // The field was required. Throw an exception.
- ThrowMissingFieldException(&pDstFields[i]);
- }
-#else
- // In lax matching mode we can ignore all fields, even those not marked optional. Simply mark this field as having the
- // default value.
- if (j == numSrcFields)
- {
- pFieldMap[dwMapIndex++] = NULL;
- continue;
- }
-#endif
-
- // Otherwise we found matching fields (in name at least, type processing is done later).
- pFieldMap[dwMapIndex++] = &pSrcFields[j];
- }
-
- pCurrDstMT = pCurrDstMT->GetParentMethodTable();
- pCurrSrcMT = pCurrSrcMT->GetParentMethodTable();
- fFirstPass = false;
- }
-
- _ASSERTE(dwMapIndex == pDstMT->GetNumInstanceFields());
-
- // Now we have a field map we should insert it into the hash.
- NewHolder<FieldMapEntry> pEntry(new FieldMapEntry(pSrcMT, pDstMT, pFieldMap));
- PREFIX_ASSUME(pEntry != NULL);
- pFieldMap.SuppressRelease();
-
- SimpleWriteLockHolder swlh(s_pFieldMapLock);
-
- UPTR key = pEntry->GetHash();
-
- FieldMapEntry *pFound = (FieldMapEntry *)s_pFieldMap->LookupValue(key, (LPVOID)pEntry);
- if (pFound == (FieldMapEntry *)INVALIDENTRY)
- {
- s_pFieldMap->InsertValue(key, (LPVOID)pEntry);
- pEntry.SuppressRelease();
- return pFieldMap;
- }
- else
- return pFound->m_pFieldMap;
-}
-
-ARG_SLOT ObjectClone::HandleFieldTypeMismatch(CorElementType dstType, CorElementType srcType, void *pData, MethodTable *pSrcMT)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END
- _ASSERTE(m_context != ObjectFreezer);
- ARG_SLOT data = 0;
- InvokeUtil::CreatePrimitiveValue(dstType, srcType, pData, pSrcMT, &data);
- return data;
-}
-
-void ObjectClone::ScanISerializableMembers(DWORD IObjRefTSOIndex, DWORD ISerTSOIndex, DWORD BoxedValTSOIndex, PTRARRAYREF refValues)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END
-
- _ASSERTE(m_context != ObjectFreezer);
- // Queue the non-primitive types
- DWORD numFieldsToBeMarshalled = 0;
- PTRARRAYREF refNewValues = NULL;
-
- LOG((LF_REMOTING, LL_INFO1000, "ScanISerializableMembers. Scanning members of ISerializable type object.\n"));
- GCPROTECT_BEGIN(refValues);
-
- refNewValues = (PTRARRAYREF) AllocateObjectArray(refValues->GetNumComponents(), g_pObjectClass, FALSE);
-
- _ASSERTE(refNewValues != NULL);
-
- for (DWORD index = 0; index < refValues->GetNumComponents(); index++)
- {
- OBJECTREF refField = refValues->GetAt(index);
- if (refField == NULL)
- continue;
-
- if (CorTypeInfo::IsPrimitiveType(refField->GetTypeHandle().GetSignatureCorElementType()) ||
- refField->GetMethodTable() == g_pStringClass)
- {
- refNewValues->SetAt(index, refField);
- continue;
- }
-
- ISerializableMemberInfo isInfo(ISerTSOIndex, index);
- QOM.Enqueue(refField, NULL, NULL, (QueuedObjectInfo *) &isInfo);
- numFieldsToBeMarshalled++;
- refNewValues->SetAt(index, NULL);
- LOG((LF_REMOTING, LL_INFO1000, "ScanISerializableMembers. Member at index %d is reference type. Adding to QOM.\n", index));
- }
- GCPROTECT_END();
-
- // Update TSO
- OBJECTREF refNames = NULL, refFields = NULL;
- QueuedObjectInfo *pDummy;
- OBJECTREF newObj;
- newObj = TSO.GetAt(ISerTSOIndex, &refNames, &refFields, &pDummy);
- _ASSERTE(newObj == m_newObject);
-
- TSO.SetAt(ISerTSOIndex, m_newObject, refNames, refNewValues, pDummy);
-
- if (numFieldsToBeMarshalled > 0)
- {
- ParentInfo fxInfo(numFieldsToBeMarshalled);
- fxInfo.SetIsISerializableInstance();
- fxInfo.SetIObjRefIndexIntoTSO(IObjRefTSOIndex);
- fxInfo.SetISerIndexIntoTSO(ISerTSOIndex);
- fxInfo.SetBoxedValIndexIntoTSO(BoxedValTSOIndex);
- QOF.Enqueue(m_newObject, NULL, NULL, (QueuedObjectInfo *) &fxInfo);
- LOG((LF_REMOTING, LL_INFO1000, "ScanISerializableMembers. Current object had total of %d reference type fields. Adding to QOF.\n", numFieldsToBeMarshalled));
- // Delay calling any OnDeserialized callbacks until the end of the cloning operation (it's difficult to tell when all the
- // children have been deserialized).
- if (HasVtsCallbacks(m_newObject->GetMethodTable(), RemotingVtsInfo::VTS_CALLBACK_ON_DESERIALIZED))
- VDC.Enqueue(m_newObject, NULL, NULL, NULL);
- if (m_cbInterface->RequiresDeserializationCallback(m_newObject->GetMethodTable()))
- {
- LOG((LF_REMOTING, LL_INFO1000, "ScanISerializableMembers. Adding object to Table of IDeserialization Callbacks\n"));
- QueuedObjectInfo noInfo;
- TDC.Enqueue(m_newObject, NULL, NULL, &noInfo);
- }
- }
- else
- {
- // This is effectively a leaf node (no complex children) so if the type has a callback for OnDeserialized we'll deliver it
- // now. This fixes callback ordering for a few more edge cases (e.g. VSW 415611) and is reasonably cheap. We can never do a
- // perfect job (in the presence of object graph cycles) and a near perfect job (intuitively ordered callbacks for acyclic
- // object graphs) is prohibitively expensive; so we're stuck with workarounds like this.
- InvokeVtsCallbacks(m_newObject, RemotingVtsInfo::VTS_CALLBACK_ON_DESERIALIZED, m_toDomain);
- if (m_cbInterface->RequiresDeserializationCallback(m_newObject->GetMethodTable()))
- MakeIDeserializationCallback(m_newObject);
- }
-}
-
-void ObjectClone::ScanArrayMembers()
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END
-#ifdef _DEBUG
- MethodTable *pCurrMT = m_currObject->GetMethodTable();
- _ASSERTE(pCurrMT && pCurrMT->IsArray());
- MethodTable *pNewMT = m_newObject->GetMethodTable();
- _ASSERTE(pNewMT && pNewMT->IsArray());
-#endif
-
- LOG((LF_REMOTING, LL_INFO1000, "ScanArrayMembers. Scanning members of array object.\n"));
- BASEARRAYREF refFromArray = (BASEARRAYREF) m_currObject;
- BASEARRAYREF refToArray = (BASEARRAYREF) m_newObject;
-
- GCPROTECT_BEGIN(refFromArray);
- GCPROTECT_BEGIN(refToArray);
-
- TypeHandle toArrayElementType = refToArray->GetArrayElementTypeHandle();
- DWORD numComponents = refFromArray->GetNumComponents();
- MethodTable *pArrayMT = refFromArray->GetMethodTable();
-
- DWORD rank = pArrayMT->GetRank();
- DWORD dwOffset = 0;
-
- DWORD *pIndices = (DWORD*) _alloca(sizeof(DWORD) * rank);
- VOID *pTemp = _alloca(sizeof(NDimArrayMemberInfo) + rank * sizeof(DWORD));
- NDimArrayMemberInfo *pArrInfo = new (pTemp) NDimArrayMemberInfo(rank);
-
- bool boxingObjects = (pArrayMT->GetArrayElementType() == ELEMENT_TYPE_VALUETYPE);
-
- // Must enter the from domain if we are going to be allocating any non-agile boxes
- ENTER_DOMAIN_PTR_PREDICATED(m_fromDomain,ADV_RUNNINGIN,boxingObjects);
-
- if (boxingObjects)
- {
- pArrInfo->SetNeedsUnboxing();
-
- // We may be required to activate value types of array elements, since we
- // are going to box them. Hoist out the required domain transition and
- // activation.
-
- MethodTable *pMT = ((BASEARRAYREF)m_currObject)->GetArrayElementTypeHandle().GetMethodTable();
- pMT->EnsureInstanceActive();
- }
-
- DWORD numFixupsNeeded = 0;
- for (DWORD i = 0; i < numComponents; i++)
- {
- // The array could be huge. To avoid keeping a pending GC waiting (and maybe timing out) we're going to pulse the GC mode
- // every so often. Do this more freqeuntly in debug builds, where each iteration through this loop takes considerably
- // longer.
-#ifdef _DEBUG
-#define COPY_CYCLES 1024
-#else
-#define COPY_CYCLES 8192
-#endif
- if ((i % COPY_CYCLES) == (COPY_CYCLES - 1))
- GetThread()->PulseGCMode();
-
- const INT32 *pBoundsPtr = refFromArray->GetBoundsPtr();
- DWORD findIndices = i;
- for (DWORD rankIndex = rank; rankIndex > 0; rankIndex--)
- {
- DWORD numElementsInDimension = pBoundsPtr[rankIndex - 1];
- DWORD quotient = findIndices / numElementsInDimension;
- DWORD remainder = findIndices % numElementsInDimension;
- pIndices[rankIndex - 1] = remainder;
- findIndices = quotient;
- }
-
- pArrInfo->SetIndices(pIndices);
-
- Object *rv = GetObjectFromArray((BASEARRAYREF *)&m_currObject, dwOffset);
- if (rv != NULL)
- {
- OBJECTREF oRef = ObjectToOBJECTREF(rv);
-
- if (oRef->GetMethodTable() == g_pStringClass && m_context != ObjectFreezer)
- {
- OBJECTREF* pElem = (OBJECTREF*)(refToArray->GetDataPtr() + (dwOffset * pArrayMT->GetComponentSize()));
- SetObjectReference(pElem,oRef,GetAppDomain());
- }
- else
- {
- // Add the object to QOM
- numFixupsNeeded++;
- QOM.Enqueue(oRef, NULL, NULL, pArrInfo);
- LOG((LF_REMOTING, LL_INFO1000, "ScanArrayMembers. Element at offset %d is reference type. Adding to QOM.\n", dwOffset));
- }
- }
- dwOffset ++;
- }
-
- if (numFixupsNeeded > 0)
- {
- ParentInfo fxInfo(numFixupsNeeded);
- QOF.Enqueue(m_newObject, NULL, NULL, (QueuedObjectInfo *)&fxInfo);
- LOG((LF_REMOTING, LL_INFO1000, "ScanArrayMembers. Current object had total of %d reference type fields. Adding to QOF.\n", numFixupsNeeded));
- }
-
- END_DOMAIN_TRANSITION;
-
- GCPROTECT_END();
- GCPROTECT_END();
-}
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable:4244)
-#endif // _MSC_VER
-Object *ObjectClone::GetObjectFromArray(BASEARRAYREF* arrObj, DWORD dwOffset)
-{
- CONTRACTL {
- THROWS;
- if ((*arrObj)->GetArrayElementTypeHandle().GetMethodTable()->IsValueType()) GC_TRIGGERS; else GC_NOTRIGGER;
- } CONTRACTL_END;
-
- // Get the type of the element...
- switch ((*arrObj)->GetArrayElementType()) {
-
- case ELEMENT_TYPE_VOID:
- return NULL;
-
- case ELEMENT_TYPE_CLASS: // Class
- case ELEMENT_TYPE_SZARRAY: // Single Dim, Zero
- case ELEMENT_TYPE_ARRAY: // General Array
- case ELEMENT_TYPE_STRING:
- case ELEMENT_TYPE_OBJECT:
- {
- _ASSERTE((*arrObj)->GetComponentSize() == sizeof(OBJECTREF));
- BYTE* pData = ((BYTE*)(*arrObj)->GetDataPtr()) + (dwOffset * sizeof(OBJECTREF));
- return *(Object **)pData;
- }
-
- case ELEMENT_TYPE_VALUETYPE:
- {
- MethodTable *pMT = (*arrObj)->GetArrayElementTypeHandle().GetMethodTable();
- WORD wComponentSize = (*arrObj)->GetComponentSize();
- BYTE* pData = ((BYTE*)(*arrObj)->GetDataPtr()) + (dwOffset * wComponentSize);
- return OBJECTREFToObject(pMT->Box(pData));
- }
- case ELEMENT_TYPE_BOOLEAN: // boolean
- case ELEMENT_TYPE_I1: // sbyte
- case ELEMENT_TYPE_U1:
- case ELEMENT_TYPE_I2: // short
- case ELEMENT_TYPE_U2:
- case ELEMENT_TYPE_CHAR: // char
- case ELEMENT_TYPE_I4: // int
- case ELEMENT_TYPE_I:
- case ELEMENT_TYPE_U:
- case ELEMENT_TYPE_U4:
- case ELEMENT_TYPE_I8: // long
- case ELEMENT_TYPE_U8:
- case ELEMENT_TYPE_R4: // float
- case ELEMENT_TYPE_R8: // double
- case ELEMENT_TYPE_PTR:
- {
- // Note that this is a cloned version of the value class case above for performance
-
- // Watch for GC here. We allocate the object and then
- // grab the void* to the data we are going to copy.
- MethodTable *pMT = (*arrObj)->GetArrayElementTypeHandle().GetMethodTable();
- OBJECTREF obj = ::AllocateObject(pMT);
- WORD wComponentSize = (*arrObj)->GetComponentSize();
- BYTE* pData = ((BYTE*)(*arrObj)->GetDataPtr()) + (dwOffset * wComponentSize);
- CopyValueClassUnchecked(obj->UnBox(), pData, (*arrObj)->GetArrayElementTypeHandle().GetMethodTable());
- return OBJECTREFToObject(obj);
- }
-
- case ELEMENT_TYPE_END:
- default:
- _ASSERTE(!"Unknown array element type");
- }
-
- _ASSERTE(!"Should never get here");
- return NULL;
-}
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif // _MSC_VER: warning C4244
-
-
-void ObjectClone::CompleteValueTypeFields(OBJECTREF newObj, OBJECTREF refParent, QueuedObjectInfo *objInfo)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- }
- CONTRACTL_END
-
-#ifdef _DEBUG
- {
- SString ssTypeName;
- SString ssParentTypeName;
- newObj->GetMethodTable()->_GetFullyQualifiedNameForClassNestedAware(ssTypeName);
- refParent->GetMethodTable()->_GetFullyQualifiedNameForClassNestedAware(ssParentTypeName);
- LOG((LF_REMOTING, LL_INFO1000, "CompleteValueTypeFields. Fixing up value type field of type %S into parent of type %S.\n",
- ssTypeName.GetUnicode(), ssParentTypeName.GetUnicode()));
- }
-#endif
-
- ValueTypeInfo *pValTypeInfo = (ValueTypeInfo *)objInfo;
- QueuedObjectInfo *pFixupInfo = pValTypeInfo->GetFixupInfo();
- PREFIX_ASSUME(pFixupInfo != NULL);
-
- _ASSERTE(pFixupInfo->NeedsUnboxing());
- if (pFixupInfo->IsArray())
- {
- m_newObject = newObj;
- HandleArrayFixup(refParent, pFixupInfo);
- }
- else
- {
- GCPROTECT_BEGIN(refParent);
- GCPROTECT_BEGIN(newObj);
- ObjectMemberInfo *pObjInfo = (ObjectMemberInfo *)pFixupInfo;
- FieldDesc *pTargetField = pObjInfo->GetFieldDesc();
-
- TypeHandle fldType = LoadExactFieldType(pTargetField, refParent, m_toDomain);
- void *pDest = refParent->GetData() + pTargetField->GetOffset();
- _ASSERTE(GetAppDomain()==m_toDomain);
-
- if (!fldType.GetMethodTable()->UnBoxInto(pDest, newObj))
- COMPlusThrow(kArgumentException,W("Arg_ObjObj"));
-
- GCPROTECT_END();
- GCPROTECT_END();
- }
- pValTypeInfo->SetHasBeenProcessed();
-}
-
-void ObjectClone::CompleteSpecialObjects()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- OBJECTREF nextObj = NULL;
- OBJECTREF refNames = NULL;
- OBJECTREF refValues = NULL;
- SpecialObjectInfo *pObjInfo = NULL;
-
- GCPROTECT_BEGIN(refNames);
- GCPROTECT_BEGIN(refValues);
-
- DWORD skippedObjects = 0;
- DWORD numLoops = 0;
-
- if (TSO.GetCount() == 0)
- goto EarlyExit;
-
- LOG((LF_REMOTING, LL_INFO1000, "CompleteSpecialObjects. Beginning.\n"));
- do
- {
- skippedObjects = 0;
- numLoops++;
- DWORD index = 0;
- TSO.BeginEnumeration(&index);
- while((nextObj = TSO.GetNext(&index, &refNames, &refValues, (QueuedObjectInfo **)&pObjInfo)) != NULL)
- {
- if (pObjInfo->HasBeenProcessed())
- continue;
-
- if (pObjInfo->IsISerializableInstance())
- {
- _ASSERTE(m_context != ObjectFreezer);
-
- LOG((LF_REMOTING, LL_INFO1000, "CompleteSpecialObjects. ISerializable instance at index %d.\n", index));
- ISerializableInstanceInfo *iserInfo = (ISerializableInstanceInfo *)pObjInfo;
- if (iserInfo->GetNumSpecialMembers() > 0)
- {
- if (CheckForUnresolvedMembers(iserInfo))
- {
- LOG((LF_REMOTING, LL_INFO1000, "CompleteSpecialObjects. Skipping ISerializable instance due to unresolved members.\n"));
- skippedObjects++;
- continue;
- }
- }
- CompleteISerializableObject(nextObj, refNames, refValues, iserInfo);
- }
- else if (pObjInfo->IsIObjRefInstance())
- {
- _ASSERTE(m_context != ObjectFreezer);
-
- LOG((LF_REMOTING, LL_INFO1000, "CompleteSpecialObjects. IObjectReference instance at index %d.\n", index));
- IObjRefInstanceInfo *iorInfo = (IObjRefInstanceInfo *)pObjInfo;
- if (iorInfo->GetNumSpecialMembers() > 0 ||
- iorInfo->GetISerTSOIndex() != (DWORD) -1)
- {
- if (CheckForUnresolvedMembers(iorInfo))
- {
- LOG((LF_REMOTING, LL_INFO1000, "CompleteSpecialObjects. Skipping IObjectReference instance due to unresolved members.\n"));
- skippedObjects++;
- continue;
- }
- }
- if (!CompleteIObjRefObject(nextObj, index, iorInfo))
- skippedObjects++;
- }
- else
- {
- _ASSERTE(pObjInfo->IsBoxedObject());
- LOG((LF_REMOTING, LL_INFO1000, "CompleteSpecialObjects. Boxed valuetype instance at index %d.\n", index));
- ValueTypeInfo *valTypeInfo = (ValueTypeInfo *)pObjInfo;
- if (valTypeInfo->GetNumSpecialMembers() > 0 ||
- valTypeInfo->GetISerTSOIndex() != (DWORD) -1 ||
- valTypeInfo->GetIObjRefTSOIndex() != (DWORD) -1)
- {
- if (CheckForUnresolvedMembers(valTypeInfo))
- {
- LOG((LF_REMOTING, LL_INFO1000, "CompleteSpecialObjects. Skipping boxed value instance due to unresolved members.\n"));
- skippedObjects++;
- continue;
- }
- }
- // If we were waiting on an IObjRef fixup then the target object will have changed.
- if (valTypeInfo->GetIObjRefTSOIndex() != (DWORD) -1)
- {
- OBJECTREF dummy1, dummy2;
- QueuedObjectInfo *dummy3;
- nextObj = TSO.GetAt(valTypeInfo->GetIObjRefTSOIndex(), &dummy1, &dummy2, &dummy3);
- }
- CompleteValueTypeFields(nextObj, refNames, valTypeInfo);
- }
-
- };
- } while (skippedObjects > 0 && numLoops < 100);
-
- if (skippedObjects > 0 && numLoops >= 100)
- {
- COMPlusThrow(kSerializationException, IDS_SERIALIZATION_UNRESOLVED_SPECIAL_OBJECT);
- }
-EarlyExit: ;
- GCPROTECT_END();
- GCPROTECT_END();
-}
-
-BOOL ObjectClone::CheckForUnresolvedMembers(SpecialObjectInfo *splInfo)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- BOOL foundUnresolvedMember = FALSE;
-
- DWORD mappingIndex = splInfo->GetMappingTableIndex();
- for (DWORD count = 0; count < splInfo->GetNumSpecialMembers(); count++)
- {
- DWORD memberIndex = TMappings.GetAt(mappingIndex++);
- SpecialObjectInfo *pMemberInfo;
- OBJECTREF dummy1, dummy2, dummy3;
- dummy1 = TSO.GetAt(memberIndex, &dummy2, &dummy3, (QueuedObjectInfo **)&pMemberInfo);
- // An unresolved IObjRef member is a blocker for any special object parent
- if (pMemberInfo->IsIObjRefInstance() && !pMemberInfo->HasBeenProcessed())
- {
- LOG((LF_REMOTING, LL_INFO1000, "CheckForUnresolvedMembers. Found unresolved IObjectReference member at index %d.\n", memberIndex));
- foundUnresolvedMember = TRUE;
- break;
- }
-
- // An unresolved ISer member is a blocker for IObjRef parent
- if (pMemberInfo->IsISerializableInstance() &&
- !pMemberInfo->HasBeenProcessed() &&
- splInfo->IsIObjRefInstance())
- {
- LOG((LF_REMOTING, LL_INFO1000, "CheckForUnresolvedMembers. Found unresolved ISerializable member at index %d.\n", memberIndex));
- foundUnresolvedMember = TRUE;
- break;
- }
-
- // An unresolved boxed object is a blocker for a boxed parent or an IObjRef parent
- if (pMemberInfo->IsBoxedObject() &&
- !pMemberInfo->HasBeenProcessed() &&
- (splInfo->IsIObjRefInstance() || splInfo->IsBoxedObject()))
- {
- LOG((LF_REMOTING, LL_INFO1000, "CheckForUnresolvedMembers. Found unresolved boxed valuetype member at index %d.\n", memberIndex));
- foundUnresolvedMember = TRUE;
- break;
- }
- }
-
- // Done checking members. Now check if this instance itself needs some processing
- // If an instance is both ISer and IObj, then ISer should be processed before IObjRef
- if (!foundUnresolvedMember && splInfo->IsIObjRefInstance())
- {
- IObjRefInstanceInfo *pObjRefInfo = (IObjRefInstanceInfo *)splInfo;
- if (pObjRefInfo->GetISerTSOIndex() != (DWORD) -1)
- {
- // Check if the ISer requirements have been met
- SpecialObjectInfo *pMemberInfo;
- OBJECTREF dummy1, dummy2, dummy3;
- dummy1 = TSO.GetAt(pObjRefInfo->GetISerTSOIndex(), &dummy2, &dummy3, (QueuedObjectInfo **)&pMemberInfo);
- if (!pMemberInfo->HasBeenProcessed())
- {
- LOG((LF_REMOTING, LL_INFO1000, "CheckForUnresolvedMembers. This instance is also ISerializable at index %d. Not resolved yet.\n", pObjRefInfo->GetISerTSOIndex()));
- foundUnresolvedMember = TRUE;
- }
- }
- }
-
- // If an instance is ISer, IObj and a boxed value type, then ISer,IObj should be processed before unboxing
- if (!foundUnresolvedMember && splInfo->IsBoxedObject())
- {
- ValueTypeInfo *pValTypeInfo = (ValueTypeInfo *)splInfo;
- if (pValTypeInfo->GetISerTSOIndex() != (DWORD) -1)
- {
- // Check if the ISer requirements have been met
- SpecialObjectInfo *pMemberInfo;
- OBJECTREF dummy1, dummy2, dummy3;
- dummy1 = TSO.GetAt(pValTypeInfo->GetISerTSOIndex(), &dummy2, &dummy3, (QueuedObjectInfo **)&pMemberInfo);
- if (!pMemberInfo->HasBeenProcessed())
- {
- LOG((LF_REMOTING, LL_INFO1000, "CheckForUnresolvedMembers. This instance is also ISerializable at index %d. Not resolved yet.\n", pValTypeInfo->GetISerTSOIndex()));
- foundUnresolvedMember = TRUE;
- }
- }
- if (!foundUnresolvedMember && pValTypeInfo->GetIObjRefTSOIndex() != (DWORD) -1)
- {
- // Check if the ISer requirements have been met
- SpecialObjectInfo *pMemberInfo;
- OBJECTREF dummy1, dummy2, dummy3;
- dummy1 = TSO.GetAt(pValTypeInfo->GetIObjRefTSOIndex(), &dummy2, &dummy3, (QueuedObjectInfo **)&pMemberInfo);
- if (!pMemberInfo->HasBeenProcessed())
- {
- LOG((LF_REMOTING, LL_INFO1000, "CheckForUnresolvedMembers. This instance is also IObjectReference at index %d. Not resolved yet.\n", pValTypeInfo->GetIObjRefTSOIndex()));
- foundUnresolvedMember = TRUE;
- }
- }
- }
- return foundUnresolvedMember;
-}
-
-void ObjectClone::CompleteISerializableObject(OBJECTREF IserObj, OBJECTREF refNames, OBJECTREF refValues, ISerializableInstanceInfo *iserInfo)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
-
- _ASSERTE(m_context != ObjectFreezer);
-
- struct _gc {
- OBJECTREF IserObj;
- OBJECTREF refNames;
- OBJECTREF refValues;
- OBJECTREF refSerInfo;
- } gc;
-
- gc.IserObj = IserObj;
- gc.refNames = refNames;
- gc.refValues = refValues;
- gc.refSerInfo = NULL;
-
- GCPROTECT_BEGIN(gc);
-
-#ifdef _DEBUG
- {
- DefineFullyQualifiedNameForClass();
- LOG((LF_REMOTING, LL_INFO1000, "CompleteISerializableObject. Completing ISerializable object of type %s.\n",
- GetFullyQualifiedNameForClassNestedAware(gc.IserObj->GetMethodTable())));
- }
-#endif
-
- BOOL bIsBoxed = gc.IserObj->GetMethodTable()->IsValueType();
-
- // StreamingContextData is an out parameter of the managed callback, so it's passed by reference on all platforms.
- RuntimeMethodHandle::StreamingContextData context = {0};
-
- PREPARE_NONVIRTUAL_CALLSITE(METHOD__OBJECTCLONEHELPER__PREPARE_DATA);
-
- DECLARE_ARGHOLDER_ARRAY(args, 4);
-
- args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(gc.IserObj);
- args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(gc.refNames);
- args[ARGNUM_2] = OBJECTREF_TO_ARGHOLDER(gc.refValues);
- args[ARGNUM_3] = PTR_TO_ARGHOLDER(&context);
-
- CATCH_HANDLER_FOUND_NOTIFICATION_CALLSITE;
- CALL_MANAGED_METHOD_RETREF(gc.refSerInfo, OBJECTREF, args);
-
- if (iserInfo->IsTargetNotISerializable())
- {
- // Prepare data would have constructed the object already
- _ASSERTE(gc.refSerInfo == NULL);
- }
- else
- {
- _ASSERTE(gc.refSerInfo != NULL);
- MethodTable *pMT = gc.IserObj->GetMethodTable();
- _ASSERTE(pMT);
-
- MethodDesc * pCtor;
-
-#ifdef FEATURE_IMPERSONATION
- // Deal with the WindowsIdentity class specially by calling an internal
- // serialization constructor; the public one has a security demand that
- // breaks partial trust scenarios and is too expensive to assert for.
- if (MscorlibBinder::IsClass(pMT, CLASS__WINDOWS_IDENTITY))
- pCtor = MscorlibBinder::GetMethod(METHOD__WINDOWS_IDENTITY__SERIALIZATION_CTOR);
- else
-#endif
- pCtor = MemberLoader::FindConstructor(pMT, &gsig_IM_SerInfo_StrContext_RetVoid);
-
- if (pCtor == NULL)
- {
- DefineFullyQualifiedNameForClassW();
- COMPlusThrow(kSerializationException, IDS_SERIALIZATION_CTOR_NOT_FOUND,
- GetFullyQualifiedNameForClassNestedAwareW(pMT));
- }
-
- MethodDescCallSite ctor(pCtor);
-
- ARG_SLOT argSlots[3];
- // Nullable<T> does not implement ISerializable.
- _ASSERTE(!Nullable::IsNullableType(gc.IserObj->GetMethodTable()));
- argSlots[0] = (bIsBoxed ? (ARG_SLOT)(SIZE_T)(gc.IserObj->UnBox()) : ObjToArgSlot(gc.IserObj));
- argSlots[1] = ObjToArgSlot(gc.refSerInfo);
-#if defined(_TARGET_X86_) || defined(_TARGET_ARM_)
- static_assert_no_msg(sizeof(context) == sizeof(ARG_SLOT));
- argSlots[2] = *(ARG_SLOT*)(&context); // StreamingContext is passed by value on x86 and ARM
-#elif defined(_WIN64)
- static_assert_no_msg(sizeof(context) > sizeof(ARG_SLOT));
- argSlots[2] = PtrToArgSlot(&context); // StreamingContext is passed by reference on WIN64
-#else // !_TARGET_X86_ && !_WIN64 && !_TARGET_ARM_
- PORTABILITY_ASSERT("ObjectClone::CompleteISerializableObject() - NYI on this platform");
-#endif // !_TARGET_X86_ && !_WIN64 && !_TARGET_ARM_
- ctor.CallWithValueTypes(&argSlots[0]);
- }
- iserInfo->SetHasBeenProcessed();
-
- GCPROTECT_END();
-
-}
-
-// FALSE means the object could not be resolved and need to perform more iterations
-BOOL ObjectClone::CompleteIObjRefObject(OBJECTREF IObjRef, DWORD tsoIndex, IObjRefInstanceInfo *iorInfo)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
-
- BOOL bResult = FALSE;
-
- struct _gc {
- OBJECTREF IObjRef;
- OBJECTREF newObj;
- OBJECTREF refParent;
- OBJECTREF refFromObj;
- OBJECTREF resolvedObject;
- } gc;
-
- gc.IObjRef = IObjRef;
- gc.newObj = NULL;
- gc.refParent = NULL;
- gc.refFromObj = NULL;
- gc.resolvedObject = NULL;
-
- GCPROTECT_BEGIN(gc);
-
- _ASSERTE(m_context != ObjectFreezer);
- // First check if this is a repeat object
- if (iorInfo->IsRepeatObject())
- {
- OBJECTREF dummy;
- dummy = TSO.GetAt(tsoIndex, &gc.refFromObj, &gc.refParent, (QueuedObjectInfo **)&iorInfo);
- PREFIX_ASSUME(gc.refFromObj != NULL);
-
- // Look in the Table of Seen objects whether this IObjRef has been resolved
- int currId;
- currId = TOS.HasID(gc.refFromObj, &gc.resolvedObject);
- _ASSERTE(currId != -1);
-
- MethodTable *pResolvedMT = gc.resolvedObject->GetMethodTable();
- if (!pResolvedMT->IsTransparentProxy() &&
- m_cbInterface->IsIObjectReferenceType(pResolvedMT))
- {
- bResult = FALSE;
- }
- else
- {
-#ifdef _DEBUG
- {
- DefineFullyQualifiedNameForClass();
- LOG((LF_REMOTING, LL_INFO1000, "CompleteIObjRefObject. Found IObjectReference object of type %s already resolved.\n",
- GetFullyQualifiedNameForClassNestedAware(gc.IObjRef->GetMethodTable())));
- }
-#endif
-
- // Yes, its been resolved.
- // Fix the object into its parent (unless it requires unboxing, in which case there's another entry in the TSO ready to
- // do that).
- QueuedObjectInfo *pFixupInfo = (QueuedObjectInfo *)iorInfo->GetFixupInfo();
- PREFIX_ASSUME(pFixupInfo != NULL);
- if (pFixupInfo->NeedsUnboxing())
- {
- TSO.SetAt(tsoIndex, gc.resolvedObject, gc.refFromObj, gc.refParent, iorInfo);
- iorInfo->SetHasBeenProcessed();
- bResult = TRUE;
- }
- else
- {
- if (gc.refParent == NULL)
- m_topObject = gc.resolvedObject;
- else
- {
- m_newObject = gc.resolvedObject;
- if (pFixupInfo->NeedsUnboxing())
- CompleteValueTypeFields(gc.resolvedObject, gc.refParent, pFixupInfo);
- else
- Fixup(gc.resolvedObject, gc.refParent, pFixupInfo);
- }
- iorInfo->SetHasBeenProcessed();
- bResult = TRUE;
- }
- }
- }
- else
- {
- MethodTable *pMT = gc.IObjRef->GetMethodTable();
- _ASSERTE(pMT);
-
- MethodTable *pItf = MscorlibBinder::GetClass(CLASS__IOBJECTREFERENCE);
- MethodDesc *pMeth = GetInterfaceMethodImpl(pMT, pItf, 0);
- MethodDescCallSite method(pMeth, &gc.IObjRef);
-
- // Ensure Streamingcontext type is loaded. Do not delete this line
- MethodTable *pMTStreamingContext;
- pMTStreamingContext = MscorlibBinder::GetClass(CLASS__STREAMING_CONTEXT);
- _ASSERTE(pMTStreamingContext);
-
- ARG_SLOT arg[2];
- arg[0] = ObjToArgSlot(gc.IObjRef);
-
- RuntimeMethodHandle::StreamingContextData context = { NULL, GetStreamingContextState() };
-#ifdef _WIN64
- static_assert_no_msg(sizeof(context) > sizeof(ARG_SLOT));
- arg[1] = PtrToArgSlot(&context);
-#else
- static_assert_no_msg(sizeof(context) <= sizeof(ARG_SLOT));
- arg[1] = *(ARG_SLOT*)(&context);
-#endif
-
- gc.newObj = method.CallWithValueTypes_RetOBJECTREF(&arg[0]);
-
- INDEBUG(DefineFullyQualifiedNameForClass();)
-
- _ASSERTE(gc.newObj != NULL);
- MethodTable *pNewMT = gc.newObj->GetMethodTable();
- if (!pNewMT->IsTransparentProxy() &&
- gc.newObj != gc.IObjRef &&
- m_cbInterface->IsIObjectReferenceType(pNewMT))
- {
-#ifdef _DEBUG
- LOG((LF_REMOTING, LL_INFO1000,
- "CompleteIObjRefObject. GetRealObject on object of type %s returned another IObjectReference. Adding back to TSO.\n",
- GetFullyQualifiedNameForClassNestedAware(gc.IObjRef->GetMethodTable())));
-#endif
-
- // Put this back into the table
- OBJECTREF dummy;
- dummy = TSO.GetAt(tsoIndex, &gc.refFromObj, &gc.refParent, (QueuedObjectInfo **)&iorInfo);
- TSO.SetAt(tsoIndex, gc.newObj, gc.refFromObj, gc.refParent, iorInfo);
- bResult = FALSE;
- }
- else
- {
-#ifdef _DEBUG
- LOG((LF_REMOTING, LL_INFO1000,
- "CompleteIObjRefObject. Called GetRealObject on object of type %s. Fixing it up into its parent.\n",
- GetFullyQualifiedNameForClassNestedAware(gc.IObjRef->GetMethodTable())));
-#endif
- // Fix the object into its parent (unless it requires unboxing, in which case there's another entry in the TSO ready to
- // do that).
- QueuedObjectInfo *pFixupInfo = (QueuedObjectInfo *)iorInfo->GetFixupInfo();
- OBJECTREF dummy;
- dummy = TSO.GetAt(tsoIndex, &gc.refFromObj, &gc.refParent, (QueuedObjectInfo **)&iorInfo);
- if (pFixupInfo->NeedsUnboxing())
- {
- TSO.SetAt(tsoIndex, gc.newObj, gc.refFromObj, gc.refParent, iorInfo);
- iorInfo->SetHasBeenProcessed();
- bResult = TRUE;
- }
- else
- {
- if (gc.refParent == NULL)
- m_topObject = gc.newObj;
- else
- {
- m_newObject = gc.newObj;
- Fixup(gc.newObj, gc.refParent, pFixupInfo);
- }
-
- // Update Table of Seen objects, so that any repeat objects can be updated too
- TOS.UpdateObject(gc.refFromObj, gc.newObj);
- iorInfo->SetHasBeenProcessed();
- bResult = TRUE;
- }
- }
- }
-
- GCPROTECT_END();
- return bResult;
-}
-
-void MakeIDeserializationCallback(OBJECTREF refTarget)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END;
-
- struct _gc {
- OBJECTREF refTarget;
- } gc;
- gc.refTarget = refTarget;
-
- GCPROTECT_BEGIN(gc);
-
- MethodTable *pMT = gc.refTarget->GetMethodTable();
- _ASSERTE(pMT);
-
- MethodTable *pItf = MscorlibBinder::GetClass(CLASS__IDESERIALIZATIONCB);
- MethodDesc *pMeth = GetInterfaceMethodImpl(pMT, pItf, 0);
- PCODE pCode = pMeth->GetSingleCallableAddrOfCode();
-
- PREPARE_NONVIRTUAL_CALLSITE_USING_CODE(pCode);
-
- DECLARE_ARGHOLDER_ARRAY(args, 2);
-
- args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(gc.refTarget);
- args[ARGNUM_1] = NULL;
-
- CATCH_HANDLER_FOUND_NOTIFICATION_CALLSITE;
- CALL_MANAGED_METHOD_NORET(args);
-
- GCPROTECT_END();
-}
-
-void ObjectClone::CompleteIDeserializationCallbacks()
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
- OBJECTREF Dummy1 = NULL, Dummy2 = NULL;
- QueuedObjectInfo *pObjInfo = NULL;
-
- if (TDC.GetCount() == 0)
- return;
-
- LOG((LF_REMOTING, LL_INFO1000, "CompleteIDeserializationCallbacks. Beginning.\n"));
-
- OBJECTREF nextObj;
- while ((nextObj = TDC.Dequeue(&Dummy1, &Dummy2, &pObjInfo)) != NULL)
- {
- MakeIDeserializationCallback(nextObj);
- }
-}
-
-void ObjectClone::CompleteVtsOnDeserializedCallbacks()
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END;
-
- OBJECTREF nextObj = NULL, Dummy1 = NULL, Dummy2 = NULL;
-
- if (VDC.GetCount() == 0)
- return;
-
- LOG((LF_REMOTING, LL_INFO1000, "CompleteVtsOnDeserializedCallbacks. Beginning.\n"));
-
- GCPROTECT_BEGIN(nextObj);
-
- while ((nextObj = VDC.Dequeue(&Dummy1, &Dummy2, NULL)) != NULL)
- InvokeVtsCallbacks(nextObj, RemotingVtsInfo::VTS_CALLBACK_ON_DESERIALIZED, m_toDomain);
-
- GCPROTECT_END();
-}
-
-void ObjectClone::CompleteVtsOnSerializedCallbacks()
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END;
-
- OBJECTREF nextObj = NULL, Dummy1 = NULL, Dummy2 = NULL;
-
- if (VSC.GetCount() == 0)
- return;
-
- LOG((LF_REMOTING, LL_INFO1000, "CompleteVtsOnSerializedCallbacks. Beginning.\n"));
-
- GCPROTECT_BEGIN(nextObj);
-
- while ((nextObj = VSC.Dequeue(&Dummy1, &Dummy2, NULL)) != NULL)
- InvokeVtsCallbacks(nextObj, RemotingVtsInfo::VTS_CALLBACK_ON_SERIALIZED, m_fromDomain);
-
- GCPROTECT_END();
-}
-
-// Does a binary search to find the object with given id, and record of given kind
-DWORD ObjectClone::FindObjectInTSO(int objId, SpecialObjects kind)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_NOTRIGGER;
- NOTHROW;
- }
- CONTRACTL_END
-
- DWORD lowIndex = 0;
- DWORD highIndex = TSO.GetCount();
- DWORD midIndex = highIndex / 2;
- DWORD firstMatch;
-
- if (highIndex == 0)
- {
- _ASSERTE(!"Special Object unexpectedly not found for given object id\n");
- return 0; // throw ?
- }
-
- SpecialObjectInfo *splInfo = NULL;
- while (true)
- {
- OBJECTREF refParent, refFromObj;
- OBJECTREF dummy;
- dummy = TSO.GetAt(midIndex, &refFromObj, &refParent, (QueuedObjectInfo **)&splInfo);
-
- if (objId < splInfo->GetObjectId())
- {
- highIndex = midIndex;
- }
- else
- {
- if (objId == splInfo->GetObjectId())
- break;
- lowIndex = midIndex;
- }
-
- DWORD oldIndex = midIndex;
- midIndex = lowIndex + (highIndex - lowIndex)/2;
- if (oldIndex == midIndex)
- {
- // Binary search failed. See comments below
- goto LinearSearch;
- }
- }
-
- // Found match at midIndex
- // Find the first record for this obj id
- firstMatch = midIndex;
- while(midIndex != 0)
- {
- midIndex -= 1;
- SpecialObjectInfo *pTemp;
- OBJECTREF refParent, refFromObj;
- OBJECTREF dummy;
- dummy = TSO.GetAt(midIndex, &refFromObj, &refParent, (QueuedObjectInfo **)&pTemp);
- if (pTemp->GetObjectId() != objId)
- break;
- else
- firstMatch = midIndex;
- };
-
- // Now look for the right kind of record
- do
- {
- OBJECTREF refParent, refFromObj;
- OBJECTREF dummy;
- dummy = TSO.GetAt(firstMatch, &refFromObj, &refParent, (QueuedObjectInfo **)&splInfo);
-
- if (splInfo->GetObjectId() == objId)
- {
- switch(kind)
- {
- case ISerializable:
- if (splInfo->IsISerializableInstance())
- return firstMatch;
- break;
- case IObjectReference:
- if (splInfo->IsIObjRefInstance())
- return firstMatch;
- break;
- case BoxedValueType:
- if (splInfo->IsBoxedObject())
- return firstMatch;
- break;
- default:
- _ASSERTE(!"Unknown enum value in FindObjectInTSO");
- };
- }
-
- firstMatch++;
-
- }while(firstMatch < TSO.GetCount());
-
-LinearSearch:
- // If there are multiple objects that are ISer/IObj, and some of them repeat in a certain fashion,
- // then the entries in TSO are not in sorted order. In such a case binary search will fail. Lets do a linear search
- // in such a case for now. This is probably reasonable since the TSO should usually be short and in-order (and presumably
- // cheaper than trying to keep the list in sorted order at all times).
- DWORD currIndex = 0;
- for (; currIndex < TSO.GetCount(); currIndex++)
- {
- OBJECTREF refParent, refFromObj;
- OBJECTREF dummy;
- dummy = TSO.GetAt(currIndex, &refFromObj, &refParent, (QueuedObjectInfo **)&splInfo);
-
- SpecialObjects foundKind = ISerializable;
- if (splInfo->IsIObjRefInstance())
- foundKind = IObjectReference;
- else if (splInfo->IsBoxedObject())
- foundKind = BoxedValueType;
- else
- _ASSERTE(splInfo->IsISerializableInstance());
-
- if (objId == splInfo->GetObjectId()
- && kind == foundKind)
- return currIndex;
- }
-
-
- _ASSERTE(!"Special Object unexpectedly not found for given object id\n");
- return 0; // throw ?
-}
-
-// This function is effectively a replica of MethodTable::Box. Its replicated to avoid "GCPROTECT_INTERIOR" that Box uses
-// and causes some leak detection asserts to go off. This is a controlled leak situation, where we know we're leaking stuff
-// and dont want the asserts.
-OBJECTREF ObjectClone::BoxValueTypeInWrongDomain(OBJECTREF refParent, DWORD offset, MethodTable *pValueTypeMT)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(pValueTypeMT->IsValueType());
- PRECONDITION(!pValueTypeMT->IsByRefLike());
- }
- CONTRACTL_END;
-
- OBJECTREF ref = NULL;
- void* pSrc = refParent->GetData() + offset;
- GCPROTECT_BEGININTERIOR(pSrc);
-
- // We must enter the target domain if we are boxing a non-agile type. This of course has some overhead
- // so we want to avoid it if possible. GetLoaderModule() == mscorlib && CanBeBlittedByObjectCloner is a
- // conservative first approximation of agile types.
- ENTER_DOMAIN_PTR_PREDICATED(m_fromDomain, ADV_RUNNINGIN,
- !pValueTypeMT->GetLoaderModule()->IsSystem() || pValueTypeMT->GetClass()->CannotBeBlittedByObjectCloner());
-
- ref = pValueTypeMT->FastBox(&pSrc);
-
- END_DOMAIN_TRANSITION;
-
- GCPROTECT_END();
- return ref;
-}
-
-// Returns whether or not a given type requires VTS callbacks of the specified kind.
-BOOL ObjectClone::HasVtsCallbacks(MethodTable *pMT, RemotingVtsInfo::VtsCallbackType eCallbackType)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- while (pMT)
- {
- if (pMT->HasRemotingVtsInfo())
- {
- PTR_RemotingVtsInfo pVtsInfo = pMT->GetRemotingVtsInfo();
- _ASSERTE(pVtsInfo != NULL);
-
- if (!pVtsInfo->m_pCallbacks[eCallbackType].IsNull())
- return TRUE;
- }
- pMT = pMT->GetParentMethodTable();
- }
-
- return FALSE;
-}
-
-// Calls all of the VTS event methods for a given callback type on the object instance provided (starting at the base class).
-void ObjectClone::InvokeVtsCallbacks(OBJECTREF refTarget, RemotingVtsInfo::VtsCallbackType eCallbackType, AppDomain* pDomain)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- GCPROTECT_BEGIN(refTarget);
-
- // Quickly walk the target's type hierarchy and determine the number of methods we'll need to call.
- DWORD cMethods = 0;
- MethodDesc *pLastCallback;
- MethodTable *pMT = refTarget->GetMethodTable();
- while (pMT)
- {
- if (pMT->HasRemotingVtsInfo())
- {
- PTR_RemotingVtsInfo pVtsInfo = pMT->GetRemotingVtsInfo();
- _ASSERTE(pVtsInfo != NULL);
-
- if (!pVtsInfo->m_pCallbacks[eCallbackType].IsNull())
- {
- cMethods++;
-
-#ifdef FEATURE_PREJIT
- // Might have to restore cross module method pointers.
- Module::RestoreMethodDescPointer(&pVtsInfo->m_pCallbacks[eCallbackType]);
-#endif
-
- pLastCallback = pVtsInfo->m_pCallbacks[eCallbackType].GetValue();
- }
- }
- pMT = pMT->GetParentMethodTable();
- }
-
- // Maybe there's no work to do.
- if (cMethods == 0)
- goto Done;
-
- // Allocate an array to hold the methods to invoke (we do this because the invocation order is the opposite way round from the
- // way we can easily scan for the methods). We can easily optimize this for the single callback case though.
- MethodDesc **pCallbacks = cMethods == 1 ? &pLastCallback : (MethodDesc**)_alloca(cMethods * sizeof(MethodDesc*));
-
- if (cMethods > 1)
- {
- // Walk the type hierarchy again, and this time fill in the methods to call in the correct slot of our callback table.
- DWORD dwSlotIndex = cMethods;
- pMT = refTarget->GetMethodTable();
- while (pMT)
- {
- if (pMT->HasRemotingVtsInfo())
- {
- PTR_RemotingVtsInfo pVtsInfo = pMT->GetRemotingVtsInfo();
- _ASSERTE(pVtsInfo != NULL);
-
- if (!pVtsInfo->m_pCallbacks[eCallbackType].IsNull())
- pCallbacks[--dwSlotIndex] = pVtsInfo->m_pCallbacks[eCallbackType].GetValue();
- }
- pMT = pMT->GetParentMethodTable();
- }
- _ASSERTE(dwSlotIndex == 0);
- }
-
- bool fSwitchDomains = pDomain != GetAppDomain();
-
- ENTER_DOMAIN_PTR(pDomain,ADV_RUNNINGIN);
-
- // If we're calling back into the from domain then reset the execution context to its original state (this will automatically be
- // popped once we return from this domain again).
- if (pDomain == m_fromDomain && fSwitchDomains)
- {
- Thread *pThread = GetThread();
- if (pThread->IsExposedObjectSet())
- {
- THREADBASEREF refThread = (THREADBASEREF)pThread->GetExposedObjectRaw();
- refThread->SetExecutionContext(m_fromExecutionContext);
- }
- }
-
- // Remember to adjust this pointer for boxed value types.
- BOOL bIsBoxed = refTarget->GetMethodTable()->IsValueType();
-
- RuntimeMethodHandle::StreamingContextData sContext = { NULL, GetStreamingContextState() };
-
- // Ensure Streamingcontext type is loaded. Do not delete this line
- MethodTable *pMTStreamingContext;
- pMTStreamingContext = MscorlibBinder::GetClass(CLASS__STREAMING_CONTEXT);
- _ASSERTE(pMTStreamingContext);
-
- // Now go and call each method in order.
- for (DWORD i = 0; i < cMethods; i++)
- {
- MethodDescCallSite callback(pCallbacks[i], &refTarget);
-
- ARG_SLOT argSlots[2];
-
- // Nullable<T> does not have any VTS functions
- _ASSERTE(!Nullable::IsNullableType(refTarget->GetMethodTable()));
-
- argSlots[0] = (bIsBoxed ? (ARG_SLOT)(SIZE_T)(refTarget->UnBox()) : ObjToArgSlot(refTarget));
-#if defined(_TARGET_X86_) || defined(_TARGET_ARM_)
- static_assert_no_msg(sizeof(sContext) == sizeof(ARG_SLOT));
- argSlots[1] = *(ARG_SLOT*)(&sContext); // StreamingContext is passed by value on x86 and ARM
-#elif defined(_WIN64)
- static_assert_no_msg(sizeof(sContext) > sizeof(ARG_SLOT));
- argSlots[1] = PtrToArgSlot(&sContext); // StreamingContext is passed by reference on WIN64
-#else // !_TARGET_X86_ && !_WIN64 && !_TARGET_ARM_
- PORTABILITY_ASSERT("ObjectClone::InvokeVtsCallbacks() - NYI on this platform");
-#endif // !_TARGET_X86_ && !_WIN64 && !_TARGET_ARM_
-
- callback.CallWithValueTypes(&argSlots[0]);
- }
-
- END_DOMAIN_TRANSITION;
-
-Done: ;
- GCPROTECT_END();
-}
-
-#endif // FEATURE_REMOTING
diff --git a/src/vm/objectclone.h b/src/vm/objectclone.h
deleted file mode 100644
index c2e237b91a..0000000000
--- a/src/vm/objectclone.h
+++ /dev/null
@@ -1,1268 +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.
-//
-// File: ObjectClone.h
-//
-
-//
-
-
-#ifndef _OBJECTCLONE_H_
-#define _OBJECTCLONE_H_
-
-#ifndef FEATURE_REMOTING
-#error FEATURE_REMOTING is not set, please do no include objectclone.h
-#endif
-
-#include "invokeutil.h"
-#include "runtimehandles.h"
-
-enum QueueType
-{
- FIFO,
- LIFO
-};
-
-enum ObjectProperties
-{
- enum_Array = 0x01,
- enum_NeedsUnboxing = 0x02,
- enum_ISerializableMember = 0x04, // This is set on member of an ISerializable instance
- enum_Iserializable = 0x08, // This is set on an ISerializable instance
- enum_IObjRef = 0x10, // This is set on an IObjRef instance
-};
-
-// This is the base class of all the different records that get
-// stored in different tables during cloning
-class QueuedObjectInfo
-{
-protected:
- BYTE m_properties;
-public:
- QueuedObjectInfo() { LIMITED_METHOD_CONTRACT; m_properties = 0; }
- BOOL IsArray() { LIMITED_METHOD_CONTRACT; return m_properties & enum_Array; }
- BOOL NeedsUnboxing() { LIMITED_METHOD_CONTRACT; return m_properties & enum_NeedsUnboxing; }
- void SetIsArray() { LIMITED_METHOD_CONTRACT; m_properties |= enum_Array; }
- void SetNeedsUnboxing() { LIMITED_METHOD_CONTRACT; m_properties |= enum_NeedsUnboxing; }
- BOOL IsISerializableMember() { LIMITED_METHOD_CONTRACT; return m_properties & enum_ISerializableMember; }
- void SetIsISerializableMember() { LIMITED_METHOD_CONTRACT; m_properties |= enum_ISerializableMember; }
- BOOL IsISerializableInstance() { LIMITED_METHOD_CONTRACT; return m_properties & enum_Iserializable; }
- void SetIsISerializableInstance() { LIMITED_METHOD_CONTRACT; m_properties |= enum_Iserializable; }
- BOOL IsIObjRefInstance() { LIMITED_METHOD_CONTRACT; return m_properties & enum_IObjRef; }
- void SetIsIObjRefInstance() { LIMITED_METHOD_CONTRACT; m_properties |= enum_IObjRef; }
- virtual DWORD GetSize()
- {
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- DWORD size = sizeof(QueuedObjectInfo);
-#if defined(_WIN64) || defined(ALIGN_ACCESS)
- size = (DWORD)ALIGN_UP(size, sizeof(SIZE_T));
-#endif // _WIN64 || ALIGN_ACCESS
- return size;
- }
-};
-
-// These are records in QOF. Represents a parent object which has at least one member to
-// be marshalled and fixed up.
-class ParentInfo : public QueuedObjectInfo
-{
- DWORD m_fixupCount;
- DWORD m_numSpecialMembers;
- DWORD m_IserIndexInTSOTable;
- DWORD m_IObjRefIndexInTSOTable;
- DWORD m_BoxedValIndexIntoTSOTable;
-public:
- ParentInfo(DWORD count)
- {
- LIMITED_METHOD_CONTRACT;
- m_fixupCount = count;
- m_numSpecialMembers = 0;
- m_IserIndexInTSOTable = (DWORD) -1;
- m_IObjRefIndexInTSOTable = (DWORD) -1;
- m_BoxedValIndexIntoTSOTable = (DWORD) -1;
- }
- DWORD DecrementFixupCount() { LIMITED_METHOD_CONTRACT; return --m_fixupCount; }
- DWORD GetNumSpecialMembers() { LIMITED_METHOD_CONTRACT; return m_numSpecialMembers; }
- DWORD IncrementSpecialMembers() { LIMITED_METHOD_CONTRACT; return ++m_numSpecialMembers; }
- DWORD GetISerIndexIntoTSO() { LIMITED_METHOD_CONTRACT; return m_IserIndexInTSOTable; }
- void SetISerIndexIntoTSO(DWORD index) { LIMITED_METHOD_CONTRACT; m_IserIndexInTSOTable = index; }
- DWORD GetIObjRefIndexIntoTSO() { LIMITED_METHOD_CONTRACT; return m_IObjRefIndexInTSOTable; }
- void SetIObjRefIndexIntoTSO(DWORD index) { LIMITED_METHOD_CONTRACT; m_IObjRefIndexInTSOTable = index; }
- DWORD GetBoxedValIndexIntoTSO() { LIMITED_METHOD_CONTRACT; return m_BoxedValIndexIntoTSOTable; }
- void SetBoxedValIndexIntoTSO(DWORD index) { LIMITED_METHOD_CONTRACT; m_BoxedValIndexIntoTSOTable = index; }
- virtual DWORD GetSize()
- {
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- DWORD size = sizeof(ParentInfo);
-#if defined(_WIN64) || defined(ALIGN_ACCESS)
- size = (DWORD)ALIGN_UP(size, sizeof(SIZE_T));
-#endif // _WIN64 || ALIGN_ACCESS
- return size;
- }
-};
-
-// Represents an object whose parent is a regular object (not an array, not ISerializable etc)
-// Contains enough information to fix this object into its parent
-class ObjectMemberInfo : public QueuedObjectInfo
-{
- FieldDesc *m_fieldDesc;
-public:
- ObjectMemberInfo(FieldDesc *field) { LIMITED_METHOD_CONTRACT; m_fieldDesc = field; }
- FieldDesc *GetFieldDesc() { LIMITED_METHOD_CONTRACT; return m_fieldDesc; }
- VOID SetFieldDesc(FieldDesc* field) { LIMITED_METHOD_CONTRACT; m_fieldDesc = field; }
- virtual DWORD GetSize()
- {
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- DWORD size = sizeof(ObjectMemberInfo);
-#if defined(_WIN64) || defined(ALIGN_ACCESS)
- size = (DWORD)ALIGN_UP(size, sizeof(SIZE_T));
-#endif // _WIN64 || ALIGN_ACCESS
- return size;
- }
-};
-
-// Represents an object whose parent is an array
-// Contains index information to fix this object into its parent
-class NDimArrayMemberInfo : public QueuedObjectInfo
-{
- DWORD m_numDimensions;
- DWORD m_index[0];
-public:
- NDimArrayMemberInfo(DWORD rank)
- {
- LIMITED_METHOD_CONTRACT;
- m_numDimensions = rank;
- SetIsArray();
- }
- virtual DWORD GetSize()
- {
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- DWORD size = sizeof(NDimArrayMemberInfo) + (sizeof(DWORD) * (m_numDimensions));
-#if defined(_WIN64) || defined(ALIGN_ACCESS)
- size = (DWORD)ALIGN_UP(size, sizeof(SIZE_T));
-#endif // _WIN64 || ALIGN_ACCESS
- return size;
- }
- DWORD *GetIndices()
- { LIMITED_METHOD_CONTRACT; return &m_index[0]; }
- void SetIndices(DWORD* indices)
- {
- LIMITED_METHOD_CONTRACT;
- memcpy(GetIndices(), indices, GetNumDimensions() * sizeof(DWORD));
- }
- DWORD GetNumDimensions()
- { LIMITED_METHOD_CONTRACT; return m_numDimensions; }
- void SetNumDimensions(DWORD rank)
- { LIMITED_METHOD_CONTRACT; m_numDimensions = rank; }
-};
-
-// Represents an object whose parent is an ISerializable object
-// Contains index information to fix this object into its parent
-class ISerializableMemberInfo : public QueuedObjectInfo
-{
- DWORD m_TIOIndex;
- DWORD m_fieldIndex;
-public:
- ISerializableMemberInfo(DWORD tableIndex, DWORD fieldIndex)
- {
- WRAPPER_NO_CONTRACT;
- m_TIOIndex = tableIndex;
- m_fieldIndex = fieldIndex;
- SetIsISerializableMember();
- }
- DWORD GetTableIndex()
- { LIMITED_METHOD_CONTRACT; return m_TIOIndex; }
- DWORD GetFieldIndex()
- { LIMITED_METHOD_CONTRACT; STATIC_CONTRACT_SO_TOLERANT; return m_fieldIndex; }
- virtual DWORD GetSize()
- {
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- DWORD size = sizeof(ISerializableMemberInfo);
-#if defined(_WIN64) || defined(ALIGN_ACCESS)
- size = (DWORD)ALIGN_UP(size, sizeof(SIZE_T));
-#endif // _WIN64 || ALIGN_ACCESS
- return size;
- }
-};
-
-// Represents a special object (ISerializable, Boxed value type, IObjectReference)
-// Entries in TSO are of this type
-class SpecialObjectInfo : public QueuedObjectInfo
-{
-protected:
- DWORD m_specialObjectProperties;
- int m_objectId;
- DWORD m_numSpecialMembers;
- DWORD m_mappingTableIndex;
-public:
- SpecialObjectInfo()
- {
- LIMITED_METHOD_CONTRACT;
- m_specialObjectProperties = 0;
- m_mappingTableIndex = 0;
- m_numSpecialMembers = 0;
- m_objectId = 0;
- }
- void SetHasBeenProcessed() { LIMITED_METHOD_CONTRACT; m_specialObjectProperties |= 0x01; }
- DWORD HasBeenProcessed() { LIMITED_METHOD_CONTRACT; return m_specialObjectProperties & 0x01; }
- void SetHasFixupInfo() { LIMITED_METHOD_CONTRACT; m_specialObjectProperties |= 0x02; }
- DWORD HasFixupInfo() { LIMITED_METHOD_CONTRACT; return m_specialObjectProperties & 0x02; }
- void SetIsRepeatObject() { LIMITED_METHOD_CONTRACT; m_specialObjectProperties |= 0x04; }
- DWORD IsRepeatObject() { LIMITED_METHOD_CONTRACT; return m_specialObjectProperties & 0x04; }
- void SetIsBoxedObject() { LIMITED_METHOD_CONTRACT; m_specialObjectProperties |= 0x08; }
- DWORD IsBoxedObject() { LIMITED_METHOD_CONTRACT; return m_specialObjectProperties & 0x08; }
- void SetTargetNotISerializable() { LIMITED_METHOD_CONTRACT; m_specialObjectProperties |= 0x10; }
- DWORD IsTargetNotISerializable() { LIMITED_METHOD_CONTRACT; return m_specialObjectProperties & 0x10; }
-
- void SetMappingTableIndex(DWORD index) { LIMITED_METHOD_CONTRACT; m_mappingTableIndex = index; }
- DWORD GetMappingTableIndex() { LIMITED_METHOD_CONTRACT; return m_mappingTableIndex; }
- DWORD GetNumSpecialMembers() { LIMITED_METHOD_CONTRACT; return m_numSpecialMembers; }
- void SetNumSpecialMembers(DWORD numSpecialMembers) { LIMITED_METHOD_CONTRACT; m_numSpecialMembers = numSpecialMembers;}
- void SetObjectId(int id) { LIMITED_METHOD_CONTRACT; m_objectId = id; }
- int GetObjectId() { LIMITED_METHOD_CONTRACT; return m_objectId; }
-};
-
-// Represents a special object (ISerializable)
-// Contains the number of IObjRef members it has
-class ISerializableInstanceInfo : public SpecialObjectInfo
-{
-public:
- ISerializableInstanceInfo(int objectId, DWORD numIObjRefMembers)
- {
- LIMITED_METHOD_CONTRACT;
- m_numSpecialMembers = numIObjRefMembers;
- m_objectId = objectId;
- SetIsISerializableInstance();
- }
- virtual DWORD GetSize()
- {
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- DWORD size = sizeof(ISerializableInstanceInfo);
-#if defined(_WIN64) || defined(ALIGN_ACCESS)
- size = (DWORD)ALIGN_UP(size, sizeof(SIZE_T));
-#endif // _WIN64 || ALIGN_ACCESS
- return size;
- }
-};
-
-// Represents a special object (IObjectReference)
-// Contains fixup information to fix the completed object into its parent
-class IObjRefInstanceInfo : public SpecialObjectInfo
-{
- DWORD m_ISerTSOIndex; // If this is also an Iserializable instance, index of the iser entry in TSO
-#if defined(_WIN64) || defined(ALIGN_ACCESS)
- DWORD m_padding;
-#endif // _WIN64 || ALIGN_ACCESS
- BYTE m_fixupData[0];
-public:
- IObjRefInstanceInfo(int objectId, DWORD numIObjRefMembers, DWORD numISerMembers)
- {
- WRAPPER_NO_CONTRACT;
- static_assert_no_msg((offsetof(IObjRefInstanceInfo, m_fixupData) % sizeof(SIZE_T)) == 0);
- m_numSpecialMembers = numIObjRefMembers + numISerMembers;
- m_ISerTSOIndex = (DWORD) -1;
- m_objectId = objectId;
- SetIsIObjRefInstance();
- }
- DWORD GetISerTSOIndex() {LIMITED_METHOD_CONTRACT; return m_ISerTSOIndex; }
- void SetISerTSOIndex(DWORD index)
- { LIMITED_METHOD_CONTRACT; m_ISerTSOIndex = index; }
- void SetFixupInfo(QueuedObjectInfo *pData)
- {
- WRAPPER_NO_CONTRACT;
- if (pData->GetSize() > 0)
- {
- SetHasFixupInfo();
- memcpy(m_fixupData, pData, pData->GetSize());
- }
- }
- QueuedObjectInfo *GetFixupInfo()
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return (HasFixupInfo() ? (QueuedObjectInfo *)&m_fixupData[0] : NULL);
- }
- virtual DWORD GetSize()
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- DWORD size = sizeof(IObjRefInstanceInfo) + (HasFixupInfo() ? ((QueuedObjectInfo *)&m_fixupData[0])->GetSize() : 0);
-#if defined(_WIN64) || defined(ALIGN_ACCESS)
- size = (DWORD)ALIGN_UP(size, sizeof(SIZE_T));
-#endif // _WIN64 || ALIGN_ACCESS
- return size;
- }
-};
-
-// Represents a special object (Boxed value type)
-// Contains fixup information to fix the completed object into its parent
-class ValueTypeInfo : public SpecialObjectInfo
-{
-protected:
- DWORD m_ISerTSOIndex; // If this is also an Iserializable instance, index of the iser entry in TSO
- DWORD m_IObjRefTSOIndex; // If this is also an IObjRef instance, index of the iser entry in TSO
- BYTE m_fixupData[0];
-public:
- ValueTypeInfo(int objectId, QueuedObjectInfo *pFixupInfo)
- {
- WRAPPER_NO_CONTRACT;
- static_assert_no_msg((offsetof(ValueTypeInfo, m_fixupData) % sizeof(SIZE_T)) == 0);
- m_ISerTSOIndex = (DWORD) -1;
- m_IObjRefTSOIndex = (DWORD) -1;
- m_objectId = objectId;
- SetNeedsUnboxing();
- SetIsBoxedObject();
- SetFixupInfo(pFixupInfo);
- }
- DWORD GetISerTSOIndex() {LIMITED_METHOD_CONTRACT; return m_ISerTSOIndex; }
- void SetISerTSOIndex(DWORD index)
- { LIMITED_METHOD_CONTRACT; m_ISerTSOIndex = index; }
- DWORD GetIObjRefTSOIndex() {LIMITED_METHOD_CONTRACT; return m_IObjRefTSOIndex; }
- void SetIObjRefTSOIndex(DWORD index)
- { LIMITED_METHOD_CONTRACT; m_IObjRefTSOIndex = index; }
- void SetFixupInfo(QueuedObjectInfo *pData)
- {
- WRAPPER_NO_CONTRACT;
- if (pData->GetSize() > 0)
- {
- SetHasFixupInfo();
- memcpy(m_fixupData, pData, pData->GetSize());
- }
- }
- QueuedObjectInfo *GetFixupInfo()
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return (HasFixupInfo() ? (QueuedObjectInfo *)&m_fixupData[0] : NULL);
- }
- virtual DWORD GetSize()
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- DWORD size = sizeof(ValueTypeInfo) + (HasFixupInfo() ? ((QueuedObjectInfo *)&m_fixupData[0])->GetSize() : 0);
-#if defined(_WIN64) || defined(ALIGN_ACCESS)
- size = (DWORD)ALIGN_UP(size, sizeof(SIZE_T));
-#endif // _WIN64 || ALIGN_ACCESS
- return size;
- }
-};
-
-// Threshold beyond which the collections switch to using the heap
-// STACK_TO_HEAP_THRESHOLD/NUM_SLOTS_PER_BUCKET must be 1 or a prime, because
-// it is used in GCSafeObjectHashTable as the number of hash table buckets.
-#ifdef _DEBUG
-#define STACK_TO_HEAP_THRESHOLD 5
-#define QOM_STACK_TO_HEAP_THRESHOLD 5
-#define QOF_STACK_TO_HEAP_THRESHOLD 5
-#define TSO_STACK_TO_HEAP_THRESHOLD 5
-#define TDC_STACK_TO_HEAP_THRESHOLD 5
-#define VSC_STACK_TO_HEAP_THRESHOLD 5
-#define VDC_STACK_TO_HEAP_THRESHOLD 5
-#else
-#define STACK_TO_HEAP_THRESHOLD (NUM_SLOTS_PER_BUCKET * 29)
-#define QOM_STACK_TO_HEAP_THRESHOLD 100
-#define QOF_STACK_TO_HEAP_THRESHOLD 16
-#define TSO_STACK_TO_HEAP_THRESHOLD 8
-#define TDC_STACK_TO_HEAP_THRESHOLD 8
-#define VSC_STACK_TO_HEAP_THRESHOLD 8
-#define VDC_STACK_TO_HEAP_THRESHOLD 8
-#endif
-
-#define NUM_SLOTS_PER_BUCKET 4
-
-#define MAGIC_FACTOR 12
-
-#define LIFO_QUEUE 1
-#define FIFO_QUEUE 2
-
-
-class GCSafeCollection
-{
- VPTR_BASE_VTABLE_CLASS(GCSafeCollection)
-protected:
- // AppDomain object leak protection: pointer to predicate which flips to false once we should stop reporting GC references.
- PTR_BOOL m_pfReportRefs;
-
-public:
- GCSafeCollection(){}
- virtual void Cleanup() = 0;
- virtual void ReportGCRefs(promote_func *fn, ScanContext* sc) = 0;
-};
-
-typedef VPTR(GCSafeCollection) PTR_GCSafeCollection;
-
-class GCSafeObjectTable : public GCSafeCollection
-{
- VPTR_VTABLE_CLASS(GCSafeObjectTable, GCSafeCollection);
-protected:
-
- PTR_OBJECTREF m_Objects1;
- PTR_OBJECTREF m_Objects2;
- PTR_OBJECTREF m_Objects3;
-
- PTR_DWORD m_dataIndices;
- PTR_BYTE m_data;
-
- DWORD m_currArraySize;
- // Objects
- DWORD m_count;
- DWORD m_head;
- // Data
- DWORD m_numDataBytes;
- DWORD m_dataHead;
-
- // LIFO/FIFO
- DWORD m_QueueType;
- BOOL m_usingHeap;
-
- BOOL m_fCleanedUp;
-
-#ifndef DACCESS_COMPILE
- void EnsureSize(DWORD requiredDataSize);
- void Resize();
-#endif
-
-public:
-#ifndef DACCESS_COMPILE
- void Init(OBJECTREF *ref1, OBJECTREF *ref2, OBJECTREF *ref3, DWORD *dwIndices, BYTE *bData, DWORD currArraySize, DWORD qType, BOOL *pfReportRefs)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_INTOLERANT;
- m_Objects1 = ref1;
- m_Objects2 = ref2;
- m_Objects3 = ref3;
- m_dataIndices = dwIndices;
- m_data = bData;
- m_QueueType = qType;
- m_currArraySize = currArraySize;
- m_usingHeap = FALSE;
- m_count = 0;
- m_head = 0;
- m_numDataBytes = 0;
- m_dataHead = 0;
- _ASSERTE(m_QueueType == LIFO_QUEUE || m_QueueType == FIFO_QUEUE);
- // If this is a lifo queue, then the data indices are definitely needed
- _ASSERTE(m_QueueType != LIFO_QUEUE || m_dataIndices != NULL);
- m_pfReportRefs = pfReportRefs;
- m_fCleanedUp = FALSE;
-#ifdef USE_CHECKED_OBJECTREFS
- ZeroMemory(m_Objects1, sizeof(OBJECTREF) * m_currArraySize);
- if (m_Objects2 != NULL)
- ZeroMemory(m_Objects2, sizeof(OBJECTREF) * m_currArraySize);
- if (m_Objects3 != NULL)
- ZeroMemory(m_Objects3, sizeof(OBJECTREF) * m_currArraySize);
- for(DWORD i = 0; i < m_currArraySize; i++)
- {
- Thread::ObjectRefProtected(&m_Objects1[i]);
- if (m_Objects2)
- Thread::ObjectRefProtected(&m_Objects2[i]);
- if (m_Objects3)
- Thread::ObjectRefProtected(&m_Objects3[i]);
- }
-#endif
- }
-
- void Init(OBJECTREF *ref1, BYTE *bData, DWORD currArraySize, DWORD qType, BOOL *pfReportRefs)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_INTOLERANT;
-
- m_Objects1 = ref1;
- m_Objects2 = NULL;
- m_Objects3 = NULL;
- m_dataIndices = NULL;
- m_data = bData;
- m_QueueType = qType;
- m_currArraySize = currArraySize;
- m_usingHeap = FALSE;
- m_count = 0;
- m_head = 0;
- m_numDataBytes = 0;
- m_dataHead = 0;
- _ASSERTE(m_QueueType == LIFO_QUEUE || m_QueueType == FIFO_QUEUE);
- // If this is a lifo queue, then the data indices are definitely needed
- _ASSERTE(m_QueueType != LIFO_QUEUE || m_dataIndices != NULL);
- m_pfReportRefs = pfReportRefs;
- m_fCleanedUp = FALSE;
-#ifdef USE_CHECKED_OBJECTREFS
- ZeroMemory(m_Objects1, sizeof(OBJECTREF) * m_currArraySize);
- if (m_Objects2 != NULL)
- ZeroMemory(m_Objects2, sizeof(OBJECTREF) * m_currArraySize);
- if (m_Objects3 != NULL)
- ZeroMemory(m_Objects3, sizeof(OBJECTREF) * m_currArraySize);
- for(DWORD i = 0; i < m_currArraySize; i++)
- {
- Thread::ObjectRefProtected(&m_Objects1[i]);
- if (m_Objects2)
- Thread::ObjectRefProtected(&m_Objects2[i]);
- if (m_Objects3)
- Thread::ObjectRefProtected(&m_Objects3[i]);
- }
-#endif
- }
-
-#endif // !DACCESS_COMPILE
-
- virtual void Cleanup()
- {
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
-
-#ifndef DACCESS_COMPILE
- // Set this first, we must disable GC reporting of our objects before we start ripping down the data structures that record
- // those objects. See ReportGCRefs for a more detailed explanation.
- m_fCleanedUp = TRUE;
-
- if (m_usingHeap == TRUE)
- {
- if (m_Objects1)
- delete[] m_Objects1;
- m_Objects1 = NULL;
- if (m_Objects2)
- delete[] m_Objects2;
- m_Objects2 = NULL;
- if (m_Objects3)
- delete[] m_Objects3;
- m_Objects3 = NULL;
- if (m_data)
- delete[] m_data;
- m_data = NULL;
- if (m_dataIndices)
- delete[] m_dataIndices;
- m_dataIndices = NULL;
- }
-
-#endif // !DACCESS_COMPILE
- }
-
- virtual void ReportGCRefs(promote_func *fn, ScanContext* sc)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
-
- // Due to the wacky way that frames are cleaned up (they're popped en masse by exception handling code in finally blocks)
- // it's possible that this object may be destructed before the custom GC frame is popped. If there's a GC in the timing
- // window then we end up here with the object destructed. It happens that the underlying storage (the stack) is still valid
- // since the exception handling code that's doing all this unwinding hasn't actually physically unwound the stack yet, but
- // the destructor has been run and may have left the object in an inconsistent state. To solve this in a really obvious
- // manner (less likely to be broken by a random change in the future) we keep a boolean that's set to true once the object
- // has been destructed (actually, once Cleanup has been called, because that's the destructive part). We don't need to
- // report anything beyond this point (and to do so would be dangerous given the state of the collection).
- if (m_fCleanedUp)
- return;
-
- // We track a predicate (actually embedded in the cloner which owns us) that tells us whether to report any GC refs at all.
- // This is used as a rip cord if the server appdomain is unloaded while we're processing in it (because this collection can
- // survive for a little while after that which is long enough to cause server objects to outlive their domain).
- if (!*m_pfReportRefs)
- {
- m_count = 0;
- if (m_Objects1)
- ZeroMemory(m_Objects1, m_currArraySize * sizeof(OBJECTREF));
- if (m_Objects2)
- ZeroMemory(m_Objects2, m_currArraySize * sizeof(OBJECTREF));
- if (m_Objects3)
- ZeroMemory(m_Objects3, m_currArraySize * sizeof(OBJECTREF));
- return;
- }
-
- PTR_PTR_Object pRefs1 = dac_cast<PTR_PTR_Object>(m_Objects1);
- PTR_PTR_Object pRefs2 = dac_cast<PTR_PTR_Object>(m_Objects2);
- PTR_PTR_Object pRefs3 = dac_cast<PTR_PTR_Object>(m_Objects3);
-
- if (m_QueueType == LIFO_QUEUE)
- {
- for (DWORD i = 0; i < m_count; i++)
- {
- _ASSERTE(i < m_currArraySize);
- if (m_Objects1)
- (*fn)(pRefs1 + i, sc, 0);
- if (m_Objects2)
- (*fn)(pRefs2 + i, sc, 0);
- if (m_Objects3)
- (*fn)(pRefs3 + i, sc, 0);
- }
- }
- else
- {
- for (DWORD i = m_head, count = 0; count < m_count; i++, count++)
- {
- i = i % m_currArraySize;
- if (m_Objects1)
- (*fn)(pRefs1 + i, sc, 0);
- if (m_Objects2)
- (*fn)(pRefs2 + i, sc, 0);
- if (m_Objects3)
- (*fn)(pRefs3 + i, sc, 0);
- }
- }
- }
-
-#ifndef DACCESS_COMPILE
- void Enqueue(OBJECTREF refObj, OBJECTREF refParent, OBJECTREF refAux, QueuedObjectInfo *pQOI);
- void Push(OBJECTREF refObj, OBJECTREF refParent, OBJECTREF refAux, QueuedObjectInfo *pQOI);
- void SetAt(DWORD index, OBJECTREF refObj, OBJECTREF refParent, OBJECTREF refAux, QueuedObjectInfo *pQOI);
- OBJECTREF Dequeue(OBJECTREF *refParent, OBJECTREF *refAux, QueuedObjectInfo **pQOI);
- OBJECTREF Pop(OBJECTREF *refParent, OBJECTREF *refAux, QueuedObjectInfo **pQOI);
- OBJECTREF GetAt(DWORD index, OBJECTREF *refParent, OBJECTREF *refAux, QueuedObjectInfo **pQOI);
- OBJECTREF Peek(OBJECTREF *refParent, OBJECTREF *refAux, QueuedObjectInfo **pQOI);
- void BeginEnumeration(DWORD *dwIndex)
- {
- LIMITED_METHOD_CONTRACT;
- if (m_QueueType == LIFO_QUEUE)
- *dwIndex = m_count;
- else
- *dwIndex = 0;
- }
-
- OBJECTREF GetNext(DWORD *dwIndex, OBJECTREF *refParent, OBJECTREF *refAux, QueuedObjectInfo **pQOI)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- OBJECTREF refRet = NULL;
- if (m_QueueType == LIFO_QUEUE)
- {
- if (*dwIndex == 0)
- return NULL;
-
- (*dwIndex)--;
- refRet = GetAt(*dwIndex, refParent, refAux, pQOI);
- }
- else
- {
- if (*dwIndex == m_count)
- return NULL;
-
- refRet = GetAt(*dwIndex, refParent, refAux, pQOI);
- (*dwIndex)++;
- }
- return refRet;
- }
-
- DWORD GetCount() { LIMITED_METHOD_CONTRACT; return m_count; }
-#endif // !DACCESS_COMPILE
-};
-
-#ifndef DACCESS_COMPILE
-class DwordArrayList
-{
- DWORD m_dwordsOnStack[STACK_TO_HEAP_THRESHOLD];
- DWORD *m_dwords;
-
- DWORD m_count;
- DWORD m_currSize;
-public:
-
- void Init()
- {
- LIMITED_METHOD_CONTRACT;
- m_dwords = &m_dwordsOnStack[0];
- m_currSize = STACK_TO_HEAP_THRESHOLD;
- m_count = 0;
- }
-
- void Add(DWORD i)
- {
- WRAPPER_NO_CONTRACT;
- EnsureSize();
- m_dwords[m_count++] = i;
- }
-
- void EnsureSize()
- {
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- STATIC_CONTRACT_SO_INTOLERANT;
- }
- CONTRACTL_END
- if (m_count < m_currSize)
- return;
-
- DWORD newSize = m_currSize * 2;
- // Does not need a holder because this is the only allocation in this method
- DWORD *pTemp = new DWORD[newSize];
- ZeroMemory(pTemp, sizeof(DWORD) * newSize);
-
- memcpy((BYTE*)pTemp, m_dwords, sizeof(DWORD) * m_currSize);
- if (m_dwords != &m_dwordsOnStack[0])
- {
- delete[] m_dwords;
- }
- m_dwords = pTemp;
- m_count = m_currSize;
- m_currSize = newSize;
- }
-
- void Cleanup()
- {
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- if (m_dwords != &m_dwordsOnStack[0])
- {
- delete[] m_dwords;
- m_dwords = &m_dwordsOnStack[0];
- }
- }
-
- DWORD GetCount() { LIMITED_METHOD_CONTRACT; return m_count; }
- DWORD GetAt(DWORD index)
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(index >= 0 && index < m_count);
- return m_dwords[index];
- }
-};
-#endif // !DACCESS_COMPILE
-
-class GCSafeObjectHashTable : public GCSafeCollection
-{
- VPTR_VTABLE_CLASS(GCSafeObjectHashTable, GCSafeCollection);
-private:
- OBJECTREF m_objectsOnStack[STACK_TO_HEAP_THRESHOLD];
- OBJECTREF m_newObjectsOnStack[STACK_TO_HEAP_THRESHOLD];
- DWORD m_dataOnStack[STACK_TO_HEAP_THRESHOLD];
- DWORD m_count;
- DWORD m_currArraySize;
- PTR_int m_ids;
- PTR_OBJECTREF m_objects;
- PTR_OBJECTREF m_newObjects;
- BOOL m_fCleanedUp;
-
-#ifndef DACCESS_COMPILE
- void Resize();
- int FindElement(OBJECTREF refObj, BOOL &seenBefore);
-#endif // !DACCESS_COMPILE
-
-public:
-
-#ifndef DACCESS_COMPILE
- virtual void Init(BOOL *pfReportRefs)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- ZeroMemory(&m_objectsOnStack[0], sizeof(m_objectsOnStack));
- ZeroMemory(&m_dataOnStack[0], sizeof(m_dataOnStack));
- m_objects = &m_objectsOnStack[0];
- m_newObjects = &m_newObjectsOnStack[0];
- m_currArraySize = STACK_TO_HEAP_THRESHOLD;
- m_count = 0;
- m_ids = (int *) &m_dataOnStack[0];
- m_pfReportRefs = pfReportRefs;
- m_fCleanedUp = FALSE;
-#ifdef USE_CHECKED_OBJECTREFS
- ZeroMemory(&m_newObjects[0], sizeof(m_newObjectsOnStack));
- for(DWORD i = 0; i < m_currArraySize; i++)
- {
- Thread::ObjectRefProtected(&m_objects[i]);
- Thread::ObjectRefProtected(&m_newObjects[i]);
- }
-#endif
- }
-#endif // !DACCESS_COMPILE
-
- virtual void Cleanup()
- {
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
-
-#ifndef DACCESS_COMPILE
- // Set this first, we must disable GC reporting of our objects before we start ripping down the data structures that record
- // those objects. See ReportGCRefs for a more detailed explanation.
- m_fCleanedUp = TRUE;
-
- if (m_newObjects != &m_newObjectsOnStack[0])
- {
- delete[] m_ids;
- m_ids = (int *) &m_dataOnStack[0];
- delete[] m_newObjects;
- m_newObjects = &m_newObjectsOnStack[0];
- delete[] m_objects;
- m_objects = &m_objectsOnStack[0];
- m_currArraySize = STACK_TO_HEAP_THRESHOLD;
- }
-#endif // !DACCESS_COMPILE
- }
-
- virtual void ReportGCRefs(promote_func *fn, ScanContext* sc)
- {
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- // Due to the wacky way that frames are cleaned up (they're popped en masse by exception handling code in finally blocks)
- // it's possible that this object may be destructed before the custom GC frame is popped. If there's a GC in the timing
- // window then we end up here with the object destructed. It happens that the underlying storage (the stack) is still valid
- // since the exception handling code that's doing all this unwinding hasn't actually physically unwound the stack yet, but
- // the destructor has been run and may have left the object in an inconsistent state. To solve this in a really obvious
- // manner (less likely to be broken by a random change in the future) we keep a boolean that's set to true once the object
- // has been destructed (actually, once Cleanup has been called, because that's the destructive part). We don't need to
- // report anything beyond this point (and to do so would be dangerous given the state of the collection).
- if (m_fCleanedUp)
- return;
-
- // We track a predicate (actually embedded in the cloner which owns us) that tells us whether to report any GC refs at all.
- // This is used as a rip cord if the server appdomain is unloaded while we're processing in it (because this collection can
- // survive for a little while after that which is long enough to cause server objects to outlive their domain).
- if (!*m_pfReportRefs)
- {
- m_count = 0;
- ZeroMemory(m_ids, m_currArraySize * sizeof(int));
- ZeroMemory(m_objects, m_currArraySize * sizeof(OBJECTREF));
- ZeroMemory(m_newObjects, m_currArraySize * sizeof(OBJECTREF));
- return;
- }
-
- PTR_PTR_Object pRefs = dac_cast<PTR_PTR_Object>(m_objects);
- PTR_PTR_Object pNewRefs = dac_cast<PTR_PTR_Object>(m_newObjects);
-
- for (DWORD i = 0; i < m_currArraySize; i++)
- {
- if (m_ids[i] != 0)
- {
- (*fn)(pRefs + i, sc, 0);
- (*fn)(pNewRefs + i, sc, 0);
- }
- }
- }
-
-#ifndef DACCESS_COMPILE
- int HasID(OBJECTREF refObj, OBJECTREF *newObj);
- int AddObject(OBJECTREF refObj, OBJECTREF newObj);
- int UpdateObject(OBJECTREF refObj, OBJECTREF newObj);
-#endif // !DACCESS_COMPILE
-};
-
-#ifndef DACCESS_COMPILE
-
-enum SpecialObjects
-{
- ISerializable = 1,
- IObjectReference,
- BoxedValueType
-};
-
-enum CloningContext
-{
- CrossAppDomain = 1,
- ObjectFreezer
-};
-
-class CrossAppDomainClonerCallback
-{
- public:
- OBJECTREF AllocateObject(OBJECTREF, MethodTable * pMT)
- {
- WRAPPER_NO_CONTRACT;
- return pMT->Allocate();
- }
-
- OBJECTREF AllocateArray(OBJECTREF, TypeHandle arrayType, INT32 *pArgs, DWORD dwNumArgs, BOOL bAllocateInLargeHeap)
- {
- WRAPPER_NO_CONTRACT;
- return ::AllocateArrayEx(arrayType, pArgs, dwNumArgs, bAllocateInLargeHeap DEBUG_ARG(FALSE));
- }
-
- STRINGREF AllocateString(STRINGREF refSrc)
- {
- LIMITED_METHOD_CONTRACT;
- return refSrc;
- }
-
- void ValidateFromType(MethodTable *pFromMT)
- {
- WRAPPER_NO_CONTRACT;
- CheckSerializable(pFromMT);
- }
-
- void ValidateToType(MethodTable *pToMT)
- {
- WRAPPER_NO_CONTRACT;
- CheckSerializable(pToMT);
- }
-
- BOOL IsRemotedType(MethodTable *pMT, AppDomain* pFromAD, AppDomain* pToDomain)
- {
- WRAPPER_NO_CONTRACT;
- if ((pMT->IsMarshaledByRef() && pFromAD != pToDomain) ||
- pMT->IsTransparentProxy())
- return TRUE;
-
- return FALSE;
- }
-
- BOOL IsISerializableType(MethodTable *pMT)
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
- return pMT->CanCastToNonVariantInterface(MscorlibBinder::GetClass(CLASS__ISERIALIZABLE));
- }
-
- BOOL IsIObjectReferenceType(MethodTable *pMT)
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
- return pMT->CanCastToNonVariantInterface(MscorlibBinder::GetClass(CLASS__IOBJECTREFERENCE));
- }
-
- BOOL RequiresDeserializationCallback(MethodTable *pMT)
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
- return pMT->CanCastToNonVariantInterface(MscorlibBinder::GetClass(CLASS__IDESERIALIZATIONCB));
- }
-
- BOOL RequiresDeepCopy(OBJECTREF refObj)
- {
- LIMITED_METHOD_CONTRACT;
- return TRUE;
- }
-
- private:
- void CheckSerializable(MethodTable *pCurrMT)
- {
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END;
-
- // Checking whether the type is marked as Serializable is not enough, all of its ancestor types must be marked this way
- // also. THe only exception is that any type that also implements ISerializable doesn't require a serializable parent.
- if (pCurrMT->IsSerializable())
- {
- MethodTable *pISerializableMT = MscorlibBinder::GetClass(CLASS__ISERIALIZABLE);
- MethodTable *pMT = pCurrMT;
- for (;;)
- {
- // We've already checked this particular type is marked Serializable, so if it implements ISerializable then
- // we're done.
- if (pMT->ImplementsInterface(pISerializableMT))
- return;
-
- // Else we get the parent type and check it is marked Serializable as well.
- pMT = pMT->GetParentMethodTable();
-
- // If we've run out of parents we're done and the type is serializable.
- if (pMT == NULL)
- return;
-
- // Otherwise check for the attribute.
- if (!pMT->IsSerializable())
- break;
- }
- }
-
- if (pCurrMT->IsMarshaledByRef())
- return;
-
- if (pCurrMT->IsTransparentProxy())
- return;
-
- if (pCurrMT->IsEnum())
- return;
-
- if (pCurrMT->IsDelegate())
- return;
-
- DefineFullyQualifiedNameForClassW();
- LPCWSTR wszCliTypeName = GetFullyQualifiedNameForClassNestedAwareW(pCurrMT);
-
- SString ssAssemblyName;
- pCurrMT->GetAssembly()->GetDisplayName(ssAssemblyName);
- COMPlusThrow(kSerializationException, IDS_SERIALIZATION_NONSERTYPE, wszCliTypeName, ssAssemblyName.GetUnicode());
- }
-};
-
-class CrossDomainFieldMap
-{
- struct FieldMapEntry
- {
- ADID m_dwSrcDomain;
- ADID m_dwDstDomain;
- MethodTable *m_pSrcMT;
- MethodTable *m_pDstMT;
- FieldDesc **m_pFieldMap;
-
- FieldMapEntry(MethodTable *pSrcMT, MethodTable *pDstMT, FieldDesc **pFieldMap);
- ~FieldMapEntry()
- {
- LIMITED_METHOD_CONTRACT;
- delete [] m_pFieldMap;
- }
-
- UPTR GetHash()
- {
- LIMITED_METHOD_CONTRACT;
- return (UINT)(SIZE_T)m_pSrcMT + ((UINT)(SIZE_T)m_pDstMT >> 2);
- }
- };
-
- static PtrHashMap *s_pFieldMap;
- static SimpleRWLock *s_pFieldMapLock;
-
- static BOOL CompareFieldMapEntry(UPTR val1, UPTR val2);
-
-public:
- static void FlushStaleEntries();
- static FieldDesc **LookupOrCreateFieldMapping(MethodTable *pDstMT, MethodTable *pSrcMT);
-};
-
-// Currently the object cloner uses DWORDs as indices. We may have to use QWORDs instead
-// if we start to have extremely large object graphs.
-class ObjectClone
-{
- OBJECTREF m_QOMObjects[QOM_STACK_TO_HEAP_THRESHOLD];
- BYTE m_QOMData[QOM_STACK_TO_HEAP_THRESHOLD * MAGIC_FACTOR];
-
- OBJECTREF m_QOFObjects[QOF_STACK_TO_HEAP_THRESHOLD];
- BYTE m_QOFData[QOF_STACK_TO_HEAP_THRESHOLD * MAGIC_FACTOR];
-
- OBJECTREF m_TSOObjects1[TSO_STACK_TO_HEAP_THRESHOLD];
- OBJECTREF m_TSOObjects2[TSO_STACK_TO_HEAP_THRESHOLD];
- OBJECTREF m_TSOObjects3[TSO_STACK_TO_HEAP_THRESHOLD];
- BYTE m_TSOData[TSO_STACK_TO_HEAP_THRESHOLD * MAGIC_FACTOR];
- DWORD m_TSOIndices[TSO_STACK_TO_HEAP_THRESHOLD];
-
- OBJECTREF m_TDCObjects[TDC_STACK_TO_HEAP_THRESHOLD];
- BYTE m_TDCData[TDC_STACK_TO_HEAP_THRESHOLD * MAGIC_FACTOR];
-
- OBJECTREF m_VSCObjects[VSC_STACK_TO_HEAP_THRESHOLD];
-
- OBJECTREF m_VDCObjects[VDC_STACK_TO_HEAP_THRESHOLD];
-
- GCSafeObjectTable QOM; // Queue_of_Object_to_be_Marshalled
- GCSafeObjectTable QOF; // Queue_of_Objects_to_be_Fixed_Up
- GCSafeObjectHashTable TOS; // Table_of_Objects_Seen
- GCSafeObjectTable TSO; // Table_of_Special_Objects
- GCSafeObjectTable TDC; // Table_of_Deserialization_Callbacks
- GCSafeObjectTable VSC; // Vts_Serialization_Callbacks
- GCSafeObjectTable VDC; // Vts_Deserialization_Callbacks
- DwordArrayList TMappings;
-
- FrameWithCookie<GCSafeCollectionFrame> QOM_Protector;
- FrameWithCookie<GCSafeCollectionFrame> QOF_Protector;
- FrameWithCookie<GCSafeCollectionFrame> TOS_Protector;
- FrameWithCookie<GCSafeCollectionFrame> TSO_Protector;
- FrameWithCookie<GCSafeCollectionFrame> TDC_Protector;
- FrameWithCookie<GCSafeCollectionFrame> VSC_Protector;
- FrameWithCookie<GCSafeCollectionFrame> VDC_Protector;
-
- BOOL m_skipFieldScan;
-
- AppDomain* m_fromDomain;
- AppDomain* m_toDomain;
-
- OBJECTREF m_currObject; // Updated within the loop in Clone method
- OBJECTREF m_newObject; // Updated within the loop in Clone method
- OBJECTREF m_topObject;
- OBJECTREF m_fromExecutionContext; // Copy of the execution context on the way in (used during callbacks to the from domain)
-
- BOOL m_securityChecked;
-
- // AppDomain object leak protection: predicate which flips to false once we should stop reporting GC references in the
- // collections this cloner owns.
- BOOL m_fReportRefs;
-
- CrossAppDomainClonerCallback *m_cbInterface;
- CloningContext m_context;
-
- PTRARRAYREF AllocateISerializable(int objectId, BOOL bIsRemotingObject);
- void AllocateArray();
- void AllocateObject();
-
- PTRARRAYREF MakeObjectLookLikeISerializable(int objectId);
-
- void HandleISerializableFixup(OBJECTREF refParent, QueuedObjectInfo *currObjFixupInfo);
- void HandleArrayFixup(OBJECTREF refParent, QueuedObjectInfo *currObjFixupInfo);
- void HandleObjectFixup(OBJECTREF refParent, QueuedObjectInfo *currObjFixupInfo);
- void Fixup(OBJECTREF newObj, OBJECTREF refParent, QueuedObjectInfo *currObjFixupInfo);
-
- void ScanMemberFields(DWORD IObjRefTSOIndex, DWORD BoxedValTSOIndex);
- DWORD CloneField(FieldDesc *pSrcField, FieldDesc *pDstField);
- static BOOL AreTypesEmittedIdentically(MethodTable *pMT1, MethodTable *pMT2);
- void ScanISerializableMembers(DWORD IObjRefTSOIndex, DWORD ISerTSOIndex, DWORD BoxedValTSOIndex, PTRARRAYREF refValues);
- void ScanArrayMembers();
- Object *GetObjectFromArray(BASEARRAYREF* arrObj, DWORD dwOffset);
-
- void CompleteValueTypeFields(OBJECTREF newObj, OBJECTREF refParent, QueuedObjectInfo *valTypeInfo);
- void CompleteSpecialObjects();
- void CompleteISerializableObject(OBJECTREF IserObj, OBJECTREF refNames, OBJECTREF refValues, ISerializableInstanceInfo *);
- BOOL CompleteIObjRefObject(OBJECTREF IObjRef, DWORD index, IObjRefInstanceInfo *iorInfo);
- void CompleteIDeserializationCallbacks();
- void CompleteVtsOnDeserializedCallbacks();
- void CompleteVtsOnSerializedCallbacks();
- BOOL CheckForUnresolvedMembers(SpecialObjectInfo *splInfo);
-
- TypeHandle GetCorrespondingTypeForTargetDomain(TypeHandle thCli);
- MethodTable * GetCorrespondingTypeForTargetDomain(MethodTable * pCliMT);
- TypeHandle GetType(const SString &ssTypeName, const SString &ssAssemName);
-
- DWORD FindObjectInTSO(int objId, SpecialObjects kind);
- ARG_SLOT HandleFieldTypeMismatch(CorElementType srcTy, CorElementType destTy, void *pData, MethodTable *pSrcMT);
- BOOL IsDelayedFixup(MethodTable *newMT, QueuedObjectInfo *);
- OBJECTREF BoxValueTypeInWrongDomain(OBJECTREF refParent, DWORD offset, MethodTable *pValueTypeMT);
-
- BOOL HasVtsCallbacks(MethodTable *pMT, RemotingVtsInfo::VtsCallbackType eCallbackType);
- void InvokeVtsCallbacks(OBJECTREF refTarget, RemotingVtsInfo::VtsCallbackType eCallbackType, AppDomain* pDomain);
-
- RuntimeMethodHandle::StreamingContextStates GetStreamingContextState()
- {
- LIMITED_METHOD_CONTRACT;
-
- if (m_context == CrossAppDomain)
- return RuntimeMethodHandle::CONTEXTSTATE_CrossAppDomain;
-
- if (m_context == ObjectFreezer)
- return RuntimeMethodHandle::CONTEXTSTATE_Other;
-
- _ASSERTE(!"Should not get here; using the cloner with a context we don't understand");
- return RuntimeMethodHandle::CONTEXTSTATE_Other;
- }
-public:
-
- void Init(BOOL bInitialInit)
- {
- WRAPPER_NO_CONTRACT;
-
- if (bInitialInit)
- {
- TOS.Init(&m_fReportRefs);
- TSO.Init(&m_TSOObjects1[0], &m_TSOObjects2[0], &m_TSOObjects3[0], &m_TSOIndices[0], &m_TSOData[0], TSO_STACK_TO_HEAP_THRESHOLD, LIFO_QUEUE, &m_fReportRefs);
- }
- QOM.Init(&m_QOMObjects[0], &m_QOMData[0], QOM_STACK_TO_HEAP_THRESHOLD, FIFO_QUEUE, &m_fReportRefs);
- QOF.Init(&m_QOFObjects[0], &m_QOFData[0], QOF_STACK_TO_HEAP_THRESHOLD, FIFO_QUEUE, &m_fReportRefs);
- TDC.Init(&m_TDCObjects[0], &m_TDCData[0], TDC_STACK_TO_HEAP_THRESHOLD, FIFO_QUEUE, &m_fReportRefs);
- VSC.Init(&m_VSCObjects[0], NULL, VSC_STACK_TO_HEAP_THRESHOLD, FIFO_QUEUE, &m_fReportRefs);
- VDC.Init(&m_VDCObjects[0], NULL, VDC_STACK_TO_HEAP_THRESHOLD, FIFO_QUEUE, &m_fReportRefs);
- TMappings.Init();
- }
- void Cleanup(BOOL bFinalCleanup)
- {
- WRAPPER_NO_CONTRACT;
- if (bFinalCleanup)
- {
- TOS.Cleanup();
- TSO.Cleanup();
- }
-
- QOM.Cleanup();
- QOF.Cleanup();
- TDC.Cleanup();
- VSC.Cleanup();
- VDC.Cleanup();
- TMappings.Cleanup();
- }
-
- ObjectClone(CrossAppDomainClonerCallback *cbInterface, CloningContext cc=CrossAppDomain, BOOL bNeedSecurityCheck = TRUE)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
- static_assert_no_msg((offsetof(ObjectClone, m_QOMObjects) % sizeof(SIZE_T)) == 0);
- static_assert_no_msg((offsetof(ObjectClone, m_QOFObjects) % sizeof(SIZE_T)) == 0);
- static_assert_no_msg((offsetof(ObjectClone, m_TSOData) % sizeof(SIZE_T)) == 0);
- static_assert_no_msg((offsetof(ObjectClone, m_TDCData) % sizeof(SIZE_T)) == 0);
- static_assert_no_msg((offsetof(ObjectClone, m_VSCObjects) % sizeof(SIZE_T)) == 0);
- static_assert_no_msg((offsetof(ObjectClone, m_VDCObjects) % sizeof(SIZE_T)) == 0);
-
- m_securityChecked = !bNeedSecurityCheck;
- m_context = cc;
- m_cbInterface = cbInterface;
- m_fReportRefs = true;
-
- Init(TRUE);
-
- // Order of these is important. The frame lowest on the stack (ie declared last inside ObjectClone) has to be pushed first
- (void)new (VDC_Protector.GetGSCookiePtr()) FrameWithCookie<GCSafeCollectionFrame>(&VDC);
- (void)new (VSC_Protector.GetGSCookiePtr()) FrameWithCookie<GCSafeCollectionFrame>(&VSC);
- (void)new (TDC_Protector.GetGSCookiePtr()) FrameWithCookie<GCSafeCollectionFrame>(&TDC);
- (void)new (TSO_Protector.GetGSCookiePtr()) FrameWithCookie<GCSafeCollectionFrame>(&TSO);
- (void)new (TOS_Protector.GetGSCookiePtr()) FrameWithCookie<GCSafeCollectionFrame>(&TOS);
- (void)new (QOF_Protector.GetGSCookiePtr()) FrameWithCookie<GCSafeCollectionFrame>(&QOF);
- (void)new (QOM_Protector.GetGSCookiePtr()) FrameWithCookie<GCSafeCollectionFrame>(&QOM);
- }
-
- void RemoveGCFrames()
- {
- LIMITED_METHOD_CONTRACT;
- // Order of these is important. The frame highest on the stack has to be pushed first
- QOM_Protector.Pop();
- QOF_Protector.Pop();
- TOS_Protector.Pop();
- TSO_Protector.Pop();
- TDC_Protector.Pop();
- VSC_Protector.Pop();
- VDC_Protector.Pop();
- }
-
- ~ObjectClone()
- {
- WRAPPER_NO_CONTRACT;
- Cleanup(TRUE);
- }
-
- OBJECTREF Clone(OBJECTREF refObj, AppDomain* fromDomain, AppDomain* toDomain, OBJECTREF refExecutionContext)
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
- TypeHandle thDummy;
- OBJECTREF refResult = Clone(refObj, thDummy, fromDomain, toDomain, refExecutionContext);
- return refResult;
- }
-
- OBJECTREF Clone(OBJECTREF refObj,
- TypeHandle expectedType,
- AppDomain *fromDomain,
- AppDomain *toDomain,
- OBJECTREF refExecutionContext);
-
- static void StopReportingRefs(ObjectClone *pThis)
- {
- pThis->m_fReportRefs = false;
- }
-};
-
-typedef Holder<ObjectClone *, DoNothing<ObjectClone*>, ObjectClone::StopReportingRefs> ReportClonerRefsHolder;
-
-#endif
-#endif
diff --git a/src/vm/olevariant.cpp b/src/vm/olevariant.cpp
index 75483fd5fe..a15a1979e2 100644
--- a/src/vm/olevariant.cpp
+++ b/src/vm/olevariant.cpp
@@ -2729,12 +2729,10 @@ void OleVariant::MarshalOleVariantForObject(OBJECTREF * const & pObj, VARIANT *p
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
if (AppX::IsAppXProcess())
{
COMPlusThrow(kPlatformNotSupportedException, IDS_EE_BADMARSHAL_TYPE_VARIANTASOBJECT);
}
-#endif // FEATURE_CORECLR
SafeVariantClear(pOle);
@@ -2859,12 +2857,10 @@ void OleVariant::MarshalOleRefVariantForObject(OBJECTREF *pObj, VARIANT *pOle)
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
if (AppX::IsAppXProcess())
{
COMPlusThrow(kPlatformNotSupportedException, IDS_EE_BADMARSHAL_TYPE_VARIANTASOBJECT);
}
-#endif // FEATURE_CORECLR
HRESULT hr = MarshalCommonOleRefVariantForObject(pObj, pOle);
@@ -3084,12 +3080,10 @@ void OleVariant::MarshalObjectForOleVariant(const VARIANT * pOle, OBJECTREF * co
}
CONTRACT_END;
-#ifdef FEATURE_CORECLR
if (AppX::IsAppXProcess())
{
COMPlusThrow(kPlatformNotSupportedException, IDS_EE_BADMARSHAL_TYPE_VARIANTASOBJECT);
}
-#endif // FEATURE_CORECLR
#ifdef MDA_SUPPORTED
MdaInvalidVariant* pProbe = MDA_GET_ASSISTANT(InvalidVariant);
diff --git a/src/vm/pefile.cpp b/src/vm/pefile.cpp
index 86785e2417..16c66b516d 100644
--- a/src/vm/pefile.cpp
+++ b/src/vm/pefile.cpp
@@ -15,10 +15,6 @@
#include "eecontract.h"
#include "apithreadstress.h"
#include "eeconfig.h"
-#ifdef FEATURE_FUSION
-#include "fusionpriv.h"
-#include "shlwapi.h"
-#endif
#include "product_version.h"
#include "eventtrace.h"
#include "security.h"
@@ -32,18 +28,11 @@
#endif
#include "strongnameinternal.h"
-#ifdef FEATURE_VERSIONING
#include "../binder/inc/applicationcontext.hpp"
-#endif
-#ifndef FEATURE_FUSION
#include "clrprivbinderutil.h"
#include "../binder/inc/coreclrbindercommon.h"
-#endif
-#ifdef FEATURE_CAS_POLICY
-#include <wintrust.h>
-#endif
#ifdef FEATURE_PREJIT
#include "compile.h"
@@ -55,11 +44,6 @@ SVAL_IMPL_INIT(DWORD, PEFile, s_NGENDebugFlags, 0);
#include "sha1.h"
-#if defined(FEATURE_FUSION)
-#include "clrprivbinderfusion.h"
-#include "clrprivbinderappx.h"
-#include "clrprivbinderloadfile.h"
-#endif
#ifndef DACCESS_COMPILE
@@ -83,25 +67,13 @@ PEFile::PEFile(PEImage *identity, BOOL fCheckAuthenticodeSignature/*=TRUE*/) :
m_pMDImport(NULL),
m_pImporter(NULL),
m_pEmitter(NULL),
-#ifndef FEATURE_CORECLR
- m_pAssemblyImporter(NULL),
- m_pAssemblyEmitter(NULL),
-#endif
m_pMetadataLock(::new SimpleRWLock(PREEMPTIVE, LOCK_TYPE_DEFAULT)),
m_refCount(1),
m_hash(NULL),
m_flags(0),
m_fStrongNameVerified(FALSE)
-#ifdef FEATURE_CAS_POLICY
- ,m_certificate(NULL),
- m_fCheckedCertificate(FALSE)
- ,m_pSecurityManager(NULL)
- ,m_securityManagerLock(CrstPEFileSecurityManager)
-#endif // FEATURE_CAS_POLICY
,m_pHostAssembly(nullptr)
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
,m_pFallbackLoadContextBinder(nullptr)
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
{
CONTRACTL
{
@@ -126,12 +98,6 @@ PEFile::PEFile(PEImage *identity, BOOL fCheckAuthenticodeSignature/*=TRUE*/) :
}
-#ifdef FEATURE_CAS_POLICY
- if (fCheckAuthenticodeSignature)
- {
- CheckAuthenticodeSignature();
- }
-#endif // FEATURE_CAS_POLICY
}
@@ -168,14 +134,6 @@ PEFile::~PEFile()
m_identity->Release();
if (m_pMetadataLock)
delete m_pMetadataLock;
-#ifdef FEATURE_CAS_POLICY
- if (m_pSecurityManager) {
- m_pSecurityManager->Release();
- m_pSecurityManager = NULL;
- }
- if (m_certificate && !g_pCertificateCache->Contains(m_certificate))
- CoTaskMemFree(m_certificate);
-#endif // FEATURE_CAS_POLICY
if (m_pHostAssembly != NULL)
{
@@ -265,215 +223,6 @@ BOOL PEFile::CanLoadLibrary()
return IsILOnly();
}
-#ifdef FEATURE_MIXEDMODE
-
-#ifndef CROSSGEN_COMPILE
-
-// Returns TRUE if this file references managed CRT (msvcmNN*).
-BOOL PEFile::ReferencesManagedCRT()
-{
- STANDARD_VM_CONTRACT;
-
- IMDInternalImportHolder pImport = GetMDImport();
- MDEnumHolder hEnum(pImport);
-
- IfFailThrow(pImport->EnumInit(mdtModuleRef, mdTokenNil, &hEnum));
-
- mdModuleRef tk;
- while (pImport->EnumNext(&hEnum, &tk))
- {
- // we are looking for "msvcmNN*"
- LPCSTR szName;
- IfFailThrow(pImport->GetModuleRefProps(tk, &szName));
-
- if (_strnicmp(szName, "msvcm", 5) == 0 && isdigit(szName[5]) && isdigit(szName[6]))
- {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-void PEFile::CheckForDisallowedInProcSxSLoadWorker()
-{
- STANDARD_VM_CONTRACT;
-
- // provide an opt-out switch for now
- if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DisableIJWVersionCheck) != 0)
- return;
-
- // ************************************************************************************************
- // 1. See if this file should be checked
- // The following checks filter out non-mixed mode assemblies that don't reference msvcmNN*. We only
- // care about non-ILONLY images (IJW) or 2.0 C++/CLI pure images.
- if (IsResource() || IsDynamic())
- return;
-
- // check the metadata version string
- COUNT_T size;
- PVOID pMetaData = (PVOID)GetMetadata(&size);
- if (!pMetaData)
- {
- // No metadata section? Well somebody should have caught this earlier so report as
- // ExecutionEngine rather than BIF.
- EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
- }
-
- LPCSTR pVersion = NULL;
- IfFailThrow(GetImageRuntimeVersionString(pMetaData, &pVersion));
-
- char chV;
- unsigned uiMajor, uiMinor;
- BOOL fLegacyImage = (sscanf_s(pVersion, "%c%u.%u", &chV, 1, &uiMajor, &uiMinor) == 3 && (chV == W('v') || chV == W('V')) && uiMajor <= 2);
-
- // Note that having VTFixups properly working really is limited to non-ILONLY images. In particular,
- // the shim does not even attempt to patch ILONLY images in any way with bootstrap thunks.
- if (IsILOnly())
- {
- // all >2.0 ILONLY images are fine because >2.0 managed CRTs can be loaded in multiple runtimes
- if (!fLegacyImage)
- return;
-
- // legacy ILONLY images that don't reference the managed CRT are fine
- if (!ReferencesManagedCRT())
- return;
- }
-
- // get the version of this runtime
- WCHAR wzThisRuntimeVersion[_MAX_PATH];
- DWORD cchVersion = COUNTOF(wzThisRuntimeVersion);
- IfFailThrow(g_pCLRRuntime->GetVersionString(wzThisRuntimeVersion, &cchVersion));
-
- // ************************************************************************************************
- // 2. For legacy assemblies, verify that legacy APIs are/would be bound to this runtime
- if (fLegacyImage)
- {
- WCHAR wzAPIVersion[_MAX_PATH];
- bool fLegacyAPIsAreBound = false;
-
- { // Check if the legacy APIs have already been bound to us using the new hosting APIs.
- ReleaseHolder<ICLRMetaHost> pMetaHost;
- IfFailThrow(CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost));
-
- ReleaseHolder<ICLRRuntimeInfo> pInfo;
- // Returns S_FALSE when no runtime is currently bound, S_OK when one is.
- HRESULT hr = pMetaHost->QueryLegacyV2RuntimeBinding(IID_ICLRRuntimeInfo, (LPVOID*)&pInfo);
- IfFailThrow(hr);
-
- if (hr == S_OK)
- { // Legacy APIs are bound, now check if they are bound to us.
- fLegacyAPIsAreBound = true;
-
- cchVersion = COUNTOF(wzAPIVersion);
- IfFailThrow(pInfo->GetVersionString(wzAPIVersion, &cchVersion));
-
- if (SString::_wcsicmp(wzThisRuntimeVersion, wzAPIVersion) == 0)
- { // This runtime is the one bound to the legacy APIs, ok to load legacy assembly.
- return;
- }
- }
- }
-
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4996) // we are going to call deprecated APIs
-#endif
- // We need the above QueryLegacyV2RuntimeBinding check because GetRequestedRuntimeInfo will not take into
- // account the current binding, which could have been set by the host rather than through an EXE config.
- // If, however, the legacy APIs are not bound (indicated in fLegacyAPIsAreBound) then we can assume that
- // the legacy APIs would bind using the equivalent of CorBindToRuntime(NULL) as a result of loading this
- // legacy IJW assembly, and so we use GetRequestedRuntimeInfo to check without actually causing the bind.
- // By avoiding causing the bind, we avoid a binding side effect in the failure case.
- if (!fLegacyAPIsAreBound &&
- SUCCEEDED(GetRequestedRuntimeInfo(NULL, NULL, NULL, 0, // pExe, pwszVersion, pConfigurationFile, startupFlags
- RUNTIME_INFO_UPGRADE_VERSION | RUNTIME_INFO_DONT_RETURN_DIRECTORY | RUNTIME_INFO_DONT_SHOW_ERROR_DIALOG,
- NULL, 0, NULL, // pDirectory, dwDirectory, pdwDirectoryLength
- wzAPIVersion, COUNTOF(wzAPIVersion), &cchVersion))) // pVersion, cchBuffer, pdwLength
- {
- if (SString::_wcsicmp(wzThisRuntimeVersion, wzAPIVersion) == 0)
- {
- // it came back as this version - call CorBindToRuntime to actually bind it
- ReleaseHolder<ICLRRuntimeHost> pHost;
- IfFailThrow(CorBindToRuntime(wzAPIVersion, NULL, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID *)&pHost));
-
- // and verify that nobody beat us to it
- IfFailThrow(GetCORVersion(wzAPIVersion, COUNTOF(wzAPIVersion), &cchVersion));
-
- if (SString::_wcsicmp(wzThisRuntimeVersion, wzAPIVersion) == 0)
- {
- // we have verified that when the assembly calls CorBindToRuntime(NULL),
- // it will get this runtime, so we allow it to be loaded
- return;
- }
- }
- }
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
- MAKE_WIDEPTR_FROMUTF8(pwzVersion, pVersion);
-
- ExternalLog(LF_LOADER, LL_ERROR, W("ERR: Rejecting IJW module built against %s because it could be loaded into another runtime in this process."), pwzVersion);
- COMPlusThrow(kFileLoadException, IDS_EE_IJWLOAD_CROSSVERSION_DISALLOWED, pwzVersion, QUOTE_MACRO_L(VER_MAJORVERSION.VER_MINORVERSION));
- }
-
- // ************************************************************************************************
- // 3. For 4.0+ assemblies, verify that it hasn't been loaded into another runtime
- ReleaseHolder<ICLRRuntimeHostInternal> pRuntimeHostInternal;
- IfFailThrow(g_pCLRRuntime->GetInterface(CLSID_CLRRuntimeHostInternal,
- IID_ICLRRuntimeHostInternal,
- &pRuntimeHostInternal));
-
- PTR_VOID pModuleBase = GetLoadedIL()->GetBase();
-
- ReleaseHolder<ICLRRuntimeInfo> pRuntimeInfo;
- HRESULT hr = pRuntimeHostInternal->LockModuleForRuntime((BYTE *)pModuleBase, IID_ICLRRuntimeInfo, &pRuntimeInfo);
-
- IfFailThrow(hr);
-
- if (hr == S_OK)
- {
- // this runtime was the first one to lock the module
- return;
- }
-
- // another runtime has loaded this module so we have to block the load
- WCHAR wzLoadedRuntimeVersion[_MAX_PATH];
- cchVersion = COUNTOF(wzLoadedRuntimeVersion);
- IfFailThrow(pRuntimeInfo->GetVersionString(wzLoadedRuntimeVersion, &cchVersion));
-
- ExternalLog(LF_LOADER, LL_ERROR, W("ERR: Rejecting IJW module because it is already loaded into runtime version %s in this process."), wzLoadedRuntimeVersion);
- COMPlusThrow(kFileLoadException, IDS_EE_IJWLOAD_MULTIRUNTIME_DISALLOWED, wzThisRuntimeVersion, wzLoadedRuntimeVersion);
-}
-
-// We don't allow loading IJW and C++/CLI pure images built against <=2.0 if legacy APIs are not bound to this
-// runtime. For IJW images built against >2.0, we don't allow the load if the image has already been loaded by
-// another runtime in this process.
-void PEFile::CheckForDisallowedInProcSxSLoad()
-{
- STANDARD_VM_CONTRACT;
-
- // have we checked this one before?
- if (!IsInProcSxSLoadVerified())
- {
- CheckForDisallowedInProcSxSLoadWorker();
-
- // if no exception was thrown, remember the fact that we don't have to do the check again
- SetInProcSxSLoadVerified();
- }
-}
-
-#else // CROSSGEN_COMPILE
-
-void PEFile::CheckForDisallowedInProcSxSLoad()
-{
- // Noop for crossgen
-}
-
-#endif // CROSSGEN_COMPILE
-
-#endif // FEATURE_MIXEDMODE
//-----------------------------------------------------------------------------------------------------
@@ -543,12 +292,6 @@ void PEFile::LoadLibrary(BOOL allowNativeSkip/*=TRUE*/) // if allowNativeSkip==F
// See if we've already loaded it.
if (CheckLoaded(allowNativeSkip))
{
-#ifdef FEATURE_MIXEDMODE
- // Prevent loading C++/CLI images into multiple runtimes in the same process. Note that if ILOnly images
- // stop being LoadLibrary'ed, the check for pure 2.0 C++/CLI images will need to be done somewhere else.
- if (!IsIntrospectionOnly())
- CheckForDisallowedInProcSxSLoad();
-#endif // FEATURE_MIXEDMODE
RETURN;
}
@@ -639,11 +382,6 @@ void PEFile::LoadLibrary(BOOL allowNativeSkip/*=TRUE*/) // if allowNativeSkip==F
}
}
-#ifdef FEATURE_MIXEDMODE
- // Prevent loading C++/CLI images into multiple runtimes in the same process. Note that if ILOnly images
- // stop being LoadLibrary'ed, the check for pure 2.0 C++/CLI images will need to be done somewhere else.
- CheckForDisallowedInProcSxSLoad();
-#endif // FEATURE_MIXEDMODE
RETURN;
}
@@ -839,86 +577,6 @@ void PEFile::GetCodeBaseOrName(SString &result)
result.SetUTF8(GetSimpleName());
}
-#ifdef FEATURE_CAS_POLICY
-
-// Returns security information for the assembly based on the codebase
-void PEFile::GetSecurityIdentity(SString &codebase, SecZone *pdwZone, DWORD dwFlags, BYTE *pbUniqueID, DWORD *pcbUniqueID)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pdwZone));
- PRECONDITION(CheckPointer(pbUniqueID));
- PRECONDITION(CheckPointer(pcbUniqueID));
- }
- CONTRACTL_END;
-
- if (IsAssembly())
- {
- ((PEAssembly*)this)->GetCodeBase(codebase);
- }
- else if (m_identity != NULL && !m_identity->GetPath().IsEmpty())
- {
- codebase.Set(W("file:///"));
- codebase.Append(m_identity->GetPath());
- }
- else
- {
- _ASSERTE( !"Unable to determine security identity" );
- }
-
- GCX_PREEMP();
-
- if(!codebase.IsEmpty())
- {
- *pdwZone = NoZone;
-
- InitializeSecurityManager();
-
- // We have a class name, return a class factory for it
- _ASSERTE(sizeof(SecZone) == sizeof(DWORD));
- IfFailThrow(m_pSecurityManager->MapUrlToZone(codebase,
- reinterpret_cast<DWORD *>(pdwZone),
- dwFlags));
-
- if (*pdwZone>=NumZones)
- IfFailThrow(SecurityPolicy::ApplyCustomZoneOverride(pdwZone));
-
- IfFailThrow(m_pSecurityManager->GetSecurityId(codebase,
- pbUniqueID,
- pcbUniqueID,
- 0));
- }
-}
-
-void PEFile::InitializeSecurityManager()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- CAN_TAKE_LOCK;
- MODE_PREEMPTIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- if(m_pSecurityManager == NULL)
- {
- CrstHolder holder(&m_securityManagerLock);
- if (m_pSecurityManager == NULL)
- {
- IfFailThrow(CoInternetCreateSecurityManager(NULL,
- &m_pSecurityManager,
- 0));
- }
- }
-}
-
-#endif // FEATURE_CAS_POLICY
// ------------------------------------------------------------
// Checks
@@ -945,42 +603,6 @@ CHECK PEFile::CheckLoaded(BOOL bAllowNativeSkip/*=TRUE*/)
CHECK_OK;
}
-#ifndef FEATURE_CORECLR
-// ------------------------------------------------------------
-// Hash support
-// ------------------------------------------------------------
-
-#ifndef SHA1_HASH_SIZE
-#define SHA1_HASH_SIZE 20
-#endif
-
-void PEFile::GetSHA1Hash(SBuffer &result)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- PRECONDITION(CheckValue(result));
- THROWS;
- MODE_ANY;
- GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- // Cache the SHA1 hash in a buffer
- if (m_hash == NULL)
- {
- // We shouldn't have to compute a SHA1 hash in any scenarios
- // where the image opening should be suppressed.
- EnsureImageOpened();
-
- m_hash = new InlineSBuffer<SHA1_HASH_SIZE>();
- GetILimage()->ComputeHash(CALG_SHA1, *m_hash);
- }
-
- result.Set(*m_hash);
-}
-#endif // FEATURE_CORECLR
// ------------------------------------------------------------
// Metadata access
@@ -1242,9 +864,7 @@ void PEFile::OpenMDImport_Unsafe()
return;
#ifdef FEATURE_PREJIT
if (m_nativeImage != NULL
-#ifdef FEATURE_CORECLR
&& m_nativeImage->GetMDImport() != NULL
-#endif
)
{
// Use native image for metadata
@@ -1297,58 +917,6 @@ void PEFile::OpenEmitter()
pIMDEmit->Release();
}
-#ifndef FEATURE_CORECLR
-void PEFile::OpenAssemblyImporter()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- // Make sure internal MD is in RW format.
- ConvertMDInternalToReadWrite();
-
- // Get the interface
- IMetaDataAssemblyImport *pIMDAImport = NULL;
- IfFailThrow(GetMetaDataPublicInterfaceFromInternal((void*)GetPersistentMDImport(),
- IID_IMetaDataAssemblyImport,
- (void **)&pIMDAImport));
-
- // Atomically swap it into the field (release it if we lose the race)
- if (FastInterlockCompareExchangePointer(&m_pAssemblyImporter, pIMDAImport, NULL) != NULL)
- pIMDAImport->Release();
-}
-
-void PEFile::OpenAssemblyEmitter()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- // Make sure internal MD is in RW format.
- ConvertMDInternalToReadWrite();
-
- IMetaDataAssemblyEmit *pIMDAssemblyEmit = NULL;
- IfFailThrow(GetMetaDataPublicInterfaceFromInternal((void*)GetPersistentMDImport(),
- IID_IMetaDataAssemblyEmit,
- (void **)&pIMDAssemblyEmit));
-
- // Atomically swap it into the field (release it if we lose the race)
- if (FastInterlockCompareExchangePointer(&m_pAssemblyEmitter, pIMDAssemblyEmit, NULL) != NULL)
- pIMDAssemblyEmit->Release();
-}
-#endif // FEATURE_CORECLR
void PEFile::ReleaseMetadataInterfaces(BOOL bDestructor, BOOL bKeepNativeData/*=FALSE*/)
{
@@ -1362,18 +930,6 @@ void PEFile::ReleaseMetadataInterfaces(BOOL bDestructor, BOOL bKeepNativeData/*=
}
CONTRACTL_END;
_ASSERTE(bDestructor || !m_bHasPersistentMDImport);
-#ifndef FEATURE_CORECLR
- if (m_pAssemblyImporter != NULL)
- {
- m_pAssemblyImporter->Release();
- m_pAssemblyImporter = NULL;
- }
- if(m_pAssemblyEmitter)
- {
- m_pAssemblyEmitter->Release();
- m_pAssemblyEmitter=NULL;
- }
-#endif
if (m_pImporter != NULL)
{
@@ -1393,161 +949,6 @@ void PEFile::ReleaseMetadataInterfaces(BOOL bDestructor, BOOL bKeepNativeData/*=
}
}
-#ifdef FEATURE_CAS_POLICY
-
-void PEFile::CheckAuthenticodeSignature()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- // Check any security signature in the header.
-
- // This publisher data can potentially be cached and passed back in via
- // PEAssembly::CreateDelayed.
- //
- // HOWEVER - even if we cache it, the certificate still may need to be verified at
- // load time. The only real caching can be done when the COR_TRUST certificate is
- // ABSENT.
- //
- // (In the case where it is present, we could still theoretically
- // cache the certificate and re-verify it and at least avoid touching the image
- // again, however this path is not implemented yet, so this is TBD if we decide
- // it is an important case to optimize for.)
-
- if (!HasSecurityDirectory())
- {
- LOG((LF_SECURITY, LL_INFO1000, "No certificates found in module\n"));
- }
- else if(g_pConfig->GeneratePublisherEvidence())
- {
- // <TODO>@todo: Just because we don't have a file path, doesn't mean we can't have a certicate (does it?)</TODO>
- if (!GetPath().IsEmpty())
- {
- GCX_PREEMP();
-
- // Ignore any errors here - if we fail to validate a certificate, we just don't
- // include it as evidence.
-
- DWORD size;
- CoTaskNewHolder<COR_TRUST> pCor = NULL;
- // Failing to find a signature is OK.
- LPWSTR pFileName = (LPWSTR) GetPath().GetUnicode();
- DWORD dwAuthFlags = COR_NOUI|COR_NOPOLICY;
-#ifndef FEATURE_CORECLR
- // Authenticode Verification Start
- FireEtwAuthenticodeVerificationStart_V1(dwAuthFlags, 0, pFileName, GetClrInstanceId());
-#endif // !FEATURE_CORECLR
-
- HRESULT hr = ::GetPublisher(pFileName,
- NULL,
- dwAuthFlags,
- &pCor,
- &size);
-
-#ifndef FEATURE_CORECLR
- // Authenticode Verification End
- FireEtwAuthenticodeVerificationStop_V1(dwAuthFlags, (ULONG)hr, pFileName, GetClrInstanceId());
-#endif // !FEATURE_CORECLR
-
- if( SUCCEEDED(hr) ) {
- DWORD index = 0;
- EnumCertificateAdditionFlags dwFlags = g_pCertificateCache->AddEntry(pCor, &index);
- switch (dwFlags) {
- case CacheSaturated:
- pCor.SuppressRelease();
- m_certificate = pCor.GetValue();
- break;
-
- case Success:
- pCor.SuppressRelease();
- // falling through
- case AlreadyExists:
- m_certificate = g_pCertificateCache->GetEntry(index);
- _ASSERTE(m_certificate);
- break;
- }
- }
- }
- }
- else
- {
- LOG((LF_SECURITY, LL_INFO1000, "Assembly has an Authenticode signature, but Publisher evidence has been disabled.\n"));
- }
-
- m_fCheckedCertificate = TRUE;
-}
-
-HRESULT STDMETHODCALLTYPE
-GetPublisher(__in __in_z IN LPWSTR pwsFileName, // File name, this is required even with the handle
- IN HANDLE hFile, // Optional file name
- IN DWORD dwFlags, // COR_NOUI or COR_NOPOLICY
- OUT PCOR_TRUST *pInfo, // Returns a PCOR_TRUST (Use FreeM)
- OUT DWORD *dwInfo) // Size of pInfo.
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- GUID gV2 = COREE_POLICY_PROVIDER;
- COR_POLICY_PROVIDER sCorPolicy;
-
- WINTRUST_DATA sWTD;
- WINTRUST_FILE_INFO sWTFI;
-
- // Set up the COR trust provider
- memset(&sCorPolicy, 0, sizeof(COR_POLICY_PROVIDER));
- sCorPolicy.cbSize = sizeof(COR_POLICY_PROVIDER);
-
- // Set up the winverify provider structures
- memset(&sWTD, 0x00, sizeof(WINTRUST_DATA));
- memset(&sWTFI, 0x00, sizeof(WINTRUST_FILE_INFO));
-
- sWTFI.cbStruct = sizeof(WINTRUST_FILE_INFO);
- sWTFI.hFile = hFile;
- sWTFI.pcwszFilePath = pwsFileName;
-
- sWTD.cbStruct = sizeof(WINTRUST_DATA);
- sWTD.pPolicyCallbackData = &sCorPolicy; // Add in the cor trust information!!
- if (dwFlags & COR_NOUI)
- {
- sWTD.dwUIChoice = WTD_UI_NONE; // No bad UI is overridden in COR TRUST provider
- }
- else
- {
- sWTD.dwUIChoice = WTD_UI_ALL; // No bad UI is overridden in COR TRUST provider
- }
- sWTD.dwUnionChoice = WTD_CHOICE_FILE;
- sWTD.pFile = &sWTFI;
-
- // Set the policies for the VM (we have stolen VMBased and use it like a flag)
- if (dwFlags != 0)
- sCorPolicy.VMBased = dwFlags;
-
- LeaveRuntimeHolder holder((size_t)WinVerifyTrust);
-
- // WinVerifyTrust calls mscorsecimpl.dll to do the policy check
- hr = WinVerifyTrust(GetFocus(), &gV2, &sWTD);
-
- *pInfo = sCorPolicy.pbCorTrust;
- *dwInfo = sCorPolicy.cbCorTrust;
-
- return hr;
-} // GetPublisher
-
-#endif // FEATURE_CAS_POLICY
// ------------------------------------------------------------
// PE file access
@@ -1699,19 +1100,6 @@ static void RuntimeVerifyVLog(DWORD level, LoggableAssembly *pLogAsm, const WCHA
WszOutputDebugString(W("\n"));
}
-#ifdef FEATURE_FUSION
- IFusionBindLog *pFusionBindLog = pLogAsm->FusionBindLog();
- if (pFusionBindLog)
- {
- pFusionBindLog->LogMessage(0, FUSION_BIND_LOG_CATEGORY_NGEN, message);
-
- if (level == LL_ERROR) {
- pFusionBindLog->SetResultCode(FUSION_BIND_LOG_CATEGORY_NGEN, E_FAIL);
- pFusionBindLog->Flush(g_dwLogLevel, FUSION_BIND_LOG_CATEGORY_NGEN);
- pFusionBindLog->Flush(g_dwLogLevel, FUSION_BIND_LOG_CATEGORY_DEFAULT);
- }
- }
-#endif //FEATURE_FUSION
}
@@ -1725,9 +1113,6 @@ static void RuntimeVerifyLog(DWORD level, LoggableAssembly *pLogAsm, const WCHAR
// Avoid calling RuntimeVerifyVLog unless logging is on
if ( ((level == LL_ERROR) && IsDebuggerPresent())
|| LoggingOn(LF_ZAP, level)
-#ifdef FEATURE_FUSION
- || (pLogAsm->FusionBindLog() != NULL)
-#endif
)
{
va_list args;
@@ -1743,17 +1128,10 @@ static void RuntimeVerifyLog(DWORD level, LoggableAssembly *pLogAsm, const WCHAR
static const LPCWSTR CorCompileRuntimeDllNames[NUM_RUNTIME_DLLS] =
{
-#ifdef FEATURE_CORECLR
MAKEDLLNAME_W(W("coreclr")),
-#else
- MAKEDLLNAME_W(W("CLR")),
-#endif
MAKEDLLNAME_W(W("clrjit"))
};
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-static LPCWSTR s_ngenCompilerDllName = NULL;
-#endif //!FEATURE_CORECLR && !CROSSGEN_COMPILE
LPCWSTR CorCompileGetRuntimeDllName(CorCompileRuntimeDlls id)
{
@@ -1767,36 +1145,6 @@ LPCWSTR CorCompileGetRuntimeDllName(CorCompileRuntimeDlls id)
}
CONTRACTL_END;
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- if (id == NGEN_COMPILER_INFO)
- {
- // The NGen compiler needs to be handled differently as it can be customized,
- // unlike the other runtime DLLs.
-
- if (s_ngenCompilerDllName == NULL)
- {
- // Check if there is an override for the compiler DLL
- LPCWSTR ngenCompilerOverride = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_NGen_JitName);
-
- if (ngenCompilerOverride == NULL)
- {
- s_ngenCompilerDllName = DEFAULT_NGEN_COMPILER_DLL_NAME;
- }
- else
- {
- if (wcsstr(ngenCompilerOverride, W(".dll")) == NULL)
- {
- EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_EXECUTIONENGINE,
- NGEN_COMPILER_OVERRIDE_KEY W(" should have a .DLL suffix"));
- }
-
- s_ngenCompilerDllName = ngenCompilerOverride;
- }
- }
-
- return s_ngenCompilerDllName;
- }
-#endif //!FEATURE_CORECLR && !CROSSGEN_COMPILE
return CorCompileRuntimeDllNames[id];
}
@@ -1823,33 +1171,17 @@ extern HMODULE CorCompileGetRuntimeDll(CorCompileRuntimeDlls id)
CONTRACTL_END;
// Currently special cased for every entry.
-#ifdef FEATURE_CORECLR
static_assert_no_msg(NUM_RUNTIME_DLLS == 2);
static_assert_no_msg(CORECLR_INFO == 0);
-#else // !FEATURE_CORECLR
- static_assert_no_msg(NUM_RUNTIME_DLLS == 2);
- static_assert_no_msg(CLR_INFO == 0);
- static_assert_no_msg(NGEN_COMPILER_INFO == 1);
-#endif // else FEATURE_CORECLR
HMODULE hMod = NULL;
// Try to load the correct DLL
switch (id)
{
-#ifdef FEATURE_CORECLR
case CORECLR_INFO:
hMod = GetCLRModule();
break;
-#else // !FEATURE_CORECLR
- case CLR_INFO:
- hMod = GetCLRModule();
- break;
-
- case NGEN_COMPILER_INFO:
- hMod = s_ngenCompilerDll;
- break;
-#endif // else FEATURE_CORECLR
default:
COMPlusThrowNonLocalized(kExecutionEngineException,
@@ -1869,68 +1201,6 @@ static BOOL RuntimeVerifyNativeImageTimestamps(const CORCOMPILE_VERSION_INFO *in
{
STANDARD_VM_CONTRACT;
-#if !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- //
- // We will automatically fail any zap files which were compiled with different runtime dlls.
- // This is so that we don't load bad ngen images after recompiling or patching the runtime.
- //
-
- for (DWORD index = 0; index < NUM_RUNTIME_DLLS; index++)
- {
- HMODULE hMod = CorCompileGetRuntimeDll((CorCompileRuntimeDlls)index);
-
- if (hMod == NULL)
- {
- // Unless this is an NGen worker process, we don't want to load JIT compiler just to do a timestamp check.
- // In an ideal case, all assemblies have native images, and JIT compiler never needs to be loaded at runtime.
- // Loading JIT compiler just to check its timestamp would reduce the benefits of have native images.
- // Since CLR and JIT are intended to be serviced together, the possibility of accidentally using native
- // images created by an older JIT is very small, and is deemed an acceptable risk.
- // Note that when multiple JIT compilers are used (e.g., clrjit.dll and compatjit.dll on x64 in .NET 4.6),
- // they must all be in the same patch family.
- if (!IsCompilationProcess())
- continue;
-
- // If we are doing ngen, then eagerly make sure all the system
- // dependencies are loaded. Else ICorCompileInfo::CheckAssemblyZap()
- // will not work correctly.
-
- LPCWSTR wszDllName = CorCompileGetRuntimeDllName((CorCompileRuntimeDlls)index);
- if (FAILED(g_pCLRRuntime->LoadLibrary(wszDllName, &hMod)))
- {
- EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_EXECUTIONENGINE, W("Unable to load CLR DLL during ngen"));
- }
- }
-
- _ASSERTE(hMod != NULL);
-
- PEDecoder pe(hMod);
-
- // Match NT header timestamp and checksum to test DLL identity
-
- if ((info->runtimeDllInfo[index].timeStamp == pe.GetTimeDateStamp()
- || info->runtimeDllInfo[index].timeStamp == 0)
- && (info->runtimeDllInfo[index].virtualSize == pe.GetVirtualSize()
- || info->runtimeDllInfo[index].virtualSize == 0))
- {
- continue;
- }
-
- {
- // set "ComPlus_CheckNGenImageTimeStamp" to 0 to ignore time-stamp-checking
- static ConfigDWORD checkNGenImageTimeStamp;
- BOOL enforceCheck = checkNGenImageTimeStamp.val(CLRConfig::EXTERNAL_CheckNGenImageTimeStamp);
-
- RuntimeVerifyLog(enforceCheck ? LL_ERROR : LL_WARNING,
- pLogAsm,
- W("Compiled with different CLR DLL (%s). Exact match expected."),
- CorCompileGetRuntimeDllName((CorCompileRuntimeDlls)index));
-
- if (enforceCheck)
- return FALSE;
- }
- }
-#endif // !CROSSGEN_COMPILE && !FEATURE_CORECLR
return TRUE;
}
@@ -1955,12 +1225,8 @@ BOOL PEAssembly::CheckNativeImageVersion(PEImage *peimage)
if (!image->CheckNativeHeaderVersion())
{
-#ifdef FEATURE_CORECLR
// Wrong native image version is fatal error on CoreCLR
ThrowHR(COR_E_NI_AND_RUNTIME_VERSION_MISMATCH);
-#else
- return FALSE;
-#endif
}
CORCOMPILE_VERSION_INFO *info = image->GetNativeVersionInfo();
@@ -1970,15 +1236,10 @@ BOOL PEAssembly::CheckNativeImageVersion(PEImage *peimage)
LoggablePEAssembly logAsm(this);
if (!RuntimeVerifyNativeImageVersion(info, &logAsm))
{
-#ifdef FEATURE_CORECLR
// Wrong native image version is fatal error on CoreCLR
ThrowHR(COR_E_NI_AND_RUNTIME_VERSION_MISMATCH);
-#else
- return FALSE;
-#endif
}
-#ifdef FEATURE_CORECLR
CorCompileConfigFlags configFlags = PEFile::GetNativeImageConfigFlagsWithOverrides();
if (IsSystem())
@@ -1999,36 +1260,10 @@ BOOL PEAssembly::CheckNativeImageVersion(PEImage *peimage)
{
return FALSE;
}
-#else
- //
- // Check image flavor. Skip this check in RuntimeVerifyNativeImageVersion called from fusion - fusion is responsible for choosing the right flavor.
- //
- if (!RuntimeVerifyNativeImageFlavor(info, &logAsm))
- {
- return FALSE;
- }
-#endif
return TRUE;
}
-#ifndef FEATURE_CORECLR
-//===========================================================================================================
-// Validates that an NI matches the required flavor (debug, instrumented, etc.)
-//
-//===========================================================================================================
-BOOL RuntimeVerifyNativeImageFlavor(const CORCOMPILE_VERSION_INFO *info, LoggableAssembly *pLogAsm)
-{
- STANDARD_VM_CONTRACT;
-
- CorCompileConfigFlags configFlags = PEFile::GetNativeImageConfigFlagsWithOverrides();
-
- if ((info->wConfigFlags & configFlags) != configFlags)
- return FALSE;
-
- return TRUE;
-}
-#endif
//===========================================================================================================
// Validates that an NI matches the running CLR, OS, CPU, etc.
@@ -2100,18 +1335,6 @@ BOOL RuntimeVerifyNativeImageVersion(const CORCOMPILE_VERSION_INFO *info, Loggab
}
#endif // CROSSGEN_COMPILE
-#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR)
- //
- // Check the right JIT compiler
- //
-
- bool nativeImageBuiltWithRyuJit = ((info->wCodegenFlags & CORCOMPILE_CODEGEN_USE_RYUJIT) != 0);
- if (UseRyuJit() != nativeImageBuiltWithRyuJit)
- {
- RuntimeVerifyLog(LL_ERROR, pLogAsm, W("JIT compiler used to generate native image doesn't match current JIT compiler."));
- return FALSE;
- }
-#endif
//
// The zap is up to date.
@@ -2240,15 +1463,6 @@ BOOL RuntimeVerifyNativeImageDependency(const CORCOMPILE_NGEN_SIGNATURE &ngenSig
W("Rejecting native image because native image dependency %s ")
W("had a different identity than expected"),
displayString.GetUnicode());
-#if (defined FEATURE_PREJIT) && (defined FEATURE_FUSION)
- if (pLogAsm->FusionBindLog())
- {
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEFUSION_KEYWORD))
- {
- pLogAsm->FusionBindLog()->ETWTraceLogMessage(ETW::BinderLog::BinderStructs::NGEN_BIND_DEPENDENCY_HAS_DIFFERENT_IDENTITY, pLogAsm->FusionAssemblyName());
- }
- }
-#endif
return FALSE;
}
@@ -2677,18 +1891,7 @@ BOOL PEFile::GetResource(LPCSTR szName, DWORD *cbResource,
return TRUE;
}
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- // The resource is either linked or embedded in a non-manifest-containing file
- if (pDomainAssembly == NULL)
- return FALSE;
-
- return pDomainAssembly->GetModuleResource(mdLinkRef, szName, cbResource,
- pbInMemoryResource, szFileName,
- dwLocation, IsMrPublic(dwResourceFlags),
- pStackMark, fSkipSecurityCheck);
-#else
return FALSE;
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
default:
ThrowHR(COR_E_BADIMAGEFORMAT, BFA_INVALID_TOKEN_IN_MANIFESTRES);
@@ -2765,39 +1968,6 @@ ULONG PEFile::GetILImageTimeDateStamp()
return GetLoadedIL()->GetTimeDateStamp();
}
-#ifdef FEATURE_CAS_POLICY
-
-//---------------------------------------------------------------------------------------
-//
-// Get a SafePEFileHandle for this PEFile
-//
-
-SAFEHANDLE PEFile::GetSafeHandle()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- SAFEHANDLE objSafeHandle = NULL;
-
- GCPROTECT_BEGIN(objSafeHandle);
-
- objSafeHandle = (SAFEHANDLE)AllocateObject(MscorlibBinder::GetClass(CLASS__SAFE_PEFILE_HANDLE));
- CallDefaultConstructor(objSafeHandle);
-
- this->AddRef();
- objSafeHandle->SetHandle(this);
-
- GCPROTECT_END();
-
- return objSafeHandle;
-}
-
-#endif // FEATURE_CAS_POLICY
// ================================================================================
// PEAssembly class - a PEFile which represents an assembly
@@ -2810,169 +1980,6 @@ void PEAssembly::Attach()
STANDARD_VM_CONTRACT;
}
-#ifdef FEATURE_FUSION
-PEAssembly::PEAssembly(PEImage *image,
- IMetaDataEmit *pEmit,
- IAssembly *pIAssembly,
- IBindResult *pNativeFusionAssembly,
- PEImage *pPEImageNI,
- IFusionBindLog *pFusionLog,
- IHostAssembly *pIHostAssembly,
- PEFile *creator,
- BOOL system,
- BOOL introspectionOnly/*=FALSE*/,
- ICLRPrivAssembly * pHostAssembly)
- : PEFile(image, FALSE),
- m_creator(NULL),
- m_pFusionAssemblyName(NULL),
- m_pFusionAssembly(NULL),
- m_pFusionLog(NULL),
- m_bFusionLogEnabled(TRUE),
- m_pIHostAssembly(NULL),
- m_pNativeAssemblyLocation(NULL),
- m_pNativeImageClosure(NULL),
- m_fStrongNameBypassed(FALSE)
-{
- CONTRACTL
- {
- CONSTRUCTOR_CHECK;
- PRECONDITION(CheckPointer(image, NULL_OK));
- PRECONDITION(CheckPointer(pEmit, NULL_OK));
- PRECONDITION(image != NULL || pEmit != NULL);
- PRECONDITION(CheckPointer(pIAssembly, NULL_OK));
- PRECONDITION(CheckPointer(pFusionLog, NULL_OK));
- PRECONDITION(CheckPointer(pIHostAssembly, NULL_OK));
- PRECONDITION(CheckPointer(creator, NULL_OK));
- STANDARD_VM_CHECK;
- }
- CONTRACTL_END;
-
- if (introspectionOnly)
- {
- if (!system) // Implementation restriction: mscorlib.dll cannot be loaded as introspection. The architecture depends on there being exactly one mscorlib.
- {
- m_flags |= PEFILE_INTROSPECTIONONLY;
-#ifdef FEATURE_PREJIT
- SetCannotUseNativeImage();
-#endif // FEATURE_PREJIT
- }
- }
-
- if (pIAssembly)
- {
- m_pFusionAssembly = pIAssembly;
- pIAssembly->AddRef();
-
- IfFailThrow(pIAssembly->GetAssemblyNameDef(&m_pFusionAssemblyName));
- }
- else if (pIHostAssembly)
- {
- m_flags |= PEFILE_ISTREAM;
-#ifdef FEATURE_PREJIT
- m_fCanUseNativeImage = FALSE;
-#endif // FEATURE_PREJIT
-
- m_pIHostAssembly = pIHostAssembly;
- pIHostAssembly->AddRef();
-
- IfFailThrow(pIHostAssembly->GetAssemblyNameDef(&m_pFusionAssemblyName));
- }
-
- if (pFusionLog)
- {
- m_pFusionLog = pFusionLog;
- pFusionLog->AddRef();
- }
-
- if (creator)
- {
- m_creator = creator;
- creator->AddRef();
- }
-
- m_flags |= PEFILE_ASSEMBLY;
- if (system)
- m_flags |= PEFILE_SYSTEM;
-
-#ifdef FEATURE_PREJIT
- // Find the native image
- if (pIAssembly)
- {
- if (pNativeFusionAssembly != NULL)
- SetNativeImage(pNativeFusionAssembly);
- }
- // Only one of pNativeFusionAssembly and pPEImageNI may be set.
- _ASSERTE(!(pNativeFusionAssembly && pPEImageNI));
-
- if (pPEImageNI != NULL)
- this->PEFile::SetNativeImage(pPEImageNI);
-#endif // FEATURE_PREJIT
-
- // If we have no native image, we require a mapping for the file.
- if (!HasNativeImage() || !IsILOnly())
- EnsureImageOpened();
-
- // Open metadata eagerly to minimize failure windows
- if (pEmit == NULL)
- OpenMDImport_Unsafe(); //constructor, cannot race with anything
- else
- {
- _ASSERTE(!m_bHasPersistentMDImport);
- IfFailThrow(GetMetaDataInternalInterfaceFromPublic(pEmit, IID_IMDInternalImport,
- (void **)&m_pMDImport));
- m_pEmitter = pEmit;
- pEmit->AddRef();
- m_bHasPersistentMDImport=TRUE;
- m_MDImportIsRW_Debugger_Use_Only = TRUE;
- }
-
- // m_pMDImport can be external
- // Make sure this is an assembly
- if (!m_pMDImport->IsValidToken(TokenFromRid(1, mdtAssembly)))
- ThrowHR(COR_E_ASSEMBLYEXPECTED);
-
- // Make sure we perform security checks after we've obtained IMDInternalImport interface
- DoLoadSignatureChecks();
-
- // Verify name eagerly
- LPCUTF8 szName = GetSimpleName();
- if (!*szName)
- {
- ThrowHR(COR_E_BADIMAGEFORMAT, BFA_EMPTY_ASSEMDEF_NAME);
- }
-
-#ifdef FEATURE_PREJIT
- if (IsResource() || IsDynamic())
- m_fCanUseNativeImage = FALSE;
-#endif // FEATURE_PREJIT
-
- if (m_pFusionAssembly)
- {
- m_loadContext = m_pFusionAssembly->GetFusionLoadContext();
- m_pFusionAssembly->GetAssemblyLocation(&m_dwLocationFlags);
- }
- else if (pHostAssembly != nullptr)
- {
- m_loadContext = LOADCTX_TYPE_HOSTED;
- m_dwLocationFlags = ASMLOC_UNKNOWN;
- m_pHostAssembly = clr::SafeAddRef(pHostAssembly); // Should use SetHostAssembly(pHostAssembly) here
- }
- else
- {
- m_loadContext = LOADCTX_TYPE_UNKNOWN;
- m_dwLocationFlags = ASMLOC_UNKNOWN;
- }
-
- TESTHOOKCALL(CompletedNativeImageBind(image,szName,HasNativeImage()));
-
-#if _DEBUG
- GetCodeBaseOrName(m_debugName);
- m_debugName.Normalize();
- m_pDebugName = m_debugName;
-#endif
-}
-
-#else // FEATURE_FUSION
PEAssembly::PEAssembly(
CoreBindResult* pBindResultInfo,
@@ -2990,11 +1997,7 @@ PEAssembly::PEAssembly(
m_creator(clr::SafeAddRef(creator)),
m_bIsFromGAC(FALSE),
m_bIsOnTpaList(FALSE)
-#ifdef FEATURE_CORECLR
,m_fProfileAssembly(0)
-#else
- ,m_fStrongNameBypassed(FALSE)
-#endif
{
CONTRACTL
{
@@ -3099,58 +2102,8 @@ PEAssembly::PEAssembly(
m_sTextualIdentity);
#endif
}
-#endif // FEATURE_FUSION
-
-
-#ifdef FEATURE_FUSION
-
-PEAssembly *PEAssembly::Open(
- PEAssembly *pParentAssembly,
- PEImage *pPEImageIL,
- BOOL isIntrospectionOnly)
-{
- STANDARD_VM_CONTRACT;
- PEAssembly * pPEAssembly = new PEAssembly(
- pPEImageIL, // PEImage
- nullptr, // IMetaDataEmit
- nullptr, // IAssembly
- nullptr, // IBindResult pNativeFusionAssembly
- nullptr, // PEImage *pNIImage
- nullptr, // IFusionBindLog
- nullptr, // IHostAssembly
- pParentAssembly, // creator
- FALSE, // isSystem
- isIntrospectionOnly, // isIntrospectionOnly
- NULL);
-
- return pPEAssembly;
-}
-
-PEAssembly *PEAssembly::Open(
- PEAssembly * pParent,
- PEImage * pPEImageIL,
- PEImage * pPEImageNI,
- ICLRPrivAssembly * pHostAssembly,
- BOOL fIsIntrospectionOnly)
-{
- STANDARD_VM_CONTRACT;
- PEAssembly * pPEAssembly = new PEAssembly(
- pPEImageIL, // PEImage
- nullptr, // IMetaDataEmit
- nullptr, // IAssembly
- nullptr, // IBindResult pNativeFusionAssembly
- pPEImageNI, // Native Image PEImage
- nullptr, // IFusionBindLog
- nullptr, // IHostAssembly
- pParent, // creator
- FALSE, // isSystem
- fIsIntrospectionOnly,
- pHostAssembly);
- return pPEAssembly;
-}
-#else //FEATURE_FUSION
PEAssembly *PEAssembly::Open(
PEAssembly * pParent,
@@ -3174,7 +2127,6 @@ PEAssembly *PEAssembly::Open(
return pPEAssembly;
}
-#endif // FEATURE_FUSION
PEAssembly::~PEAssembly()
{
@@ -3188,22 +2140,6 @@ PEAssembly::~PEAssembly()
CONTRACTL_END;
GCX_PREEMP();
-#ifdef FEATURE_FUSION
- if (m_pFusionAssemblyName != NULL)
- m_pFusionAssemblyName->Release();
- if (m_pFusionAssembly != NULL)
- m_pFusionAssembly->Release();
- if (m_pIHostAssembly != NULL)
- m_pIHostAssembly->Release();
- if (m_pNativeAssemblyLocation != NULL)
- {
- m_pNativeAssemblyLocation->Release();
- }
- if (m_pNativeImageClosure!=NULL)
- m_pNativeImageClosure->Release();
- if (m_pFusionLog != NULL)
- m_pFusionLog->Release();
-#endif // FEATURE_FUSION
if (m_creator != NULL)
m_creator->Release();
@@ -3222,35 +2158,6 @@ void PEAssembly::ReleaseIL()
CONTRACTL_END;
GCX_PREEMP();
-#ifdef FEATURE_FUSION
- if (m_pFusionAssemblyName != NULL)
- {
- m_pFusionAssemblyName->Release();
- m_pFusionAssemblyName=NULL;
- }
- if (m_pFusionAssembly != NULL)
- {
- m_pFusionAssembly->Release();
- m_pFusionAssembly=NULL;
- }
- if (m_pIHostAssembly != NULL)
- {
- m_pIHostAssembly->Release();
- m_pIHostAssembly=NULL;
- }
- if (m_pNativeAssemblyLocation != NULL)
- {
- m_pNativeAssemblyLocation->Release();
- m_pNativeAssemblyLocation=NULL;
- }
- _ASSERTE(m_pNativeImageClosure==NULL);
-
- if (m_pFusionLog != NULL)
- {
- m_pFusionLog->Release();
- m_pFusionLog=NULL;
- }
-#endif // FEATURE_FUSION
if (m_creator != NULL)
{
m_creator->Release();
@@ -3263,11 +2170,7 @@ void PEAssembly::ReleaseIL()
/* static */
-#ifdef FEATURE_FUSION
-PEAssembly *PEAssembly::OpenSystem(IApplicationContext * pAppCtx)
-#else
PEAssembly *PEAssembly::OpenSystem(IUnknown * pAppCtx)
-#endif
{
STANDARD_VM_CONTRACT;
@@ -3292,11 +2195,7 @@ PEAssembly *PEAssembly::OpenSystem(IUnknown * pAppCtx)
}
/* static */
-#ifdef FEATURE_FUSION
-PEAssembly *PEAssembly::DoOpenSystem(IApplicationContext * pAppCtx)
-#else
PEAssembly *PEAssembly::DoOpenSystem(IUnknown * pAppCtx)
-#endif
{
CONTRACT(PEAssembly *)
{
@@ -3305,84 +2204,6 @@ PEAssembly *PEAssembly::DoOpenSystem(IUnknown * pAppCtx)
}
CONTRACT_END;
-#ifdef FEATURE_FUSION
- SafeComHolder<IAssemblyName> pName;
- IfFailThrow(CreateAssemblyNameObject(&pName, W("mscorlib"), 0, NULL));
-
- UINT64 publicKeyValue = I64(CONCAT_MACRO(0x, VER_ECMA_PUBLICKEY));
- BYTE publicKeyToken[8] =
- {
- (BYTE) (publicKeyValue>>56),
- (BYTE) (publicKeyValue>>48),
- (BYTE) (publicKeyValue>>40),
- (BYTE) (publicKeyValue>>32),
- (BYTE) (publicKeyValue>>24),
- (BYTE) (publicKeyValue>>16),
- (BYTE) (publicKeyValue>>8),
- (BYTE) (publicKeyValue),
- };
-
- IfFailThrow(pName->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, publicKeyToken, sizeof(publicKeyToken)));
-
- USHORT version = VER_ASSEMBLYMAJORVERSION;
- IfFailThrow(pName->SetProperty(ASM_NAME_MAJOR_VERSION, &version, sizeof(version)));
- version = VER_ASSEMBLYMINORVERSION;
- IfFailThrow(pName->SetProperty(ASM_NAME_MINOR_VERSION, &version, sizeof(version)));
- version = VER_ASSEMBLYBUILD;
- IfFailThrow(pName->SetProperty(ASM_NAME_BUILD_NUMBER, &version, sizeof(version)));
- version = VER_ASSEMBLYBUILD_QFE;
- IfFailThrow(pName->SetProperty(ASM_NAME_REVISION_NUMBER, &version, sizeof(version)));
-
- IfFailThrow(pName->SetProperty(ASM_NAME_CULTURE, W(""), sizeof(WCHAR)));
-
-#ifdef FEATURE_PREJIT
-#ifdef PROFILING_SUPPORTED
- if (NGENImagesAllowed())
- {
- // Binding flags, zap string
- CorCompileConfigFlags configFlags = PEFile::GetNativeImageConfigFlagsWithOverrides();
- IfFailThrow(pName->SetProperty(ASM_NAME_CONFIG_MASK, &configFlags, sizeof(configFlags)));
-
- LPCWSTR configString = g_pConfig->ZapSet();
- IfFailThrow(pName->SetProperty(ASM_NAME_CUSTOM, (PVOID)configString,
- (DWORD) (wcslen(configString)+1)*sizeof(WCHAR)));
-
- // @TODO: Need some fuslogvw logging here
- }
-#endif //PROFILING_SUPPORTED
-#endif // FEATURE_PREJIT
-
- SafeComHolder<IAssembly> pIAssembly;
- SafeComHolder<IBindResult> pNativeFusionAssembly;
- SafeComHolder<IFusionBindLog> pFusionLog;
-
- {
- ETWOnStartup (FusionBinding_V1, FusionBindingEnd_V1);
- IfFailThrow(BindToSystem(pName, SystemDomain::System()->SystemDirectory(), NULL, pAppCtx, &pIAssembly, &pNativeFusionAssembly, &pFusionLog));
- }
-
- StackSString path;
- FusionBind::GetAssemblyManifestModulePath(pIAssembly, path);
-
- // Open the image with no required mapping. This will be
- // promoted to a real open if we don't have a native image.
- PEImageHolder image (PEImage::OpenImage(path));
-
- PEAssembly* pPEAssembly = new PEAssembly(image, NULL, pIAssembly,pNativeFusionAssembly, NULL, pFusionLog, NULL, NULL, TRUE, FALSE);
-
-#ifdef FEATURE_APPX_BINDER
- if (AppX::IsAppXProcess())
- {
- // Since mscorlib is loaded as a special case, create and assign an ICLRPrivAssembly for the new PEAssembly here.
- CLRPrivBinderAppX * pBinder = CLRPrivBinderAppX::GetOrCreateBinder();
- CLRPrivBinderFusion * pFusionBinder = pBinder->GetFusionBinder();
-
- pFusionBinder->BindMscorlib(pPEAssembly);
- }
-#endif
-
- RETURN pPEAssembly;
-#else // FEATURE_FUSION
ETWOnStartup (FusionBinding_V1, FusionBindingEnd_V1);
CoreBindResult bindResult;
ReleaseHolder<ICLRPrivAssembly> pPrivAsm;
@@ -3393,153 +2214,8 @@ PEAssembly *PEAssembly::DoOpenSystem(IUnknown * pAppCtx)
}
RETURN new PEAssembly(&bindResult, NULL, NULL, TRUE, FALSE);
-#endif // FEATURE_FUSION
-}
-
-#ifdef FEATURE_FUSION
-/* static */
-PEAssembly *PEAssembly::Open(IAssembly *pIAssembly,
- IBindResult *pNativeFusionAssembly,
- IFusionBindLog *pFusionLog/*=NULL*/,
- BOOL isSystemAssembly/*=FALSE*/,
- BOOL isIntrospectionOnly/*=FALSE*/)
-{
- STANDARD_VM_CONTRACT;
-
- PEAssembly *result = NULL;
- EX_TRY
- {
- result = DoOpen(pIAssembly, pNativeFusionAssembly, pFusionLog, isSystemAssembly, isIntrospectionOnly);
- }
- EX_HOOK
- {
- Exception *ex = GET_EXCEPTION();
-
- // Rethrow non-transient exceptions as file load exceptions with proper
- // context
- if (!ex->IsTransient())
- EEFileLoadException::Throw(pIAssembly, NULL, ex->GetHR(), ex);
- }
- EX_END_HOOK;
-
- return result;
-}
-
-// Thread stress
-class DoOpenIAssemblyStress : APIThreadStress
-{
-public:
- IAssembly *pIAssembly;
- IBindResult *pNativeFusionAssembly;
- IFusionBindLog *pFusionLog;
- DoOpenIAssemblyStress(IAssembly *pIAssembly, IBindResult *pNativeFusionAssembly, IFusionBindLog *pFusionLog)
- : pIAssembly(pIAssembly), pNativeFusionAssembly(pNativeFusionAssembly),pFusionLog(pFusionLog) {LIMITED_METHOD_CONTRACT;}
- void Invoke()
- {
- WRAPPER_NO_CONTRACT;
- PEAssemblyHolder result (PEAssembly::Open(pIAssembly, pNativeFusionAssembly, pFusionLog, FALSE, FALSE));
- }
-};
-
-/* static */
-PEAssembly *PEAssembly::DoOpen(IAssembly *pIAssembly,
- IBindResult *pNativeFusionAssembly,
- IFusionBindLog *pFusionLog,
- BOOL isSystemAssembly,
- BOOL isIntrospectionOnly/*=FALSE*/)
-{
- CONTRACT(PEAssembly *)
- {
- PRECONDITION(CheckPointer(pIAssembly));
- POSTCONDITION(CheckPointer(RETVAL));
- STANDARD_VM_CHECK;
- }
- CONTRACT_END;
-
- DoOpenIAssemblyStress ts(pIAssembly,pNativeFusionAssembly,pFusionLog);
-
- PEImageHolder image;
-
- StackSString path;
- FusionBind::GetAssemblyManifestModulePath(pIAssembly, path);
-
- // Open the image with no required mapping. This will be
- // promoted to a real open if we don't have a native image.
- image = PEImage::OpenImage(path, MDInternalImport_NoCache); // "identity" does not need to be cached
-
- PEAssemblyHolder assembly (new PEAssembly(image, NULL, pIAssembly, pNativeFusionAssembly, NULL, pFusionLog,
- NULL, NULL, isSystemAssembly, isIntrospectionOnly));
-
- RETURN assembly.Extract();
}
-/* static */
-PEAssembly *PEAssembly::Open(IHostAssembly *pIHostAssembly, BOOL isSystemAssembly, BOOL isIntrospectionOnly)
-{
- STANDARD_VM_CONTRACT;
-
- PEAssembly *result = NULL;
-
- EX_TRY
- {
- result = DoOpen(pIHostAssembly, isSystemAssembly, isIntrospectionOnly);
- }
- EX_HOOK
- {
- Exception *ex = GET_EXCEPTION();
-
- // Rethrow non-transient exceptions as file load exceptions with proper
- // context
-
- if (!ex->IsTransient())
- EEFileLoadException::Throw(NULL, pIHostAssembly, ex->GetHR(), ex);
- }
- EX_END_HOOK;
- return result;
-}
-
-// Thread stress
-class DoOpenIHostAssemblyStress : APIThreadStress
-{
-public:
- IHostAssembly *pIHostAssembly;
- DoOpenIHostAssemblyStress(IHostAssembly *pIHostAssembly) :
- pIHostAssembly(pIHostAssembly) {LIMITED_METHOD_CONTRACT;}
- void Invoke()
- {
- WRAPPER_NO_CONTRACT;
- PEAssemblyHolder result (PEAssembly::Open(pIHostAssembly, FALSE, FALSE));
- }
-};
-
-/* static */
-PEAssembly *PEAssembly::DoOpen(IHostAssembly *pIHostAssembly, BOOL isSystemAssembly,
- BOOL isIntrospectionOnly)
-{
- CONTRACT(PEAssembly *)
- {
- PRECONDITION(CheckPointer(pIHostAssembly));
- POSTCONDITION(CheckPointer(RETVAL));
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- DoOpenIHostAssemblyStress ts(pIHostAssembly);
-
- UINT64 AssemblyId;
- IfFailThrow(pIHostAssembly->GetAssemblyId(&AssemblyId));
-
- PEImageHolder image(PEImage::FindById(AssemblyId, 0));
-
- PEAssemblyHolder assembly (new PEAssembly(image, NULL, NULL, NULL, NULL, NULL,
- pIHostAssembly, NULL, isSystemAssembly, isIntrospectionOnly));
-
- RETURN assembly.Extract();
-}
-#endif // FEATURE_FUSION
#ifndef CROSSGEN_COMPILE
/* static */
@@ -3621,114 +2297,18 @@ PEAssembly *PEAssembly::DoOpenMemory(
if (!image->CheckILFormat())
ThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL);
-#if !defined(FEATURE_CORECLR)
- if(pBinderToUse != NULL && !isIntrospectionOnly)
- {
- ReleaseHolder<ICLRPrivAssembly> pAsm;
- ReleaseHolder<IAssemblyName> pAssemblyName;
- IfFailThrow(pBinderToUse->BindAssemblyExplicit(image, &pAssemblyName, &pAsm));
- PEAssembly* pFile = nullptr;
- IfFailThrow(GetAppDomain()->BindHostedPrivAssembly(pParentAssembly, pAsm, pAssemblyName, &pFile));
- _ASSERTE(pFile);
- RETURN pFile;
- }
-#endif // !FEATURE_CORECLR
-#ifdef FEATURE_FUSION
- RETURN new PEAssembly(image, NULL, NULL, NULL, NULL, NULL, NULL, pParentAssembly, FALSE, isIntrospectionOnly);
-#else
CoreBindResult bindResult;
ReleaseHolder<ICLRPrivAssembly> assembly;
IfFailThrow(CCoreCLRBinderHelper::GetAssemblyFromImage(image, NULL, &assembly));
bindResult.Init(assembly,FALSE,FALSE);
RETURN new PEAssembly(&bindResult, NULL, pParentAssembly, FALSE, isIntrospectionOnly);
-#endif
}
#endif // !CROSSGEN_COMPILE
-#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE)
-// Use for main exe loading
-// This is also used for "spontaneous" (IJW) dll loading where
-// we need to deliver DllMain callbacks, but we should eliminate this case
-
-/* static */
-PEAssembly *PEAssembly::OpenHMODULE(HMODULE hMod,
- IAssembly *pFusionAssembly,
- IBindResult *pNativeFusionAssembly,
- IFusionBindLog *pFusionLog/*=NULL*/,
- BOOL isIntrospectionOnly/*=FALSE*/)
-{
- STANDARD_VM_CONTRACT;
-
- PEAssembly *result = NULL;
-
- ETWOnStartup (OpenHModule_V1, OpenHModuleEnd_V1);
-
- EX_TRY
- {
- result = DoOpenHMODULE(hMod, pFusionAssembly, pNativeFusionAssembly, pFusionLog, isIntrospectionOnly);
- }
- EX_HOOK
- {
- Exception *ex = GET_EXCEPTION();
-
- // Rethrow non-transient exceptions as file load exceptions with proper
- // context
- if (!ex->IsTransient())
- EEFileLoadException::Throw(pFusionAssembly, NULL, ex->GetHR(), ex);
- }
- EX_END_HOOK;
- return result;
-}
-
-// Thread stress
-class DoOpenHMODULEStress : APIThreadStress
-{
-public:
- HMODULE hMod;
- IAssembly *pFusionAssembly;
- IBindResult *pNativeFusionAssembly;
- IFusionBindLog *pFusionLog;
- DoOpenHMODULEStress(HMODULE hMod, IAssembly *pFusionAssembly, IBindResult *pNativeFusionAssembly, IFusionBindLog *pFusionLog)
- : hMod(hMod), pFusionAssembly(pFusionAssembly), pNativeFusionAssembly(pNativeFusionAssembly),pFusionLog(pFusionLog) {LIMITED_METHOD_CONTRACT;}
- void Invoke()
- {
- WRAPPER_NO_CONTRACT;
- PEAssemblyHolder result(PEAssembly::OpenHMODULE(hMod, pFusionAssembly,pNativeFusionAssembly, pFusionLog, FALSE));
- }
-};
-
-/* static */
-PEAssembly *PEAssembly::DoOpenHMODULE(HMODULE hMod,
- IAssembly *pFusionAssembly,
- IBindResult *pNativeFusionAssembly,
- IFusionBindLog *pFusionLog,
- BOOL isIntrospectionOnly/*=FALSE*/)
-{
- CONTRACT(PEAssembly *)
- {
- PRECONDITION(CheckPointer(hMod));
- PRECONDITION(CheckPointer(pFusionAssembly));
- PRECONDITION(CheckPointer(pNativeFusionAssembly,NULL_OK));
- POSTCONDITION(CheckPointer(RETVAL));
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- DoOpenHMODULEStress ts(hMod, pFusionAssembly, pNativeFusionAssembly, pFusionLog);
-
- PEImageHolder image(PEImage::LoadImage(hMod));
- RETURN new PEAssembly(image, NULL, pFusionAssembly, pNativeFusionAssembly, NULL, pFusionLog, NULL, NULL, FALSE, isIntrospectionOnly);
-}
-#endif // FEATURE_MIXEDMODE && !CROSSGEN_COMPILE
-
-#ifndef FEATURE_FUSION
PEAssembly* PEAssembly::Open(CoreBindResult* pBindResult,
BOOL isSystem, BOOL isIntrospectionOnly)
{
@@ -3736,7 +2316,6 @@ PEAssembly* PEAssembly::Open(CoreBindResult* pBindResult,
return new PEAssembly(pBindResult,NULL,NULL,isSystem,isIntrospectionOnly);
};
-#endif
/* static */
PEAssembly *PEAssembly::Create(PEAssembly *pParentAssembly,
@@ -3756,99 +2335,14 @@ PEAssembly *PEAssembly::Create(PEAssembly *pParentAssembly,
// we have.)
SafeComHolder<IMetaDataEmit> pEmit;
pAssemblyEmit->QueryInterface(IID_IMetaDataEmit, (void **)&pEmit);
-#ifdef FEATURE_FUSION
- ReleaseHolder<ICLRPrivAssembly> pPrivAssembly;
- if (pParentAssembly->HasHostAssembly())
- {
- // Dynamic assemblies in AppX use their parent's ICLRPrivAssembly as the binding context.
- pPrivAssembly = clr::SafeAddRef(new CLRPrivBinderUtil::CLRPrivBinderAsAssemblyWrapper(
- pParentAssembly->GetHostAssembly()));
- }
-
- PEAssemblyHolder pFile(new PEAssembly(
- NULL, pEmit, NULL, NULL, NULL, NULL, NULL, pParentAssembly,
- FALSE, bIsIntrospectionOnly,
- pPrivAssembly));
-#else
PEAssemblyHolder pFile(new PEAssembly(NULL, pEmit, pParentAssembly, FALSE, bIsIntrospectionOnly));
-#endif
RETURN pFile.Extract();
}
#ifdef FEATURE_PREJIT
-#ifdef FEATURE_FUSION
-BOOL PEAssembly::HasEqualNativeClosure(DomainAssembly * pDomainAssembly)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- THROWS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pDomainAssembly));
- }
- CONTRACTL_END;
- if (IsSystem())
- return TRUE;
- HRESULT hr = S_OK;
-
-
- if (m_pNativeImageClosure == NULL)
- return FALSE;
-
- // ensure theclosures are walked
- IAssemblyBindingClosure * pClosure = pDomainAssembly->GetAssemblyBindingClosure(LEVEL_COMPLETE);
- _ASSERTE(pClosure != NULL);
-
- if (m_pNativeImageClosure->HasBeenWalked(LEVEL_COMPLETE) != S_OK )
- {
- GCX_COOP();
-
- ENTER_DOMAIN_PTR(SystemDomain::System()->DefaultDomain(),ADV_DEFAULTAD);
- {
- GCX_PREEMP();
- IfFailThrow(m_pNativeImageClosure->EnsureWalked(GetFusionAssembly(),GetAppDomain()->GetFusionContext(),LEVEL_COMPLETE));
- }
- END_DOMAIN_TRANSITION;
- }
-
-
- hr = pClosure->IsEqual(m_pNativeImageClosure);
- IfFailThrow(hr);
- return (hr == S_OK);
-}
-#endif //FEATURE_FUSION
-
-#ifdef FEATURE_FUSION
-void PEAssembly::SetNativeImage(IBindResult *pNativeFusionAssembly)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- STANDARD_VM_CHECK;
- }
- CONTRACTL_END;
-
- StackSString path;
- WCHAR pwzPath[MAX_LONGPATH];
- DWORD dwCCPath = MAX_LONGPATH;
- ReleaseHolder<IAssemblyLocation> pIAssemblyLocation;
- IfFailThrow(pNativeFusionAssembly->GetAssemblyLocation(&pIAssemblyLocation));
- IfFailThrow(pIAssemblyLocation->GetPath(pwzPath, &dwCCPath));
- path.Set(pwzPath);
-
- PEImageHolder image(PEImage::OpenImage(path));
- image->Load();
-
- // For desktop dev11, this verification is now done at native binding time.
- _ASSERTE(CheckNativeImageVersion(image));
-
- PEFile::SetNativeImage(image);
- IfFailThrow(pNativeFusionAssembly->GetAssemblyLocation(&m_pNativeAssemblyLocation));
-}
-#else //FEATURE_FUSION
void PEAssembly::SetNativeImage(PEImage * image)
{
CONTRACTL
@@ -3891,243 +2385,23 @@ void PEAssembly::SetNativeImage(PEImage * image)
ExternalLog(LL_WARNING, "Native image is not correct version.");
}
}
-#endif //FEATURE_FUSION
-#ifdef FEATURE_FUSION
-void PEAssembly::ClearNativeImage()
-{
- CONTRACT_VOID
- {
- INSTANCE_CHECK;
- PRECONDITION(HasNativeImage());
- POSTCONDITION(!HasNativeImage());
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- PEFile::ClearNativeImage();
-
- if (m_pNativeAssemblyLocation != NULL)
- m_pNativeAssemblyLocation->Release();
- m_pNativeAssemblyLocation = NULL;
- if (m_pNativeImageClosure != NULL)
- m_pNativeImageClosure->Release();
- m_pNativeImageClosure = NULL;
- RETURN;
-}
-#endif //FEATURE_FUSION
#endif // FEATURE_PREJIT
-#ifdef FEATURE_FUSION
-BOOL PEAssembly::IsBindingCodeBase()
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- if (m_pIHostAssembly != NULL)
- return FALSE;
-
- if (m_pFusionAssembly == NULL)
- return (!GetPath().IsEmpty());
-
- if (m_dwLocationFlags == ASMLOC_UNKNOWN)
- return FALSE;
-
- return ((m_dwLocationFlags & ASMLOC_CODEBASE_HINT) != 0);
-}
-
-BOOL PEAssembly::IsSourceGAC()
-{
- LIMITED_METHOD_CONTRACT;
-
- if ((m_pIHostAssembly != NULL) || (m_pFusionAssembly == NULL))
- {
- return FALSE;
- }
-
- return ((m_dwLocationFlags & ASMLOC_LOCATION_MASK) == ASMLOC_GAC);
-}
-
-BOOL PEAssembly::IsSourceDownloadCache()
-{
- LIMITED_METHOD_CONTRACT;
-
- if ((m_pIHostAssembly != NULL) || (m_pFusionAssembly == NULL))
- {
- return FALSE;
- }
-
- return ((m_dwLocationFlags & ASMLOC_LOCATION_MASK) == ASMLOC_DOWNLOAD_CACHE);
-}
-
-#else // FEATURE_FUSION
BOOL PEAssembly::IsSourceGAC()
{
WRAPPER_NO_CONTRACT;
return m_bIsFromGAC;
};
-#endif // FEATURE_FUSION
#endif // #ifndef DACCESS_COMPILE
-#ifdef FEATURE_FUSION
-BOOL PEAssembly::IsContextLoad()
-{
- LIMITED_METHOD_CONTRACT;
- if ((m_pIHostAssembly != NULL) || (m_pFusionAssembly == NULL))
- {
- return FALSE;
- }
- return (IsSystem() || (m_loadContext == LOADCTX_TYPE_DEFAULT));
-}
-
-LOADCTX_TYPE PEAssembly::GetLoadContext()
-{
- LIMITED_METHOD_CONTRACT;
-
- return m_loadContext;
-}
-
-DWORD PEAssembly::GetLocationFlags()
-{
- LIMITED_METHOD_CONTRACT;
-
- return m_dwLocationFlags;
-}
-
-#endif
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_FUSION
-PEKIND PEAssembly::GetFusionProcessorArchitecture()
-{
- CONTRACTL
- {
- THROWS;
- MODE_ANY;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- PEImage * pImage = NULL;
-
-#ifdef FEATURE_PREJIT
- pImage = m_nativeImage;
-#endif
-
- if (pImage == NULL)
- pImage = GetILimage();
-
- return pImage->GetFusionProcessorArchitecture();
-}
-
-IAssemblyName * PEAssembly::GetFusionAssemblyName()
-{
- CONTRACT(IAssemblyName *)
- {
- INSTANCE_CHECK;
- POSTCONDITION(CheckPointer(RETVAL));
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- if (m_pFusionAssemblyName == NULL)
- {
- AssemblySpec spec;
- spec.InitializeSpec(this);
- PEImage * pImage = GetILimage();
-
-#ifdef FEATURE_PREJIT
- if ((pImage != NULL) && !pImage->MDImportLoaded())
- pImage = m_nativeImage;
-#endif
-
- if (pImage != NULL)
- {
- spec.SetPEKIND(pImage->GetFusionProcessorArchitecture());
- }
-
- GCX_PREEMP();
-
- IfFailThrow(spec.CreateFusionName(&m_pFusionAssemblyName, FALSE));
- }
-
- RETURN m_pFusionAssemblyName;
-}
-
-// This version of GetFusionAssemlyName that can be used to return the reference in a
-// NOTHROW/NOTRIGGER fashion. This is useful for scenarios where you dont want to invoke the THROWS/GCTRIGGERS
-// version when you know the name would have been created and is available.
-IAssemblyName * PEAssembly::GetFusionAssemblyNameNoCreate()
-{
- LIMITED_METHOD_CONTRACT;
-
- return m_pFusionAssemblyName;
-}
-
-IAssembly *PEAssembly::GetFusionAssembly()
-{
- CONTRACT(IAssembly *)
- {
- INSTANCE_CHECK;
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACT_END;
-
- RETURN m_pFusionAssembly;
-}
-
-IHostAssembly *PEAssembly::GetIHostAssembly()
-{
- CONTRACT(IHostAssembly *)
- {
- INSTANCE_CHECK;
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACT_END;
-
- RETURN m_pIHostAssembly;
-}
-
-IAssemblyLocation *PEAssembly::GetNativeAssemblyLocation()
-{
- CONTRACT(IAssemblyLocation *)
- {
- INSTANCE_CHECK;
- PRECONDITION(HasNativeImage());
- POSTCONDITION(CheckPointer(RETVAL));
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACT_END;
-
- RETURN m_pNativeAssemblyLocation;
-}
-#endif // FEATURE_FUSION
// ------------------------------------------------------------
// Hash support
@@ -4151,13 +2425,8 @@ void PEAssembly::VerifyStrongName()
return;
}
-#ifdef FEATURE_FUSION
- // System and dynamic assemblies don't need hash checks
- if (IsSystem() || IsDynamic())
-#else
// Without FUSION/GAC, we need to verify SN on all assemblies, except dynamic assemblies.
if (IsDynamic())
-#endif
{
m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
@@ -4166,72 +2435,18 @@ void PEAssembly::VerifyStrongName()
}
// Next, verify the strong name, if necessary
-#ifdef FEATURE_FUSION
- // See if the assembly comes from a secure location
- IAssembly *pFusionAssembly = GetAssembly()->GetFusionAssembly();
- if (pFusionAssembly)
- {
- DWORD dwLocation;
- IfFailThrow(pFusionAssembly->GetAssemblyLocation(&dwLocation));
-
- switch (dwLocation & ASMLOC_LOCATION_MASK)
- {
- case ASMLOC_GAC:
- case ASMLOC_DOWNLOAD_CACHE:
- case ASMLOC_DEV_OVERRIDE:
- // Assemblies from the GAC or download cache have
- // already been verified by Fusion.
- m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
- m_fStrongNameVerified = TRUE;
- return;
-
- case ASMLOC_RUN_FROM_SOURCE:
- case ASMLOC_UNKNOWN:
- // For now, just verify these every time, we need to
- // cache the fact that at least one verification has
- // been performed (if strong name policy permits
- // caching of verification results)
- break;
-
- default:
- UNREACHABLE();
- }
- }
-#endif
// Check format of image. Note we must delay this until after the GAC status has been
// checked, to handle the case where we are not loading m_image.
EnsureImageOpened();
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- if (IsWindowsRuntime())
- {
- // Winmd files are always loaded in full trust.
- m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
- m_fStrongNameVerified = TRUE;
- return;
- }
-#endif
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
if (m_nativeImage == NULL && !GetILimage()->IsTrustedNativeImage())
-#else
- if (!GetILimage()->IsTrustedNativeImage())
-#endif
{
if (!GetILimage()->CheckILFormat())
ThrowHR(COR_E_BADIMAGEFORMAT);
}
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- // Do not validate strong name signature during CrossGen. This is necessary
- // to make build-lab scenarios to work.
- if (IsCompilationProcess())
- {
- m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
- }
- else
-#endif
// Check the strong name if present.
if (IsIntrospectionOnly())
{
@@ -4239,59 +2454,16 @@ void PEAssembly::VerifyStrongName()
// need to do module hash checks.
m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
}
-#if !defined(FEATURE_CORECLR)
- //We do this to early out for WinMD files that are unsigned but have NI images as well.
- else if (!HasStrongNameSignature())
- {
-#ifdef FEATURE_CAS_POLICY
- // We only check module hashes if there is a strong name or Authenticode signature
- if (m_certificate == NULL)
- {
- m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
- }
-#endif
- }
-#endif // !defined(FEATURE_CORECLR)
else
{
-#ifdef FEATURE_CORECLR
// Runtime policy on CoreCLR is to skip verification of ALL assemblies
m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
m_fStrongNameVerified = TRUE;
-#else
- DWORD verifyOutputFlags = 0;
- HRESULT hr = GetILimage()->VerifyStrongName(&verifyOutputFlags);
-
- if (SUCCEEDED(hr))
- {
- // Strong name verified or delay sign OK'ed.
- // We will skip verification of modules in the delay signed case.
-
- if ((verifyOutputFlags & SN_OUTFLAG_WAS_VERIFIED) == 0)
- m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
- }
- else
- {
- // Strong name missing or error. Throw in the latter case.
- if (hr != CORSEC_E_MISSING_STRONGNAME)
- ThrowHR(hr);
-
-#ifdef FEATURE_CAS_POLICY
- // Since we are not strong named, don't check module hashes.
- // (Unless we have a security certificate, in which case check anyway.)
-
- if (m_certificate == NULL)
- m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
-#endif
- }
-
-#endif // FEATURE_CORECLR
}
m_fStrongNameVerified = TRUE;
}
-#ifdef FEATURE_CORECLR
BOOL PEAssembly::IsProfileAssembly()
{
CONTRACTL
@@ -4324,7 +2496,6 @@ BOOL PEAssembly::IsProfileAssembly()
m_fProfileAssembly = bProfileAssembly ? 1 : -1;
return bProfileAssembly;
}
-#endif // FEATURE_CORECLR
// ------------------------------------------------------------
// Descriptive strings
@@ -4374,29 +2545,6 @@ void PEAssembly::GetCodeBase(SString &result, BOOL fCopiedName/*=FALSE*/)
INJECT_FAULT(COMPlusThrowOM(););
}
CONTRACTL_END;
-#ifdef FEATURE_FUSION
- // For a copied name, we always use the actual file path rather than the fusion info
- if (!fCopiedName && m_pFusionAssembly)
- {
- if ( ((m_dwLocationFlags & ASMLOC_LOCATION_MASK) == ASMLOC_RUN_FROM_SOURCE) ||
- ((m_dwLocationFlags & ASMLOC_LOCATION_MASK) == ASMLOC_DOWNLOAD_CACHE) )
- {
- // Assemblies in the download cache or run from source should have
- // a proper codebase set in them.
- FusionBind::GetAssemblyNameStringProperty(GetFusionAssemblyName(),
- ASM_NAME_CODEBASE_URL,
- result);
- return;
- }
- }
- else if (m_pIHostAssembly)
- {
- FusionBind::GetAssemblyNameStringProperty(GetFusionAssemblyName(),
- ASM_NAME_CODEBASE_URL,
- result);
- return;
- }
-#endif
// All other cases use the file path.
result.Set(GetEffectivePath());
@@ -4512,21 +2660,6 @@ void PEAssembly::ExternalVLog(DWORD facility, DWORD level, const WCHAR *fmt, va_
PEFile::ExternalVLog(facility, level, fmt, args);
-#ifdef FEATURE_FUSION
- if (FusionLoggingEnabled())
- {
- DWORD dwLogCategory = (facility == LF_ZAP ? FUSION_BIND_LOG_CATEGORY_NGEN : FUSION_BIND_LOG_CATEGORY_DEFAULT);
-
- StackSString message;
- message.VPrintf(fmt, args);
- m_pFusionLog->LogMessage(0, dwLogCategory, message);
-
- if (level == LL_ERROR) {
- m_pFusionLog->SetResultCode(dwLogCategory, E_FAIL);
- FlushExternalLog();
- }
- }
-#endif //FEATURE_FUSION
RETURN;
}
@@ -4540,12 +2673,6 @@ void PEAssembly::FlushExternalLog()
}
CONTRACT_END;
-#ifdef FEATURE_FUSION
- if (FusionLoggingEnabled()) {
- m_pFusionLog->Flush(g_dwLogLevel, FUSION_BIND_LOG_CATEGORY_NGEN);
- m_pFusionLog->Flush(g_dwLogLevel, FUSION_BIND_LOG_CATEGORY_DEFAULT);
- }
-#endif //FEATURE_FUSION
RETURN;
}
@@ -4595,399 +2722,6 @@ HRESULT PEFile::GetVersion(USHORT *pMajor, USHORT *pMinor, USHORT *pBuild, USHOR
return hr;
}
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-// ================================================================================
-// PEModule class - a PEFile which represents a satellite module
-// ================================================================================
-
-PEModule::PEModule(PEImage *image, PEAssembly *assembly, mdFile token, IMetaDataEmit *pEmit)
- : PEFile(image),
- m_assembly(NULL),
- m_token(token),
- m_bIsResource(-1)
-{
- CONTRACTL
- {
- PRECONDITION(CheckPointer(image, NULL_OK));
- PRECONDITION(CheckPointer(assembly));
- PRECONDITION(!IsNilToken(token));
- PRECONDITION(CheckPointer(pEmit, NULL_OK));
- PRECONDITION(image != NULL || pEmit != NULL);
- CONSTRUCTOR_CHECK;
- STANDARD_VM_CHECK;
- }
- CONTRACTL_END;
-
- DWORD flags;
-
- // get only the data which is required, here - flags
- // this helps avoid unnecessary memory touches
- IfFailThrow(assembly->GetPersistentMDImport()->GetFileProps(token, NULL, NULL, NULL, &flags));
-
- if (image != NULL)
- {
- if (IsFfContainsMetaData(flags) && !image->CheckILFormat())
- ThrowHR(COR_E_BADIMAGEFORMAT);
-
- if (assembly->IsIStream())
- {
- m_flags |= PEFILE_ISTREAM;
-#ifdef FEATURE_PREJIT
- m_fCanUseNativeImage = FALSE;
-#endif
- }
- }
-
- assembly->AddRef();
-
- m_assembly = assembly;
-
- m_flags |= PEFILE_MODULE;
- if (assembly->IsSystem())
- {
- m_flags |= PEFILE_SYSTEM;
- }
- else
- {
- if (assembly->IsIntrospectionOnly())
- {
- m_flags |= PEFILE_INTROSPECTIONONLY;
-#ifdef FEATURE_PREJIT
- SetCannotUseNativeImage();
-#endif
- }
- }
-
-
- // Verify module format. Note that some things have already happened:
- // - Fusion has verified the name matches the metadata
- // - PEimage has performed PE file format validation
-
- if (assembly->NeedsModuleHashChecks())
- {
- ULONG size;
- const void *hash;
- IfFailThrow(assembly->GetPersistentMDImport()->GetFileProps(token, NULL, &hash, &size, NULL));
-
- if (!CheckHash(assembly->GetHashAlgId(), hash, size))
- ThrowHR(COR_E_MODULE_HASH_CHECK_FAILED);
- }
-
-#if defined(FEATURE_PREJIT) && !defined(CROSSGEN_COMPILE)
- // Find the native image
- if (IsFfContainsMetaData(flags)
- && m_fCanUseNativeImage
- && assembly->HasNativeImage()
- && assembly->GetFusionAssembly() != NULL)
- {
- IAssemblyLocation *pIAssemblyLocation = assembly->GetNativeAssemblyLocation();
-
- WCHAR wzPath[MAX_LONGPATH];
- WCHAR *pwzTemp = NULL;
- DWORD dwCCPath = MAX_LONGPATH;
- SString path;
- SString moduleName(SString::Utf8, GetSimpleName());
-
- // Compute the module path from the manifest module path
- IfFailThrow(pIAssemblyLocation->GetPath(wzPath, &dwCCPath));
- pwzTemp = PathFindFileName(wzPath);
- *pwzTemp = (WCHAR) 0x00;
-
- // <TODO>@todo: GetAppDomain????</TODO>
- path.Set(wzPath);
- path.Append((LPCWSTR) moduleName);
-
- SetNativeImage(path);
- }
-#endif // FEATURE_PREJIT && !CROSSGEN_COMPILE
-
-#if _DEBUG
- GetCodeBaseOrName(m_debugName);
- m_pDebugName = m_debugName;
-#endif
-
- if (IsFfContainsMetaData(flags))
- {
- if (image != NULL)
- {
- OpenMDImport_Unsafe(); //constructor. cannot race with anything
- }
- else
- {
- _ASSERTE(!m_bHasPersistentMDImport);
- IfFailThrow(GetMetaDataInternalInterfaceFromPublic(pEmit, IID_IMDInternalImport,
- (void **)&m_pMDImport));
- m_pEmitter = pEmit;
- pEmit->AddRef();
- m_bHasPersistentMDImport=TRUE;
- m_MDImportIsRW_Debugger_Use_Only = TRUE;
- }
-
- // Fusion probably checks this, but we need to check this ourselves if
- // this file didn't come from Fusion
- if (!m_pMDImport->IsValidToken(m_pMDImport->GetModuleFromScope()))
- COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
- }
- else
- {
- // Go ahead and "load" image since it is essentially a noop, but will enable
- // more operations on the module earlier in the loading process.
- LoadLibrary();
- }
-#ifdef FEATURE_PREJIT
- if (IsResource() || IsDynamic())
- m_fCanUseNativeImage = FALSE;
-#endif
-}
-
-PEModule::~PEModule()
-{
- CONTRACTL
- {
- DESTRUCTOR_CHECK;
- NOTHROW;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- m_assembly->Release();
-}
-
-/* static */
-PEModule *PEModule::Open(PEAssembly *assembly, mdFile token,
- const SString &fileName)
-{
- STANDARD_VM_CONTRACT;
-
- PEModule *result = NULL;
-
- EX_TRY
- {
- result = DoOpen(assembly, token, fileName);
- }
- EX_HOOK
- {
- Exception *ex = GET_EXCEPTION();
-
- // Rethrow non-transient exceptions as file load exceptions with proper
- // context
-
- if (!ex->IsTransient())
- EEFileLoadException::Throw(fileName, ex->GetHR(), ex);
- }
- EX_END_HOOK;
-
- return result;
-}
-// Thread stress
-class DoOpenPathStress : APIThreadStress
-{
-public:
- PEAssembly *assembly;
- mdFile token;
- const SString &fileName;
- DoOpenPathStress(PEAssembly *assembly, mdFile token,
- const SString &fileName)
- : assembly(assembly), token(token), fileName(fileName)
- {
- WRAPPER_NO_CONTRACT;
- fileName.Normalize();
- }
- void Invoke()
- {
- WRAPPER_NO_CONTRACT;
- PEModuleHolder result(PEModule::Open(assembly, token, fileName));
- }
-};
-
-/* static */
-PEModule *PEModule::DoOpen(PEAssembly *assembly, mdFile token,
- const SString &fileName)
-{
- CONTRACT(PEModule *)
- {
- PRECONDITION(CheckPointer(assembly));
- PRECONDITION(CheckValue(fileName));
- PRECONDITION(!IsNilToken(token));
- PRECONDITION(!fileName.IsEmpty());
- POSTCONDITION(CheckPointer(RETVAL));
- STANDARD_VM_CHECK;
- }
- CONTRACT_END;
-
- DoOpenPathStress ts(assembly, token, fileName);
-
- // If this is a resource module, we must explicitly request a flat mapping
- DWORD flags;
- IfFailThrow(assembly->GetPersistentMDImport()->GetFileProps(token, NULL, NULL, NULL, &flags));
-
- PEImageHolder image;
-#ifdef FEATURE_FUSION
- if (assembly->IsIStream())
- {
- SafeComHolder<IHostAssemblyModuleImport> pModuleImport;
- IfFailThrow(assembly->GetIHostAssembly()->GetModuleByName(fileName, &pModuleImport));
-
- SafeComHolder<IStream> pIStream;
- IfFailThrow(pModuleImport->GetModuleStream(&pIStream));
-
- DWORD dwModuleId;
- IfFailThrow(pModuleImport->GetModuleId(&dwModuleId));
- image = PEImage::OpenImage(pIStream, assembly->m_identity->m_StreamAsmId,
- dwModuleId, (flags & ffContainsNoMetaData));
- }
- else
-#endif
- {
- image = PEImage::OpenImage(fileName);
- }
-
- if (flags & ffContainsNoMetaData)
- image->LoadNoMetaData(assembly->IsIntrospectionOnly());
-
- PEModuleHolder module(new PEModule(image, assembly, token, NULL));
-
- RETURN module.Extract();
-}
-
-/* static */
-PEModule *PEModule::OpenMemory(PEAssembly *assembly, mdFile token,
- const void *flat, COUNT_T size)
-{
- STANDARD_VM_CONTRACT;
-
- PEModule *result = NULL;
-
- EX_TRY
- {
- result = DoOpenMemory(assembly, token, flat, size);
- }
- EX_HOOK
- {
- Exception *ex = GET_EXCEPTION();
-
- // Rethrow non-transient exceptions as file load exceptions with proper
- // context
- if (!ex->IsTransient())
- EEFileLoadException::Throw(assembly, flat, size, ex->GetHR(), ex);
- }
- EX_END_HOOK;
- return result;
-}
-
-// Thread stress
-class DoOpenTokenStress : APIThreadStress
-{
-public:
- PEAssembly *assembly;
- mdFile token;
- const void *flat;
- COUNT_T size;
- DoOpenTokenStress(PEAssembly *assembly, mdFile token,
- const void *flat, COUNT_T size)
- : assembly(assembly), token(token), flat(flat), size(size) {LIMITED_METHOD_CONTRACT;}
- void Invoke()
- {
- WRAPPER_NO_CONTRACT;
- PEModuleHolder result(PEModule::OpenMemory(assembly, token, flat, size));
- }
-};
-
-// REVIEW: do we need to know the creator module which emitted the module (separately
-// from the assembly parent) for security reasons?
-/* static */
-PEModule *PEModule::DoOpenMemory(PEAssembly *assembly, mdFile token,
- const void *flat, COUNT_T size)
-{
- CONTRACT(PEModule *)
- {
- PRECONDITION(CheckPointer(assembly));
- PRECONDITION(!IsNilToken(token));
- PRECONDITION(CheckPointer(flat));
- POSTCONDITION(CheckPointer(RETVAL));
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACT_END;
-
- DoOpenTokenStress ts(assembly, token, flat, size);
-
- PEImageHolder image(PEImage::LoadFlat(flat, size));
-
- RETURN new PEModule(image, assembly, token, NULL);
-}
-
-/* static */
-PEModule *PEModule::Create(PEAssembly *assembly, mdFile token, IMetaDataEmit *pEmit)
-{
- CONTRACT(PEModule *)
- {
- PRECONDITION(CheckPointer(assembly));
- PRECONDITION(!IsNilToken(token));
- STANDARD_VM_CHECK;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN new PEModule(NULL, assembly, token, pEmit);
-}
-
-// ------------------------------------------------------------
-// Logging
-// ------------------------------------------------------------
-#ifdef FEATURE_PREJIT
-void PEModule::ExternalVLog(DWORD facility, DWORD level, const WCHAR *fmt, va_list args)
-{
- CONTRACT_VOID
- {
- THROWS;
- GC_TRIGGERS;
- }
- CONTRACT_END;
-
- m_assembly->ExternalVLog(facility, level, fmt, args);
-
- RETURN;
-}
-
-void PEModule::FlushExternalLog()
-{
- CONTRACT_VOID
- {
- THROWS;
- GC_TRIGGERS;
- }
- CONTRACT_END;
-
- m_assembly->FlushExternalLog();
-
- RETURN;
-}
-
-// ------------------------------------------------------------
-// Loader support routines
-// ------------------------------------------------------------
-void PEModule::SetNativeImage(const SString &fullPath)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- PRECONDITION(CheckValue(fullPath));
- PRECONDITION(!fullPath.IsEmpty());
- STANDARD_VM_CHECK;
- }
- CONTRACTL_END;
-
- PEImageHolder image(PEImage::OpenImage(fullPath));
- image->Load();
-
- PEFile::SetNativeImage(image);
-}
-#endif // FEATURE_PREJIT
-
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
void PEFile::EnsureImageOpened()
@@ -5052,20 +2786,6 @@ PEAssembly::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
}
}
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-void
-PEModule::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
-{
- WRAPPER_NO_CONTRACT;
-
- PEFile::EnumMemoryRegions(flags);
-
- if (m_assembly.IsValid())
- {
- m_assembly->EnumMemoryRegions(flags);
- }
-}
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
#endif // #ifdef DACCESS_COMPILE
@@ -5097,26 +2817,6 @@ LPCWSTR PEFile::GetPathForErrorMessages()
}
}
-#ifndef FEATURE_CORECLR
-BOOL PEAssembly::IsReportedToUsageLog()
-{
- LIMITED_METHOD_CONTRACT;
- BOOL fReported = TRUE;
-
- if (!IsDynamic())
- fReported = m_identity->IsReportedToUsageLog();
-
- return fReported;
-}
-
-void PEAssembly::SetReportedToUsageLog()
-{
- LIMITED_METHOD_CONTRACT;
-
- if (!IsDynamic())
- m_identity->SetReportedToUsageLog();
-}
-#endif // !FEATURE_CORECLR
#ifdef DACCESS_COMPILE
TADDR PEFile::GetMDInternalRWAddress()
@@ -5149,12 +2849,10 @@ PTR_ICLRPrivBinder PEFile::GetBindingContext()
PTR_ICLRPrivBinder pBindingContext = NULL;
-#if defined(FEATURE_CORECLR)
// Mscorlib is always bound in context of the TPA Binder. However, since it gets loaded and published
// during EEStartup *before* TPAbinder is initialized, we dont have a binding context to publish against.
// Thus, we will always return NULL for its binding context.
if (!IsSystem())
-#endif // defined(FEATURE_CORECLR)
{
pBindingContext = dac_cast<PTR_ICLRPrivBinder>(GetHostAssembly());
}
diff --git a/src/vm/pefile.h b/src/vm/pefile.h
index 413d08c185..b7c7bd3e7c 100644
--- a/src/vm/pefile.h
+++ b/src/vm/pefile.h
@@ -26,11 +26,6 @@
#include "loaderheap.h"
#include "sstring.h"
#include "ex.h"
-#ifdef FEATURE_FUSION
-#include <fusion.h>
-#include <fusionbind.h>
-#include "binderngen.h"
-#endif
#include "assemblyspecbase.h"
#include "eecontract.h"
#include "metadatatracker.h"
@@ -141,14 +136,6 @@ private:
public:
void LoadLibrary(BOOL allowNativeSkip = TRUE);
-#ifdef FEATURE_MIXEDMODE
-protected:
- // Returns TRUE if this file references managed CRT (msvcmNN*).
- BOOL ReferencesManagedCRT();
-
- // Checks for unsupported loads of C++/CLI assemblies into multiple runtimes in this process.
- void CheckForDisallowedInProcSxSLoad();
-#endif // FEATURE_MIXEDMODE
private:
void CheckForDisallowedInProcSxSLoadWorker();
@@ -194,9 +181,6 @@ public:
BOOL Equals(PEImage *pImage);
#endif // DACCESS_COMPILE
-#ifndef FEATURE_CORECLR
- BOOL IsShareable();
-#endif
void GetMVID(GUID *pMvid);
@@ -291,9 +275,6 @@ public:
LPCSTR GetLocale();
DWORD GetFlags();
HRESULT GetFlagsNoTrigger(DWORD * pdwFlags);
-#ifdef FEATURE_CAS_POLICY
- COR_TRUST *GetAuthenticodeSignature();
-#endif
// ------------------------------------------------------------
// PE file access
// ------------------------------------------------------------
@@ -347,9 +328,6 @@ public:
ULONG GetILImageTimeDateStamp();
-#ifdef FEATURE_CAS_POLICY
- SAFEHANDLE GetSafeHandle();
-#endif // FEATURE_CAS_POLICY
// ------------------------------------------------------------
// Image memory access
@@ -400,6 +378,7 @@ public:
PEImage *GetNativeImageWithRef();
PEImage *GetPersistentNativeImage();
#endif
+ BOOL HasNativeOrReadyToRunImage();
BOOL HasNativeImage();
PTR_PEImageLayout GetLoaded();
PTR_PEImageLayout GetLoadedNative();
@@ -520,10 +499,6 @@ protected:
void ConvertMDInternalToReadWrite();
void ReleaseMetadataInterfaces(BOOL bDestructor, BOOL bKeepNativeData=FALSE);
-#ifdef FEATURE_CAS_POLICY
- // Check the Authenticode signature of a PE file
- void CheckAuthenticodeSignature();
-#endif // FEATURE_CAS_POLICY
friend class Module;
#ifdef FEATURE_PREJIT
@@ -572,21 +547,11 @@ protected:
#endif
IMetaDataImport2 *m_pImporter;
IMetaDataEmit *m_pEmitter;
-#ifndef FEATURE_CORECLR
- IMetaDataAssemblyImport *m_pAssemblyImporter;
- IMetaDataAssemblyEmit *m_pAssemblyEmitter;
-#endif
SimpleRWLock *m_pMetadataLock;
Volatile<LONG> m_refCount;
SBuffer *m_hash; // cached SHA1 hash value
int m_flags;
BOOL m_fStrongNameVerified;
-#ifdef FEATURE_CAS_POLICY
- COR_TRUST *m_certificate;
- BOOL m_fCheckedCertificate;
- IInternetSecurityManager *m_pSecurityManager;
- Crst m_securityManagerLock;
-#endif // FEATURE_CAS_POLICY
#ifdef DEBUGGING_SUPPORTED
#ifdef FEATURE_PREJIT
@@ -659,7 +624,6 @@ public:
protected:
PTR_ICLRPrivAssembly m_pHostAssembly;
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
// For certain assemblies, we do not have m_pHostAssembly since they are not bound using an actual binder.
// An example is Ref-Emitted assemblies. Thus, when such assemblies trigger load of their dependencies,
// we need to ensure they are loaded in appropriate load context.
@@ -668,13 +632,10 @@ protected:
// assembly that created the dynamic assembly. If the creator assembly is dynamic itself, then its fallback
// load context would be propagated to the assembly being dynamically generated.
ICLRPrivBinder *m_pFallbackLoadContextBinder;
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
protected:
- friend class CLRPrivBinderFusion;
#ifndef DACCESS_COMPILE
- // CLRPrivBinderFusion calls this for Fusion-bound assemblies in AppX processes.
void SetHostAssembly(ICLRPrivAssembly * pHostAssembly)
{ LIMITED_METHOD_CONTRACT; m_pHostAssembly = clr::SafeAddRef(pHostAssembly); }
#endif //DACCESS_COMPILE
@@ -696,7 +657,6 @@ public:
bool CanUseWithBindingCache()
{ LIMITED_METHOD_CONTRACT; return !HasHostAssembly(); }
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
void SetFallbackLoadContextBinder(ICLRPrivBinder *pFallbackLoadContextBinder)
{
LIMITED_METHOD_CONTRACT;
@@ -709,7 +669,6 @@ public:
return m_pFallbackLoadContextBinder;
}
-#endif //defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
}; // class PEFile
@@ -728,19 +687,6 @@ class PEAssembly : public PEFile
// Public API
// ------------------------------------------------------------
-#if !defined(FEATURE_CORECLR)
- static PEAssembly * Open(
- PEAssembly * pParentAssembly,
- PEImage * pPEImageIL,
- PEImage * pPEImageNI,
- ICLRPrivAssembly * pHostAssembly,
- BOOL fIsIntrospectionOnly);
-
- static PEAssembly * Open(
- PEAssembly * pParentAssembly,
- PEImage * pPEImageIL,
- BOOL isIntrospectionOnly = FALSE);
-#else //!FEATURE_CORECLR
// CoreCLR's PrivBinder PEAssembly creation entrypoint
static PEAssembly * Open(
PEAssembly * pParent,
@@ -748,69 +694,17 @@ class PEAssembly : public PEFile
PEImage * pPEImageNI,
ICLRPrivAssembly * pHostAssembly,
BOOL fIsIntrospectionOnly = FALSE);
-#endif //!FEATURE_CORECLR
// This opens the canonical mscorlib.dll
-#ifdef FEATURE_FUSION
- static PEAssembly *OpenSystem(IApplicationContext *pAppCtx);
-#else
static PEAssembly *OpenSystem(IUnknown *pAppCtx);
-#endif
#ifdef DACCESS_COMPILE
virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
#endif
-#ifdef FEATURE_FUSION
- static PEAssembly *Open(
- IAssembly *pIAssembly,
- IBindResult *pNativeFusionAssembly,
- IFusionBindLog *pFusionLog = NULL,
- BOOL isSystemAssembly = FALSE,
- BOOL isIntrospectionOnly = FALSE);
-
- static PEAssembly *Open(
- IHostAssembly *pIHostAssembly,
- BOOL isSystemAssembly = FALSE,
- BOOL isIntrospectionOnly = FALSE);
-
-#ifdef FEATURE_MIXEDMODE
- // Use for main exe loading
- // NOTE: This may also be used for "spontaneous" (IJW) dll loading where
- // we need to deliver DllMain callbacks, but we should eliminate this case
-
- static PEAssembly *OpenHMODULE(
- HMODULE hMod,
- IAssembly *pFusionAssembly,
- IBindResult *pNativeFusionAssembly,
- IFusionBindLog *pFusionLog = NULL,
- BOOL isIntrospectionOnly = FALSE);
-#endif // FEATURE_MIXEDMODE
-
- static PEAssembly *DoOpen(
- IAssembly *pIAssembly,
- IBindResult *pNativeFusionAssembly,
- IFusionBindLog *pFusionLog,
- BOOL isSystemAssembly,
- BOOL isIntrospectionOnly = FALSE);
-
- static PEAssembly *DoOpen(
- IHostAssembly *pIHostAssembly,
- BOOL isSystemAssembly,
- BOOL isIntrospectionOnly = FALSE);
-#ifdef FEATURE_MIXEDMODE
- static PEAssembly *DoOpenHMODULE(
- HMODULE hMod,
- IAssembly *pFusionAssembly,
- IBindResult *pNativeFusionAssembly,
- IFusionBindLog *pFusionLog,
- BOOL isIntrospectionOnly = FALSE);
-#endif // FEATURE_MIXEDMODE
-#else
static PEAssembly *Open(
CoreBindResult* pBindResult,
BOOL isSystem,
BOOL isIntrospectionOnly);
-#endif // FEATURE_FUSION
static PEAssembly *Create(
PEAssembly *pParentAssembly,
@@ -833,11 +727,7 @@ class PEAssembly : public PEFile
private:
// Private helpers for crufty exception handling reasons
-#ifdef FEATURE_FUSION
- static PEAssembly *DoOpenSystem(IApplicationContext *pAppCtx);
-#else
static PEAssembly *DoOpenSystem(IUnknown *pAppCtx);
-#endif
public:
@@ -846,50 +736,9 @@ class PEAssembly : public PEFile
// ------------------------------------------------------------
BOOL IsSourceGAC();
-#ifdef FEATURE_CORECLR
BOOL IsProfileAssembly();
-#endif // FEATURE_CORECLR
ULONG HashIdentity();
-#ifdef FEATURE_FUSION
-
- BOOL FusionLoggingEnabled()
- {
- LIMITED_METHOD_CONTRACT;
- return m_bFusionLogEnabled && (m_pFusionLog != NULL);
- };
- void DisableFusionLogging()
- {
- m_bFusionLogEnabled = FALSE;
- };
-
- IFusionBindLog *GetFusionBindLog()
- {
- LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_FUSION
- return (m_bFusionLogEnabled && (m_pFusionLog != NULL)) ? m_pFusionLog : NULL;
-#else
- return NULL;
-#endif
- }
-
-
- BOOL IsBindingCodeBase();
-
- BOOL IsSourceDownloadCache();
-
- LOADCTX_TYPE GetLoadContext();
- BOOL IsContextLoad();
-
- // Can we avoid exposing these?
- IAssembly *GetFusionAssembly();
- IHostAssembly *GetIHostAssembly();
- IAssemblyName *GetFusionAssemblyName();
- IAssemblyName *GetFusionAssemblyNameNoCreate();
- IAssemblyLocation* GetNativeAssemblyLocation();
- DWORD GetLocationFlags();
- PEKIND GetFusionProcessorArchitecture();
-#endif
#ifndef DACCESS_COMPILE
virtual void ReleaseIL();
@@ -947,49 +796,12 @@ class PEAssembly : public PEFile
#ifdef FEATURE_PREJIT
void ExternalVLog(DWORD facility, DWORD level, const WCHAR *fmt, va_list args) DAC_EMPTY();
void FlushExternalLog() DAC_EMPTY();
-#ifdef FEATURE_FUSION
- void ETWTraceLogMessage(DWORD dwETWLogCategory, PEAssembly *pAsm)
- {
- LIMITED_METHOD_CONTRACT
- if (FusionLoggingEnabled() &&
- (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEFUSION_KEYWORD)))
- {
- m_pFusionLog->ETWTraceLogMessage(dwETWLogCategory, (pAsm?pAsm->m_pFusionAssemblyName:NULL));
- }
- }
- ULONGLONG GetBindingID()
- {
- LIMITED_METHOD_CONTRACT;
- ULONGLONG ullBindingID = 0;
- if (FusionLoggingEnabled())
- m_pFusionLog->GetBindingID(&ullBindingID);
- return ullBindingID;
- }
-#endif
#endif
-#ifndef FEATURE_CORECLR
- BOOL IsReportedToUsageLog();
- void SetReportedToUsageLog();
-#endif // !FEATURE_CORECLR
protected:
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_FUSION
- PEAssembly(
- PEImage *image,
- IMetaDataEmit *pEmit,
- IAssembly *pIAssembly,
- IBindResult *pNativeFusionAssembly,
- PEImage *pNIImage,
- IFusionBindLog *pFusionLog,
- IHostAssembly *pIHostAssembly,
- PEFile *creator,
- BOOL system,
- BOOL introspectionOnly = FALSE,
- ICLRPrivAssembly * pHostAssembly = NULL);
-#else
PEAssembly(
CoreBindResult* pBindResultInfo,
IMetaDataEmit *pEmit,
@@ -1000,7 +812,6 @@ class PEAssembly : public PEFile
PEImage * pPEImageNI = NULL,
ICLRPrivAssembly * pHostAssembly = NULL
);
-#endif
virtual ~PEAssembly();
#endif
@@ -1011,28 +822,11 @@ class PEAssembly : public PEFile
friend class DomainAssembly;
#ifdef FEATURE_PREJIT
-#ifdef FEATURE_FUSION
- void SetNativeImage(IBindResult *pNativeFusionAssembly);
-#else
void SetNativeImage(PEImage *image);
-#endif
BOOL CheckNativeImageVersion(PEImage *image);
-#ifdef FEATURE_FUSION
- void ClearNativeImage();
- void SetNativeImageClosure(IAssemblyBindingClosure *pClosure)
- {
- LIMITED_METHOD_CONTRACT;
- if (m_pNativeImageClosure!=NULL)
- m_pNativeImageClosure->Release();
- if (pClosure)
- pClosure->AddRef();
- m_pNativeImageClosure=pClosure;
- };
- BOOL HasEqualNativeClosure(DomainAssembly* pDomainAssembly);
-#endif //FEATURE_FUSION
#endif // FEATURE_PREJIT
@@ -1049,29 +843,13 @@ class PEAssembly : public PEFile
// ------------------------------------------------------------
PTR_PEFile m_creator;
-#ifdef FEATURE_FUSION
- IAssemblyName *m_pFusionAssemblyName;
- IAssembly *m_pFusionAssembly;
- IFusionBindLog *m_pFusionLog;
- BOOL m_bFusionLogEnabled;
- IHostAssembly *m_pIHostAssembly;
- IAssemblyLocation *m_pNativeAssemblyLocation;
- IAssemblyBindingClosure *m_pNativeImageClosure; //present only for shared
- LOADCTX_TYPE m_loadContext;
- DWORD m_dwLocationFlags;
-#else
BOOL m_bIsFromGAC;
BOOL m_bIsOnTpaList;
// Using a separate entry and not m_pHostAssembly because otherwise
// HasHostAssembly becomes true that trips various other code paths resulting in bad
// things
SString m_sTextualIdentity;
-#endif
-#ifdef FEATURE_CORECLR
int m_fProfileAssembly; // Tri-state cache
-#else
- BOOL m_fStrongNameBypassed;
-#endif
public:
PTR_PEFile GetCreator()
@@ -1090,98 +868,15 @@ class PEAssembly : public PEFile
inline bool CanUseWithBindingCache()
{
STATIC_CONTRACT_WRAPPER;
-#if !defined(FEATURE_APPX_BINDER)
return (HasBindableIdentity());
-#else
- return (PEFile::CanUseWithBindingCache() && HasBindableIdentity());
-#endif // FEATURE_CORECLR
}
};
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-
-class PEModule : public PEFile
-{
- VPTR_VTABLE_CLASS(PEModule, PEFile)
-
- public:
-
- // ------------------------------------------------------------
- // Public API
- // ------------------------------------------------------------
-
- static PEModule *Open(PEAssembly *assembly, mdFile token,
- const SString &fileName);
-
- static PEModule *OpenMemory(PEAssembly *assembly, mdFile kToken,
- const void *flat, COUNT_T size);
-
- static PEModule *Create(PEAssembly *assembly, mdFile kToken, IMetaDataEmit *pEmit);
-
-#ifdef DACCESS_COMPILE
- virtual void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
-#endif
-
- private:
- // Private helpers for crufty exception handling reasons
- static PEModule *DoOpen(PEAssembly *assembly, mdFile token,
- const SString &fileName);
-
- static PEModule *DoOpenMemory(PEAssembly *assembly, mdFile kToken,
- const void *flat, COUNT_T size);
- public:
-
- // ------------------------------------------------------------
- // Metadata access
- // ------------------------------------------------------------
-
- PEAssembly *GetAssembly();
- mdFile GetToken();
- BOOL IsResource();
- BOOL IsIStream();
- LPCUTF8 GetSimpleName();
-
- // ------------------------------------------------------------
- // Logging
- // ------------------------------------------------------------
-#ifdef FEATURE_PREJIT
- void ExternalVLog(DWORD facility, DWORD level, const WCHAR *fmt, va_list args) DAC_EMPTY();
- void FlushExternalLog() DAC_EMPTY();
-#endif
-private:
- // ------------------------------------------------------------
- // Loader access API
- // ------------------------------------------------------------
-
- friend class DomainModule;
-#ifdef FEATURE_PREJIT
- void SetNativeImage(const SString &fullPath);
-#endif // FEATURE_PREJIT
-
-private:
-
-#ifndef DACCESS_COMPILE
- PEModule(PEImage *image, PEAssembly *assembly, mdFile token, IMetaDataEmit *pEmit);
- virtual ~PEModule();
-#endif
-
- // ------------------------------------------------------------
- // Instance fields
- // ------------------------------------------------------------
-
- PTR_PEAssembly m_assembly;
- mdFile m_token;
- BOOL m_bIsResource;
-};
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
typedef ReleaseHolder<PEFile> PEFileHolder;
typedef ReleaseHolder<PEAssembly> PEAssemblyHolder;
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-typedef ReleaseHolder<PEModule> PEModuleHolder;
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
// A small shim around PEAssemblies/IBindResult that allow us to write Fusion/CLR-agnostic
@@ -1199,21 +894,6 @@ class LoggablePEAssembly : public LoggableAssembly
return m_peAssembly->GetPath();
}
-#ifdef FEATURE_FUSION
- virtual IAssemblyName* FusionAssemblyName()
- {
- STANDARD_VM_CONTRACT;
-
- return m_peAssembly->GetFusionAssemblyName();
- }
-
- virtual IFusionBindLog* FusionBindLog()
- {
- STANDARD_VM_CONTRACT;
-
- return m_peAssembly->GetFusionBindLog();
- }
-#endif // FEATURE_FUSION
LoggablePEAssembly(PEAssembly *peAssembly)
{
diff --git a/src/vm/pefile.inl b/src/vm/pefile.inl
index 09cb89f548..44192ae3e7 100644
--- a/src/vm/pefile.inl
+++ b/src/vm/pefile.inl
@@ -12,9 +12,6 @@
#include "strongname.h"
#include "strongnameholders.h"
-#ifdef FEATURE_FUSION
-#include "fusionbind.h"
-#endif
#include "check.h"
#include "simplerwlock.hpp"
#include "eventtrace.h"
@@ -106,19 +103,7 @@ inline ULONG PEAssembly::HashIdentity()
GC_TRIGGERS;
}
CONTRACTL_END;
-#ifdef FEATURE_VERSIONING
return BINDER_SPACE::GetAssemblyFromPrivAssemblyFast(m_pHostAssembly)->GetAssemblyName()->Hash(BINDER_SPACE::AssemblyName::INCLUDE_VERSION);
-#else
- if (!m_identity->HasID())
- {
- if (!IsLoaded())
- return 0;
- else
- return (ULONG) dac_cast<TADDR>(GetLoaded()->GetBase());
- }
- else
- return m_identity->GetIDHash();
-#endif
}
inline void PEFile::ValidateForExecution()
@@ -179,23 +164,6 @@ inline BOOL PEFile::IsMarkedAsContentTypeWindowsRuntime()
return (IsAfContentType_WindowsRuntime(GetFlags()));
}
-#ifndef FEATURE_CORECLR
-inline BOOL PEFile::IsShareable()
-{
- CONTRACTL
- {
- PRECONDITION(CheckPointer(m_identity));
- MODE_ANY;
- THROWS;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- if (!m_identity->HasID())
- return FALSE;
- return TRUE ;
-}
-#endif
inline void PEFile::GetMVID(GUID *pMvid)
{
@@ -368,11 +336,7 @@ inline BOOL PEFile::IsResource() const
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- return IsModule() && dac_cast<PTR_PEModule>(this)->IsResource();
-#else
return FALSE;
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
}
inline BOOL PEFile::IsIStream() const
@@ -386,13 +350,6 @@ inline BOOL PEFile::IsIntrospectionOnly() const
{
WRAPPER_NO_CONTRACT;
STATIC_CONTRACT_SO_TOLERANT;
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- if (IsModule())
- {
- return dac_cast<PTR_PEModule>(this)->GetAssembly()->IsIntrospectionOnly();
- }
- else
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
{
return (m_flags & PEFILE_INTROSPECTIONONLY) != 0;
}
@@ -402,16 +359,9 @@ inline BOOL PEFile::IsIntrospectionOnly() const
inline PEAssembly *PEFile::GetAssembly() const
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- if (IsAssembly())
- return dac_cast<PTR_PEAssembly>(this);
- else
- return dac_cast<PTR_PEModule>(this)->GetAssembly();
-#else
_ASSERTE(IsAssembly());
return dac_cast<PTR_PEAssembly>(this);
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
}
// ------------------------------------------------------------
@@ -525,9 +475,6 @@ inline IMDInternalImport* PEFile::GetPersistentMDImport()
CONTRACT_END;
*/
SUPPORTS_DAC;
-#ifndef FEATURE_CORECLR
-_ASSERTE(m_bHasPersistentMDImport);
-#endif
#if !defined(__GNUC__)
_ASSERTE(!IsResource());
@@ -624,46 +571,6 @@ inline IMetaDataEmit *PEFile::GetEmitter()
RETURN m_pEmitter;
}
-#ifndef FEATURE_CORECLR
-inline IMetaDataAssemblyImport *PEFile::GetAssemblyImporter()
-{
- CONTRACT(IMetaDataAssemblyImport *)
- {
- INSTANCE_CHECK;
- MODE_ANY;
- GC_NOTRIGGER;
- PRECONDITION(!IsResource());
- POSTCONDITION(CheckPointer(RETVAL));
- PRECONDITION(m_bHasPersistentMDImport);
- THROWS;
- }
- CONTRACT_END;
-
- if (m_pAssemblyImporter == NULL)
- OpenAssemblyImporter();
-
- RETURN m_pAssemblyImporter;
-}
-
-inline IMetaDataAssemblyEmit *PEFile::GetAssemblyEmitter()
-{
- CONTRACT(IMetaDataAssemblyEmit *)
- {
- INSTANCE_CHECK;
- MODE_ANY;
- GC_NOTRIGGER;
- PRECONDITION(!IsResource());
- POSTCONDITION(CheckPointer(RETVAL));
- PRECONDITION(m_bHasPersistentMDImport);
- }
- CONTRACT_END;
-
- if (m_pAssemblyEmitter == NULL)
- OpenAssemblyEmitter();
-
- RETURN m_pAssemblyEmitter;
-}
-#endif // FEATURE_CORECLR
#endif // DACCESS_COMPILE
@@ -685,10 +592,6 @@ inline LPCUTF8 PEFile::GetSimpleName()
if (IsAssembly())
RETURN dac_cast<PTR_PEAssembly>(this)->GetSimpleName();
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- else if (IsModule())
- RETURN dac_cast<PTR_PEModule>(this)->GetSimpleName();
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
else
{
LPCUTF8 szScopeName;
@@ -1391,7 +1294,7 @@ inline BOOL PEFile::IsPtrInILImage(PTR_CVOID data)
if (HasOpenedILimage())
{
-#if defined(FEATURE_PREJIT) && defined(FEATURE_CORECLR)
+#if defined(FEATURE_PREJIT)
if (m_openedILimage == m_nativeImage)
{
// On Apollo builds, we sometimes open the native image into the slot
@@ -1405,7 +1308,7 @@ inline BOOL PEFile::IsPtrInILImage(PTR_CVOID data)
TADDR taddrILMetadata = dac_cast<TADDR>(pDecoder->GetMetadata(&cbILMetadata));
return ((taddrILMetadata <= taddrData) && (taddrData < taddrILMetadata + cbILMetadata));
}
-#endif // defined(FEATURE_PREJIT) && defined(FEATURE_CORECLR)
+#endif // defined(FEATURE_PREJIT)
return GetOpenedILimage()->IsPtrInImage(data);
}
else
@@ -1435,6 +1338,23 @@ inline BOOL PEFile::HasNativeImage()
#endif
}
+inline BOOL PEFile::HasNativeOrReadyToRunImage()
+{
+ CONTRACTL
+ {
+ INSTANCE_CHECK;
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ SO_TOLERANT;
+ CANNOT_TAKE_LOCK;
+ SUPPORTS_DAC;
+ }
+ CONTRACTL_END;
+
+ return (HasNativeImage() || IsILImageReadyToRun());
+}
+
inline PTR_PEImageLayout PEFile::GetLoadedIL()
{
LIMITED_METHOD_CONTRACT;
@@ -1704,9 +1624,6 @@ inline void PEAssembly::GetDisplayName(SString &result, DWORD flags)
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_FUSION
- FusionBind::GetAssemblyNameDisplayName(GetFusionAssemblyName(), result, flags);
-#else
if ((flags == (ASM_DISPLAYF_VERSION | ASM_DISPLAYF_CULTURE | ASM_DISPLAYF_PUBLIC_KEY_TOKEN)) &&
!m_sTextualIdentity.IsEmpty())
{
@@ -1718,7 +1635,6 @@ inline void PEAssembly::GetDisplayName(SString &result, DWORD flags)
spec.InitializeSpec(this);
spec.GetFileOrDisplayName(flags, result);
}
-#endif // FEATURE_FUSION
#else
IMDInternalImport *pImport = GetMDImport();
@@ -1868,25 +1784,6 @@ inline HRESULT PEFile::GetFlagsNoTrigger(DWORD * pdwFlags)
return GetPersistentMDImport()->GetAssemblyProps(TokenFromRid(1, mdtAssembly), NULL, NULL, NULL, NULL, NULL, pdwFlags);
}
-#ifdef FEATURE_CAS_POLICY
-inline COR_TRUST *PEFile::GetAuthenticodeSignature()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- }
- CONTRACTL_END;
-
- if (!m_fCheckedCertificate && HasSecurityDirectory())
- {
- CheckAuthenticodeSignature();
- }
-
- return m_certificate;
-}
-#endif
// ------------------------------------------------------------
// Hash support
@@ -1946,159 +1843,11 @@ inline BOOL PEAssembly::IsFullySigned()
}
}
-#ifndef FEATURE_CORECLR
-//---------------------------------------------------------------------------------------
-//
-// Mark that an assembly has had its strong name verification bypassed
-//
-
-inline void PEAssembly::SetStrongNameBypassed()
-{
- LIMITED_METHOD_CONTRACT;
- m_fStrongNameBypassed = TRUE;
-}
-
-inline BOOL PEAssembly::NeedsModuleHashChecks()
-{
- LIMITED_METHOD_CONTRACT;
-
- return ((m_flags & PEFILE_SKIP_MODULE_HASH_CHECKS) == 0) && !m_fStrongNameBypassed;
-}
-#endif // FEATURE_CORECLR
-
-#ifdef FEATURE_CAS_POLICY
-//---------------------------------------------------------------------------------------
-//
-// Verify the Authenticode and strong name signatures of an assembly during the assembly
-// load code path. To verify the strong name signature outside of assembly load, use the
-// VefifyStrongName method instead.
-//
-// If the applicaiton is using strong name bypass, then this method may not cause a real
-// strong name verification, delaying the assembly's strong name load until we know that
-// the verification is required. If the assembly must be forced to have its strong name
-// verified, then the VerifyStrongName method should also be chosen.
-//
-// See code:AssemblySecurityDescriptor::ResolveWorker#StrongNameBypass
-//
-
-inline void PEAssembly::DoLoadSignatureChecks()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS; // Fusion uses crsts on AddRef/Release
- MODE_ANY;
- }
- CONTRACTL_END;
-
- ETWOnStartup(SecurityCatchCall_V1, SecurityCatchCallEnd_V1);
-
- // If this isn't mscorlib or a dynamic assembly, verify the Authenticode signature.
- if (IsSystem() || IsDynamic())
- {
- // If it was a dynamic module (or mscorlib), then we don't want to be doing module hash checks on it
- m_flags |= PEFILE_SKIP_MODULE_HASH_CHECKS;
- }
- // Check strong name signature. We only want to do this now if the application is not using the strong
- // name bypass feature. Otherwise we'll delay strong name verification until we figure out how trusted
- // the assembly is.
- //
- // For more information see code:AssemblySecurityDescriptor::ResolveWorker#StrongNameBypass
-
- // Make sure m_pMDImport is initialized as we need to call VerifyStrongName which calls GetFlags
- // BypassTrustedAppStrongNames = false is a relatively uncommon scenario so we need to make sure
- // the initialization order is always correct and we don't miss this uncommon case
- _ASSERTE(GetMDImport());
-
- if (!g_pConfig->BypassTrustedAppStrongNames())
- {
- VerifyStrongName();
- }
-}
-#endif // FEATURE_CAS_POLICY
// ------------------------------------------------------------
// Metadata access
// ------------------------------------------------------------
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-inline PEAssembly *PEModule::GetAssembly()
-{
- CONTRACT(PEAssembly *)
- {
- POSTCONDITION(CheckPointer(RETVAL));
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- CANNOT_TAKE_LOCK;
- SO_TOLERANT;
- SUPPORTS_DAC;
- }
- CONTRACT_END;
-
- RETURN m_assembly;
-}
-
-inline BOOL PEModule::IsResource()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- SUPPORTS_DAC;
- }
- CONTRACTL_END;
-#ifdef DACCESS_COMPILE
- _ASSERTE(m_bIsResource!=-1);
-#else
- if (m_bIsResource==-1)
- {
- DWORD flags;
- if (FAILED(m_assembly->GetPersistentMDImport()->GetFileProps(m_token, NULL, NULL, NULL, &flags)))
- {
- _ASSERTE(!"If this fires, then we have to throw for corrupted images");
- flags = 0;
- }
- m_bIsResource=((flags & ffContainsNoMetaData) != 0);
- }
-#endif
-
- return m_bIsResource;
-}
-
-inline LPCUTF8 PEModule::GetSimpleName()
-{
- CONTRACT(LPCUTF8)
- {
- POSTCONDITION(CheckPointer(RETVAL));
- POSTCONDITION(strlen(RETVAL) > 0);
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- SUPPORTS_DAC;
- }
- CONTRACT_END;
-
- LPCUTF8 name;
-
- if (FAILED(m_assembly->GetPersistentMDImport()->GetFileProps(m_token, &name, NULL, NULL, NULL)))
- {
- _ASSERTE(!"If this fires, then we have to throw for corrupted images");
- name = "";
- }
-
- RETURN name;
-}
-
-inline mdFile PEModule::GetToken()
-{
- LIMITED_METHOD_CONTRACT;
- return m_token;
-}
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
#ifndef DACCESS_COMPILE
inline void PEFile::RestoreMDImport(IMDInternalImport* pImport)
diff --git a/src/vm/pefingerprint.cpp b/src/vm/pefingerprint.cpp
index 775966663f..b02e8a30bb 100644
--- a/src/vm/pefingerprint.cpp
+++ b/src/vm/pefingerprint.cpp
@@ -33,330 +33,6 @@
#include "pefile.h"
#include "pefingerprint.h"
-#ifdef FEATURE_FUSION
-
-static VOID ThrowTornState(LPCWSTR path);
-static void FetchILTimestampAndSize(LPCWSTR path, FILETIME *pTimestamp, DWORD *pSize, HANDLE hFileHandleIfOpen = INVALID_HANDLE_VALUE);
-
-
-const size_t PEFingerprint::s_offsets[] =
-{
- offsetof(PEFingerprint, m_timeStamp),
- offsetof(PEFingerprint, m_size),
- offsetof(PEFingerprint, m_mvid),
-};
-
-const DWORD PEFingerprint::s_sizes[] =
-{
- sizeof(((PEFingerprint *)NULL)->m_timeStamp),
- sizeof(((PEFingerprint *)NULL)->m_size),
- sizeof(((PEFingerprint *)NULL)->m_mvid),
-};
-
-
-
-//---------------------------------------------------------------
-// Ctor
-//---------------------------------------------------------------
-PEFingerprint::PEFingerprint(PEImage *owner) :
- m_pcrst(NULL)
- ,m_peimage(owner)
- ,m_commitMask(0)
- ,m_alreadyLoaded(FALSE)
- ,m_priorLockAndLoadFailure(S_OK)
-{
-
- LIMITED_METHOD_CONTRACT;
-
- _ASSERTE(owner);
-
- memset(&m_timeStamp, 0xcc, sizeof(m_timeStamp));
- memset(&m_size, 0xcc, sizeof(m_size));
- memset(&m_mvid, 0xcc, sizeof(m_mvid));
-
- return;
-}
-
-
-//---------------------------------------------------------------
-// PEFingerprint factory
-//---------------------------------------------------------------
-/*static*/ PEFingerprint *PEFingerprint::CreatePEFingerprint(PEImage *owner)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- SO_INTOLERANT;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END
-
- NewHolder<PEFingerprint> pPEFingerprint = new PEFingerprint(owner);
- pPEFingerprint->m_pcrst = new Crst(CrstLeafLock);
-
- //---------------------------------------------------------------
- // Since obtaining the timestamp is cheap and doesn't need to open the
- // file, go ahead and get it now and commit into the fingerprint.
- //
- // @review: Would it be better to lock the file right now to
- // prevent overwriter for the life of the fingerprint?
- //---------------------------------------------------------------
- LPCWSTR path = pPEFingerprint->m_peimage->GetPath();
- _ASSERTE(path);
-
- FILETIME lastWriteTime;
- DWORD size;
- FetchILTimestampAndSize(path, &lastWriteTime, &size);
-
- ILFingerprintComponent components[] =
- {
- { ILFTagTimestamp, &lastWriteTime },
- { ILFTagSize, &size },
- };
- BOOL success = pPEFingerprint->CommitAndCompareMulti(COUNTOF(components), components);
- _ASSERTE(success); // No way this commit can fail - we own the only pointer!
- return pPEFingerprint.Extract();
-}
-
-
-
-//---------------------------------------------------------------
-// Dtor
-//---------------------------------------------------------------
-PEFingerprint::~PEFingerprint()
-{
- LIMITED_METHOD_CONTRACT;
- delete m_pcrst;
- return;
-}
-
-//---------------------------------------------------------------
-// AddRef
-//---------------------------------------------------------------
-ULONG PEFingerprint::AddRef()
-{
- LIMITED_METHOD_CONTRACT;
- return m_peimage->AddRef();
-}
-
-//---------------------------------------------------------------
-// Release
-//---------------------------------------------------------------
-ULONG PEFingerprint::Release()
-{
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_CAN_TAKE_LOCK;
- return m_peimage->Release();
-}
-
-//---------------------------------------------------------------------------------------------
-// Convenience fcn: equivalent to calling CommitAndCompareMulti() with one component.
-//---------------------------------------------------------------------------------------------
-BOOL PEFingerprint::CommitAndCompare(ILFingerprintTag componentType, LPCVOID data)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- SO_INTOLERANT;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END
-
- ILFingerprintComponent c = {componentType, data};
- return CommitAndCompareMulti(1, &c);
-}
-
-
- //---------------------------------------------------------------------------------------------
- // CommitAndCompareMulti(): Atomically commits one or more fingerprint components into
- // the fingerprint. Once a component is committed, its value can never change.
- //
- // An attempt to commit a component succeeds only if the component was not already committed
- // or the prior value maches the new one exactly.
- //
- // Calling CommitAndCompare() multiple times is not equivalent to calling CommitAndCompareMulti().
- // CommitAndCompareMulti() is atomic - either all the commits happen or none of them do.
- //
- // Returns:
- // TRUE: All passed components committed successful.
- // FALSE: At leat one component failed to commit successfully.
- //---------------------------------------------------------------------------------------------
-BOOL PEFingerprint::CommitAndCompareMulti(UINT numComponents, const ILFingerprintComponent *pComponents)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- SO_INTOLERANT;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END
-
- //------------------------------------------------------------------------------
- // See "Dev11 note on timing of torn state detection". This step should not be
- // here but this is how we "verify" the MVID/SNHash on IL open. We wait until
- // the first time someone attempts a commit on an opened file to do the check.
- // The caller will think we did the check at file open time, even though we
- // actually left a window of vulnerability.
- //------------------------------------------------------------------------------
- if (!m_alreadyLoaded)
- {
- PEImageHolder pOpenedILimage;
- m_peimage->Clone(MDInternalImport_OnlyLookInCache,&pOpenedILimage);
-
- if(pOpenedILimage != NULL && pOpenedILimage->IsOpened())
- {
-
- for (UINT j = 0; j < numComponents; j++)
- {
- // Don't open if we're just checking timestamp (forecloses possible reentrancy problems
- // due to timestamp commits occurring within PEImage itself.)
- ILFingerprintTag tag = pComponents[j]._tag;
- if (tag == ILFTagMvid)
- {
- this->LockAndLoadIL();
- break;
- }
-
- }
- }
- }
-
- //------------------------------------------------------------------------------
- // Inside the crit section, make sure all the components can successfully commit
- // before commitng any of them.
- //------------------------------------------------------------------------------
- CrstHolder ch(m_pcrst);
- UINT i;
- for (i = 0; i < numComponents; i++)
- {
- ILFingerprintTag tag = pComponents[i]._tag;
- if (IsComponentCommitted(tag))
- {
- if (0 != memcmp(pComponents[i]._data, TagDataStart(tag), TagDataSize(tag)))
- return FALSE;
- }
- }
- for (i = 0; i < numComponents; i++)
- {
- ILFingerprintTag tag = pComponents[i]._tag;
- if (!IsComponentCommitted(tag))
- {
- memcpy(TagDataStart(tag), pComponents[i]._data, TagDataSize(tag));
- SetComponentCommitted(tag);
- }
- }
-
- return TRUE;
-}
-
-
-
-//---------------------------------------------------------------------------------------------
-// LockAndLoadIL()
-//
-// Forces the runtime to open the IL file and lock it against future overwrites. This
-// is bad for working set so this should be avoided.
-//
-// Once opened and locked, this method extracts the actual fingerprint from the IL file
-// and attempts to commit it into the ILFingerprint. If successful, all future commits
-// will now be compared against this trusted data. If unsuccessful, this is a torn state
-// situation and LockAndLoadIL() throws the torn state exception.
-//---------------------------------------------------------------------------------------------
-void PEFingerprint::LockAndLoadIL()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- SO_INTOLERANT;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END
-
- //----------------------------------------------------------------------------------
- // If already loaded, return the prior result.
- //----------------------------------------------------------------------------------
- if (m_alreadyLoaded)
- {
- if (FAILED(m_priorLockAndLoadFailure))
- {
- ThrowHR(m_priorLockAndLoadFailure);
- }
- else
- {
- return;
- }
- }
- PEImageHolder pOpenedILimage;
- m_peimage->Clone(MDInternalImport_Default,&pOpenedILimage);
- HRESULT hr = S_OK;
- {
- GCX_PREEMP();
- IfFailThrow(m_peimage->TryOpenFile());
- }
- //----------------------------------------------------------------------------------
- // Force the file open (by requesting a metadata pointer to it.)
- //----------------------------------------------------------------------------------
- IMDInternalImport *pMDImport = NULL;
- EX_TRY
- {
- pMDImport = pOpenedILimage->GetMDImport();
- hr = S_OK;
- }
- EX_CATCH_HRESULT(hr);
- if (Exception::IsTransient(hr))
- ThrowHR(hr);
- if (FAILED(hr))
- {
- m_priorLockAndLoadFailure = hr;
- m_alreadyLoaded = TRUE;
- ThrowHR(hr);
- }
-
- m_alreadyLoaded = TRUE;
-
- //------------------------------------------------------------------------------
- // See "Dev11 note on timing of torn state detection". This step should not be
- // here as the "right" design is to extract the actual MVID before we officially
- // open the file. But since we don't do that in the current implementation, we do
- // it now.
- //------------------------------------------------------------------------------
- GUID mvid;
- pOpenedILimage->GetMVID(&mvid);
-
- BOOL success = this->CommitAndCompare(ILFTagMvid, &mvid);
- if (!success)
- ThrowTornState(m_peimage->GetPath());
-}
-
-
-//==================================================================================
-// Helper for throwing a torn state exception.
-//==================================================================================
-static VOID ThrowTornState(LPCWSTR path)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- SO_INTOLERANT;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END
-
- COMPlusThrow(kFileLoadException, IDS_EE_TORNSTATE, path);
-}
-
-#endif // FEATURE_FUSION
@@ -384,240 +60,7 @@ PEFingerprintVerificationHolder::PEFingerprintVerificationHolder(PEImage *owner)
}
CONTRACTL_END
-#ifdef FEATURE_FUSION
- if (owner->IsTrustedNativeImage())
- return; // Waste of cycles to check timestamps for NI images.
-
-
- LPCWSTR path = owner->GetPath();
- _ASSERTE(path);
-
- if (owner->IsOpened())
- return; // Not the first layout to be opened - no need to repeat the work in that case.
-
- // First, lock the file and verify that the timestamp hasn't changed.
- TESTHOOKCALL(AboutToLockImage(path, IsCompilationProcess()));
- m_fileHandle = WszCreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
- if (m_fileHandle == INVALID_HANDLE_VALUE)
- {
- // @review: If this call to open the file fails, it sounds a bit risky to fail the PE open altogether
- // just to do a torn state check. Let the torn state detection bake a bit before we take this step.
- return;
- }
-
- FILETIME lastWriteTime;
- DWORD size;
- FetchILTimestampAndSize(path, &lastWriteTime, &size, m_fileHandle);
- ReleaseHolder<IILFingerprint> fingerPrint;
- ILFingerprintComponent components[] =
- {
- { ILFTagTimestamp, &lastWriteTime },
- { ILFTagSize, &size },
- };
- IfFailThrow(owner->GetILFingerprint(&fingerPrint));
- if (!fingerPrint->CommitAndCompareMulti(COUNTOF(components), components))
- ThrowTornState(path);
-
-
- // Now, verify that the MVID/SNHash/TPBand hasn't changed.
- // Oh wait, where that'd code go? See "Dev11 note on timing of torn state detection".
-#endif // FEATURE_FUSION
- return;
-}
-
-#ifdef FEATURE_FUSION
-#ifndef DACCESS_COMPILE
-class CachingILFingerprintFactory : public IILFingerprintFactory
-{
-private:
- LONG m_refCount;
- Crst m_lock;
-
- // Hash Type ... NOTE! This is a case sensitive hash of a filename to an IL fingerprint.
- // This is acceptable as duplicates are not errors, and chosen as case insensitive hashes
- // are somewhat slower, and most hash lookups will actually match in case. If this is not
- // the case, converting to a case-insensitive hash should be trivial.
- typedef StringSHashWithCleanup< IILFingerprint, WCHAR > ILFingerprintHash;
- typedef StringHashElement< IILFingerprint, WCHAR > ILFingerprintHashElement;
-
- ILFingerprintHash m_hash;
-
- ~CachingILFingerprintFactory()
- {
- }
-
-public:
-
- CachingILFingerprintFactory() : m_refCount(1), m_lock(CrstILFingerprintCache)
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
- }
-
- STDMETHOD_(ULONG, AddRef)()
- {
- CONTRACT(ULONG)
- {
- PRECONDITION(m_refCount>0 && m_refCount < COUNT_T_MAX);
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACT_END;
-
- RETURN (static_cast<ULONG>(FastInterlockIncrement(&m_refCount)));
- }
-
- STDMETHOD_(ULONG, Release)()
- {
- CONTRACTL
- {
- DESTRUCTOR_CHECK;
- NOTHROW;
- MODE_ANY;
- FORBID_FAULT;
- }
- CONTRACTL_END;
-
- ULONG result = 0;
- result=FastInterlockDecrement(&m_refCount);
- if (result == 0)
- delete this;
-
- return result;
- }
-
- STDMETHOD(GetILFingerprintForPath)(
- LPCWSTR pwzPath,
- IILFingerprint **ppFingerprint)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
- HRESULT hr = S_OK;
-
- EX_TRY
- {
- CrstHolder ch(&m_lock);
- // Lookup in cache
- ILFingerprintHashElement *pCacheElement = m_hash.Lookup(pwzPath);
-
- // If that fails, run the parser, and populate the cache
- if (pCacheElement != NULL)
- {
- *ppFingerprint = clr::SafeAddRef(pCacheElement->Object);
- }
- else
- {
- // Create new assembly name object;
- ReleaseHolder<IILFingerprint> pFingerprint;
- NewArrayHolder<WCHAR> pwzPathCopy;
- IfFailThrow(RuntimeGetILFingerprintForPath(pwzPath, &pFingerprint));
-
- // Create hash element object
- NewHolder<ILFingerprintHashElement> pHashElem = new ILFingerprintHashElement();
- pwzPathCopy = DuplicateStringThrowing(pwzPath);
- pHashElem->String = pwzPathCopy;
- pHashElem->Object = pFingerprint;
-
- // Insert into hash table
- m_hash.Add(pHashElem);
-
- *ppFingerprint = clr::SafeAddRef(pFingerprint);
-
- // Prevent disastrous cleanup
- pwzPathCopy.SuppressRelease();
- pHashElem.SuppressRelease();
- pFingerprint.SuppressRelease();
- }
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
- }
-};
-
-HRESULT RuntimeCreateCachingILFingerprintFactory(IILFingerprintFactory **ppILFingerprintFactory)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
- HRESULT hr = S_OK;
-
- EX_TRY
- {
- *ppILFingerprintFactory = new CachingILFingerprintFactory();
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
-//-------------------------------------------------------------------------------------------------------------
-// Common routine to fetch the IL file's timestamp and size. If the caller already has an open file handle, it should
-// pass that as "hFileHandleIfOpen" to avoid the overhead of opening the file again.
-//-------------------------------------------------------------------------------------------------------------
-static void FetchILTimestampAndSize(LPCWSTR path, FILETIME *pTimestamp, DWORD *pSize, HANDLE hFileHandleIfOpen /* = INVALID_HANDLE_VALUE*/)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- SO_INTOLERANT;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END
-
- _ASSERTE(pTimestamp != NULL && pSize != NULL);
-
- if (hFileHandleIfOpen != INVALID_HANDLE_VALUE)
- {
- BY_HANDLE_FILE_INFORMATION info;
- if (!GetFileInformationByHandle(hFileHandleIfOpen, &info))
- ThrowLastError();
- *pTimestamp = info.ftLastWriteTime;
- *pSize = info.nFileSizeLow;
- return;
- }
-
- // For normal files, we can obtain the timestamp without opening the file - attempt to do so.
- WIN32_FILE_ATTRIBUTE_DATA wfd;
- if (!WszGetFileAttributesEx(path, GetFileExInfoStandard, &wfd))
- ThrowLastError();
- if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))
- {
- *pTimestamp = wfd.ftLastWriteTime;
- *pSize = wfd.nFileSizeLow;
- return;
- }
-
- // If we got here, the original path pointed to a symbolic or some other form of reparse point. In such cases, GetFileAttributesEx
- // may not return the same timestamp as GetFileInformationByHandle. (E.g. in the symbolic link case, GetFileAttributeEx returns
- // the symbolic link's timestamp rather than the target's timestamp.)
- //
- // Since this is the uncommon case, we can justify the perf hit of opening the file so we get the timestamp
- // on the actual target.
- HandleHolder hFile(WszCreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
- if (hFile == INVALID_HANDLE_VALUE)
- ThrowLastError();
- BY_HANDLE_FILE_INFORMATION info;
- if (!GetFileInformationByHandle(hFile, &info))
- ThrowLastError();
- *pTimestamp = info.ftLastWriteTime;
- *pSize = info.nFileSizeLow;
return;
}
-#endif // !DACCESS_COMPILE
-#endif // FEATURE_FUSION
diff --git a/src/vm/pefingerprint.h b/src/vm/pefingerprint.h
index 357351f4ae..8db8df729a 100644
--- a/src/vm/pefingerprint.h
+++ b/src/vm/pefingerprint.h
@@ -11,95 +11,6 @@
#define PEFINGERPRINT_H_
-#ifdef FEATURE_FUSION
-
-#include "corcompile.h"
-
-class PEImage;
-
-//==================================================================================
-// This is the implementation of IILFingerprint object maintained by PEImage objects.
-// IILFingerprint is described in detail in IILFingerprint.h
-//==================================================================================
-class PEFingerprint : public IILFingerprint
-{
- public:
- //----------------------------------------------------------------
- // IILFingerprint methods
- //----------------------------------------------------------------
- STDMETHOD_(ULONG, AddRef)();
- STDMETHOD_(ULONG, Release)();
- STDMETHOD_(BOOL, CommitAndCompare)(ILFingerprintTag componentType, LPCVOID data);
- STDMETHOD_(BOOL, CommitAndCompareMulti)(UINT numComponents, const ILFingerprintComponent *pComponents);
- STDMETHOD_(void, LockAndLoadIL)();
-
- //----------------------------------------------------------------
- // Non-interface public methods.
- //----------------------------------------------------------------
- public:
- static PEFingerprint* PEFingerprint::CreatePEFingerprint(PEImage *owner);
- virtual ~PEFingerprint();
-
- private:
- PEFingerprint(PEImage *owner);
-
- //----------------------------------------------------------------
- // Private methods.
- //----------------------------------------------------------------
- private:
-
- BOOL IsComponentCommitted(ILFingerprintTag tag)
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(tag < ILFTagCount);
- return 0 != (m_commitMask & (1 << tag));
- }
-
- void SetComponentCommitted(ILFingerprintTag tag)
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(tag < ILFTagCount);
- m_commitMask |= (1 << tag);
- }
-
- LPVOID TagDataStart(ILFingerprintTag tag)
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(tag < ILFTagCount);
- return (LPVOID)(((LPBYTE)this) + s_offsets[tag]);
- }
-
- DWORD TagDataSize(ILFingerprintTag tag)
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE(tag < ILFTagCount);
- return s_sizes[tag];
- }
-
-
- //----------------------------------------------------------------
- // Private instance data
- //----------------------------------------------------------------
- private:
- Crst *m_pcrst; // Synchronizes updates to fingerprint
- PEImage *m_peimage; // Backpointer to PEImage (for ref-counting purposes, the PEImage and PEFingerprint have the same identity)
- DWORD m_commitMask; // Bitmask to indicate which components have been committed ( fCommitted = (m_commitMask & (1 << tag)) )
- FILETIME m_timeStamp; // Component: File system lastwrite Timestamp
- DWORD m_size; // Component: File size
- GUID m_mvid; // Component: Mvid
-
- BOOL m_alreadyLoaded; // Turns repeated attempts to LockAndLoadIL() into NOP's
- HRESULT m_priorLockAndLoadFailure; // If LockAndLoadIL() failed the first time, return the same failure on subsequent attempts.
-
- //----------------------------------------------------------------
- // Private static data
- //----------------------------------------------------------------
- private:
- const static size_t s_offsets[ILFTagCount]; // static: Maps tags to offsets within PEFingerprint
- const static DWORD s_sizes[ILFTagCount]; // static: Maps tag to expected data size
-};
-
-#endif // FEATURE_FUSION
//==================================================================================
diff --git a/src/vm/peimage.cpp b/src/vm/peimage.cpp
index 583c5e3144..39b71ff62f 100644
--- a/src/vm/peimage.cpp
+++ b/src/vm/peimage.cpp
@@ -28,10 +28,6 @@
CrstStatic PEImage::s_hashLock;
PtrHashMap *PEImage::s_Images = NULL;
-#ifdef FEATURE_MIXEDMODE
-CrstStatic PEImage::s_ijwHashLock;
-PtrHashMap *PEImage::s_ijwFixupDataHash;
-#endif
extern LocaleID g_lcid; // fusion path comparison lcid
@@ -58,20 +54,12 @@ void PEImage::Startup()
LockOwner lock = { &s_hashLock, IsOwnerOfCrst };
s_Images = ::new PtrHashMap;
s_Images->Init(CompareImage, FALSE, &lock);
-#ifdef FEATURE_MIXEDMODE
- s_ijwHashLock.Init(CrstIJWHash, CRST_REENTRANCY);
- LockOwner ijwLock = { &s_ijwHashLock, IsOwnerOfCrst };
- s_ijwFixupDataHash = ::new PtrHashMap;
- s_ijwFixupDataHash->Init(CompareIJWDataBase, FALSE, &ijwLock);
-#endif
PEImageLayout::Startup();
-#ifndef FEATURE_FUSION
#ifdef FEATURE_USE_LCID
g_lcid = MAKELCID(LOCALE_INVARIANT, SORT_DEFAULT);
#else // FEATURE_USE_LCID
g_lcid = NULL; // invariant
#endif //FEATURE_USE_LCID
-#endif
END_SO_INTOLERANT_CODE;
RETURN;
@@ -226,27 +214,8 @@ PEImage::~PEImage()
m_pMDTracker->Deactivate();
#endif // METADATATRACKER_ENABLED
-#ifdef FEATURE_FUSION
- delete m_pILFingerprint;
-#endif // FEATURE_FUSION
}
-#ifdef FEATURE_MIXEDMODE
-/* static */
-BOOL PEImage::CompareIJWDataBase(UPTR base, UPTR mapping)
-{
- CONTRACTL {
- PRECONDITION(CheckStartup());
- PRECONDITION(CheckPointer((BYTE *) (base<<1)));
- PRECONDITION(CheckPointer((IJWFixupData *)mapping));
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- return ((BYTE *) (base<<1) == ((IJWFixupData*)mapping)->GetBase());
-}
-#endif // FEATURE_MIXEDMODE
// Thread stress
#if 0
@@ -444,12 +413,6 @@ BOOL PEImage::CompareImage(UPTR u1, UPTR u2)
// This is the value stored in the table
PEImage *pImage = (PEImage *) u2;
-#ifdef FEATURE_FUSION
- if (pLocator->m_fIsIStream)
- {
- return pImage->m_fIsIStream && (pLocator->m_StreamAsmId == pImage->m_StreamAsmId) && (pLocator->m_dwStreamModuleId == pImage->m_dwStreamModuleId);
- }
-#endif
BOOL ret = FALSE;
HRESULT hr;
@@ -475,103 +438,13 @@ BOOL PEImage::Equals(PEImage *pImage)
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
// PEImage is always unique on CoreCLR so a simple pointer check is sufficient
_ASSERTE(m_bInHashMap || GetPath().IsEmpty());
_ASSERTE(pImage->m_bInHashMap || pImage->GetPath().IsEmpty());
return dac_cast<TADDR>(pImage) == dac_cast<TADDR>(this);
-#else // FEATURE_CORECLR
- if (pImage == this)
- return TRUE;
-
- if (GetPath().IsEmpty())
- {
-#ifdef FEATURE_FUSION
- if (m_fIsIStream && pImage->m_fIsIStream)
- {
- return (m_StreamAsmId == pImage->m_StreamAsmId) && (m_dwStreamModuleId == pImage->m_dwStreamModuleId);
- }
-#endif
-
- return FALSE;
- }
- else
- {
- BOOL ret = FALSE;
- HRESULT hr;
- EX_TRY
- {
- if (PathEquals(GetPath(), pImage->GetPath()))
- ret = TRUE;
- }
- EX_CATCH_HRESULT(hr); //<TODO>ignores failure!</TODO>
- return ret;
- }
-#endif // FEATURE_CORECLR
-}
-
-#ifndef FEATURE_CORECLR
-void PEImage::ComputeHash(ALG_ID algorithm, SBuffer &result)
-{
- CONTRACTL
- {
- INSTANCE_CHECK;
- PRECONDITION(CheckStartup());
- PRECONDITION(CheckValue(result));
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- PEImageLayoutHolder pview(GetLayout(PEImageLayout::LAYOUT_FLAT,PEImage::LAYOUT_CREATEIFNEEDED));
-
- if (algorithm == CALG_SHA1)
- {
- SHA1Hash hasher;
- hasher.AddData((BYTE *) pview->GetBase(), pview->GetSize());
- result.Set(hasher.GetHash(), SHA1_HASH_SIZE);
- return;
- }
-
- DWORD size = 0;
- if(!StrongNameHashSize(algorithm, &size))
- {
- ThrowHR(StrongNameErrorInfo());
- }
-
- BYTE *buffer = result.OpenRawBuffer(size);
-
- DWORD hashSize;
- IfFailThrow(GetHashFromBlob((BYTE *) pview->GetBase(), pview->GetSize(), &algorithm, buffer, size, &hashSize));
-
- _ASSERTE(size == hashSize);
-
- result.CloseRawBuffer(hashSize);
}
-CHECK PEImage::CheckHash(ALG_ID algorithm, const void *pbHash, COUNT_T cbHash)
-{
- CONTRACT_CHECK
- {
- INSTANCE_CHECK;
- PRECONDITION(CheckStartup());
- INSTANCE_CHECK;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACT_CHECK_END;
-
- StackSBuffer hash;
- ComputeHash(algorithm, hash);
-
- CHECK(hash.Equals((const BYTE *) pbHash, cbHash));
-
- CHECK_OK;
-}
-#endif // FEATURE_CORECLR
IMDInternalImport* PEImage::GetMDImport()
{
@@ -833,481 +706,9 @@ void DECLSPEC_NORETURN PEImage::ThrowFormat(HRESULT hrError)
EEFileLoadException::Throw(m_path, hrError);
}
-#ifdef FEATURE_FUSION
-// --------------------------------------------------------------------------------
-// Exports for the metadata APIs for fusion.
-// --------------------------------------------------------------------------------
-
-HRESULT STDMETHODCALLTYPE RuntimeOpenImage(LPCWSTR pszFileName, HCORMODULE* hHandle)
-{
- WRAPPER_NO_CONTRACT;
- return RuntimeOpenImageInternal(pszFileName, hHandle, NULL, MDInternalImport_Default);
-}
-
-HRESULT STDMETHODCALLTYPE RuntimeOpenImageInternal(LPCWSTR pszFileName, HCORMODULE* hHandle, DWORD *pdwLength, MDInternalImportFlags flags, HANDLE hFile)
-{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_SO_INTOLERANT;
- HRESULT hr = S_OK;
- ETWOnStartup (LoaderCatchCall_V1,LoaderCatchCallEnd_V1);
- EX_TRY
- {
- PEImage::Startup();
- PEImageHolder pFile(PEImage::OpenImage(pszFileName, flags));
- if (hFile != INVALID_HANDLE_VALUE)
- {
- pFile->SetFileHandle(hFile);
- }
- if (pdwLength)
- {
- PEImageLayoutHolder pLayout(pFile->GetLayout(PEImageLayout::LAYOUT_MAPPED,PEImage::LAYOUT_CREATEIFNEEDED));
- pFile->CachePEKindAndMachine();
- *pdwLength = pLayout->GetSize();
- }
- *hHandle = (HCORMODULE)pFile.Extract();
- }
- EX_CATCH_HRESULT(hr);
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE RuntimeOpenImageByStream(IStream* pIStream, UINT64 AssemblyId,
- DWORD dwModuleId,
- HCORMODULE* hHandle, DWORD *pdwLength, MDInternalImportFlags flags)
-{
- STATIC_CONTRACT_NOTHROW;
- HRESULT hr = S_OK;
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
- EX_TRY
- {
- PEImage::Startup();
-
- PEImageHolder pFile(PEImage::OpenImage(pIStream, AssemblyId, dwModuleId, FALSE, flags));
- *hHandle = (HCORMODULE) pFile.Extract();
- if (pdwLength)
- {
- PEImageLayoutHolder pImage(pFile->GetLayout(PEImageLayout::LAYOUT_ANY,0));
- pFile->CachePEKindAndMachine();
- *pdwLength = pImage->GetSize();
- }
- }
- EX_CATCH_HRESULT(hr);
- END_SO_INTOLERANT_CODE;
-
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE RuntimeReleaseHandle(HCORMODULE hHandle)
-{
- STATIC_CONTRACT_NOTHROW;
- HRESULT hr = S_OK;
-
- PEImage *pImage = (PEImage*)hHandle;
-
- if (pImage != NULL)
- pImage->Release();
-
- return hr;
-}
-
-void RuntimeAddRefHandle(HCORMODULE hHandle)
-{
- STATIC_CONTRACT_NOTHROW;
-
- PEImage *pImage = (PEImage*)hHandle;
-
- if (pImage != NULL)
- pImage->AddRef();
-}
-
-HRESULT STDMETHODCALLTYPE RuntimeGetMDInternalImport(HCORMODULE hHandle, MDInternalImportFlags flags, IMDInternalImport** ppMDImport)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- SO_TOLERANT;
- }
- CONTRACTL_END;
- PEImage* pImage=(PEImage*)hHandle;
- HRESULT hr=S_OK;
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
- EX_TRY
- {
- if (!pImage->HasNTHeaders() || !pImage->HasCorHeader())
- hr=HRESULT_FROM_WIN32(ERROR_FILE_INVALID);
- else
- {
-#ifdef FEATURE_PREJIT
- if (pImage->HasNativeHeader())
- {
- if (!pImage->CheckNativeFormat())
- hr=COR_E_BADIMAGEFORMAT;
- else
- {
- if (flags & MDInternalImport_ILMetaData)
- goto OPEN_IL_METADATA;
-
- *ppMDImport=pImage->GetNativeMDImport();
- if (*ppMDImport)
- (*ppMDImport)->AddRef();
- else
- hr=COR_E_BADIMAGEFORMAT;
- }
- }
- else
-#endif //FEATURE_PREJIT
- {
- if (!pImage->CheckILFormat())
- hr=COR_E_BADIMAGEFORMAT;
- else
- {
-#ifdef FEATURE_PREJIT
- OPEN_IL_METADATA:
-#endif
- *ppMDImport=pImage->GetMDImport();
- if (*ppMDImport)
- (*ppMDImport)->AddRef();
- else
- hr=COR_E_BADIMAGEFORMAT;
- }
- }
- }
- }
- EX_CATCH_HRESULT(hr);
- END_SO_INTOLERANT_CODE;
-
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE RuntimeGetImageBase(HCORMODULE hHandle,LPVOID* base, BOOL bMapped, COUNT_T* dwSize)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- SO_TOLERANT;
- }
- CONTRACTL_END;
- HRESULT hr=S_FALSE;
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
- EX_TRY
- {
- PEImage* pImage=(PEImage*)hHandle;
- *base=NULL;
- if (!pImage->HasLoadedLayout())
- {
- PEImageLayoutHolder pLayout(pImage->GetLayout(bMapped
- ?PEImageLayout::LAYOUT_MAPPED
- :PEImageLayout::LAYOUT_FLAT,0));
- if (pLayout!=NULL)
- {
- if(dwSize)
- *dwSize=pLayout->GetSize();
- *base=pLayout->GetBase();
- hr=S_OK;
- }
- }
-
- if (hr==S_FALSE && pImage->HasLoadedLayout())
- {
- BOOL bIsMapped=pImage->GetLoadedLayout()->IsMapped();
- if ((bIsMapped && bMapped) || (!bIsMapped && !bMapped))
- {
- //the one we want
- *base=pImage->GetLoadedLayout()->GetBase();
- if (dwSize)
- *dwSize=pImage->GetLoadedLayout()->GetSize();
- hr=S_OK;
- }
- }
- }
- EX_CATCH_HRESULT(hr);
- END_SO_INTOLERANT_CODE;
-
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE RuntimeGetImageKind(HCORMODULE hHandle,DWORD* pdwKind, DWORD* pdwMachine)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- SO_TOLERANT;
- }
- CONTRACTL_END;
- HRESULT hr=S_FALSE;
-
- PEImage* pImage=(PEImage*)hHandle;
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
- EX_TRY
- {
- pImage->GetPEKindAndMachine(pdwKind, pdwMachine);
- hr = S_OK;
- }
- EX_CATCH_HRESULT(hr);
- END_SO_INTOLERANT_CODE;
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE RuntimeOSHandle(HCORMODULE hHandle, HMODULE* hModule)
-{
- LIMITED_METHOD_CONTRACT;
- if(hHandle==NULL || hModule == NULL)
- return E_POINTER;
- PEImage* pImage= (PEImage*) hHandle;
- if (!pImage->HasLoadedLayout())
- return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
- *hModule=(HMODULE)pImage->GetLoadedLayout()->GetBase();
- return S_OK;
-}
-HRESULT RuntimeGetAssemblyStrongNameHashForModule(HCORMODULE hModule,
- IMetaDataImport * pMDImport,
- BYTE *pbSNHash,
- DWORD *pcbSNHash)
-{
- STATIC_CONTRACT_NOTHROW;
- HRESULT hr = S_OK;
- PEImage* pImage = (PEImage*)hModule;
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
- EX_TRY
- {
-
- if (pImage->HasStrongNameSignature())
- {
- if (pImage->IsStrongNameSigned())
- {
- SBuffer signature;
- pImage->GetHashedStrongNameSignature(signature);
- *pcbSNHash = min(signature.GetSize(), *pcbSNHash);
- signature.Copy(pbSNHash, signature.Begin(), *pcbSNHash);
- }
- else
- {
- // This assembly is delay signed (in this limited scenario).
- // We'll use the assembly MVID as the hash and leave assembly verification
- // up to the loader to determine if delay signed assemblies are allowed.
- // This allows us to fix the perf degrade observed with the hashing code and
- // detailed in BUG 126760.
-
- // <TODO>@TODO:workaround: This is a workaround because Fusion is expecting at least 20 bytes of data.</TODO>
- if (max(sizeof(GUID), 20) <= *pcbSNHash)
- {
- memset(pbSNHash, 0, *pcbSNHash);
- hr = pMDImport->GetScopeProps(NULL, 0, NULL, (GUID *) pbSNHash);
- }
- else
- hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
-
- *pcbSNHash = max(sizeof(GUID), 20);
- }
- }
- else
- {
- hr = CORSEC_E_MISSING_STRONGNAME;
- }
- }
- EX_CATCH_HRESULT(hr);
- END_SO_INTOLERANT_CODE;
-
- return hr;
-}
-
-#endif // FEATURE_FUSION
-
-
-#if defined(FEATURE_MIXEDMODE) && !defined(CROSSGEN_COMPILE)
-
-//may outlive PEImage
-PEImage::IJWFixupData::IJWFixupData(void *pBase)
- : m_lock(CrstIJWFixupData),
- m_base(pBase), m_flags(0),m_DllThunkHeap(NULL),m_iNextFixup(0),m_iNextMethod(0)
-{
- WRAPPER_NO_CONTRACT;
-}
-
-PEImage::IJWFixupData::~IJWFixupData()
-{
- WRAPPER_NO_CONTRACT;
- if (m_DllThunkHeap)
- delete m_DllThunkHeap;
-}
-
-
-// Self-initializing accessor for m_DllThunkHeap
-LoaderHeap *PEImage::IJWFixupData::GetThunkHeap()
-{
- CONTRACT (LoaderHeap *)
- {
- INSTANCE_CHECK;
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END
-
- if (!m_DllThunkHeap)
- {
- size_t * pPrivatePCLBytes = NULL;
- size_t * pGlobalPCLBytes = NULL;
-
-#ifdef PROFILING_SUPPORTED
- pPrivatePCLBytes = &(GetPerfCounters().m_Loading.cbLoaderHeapSize);
-#endif
-
- LoaderHeap *pNewHeap = new LoaderHeap(VIRTUAL_ALLOC_RESERVE_GRANULARITY, // DWORD dwReserveBlockSize
- 0, // DWORD dwCommitBlockSize
- pPrivatePCLBytes,
- ThunkHeapStubManager::g_pManager->GetRangeList(),
- TRUE); // BOOL fMakeExecutable
-
- if (FastInterlockCompareExchangePointer((PVOID*)&m_DllThunkHeap, (VOID*)pNewHeap, (VOID*)0) != 0)
- {
- delete pNewHeap;
- }
- }
-
- RETURN m_DllThunkHeap;
-}
-
-void PEImage::IJWFixupData::MarkMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod)
-{
- LIMITED_METHOD_CONTRACT;
- // supports only sequential fixup/method
- _ASSERTE( (iFixup == m_iNextFixup+1 && iMethod ==0) || //first method of the next fixup or
- (iFixup == m_iNextFixup && iMethod == m_iNextMethod) ); //the method that was next to fixup
-
- m_iNextFixup = iFixup;
- m_iNextMethod = iMethod+1;
-}
-
-BOOL PEImage::IJWFixupData::IsMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod)
-{
- LIMITED_METHOD_CONTRACT;
- if (iFixup < m_iNextFixup)
- return TRUE;
- if (iFixup > m_iNextFixup)
- return FALSE;
- if (iMethod < m_iNextMethod)
- return TRUE;
-
- return FALSE;
-}
-
-/*static */
-PTR_LoaderHeap PEImage::GetDllThunkHeap(void *pBase)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
- return GetIJWData(pBase)->GetThunkHeap();
-}
-
-/* static */
-PEImage::IJWFixupData *PEImage::GetIJWData(void *pBase)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END
-
- // Take the IJW hash lock
- CrstHolder hashLockHolder(&s_ijwHashLock);
-
- // Try to find the data
- IJWFixupData *pData = (IJWFixupData *)s_ijwFixupDataHash->LookupValue((UPTR) pBase, pBase);
-
- // No data, must create
- if ((UPTR)pData == (UPTR)INVALIDENTRY)
- {
- pData = new IJWFixupData(pBase);
- s_ijwFixupDataHash->InsertValue((UPTR) pBase, pData);
- }
-
- // Return the new data
- return (pData);
-}
-
-/* static */
-void PEImage::UnloadIJWModule(void *pBase)
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- } CONTRACTL_END
-
- // Take the IJW hash lock
- CrstHolder hashLockHolder(&s_ijwHashLock);
-
- // Try to delete the hash entry
- IJWFixupData *pData = (IJWFixupData *)s_ijwFixupDataHash->DeleteValue((UPTR) pBase, pBase);
-
- // Now delete the data
- if ((UPTR)pData != (UPTR)INVALIDENTRY)
- delete pData;
-
-}
-
-#endif // FEATURE_MIXEDMODE && !CROSSGEN_COMPILE
-
-#ifdef FEATURE_FUSION
-void PEImage::Init(IStream* pIStream, UINT64 uAsmStreamId,
- DWORD dwModuleId, BOOL resourceFile)
-{
- CONTRACT_VOID
- {
- CONSTRUCTOR_CHECK;
- PRECONDITION(CheckStartup());
- STANDARD_VM_CHECK;
- }
- CONTRACT_END;
-
- m_StreamAsmId = uAsmStreamId;
- m_dwStreamModuleId = dwModuleId;
- m_fIsIStream = TRUE;
-
- LOG((LF_LOADER, LL_INFO100, "PEImage: Opening flat stream\n"));
-
- if (!pIStream)
- ThrowHR(COR_E_FILELOAD);
-
- // Just copy bytes.
-
- PEImageLayoutHolder pFlatLayout(PEImageLayout::CreateFromStream(pIStream, this));
-
- if (!resourceFile) {
- if (!pFlatLayout->CheckCORFormat())
- ThrowFormat(COR_E_BADIMAGEFORMAT);
-
- if (!CheckLayoutFormat(pFlatLayout))
- ThrowHR(COR_E_NOTSUPPORTED);
- }
-
- pFlatLayout.SuppressRelease();
- SetLayout(IMAGE_FLAT, pFlatLayout);
-
- RETURN;
-}
-#endif // FEATURE_FUSION
#endif // #ifndef DACCESS_COMPILE
@@ -1407,7 +808,7 @@ void PEImage::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
m_pLayouts[IMAGE_MAPPED]->EnumMemoryRegions(flags);
if (m_pLayouts[IMAGE_LOADED].IsValid() && m_pLayouts[IMAGE_LOADED]!=NULL)
m_pLayouts[IMAGE_LOADED]->EnumMemoryRegions(flags);
- if (m_pLayouts[IMAGE_LOADED_FOR_INTROSPECTION].IsValid() && m_pLayouts[IMAGE_LOADED]!=NULL)
+ if (m_pLayouts[IMAGE_LOADED_FOR_INTROSPECTION].IsValid() && m_pLayouts[IMAGE_LOADED_FOR_INTROSPECTION]!=NULL)
m_pLayouts[IMAGE_LOADED_FOR_INTROSPECTION]->EnumMemoryRegions(flags);
}
@@ -1419,34 +820,20 @@ PEImage::PEImage():
m_bIsTrustedNativeImage(FALSE),
m_bIsNativeImageInstall(FALSE),
m_bPassiveDomainOnly(FALSE),
-#ifndef FEATURE_CORECLR
- m_fReportedToUsageLog(FALSE),
-#endif // !FEATURE_CORECLR
m_bInHashMap(FALSE),
#ifdef METADATATRACKER_DATA
m_pMDTracker(NULL),
#endif // METADATATRACKER_DATA
m_pMDImport(NULL),
m_pNativeMDImport(NULL),
-#ifdef FEATURE_FUSION
- m_StreamAsmId(0),
- m_dwStreamModuleId(0),
- m_fIsIStream(FALSE),
-#endif
m_hFile(INVALID_HANDLE_VALUE),
m_bOwnHandle(true),
m_bSignatureInfoCached(FALSE),
m_hrSignatureInfoStatus(E_UNEXPECTED),
m_dwSignatureInfo(0),
-#ifdef FEATURE_FUSION
- m_pILFingerprint(NULL),
-#endif //FEATURE_FUSION
m_dwPEKind(0),
m_dwMachine(0),
m_fCachedKindAndMachine(FALSE)
-#ifdef FEATURE_APTCA
- , m_fMayBeConditionalAptca(TRUE)
-#endif // FEATURE_APTCA
#ifdef FEATURE_LAZY_COW_PAGES
,m_bAllocatedLazyCOWPages(FALSE)
#endif // FEATURE_LAZY_COW_PAGES
@@ -1526,34 +913,12 @@ PTR_PEImageLayout PEImage::GetLayoutInternal(DWORD imageLayoutMask,DWORD flags)
{
PEImageLayout * pLoadLayout = NULL;
-#ifdef FEATURE_CORECLR
if (m_bIsTrustedNativeImage || IsFile())
{
// For CoreCLR, try to load all files via LoadLibrary first. If LoadLibrary did not work, retry using
// regular mapping - but not for native images.
pLoadLayout = PEImageLayout::Load(this, TRUE /* bNTSafeLoad */, m_bIsTrustedNativeImage /* bThrowOnError */);
}
-#else
- if (m_bIsTrustedNativeImage)
- {
- pLoadLayout = PEImageLayout::Load(this, FALSE);
- }
- else if (m_bIsNativeImageInstall)
- {
- // When ESB (extended secure boot) is enabled, a native image that is being installed can
- // only be loaded flat.
- PEImageLayout* pFlatLayout=PEImageLayout::LoadFlat(GetFileHandle(),this);
- SetLayout(IMAGE_FLAT,pFlatLayout);
- pLoadLayout = new ConvertedImageLayout(pFlatLayout);
- }
-#ifdef FEATURE_READYTORUN
- else if (ReadyToRunInfo::IsReadyToRunEnabled() && IsFile())
- {
- pLoadLayout = PEImageLayout::Load(this, FALSE, FALSE);
- }
-#endif // FEATURE_READYTORUN
-
-#endif // FEATURE_CORECLR
if (pLoadLayout != NULL)
{
@@ -1572,46 +937,9 @@ PTR_PEImageLayout PEImage::GetLayoutInternal(DWORD imageLayoutMask,DWORD flags)
// since LoadLibrary is needed if we are to actually load code.
if (pLayout->HasCorHeader() && pLayout->IsILOnly())
{
-#ifdef FEATURE_CORECLR
// For CoreCLR, IL only images will always be mapped. We also dont bother doing the conversion of PE header on 64bit,
// as done below for the desktop case, as there is no appcompat burden for CoreCLR on 64bit to have that conversion done.
fMarkAnyCpuImageAsLoaded = true;
-#else // !FEATURE_CORECLR
-
-#ifdef _WIN64
- // When attempting to load an assembly using LoadLibrary on x64,
- // the execution will go via the shell-shim that will try to determine
- // if the assembly is ILOnly with Pe32 header (i.e. built as anycpu). If it is,
- // it will convert the in-memory PEheader of the image to be PE32+ (i.e. mark it as 64bit image).
- //
- // Since we are trying to avoid mapping twice for ILOnly images by simply memory mapping them,
- // we should emulate the shell-shim behaviour for 64bit. This will allow inproc-components (e.g. ASP.NET),
- // which check for Pe32+ header, to continue working as expected.
- //
- // If we fail for some reason to change the header, in retail build, we will simply fallback to the double-loading behaviour without
- // any functional problems.
- if (pLayout->Has32BitNTHeaders())
- {
- fMarkAnyCpuImageAsLoaded = pLayout->ConvertILOnlyPE32ToPE64();
- }
- else
- {
- // Before assuming that PE32+ file can be loaded, confirm that
- // it is the expected machine type. This will ensure AMD64 does not load ARM64 or IA64 assemblies (and likewise).
- // If the machine type does not match, the Loader will fail the load at a later point.
- if (pLayout->GetMachine() == IMAGE_FILE_MACHINE_NATIVE)
- {
- fMarkAnyCpuImageAsLoaded = true; // PE32+ (aka native 64bit) binaries dont require any extra processing.
- }
- }
-#else // !_WIN64
- // Why can we not blindly assume that on 32bit OS, image should always be loaded? This is because it is possible to load
- // PE32+ image and map it to the 32bit process in WOW64.
- if (pLayout->Has32BitNTHeaders())
- fMarkAnyCpuImageAsLoaded = true;
-#endif // _WIN64
-
-#endif // FEATURE_CORECLR
}
pLayout.SuppressRelease();
@@ -1636,9 +964,6 @@ PTR_PEImageLayout PEImage::GetLayoutInternal(DWORD imageLayoutMask,DWORD flags)
else
if (imageLayoutMask&PEImageLayout::LAYOUT_FLAT)
{
-#ifdef FEATURE_FUSION
- _ASSERTE(!m_fIsIStream); //images created from streams should always have this one
-#endif
pRetVal=PEImageLayout::LoadFlat(GetFileHandle(),this);
m_pLayouts[IMAGE_FLAT]=pRetVal;
}
@@ -1720,36 +1045,8 @@ void PEImage::Load()
}
else
{
-#ifdef FEATURE_CORECLR
if(m_pLayouts[IMAGE_LOADED]==NULL)
SetLayout(IMAGE_LOADED,PEImageLayout::Load(this,TRUE));
-#else
-
- //as part of Load() call we may initialize loaded image in DllMain
- //so we have to leave the lock and be prepared that when PEImageLayout::Load returns
- //m_pLayouts[IMAGE_LOADED] is set to something else
- lock.Release();
-
- FileHandleHolder pProtect=GetProtectingFileHandle(FALSE);
-
- // if the image is IL-only, try to load it in the safe manner
-
- // using the Internal function here because we are under the writer lock
- PEImageLayoutHolder pLayout=GetLayoutInternal(PEImageLayout::LAYOUT_ANY,0);
- BOOL bPreferSafeLoad=(pLayout && pLayout->IsILOnly());
-
- // Always use safe load during NGen to avoid running unmanaged code in IJW assemblies
- if (IsCompilationProcess())
- bPreferSafeLoad = TRUE;
-
- PEImageLayoutHolder pLoaded(PEImageLayout::Load(this,bPreferSafeLoad));
-
- lock.Acquire();
-
- if(m_pLayouts[IMAGE_LOADED]==NULL)
- SetLayout(IMAGE_LOADED,pLoaded.Extract());
-
-#endif // FEATURE_CORECLR
}
}
@@ -1867,38 +1164,6 @@ LPCWSTR PEImage::GetPathForErrorMessages()
return m_path;
}
-#ifdef FEATURE_FUSION
-PEKIND PEImage::GetFusionProcessorArchitecture()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- DWORD dwPEKind, dwMachine;
- GetPEKindAndMachine(&dwPEKind, &dwMachine);
-
- DWORD dwAssemblyFlags = 0;
-
- IfFailThrow(m_pMDImport->GetAssemblyProps(TokenFromRid(1, mdtAssembly),
- NULL, NULL, NULL,
- NULL, NULL, &dwAssemblyFlags));
-
- PEKIND retval;
- if (FAILED(TranslatePEToArchitectureType(
- (CorPEKind)dwPEKind,
- dwMachine,
- dwAssemblyFlags,
- &retval)))
- {
- return peInvalid;
- }
- return retval;
-}
-#endif //FEATURE_FUSION
HANDLE PEImage::GetFileHandle()
{
@@ -2040,67 +1305,6 @@ BOOL PEImage::IsPtrInImage(PTR_CVOID data)
return FALSE;
}
-#ifdef FEATURE_FUSION
-#ifndef DACCESS_COMPILE
-HRESULT PEImage::GetILFingerprint(IILFingerprint **ppFingerprint)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
- *ppFingerprint = NULL;
- if (m_pILFingerprint == NULL)
- {
- HRESULT hr = S_OK;
- NewHolder<PEFingerprint> pNewFingerprint;
- EX_TRY
- {
- pNewFingerprint = PEFingerprint::CreatePEFingerprint(this);
- hr = S_OK;
- }
- EX_CATCH_HRESULT(hr);
- if (FAILED(hr))
- {
- return hr;
- }
-
- if (InterlockedCompareExchangeT(&m_pILFingerprint, (PEFingerprint*)(pNewFingerprint.GetValue()), NULL) == NULL)
- {
- pNewFingerprint.SuppressRelease(); // Won the race
- }
- }
-
- *ppFingerprint = m_pILFingerprint;
- (*ppFingerprint)->AddRef();
- return S_OK;
-}
-
-// NOTE: Performance critical codepaths should cache the result of this function.
-HRESULT RuntimeGetILFingerprintForPath(LPCWSTR path, IILFingerprint **ppFingerprint)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- HRESULT hr;
- HCORMODULE hCorModule;
- IfFailGo(RuntimeOpenImageInternal(path, &hCorModule, NULL, MDInternalImport_NoCache));
- {
- ReleaseHolder<PEImage> peImage((PEImage*)hCorModule);
- IfFailGo(peImage->GetILFingerprint(ppFingerprint));
- }
- hr = S_OK;
- ErrExit:
- return hr;
-}
-
-#endif //!DACCESS_COMPILE
-#endif //FEATURE_FUSION
#if !defined(DACCESS_COMPILE)
PEImage * PEImage::OpenImage(
@@ -2136,18 +1340,6 @@ PEImage * PEImage::OpenImage(
pPEImage = PEImage::LoadImage(hMod);
}
#endif // !FEATURE_PAL
-#ifdef FEATURE_FUSION
- else if (iidResource == __uuidof(ICLRPrivResourceStream))
- {
- ReleaseHolder<ICLRPrivResourceStream> pIResourceStream;
- IfFailThrow(pIResource->QueryInterface(__uuidof(ICLRPrivResourceStream), (LPVOID*)&pIResourceStream));
- ReleaseHolder<IStream> pStream;
- IfFailThrow(pIResourceStream->GetStream(__uuidof(IStream), (LPVOID*)&pStream));
- UINT64 i64AssemblyId = static_cast<UINT64>(reinterpret_cast<UINT_PTR>(reinterpret_cast<ICLRPrivAssembly*>(pIResource)));
- DWORD dwModuleId = static_cast<DWORD>(i64AssemblyId);
- pPEImage = PEImage::OpenImage(pStream, i64AssemblyId, FALSE, dwModuleId, flags);
- }
-#endif
else
{
ThrowHR(COR_E_BADIMAGEFORMAT);
diff --git a/src/vm/peimage.h b/src/vm/peimage.h
index 12a4dd763e..3245621610 100644
--- a/src/vm/peimage.h
+++ b/src/vm/peimage.h
@@ -60,9 +60,6 @@ typedef DPTR(class PEImage) PTR_PEImage;
class PEImage
{
friend class PEModule;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- friend class CCLRDebugManager;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
public:
// ------------------------------------------------------------
// Public constants
@@ -111,14 +108,6 @@ public:
LPCWSTR pPath,
MDInternalImportFlags flags = MDInternalImport_Default);
-#ifdef FEATURE_FUSION
- static PTR_PEImage OpenImage(
- IStream *pIStream,
- UINT64 uStreamAsmId,
- DWORD dwModuleId,
- BOOL resourceFile,
- MDInternalImportFlags flags = MDInternalImport_Default);
-#endif
// clones the image with new flags (this is pretty much about cached / noncached difference)
void Clone(MDInternalImportFlags flags, PTR_PEImage* ppImage)
@@ -261,13 +250,6 @@ public:
void VerifyIsAssembly();
void VerifyIsNIAssembly();
-#ifndef FEATURE_CORECLR
- BOOL IsReportedToUsageLog();
- void SetReportedToUsageLog();
-#ifndef DACCESS_COMPILE
- HRESULT GetILFingerprint(IILFingerprint **ppFingerprint);
-#endif //!DACCESS_COMPILE
-#endif //!FEATURE_CORECLR
static void GetAll(SArray<PEImage*> &images);
@@ -293,33 +275,9 @@ private:
struct PEImageLocator
{
-#ifdef FEATURE_FUSION
- BOOL m_fIsIStream;
- DWORD m_dwStreamModuleId;
- UINT64 m_StreamAsmId;
-#endif
LPCWSTR m_pPath;
-#ifdef FEATURE_FUSION
- PEImageLocator(LPCWSTR pPath)
- : m_fIsIStream(FALSE), m_pPath(pPath)
- {
- }
-
- PEImageLocator(UINT64 uStreamAsmId, DWORD dwModuleId)
- : m_fIsIStream(TRUE), m_dwStreamModuleId(dwModuleId), m_StreamAsmId(uStreamAsmId)
- {
- }
-
- PEImageLocator(PEImage * pImage)
- : m_fIsIStream(pImage->m_fIsIStream),
- m_dwStreamModuleId(pImage->m_dwStreamModuleId),
- m_StreamAsmId(pImage->m_StreamAsmId),
- m_pPath(pImage->m_path.GetUnicode())
- {
- }
-#else // FEATURE_FUSION
PEImageLocator(LPCWSTR pPath)
: m_pPath(pPath)
{
@@ -329,13 +287,9 @@ private:
: m_pPath(pImage->m_path.GetUnicode())
{
}
-#endif // FEATURE_FUSION
};
static BOOL CompareImage(UPTR image1, UPTR image2);
-#ifdef FEATURE_MIXEDMODE
- static BOOL CompareIJWDataBase(UPTR base, UPTR mapping);
-#endif // FEATURE_MIXEDMODE
void DECLSPEC_NORETURN ThrowFormat(HRESULT hr);
@@ -359,9 +313,6 @@ private:
BOOL m_bIsTrustedNativeImage;
BOOL m_bIsNativeImageInstall;
BOOL m_bPassiveDomainOnly;
-#ifndef FEATURE_CORECLR
- BOOL m_fReportedToUsageLog;
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_LAZY_COW_PAGES
BOOL m_bAllocatedLazyCOWPages;
#endif // FEATURE_LAZY_COW_PAGES
@@ -392,11 +343,6 @@ protected:
IMDInternalImport* m_pMDImport;
IMDInternalImport* m_pNativeMDImport;
-#ifdef FEATURE_FUSION
- UINT64 m_StreamAsmId;
- DWORD m_dwStreamModuleId;
- BOOL m_fIsIStream;
-#endif
private:
@@ -415,73 +361,17 @@ private:
BOOL m_bSignatureInfoCached;
HRESULT m_hrSignatureInfoStatus;
DWORD m_dwSignatureInfo;
-#ifdef FEATURE_MIXEDMODE
- //@TODO:workaround: Remove this when we have one PEImage per mapped image,
- //@TODO:workaround: and move the lock there
- // This is for IJW thunk initialization, as it is no longer guaranteed
- // that the initialization will occur under the loader lock.
- static CrstStatic s_ijwHashLock;
- static PtrHashMap *s_ijwFixupDataHash;
-
-public:
- class IJWFixupData
- {
- private:
- Crst m_lock;
- void *m_base;
- DWORD m_flags;
- PTR_LoaderHeap m_DllThunkHeap;
-
- // the fixup for the next iteration in FixupVTables
- // we use it to make sure that we do not try to fix up the same entry twice
- // if there was a pass that was aborted in the middle
- COUNT_T m_iNextFixup;
- COUNT_T m_iNextMethod;
-
- enum {
- e_FIXED_UP = 0x1
- };
-
- public:
- IJWFixupData(void *pBase);
- ~IJWFixupData();
- void *GetBase() { LIMITED_METHOD_CONTRACT; return m_base; }
- Crst *GetLock() { LIMITED_METHOD_CONTRACT; return &m_lock; }
- BOOL IsFixedUp() { LIMITED_METHOD_CONTRACT; return m_flags & e_FIXED_UP; }
- void SetIsFixedUp() { LIMITED_METHOD_CONTRACT; m_flags |= e_FIXED_UP; }
- PTR_LoaderHeap GetThunkHeap();
- void MarkMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod);
- BOOL IsMethodFixedUp(COUNT_T iFixup, COUNT_T iMethod);
- };
-
- static IJWFixupData *GetIJWData(void *pBase);
- static PTR_LoaderHeap GetDllThunkHeap(void *pBase);
- static void UnloadIJWModule(void *pBase);
-#endif //FEATURE_MIXEDMODE
private:
DWORD m_dwPEKind;
DWORD m_dwMachine;
BOOL m_fCachedKindAndMachine;
-#ifdef FEATURE_APTCA
- BOOL m_fMayBeConditionalAptca;
-#endif // FEATURE_APTCA
-#ifdef FEATURE_FUSION
- PEFingerprint *m_pILFingerprint; // has to be the real type (as opposed to an interface) so we can delete it
-#endif // FEATURE_FUSION
public:
void CachePEKindAndMachine();
void GetPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine);
-#ifdef FEATURE_FUSION
- PEKIND GetFusionProcessorArchitecture();
-#endif
-#ifdef FEATURE_APTCA
- inline BOOL MayBeConditionalAptca();
- inline void SetIsNotConditionalAptca();
-#endif // FEATURE_APTCA
};
FORCEINLINE void PEImageRelease(PEImage *i)
diff --git a/src/vm/peimage.inl b/src/vm/peimage.inl
index 2f4d7d4f31..954d8872f6 100644
--- a/src/vm/peimage.inl
+++ b/src/vm/peimage.inl
@@ -405,47 +405,6 @@ inline const BOOL PEImage::HasStrongNameSignature()
#ifndef DACCESS_COMPILE
-#if !defined(FEATURE_CORECLR)
-inline const HRESULT PEImage::VerifyStrongName(DWORD* verifyOutputFlags)
-{
- WRAPPER_NO_CONTRACT;
- _ASSERTE(verifyOutputFlags);
- if (m_bSignatureInfoCached)
- {
- if (SUCCEEDED(m_hrSignatureInfoStatus))
- *verifyOutputFlags=m_dwSignatureInfo;
- return m_hrSignatureInfoStatus;
- }
-
- BOOL result = FALSE;
-
- PEImageLayoutHolder pLayout(GetLayout(PEImageLayout::LAYOUT_FLAT,0));
- if(pLayout!=NULL)
- {
- result = StrongNameSignatureVerificationFromImage((BYTE *) pLayout->GetBase(), pLayout->GetSize(),
- SN_INFLAG_INSTALL|SN_INFLAG_ALL_ACCESS,
- verifyOutputFlags);
- }
- else
- {
- CONSISTENCY_CHECK(!GetPath().IsEmpty());
- _ASSERTE(IsFileLocked());
- result = StrongNameSignatureVerification(GetPath(),
- SN_INFLAG_INSTALL|SN_INFLAG_ALL_ACCESS|SN_INFLAG_RUNTIME,
- verifyOutputFlags);
- }
-
- HRESULT hr=result?S_OK: StrongNameErrorInfo();
-
- if (SUCCEEDED(hr) || !Exception::IsTransient(hr))
- {
- m_hrSignatureInfoStatus=hr;
- m_dwSignatureInfo=*verifyOutputFlags;
- m_bSignatureInfoCached=TRUE;
- }
- return hr;
-}
-#endif // !FEATURE_CORECLR
#endif // !DACCESS_COMPILE
@@ -579,59 +538,6 @@ inline void PEImage::Init(LPCWSTR pPath)
}
#ifndef DACCESS_COMPILE
-#if !defined(FEATURE_CORECLR)
-/*static*/
-inline PTR_PEImage PEImage::FindByLongPath(LPCWSTR pPath)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(s_hashLock.OwnedByCurrentThread());
- }
- CONTRACTL_END;
-
- PathString sLongPath;
- COUNT_T nLen = WszGetLongPathName(pPath, sLongPath);
-
- // Check for any kind of error other than an insufficient buffer result.
- if (nLen == 0)
- {
- HRESULT hr=HRESULT_FROM_WIN32(GetLastError());
- if(Exception::IsTransient(hr))
- ThrowHR(hr);
- return (PEImage*)INVALIDENTRY;
- }
- return FindByPath(sLongPath.GetUnicode());
-}
-
-/*static*/
-inline PTR_PEImage PEImage::FindByShortPath(LPCWSTR pPath)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(s_hashLock.OwnedByCurrentThread());
- }
- CONTRACTL_END;
-
- PathString sShortPath;
- COUNT_T nLen = WszGetShortPathName(pPath, sShortPath);
-
- // Check for any kind of error other than an insufficient buffer result.
- if (nLen == 0)
- {
- HRESULT hr=HRESULT_FROM_WIN32(GetLastError());
- if(Exception::IsTransient(hr))
- ThrowHR(hr);
- return (PEImage*)INVALIDENTRY;
- }
- return FindByPath(sShortPath.GetUnicode());
-}
-#endif // !FEATURE_CORECLR
/*static*/
inline PTR_PEImage PEImage::FindByPath(LPCWSTR pPath)
@@ -673,13 +579,6 @@ inline PTR_PEImage PEImage::OpenImage(LPCWSTR pPath, MDInternalImportFlags flags
PEImage* found = FindByPath(pPath);
-#if !defined(FEATURE_CORECLR)
- if(found == (PEImage*) INVALIDENTRY && (flags & MDInternalImport_CheckLongPath))
- found=FindByLongPath(pPath);
-
- if(found == (PEImage*) INVALIDENTRY && (flags & MDInternalImport_CheckShortPath))
- found=FindByShortPath(pPath);
-#endif
if (found == (PEImage*) INVALIDENTRY)
{
@@ -716,49 +615,6 @@ inline BOOL PEImage::IsFileLocked()
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_FUSION
-/* static */
-inline PTR_PEImage PEImage::FindById(UINT64 uStreamAsmId, DWORD dwModuleId)
-{
- PEImageLocator locator(uStreamAsmId, dwModuleId);
- CrstHolder holder(&s_hashLock);
- PEImage* found = (PEImage *) s_Images->LookupValue(HashStreamIds(uStreamAsmId, dwModuleId), &locator);
- if (found == (PEImage*) INVALIDENTRY)
- return NULL;
- found->AddRef();
- return dac_cast<PTR_PEImage>(found);
-}
-
-/* static */
-inline PTR_PEImage PEImage::OpenImage(IStream *pIStream, UINT64 uStreamAsmId,
- DWORD dwModuleId, BOOL resourceFile, MDInternalImportFlags flags /* = MDInternalImport_Default */)
-{
- BOOL fUseCache = !((flags & MDInternalImport_NoCache) == MDInternalImport_NoCache);
-
- if (!fUseCache)
- {
- PEImageHolder pImage(new PEImage());
- pImage->Init(pIStream, uStreamAsmId, dwModuleId, resourceFile);
- return dac_cast<PTR_PEImage>(pImage.Extract());
- }
-
-
- DWORD hash = HashStreamIds(uStreamAsmId, dwModuleId);
- PEImageLocator locator(uStreamAsmId,dwModuleId);
- CrstHolder holder(&s_hashLock);
- PEImage* found = (PEImage *) s_Images->LookupValue(hash, &locator);
- if (found != (PEImage*) INVALIDENTRY)
- {
- found->AddRef();
- return dac_cast<PTR_PEImage>(found);
- }
- PEImageHolder pImage(new PEImage());
- pImage->Init(pIStream, uStreamAsmId, dwModuleId, resourceFile);
-
- pImage->AddToHashMap();
- return dac_cast<PTR_PEImage>(pImage.Extract());
-}
-#endif // FEATURE_FUSION
inline void PEImage::AddToHashMap()
{
@@ -796,10 +652,6 @@ inline BOOL PEImage::HasID()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_FUSION
- if (m_fIsIStream)
- return TRUE;
-#endif
return !GetPath().IsEmpty();
}
@@ -815,10 +667,6 @@ inline ULONG PEImage::GetIDHash()
}
CONTRACT_END;
-#ifdef FEATURE_FUSION
- if (m_fIsIStream)
- RETURN HashStreamIds(m_StreamAsmId, m_dwStreamModuleId);
-#endif
#ifdef FEATURE_CASE_SENSITIVE_FILESYSTEM
RETURN m_path.Hash();
@@ -873,33 +721,7 @@ inline void PEImage::GetPEKindAndMachine(DWORD* pdwKind, DWORD* pdwMachine)
*pdwMachine = m_dwMachine;
}
-#ifdef FEATURE_APTCA
-inline BOOL PEImage::MayBeConditionalAptca()
-{
- LIMITED_METHOD_CONTRACT;
- return m_fMayBeConditionalAptca;
-}
-inline void PEImage::SetIsNotConditionalAptca()
-{
- LIMITED_METHOD_CONTRACT;
- m_fMayBeConditionalAptca = FALSE;
-}
-#endif // FEATURE_APTCA
-
-#ifndef FEATURE_CORECLR
-inline BOOL PEImage::IsReportedToUsageLog()
-{
- LIMITED_METHOD_CONTRACT;
- return m_fReportedToUsageLog;
-}
-
-inline void PEImage::SetReportedToUsageLog()
-{
- LIMITED_METHOD_CONTRACT;
- m_fReportedToUsageLog = TRUE;
-}
-#endif // !FEATURE_CORECLR
#ifndef DACCESS_COMPILE
inline void PEImage::AllocateLazyCOWPages()
diff --git a/src/vm/peimagelayout.cpp b/src/vm/peimagelayout.cpp
index 2b50adefb8..fb2ce5760c 100644
--- a/src/vm/peimagelayout.cpp
+++ b/src/vm/peimagelayout.cpp
@@ -17,13 +17,6 @@ PEImageLayout* PEImageLayout::CreateFlat(const void *flat, COUNT_T size,PEImage*
return new RawImageLayout(flat,size,pOwner);
}
-#ifdef FEATURE_FUSION
-PEImageLayout* PEImageLayout::CreateFromStream(IStream* pIStream,PEImage* pOwner)
-{
- STANDARD_VM_CONTRACT;
- return new StreamImageLayout(pIStream,pOwner);
-}
-#endif
PEImageLayout* PEImageLayout::CreateFromHMODULE(HMODULE hModule,PEImage* pOwner, BOOL bTakeOwnership)
{
@@ -258,47 +251,6 @@ void PEImageLayout::ApplyBaseRelocations()
}
#endif // FEATURE_PREJIT
-#ifndef FEATURE_CORECLR
-// Event Tracing for Windows is used to log data for performance and functional testing purposes.
-// The events in this structure are used to measure the time taken by PE image mapping. This is useful to reliably measure the
-// performance of the assembly loader by subtracting the time taken by the possibly I/O-intensive work of PE image mapping.
-struct ETWLoaderMappingPhaseHolder { // Special-purpose holder structure to ensure the LoaderMappingPhaseEnd ETW event is fired when returning from a function.
- StackSString ETWCodeBase;
- DWORD _dwAppDomainId;
- BOOL initialized;
-
- ETWLoaderMappingPhaseHolder(){
- LIMITED_METHOD_CONTRACT;
- _dwAppDomainId = ETWAppDomainIdNotAvailable;
- initialized = FALSE;
- }
-
- void Init(DWORD dwAppDomainId, SString wszCodeBase) {
- _dwAppDomainId = dwAppDomainId;
-
- EX_TRY
- {
- ETWCodeBase.Append(wszCodeBase);
- ETWCodeBase.Normalize(); // Ensures that the later cast to LPCWSTR does not throw.
- }
- EX_CATCH
- {
- ETWCodeBase.Clear();
- }
- EX_END_CATCH(RethrowTransientExceptions)
-
- FireEtwLoaderMappingPhaseStart(_dwAppDomainId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, ETWCodeBase.IsEmpty() ? NULL : (LPCWSTR)ETWCodeBase, NULL, GetClrInstanceId());
-
- initialized = TRUE;
- }
-
- ~ETWLoaderMappingPhaseHolder() {
- if (initialized) {
- FireEtwLoaderMappingPhaseEnd(_dwAppDomainId, ETWLoadContextNotAvailable, ETWFieldUnused, ETWLoaderLoadTypeNotAvailable, ETWCodeBase.IsEmpty() ? NULL : (LPCWSTR)ETWCodeBase, NULL, GetClrInstanceId());
- }
- }
-};
-#endif // FEATURE_CORECLR
RawImageLayout::RawImageLayout(const void *flat, COUNT_T size,PEImage* pOwner)
{
@@ -316,12 +268,6 @@ RawImageLayout::RawImageLayout(const void *flat, COUNT_T size,PEImage* pOwner)
PEFingerprintVerificationHolder verifyHolder(pOwner); // Do not remove: This holder ensures the IL file hasn't changed since the runtime started making assumptions about it.
-#ifndef FEATURE_CORECLR
- ETWLoaderMappingPhaseHolder loaderMappingPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
- loaderMappingPhaseHolder.Init(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, GetPath());
- }
-#endif // FEATURE_CORECLR
if (size)
{
@@ -355,12 +301,6 @@ RawImageLayout::RawImageLayout(const void *mapped, PEImage* pOwner, BOOL bTakeOw
PEFingerprintVerificationHolder verifyHolder(pOwner); // Do not remove: This holder ensures the IL file hasn't changed since the runtime started making assumptions about it.
-#ifndef FEATURE_CORECLR
- ETWLoaderMappingPhaseHolder loaderMappingPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
- loaderMappingPhaseHolder.Init(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, GetPath());
- }
-#endif // FEATURE_CORECLR
if (bTakeOwnership)
{
@@ -392,12 +332,6 @@ ConvertedImageLayout::ConvertedImageLayout(PEImageLayout* source)
PEFingerprintVerificationHolder verifyHolder(source->m_pOwner); // Do not remove: This holder ensures the IL file hasn't changed since the runtime started making assumptions about it.
-#ifndef FEATURE_CORECLR
- ETWLoaderMappingPhaseHolder loaderMappingPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
- loaderMappingPhaseHolder.Init(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, GetPath());
- }
-#endif // FEATURE_CORECLR
if (!source->HasNTHeaders())
EEFileLoadException::Throw(GetPath(), COR_E_BADIMAGEFORMAT);
@@ -447,12 +381,6 @@ MappedImageLayout::MappedImageLayout(HANDLE hFile, PEImage* pOwner)
#ifndef FEATURE_PAL
-#ifndef FEATURE_CORECLR
- ETWLoaderMappingPhaseHolder loaderMappingPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
- loaderMappingPhaseHolder.Init(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, GetPath());
- }
-#endif // FEATURE_CORECLR
// Let OS map file for us
@@ -461,23 +389,12 @@ MappedImageLayout::MappedImageLayout(HANDLE hFile, PEImage* pOwner)
if (m_FileMap == NULL)
{
#ifndef CROSSGEN_COMPILE
-#ifdef FEATURE_CORECLR
// There is no reflection-only load on CoreCLR and so we can always throw an error here.
// It is important on Windows Phone. All assemblies that we load must have SEC_IMAGE set
// so that the OS can perform signature verification.
ThrowLastError();
-#else // FEATURE_CORECLR
-
- // We need to ensure any signature validation errors are caught if Extended Secure Boot (ESB) is on.
- // Also, we have to always throw here during NGen to ensure that the signature validation is never skipped.
- if (GetLastError() != ERROR_BAD_EXE_FORMAT || IsCompilationProcess())
- {
- ThrowLastError();
- }
-
-#endif // FEATURE_CORECLR
#endif // CROSSGEN_COMPILE
return;
@@ -492,34 +409,6 @@ MappedImageLayout::MappedImageLayout(HANDLE hFile, PEImage* pOwner)
}
#endif // _DEBUG
-#ifdef FEATURE_MIXEDMODE
- //
- // For our preliminary loads, we don't want to take the preferred base address. We want to leave
- // that open for a LoadLibrary. So, we first a phony MapViewOfFile to occupy the base
- // address temporarily.
- //
- // Note that this is bad if we are racing another thread which is doing a LoadLibrary. We
- // may want to tweak this logic, but it's pretty difficult to tell MapViewOfFileEx to map
- // a file NOT at its preferred base address. Hopefully the ulimate solution here will be
- // just mapping the file once.
- //
- // There are two distinct cases that this code takes care of:
- //
- // * NGened IL-only assembly: The IL image will get mapped here and LoadLibrary will be called
- // on the NGen image later. If we need to, we can avoid creating the fake view on VISTA in this
- // case. ASLR will map the IL image and NGen image at different addresses for free.
- //
- // * Mixed-mode assembly (either NGened or not): The mixed-mode image will get mapped here and
- // LoadLibrary will be called on the same image again later. Note that ASLR does not help
- // in this case. The fake view has to be created even on VISTA in this case to avoid relocations.
- //
- CLRMapViewHolder temp;
-
- // We don't want to map at the prefered address, so have the temporary view take it.
- temp.Assign(CLRMapViewOfFile(m_FileMap, 0, 0, 0, 0));
- if (temp == NULL)
- ThrowLastError();
-#endif // FEATURE_MIXEDMODE
m_FileView.Assign(CLRMapViewOfFile(m_FileMap, 0, 0, 0, 0));
if (m_FileView == NULL)
ThrowLastError();
@@ -624,12 +513,6 @@ LoadedImageLayout::LoadedImageLayout(PEImage* pOwner, BOOL bNTSafeLoad, BOOL bTh
PEFingerprintVerificationHolder verifyHolder(pOwner); // Do not remove: This holder ensures the IL file hasn't changed since the runtime started making assumptions about it.
-#ifndef FEATURE_CORECLR
- ETWLoaderMappingPhaseHolder loaderMappingPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
- loaderMappingPhaseHolder.Init(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, GetPath());
- }
-#endif // FEATURE_CORECLR
DWORD dwFlags = GetLoadWithAlteredSearchPathFlag();
if (bNTSafeLoad)
@@ -667,12 +550,6 @@ FlatImageLayout::FlatImageLayout(HANDLE hFile, PEImage* pOwner)
PEFingerprintVerificationHolder verifyHolder(pOwner); // Do not remove: This holder ensures the IL file hasn't changed since the runtime started making assumptions about it.
-#ifndef FEATURE_CORECLR
- ETWLoaderMappingPhaseHolder loaderMappingPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
- loaderMappingPhaseHolder.Init(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, GetPath());
- }
-#endif // FEATURE_CORECLR
COUNT_T size = SafeGetFileSize(hFile, NULL);
if (size == 0xffffffff && GetLastError() != NOERROR)
@@ -695,57 +572,6 @@ FlatImageLayout::FlatImageLayout(HANDLE hFile, PEImage* pOwner)
Init(m_FileView, size);
}
-#ifdef FEATURE_FUSION
-StreamImageLayout::StreamImageLayout(IStream* pIStream,PEImage* pOwner)
-{
- CONTRACTL
- {
- CONSTRUCTOR_CHECK;
- STANDARD_VM_CHECK;
- }
- CONTRACTL_END;
-
- m_Layout=LAYOUT_FLAT;
- m_pOwner=pOwner;
-
- PEFingerprintVerificationHolder verifyHolder(pOwner); // Do not remove: This holder ensures the IL file hasn't changed since the runtime started making assumptions about it.
-
-#ifndef FEATURE_CORECLR
- ETWLoaderMappingPhaseHolder loaderMappingPhaseHolder;
- if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, TRACE_LEVEL_INFORMATION, CLR_PRIVATEBINDING_KEYWORD)) {
- loaderMappingPhaseHolder.Init(GetAppDomain() ? GetAppDomain()->GetId().m_dwId : ETWAppDomainIdNotAvailable, GetPath());
- }
-#endif // FEATURE_CORECLR
-
- STATSTG statStg;
- IfFailThrow(pIStream->Stat(&statStg, STATFLAG_NONAME));
- if (statStg.cbSize.u.HighPart > 0)
- ThrowHR(COR_E_FILELOAD);
-
- DWORD cbRead = 0;
-
- // Resources files may have zero length (and would be mapped as FLAT)
- if (statStg.cbSize.u.LowPart) {
- m_FileMap.Assign(WszCreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
- statStg.cbSize.u.LowPart, NULL));
- if (m_FileMap == NULL)
- ThrowWin32(GetLastError());
-
- m_FileView.Assign(CLRMapViewOfFile(m_FileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0));
-
- if (m_FileView == NULL)
- ThrowWin32(GetLastError());
-
- HRESULT hr = pIStream->Read(m_FileView, statStg.cbSize.u.LowPart, &cbRead);
- if (hr == S_FALSE)
- hr = COR_E_FILELOAD;
-
- IfFailThrow(hr);
- }
- TESTHOOKCALL(ImageMapped(GetPath(),m_FileView,IM_FLAT));
- Init(m_FileView,(COUNT_T)cbRead);
-}
-#endif // FEATURE_FUSION
#endif // !DACESS_COMPILE
diff --git a/src/vm/peimagelayout.h b/src/vm/peimagelayout.h
index 68d6315be4..79df992822 100644
--- a/src/vm/peimagelayout.h
+++ b/src/vm/peimagelayout.h
@@ -33,9 +33,6 @@ class PEImageLayout : public PEDecoder
{
VPTR_BASE_CONCRETE_VTABLE_CLASS(PEImageLayout)
friend class PEModule;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- friend class CCLRDebugManager;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
public:
// ------------------------------------------------------------
// Public constants
@@ -176,20 +173,6 @@ public:
};
-#ifdef FEATURE_FUSION
-class StreamImageLayout: public PEImageLayout
-{
- VPTR_VTABLE_CLASS(StreamImageLayout,PEImageLayout)
- VPTR_UNIQUE(0x71)
-protected:
- HandleHolder m_FileMap;
- CLRMapViewHolder m_FileView;
-public:
-#ifndef DACCESS_COMPILE
- StreamImageLayout(IStream* pIStream,PEImage* pOwner);
-#endif
-};
-#endif // FEATURE_FUSION
#endif // PEIMAGELAYOUT_H_
diff --git a/src/vm/precode.cpp b/src/vm/precode.cpp
index 1934eb10b4..9707b2756b 100644
--- a/src/vm/precode.cpp
+++ b/src/vm/precode.cpp
@@ -300,20 +300,54 @@ Precode* Precode::GetPrecodeForTemporaryEntryPoint(TADDR temporaryEntryPoints, i
return PTR_Precode(temporaryEntryPoints + index * oneSize);
}
-SIZE_T Precode::SizeOfTemporaryEntryPoints(PrecodeType t, int count)
+SIZE_T Precode::SizeOfTemporaryEntryPoints(PrecodeType t, bool preallocateJumpStubs, int count)
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;
+
#ifdef HAS_FIXUP_PRECODE_CHUNKS
if (t == PRECODE_FIXUP)
{
- return count * (sizeof(FixupPrecode) + sizeof(PCODE)) + sizeof(PTR_MethodDesc);
+ SIZE_T size = count * sizeof(FixupPrecode) + sizeof(PTR_MethodDesc);
+
+#ifdef FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
+ if (preallocateJumpStubs)
+ {
+ // For dynamic methods, space for jump stubs is allocated along with the precodes as part of the temporary entry
+ // points block. The first jump stub begins immediately after the PTR_MethodDesc.
+ size += count * BACK_TO_BACK_JUMP_ALLOCATE_SIZE;
+ }
+#else // !FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
+ _ASSERTE(!preallocateJumpStubs);
+#endif // FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
+
+ return size;
+ }
+ else
+ {
+ _ASSERTE(!preallocateJumpStubs);
}
#endif
SIZE_T oneSize = SizeOfTemporaryEntryPoint(t);
return count * oneSize;
}
+SIZE_T Precode::SizeOfTemporaryEntryPoints(TADDR temporaryEntryPoints, int count)
+{
+ WRAPPER_NO_CONTRACT;
+ SUPPORTS_DAC;
+
+ PrecodeType precodeType = PTR_Precode(temporaryEntryPoints)->GetType();
+#ifdef FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
+ bool preallocateJumpStubs =
+ precodeType == PRECODE_FIXUP &&
+ ((PTR_MethodDesc)((PTR_FixupPrecode)temporaryEntryPoints)->GetMethodDesc())->IsLCGMethod();
+#else // !FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
+ bool preallocateJumpStubs = false;
+#endif // FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
+ return SizeOfTemporaryEntryPoints(precodeType, preallocateJumpStubs, count);
+}
+
#ifndef DACCESS_COMPILE
Precode* Precode::Allocate(PrecodeType t, MethodDesc* pMD,
@@ -387,14 +421,14 @@ void Precode::Init(PrecodeType t, MethodDesc* pMD, LoaderAllocator *pLoaderAlloc
_ASSERTE(IsValidType(GetType()));
}
-BOOL Precode::SetTargetInterlocked(PCODE target)
+BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub)
{
WRAPPER_NO_CONTRACT;
PCODE expected = GetTarget();
BOOL ret = FALSE;
- if (!IsPointingToPrestub(expected))
+ if (fOnlyRedirectFromPrestub && !IsPointingToPrestub(expected))
return FALSE;
g_IBCLogger.LogMethodPrecodeWriteAccess(GetMethodDesc());
@@ -464,16 +498,28 @@ TADDR Precode::AllocateTemporaryEntryPoints(MethodDescChunk * pChunk,
int count = pChunk->GetCount();
PrecodeType t = PRECODE_STUB;
+ bool preallocateJumpStubs = false;
#ifdef HAS_FIXUP_PRECODE
// Default to faster fixup precode if possible
if (!pFirstMD->RequiresMethodDescCallingConvention(count > 1))
{
t = PRECODE_FIXUP;
+
+#ifdef FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
+ if (pFirstMD->IsLCGMethod())
+ {
+ preallocateJumpStubs = true;
+ }
+#endif // FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS
+ }
+ else
+ {
+ _ASSERTE(!pFirstMD->IsLCGMethod());
}
#endif // HAS_FIXUP_PRECODE
- SIZE_T totalSize = SizeOfTemporaryEntryPoints(t, count);
+ SIZE_T totalSize = SizeOfTemporaryEntryPoints(t, preallocateJumpStubs, count);
#ifdef HAS_COMPACT_ENTRYPOINTS
// Note that these are just best guesses to save memory. If we guessed wrong,
diff --git a/src/vm/precode.h b/src/vm/precode.h
index 430da663d7..7dd4cd22f0 100644
--- a/src/vm/precode.h
+++ b/src/vm/precode.h
@@ -256,7 +256,7 @@ public:
void Init(PrecodeType t, MethodDesc* pMD, LoaderAllocator *pLoaderAllocator);
#ifndef DACCESS_COMPILE
- BOOL SetTargetInterlocked(PCODE target);
+ BOOL SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub = TRUE);
// Reset precode to point to prestub
void Reset();
@@ -311,13 +311,8 @@ public:
static Precode * GetPrecodeForTemporaryEntryPoint(TADDR temporaryEntryPoints, int index);
- static SIZE_T SizeOfTemporaryEntryPoints(PrecodeType t, int count);
- static SIZE_T SizeOfTemporaryEntryPoints(TADDR temporaryEntryPoints, int count)
- {
- WRAPPER_NO_CONTRACT;
- SUPPORTS_DAC;
- return SizeOfTemporaryEntryPoints(PTR_Precode(temporaryEntryPoints)->GetType(), count);
- }
+ static SIZE_T SizeOfTemporaryEntryPoints(PrecodeType t, bool preallocateJumpStubs, int count);
+ static SIZE_T SizeOfTemporaryEntryPoints(TADDR temporaryEntryPoints, int count);
static TADDR AllocateTemporaryEntryPoints(MethodDescChunk* pChunk,
LoaderAllocator *pLoaderAllocator, AllocMemTracker *pamTracker);
diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp
index 9fd7c52446..67639e99b2 100644
--- a/src/vm/prestub.cpp
+++ b/src/vm/prestub.cpp
@@ -17,14 +17,10 @@
#include "eeconfig.h"
#include "dllimport.h"
#include "comdelegate.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "dbginterface.h"
#include "listlock.inl"
#include "stubgen.h"
#include "eventtrace.h"
-#include "constrainedexecutionregion.h"
#include "array.h"
#include "compile.h"
#include "ecall.h"
@@ -52,6 +48,10 @@
#include "perfmap.h"
#endif
+#ifdef FEATURE_TIERED_COMPILATION
+#include "callcounter.h"
+#endif
+
#ifndef DACCESS_COMPILE
EXTERN_C void STDCALL ThePreStub();
@@ -271,10 +271,12 @@ PCODE MethodDesc::MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, CORJIT_FLAGS fla
PCODE pCode = NULL;
ULONG sizeOfCode = 0;
+#if defined(FEATURE_INTERPRETER) || defined(FEATURE_TIERED_COMPILATION)
+ BOOL fStable = TRUE; // True iff the new code address (to be stored in pCode), is a stable entry point.
+#endif
#ifdef FEATURE_INTERPRETER
PCODE pPreviousInterpStub = NULL;
BOOL fInterpreted = FALSE;
- BOOL fStable = TRUE; // True iff the new code address (to be stored in pCode), is a stable entry point.
#endif
#ifdef FEATURE_MULTICOREJIT
@@ -283,6 +285,20 @@ PCODE MethodDesc::MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, CORJIT_FLAGS fla
bool fBackgroundThread = flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MCJIT_BACKGROUND);
#endif
+ // If this is the first stage of a tiered compilation progression, use tier0, otherwise
+ // use default compilation options
+#ifdef FEATURE_TIERED_COMPILATION
+ if (!IsEligibleForTieredCompilation())
+ {
+ fStable = TRUE;
+ }
+ else
+ {
+ fStable = FALSE;
+ flags.Add(CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_TIER0));
+ }
+#endif
+
{
// Enter the global lock which protects the list of all functions being JITd
ListLockHolder pJitLock (GetDomain()->GetJitLock());
@@ -685,8 +701,10 @@ void CreateInstantiatingILStubTargetSig(MethodDesc *pBaseMD,
SigPointer pReturn = msig.GetReturnProps();
pReturn.ConvertToInternalExactlyOne(msig.GetModule(), &typeContext, stubSigBuilder, FALSE);
+#ifndef _TARGET_X86_
// The hidden context parameter
stubSigBuilder->AppendElementType(ELEMENT_TYPE_I);
+#endif // !_TARGET_X86_
// Copy rest of the arguments
msig.NextArg();
@@ -696,6 +714,10 @@ void CreateInstantiatingILStubTargetSig(MethodDesc *pBaseMD,
pArgs.ConvertToInternalExactlyOne(msig.GetModule(), &typeContext, stubSigBuilder);
}
+#ifdef _TARGET_X86_
+ // The hidden context parameter
+ stubSigBuilder->AppendElementType(ELEMENT_TYPE_I);
+#endif // _TARGET_X86_
}
Stub * CreateUnboxingILStubForSharedGenericValueTypeMethods(MethodDesc* pTargetMD)
@@ -732,14 +754,22 @@ Stub * CreateUnboxingILStubForSharedGenericValueTypeMethods(MethodDesc* pTargetM
// 2. Emit the method body
mdToken tokPinningHelper = pCode->GetToken(MscorlibBinder::GetField(FIELD__PINNING_HELPER__M_DATA));
-
+
// 2.1 Push the thisptr
// We need to skip over the MethodTable*
- // The trick below will do that.
+ // The trick below will do that.
pCode->EmitLoadThis();
pCode->EmitLDFLDA(tokPinningHelper);
- // 2.2 Push the hidden context param
+#if defined(_TARGET_X86_)
+ // 2.2 Push the rest of the arguments for x86
+ for (unsigned i = 0; i < msig.NumFixedArgs();i++)
+ {
+ pCode->EmitLDARG(i);
+ }
+#endif
+
+ // 2.3 Push the hidden context param
// The context is going to be captured from the thisptr
pCode->EmitLoadThis();
pCode->EmitLDFLDA(tokPinningHelper);
@@ -747,16 +777,18 @@ Stub * CreateUnboxingILStubForSharedGenericValueTypeMethods(MethodDesc* pTargetM
pCode->EmitSUB();
pCode->EmitLDIND_I();
- // 2.3 Push the rest of the arguments
+#if !defined(_TARGET_X86_)
+ // 2.4 Push the rest of the arguments for not x86
for (unsigned i = 0; i < msig.NumFixedArgs();i++)
{
pCode->EmitLDARG(i);
}
+#endif
- // 2.4 Push the target address
+ // 2.5 Push the target address
pCode->EmitLDC((TADDR)pTargetMD->GetMultiCallableAddrOfCode(CORINFO_ACCESS_ANY));
- // 2.5 Do the calli
+ // 2.6 Do the calli
pCode->EmitCALLI(TOKEN_ILSTUB_TARGET_SIG, msig.NumFixedArgs() + 1, msig.IsReturnTypeVoid() ? 0 : 1);
pCode->EmitRET();
@@ -829,39 +861,31 @@ Stub * CreateInstantiatingILStub(MethodDesc* pTargetMD, void* pHiddenArg)
CreateInstantiatingILStubTargetSig(pTargetMD, typeContext, &stubSigBuilder);
// 2. Emit the method body
- unsigned int numArgs = msig.NumFixedArgs();
if (msig.HasThis())
{
// 2.1 Push the thisptr
pCode->EmitLoadThis();
- numArgs++;
}
#if defined(_TARGET_X86_)
- if (numArgs < NUM_ARGUMENT_REGISTERS)
+ // 2.2 Push the rest of the arguments for x86
+ for (unsigned i = 0; i < msig.NumFixedArgs();i++)
{
-#endif // _TARGET_X86_
- // 2.2 Push the hidden context param
- // InstantiatingStub
- pCode->EmitLDC((TADDR)pHiddenArg);
-#if defined(_TARGET_X86_)
+ pCode->EmitLDARG(i);
}
#endif // _TARGET_X86_
- // 2.3 Push the rest of the arguments
+ // 2.3 Push the hidden context param
+ // InstantiatingStub
+ pCode->EmitLDC((TADDR)pHiddenArg);
+
+#if !defined(_TARGET_X86_)
+ // 2.4 Push the rest of the arguments for not x86
for (unsigned i = 0; i < msig.NumFixedArgs();i++)
{
pCode->EmitLDARG(i);
}
-
-#if defined(_TARGET_X86_)
- if (numArgs >= NUM_ARGUMENT_REGISTERS)
- {
- // 2.4 Push the hidden context param
- // InstantiatingStub
- pCode->EmitLDC((TADDR)pHiddenArg);
- }
-#endif // _TARGET_X86_
+#endif // !_TARGET_X86_
// 2.5 Push the target address
pCode->EmitLDC((TADDR)pTargetMD->GetMultiCallableAddrOfCode(CORINFO_ACCESS_ANY));
@@ -893,7 +917,7 @@ Stub * CreateInstantiatingILStub(MethodDesc* pTargetMD, void* pHiddenArg)
}
#endif
-/* Make a stub that for a value class method that expects a BOXed this poitner */
+/* Make a stub that for a value class method that expects a BOXed this pointer */
Stub * MakeUnboxingStubWorker(MethodDesc *pMD)
{
CONTRACT(Stub*)
@@ -1233,12 +1257,6 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT)
RETURN GetStableEntryPoint();
}
-#if defined(FEATURE_PREJIT) && defined(FEATURE_CER)
- // If this method is the root of a CER call graph and we've recorded this fact in the ngen image then we're in the prestub in
- // order to trip any runtime level preparation needed for this graph (P/Invoke stub generation/library binding, generic
- // dictionary prepopulation etc.).
- GetModule()->RestoreCer(this);
-#endif // FEATURE_PREJIT && FEATURE_CER
#ifdef FEATURE_COMINTEROP
/************************** INTEROP *************************/
@@ -1285,6 +1303,22 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT)
if (!IsPointingToPrestub())
#endif
{
+ // If we are counting calls for tiered compilation, leave the prestub
+ // in place so that we can continue intercepting method invocations.
+ // When the TieredCompilationManager has received enough call notifications
+ // for this method only then do we back-patch it.
+#ifdef FEATURE_TIERED_COMPILATION
+ PCODE pNativeCode = GetNativeCode();
+ if (pNativeCode && IsEligibleForTieredCompilation())
+ {
+ CallCounter * pCallCounter = GetAppDomain()->GetCallCounter();
+ BOOL doBackPatch = pCallCounter->OnMethodCalled(this);
+ if (!doBackPatch)
+ {
+ return pNativeCode;
+ }
+ }
+#endif
LOG((LF_CLASSLOADER, LL_INFO10000,
" In PreStubWorker, method already jitted, backpatching call point\n"));
@@ -1301,13 +1335,6 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT)
{
pStub = MakeUnboxingStubWorker(this);
}
-#ifdef FEATURE_REMOTING
- else if (pMT->IsInterface() && !IsStatic() && !IsFCall())
- {
- pCode = CRemotingServices::GetDispatchInterfaceHelper(this);
- GetOrCreatePrecode();
- }
-#endif // FEATURE_REMOTING
#if defined(FEATURE_SHARE_GENERIC_CODE)
else if (IsInstantiatingStub())
{
@@ -1317,8 +1344,8 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT)
else if (IsIL() || IsNoMetadata())
{
// remember if we need to backpatch the MethodTable slot
- BOOL fBackpatch = !fRemotingIntercepted
- && !IsEnCMethod();
+ BOOL fBackpatch = !fRemotingIntercepted
+ && IsNativeCodeStableAfterInit();
#ifdef FEATURE_PREJIT
//
@@ -1576,24 +1603,6 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT)
// stub that performs declarative checks prior to calling the real stub.
// record if security needs to intercept this call (also depends on whether we plan to use stubs for declarative security)
-#if !defined( HAS_REMOTING_PRECODE) && defined (FEATURE_REMOTING)
- /************************** REMOTING *************************/
-
- // check for MarshalByRef scenarios ... we need to intercept
- // Non-virtual calls on MarshalByRef types
- if (fRemotingIntercepted)
- {
- // let us setup a remoting stub to intercept all the calls
- Stub *pRemotingStub = CRemotingServices::GetStubForNonVirtualMethod(this,
- (pStub != NULL) ? (LPVOID)pStub->GetEntryPoint() : (LPVOID)pCode, pStub);
-
- if (pRemotingStub != NULL)
- {
- pStub = pRemotingStub;
- pCode = NULL;
- }
- }
-#endif // HAS_REMOTING_PRECODE
_ASSERTE((pStub != NULL) ^ (pCode != NULL));
@@ -1610,6 +1619,22 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT)
MemoryBarrier();
#endif
+ // If we are counting calls for tiered compilation, leave the prestub
+ // in place so that we can continue intercepting method invocations.
+ // When the TieredCompilationManager has received enough call notifications
+ // for this method only then do we back-patch it.
+#ifdef FEATURE_TIERED_COMPILATION
+ if (pCode && IsEligibleForTieredCompilation())
+ {
+ CallCounter * pCallCounter = GetAppDomain()->GetCallCounter();
+ BOOL doBackPatch = pCallCounter->OnMethodCalled(this);
+ if (!doBackPatch)
+ {
+ return pCode;
+ }
+ }
+#endif
+
if (pCode != NULL)
{
if (HasPrecode())
@@ -1626,6 +1651,7 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT)
else
#endif // FEATURE_INTERPRETER
{
+ ReJitPublishMethodHolder publishWorker(this, pCode);
SetStableEntryPointInterlocked(pCode);
}
}
@@ -1738,7 +1764,7 @@ static PCODE PatchNonVirtualExternalMethod(MethodDesc * pMD, PCODE pCode, PTR_CO
//
#ifdef HAS_FIXUP_PRECODE
if (pMD->HasPrecode() && pMD->GetPrecode()->GetType() == PRECODE_FIXUP
- && !pMD->IsEnCMethod()
+ && pMD->IsNativeCodeStableAfterInit()
#ifndef HAS_REMOTING_PRECODE
&& !pMD->IsRemotingInterceptedViaPrestub()
#endif
diff --git a/src/vm/profattach.cpp b/src/vm/profattach.cpp
index 5b10e8f10e..ed83201bf9 100644
--- a/src/vm/profattach.cpp
+++ b/src/vm/profattach.cpp
@@ -711,23 +711,6 @@ HRESULT ProfilingAPIAttachDetach::Initialize()
INDEBUG(VerifyMessageStructureLayout());
- // If the CLR is being memory- or sync-hosted, then attach is not supported
- // (see comments above)
- if (CLRMemoryHosted() || CLRSyncHosted())
- {
- LOG((
- LF_CORPROF,
- LL_INFO10,
- "**PROF: Process is running with a host that implements custom memory or "
- "synchronization management. So it will not be possible to attach a "
- "profiler to this process.\n"));
-
- // NOTE: Intentionally not logging this to the event log, as it would be
- // obnoxious to see such a message every time SQL started up
-
- return S_FALSE;
- }
-
InitializeAttachThreadingMode();
if (s_attachThreadingMode == kOnDemand)
diff --git a/src/vm/profilinghelper.cpp b/src/vm/profilinghelper.cpp
index 1dd60b47e1..b1fb228acb 100644
--- a/src/vm/profilinghelper.cpp
+++ b/src/vm/profilinghelper.cpp
@@ -138,9 +138,6 @@
#include "profilinghelper.inl"
#include "eemessagebox.h"
-#if defined(FEATURE_PROFAPI_EVENT_LOGGING) && !defined(FEATURE_CORECLR)
-#include <eventmsg.h>
-#endif // FEATURE_PROFAPI_EVENT_LOGGING) && !FEATURE_CORECLR
#ifdef FEATURE_PROFAPI_ATTACH_DETACH
#include "profattach.h"
@@ -398,30 +395,8 @@ void ProfilingAPIUtility::LogProfEventVA(
AppendSupplementaryInformation(iStringResourceID, &messageToLog);
-#if defined(FEATURE_CORECLR)
// CoreCLR on Windows ouputs debug strings for diagnostic messages.
WszOutputDebugString(messageToLog);
-#else
- // Get the user SID for the current process, so it can be provided to the event
- // logging API, which will then fill out the "User" field in the event log entry. If
- // this fails, that's not fatal. We can just pass NULL for the PSID, and the "User"
- // field will be left blank.
- PSID psid = NULL;
- HRESULT hr = GetCurrentProcessUserSid(&psid);
- if (FAILED(hr))
- {
- // No biggie. Just pass in a NULL psid, and the User field will be empty
- _ASSERTE(psid == NULL);
- }
-
- // On desktop CLR builds, the profiling API uses the event log for end-user-friendly
- // diagnostic messages.
- ReportEventCLR(wEventType, // wType
- 0, // wCategory
- COR_Profiler, // dwEventID
- psid, // lpUserSid
- &messageToLog); // uh duh
-#endif // FEATURE_CORECLR
#endif // FEATURE_PROFAPI_EVENT_LOGGING
}
@@ -732,11 +707,7 @@ HRESULT ProfilingAPIUtility::AttemptLoadProfilerForStartup()
// Find out if profiling is enabled
DWORD fProfEnabled = 0;
-#ifdef FEATURE_CORECLR
fProfEnabled = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CORECLR_ENABLE_PROFILING);
-#else //FEATURE_CORECLR
- fProfEnabled = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_COR_ENABLE_PROFILING);
-#endif //FEATURE_CORECLR
// If profiling is not enabled, return.
if (fProfEnabled == 0)
@@ -751,7 +722,6 @@ HRESULT ProfilingAPIUtility::AttemptLoadProfilerForStartup()
NewArrayHolder<WCHAR> wszClsid(NULL);
NewArrayHolder<WCHAR> wszProfilerDLL(NULL);
-#ifdef FEATURE_CORECLR
IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CORECLR_PROFILER, &wszClsid));
#if defined(_TARGET_X86_)
@@ -763,19 +733,6 @@ HRESULT ProfilingAPIUtility::AttemptLoadProfilerForStartup()
{
IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_CORECLR_PROFILER_PATH, &wszProfilerDLL));
}
-#else // FEATURE_CORECLR
- IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_COR_PROFILER, &wszClsid));
-
-#if defined(_TARGET_X86_)
- IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_COR_PROFILER_PATH_32, &wszProfilerDLL));
-#elif defined(_TARGET_AMD64_)
- IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_COR_PROFILER_PATH_64, &wszProfilerDLL));
-#endif
- if(wszProfilerDLL == NULL)
- {
- IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_COR_PROFILER_PATH, &wszProfilerDLL));
- }
-#endif // FEATURE_CORECLR
// If the environment variable doesn't exist, profiling is not enabled.
if (wszClsid == NULL)
diff --git a/src/vm/proftoeeinterfaceimpl.cpp b/src/vm/proftoeeinterfaceimpl.cpp
index da66dbde44..cfd99adf27 100644
--- a/src/vm/proftoeeinterfaceimpl.cpp
+++ b/src/vm/proftoeeinterfaceimpl.cpp
@@ -1022,7 +1022,7 @@ ClassID SafeGetClassIDFromObject(Object * pObj)
//---------------------------------------------------------------------------------------
//
-// Callback of type walk_fn used by GCHeapUtilities::DiagWalkObject. Keeps a count of each
+// Callback of type walk_fn used by IGCHeap::DiagWalkObject. Keeps a count of each
// object reference found.
//
// Arguments:
@@ -1033,7 +1033,7 @@ ClassID SafeGetClassIDFromObject(Object * pObj)
// Always returns TRUE to object walker so it walks the entire object
//
-BOOL CountContainedObjectRef(Object * pBO, void * context)
+bool CountContainedObjectRef(Object * pBO, void * context)
{
LIMITED_METHOD_CONTRACT;
// Increase the count
@@ -1044,7 +1044,7 @@ BOOL CountContainedObjectRef(Object * pBO, void * context)
//---------------------------------------------------------------------------------------
//
-// Callback of type walk_fn used by GCHeapUtilities::DiagWalkObject. Stores each object reference
+// Callback of type walk_fn used by IGCHeap::DiagWalkObject. Stores each object reference
// encountered into an array.
//
// Arguments:
@@ -1058,7 +1058,7 @@ BOOL CountContainedObjectRef(Object * pBO, void * context)
// Always returns TRUE to object walker so it walks the entire object
//
-BOOL SaveContainedObjectRef(Object * pBO, void * context)
+bool SaveContainedObjectRef(Object * pBO, void * context)
{
LIMITED_METHOD_CONTRACT;
// Assign the value
@@ -1096,7 +1096,7 @@ BOOL SaveContainedObjectRef(Object * pBO, void * context)
//
extern bool s_forcedGCInProgress;
-BOOL HeapWalkHelper(Object * pBO, void * pvContext)
+bool HeapWalkHelper(Object * pBO, void * pvContext)
{
CONTRACTL
{
@@ -1221,7 +1221,7 @@ BOOL HeapWalkHelper(Object * pBO, void * pvContext)
// Currently always returns TRUE
//
-BOOL AllocByClassHelper(Object * pBO, void * pv)
+bool AllocByClassHelper(Object * pBO, void * pv)
{
CONTRACTL
{
@@ -3557,90 +3557,7 @@ HRESULT ProfToEEInterfaceImpl::GetContextStaticAddress(ClassID classId,
fieldToken,
contextId));
-#ifdef FEATURE_REMOTING
-
- //
- // Check for NULL parameters
- //
- if ((classId == NULL) || (contextId == NULL) || (ppAddress == NULL))
- {
- return E_INVALIDARG;
- }
-
- if (GetThread() == NULL)
- {
- return CORPROF_E_NOT_MANAGED_THREAD;
- }
-
- if (GetAppDomain() == NULL)
- {
- return E_FAIL;
- }
-
- TypeHandle typeHandle = TypeHandle::FromPtr((void *)classId);
-
- //
- // If this class is not fully restored, that is all the information we can get at this time.
- //
- if (!typeHandle.IsRestored())
- {
- return CORPROF_E_DATAINCOMPLETE;
- }
-
- //
- // Get the field descriptor object
- //
- FieldDesc *pFieldDesc = typeHandle.GetModule()->LookupFieldDef(fieldToken);
-
- if (pFieldDesc == NULL)
- {
- return E_INVALIDARG;
- }
-
- //
- // Verify this field is of the right type
- //
- if(!pFieldDesc->IsStatic() ||
- !pFieldDesc->IsContextStatic() ||
- pFieldDesc->IsRVA() ||
- pFieldDesc->IsThreadStatic())
- {
- return E_INVALIDARG;
- }
-
- // It may seem redundant to try to retrieve the same method table from GetEnclosingMethodTable, but classId
- // leads to the instantiated method table while GetEnclosingMethodTable returns the uninstantiated one.
- MethodTable *pMethodTable = pFieldDesc->GetEnclosingMethodTable();
-
- //
- // Check that the data is available
- //
- if (!IsClassOfMethodTableInited(pMethodTable, GetAppDomain()))
- {
- return CORPROF_E_DATAINCOMPLETE;
- }
-
- //
- // Get the context
- //
- Context *pContext = reinterpret_cast<Context *>(contextId);
-
- //
- // Store the result and return
- //
- PTR_VOID pAddress = pContext->GetStaticFieldAddrNoCreate(pFieldDesc);
- if (pAddress == NULL)
- {
- return E_INVALIDARG;
- }
-
- *ppAddress = pAddress;
-
- return S_OK;
-
-#else // FEATURE_REMOTING
return E_NOTIMPL;
-#endif // FEATURE_REMOTING
}
/*
@@ -4727,16 +4644,10 @@ HRESULT ProfToEEInterfaceImpl::SetILInstrumentedCodeMap(FunctionID functionId,
if (!pMethodDesc ->IsRestored())
return CORPROF_E_DATAINCOMPLETE;
-#ifdef FEATURE_CORECLR
if (g_pDebugInterface == NULL)
{
return CORPROF_E_DEBUGGING_DISABLED;
}
-#else
- // g_pDebugInterface is initialized on startup on desktop CLR, regardless of whether a debugger
- // or profiler is loaded. So it should always be available.
- _ASSERTE(g_pDebugInterface != NULL);
-#endif // FEATURE_CORECLR
COR_IL_MAP * rgNewILMapEntries = new (nothrow) COR_IL_MAP[cILMapEntries];
@@ -5181,16 +5092,10 @@ HRESULT ProfToEEInterfaceImpl::GetILToNativeMapping2(FunctionID functionId,
return E_INVALIDARG;
}
-#ifdef FEATURE_CORECLR
if (g_pDebugInterface == NULL)
{
return CORPROF_E_DEBUGGING_DISABLED;
}
-#else
- // g_pDebugInterface is initialized on startup on desktop CLR, regardless of whether a debugger
- // or profiler is loaded. So it should always be available.
- _ASSERTE(g_pDebugInterface != NULL);
-#endif // FEATURE_CORECLR
return (g_pDebugInterface->GetILToNativeMapping(pMD, cMap, pcMap, map));
#else
@@ -8681,11 +8586,7 @@ HRESULT ProfToEEInterfaceImpl::GetRuntimeInformation(USHORT * pClrInstanceId,
if (pRuntimeType != NULL)
{
-#ifdef FEATURE_CORECLR
*pRuntimeType = COR_PRF_CORE_CLR;
-#else // FEATURE_CORECLR
- *pRuntimeType = COR_PRF_DESKTOP_CLR;
-#endif // FEATURE_CORECLR
}
if (pMajorVersion != NULL)
@@ -9413,8 +9314,7 @@ HRESULT ProfToEEInterfaceImpl::EnumNgenModuleMethodsInliningThisMethod(
return CORPROF_E_DATAINCOMPLETE;
}
- PersistentInlineTrackingMap *inliningMap = inlinersModule->GetNgenInlineTrackingMap();
- if (inliningMap == NULL)
+ if (!inlinersModule->HasInlineTrackingMap())
{
return CORPROF_E_DATAINCOMPLETE;
}
@@ -9427,14 +9327,14 @@ HRESULT ProfToEEInterfaceImpl::EnumNgenModuleMethodsInliningThisMethod(
EX_TRY
{
// Trying to use static buffer
- COUNT_T methodsAvailable = inliningMap->GetInliners(inlineeOwnerModule, inlineeMethodId, staticBufferSize, staticBuffer, incompleteData);
+ COUNT_T methodsAvailable = inlinersModule->GetInliners(inlineeOwnerModule, inlineeMethodId, staticBufferSize, staticBuffer, incompleteData);
// If static buffer is not enough, allocate an array.
if (methodsAvailable > staticBufferSize)
{
DWORD dynamicBufferSize = methodsAvailable;
dynamicBuffer = methodsBuffer = new MethodInModule[dynamicBufferSize];
- methodsAvailable = inliningMap->GetInliners(inlineeOwnerModule, inlineeMethodId, dynamicBufferSize, dynamicBuffer, incompleteData);
+ methodsAvailable = inlinersModule->GetInliners(inlineeOwnerModule, inlineeMethodId, dynamicBufferSize, dynamicBuffer, incompleteData);
if (methodsAvailable > dynamicBufferSize)
{
_ASSERTE(!"Ngen image inlining info changed, this shouldn't be possible.");
diff --git a/src/vm/qcall.h b/src/vm/qcall.h
index f6708470ce..ccf4c06997 100644
--- a/src/vm/qcall.h
+++ b/src/vm/qcall.h
@@ -118,7 +118,11 @@
// }
+#ifdef PLATFORM_UNIX
+#define QCALLTYPE __cdecl
+#else // PLATFORM_UNIX
#define QCALLTYPE __stdcall
+#endif // !PLATFORM_UNIX
#define BEGIN_QCALL \
INSTALL_MANAGED_EXCEPTION_DISPATCHER \
diff --git a/src/vm/rcwwalker.cpp b/src/vm/rcwwalker.cpp
index 0b875360fd..7ecf2b68c5 100644
--- a/src/vm/rcwwalker.cpp
+++ b/src/vm/rcwwalker.cpp
@@ -129,7 +129,7 @@ STDMETHODIMP CLRServicesImpl::GarbageCollect(DWORD dwFlags)
{
GCX_COOP_THREAD_EXISTS(GET_THREAD());
if (dwFlags & GC_FOR_APPX_SUSPEND) {
- GCHeapUtilities::GetGCHeap()->GarbageCollect(2, TRUE, collection_blocking | collection_optimized);
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(2, true, collection_blocking | collection_optimized);
}
else
GCHeapUtilities::GetGCHeap()->GarbageCollect();
diff --git a/src/vm/readytoruninfo.cpp b/src/vm/readytoruninfo.cpp
index a0e44ceaf3..b85cf9a9c3 100644
--- a/src/vm/readytoruninfo.cpp
+++ b/src/vm/readytoruninfo.cpp
@@ -53,7 +53,7 @@ MethodDesc * ReadyToRunInfo::GetMethodDescForEntryPoint(PCODE entryPoint)
}
CONTRACTL_END;
-#ifdef _TARGET_AMD64_
+#if defined(_TARGET_AMD64_) || (defined(_TARGET_X86_) && defined(FEATURE_PAL))
// A normal method entry point is always 8 byte aligned, but a funclet can start at an odd address.
// Since PtrHashMap can't handle odd pointers, check for this case and return NULL.
if ((entryPoint & 0x1) != 0)
@@ -491,13 +491,8 @@ PTR_ReadyToRunInfo ReadyToRunInfo::Initialize(Module * pModule, AllocMemTracker
if (!pLayout->IsNativeMachineFormat())
{
-#ifdef FEATURE_CORECLR
// For CoreCLR, be strict about disallowing machine mismatches.
COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
-#else
- DoLog("Ready to Run disabled - mismatched architecture");
- return NULL;
-#endif
}
#ifdef FEATURE_NATIVE_IMAGE_GENERATION
@@ -538,11 +533,11 @@ PTR_ReadyToRunInfo ReadyToRunInfo::Initialize(Module * pModule, AllocMemTracker
DoLog("Ready to Run initialized successfully");
- return new (pMemory) ReadyToRunInfo(pModule, pLayout, pHeader);
+ return new (pMemory) ReadyToRunInfo(pModule, pLayout, pHeader, pamTracker);
}
-ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYTORUN_HEADER * pHeader)
- : m_pModule(pModule), m_pLayout(pLayout), m_pHeader(pHeader), m_Crst(CrstLeafLock)
+ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYTORUN_HEADER * pHeader, AllocMemTracker *pamTracker)
+ : m_pModule(pModule), m_pLayout(pLayout), m_pHeader(pHeader), m_Crst(CrstLeafLock), m_pPersistentInlineTrackingMap(NULL)
{
STANDARD_VM_CONTRACT;
@@ -594,6 +589,30 @@ ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYT
LockOwner lock = {&m_Crst, IsOwnerOfCrst};
m_entryPointToMethodDescMap.Init(TRUE, &lock);
}
+
+ // For format version 2.1 and later, there is an optional inlining table
+ if (IsImageVersionAtLeast(2, 1))
+ {
+ IMAGE_DATA_DIRECTORY * pInlineTrackingInfoDir = FindSection(READYTORUN_SECTION_INLINING_INFO);
+ if (pInlineTrackingInfoDir != NULL)
+ {
+ const BYTE* pInlineTrackingMapData = (const BYTE*)GetImage()->GetDirectoryData(pInlineTrackingInfoDir);
+ PersistentInlineTrackingMapR2R::TryLoad(pModule, pInlineTrackingMapData, pInlineTrackingInfoDir->Size,
+ pamTracker, &m_pPersistentInlineTrackingMap);
+ }
+ }
+ // Fpr format version 2.2 and later, there is an optional profile-data section
+ if (IsImageVersionAtLeast(2, 2))
+ {
+ IMAGE_DATA_DIRECTORY * pProfileDataInfoDir = FindSection(READYTORUN_SECTION_PROFILEDATA_INFO);
+ if (pProfileDataInfoDir != NULL)
+ {
+ CORCOMPILE_METHOD_PROFILE_LIST * pMethodProfileList;
+ pMethodProfileList = (CORCOMPILE_METHOD_PROFILE_LIST *)GetImage()->GetDirectoryData(pProfileDataInfoDir);
+
+ pModule->SetMethodProfileList(pMethodProfileList);
+ }
+ }
}
static bool SigMatchesMethodDesc(MethodDesc* pMD, SigPointer &sig, Module * pModule)
@@ -859,4 +878,12 @@ DWORD ReadyToRunInfo::GetFieldBaseOffset(MethodTable * pMT)
return (DWORD)sizeof(Object) + dwCumulativeInstanceFieldPos - dwOffsetBias;
}
+BOOL ReadyToRunInfo::IsImageVersionAtLeast(int majorVersion, int minorVersion)
+{
+ LIMITED_METHOD_CONTRACT;
+ return (m_pHeader->MajorVersion == majorVersion && m_pHeader->MinorVersion >= minorVersion) ||
+ (m_pHeader->MajorVersion > majorVersion);
+
+}
+
#endif // DACCESS_COMPILE
diff --git a/src/vm/readytoruninfo.h b/src/vm/readytoruninfo.h
index 28efe01e8d..2266e9c119 100644
--- a/src/vm/readytoruninfo.h
+++ b/src/vm/readytoruninfo.h
@@ -13,6 +13,7 @@
#define _READYTORUNINFO_H_
#include "nativeformatreader.h"
+#include "inlinetracking.h"
typedef DPTR(struct READYTORUN_SECTION) PTR_READYTORUN_SECTION;
@@ -40,7 +41,9 @@ class ReadyToRunInfo
Crst m_Crst;
PtrHashMap m_entryPointToMethodDescMap;
- ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYTORUN_HEADER * pHeader);
+ PTR_PersistentInlineTrackingMapR2R m_pPersistentInlineTrackingMap;
+
+ ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYTORUN_HEADER * pHeader, AllocMemTracker *pamTracker);
public:
static BOOL IsReadyToRunEnabled();
@@ -118,10 +121,16 @@ public:
static DWORD GetFieldBaseOffset(MethodTable * pMT);
+ PTR_PersistentInlineTrackingMapR2R GetInlineTrackingMap()
+ {
+ return m_pPersistentInlineTrackingMap;
+ }
+
private:
BOOL GetTypeNameFromToken(IMDInternalImport * pImport, mdToken mdType, LPCUTF8 * ppszName, LPCUTF8 * ppszNameSpace);
BOOL GetEnclosingToken(IMDInternalImport * pImport, mdToken mdType, mdToken * pEnclosingToken);
BOOL CompareTypeNameOfTokens(mdToken mdToken1, IMDInternalImport * pImport1, mdToken mdToken2, IMDInternalImport * pImport2);
+ BOOL IsImageVersionAtLeast(int majorVersion, int minorVersion);
};
class DynamicHelpers
diff --git a/src/vm/reflectclasswriter.h b/src/vm/reflectclasswriter.h
index 486a25a78f..afd33c067b 100644
--- a/src/vm/reflectclasswriter.h
+++ b/src/vm/reflectclasswriter.h
@@ -91,11 +91,6 @@ public:
m_pOnDiskEmitter = pOnDiskEmitter;
}
-#ifndef FEATURE_CORECLR
- //HRESULT EnsureCeeFileGenCreated(DWORD corhFlags = COMIMAGE_FLAGS_ILONLY, DWORD peFlags = ICEE_CREATE_FILE_PURE_IL);
- HRESULT EnsureCeeFileGenCreated(DWORD corhFlags, DWORD peFlags);
- HRESULT DestroyCeeFileGen();
-#endif
~RefClassWriter();
};
diff --git a/src/vm/reflectioninvocation.cpp b/src/vm/reflectioninvocation.cpp
index 4a2be35581..626e872255 100644
--- a/src/vm/reflectioninvocation.cpp
+++ b/src/vm/reflectioninvocation.cpp
@@ -13,16 +13,12 @@
#include "typehandle.h"
#include "field.h"
#include "security.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "eeconfig.h"
#include "vars.hpp"
#include "jitinterface.h"
#include "contractimpl.h"
#include "virtualcallstub.h"
#include "comdelegate.h"
-#include "constrainedexecutionregion.h"
#include "generics.h"
#ifdef FEATURE_COMINTEROP
@@ -234,13 +230,6 @@ FCIMPL5(void, ReflectionInvocation::PerformVisibilityCheckOnField, FieldDesc *pF
}
CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- // Security checks are expensive as they involve stack walking. Avoid them if we can.
- // In immersive we don't allow private reflection to framework code. So we need to perform
- // the access check even if all the domains on the stack are fully trusted.
- if (Security::AllDomainsOnStackFullyTrusted() && !AppX::IsAppXProcess())
- return;
-#endif
REFLECTCLASSBASEREF refDeclaringType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pDeclaringTypeUNSAFE);
@@ -262,9 +251,6 @@ FCIMPL5(void, ReflectionInvocation::PerformVisibilityCheckOnField, FieldDesc *pF
bool targetRemoted = FALSE;
-#ifndef FEATURE_CORECLR
- targetRemoted = targetObj != NULL && InvokeUtil::IsTargetRemoted(pFieldDesc, targetObj->GetMethodTable());
-#endif //FEATURE_CORECLR
RefSecContext sCtx(InvokeUtil::GetInvocationAccessCheckType(targetRemoted));
@@ -484,21 +470,17 @@ FCIMPL1(Object*, RuntimeTypeHandle::Allocate, ReflectClassBaseObject* pTypeUNSAF
}//Allocate
FCIMPLEND
-FCIMPL6(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refThisUNSAFE,
+FCIMPL4(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refThisUNSAFE,
CLR_BOOL publicOnly,
- CLR_BOOL securityOff,
CLR_BOOL* pbCanBeCached,
- MethodDesc** pConstructor,
- CLR_BOOL *pbNeedSecurityCheck) {
+ MethodDesc** pConstructor) {
CONTRACTL {
FCALL_CHECK;
PRECONDITION(CheckPointer(refThisUNSAFE));
PRECONDITION(CheckPointer(pbCanBeCached));
- PRECONDITION(CheckPointer(pbNeedSecurityCheck));
PRECONDITION(CheckPointer(pConstructor));
PRECONDITION(*pbCanBeCached == false);
PRECONDITION(*pConstructor == NULL);
- PRECONDITION(*pbNeedSecurityCheck == true);
}
CONTRACTL_END;
@@ -522,7 +504,6 @@ FCIMPL6(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refT
HELPER_METHOD_FRAME_BEGIN_RET_2(rv, refThis);
MethodTable* pVMT;
- bool bNeedAccessCheck;
// Get the type information associated with refThis
if (thisTH.IsNull() || thisTH.IsTypeDesc())
@@ -532,8 +513,6 @@ FCIMPL6(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refT
pVMT->EnsureInstanceActive();
- bNeedAccessCheck = false;
-
#ifdef FEATURE_COMINTEROP
// If this is __ComObject then create the underlying COM object.
if (IsComObjectClass(refThis->GetType())) {
@@ -591,44 +570,16 @@ FCIMPL6(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refT
COMPlusThrow(kMissingMethodException,W("Arg_NoDefCTor"));
}
- if (!securityOff)
- {
-#ifndef FEATURE_CORECLR
- // Security checks are expensive as they involve stack walking. Avoid them if we can.
- // In immersive we don't allow private reflection to framework code. So we need to perform
- // the access check even if all the domains on the stack are fully trusted.
- if (Security::AllDomainsOnStackFullyTrusted() && !AppX::IsAppXProcess())
- {
- bNeedAccessCheck = false;
- }
- else
-#endif //FEATURE_CORECLR
- {
- // Public critical types cannot be accessed by transparent callers
- bNeedAccessCheck = !pVMT->IsExternallyVisible() || Security::TypeRequiresTransparencyCheck(pVMT);
- }
-
- if (bNeedAccessCheck)
- {
- RefSecContext sCtx(InvokeUtil::GetInvocationAccessCheckType());
- InvokeUtil::CanAccessClass(&sCtx, pVMT, TRUE);
- }
- }
-
- // Handle the nullable<T> special case
+ // Handle the nullable<T> special case
if (Nullable::IsNullableType(thisTH)) {
rv = Nullable::BoxedNullableNull(thisTH);
}
else
rv = pVMT->Allocate();
- // Since no security checks will be performed on cached value types without default ctors,
- // we cannot cache those types that require access checks.
- // In fact, we don't even need to set pbNeedSecurityCheck to false here.
- if (!pVMT->Collectible() && !bNeedAccessCheck)
+ if (!pVMT->Collectible())
{
*pbCanBeCached = true;
- *pbNeedSecurityCheck = false;
}
}
else // !pVMT->HasDefaultConstructor()
@@ -641,49 +592,11 @@ FCIMPL6(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refT
if (!IsMdPublic(attr) && publicOnly)
COMPlusThrow(kMissingMethodException,W("Arg_NoDefCTor"));
- if (!securityOff)
- {
- // If the type is critical or the constructor we're using is critical, we need to ensure that
- // the caller is allowed to invoke it.
- bool needsTransparencyCheck = Security::TypeRequiresTransparencyCheck(pVMT) ||
- (Security::IsMethodCritical(pMeth) && !Security::IsMethodSafeCritical(pMeth));
-
- // We also need to do a check if the method or type is not public
- bool needsVisibilityCheck = !IsMdPublic(attr) || !pVMT->IsExternallyVisible();
-
- // If the visiblity, transparency, or legacy LinkDemands on the type or constructor dictate that
- // we need to check the caller, then do that now.
- bNeedAccessCheck = needsTransparencyCheck ||
- needsVisibilityCheck ||
- pMeth->RequiresLinktimeCheck();
-
- if (bNeedAccessCheck)
- {
- // this security context will be used in cast checking as well
- RefSecContext sCtx(InvokeUtil::GetInvocationAccessCheckType());
- InvokeUtil::CanAccessMethod(pMeth, pVMT, NULL, &sCtx);
- }
- }
-
// We've got the class, lets allocate it and call the constructor
OBJECTREF o;
bool remoting = false;
-#ifdef FEATURE_REMOTING
- if (pVMT->IsTransparentProxy())
- COMPlusThrow(kMissingMethodException,W("NotSupported_Constructor"));
-
- if (pVMT->MayRequireManagedActivation())
- {
- o = CRemotingServices::CreateProxyOrObject(pVMT);
- remoting = true;
- }
- else
- o = AllocateObject(pVMT);
-
-#else
o = AllocateObject(pVMT);
-#endif
GCPROTECT_BEGIN(o);
MethodDescCallSite ctor(pMeth, &o);
@@ -701,12 +614,13 @@ FCIMPL6(Object*, RuntimeTypeHandle::CreateInstance, ReflectClassBaseObject* refT
rv = o;
GCPROTECT_END();
- // No need to set these if they cannot be cached
- if (!remoting && !pVMT->Collectible())
+ // No need to set these if they cannot be cached. In particular, if the type is a value type with a custom
+ // parameterless constructor, don't allow caching and have subsequent calls come back here to allocate an object and
+ // call the constructor.
+ if (!remoting && !pVMT->Collectible() && !pVMT->IsValueType())
{
*pbCanBeCached = true;
*pConstructor = pMeth;
- *pbNeedSecurityCheck = bNeedAccessCheck;
}
}
}
@@ -752,10 +666,6 @@ FCIMPL2(Object*, RuntimeTypeHandle::CreateInstanceForGenericType, ReflectClassBa
MethodDescCallSite ctor(pMeth);
// We've got the class, lets allocate it and call the constructor
-#ifdef FEATURE_REMOTING
- _ASSERTE(!pVMT->IsTransparentProxy());
- _ASSERTE(!pVMT->MayRequireManagedActivation());
-#endif
// Nullables don't take this path, if they do we need special logic to make an instance
_ASSERTE(!Nullable::IsNullableType(instantiatedType));
@@ -871,109 +781,6 @@ FCIMPL1(DWORD, ReflectionInvocation::GetSpecialSecurityFlags, ReflectMethodObjec
}
FCIMPLEND
-#ifndef FEATURE_CORECLR
-
-// Can not inline this function.
-#ifdef _MSC_VER
-__declspec(noinline)
-#endif
-void PerformSecurityCheckHelper(Object *targetUnsafe, MethodDesc *pMeth, MethodTable* pParentMT, DWORD dwFlags)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
-
- PRECONDITION(CheckPointer(pMeth));
- }
- CONTRACTL_END;
-
- OBJECTREF target (targetUnsafe);
- GCPROTECT_BEGIN (target);
- FrameWithCookie<DebuggerSecurityCodeMarkFrame> __dbgSecFrame;
-
- bool targetRemoted = false;
-
-#ifndef FEATURE_CORECLR
- targetRemoted = target != NULL && InvokeUtil::IsTargetRemoted(pMeth, target->GetMethodTable());
-#endif //FEATURE_CORECLR
-
- RefSecContext sCtx(InvokeUtil::GetInvocationAccessCheckType(targetRemoted));
-
- MethodTable* pInstanceMT = NULL;
- if (target != NULL) {
- if (!target->GetTypeHandle().IsTypeDesc())
- pInstanceMT = target->GetTypeHandle().AsMethodTable();
- }
-
-#ifdef FEATURE_CORECLR
- if (dwFlags & (INVOCATION_FLAGS_RISKY_METHOD|INVOCATION_FLAGS_IS_DELEGATE_CTOR))
- {
- // On CoreCLR we assert that "dangerous" methods (see IsDangerousMethods) can only
- // be reflection-invoked by platform code (C or SC).
-
- // Also, for delegates, in desktop we used to demand unmanaged
- // code permission for this since it's hard to validate the target address.
- // Here we just restrict access to Critical code.
- MethodDesc *pCallerMD = sCtx.GetCallerMethod();
-
- if (pCallerMD && Security::IsMethodTransparent(pCallerMD))
- {
- ThrowMethodAccessException(pCallerMD, pMeth, FALSE, IDS_E_TRANSPARENT_REFLECTION);
- }
- }
-
- if (dwFlags & (INVOCATION_FLAGS_NEED_SECURITY|INVOCATION_FLAGS_CONSTRUCTOR_INVOKE))
-#endif
- {
-
- if (dwFlags & INVOCATION_FLAGS_CONSTRUCTOR_INVOKE)
- InvokeUtil::CanAccessMethod(pMeth,
- pParentMT,
- pInstanceMT,
- &sCtx,
- TRUE /*fCriticalToFullDemand*/);
- else
- InvokeUtil::CanAccessMethod(pMeth,
- pParentMT,
- pInstanceMT,
- &sCtx,
- TRUE /*fCriticalToFullDemand*/,
- (dwFlags & INVOCATION_FLAGS_IS_CTOR) != 0 /*checkSkipVer*/);
- }
-
- __dbgSecFrame.Pop();
- GCPROTECT_END();
-}
-
-FCIMPL4(void, ReflectionInvocation::PerformSecurityCheck, Object *target, MethodDesc *pMeth, ReflectClassBaseObject *pParentUNSAFE, DWORD dwFlags) {
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(pMeth));
- }
- CONTRACTL_END;
-
-#ifndef FEATURE_CORECLR
- // Security checks are expensive as they involve stack walking. Avoid them if we can.
- // In immersive we don't allow private reflection to framework code. So we need to perform
- // the access check even if all the domains on the stack are fully trusted.
- if (Security::AllDomainsOnStackFullyTrusted() && !AppX::IsAppXProcess())
- return;
-#endif
-
- REFLECTCLASSBASEREF refParent = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pParentUNSAFE);
-
- HELPER_METHOD_FRAME_BEGIN_1(refParent);
- //CAUTION: PerformSecurityCheckHelper could trigger GC!
-
- TypeHandle parent = refParent != NULL ? refParent->GetType() : TypeHandle();
- PerformSecurityCheckHelper(target,pMeth,parent.GetMethodTable(),dwFlags);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-#endif // FEATURE_CORECLR
/****************************************************************************/
/* boxed Nullable<T> are represented as a boxed T, so there is no unboxed
@@ -1207,9 +1014,7 @@ void DECLSPEC_NORETURN ThrowInvokeMethodException(MethodDesc * pMethod, OBJECTRE
GCPROTECT_BEGIN(targetException);
#if defined(_DEBUG) && !defined(FEATURE_PAL)
-#ifdef FEATURE_CORECLR
if (IsWatsonEnabled())
-#endif // FEATURE_CORECLR
{
if (!CLRException::IsPreallocatedExceptionObject(targetException))
{
@@ -1258,9 +1063,7 @@ void DECLSPEC_NORETURN ThrowInvokeMethodException(MethodDesc * pMethod, OBJECTRE
OBJECTREF except = InvokeUtil::CreateTargetExcept(&targetException);
#ifndef FEATURE_PAL
-#ifdef FEATURE_CORECLR
if (IsWatsonEnabled())
-#endif // FEATURE_CORECLR
{
struct
{
@@ -1380,14 +1183,6 @@ FCIMPL4(Object*, RuntimeMethodHandle::InvokeMethod,
MethodTable * pMT = ownerType.AsMethodTable();
-#ifdef FEATURE_REMOTING
- if (pMT->MayRequireManagedActivation())
- {
- gc.retVal = CRemotingServices::CreateProxyOrObject(pMT);
- fForceActivationForRemoting = TRUE;
- }
- else
-#endif
{
if (pMT != g_pStringClass)
gc.retVal = pMT->Allocate();
@@ -1395,12 +1190,6 @@ FCIMPL4(Object*, RuntimeMethodHandle::InvokeMethod,
}
else
{
-#ifdef FEATURE_REMOTING
- if (gc.target != NULL)
- {
- fForceActivationForRemoting = gc.target->IsTransparentProxy();
- }
-#endif
}
{
@@ -1731,95 +1520,6 @@ Done:
}
FCIMPLEND
-#ifdef FEATURE_SERIALIZATION
-FCIMPL4(void, RuntimeMethodHandle::SerializationInvoke,
- ReflectMethodObject *pMethodUNSAFE, Object* targetUNSAFE, Object* serializationInfoUNSAFE, struct StreamingContextData * pContext) {
- FCALL_CONTRACT;
-
- struct _gc
- {
- OBJECTREF target;
- OBJECTREF serializationInfo;
- REFLECTMETHODREF refMethod;
- } gc;
-
- gc.target = (OBJECTREF) targetUNSAFE;
- gc.serializationInfo = (OBJECTREF) serializationInfoUNSAFE;
- gc.refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
-
- MethodDesc* pMethod = pMethodUNSAFE->GetMethod();
-
- Assembly *pAssem = pMethod->GetAssembly();
-
- if (pAssem->IsIntrospectionOnly())
- FCThrowExVoid(kInvalidOperationException, IDS_EE_CODEEXECUTION_IN_INTROSPECTIVE_ASSEMBLY, NULL, NULL, NULL);
-
- if (pAssem->IsDynamic() && !pAssem->HasRunAccess())
- FCThrowResVoid(kNotSupportedException, W("NotSupported_DynamicAssemblyNoRunAccess"));
-
- HELPER_METHOD_FRAME_BEGIN_PROTECT(gc);
-
- {
- ARG_SLOT newArgs[3];
-
- // Nullable<T> does not support the ISerializable constructor, so we should never get here.
- _ASSERTE(!Nullable::IsNullableType(gc.target->GetMethodTable()));
-
- if (pMethod == MscorlibBinder::GetMethod(METHOD__WINDOWS_IDENTITY__SERIALIZATION_CTOR))
- {
- // WindowsIdentity.ctor takes only one argument
- MethodDescCallSite method(pMethod, &gsig_IM_SerInfo_RetVoid, &gc.target);
-
- // NO GC AFTER THIS POINT
- // Copy "this" pointer: only unbox if type is value type and method is not unboxing stub
- if (pMethod->GetMethodTable()->IsValueType() && !pMethod->IsUnboxingStub())
- newArgs[0] = PtrToArgSlot(gc.target->UnBox());
- else
- newArgs[0] = ObjToArgSlot(gc.target);
-
- newArgs[1] = ObjToArgSlot(gc.serializationInfo);
-
- TryCallMethod(&method, newArgs);
- }
- else
- {
- //
- // Use hardcoded sig for performance
- //
- MethodDescCallSite method(pMethod, &gsig_IM_SerInfo_StrContext_RetVoid, &gc.target);
-
- // NO GC AFTER THIS POINT
- // Copy "this" pointer: only unbox if type is value type and method is not unboxing stub
- if (pMethod->GetMethodTable()->IsValueType() && !pMethod->IsUnboxingStub())
- newArgs[0] = PtrToArgSlot(gc.target->UnBox());
- else
- newArgs[0] = ObjToArgSlot(gc.target);
-
- newArgs[1] = ObjToArgSlot(gc.serializationInfo);
-
-#ifdef _WIN64
- //
- // on win64 the struct does not fit in an ARG_SLOT, so we pass it by reference
- //
- static_assert_no_msg(sizeof(*pContext) > sizeof(ARG_SLOT));
- newArgs[2] = PtrToArgSlot(pContext);
-#else // _WIN64
- //
- // on x86 the struct fits in an ARG_SLOT, so we pass it by value
- //
- static_assert_no_msg(sizeof(*pContext) == sizeof(ARG_SLOT));
- newArgs[2] = *(ARG_SLOT*)pContext;
-#endif // _WIN64
-
- TryCallMethod(&method, newArgs);
- }
- }
-
- HELPER_METHOD_FRAME_END_POLL();
-}
-FCIMPLEND
-#endif // FEATURE_SERIALIZATION
-
struct SkipStruct {
StackCrawlMark* pStackMark;
MethodDesc* pMeth;
@@ -1961,9 +1661,6 @@ FCIMPL4(Object*, RuntimeFieldHandle::GetValueDirect, ReflectFieldObject *pFieldU
bool targetRemoted = false;
-#ifndef FEATURE_CORECLR
- targetRemoted = !targetType.IsNull() && InvokeUtil::IsTargetRemoted(pField, targetType.AsMethodTable());
-#endif //FEATURE_CORECLR
RefSecContext sCtx(InvokeUtil::GetInvocationAccessCheckType(targetRemoted));
@@ -2144,9 +1841,6 @@ FCIMPL5(void, RuntimeFieldHandle::SetValueDirect, ReflectFieldObject *pFieldUNSA
// security and consistency checks
bool targetRemoted = false;
-#ifndef FEATURE_CORECLR
- targetRemoted = targetType.IsNull() && InvokeUtil::IsTargetRemoted(pField, targetType.AsMethodTable());
-#endif //FEATURE_CORECLR
RefSecContext sCtx(InvokeUtil::GetInvocationAccessCheckType(targetRemoted));
@@ -2344,10 +2038,8 @@ FCIMPL1(void, ReflectionInvocation::RunClassConstructor, ReflectClassBaseObject
HELPER_METHOD_FRAME_BEGIN_1(refType);
// We perform the access check only on CoreCLR for backward compatibility.
-#ifdef FEATURE_CORECLR
RefSecContext sCtx(InvokeUtil::GetInvocationAccessCheckType());
InvokeUtil::CanAccessClass(&sCtx, pMT);
-#endif //FEATURE_CORECLR
pMT->CheckRestore();
pMT->EnsureInstanceActive();
@@ -2389,116 +2081,6 @@ FCIMPL1(void, ReflectionInvocation::RunModuleConstructor, ReflectModuleBaseObjec
}
FCIMPLEND
-#ifndef FEATURE_CORECLR
-// This method triggers a given method to be jitted
-FCIMPL3(void, ReflectionInvocation::PrepareMethod, ReflectMethodObject* pMethodUNSAFE, TypeHandle *pInstantiation, UINT32 cInstantiation)
-{
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(pMethodUNSAFE, NULL_OK));
- PRECONDITION(CheckPointer(pInstantiation, NULL_OK));
- }
- CONTRACTL_END;
-
- REFLECTMETHODREF refMethod = (REFLECTMETHODREF)ObjectToOBJECTREF(pMethodUNSAFE);
-
- if (refMethod == NULL)
- FCThrowArgumentVoidEx(kArgumentException, NULL, W("InvalidOperation_HandleIsNotInitialized"));
-
- MethodDesc *pMD = refMethod->GetMethod();
-
- HELPER_METHOD_FRAME_BEGIN_1(refMethod);
-
- if (pMD->IsAbstract())
- COMPlusThrowArgumentNull(W("method"), W("Argument_CannotPrepareAbstract"));
-
- pMD->CheckRestore();
-
- MethodTable * pExactMT = pMD->GetMethodTable();
- if (pInstantiation != NULL)
- {
- // We were handed an instantiation, check that the method expects it and the right number of types has been provided (the
- // caller supplies one array containing the class instantiation immediately followed by the method instantiation).
- if (cInstantiation != (pMD->GetNumGenericMethodArgs() + pMD->GetNumGenericClassArgs()))
- COMPlusThrow(kArgumentException, W("Argument_InvalidGenericInstantiation"));
-
- // We need to find the actual class and/or method instantiations, even though we've been passed them. This is an issue of
- // lifetime -- the instantiation passed in will go away at some point whereas preparation of the method has the potential to
- // persist a copy of the instantiation pointer. By finding the actual instantiation we get a stable pointer whose lifetime
- // is at least as long as the data generated by preparation.
-
- // Check we've got a reasonable looking instantiation.
- if (!Generics::CheckInstantiation(Instantiation(pInstantiation, cInstantiation)))
- COMPlusThrow(kArgumentException, W("Argument_InvalidGenericInstantiation"));
- for (ULONG i = 0; i < cInstantiation; i++)
- if (pInstantiation[i].ContainsGenericVariables())
- COMPlusThrow(kArgumentException, W("Argument_InvalidGenericInstantiation"));
-
- // Load the exact type of the method if it needs to be instantiated (because it's a generic type definition, e.g. C<T>, or a
- // shared type instantiation, e.g. C<Object>).
- if (pExactMT->IsGenericTypeDefinition() || pExactMT->IsSharedByGenericInstantiations())
- {
- TypeHandle thExactType = ClassLoader::LoadGenericInstantiationThrowing(pMD->GetModule(),
- pMD->GetMethodTable()->GetCl(),
- Instantiation(pInstantiation, pMD->GetNumGenericClassArgs()));
- pExactMT = thExactType.AsMethodTable();
- }
-
- // As for the class we might need to find a method desc with an exact instantiation if the one we have is too vague.
- // Note: IsGenericMethodDefinition implies ContainsGenericVariables so there's no need to check it separately.
- if (pMD->IsSharedByGenericInstantiations() || pMD->ContainsGenericVariables())
- pMD = MethodDesc::FindOrCreateAssociatedMethodDesc(pMD,
- pExactMT,
- FALSE,
- Instantiation(&pInstantiation[pMD->GetNumGenericClassArgs()], pMD->GetNumGenericMethodArgs()),
- FALSE);
- }
- else
- {
- // No instantiation provided, the method better not be expecting one.
-
- // Methods that are generic definitions (e.g. C.Foo<U>) and those that are shared (e.g. C<Object>.Foo, C.Foo<Object>) need
- // extra instantiation data.
- // Note: IsGenericMethodDefinition implies ContainsGenericVariables so there's no need to check it separately.
- if (pMD->IsSharedByGenericInstantiations() || pMD->ContainsGenericVariables())
- COMPlusThrow(kArgumentException, W("Argument_InvalidGenericInstantiation"));
-
- // The rest of the cases (non-generics related methods, instantiating stubs, methods instantiated over non-shared types
- // etc.) should be able to provide their instantiation for us as necessary.
- }
-
- // Go prepare the method at the specified instantiation.
- PrepareMethodDesc(pMD, pExactMT->GetInstantiation(), pMD->GetMethodInstantiation());
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-// This method triggers a given delegate to be prepared. This involves preparing the
-// delegate's Invoke method and preparing the target of that Invoke. In the case of
-// a multi-cast delegate, we rely on the fact that each individual component was prepared
-// prior to the Combine. If our event sinks perform the Combine, this is always true.
-// If the client calls Combine himself, he is responsible for his own preparation.
-FCIMPL1(void, ReflectionInvocation::PrepareDelegate, Object* delegateUNSAFE)
-{
- CONTRACTL {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(delegateUNSAFE, NULL_OK));
- }
- CONTRACTL_END;
-
- if (delegateUNSAFE == NULL)
- return;
-
- OBJECTREF delegate = ObjectToOBJECTREF(delegateUNSAFE);
- HELPER_METHOD_FRAME_BEGIN_1(delegate);
-
- PrepareDelegateHelper(&delegate, FALSE);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
FCIMPL1(void, ReflectionInvocation::PrepareContractedDelegate, Object * delegateUNSAFE)
{
@@ -2508,103 +2090,9 @@ FCIMPL1(void, ReflectionInvocation::PrepareContractedDelegate, Object * delegate
}
CONTRACTL_END;
-#ifdef FEATURE_CER
- if (delegateUNSAFE == NULL)
- return;
-
- OBJECTREF delegate = ObjectToOBJECTREF(delegateUNSAFE);
- HELPER_METHOD_FRAME_BEGIN_1(delegate);
-
- PrepareDelegateHelper(&delegate, TRUE);
-
- HELPER_METHOD_FRAME_END();
-#endif // FEATURE_CER
}
FCIMPLEND
-#ifdef FEATURE_CER
-void ReflectionInvocation::PrepareDelegateHelper(OBJECTREF *pDelegate, BOOL onlyContractedMethod)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pDelegate));
- PRECONDITION(CheckPointer(OBJECTREFToObject(*pDelegate)));
- }
- CONTRACTL_END;
-
- // Make sure the delegate subsystem itself is prepared.
- // Force the immediate creation of any global stubs required. This is platform specific.
-#ifdef _TARGET_X86_
- {
- GCX_PREEMP();
- COMDelegate::TheDelegateInvokeStub();
- }
-#endif
-
- MethodDesc *pMDTarget = COMDelegate::GetMethodDesc(*pDelegate);
- MethodDesc *pMDInvoke = COMDelegate::FindDelegateInvokeMethod((*pDelegate)->GetMethodTable());
-
- // If someone does give us a multicast delegate, then both MDs will be the same -- they
- // will both be the Delegate's Invoke member. Normally, pMDTarget points at the method
- // the delegate is wrapping, of course.
- if (pMDTarget == pMDInvoke)
- {
- pMDTarget->CheckRestore();
-
- // The invoke method itself is never generic, but the delegate class itself might be.
- PrepareMethodDesc(pMDInvoke,
- pMDInvoke->GetExactClassInstantiation((*pDelegate)->GetTypeHandle()),
- Instantiation(),
- onlyContractedMethod);
- }
- else
- {
- pMDTarget->CheckRestore();
- pMDInvoke->CheckRestore();
-
- // Prepare the eventual target method first.
-
- // Load the exact type of the method if it needs to be instantiated (because it's a generic type definition, e.g. C<T>, or a
- // shared type instantiation, e.g. C<Object>).
- MethodTable *pExactMT = pMDTarget->GetMethodTable();
- if (pExactMT->IsGenericTypeDefinition() || pExactMT->IsSharedByGenericInstantiations())
- {
- OBJECTREF targetObj = COMDelegate::GetTargetObject(*pDelegate);
-
-#ifdef FEATURE_REMOTING
- // We prepare the delegate for the sole purpose of reliability (CER).
- // If the target is a transparent proxy, we cannot guarantee reliability anyway.
- if (CRemotingServices::IsTransparentProxy(OBJECTREFToObject(targetObj)))
- return;
-#endif //FEATURE_REMOTING
-
- pExactMT = targetObj->GetMethodTable();
- }
-
-
- // For delegates with generic target methods it must be the case that we are passed an instantiating stub -- there's no
- // other way the necessary method instantiation information can be passed to us.
- // The target MD may be shared by generic instantiations as long as it does not require extra instantiation arguments.
- // We have the actual target object so we can extract the exact class instantiation from it.
- _ASSERTE(!pMDTarget->RequiresInstArg() &&
- !pMDTarget->ContainsGenericVariables());
-
- PrepareMethodDesc(pMDTarget,
- pMDTarget->GetExactClassInstantiation(TypeHandle(pExactMT)),
- pMDTarget->GetMethodInstantiation(),
- onlyContractedMethod);
-
- // Now prepare the delegate invoke method.
- // The invoke method itself is never generic, but the delegate class itself might be.
- PrepareMethodDesc(pMDInvoke,
- pMDInvoke->GetExactClassInstantiation((*pDelegate)->GetTypeHandle()),
- Instantiation(),
- onlyContractedMethod);
- }
-}
-#endif // FEATURE_CER
FCIMPL0(void, ReflectionInvocation::ProbeForSufficientStack)
{
@@ -2851,18 +2339,6 @@ FCIMPL3(void, ReflectionInvocation::ExecuteCodeWithGuaranteedCleanup, Object* co
if (gc.backoutDelegate == NULL)
COMPlusThrowArgumentNull(W("backoutCode"));
-#ifdef FEATURE_CER
- if (!IsCompilationProcess())
- {
- // Delegates are prepared as part of the ngen process, so only prepare the backout
- // delegate for non-ngen processes.
- PrepareDelegateHelper((OBJECTREF *)&gc.backoutDelegate, FALSE);
-
- // Make sure the managed backout code helper function has been prepared before we
- // attempt to run the backout code.
- PrepareMethodDesc(g_pExecuteBackoutCodeHelperMethod, Instantiation(), Instantiation(), FALSE, TRUE);
- }
-#endif // FEATURE_CER
ExecuteCodeWithGuaranteedCleanupHelper(&gc);
@@ -3255,77 +2731,22 @@ FCIMPL1(Object*, ReflectionSerialization::GetUninitializedObject, ReflectClassBa
if (pMT->IsAbstract()) {
COMPlusThrow(kMemberAccessException,W("Acc_CreateAbst"));
}
- else if (pMT->ContainsGenericVariables()) {
+
+ if (pMT->ContainsGenericVariables()) {
COMPlusThrow(kMemberAccessException,W("Acc_CreateGeneric"));
}
- // Never allow allocation of generics actually instantiated over __Canon
- else if (pMT->IsSharedByGenericInstantiations()) {
- COMPlusThrow(kNotSupportedException, W("NotSupported_Type"));
- }
-
- // Never allow the allocation of an unitialized ContextBoundObject derived type, these must always be created with a paired
- // transparent proxy or the jit will get confused.
-#ifdef FEATURE_REMOTING
- if (pMT->IsContextful())
- COMPlusThrow(kNotSupportedException, W("NotSupported_ManagedActivation"));
-#endif
-
-#ifdef FEATURE_COMINTEROP
- // Also do not allow allocation of uninitialized RCWs (COM objects).
- if (pMT->IsComObjectType())
- COMPlusThrow(kNotSupportedException, W("NotSupported_ManagedActivation"));
-#endif // FEATURE_COMINTEROP
-
- // If it is a nullable, return the underlying type instead.
- if (Nullable::IsNullableType(pMT))
- pMT = pMT->GetInstantiation()[0].GetMethodTable();
-
- retVal = pMT->Allocate();
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(retVal);
-}
-FCIMPLEND
-
-FCIMPL1(Object*, ReflectionSerialization::GetSafeUninitializedObject, ReflectClassBaseObject* objTypeUNSAFE) {
- FCALL_CONTRACT;
-
- OBJECTREF retVal = NULL;
- REFLECTCLASSBASEREF objType = (REFLECTCLASSBASEREF) objTypeUNSAFE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_1(objType);
-
- if (objType == NULL)
- COMPlusThrowArgumentNull(W("type"), W("ArgumentNull_Type"));
-
- TypeHandle type = objType->GetType();
-
- // Don't allow arrays, pointers, byrefs or function pointers.
- if (type.IsTypeDesc())
- COMPlusThrow(kArgumentException, W("Argument_InvalidValue"));
-
- MethodTable *pMT = type.GetMethodTable();
- PREFIX_ASSUME(pMT != NULL);
-
- //We don't allow unitialized strings.
- if (pMT == g_pStringClass)
- COMPlusThrow(kArgumentException, W("Argument_NoUninitializedStrings"));
+ if (pMT->IsByRefLike()) {
+ COMPlusThrow(kNotSupportedException, W("NotSupported_ByRefLike"));
+ }
- // if this is an abstract class or an interface type then we will
- // fail this
- if (pMT->IsAbstract())
- COMPlusThrow(kMemberAccessException,W("Acc_CreateAbst"));
- else if (pMT->ContainsGenericVariables()) {
- COMPlusThrow(kMemberAccessException,W("Acc_CreateGeneric"));
+ // Never allow allocation of generics actually instantiated over __Canon
+ if (pMT->IsSharedByGenericInstantiations()) {
+ COMPlusThrow(kNotSupportedException, W("NotSupported_Type"));
}
// Never allow the allocation of an unitialized ContextBoundObject derived type, these must always be created with a paired
// transparent proxy or the jit will get confused.
-#ifdef FEATURE_REMOTING
- if (pMT->IsContextful())
- COMPlusThrow(kNotSupportedException, W("NotSupported_ManagedActivation"));
-#endif
#ifdef FEATURE_COMINTEROP
// Also do not allow allocation of uninitialized RCWs (COM objects).
@@ -3344,14 +2765,6 @@ FCIMPL1(Object*, ReflectionSerialization::GetSafeUninitializedObject, ReflectCla
}
FCIMPLEND
-FCIMPL0(FC_BOOL_RET, ReflectionSerialization::GetEnableUnsafeTypeForwarders)
-{
- FCALL_CONTRACT;
- FC_RETURN_BOOL(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Serialization_UnsafeTypeForwarding));
-}
-FCIMPLEND
-
-
//*************************************************************************************************
//*************************************************************************************************
//*************************************************************************************************
diff --git a/src/vm/reflectioninvocation.h b/src/vm/reflectioninvocation.h
index 7f72b61cd8..206e7516be 100644
--- a/src/vm/reflectioninvocation.h
+++ b/src/vm/reflectioninvocation.h
@@ -50,10 +50,6 @@ public:
static FCDECL1(void, RunClassConstructor, ReflectClassBaseObject *pTypeUNSAFE);
static FCDECL1(void, RunModuleConstructor, ReflectModuleBaseObject *pModuleUNSAFE);
-#ifndef FEATURE_CORECLR
- static FCDECL3(void, PrepareMethod, ReflectMethodObject* pMethodUNSAFE, TypeHandle *pInstantiation, UINT32 cInstantiation);
- static FCDECL1(void, PrepareDelegate, Object* delegateUNSAFE);
-#endif // !FEATURE_CORECLR
static FCDECL1(void, PrepareContractedDelegate, Object* delegateUNSAFE);
static FCDECL0(void, ProbeForSufficientStack);
static FCDECL0(void, EnsureSufficientExecutionStack);
@@ -93,8 +89,6 @@ public:
class ReflectionSerialization {
public:
static FCDECL1(Object*, GetUninitializedObject, ReflectClassBaseObject* objTypeUNSAFE);
- static FCDECL1(Object*, GetSafeUninitializedObject, ReflectClassBaseObject* objTypeUNSAFE);
- static FCDECL0(FC_BOOL_RET, GetEnableUnsafeTypeForwarders);
};
class ReflectionEnum {
diff --git a/src/vm/rejit.cpp b/src/vm/rejit.cpp
index 0b6e922831..7bbd0e2f71 100644
--- a/src/vm/rejit.cpp
+++ b/src/vm/rejit.cpp
@@ -447,16 +447,10 @@ HRESULT ProfilerFunctionControl::SetILInstrumentedCodeMap(ULONG cILMapEntries, C
return E_INVALIDARG;
}
-#ifdef FEATURE_CORECLR
if (g_pDebugInterface == NULL)
{
return CORPROF_E_DEBUGGING_DISABLED;
}
-#else
- // g_pDebugInterface is initialized on startup on desktop CLR, regardless of whether a debugger
- // or profiler is loaded. So it should always be available.
- _ASSERTE(g_pDebugInterface != NULL);
-#endif // FEATURE_CORECLR
// copy the il map and il map entries into the corresponding fields.
diff --git a/src/vm/remoting.cpp b/src/vm/remoting.cpp
deleted file mode 100644
index 1b65323bb6..0000000000
--- a/src/vm/remoting.cpp
+++ /dev/null
@@ -1,3773 +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.
-//
-// File: remoting.cpp
-//
-
-//
-// Purpose: Defines various remoting related objects such as
-// proxies
-//
-
-//
-
-
-#include "common.h"
-
-#ifdef FEATURE_REMOTING
-#include "virtualcallstub.h"
-#include "excep.h"
-#include "comdelegate.h"
-#include "remoting.h"
-#include "field.h"
-#include "siginfo.hpp"
-#include "stackbuildersink.h"
-#include "eehash.h"
-#include "profilepriv.h"
-#include "message.h"
-#include "eeconfig.h"
-#include "comcallablewrapper.h"
-#include "interopconverter.h"
-#include "asmconstants.h"
-#include "crossdomaincalls.h"
-#include "contractimpl.h"
-#include "typestring.h"
-#include "generics.h"
-#include "appdomain.inl"
-#include "dbginterface.h"
-
-#ifndef DACCESS_COMPILE
-
-// These hold label offsets into non-virtual thunks. They are used by
-// CNonVirtualThunkMgr::DoTraceStub and ::TraceManager to help the
-// debugger figure out where the thunk is going to go.
-DWORD g_dwNonVirtualThunkRemotingLabelOffset = 0;
-DWORD g_dwNonVirtualThunkReCheckLabelOffset = 0;
-
-// Statics
-
-MethodTable *CRemotingServices::s_pMarshalByRefObjectClass;
-MethodTable *CRemotingServices::s_pServerIdentityClass;
-
-MethodDesc *CRemotingServices::s_pRPPrivateInvoke;
-MethodDesc *CRemotingServices::s_pRPInvokeStatic;
-MethodDesc *CRemotingServices::s_pWrapMethodDesc;
-MethodDesc *CRemotingServices::s_pIsCurrentContextOK;
-MethodDesc *CRemotingServices::s_pCheckCast;
-MethodDesc *CRemotingServices::s_pFieldSetterDesc;
-MethodDesc *CRemotingServices::s_pFieldGetterDesc;
-MethodDesc *CRemotingServices::s_pObjectGetTypeDesc;
-MethodDesc *CRemotingServices::s_pGetTypeDesc;
-MethodDesc *CRemotingServices::s_pProxyForDomainDesc;
-MethodDesc *CRemotingServices::s_pServerContextForProxyDesc;
-MethodDesc *CRemotingServices::s_pServerDomainIdForProxyDesc;
-DWORD CRemotingServices::s_dwServerOffsetInRealProxy;
-DWORD CRemotingServices::s_dwSrvIdentityOffsetInRealProxy;
-DWORD CRemotingServices::s_dwIdOffset;
-DWORD CRemotingServices::s_dwTPOrObjOffsetInIdentity;
-DWORD CRemotingServices::s_dwMBRIDOffset;
-DWORD CRemotingServices::s_dwLeaseOffsetInIdentity;
-DWORD CRemotingServices::s_dwURIOffsetInIdentity;
-CrstStatic CRemotingServices::s_RemotingCrst;
-BOOL CRemotingServices::s_fRemotingStarted;
-MethodDesc *CRemotingServices::s_pRenewLeaseOnCallDesc;
-
-
-#ifdef FEATURE_COMINTEROP
-MethodDesc *CRemotingServices::s_pCreateObjectForCom;
-#endif
-
-// CTPMethodTable Statics
-DWORD CTPMethodTable::s_dwCommitedTPSlots;
-DWORD CTPMethodTable::s_dwReservedTPSlots;
-DWORD CTPMethodTable::s_dwReservedTPIndirectionSlotSize;
-DWORD CTPMethodTable::s_dwGCInfoBytes;
-DWORD CTPMethodTable::s_dwMTDataSlots;
-MethodTable *CTPMethodTable::s_pRemotingProxyClass;
-CrstStatic CTPMethodTable::s_TPMethodTableCrst;
-EEThunkHashTable *CTPMethodTable::s_pThunkHashTable;
-BOOL CTPMethodTable::s_fTPTableFieldsInitialized;
-
-#endif // !DACCESS_COMPILE
-
-
-SPTR_IMPL(MethodTable, CTPMethodTable, s_pThunkTable);
-
-#ifndef DACCESS_COMPILE
-
-// CVirtualThunks statics
-CVirtualThunks *CVirtualThunks::s_pVirtualThunks;
-
-// CVirtualThunkMgr statics
-CVirtualThunkMgr *CVirtualThunkMgr::s_pVirtualThunkMgr;
-
-#ifndef HAS_REMOTING_PRECODE
-// CNonVirtualThunk statics
-CNonVirtualThunk *CNonVirtualThunk::s_pNonVirtualThunks;
-SimpleRWLock* CNonVirtualThunk::s_pNonVirtualThunksListLock;
-
-// CNonVirtualThunkMgr statics
-CNonVirtualThunkMgr *CNonVirtualThunkMgr::s_pNonVirtualThunkMgr;
-#endif
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::Initialize public
-//
-// Synopsis: Initialized remoting state
-//
-//+----------------------------------------------------------------------------
-VOID CRemotingServices::Initialize()
-{
- STANDARD_VM_CONTRACT;
-
- // Initialize the remoting services critical section
- s_RemotingCrst.Init(CrstRemoting, CrstFlags(CRST_REENTRANCY|CRST_HOST_BREAKABLE));
-
- CTPMethodTable::Initialize();
-}
-
-INT32 CRemotingServices::IsTransparentProxy(Object* orTP)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- INT32 fIsTPMT = FALSE;
-
- if(orTP != NULL)
- {
- // Check if the supplied object has transparent proxy method table
- MethodTable *pMT = orTP->GetMethodTable();
- fIsTPMT = pMT->IsTransparentProxy() ? TRUE : FALSE;
- }
-
- LOG((LF_REMOTING, LL_EVERYTHING, "!IsTransparentProxyEx(0x%x) returning %s",
- orTP, fIsTPMT ? "TRUE" : "FALSE"));
-
- return(fIsTPMT);
-}
-
-
-Object* CRemotingServices::GetRealProxy(Object* objTP)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- OBJECTREF rv = NULL;
-
- if ((objTP != NULL) && (IsTransparentProxy(objTP)))
- {
- _ASSERTE(s_fRemotingStarted);
- rv = CTPMethodTable::GetRP(OBJECTREF(objTP));
- }
-
- LOG((LF_REMOTING, LL_INFO100, "!GetRealProxy(0x%x) returning 0x%x\n", objTP, OBJECTREFToObject(rv)));
-
- return OBJECTREFToObject(rv);
-}
-
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::EnsureRemotingStarted
-//
-// Synopsis: Startup the remoting services.
-//
-//
-//+----------------------------------------------------------------------------
-VOID CRemotingServices::EnsureRemotingStarted()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (!CRemotingServices::s_fRemotingStarted)
- CRemotingServices::StartRemoting();
-
- if (!CTPMethodTable::s_fTPTableFieldsInitialized)
- CTPMethodTable::EnsureFieldsInitialized();
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::StartRemoting private
-//
-// Synopsis: Initialize the static fields of CRemotingServices class
-//
-//
-//+----------------------------------------------------------------------------
-VOID CRemotingServices::StartRemoting()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // Acquire the remoting lock before initializing fields
- GCX_PREEMP();
-
- CrstHolder ch(&s_RemotingCrst);
-
- // Make sure that no other thread has initialized the fields
- if (!s_fRemotingStarted)
- {
- InitActivationServicesClass();
- InitRealProxyClass();
- InitRemotingProxyClass();
- InitIdentityClass();
- InitServerIdentityClass();
- InitMarshalByRefObjectClass();
- InitRemotingServicesClass();
- InitObjectClass();
- InitLeaseClass();
-
- // ********* NOTE ************
- // This must always be the last statement in this block to prevent races
- //
- VolatileStore(&s_fRemotingStarted, TRUE);
- // ********* END NOTE ************
- }
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::InitActivationServicesClass private
-//
-// Synopsis: Extract the method descriptors and fields of ActivationServices class
-//
-//
-//+----------------------------------------------------------------------------
-VOID CRemotingServices::InitActivationServicesClass()
-{
- STANDARD_VM_CONTRACT;
-
- s_pIsCurrentContextOK = MscorlibBinder::GetMethod(METHOD__ACTIVATION_SERVICES__IS_CURRENT_CONTEXT_OK);
-#ifdef FEATURE_COMINTEROP
- s_pCreateObjectForCom = MscorlibBinder::GetMethod(METHOD__ACTIVATION_SERVICES__CREATE_OBJECT_FOR_COM);
-#endif
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::InitRealProxyClass private
-//
-// Synopsis: Extract the method descriptors and fields of Real Proxy class
-//
-//
-//+----------------------------------------------------------------------------
-VOID CRemotingServices::InitRealProxyClass()
-{
- STANDARD_VM_CONTRACT;
-
- // Now store the methoddesc of the PrivateInvoke method on the RealProxy class
- s_pRPPrivateInvoke = MscorlibBinder::GetMethod(METHOD__REAL_PROXY__PRIVATE_INVOKE);
-
- // Now find the offset to the _identity field inside the
- // RealProxy class
- s_dwIdOffset = RealProxyObject::GetOffsetOfIdentity() - Object::GetOffsetOfFirstField();
-
- s_dwServerOffsetInRealProxy = RealProxyObject::GetOffsetOfServerObject() - Object::GetOffsetOfFirstField();
-
- s_dwSrvIdentityOffsetInRealProxy = RealProxyObject::GetOffsetOfServerIdentity() - Object::GetOffsetOfFirstField();
-
- return;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::InitRemotingProxyClass private
-//
-// Synopsis: Extract the method descriptors and fields of RemotingProxy class
-//
-//
-//+----------------------------------------------------------------------------
-VOID CRemotingServices::InitRemotingProxyClass()
-{
- STANDARD_VM_CONTRACT;
-
- s_pRPInvokeStatic = MscorlibBinder::GetMethod(METHOD__REMOTING_PROXY__INVOKE);
-
- // Note: We cannot do this inside TPMethodTable::InitializeFields ..
- // that causes recursions if in some situation only the latter is called
- // If you do this you will see Asserts when running any process under CorDbg
- // This is because jitting of NV methods on MBR objects calls
- // InitializeFields and when actually doing that we should not need to
- // JIT another NV method on some MBR object.
- CTPMethodTable::s_pRemotingProxyClass = MscorlibBinder::GetClass(CLASS__REMOTING_PROXY);
- _ASSERTE(CTPMethodTable::s_pRemotingProxyClass);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::InitServerIdentityClass private
-//
-// Synopsis: Extract the method descriptors and fields of ServerIdentity class
-//
-//
-//+----------------------------------------------------------------------------
-VOID CRemotingServices::InitServerIdentityClass()
-{
- STANDARD_VM_CONTRACT;
-
- s_pServerIdentityClass = MscorlibBinder::GetClass(CLASS__SERVER_IDENTITY);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::InitIdentityClass private
-//
-// Synopsis: Extract the method descriptors and fields of Identity class
-//
-//
-//+----------------------------------------------------------------------------
-VOID CRemotingServices::InitIdentityClass()
-{
- STANDARD_VM_CONTRACT;
-
- s_dwTPOrObjOffsetInIdentity = MscorlibBinder::GetFieldOffset(FIELD__IDENTITY__TP_OR_OBJECT);
-
- s_dwLeaseOffsetInIdentity = MscorlibBinder::GetFieldOffset(FIELD__IDENTITY__LEASE);
-
- s_dwURIOffsetInIdentity = MscorlibBinder::GetFieldOffset(FIELD__IDENTITY__OBJURI);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::InitMarshalByRefObjectClass private
-//
-// Synopsis: Extract the method descriptors and fields of MarshalByRefObject class
-//
-//
-//+----------------------------------------------------------------------------
-VOID CRemotingServices::InitMarshalByRefObjectClass()
-{
- STANDARD_VM_CONTRACT;
-
- s_pMarshalByRefObjectClass = MscorlibBinder::GetClass(CLASS__MARSHAL_BY_REF_OBJECT);
- s_dwMBRIDOffset = MarshalByRefObjectBaseObject::GetOffsetOfServerIdentity() - Object::GetOffsetOfFirstField();
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::InitRemotingServicesClass private
-//
-// Synopsis: Extract the method descriptors and fields of RemotingServices class
-//
-//
-//+----------------------------------------------------------------------------
-VOID CRemotingServices::InitRemotingServicesClass()
-{
- STANDARD_VM_CONTRACT;
-
- s_pCheckCast = MscorlibBinder::GetMethod(METHOD__REMOTING_SERVICES__CHECK_CAST);
-
- // Need these to call wrap/unwrap from the VM (message.cpp).
- // Also used by JIT helpers to wrap/unwrap
- s_pWrapMethodDesc = MscorlibBinder::GetMethod(METHOD__REMOTING_SERVICES__WRAP);
- s_pProxyForDomainDesc = MscorlibBinder::GetMethod(METHOD__REMOTING_SERVICES__CREATE_PROXY_FOR_DOMAIN);
- s_pServerContextForProxyDesc = MscorlibBinder::GetMethod(METHOD__REMOTING_SERVICES__GET_SERVER_CONTEXT_FOR_PROXY);
- s_pServerDomainIdForProxyDesc = MscorlibBinder::GetMethod(METHOD__REMOTING_SERVICES__GET_SERVER_DOMAIN_ID_FOR_PROXY);
- s_pGetTypeDesc = MscorlibBinder::GetMethod(METHOD__REMOTING_SERVICES__GET_TYPE);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::InitObjectClass private
-//
-// Synopsis: Extract the method descriptors and fields of Object class
-//
-//
-//+----------------------------------------------------------------------------
-VOID CRemotingServices::InitObjectClass()
-{
- STANDARD_VM_CONTRACT;
-
- s_pFieldSetterDesc = MscorlibBinder::GetMethod(METHOD__OBJECT__FIELD_SETTER);
- s_pFieldGetterDesc = MscorlibBinder::GetMethod(METHOD__OBJECT__FIELD_GETTER);
- s_pObjectGetTypeDesc = MscorlibBinder::GetMethod(METHOD__OBJECT__GET_TYPE);
-}
-
-VOID CRemotingServices::InitLeaseClass()
-{
- STANDARD_VM_CONTRACT;
-
- s_pRenewLeaseOnCallDesc = MscorlibBinder::GetMethod(METHOD__LEASE__RENEW_ON_CALL);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::RequiresManagedActivation private
-//
-// Synopsis: Determine if a config file has been parsed or if there
-// are any attributes on the class that would require us
-// to go into the managed activation codepath.
-//
-//
-// Note: Called by CreateProxyOrObject (JIT_NewCrossContext)
-//
-//+----------------------------------------------------------------------------
-ManagedActivationType __stdcall CRemotingServices::RequiresManagedActivation(TypeHandle ty)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- PRECONDITION(!ty.IsNull());
- }
- CONTRACTL_END;
-
- MethodTable* pMT = ty.GetMethodTable();
-
- PREFIX_ASSUME(pMT != NULL);
- if (!pMT->MayRequireManagedActivation())
- return NoManagedActivation;
-
-#ifdef _DEBUG
-
- ManagedActivationType bManaged = NoManagedActivation;
- if (pMT->IsRemotingConfigChecked())
- {
- // We have done work to figure this out in the past ...
- // use the cached result
- bManaged = pMT->RequiresManagedActivation() ? ManagedActivation : NoManagedActivation;
- }
- else if (pMT->IsContextful() || pMT->GetClass()->HasRemotingProxyAttribute())
- {
- // Contextful and classes that have a remoting proxy attribute
- // (whether they are MarshalByRef or ContextFul) always take the slow
- // path of managed activation
- bManaged = ManagedActivation;
- }
- else
- {
- // If we have parsed a config file that might have configured
- // this Type to be activated remotely
- if (GetAppDomain()->IsRemotingConfigured())
- {
- bManaged = ManagedActivation;
- // We will remember if the activation is actually going
- // remote based on if the managed call to IsContextOK returned us
- // a proxy or not
- }
-
-#ifdef FEATURE_COMINTEROP
- else if (pMT->IsComObjectType())
- {
- bManaged = ComObjectType;
- }
-#endif // FEATURE_COMINTEROP
-
- }
-
-#endif // _DEBUG
-
- if (pMT->RequiresManagedActivation())
- {
- // Contextful and classes that have a remoting proxy attribute
- // (whether they are MarshalByRef or ContextFul) always take the slow
- // path of managed activation
- _ASSERTE(bManaged == ManagedActivation);
- return ManagedActivation;
- }
-
- ManagedActivationType bMng = NoManagedActivation;
- if (!pMT->IsRemotingConfigChecked())
- {
- g_IBCLogger.LogMethodTableAccess(pMT);
-
- // If we have parsed a config file that might have configured
- // this Type to be activated remotely
- if (GetAppDomain()->IsRemotingConfigured())
- {
- bMng = ManagedActivation;
- // We will remember if the activation is actually going
- // remote based on if the managed call to IsContextOK returned us
- // a proxy or not
- }
-
-#ifdef FEATURE_COMINTEROP
- else if (pMT->IsComObjectType())
- {
- bMng = ComObjectType;
- }
-#endif // FEATURE_COMINTEROP
-
- if (bMng == NoManagedActivation)
- {
- pMT->TrySetRemotingConfigChecked();
- }
- }
-
- _ASSERTE(bManaged == bMng);
- return bMng;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::CreateProxyOrObject public
-//
-// Synopsis: Determine if the current context is appropriate
-// for activation. If the current context is OK then it creates
-// an object else it creates a proxy.
-//
-//
-// Note: Called by JIT_NewCrossContext
-//
-//+----------------------------------------------------------------------------
-OBJECTREF CRemotingServices::CreateProxyOrObject(MethodTable* pMT,
- BOOL fIsCom /*default:FALSE*/, BOOL fIsNewObj /*default:FALSE*/)
- /* fIsCom == Did we come here through CoCreateInstance */
- /* fIsNewObj == Did we come here through Jit_NewCrossContext (newObj) */
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pMT));
- PRECONDITION(!pMT->IsTransparentProxy());
-
- // By the time we reach here, we have already checked that the class may require
- // managed activation. This check is made either through the JIT_NewCrossContext helper
- // or Activator.CreateInstance codepath.
- PRECONDITION(pMT->MayRequireManagedActivation());
- }
- CONTRACTL_END;
-
- // Ensure remoting has been started.
- EnsureRemotingStarted();
-
- // Get the address of IsCurrentContextOK in managed code
- MethodDesc* pTargetMD = NULL;
- Object *pServer = NULL;
-
-#ifdef FEATURE_COMINTEROP
- if(fIsCom)
- {
- pTargetMD = CRemotingServices::MDofCreateObjectForCom();
- }
- else
-#endif // FEATURE_COMINTEROP
- {
- pTargetMD = CRemotingServices::MDofIsCurrentContextOK();
- }
-
- // Arrays are not created by JIT_NewCrossContext
- _ASSERTE(!pMT->IsArray());
-
- // Get the type seen by reflection
- REFLECTCLASSBASEREF reflectType = (REFLECTCLASSBASEREF) pMT->GetManagedClassObject();
- LPVOID pvType = NULL;
- *(REFLECTCLASSBASEREF *)&pvType = reflectType;
-
- // This will return either an uninitialized object or a proxy
- pServer = (Object *)CTPMethodTable::CallTarget(pTargetMD, pvType, NULL, (LPVOID)(size_t)(fIsNewObj?1:0));
-
- if (!pMT->IsContextful() && !pMT->IsComObjectType())
- {
- // Cache the result of the activation attempt ...
- // if a strictly MBR class is not configured for remote
- // activation we will not go
- // through this slow path next time!
- // (see RequiresManagedActivation)
- if (IsTransparentProxy(pServer))
- {
- // Set the flag that this class is remote activate
- // which means activation will go to managed code.
- pMT->SetRequiresManagedActivation();
- }
- else
- {
- // Set only the flag that no managed checks are required
- // for this class next time.
- pMT->SetRemotingConfigChecked();
- }
- }
-
- LOG((LF_REMOTING, LL_INFO1000, "CreateProxyOrObject returning 0x%p\n", pServer));
- if (pMT->IsContextful())
- {
- COUNTER_ONLY(GetPerfCounters().m_Context.cObjAlloc++);
- }
- return ObjectToOBJECTREF(pServer);
-}
-
-
-#ifndef HAS_REMOTING_PRECODE
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::GetStubForNonVirtualMethod public
-//
-// Synopsis: Get a stub for a non virtual method.
-//
-//
-//+----------------------------------------------------------------------------
-Stub* CRemotingServices::GetStubForNonVirtualMethod(MethodDesc* pMD, LPVOID pvAddrOfCode, Stub* pInnerStub)
-{
- CONTRACT (Stub*)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pMD));
- PRECONDITION(CheckPointer(pvAddrOfCode));
- PRECONDITION(CheckPointer(pInnerStub, NULL_OK));
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- CPUSTUBLINKER sl;
- Stub* pStub = CTPMethodTable::CreateStubForNonVirtualMethod(pMD, &sl, pvAddrOfCode, pInnerStub);
-
- RETURN pStub;
-}
-#endif // HAS_REMOTING_PRECODE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::GetNonVirtualEntryPointForVirtualMethod public
-//
-// Synopsis: Get a thunk for a non-virtual call to a virtual method.
-// Virtual methods do not normally get thunked in the vtable. This
-// is because virtual calls use the object's vtable, and proxied objects
-// would use the proxy's vtable. Hence local object (which would
-// have the real vtable) can make virtual calls without going through
-// the thunk.
-// However, if the virtual function is called non-virtually, we have
-// a problem (since this would bypass the proxy's vtable). Since this
-// is not a common case, we fix it by using a stub in such cases.
-//
-//
-//+----------------------------------------------------------------------------
-PCODE CRemotingServices::GetNonVirtualEntryPointForVirtualMethod(MethodDesc* pMD)
-{
- CONTRACT (PCODE)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pMD));
- PRECONDITION(pMD->IsRemotingInterceptedViaVirtualDispatch());
- POSTCONDITION(RETVAL != NULL);
- }
- CONTRACT_END;
-
-#ifdef HAS_REMOTING_PRECODE
- RETURN pMD->GetLoaderAllocator()->GetFuncPtrStubs()->GetFuncPtrStub(pMD, PRECODE_REMOTING);
-#else
- GCX_PREEMP();
- RETURN *CTPMethodTable::GetOrCreateNonVirtualSlotForVirtualMethod(pMD);
-#endif
-}
-
-#ifndef HAS_REMOTING_PRECODE
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::DestroyThunk public
-//
-// Synopsis: Destroy the thunk for the non virtual method.
-//
-//
-//+----------------------------------------------------------------------------
-void CRemotingServices::DestroyThunk(MethodDesc* pMD)
-{
- WRAPPER_NO_CONTRACT;
-
- // Delegate to a helper routine
- CTPMethodTable::DestroyThunk(pMD);
-}
-#endif // HAS_REMOTING_PRECODE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::GetDispatchInterfaceHelper public
-//
-// Synopsis: Returns helper for dispatching interface call into the remoting system
-// with exact MethodDesc. Used for remoting of calls on generic interfaces.
-// The returned helper has MethodDesc calling convention
-//+----------------------------------------------------------------------------
-PCODE CRemotingServices::GetDispatchInterfaceHelper(MethodDesc* pMD)
-{
- WRAPPER_NO_CONTRACT;
-
- return GetEEFuncEntryPoint(CRemotingServices__DispatchInterfaceCall);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::CheckCast public
-//
-// Synopsis: Checks either
-// (1) If the object type supports the given interface OR
-// (2) If the given type is present in the hierarchy of the
-// object type
-//
-//+----------------------------------------------------------------------------
-BOOL CRemotingServices::CheckCast(OBJECTREF orTP, TypeHandle objTy, TypeHandle ty)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(orTP != NULL);
- PRECONDITION(!objTy.IsNull());
- PRECONDITION(!ty.IsNull());
-
- // Object class can never be an interface. We use a separate cached
- // entry for storing interfaces that the proxy supports.
- PRECONDITION(!objTy.IsInterface());
- }
- CONTRACTL_END;
-
- // Early out if someone's trying to cast us to a type desc (such as a byref,
- // array or function pointer).
- if (ty.IsTypeDesc())
- return FALSE;
-
- BOOL fCastOK = FALSE;
-
- // (1) We are trying to cast to an interface
- if (ty.IsInterface())
- {
- // Do a quick check for interface cast by comparing it against the
- // cached entry
- MethodTable *pItfMT = ((TRANSPARENTPROXYREF)orTP)->GetInterfaceMethodTable();
- if (NULL != pItfMT)
- {
- if(pItfMT == ty.GetMethodTable())
- fCastOK = TRUE;
- else
- fCastOK = pItfMT->CanCastToInterface(ty.GetMethodTable());
- }
-
- if(!fCastOK)
- fCastOK = objTy.GetMethodTable()->CanCastToInterface(ty.GetMethodTable());
- }
- // (2) Everything else...
- else
- {
- // Walk up the class hierarchy and find a matching class
- while (ty != objTy)
- {
- if (objTy.IsNull())
- {
- // Oh-oh, the cast did not succeed. Maybe we have to refine
- // the proxy to match the clients view
- break;
- }
-
- // Continue searching
- objTy = objTy.GetParent();
- }
-
- if(objTy == ty)
- fCastOK = TRUE;
- }
-
- return fCastOK;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::CheckCast public
-//
-// Synopsis: Refine the type hierarchy that the proxy represents to match
-// the client view. If the client is trying to cast the proxy
-// to a type not supported by the server object then we
-// return NULL
-//
-//
-//+----------------------------------------------------------------------------
-BOOL CRemotingServices::CheckCast(OBJECTREF orTP, TypeHandle ty)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(orTP != NULL);
- PRECONDITION(!ty.IsNull());
- }
- CONTRACTL_END;
-
- BOOL fCastOK = FALSE;
-
- GCPROTECT_BEGIN(orTP);
-
- // Make sure the type being cast to has been restored.
- ty.CheckRestore();
-
- MethodTable *pMT = orTP->GetMethodTable();
-
- // Make sure that we have a transparent proxy
- _ASSERTE(pMT->IsTransparentProxy());
-
- pMT = orTP->GetTrueMethodTable();
-
- // Do a cast check without taking a lock
- fCastOK = CheckCast(orTP, TypeHandle(pMT), ty);
-
- if (!fCastOK && !ty.IsTypeDesc())
- {
- // We reach here only if any of the types in the current type hierarchy
- // represented by the proxy does not match the given type.
- // Call a helper routine in managed RemotingServices to find out
- // whether the server object supports the given type
- MethodDesc* pTargetMD = MDofCheckCast();
- fCastOK = CTPMethodTable::CheckCast(pTargetMD, (TRANSPARENTPROXYREF)orTP, ty);
- }
-
- if (fCastOK)
- {
- // Do the type equivalence tests
- CRealProxy::UpdateOptFlags(orTP);
- }
-
- GCPROTECT_END();
-
- LOG((LF_REMOTING, LL_INFO100, "CheckCast returning %s for object 0x%x and class 0x%x \n", (fCastOK ? "TRUE" : "FALSE")));
-
- return (fCastOK);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::FieldAccessor public
-//
-// Synopsis: Sets/Gets the value of the field given an instance or a proxy
-//
-//+----------------------------------------------------------------------------
-void CRemotingServices::FieldAccessor(FieldDesc* pFD, OBJECTREF o, LPVOID pVal, BOOL fIsGetter)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pFD));
- PRECONDITION(o != NULL);
- PRECONDITION(CheckPointer(pVal, NULL_OK));
- PRECONDITION(o->IsTransparentProxy() || o->GetMethodTable()->IsMarshaledByRef());
- }
- CONTRACTL_END;
-
- MethodTable *pMT = o->GetMethodTable();
- TypeHandle fldClass;
- TypeHandle thRealObjectType;
-
- GCPROTECT_BEGIN(o);
- GCPROTECT_BEGININTERIOR(pVal);
-
- // If the field descriptor type is not exact (i.e. it's a representative
- // descriptor for a generic field) then we need to be more careful
- // determining the properties of the field.
- if (pFD->IsSharedByGenericInstantiations())
- {
- // We need to resolve the field type in the context of the actual object
- // it belongs to. If we've been handed a proxy we have to go grab the
- // proxied type for this to work.
- thRealObjectType = o->GetTrueTypeHandle();
-
- // Evaluate the field signature in the type context of the parent object.
- MetaSig sig(pFD, thRealObjectType);
- sig.NextArg();
- fldClass = sig.GetLastTypeHandleThrowing();
- }
- else
- {
- fldClass = pFD->GetFieldTypeHandleThrowing();
- }
-
- GCPROTECT_END();
- GCPROTECT_END();
-
- CorElementType fieldType = fldClass.GetSignatureCorElementType();
- UINT cbSize = GetSizeForCorElementType(fieldType);
- BOOL fIsGCRef = CorTypeInfo::IsObjRef(fieldType);
- BOOL fIsByValue = fieldType == ELEMENT_TYPE_VALUETYPE;
-
- if(pMT->IsMarshaledByRef())
- {
- GCX_FORBID();
-
- _ASSERTE(!o->IsTransparentProxy());
-
- // This is a reference to a real object. Get/Set the field value
- // and return
- LPVOID pFieldAddress = pFD->GetAddress((LPVOID)OBJECTREFToObject(o));
- LPVOID pDest = (fIsGetter ? pVal : pFieldAddress);
- LPVOID pSrc = (fIsGetter ? pFieldAddress : pVal);
- if(fIsGCRef && !fIsGetter)
- {
- SetObjectReference((OBJECTREF*)pDest, ObjectToOBJECTREF(*(Object **)pSrc), o->GetAppDomain());
- }
- else if(fIsByValue)
- {
- CopyValueClass(pDest, pSrc, fldClass.AsMethodTable(), o->GetAppDomain());
- }
- else
- {
- CopyDestToSrc(pDest, pSrc, cbSize);
- }
- }
- else
- {
- // Call the managed code to start the field access call
- CallFieldAccessor(pFD, o, pVal, fIsGetter, fIsByValue, fIsGCRef, thRealObjectType, fldClass, fieldType, cbSize);
- }
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::CopyDestToSrc private
-//
-// Synopsis: Copies the specified number of bytes from the src to dest
-//
-//
-//+----------------------------------------------------------------------------
-VOID CRemotingServices::CopyDestToSrc(LPVOID pDest, LPVOID pSrc, UINT cbSize)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pDest));
- PRECONDITION(CheckPointer(pSrc));
- }
- CONTRACTL_END;
-
- switch (cbSize)
- {
- case 1:
- VolatileStore((INT8*)pDest, *(INT8*)pSrc);
- break;
-
- case 2:
- VolatileStore((INT16*)pDest, *(INT16*)pSrc);
- break;
-
- case 4:
- VolatileStore((INT32*)pDest, *(INT32*)pSrc);
- break;
-
- case 8:
- VolatileStore((INT64*)pDest, *(INT64*)pSrc);
- break;
-
- default:
- UNREACHABLE();
- break;
- }
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::CallFieldAccessor private
-//
-// Synopsis: Sets up the arguments and calls RealProxy::FieldAccessor
-//
-//
-//+----------------------------------------------------------------------------
-VOID CRemotingServices::CallFieldAccessor(FieldDesc* pFD,
- OBJECTREF o,
- VOID* pVal,
- BOOL fIsGetter,
- BOOL fIsByValue,
- BOOL fIsGCRef,
- TypeHandle ty,
- TypeHandle fldTy,
- CorElementType fieldType,
- UINT cbSize)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pFD));
- PRECONDITION(o != NULL);
- PRECONDITION(CheckPointer(pVal));
- }
- CONTRACTL_END;
-
- //****************************WARNING******************************
- // GC Protect all non-primitive variables
- //*****************************************************************
-
- FieldArgs fieldArgs;
- fieldArgs.obj = NULL;
- fieldArgs.val = NULL;
- fieldArgs.typeName = NULL;
- fieldArgs.fieldName = NULL;
-
- GCPROTECT_BEGIN(fieldArgs);
- GCPROTECT_BEGININTERIOR(pVal);
-
- fieldArgs.obj = o;
-
- // protect the field value if it is a gc-ref type
- if(fIsGCRef)
- fieldArgs.val = ObjectToOBJECTREF(*(Object **)pVal);
-
-
- // Set up the arguments
-
- // Argument 1: String typeName
- // Argument 2: String fieldName
- // Get the type name and field name strings
- GetTypeAndFieldName(&fieldArgs, pFD, ty);
-
- // Argument 3: Object val
- OBJECTREF val = NULL;
- if(!fIsGetter)
- {
- // If we are setting a field value then we create a variant data
- // structure to hold the field value
- // Extract the field from the gc protected structure if it is an object
- // else use the value passed to the function
- LPVOID pvFieldVal = (fIsGCRef ? (LPVOID)&(fieldArgs.val) : pVal);
- // <REVISIT_TODO>: This can cause a GC. We need some way to protect the variant
- // data</REVISIT_TODO>
- OBJECTREF *lpVal = &val;
- GCPROTECT_BEGININTERIOR (pvFieldVal);
- CMessage::GetObjectFromStack(lpVal, &pvFieldVal, fieldType, fldTy, TRUE);
- GCPROTECT_END ();
- }
-
- // Get the method descriptor of the call
- MethodDesc *pMD = (fIsGetter ? MDofFieldGetter() : MDofFieldSetter());
-
- // Call the field accessor function
- //////////////////////////////// GETTER ///////////////////////////////////
- if(fIsGetter)
- {
- // Set up the return value
- OBJECTREF oRet = NULL;
-
- GCPROTECT_BEGIN (oRet);
- CRemotingServices__CallFieldGetter(pMD,
- (LPVOID)OBJECTREFToObject(fieldArgs.obj),
- (LPVOID)OBJECTREFToObject(fieldArgs.typeName),
- (LPVOID)OBJECTREFToObject(fieldArgs.fieldName),
- (LPVOID)&(oRet));
-
- // If we are getting a field value then extract the field value
- // based on the type of the field
- if(fIsGCRef)
- {
- // Do a check cast to ensure that the field type and the
- // return value are compatible
- OBJECTREF orRet = oRet;
- OBJECTREF orSaved = orRet;
- if(IsTransparentProxy(OBJECTREFToObject(orRet)))
- {
- GCPROTECT_BEGIN(orRet);
-
- if(!CheckCast(orRet, fldTy))
- COMPlusThrow(kInvalidCastException, W("Arg_ObjObj"));
-
- orSaved = orRet;
-
- GCPROTECT_END();
- }
-
- *(OBJECTREF *)pVal = orSaved;
- }
- else if (fIsByValue)
- {
- // Copy from the source to the destination
- if (oRet != NULL)
- {
- fldTy.GetMethodTable()->UnBoxIntoUnchecked(pVal, oRet);
- }
- }
- else
- {
- if (oRet != NULL)
- CopyDestToSrc(pVal, oRet->UnBox(), cbSize);
- }
- GCPROTECT_END ();
- }
- ///////////////////////// SETTER //////////////////////////////////////////
- else
- {
- CRemotingServices__CallFieldSetter(pMD,
- (LPVOID)OBJECTREFToObject(fieldArgs.obj),
- (LPVOID)OBJECTREFToObject(fieldArgs.typeName),
- (LPVOID)OBJECTREFToObject(fieldArgs.fieldName),
- (LPVOID)OBJECTREFToObject(val));
- }
-
- GCPROTECT_END(); // pVal
- GCPROTECT_END(); // fieldArgs
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::GetTypeAndFieldName private
-//
-// Synopsis: Get the type name and field name of the
-//
-//
-//+----------------------------------------------------------------------------
-VOID CRemotingServices::GetTypeAndFieldName(FieldArgs *pArgs, FieldDesc *pFD, TypeHandle thEnclosingClass)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pArgs));
- PRECONDITION(CheckPointer(pFD));
- }
- CONTRACTL_END;
-
- TypeHandle thDeclaringType = !thEnclosingClass.IsNull() ?
- pFD->GetExactDeclaringType(thEnclosingClass.AsMethodTable()) : pFD->GetEnclosingMethodTable();
- _ASSERTE(!thDeclaringType.IsNull());
-
- // Extract the type name and field name string
- // <REVISIT_TODO>FUTURE: Put this in the reflection data structure cache TarunA 11/26/00</REVISIT_TODO>
- StackSString ss;
- TypeString::AppendType(ss, thDeclaringType, TypeString::FormatNamespace | TypeString::FormatFullInst);
- pArgs->typeName = StringObject::NewString(ss);
-
- pArgs->fieldName = StringObject::NewString(pFD->GetName());
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::MatchField private
-//
-// Synopsis: Find out whether the given field name is the same as the name
-// of the field descriptor field name.
-//
-//
-//+----------------------------------------------------------------------------
-BOOL CRemotingServices::MatchField(FieldDesc* pCurField, LPCUTF8 szFieldName)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pCurField));
- PRECONDITION(CheckPointer(szFieldName));
- }
- CONTRACTL_END;
-
- // Get the name of the field
- LPCUTF8 szCurFieldName;
- if (FAILED(pCurField->GetName_NoThrow(&szCurFieldName)))
- {
- return FALSE;
- }
-
- return strcmp(szCurFieldName, szFieldName) == 0;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::Wrap public
-//
-// Synopsis: Wrap a contextful object to create a proxy
-// Delegates to a helper method to do the actual work
-//
-//
-//+----------------------------------------------------------------------------
-OBJECTREF CRemotingServices::Wrap(OBJECTREF obj)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- // Basic sanity check
- VALIDATEOBJECTREF(obj);
-
- // ******************* WARNING ********************************************
- // Do not throw any exceptions or provoke GC without setting up a frame.
- // At present its the callers responsibility to setup a frame that can
- // handle exceptions.
- // ************************************************************************
- OBJECTREF orProxy = obj;
- if(obj != NULL && (obj->GetMethodTable()->IsContextful()))
- {
- if(!IsTransparentProxy(OBJECTREFToObject(obj)))
- {
- // See if we can extract the proxy from the object
- orProxy = GetProxyFromObject(obj);
- if(orProxy == NULL)
- {
- // ask the remoting services to wrap the object
- orProxy = CRemotingServices::WrapHelper(obj);
- }
- }
- }
-
- return orProxy;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::WrapHelper public
-//
-// Synopsis: Wrap an object to return a proxy. This function assumes that
-// a fcall frame is already setup.
-//
-//+----------------------------------------------------------------------------
-OBJECTREF CRemotingServices::WrapHelper(OBJECTREF obj)
-{
- // Basic sanity check
- VALIDATEOBJECTREF(obj);
-
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(obj != NULL);
- PRECONDITION(!IsTransparentProxy(OBJECTREFToObject(obj)));
- PRECONDITION(obj->GetMethodTable()->IsContextful());
- }
- CONTRACTL_END;
-
-
- // Default return value indicates an error
- OBJECTREF newobj = NULL;
- MethodDesc* pTargetMD = NULL;
-
- // Ensure remoting has been started.
- EnsureRemotingStarted();
-
- // Get the address of wrap in managed code
- pTargetMD = CRemotingServices::MDofWrap();
-
- // call the managed method to wrap
- newobj = ObjectToOBJECTREF( (Object *)CTPMethodTable::CallTarget(pTargetMD,
- (LPVOID)OBJECTREFToObject(obj),
- NULL));
-
- return newobj;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::GetProxyFromObject public
-//
-// Synopsis: Extract the proxy from the field in the
-// ContextBoundObject class
-//
-//
-//+----------------------------------------------------------------------------
-OBJECTREF CRemotingServices::GetProxyFromObject(OBJECTREF obj)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- PRECONDITION(obj != NULL);
- }
- CONTRACTL_END;
-
- // Basic sanity check
- VALIDATEOBJECTREF(obj);
-
- // We can derive a proxy for contextful types only.
- _ASSERTE(obj->GetMethodTable()->IsContextful());
-
- OBJECTREF srvID = (OBJECTREF)(Object*)obj->GetPtrOffset(s_dwMBRIDOffset);
- OBJECTREF orProxy = NULL;
-
- if (srvID != NULL)
- orProxy = (OBJECTREF)(Object*)srvID->GetPtrOffset(s_dwTPOrObjOffsetInIdentity);
-
- // This should either be null or a proxy type
- _ASSERTE((orProxy == NULL) || IsTransparentProxy(OBJECTREFToObject(orProxy)));
-
- return orProxy;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::IsProxyToRemoteObject public
-//
-// Synopsis: Check if the proxy is to a remote object
-// (1) TRUE : if object is non local (ie outside this PROCESS) otherwise
-// (2) FALSE
-//
-//+----------------------------------------------------------------------------
-BOOL CRemotingServices::IsProxyToRemoteObject(OBJECTREF obj)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(obj != NULL);
- }
- CONTRACTL_END;
-
- // Basic sanity check
- VALIDATEOBJECTREF(obj);
-
- // If remoting is not started, for now let us just return FALSE
- if(!s_fRemotingStarted)
- return FALSE;
-
- if(!obj->IsTransparentProxy())
- return FALSE;
-
- // so it is a transparent proxy
- AppDomain *pDomain = GetServerDomainForProxy(obj);
- if(pDomain != NULL)
- return TRUE;
-
- return FALSE;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::GetObjectFromProxy public
-//
-// Synopsis: Extract the object given a proxy.
-//
-//
-//+----------------------------------------------------------------------------
-OBJECTREF CRemotingServices::GetObjectFromProxy(OBJECTREF obj)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- PRECONDITION(obj != NULL);
- PRECONDITION(s_fRemotingStarted);
- PRECONDITION(IsTransparentProxy(OBJECTREFToObject(obj)));
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- // Basic sanity check
- VALIDATEOBJECTREF(obj);
-
- OBJECTREF oref = NULL;
- if (CTPMethodTable__GenericCheckForContextMatch(OBJECTREFToObject(obj)))
- {
- OBJECTREF objRef = ObjectToOBJECTREF(GetRealProxy(OBJECTREFToObject(obj)));
- oref = (OBJECTREF)(Object*)objRef->GetPtrOffset(s_dwServerOffsetInRealProxy);
- if (oref != NULL)
- obj = oref;
- }
-
- return obj;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::GetServerIdentityFromProxy private
-//
-// Synopsis: Gets the server identity (if one exists) from a proxy
-//
-//
-//
-//
-//+----------------------------------------------------------------------------
-OBJECTREF CRemotingServices::GetServerIdentityFromProxy(OBJECTREF obj)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(obj != NULL);
- PRECONDITION(IsTransparentProxy(OBJECTREFToObject(obj)));
- }
- CONTRACTL_END;
-
-
- // Extract the real proxy underlying the transparent proxy
- OBJECTREF pObj = ObjectToOBJECTREF(GetRealProxy(OBJECTREFToObject(obj)));
-
- OBJECTREF id = NULL;
-
- // Extract the identity object
- pObj = (OBJECTREF)(Object*)pObj->GetPtrOffset(s_dwIdOffset);
-
- // Extract the _identity from the real proxy only if it is an instance of
- // remoting proxy
- if((pObj != NULL) && IsInstanceOfServerIdentity(pObj->GetMethodTable()))
- id = pObj;
-
- return id;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::GetServerDomainForProxy public
-//
-// Synopsis: Returns the AppDomain corresponding to the server
-// if the proxy and the server are in the same process.
-//
-//
-//+----------------------------------------------------------------------------
-AppDomain *CRemotingServices::GetServerDomainForProxy(OBJECTREF proxy)
-{
- CONTRACT (AppDomain*)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(proxy != NULL);
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END;
-
- // call the managed method
- Context *pContext = (Context *)GetServerContextForProxy(proxy);
- if (pContext)
- RETURN pContext->GetDomain();
- else
- RETURN NULL;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::GetServerDomainIdForProxy public
-//
-// Synopsis: Returns the AppDomain ID corresponding to the server
-// if the proxy and the server are in the same process.
-// Returns 0 if it cannot determine.
-//
-//
-//+----------------------------------------------------------------------------
-int CRemotingServices::GetServerDomainIdForProxy(OBJECTREF proxy)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(proxy != NULL);
- PRECONDITION(IsTransparentProxy(OBJECTREFToObject(proxy)));
- }
- CONTRACTL_END;
-
- // Get the address of GetDomainIdForProxy in managed code
- MethodDesc* pTargetMD = CRemotingServices::MDofGetServerDomainIdForProxy();
-
- // This will just read the appDomain ID from the marshaled data
- // for the proxy. It returns 0 if the proxy is to a server in another
- // process. It may also return 0 if it cannot determine the server
- // domain ID (eg. for Well Known Object proxies).
-
- // call the managed method
- // <REVISIT_TODO>This cast to Int32 actually causes a potential loss
- // of data.</REVISIT_TODO>
- return (int)(INT_PTR)CTPMethodTable::CallTarget(
- pTargetMD,
- (LPVOID)OBJECTREFToObject(proxy),
- NULL);
-}
-
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::GetServerContextForProxy public
-//
-// Synopsis: Returns the AppDomain corresponding to the server
-// if the proxy and the server are in the same process.
-//
-//
-//+----------------------------------------------------------------------------
-Context *CRemotingServices::GetServerContextForProxy(OBJECTREF proxy)
-{
- CONTRACT (Context*)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(proxy != NULL);
- PRECONDITION(IsTransparentProxy(OBJECTREFToObject(proxy)));
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END;
-
- // Get the address of GetAppDomainForProxy in managed code
- MethodDesc* pTargetMD = CRemotingServices::MDofGetServerContextForProxy();
-
- // This will return the correct VM Context object for the server if
- // the proxy is true cross domain proxy to a server in another domain
- // in the same process. The managed method will Assert if called on a proxy
- // which is either half-built or does not have an ObjRef ... which may
- // happen for eg. if the proxy and the server are in the same appdomain.
-
- // we return NULL if the server object for the proxy is in another
- // process or if the appDomain for the server is invalid or if we cannot
- // determine the context (eg. well known object proxies).
-
- // call the managed method
- RETURN (Context *)CTPMethodTable::CallTarget(
- pTargetMD,
- (LPVOID)OBJECTREFToObject(proxy),
- NULL);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::CreateProxyForDomain public
-//
-// Synopsis: Create a proxy for the app domain object by calling marshal
-// inside the newly created domain and unmarshaling in the old
-// domain
-//
-//
-//+----------------------------------------------------------------------------
-OBJECTREF CRemotingServices::CreateProxyForDomain(AppDomain* pDomain)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pDomain));
- }
- CONTRACTL_END;
-
- // Ensure remoting has been started.
- EnsureRemotingStarted();
-
- MethodDesc* pTargetMD = MDOfCreateProxyForDomain();
-
- // Call the managed method which will marshal and unmarshal the
- // appdomain object to create the proxy
-
- // We pass the ContextID of the default context of the new appDomain
- // object. This helps the boot-strapping! (i.e. entering the new domain
- // to marshal itself out).
-
- Object *proxy = (Object *)CTPMethodTable::CallTarget(
- pTargetMD,
- (LPVOID)(DWORD_PTR)pDomain->GetId().m_dwId,
- (LPVOID)pDomain->GetDefaultContext());
- return ObjectToOBJECTREF(proxy);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::GetClass public
-//
-// Synopsis: Extract the true class of the object whose proxy is given.
-//
-//
-//
-//+----------------------------------------------------------------------------
-REFLECTCLASSBASEREF CRemotingServices::GetClass(OBJECTREF pThis)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(pThis != NULL);
- }
- CONTRACTL_END;
-
- REFLECTCLASSBASEREF refClass = NULL;
- MethodTable *pMT = NULL;
-
- GCPROTECT_BEGIN(pThis);
-
- // For proxies to objects in the same appdomain, we always know the
- // correct type
- if(GetServerIdentityFromProxy(pThis) != NULL)
- {
- pMT = pThis->GetTrueMethodTable();
- }
- else
- {
- // For everything else either we have refined the proxy to its correct type
- // or we have to consult the objref to get the true type
-
- MethodDesc* pTargetMD = CRemotingServices::MDofGetType();
-
- refClass = (REFLECTCLASSBASEREF)(ObjectToOBJECTREF((Object *)CTPMethodTable::CallTarget(pTargetMD,
- (LPVOID)OBJECTREFToObject(pThis), NULL)));
-
- if(refClass == NULL)
- {
- // There was no objref associated with the proxy or it is a proxy
- // that we do not understand.
- // In this case, we return the class that is stored in the proxy
- pMT = pThis->GetTrueMethodTable();
- }
-
- _ASSERTE(refClass != NULL || pMT != NULL);
-
- // Refine the proxy to the class just retrieved
- if(refClass != NULL)
- {
- CTPMethodTable::RefineProxy((TRANSPARENTPROXYREF)pThis, refClass->GetType());
- }
- }
-
- if (refClass == NULL)
- {
- PREFIX_ASSUME(pMT != NULL);
- refClass = (REFLECTCLASSBASEREF)pMT->GetManagedClassObject();
- }
-
- GCPROTECT_END();
-
- _ASSERTE(refClass != NULL);
- return refClass;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRealProxy::SetStubData public
-//
-// Synopsis: Set the stub data in the transparent proxy
-//
-//+----------------------------------------------------------------------------
-FCIMPL2(VOID, CRealProxy::SetStubData, Object* orRPUNSAFE, Object* orStubDataUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- }
- CONTRACTL_END;
-
- BOOL fThrow = FALSE;
- REALPROXYREF orRP = (REALPROXYREF)ObjectToOBJECTREF(orRPUNSAFE);
- OBJECTREF orStubData = ObjectToOBJECTREF(orStubDataUNSAFE);
-
- if (orRP != NULL && orStubData != NULL)
- {
- TRANSPARENTPROXYREF orTP = orRP->GetTransparentProxy();
- if (orTP != NULL)
- {
- orTP->SetStubData(orStubData);
- }
- else
- {
- fThrow = TRUE;
- }
- }
- else
- {
- fThrow = TRUE;
- }
-
- if(fThrow)
- FCThrowVoid(kArgumentNullException);
-}
-FCIMPLEND
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRealProxy::GetStubData public
-//
-// Synopsis: Get the stub data in the transparent proxy
-//
-//+----------------------------------------------------------------------------
-FCIMPL1(Object*, CRealProxy::GetStubData, Object* orRPUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- }
- CONTRACTL_END;
-
- BOOL fThrow = FALSE;
- REALPROXYREF orRP = (REALPROXYREF)ObjectToOBJECTREF(orRPUNSAFE);
- OBJECTREF orRet = NULL;
-
- if (orRP != NULL)
- {
- TRANSPARENTPROXYREF orTP = orRP->GetTransparentProxy();
- if (orTP != NULL)
- orRet = orTP->GetStubData();
- else
- fThrow = TRUE;
- }
- else
- {
- fThrow = TRUE;
- }
-
- if(fThrow)
- FCThrow(kArgumentNullException);
-
- return OBJECTREFToObject(orRet);
-}
-FCIMPLEND
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRealProxy::GetDefaultStub public
-//
-// Synopsis: Get the default stub implemented by us which matches contexts
-//
-//+----------------------------------------------------------------------------
-FCIMPL0(LPVOID, CRealProxy::GetDefaultStub)
-{
- FCALL_CONTRACT;
-
- return (LPVOID)CRemotingServices__CheckForContextMatch;
-}
-FCIMPLEND
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRealProxy::GetStub public
-//
-// Synopsis: Get the stub pointer in the transparent proxy
-//
-//+----------------------------------------------------------------------------
-FCIMPL1(LPVOID, CRealProxy::GetStub, Object* orRPUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(orRPUNSAFE));
- }
- CONTRACTL_END;
-
- REALPROXYREF orRP = (REALPROXYREF)ObjectToOBJECTREF(orRPUNSAFE);
- TRANSPARENTPROXYREF orTP = orRP->GetTransparentProxy();
-
- return orTP->GetStub();
-}
-FCIMPLEND
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRealProxy::GetProxiedType public
-//
-// Synopsis: Get the type that is represented by the transparent proxy
-//
-//+----------------------------------------------------------------------------
-FCIMPL1(Object*, CRealProxy::GetProxiedType, Object* orRPUNSAFE)
-{
- FCALL_CONTRACT;
-
- REFLECTCLASSBASEREF refClass = NULL;
- REALPROXYREF orRP = (REALPROXYREF)ObjectToOBJECTREF(orRPUNSAFE);
- HELPER_METHOD_FRAME_BEGIN_RET_1(orRP);
-
- TRANSPARENTPROXYREF orTP = orRP->GetTransparentProxy();
-
- refClass = CRemotingServices::GetClass(orTP);
- _ASSERTE(refClass != NULL);
-
- HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(refClass);
-}
-FCIMPLEND
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::Initialize public
-//
-// Synopsis: Initialized data structures needed for managing tranparent
-// proxies
-//
-//+----------------------------------------------------------------------------
-VOID CTPMethodTable::Initialize()
-{
- STANDARD_VM_CONTRACT;
-
- s_TPMethodTableCrst.Init(CrstTPMethodTable);
-}
-
-//+----------------------------------------------------------------------------
-
-PCODE CTPMethodTable::GetTPStubEntryPoint()
-{
- LIMITED_METHOD_CONTRACT;
- return GetEEFuncEntryPoint(TransparentProxyStub);
-}
-
-PCODE CTPMethodTable::GetDelegateStubEntryPoint()
-{
- LIMITED_METHOD_CONTRACT;
- return GetEEFuncEntryPoint(TransparentProxyStub_CrossContext);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::EnsureFieldsInitialized private
-//
-// Synopsis: Initialize the static fields of CTPMethodTable class
-// and the thunk manager classes
-//
-//
-//+----------------------------------------------------------------------------
-void CTPMethodTable::EnsureFieldsInitialized()
-{
- CONTRACT_VOID
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- POSTCONDITION(s_fTPTableFieldsInitialized);
- }
- CONTRACT_END;
-
- if (!s_fTPTableFieldsInitialized)
- {
- GCX_PREEMP();
-
- // Load Tranparent proxy class (do this before we enter the critical section)
- MethodTable* pTPMT = MscorlibBinder::GetClass(CLASS__TRANSPARENT_PROXY);
- _ASSERTE(pTPMT->IsTransparentProxy());
-
- CrstHolder ch(&s_TPMethodTableCrst);
-
- if(!s_fTPTableFieldsInitialized)
- {
- // Obtain size of GCInfo stored above the method table
- CGCDesc *pGCDesc = CGCDesc::GetCGCDescFromMT(pTPMT);
- BYTE *pGCTop = (BYTE *) pGCDesc->GetLowestSeries();
- s_dwGCInfoBytes = (DWORD)(((BYTE *) pTPMT) - pGCTop);
- _ASSERTE((s_dwGCInfoBytes & 3) == 0);
-
- // Obtain the number of bytes to be copied for creating the TP
- // method tables containing thunks
- _ASSERTE(((s_dwGCInfoBytes + sizeof(MethodTable)) & (sizeof(PCODE)-1)) == 0);
- s_dwMTDataSlots = ((s_dwGCInfoBytes + sizeof(MethodTable)) / sizeof(PCODE));
- _ASSERTE(sizeof(MethodTable) == MethodTable::GetVtableOffset());
-
- // We rely on the number of interfaces implemented by the
- // Transparent proxy being 0, so that InterfaceInvoke hints
- // fail and trap to InnerFailStub which also fails and
- // in turn traps to FailStubWorker. In FailStubWorker, we
- // determine the class being proxied and return correct slot.
- _ASSERTE(pTPMT->GetNumInterfaces() == 0);
-
- CVirtualThunkMgr::InitVirtualThunkManager();
-
- // Create the global thunk table and set the cycle between
- // the transparent proxy class and the global thunk table
- CreateTPMethodTable(pTPMT);
-
-#ifdef HAS_REMOTING_PRECODE
- // Activate the remoting precode helper
- ActivatePrecodeRemotingThunk();
-#endif // HAS_REMOTING_PRECODE
-
- // NOTE: This must always be the last statement in this block
- // to prevent races
- // Load Tranparent proxy class
- s_fTPTableFieldsInitialized = TRUE;
- }
- }
-
- RETURN;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::GetRP public
-//
-// Synopsis: Get the real proxy backing the transparent proxy
-//
-//+----------------------------------------------------------------------------
-REALPROXYREF CTPMethodTable::GetRP(OBJECTREF orTP)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- PRECONDITION(orTP != NULL);
- PRECONDITION(orTP->IsTransparentProxy());
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- return (REALPROXYREF)(((TRANSPARENTPROXYREF)orTP)->GetRealProxy());
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::GetMethodTableBeingProxied public
-//
-// Synopsis: Get the real type backing the transparent proxy
-//
-//+----------------------------------------------------------------------------
-MethodTable * CTPMethodTable::GetMethodTableBeingProxied(OBJECTREF orTP)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- SO_TOLERANT;
- PRECONDITION(orTP != NULL);
- PRECONDITION(orTP->IsTransparentProxy());
- }
- CONTRACTL_END;
-
- return ((TRANSPARENTPROXYREF)orTP)->GetMethodTableBeingProxied();
-}
-
-#define PAGE_ROUND_UP(cb) (((cb) + g_SystemInfo.dwAllocationGranularity) & ~(g_SystemInfo.dwAllocationGranularity - 1))
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::CreateTPMethodTable private
-//
-// Synopsis: (1) Reserves a transparent proxy method table that is large
-// enough to support the largest vtable
-// (2) Commits memory for the GC info of the global thunk table and
-// sets the cycle between the transparent proxy class and the
-// globale thunk table.
-//
-//+----------------------------------------------------------------------------
-
-void CTPMethodTable::CreateTPMethodTable(MethodTable* pTPMT)
-{
- CONTRACT_VOID {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(s_pThunkTable));
- } CONTRACT_END;
-
- // The largest possible vtable size 64K
- DWORD dwMaxSlots = 64*1024;
-
- // Allocate virtual memory that is big enough to hold a method table
- // of the maximum possible size
- DWORD dwReserveSize = 0;
- DWORD dwMethodTableReserveSize = (DWORD)(s_dwMTDataSlots * sizeof(PCODE));
- s_dwReservedTPIndirectionSlotSize = MethodTable::GetNumVtableIndirections(dwMaxSlots) * sizeof(PTR_PCODE);
- dwMethodTableReserveSize += s_dwReservedTPIndirectionSlotSize;
-
- dwMethodTableReserveSize += (DWORD)(dwMaxSlots * sizeof(PCODE));
- dwReserveSize = PAGE_ROUND_UP(dwMethodTableReserveSize);
-
- void *pAlloc = ::ClrVirtualAlloc(0, dwReserveSize, MEM_RESERVE | MEM_TOP_DOWN, PAGE_EXECUTE_READWRITE);
-
- if (pAlloc)
- {
- BOOL bFailed = TRUE;
-
- // Make sure that we have not created the one and only
- // transparent proxy method table before
- _ASSERTE(NULL == s_pThunkTable);
-
- // Commit the required amount of memory
- DWORD dwCommitSize = 0;
-
- // MethodTable memory
- DWORD dwMethodTableCommitSize = (s_dwMTDataSlots) * sizeof(PCODE);
- if (!ClrSafeInt<DWORD>::addition(0, dwMethodTableCommitSize, dwCommitSize))
- {
- COMPlusThrowHR(COR_E_OVERFLOW);
- }
-
- if (::ClrVirtualAlloc(pAlloc, dwCommitSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE))
- {
- // Copy the fixed portion from the true TP Method Table
- memcpy(pAlloc,MTToAlloc(pTPMT, s_dwGCInfoBytes), (dwMethodTableCommitSize));
-
- // Initialize the transparent proxy method table
- InitThunkTable(0, dwMaxSlots, AllocToMT((BYTE *) pAlloc, s_dwGCInfoBytes));
-
- // At this point the transparent proxy class points to the
- // the true TP Method Table and not the transparent
- // proxy method table. We do not use the true method table
- // any more. Instead we use the transparent proxy method table
- // for allocating transparent proxies. So, we have to make the
- // transparent proxy class point to the one and only transparent
- // proxy method table
- pTPMT->GetClass()->SetMethodTableForTransparentProxy(s_pThunkTable);
-
- // Allocate the slots of the Object class method table because
- // we can reflect on the __Transparent proxy class even though
- // we never intend to use remoting.
- _ASSERTE(NULL != g_pObjectClass);
- _ASSERTE(0 == GetCommitedTPSlots());
- if(ExtendCommitedSlots(g_pObjectClass->GetNumMethods()))
- bFailed = FALSE;
- }
- else
- {
- ClrVirtualFree(pAlloc, 0, MEM_RELEASE);
- }
-
- if(bFailed)
- DestroyThunkTable();
- }
- else {
- if (pAlloc != NULL)
- ::ClrVirtualFree(pAlloc, 0, MEM_RELEASE);
- }
-
- // Note that the thunk table is set to null on any failure path
- // via DestroyThunkTable
- if (!s_pThunkTable)
- COMPlusThrowOM();
-
- RETURN;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::ExtendCommitedSlots private
-//
-// Synopsis: Extends the commited slots of transparent proxy method table to
-// the desired number
-//
-//+----------------------------------------------------------------------------
-BOOL CTPMethodTable::ExtendCommitedSlots(_In_range_(1,64*1024) DWORD dwSlots)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- INJECT_FAULT(return FALSE);
- PRECONDITION(s_dwCommitedTPSlots <= dwSlots);
- PRECONDITION(dwSlots <= s_dwReservedTPSlots);
- PRECONDITION((CVirtualThunks::GetVirtualThunks() == NULL) ||
- (s_dwCommitedTPSlots == CVirtualThunks::GetVirtualThunks()->_dwCurrentThunk));
-
- // Either we have initialized everything or we are asked to allocate
- // some slots during initialization
- PRECONDITION(s_fTPTableFieldsInitialized || (0 == s_dwCommitedTPSlots));
- }
- CONTRACTL_END;
-
- // Commit memory for TPMethodTable
- BOOL bAlloc = FALSE;
- void *pAlloc = MTToAlloc(s_pThunkTable, s_dwGCInfoBytes);
- ClrSafeInt<DWORD> dwCommitSize;
- dwCommitSize += s_dwMTDataSlots * sizeof(PCODE);
- dwCommitSize += MethodTable::GetNumVtableIndirections(dwSlots) * sizeof(PTR_PCODE);
-
- DWORD dwLastIndirectionSlot = s_pThunkTable->GetIndexOfVtableIndirection(s_pThunkTable->GetNumVirtuals() - 1);
- DWORD dwSlotsCommitSize = dwSlots * sizeof(PCODE);
- PCODE *pAllocSlots = (PCODE*)(((BYTE*)s_pThunkTable) + s_dwMTDataSlots * sizeof(PCODE) + s_dwReservedTPIndirectionSlotSize);
-
- if (dwCommitSize.IsOverflow())
- {
- return FALSE; // error condition
- }
-
- if (::ClrVirtualAlloc(pAlloc, dwCommitSize.Value(), MEM_COMMIT, PAGE_EXECUTE_READWRITE) &&
- ::ClrVirtualAlloc(pAllocSlots, dwSlotsCommitSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE))
- {
- _ASSERTE(FitsIn<WORD>(dwSlots));
- s_pThunkTable->SetNumVirtuals((WORD)dwSlots);
-
- MethodTable::VtableIndirectionSlotIterator it = s_pThunkTable->IterateVtableIndirectionSlotsFrom(dwLastIndirectionSlot);
- do
- {
- it.SetIndirectionSlot(&pAllocSlots[it.GetStartSlot()]);
- }
- while (it.Next());
-
- bAlloc = AllocateThunks(dwSlots, dwCommitSize.Value());
- }
-
- return bAlloc;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::AllocateThunks private
-//
-// Synopsis: Allocates the desired number of thunks for virtual methods
-//
-//+----------------------------------------------------------------------------
-BOOL CTPMethodTable::AllocateThunks(DWORD dwSlots, DWORD dwCommitSize)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
- // Check for existing thunks
- DWORD dwCommitThunks = 0;
- DWORD dwAllocThunks = dwSlots;
- MethodTable *pThunkTable = s_pThunkTable;
-
- CVirtualThunks* pThunks = CVirtualThunks::GetVirtualThunks();
- if (pThunks)
- {
- // Compute the sizes of memory to be commited and allocated
- BOOL fCommit;
- if (dwSlots < pThunks->_dwReservedThunks)
- {
- fCommit = TRUE;
- dwCommitThunks = dwSlots;
- dwAllocThunks = 0;
- }
- else
- {
- fCommit = (pThunks->_dwCurrentThunk != pThunks->_dwReservedThunks);
- dwCommitThunks = pThunks->_dwReservedThunks;
- dwAllocThunks = dwSlots - pThunks->_dwReservedThunks;
- }
-
- // Commit memory if needed
- if (fCommit)
- {
- DWORD dwCommitSizeTmp = (sizeof(CVirtualThunks) - ConstVirtualThunkSize) +
- ((dwCommitThunks - pThunks->_dwStartThunk) * ConstVirtualThunkSize);
-
- if (!::ClrVirtualAlloc(pThunks, dwCommitSizeTmp, MEM_COMMIT, PAGE_EXECUTE_READWRITE))
- return(NULL);
-
- // Generate thunks that push slot number and jump to TP stub
- DWORD dwStartSlot = pThunks->_dwStartThunk;
- DWORD dwCurrentSlot = pThunks->_dwCurrentThunk;
- while (dwCurrentSlot < dwCommitThunks)
- {
- PCODE pCode = CreateThunkForVirtualMethod(dwCurrentSlot, (BYTE *)&pThunks->ThunkCode[dwCurrentSlot-dwStartSlot]);
- pThunkTable->SetSlot(dwCurrentSlot, pCode);
- ++dwCurrentSlot;
- }
-
- ClrFlushInstructionCache(&pThunks->ThunkCode[pThunks->_dwCurrentThunk-dwStartSlot],
- (dwCommitThunks-pThunks->_dwCurrentThunk)*ConstVirtualThunkSize);
-
- s_dwCommitedTPSlots = dwCommitThunks;
- pThunks->_dwCurrentThunk = dwCommitThunks;
- }
- }
-
- // <REVISIT_TODO>
- // Check for the avialability of a TP method table that is no longer being
- // reused </REVISIT_TODO>
-
- // Allocate memory if necessary
- if (dwAllocThunks)
- {
- DWORD dwReserveSize = ((sizeof(CVirtualThunks) - ConstVirtualThunkSize) +
- ((dwAllocThunks << 1) * ConstVirtualThunkSize) +
- g_SystemInfo.dwAllocationGranularity) & ~((size_t) g_SystemInfo.dwAllocationGranularity - 1);
-
- void *pAlloc = ::ClrVirtualAlloc(0, dwReserveSize,
- MEM_RESERVE | MEM_TOP_DOWN,
- PAGE_EXECUTE_READWRITE);
- if (pAlloc)
- {
- // Commit the required amount of memory
- DWORD dwCommitSizeTmp = (sizeof(CVirtualThunks) - ConstVirtualThunkSize) +
- (dwAllocThunks * ConstVirtualThunkSize);
-
- if (::ClrVirtualAlloc(pAlloc, dwCommitSizeTmp, MEM_COMMIT, PAGE_EXECUTE_READWRITE))
- {
- ((CVirtualThunks *) pAlloc)->_pNext = pThunks;
- pThunks = CVirtualThunks::SetVirtualThunks((CVirtualThunks *) pAlloc);
- pThunks->_dwReservedThunks = (dwReserveSize -
- (sizeof(CVirtualThunks) - ConstVirtualThunkSize)) /
- ConstVirtualThunkSize;
- pThunks->_dwStartThunk = dwCommitThunks;
- pThunks->_dwCurrentThunk = dwCommitThunks;
-
- // Generate thunks that push slot number and jump to TP stub
- DWORD dwStartSlot = pThunks->_dwStartThunk;
- DWORD dwCurrentSlot = pThunks->_dwCurrentThunk;
- while (dwCurrentSlot < dwSlots)
- {
- PCODE pCode = CreateThunkForVirtualMethod(dwCurrentSlot, (BYTE *)&pThunks->ThunkCode[dwCurrentSlot-dwStartSlot]);
- pThunkTable->SetSlot(dwCurrentSlot, pCode);
- ++dwCurrentSlot;
- }
-
- ClrFlushInstructionCache(&pThunks->ThunkCode[pThunks->_dwCurrentThunk-dwStartSlot],
- (dwSlots-pThunks->_dwCurrentThunk)*ConstVirtualThunkSize);
-
- s_dwCommitedTPSlots = dwSlots;
- pThunks->_dwCurrentThunk = dwSlots;
- }
- else
- {
- ::ClrVirtualFree(pAlloc, 0, MEM_RELEASE);
- return FALSE;
- }
- }
- else
- {
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::CreateTPOfClassForRP private
-//
-// Synopsis: Creates a transparent proxy that behaves as an object of the
-// supplied class
-//
-//+----------------------------------------------------------------------------
-void CTPMethodTable::CreateTPOfClassForRP(TypeHandle ty, REALPROXYREF *pRP, TRANSPARENTPROXYREF *pTP)
-{
- CONTRACT_VOID
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(!ty.IsNull());
- PRECONDITION(pRP != NULL);
- PRECONDITION(*pRP != NULL);
- PRECONDITION(pTP != NULL);
- POSTCONDITION(*pTP != NULL);
- }
- CONTRACT_END;
-
- // Ensure remoting is started.
- EnsureFieldsInitialized();
-
- MethodTable * pMT = ty.GetMethodTable();
-
- // Get the size of the VTable for the class to proxy
- DWORD dwSlots = pMT->GetNumVirtuals();
-
- if (dwSlots == 0)
- dwSlots = 1;
-
- // The global thunk table must have been initialized
- _ASSERTE(s_pThunkTable != NULL);
-
- // Check for the need to extend existing TP method table
- if (dwSlots > GetCommitedTPSlots())
- {
- CrstHolder ch(&s_TPMethodTableCrst);
-
- if (dwSlots > GetCommitedTPSlots())
- {
- if (!ExtendCommitedSlots(dwSlots))
- COMPlusThrowOM();
- }
- }
-
- // Create a TP Object
- IfNullThrow(*pTP = (TRANSPARENTPROXYREF) AllocateObject(GetMethodTable()));
-
- // Create the cycle between TP and RP
- (*pRP)->SetTransparentProxy(*pTP);
-
- // Make the TP behave as an object of supplied class
- (*pTP)->SetRealProxy(*pRP);
-
- // If we are creating a proxy for an interface then the class
- // is the object class else it is the class supplied
- if (pMT->IsInterface())
- {
- _ASSERTE(NULL != g_pObjectClass);
-
- (*pTP)->SetMethodTableBeingProxied(CRemotingServices::GetMarshalByRefClass());
-
- // Set the cached interface method table to the given interface
- // method table
- (*pTP)->SetInterfaceMethodTable(pMT);
- }
- else
- {
- (*pTP)->SetMethodTableBeingProxied(pMT);
- }
-
- RETURN;
-}
-
-Signature InitMessageData(messageData *msgData,
- FramedMethodFrame *pFrame,
- Module **ppModule,
- SigTypeContext *pTypeContext)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(msgData));
- PRECONDITION(CheckPointer(pFrame));
- PRECONDITION(CheckPointer(ppModule));
- PRECONDITION(CheckPointer(pTypeContext));
- }
- CONTRACTL_END;
-
- msgData->pFrame = pFrame;
- msgData->iFlags = 0;
-
- MethodDesc *pMD = pFrame->GetFunction();
- _ASSERTE(!pMD->ContainsGenericVariables());
- _ASSERTE(pMD->IsRuntimeMethodHandle());
-
- TypeHandle thGoverningType;
- BOOL fIsDelegate = pMD->GetMethodTable()->IsDelegate();
-
- // We want to calculate and store a governing type for the method since
- // sometimes the parent method table might be representative. We get the
- // exact type context from the this reference we're calling on (adjusting
- // for the fact it's a TP).
-
- // But cope with the common cases first for speed:
- // * If the method is not on a generic type and this is not the async
- // delegate case (which requires us to unwrap the delegate and have a
- // look) then we know the method desc's parent method table will be exact.
- // * We require method descs to be exact for the interface case as well (since
- // the target object doesn't help us resolve the interface type at all).
- // * COM interop can use this code path, but that doesn't support generics so
- // we can use the quick logic for that too.
- if ((!pMD->HasClassInstantiation() && !fIsDelegate) ||
- pMD->IsInterface() ||
- pMD->IsComPlusCall())
- {
- thGoverningType = TypeHandle(pMD->GetMethodTable());
- }
- else
- {
- MethodDesc *pTargetMD;
- MethodTable *pTargetMT;
- if (fIsDelegate)
- {
- // Async delegates are also handled differently in that the method and the
- // this are delegate wrappers round the real method and target.
- pTargetMD = COMDelegate::GetMethodDesc(pFrame->GetThis());
-
- // Delegates on static methods don't have a useful target instance.
- // But in that case the target method is guaranteed to have exact
- // type information.
- if (pTargetMD->IsStatic())
- pTargetMT = pTargetMD->GetMethodTable();
- else
- {
- OBJECTREF refDelegateTarget = COMDelegate::GetTargetObject(pFrame->GetThis());
- pTargetMT = refDelegateTarget->GetTrueMethodTable();
- }
- }
- else
- {
- pTargetMD = pMD;
- pTargetMT = CTPMethodTable::GetMethodTableBeingProxied(pFrame->GetThis());
- }
-
- // One last check to see if we can optimize the delegate case now we've
- // unwrapped it.
- if (fIsDelegate && !pTargetMD->HasClassInstantiation() && !pTargetMT->IsDelegate())
- {
- thGoverningType = TypeHandle(pTargetMD->GetMethodTable());
- }
- else
- {
- // Not quite done yet, we need to get the type that declares the method,
- // which may be a superclass of the type we're calling on.
- MethodTable *pDeclaringMT = pTargetMD->GetMethodTable();
- thGoverningType = ClassLoader::LoadGenericInstantiationThrowing(pDeclaringMT->GetModule(),
- pDeclaringMT->GetCl(),
- pTargetMD->GetExactClassInstantiation(TypeHandle(pTargetMT)));
- }
- }
-
- msgData->thGoverningType = thGoverningType;
-
- if (fIsDelegate)
- {
- DelegateEEClass* delegateCls = (DelegateEEClass*) pMD->GetMethodTable()->GetClass();
-
- _ASSERTE(pFrame->GetThis()->GetMethodTable()->IsDelegate());
-
- msgData->pDelegateMD = pMD;
- msgData->pMethodDesc = COMDelegate::GetMethodDesc(pFrame->GetThis());
-
- _ASSERTE(msgData->pMethodDesc != NULL);
- _ASSERTE(!msgData->pMethodDesc->ContainsGenericVariables());
- _ASSERTE(msgData->pMethodDesc->IsRuntimeMethodHandle());
-
- if (pMD == delegateCls->m_pBeginInvokeMethod)
- {
- msgData->iFlags |= MSGFLG_BEGININVOKE;
- }
- else
- {
- _ASSERTE(pMD == delegateCls->m_pEndInvokeMethod);
- msgData->iFlags |= MSGFLG_ENDINVOKE;
- }
- }
- else
- {
- msgData->pDelegateMD = NULL;
- msgData->pMethodDesc = pMD;
- _ASSERTE(msgData->pMethodDesc->IsRuntimeMethodHandle());
- }
-
- if (msgData->pMethodDesc->IsOneWay())
- {
- msgData->iFlags |= MSGFLG_ONEWAY;
- }
-
- if (msgData->pMethodDesc->IsCtor())
- {
- msgData->iFlags |= MSGFLG_CTOR;
- }
-
- Signature signature;
- Module *pModule;
-
- if (msgData->pDelegateMD)
- {
- signature = msgData->pDelegateMD->GetSignature();
- pModule = msgData->pDelegateMD->GetModule();
-
- // If the delegate is generic, pDelegateMD may not represent the exact instantiation so we recover it from 'this'.
- SigTypeContext::InitTypeContext(pFrame->GetThis()->GetMethodTable()->GetInstantiation(), Instantiation(), pTypeContext);
- }
- else if (msgData->pMethodDesc->IsVarArg())
- {
- VASigCookie *pVACookie = pFrame->GetVASigCookie();
- signature = pVACookie->signature;
- pModule = pVACookie->pModule;
- SigTypeContext::InitTypeContext(pTypeContext);
-
- }
- else
- {
- signature = msgData->pMethodDesc->GetSignature();
- pModule = msgData->pMethodDesc->GetModule();
- SigTypeContext::InitTypeContext(msgData->pMethodDesc, thGoverningType, pTypeContext);
- }
-
- *ppModule = pModule;
- return signature;
-}
-
-VOID CRealProxy::UpdateOptFlags(OBJECTREF refTP)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
-
- DWORD hierarchyDepth = 0;
- REALPROXYREF refRP = CTPMethodTable::GetRP(refTP);
-
- OBJECTHANDLE hServerIdentity = (OBJECTHANDLE)refRP->GetPtrOffset(CRemotingServices::GetOffsetOfSrvIdentityInRP());
- if (hServerIdentity == NULL)
- return;
-
- // Check if the proxy has already been marked as not equivalent.
- // In which case, it can never get marked as anything else
- RealProxyObject *rpTemp = (RealProxyObject *)OBJECTREFToObject(refRP);
-
- DWORD domainID = rpTemp->GetDomainID();
- AppDomainFromIDHolder ad((ADID)domainID, TRUE);
- if (domainID == 0 || ad.IsUnloaded()) //we do not use ptr
- return; // The appdomain the server belongs to, has been unloaded
- ad.Release();
- DWORD optFlag = rpTemp->GetOptFlags();
- if ((optFlag & OPTIMIZATION_FLAG_INITTED) &&
- !(optFlag & OPTIMIZATION_FLAG_PROXY_EQUIVALENT))
- return;
-
- OBJECTREF refSrvIdentity = ObjectFromHandle(hServerIdentity);
- // Is this a disconnected proxy ?
- if (refSrvIdentity == NULL)
- return;
-
- OBJECTREF refSrvObject = ObjectToOBJECTREF((Object *)refSrvIdentity->GetPtrOffset(CRemotingServices::GetOffsetOfTPOrObjInIdentity()));
-
- MethodTable *pCliMT = CTPMethodTable::GetMethodTableBeingProxied(refTP);
-
- BOOL bProxyQualifies = FALSE;
- BOOL bCastToSharedType = FALSE;
-
- // Check if modules are physically the same
-
- // Check the inheritance hierarchy of the server object, to find the type
- // that corresponds to the type the proxy is being cast to
- // @TODO - If being cast to an interface, currently the proxy doesnt get marked equivalent
- // @TODO - Need to check equivalency of the interface being cast to, and then reuse interface slot # on other side
- LPCUTF8 szCliTypeName, szCliNameSpace;
- szCliTypeName = pCliMT->GetFullyQualifiedNameInfo(&szCliNameSpace);
- PREFIX_ASSUME(szCliTypeName != NULL);
-
- MethodTable *pSrvHierarchy = refSrvObject->GetMethodTable();
-
- GCPROTECT_BEGIN(refRP);
- while (pSrvHierarchy)
- {
- LPCUTF8 szSrvTypeName, szSrvNameSpace;
- szSrvTypeName = pSrvHierarchy->GetFullyQualifiedNameInfo(&szSrvNameSpace);
- PREFIX_ASSUME(szSrvNameSpace != NULL);
-
- if (!strcmp(szCliTypeName, szSrvTypeName) && !strcmp(szCliNameSpace, szSrvNameSpace))
- {
- // Check if the types are shared. If they are, no further check neccesary
- if (pSrvHierarchy == pCliMT)
- {
- bProxyQualifies = TRUE;
- bCastToSharedType = TRUE;
- }
- else
- {
- bProxyQualifies = CRealProxy::ProxyTypeIdentityCheck(pCliMT, pSrvHierarchy);
- }
- break;
- }
-
- pSrvHierarchy = pSrvHierarchy->GetParentMethodTable();
- hierarchyDepth++;
- }
- GCPROTECT_END();
-
- optFlag = 0;
- if (bProxyQualifies && hierarchyDepth < OPTIMIZATION_FLAG_DEPTH_MASK)
- {
- optFlag = OPTIMIZATION_FLAG_INITTED | OPTIMIZATION_FLAG_PROXY_EQUIVALENT;
- if (bCastToSharedType)
- optFlag |= OPTIMIZATION_FLAG_PROXY_SHARED_TYPE;
- optFlag |= (hierarchyDepth & OPTIMIZATION_FLAG_DEPTH_MASK);
- }
- else
- optFlag = OPTIMIZATION_FLAG_INITTED;
-
- RealProxyObject *rpUNSAFE = (RealProxyObject *)OBJECTREFToObject(refRP);
- rpUNSAFE->SetOptFlags(optFlag);
-}
-
-BOOL CRealProxy::ProxyTypeIdentityCheck(MethodTable *pCliHierarchy, MethodTable *pSrvHierarchy)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- THROWS;
- }
- CONTRACTL_END
- // We have found the server side type that corresponds to the most derived type
- // on client side, that the proxy is cast to
- // Now do identity check on the server type hierarchy to see if there is an exact match
-
- BOOL bProxyQualifies = FALSE;
- do
- {
- LPCUTF8 szCliTypeName, szCliNameSpace;
- LPCUTF8 szSrvTypeName, szSrvNameSpace;
- szCliTypeName = pCliHierarchy->GetFullyQualifiedNameInfo(&szCliNameSpace);
- szSrvTypeName = pSrvHierarchy->GetFullyQualifiedNameInfo(&szSrvNameSpace);
- PREFIX_ASSUME(szCliTypeName != NULL);
- PREFIX_ASSUME(szSrvNameSpace != NULL);
-
- // If type names are different, there is no match
- if (strcmp(szCliTypeName, szSrvTypeName) ||
- strcmp(szCliNameSpace, szSrvNameSpace))
- {
- bProxyQualifies = FALSE;
- return bProxyQualifies;
- }
-
- PEAssembly *pClientPE = pCliHierarchy->GetAssembly()->GetManifestFile();
- PEAssembly *pServerPE = pSrvHierarchy->GetAssembly()->GetManifestFile();
- // If the PE files are different, there is no match
- if (!pClientPE->Equals(pServerPE))
- {
- bProxyQualifies = FALSE;
- return bProxyQualifies;
- }
-
- // If the number of interfaces implemented are different, there is no match
- if (pSrvHierarchy->GetNumInterfaces() != pCliHierarchy->GetNumInterfaces())
- {
- bProxyQualifies = FALSE;
- return bProxyQualifies;
- }
-
- MethodTable::InterfaceMapIterator srvItfIt = pSrvHierarchy->IterateInterfaceMap();
- MethodTable::InterfaceMapIterator cliItfIt = pCliHierarchy->IterateInterfaceMap();
- while (srvItfIt.Next())
- {
- BOOL succeeded;
- succeeded = cliItfIt.Next();
- CONSISTENCY_CHECK(succeeded);
- if (!ProxyTypeIdentityCheck(srvItfIt.GetInterface(), cliItfIt.GetInterface()))
- {
- bProxyQualifies = FALSE;
- return bProxyQualifies;
- }
- }
-
- pSrvHierarchy = pSrvHierarchy->GetParentMethodTable();
- pCliHierarchy = pCliHierarchy->GetParentMethodTable();
- }
- while (pSrvHierarchy && pCliHierarchy);
-
- if (pSrvHierarchy || pCliHierarchy)
- {
- bProxyQualifies = FALSE;
- return bProxyQualifies;
- }
-
- bProxyQualifies = TRUE;
- return bProxyQualifies;
-
-}
-
-ProfilerRemotingClientCallbackHolder::ProfilerRemotingClientCallbackHolder()
-{
-#ifdef PROFILING_SUPPORTED
- // If profiling is active, notify it that remoting stuff is kicking in
- BEGIN_PIN_PROFILER(CORProfilerTrackRemoting());
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->RemotingClientInvocationStarted();
- END_PIN_PROFILER();
-#endif // PROFILING_SUPPORTED
-}
-
-ProfilerRemotingClientCallbackHolder::~ProfilerRemotingClientCallbackHolder()
-{
-#ifdef PROFILING_SUPPORTED
- // If profiling is active, tell profiler we've made the call, received the
- // return value, done any processing necessary, and now remoting is done.
- BEGIN_PIN_PROFILER(CORProfilerTrackRemoting());
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->RemotingClientInvocationFinished();
- END_PIN_PROFILER();
-#endif // PROFILING_SUPPORTED
-}
-
-enum
-{
- CALLTYPE_INVALIDCALL = 0x0, // Important:: sync this with RealProxy.cs
- CALLTYPE_METHODCALL = 0x1, // Important:: sync this with RealProxy.cs
- CALLTYPE_CONSTRUCTORCALL = 0x2 // Important:: sync this with RealProxy.cs
-};
-
-extern "C" void STDCALL TransparentProxyStubPatch();
-
-//+----------------------------------------------------------------------------
-//
-// Method: TransparentProxyStubWorker
-//
-// Synopsis: This function gets control in two situations
-// (1) When a call is made on the transparent proxy it delegates to
-// PrivateInvoke method on the real proxy
-// (2) When a call is made on the constructor it again delegates to the
-// PrivateInvoke method on the real proxy.
-//
-//
-//+----------------------------------------------------------------------------
-extern "C" UINT32 STDCALL TransparentProxyStubWorker(TransitionBlock * pTransitionBlock, TADDR pMethodDescOrSlot)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- ENTRY_POINT;
- PRECONDITION(CheckPointer(pTransitionBlock));
- }
- CONTRACTL_END;
-
- UINT fpRetSize = 0;
-
- FrameWithCookie<TPMethodFrame> frame(pTransitionBlock);
- TPMethodFrame * pFrame = &frame;
-
- //we need to zero out the return value buffer because we will report it during GC
-#ifdef ENREGISTERED_RETURNTYPE_MAXSIZE
- ZeroMemory (pFrame->GetReturnValuePtr(), ENREGISTERED_RETURNTYPE_MAXSIZE);
-#else
- *(ARG_SLOT *)pFrame->GetReturnValuePtr() = 0;
-#endif
-
- // For virtual calls the slot number is pushed but for
- // non virtual calls/interface invoke the method descriptor is already
- // pushed
- MethodDesc * pMD;
- if ((pMethodDescOrSlot >> 16) == 0)
- {
- // The frame is not completly setup at this point.
- // Do not throw exceptions or provoke GC
- MethodTable* pMT = CTPMethodTable::GetMethodTableBeingProxied(pFrame->GetThis());
- _ASSERTE(pMT);
-
- // Replace the slot number with the method descriptor on the stack
- pMD = pMT->GetMethodDescForSlot((WORD)pMethodDescOrSlot);
- }
- else
- {
- pMD = dac_cast<PTR_MethodDesc>(pMethodDescOrSlot);
- }
- pFrame->SetFunction(pMD);
-
- pFrame->Push();
-
- // Give debugger opportunity to stop here now that we know the MethodDesc *
- TransparentProxyStubPatch();
-
- INSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
- if (g_pConfig->UseNewCrossDomainRemoting())
- {
- BOOL bOptSuccess = FALSE;
- CrossDomainChannel cdc;
- bOptSuccess = cdc.CheckCrossDomainCall(pFrame);
- if (bOptSuccess)
- {
- fpRetSize = cdc.GetFPReturnSize();
- goto Done;
- }
- }
-
- {
- messageData msgData;
- Module *pModule = NULL;
- SigTypeContext inst;
- Signature signature = InitMessageData(&msgData, pFrame, &pModule, &inst);
-
- _ASSERTE(!signature.IsEmpty() && pModule);
-
- // Allocate metasig on the stack
- MetaSig mSig(signature, pModule, &inst);
- msgData.pSig = &mSig;
-
- MethodDesc *pMD = pFrame->GetFunction();
- if (pMD->GetMethodTable()->IsDelegate())
- {
- // check that there is only one target
- if (COMDelegate::IsTrueMulticastDelegate(pFrame->GetThis()))
- {
- COMPlusThrow(kArgumentException, W("Remoting_Delegate_TooManyTargets"));
- }
- }
-
- {
- ProfilerRemotingClientCallbackHolder profilerHolder;
-
- OBJECTREF pThisPointer = NULL;
-
- if (pMD->GetMethodTable()->IsDelegate())
- {
- // this is an async call
- _ASSERTE(pFrame->GetThis()->GetMethodTable()->IsDelegate());
-
- pThisPointer = COMDelegate::GetTargetObject(pFrame->GetThis());
- }
- else
- {
- pThisPointer = pFrame->GetThis();
- }
-
- OBJECTREF firstParameter;
- MethodDesc* pTargetMD = NULL;
- size_t callType = CALLTYPE_INVALIDCALL;
-
- // We are invoking either the constructor or a method on the object
- if(pMD->IsCtor())
- {
- // Get the address of PrivateInvoke in managed code
- pTargetMD = CRemotingServices::MDofPrivateInvoke();
- _ASSERTE(pThisPointer->IsTransparentProxy());
-
- firstParameter = CTPMethodTable::GetRP(pThisPointer);
-
- // Set a field to indicate that it is a constructor call
- callType = CALLTYPE_CONSTRUCTORCALL;
- }
- else
- {
- // Set a field to indicate that it is a method call
- callType = CALLTYPE_METHODCALL;
-
- if (pThisPointer->IsTransparentProxy())
- {
- // Extract the real proxy underlying the transparent proxy
- firstParameter = CTPMethodTable::GetRP(pThisPointer);
-
- // Get the address of PrivateInvoke in managed code
- pTargetMD = CRemotingServices::MDofPrivateInvoke();
- _ASSERTE(pTargetMD);
- }
- else
- {
- // must be async if this is not a TP
- _ASSERTE(pMD->GetMethodTable()->IsDelegate());
- firstParameter = NULL;
-
- // Get the address of PrivateInvoke in managed code
- pTargetMD = CRemotingServices::MDofInvokeStatic();
- }
-
- // Go ahead and call PrivateInvoke on Real proxy. There is no need to
- // catch exceptions thrown by it
- // See RealProxy.cs
- }
-
- _ASSERTE(pTargetMD);
-
- // Call the appropriate target
- CTPMethodTable::CallTarget(pTargetMD, (LPVOID)OBJECTREFToObject(firstParameter), (LPVOID)&msgData, (LPVOID)callType);
-
- // Check for the need to trip thread
- if (GetThread()->CatchAtSafePointOpportunistic())
- {
- // There is no need to GC protect the return object as
- // TPFrame is GC protecting it
- CommonTripThread();
- }
- } // ProfilerClientCallbackHolder
-
- {
- mSig.Reset();
-
- ArgIterator argit(&mSig);
-
-#ifdef _TARGET_X86_
- // Set the number of bytes to pop for x86
- pFrame->SetCbStackPop(argit.CbStackPop());
-#endif // _TARGET_X86_
-
- fpRetSize = argit.GetFPReturnSize();
- }
- }
-
-Done: ;
-
- pFrame->Pop();
-
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
-
- return fpRetSize;
-}
-
-
-// Helper due to inability to combine SEH with anything interesting.
-BOOL CTPMethodTable::CheckCastHelper(MethodDesc* pTargetMD, LPVOID pFirst, LPVOID pSecond)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pTargetMD));
- PRECONDITION(CheckPointer(pFirst, NULL_OK));
- PRECONDITION(CheckPointer(pSecond, NULL_OK));
- }
- CONTRACTL_END;
-
- // Actual return type is a managed 'bool', so only look at a CLR_BOOL-sized
- // result. The high bits are undefined on AMD64. (Note that a narrowing
- // cast to CLR_BOOL will not work since it is the same as checking the
- // size_t result != 0.)
- LPVOID ret = CallTarget(pTargetMD, pFirst, pSecond);
- return *(CLR_BOOL*)StackElemEndianessFixup(&ret, sizeof(CLR_BOOL));
-}
-
-
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::CheckCast private
-//
-// Synopsis: Call the managed checkcast method to determine whether the
-// server type can be cast to the given type
-//
-//
-//
-//+----------------------------------------------------------------------------
-BOOL CTPMethodTable::CheckCast(MethodDesc* pTargetMD, TRANSPARENTPROXYREF orTP, TypeHandle ty)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pTargetMD));
- PRECONDITION(orTP != NULL);
- PRECONDITION(!ty.IsNull());
- }
- CONTRACTL_END;
-
- REFLECTCLASSBASEREF reflectType = NULL;
- LPVOID pvType = NULL;
- BOOL fCastOK = FALSE;
-
- typedef struct _GCStruct
- {
- TRANSPARENTPROXYREF orTP;
- REALPROXYREF orRP;
- } GCStruct;
-
- GCStruct gcValues;
- gcValues.orTP = orTP;
- gcValues.orRP = GetRP(orTP);
-
- GCPROTECT_BEGIN (gcValues);
-
- reflectType = (REFLECTCLASSBASEREF) ty.GetMethodTable()->GetManagedClassObject();
- *(REFLECTCLASSBASEREF *)&pvType = reflectType;
-
- fCastOK = CheckCastHelper(pTargetMD,
- (LPVOID)OBJECTREFToObject(gcValues.orRP),
- pvType);
-
- if (fCastOK)
- {
- _ASSERTE(s_fTPTableFieldsInitialized);
-
- // The cast succeeded. Replace the current type in the proxy
- // with the given type.
-
- CrstHolder ch(&s_TPMethodTableCrst);
-
- if (ty.IsInterface())
- {
- // We replace the cached interface method table with the interface
- // method table that we are trying to cast to. This will ensure that
- // casts to this interface, which are likely to happen, will succeed.
- gcValues.orTP->SetInterfaceMethodTable(ty.GetMethodTable());
- }
- else
- {
- MethodTable *pCurrent = gcValues.orTP->GetMethodTableBeingProxied();
-
- BOOL fDerivedClass = FALSE;
- // Check whether this class derives from the current class
- fDerivedClass = CRemotingServices::CheckCast(gcValues.orTP, ty,
- TypeHandle(pCurrent));
- // We replace the current method table only if we cast to a more
- // derived class
- if (fDerivedClass)
- {
- // Set the method table in the proxy to the given method table
- RefineProxy(gcValues.orTP, ty);
- }
- }
- }
-
- GCPROTECT_END();
- return fCastOK;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::RefineProxy public
-//
-// Synopsis: Set the method table in the proxy to the given class' method table.
-// Additionally, expand the TP method table to the required number of slots.
-//
-//
-//+----------------------------------------------------------------------------
-void CTPMethodTable::RefineProxy(TRANSPARENTPROXYREF orTP, TypeHandle ty)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(orTP != NULL);
- PRECONDITION(!ty.IsNull());
- }
- CONTRACTL_END;
-
- // Do the expansion only if necessary
- MethodTable *pMT = ty.GetMethodTable();
-
- if (pMT != orTP->GetMethodTableBeingProxied())
- {
- orTP->SetMethodTableBeingProxied(pMT);
-
- // Extend the vtable if necessary
- DWORD dwSlots = pMT->GetNumVirtuals();
-
- if (dwSlots == 0)
- dwSlots = 1;
-
- if((dwSlots > GetCommitedTPSlots()) && !ExtendCommitedSlots(dwSlots))
- {
- // We failed to extend the committed slots. Out of memory.
- COMPlusThrowOM();
- }
-
- }
-}
-
-#ifndef HAS_REMOTING_PRECODE
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::GetOrCreateNonVirtualSlotForVirtualMethod private
-//
-// Synopsis: Get a slot for a non-virtual call to a virtual method.
-//
-//+----------------------------------------------------------------------------
-PTR_PCODE CTPMethodTable::GetOrCreateNonVirtualSlotForVirtualMethod(MethodDesc* pMD)
-{
- CONTRACT (PTR_PCODE)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pMD));
- PRECONDITION(pMD->IsRemotingInterceptedViaVirtualDispatch());
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- // Ensure the TP MethodTable's fields have been initialized.
- EnsureFieldsInitialized();
-
- PTR_PCODE pSlot;
-
- {
- // Create the thunk in a thread safe manner
- CrstHolder ch(&s_TPMethodTableCrst);
-
- // NOTE: CNonVirtualThunk::SetNonVirtualThunks() depends on the lock being initialized
- CNonVirtualThunk::InitializeListLock();
-
- // Create hash table if we do not have one yet
- if (s_pThunkHashTable == NULL)
- {
- NewHolder <EEThunkHashTable> pTempHash(new EEThunkHashTable());
-
- LockOwner lock = {&s_TPMethodTableCrst, IsOwnerOfCrst};
- IfNullThrow(pTempHash->Init(23,&lock));
-
- s_pThunkHashTable = pTempHash.Extract();
- }
-
- if (!s_pThunkHashTable->GetValue(pMD, (HashDatum *)&pSlot))
- {
- PCODE pThunkCode = CreateNonVirtualThunkForVirtualMethod(pMD);
-
- _ASSERTE(CNonVirtualThunkMgr::IsThunkByASM(pThunkCode));
- _ASSERTE(CNonVirtualThunkMgr::GetMethodDescByASM(pThunkCode));
-
- // Set the generated thunk once and for all..
- CNonVirtualThunk *pThunk = CNonVirtualThunk::SetNonVirtualThunks((BYTE*)pThunkCode);
-
- // Remember the thunk address in a hash table
- // so that we dont generate it again
- pSlot = (PTR_PCODE)pThunk->GetAddrOfCode();
- s_pThunkHashTable->InsertValue(pMD, (HashDatum)pSlot);
- }
- }
-
- RETURN pSlot;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::DestroyThunk public
-//
-// Synopsis: Destroy the thunk for the non virtual method.
-//
-//
-//+----------------------------------------------------------------------------
-void CTPMethodTable::DestroyThunk(MethodDesc* pMD)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pMD));
- }
- CONTRACTL_END;
-
- if(s_pThunkHashTable)
- {
- CrstHolder ch(&s_TPMethodTableCrst);
-
- LPVOID pvCode = NULL;
- s_pThunkHashTable->GetValue(pMD, (HashDatum *)&pvCode);
- CNonVirtualThunk *pThunk = NULL;
- if(NULL != pvCode)
- {
- pThunk = CNonVirtualThunk::AddrToThunk(pvCode);
- delete pThunk;
- s_pThunkHashTable->DeleteValue(pMD);
- }
- }
-}
-#endif // HAS_REMOTING_PRECODE
-
-static LPVOID CallTargetWorker1(MethodDesc* pTargetMD,
- LPVOID pvFirst,
- LPVOID pvSecond)
-{
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_MODE_COOPERATIVE;
- STATIC_CONTRACT_SO_INTOLERANT;
-
- LPVOID ret = NULL;
- PCODE pTarget = pTargetMD->GetSingleCallableAddrOfCode();
-
-#if defined(DEBUGGING_SUPPORTED)
- if (CORDebuggerTraceCall())
- {
- g_pDebugInterface->TraceCall((const BYTE*)pTarget);
- }
-#endif // DEBUGGING_SUPPORTED
-
-
- BEGIN_CALL_TO_MANAGED();
-
- ret = CTPMethodTable__CallTargetHelper2((const BYTE*)pTarget, pvFirst, pvSecond);
-
- END_CALL_TO_MANAGED();
-
- return ret;
-}
-
-
-//+----------------------------------------------------------------------------
-//
-// Method: CTPMethodTable::CallTarget private
-//
-// Synopsis: Calls the target method on the given object
-//
-//+----------------------------------------------------------------------------
-LPVOID __stdcall CTPMethodTable::CallTarget (MethodDesc* pTargetMD,
- LPVOID pvFirst,
- LPVOID pvSecond)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- SO_INTOLERANT;
- PRECONDITION(CheckPointer(pTargetMD));
- PRECONDITION(CheckPointer(pvFirst, NULL_OK));
- PRECONDITION(CheckPointer(pvSecond, NULL_OK));
- }
- CONTRACTL_END;
-
-#ifdef _DEBUG
-
- Thread* curThread = GetThread();
-
- Object* ObjRefTable[OBJREF_TABSIZE];
-
- if (curThread)
- memcpy(ObjRefTable, curThread->dangerousObjRefs, sizeof(curThread->dangerousObjRefs));
-
-#endif // _DEBUG
-
- LPVOID ret = CallTargetWorker1(pTargetMD, pvFirst, pvSecond);
-
-#ifdef _DEBUG
- // Restore dangerousObjRefs when we return back to EE after call
- if (curThread)
- memcpy(curThread->dangerousObjRefs, ObjRefTable, sizeof(curThread->dangerousObjRefs));
-
- ENABLESTRESSHEAP ();
-#endif // _DEBUG
-
- return ret;
-}
-
-
-static LPVOID CallTargetWorker2(MethodDesc* pTargetMD,
- LPVOID pvFirst,
- LPVOID pvSecond,
- LPVOID pvThird)
-{
- STATIC_CONTRACT_THROWS;
- STATIC_CONTRACT_GC_TRIGGERS;
- STATIC_CONTRACT_MODE_COOPERATIVE;
- STATIC_CONTRACT_SO_INTOLERANT;
-
- LPVOID ret = NULL;
- PCODE pTarget = pTargetMD->GetSingleCallableAddrOfCode();
-
-#if defined(DEBUGGING_SUPPORTED)
- if (CORDebuggerTraceCall())
- {
- g_pDebugInterface->TraceCall((const BYTE*)pTarget);
- }
-#endif // DEBUGGING_SUPPORTED
-
- BEGIN_CALL_TO_MANAGED();
-
- ret = CTPMethodTable__CallTargetHelper3((const BYTE*)pTarget, pvFirst, pvSecond, pvThird);
-
- END_CALL_TO_MANAGED();
- return ret;
-
-}
-
-LPVOID __stdcall CTPMethodTable::CallTarget (MethodDesc* pTargetMD,
- LPVOID pvFirst,
- LPVOID pvSecond,
- LPVOID pvThird)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- SO_INTOLERANT;
- PRECONDITION(CheckPointer(pTargetMD));
- PRECONDITION(CheckPointer(pvFirst, NULL_OK));
- PRECONDITION(CheckPointer(pvSecond, NULL_OK));
- PRECONDITION(CheckPointer(pvThird, NULL_OK));
- }
- CONTRACTL_END;
-
-#ifdef _DEBUG
- Thread* curThread = GetThread();
-
- Object* ObjRefTable[OBJREF_TABSIZE];
- if (curThread)
- memcpy(ObjRefTable, curThread->dangerousObjRefs, sizeof(curThread->dangerousObjRefs));
-
-#endif // _DEBUG
-
- LPVOID ret = CallTargetWorker2(pTargetMD, pvFirst, pvSecond, pvThird);
-
-#ifdef _DEBUG
- // Restore dangerousObjRefs when we return back to EE after call
- if (curThread)
- memcpy(curThread->dangerousObjRefs, ObjRefTable, sizeof(curThread->dangerousObjRefs));
-
- ENABLESTRESSHEAP ();
-#endif // _DEBUG
-
- return ret;
-}
-
-
-#ifndef HAS_REMOTING_PRECODE
-//+----------------------------------------------------------------------------
-//
-// Method: CNonVirtualThunk::SetNextThunk public
-//
-// Synopsis: Creates a thunk for the given address and adds it to the global
-// list
-//
-//+----------------------------------------------------------------------------
-CNonVirtualThunk* CNonVirtualThunk::SetNonVirtualThunks(const BYTE* pbCode)
-{
- CONTRACT (CNonVirtualThunk*)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pbCode));
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- CNonVirtualThunk *pThunk = new CNonVirtualThunk(pbCode);
-
- // Put the generated thunk in a global list
- // Note: this is called when a NV thunk is being created ..
- // The TPMethodTable critsec is held at this point
- pThunk->SetNextThunk();
-
- // Set up the stub manager if necessary
- CNonVirtualThunkMgr::InitNonVirtualThunkManager();
-
- RETURN pThunk;
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CNonVirtualThunk::~CNonVirtualThunk public
-//
-// Synopsis: Deletes the thunk from the global list of thunks
-//
-//
-//+----------------------------------------------------------------------------
-CNonVirtualThunk::~CNonVirtualThunk()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(s_pNonVirtualThunks));
- }
- CONTRACTL_END;
-
- CNonVirtualThunk* pCurr = s_pNonVirtualThunks;
- CNonVirtualThunk* pPrev = NULL;
- BOOL found = FALSE;
-
- // Note: This is called with the TPMethodTable critsec held
- while(!found && (NULL != pCurr))
- {
- if(pCurr == this)
- {
- found = TRUE;
- SimpleRWLock::SimpleWriteLockHolder swlh(s_pNonVirtualThunksListLock);
-
- // Unlink from the chain
- if(NULL != pPrev)
- {
- pPrev->_pNext = pCurr->_pNext;
- }
- else
- {
- // First entry needs to be deleted
- s_pNonVirtualThunks = pCurr->_pNext;
- }
- }
- pPrev = pCurr;
- pCurr = pCurr->_pNext;
- }
-
- _ASSERTE(found);
-}
-#endif // HAS_REMOTING_PRECODE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CVirtualThunkMgr::InitVirtualThunkManager public
-//
-// Synopsis: Adds the stub manager to aid debugger in stepping into calls
-//
-//
-//+----------------------------------------------------------------------------
-void CVirtualThunkMgr::InitVirtualThunkManager()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- }
- CONTRACTL_END;
-
- // This is function is already threadsafe since this method is called from within a
- // critical section
- if(NULL == s_pVirtualThunkMgr)
- {
- // Add the stub manager for vtable calls
- s_pVirtualThunkMgr = new CVirtualThunkMgr();
-
- StubManager::AddStubManager(s_pVirtualThunkMgr);
- }
-
-}
-
-#endif // !DACCESS_COMPILE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CVirtualThunkMgr::CheckIsStub_Internal public
-//
-// Synopsis: Returns TRUE if the given address is the starting address of
-// the transparent proxy stub
-//
-//+----------------------------------------------------------------------------
-BOOL CVirtualThunkMgr::CheckIsStub_Internal(PCODE stubStartAddress)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SUPPORTS_DAC;
- }
- CONTRACTL_END;
-
- BOOL bIsStub = FALSE;
-
-#ifndef DACCESS_COMPILE
- if (!IsThunkByASM(stubStartAddress))
- return FALSE;
- if(NULL != FindThunk((const BYTE *) stubStartAddress))
- bIsStub = TRUE;
-#endif // !DACCESS_COMPILE
-
- return bIsStub;
-}
-
-#ifndef DACCESS_COMPILE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CVirtualThunkMgr::Entry2MethodDesc public
-//
-// Synopsis: Convert a starting address to a MethodDesc
-//
-//+----------------------------------------------------------------------------
-MethodDesc *CVirtualThunkMgr::Entry2MethodDesc(PCODE StubStartAddress, MethodTable *pMT)
-{
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pMT, NULL_OK));
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END;
-
- if (s_pVirtualThunkMgr == NULL)
- RETURN NULL;
-
- if (!pMT)
- RETURN NULL;
-
- if (!s_pVirtualThunkMgr->CheckIsStub_Internal(StubStartAddress))
- RETURN NULL;
-
- RETURN GetMethodDescByASM(StubStartAddress, pMT);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CVirtualThunkMgr::FindThunk private
-//
-// Synopsis: Finds a thunk that matches the given starting address
-//
-//+----------------------------------------------------------------------------
-LPBYTE CVirtualThunkMgr::FindThunk(const BYTE *stubStartAddress)
-{
- CONTRACT (LPBYTE)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(stubStartAddress, NULL_OK));
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- SO_TOLERANT;
- }
- CONTRACT_END;
-
- CVirtualThunks* pThunks = CVirtualThunks::GetVirtualThunks();
- LPBYTE pThunkAddr = NULL;
-
- while(NULL != pThunks)
- {
- DWORD dwStartSlot = pThunks->_dwStartThunk;
- DWORD dwCurrSlot = pThunks->_dwStartThunk;
- DWORD dwMaxSlot = pThunks->_dwCurrentThunk;
- while (dwCurrSlot < dwMaxSlot)
- {
- LPBYTE pStartAddr = pThunks->ThunkCode[dwCurrSlot-dwStartSlot].pCode;
- if((stubStartAddress >= pStartAddr) &&
- (stubStartAddress < (pStartAddr + ConstVirtualThunkSize)))
- {
- pThunkAddr = pStartAddr;
- break;
- }
- ++dwCurrSlot;
- }
-
- pThunks = pThunks->GetNextThunk();
- }
-
- RETURN pThunkAddr;
-}
-
-#endif // !DACCESS_COMPILE
-
-#ifndef HAS_REMOTING_PRECODE
-
-#ifndef DACCESS_COMPILE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CNonVirtualThunkMgr::InitNonVirtualThunkManager public
-//
-// Synopsis: Adds the stub manager to aid debugger in stepping into calls
-//
-//
-//+----------------------------------------------------------------------------
-void CNonVirtualThunkMgr::InitNonVirtualThunkManager()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- }
- CONTRACTL_END;
-
- // This function is already thread safe since this method is called from within a
- // critical section
- if(NULL == s_pNonVirtualThunkMgr)
- {
- // Add the stub manager for non vtable calls
- s_pNonVirtualThunkMgr = new CNonVirtualThunkMgr();
-
- StubManager::AddStubManager(s_pNonVirtualThunkMgr);
- }
-}
-
-#endif // !DACCESS_COMPILE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CNonVirtualThunkMgr::CheckIsStub_Internal public
-//
-// Synopsis: Returns TRUE if the given address is the starting address of
-// one of our thunks
-//
-//+----------------------------------------------------------------------------
-BOOL CNonVirtualThunkMgr::CheckIsStub_Internal(PCODE stubStartAddress)
-{
- WRAPPER_NO_CONTRACT;
-
- BOOL bIsStub = FALSE;
-
-#ifndef DACCESS_COMPILE
- if (!IsThunkByASM(stubStartAddress))
- return FALSE;
- if(NULL != FindThunk((const BYTE *) stubStartAddress))
- bIsStub = TRUE;
-#endif // !DACCESS_COMPILE
-
- return bIsStub;
-}
-
-#ifndef DACCESS_COMPILE
-
-//+----------------------------------------------------------------------------
-//
-// Method: CNonVirtualThunkMgr::Entry2MethodDesc public
-//
-// Synopsis: Convert a starting address to a MethodDesc
-//
-//+----------------------------------------------------------------------------
-MethodDesc *CNonVirtualThunkMgr::Entry2MethodDesc(PCODE StubStartAddress, MethodTable *pMT)
-{
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pMT, NULL_OK));
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END;
-
- if (s_pNonVirtualThunkMgr == NULL)
- RETURN NULL;
-
- if (!s_pNonVirtualThunkMgr->CheckIsStub_Internal(StubStartAddress))
- RETURN NULL;
-
- RETURN GetMethodDescByASM(StubStartAddress);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: CNonVirtualThunkMgr::FindThunk private
-//
-// Synopsis: Finds a thunk that matches the given starting address
-//
-//+----------------------------------------------------------------------------
-CNonVirtualThunk* CNonVirtualThunkMgr::FindThunk(const BYTE *stubStartAddress)
-{
- CONTRACT (CNonVirtualThunk*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(stubStartAddress, NULL_OK));
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- SO_TOLERANT;
- }
- CONTRACT_END;
-
- SimpleRWLock::SimpleReadLockHolder srlh(CNonVirtualThunk::GetThunksListLock());
- CNonVirtualThunk* pThunk = CNonVirtualThunk::GetNonVirtualThunks();
-
- while(NULL != pThunk)
- {
- if(stubStartAddress == pThunk->GetThunkCode())
- break;
-
- pThunk = pThunk->GetNextThunk();
- }
-
- RETURN pThunk;
-}
-
-#endif // !DACCESS_COMPILE
-
-#endif // HAS_REMOTING_PRECODE
-
-
-#ifndef DACCESS_COMPILE
-
-//+----------------------------------------------------------------------------
-//+- HRESULT MethodDescDispatchHelper(MethodDesc* pMD, ARG_SLOT[] args, ARG_SLOT *pret)
-//+----------------------------------------------------------------------------
-HRESULT MethodDescDispatchHelper(MethodDescCallSite* pMethodCallSite, ARG_SLOT args[], ARG_SLOT *pret)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pMethodCallSite));
- PRECONDITION(CheckPointer(args));
- PRECONDITION(CheckPointer(pret));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- EX_TRY
- {
- *pret = pMethodCallSite->Call_RetArgSlot(args);
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
-
-#ifdef FEATURE_COMINTEROP
-
-//+----------------------------------------------------------------------------
-//
-// Method: VOID CRemotingServices::CallSetDCOMProxy(OBJECTREF realProxy, IUnknown* pUnk)
-//
-//+----------------------------------------------------------------------------
-
-VOID CRemotingServices::CallSetDCOMProxy(OBJECTREF realProxy, IUnknown* pUnk)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(realProxy != NULL);
- PRECONDITION(CheckPointer(pUnk, NULL_OK));
- }
- CONTRACTL_END;
-
- GCPROTECT_BEGIN(realProxy);
-
- MethodDescCallSite setDCOMProxy(METHOD__REAL_PROXY__SETDCOMPROXY, &realProxy);
-
- ARG_SLOT args[] =
- {
- ObjToArgSlot(realProxy),
- (ARG_SLOT)pUnk
- };
-
- ARG_SLOT ret;
- MethodDescDispatchHelper(&setDCOMProxy, args, &ret);
-
- GCPROTECT_END();
-}
-
-
-BOOL CRemotingServices::CallSupportsInterface(OBJECTREF realProxy, REFIID iid, ARG_SLOT* pret)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(realProxy != NULL);
- PRECONDITION(CheckPointer(pret));
- }
- CONTRACTL_END;
-
- BOOL fResult = TRUE;
-
- GCPROTECT_BEGIN(realProxy);
-
- MethodDescCallSite supportsInterface(METHOD__REAL_PROXY__SUPPORTSINTERFACE, &realProxy);
-
- ARG_SLOT args[] =
- {
- ObjToArgSlot(realProxy),
- (ARG_SLOT)&iid
- };
-
- HRESULT hr = MethodDescDispatchHelper(&supportsInterface, args, pret);
-
- // It is allowed for the managed code to return a NULL interface pointer without returning
- // a failure HRESULT. This is done for performance to avoid having to throw an exception.
- // If this occurs, we need to return E_NOINTERFACE.
- if ((*(IUnknown**)pret) == NULL)
- hr = E_NOINTERFACE;
-
- if (FAILED(hr))
- fResult = FALSE;
-
- GCPROTECT_END();
- return fResult;
-}
-#endif // FEATURE_COMINTEROP
-
-//+----------------------------------------------------------------------------
-//
-// Method: CRemotingServices::GetStubForInterfaceMethod
-//
-// Synopsis: Given the exact interface method we wish to invoke on, return
-// the entry point of a stub that will correctly transition into
-// the remoting system passing it this method.
-// The stubs is just another kind of precode. They are cached
-// in per appdomain hash.
-//
-//
-//+----------------------------------------------------------------------------
-PCODE CRemotingServices::GetStubForInterfaceMethod(MethodDesc *pItfMD)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pItfMD));
- PRECONDITION(pItfMD->IsInterface() && !pItfMD->IsStatic());
- }
- CONTRACTL_END;
-
- return pItfMD->GetLoaderAllocator()->GetFuncPtrStubs()->GetFuncPtrStub(pItfMD, PRECODE_STUB);
-}
-
-#endif // !DACCESS_COMPILE
-#endif // FEATURE_REMOTING
diff --git a/src/vm/remoting.h b/src/vm/remoting.h
deleted file mode 100644
index 4a63df6295..0000000000
--- a/src/vm/remoting.h
+++ /dev/null
@@ -1,957 +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.
-//
-// File: remoting.h
-//
-
-//
-// Purpose: Defines various remoting related objects such as
-// proxies
-//
-
-//
-
-
-#ifndef __REMOTING_H__
-#define __REMOTING_H__
-
-#ifndef FEATURE_REMOTING
-#error FEATURE_REMOTING is not set, please do not include remoting.h
-#endif
-
-#include "fcall.h"
-#include "stubmgr.h"
-
-// Forward declaration
-class TPMethodFrame;
-
-// <TODO>@TODO: Set the hashtable to delete the data.</TODO>
-
-// Thunk hash table - the keys are MethodDesc
-typedef EEHashTable<MethodDesc *, EEPtrHashTableHelper<MethodDesc *>, FALSE> EEThunkHashTable;
-
-// ConstVirtualThunkSize declares the size of the code generated by
-// CTPMethodTable::CreateThunkForVirtualMethod
-#ifdef _TARGET_X86_
-
-static const DWORD ConstVirtualThunkSize = sizeof(BYTE) + sizeof(DWORD) + sizeof(BYTE) + sizeof(LONG);
-
-#elif defined(_TARGET_AMD64_)
-
-static const DWORD ConstVirtualThunkSize = sizeof(DWORD) + sizeof(UINT64) + 7;
-
-#elif defined(_TARGET_ARM_)
-
-static const DWORD ConstVirtualThunkSize = 12;
-
-#else
-PORTABILITY_WARNING("Remoting thunk size not defined for this platform.")
-static const DWORD ConstVirtualThunkSize = sizeof(LPVOID);
-#endif
-
-extern "C"
-{
- UINT_PTR __stdcall CRemotingServices__CheckForContextMatch(Object* pStubData);
- void __stdcall CRemotingServices__DispatchInterfaceCall();
- void __stdcall CRemotingServices__CallFieldGetter(MethodDesc *pMD, LPVOID pThis, LPVOID pFirst, LPVOID pSecond, LPVOID pThird);
- void __stdcall CRemotingServices__CallFieldSetter(MethodDesc *pMD, LPVOID pThis, LPVOID pFirst, LPVOID pSecond, LPVOID pThird);
-}
-
-extern "C" LPVOID __stdcall CTPMethodTable__CallTargetHelper2(const void *pTarget, LPVOID pvFirst, LPVOID pvSecond);
-extern "C" LPVOID __stdcall CTPMethodTable__CallTargetHelper3(const void *pTarget, LPVOID pvFirst, LPVOID pvSecond, LPVOID pvThird);
-extern "C" BOOL __stdcall CTPMethodTable__GenericCheckForContextMatch(Object* orTP);
-
-
-// These are the values returned by RequiresManagedActivation
-enum ManagedActivationType
-{
- NoManagedActivation = 0,
- ManagedActivation = 0x1,
-#ifdef FEATURE_COMINTEROP
- ComObjectType = 0x2,
-#endif // FEATURE_COMINTEROP
-};
-
-
-struct timingData
-{
- DWORD threadId;
- BYTE stage;
- __int64 cycleCount;
-};
-
-
-// This struct is also accessed from managed world
-struct messageData
-{
- PVOID pFrame;
- MethodDesc *pMethodDesc;
- MethodDesc *pDelegateMD;
- MetaSig *pSig;
- TypeHandle thGoverningType;
- INT32 iFlags;
-};
-
-
-// The real proxy class is the class behind the
-// transparent proxy class
-class CRealProxy
-{
-public:
- // Native helpers
- static FCDECL2(VOID, SetStubData, Object* orRPUNSAFE, Object* orStubDataUNSAFE);
- static FCDECL1(Object*, GetStubData, Object* orRPUNSAFE);
- static FCDECL1(LPVOID, GetStub, Object* orRPUNSAFE);
- static FCDECL0(LPVOID, GetDefaultStub);
- static FCDECL1(Object*, GetProxiedType, Object* orRPUNSAFE);
-
- static VOID UpdateOptFlags(OBJECTREF refTP);
- static BOOL ProxyTypeIdentityCheck(MethodTable *pCliHierarchy, MethodTable *pSrvHierarchy);
-};
-
-// Forward declarations
-class CVirtualThunkMgr;
-class CNonVirtualThunkMgr;
-
-
-
-
-// Class that provides various remoting services
-// to the exposed world
-class CRemotingServices
-{
-private:
- //+-------------------------------------------------------------------
- //
- // Struct: FieldArgs
- //
- // Synopsis: Structure to GC protect arguments for a field accessor call.
- // DO NOT add non OBJECTREF data types in the structure
- // see GCPROTECT_BEGIN() for a better explanation.
- //
- //+-------------------------------------------------------------------
- typedef struct _FieldArgs
- {
- OBJECTREF obj;
- OBJECTREF val;
- STRINGREF typeName;
- STRINGREF fieldName;
- } FieldArgs;
-
-public:
-
- // Methods related to interception of non virtual methods & virtual methods called
- // non virtually
- static PCODE GetNonVirtualEntryPointForVirtualMethod(MethodDesc* pMD);
-
-#ifndef HAS_REMOTING_PRECODE
- static Stub* GetStubForNonVirtualMethod(MethodDesc* pMD, LPVOID pvAddrOfCode, Stub* pInnerStub);
-#endif
-
- static void DestroyThunk(MethodDesc* pMD);
-
- // Methods related to interception of interface calls
- static PCODE GetDispatchInterfaceHelper(MethodDesc* pMD);
-
- static OBJECTREF CreateProxyOrObject(MethodTable *pMT, BOOL fIsCom = FALSE, BOOL fIsNewObj = FALSE);
-
- // Methods related to field accessors
- static void FieldAccessor(FieldDesc* pFD, OBJECTREF o, LPVOID pVal, BOOL fIsGetter);
-
- // Methods related to wrapping/unwrapping of objects
- static OBJECTREF WrapHelper(OBJECTREF obj);
-
- static OBJECTREF Wrap(OBJECTREF obj);
- static OBJECTREF GetProxyFromObject(OBJECTREF obj);
- static OBJECTREF GetObjectFromProxy(OBJECTREF obj);
- static BOOL IsProxyToRemoteObject(OBJECTREF obj);
- static OBJECTREF GetServerContext(OBJECTREF obj);
-
- // Methods related to creation and marshaling of appdomains
- static OBJECTREF CreateProxyForDomain(AppDomain *pDomain);
-
- // Extract the true class of a proxy
- static REFLECTCLASSBASEREF GetClass(OBJECTREF pThis);
-
- // Initialization function.
- static VOID Initialize();
-
- // Start up function. This actually starts up the remoting services.
- static void EnsureRemotingStarted();
-
- // Other helper functions.
- inline static MethodDesc *MDofPrivateInvoke()
- {
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN s_pRPPrivateInvoke;
- }
-
- inline static MethodDesc *MDofInvokeStatic()
- {
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN s_pRPInvokeStatic;
- }
-
- inline static MethodDesc *MDofIsCurrentContextOK()
- {
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN s_pIsCurrentContextOK;
- }
-
- inline static MethodDesc *MDofCheckCast()
- {
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN s_pCheckCast;
- }
-
- inline static MethodDesc *MDofWrap()
- {
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN s_pWrapMethodDesc;
- }
-
- inline static MethodDesc *MDofFieldSetter()
- {
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN s_pFieldSetterDesc;
- }
-
- inline static MethodDesc *MDofFieldGetter()
- {
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN s_pFieldGetterDesc;
- }
-
- inline static MethodDesc *MDofGetType()
- {
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN s_pGetTypeDesc;
- }
-
- inline static MethodDesc *MDofObjectGetType()
- {
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN s_pObjectGetTypeDesc;
- }
-
-#ifdef FEATURE_COMINTEROP
- inline static MethodDesc *MDofCreateObjectForCom()
- {
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN s_pCreateObjectForCom;
- }
-
-
- static BOOL CallSupportsInterface(OBJECTREF realProxy, REFIID iid, ARG_SLOT *pret);
-
- // helpers to call methods in real proxy
- static VOID CallSetDCOMProxy(OBJECTREF realProxy, IUnknown* pUnk);
-
-#endif // FEATURE_COMINTEROP
-
- inline static BOOL IsInstanceOfServerIdentity(MethodTable* pMT)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pMT));
- }
- CONTRACTL_END;
-
- return s_pServerIdentityClass == pMT;
- }
-
- inline static MethodTable *GetMarshalByRefClass()
- {
- CONTRACT (MethodTable*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN s_pMarshalByRefObjectClass;
- }
-
- static INT32 IsTransparentProxy(Object* obj);
- static Object* GetRealProxy(Object* obj);
-
- static BOOL CheckCast(OBJECTREF orTP, TypeHandle ty);
- static BOOL CheckCast(OBJECTREF orTP, TypeHandle objTy, TypeHandle ty);
- static OBJECTREF GetExposedContext();
- static AppDomain *GetServerDomainForProxy(OBJECTREF orTP);
- static Context *GetServerContextForProxy(OBJECTREF orTP);
- static int GetServerDomainIdForProxy(OBJECTREF orTP);
- static UINT_PTR CheckForContextMatch(Object* pStubData);
-
- static ManagedActivationType __stdcall RequiresManagedActivation(TypeHandle ty);
- static BOOL IsRemotingStarted()
- {
- LIMITED_METHOD_CONTRACT;
- return s_fRemotingStarted;
- };
-
- static DWORD GetOffsetOfSrvIdentityInRP() { return s_dwSrvIdentityOffsetInRealProxy; }
- static DWORD GetOffsetOfCliIdentityInRP() { return s_dwIdOffset; }
- static DWORD GetOffsetOfTPOrObjInIdentity() { return s_dwTPOrObjOffsetInIdentity; }
- static DWORD GetOffsetOfLeaseInIdentity() { return s_dwLeaseOffsetInIdentity; }
- static DWORD GetOffsetOfURIInIdentity() { return s_dwURIOffsetInIdentity; }
- inline static MethodDesc *MDofRenewLeaseOnCall() { return s_pRenewLeaseOnCallDesc; }
-
- static PCODE GetStubForInterfaceMethod(MethodDesc *pItfMD);
-private:
- static void StartRemoting();
- static void CopyDestToSrc(LPVOID pDest, LPVOID pSrc, UINT cbSize);
- static void CallFieldAccessor(FieldDesc* pFD, OBJECTREF o, VOID * pVal,
- BOOL fIsGetter, BOOL fIsByValue, BOOL fIsGCRef,
- TypeHandle ty, TypeHandle fldTy,
- CorElementType fieldType, UINT cbSize);
-
- static void GetTypeAndFieldName(FieldArgs *pArgs, FieldDesc *pFD, TypeHandle thEnclosingClass);
- static BOOL MatchField(FieldDesc* pCurField, LPCUTF8 szFieldName);
- static OBJECTREF SetExposedContext(OBJECTREF newContext);
- static OBJECTREF GetServerIdentityFromProxy(OBJECTREF obj);
- inline static MethodDesc *MDOfCreateProxyForDomain()
- {
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN s_pProxyForDomainDesc;
- }
-
- inline static MethodDesc *MDofGetServerContextForProxy()
- {
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN s_pServerContextForProxyDesc;
- }
-
- inline static MethodDesc *MDofGetServerDomainIdForProxy()
- {
- CONTRACT (MethodDesc*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN s_pServerDomainIdForProxyDesc;
- }
-
- static VOID InitActivationServicesClass();
- static VOID InitRealProxyClass();
- static VOID InitRemotingProxyClass();
- static VOID InitServerIdentityClass();
- static VOID InitIdentityClass();
- static VOID InitMarshalByRefObjectClass();
- static VOID InitRemotingServicesClass();
- static VOID InitObjectClass();
- static VOID InitLeaseClass();
-
- static MethodTable *s_pMarshalByRefObjectClass;
- static MethodTable *CRemotingServices::s_pServerIdentityClass;
- static MethodTable *CRemotingServices::s_pContextClass;
-
- static MethodDesc *s_pRPPrivateInvoke;
- static MethodDesc *s_pRPInvokeStatic;
- static MethodDesc *s_pIsCurrentContextOK;
- static MethodDesc *s_pCheckCast;
- static MethodDesc *s_pWrapMethodDesc;
- static MethodDesc *s_pFieldSetterDesc;
- static MethodDesc *s_pFieldGetterDesc;
- static MethodDesc *s_pObjectGetTypeDesc;
- static MethodDesc *s_pGetTypeDesc;
- static MethodDesc *s_pProxyForDomainDesc;
- static MethodDesc *s_pServerContextForProxyDesc;
- static MethodDesc *s_pServerDomainIdForProxyDesc;
- static MethodDesc *s_pRenewLeaseOnCallDesc;
- static DWORD s_dwIdOffset;
- static DWORD s_dwServerOffsetInRealProxy;
- static DWORD s_dwSrvIdentityOffsetInRealProxy;
- static DWORD s_dwTPOrObjOffsetInIdentity;
- static DWORD s_dwLeaseOffsetInIdentity;
- static DWORD s_dwURIOffsetInIdentity;
- static DWORD s_dwMBRIDOffset;
- static CrstStatic s_RemotingCrst;
- static BOOL s_fRemotingStarted;
-
-#ifdef FEATURE_COMINTEROP
- static MethodDesc *s_pCreateObjectForCom;
-#endif // FEATURE_COMINTEROP
-
-};
-
-// Class that manages transparent proxy thunks
-class CVirtualThunks
-{
-public:
- inline static CVirtualThunks* GetVirtualThunks()
- {
- CONTRACT (CVirtualThunks*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- SO_TOLERANT;
- }
- CONTRACT_END;
-
- RETURN s_pVirtualThunks;
- }
-
- inline static CVirtualThunks* SetVirtualThunks(CVirtualThunks* pThunks)
- {
- CONTRACT (CVirtualThunks*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pThunks));
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN (s_pVirtualThunks = pThunks);
- }
-
- inline CVirtualThunks* GetNextThunk()
- {
- CONTRACT (CVirtualThunks*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- SO_TOLERANT;
- }
- CONTRACT_END;
-
- RETURN _pNext;
- }
-
- // Public member variables
- CVirtualThunks *_pNext;
- DWORD _dwReservedThunks;
- DWORD _dwStartThunk;
- DWORD _dwCurrentThunk;
-
-#ifdef CVIRTUALTHUNKS_ALIGNPAD_BYTES
- BYTE pad[CVIRTUALTHUNKS_ALIGNPAD_BYTES];
-#endif
-
- struct tagThunkCode
- {
- BYTE pCode[ConstVirtualThunkSize];
- } ThunkCode[1];
-
-private:
- // Cannot be created
- CVirtualThunks(CVirtualThunks *pNext, DWORD dwCommitedSlots, DWORD dwReservedSlots, DWORD dwStartSlot, DWORD dwCurrentSlot)
- {
- LIMITED_METHOD_CONTRACT;
- }
-
- // Private statics
- static CVirtualThunks *s_pVirtualThunks;
-};
-
-
-#ifndef HAS_REMOTING_PRECODE
-
-class CNonVirtualThunk
-{
-public:
- // Constructor
- CNonVirtualThunk(const BYTE* pbCode)
- : _addrOfCode(pbCode), _pNext(NULL)
- {
- WRAPPER_NO_CONTRACT;
- }
-
- ~CNonVirtualThunk();
-
- inline LPVOID* GetAddrOfCode()
- {
- CONTRACT (LPVOID*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN (LPVOID*)&_addrOfCode;
- }
-
- inline const BYTE* GetThunkCode()
- {
- CONTRACT (const BYTE*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- SO_TOLERANT;
- }
- CONTRACT_END;
-
- RETURN _addrOfCode;
- }
-
- inline CNonVirtualThunk* GetNextThunk()
- {
- CONTRACT (CNonVirtualThunk*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- SO_TOLERANT;
- }
- CONTRACT_END;
-
- RETURN _pNext;
- }
-
- static void InitializeListLock();
- static CNonVirtualThunk* AddrToThunk(LPVOID pAddr);
- inline static CNonVirtualThunk* GetNonVirtualThunks()
- {
- CONTRACT (CNonVirtualThunk*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- SO_TOLERANT;
- }
- CONTRACT_END;
-
- RETURN s_pNonVirtualThunks;
- }
-
- inline static SimpleRWLock* GetThunksListLock()
- {
- LIMITED_METHOD_CONTRACT;
-
- return s_pNonVirtualThunksListLock;
- }
-
- static CNonVirtualThunk* SetNonVirtualThunks(const BYTE* pbCode);
-
- const BYTE* _addrOfCode;
-
-private:
-
- void SetNextThunk();
-
- // Private statics
- static CNonVirtualThunk *s_pNonVirtualThunks;
-
- // reader/writer lock to be taken when manipulating s_pNonVirtualThunks
- static SimpleRWLock* s_pNonVirtualThunksListLock;
-
- // Private members
- CNonVirtualThunk* _pNext;
-};
-
-inline void CNonVirtualThunk::InitializeListLock()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (s_pNonVirtualThunksListLock == NULL)
- s_pNonVirtualThunksListLock = new SimpleRWLock(COOPERATIVE_OR_PREEMPTIVE, LOCK_TYPE_DEFAULT);
-}
-
-inline void CNonVirtualThunk::SetNextThunk()
-{
- LIMITED_METHOD_CONTRACT;
-
- SimpleRWLock::SimpleWriteLockHolder swlh(s_pNonVirtualThunksListLock);
-
- _pNext = s_pNonVirtualThunks;
- s_pNonVirtualThunks = this;
-}
-
-inline CNonVirtualThunk* CNonVirtualThunk::AddrToThunk(LPVOID pAddr)
-{
- CONTRACT (CNonVirtualThunk*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pAddr));
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN (CNonVirtualThunk *)((size_t)pAddr - (size_t)offsetof(CNonVirtualThunk, _addrOfCode));
-}
-
-#endif // HAS_REMOTING_PRECODE
-
-
-class CTPMethodTable
-{
- friend class CRemotingServices;
- friend class RemotingNative;
-
-public:
- // Public statics
- static DWORD GetCommitedTPSlots()
- {
- LIMITED_METHOD_CONTRACT;
- return s_dwCommitedTPSlots;
- }
-
- static MethodTable *GetMethodTable()
- {
- CONTRACT (MethodTable*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL));
- SO_TOLERANT;
- }
- CONTRACT_END;
-
- RETURN s_pThunkTable;
- }
-
- static VOID Initialize();
-
-#ifndef HAS_REMOTING_PRECODE
- static PTR_PCODE GetOrCreateNonVirtualSlotForVirtualMethod(MethodDesc* pMD);
- static PCODE CreateNonVirtualThunkForVirtualMethod(MethodDesc* pMD);
- static Stub* CreateStubForNonVirtualMethod(MethodDesc* pMD, CPUSTUBLINKER *psl, LPVOID pvAddrOfCode, Stub* pInnerStub);
-#endif // HAS_REMOTING_PRECODE
-
- static REALPROXYREF GetRP(OBJECTREF orTP);
- static MethodTable * GetMethodTableBeingProxied(OBJECTREF orTP);
-
- static LPVOID __stdcall CallTarget(MethodDesc* pTargetMD, LPVOID pvFirst, LPVOID pvSecond);
- static LPVOID __stdcall CallTarget(MethodDesc* pTargetMD, LPVOID pvFirst, LPVOID pvSecond, LPVOID pvThird);
- static BOOL CheckCastHelper(MethodDesc* pTargetMD, LPVOID pvFirst, LPVOID pvSecond);
- static BOOL CheckCast(MethodDesc* pTargetMD, TRANSPARENTPROXYREF orTP, TypeHandle ty);
- static void RefineProxy(TRANSPARENTPROXYREF orTP, TypeHandle ty);
-
- static PCODE GetTPStubEntryPoint();
- static PCODE GetDelegateStubEntryPoint();
-
- static void DestroyThunk(MethodDesc* pMD);
-
- // Interpretation of __TransparentProxy._stub
- typedef UINT_PTR CheckContextCrossingProc (Object*);
-
- inline static BOOL IsInstanceOfRemotingProxy(MethodTable *pMT)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pMT));
- }
- CONTRACTL_END;
-
- return s_pRemotingProxyClass == pMT;
- }
-
-private:
-
-#ifndef DACCESS_COMPILE
-
- // Private statics
- static void InitThunkTable(DWORD dwCommitedTPSlots, DWORD dwReservedTPSlots, MethodTable* pTPMethodTable)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pTPMethodTable));
- }
- CONTRACTL_END;
-
- s_dwCommitedTPSlots = dwCommitedTPSlots;
- s_dwReservedTPSlots = dwReservedTPSlots;
- s_pThunkTable = pTPMethodTable;
- }
-
-
- static void DestroyThunkTable()
- {
- WRAPPER_NO_CONTRACT;
- ::ClrVirtualFree(MTToAlloc(s_pThunkTable, s_dwGCInfoBytes), 0, MEM_RELEASE);
- s_pThunkTable = NULL;
- s_dwCommitedTPSlots = 0;
- s_dwReservedTPSlots = 0;
- }
-
-#endif // #ifndef DACCESS_COMPILE
-
- static void EnsureFieldsInitialized();
-
- static void CreateTPOfClassForRP(TypeHandle ty, REALPROXYREF *pRP, TRANSPARENTPROXYREF *pTP);
- static void CreateTPMethodTable(MethodTable* pTPMT);
- static BOOL ExtendCommitedSlots(_In_range_(1,64*1024) DWORD dwSlots);
- static BOOL AllocateThunks(DWORD dwSlots, DWORD dwCommitSize);
-#ifdef HAS_REMOTING_PRECODE
- static void ActivatePrecodeRemotingThunk();
-#endif // HAS_REMOTING_PRECODE
- static MethodTable *AllocToMT(BYTE *Alloc, LONG off)
- {
- CONTRACT (MethodTable*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(Alloc));
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN (MethodTable *) (Alloc + off);
- }
-
- static BYTE *MTToAlloc(MethodTable *MT, LONG off)
- {
- CONTRACT (BYTE*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(MT));
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN (((BYTE *) MT) - off);
- }
-
- static PCODE CreateThunkForVirtualMethod(DWORD dwSlot, BYTE *bCode);
-
- // Static members
- static DWORD s_dwCommitedTPSlots;
- static DWORD s_dwReservedTPSlots;
- static DWORD s_dwReservedTPIndirectionSlotSize;
- SPTR_DECL(MethodTable, s_pThunkTable);
- static MethodTable* s_pRemotingProxyClass;
- static DWORD s_dwGCInfoBytes;
- static DWORD s_dwMTDataSlots;
- static CrstStatic s_TPMethodTableCrst;
- static EEThunkHashTable *s_pThunkHashTable;
- static BOOL s_fTPTableFieldsInitialized;
-};
-
-extern "C" UINT32 STDCALL TransparentProxyStubWorker(TransitionBlock * pTransitionBlock, TADDR pMethodDescOrSlot);
-
-// Holder for remoting profiler notifications
-class ProfilerRemotingClientCallbackHolder
-{
-public:
- ProfilerRemotingClientCallbackHolder();
- ~ProfilerRemotingClientCallbackHolder();
-};
-
-// These stub manager classes help the debugger to step
-// through the various stubs and thunks generated by the
-// remoting infrastructure
-class CVirtualThunkMgr :public StubManager
-{
- friend class CTPMethodTable;
-
- VPTR_VTABLE_CLASS(CVirtualThunkMgr, StubManager)
-
-public:
- static void InitVirtualThunkManager();
-#ifndef DACCESS_COMPILE
- CVirtualThunkMgr()
- {
- WRAPPER_NO_CONTRACT;
- }
-#endif
-
-public:
-#ifdef _DEBUG
- virtual const char * DbgGetName() { LIMITED_METHOD_CONTRACT; return "CVirtualThunkMgr"; }
-#endif
-
- virtual BOOL CheckIsStub_Internal(PCODE stubStartAddress);
-
- virtual BOOL DoTraceStub(PCODE stubStartAddress, TraceDestination *trace) DAC_EMPTY_RET(FALSE);
-
- static MethodDesc *Entry2MethodDesc(PCODE StubStartAddress, MethodTable *pMT);
-
-private:
- // Private methods
- LPBYTE FindThunk(const BYTE *stubStartAddress);
- static MethodDesc *GetMethodDescByASM(PCODE startaddr, MethodTable *pMT);
- static BOOL IsThunkByASM(PCODE startaddr);
-
- // Private statics
- static CVirtualThunkMgr *s_pVirtualThunkMgr;
-
-#ifdef DACCESS_COMPILE
-protected:
- virtual LPCWSTR GetStubManagerName(PCODE addr)
- { LIMITED_METHOD_CONTRACT; return W("CVirtualThunk"); }
-#endif
-};
-
-
-#ifndef HAS_REMOTING_PRECODE
-
-class CNonVirtualThunkMgr :public StubManager
-{
- friend class CTPMethodTable;
-
- VPTR_VTABLE_CLASS(CNonVirtualThunkMgr, StubManager)
-
-public:
- static void InitNonVirtualThunkManager();
-
-public:
-#ifdef _DEBUG
- virtual const char * DbgGetName() { return "CNonVirtualThunkMgr"; }
-#endif
-
- virtual BOOL CheckIsStub_Internal(PCODE stubStartAddress);
-
- virtual BOOL DoTraceStub(PCODE stubStartAddress, TraceDestination *trace) DAC_EMPTY_RET(FALSE);
-
- virtual BOOL TraceManager(Thread *thread,
- TraceDestination *trace,
- CONTEXT *pContext,
- BYTE **pRetAddr) DAC_EMPTY_RET(FALSE);
-
- static MethodDesc *Entry2MethodDesc(PCODE StubStartAddress, MethodTable *pMT);
-
-private:
- // Private methods
- CNonVirtualThunk* FindThunk(const BYTE *stubStartAddress);
- static MethodDesc *GetMethodDescByASM(PCODE startaddr);
- static BOOL IsThunkByASM(PCODE startaddr);
-
- // Private statics
- static CNonVirtualThunkMgr *s_pNonVirtualThunkMgr;
-
-#ifdef DACCESS_COMPILE
-protected:
- virtual LPCWSTR GetStubManagerName(PCODE addr)
- { LIMITED_METHOD_CONTRACT; return W("CNonVirtualThunk"); }
-#endif
-};
-
-#endif // HAS_REMOTING_PRECODE
-
-#endif // __REMOTING_H__
diff --git a/src/vm/rexcep.h b/src/vm/rexcep.h
index 3ff4963996..b4a8318d92 100644
--- a/src/vm/rexcep.h
+++ b/src/vm/rexcep.h
@@ -109,12 +109,7 @@
//
DEFINE_EXCEPTION(g_ReflectionNS, AmbiguousMatchException, false, COR_E_AMBIGUOUSMATCH)
-#ifdef FEATURE_CORECLR
-// ApplicationException is removed in CoreCLR
-#define kApplicationException kException
-#else
DEFINE_EXCEPTION(g_SystemNS, ApplicationException, false, COR_E_APPLICATION)
-#endif // FEATURE_CORECLR
DEFINE_EXCEPTION(g_SystemNS, AppDomainUnloadedException, false, COR_E_APPDOMAINUNLOADED)
DEFINE_EXCEPTION(g_SystemNS, ArithmeticException, false, COR_E_ARITHMETIC)
@@ -142,27 +137,15 @@ DEFINE_EXCEPTION(g_SystemNS, BadImageFormatException, true,
META_E_BAD_SIGNATURE,
COR_E_LOADING_WINMD_REFERENCE_ASSEMBLY)
-#ifdef FEATURE_CORECLR
// CannotUnloadAppDomainException is removed in CoreCLR
#define kCannotUnloadAppDomainException kException
-#else
-DEFINE_EXCEPTION(g_SystemNS, CannotUnloadAppDomainException, false, COR_E_CANNOTUNLOADAPPDOMAIN)
-#endif // FEATURE_CORECLR
DEFINE_EXCEPTION(g_CodeContractsNS, ContractException, false, COR_E_CODECONTRACTFAILED)
-#ifdef FEATURE_REMOTING
-DEFINE_EXCEPTION(g_SystemNS, ContextMarshalException, false, COR_E_CONTEXTMARSHAL)
-#endif
DEFINE_EXCEPTION(g_ReflectionNS, CustomAttributeFormatException, false, COR_E_CUSTOMATTRIBUTEFORMAT)
-#if defined(FEATURE_X509) || defined(FEATURE_CRYPTO)
DEFINE_EXCEPTION(g_CryptographyNS, CryptographicException, false, CORSEC_E_CRYPTO)
-#endif // FEATURE_X509 || FEATURE_CRYPTO
-#ifndef FEATURE_CORECLR
-DEFINE_EXCEPTION(g_CryptographyNS, CryptographicUnexpectedOperationException, false, CORSEC_E_CRYPTO_UNEX_OPER)
-#endif // FEATURE_CORECLR
DEFINE_EXCEPTION(g_SystemNS, DataMisalignedException, false, COR_E_DATAMISALIGNED)
@@ -267,14 +250,8 @@ DEFINE_EXCEPTION(g_SystemNS, PlatformNotSupportedException, false, C
DEFINE_EXCEPTION(g_SystemNS, RankException, false, COR_E_RANK)
DEFINE_EXCEPTION(g_ReflectionNS, ReflectionTypeLoadException, false, COR_E_REFLECTIONTYPELOAD)
-#ifdef FEATURE_REMOTING
-DEFINE_EXCEPTION(g_RemotingNS, RemotingException, false, COR_E_REMOTING)
-#endif // FEATURE_REMOTING
DEFINE_EXCEPTION(g_CompilerServicesNS, RuntimeWrappedException, false, COR_E_RUNTIMEWRAPPED)
-#ifdef FEATURE_REMOTING
-DEFINE_EXCEPTION(g_RemotingNS, ServerException, false, COR_E_SERVER)
-#endif // FEATURE_REMOTING
DEFINE_EXCEPTION(g_SecurityNS, SecurityException, true,
COR_E_SECURITY, CORSEC_E_INVALID_STRONGNAME,
@@ -315,10 +292,6 @@ DEFINE_EXCEPTION(g_SystemNS, UnauthorizedAccessException, true, C
DEFINE_EXCEPTION(g_SecurityNS, VerificationException, false, COR_E_VERIFICATION)
-#ifdef FEATURE_CAS_POLICY
-DEFINE_EXCEPTION(g_PolicyNS, PolicyException, true, CORSEC_E_POLICY_EXCEPTION, CORSEC_E_NO_EXEC_PERM, CORSEC_E_MIN_GRANT_FAIL)
-DEFINE_EXCEPTION(g_SecurityNS, XmlSyntaxException, false, CORSEC_E_XMLSYNTAX)
-#endif // FEATURE_CAS_POLICY
DEFINE_EXCEPTION(g_InteropNS, COMException, false, E_FAIL)
DEFINE_EXCEPTION(g_InteropNS, ExternalException, false, E_FAIL)
@@ -327,19 +300,8 @@ DEFINE_EXCEPTION(g_SystemNS, NotImplementedException, false, E
DEFINE_EXCEPTION(g_SystemNS, OutOfMemoryException, false, E_OUTOFMEMORY, CTL_E_OUTOFMEMORY, STD_CTL_SCODE(31001))
-#ifdef FEATURE_CORECLR
DEFINE_EXCEPTION(g_SystemNS, CrossAppDomainMarshaledException, false, E_FAIL)
-#endif //FEATURE_CORECLR
-
-#ifdef FEATURE_ISOSTORE
-DEFINE_EXCEPTION(g_IsolatedStorageNS, IsolatedStorageException, true,
- ISS_E_ISOSTORE, ISS_E_ISOSTORE, ISS_E_OPEN_STORE_FILE,
- ISS_E_OPEN_FILE_MAPPING, ISS_E_MAP_VIEW_OF_FILE, ISS_E_GET_FILE_SIZE, ISS_E_CREATE_MUTEX, ISS_E_LOCK_FAILED,
- ISS_E_FILE_WRITE, ISS_E_SET_FILE_POINTER, ISS_E_CREATE_DIR,
- ISS_E_CORRUPTED_STORE_FILE, ISS_E_STORE_VERSION, ISS_E_FILE_NOT_MAPPED, ISS_E_BLOCK_SIZE_TOO_SMALL,
- ISS_E_ALLOC_TOO_LARGE, ISS_E_USAGE_WILL_EXCEED_QUOTA, ISS_E_TABLE_ROW_NOT_FOUND, ISS_E_DEPRECATE, ISS_E_CALLER,
- ISS_E_PATH_LENGTH, ISS_E_MACHINE, ISS_E_STORE_NOT_OPEN, ISS_E_MACHINE_DACL)
-#endif // FEATURE_ISOSTORE
+
DEFINE_EXCEPTION(g_SystemNS, ArgumentNullException, false, E_POINTER)
diff --git a/src/vm/runtimecallablewrapper.cpp b/src/vm/runtimecallablewrapper.cpp
index 359b6896bc..11881bb322 100644
--- a/src/vm/runtimecallablewrapper.cpp
+++ b/src/vm/runtimecallablewrapper.cpp
@@ -35,17 +35,10 @@ class Object;
#include "notifyexternals.h"
#include "winrttypenameconverter.h"
#include "../md/compiler/custattr.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "mdaassistants.h"
#include "olevariant.h"
#include "interopconverter.h"
-#include "constrainedexecutionregion.h"
#include "typestring.h"
-#ifdef FEATURE_REMOTING
-#include "crossdomaincalls.h"
-#endif
#include "caparser.h"
#include "classnames.h"
#include "objectnative.h"
@@ -126,13 +119,9 @@ IUnknown *ComClassFactory::CreateInstanceFromClassFactory(IClassFactory *pClassF
FrameWithCookie<DebuggerExitFrame> __def;
{
GCX_PREEMP();
- {
- LeaveRuntimeHolder lrh(**(size_t**)(IUnknown*)pClassFact);
- hr = pClassFact->CreateInstance(punkOuter, IID_IUnknown, (void **)&pUnk);
- }
+ hr = pClassFact->CreateInstance(punkOuter, IID_IUnknown, (void **)&pUnk);
if (FAILED(hr) && punkOuter)
{
- LeaveRuntimeHolder lrh(**(size_t**)(IUnknown*)pClassFact);
hr = pClassFact->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
if (pfDidContainment)
*pfDidContainment = TRUE;
@@ -148,7 +137,6 @@ IUnknown *ComClassFactory::CreateInstanceFromClassFactory(IClassFactory *pClassF
FrameWithCookie<DebuggerExitFrame> __def;
{
GCX_PREEMP();
- LeaveRuntimeHolder lrh(**(size_t**)(IUnknown*)pClassFact);
hr = pClassFact->CreateInstance(punkOuter, IID_IUnknown, (void **)&pUnk);
if (FAILED(hr) && punkOuter)
{
@@ -237,7 +225,6 @@ IUnknown *ComClassFactory::CreateInstanceFromClassFactory(IClassFactory *pClassF
{
// Either it's design time, or the current context doesn't
// supply a runtime license key.
- LeaveRuntimeHolder lrh(**(size_t**)(IUnknown*)pClassFact);
hr = pClassFact->CreateInstance(punkOuter, IID_IUnknown, (void **)&pUnk);
if (FAILED(hr) && punkOuter)
{
@@ -250,7 +237,6 @@ IUnknown *ComClassFactory::CreateInstanceFromClassFactory(IClassFactory *pClassF
{
// It's runtime, and we do have a non-null license key.
_ASSERTE(bstrKey != NULL);
- LeaveRuntimeHolder lrh(**(size_t**)(IUnknown*)pClassFact);
hr = pClassFact2->CreateInstanceLic(punkOuter, NULL, IID_IUnknown, bstrKey, (void**)&pUnk);
if (FAILED(hr) && punkOuter)
{
@@ -520,13 +506,11 @@ IClassFactory *ComClassFactory::GetIClassFactory()
ServerInfo.pwszName = m_pwszServer;
// Try to retrieve the IClassFactory passing in CLSCTX_REMOTE_SERVER.
- LeaveRuntimeHolder lrh((size_t)CoGetClassObject);
hr = CoGetClassObject(m_rclsid, CLSCTX_REMOTE_SERVER, &ServerInfo, IID_IClassFactory, (void**)&pClassFactory);
}
else
{
// No server name is specified so we use CLSCTX_SERVER.
- LeaveRuntimeHolder lrh((size_t)CoGetClassObject);
#ifdef FEATURE_CLASSIC_COMINTEROP
// If the CLSID is hosted by the CLR itself, then we do not want to go through the COM registration
@@ -541,49 +525,9 @@ IClassFactory *ComClassFactory::GetIClassFactory()
StackSString ssServer;
if (FAILED(Clr::Util::Com::FindServerUsingCLSID(m_rclsid, ssServer)))
{
-#ifndef FEATURE_CORECLR
- // If there is no server entry, then that implies the CLSID could be implemented by CLR.DLL itself,
- // if the CLSID is one of the special ones implemented by the CLR. We need to check against the
- // specific list of CLSIDs here because CLR.DLL-implemented CLSIDs and managed class-implemented
- // CLSIDs look the same until you start interating the subkeys. For now, the set of CLSIDs implemented
- // by CLR.DLL is a short and tractable list, but at some point it might become worthwhile to move over
- // to the more generalized solution of looking for the entries that identify when the CLSID is
- // implemented by a managed type to avoid having to maintain the hardcoded list.
- if (IsClrHostedLegacyComObject(m_rclsid))
- {
- PDllGetClassObject pFN = NULL;
- hr = g_pCLRRuntime->GetProcAddress("DllGetClassObjectInternal", reinterpret_cast<void**>(&pFN));
-
- if (FAILED(hr))
- hr = g_pCLRRuntime->GetProcAddress("DllGetClassObject", reinterpret_cast<void**>(&pFN));
-
- if (SUCCEEDED(hr))
- hr = pFN(m_rclsid, IID_IClassFactory, (void**)&pClassFactory);
- }
-#endif
}
else
{
-#ifndef FEATURE_CORECLR
- // @CORESYSTODO: ?
-
- // There is a SxS DLL that implements this CLSID.
- // NOTE: It is standard practise for RCWs and P/Invokes to leak their module handles,
- // as there is no automated mechanism for the runtime to call CanUnloadDllNow.
- HMODULE hServer = NULL;
- if (SUCCEEDED(hr = g_pCLRRuntime->LoadLibrary(ssServer.GetUnicode(), &hServer)))
- {
- PDllGetClassObject pFN = reinterpret_cast<PDllGetClassObject>(GetProcAddress(hServer, "DllGetClassObject"));
- if (pFN != NULL)
- {
- hr = pFN(m_rclsid, IID_IClassFactory, (void**)&pClassFactory);
- }
- else
- {
- hr = HRESULT_FROM_GetLastError();
- }
- }
-#endif
}
}
#endif // FEATURE_CLASSIC_COMINTEROP
@@ -764,8 +708,6 @@ IUnknown *AppXComClassFactory::CreateInstanceInternal(IUnknown *pOuter, BOOL *pf
IfFailThrow(E_FAIL);
}
#endif
-
- LeaveRuntimeHolder lrh((size_t)CoCreateInstanceFromApp);
if (m_pwszServer)
{
@@ -1917,13 +1859,6 @@ HRESULT RCWCleanupList::ReleaseRCWListInCorrectCtx(LPVOID pData)
ReleaseRCWList_Args* args = (ReleaseRCWList_Args*)pData;
-#ifdef FEATURE_REMOTING
- if (InSendMessage())
- {
- args->ctxBusy = TRUE;
- return S_OK;
- }
-#endif
RCW* pHead = (RCW *)args->pHead;
@@ -2450,9 +2385,6 @@ void RCW::Initialize(IUnknown* pUnk, DWORD dwSyncBlockIndex, MethodTable *pClass
// calling Marshal.CleanupUnusedObjectsInCurrentContext periodically. The best place
// to make that call is within their own message pump.
if (!disableEagerCleanup
-#ifdef FEATURE_REMOTING
- && !InSendMessage()
-#endif
)
{
_ASSERTE(g_pRCWCleanupList != NULL);
@@ -3109,12 +3041,10 @@ IUnknown *RCW::GetWellKnownInterface(REFIID riid)
// make sure it is on the right thread
IDispatch *RCW::GetIDispatch()
{
-#ifdef FEATURE_CORECLR
if (AppX::IsAppXProcess())
{
COMPlusThrow(kPlatformNotSupportedException, IDS_EE_ERROR_IDISPATCH);
}
-#endif // FEATURE_CORECLR
WRAPPER_NO_CONTRACT;
return (IDispatch *)GetWellKnownInterface(IID_IDispatch);
@@ -4576,9 +4506,7 @@ bool RCW::SupportsMngStdInterface(MethodTable *pItfMT)
if (pItfMT == MscorlibBinder::GetExistingClass(CLASS__IENUMERABLE))
{
SafeComHolder<IDispatch> pDisp = NULL;
-#ifdef FEATURE_CORECLR
if (!AppX::IsAppXProcess())
-#endif // FEATURE_CORECLR
{
// Get the IDispatch on the current thread.
pDisp = GetIDispatch();
@@ -4596,9 +4524,6 @@ bool RCW::SupportsMngStdInterface(MethodTable *pItfMT)
// We are about to make a call to COM so switch to preemptive GC.
GCX_PREEMP();
- // Can not get the IP for pDisp->Invoke, instead using the first IP in vtable.
- LeaveRuntimeHolder holder (**(size_t**)((IDispatch*)pDisp));
-
// Call invoke with DISPID_NEWENUM to see if such a member exists.
hr = pDisp->Invoke(
DISPID_NEWENUM,
@@ -4902,7 +4827,6 @@ BOOL ComObject::SupportsInterface(OBJECTREF oref, MethodTable* pIntfTable)
if (SUCCEEDED(hr))
{
GCX_PREEMP(); // make sure we switch to preemptive mode before calling the external COM object
- LeaveRuntimeHolder lrh(*((*(size_t**)(IConnectionPointContainer*)pCPC)+4));
hr = pCPC->FindConnectionPoint(SrcItfIID, &pCP);
if (SUCCEEDED(hr))
{
diff --git a/src/vm/runtimehandles.cpp b/src/vm/runtimehandles.cpp
index 68ad24c8f6..4ff6512a52 100644
--- a/src/vm/runtimehandles.cpp
+++ b/src/vm/runtimehandles.cpp
@@ -352,13 +352,6 @@ FCIMPL3(void, RuntimeMethodHandle::CheckLinktimeDemands, ReflectMethodObject *pM
}
}
-#ifndef FEATURE_CORECLR
- if (pCallee->RequiresLinktimeCheck())
- {
- Module *pModule = refModule->GetModule();
- Security::LinktimeCheckMethod(pDecoratedModule->GetAssembly(), pCallee);
- }
-#endif // !FEATURE_CORECLR
}
HELPER_METHOD_FRAME_END();
}
@@ -568,43 +561,6 @@ FCIMPLEND
-#ifndef FEATURE_CORECLR
-FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::IsEquivalentTo, ReflectClassBaseObject *rtType1UNSAFE, ReflectClassBaseObject *rtType2UNSAFE)
-{
- FCALL_CONTRACT;
-
- BOOL bResult = FALSE;
-
- REFLECTCLASSBASEREF rtType1 = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(rtType1UNSAFE);
- REFLECTCLASSBASEREF rtType2 = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(rtType2UNSAFE);
-
- HELPER_METHOD_FRAME_BEGIN_RET_2(rtType1, rtType2);
- if (rtType1 == NULL)
- COMPlusThrowArgumentNull(W("rtType1"));
- if (rtType2 == NULL)
- COMPlusThrowArgumentNull(W("rtType2"));
-
- bResult = rtType1->GetType().IsEquivalentTo(rtType2->GetType());
- HELPER_METHOD_FRAME_END();
-
- FC_RETURN_BOOL(bResult);
-}
-FCIMPLEND
-
-FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsEquivalentType, ReflectClassBaseObject *rtTypeUNSAFE)
-{
- FCALL_CONTRACT;
-
- BOOL bResult = FALSE;
-
- TypeHandle typeHandle = rtTypeUNSAFE->GetType();
- if (!typeHandle.IsTypeDesc())
- bResult = typeHandle.AsMethodTable()->GetClass()->IsEquivalentType();
-
- FC_RETURN_BOOL(bResult);
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_COMINTEROP
FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsWindowsRuntimeObjectType, ReflectClassBaseObject *rtTypeUNSAFE)
@@ -1261,32 +1217,6 @@ FCIMPL1(INT32, RuntimeTypeHandle::GetAttributes, ReflectClassBaseObject *pTypeUN
}
FCIMPLEND
-#ifdef FEATURE_REMOTING
-FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsContextful, ReflectClassBaseObject *pTypeUNSAFE) {
- CONTRACTL {
- FCALL_CHECK;
- }
- CONTRACTL_END;
-
- REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
-
- if (refType == NULL)
- FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
-
- TypeHandle typeHandle = refType->GetType();
-
- if (typeHandle.IsTypeDesc())
- FC_RETURN_BOOL(FALSE);
-
- MethodTable* pMT= typeHandle.GetMethodTable();
-
- if (!pMT)
- FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
-
- FC_RETURN_BOOL(pMT->IsContextful());
-}
-FCIMPLEND
-#endif
FCIMPL1(FC_BOOL_RET, RuntimeTypeHandle::IsValueType, ReflectClassBaseObject *pTypeUNSAFE)
{
@@ -3263,36 +3193,6 @@ FCIMPL1(INT32, AssemblyHandle::GetToken, AssemblyBaseObject* pAssemblyUNSAFE) {
}
FCIMPLEND
-#ifdef FEATURE_APTCA
-FCIMPL2(FC_BOOL_RET, AssemblyHandle::AptcaCheck, AssemblyBaseObject* pTargetAssemblyUNSAFE, AssemblyBaseObject* pSourceAssemblyUNSAFE)
-{
- FCALL_CONTRACT;
-
- ASSEMBLYREF refTargetAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pTargetAssemblyUNSAFE);
- ASSEMBLYREF refSourceAssembly = (ASSEMBLYREF)ObjectToOBJECTREF(pSourceAssemblyUNSAFE);
-
- if ((refTargetAssembly == NULL) || (refSourceAssembly == NULL))
- FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
-
- DomainAssembly *pTargetAssembly = refTargetAssembly->GetDomainAssembly();
- DomainAssembly *pSourceAssembly = refSourceAssembly->GetDomainAssembly();
-
- if (pTargetAssembly == pSourceAssembly)
- FC_RETURN_BOOL(TRUE);
-
- BOOL bResult = TRUE;
-
- HELPER_METHOD_FRAME_BEGIN_RET_2(refSourceAssembly, refTargetAssembly);
- {
- bResult = ( pTargetAssembly->GetAssembly()->AllowUntrustedCaller() || // target assembly allows untrusted callers unconditionally
- pSourceAssembly->GetSecurityDescriptor()->IsFullyTrusted());
- }
- HELPER_METHOD_FRAME_END();
-
- FC_RETURN_BOOL(bResult);
-}
-FCIMPLEND
-#endif // FEATURE_APTCA
void QCALLTYPE ModuleHandle::GetPEKind(QCall::ModuleHandle pModule, DWORD* pdwPEKind, DWORD* pdwMachine)
{
diff --git a/src/vm/runtimehandles.h b/src/vm/runtimehandles.h
index afe1902359..2963fbe84f 100644
--- a/src/vm/runtimehandles.h
+++ b/src/vm/runtimehandles.h
@@ -12,7 +12,6 @@
#include "fcall.h"
#include "field.h"
#include "typectxt.h"
-#include "constrainedexecutionregion.h"
typedef void* EnregisteredTypeHandle;
class SignatureNative;
@@ -127,12 +126,10 @@ public:
// Static method on RuntimeTypeHandle
static FCDECL1(Object*, Allocate, ReflectClassBaseObject *refType) ; //A.CI work
- static FCDECL6(Object*, CreateInstance, ReflectClassBaseObject* refThisUNSAFE,
+ static FCDECL4(Object*, CreateInstance, ReflectClassBaseObject* refThisUNSAFE,
CLR_BOOL publicOnly,
- CLR_BOOL securityOff,
CLR_BOOL *pbCanBeCached,
- MethodDesc** pConstructor,
- CLR_BOOL *pbNeedSecurityCheck);
+ MethodDesc** pConstructor);
static FCDECL2(Object*, CreateCaInstance, ReflectClassBaseObject* refCaType, ReflectMethodObject* pCtorUNSAFE);
@@ -158,10 +155,6 @@ public:
static FCDECL2(FC_BOOL_RET, TypeEQ, Object* left, Object* right);
static FCDECL2(FC_BOOL_RET, TypeNEQ, Object* left, Object* right);
-#ifndef FEATURE_CORECLR
- static FCDECL2(FC_BOOL_RET, IsEquivalentTo, ReflectClassBaseObject *rtType1UNSAFE, ReflectClassBaseObject *rtType2UNSAFE);
- static FCDECL1(FC_BOOL_RET, IsEquivalentType, ReflectClassBaseObject *rtTypeUNSAFE);
-#endif // !FEATURE_CORECLR
#ifdef FEATURE_COMINTEROP
static FCDECL1(FC_BOOL_RET, IsWindowsRuntimeObjectType, ReflectClassBaseObject *rtTypeUNSAFE);
@@ -198,9 +191,6 @@ public:
void QCALLTYPE GetDefaultConstructor(EnregisteredTypeHandle pTypeHandle, QCall::ObjectHandleOnStack retMethod);
static FCDECL1(ReflectClassBaseObject*, GetDeclaringType, ReflectClassBaseObject* pType);
-#ifdef FEATURE_REMOTING
- static FCDECL1(FC_BOOL_RET, IsContextful, ReflectClassBaseObject* pType);
-#endif
static FCDECL1(FC_BOOL_RET, IsValueType, ReflectClassBaseObject* pType);
static FCDECL1(FC_BOOL_RET, IsInterface, ReflectClassBaseObject* pType);
@@ -462,9 +452,6 @@ public:
static FCDECL1(ReflectModuleBaseObject*, GetManifestModule, AssemblyBaseObject *pAssemblyUNSAFE);
static FCDECL1(INT32, GetToken, AssemblyBaseObject *pAssemblyUNSAFE);
-#ifdef FEATURE_APTCA
- static FCDECL2(FC_BOOL_RET, AptcaCheck, AssemblyBaseObject *pTargetAssemblyUNSAFE, AssemblyBaseObject *pSourceAssemblyUNSAFE);
-#endif // FEATURE_APTCA
};
class SignatureNative;
diff --git a/src/vm/rwlock.cpp b/src/vm/rwlock.cpp
deleted file mode 100644
index 9d8233d140..0000000000
--- a/src/vm/rwlock.cpp
+++ /dev/null
@@ -1,2952 +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.
-//
-
-//
-//+-------------------------------------------------------------------
-//
-// File: RWLock.cpp
-//
-// Contents: Reader writer lock implementation that supports the
-// following features
-// 1. Cheap enough to be used in large numbers
-// such as per object synchronization.
-// 2. Supports timeout. This is a valuable feature
-// to detect deadlocks
-// 3. Supports caching of events. This allows
-// the events to be moved from least contentious
-// regions to the most contentious regions.
-// In other words, the number of events needed by
-// Reader-Writer lockls is bounded by the number
-// of threads in the process.
-// 4. Supports nested locks by readers and writers
-// 5. Supports spin counts for avoiding context switches
-// on multi processor machines.
-// 6. Supports functionality for upgrading to a writer
-// lock with a return argument that indicates
-// intermediate writes. Downgrading from a writer
-// lock restores the state of the lock.
-// 7. Supports functionality to Release Lock for calling
-// app code. RestoreLock restores the lock state and
-// indicates intermediate writes.
-// 8. Recovers from most common failures such as creation of
-// events. In other words, the lock mainitains consistent
-// internal state and remains usable
-//
-//
-// Classes: CRWLock
-//
-//--------------------------------------------------------------------
-
-
-#include "common.h"
-#include "rwlock.h"
-#include "corhost.h"
-
-#ifdef FEATURE_RWLOCK
-
-// Reader increment
-#define READER 0x00000001
-// Max number of readers
-#define READERS_MASK 0x000003FF
-// Reader being signaled
-#define READER_SIGNALED 0x00000400
-// Writer being signaled
-#define WRITER_SIGNALED 0x00000800
-#define WRITER 0x00001000
-// Waiting reader increment
-#define WAITING_READER 0x00002000
-// Note size of waiting readers must be less
-// than or equal to size of readers
-#define WAITING_READERS_MASK 0x007FE000
-#define WAITING_READERS_SHIFT 13
-// Waiting writer increment
-#define WAITING_WRITER 0x00800000
-// Max number of waiting writers
-#define WAITING_WRITERS_MASK 0xFF800000
-// Events are being cached
-#define CACHING_EVENTS (READER_SIGNALED | WRITER_SIGNALED)
-
-// Cookie flags
-#define UPGRADE_COOKIE 0x02000
-#define RELEASE_COOKIE 0x04000
-#define COOKIE_NONE 0x10000
-#define COOKIE_WRITER 0x20000
-#define COOKIE_READER 0x40000
-#define INVALID_COOKIE (~(UPGRADE_COOKIE | RELEASE_COOKIE | \
- COOKIE_NONE | COOKIE_WRITER | COOKIE_READER))
-#define RWLOCK_MAX_ACQUIRE_COUNT 0xFFFF
-
-// globals
-Volatile<LONGLONG> CRWLock::s_mostRecentLockID = 0;
-CrstStatic CRWLock::s_RWLockCrst;
-
-// Default values
-#ifdef _DEBUG
-DWORD gdwDefaultTimeout = 120000;
-#else //!_DEBUG
-DWORD gdwDefaultTimeout = INFINITE;
-#endif //_DEBUG
-const DWORD gdwReasonableTimeout = 120000;
-DWORD gdwDefaultSpinCount = 0;
-BOOL fBreakOnErrors = FALSE; // Temporarily break on errors
-
-// <REVISIT_TODO> REVISIT_TODO: Bad practise</REVISIT_TODO>
-#define HEAP_SERIALIZE 0
-#define RWLOCK_RECOVERY_FAILURE (0xC0000227L)
-
-// Catch GC holes
-#if _DEBUG
-#define VALIDATE_LOCK(pRWLock) ((Object *) (pRWLock))->Validate();
-#else // !_DEBUG
-#define VALIDATE_LOCK(pRWLock)
-#endif // _DEBUG
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::ProcessInit public
-//
-// Synopsis: Reads default values from registry and intializes
-// process wide data structures
-//
-//+-------------------------------------------------------------------
-void CRWLock::ProcessInit()
-{
- CONTRACTL
- {
- THROWS; // From Crst.Init()
- GC_NOTRIGGER;
- PRECONDITION((g_SystemInfo.dwNumberOfProcessors != 0));
- }
- CONTRACTL_END;
-
- gdwDefaultSpinCount = (g_SystemInfo.dwNumberOfProcessors != 1) ? 500 : 0;
-
- PPEB peb = (PPEB) ClrTeb::GetProcessEnvironmentBlock();
- DWORD dwTimeout = (DWORD)(peb->CriticalSectionTimeout.QuadPart/-10000000);
- if (dwTimeout)
- {
- gdwDefaultTimeout = dwTimeout;
- }
-
- // Initialize the critical section used by the lock
- // Can throw out of memory here.
- s_RWLockCrst.Init(CrstRWLock, CRST_UNSAFE_ANYMODE);
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::CRWLock public
-//
-// Synopsis: Constructor
-//
-//+-------------------------------------------------------------------
-CRWLock::CRWLock()
-: _hWriterEvent(NULL),
- _hReaderEvent(NULL),
- _dwState(0),
- _dwWriterID(0),
- _dwWriterSeqNum(1),
- _wWriterLevel(0)
-#ifdef RWLOCK_STATISTICS
- ,
- _dwReaderEntryCount(0),
- _dwReaderContentionCount(0),
- _dwWriterEntryCount(0),
- _dwWriterContentionCount(0),
- _dwEventsReleasedCount(0)
-#endif
-{
-
- CONTRACT_VOID
- {
- NOTHROW;
- GC_NOTRIGGER;
- POSTCONDITION((_dwLLockID > 0));
- }
- CONTRACT_END;
-
- LONGLONG qwLockID = s_mostRecentLockID;
- while (true)
- {
- LONGLONG qwNextLockID = qwLockID + 1;
- if (static_cast<LONG>(qwNextLockID) == 0)
- {
- // A value of zero for the lower half of the ID is reserved to identify that a thread does not own any RW locks,
- // regardless of the upper half of the ID
- ++qwNextLockID;
- }
-
- LONGLONG qwLockIDBeforeExchange = RWInterlockedCompareExchange64(&s_mostRecentLockID, qwNextLockID, qwLockID);
- if (qwLockIDBeforeExchange == qwLockID)
- {
- qwLockID = qwNextLockID;
- break;
- }
-
- qwLockID = qwLockIDBeforeExchange;
- }
-
- _dwLLockID = static_cast<LONG>(qwLockID);
- _dwULockID = static_cast<LONG>(qwLockID >> 32);
-
- RETURN;
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::Cleanup public
-//
-// Synopsis: Cleansup state
-//
-//+-------------------------------------------------------------------
-void CRWLock::Cleanup()
-{
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- PRECONDITION((_dwState == 0)); // sanity checks
- PRECONDITION((_dwWriterID == 0));
- PRECONDITION((_wWriterLevel == 0));
- }
- CONTRACTL_END;
-
- if(_hWriterEvent) {
- delete _hWriterEvent;
- _hWriterEvent = NULL;
- }
- if(_hReaderEvent) {
- delete _hReaderEvent;
- _hReaderEvent = NULL;
- }
-
- return;
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::ChainEntry private
-//
-// Synopsis: Chains the given lock entry into the chain
-//
-//+-------------------------------------------------------------------
-inline void CRWLock::ChainEntry(Thread *pThread, LockEntry *pLockEntry)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- // This is to synchronize with finalizer thread and deadlock detection.
- CrstHolder rwl(&s_RWLockCrst);
- LockEntry *pHeadEntry = pThread->m_pHead;
- pLockEntry->pNext = pHeadEntry;
- pLockEntry->pPrev = pHeadEntry->pPrev;
- pLockEntry->pPrev->pNext = pLockEntry;
- pHeadEntry->pPrev = pLockEntry;
-
- return;
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::GetLockEntry private
-//
-// Synopsis: Gets lock entry from TLS
-//
-//+-------------------------------------------------------------------
-inline LockEntry *CRWLock::GetLockEntry(Thread* pThread)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- if (pThread == NULL) {
- pThread = GetThread();
- }
- LockEntry *pHeadEntry = pThread->m_pHead;
- LockEntry *pLockEntry = pHeadEntry;
- do
- {
- if((pLockEntry->dwLLockID == _dwLLockID) && (pLockEntry->dwULockID == _dwULockID))
- return(pLockEntry);
- pLockEntry = pLockEntry->pNext;
- } while(pLockEntry != pHeadEntry);
-
- return(NULL);
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::FastGetOrCreateLockEntry private
-//
-// Synopsis: The fast path for getting a lock entry from TLS
-//
-//+-------------------------------------------------------------------
-inline LockEntry *CRWLock::FastGetOrCreateLockEntry()
-{
-
- CONTRACTL
- {
- THROWS; // SlowGetOrCreateLockEntry can throw out of memory exception
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- Thread *pThread = GetThread();
- _ASSERTE(pThread);
- LockEntry *pLockEntry = pThread->m_pHead;
- if(pLockEntry->dwLLockID == 0)
- {
- _ASSERTE(pLockEntry->wReaderLevel == 0);
- pLockEntry->dwLLockID = _dwLLockID;
- pLockEntry->dwULockID = _dwULockID;
- return(pLockEntry);
- }
- else if((pLockEntry->dwLLockID == _dwLLockID) && (pLockEntry->dwULockID == _dwULockID))
- {
- // Note, StaticAcquireReaderLock can have reentry via pumping while it's blocking
- // so no assertions about pLockEntry->wReaderLevel's state
- return(pLockEntry);
- }
-
- return(SlowGetOrCreateLockEntry(pThread));
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::SlowGetorCreateLockEntry private
-//
-// Synopsis: The slow path for getting a lock entry from TLS
-//
-//+-------------------------------------------------------------------
-LockEntry *CRWLock::SlowGetOrCreateLockEntry(Thread *pThread)
-{
-
- CONTRACTL
- {
- THROWS; // memory allocation can throw out of memory exception
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- LockEntry *pFreeEntry = NULL;
- LockEntry *pHeadEntry = pThread->m_pHead;
-
- // Search for an empty entry or an entry belonging to this lock
- LockEntry *pLockEntry = pHeadEntry->pNext;
- while(pLockEntry != pHeadEntry)
- {
- if(pLockEntry->dwLLockID &&
- ((pLockEntry->dwLLockID != _dwLLockID) || (pLockEntry->dwULockID != _dwULockID)))
- {
- // Move to the next entry
- pLockEntry = pLockEntry->pNext;
- }
- else
- {
- // Prepare to move it to the head
- pFreeEntry = pLockEntry;
- pLockEntry->pPrev->pNext = pLockEntry->pNext;
- pLockEntry->pNext->pPrev = pLockEntry->pPrev;
-
- break;
- }
- }
-
- if(pFreeEntry == NULL)
- {
- pFreeEntry = new LockEntry;
- pFreeEntry->wReaderLevel = 0;
- }
-
- if(pFreeEntry)
- {
- _ASSERTE((pFreeEntry->dwLLockID != 0) || (pFreeEntry->wReaderLevel == 0));
- _ASSERTE((pFreeEntry->wReaderLevel == 0) ||
- ((pFreeEntry->dwLLockID == _dwLLockID) && (pFreeEntry->dwULockID == _dwULockID)));
-
- // Chain back the entry
- ChainEntry(pThread, pFreeEntry);
-
- // Move this entry to the head
- pThread->m_pHead = pFreeEntry;
-
- // Mark the entry as belonging to this lock
- pFreeEntry->dwLLockID = _dwLLockID;
- pFreeEntry->dwULockID = _dwULockID;
- }
-
- return pFreeEntry;
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::FastRecycleLockEntry private
-//
-// Synopsis: Fast path for recycling the lock entry that is used
-// when the thread is the next few instructions is going
-// to call FastGetOrCreateLockEntry again
-//
-//+-------------------------------------------------------------------
-inline void CRWLock::FastRecycleLockEntry(LockEntry *pLockEntry)
-{
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
-
- // Sanity checks
- PRECONDITION(pLockEntry->wReaderLevel == 0);
- PRECONDITION((pLockEntry->dwLLockID == _dwLLockID) && (pLockEntry->dwULockID == _dwULockID));
- PRECONDITION(pLockEntry == GetThread()->m_pHead);
- }
- CONTRACTL_END;
-
-
- pLockEntry->dwLLockID = 0;
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::RecycleLockEntry private
-//
-// Synopsis: Fast path for recycling the lock entry
-//
-//+-------------------------------------------------------------------
-inline void CRWLock::RecycleLockEntry(LockEntry *pLockEntry)
-{
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
-
- // Sanity check
- PRECONDITION(pLockEntry->wReaderLevel == 0);
- }
- CONTRACTL_END;
-
- // Move the entry to tail
- Thread *pThread = GetThread();
- LockEntry *pHeadEntry = pThread->m_pHead;
- if(pLockEntry == pHeadEntry)
- {
- pThread->m_pHead = pHeadEntry->pNext;
- }
- else if(pLockEntry->pNext->dwLLockID)
- {
- // Prepare to move the entry to tail
- pLockEntry->pPrev->pNext = pLockEntry->pNext;
- pLockEntry->pNext->pPrev = pLockEntry->pPrev;
-
- // Chain back the entry
- ChainEntry(pThread, pLockEntry);
- }
-
- // The entry does not belong to this lock anymore
- pLockEntry->dwLLockID = 0;
- return;
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticIsWriterLockHeld public
-//
-// Synopsis: Return TRUE if writer lock is held
-//
-//+-------------------------------------------------------------------
-FCIMPL1(FC_BOOL_RET, CRWLock::StaticIsWriterLockHeld, CRWLock *pRWLock)
-{
- FCALL_CONTRACT;
-
- if (pRWLock == NULL)
- {
- FCThrow(kNullReferenceException);
- }
-
- if(pRWLock->_dwWriterID == GetThread()->GetThreadId())
- FC_RETURN_BOOL(TRUE);
-
- FC_RETURN_BOOL(FALSE);
-}
-FCIMPLEND
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticIsReaderLockHeld public
-//
-// Synopsis: Return TRUE if reader lock is held
-//
-//+-------------------------------------------------------------------
-FCIMPL1(FC_BOOL_RET, CRWLock::StaticIsReaderLockHeld, CRWLock *pRWLock)
-{
- FCALL_CONTRACT;
-
- if (pRWLock == NULL)
- {
- FCThrow(kNullReferenceException);
- }
-
- LockEntry *pLockEntry = pRWLock->GetLockEntry();
- if(pLockEntry)
- {
- FC_RETURN_BOOL(pLockEntry->wReaderLevel > 0);
- }
-
- FC_RETURN_BOOL(FALSE);
-}
-FCIMPLEND
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::AssertWriterLockHeld public
-//
-// Synopsis: Asserts that writer lock is held
-//
-//+-------------------------------------------------------------------
-#ifdef _DEBUG
-BOOL CRWLock::AssertWriterLockHeld()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- if(_dwWriterID == GetThread()->GetThreadId())
- return(TRUE);
-
- _ASSERTE(!"Writer lock not held by the current thread");
- return(FALSE);
-}
-#endif
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::AssertWriterLockNotHeld public
-//
-// Synopsis: Asserts that writer lock is not held
-//
-//+-------------------------------------------------------------------
-#ifdef _DEBUG
-BOOL CRWLock::AssertWriterLockNotHeld()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- if(_dwWriterID != GetThread()->GetThreadId())
- return(TRUE);
-
- _ASSERTE(!"Writer lock held by the current thread");
- return(FALSE);
-}
-#endif
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::AssertReaderLockHeld public
-//
-// Synopsis: Asserts that reader lock is held
-//
-//+-------------------------------------------------------------------
-#ifdef _DEBUG
-BOOL CRWLock::AssertReaderLockHeld()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- LockEntry *pLockEntry = GetLockEntry();
- if(pLockEntry)
- {
- _ASSERTE(pLockEntry->wReaderLevel);
- return(TRUE);
- }
-
- _ASSERTE(!"Reader lock not held by the current thread");
- return(FALSE);
-}
-#endif
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::AssertReaderLockNotHeld public
-//
-// Synopsis: Asserts that writer lock is not held
-//
-//+-------------------------------------------------------------------
-#ifdef _DEBUG
-BOOL CRWLock::AssertReaderLockNotHeld()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- LockEntry *pLockEntry = GetLockEntry();
- if(pLockEntry == NULL)
- return(TRUE);
-
- _ASSERTE(pLockEntry->wReaderLevel);
- _ASSERTE(!"Reader lock held by the current thread");
-
- return(FALSE);
-}
-#endif
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::AssertReaderOrWriterLockHeld public
-//
-// Synopsis: Asserts that writer lock is not held
-//
-//+-------------------------------------------------------------------
-#ifdef _DEBUG
-BOOL CRWLock::AssertReaderOrWriterLockHeld()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- if(_dwWriterID == GetThread()->GetThreadId())
- {
- return(TRUE);
- }
- else
- {
- LockEntry *pLockEntry = GetLockEntry();
- if(pLockEntry)
- {
- _ASSERTE(pLockEntry->wReaderLevel);
- return(TRUE);
- }
- }
-
- _ASSERTE(!"Neither Reader nor Writer lock held");
- return(FALSE);
-}
-#endif
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::RWSetEvent private
-//
-// Synopsis: Helper function for setting an event
-//
-//+-------------------------------------------------------------------
-inline void CRWLock::RWSetEvent(CLREvent* event)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- if(!event->Set())
- {
- _ASSERTE(!"SetEvent failed");
- if(fBreakOnErrors) // fBreakOnErrors == FALSE so will be optimized out.
- DebugBreak();
- COMPlusThrowWin32(E_UNEXPECTED);
- }
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::RWResetEvent private
-//
-// Synopsis: Helper function for resetting an event
-//
-//+-------------------------------------------------------------------
-inline void CRWLock::RWResetEvent(CLREvent* event)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- if(!event->Reset())
- {
- _ASSERTE(!"ResetEvent failed");
- if(fBreakOnErrors) // fBreakOnErrors == FALSE so will be optimized out.
- DebugBreak();
- COMPlusThrowWin32(E_UNEXPECTED);
- }
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::RWWaitForSingleObject public
-//
-// Synopsis: Helper function for waiting on an event
-//
-//+-------------------------------------------------------------------
-inline DWORD CRWLock::RWWaitForSingleObject(CLREvent* event, DWORD dwTimeout)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- DWORD status = WAIT_FAILED;
- EX_TRY
- {
- status = event->Wait(dwTimeout,TRUE);
- }
- EX_CATCH
- {
- status = GET_EXCEPTION()->GetHR();
- if (status == S_OK)
- {
- status = WAIT_FAILED;
- }
- }
- EX_END_CATCH(SwallowAllExceptions); // The caller will rethrow the exception
-
- return status;
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::RWSleep public
-//
-// Synopsis: Helper function for calling Sleep
-//
-//+-------------------------------------------------------------------
-inline void CRWLock::RWSleep(DWORD dwTime)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- ClrSleepEx(dwTime, TRUE);
-}
-
-
-#undef volatile
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::RWInterlockedCompareExchange public
-//
-// Synopsis: Helper function for calling intelockedCompareExchange
-//
-//+-------------------------------------------------------------------
-inline LONG CRWLock::RWInterlockedCompareExchange(LONG volatile *pvDestination,
- LONG dwExchange,
- LONG dwComparand)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- return FastInterlockCompareExchange(pvDestination,
- dwExchange,
- dwComparand);
-}
-
-inline LONGLONG CRWLock::RWInterlockedCompareExchange64(LONGLONG volatile *pvDestination,
- LONGLONG qwExchange,
- LONGLONG qwComparand)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- return FastInterlockCompareExchangeLong(pvDestination, qwExchange, qwComparand);
-}
-
-inline void* CRWLock::RWInterlockedCompareExchangePointer(PVOID volatile *pvDestination,
- void* pExchange,
- void* pComparand)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- return FastInterlockCompareExchangePointer(pvDestination,
- pExchange,
- pComparand);
-}
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::RWInterlockedExchangeAdd public
-//
-// Synopsis: Helper function for adding state
-//
-//+-------------------------------------------------------------------
-inline LONG CRWLock::RWInterlockedExchangeAdd(LONG volatile *pvDestination,
- LONG dwAddToState)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- return FastInterlockExchangeAdd(pvDestination, dwAddToState);
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::RWInterlockedIncrement public
-//
-// Synopsis: Helper function for incrementing a pointer
-//
-//+-------------------------------------------------------------------
-inline LONG CRWLock::RWInterlockedIncrement(LONG volatile *pdwState)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- return FastInterlockIncrement(pdwState);
-}
-
-#define volatile DoNotUserVolatileKeyword
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::ReleaseEvents public
-//
-// Synopsis: Helper function for caching events
-//
-//+-------------------------------------------------------------------
-void CRWLock::ReleaseEvents()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- PRECONDITION(((_dwState & CACHING_EVENTS) == CACHING_EVENTS)); // Ensure that reader and writers have been stalled
-
- }
- CONTRACTL_END;
-
- // Save writer event
- CLREvent *hWriterEvent = _hWriterEvent;
- _hWriterEvent = NULL;
-
- // Save reader event
- CLREvent *hReaderEvent = _hReaderEvent;
- _hReaderEvent = NULL;
-
- // Allow readers and writers to continue
- RWInterlockedExchangeAdd(&_dwState, -(CACHING_EVENTS));
-
- // Cache events
- // <REVISIT_TODO>:
- // I am closing events for now. What is needed
- // is an event cache to which the events are
- // released using InterlockedCompareExchange64</REVISIT_TODO>
- if(hWriterEvent)
- {
- LOG((LF_SYNC, LL_INFO10, "Releasing writer event\n"));
- delete hWriterEvent;
- }
- if(hReaderEvent)
- {
- LOG((LF_SYNC, LL_INFO10, "Releasing reader event\n"));
- delete hReaderEvent;
- }
-#ifdef RWLOCK_STATISTICS
- RWInterlockedIncrement(&_dwEventsReleasedCount);
-#endif
-
- return;
-}
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::GetWriterEvent public
-//
-// Synopsis: Helper function for obtaining a auto reset event used
-// for serializing writers. It utilizes event cache
-//
-//+-------------------------------------------------------------------
-CLREvent* CRWLock::GetWriterEvent(HRESULT *pHR)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- *pHR = S_OK;
- //GC could happen in ~CLREvent or EH. "this" is a GC object so it could be moved
- //during GC. So we need to cache the field before GC could happen
- CLREvent * result = _hWriterEvent;
-
- if(_hWriterEvent == NULL)
- {
- EX_TRY
- {
- CLREvent *pEvent = new CLREvent();
- NewHolder<CLREvent> hWriterEvent (pEvent);
- hWriterEvent->CreateRWLockWriterEvent(FALSE,this);
- if(hWriterEvent)
- {
- if(RWInterlockedCompareExchangePointer((PVOID*) &_hWriterEvent,
- hWriterEvent.GetValue(),
- NULL) == NULL)
- {
- hWriterEvent.SuppressRelease();
- }
- //GC could happen in ~CLREvent or EH. "this" is a GC object so it could be moved
- //during GC. So we need to cache the field before GC could happen.
- result = _hWriterEvent;
- }
- }
- EX_CATCH
- {
- *pHR = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
- }
-
- return(result);
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::GetReaderEvent public
-//
-// Synopsis: Helper function for obtaining a manula reset event used
-// by readers to wait when a writer holds the lock.
-// It utilizes event cache
-//
-//+-------------------------------------------------------------------
-CLREvent* CRWLock::GetReaderEvent(HRESULT *pHR)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- *pHR = S_OK;
- //GC could happen in ~CLREvent or EH. "this" is a GC object so it could be moved
- //during GC. So we need to cache the field before GC could happen
- CLREvent * result = _hReaderEvent;
-
- if(_hReaderEvent == NULL)
- {
- EX_TRY
- {
- CLREvent *pEvent = new CLREvent();
- NewHolder<CLREvent> hReaderEvent (pEvent);
- hReaderEvent->CreateRWLockReaderEvent(FALSE, this);
- if(hReaderEvent)
- {
- if(RWInterlockedCompareExchangePointer((PVOID*) &_hReaderEvent,
- hReaderEvent.GetValue(),
- NULL) == NULL)
- {
- hReaderEvent.SuppressRelease();
- }
- //GC could happen in ~CLREvent or EH. "this" is a GC object so it could be moved
- //during GC. So we need to cache the field before GC could happen
- result = _hReaderEvent;
- }
- }
- EX_CATCH
- {
- *pHR = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
- }
-
- return(result);
-}
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticRecoverLock public
-//
-// Synopsis: Helper function to restore the lock to
-// the original state
-//
-
-//
-//+-------------------------------------------------------------------
-void CRWLock::StaticRecoverLock(
- CRWLock **ppRWLock,
- LockCookie *pLockCookie,
- DWORD dwFlags)
-{
- CONTRACTL
- {
- THROWS; // StaticAcquireWriterLock can throw exception
- GC_TRIGGERS;
- CAN_TAKE_LOCK;
- }
- CONTRACTL_END;
-
- DWORD dwTimeout = (gdwDefaultTimeout > gdwReasonableTimeout)
- ? gdwDefaultTimeout
- : gdwReasonableTimeout;
-
- Thread *pThread = GetThread();
- _ASSERTE (pThread);
-
- EX_TRY
- {
- // Check if the thread was a writer
- if(dwFlags & COOKIE_WRITER)
- {
- // Acquire writer lock
- StaticAcquireWriterLock(ppRWLock, dwTimeout);
- _ASSERTE (pThread->m_dwLockCount >= (*ppRWLock)->_wWriterLevel);
- ASSERT_UNLESS_NO_DEBUG_STATE(__pClrDebugState->GetLockCount(kDbgStateLockType_User) >= (*ppRWLock)->_wWriterLevel);
- pThread->m_dwLockCount -= (*ppRWLock)->_wWriterLevel;
- USER_LOCK_RELEASED_MULTIPLE((*ppRWLock)->_wWriterLevel, GetPtrForLockContract(ppRWLock));
- (*ppRWLock)->_wWriterLevel = pLockCookie->wWriterLevel;
- pThread->m_dwLockCount += (*ppRWLock)->_wWriterLevel;
- USER_LOCK_TAKEN_MULTIPLE((*ppRWLock)->_wWriterLevel, GetPtrForLockContract(ppRWLock));
- }
- // Check if the thread was a reader
- else if(dwFlags & COOKIE_READER)
- {
- StaticAcquireReaderLock(ppRWLock, dwTimeout);
- LockEntry *pLockEntry = (*ppRWLock)->GetLockEntry();
- _ASSERTE(pLockEntry);
- _ASSERTE (pThread->m_dwLockCount >= pLockEntry->wReaderLevel);
- ASSERT_UNLESS_NO_DEBUG_STATE(__pClrDebugState->GetLockCount(kDbgStateLockType_User) >= pLockEntry->wReaderLevel);
- pThread->m_dwLockCount -= pLockEntry->wReaderLevel;
- USER_LOCK_RELEASED_MULTIPLE(pLockEntry->wReaderLevel, GetPtrForLockContract(ppRWLock));
- pLockEntry->wReaderLevel = pLockCookie->wReaderLevel;
- pThread->m_dwLockCount += pLockEntry->wReaderLevel;
- USER_LOCK_TAKEN_MULTIPLE(pLockEntry->wReaderLevel, GetPtrForLockContract(ppRWLock));
- }
- }
- EX_CATCH
- {
- // Removed an assert here. This error is expected in case of
- // ThreadAbort.
- COMPlusThrowWin32(RWLOCK_RECOVERY_FAILURE);
- }
- EX_END_CATCH_UNREACHABLE
-}
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticAcquireReaderLockPublic public
-//
-// Synopsis: Public access to StaticAcquireReaderLock
-//
-//+-------------------------------------------------------------------
-FCIMPL2(void, CRWLock::StaticAcquireReaderLockPublic, CRWLock *pRWLockUNSAFE, DWORD dwDesiredTimeout)
-{
- FCALL_CONTRACT;
-
- if (pRWLockUNSAFE == NULL)
- {
- FCThrowVoid(kNullReferenceException);
- }
-
- OBJECTREF pRWLock = ObjectToOBJECTREF((Object*)pRWLockUNSAFE);
- HELPER_METHOD_FRAME_BEGIN_1(pRWLock);
-
- StaticAcquireReaderLock((CRWLock**)&pRWLock, dwDesiredTimeout);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticAcquireReaderLock private
-//
-// Synopsis: Makes the thread a reader. Supports nested reader locks.
-//
-//+-------------------------------------------------------------------
-
-void CRWLock::StaticAcquireReaderLock(
- CRWLock **ppRWLock,
- DWORD dwDesiredTimeout)
-{
-
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS; // CLREvent::Wait is GC_TRIGGERS
- CAN_TAKE_LOCK;
- PRECONDITION(CheckPointer(ppRWLock));
- PRECONDITION(CheckPointer(*ppRWLock));
- }
- CONTRACTL_END;
-
- TESTHOOKCALL(AppDomainCanBeUnloaded(GetThread()->GetDomain()->GetId().m_dwId,FALSE));
-
- if (GetThread()->IsAbortRequested()) {
- GetThread()->HandleThreadAbort();
- }
-
- LockEntry *pLockEntry = (*ppRWLock)->FastGetOrCreateLockEntry();
- if (pLockEntry == NULL)
- {
- COMPlusThrowWin32(STATUS_NO_MEMORY);
- }
-
- DWORD dwStatus = WAIT_OBJECT_0;
- // Check for the fast path
- if(RWInterlockedCompareExchange(&(*ppRWLock)->_dwState, READER, 0) == 0)
- {
- _ASSERTE(pLockEntry->wReaderLevel == 0);
- }
- // Check for nested reader
- else if(pLockEntry->wReaderLevel != 0)
- {
- _ASSERTE((*ppRWLock)->_dwState & READERS_MASK);
-
- if (pLockEntry->wReaderLevel == RWLOCK_MAX_ACQUIRE_COUNT) {
- COMPlusThrow(kOverflowException, W("Overflow_UInt16"));
- }
- ++pLockEntry->wReaderLevel;
- INCTHREADLOCKCOUNT();
- USER_LOCK_TAKEN(GetPtrForLockContract(ppRWLock));
- return;
- }
- // Check if the thread already has writer lock
- else if((*ppRWLock)->_dwWriterID == GetThread()->GetThreadId())
- {
- StaticAcquireWriterLock(ppRWLock, dwDesiredTimeout);
- (*ppRWLock)->FastRecycleLockEntry(pLockEntry);
- return;
- }
- else
- {
- DWORD dwSpinCount;
- DWORD dwCurrentState, dwKnownState;
-
- // Initialize
- dwSpinCount = 0;
- dwCurrentState = (*ppRWLock)->_dwState;
- do
- {
- dwKnownState = dwCurrentState;
-
- // Reader need not wait if there are only readers and no writer
- if((dwKnownState < READERS_MASK) ||
- (((dwKnownState & READER_SIGNALED) && ((dwKnownState & WRITER) == 0)) &&
- (((dwKnownState & READERS_MASK) +
- ((dwKnownState & WAITING_READERS_MASK) >> WAITING_READERS_SHIFT)) <=
- (READERS_MASK - 2))))
- {
- // Add to readers
- dwCurrentState = RWInterlockedCompareExchange(&(*ppRWLock)->_dwState,
- (dwKnownState + READER),
- dwKnownState);
- if(dwCurrentState == dwKnownState)
- {
- // One more reader
- break;
- }
- }
- // Check for too many Readers or waiting readers or signaling in progress
- else if(((dwKnownState & READERS_MASK) == READERS_MASK) ||
- ((dwKnownState & WAITING_READERS_MASK) == WAITING_READERS_MASK) ||
- ((dwKnownState & CACHING_EVENTS) == READER_SIGNALED))
- {
- // Sleep
- GetThread()->UserSleep(1000);
-
- // Update to latest state
- dwSpinCount = 0;
- dwCurrentState = (*ppRWLock)->_dwState;
- }
- // Check if events are being cached
- else if((dwKnownState & CACHING_EVENTS) == CACHING_EVENTS)
- {
- if(++dwSpinCount > gdwDefaultSpinCount)
- {
- RWSleep(1);
- dwSpinCount = 0;
- }
- dwCurrentState = (*ppRWLock)->_dwState;
- }
- // Check spin count
- else if(++dwSpinCount <= gdwDefaultSpinCount)
- {
- dwCurrentState = (*ppRWLock)->_dwState;
- }
- else
- {
- // Add to waiting readers
- dwCurrentState = RWInterlockedCompareExchange(&(*ppRWLock)->_dwState,
- (dwKnownState + WAITING_READER),
- dwKnownState);
- if(dwCurrentState == dwKnownState)
- {
- CLREvent* hReaderEvent;
- DWORD dwModifyState;
-
- // One more waiting reader
-#ifdef RWLOCK_STATISTICS
- RWInterlockedIncrement(&(*ppRWLock)->_dwReaderContentionCount);
-#endif
- HRESULT hr;
- hReaderEvent = (*ppRWLock)->GetReaderEvent(&hr);
- if(hReaderEvent)
- {
- dwStatus = RWWaitForSingleObject(hReaderEvent, dwDesiredTimeout);
- VALIDATE_LOCK(*ppRWLock);
-
- // StaticAcquireReaderLock can have reentry via pumping while waiting for
- // hReaderEvent, which may change pLockEntry's state from underneath us.
- if ((pLockEntry->dwLLockID != (*ppRWLock)->_dwLLockID) ||
- (pLockEntry->dwULockID != (*ppRWLock)->_dwULockID))
- {
- pLockEntry = (*ppRWLock)->FastGetOrCreateLockEntry();
- if (pLockEntry == NULL)
- {
- COMPlusThrowWin32(STATUS_NO_MEMORY);
- }
- }
- }
- else
- {
- LOG((LF_SYNC, LL_WARNING,
- "AcquireReaderLock failed to create reader "
- "event for RWLock 0x%x\n", *ppRWLock));
- dwStatus = E_FAIL;
- }
-
- if(dwStatus == WAIT_OBJECT_0)
- {
- _ASSERTE((*ppRWLock)->_dwState & READER_SIGNALED);
- _ASSERTE(((*ppRWLock)->_dwState & READERS_MASK) < READERS_MASK);
- dwModifyState = READER - WAITING_READER;
- }
- else
- {
- dwModifyState = (DWORD) -WAITING_READER;
- if(dwStatus == WAIT_TIMEOUT)
- {
- LOG((LF_SYNC, LL_WARNING,
- "Timed out trying to acquire reader lock "
- "for RWLock 0x%x\n", *ppRWLock));
- hr = HRESULT_FROM_WIN32(ERROR_TIMEOUT);
- }
- else if(dwStatus == WAIT_IO_COMPLETION)
- {
- LOG((LF_SYNC, LL_WARNING,
- "Thread interrupted while trying to acquire reader lock "
- "for RWLock 0x%x\n", *ppRWLock));
- hr = COR_E_THREADINTERRUPTED;
- }
- else if (dwStatus == WAIT_FAILED)
- {
- if (SUCCEEDED(hr))
- {
- dwStatus = GetLastError();
- if (dwStatus == WAIT_OBJECT_0)
- {
- dwStatus = WAIT_FAILED;
- }
- hr = HRESULT_FROM_WIN32(dwStatus);
- LOG((LF_SYNC, LL_WARNING,
- "WaitForSingleObject on Event 0x%x failed for "
- "RWLock 0x%x with status code 0x%x\n",
- hReaderEvent, *ppRWLock, dwStatus));
- }
- }
- }
-
- // One less waiting reader and he may have become a reader
- dwKnownState = RWInterlockedExchangeAdd(&(*ppRWLock)->_dwState, dwModifyState);
-
- // Check for last signaled waiting reader
- if(dwStatus == WAIT_OBJECT_0)
- {
- _ASSERTE(dwKnownState & READER_SIGNALED);
- _ASSERTE((dwKnownState & READERS_MASK) < READERS_MASK);
- if((dwKnownState & WAITING_READERS_MASK) == WAITING_READER)
- {
- // Reset the event and lower reader signaled flag
- RWResetEvent(hReaderEvent);
- RWInterlockedExchangeAdd(&(*ppRWLock)->_dwState, -READER_SIGNALED);
- }
- }
- else
- {
- if(((dwKnownState & WAITING_READERS_MASK) == WAITING_READER) &&
- (dwKnownState & READER_SIGNALED))
- {
- HRESULT hr1;
- if(hReaderEvent == NULL)
- hReaderEvent = (*ppRWLock)->GetReaderEvent(&hr1);
- _ASSERTE(hReaderEvent);
-
- // Ensure the event is signalled before resetting it.
- DWORD dwTemp;
- dwTemp = hReaderEvent->Wait(INFINITE, FALSE);
- _ASSERTE(dwTemp == WAIT_OBJECT_0);
- _ASSERTE(((*ppRWLock)->_dwState & READERS_MASK) < READERS_MASK);
-
- // Reset the event and lower reader signaled flag
- RWResetEvent(hReaderEvent);
- RWInterlockedExchangeAdd(&(*ppRWLock)->_dwState, (READER - READER_SIGNALED));
-
- // Honor the orginal status
- ++pLockEntry->wReaderLevel;
- INCTHREADLOCKCOUNT();
- USER_LOCK_TAKEN(GetPtrForLockContract(ppRWLock));
- StaticReleaseReaderLock(ppRWLock);
- }
- else
- {
- (*ppRWLock)->FastRecycleLockEntry(pLockEntry);
- }
-
- _ASSERTE((pLockEntry == NULL) ||
- ((pLockEntry->dwLLockID == 0) &&
- (pLockEntry->wReaderLevel == 0)));
- if(fBreakOnErrors) // fBreakOnErrors == FALSE so will be optimized out.
- {
- _ASSERTE(!"Failed to acquire reader lock");
- DebugBreak();
- }
-
- // Prepare the frame for throwing an exception
- if ((DWORD)HOST_E_DEADLOCK == dwStatus)
- {
- // So that the error message is in the exception.
- RaiseDeadLockException();
- } else if ((DWORD)COR_E_THREADINTERRUPTED == dwStatus) {
- COMPlusThrow(kThreadInterruptedException);
- }
- else
- {
- COMPlusThrowWin32 (hr);
- }
- }
-
- // Sanity check
- _ASSERTE(dwStatus == WAIT_OBJECT_0);
- break;
- }
- }
- YieldProcessor(); // Indicate to the processor that we are spining
- } while(TRUE);
- }
-
- // Success
- _ASSERTE(dwStatus == WAIT_OBJECT_0);
- _ASSERTE(((*ppRWLock)->_dwState & WRITER) == 0);
- _ASSERTE((*ppRWLock)->_dwState & READERS_MASK);
- ++pLockEntry->wReaderLevel;
- INCTHREADLOCKCOUNT();
- USER_LOCK_TAKEN(GetPtrForLockContract(ppRWLock));
-#ifdef RWLOCK_STATISTICS
- RWInterlockedIncrement(&(*ppRWLock)->_dwReaderEntryCount);
-#endif
- return;
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticAcquireWriterLockPublic public
-//
-// Synopsis: Public access to StaticAcquireWriterLock
-//
-//+-------------------------------------------------------------------
-FCIMPL2(void, CRWLock::StaticAcquireWriterLockPublic, CRWLock *pRWLockUNSAFE, DWORD dwDesiredTimeout)
-{
- FCALL_CONTRACT;
-
- if (pRWLockUNSAFE == NULL)
- {
- FCThrowVoid(kNullReferenceException);
- }
-
- OBJECTREF pRWLock = ObjectToOBJECTREF((Object*)pRWLockUNSAFE);
- HELPER_METHOD_FRAME_BEGIN_1(pRWLock);
-
- StaticAcquireWriterLock((CRWLock**)&pRWLock, dwDesiredTimeout);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticAcquireWriterLock private
-//
-// Synopsis: Makes the thread a writer. Supports nested writer
-// locks
-//
-//+-------------------------------------------------------------------
-
-void CRWLock::StaticAcquireWriterLock(
- CRWLock **ppRWLock,
- DWORD dwDesiredTimeout)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS; // CLREvent::Wait can trigger GC
- CAN_TAKE_LOCK;
- PRECONDITION((CheckPointer(ppRWLock)));
- PRECONDITION((CheckPointer(*ppRWLock)));
- }
- CONTRACTL_END;
-
- TESTHOOKCALL(AppDomainCanBeUnloaded(GetThread()->GetDomain()->GetId().m_dwId,FALSE));
- if (GetThread()->IsAbortRequested()) {
- GetThread()->HandleThreadAbort();
- }
-
- // Declare locals needed for setting up frame
- DWORD dwThreadID = GetThread()->GetThreadId();
- DWORD dwStatus;
-
- // Check for the fast path
- if(RWInterlockedCompareExchange(&(*ppRWLock)->_dwState, WRITER, 0) == 0)
- {
- _ASSERTE(((*ppRWLock)->_dwState & READERS_MASK) == 0);
- }
- // Check if the thread already has writer lock
- else if((*ppRWLock)->_dwWriterID == dwThreadID)
- {
- if ((*ppRWLock)->_wWriterLevel == RWLOCK_MAX_ACQUIRE_COUNT) {
- COMPlusThrow(kOverflowException, W("Overflow_UInt16"));
- }
- ++(*ppRWLock)->_wWriterLevel;
- INCTHREADLOCKCOUNT();
- USER_LOCK_TAKEN(GetPtrForLockContract(ppRWLock));
- return;
- }
- else
- {
- DWORD dwCurrentState, dwKnownState;
- DWORD dwSpinCount;
-
- // Initialize
- dwSpinCount = 0;
- dwCurrentState = (*ppRWLock)->_dwState;
- do
- {
- dwKnownState = dwCurrentState;
-
- // Writer need not wait if there are no readers and writer
- if((dwKnownState == 0) || (dwKnownState == CACHING_EVENTS))
- {
- // Can be a writer
- dwCurrentState = RWInterlockedCompareExchange(&(*ppRWLock)->_dwState,
- (dwKnownState + WRITER),
- dwKnownState);
- if(dwCurrentState == dwKnownState)
- {
- // Only writer
- break;
- }
- }
- // Check for too many waiting writers
- else if(((dwKnownState & WAITING_WRITERS_MASK) == WAITING_WRITERS_MASK))
- {
- // Sleep
- GetThread()->UserSleep(1000);
-
- // Update to latest state
- dwSpinCount = 0;
- dwCurrentState = (*ppRWLock)->_dwState;
- }
- // Check if events are being cached
- else if((dwKnownState & CACHING_EVENTS) == CACHING_EVENTS)
- {
- if(++dwSpinCount > gdwDefaultSpinCount)
- {
- RWSleep(1);
- dwSpinCount = 0;
- }
- dwCurrentState = (*ppRWLock)->_dwState;
- }
- // Check spin count
- else if(++dwSpinCount <= gdwDefaultSpinCount)
- {
- dwCurrentState = (*ppRWLock)->_dwState;
- }
- else
- {
- // Add to waiting writers
- dwCurrentState = RWInterlockedCompareExchange(&(*ppRWLock)->_dwState,
- (dwKnownState + WAITING_WRITER),
- dwKnownState);
- if(dwCurrentState == dwKnownState)
- {
- CLREvent* hWriterEvent;
- DWORD dwModifyState;
-
- // One more waiting writer
-#ifdef RWLOCK_STATISTICS
- RWInterlockedIncrement(&(*ppRWLock)->_dwWriterContentionCount);
-#endif
- HRESULT hr;
- hWriterEvent = (*ppRWLock)->GetWriterEvent(&hr);
- if(hWriterEvent)
- {
- dwStatus = RWWaitForSingleObject(hWriterEvent, dwDesiredTimeout);
- VALIDATE_LOCK(*ppRWLock);
- }
- else
- {
- LOG((LF_SYNC, LL_WARNING,
- "AcquireWriterLock failed to create writer "
- "event for RWLock 0x%x\n", *ppRWLock));
- dwStatus = WAIT_FAILED;
- }
-
- if(dwStatus == WAIT_OBJECT_0)
- {
- _ASSERTE((*ppRWLock)->_dwState & WRITER_SIGNALED);
- dwModifyState = WRITER - WAITING_WRITER - WRITER_SIGNALED;
- }
- else
- {
- dwModifyState = (DWORD) -WAITING_WRITER;
- if(dwStatus == WAIT_TIMEOUT)
- {
- LOG((LF_SYNC, LL_WARNING,
- "Timed out trying to acquire writer "
- "lock for RWLock 0x%x\n", *ppRWLock));
- hr = HRESULT_FROM_WIN32 (ERROR_TIMEOUT);
- }
- else if(dwStatus == WAIT_IO_COMPLETION)
- {
- LOG((LF_SYNC, LL_WARNING,
- "Thread interrupted while trying to acquire writer lock "
- "for RWLock 0x%x\n", *ppRWLock));
- hr = COR_E_THREADINTERRUPTED;
- }
- else if (dwStatus == WAIT_FAILED)
- {
- if (SUCCEEDED(hr))
- {
- dwStatus = GetLastError();
- if (dwStatus == WAIT_OBJECT_0)
- {
- dwStatus = WAIT_FAILED;
- }
- hr = HRESULT_FROM_WIN32(dwStatus);
- LOG((LF_SYNC, LL_WARNING,
- "WaitForSingleObject on Event 0x%x failed for "
- "RWLock 0x%x with status code 0x%x",
- hWriterEvent, *ppRWLock, dwStatus));
- }
- }
- }
-
- // One less waiting writer and he may have become a writer
- dwKnownState = RWInterlockedExchangeAdd(&(*ppRWLock)->_dwState, dwModifyState);
-
- // Check for last timing out signaled waiting writer
- if(dwStatus == WAIT_OBJECT_0)
- {
- // Common case
- }
- else
- {
- if((dwKnownState & WRITER_SIGNALED) &&
- ((dwKnownState & WAITING_WRITERS_MASK) == WAITING_WRITER))
- {
- HRESULT hr1;
- if(hWriterEvent == NULL)
- hWriterEvent = (*ppRWLock)->GetWriterEvent(&hr1);
- _ASSERTE(hWriterEvent);
- do
- {
- dwKnownState = (*ppRWLock)->_dwState;
- if((dwKnownState & WRITER_SIGNALED) &&
- ((dwKnownState & WAITING_WRITERS_MASK) == 0))
- {
- DWORD dwTemp = hWriterEvent->Wait(10, FALSE);
- if(dwTemp == WAIT_OBJECT_0)
- {
- dwKnownState = RWInterlockedExchangeAdd(&(*ppRWLock)->_dwState, (WRITER - WRITER_SIGNALED));
- _ASSERTE(dwKnownState & WRITER_SIGNALED);
- _ASSERTE((dwKnownState & WRITER) == 0);
-
- // Honor the orginal status
- (*ppRWLock)->_dwWriterID = dwThreadID;
- Thread *pThread = GetThread();
- _ASSERTE (pThread);
- _ASSERTE ((*ppRWLock)->_wWriterLevel == 0);
- pThread->m_dwLockCount ++;
- USER_LOCK_TAKEN(GetPtrForLockContract(ppRWLock));
- (*ppRWLock)->_wWriterLevel = 1;
- StaticReleaseWriterLock(ppRWLock);
- break;
- }
- // else continue;
- }
- else
- break;
- }while(TRUE);
- }
-
- if(fBreakOnErrors) // fBreakOnErrors == FALSE so will be optimized out.
- {
- _ASSERTE(!"Failed to acquire writer lock");
- DebugBreak();
- }
-
- // Prepare the frame for throwing an exception
- if ((DWORD)HOST_E_DEADLOCK == dwStatus)
- {
- // So that the error message is in the exception.
- RaiseDeadLockException();
- } else if ((DWORD)COR_E_THREADINTERRUPTED == dwStatus) {
- COMPlusThrow(kThreadInterruptedException);
- }
- else
- {
- COMPlusThrowWin32(hr);
- }
- }
-
- // Sanity check
- _ASSERTE(dwStatus == WAIT_OBJECT_0);
- break;
- }
- }
- YieldProcessor(); // indicate to the processor that we are spinning
- } while(TRUE);
- }
-
- // Success
- _ASSERTE((*ppRWLock)->_dwState & WRITER);
- _ASSERTE(((*ppRWLock)->_dwState & READERS_MASK) == 0);
- _ASSERTE((*ppRWLock)->_dwWriterID == 0);
-
- // Save threadid of the writer
- (*ppRWLock)->_dwWriterID = dwThreadID;
- (*ppRWLock)->_wWriterLevel = 1;
- INCTHREADLOCKCOUNT();
- USER_LOCK_TAKEN(GetPtrForLockContract(ppRWLock));
- ++(*ppRWLock)->_dwWriterSeqNum;
-#ifdef RWLOCK_STATISTICS
- ++(*ppRWLock)->_dwWriterEntryCount;
-#endif
- return;
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticReleaseWriterLockPublic public
-//
-// Synopsis: Public access to StaticReleaseWriterLock
-//
-//+-------------------------------------------------------------------
-FCIMPL1(void, CRWLock::StaticReleaseWriterLockPublic, CRWLock *pRWLockUNSAFE)
-{
- FCALL_CONTRACT;
-
- if (pRWLockUNSAFE == NULL)
- {
- FCThrowVoid(kNullReferenceException);
- }
-
- OBJECTREF pRWLock = ObjectToOBJECTREF((Object*)pRWLockUNSAFE);
-
- HELPER_METHOD_FRAME_BEGIN_ATTRIB_1(Frame::FRAME_ATTR_NO_THREAD_ABORT, pRWLock);
-
- // We don't want to block thread abort when we need to construct exception in
- // unwind-continue handler.
- // note that we cannot use this holder in FCALLs outside our HMF since it breaks the epilog walker on x86!
- ThreadPreventAbortHolder preventAbortIn;
-
- StaticReleaseWriterLock((CRWLock**)&pRWLock);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticReleaseWriterLock private
-//
-// Synopsis: Removes the thread as a writer if not a nested
-// call to release the lock
-//
-//+-------------------------------------------------------------------
-void CRWLock::StaticReleaseWriterLock(
- CRWLock **ppRWLock)
-{
-
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- PRECONDITION((CheckPointer(ppRWLock)));
- PRECONDITION((CheckPointer(*ppRWLock)));
- }
- CONTRACTL_END;
-
- DWORD dwThreadID = GetThread()->GetThreadId();
-
- // Check validity of caller
- if((*ppRWLock)->_dwWriterID == dwThreadID)
- {
- DECTHREADLOCKCOUNT();
- USER_LOCK_RELEASED(GetPtrForLockContract(ppRWLock));
- // Check for nested release
- if(--(*ppRWLock)->_wWriterLevel == 0)
- {
- DWORD dwCurrentState, dwKnownState, dwModifyState;
- BOOL fCacheEvents;
- CLREvent* hReaderEvent = NULL, *hWriterEvent = NULL;
-
- // Not a writer any more
- (*ppRWLock)->_dwWriterID = 0;
- dwCurrentState = (*ppRWLock)->_dwState;
- do
- {
- dwKnownState = dwCurrentState;
- dwModifyState = (DWORD) -WRITER;
- fCacheEvents = FALSE;
- if(dwKnownState & WAITING_READERS_MASK)
- {
- HRESULT hr;
- hReaderEvent = (*ppRWLock)->GetReaderEvent(&hr);
- if(hReaderEvent == NULL)
- {
- LOG((LF_SYNC, LL_WARNING,
- "ReleaseWriterLock failed to create "
- "reader event for RWLock 0x%x\n", *ppRWLock));
- RWSleep(100);
- dwCurrentState = (*ppRWLock)->_dwState;
- dwKnownState = 0;
- _ASSERTE(dwCurrentState != dwKnownState);
- continue;
- }
- dwModifyState += READER_SIGNALED;
- }
- else if(dwKnownState & WAITING_WRITERS_MASK)
- {
- HRESULT hr;
- hWriterEvent = (*ppRWLock)->GetWriterEvent(&hr);
- if(hWriterEvent == NULL)
- {
- LOG((LF_SYNC, LL_WARNING,
- "ReleaseWriterLock failed to create "
- "writer event for RWLock 0x%x\n", *ppRWLock));
- RWSleep(100);
- dwCurrentState = (*ppRWLock)->_dwState;
- dwKnownState = 0;
- _ASSERTE(dwCurrentState != dwKnownState);
- continue;
- }
- dwModifyState += WRITER_SIGNALED;
- }
- else if(((*ppRWLock)->_hReaderEvent || (*ppRWLock)->_hWriterEvent) &&
- (dwKnownState == WRITER))
- {
- fCacheEvents = TRUE;
- dwModifyState += CACHING_EVENTS;
- }
-
- // Sanity checks
- _ASSERTE((dwKnownState & READERS_MASK) == 0);
-
- dwCurrentState = RWInterlockedCompareExchange(&(*ppRWLock)->_dwState,
- (dwKnownState + dwModifyState),
- dwKnownState);
- } while(dwCurrentState != dwKnownState);
-
- // Check for waiting readers
- if(dwKnownState & WAITING_READERS_MASK)
- {
- _ASSERTE((*ppRWLock)->_dwState & READER_SIGNALED);
- _ASSERTE(hReaderEvent);
- RWSetEvent(hReaderEvent);
- }
- // Check for waiting writers
- else if(dwKnownState & WAITING_WRITERS_MASK)
- {
- _ASSERTE((*ppRWLock)->_dwState & WRITER_SIGNALED);
- _ASSERTE(hWriterEvent);
- RWSetEvent(hWriterEvent);
- }
- // Check for the need to release events
- else if(fCacheEvents)
- {
- (*ppRWLock)->ReleaseEvents();
- }
-
- Thread *pThread = GetThread();
- TESTHOOKCALL(AppDomainCanBeUnloaded(pThread->GetDomain()->GetId().m_dwId,FALSE));
- if (pThread->IsAbortRequested()) {
- pThread->HandleThreadAbort();
- }
-
- }
- }
- else
- {
- if(fBreakOnErrors) // fBreakOnErrors == FALSE so will be optimized out.
- {
- _ASSERTE(!"Attempt to release writer lock on a wrong thread");
- DebugBreak();
- }
- COMPlusThrowWin32(ERROR_NOT_OWNER);
- }
-
- return;
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticReleaseReaderLockPublic public
-//
-// Synopsis: Public access to StaticReleaseReaderLock
-//
-//+-------------------------------------------------------------------
-FCIMPL1(void, CRWLock::StaticReleaseReaderLockPublic, CRWLock *pRWLockUNSAFE)
-{
- FCALL_CONTRACT;
-
- if (pRWLockUNSAFE == NULL)
- {
- FCThrowVoid(kNullReferenceException);
- }
-
- OBJECTREF pRWLock = ObjectToOBJECTREF((Object*)pRWLockUNSAFE);
-
- HELPER_METHOD_FRAME_BEGIN_ATTRIB_1(Frame::FRAME_ATTR_NO_THREAD_ABORT, pRWLock);
-
- // note that we cannot use this holder in FCALLs outside our HMF since it breaks the epilog walker on x86!
- ThreadPreventAbortHolder preventAbortIn;
-
- StaticReleaseReaderLock((CRWLock**)&pRWLock);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticReleaseReaderLock private
-//
-// Synopsis: Removes the thread as a reader
-//
-//+-------------------------------------------------------------------
-
-void CRWLock::StaticReleaseReaderLock(
- CRWLock **ppRWLock)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- PRECONDITION((CheckPointer(ppRWLock)));
- PRECONDITION((CheckPointer(*ppRWLock)));
- }
- CONTRACTL_END;
-
- // Check if the thread has writer lock
- if((*ppRWLock)->_dwWriterID == GetThread()->GetThreadId())
- {
- StaticReleaseWriterLock(ppRWLock);
- }
- else
- {
- LockEntry *pLockEntry = (*ppRWLock)->GetLockEntry();
- if(pLockEntry)
- {
- --pLockEntry->wReaderLevel;
- DECTHREADLOCKCOUNT();
- USER_LOCK_RELEASED(GetPtrForLockContract(ppRWLock));
- if(pLockEntry->wReaderLevel == 0)
- {
- DWORD dwCurrentState, dwKnownState, dwModifyState;
- BOOL fLastReader, fCacheEvents = FALSE;
- CLREvent* hReaderEvent = NULL, *hWriterEvent = NULL;
-
- // Sanity checks
- _ASSERTE(((*ppRWLock)->_dwState & WRITER) == 0);
- _ASSERTE((*ppRWLock)->_dwState & READERS_MASK);
-
- // Not a reader any more
- dwCurrentState = (*ppRWLock)->_dwState;
- do
- {
- dwKnownState = dwCurrentState;
- dwModifyState = (DWORD) -READER;
- if((dwKnownState & (READERS_MASK | READER_SIGNALED)) == READER)
- {
- fLastReader = TRUE;
- fCacheEvents = FALSE;
- if(dwKnownState & WAITING_WRITERS_MASK)
- {
- HRESULT hr;
- hWriterEvent = (*ppRWLock)->GetWriterEvent(&hr);
- if(hWriterEvent == NULL)
- {
- LOG((LF_SYNC, LL_WARNING,
- "ReleaseReaderLock failed to create "
- "writer event for RWLock 0x%x\n", *ppRWLock));
- RWSleep(100);
- dwCurrentState = (*ppRWLock)->_dwState;
- dwKnownState = 0;
- _ASSERTE(dwCurrentState != dwKnownState);
- continue;
- }
- dwModifyState += WRITER_SIGNALED;
- }
- else if(dwKnownState & WAITING_READERS_MASK)
- {
- HRESULT hr;
- hReaderEvent = (*ppRWLock)->GetReaderEvent(&hr);
- if(hReaderEvent == NULL)
- {
- LOG((LF_SYNC, LL_WARNING,
- "ReleaseReaderLock failed to create "
- "reader event\n", *ppRWLock));
- RWSleep(100);
- dwCurrentState = (*ppRWLock)->_dwState;
- dwKnownState = 0;
- _ASSERTE(dwCurrentState != dwKnownState);
- continue;
- }
- dwModifyState += READER_SIGNALED;
- }
- else if(((*ppRWLock)->_hReaderEvent || (*ppRWLock)->_hWriterEvent) &&
- (dwKnownState == READER))
- {
- fCacheEvents = TRUE;
- dwModifyState += CACHING_EVENTS;
- }
- }
- else
- {
- fLastReader = FALSE;
- }
-
- // Sanity checks
- _ASSERTE((dwKnownState & WRITER) == 0);
- _ASSERTE(dwKnownState & READERS_MASK);
-
- dwCurrentState = RWInterlockedCompareExchange(&(*ppRWLock)->_dwState,
- (dwKnownState + dwModifyState),
- dwKnownState);
- } while(dwCurrentState != dwKnownState);
-
- // Check for last reader
- if(fLastReader)
- {
- // Check for waiting writers
- if(dwKnownState & WAITING_WRITERS_MASK)
- {
- _ASSERTE((*ppRWLock)->_dwState & WRITER_SIGNALED);
- _ASSERTE(hWriterEvent);
- RWSetEvent(hWriterEvent);
- }
- // Check for waiting readers
- else if(dwKnownState & WAITING_READERS_MASK)
- {
- _ASSERTE((*ppRWLock)->_dwState & READER_SIGNALED);
- _ASSERTE(hReaderEvent);
- RWSetEvent(hReaderEvent);
- }
- // Check for the need to release events
- else if(fCacheEvents)
- {
- (*ppRWLock)->ReleaseEvents();
- }
- }
-
- // Recycle lock entry
- RecycleLockEntry(pLockEntry);
-
- Thread *pThread = GetThread();
- TESTHOOKCALL(AppDomainCanBeUnloaded(pThread->GetDomain()->GetId().m_dwId,FALSE));
-
- if (pThread->IsAbortRequested()) {
- pThread->HandleThreadAbort();
- }
- }
- }
- else
- {
- if(fBreakOnErrors) // fBreakOnErrors == FALSE so will be optimized out.
- {
- _ASSERTE(!"Attempt to release reader lock on a wrong thread");
- DebugBreak();
- }
- COMPlusThrowWin32(ERROR_NOT_OWNER);
- }
- }
-
- return;
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticDoUpgradeToWriterLockPublic private
-//
-// Synopsis: Public Access to StaticUpgradeToWriterLockPublic
-//
-//
-//+-------------------------------------------------------------------
-FCIMPL3(void, CRWLock::StaticDoUpgradeToWriterLockPublic, CRWLock *pRWLockUNSAFE, LockCookie * pLockCookie, DWORD dwDesiredTimeout)
-{
- FCALL_CONTRACT;
-
- if (pRWLockUNSAFE == NULL)
- {
- FCThrowVoid(kNullReferenceException);
- }
-
- OBJECTREF pRWLock = ObjectToOBJECTREF((Object*)pRWLockUNSAFE);
- HELPER_METHOD_FRAME_BEGIN_1(pRWLock);
- GCPROTECT_BEGININTERIOR (pLockCookie)
-
- StaticUpgradeToWriterLock((CRWLock**)&pRWLock, pLockCookie, dwDesiredTimeout);
-
- GCPROTECT_END ();
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticUpgradeToWriterLock Private
-//
-// Synopsis: Upgrades to a writer lock. It returns a BOOL that
-// indicates intervening writes.
-//
-
-//
-//+-------------------------------------------------------------------
-
-void CRWLock::StaticUpgradeToWriterLock(
- CRWLock **ppRWLock,
- LockCookie *pLockCookie,
- DWORD dwDesiredTimeout)
-
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- CAN_TAKE_LOCK;
- }
- CONTRACTL_END;
-
- DWORD dwThreadID = GetThread()->GetThreadId();
-
- // Check if the thread is already a writer
- if((*ppRWLock)->_dwWriterID == dwThreadID)
- {
- // Update cookie state
- pLockCookie->dwFlags = UPGRADE_COOKIE | COOKIE_WRITER;
- pLockCookie->wWriterLevel = (*ppRWLock)->_wWriterLevel;
-
- // Acquire the writer lock again
- StaticAcquireWriterLock(ppRWLock, dwDesiredTimeout);
- }
- else
- {
- BOOL fAcquireWriterLock;
- LockEntry *pLockEntry = (*ppRWLock)->GetLockEntry();
- if(pLockEntry == NULL)
- {
- fAcquireWriterLock = TRUE;
- pLockCookie->dwFlags = UPGRADE_COOKIE | COOKIE_NONE;
- }
- else
- {
- // Sanity check
- _ASSERTE((*ppRWLock)->_dwState & READERS_MASK);
- _ASSERTE(pLockEntry->wReaderLevel);
-
- // Save lock state in the cookie
- pLockCookie->dwFlags = UPGRADE_COOKIE | COOKIE_READER;
- pLockCookie->wReaderLevel = pLockEntry->wReaderLevel;
- pLockCookie->dwWriterSeqNum = (*ppRWLock)->_dwWriterSeqNum;
-
- // If there is only one reader, try to convert reader to a writer
- DWORD dwKnownState = RWInterlockedCompareExchange(&(*ppRWLock)->_dwState,
- WRITER,
- READER);
- if(dwKnownState == READER)
- {
- // Thread is no longer a reader
- Thread* pThread = GetThread();
- _ASSERTE (pThread);
- _ASSERTE (pThread->m_dwLockCount >= pLockEntry->wReaderLevel);
- ASSERT_UNLESS_NO_DEBUG_STATE(__pClrDebugState->GetLockCount(kDbgStateLockType_User) >= pLockEntry->wReaderLevel);
- pThread->m_dwLockCount -= pLockEntry->wReaderLevel;
- USER_LOCK_RELEASED_MULTIPLE(pLockEntry->wReaderLevel, GetPtrForLockContract(ppRWLock));
- pLockEntry->wReaderLevel = 0;
- RecycleLockEntry(pLockEntry);
-
- // Thread is a writer
- (*ppRWLock)->_dwWriterID = dwThreadID;
- (*ppRWLock)->_wWriterLevel = 1;
- INCTHREADLOCKCOUNT();
- USER_LOCK_TAKEN(GetPtrForLockContract(ppRWLock));
- ++(*ppRWLock)->_dwWriterSeqNum;
- fAcquireWriterLock = FALSE;
-
- // No intevening writes
-#if RWLOCK_STATISTICS
- ++(*ppRWLock)->_dwWriterEntryCount;
-#endif
- }
- else
- {
- // Release the reader lock
- Thread *pThread = GetThread();
- _ASSERTE (pThread);
- _ASSERTE (pThread->m_dwLockCount >= (DWORD)(pLockEntry->wReaderLevel - 1));
- ASSERT_UNLESS_NO_DEBUG_STATE(__pClrDebugState->GetLockCount(kDbgStateLockType_User) >=
- (DWORD)(pLockEntry->wReaderLevel - 1));
- pThread->m_dwLockCount -= (pLockEntry->wReaderLevel - 1);
- USER_LOCK_RELEASED_MULTIPLE(pLockEntry->wReaderLevel - 1, GetPtrForLockContract(ppRWLock));
- pLockEntry->wReaderLevel = 1;
- StaticReleaseReaderLock(ppRWLock);
- fAcquireWriterLock = TRUE;
- }
- }
-
- // Check for the need to acquire the writer lock
- if(fAcquireWriterLock)
- {
-
- // Declare and Setup the frame as we are aware of the contention
- // on the lock and the thread will most probably block
- // to acquire writer lock
-
- EX_TRY
- {
- StaticAcquireWriterLock(ppRWLock, dwDesiredTimeout);
- }
- EX_CATCH
- {
- // Invalidate cookie
- DWORD dwFlags = pLockCookie->dwFlags;
- pLockCookie->dwFlags = INVALID_COOKIE;
-
- StaticRecoverLock(ppRWLock, pLockCookie, dwFlags & COOKIE_READER);
-
- EX_RETHROW;
- }
- EX_END_CATCH_UNREACHABLE
- }
- }
-
-
- // Update the validation fields of the cookie
- pLockCookie->dwThreadID = dwThreadID;
-
- return;
-}
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticDowngradeFromWriterLock public
-//
-// Synopsis: Downgrades from a writer lock.
-//
-//+-------------------------------------------------------------------
-
-inline CRWLock* GetLock(OBJECTREF orLock)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- return (CRWLock*)OBJECTREFToObject(orLock);
-}
-
-FCIMPL2(void, CRWLock::StaticDowngradeFromWriterLock, CRWLock *pRWLockUNSAFE, LockCookie* pLockCookie)
-{
- FCALL_CONTRACT;
- STATIC_CONTRACT_CAN_TAKE_LOCK;
-
- DWORD dwThreadID = GetThread()->GetThreadId();
-
- if (pRWLockUNSAFE == NULL)
- {
- FCThrowVoid(kNullReferenceException);
- }
-
- if( NULL == pLockCookie) {
- FCThrowVoid(kNullReferenceException);
- }
-
- OBJECTREF pRWLock = ObjectToOBJECTREF((Object*)pRWLockUNSAFE);
- HELPER_METHOD_FRAME_BEGIN_1(pRWLock);
-
- if (GetLock(pRWLock)->_dwWriterID != dwThreadID)
- {
- COMPlusThrowWin32(ERROR_NOT_OWNER);
- }
-
- // Validate cookie
- DWORD dwStatus;
- if(((pLockCookie->dwFlags & INVALID_COOKIE) == 0) &&
- (pLockCookie->dwThreadID == dwThreadID))
- {
- DWORD dwFlags = pLockCookie->dwFlags;
- pLockCookie->dwFlags = INVALID_COOKIE;
-
- // Check if the thread was a reader
- if(dwFlags & COOKIE_READER)
- {
- // Sanity checks
- _ASSERTE(GetLock(pRWLock)->_wWriterLevel == 1);
-
- LockEntry *pLockEntry = GetLock(pRWLock)->FastGetOrCreateLockEntry();
- if(pLockEntry)
- {
- DWORD dwCurrentState, dwKnownState, dwModifyState;
- CLREvent* hReaderEvent = NULL;
-
- // Downgrade to a reader
- GetLock(pRWLock)->_dwWriterID = 0;
- GetLock(pRWLock)->_wWriterLevel = 0;
- DECTHREADLOCKCOUNT ();
- USER_LOCK_RELEASED(GetPtrForLockContract((CRWLock**)&pRWLock));
- dwCurrentState = GetLock(pRWLock)->_dwState;
- do
- {
- dwKnownState = dwCurrentState;
- dwModifyState = READER - WRITER;
- if(dwKnownState & WAITING_READERS_MASK)
- {
- HRESULT hr;
- hReaderEvent = GetLock(pRWLock)->GetReaderEvent(&hr);
- if(hReaderEvent == NULL)
- {
- LOG((LF_SYNC, LL_WARNING,
- "DowngradeFromWriterLock failed to create "
- "reader event for RWLock 0x%x\n", GetLock(pRWLock)));
- RWSleep(100);
- dwCurrentState = GetLock(pRWLock)->_dwState;
- dwKnownState = 0;
- _ASSERTE(dwCurrentState != dwKnownState);
- continue;
- }
- dwModifyState += READER_SIGNALED;
- }
-
- // Sanity checks
- _ASSERTE((dwKnownState & READERS_MASK) == 0);
-
- dwCurrentState = RWInterlockedCompareExchange(&GetLock(pRWLock)->_dwState,
- (dwKnownState + dwModifyState),
- dwKnownState);
- } while(dwCurrentState != dwKnownState);
-
- // Check for waiting readers
- if(dwKnownState & WAITING_READERS_MASK)
- {
- _ASSERTE(GetLock(pRWLock)->_dwState & READER_SIGNALED);
- _ASSERTE(hReaderEvent);
- RWSetEvent(hReaderEvent);
- }
-
- // Restore reader nesting level
- Thread *pThread = GetThread();
- _ASSERTE (pThread);
- _ASSERTE (pThread->m_dwLockCount >= pLockEntry->wReaderLevel);
- ASSERT_UNLESS_NO_DEBUG_STATE(__pClrDebugState->GetLockCount(kDbgStateLockType_User) >=
- pLockEntry->wReaderLevel);
- pThread->m_dwLockCount -= pLockEntry->wReaderLevel;
- USER_LOCK_RELEASED_MULTIPLE(pLockEntry->wReaderLevel, GetPtrForLockContract((CRWLock**)&pRWLock));
- pLockEntry->wReaderLevel = pLockCookie->wReaderLevel;
- pThread->m_dwLockCount += pLockEntry->wReaderLevel;
- USER_LOCK_TAKEN_MULTIPLE(pLockEntry->wReaderLevel, GetPtrForLockContract((CRWLock**)&pRWLock));
- #ifdef RWLOCK_STATISTICS
- RWInterlockedIncrement(&GetLock(pRWLock)->_dwReaderEntryCount);
- #endif
- }
- else
- {
- // Removed assert, as thread abort can occur normally
- dwStatus = RWLOCK_RECOVERY_FAILURE;
- goto ThrowException;
- }
- }
- else if(dwFlags & (COOKIE_WRITER | COOKIE_NONE))
- {
- // Release the writer lock
- StaticReleaseWriterLock((CRWLock**)&pRWLock);
- _ASSERTE((GetLock(pRWLock)->_dwWriterID != GetThread()->GetThreadId()) ||
- (dwFlags & COOKIE_WRITER));
- }
- }
- else
- {
- dwStatus = E_INVALIDARG;
-ThrowException:
- COMPlusThrowWin32(dwStatus);
- }
-
- HELPER_METHOD_FRAME_END();
-
- // Update the validation fields of the cookie
- pLockCookie->dwThreadID = dwThreadID;
-
-}
-FCIMPLEND
-
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticDoReleaseLock private
-//
-// Synopsis: Releases the lock held by the current thread
-//
-//+-------------------------------------------------------------------
-
-FCIMPL2(void, CRWLock::StaticDoReleaseLock, CRWLock *pRWLockUNSAFE, LockCookie * pLockCookie)
-{
- FCALL_CONTRACT;
-
- if (pRWLockUNSAFE == NULL)
- {
- FCThrowVoid(kNullReferenceException);
- }
-
- DWORD dwThreadID = GetThread()->GetThreadId();
-
- OBJECTREF pRWLock = ObjectToOBJECTREF((Object*)pRWLockUNSAFE);
-
- HELPER_METHOD_FRAME_BEGIN_ATTRIB_1(Frame::FRAME_ATTR_NO_THREAD_ABORT, pRWLock);
-
- // note that we cannot use this holder in FCALLs outside our HMF since it breaks the epilog walker on x86!
- ThreadPreventAbortHolder preventAbortIn;
-
- GCPROTECT_BEGININTERIOR (pLockCookie)
-
- // Check if the thread is a writer
- if(GetLock(pRWLock)->_dwWriterID == dwThreadID)
- {
- // Save lock state in the cookie
- pLockCookie->dwFlags = RELEASE_COOKIE | COOKIE_WRITER;
- pLockCookie->dwWriterSeqNum = GetLock(pRWLock)->_dwWriterSeqNum;
- pLockCookie->wWriterLevel = GetLock(pRWLock)->_wWriterLevel;
-
- // Release the writer lock
- Thread *pThread = GetThread();
- _ASSERTE (pThread);
- _ASSERTE (pThread->m_dwLockCount >= (DWORD)(GetLock(pRWLock)->_wWriterLevel - 1));
- ASSERT_UNLESS_NO_DEBUG_STATE(__pClrDebugState->GetLockCount(kDbgStateLockType_User) >=
- (DWORD)(GetLock(pRWLock)->_wWriterLevel - 1));
- pThread->m_dwLockCount -= (GetLock(pRWLock)->_wWriterLevel - 1);
- USER_LOCK_RELEASED_MULTIPLE(GetLock(pRWLock)->_wWriterLevel - 1, GetPtrForLockContract((CRWLock**)&pRWLock));
- GetLock(pRWLock)->_wWriterLevel = 1;
- StaticReleaseWriterLock((CRWLock**)&pRWLock);
- }
- else
- {
- LockEntry *pLockEntry = GetLock(pRWLock)->GetLockEntry();
- if(pLockEntry)
- {
- // Sanity check
- _ASSERTE(GetLock(pRWLock)->_dwState & READERS_MASK);
- _ASSERTE(pLockEntry->wReaderLevel);
-
- // Save lock state in the cookie
- pLockCookie->dwFlags = RELEASE_COOKIE | COOKIE_READER;
- pLockCookie->wReaderLevel = pLockEntry->wReaderLevel;
- pLockCookie->dwWriterSeqNum = GetLock(pRWLock)->_dwWriterSeqNum;
-
- // Release the reader lock
- Thread *pThread = GetThread();
- _ASSERTE (pThread);
- _ASSERTE (pThread->m_dwLockCount >= (DWORD)(pLockEntry->wReaderLevel - 1));
- ASSERT_UNLESS_NO_DEBUG_STATE(__pClrDebugState->GetLockCount(kDbgStateLockType_User) >=
- (DWORD)(pLockEntry->wReaderLevel - 1));
- pThread->m_dwLockCount -= (pLockEntry->wReaderLevel - 1);
- USER_LOCK_RELEASED_MULTIPLE(pLockEntry->wReaderLevel - 1, GetPtrForLockContract((CRWLock**)&pRWLock));
- pLockEntry->wReaderLevel = 1;
- StaticReleaseReaderLock((CRWLock**)&pRWLock);
- }
- else
- {
- pLockCookie->dwFlags = RELEASE_COOKIE | COOKIE_NONE;
- }
- }
-
- GCPROTECT_END ();
-
- HELPER_METHOD_FRAME_END();
-
- // Update the validation fields of the cookie
- pLockCookie->dwThreadID = dwThreadID;
-}
-FCIMPLEND
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticRestoreLockPublic public
-//
-// Synopsis: Public Access to StaticRestoreLock
-//
-//
-//+-------------------------------------------------------------------
-
-FCIMPL2(void, CRWLock::StaticRestoreLockPublic, CRWLock *pRWLockUNSAFE, LockCookie* pLockCookie)
-{
- FCALL_CONTRACT;
-
- if (pRWLockUNSAFE == NULL) {
- FCThrowVoid(kNullReferenceException);
- }
-
- if( NULL == pLockCookie) {
- FCThrowVoid(kNullReferenceException);
- }
-
- OBJECTREF pRWLock = ObjectToOBJECTREF((Object*)pRWLockUNSAFE);
- HELPER_METHOD_FRAME_BEGIN_1(pRWLock);
-
- StaticRestoreLock((CRWLock**)&pRWLock, pLockCookie);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-//+-------------------------------------------------------------------
-//
-// Method: CRWLock::StaticRestoreLock Private
-//
-// Synopsis: Restore the lock held by the current thread
-//
-
-//
-//+-------------------------------------------------------------------
-
-void CRWLock::StaticRestoreLock(
- CRWLock **ppRWLock,
- LockCookie *pLockCookie)
-{
- CONTRACTL
- {
- THROWS;
- CAN_TAKE_LOCK;
- GC_TRIGGERS; // CRWLock::StaticAquireWriterLock can trigger GC
- }
- CONTRACTL_END;
-
- // Validate cookie
- DWORD dwThreadID = GetThread()->GetThreadId();
- DWORD dwFlags = pLockCookie->dwFlags;
- if(pLockCookie->dwThreadID == dwThreadID)
- {
- if (((*ppRWLock)->_dwWriterID == dwThreadID) || ((*ppRWLock)->GetLockEntry() != NULL))
- {
- COMPlusThrow(kSynchronizationLockException, W("Arg_RWLockRestoreException"));
- }
-
- // Check for the no contention case
- pLockCookie->dwFlags = INVALID_COOKIE;
- if(dwFlags & COOKIE_WRITER)
- {
- if(RWInterlockedCompareExchange(&(*ppRWLock)->_dwState, WRITER, 0) == 0)
- {
- // Restore writer nesting level
- (*ppRWLock)->_dwWriterID = dwThreadID;
- Thread *pThread = GetThread();
- _ASSERTE (pThread);
- _ASSERTE (pThread->m_dwLockCount >= (*ppRWLock)->_wWriterLevel);
- ASSERT_UNLESS_NO_DEBUG_STATE(__pClrDebugState->GetLockCount(kDbgStateLockType_User) >=
- (*ppRWLock)->_wWriterLevel);
- pThread->m_dwLockCount -= (*ppRWLock)->_wWriterLevel;
- USER_LOCK_RELEASED_MULTIPLE((*ppRWLock)->_wWriterLevel, GetPtrForLockContract(ppRWLock));
- (*ppRWLock)->_wWriterLevel = pLockCookie->wWriterLevel;
- pThread->m_dwLockCount += (*ppRWLock)->_wWriterLevel;
- USER_LOCK_TAKEN_MULTIPLE((*ppRWLock)->_wWriterLevel, GetPtrForLockContract(ppRWLock));
- ++(*ppRWLock)->_dwWriterSeqNum;
-#ifdef RWLOCK_STATISTICS
- ++(*ppRWLock)->_dwWriterEntryCount;
-#endif
- goto LNormalReturn;
- }
- }
- else if(dwFlags & COOKIE_READER)
- {
- LockEntry *pLockEntry = (*ppRWLock)->FastGetOrCreateLockEntry();
- if(pLockEntry)
- {
- // This thread should not already be a reader
- // else bad things can happen
- _ASSERTE(pLockEntry->wReaderLevel == 0);
- DWORD dwKnownState = (*ppRWLock)->_dwState;
- if(dwKnownState < READERS_MASK)
- {
- DWORD dwCurrentState = RWInterlockedCompareExchange(&(*ppRWLock)->_dwState,
- (dwKnownState + READER),
- dwKnownState);
- if(dwCurrentState == dwKnownState)
- {
- // Restore reader nesting level
- Thread *pThread = GetThread();
- _ASSERTE (pThread);
- pLockEntry->wReaderLevel = pLockCookie->wReaderLevel;
- pThread->m_dwLockCount += pLockEntry->wReaderLevel;
- USER_LOCK_TAKEN_MULTIPLE(pLockEntry->wReaderLevel, GetPtrForLockContract(ppRWLock));
-#ifdef RWLOCK_STATISTICS
- RWInterlockedIncrement(&(*ppRWLock)->_dwReaderEntryCount);
-#endif
- goto LNormalReturn;
- }
- }
-
- // Recycle the lock entry for the slow case
- (*ppRWLock)->FastRecycleLockEntry(pLockEntry);
- }
- else
- {
- // Ignore the error and try again below. May be thread will luck
- // out the second time
- }
- }
- else if(dwFlags & COOKIE_NONE)
- {
- goto LNormalReturn;
- }
-
- // Declare and Setup the frame as we are aware of the contention
- // on the lock and the thread will most probably block
- // to acquire lock below
-ThrowException:
- if((dwFlags & INVALID_COOKIE) == 0)
- {
- StaticRecoverLock(ppRWLock, pLockCookie, dwFlags);
- }
- else
- {
- COMPlusThrowWin32(E_INVALIDARG);
- }
-
- goto LNormalReturn;
- }
- else
- {
- dwFlags = INVALID_COOKIE;
- goto ThrowException;
- }
-
-LNormalReturn:
- return;
-}
-
-
-//+-------------------------------------------------------------------
-//
-// Class: CRWLock::StaticPrivateInitialize
-//
-// Synopsis: Initialize lock
-//
-//+-------------------------------------------------------------------
-FCIMPL1(void, CRWLock::StaticPrivateInitialize, CRWLock *pRWLock)
-{
- FCALL_CONTRACT;
-
- HELPER_METHOD_FRAME_BEGIN_1(pRWLock);
-
- // Run the constructor on the GC allocated space
- // CRWLock's constructor can throw exception
-#ifndef _PREFAST_
- // Prefast falsely complains of memory leak.
- CRWLock *pTemp;
- pTemp = new (pRWLock) CRWLock();
- _ASSERTE(pTemp == pRWLock);
-#endif
-
- // Catch GC holes
- VALIDATE_LOCK(pRWLock);
-
- HELPER_METHOD_FRAME_END();
- return;
-}
-FCIMPLEND
-
-
-//+-------------------------------------------------------------------
-//
-// Class: CRWLock::StaticPrivateDestruct
-//
-// Synopsis: Destruct lock
-//+-------------------------------------------------------------------
-FCIMPL1(void, CRWLock::StaticPrivateDestruct, CRWLock *pRWLock)
-{
- FCALL_CONTRACT;
-
- HELPER_METHOD_FRAME_BEGIN_ATTRIB_1(Frame::FRAME_ATTR_NO_THREAD_ABORT, pRWLock);
-
- // Fixing one handle recycling security hole by
- // ensuring we don't delete the events more than once.
- // After deletion (for now, assuming ONE FINALIZER THREAD)
- // make the object essentially unusable by setting handle to
- // INVALID_HANDLE_VALUE (unusable) versus NULL (uninitialized)
-
- if ((pRWLock->_hWriterEvent != INVALID_HANDLE_VALUE) && (pRWLock->_hReaderEvent != INVALID_HANDLE_VALUE))
- {
- // Note, this still allows concurrent event consumers (such as StaticAcquireReaderLock)
- // to Set and/or Wait on non-events. There still exists a security hole here.
- if(pRWLock->_hWriterEvent)
- {
- CLREvent *h = (CLREvent *) FastInterlockExchangePointer((PVOID *)&(pRWLock->_hWriterEvent), INVALID_HANDLE_VALUE);
- delete h;
- }
- if(pRWLock->_hReaderEvent)
- {
- CLREvent *h = (CLREvent *) FastInterlockExchangePointer((PVOID *)&(pRWLock->_hReaderEvent), INVALID_HANDLE_VALUE);
- delete h;
- }
-
- // There is no LockEntry for this lock.
- if (pRWLock->_dwState != 0)
- {
- // Recycle LockEntry on threads
- ThreadStoreLockHolder tsl;
-
- // Take ThreadStore lock and walk over every thread in the process
- Thread *thread = NULL;
- while ((thread = ThreadStore::s_pThreadStore->GetAllThreadList(thread,
- Thread::TS_Unstarted|Thread::TS_Dead|Thread::TS_Detached, 0))
- != NULL)
- {
- LockEntry *pLockEntry;
- {
- CrstHolder rwl(&s_RWLockCrst);
- pLockEntry = pRWLock->GetLockEntry(thread);
- }
- if (pLockEntry)
- {
- // The entry does not belong to this lock anymore
- pLockEntry->dwLLockID = 0;
- pLockEntry->wReaderLevel = 0;
- }
- }
- }
- }
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-
-//+-------------------------------------------------------------------
-//
-// Class: CRWLock::StaticGetWriterSeqNum
-//
-// Synopsis: Returns the current sequence number
-//
-//+-------------------------------------------------------------------
-FCIMPL1(INT32, CRWLock::StaticGetWriterSeqNum, CRWLock *pRWLock)
-{
- FCALL_CONTRACT;
-
- if (pRWLock == NULL)
- {
- FCThrow(kNullReferenceException);
- }
-
- return(pRWLock->_dwWriterSeqNum);
-}
-FCIMPLEND
-
-
-//+-------------------------------------------------------------------
-//
-// Class: CRWLock::StaticAnyWritersSince
-//
-// Synopsis: Returns TRUE if there were writers since the given
-// sequence number
-//
-//+-------------------------------------------------------------------
-FCIMPL2(FC_BOOL_RET, CRWLock::StaticAnyWritersSince, CRWLock *pRWLock, DWORD dwSeqNum)
-{
- FCALL_CONTRACT;
-
- if (pRWLock == NULL)
- {
- FCThrow(kNullReferenceException);
- }
-
-
- if(pRWLock->_dwWriterID == GetThread()->GetThreadId())
- ++dwSeqNum;
-
- FC_RETURN_BOOL(pRWLock->_dwWriterSeqNum > dwSeqNum);
-}
-FCIMPLEND
-
-struct RWLockIterator
-{
- IHostTask **m_Owner;
- DWORD m_Capacity;
- DWORD m_index;
-};
-
-OBJECTHANDLE CRWLock::GetObjectHandle()
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- if (_hObjectHandle == NULL)
- {
- OBJECTREF obj = ObjectToOBJECTREF((Object*)this);
- OBJECTHANDLE handle = GetAppDomain()->CreateLongWeakHandle(obj);
- if (RWInterlockedCompareExchangePointer((PVOID*)&_hObjectHandle, handle, NULL) != NULL)
- {
- DestroyLongWeakHandle(handle);
- }
- }
- return _hObjectHandle;
-}
-
-// CRWLock::CreateOwnerIterator can return E_OUTOFMEMORY
-//
-HRESULT CRWLock::CreateOwnerIterator(SIZE_T *pIterator)
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_PREEMPTIVE;
- GC_NOTRIGGER;
- SO_INTOLERANT;
- }
- CONTRACTL_END;
-
- *pIterator = 0;
- if (_dwState == 0) {
- return S_OK;
- }
- NewHolder<RWLockIterator> IteratorHolder(new (nothrow) RWLockIterator);
- RWLockIterator *pRWLockIterator = IteratorHolder;
- if (pRWLockIterator == NULL) {
- return E_OUTOFMEMORY;
- }
- // Writer can be handled fast
- if (_dwState & WRITER) {
- DWORD writerID = _dwWriterID;
- if (writerID != 0)
- {
- pRWLockIterator->m_Capacity = 1;
- pRWLockIterator->m_index = 0;
- pRWLockIterator->m_Owner = new (nothrow) IHostTask*[1];
- if (pRWLockIterator->m_Owner == NULL) {
- return E_OUTOFMEMORY;
- }
- Thread *pThread = g_pThinLockThreadIdDispenser->IdToThreadWithValidation(writerID);
- if (pThread == NULL)
- {
- return S_OK;
- }
- IteratorHolder.SuppressRelease();
- pRWLockIterator->m_Owner[0] = pThread->GetHostTaskWithAddRef();
- *pIterator = (SIZE_T)pRWLockIterator;
- return S_OK;
- }
- }
- if (_dwState == 0) {
- return S_OK;
- }
- pRWLockIterator->m_Capacity = 4;
- pRWLockIterator->m_index = 0;
- pRWLockIterator->m_Owner = new (nothrow) IHostTask*[pRWLockIterator->m_Capacity];
- if (pRWLockIterator->m_Owner == NULL) {
- return E_OUTOFMEMORY;
- }
-
- HRESULT hr = S_OK;
-
- NewArrayHolder<IHostTask*> OwnerHolder(pRWLockIterator->m_Owner);
-
- // Take ThreadStore lock and walk over every thread in the process
- Thread *thread = NULL;
- while ((thread = ThreadStore::s_pThreadStore->GetAllThreadList(thread,
- Thread::TS_Unstarted|Thread::TS_Dead|Thread::TS_Detached, 0))
- != NULL)
- {
- LockEntry *pLockEntry;
- {
- CrstHolder rwl(&s_RWLockCrst);
- pLockEntry = GetLockEntry(thread);
- }
- if (pLockEntry && pLockEntry->wReaderLevel >= 1) {
- if (pRWLockIterator->m_index == pRWLockIterator->m_Capacity) {
- IHostTask** newArray = new (nothrow) IHostTask*[2*pRWLockIterator->m_Capacity];
- if (newArray == NULL) {
- hr = E_OUTOFMEMORY;
- break;
- }
- memcpy (newArray,pRWLockIterator->m_Owner,pRWLockIterator->m_Capacity*sizeof(IHostTask*));
- pRWLockIterator->m_Owner = newArray;
- pRWLockIterator->m_Capacity *= 2;
- OwnerHolder = pRWLockIterator->m_Owner;
- }
- IHostTask *pHostTask = thread->GetHostTaskWithAddRef();
- if (pHostTask)
- {
- pRWLockIterator->m_Owner[pRWLockIterator->m_index++] = pHostTask;
- }
- }
- }
- if (FAILED(hr))
- {
- for (DWORD i = 0; i < pRWLockIterator->m_index; i ++)
- {
- if (pRWLockIterator->m_Owner[i])
- {
- pRWLockIterator->m_Owner[i]->Release();
- }
- }
- }
- if (SUCCEEDED(hr)) {
- IteratorHolder.SuppressRelease();
- OwnerHolder.SuppressRelease();
- pRWLockIterator->m_Capacity = pRWLockIterator->m_index;
- pRWLockIterator->m_index = 0;
- *pIterator = (SIZE_T)pRWLockIterator;
- }
-
- return hr;
-}
-
-void CRWLock::GetNextOwner(SIZE_T Iterator, IHostTask **ppOwnerHostTask)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- *ppOwnerHostTask = NULL;
- if (Iterator) {
- RWLockIterator* tmp = (RWLockIterator*)Iterator;
- if (tmp->m_index < tmp->m_Capacity) {
- *ppOwnerHostTask = tmp->m_Owner[tmp->m_index];
- tmp->m_index ++;
- }
- }
-}
-
-void CRWLock::DeleteOwnerIterator(SIZE_T Iterator)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
-
- if (Iterator) {
- RWLockIterator* pIterator = (RWLockIterator*)Iterator;
- while (pIterator->m_index < pIterator->m_Capacity) {
- IHostTask *pHostTask = pIterator->m_Owner[pIterator->m_index];
- if (pHostTask)
- {
- pHostTask->Release();
- }
- pIterator->m_index ++;
- }
- delete[] pIterator->m_Owner;
- delete pIterator;
- }
-}
-#endif // FEATURE_RWLOCK
diff --git a/src/vm/rwlock.h b/src/vm/rwlock.h
deleted file mode 100644
index dc8e67e6fb..0000000000
--- a/src/vm/rwlock.h
+++ /dev/null
@@ -1,287 +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.
-//
-
-//
-//+-------------------------------------------------------------------
-//
-// File: RWLock.h
-//
-// Contents: Reader writer lock implementation that supports the
-// following features
-// 1. Cheap enough to be used in large numbers
-// such as per object synchronization.
-// 2. Supports timeout. This is a valuable feature
-// to detect deadlocks
-// 3. Supports caching of events. The allows
-// the events to be moved from least contentious
-// regions to the most contentious regions.
-// In other words, the number of events needed by
-// Reader-Writer lockls is bounded by the number
-// of threads in the process.
-// 4. Supports nested locks by readers and writers
-// 5. Supports spin counts for avoiding context switches
-// on multi processor machines.
-// 6. Supports functionality for upgrading to a writer
-// lock with a return argument that indicates
-// intermediate writes. Downgrading from a writer
-// lock restores the state of the lock.
-// 7. Supports functionality to Release Lock for calling
-// app code. RestoreLock restores the lock state and
-// indicates intermediate writes.
-// 8. Recovers from most common failures such as creation of
-// events. In other words, the lock mainitains consistent
-// internal state and remains usable
-//
-// Classes: CRWLock,
-// CStaticRWLock
-//
-//--------------------------------------------------------------------
-
-#ifdef FEATURE_RWLOCK
-#ifndef _RWLOCK_H_
-#define _RWLOCK_H_
-#include "common.h"
-#include "threads.h"
-
-// If you do define this, make sure you define this in managed as well.
-//#define RWLOCK_STATISTICS 0
-
-extern DWORD gdwDefaultTimeout;
-extern DWORD gdwDefaultSpinCount;
-
-
-//+-------------------------------------------------------------------
-//
-// Struct: LockCookie
-//
-// Synopsis: Lock cookies returned to the client
-//
-//+-------------------------------------------------------------------
-typedef struct {
- DWORD dwFlags;
- DWORD dwWriterSeqNum;
- WORD wReaderLevel;
- WORD wWriterLevel;
- DWORD dwThreadID;
-} LockCookie;
-
-//+-------------------------------------------------------------------
-//
-// Class: CRWLock
-//
-// Synopsis: Class the implements the reader writer locks.
-//
-//+-------------------------------------------------------------------
-class CRWLock : public Object
-{
- friend class MscorlibBinder;
-
-public:
- // Constuctor
- CRWLock();
-
- // Cleanup
- void Cleanup();
-
- OBJECTHANDLE GetObjectHandle();
- HRESULT CreateOwnerIterator(SIZE_T *pIterator);
- static void GetNextOwner(SIZE_T Iterator, IHostTask **ppOwnerHostTask);
- static void DeleteOwnerIterator(SIZE_T Iterator);
-
- // Statics that do the core work
- static FCDECL1 (void, StaticPrivateInitialize, CRWLock *pRWLock);
- static FCDECL1 (void, StaticPrivateDestruct, CRWLock *pRWLock);
- static FCDECL2 (void, StaticAcquireReaderLockPublic, CRWLock *pRWLock, DWORD dwDesiredTimeout);
- static FCDECL2 (void, StaticAcquireWriterLockPublic, CRWLock *pRWLock, DWORD dwDesiredTimeout);
- static FCDECL1 (void, StaticReleaseReaderLockPublic, CRWLock *pRWLock);
- static FCDECL1 (void, StaticReleaseWriterLockPublic, CRWLock *pRWLock);
- static FCDECL3 (void, StaticDoUpgradeToWriterLockPublic, CRWLock *pRWLock, LockCookie * pLockCookie, DWORD dwDesiredTimeout);
- static FCDECL2 (void, StaticDowngradeFromWriterLock, CRWLock *pRWLock, LockCookie* pLockCookie);
- static FCDECL2 (void, StaticDoReleaseLock, CRWLock *pRWLock, LockCookie * pLockCookie);
- static FCDECL2 (void, StaticRestoreLockPublic, CRWLock *pRWLock, LockCookie* pLockCookie);
- static FCDECL1 (FC_BOOL_RET, StaticIsReaderLockHeld, CRWLock *pRWLock);
- static FCDECL1 (FC_BOOL_RET, StaticIsWriterLockHeld, CRWLock *pRWLock);
- static FCDECL1 (INT32, StaticGetWriterSeqNum, CRWLock *pRWLock);
- static FCDECL2 (FC_BOOL_RET, StaticAnyWritersSince, CRWLock *pRWLock, DWORD dwSeqNum);
-private:
- static void StaticAcquireReaderLock(CRWLock **ppRWLock, DWORD dwDesiredTimeout);
- static void StaticAcquireWriterLock(CRWLock **ppRWLock, DWORD dwDesiredTimeout);
- static void StaticReleaseReaderLock(CRWLock **ppRWLock);
- static void StaticReleaseWriterLock(CRWLock **ppRWLock);
- static void StaticRecoverLock(CRWLock **ppRWLock, LockCookie *pLockCookie, DWORD dwFlags);
- static void StaticRestoreLock(CRWLock **ppRWLock, LockCookie *pLockCookie);
- static void StaticUpgradeToWriterLock(CRWLock **ppRWLock, LockCookie *pLockCookie, DWORD dwDesiredTimeout);
-public:
- // Assert functions
-#ifdef _DEBUG
- BOOL AssertWriterLockHeld();
- BOOL AssertWriterLockNotHeld();
- BOOL AssertReaderLockHeld();
- BOOL AssertReaderLockNotHeld();
- BOOL AssertReaderOrWriterLockHeld();
- void AssertHeld()
- {
- WRAPPER_NO_CONTRACT;
- AssertWriterLockHeld();
- }
- void AssertNotHeld()
- {
- WRAPPER_NO_CONTRACT;
- AssertWriterLockNotHeld();
- AssertReaderLockNotHeld();
- }
-#else
- void AssertWriterLockHeld() { LIMITED_METHOD_CONTRACT; }
- void AssertWriterLockNotHeld() { LIMITED_METHOD_CONTRACT; }
- void AssertReaderLockHeld() { LIMITED_METHOD_CONTRACT; }
- void AssertReaderLockNotHeld() { LIMITED_METHOD_CONTRACT; }
- void AssertReaderOrWriterLockHeld() { LIMITED_METHOD_CONTRACT; }
- void AssertHeld() { LIMITED_METHOD_CONTRACT; }
- void AssertNotHeld() { LIMITED_METHOD_CONTRACT; }
-#endif
-
- // Helper functions
-#ifdef RWLOCK_STATISTICS
- DWORD GetReaderEntryCount()
- {
- LIMITED_METHOD_CONTRACT;
- return(_dwReaderEntryCount);
- }
- DWORD GetReaderContentionCount() { LIMITED_METHOD_CONTRACT; return(_dwReaderContentionCount); }
- DWORD GetWriterEntryCount() { LIMITED_METHOD_CONTRACT; return(_dwWriterEntryCount); }
- DWORD GetWriterContentionCount() { LIMITED_METHOD_CONTRACT; return(_dwWriterContentionCount); }
-#endif
- // Static functions
- static void *operator new(size_t size)
- {
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- return ::operator new(size);
- }
- static void ProcessInit();
-
- static void SetTimeout(DWORD dwTimeout)
- {
- LIMITED_METHOD_CONTRACT;
-
- gdwDefaultTimeout = dwTimeout;
- }
- static DWORD GetTimeout()
- {
- LIMITED_METHOD_CONTRACT;
- return(gdwDefaultTimeout);
- }
- static void SetSpinCount(DWORD dwSpinCount)
- {
- LIMITED_METHOD_CONTRACT;
-
- gdwDefaultSpinCount = g_SystemInfo.dwNumberOfProcessors > 1
- ? dwSpinCount
- : 0;
- }
- static DWORD GetSpinCount() { LIMITED_METHOD_CONTRACT; return(gdwDefaultSpinCount); }
-
-private:
- // Private helpers
- static void ChainEntry(Thread *pThread, LockEntry *pLockEntry);
- LockEntry *GetLockEntry(Thread *pThread = NULL);
- LockEntry *FastGetOrCreateLockEntry();
- LockEntry *SlowGetOrCreateLockEntry(Thread *pThread);
- void FastRecycleLockEntry(LockEntry *pLockEntry);
- static void RecycleLockEntry(LockEntry *pLockEntry);
-
- CLREvent* GetReaderEvent(HRESULT *pHR);
- CLREvent* GetWriterEvent(HRESULT *pHR);
- void ReleaseEvents();
-
- static LONG RWInterlockedCompareExchange(LONG RAW_KEYWORD(volatile) *pvDestination,
- LONG dwExchange,
- LONG dwComperand);
- static LONGLONG RWInterlockedCompareExchange64(LONGLONG RAW_KEYWORD(volatile) *pvDestination,
- LONGLONG qwExchange,
- LONGLONG qwComparand);
- static void* RWInterlockedCompareExchangePointer(PVOID RAW_KEYWORD(volatile) *pvDestination,
- PVOID pExchange,
- PVOID pComparand);
- static LONG RWInterlockedExchangeAdd(LONG RAW_KEYWORD(volatile) *pvDestination, LONG dwAddState);
- static LONG RWInterlockedIncrement(LONG RAW_KEYWORD(volatile) *pdwState);
-
- static DWORD RWWaitForSingleObject(CLREvent* event, DWORD dwTimeout);
- static void RWSetEvent(CLREvent* event);
- static void RWResetEvent(CLREvent* event);
- static void RWSleep(DWORD dwTime);
-
-#if defined(ENABLE_CONTRACTS_IMPL)
- // The LOCK_TAKEN/RELEASED macros need a "pointer" to the lock object to do
- // comparisons between takes & releases (and to provide debugging info to the
- // developer). We can't use "this" (*ppRWLock), because CRWLock is an Object and thus
- // can move. So we use _dwLLockID instead. It's not exactly unique, but it's
- // good enough--worst that can happen is if a thread takes RWLock A and erroneously
- // releases RWLock B (instead of A), we'll fail to catch that if their _dwLLockID's
- // are the same. On 64 bits, we can use both _dwULockID & _dwLLockID and be unique
- static void * GetPtrForLockContract(CRWLock ** ppRWLock)
- {
-#if defined(_WIN64)
- return (void *)
- (
- (
- ((__int64) ((*ppRWLock)->_dwULockID)) << 32
- )
- |
- (
- (__int64) ((*ppRWLock)->_dwLLockID)
- )
- );
-#else //defined(_WIN64)
- return LongToPtr((*ppRWLock)->_dwLLockID);
-#endif //defined(_WIN64)
- }
-#endif //defined(ENABLE_CONTRACTS_IMPL)
-
- // private new
- static void *operator new(size_t size, void *pv) { LIMITED_METHOD_CONTRACT; return(pv); }
-
- // Private data
- CLREvent *_hWriterEvent;
- CLREvent *_hReaderEvent;
- OBJECTHANDLE _hObjectHandle;
- Volatile<LONG> _dwState;
- LONG _dwULockID;
- LONG _dwLLockID;
- DWORD _dwWriterID;
- DWORD _dwWriterSeqNum;
- WORD _wWriterLevel;
-#ifdef RWLOCK_STATISTICS
- // WARNING: You must explicitly #define RWLOCK_STATISTICS when you build
- // in both the VM and BCL directories, as the managed class must also
- // contain these fields!
- Volatile<LONG> _dwReaderEntryCount;
- Volatile<LONG> _dwReaderContentionCount;
- Volatile<LONG> _dwWriterEntryCount;
- Volatile<LONG> _dwWriterContentionCount;
- Volatile<LONG> _dwEventsReleasedCount;
-#endif
-
- // Static data
- static Volatile<LONGLONG> s_mostRecentLockID;
- static CrstStatic s_RWLockCrst;
-};
-
-#ifdef USE_CHECKED_OBJECTREFS
-typedef REF<CRWLock> RWLOCKREF;
-
-#else
-typedef CRWLock* RWLOCKREF;
-#endif
-
-#endif // _RWLOCK_H_
-
-#endif // FEATURE_RWLOCK
-
diff --git a/src/vm/sampleprofiler.cpp b/src/vm/sampleprofiler.cpp
new file mode 100644
index 0000000000..004b3c68b0
--- /dev/null
+++ b/src/vm/sampleprofiler.cpp
@@ -0,0 +1,155 @@
+// 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 "common.h"
+#include "sampleprofiler.h"
+#include "hosting.h"
+#include "threadsuspend.h"
+
+Volatile<BOOL> SampleProfiler::s_profilingEnabled = false;
+Thread* SampleProfiler::s_pSamplingThread = NULL;
+CLREventStatic SampleProfiler::s_threadShutdownEvent;
+#ifdef FEATURE_PAL
+long SampleProfiler::s_samplingRateInNs = 1000000; // 1ms
+#endif
+
+// Synchronization of multiple callers occurs in EventPipe::Enable.
+void SampleProfiler::Enable()
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ PRECONDITION(s_pSamplingThread == NULL);
+ }
+ CONTRACTL_END;
+
+ s_profilingEnabled = true;
+ s_pSamplingThread = SetupUnstartedThread();
+ if(s_pSamplingThread->CreateNewThread(0, ThreadProc, NULL))
+ {
+ // Start the sampling thread.
+ s_pSamplingThread->SetBackground(TRUE);
+ s_pSamplingThread->StartThread();
+ }
+ else
+ {
+ _ASSERT(!"Unable to create sample profiler thread.");
+ }
+}
+
+// Synchronization of multiple callers occurs in EventPipe::Disable.
+void SampleProfiler::Disable()
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ // Bail early if profiling is not enabled.
+ if(!s_profilingEnabled)
+ {
+ return;
+ }
+
+ // Reset the event before shutdown.
+ s_threadShutdownEvent.Reset();
+
+ // The sampling thread will watch this value and exit
+ // when profiling is disabled.
+ s_profilingEnabled = false;
+
+ // Wait for the sampling thread to clean itself up.
+ s_threadShutdownEvent.Wait(0, FALSE /* bAlertable */);
+}
+
+DWORD WINAPI SampleProfiler::ThreadProc(void *args)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ PRECONDITION(s_pSamplingThread != NULL);
+ }
+ CONTRACTL_END;
+
+ // Complete thread initialization and start the profiling loop.
+ if(s_pSamplingThread->HasStarted())
+ {
+ // Switch to pre-emptive mode so that this thread doesn't starve the GC.
+ GCX_PREEMP();
+
+ while(s_profilingEnabled)
+ {
+ // Check to see if we can suspend managed execution.
+ if(ThreadSuspend::SysIsSuspendInProgress() || (ThreadSuspend::GetSuspensionThread() != 0))
+ {
+ // Skip the current sample.
+#ifdef FEATURE_PAL
+ PAL_nanosleep(s_samplingRateInNs);
+#else
+ ClrSleepEx(1, FALSE);
+#endif
+ continue;
+ }
+
+ // Actually suspend managed execution.
+ ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_REASON::SUSPEND_OTHER);
+
+ // Walk all managed threads and capture stacks.
+ WalkManagedThreads();
+
+ // Resume managed execution.
+ ThreadSuspend::RestartEE(FALSE /* bFinishedGC */, TRUE /* SuspendSucceeded */);
+
+ // Wait until it's time to sample again.
+#ifdef FEATURE_PAL
+ PAL_nanosleep(s_samplingRateInNs);
+#else
+ ClrSleepEx(1, FALSE);
+#endif
+ }
+ }
+
+ // Destroy the sampling thread when done running.
+ DestroyThread(s_pSamplingThread);
+ s_pSamplingThread = NULL;
+
+ // Signal Disable() that the thread has been destroyed.
+ s_threadShutdownEvent.Set();
+
+ return S_OK;
+}
+
+// The thread store lock must already be held by the thread before this function
+// is called. ThreadSuspend::SuspendEE acquires the thread store lock.
+void SampleProfiler::WalkManagedThreads()
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_TRIGGERS;
+ MODE_PREEMPTIVE;
+ }
+ CONTRACTL_END;
+
+ Thread *pThread = NULL;
+ StackContents stackContents;
+
+ // Iterate over all managed threads.
+ // Assumes that the ThreadStoreLock is held because we've suspended all threads.
+ while ((pThread = ThreadStore::GetThreadList(pThread)) != NULL)
+ {
+ // Walk the stack and write it out as an event.
+ if(EventPipe::WalkManagedStackForThread(pThread, stackContents) && !stackContents.IsEmpty())
+ {
+ EventPipe::WriteSampleProfileEvent(pThread, stackContents);
+ }
+ }
+}
diff --git a/src/vm/sampleprofiler.h b/src/vm/sampleprofiler.h
new file mode 100644
index 0000000000..2c7466f4c9
--- /dev/null
+++ b/src/vm/sampleprofiler.h
@@ -0,0 +1,44 @@
+// 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.
+
+#ifndef __SAMPLEPROFILER_H__
+#define __SAMPLEPROFILER_H__
+
+#include "common.h"
+#include "eventpipe.h"
+
+class SampleProfiler
+{
+ public:
+
+ // Enable profiling.
+ static void Enable();
+
+ // Disable profiling.
+ static void Disable();
+
+ private:
+
+ // Iterate through all managed threads and walk all stacks.
+ static void WalkManagedThreads();
+
+ // Profiling thread proc. Invoked on a new thread when profiling is enabled.
+ static DWORD WINAPI SampleProfiler::ThreadProc(void *args);
+
+ // True when profiling is enabled.
+ static Volatile<BOOL> s_profilingEnabled;
+
+ // The sampling thread.
+ static Thread *s_pSamplingThread;
+
+ // Thread shutdown event for synchronization between Disable() and the sampling thread.
+ static CLREventStatic s_threadShutdownEvent;
+
+#ifdef FEATURE_PAL
+ // The sampling rate.
+ static long s_samplingRateInNs;
+#endif
+};
+
+#endif // __SAMPLEPROFILER_H__
diff --git a/src/vm/security.cpp b/src/vm/security.cpp
index 95c16bf5cd..2afb946467 100644
--- a/src/vm/security.cpp
+++ b/src/vm/security.cpp
@@ -41,31 +41,13 @@ void Security::DeleteSharedSecurityDescriptor(ISharedSecurityDescriptor *descrip
delete static_cast<SharedSecurityDescriptor *>(descriptor);
}
-#ifndef FEATURE_CORECLR
-IPEFileSecurityDescriptor* Security::CreatePEFileSecurityDescriptor(AppDomain* pDomain, PEFile *pPEFile)
-{
- WRAPPER_NO_CONTRACT;
-
- return static_cast<IPEFileSecurityDescriptor*>(new PEFileSecurityDescriptor(pDomain, pPEFile));
-}
-#endif
BOOL Security::IsTransparencyEnforcementEnabled()
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_CORECLR
// No transparency enforcement in .NET Core
return FALSE;
-#else
-
-#ifdef _DEBUG
- if (g_pConfig->DisableTransparencyEnforcement())
- return FALSE;
-#endif
-
- return TRUE;
-#endif // FEATURE_CORECLR
}
//---------------------------------------------------------------------------------------
diff --git a/src/vm/security.h b/src/vm/security.h
index 3f3cb38c09..7f42c4b10b 100644
--- a/src/vm/security.h
+++ b/src/vm/security.h
@@ -16,9 +16,6 @@
#include "securitydeclarative.h"
#include "securitytransparentassembly.h"
-#ifdef FEATURE_APTCA
-#include "aptca.h"
-#endif
class IAssemblySecurityDescriptor;
class IApplicationSecurityDescriptor;
@@ -71,10 +68,6 @@ namespace Security
inline void SaveCache();
// Policy
-#ifdef FEATURE_CAS_POLICY
- inline bool IsProcessWideLegacyCasPolicyEnabled();
- inline bool CanLoadFromRemoteSources();
-#endif // FEATURE_CAS_POLICY
BOOL IsTransparencyEnforcementEnabled();
@@ -132,17 +125,8 @@ namespace Security
// other CAS Actions
inline void Demand(SecurityStackWalkType eType, OBJECTREF demand) ;
-#ifdef FEATURE_CAS_POLICY
- inline void DemandGrantSet(IAssemblySecurityDescriptor *psdAssembly);
-#endif // FEATURE_CAS_POLICY
inline void DemandSet(SecurityStackWalkType eType, OBJECTREF demand) ;
inline void DemandSet(SecurityStackWalkType eType, PsetCacheEntry *pPCE, DWORD dwAction) ;
-#ifdef FEATURE_CAS_POLICY
- inline void ReflectionTargetDemand(DWORD dwPermission, IAssemblySecurityDescriptor *psdTarget);
- inline void ReflectionTargetDemand(DWORD dwPermission,
- IAssemblySecurityDescriptor *psdTarget,
- DynamicResolver * pAccessContext);
-#endif // FEATURE_CAS_POLICY
inline void SpecialDemand(SecurityStackWalkType eType, DWORD whatPermission) ;
inline void InheritanceLinkDemandCheck(Assembly *pTargetAssembly, MethodDesc * pMDLinkDemand);
@@ -151,10 +135,6 @@ namespace Security
inline void FullTrustLinkDemand(Assembly *pTargetAssembly);
// Compressed Stack
-#ifdef FEATURE_COMPRESSEDSTACK
- inline COMPRESSEDSTACKREF GetCSFromContextTransitionFrame(Frame *pFrame) ;
- inline BOOL IsContextTransitionFrameWithCS(Frame *pFrame);
-#endif // #ifdef FEATURE_COMPRESSEDSTACK
// Misc - todo: put these in better categories
@@ -163,9 +143,6 @@ namespace Security
IAssemblySecurityDescriptor* CreateAssemblySecurityDescriptor(AppDomain *pDomain, DomainAssembly *pAssembly, LoaderAllocator *pLoaderAllocator);
ISharedSecurityDescriptor* CreateSharedSecurityDescriptor(Assembly* pAssembly);
void DeleteSharedSecurityDescriptor(ISharedSecurityDescriptor *descriptor);
-#ifndef FEATURE_CORECLR
- IPEFileSecurityDescriptor* CreatePEFileSecurityDescriptor(AppDomain* pDomain, PEFile *pPEFile);
-#endif
inline void SetDefaultAppDomainProperty(IApplicationSecurityDescriptor* pASD);
inline void SetDefaultAppDomainEvidenceProperty(IApplicationSecurityDescriptor* pASD);
@@ -224,15 +201,6 @@ namespace Security
// security enforcement
inline BOOL ContainsBuiltinCASPermsOnly(CORSEC_ATTRSET* pAttrSet);
-#ifdef FEATURE_APTCA
- inline BOOL IsUntrustedCallerCheckNeeded(MethodDesc *pCalleeMD, Assembly *pCallerAssem = NULL) ;
- inline void DoUntrustedCallerChecks(Assembly *pCaller, MethodDesc *pCalee, BOOL fFullStackWalk) ;
-
- inline bool NativeImageHasValidAptcaDependencies(PEImage *pNativeImage, DomainAssembly *pDomainAssembly);
-
- inline SString GetAptcaKillBitAccessExceptionContext(Assembly *pTargetAssembly);
- inline SString GetConditionalAptcaAccessExceptionContext(Assembly *pTargetAssembly);
-#endif // FEATURE_APTCA
inline bool SecurityCalloutQuickCheck(MethodDesc *pCallerMD);
@@ -258,11 +226,6 @@ public:
virtual void Resolve() = 0;
virtual BOOL IsResolved() const = 0;
-#ifdef FEATURE_CAS_POLICY
- virtual OBJECTREF GetEvidence() = 0;
- virtual BOOL IsEvidenceComputed() const = 0;
- virtual void SetEvidence(OBJECTREF evidence) = 0;
-#endif // FEATURE_CAS_POLICY
virtual OBJECTREF GetGrantedPermissionSet(OBJECTREF* RefusedPermissions = NULL) = 0;
#endif // !DACCESS_COMPILE
@@ -299,16 +262,7 @@ public:
// or if unmanaged code access is allowed at this time
virtual DWORD GetDomainWideSpecialFlag() const = 0;
-#ifdef FEATURE_CAS_POLICY
- virtual void SetLegacyCasPolicyEnabled() = 0;
- virtual BOOL IsLegacyCasPolicyEnabled() = 0;
- virtual BOOL AllowsLoadsFromRemoteSources() = 0;
-#endif // FEATURE_CAS_POLICY
-#ifdef FEATURE_APTCA
- virtual ConditionalAptcaCache *GetConditionalAptcaCache() = 0;
- virtual void SetCanonicalConditionalAptcaList(LPCWSTR wszCanonicalConditionalAptcaList) = 0;
-#endif // FEATURE_APTCA
#endif // !DACCESS_COMPILE
};
@@ -331,20 +285,9 @@ public:
virtual void ResolvePolicy(ISharedSecurityDescriptor *pSharedDesc, BOOL fShouldSkipPolicyResolution) = 0;
-#ifdef FEATURE_CAS_POLICY
- virtual HRESULT LoadSignature( COR_TRUST **ppSignature = NULL) = 0;
-
- virtual void SetAdditionalEvidence(OBJECTREF evidence) = 0;
- virtual BOOL HasAdditionalEvidence() = 0;
- virtual OBJECTREF GetAdditionalEvidence() = 0;
- virtual void SetEvidenceFromPEFile(IPEFileSecurityDescriptor *pPEFileSecDesc) = 0;
-#endif // FEATURE_CAS_POLICY
virtual void PropagatePermissionSet(OBJECTREF GrantedPermissionSet, OBJECTREF DeniedPermissionSet, DWORD dwSpecialFlags) = 0;
-#ifndef FEATURE_CORECLR
- virtual BOOL AllowApplicationSpecifiedAppDomainManager() = 0;
-#endif
// Check to make sure that security will allow this assembly to load. Throw an exception if the
// assembly should be forbidden from loading for security related purposes
@@ -361,13 +304,6 @@ public:
virtual Assembly* GetAssembly() = 0;
};
-#ifndef FEATURE_CORECLR
-class IPEFileSecurityDescriptor : public ISecurityDescriptor
-{
-public:
- virtual BOOL AllowBindingRedirects() = 0;
-};
-#endif
#include "security.inl"
#include "securitydeclarative.inl"
diff --git a/src/vm/security.inl b/src/vm/security.inl
index fe11589787..f2d7d7d683 100644
--- a/src/vm/security.inl
+++ b/src/vm/security.inl
@@ -25,59 +25,10 @@ inline void Security::Stop()
WRAPPER_NO_CONTRACT;
SecurityPolicy::Stop();
}
-#ifdef FEATURE_CAS_POLICY
-inline void Security::SaveCache()
-{
- WRAPPER_NO_CONTRACT;
- SecurityPolicy::SaveCache();
-}
-#endif
// ----------------------------------------
// SecurityPolicy
// ----------------------------------------
-#ifdef FEATURE_CAS_POLICY
-
-//---------------------------------------------------------------------------------------
-//
-// Determine if the entire process is running with CAS policy enabled for legacy
-// compatibility. If this value is false, the CLR does not apply any security policy.
-// Instead, it defers to a host if one is present or grants assemblies full trust.
-//
-
-inline bool Security::IsProcessWideLegacyCasPolicyEnabled()
-{
- LIMITED_METHOD_CONTRACT;
-
- // APPX precludes the use of legacy CAS policy
- if (AppX::IsAppXProcess())
- {
- return false;
- }
-
- return CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Security_LegacyCasPolicy) ||
- CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Security_NetFx40LegacySecurityPolicy);
-}
-
-//---------------------------------------------------------------------------------------
-//
-// In pre-v4 versions of the CLR, doing a LoadFrom for a file in a remote location would
-// implicitly sandbox that assembly. If CAS policy is disabled, then these applications
-// will suddenly be granting full trust to assemblies they expected to be sandboxed. In
-// order to prevent this, these LoadFroms are disabled unless the application has explcitly
-// configured itself to allow them.
-//
-// This method returns the a value that indicates if the application has indicated that it
-// is safe to LoadFrom remote locations and that the CLR should not block these loads.
-//
-
-inline bool Security::CanLoadFromRemoteSources()
-{
- WRAPPER_NO_CONTRACT;
- return !!CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_Security_LoadFromRemoteSources);
-}
-
-#endif // FEATURE_CAS_POLICY
inline BOOL Security::CanCallUnmanagedCode(Module *pModule)
{
@@ -173,17 +124,11 @@ inline LinktimeCheckReason Security::GetLinktimeCheckReason(MethodDesc *pMD,
inline void Security::CheckLinkDemandAgainstAppDomain(MethodDesc *pMD)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityDeclarative::CheckLinkDemandAgainstAppDomain(pMD);
-#endif
}
inline void Security::LinktimeCheckMethod(Assembly *pCaller, MethodDesc *pCallee)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityDeclarative::LinktimeCheckMethod(pCaller, pCallee);
-#endif
}
inline void Security::ClassInheritanceCheck(MethodTable *pClass, MethodTable *pParent)
@@ -201,18 +146,12 @@ inline void Security::MethodInheritanceCheck(MethodDesc *pMethod, MethodDesc *pP
inline void Security::DoDeclarativeActions(MethodDesc *pMD, DeclActionInfo *pActions, LPVOID pSecObj, MethodSecurityDescriptor *pMSD)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityDeclarative::DoDeclarativeActions(pMD, pActions, pSecObj, pMSD);
-#endif
}
#ifndef DACCESS_COMPILE
inline void Security::CheckNonCasDemand(OBJECTREF *prefDemand)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityDeclarative::CheckNonCasDemand(prefDemand);
-#endif
}
#endif // #ifndef DACCESS_COMPILE
@@ -236,18 +175,8 @@ inline BOOL Security::MethodIsVisibleOutsideItsAssembly(DWORD dwMethodAttr, DWOR
inline void Security::Demand(SecurityStackWalkType eType, OBJECTREF demand)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityStackWalk::Demand(eType, demand);
-#endif
}
-#ifdef FEATURE_CAS_POLICY
-inline void Security::DemandGrantSet(IAssemblySecurityDescriptor *psdAssembly)
-{
- WRAPPER_NO_CONTRACT;
- SecurityStackWalk::DemandGrantSet(static_cast<AssemblySecurityDescriptor*>(psdAssembly));
-}
-#endif // FEATURE_CAS_POLICY
inline void Security::DemandSet(SecurityStackWalkType eType, OBJECTREF demand)
{
@@ -258,82 +187,34 @@ inline void Security::DemandSet(SecurityStackWalkType eType, OBJECTREF demand)
MODE_COOPERATIVE;
}
CONTRACTL_END;
-#ifdef FEATURE_CAS_POLICY
- SecurityStackWalk::DemandSet(eType, demand);
-#endif
}
inline void Security::DemandSet(SecurityStackWalkType eType, PsetCacheEntry *pPCE, DWORD dwAction)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityStackWalk::DemandSet(eType, pPCE, dwAction);
-#endif
}
-#ifdef FEATURE_CAS_POLICY
-inline void Security::ReflectionTargetDemand(DWORD dwPermission, IAssemblySecurityDescriptor *psdTarget)
-{
- WRAPPER_NO_CONTRACT;
- SecurityStackWalk::ReflectionTargetDemand(dwPermission, static_cast<AssemblySecurityDescriptor*>(psdTarget));
-}
-
-inline void Security::ReflectionTargetDemand(DWORD dwPermission,
- IAssemblySecurityDescriptor *psdTarget,
- DynamicResolver * pAccessContext)
-{
- WRAPPER_NO_CONTRACT;
- SecurityStackWalk::ReflectionTargetDemand(dwPermission, static_cast<AssemblySecurityDescriptor*>(psdTarget), pAccessContext);
-}
-#endif // FEATURE_CAS_POLICY
inline void Security::SpecialDemand(SecurityStackWalkType eType, DWORD whatPermission)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityStackWalk::SpecialDemand(eType, whatPermission);
-#endif
}
inline void Security::InheritanceLinkDemandCheck(Assembly *pTargetAssembly, MethodDesc * pMDLinkDemand)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityDeclarative::InheritanceLinkDemandCheck(pTargetAssembly, pMDLinkDemand);
-#endif
}
inline void Security::FullTrustInheritanceDemand(Assembly *pTargetAssembly)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityDeclarative::FullTrustInheritanceDemand(pTargetAssembly);
-#endif
}
inline void Security::FullTrustLinkDemand(Assembly *pTargetAssembly)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_CAS_POLICY
- SecurityDeclarative::FullTrustLinkDemand(pTargetAssembly);
-#endif
-}
-
-#ifdef FEATURE_COMPRESSEDSTACK
-// Compressed Stack
-
-inline COMPRESSEDSTACKREF Security::GetCSFromContextTransitionFrame(Frame *pFrame)
-{
- WRAPPER_NO_CONTRACT;
- return SecurityStackWalk::GetCSFromContextTransitionFrame(pFrame);
}
-inline BOOL Security::IsContextTransitionFrameWithCS(Frame *pFrame)
-{
- WRAPPER_NO_CONTRACT;
- return SecurityStackWalk::IsContextTransitionFrameWithCS(pFrame);
-}
-#endif // #ifdef FEATURE_COMPRESSEDSTACK
// Misc - todo: put these in better categories
FORCEINLINE VOID Security::IncrementSecurityPerfCounter()
@@ -538,43 +419,8 @@ inline BOOL Security::CanSkipVerification(MethodDesc * pMD)
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
// Always skip verification on CoreCLR
return TRUE;
-#else
-
- // Special case the System.Object..ctor:
- // System.Object..ctor is not verifiable according to current verifier rules (that require to call the base
- // class ctor). But since we want System.Object..ctor() to be marked transparent, it cannot be unverifiable
- // (v4 security rules prohibit transparent code from being unverifiable)
-
-#ifndef DACCESS_COMPILE
- if (g_pObjectCtorMD == pMD)
- return TRUE;
-#endif
-
- // In AppX, all dynamic code (dynamic assemblies and dynamic methods) should be verified..
- if (AppX::IsAppXProcess() && !AppX::IsAppXDesignMode())
- {
- if (pMD->IsLCGMethod() || pMD->GetAssembly()->IsDynamic())
- return FALSE;
- }
-
- BOOL fCanSkipVerification = Security::CanSkipVerification(pMD->GetAssembly()->GetDomainAssembly());
- if (fCanSkipVerification)
- {
- // check for transparency
- if (SecurityTransparent::IsMethodTransparent(pMD))
- {
- ModuleSecurityDescriptor *pModuleSecDesc = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pMD->GetAssembly());
- if (!pModuleSecDesc->CanTransparentCodeSkipVerification())
- {
- return FALSE;
- }
- }
- }
- return fCanSkipVerification;
-#endif // !FEATURE_CORECLR
}
#endif //!DACCESS_COMPILE
@@ -603,38 +449,6 @@ inline BOOL Security::ContainsBuiltinCASPermsOnly(CORSEC_ATTRSET* pAttrSet)
return SecurityAttributes::ContainsBuiltinCASPermsOnly(pAttrSet);
}
-#ifdef FEATURE_APTCA
-inline BOOL Security::IsUntrustedCallerCheckNeeded(MethodDesc *pCalleeMD, Assembly *pCallerAssem)
-{
- WRAPPER_NO_CONTRACT;
- return SecurityDeclarative::IsUntrustedCallerCheckNeeded(pCalleeMD, pCallerAssem);
-}
-
-inline void Security::DoUntrustedCallerChecks(Assembly *pCaller, MethodDesc *pCalee, BOOL fFullStackWalk)
-{
- WRAPPER_NO_CONTRACT;
- SecurityDeclarative::DoUntrustedCallerChecks(pCaller, pCalee, fFullStackWalk);
-}
-
-inline bool Security::NativeImageHasValidAptcaDependencies(PEImage *pNativeImage, DomainAssembly *pDomainAssembly)
-{
- WRAPPER_NO_CONTRACT;
- return ::NativeImageHasValidAptcaDependencies(pNativeImage, pDomainAssembly);
-}
-
-inline SString Security::GetAptcaKillBitAccessExceptionContext(Assembly *pTargetAssembly)
-{
- WRAPPER_NO_CONTRACT;
- return ::GetAptcaKillBitAccessExceptionContext(pTargetAssembly);
-}
-
-inline SString Security::GetConditionalAptcaAccessExceptionContext(Assembly *pTargetAssembly)
-{
- WRAPPER_NO_CONTRACT;
- return ::GetConditionalAptcaAccessExceptionContext(pTargetAssembly);
-}
-
-#endif // FEATURE_APTCA
inline bool Security::SecurityCalloutQuickCheck(MethodDesc *pCallerMD)
{
@@ -646,12 +460,6 @@ inline bool Security::CanShareAssembly(DomainAssembly *pAssembly)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_APTCA
- if (!DomainCanShareAptcaAssembly(pAssembly))
- {
- return false;
- }
-#endif // FEATURE_APTCA
return true;
}
@@ -674,34 +482,7 @@ FORCEINLINE BOOL SecurityStackWalk::HasFlagsOrFullyTrustedIgnoreMode (DWORD flag
}
CONTRACTL_END;
-#ifndef FEATURE_CAS_POLICY
return TRUE;
-#else
- // either the desired flag (often 0) or fully trusted will do
- flags |= (1<<SECURITY_FULL_TRUST);
-
- // in order for us to use the threadwide state it has to be the case that there have been no
- // overrides since the evaluation (e.g. no denies) We keep the state up-to-date by updating
- // it whenever a new AppDomainStackEntry is pushed on the AppDomainStack attached to the thread.
- // When we evaluate the demand, we always intersect the current thread state with the AppDomain
- // wide flags, which are updated anytime a new Assembly is loaded into that domain.
- //
- // note if the flag is clear we still might be able to satisfy the demand if we do the full
- // stackwalk.
- //
- // this code is very perf sensitive, do not make changes here without running
- // a lot of interop and declarative security benchmarks
- //
- // it's important that we be able to do these checks without having to touch objects
- // other than the thread itself -- that's where a big part of the speed comes from
- // L1 cache misses are at a premium on this code path -- never mind L2...
- // main memory is right out :)
-
- Thread* pThread = GetThread();
- return ((pThread->GetOverridesCount() == 0) &&
- pThread->CheckThreadWideSpecialFlag(flags) &&
- static_cast<ApplicationSecurityDescriptor*>(pThread->GetDomain()->GetSecurityDescriptor())->CheckDomainWideSpecialFlag(flags));
-#endif
}
// Returns true if everyone is fully trusted or has the indicated flags AND we're not in legacy CAS mode
diff --git a/src/vm/securityattributes.cpp b/src/vm/securityattributes.cpp
index 1f8e3e1d4d..798d8099a5 100644
--- a/src/vm/securityattributes.cpp
+++ b/src/vm/securityattributes.cpp
@@ -786,110 +786,12 @@ HRESULT GetFullyQualifiedTypeName(SString* pString, mdAssemblyRef tkAssemblyRef,
(*pString) += W(", ");
DWORD dwDisplayFlags = ASM_DISPLAYF_VERSION | ASM_DISPLAYF_PUBLIC_KEY_TOKEN | ASM_DISPLAYF_CULTURE;
-#ifdef FEATURE_FUSION // why is Security accessing Fusion interfaces bypassing Loader?
- // Retrieve size of assembly name
- ASSEMBLYMETADATA sContext;
- ZeroMemory(&sContext, sizeof(ASSEMBLYMETADATA));
- HRESULT hr = S_OK;
- LPWSTR wszAssemblyName = NULL;
- BYTE *pbPublicKeyOrToken = NULL;
- DWORD cbPublicKeyOrToken = 0;
- DWORD dwFlags = 0;
- if(TypeFromToken(tkAssemblyRef) == mdtAssembly)
- {
- DWORD cchName;
- hr = pImport->GetAssemblyProps(tkAssemblyRef, // [IN] The Assembly for which to get the properties.
- NULL, // [OUT] Pointer to the public key or token.
- NULL, // [OUT] Count of bytes in the public key or token.
- NULL, // [OUT] Hash Algorithm
- NULL, // [OUT] Buffer to fill with name.
- NULL, // [IN] Size of buffer in wide chars.
- &cchName, // [OUT] Actual # of wide chars in name.
- &sContext, // [OUT] Assembly MetaData.
- NULL); // [OUT] Flags.
- if(FAILED(hr))
- return hr;
-
- // Get the assembly name other naming properties
- wszAssemblyName = (LPWSTR)_alloca(cchName * sizeof(WCHAR));
- hr = pImport->GetAssemblyProps(tkAssemblyRef,
- (const void **)&pbPublicKeyOrToken,
- &cbPublicKeyOrToken,
- NULL,
- wszAssemblyName,
- cchName,
- &cchName,
- &sContext,
- &dwFlags);
- if(FAILED(hr))
- return hr;
- }
- else if(TypeFromToken(tkAssemblyRef) == mdtAssemblyRef)
- {
- DWORD cchName;
- hr = pImport->GetAssemblyRefProps(tkAssemblyRef, // [IN] The AssemblyRef for which to get the properties.
- NULL, // [OUT] Pointer to the public key or token.
- NULL, // [OUT] Count of bytes in the public key or token.
- NULL, // [OUT] Buffer to fill with name.
- NULL, // [IN] Size of buffer in wide chars.
- &cchName, // [OUT] Actual # of wide chars in name.
- &sContext, // [OUT] Assembly MetaData.
- NULL, // [OUT] Hash blob.
- NULL, // [OUT] Count of bytes in the hash blob.
- NULL); // [OUT] Flags.
- if(FAILED(hr))
- return hr;
-
- // Get the assembly name other naming properties
- wszAssemblyName = (LPWSTR)_alloca(cchName * sizeof(WCHAR));
- hr = pImport->GetAssemblyRefProps(tkAssemblyRef,
- (const void **)&pbPublicKeyOrToken,
- &cbPublicKeyOrToken,
- wszAssemblyName,
- cchName,
- &cchName,
- &sContext,
- NULL,
- NULL,
- &dwFlags);
- if(FAILED(hr))
- return hr;
- }
- else
- {
- _ASSERTE(false && "unexpected token");
- }
-
- // Convert to an AssemblyNameObject
- ReleaseHolder<IAssemblyName> pAssemblyNameObj;
- hr = CreateAssemblyNameObject(&pAssemblyNameObj, wszAssemblyName, CANOF_PARSE_DISPLAY_NAME, NULL);
- if(FAILED(hr))
- return hr;
- _ASSERTE(pAssemblyNameObj && "assembly name object shouldn't be NULL");
- pAssemblyNameObj->SetProperty(ASM_NAME_MAJOR_VERSION, &sContext.usMajorVersion, sizeof(WORD));
- pAssemblyNameObj->SetProperty(ASM_NAME_MINOR_VERSION, &sContext.usMinorVersion, sizeof(WORD));
- pAssemblyNameObj->SetProperty(ASM_NAME_BUILD_NUMBER, &sContext.usBuildNumber, sizeof(WORD));
- pAssemblyNameObj->SetProperty(ASM_NAME_REVISION_NUMBER, &sContext.usRevisionNumber, sizeof(WORD));
- pAssemblyNameObj->SetProperty(ASM_NAME_CULTURE, W(""), sizeof(WCHAR));
- if(pbPublicKeyOrToken && cbPublicKeyOrToken > 0)
- {
- if(dwFlags & afPublicKey)
- pAssemblyNameObj->SetProperty(ASM_NAME_PUBLIC_KEY, pbPublicKeyOrToken, cbPublicKeyOrToken);
- else
- pAssemblyNameObj->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, pbPublicKeyOrToken, cbPublicKeyOrToken);
- }
-
- // Convert assembly name to an ole string
- StackSString name;
- FusionBind::GetAssemblyNameDisplayName(pAssemblyNameObj, name, dwDisplayFlags);
-#else // FEATURE_FUSION
HRESULT hr;
AssemblySpec spec;
StackSString name;
IfFailRet(spec.Init((mdToken)tkAssemblyRef,pImport));
spec.GetFileOrDisplayName(dwDisplayFlags,name);
-#endif // FEATURE_FUSION
_ASSERTE(!name.IsEmpty() && "the assembly name should not be empty here");
(*pString) += name;
diff --git a/src/vm/securityattributes.h b/src/vm/securityattributes.h
index 5bcff51ec9..8408309b0a 100644
--- a/src/vm/securityattributes.h
+++ b/src/vm/securityattributes.h
@@ -38,22 +38,12 @@ namespace SecurityAttributes
// Creates a new permission set
OBJECTREF CreatePermissionSet(BOOL fTrusted);
-#ifdef FEATURE_CAS_POLICY
- // Takes two PermissionSets (referenced by index) and merges them (unions or intersects
- // depending on fIntersect) and returns the index of the merged PermissionSet
- PsetCacheEntry* MergePermissionSets(IN PsetCacheEntry *pPCE1, IN PsetCacheEntry *pPCE2, IN bool fIntersect, IN DWORD dwAction);
-#endif // FEATURE_CAS_POLICY
// Uses new to create the byte array that is returned.
void CopyByteArrayToEncoding(IN U1ARRAYREF* pArray,
OUT PBYTE* pbData,
OUT DWORD* cbData);
-#ifdef FEATURE_CAS_POLICY
- void EncodePermissionSet(IN OBJECTREF* pRef,
- OUT PBYTE* ppbData,
- OUT DWORD* pcbData);
-#endif // FEATURE_CAS_POLICY
// Generic routine, use with encoding calls that
// use the EncodePermission client data
@@ -125,16 +115,6 @@ namespace SecurityAttributes
void AttrArrayToPermissionSet(OBJECTREF* attrArray, bool fSerialize, DWORD attrCount, BYTE **ppbOutput, DWORD *pcbOutput, BYTE **ppbNonCasOutput, DWORD *pcbNonCasOutput, bool fAllowEmptyPermissionSet, OBJECTREF* pPermSet);
void AttrSetBlobToPermissionSets(IN BYTE* pbRawPermissions, IN DWORD cbRawPermissions, OUT OBJECTREF* pObj, IN DWORD dwAction);
-#ifdef FEATURE_CAS_POLICY
- void XmlToPermissionSet(PBYTE pbXmlBlob,
- DWORD cbXmlBlob,
- OBJECTREF* pPermSet,
- OBJECTREF* pEncoding,
- PBYTE pbNonCasXmlBlob,
- DWORD cbNonCasXmlBlob,
- OBJECTREF* pNonCasPermSet,
- OBJECTREF* pNonCasEncoding);
-#endif // FEATURE_CAS_POLICY
bool ActionAllowsNullPermissionSet(CorDeclSecurity action);
diff --git a/src/vm/securityconfig.cpp b/src/vm/securityconfig.cpp
deleted file mode 100644
index 9c7970db8c..0000000000
--- a/src/vm/securityconfig.cpp
+++ /dev/null
@@ -1,2181 +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.
-//
-// File: SecurityConfig.cpp
-//
-
-//
-// Native implementation for security config access and manipulation
-//
-
-
-// #SecurityConfigFormat
-//
-// The security config system resides outside of the rest
-// of the config system since our needs are different. The
-// unmanaged portion of the security config system is only
-// concerned with data file/cache file pairs, not what they
-// are used for. It performs all the duties of reading data
-// from the disk, saving data back to the disk, and maintaining
-// the policy and quick cache data structures.
-//
-// FILE FORMAT
-//
-// The data file is a purely opaque blob for the unmanaged
-// code; however, the cache file is constructed and maintained
-// completely in the unmanaged code. It's format is as follows:
-//
-// CacheHeader
-// |
-// +-- dummyFileTime (FILETIME, 8 bytes) = this exists to make sure we don't read old format cache files. Must be set to {1, 0}.
-// |
-// +-- version (DWORD) = The version of this config file.
-// |
-// +-- configFileTime (FILETIME, 8 bytes) = The file time of the config file associated with this cache file.
-// |
-// +-- isSecurityOn (DWORD, 4 bytes) = This is currently not used.
-// |
-// +-- quickCache (DWORD, 4 bytes) = Used as a bitfield to maintain the information for the QuickCache. See the QuickCache section for more details.
-// |
-// +-- registryExtensionsInfo (struct RegistryExtensionsInfo) = Indicates whether this cache file was generated in the presence of registry extensions.
-// |
-// +-- numEntries (DWORD, 4 bytes) = The number of policy cache entries in the latter portion of this cache file.
-// |
-// +-- sizeConfig (DWORD, 4 bytes) = The size of the config information stored in the latter portion of this cache file.
-//
-// Config Data (if any)
-// The cache file can include an entire copy of this
-// information in the adjoining config file. This is
-// necessary since the cache often allows us to make
-// policy decisions without having parsed the data in
-// the config file. In order to guarantee that the config
-// data used by this process is not altered in the
-// meantime, we need to store the data in a readonly
-// location. Due to the design of the caching system
-// the cache file is locked when it is opened and therefore
-// is the perfect place to store this information. The
-// other alternative is to hold it in memory, but since
-// this can amount to many kilobytes of data we decided
-// on this design.
-//
-// List of CacheEntries
-// |
-// +-- CacheEntry
-// | |
-// | +-- numItemsInKey (DWORD, 4 bytes) = The number of evidence objects serialized in the key blob
-// | |
-// | +-- keySize (DWORD, 4 bytes) = The number of bytes in the key blob.
-// | |
-// | +-- dataSize (DWORD, 4 bytes) = The number of bytes in the data blob.
-// | |
-// | +-- keyBlob (raw) = A raw blob representing the serialized evidence.
-// | |
-// | +-- dataBlob (raw) = A raw blob representing an XML serialized PolicyStatement
-// |
-// +-- ...
-
-#include "common.h"
-
-#ifdef FEATURE_CAS_POLICY
-
-#include "securityconfig.h"
-
-// Header version of the cache file.
-#define CONFIG_VERSION 2
-// This controls the maximum size of the cache file.
-#define MAX_CACHEFILE_SIZE (1 << 20)
-
-#define SIZE_OF_ENTRY( X ) sizeof( CacheEntryHeader ) + X->header.keySize + X->header.dataSize
-#define MAX_NUM_LENGTH 16
-
-WCHAR* SecurityConfig::wcscatDWORD( __out_ecount(cchdst) __out_z WCHAR* dst, size_t cchdst, DWORD num )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END
-
- _ASSERTE( SecurityConfig::dataLock_.OwnedByCurrentThread() );
-
- static WCHAR buffer[MAX_NUM_LENGTH];
-
- buffer[MAX_NUM_LENGTH-1] = W('\0');
-
- size_t index = MAX_NUM_LENGTH-2;
-
- if (num == 0)
- {
- buffer[index--] = W('0');
- }
- else
- {
- while (num != 0)
- {
- buffer[index--] = (WCHAR)(W('0') + (num % 10));
- num = num / 10;
- }
- }
-
- wcscat_s( dst, cchdst, buffer + index + 1 );
-
- return dst;
-}
-
-inline WCHAR * Wszdup(const WCHAR * str)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- size_t len = wcslen(str) + 1;
- WCHAR * ret = new WCHAR[len];
- wcscpy_s(ret, len, str);
- return ret;
-}
-
-struct CacheHeader
-{
- FILETIME dummyFileTime;
- DWORD version;
- FILETIME configFileTime;
- DWORD isSecurityOn, quickCache;
- SecurityConfig::RegistryExtensionsInfo registryExtensionsInfo;
- DWORD numEntries, sizeConfig;
-
- CacheHeader() : isSecurityOn( (DWORD) -1 ), quickCache( 0 ), numEntries( 0 ), sizeConfig( 0 )
- {
- WRAPPER_NO_CONTRACT;
- memset( &this->configFileTime, 0, sizeof( configFileTime ) );
- dummyFileTime.dwLowDateTime = 1;
- dummyFileTime.dwHighDateTime = 0;
- version = CONFIG_VERSION;
- memset(&registryExtensionsInfo, 0, sizeof(registryExtensionsInfo));
- _ASSERTE( IsValid() && "CacheHeader constructor should make it valid" );
- };
-
- bool IsValid()
- {
- LIMITED_METHOD_CONTRACT;
- return dummyFileTime.dwLowDateTime == 1 &&
- dummyFileTime.dwHighDateTime == 0 &&
- version == CONFIG_VERSION;
- }
-};
-
-struct CacheEntryHeader
-{
- DWORD numItemsInKey;
- DWORD keySize;
- DWORD dataSize;
-};
-
-struct CacheEntry
-{
- CacheEntryHeader header;
- BYTE* key;
- BYTE* data;
- DWORD cachePosition;
- BOOL used;
-
- CacheEntry() : key( NULL ), data( NULL ), used( FALSE )
- {
- LIMITED_METHOD_CONTRACT;
- };
-
- ~CacheEntry( void )
- {
- WRAPPER_NO_CONTRACT;
- delete [] key;
- delete [] data;
- }
-};
-
-struct Data
-{
- enum State
- {
- None = 0x0,
- UsingCacheFile = 0x1,
- CopyCacheFile = 0x2,
- CacheUpdated = 0x4,
- UsingConfigFile = 0x10,
- CacheExhausted = 0x20,
- NewConfigFile = 0x40
- };
-
- INT32 id;
- WCHAR* configFileName;
- WCHAR* cacheFileName;
- WCHAR* cacheFileNameTemp;
-
- LPBYTE configData;
- DWORD configDataSize;
- FILETIME configFileTime;
- FILETIME cacheFileTime;
- CacheHeader header;
- ArrayList* oldCacheEntries;
- ArrayList* newCacheEntries;
- State state;
- DWORD cacheCurrentPosition;
- HANDLE cache;
- PBYTE configBuffer;
- DWORD sizeConfig;
- SecurityConfig::ConfigRetval initRetval;
- DWORD newEntriesSize;
-
- Data( INT32 id )
- : id( id ),
- configFileName( NULL ),
- cacheFileName( NULL ),
- configData( NULL ),
- oldCacheEntries( new ArrayList ),
- newCacheEntries( new ArrayList ),
- state( Data::None ),
- cache( INVALID_HANDLE_VALUE ),
- configBuffer( NULL ),
- newEntriesSize( 0 )
- {
- LIMITED_METHOD_CONTRACT;
- }
-
- Data( INT32 id, STRINGREF* configFile )
- : id( id ),
- cacheFileName( NULL ),
- configData( NULL ),
- oldCacheEntries( new ArrayList ),
- newCacheEntries( new ArrayList ),
- state( Data::None ),
- cache( INVALID_HANDLE_VALUE ),
- configBuffer( NULL ),
- newEntriesSize( 0 )
- {
- CONTRACTL {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(*configFile != NULL);
- } CONTRACTL_END;
-
- configFileName = Wszdup( (*configFile)->GetBuffer() );
- cacheFileName = NULL;
- cacheFileNameTemp = NULL;
- }
-
- Data( INT32 id, STRINGREF* configFile, STRINGREF* cacheFile )
- : id( id ),
- configData( NULL ),
- oldCacheEntries( new ArrayList ),
- newCacheEntries( new ArrayList ),
- state( Data::None ),
- cache( INVALID_HANDLE_VALUE ),
- configBuffer( NULL ),
- newEntriesSize( 0 )
- {
- CONTRACTL {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(*configFile != NULL);
- } CONTRACTL_END;
-
- configFileName = Wszdup( (*configFile)->GetBuffer() );
-
- if (cacheFile != NULL)
- {
- // Since temp cache files can stick around even after the process that
- // created them, we want to make sure they are fairly unique (if they
- // aren't, we'll just fail to save cache information, which is not good
- // but it won't cause anyone to crash or anything). The unique name
- // algorithm used here is to append the process id and tick count to
- // the name of the cache file.
-
- cacheFileName = Wszdup( (*cacheFile)->GetBuffer() );
- size_t len = wcslen( cacheFileName ) + 1 + 2 * MAX_NUM_LENGTH;
- cacheFileNameTemp = new WCHAR[len];
- wcscpy_s( cacheFileNameTemp, len, cacheFileName );
- wcscat_s( cacheFileNameTemp, len, W(".") );
- SecurityConfig::wcscatDWORD( cacheFileNameTemp, len, GetCurrentProcessId() );
- wcscat_s( cacheFileNameTemp, len, W(".") );
- SecurityConfig::wcscatDWORD( cacheFileNameTemp, len, GetTickCount() );
- }
- else
- {
- cacheFileName = NULL;
- cacheFileNameTemp = NULL;
- }
- }
-
- Data( INT32 id, const WCHAR* configFile, const WCHAR* cacheFile )
- : id( id ),
- configData( NULL ),
- oldCacheEntries( new ArrayList ),
- newCacheEntries( new ArrayList ),
- state( Data::None ),
- cache( INVALID_HANDLE_VALUE ),
- configBuffer( NULL ),
- newEntriesSize( 0 )
-
- {
- CONTRACTL {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(*configFile != NULL);
- } CONTRACTL_END;
-
- configFileName = Wszdup( configFile );
-
- if (cacheFile != NULL)
- {
- cacheFileName = Wszdup( cacheFile );
- size_t len = wcslen( cacheFileName ) + 1 + 2 * MAX_NUM_LENGTH;
- cacheFileNameTemp = new WCHAR[len];
- wcscpy_s( cacheFileNameTemp, len, cacheFileName );
- wcscat_s( cacheFileNameTemp, len, W(".") );
- SecurityConfig::wcscatDWORD( cacheFileNameTemp, len, GetCurrentProcessId() );
- wcscat_s( cacheFileNameTemp, len, W(".") );
- SecurityConfig::wcscatDWORD( cacheFileNameTemp, len, GetTickCount() );
- }
- else
- {
- cacheFileName = NULL;
- cacheFileNameTemp = NULL;
- }
- }
-
- void Reset( void )
- {
- CONTRACTL {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- delete [] configBuffer;
- configBuffer = NULL;
-
- if (cache != INVALID_HANDLE_VALUE)
- {
- CloseHandle( cache );
- cache = INVALID_HANDLE_VALUE;
- }
-
- if (cacheFileNameTemp != NULL)
- {
- // Note: we don't check a return value here as the worst thing that
- // happens is we leave a spurious cache file.
-
- WszDeleteFile( cacheFileNameTemp );
- }
-
- if (configData != NULL)
- delete [] configData;
- configData = NULL;
-
- DeleteAllEntries();
- header = CacheHeader();
-
- oldCacheEntries = new ArrayList();
- newCacheEntries = new ArrayList();
-
- }
-
- void Cleanup( void )
- {
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- if (cache != INVALID_HANDLE_VALUE)
- {
- CloseHandle( cache );
- cache = INVALID_HANDLE_VALUE;
- }
-
- if (cacheFileNameTemp != NULL)
- {
- // Note: we don't check a return value here as the worst thing that
- // happens is we leave a spurious cache file.
-
- WszDeleteFile( cacheFileNameTemp );
- }
- }
-
- ~Data( void )
- {
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- Cleanup();
- delete [] configBuffer;
-
- delete [] configFileName;
- delete [] cacheFileName;
- delete [] cacheFileNameTemp;
-
- if (configData != NULL)
- delete [] configData;
- DeleteAllEntries();
- }
-
- void DeleteAllEntries( void );
-};
-
-void Data::DeleteAllEntries( void )
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- } CONTRACTL_END;
-
- ArrayList::Iterator iter;
-
- if (oldCacheEntries != NULL)
- {
- iter = oldCacheEntries->Iterate();
-
- while (iter.Next())
- {
- delete (CacheEntry*) iter.GetElement();
- }
-
- delete oldCacheEntries;
- oldCacheEntries = NULL;
- }
-
- if (newCacheEntries != NULL)
- {
- iter = newCacheEntries->Iterate();
-
- while (iter.Next())
- {
- delete (CacheEntry*) iter.GetElement();
- }
-
- delete newCacheEntries;
- newCacheEntries = NULL;
- }
-}
-
-void* SecurityConfig::GetData( INT32 id )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END
-
- ArrayList::Iterator iter = entries_.Iterate();
-
- while (iter.Next())
- {
- Data* data = (Data*)iter.GetElement();
-
- if (data->id == id)
- {
- return data;
- }
- }
-
- return NULL;
-}
-
-static BOOL CacheOutOfDate( FILETIME* configFileTime, __in_z WCHAR* configFileName, __in_z_opt WCHAR* cacheFileName )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_PREEMPTIVE;
- }
- CONTRACTL_END
-
- BOOL retval = TRUE;
- BOOL deleteFile = FALSE;
-
- HandleHolder config(WszCreateFile( configFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ));
-
- if (config.GetValue() == INVALID_HANDLE_VALUE)
- {
- goto CLEANUP;
- }
-
- // Get the last write time for both files.
-
- FILETIME newConfigTime;
-
- if (!GetFileTime( config.GetValue(), NULL, NULL, &newConfigTime ))
- {
- goto CLEANUP;
- }
-
- if (CompareFileTime( configFileTime, &newConfigTime ) != 0)
- {
- // Cache is dated. Delete the cache.
- deleteFile = TRUE;
- goto CLEANUP;
- }
-
- retval = FALSE;
-
-CLEANUP:
- // Note: deleting this file is a perf optimization so that
- // we don't have to do this file time comparison next time.
- // Therefore, if it fails for some reason we just loss a
- // little perf.
-
- if (deleteFile && cacheFileName != NULL)
- WszDeleteFile( cacheFileName );
-
- return retval;
-}
-
-static BOOL CacheOutOfDate( FILETIME* cacheFileTime, HANDLE cache, __in_z_opt WCHAR* cacheFileName )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_PREEMPTIVE;
- }
- CONTRACTL_END
-
- BOOL retval = TRUE;
-
- // Get the last write time for both files.
-
- FILETIME newCacheTime;
-
- if (!GetFileTime( cache, NULL, NULL, &newCacheTime ))
- {
- goto CLEANUP;
- }
-
- if (CompareFileTime( cacheFileTime, &newCacheTime ) != 0)
- {
- // Cache is dated. Delete the cache.
- // Note: deleting this file is a perf optimization so that
- // we don't have to do this file time comparison next time.
- // Therefore, if it fails for some reason we just loss a
- // little perf.
-
- if (cacheFileName != NULL)
- {
- CloseHandle( cache );
- WszDeleteFile( cacheFileName );
- }
- goto CLEANUP;
- }
-
- retval = FALSE;
-
-CLEANUP:
- return retval;
-}
-
-static BOOL CacheOutOfDate( FILETIME* configTime, FILETIME* cachedConfigTime )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_PREEMPTIVE;
- }
- CONTRACTL_END
-
- DWORD result = CompareFileTime( configTime, cachedConfigTime );
-
- return result != 0;
-}
-
-static DWORD GetShareFlags()
-{
- LIMITED_METHOD_CONTRACT;
-
- return FILE_SHARE_READ | FILE_SHARE_DELETE;
-}
-
-static DWORD WriteFileData( HANDLE file, LPCBYTE data, DWORD size )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END
-
- DWORD totalBytesWritten = 0;
- DWORD bytesWritten;
-
- do
- {
- if (WriteFile( file, data, size - totalBytesWritten, &bytesWritten, NULL ) == 0)
- {
- return E_FAIL;
- }
- if (bytesWritten == 0)
- {
- return E_FAIL;
- }
- totalBytesWritten += bytesWritten;
- } while (totalBytesWritten < size);
-
- return S_OK;
-}
-
-// the data argument to this function can be a pointer to GC heap.
-// We do ensure cooperative mode before we call this function using a pointer to GC heap,
-// so we can't change GC mode inside this function.
-// Greg will look into the ways to pin the object.
-
-static DWORD ReadFileData( HANDLE file, PBYTE data, DWORD size )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END
-
- DWORD totalBytesRead = 0;
- DWORD bytesRead;
- do
- {
- if (ReadFile( file, data, size - totalBytesRead, &bytesRead, NULL ) == 0)
- {
- return E_FAIL;
- }
-
- if (bytesRead == 0)
- {
- return E_FAIL;
- }
-
- totalBytesRead += bytesRead;
-
- } while (totalBytesRead < size);
-
- return S_OK;
-}
-
-SecurityConfig::ConfigRetval SecurityConfig::InitData( INT32 id, const WCHAR* configFileName, const WCHAR* cacheFileName )
-{
- STANDARD_VM_CONTRACT;
-
- Data* data = (Data*)GetData( id );
- if (data != NULL)
- {
- return data->initRetval;
- }
-
- if (configFileName == NULL || wcslen( configFileName ) == 0)
- {
- return NoFile;
- }
-
- {
- CrstHolder ch( &dataLock_ );
- data = new (nothrow) Data( id, configFileName, cacheFileName );
- }
-
- if (data == NULL)
- {
- return NoFile;
- }
-
- return InitData( data, TRUE );
-}
-
-
-SecurityConfig::ConfigRetval SecurityConfig::InitData( void* configDataParam, BOOL addToList )
-{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE( configDataParam != NULL );
-
- Data* data = (Data*) configDataParam;
- DWORD cacheSize;
- DWORD configSize;
- ConfigRetval retval = NoFile;
- DWORD shareFlags;
-
- shareFlags = GetShareFlags();
-
- // Crack open the config file.
-
- HandleHolder config(WszCreateFile( data->configFileName, GENERIC_READ, shareFlags, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ));
- if (config == INVALID_HANDLE_VALUE || !GetFileTime( config, NULL, NULL, &data->configFileTime ))
- {
- memset( &data->configFileTime, 0, sizeof( data->configFileTime ) );
- }
- else
- {
- data->state = (Data::State)(Data::UsingConfigFile | data->state);
- }
-
- // If we want a cache file, try to open that up.
- // Note: we do not use a holder for data->cache because the new holder for data will
- // delete the entire data structure which includes closing this handle as necessary.
-
- if (data->cacheFileName != NULL)
- data->cache = WszCreateFile( data->cacheFileName, GENERIC_READ, shareFlags, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
-
- if (data->cache == INVALID_HANDLE_VALUE)
- {
- goto READ_DATA;
- }
-
- // Validate that the cache file is in a good form by checking
- // that it is at least big enough to contain a header.
-
- cacheSize = SafeGetFileSize( data->cache, NULL );
-
- if (cacheSize == 0xFFFFFFFF)
- {
- goto READ_DATA;
- }
-
- if (cacheSize < sizeof( CacheHeader ))
- {
- goto READ_DATA;
- }
-
- // Finally read the data from the file into the buffer.
-
- if (ReadFileData( data->cache, (BYTE*)&data->header, sizeof( CacheHeader ) ) != S_OK)
- {
- goto READ_DATA;
- }
-
- if (!data->header.IsValid())
- {
- goto READ_DATA;
- }
-
- // Check to make sure the cache file and the config file
- // match up by comparing the actual file time of the config
- // file and the config file time stored in the cache file.
-
- if (CacheOutOfDate( &data->configFileTime, &data->header.configFileTime ))
- {
- goto READ_DATA;
- }
-
- if (!GetFileTime( data->cache, NULL, NULL, &data->cacheFileTime ))
- {
- goto READ_DATA;
- }
-
- // Set the file pointer to after both the header and config data (if any) so
- // that we are ready to read cache entries.
-
- if (SetFilePointer( data->cache, sizeof( CacheHeader ) + data->header.sizeConfig, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- {
- goto READ_DATA;
- }
-
- data->cacheCurrentPosition = sizeof( CacheHeader ) + data->header.sizeConfig;
- data->state = (Data::State)(Data::UsingCacheFile | Data::CopyCacheFile | data->state);
-
- retval = (ConfigRetval)(retval | CacheFile);
-
-READ_DATA:
- // If we are not using the cache file but we successfully opened it, we need
- // to close it now. In addition, we need to reset the cache information
- // stored in the Data object to make sure there is no spill over.
-
- if (data->cache != INVALID_HANDLE_VALUE && (data->state & Data::UsingCacheFile) == 0)
- {
- CloseHandle( data->cache );
- data->header = CacheHeader();
- data->cache = INVALID_HANDLE_VALUE;
- }
-
- if (config != INVALID_HANDLE_VALUE)
- {
- configSize = SafeGetFileSize( config, NULL );
-
- if (configSize == 0xFFFFFFFF)
- {
- goto ADD_DATA;
- }
-
- // Be paranoid and only use the cache file version if we find that it has the correct sized
- // blob in it.
-
- if ((data->state & Data::UsingCacheFile) != 0 && configSize == data->header.sizeConfig)
- {
- goto ADD_DATA;
- }
- else
- {
- if (data->cache != INVALID_HANDLE_VALUE)
- {
- CloseHandle( data->cache );
- data->header = CacheHeader();
- data->cache = INVALID_HANDLE_VALUE;
- data->state = (Data::State)(data->state & ~(Data::UsingCacheFile));
- }
-
- data->configData = new BYTE[configSize];
- if (ReadFileData( config, data->configData, configSize ) != S_OK)
- {
- goto ADD_DATA;
- }
- data->configDataSize = configSize;
- }
- retval = (ConfigRetval)(retval | ConfigFile);
- }
-
-ADD_DATA:
- {
- CrstHolder ch(&dataLock_);
-
- if (addToList)
- {
- IfFailThrow(entries_.Append(data));
- }
- }
-
- _ASSERTE( data );
- data->initRetval = retval;
-
- return retval;
-
-};
-
-static CacheEntry* LoadNextEntry( HANDLE cache, Data* data )
-{
- STANDARD_VM_CONTRACT;
-
- if ((data->state & Data::CacheExhausted) != 0)
- return NULL;
-
- NewHolder<CacheEntry> entry(new CacheEntry());
-
- if (SetFilePointer( cache, data->cacheCurrentPosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- {
- return NULL;
- }
-
- if (ReadFileData( cache, (BYTE*)&entry.GetValue()->header, sizeof( CacheEntryHeader ) ) != S_OK)
- {
- return NULL;
- }
-
- entry.GetValue()->cachePosition = data->cacheCurrentPosition + sizeof( entry.GetValue()->header );
-
- data->cacheCurrentPosition += sizeof( entry.GetValue()->header ) + entry.GetValue()->header.keySize + entry.GetValue()->header.dataSize;
-
- if (SetFilePointer( cache, entry.GetValue()->header.keySize + entry->header.dataSize, NULL, FILE_CURRENT ) == INVALID_SET_FILE_POINTER)
- {
- return NULL;
- }
-
- // We append a partially populated entry. CompareEntry is robust enough to handle this.
- IfFailThrow(data->oldCacheEntries->Append( entry ));
-
- return entry.Extract();
-}
-
-static BOOL WriteEntry( HANDLE cache, CacheEntry* entry, HANDLE oldCache = NULL )
-{
- STANDARD_VM_CONTRACT;
-
- if (WriteFileData( cache, (BYTE*)&entry->header, sizeof( CacheEntryHeader ) ) != S_OK)
- {
- return FALSE;
- }
-
- if (entry->key == NULL)
- {
- _ASSERTE (oldCache != NULL);
-
- // We were lazy in reading the entry. Read the key now.
- entry->key = new BYTE[entry->header.keySize];
-
- _ASSERTE (cache != INVALID_HANDLE_VALUE);
-
- if (SetFilePointer( oldCache, entry->cachePosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- return NULL;
-
- if (ReadFileData( oldCache, entry->key, entry->header.keySize ) != S_OK)
- {
- return NULL;
- }
-
- entry->cachePosition += entry->header.keySize;
- }
-
- _ASSERTE( entry->key != NULL );
-
- if (entry->data == NULL)
- {
- _ASSERTE (oldCache != NULL);
-
- // We were lazy in reading the entry. Read the data also.
- entry->data = new BYTE[entry->header.dataSize];
-
- if (SetFilePointer( oldCache, entry->cachePosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- return NULL;
-
- if (ReadFileData( oldCache, entry->data, entry->header.dataSize ) != S_OK)
- return NULL;
-
- entry->cachePosition += entry->header.dataSize;
- }
-
- _ASSERT( entry->data != NULL );
-
- if (WriteFileData( cache, entry->key, entry->header.keySize ) != S_OK)
- {
- return FALSE;
- }
-
- if (WriteFileData( cache, entry->data, entry->header.dataSize ) != S_OK)
- {
- return FALSE;
- }
-
- return TRUE;
-}
-
-BOOL SecurityConfig::SaveCacheData( INT32 id )
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END
-
- GCX_PREEMP();
-
- // Note: this function should only be called at EEShutdown time.
- // This is because we need to close the current cache file in
- // order to delete it. If it ever became necessary to do
- // cache saves while a process we still executing managed code
- // it should be possible to create a locking scheme for usage
- // of the cache handle with very little reordering of the below
- // (as it should always be possible for us to have a live copy of
- // the file and yet still be making the swap).
-
- HandleHolder cache;
- HandleHolder config;
- CacheHeader header;
- BOOL retval = FALSE;
- BOOL fWriteSucceeded = FALSE;
- DWORD numEntriesWritten = 0;
- DWORD amountWritten = 0;
- DWORD sizeConfig = 0;
- NewHolder<BYTE> configBuffer;
- BOOL useConfigData = FALSE;
-
- Data* data = (Data*)GetData( id );
-
- // If there is not data by the id or there is no
- // cache file name associated with the data, then fail.
-
- if (data == NULL || data->cacheFileName == NULL)
- return FALSE;
-
- // If we haven't added anything new to the cache
- // then just return success.
-
- if ((data->state & Data::CacheUpdated) == 0)
- return TRUE;
-
- // If the config file has changed since the process started
- // then our cache data is no longer valid. We'll just
- // return success in this case.
-
- if ((data->state & Data::UsingConfigFile) != 0 && CacheOutOfDate( &data->configFileTime, data->configFileName, NULL ))
- return TRUE;
-
- DWORD fileNameLength = (DWORD)wcslen( data->cacheFileName );
-
- NewArrayHolder<WCHAR> newFileName(new WCHAR[fileNameLength + 5]);
-
- swprintf_s( newFileName.GetValue(), fileNameLength + 5, W("%s%s"), data->cacheFileName, W(".new") );
-
- cache.Assign( WszCreateFile( newFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ) );
-
- for (DWORD RetryCount = 0; RetryCount < 5; RetryCount++)
- {
- if (cache != INVALID_HANDLE_VALUE)
- {
- break;
- }
- else
- {
- DWORD error = GetLastError();
-
- if (error == ERROR_PATH_NOT_FOUND)
- {
- // The directory does not exist, iterate through and try to create it.
-
- WCHAR* currentChar = newFileName;
-
- // Skip the first backslash
-
- while (*currentChar != W('\0'))
- {
- if (*currentChar == W('\\') || *currentChar == W('/'))
- {
- currentChar++;
- break;
- }
- currentChar++;
- }
-
- // Iterate through trying to create each subdirectory.
-
- while (*currentChar != W('\0'))
- {
- if (*currentChar == W('\\') || *currentChar == W('/'))
- {
- *currentChar = W('\0');
-
- if (!WszCreateDirectory( newFileName, NULL ))
- {
- error = GetLastError();
-
- if (error != ERROR_ACCESS_DENIED && error != ERROR_INVALID_NAME && error != ERROR_ALREADY_EXISTS)
- {
- goto CLEANUP;
- }
- }
-
- *currentChar = W('\\');
- }
- currentChar++;
- }
-
- // Try the file creation again
- continue;
- }
- }
-
- // CreateFile failed. Sleep a little and retry, in case a
- // virus scanner caused the creation to fail.
- ClrSleepEx(10, FALSE);
- }
-
- if (cache.GetValue() == INVALID_HANDLE_VALUE)
- goto CLEANUP;
-
- // This code seems complicated only because of the
- // number of cases that we are trying to handle. All we
- // are trying to do is determine the amount of space to
- // leave for the config information.
-
- // If we saved out a new config file during this run, use
- // the config size stored in the Data object itself.
-
- if (data->configData != NULL)
- {
- useConfigData = TRUE;
- }
-
- if ((data->state & Data::NewConfigFile) != 0)
- {
- sizeConfig = data->sizeConfig;
- }
-
- // If we have a cache file, then use the size stored in the
- // cache header.
-
- else if ((data->state & Data::UsingCacheFile) != 0)
- {
- sizeConfig = data->header.sizeConfig;
- }
-
- // If we read in the config data, use the size of the
- // managed byte array that it is stored in.
-
- else if (useConfigData)
- {
- sizeConfig = data->configDataSize;
- }
-
- // Otherwise, check the config file itself to get the size.
-
- else
- {
- DWORD shareFlags;
-
- shareFlags = GetShareFlags();
-
- config.Assign( WszCreateFile( data->configFileName, GENERIC_READ, shareFlags, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ) );
-
- if (config == INVALID_HANDLE_VALUE)
- {
- sizeConfig = 0;
- }
- else
- {
- sizeConfig = SafeGetFileSize( config, NULL );
-
- if (sizeConfig == 0xFFFFFFFF)
- {
- sizeConfig = 0;
- }
- }
- }
-
- // First write the entries.
-
- if (SetFilePointer( cache, sizeof( CacheHeader ) + sizeConfig, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- {
- goto CLEANUP;
- }
-
- // We're going to write out the cache entries in a modified
- // least recently used order, throwing out any that end up
- // taking us past our hardcoded max file size.
-
- {
- // First, write the entries from the cache file that were used.
- // We do this because presumably these are system assemblies
- // and other assemblies used by a number of applications.
-
- ArrayList::Iterator iter;
-
- if ((data->state & Data::UsingCacheFile) != 0)
- {
- iter = data->oldCacheEntries->Iterate();
-
- while (iter.Next() && amountWritten < MAX_CACHEFILE_SIZE)
- {
- CacheEntry* currentEntry = (CacheEntry*)iter.GetElement();
-
- if (currentEntry->used)
- {
- if(!WriteEntry( cache, currentEntry, data->cache ))
- {
- goto CLEANUP;
- }
-
- amountWritten += SIZE_OF_ENTRY( currentEntry );
- numEntriesWritten++;
- }
- }
- }
-
- // Second, write any new cache entries to the file. These are
- // more likely to be assemblies specific to this app.
-
- iter = data->newCacheEntries->Iterate();
-
- while (iter.Next() && amountWritten < MAX_CACHEFILE_SIZE)
- {
- CacheEntry* currentEntry = (CacheEntry*)iter.GetElement();
-
- if (!WriteEntry( cache, currentEntry ))
- {
- goto CLEANUP;
- }
-
- amountWritten += SIZE_OF_ENTRY( currentEntry );
- numEntriesWritten++;
- }
-
- // Third, if we are using the cache file, write the old entries
- // that were not used this time around.
-
- if ((data->state & Data::UsingCacheFile) != 0)
- {
- // First, write the ones that we already have partially loaded
-
- iter = data->oldCacheEntries->Iterate();
-
- while (iter.Next() && amountWritten < MAX_CACHEFILE_SIZE)
- {
- CacheEntry* currentEntry = (CacheEntry*)iter.GetElement();
-
- if (!currentEntry->used)
- {
- if(!WriteEntry( cache, currentEntry, data->cache ))
- {
- goto CLEANUP;
- }
-
- amountWritten += SIZE_OF_ENTRY( currentEntry );
- numEntriesWritten++;
- }
- }
-
- while (amountWritten < MAX_CACHEFILE_SIZE)
- {
- CacheEntry* entry = LoadNextEntry( data->cache, data );
-
- if (entry == NULL)
- break;
-
- if (!WriteEntry( cache, entry, data->cache ))
- {
- goto CLEANUP;
- }
-
- amountWritten += SIZE_OF_ENTRY( entry );
- numEntriesWritten++;
- }
- }
-
- fWriteSucceeded = TRUE;
- }
-
-
- if (!fWriteSucceeded)
- {
- CloseHandle( cache.GetValue() );
- cache.SuppressRelease();
- WszDeleteFile( newFileName );
- goto CLEANUP;
- }
-
- // End with writing the header.
-
- header.configFileTime = data->configFileTime;
- header.isSecurityOn = 1;
- header.numEntries = numEntriesWritten;
- header.quickCache = data->header.quickCache;
- header.sizeConfig = sizeConfig;
-
- if (SetFilePointer( cache, 0, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- {
- // Couldn't move to the beginning of the file
- goto CLEANUP;
- }
-
- if (WriteFileData( cache, (PBYTE)&header, sizeof( header ) ) != S_OK)
- {
- // Couldn't write header info.
- goto CLEANUP;
- }
-
- if (sizeConfig != 0)
- {
- if ((data->state & Data::NewConfigFile) != 0)
- {
- if (WriteFileData( cache, data->configBuffer, sizeConfig ) != S_OK)
- {
- goto CLEANUP;
- }
- }
- else
- {
- if (data->configData != NULL)
- {
- if (WriteFileData( cache, data->configData, sizeConfig ) != S_OK)
- {
- goto CLEANUP;
- }
- }
- else if ((data->state & Data::UsingCacheFile) != 0)
- {
- configBuffer.Assign( new BYTE[sizeConfig] );
-
- if (SetFilePointer( data->cache, sizeof( CacheHeader ), NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- {
- goto CLEANUP;
- }
-
- if (ReadFileData( data->cache, configBuffer.GetValue(), sizeConfig ) != S_OK)
- {
- goto CLEANUP;
- }
-
- if (WriteFileData( cache, configBuffer.GetValue(), sizeConfig ) != S_OK)
- {
- goto CLEANUP;
- }
- }
- else
- {
- configBuffer.Assign( new BYTE[sizeConfig] );
-
- if (SetFilePointer( config, 0, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- {
- goto CLEANUP;
- }
-
- if (ReadFileData( config, configBuffer.GetValue(), sizeConfig ) != S_OK)
- {
- goto CLEANUP;
- }
-
- if (WriteFileData( cache, configBuffer.GetValue(), sizeConfig ) != S_OK)
- {
- goto CLEANUP;
- }
- }
- }
- }
-
- // Flush the file buffers to make sure
- // we get full write through.
-
- FlushFileBuffers( cache.GetValue() );
-
- CloseHandle( cache );
- cache.SuppressRelease();
- CloseHandle( data->cache );
- data->cache = INVALID_HANDLE_VALUE;
-
- // Move the existing file out of the way
- // Note: use MoveFile because we know it will never cross
- // device boundaries.
-
- // Note: the delete file can fail, but we can't really do anything
- // if it does so just ignore any failures.
- WszDeleteFile( data->cacheFileNameTemp );
-
- // Try to move the existing cache file out of the way. However, if we can't
- // then try to delete it. If it can't be deleted then just bail out.
- if (!WszMoveFile( data->cacheFileName, data->cacheFileNameTemp ) &&
- (!Assembly::FileNotFound(HRESULT_FROM_WIN32(GetLastError()))) &&
- !WszDeleteFile( data->cacheFileName ))
- {
- if (!Assembly::FileNotFound(HRESULT_FROM_WIN32(GetLastError())))
- goto CLEANUP;
- }
-
- // Move the new file into position
-
- if (!WszMoveFile( newFileName, data->cacheFileName ))
- {
- goto CLEANUP;
- }
-
- retval = TRUE;
-
-CLEANUP:
- if (retval)
- cache.SuppressRelease();
-
- return retval;
-
-}
-
-void QCALLTYPE SecurityConfig::ResetCacheData(INT32 id)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- Data* data = (Data*)GetData( id );
-
- if (data != NULL)
- {
- CrstHolder ch(&dataLock_);
-
- data->DeleteAllEntries();
-
- data->oldCacheEntries = new ArrayList;
- data->newCacheEntries = new ArrayList;
-
- data->header = CacheHeader();
- data->state = (Data::State)(~(Data::CopyCacheFile | Data::UsingCacheFile) & data->state);
-
- HandleHolder config(WszCreateFile( data->configFileName, GENERIC_READ, GetShareFlags(), NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ));
-
- if (config.GetValue() != INVALID_HANDLE_VALUE)
- {
- VERIFY(GetFileTime( config, NULL, NULL, &data->configFileTime ));
- VERIFY(GetFileTime( config, NULL, NULL, &data->header.configFileTime ));
- }
-}
-
- END_QCALL;
-}
-
-HRESULT QCALLTYPE SecurityConfig::SaveDataByte(LPCWSTR wszConfigPath, LPCBYTE pbData, DWORD cbData)
-{
- QCALL_CONTRACT;
-
- HRESULT retval = E_FAIL;
-
- BEGIN_QCALL;
-
- HandleHolder newFile(INVALID_HANDLE_VALUE);
-
- int RetryCount;
- DWORD error = 0;
- DWORD fileNameLength = (DWORD) wcslen(wszConfigPath);
-
- NewArrayHolder<WCHAR> newFileName(new WCHAR[fileNameLength + 5]);
- NewArrayHolder<WCHAR> oldFileName(new WCHAR[fileNameLength + 5]);
-
- swprintf_s( newFileName.GetValue(), fileNameLength + 5, W("%s%s"), wszConfigPath, W(".new") );
- swprintf_s( oldFileName.GetValue(), fileNameLength + 5, W("%s%s"), wszConfigPath, W(".old") );
-
- // Create the new file.
- for (RetryCount = 0; RetryCount < 5; RetryCount++) {
- newFile.Assign( WszCreateFile( newFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ) );
-
- if (newFile != INVALID_HANDLE_VALUE)
- break;
- else
- {
- error = GetLastError();
-
- if (error == ERROR_PATH_NOT_FOUND)
- {
- // The directory does not exist, iterate through and try to create it.
-
- WCHAR* currentChar = newFileName;
-
- // Skip the first backslash
-
- while (*currentChar != W('\0'))
- {
- if (*currentChar == W('\\') || *currentChar == W('/'))
- {
- currentChar++;
- break;
- }
- currentChar++;
- }
-
- // Iterate through trying to create each subdirectory.
-
- while (*currentChar != W('\0'))
- {
- if (*currentChar == W('\\') || *currentChar == W('/'))
- {
- *currentChar = W('\0');
-
- if (!WszCreateDirectory( newFileName, NULL ))
- {
- error = GetLastError();
-
- if (error != ERROR_ACCESS_DENIED && error != ERROR_ALREADY_EXISTS)
- {
- goto CLEANUP;
- }
- }
-
- *currentChar = W('\\');
- }
- currentChar++;
- }
-
- // Try the file creation again
- continue;
- }
- }
-
- // CreateFile failed. Sleep a little and retry, in case a
- // virus scanner caused the creation to fail.
- ClrSleepEx(10, FALSE);
- }
-
- if (newFile == INVALID_HANDLE_VALUE) {
- goto CLEANUP;
- }
-
- // Write the data into it.
- if ((retval = WriteFileData(newFile.GetValue(), pbData, cbData)) != S_OK)
- {
- // Write failed, destroy the file and bail.
- // Note: if the delete fails, we always do a CREATE_NEW
- // for this file so that should take care of it. If not
- // we'll fail to write out future cache files.
- CloseHandle( newFile.GetValue() );
- newFile.SuppressRelease();
- WszDeleteFile( newFileName );
- goto CLEANUP;
- }
-
- if (!FlushFileBuffers(newFile.GetValue()))
- {
- error = GetLastError();
- goto CLEANUP;
- }
-
- CloseHandle( newFile.GetValue() );
- newFile.SuppressRelease();
-
- // Move the existing file out of the way
- if (!WszMoveFileEx( wszConfigPath, oldFileName, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED ))
- {
- // If move fails for a reason other than not being able to find the file, bail out.
- // Also, if the old file didn't exist, we have no need to delete it.
- HRESULT hrMove = HRESULT_FROM_WIN32(GetLastError());
- if (!Assembly::FileNotFound(hrMove))
- {
- retval = hrMove;
- WszDeleteFile(wszConfigPath);
- goto CLEANUP;
- }
- }
-
- // Move the new file into position
-
- if (!WszMoveFileEx( newFileName, wszConfigPath, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED ))
- {
- error = GetLastError();
- goto CLEANUP;
- }
-
- retval = S_OK;
-
-CLEANUP:
- if (retval == E_FAIL && error != 0)
- retval = HRESULT_FROM_WIN32(error);
-
- END_QCALL;
-
- return retval;
-}
-
-BOOL QCALLTYPE SecurityConfig::RecoverData(INT32 id)
- {
- QCALL_CONTRACT;
-
- BOOL retval = FALSE;
-
- BEGIN_QCALL;
-
- Data* data = (Data*)GetData( id );
-
- if (data == NULL)
- goto CLEANUP;
-
- {
- DWORD fileNameLength = (DWORD)wcslen( data->configFileName );
-
- NewArrayHolder<WCHAR> tempFileName(new WCHAR[fileNameLength + 10]);
- NewArrayHolder<WCHAR> oldFileName(new WCHAR[fileNameLength + 5]);
-
- swprintf_s( tempFileName.GetValue(), fileNameLength + 10, W("%s%s"), data->configFileName, W(".old.temp") );
- swprintf_s( oldFileName.GetValue(), fileNameLength + 5, W("%s%s"), data->configFileName, W(".old") );
-
- HandleHolder oldFile(WszCreateFile( oldFileName, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ));
-
- if (oldFile.GetValue() == INVALID_HANDLE_VALUE)
- {
- goto CLEANUP;
- }
-
- CloseHandle( oldFile );
- oldFile.SuppressRelease();
-
- if (!WszMoveFile( data->configFileName, tempFileName ))
- {
- goto CLEANUP;
- }
-
- if (!WszMoveFile( oldFileName, data->configFileName ))
- {
- goto CLEANUP;
- }
-
- if (!WszMoveFile( tempFileName, oldFileName ))
- {
- goto CLEANUP;
- }
- }
-
- // We need to do some work to reset the unmanaged data object
- // so that the managed side of things behaves like you'd expect.
- // This basically means cleaning up the open resources and
- // doing the work to init on a different set of files.
-
- data->Reset();
- InitData( data, FALSE );
-
- retval = TRUE;
-
-CLEANUP:
- END_QCALL;
-
- return retval;
-}
-
-BOOL SecurityConfig::GetQuickCacheEntry( INT32 id, QuickCacheEntryType type )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END
-
- //
- // If there is no config file for this level, then we'll assume the default
- // security policy is in effect. This could happen for example if there is
- // user profile loaded or if the config file is not present.
- //
-
- Data* data = (Data*)GetData( id );
- if (data == NULL || ((data->state & Data::UsingConfigFile) == 0))
- return (type == FullTrustZoneMyComputer); // MyComputer gets FT by default.
-
- if ((data->state & Data::UsingCacheFile) == 0)
- return FALSE;
-
- return (data->header.quickCache & type);
-}
-
-void QCALLTYPE SecurityConfig::SetQuickCache(INT32 id, QuickCacheEntryType type)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- Data* data = (Data*)GetData( id );
-
- if (data != NULL && (DWORD) type != data->header.quickCache)
- {
- CrstHolder ch(&dataLock_);
-
- data->state = (Data::State)(Data::CacheUpdated | data->state);
- data->header.quickCache = type;
- }
-
- END_QCALL;
-}
-
-static HANDLE OpenCacheFile( Data* data )
-{
- STANDARD_VM_CONTRACT;
-
- CrstHolder ch(&SecurityConfig::dataLock_);
-
- if (data->cache != INVALID_HANDLE_VALUE)
- return data->cache;
-
- _ASSERTE( FALSE && "This case should never happen" );
-
- data->cache = WszCreateFile( data->cacheFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
- if (data->cache == INVALID_HANDLE_VALUE)
- return NULL;
-
- // Check whether the cache has changed since we first looked at it.
- // If it has but the config file hasn't, then we need to start fresh.
- // However, if the config file has changed then we have to ignore it.
-
- if (CacheOutOfDate( &data->cacheFileTime, data->cache, NULL ))
- {
- if (CacheOutOfDate( &data->configFileTime, data->configFileName, NULL ))
- return NULL;
-
- if (ReadFileData( data->cache, (BYTE*)&data->header, sizeof( CacheHeader ) ) != S_OK)
- return NULL;
-
- data->cacheCurrentPosition = sizeof( CacheHeader );
-
- if (data->oldCacheEntries != NULL)
- {
- ArrayList::Iterator iter = data->oldCacheEntries->Iterate();
- while (iter.Next())
- {
- delete (CacheEntry*)iter.GetElement();
- }
- delete data->oldCacheEntries;
- data->oldCacheEntries = new ArrayList();
- }
- }
-
- return data->cache;
-}
-
-static BYTE* CompareEntry( CacheEntry* entry, DWORD numEvidence, DWORD evidenceSize, LPCBYTE evidenceBlock, HANDLE cache, DWORD* size)
-{
- STANDARD_VM_CONTRACT;
-
- _ASSERTE (entry);
-
- if (entry->header.numItemsInKey == numEvidence &&
- entry->header.keySize == evidenceSize)
- {
- if (entry->key == NULL)
- {
- // We were lazy in reading the entry. Read the key now.
- entry->key = new BYTE[entry->header.keySize];
-
- _ASSERTE (cache != INVALID_HANDLE_VALUE);
-
- if (SetFilePointer( cache, entry->cachePosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- return NULL;
-
- if (ReadFileData( cache, entry->key, entry->header.keySize ) != S_OK)
- return NULL;
-
- entry->cachePosition += entry->header.keySize;
- }
-
- _ASSERTE (entry->key);
-
- if (memcmp( entry->key, evidenceBlock, entry->header.keySize ) == 0)
- {
- if (entry->data == NULL)
- {
- // We were lazy in reading the entry. Read the data also.
- entry->data = new BYTE[entry->header.dataSize];
-
- if (SetFilePointer( cache, entry->cachePosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- return NULL;
-
- if (ReadFileData( cache, entry->data, entry->header.dataSize ) != S_OK)
- return NULL;
-
- entry->cachePosition += entry->header.dataSize;
- }
-
- entry->used = TRUE;
- *size = entry->header.dataSize;
-
- return entry->data;
- }
- }
- return NULL;
-}
-
-BOOL QCALLTYPE SecurityConfig::GetCacheEntry(INT32 id, DWORD numEvidence, LPCBYTE pEvidence, DWORD cbEvidence, QCall::ObjectHandleOnStack retPolicy)
-{
- QCALL_CONTRACT;
-
- BOOL success = FALSE;
-
- BEGIN_QCALL;
-
- HANDLE cache = INVALID_HANDLE_VALUE;
-
- BYTE* retval = NULL;
- DWORD size = (DWORD) -1;
-
- Data* data = (Data*)GetData( id );
-
- if (data == NULL)
- {
- goto CLEANUP;
- }
-
- {
-
- ArrayList::Iterator iter;
-
- if ((data->state & Data::UsingCacheFile) == 0)
- {
- // We know we don't have anything in the config file, so
- // let's just look through the new entries to make sure we
- // aren't getting any repeats.
-
- // Then try the existing new entries
-
- iter = data->newCacheEntries->Iterate();
-
- while (iter.Next())
- {
- // newCacheEntries do not need the cache file so pass in NULL.
- retval = CompareEntry( (CacheEntry*)iter.GetElement(), numEvidence, cbEvidence, pEvidence, NULL, &size );
-
- if (retval != NULL)
- {
- success = TRUE;
- goto CLEANUP;
- }
- }
-
- goto CLEANUP;
- }
-
- // Its possible that the old entries were not read in completely
- // so we keep the cache file open before iterating through the
- // old entries.
-
- cache = OpenCacheFile( data );
-
- if ( cache == NULL )
- {
- goto CLEANUP;
- }
-
- // First, iterator over the old entries
-
- {
- CrstHolder ch(&dataLock_);
-
- iter = data->oldCacheEntries->Iterate();
- while (iter.Next())
- {
- retval = CompareEntry( (CacheEntry*)iter.GetElement(), numEvidence, cbEvidence, pEvidence, cache, &size );
- if (retval != NULL)
- {
- success = TRUE;
- goto CLEANUP;
- }
- }
-
- // LockHolder goes out of scope here
- }
-
- // Then try the existing new entries
- iter = data->newCacheEntries->Iterate();
- while (iter.Next())
- {
- // newCacheEntries do not need the cache file so pass in NULL.
- retval = CompareEntry( (CacheEntry*)iter.GetElement(), numEvidence, cbEvidence, pEvidence, NULL, &size );
- if (retval != NULL)
- {
- success = TRUE;
- goto CLEANUP;
- }
- }
-
- // Finally, try loading existing entries from the file
-
- {
- CrstHolder ch(&dataLock_);
-
- if (SetFilePointer( cache, data->cacheCurrentPosition, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER)
- {
- goto CLEANUP;
- }
-
- do
- {
- CacheEntry* entry = LoadNextEntry( cache, data );
- if (entry == NULL)
- {
- data->state = (Data::State)(Data::CacheExhausted | data->state);
- break;
- }
-
- retval = CompareEntry( entry, numEvidence, cbEvidence, pEvidence, cache, &size );
- if (retval != NULL)
- {
- success = TRUE;
- break;
- }
- } while (TRUE);
-
- // LockHolder goes out of scope here
- }
- }
-
-CLEANUP:
- if (success && retval != NULL)
- {
- _ASSERTE( size != (DWORD) -1 );
- retPolicy.SetByteArray(retval, size);
- }
-
- END_QCALL;
-
- return success;
-}
-
-void QCALLTYPE SecurityConfig::AddCacheEntry(INT32 id, DWORD numEvidence, LPCBYTE pEvidence, DWORD cbEvidence, LPCBYTE pPolicy, DWORD cbPolicy)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- Data* data = (Data*)GetData( id );
-
- DWORD sizeOfEntry = 0;
- NewHolder<CacheEntry> entry;
-
- if (data == NULL)
- {
- goto lExit;
- }
-
- // In order to limit how large a long running app can become,
- // we limit the total memory held by the new cache entries list.
- // For now this limit corresponds with how large the max cache file
- // can be.
-
- sizeOfEntry = cbEvidence + cbPolicy + sizeof( CacheEntryHeader );
-
- if (data->newEntriesSize + sizeOfEntry >= MAX_CACHEFILE_SIZE)
- {
- goto lExit;
- }
-
- entry = new CacheEntry();
-
- entry->header.numItemsInKey = numEvidence;
- entry->header.keySize = cbEvidence;
- entry->header.dataSize = cbPolicy;
-
- entry->key = new BYTE[entry->header.keySize];
- entry->data = new BYTE[entry->header.dataSize];
-
- memcpyNoGCRefs(entry->key, pEvidence, cbEvidence);
- memcpyNoGCRefs(entry->data, pPolicy, cbPolicy);
-
- {
- CrstHolder ch(&dataLock_);
-
- // Check the size again to handle the race.
- if (data->newEntriesSize + sizeOfEntry < MAX_CACHEFILE_SIZE)
- {
- data->state = (Data::State)(Data::CacheUpdated | data->state);
- IfFailThrow(data->newCacheEntries->Append( entry.GetValue() ));
- entry.SuppressRelease();
- data->newEntriesSize += sizeOfEntry;
- }
- }
-
-lExit: ;
-
- END_QCALL;
-}
-
-ArrayListStatic SecurityConfig::entries_;
-CrstStatic SecurityConfig::dataLock_;
-
-void SecurityConfig::Init( void )
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END
-
- dataLock_.Init(CrstSecurityPolicyCache);
- entries_.Init();
-}
-
-void SecurityConfig::Cleanup( void )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END
-
- ArrayList::Iterator iter = entries_.Iterate();
-
- GCX_PREEMP();
-
- CrstHolder ch(&dataLock_);
-
- while (iter.Next())
- {
- ((Data*) iter.GetElement())->Cleanup();
- }
-}
-
-void SecurityConfig::Delete( void )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END
-
- ArrayList::Iterator iter = entries_.Iterate();
-
- while (iter.Next())
- {
- delete (Data*) iter.GetElement();
- }
-
- entries_.Destroy();
- dataLock_.Destroy();
-}
-
-void QCALLTYPE SecurityConfig::_GetMachineDirectory(QCall::StringHandleOnStack retDirectory)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- WCHAR machine[MAX_LONGPATH];
-
- HRESULT hr = GetMachineDirectory(machine, MAX_LONGPATH);
- if (FAILED(hr))
- ThrowHR(hr);
-
- retDirectory.Set(machine);
-
- END_QCALL;
-}
-
-void QCALLTYPE SecurityConfig::_GetUserDirectory(QCall::StringHandleOnStack retDirectory)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- WCHAR user[MAX_LONGPATH];
-
- BOOL result = GetUserDirectory(user, MAX_LONGPATH);
- if (result)
- retDirectory.Set(user);
-
- END_QCALL;
-}
-
-HRESULT SecurityConfig::GetMachineDirectory(__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr;
-
- DWORD length = (DWORD)bufferCount;
- hr = GetInternalSystemDirectory(buffer, &length);
- if (FAILED(hr))
- return hr;
-
- // Make sure we have enough buffer to concat the string.
- // Note the length including the terminating zero.
- if((bufferCount - wcslen(buffer) - 1) < wcslen(W("config\\")))
- return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
-
- wcscat_s(buffer, bufferCount, W("config\\"));
-
- return S_OK;
-}
-
-BOOL SecurityConfig::GetVIUserDirectory(__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount)
-{
- STANDARD_VM_CONTRACT;
-
- WCHAR scratchBuffer[MAX_LONGPATH];
- BOOL retval = FALSE;
-
- DWORD size = MAX_LONGPATH;
-
- if (!GetUserDir(buffer, bufferCount, TRUE))
- goto CLEANUP;
-
- wcscpy_s( scratchBuffer, COUNTOF(scratchBuffer), W("\\Microsoft\\CLR Security Config\\") );
-
- if (bufferCount < wcslen( buffer ) + wcslen( scratchBuffer ) + 1)
- {
- goto CLEANUP;
- }
-
- wcscat_s( buffer, bufferCount, scratchBuffer );
-
- retval = TRUE;
-
-CLEANUP:
- return retval;
-}
-
-BOOL SecurityConfig::GetUserDirectory(__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount)
-{
- STANDARD_VM_CONTRACT;
-
- StackSString ssScratchBuffer;
- BOOL retval = FALSE;
-
- WCHAR* wszScratchBuffer = ssScratchBuffer.OpenUnicodeBuffer( (COUNT_T)bufferCount );
- retval = GetVIUserDirectory(wszScratchBuffer, bufferCount);
- ssScratchBuffer.CloseBuffer( (COUNT_T)wcslen( wszScratchBuffer ) );
-
- if (!retval)
- return retval;
-
- ssScratchBuffer.Append( W("v") );
- ssScratchBuffer.Append( VER_PRODUCTVERSION_NO_QFE_STR_L );
- ssScratchBuffer.Append( W("\\") );
-
-#ifdef _WIN64
- ssScratchBuffer.Append( W("64bit\\") );
-#endif // _WIN64
-
- if (ssScratchBuffer.GetCount() + 1 > bufferCount)
- return FALSE;
-
- wcscpy_s( buffer, bufferCount, ssScratchBuffer.GetUnicode() );
-
- return TRUE;
-}
-
-BOOL QCALLTYPE SecurityConfig::WriteToEventLog(LPCWSTR wszMessage)
-{
- QCALL_CONTRACT;
-
- BOOL retVal = FALSE;
-
- BEGIN_QCALL;
-
- retVal = ReportEventCLR(
- EVENTLOG_WARNING_TYPE, // event type
- 0, // category
- (DWORD)1000, // event identifier
- NULL, // no user security identifier
- &StackSString(wszMessage)); // message to log
-
- END_QCALL
-
- return retVal;
-}
-
-#ifdef _DEBUG
-HRESULT QCALLTYPE SecurityConfig::DebugOut(LPCWSTR wszFileName, LPCWSTR wszMessage)
-{
- HRESULT retVal = E_FAIL;
-
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- HandleHolder file(WszCreateFile( wszFileName, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ));
-
- if (file == INVALID_HANDLE_VALUE)
- {
- goto lExit;
- }
-
- SetFilePointer( file, 0, NULL, FILE_END );
-
- DWORD cbMessage;
- DWORD cbWritten;
-
- cbMessage = (DWORD)wcslen(wszMessage) * sizeof(WCHAR);
- if (!WriteFile( file, wszMessage, cbMessage, &cbWritten, NULL ))
- {
- goto lExit;
- }
-
- if (cbMessage != cbWritten)
- {
- goto lExit;
- }
-
- retVal = S_OK;
-
-lExit: ;
- END_QCALL;
-
- return retVal;
-}
-#endif
-
-#endif // FEATURE_CAS_POLICY
diff --git a/src/vm/securityconfig.h b/src/vm/securityconfig.h
deleted file mode 100644
index e7517c517e..0000000000
--- a/src/vm/securityconfig.h
+++ /dev/null
@@ -1,122 +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.
-//
-// File: SecurityConfig.h
-//
-
-//
-// Native implementation for security config access and manipulation
-//
-
-
-#ifndef _COMSecurityConfig_H_
-#define _COMSecurityConfig_H_
-#ifdef FEATURE_CAS_POLICY
-
-#include "qcall.h"
-
-class SecurityConfig
-{
-friend struct CacheHeader;
-
-private:
- // These structures can be removed in the next SxS runtime version when we won't have to potentially read
- // config files generated by an in-place runtime that used to include them in the header.
- enum RegistryExtensionsAccessStatus {
- Unknown = 0,
- NoExtensions = 1,
- AccessFailure = 2,
- AccessSuccess = 3
- };
-
- struct RegistryExtensionsInfo {
- RegistryExtensionsAccessStatus eStatus;
- FILETIME ftLastWriteTime;
- };
-
-public:
- // Duplicated in System.Security.Util.Config.cs
- enum ConfigId
- {
- None = 0,
- MachinePolicyLevel = 1,
- UserPolicyLevel = 2,
- EnterprisePolicyLevel = 3,
- };
-
- // Duplicated in System.Security.Util.Config.cs
- enum QuickCacheEntryType
- {
- FullTrustZoneMyComputer = 0x1000000,
- FullTrustZoneIntranet = 0x2000000,
- FullTrustZoneInternet = 0x4000000,
- FullTrustZoneTrusted = 0x8000000,
- FullTrustZoneUntrusted = 0x10000000,
- FullTrustAll = 0x20000000,
- };
-
- // Duplicated in System.Security.Util.Config.cs
- enum ConfigRetval
- {
- NoFile = 0,
- ConfigFile = 1,
- CacheFile = 2
- };
-
- static ConfigRetval InitData( INT32 id, const WCHAR* configFileName, const WCHAR* cacheFileName );
- static ConfigRetval InitData( void* configData, BOOL addToList );
-
- static BOOL SaveCacheData( INT32 id );
-
- static
- void QCALLTYPE ResetCacheData(INT32 id);
-
- static
- HRESULT QCALLTYPE SaveDataByte(LPCWSTR wszConfigPath, LPCBYTE pbData, DWORD cbData);
-
- static
- BOOL QCALLTYPE RecoverData(INT32 id);
-
- static
- void QCALLTYPE SetQuickCache(INT32 id, QuickCacheEntryType type);
-
- static
- BOOL QCALLTYPE GetCacheEntry(INT32 id, DWORD numEvidence, LPCBYTE pEvidence, DWORD cbEvidence, QCall::ObjectHandleOnStack retPolicy);
-
- static
- void QCALLTYPE AddCacheEntry(INT32 id, DWORD numEvidence, LPCBYTE pEvidence, DWORD cbEvidence, LPCBYTE pPolicy, DWORD cbPolicy);
-
- static
- void QCALLTYPE _GetMachineDirectory(QCall::StringHandleOnStack retDirectory);
-
- static
- void QCALLTYPE _GetUserDirectory(QCall::StringHandleOnStack retDirectory);
-
- static HRESULT GetMachineDirectory (__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount);
- static BOOL GetUserDirectory(__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount);
- static BOOL GetVIUserDirectory(__out_ecount(bufferCount) __out_z WCHAR* buffer, size_t bufferCount);
-
- static
- BOOL QCALLTYPE WriteToEventLog(LPCWSTR wszMessage);
-
-#ifdef _DEBUG
- static
- HRESULT QCALLTYPE DebugOut(LPCWSTR wszFileName, LPCWSTR wszMessage);
-#endif
-
- static void Init( void );
- static void Cleanup( void );
- static void Delete( void );
-
- static BOOL GetQuickCacheEntry( INT32 id, QuickCacheEntryType type );
-
- static void* GetData( INT32 id );
-
- static ArrayListStatic entries_;
- static CrstStatic dataLock_;
-
- static WCHAR* wcscatDWORD( __out_ecount(cchdst) __out_z WCHAR* dst, size_t cchdst, DWORD num );
-};
-#endif // FEATURE_CAS_POLICY
-#endif
diff --git a/src/vm/securitydeclarative.cpp b/src/vm/securitydeclarative.cpp
index e0aff16ddd..5771138b7d 100644
--- a/src/vm/securitydeclarative.cpp
+++ b/src/vm/securitydeclarative.cpp
@@ -12,9 +12,6 @@
#include "securitydeclarative.inl"
#include "eventtrace.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif // FEATURE_REMOTING
//-----------------------------------------------------------------------------
@@ -198,19 +195,11 @@ void SecurityDeclarative::AddDeclAction(CorDeclSecurity action, PsetCacheEntry *
break;
case DS_UNION:
-#ifdef FEATURE_CAS_POLICY
- LinkNewDeclAction(ppActionList, action, SecurityAttributes::MergePermissionSets(pClassPCE, pMethodPCE, false, action), pMeth);
-#else // FEATURE_CAS_POLICY
_ASSERTE(!"Declarative permission sets may not be unioned together in CoreCLR. Are you attempting to have a declarative demand or deny on both a method and its enclosing class?");
-#endif // FEATURE_CAS_POLICY
break;
case DS_INTERSECT:
-#ifdef FEATURE_CAS_POLICY
- LinkNewDeclAction(ppActionList, action, SecurityAttributes::MergePermissionSets(pClassPCE, pMethodPCE, true, action), pMeth);
-#else // FEATURE_CAS_POLICY
_ASSERTE(!"Declarative permission sets may not be intersected in CoreCLR. Are you attempting to have a declarative permit only on both a method and its enclosing class?");
-#endif // FEATURE_CAS_POLICY
break;
case DS_APPLY_METHOD_THEN_CLASS:
@@ -269,14 +258,7 @@ DeclActionInfo* SecurityDeclarative::DetectDeclActions(MethodDesc *pMeth, DWORD
if (pClass->HasSuppressUnmanagedCodeAccessAttr())
{
-#ifdef FEATURE_CORECLR
hr = S_OK;
-#else
- hr = pInternalImport->GetCustomAttributeByName(pMT->GetCl(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL);
-#endif // FEATURE_CORECLR
if (hr != S_OK)
{
g_IBCLogger.LogEEClassCOWTableAccess(pMT);
@@ -536,15 +518,7 @@ HRESULT SecurityDeclarative::GetDeclarationFlags(IMDInternalImport *pInternalImp
BOOL hasSuppressUnmanagedCodeAccessAttr;
if (pfHasSuppressUnmanagedCodeAccessAttr == NULL)
{
-#ifdef FEATURE_CORECLR
hasSuppressUnmanagedCodeAccessAttr = TRUE;
-#else
- hasSuppressUnmanagedCodeAccessAttr =
- (pInternalImport->GetCustomAttributeByName(token,
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK);
-#endif
}
else
hasSuppressUnmanagedCodeAccessAttr = *pfHasSuppressUnmanagedCodeAccessAttr;
@@ -605,175 +579,10 @@ void SecurityDeclarative::MethodInheritanceCheck(MethodDesc *pMethod, MethodDesc
//
//-----------------------------------------------------------------------------
-#ifdef FEATURE_APTCA
-void DECLSPEC_NORETURN SecurityDeclarative::ThrowAPTCAException(Assembly *pCaller, MethodDesc *pCallee)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- MethodDescCallSite throwSecurityException(METHOD__SECURITY_ENGINE__THROW_SECURITY_EXCEPTION);
-
- OBJECTREF callerObj = NULL;
- if (pCaller != NULL && pCaller->GetDomain() == GetAppDomain())
- callerObj = pCaller->GetExposedObject();
-
- ARG_SLOT args[7];
- args[0] = ObjToArgSlot(callerObj);
- args[1] = ObjToArgSlot(NULL);
- args[2] = ObjToArgSlot(NULL);
- args[3] = PtrToArgSlot(pCallee);
- args[4] = (ARG_SLOT)dclLinktimeCheck;
- args[5] = ObjToArgSlot(NULL);
- args[6] = ObjToArgSlot(NULL);
- throwSecurityException.Call(args);
-
- UNREACHABLE();
-}
-#endif // FEATURE_APTCA
-
-#ifdef FEATURE_CAS_POLICY
-void DECLSPEC_NORETURN SecurityDeclarative::ThrowHPException(EApiCategories protectedCategories, EApiCategories demandedCategories)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- OBJECTREF hpException = NULL;
- GCPROTECT_BEGIN(hpException);
-
- MethodTable* pMT = MscorlibBinder::GetClass(CLASS__HOST_PROTECTION_EXCEPTION);
- hpException = (OBJECTREF) AllocateObject(pMT);
-
-
- MethodDescCallSite ctor(METHOD__HOST_PROTECTION_EXCEPTION__CTOR);
-
- ARG_SLOT arg[3] = {
- ObjToArgSlot(hpException),
- protectedCategories,
- demandedCategories
- };
- ctor.Call(arg);
-
- COMPlusThrow(hpException);
-
- GCPROTECT_END();
-}
-#endif // FEATURE_CAS_POLICY
-
-#ifdef FEATURE_APTCA
-BOOL SecurityDeclarative::IsUntrustedCallerCheckNeeded(MethodDesc *pCalleeMD, Assembly *pCallerAssem)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- Assembly *pCalleeAssembly = pCalleeMD->GetAssembly();
- _ASSERTE(pCalleeAssembly != NULL);
-
- // ATPCA is only enforced for cross-assembly calls, so if the target is not accessable from outside
- // the assembly, or if the caller and callee are both within the same assembly, we do not need to
- // do any APTCA checks
- if (pCallerAssem == pCalleeAssembly)
- {
- return FALSE;
- }
-
- if (!MethodIsVisibleOutsideItsAssembly(pCalleeMD))
- {
- return FALSE;
- }
-
- // If the target assembly allows untrusted callers unconditionally, then the call should be allowed
- if (pCalleeAssembly->AllowUntrustedCaller())
- {
- return FALSE;
- }
-
- // Otherwise, we need to ensure the caller is fully trusted
- return TRUE;
-}
-#endif // FEATURE_APTCA
-
-#ifdef FEATURE_APTCA
-// Do a fulltrust check on the caller if the callee is fully trusted and
-// callee did not enable AllowUntrustedCallerChecks
-/*static*/
-void SecurityDeclarative::DoUntrustedCallerChecks(
- Assembly *pCaller, MethodDesc *pCallee,
- BOOL fFullStackWalk)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
- BOOL fRet = TRUE;
-#ifdef _DEBUG
- if (!g_pConfig->Do_AllowUntrustedCaller_Checks())
- return;
-#endif
-
- if (!IsUntrustedCallerCheckNeeded(pCallee, pCaller))
- return;
-
- // Expensive calls after this point, this could end up resolving policy
-
- if (fFullStackWalk)
- {
- // It is possible that wrappers like VBHelper libraries that are
- // fully trusted, make calls to public methods that do not have
- // safe for Untrusted caller custom attribute set.
- // Like all other link demand that gets transformed to a full stack
- // walk for reflection, calls to public methods also gets
- // converted to full stack walk
-
- OBJECTREF permSet = NULL;
- GCPROTECT_BEGIN(permSet);
-
- GetPermissionInstance(&permSet, SECURITY_FULL_TRUST);
- EX_TRY
- {
- SecurityStackWalk::DemandSet(SSWT_LATEBOUND_LINKDEMAND, permSet);
- }
- EX_CATCH
- {
- fRet = FALSE;
- }
- EX_END_CATCH(RethrowTerminalExceptions);
-
- GCPROTECT_END();
- }
- else
- {
- _ASSERTE(pCaller);
-
- // Link Demand only, no full stack walk here
- if (!pCaller->GetSecurityDescriptor()->IsFullyTrusted())
- fRet = FALSE;
- }
-
- if (!fRet)
- {
- ThrowAPTCAException(pCaller, pCallee);
- }
-}
-#endif // FEATURE_APTCA
// Retrieve all linktime demands sets for a method. This includes both CAS and
// non-CAS sets for LDs at the class and the method level, so we could get up to
@@ -791,17 +600,6 @@ void SecurityDeclarative::RetrieveLinktimeDemands(MethodDesc *pMD,
INJECT_FAULT(COMPlusThrowOM(););
} CONTRACTL_END;
-#ifdef FEATURE_CAS_POLICY
- MethodTable * pMT = pMD->GetMethodTable();
-
- // Class level first.
- if (pMT->GetClass()->RequiresLinktimeCheck())
- *pClassCas = TypeSecurityDescriptor::GetLinktimePermissions(pMT, pClassNonCas);
-
- // Then the method level.
- if (IsMdHasSecurity(pMD->GetAttrs()))
- *pMethodCas = MethodSecurityDescriptor::GetLinktimePermissions(pMD, pMethodNonCas);
-#endif
}
//
@@ -841,7 +639,7 @@ LinktimeCheckReason SecurityDeclarative::GetLinktimeCheckReason(MethodDesc *pMD,
LinktimeCheckReason reason = LinktimeCheckReason_None;
-#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_CORESYSTEM)
ModuleSecurityDescriptor *pMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pMD->GetAssembly());
// If the method does not allow partially trusted callers, then the check is because we need to ensure all
@@ -850,7 +648,7 @@ LinktimeCheckReason SecurityDeclarative::GetLinktimeCheckReason(MethodDesc *pMD,
{
reason |= LinktimeCheckReason_AptcaCheck;
}
-#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#endif // defined(FEATURE_CORESYSTEM)
//
// If the method has a LinkDemand on it for either CAS or non-CAS permissions, get those and set the
@@ -952,688 +750,5 @@ LinktimeCheckReason SecurityDeclarative::GetLinktimeCheckReason(MethodDesc *pMD,
return reason;
}
-#ifdef FEATURE_CAS_POLICY
-// Issue an inheritance demand against the target assembly
-
-// static
-void SecurityDeclarative::InheritanceDemand(Assembly *pTargetAssembly, OBJECTREF refDemand)
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- PRECONDITION(CheckPointer(pTargetAssembly));
- PRECONDITION(refDemand != NULL);
- }
- CONTRACTL_END;
-
- struct
- {
- OBJECTREF refDemand;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
- gc.refDemand = refDemand;
-
- GCPROTECT_BEGIN(gc);
-
- IAssemblySecurityDescriptor *pTargetASD = pTargetAssembly->GetSecurityDescriptor();
- SecurityStackWalk::LinkOrInheritanceCheck(pTargetASD,
- gc.refDemand,
- pTargetAssembly,
- dclInheritanceCheck);
- GCPROTECT_END();
-}
-
-// static
-void SecurityDeclarative::InheritanceLinkDemandCheck(Assembly *pTargetAssembly, MethodDesc * pMDLinkDemand)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pTargetAssembly));
- PRECONDITION(CheckPointer(pMDLinkDemand));
- }
- CONTRACTL_END;
-
- GCX_COOP();
- struct
- {
- OBJECTREF refClassCas;
- OBJECTREF refClassNonCas;
- OBJECTREF refMethodCas;
- OBJECTREF refMethodNonCas;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- Security::RetrieveLinktimeDemands(pMDLinkDemand,
- &gc.refClassCas,
- &gc.refClassNonCas,
- &gc.refMethodCas,
- &gc.refMethodNonCas);
-
- if (gc.refClassCas != NULL)
- {
- InheritanceDemand(pTargetAssembly, gc.refClassCas);
- }
-
- if (gc.refMethodCas != NULL)
- {
- InheritanceDemand(pTargetAssembly, gc.refMethodCas);
- }
-
- GCPROTECT_END();
-}
-
-// Issue a FullTrust inheritance demand against the target assembly
-
-// static
-void SecurityDeclarative::FullTrustInheritanceDemand(Assembly *pTargetAssembly)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pTargetAssembly));
- }
- CONTRACTL_END;
-
- GCX_COOP();
-
- struct
- {
- OBJECTREF refFullTrust;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.refFullTrust = Security::CreatePermissionSet(TRUE);
- InheritanceDemand(pTargetAssembly, gc.refFullTrust);
-
- GCPROTECT_END();
-}
-
-// Issue a FullTrust link demand against the target assembly
-
-// static
-void SecurityDeclarative::FullTrustLinkDemand(Assembly *pTargetAssembly)
-{
- CONTRACTL
- {
- THROWS;
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- PRECONDITION(CheckPointer(pTargetAssembly));
- }
- CONTRACTL_END;
-
- struct
- {
- OBJECTREF refFullTrust;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.refFullTrust = Security::CreatePermissionSet(TRUE);
- IAssemblySecurityDescriptor *pTargetASD = pTargetAssembly->GetSecurityDescriptor();
- SecurityStackWalk::LinkOrInheritanceCheck(pTargetASD,
- gc.refFullTrust,
- pTargetAssembly,
- dclLinktimeCheck);
- GCPROTECT_END();
-}
-
-// Used by interop to simulate the effect of link demands when the caller is
-// in fact script constrained by an appdomain setup by IE.
-void SecurityDeclarative::CheckLinkDemandAgainstAppDomain(MethodDesc *pMD)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- if (!pMD->RequiresLinktimeCheck())
- return;
-
- // Find the outermost (closest to caller) appdomain. This
- // represents the domain in which the unmanaged caller is
- // considered to "live" (or, at least, be constrained by).
- AppDomain *pDomain = GetThread()->GetInitialDomain();
-
- // The link check is only performed if this app domain has
- // security permissions associated with it, which will be
- // the case for all IE scripting callers that have got this
- // far because we automatically reported our managed classes
- // as "safe for scripting".
- //
- // We also can't do the check if the AppDomain isn't fully
- // setup yet, since we might not have a domain grant set.
- // This is acceptable, since the only code that should run
- // during AppDomain creation is fully trusted.
- IApplicationSecurityDescriptor *pSecDesc = pDomain->GetSecurityDescriptor();
- if (pSecDesc == NULL || pSecDesc->IsInitializationInProgress() || pSecDesc->IsDefaultAppDomain())
- return;
-
- struct _gc
- {
- OBJECTREF refGrant;
- OBJECTREF refRefused;
- OBJECTREF refClassNonCasDemands;
- OBJECTREF refClassCasDemands;
- OBJECTREF refMethodNonCasDemands;
- OBJECTREF refMethodCasDemands;
- OBJECTREF refAssembly;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
-#ifdef FEATURE_APTCA
- // Do a fulltrust check on the caller if the callee did not enable
- // AllowUntrustedCallerChecks. Pass a NULL caller assembly:
- // DoUntrustedCallerChecks needs to be able to cope with this.
- SecurityDeclarative::DoUntrustedCallerChecks(NULL, pMD, TRUE);
-#endif // FEATURE_APTCA
-
- // Fetch link demand sets from all the places in metadata where we might
- // find them (class and method). These might be split into CAS and non-CAS
- // sets as well.
- SecurityDeclarative::RetrieveLinktimeDemands(pMD,
- &gc.refClassCasDemands,
- &gc.refClassNonCasDemands,
- &gc.refMethodCasDemands,
- &gc.refMethodNonCasDemands);
-
- // Check CAS link demands.
- bool fGotGrantSet = false;
- if (gc.refClassCasDemands != NULL || gc.refMethodCasDemands != NULL)
- {
- // Get grant (and possibly denied) sets from the app
- // domain.
- gc.refGrant = pSecDesc->GetGrantedPermissionSet(NULL);
- fGotGrantSet = true;
- gc.refAssembly = pMD->GetAssembly()->GetExposedObject();
-
- if (gc.refClassCasDemands != NULL)
- SecurityStackWalk::CheckSetHelper(&gc.refClassCasDemands,
- &gc.refGrant,
- &gc.refRefused,
- pDomain,
- pMD,
- &gc.refAssembly,
- dclLinktimeCheck);
-
- if (gc.refMethodCasDemands != NULL)
- SecurityStackWalk::CheckSetHelper(&gc.refMethodCasDemands,
- &gc.refGrant,
- &gc.refRefused,
- pDomain,
- pMD,
- &gc.refAssembly,
- dclLinktimeCheck);
-
- }
-
- // Non-CAS demands are not applied against a grant
- // set, they're standalone.
- if (gc.refClassNonCasDemands != NULL)
- CheckNonCasDemand(&gc.refClassNonCasDemands);
-
- if (gc.refMethodNonCasDemands != NULL)
- CheckNonCasDemand(&gc.refMethodNonCasDemands);
-
-#ifndef FEATURE_CORECLR
- // On CORECLR, we do this from the JIT callouts if the caller is transparent: if caller is critical, no checks needed
-
- // We perform automatic linktime checks for UnmanagedCode in three cases:
- // o P/Invoke calls (shouldn't get these here, but let's be paranoid).
- // o Calls through an interface that have a suppress runtime check
- // attribute on them (these are almost certainly interop calls).
- // o Interop calls made through method impls.
- // Just walk the stack in these cases, they'll be extremely rare and the
- // perf delta isn't that huge.
- if (pMD->IsNDirect() ||
- (pMD->IsInterface() &&
- (pMD->GetMDImport()->GetCustomAttributeByName(pMD->GetMethodTable()->GetCl(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK ||
- pMD->GetMDImport()->GetCustomAttributeByName(pMD->GetMemberDef(),
- COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE_ANSI,
- NULL,
- NULL) == S_OK) ) ||
- (pMD->IsComPlusCall() && !pMD->IsInterface()))
- SecurityStackWalk::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_UNMANAGED_CODE);
-#endif // FEATURE_CORECLR
-
- GCPROTECT_END();
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-//-----------------------------------------------------------------------------
-//
-//
-// CODE FOR PERFORMING RUN-TIME CHECKS
-//
-//
-//-----------------------------------------------------------------------------
-
-void SecurityDeclarative::EnsureAssertAllowed(MethodDesc *pMeth, MethodSecurityDescriptor *pMSD)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- PRECONDITION(CheckPointer(pMeth));
- PRECONDITION(pMSD == NULL || pMSD->GetMethod() == pMeth);
- } CONTRACTL_END;
-
- // Check if this Assembly has permission to assert
- if (pMSD == NULL || !pMSD->CanAssert()) // early out if we have an MSD and we already have checked this permission
- {
- Module* pModule = pMeth->GetModule();
- PREFIX_ASSUME_MSG(pModule != NULL, "Should be a Module pointer here");
-
- if (!Security::CanAssert(pModule))
- SecurityPolicy::ThrowSecurityException(g_SecurityPermissionClassName, SPFLAGSASSERTION);
- }
-
- // Check if the Method is allowed to assert based on transparent/critical classification
- if (!SecurityTransparent::IsAllowedToAssert(pMeth) && Security::IsTransparencyEnforcementEnabled())
- {
-#ifdef _DEBUG
- if (g_pConfig->LogTransparencyErrors())
- {
- SecurityTransparent::LogTransparencyError(pMeth, "Transparent method using a security assert");
- }
-#endif // _DEBUG
- // if assembly is transparent fail the ASSERT operations
- COMPlusThrow(kInvalidOperationException, W("InvalidOperation_AssertTransparentCode"));
- }
-
- return;
-}
-
-void SecurityDeclarative::InvokeDeclarativeActions (MethodDesc *pMeth, DeclActionInfo *pActions, MethodSecurityDescriptor *pMSD)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- OBJECTREF refPermSet = NULL;
- ARG_SLOT arg = 0;
-
- // If we get a real PermissionSet, then invoke the action.
- switch (pActions->dwDeclAction)
- {
- case DECLSEC_DEMANDS:
- SecurityStackWalk::DemandSet(SSWT_DECLARATIVE_DEMAND, pActions->pPCE, dclDemand);
- break;
-
- case DECLSEC_ASSERTIONS:
- EnsureAssertAllowed(pMeth, pMSD);
- GetThread()->IncrementAssertCount();
- break;
-
- case DECLSEC_DENIALS:
- case DECLSEC_PERMITONLY:
- GetThread()->IncrementOverridesCount();
- break;
-
- case DECLSEC_NONCAS_DEMANDS:
- refPermSet = pActions->pPCE->CreateManagedPsetObject (dclNonCasDemand);
- if (refPermSet == NULL)
- break;
- if(!((PERMISSIONSETREF)refPermSet)->CheckedForNonCas() ||((PERMISSIONSETREF)refPermSet)->ContainsNonCas())
- {
- GCPROTECT_BEGIN(refPermSet);
- MethodDescCallSite demand(METHOD__PERMISSION_SET__DEMAND_NON_CAS, &refPermSet);
-
- arg = ObjToArgSlot(refPermSet);
- demand.Call(&arg);
- GCPROTECT_END();
- }
- break;
-
- default:
- _ASSERTE(!"Unknown action requested in InvokeDeclarativeActions");
- break;
-
- } // switch
-}
-
-
-//
-// CODE FOR PERFORMING RUN-TIME CHECKS
-//
-extern LPVOID GetSecurityObjectForFrameInternal(StackCrawlMark *stackMark, INT32 create, OBJECTREF *pRefSecDesc);
-
-namespace
-{
- inline void UpdateFrameSecurityObj(DWORD dwAction, OBJECTREF *refPermSet, OBJECTREF * pSecObj)
- {
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- GetSecurityObjectForFrameInternal(NULL, true, pSecObj);
-
- FRAMESECDESCREF fsdRef = (FRAMESECDESCREF)*pSecObj;
- switch (dwAction)
- {
- // currently we require declarative security to store the data in both the fields in the FSD
- case dclAssert:
- fsdRef->SetDeclarativeAssertions(*refPermSet);
- {
- PERMISSIONSETREF psRef = (PERMISSIONSETREF)*refPermSet;
- if (psRef != NULL && psRef->IsUnrestricted())
- fsdRef->SetAssertFT(TRUE);
- }
- break;
-
- case dclDeny:
- fsdRef->SetDeclarativeDenials(*refPermSet);
- break;
-
- case dclPermitOnly:
- fsdRef->SetDeclarativeRestrictions(*refPermSet);
- break;
-
- default:
- _ASSERTE(0 && "Unreached, add code to handle if reached here...");
- break;
- }
- }
-}
-
-void SecurityDeclarative::InvokeDeclarativeStackModifiers(MethodDesc * pMeth, DeclActionInfo * pActions, OBJECTREF * pSecObj)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- OBJECTREF refPermSet = NULL;
-
- // If we get a real PermissionSet, then invoke the action.
- switch (pActions->dwDeclAction)
- {
- case DECLSEC_DEMANDS:
- case DECLSEC_NONCAS_DEMANDS:
- // Nothing to do for demands
- break;
-
- case DECLSEC_ASSERTIONS:
- refPermSet = pActions->pPCE->CreateManagedPsetObject (dclAssert);
- if (refPermSet == NULL)
- break;
- GCPROTECT_BEGIN(refPermSet);
- // Now update the frame security object
- UpdateFrameSecurityObj(dclAssert, &refPermSet, pSecObj);
- GCPROTECT_END();
- break;
-
- case DECLSEC_DENIALS:
- // Update the frame security object
- refPermSet = pActions->pPCE->CreateManagedPsetObject (dclDeny);
-
- if (refPermSet == NULL)
- break;
-
- GCPROTECT_BEGIN(refPermSet);
-
-#ifdef FEATURE_CAS_POLICY
- // Deny is only valid if we're in legacy CAS mode
- IApplicationSecurityDescriptor *pSecDesc = GetAppDomain()->GetSecurityDescriptor();
- if (!pSecDesc->IsLegacyCasPolicyEnabled())
- {
- COMPlusThrow(kNotSupportedException, W("NotSupported_CasDeny"));
- }
-#endif // FEATURE_CAS_POLICY
-
- UpdateFrameSecurityObj(dclDeny, &refPermSet, pSecObj);
-
- GCPROTECT_END();
- break;
-
- case DECLSEC_PERMITONLY:
- // Update the frame security object
- refPermSet = pActions->pPCE->CreateManagedPsetObject (dclPermitOnly);
-
- if (refPermSet == NULL)
- break;
- GCPROTECT_BEGIN(refPermSet);
- UpdateFrameSecurityObj(dclPermitOnly, &refPermSet, pSecObj);
- GCPROTECT_END();
- break;
-
-
- default:
- _ASSERTE(!"Unknown action requested in InvokeDeclarativeStackModifiers");
- break;
-
- } // switch
-}
-
-void SecurityDeclarative::DoDeclarativeActions(MethodDesc *pMeth, DeclActionInfo *pActions, LPVOID pSecObj, MethodSecurityDescriptor *pMSD)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
-#ifndef FEATURE_CAS_POLICY
- // In the CoreCLR, we don't support CAS actions outside mscorlib.
- // However, we do have to expose certain types in mscorlib due to compiler requirements
- // (c# compiler requires us to expose SecurityPermission/SecurityAction etc so that it can
- // insert a RequestMinimum for SkipVerification).
- // This means that code outside mscorlib could construct IL that has declarative security
- // in it. This is not a security issue - even if they try to create IL that asserts for
- // permissions they don't have, it's not going to work for the same reasons it didn't in the desktop.
- // However, we could have bugs like DDB 120109 where they can cause Demands to fail etc.
- // So for goodness, we're not going to do any runtime declarative work on assemblies other than mscorlib.
- if (!pMeth->GetModule()->IsSystem())
- {
- // Non-mscorlib code reached... exit
- return;
- }
-#endif //!FEATURE_CAS_POLICY
-
-
- // --------------------------------------------------------------------------- //
- // D E C L A R A T I V E S E C U R I T Y D E M A N D S //
- // --------------------------------------------------------------------------- //
- // The frame is now fully formed, arguments have been copied into place,
- // and synchronization monitors have been entered if necessary. At this
- // point, we are prepared for something to throw an exception, so we may
- // check for declarative security demands and execute them. We need a
- // well-formed frame and synchronization domain to accept security excep-
- // tions thrown by the SecurityManager. We MAY need argument values in
- // the frame so that the arguments may be finalized if security throws an
- // exception across them (unknown).
- if (pActions != NULL && pActions->dwDeclAction == DECLSEC_UNMNGD_ACCESS_DEMAND &&
- pActions->pNext == NULL)
- {
- /* We special-case the security check on single pinvoke/interop calls
- so we can avoid setting up the GCFrame */
-
- SecurityStackWalk::SpecialDemand(SSWT_DECLARATIVE_DEMAND, SECURITY_UNMANAGED_CODE);
- return;
- }
- else
- {
-#ifdef FEATURE_COMPRESSEDSTACK
- // If this is an anonymously hosted dynamic method, there aren't any direct modifiers, but if it has a compressed stack that
- // might have modifiers, mark that there are modifiers so we make sure to do a stack walk
- if(SecurityStackWalk::MethodIsAnonymouslyHostedDynamicMethodWithCSToEvaluate(pMeth))
- {
- // We don't know how many asserts or overrides might be in the compressed stack,
- // but we just need to increment the counters to ensure optimizations don't skip CS evaluation
- GetThread()->IncrementAssertCount();
- GetThread()->IncrementOverridesCount();
- }
-#endif // FEATURE_COMPRESSEDSTACK
-
- for (/**/; pActions; pActions = pActions->pNext)
- {
- if (pActions->dwDeclAction == DECLSEC_UNMNGD_ACCESS_DEMAND)
- {
- SecurityStackWalk::SpecialDemand(SSWT_DECLARATIVE_DEMAND, SECURITY_UNMANAGED_CODE);
- }
- else
- {
- InvokeDeclarativeActions(pMeth, pActions, pMSD);
- }
- }
-
- }
-}
-void SecurityDeclarative::DoDeclarativeStackModifiers(MethodDesc *pMeth, AppDomain* pAppDomain, LPVOID pSecObj)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
-#ifndef FEATURE_CAS_POLICY
- // In the CoreCLR, we don't support CAS actions outside mscorlib.
- // However, we do have to expose certain types in mscorlib due to compiler requirements
- // (c# compiler requires us to expose SecurityPermission/SecurityAction etc so that it can
- // insert a RequestMinimum for SkipVerification).
- // This means that code outside mscorlib could construct IL that has declarative security
- // in it. This is not a security issue - even if they try to create IL that asserts for
- // permissions they don't have, it's not going to work for the same reasons it didn't in the desktop.
- // However, we could have bugs like DDB 120109 where they can cause Demands to fail etc.
- // So for goodness, we're not going to do any runtime declarative work on assemblies other than mscorlib.
- if (!pMeth->GetModule()->IsSystem())
- {
- // Non-mscorlib code reached... exit
- return;
- }
-#endif //!FEATURE_CAS_POLICY
-
-
- AppDomain* pCurrentDomain = GetAppDomain();
-
- if (pCurrentDomain != pAppDomain)
- {
- ENTER_DOMAIN_PTR(pAppDomain, ADV_RUNNINGIN)
- {
- DoDeclarativeStackModifiersInternal(pMeth, pSecObj);
- }
- END_DOMAIN_TRANSITION;
- }
- else
- {
- DoDeclarativeStackModifiersInternal(pMeth, pSecObj);
- }
- }
-
-void SecurityDeclarative::DoDeclarativeStackModifiersInternal(MethodDesc *pMeth, LPVOID pSecObj)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- Object** ppSecObject = (Object**) pSecObj;
- _ASSERTE(pMeth->IsInterceptedForDeclSecurity() && !pMeth->IsInterceptedForDeclSecurityCASDemandsOnly());
-
- MethodSecurityDescriptor MDSecDesc(pMeth);
- MethodSecurityDescriptor::LookupOrCreateMethodSecurityDescriptor(&MDSecDesc);
- DeclActionInfo* pActions = MDSecDesc.GetRuntimeDeclActionInfo();
-
- OBJECTREF fsdRef = ObjectToOBJECTREF(*ppSecObject);
- GCPROTECT_BEGIN(fsdRef);
-
- for (/**/; pActions; pActions = pActions->pNext)
- {
- InvokeDeclarativeStackModifiers(pMeth, pActions, &fsdRef);
- }
- // If we had just NON-CAS demands, we'd come here but not create an FSD.
- if (fsdRef != NULL)
- {
- ((FRAMESECDESCREF)(fsdRef))->SetDeclSecComputed(TRUE);
-
- if (*ppSecObject == NULL)
- {
- // we came in with a NULL FSD and the FSD got created here...so we need to copy it back
- // If we had come in with a non-NULL FSD, that would have been updated and this (shallow/pointer) copy
- // would not be necessary
- *ppSecObject = OBJECTREFToObject(fsdRef);
- }
-}
-
- GCPROTECT_END();
-}
-
-
-void SecurityDeclarative::CheckNonCasDemand(OBJECTREF *prefDemand)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(IsProtectedByGCFrame (prefDemand));
- } CONTRACTL_END;
-
- if(((PERMISSIONSETREF)*prefDemand)->CheckedForNonCas())
- {
- if(!((PERMISSIONSETREF)*prefDemand)->ContainsNonCas())
- return;
- }
- MethodDescCallSite demand(METHOD__PERMISSION_SET__DEMAND_NON_CAS, prefDemand);
- ARG_SLOT arg = ObjToArgSlot(*prefDemand);
- demand.Call(&arg);
-}
-
-#endif // FEATURE_CAS_POLICY
#endif // CROSSGEN_COMPILE
diff --git a/src/vm/securitydeclarative.h b/src/vm/securitydeclarative.h
index 151d094e97..9874148326 100644
--- a/src/vm/securitydeclarative.h
+++ b/src/vm/securitydeclarative.h
@@ -126,20 +126,6 @@ namespace SecurityDeclarative
inline BOOL FullTrustCheckForLinkOrInheritanceDemand(Assembly *pAssembly);
-#ifdef FEATURE_APTCA
- // Returns TRUE if an APTCA check is necessary
- // Callers:
- // CanAccess
- BOOL IsUntrustedCallerCheckNeeded(MethodDesc *pCalleeMD, Assembly *pCallerAssem = NULL);
-
- // Perform the APTCA check
- // Callers:
- // CanAccess
- // Security::CheckLinkDemandAgainstAppDomain
- void DoUntrustedCallerChecks(
- Assembly *pCaller, MethodDesc *pCalee,
- BOOL fFullStackWalk);
-#endif // FEATURE_APTCA
#ifndef DACCESS_COMPILE
// Calls PermissionSet.Demand
@@ -166,15 +152,6 @@ namespace SecurityDeclarative
inline BOOL ClassIsVisibleOutsideItsAssembly(DWORD dwClassAttr, BOOL fIsGlobalClass);
-#ifdef FEATURE_APTCA
- // Returns an instance of a SecurityException with the message "This method doesn't allow partially trusted callers"
- // Callers:
- // DoUntrustedCallerChecks
- void DECLSPEC_NORETURN ThrowAPTCAException(Assembly *pCaller, MethodDesc *pCallee);
-#endif // FEATURE_APTCA
-#ifdef FEATURE_CAS_POLICY
- void DECLSPEC_NORETURN ThrowHPException(EApiCategories protectedCategories, EApiCategories demandedCategories);
-#endif // FEATURE_CAS_POLICY
// Add a declarative action and PermissionSet index to the linked list
void AddDeclAction(CorDeclSecurity action, PsetCacheEntry *pClassPCE, PsetCacheEntry *pMethodPCE, DeclActionInfo** ppActionList, MethodDesc *pMeth);
diff --git a/src/vm/securitydeclarativecache.cpp b/src/vm/securitydeclarativecache.cpp
index dcfc1e0c4d..202c016459 100644
--- a/src/vm/securitydeclarativecache.cpp
+++ b/src/vm/securitydeclarativecache.cpp
@@ -75,65 +75,7 @@ OBJECTREF PsetCacheEntry::CreateManagedPsetObject(DWORD dwAction, bool createEmp
MODE_COOPERATIVE;
} CONTRACTL_END;
-#ifdef FEATURE_CAS_POLICY
- OBJECTREF orRet;
-
- orRet = GetManagedPsetObject();
- if (orRet != NULL) {
- return orRet;
- }
-
- if (!createEmptySet && m_fEmptyPermissionSet) {
- return NULL;
- }
-
- struct _gc {
- OBJECTREF pset;
- OBJECTREF encoding;
- OBJECTREF nonCasPset;
- OBJECTREF orNonCasPset;
- OBJECTREF orNonCasEncoding;
- } gc;
- memset(&gc, 0, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- if ( (m_pKey->m_cbPset > 0) && (m_pKey->m_pbPset[0] == LAZY_DECL_SEC_FLAG) ) {
-
- SecurityAttributes::AttrSetBlobToPermissionSets(m_pKey->m_pbPset,
- m_pKey->m_cbPset,
- &gc.pset,
- dwAction);
-
- } else {
-
- SecurityAttributes::XmlToPermissionSet(m_pKey->m_pbPset,
- m_pKey->m_cbPset,
- &gc.pset,
- &gc.encoding,
- NULL,
- 0,
- &gc.orNonCasPset,
- &gc.orNonCasEncoding);
- }
-
- StoreFirstObjectInHandle(m_handle, gc.pset);
-
- if (gc.pset == NULL)
- m_fEmptyPermissionSet = true;
-
- GCPROTECT_END();
-
- //
- // Some other thread may have won the race, and stored away a different
- // object in the handle.
- //
-
- orRet = GetManagedPsetObject();
- return orRet;
-#else
return NULL;
-#endif
}
#endif // CROSSGEN_COMPILE
diff --git a/src/vm/securitydescriptor.cpp b/src/vm/securitydescriptor.cpp
index a14095a981..2ff1823bb5 100644
--- a/src/vm/securitydescriptor.cpp
+++ b/src/vm/securitydescriptor.cpp
@@ -56,65 +56,9 @@ OBJECTREF SecurityDescriptor::GetGrantedPermissionSet(OBJECTREF* pRefusedPermiss
//
// Returns TRUE if the given zone has the given special permission.
//
-#ifdef FEATURE_CAS_POLICY
-BOOL SecurityDescriptor::CheckQuickCache(SecurityConfig::QuickCacheEntryType all, DWORD dwZone)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled());
- PRECONDITION(SecurityPolicy::s_fPolicyInitialized);
- } CONTRACTL_END;
-
- static const SecurityConfig::QuickCacheEntryType zoneTable[] =
- {
- SecurityConfig::FullTrustZoneMyComputer,
- SecurityConfig::FullTrustZoneIntranet,
- SecurityConfig::FullTrustZoneTrusted,
- SecurityConfig::FullTrustZoneInternet,
- SecurityConfig::FullTrustZoneUntrusted
- };
-
- // If an additional evidence was provided, then perform the normal
- // policy resolution. This is true for all AppDomains and also for
- // assemblies loaded with a specific additional evidence. Note that
- // for the default AppDomain, the policy resolution code paths short
- // circuits the parsing of the security XML files by granting FullTrust
- // to the default AppDomain.
-
- if (m_hAdditionalEvidence != NULL)
- return FALSE;
-
- BOOL fMachine = SecurityConfig::GetQuickCacheEntry(SecurityConfig::MachinePolicyLevel, all);
- BOOL fUser = SecurityConfig::GetQuickCacheEntry(SecurityConfig::UserPolicyLevel, all);
- BOOL fEnterprise = SecurityConfig::GetQuickCacheEntry(SecurityConfig::EnterprisePolicyLevel, all);
-
- if (fMachine && fUser && fEnterprise)
- return TRUE;
-
- // If we can't match for all, try for our zone.
- if (dwZone == 0xFFFFFFFF)
- return FALSE;
-
- fMachine = SecurityConfig::GetQuickCacheEntry(SecurityConfig::MachinePolicyLevel, zoneTable[dwZone]);
- fUser = SecurityConfig::GetQuickCacheEntry(SecurityConfig::UserPolicyLevel, zoneTable[dwZone]);
- fEnterprise = SecurityConfig::GetQuickCacheEntry(SecurityConfig::EnterprisePolicyLevel, zoneTable[dwZone]);
-
- return (fMachine && fUser && fEnterprise);
-}
-#endif // FEATURE_CAS_POLICY
#endif // DACCESS_COMPILE
-#ifdef FEATURE_CAS_POLICY
-BOOL SecurityDescriptor::IsEvidenceComputed() const
-{
- LIMITED_METHOD_CONTRACT;
- return m_fEvidenceComputed;
-}
-#endif //FEATURE_CAS_POLICY
//
// This method will return TRUE if this object is fully trusted.
@@ -179,25 +123,6 @@ void SecurityDescriptor::SetGrantedPermissionSet(OBJECTREF GrantedPermissionSet,
}
-#ifdef FEATURE_CAS_POLICY
-void SecurityDescriptor::SetEvidence(OBJECTREF evidence)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(evidence != NULL);
- }
- CONTRACTL_END;
-
- if (evidence != NULL)
- {
- StoreObjectInLazyHandle(m_hAdditionalEvidence, evidence, m_pLoaderAllocator);
- SetEvidenceComputed();
- }
-}
-#endif // FEATURE_CAS_POLICY
#endif // !DACCESS_COMPILE
AppDomain* SecurityDescriptor::GetDomain() const
@@ -208,219 +133,6 @@ AppDomain* SecurityDescriptor::GetDomain() const
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_CAS_POLICY
-
-//---------------------------------------------------------------------------------------
-//
-// Build an evidence collection which can generate evidence about a PEFile
-//
-// Arguments:
-// pPEFile - PEFile the evidence collection will generate evidence for
-// objHostSuppliedEvidence - additional evidence to merge into the collection supplied by the host
-//
-// Return Value:
-// Evidence collection which targets this PEFile
-//
-// Notes:
-// Calls System.Security.Policy.PEFileEvidenceFactory.CreateSecurityIdentity
-//
-
-// static
-OBJECTREF PEFileSecurityDescriptor::BuildEvidence(PEFile *pPEFile, const OBJECTREF& objHostSuppliedEvidence)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pPEFile));
- }
- CONTRACTL_END;
-
- struct
- {
- SAFEHANDLE objPEFile;
- OBJECTREF objHostSuppliedEvidence;
- OBJECTREF objEvidence;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- BEGIN_SO_INTOLERANT_CODE(GetThread());
-
- gc.objPEFile = pPEFile->GetSafeHandle();
- gc.objHostSuppliedEvidence = objHostSuppliedEvidence;
-
- MethodDescCallSite createSecurityIdentity(METHOD__PEFILE_EVIDENCE_FACTORY__CREATE_SECURITY_IDENTITY);
-
- ARG_SLOT args[] =
- {
- ObjToArgSlot(gc.objPEFile),
- ObjToArgSlot(gc.objHostSuppliedEvidence)
- };
-
- gc.objEvidence = createSecurityIdentity.Call_RetOBJECTREF(args);
-
- END_SO_INTOLERANT_CODE;
- GCPROTECT_END();
-
- return gc.objEvidence;
-}
-
-#endif // FEATURE_CAS_POLICY
-
-#ifndef FEATURE_CORECLR
-BOOL PEFileSecurityDescriptor::QuickIsFullyTrusted()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
-#ifdef CROSSGEN_COMPILE
- return TRUE;
-#else
- if (!m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled())
- {
- return TRUE;
- }
- else if (m_pAppDomain->IsCompilationDomain())
- {
- return TRUE;
- }
- else
- {
- return CheckQuickCache(SecurityConfig::FullTrustAll, GetZone());
- }
-#endif
-}
-
-#ifndef CROSSGEN_COMPILE
-//---------------------------------------------------------------------------------------
-//
-// Get the evidence for this PE file
-//
-
-OBJECTREF PEFileSecurityDescriptor::GetEvidence()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(m_pAppDomain == GetAppDomain());
- INJECT_FAULT(COMPlusThrowOM());
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- // If we already have evidence, then just return that
- if (IsEvidenceComputed())
- return ObjectFromLazyHandle(m_hAdditionalEvidence, m_pLoaderAllocator);
-
- struct
- {
- OBJECTREF objHostProvidedEvidence;
- OBJECTREF objEvidence;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- BEGIN_SO_INTOLERANT_CODE(GetThread());
-
-#if CHECK_APP_DOMAIN_LEAKS
- if (g_pConfig->AppDomainLeaks())
- _ASSERTE(gc.objHostProvidedEvidence == NULL || GetAppDomain() == gc.objHostProvidedEvidence->GetAppDomain());
-#endif // CHECK_APP_DOMAIN_LEAKS
-
- gc.objHostProvidedEvidence = ObjectFromLazyHandle(m_hAdditionalEvidence, m_pLoaderAllocator);
- gc.objEvidence = PEFileSecurityDescriptor::BuildEvidence(m_pPEFile, gc.objHostProvidedEvidence);
- SetEvidence(gc.objEvidence);
-
-#if CHECK_APP_DOMAIN_LEAKS
- if (g_pConfig->AppDomainLeaks())
- _ASSERTE(gc.objEvidence == NULL || GetAppDomain() == gc.objEvidence->GetAppDomain());
-#endif // CHECK_APP_DOMAIN_LEAKS
-
- END_SO_INTOLERANT_CODE;
-
- GCPROTECT_END();
-
- return gc.objEvidence;
-}
-
-DWORD PEFileSecurityDescriptor::GetZone()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- PRECONDITION(m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled());
- }
- CONTRACTL_END;
-
- SecZone dwZone = NoZone;
- BEGIN_SO_INTOLERANT_CODE(GetThread());
-
- StackSString codebase;
- BYTE rbUniqueID[MAX_SIZE_SECURITY_ID];
- DWORD cbUniqueID = sizeof(rbUniqueID);
-
- m_pPEFile->GetSecurityIdentity(codebase, &dwZone, 0, rbUniqueID, &cbUniqueID);
- END_SO_INTOLERANT_CODE;
- return dwZone;
-}
-#endif // !CROSSGEN_COMPILE
-
-void PEFileSecurityDescriptor::Resolve()
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- if (IsResolved())
- return;
- ResolveWorker();
-}
-
-void PEFileSecurityDescriptor::ResolveWorker()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- SetGrantedPermissionSet(NULL, NULL, 0xFFFFFFFF);
-}
-
-BOOL PEFileSecurityDescriptor::AllowBindingRedirects()
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(IsResolved());
- } CONTRACTL_END;
-
- ETWOnStartup (AllowBindingRedirs_V1, AllowBindingRedirsEnd_V1);
-
- return CheckSpecialFlag(1 << SECURITY_BINDING_REDIRECTS);
-}
-#endif // FEATURE_CORECLR
#endif // !DACCESS_COMPILE
diff --git a/src/vm/securitydescriptor.h b/src/vm/securitydescriptor.h
index 06c096f4ee..eb1c287b4b 100644
--- a/src/vm/securitydescriptor.h
+++ b/src/vm/securitydescriptor.h
@@ -9,7 +9,6 @@
#ifndef __SECURITYDESCRIPTOR_H__
#define __SECURITYDESCRIPTOR_H__
-#include "securityconfig.h"
#include "securityattributes.h"
#include "securitypolicy.h"
@@ -68,9 +67,6 @@ inline void StoreObjectInLazyHandle(LOADERHANDLE& handle, OBJECTREF ref, LoaderA
class SecurityDescriptor
{
protected:
-#ifdef FEATURE_CAS_POLICY
- LOADERHANDLE m_hAdditionalEvidence; // Evidence Object
-#endif // FEATURE_CAS_POLICY
// The unmanaged DomainAssembly object
DomainAssembly *m_pAssem;
@@ -82,9 +78,6 @@ protected:
AppDomain* m_pAppDomain;
BOOL m_fSDResolved;
-#ifdef FEATURE_CAS_POLICY
- BOOL m_fEvidenceComputed;
-#endif // FEATURE_CAS_POLICY
DWORD m_dwSpecialFlags;
LoaderAllocator *m_pLoaderAllocator;
@@ -102,15 +95,6 @@ public:
AppDomain* GetDomain() const;
BOOL CanCallUnmanagedCode() const;
-#ifdef FEATURE_CAS_POLICY
-
-#ifndef DACCESS_COMPILE
- void SetEvidence(OBJECTREF evidence);
- BOOL CheckQuickCache(SecurityConfig::QuickCacheEntryType all, DWORD dwZone);
-#endif // FEATURE_CAS_POLICY
- BOOL IsEvidenceComputed() const;
- inline void SetEvidenceComputed();
-#endif // FEATURE_CAS_POLICY
#ifndef DACCESS_COMPILE
void SetGrantedPermissionSet(OBJECTREF GrantedPermissionSet,
@@ -156,44 +140,12 @@ public:
virtual BOOL IsResolved() const { return SecurityDescriptor::IsResolved(); }
-#ifdef FEATURE_CAS_POLICY
- virtual BOOL IsEvidenceComputed() const { return SecurityDescriptor::IsEvidenceComputed(); }
-#ifndef DACCESS_COMPILE
- virtual void SetEvidence(OBJECTREF evidence) { SecurityDescriptor::SetEvidence(evidence); }
-#endif // DACCESS_COMPILE
-#endif // FEATURE_CAS_POLICY
#ifndef DACCESS_COMPILE
virtual OBJECTREF GetGrantedPermissionSet(OBJECTREF* RefusedPermissions = NULL) { return SecurityDescriptor::GetGrantedPermissionSet(RefusedPermissions); }
#endif
};
-#ifndef FEATURE_CORECLR
-class PEFileSecurityDescriptor : public SecurityDescriptorBase<IPEFileSecurityDescriptor>
-{
-public:
- virtual BOOL AllowBindingRedirects();
- BOOL QuickIsFullyTrusted();
- virtual VOID Resolve();
-
-#ifndef DACCESS_COMPILE
- inline PEFileSecurityDescriptor(AppDomain* pDomain, PEFile *pPEFile);
-#endif
-
-#ifdef FEATURE_CAS_POLICY
- virtual OBJECTREF GetEvidence();
- DWORD GetZone();
-#endif // FEATURE_CAS_POLICY
-
-
-#ifdef FEATURE_CAS_POLICY
- static
- OBJECTREF BuildEvidence(PEFile *pPEFile, const OBJECTREF& objHostSuppliedEvidence);
-#endif // FEATURE_CAS_POLICY
-private:
- VOID ResolveWorker();
-};
-#endif // !FEATURE_CORECLR
#include "securitydescriptor.inl"
diff --git a/src/vm/securitydescriptor.inl b/src/vm/securitydescriptor.inl
index 8d571f9fa1..f894831db6 100644
--- a/src/vm/securitydescriptor.inl
+++ b/src/vm/securitydescriptor.inl
@@ -38,16 +38,10 @@ inline SecurityDescriptor::SecurityDescriptor(AppDomain *pAppDomain,
DomainAssembly *pAssembly,
PEFile* pPEFile,
LoaderAllocator *pLoaderAllocator) :
-#ifdef FEATURE_CAS_POLICY
- m_hAdditionalEvidence(NULL),
-#endif // FEATURE_CAS_POLICY
m_pAssem(pAssembly),
m_pPEFile(pPEFile),
m_pAppDomain(pAppDomain),
m_fSDResolved(FALSE),
-#ifdef FEATURE_CAS_POLICY
- m_fEvidenceComputed(FALSE),
-#endif // FEATURE_CAS_POLICY
m_dwSpecialFlags(0),
m_pLoaderAllocator(pLoaderAllocator)
#ifndef CROSSGEN_COMPILE
@@ -59,14 +53,6 @@ inline SecurityDescriptor::SecurityDescriptor(AppDomain *pAppDomain,
}
#endif // !DACCESS_COMPILE
-#ifdef FEATURE_CAS_POLICY
-inline void SecurityDescriptor::SetEvidenceComputed()
-{
- LIMITED_METHOD_CONTRACT;
- m_fEvidenceComputed = TRUE;
-}
-
-#endif // FEATURE_CAS_POLICY
// Checks for one of the special security flags such as FullTrust or UnmanagedCode
FORCEINLINE BOOL SecurityDescriptor::CheckSpecialFlag (DWORD flags) const
@@ -94,16 +80,5 @@ inline SecurityDescriptorBase<IT>::SecurityDescriptorBase(AppDomain *pAppDomain,
}
#endif // !DACCESS_COMPILE
-#ifndef FEATURE_CORECLR
-
-#ifndef DACCESS_COMPILE
-inline PEFileSecurityDescriptor::PEFileSecurityDescriptor(AppDomain* pDomain, PEFile *pPEFile) :
- SecurityDescriptorBase<IPEFileSecurityDescriptor>(pDomain, NULL,pPEFile, pDomain->GetLoaderAllocator())
-{
- LIMITED_METHOD_CONTRACT
-}
-#endif // !DACCESS_COMPILE
-
-#endif // !FEATURE_CORECLR
#endif // #define __SECURITYDESCRIPTOR_INL__
diff --git a/src/vm/securitydescriptorappdomain.cpp b/src/vm/securitydescriptorappdomain.cpp
index fecb6a5d3f..173b4c83e1 100644
--- a/src/vm/securitydescriptorappdomain.cpp
+++ b/src/vm/securitydescriptorappdomain.cpp
@@ -8,11 +8,7 @@
#include "common.h"
#include "security.h"
-#ifdef FEATURE_REMOTING
-#include "crossdomaincalls.h"
-#else
#include "callhelpers.h"
-#endif
#ifndef DACCESS_COMPILE
@@ -100,34 +96,6 @@ void ApplicationSecurityDescriptor::InitializePLS()
INJECT_FAULT(COMPlusThrowOM(););
} CONTRACTL_END;
-#ifdef FEATURE_PLS
- struct _gc {
- OBJECTREF refGrantedSet;
- OBJECTREF refDeniedSet;
- OBJECTREF refPermListSet;
- OBJECTREF refRetVal;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- if (!IsFullyTrusted()) {
- GCPROTECT_BEGIN(gc);
-
- gc.refPermListSet = ObjectFromLazyHandle(m_hDomainPermissionListSet, m_pLoaderAllocator);
- gc.refGrantedSet = GetGrantedPermissionSet(&gc.refDeniedSet);
-
- MethodDescCallSite updateAppDomainPLS(METHOD__SECURITY_ENGINE__UPDATE_APPDOMAIN_PLS);
- ARG_SLOT args[] = {
- ObjToArgSlot(gc.refPermListSet),
- ObjToArgSlot(gc.refGrantedSet),
- ObjToArgSlot(gc.refDeniedSet),
- };
- gc.refRetVal = updateAppDomainPLS.Call_RetOBJECTREF(args);
-
- GCPROTECT_END();
- }
-
- StoreObjectInLazyHandle(m_hDomainPermissionListSet, gc.refRetVal, m_pLoaderAllocator);
-#endif // FEATURE_PLS
m_dwDomainWideSpecialFlags = m_dwSpecialFlags;
}
@@ -150,53 +118,6 @@ void ApplicationSecurityDescriptor::AddNewSecDescToPLS(AssemblySecurityDescripto
//
if (!pNewSecDescriptor->IsFullyTrusted()) {
-#ifdef FEATURE_PLS
- struct _gc {
- OBJECTREF refGrantedSet;
- OBJECTREF refDeniedSet;
- OBJECTREF refPermListSet;
- OBJECTREF refRetVal;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.refGrantedSet = pNewSecDescriptor->GetGrantedPermissionSet(&gc.refDeniedSet);
- if (gc.refDeniedSet != NULL)
- m_fContainsAnyRefusedPermissions = TRUE;
-
- // Ensure that the handle is created so that the compare exchange below will work correctly
- if (m_hDomainPermissionListSet == NULL)
- {
- LOADERHANDLE tmpHandle = m_pLoaderAllocator->AllocateHandle(NULL);
-
- // Races where this fails should be sufficiently rare that leaking this handle
- // until LoaderAllocator destruction is acceptable.
- FastInterlockCompareExchangePointer(&m_hDomainPermissionListSet, tmpHandle, static_cast<LOADERHANDLE>(NULL));
- }
-
- // we have to synchronize the update to the PLS across concurring threads.
- // we don't care if another thread is checking the existing PLS while this
- // update is in progress as the loaded assembly won't be on the stack for such
- // a demand and so will not affect the result of the existing PLS optimization.
- do {
- gc.refPermListSet = ObjectFromLazyHandle(m_hDomainPermissionListSet, m_pLoaderAllocator);
-
- MethodDescCallSite updateAppDomainPLS(METHOD__SECURITY_ENGINE__UPDATE_APPDOMAIN_PLS);
- ARG_SLOT args[] = {
- ObjToArgSlot(gc.refPermListSet),
- ObjToArgSlot(gc.refGrantedSet),
- ObjToArgSlot(gc.refDeniedSet),
- };
- // This returns a new copy of the PermissionListSet
- gc.refRetVal = updateAppDomainPLS.Call_RetOBJECTREF(args);
- }
- // If some other thread beat us to the PLS object handle, just try updating the PLS again
- // This race should be rare enough that recomputing the PLS is acceptable.
- while (m_pLoaderAllocator->CompareExchangeValueInHandle(m_hDomainPermissionListSet, gc.refRetVal, gc.refPermListSet) != gc.refPermListSet);
-
- GCPROTECT_END();
-#endif // FEATURE_PLS
LONG dwNewDomainWideSpecialFlags = 0;
LONG dwOldDomainWideSpecialFlags = 0;
@@ -208,66 +129,6 @@ void ApplicationSecurityDescriptor::AddNewSecDescToPLS(AssemblySecurityDescripto
}
}
-#ifdef FEATURE_PLS
-BOOL ApplicationSecurityDescriptor::CheckPLS (OBJECTREF* orDemand, DWORD dwDemandSpecialFlags, BOOL fDemandSet)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- // Check if all assemblies so far have full trust.
- if (CheckDomainWideSpecialFlag(1 << SECURITY_FULL_TRUST))
- return TRUE;
-
- // Check if this is a one of the well-known permissions tracked in the special flags.
- if (CheckDomainWideSpecialFlag(dwDemandSpecialFlags))
- return TRUE;
-
- CLR_BOOL fResult = FALSE;
- //
- // only evaluate the PLS if we don't need to marshal the demand across AppDomains
- // This means we would perform a stack walk when there are multiple semi-trust
- // AppDomains on the stack, which is acceptable.
- // In homogeneous cases, the stack walk could potentially detect the situation
- // and avoid the expensive walk of the assemblies if the permission demand is a
- // subset of the homogeneous grant set applied to the AppDomain.
- //
- if (m_pAppDomain == GetThread()->GetDomain()) {
- OBJECTREF refDomainPLS = NULL;
-
- GCPROTECT_BEGIN(refDomainPLS);
- refDomainPLS = ObjectFromLazyHandle(m_hDomainPermissionListSet, m_pLoaderAllocator);
-
- EX_TRY
- {
- if (fDemandSet) {
- PREPARE_NONVIRTUAL_CALLSITE(METHOD__PERMISSION_LIST_SET__CHECK_SET_DEMAND_NO_THROW);
- DECLARE_ARGHOLDER_ARRAY(args, 2);
- args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(refDomainPLS); // arg 0
- args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(*orDemand); // arg 1
- CATCH_HANDLER_FOUND_NOTIFICATION_CALLSITE;
- CALL_MANAGED_METHOD(fResult, CLR_BOOL, args);
- }
- else {
- PREPARE_NONVIRTUAL_CALLSITE(METHOD__PERMISSION_LIST_SET__CHECK_DEMAND_NO_THROW);
- DECLARE_ARGHOLDER_ARRAY(args, 2);
- args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(refDomainPLS); // arg 0
- args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(*orDemand); // arg 1
- CATCH_HANDLER_FOUND_NOTIFICATION_CALLSITE;
- CALL_MANAGED_METHOD(fResult, CLR_BOOL, args);
- }
- }
- EX_SWALLOW_NONTRANSIENT;
-
- GCPROTECT_END();
- }
-
- return fResult;
-}
-#endif // FEATURE_PLS
DWORD ApplicationSecurityDescriptor::GetDomainWideSpecialFlag() const
{
@@ -321,9 +182,6 @@ BOOL ApplicationSecurityDescriptor::IsDefaultAppDomain() const
{
LIMITED_METHOD_CONTRACT;
return m_fIsDefaultAppdomain
-#ifndef FEATURE_CORECLR
- && !m_fHomogeneous
-#endif // FEATURE_CORECLR
;
}
@@ -355,19 +213,6 @@ BOOL ApplicationSecurityDescriptor::DomainMayContainPartialTrustCode()
return !m_fHomogeneous || !IsFullyTrusted();
}
-#ifdef FEATURE_APTCA
-ConditionalAptcaCache *ApplicationSecurityDescriptor::GetConditionalAptcaCache()
-{
- LIMITED_METHOD_CONTRACT;
- return m_pConditionalAptcaCache;
-}
-
-void ApplicationSecurityDescriptor::SetCanonicalConditionalAptcaList(LPCWSTR wszCanonicalConditionalAptcaList)
-{
- WRAPPER_NO_CONTRACT;
- return this->GetConditionalAptcaCache()->SetCanonicalConditionalAptcaList(wszCanonicalConditionalAptcaList);
-}
-#endif // FEATURE_APTCA
#endif // !DACCESS_COMPILE
diff --git a/src/vm/securitydescriptorappdomain.h b/src/vm/securitydescriptorappdomain.h
index ff5bbda616..3e75c4f881 100644
--- a/src/vm/securitydescriptorappdomain.h
+++ b/src/vm/securitydescriptorappdomain.h
@@ -50,10 +50,6 @@ private:
HOST_RESOLVE_POLICY = 0x0010
};
-#ifdef FEATURE_PLS
- // Intersection of granted/denied permissions of all assemblies in domain
- LOADERHANDLE m_hDomainPermissionListSet;
-#endif // FEATURE_PLS
// The bits represent the status of security checks on some specific permissions within this domain
Volatile<DWORD> m_dwDomainWideSpecialFlags;
@@ -76,9 +72,6 @@ private:
// exists on the AppDomain. (In the managed world: AppDomain._SecurityIdentity != null)
BOOL m_fHomogeneous; // This AppDomain has an ApplicationTrust
BOOL m_fRuntimeSuppliedHomogenousGrantSet; // This AppDomain is homogenous only because the v4 CLR defaults to creating homogenous domains, and would not have been homogenous in v2
-#ifdef FEATURE_CAS_POLICY
- BOOL m_fLegacyCasPolicy; // This AppDomain is using legacy CAS policy
-#endif // FEATURE_CAS_POLICY
DWORD m_dwHostSecurityManagerFlags; // Flags indicating what decisions the host wants to participate in.
BOOL m_fContainsAnyRefusedPermissions;
@@ -86,9 +79,6 @@ private:
BOOL m_fPreResolutionFullTrust; // Was the domain pre-resolved to be full trust
BOOL m_fPreResolutionHomogeneous; // Was the domain pre-resolved to be homogenous
-#ifdef FEATURE_APTCA
- ConditionalAptcaCache* m_pConditionalAptcaCache; // Cache of known conditional APTCA assemblies in this domain
-#endif // FEATURE_APTCA
#ifndef DACCESS_COMPILE
public:
@@ -100,9 +90,6 @@ public:
//--------------------
// Destructor
//--------------------
-#ifdef FEATURE_APTCA // The destructor only deletes the ConditionalAptcaCache
- inline ~ApplicationSecurityDescriptor();
-#endif // FEATURE_APTCA
public:
// Indicates whether the initialization phase is in progress.
@@ -131,20 +118,12 @@ public:
inline void SetHomogeneousFlag(BOOL fRuntimeSuppliedHomogenousGrantSet);
virtual BOOL IsHomogeneous() const;
-#ifdef FEATURE_CAS_POLICY
- virtual BOOL IsLegacyCasPolicyEnabled();
- virtual void SetLegacyCasPolicyEnabled();
-#endif // FEATURE_CAS_POLICY
virtual BOOL ContainsAnyRefusedPermissions();
// Should the HSM be consulted for security decisions in this AppDomain.
virtual BOOL CallHostSecurityManager();
-#ifdef FEATURE_CAS_POLICY
- // Does the domain's HSM need to be consulted for assemblies loaded into the domain
- inline BOOL CallHostSecurityManagerForAssemblies();
-#endif // FEATURE_CAS_POLICY
// Initialize the PLS on the AppDomain.
void InitializePLS();
@@ -152,10 +131,6 @@ public:
// Called everytime an AssemblySecurityDescriptor is resolved.
void AddNewSecDescToPLS(AssemblySecurityDescriptor *pNewSecDescriptor);
-#ifdef FEATURE_PLS
- // Check the demand against the PLS in this AppDomain
- BOOL CheckPLS (OBJECTREF* orDemand, DWORD dwDemandSpecialFlags, BOOL fDemandSet);
-#endif // FEATURE_PLS
// Checks for one of the special domain wide flags
// such as if we are currently in a "fully trusted" environment
@@ -163,21 +138,11 @@ public:
inline BOOL CheckDomainWideSpecialFlag(DWORD flags) const;
virtual DWORD GetDomainWideSpecialFlag() const;
-#ifdef FEATURE_CAS_POLICY
- virtual OBJECTREF GetEvidence();
- DWORD GetZone();
-
- virtual BOOL AllowsLoadsFromRemoteSources();
-#endif // FEATURE_CAS_POLICY
virtual BOOL DomainMayContainPartialTrustCode();
BOOL QuickIsFullyTrusted();
-#ifdef FEATURE_APTCA
- virtual ConditionalAptcaCache *GetConditionalAptcaCache();
- virtual void SetCanonicalConditionalAptcaList(LPCWSTR wszCanonicalConditionalAptcaList);
-#endif // FEATURE_APTCA
#endif // #ifndef DACCESS_COMPILE
};
diff --git a/src/vm/securitydescriptorappdomain.inl b/src/vm/securitydescriptorappdomain.inl
index fdb8b3faef..8c66a49fa7 100644
--- a/src/vm/securitydescriptorappdomain.inl
+++ b/src/vm/securitydescriptorappdomain.inl
@@ -12,26 +12,17 @@
inline ApplicationSecurityDescriptor::ApplicationSecurityDescriptor(AppDomain *pAppDomain) :
SecurityDescriptorBase<IApplicationSecurityDescriptor>(pAppDomain, NULL, NULL, pAppDomain->GetLoaderAllocator()),
-#ifdef FEATURE_PLS
- m_hDomainPermissionListSet(NULL),
-#endif // FEAUTRE_PLS
m_dwDomainWideSpecialFlags(0xFFFFFFFF),
m_fIsInitializationInProgress(TRUE),
m_fIsDefaultAppdomain(FALSE),
m_fIsDefaultAppdomainEvidence(FALSE),
m_fHomogeneous(FALSE),
m_fRuntimeSuppliedHomogenousGrantSet(FALSE),
-#ifdef FEATURE_CAS_POLICY
- m_fLegacyCasPolicy(Security::IsProcessWideLegacyCasPolicyEnabled()),
-#endif // FEATURE_CAS_POLICY
m_dwHostSecurityManagerFlags(HOST_NONE),
m_fContainsAnyRefusedPermissions(FALSE),
m_fIsPreResolved(FALSE),
m_fPreResolutionFullTrust(FALSE),
m_fPreResolutionHomogeneous(FALSE)
-#ifdef FEATURE_APTCA
- ,m_pConditionalAptcaCache(new ConditionalAptcaCache(pAppDomain))
-#endif // FEATURE_APTCA
{
CONTRACTL
{
@@ -45,20 +36,6 @@ inline ApplicationSecurityDescriptor::ApplicationSecurityDescriptor(AppDomain *p
return;
}
-#ifdef FEATURE_APTCA
-inline ApplicationSecurityDescriptor::~ApplicationSecurityDescriptor()
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_ANY;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- delete m_pConditionalAptcaCache;
-}
-#endif // FEATURE_APTCA
inline void ApplicationSecurityDescriptor::ResetInitializationInProgress()
{
@@ -93,34 +70,6 @@ inline void ApplicationSecurityDescriptor::SetHomogeneousFlag(BOOL fRuntimeSuppl
m_fRuntimeSuppliedHomogenousGrantSet = fRuntimeSuppliedHomogenousGrantSet;
}
-#ifdef FEATURE_CAS_POLICY
-
-// Does the domain's HSM need to be consulted for assemblies loaded into the domain
-inline BOOL ApplicationSecurityDescriptor::CallHostSecurityManagerForAssemblies()
-{
- LIMITED_METHOD_CONTRACT;
-
- // We always need to call the HSM if it wants to specify the assembly's grant set
- if (m_dwHostSecurityManagerFlags & HOST_RESOLVE_POLICY)
- {
- return TRUE;
- }
-
- // In legacy CAS mode, we also need to call the HSM if it wants to supply evidence or if we have an
- // AppDomain policy level
- if (IsLegacyCasPolicyEnabled())
- {
- if ((m_dwHostSecurityManagerFlags & HOST_ASM_EVIDENCE) ||
- (m_dwHostSecurityManagerFlags & HOST_POLICY_LEVEL))
- {
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-#endif // FEATURE_CAS_POLICY
#endif // #ifndef DACCESS_COMPILE
diff --git a/src/vm/securitydescriptorassembly.cpp b/src/vm/securitydescriptorassembly.cpp
index 715d956123..383d62c3e3 100644
--- a/src/vm/securitydescriptorassembly.cpp
+++ b/src/vm/securitydescriptorassembly.cpp
@@ -15,14 +15,6 @@ AssemblySecurityDescriptor::AssemblySecurityDescriptor(AppDomain *pDomain, Domai
m_dwNumPassedDemands(0),
m_pSignature(NULL),
m_pSharedSecDesc(NULL),
-#ifdef FEATURE_CAS_POLICY
- m_hRequiredPermissionSet(NULL),
- m_hOptionalPermissionSet(NULL),
- m_hDeniedPermissionSet(NULL),
- m_fAdditionalEvidence(FALSE),
- m_fIsSignatureLoaded(FALSE),
- m_fAssemblyRequestsComputed(FALSE),
-#endif
m_fMicrosoftPlatform(FALSE),
m_fAllowSkipVerificationInFullTrust(TRUE)
{
@@ -151,48 +143,6 @@ BOOL AssemblySecurityDescriptor::QuickIsFullyTrusted()
if (IsSystem())
return TRUE;
-#ifdef FEATURE_CAS_POLICY
-
- // NGEN is always done in full trust
- if (m_pAppDomain->IsCompilationDomain())
- {
- return TRUE;
- }
-
- // If the assembly is in the GAC then it gets FullTrust.
- if (m_pAssem->GetFile()->IsSourceGAC())
- return TRUE;
-
- // quickly detect if we've got a request refused or a request optional.
- if (m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled())
- {
- ReleaseHolder<IMDInternalImport> pImport(m_pAssem->GetFile()->GetMDImportWithRef());
- if (SecurityAttributes::RestrictiveRequestsInAssembly(pImport))
- return FALSE;
- }
-
- // Check if we need to call the HostSecurityManager.
- ApplicationSecurityDescriptor* pAppSecDesc = static_cast<ApplicationSecurityDescriptor*>(m_pAppDomain->GetSecurityDescriptor());
- if (pAppSecDesc->CallHostSecurityManagerForAssemblies())
- return FALSE;
-
- // - If the AppDomain is homogeneous, we currently simply detect the FT case
- // - Not having CAS on implies full trust. We can get here if we're still in the process of setting up
- // the AppDomain and the CLR hasn't yet setup the homogenous flag.
- // - Otherwise, check the quick cache
- if (pAppSecDesc->IsHomogeneous())
- {
- return m_pAppDomain->GetSecurityDescriptor()->IsFullyTrusted();
- }
- else if (!m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled())
- {
- return TRUE;
- }
- else if (CheckQuickCache(SecurityConfig::FullTrustAll, GetZone()))
- {
- return TRUE;
- }
-#endif
// See if we've already determined that the assembly is FT
// in another AppDomain, in case this is a shared assembly.
@@ -231,115 +181,6 @@ void AssemblySecurityDescriptor::PropagatePermissionSet(OBJECTREF GrantedPermiss
Resolve();
}
-#ifdef FEATURE_CAS_POLICY
-//-----------------------------------------------------------------------------------------------------------
-//
-// Use the evidence already generated for this assembly's PEFile as the evidence for the assembly
-//
-// Arguments:
-// pPEFileSecDesc - PEFile security descriptor contining the already generated evidence
-//
-void AssemblySecurityDescriptor::SetEvidenceFromPEFile(IPEFileSecurityDescriptor *pPEFileSecDesc)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(pPEFileSecDesc));
- PRECONDITION(GetPEFile()->Equals(static_cast<PEFileSecurityDescriptor*>(pPEFileSecDesc)->GetPEFile()));
- }
- CONTRACTL_END;
-
- // If we couldn't determine the assembly was fully trusted without first generating evidence for it,
- // then we cannot reuse the PEFile's evidence. In that case we'll just use what we've generated for the
- // assembly, and discard the PEFile's version.
- if (!IsEvidenceComputed())
- {
- struct
- {
- OBJECTREF objPEFileEvidence;
- OBJECTREF objEvidence;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.objPEFileEvidence = pPEFileSecDesc->GetEvidence();
- gc.objEvidence = UpgradePEFileEvidenceToAssemblyEvidence(gc.objPEFileEvidence);
- SetEvidence(gc.objEvidence);
-
- GCPROTECT_END();
- }
-}
-
-//---------------------------------------------------------------------------------------
-//
-// Get the evidence collection for this Assembly
-//
-//
-OBJECTREF AssemblySecurityDescriptor::GetEvidence()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(m_pAppDomain == GetAppDomain());
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- // If we already have evidence, then just return that
- if (IsEvidenceComputed())
- return ObjectFromLazyHandle(m_hAdditionalEvidence, m_pLoaderAllocator);
-
- struct
- {
- OBJECTREF objHostProvidedEvidence;
- OBJECTREF objPEFileEvidence;
- OBJECTREF objEvidence;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
- BEGIN_SO_INTOLERANT_CODE(GetThread());
-
- gc.objHostProvidedEvidence = ObjectFromLazyHandle(m_hAdditionalEvidence, m_pLoaderAllocator);
-
-#if CHECK_APP_DOMAIN_LEAKS
- if (g_pConfig->AppDomainLeaks())
- {
- _ASSERTE(gc.objPEFileEvidence == NULL || GetAppDomain() == gc.objPEFileEvidence->GetAppDomain());
- _ASSERTE(gc.objHostProvidedEvidence == NULL || GetAppDomain() == gc.objHostProvidedEvidence->GetAppDomain());
- }
-#endif // CHECK_APP_DOMAIN_LEAKS
-
- //
- // First get an evidence collection which targets our PEFile, then upgrade it to use this assembly as a
- // target. We create a new Evidence for the PEFile here, which means that any evidence that PEFile may
- // have already had is not used in this upgrade. If an existing PEFileSecurityDescriptor exists for the
- // PEFile, then that should be upgraded directly, rather than going through this code path.
- //
-
- gc.objPEFileEvidence = PEFileSecurityDescriptor::BuildEvidence(m_pPEFile, gc.objHostProvidedEvidence);
- gc.objEvidence = UpgradePEFileEvidenceToAssemblyEvidence(gc.objPEFileEvidence);
- SetEvidence(gc.objEvidence);
-
-#if CHECK_APP_DOMAIN_LEAKS
- if (g_pConfig->AppDomainLeaks())
- _ASSERTE(gc.objEvidence == NULL || GetAppDomain() == gc.objEvidence->GetAppDomain());
-#endif // CHECK_APP_DOMAIN_LEAKS
-
- END_SO_INTOLERANT_CODE;
-
- GCPROTECT_END();
-
- return gc.objEvidence;
-}
-#endif // FEATURE_CAS_POLICY
#endif // !DACCESS_COMPILE
BOOL AssemblySecurityDescriptor::IsSystem()
@@ -369,36 +210,6 @@ void AssemblySecurityDescriptor::Resolve()
pSharedSecDesc->Resolve(this);
}
-#ifdef FEATURE_CAS_POLICY
-// This routine is called when we have determined that it that there is no SECURITY reason
-// to verify an image, but we may want to do so anyway to insure that 3rd parties don't
-// accidentally ship delay signed dlls because the application happens to be full trust.
-//
-static bool DontNeedToFlagAccidentalDelaySigning(PEAssembly* assem)
-{
- WRAPPER_NO_CONTRACT;
-
- // If the file has a native image, then either it is strongly named and can be considered
- // fully signed (see additional comments in code:PEAssembly::IsFullySigned), or it is not
- // strong named and thus can't be delay signed. Either way no check is needed.
- // If the file fully signed, then people did not accidentally forget, so no check is needed
- if (assem->HasNativeImage() || assem->IsFullySigned())
- return true;
-
- // If mscorlib itself is not signed, this is not an offical CLR, you don't need to
- // to do the checking in this case either because 3rd parties should not be running this way.
- // This is useful because otherwise when we run perf runs on normal CLR lab builds we don't
- // measure the performance that we get for a offical runtime (since official runtimes will
- // be signed).
- PEAssembly* mscorlib = SystemDomain::SystemFile();
- if (!mscorlib->HasNativeImage())
- return false;
- if ((mscorlib->GetLoadedNative()->GetNativeHeader()->COR20Flags & COMIMAGE_FLAGS_STRONGNAMESIGNED) == 0)
- return true;
-
- return false;
-}
-#endif // FEATURE_CAS_POLICY
void AssemblySecurityDescriptor::ResolveWorker()
{
@@ -463,27 +274,6 @@ void AssemblySecurityDescriptor::ResolvePolicy(ISharedSecurityDescriptor *pShare
__dcimf.Pop();
}
-#ifdef FEATURE_CAS_POLICY
-DWORD AssemblySecurityDescriptor::GetZone()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- PRECONDITION(m_pAppDomain->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled());
- } CONTRACTL_END;
-
- StackSString codebase;
- SecZone dwZone = NoZone;
- BYTE rbUniqueID[MAX_SIZE_SECURITY_ID];
- DWORD cbUniqueID = sizeof(rbUniqueID);
-
- m_pAssem->GetSecurityIdentity(codebase, &dwZone, 0, rbUniqueID, &cbUniqueID);
- return dwZone;
-}
-#endif // FEATURE_CAS_POLICY
Assembly* AssemblySecurityDescriptor::GetAssembly()
{
@@ -498,130 +288,7 @@ BOOL AssemblySecurityDescriptor::CanSkipPolicyResolution()
}
-#ifdef FEATURE_CAS_POLICY
-//-----------------------------------------------------------------------------------------------------------
-//
-// Upgrade the evidence used for resolving a PEFile to be targeted at the Assembly the PEFile represents
-//
-// Arguments:
-// objPEFileEvidence -
-//
-// Notes:
-// During CLR startup we may need to resolve policy against a PEFile before we have the associated
-// Assembly. Once we have the Assembly we don't want to recompute potenially expensive evidence, so this
-// method can be used to upgrade the evidence who's target was the PEFile to target the assembly instead.
-//
-// Will call into System.Reflection.Assembly.UpgradeSecurityIdentity
-//
-OBJECTREF AssemblySecurityDescriptor::UpgradePEFileEvidenceToAssemblyEvidence(const OBJECTREF& objPEFileEvidence)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(objPEFileEvidence != NULL);
- }
- CONTRACTL_END;
-
- struct
- {
- OBJECTREF objAssembly;
- OBJECTREF objEvidence;
- OBJECTREF objUpgradedEvidence;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.objAssembly = m_pAssem->GetExposedAssemblyObject();
- gc.objEvidence = objPEFileEvidence;
-
- MethodDescCallSite upgradeSecurityIdentity(METHOD__ASSEMBLY_EVIDENCE_FACTORY__UPGRADE_SECURITY_IDENTITY);
-
- ARG_SLOT args[] =
- {
- ObjToArgSlot(gc.objEvidence),
- ObjToArgSlot(gc.objAssembly)
- };
-
- gc.objUpgradedEvidence = upgradeSecurityIdentity.Call_RetOBJECTREF(args);
-
- GCPROTECT_END();
-
- return gc.objUpgradedEvidence;
-}
-
-HRESULT AssemblySecurityDescriptor::LoadSignature(COR_TRUST **ppSignature)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- } CONTRACTL_END;
-
- if (IsSignatureLoaded())
- {
- if (ppSignature)
- {
- *ppSignature = m_pSignature;
- }
-
- return S_OK;
- }
-
- GCX_PREEMP();
- m_pSignature = m_pAssem->GetFile()->GetAuthenticodeSignature();
-
- SetSignatureLoaded();
-
- if (ppSignature)
- {
- *ppSignature = m_pSignature;
- }
-
- return S_OK;
-}
-
-void AssemblySecurityDescriptor::SetAdditionalEvidence(OBJECTREF evidence)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- StoreObjectInLazyHandle(m_hAdditionalEvidence, evidence, m_pLoaderAllocator);
- m_fAdditionalEvidence = TRUE;
-}
-
-BOOL AssemblySecurityDescriptor::HasAdditionalEvidence()
-{
- LIMITED_METHOD_CONTRACT;
- return m_fAdditionalEvidence;
-}
-
-OBJECTREF AssemblySecurityDescriptor::GetAdditionalEvidence()
-{
- WRAPPER_NO_CONTRACT;
- return ObjectFromLazyHandle(m_hAdditionalEvidence, m_pLoaderAllocator);
-}
-#endif // FEATURE_CAS_POLICY
-
-#ifndef FEATURE_CORECLR
-BOOL AssemblySecurityDescriptor::AllowApplicationSpecifiedAppDomainManager()
-{
- WRAPPER_NO_CONTRACT;
-
- // Only fully trusted assemblies are allowed to specify their AppDomainManager in a config file
- return this->IsFullyTrusted();
-}
-#endif // FEATURE_CORECLR
// Check to make sure that security will allow this assembly to load. Throw an exception if the assembly
// should be forbidden from loading for security related purposes
diff --git a/src/vm/securitydescriptorassembly.h b/src/vm/securitydescriptorassembly.h
index 4ba65eb11d..d414de033d 100644
--- a/src/vm/securitydescriptorassembly.h
+++ b/src/vm/securitydescriptorassembly.h
@@ -65,15 +65,6 @@ private:
COR_TRUST *m_pSignature; // Contains the publisher, requested permission
SharedSecurityDescriptor *m_pSharedSecDesc; // Shared state for assemblies loaded into multiple appdomains
-#ifdef FEATURE_CAS_POLICY
- LOADERHANDLE m_hRequiredPermissionSet; // Required Requested Permissions
- LOADERHANDLE m_hOptionalPermissionSet; // Optional Requested Permissions
- LOADERHANDLE m_hDeniedPermissionSet; // Denied Permissions
-
- BOOL m_fAdditionalEvidence;
- BOOL m_fIsSignatureLoaded;
- BOOL m_fAssemblyRequestsComputed;
-#endif // FEATURE_CAS_POLICY
BOOL m_fMicrosoftPlatform;
BOOL m_fAllowSkipVerificationInFullTrust;
@@ -108,24 +99,7 @@ public:
virtual void PropagatePermissionSet(OBJECTREF GrantedPermissionSet, OBJECTREF DeniedPermissionSet, DWORD dwSpecialFlags);
#endif // !DACCESS_COMPILE
-#ifdef FEATURE_CAS_POLICY
- virtual HRESULT LoadSignature(COR_TRUST **ppSignature = NULL);
- virtual OBJECTREF GetEvidence();
- DWORD GetZone();
-
- OBJECTREF GetRequestedPermissionSet(OBJECTREF *pOptionalPermissionSet, OBJECTREF *pDeniedPermissionSet);
-
-#ifndef DACCESS_COMPILE
- virtual void SetAdditionalEvidence(OBJECTREF evidence);
- virtual BOOL HasAdditionalEvidence();
- virtual OBJECTREF GetAdditionalEvidence();
- virtual void SetEvidenceFromPEFile(IPEFileSecurityDescriptor *pPEFileSecDesc);
-#endif // !DACCESS_COMPILE
-#endif // FEATURE_CAS_POLICY
-#ifndef FEATURE_CORECLR
- virtual BOOL AllowApplicationSpecifiedAppDomainManager();
-#endif // !FEATURE_CORECLR
virtual void CheckAllowAssemblyLoad();
@@ -135,18 +109,7 @@ private:
void ResolveWorker();
-#ifdef FEATURE_CAS_POLICY
- inline BOOL IsAssemblyRequestsComputed();
- inline BOOL IsSignatureLoaded();
- inline void SetSignatureLoaded();
-#endif
-#ifdef FEATURE_APTCA
- // If you think you need to call this method, you're probably wrong. We shouldn't be making any
- // security enforcement decisions based upon this result -- it's strictly for ensuring that we load
- // conditional APTCA assemblies correctly.
- inline BOOL IsConditionalAptca();
-#endif // FEATURE_APTCA
#endif // #ifndef DACCESS_COMPILE
};
diff --git a/src/vm/securitydescriptorassembly.inl b/src/vm/securitydescriptorassembly.inl
index 44b49a32c9..e12a6c5963 100644
--- a/src/vm/securitydescriptorassembly.inl
+++ b/src/vm/securitydescriptorassembly.inl
@@ -35,38 +35,7 @@ inline void AssemblySecurityDescriptor::TryCachePassedDemand(PsetCacheEntry *pCa
m_arrPassedLinktimeDemands[m_dwNumPassedDemands++] = pCasDemands;
}
-#ifdef FEATURE_CAS_POLICY
-inline BOOL AssemblySecurityDescriptor::IsAssemblyRequestsComputed()
-{
- LIMITED_METHOD_CONTRACT;
- return m_fAssemblyRequestsComputed;
-}
-
-inline BOOL AssemblySecurityDescriptor::IsSignatureLoaded()
-{
- LIMITED_METHOD_CONTRACT;
- return m_fIsSignatureLoaded;
-}
-
-inline void AssemblySecurityDescriptor::SetSignatureLoaded()
-{
- LIMITED_METHOD_CONTRACT;
- m_fIsSignatureLoaded = TRUE;
-}
-
-#endif // FEATURE_CAS_POLICY
-
-#ifdef FEATURE_APTCA
-
-inline BOOL AssemblySecurityDescriptor::IsConditionalAptca()
-{
- WRAPPER_NO_CONTRACT;
- ModuleSecurityDescriptor *pMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(m_pAssem->GetAssembly());
- return (pMSD->GetTokenFlags() & TokenSecurityDescriptorFlags_ConditionalAPTCA) == TokenSecurityDescriptorFlags_ConditionalAPTCA;
-}
-
-#endif // FEATURE_APTCA
#endif // !DACCESS_COMPILE
diff --git a/src/vm/securitymeta.cpp b/src/vm/securitymeta.cpp
index ff286ddb68..1374d9ff55 100644
--- a/src/vm/securitymeta.cpp
+++ b/src/vm/securitymeta.cpp
@@ -21,7 +21,6 @@
#include "security.h"
#include "perfcounters.h"
-#include "nlstable.h"
#include "frames.h"
#include "dllimport.h"
#include "strongname.h"
@@ -29,10 +28,6 @@
#include "field.h"
#include "threads.h"
#include "eventtrace.h"
-#ifdef FEATURE_REMOTING
-#include "appdomainhelper.h"
-#include "objectclone.h"
-#endif //FEATURE_REMOTING
#include "typestring.h"
#include "securitydeclarative.h"
#include "customattribute.h"
@@ -56,9 +51,6 @@ void FieldSecurityDescriptor::VerifyDataComputed()
return;
}
-#ifndef FEATURE_CORECLR
- FieldSecurityDescriptorTransparencyEtwEvents etw(this);
-#endif // !FEATURE_CORECLR
#ifdef _DEBUG
// If we've setup a breakpoint when we compute the transparency of this field, then stop in the debugger
@@ -283,9 +275,6 @@ void MethodSecurityDescriptor::ComputeCriticalTransparentInfo()
}
CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- MethodSecurityDescriptorTransparencyEtwEvents etw(this);
-#endif // !FEATURE_CORECLR
MethodTable* pMT = m_pMD->GetMethodTable();
@@ -739,72 +728,6 @@ void MethodSecurityDescriptor::InvokeInheritanceChecks(MethodDesc *pChildMD)
}
}
-#ifndef FEATURE_CORECLR
- // Check CAS Inheritance
-
- // Early out if we're fully trusted
- if (SecurityDeclarative::FullTrustCheckForLinkOrInheritanceDemand(pChildMD->GetAssembly()))
- {
- return;
- }
-
- if (HasInheritanceDeclarativeSecurity())
- {
-#ifdef CROSSGEN_COMPILE
- // NGen is always full trust. This path should be unreachable.
- CrossGenNotSupported("HasInheritanceDeclarativeSecurity()");
-#else // CROSSGEN_COMPILE
- GCX_COOP();
-
- OBJECTREF refCasDemands = NULL;
- PsetCacheEntry* pCasDemands = NULL;
-
- HRESULT hr = GetDeclaredPermissionsWithCache(dclInheritanceCheck, &refCasDemands, &pCasDemands);
- if (refCasDemands != NULL)
- {
- _ASSERTE(pCasDemands != NULL);
-
- // See if inheritor's assembly has passed this demand before
- AssemblySecurityDescriptor *pInheritorAssem = static_cast<AssemblySecurityDescriptor*>(pChildMD->GetAssembly()->GetSecurityDescriptor());
- BOOL fSkipCheck = pInheritorAssem->AlreadyPassedDemand(pCasDemands);
-
- if (!fSkipCheck)
- {
- GCPROTECT_BEGIN(refCasDemands);
-
- // Perform the check (it's really just a LinkDemand)
- SecurityStackWalk::LinkOrInheritanceCheck(pChildMD->GetAssembly()->GetSecurityDescriptor(), refCasDemands, pChildMD->GetAssembly(), dclInheritanceCheck);
-
- // Demand passed. Add it to the Inheritor's assembly's list of passed demands
- pInheritorAssem->TryCachePassedDemand(pCasDemands);
-
- GCPROTECT_END();
- }
- }
-
- // @todo -- non cas shouldn't be used for inheritance demands...
-
- // Check non-CAS Inheritance
- OBJECTREF refNonCasDemands = NULL;
- hr = GetDeclaredPermissionsWithCache( dclNonCasInheritance, &refNonCasDemands, NULL);
- if (refNonCasDemands != NULL)
- {
- _ASSERTE(((PERMISSIONSETREF)refNonCasDemands)->CheckedForNonCas() && "Declarative permissions should have been checked for nonCAS in PermissionSet.CreateSerialized");
- if (((PERMISSIONSETREF)refNonCasDemands)->ContainsNonCas())
- {
- GCPROTECT_BEGIN(refNonCasDemands);
-
- // Perform the check
- MethodDescCallSite demand(METHOD__PERMISSION_SET__DEMAND_NON_CAS, &refNonCasDemands);
- ARG_SLOT arg = ObjToArgSlot(refNonCasDemands);
- demand.Call(&arg);
-
- GCPROTECT_END();
- }
- }
-#endif // CROSSGEN_COMPILE
- }
-#endif // FEATURE_CORECLR
}
MethodSecurityDescriptor::MethodImplementationIterator::MethodImplementationIterator(MethodDesc *pMD)
@@ -977,117 +900,6 @@ TypeSecurityDescriptor* TypeSecurityDescriptor::GetTypeSecurityDescriptor(Method
return pTypeSecurityDesc;
}
-#if !defined(CROSSGEN_COMPILE) && defined(FEATURE_CAS_POLICY)
-HRESULT TokenDeclActionInfo::GetDeclaredPermissionsWithCache(
- IN CorDeclSecurity action,
- OUT OBJECTREF *pDeclaredPermissions,
- OUT PsetCacheEntry **pPCE)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
- HRESULT hr = S_OK;
- DWORD dwActionFlag = DclToFlag((CorDeclSecurity)action);
-
- PsetCacheEntry *ptempPCE=NULL;
- TokenDeclActionInfo* pCurrentAction = this;
- for (;
- pCurrentAction;
- pCurrentAction = pCurrentAction->pNext)
- {
- if (pCurrentAction->dwDeclAction == dwActionFlag)
- {
- ptempPCE = pCurrentAction->pPCE;
- break;
- }
- }
- if (pDeclaredPermissions && pCurrentAction)
- {
- *pDeclaredPermissions = ptempPCE->CreateManagedPsetObject (action);
- }
- if (pPCE && pCurrentAction)
- {
- *pPCE = ptempPCE;
- }
-
- return hr;
-}
-
-OBJECTREF TokenDeclActionInfo::GetLinktimePermissions(OBJECTREF *prefNonCasDemands)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- OBJECTREF refCasDemands = NULL;
- GCPROTECT_BEGIN(refCasDemands);
-
- GetDeclaredPermissionsWithCache(
- dclLinktimeCheck,
- &refCasDemands, NULL);
-
- TokenDeclActionInfo::GetDeclaredPermissionsWithCache(
- dclNonCasLinkDemand,
- prefNonCasDemands, NULL);
-
- GCPROTECT_END();
- return refCasDemands;
-}
-
-void TokenDeclActionInfo::InvokeLinktimeChecks(Assembly* pCaller)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM(););
- PRECONDITION(CheckPointer(pCaller));
- }
- CONTRACTL_END;
-
-#ifdef FEATURE_MULTICOREJIT
-
- // Reset the flag to allow managed code to be called in multicore JIT background thread from this routine
- ThreadStateNCStackHolder holder(-1, Thread::TSNC_CallingManagedCodeDisabled);
-
-#endif
-
- struct gc
- {
- OBJECTREF refNonCasDemands;
- OBJECTREF refCasDemands;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- // CAS LinkDemands
- GetDeclaredPermissionsWithCache(dclLinktimeCheck,
- &gc.refCasDemands,
- NULL);
-
- if (gc.refCasDemands != NULL)
- {
- SecurityStackWalk::LinkOrInheritanceCheck(pCaller->GetSecurityDescriptor(), gc.refCasDemands, pCaller, dclLinktimeCheck);
- }
-
- // NON CAS LinkDEMANDS (we shouldn't support this).
- GetDeclaredPermissionsWithCache(dclNonCasLinkDemand,
- &gc.refNonCasDemands,
- NULL);
-
- GCPROTECT_END();
-}
-#endif // !CROSSGEN_COMPILE && FEATURE_CAS_POLICY
void TypeSecurityDescriptor::ComputeCriticalTransparentInfo()
{
@@ -1099,9 +911,6 @@ void TypeSecurityDescriptor::ComputeCriticalTransparentInfo()
}
CONTRACTL_END;
-#ifndef FEATURE_CORECLR
- TypeSecurityDescriptorTransparencyEtwEvents etw(this);
-#endif // !FEATURE_CORECLR
#ifdef _DEBUG
// If we've setup a breakpoint when we compute the transparency of this type, then stop in the debugger now
@@ -1240,9 +1049,6 @@ void TypeSecurityDescriptor::ComputeCriticalTransparentInfo()
// Update the cached values in the EE Class.
g_IBCLogger.LogEEClassCOWTableAccess(m_pMT);
pClass->SetCriticalTransparentInfo(
-#ifndef FEATURE_CORECLR
- typeFlags & (TypeSecurityDescriptorFlags_IsCritical | TypeSecurityDescriptorFlags_IsAllCritical),
-#endif // FEATURE_CORECLR
typeFlags & TypeSecurityDescriptorFlags_IsTreatAsSafe,
typeFlags & TypeSecurityDescriptorFlags_IsAllTransparent,
typeFlags & TypeSecurityDescriptorFlags_IsAllCritical);
@@ -1484,73 +1290,6 @@ void TypeSecurityDescriptor::InvokeInheritanceChecks(MethodTable* pChildMT)
}
}
-#ifndef FEATURE_CORECLR
- // Fast path check
- if (SecurityDeclarative::FullTrustCheckForLinkOrInheritanceDemand(pChildMT->GetAssembly()))
- {
- return;
- }
-
- if (HasInheritanceDeclarativeSecurity())
- {
-#ifdef CROSSGEN_COMPILE
- // NGen is always full trust. This path should be unreachable.
- CrossGenNotSupported("HasInheritanceDeclarativeSecurity()");
-#else // CROSSGEN_COMPILE
- GCX_COOP();
-
- // If we have a class that requires inheritance checks,
- // then we require a thread to perform the checks.
- // We won't have a thread when some of the system classes
- // are preloaded, so make sure that none of them have
- // inheritance checks.
- _ASSERTE(GetThread() != NULL);
-
- struct
- {
- OBJECTREF refCasDemands;
- OBJECTREF refNonCasDemands;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- EEClass *pClass = m_pMT->GetClass();
- if (pClass->RequiresCasInheritanceCheck())
- {
- GetDeclaredPermissionsWithCache(dclInheritanceCheck, &gc.refCasDemands, NULL);
- }
-
- if (pClass->RequiresNonCasInheritanceCheck())
- {
- GetDeclaredPermissionsWithCache(dclNonCasInheritance, &gc.refNonCasDemands, NULL);
- }
-
- if (gc.refCasDemands != NULL)
- {
- SecurityStackWalk::LinkOrInheritanceCheck(pChildMT->GetAssembly()->GetSecurityDescriptor(),
- gc.refCasDemands,
- pChildMT->GetAssembly(),
- dclInheritanceCheck);
- }
-
- if (gc.refNonCasDemands != NULL)
- {
- _ASSERTE(((PERMISSIONSETREF)gc.refNonCasDemands)->CheckedForNonCas() && "Declarative permissions should have been checked for nonCAS in PermissionSet.CreateSerialized");
- if(((PERMISSIONSETREF)gc.refNonCasDemands)->ContainsNonCas())
- {
- MethodDescCallSite demand(METHOD__PERMISSION_SET__DEMAND_NON_CAS, &gc.refNonCasDemands);
-
- ARG_SLOT arg = ObjToArgSlot(gc.refNonCasDemands);
- demand.Call(&arg);
- }
- }
-
- GCPROTECT_END();
-#endif // CROSSGEN_COMPILE
- }
-#endif // FEATURE_CORECLR
}
// Module security descriptor contains static security information about the module
@@ -1571,9 +1310,6 @@ void ModuleSecurityDescriptor::VerifyDataComputed()
return;
}
-#ifndef FEATURE_CORECLR
- ModuleSecurityDescriptorTransparencyEtwEvents etw(this);
-#endif // !FEATURE_CORECLR
// Read the security attributes from the assembly
Assembly *pAssembly = m_pModule->GetAssembly();
@@ -1583,24 +1319,7 @@ void ModuleSecurityDescriptor::VerifyDataComputed()
// choosing.
TokenSecurityDescriptorFlags tokenFlags = GetTokenFlags();
-#ifdef FEATURE_APTCA
- // We need to post-process the APTCA bits on the token security descriptor to handle:
- // 1. Conditional APTCA assemblies, which should appear as either APTCA-enabled or APTCA-disabled
- // 2. APTCA killbitted assemblies, which should appear as APTCA-disabled
- tokenFlags = ProcessAssemblyAptcaFlags(pAssembly->GetDomainAssembly(), tokenFlags);
-#endif // FEATURE_APTCA
-#ifndef FEATURE_CORECLR
- // Make sure we understand the security rule set being asked for
- if (GetSecurityRuleSet() < SecurityRuleSet_Min || GetSecurityRuleSet() > SecurityRuleSet_Max)
- {
- // Unknown rule set - fail to load this module
- SString strAssemblyName;
- pAssembly->GetDisplayName(strAssemblyName);
- COMPlusThrow(kFileLoadException, IDS_E_UNKNOWN_SECURITY_RULESET, strAssemblyName.GetUnicode());
- }
-
-#endif // !FEATURE_CORECLR
// Get a transparency behavior object for the assembly.
const SecurityTransparencyBehavior *pTransparencyBehavior =
@@ -1691,14 +1410,6 @@ void ModuleSecurityDescriptor::VerifyDataComputed()
}
}
-#ifdef FEATURE_APTCA
- // If the security model implies that unsigned assemblies are APTCA, then check to see if we're unsigned
- // and set the APTCA bit.
- if (pTransparencyBehavior->DoesUnsignedImplyAPTCA() && !pAssembly->IsStrongNamed())
- {
- moduleFlags |= ModuleSecurityDescriptorFlags_IsAPTCA;
- }
-#endif // FEATURE_APTCA
#ifdef _DEBUG
// If we're being forced to generate native code for this assembly which can be used in a partial trust
@@ -1721,40 +1432,6 @@ void ModuleSecurityDescriptor::VerifyDataComputed()
_ASSERTE(m_flags == moduleFlags);
}
-#ifndef FEATURE_CORECLR
-
-// Determine if this assembly was build against a version of the runtime that only supported legacy transparency
-BOOL ModuleSecurityDescriptor::AssemblyVersionRequiresLegacyTransparency()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- SO_INTOLERANT;
- }
- CONTRACTL_END;
-
- BOOL fIsLegacyAssembly = FALSE;
-
- // Check the manifest version number to see if we're a v1 or v2 assembly. We specifically check for the
- // manifest version to come back as a string that starts with either v1 or v2; if we get anything
- // unexpected, we'll just use the default transparency implementation
- LPCSTR szVersion = NULL;
- IMDInternalImport *pmdImport = m_pModule->GetAssembly()->GetManifestImport();
- if (SUCCEEDED(pmdImport->GetVersionString(&szVersion)))
- {
- if (szVersion != NULL && strlen(szVersion) > 2)
- {
- fIsLegacyAssembly = szVersion[0] == 'v' &&
- (szVersion[1] == '1' || szVersion[1] == '2');
- }
- }
-
- return fIsLegacyAssembly;
-}
-
-#endif // !FEATURE_CORECLR
ModuleSecurityDescriptor* ModuleSecurityDescriptor::GetModuleSecurityDescriptor(Assembly *pAssembly)
{
@@ -1786,7 +1463,7 @@ VOID ModuleSecurityDescriptor::Fixup(DataImage *image)
}
#endif
-#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_CORESYSTEM)
//---------------------------------------------------------------------------------------
//
@@ -1829,7 +1506,7 @@ TokenSecurityDescriptorFlags ParseAptcaAttribute(const BYTE *pbAptcaBlob, DWORD
return aptcaFlags;
}
-#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#endif // defined(FEATURE_CORESYSTEM)
//---------------------------------------------------------------------------------------
//
@@ -1935,7 +1612,7 @@ TokenSecurityDescriptorFlags TokenSecurityDescriptor::ReadSecurityAttributes(IMD
szAttributeNamespace != NULL &&
strcmp(g_SecurityNS, szAttributeNamespace) == 0)
{
-#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_CORESYSTEM)
if (strcmp(g_SecurityAPTCA + sizeof(g_SecurityNS), szAttributeName) == 0)
{
// Check the visibility parameter
@@ -1951,36 +1628,11 @@ TokenSecurityDescriptorFlags TokenSecurityDescriptor::ReadSecurityAttributes(IMD
flags |= aptcaFlags;
}
else
-#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#endif // defined(FEATURE_CORESYSTEM)
if (strcmp(g_SecurityCriticalAttribute + sizeof(g_SecurityNS), szAttributeName) == 0)
{
flags |= TokenSecurityDescriptorFlags_Critical;
-#ifndef FEATURE_CORECLR
- // Check the SecurityCriticalScope parameter
- const BYTE *pbAttributeBlob;
- ULONG cbAttributeBlob;
-
- if (FAILED(pmdImport->GetCustomAttributeAsBlob(
- currentAttribute,
- reinterpret_cast<const void **>(&pbAttributeBlob),
- &cbAttributeBlob)))
- {
- continue;
- }
- CustomAttributeParser cap(pbAttributeBlob, cbAttributeBlob);
- if (SUCCEEDED(cap.SkipProlog()))
- {
- UINT32 dwCriticalFlags;
- if (SUCCEEDED(cap.GetU4(&dwCriticalFlags)))
- {
- if (dwCriticalFlags == SecurityCriticalFlags_All)
- {
- flags |= TokenSecurityDescriptorFlags_AllCritical;
- }
- }
- }
-#endif // !FEATURE_CORECLR
}
else if (strcmp(g_SecuritySafeCriticalAttribute + sizeof(g_SecurityNS), szAttributeName) == 0)
{
@@ -1990,30 +1642,6 @@ TokenSecurityDescriptorFlags TokenSecurityDescriptor::ReadSecurityAttributes(IMD
{
flags |= TokenSecurityDescriptorFlags_Transparent;
}
-#ifndef FEATURE_CORECLR
- else if (strcmp(g_SecurityRulesAttribute + sizeof(g_SecurityNS), szAttributeName) == 0)
- {
- const BYTE *pbAttributeBlob;
- ULONG cbAttributeBlob;
-
- if (FAILED(pmdImport->GetCustomAttributeAsBlob(
- currentAttribute,
- reinterpret_cast<const void **>(&pbAttributeBlob),
- &cbAttributeBlob)))
- {
- continue;
- }
-
- TokenSecurityDescriptorFlags securityRulesFlags =
- ParseSecurityRulesAttribute(pbAttributeBlob, cbAttributeBlob);
-
- flags |= securityRulesFlags;
- }
- else if (strcmp(g_SecurityTreatAsSafeAttribute + sizeof(g_SecurityNS), szAttributeName) == 0)
- {
- flags |= TokenSecurityDescriptorFlags_TreatAsSafe;
- }
-#endif // !FEATURE_CORECLR
}
}
@@ -2041,9 +1669,6 @@ void TokenSecurityDescriptor::VerifySemanticDataComputed()
return;
}
-#ifndef FEATURE_CORECLR
- TokenSecurityDescriptorTransparencyEtwEvents etw(this);
-#endif // !FEATURE_CORECLR
bool fIsSemanticallyCritical = false;
bool fIsSemanticallyTreatAsSafe = false;
diff --git a/src/vm/securitymeta.h b/src/vm/securitymeta.h
index d78b7bde54..8247204e56 100644
--- a/src/vm/securitymeta.h
+++ b/src/vm/securitymeta.h
@@ -158,10 +158,6 @@ inline SecurityRuleSet GetSecurityRuleSet(TokenSecurityDescriptorFlags flags);
// Encode a security rule set into token flags - this reverses GetSecurityRuleSet
inline TokenSecurityDescriptorFlags EncodeSecurityRuleSet(SecurityRuleSet ruleSet);
-#ifdef FEATURE_APTCA
-TokenSecurityDescriptorFlags ParseAptcaAttribute(const BYTE *pbAptcaBlob,
- DWORD cbAptcaBlob);
-#endif // FEATURE_APTCA
TokenSecurityDescriptorFlags ParseSecurityRulesAttribute(const BYTE *pbSecurityRulesBlob,
DWORD cbSecurityRulesBlob);
@@ -575,9 +571,6 @@ inline ModuleSecurityDescriptorFlags operator&=(ModuleSecurityDescriptorFlags& l
inline ModuleSecurityDescriptorFlags operator~(ModuleSecurityDescriptorFlags flags);
-#ifdef FEATURE_APTCA
-BOOL CheckAssemblyHasBeenKillBitted(LPASSEMBLYNAME pAssemblyName, ULARGE_INTEGER uliFileVersion);
-#endif
// Module security descriptor, this class contains static security information about the module
// this information will get persisted in the NGen image
@@ -636,19 +629,12 @@ public:
// Get the rule set the assembly uses
inline SecurityRuleSet GetSecurityRuleSet();
-#ifndef FEATURE_CORECLR
- // Can fully trusted transparent code bypass verification
- inline BOOL CanTransparentCodeSkipVerification();
-#endif // !FEATURE_CORECLR
-#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_CORESYSTEM)
// Does the assembly allow partially trusted callers
inline BOOL IsAPTCA();
-#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#endif // defined(FEATURE_CORESYSTEM)
-#ifndef FEATURE_CORECLR
- BOOL AssemblyVersionRequiresLegacyTransparency();
-#endif // !FEATURE_CORECLR
private:
// Helper class which fires transparency calculation begin/end ETW events
diff --git a/src/vm/securitymeta.inl b/src/vm/securitymeta.inl
index adb6faa5ac..59525d783a 100644
--- a/src/vm/securitymeta.inl
+++ b/src/vm/securitymeta.inl
@@ -411,30 +411,8 @@ inline BOOL MethodSecurityDescriptor::IsDeclSecurityCASDemandsOnly(DWORD dwMethD
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
// Non-CAS demands are not supported in CoreCLR
return TRUE;
-#else
- GCX_COOP();
-
- PsetCacheEntry *tokenSetIndexes[dclMaximumValue + 1];
- SecurityDeclarative::DetectDeclActionsOnToken(_mdToken, dwMethDeclFlags, tokenSetIndexes, pInternalImport);
- SecurityProperties sp(dwMethDeclFlags);
- if (!sp.FDemandsOnly())
- return FALSE;
-
- DWORD dwLocalAction;
- bool builtInCASPermsOnly = true;
- for (dwLocalAction = 0; dwLocalAction <= dclMaximumValue && builtInCASPermsOnly; dwLocalAction++)
- {
- if (tokenSetIndexes[dwLocalAction] != NULL)
- {
- builtInCASPermsOnly = builtInCASPermsOnly && (tokenSetIndexes[dwLocalAction]->ContainsBuiltinCASPermsOnly(dwLocalAction));
- }
- }
-
- return (builtInCASPermsOnly); // we only get here if there are only demands...so it suffices to return this value directly
-#endif
}
#ifndef DACCESS_COMPILE
@@ -632,9 +610,6 @@ inline BOOL TypeSecurityDescriptor::IsCritical()
}
return pClass->IsAllCritical()
-#ifndef FEATURE_CORECLR
- || pClass->IsCritical()
-#endif // !FEATURE_CORECLR
;
}
@@ -1101,25 +1076,15 @@ inline BOOL ModuleSecurityDescriptor::IsMixedTransparency()
return !IsAllCritical() && !IsAllTransparent();
}
-#ifndef FEATURE_CORECLR
-inline BOOL ModuleSecurityDescriptor::CanTransparentCodeSkipVerification()
-{
- WRAPPER_NO_CONTRACT;
- VerifyDataComputed();
- return !!(m_flags & ModuleSecurityDescriptorFlags_SkipFullTrustVerification);
-}
-
-#endif // !FEATURE_CORECLR
-
-#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_CORESYSTEM)
inline BOOL ModuleSecurityDescriptor::IsAPTCA()
{
WRAPPER_NO_CONTRACT;
VerifyDataComputed();
return !!(m_flags & ModuleSecurityDescriptorFlags_IsAPTCA);
}
-#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#endif // defined(FEATURE_CORESYSTEM)
// Get the set of security rules that the assembly is using
inline SecurityRuleSet ModuleSecurityDescriptor::GetSecurityRuleSet()
@@ -1139,12 +1104,6 @@ inline SecurityRuleSet ModuleSecurityDescriptor::GetSecurityRuleSet()
{
return ::GetSecurityRuleSet(tokenFlags);
}
-#ifndef FEATURE_CORECLR
- else if (AssemblyVersionRequiresLegacyTransparency())
- {
- return SecurityRuleSet_Level1;
- }
-#endif // !FEATURE_CORECLR
else
{
// The assembly hasn't specified the rule set that it needs to use. We'll just use the default rule
diff --git a/src/vm/securitypolicy.cpp b/src/vm/securitypolicy.cpp
index fe1da90b8d..a1fb35dbe1 100644
--- a/src/vm/securitypolicy.cpp
+++ b/src/vm/securitypolicy.cpp
@@ -30,66 +30,6 @@ void SecurityProperties::operator delete(void *pMem)
// No action required
}
-#ifdef FEATURE_CAS_POLICY
-
-// static
-CrstStatic SecurityPolicy::s_crstPolicyInit;
-
-// static
-bool SecurityPolicy::s_fPolicyInitialized = false;
-
-void SecurityPolicy::InitPolicyConfig()
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- GCX_PREEMP();
-
- CrstHolder initializePolicy(&s_crstPolicyInit);
-
- if (!s_fPolicyInitialized)
- {
- // Note: These buffers should be at least as big as the longest possible
- // string that will be placed into them by the code below.
- const size_t cchcache = MAX_LONGPATH + sizeof( W("defaultusersecurity.config.cch") ) / sizeof( WCHAR ) + 1;
- const size_t cchconfig = MAX_LONGPATH + sizeof( W("defaultusersecurity.config.cch") ) / sizeof( WCHAR ) + 1;
- NewArrayHolder<WCHAR> cache(new WCHAR[cchcache]);
- NewArrayHolder<WCHAR> config(new WCHAR[cchconfig]);
-
- HRESULT hr = SecurityConfig::GetMachineDirectory(config, MAX_LONGPATH);
- if (FAILED(hr))
- ThrowHR(hr);
-
- wcscat_s( config, cchconfig, W("security.config") );
- wcscpy_s( cache, cchcache, config );
- wcscat_s( cache, cchcache, W(".cch") );
- SecurityConfig::InitData( SecurityConfig::MachinePolicyLevel, config, cache );
-
- hr = SecurityConfig::GetMachineDirectory(config, MAX_LONGPATH);
- if (FAILED(hr))
- ThrowHR(hr);
-
- wcscat_s( config, cchconfig, W("enterprisesec.config") );
- wcscpy_s( cache, cchcache, config );
- wcscat_s( cache, cchcache, W(".cch") );
- SecurityConfig::InitData( SecurityConfig::EnterprisePolicyLevel, config, cache );
-
- BOOL result = SecurityConfig::GetUserDirectory(config, MAX_LONGPATH);
- if (result) {
- wcscat_s( config, cchconfig, W("security.config") );
- wcscpy_s( cache, cchcache, config );
- wcscat_s( cache, cchcache, W(".cch") );
- SecurityConfig::InitData( SecurityConfig::UserPolicyLevel, config, cache );
- }
-
- s_fPolicyInitialized = true;
- }
-}
-#endif // FEATURE_CAS_POLICY
void SecurityPolicy::Start()
{
@@ -109,18 +49,6 @@ void SecurityPolicy::Start()
_ASSERTE(URLZONE_UNTRUSTED == Untrusted);
#endif // !FEATURE_PAL
-#ifdef FEATURE_CAS_POLICY
- s_crstPolicyInit.Init(CrstSecurityPolicyInit);
-
- SecurityConfig::Init();
-
- if (Security::IsProcessWideLegacyCasPolicyEnabled())
- {
- SecurityPolicy::InitPolicyConfig();
- }
-
- g_pCertificateCache = new CertificateCache();
-#endif // FEATURE_CAS_POLICY
}
void SecurityPolicy::Stop()
@@ -134,50 +62,6 @@ void SecurityPolicy::Stop()
}
-#ifdef FEATURE_CAS_POLICY
-void SecurityPolicy::SaveCache()
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM(););
- } CONTRACTL_END;
-
- Thread *pThread = GetThread();
- if (pThread == NULL)
- {
- BOOL fRet = FALSE;
- EX_TRY
- {
- // If CLR is hosted, a host can deny a thread during SetupThread call.
- if (IsShutdownSpecialThread())
- {
- SetupInternalThread();
- }
- else
- {
- SetupThread();
- }
- }
- EX_CATCH
- {
- fRet = TRUE;
- }
- EX_END_CATCH(SwallowAllExceptions);
- if (fRet)
- {
- return;
- }
- }
-
- SecurityConfig::SaveCacheData( SecurityConfig::MachinePolicyLevel );
- SecurityConfig::SaveCacheData( SecurityConfig::UserPolicyLevel );
- SecurityConfig::SaveCacheData( SecurityConfig::EnterprisePolicyLevel );
-
- SecurityConfig::Cleanup();
-}
-#endif
void QCALLTYPE SecurityPolicy::GetGrantedPermissions(QCall::ObjectHandleOnStack retGranted, QCall::ObjectHandleOnStack retDenied, QCall::StackCrawlMarkHandle stackmark)
{
@@ -206,14 +90,6 @@ void QCALLTYPE SecurityPolicy::GetGrantedPermissions(QCall::ObjectHandleOnStack
END_QCALL;
}
-#ifdef FEATURE_IMPERSONATION
-FCIMPL0(DWORD, SecurityPolicy::GetImpersonationFlowMode)
-{
- FCALL_CONTRACT;
- return (g_pConfig->ImpersonationMode());
-}
-FCIMPLEND
-#endif
void SecurityPolicy::CreateSecurityException(__in_z const char *szDemandClass, DWORD dwFlags, OBJECTREF *pThrowable)
{
@@ -228,58 +104,6 @@ void SecurityPolicy::CreateSecurityException(__in_z const char *szDemandClass, D
MethodTable * pMT = MscorlibBinder::GetClass(CLASS__SECURITY_EXCEPTION);
-#ifdef FEATURE_CAS_POLICY
- MethodTable * pMTSecPerm = MscorlibBinder::GetClass(CLASS__SECURITY_PERMISSION);
-
- struct _gc {
- STRINGREF strDemandClass;
- OBJECTREF secPerm;
- STRINGREF strPermState;
- OBJECTREF secPermType;
- OBJECTREF secElement;
- } gc;
- memset(&gc, 0, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.strDemandClass = StringObject::NewString(wszDemandClass);
- if (gc.strDemandClass == NULL) COMPlusThrowOM();
- // Get the type seen by reflection
- gc.secPermType = pMTSecPerm->GetManagedClassObject();
- // Allocate the security exception object
- *pThrowable = AllocateObject(pMT);
- // Allocate the security permission object
- gc.secPerm = AllocateObject(pMTSecPerm);
-
- // Call the construtor with the correct flag
- MethodDescCallSite ctor(METHOD__SECURITY_PERMISSION__CTOR);
- ARG_SLOT arg3[2] = {
- ObjToArgSlot(gc.secPerm),
- (ARG_SLOT)dwFlags
- };
- ctor.Call(arg3);
-
- // Now, get the ToXml method
- MethodDescCallSite toXML(METHOD__SECURITY_PERMISSION__TOXML, &gc.secPerm);
- ARG_SLOT arg4 = ObjToArgSlot(gc.secPerm);
- gc.secElement = toXML.Call_RetOBJECTREF(&arg4);
-
- MethodDescCallSite toString(METHOD__SECURITY_ELEMENT__TO_STRING, &gc.secElement);
- ARG_SLOT arg5 = ObjToArgSlot(gc.secElement);
- gc.strPermState = toString.Call_RetSTRINGREF(&arg5);
-
- MethodDescCallSite exceptionCtor(METHOD__SECURITY_EXCEPTION__CTOR);
-
- ARG_SLOT arg6[4] = {
- ObjToArgSlot(*pThrowable),
- ObjToArgSlot(gc.strDemandClass),
- ObjToArgSlot(gc.secPermType),
- ObjToArgSlot(gc.strPermState),
- };
- exceptionCtor.Call(arg6);
-
- GCPROTECT_END();
-#else // FEATURE_CAS_POLICY
UNREFERENCED_PARAMETER(szDemandClass);
UNREFERENCED_PARAMETER(dwFlags);
@@ -288,7 +112,6 @@ void SecurityPolicy::CreateSecurityException(__in_z const char *szDemandClass, D
*pThrowable = AllocateObject(pMT);
CallDefaultConstructor(*pThrowable);
-#endif // FEATURE_CAS_POLICY
}
DECLSPEC_NORETURN void SecurityPolicy::ThrowSecurityException(__in_z const char *szDemandClass, DWORD dwFlags)
@@ -315,137 +138,6 @@ DECLSPEC_NORETURN void SecurityPolicy::ThrowSecurityException(__in_z const char
GCPROTECT_END();
}
-#ifdef FEATURE_CAS_POLICY
-//-----------------------------------------------------------------------------------------
-//
-// Fire an ETW event to indicate that an evidence object has been generated for an assembly
-//
-// Arguments:
-// type - Type of evidence that was generated
-// pPEFile - PEFile for the assembly the evidence was for
-//
-
-// static
-void SecurityPolicy::TraceEvidenceGeneration(EvidenceType type, PEFile *pPEFile)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pPEFile));
- PRECONDITION(type >= kAssemblySupplied && type <= kZone);
- }
- CONTRACTL_END;
-
- const SString& strPath = pPEFile->GetILimage()->GetPath();
- FireEtwEvidenceGenerated(type,
- GetThread()->GetDomain()->GetId().m_dwId,
- strPath.IsEmpty() ? W("") : strPath.GetUnicode(),
- GetClrInstanceId());
-}
-
-// Called if CAS policy is not enabled, but we either have a host or a simple sandbox domain which will
-// determine the grant set of some evidence.
-OBJECTREF SecurityPolicy::ResolveGrantSet(OBJECTREF evidence, DWORD *pdwSpecialFlags, BOOL fCheckExecutionPermission)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(!GetAppDomain()->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled());
- PRECONDITION(CheckPointer(pdwSpecialFlags));
- }
- CONTRACTL_END;
-
- struct
- {
- OBJECTREF evidence;
- OBJECTREF grantSet;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- gc.evidence = evidence;
-
- GCPROTECT_BEGIN(gc);
-
- MethodDescCallSite resolve(METHOD__SECURITY_ENGINE__RESOLVE_GRANT_SET);
-
- ARG_SLOT args[3];
- args[0] = ObjToArgSlot(gc.evidence);
- args[1] = PtrToArgSlot(pdwSpecialFlags);
- args[2] = BoolToArgSlot(fCheckExecutionPermission);
-
- gc.grantSet = resolve.Call_RetOBJECTREF(args);
-
- GCPROTECT_END();
-
- return gc.grantSet;
-}
-
-// Resolve legacy CAS policy
-OBJECTREF SecurityPolicy::ResolveCasPolicy(OBJECTREF evidence,
- OBJECTREF reqdPset,
- OBJECTREF optPset,
- OBJECTREF denyPset,
- OBJECTREF* grantdenied,
- DWORD* dwSpecialFlags,
- BOOL checkExecutionPermission)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM(););
- PRECONDITION(GetAppDomain()->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled());
- PRECONDITION(SecurityPolicy::s_fPolicyInitialized);
- PRECONDITION(CheckPointer(dwSpecialFlags));
- } CONTRACTL_END;
-
-
- OVERRIDE_TYPE_LOAD_LEVEL_LIMIT(CLASS_LOADED);
-
- // If we got here, then we are going to do at least one security
- // check. Make sure security is initialized.
-
- struct _gc {
- OBJECTREF reqdPset; // Required Requested Permissions
- OBJECTREF optPset; // Optional Requested Permissions
- OBJECTREF denyPset; // Denied Permissions
- OBJECTREF evidence; // Object containing evidence
- OBJECTREF refRetVal;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
- gc.evidence = evidence;
- gc.reqdPset = reqdPset;
- gc.denyPset = denyPset;
- gc.optPset = optPset;
-
- GCPROTECT_BEGIN(gc);
-
- MethodDescCallSite resolvePolicy(METHOD__SECURITY_MANAGER__RESOLVE_CAS_POLICY);
-
- ARG_SLOT args[7];
- args[0] = ObjToArgSlot(gc.evidence);
- args[1] = ObjToArgSlot(gc.reqdPset);
- args[2] = ObjToArgSlot(gc.optPset);
- args[3] = ObjToArgSlot(gc.denyPset);
- args[4] = PtrToArgSlot(grantdenied);
- args[5] = PtrToArgSlot(dwSpecialFlags);
- args[6] = BoolToArgSlot(checkExecutionPermission);
-
- {
- // Elevate thread's allowed loading level. This can cause load failures if assemblies loaded from this point on require
- // any assemblies currently being loaded.
- OVERRIDE_LOAD_LEVEL_LIMIT(FILE_ACTIVE);
- // call policy resolution routine in managed code
- gc.refRetVal = resolvePolicy.Call_RetOBJECTREF(args);
- }
-
- GCPROTECT_END();
- return gc.refRetVal;
-}
-#endif // FEATURE_CAS_POLICY
#endif // CROSSGEN_COMPILE
@@ -501,139 +193,6 @@ BOOL SecurityPolicy::CanCallUnmanagedCode(Module *pModule)
#ifndef CROSSGEN_COMPILE
-#ifdef FEATURE_CAS_POLICY
-SecZone QCALLTYPE SecurityPolicy::CreateFromUrl(LPCWSTR wszUrl)
-{
- QCALL_CONTRACT;
-
- SecZone dwZone = NoZone;
-
- BEGIN_QCALL;
-
- if (wszUrl != NULL)
- {
- dwZone = SecurityPolicy::MapUrlToZone(wszUrl);
- }
-
- END_QCALL;
-
- return dwZone;
-}
-
-HRESULT
-GetSecurityPolicyRegKey(
- __out WCHAR **ppszSecurityPolicy)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- INJECT_FAULT(return E_OUTOFMEMORY);
- }
- CONTRACTL_END;
-
- DWORD dwLen = 0;
-
- HRESULT hr = g_pCLRRuntime->GetVersionString(NULL, &dwLen);
- if (hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- return hr;
-
- size_t bufSize = _countof(FRAMEWORK_REGISTRY_KEY_W) + 1 + dwLen + _countof(KEY_COM_SECURITY_POLICY);
- NewArrayHolder<WCHAR> key(new(nothrow) WCHAR[bufSize]);
- if (key == NULL)
- return E_OUTOFMEMORY;
- wcscpy_s(key, bufSize, FRAMEWORK_REGISTRY_KEY_W W("\\"));
-
- hr = g_pCLRRuntime->GetVersionString(key + NumItems(FRAMEWORK_REGISTRY_KEY_W), &dwLen);
- if (FAILED(hr))
- return hr;
-
- size_t offset = _countof(FRAMEWORK_REGISTRY_KEY_W)+dwLen-1;
- wcscpy_s(key + offset, bufSize - offset, KEY_COM_SECURITY_POLICY);
- key.SuppressRelease();
- *ppszSecurityPolicy = key;
- return S_OK;
-} // GetSecurityPolicyRegKey
-
-HRESULT SecurityPolicy::ApplyCustomZoneOverride(SecZone *pdwZone)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- PRECONDITION(*pdwZone >= NumZones);
- INJECT_FAULT(return E_OUTOFMEMORY);
- }
- CONTRACTL_END;
-
- NewArrayHolder<WCHAR> key(NULL);
- HRESULT hr = GetSecurityPolicyRegKey(&key);
- if (FAILED(hr))
- return hr;
- if (REGUTIL::GetLong(KEY_COM_SECURITY_ZONEOVERRIDE, 0, key, HKEY_POLICY_ROOT) == 1)
- *pdwZone=Internet;
- return S_OK;
-} // ApplyCustomZoneOverride
-
-//---------------------------------------------------------------------------------------
-//
-// Determine which security zone a URL belongs to
-//
-// Arguments:
-// wszUrl - URL to get zone information about
-//
-// Return Value:
-// Security zone the URL belongs to
-//
-// Notes:
-// If the runtime cannot map the URL, we'll return NoZone. A mapping to a zone that the VM doesn't
-// know about will cause us to check the TreatCustomZonesAsInternetZone registry key and potentially
-// map it back to the Internet zone.
-//
-
-// static
-SecZone SecurityPolicy::MapUrlToZone(__in_z LPCWSTR wszUrl)
-{
- CONTRACTL
- {
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(wszUrl != NULL);
- }
- CONTRACTL_END;
-
- SecZone dwZone = NoZone;
-
- ReleaseHolder<IInternetSecurityManager> securityManager = NULL;
- HRESULT hr = CoInternetCreateSecurityManager(NULL, &securityManager, 0);
-
- if (SUCCEEDED(hr))
- {
- _ASSERTE(sizeof(SecZone) == sizeof(DWORD));
- hr = securityManager->MapUrlToZone(wszUrl, reinterpret_cast<DWORD *>(&dwZone), 0);
-
- if (SUCCEEDED(hr))
- {
- // if this is a custom zone, see if the user wants us to map it back to the Internet zone
- if (dwZone >= NumZones)
- {
- SecZone dwMappedZone = dwZone;
- hr = ApplyCustomZoneOverride(&dwMappedZone);
- if (SUCCEEDED(hr))
- {
- dwZone = dwMappedZone;
- }
- }
- }
- else
- {
- dwZone = NoZone;
- }
- }
-
- return dwZone;
-}
-#endif //FEATURE_CAS_POLICY
BOOL QCALLTYPE SecurityPolicy::IsLocalDrive(LPCWSTR wszPath)
{
@@ -790,130 +349,8 @@ void QCALLTYPE SecurityPolicy::GetDeviceName(LPCWSTR wszDriveLetter, QCall::Stri
{
QCALL_CONTRACT;
-#if !defined(FEATURE_CORECLR)
- BEGIN_QCALL;
-
- WCHAR networkName[MAX_LONGPATH];
- DWORD networkNameSize = MAX_LONGPATH;
- ZeroMemory( networkName, sizeof( networkName ) );
-
- UINT driveType = WszGetDriveType( wszDriveLetter );
- if (driveType == DRIVE_REMOVABLE ||
- driveType == DRIVE_FIXED ||
- driveType == DRIVE_CDROM ||
- driveType == DRIVE_RAMDISK)
- {
- retDeviceName.Set( wszDriveLetter );
- goto lExit;
- }
-
- if (WszWNetGetConnection(wszDriveLetter, networkName, &networkNameSize) != NO_ERROR)
- {
- goto lExit;
- }
-
- retDeviceName.Set( networkName );
-
-lExit: ;
-
- END_QCALL;
-#endif // !FEATURE_CORECLR
-}
-
-#ifdef FEATURE_CAS_POLICY
-
-//
-// Fire the ETW event that signals that a specific type of evidence has been created
-//
-// Arguments:
-// pPEFile - PEFile the evidence was generated for
-// type - type of evidence generated
-//
-
-// static
-void QCALLTYPE SecurityPolicy::FireEvidenceGeneratedEvent(PEFile *pPEFile,
- EvidenceType type)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(CheckPointer(pPEFile));
- }
- CONTRACTL_END;
-
- BEGIN_QCALL;
-
- TraceEvidenceGeneration(type, pPEFile);
-
- END_QCALL;
}
-// static
-
-void QCALLTYPE SecurityPolicy::GetEvidence(QCall::AssemblyHandle pAssembly, QCall::ObjectHandleOnStack retEvidence)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
- IAssemblySecurityDescriptor *pSecDesc = pAssembly->GetSecurityDescriptor();
-
- _ASSERTE(pSecDesc->GetDomain() == GetAppDomain());
-
- GCX_COOP();
- if (pSecDesc->IsEvidenceComputed())
- retEvidence.Set(pSecDesc->GetAdditionalEvidence());
- else
- retEvidence.Set(pSecDesc->GetEvidence());
-
- END_QCALL;
-}
-
-//---------------------------------------------------------------------------------------
-//
-// Determine if an evidence collection has a delay generated strong name evidence object
-// which was used during the process of demand evaluation.
-//
-// Arguments:
-// orEvidence - evidence collection to examine
-//
-// Return Value:
-// true if orEvidence contains unverified strong name evidence which has been used to generate a grant,
-// false if orEvidence does not contain strong name evidence or that evidence was verified / not used
-//
-
-// static
-BOOL SecurityPolicy::WasStrongNameEvidenceUsed(OBJECTREF orEvidence)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- // If we don't have any evidence, then there isn't any strong name evidence, and therefore it couldn't
- // have been used.
- if (orEvidence == NULL)
- {
- return FALSE;
- }
-
- BOOL fStrongNameEvidenceWasUsed = FALSE;
-
- GCPROTECT_BEGIN(orEvidence);
-
- MethodDescCallSite wasSnEvidenceUsed(METHOD__EVIDENCE__WAS_STRONGNAME_EVIDENCE_USED);
-
- ARG_SLOT args[] = { ObjToArgSlot(orEvidence) };
- fStrongNameEvidenceWasUsed = !!wasSnEvidenceUsed.Call_RetBool(args);
-
- GCPROTECT_END();
-
- return fStrongNameEvidenceWasUsed;
-}
-#endif // FEATURE_CAS_POLICY
FCIMPL0(void, SecurityPolicy::IncrementOverridesCount)
{
@@ -951,269 +388,7 @@ FCIMPL0(void, SecurityPolicy::DecrementAssertCount)
}
FCIMPLEND
-#ifdef FEATURE_CAS_POLICY
-//
-// Evidence QCalls
-//
-
-//---------------------------------------------------------------------------------------
-//
-// Get the assembly level permission requests
-//
-// Arguments:
-// pAssembly - Assembly to get the declarative security of
-// retMinimumPermissions - [out] RequestMinimum set of the assembly
-// retOptionalPermissions - [out] RequestOptional set of the assembly
-// retRefusedPermissions - [out] RequestRefuse set of the assembly
-//
-
-// static
-void QCALLTYPE SecurityPolicy::GetAssemblyPermissionRequests(QCall::AssemblyHandle pAssembly,
- QCall::ObjectHandleOnStack retMinimumPermissions,
- QCall::ObjectHandleOnStack retOptionalPermissions,
- QCall::ObjectHandleOnStack retRefusedPermissions)
-{
- QCALL_CONTRACT;
-
- BEGIN_QCALL;
-
-
- TraceEvidenceGeneration(kPermissionRequest, pAssembly->GetFile());
- AssemblySecurityDescriptor *pSecurityDescriptor = static_cast<AssemblySecurityDescriptor*>(pAssembly->GetSecurityDescriptor());
-
- _ASSERTE(pSecurityDescriptor->GetDomain()->GetSecurityDescriptor()->IsLegacyCasPolicyEnabled());
-
- struct
- {
- OBJECTREF objMinimumPermissions;
- OBJECTREF objOptionalPermissions;
- OBJECTREF objRefusedPermissions;
- }
- gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCX_COOP();
- GCPROTECT_BEGIN(gc);
-
- gc.objMinimumPermissions = pSecurityDescriptor->GetRequestedPermissionSet(&gc.objOptionalPermissions,
- &gc.objRefusedPermissions);
- retMinimumPermissions.Set(gc.objMinimumPermissions);
- retOptionalPermissions.Set(gc.objOptionalPermissions);
- retRefusedPermissions.Set(gc.objRefusedPermissions);
-
- GCPROTECT_END();
-
- END_QCALL;
-}
-
-//---------------------------------------------------------------------------------------
-//
-// Get the serialized evidence stream from an assembly
-//
-// Arguments:
-// pPEFile - PEFile to load the evidence stream from
-// retSerializedEvidence - [out] contents of the serialized evidence
-//
-
-// static
-void QCALLTYPE SecurityPolicy::GetAssemblySuppliedEvidence(PEFile *pPEFile,
- QCall::ObjectHandleOnStack retSerializedEvidence)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(CheckPointer(pPEFile));
- }
- CONTRACTL_END;
-
- BEGIN_QCALL;
-
- DWORD cbResource;
- BYTE *pbResource;
-
- // Load the resource from the PE file. We do not need to free this memory, since we're getting a direct
- // pointer into the PE contents rather than a buffer.
- TraceEvidenceGeneration(kAssemblySupplied, pPEFile);
- BOOL fFoundSerializedEvidence = pPEFile->GetResource("Security.Evidence",
- &cbResource,
- &pbResource,
- NULL,
- NULL,
- NULL,
- NULL,
- FALSE,
- TRUE,
- NULL,
- NULL);
-
- if (fFoundSerializedEvidence)
- {
- retSerializedEvidence.SetByteArray(pbResource, cbResource);
- }
-
- END_QCALL;
-}
-
-//---------------------------------------------------------------------------------------
-//
-// Get the zone and URL that the PEFile was loaded from
-//
-// Arguments:
-// pPEFile - PEFile to load the evidence stream from
-// pZone - [out] SecurityZone the file was loaded from
-// retUrl - [out] URL the file was loaded from
-
-// static
-void QCALLTYPE SecurityPolicy::GetLocationEvidence(PEFile *pPEFile,
- SecZone *pZone,
- QCall::StringHandleOnStack retUrl)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(CheckPointer(pPEFile));
- }
- CONTRACTL_END;
-
- BEGIN_QCALL;
-
- StackSString ssCodeBase;
- BYTE pbUniqueID[MAX_SIZE_SECURITY_ID];
- DWORD cbUniqueID = COUNTOF(pbUniqueID);
-
- // The location information is used to create Site, Url, and Zone evidence so fire all three events
- TraceEvidenceGeneration(kSite, pPEFile);
- TraceEvidenceGeneration(kUrl, pPEFile);
- TraceEvidenceGeneration(kZone, pPEFile);
-
- pPEFile->GetSecurityIdentity(ssCodeBase, pZone, 0, pbUniqueID, &cbUniqueID);
-
- retUrl.Set(ssCodeBase);
-
- END_QCALL;
-}
-
-//---------------------------------------------------------------------------------------
-//
-// Get the X.509 certificate that the PE file's Authenticode signature was created with
-//
-// Arguments:
-// pPEFile - PEFile to load the evidence stream from
-// retCertificate - [out] certificate that signed the file
-
-// static
-void QCALLTYPE SecurityPolicy::GetPublisherCertificate(PEFile *pPEFile,
- QCall::ObjectHandleOnStack retCertificate)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(CheckPointer(pPEFile));
- }
- CONTRACTL_END;
-
- BEGIN_QCALL;
-
- TraceEvidenceGeneration(kPublisher, pPEFile);
- COR_TRUST *pAuthenticodeSignature = pPEFile->GetAuthenticodeSignature();
- if (pAuthenticodeSignature != NULL && pAuthenticodeSignature->pbSigner != NULL)
- {
- retCertificate.SetByteArray(pAuthenticodeSignature->pbSigner, pAuthenticodeSignature->cbSigner);
- }
-
- END_QCALL;
-}
-
-//---------------------------------------------------------------------------------------
-//
-// Get the components of an assembly's strong name to generate strong name evidence with
-//
-// Arguments:
-// pAssembly - assembly to get the strong name of
-// retPublicKeyBlob - [out] public component of the key the assembly is signed with
-// retSimpleName - [out] simple name of the file
-// piMajorVersion - [out] major version
-// piMinorVersion - [out] minor version
-// piBuild - [out] build
-// piRevision - [out] revision
-//
-// Notes:
-// retPublicKeyBlob will be null for a simply named assembly
-//
-
-// static
-void QCALLTYPE SecurityPolicy::GetStrongNameInformation(QCall::AssemblyHandle pAssembly,
- QCall::ObjectHandleOnStack retPublicKeyBlob,
- QCall::StringHandleOnStack retSimpleName,
- USHORT *piMajorVersion,
- USHORT *piMinorVersion,
- USHORT *piBuild,
- USHORT *piRevision)
-{
- CONTRACTL
- {
- QCALL_CHECK;
- PRECONDITION(CheckPointer(piMajorVersion));
- PRECONDITION(CheckPointer(piMinorVersion));
- PRECONDITION(CheckPointer(piBuild));
- PRECONDITION(CheckPointer(piRevision));
- }
- CONTRACTL_END;
-
- BEGIN_QCALL;
-
- PEAssembly *pPEAssembly = pAssembly->GetFile();
- TraceEvidenceGeneration(kStrongName, pPEAssembly);
-
- DWORD cbPublicKey;
- const BYTE *pbPublicKey = reinterpret_cast<const BYTE*>(pPEAssembly->GetPublicKey(&cbPublicKey));
-
- if (pbPublicKey != NULL && cbPublicKey > 0)
- {
- pPEAssembly->GetVersion(piMajorVersion, piMinorVersion, piBuild, piRevision);
- retPublicKeyBlob.SetByteArray(pbPublicKey, cbPublicKey);
- retSimpleName.Set(pPEAssembly->GetSimpleName());
- }
- else
- {
- GCX_COOP();
- retPublicKeyBlob.Set(NULL);
- }
-
- END_QCALL;
-}
-
-#endif // FEATURE_CAS_POLICY
-
-#ifdef FEATURE_FUSION
-static void GetFusionNameFromAssemblyQualifiedTypeName(LPCWSTR pAssemblyQualifedTypeName, IAssemblyName ** ppFusionName)
-{
- STANDARD_VM_CONTRACT;
-
- StackSString ssAssemblyQualifedTypeName(pAssemblyQualifedTypeName);
- StackSString ssAssemblyName;
-
- SString::Iterator iter = ssAssemblyQualifedTypeName.Begin();
-
- if (ssAssemblyQualifedTypeName.Find( iter, ',' ))
- {
- iter++;
- while (*iter == ' ' )
- iter++;
-
- ssAssemblyName.Set( ssAssemblyQualifedTypeName,
- iter,
- ssAssemblyQualifedTypeName.End() );
-}
-
- StackScratchBuffer sBuffer;
- AssemblySpec spec;
- spec.Init(ssAssemblyName.GetANSI(sBuffer));
-
- IfFailThrow(spec.CreateFusionName(ppFusionName));
-}
-#endif // FEATURE_FUSION
BOOL QCALLTYPE SecurityPolicy::IsSameType(LPCWSTR pLeft, LPCWSTR pRight)
{
@@ -1225,36 +400,7 @@ BOOL QCALLTYPE SecurityPolicy::IsSameType(LPCWSTR pLeft, LPCWSTR pRight)
// @telesto: Is this #ifdef-#else-#endif required anymore? Used to be needed when security was bypassing
// loader and accessing Fusion interfaces. Seems like that's been fixed to use GetFusionNameFrom...
-#ifdef FEATURE_FUSION
-
- AppDomain* pDomain = GetAppDomain();
- IApplicationContext* pAppCtx = pDomain->GetFusionContext();
-
- _ASSERTE( pAppCtx != NULL && "Fusion context not setup yet" );
-
- SafeComHolderPreemp<IAssemblyName> pAssemblyNameLeft;
- SafeComHolderPreemp<IAssemblyName> pAssemblyNameRight;
-
- GetFusionNameFromAssemblyQualifiedTypeName(pLeft, &pAssemblyNameLeft);
- GetFusionNameFromAssemblyQualifiedTypeName(pRight, &pAssemblyNameRight);
-
- SafeComHolderPreemp<IAssemblyName> pAssemblyNamePostPolicyLeft;
- SafeComHolderPreemp<IAssemblyName> pAssemblyNamePostPolicyRight;
-
- if (FAILED(PreBindAssembly(pAppCtx, pAssemblyNameLeft, NULL, &pAssemblyNamePostPolicyLeft, NULL)) ||
- FAILED(PreBindAssembly(pAppCtx, pAssemblyNameRight, NULL, &pAssemblyNamePostPolicyRight, NULL)))
- {
- // version-agnostic comparison.
- bEqual = pAssemblyNameLeft->IsEqual(pAssemblyNameRight, ASM_CMPF_NAME | ASM_CMPF_PUBLIC_KEY_TOKEN | ASM_CMPF_CULTURE) == S_OK;
- }
- else
- {
- // version-agnostic comparison.
- bEqual = pAssemblyNamePostPolicyLeft->IsEqual(pAssemblyNamePostPolicyRight, ASM_CMPF_NAME | ASM_CMPF_PUBLIC_KEY_TOKEN | ASM_CMPF_CULTURE) == S_OK;
- }
-#else // FEATURE_FUSION
bEqual=TRUE;
-#endif // FEATURE_FUSION
END_QCALL;
diff --git a/src/vm/securitypolicy.h b/src/vm/securitypolicy.h
index d22eceb11e..d13ab04eb1 100644
--- a/src/vm/securitypolicy.h
+++ b/src/vm/securitypolicy.h
@@ -17,7 +17,6 @@
#include "fcall.h"
#include "qcall.h"
#include "cgensys.h"
-#include "rwlock.h"
#define SPFLAGSASSERTION 0x01
#define SPFLAGSUNMANAGEDCODE 0x02
@@ -36,9 +35,6 @@ class SystemNative;
class NDirect;
class SystemDomain;
class AssemblySecurityDescriptor;
-#ifndef FEATURE_CORECLR
-class PEFileSecurityDescriptor;
-#endif
class SharedSecurityDescriptor;
class SecurityStackWalkData;
class DemandStackWalk;
@@ -75,14 +71,8 @@ namespace SecurityPolicy
void QCALLTYPE GetGrantedPermissions(QCall::ObjectHandleOnStack retGranted, QCall::ObjectHandleOnStack retDenied, QCall::StackCrawlMarkHandle stackmark);
-#ifdef FEATURE_IMPERSONATION
- FCDECL0(DWORD, GetImpersonationFlowMode);
-#endif // #ifdef FEATURE_IMPERSONATION
FCDECL0(FC_BOOL_RET, IsDefaultThreadSecurityInfo);
-#ifdef FEATURE_CAS_POLICY
- SecZone QCALLTYPE CreateFromUrl(LPCWSTR wszUrl);
-#endif // FEATURE_CAS_POLICY
void QCALLTYPE _GetLongPathName(LPCWSTR wszPath, QCall::StringHandleOnStack retLongPath);
BOOL QCALLTYPE IsLocalDrive(LPCWSTR wszPath);
@@ -97,35 +87,6 @@ namespace SecurityPolicy
FCDECL0(VOID, DecrementAssertCount);
-#ifdef FEATURE_CAS_POLICY
- //
- // Evidence QCalls
- //
-
-//public:
- void QCALLTYPE FireEvidenceGeneratedEvent(PEFile *pPEFile, EvidenceType type);
-
- void QCALLTYPE GetEvidence(QCall::AssemblyHandle pAssembly, QCall::ObjectHandleOnStack retEvidence);
-
- void QCALLTYPE GetAssemblyPermissionRequests(QCall::AssemblyHandle pAssembly,
- QCall::ObjectHandleOnStack retMinimumPermissions,
- QCall::ObjectHandleOnStack retOptionalPermissions,
- QCall::ObjectHandleOnStack retRefusedPermissions);
-
- void QCALLTYPE GetAssemblySuppliedEvidence(PEFile *pPEFile, QCall::ObjectHandleOnStack retSerializedEvidence);
-
- void QCALLTYPE GetLocationEvidence(PEFile *pPEFile, SecZone *pZone, QCall::StringHandleOnStack retUrl);
-
- void QCALLTYPE GetPublisherCertificate(PEFile *pPEFile, QCall::ObjectHandleOnStack retCertificate);
-
- void QCALLTYPE GetStrongNameInformation(QCall::AssemblyHandle pAssembly,
- QCall::ObjectHandleOnStack retPublicKeyBlob,
- QCall::StringHandleOnStack retSimpleName,
- USHORT *piMajorVersion,
- USHORT *piMinorVersion,
- USHORT *piBuild,
- USHORT *piRevision);
-#endif // FEATURE_CAS_POLICY
//private:
// -----------------------------------------------------------
@@ -142,12 +103,6 @@ namespace SecurityPolicy
// <currently unused> @TODO: shouldn't EEShutDownHelper call this?
void Stop();
-#ifdef FEATURE_CAS_POLICY
- // Saves security cache data
- // Callers:
- // EEShutDownHelper
- void SaveCache();
-#endif
// -----------------------------------------------------------
@@ -169,41 +124,9 @@ namespace SecurityPolicy
BOOL CanSkipVerification(DomainAssembly * pAssembly);
-#ifdef FEATURE_CAS_POLICY
- void TraceEvidenceGeneration(EvidenceType type, PEFile *pPEFile);
-
- // Map a URL to a zone, applying any user supplied policy
- SecZone MapUrlToZone(__in_z LPCWSTR wszUrl);
-
- // Apply user supplied policy to a zone
- HRESULT ApplyCustomZoneOverride(SecZone *pdwZone);
-
- // Determine what the grant set of an assembly is
- OBJECTREF ResolveGrantSet(OBJECTREF evidence, OUT DWORD *pdwSpecialFlags, BOOL fcheckExecutionPermission);
-
- // Resolve legacy CAS policy on the assembly
- // Callers:
- // SecurityDescriptor::ResolveWorker
- OBJECTREF ResolveCasPolicy(OBJECTREF evidence,
- OBJECTREF reqdPset,
- OBJECTREF optPset,
- OBJECTREF denyPset,
- OBJECTREF* grantdenied,
- DWORD* pdwSpecialFlags,
- BOOL checkExecutionPermission);
-
- // Load the policy config/cache files at EE startup
- void InitPolicyConfig();
-
- BOOL WasStrongNameEvidenceUsed(OBJECTREF evidence);
-#endif
// Like WszGetLongPathName, but it works with nonexistant files too
size_t GetLongPathNameHelper( const WCHAR* wszShortPath, SString& wszBuffer);
-#ifdef FEATURE_CAS_POLICY
- extern CrstStatic s_crstPolicyInit;
- extern bool s_fPolicyInitialized;
-#endif // FEATURE_CAS_POLICY
}
struct SharedPermissionObjects
diff --git a/src/vm/securitystackwalk.h b/src/vm/securitystackwalk.h
index aa6c1c1e6a..57be57f387 100644
--- a/src/vm/securitystackwalk.h
+++ b/src/vm/securitystackwalk.h
@@ -18,14 +18,7 @@
#include "perfcounters.h"
#include "security.h"
#include "holder.h"
-#ifdef FEATURE_REMOTING
-#include "appdomainhelper.h"
-#endif
-
-#ifdef FEATURE_COMPRESSEDSTACK
-class NewCompressedStack;
-class DomainCompressedStack;
-#endif // FEATURE_COMPRESSEDSTACK
+
class ApplicationSecurityDescriptor;
class DemandStackWalk;
class CountOverridesStackWalk;
@@ -44,9 +37,6 @@ protected:
DWORD m_dwFlags;
public:
-#ifdef FEATURE_REMOTING
- MarshalCache m_objects;
-#else //!FEATURE_REMOTING
struct ObjectCache
{
struct gc
@@ -103,7 +93,6 @@ public:
}
} m_objects;
-#endif //!FEATURE_REMOTING
SecurityStackWalk(SecurityStackWalkType eType, DWORD flags)
{
@@ -169,9 +158,6 @@ public:
// Callers:
// CanAccess (ReflectionInvocation)
// ReflectionSerialization::GetSafeUninitializedObject
-#ifdef FEATURE_APTCA
- // SecurityDeclarative::DoUntrustedCallerChecks
-#endif // FEATURE_APTCA
static void DemandSet(SecurityStackWalkType eType, OBJECTREF demand);
// Native version of PermissionSet.Demand() that delays instantiating the PermissionSet object
@@ -211,25 +197,6 @@ public:
// Compressed Stack
// ----------------------------------------------------
public:
-#ifdef FEATURE_COMPRESSEDSTACK
- static FCDECL2(Object*, EcallGetDelayedCompressedStack, StackCrawlMark* stackMark, CLR_BOOL fWalkStack);
- static FCDECL1(VOID, FcallDestroyDelayedCompressedStack, void *compressedStack);
- static COMPRESSEDSTACKREF GetCSFromContextTransitionFrame(Frame *pFrame);
- static BOOL IsContextTransitionFrameWithCS(Frame *pFrame)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
- return (GetCSFromContextTransitionFrame(pFrame) != NULL);
- }
- static BOOL MethodIsAnonymouslyHostedDynamicMethodWithCSToEvaluate(MethodDesc* pMeth);
-
-#endif // #ifdef FEATURE_COMPRESSEDSTACK
#ifndef DACCESS_COMPILE
FORCEINLINE static BOOL HasFlagsOrFullyTrustedIgnoreMode (DWORD flags);
diff --git a/src/vm/securitytransparentassembly.cpp b/src/vm/securitytransparentassembly.cpp
index be13cab612..b48451f41c 100644
--- a/src/vm/securitytransparentassembly.cpp
+++ b/src/vm/securitytransparentassembly.cpp
@@ -233,20 +233,6 @@ static void ConvertCriticalMethodToLinkDemand(MethodDesc *pCallerMD)
}
CONTRACTL_END;
-#if !defined(CROSSGEN_COMPILE) && defined(FEATURE_CAS_POLICY)
- if (NingenEnabled())
- return;
-
- GCX_COOP();
-
- OBJECTREF permSet = NULL;
- GCPROTECT_BEGIN(permSet);
-
- Security::GetPermissionInstance(&permSet, SECURITY_FULL_TRUST);
- Security::DemandSet(SSWT_LATEBOUND_LINKDEMAND, permSet);
-
- GCPROTECT_END();
-#endif // !CROSSGEN_COMPILE && FEATURE_CAS_POLICY
}
// static
@@ -324,7 +310,6 @@ BOOL SecurityTransparent::CheckCriticalAccess(AccessCheckContext* pContext,
return TRUE;
}
-#ifdef FEATURE_CORECLR
// On the coreCLR, a method can be transparent even if the containing type is marked Critical.
// This will happen when that method is an override of a base transparent method, and the type that
// contains the override is marked Critical. And that's the only case it can happen.
@@ -334,7 +319,6 @@ BOOL SecurityTransparent::CheckCriticalAccess(AccessCheckContext* pContext,
{
return TRUE;
}
-#endif // FEATURE_CORECLR
// an attached profiler may wish to have these checks suppressed
if (Security::BypassSecurityChecksForProfiler(pCurrentMD))
@@ -395,41 +379,9 @@ BOOL SecurityTransparent::IsAllowedToAssert(MethodDesc *pMD)
return TRUE;
}
-#ifdef FEATURE_CORECLR
// On CoreCLR only critical code may ever assert - there are no compatibility reasons to allow
// transparent asserts.
return FALSE;
-#else // !FEATURE_CORECLR
- // We must be in a heterogenous AppDomain for transparent asserts to work
- if (GetAppDomain()->GetSecurityDescriptor()->IsHomogeneous())
- {
- return FALSE;
- }
-
- ModuleSecurityDescriptor *pMSD = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pMD->GetAssembly());
-
- // Only assemblies whose version requires them to use legacy transparency (rather than assemblies which
- // get legacy transparency via RuleSet.Level1) can assert from transparent code
- if (!pMSD->AssemblyVersionRequiresLegacyTransparency())
- {
- return FALSE;
- }
-
- // Finally, the assembly must not have had any of the transparency attributes on it
- const TokenSecurityDescriptorFlags transparencyAwareFlags =
- TokenSecurityDescriptorFlags_AllCritical | // [SecurityCritical(SecurityCriticalScope.All)]
- TokenSecurityDescriptorFlags_Critical | // [SecurityCritical]
- TokenSecurityDescriptorFlags_SafeCritical | // [SecuritySafeCritical]
- TokenSecurityDescriptorFlags_Transparent | // [SecurityTransparent]
- TokenSecurityDescriptorFlags_TreatAsSafe; // [SecurityTreatAsSafe]
- TokenSecurityDescriptorFlags moduleAttributes = pMSD->GetTokenFlags();
- if ((moduleAttributes & transparencyAwareFlags) != TokenSecurityDescriptorFlags_None)
- {
- return FALSE;
- }
-
- return TRUE;
-#endif // FEATURE_CORECLR
}
// Functor class to aid in determining if a type requires a transparency check
@@ -528,40 +480,6 @@ CorInfoCanSkipVerificationResult SecurityTransparent::JITCanSkipVerification(Met
CorInfoCanSkipVerificationResult canSkipVerif = hasSkipVerificationPermisson ? CORINFO_VERIFICATION_CAN_SKIP : CORINFO_VERIFICATION_CANNOT_SKIP;
-#ifndef FEATURE_CORECLR
- // also check to see if the method is marked transparent
- if (hasSkipVerificationPermisson)
- {
- if (pDomainAssembly == GetAppDomain()->GetAnonymouslyHostedDynamicMethodsAssembly())
- {
- // This assembly is FullTrust. However, it cannot contain unverifiable code.
- // The JIT compiler is not hardened to deal with invalid code. Hence, we cannot
- // return CORINFO_VERIFICATION_RUNTIME_CHECK for IL that could have been generated
- // by a low-trust assembly.
- canSkipVerif = CORINFO_VERIFICATION_CANNOT_SKIP;
- }
- // also check to see if the method is marked transparent
- else if (SecurityTransparent::IsMethodTransparent(pMD))
- {
- // If the assembly requested that even its transparent members not be verified, then we can skip
- // verification. Otherwise, we need to either inject a runtime demand in the v2 model, or fail
- // verification in the v4 model.
- ModuleSecurityDescriptor *pModuleSecDesc = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pMD->GetAssembly());
- if (pModuleSecDesc->CanTransparentCodeSkipVerification())
- {
- canSkipVerif = CORINFO_VERIFICATION_CAN_SKIP;
- }
- else if (pMD->GetAssembly()->GetSecurityTransparencyBehavior()->CanTransparentCodeSkipVerification())
- {
- canSkipVerif = CORINFO_VERIFICATION_RUNTIME_CHECK;
- }
- else
- {
- canSkipVerif = CORINFO_VERIFICATION_CANNOT_SKIP;
- }
- }
- }
-#endif //FEATURE_CORECLR
return canSkipVerif;
}
@@ -587,14 +505,6 @@ CorInfoCanSkipVerificationResult SecurityTransparent::JITCanSkipVerification(Dom
{
// In CoreCLR, do not enable transparency checks here. We depend on this method being "honest" in
// JITCanSkipVerification to skip transparency checks on profile assemblies.
-#ifndef FEATURE_CORECLR
- ModuleSecurityDescriptor *pMsd = ModuleSecurityDescriptor::GetModuleSecurityDescriptor(pAssembly->GetAssembly());
- if (pMsd->IsAllTransparent() &&
- pAssembly->GetAssembly()->GetSecurityTransparencyBehavior()->CanTransparentCodeSkipVerification())
- {
- canSkipVerif = CORINFO_VERIFICATION_RUNTIME_CHECK;
- }
-#endif // !FEATURE_CORECLR
}
return canSkipVerif;
@@ -620,34 +530,6 @@ bool SecurityTransparent::SecurityCalloutQuickCheck(MethodDesc *pCallerMD)
// In coreclr, we modified the logic in the callout to also do some transparency method access checks
// These checks need to happen regardless of trust level and we shouldn't be bailing out early
// just because we happen to be in Full Trust
-#ifndef FEATURE_CORECLR
- // See if we need to process this callout for real, or if we can bail out early before setting up a HMF,
- // and spending a lot of time processing the transparency evaluation. The simplest case where we can do
- // this is if the caller is critical. In that case, we know that the caller is allowed to do whatever
- // it wants, so we quit out.
- //
- // Additionally, if the caller is using SecurityRuleSet.Level1, which turns transparency violations into
- // security demands, we can bail out early if we know for sure all demands will succeed on the current
- // call stack. (Note: this remains true as long as we don't start generating callouts for transparent
- // level 1 calling critical level 1, or transparent level 1 doing an assert, which are the only two
- // violations which do not succeed in the face of a successful demand).
- if (pCallerMD->IsCritical())
- {
- return true;
- }
- else
- {
- // The caller is transparent, so let's see if demands can cause transparency violations to succeed,
- // and also if all demands issued from this context will succeed.
- const SecurityTransparencyBehavior *pCallerTransparency = pCallerMD->GetAssembly()->TryGetSecurityTransparencyBehavior();
- if (pCallerTransparency != NULL &&
- pCallerTransparency->CanTransparentCodeCallLinkDemandMethods() &&
- SecurityStackWalk::HasFlagsOrFullyTrustedIgnoreMode(0))
- {
- return true;
- }
- }
-#endif // !FEATURE_CORECLR
return false;
}
@@ -724,44 +606,6 @@ VOID SecurityTransparent::PerformTransparencyChecksForLoadByteArray(MethodDesc*
}
CONTRACTL_END
-#ifdef FEATURE_CAS_POLICY
- GCX_COOP();
- // check to see if the method that does the Load(byte[] ) is transparent
- if (IsMethodTransparent(pCallerMD))
- {
- Assembly* pLoadedAssembly = pLoadedSecDesc->GetAssembly();
- // check to see if the byte[] being loaded is critical, i.e. not Transparent
- if (!ModuleSecurityDescriptor::IsMarkedTransparent(pLoadedAssembly))
- {
- // if transparent code loads a byte[] that is critical, need to inject appropriate demands
- if (pLoadedSecDesc->IsFullyTrusted()) // if the loaded code is full-trust
- {
- // do a full-demand for Full-Trust
- OBJECTREF permSet = NULL;
- GCPROTECT_BEGIN(permSet);
- Security::GetPermissionInstance(&permSet, SECURITY_FULL_TRUST);
- Security::DemandSet(SSWT_LATEBOUND_LINKDEMAND, permSet);
- GCPROTECT_END();// do a full-demand for Full-Trust
- }
- else
- {
- // otherwise inject a Demand for permissions being granted?
- struct _localGC {
- OBJECTREF granted;
- OBJECTREF denied;
- } localGC;
- ZeroMemory(&localGC, sizeof(localGC));
-
- GCPROTECT_BEGIN(localGC);
- {
- localGC.granted = pLoadedSecDesc->GetGrantedPermissionSet(&(localGC.denied));
- Security::DemandSet(SSWT_LATEBOUND_LINKDEMAND, localGC.granted);
- }
- GCPROTECT_END();
- }
- }
- }
-#endif // FEATURE_CAS_POLICY
}
static void ConvertLinkDemandToFullDemand(MethodDesc* pCallerMD, MethodDesc* pCalleeMD)
@@ -812,44 +656,6 @@ static void ConvertLinkDemandToFullDemand(MethodDesc* pCallerMD, MethodDesc* pCa
&gc.refMethodCasDemands,
&gc.refMethodNonCasDemands);
-#ifdef FEATURE_APTCA
- BOOL fCallerIsAPTCA = pCallerMD->GetAssembly()->AllowUntrustedCaller();
-
- if ((linktimeCheckReason & LinktimeCheckReason_AptcaCheck))
- {
- if (fCallerIsAPTCA &&
- Security::IsUntrustedCallerCheckNeeded(pCalleeMD, pCallerMD->GetAssembly()))
- {
-#ifdef _DEBUG
- if (g_pConfig->LogTransparencyErrors())
- {
- SecurityTransparent::LogTransparencyError(pCallerMD, "Transparent method calling an APTCA protected assembly", pCalleeMD);
- }
- if (!g_pConfig->DisableTransparencyEnforcement())
-#endif // _DEBUG
- {
- // Depending on the transparency model, we need to either fail the attempt to call a method
- // protected with the APTCA link demand, or conver it to a full demand. Note that we need to
- // upgrade to a full demand if either the caller of callee are in v2 mode, the APTCA check is
- // conceptually a link demand, and for link demands we do the conversion if either assembly is
- // using the v2 rules.
- if (pCallerMD->GetAssembly()->GetSecurityTransparencyBehavior()->CanTransparentCodeCallLinkDemandMethods() ||
- pCalleeMD->GetAssembly()->GetSecurityTransparencyBehavior()->CanTransparentCodeCallLinkDemandMethods())
- {
- OBJECTREF permSet = NULL;
- GCPROTECT_BEGIN(permSet);
- Security::GetPermissionInstance(&permSet, SECURITY_FULL_TRUST);
- Security::DemandSet(SSWT_LATEBOUND_LINKDEMAND, permSet);
- GCPROTECT_END();
- }
- else
- {
- ::ThrowMethodAccessException(pCallerMD, pCalleeMD, FALSE, IDS_E_TRANSPARENT_CALL_LINKDEMAND);
- }
- }
- }
- }
-#endif // FEATURE_APTCA
// The following logic turns link demands on the target method into full stack walks
@@ -905,15 +711,6 @@ static void ConvertLinkDemandToFullDemand(MethodDesc* pCallerMD, MethodDesc* pCa
if (pCallerMD->GetAssembly()->GetSecurityTransparencyBehavior()->CanTransparentCodeCallUnmanagedCode())
{
-#ifdef FEATURE_APTCA
- if (fCallerIsAPTCA)
- {
- // if the caller assembly is APTCA, then only inject this demand, for NON-APTCA we will allow
- // calls to native code
- // NOTE: the JIT would have already performed the LinkDemand for this anyways
- Security::SpecialDemand(SSWT_LATEBOUND_LINKDEMAND, SECURITY_UNMANAGED_CODE);
- }
-#endif // FEATURE_APTCA
}
else
{
@@ -994,7 +791,6 @@ VOID SecurityTransparent::EnforceTransparentDelegateChecks(MethodTable* pDelegat
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
// We only enforce delegate binding rules in partial trust
if (GetAppDomain()->GetSecurityDescriptor()->IsFullyTrusted())
return;
@@ -1005,7 +801,6 @@ VOID SecurityTransparent::EnforceTransparentDelegateChecks(MethodTable* pDelegat
TypeString::AppendType(strDelegateType, pDelegateMT, TypeString::FormatNamespace | TypeString::FormatAngleBrackets| TypeString::FormatSignature);
COMPlusThrowHR(COR_E_METHODACCESS, IDS_E_DELEGATE_BINDING_TRANSPARENCY, strDelegateType.GetUnicode(), strMethod.GetUnicode());
-#endif // FEATURE_CORECLR
}
#endif // CROSSGEN_COMPILE
@@ -1443,12 +1238,12 @@ public:
ModuleSecurityDescriptorFlags moduleFlags = ModuleSecurityDescriptorFlags_None;
-#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_CORESYSTEM)
if (tokenFlags & TokenSecurityDescriptorFlags_APTCA)
{
moduleFlags |= ModuleSecurityDescriptorFlags_IsAPTCA;
}
-#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
+#endif // defined(FEATURE_CORESYSTEM)
if (tokenFlags & TokenSecurityDescriptorFlags_Critical)
{
@@ -1531,202 +1326,6 @@ public:
}
};
-#ifndef FEATURE_CORECLR
-
-//---------------------------------------------------------------------------------------
-//
-// Transparency behavior implementation for v2 assemblies
-//
-
-class LegacyTransparencyBehaviorImpl : public ISecurityTransparencyImpl
-{
-public:
- // Get bits that indicate how transparency should behave in different situations
- virtual SecurityTransparencyBehaviorFlags GetBehaviorFlags() const
- {
- LIMITED_METHOD_CONTRACT;
- return SecurityTransparencyBehaviorFlags_IntroducedCriticalsMayAddTreatAsSafe |
- SecurityTransparencyBehaviorFlags_OpportunisticIsSafeCriticalMethods |
- SecurityTransparencyBehaviorFlags_PartialTrustImpliesAllTransparent |
- SecurityTransparencyBehaviorFlags_PublicImpliesTreatAsSafe |
- SecurityTransparencyBehaviorFlags_TransparentCodeCanCallLinkDemand |
- SecurityTransaprencyBehaviorFlags_TransparentCodeCanCallUnmanagedCode |
- SecurityTransparencyBehaviorFlags_TransparentCodeCanSkipVerification |
- SecurityTransparencyBehaviorFlags_UnsignedImpliesAPTCA;
- }
-
- // Legacy transparency field behavior mappings:
- // Attribute Behavior
- // -----------------------------------------------------
- // Critical (any) Critical
- // SafeCritical Safe critical
- // TAS (no critical) No effect
- // TAS (with any critical) Safe critical
- virtual FieldSecurityDescriptorFlags MapFieldAttributes(TokenSecurityDescriptorFlags tokenFlags) const
- {
- WRAPPER_NO_CONTRACT;
-
- // Legacy transparency behaves the same for fields as the current transparency model, so we just forward
- // this call to that implementation.
- TransparencyBehaviorImpl forwardImpl;
- return forwardImpl.MapFieldAttributes(tokenFlags);
- }
-
-
- // Legacy transparency method behavior mappings:
- // Attribute Behavior
- // -----------------------------------------------------
- // Critical (any) Critical
- // SafeCritical Safe critical
- // TAS (no critical) No effect
- // TAS (with any critical) Safe critical
- virtual MethodSecurityDescriptorFlags MapMethodAttributes(TokenSecurityDescriptorFlags tokenFlags) const
- {
- WRAPPER_NO_CONTRACT;
-
- // Legacy transparency behaves the same for methods as the current transparency model, so we just forward
- // this call to that implementation.
- TransparencyBehaviorImpl forwardImpl;
- return forwardImpl.MapMethodAttributes(tokenFlags);
- }
-
- // Legacy transparency module behavior mappings:
- // Attribute Behavior
- // -----------------------------------------------------
- // APTCA APTCA
- // ConditionlAPTCA Exception
- // Critical (scoped) Mixed transparency
- // Critical (all) All critical
- // SafeCritical All safe critical
- // TAS (no critical) No effect
- // TAS (with scoped critical) No effect
- // TAS (with all critical) All safe critical
- // Transparent All transparent
- //
- // Having no transparent, critical, or safe critical attributes means that the assembly should have all
- // transparent types and all safe critical methods.
- virtual ModuleSecurityDescriptorFlags MapModuleAttributes(TokenSecurityDescriptorFlags tokenFlags) const
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- SO_INTOLERANT;
- }
- CONTRACTL_END;
-
- ModuleSecurityDescriptorFlags moduleFlags = ModuleSecurityDescriptorFlags_None;
- bool fShouldBeOpportunisticallyCritical = true;
-
-#if defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
- if (tokenFlags & TokenSecurityDescriptorFlags_APTCA)
- {
- moduleFlags |= ModuleSecurityDescriptorFlags_IsAPTCA;
- }
-#endif // defined(FEATURE_APTCA) || defined(FEATURE_CORESYSTEM)
-
- if (tokenFlags & TokenSecurityDescriptorFlags_Transparent)
- {
- moduleFlags |= ModuleSecurityDescriptorFlags_IsAllTransparent;
- fShouldBeOpportunisticallyCritical = false;
- }
-
- if (tokenFlags & TokenSecurityDescriptorFlags_Critical)
- {
- fShouldBeOpportunisticallyCritical = false;
-
- // If we're critical, but not all critical that means we're mixed.
- if (tokenFlags & TokenSecurityDescriptorFlags_AllCritical)
- {
- moduleFlags |= ModuleSecurityDescriptorFlags_IsAllCritical;
-
- // If we're all critical and treat as safe, that means we're safe critical
- if (tokenFlags & TokenSecurityDescriptorFlags_TreatAsSafe)
- {
- moduleFlags |= ModuleSecurityDescriptorFlags_IsTreatAsSafe;
- }
- }
- }
-
- // SafeCritical always means Critical + TreatAsSafe; we can get in this case for legacy assemblies if the
- // assembly is actually a v4 assembly which is using the Legacy attribute.
- if (tokenFlags & TokenSecurityDescriptorFlags_SafeCritical)
- {
- moduleFlags |= ModuleSecurityDescriptorFlags_IsAllCritical |
- ModuleSecurityDescriptorFlags_IsTreatAsSafe;
- fShouldBeOpportunisticallyCritical = false;
- }
-
- // If we didn't find an attribute that indicates the assembly cares about transparency, then it is
- // opportunistically critical.
- if (fShouldBeOpportunisticallyCritical)
- {
- _ASSERTE(!(moduleFlags & ModuleSecurityDescriptorFlags_IsAllTransparent));
- _ASSERTE(!(moduleFlags & ModuleSecurityDescriptorFlags_IsAllCritical));
-
- moduleFlags |= ModuleSecurityDescriptorFlags_IsOpportunisticallyCritical;
- }
-
- // If the token asks to not have IL verification done in full trust, propigate that to the module
- if (tokenFlags & TokenSecurityDescriptorFlags_SkipFullTrustVerification)
- {
- moduleFlags |= ModuleSecurityDescriptorFlags_SkipFullTrustVerification;
- }
-
- return moduleFlags;
- }
-
- // Legacy transparency type behavior mappings:
- // Attribute Behavior
- // -----------------------------------------------------
- // Critical (scoped) Critical, but not all critical
- // Critical (all) All critical
- // SafeCritical All safe critical
- // TAS (no critical) No effect on the type, but save TAS bit for members of the type
- // TAS (with scoped critical) SafeCritical, but not all critical
- // TAS (with all critical) All SafeCritical
- virtual TypeSecurityDescriptorFlags MapTypeAttributes(TokenSecurityDescriptorFlags tokenFlags) const
- {
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- SO_INTOLERANT;
- }
- CONTRACTL_END;
-
- TypeSecurityDescriptorFlags typeFlags = TypeSecurityDescriptorFlags_None;
-
- if (tokenFlags & TokenSecurityDescriptorFlags_Critical)
- {
- typeFlags |= TypeSecurityDescriptorFlags_IsCritical;
-
- // We only consider all critical if the critical attribute was present
- if (tokenFlags & TokenSecurityDescriptorFlags_AllCritical)
- {
- typeFlags |= TypeSecurityDescriptorFlags_IsAllCritical;
- }
- }
-
- // SafeCritical always means all critical + TAS
- if (tokenFlags & TokenSecurityDescriptorFlags_SafeCritical)
- {
- typeFlags |= TypeSecurityDescriptorFlags_IsCritical |
- TypeSecurityDescriptorFlags_IsAllCritical |
- TypeSecurityDescriptorFlags_IsTreatAsSafe;
- }
-
- if (tokenFlags & TokenSecurityDescriptorFlags_TreatAsSafe)
- {
- typeFlags |= TypeSecurityDescriptorFlags_IsTreatAsSafe;
- }
-
- return typeFlags;
- }
-};
-
-#endif // !FEATURE_CORECLR
-
//
// Shared transparency behavior objects
//
@@ -1771,13 +1370,6 @@ const SecurityTransparencyBehavior *GetOrCreateTransparencyBehavior(SecurityTran
// static
SecurityTransparencyBehavior *SecurityTransparencyBehavior::s_pStandardTransparencyBehavior = NULL;
-#ifndef FEATURE_CORECLR
-
-// Transpraency behavior object for v2 transparent assemblies
-// static
-SecurityTransparencyBehavior *SecurityTransparencyBehavior::s_pLegacyTransparencyBehavior = NULL;
-
-#endif // !FEATURE_CORECLR
//---------------------------------------------------------------------------------------
//
@@ -1800,14 +1392,6 @@ const SecurityTransparencyBehavior *SecurityTransparencyBehavior::GetTransparenc
}
CONTRACT_END;
-#ifndef FEATURE_CORECLR
- if (ruleSet == SecurityRuleSet_Level1)
- {
- // Level 1 rules - v2.0 behavior
- RETURN(GetOrCreateTransparencyBehavior<LegacyTransparencyBehaviorImpl>(&s_pLegacyTransparencyBehavior));
- }
- else
-#endif // FEATURE_CORECLR;
{
// Level 2 rules - v4.0 behavior
RETURN(GetOrCreateTransparencyBehavior<TransparencyBehaviorImpl>(&s_pStandardTransparencyBehavior));
diff --git a/src/vm/sha1.h b/src/vm/sha1.h
index 0dd70f64a7..23ea8d2c3e 100644
--- a/src/vm/sha1.h
+++ b/src/vm/sha1.h
@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
//
-#if defined(FEATURE_CORECLR)
#ifndef SHA1_H_
#define SHA1_H_
@@ -49,6 +48,3 @@ public:
};
#endif // SHA1_H_
-#else // !defined(FEATURE_CORECLR)
-#include "crypto/sha1.h"
-#endif // defined(FEATURE_CORECLR)
diff --git a/src/vm/spinlock.cpp b/src/vm/spinlock.cpp
index de5894ee87..d82661dca5 100644
--- a/src/vm/spinlock.cpp
+++ b/src/vm/spinlock.cpp
@@ -37,9 +37,6 @@ SpinLock::SpinLock()
STATIC_CONTRACT_NOTHROW;
STATIC_CONTRACT_GC_NOTRIGGER;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- m_hostLock = NULL;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
m_Initialized = UnInitialized;
}
@@ -53,12 +50,6 @@ SpinLock::~SpinLock()
}
CONTRACTL_END;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (CLRSyncHosted() && m_hostLock) {
- m_hostLock->Release();
- m_hostLock = NULL;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
void SpinLock::Init(LOCK_TYPE type, bool RequireCoopGC)
@@ -70,24 +61,6 @@ void SpinLock::Init(LOCK_TYPE type, bool RequireCoopGC)
}
CONTRACTL_END;
- // Disallow creation of locks before EE starts. But only complain if we end up
- // being hosted, since such locks have escaped the hosting net and will cause
- // AVs on next use.
-#ifdef _DEBUG
- static bool fEarlyInit; // = false
-
- if (!(g_fEEStarted || g_fEEInit))
- {
- if (!CLRSyncHosted())
- fEarlyInit = true;
- }
-
- // If we are now hosted, we better not have *ever* created some locks that are
- // not known to our host.
- _ASSERTE(!fEarlyInit || !CLRSyncHosted());
-
-#endif
-
if (m_Initialized == Initialized)
{
_ASSERTE (type == m_LockType);
@@ -115,26 +88,6 @@ void SpinLock::Init(LOCK_TYPE type, bool RequireCoopGC)
}
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSyncManager *pManager = CorHost2::GetHostSyncManager();
- _ASSERTE((pManager == NULL && m_lock == 0) ||
- (pManager && m_hostLock == NULL));
-
- if (pManager)
- {
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->CreateCrst(&m_hostLock);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (hr != S_OK) {
- _ASSERTE (hr == E_OUTOFMEMORY);
- _ASSERTE (m_Initialized == BeingInitialized);
- m_Initialized = UnInitialized;
- ThrowOutOfMemory();
- }
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
m_lock = 0;
}
@@ -196,19 +149,6 @@ void SpinLock::GetLock(Thread* pThread)
dbg_PreEnterLock();
#endif
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (CLRSyncHosted())
- {
- DWORD option = WAIT_NOTINDEADLOCK;
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(pThread);
- hr = m_hostLock->Enter(option);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- _ASSERTE(hr == S_OK);
- EE_LOCK_TAKEN(this);
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
// Not CLR Sync hosted, so we use interlocked operations on
// m_lock to acquire the lock. This will automatically cause
@@ -241,25 +181,6 @@ BOOL SpinLock::GetLockNoWait()
}
CONTRACTL_END;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (CLRSyncHosted())
- {
- BOOL result;
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = m_hostLock->TryEnter(WAIT_NOTINDEADLOCK, &result);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- _ASSERTE(hr == S_OK);
-
- if (result)
- {
- EE_LOCK_TAKEN(this);
- }
-
- return result;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
if (VolatileLoad(&m_lock) == 0 && FastInterlockExchange (&m_lock, 1) == 0)
{
@@ -292,17 +213,6 @@ void SpinLock::FreeLock(Thread* pThread)
dbg_LeaveLock();
#endif
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (CLRSyncHosted())
- {
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(pThread);
- hr = m_hostLock->Leave();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- _ASSERTE (hr == S_OK);
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
VolatileStore(&m_lock, (LONG)0);
}
@@ -331,8 +241,6 @@ SpinLock::SpinToAcquire()
}
CONTRACTL_END;
- _ASSERTE (!CLRSyncHosted());
-
DWORD backoffs = 0;
ULONG ulSpins = 0;
diff --git a/src/vm/spinlock.h b/src/vm/spinlock.h
index 23a9c47760..f576f6cc15 100644
--- a/src/vm/spinlock.h
+++ b/src/vm/spinlock.h
@@ -153,9 +153,6 @@ private:
union {
// m_lock has to be the fist data member in the class
LONG m_lock; // LONG used in interlocked exchange
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostCrst *m_hostLock;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
};
enum SpinLockState
@@ -210,24 +207,14 @@ public:
static void AcquireLock(SpinLock *s, Thread * pThread);
static void ReleaseLock(SpinLock *s, Thread * pThread);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-#define SPINLOCK_THREAD_PARAM_ONLY_IN_SOME_BUILDS m_pThread
-#else
#define SPINLOCK_THREAD_PARAM_ONLY_IN_SOME_BUILDS NULL
-#endif
class Holder
{
SpinLock * m_pSpinLock;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- Thread * m_pThread;
-#endif
public:
Holder(SpinLock * s) :
m_pSpinLock(s)
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- , m_pThread(GetThread())
-#endif
{
SCAN_SCOPE_BEGIN;
STATIC_CONTRACT_GC_NOTRIGGER;
diff --git a/src/vm/stackbuildersink.cpp b/src/vm/stackbuildersink.cpp
deleted file mode 100644
index 2e363f2802..0000000000
--- a/src/vm/stackbuildersink.cpp
+++ /dev/null
@@ -1,702 +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.
-//
-// File: StackBuilderSink.cpp
-//
-
-//
-// Purpose: Native implementation for System.Runtime.Remoting.Messaging.StackBuilderSink
-//
-
-
-#include "common.h"
-
-#ifdef FEATURE_REMOTING
-
-#include "excep.h"
-#include "message.h"
-#include "stackbuildersink.h"
-#include "dbginterface.h"
-#include "remoting.h"
-#include "profilepriv.h"
-#include "class.h"
-
-struct ArgInfo
-{
- PBYTE dataLocation;
- INT32 dataSize;
- TypeHandle dataTypeHandle;
- BYTE dataType;
- BYTE byref;
-};
-
-
-//+----------------------------------------------------------------------------
-//
-// Method: CStackBuilderSink::PrivateProcessMessage, public
-//
-// Synopsis: Builds the stack and calls an object
-//
-//
-//+----------------------------------------------------------------------------
-FCIMPL5(Object*, CStackBuilderSink::PrivateProcessMessage,
- Object* pSBSinkUNSAFE,
- MethodDesc* pMD,
- PTRArray* pArgsUNSAFE,
- Object* pServerUNSAFE,
- PTRARRAYREF* ppVarOutParams)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(pMD));
- PRECONDITION(!pMD->IsGenericMethodDefinition());
- PRECONDITION(pMD->IsRuntimeMethodHandle());
- }
- CONTRACTL_END;
-
- struct _gc
- {
- PTRARRAYREF pArgs;
- OBJECTREF pServer;
- OBJECTREF pSBSink;
- OBJECTREF ret;
- } gc;
- gc.pArgs = (PTRARRAYREF) pArgsUNSAFE;
- gc.pServer = (OBJECTREF) pServerUNSAFE;
- gc.pSBSink = (OBJECTREF) pSBSinkUNSAFE;
- gc.ret = NULL;
-
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
-
- // pMD->IsStatic() is SO_INTOLERANT.
- // Either pServer is non-null or the method is static (but not both)
- _ASSERTE( (pServerUNSAFE!=NULL) == !(pMD->IsStatic()) );
-
- LOG((LF_REMOTING, LL_INFO10, "CStackBuilderSink::PrivateProcessMessage\n"));
-
- MethodDesc *pResolvedMD = pMD;
- // Check if this is an interface invoke, if yes, then we have to find the
- // real method descriptor on the class of the server object.
- if(pMD->GetMethodTable()->IsInterface())
- {
- _ASSERTE(gc.pServer != NULL);
-
- // NOTE: This method can trigger GC
- // The last parameter (true) causes the method to take into account that
- // the object passed in is a TP and try to resolve the interface MD into
- // a server MD anyway (normally the call short circuits thunking objects
- // and just returns the interface MD unchanged).
- MethodTable *pRealMT = gc.pServer->GetTrueMethodTable();
-
-#ifdef FEATURE_COMINTEROP
- if (pRealMT->IsComObjectType())
- pResolvedMD = pRealMT->GetMethodDescForComInterfaceMethod(pMD, true);
- else
-#endif // FEATURE_COMINTEROP
- {
- if (pRealMT->ImplementsInterface(pMD->GetMethodTable()))
- {
- pResolvedMD = pRealMT->GetMethodDescForInterfaceMethod(TypeHandle(pMD->GetMethodTable()), pMD);
-
- // If the method is generic then we have more work to do --
- // we'll get back the generic method descriptor and we'll have
- // to load the version with the right instantiation (get the
- // instantiation from the interface method).
- if (pResolvedMD->HasMethodInstantiation())
- {
- _ASSERTE(pResolvedMD->IsGenericMethodDefinition());
- _ASSERTE(pMD->GetNumGenericMethodArgs() == pResolvedMD->GetNumGenericMethodArgs());
-
- pResolvedMD = MethodDesc::FindOrCreateAssociatedMethodDesc(pResolvedMD,
- pRealMT,
- FALSE,
- pMD->GetMethodInstantiation(),
- FALSE);
-
- _ASSERTE(!pResolvedMD->ContainsGenericVariables());
- }
- }
- else
- pResolvedMD = NULL;
- }
-
- if(!pResolvedMD)
- {
- MAKE_WIDEPTR_FROMUTF8(wName, pMD->GetName());
- COMPlusThrow(kMissingMethodException, IDS_EE_MISSING_METHOD, wName);
- }
- }
-
- // <TODO>This looks a little dodgy for generics: pResolvedMD has been interface-resolved but not
- // virtual-resolved. So we seem to be taking the signature of a
- // half-resolved-virtual-call. But the MetaSig
- // is only used for GC purposes, and thus is probably OK: although the
- // metadata for the signature of a call may be different
- // as we move to base classes, the instantiated version
- // of the signature will still be the same
- // at both the callsite and the target). </TODO>
- MetaSig mSig(pResolvedMD);
-
- // get the target depending on whether the method is virtual or non-virtual
- // like a constructor, private or final method
- PCODE pTarget = pResolvedMD->GetCallTarget(&(gc.pServer));
-
- VASigCookie *pCookie = NULL;
- _ASSERTE(NULL != pTarget);
-
- // this function does the work
- ::CallDescrWithObjectArray(
- gc.pServer,
- pResolvedMD,
- //pRM,
- pTarget,
- &mSig,
- pCookie,
- gc.pArgs,
- &gc.ret,
- ppVarOutParams);
-
- LOG((LF_REMOTING, LL_INFO10, "CStackBuilderSink::PrivateProcessMessage OUT\n"));
-
- HELPER_METHOD_FRAME_END();
-
- return OBJECTREFToObject(gc.ret);
-}
-FCIMPLEND
-
-class ProfilerServerCallbackHolder
-{
-public:
- ProfilerServerCallbackHolder(Thread* pThread) : m_pThread(pThread)
- {
-#ifdef PROFILING_SUPPORTED
- // If we're profiling, notify the profiler that we're about to invoke the remoting target
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackRemoting());
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->RemotingServerInvocationStarted();
- END_PIN_PROFILER();
- }
-#endif // PROFILING_SUPPORTED
- }
-
- ~ProfilerServerCallbackHolder()
- {
-#ifdef PROFILING_SUPPORTED
- // If profiling is active, tell profiler we've made the call, received the
- // return value, done any processing necessary, and now remoting is done.
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackRemoting());
- GCX_PREEMP();
- g_profControlBlock.pProfInterface->RemotingServerInvocationReturned();
- END_PIN_PROFILER();
- }
-#endif // PROFILING_SUPPORTED
- }
-
-private:
- Thread* m_pThread;
-};
-
-//+----------------------------------------------------------------------------
-//
-// Function: CallDescrWithObjectArray, private
-//
-// Synopsis: Builds the stack from a object array and call the object
-//
-//
-// Note this function triggers GC and assumes that pServer, pArguments, pVarRet, and ppVarOutParams are
-// all already protected!!
-//+----------------------------------------------------------------------------
-void CallDescrWithObjectArray(OBJECTREF& pServer,
- //ReflectMethod *pRM,
- MethodDesc *pMeth,
- PCODE pTarget,
- MetaSig* sig,
- VASigCookie *pCookie,
- PTRARRAYREF& pArgArray,
- OBJECTREF *pVarRet,
- PTRARRAYREF *ppVarOutParams)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM());
- }
- CONTRACTL_END;
-
- LOG((LF_REMOTING, LL_INFO10, "CallDescrWithObjectArray IN\n"));
-
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:6263) // "Suppress PREFast warning about _alloca in a loop"
- // _alloca is called within a loop in a number of places within this method
- // (as an ultra fast means of acquiring temporary storage). This can be a
- // problem in some scenarios (swiftly drive us to stack overflow). But in
- // this case the allocations are tightly bounded (by the number of arguments
- // in the target method) and the allocations themselves are small (no worse
- // really than calling the method an extra time).
-#endif
-
- ByRefInfo *pByRefs = NULL;
- FrameWithCookie<ProtectValueClassFrame> *pProtectValueClassFrame = NULL;
- FrameWithCookie<ProtectByRefsFrame> *pProtectionFrame = NULL;
- UINT nStackBytes = 0;
- LPBYTE pAlloc = 0;
- LPBYTE pTransitionBlock = 0;
- UINT32 numByRef = 0;
- //DWORD attr = pRM->dwFlags;
-#ifdef _DEBUG
- //MethodDesc *pMD = pRM->pMethod;
-#endif
- ValueClassInfo *pValueClasses = NULL;
-
- // check the calling convention
-
- BYTE callingconvention = sig->GetCallingConvention();
- if (!isCallConv(callingconvention, IMAGE_CEE_CS_CALLCONV_DEFAULT))
- {
- _ASSERTE(!"This calling convention is not supported.");
- COMPlusThrow(kInvalidProgramException);
- }
-
- // Make sure we are properly loaded
- CONSISTENCY_CHECK(GetAppDomain()->CheckCanExecuteManagedCode(pMeth));
-
- // Note this is redundant with the above but we do it anyway for safety
- pMeth->EnsureActive();
-
-#ifdef DEBUGGING_SUPPORTED
- // debugger goo What does this do? can someone put a comment here?
- if (CORDebuggerTraceCall())
- {
- g_pDebugInterface->TraceCall((const BYTE *)pTarget);
- }
-#endif // DEBUGGING_SUPPORTED
-
- Thread * pThread = GetThread();
-
- {
- ProfilerServerCallbackHolder profilerHolder(pThread);
-
- ArgIterator argit(sig);
-
- // Create a fake FramedMethodFrame on the stack.
- nStackBytes = argit.SizeOfFrameArgumentArray();
-
- UINT32 cbAlloc = 0;
- if (!ClrSafeInt<UINT32>::addition(TransitionBlock::GetNegSpaceSize(), sizeof(TransitionBlock), cbAlloc))
- COMPlusThrow(kArgumentException);
- if (!ClrSafeInt<UINT32>::addition(cbAlloc, nStackBytes, cbAlloc))
- COMPlusThrow(kArgumentException);
-
- pAlloc = (LPBYTE)_alloca(cbAlloc);
- pTransitionBlock = pAlloc + TransitionBlock::GetNegSpaceSize();
-
- // cycle through the parameters and see if there are byrefs
- BOOL fHasByRefs = FALSE;
-
- //if (attr & RM_ATTR_BYREF_FLAG_SET)
- // fHasByRefs = attr & RM_ATTR_HAS_BYREF_ARG;
- //else
- {
- sig->Reset();
- CorElementType typ;
- while ((typ = sig->NextArg()) != ELEMENT_TYPE_END)
- {
- if (typ == ELEMENT_TYPE_BYREF)
- {
- fHasByRefs = TRUE;
- //attr |= RM_ATTR_HAS_BYREF_ARG;
- break;
- }
- }
- //attr |= RM_ATTR_BYREF_FLAG_SET;
- //pRM->dwFlags = attr;
- sig->Reset();
- }
-
- UINT32 nFixedArgs = sig->NumFixedArgs();
- // To avoid any security problems with integer overflow/underflow we're
- // going to validate the number of args here (we're about to _alloca an
- // array of ArgInfo structures and maybe a managed object array as well
- // based on this count).
- _ASSERTE(sizeof(Object*) <= sizeof(ArgInfo));
- UINT32 nMaxArgs = UINT32_MAX / sizeof(ArgInfo);
- if (nFixedArgs > nMaxArgs)
- COMPlusThrow(kArgumentException);
-
- // if there are byrefs allocate and array for the out parameters
- if (fHasByRefs)
- {
- *ppVarOutParams = PTRARRAYREF(AllocateObjectArray(sig->NumFixedArgs(), g_pObjectClass));
-
- // Null out the array
- memset(&(*ppVarOutParams)->m_Array, 0, sizeof(OBJECTREF) * sig->NumFixedArgs());
- }
-
- OBJECTREF *ppThis = NULL;
-
- if (sig->HasThis())
- {
- ppThis = (OBJECTREF*)(pTransitionBlock + argit.GetThisOffset());
-
- // *ppThis is not GC protected. It will be set to the right value
- // after all object allocations are made.
- *ppThis = NULL;
- }
-
- // if we have the Value Class return, we need to allocate that class and place a pointer to it on the stack.
-
- *pVarRet = NULL;
- TypeHandle retType = sig->GetRetTypeHandleThrowing();
- // Note that we want the unnormalized (signature) type because GetStackObject
- // boxes as the element type, which if we normalized it would loose information.
- CorElementType retElemType = sig->GetReturnType();
-
- // The MethodTable pointer of the return type, if that's a struct
- MethodTable* pStructRetTypeMT = NULL;
-
- // Allocate a boxed struct instance to hold the return value in any case.
- if (retElemType == ELEMENT_TYPE_VALUETYPE)
- {
- pStructRetTypeMT = retType.GetMethodTable();
- *pVarRet = pStructRetTypeMT->Allocate();
- }
- else {
- _ASSERTE(!argit.HasRetBuffArg());
- }
-
-#ifdef CALLDESCR_REGTYPEMAP
- UINT64 dwRegTypeMap = 0;
- BYTE* pMap = (BYTE*)&dwRegTypeMap;
-#endif // CALLDESCR_REGTYPEMAP
-
-#ifdef CALLDESCR_FPARGREGS
- FloatArgumentRegisters *pFloatArgumentRegisters = NULL;
-#endif // CALLDESCR_FPARGREGS
-
- // gather data about the parameters by iterating over the sig:
- UINT32 arg = 0;
- int ofs = 0;
-
- // REVIEW: need to use actual arg count if VarArgs are supported
- ArgInfo* pArgInfoStart = (ArgInfo*) _alloca(nFixedArgs*sizeof(ArgInfo));
-
-#ifdef _DEBUG
- // We expect to write useful data over every part of this so need
- // not do this in retail!
- memset((void *)pArgInfoStart, 0, sizeof(ArgInfo)*nFixedArgs);
-#endif
-
- for (; TransitionBlock::InvalidOffset != (ofs = argit.GetNextOffset()); arg++)
- {
- CONSISTENCY_CHECK(arg < nFixedArgs);
- ArgInfo* pArgInfo = pArgInfoStart + arg;
-
-#ifdef CALLDESCR_REGTYPEMAP
- FillInRegTypeMap(ofs, argit.GetArgType(), pMap);
-#endif
-
-#ifdef CALLDESCR_FPARGREGS
- // Under CALLDESCR_FPARGREGS we can have arguments in floating point registers. If we have at
- // least one such argument we point the call worker at the floating point area of the frame (we leave
- // it null otherwise since the worker can perform a useful optimization if it knows no floating point
- // registers need to be set up).
- if (TransitionBlock::HasFloatRegister(ofs, argit.GetArgLocDescForStructInRegs()) &&
- (pFloatArgumentRegisters == NULL))
- {
- pFloatArgumentRegisters = (FloatArgumentRegisters*)(pTransitionBlock +
- TransitionBlock::GetOffsetOfFloatArgumentRegisters());
- }
-#endif
-
- if (argit.GetArgType() == ELEMENT_TYPE_BYREF)
- {
- TypeHandle ty = TypeHandle();
- CorElementType brType = sig->GetByRefType(&ty);
- if (CorIsPrimitiveType(brType))
- {
- pArgInfo->dataSize = gElementTypeInfo[brType].m_cbSize;
- }
- else if (ty.IsValueType())
- {
- pArgInfo->dataSize = ty.GetMethodTable()->GetNumInstanceFieldBytes();
- numByRef ++;
- }
- else
- {
- pArgInfo->dataSize = sizeof(Object *);
- numByRef ++;
- }
-
- ByRefInfo *brInfo = (ByRefInfo *) _alloca(offsetof(ByRefInfo,data) + pArgInfo->dataSize);
- brInfo->argIndex = arg;
- brInfo->typ = brType;
- brInfo->typeHandle = ty;
- brInfo->pNext = pByRefs;
- pByRefs = brInfo;
- pArgInfo->dataLocation = (BYTE*)brInfo->data;
- *((void**)(pTransitionBlock + ofs)) = (void*)pArgInfo->dataLocation;
- pArgInfo->dataTypeHandle = ty;
- pArgInfo->dataType = static_cast<BYTE>(brType);
- pArgInfo->byref = TRUE;
- }
- else
- {
- pArgInfo->dataLocation = pTransitionBlock + ofs;
- pArgInfo->dataSize = argit.GetArgSize();
- pArgInfo->dataTypeHandle = sig->GetLastTypeHandleThrowing(); // this may cause GC!
- pArgInfo->dataType = (BYTE)argit.GetArgType();
- pArgInfo->byref = FALSE;
- }
- }
-
-
- if (ppThis)
- {
- // If this isn't a value class, verify the objectref
-#ifdef _DEBUG
- //if (pMD->GetMethodTable()->IsValueType() == FALSE)
- //{
- // VALIDATEOBJECTREF(pServer);
- //}
-#endif //_DEBUG
- *ppThis = pServer;
- }
-
- PVOID pRetBufStackData = NULL;
-
- if (argit.HasRetBuffArg())
- {
- // If the return buffer *must* be a stack-allocated object, allocate it.
- PVOID pRetBufData = NULL;
- if (pStructRetTypeMT->IsStructRequiringStackAllocRetBuf())
- {
- SIZE_T sz = pStructRetTypeMT->GetNumInstanceFieldBytes();
- pRetBufData = pRetBufStackData = _alloca(sz);
- memset(pRetBufData, 0, sz);
- pValueClasses = new (_alloca(sizeof(ValueClassInfo))) ValueClassInfo(pRetBufStackData, pStructRetTypeMT, pValueClasses);
- }
- else
- {
- pRetBufData = (*pVarRet)->GetData();
- }
- *((LPVOID*) (pTransitionBlock + argit.GetRetBuffArgOffset())) = pRetBufData;
- }
-
- // There should be no GC when we fill up the stack with parameters, as we don't protect them
- // Assignment of "*ppThis" above triggers the point where we become unprotected.
- {
- GCX_FORBID();
-
- PBYTE dataLocation;
- INT32 dataSize;
- TypeHandle dataTypeHandle;
- BYTE dataType;
-
- OBJECTREF* pArguments = pArgArray->m_Array;
- UINT32 i;
- for (i=0; i<nFixedArgs; i++)
- {
- ArgInfo* pArgInfo = pArgInfoStart + i;
-
- dataSize = pArgInfo->dataSize;
- dataLocation = pArgInfo->dataLocation;
- dataTypeHandle = pArgInfo->dataTypeHandle;
- dataType = pArgInfo->dataType;
-
- // Nullable<T> needs special treatment, even if it is 1, 2, 4, or 8 bytes
- if (dataType == ELEMENT_TYPE_VALUETYPE)
- goto DEFAULT_CASE;
-
- switch (dataSize)
- {
- case 1:
- // This "if" statement is necessary to make the assignement big-endian aware
- if (pArgInfo->byref)
- *((INT8*)dataLocation) = *((INT8*)pArguments[i]->GetData());
- else
- *(StackElemType*)dataLocation = (StackElemType)*((INT8*)pArguments[i]->GetData());
- break;
- case 2:
- // This "if" statement is necessary to make the assignement big-endian aware
- if (pArgInfo->byref)
- *((INT16*)dataLocation) = *((INT16*)pArguments[i]->GetData());
- else
- *(StackElemType*)dataLocation = (StackElemType)*((INT16*)pArguments[i]->GetData());
- break;
- case 4:
-#ifndef _WIN64
- if ((dataType == ELEMENT_TYPE_STRING) ||
- (dataType == ELEMENT_TYPE_OBJECT) ||
- (dataType == ELEMENT_TYPE_CLASS) ||
- (dataType == ELEMENT_TYPE_SZARRAY) ||
- (dataType == ELEMENT_TYPE_ARRAY))
- {
- *(OBJECTREF *)dataLocation = pArguments[i];
- }
- else
- {
- *(StackElemType*)dataLocation = (StackElemType)*((INT32*)pArguments[i]->GetData());
- }
-#else // !_WIN64
- // This "if" statement is necessary to make the assignement big-endian aware
- if (pArgInfo->byref)
- *(INT32*)dataLocation = *((INT32*)pArguments[i]->GetData());
- else
- *(StackElemType*)dataLocation = (StackElemType)*((INT32*)pArguments[i]->GetData());
-#endif // !_WIN64
- break;
-
- case 8:
-#ifdef _WIN64
- if ((dataType == ELEMENT_TYPE_STRING) ||
- (dataType == ELEMENT_TYPE_OBJECT) ||
- (dataType == ELEMENT_TYPE_CLASS) ||
- (dataType == ELEMENT_TYPE_SZARRAY) ||
- (dataType == ELEMENT_TYPE_ARRAY))
- {
- *(OBJECTREF *)dataLocation = pArguments[i];
- }
- else
- {
- *((INT64*)dataLocation) = *((INT64*)pArguments[i]->GetData());
- }
-#else // _WIN64
- *((INT64*)dataLocation) = *((INT64*)pArguments[i]->GetData());
-#endif // _WIN64
- break;
-
- default:
- {
- DEFAULT_CASE:
- MethodTable * pMT = dataTypeHandle.GetMethodTable();
-
-#ifdef ENREGISTERED_PARAMTYPE_MAXSIZE
- // We do not need to allocate a buffer if the argument is already passed by reference.
- if (!pArgInfo->byref && ArgIterator::IsArgPassedByRef(dataTypeHandle))
- {
- PVOID pvArg = _alloca(dataSize);
- pMT->UnBoxIntoUnchecked(pvArg, pArguments[i]);
- *(PVOID*)dataLocation = pvArg;
-
- pValueClasses = new (_alloca(sizeof(ValueClassInfo))) ValueClassInfo(pvArg, pMT, pValueClasses);
- }
- else
-#endif
- {
- pMT->UnBoxIntoUnchecked(dataLocation, pArguments[i]);
- }
- }
- }
- }
-
-#ifdef _DEBUG
- // Should not be using this any more
- memset((void *)pArgInfoStart, 0, sizeof(ArgInfo)*nFixedArgs);
-#endif
-
- // if there were byrefs, push a protection frame
- if (pByRefs && numByRef > 0)
- {
- char *pBuffer = (char*)_alloca (sizeof (FrameWithCookie<ProtectByRefsFrame>));
- pProtectionFrame = new (pBuffer) FrameWithCookie<ProtectByRefsFrame>(pThread, pByRefs);
- }
-
- // If there were any value classes that must be protected by the
- // caller, push a ProtectValueClassFrame.
- if (pValueClasses)
- {
- char *pBuffer = (char*)_alloca (sizeof (FrameWithCookie<ProtectValueClassFrame>));
- pProtectValueClassFrame = new (pBuffer) FrameWithCookie<ProtectValueClassFrame>(pThread, pValueClasses);
- }
-
- } // GCX_FORBID
-
- UINT fpReturnSize = argit.GetFPReturnSize();
-
- CallDescrData callDescrData;
-
- callDescrData.pSrc = pTransitionBlock + sizeof(TransitionBlock);
- callDescrData.numStackSlots = nStackBytes / STACK_ELEM_SIZE;
-#ifdef CALLDESCR_ARGREGS
- callDescrData.pArgumentRegisters = (ArgumentRegisters*)(pTransitionBlock + TransitionBlock::GetOffsetOfArgumentRegisters());
-#endif
-#ifdef CALLDESCR_FPARGREGS
- callDescrData.pFloatArgumentRegisters = pFloatArgumentRegisters;
-#endif
-#ifdef CALLDESCR_REGTYPEMAP
- callDescrData.dwRegTypeMap = dwRegTypeMap;
-#endif
- callDescrData.fpReturnSize = fpReturnSize;
- callDescrData.pTarget = pTarget;
-
- CallDescrWorkerWithHandler(&callDescrData);
-
- // It is still illegal to do a GC here. The return type might have/contain GC pointers.
- if (retElemType == ELEMENT_TYPE_VALUETYPE)
- {
- _ASSERTE(*pVarRet != NULL); // we have already allocated a return object
- PVOID pVarRetData = (*pVarRet)->GetData();
-
- // If the return result was passed back in registers, then copy it into the return object
- if (!argit.HasRetBuffArg())
- {
- CopyValueClass(pVarRetData, &callDescrData.returnValue, (*pVarRet)->GetMethodTable(), (*pVarRet)->GetAppDomain());
- }
- else if (pRetBufStackData != NULL)
- {
- // Copy the stack-allocated ret buff to the heap-allocated one.
- CopyValueClass(pVarRetData, pRetBufStackData, (*pVarRet)->GetMethodTable(), (*pVarRet)->GetAppDomain());
- }
-
- // If the return is a Nullable<T>, box it using Nullable<T> conventions.
- // TODO: this double allocates on constructions which is wasteful
- if (!retType.IsNull())
- *pVarRet = Nullable::NormalizeBox(*pVarRet);
- }
- else
- CMessage::GetObjectFromStack(pVarRet, &callDescrData.returnValue, retElemType, retType);
-
- // You can now do GCs if you want to
-
- if (pProtectValueClassFrame)
- pProtectValueClassFrame->Pop(pThread);
-
- // extract the out args from the byrefs
- if (pByRefs)
- {
- do
- {
- // Always extract the data ptr every time we enter this loop because
- // calls to GetObjectFromStack below can cause a GC.
- // Even this is not enough, because that we are passing a pointer to GC heap
- // to GetObjectFromStack . If GC happens, nobody is protecting the passed in pointer.
-
- OBJECTREF pTmp = NULL;
- void* dataLocation = pByRefs->data;
- CMessage::GetObjectFromStack(&pTmp, &dataLocation, pByRefs->typ, pByRefs->typeHandle, TRUE);
- (*ppVarOutParams)->SetAt(pByRefs->argIndex, pTmp);
- pByRefs = pByRefs->pNext;
- }
- while (pByRefs);
-
- if (pProtectionFrame)
- pProtectionFrame->Pop(pThread);
- }
-
- } // ProfilerServerCallbackHolder
-
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
- LOG((LF_REMOTING, LL_INFO10, "CallDescrWithObjectArray OUT\n"));
-}
-
-#endif // FEATURE_REMOTING
diff --git a/src/vm/stackbuildersink.h b/src/vm/stackbuildersink.h
deleted file mode 100644
index 7c4271e258..0000000000
--- a/src/vm/stackbuildersink.h
+++ /dev/null
@@ -1,49 +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.
-//
-// File: StackBuilderSink.h
-//
-
-//
-// Purpose: Native implementation for System.Runtime.Remoting.Messaging.StackBuilderSink
-//
-
-
-#ifndef __STACKBUILDERSINK_H__
-#define __STACKBUILDERSINK_H__
-
-#ifndef FEATURE_REMOTING
-#error FEATURE_REMOTING is not set, please do not include stackbuildersink.h
-#endif
-
-void CallDescrWithObjectArray(OBJECTREF& pServer, MethodDesc *pMD, //ReflectMethod *pMD,
- PCODE pTarget, MetaSig* sig, VASigCookie *pCookie,
- PTRARRAYREF& pArguments,
- OBJECTREF* pVarRet, PTRARRAYREF* ppVarOutParams);
-
-//+----------------------------------------------------------
-//
-// Class: CStackBuilderSink
-//
-// Synopsis: EE counterpart to
-// Microsoft.Runtime.StackBuilderSink
-// Code helper to build a stack of parameter
-// arguments and make a function call on an
-// object.
-//
-//
-//------------------------------------------------------------
-class CStackBuilderSink
-{
-public:
-
- static FCDECL5(Object*, PrivateProcessMessage,
- Object* pSBSinkUNSAFE,
- MethodDesc* pMD,
- PTRArray* pArgsUNSAFE,
- Object* pServerUNSAFE,
- PTRARRAYREF* ppVarOutParams);
-};
-
-#endif // __STACKBUILDERSINK_H__
diff --git a/src/vm/stackprobe.h b/src/vm/stackprobe.h
index 36909aa28c..0bf08b7423 100644
--- a/src/vm/stackprobe.h
+++ b/src/vm/stackprobe.h
@@ -684,11 +684,6 @@ INDEBUG(void AddHostCallsStaticMarker();)
{ \
ULONGLONG __entryTime = 0; \
__int64 __entryTimeStamp = 0; \
- if (CLRTaskHosted()) \
- { \
- __entryTimeStamp = getTimeStamp(); \
- __entryTime = CLRGetTickCount64(); \
- } \
_ASSERTE(CanThisThreadCallIntoHost()); \
_ASSERTE((pThread == NULL) || \
(pThread->GetClrDebugState() == NULL) || \
@@ -707,17 +702,6 @@ INDEBUG(void AddHostCallsStaticMarker();)
DEBUG_ASSURE_NO_RETURN_END(STACK_PROBE) \
boundary_guard_XXX.SetNoExceptionNoPop(); \
} \
- if (CLRTaskHosted()) \
- { \
- ULONGLONG __endTime = CLRGetTickCount64(); \
- ULONGLONG __elapse = __endTime - __entryTime; \
- if (__elapse > 20000 && __entryTimeStamp) \
- { \
- STRESS_LOG4(LF_EH, LL_INFO10, \
- "CALLING HOST takes %d ms: line %d in %s(%s)\n", \
- (int)__elapse, __LINE__, __FUNCTION__, __FILE__); \
- } \
- } \
}
//-----------------------------------------------------------------------------
diff --git a/src/vm/stackwalk.cpp b/src/vm/stackwalk.cpp
index 36af466e12..31e233ceb7 100644
--- a/src/vm/stackwalk.cpp
+++ b/src/vm/stackwalk.cpp
@@ -630,7 +630,10 @@ PCODE Thread::VirtualUnwindCallFrame(T_CONTEXT* pContext,
pFunctionEntryFromOS = RtlLookupFunctionEntry(uControlPc,
ARM_ONLY((DWORD*))(&uImageBaseFromOS),
NULL);
- _ASSERTE( (uImageBase == uImageBaseFromOS) && (pFunctionEntry == pFunctionEntryFromOS) );
+
+ // Note that he address returned from the OS is different from the one we have computed
+ // when unwind info is registered using RtlAddGrowableFunctionTable. Compare RUNTIME_FUNCTION content.
+ _ASSERTE( (uImageBase == uImageBaseFromOS) && (memcmp(pFunctionEntry, pFunctionEntryFromOS, sizeof(RUNTIME_FUNCTION)) == 0) );
#endif // _DEBUG && !FEATURE_PAL
}
@@ -658,20 +661,7 @@ PCODE Thread::VirtualUnwindCallFrame(T_CONTEXT* pContext,
return uControlPc;
}
-#ifdef DACCESS_COMPILE
-
-PCODE Thread::VirtualUnwindLeafCallFrame(T_CONTEXT* pContext)
-{
- DacNotImpl();
- return 0;
-}
-UINT_PTR Thread::VirtualUnwindToFirstManagedCallFrame(T_CONTEXT* pContext)
-{
- DacNotImpl();
- return 0;
-}
-
-#else // !DACCESS_COMPILE
+#ifndef DACCESS_COMPILE
// static
PCODE Thread::VirtualUnwindLeafCallFrame(T_CONTEXT* pContext)
@@ -796,7 +786,7 @@ UINT_PTR Thread::VirtualUnwindToFirstManagedCallFrame(T_CONTEXT* pContext)
return uControlPc;
}
-#endif // DACCESS_COMPILE
+#endif // !DACCESS_COMPILE
#endif // WIN64EXCEPTIONS
#ifdef _DEBUG
@@ -1740,10 +1730,12 @@ ProcessFuncletsForGCReporting:
// was a caller of an already executed exception handler based on the previous exception trackers.
// The handler funclet frames are already gone from the stack, so the exception trackers are the
// only source of evidence about it.
- // The filter funclet is different though, its frame is always present on the stack when its parent
- // frame is reached by the stack walker, because no exception can escape a filter funclet.
// This is different from Windows where the full stack is preserved until an exception is fully handled
// and so we can detect it just from walking the stack.
+ // The filter funclet frames are different, they behave the same way on Windows and Unix. They can be present
+ // on the stack when we reach their parent frame if the filter hasn't finished running yet or they can be
+ // gone if the filter completed running, either succesfully or with unhandled exception.
+ // So the special handling below ignores trackers belonging to filter clauses.
bool fProcessingFilterFunclet = !m_sfFuncletParent.IsNull() && !(m_fProcessNonFilterFunclet || m_fProcessIntermediaryNonFilterFunclet);
if (!fRecheckCurrentFrame && !fSkippingFunclet && (pTracker != NULL) && !fProcessingFilterFunclet)
{
@@ -1752,25 +1744,30 @@ ProcessFuncletsForGCReporting:
// frame matching the current frame, it means that the funclet stack frame was reclaimed.
StackFrame sfFuncletParent;
ExceptionTracker* pCurrTracker = pTracker;
- bool hasFuncletStarted = m_crawl.pThread->GetExceptionState()->GetCurrentEHClauseInfo()->IsManagedCodeEntered();
+
+ bool hasFuncletStarted = pTracker->GetEHClauseInfo()->IsManagedCodeEntered();
while (pCurrTracker != NULL)
{
- if (hasFuncletStarted)
+ // Ignore exception trackers for filter clauses, since their frames are handled the same way as on Windows
+ if (pCurrTracker->GetEHClauseInfo()->GetClauseType() != COR_PRF_CLAUSE_FILTER)
{
- sfFuncletParent = pCurrTracker->GetCallerOfEnclosingClause();
+ if (hasFuncletStarted)
+ {
+ sfFuncletParent = pCurrTracker->GetCallerOfEnclosingClause();
+ if (!sfFuncletParent.IsNull() && ExceptionTracker::IsUnwoundToTargetParentFrame(&m_crawl, sfFuncletParent))
+ {
+ break;
+ }
+ }
+
+ sfFuncletParent = pCurrTracker->GetCallerOfCollapsedEnclosingClause();
if (!sfFuncletParent.IsNull() && ExceptionTracker::IsUnwoundToTargetParentFrame(&m_crawl, sfFuncletParent))
{
break;
}
}
- sfFuncletParent = pCurrTracker->GetCallerOfCollapsedEnclosingClause();
- if (!sfFuncletParent.IsNull() && ExceptionTracker::IsUnwoundToTargetParentFrame(&m_crawl, sfFuncletParent))
- {
- break;
- }
-
// Funclets handling exception for trackers older than the current one were always started,
// since the current tracker was created due to an exception in the funclet belonging to
// the previous tracker.
@@ -3152,7 +3149,10 @@ void StackFrameIterator::PreProcessingForManagedFrames(void)
INDEBUG(m_crawl.pThread->DebugLogStackWalkInfo(&m_crawl, "CONSIDER", m_uFramesProcessed));
-#if defined(_DEBUG) && defined(_TARGET_X86_) && !defined(DACCESS_COMPILE)
+#if defined(_DEBUG) && !defined(WIN64EXCEPTIONS) && !defined(DACCESS_COMPILE)
+ //
+ // VM is responsible for synchronization on non-funclet EH model.
+ //
// m_crawl.GetThisPointer() requires full unwind
// In GC's relocate phase, objects is not verifiable
if ( !(m_flags & (LIGHTUNWIND | QUICKUNWIND | ALLOW_INVALID_OBJECTS)) &&
@@ -3176,7 +3176,7 @@ void StackFrameIterator::PreProcessingForManagedFrames(void)
END_GCX_ASSERT_COOP;
}
-#endif // _DEBUG && _TARGET_X86_ && !DACCESS_COMPILE
+#endif // _DEBUG && !WIN64EXCEPTIONS && !DACCESS_COMPILE
m_frameState = SFITER_FRAMELESS_METHOD;
} // StackFrameIterator::PreProcessingForManagedFrames()
diff --git a/src/vm/stdinterfaces.cpp b/src/vm/stdinterfaces.cpp
index c80ec3fe22..34ba39019e 100644
--- a/src/vm/stdinterfaces.cpp
+++ b/src/vm/stdinterfaces.cpp
@@ -27,9 +27,6 @@
#include "threads.h"
#include "interoputil.h"
#include "tlbexport.h"
-#ifdef FEATURE_COMINTEROP_TLB_SUPPORT
-#include "comtypelibconverter.h"
-#endif
#include "comdelegate.h"
#include "olevariant.h"
#include "eeconfig.h"
@@ -37,9 +34,6 @@
#include "posterror.h"
#include <corerror.h>
#include <mscoree.h>
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "mtx.h"
#include "cgencpu.h"
#include "interopconverter.h"
@@ -249,24 +243,6 @@ Unknown_QueryInterface_Internal(ComCallWrapper* pWrap, IUnknown* pUnk, REFIID ri
pDestItf = ComCallWrapper::GetComIPFromCCW(pWrap, riid, NULL, GetComIPFromCCW::CheckVisibility);
if (pDestItf == NULL)
{
-#ifdef FEATURE_REMOTING
- // Check if the wrapper is a transparent proxy if so delegate the QI to the real proxy
- if (pWrap->IsObjectTP())
- {
- ARG_SLOT ret = 0;
- {
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
- OBJECTREF oref = pWrap->GetObjectRef();
- OBJECTREF realProxy = ObjectToOBJECTREF(CRemotingServices::GetRealProxy(OBJECTREFToObject(oref)));
- _ASSERTE(realProxy != NULL);
-
- if (!CRemotingServices::CallSupportsInterface(realProxy, riid, &ret))
- goto ErrExit;
- } // end GCX_COOP scope, pDestItf must be assigned to in preemptive mode
-
- pDestItf = (IUnknown*)ret;
- }
-#endif // FEATURE_REMOTING
}
}
@@ -626,219 +602,8 @@ HRESULT GetITypeLibForAssembly(Assembly *pAssembly, ITypeLib **ppTLB, int bAutoC
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
//@CORESYSTODO: what to do?
return E_FAIL;
-#else
-
- HRESULT hr = S_OK; // A result.
- CQuickWSTRBase rName; // Library (scope) or file name.
- int bResize=false; // If true, had to resize the buffer to hold the name.
- LPCWSTR szModule=0; // The module name.
- GUID guid; // A GUID.
- ITypeLib *pITLB=0; // The TypeLib.
- Module *pModule; // The assembly's module.
- WCHAR rcDrive[_MAX_DRIVE]; // Module's drive letter.
- WCHAR rcDir[_MAX_DIR]; // Module's directory.
- WCHAR rcFname[_MAX_FNAME]; // Module's file name.
- USHORT wMajor; // Major version number.
- USHORT wMinor; // Minor version number.
-
- rName.Init();
-
- // Check to see if we have a cached copy.
- pITLB = pAssembly->GetTypeLib();
- if (pITLB)
- {
- // Check to see if the cached value is -1. This indicate that we tried
- // to export the typelib but that the export failed.
- if (pITLB == (ITypeLib*)-1)
- {
- hr = E_FAIL;
- goto ReturnHR;
- }
-
- // We have a cached copy so return it.
- *ppTLB = pITLB;
- hr = S_OK;
- goto ReturnHR;
- }
-
- // Retrieve the name of the module.
- pModule = pAssembly->GetManifestModule();
-
- EX_TRY
- {
- // SString::ConvertToUnicode is THROW_UNLESS_NORMALIZED
- szModule = pModule->GetPath();
- }
- EX_CATCH_HRESULT(hr);
- IfFailGo(hr);
-
- // Retrieve the guid for typelib that would be generated from the assembly.
- IfFailGo(GetTypeLibGuidForAssembly(pAssembly, &guid));
-
- // If the typelib is for the runtime library, we'd better know where it is.
- if (guid == LIBID_ComPlusRuntime)
- {
- ULONG dwSize = (ULONG)rName.MaxSize();
- while (FAILED(GetInternalSystemDirectory(rName.Ptr(), &dwSize)))
- {
- IfFailGo(rName.ReSizeNoThrow(dwSize=(ULONG)rName.MaxSize()*2));
- }
-
- IfFailGo(rName.ReSizeNoThrow(dwSize + wcslen(g_pwBaseLibraryTLB) + 3));
- wcscat_s(rName.Ptr(), rName.Size(), g_pwBaseLibraryTLB);
- hr = LoadTypeLibExWithFlags(rName.Ptr(), flags, &pITLB);
- goto ErrExit;
- }
-
- // Retrieve the major and minor version number.
- IfFailGo(GetTypeLibVersionForAssembly(pAssembly, &wMajor, &wMinor));
-
- // Maybe the module was imported from COM, and we can get the libid of the existing typelib.
- if (pAssembly->IsImportedFromTypeLib())
- {
- hr = LoadRegTypeLibWithFlags(guid, wMajor, wMinor, flags, &pITLB);
- if (SUCCEEDED(hr))
- goto ErrExit;
-
- // Try just the Assembly version
- pAssembly->GetVersion(&wMajor, &wMinor, NULL, NULL);
- hr = LoadRegTypeLibWithFlags(guid, wMajor, wMinor, flags, &pITLB);
- if (SUCCEEDED(hr))
- goto ErrExit;
-
- // Try loading the highest registered version.
- hr = LoadRegTypeLibWithFlags(guid, -1, -1, flags, &pITLB);
- if (SUCCEEDED(hr))
- goto ErrExit;
-
- // The module is known to be imported, so no need to try conversion.
-
- // Set the error info for most callers.
- VMPostError(TLBX_E_CIRCULAR_EXPORT2, szModule);
-
- // Set the hr for the case where we're trying to load a type library to
- // resolve a type reference from another library. The error message will
- // be posted where more information is available.
- if (hr == TYPE_E_LIBNOTREGISTERED)
- hr = TLBX_W_LIBNOTREGISTERED;
- else
- hr = TLBX_E_CANTLOADLIBRARY;
-
- IfFailGo(hr);
- }
-
- // Try to load the registered typelib.
- hr = LoadRegTypeLibWithFlags(guid, wMajor, wMinor, flags, &pITLB);
- if(hr == S_OK)
- goto ErrExit;
-
- // Try just the Assembly version
- pAssembly->GetVersion(&wMajor, &wMinor, NULL, NULL);
- hr = LoadRegTypeLibWithFlags(guid, wMajor, wMinor, flags, &pITLB);
- if (SUCCEEDED(hr))
- goto ErrExit;
-
- // If that fails, try loading the highest registered version.
- hr = LoadRegTypeLibWithFlags(guid, -1, -1, flags, &pITLB);
- if(hr == S_OK)
- goto ErrExit;
-
- // If caller only wants registered typelibs, exit now, with error from prior call.
- if (flags & TlbExporter_OnlyReferenceRegistered)
- goto ErrExit;
-
- // If we haven't managed to find the typelib so far try and load the typelib by name.
- hr = LoadTypeLibExWithFlags(szModule, flags, &pITLB);
- if(hr == S_OK)
- {
- // Check libid.
- TLIBATTR *pTlibAttr;
- int bMatch;
-
- IfFailGo(pITLB->GetLibAttr(&pTlibAttr));
- bMatch = pTlibAttr->guid == guid;
- pITLB->ReleaseTLibAttr(pTlibAttr);
-
- if (bMatch)
- {
- goto ErrExit;
- }
- else
- {
- SafeReleasePreemp(pITLB);
- pITLB = NULL;
- hr = TLBX_E_CANTLOADLIBRARY;
- }
- }
-
- // Add a ".tlb" extension and try again.
- IfFailGo(rName.ReSizeNoThrow((int)(wcslen(szModule) + 5)));
- // Check if szModule already has an extension.
- LPCWSTR ext;
- size_t extSize;
- SplitPathInterior(szModule, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, &ext, &extSize);
- if (ext != nullptr)
- {
- // szModule already has an extension. Make a copy without the extension.
- wcsncpy_s(rName.Ptr(), rName.Size(), szModule, ext - szModule);
- }
- else
- {
- // szModule does not have an extension. Copy the whole string.
- wcscpy_s(rName.Ptr(), rName.Size(), szModule);
- }
- wcscat_s(rName.Ptr(), rName.Size(), W(".tlb"));
-
- hr = LoadTypeLibExWithFlags(rName.Ptr(), flags, &pITLB);
- if(hr == S_OK)
- {
- // Check libid.
- TLIBATTR *pTlibAttr;
- int bMatch;
- IfFailGo(pITLB->GetLibAttr(&pTlibAttr));
- bMatch = pTlibAttr->guid == guid;
- pITLB->ReleaseTLibAttr(pTlibAttr);
- if (bMatch)
- {
- goto ErrExit;
- }
- else
- {
- SafeReleasePreemp(pITLB);
- pITLB = NULL;
- hr = TLBX_E_CANTLOADLIBRARY;
- }
- }
-
- // If the auto create flag is set then try and export the typelib from the module.
- if (bAutoCreate)
- {
- // Try to export the typelib right now.
- // This is FTL export (Fractionally Too Late).
- hr = ExportTypeLibFromLoadedAssemblyNoThrow(pAssembly, 0, &pITLB, 0, flags);
- if (FAILED(hr))
- {
- // If the export failed then remember it failed by setting the typelib
- // to -1 on the assembly.
- pAssembly->SetTypeLib((ITypeLib *)-1);
- IfFailGo(hr);
- }
- }
-
-ErrExit:
- // If we successfully opened (or created) the typelib, cache a pointer, and return it to caller.
- if (pITLB)
- {
- pAssembly->SetTypeLib(pITLB);
- *ppTLB = pITLB;
- }
-ReturnHR:
- rName.Destroy();
- return hr;
-#endif //FEATURE_CORECLR
} // HRESULT GetITypeLibForAssembly()
@@ -1651,8 +1416,6 @@ OleAutDispatchImpl_Invoke
pDisp = (IDispatch*)pCCW->GetIClassXIP();
}
- LeaveRuntimeHolder holder(**(size_t**)pTI);
-
hr = pTI->Invoke(pDisp, dispidMember, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
}
EX_CATCH
@@ -2681,44 +2444,6 @@ HRESULT __stdcall WeakReferenceSource_GetWeakReference (
return hr;
}
-#ifdef FEATURE_REMOTING
-// HELPER to call RealProxy::GetIUnknown to get the iunknown to give out
-// for this transparent proxy for calls to IMarshal
-IUnknown* GetIUnknownForTransparentProxyHelper(SimpleComCallWrapper *pSimpleWrap)
-{
- CONTRACT (IUnknown*)
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- PRECONDITION(CheckPointer(pSimpleWrap));
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- IUnknown* pMarshalerObj = NULL;
-
- GCX_COOP();
-
- EX_TRY
- {
- OBJECTREF oref = pSimpleWrap->GetObjectRef();
- GCPROTECT_BEGIN(oref)
- {
- pMarshalerObj = GetIUnknownForTransparentProxy(&oref, TRUE);
- oref = NULL;
- }
- GCPROTECT_END();
- }
- EX_CATCH
- {
- // ignore
- }
- EX_END_CATCH(SwallowAllExceptions)
-
- RETURN pMarshalerObj;
-}
-#endif // FEATURE_REMOTING
// Helper to setup IMarshal
HRESULT GetSpecialMarshaler(IMarshal* pMarsh, SimpleComCallWrapper* pSimpleWrap, ULONG dwDestContext, IMarshal **ppMarshalRet)
@@ -2735,42 +2460,10 @@ HRESULT GetSpecialMarshaler(IMarshal* pMarsh, SimpleComCallWrapper* pSimpleWrap,
HRESULT hr = S_OK;
-#ifdef FEATURE_REMOTING
- // transparent proxies are special
- if (pSimpleWrap->IsObjectTP())
- {
- SafeComHolderPreemp<IUnknown> pMarshalerObj = NULL;
-
- pMarshalerObj = GetIUnknownForTransparentProxyHelper(pSimpleWrap);
- // QI for the IMarshal Interface and verify that we don't get back
- // a pointer to us (GetIUnknownForTransparentProxyHelper could return
- // a pointer back to the same object if realproxy::GetCOMIUnknown
- // is not overriden
- if (pMarshalerObj != NULL)
- {
- SafeComHolderPreemp<IMarshal> pMsh = NULL;
- hr = SafeQueryInterfacePreemp(pMarshalerObj, IID_IMarshal, (IUnknown**)&pMsh);
-
- // make sure we don't recurse
- if(SUCCEEDED(hr) && pMsh != pMarsh)
- {
- *ppMarshalRet = pMsh.Extract();
- return S_OK;
- }
- }
- }
-#endif // FEATURE_REMOTING
// In case of APPX process we always use the standard marshaller.
// In Non-APPX process use standard marshalling for everything except in-proc servers.
// In case of CoreCLR, we always use the standard marshaller as well.
-#if !defined(FEATURE_CORECLR)
- if (!AppX::IsAppXProcess() && (dwDestContext == MSHCTX_INPROC))
- {
- *ppMarshalRet = NULL;
- return S_OK;
- }
-#endif // !FEATURE_CORECLR
SafeComHolderPreemp<IUnknown> pMarshalerObj = NULL;
IfFailRet(CoCreateFreeThreadedMarshaler(NULL, &pMarshalerObj));
@@ -3084,49 +2777,8 @@ HRESULT __stdcall ManagedObject_GetSerializedBuffer(IManagedObject *pManaged,
}
CONTRACTL_END;
-#ifdef FEATURE_CORECLR
_ASSERTE(!"NYI");
return E_NOTIMPL;
-#else // FEATURE_CORECLR
-
- HRESULT hr = S_OK;
- if (pBStr == NULL)
- return E_POINTER;
-
- *pBStr = NULL;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
- {
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
-
- SimpleComCallWrapper *pSimpleWrap = SimpleComCallWrapper::GetWrapperFromIP( pManaged );
- ComCallWrapper *pComCallWrap = pSimpleWrap->GetMainWrapper();
-
- _ASSERTE(pComCallWrap != NULL);
-
- //@todo don't allow serialization of Configured objects through DCOM
- _ASSERTE(GetThread()->GetDomain()->GetId() == pSimpleWrap->GetDomainID());
-
- BOOL fLegacyMode = (GetAppDomain()->GetComOrRemotingFlag() == COMorRemoting_LegacyMode);
-
- OBJECTREF oref = pComCallWrap->GetObjectRef();
- GCPROTECT_BEGIN(oref)
- {
- // GetSerializedBuffer is only called in cross-runtime/cross-process scenarios so we pass
- // fCrossRuntime=TRUE unless we are in legacy mode
- if (!ConvertObjectToBSTR(&oref, !fLegacyMode, pBStr))
- {
- // ConvertObjectToBSTR returning FALSE is equivalent to throwing SerializationException
- hr = COR_E_SERIALIZATION;
- }
- }
- GCPROTECT_END();
- }
- END_EXTERNAL_ENTRYPOINT;
-
- return hr;
-
-#endif // FEATURE_CORECLR
}
//------------------------------------------------------------------------------------------
diff --git a/src/vm/stubhelpers.cpp b/src/vm/stubhelpers.cpp
index cbe1d37c94..0a5c143bf4 100644
--- a/src/vm/stubhelpers.cpp
+++ b/src/vm/stubhelpers.cpp
@@ -21,10 +21,6 @@
#include "comdatetime.h"
#include "gcheaputilities.h"
#include "interoputil.h"
-#include "gcscan.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#ifdef FEATURE_COMINTEROP
#include <oletls.h>
@@ -61,7 +57,7 @@ void StubHelpers::ValidateObjectInternal(Object *pObjUNSAFE, BOOL fValidateNextO
}
CONTRACTL_END;
- _ASSERTE(GCScan::GetGcRuntimeStructuresValid());
+ _ASSERTE(GCHeapUtilities::GetGCHeap()->RuntimeStructuresValid());
// validate the object - there's no need to validate next object's
// header since we validate the next object explicitly below
@@ -162,7 +158,7 @@ void StubHelpers::ProcessByrefValidationList()
{
entry = s_ByrefValidationEntries[i];
- Object *pObjUNSAFE = GCHeapUtilities::GetGCHeap()->GetContainingObject(entry.pByref);
+ Object *pObjUNSAFE = GCHeapUtilities::GetGCHeap()->GetContainingObject(entry.pByref, false);
ValidateObjectInternal(pObjUNSAFE, TRUE);
}
}
@@ -373,42 +369,6 @@ FORCEINLINE static void *GetCOMIPFromRCW_GetTarget(IUnknown *pUnk, ComPlusCallIn
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
-#ifdef _TARGET_X86_
- // m_pInterceptStub is either NULL if we never called on this method, -1 if we're not
- // hosted, or the host hook stub if we are hosted. The stub will extract the real target
- // from the 'this' argument.
- PVOID pInterceptStub = VolatileLoadWithoutBarrier(&pComInfo->m_pInterceptStub);
-
- if (pInterceptStub != (LPVOID)-1)
- {
- if (pInterceptStub != NULL)
- {
- return pInterceptStub;
- }
-
- if (NDirect::IsHostHookEnabled() || pComInfo->HasCopyCtorArgs())
- {
- return NULL;
- }
-
- if (!EnsureWritablePagesNoThrow(&pComInfo->m_pInterceptStub, sizeof(pComInfo->m_pInterceptStub)))
- {
- return NULL;
- }
-
- pComInfo->m_pInterceptStub = (LPVOID)-1;
- }
-#else // _TARGET_X86_
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (NDirect::IsHostHookEnabled())
- {
- // There's one static stub on !_TARGET_X86_.
- return (LPVOID)GetEEFuncEntryPoint(PInvokeStubForHost);
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-#endif // _TARGET_X86_
-#endif // FEATURE_CORECLR
LPVOID *lpVtbl = *(LPVOID **)pUnk;
return lpVtbl[pComInfo->m_cachedComSlot];
@@ -435,44 +395,6 @@ NOINLINE static IUnknown* GetCOMIPFromRCWHelper(LPVOID pFCall, OBJECTREF pSrc, M
pRetUnk.Release();
}
-#ifndef FEATURE_CORECLR
-#ifdef _TARGET_X86_
- GCX_PREEMP();
- Stub *pInterceptStub = NULL;
-
- if (pComInfo->m_pInterceptStub == NULL)
- {
- if (pComInfo->HasCopyCtorArgs())
- {
- // static stub that gets its arguments in a thread-static field
- pInterceptStub = NDirect::GetStubForCopyCtor();
- }
-
- if (NDirect::IsHostHookEnabled())
- {
- pInterceptStub = pComInfo->GenerateStubForHost(
- pMD->GetDomain()->GetLoaderAllocator()->GetStubHeap(),
- pInterceptStub);
- }
-
- EnsureWritablePages(&pComInfo->m_pInterceptStub);
-
- if (pInterceptStub != NULL)
- {
- if (InterlockedCompareExchangeT(&pComInfo->m_pInterceptStub,
- (LPVOID)pInterceptStub->GetEntryPoint(),
- NULL) != NULL)
- {
- pInterceptStub->DecRef();
- }
- }
- else
- {
- pComInfo->m_pInterceptStub = (LPVOID)-1;
- }
- }
-#endif // _TARGET_X86_
-#endif // !FEATURE_CORECLR
*ppTarget = GetCOMIPFromRCW_GetTarget(pRetUnk, pComInfo);
_ASSERTE(*ppTarget != NULL);
@@ -852,10 +774,7 @@ FCIMPL1(StringObject*, StubHelpers::UriMarshaler__GetRawUriFromNative, ABI::Wind
GCX_PREEMP();
// Get the RawUri string from the WinRT URI object
- {
- LeaveRuntimeHolder lrh(**(size_t**)(IUnknown*)pIUriRC);
- IfFailThrow(pIUriRC->get_RawUri(hsRawUriName.Address()));
- }
+ IfFailThrow(pIUriRC->get_RawUri(hsRawUriName.Address()));
pwszRawUri = hsRawUriName.GetRawBuffer(&cchRawUri);
}
@@ -904,18 +823,15 @@ StubHelpers::EventArgsMarshaler__CreateNativeNCCEventArgsInstance
SafeComHolderPreemp<IInspectable> pInner;
HRESULT hr;
- {
- LeaveRuntimeHolder lrh(**(size_t **)(IUnknown *)pFactory);
- hr = pFactory->CreateInstanceWithAllParameters(
- (ABI::Windows::UI::Xaml::Interop::NotifyCollectionChangedAction)action,
- (ABI::Windows::UI::Xaml::Interop::IBindableVector *)newItem,
- (ABI::Windows::UI::Xaml::Interop::IBindableVector *)oldItem,
- newIndex,
- oldIndex,
- NULL,
- &pInner,
- &pArgsRC);
- }
+ hr = pFactory->CreateInstanceWithAllParameters(
+ (ABI::Windows::UI::Xaml::Interop::NotifyCollectionChangedAction)action,
+ (ABI::Windows::UI::Xaml::Interop::IBindableVector *)newItem,
+ (ABI::Windows::UI::Xaml::Interop::IBindableVector *)oldItem,
+ newIndex,
+ oldIndex,
+ NULL,
+ &pInner,
+ &pArgsRC);
IfFailThrow(hr);
END_QCALL;
@@ -937,14 +853,11 @@ ABI::Windows::UI::Xaml::Data::IPropertyChangedEventArgs* QCALLTYPE
SafeComHolderPreemp<IInspectable> pInner;
HRESULT hr;
- {
- LeaveRuntimeHolder lrh(**(size_t **)(IUnknown *)pFactory);
- hr = pFactory->CreateInstance(
- name,
- NULL,
- &pInner,
- &pArgsRC);
- }
+ hr = pFactory->CreateInstance(
+ name,
+ NULL,
+ &pInner,
+ &pArgsRC);
IfFailThrow(hr);
END_QCALL;
@@ -1261,13 +1174,6 @@ FCIMPL2(void*, StubHelpers::GetDelegateTarget, DelegateObject *pThisUNSAFE, UINT
// see IL code gen in NDirectStubLinker::DoNDirect for details.
*ppStubArg = target;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (NDirect::IsHostHookEnabled())
- {
- // There's one static stub on !_TARGET_X86_.
- pEntryPoint = GetEEFuncEntryPoint(PInvokeStubForHost);
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#elif defined(_TARGET_ARM_)
// @ARMTODO: Nothing to do for ARM yet since we don't support the hosted path.
#endif // _WIN64, _TARGET_ARM_
@@ -1285,109 +1191,7 @@ FCIMPL2(void*, StubHelpers::GetDelegateTarget, DelegateObject *pThisUNSAFE, UINT
}
FCIMPLEND
-#ifndef FEATURE_CORECLR // CAS
-static void DoDeclarativeActionsForPInvoke(MethodDesc* pCurrent)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_TRIGGERS;
- THROWS;
- SO_INTOLERANT;
- }
- CONTRACTL_END;
-
- MethodSecurityDescriptor MDSecDesc(pCurrent);
- MethodSecurityDescriptor::LookupOrCreateMethodSecurityDescriptor(&MDSecDesc);
-
- DeclActionInfo* pRuntimeDeclActionInfo = MDSecDesc.GetRuntimeDeclActionInfo();
- if (pRuntimeDeclActionInfo != NULL)
- {
- // Tell the debugger not to start on any managed code that we call in this method
- FrameWithCookie<DebuggerSecurityCodeMarkFrame> __dbgSecFrame;
-
- Security::DoDeclarativeActions(pCurrent, pRuntimeDeclActionInfo, NULL, &MDSecDesc);
-
- // Pop the debugger frame
- __dbgSecFrame.Pop();
- }
-}
-#endif // FEATURE_CORECLR
-
-#ifndef FEATURE_CORECLR
-#ifndef _WIN64
-FCIMPL3(void*, StubHelpers::GetFinalStubTarget, LPVOID pStubArg, LPVOID pUnmngThis, DWORD dwFlags)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(SF_IsForwardStub(dwFlags));
- }
- CONTRACTL_END;
- if (SF_IsCALLIStub(dwFlags))
- {
- // stub argument is the target
- return pStubArg;
- }
- else if (SF_IsDelegateStub(dwFlags))
- {
- // stub argument is not used but we pass _methodPtrAux which is the target
- return pStubArg;
- }
- else if (SF_IsCOMStub(dwFlags))
- {
- // stub argument is a ComPlusCallMethodDesc
- ComPlusCallMethodDesc *pCMD = (ComPlusCallMethodDesc *)pStubArg;
- LPVOID *lpVtbl = *(LPVOID **)pUnmngThis;
- return lpVtbl[pCMD->m_pComPlusCallInfo->m_cachedComSlot];
- }
- else // P/Invoke
- {
- // secret stub argument is an NDirectMethodDesc
- NDirectMethodDesc *pNMD = (NDirectMethodDesc *)pStubArg;
- return pNMD->GetNativeNDirectTarget();
- }
-}
-FCIMPLEND
-#endif // !_WIN64
-
-FCIMPL1(void, StubHelpers::DemandPermission, NDirectMethodDesc *pNMD)
-{
- FCALL_CONTRACT;
-
- // ETWOnStartup (SecurityCatchCall, SecurityCatchCallEnd); // this is messing up HMF below
-
- if (pNMD != NULL)
- {
- g_IBCLogger.LogMethodDescAccess(pNMD);
-
- if (pNMD->IsInterceptedForDeclSecurity())
- {
- if (pNMD->IsInterceptedForDeclSecurityCASDemandsOnly() &&
- SecurityStackWalk::HasFlagsOrFullyTrusted(1 << SECURITY_UNMANAGED_CODE))
- {
- // Track perfmon counters. Runtime security checks.
- Security::IncrementSecurityPerfCounter();
- }
- else
- {
- HELPER_METHOD_FRAME_BEGIN_0();
- DoDeclarativeActionsForPInvoke(pNMD);
- HELPER_METHOD_FRAME_END();
- }
- }
- }
- else
- {
- // This is either CLR->COM or delegate P/Invoke (we don't call this helper for CALLI).
- HELPER_METHOD_FRAME_BEGIN_0();
- SecurityStackWalk::SpecialDemand(SSWT_DECLARATIVE_DEMAND, SECURITY_UNMANAGED_CODE);
- HELPER_METHOD_FRAME_END();
- }
-}
-FCIMPLEND
-#endif // !FEATURE_CORECLR
FCIMPL2(void, StubHelpers::ThrowInteropParamException, UINT resID, UINT paramIdx)
{
diff --git a/src/vm/stubhelpers.h b/src/vm/stubhelpers.h
index b64d2868d8..f7577d7a44 100644
--- a/src/vm/stubhelpers.h
+++ b/src/vm/stubhelpers.h
@@ -95,12 +95,6 @@ public:
static FCDECL1(void*, GetNDirectTarget, NDirectMethodDesc* pNMD);
static FCDECL2(void*, GetDelegateTarget, DelegateObject *pThisUNSAFE, UINT_PTR *ppStubArg);
-#ifndef FEATURE_CORECLR
-#ifndef _WIN64
- static FCDECL3(void*, GetFinalStubTarget, LPVOID pStubArg, LPVOID pUnmngThis, DWORD dwFlags);
-#endif // !_WIN64
- static FCDECL1(void, DemandPermission, NDirectMethodDesc *pNMD);
-#endif // !FEATURE_CORECLR
static FCDECL2(void, ThrowInteropParamException, UINT resID, UINT paramIdx);
static FCDECL1(Object*, GetHRExceptionObject, HRESULT hr);
diff --git a/src/vm/stubmgr.cpp b/src/vm/stubmgr.cpp
index 39f4c25a7d..e30fb3792e 100644
--- a/src/vm/stubmgr.cpp
+++ b/src/vm/stubmgr.cpp
@@ -9,9 +9,6 @@
#include "dllimportcallback.h"
#include "stubhelpers.h"
#include "asmconstants.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#ifdef FEATURE_COMINTEROP
#include "olecontexthelpers.h"
#endif
@@ -2102,18 +2099,6 @@ BOOL InteropDispatchStubManager::TraceManager(Thread *thread,
Object * pThis = StubManagerHelpers::GetThisPtr(pContext);
-#ifdef FEATURE_REMOTING
- if (pThis != NULL && pThis->IsTransparentProxy())
- {
- // We have remoting proxy in the way
-#ifdef DACCESS_COMPILE
- DacNotImpl();
-#else
- trace->InitForFramePush(GetEEFuncEntryPoint(TransparentProxyStubPatchLabel));
-#endif
- }
- else
-#endif // FEATURE_REMOTING
{
if (!pCMD->m_pComPlusCallInfo->m_pInterfaceMT->IsComEventItfType() && (pCMD->m_pComPlusCallInfo->m_pILStub != NULL))
{
diff --git a/src/vm/syncblk.cpp b/src/vm/syncblk.cpp
index 171a8d3bb7..78e455a580 100644
--- a/src/vm/syncblk.cpp
+++ b/src/vm/syncblk.cpp
@@ -30,7 +30,6 @@
#include "corhost.h"
#include "comdelegate.h"
#include "finalizerthread.h"
-#include "gcscan.h"
#ifdef FEATURE_COMINTEROP
#include "runtimecallablewrapper.h"
@@ -2518,7 +2517,7 @@ BOOL ObjHeader::Validate (BOOL bVerifySyncBlkIndex)
//rest of the DWORD is SyncBlk Index
if (!(bits & BIT_SBLK_IS_HASHCODE))
{
- if (bVerifySyncBlkIndex && GCScan::GetGcRuntimeStructuresValid ())
+ if (bVerifySyncBlkIndex && GCHeapUtilities::GetGCHeap()->RuntimeStructuresValid ())
{
DWORD sbIndex = bits & MASK_SYNCBLOCKINDEX;
ASSERT_AND_CHECK(SyncTableEntry::GetSyncTableEntry()[sbIndex].m_Object == obj);
@@ -3298,10 +3297,6 @@ bool AwareLock::Contention(INT32 timeOut)
COUNTER_ONLY(GetPerfCounters().m_LocksAndThreads.cContention++);
-#ifndef FEATURE_CORECLR
- // Fire a contention start event for a managed contention
- FireEtwContentionStart_V1(ETW::ContentionLog::ContentionStructs::ManagedContention, GetClrInstanceId());
-#endif // !FEATURE_CORECLR
LogContention();
Thread *pCurThread = GetThread();
@@ -3406,9 +3401,6 @@ entered: ;
Enter();
bEntered = TRUE;
}
-#ifndef FEATURE_CORECLR
- FireEtwContentionStop(ETW::ContentionLog::ContentionStructs::ManagedContention, GetClrInstanceId());
-#endif // !FEATURE_CORECLR
return bEntered;
}
@@ -3541,18 +3533,7 @@ BOOL SyncBlock::Wait(INT32 timeOut, BOOL exitContext)
Context* defaultContext;
defaultContext = pCurThread->GetDomain()->GetDefaultContext();
_ASSERTE(defaultContext);
-#ifdef FEATURE_REMOTING
- if (exitContext &&
- targetContext != defaultContext)
- {
- Context::MonitorWaitArgs waitArgs = {timeOut, &syncState, &isTimedOut};
- Context::CallBackInfo callBackInfo = {Context::MonitorWait_callback, (void*) &waitArgs};
- Context::RequestCallBack(CURRENT_APPDOMAIN_ID, defaultContext, &callBackInfo);
- }
- else
-#else
_ASSERTE( exitContext==NULL || targetContext == defaultContext);
-#endif
{
isTimedOut = pCurThread->Block(timeOut, &syncState);
}
diff --git a/src/vm/synch.cpp b/src/vm/synch.cpp
index 216dd31587..e159b7813a 100644
--- a/src/vm/synch.cpp
+++ b/src/vm/synch.cpp
@@ -9,7 +9,6 @@
#include "corhost.h"
#include "synch.h"
-#include "rwlock.h"
void CLREventBase::CreateAutoEvent (BOOL bInitialState // If TRUE, initial state is signalled
)
@@ -28,28 +27,6 @@ void CLREventBase::CreateAutoEvent (BOOL bInitialState // If TRUE, initial stat
SetAutoEvent();
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSyncManager *pManager = CorHost2::GetHostSyncManager();
- if (pManager != NULL) {
- IHostAutoEvent *pEvent;
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->CreateAutoEvent(&pEvent);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (hr != S_OK) {
- _ASSERTE (hr == E_OUTOFMEMORY);
- ThrowOutOfMemory();
- }
- if (bInitialState)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pEvent->Set();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
- m_handle = (HANDLE)pEvent;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
HANDLE h = UnsafeCreateEvent(NULL,FALSE,bInitialState,NULL);
if (h == NULL) {
@@ -102,22 +79,6 @@ void CLREventBase::CreateManualEvent (BOOL bInitialState // If TRUE, initial st
}
CONTRACTL_END;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSyncManager *pManager = CorHost2::GetHostSyncManager();
- if (pManager != NULL){
- IHostManualEvent *pEvent;
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->CreateManualEvent(bInitialState, &pEvent);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (hr != S_OK) {
- _ASSERTE (hr == E_OUTOFMEMORY);
- ThrowOutOfMemory();
- }
- m_handle = (HANDLE)pEvent;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
HANDLE h = UnsafeCreateEvent(NULL,TRUE,bInitialState,NULL);
if (h == NULL) {
@@ -170,28 +131,6 @@ void CLREventBase::CreateMonitorEvent(SIZE_T Cookie)
// thread-safe SetAutoEvent
FastInterlockOr(&m_dwFlags, CLREVENT_FLAGS_AUTO_EVENT);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSyncManager *pManager = CorHost2::GetHostSyncManager();
- if (pManager != NULL){
- IHostAutoEvent *pEvent;
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->CreateMonitorEvent(Cookie,&pEvent);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (hr != S_OK) {
- _ASSERTE (hr == E_OUTOFMEMORY);
- ThrowOutOfMemory();
- }
- if (FastInterlockCompareExchangePointer(&m_handle,
- reinterpret_cast<HANDLE>(pEvent),
- INVALID_HANDLE_VALUE) != INVALID_HANDLE_VALUE)
- {
- // We lost the race
- pEvent->Release();
- }
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
HANDLE h = UnsafeCreateEvent(NULL,FALSE,FALSE,NULL);
if (h == NULL) {
@@ -271,101 +210,6 @@ void CLREventBase::SetMonitorEvent()
}
}
-#ifdef FEATURE_RWLOCK
-void CLREventBase::CreateRWLockWriterEvent (BOOL bInitialState, // If TRUE, initial state is signalled
- CRWLock *pRWLock
- )
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- // disallow creation of Crst before EE starts
- PRECONDITION((g_fEEStarted));
- PRECONDITION((m_handle == INVALID_HANDLE_VALUE));
- PRECONDITION((GetThread() != NULL));
- PRECONDITION((!IsOSEvent()));
- }
- CONTRACTL_END;
-
- SetAutoEvent();
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSyncManager *pManager = CorHost2::GetHostSyncManager();
- if (pManager != NULL){
- // Need to have a fixed cookie. Use a weak handle for this purpose.
- IHostAutoEvent *pEvent;
- HRESULT hr;
- SIZE_T cookie = (SIZE_T)pRWLock->GetObjectHandle();
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->CreateRWLockWriterEvent(cookie, &pEvent);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (hr != S_OK) {
- _ASSERTE (hr == E_OUTOFMEMORY);
- ThrowOutOfMemory();
- }
- if (bInitialState)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pEvent->Set();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
- m_handle = (HANDLE)pEvent;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- {
- HANDLE h = UnsafeCreateEvent(NULL,FALSE,bInitialState,NULL);
- if (h == NULL) {
- ThrowOutOfMemory();
- }
- m_handle = h;
- }
-
- SetInDeadlockDetection();
-}
-
-void CLREventBase::CreateRWLockReaderEvent (BOOL bInitialState, // If TRUE, initial state is signalled
- CRWLock *pRWLock
- )
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- // disallow creation of Crst before EE starts
- PRECONDITION((g_fEEStarted));
- PRECONDITION((m_handle == INVALID_HANDLE_VALUE));
- PRECONDITION((GetThread() != NULL));
- PRECONDITION((!IsOSEvent()));
- }
- CONTRACTL_END;
-
- IHostSyncManager *pManager = CorHost2::GetHostSyncManager();
- if (pManager == NULL) {
- HANDLE h = UnsafeCreateEvent(NULL,TRUE,bInitialState,NULL);
- if (h == NULL) {
- ThrowOutOfMemory();
- }
- m_handle = h;
- }
- else {
- IHostManualEvent *pEvent;
- HRESULT hr;
- SIZE_T cookie = (SIZE_T)pRWLock->GetObjectHandle();
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->CreateRWLockReaderEvent(bInitialState, cookie, &pEvent);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (hr != S_OK) {
- _ASSERTE (hr == E_OUTOFMEMORY);
- ThrowOutOfMemory();
- }
- m_handle = (HANDLE)pEvent;
- }
-
- SetInDeadlockDetection();
-}
-#endif // FEATURE_RWLOCK
void CLREventBase::CreateOSAutoEvent (BOOL bInitialState // If TRUE, initial state is signalled
@@ -480,22 +324,6 @@ void CLREventBase::CloseEvent()
_ASSERTE(Thread::Debug_AllowCallout());
if (m_handle != INVALID_HANDLE_VALUE) {
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (!IsOSEvent() && CLRSyncHosted())
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
-
- if (IsAutoEvent()) {
- ((IHostAutoEvent*)m_handle)->Release();
- }
- else {
- ((IHostManualEvent*)m_handle)->Release();
- }
-
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
CloseHandle(m_handle);
}
@@ -519,26 +347,6 @@ BOOL CLREventBase::Set()
_ASSERTE(Thread::Debug_AllowCallout());
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (!IsOSEvent() && CLRSyncHosted())
- {
- if (IsAutoEvent()) {
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = ((IHostAutoEvent*)m_handle)->Set();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- return hr == S_OK;
- }
- else {
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = ((IHostManualEvent*)m_handle)->Set();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- return hr == S_OK;
- }
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
return UnsafeSetEvent(m_handle);
}
@@ -563,170 +371,17 @@ BOOL CLREventBase::Reset()
_ASSERTE (!IsAutoEvent() ||
!"Can not call Reset on AutoEvent");
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (!IsOSEvent() && CLRSyncHosted())
- {
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = ((IHostManualEvent*)m_handle)->Reset();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- return hr == S_OK;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
return UnsafeResetEvent(m_handle);
}
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-static DWORD HostAutoEventWait (void *args, DWORD timeout, DWORD option)
-{
- BOOL alertable = (option & WAIT_ALERTABLE);
- CONTRACTL
- {
- if (alertable)
- {
- THROWS;
- }
- else
- {
- NOTHROW;
- }
- if (GetThread())
- {
- if (alertable)
- GC_TRIGGERS;
- else
- GC_NOTRIGGER;
- }
- else
- {
- DISABLED(GC_TRIGGERS);
- }
- SO_TOLERANT;
- PRECONDITION(CheckPointer(args));
- }
- CONTRACTL_END;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = ((IHostAutoEvent*)args)->Wait(timeout,option);
- END_SO_TOLERANT_CODE_CALLING_HOST;
-#ifdef _DEBUG
- if (FAILED(hr) && timeout == INFINITE) {
- _ASSERTE (option & WAIT_ALERTABLE);
- }
-#endif
- if (hr == S_OK) {
- return WAIT_OBJECT_0;
- }
- else if (hr == HOST_E_DEADLOCK) {
- RaiseDeadLockException();
- }
- else if (hr == HOST_E_INTERRUPTED) {
- _ASSERTE (option & WAIT_ALERTABLE);
- Thread *pThread = GetThread();
- if (pThread)
- {
- Thread::UserInterruptAPC(APC_Code);
- }
- return WAIT_IO_COMPLETION;
- }
- else if (hr == HOST_E_TIMEOUT) {
- return WAIT_TIMEOUT;
- }
- else if (hr == HOST_E_ABANDONED) {
- return WAIT_ABANDONED;
- }
- else if (hr == E_FAIL) {
- _ASSERTE (!"Unknown host wait failure");
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- {
- _ASSERTE (!"Unknown host wait return");
- }
- return 0;
-}
-
-static DWORD HostManualEventWait (void *args, DWORD timeout, DWORD option)
-{
- CONTRACTL
- {
- if (option & WAIT_ALERTABLE)
- {
- THROWS;
- }
- else
- {
- NOTHROW;
- }
- GC_NOTRIGGER;
- SO_TOLERANT;
- PRECONDITION(CheckPointer(args));
- }
- CONTRACTL_END;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = ((IHostManualEvent*)args)->Wait(timeout,option);
- END_SO_TOLERANT_CODE_CALLING_HOST;
-
- if (hr == COR_E_STACKOVERFLOW)
- {
- Thread *pThread = GetThread();
- if (pThread && pThread->HasThreadStateNC(Thread::TSNC_WaitUntilGCFinished))
- {
- return hr;
- }
- }
-#ifdef _DEBUG
- if (FAILED(hr) && timeout == INFINITE) {
- _ASSERTE (option & WAIT_ALERTABLE);
- }
-#endif
- if (hr == S_OK) {
- return WAIT_OBJECT_0;
- }
- else if (hr == HOST_E_DEADLOCK) {
- RaiseDeadLockException();
- }
- else if (hr == HOST_E_INTERRUPTED) {
- _ASSERTE (option & WAIT_ALERTABLE);
- Thread *pThread = GetThread();
- if (pThread)
- {
- Thread::UserInterruptAPC(APC_Code);
- }
- return WAIT_IO_COMPLETION;
- }
- else if (hr == HOST_E_TIMEOUT) {
- return WAIT_TIMEOUT;
- }
- else if (hr == HOST_E_ABANDONED) {
- return WAIT_ABANDONED;
- }
- else if (hr == E_FAIL) {
- _ASSERTE (!"Unknown host wait failure");
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- {
- _ASSERTE (!"Unknown host wait return");
- }
- return 0;
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
static DWORD CLREventWaitHelper2(HANDLE handle, DWORD dwMilliseconds, BOOL alertable)
{
STATIC_CONTRACT_THROWS;
STATIC_CONTRACT_SO_TOLERANT;
- LeaveRuntimeHolder holder((size_t)WaitForSingleObjectEx);
return WaitForSingleObjectEx(handle,dwMilliseconds,alertable);
}
@@ -813,35 +468,6 @@ DWORD CLREventBase::WaitEx(DWORD dwMilliseconds, WaitMode mode, PendingSync *syn
#endif
_ASSERTE((pThread != NULL) || !g_fEEStarted || dbgOnly_IsSpecialEEThread());
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (!IsOSEvent() && CLRSyncHosted())
- {
- if ((pThread != NULL) && alertable) {
- DWORD dwRet = WAIT_FAILED;
- BEGIN_SO_INTOLERANT_CODE_NOTHROW (pThread, return WAIT_FAILED;);
- dwRet = pThread->DoAppropriateWait(IsAutoEvent()?HostAutoEventWait:HostManualEventWait,
- m_handle,dwMilliseconds,
- mode,
- syncState);
- END_SO_INTOLERANT_CODE;
- return dwRet;
- }
- else {
- _ASSERTE (syncState == NULL);
- DWORD option = 0;
- if (alertable) {
- option |= WAIT_ALERTABLE;
- }
- if (IsAutoEvent()) {
- return HostAutoEventWait((IHostAutoEvent*)m_handle,dwMilliseconds, option);
- }
- else {
- return HostManualEventWait((IHostManualEvent*)m_handle,dwMilliseconds, option);
- }
- }
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
if (pThread && alertable) {
DWORD dwRet = WAIT_FAILED;
@@ -870,25 +496,6 @@ void CLRSemaphore::Create (DWORD dwInitial, DWORD dwMax)
}
CONTRACTL_END;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostSyncManager *pManager = CorHost2::GetHostSyncManager();
- if (pManager != NULL) {
- IHostSemaphore *pSemaphore;
- #undef CreateSemaphore
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->CreateSemaphore(dwInitial,dwMax,&pSemaphore);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- #define CreateSemaphore(lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName) \
- Dont_Use_CreateSemaphore(lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName)
- if (hr != S_OK) {
- _ASSERTE(hr == E_OUTOFMEMORY);
- ThrowOutOfMemory();
- }
- m_handle = (HANDLE)pSemaphore;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
HANDLE h = UnsafeCreateSemaphore(NULL,dwInitial,dwMax,NULL);
if (h == NULL) {
@@ -904,14 +511,7 @@ void CLRSemaphore::Close()
LIMITED_METHOD_CONTRACT;
if (m_handle != INVALID_HANDLE_VALUE) {
- if (!CLRSyncHosted()) {
- CloseHandle(m_handle);
- }
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- else {
- ((IHostSemaphore*)m_handle)->Release();
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
+ CloseHandle(m_handle);
m_handle = INVALID_HANDLE_VALUE;
}
}
@@ -927,75 +527,11 @@ BOOL CLRSemaphore::Release(LONG lReleaseCount, LONG *lpPreviousCount)
}
CONTRACTL_END;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (CLRSyncHosted())
- {
- #undef ReleaseSemaphore
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = ((IHostSemaphore*)m_handle)->ReleaseSemaphore(lReleaseCount,lpPreviousCount);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- #define ReleaseSemaphore(hSemaphore, lReleaseCount, lpPreviousCount) \
- Dont_Use_ReleaseSemaphore(hSemaphore, lReleaseCount, lpPreviousCount)
- return hr == S_OK;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
return ::UnsafeReleaseSemaphore(m_handle, lReleaseCount, lpPreviousCount);
}
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-static DWORD HostSemaphoreWait (void *args, DWORD timeout, DWORD option)
-{
- CONTRACTL
- {
- if ((option & WAIT_ALERTABLE))
- {
- THROWS; // Thread::DoAppropriateWait can throw
- }
- else
- {
- NOTHROW;
- }
- GC_NOTRIGGER;
- SO_TOLERANT;
- PRECONDITION(CheckPointer(args));
- }
- CONTRACTL_END;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = ((IHostSemaphore*)args)->Wait(timeout,option);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (hr == S_OK) {
- return WAIT_OBJECT_0;
- }
- else if (hr == HOST_E_INTERRUPTED) {
- _ASSERTE (option & WAIT_ALERTABLE);
- Thread *pThread = GetThread();
- if (pThread)
- {
- Thread::UserInterruptAPC(APC_Code);
- }
- return WAIT_IO_COMPLETION;
- }
- else if (hr == HOST_E_TIMEOUT) {
- return WAIT_TIMEOUT;
- }
- else if (hr == E_FAIL) {
- _ASSERTE (!"Unknown host wait failure");
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- {
- _ASSERTE (!"Unknown host wait return");
- }
- return 0;
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
DWORD CLRSemaphore::Wait(DWORD dwMilliseconds, BOOL alertable)
{
@@ -1029,25 +565,6 @@ DWORD CLRSemaphore::Wait(DWORD dwMilliseconds, BOOL alertable)
Thread *pThread = GetThread();
_ASSERTE (pThread || !g_fEEStarted || dbgOnly_IsSpecialEEThread());
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (CLRSyncHosted())
- {
- if (pThread && alertable) {
- return pThread->DoAppropriateWait(HostSemaphoreWait,
- m_handle,dwMilliseconds,
- alertable?WaitMode_Alertable:WaitMode_None,
- NULL);
- }
- else {
- DWORD option = 0;
- if (alertable) {
- option |= WAIT_ALERTABLE;
- }
- return HostSemaphoreWait((IHostSemaphore*)m_handle,dwMilliseconds,option);
- }
- }
- else
-#endif // !FEATURE_INCLUDE_ALL_INTERFACES
{
// TODO wwl: if alertable is FALSE, do we support a host to break a deadlock?
// Currently we can not call through DoAppropriateWait because of CannotThrowComplusException.
@@ -1061,7 +578,6 @@ DWORD CLRSemaphore::Wait(DWORD dwMilliseconds, BOOL alertable)
DWORD result = WAIT_FAILED;
EX_TRY
{
- LeaveRuntimeHolder holder((size_t)WaitForSingleObjectEx);
result = WaitForSingleObjectEx(m_handle,dwMilliseconds,alertable);
}
EX_CATCH
@@ -1085,17 +601,9 @@ void CLRMutex::Create(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwne
}
CONTRACTL_END;
- if (bInitialOwner)
- {
- Thread::BeginThreadAffinity();
- }
m_handle = WszCreateMutex(lpMutexAttributes,bInitialOwner,lpName);
if (m_handle == NULL)
{
- if (bInitialOwner)
- {
- Thread::EndThreadAffinity();
- }
ThrowOutOfMemory();
}
}
@@ -1125,7 +633,6 @@ BOOL CLRMutex::Release()
BOOL fRet = ReleaseMutex(m_handle);
if (fRet)
{
- Thread::EndThreadAffinity();
EE_LOCK_RELEASED(this);
}
return fRet;
@@ -1141,12 +648,7 @@ DWORD CLRMutex::Wait(DWORD dwMilliseconds, BOOL bAlertable)
}
CONTRACTL_END;
- Thread::BeginThreadAffinity();
DWORD fRet = WaitForSingleObjectEx(m_handle, dwMilliseconds, bAlertable);
- if ((fRet != WAIT_OBJECT_0) && (fRet != WAIT_ABANDONED))
- {
- Thread::EndThreadAffinity();
- }
if (fRet == WAIT_OBJECT_0)
{
diff --git a/src/vm/synch.h b/src/vm/synch.h
index 8605eea062..d88ec46342 100644
--- a/src/vm/synch.h
+++ b/src/vm/synch.h
@@ -42,10 +42,6 @@ public:
void CreateMonitorEvent(SIZE_T Cookie); // robust against initialization races - for exclusive use by AwareLock
-#ifdef FEATURE_RWLOCK
- void CreateRWLockReaderEvent(BOOL bInitialState, CRWLock* pRWLock);
- void CreateRWLockWriterEvent(BOOL bInitialState, CRWLock* pRWLock);
-#endif
// Create an Event that is not host aware
void CreateOSAutoEvent (BOOL bInitialState);
@@ -72,7 +68,6 @@ public:
#ifndef DACCESS_COMPILE
HANDLE GetHandleUNHOSTED() {
LIMITED_METHOD_CONTRACT;
- _ASSERTE (IsOSEvent() || !CLRSyncHosted());
return m_handle;
}
#endif // DACCESS_COMPILE
diff --git a/src/vm/synchronizationcontextnative.cpp b/src/vm/synchronizationcontextnative.cpp
index 4c37b75c73..ac67f39349 100644
--- a/src/vm/synchronizationcontextnative.cpp
+++ b/src/vm/synchronizationcontextnative.cpp
@@ -20,7 +20,6 @@
#endif
#include "synchronizationcontextnative.h"
-#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
FCIMPL3(DWORD, SynchronizationContextNative::WaitHelper, PTRArray *handleArrayUNSAFE, CLR_BOOL waitAll, DWORD millis)
{
FCALL_CONTRACT;
@@ -46,7 +45,6 @@ FCIMPL3(DWORD, SynchronizationContextNative::WaitHelper, PTRArray *handleArrayUN
return ret;
}
FCIMPLEND
-#endif // #ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
#ifdef FEATURE_APPX
diff --git a/src/vm/synchronizationcontextnative.h b/src/vm/synchronizationcontextnative.h
index ebbcc2faf9..917d3a0afb 100644
--- a/src/vm/synchronizationcontextnative.h
+++ b/src/vm/synchronizationcontextnative.h
@@ -19,9 +19,7 @@ class SynchronizationContextNative
{
public:
-#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
static FCDECL3(DWORD, WaitHelper, PTRArray *handleArrayUNSAFE, CLR_BOOL waitAll, DWORD millis);
-#endif
#ifdef FEATURE_APPX
static void* QCALLTYPE GetWinRTDispatcherForCurrentThread();
diff --git a/src/vm/testhookmgr.cpp b/src/vm/testhookmgr.cpp
index 48370134d2..f9338745b7 100644
--- a/src/vm/testhookmgr.cpp
+++ b/src/vm/testhookmgr.cpp
@@ -638,7 +638,6 @@ VOID CLRTestHookManager::DoApproriateWait( int cObjs, HANDLE *pObjs, INT32 iTime
result=thread->DoAppropriateWait(cObjs,pObjs,bWaitAll,iTimeout,WaitMode_Alertable,NULL);
else
{
- LeaveRuntimeHolder holder((size_t)WaitForSingleObjectEx);
result = WaitForMultipleObjectsEx(cObjs,pObjs,bWaitAll,iTimeout,TRUE);
}
}
diff --git a/src/vm/threadpoolrequest.cpp b/src/vm/threadpoolrequest.cpp
index a5c1c4263d..247deea304 100644
--- a/src/vm/threadpoolrequest.cpp
+++ b/src/vm/threadpoolrequest.cpp
@@ -25,9 +25,6 @@
#include "eeconfig.h"
#include "corhost.h"
#include "nativeoverlapped.h"
-#ifdef FEATURE_REMOTING
-#include "crossdomaincalls.h"
-#endif
#include "appdomain.inl"
BYTE PerAppDomainTPCountList::s_padding[64 - sizeof(LONG)];
@@ -371,11 +368,8 @@ void UnManagedPerAppDomainTPCount::SetAppDomainRequestsActive()
LONG prevCount = FastInterlockCompareExchange(&m_outstandingThreadRequestCount, count+1, count);
if (prevCount == count)
{
- if (!CLRThreadpoolHosted())
- {
- ThreadpoolMgr::MaybeAddWorkingWorker();
- ThreadpoolMgr::EnsureGateThreadRunning();
- }
+ ThreadpoolMgr::MaybeAddWorkingWorker();
+ ThreadpoolMgr::EnsureGateThreadRunning();
break;
}
count = prevCount;
@@ -611,11 +605,8 @@ void ManagedPerAppDomainTPCount::SetAppDomainRequestsActive()
LONG prev = FastInterlockCompareExchange(&m_numRequestsPending, count+1, count);
if (prev == count)
{
- if (!CLRThreadpoolHosted())
- {
- ThreadpoolMgr::MaybeAddWorkingWorker();
- ThreadpoolMgr::EnsureGateThreadRunning();
- }
+ ThreadpoolMgr::MaybeAddWorkingWorker();
+ ThreadpoolMgr::EnsureGateThreadRunning();
break;
}
count = prev;
@@ -691,7 +682,7 @@ void ManagedPerAppDomainTPCount::ClearAppDomainUnloading()
// AD.
//
VolatileStore(&m_numRequestsPending, (LONG)ThreadpoolMgr::NumberOfProcessors);
- if (!CLRThreadpoolHosted() && ThreadpoolMgr::IsInitialized())
+ if (ThreadpoolMgr::IsInitialized())
{
ThreadpoolMgr::MaybeAddWorkingWorker();
ThreadpoolMgr::EnsureGateThreadRunning();
diff --git a/src/vm/threads.cpp b/src/vm/threads.cpp
index 5bb9bf35d7..a126d1c816 100644
--- a/src/vm/threads.cpp
+++ b/src/vm/threads.cpp
@@ -30,16 +30,10 @@
#include "jitinterface.h"
#include "appdomainstack.inl"
#include "eventtrace.h"
-#ifdef FEATURE_REMOTING
-#include "appdomainhelper.h"
-#endif
#include "comutilnative.h"
#include "finalizerthread.h"
#include "threadsuspend.h"
-#ifdef FEATURE_FUSION
-#include "fusion.h"
-#endif
#include "wrappers.h"
#include "nativeoverlapped.h"
@@ -60,10 +54,6 @@
#include "olecontexthelpers.h"
#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
-#ifdef FEATURE_UEF_CHAINMANAGER
-// This is required to register our UEF callback with the UEF chain manager
-#include <mscoruefwrapper.h>
-#endif // FEATURE_UEF_CHAINMANAGER
SPTR_IMPL(ThreadStore, ThreadStore, s_pThreadStore);
@@ -72,7 +62,6 @@ CLREvent *ThreadStore::s_pWaitForStackCrawlEvent;
#ifndef DACCESS_COMPILE
-#include "constrainedexecutionregion.h"
BOOL Thread::s_fCleanFinalizedThread = FALSE;
@@ -392,18 +381,6 @@ BOOL Thread::Alert ()
CONTRACTL_END;
BOOL fRetVal = FALSE;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HostComHolder<IHostTask> pHostTask(GetHostTaskWithAddRef());
- if (pHostTask && !HasThreadStateNC(TSNC_OSAlertableWait)) {
- HRESULT hr;
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pHostTask->Alert();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- fRetVal = SUCCEEDED(hr);
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
HANDLE handle = GetThreadHandle();
if (handle != INVALID_HANDLE_VALUE && handle != SWITCHOUT_HANDLE_VALUE)
@@ -415,64 +392,6 @@ BOOL Thread::Alert ()
return fRetVal;
}
-struct HostJoinOnThreadArgs
-{
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTask *pHostTask;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- WaitMode mode;
-};
-
-DWORD HostJoinOnThread (void *args, DWORD timeout, DWORD option)
-{
- CONTRACTL {
- THROWS;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- }
- CONTRACTL_END;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HostJoinOnThreadArgs *joinArgs = (HostJoinOnThreadArgs*) args;
- IHostTask *pHostTask = joinArgs->pHostTask;
- if ((joinArgs->mode & WaitMode_InDeadlock) == 0)
- {
- option |= WAIT_NOTINDEADLOCK;
- }
-
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pHostTask->Join(timeout, option);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (hr == S_OK) {
- return WAIT_OBJECT_0;
- }
- else if (hr == HOST_E_TIMEOUT) {
- return WAIT_TIMEOUT;
- }
- else if (hr == HOST_E_INTERRUPTED) {
- _ASSERTE (option & WAIT_ALERTABLE);
- Thread *pThread = GetThread();
- if (pThread)
- {
- Thread::UserInterruptAPC(APC_Code);
- }
- return WAIT_IO_COMPLETION;
- }
- else if (hr == HOST_E_ABANDONED)
- {
- // The task died.
- return WAIT_OBJECT_0;
- }
- else if (hr == HOST_E_DEADLOCK)
- {
- _ASSERTE ((option & WAIT_NOTINDEADLOCK) == 0);
- RaiseDeadLockException();
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- _ASSERTE (!"Unknown host join status\n");
- return E_FAIL;
-}
-
DWORD Thread::Join(DWORD timeout, BOOL alertable)
{
@@ -492,19 +411,6 @@ DWORD Thread::JoinEx(DWORD timeout, WaitMode mode)
Thread *pCurThread = GetThread();
_ASSERTE(pCurThread || dbgOnly_IsSpecialEEThread());
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HostComHolder<IHostTask> pHostTask (GetHostTaskWithAddRef());
- if (pHostTask != NULL) {
- HostJoinOnThreadArgs args = {pHostTask, mode};
- if (pCurThread) {
- return GetThread()->DoAppropriateWait(HostJoinOnThread, &args, timeout, mode);
- }
- else {
- return HostJoinOnThread (&args,timeout,alertable?WAIT_ALERTABLE:0);
- }
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
// We're not hosted, so WaitMode_InDeadlock is irrelevant. Clear it, so that this wait can be
// forwarded to a SynchronizationContext if needed.
@@ -537,15 +443,6 @@ BOOL Thread::SetThreadPriority(
CONTRACTL_END;
BOOL fRet;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HostComHolder<IHostTask> pHostTask (GetHostTaskWithAddRef());
- if (pHostTask != NULL) {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- fRet = (pHostTask->SetPriority(nPriority) == S_OK);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
if (GetThreadHandle() == INVALID_HANDLE_VALUE) {
// When the thread starts running, we will set the thread priority.
@@ -577,19 +474,6 @@ int Thread::GetThreadPriority()
CONTRACTL_END;
int nRetVal = -1;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HostComHolder<IHostTask> pHostTask(GetHostTaskWithAddRef());
- if (pHostTask != NULL) {
- int nPriority;
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pHostTask->GetPriority(&nPriority);
- END_SO_TOLERANT_CODE_CALLING_HOST;
-
- nRetVal = (hr == S_OK)?nPriority:THREAD_PRIORITY_ERROR_RETURN;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
if (GetThreadHandle() == INVALID_HANDLE_VALUE) {
nRetVal = FALSE;
}
@@ -612,14 +496,6 @@ void Thread::ChooseThreadCPUGroupAffinity()
if (!CPUGroupInfo::CanEnableGCCPUGroups() || !CPUGroupInfo::CanEnableThreadUseAllCpuGroups())
return;
-#ifndef FEATURE_CORECLR
- // We only handle the non-hosted case here. If CLR is hosted, the hosting
- // process controls the physical OS Threads. If CLR is not hosted, we can
- // set thread group affinity on OS threads directly.
- HostComHolder<IHostTask> pHostTask (GetHostTaskWithAddRef());
- if (pHostTask != NULL)
- return;
-#endif //!FEATURE_CORECLR
//Borrow the ThreadStore Lock here: Lock ThreadStore before distributing threads
ThreadStoreLockHolder TSLockHolder(TRUE);
@@ -652,14 +528,6 @@ void Thread::ClearThreadCPUGroupAffinity()
if (!CPUGroupInfo::CanEnableGCCPUGroups() || !CPUGroupInfo::CanEnableThreadUseAllCpuGroups())
return;
-#ifndef FEATURE_CORECLR
- // We only handle the non-hosted case here. If CLR is hosted, the hosting
- // process controls the physical OS Threads. If CLR is not hosted, we can
- // set thread group affinity on OS threads directly.
- HostComHolder<IHostTask> pHostTask (GetHostTaskWithAddRef());
- if (pHostTask != NULL)
- return;
-#endif //!FEATURE_CORECLR
ThreadStoreLockHolder TSLockHolder(TRUE);
@@ -692,27 +560,11 @@ DWORD Thread::StartThread()
_ASSERTE (m_Creater.IsCurrentThread());
m_Creater.Clear();
#endif
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HostComHolder<IHostTask> pHostTask(GetHostTaskWithAddRef());
- if (pHostTask)
- {
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pHostTask->Start();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (hr == S_OK) {
- dwRetVal = 1;
- }
- else
- dwRetVal = (DWORD) -1;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- {
- _ASSERTE (GetThreadHandle() != INVALID_HANDLE_VALUE &&
- GetThreadHandle() != SWITCHOUT_HANDLE_VALUE);
- dwRetVal = ::ResumeThread(GetThreadHandle());
- }
+
+ _ASSERTE (GetThreadHandle() != INVALID_HANDLE_VALUE &&
+ GetThreadHandle() != SWITCHOUT_HANDLE_VALUE);
+ dwRetVal = ::ResumeThread(GetThreadHandle());
+
return dwRetVal;
}
@@ -847,38 +699,6 @@ Thread* SetupThread(BOOL fInternal)
EnsurePreemptiveModeIfException ensurePreemptive;
#ifdef _DEBUG
- // Verify that for fiber mode, we do not have a thread that matches the current StackBase.
- if (CLRTaskHosted()) {
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *provider = CorHost2::GetHostTaskManager();
-
- IHostTask *pHostTask = NULL;
-
- // Starting with SQL11 GetCurrentTask() may actually create a task if one does not
- // exist yet. To avoid an unbalanced BeginThreadAffinity/EndThreadAffinity assert
- // we must not call it inside a scope protected by ThreadStoreLockHolder (which calls
- // BeginThreadAffinity/EndThreadAffinity in its constructor/destructor). Post SQL11,
- // SQL may create the task in BeginThreadAffinity() but until then we have to be
- // able to run on CHK bits w/o tripping the ASSERT.
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- provider->GetCurrentTask(&pHostTask);
- END_SO_TOLERANT_CODE_CALLING_HOST;
-
- if (pHostTask)
- {
- ThreadStoreLockHolder TSLockHolder;
- SafeComHolder<IHostTask> pHostTaskHolder(pHostTask);
- while ((pThread = ThreadStore::s_pThreadStore->GetAllThreadList(pThread, 0, 0)) != NULL)
- {
- _ASSERTE ((pThread->m_State&Thread::TS_Unstarted) || pThread->GetHostTask() != pHostTask);
- }
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- }
-#endif
-
-#ifdef _DEBUG
CHECK chk;
if (g_pConfig->SuppressChecks())
{
@@ -895,32 +715,11 @@ Thread* SetupThread(BOOL fInternal)
if (ThreadStore::s_pThreadStore->m_PendingThreadCount != 0)
{
DWORD ourOSThreadId = ::GetCurrentThreadId();
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTask *curHostTask = NULL;
- IHostTaskManager *hostTaskManager = CorHost2::GetHostTaskManager();
- if (hostTaskManager) {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hostTaskManager->GetCurrentTask(&curHostTask);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-
- SafeComHolder<IHostTask> pHostTaskHolder(curHostTask);
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
ThreadStoreLockHolder TSLockHolder;
_ASSERTE(pThread == NULL);
while ((pThread = ThreadStore::s_pThreadStore->GetAllThreadList(pThread, Thread::TS_Unstarted | Thread::TS_FailStarted, Thread::TS_Unstarted)) != NULL)
{
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (curHostTask)
- {
- if (curHostTask == pThread->GetHostTask())
- {
- break;
- }
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
if (pThread->GetOSThreadId() == ourOSThreadId)
{
break;
@@ -1184,13 +983,7 @@ void DestroyThread(Thread *th)
#endif // _TARGET_X86_
#endif // WIN64EXCEPTIONS
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- // If CLR is hosted, don't call OnThreadTerminate here. Instead the host will call
- // ExitTask which calls DetachThread.
- if (th->GetHostTask() == NULL)
-#else // !FEATURE_INCLUDE_ALL_INTERFACES
if (g_fEEShutDown == 0)
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
th->SetThreadState(Thread::TS_ReportDead);
th->OnThreadTerminate(FALSE);
@@ -1347,7 +1140,7 @@ DWORD GetRuntimeId()
//---------------------------------------------------------------------------
// Creates new Thread for reverse p-invoke calls.
//---------------------------------------------------------------------------
-Thread* __stdcall CreateThreadBlockThrow()
+Thread* WINAPI CreateThreadBlockThrow()
{
WRAPPER_NO_CONTRACT;
@@ -1919,11 +1712,6 @@ Thread::Thread()
m_dwLockCount = 0;
m_dwBeginLockCount = 0;
-#ifndef FEATURE_CORECLR
- m_dwBeginCriticalRegionCount = 0;
- m_dwCriticalRegionCount = 0;
- m_dwThreadAffinityCount = 0;
-#endif // !FEATURE_CORECLR
#ifdef _DEBUG
dbg_m_cSuspendedThreads = 0;
@@ -1985,10 +1773,6 @@ Thread::Thread()
m_LastThrownObjectHandle = NULL;
m_ltoIsUnhandled = FALSE;
- #if HAS_TRACK_CXX_EXCEPTION_CODE_HACK // Is C++ exception code tracking turned on?vs
- m_LastCxxSEHExceptionCode = 0;
- #endif // HAS_TRACK_CXX_EXCEPTION_CODE_HACK
-
m_AbortReason = NULL;
@@ -2041,6 +1825,7 @@ Thread::Thread()
#ifdef FEATURE_COMINTEROP
m_fDisableComObjectEagerCleanup = false;
#endif //FEATURE_COMINTEROP
+ m_fHasDeadThreadBeenConsideredForGCTrigger = false;
m_Context = NULL;
m_TraceCallCount = 0;
m_ThrewControlForThread = 0;
@@ -2085,13 +1870,6 @@ Thread::Thread()
m_dwAbortPoint = 0;
#endif
-#ifdef STRESS_THREAD
- m_stressThreadCount = -1;
-#endif
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- m_pHostTask = NULL;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
m_pFiberData = NULL;
m_TaskId = INVALID_TASK_ID;
@@ -2101,7 +1879,7 @@ Thread::Thread()
DWORD_PTR *ttInfo = NULL;
size_t nBytes = MaxThreadRecord *
(sizeof(FiberSwitchInfo)-sizeof(size_t)+MaxStackDepth*sizeof(size_t));
- if (CLRTaskHosted() || g_pConfig->SaveThreadInfo()) {
+ if (g_pConfig->SaveThreadInfo()) {
ttInfo = new DWORD_PTR[(nBytes/sizeof(DWORD_PTR))*ThreadTrackInfo_Max];
memset(ttInfo,0,nBytes*ThreadTrackInfo_Max);
}
@@ -2116,14 +1894,7 @@ Thread::Thread()
m_OSContext = new CONTEXT();
NewHolder<CONTEXT> contextHolder(m_OSContext);
- if (CLRTaskHosted())
- {
- m_pSavedRedirectContext = new CONTEXT();
- }
- else
- {
- m_pSavedRedirectContext = NULL;
- }
+ m_pSavedRedirectContext = NULL;
NewHolder<CONTEXT> savedRedirectContextHolder(m_pSavedRedirectContext);
#ifdef FEATURE_COMINTEROP
@@ -2166,7 +1937,6 @@ Thread::Thread()
m_fCompletionPortDrained = FALSE;
- m_WorkingOnThreadContext = NULL;
m_debuggerActivePatchSkipper = NULL;
m_dwThreadHandleBeingUsed = 0;
SetProfilerCallbacksAllowed(TRUE);
@@ -2217,10 +1987,8 @@ Thread::Thread()
contextHolder.SuppressRelease();
savedRedirectContextHolder.SuppressRelease();
-#ifndef FEATURE_LEAK_CULTURE_INFO
managedThreadCurrentCulture = NULL;
managedThreadCurrentUICulture = NULL;
-#endif // FEATURE_LEAK_CULTURE_INFO
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
m_ullProcessorUsageBaseline = 0;
@@ -2254,21 +2022,6 @@ BOOL Thread::InitThread(BOOL fInternal)
}
CONTRACTL_END;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *provider = CorHost2::GetHostTaskManager();
- if (provider) {
- if (m_pHostTask == NULL)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- provider->GetCurrentTask(&m_pHostTask);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
- // workaround wwl: finalizer thread is not created by SQL
- if (m_pHostTask == NULL && !fInternal) {
- ThrowHR(HOST_E_INVALIDOPERATION);
- }
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
HANDLE hDup = INVALID_HANDLE_VALUE;
BOOL ret = TRUE;
@@ -2291,7 +2044,6 @@ BOOL Thread::InitThread(BOOL fInternal)
#ifndef FEATURE_PAL
// workaround: Remove this when we flow impersonation token to host.
- ThreadAffinityHolder affinityHolder(FALSE);
BOOL reverted = FALSE;
HANDLE threadToken = INVALID_HANDLE_VALUE;
#endif // !FEATURE_PAL
@@ -2319,7 +2071,7 @@ BOOL Thread::InitThread(BOOL fInternal)
// THREAD_SUSPEND_RESUME nor THREAD_GET_CONTEXT. We need to be able to suspend the thread, and we need to be
// able to get its context. Therefore, if we're impersonating, we revert to self, dup the handle, then
// re-impersonate before we leave this routine.
- if (!RevertIfImpersonated(&reverted, &threadToken, &affinityHolder))
+ if (!RevertIfImpersonated(&reverted, &threadToken))
{
COMPlusThrowWin32();
}
@@ -2419,28 +2171,17 @@ BOOL Thread::AllocHandles()
{
WRAPPER_NO_CONTRACT;
- _ASSERTE(!m_SafeEvent.IsValid());
- _ASSERTE(!m_UserSuspendEvent.IsValid());
_ASSERTE(!m_DebugSuspendEvent.IsValid());
_ASSERTE(!m_EventWait.IsValid());
BOOL fOK = TRUE;
EX_TRY {
// create a manual reset event for getting the thread to a safe point
- m_SafeEvent.CreateManualEvent(FALSE);
- m_UserSuspendEvent.CreateManualEvent(FALSE);
m_DebugSuspendEvent.CreateManualEvent(FALSE);
m_EventWait.CreateManualEvent(TRUE);
}
EX_CATCH {
fOK = FALSE;
- if (!m_SafeEvent.IsValid()) {
- m_SafeEvent.CloseEvent();
- }
-
- if (!m_UserSuspendEvent.IsValid()) {
- m_UserSuspendEvent.CloseEvent();
- }
if (!m_DebugSuspendEvent.IsValid()) {
m_DebugSuspendEvent.CloseEvent();
@@ -2545,15 +2286,6 @@ BOOL Thread::HasStarted(BOOL bRequiresTSL)
SetupThreadForHost();
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (m_pHostTask)
- {
- // If we have notify host of ICLRTask, host will call code:ExitTask to release
- // its reference to ICLRTask. Also host may call SwitchOut and SwitchIn.
- // ExitTask needs Thread in TLS.
- fKeepTLS = TRUE;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
ThreadStore::TransferStartedThread(this, bRequiresTSL);
@@ -2662,30 +2394,8 @@ FAILURE:
}
#endif // PROFILING_SUPPORTED
- // Is there a pending user suspension?
- if (m_State & TS_SuspendUnstarted)
- {
- BOOL doSuspend = FALSE;
-
- {
- ThreadStoreLockHolder TSLockHolder;
-
- // Perhaps we got resumed before it took effect?
- if (m_State & TS_SuspendUnstarted)
- {
- FastInterlockAnd((ULONG *) &m_State, ~TS_SuspendUnstarted);
- SetupForSuspension(TS_UserSuspendPending);
- MarkForSuspension(TS_UserSuspendPending);
- doSuspend = TRUE;
- }
- }
-
- if (doSuspend)
- {
- GCX_PREEMP();
- WaitSuspendEvents();
- }
- }
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(m_State & TS_SuspendUnstarted));
}
return res;
@@ -2764,17 +2474,16 @@ void Thread::HandleThreadStartupFailure()
}
#ifndef FEATURE_PAL
-BOOL RevertIfImpersonated(BOOL *bReverted, HANDLE *phToken, ThreadAffinityHolder *pTAHolder)
+BOOL RevertIfImpersonated(BOOL *bReverted, HANDLE *phToken)
{
WRAPPER_NO_CONTRACT;
BOOL bImpersonated = OpenThreadToken(GetCurrentThread(), // we are assuming that if this call fails,
- TOKEN_IMPERSONATE, // we are not impersonating. There is no win32
- TRUE, // api to figure this out. The only alternative
+ TOKEN_IMPERSONATE, // we are not impersonating. There is no win32
+ TRUE, // api to figure this out. The only alternative
phToken); // is to use NtCurrentTeb->IsImpersonating().
if (bImpersonated)
{
- pTAHolder->Acquire();
*bReverted = RevertToSelf();
return *bReverted;
@@ -2817,21 +2526,15 @@ BOOL Thread::CreateNewThread(SIZE_T stackSize, LPTHREAD_START_ROUTINE start, voi
_ASSERTE(stackSize <= 0xFFFFFFFF);
#ifndef FEATURE_PAL
- ThreadAffinityHolder affinityHolder(FALSE);
HandleHolder token;
BOOL bReverted = FALSE;
- bRet = RevertIfImpersonated(&bReverted, &token, &affinityHolder);
+ bRet = RevertIfImpersonated(&bReverted, &token);
if (bRet != TRUE)
return bRet;
#endif // !FEATURE_PAL
m_StateNC = (ThreadStateNoConcurrency)((ULONG)m_StateNC | TSNC_CLRCreatedThread);
- if (!CLRTaskHosted()) {
- bRet = CreateNewOSThread(stackSize, start, args);
- }
- else {
- bRet = CreateNewHostTask(stackSize, start, args);
- }
+ bRet = CreateNewOSThread(stackSize, start, args);
#ifndef FEATURE_PAL
UndoRevert(bReverted, token);
#endif // !FEATURE_PAL
@@ -2842,7 +2545,7 @@ BOOL Thread::CreateNewThread(SIZE_T stackSize, LPTHREAD_START_ROUTINE start, voi
// This is to avoid the 64KB/1MB aliasing problem present on Pentium 4 processors,
// which can significantly impact performance with HyperThreading enabled
-DWORD __stdcall Thread::intermediateThreadProc(PVOID arg)
+DWORD WINAPI Thread::intermediateThreadProc(PVOID arg)
{
WRAPPER_NO_CONTRACT;
@@ -2898,106 +2601,6 @@ HANDLE Thread::CreateUtilityThread(Thread::StackSizeBucket stackSizeBucket, LPTH
return hThread;
}
-#ifndef FEATURE_CORECLR
-/*
- The following are copied from MSDN:
- http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/thread_stack_size.asp
-
- To change the initially committed stack space, use the dwStackSize parameter of the CreateThread,
- CreateRemoteThread, or CreateFiber function. This value is rounded up to the nearest page.
- Generally, the reserve size is the default reserve size specified in the executable header.
- However, if the initially committed size specified by dwStackSize is larger than the default reserve size,
- the reserve size is this new commit size rounded up to the nearest multiple of 1 MB.
-
- To change the reserved stack size, set the dwCreationFlags parameter of CreateThread or CreateRemoteThread
- to STACK_SIZE_PARAM_IS_A_RESERVATION and use the dwStackSize parameter. In this case, the initially
- committed size is the default size specified in the executable header.
-
-*/
-BOOL Thread::CheckThreadStackSize(SIZE_T *pSizeToCommitOrReserve,
- BOOL isSizeToReserve // When TRUE, the previous argument is the stack size to reserve.
- // Otherwise, it is the size to commit.
- )
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- //g_SystemInfo is global pointer to SYSTEM_INFO struct
- SIZE_T dwAllocSize = (SIZE_T)g_SystemInfo.dwAllocationGranularity;
- SIZE_T dwPageSize = (SIZE_T)g_SystemInfo.dwPageSize;
-
- //Don't want users creating threads
- // with a stackSize request < 256K
- //This value may change up or down as we see fit so don't doc to user
- //
- if(isSizeToReserve && 0x40000 > (*pSizeToCommitOrReserve))
- {
- *pSizeToCommitOrReserve = 0x40000;
- }
-
- *pSizeToCommitOrReserve = ALIGN(*pSizeToCommitOrReserve, dwAllocSize);
-
- //
- // Let's get the stack sizes from the PE file that started process.
- //
- SIZE_T ExeSizeOfStackReserve = 0;
- SIZE_T ExeSizeOfStackCommit = 0;
-
- if (!GetProcessDefaultStackSize(&ExeSizeOfStackReserve, &ExeSizeOfStackCommit))
- return FALSE;
-
- // Now let's decide which sizes OS are going to use.
- SIZE_T sizeToReserve = 0;
- SIZE_T sizeToCommit = 0;
-
- if (isSizeToReserve) {
- // The passed-in *pSizeToCommitOrReserve is the stack size to reserve.
- sizeToReserve = *pSizeToCommitOrReserve;
- // OS will use ExeSizeOfStackCommit as the commited size.
- sizeToCommit = ExeSizeOfStackCommit;
- }
- else {
- // The passed-in *pSizeToCommitOrReserve is the stack size to commit.
- sizeToCommit = *pSizeToCommitOrReserve;
- // OS will use ExeSizeOfStackReserve as the reserved size.
- sizeToReserve = ExeSizeOfStackReserve;
-
- // However, if the initially committed size specified by dwStackSize is larger than
- // the default reserve size, the reserve size is this new commit size rounded up to
- // the nearest multiple of 1 MB.
- if (sizeToCommit > ExeSizeOfStackReserve) {
- sizeToReserve = ALIGN(sizeToCommit, 0x1000000);
- }
-
- if (!g_pConfig->GetDisableCommitThreadStack())
- {
- // We will commit the full stack when a thread starts. But if the PageFile is full, we may hit
- // stack overflow at random places during startup.
- // Therefore if we are unlikely to obtain space from PageFile, we will fail creation of a thread.
-
- *pSizeToCommitOrReserve = sizeToReserve - HARD_GUARD_REGION_SIZE;
-
- // OS's behavior is not consistent on if guard page is marked when we ask OS to commit the stack
- // up to 2nd to last page.
- // On Win2k3, the 2nd to last page is marked with guard bit.
- // On WinXP, the 2nd to last page is not marked with guard bit.
- // To be safe, we will not commit the 2nd to last page.
- *pSizeToCommitOrReserve -= HARD_GUARD_REGION_SIZE;
- // To make it more interesting, on X64, if we request to commit stack except the last two pages,
- // OS commit the whole stack, and mark the last two pages as guard page.
- *pSizeToCommitOrReserve -= 2*HARD_GUARD_REGION_SIZE;
- }
- }
-
- // Ok, we now know what sizes OS will use to create the thread.
- // Check to see if we have the room for guard pages.
- return ThreadWillCreateGuardPage(sizeToReserve, sizeToCommit);
-}
-#endif // FEATURE_CORECLR
BOOL Thread::GetProcessDefaultStackSize(SIZE_T* reserveSize, SIZE_T* commitSize)
{
@@ -3059,7 +2662,6 @@ BOOL Thread::CreateNewOSThread(SIZE_T sizeToCommitOrReserve, LPTHREAD_START_ROUT
HANDLE h = NULL;
DWORD dwCreationFlags = CREATE_SUSPENDED;
-#ifdef FEATURE_CORECLR
dwCreationFlags |= STACK_SIZE_PARAM_IS_A_RESERVATION;
#ifndef FEATURE_PAL // the PAL does its own adjustments as necessary
@@ -3070,29 +2672,6 @@ BOOL Thread::CreateNewOSThread(SIZE_T sizeToCommitOrReserve, LPTHREAD_START_ROUT
sizeToCommitOrReserve = OS_PAGE_SIZE + 1;
}
#endif // !FEATURE_PAL
-#else
- if(sizeToCommitOrReserve != 0)
- {
- dwCreationFlags |= STACK_SIZE_PARAM_IS_A_RESERVATION;
-
- //
- // In this case we also force CommitThreadStack to commit the whole stack, even if we're configured not to do so.
- // The config value is used to reduce the resource usage for default stack allocations; for non-default allocations,
- // we assume the user has given us the correct size (and they're really going to need it). This way we don't
- // need to offer a Thread constructor that takes a confusing "stack size param is a commit size" parameter.
- //
- SetThreadStateNC(TSNC_ForceStackCommit);
- }
-
- // Check that we will have (reserved and never committed) guard pages at the end of the stack.
- // If this call returns false then it will lead to an OOM exception on return.
- // This is reasonable since a large stack was requested and we couldn't get it.
- if(!CheckThreadStackSize(&sizeToCommitOrReserve,
- (sizeToCommitOrReserve != 0)))
- {
- return FALSE;
- }
-#endif
intermediateThreadParam* lpThreadArgs = new (nothrow) intermediateThreadParam;
if (lpThreadArgs == NULL)
@@ -3149,65 +2728,6 @@ BOOL Thread::CreateNewOSThread(SIZE_T sizeToCommitOrReserve, LPTHREAD_START_ROUT
return TRUE;
}
-
-
-BOOL Thread::CreateNewHostTask(SIZE_T stackSize, LPTHREAD_START_ROUTINE start, void *args)
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- // Make sure we have all our handles, in case someone tries to suspend us
- // as we are starting up.
-
- if (!AllocHandles())
- {
- return FALSE;
- }
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTask *pHostTask = NULL;
-
- if (CorHost2::GetHostTaskManager()) {
- //If you change this value to pass a SIZE_T stackSize you must
- // remove this _ASSERTE(stackSize <= 0xFFFFFFFF); from
- // CreateNewThread
- //
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = CorHost2::GetHostTaskManager()->CreateTask((DWORD)stackSize, start, args, &pHostTask);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (hr != S_OK)
- return FALSE;
- }
-
- _ASSERTE(!m_fPreemptiveGCDisabled); // leave in preemptive until HasStarted.
-
- // Before we do the resume, we need to take note of the new ThreadId. This
- // is necessary because -- before the thread starts executing at KickofThread --
- // it may perform some DllMain DLL_THREAD_ATTACH notifications. These could
- // call into managed code. During the consequent SetupThread, we need to
- // perform the Thread::HasStarted call instead of going through the normal
- // 'new thread' pathway.
- _ASSERTE(m_pHostTask == NULL);
- _ASSERTE(pHostTask != NULL);
-
- m_pHostTask = pHostTask;
-
- FastInterlockIncrement(&ThreadStore::s_pThreadStore->m_PendingThreadCount);
-
-#ifdef _DEBUG
- m_Creater.SetToCurrentThread();
-#endif
-
- return TRUE;
-#else // !FEATURE_INCLUDE_ALL_INTERFACES
- return FALSE;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-}
-
//
// #threadDestruction
//
@@ -3335,11 +2855,6 @@ int Thread::DecExternalCount(BOOL holdingLock)
::CloseHandle(h);
SetThreadHandle(INVALID_HANDLE_VALUE);
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (m_pHostTask) {
- ReleaseHostTask();
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
// Switch back to cooperative mode to manipulate the thread.
if (pCurThread)
{
@@ -3517,14 +3032,6 @@ Thread::~Thread()
CloseHandle(GetThreadHandle());
}
- if (m_SafeEvent.IsValid())
- {
- m_SafeEvent.CloseEvent();
- }
- if (m_UserSuspendEvent.IsValid())
- {
- m_UserSuspendEvent.CloseEvent();
- }
if (m_DebugSuspendEvent.IsValid())
{
m_DebugSuspendEvent.CloseEvent();
@@ -3573,11 +3080,6 @@ Thread::~Thread()
_ASSERTE(m_pTLBTable == NULL);
_ASSERTE(m_TLBTableSize == 0);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (m_pHostTask) {
- ReleaseHostTask();
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#ifdef FEATURE_PREJIT
if (m_pIBCInfo) {
@@ -3889,15 +3391,6 @@ void Thread::OnThreadTerminate(BOOL holdingLock)
// Free all structures related to thread statics for this thread
DeleteThreadStaticData();
-#ifdef FEATURE_LEAK_CULTURE_INFO
- //Clear the references which could create cycles
- // This allows the GC to collect them
- THREADBASEREF thread = (THREADBASEREF) GetExposedObjectRaw();
- if (thread != NULL)
- {
- thread->ResetCulture();
- }
-#endif
}
if (GCHeapUtilities::IsGCHeapInitialized())
@@ -3907,7 +3400,7 @@ void Thread::OnThreadTerminate(BOOL holdingLock)
if (ThisThreadID == CurrentThreadID)
{
GCX_COOP();
- GCHeapUtilities::GetGCHeap()->FixAllocContext(&m_alloc_context, FALSE, NULL, NULL);
+ GCHeapUtilities::GetGCHeap()->FixAllocContext(&m_alloc_context, false, NULL, NULL);
m_alloc_context.init();
}
}
@@ -3958,26 +3451,19 @@ void Thread::OnThreadTerminate(BOOL holdingLock)
LOG((LF_SYNC, INFO3, "OnThreadTerminate obtain lock\n"));
ThreadSuspend::LockThreadStore(ThreadSuspend::SUSPEND_OTHER);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (ThisThreadID == CurrentThreadID && pCurrentThread)
- {
- // Before we call UnlockThreadStore, we remove out Thread from TLS
- // Therefore we will not dec the lock count on thread.
- DECTHREADLOCKCOUNTTHREAD(pCurrentThread);
- }
-#endif
}
if (GCHeapUtilities::IsGCHeapInitialized() && ThisThreadID != CurrentThreadID)
{
// We must be holding the ThreadStore lock in order to clean up alloc context.
// We should never call FixAllocContext during GC.
- GCHeapUtilities::GetGCHeap()->FixAllocContext(&m_alloc_context, FALSE, NULL, NULL);
+ GCHeapUtilities::GetGCHeap()->FixAllocContext(&m_alloc_context, false, NULL, NULL);
m_alloc_context.init();
}
FastInterlockOr((ULONG *) &m_State, TS_Dead);
ThreadStore::s_pThreadStore->m_DeadThreadCount++;
+ ThreadStore::s_pThreadStore->IncrementDeadThreadCountForGCTrigger();
if (IsUnstarted())
ThreadStore::s_pThreadStore->m_UnstartedThreadCount--;
@@ -4002,8 +3488,8 @@ void Thread::OnThreadTerminate(BOOL holdingLock)
if (m_State & TS_DebugSuspendPending)
UnmarkForSuspension(~TS_DebugSuspendPending);
- if (m_State & TS_UserSuspendPending)
- UnmarkForSuspension(~TS_UserSuspendPending);
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(m_State & TS_UserSuspendPending));
if (CurrentThreadID == ThisThreadID && IsAbortRequested())
{
@@ -4236,10 +3722,6 @@ DWORD MsgWaitHelper(int numWaiters, HANDLE* phEvent, BOOL bWaitAll, DWORD millis
// So on CoreCLR (where FEATURE_COMINTEROP is not currently defined) we can actually reach this point.
// We can't fix this, because it's a breaking change, so we just won't assert here.
// The result is that WaitAll on an STA thread in CoreCLR will behave stragely, as described above.
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORECLR)
- else
- _ASSERTE(!"WaitAll in an STA with more than one handle will deadlock");
-#endif
}
if (bWaitAll)
@@ -4390,7 +3872,6 @@ DWORD Thread::DoAppropriateWaitWorker(int countHandles, HANDLE *handles, BOOL wa
DWORD ret = 0;
BOOL alertable = (mode & WaitMode_Alertable) != 0;
-#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
// Waits from SynchronizationContext.WaitHelper are always just WaitMode_IgnoreSyncCtx.
// So if we defer to a sync ctx, we will lose any extra bits. We must therefore not
// defer to a sync ctx if doing any non-default wait.
@@ -4432,7 +3913,6 @@ DWORD Thread::DoAppropriateWaitWorker(int countHandles, HANDLE *handles, BOOL wa
if (fSyncCtxPresent)
return ret;
}
-#endif // #ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
// Before going to pre-emptive mode the thread needs to be flagged as waiting for
// the debugger. This used to be accomplished by the TS_Interruptible flag but that
@@ -4449,7 +3929,6 @@ DWORD Thread::DoAppropriateWaitWorker(int countHandles, HANDLE *handles, BOOL wa
DoAppropriateWaitWorkerAlertableHelper(mode);
}
- LeaveRuntimeHolder holder((size_t)WaitForMultipleObjectsEx);
StateHolder<MarkOSAlertableWait,UnMarkOSAlertableWait> OSAlertableWait(alertable);
ThreadStateHolder tsh(alertable, TS_Interruptible | TS_Interrupted);
@@ -4770,7 +4249,6 @@ DWORD Thread::DoSignalAndWaitWorker(HANDLE* pHandles, DWORD millis,BOOL alertabl
DoAppropriateWaitWorkerAlertableHelper(WaitMode_None);
}
- LeaveRuntimeHolder holder((size_t)WaitForMultipleObjectsEx);
StateHolder<MarkOSAlertableWait,UnMarkOSAlertableWait> OSAlertableWait(alertable);
ThreadStateHolder tsh(alertable, TS_Interruptible | TS_Interrupted);
@@ -4856,7 +4334,6 @@ WaitCompleted:
}
#endif // !FEATURE_PAL
-#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
DWORD Thread::DoSyncContextWait(OBJECTREF *pSyncCtxObj, int countHandles, HANDLE *handles, BOOL waitAll, DWORD millis)
{
CONTRACTL
@@ -4886,7 +4363,6 @@ DWORD Thread::DoSyncContextWait(OBJECTREF *pSyncCtxObj, int countHandles, HANDLE
return invokeWaitMethodHelper.Call_RetI4(args);
}
-#endif // #ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
// Called out of SyncBlock::Wait() to block this thread until the Notify occurs.
BOOL Thread::Block(INT32 timeOut, PendingSync *syncState)
@@ -5115,7 +4591,7 @@ void PendingSync::Restore(BOOL bRemoveFromSB)
// This is the callback from the OS, when we queue an APC to interrupt a waiting thread.
// The callback occurs on the thread we wish to interrupt. It is a STATIC method.
-void __stdcall Thread::UserInterruptAPC(ULONG_PTR data)
+void WINAPI Thread::UserInterruptAPC(ULONG_PTR data)
{
CONTRACTL {
NOTHROW;
@@ -5338,10 +4814,6 @@ void Thread::SetExposedObject(OBJECTREF exposed)
StoreObjectInHandle(m_ExposedObject, exposed);
// This makes sure the contexts on the backing thread
// and the managed thread start off in sync with each other.
-#ifdef FEATURE_REMOTING
- _ASSERTE(m_Context);
- ((THREADBASEREF)exposed)->SetExposedContext(m_Context->GetExposedObjectRaw());
-#endif
// BEWARE: the IncExternalCount call below may cause GC to happen.
// IncExternalCount will store exposed in m_StrongHndToExposedObject which is in default domain.
@@ -5602,9 +5074,12 @@ void Thread::SafeUpdateLastThrownObject(void)
{
EX_TRY
{
- // Using CreateDuplicateHandle here ensures that the AD of the last thrown object matches the domain of
- // the current throwable.
- SetLastThrownObjectHandle(CreateDuplicateHandle(hThrowable));
+ IGCHandleTable *pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
+
+ // Creating a duplicate handle here ensures that the AD of the last thrown object
+ // matches the domain of the current throwable.
+ OBJECTHANDLE duplicateHandle = pHandleTable->CreateDuplicateHandle(hThrowable);
+ SetLastThrownObjectHandle(duplicateHandle);
}
EX_CATCH
{
@@ -6228,6 +5703,8 @@ ThreadStore::ThreadStore()
m_BackgroundThreadCount(0),
m_PendingThreadCount(0),
m_DeadThreadCount(0),
+ m_DeadThreadCountForGCTrigger(0),
+ m_TriggerGCForDeadThreads(false),
m_GuidCreated(FALSE),
m_HoldingThread(0)
{
@@ -6267,6 +5744,16 @@ void ThreadStore::InitThreadStore()
s_pWaitForStackCrawlEvent = new CLREvent();
s_pWaitForStackCrawlEvent->CreateManualEvent(FALSE);
+
+ s_DeadThreadCountThresholdForGCTrigger =
+ static_cast<LONG>(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_Thread_DeadThreadCountThresholdForGCTrigger));
+ if (s_DeadThreadCountThresholdForGCTrigger < 0)
+ {
+ s_DeadThreadCountThresholdForGCTrigger = 0;
+ }
+ s_DeadThreadGCTriggerPeriodMilliseconds =
+ CLRConfig::GetConfigValue(CLRConfig::INTERNAL_Thread_DeadThreadGCTriggerPeriodMilliseconds);
+ s_DeadThreadGenerationCounts = nullptr;
}
// Enter and leave the critical section around the thread store. Clients should
@@ -6353,13 +5840,6 @@ void ThreadStore::AddThread(Thread *newThread, BOOL bRequiresTSL)
BOOL ThreadStore::CanAcquireLock()
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (!s_pThreadStore->m_Crst.IsOSCritSec())
- {
- return true;
- }
- else
-#endif
{
return (s_pThreadStore->m_Crst.m_criticalsection.LockCount == -1 || (size_t)s_pThreadStore->m_Crst.m_criticalsection.OwningThread == (size_t)GetCurrentThreadId());
}
@@ -6416,7 +5896,10 @@ BOOL ThreadStore::RemoveThread(Thread *target)
s_pThreadStore->m_ThreadCount--;
if (target->IsDead())
+ {
s_pThreadStore->m_DeadThreadCount--;
+ s_pThreadStore->DecrementDeadThreadCountForGCTrigger();
+ }
// Unstarted threads are not in the Background count:
if (target->IsUnstarted())
@@ -6505,6 +5988,200 @@ void ThreadStore::TransferStartedThread(Thread *thread, BOOL bRequiresTSL)
CheckForEEShutdown();
}
+LONG ThreadStore::s_DeadThreadCountThresholdForGCTrigger = 0;
+DWORD ThreadStore::s_DeadThreadGCTriggerPeriodMilliseconds = 0;
+SIZE_T *ThreadStore::s_DeadThreadGenerationCounts = nullptr;
+
+void ThreadStore::IncrementDeadThreadCountForGCTrigger()
+{
+ CONTRACTL {
+ NOTHROW;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ // Although all increments and decrements are usually done inside a lock, that is not sufficient to synchronize with a
+ // background GC thread resetting this value, hence the interlocked operation. Ignore overflow; overflow would likely never
+ // occur, the count is treated as unsigned, and nothing bad would happen if it were to overflow.
+ SIZE_T count = static_cast<SIZE_T>(FastInterlockIncrement(&m_DeadThreadCountForGCTrigger));
+
+ SIZE_T countThreshold = static_cast<SIZE_T>(s_DeadThreadCountThresholdForGCTrigger);
+ if (count < countThreshold || countThreshold == 0)
+ {
+ return;
+ }
+
+ IGCHeap *gcHeap = GCHeapUtilities::GetGCHeap();
+ if (gcHeap == nullptr)
+ {
+ return;
+ }
+
+ SIZE_T gcLastMilliseconds = gcHeap->GetLastGCStartTime(gcHeap->GetMaxGeneration());
+ SIZE_T gcNowMilliseconds = gcHeap->GetNow();
+ if (gcNowMilliseconds - gcLastMilliseconds < s_DeadThreadGCTriggerPeriodMilliseconds)
+ {
+ return;
+ }
+
+ if (!g_fEEStarted) // required for FinalizerThread::EnableFinalization() below
+ {
+ return;
+ }
+
+ // The GC is triggered on the finalizer thread since it's not safe to trigger it on DLL_THREAD_DETACH.
+ // TriggerGCForDeadThreadsIfNecessary() will determine which generation of GC to trigger, and may not actually trigger a GC.
+ // If a GC is triggered, since there would be a delay before the dead thread count is updated, clear the count and wait for
+ // it to reach the threshold again. If a GC would not be triggered, the count is still cleared here to prevent waking up the
+ // finalizer thread to do the work in TriggerGCForDeadThreadsIfNecessary() for every dead thread.
+ m_DeadThreadCountForGCTrigger = 0;
+ m_TriggerGCForDeadThreads = true;
+ FinalizerThread::EnableFinalization();
+}
+
+void ThreadStore::DecrementDeadThreadCountForGCTrigger()
+{
+ CONTRACTL {
+ NOTHROW;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ // Although all increments and decrements are usually done inside a lock, that is not sufficient to synchronize with a
+ // background GC thread resetting this value, hence the interlocked operation.
+ if (FastInterlockDecrement(&m_DeadThreadCountForGCTrigger) < 0)
+ {
+ m_DeadThreadCountForGCTrigger = 0;
+ }
+}
+
+void ThreadStore::OnMaxGenerationGCStarted()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ // A dead thread may contribute to triggering a GC at most once. After a max-generation GC occurs, if some dead thread
+ // objects are still reachable due to references to the thread objects, they will not contribute to triggering a GC again.
+ // Synchronize the store with increment/decrement operations occurring on different threads, and make the change visible to
+ // other threads in order to prevent unnecessary GC triggers.
+ FastInterlockExchange(&m_DeadThreadCountForGCTrigger, 0);
+}
+
+bool ThreadStore::ShouldTriggerGCForDeadThreads()
+{
+ LIMITED_METHOD_CONTRACT;
+
+ return m_TriggerGCForDeadThreads;
+}
+
+void ThreadStore::TriggerGCForDeadThreadsIfNecessary()
+{
+ CONTRACTL {
+ THROWS;
+ GC_TRIGGERS;
+ }
+ CONTRACTL_END;
+
+ if (!m_TriggerGCForDeadThreads)
+ {
+ return;
+ }
+ m_TriggerGCForDeadThreads = false;
+
+ if (g_fEEShutDown)
+ {
+ // Not safe to touch CLR state
+ return;
+ }
+
+ unsigned gcGenerationToTrigger = 0;
+ IGCHeap *gcHeap = GCHeapUtilities::GetGCHeap();
+ _ASSERTE(gcHeap != nullptr);
+ SIZE_T generationCountThreshold = static_cast<SIZE_T>(s_DeadThreadCountThresholdForGCTrigger) / 2;
+ unsigned maxGeneration = gcHeap->GetMaxGeneration();
+ if (!s_DeadThreadGenerationCounts)
+ {
+ // initialize this field on first use with an entry for every table.
+ s_DeadThreadGenerationCounts = new (nothrow) SIZE_T[maxGeneration + 1];
+ if (!s_DeadThreadGenerationCounts)
+ {
+ return;
+ }
+ }
+
+ memset(s_DeadThreadGenerationCounts, 0, sizeof(SIZE_T) * (maxGeneration + 1));
+ {
+ ThreadStoreLockHolder threadStoreLockHolder;
+ GCX_COOP();
+
+ // Determine the generation for which to trigger a GC. Iterate over all dead threads that have not yet been considered
+ // for triggering a GC and see how many are in which generations.
+ for (Thread *thread = ThreadStore::GetAllThreadList(NULL, Thread::TS_Dead, Thread::TS_Dead);
+ thread != nullptr;
+ thread = ThreadStore::GetAllThreadList(thread, Thread::TS_Dead, Thread::TS_Dead))
+ {
+ if (thread->HasDeadThreadBeenConsideredForGCTrigger())
+ {
+ continue;
+ }
+
+ Object *exposedObject = OBJECTREFToObject(thread->GetExposedObjectRaw());
+ if (exposedObject == nullptr)
+ {
+ continue;
+ }
+
+ unsigned exposedObjectGeneration = gcHeap->WhichGeneration(exposedObject);
+ SIZE_T newDeadThreadGenerationCount = ++s_DeadThreadGenerationCounts[exposedObjectGeneration];
+ if (exposedObjectGeneration > gcGenerationToTrigger && newDeadThreadGenerationCount >= generationCountThreshold)
+ {
+ gcGenerationToTrigger = exposedObjectGeneration;
+ if (gcGenerationToTrigger >= maxGeneration)
+ {
+ break;
+ }
+ }
+ }
+
+ // Make sure that enough time has elapsed since the last GC of the desired generation. We don't want to trigger GCs
+ // based on this heuristic too often. Give it some time to let the memory pressure trigger GCs automatically, and only
+ // if it doesn't in the given time, this heuristic may kick in to trigger a GC.
+ SIZE_T gcLastMilliseconds = gcHeap->GetLastGCStartTime(gcGenerationToTrigger);
+ SIZE_T gcNowMilliseconds = gcHeap->GetNow();
+ if (gcNowMilliseconds - gcLastMilliseconds < s_DeadThreadGCTriggerPeriodMilliseconds)
+ {
+ return;
+ }
+
+ // For threads whose exposed objects are in the generation of GC that will be triggered or in a lower GC generation,
+ // mark them as having contributed to a GC trigger to prevent redundant GC triggers
+ for (Thread *thread = ThreadStore::GetAllThreadList(NULL, Thread::TS_Dead, Thread::TS_Dead);
+ thread != nullptr;
+ thread = ThreadStore::GetAllThreadList(thread, Thread::TS_Dead, Thread::TS_Dead))
+ {
+ if (thread->HasDeadThreadBeenConsideredForGCTrigger())
+ {
+ continue;
+ }
+
+ Object *exposedObject = OBJECTREFToObject(thread->GetExposedObjectRaw());
+ if (exposedObject == nullptr)
+ {
+ continue;
+ }
+
+ if (gcGenerationToTrigger < maxGeneration &&
+ gcHeap->WhichGeneration(exposedObject) > gcGenerationToTrigger)
+ {
+ continue;
+ }
+
+ thread->SetHasDeadThreadBeenConsideredForGCTrigger();
+ }
+ } // ThreadStoreLockHolder, GCX_COOP()
+
+ GCHeapUtilities::GetGCHeap()->GarbageCollect(gcGenerationToTrigger, FALSE, collection_non_blocking);
+}
+
#endif // #ifndef DACCESS_COMPILE
@@ -6722,8 +6399,8 @@ Retry:
if (cur->m_State & Thread::TS_DebugSuspendPending)
cntReturn++;
- if (cur->m_State & Thread::TS_UserSuspendPending)
- cntReturn++;
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(cur->m_State & Thread::TS_UserSuspendPending));
if (cur->m_TraceCallCount > 0)
cntReturn++;
@@ -7430,26 +7107,6 @@ HRESULT Thread::CLRSetThreadStackGuarantee(SetThreadStackGuaranteeScope fScope)
LOG((LF_EH, LL_INFO10000, "STACKOVERFLOW: setting thread stack guarantee to 0x%x\n", uGuardSize));
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (CorHost2::GetHostTaskManager())
- {
- HRESULT hr;
- ULONG uCurrentGuarantee = 0;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
-
- // First, we'll see what the current guard size is.
- hr = CorHost2::GetHostTaskManager()->GetStackGuarantee(&uCurrentGuarantee);
-
- // Call SetStackGuarantee only if the guard isn't big enough for us.
- if (FAILED(hr) || uCurrentGuarantee < uGuardSize)
- hr = CorHost2::GetHostTaskManager()->SetStackGuarantee(uGuardSize);
-
- END_SO_TOLERANT_CODE_CALLING_HOST;
-
- if (hr != E_NOTIMPL)
- return hr;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
if (!::SetThreadStackGuarantee(&uGuardSize))
{
return HRESULT_FROM_GetLastErrorNA();
@@ -7707,81 +7364,6 @@ __declspec(noinline) void AllocateSomeStack(){
BOOL Thread::CommitThreadStack(Thread* pThreadOptional)
{
-#ifndef FEATURE_CORECLR
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- if (FAILED(CLRSetThreadStackGuarantee(STSGuarantee_Force)))
- return FALSE;
-
- if (g_pConfig->GetDisableCommitThreadStack() && (pThreadOptional == NULL || !pThreadOptional->HasThreadStateNC(TSNC_ForceStackCommit)))
- return TRUE;
-
-
- // This is a temporary fix for VSWhidbey 259155. In CommitThreadStack() we determine the bounds of the
- // region between the guard page and the hard guard region for a thread's stack and then commit that
- // region. Sometimes we cross a page boundary while calculating the bounds or doing the commit (in
- // VirtualQuery or VirtualAlloc), such that the guard page is moved after we've already gotten it's
- // location. When that happens we commit too many pages and destroy the guard page. To fix this we
- // do a small stack allocation that ensures that we have enough stack space for all of the
- // CommitThreadStack() work
-
- AllocateSomeStack();
-
- // Grab the info about the first region of the stack. First, we grab the region where we are now (&tmpMBI),
- // then we use the allocation base of that to grab the first region.
- MEMORY_BASIC_INFORMATION tmpMBI;
- SIZE_T dwRes;
-
- dwRes = ClrVirtualQuery((const void *)&tmpMBI, &tmpMBI, sizeof(MEMORY_BASIC_INFORMATION));
-
- if (sizeof(MEMORY_BASIC_INFORMATION) != dwRes)
- {
- return FALSE;
- }
-
- dwRes = ClrVirtualQuery((const void *)((BYTE*)tmpMBI.AllocationBase + HARD_GUARD_REGION_SIZE), &tmpMBI, sizeof(MEMORY_BASIC_INFORMATION));
-
- if (sizeof(MEMORY_BASIC_INFORMATION) != dwRes)
- {
- return FALSE;
- }
-
- // We commit the reserved part of the stack, if necessary, minus one page for the "hard" guard page.
- if (tmpMBI.State == MEM_RESERVE)
- {
- // Note: we leave the "hard" guard region uncommitted.
- void *base = (BYTE*)tmpMBI.AllocationBase + HARD_GUARD_REGION_SIZE;
-
- // We are committing a page on stack. If we call host for this operation,
- // host needs to avoid adding it to the memory consumption. Therefore
- // we call into OS directly.
-#undef VirtualAlloc
- void *p = VirtualAlloc(base,
- tmpMBI.RegionSize,
- MEM_COMMIT,
- PAGE_READWRITE);
-#define VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect) \
- Dont_Use_VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect)
-
- if (p != base )
- {
- DWORD err = GetLastError();
- STRESS_LOG2(LF_EH, LL_ALWAYS,
- "Thread::CommitThreadStack: failed to commit stack for TID 0x%x with error 0x%x\n",
- ::GetCurrentThreadId(), err);
-
- return FALSE;
- }
- }
-
- INDEBUG(DebugLogStackMBIs());
-
-#endif
return TRUE;
}
@@ -8475,40 +8057,6 @@ void MakeCallWithAppDomainTransition(
}
-#ifdef FEATURE_REMOTING
-void Thread::SetExposedContext(Context *c)
-{
-
- // Set the ExposedContext ...
-
- // Note that we use GetxxRaw() here to cover our bootstrap case
- // for AppDomain proxy creation
- // Leaving the exposed object NULL lets us create the default
- // managed context just before we marshal a new AppDomain in
- // RemotingServices::CreateProxyForDomain.
-
- Thread* pThread = GetThread();
- if (!pThread)
- return;
-
- CONTRACTL {
- NOTHROW;
- MODE_COOPERATIVE;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- if(m_ExposedObject != NULL) {
- THREADBASEREF threadObj = (THREADBASEREF) ObjectFromHandle(m_ExposedObject);
- if(threadObj != NULL)
- if (!c)
- threadObj->SetExposedContext(NULL);
- else
- threadObj->SetExposedContext(c->GetExposedObjectRaw());
-
- }
-}
-#endif
void Thread::InitContext()
{
@@ -8523,9 +8071,6 @@ void Thread::InitContext()
_ASSERTE(m_pDomain == NULL);
GCX_COOP_NO_THREAD_BROKEN();
m_Context = SystemDomain::System()->DefaultDomain()->GetDefaultContext();
-#ifdef FEATURE_REMOTING
- SetExposedContext(m_Context);
-#endif
m_pDomain = m_Context->GetDomain();
_ASSERTE(m_pDomain);
m_pDomain->ThreadEnter(this, NULL);
@@ -8552,9 +8097,6 @@ void Thread::ClearContext()
// must set exposed context to null first otherwise object verification
// checks will fail AV when m_Context is null
-#ifdef FEATURE_REMOTING
- SetExposedContext(NULL);
-#endif
m_pDomain = NULL;
#ifdef FEATURE_COMINTEROP
m_fDisableComObjectEagerCleanup = false;
@@ -8597,14 +8139,7 @@ void Thread::DoContextCallBack(ADID appDomain, Context *pContext, Context::ADCal
}
else
{
-#ifdef FEATURE_REMOTING
- _ASSERTE(pContext->GetDomain()==::GetAppDomain());
- Context::ADCallBackArgs callTgtArgs = {pTarget, args};
- Context::CallBackInfo callBackInfo = {Context::ADTransition_callback, (void*) &callTgtArgs};
- Context::RequestCallBack(appDomain,pContext, (void*) &callBackInfo);
-#else
UNREACHABLE();
-#endif
}
LOG((LF_APPDOMAIN, LL_INFO100, "Thread::DoADCallBack Done at esp %p\n", espVal));
}
@@ -8680,13 +8215,7 @@ void Thread::DoADCallBack(AppDomain* pDomain , Context::ADCallBackFcnType pTarge
}
else
{
-#ifdef FEATURE_REMOTING
- Context::ADCallBackArgs callTgtArgs = {pTarget, args};
- Context::CallBackInfo callBackInfo = {Context::ADTransition_callback, (void*) &callTgtArgs};
- Context::RequestCallBack(CURRENT_APPDOMAIN_ID, pCurrDomain->GetDefaultContext(), (void*) &callBackInfo);
-#else
UNREACHABLE();
-#endif
}
LOG((LF_APPDOMAIN, LL_INFO100, "Thread::DoADCallBack Done at esp %p\n", espVal));
}
@@ -8760,13 +8289,7 @@ void Thread::DoADCallBack(ADID appDomainID , Context::ADCallBackFcnType pTarget,
}
else
{
-#ifdef FEATURE_REMOTING
- Context::ADCallBackArgs callTgtArgs = {pTarget, args};
- Context::CallBackInfo callBackInfo = {Context::ADTransition_callback, (void*) &callTgtArgs};
- Context::RequestCallBack(CURRENT_APPDOMAIN_ID, pCurrDomain->GetDefaultContext(), (void*) &callBackInfo);
-#else
UNREACHABLE();
-#endif
}
LOG((LF_APPDOMAIN, LL_INFO100, "Thread::DoADCallBack Done at esp %p\n", espVal));
}
@@ -8802,10 +8325,6 @@ void Thread::EnterContextRestricted(Context *pContext, ContextTransitionFrame *p
{
pFrame->SetLockCount(m_dwBeginLockCount);
m_dwBeginLockCount = m_dwLockCount;
-#ifndef FEATURE_CORECLR
- pFrame->SetCriticalRegionCount(m_dwBeginCriticalRegionCount);
- m_dwBeginCriticalRegionCount = m_dwCriticalRegionCount;
-#endif // !FEATURE_CORECLR
}
if (m_Context == pContext) {
@@ -8849,22 +8368,6 @@ void Thread::EnterContextRestricted(Context *pContext, ContextTransitionFrame *p
PushDomain(pDomain->GetId());
STRESS_LOG1(LF_APPDOMAIN, LL_INFO100000, "Entering into ADID=%d\n", pDomain->GetId().m_dwId);
-#ifndef FEATURE_CORECLR
- //
- // Push execution contexts (that could contain call context) into frame to avoid leaks
- //
-
- if (IsExposedObjectSet())
- {
- THREADBASEREF ref = (THREADBASEREF) ObjectFromHandle(m_ExposedObject);
- _ASSERTE(ref != NULL);
- if (ref->GetExecutionContext() != NULL)
- {
- pFrame->SetReturnExecutionContext(ref->GetExecutionContext());
- ref->SetExecutionContext(NULL);
- }
- }
-#endif //!FEATURE_CORECLR
//
// Store the last thrown object in the ContextTransitionFrame before we null it out
@@ -8903,9 +8406,6 @@ void Thread::EnterContextRestricted(Context *pContext, ContextTransitionFrame *p
m_pDomain = pDomain;
SetAppDomain(m_pDomain);
}
-#ifdef FEATURE_REMOTING
- SetExposedContext(pContext);
-#endif
}
// main difference between EnterContext and ReturnToContext is that are allowed to return
@@ -8989,10 +8489,6 @@ void Thread::ReturnToContext(ContextTransitionFrame *pFrame)
m_dwLockCount = m_dwBeginLockCount;
m_dwBeginLockCount = pFrame->GetLockCount();
-#ifndef FEATURE_CORECLR
- m_dwCriticalRegionCount = m_dwBeginCriticalRegionCount;
- m_dwBeginCriticalRegionCount = pFrame->GetCriticalRegionCount();
-#endif // !FEATURE_CORECLR
}
@@ -9023,9 +8519,6 @@ void Thread::ReturnToContext(ContextTransitionFrame *pFrame)
CantStopHolder hCantStop;
m_Context = pReturnContext;
-#ifdef FEATURE_REMOTING
- SetExposedContext(pReturnContext);
-#endif
if (fChangedDomains)
{
@@ -9068,18 +8561,6 @@ void Thread::ReturnToContext(ContextTransitionFrame *pFrame)
if (fChangedDomains)
{
-#ifndef FEATURE_CORECLR
- //
- // Pop execution contexts (could contain call context) from frame if applicable
- //
-
- if (IsExposedObjectSet())
- {
- THREADBASEREF ref = (THREADBASEREF) ObjectFromHandle(m_ExposedObject);
- _ASSERTE(ref != NULL);
- ref->SetExecutionContext(pFrame->GetReturnExecutionContext());
- }
-#endif //!FEATURE_CORECLR
// Do this last so that thread is not labeled as out of the domain until all cleanup is done.
ADID adid=pCurrentDomain->GetId();
@@ -9175,356 +8656,6 @@ void Thread::ReturnToContextAndOOM(ContextTransitionFrame* pFrame)
COMPlusThrowOM();
}
-#ifdef FEATURE_REMOTING
-// for cases when marshaling is not needed
-// throws it is able to take a shortcut, otherwise just returns
-void Thread::RaiseCrossContextExceptionHelper(Exception* pEx, ContextTransitionFrame* pFrame)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
-#ifndef FEATURE_PAL
- // Ensure that IP for WatsonBucketing has been collected if the exception is preallocated.
-#ifdef _DEBUG
-
-#ifdef FEATURE_CORECLR
- // On CoreCLR, Watson may not be enabled. Thus, we should
- // skip this.
- if (IsWatsonEnabled())
-#endif // FEATURE_CORECLR
- {
- if (CLRException::IsPreallocatedExceptionObject(CLRException::GetThrowableFromException(pEx)))
- {
- // If a preallocated exception escapes unhandled till the AD Transition boundary, then
- // AppDomainTransitionExceptionFilter will capture the watson buckets and stick them
- // in the UE Watson bucket tracker.
- //
- // This is done *only* for exceptions escaping AD transition boundaries that are NOT
- // at the thread base.
- PTR_EHWatsonBucketTracker pUEWatsonBucketTracker = GetThread()->GetExceptionState()->GetUEWatsonBucketTracker();
- if(pUEWatsonBucketTracker->RetrieveWatsonBuckets() != NULL)
- {
- _ASSERTE(pUEWatsonBucketTracker->CapturedAtADTransition() || pUEWatsonBucketTracker->CapturedForThreadAbort());
- }
- }
- }
-#endif // _DEBUG
-#endif // !FEATURE_PAL
-
-#ifdef FEATURE_TESTHOOKS
- ADID adid=GetAppDomain()->GetId();
-#endif
-
-#define RETURNANDTHROWNEWEXCEPTION(pOldException, Type, ExArgs) \
- { \
- Exception::Delete(pOldException); \
- SetLastThrownObject(NULL); \
- ReturnToContext(pFrame); \
- CONTRACT_VIOLATION(ThrowsViolation); \
- TESTHOOKCALL(LeftAppDomain(adid.m_dwId)); \
- Type ex ExArgs; \
- COMPlusThrow(CLRException::GetThrowableFromException(&ex)); \
- }
-
-#define RETURNANDRETHROW(ex) \
- { \
- SafeSetLastThrownObject (NULL); \
- ReturnToContext(pFrame); \
- CONTRACT_VIOLATION(ThrowsViolation); \
- TESTHOOKCALL(LeftAppDomain(adid.m_dwId)); \
- PAL_CPP_THROW(Exception*,ex); \
- }
-
- CANNOTTHROWCOMPLUSEXCEPTION(); //no exceptions until returning to context
-
- Frame* pUnloadBoundary = GetUnloadBoundaryFrame();
-
- LOG((LF_EH, LL_INFO100, "Exception crossed into another context. Rethrowing in new context.\n"));
-
-
- // will throw a kAppDomainUnloadedException if necessary
- if (ShouldChangeAbortToUnload(pFrame, pUnloadBoundary))
- RETURNANDTHROWNEWEXCEPTION(pEx,EEResourceException,(kAppDomainUnloadedException, W("Remoting_AppDomainUnloaded_ThreadUnwound")));
-
- // Can't marshal return value from unloaded appdomain. Haven't
- // yet hit the boundary. Throw a generic exception instead.
- // ThreadAbort is more consistent with what goes on elsewhere --
- // the AppDomainUnloaded is only introduced at the top-most boundary.
- //
-
- if (GetDomain() == SystemDomain::AppDomainBeingUnloaded()
- && GetThread()!=SystemDomain::System()->GetUnloadingThread() &&
- GetThread()!=FinalizerThread::GetFinalizerThread())
- {
- if (pUnloadBoundary)
- RETURNANDTHROWNEWEXCEPTION(pEx,EEException,(kThreadAbortException))
- else
- RETURNANDTHROWNEWEXCEPTION(pEx,EEResourceException,(kAppDomainUnloadedException, W("Remoting_AppDomainUnloaded_ThreadUnwound")));
- }
-
- if (IsRudeAbort())
- RETURNANDTHROWNEWEXCEPTION(pEx,EEException,(kThreadAbortException));
-
-
- // There are a few classes that have the potential to create
- // infinite loops if we try to marshal them. For ThreadAbort,
- // ExecutionEngine, StackOverflow, and
- // OutOfMemory, throw a new exception of the same type.
- //
- // <TODO>@NICE: We lose the inner stack trace. A little better
- // would be to at least check if the inner exceptions are
- // all the same type as the outer. They could be
- // rethrown if this were true.</TODO>
- //
-
- if(pEx && !pEx->IsDomainBound())
- {
- RETURNANDRETHROW(pEx);
- }
-#undef RETURNANDTHROWNEWEXCEPTION
-#undef RETURNANDRETHROW
-}
-
-Thread::RaiseCrossContextResult
-Thread::TryRaiseCrossContextException(Exception **ppExOrig,
- Exception *pException,
- RuntimeExceptionKind *pKind,
- OBJECTREF *ppThrowable,
- ORBLOBREF *pOrBlob)
-{
- CONTRACTL
- {
- NOTHROW;
- WRAPPER(GC_TRIGGERS);
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- BOOL bIsClassInitException = FALSE;
- RaiseCrossContextResult result = RaiseCrossContextSuccess;
- int alreadyMarshaling = StartedMarshalingException();
-
- EX_TRY
- {
- bIsClassInitException = (pException->GetHR() == COR_E_TYPEINITIALIZATION);
-
- //just in case something throws
- //!!!should be released before any call to ReturnToContext !!!
- ExceptionHolder exception(*ppExOrig);
-
- if (IsExceptionOfType(kOutOfMemoryException, pException))
- *pKind = kOutOfMemoryException;
- else
- if (IsExceptionOfType(kThreadAbortException, pException))
- *pKind = kThreadAbortException;
- else
- if (IsExceptionOfType(kStackOverflowException, pException))
- *pKind = kStackOverflowException;
- else
- if (alreadyMarshaling)
- {
- // If we started marshaling already, something went wrong
- // This should only happen in case of busted ResourceManager
- _ASSERTE(!"Already marshalling the exception for cross AD transition - perhaps ResourceManager issue?");
-
- // ASK: Instead of throwing ExecutionEngineException from here, is there a better
- // ResourceManager related exception that can be thrown instead? If none, can
- // kContextMarshalException be thrown? Its obsolete but comes close to the usage
- // context.
- *pKind = kContextMarshalException;
- }
-
- // Serialize the exception
- if (*pKind == kLastException)
- {
- *ppThrowable = CLRException::GetThrowableFromException(exception);
- _ASSERTE(*ppThrowable != NULL);
-
- AppDomainHelper::MarshalObject(ppThrowable, pOrBlob);
- }
- }
- EX_CATCH
- {
- // We got a new Exception in original domain
- *ppExOrig = EXTRACT_EXCEPTION();
- // Got ClassInitException while marshaling ClassInitException. Class is unusable. Do not attempt anymore.
- if (bIsClassInitException && *ppExOrig && ((*ppExOrig)->GetHR() == COR_E_TYPEINITIALIZATION))
- result = RaiseCrossContextClassInit;
- else
- result = RaiseCrossContextRetry;
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- FinishedMarshalingException();
-
- return result;
-}
-
-// * pEx should be deleted before popping the frame, except for one case
-// * SafeSetLastThrownObject is called after pEx is deleted
-void DECLSPEC_NORETURN Thread::RaiseCrossContextException(Exception* pExOrig, ContextTransitionFrame* pFrame)
-{
- CONTRACTL
- {
- THROWS;
- WRAPPER(GC_TRIGGERS);
- }
- CONTRACTL_END;
-
- // <TODO>@TODO: Set the IsInUnmanagedHandler bits (aka IgnoreThreadAbort bits) appropriately.</TODO>
-
- GCX_COOP();
-
- // These are the only data transfered between the appdomains
- // Make sure that anything added here is appdomain agile
- RuntimeExceptionKind kind = kLastException;
- RaiseCrossContextResult result = RaiseCrossContextSuccess;
- ORBLOBREF orBlob = NULL;
-
- // Get the corruption severity for the exception caught at AppDomain transition boundary.
-#ifdef FEATURE_CORRUPTING_EXCEPTIONS
- CorruptionSeverity severity = GetThread()->GetExceptionState()->GetLastActiveExceptionCorruptionSeverity();
- if (severity == NotSet)
- {
- // No severity set at this point implies the exception was not corrupting
- severity = NotCorrupting;
- }
-#endif // FEATURE_CORRUPTING_EXCEPTIONS
-
-#ifdef FEATURE_TESTHOOKS
- ADID adid=GetAppDomain()->GetId();
-#endif
-
-#define MAX_RAISE_RETRY_COUNT 256
-
- DWORD dwRaiseRetryCount;
- for (dwRaiseRetryCount = 0; dwRaiseRetryCount < MAX_RAISE_RETRY_COUNT; dwRaiseRetryCount++)
- {
- // pEx is NULL means that the exception is CLRLastThrownObjectException
- CLRLastThrownObjectException lastThrown;
- Exception* pException = pExOrig?pExOrig:&lastThrown;
-
- // Set the current frame
- SetFrame(pFrame);
- RaiseCrossContextExceptionHelper(pExOrig, pFrame);
- _ASSERTE(pFrame->GetReturnContext());
-
- struct _gc {
- OBJECTREF pThrowable;
- ORBLOBREF orBlob;
- } gc;
- ZeroMemory(&gc, sizeof(_gc));
-
- GCPROTECT_BEGIN(gc);
- result = Thread::TryRaiseCrossContextException(&pExOrig, pException, &kind, &gc.pThrowable, &gc.orBlob);
- GCPROTECT_END();
-
- if (result != RaiseCrossContextRetry)
- {
- orBlob = gc.orBlob;
- break;
- }
-
- // We got a new exception and therefore need to retry marshaling it.
- GCX_COOP_NO_DTOR();
- }
-
- // Set the exception kind if we exceed MAX_RAISE_RETRY_COUNT, something is really wrong.
- if (dwRaiseRetryCount == MAX_RAISE_RETRY_COUNT)
- {
- LOG((LF_EH, LL_INFO100, "Unable to marshal the exception event after maximum retries (%d). Using ContextMarshalException instead.\n", MAX_RAISE_RETRY_COUNT));
- // This might be a good place to use ContextMarshalException type. However, it is marked obsolete.
- kind = kContextMarshalException;
- }
-
- // Return to caller domain
- {
- // ReturnToContext does not work inside GC_PROTECT and has GC_NOTRIGGER contract.
- // GCX_FORBID() ensures that the formerly protected values remain intact.
- GCX_FORBID();
- ReturnToContext(pFrame);
- }
-
- {
- struct _gc {
- OBJECTREF pMarshaledInit;
- OBJECTREF pMarshaledThrowable;
- ORBLOBREF orBlob;
- } gc;
- ZeroMemory(&gc, sizeof(_gc));
-
- gc.orBlob = orBlob;
-
- // Create the appropriate exception
- GCPROTECT_BEGIN(gc);
-#ifdef FEATURE_TESTHOOKS
- TESTHOOKCALL(LeftAppDomain(adid.m_dwId));
-#endif
- if (result == RaiseCrossContextClassInit)
- {
- HRESULT hr=S_OK;
- EX_TRY
- {
- WCHAR wszTemplate[30];
- IfFailThrow(UtilLoadStringRC(IDS_EE_NAME_UNKNOWN,
- wszTemplate,
- sizeof(wszTemplate)/sizeof(wszTemplate[0]),
- FALSE));
-
- CreateTypeInitializationExceptionObject(wszTemplate, NULL, &gc.pMarshaledInit, &gc.pMarshaledThrowable);
- }
- EX_CATCH
- {
- // Unable to create ClassInitException in caller domain
- hr=COR_E_TYPEINITIALIZATION;
- }
- EX_END_CATCH(RethrowTransientExceptions);
- IfFailThrow(hr);
- }
- else
- {
- switch (kind)
- {
- case kLastException:
-#ifdef FEATURE_CORECLR
- gc.pMarshaledThrowable = gc.orBlob;
-#else
- AppDomainHelper::UnmarshalObject(GetAppDomain(), &gc.orBlob, &gc.pMarshaledThrowable);
-#endif //FEATURE_CORECLR
-
- break;
- case kOutOfMemoryException:
- COMPlusThrowOM();
- break;
- case kStackOverflowException:
- gc.pMarshaledThrowable = CLRException::GetPreallocatedStackOverflowException();
- break;
- default:
- {
- EEException ex(kind);
- gc.pMarshaledThrowable = CLRException::GetThrowableFromException(&ex);
- }
- }
- }
-
- // ... and throw it.
- VALIDATEOBJECTREF(gc.pMarshaledThrowable);
- COMPlusThrow(gc.pMarshaledThrowable
-#ifdef FEATURE_CORRUPTING_EXCEPTIONS
- , severity
-#endif // FEATURE_CORRUPTING_EXCEPTIONS
- );
-
- GCPROTECT_END();
- }
-}
-
-#else // FEATURE_REMOTING
void DECLSPEC_NORETURN Thread::RaiseCrossContextException(Exception* pExOrig, ContextTransitionFrame* pFrame)
{
@@ -9541,7 +8672,6 @@ void DECLSPEC_NORETURN Thread::RaiseCrossContextException(Exception* pExOrig, Co
COMPlusThrow(CLRException::GetThrowableFromException(pException));
}
-#endif
struct FindADCallbackType {
AppDomain *pSearchDomain;
@@ -9739,9 +8869,9 @@ BOOL Thread::HaveExtraWorkForFinalizer()
|| ExecutionManager::IsCacheCleanupRequired()
|| Thread::CleanupNeededForFinalizedThread()
|| (m_DetachCount > 0)
- || CExecutionEngine::HasDetachedTlsInfo()
|| AppDomain::HasWorkForFinalizerThread()
- || SystemDomain::System()->RequireAppDomainCleanup();
+ || SystemDomain::System()->RequireAppDomainCleanup()
+ || ThreadStore::s_pThreadStore->ShouldTriggerGCForDeadThreads();
}
void Thread::DoExtraWorkForFinalizer()
@@ -9784,8 +8914,6 @@ void Thread::DoExtraWorkForFinalizer()
SystemDomain::System()->ProcessDelayedUnloadDomains();
}
- CExecutionEngine::CleanupDetachedTlsInfo();
-
if(m_DetachCount > 0 || Thread::CleanupNeededForFinalizedThread())
{
Thread::CleanupDetachedThreads();
@@ -9800,7 +8928,8 @@ void Thread::DoExtraWorkForFinalizer()
// If there were any TimerInfos waiting to be released, they'll get flushed now
ThreadpoolMgr::FlushQueueOfTimerInfos();
-
+
+ ThreadStore::s_pThreadStore->TriggerGCForDeadThreadsIfNecessary();
}
@@ -10225,7 +9354,6 @@ static LONG ThreadBaseRedirectingFilter(PEXCEPTION_POINTERS pExceptionInfo, LPVO
{
_ASSERTE(flags == MTCSF_NormalBase);
-#ifdef FEATURE_CORECLR
if(!IsSingleAppDomain())
{
// This assert shouldnt be hit in CoreCLR since:
@@ -10239,11 +9367,9 @@ static LONG ThreadBaseRedirectingFilter(PEXCEPTION_POINTERS pExceptionInfo, LPVO
// So, if this is hit, something is not right!
_ASSERTE(!"How come a managed thread in CoreCLR has suffered unhandled exception in DefaultDomain?");
}
-#endif // FEATURE_CORECLR
LOG((LF_EH, LL_INFO100, "ThreadBaseRedirectingFilter: setting TSNC_ProcessedUnhandledException\n"));
-#if defined(FEATURE_CORECLR)
//
// In the default domain, when an exception goes unhandled on a managed thread whose threadbase is in the VM (e.g. explicitly spawned threads,
// ThreadPool threads, finalizer thread, etc), CLR can end up in the unhandled exception processing path twice.
@@ -10271,7 +9397,6 @@ static LONG ThreadBaseRedirectingFilter(PEXCEPTION_POINTERS pExceptionInfo, LPVO
// will fail to honor the host policy (e.g. swallow unhandled exception). Thus, the 2nd unhandled exception may end up crashing the app when it should not.
//
if (IsSingleAppDomain() && (ret != EXCEPTION_EXECUTE_HANDLER))
-#endif // defined(FEATURE_CORECLR)
{
// Since we have already done unhandled exception processing for it, we dont want it
// to happen again if our UEF gets invoked upon returning back to the OS.
@@ -10281,14 +9406,6 @@ static LONG ThreadBaseRedirectingFilter(PEXCEPTION_POINTERS pExceptionInfo, LPVO
}
}
-#ifdef FEATURE_UEF_CHAINMANAGER
- if (g_pUEFManager && (ret == EXCEPTION_CONTINUE_SEARCH))
- {
- // Since the "UEF" of this runtime instance didnt handle the exception,
- // invoke the other registered UEF callbacks as well
- ret = g_pUEFManager->InvokeUEFCallbacks(pExceptionInfo);
- }
-#endif // FEATURE_UEF_CHAINMANAGER
END_SO_INTOLERANT_CODE;
return ret;
@@ -10321,9 +9438,7 @@ static void ManagedThreadBase_DispatchOuter(ManagedThreadCallState *pCallState)
TryParam *pTryParam;
Thread *pThread;
-#ifdef FEATURE_CORECLR
BOOL *pfHadException;
-#endif // FEATURE_CORECLR
#ifdef WIN64EXCEPTIONS
Frame *pFrame;
@@ -10333,10 +9448,8 @@ static void ManagedThreadBase_DispatchOuter(ManagedThreadCallState *pCallState)
args.pTryParam = &param;
args.pThread = pThread;
-#ifdef FEATURE_CORECLR
BOOL fHadException = TRUE;
args.pfHadException = &fHadException;
-#endif // FEATURE_CORECLR
#ifdef WIN64EXCEPTIONS
args.pFrame = pFrame;
@@ -10368,13 +9481,10 @@ static void ManagedThreadBase_DispatchOuter(ManagedThreadCallState *pCallState)
}
PAL_ENDTRY;
-#ifdef FEATURE_CORECLR
*(pArgs->pfHadException) = FALSE;
-#endif // FEATURE_CORECLR
}
PAL_FINALLY
{
-#ifdef FEATURE_CORECLR
// If we had a breakpoint exception that has gone unhandled,
// then switch to the correct AD context. Its fine to do this
// here because:
@@ -10386,7 +9496,6 @@ static void ManagedThreadBase_DispatchOuter(ManagedThreadCallState *pCallState)
{
ReturnToPreviousAppDomain();
}
-#endif // FEATURE_CORECLR
catchFrame.Pop();
}
PAL_ENDTRY;
@@ -10723,38 +9832,7 @@ void Thread::DeleteThreadStaticData(AppDomain *pDomain)
}
}
-#ifdef FEATURE_LEAK_CULTURE_INFO
-void Thread::ResetCultureForDomain(ADID id)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- THREADBASEREF thread = (THREADBASEREF) GetExposedObjectRaw();
-
- if (thread == NULL)
- return;
- CULTUREINFOBASEREF userCulture = thread->GetCurrentUserCulture();
- if (userCulture != NULL)
- {
- if (!userCulture->IsSafeCrossDomain() && userCulture->GetCreatedDomainID() == id)
- thread->ResetCurrentUserCulture();
- }
-
- CULTUREINFOBASEREF UICulture = thread->GetCurrentUICulture();
- if (UICulture != NULL)
- {
- if (!UICulture->IsSafeCrossDomain() && UICulture->GetCreatedDomainID() == id)
- thread->ResetCurrentUICulture();
- }
-}
-#endif // FEATURE_LEAK_CULTURE_INFO
-
-#ifndef FEATURE_LEAK_CULTURE_INFO
void Thread::InitCultureAccessors()
{
CONTRACTL {
@@ -10778,7 +9856,6 @@ void Thread::InitCultureAccessors()
pCurrentCulture = (OBJECTREF*)pThread->GetStaticFieldAddress(managedThreadCurrentUICulture);
}
}
-#endif // FEATURE_LEAK_CULTURE_INFO
ARG_SLOT Thread::CallPropertyGet(BinderMethodID id, OBJECTREF pObject)
@@ -11159,30 +10236,6 @@ BOOL ThreadStore::HoldingThreadStore(Thread *pThread)
}
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-void Thread::SetupFiberData()
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- _ASSERTE (this == GetThread());
- _ASSERTE (m_pFiberData == NULL);
-
- m_pFiberData = ClrTeb::GetFiberDataPtr();
- if (m_pFiberData != NULL && (g_CORDebuggerControlFlags & DBCF_FIBERMODE) == 0)
- {
- // We are in fiber mode
- g_CORDebuggerControlFlags |= DBCF_FIBERMODE;
- if (g_pDebugInterface)
- {
- g_pDebugInterface->SetFiberMode(true);
- }
- }
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#ifdef _DEBUG
@@ -11311,19 +10364,6 @@ HRESULT Thread::SwitchIn(HANDLE threadHandle)
EnsureTlsData ensure(this);
-#ifdef _DEBUG
- if (CLRTaskHosted()) {
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTask *pTask = NULL;
- _ASSERTE (CorHost2::GetHostTaskManager()->GetCurrentTask(&pTask) == S_OK &&
- (pTask == GetHostTask() || GetHostTask() == NULL));
-
- if (pTask)
- pTask->Release();
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- }
-#endif
-
if (SetThread(this))
{
Thread *pThread = GetThread();
@@ -11345,40 +10385,6 @@ HRESULT Thread::SwitchIn(HANDLE threadHandle)
_ASSERTE (!PreemptiveGCDisabled());
#endif
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (CLRTaskHosted() && GetHostTask() == NULL)
- {
- // Reset has been called on this task.
-
- if (! SetStackLimits(fAll))
- {
- return E_FAIL;
- }
-
- // We commit the thread's entire stack when it enters the runtime to allow us to be reliable in low memory
- // situtations. See the comments in front of Thread::CommitThreadStack() for mor information.
- if (!Thread::CommitThreadStack(this))
- {
- return E_OUTOFMEMORY;
- }
-
- HRESULT hr = CorHost2::GetHostTaskManager()->GetCurrentTask(&m_pHostTask);
- _ASSERTE (hr == S_OK && m_pHostTask);
-
-#ifdef _DEBUG
- AddFiberInfo(ThreadTrackInfo_Lifetime);
-#endif
-
- m_pFiberData = ClrTeb::GetFiberDataPtr();
-
- m_OSThreadId = ::GetCurrentThreadId();
-
-#ifdef ENABLE_CONTRACTS
- m_pClrDebugState = ::GetClrDebugState();
-#endif
- ResetThreadState(TS_TaskReset);
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
// We have to be switched in on the same fiber
_ASSERTE (GetCachedStackBase() == GetStackUpperBound());
@@ -11550,25 +10556,6 @@ void Thread::InternalSwitchOut()
(CExecutionEngine::CheckThreadStateNoCreate(0) == NULL));
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-HRESULT Thread::GetMemStats (COR_GC_THREAD_STATS *pStats)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- // Get the allocation context which contains this counter in it.
- gc_alloc_context *p = &m_alloc_context;
- pStats->PerThreadAllocation = p->alloc_bytes + p->alloc_bytes_loh;
- if (GetHasPromotedBytes())
- pStats->Flags = COR_GC_THREAD_HAS_PROMOTED_BYTES;
-
- return S_OK;
-}
-#endif //FEATURE_INCLUDE_ALL_INTERFACES
LONG Thread::GetTotalThreadPoolCompletionCount()
@@ -11720,13 +10707,6 @@ void Thread::InternalReset(BOOL fFull, BOOL fNotFinalizerThread, BOOL fThreadObj
FullResetThread();
}
-#ifndef FEATURE_CORECLR
- _ASSERTE (m_dwCriticalRegionCount == 0);
- m_dwCriticalRegionCount = 0;
-
- _ASSERTE (m_dwThreadAffinityCount == 0);
- m_dwThreadAffinityCount = 0;
-#endif // !FEATURE_CORECLR
//m_MarshalAlloc.Collapse(NULL);
@@ -11773,14 +10753,6 @@ HRESULT Thread::Reset(BOOL fFull)
BEGIN_SO_INTOLERANT_CODE_NOPROBE;
#ifdef _DEBUG
- if (CLRTaskHosted()) {
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- // Reset is a heavy operation. We will call into SQL for lock and memory operations.
- // The host better keeps IHostTask alive.
- _ASSERTE (GetCurrentHostTask() == GetHostTask());
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
- }
-
_ASSERTE (GetThread() == this);
#ifdef _TARGET_X86_
_ASSERTE (GetExceptionState()->GetContextRecord() == NULL);
@@ -11834,15 +10806,6 @@ HRESULT Thread::Reset(BOOL fFull)
}
{
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- // We need to scope this assert because of
- // the jumps to ErrExit from above.
- GCX_ASSERT_PREEMP();
-
- _ASSERTE (m_pHostTask);
-
- ReleaseHostTask();
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#ifdef WIN64EXCEPTIONS
ExceptionTracker::PopTrackers((void*)-1);
@@ -11850,9 +10813,6 @@ HRESULT Thread::Reset(BOOL fFull)
ResetThreadStateNC(TSNC_UnbalancedLocks);
m_dwLockCount = 0;
-#ifndef FEATURE_CORECLR
- m_dwCriticalRegionCount = 0;
-#endif // !FEATURE_CORECLR
InternalSwitchOut();
m_OSThreadId = SWITCHED_OUT_FIBER_OSID;
@@ -11992,244 +10952,12 @@ HRESULT Thread::NeedsPriorityScheduling(BOOL *pbNeedsPriorityScheduling)
return S_OK;
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-HRESULT Thread::YieldTask()
-{
-#undef Sleep
- CONTRACTL {
- NOTHROW;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- //can't do heap allocation in this method
- CantAllocHolder caHolder;
- _ASSERTE(CLRTaskHosted());
-
- // The host must guarantee that we have enough stack before they call this API.
- // We unfortunately do not have a good mechanism to indicate/enforce this and it's too
- // late in Whidbey to add one now. We should definitely consider adding such a
- // mechanism in Orcas however. For now we will work around this by marking the
- // method as SO_TOLERANT and disabling SO tolerance violations for any code it calls.
- CONTRACT_VIOLATION(SOToleranceViolation);
-
- //
- // YieldTask should not be called from a managed thread, as it can lead to deadlocks.
- // However, some tests do this, and it would be hard to change that. Let's at least ensure
- // that they are not shooting themselves in the foot.
- //
- Thread* pCurThread = GetThread();
- if (this == pCurThread)
- {
- // We will suspend the target thread. If YieldTask is called on the current thread,
- // we will suspend the current thread forever.
- return HOST_E_INVALIDOPERATION;
- }
-
- FAULT_FORBID();
-
- // This function has been called by the host, and the host needs not
- // be reentrant. Therefore, no code running below this function can
- // cause calls back into the host.
- ForbidCallsIntoHostOnThisThreadHolder forbidCallsIntoHostOnThisThread(TRUE /*dummy*/);
- while (!forbidCallsIntoHostOnThisThread.Acquired())
- {
- // We can not call __SwitchToThread since we can not go back to host.
- ::Sleep(10);
- forbidCallsIntoHostOnThisThread.Acquire();
- }
-
- // So that the thread can yield when it tries to switch to coop gc.
- CounterHolder trtHolder(&g_TrapReturningThreads);
-
- // One worker on a thread only.
- while (TRUE)
- {
- LONG curValue = m_State;
- if ((curValue & TS_YieldRequested) != 0)
- {
- // The host has previously called YieldTask for this thread,
- // and the thread has not cleared the flag yet.
- return S_FALSE;
- }
- else if ((curValue & TS_Unstarted) != 0)
- {
- // The task is still unstarted, so we can consider the host
- // to be in control of this thread, which means we have
- // succeeded in getting the host in control.
- return S_OK;
- }
-
- CONSISTENCY_CHECK(sizeof(m_State) == sizeof(LONG));
- if (FastInterlockCompareExchange((LONG*)&m_State, curValue | TS_YieldRequested, curValue) == curValue)
- {
- break;
- }
- }
-
-#ifdef PROFILING_SUPPORTED
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackSuspends());
- g_profControlBlock.pProfInterface->RuntimeThreadSuspended((ThreadID)this);
- END_PIN_PROFILER();
- }
-#endif // PROFILING_SUPPORTED
-
- while (m_State & TS_YieldRequested)
- {
- BOOL fDone = FALSE;
-
- if (m_State & (TS_Dead | TS_Detached))
- {
- // The thread is dead, in other words, yielded forever.
- // Don't bother clearing TS_YieldRequested, as nobody
- // is going to look at it any more.
- break;
- }
-
- CounterHolder handleHolder(&m_dwThreadHandleBeingUsed);
- HANDLE hThread = GetThreadHandle();
- if (hThread == INVALID_HANDLE_VALUE)
- {
- // The thread is dead, in other words, yielded forever.
- // Don't bother clearing TS_YieldRequested, as nobody
- // is going to look at it any more.
- break;
- }
- else if (hThread == SWITCHOUT_HANDLE_VALUE)
- {
- // The thread is currently switched out.
- // This means that the host has control of the thread,
- // so we can stop our attempts to yield it. Note that
- // TS_YieldRequested is cleared in InternalSwitchOut. (If we
- // were to clear it here, we could race against another
- // thread that is running YieldTask.)
- break;
- }
-
- DWORD dwSuspendCount = ::SuspendThread(hThread);
- if ((int)dwSuspendCount >= 0)
- {
- if (!EnsureThreadIsSuspended(hThread, this))
- {
- goto Retry;
- }
-
- if (hThread == GetThreadHandle())
- {
- if (m_dwForbidSuspendThread != 0)
- {
- goto Retry;
- }
- }
- else
- {
- // A thread was switch out but in again.
- // We suspended the wrong thread; resume it and give
- // up our attempts to yield. Note that TS_YieldRequested
- // is cleared in InternalSwitchOut.
- ::ResumeThread(hThread);
- break;
- }
- }
- else
- {
- // We can get here either SuspendThread fails
- // Or the fiber thread dies after this fiber switched out.
-
- if ((int)dwSuspendCount != -1)
- {
- STRESS_LOG1(LF_SYNC, LL_INFO1000, "In Thread::YieldTask ::SuspendThread returned %x \n", dwSuspendCount);
- }
- if (GetThreadHandle() == SWITCHOUT_HANDLE_VALUE)
- {
- // The thread was switched out while we tried to suspend it.
- // This means that the host has control of the thread,
- // so we can stop our attempts to yield it. Note that
- // TS_YieldRequested is cleared in InternalSwitchOut. (If we
- // were to clear it here, we could race against another
- // thread that is running YieldTask.)
- break;
- }
- else {
- continue;
- }
- }
-
- if (!m_fPreemptiveGCDisabled)
- {
- ::ResumeThread(hThread);
- break;
- }
-
-#ifdef FEATURE_HIJACK
-
-#ifdef _DEBUG
- if (pCurThread != NULL)
- {
- pCurThread->dbg_m_cSuspendedThreads ++;
- _ASSERTE(pCurThread->dbg_m_cSuspendedThreads > 0);
- }
-#endif
-
- // Only check for HandledJITCase if we actually suspended the thread.
- if ((int)dwSuspendCount >= 0)
- {
- WorkingOnThreadContextHolder workingOnThreadContext(this);
- if (workingOnThreadContext.Acquired() && HandledJITCase())
- {
- // Redirect thread so we can capture a good thread context
- // (GetThreadContext is not sufficient, due to an OS bug).
- // If we don't succeed (should only happen on Win9X, due to
- // a different OS bug), we must resume the thread and try
- // again.
- fDone = CheckForAndDoRedirectForYieldTask();
- }
- }
-
-#ifdef _DEBUG
- if (pCurThread != NULL)
- {
- _ASSERTE(pCurThread->dbg_m_cSuspendedThreads > 0);
- pCurThread->dbg_m_cSuspendedThreads --;
- _ASSERTE(pCurThread->dbg_m_cSuspendedThreadsWithoutOSLock <= pCurThread->dbg_m_cSuspendedThreads);
- }
-#endif //_DEBUG
-
-#endif // FEATURE_HIJACK
-
-Retry:
- ::ResumeThread(hThread);
- if (fDone)
- {
- // We managed to redirect the thread, so we know that it will yield.
- // We can let the actual yielding happen asynchronously.
- break;
- }
- handleHolder.Release();
- ::Sleep(1);
- }
-#ifdef PROFILING_SUPPORTED
- {
- BEGIN_PIN_PROFILER(CORProfilerTrackSuspends());
- g_profControlBlock.pProfInterface->RuntimeThreadResumed((ThreadID)this);
- END_PIN_PROFILER();
- }
-#endif
- return S_OK;
-#define Sleep(a) Dont_Use_Sleep(a)
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
HRESULT Thread::LocksHeld(SIZE_T *pLockCount)
{
LIMITED_METHOD_CONTRACT;
*pLockCount = m_dwLockCount;
-#ifndef FEATURE_CORECLR
- *pLockCount += m_dwCriticalRegionCount;
-#endif // !FEATURE_CORECLR
return S_OK;
}
@@ -12280,57 +11008,6 @@ HRESULT Thread::EndPreventAsyncAbort()
return S_OK;
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-// We release m_pHostTask during ICLRTask::Reset and ICLRTask::ExitTask call.
-// This function allows us to synchronize obtaining m_pHostTask with Thread reset or exit.
-IHostTask* Thread::GetHostTaskWithAddRef()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- CounterIncrease(&m_dwHostTaskRefCount);
- IHostTask *pHostTask = m_pHostTask;
- if (pHostTask != NULL)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pHostTask->AddRef();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
- CounterDecrease(&m_dwHostTaskRefCount);
- return pHostTask;
-}
-
-void Thread::ReleaseHostTask()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- if (m_pHostTask == NULL)
- {
- return;
- }
-
- IHostTask *pHostTask = m_pHostTask;
- m_pHostTask = NULL;
-
- YIELD_WHILE (m_dwHostTaskRefCount > 0);
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pHostTask->Release();
- END_SO_TOLERANT_CODE_CALLING_HOST;
-
- STRESS_LOG1 (LF_SYNC, LL_INFO100, "Release HostTask %p", pHostTask);
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
ULONG Thread::AddRef()
{
@@ -12365,537 +11042,8 @@ HRESULT Thread::QueryInterface(REFIID riid, void **ppUnk)
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (IID_ICLRTask2 == riid)
- *ppUnk = (ICLRTask2 *)this;
- else if (IID_ICLRTask == riid)
- *ppUnk = (ICLRTask *)this;
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
return E_NOINTERFACE;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- AddRef();
- return S_OK;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-}
-
-BOOL IsHostedThread()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- if (!CLRTaskHosted())
- {
- return FALSE;
- }
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- Thread *pThread = GetThread();
- if (pThread && pThread->GetHostTask() != NULL)
- {
- return TRUE;
- }
-
- IHostTaskManager *pManager = CorHost2::GetHostTaskManager();
- IHostTask *pHostTask = NULL;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pManager->GetCurrentTask(&pHostTask);
- END_SO_TOLERANT_CODE_CALLING_HOST;
-
- BOOL fRet = (pHostTask != NULL);
- if (pHostTask)
- {
- if (pThread)
- {
- _ASSERTE (pThread->GetHostTask() == NULL);
- pThread->m_pHostTask = pHostTask;
- }
- else
- {
- pHostTask->Release();
- }
- }
-
- return fRet;
-#else // !FEATURE_INCLUDE_ALL_INTERFACES
- return FALSE;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-}
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-IHostTask *GetCurrentHostTask()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- IHostTaskManager *provider = CorHost2::GetHostTaskManager();
-
- IHostTask *pHostTask = NULL;
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- provider->GetCurrentTask(&pHostTask);
- END_SO_TOLERANT_CODE_CALLING_HOST;
-
- if (pHostTask)
- {
- pHostTask->Release();
- }
-
- return pHostTask;
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
-void __stdcall Thread::LeaveRuntime(size_t target)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = LeaveRuntimeNoThrow(target);
- if (FAILED(hr))
- ThrowHR(hr);
-}
-
-HRESULT Thread::LeaveRuntimeNoThrow(size_t target)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- if (!CLRTaskHosted())
- {
- return S_OK;
- }
-
- if (!IsHostedThread())
- {
- return S_OK;
- }
-
- HRESULT hr = S_OK;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- // A SQL thread can enter the runtime w/o a managed thread.
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(hr = COR_E_STACKOVERFLOW);
-
- IHostTaskManager *pManager = CorHost2::GetHostTaskManager();
- if (pManager)
- {
-#ifdef _DEBUG
- Thread *pThread = GetThread();
- if (pThread)
- {
- pThread->AddFiberInfo(Thread::ThreadTrackInfo_UM_M);
- }
-#endif
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->LeaveRuntime(target);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
- END_SO_INTOLERANT_CODE;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- return hr;
-}
-
-void __stdcall Thread::LeaveRuntimeThrowComplus(size_t target)
-{
-
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *pManager = NULL;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- if (!CLRTaskHosted())
- {
- goto Exit;
- }
-
- if (!IsHostedThread())
- {
- goto Exit;
- }
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- pManager = CorHost2::GetHostTaskManager();
- if (pManager)
- {
-#ifdef _DEBUG
- Thread *pThread = GetThread();
- if (pThread)
- {
- pThread->AddFiberInfo(Thread::ThreadTrackInfo_UM_M);
- }
-#endif
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->LeaveRuntime(target);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- if (FAILED(hr))
- {
- INSTALL_UNWIND_AND_CONTINUE_HANDLER;
- ThrowHR(hr);
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
- }
-
-
-Exit:
-;
-
-}
-
-void __stdcall Thread::EnterRuntime()
-{
- if (!CLRTaskHosted())
- {
- // optimize for the most common case
- return;
- }
-
- DWORD dwLastError = GetLastError();
-
- CONTRACTL {
- THROWS;
- ENTRY_POINT;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- //BEGIN_ENTRYPOINT_THROWS;
-
- HRESULT hr = EnterRuntimeNoThrowWorker();
- if (FAILED(hr))
- ThrowHR(hr);
-
- SetLastError(dwLastError);
- //END_ENTRYPOINT_THROWS;
-
-}
-
-HRESULT Thread::EnterRuntimeNoThrow()
-{
- if (!CLRTaskHosted())
- {
- // optimize for the most common case
- return S_OK;
- }
-
- DWORD dwLastError = GetLastError();
-
- // This function can be called during a hard SO when managed code has called out to native
- // which has SOd, so we can't probe here. We already probe in LeaveRuntime, which will be
- // called at roughly the same stack level as LeaveRuntime, so we assume that the probe for
- // LeaveRuntime will cover us here.
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- HRESULT hr = EnterRuntimeNoThrowWorker();
-
- SetLastError(dwLastError);
-
- return hr;
-}
-
-HRESULT Thread::EnterRuntimeNoThrowWorker()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- if (!IsHostedThread())
- {
- return S_OK;
- }
-
- HRESULT hr = S_OK;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *pManager = CorHost2::GetHostTaskManager();
-
- if (pManager)
- {
-#ifdef _DEBUG
- // A SQL thread can enter the runtime w/o a managed thread.
- Thread *pThread = GetThread();
- if (pThread)
- {
- pThread->AddFiberInfo(Thread::ThreadTrackInfo_UM_M);
- }
-#endif
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->EnterRuntime();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- return hr;
-}
-
-void Thread::ReverseEnterRuntime()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- SO_TOLERANT;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- HRESULT hr = ReverseEnterRuntimeNoThrow();
-
- if (hr != S_OK)
- ThrowHR(hr);
-}
-
-__declspec(noinline) void Thread::ReverseEnterRuntimeThrowComplusHelper(HRESULT hr)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- SO_TOLERANT;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- INSTALL_UNWIND_AND_CONTINUE_HANDLER;
- ThrowHR(hr);
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
-}
-
-void Thread::ReverseEnterRuntimeThrowComplus()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- SO_TOLERANT;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- HRESULT hr = ReverseEnterRuntimeNoThrow();
-
- if (hr != S_OK)
- {
- ReverseEnterRuntimeThrowComplusHelper(hr);
- }
-}
-
-
-HRESULT Thread::ReverseEnterRuntimeNoThrow()
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- if (!CLRTaskHosted())
- {
- return S_OK;
- }
-
- if (!IsHostedThread())
- {
- return S_OK;
- }
-
- HRESULT hr = S_OK;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *pManager = CorHost2::GetHostTaskManager();
- if (pManager)
- {
-#ifdef _DEBUG
- // A SQL thread can enter the runtime w/o a managed thread.
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(hr = COR_E_STACKOVERFLOW);
-
- Thread *pThread = GetThread();
- if (pThread)
- {
- pThread->AddFiberInfo(Thread::ThreadTrackInfo_UM_M);
- }
- END_SO_INTOLERANT_CODE;
-
-#endif
- hr = pManager->ReverseEnterRuntime();
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- return hr;
-}
-
-void Thread::ReverseLeaveRuntime()
-{
- // This function can be called during a hard SO so we can't probe here. We already probe in
- // ReverseEnterRuntime, which will be called at roughly the same stack level as ReverseLeaveRuntime,
- // so we assume that the probe for ReverseEnterRuntime will cover us here.
-
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- // SetupForComCallHR calls this inside a CATCH, but it triggers a THROWs violation
- CONTRACT_VIOLATION(ThrowsViolation);
-
- if (!CLRTaskHosted())
- {
- return;
- }
-
- if (!IsHostedThread())
- {
- return;
- }
-
- HRESULT hr = S_OK;
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *pManager = CorHost2::GetHostTaskManager();
-
- if (pManager)
- {
-#ifdef _DEBUG
- // A SQL thread can enter the runtime w/o a managed thread.
- Thread *pThread = GetThread();
- if (pThread)
- {
- pThread->AddFiberInfo(Thread::ThreadTrackInfo_UM_M);
- }
-#endif
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->ReverseLeaveRuntime();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- if (hr != S_OK)
- ThrowHR(hr);
-
-}
-
-// For OS EnterCriticalSection, call host to enable ThreadAffinity
-void Thread::BeginThreadAffinity()
-{
- LIMITED_METHOD_CONTRACT;
-
-#ifndef FEATURE_CORECLR
- if (!CLRTaskHosted())
- {
- return;
- }
-
- if (IsGCSpecialThread() || IsDbgHelperSpecialThread())
- {
- return;
- }
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *pManager = CorHost2::GetHostTaskManager();
-
- HRESULT hr;
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->BeginThreadAffinity();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- _ASSERTE (hr == S_OK);
- Thread *pThread = GetThread();
-
- if (pThread)
- {
- pThread->IncThreadAffinityCount();
-#ifdef _DEBUG
- pThread->AddFiberInfo(Thread::ThreadTrackInfo_Affinity);
-#endif
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-#endif // !FEATURE_CORECLR
-}
-
-
-// For OS EnterCriticalSection, call host to enable ThreadAffinity
-void Thread::EndThreadAffinity()
-{
- LIMITED_METHOD_CONTRACT;
-
-#ifndef FEATURE_CORECLR
- if (!CLRTaskHosted())
- {
- return;
- }
-
- if (IsGCSpecialThread() || IsDbgHelperSpecialThread())
- {
- return;
- }
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *pManager = CorHost2::GetHostTaskManager();
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- Thread *pThread = GetThread();
- if (pThread)
- {
- pThread->DecThreadAffinityCount ();
-#ifdef _DEBUG
- pThread->AddFiberInfo(Thread::ThreadTrackInfo_Affinity);
-#endif
- }
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HRESULT hr = S_OK;
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pManager->EndThreadAffinity();
- END_SO_TOLERANT_CODE_CALLING_HOST;
-
- _ASSERTE (hr == S_OK);
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-#endif // !FEATURE_CORECLR
}
void Thread::SetupThreadForHost()
@@ -12911,35 +11059,6 @@ void Thread::SetupThreadForHost()
_ASSERTE (GetThread() == this);
CONTRACT_VIOLATION(SOToleranceViolation);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTask *pHostTask = GetHostTask();
- if (pHostTask) {
- SetupFiberData();
-
- // @todo - need to block for Interop debugging before leaving the runtime here.
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = pHostTask->SetCLRTask(this);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- {
- ThrowHR(hr);
- }
- if (m_WeOwnThreadHandle)
- {
- // If host provides a thread handle, we do not need to own a handle.
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- CorHost2::GetHostTaskManager()->SwitchToTask(0);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (m_ThreadHandleForClose != INVALID_HANDLE_VALUE)
- {
- m_WeOwnThreadHandle = FALSE;
- CloseHandle(m_ThreadHandleForClose);
- m_ThreadHandleForClose = INVALID_HANDLE_VALUE;
- }
- }
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
diff --git a/src/vm/threads.h b/src/vm/threads.h
index 51116e1ad6..a055f2e9e0 100644
--- a/src/vm/threads.h
+++ b/src/vm/threads.h
@@ -143,6 +143,7 @@
#include "mscoree.h"
#include "appdomainstack.h"
#include "gcheaputilities.h"
+#include "gchandletableutilities.h"
#include "gcinfotypes.h"
#include <clrhost.h>
@@ -244,12 +245,6 @@ public:
static void ObjectRefProtected(const OBJECTREF* ref) { }
static void ObjectRefNew(const OBJECTREF* ref) { }
- static void ReverseLeaveRuntime();
- static void __stdcall EnterRuntime();
-
- static void BeginThreadAffinity() { }
- static void EndThreadAffinity() { }
-
void EnablePreemptiveGC() { }
void DisablePreemptiveGC() { }
@@ -419,32 +414,6 @@ public:
}
};
-class LeaveRuntimeHolder
-{
-public:
- template <typename T>
- LeaveRuntimeHolder(T target)
- {
- STATIC_CONTRACT_LIMITED_METHOD;
- }
-};
-
-class LeaveRuntimeHolderNoThrow
-{
-public:
- template <typename T>
- LeaveRuntimeHolderNoThrow(T target)
- {
- STATIC_CONTRACT_LIMITED_METHOD;
- }
-
- HRESULT GetHR() const
- {
- STATIC_CONTRACT_LIMITED_METHOD;
- return S_OK;
- }
-};
-
inline BOOL dbgOnly_IsSpecialEEThread() { return FALSE; }
#define INCTHREADLOCKCOUNT() { }
@@ -584,14 +553,6 @@ inline Thread* GetThreadNULLOk()
#define GetThreadNULLOk() GetThread()
#endif
-//***************************************************************************
-#if defined(_DEBUG) && defined(_TARGET_X86_) && !defined(FEATURE_CORECLR)
- #define HAS_TRACK_CXX_EXCEPTION_CODE_HACK 1
- #define TRACK_CXX_EXCEPTION_CODE_HACK
-#else
- #define HAS_TRACK_CXX_EXCEPTION_CODE_HACK 0
-#endif
-
// manifest constant for waiting in the exposed classlibs
const INT32 INFINITE_TIMEOUT = -1;
@@ -675,7 +636,7 @@ DWORD GetAppDomainTLSIndex();
DWORD GetRuntimeId();
-EXTERN_C Thread* __stdcall CreateThreadBlockThrow();
+EXTERN_C Thread* WINAPI CreateThreadBlockThrow();
//---------------------------------------------------------------------------
// One-time initialization. Called during Dll initialization.
@@ -688,9 +649,9 @@ void InitThreadManager();
#ifdef FEATURE_HIJACK
-EXTERN_C void __stdcall OnHijackTripThread();
+EXTERN_C void WINAPI OnHijackTripThread();
#ifdef _TARGET_X86_
-EXTERN_C void __stdcall OnHijackFPTripThread(); // hijacked JIT code is returning an FP value
+EXTERN_C void WINAPI OnHijackFPTripThread(); // hijacked JIT code is returning an FP value
#endif // _TARGET_X86_
#endif // FEATURE_HIJACK
@@ -1036,14 +997,10 @@ class BaseStackGuard;
//
// A code:Thread contains all the per-thread information needed by the runtime. You can get at this
// structure throught the and OS TLS slot see code:#RuntimeThreadLocals for more
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-class Thread: public ICLRTask2
-#else // !FEATURE_INCLUDE_ALL_INTERFACES
// Implementing IUnknown would prevent the field (e.g. m_Context) layout from being rearranged (which will need to be fixed in
// "asmconstants.h" for the respective architecture). As it is, ICLRTask derives from IUnknown and would have got IUnknown implemented
// here - so doing this explicitly and maintaining layout sanity should be just fine.
class Thread: public IUnknown
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
friend struct ThreadQueue; // used to enqueue & dequeue threads onto SyncBlocks
friend class ThreadStore;
@@ -1274,9 +1231,7 @@ public:
// effort.
//
// Once we are completely independent of the OS UEF, we could remove this.
-#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
TSNC_InsideSyncContextWait = 0x02000000, // Whether we are inside DoSyncContextWait
-#endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
TSNC_DebuggerSleepWaitJoin = 0x04000000, // Indicates to the debugger that this thread is in a sleep wait or join state
// This almost mirrors the TS_Interruptible state however that flag can change
// during GC-preemptive mode whereas this one cannot.
@@ -1309,10 +1264,6 @@ public:
DAC_EMPTY_RET(E_FAIL);
STDMETHODIMP Reset (BOOL fFull)
DAC_EMPTY_RET(E_FAIL);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- STDMETHODIMP GetMemStats(COR_GC_THREAD_STATS *memUsage)
- DAC_EMPTY_RET(E_FAIL);
-#endif //FEATURE_INCLUDE_ALL_INTERFACES
STDMETHODIMP ExitTask()
DAC_EMPTY_RET(E_FAIL);
STDMETHODIMP Abort()
@@ -1500,6 +1451,24 @@ public:
}
#endif //FEATURE_COMINTEROP
+#ifndef DACCESS_COMPILE
+ bool HasDeadThreadBeenConsideredForGCTrigger()
+ {
+ LIMITED_METHOD_CONTRACT;
+ _ASSERTE(IsDead());
+
+ return m_fHasDeadThreadBeenConsideredForGCTrigger;
+ }
+
+ void SetHasDeadThreadBeenConsideredForGCTrigger()
+ {
+ LIMITED_METHOD_CONTRACT;
+ _ASSERTE(IsDead());
+
+ m_fHasDeadThreadBeenConsideredForGCTrigger = true;
+ }
+#endif // !DACCESS_COMPILE
+
// returns if there is some extra work for the finalizer thread.
BOOL HaveExtraWorkForFinalizer();
@@ -1641,13 +1610,6 @@ public:
// in the object header to store it.
DWORD m_ThreadId;
- #if HAS_TRACK_CXX_EXCEPTION_CODE_HACK // do we have C++ exception code tracking?
- // It's very hard to deal with SEH properly using C++ catch handlers. The
- // following field is updated with the correct SEH exception whenever a C++
- // __CxxFrameHandler3 call is made on this thread. If you grab it at the
- // top of a C++ catch(...), it's likely to be correct.
- DWORD m_LastCxxSEHExceptionCode;
- #endif // HAS_TRACK_CXX_EXCEPTION_CODE_HACK
// RWLock state
LockEntry *m_pHead;
@@ -1790,12 +1752,6 @@ public:
private:
DWORD m_dwBeginLockCount; // lock count when the thread enters current domain
-#ifndef FEATURE_CORECLR
- DWORD m_dwBeginCriticalRegionCount; // lock count when the thread enters current domain
- DWORD m_dwCriticalRegionCount;
-
- DWORD m_dwThreadAffinityCount;
-#endif // !FEATURE_CORECLR
#ifdef _DEBUG
DWORD dbg_m_cSuspendedThreads;
@@ -1888,68 +1844,19 @@ public:
LIMITED_METHOD_CONTRACT;
_ASSERTE(m_dwLockCount >= m_dwBeginLockCount);
-#ifndef FEATURE_CORECLR
- _ASSERTE(m_dwCriticalRegionCount >= m_dwBeginCriticalRegionCount);
-#endif // !FEATURE_CORECLR
// Equivalent to (m_dwLockCount != m_dwBeginLockCount ||
// m_dwCriticalRegionCount ! m_dwBeginCriticalRegionCount),
// but without branching instructions
BOOL fHasLock = (m_dwLockCount ^ m_dwBeginLockCount);
-#ifndef FEATURE_CORECLR
- fHasLock |= (m_dwCriticalRegionCount ^ m_dwBeginCriticalRegionCount);
-#endif // !FEATURE_CORECLR
return fHasLock;
}
-#ifndef FEATURE_CORECLR
- inline void BeginCriticalRegion()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE (GetThread() == this);
- if (CLRHosted())
- {
- m_dwCriticalRegionCount ++;
- _ASSERTE (m_dwCriticalRegionCount != 0);
- }
- }
-
- inline void EndCriticalRegion()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE (GetThread() == this);
- if (CLRHosted())
- {
- _ASSERTE (m_dwCriticalRegionCount > 0);
- m_dwCriticalRegionCount --;
- }
- }
-
- inline void BeginCriticalRegion_NoCheck()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE (GetThread() == this);
- m_dwCriticalRegionCount ++;
- _ASSERTE (m_dwCriticalRegionCount != 0);
- }
-
- inline void EndCriticalRegion_NoCheck()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE (GetThread() == this);
- _ASSERTE (m_dwCriticalRegionCount > 0);
- m_dwCriticalRegionCount --;
- }
-#endif // !FEATURE_CORECLR
inline BOOL HasCriticalRegion()
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- return m_dwCriticalRegionCount != 0;
-#else
return FALSE;
-#endif
}
inline DWORD GetNewHashCode()
@@ -1982,63 +1889,11 @@ public:
#endif
public:
- static void __stdcall LeaveRuntime(size_t target);
- static HRESULT LeaveRuntimeNoThrow(size_t target);
- static void __stdcall LeaveRuntimeThrowComplus(size_t target);
- static void __stdcall EnterRuntime();
- static HRESULT EnterRuntimeNoThrow();
- static HRESULT EnterRuntimeNoThrowWorker();
-
- // Reverse PInvoke hook for host
- static void ReverseEnterRuntime();
- static HRESULT ReverseEnterRuntimeNoThrow();
- static void ReverseEnterRuntimeThrowComplusHelper(HRESULT hr);
- static void ReverseEnterRuntimeThrowComplus();
- static void ReverseLeaveRuntime();
-
- // Hook for OS Critical Section, Mutex, and others that require thread affinity
- static void BeginThreadAffinity();
- static void EndThreadAffinity();
-
-#ifndef FEATURE_CORECLR
- inline void IncThreadAffinityCount()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE (GetThread() == this);
- m_dwThreadAffinityCount++;
- _ASSERTE (m_dwThreadAffinityCount > 0);
- }
- inline void DecThreadAffinityCount()
- {
- LIMITED_METHOD_CONTRACT;
- _ASSERTE (GetThread() == this);
- _ASSERTE (m_dwThreadAffinityCount > 0);
- m_dwThreadAffinityCount --;
- }
-
- static void BeginThreadAffinityAndCriticalRegion()
- {
- LIMITED_METHOD_CONTRACT;
- BeginThreadAffinity();
- GetThread()->BeginCriticalRegion();
- }
-
- static void EndThreadAffinityAndCriticalRegion()
- {
- LIMITED_METHOD_CONTRACT;
- GetThread()->EndCriticalRegion();
- EndThreadAffinity();
- }
-#endif // !FEATURE_CORECLR
BOOL HasThreadAffinity()
{
LIMITED_METHOD_CONTRACT;
-#ifndef FEATURE_CORECLR
- return m_dwThreadAffinityCount > 0;
-#else
return FALSE;
-#endif
}
private:
@@ -2603,9 +2458,6 @@ public:
return m_Context;
}
-#ifdef FEATURE_REMOTING
- void SetExposedContext(Context *c);
-#endif
// This callback is used when we are executing in the EE and discover that we need
// to switch appdomains.
@@ -2636,11 +2488,7 @@ private:
//
// In Telesto, we don't support true appdomain marshaling so the "orBlob" is in fact an
// agile wrapper object whose ToString() echoes the original exception's ToString().
-#ifdef FEATURE_CORECLR
typedef OBJECTREF ORBLOBREF;
-#else
- typedef U1ARRAYREF ORBLOBREF;
-#endif
RaiseCrossContextResult TryRaiseCrossContextException(Exception **ppExOrig,
Exception *pException,
@@ -2797,7 +2645,6 @@ public:
return (ObjectFromHandle(m_ExposedObject) != NULL) ;
}
-#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
void GetSynchronizationContext(OBJECTREF *pSyncContextObj)
{
CONTRACTL
@@ -2815,24 +2662,7 @@ public:
if (ExposedThreadObj != NULL)
*pSyncContextObj = ExposedThreadObj->GetSynchronizationContext();
}
-#endif // FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
-#ifdef FEATURE_COMPRESSEDSTACK
- OBJECTREF GetCompressedStack()
- {
- CONTRACTL
- {
- MODE_COOPERATIVE;
- GC_NOTRIGGER;
- NOTHROW;
- }
- CONTRACTL_END;
- THREADBASEREF ExposedThreadObj = (THREADBASEREF)GetExposedObjectRaw();
- if (ExposedThreadObj != NULL)
- return (OBJECTREF)(ExposedThreadObj->GetCompressedStack());
- return NULL;
- }
-#endif // #ifdef FEATURE_COMPRESSEDSTACK
// When we create a managed thread, the thread is suspended. We call StartThread to get
// the thread start.
@@ -2909,9 +2739,6 @@ public:
)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- _ASSERTE (m_pHostTask == NULL || GetThreadHandle() != SWITCHOUT_HANDLE_VALUE);
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
return ::GetThreadContext (GetThreadHandle(), lpContext);
}
@@ -2921,9 +2748,6 @@ public:
)
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- _ASSERTE (m_pHostTask == NULL || GetThreadHandle() != SWITCHOUT_HANDLE_VALUE);
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
return ::SetThreadContext (GetThreadHandle(), lpContext);
}
#endif
@@ -2931,12 +2755,7 @@ public:
BOOL HasValidThreadHandle ()
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- return m_pHostTask != NULL ||
- GetThreadHandle() != INVALID_HANDLE_VALUE;
-#else // !FEATURE_INCLUDE_ALL_INTERFACES
return GetThreadHandle() != INVALID_HANDLE_VALUE;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
DWORD GetThreadId()
@@ -2978,17 +2797,6 @@ public:
return m_dwConnectionId;
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTask* GetHostTask() const
- {
- LIMITED_METHOD_CONTRACT;
- return m_pHostTask;
- }
-
- IHostTask* GetHostTaskWithAddRef();
-
- void ReleaseHostTask();
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
void SetConnectionId(CONNID dwConnectionId)
{
@@ -3007,10 +2815,6 @@ public:
static bool SysStartSuspendForDebug(AppDomain *pAppDomain);
static bool SysSweepThreadsForDebug(bool forceSync);
static void SysResumeFromDebug(AppDomain *pAppDomain);
-#ifndef FEATURE_CORECLR
- void UserSuspendThread();
- BOOL UserResumeThread();
-#endif // FEATURE_CORECLR
void UserSleep(INT32 time);
@@ -3515,9 +3319,7 @@ private:
DWORD DoSignalAndWaitWorker(HANDLE* pHandles, DWORD millis,BOOL alertable);
#endif // !FEATURE_PAL
DWORD DoAppropriateAptStateWait(int numWaiters, HANDLE* pHandles, BOOL bWaitAll, DWORD timeout, WaitMode mode);
-#ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
DWORD DoSyncContextWait(OBJECTREF *pSyncCtxObj, int countHandles, HANDLE *handles, BOOL waitAll, DWORD millis);
-#endif // #ifdef FEATURE_SYNCHRONIZATIONCONTEXT_WAIT
public:
//************************************************************************
@@ -3615,10 +3417,12 @@ public:
static PCODE VirtualUnwindCallFrame(T_CONTEXT* pContext, T_KNONVOLATILE_CONTEXT_POINTERS* pContextPointers = NULL,
EECodeInfo * pCodeInfo = NULL);
static UINT_PTR VirtualUnwindCallFrame(PREGDISPLAY pRD, EECodeInfo * pCodeInfo = NULL);
+#ifndef DACCESS_COMPILE
static PCODE VirtualUnwindLeafCallFrame(T_CONTEXT* pContext);
static PCODE VirtualUnwindNonLeafCallFrame(T_CONTEXT* pContext, T_KNONVOLATILE_CONTEXT_POINTERS* pContextPointers = NULL,
PT_RUNTIME_FUNCTION pFunctionEntry = NULL, UINT_PTR uImageBase = NULL);
static UINT_PTR VirtualUnwindToFirstManagedCallFrame(T_CONTEXT* pContext);
+#endif // DACCESS_COMPILE
#endif // WIN64EXCEPTIONS
// During a <clinit>, this thread must not be asynchronously
@@ -3702,9 +3506,6 @@ public:
OBJECTREF GetCulture(BOOL bUICulture);
// Release user cultures that can't survive appdomain unload
-#ifdef FEATURE_LEAK_CULTURE_INFO
- void ResetCultureForDomain(ADID id);
-#endif // FEATURE_LEAK_CULTURE_INFO
// Functions to set the culture on the thread.
void SetCultureId(LCID lcid, BOOL bUICulture);
@@ -3930,9 +3731,11 @@ private:
void SetupForSuspension(ULONG bit)
{
WRAPPER_NO_CONTRACT;
- if (bit & TS_UserSuspendPending) {
- m_UserSuspendEvent.Reset();
- }
+
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(bit & TS_UserSuspendPending));
+
+
if (bit & TS_DebugSuspendPending) {
m_DebugSuspendEvent.Reset();
}
@@ -3949,8 +3752,14 @@ private:
//
ThreadState oldState = m_State;
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(oldState & TS_UserSuspendPending));
+
while ((oldState & (TS_UserSuspendPending | TS_DebugSuspendPending)) == 0)
{
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(oldState & TS_UserSuspendPending));
+
//
// Construct the destination state we desire - all suspension bits turned off.
//
@@ -3969,9 +3778,8 @@ private:
oldState = m_State;
}
- if (bit & TS_UserSuspendPending) {
- m_UserSuspendEvent.Set();
- }
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(bit & TS_UserSuspendPending));
if (bit & TS_DebugSuspendPending) {
m_DebugSuspendEvent.Set();
@@ -3979,13 +3787,6 @@ private:
}
- // For getting a thread to a safe point. A client waits on the event, which is
- // set by the thread when it reaches a safe spot.
-#ifndef FEATURE_CORECLR
- void FinishSuspendingThread();
-#endif // FEATURE_CORECLR
- void SetSafeEvent();
-
public:
FORCEINLINE void UnhijackThreadNoAlloc()
{
@@ -4070,7 +3871,7 @@ private:
void HandleThreadInterrupt(BOOL fWaitForADUnload);
public:
- static void __stdcall UserInterruptAPC(ULONG_PTR ignore);
+ static void WINAPI UserInterruptAPC(ULONG_PTR ignore);
#if defined(_DEBUG) && defined(TRACK_SYNC)
@@ -4106,8 +3907,6 @@ public:
private:
// For suspends:
- CLREvent m_SafeEvent;
- CLREvent m_UserSuspendEvent;
CLREvent m_DebugSuspendEvent;
// For Object::Wait, Notify and NotifyAll, we use an Event inside the
@@ -4177,7 +3976,6 @@ private:
DWORD m_OSThreadId;
BOOL CreateNewOSThread(SIZE_T stackSize, LPTHREAD_START_ROUTINE start, void *args);
- BOOL CreateNewHostTask(SIZE_T stackSize, LPTHREAD_START_ROUTINE start, void *args);
OBJECTHANDLE m_ExposedObject;
OBJECTHANDLE m_StrongHndToExposedObject;
@@ -4649,11 +4447,9 @@ public:
public:
typedef Holder<Thread *, DoNothing, Thread::LoadingFileRelease> LoadingFileHolder;
-#ifndef FEATURE_LEAK_CULTURE_INFO
void InitCultureAccessors();
FieldDesc *managedThreadCurrentCulture;
FieldDesc *managedThreadCurrentUICulture;
-#endif
private:
// Don't allow a thread to be asynchronously stopped or interrupted (e.g. because
// it is performing a <clinit>)
@@ -4903,16 +4699,6 @@ public:
size_t *m_pCleanedStackBase;
#endif
-#ifdef STRESS_THREAD
-public:
- LONG m_stressThreadCount;
-#endif
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-public:
- IHostTask *m_pHostTask;
-#endif
-
private:
PVOID m_pFiberData;
@@ -4985,7 +4771,7 @@ public:
private:
// used to pad stack on thread creation to avoid aliasing penalty in P4 HyperThread scenarios
- static DWORD __stdcall intermediateThreadProc(PVOID arg);
+ static DWORD WINAPI intermediateThreadProc(PVOID arg);
static int m_offset_counter;
static const int offset_multiplier = 128;
@@ -5247,10 +5033,6 @@ public:
static BOOL GetProcessDefaultStackSize(SIZE_T* reserveSize, SIZE_T* commitSize);
private:
- // YieldTask, ThreadAbort, GC all change thread context. ThreadAbort and GC uses ThreadStore lock to synchronize. But YieldTask can
- // not block. We use a counter to allow one thread to change thread context.
-
- Volatile<PVOID> m_WorkingOnThreadContext;
// Although this is a pointer, it is used as a flag to indicate the current context is unsafe
// to inspect. When NULL the context is safe to use, otherwise it points to the active patch skipper
@@ -5291,37 +5073,16 @@ private:
{
return FALSE;
}
- if (CLRTaskHosted())
- {
- PVOID myID = ClrTeb::GetFiberPtrId();
- PVOID id = FastInterlockCompareExchangePointer(pThread->m_WorkingOnThreadContext.GetPointer(), myID, NULL);
- return id == NULL || id == myID;
- }
- else
- {
- return TRUE;
- }
+ return TRUE;
}
static void LeaveWorkingOnThreadContext(Thread *pThread)
{
LIMITED_METHOD_CONTRACT;
-
- if (pThread->m_WorkingOnThreadContext == ClrTeb::GetFiberPtrId())
- {
- pThread->m_WorkingOnThreadContext = NULL;
- }
}
typedef ConditionalStateHolder<Thread *, Thread::EnterWorkingOnThreadContext, Thread::LeaveWorkingOnThreadContext> WorkingOnThreadContextHolder;
- BOOL WorkingOnThreadContext()
- {
- LIMITED_METHOD_CONTRACT;
-
- return !CLRTaskHosted() || m_WorkingOnThreadContext == ClrTeb::GetFiberPtrId();
- }
-
public:
void PrepareThreadForSOWork()
{
@@ -5489,6 +5250,9 @@ private:
// Disables pumping and thread join in RCW creation
bool m_fDisableComObjectEagerCleanup;
+ // See ThreadStore::TriggerGCForDeadThreadsIfNecessary()
+ bool m_fHasDeadThreadBeenConsideredForGCTrigger;
+
private:
CLRRandom m_random;
@@ -5603,16 +5367,9 @@ public:
LCID GetThreadCultureIdNoThrow(Thread *pThread, BOOL bUICulture);
-#ifndef FEATURE_CORECLR
-// Request/Remove Thread Affinity for the current thread
-typedef StateHolder<Thread::BeginThreadAffinityAndCriticalRegion, Thread::EndThreadAffinityAndCriticalRegion> ThreadAffinityAndCriticalRegionHolder;
-#endif // !FEATURE_CORECLR
-typedef StateHolder<Thread::BeginThreadAffinity, Thread::EndThreadAffinity> ThreadAffinityHolder;
-
typedef Thread::ForbidSuspendThreadHolder ForbidSuspendThreadHolder;
typedef Thread::ThreadPreventAsyncHolder ThreadPreventAsyncHolder;
typedef Thread::ThreadPreventAbortHolder ThreadPreventAbortHolder;
-typedef StateHolder<Thread::ReverseEnterRuntime, Thread::ReverseLeaveRuntime> ReverseEnterRuntimeHolder;
// Combines ForBindSuspendThreadHolder and CrstHolder into one.
class ForbidSuspendThreadCrstHolder
@@ -5629,97 +5386,13 @@ private:
CrstHolder m_lock_holder;
};
-// Non-throwing flavor of ReverseEnterRuntimeHolder that requires explicit call to AcquireNoThrow to acquire
-class ReverseEnterRuntimeHolderNoThrow : StateHolder<DoNothing, Thread::ReverseLeaveRuntime>
-{
-public:
- ReverseEnterRuntimeHolderNoThrow()
- : StateHolder<DoNothing, Thread::ReverseLeaveRuntime>(FALSE)
- {
- }
-
- HRESULT AcquireNoThrow()
- {
- WRAPPER_NO_CONTRACT;
-
- HRESULT hr = Thread::ReverseEnterRuntimeNoThrow();
- if (SUCCEEDED(hr))
- Acquire();
- return hr;
- }
-};
-
ETaskType GetCurrentTaskType();
-class LeaveRuntimeHolder
-{
-public:
- template <typename T>
- LeaveRuntimeHolder(T target)
- {
- STATIC_CONTRACT_WRAPPER;
- if (!CLRTaskHosted())
- return;
-
- Thread::LeaveRuntime((size_t)target);
- }
-
- ~LeaveRuntimeHolder()
- {
- STATIC_CONTRACT_WRAPPER;
- if (!CLRTaskHosted())
- return;
-
- Thread::EnterRuntime();
- }
-};
-
-class LeaveRuntimeHolderNoThrow
-{
-public:
- template <typename T>
- LeaveRuntimeHolderNoThrow(T target)
- {
- STATIC_CONTRACT_WRAPPER;
- if (!CLRTaskHosted())
- {
- hr = S_OK;
- return;
- }
-
- hr = Thread::LeaveRuntimeNoThrow((size_t)target);
- }
-
- ~LeaveRuntimeHolderNoThrow()
- {
- STATIC_CONTRACT_WRAPPER;
- if (!CLRTaskHosted())
- {
- hr = S_OK;
- return;
- }
-
- hr = Thread::EnterRuntimeNoThrow();
- }
-
- HRESULT GetHR() const
- {
- LIMITED_METHOD_CONTRACT;
- return hr;
- }
-
-private:
- HRESULT hr;
-};
-
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-IHostTask *GetCurrentHostTask();
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
typedef Thread::AVInRuntimeImplOkayHolder AVInRuntimeImplOkayHolder;
-BOOL RevertIfImpersonated(BOOL *bReverted, HANDLE *phToken, ThreadAffinityHolder *pTAHolder);
+BOOL RevertIfImpersonated(BOOL *bReverted, HANDLE *phToken);
void UndoRevert(BOOL bReverted, HANDLE hToken);
// ---------------------------------------------------------------------------
@@ -5866,6 +5539,8 @@ private:
LONG m_PendingThreadCount;
LONG m_DeadThreadCount;
+ LONG m_DeadThreadCountForGCTrigger;
+ bool m_TriggerGCForDeadThreads;
private:
// Space for the lazily-created GUID.
@@ -5878,6 +5553,11 @@ private:
Thread *m_HoldingThread;
EEThreadId m_holderthreadid; // current holder (or NULL)
+private:
+ static LONG s_DeadThreadCountThresholdForGCTrigger;
+ static DWORD s_DeadThreadGCTriggerPeriodMilliseconds;
+ static SIZE_T *s_DeadThreadGenerationCounts;
+
public:
static BOOL HoldingThreadStore()
@@ -5951,6 +5631,14 @@ public:
LIMITED_METHOD_CONTRACT;
s_pWaitForStackCrawlEvent->Reset();
}
+
+private:
+ void IncrementDeadThreadCountForGCTrigger();
+ void DecrementDeadThreadCountForGCTrigger();
+public:
+ void OnMaxGenerationGCStarted();
+ bool ShouldTriggerGCForDeadThreads();
+ void TriggerGCForDeadThreadsIfNecessary();
};
struct TSSuspendHelper {
@@ -6201,59 +5889,12 @@ struct PendingSync
void Restore(BOOL bRemoveFromSB);
};
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-
-//
-// Tracking of unmanaged locks has very low value. It is only
-// exposed via SQL hosting interfaces. The hosts cannot really
-// do anything interesting with it because of the unmanaged locks
-// are always taken with holders in the VM, and hosts can keep
-// track of the unmanaged locks taken via hosting API. We should
-// consider getting rid of it in the next SxS version.
-//
-
-#define INCTHREADLOCKCOUNT() \
-{ \
- /* IncLockCount() asserts GetThread() == this */ \
- BEGIN_GETTHREAD_ALLOWED_IN_NO_THROW_REGION; \
- Thread *thread = GetThread(); \
- if (thread) \
- thread->IncLockCount(); \
- END_GETTHREAD_ALLOWED_IN_NO_THROW_REGION; \
-}
-
-#define INCTHREADLOCKCOUNTTHREAD(thread) \
-{ \
- /* IncLockCount() asserts GetThread() == this */ \
- if (thread) \
- (thread)->IncLockCount(); \
-}
-
-#define DECTHREADLOCKCOUNT( ) \
-{ \
- /* IncLockCount() asserts GetThread() == this */ \
- BEGIN_GETTHREAD_ALLOWED_IN_NO_THROW_REGION; \
- Thread *thread = GetThread(); \
- if (thread) \
- thread->DecLockCount(); \
- END_GETTHREAD_ALLOWED_IN_NO_THROW_REGION; \
-}
-
-#define DECTHREADLOCKCOUNTTHREAD(thread) \
-{ \
- /* IncLockCount() asserts GetThread() == this */ \
- if (thread) \
- (thread)->DecLockCount(); \
-}
-
-#else
#define INCTHREADLOCKCOUNT() { }
#define DECTHREADLOCKCOUNT() { }
#define INCTHREADLOCKCOUNTTHREAD(thread) { }
#define DECTHREADLOCKCOUNTTHREAD(thread) { }
-#endif
// --------------------------------------------------------------------------------
// GCHolder is used to implement the normal GCX_ macros.
diff --git a/src/vm/threadsuspend.cpp b/src/vm/threadsuspend.cpp
index cdfbd79497..ab1f2bbff5 100644
--- a/src/vm/threadsuspend.cpp
+++ b/src/vm/threadsuspend.cpp
@@ -467,11 +467,7 @@ DWORD Thread::ResumeThread()
_ASSERTE (m_ThreadHandleForResume != INVALID_HANDLE_VALUE);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- _ASSERTE (m_pHostTask == 0 || GetThreadHandle() != SWITCHOUT_HANDLE_VALUE);
-#else // !FEATURE_INCLUDE_ALL_INTERFACES
_ASSERTE (GetThreadHandle() != SWITCHOUT_HANDLE_VALUE);
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
//DWORD res = ::ResumeThread(GetThreadHandle());
DWORD res = ::ResumeThread(m_ThreadHandleForResume);
@@ -754,29 +750,6 @@ static StackWalkAction TAStackCrawlCallBackWorker(CrawlFrame* pCf, StackCrawlCon
}
#undef METHODNAME
-#ifdef FEATURE_CER
- // If we're asking about CERs and we don't yet have a definite answer either way then take a closer look at the current method.
- if (pData->eType & StackCrawlContext::SCC_CheckWithinCer && !pData->fUnprotectedCode && !pData->fWithinCer)
- {
- // Check for CER root methods (these are never inlined). If we've found one of these at the root of a bunch of potential CER
- // methods (i.e. those with a compatible reliability contract) then we're executing in a CER.
- if (IsCerRootMethod(pMD))
- pData->fWithinCer = true;
-
- // Only need to look deeper if we couldn't decide if we're in a CER yet.
- if (!pData->fWithinCer)
- {
- // IL stubs are transparent to CERs.
- if (!pMD->IsILStub())
- // Check for reliability contracts on the method (and class and assembly). If it's high enough level to be included
- // in a CER then we can continue (hopefully finding a CER root method further down the stack). Otherwise we've got
- // at least one method that's not part of a CER on the top of the stack so we're definitely not executing within a
- // CER.
- if (CheckForReliabilityContract(pMD) < RCL_BASIC_CONTRACT)
- pData->fUnprotectedCode = true;
- }
- }
-#endif // FEATURE_CER
// If we weren't asked about EH clauses then we can return now (stop the stack trace if we have a definitive answer on the CER
// question, move to the next frame otherwise).
@@ -1124,50 +1097,6 @@ struct CerStackCrawlContext
bool m_fWithinCer; // The result
};
-#ifdef FEATURE_CER
-// Callback used on the stack crawl described above.
-StackWalkAction CerStackCrawlCallBack(CrawlFrame *pCf, void *pData)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- CerStackCrawlContext *pCtx = (CerStackCrawlContext *)pData;
-
- // Skip initial frame which should be our target.
- if (pCtx->m_fFirstFrame)
- {
- _ASSERTE(pCtx->m_pStartMethod == pCf->GetFunction());
- pCtx->m_fFirstFrame = false;
- return SWA_CONTINUE;
- }
-
- // If we get this far we've located the target method and are scanning the calling tree to see if we have a chain of methods
- // marked with strong reliability contracts terminated by a CER root method.
- MethodDesc *pMD = pCf->GetFunction();
- _ASSERTE(pMD != NULL);
-
- // If the current method is the root of a CER then we can say the target method was executing in a CER and terminate the stack
- // walk.
- // @TODO: Need to be more specific than this: only certain areas of the root method are actually in the CER.
- if (IsCerRootMethod(pMD))
- {
- pCtx->m_fWithinCer = true;
- return SWA_ABORT;
- }
-
- // Now look at reliability contracts on the current method. If they're missing or very weak then the chain is broken and the
- // target method cannot possibly be in a CER.
- if (CheckForReliabilityContract(pMD) < RCL_BASIC_CONTRACT)
- return SWA_ABORT;
-
- // Otherwise everything looks OK so far and we need to investigate the next frame.
- return SWA_CONTINUE;
-}
-#endif // FEATURE_CER
// Determine whether the method at the given depth in the thread's execution stack is executing within a CER.
BOOL Thread::IsWithinCer(CrawlFrame *pCf)
@@ -1179,126 +1108,7 @@ BOOL Thread::IsWithinCer(CrawlFrame *pCf)
}
CONTRACTL_END;
-#ifndef FEATURE_CER
return FALSE;
-#else
- // There had better be a method associated with this frame.
- MethodDesc *pMD = pCf->GetFunction();
- _ASSERTE(pMD != NULL);
-
- // Try the cheap checks first (before resorting to an actual stackwalk).
-
- // Handle IL stubs specially. We get called for these guys and they always appear to have a strong reliability contract (due to
- // the System.StubHelpers class they're placed in) but the stack walking logic we have below will skip them (messing up our
- // accounting). For simplicitly and speed we'll just always say these guys are in a CER (we trust the code and it won't block
- // indefinitely so it's a safe guess).
- if (pMD->IsILStub())
- return TRUE;
-
- // If the method is itself the root of a CER then we say yes immediately.
- // @TODO: Need to be more specific than this: only certain areas of the root method are actually in the CER.
- if (IsCerRootMethod(pMD))
- return TRUE;
-
- // Now look at reliability contracts on the method. If they're missing or very weak then this method cannot possibly be in a
- // CER.
- if (CheckForReliabilityContract(pMD) < RCL_BASIC_CONTRACT)
- return FALSE;
-
- // No way around it: this method has a good reliability contract but is not the root of a CER. We'll have to have to walk the
- // stack to determine whether it was called from a good root.
-
- // Now things get really tricky. We want to perform a recursive stackwalk (we're called as part of an ongoing stackwalk and we
- // wish to recursively look at one or more of the callers of the current frame).
- //
- // On x86 this is relatively straightforward -- we make a copy of the current crawl frame context (since walking the stack
- // updates the context) and build a new regdisplay around it. We can then start a new crawl from that context (ignoring the
- // first frame of course, because that's this frame).
- //
- // 64-bit is trickier because the context provided by the OS might not be (from our point of view) a valid current context. In
- // particular IA64 provides a mostly valid context except that the SP is from the caller. AMD64 on the other hand will always
- // provide a consistent context, but it may belong to either the current or caller frame. As noted above though, we're really
- // not all that interested in the current context, so as long as we can get to a consistent caller context we're happy.
- //
- // So for AMD64 we'll either have a complete current context and we'll use the the x86 algorithm or we have a complete caller
- // context and we can use more or less the x86 algorithm except we don't need to skip the first frame on the stackwalk callback.
- //
- // IA64 is trickier since it doesn't always give us a consistent context (current or caller). Here we'll have to bite the bullet
- // and perform a full stackwalk to build the context we're after. We'll use a combination of the caller SP and the current BSP
- // as a discriminator (to determine when the full stackwalk has synchronized with this frame and the real walk can begin, it's
- // the same discriminator the OS uses).
- //
- // <REVISIT_TODO> We will want to try and cache the context we eventually arrive at from this stack walk, since we're likely to see
- // further calls to IsWithinCer further down the stack and we can use the end context as a much faster way to sync to a valid
- // context in those cases. The chief technical difficulty there is cache management since the OS is handling the actual
- // exception walk (so we're not sure when to invalidate our cached data, which presumably we'd store on the Thread). Look into
- // hooking into the ExceptionTracker mechanism for this.</REVISIT_TODO>
-
- REGDISPLAY *pCurrentRd = pCf->GetRegisterSet();
- REGDISPLAY rd;
- CONTEXT ctx;
- CerStackCrawlContext sContext = { pMD, true, false };
-
-#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM_)
- // This check is similar to the one in ExceptionTracker::InitializeCrawlFrame.
- //
- // However, on ARM, we can easily check if we have the caller context (or not) by
- // checking the IsCallerContextValid field of RegDisplay, which is set during
- // the first pass of exception dispatch since the OS always passes us the caller
- // context in that scenario (refer to ExceptionTracker::InitializeCrawlFrame
- // implementation for details).
- if (ARM_ONLY(pCurrentRd->IsCallerContextValid) NOT_ARM(GetControlPC(pCurrentRd) != GetIP(pCurrentRd->pCurrentContext)))
- {
- // This is the case on AMD64, or ARM, where the OS has handed us the caller context. Build a regdisplay around that (pretending that
- // it's the current context) and reset our first frame flag so the stack walk we're about to do thinks we've already
- // processed the current frame.
- ctx = *pCurrentRd->pCallerContext;
- FillRegDisplay(&rd, &ctx);
- sContext.m_fFirstFrame = false;
- }
- else
-#endif // defined(_TARGET_AMD64_) || defined(_TARGET_ARM_)
- {
- // On x86, ARM or AMD64, where the OS gave us the current context, we just copy that into a new regdisplay (our stackwalking
- // callback will skip the first (current) frame for us).
- CopyRegDisplay(pCurrentRd, &rd, &ctx);
- }
-
- // The stackwalker requires a starting frame as input. If we're currently inspecting an explicit frame then it's easy -- we just
- // pass that. Otherwise (we're on some frameless managed method) we look at all of the frames for the current thread and choose
- // the one that would synchronize us for walking to the next frame.
- Frame *pFrame;
- if (pCf->IsFrameless())
- {
-#if defined(_TARGET_X86_)
- TADDR limitSP = GetRegdisplaySP(&rd);
-#else
- TADDR limitSP = (TADDR)( EECodeManager::GetCallerSp(&rd) );
-#endif
- pFrame = GetFrame();
- while (pFrame && (TADDR)(pFrame) < limitSP)
- pFrame = pFrame->Next();
- }
- else
- {
- pFrame = pCf->GetFrame();
-
-#ifdef _TARGET_X86_
- if (pFrame->GetVTablePtr() == InlinedCallFrame::GetMethodFrameVPtr())
- {
- // If we walk from an ICF, the function will not be reported again because X86 stack walker handles managed stack frame
- // before explicit frames contained in it.
- sContext.m_fFirstFrame = false;
- }
-#endif // _TARGET_X86_
- }
-
- StackWalkFramesEx(&rd, CerStackCrawlCallBack, &sContext, QUICKUNWIND | FUNCTIONSONLY, pFrame);
-
- _ASSERTE(!sContext.m_fFirstFrame);
-
- return sContext.m_fWithinCer;
-#endif // FEATURE_CER
}
#if defined(_TARGET_AMD64_) && defined(FEATURE_HIJACK)
@@ -1856,7 +1666,6 @@ Thread::UserAbort(ThreadAbortRequester requester,
DWORD elapsed_time = 0;
#endif
- ThreadAffinityHolder affinity;
// We do not want this thread to be alerted.
ThreadPreventAsyncHolder preventAsync(pCurThread != NULL);
@@ -2169,6 +1978,9 @@ LRetry:
m_dwAbortPoint = 7;
#endif
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(m_State & TS_UserSuspendPending));
+
//
// If it's stopped by the debugger, we don't want to throw an exception.
// Debugger suspension is to have no effect of the runtime behaviour.
@@ -3095,11 +2907,6 @@ void ThreadSuspend::LockThreadStore(ThreadSuspend::SUSPEND_REASON reason)
}
}
- // ThreadStoreLock is a critical lock used by GC, ThreadAbort, AD unload, Yield.
- // If a task is switched out while it owns ThreadStoreLock, it may not be able to
- // release it because the scheduler may be running managed code without yielding.
- Thread::BeginThreadAffinity();
-
// This is shutdown aware. If we're in shutdown, and not helper/finalizer/shutdown
// then this will not take the lock and just block forever.
ThreadStore::s_pThreadStore->Enter();
@@ -3159,8 +2966,6 @@ void ThreadSuspend::UnlockThreadStore(BOOL bThreadDestroyed, ThreadSuspend::SUSP
ThreadStore::s_pThreadStore->m_holderthreadid.Clear();
ThreadStore::s_pThreadStore->Leave();
- Thread::EndThreadAffinity();
-
// We're out of the critical area for managed/unmanaged debugging.
if (!bThreadDestroyed && pCurThread)
pCurThread->SetDebugCantStop(false);
@@ -3288,6 +3093,9 @@ void Thread::RareDisablePreemptiveGC()
goto Exit;
}
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(m_State & TS_UserSuspendPending));
+
// Note IsGCInProgress is also true for say Pause (anywhere SuspendEE happens) and GCThread is the
// thread that did the Pause. While in Pause if another thread attempts Rev/Pinvoke it should get inside the following and
// block until resume
@@ -3303,6 +3111,9 @@ void Thread::RareDisablePreemptiveGC()
do
{
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(m_State & TS_UserSuspendPending));
+
EnablePreemptiveGC();
// Cannot use GCX_PREEMP_NO_DTOR here because we're inside of the thread
@@ -3328,32 +3139,6 @@ void Thread::RareDisablePreemptiveGC()
#endif // PROFILING_SUPPORTED
-#if !defined(FEATURE_CORECLR) // simple hosting
- // First, check to see if there's an IDbgThreadControl interface that needs
- // notification of the suspension
- if (m_State & TS_DebugSuspendPending)
- {
- IDebuggerThreadControl *pDbgThreadControl = CorHost::GetDebuggerThreadControl();
-
- if (pDbgThreadControl)
- pDbgThreadControl->ThreadIsBlockingForDebugger();
-
- }
-
- if (CLRGCHosted())
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- CorHost2::GetHostGCManager()->ThreadIsBlockingForSuspension();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-
- // If not, check to see if there's an IGCThreadControl interface that needs
- // notification of the suspension
- IGCThreadControl *pGCThreadControl = CorHost::GetGCThreadControl();
-
- if (pGCThreadControl)
- pGCThreadControl->ThreadIsBlockingForSuspension();
-#endif // !defined(FEATURE_CORECLR)
DWORD status = S_OK;
SetThreadStateNC(TSNC_WaitUntilGCFinished);
@@ -3453,32 +3238,6 @@ void Thread::RareDisablePreemptiveGC()
#endif // PROFILING_SUPPORTED
-#if !defined(FEATURE_CORECLR) // simple hosting
- // First, check to see if there's an IDbgThreadControl interface that needs
- // notification of the suspension
- if (m_State & TS_DebugSuspendPending)
- {
- IDebuggerThreadControl *pDbgThreadControl = CorHost::GetDebuggerThreadControl();
-
- if (pDbgThreadControl)
- pDbgThreadControl->ThreadIsBlockingForDebugger();
-
- }
-
- if (CLRGCHosted())
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- CorHost2::GetHostGCManager()->ThreadIsBlockingForSuspension();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-
- // If not, check to see if there's an IGCThreadControl interface that needs
- // notification of the suspension
- IGCThreadControl *pGCThreadControl = CorHost::GetGCThreadControl();
-
- if (pGCThreadControl)
- pGCThreadControl->ThreadIsBlockingForSuspension();
-#endif // !defined(FEATURE_CORECLR)
// The thread is blocked for shutdown. We do not concern for GC violation.
CONTRACT_VIOLATION(GCViolation);
@@ -3745,7 +3504,11 @@ void Thread::PerformPreemptiveGC()
{
GCX_COOP();
m_bGCStressing = TRUE;
- GCHeapUtilities::GetGCHeap()->StressHeap();
+
+ // BUG(github #10318) - when not using allocation contexts, the alloc lock
+ // must be acquired here. Until fixed, this assert prevents random heap corruption.
+ _ASSERTE(GCHeapUtilities::UseThreadAllocationContexts());
+ GCHeapUtilities::GetGCHeap()->StressHeap(GetThread()->GetAllocContext());
m_bGCStressing = FALSE;
}
m_GCOnTransitionsOK = TRUE;
@@ -3804,7 +3567,6 @@ void Thread::RareEnablePreemptiveGC()
#endif // FEATURE_HIJACK
// wake up any threads waiting to suspend us, like the GC thread.
- SetSafeEvent();
ThreadSuspend::g_pGCSuspendEvent->Set();
// for GC, the fact that we are leaving the EE means that it no longer needs to
@@ -3812,6 +3574,9 @@ void Thread::RareEnablePreemptiveGC()
// Give the debugger precedence over user suspensions:
while (m_State & (TS_DebugSuspendPending | TS_UserSuspendPending))
{
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(m_State & TS_UserSuspendPending));
+
#ifdef DEBUGGING_SUPPORTED
// We don't notify the debugger that this thread is now suspended. We'll just
// let the debugger's helper thread sweep and pick it up.
@@ -3819,34 +3584,12 @@ void Thread::RareEnablePreemptiveGC()
// Life's much simpler this way...
-#if !defined(FEATURE_CORECLR) // simple hosting
- // Check to see if there's an IDbgThreadControl interface that needs
- // notification of the suspension
- if (m_State & TS_DebugSuspendPending)
- {
- IDebuggerThreadControl *pDbgThreadControl = CorHost::GetDebuggerThreadControl();
-
- if (pDbgThreadControl)
- pDbgThreadControl->ThreadIsBlockingForDebugger();
-
- }
-#endif // !defined(FEATURE_CORECLR)
#endif // DEBUGGING_SUPPORTED
#ifdef LOGGING
-#if !defined(FEATURE_CORECLR) // simple hosting
- if (!CorHost::IsDebuggerSpecialThread(GetThreadId()))
-#endif // !defined(FEATURE_CORECLR)
{
LOG((LF_CORDB, LL_INFO1000, "[0x%x] SUSPEND: suspended while enabling gc.\n", GetThreadId()));
}
-#if !defined(FEATURE_CORECLR) // simple hosting
- else
- {
- LOG((LF_CORDB, LL_INFO1000,
- "[0x%x] ALERT: debugger special thread did not suspend while enabling gc.\n", GetThreadId()));
- }
-#endif // !defined(FEATURE_CORECLR)
#endif
WaitSuspendEvents(); // sets bits, too
@@ -4092,11 +3835,6 @@ void NotifyHostOnGCSuspension()
}
CONTRACTL_END;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- CorHost2::GetHostGCManager()->ThreadIsBlockingForSuspension();
- END_SO_TOLERANT_CODE_CALLING_HOST;
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
// This function is called from the assembly functions used to redirect a thread. It must not cause
@@ -4176,30 +3914,11 @@ void __stdcall Thread::RedirectedHandledJITCase(RedirectReason reason)
// Enable PGC before calling out to the client to allow runtime suspend to finish
GCX_PREEMP_NO_DTOR();
- // <REVISIT_TODO>@TODO: Is this necessary? Does debugger wait on the events, or does it just
- // poll every so often?</REVISIT_TODO>
- // Notify the thread that is performing the suspension that this thread
- // is now in PGC mode and that it can remove this thread from the list of
- // threads it needs to wait for.
- pThread->SetSafeEvent();
-
// Notify the interface of the pending suspension
switch (reason) {
case RedirectReason_GCSuspension:
-#if !defined(FEATURE_CORECLR) // simple hosting
- if (CorHost::GetGCThreadControl())
- CorHost::GetGCThreadControl()->ThreadIsBlockingForSuspension();
- if (CLRGCHosted())
- {
- NotifyHostOnGCSuspension();
- }
-#endif // !defined(FEATURE_CORECLR)
break;
case RedirectReason_DebugSuspension:
-#if !defined(FEATURE_CORECLR) // simple hosting
- if (CorHost::GetDebuggerThreadControl() && CorHost::IsDebuggerSpecialThread(pThread->GetThreadId()))
- CorHost::GetDebuggerThreadControl()->ThreadIsBlockingForDebugger();
-#endif // !defined(FEATURE_CORECLR)
break;
case RedirectReason_UserSuspension:
// Do nothing;
@@ -4480,13 +4199,6 @@ BOOL Thread::RedirectThreadAtHandledJITCase(PFN_REDIRECTTARGET pTgt)
if (!IsContextSafeToRedirect(pCtx))
return (FALSE);
- if (CLRTaskHosted())
- {
- PCODE dwOrigEip = GetIP(pCtx);
- if (!ExecutionManager::IsManagedCode(dwOrigEip))
- return FALSE;
- }
-
////////////////////////////////////////////////////
// Now redirect the thread to the helper function
@@ -4857,21 +4569,6 @@ HRESULT ThreadSuspend::SuspendRuntime(ThreadSuspend::SUSPEND_REASON reason)
STRESS_LOG1(LF_SYNC, LL_INFO1000, "Thread::SuspendRuntime(reason=0x%x)\n", reason);
-#if !defined(FEATURE_CORECLR) // simple hosting
- // Alert the host that a GC is starting, in case the host is scheduling threads
- // for non-runtime tasks during GC.
- IGCThreadControl *pGCThreadControl = CorHost::GetGCThreadControl();
-
- if (pGCThreadControl)
- pGCThreadControl->SuspensionStarting();
-
- if (CLRGCHosted())
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- CorHost2::GetHostGCManager()->SuspensionStarting();
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // !defined(FEATURE_CORECLR)
#ifdef PROFILING_SUPPORTED
// If the profiler desires information about GCs, then let it know that one
@@ -4911,19 +4608,6 @@ HRESULT ThreadSuspend::SuspendRuntime(ThreadSuspend::SUSPEND_REASON reason)
}
}
-#ifdef FEATURE_STACK_PROBE
- // If CLR is hosted with IHostTaskManager and escalation policy for StackOverflow,
- // we need to make sure a thread is never blocked with a small stack, because the thread can
- // not be moved from scheduler in the host, and the scheduler may hold some resource needed by
- // suspension thread.
-
- // If we need to handle SO, GC will wait until a target thread has finished LeaveRuntime call. At
- // this point, the thread is off scheduler. If it hits SO, we will kill the process. If the thread hits
- // SO while calling LeaveRuntime, we treat this as SO in managed code, and unload the domain instead.
- BOOL fConsiderSO = (CLRTaskHosted() &&
- GetEEPolicy()->GetActionOnFailure(FAIL_StackOverflow) == eRudeUnloadAppDomain);
-#endif
-
// From this point until the end of the function, consider all active thread
// suspension to be in progress. This is mainly to give the profiler API a hint
// that trying to suspend a thread (in order to walk its stack) could delay the
@@ -5124,23 +4808,6 @@ HRESULT ThreadSuspend::SuspendRuntime(ThreadSuspend::SUSPEND_REASON reason)
QueueUserAPC((PAPCFUNC)PauseAPC, handle, APC_Code);
}
}
-
-#ifdef FEATURE_STACK_PROBE
- if (thread->m_fPreemptiveGCDisabled.Load() == 0 && fConsiderSO)
- {
- if ((UINT_PTR)thread->m_pFrame - thread->GetLastAllowableStackAddress() <
- ADJUST_PROBE(BACKOUT_CODE_STACK_LIMIT) * OS_PAGE_SIZE)
- {
- if (!thread->HasThreadState(Thread::TS_GCSuspendPending))
- {
- thread->SetThreadState(Thread::TS_GCSuspendPending);
- countThreads++;
- STRESS_LOG2(LF_SYNC, LL_INFO1000, " Setting thread 0x%x ID 0x%x for GC (SO)\n",
- thread, thread->GetThreadId());
- }
- }
- }
-#endif
}
#ifdef _DEBUG
@@ -5197,28 +4864,18 @@ HRESULT ThreadSuspend::SuspendRuntime(ThreadSuspend::SUSPEND_REASON reason)
if (!thread->m_fPreemptiveGCDisabled)
{
-#ifdef FEATURE_STACK_PROBE
- if (fConsiderSO && (UINT_PTR)thread->m_pFrame - thread->GetLastAllowableStackAddress() <
- ADJUST_PROBE(BACKOUT_CODE_STACK_LIMIT) * OS_PAGE_SIZE)
- {
- // The thread is not ready for GC.
- }
- else
-#endif
+ // Inlined N/Direct can sneak out to preemptive without actually checking.
+ // If we find one, we can consider it suspended (since it can't get back in).
+ STRESS_LOG1(LF_SYNC, LL_INFO1000, " Thread %x went preemptive it is at a GC safe point\n", thread);
+ countThreads--;
+ thread->ResetThreadState(Thread::TS_GCSuspendPending);
+
+ // To ensure 0 CPU utilization for FAS (see implementation of PauseAPC)
+ // we queue the APC to all interruptable threads.
+ if(g_IsPaused && (thread->m_State & Thread::TS_Interruptible))
{
- // Inlined N/Direct can sneak out to preemptive without actually checking.
- // If we find one, we can consider it suspended (since it can't get back in).
- STRESS_LOG1(LF_SYNC, LL_INFO1000, " Thread %x went preemptive it is at a GC safe point\n", thread);
- countThreads--;
- thread->ResetThreadState(Thread::TS_GCSuspendPending);
-
- // To ensure 0 CPU utilization for FAS (see implementation of PauseAPC)
- // we queue the APC to all interruptable threads.
- if(g_IsPaused && (thread->m_State & Thread::TS_Interruptible))
- {
- HANDLE handle = thread->GetThreadHandle();
- QueueUserAPC((PAPCFUNC)PauseAPC, handle, APC_Code);
- }
+ HANDLE handle = thread->GetThreadHandle();
+ QueueUserAPC((PAPCFUNC)PauseAPC, handle, APC_Code);
}
}
}
@@ -5562,33 +5219,6 @@ void ThreadSuspend::ResumeRuntime(BOOL bFinishedGC, BOOL SuspendSucceded)
// Notify everyone who cares, that this suspension is over, and this thread is going to go do other things.
//
-#if !defined(FEATURE_CORECLR) // simple hosting
- // Alert the host that a GC is ending, in case the host is scheduling threads
- // for non-runtime tasks during GC.
- IGCThreadControl *pGCThreadControl = CorHost::GetGCThreadControl();
-
- if (pGCThreadControl)
- {
- // If we the suspension was for a GC, tell the host what generation GC.
- DWORD Generation = (bFinishedGC
- ? GCHeapUtilities::GetGCHeap()->GetCondemnedGeneration()
- : ~0U);
-
- pGCThreadControl->SuspensionEnding(Generation);
- }
-
- if (CLRGCHosted())
- {
- // If we the suspension was for a GC, tell the host what generation GC.
- DWORD Generation = (bFinishedGC
- ? GCHeapUtilities::GetGCHeap()->GetCondemnedGeneration()
- : ~0U);
-
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- CorHost2::GetHostGCManager()->SuspensionEnding(Generation);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // !defined(FEATURE_CORECLR)
#ifdef PROFILING_SUPPORTED
// Need to give resume event for the GC thread
@@ -5961,13 +5591,6 @@ bool Thread::SysStartSuspendForDebug(AppDomain *pAppDomain)
// Caller is expected to be holding the ThreadStore lock
_ASSERTE(ThreadStore::HoldingThreadStore() || IsAtProcessExit());
-#if !defined(FEATURE_CORECLR) // simple hosting
- // If there is a debugging thread control object, tell it we're suspending the Runtime.
- IDebuggerThreadControl *pDbgThreadControl = CorHost::GetDebuggerThreadControl();
-
- if (pDbgThreadControl)
- pDbgThreadControl->StartBlockingForDebugger(0);
-#endif // !defined(FEATURE_CORECLR)
// NOTE::NOTE::NOTE::NOTE::NOTE
// This function has parallel logic in SuspendRuntime. Please make
@@ -6341,16 +5964,6 @@ void Thread::SysResumeFromDebug(AppDomain *pAppDomain)
LOG((LF_CORDB, LL_INFO1000, "RESUME: starting resume AD:0x%x.\n", pAppDomain));
-#if !defined(FEATURE_CORECLR) // simple hosting
- // Notify the client that it should release any threads that it had doing work
- // while the runtime was debugger-suspended.
- IDebuggerThreadControl *pIDTC = CorHost::GetDebuggerThreadControl();
- if (pIDTC)
- {
- LOG((LF_CORDB, LL_INFO1000, "RESUME: notifying IDebuggerThreadControl client.\n"));
- pIDTC->ReleaseAllRuntimeThreads();
- }
-#endif // !defined(FEATURE_CORECLR)
// Make sure we completed the previous sync
_ASSERTE(m_DebugWillSyncCount == -1);
@@ -6407,335 +6020,6 @@ void Thread::SysResumeFromDebug(AppDomain *pAppDomain)
LOG((LF_CORDB, LL_INFO1000, "RESUME: resume complete. Trap count: %d\n", g_TrapReturningThreads.Load()));
}
-#ifndef FEATURE_CORECLR
-
-// Suspend a thread at the system level. We distinguish between user suspensions,
-// and system suspensions so that a VB program cannot resume a thread we have
-// suspended for GC.
-//
-// This service won't return until the suspension is complete. This deserves some
-// explanation. The thread is considered to be suspended if it can make no further
-// progress within the EE. For example, a thread that has exited the EE via
-// COM Interop or N/Direct is considered suspended -- if we've arranged it so that
-// the thread cannot return back to the EE without blocking.
-void Thread::UserSuspendThread()
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- // Read the general comments on thread suspension earlier, to understand why we
- // take these locks.
-
- // GC can occur in here:
- STRESS_LOG0(LF_SYNC, LL_INFO100, "UserSuspendThread obtain lock\n");
- ThreadStoreLockHolder tsl;
-
- // User suspensions (e.g. from VB and C#) are distinguished from internal
- // suspensions so a poorly behaved program cannot resume a thread that the system
- // has suspended for GC.
- if (m_State & TS_UserSuspendPending)
- {
- // This thread is already experiencing a user suspension, so ignore the
- // new request.
- _ASSERTE(!ThreadStore::HoldingThreadStore(this));
- }
- else
- if (this != GetThread())
- {
- // First suspension of a thread other than the current one.
- if (m_State & TS_Unstarted)
- {
- // There is an important window in here. T1 can call T2.Start() and then
- // T2.Suspend(). Suspend is disallowed on an unstarted thread. But from T1's
- // point of view, T2 is started. In reality, T2 hasn't been scheduled by the
- // OS, so it is still an unstarted thread. We don't want to perform a normal
- // suspension on it in this case, because it is currently contributing to the
- // PendingThreadCount. We want to get it fully started before we suspend it.
- // This is particularly important if its background status is changing
- // underneath us because otherwise we might not detect that the process should
- // be exited at the right time.
- //
- // It turns out that this is a simple situation to implement. We are holding
- // the ThreadStoreLock. TransferStartedThread will likewise acquire that
- // lock. So if we detect it, we simply set a bit telling the thread to
- // suspend itself. This is NOT the normal suspension request because we don't
- // want the thread to suspend until it has fully started.
- FastInterlockOr((ULONG *) &m_State, TS_SuspendUnstarted);
- }
- else if (m_State & (TS_Detached | TS_Dead))
- {
- return;
- }
- else
- {
- // We just want to trap this thread if it comes back into cooperative mode
- SetupForSuspension(TS_UserSuspendPending);
- m_SafeEvent.Reset();
-
- // Pause it so we can operate on it without it squirming under us.
-RetrySuspension:
- // We can not allocate memory after we suspend a thread.
- // Otherwise, we may deadlock the process when CLR is hosted.
- ThreadStore::AllocateOSContext();
-
- SuspendThreadResult str = SuspendThread();
-
- // The only safe place to suspend a thread asynchronously is if it is in
- // fully interruptible cooperative JIT code. Preemptive mode can hold all
- // kinds of locks that make it unsafe to suspend. All other cases are
- // handled somewhat synchronously (e.g. through hijacks, GC mode toggles, etc.)
- //
- // For example, on a SMP if the thread is blocked waiting for the ThreadStore
- // lock, it can cause a deadlock if we suspend it (even though it is in
- // preemptive mode).
- //
- // If a thread is in preemptive mode (including the tricky optimized N/Direct
- // case), we can just mark it for suspension. It will make no further progress
- // in the EE.
- if (str == STR_NoStressLog)
- {
- // We annot assume anything about the thread's current state.
- goto RetrySuspension;
- }
- else if (!m_fPreemptiveGCDisabled)
- {
- MarkForSuspension(TS_UserSuspendPending);
-
- // Let the thread run until it reaches a safe spot.
- if (str == STR_Success)
- {
- ResumeThread();
- }
- }
- else if (str == STR_Failure || str == STR_UnstartedOrDead)
- {
- // The thread cannot be unstarted, as we have already
- // checked for that above.
- _ASSERTE(!(m_State & TS_Unstarted));
-
- // Nothing to do if the thread has already terminated.
- }
- else if (str == STR_SwitchedOut)
- {
- goto RetrySuspension;
- }
- else
- {
- _ASSERTE(str == STR_Success);
-#if defined(FEATURE_HIJACK) && !defined(PLATFORM_UNIX)
- WorkingOnThreadContextHolder workingOnThreadContext(this);
- if (workingOnThreadContext.Acquired() && HandledJITCase())
- {
- _ASSERTE(m_fPreemptiveGCDisabled);
- // Redirect thread so we can capture a good thread context
- // (GetThreadContext is not sufficient, due to an OS bug).
- // If we don't succeed (should only happen on Win9X, due to
- // a different OS bug), we must resume the thread and try
- // again.
- if (!CheckForAndDoRedirectForUserSuspend())
- {
- ResumeThread();
- goto RetrySuspension;
- }
- }
-#endif // FEATURE_HIJACK && !PLATFORM_UNIX
-
- // Thread is executing in cooperative mode. We're going to have to
- // move it to a safe spot.
- MarkForSuspension(TS_UserSuspendPending);
-
- // Let the thread run until it reaches a safe spot.
- ResumeThread();
-
- // wait until it leaves cooperative GC mode or is JIT suspended
- FinishSuspendingThread();
- }
- }
- }
- else
- {
- GCX_PREEMP();
- SetupForSuspension(TS_UserSuspendPending);
- MarkForSuspension(TS_UserSuspendPending);
-
- // prepare to block ourselves
- tsl.Release();
- _ASSERTE(!ThreadStore::HoldingThreadStore(this));
-
- WaitSuspendEvents();
- }
-}
-
-
-// if the only suspension of this thread is user imposed, resume it. But don't
-// resume from any system suspensions (like GC).
-BOOL Thread::UserResumeThread()
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- // If we are attempting to resume when we aren't in a user suspension,
- // its an error.
- BOOL res = FALSE;
-
- // Note that the model does not count. In other words, you can call Thread.Suspend()
- // five times and Thread.Resume() once. The result is that the thread resumes.
-
- STRESS_LOG0(LF_SYNC, INFO3, "UserResumeThread obtain lock\n");
- ThreadStoreLockHolder TSLockHolder;
-
- // If we have marked a thread for suspension, while that thread is still starting
- // up, simply remove the bit to resume it.
- if (m_State & TS_SuspendUnstarted)
- {
- _ASSERTE((m_State & TS_UserSuspendPending) == 0);
- FastInterlockAnd((ULONG *) &m_State, ~TS_SuspendUnstarted);
- res = TRUE;
- }
-
- // If we are still trying to suspend the thread, forget about it.
- if (m_State & TS_UserSuspendPending)
- {
- ReleaseFromSuspension(TS_UserSuspendPending);
- SetSafeEvent();
- res = TRUE;
- }
-
- return res;
-}
-
-
-// We are asynchronously trying to suspend this thread. Stay here until we achieve
-// that goal (in fully interruptible JIT code), or the thread dies, or it leaves
-// the EE (in which case the Pending flag will cause it to synchronously suspend
-// itself later, or if the thread tells us it is going to synchronously suspend
-// itself because of hijack activity, etc.
-void Thread::FinishSuspendingThread()
-{
- CONTRACTL {
- NOTHROW;
- if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);}
- }
- CONTRACTL_END;
-
- DWORD res;
-
- // There are two threads of interest -- the current thread and the thread we are
- // going to wait for. Since the current thread is about to wait, it's important
- // that it be in preemptive mode at this time.
-
-#if _DEBUG
- DWORD dbgTotalTimeout = 0;
-#endif
-
- // Wait for us to enter the ping period, then check if we are in interruptible
- // JIT code.
- while (TRUE)
- {
- ThreadSuspend::UnlockThreadStore();
- res = m_SafeEvent.Wait(PING_JIT_TIMEOUT,FALSE);
- STRESS_LOG0(LF_SYNC, INFO3, "FinishSuspendingThread obtain lock\n");
- ThreadSuspend::LockThreadStore(ThreadSuspend::SUSPEND_OTHER);
-
- if (res == WAIT_TIMEOUT)
- {
-#ifdef _DEBUG
- if ((dbgTotalTimeout += PING_JIT_TIMEOUT) >= g_pConfig->SuspendDeadlockTimeout())
- {
- _ASSERTE(!"Timeout detected trying to synchronously suspend a thread");
- dbgTotalTimeout = 0;
- }
-#endif
- // Suspend the thread and see if we are in interruptible code (placing
- // a hijack if warranted).
-#if defined(FEATURE_HIJACK) && !defined(PLATFORM_UNIX)
- RetrySuspension:
-#endif
- // The thread is detached/dead. Suspend is no op.
- if (m_State & (TS_Detached | TS_Dead))
- {
- return;
- }
-
- // We can not allocate memory after we suspend a thread.
- // Otherwise, we may deadlock the process when CLR is hosted.
- ThreadStore::AllocateOSContext();
-
- SuspendThreadResult str = SuspendThread();
-
- if (m_fPreemptiveGCDisabled && str == STR_Success)
- {
-#if defined(FEATURE_HIJACK) && !defined(PLATFORM_UNIX)
- WorkingOnThreadContextHolder workingOnThreadContext(this);
- if (workingOnThreadContext.Acquired() && HandledJITCase())
- {
- _ASSERTE(m_State & TS_UserSuspendPending);
- // Redirect thread so we can capture a good thread context
- // (GetThreadContext is not sufficient, due to an OS bug).
- // If we don't succeed (should only happen on Win9X, due to
- // a different OS bug), we must resume the thread and try
- // again.
- if (!CheckForAndDoRedirectForUserSuspend())
- {
- ResumeThread();
- goto RetrySuspension;
- }
- }
-#endif // FEATURE_HIJACK && !PLATFORM_UNIX
- // Keep trying...
- ResumeThread();
- }
- else if (!m_fPreemptiveGCDisabled)
- {
- // The thread has transitioned out of the EE. It can't get back in
- // without synchronously suspending itself. We can now return to our
- // caller since this thread cannot make further progress within the
- // EE.
- if (str == STR_Success)
- {
- ResumeThread();
- }
- break;
- }
- else if (str == STR_SwitchedOut)
- {
- // The task has been switched out while in Cooperative GC mode.
- // We will wait for the thread again.
- }
- }
- else
- {
- // SafeEvent has been set so we don't need to actually suspend. Either
- // the thread died, or it will enter a synchronous suspension based on
- // the UserSuspendPending bit.
- _ASSERTE(res == WAIT_OBJECT_0);
- _ASSERTE(!ThreadStore::HoldingThreadStore(this));
- break;
- }
- }
-}
-
-#endif // FEATURE_CORECLR
-
-
-void Thread::SetSafeEvent()
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- m_SafeEvent.Set();
-}
-
-
/*
*
* WaitSuspendEventsHelper
@@ -6762,28 +6046,10 @@ BOOL Thread::WaitSuspendEventsHelper(void)
EX_TRY {
- if (m_State & TS_UserSuspendPending) {
-
- ThreadState oldState = m_State;
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(m_State & TS_UserSuspendPending));
- while (oldState & TS_UserSuspendPending) {
-
- ThreadState newState = (ThreadState)(oldState | TS_SyncSuspended);
- if (FastInterlockCompareExchange((LONG *)&m_State, newState, oldState) == (LONG)oldState)
- {
- result = m_UserSuspendEvent.Wait(INFINITE,FALSE);
-#if _DEBUG
- newState = m_State;
- _ASSERTE(!(newState & TS_SyncSuspended) || (newState & TS_DebugSuspendPending));
-#endif
- break;
- }
-
- oldState = m_State;
- }
-
-
- } else if (m_State & TS_DebugSuspendPending) {
+ if (m_State & TS_DebugSuspendPending) {
ThreadState oldState = m_State;
@@ -6833,6 +6099,9 @@ void Thread::WaitSuspendEvents(BOOL fDoWait)
ThreadState oldState = m_State;
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(!(oldState & TS_UserSuspendPending));
+
//
// If all reasons to suspend are off, we think we can exit
// this loop, but we need to check atomically.
@@ -7693,8 +6962,6 @@ BOOL Thread::HandledJITCase(BOOL ForTaskSwitchIn)
ExecutionState esb;
StackWalkAction action;
- _ASSERTE(WorkingOnThreadContext());
-
CONTEXT ctx;
REGDISPLAY rd;
if (!GetSafelyRedirectableThreadContext(
@@ -7814,9 +7081,9 @@ void Thread::MarkForSuspension(ULONG bit)
}
CONTRACTL_END;
+ // CoreCLR does not support user-requested thread suspension
_ASSERTE(bit == TS_DebugSuspendPending ||
- bit == (TS_DebugSuspendPending | TS_DebugWillSync) ||
- bit == TS_UserSuspendPending);
+ bit == (TS_DebugSuspendPending | TS_DebugWillSync));
_ASSERTE(IsAtProcessExit() || ThreadStore::HoldingThreadStore());
@@ -7834,8 +7101,8 @@ void Thread::UnmarkForSuspension(ULONG mask)
}
CONTRACTL_END;
- _ASSERTE(mask == ~TS_DebugSuspendPending ||
- mask == ~TS_UserSuspendPending);
+ // CoreCLR does not support user-requested thread suspension
+ _ASSERTE(mask == ~TS_DebugSuspendPending);
_ASSERTE(IsAtProcessExit() || ThreadStore::HoldingThreadStore());
@@ -7897,7 +7164,7 @@ void ThreadSuspend::RestartEE(BOOL bFinishedGC, BOOL SuspendSucceded)
// Revert to being a normal thread
//
ClrFlsClearThreadType (ThreadType_DynamicSuspendEE);
- GCHeapUtilities::GetGCHeap()->SetGCInProgress(FALSE);
+ GCHeapUtilities::GetGCHeap()->SetGCInProgress(false);
//
// Allow threads to enter COOP mode (though we still need to wake the ones
@@ -8065,7 +7332,7 @@ retry_for_debugger:
// It seems like much of the above is redundant. We should investigate reducing the number
// of mechanisms we use to indicate that a suspension is in progress.
//
- GCHeapUtilities::GetGCHeap()->SetGCInProgress(TRUE);
+ GCHeapUtilities::GetGCHeap()->SetGCInProgress(true);
//
// Gratuitous memory barrier. (may be needed - but I'm not sure why.)
diff --git a/src/vm/threadsuspend.h b/src/vm/threadsuspend.h
index 428c914372..022e46a35e 100644
--- a/src/vm/threadsuspend.h
+++ b/src/vm/threadsuspend.h
@@ -92,8 +92,7 @@ struct SuspendStatistics
// a Suspend to the end of a Restart. We can compute 'avg' using 'cnt' and 'tot' values.
MinMaxTot suspend, restart, paused;
- // We know there can be contention on acquiring the ThreadStoreLock, or yield points when hosted (like
- // BeginThreadAffinity on the leading edge and EndThreadAffinity on the trailing edge).
+ // We know there can be contention on acquiring the ThreadStoreLock.
MinMaxTot acquireTSL, releaseTSL;
// And if we OS suspend a thread that is blocking or perhaps throwing an exception and is therefore
diff --git a/src/vm/tieredcompilation.cpp b/src/vm/tieredcompilation.cpp
new file mode 100644
index 0000000000..2032e66f1b
--- /dev/null
+++ b/src/vm/tieredcompilation.cpp
@@ -0,0 +1,377 @@
+// 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.
+// ===========================================================================
+// File: TieredCompilation.CPP
+//
+// ===========================================================================
+
+
+
+#include "common.h"
+#include "excep.h"
+#include "log.h"
+#include "win32threadpool.h"
+#include "tieredcompilation.h"
+
+// TieredCompilationManager determines which methods should be recompiled and
+// how they should be recompiled to best optimize the running code. It then
+// handles logistics of getting new code created and installed.
+//
+//
+// # Current feature state
+//
+// This feature is incomplete and currently experimental. To enable it
+// you need to set COMPLUS_EXPERIMENTAL_TieredCompilation = 1. When the environment
+// variable is unset the runtime should work as normal, but when it is set there are
+// anticipated incompatibilities and limited cross cutting test coverage so far.
+// Profiler - Anticipated incompatible with ReJIT, untested in general
+// ETW - Anticipated incompatible with the ReJIT id of the MethodJitted rundown events
+// Managed debugging - Anticipated incompatible with breakpoints/stepping that are
+// active when a method is recompiled.
+//
+//
+// Testing that has been done so far largely consists of regression testing with
+// the environment variable off + functional/perf testing of the Music Store ASP.Net
+// workload as a basic example that the feature can work. Running the coreclr repo
+// tests with the env var on generates about a dozen failures in JIT tests. The issues
+// are likely related to assertions about optimization behavior but haven't been
+// properly investigated yet.
+//
+// If you decide to try this out on a new workload and run into trouble a quick note
+// on github is appreciated but this code may have high churn for a while to come and
+// there will be no sense investing a lot of time investigating only to have it rendered
+// moot by changes. I aim to keep this comment updated as things change.
+//
+//
+// # Important entrypoints in this code:
+//
+//
+// a) .ctor and Init(...) - called once during AppDomain initialization
+// b) OnMethodCalled(...) - called when a method is being invoked. When a method
+// has been called enough times this is currently the only
+// trigger that initiates re-compilation.
+// c) OnAppDomainShutdown() - called during AppDomain::Exit() to begin the process
+// of stopping tiered compilation. After this point no more
+// background optimization work will be initiated but in-progress
+// work still needs to complete.
+//
+// # Overall workflow
+//
+// Methods initially call into OnMethodCalled() and once the call count exceeds
+// a fixed limit we queue work on to our internal list of methods needing to
+// be recompiled (m_methodsToOptimize). If there is currently no thread
+// servicing our queue asynchronously then we use the runtime threadpool
+// QueueUserWorkItem to recruit one. During the callback for each threadpool work
+// item we handle as many methods as possible in a fixed period of time, then
+// queue another threadpool work item if m_methodsToOptimize hasn't been drained.
+//
+// The background thread enters at StaticOptimizeMethodsCallback(), enters the
+// appdomain, and then begins calling OptimizeMethod on each method in the
+// queue. For each method we jit it, then update the precode so that future
+// entrypoint callers will run the new code.
+//
+// # Error handling
+//
+// The overall principle is don't swallow terminal failures that may have corrupted the
+// process (AV for example), but otherwise for any transient issue or functional limitation
+// that prevents us from optimizing log it for diagnostics and then back out gracefully,
+// continuing to run the less optimal code. The feature should be constructed so that
+// errors are limited to OS resource exhaustion or poorly behaved managed code
+// (for example within an AssemblyResolve event or static constructor triggered by the JIT).
+
+#ifdef FEATURE_TIERED_COMPILATION
+
+// Called at AppDomain construction
+TieredCompilationManager::TieredCompilationManager() :
+ m_isAppDomainShuttingDown(FALSE),
+ m_countOptimizationThreadsRunning(0),
+ m_callCountOptimizationThreshhold(30),
+ m_optimizationQuantumMs(50)
+{
+ LIMITED_METHOD_CONTRACT;
+ m_lock.Init(LOCK_TYPE_DEFAULT);
+}
+
+// Called at AppDomain Init
+void TieredCompilationManager::Init(ADID appDomainId)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CAN_TAKE_LOCK;
+ MODE_PREEMPTIVE;
+ }
+ CONTRACTL_END;
+
+ SpinLockHolder holder(&m_lock);
+ m_domainId = appDomainId;
+}
+
+// Called each time code in this AppDomain has been run. This is our sole entrypoint to begin
+// tiered compilation for now. Returns TRUE if no more notifications are necessary, but
+// more notifications may come anyways.
+//
+// currentCallCount is pre-incremented, that is to say the value is 1 on first call for a given
+// method.
+BOOL TieredCompilationManager::OnMethodCalled(MethodDesc* pMethodDesc, DWORD currentCallCount)
+{
+ STANDARD_VM_CONTRACT;
+
+ if (currentCallCount < m_callCountOptimizationThreshhold)
+ {
+ return FALSE; // continue notifications for this method
+ }
+ else if (currentCallCount > m_callCountOptimizationThreshhold)
+ {
+ return TRUE; // stop notifications for this method
+ }
+
+ // Insert the method into the optimization queue and trigger a thread to service
+ // the queue if needed.
+ //
+ // Terminal exceptions escape as exceptions, but all other errors should gracefully
+ // return to the caller. Non-terminal error conditions should be rare (ie OOM,
+ // OS failure to create thread) and we consider it reasonable for some methods
+ // to go unoptimized or have their optimization arbitrarily delayed under these
+ // circumstances. Note an error here could affect concurrent threads running this
+ // code. Those threads will observe m_countOptimizationThreadsRunning > 0 and return,
+ // then QueueUserWorkItem fails on this thread lowering the count and leaves them
+ // unserviced. Synchronous retries appear unlikely to offer any material improvement
+ // and complicating the code to narrow an already rare error case isn't desirable.
+ {
+ SListElem<MethodDesc*>* pMethodListItem = new (nothrow) SListElem<MethodDesc*>(pMethodDesc);
+ SpinLockHolder holder(&m_lock);
+ if (pMethodListItem != NULL)
+ {
+ m_methodsToOptimize.InsertTail(pMethodListItem);
+ }
+
+ if (0 == m_countOptimizationThreadsRunning && !m_isAppDomainShuttingDown)
+ {
+ // Our current policy throttles at 1 thread, but in the future we
+ // could experiment with more parallelism.
+ m_countOptimizationThreadsRunning++;
+ }
+ else
+ {
+ return TRUE; // stop notifications for this method
+ }
+ }
+
+ EX_TRY
+ {
+ if (!ThreadpoolMgr::QueueUserWorkItem(StaticOptimizeMethodsCallback, this, QUEUE_ONLY, TRUE))
+ {
+ SpinLockHolder holder(&m_lock);
+ m_countOptimizationThreadsRunning--;
+ STRESS_LOG1(LF_TIEREDCOMPILATION, LL_WARNING, "TieredCompilationManager::OnMethodCalled: "
+ "ThreadpoolMgr::QueueUserWorkItem returned FALSE (no thread will run), method=%pM\n",
+ pMethodDesc);
+ }
+ }
+ EX_CATCH
+ {
+ SpinLockHolder holder(&m_lock);
+ m_countOptimizationThreadsRunning--;
+ STRESS_LOG2(LF_TIEREDCOMPILATION, LL_WARNING, "TieredCompilationManager::OnMethodCalled: "
+ "Exception queuing work item to threadpool, hr=0x%x, method=%pM\n",
+ GET_EXCEPTION()->GetHR(), pMethodDesc);
+ }
+ EX_END_CATCH(RethrowTerminalExceptions);
+
+ return TRUE; // stop notifications for this method
+}
+
+void TieredCompilationManager::OnAppDomainShutdown()
+{
+ SpinLockHolder holder(&m_lock);
+ m_isAppDomainShuttingDown = TRUE;
+}
+
+// This is the initial entrypoint for the background thread, called by
+// the threadpool.
+DWORD WINAPI TieredCompilationManager::StaticOptimizeMethodsCallback(void *args)
+{
+ STANDARD_VM_CONTRACT;
+
+ TieredCompilationManager * pTieredCompilationManager = (TieredCompilationManager *)args;
+ pTieredCompilationManager->OptimizeMethodsCallback();
+
+ return 0;
+}
+
+//This method will process one or more methods from optimization queue
+// on a background thread. Each such method will be jitted with code
+// optimizations enabled and then installed as the active implementation
+// of the method entrypoint.
+//
+// We need to be carefuly not to work for too long in a single invocation
+// of this method or we could starve the threadpool and force
+// it to create unnecessary additional threads.
+void TieredCompilationManager::OptimizeMethodsCallback()
+{
+ STANDARD_VM_CONTRACT;
+
+ // This app domain shutdown check isn't required for correctness
+ // but it should reduce some unneeded exceptions trying
+ // to enter a closed AppDomain
+ {
+ SpinLockHolder holder(&m_lock);
+ if (m_isAppDomainShuttingDown)
+ {
+ m_countOptimizationThreadsRunning--;
+ return;
+ }
+ }
+
+ ULONGLONG startTickCount = CLRGetTickCount64();
+ MethodDesc* pMethod = NULL;
+ EX_TRY
+ {
+ ENTER_DOMAIN_ID(m_domainId);
+ {
+ while (true)
+ {
+ {
+ SpinLockHolder holder(&m_lock);
+ pMethod = GetNextMethodToOptimize();
+ if (pMethod == NULL ||
+ m_isAppDomainShuttingDown)
+ {
+ m_countOptimizationThreadsRunning--;
+ break;
+ }
+
+ }
+ OptimizeMethod(pMethod);
+
+ // If we have been running for too long return the thread to the threadpool and queue another event
+ // This gives the threadpool a chance to service other requests on this thread before returning to
+ // this work.
+ ULONGLONG currentTickCount = CLRGetTickCount64();
+ if (currentTickCount >= startTickCount + m_optimizationQuantumMs)
+ {
+ if (!ThreadpoolMgr::QueueUserWorkItem(StaticOptimizeMethodsCallback, this, QUEUE_ONLY, TRUE))
+ {
+ SpinLockHolder holder(&m_lock);
+ m_countOptimizationThreadsRunning--;
+ STRESS_LOG0(LF_TIEREDCOMPILATION, LL_WARNING, "TieredCompilationManager::OptimizeMethodsCallback: "
+ "ThreadpoolMgr::QueueUserWorkItem returned FALSE (no thread will run)\n");
+ }
+ break;
+ }
+ }
+ }
+ END_DOMAIN_TRANSITION;
+ }
+ EX_CATCH
+ {
+ STRESS_LOG2(LF_TIEREDCOMPILATION, LL_ERROR, "TieredCompilationManager::OptimizeMethodsCallback: "
+ "Unhandled exception during method optimization, hr=0x%x, last method=%pM\n",
+ GET_EXCEPTION()->GetHR(), pMethod);
+ }
+ EX_END_CATCH(RethrowTerminalExceptions);
+}
+
+// Jit compiles and installs new optimized code for a method.
+// Called on a background thread.
+void TieredCompilationManager::OptimizeMethod(MethodDesc* pMethod)
+{
+ STANDARD_VM_CONTRACT;
+
+ _ASSERTE(pMethod->IsEligibleForTieredCompilation());
+ PCODE pJittedCode = CompileMethod(pMethod);
+ if (pJittedCode != NULL)
+ {
+ InstallMethodCode(pMethod, pJittedCode);
+ }
+}
+
+// Compiles new optimized code for a method.
+// Called on a background thread.
+PCODE TieredCompilationManager::CompileMethod(MethodDesc* pMethod)
+{
+ STANDARD_VM_CONTRACT;
+
+ PCODE pCode = NULL;
+ ULONG sizeOfCode = 0;
+ EX_TRY
+ {
+ CORJIT_FLAGS flags = CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_MCJIT_BACKGROUND);
+ flags.Add(CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_TIER1));
+
+ if (pMethod->IsDynamicMethod())
+ {
+ ILStubResolver* pResolver = pMethod->AsDynamicMethodDesc()->GetILStubResolver();
+ flags.Add(pResolver->GetJitFlags());
+ COR_ILMETHOD_DECODER* pILheader = pResolver->GetILHeader();
+ pCode = UnsafeJitFunction(pMethod, pILheader, flags, &sizeOfCode);
+ }
+ else
+ {
+ COR_ILMETHOD_DECODER::DecoderStatus status;
+ COR_ILMETHOD_DECODER header(pMethod->GetILHeader(), pMethod->GetModule()->GetMDImport(), &status);
+ pCode = UnsafeJitFunction(pMethod, &header, flags, &sizeOfCode);
+ }
+ }
+ EX_CATCH
+ {
+ // Failing to jit should be rare but acceptable. We will leave whatever code already exists in place.
+ STRESS_LOG2(LF_TIEREDCOMPILATION, LL_INFO10, "TieredCompilationManager::CompileMethod: Method %pM failed to jit, hr=0x%x\n",
+ pMethod, GET_EXCEPTION()->GetHR());
+ }
+ EX_END_CATCH(RethrowTerminalExceptions)
+
+ return pCode;
+}
+
+// Updates the MethodDesc and precode so that future invocations of a method will
+// execute the native code pointed to by pCode.
+// Called on a background thread.
+void TieredCompilationManager::InstallMethodCode(MethodDesc* pMethod, PCODE pCode)
+{
+ STANDARD_VM_CONTRACT;
+
+ _ASSERTE(!pMethod->IsNativeCodeStableAfterInit());
+
+ PCODE pExistingCode = pMethod->GetNativeCode();
+ if (!pMethod->SetNativeCodeInterlocked(pCode, pExistingCode))
+ {
+ //We aren't there yet, but when the feature is finished we shouldn't be racing against any other code mutator and there would be no
+ //reason for this to fail
+ STRESS_LOG2(LF_TIEREDCOMPILATION, LL_INFO10, "TieredCompilationManager::InstallMethodCode: Method %pM failed to update native code slot. Code=%pK\n",
+ pMethod, pCode);
+ }
+ else
+ {
+ Precode* pPrecode = pMethod->GetPrecode();
+ if (!pPrecode->SetTargetInterlocked(pCode, FALSE))
+ {
+ //We aren't there yet, but when the feature is finished we shouldn't be racing against any other code mutator and there would be no
+ //reason for this to fail
+ STRESS_LOG2(LF_TIEREDCOMPILATION, LL_INFO10, "TieredCompilationManager::InstallMethodCode: Method %pM failed to update precode. Code=%pK\n",
+ pMethod, pCode);
+ }
+ }
+}
+
+// Dequeues the next method in the optmization queue.
+// This should be called with m_lock already held and runs
+// on the background thread.
+MethodDesc* TieredCompilationManager::GetNextMethodToOptimize()
+{
+ STANDARD_VM_CONTRACT;
+
+ SListElem<MethodDesc*>* pElem = m_methodsToOptimize.RemoveHead();
+ if (pElem != NULL)
+ {
+ MethodDesc* pMD = pElem->GetValue();
+ delete pElem;
+ return pMD;
+ }
+ return NULL;
+}
+
+#endif // FEATURE_TIERED_COMPILATION
diff --git a/src/vm/tieredcompilation.h b/src/vm/tieredcompilation.h
new file mode 100644
index 0000000000..71236c5374
--- /dev/null
+++ b/src/vm/tieredcompilation.h
@@ -0,0 +1,51 @@
+// 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.
+// ===========================================================================
+// File: TieredCompilation.h
+//
+// ===========================================================================
+
+
+#ifndef TIERED_COMPILATION_H
+#define TIERED_COMPILATION_H
+
+#ifdef FEATURE_TIERED_COMPILATION
+
+// TieredCompilationManager determines which methods should be recompiled and
+// how they should be recompiled to best optimize the running code. It then
+// handles logistics of getting new code created and installed.
+class TieredCompilationManager
+{
+public:
+#if defined(DACCESS_COMPILE) || defined(CROSSGEN_COMPILE)
+ TieredCompilationManager() {}
+#else
+ TieredCompilationManager();
+#endif
+
+ void Init(ADID appDomainId);
+ BOOL OnMethodCalled(MethodDesc* pMethodDesc, DWORD currentCallCount);
+ void OnAppDomainShutdown();
+
+private:
+
+ static DWORD StaticOptimizeMethodsCallback(void* args);
+ void OptimizeMethodsCallback();
+ void OptimizeMethod(MethodDesc* pMethod);
+ MethodDesc* GetNextMethodToOptimize();
+ PCODE CompileMethod(MethodDesc* pMethod);
+ void InstallMethodCode(MethodDesc* pMethod, PCODE pCode);
+
+ SpinLock m_lock;
+ SList<SListElem<MethodDesc*>> m_methodsToOptimize;
+ ADID m_domainId;
+ BOOL m_isAppDomainShuttingDown;
+ DWORD m_countOptimizationThreadsRunning;
+ DWORD m_callCountOptimizationThreshhold;
+ DWORD m_optimizationQuantumMs;
+};
+
+#endif // FEATURE_TIERED_COMPILATION
+
+#endif // TIERED_COMPILATION_H
diff --git a/src/vm/tlbexport.cpp b/src/vm/tlbexport.cpp
deleted file mode 100644
index 01f5239620..0000000000
--- a/src/vm/tlbexport.cpp
+++ /dev/null
@@ -1,6344 +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.
-//===========================================================================
-// File: TlbExport.CPP
-//
-
-//
-// Notes: Create a TypeLib from COM+ metadata.
-//---------------------------------------------------------------------------
-
-#include "common.h"
-
-#include "comcallablewrapper.h"
-#include "field.h"
-#include "dllimport.h"
-#include "fieldmarshaler.h"
-#include "eeconfig.h"
-#include "comdelegate.h"
-#include <nsutilpriv.h>
-#include <tlbimpexp.h>
-#include <mlang.h>
-#include "tlbexport.h"
-#include "commtmemberinfomap.h"
-#include <corerror.h>
-#include "posterror.h"
-#include "typeparse.h"
-
-#if defined(VALUE_MASK)
-#undef VALUE_MASK
-#endif
-
-#include <guidfromname.h>
-#include <stgpool.h>
-#include <siginfo.hpp>
-#include <typestring.h>
-#include "perfcounters.h"
-#include "comtypelibconverter.h"
-#include "caparser.h"
-
-// Define to export an empty dispinterface for an AutoDispatch IClassX
-#define EMPTY_DISPINTERFACE_ICLASSX
-#ifndef S_USEIUNKNOWN
-#define S_USEIUNKNOWN (HRESULT)2
-#endif
-
-#if defined(_DEBUG) && defined(_TRACE)
-#define TRACE printf
-#else
-#define TRACE NullFn
-inline void NullFn(const char *pf,...) {}
-#endif
-
-#if defined(_DEBUG)
-#define IfFailReport(expr) \
- do { if(FAILED(hr = (expr))) { DebBreakHr(hr); ReportError(hr); } } while (0)
-#else
-#define IfFailReport(expr) \
- do { if(FAILED(hr = (expr))) { ReportError(hr); } } while (0)
-#endif
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// This value determines whether, by default, we add the TYPEFLAG_FPROXY bit
-// to exported interfaces. If the value is true, Automation proxy is the
-// default, and we do not set the bit. If the value is false, no Automation
-// proxy is the default and we DO set the bit.
-#define DEFAULT_AUTOMATION_PROXY_VALUE TRUE
-//-----------------------------------------------------------------------------
-
-//*****************************************************************************
-// Constants.
-//*****************************************************************************
-static const WCHAR szRetVal[] = W("pRetVal");
-static const WCHAR szTypeLibExt[] = W(".TLB");
-
-static const WCHAR szTypeLibKeyName[] = W("TypeLib");
-static const WCHAR szClsidKeyName[] = W("CLSID");
-
-static const WCHAR szIClassX[] = W("_%ls");
-static const int cbIClassX = 1;
-static const WCHAR cIClassX = W('_');
-
-static const WCHAR szAlias[] = W("_MIDL_COMPAT_%ls");
-static const int cbAlias = lengthof(szAlias) - 1;
-static const WCHAR szParamName[] = W("p%d");
-
-static const WCHAR szGuidName[] = W("GUID");
-
-static const CHAR szObjectClass[] = "Object";
-static const CHAR szArrayClass[] = "Array";
-static const CHAR szDateTimeClass[] = "DateTime";
-static const CHAR szDecimalClass[] = "Decimal";
-static const CHAR szGuidClass[] = "Guid";
-static const CHAR szStringClass[] = g_StringName;
-static const CHAR szStringBufferClass[] = g_StringBufferName;
-static const CHAR szIEnumeratorClass[] = "IEnumerator";
-static const CHAR szColor[] = "Color";
-
-static const char szRuntime[] = {"System."};
-static const size_t cbRuntime = (lengthof(szRuntime)-1);
-
-static const char szText[] = {"System.Text."};
-static const size_t cbText = (lengthof(szText)-1);
-
-static const char szCollections[] = {"System.Collections."};
-static const size_t cbCollections = (lengthof(szCollections)-1);
-
-static const char szDrawing[] = {"System.Drawing."};
-static const size_t cbDrawing = (lengthof(szDrawing)-1);
-
-// The length of the following string(w/o the terminator): "HKEY_CLASSES_ROOT\\CLSID\\{00000000-0000-0000-0000-000000000000}".
-static const int cCOMCLSIDRegKeyLength = 62;
-
-// The length of the following string(w/o the terminator): "{00000000-0000-0000-0000-000000000000}".
-static const int cCLSIDStrLength = 38;
-
-// {17093CC8-9BD2-11cf-AA4F-304BF89C0001}
-static const GUID GUID_TRANS_SUPPORTED = {0x17093CC8,0x9BD2,0x11cf,{0xAA,0x4F,0x30,0x4B,0xF8,0x9C,0x00,0x01}};
-
-// {00020430-0000-0000-C000-000000000046}
-static const GUID LIBID_STDOLE2 = { 0x00020430, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
-
-// {66504301-BE0F-101A-8BBB-00AA00300CAB}
-static const GUID GUID_OleColor = { 0x66504301, 0xBE0F, 0x101A, { 0x8B, 0xBB, 0x00, 0xAA, 0x00, 0x30, 0x0C, 0xAB } };
-
-// LIBID mscoree
-static const GUID LIBID_MSCOREE = {0x5477469e,0x83b1,0x11d2,{0x8b,0x49,0x00,0xa0,0xc9,0xb7,0xc9,0xc4}};
-
-static const char XXX_DESCRIPTION_TYPE[] = {"System.ComponentModel.DescriptionAttribute"};
-static const char XXX_ASSEMBLY_DESCRIPTION_TYPE[] = {"System.Reflection.AssemblyDescriptionAttribute"};
-
-//*****************************************************************************
-// Table to map COM+ calling conventions to TypeLib calling conventions.
-//*****************************************************************************
-CALLCONV Clr2TlbCallConv[] =
-{
- CC_STDCALL, // IMAGE_CEE_CS_CALLCONV_DEFAULT = 0x0,
- CC_CDECL, // IMAGE_CEE_CS_CALLCONV_C = 0x1,
- CC_STDCALL, // IMAGE_CEE_CS_CALLCONV_STDCALL = 0x2,
- CC_STDCALL, // IMAGE_CEE_CS_CALLCONV_THISCALL = 0x3,
- CC_FASTCALL, // IMAGE_CEE_CS_CALLCONV_FASTCALL = 0x4,
- CC_CDECL, // IMAGE_CEE_CS_CALLCONV_VARARG = 0x5,
- CC_MAX // IMAGE_CEE_CS_CALLCONV_FIELD = 0x6,
- // IMAGE_CEE_CS_CALLCONV_MAX = 0x7
-};
-
-
-
-// Forward declarations.
-extern HRESULT _FillVariant(MDDefaultValue *pMDDefaultValue, VARIANT *pvar);
-extern HRESULT _FillMDDefaultValue(BYTE bType, void const *pValue, MDDefaultValue *pMDDefaultValue);
-
-//*****************************************************************************
-// Stolen from classlib.
-//*****************************************************************************
-double _TicksToDoubleDate(const __int64 ticks)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- const INT64 MillisPerSecond = 1000;
- const INT64 MillisPerDay = MillisPerSecond * 60 * 60 * 24;
- const INT64 TicksPerMillisecond = 10000;
- const INT64 TicksPerSecond = TicksPerMillisecond * 1000;
- const INT64 TicksPerMinute = TicksPerSecond * 60;
- const INT64 TicksPerHour = TicksPerMinute * 60;
- const INT64 TicksPerDay = TicksPerHour * 24;
- const int DaysPer4Years = 365 * 4 + 1;
- const int DaysPer100Years = DaysPer4Years * 25 - 1;
- const int DaysPer400Years = DaysPer100Years * 4 + 1;
- const int DaysTo1899 = DaysPer400Years * 4 + DaysPer100Years * 3 - 367;
- const INT64 DoubleDateOffset = DaysTo1899 * TicksPerDay;
- const int DaysTo10000 = DaysPer400Years * 25 - 366;
- const INT64 MaxMillis = DaysTo10000 * MillisPerDay;
- const int DaysPerYear = 365; // non-leap year
- const INT64 OADateMinAsTicks = (DaysPer100Years - DaysPerYear) * TicksPerDay;
-
- // Returns OleAut's zero'ed date ticks.
- if (ticks == 0)
- return 0.0;
-
- if (ticks < OADateMinAsTicks)
- return 0.0;
-
- // Currently, our max date == OA's max date (12/31/9999), so we don't
- // need an overflow check in that direction.
- __int64 millis = (ticks - DoubleDateOffset) / TicksPerMillisecond;
- if (millis < 0)
- {
- __int64 frac = millis % MillisPerDay;
- if (frac != 0) millis -= (MillisPerDay + frac) * 2;
- }
-
- return (double)millis / MillisPerDay;
-} // double _TicksToDoubleDate()
-
-
-//*****************************************************************************
-// Get the name of a typelib or typeinfo, add it to error text.
-//*****************************************************************************
-void PostTypeLibError(
- IUnknown *pUnk, // An interface on the typeinfo.
- HRESULT hrT, // The TypeInfo error.
- HRESULT hrX) // The Exporter error.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pUnk));
- }
- CONTRACTL_END;
-
- HRESULT hr; // A result.
- WCHAR rcErr[1024]; // Buffer for error message.
-
- SafeComHolder<ITypeInfo> pITI=0; // The ITypeInfo * on the typeinfo.
- SafeComHolder<ITypeLib> pITLB=0; // The ITypeLib *.
- BSTRHolder name=0; // The name of the TypeInfo.
-
- // Try to get a name.
- hr = SafeQueryInterface(pUnk, IID_ITypeInfo, (IUnknown**)&pITI);
- if (SUCCEEDED(hr))
- {
- IfFailThrow(pITI->GetDocumentation(MEMBERID_NIL, &name, 0,0,0));
- }
- else
- {
- hr = SafeQueryInterface(pUnk, IID_ITypeLib, (IUnknown**)&pITLB);
- if (SUCCEEDED(hr))
- IfFailThrow(pITLB->GetDocumentation(MEMBERID_NIL, &name, 0,0,0));
- }
-
- if (name == NULL)
- {
- name = SysAllocString(W("???"));
- if (name == NULL)
- COMPlusThrowHR(E_OUTOFMEMORY);
- }
-
- // Format the typelib error.
- FormatRuntimeError(rcErr, lengthof(rcErr), hrT);
-
- SString strHRHex;
- strHRHex.Printf("%.8x", hrX);
-
- COMPlusThrowHR(hrX, hrX, strHRHex, name, rcErr);
-} // void PostTypeLibError()
-
-
-
-
-void ExportTypeLibFromLoadedAssembly(
- Assembly *pAssembly, // The assembly.
- LPCWSTR szTlb, // The typelib name.
- ITypeLib **ppTlb, // If not null, also return ITypeLib here.
- ITypeLibExporterNotifySink *pINotify,// Notification callback.
- int flags) // Export flags.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pAssembly));
- PRECONDITION(CheckPointer(szTlb, NULL_OK));
- PRECONDITION(CheckPointer(ppTlb));
- PRECONDITION(CheckPointer(pINotify, NULL_OK));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- TypeLibExporter exporter; // Exporter object.
- LPCWSTR szModule=0; // Module filename.
- StackSString ssDrive;
- StackSString ssDir;
- StackSString ssFile;
- size_t cchDrive;
- size_t cchDir;
- size_t cchFile;
- CQuickWSTR rcTlb; // Buffer for the tlb filename.
- int bDynamic=0; // If true, dynamic module.
- Module *pModule; // The Assembly's SecurityModule.
-
- pModule = pAssembly->GetManifestModule();
- _ASSERTE(pModule);
-
- // Retrieve the module filename.
- szModule = pModule->GetPath();
- PREFIX_ASSUME(szModule != NULL);
-
- // Make sure the assembly has not been imported from COM.
- if (pAssembly->IsImportedFromTypeLib())
- COMPlusThrowHR(TLBX_E_CIRCULAR_EXPORT, (UINT)TLBX_E_CIRCULAR_EXPORT, W(""), szModule, NULL);
-
- // If the module is dynamic then it will not have a file name. We
- // assign a dummy name for typelib name (if the scope does not have
- // a name), but won't create a typelib on disk.
- if (*szModule == 0)
- {
- bDynamic = TRUE;
- szModule = W("Dynamic");
- }
-
- // Create the typelib name, if none provided. Don't create one for Dynamic modules.
- if (!szTlb || !*szTlb)
- {
- if (bDynamic)
- szTlb = W("");
- else
- {
- SplitPath(szModule, &ssDrive, &ssDir, &ssFile, nullptr);
- MakePath(rcTlb, ssDrive.GetUnicode(), ssDir.GetUnicode(), ssFile.GetUnicode(), szTypeLibExt);
- szTlb = rcTlb.Ptr();
- }
- }
-
- // Do the conversion.
- exporter.Convert(pAssembly, szTlb, pINotify, flags);
-
- // Get a copy of the ITypeLib*
- IfFailThrow(exporter.GetTypeLib(IID_ITypeLib, (IUnknown**)ppTlb));
-} // void ExportTypeLibFromLoadedAssemblyInternal()
-
-
-HRESULT ExportTypeLibFromLoadedAssemblyNoThrow(
- Assembly *pAssembly, // The assembly.
- LPCWSTR szTlb, // The typelib name.
- ITypeLib **ppTlb, // If not null, also return ITypeLib here.
- ITypeLibExporterNotifySink *pINotify,// Notification callback.
- int flags) // Export flags.
-{
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- EX_TRY
- {
- ExportTypeLibFromLoadedAssembly(pAssembly,
- szTlb,
- ppTlb,
- pINotify,
- flags);
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
-//*****************************************************************************
-// Default notification class.
-//*****************************************************************************
-class CDefaultNotify : public ITypeLibExporterNotifySink
-{
-public:
- virtual HRESULT __stdcall ReportEvent(
- ImporterEventKind EventKind, // Type of event.
- long EventCode, // HR of event.
- BSTR EventMsg) // Text message for event.
- {
- LIMITED_METHOD_CONTRACT;
- return S_OK;
- } // virtual HRESULT __stdcall ReportEvent()
-
- //-------------------------------------------------------------------------
- virtual HRESULT __stdcall ResolveRef(
- IUnknown *Asm,
- IUnknown **pRetVal)
- {
- CONTRACTL
- {
- DISABLED(NOTHROW);
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- SO_TOLERANT;
- PRECONDITION(CheckPointer(Asm));
- PRECONDITION(CheckPointer(pRetVal));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- Assembly *pAssembly=0; // The referenced Assembly.
- ITypeLib *pTLB=0; // The created TypeLib.
- MethodTable *pAssemblyClass = NULL; //@todo -- get this.
- LPVOID RetObj = NULL; // The object to return.
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
- {
- {
- GCX_COOP_THREAD_EXISTS(GET_THREAD());
- // Get the Referenced Assembly from the IUnknown.
- ASSEMBLYREF asmRef = NULL;
- GCPROTECT_BEGIN(asmRef);
- GetObjectRefFromComIP((OBJECTREF*)&asmRef, Asm, pAssemblyClass);
- pAssembly = asmRef->GetAssembly();
- GCPROTECT_END();
- }
-
- // Default resolution provides no notification, flags are 0.
- ExportTypeLibFromLoadedAssembly(pAssembly, 0, &pTLB, 0 /*pINotify*/, 0 /* flags*/);
- }
- END_EXTERNAL_ENTRYPOINT;
-
- *pRetVal = pTLB;
-
- return hr;
- } // virtual HRESULT __stdcall ResolveRef()
-
- //-------------------------------------------------------------------------
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(// S_OK or E_NOINTERFACE
- REFIID riid, // Desired interface.
- void **ppvObject) // Put interface pointer here.
- {
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_PREEMPTIVE;
- SO_TOLERANT;
- PRECONDITION(CheckPointer(ppvObject));
- }
- CONTRACTL_END;
-
- *ppvObject = 0;
- if (riid == IID_IUnknown || riid == IID_ITypeLibExporterNotifySink)
- {
- *ppvObject = this;
- return S_OK;
- }
- return E_NOINTERFACE;
- } // virtual HRESULT QueryInterface()
-
- //-------------------------------------------------------------------------
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- } // virtual ULONG STDMETHODCALLTYPE AddRef()
-
- //-------------------------------------------------------------------------
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- } // virtual ULONG STDMETHODCALLTYPE Release()
-};
-
-static CDefaultNotify g_Notify;
-
-//*****************************************************************************
-// CTOR/DTOR.
-//*****************************************************************************
-TypeLibExporter::TypeLibExporter()
- : m_pICreateTLB(0),
- m_pIUnknown(0),
- m_pIDispatch(0),
- m_pGuid(0),
- m_hIUnknown(-1)
-{
- LIMITED_METHOD_CONTRACT;
-
-#if defined(_DEBUG)
- static int i;
- ++i; // So a breakpoint can be set.
-#endif
-} // TypeLibExporter::TypeLibExporter()
-
-TypeLibExporter::~TypeLibExporter()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- }
- CONTRACTL_END;
-
- ReleaseResources();
-} // TypeLibExporter::~TypeLibExporter()
-
-//*****************************************************************************
-// Get an interface pointer from the ICreateTypeLib interface.
-//*****************************************************************************
-HRESULT TypeLibExporter::GetTypeLib(
- REFGUID iid,
- IUnknown **ppITypeLib)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(ppITypeLib));
- }
- CONTRACTL_END;
-
- return SafeQueryInterface(m_pICreateTLB, iid, (IUnknown**)ppITypeLib);
-} // HRESULT TypeLibExporter::GetTypeLib()
-
-//*****************************************************************************
-// LayOut a TypeLib. Call LayOut on all ICreateTypeInfo2s first.
-//*****************************************************************************
-void TypeLibExporter::LayOut() // S_OK or error.
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK; // A result.
- int cTypes; // Count of exported types.
- int ix; // Loop control.
- CExportedTypesInfo *pData; // For iterating the entries.
-
- cTypes = m_Exports.Count();
-
- // Call LayOut on all ICreateTypeInfo2*s.
- for (ix=0; ix<cTypes; ++ix)
- {
- pData = m_Exports[ix];
- if (pData->pCTI && FAILED(hr = pData->pCTI->LayOut()))
- PostTypeLibError(pData->pCTI, hr, TLBX_E_LAYOUT_ERROR);
- }
-
- for (ix=0; ix<cTypes; ++ix)
- {
- pData = m_Exports[ix];
- if (pData->pCTIClassItf && FAILED(hr = pData->pCTIClassItf->LayOut()))
- PostTypeLibError(pData->pCTIClassItf, hr, TLBX_E_LAYOUT_ERROR);
- }
-
- // Repeat for injected types.
- cTypes = m_InjectedExports.Count();
- for (ix=0; ix<cTypes; ++ix)
- {
- pData = m_InjectedExports[ix];
- if (pData->pCTI && FAILED(hr = pData->pCTI->LayOut()))
- PostTypeLibError(pData->pCTI, hr, TLBX_E_LAYOUT_ERROR);
- }
-
- for (ix=0; ix<cTypes; ++ix)
- {
- pData = m_InjectedExports[ix];
- if (pData->pCTIClassItf && FAILED(hr = pData->pCTIClassItf->LayOut()))
- PostTypeLibError(pData->pCTIClassItf, hr, TLBX_E_LAYOUT_ERROR);
- }
-} // HRESULT TypeLibExporter::LayOut()
-
-//*****************************************************************************
-// Release all pointers.
-//*****************************************************************************
-void TypeLibExporter::ReleaseResources()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // Release the ITypeInfo* pointers.
- m_Exports.Clear();
- m_InjectedExports.Clear();
-
- // Clean up the created TLB.
- SafeRelease(m_pICreateTLB);
- m_pICreateTLB = 0;
-
- // Clean up the ITypeInfo*s for well-known interfaces.
- SafeRelease(m_pIUnknown);
- m_pIUnknown = 0;
-
- SafeRelease(m_pIDispatch);
- m_pIDispatch = 0;
-
- SafeRelease(m_pGuid);
- m_pGuid = 0;
-} // void TypeLibExporter::ReleaseResources()
-
-//*****************************************************************************
-// Enumerate the Types in a Module, add to the list.
-//*****************************************************************************
-void TypeLibExporter::AddModuleTypes(
- Module *pModule) // The module to convert.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pModule));
- }
- CONTRACTL_END;
-
- HRESULT hr;
- ULONG cTD; // Count of typedefs.
- mdTypeDef td; // A TypeDef.
- MethodTable *pClass; // A MethodTable for a TypeDef.
- ULONG ix; // Loop control.
- CExportedTypesInfo *pExported; // For adding classes to the exported types cache.
- CExportedTypesInfo sExported; // For adding classes to the exported types cache.
-
-
- // Convert all the types visible to COM.
- // Get an enumerator on TypeDefs in the scope.
- HENUMInternalHolder eTD(pModule->GetMDImport());
- eTD.EnumTypeDefInit();
- cTD = pModule->GetMDImport()->EnumTypeDefGetCount(&eTD);
-
- // Add all the classes to the hash.
- for (ix=0; ix<cTD; ++ix)
- {
- ZeroHolder zhType = &m_ErrorContext.m_pScope; // Clear error reporting info.
-
- // Get the TypeDef.
- if (!pModule->GetMDImport()->EnumTypeDefNext(&eTD, &td))
- IfFailReport(E_UNEXPECTED);
-
- IMDInternalImport* pInternalImport = pModule->GetMDImport();
-
- // Error reporting info.
- m_ErrorContext.m_tkType = td;
- m_ErrorContext.m_pScope = pModule->GetMDImport();
-
- // Get the class, perform the step.
- pClass = LoadClass(pModule, td);
-
- // Enumerate the formal type parameters
- HENUMInternal hEnumGenericPars;
- hr = pInternalImport->EnumInit(mdtGenericParam, td, &hEnumGenericPars);
- if (SUCCEEDED(hr))
- {
- DWORD numGenericArgs = pInternalImport->EnumGetCount(&hEnumGenericPars);
- // skip generic classes
- if( numGenericArgs > 0 )
- {
- // We'll only warn if the type is marked ComVisible.
- if (SpecialIsGenericTypeVisibleFromCom(TypeHandle(pClass)))
- ReportWarning(TLBX_I_GENERIC_TYPE, TLBX_I_GENERIC_TYPE);
-
- continue;
- }
- }
-
- // If the flag to not ignore non COM visible types in name decoration is set, then
- // add the ComVisible(false) types to our list of exported types by skipping this check.
- if ((m_flags & TlbExporter_OldNames) == 0)
- {
- // If the type isn't visible from COM, don't add it to the list of exports.
- if (!IsTypeVisibleFromCom(TypeHandle(pClass)))
- continue;
- }
-
- // See if this class is already in the list.
- sExported.pClass = pClass;
- pExported = m_Exports.Find(&sExported);
- if (pExported != 0)
- continue;
-
- // New class, add to list.
- pExported = m_Exports.Add(&sExported);
- if (!pExported)
- IfFailReport(E_OUTOFMEMORY);
-
- // Prefix can't tell that IfFailReport will actually throw an exception if pExported is NULL so
- // let's tell it explicitly that if we reach this point pExported will not be NULL.
- PREFIX_ASSUME(pExported != NULL);
- pExported->pClass = pClass;
- pExported->pCTI = 0;
- pExported->pCTIClassItf = 0;
- }
-} // HRESULT TypeLibExporter::AddModuleTypes()
-
-//*****************************************************************************
-// Enumerate the Modules in an assembly, add the types to the list.
-//*****************************************************************************
-void TypeLibExporter::AddAssemblyTypes(
- Assembly *pAssembly) // The assembly to convert.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pAssembly));
- }
- CONTRACTL_END;
-
- Module *pManifestModule; // A module in the assembly.
- mdFile mf; // A file token.
-
- if (pAssembly->GetManifestImport())
- {
- // Enumerator over the modules of the assembly.
- HENUMInternalHolder phEnum(pAssembly->GetManifestImport());
- phEnum.EnumInit(mdtFile, mdTokenNil);
-
- // Get the module for the assembly.
- pManifestModule = pAssembly->GetManifestModule();
- AddModuleTypes(pManifestModule);
-
- while (pAssembly->GetManifestImport()->EnumNext(&phEnum, &mf))
- {
- DomainFile *pDomainFile = pAssembly->GetManifestModule()->LoadModule(GetAppDomain(), mf, FALSE);
-
- if (pDomainFile != NULL && !pDomainFile->GetFile()->IsResource())
- AddModuleTypes(pDomainFile->GetModule());
- }
- }
-} // HRESULT TypeLibExporter::AddAssemblyTypes()
-
-//*****************************************************************************
-// Convert COM+ metadata to a typelib.
-//*****************************************************************************
-void TypeLibExporter::Convert(
- Assembly *pAssembly, // The Assembly to convert
- LPCWSTR szTlbName, // Name of resulting TLB
- ITypeLibExporterNotifySink *pNotify,// Notification callback.
- int flags) // Conversion flags
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pAssembly));
- PRECONDITION(CheckPointer(szTlbName));
- PRECONDITION(CheckPointer(pNotify, NULL_OK));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- ULONG i; // Loop control.
- SString sName; // Library name.
- GUID guid; // Library guid.
- VARIANT vt = {0}; // Variant for ExportedFromComPlus.
- CQuickArray<WCHAR> qLocale; // Wide string for locale.
- LCID lcid; // LCID for typelib, default 0.
-
- // Set PerfCounters
- COUNTER_ONLY(GetPerfCounters().m_Interop.cTLBExports++);
-
- SafeComHolder<IMultiLanguage> pIML=0; // For locale->lcid conversion.
- SafeComHolder<ITypeLib> pITLB=0; // TypeLib for IUnknown, IDispatch.
- BSTRHolder szTIName=0; // Name of a TypeInfo.
- BSTRHolder szDescription=0; // Assembly Description.
-
- // Error reporting information.
- m_ErrorContext.m_szAssembly = pAssembly->GetSimpleName();
-
- m_flags = flags;
-
- // Set the callback.
- m_pNotify = pNotify ? pNotify : &g_Notify;
-
- // If we haven't set 32-bit or 64-bit export yet, set it now with defaults.
- UpdateBitness(pAssembly);
-
- // Check the bitness of the assembly against our output bitness
- IfFailReport(CheckBitness(pAssembly));
-
- // Get some well known TypeInfos.
- GCX_PREEMP();
-
- BSTR wzPath;// = SysAllocStringLen(NULL, _MAX_PATH);
- IfFailReport(QueryPathOfRegTypeLib(LIBID_STDOLE2, -1, -1, 0, &wzPath));
-
- if (IsExportingAs64Bit())
- {
- hr = LoadTypeLibEx(wzPath, (REGKIND)(REGKIND_NONE | LOAD_TLB_AS_64BIT), &pITLB);
- }
- else
- {
- hr = LoadTypeLibEx(wzPath, (REGKIND)(REGKIND_NONE | LOAD_TLB_AS_32BIT), &pITLB);
- }
-
- // If we failed to load StdOle2.tlb, then we're probably on a downlevel platform (< XP)
- // so we'll just load whatever we have...note that at this point, cross-compile is not an option.
- if (FAILED(hr))
- {
- IfFailReport(LoadRegTypeLib(LIBID_STDOLE2, -1, -1, 0, &pITLB));
- }
-
- IfFailReport(pITLB->GetTypeInfoOfGuid(IID_IUnknown, &m_pIUnknown));
- IfFailReport(pITLB->GetTypeInfoOfGuid(IID_IDispatch, &m_pIDispatch));
-
- // Look for GUID (which unfortunately has no GUID).
- for (i=0; i<pITLB->GetTypeInfoCount() && !m_pGuid; ++i)
- {
- IfFailReport(pITLB->GetDocumentation(i, &szTIName, 0, 0, 0));
- if (SString::_wcsicmp(szTIName, szGuidName) == 0)
- IfFailReport(pITLB->GetTypeInfo(i, &m_pGuid));
- }
-
- // Create the output typelib.
-
- // Win2K: passing in too long a filename triggers a nasty buffer overrun bug
- // when the SaveAll() method is called. We'll avoid triggering this here.
- //
- if (wcslen(szTlbName) > MAX_PATH_FNAME)
- IfFailReport(HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE));
-
- // Reverting to old behavior here until we can fix up the vtable offsets as well.
- // Set the SYSKIND based on the 64bit/32bit switches
- if (IsExportingAs64Bit())
- {
- IfFailReport(CreateTypeLib2(SYS_WIN64, szTlbName, &m_pICreateTLB));
- }
- else
- {
- IfFailReport(CreateTypeLib2(SYS_WIN32, szTlbName, &m_pICreateTLB));
- }
-
- // Set the typelib GUID.
- IfFailReport(GetTypeLibGuidForAssembly(pAssembly, &guid));
- IfFailReport(m_pICreateTLB->SetGuid(guid));
-
- // Retrieve the type library's version number.
- USHORT usMaj, usMin;
- IfFailReport(GetTypeLibVersionForAssembly(pAssembly, &usMaj, &usMin));
-
- // Set the TLB's version number.
- IfFailReport(m_pICreateTLB->SetVersion(usMaj, usMin));
-
- // Set the LCID. If no locale, set to 0, otherwise typelib defaults to 409.
- lcid = 0;
- LPCUTF8 pLocale = pAssembly->GetLocale();
- if (pLocale && *pLocale)
- {
- // Have to build a BSTR, not just a unicode string (i.e. allocate a
- // DWORD of length information at a negative offset from the string
- // start).
- _ASSERTE((sizeof(WCHAR) * 2) == sizeof(DWORD));
- hr = qLocale.ReSizeNoThrow(sizeof(DWORD));
- if (SUCCEEDED(hr))
- hr = Utf2Quick(pLocale, qLocale, 2);
- if (SUCCEEDED(hr))
- {
- *(DWORD*)qLocale.Ptr() = (DWORD)wcslen(&qLocale.Ptr()[2]);
- hr = ::CoCreateInstance(CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER, IID_IMultiLanguage, (void**)&pIML);
- }
- if (SUCCEEDED(hr))
- pIML->GetLcidFromRfc1766(&lcid, (BSTR)&qLocale.Ptr()[2]);
- }
- HRESULT hr2 = m_pICreateTLB->SetLcid(lcid);
- if (hr2 == TYPE_E_UNKNOWNLCID)
- {
- ReportWarning(TYPE_E_UNKNOWNLCID, TYPE_E_UNKNOWNLCID);
- hr2 = m_pICreateTLB->SetLcid(0);
- }
- IfFailReport(hr2);
-
- // Get the list of types in the assembly.
- AddAssemblyTypes(pAssembly);
- m_Exports.InitArray();
-
- // Get the assembly value for AutomationProxy.
- m_bAutomationProxy = DEFAULT_AUTOMATION_PROXY_VALUE;
- GetAutomationProxyAttribute(pAssembly->GetManifestImport(), TokenFromRid(1, mdtAssembly), &m_bAutomationProxy);
-
- // Pre load any caller-specified names into the typelib namespace.
- PreLoadNames();
-
- // Convert all the types.
- ConvertAllTypeDefs();
-
- // Set library level properties.
- sName.AppendUTF8(pAssembly->GetSimpleName());
-
- // Make it a legal typelib name.
- SString replaceChar = SL(W("_"));
-
- SString::Iterator iter = sName.Begin();
- while (sName.Find(iter, W(".")))
- sName.Replace(iter, 1, replaceChar);
-
- iter = sName.Begin();
- while (sName.Find(iter, W(" ")))
- sName.Replace(iter, 1, replaceChar);
-
- IfFailReport(m_pICreateTLB->SetName((LPOLESTR)sName.GetUnicode()));
-
- // If the assembly has a description CA, set that as the library Doc string.
- if (GetStringCustomAttribute(pAssembly->GetManifestImport(), XXX_ASSEMBLY_DESCRIPTION_TYPE, TokenFromRid(mdtAssembly, 1), (BSTR &)szDescription))
- m_pICreateTLB->SetDocString((LPWSTR)szDescription);
-
- // Mark this typelib as exported.
- LPCWSTR pszFullName;
- {
- //@todo: exceptions?
- StackSString name;
- pAssembly->GetDisplayName(name);
- pszFullName = name.GetUnicode();
-
- vt.vt = VT_BSTR;
- vt.bstrVal = SysAllocString(pszFullName);
- if (vt.bstrVal == NULL)
- IfFailReport(E_OUTOFMEMORY);
- }
-
- //WszMultiByteToWideChar(CP_ACP,0, (char*)rBuf.Ptr(), (DWORD)rBuf.Size(), vt.bstrVal, (DWORD)rBuf.Size());
- IfFailReport(m_pICreateTLB->SetCustData(GUID_ExportedFromComPlus, &vt));
-
- // Lay out the TypeInfos.
- LayOut();
-
- if(vt.bstrVal)
- {
- SysFreeString(vt.bstrVal);
- vt.bstrVal = NULL;
- }
-
-} // HRESULT TypeLibExporter::Convert()
-
-
-void TypeLibExporter::UpdateBitness(Assembly* pAssembly)
-{
- WRAPPER_NO_CONTRACT;
-
- // If one has already been set, just return.
- if ((TlbExportAs64Bit(m_flags)) || (TlbExportAs32Bit(m_flags)))
- return;
-
- // If we are exporting a dynamic assembly, just go with the machine type we're running on.
- if (pAssembly->IsDynamic())
- {
-#ifdef _WIN64
- m_flags |= TlbExporter_ExportAs64Bit;
-#else
- m_flags |= TlbExporter_ExportAs32Bit;
-#endif
- return;
- }
-
- // Get the assembly info
- PEFile* pPEFile = pAssembly->GetDomainAssembly()->GetFile();
- _ASSERTE(pPEFile);
-
- DWORD PEKind, MachineKind;
- pPEFile->GetPEKindAndMachine(&PEKind, &MachineKind);
-
- // Based on the assembly flags, determine a bitness to export with.
- // Algorithm base copied from ComputeProcArchFlags() in bcl\system\reflection\assembly.cs
- if ((PEKind & pe32Plus) == pe32Plus)
- {
- switch (MachineKind)
- {
- case IMAGE_FILE_MACHINE_IA64:
- case IMAGE_FILE_MACHINE_AMD64:
- m_flags |= TlbExporter_ExportAs64Bit;
- break;
-
- case IMAGE_FILE_MACHINE_I386:
- if ((PEKind & peILonly) == peILonly)
- {
-#ifdef _WIN64
- m_flags |= TlbExporter_ExportAs64Bit;
-#else
- m_flags |= TlbExporter_ExportAs32Bit;
-#endif
- }
- else
- {
- _ASSERTE(!"Invalid MachineKind / PEKind pair on the assembly!");
- }
- break;
-
- default:
- _ASSERTE(!"Unknown MachineKind!");
- }
- }
- else if (MachineKind == IMAGE_FILE_MACHINE_I386)
- {
- if ((PEKind & pe32BitRequired) == pe32BitRequired)
- {
- m_flags |= TlbExporter_ExportAs32Bit;
- }
- else if ((PEKind & peILonly) == peILonly)
- {
-#ifdef _WIN64
- m_flags |= TlbExporter_ExportAs64Bit;
-#else
- m_flags |= TlbExporter_ExportAs32Bit;
-#endif
- }
- else
- {
- m_flags |= TlbExporter_ExportAs32Bit;
- }
- }
- else if (MachineKind == IMAGE_FILE_MACHINE_ARMNT)
- {
- m_flags |= TlbExporter_ExportAs32Bit;
- }
- else
- {
-#ifdef _WIN64
- m_flags |= TlbExporter_ExportAs64Bit;
-#else
- m_flags |= TlbExporter_ExportAs32Bit;
-#endif
- }
-}
-
-
-// Find out if our assembly / bitness combination is valid.
-HRESULT TypeLibExporter::CheckBitness(Assembly* pAssembly)
-{
- WRAPPER_NO_CONTRACT;
-
- if (pAssembly->IsDynamic())
- return S_OK;
-
- PEFile* pPEFile = pAssembly->GetDomainAssembly()->GetFile();
- if (pPEFile == NULL)
- return TLBX_E_BITNESS_MISMATCH;
-
- DWORD PEKind, MachineKind;
- pPEFile->GetPEKindAndMachine(&PEKind, &MachineKind);
-
- // Neutral assembly?
- if ((PEKind & peILonly) == peILonly)
- return S_OK;
-
- if (IsExportingAs64Bit())
- {
- if ((MachineKind == IMAGE_FILE_MACHINE_IA64) || (MachineKind == IMAGE_FILE_MACHINE_AMD64))
- return S_OK;
- }
- else
- {
- if ((MachineKind == IMAGE_FILE_MACHINE_I386) || (MachineKind == IMAGE_FILE_MACHINE_ARMNT))
- return S_OK;
- }
-
- return TLBX_E_BITNESS_MISMATCH;
-}
-
-
-//*****************************************************************************
-//*****************************************************************************
-void TypeLibExporter::PreLoadNames()
-{
- STANDARD_VM_CONTRACT;
-
- SafeComHolder<ITypeLibExporterNameProvider> pINames = 0;
- HRESULT hr = S_OK; // A result.
- SafeArrayHolder pNames = 0; // Names provided by caller.
- VARTYPE vt; // Type of data.
- int lBound, uBound, ix; // Loop control.
- BSTR name;
-
- // Look for names provider, but don't require it.
- hr = SafeQueryInterface(m_pNotify, IID_ITypeLibExporterNameProvider, (IUnknown**)&pINames);
- if (FAILED(hr))
- return;
-
- // There is a provider, so get the list of names.
- IfFailReport(pINames->GetNames(&pNames));
-
- // Better have a single dimension array of strings.
- if (pNames == 0)
- IfFailReport(TLBX_E_BAD_NAMES);
-
- if (SafeArrayGetDim(pNames) != 1)
- IfFailReport(TLBX_E_BAD_NAMES);
-
- IfFailReport(SafeArrayGetVartype(pNames, &vt));
- if (vt != VT_BSTR)
- IfFailReport(TLBX_E_BAD_NAMES);
-
- // Get names bounds.
- IfFailReport(SafeArrayGetLBound(pNames, 1, (LONG*)&lBound));
- IfFailReport(SafeArrayGetUBound(pNames, 1, (LONG*)&uBound));
-
- // Enumerate the names.
- for (ix=lBound; ix<=uBound; ++ix)
- {
- IfFailReport(SafeArrayGetElement(pNames, (LONG*)&ix, (void*)&name));
- m_pICreateTLB->SetName(name);
- }
-}
-
-//*****************************************************************************
-//*****************************************************************************
-void TypeLibExporter::FormatErrorContextString(
- CErrorContext *pContext, // The context to format.
- SString *pOut) // Buffer to format into.
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pContext));
- PRECONDITION(CheckPointer(pOut));
- }
- CONTRACTL_END;
-
- HRESULT hr;
- SString *pBuf;
- SString ssInternal;
-
- // Nested contexts?
- if (pContext->m_prev == 0)
- { // No, just convert into caller's buffer.
- pBuf = pOut;
- }
- else
- { // Yes, convert locally, then concatenate.
- pBuf = &ssInternal;
- }
-
- // More?
- if (pContext->m_pScope)
- {
- // Check whether type is nested (which requires more formatting).
- DWORD dwFlags;
- IfFailReport(pContext->m_pScope->GetTypeDefProps(pContext->m_tkType, &dwFlags, 0));
-
- if (IsTdNested(dwFlags))
- {
- TypeNameBuilder tnb(pBuf, TypeNameBuilder::ParseStateNAME);
- TypeString::AppendNestedTypeDef(tnb, pContext->m_pScope, pContext->m_tkType);
- }
- else
- TypeString::AppendTypeDef(*pBuf, pContext->m_pScope, pContext->m_tkType);
-
- // Member?
- if (pContext->m_szMember)
- {
- pBuf->Append(NAMESPACE_SEPARATOR_WSTR);
-
- pBuf->AppendUTF8(pContext->m_szMember);
-
- // Param?
- if (pContext->m_szParam)
- {
- pBuf->Append(W("("));
- pBuf->AppendUTF8(pContext->m_szParam);
- pBuf->Append(W(")"));
- }
- else if (pContext->m_ixParam > -1)
- {
- pBuf->AppendPrintf(W("(#%d)"), pContext->m_ixParam);
- }
- } // member
-
- pBuf->Append(ASSEMBLY_SEPARATOR_WSTR);
- } // Type name
-
- pBuf->AppendUTF8(pContext->m_szAssembly);
-
- // If there is a nested context, put it all together.
- if (pContext->m_prev)
- {
- // Format the context this one was nested inside.
- SString ssOuter;
- FormatErrorContextString(pContext->m_prev, &ssOuter);
-
- // Put them together with text.
- LPWSTR pUnicodeBuffer = pOut->OpenUnicodeBuffer(1024);
- FormatRuntimeError(pUnicodeBuffer, 1024, TLBX_E_CTX_NESTED, pBuf->GetUnicode(), ssOuter.GetUnicode());
- pOut->CloseBuffer((COUNT_T)wcslen(pUnicodeBuffer));
- }
-} // HRESULT TypeLibExporter::FormatErrorContextString()
-
-//*****************************************************************************
-//*****************************************************************************
-void TypeLibExporter::FormatErrorContextString(
- SString *pBuf) // Buffer to format into.
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pBuf));
- }
- CONTRACTL_END;
-
- FormatErrorContextString(&m_ErrorContext, pBuf);
-} // HRESULT TypeLibExporter::FormatErrorContextString()
-
-//*****************************************************************************
-// Event reporting helper.
-//*****************************************************************************
-void TypeLibExporter::ReportError(HRESULT hrRpt)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- WCHAR rcErr[1024];
- SString ssName;
- SafeComHolder<IErrorInfo> pErrorInfo;
- BSTRHolder bstrDescription = NULL;
-
- // Format the error message.
- if (SafeGetErrorInfo(&pErrorInfo) != S_OK)
- pErrorInfo = NULL;
-
- // If we retrieved and IErrorInfo then retrieve the description.
- if (pErrorInfo)
- {
- if (FAILED(pErrorInfo->GetDescription(&bstrDescription)))
- bstrDescription = NULL;
- }
-
- if (bstrDescription)
- {
- // Use the description as the error message.
- wcsncpy_s(rcErr, COUNTOF(rcErr), bstrDescription, _TRUNCATE);
- }
- else
- {
- // Format the error message.
- FormatRuntimeError(rcErr, lengthof(rcErr), hrRpt);
- }
-
- // Format the context.
- FormatErrorContextString(&ssName);
-
- // Post the error to the errorinfo object.
- VMPostError(TLBX_E_ERROR_MESSAGE, ssName.GetUnicode(), rcErr);
-
- // Throw the exception, including context info.
- COMPlusThrowHR(TLBX_E_ERROR_MESSAGE, kGetErrorInfo);
-} // void TypeLibExporter::ReportError()
-
-//*****************************************************************************
-// Event reporting helper.
-//*****************************************************************************
-void TypeLibExporter::ReportEvent( // Returns the original HR.
- int ev, // The event kind.
- int hr, // HR.
- ...) // Variable args.
-{
- STANDARD_VM_CONTRACT;
-
- WCHAR rcMsg[1024]; // Buffer for message.
- va_list marker; // User text.
- BSTRHolder bstrMsg=0; // BSTR for message.
-
- // Format the message.
- va_start(marker, hr);
- hr = FormatRuntimeErrorVa(rcMsg, lengthof(rcMsg), hr, marker);
- va_end(marker);
-
- // Convert to a BSTR.
- bstrMsg = SysAllocString(rcMsg);
-
- // Display it, and clean up.
- if (bstrMsg != NULL)
- m_pNotify->ReportEvent(static_cast<ImporterEventKind>(ev), hr, bstrMsg);
-
-} // HRESULT CImportTlb::ReportEvent()
-
-//*****************************************************************************
-// Warning reporting helper.
-//*****************************************************************************
-void TypeLibExporter::ReportWarning( // Original error code.
- HRESULT hrReturn, // HR to return.
- HRESULT hrRpt, // Error code.
- ...) // Args to message.
-{
- STANDARD_VM_CONTRACT;
-
- WCHAR rcErr[1024]; // Buffer for error message.
- SString ssName; // Buffer for context.
- va_list marker; // User text.
- BSTRHolder bstrMsg=0; // BSTR for message.
- BSTRHolder bstrBuf=0; // Buffer for message.
- UINT iLen; // Length of allocated buffer.
-
- // Format the message.
- va_start(marker, hrRpt);
- FormatRuntimeErrorVa(rcErr, lengthof(rcErr), hrRpt, marker);
- va_end(marker);
-
- // Format the context.
- FormatErrorContextString(&ssName);
-
- // Put them together.
- iLen = (UINT)(wcslen(rcErr) + ssName.GetCount() + 200);
- bstrBuf = SysAllocStringLen(0, iLen);
-
- if (bstrBuf != NULL)
- {
- FormatRuntimeError(bstrBuf, iLen, TLBX_W_WARNING_MESSAGE, ssName.GetUnicode(), rcErr);
-
- // Have to copy to another BSTR, because the runtime will also print the trash after the
- // terminating nul.
- bstrMsg = SysAllocString(bstrBuf);
-
- if (bstrMsg != NULL)
- m_pNotify->ReportEvent(NOTIF_CONVERTWARNING, hrRpt, bstrMsg);
- }
-
-} // void TypeLibExporter::ReportWarning()
-
-// Throws exceptions encountered during type exportation.
-// Wrapped with ThrowHRWithContext.
-void TypeLibExporter::InternalThrowHRWithContext(HRESULT hrRpt, ...)
-{
- STANDARD_VM_CONTRACT;
-
- WCHAR rcErr[2048];
- SString ssName;
- va_list marker;
-
- // Format the error message.
- va_start(marker, hrRpt);
- FormatRuntimeErrorVa(rcErr, lengthof(rcErr), hrRpt, marker);
- va_end(marker);
-
- // Format the context.
- FormatErrorContextString(&ssName);
-
- // Post the error to the errorinfo object.
- VMPostError(TLBX_E_ERROR_MESSAGE, ssName.GetUnicode(), rcErr);
-
- // Throw the exception, including context info.
- COMPlusThrowHR(TLBX_E_ERROR_MESSAGE, kGetErrorInfo);
-} // void TypeLibExporter::InternalThrowHRWithContext()
-
-//*****************************************************************************
-// Post a class load error on failure.
-//*****************************************************************************
-void TypeLibExporter::PostClassLoadError(
- LPCUTF8 pszName, // Name of the class.
- SString& message) // Exception message of class load failure.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pszName));
- }
- CONTRACTL_END;
-
- // See if we got anything back.
- if (!message.IsEmpty())
- InternalThrowHRWithContext(TLBX_E_CLASS_LOAD_EXCEPTION, pszName, message.GetUnicode());
- else
- InternalThrowHRWithContext(TLBX_E_CANT_LOAD_CLASS, pszName);
-} // HRESULT TypeLibExporter::PostClassLoadError()
-
-//*****************************************************************************
-// Determine the type, if any, of auto-interface for a class.
-// May be none, dispatch, or dual.
-//*****************************************************************************
-void TypeLibExporter::ClassHasIClassX(
- MethodTable *pClass, // The class.
- CorClassIfaceAttr *pClassItfType) // None, dual, dispatch
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pClass));
- PRECONDITION(!pClass->IsInterface());
- PRECONDITION(CheckPointer(pClassItfType));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- ComMethodTable *pClassComMT = NULL;
-
- *pClassItfType = clsIfNone;
-
- // If the class is a COM import or if it isn't COM visible, then from the
- // exporter's perspective, it doens't have an IClassX.
- if (!pClass->IsComImport())
- {
- ComCallWrapperTemplate *pTemplate = ComCallWrapperTemplate::GetTemplate(pClass);
- if (pTemplate->SupportsIClassX())
- {
- pClassComMT = ComCallWrapperTemplate::SetupComMethodTableForClass(pClass, FALSE);
- _ASSERTE(pClassComMT);
-
- if (pClassComMT->IsComVisible())
- *pClassItfType = pClassComMT->GetClassInterfaceType();
- }
- }
-} // HRESULT TypeLibExporter::ClassHasIClassX()
-
-//*****************************************************************************
-// Load a class by token, post an error on failure.
-//*****************************************************************************
-MethodTable * TypeLibExporter::LoadClass(
- Module *pModule, // Module with Loader to use to load the class.
- mdToken tk) // The token to load.
-{
- CONTRACT(MethodTable *)
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pModule));
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- // Get the MethodTable for the token.
- TypeHandle th;
- SString exceptionMessage;
-
- EX_TRY
- {
- th = ClassLoader::LoadTypeDefOrRefThrowing(pModule, tk,
- ClassLoader::ThrowIfNotFound,
- ClassLoader::PermitUninstDefOrRef);
- }
- EX_CATCH
- {
- GET_EXCEPTION()->GetMessage(exceptionMessage);
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- if (th.IsNull())
- {
- // Format a hopefully useful error message.
- LPCUTF8 pNS, pName;
- SString sName;
-
- if (TypeFromToken(tk) == mdtTypeDef)
- {
- if (FAILED(pModule->GetMDImport()->GetNameOfTypeDef(tk, &pName, &pNS)))
- {
- pName = pNS = "Invalid TypeDef record";
- }
- }
- else
- {
- _ASSERTE(TypeFromToken(tk) == mdtTypeRef);
- if (FAILED(pModule->GetMDImport()->GetNameOfTypeRef(tk, &pNS, &pName)))
- {
- pNS = pName = "Invalid TypeRef record";
- }
- }
-
- if (pNS && *pNS)
- {
- sName.AppendUTF8(pNS);
- sName.AppendUTF8(NAMESPACE_SEPARATOR_STR);
- }
-
- sName.AppendUTF8(pName);
-
- StackScratchBuffer scratch;
- PostClassLoadError(sName.GetUTF8(scratch), exceptionMessage);
- }
-
- RETURN (th.AsMethodTable());
-
-} // void TypeLibExporter::LoadClass()
-
-//*****************************************************************************
-// Load a class by name, post an error on failure.
-//*****************************************************************************
-TypeHandle TypeLibExporter::LoadClass(
- Module *pModule, // Module with Loader to use to load the class.
- LPCUTF8 pszName) // Name of class to load.
-{
- CONTRACT(TypeHandle)
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pModule));
- PRECONDITION(CheckPointer(pszName));
- POSTCONDITION(!RETVAL.IsNull());
- }
- CONTRACT_END;
-
- TypeHandle th;
- SString exceptionMessage;
-
- EX_TRY
- {
- th = TypeName::GetTypeUsingCASearchRules(pszName, pModule->GetAssembly());
- _ASSERTE(!th.IsNull());
- }
- EX_CATCH
- {
- GET_EXCEPTION()->GetMessage(exceptionMessage);
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- if (th.IsNull())
- {
- PostClassLoadError(pszName, exceptionMessage);
- }
-
- RETURN th;
-
-} // void TypeLibExporter::LoadClass()
-
-
-//*****************************************************************************
-// Enumerate the TypeDefs and convert them to TypeInfos.
-//*****************************************************************************
-void TypeLibExporter::ConvertAllTypeDefs()
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK; // A result.
- CExportedTypesInfo *pData; // For iterating the entries.
- int cTypes; // Count of types.
- int ix; // Loop control.
-
- LPCSTR pName1, pNS1; // Names of a type.
- LPCSTR pName2, pNS2; // Names of another type.
- MethodTable *pc1; // A Type.
- MethodTable *pc2; // Another type.
- CQuickArray<BYTE> bNamespace; // Array of flags for namespace decoration.
-
- cTypes = m_Exports.Count();
-
- // If there are no types in the assembly, then we are done.
- if (cTypes <= 0)
- return;
-
- // Order by name, then look for duplicates.
- m_Exports.SortByName();
-
- // Resize the array for namespace flags now, but use the ICreateTypeInfo*, so that
- // the flags will be sorted.
- bNamespace.ReSizeThrows(cTypes);
-
- // Get names of first type.
- pc1 = m_Exports[0]->pClass;
- IfFailReport(pc1->GetMDImport()->GetNameOfTypeDef(pc1->GetCl(), &pName1, &pNS1));
-
- // Iterate through the types, looking for duplicate type names.
- for (ix=0; ix<cTypes-1; ++ix)
- {
- // Get the Type pointers and the types' names.
- pc2 = m_Exports[ix+1]->pClass;
- IfFailReport(pc2->GetMDImport()->GetNameOfTypeDef(pc2->GetCl(), &pName2, &pNS2));
-
- // If the types match (case insensitive). mark both types for namespace
- // decoration.
- if (stricmpUTF8(pName1, pName2) == 0)
- {
- m_Exports[ix]->pCTI = reinterpret_cast<ICreateTypeInfo2*>(1);
- m_Exports[ix+1]->pCTI = reinterpret_cast<ICreateTypeInfo2*>(1);
- }
- else
- { // Didn't match, so advance "class 1" pointer.
- pc1 = pc2;
- pName1 = pName2;
- pNS1 = pNS2;
- }
- }
-
- // Put into token order for actual creation.
- m_Exports.SortByToken();
-
- // Fill the flag array, from the ICreateTypeInfo* pointers.
- memset(bNamespace.Ptr(), 0, bNamespace.Size()*sizeof(BYTE));
- for (ix=0; ix<cTypes; ++ix)
- {
- if (m_Exports[ix]->pCTI)
- bNamespace[ix] = 1, m_Exports[ix]->pCTI = 0;
- }
-
- // Pass 1. Create the TypeInfos.
- // There are four steps in the process:
- // a) Creates the TypeInfos for the types themselves. When a duplicate
- // is encountered, skip the type until later, so that we don't create
- // a decorated name that will conflict with a subsequent non-decorated
- // name. We want to preserve a type's given name as much as possible.
- // b) Create the TypeInfos for the types that were duplicates in step a.
- // Perform decoration of the names as necessary to eliminate duplicates.
- // c) Create the TypeInfos for the IClassXs. When there is a duplicate,
- // skip, as in step a.
- // d) Create the remaining TypeInfos for IClassXs. Perform decoration of
- // the names as necessary to eliminate duplicates.
-
- // Step a, Create the TypeInfos for the TypeDefs, no decoration.
- for (ix=0; ix<cTypes; ++ix)
- {
- int bAutoProxy = m_bAutomationProxy;
- pData = m_Exports[ix];
- pData->tkind = TKindFromClass(pData->pClass);
- GetAutomationProxyAttribute(pData->pClass->GetMDImport(), pData->pClass->GetCl(), &bAutoProxy);
- pData->bAutoProxy = (bAutoProxy != 0);
-
- CreateITypeInfo(pData, (bNamespace[ix]!=0), false);
- }
- // Step b, Create the TypeInfos for the TypeDefs, decoration as needed.
- for (ix=0; ix<cTypes; ++ix)
- {
- pData = m_Exports[ix];
- if (pData->pCTI == 0)
- CreateITypeInfo(pData, (bNamespace[ix]!=0), true);
- }
-
- // Step c, Create the TypeInfos for the IClassX interfaces. No decoration.
- for (ix=0; ix<cTypes; ++ix)
- {
- pData = m_Exports[ix];
- CreateIClassXITypeInfo(pData, (bNamespace[ix]!=0), false);
- }
- // Step d, Create the TypeInfos for the IClassX interfaces. Decoration as required.
- for (ix=0; ix<cTypes; ++ix)
- {
- pData = m_Exports[ix];
- if (pData->pCTIClassItf == 0)
- CreateIClassXITypeInfo(pData, (bNamespace[ix]!=0), true);
- }
-
- // Pass 2, add the ImplTypes to the CoClasses.
- for (ix=0; ix<cTypes; ++ix)
- {
- pData = m_Exports[ix];
- ConvertImplTypes(pData);
- }
-
- // Pass 3, fill in the TypeInfo details...
- for (ix=0; ix<cTypes; ++ix)
- {
- pData = m_Exports[ix];
- ConvertDetails(pData);
- }
-
- hr = S_OK;
-} // void TypeLibExporter::ConvertAllTypeDefs()
-
-//*****************************************************************************
-// Convert one TypeDef. Useful for one-off TypeDefs in other scopes where
-// that other scope's typelib doesn't contain a TypeInfo. This happens
-// for the event information with imported typelibs.
-//*****************************************************************************
-HRESULT TypeLibExporter::ConvertOneTypeDef(
- MethodTable *pClass) // The one class to convert.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pClass));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- ICreateTypeInfo2 *pCTI=0; // The TypeInfo to create.
- ICreateTypeInfo2 *pDefault=0; // A possible IClassX TypeInfo.
- CErrorContext SavedContext; // Previous error context.
- CExportedTypesInfo *pExported; // For adding classes to the exported types cache.
- CExportedTypesInfo sExported; // For adding classes to the exported types cache.
-
- // Save error reporting context.
- SavedContext = m_ErrorContext;
- m_ErrorContext.m_szAssembly = pClass->GetAssembly()->GetSimpleName();
- m_ErrorContext.m_tkType = mdTypeDefNil;
- m_ErrorContext.m_pScope = 0;
- m_ErrorContext.m_szMember = 0;
- m_ErrorContext.m_szParam = 0;
- m_ErrorContext.m_ixParam = -1;
- m_ErrorContext.m_prev = &SavedContext;
-
- // See if this class is already in the list.
- sExported.pClass = pClass;
- pExported = m_InjectedExports.Find(&sExported);
- if (pExported == 0)
- {
- // Get the AutoProxy value for an isolated class.
- int bAutoProxy = DEFAULT_AUTOMATION_PROXY_VALUE;
- if (FALSE == GetAutomationProxyAttribute(pClass->GetMDImport(), pClass->GetCl(), &bAutoProxy))
- GetAutomationProxyAttribute(pClass->GetAssembly()->GetManifestImport(), TokenFromRid(1, mdtAssembly), &bAutoProxy);
-
- // New class, add to list.
- if (NULL == (pExported = m_InjectedExports.Add(&sExported)))
- IfFailReport(E_OUTOFMEMORY);
- m_InjectedExports.UpdateArray();
-
- // Prefix can't tell that IfFailReport will actually throw an exception if pExported is NULL so
- // let's tell it explicitly that if we reach this point pExported will not be NULL.
- PREFIX_ASSUME(pExported != NULL);
- pExported->pClass = pClass;
- pExported->pCTI = 0;
- pExported->pCTIClassItf = 0;
- pExported->tkind = TKindFromClass(pClass);
- pExported->bAutoProxy = (bAutoProxy != 0);
-
- // Step 1, Create the TypeInfos for the TypeDefs.
- CreateITypeInfo(pExported);
-
- // Step 1a, Create the TypeInfos for the IClassX interfaces.
- CreateIClassXITypeInfo(pExported);
-
- // Step 2, add the ImplTypes to the CoClasses.
- ConvertImplTypes(pExported);
-
- // Step 3, fill in the TypeInfo details...
- ConvertDetails(pExported);
- }
-
- // Restore error reporting context.
- m_ErrorContext = SavedContext;
-
- return (hr);
-} // HRESULT TypeLibExporter::ConvertOneTypeDef()
-
-
-//*****************************************************************************
-// Create the ITypeInfo for a type. Well, sort of. This function will create
-// the first of possibly two typeinfos for the type. If the type is a class
-// we will create a COCLASS typeinfo now, and an INTERFACE typeinfo later,
-// which typeinfo will be the default interface for the coclass. If this
-// typeinfo needs to be aliased, we will create the ALIAS now (with the
-// real name) and the aliased typeinfo later, with the real attributes, but
-// with a mangled name.
-//*****************************************************************************
-void TypeLibExporter::CreateITypeInfo(
- CExportedTypesInfo *pData, // Conversion data.
- bool bNamespace, // If true, use namespace + name
- bool bResolveDup) // If true, decorate name to resolve dups.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pData));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- LPCUTF8 pName; // Name in UTF8.
- LPCUTF8 pNS; // Namespace in UTF8.
- SString sName; // Name of the TypeDef.
- TYPEKIND tkind; // The TYPEKIND of a TypeDef.
- GUID clsid; // A TypeDef's clsid.
- DWORD dwFlags; // A TypeDef's flags.
- int iSuffix = 0; // Counter for suffix.
- mdTypeDef td; // Token for the class.
-
- VariantHolder vt; // For defining custom attribute.
- SafeComHolder<ICreateTypeInfo> pCTITemp=0; // For creating a typeinfo.
- SafeComHolder<ICreateTypeInfo2> pCTI2=0; // For creating the typeinfo.
- SafeComHolder<ITypeLib> pITLB=0; // For dup IID reporting.
- SafeComHolder<ITypeInfo> pITIDup=0; // For dup IID reporting.
- BSTRHolder bstrDup=0; // For dup IID reporting.
- BSTRHolder bstrDescr=0; // For description.
- ZeroHolder zhType = &m_ErrorContext.m_pScope; // Clear error reporting info.
- CorClassIfaceAttr classItfType = clsIfNone; // For class interface type.
- TypeHandle thClass = TypeHandle(pData->pClass); // TypeHandle representing the class.
-
- DefineFullyQualifiedNameForClassW();
-
- // Get the TypeDef and some info about it.
- td = pData->pClass->GetCl();
- IfFailReport(pData->pClass->GetMDImport()->GetTypeDefProps(td, &dwFlags, 0));
- tkind = pData->tkind;
-
- // Error reporting info.
- m_ErrorContext.m_tkType = td;
- m_ErrorContext.m_pScope = pData->pClass->GetMDImport();
-
- pData->pCTI = 0;
- pData->pCTIClassItf = 0;
-
- // If it is ComImport or WindowsRuntimeImport, do not export it.
- if (IsTdImport(dwFlags) || pData->pClass->IsProjectedFromWinRT())
- return;
-
- // Check to see if the type is supposed to be visible from COM. If it
- // is not then we go to the next type.
- if (!IsTypeVisibleFromCom(TypeHandle(pData->pClass)))
- return;
-
- // Get the GUID for the class. Will generate from name if no defined GUID,
- // will also use signatures if interface.
- pData->pClass->GetGuid(&clsid, TRUE);
-
- // Get the name.
- IfFailReport(pData->pClass->GetMDImport()->GetNameOfTypeDef(td, &pName, &pNS));
-
- // Warn about exporting AutoLayout valueclasses
- if ( (pData->pClass->IsValueType()) && (!pData->pClass->IsEnum()) && (IsTdAutoLayout(pData->pClass->GetAttrClass())))
- ReportWarning(TLBX_W_EXPORTING_AUTO_LAYOUT, TLBX_W_EXPORTING_AUTO_LAYOUT, pName);
-
- // Warn about exporting generic classes.
- if (pData->pClass->GetNumGenericArgs() != 0)
- ReportWarning(TLBX_I_GENERIC_TYPE, TLBX_I_GENERIC_TYPE);
-
- // Classes that derive from generic classes can be COM visible, however we don't
- // expose a class interface for them. Give a warning to the user about this.
- if (pData->pClass->HasGenericClassInstantiationInHierarchy())
- {
- if (!pData->pClass->IsComImport() && IsTypeVisibleFromCom(thClass))
- {
- // Note that we can't call ClassHasIClassX here since it would return
- // classIfNone if the type has generic parents in it's hierarchy.
- if (ReadClassInterfaceTypeCustomAttribute(thClass) != clsIfNone)
- ReportWarning(TLBX_I_GENERIC_BASE_TYPE, TLBX_I_GENERIC_BASE_TYPE);
- }
- }
-
- // Warn about exporting reference types as structs.
- if ((pData->tkind == TKIND_RECORD || pData->tkind == TKIND_UNION) && !pData->pClass->IsValueType())
- ReportWarning(TLBX_I_REF_TYPE_AS_STRUCT, TLBX_I_REF_TYPE_AS_STRUCT);
-
- // workaround for microsoft.wfc.interop.dll -- skip their IDispatch.
- if (clsid == IID_IDispatch || clsid == IID_IUnknown)
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_S_NOSTDINTERFACE, pName);
- return;
- }
-
- if (bNamespace)
- {
- sName.MakeFullNamespacePath(SString(SString::Utf8, pNS), SString(SString::Utf8, pName));
-
- SString replaceChar = SL(W("_"));
-
- SString::Iterator iter = sName.Begin();
- while (sName.Find(iter, W(".")))
- sName.Replace(iter, 1, replaceChar);
- }
- else
- { // Convert name to wide chars.
- sName.AppendUTF8(pName);
- }
-
- // Create the typeinfo for this typedef.
- for (;;)
- {
- // Attempt to create the TypeDef.
- hr = m_pICreateTLB->CreateTypeInfo((LPOLESTR)sName.GetUnicode(), tkind, &pCTITemp);
-
- // If a name conflict, decorate, otherwise, done.
- if (hr != TYPE_E_NAMECONFLICT)
- break;
-
- if (!bResolveDup)
- {
- hr = S_FALSE;
- return;
- }
-
- if (iSuffix == 0)
- {
- iSuffix = 2;
- }
- else
- {
- sName.Delete(sName.End()-=2, 2);
- }
-
- SString sDup;
- sDup.Printf(szDuplicateDecoration, iSuffix++);
-
- sName.Append(sDup);
- }
-
- IfFailReport(hr);
- IfFailReport(SafeQueryInterface(pCTITemp, IID_ICreateTypeInfo2, (IUnknown**)&pCTI2));
-
- // Set the guid.
- _ASSERTE(clsid != GUID_NULL);
- hr = pCTI2->SetGuid(clsid);
- if (FAILED(hr))
- {
- if (hr == TYPE_E_DUPLICATEID)
- {
- IfFailReport(SafeQueryInterface(m_pICreateTLB, IID_ITypeLib, (IUnknown**)&pITLB));
- IfFailReport(pITLB->GetTypeInfoOfGuid(clsid, &pITIDup));
- IfFailReport(pITIDup->GetDocumentation(MEMBERID_NIL, &bstrDup, 0,0,0));
- InternalThrowHRWithContext(TLBX_E_DUPLICATE_IID, sName.GetUnicode(), (BSTR)bstrDup);
- }
- return;
- }
- TRACE("TypeInfo %x: %ls, {%08x-%04x-%04x-%04x-%02x%02x%02x%02x}\n", pCTI2, sName,
- clsid.Data1, clsid.Data2, clsid.Data3, clsid.Data4[0]<<8|clsid.Data4[1], clsid.Data4[2], clsid.Data4[3], clsid.Data4[4], clsid.Data4[5]);
-
- IfFailReport(pCTI2->SetVersion(1, 0));
-
- // Record the fully qualified type name in a custom attribute.
- // If the TypelibImportClassAttribute exists, use that instead.
- SString sName2;
- hr = GetTypeLibImportClassName(pData->pClass, sName2);
- if (hr == S_OK)
- {
- V_BSTR(&vt) = ::SysAllocString(sName2.GetUnicode());
- if (V_BSTR(&vt) == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- V_VT(&vt) = VT_BSTR;
- }
- else
- {
- // Default to the real name.
- LPCWSTR pszName = GetFullyQualifiedNameForClassNestedAwareW(pData->pClass);
-
- V_BSTR(&vt) = ::SysAllocString(pszName);
- if (V_BSTR(&vt) == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- V_VT(&vt) = VT_BSTR;
- }
-
- IfFailReport(pCTI2->SetCustData(GUID_ManagedName, &vt));
-
- // If the class is decorated with a description, apply it to the typelib.
- if (GetDescriptionString(pData->pClass, td, (BSTR &)bstrDescr))
- IfFailReport(pCTI2->SetDocString(bstrDescr));
-
- // Transfer ownership of the pointer.
- pData->pCTI = pCTI2;
- pCTI2.SuppressRelease();
- pCTI2 = 0;
-} // void TypeLibExporter::CreateITypeInfo()
-
-HRESULT TypeLibExporter::GetTypeLibImportClassName(
- MethodTable*pClass,
- SString& szName)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
- _ASSERTE(NULL != pClass);
-
- HRESULT hr = S_OK;
-
- // Check for the presence of the TypelibImportClassAttribute.
- const char* pvData; // Pointer to a custom attribute data.
- ULONG cbData; // Size of custom attribute data.
-
- hr = pClass->GetMDImport()->GetCustomAttributeByName(pClass->GetCl(),
- INTEROP_TYPELIBIMPORTCLASS_TYPE,
- reinterpret_cast<const void**>(&pvData),
- &cbData);
-
- if (hr == S_OK && cbData > 5 && pvData[0] == 1 && pvData[1] == 0)
- {
- CustomAttributeParser cap(pvData, cbData);
- VERIFY(SUCCEEDED(cap.ValidateProlog())); // Validated above, just ensure consistency.
-
- LPCUTF8 szString;
- ULONG cbString;
- if (SUCCEEDED(cap.GetNonNullString(&szString, &cbString)))
- {
- // Set the string and null terminate it.
- szName.SetUTF8(szString, cbString);
- szName.AppendASCII("\0");
-
- // We successfully retrieved the string.
- return S_OK;
- }
- }
-
- return S_FALSE;
-}
-
-
-
-//*****************************************************************************
-// See if an object has a Description, and get it as a BSTR.
-//*****************************************************************************
-BOOL TypeLibExporter::GetDescriptionString(
- MethodTable *pClass, // Class containing the token.
- mdToken tk, // Token of the object.
- BSTR &bstrDescr) // Put description here.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pClass));
- }
- CONTRACTL_END;
-
- // Check for a description custom attribute.
- return GetStringCustomAttribute(pClass->GetMDImport(), XXX_DESCRIPTION_TYPE, tk, bstrDescr);
-
-} // HRESULT TypeLibExporter::GetDescriptionString()
-
-//*****************************************************************************
-// See if an object has a custom attribute, and get it as a BSTR.
-//*****************************************************************************
-BOOL TypeLibExporter::GetStringCustomAttribute(
- IMDInternalImport *pImport,
- LPCSTR szName,
- mdToken tk,
- BSTR &bstrDescr)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pImport));
- PRECONDITION(CheckPointer(szName));
- }
- CONTRACTL_END;
-
- HRESULT hr; // A result.
- const void *pvData; // Pointer to a custom attribute data.
- ULONG cbData; // Size of custom attribute data.
-
- // Look for the desired custom attribute.
- IfFailReport(pImport->GetCustomAttributeByName(tk, szName, &pvData,&cbData));
- if (hr == S_OK && cbData > 2)
- {
- CustomAttributeParser cap(pvData, cbData);
- IfFailReport(cap.SkipProlog());
-
- LPCUTF8 szString;
- ULONG cbString;
- IfFailReport(cap.GetString(&szString, &cbString));
-
- bstrDescr = SysAllocStringLen(0, cbString); // allocates cbString+1 characters (appends '\0')
- if (bstrDescr == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- if (cbString > 0)
- {
- ULONG cch = WszMultiByteToWideChar(CP_UTF8, 0, szString, cbString, bstrDescr, cbString);
- bstrDescr[cch] = W('\0');
- }
-
- return TRUE;
- }
-
- return FALSE;
-} // HRESULT GetStringCustomAttribute()
-
-//*****************************************************************************
-// Get the value for AutomationProxy for an object. Return the default
-// if there is no attribute.
-//*****************************************************************************
-BOOL TypeLibExporter::GetAutomationProxyAttribute(
- IMDInternalImport *pImport,
- mdToken tk,
- int *bValue)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pImport));
- PRECONDITION(CheckPointer(bValue));
- }
- CONTRACTL_END;
-
- HRESULT hr; // A result.
- const void *pvData; // Pointer to a custom attribute data.
- ULONG cbData; // Size of custom attribute data.
-
- IfFailReport(pImport->GetCustomAttributeByName(tk, INTEROP_AUTOPROXY_TYPE, &pvData, &cbData));
- if (hr == S_OK && cbData > 2)
- {
- CustomAttributeParser cap(pvData, cbData);
- if (FAILED(cap.SkipProlog()))
- return FALSE;
-
- UINT8 u1;
- if (FAILED(cap.GetU1(&u1)))
- return FALSE;
-
- *bValue = u1 != 0;
- }
-
- if (hr == S_OK)
- return TRUE;
-
- return FALSE;
-} // void TypeLibExporter::GetAutomationProxyAttribute()
-
-//*****************************************************************************
-// Create the IClassX ITypeInfo.
-//*****************************************************************************
-void TypeLibExporter::CreateIClassXITypeInfo(
- CExportedTypesInfo *pData, // Conversion data.
- bool bNamespace, // If true, use namespace + name
- bool bResolveDup) // If true, decorate name to resolve dups.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pData));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- LPCUTF8 pName; // Name in UTF8.
- LPCUTF8 pNS; // Namespace in UTF8.
- SString sName; // Name of the TypeDef.
- SString sNameTypeInfo; // Name of the IClassX.
- TYPEKIND tkind; // The TYPEKIND of a TypeDef.
- GUID clsid; // A TypeDef's clsid.
- DWORD dwFlags; // A TypeDef's flags.
- LPWSTR pSuffix; // Pointer into the name.
- int iSuffix = 0; // Counter for suffix.
- GUID guid = {0}; // A default interface's IID.
- HREFTYPE href; // href of base interface of IClassX.
- mdTypeDef td; // Token for the class.
- CorClassIfaceAttr classItfType = clsIfNone; // For class interface type.
-
- VariantHolder vt; // For defining custom attribute.
- SafeComHolder<ICreateTypeInfo> pCTITemp=0; // For creating a typeinfo.
- SafeComHolder<ITypeInfo> pITemp=0; // An ITypeInfo to get a name.
- SafeComHolder<ITypeLib> pITLB=0; // For dup IID reporting.
- SafeComHolder<ITypeInfo> pITIDup=0; // For dup IID reporting.
- SafeComHolder<ICreateTypeInfo2> pCTI2=0; // For creating the typeinfo.
- BSTRHolder bstrName=0; // An ITypeInfo's name.
- BSTRHolder bstrDescr=0; // For description.
- BSTRHolder bstrDup=0; // For dup IID reporting.
- ZeroHolder zhType = &m_ErrorContext.m_pScope; // Clear error reporting info.
-
- MethodTable* pClassOuter = pData->pClass;
-
- DefineFullyQualifiedNameForClassW();
-
- // Get the TypeDef and some info about it.
- td = pData->pClass->GetCl();
- IfFailReport(pData->pClass->GetMDImport()->GetTypeDefProps(td, &dwFlags, 0));
- tkind = pData->tkind;
-
- // Error reporting info.
- m_ErrorContext.m_tkType = td;
- m_ErrorContext.m_pScope = pData->pClass->GetMDImport();
-
- // A CoClass needs an IClassX, and an alias kind needs an alias.
- if (tkind != TKIND_COCLASS)
- return;
-
- // Check to see if the type is supposed to be visible from COM. If it
- // is not then we go to the next type.
- if (!IsTypeVisibleFromCom(TypeHandle(pClassOuter)))
- return;
-
- // Imported types don't need an IClassX.
- if (IsTdImport(dwFlags))
- return;
-
- // Check to see if we need to set up an IClassX for the class.
- ClassHasIClassX(pData->pClass, &classItfType);
- if (classItfType == clsIfNone)
- return;
-
- // Get full name from metadata.
- IfFailReport(pData->pClass->GetMDImport()->GetNameOfTypeDef(td, &pName, &pNS));
-
- // Get the GUID for the class. Used to generate IClassX guid.
- pData->pClass->GetGuid(&clsid, TRUE);
-
- // Get the name of the class. Use the ITypeInfo if there is one, except don't
- // use the typeinfo for types which are Aliased.
- if (pData->pCTI)
- {
- IfFailReport(SafeQueryInterface(pData->pCTI, IID_ITypeInfo, (IUnknown**)&pITemp));
- IfFailReport(pITemp->GetDocumentation(MEMBERID_NIL, &bstrName, 0,0,0));
- sName.Append(bstrName);
- }
- else
- {
- sName.AppendUTF8(pName);
- }
-
- // Create the typeinfo name for the IClassX
- sNameTypeInfo.Set(cIClassX);
- sNameTypeInfo.Append(sName);
-
- tkind = TKIND_INTERFACE;
- pSuffix = 0;
- for (;;)
- {
- // Try to create the TypeInfo.
- hr = m_pICreateTLB->CreateTypeInfo((LPOLESTR)sNameTypeInfo.GetUnicode(), tkind, &pCTITemp);
-
- // If a name conflict, decorate, otherwise, done.
- if (hr != TYPE_E_NAMECONFLICT)
- break;
-
- if (!bResolveDup)
- {
- hr = S_FALSE;
- return;
- }
-
- if (iSuffix == 0)
- {
- iSuffix = 2;
- }
- else
- {
- sNameTypeInfo.Delete(sNameTypeInfo.End()-=2, 2);
- }
-
- SString sDup;
- sDup.Printf(szDuplicateDecoration, iSuffix++);
-
- sNameTypeInfo.Append(sDup);
- }
-
- IfFailReport(hr);
- IfFailReport(SafeQueryInterface(pCTITemp, IID_ICreateTypeInfo2, (IUnknown**)&pCTI2));
-
- // Generate the "IClassX" UUID and set it.
- GenerateClassItfGuid(TypeHandle(pData->pClass), &guid);
- hr = pCTI2->SetGuid(guid);
- if (FAILED(hr))
- {
- if (hr == TYPE_E_DUPLICATEID)
- {
- IfFailReport(SafeQueryInterface(m_pICreateTLB, IID_ITypeLib, (IUnknown**)&pITLB));
- IfFailReport(pITLB->GetTypeInfoOfGuid(guid, &pITIDup));
- IfFailReport(pITIDup->GetDocumentation(MEMBERID_NIL, &bstrDup, 0,0,0));
- InternalThrowHRWithContext(TLBX_E_DUPLICATE_IID, sNameTypeInfo.GetUnicode(), (BSTR)bstrDup);
- }
- return;
- }
-
- // Adding methods may cause an href to this typeinfo, which will cause it to be layed out.
- // Set the inheritance, so that nesting will be correct when that layout happens.
- // Add IDispatch as impltype 0.
- GetRefTypeInfo(pCTI2, m_pIDispatch, &href);
- IfFailReport(pCTI2->AddImplType(0, href));
-
- // Record the fully qualified type name in a custom attribute.
- LPCWSTR szName = GetFullyQualifiedNameForClassNestedAwareW(pData->pClass);
- V_VT(&vt) = VT_BSTR;
- V_BSTR(&vt) = SysAllocString(szName);
- if (V_BSTR(&vt) == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- IfFailReport(pCTI2->SetCustData(GUID_ManagedName, &vt));
-
- TRACE("IClassX %x: %ls, {%08x-%04x-%04x-%04x-%02x%02x%02x%02x}\n", pCTI2, sName,
- guid.Data1, guid.Data2, guid.Data3, guid.Data4[0]<<8|guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5]);
-
- // If the class is decorated with a description, apply it to the typelib.
- if(GetDescriptionString(pData->pClass, td, (BSTR &)bstrDescr))
- IfFailReport(pCTI2->SetDocString(bstrDescr));
-
- // Transfer ownership of the pointer.
- _ASSERTE(pData->pCTIClassItf == 0);
- pData->pCTIClassItf = pCTI2;
- pCTI2.SuppressRelease();
- pCTI2 = 0;
-} // HRESULT TypeLibExporter::CreateIClassXITypeInfo()
-
-//*****************************************************************************
-// Add the impltypes to an ITypeInfo.
-//*****************************************************************************
-void TypeLibExporter::ConvertImplTypes(
- CExportedTypesInfo *pData) // Conversion data.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pData));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- DWORD dwFlags; // A TypeDef's flags.
- mdTypeDef td; // Token for the class.
- ZeroHolder zhType = &m_ErrorContext.m_pScope; // Clear error reporting info.
-
- // Get the TypeDef and some info about it.
- td = pData->pClass->GetCl();
- IfFailReport(pData->pClass->GetMDImport()->GetTypeDefProps(td, &dwFlags, 0));
-
- // Error reporting info.
- m_ErrorContext.m_tkType = td;
- m_ErrorContext.m_pScope = pData->pClass->GetMDImport();
-
- // If there is no ITypeInfo, skip it.
- if (pData->pCTI == 0)
- return;
-
- // Check to see if the type is supposed to be visible from COM. If it
- // is not then we go to the next type.
- if (!IsTypeVisibleFromCom(TypeHandle(pData->pClass)))
- return;
-
- // Add the ImplTypes to the CoClass.
- switch (pData->tkind)
- {
- case TKIND_INTERFACE:
- case TKIND_DISPATCH:
- // Add the base type to the interface.
- ConvertInterfaceImplTypes(pData->pCTI, pData->pClass);
- break;
-
- case TKIND_RECORD:
- case TKIND_UNION:
- case TKIND_ENUM:
- // Nothing to do at this step.
- break;
-
- case TKIND_COCLASS:
- // Add the ImplTypes to the CoClass.
- ConvertClassImplTypes(pData->pCTI, pData->pCTIClassItf, pData->pClass);
- break;
-
- default:
- _ASSERTE(!"Unknown TYPEKIND");
- IfFailReport(E_INVALIDARG);
- break;
- }
-} // HRESULT TypeLibExporter::ConvertImplTypes()
-
-//*****************************************************************************
-// Convert the details (members) of an ITypeInfo.
-//*****************************************************************************
-void TypeLibExporter::ConvertDetails(
- CExportedTypesInfo *pData) // Conversion data.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pData));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- DWORD dwFlags; // A TypeDef's flags.
- mdTypeDef td; // Token for the class.
- ZeroHolder zhType = &m_ErrorContext.m_pScope; // Clear error reporting info.
-
- // Get the TypeDef and some info about it.
- td = pData->pClass->GetCl();
- IfFailReport(pData->pClass->GetMDImport()->GetTypeDefProps(td, &dwFlags, 0));
-
- // Error reporting info.
- m_ErrorContext.m_tkType = td;
- m_ErrorContext.m_pScope = pData->pClass->GetMDImport();
-
- // If there is no TypeInfo, skip it, but for CoClass need to populate IClassX.
- if (pData->pCTI == 0 && pData->tkind != TKIND_COCLASS)
- return;
-
- // Check to see if the type is supposed to be visible from COM. If it
- // is not then we go to the next type.
- if (!IsTypeVisibleFromCom(TypeHandle(pData->pClass)))
- return;
-
- // Fill in the rest of the typeinfo for this typedef.
- switch (pData->tkind)
- {
- case TKIND_INTERFACE:
- case TKIND_DISPATCH:
- ConvertInterfaceDetails(pData->pCTI, pData->pClass, pData->bAutoProxy);
- break;
-
- case TKIND_RECORD:
- case TKIND_UNION:
- ConvertRecord(pData);
- break;
-
- case TKIND_ENUM:
- ConvertEnum(pData->pCTI, pData->pClass);
- break;
-
- case TKIND_COCLASS:
- // Populate the methods on the IClassX interface.
- ConvertClassDetails(pData->pCTI, pData->pCTIClassItf, pData->pClass, pData->bAutoProxy);
- break;
-
- default:
- _ASSERTE(!"Unknown TYPEKIND");
- IfFailReport(E_INVALIDARG);
- break;
- } // Switch (tkind)
-
- // Report that this type has been converted.
- SString ssType;
- if (IsTdNested(dwFlags))
- {
- TypeNameBuilder tnb(&ssType, TypeNameBuilder::ParseStateNAME);
- TypeString::AppendNestedTypeDef(tnb, m_ErrorContext.m_pScope, m_ErrorContext.m_tkType);
- }
- else
- TypeString::AppendTypeDef(ssType, m_ErrorContext.m_pScope, m_ErrorContext.m_tkType);
- ReportEvent(NOTIF_TYPECONVERTED, TLBX_I_TYPE_EXPORTED, ssType.GetUnicode());
-} // void TypeLibExporter::ConvertDetails()
-
-//*****************************************************************************
-// Add the ImplTypes to the TypeInfo.
-//*****************************************************************************
-void TypeLibExporter::ConvertInterfaceImplTypes(
- ICreateTypeInfo2 *pThisTypeInfo, // The typeinfo being created.
- MethodTable *pClass) // MethodTable for the TypeInfo.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pThisTypeInfo));
- PRECONDITION(CheckPointer(pClass));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- ULONG ulIface; // Is this interface [dual]?
- HREFTYPE href; // href of base interface.
-
- // IDispatch or IUnknown derived?
- IfFailReport(pClass->GetMDImport()->GetIfaceTypeOfTypeDef(pClass->GetCl(), &ulIface));
-
- // Parent interface.
- if (IsDispatchBasedItf((CorIfaceAttr)ulIface))
- {
- // Get the HREFTYPE for IDispatch.
- GetRefTypeInfo(pThisTypeInfo, m_pIDispatch, &href);
- }
- else
- {
- // Get the HREFTYPE for IUnknown.
- GetRefTypeInfo(pThisTypeInfo, m_pIUnknown, &href);
- }
-
- // Add the HREF as an interface.
- IfFailReport(pThisTypeInfo->AddImplType(0, href));
-} // void TypeLibExporter::ConvertInterfaceImplTypes()
-
-
-//*****************************************************************************
-// Create the TypeInfo for an interface by iterating over functions.
-//*****************************************************************************
-void TypeLibExporter::ConvertInterfaceDetails (
- ICreateTypeInfo2 *pThisTypeInfo, // The typeinfo being created.
- MethodTable *pMT, // MethodTable for the TypeInfo.
- int bAutoProxy) // If true, oleaut32 is the interface's marshaller.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pThisTypeInfo));
- PRECONDITION(CheckPointer(pMT));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- ULONG ulIface; // Is this interface [dual]?
- DWORD dwTIFlags=0; // TypeLib flags.
- int cVisibleMembers = 0; // The count of methods that are visible to COM.
-
- // Retrieve the map of members.
- ComMTMemberInfoMap MemberMap(pMT);
-
- // IDispatch or IUnknown derived?
- IfFailReport(pMT->GetMDImport()->GetIfaceTypeOfTypeDef(pMT->GetCl(), &ulIface));
-
- if (IsDispatchBasedItf((CorIfaceAttr)ulIface))
- {
- // IDispatch derived.
- dwTIFlags |= TYPEFLAG_FDISPATCHABLE;
-
- if (ulIface == ifDual)
- dwTIFlags |= TYPEFLAG_FDUAL | TYPEFLAG_FOLEAUTOMATION;
- else
- _ASSERTE(ulIface == ifDispatch);
- }
- else
- {
- // IUnknown derived.
- dwTIFlags |= TYPEFLAG_FOLEAUTOMATION;
- }
-
- if (!bAutoProxy)
- dwTIFlags |= TYPEFLAG_FPROXY;
-
- // Set appropriate flags.
- IfFailReport(pThisTypeInfo->SetTypeFlags(dwTIFlags));
-
- // Retrieve the method properties.
- size_t sizeOfPtr = IsExportingAs64Bit() ? 8 : 4;
-
- MemberMap.Init(sizeOfPtr);
- if (MemberMap.HadDuplicateDispIds())
- ReportWarning(TLBX_I_DUPLICATE_DISPID, TLBX_I_DUPLICATE_DISPID);
-
- // We need a scope to bypass the inialization skipped by goto ErrExit
- // compiler error.
- {
- CQuickArray<ComMTMethodProps> &rProps = MemberMap.GetMethods();
-
- // Now add the methods to the TypeInfo.
- MethodTable::MethodIterator it(pMT);
- for (; it.IsValid(); it.Next())
- {
- if (it.IsVirtual())
- {
- // Only convert the method if it is visible from COM.
- if (rProps[it.GetSlotNumber()].bMemberVisible)
- {
- if (ConvertMethod(pThisTypeInfo, &rProps[it.GetSlotNumber()], cVisibleMembers, ulIface))
- cVisibleMembers++;
- }
- }
- }
- }
-} // void TypeLibExporter::ConvertInterfaceDetails()
-
-//*****************************************************************************
-// Export a Record to a TypeLib.
-//*****************************************************************************
-void TypeLibExporter::ConvertRecordBaseClass(
- CExportedTypesInfo *pData, // Conversion data.
- MethodTable *pSubMT, // The base class.
- ULONG &ixVar) // Variable index in the typelib.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pData));
- PRECONDITION(CheckPointer(pSubMT));
- }
- CONTRACTL_END;
-
- // The typeinfo being created.
- ICreateTypeInfo2 *pThisTypeInfo = pData->pCTI;
-
- HRESULT hr = S_OK; // A result.
- mdFieldDef fd; // A Field def.
- ULONG iFD; // Loop control.
- ULONG cFD; // Count of total MemberDefs.
- DWORD dwFlags; // Field flags.
- LPCUTF8 szName; // Name in UTF8.
- LPCUTF8 szNamespace; // A Namespace in UTF8.
- SString sName; // Name
-
- // To enum fields.
- HENUMInternalHolder eFDi(pSubMT->GetMDImport());
-
- // If there is no class here, or if the class is Object, don't add members.
- if (pSubMT == 0 ||
- pSubMT == g_pObjectClass)
- return;
-
- // If this class has a base class, export those members first.
- ConvertRecordBaseClass(pData, pSubMT->GetParentMethodTable(), ixVar);
-
- // Build the member name prefix.
- IfFailReport(pSubMT->GetMDImport()->GetNameOfTypeDef(pSubMT->GetCl(), &szName, &szNamespace));
-
- sName.SetUTF8(szName);
- sName.Append(W("_"));
-
- // Get an enumerator for the MemberDefs in the TypeDef.
- eFDi.EnumInit(mdtFieldDef, pSubMT->GetCl());
- cFD = pSubMT->GetMDImport()->EnumGetCount(&eFDi);
-
- SString sNameMember;
- // For each MemberDef...
- for (iFD=0; iFD<cFD; ++iFD)
- {
- // Get the next field.
- if (!pSubMT->GetMDImport()->EnumNext(&eFDi, &fd))
- {
- IfFailReport(E_UNEXPECTED);
- }
-
- IfFailReport(pSubMT->GetMDImport()->GetFieldDefProps(fd, &dwFlags));
-
- // Only non-static fields.
- if (!IsFdStatic(dwFlags))
- {
- IfFailReport(pSubMT->GetMDImport()->GetNameOfFieldDef(fd, &szName));
-
- sNameMember.Set(sName);
- sNameMember.AppendUTF8(szName);
- if (ConvertVariable(pThisTypeInfo, pSubMT, fd, sNameMember, ixVar))
- ixVar++;
- }
- }
-} // void TypeLibExporter::ConvertRecordBaseClass()
-
-void TypeLibExporter::ConvertRecord(
- CExportedTypesInfo *pData) // Conversion data.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pData));
- }
- CONTRACTL_END;
-
- ICreateTypeInfo2 *pThisTypeInfo=pData->pCTI; // The typeinfo being created.
- MethodTable *pMT=pData->pClass; // MethodTable for the TypeInfo.
-
- HRESULT hr = S_OK; // A result.
- mdFieldDef fd; // A Field def.
- ULONG iFD; // Loop control.
- ULONG ixVar=0; // Index of current var converted.
- ULONG cFD; // Count of total MemberDefs.
- DWORD dwFlags; // Field flags.
- DWORD dwPack; // Class pack size.
- mdToken tkExtends; // A class's parent.
- LPCUTF8 szName; // Name in UTF8.
- SString sName; // Name.
-
- // To enum fields.
- HENUMInternalHolder eFDi(pMT->GetMDImport());
-
- // If the type is a struct, but it has explicit layout, don't export the members,
- // because we can't export them accurately (unless they're really sequential).
- if (pData->tkind == TKIND_RECORD)
- {
- IfFailReport(pMT->GetMDImport()->GetTypeDefProps(pMT->GetCl(), &dwFlags, &tkExtends));
-
- if (IsTdExplicitLayout(dwFlags))
- {
- ReportWarning(S_OK, TLBX_I_NONSEQUENTIALSTRUCT);
- return;
- }
- }
-
- // Set the packing size, if there is one.
- dwPack = 0;
- if (FAILED(pMT->GetMDImport()->GetClassPackSize(pMT->GetCl(), &dwPack)))
- {
- dwPack = 0;
- }
- if (dwPack == 0)
- {
- dwPack = DEFAULT_PACKING_SIZE;
- }
-
- IfFailReport(pThisTypeInfo->SetAlignment((USHORT)dwPack));
-
- // Haven't seen any non-public members yet.
- m_bWarnedOfNonPublic = FALSE;
-
- // If this class has a base class, export those members first.
- ConvertRecordBaseClass(pData, pMT->GetParentMethodTable(), ixVar);
-
- // Get an enumerator for the MemberDefs in the TypeDef.
- eFDi.EnumInit(mdtFieldDef, pMT->GetCl());
- cFD = pMT->GetMDImport()->EnumGetCount(&eFDi);
-
- // For each MemberDef...
- for (iFD=0; iFD<cFD; ++iFD)
- {
- // Get the next field.
- if (!pMT->GetMDImport()->EnumNext(&eFDi, &fd))
- {
- IfFailReport(E_UNEXPECTED);
- }
-
- IfFailReport(pMT->GetMDImport()->GetFieldDefProps(fd, &dwFlags));
-
- // Skip static fields.
- if (IsFdStatic(dwFlags) == 0)
- {
- IfFailReport(pMT->GetMDImport()->GetNameOfFieldDef(fd, &szName));
-
- sName.SetUTF8(szName);
- if (ConvertVariable(pThisTypeInfo, pMT, fd, sName, ixVar))
- ixVar++;
- }
- }
-} // HRESULT TypeLibExporter::ConvertRecord()
-
-//*****************************************************************************
-// Export an Enum to a typelib.
-//*****************************************************************************
-void TypeLibExporter::ConvertEnum(
- ICreateTypeInfo2 *pThisTypeInfo, // The typeinfo being created.
- MethodTable *pMT) // MethodTable for the TypeInfo.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pThisTypeInfo));
- PRECONDITION(CheckPointer(pMT));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- mdFieldDef fd; // A Field def.
- DWORD dwTIFlags=0; // TypeLib flags.
- ULONG dwFlags; // A field's flags.
- ULONG iFD; // Loop control.
- ULONG cFD; // Count of total MemberDefs.
- ULONG iVar=0; // Count of vars actually converted.
- LPCUTF8 szName; // Name in UTF8.
- SString sName; // Name.
- SafeComHolder<ITypeInfo> pThisTI=0; // TypeInfo for this ICreateITypeInfo.
- BSTRHolder szThisTypeInfo=0; // Name of this ITypeInfo.
-
- IMDInternalImport* pImport = pMT->GetMDImport();
-
- // To enum fields.
- HENUMInternalHolder eFDi(pImport);
-
- // Explicitly set the flags.
- IfFailReport(pThisTypeInfo->SetTypeFlags(dwTIFlags));
-
- // Get an enumerator for the MemberDefs in the TypeDef.
- eFDi.EnumInit(mdtFieldDef, pMT->GetCl());
- cFD = pImport->EnumGetCount(&eFDi);
-
- // Build the member name prefix. If generating an enum, get the real name from the default interface.
- IfFailReport(SafeQueryInterface(pThisTypeInfo, IID_ITypeInfo, (IUnknown**)&pThisTI));
- IfFailReport(pThisTI->GetDocumentation(MEMBERID_NIL, &szThisTypeInfo, 0,0,0));
-
- sName.Set(szThisTypeInfo);
- sName.Append(W("_"));
-
- SString sNameMember;
- // For each MemberDef...
- for (iFD=0; iFD<cFD; ++iFD)
- {
- // Get the next field.
- if (!pImport->EnumNext(&eFDi, &fd))
- {
- IfFailReport(E_UNEXPECTED);
- }
-
- // Only convert static fields.
- IfFailReport(pImport->GetFieldDefProps(fd, &dwFlags));
-
- if (IsFdStatic(dwFlags) == 0)
- {
- continue;
- }
-
- // Skip ComVisible(false) members
- if (!IsMemberVisibleFromCom(pMT, fd, mdTokenNil))
- {
- continue;
- }
-
- sNameMember.Set(sName);
- IfFailReport(pImport->GetNameOfFieldDef(fd, &szName));
-
- sNameMember.AppendUTF8(szName);
-
- if (ConvertEnumMember(pThisTypeInfo, pMT, fd, sNameMember, iVar))
- {
- iVar++;
- }
- }
-} // void TypeLibExporter::ConvertEnum()
-
-//*****************************************************************************
-// Does a class have a default ctor?
-//*****************************************************************************
-BOOL TypeLibExporter::HasDefaultCtor(
- MethodTable *pMT) // The class in question.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pMT));
- }
- CONTRACTL_END;
-
- HRESULT hr; // A result.
- mdMethodDef md; // A method of the type.
- DWORD dwFlags; // Method's flags.
- ULONG cMD; // Count of returned tokens.
- ULONG iMD; // Loop control.
- PCCOR_SIGNATURE pSig; // The signature.
- ULONG ixSig; // Index into signature.
- ULONG cbSig; // Size of the signature.
- ULONG callconv; // Method's calling convention.
- ULONG cParams; // Method's count of parameters.
- BOOL rslt=FALSE; // Was one found?
- LPCUTF8 pName; // Method name.
-
- IMDInternalImport* pImport = pMT->GetMDImport();
-
- // To enum methods.
- HENUMInternalHolder eMDi(pImport);
-
- // Get an enumerator for the MemberDefs in the TypeDef.
- eMDi.EnumInit(mdtMethodDef, pMT->GetCl());
- cMD = pImport->EnumGetCount(&eMDi);
-
- // For each MemberDef...
- for (iMD=0; iMD<cMD; ++iMD)
- {
- // Get the next field.
- if (!pImport->EnumNext(&eMDi, &md))
- {
- IfFailReport(E_UNEXPECTED);
- }
-
- // Is the name special? Is the method public?
- IfFailReport(pImport->GetMethodDefProps(md, &dwFlags));
-
- if (!IsMdRTSpecialName(dwFlags) || !IsMdPublic(dwFlags))
- continue;
-
- // Yes, is the name a ctor?
- IfFailReport(pImport->GetNameOfMethodDef(md, &pName));
-
- if (!IsMdInstanceInitializer(dwFlags, pName))
- continue;
-
- // It is a ctor. Is it a default ctor?
- IfFailReport(pImport->GetSigOfMethodDef(md, &cbSig, &pSig));
-
- // Skip the calling convention, and get the param count.
- ixSig = CorSigUncompressData(pSig, &callconv);
- CorSigUncompressData(&pSig[ixSig], &cParams);
-
- // Default ctor has zero params.
- if (cParams == 0)
- {
- rslt = TRUE;
- break;
- }
- }
-
- return rslt;
-} // BOOL TypeLibExporter::HasDefaultCtor()
-
-//*****************************************************************************
-// Export a class to a TypeLib.
-//*****************************************************************************
-void TypeLibExporter::ConvertClassImplTypes(
- ICreateTypeInfo2 *pThisTypeInfo, // The typeinfo being created.
- ICreateTypeInfo2 *pClassItfTypeInfo,// The ICLassX for the TypeInfo.
- MethodTable *pMT) // MethodTable for the TypeInfo.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pThisTypeInfo, NULL_OK));
- PRECONDITION(CheckPointer(pClassItfTypeInfo, NULL_OK));
- PRECONDITION(CheckPointer(pMT));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- HREFTYPE href; // HREF to a TypeInfo.
- DWORD dwFlags; // Metadata flags.
- int flags=0; // Flags for the interface impl or CoClass.
- UINT iImpl=0; // Current Impl index.
- MethodTable *pIDefault = 0; // Default interface, if any.
- MethodTable *pDefItfMT = 0; // Default interface method table, if any.
- CQuickArray<MethodTable *> SrcItfList; // List of event sources.
- CorClassIfaceAttr classItfType = clsIfNone; // For class interface type.
- DefaultInterfaceType DefItfType;
- TypeHandle hndDefItfClass;
-
- SafeComHolder<ITypeInfo> pTI=0; // TypeInfo for default dispinterface.
- SafeComHolder<ICreateTypeInfo2> pCTI2 = NULL; // The ICreateTypeInfo2 interface used to define custom data.
-
- // We should never be converting the class impl types of COM imported CoClasses.
- _ASSERTE(!pMT->IsComImport());
-
- if (pThisTypeInfo)
- {
- IfFailReport(pMT->GetMDImport()->GetTypeDefProps(pMT->GetCl(), &dwFlags, 0));
-
- // If abstract class, or no default ctor, don't make it creatable.
- if (!IsTdAbstract(dwFlags) && HasDefaultCtor(pMT))
- flags |= TYPEFLAG_FCANCREATE;
-
- // PreDeclid as appropriate.
- IfFailReport(pThisTypeInfo->SetTypeFlags(flags));
- }
-
- // Retrieve the MethodTable that represents the default interface.
- DefItfType = GetDefaultInterfaceForClassWrapper(TypeHandle(pMT), &hndDefItfClass);
-
- // Remember the MethodTable of the default interface.
- pIDefault = hndDefItfClass.GetMethodTable();
-
- // For some classes we synthesize an IClassX. We don't do that for
- // configured class, classes imported from COM,
- // or for classes with an explicit default interface.
- if (pClassItfTypeInfo)
- {
- // Set the interface as the default for the class.
- IfFailReport(SafeQueryInterface(pClassItfTypeInfo, IID_ITypeInfo, (IUnknown**)&pTI));
- GetRefTypeInfo(pThisTypeInfo, pTI, &href);
- IfFailReport(pThisTypeInfo->AddImplType(iImpl, href));
-
- // If the class interface is the default interface, mark it as such.
- if (pMT == pIDefault)
- IfFailReport(pThisTypeInfo->SetImplTypeFlags(iImpl, IMPLTYPEFLAG_FDEFAULT));
-
- // Increment the impl count.
- ++iImpl;
- }
-
- // Go up the class hierarchy and add the IClassX's of the parent classes
- // as interfaces implemented by the COM component.
- MethodTable *pParentClass = pMT->GetComPlusParentMethodTable();
- while (pParentClass)
- {
- // If the parent class has an IClassX interface then add it.
- ClassHasIClassX(pParentClass, &classItfType);
- if (classItfType == clsIfAutoDual)
- {
- hr = EEClassToHref(pThisTypeInfo, pParentClass, FALSE, &href);
-
- // If not IUnknown, add the HREF as an interface.
- if (hr != S_USEIUNKNOWN)
- {
- IfFailReport(pThisTypeInfo->AddImplType(iImpl, href));
- if (pParentClass == pIDefault)
- IfFailReport(pThisTypeInfo->SetImplTypeFlags(iImpl, IMPLTYPEFLAG_FDEFAULT));
-
- ++iImpl;
- }
- }
-
- // Process the next class up the hierarchy.
- pParentClass = pParentClass->GetComPlusParentMethodTable();
- }
-
- ComCallWrapperTemplate *pClassTemplate = ComCallWrapperTemplate::GetTemplate(TypeHandle(pMT));
- MethodTable::InterfaceMapIterator it = pMT->IterateInterfaceMap();
- while (it.Next())
- {
- flags = 0;
-
- // Get the MethodTable for an implemented interface.
- MethodTable *pIClass = it.GetInterface();
-
- // Retrieve the ComMethodTable for the interface.
- ComMethodTable *pItfComMT = pClassTemplate->GetComMTForItf(pIClass);
-
- // If the interface is visible from COM, add it.
- if (IsTypeVisibleFromCom(TypeHandle(pIClass)) && !pItfComMT->IsComClassItf())
- {
-#if defined(_DEBUG)
- TRACE("Class %s implements %s\n", pMT->GetDebugClassName(), pIClass->GetDebugClassName());
-#endif
- // Get an href for the managed class.
- hr = EEClassToHref(pThisTypeInfo, pIClass, FALSE, &href);
-
- // If not IUnknown, add the HREF as an interface.
- if (hr != S_USEIUNKNOWN)
- {
- if (pIClass == pIDefault)
- flags |= IMPLTYPEFLAG_FDEFAULT;
-
- IfFailReport(pThisTypeInfo->AddImplType(iImpl, href));
- IfFailReport(pThisTypeInfo->SetImplTypeFlags(iImpl, flags));
- ++iImpl;
- }
- }
- else if (!IsTypeVisibleFromCom(TypeHandle(pIClass)) && (pIClass == pIDefault))
- {
- // Report a warning if the default interface is not COM visible
- ReportWarning(TLBX_W_DEFAULT_INTF_NOT_VISIBLE, TLBX_W_DEFAULT_INTF_NOT_VISIBLE);
- }
- }
-
- // Retrieve the list of COM source interfaces for the managed class.
- GetComSourceInterfacesForClass(pMT, SrcItfList);
-
- // Add all the source interfaces to the CoClass.
- flags = IMPLTYPEFLAG_FSOURCE | IMPLTYPEFLAG_FDEFAULT;
- for (UINT i = 0; i < SrcItfList.Size(); i++)
- {
- hr = EEClassToHref(pThisTypeInfo, SrcItfList[i], FALSE, &href);
-
- // If not IUnknown, add the HREF as an interface.
- if (hr != S_USEIUNKNOWN)
- {
- IfFailReport(pThisTypeInfo->AddImplType(iImpl, href));
- IfFailReport(pThisTypeInfo->SetImplTypeFlags(iImpl, flags));
- ++iImpl;
- flags = IMPLTYPEFLAG_FSOURCE;
- }
- }
-} // void TypeLibExporter::ConvertClassImplTypes()
-
-//*****************************************************************************
-// Export a class to a TypeLib.
-//*****************************************************************************
-void TypeLibExporter::ConvertClassDetails(
- ICreateTypeInfo2 *pThisTypeInfo, // The typeinfo being created.
- ICreateTypeInfo2 *pDefaultTypeInfo, // The ICLassX for the TypeInfo.
- MethodTable *pMT, // MethodTable for the TypeInfo.
- int bAutoProxy) // If true, oleaut32 is the proxy.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pThisTypeInfo, NULL_OK));
- PRECONDITION(CheckPointer(pDefaultTypeInfo, NULL_OK));
- PRECONDITION(CheckPointer(pMT));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- CorClassIfaceAttr classItfType = clsIfNone;
-
- ClassHasIClassX(pMT, &classItfType);
- if (classItfType == clsIfAutoDual)
- {
- // Set up the IClassX interface.
- ConvertIClassX(pDefaultTypeInfo, pMT, bAutoProxy);
- }
- else if (pDefaultTypeInfo)
- {
- DWORD dwTIFlags = TYPEFLAG_FDUAL | TYPEFLAG_FOLEAUTOMATION | TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FHIDDEN;
- if (!bAutoProxy)
- dwTIFlags |= TYPEFLAG_FPROXY;
- IfFailReport(pDefaultTypeInfo->SetTypeFlags(dwTIFlags));
- }
-} // void TypeLibExporter::ConvertClassDetails()
-
-//*****************************************************************************
-// Create the DispInterface for the vtable that describes an entire class.
-//*****************************************************************************
-void TypeLibExporter::ConvertIClassX(
- ICreateTypeInfo2 *pThisTypeInfo, // The TypeInfo for the IClassX.
- MethodTable *pMT, // The MethodTable object for the class.
- int bAutoProxy) // If true, oleaut32 is the proxy.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pThisTypeInfo));
- PRECONDITION(CheckPointer(pMT));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- DWORD dwTIFlags=0; // TypeLib flags.
- DWORD nSlots; // Number of vtable slots.
- UINT i; // Loop control.
- int cVisibleMembers = 0; // The count of methods that are visible to COM.
- ComMTMemberInfoMap MemberMap(pMT); // The map of members.
-
- // Should be an actual class.
- _ASSERTE(!pMT->IsInterface());
-
- // Retrieve the method properties.
- size_t sizeOfPtr = IsExportingAs64Bit() ? 8 : 4;
-
- MemberMap.Init(sizeOfPtr);
- if (MemberMap.HadDuplicateDispIds())
- ReportWarning(TLBX_I_DUPLICATE_DISPID, TLBX_I_DUPLICATE_DISPID);
-
- // We need a scope to bypass the inialization skipped by goto ErrExit
- // compiler error.
- {
- CQuickArray<ComMTMethodProps> &rProps = MemberMap.GetMethods();
- nSlots = (DWORD)rProps.Size();
-
- dwTIFlags |= TYPEFLAG_FDUAL | TYPEFLAG_FOLEAUTOMATION | TYPEFLAG_FDISPATCHABLE | TYPEFLAG_FHIDDEN | TYPEFLAG_FNONEXTENSIBLE;
- if (!bAutoProxy)
- dwTIFlags |= TYPEFLAG_FPROXY;
- IfFailReport(pThisTypeInfo->SetTypeFlags(dwTIFlags));
-
- // Assign slot numbers.
- for (i=0; i<nSlots; ++i)
- rProps[i].oVft = (short)((7 + i) * sizeOfPtr);
-
- // Now add the methods to the TypeInfo.
- for (i=0; i<nSlots; ++i)
- {
- TRACE("[%d] %10ls pMeth:%08x, prop:%d, semantic:%d, dispid:0x%x, oVft:%d\n", i, rProps[i].pName, rProps[i].pMeth,
- rProps[i].property, rProps[i].semantic, rProps[i].dispid, rProps[i].oVft);
- if (rProps[i].bMemberVisible)
- {
- if (rProps[i].semantic < FieldSemanticOffset)
- {
- if (ConvertMethod(pThisTypeInfo, &rProps[i], cVisibleMembers, ifDual))
- cVisibleMembers++;
- }
- else
- {
- if (ConvertFieldAsMethod(pThisTypeInfo, &rProps[i], cVisibleMembers))
- cVisibleMembers++;
- }
- }
- }
- }
-} // void TypeLibExporter::ConvertIClassX()
-
-
-//*****************************************************************************
-// Export a Method's metadata to a typelib.
-//*****************************************************************************
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
-#endif
-BOOL TypeLibExporter::ConvertMethod(
- ICreateTypeInfo2 *pCTI, // ICreateTypeInfo2 to get the method.
- ComMTMethodProps *pProps, // Some properties of the method.
- ULONG iMD, // Index of the member
- ULONG ulIface) // Is this interface : IUnknown, [dual], or DISPINTERFACE?
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pCTI));
- PRECONDITION(CheckPointer(pProps));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- HRESULT hrSignature = S_OK; // A failure HR;
- LPCUTF8 pszName; // Name in UTF8.
- SString sName; // Holds name.
- ULONG dwImplFlags; // The function's impl flags.
- PCCOR_SIGNATURE pbSig; // Pointer to Cor signature.
- ULONG cbSig; // Size of Cor signature.
- ULONG ixSig; // Index into signature.
- ULONG cbElem; // Size of an element in the signature.
- ULONG callconv; // A member's calling convention.
- ULONG ret; // The return type.
- ULONG elem; // A signature element.
- TYPEDESC *pRetVal=0; // Return type's TYPEDESC.
- ULONG cSrcParams; // Count of source params.
- ULONG cDestParams = 0; // Count of dest parameters.
- USHORT iSrcParam; // Loop control, over params.
- USHORT iDestParam; // Loop control, over params.
- USHORT iLCIDParam; // The index of the LCID param.
- ULONG dwParamFlags; // A parameter's flags.
- CDescPool sPool; // Pool of memory in which to build funcdesc.
- CDescPool sVariants; // Pool of variants for default values.
- PARAMDESCEX *pParamDesc; // Pointer to one param default value.
- int bHrMunge=true; // Munge return type to HRESULT?
- CQuickArray<BSTR> rNames; // Array of names to function and parameters.
- ULONG cNames=0; // Count of function and parameter names.
- FUNCDESC *pfunc = NULL; // A funcdesc.
- MethodDesc *pMeth; // A MethodDesc.
- IMDInternalImport *pInternalImport; // Internal interface containing the method.
- MDDefaultValue defaultValue; // place holder for default value
- PCCOR_SIGNATURE pvNativeType; // native parameter type
- ULONG cbNativeType = 0; // native parameter type length
- MethodTable *pMT; // Class containing the method.
- int bHasOptorDefault=false; // If true, the method has optional params or default values -- no vararg
- const void *pvData; // Pointer to a custom attribute.
- ULONG cbData; // Size of custom attribute.
- BOOL bByRef; // Is a parameter byref?
- BSTRHolder bstrDescr=0; // Description of the method.
- VariantHolder vtManagedName; // Variant used to set the managed name of the member.
-
- ZeroHolder zhParam = &m_ErrorContext.m_szParam; // Clear error reporting info.
- ZeroHolder zhMember = &m_ErrorContext.m_szMember; // Clear error reporting info.
-
- // Get info about the method.
- pMeth = pProps->pMeth;
- pMeth->GetSig(&pbSig, &cbSig);
- pInternalImport = pMeth->GetMDImport();
- pMT = pMeth->GetMethodTable();
- IfFailReport(pInternalImport->GetMethodImplProps(pMeth->GetMemberDef(), 0, &dwImplFlags));
-
- // Error reporting info.
- IfFailReport(pInternalImport->GetNameOfMethodDef(pMeth->GetMemberDef(), &m_ErrorContext.m_szMember));
-
- // Allocate one variant.
- pParamDesc = reinterpret_cast<PARAMDESCEX*>(sVariants.AllocZero(sizeof(PARAMDESCEX)));
- if(NULL == pParamDesc)
- IfFailReport(E_OUTOFMEMORY);
-
- // Prepare to parse signature and build the FUNCDESC.
- pfunc = reinterpret_cast<FUNCDESC*>(sPool.AllocZero(sizeof(FUNCDESC)));
- if (pfunc == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- ixSig = 0;
-
- // Get the calling convention.
- ixSig += CorSigUncompressData(&pbSig[ixSig], &callconv);
- _ASSERTE((callconv & IMAGE_CEE_CS_CALLCONV_MASK) != IMAGE_CEE_CS_CALLCONV_FIELD);
- pfunc->callconv = Clr2TlbCallConv[callconv & IMAGE_CEE_CS_CALLCONV_MASK];
-
- // vtable offset.
- pfunc->oVft = pProps->oVft;
-
- // Get the argument count. Allow for an extra in case of [retval].
- ixSig += CorSigUncompressData(&pbSig[ixSig], &cSrcParams);
- cDestParams = cSrcParams;
- rNames.ReSizeThrows(cDestParams+3);
- memset(rNames.Ptr(), 0, (cDestParams+3) * sizeof(BSTR));
-
- // Set some method properties.
- pfunc->memid = pProps->dispid;
- if (pfunc->memid == -11111) //@todo: fix for msvbalib.dll
- pfunc->memid = -1;
- pfunc->funckind = FUNC_PUREVIRTUAL;
-
- // Set the invkind based on whether the function is an accessor.
- if (pProps->semantic == 0)
- pfunc->invkind = INVOKE_FUNC;
- else if (pProps->semantic == msGetter)
- pfunc->invkind = INVOKE_PROPERTYGET;
- else if (pProps->semantic == msSetter)
- pfunc->invkind = INVOKE_PROPERTYPUTREF;
- else if (pProps->semantic == msOther)
- pfunc->invkind = INVOKE_PROPERTYPUT;
- else
- pfunc->invkind = INVOKE_FUNC; // non-accessor property function.
-
- rNames[0] = pProps->pName;
- cNames = 1;
-
- // Convert return type to elemdesc. If we are doing HRESULT munging, we need to
- // examine the return type, and if it is not VOID, create an additional final
- // parameter as a pointer to the type.
-
- // Get the return type.
- cbElem = CorSigUncompressData(&pbSig[ixSig], &ret);
-
- // Error reporting info.
- m_ErrorContext.m_ixParam = 0;
-
- // Get native type of return if available
- mdParamDef pdParam;
- pvNativeType = NULL;
- hr = pInternalImport->FindParamOfMethod(pMeth->GetMemberDef(), 0, &pdParam);
- if (hr == S_OK)
- {
- hr = pInternalImport->GetFieldMarshal(pdParam, &pvNativeType, &cbNativeType);
- if (hr != CLDB_E_RECORD_NOTFOUND)
- {
- IfFailReport(hr);
- }
- }
-
- // Determine if we need to do HRESULT munging.
- bHrMunge = !IsMiPreserveSig(dwImplFlags);
-
- // Reset some properties for DISPINTERFACES.
- if (ulIface == ifDispatch)
- {
- pfunc->callconv = CC_STDCALL;
- pfunc->funckind = FUNC_DISPATCH;
-
- // Never munge a dispinterface.
- bHrMunge = false;
- }
-
- if (bHrMunge)
- {
- // Munge the return type into a new last param, set return type to HRESULT.
- pfunc->elemdescFunc.tdesc.vt = VT_HRESULT;
-
- // Does the function actually return anything?
- if (ret == ELEMENT_TYPE_VOID)
- {
- // Skip over the return value, no [retval].
- pRetVal = 0;
- ixSig += cbElem;
- }
- else
- {
- // Allocate a TYPEDESC to be pointed to, convert type into it.
- pRetVal = reinterpret_cast<TYPEDESC*>(sPool.AllocZero(sizeof(TYPEDESC)));
- if (pRetVal == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- hr = CorSigToTypeDesc(pCTI, pMT, &pbSig[ixSig], pvNativeType, cbNativeType, &cbElem, pRetVal, &sPool, TRUE);
- if (FAILED(hr))
- return FALSE;
-
- ixSig += cbElem;
-
- ++cDestParams;
- // It is pretty weird for a property putter to return something, but apparenly legal.
- //_ASSERTE(pfunc->invkind != INVOKE_PROPERTYPUT && pfunc->invkind != INVOKE_PROPERTYPUTREF);
-
- // Todo: When the C compiler tries to import a typelib with a C
- // array return type (even if it's a retval),
- // it generates a wrapper method with a signature like "int [] foo()",
- // which isn't valid C, so it barfs. So, we'll change the return type
- // to a pointer by hand.
- if (pRetVal->vt == VT_CARRAY)
- {
- pRetVal->vt = VT_PTR;
- pRetVal->lptdesc = &pRetVal->lpadesc->tdescElem;
- }
- }
- }
- else
- {
- // No munging, convert return type.
- pRetVal = 0;
- hr = CorSigToTypeDesc(pCTI, pMT, &pbSig[ixSig], pvNativeType, cbNativeType, &cbElem, &pfunc->elemdescFunc.tdesc, &sPool, TRUE);
- if (FAILED(hr))
- return FALSE;
-
- ixSig += cbElem;
- }
-
- // Error reporting info.
- m_ErrorContext.m_ixParam = -1;
-
- // Check to see if there is an LCIDConversion attribute on the method.
- iLCIDParam = (USHORT)GetLCIDParameterIndex(pMeth);
- if (iLCIDParam != (USHORT)-1)
- {
- BOOL bValidLCID = TRUE;
-
- // Make sure the parameter index is valid.
- if (iLCIDParam > cSrcParams)
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_INVALIDLCIDPARAM);
- bValidLCID = FALSE;
- }
-
- // LCID's are not allowed on pure dispatch interfaces.
- if (ulIface == ifDispatch)
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_LCIDONDISPONLYITF);
- bValidLCID = FALSE;
- }
-
- if (bValidLCID)
- {
- // Take the LCID parameter into account in the exported method.
- ++cDestParams;
- }
- else
- {
- // The LCID is invalid so we will ignore it.
- iLCIDParam = -1;
- }
- }
-
- // for each parameter
- pfunc->lprgelemdescParam = reinterpret_cast<ELEMDESC*>(sPool.AllocZero(cDestParams * sizeof(ELEMDESC)));
- if (pfunc->lprgelemdescParam == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- // Holds the allocated strings so we can deallocate on function exit.
- // Only need +1 as we don't clean up the first and last names (function name and retval)
- NewArrayHolder<BSTRHolder> namesHolder = new BSTRHolder[cDestParams+1];
-
- // Variant array used to hold default value data
- NewArrayHolder<VariantPtrHolder> vtDefaultValues = new VariantPtrHolder[cDestParams];
-
- pfunc->cParams = static_cast<short>(cDestParams);
- for (iSrcParam=1, iDestParam=0; iDestParam<cDestParams; ++iSrcParam, ++iDestParam)
- {
- // Check to see if we need to insert the LCID param before the current param.
- if (iLCIDParam == iDestParam)
- {
- // Set the flags and the type of the parameter.
- pfunc->lprgelemdescParam[iDestParam].paramdesc.wParamFlags = PARAMFLAG_FIN | PARAMFLAG_FLCID;
- pfunc->lprgelemdescParam[iDestParam].tdesc.vt = VT_I4;
-
- // Generate a parameter name.
- sName.Printf(szParamName, iDestParam + 1);
-
- rNames[iDestParam + 1] = SysAllocString(sName.GetUnicode());
- if (rNames[iDestParam + 1] == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- namesHolder[iDestParam+1] = rNames[iDestParam + 1];
-
- ++cNames;
-
- // Increment the current destination parameter.
- ++iDestParam;
- }
-
- // If we are past the end of the source parameters then we are done.
- if (iSrcParam > cSrcParams)
- break;
-
- // Get additional parameter metadata.
- dwParamFlags = 0;
- sName.Clear();
-
- // Error reporting info.
- m_ErrorContext.m_ixParam = iSrcParam;
-
- // See if there is a ParamDef for this param.
- hr = pInternalImport->FindParamOfMethod(pMeth->GetMemberDef(), iSrcParam, &pdParam);
-
- pvNativeType = NULL;
- if (hr == S_OK)
- {
- // Get info about the param.
- IfFailReport(pInternalImport->GetParamDefProps(pdParam, &iSrcParam, &dwParamFlags, &pszName));
-
- // Error reporting info.
- m_ErrorContext.m_szParam = pszName;
-
- // Turn off reserved (internal use) bits.
- dwParamFlags &= ~pdReservedMask;
-
- // Convert name from UTF8 to unicode.
- sName.SetUTF8(pszName);
-
- // Param default value, if any.
- IfFailReport(pInternalImport->GetDefaultValue(pdParam, &defaultValue));
- IfFailReport(_FillVariant(&defaultValue, &pParamDesc->varDefaultValue));
-
- // If no default value, check for decimal custom attribute.
- if (pParamDesc->varDefaultValue.vt == VT_EMPTY)
- {
- IfFailReport(pMT->GetMDImport()->GetCustomAttributeByName(pdParam, INTEROP_DECIMALVALUE_TYPE, &pvData,&cbData));
- if (hr == S_OK && cbData >= (2 + sizeof(BYTE)+sizeof(BYTE)+sizeof(UINT)+sizeof(UINT)+sizeof(UINT)))
- {
- const BYTE *pbData = (const BYTE *)pvData;
- pParamDesc->varDefaultValue.vt = VT_DECIMAL;
- pParamDesc->varDefaultValue.decVal.scale = *(BYTE*)(pbData+2);
- pParamDesc->varDefaultValue.decVal.sign= *(BYTE*)(pbData+3);
- pParamDesc->varDefaultValue.decVal.Hi32= GET_UNALIGNED_32(pbData+4);
- pParamDesc->varDefaultValue.decVal.Mid32= GET_UNALIGNED_32(pbData+8);
- pParamDesc->varDefaultValue.decVal.Lo32= GET_UNALIGNED_32(pbData+12);
- }
- }
- // If still no default value, check for date time custom attribute.
- if (pParamDesc->varDefaultValue.vt == VT_EMPTY)
- {
- IfFailReport(pMT->GetMDImport()->GetCustomAttributeByName(pdParam, INTEROP_DATETIMEVALUE_TYPE, &pvData,&cbData));
- if (hr == S_OK && cbData >= (2 + sizeof(__int64)))
- {
- const BYTE *pbData = (const BYTE *)pvData;
- pParamDesc->varDefaultValue.vt = VT_DATE;
- pParamDesc->varDefaultValue.date = _TicksToDoubleDate(GET_UNALIGNED_64(pbData+2));
- }
- }
- // If still no default value, check for IDispatch custom attribute.
- if (pParamDesc->varDefaultValue.vt == VT_EMPTY)
- {
- IfFailReport(pMT->GetMDImport()->GetCustomAttributeByName(pdParam, INTEROP_IDISPATCHVALUE_TYPE, &pvData,&cbData));
- if (hr == S_OK)
- {
- pParamDesc->varDefaultValue.vt = VT_DISPATCH;
- pParamDesc->varDefaultValue.pdispVal = 0;
- }
- }
- // If still no default value, check for IUnknown custom attribute.
- if (pParamDesc->varDefaultValue.vt == VT_EMPTY)
- {
- IfFailReport(pMT->GetMDImport()->GetCustomAttributeByName(pdParam, INTEROP_IUNKNOWNVALUE_TYPE, &pvData,&cbData));
- if (hr == S_OK)
- {
- pParamDesc->varDefaultValue.vt = VT_UNKNOWN;
- pParamDesc->varDefaultValue.punkVal = 0;
- }
- }
-
- if (pParamDesc->varDefaultValue.vt != VT_EMPTY)
- {
- // Copy the variant into the holder object so we release on function exit.
- vtDefaultValues[iDestParam] = (VARIANT*)&pParamDesc->varDefaultValue;
-
- pfunc->lprgelemdescParam[iDestParam].paramdesc.pparamdescex = pParamDesc;
- dwParamFlags |= PARAMFLAG_FHASDEFAULT;
-
- // Allocate another paramdesc.
- pParamDesc = reinterpret_cast<PARAMDESCEX*>(sVariants.AllocZero(sizeof(PARAMDESCEX)));
- if (pParamDesc == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- bHasOptorDefault = true;
- }
-
- // native marshal type, if any.
- hr = pInternalImport->GetFieldMarshal(pdParam, &pvNativeType, &cbNativeType);
- if (hr != CLDB_E_RECORD_NOTFOUND)
- {
- IfFailReport(hr);
- }
-
- // Remember if there are optional params.
- if (dwParamFlags & PARAMFLAG_FOPT)
- bHasOptorDefault = true;
- }
- else
- {
- pdParam = 0, m_ErrorContext.m_szParam = 0;
- }
-
- // Do we need a name for this parameter?
- if ((pfunc->invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF)) == 0 ||
- iSrcParam < cSrcParams)
- {
- // Yes, so make one up if we don't have one.
- if (sName.GetCount() == 0)
- {
- sName.Printf(szParamName, iDestParam + 1);
- }
-
- rNames[iDestParam + 1] = SysAllocString(sName.GetUnicode());
- if (rNames[iDestParam + 1] == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- namesHolder[iDestParam+1] = rNames[iDestParam + 1];
-
- ++cNames;
- }
-
- // Save the element type.
- CorSigUncompressData(&pbSig[ixSig], &elem);
-
- // Convert the param info to elemdesc.
- bByRef = FALSE;
- hr = CorSigToTypeDesc(pCTI, pMT, &pbSig[ixSig], pvNativeType, cbNativeType, &cbElem,
- &pfunc->lprgelemdescParam[iDestParam].tdesc, &sPool, TRUE, &bByRef);
- if (FAILED(hr))
- return FALSE;
-
- ixSig += cbElem;
-
- // If there is no [in,out], set one, based on the parameter.
- if ((dwParamFlags & (PARAMFLAG_FOUT | PARAMFLAG_FIN)) == 0)
- {
- // If param is by reference, make in/out
- if (bByRef)
- dwParamFlags |= PARAMFLAG_FIN | PARAMFLAG_FOUT;
- else
- dwParamFlags |= PARAMFLAG_FIN;
- }
-
- // If this is the last param, and it an array of objects, and has a ParamArrayAttribute,
- // the function is varargs.
- if ((iSrcParam == cSrcParams) && !IsNilToken(pdParam) && !bHasOptorDefault)
- {
- if (pfunc->lprgelemdescParam[iDestParam].tdesc.vt == VT_SAFEARRAY &&
- pfunc->lprgelemdescParam[iDestParam].tdesc.lpadesc->tdescElem.vt == VT_VARIANT)
- {
- if (pInternalImport->GetCustomAttributeByName(pdParam, INTEROP_PARAMARRAY_TYPE, 0,0) == S_OK)
- pfunc->cParamsOpt = -1;
- }
- }
-
- pfunc->lprgelemdescParam[iDestParam].paramdesc.wParamFlags = static_cast<USHORT>(dwParamFlags);
- }
-
- // Is there a [retval]?
- if (pRetVal)
- {
- // Error reporting info.
- m_ErrorContext.m_ixParam = 0;
- m_ErrorContext.m_szParam = 0;
-
- _ASSERTE(bHrMunge);
- _ASSERTE(cDestParams > cSrcParams);
- pfunc->lprgelemdescParam[cDestParams-1].tdesc.vt = VT_PTR;
- pfunc->lprgelemdescParam[cDestParams-1].tdesc.lptdesc = pRetVal;
- pfunc->lprgelemdescParam[cDestParams-1].paramdesc.wParamFlags = PARAMFLAG_FOUT | PARAMFLAG_FRETVAL;
-
- // no need to allocate a new string for this. rather use the constant szRetVal
- rNames[cDestParams] = (LPWSTR)szRetVal;
-
- ++cNames;
- }
-
- // Error reporting info.
- m_ErrorContext.m_ixParam = -1;
-
- // Was there a signature error? If so, exit now that all sigs have been reported.
- IfFailReport(hrSignature);
-
- IfFailReport(pCTI->AddFuncDesc(iMD, pfunc));
-
- IfFailReport(pCTI->SetFuncAndParamNames(iMD, rNames.Ptr(), cNames));
-
- if (pProps->bFunction2Getter)
- {
- VARIANT vtOne;
- vtOne.vt = VT_I4;
- vtOne.lVal = 1;
- IfFailReport(pCTI->SetFuncCustData(iMD, GUID_Function2Getter, &vtOne));
- }
-
- // If the managed name of the method is different from the unmanaged name, then
- // we need to capture the managed name in a custom value. We only apply this
- // attribute for methods since properties cannot be overloaded.
- if (pProps->semantic == 0)
- {
- sName.SetUTF8(pMeth->GetName());
- if (sName.Compare(SString(pProps->pName)) != 0)
- {
- V_VT(&vtManagedName) = VT_BSTR;
-
- if (NULL == (V_BSTR(&vtManagedName) = SysAllocString(sName.GetUnicode())))
- IfFailReport(E_OUTOFMEMORY);
-
- IfFailReport(pCTI->SetFuncCustData(iMD, GUID_ManagedName, &vtManagedName));
- }
- }
-
- // Check for a description.
- if(GetDescriptionString(pMT, pMeth->GetMemberDef(), (BSTR &)bstrDescr))
- IfFailReport(pCTI->SetFuncDocString(iMD, bstrDescr));
-
-
- // Error reporting info.
- m_ErrorContext.m_szMember = 0;
- m_ErrorContext.m_szParam = 0;
- m_ErrorContext.m_ixParam = -1;
-
- return TRUE;
-} // void TypeLibExporter::ConvertMethod()
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
-//*****************************************************************************
-// Export a Field as getter/setter method's to a typelib.
-//*****************************************************************************
-BOOL TypeLibExporter::ConvertFieldAsMethod(
- ICreateTypeInfo2 *pCTI, // ICreateTypeInfo2 to get the method.
- ComMTMethodProps *pProps, // Some properties of the method.
- ULONG iMD) // Index of the member
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pCTI));
- PRECONDITION(CheckPointer(pProps));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- PCCOR_SIGNATURE pbSig; // Pointer to Cor signature.
- ULONG cbSig; // Size of Cor signature.
- ULONG ixSig; // Index into signature.
- ULONG cbElem; // Size of an element in the signature.
-
- ULONG callconv; // A member's calling convention.
- TYPEDESC *pType; // TYPEDESC for the field type.
- CDescPool sPool; // Pool of memory in which to build funcdesc.
- BSTR rNames[2]; // Array of names to function and parameters.
- ULONG cNames; // Count of function and parameter names.
- FUNCDESC *pfunc; // A funcdesc.
- ComCallMethodDesc *pFieldMeth; // A MethodDesc for a field call.
- FieldDesc *pField; // A FieldDesc.
- IMDInternalImport *pInternalImport; // Internal interface containing the field.
- PCCOR_SIGNATURE pvNativeType; // native field type
- ULONG cbNativeType; // native field type length
- MethodTable *pMT; // Class containing the field.
- BSTRHolder bstrDescr=0; // Description of the method.
-
- // Get info about the method.
- pFieldMeth = reinterpret_cast<ComCallMethodDesc*>(pProps->pMeth);
- pField = pFieldMeth->GetFieldDesc();
- pField->GetSig(&pbSig, &cbSig);
- pInternalImport = pField->GetMDImport();
- pMT = pField->GetEnclosingMethodTable();
-
- // Error reporting info.
- IfFailReport(pMT->GetMDImport()->GetNameOfFieldDef(pField->GetMemberDef(), &m_ErrorContext.m_szMember));
-
- // Prepare to parse signature and build the FUNCDESC.
- pfunc = reinterpret_cast<FUNCDESC*>(sPool.AllocZero(sizeof(FUNCDESC)));
- if (NULL == pfunc)
- IfFailReport(E_OUTOFMEMORY);
- ixSig = 0;
-
- // Get the calling convention.
- ixSig += CorSigUncompressData(&pbSig[ixSig], &callconv);
- _ASSERTE(callconv == IMAGE_CEE_CS_CALLCONV_FIELD);
- pfunc->callconv = CC_STDCALL;
-
- // vtable offset.
- pfunc->oVft = pProps->oVft;
-
- // Set some method properties.
- pfunc->memid = pProps->dispid;
- pfunc->funckind = FUNC_PUREVIRTUAL;
-
- // Set the invkind based on whether the function is an accessor.
- if ((pProps->semantic - FieldSemanticOffset) == msGetter)
- pfunc->invkind = INVOKE_PROPERTYGET;
- else if ((pProps->semantic - FieldSemanticOffset) == msSetter)
- {
- if (IsVbRefType(&pbSig[ixSig], pInternalImport))
- pfunc->invkind = INVOKE_PROPERTYPUTREF;
- else
- pfunc->invkind = INVOKE_PROPERTYPUT;
- }
- else
- _ASSERTE(!"Incorrect semantic in ConvertFieldAsMethod");
-
- // Name of the function.
- rNames[0] = pProps->pName;
- cNames = 1;
-
- // Return type is HRESULT.
- pfunc->elemdescFunc.tdesc.vt = VT_HRESULT;
-
- // Set up the one and only parameter.
- pfunc->lprgelemdescParam = reinterpret_cast<ELEMDESC*>(sPool.AllocZero(sizeof(ELEMDESC)));
- if (NULL == pfunc->lprgelemdescParam)
- IfFailReport(E_OUTOFMEMORY);
- pfunc->cParams = 1;
-
- // Do we need a name for the parameter? If PROPERTYGET, we do.
- if (pfunc->invkind == INVOKE_PROPERTYGET)
- {
- // Yes, so make one up.
- rNames[1] = (WCHAR*)szRetVal;
- ++cNames;
- }
-
- // If Getter, convert param as ptr, otherwise convert directly.
- if (pfunc->invkind == INVOKE_PROPERTYGET)
- {
- pType = reinterpret_cast<TYPEDESC*>(sPool.AllocZero(sizeof(TYPEDESC)));
- if (NULL == pType)
- IfFailReport(E_OUTOFMEMORY);
-
- pfunc->lprgelemdescParam[0].tdesc.vt = VT_PTR;
- pfunc->lprgelemdescParam[0].tdesc.lptdesc = pType;
- pfunc->lprgelemdescParam[0].paramdesc.wParamFlags = PARAMFLAG_FOUT | PARAMFLAG_FRETVAL;
- }
- else
- {
- pType = &pfunc->lprgelemdescParam[0].tdesc;
- pfunc->lprgelemdescParam[0].paramdesc.wParamFlags = PARAMFLAG_FIN;
- }
-
- // Get native field type
- pvNativeType = NULL;
- hr = pInternalImport->GetFieldMarshal(
- pField->GetMemberDef(),
- &pvNativeType,
- &cbNativeType);
- if (hr != CLDB_E_RECORD_NOTFOUND)
- {
- IfFailReport(hr);
- }
-
- // Convert the field type to elemdesc.
- hr = CorSigToTypeDesc(pCTI, pMT, &pbSig[ixSig], pvNativeType, cbNativeType, &cbElem, pType, &sPool, TRUE);
- if (FAILED(hr))
- return FALSE;
-
- ixSig += cbElem;
-
- // It is unfortunate that we can not handle this better. Fortunately
- // this should be very rare.
- // This is a weird case - if we're getting a CARRAY, we cannot add
- // a VT_PTR in the sig, as it will cause the C getter to return an
- // array, which is bad. So we omit the extra pointer, which at least
- // makes the compiler happy.
- if (pfunc->invkind == INVOKE_PROPERTYGET
- && pType->vt == VT_CARRAY)
- {
- pfunc->lprgelemdescParam[0].tdesc.vt = pType->vt;
- pfunc->lprgelemdescParam[0].tdesc.lptdesc = pType->lptdesc;
- }
-
- // A property put of an object should be a propertyputref
- if (pfunc->invkind == INVOKE_PROPERTYPUT &&
- (pType->vt == VT_UNKNOWN || pType->vt == VT_DISPATCH))
- {
- pfunc->invkind = INVOKE_PROPERTYPUTREF;
- }
-
- IfFailReport(pCTI->AddFuncDesc(iMD, pfunc));
-
- IfFailReport(pCTI->SetFuncAndParamNames(iMD, rNames, cNames));
-
- // Check for a description.
- if(GetDescriptionString(pMT, pField->GetMemberDef(), (BSTR &)bstrDescr))
- IfFailReport(pCTI->SetFuncDocString(iMD, bstrDescr));
-
- // Error reporting info.
- m_ErrorContext.m_szMember = 0;
-
- return TRUE;
-} // void TypeLibExporter::ConvertFieldAsMethod()
-
-//*****************************************************************************
-// Export a variable's metadata to a typelib.
-//*****************************************************************************
-BOOL TypeLibExporter::ConvertVariable(
- ICreateTypeInfo2 *pCTI, // ICreateTypeInfo2 to get the variable.
- MethodTable *pMT, // The class containing the variable.
- mdFieldDef md, // The member definition.
- SString& sName, // Name of the member.
- ULONG iMD) // Index of the member
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pCTI));
- PRECONDITION(CheckPointer(pMT));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- PCCOR_SIGNATURE pbSig; // Pointer to Cor signature.
- ULONG cbSig; // Size of Cor signature.
- ULONG ixSig; // Index into signature.
- ULONG cbElem; // Size of an element in the signature.
- DWORD dwFlags; // A member's flags.
- ULONG callconv; // A member's calling convention.
- MDDefaultValue defaultValue; // default value
- ULONG dispid=DISPID_UNKNOWN; // The variable's dispid.
- CDescPool sPool; // Pool of memory in which to build vardesc.
- VARDESC *pvar; // A vardesc.
- PCCOR_SIGNATURE pvNativeType; // native field type
- ULONG cbNativeType; // native field type length
- const void *pvData; // Pointer to a custom attribute.
- ULONG cbData; // Size of custom attribute.
- LPWSTR pSuffix; // Pointer into the name.
- int iSuffix = 0; // Counter for suffix.
- BSTRHolder bstrDescr=0; // Description of the method.
-
- VARIANT vtTemp;
- VariantPtrHolder vtVariant = &vtTemp;
-
- SafeVariantInit(vtVariant);
-
- // Error reporting info.
- IfFailReport(pMT->GetMDImport()->GetNameOfFieldDef(md, &m_ErrorContext.m_szMember));
-
- // Get info about the field.
- IfFailReport(pMT->GetMDImport()->GetDispIdOfMemberDef(md, &dispid));
- IfFailReport(pMT->GetMDImport()->GetFieldDefProps(md, &dwFlags));
- if (IsFdHasDefault(dwFlags))
- {
- IfFailReport(pMT->GetMDImport()->GetDefaultValue(md, &defaultValue));
- IfFailReport( _FillVariant(&defaultValue, vtVariant) );
- }
-
- // If exporting a non-public member of a struct, warn the user.
- if (!IsFdPublic(dwFlags) && !m_bWarnedOfNonPublic)
- {
- m_bWarnedOfNonPublic = TRUE;
- ReportWarning(TLBX_E_NONPUBLIC_FIELD, TLBX_E_NONPUBLIC_FIELD);
- }
-
- IfFailReport(pMT->GetMDImport()->GetSigOfFieldDef(md, &cbSig, &pbSig));
-
- // Prepare to parse signature and build the VARDESC.
- pvar = reinterpret_cast<VARDESC*>(sPool.AllocZero(sizeof(VARDESC)));
- if(pvar == NULL)
- IfFailReport(E_OUTOFMEMORY);
- ixSig = 0;
-
- // Get the calling convention.
- ixSig += CorSigUncompressData(&pbSig[ixSig], &callconv);
- _ASSERTE(callconv == IMAGE_CEE_CS_CALLCONV_FIELD);
-
- // Get native field type
- pvNativeType = NULL;
- hr = pMT->GetMDImport()->GetFieldMarshal(md, &pvNativeType, &cbNativeType);
- if (hr != CLDB_E_RECORD_NOTFOUND)
- {
- IfFailReport(hr);
- }
-
- // Convert the type to elemdesc.
- hr = CorSigToTypeDesc(pCTI, pMT, &pbSig[ixSig], pvNativeType, cbNativeType, &cbElem, &pvar->elemdescVar.tdesc, &sPool, FALSE);
- if (FAILED(hr))
- return FALSE;
-
- ixSig += cbElem;
-
- pvar->wVarFlags = 0;
- pvar->varkind = VAR_PERINSTANCE;
- pvar->memid = dispid;
-
- // Constant value.
- if (vtVariant->vt != VT_EMPTY)
- pvar->lpvarValue = vtVariant;
- else
- {
- IfFailReport(pMT->GetMDImport()->GetCustomAttributeByName(md, INTEROP_DECIMALVALUE_TYPE, &pvData,&cbData));
- if (hr == S_OK && cbData >= (2 + sizeof(BYTE)+sizeof(BYTE)+sizeof(UINT)+sizeof(UINT)+sizeof(UINT)))
- {
- const BYTE *pbData = (const BYTE *)pvData;
- vtVariant->vt = VT_DECIMAL;
- vtVariant->decVal.scale = *(BYTE*)(pbData+2);
- vtVariant->decVal.sign= *(BYTE*)(pbData+3);
- vtVariant->decVal.Hi32= GET_UNALIGNED_32(pbData+4);
- vtVariant->decVal.Mid32= GET_UNALIGNED_32(pbData+8);
- vtVariant->decVal.Lo32= GET_UNALIGNED_32(pbData+12);
- pvar->lpvarValue = vtVariant;
- }
- // If still no default value, check for date time custom attribute.
- if (vtVariant->vt == VT_EMPTY)
- {
- IfFailReport(pMT->GetMDImport()->GetCustomAttributeByName(md, INTEROP_DATETIMEVALUE_TYPE, &pvData,&cbData));
- if (hr == S_OK && cbData >= (2 + sizeof(__int64)))
- {
- const BYTE *pbData = (const BYTE *)pvData;
- vtVariant->vt = VT_DATE;
- vtVariant->date = _TicksToDoubleDate(GET_UNALIGNED_64(pbData+2));
- }
- }
- // If still no default value, check for IDispatch custom attribute.
- if (vtVariant->vt == VT_EMPTY)
- {
- IfFailReport(pMT->GetMDImport()->GetCustomAttributeByName(md, INTEROP_IDISPATCHVALUE_TYPE, &pvData,&cbData));
- if (hr == S_OK)
- {
- vtVariant->vt = VT_DISPATCH;
- vtVariant->pdispVal = 0;
- }
- }
- // If still no default value, check for IUnknown custom attribute.
- if (vtVariant->vt == VT_EMPTY)
- {
- IfFailReport(pMT->GetMDImport()->GetCustomAttributeByName(md, INTEROP_IUNKNOWNVALUE_TYPE, &pvData,&cbData));
- if (hr == S_OK)
- {
- vtVariant->vt = VT_UNKNOWN;
- vtVariant->punkVal = 0;
- }
- }
- }
-
- IfFailReport(pCTI->AddVarDesc(iMD, pvar));
-
- // Set the name for the member; decorate if necessary.
- pSuffix = 0;
- for (;;)
- {
- // Attempt to set the name.
- hr = pCTI->SetVarName(iMD, (LPOLESTR)sName.GetUnicode());
-
- // If a name conflict, decorate, otherwise, done.
- if (hr != TYPE_E_AMBIGUOUSNAME)
- break;
-
- if (iSuffix == 0)
- {
- iSuffix = 2;
- }
- else
- {
- sName.Delete(sName.End()-=2, 2);
- }
-
- SString sDup;
- sDup.Printf(szDuplicateDecoration, iSuffix++);
-
- sName.Append(sDup);
- }
- IfFailReport(hr);
-
- // Check for a description.
- if(GetDescriptionString(pMT, md, (BSTR &)bstrDescr))
- IfFailReport(pCTI->SetVarDocString(iMD, bstrDescr));
-
- // Error reporting info.
- m_ErrorContext.m_szMember = 0;
-
- return TRUE;
-} // HRESULT TypeLibExporter::ConvertVariable()
-
-//*****************************************************************************
-// Export a variable's metadata to a typelib.
-//*****************************************************************************
-BOOL TypeLibExporter::ConvertEnumMember(
- ICreateTypeInfo2 *pCTI, // ICreateTypeInfo2 to get the variable.
- MethodTable *pMT, // The Class containing the member.
- mdFieldDef md, // The member definition.
- SString& sName, // Name of the member.
- ULONG iMD) // Index of the member
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pCTI));
- PRECONDITION(CheckPointer(pMT));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- LPCUTF8 pName, pNS; // To format name.
- DWORD dwFlags; // A member's flags.
- VARIANT vtVariant; // A Variant.
- MDDefaultValue defaultValue; // default value
- ULONG dispid=DISPID_UNKNOWN; // The variable's dispid.
- CDescPool sPool; // Pool of memory in which to build vardesc.
- VARDESC *pvar; // A vardesc.
- BSTRHolder bstrDescr=0; // Description of the method.
-
- vtVariant.vt = VT_EMPTY;
-
- // Error reporting info.
- IfFailReport(pMT->GetMDImport()->GetNameOfFieldDef(md, &m_ErrorContext.m_szMember));
-
- // Get info about the field.
- IfFailReport(pMT->GetMDImport()->GetDispIdOfMemberDef(md, &dispid));
- IfFailReport(pMT->GetMDImport()->GetFieldDefProps(md, &dwFlags));
-
- // We do not need to handle decimal's here since enum's can only be integral types.
- IfFailReport(pMT->GetMDImport()->GetDefaultValue(md, &defaultValue));
-
- // Prepare to parse signature and build the VARDESC.
- pvar = reinterpret_cast<VARDESC*>(sPool.AllocZero(sizeof(VARDESC)));
- if (NULL == pvar)
- IfFailReport(E_OUTOFMEMORY);
-
- IfFailReport( _FillVariant(&defaultValue, &vtVariant) );
-
- // Don't care what the metadata says the type is -- the type is I4 in the typelib.
- pvar->elemdescVar.tdesc.vt = VT_I4;
-
- pvar->wVarFlags = 0;
- pvar->varkind = VAR_CONST;
- pvar->memid = dispid;
-
- // Constant value.
- if (vtVariant.vt != VT_EMPTY)
- {
- pvar->lpvarValue = &vtVariant;
-
- // If this is an I8 or UI8, do the conversion manually, because some
- // systems' oleaut32 don't support 64-bit integers.
- if (vtVariant.vt == VT_I8)
- {
- // If withing range of 32-bit signed number, OK.
- if (vtVariant.llVal <= LONG_MAX && vtVariant.llVal >= LONG_MIN)
- vtVariant.vt = VT_I4, hr = S_OK;
- else
- hr = E_FAIL;
- }
- else if (vtVariant.vt == VT_UI8)
- {
- // If withing range of 32-bit unsigned number, OK.
- if (vtVariant.ullVal <= ULONG_MAX)
- vtVariant.vt = VT_UI4, hr = S_OK;
- else
- hr = E_FAIL;
- }
- else
- {
- hr = SafeVariantChangeTypeEx(&vtVariant, &vtVariant, 0, 0, VT_I4);
- }
-
- if (FAILED(hr))
- {
- if (FAILED(pMT->GetMDImport()->GetNameOfTypeDef(pMT->GetCl(), &pName, &pNS)))
- {
- pName = pNS = "Invalid TypeDef record";
- }
- ReportWarning(TLBX_W_ENUM_VALUE_TOOBIG, TLBX_W_ENUM_VALUE_TOOBIG, pName, sName.GetUnicode());
- return FALSE;
- }
- }
- else
- { // No value assigned, use 0.
- pvar->lpvarValue = &vtVariant;
- vtVariant.vt = VT_I4;
- vtVariant.lVal = 0;
- }
-
- IfFailReport(pCTI->AddVarDesc(iMD, pvar));
- IfFailReport(pCTI->SetVarName(iMD, (LPOLESTR)sName.GetUnicode()));
-
- // Check for a description.
- if(GetDescriptionString(pMT, md, (BSTR &)bstrDescr))
- IfFailReport(pCTI->SetVarDocString(iMD, bstrDescr));
-
- // Error reporting info.
- m_ErrorContext.m_szMember = 0;
-
- return TRUE;
-} // void TypeLibExporter::ConvertEnumMember()
-
-//*****************************************************************************
-// Given a COM+ signature of a field or property, determine if it should
-// be a PROPERTYPUT or PROPERTYPUTREF.
-//*****************************************************************************
-BOOL TypeLibExporter::IsVbRefType(
- PCCOR_SIGNATURE pbSig,
- IMDInternalImport *pInternalImport)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pInternalImport));
- }
- CONTRACTL_END;
-
- ULONG elem=0; // An element from a COM+ signature.
- ULONG cbElem=0;
-
- cbElem = CorSigUncompressData(pbSig, &elem);
- if (elem == ELEMENT_TYPE_PTR || elem == ELEMENT_TYPE_BYREF)
- {
- return IsVbRefType(&pbSig[cbElem], pInternalImport);
- }
- else
- {
- switch (elem)
- {
- // For documentation -- arrays are NOT ref types here.
- //case ELEMENT_TYPE_SDARRAY:
- //case ELEMENT_TYPE_ARRAY:
- //case ELEMENT_TYPE_SZARRAY:
- // Look for variant.
- case ELEMENT_TYPE_VALUETYPE:
- return FALSE;
-
- case ELEMENT_TYPE_CLASS:
- return TRUE;
-
- case ELEMENT_TYPE_OBJECT:
- return FALSE;
-
- default:
- break;
- }
- }
-
- return FALSE;
-} // BOOL TypeLibExporter::IsVbRefType()
-
-BOOL TypeLibExporter::IsExportingAs64Bit()
-{
- LIMITED_METHOD_CONTRACT;
- if (TlbExportAs64Bit(m_flags))
- {
- return TRUE;
- }
- else if (TlbExportAs32Bit(m_flags))
- {
- return FALSE;
- }
- else
- {
-#ifdef _WIN64
- return TRUE;
-#else
- return FALSE;
-#endif
- }
-} // BOOL TypeLibExporter::IsExportingAs64Bit()
-
-void TypeLibExporter::ArrayToTypeDesc(ICreateTypeInfo2 *pCTI, CDescPool *ppool, ArrayMarshalInfo *pArrayMarshalInfo, TYPEDESC *ptdesc)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pCTI));
- PRECONDITION(CheckPointer(ppool));
- PRECONDITION(CheckPointer(pArrayMarshalInfo));
- PRECONDITION(CheckPointer(ptdesc));
- }
- CONTRACTL_END;
-
- HRESULT hr = E_FAIL;
- VARTYPE vtElement = pArrayMarshalInfo->GetElementVT();
- TypeHandle thElement = pArrayMarshalInfo->GetElementTypeHandle();
-
- if (vtElement == VT_RECORD)
- {
- // We are dealing with an array of embedded structures.
- ptdesc->vt = VT_USERDEFINED;
- EEClassToHref(pCTI, thElement.GetMethodTable(), FALSE, &ptdesc->hreftype);
- }
- else if ((vtElement == VT_UNKNOWN || vtElement == VT_DISPATCH) && !thElement.IsObjectType())
- {
- if (!thElement.IsValueType() && !pArrayMarshalInfo->IsSafeArraySubTypeExplicitlySpecified())
- {
- // We are dealing with an array of user defined interfaces.
- ptdesc->vt = VT_PTR;
- ptdesc->lptdesc = reinterpret_cast<TYPEDESC*>(ppool->AllocZero(sizeof(TYPEDESC)));
- if (ptdesc->lptdesc == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- ptdesc->lptdesc->vt = VT_USERDEFINED;
- EEClassToHref(pCTI, thElement.GetMethodTable(), FALSE, &ptdesc->lptdesc->hreftype);
- }
- else
- {
- // The user specified that the array of value classes be converted to an
- // array of IUnknown or IDispatch pointers.
- ptdesc->vt = vtElement;
- }
- }
- else if (pArrayMarshalInfo->IsPtr())
- {
- ptdesc->vt = VT_PTR;
- ptdesc->lptdesc = reinterpret_cast<TYPEDESC*>(ppool->AllocZero(sizeof(TYPEDESC)));
- if (ptdesc->lptdesc == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- ptdesc->lptdesc->vt = vtElement;
- }
- else
- {
- // We are dealing with an array of primitive types.
- ptdesc->vt = vtElement;
- }
-}
-// HRESULT ArrayToTypeDesc(ArrayMarshalInfo *pArrayMarshalInfo, TYPEDESC *pElementTypeDesc)
-
-VARTYPE TypeLibExporter::GetVtForIntPtr()
-{
- WRAPPER_NO_CONTRACT;
-
- return static_cast<VARTYPE>(IsExportingAs64Bit() ? VT_I8 : VT_I4);
-} // VARTYPE TypeLibExporter::GetVtForIntPtr()
-
-VARTYPE TypeLibExporter::GetVtForUIntPtr()
-{
- WRAPPER_NO_CONTRACT;
-
- return static_cast<VARTYPE>(IsExportingAs64Bit() ? VT_UI8 : VT_UI4);
-} // VARTYPE TypeLibExporter::GetVtForUIntPtr()
-
-/*
-BOOL TypeLibExporter::ValidateSafeArrayElemVT(VARTYPE vt)
-{
- switch(vt)
- {
- case VT_I2:
- case VT_I4:
- case VT_R4:
- case VT_R8:
- case VT_CY:
- case VT_DATE:
- case VT_BSTR:
- case VT_DISPATCH:
- case VT_ERROR:
- case VT_BOOL:
- case VT_VARIANT:
- case VT_UNKNOWN:
- case VT_DECIMAL:
- case VT_RECORD:
- case VT_I1:
- case VT_UI1:
- case VT_UI2:
- case VT_UI4:
- case VT_INT:
- case VT_UINT:
- return TRUE;
-
- default:
- return FALSE;
- }
-}
-*/
-
-//*****************************************************************************
-// Read a COM+ signature element and create a TYPEDESC that corresponds
-// to it.
-//*****************************************************************************
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
-#endif
-HRESULT TypeLibExporter::CorSigToTypeDesc(
- ICreateTypeInfo2 *pCTI, // Typeinfo being created.
- MethodTable *pMT, // MethodTable with the token.
- PCCOR_SIGNATURE pbSig, // Pointer to the Cor Signature.
- PCCOR_SIGNATURE pbNativeSig, // Pointer to the native sig, if any
- ULONG cbNativeSig, // Count of bytes in native sig.
- ULONG *pcbElem, // Put # bytes consumed here.
- TYPEDESC *ptdesc, // Build the typedesc here.
- CDescPool *ppool, // Pool for additional storage as required.
- BOOL bMethodSig, // TRUE if the sig is for a method, FALSE for a field.
- BOOL *pbByRef) // If not null, and the type is byref, set to true.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pCTI));
- PRECONDITION(CheckPointer(pMT));
- PRECONDITION(CheckPointer(pcbElem));
- PRECONDITION(CheckPointer(ptdesc));
- PRECONDITION(CheckPointer(ppool));
- PRECONDITION(CheckPointer(pbByRef, NULL_OK));
- }
- CONTRACTL_END;
-
- HRESULT hr=S_OK;
- ULONG elem = 0; // The element type.
- ULONG cbElem = 0; // Bytes in the element.
- ULONG cb; // Bytes in a sub-element.
- ULONG cbNativeElem = 0; // # of bytes parsed off of native type.
- ULONG nativeElem = 0; // The native element type
- ULONG nativeCount; // The native element size
- mdToken tkTypeRef; // Token for a TypeRef/TypeDef
- SString sName; // Buffer to build a name from NS/Name.
- LPCUTF8 pclsname; // Class name for ELEMENT_TYPE_CLASS.
- HREFTYPE hRef = 0; // HREF to some type.
- IMDInternalImport *pInternalImport; // Internal interface containing the signature.
- Module* pModule = NULL; // Module containing the signature.
- int i; // Loop control.
- SigTypeContext emptyTypeContext; // an empty type context is sufficient: all methods should be non-generic
- ULONG dwTypeFlags = 0; // The type flags.
- BOOL fAnsi = FALSE; // Is the structure marked as CharSet=Ansi.
- BOOL fIsStringBuilder = FALSE;
- LPCUTF8 pNS;
-
-
- pInternalImport = pMT->GetMDImport();
- pModule = pMT->GetModule();
-
- // Just be sure the count is zero if the pointer is.
- if (pbNativeSig == NULL)
- cbNativeSig = 0;
-
- // Grab the native marshaling type.
- if (cbNativeSig > 0)
- {
- cbNativeElem = CorSigUncompressData(pbNativeSig, &nativeElem);
- pbNativeSig += cbNativeElem;
- cbNativeSig -= cbNativeElem;
-
- // AsAny makes no sense for COM Interop. Ignore it.
- if (nativeElem == NATIVE_TYPE_ASANY)
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_ASANY);
- nativeElem = 0;
- }
- }
-
- // If we are dealing with a struct, determine if it is marked as CharSet=Ansi.
- if (!bMethodSig)
- {
- // Make sure one of Auto, Ansi or Unicode is specified.
- if (!IsTdAnsiClass(dwTypeFlags) && !IsTdAutoClass(dwTypeFlags) && !IsTdUnicodeClass(dwTypeFlags))
- {
- _ASSERTE(!"Bad stringformat value in wrapper class.");
- ReportWarning(TLBX_E_BAD_SIGNATURE, E_FAIL); // bad metadata
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- if (FAILED(pInternalImport->GetTypeDefProps(pMT->GetCl(), &dwTypeFlags, NULL)))
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, E_FAIL);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
- fAnsi = IsTdAnsiClass(dwTypeFlags);
- }
-
- // Get the element type.
-TryAgain:
- cbElem += CorSigUncompressData(pbSig+cbElem, &elem);
-
- // Handle the custom marshaler native type separately.
- if (elem != ELEMENT_TYPE_BYREF && nativeElem == NATIVE_TYPE_CUSTOMMARSHALER)
- {
- switch(elem)
- {
- case ELEMENT_TYPE_VAR:
- case ELEMENT_TYPE_CLASS:
- case ELEMENT_TYPE_OBJECT:
- // @TODO(DM): Ask the custom marshaler for the ITypeInfo to use for the unmanaged type.
- ptdesc->vt = VT_UNKNOWN;
- break;
-
- case ELEMENT_TYPE_STRING:
- case ELEMENT_TYPE_SZARRAY:
- case ELEMENT_TYPE_ARRAY:
- ptdesc->vt = GetVtForIntPtr();
- break;
-
- default:
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- return(TLBX_E_BAD_SIGNATURE);
- break;
- }
-
- // Eat the rest of the signature. The extra -1's are to account
- // for the byte parsed off above.
- SigPointer p(&pbSig[cbElem-1]);
- IfFailThrow(p.SkipExactlyOne());
- cbElem += (ULONG)(p.GetPtr() - &pbSig[cbElem]); // Note I didn't use -1 here.
- goto ExitFunc;
- }
-
-// This label is used to try again with a new element type, but without consuming more signature.
-// Usage is to set 'elem' to a new value, goto this label.
-TryWithElemType:
- switch (elem)
- {
- case ELEMENT_TYPE_END: // 0x0,
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_UNKNOWN_SIGNATURE);
- return(TLBX_E_BAD_SIGNATURE);
- break;
-
- case ELEMENT_TYPE_VOID: // 0x1,
- ptdesc->vt = VT_VOID;
- break;
-
- case ELEMENT_TYPE_BOOLEAN: // 0x2,
- switch (nativeElem)
- {
- case 0:
- ptdesc->vt = static_cast<VARTYPE>(bMethodSig ? VT_BOOL : VT_I4);
- break;
-
- case NATIVE_TYPE_VARIANTBOOL:
- ptdesc->vt = VT_BOOL;
- break;
-
- case NATIVE_TYPE_BOOLEAN:
- ptdesc->vt = VT_I4;
- break;
-
- case NATIVE_TYPE_U1:
- case NATIVE_TYPE_I1:
- ptdesc->vt = VT_UI1;
- break;
-
- default:
- DEBUG_STMT(DbgWriteEx(W("Bad Native COM attribute specified!\n")));
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- return(TLBX_E_BAD_SIGNATURE);
- }
- break;
-
- case ELEMENT_TYPE_CHAR: // 0x3,
- if (nativeElem == 0)
- {
- if (!bMethodSig && IsTdAutoClass(dwTypeFlags))
- {
- // Types with a char set of auto and that would be represented differently
- // on different platforms are not allowed to be exported to COM.
- DefineFullyQualifiedNameForClassW();
- LPCWSTR szName = GetFullyQualifiedNameForClassW(pMT);
- _ASSERTE(szName);
-
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_AUTO_CS_NOT_ALLOWED, szName);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- ptdesc->vt = static_cast<VARTYPE>(fAnsi ? VT_UI1 : VT_UI2);
- }
- else
- {
- switch (nativeElem)
- {
- case 0:
- case NATIVE_TYPE_U2:
- case NATIVE_TYPE_I2:
- ptdesc->vt = VT_UI2;
- break;
-
- case NATIVE_TYPE_U1:
- case NATIVE_TYPE_I1:
- ptdesc->vt = VT_UI1;
- break;
-
- default:
- DEBUG_STMT(DbgWriteEx(W("Bad Native COM attribute specified!\n")));
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
- }
- break;
-
- case ELEMENT_TYPE_I1: // 0x4,
- ptdesc->vt = VT_I1;
- break;
-
- case ELEMENT_TYPE_U1: // 0x5,
- ptdesc->vt = VT_UI1;
- break;
-
- case ELEMENT_TYPE_I2: // 0x6,
- ptdesc->vt = VT_I2;
- break;
-
- case ELEMENT_TYPE_U2: // 0x7,
- ptdesc->vt = VT_UI2;
- break;
-
- case ELEMENT_TYPE_I4: // 0x8,
- switch (nativeElem)
- {
- case 0:
- case NATIVE_TYPE_I4:
- case NATIVE_TYPE_U4: case NATIVE_TYPE_INTF: //@todo: Fix Microsoft.Win32.Interop.dll and remove this line.
- ptdesc->vt = VT_I4;
- break;
-
- case NATIVE_TYPE_ERROR:
- ptdesc->vt = VT_HRESULT;
- break;
-
- default:
- DEBUG_STMT(DbgWriteEx(W("Bad Native COM attribute specified!\n")));
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
- break;
-
- case ELEMENT_TYPE_U4: // 0x9,
- switch (nativeElem)
- {
- case 0:
- case NATIVE_TYPE_U4:
- ptdesc->vt = VT_UI4;
- break;
-
- case NATIVE_TYPE_ERROR:
- ptdesc->vt = VT_HRESULT;
- break;
-
- default:
- DEBUG_STMT(DbgWriteEx(W("Bad Native COM attribute specified!\n")));
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
- break;
-
- case ELEMENT_TYPE_I8: // 0xa,
- ptdesc->vt = VT_I8;
- break;
-
- case ELEMENT_TYPE_U8: // 0xb,
- ptdesc->vt = VT_UI8;
- break;
-
- case ELEMENT_TYPE_R4: // 0xc,
- ptdesc->vt = VT_R4;
- break;
-
- case ELEMENT_TYPE_R8: // 0xd,
- ptdesc->vt = VT_R8;
- break;
-
- case ELEMENT_TYPE_OBJECT:
- goto IsObject;
-
- case ELEMENT_TYPE_STRING: // 0xe,
- IsString:
- if (nativeElem == 0)
- {
- if (bMethodSig)
- {
- ptdesc->vt = VT_BSTR;
- }
- else
- {
- if (IsTdAutoClass(dwTypeFlags))
- {
- // Types with a char set of auto and that would be represented differently
- // on different platforms are not allowed to be exported to COM.
- DefineFullyQualifiedNameForClassW();
- LPCWSTR szName = GetFullyQualifiedNameForClassW(pMT);
- _ASSERTE(szName);
-
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_AUTO_CS_NOT_ALLOWED, szName);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- ptdesc->vt = static_cast<VARTYPE>(fAnsi ? VT_LPSTR : VT_LPWSTR);
- }
- }
- else
- {
- switch (nativeElem)
- {
- case NATIVE_TYPE_BSTR:
- if (fIsStringBuilder)
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
- ptdesc->vt = VT_BSTR;
- break;
-
- case NATIVE_TYPE_LPSTR:
- ptdesc->vt = VT_LPSTR;
- break;
-
- case NATIVE_TYPE_LPWSTR:
- ptdesc->vt = VT_LPWSTR;
- break;
-
- case NATIVE_TYPE_LPTSTR:
- {
- // NATIVE_TYPE_LPTSTR is not allowed to be exported to COM.
- DefineFullyQualifiedNameForClassW();
- LPCWSTR szName = GetFullyQualifiedNameForClassW(pMT);
- _ASSERTE(szName);
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_LPTSTR_NOT_ALLOWED, szName);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
- case NATIVE_TYPE_FIXEDSYSSTRING:
- // NATIVE_TYPE_FIXEDSYSSTRING is only allowed on fields.
- if (bMethodSig)
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- // Retrieve the count of characters.
- if (cbNativeSig != 0)
- {
- cb = CorSigUncompressData(pbNativeSig, &nativeCount);
- pbNativeSig += cb;
- cbNativeSig -= cb;
- }
- else
- {
- nativeCount = 0;
- }
-
- // Fixed strings become embedded array's of characters.
- ptdesc->vt = VT_CARRAY;
- ptdesc->lpadesc = reinterpret_cast<ARRAYDESC*>(ppool->AllocZero(sizeof(ARRAYDESC)));
- if (ptdesc->lpadesc == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- // Set the count of characters.
- ptdesc->lpadesc->cDims = 1;
- ptdesc->lpadesc->rgbounds[0].cElements = nativeCount;
- ptdesc->lpadesc->rgbounds[0].lLbound = 0;
-
- if (IsTdAutoClass(dwTypeFlags))
- {
- // Types with a char set of auto and that would be represented differently
- // on different platforms are not allowed to be exported to COM.
- DefineFullyQualifiedNameForClassW();
- LPCWSTR szName = GetFullyQualifiedNameForClassW(pMT);
- _ASSERTE(szName);
-
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_AUTO_CS_NOT_ALLOWED, szName);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- ptdesc->lpadesc->tdescElem.vt = static_cast<VARTYPE>(fAnsi ? VT_UI1 : VT_UI2);
- break;
-
- default:
- DEBUG_STMT(DbgWriteEx(W("Bad Native COM attribute specified!\n")));
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
- }
- break;
-
- // every type above PTR will be simple type
- case ELEMENT_TYPE_PTR: // 0xf,
- case ELEMENT_TYPE_BYREF: // 0x10,
- // TYPEDESC is a pointer.
- ptdesc->vt = VT_PTR;
- if (pbByRef)
- *pbByRef = TRUE;
-
- // Pointer to what?
- ptdesc->lptdesc = reinterpret_cast<TYPEDESC*>(ppool->AllocZero(sizeof(TYPEDESC)));
- if (ptdesc->lptdesc == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- hr = CorSigToTypeDesc(pCTI, pMT, &pbSig[cbElem], pbNativeSig-cbNativeElem,
- cbNativeSig+cbNativeElem, &cb, ptdesc->lptdesc, ppool, bMethodSig);
- cbElem += cb;
-
- if (FAILED(hr))
- goto ExitFunc;
-
- break;
-
- case ELEMENT_TYPE_CLASS: // 0x12,
- case ELEMENT_TYPE_VALUETYPE:
- // Get the TD/TR.
- cb = CorSigUncompressToken(&pbSig[cbElem], &tkTypeRef);
- cbElem += cb;
-
- if (TypeFromToken(tkTypeRef) == mdtTypeDef)
- {
- // Get the name of the TypeDef.
- if (FAILED(pInternalImport->GetNameOfTypeDef(tkTypeRef, &pclsname, &pNS)))
- {
- IfFailReport(COR_E_BADIMAGEFORMAT);
- }
- }
- else
- {
- // Get the name of the TypeRef.
- _ASSERTE(TypeFromToken(tkTypeRef) == mdtTypeRef);
- IfFailReport(pInternalImport->GetNameOfTypeRef(tkTypeRef, &pNS, &pclsname));
- }
-
- if (pNS)
- {
- sName.MakeFullNamespacePath(SString(SString::Utf8, pNS), SString(SString::Utf8, pclsname));
- StackScratchBuffer scratch;
- pclsname = sName.GetUTF8(scratch);
- }
-
- _ASSERTE(strlen(szRuntime) == cbRuntime); // If you rename System, fix this invariant.
- _ASSERTE(strlen(szText) == cbText); // If you rename System.Text, fix this invariant.
-
- // Is it System.something?
- if (SString::_strnicmp(pclsname, szRuntime, cbRuntime) == 0)
- {
- // Which one?
- LPCUTF8 pcls; pcls = pclsname + cbRuntime;
- if (stricmpUTF8(pcls, szStringClass) == 0)
- {
- goto IsString;
- }
- else if (stricmpUTF8(pcls, szDateTimeClass) == 0)
- {
- ptdesc->vt = VT_DATE;
- goto ExitFunc;
- }
- else if (stricmpUTF8(pcls, szDecimalClass) == 0)
- {
- switch (nativeElem)
- {
- case NATIVE_TYPE_CURRENCY:
- // Make this a currency.
- ptdesc->vt = VT_CY;
- break;
-
- case 0:
- // Make this a decimal
- ptdesc->vt = VT_DECIMAL;
- break;
-
- default:
- DEBUG_STMT(DbgWriteEx(W("Bad Native COM attribute specified!\n")));
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
- goto ExitFunc;
- }
- else if (stricmpUTF8(pcls, szGuidClass) == 0)
- {
- switch (nativeElem)
- {
- case NATIVE_TYPE_LPSTRUCT:
- // Make this a pointer to . . .
- ptdesc->vt = VT_PTR;
- if (pbByRef)
- *pbByRef = TRUE;
-
- ptdesc->lptdesc = reinterpret_cast<TYPEDESC*>(ppool->AllocZero(sizeof(TYPEDESC)));
- if (ptdesc->lptdesc == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- // . . . a user defined type for GUID
- ptdesc->lptdesc->vt = VT_USERDEFINED;
- GetRefTypeInfo(pCTI, m_pGuid, &ptdesc->lptdesc->hreftype);
- break;
-
- case 0:
- case NATIVE_TYPE_STRUCT:
- // a user defined type for GUID
- ptdesc->vt = VT_USERDEFINED;
- GetRefTypeInfo(pCTI, m_pGuid, &ptdesc->hreftype);
- break;
-
- default:
- DEBUG_STMT(DbgWriteEx(W("Bad Native COM attribute specified!\n")));
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
- goto ExitFunc;
- }
- else if (stricmpUTF8(pcls, szArrayClass) == 0)
- {
- // If no native type is specified then assume its a NATIVE_TYPE_INTF.
- if (nativeElem == 0)
- nativeElem = NATIVE_TYPE_INTF;
-
- if (nativeElem == NATIVE_TYPE_SAFEARRAY)
- {
- // Compat: If no safe array used def subtype was specified we will map it to a SAFEARRAY of VARIANTs.
- ULONG vtElement = VT_VARIANT;
- TypeHandle thElement = TypeHandle(g_pObjectClass);
-
- if (cbNativeSig > 0)
- {
- // Retrieve the safe array sub type.
- cb = CorSigUncompressData(pbNativeSig, &vtElement);
- pbNativeSig += cb;
- cbNativeSig -= cb;
-
- // Get the type name if specified.
- if (cbNativeSig > 0)
- {
- ULONG cbClass = 0;
-
- cb = CorSigUncompressData(pbNativeSig, &cbClass);
- pbNativeSig += cb;
- cbNativeSig -= cb;
-
- if (cbClass > 0)
- {
- // Load the type. Use an SString for the string since we need to NULL terminate the string
- // that comes from the metadata.
- StackScratchBuffer utf8Name;
- SString safeArrayUserDefTypeName(SString::Utf8, (LPUTF8)pbNativeSig, cbClass);
- thElement = LoadClass(pMT->GetModule(), safeArrayUserDefTypeName.GetUTF8(utf8Name));
- }
- }
- }
- else
- {
- if (!bMethodSig)
- {
- // The field marshaller converts these to SAFEARRAYs of the type specified
- // at runtime by the array. This isn't expressible in a type library
- // so provide a warning.
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_W_BAD_SAFEARRAYFIELD_NO_ELEMENTVT);
- }
- }
-
- ArrayMarshalInfo arrayMarshalInfo(IsExportingAs64Bit() ? amiExport64Bit : amiExport32Bit);
- MarshalInfo::MarshalScenario ms = bMethodSig ? MarshalInfo::MARSHAL_SCENARIO_COMINTEROP : MarshalInfo::MARSHAL_SCENARIO_FIELD;
- arrayMarshalInfo.InitForSafeArray(ms, thElement, (VARTYPE)vtElement, fAnsi);
-
- if (!arrayMarshalInfo.IsValid())
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, arrayMarshalInfo.GetErrorResourceId());
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- // TYPEDESC is an array.
- ptdesc->vt = VT_SAFEARRAY;
- ptdesc->lptdesc = reinterpret_cast<TYPEDESC*>(ppool->AllocZero(sizeof(TYPEDESC)));
- if (ptdesc->lptdesc == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- ArrayToTypeDesc(pCTI, ppool, &arrayMarshalInfo, ptdesc->lptdesc);
-
- goto ExitFunc;
- }
- else if (nativeElem == NATIVE_TYPE_FIXEDARRAY)
- {
- // NATIVE_TYPE_FIXEDARRAY is only allowed on fields.
- if (bMethodSig)
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- // Retrieve the size of the fixed array. This is required.
- if (cbNativeSig == 0)
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, IDS_EE_BADMARSHALFIELD_FIXEDARRAY_NOSIZE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- cb = CorSigUncompressData(pbNativeSig, &nativeCount);
- pbNativeSig += cb;
- cbNativeSig -= cb;
-
- // A size const of 0 isn't supported.
- if (nativeCount == 0)
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, IDS_EE_BADMARSHALFIELD_FIXEDARRAY_ZEROSIZE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- // Since these always export to arrays of BSTRs, we don't need to fetch the native type.
-
- // Set the data
- ptdesc->vt = VT_CARRAY;
- ptdesc->lpadesc = NULL;
- ptdesc->lpadesc = reinterpret_cast<ARRAYDESC*>(ppool->AllocZero(sizeof(ARRAYDESC)));
- if (ptdesc->lpadesc == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- // Compat: FixedArrays of System.Arrays map to fixed arrays of BSTRs.
- ptdesc->lpadesc->tdescElem.vt = VT_BSTR;
- ptdesc->lpadesc->cDims = 1;
- ptdesc->lpadesc->rgbounds->cElements = nativeCount;
- ptdesc->lpadesc->rgbounds->lLbound = 0;
-
- goto ExitFunc;
- }
- else if (nativeElem != NATIVE_TYPE_INTF)
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- // If the native type is NATIVE_TYPE_INTF then we fall through and convert
- // System.Array to its IClassX interface.
- }
- else if (stricmpUTF8(pcls, szObjectClass) == 0)
- {
- IsObject:
- // This next statement is to work around a "feature" that marshals an object inside
- // a struct as an interface, instead of as a variant. fieldmarshal metadata
- // can override that.
- if (nativeElem == 0 && !bMethodSig)
- nativeElem = NATIVE_TYPE_IUNKNOWN;
-
- switch (nativeElem)
- {
- case NATIVE_TYPE_INTF:
- case NATIVE_TYPE_IUNKNOWN:
- // an IUnknown based interface.
- ptdesc->vt = VT_UNKNOWN;
- break;
-
- case NATIVE_TYPE_IDISPATCH:
- // an IDispatch based interface.
- ptdesc->vt = VT_DISPATCH;
- break;
-
- case 0:
- case NATIVE_TYPE_STRUCT:
- // a VARIANT
- ptdesc->vt = VT_VARIANT;
- break;
-
- default:
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
- goto ExitFunc;
- }
- } // System
-
- if (SString::_strnicmp(pclsname, szText, cbText) == 0)
- {
- LPCUTF8 pcls; pcls = pclsname + cbText;
- if (stricmpUTF8(pcls, szStringBufferClass) == 0)
- {
- fIsStringBuilder = TRUE;
-
- // If there is no fieldmarshal information, marshal as a LPWSTR
- if (nativeElem == 0)
- nativeElem = NATIVE_TYPE_LPWSTR;
-
- // Marshaller treats stringbuilders as [in, out] by default.
- if (pbByRef)
- *pbByRef = TRUE;
-
- goto IsString;
- }
- } // System.Text
-
- if (SString::_strnicmp(pclsname, szCollections, cbCollections) == 0)
- {
- LPCUTF8 pcls; pcls = pclsname + cbCollections;
- if (stricmpUTF8(pcls, szIEnumeratorClass) == 0)
- {
- StdOleTypeToHRef(pCTI, IID_IEnumVARIANT, &hRef);
- ptdesc->vt = VT_PTR;
- ptdesc->lptdesc = reinterpret_cast<TYPEDESC*>(ppool->AllocZero(sizeof(TYPEDESC)));
- if (ptdesc->lptdesc == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- ptdesc->lptdesc->vt = VT_USERDEFINED;
- ptdesc->lptdesc->hreftype = hRef;
- goto ExitFunc;
- }
- } // System.Collections
-
- if (SString::_strnicmp(pclsname, szDrawing, cbDrawing) == 0)
- {
- LPCUTF8 pcls; pcls = pclsname + cbDrawing;
- if (stricmpUTF8(pcls, szColor) == 0)
- {
- StdOleTypeToHRef(pCTI, GUID_OleColor, &hRef);
- ptdesc->vt = VT_USERDEFINED;
- ptdesc->hreftype = hRef;
- goto ExitFunc;
- }
- } // System.Drawing
-
- // It is not a built-in VT type, so build the typedesc.
-
- // Determine whether the type is a reference type (IUnknown derived) or a struct type.
- // Get the MethodTable for the referenced class.
- MethodTable *pRefdClass; // MethodTable object for referenced TypeDef.
- pRefdClass = LoadClass(pMT->GetModule(), tkTypeRef);
-
- // Is the type a ref type or a struct type. Note that a ref type that has layout
- // is exported as a TKIND_RECORD but is referenced as a **Foo, whereas a
- // value type is also exported as a TKIND_RECORD but is referenced as a *Foo.
- if (elem == ELEMENT_TYPE_CLASS)
- {
- // Check if it is a delegate (which can be marshaled as a function pointer).
- if (COMDelegate::IsDelegate(pRefdClass))
- {
- if (nativeElem == NATIVE_TYPE_FUNC)
- {
- ptdesc->vt = GetVtForIntPtr();
- goto ExitFunc;
- }
- else if (nativeElem != 0 && nativeElem != NATIVE_TYPE_INTF)
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
- }
- else if (TypeHandle(pRefdClass).CanCastTo(TypeHandle(MscorlibBinder::GetClass(CLASS__SAFE_HANDLE))))
- {
- ptdesc->vt = GetVtForIntPtr();
- goto ExitFunc;
- }
- else if (TypeHandle(pRefdClass).CanCastTo(TypeHandle(MscorlibBinder::GetClass(CLASS__CRITICAL_HANDLE))))
- {
- ptdesc->vt = GetVtForIntPtr();
- goto ExitFunc;
- }
-
- if (pRefdClass->HasLayout())
- {
- if (nativeElem == NATIVE_TYPE_INTF)
- {
- // Classes with layout are exported as structs. Because of this, we can't export field or
- // parameters of these types marked with [MarshalAs(UnmanagedType.Interface)] as interface
- // pointers of the actual type. The best we can do is make them IUnknown pointers and
- // provide a warning.
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_W_LAYOUTCLASS_AS_INTERFACE);
- ptdesc->vt = VT_UNKNOWN;
- goto ExitFunc;
- }
- else if (!bMethodSig)
- {
- // Classes with layout inside structures must be either marked with [MarshalAs(UnmanagedType.Interface)],
- // [MarshalAs(UnmanagedType.Struct)] or not have any MarshalAs information.
- if ((nativeElem != 0) && (nativeElem != NATIVE_TYPE_STRUCT))
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- // These types are embedded structures so we can treat them as value classes.
- goto IsStructWithLayout;
- }
- else
- {
- // Classes with layout as parameters must be either marked with [MarshalAs(UnmanagedType.Interface)]
- // [MarshalAs(UnmanagedType.LPStruct)] or not have any MarshalAs information.
- if ((nativeElem != 0) && (nativeElem != NATIVE_TYPE_LPSTRUCT))
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
- }
- }
-
- // A reference to some non-system-defined/non delegate derived type. Get the reference to the
- // type, unless it is an imported COM type, in which case, we'll just use
- // IUnknown.
- // If the type is not visible from COM then we return S_USEIUNKNOWN.
- if (!IsTypeVisibleFromCom(TypeHandle(pRefdClass)))
- hr = S_USEIUNKNOWN;
- else
- hr = EEClassToHref(pCTI, pRefdClass, TRUE, &hRef);
-
- if (hr == S_USEIUNKNOWN)
- {
- // Not a known type, so use IUnknown
- ptdesc->vt = VT_UNKNOWN;
- goto ExitFunc;
- }
-
- // Not a known class, so make this a pointer to . . .
- ptdesc->vt = VT_PTR;
- ptdesc->lptdesc = reinterpret_cast<TYPEDESC*>(ppool->AllocZero(sizeof(TYPEDESC)));
- if (ptdesc->lptdesc == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- // . . . a user defined type . . .
- ptdesc->lptdesc->vt = VT_USERDEFINED;
- // . . . based on the token.
- ptdesc->lptdesc->hreftype = hRef;
- }
- else // It's a value type.
- {
-IsStructWithLayout:
- // If it is an enum, check the underlying type. All COM enums are 32 bits,
- // so if the .Net enum is not a 32 bit enum, convert to the underlying type
- // instead of the enum type.
- if (pRefdClass->IsEnum())
- {
- // Get the element type of the underlying type.
- CorElementType et = pRefdClass->GetInternalCorElementType();
- // If it is not a 32-bit type or MarshalAs is specified, convert as the
- // underlying type.
- if ((et != ELEMENT_TYPE_I4 && et != ELEMENT_TYPE_U4) ||
- (nativeElem != 0))
- {
- elem = et;
- goto TryWithElemType;
- }
- // Fall through to convert as the enum type.
- }
- else
- {
- // Value classes must be either marked with [MarshalAs(UnmanagedType.Struct)]
- // or not have any MarshalAs information.
- if ((nativeElem != 0) && (nativeElem != NATIVE_TYPE_STRUCT))
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
- }
-
- // A reference to some non-system-defined type. Get the reference to the
- // type. Since this is a value class we must get a valid href. Otherwise
- // we fail the conversion.
- hr = TokenToHref(pCTI, pMT, tkTypeRef, FALSE, &hRef);
- if (hr == S_USEIUNKNOWN)
- {
- SString sClsName;
- sClsName.SetUTF8(pclsname);
-
- LPCWSTR szVCName = sClsName.GetUnicode();
- if (NAMESPACE_SEPARATOR_WCHAR == *szVCName)
- szVCName++;
-
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_NONVISIBLEVALUECLASS, szVCName);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- // Value class is like other UserDefined types, except passed by value, ie
- // on the stack, instead of by pointer.
- // . . . a user defined type . . .
- ptdesc->vt = VT_USERDEFINED;
- // . . . based on the token.
- ptdesc->hreftype = hRef;
- }
- break;
-
- case ELEMENT_TYPE_SZARRAY:
- case ELEMENT_TYPE_ARRAY:
- {
- SigPointer sig(&pbSig[cbElem]);
-
- // Retrieve the type handle for the array elements.
- TypeHandle thElement = sig.GetTypeHandleThrowing(pModule, &emptyTypeContext);
- _ASSERTE(!thElement.IsNull());
-
- // Update the index into the managed signature array.
- IfFailThrow(sig.SkipExactlyOne());
- cbElem += static_cast<ULONG>(sig.GetPtr() - &pbSig[cbElem]);
-
- switch (nativeElem)
- {
- case 0:
- case NATIVE_TYPE_SAFEARRAY:
- {
- ULONG vtElement = VT_EMPTY;
-
- // Retrieve the safe array element type.
- if (cbNativeSig != 0)
- {
- cb = CorSigUncompressData(pbNativeSig, &vtElement);
- pbNativeSig += cb;
- cbNativeSig -= cb;
- }
-
- ArrayMarshalInfo arrayMarshalInfo(IsExportingAs64Bit() ? amiExport64Bit : amiExport32Bit);
- MarshalInfo::MarshalScenario ms = bMethodSig ? MarshalInfo::MARSHAL_SCENARIO_COMINTEROP : MarshalInfo::MARSHAL_SCENARIO_FIELD;
- arrayMarshalInfo.InitForSafeArray(ms, thElement, (VARTYPE)vtElement, fAnsi);
-
- if (!arrayMarshalInfo.IsValid())
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, arrayMarshalInfo.GetErrorResourceId());
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- // TYPEDESC is an array.
- ptdesc->vt = VT_SAFEARRAY;
- ptdesc->lptdesc = reinterpret_cast<TYPEDESC*>(ppool->AllocZero(sizeof(TYPEDESC)));
- if (ptdesc->lptdesc == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- ArrayToTypeDesc(pCTI, ppool, &arrayMarshalInfo, ptdesc->lptdesc);
- }
- break;
-
- case NATIVE_TYPE_FIXEDARRAY:
- {
- ULONG ntElement = NATIVE_TYPE_DEFAULT;
-
- // NATIVE_TYPE_FIXEDARRAY is only allowed on fields.
- if (bMethodSig)
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- // Retrieve the size of the fixed array. This is required.
- if (cbNativeSig == 0)
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, IDS_EE_BADMARSHALFIELD_FIXEDARRAY_NOSIZE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- cb = CorSigUncompressData(pbNativeSig, &nativeCount);
- pbNativeSig += cb;
- cbNativeSig -= cb;
-
- // A size const of 0 isn't supported.
- if (nativeCount == 0)
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, IDS_EE_BADMARSHALFIELD_FIXEDARRAY_ZEROSIZE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- // Read the optional array sub type if specified.
- if (cbNativeSig != 0)
- {
- cb = CorSigUncompressData(pbNativeSig, &ntElement);
- pbNativeSig += cb;
- cbNativeSig -= cb;
- }
-
- ArrayMarshalInfo arrayMarshalInfo(IsExportingAs64Bit() ? amiExport64Bit : amiExport32Bit);
- arrayMarshalInfo.InitForFixedArray(thElement, (CorNativeType)ntElement, fAnsi);
-
- if (!arrayMarshalInfo.IsValid())
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, arrayMarshalInfo.GetErrorResourceId());
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- // Set the data
- ptdesc->vt = VT_CARRAY;
- ptdesc->lpadesc = reinterpret_cast<ARRAYDESC*>(ppool->AllocZero(sizeof(ARRAYDESC)));
- if (ptdesc->lpadesc == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- ArrayToTypeDesc(pCTI, ppool, &arrayMarshalInfo, &ptdesc->lpadesc->tdescElem);
-
- ptdesc->lpadesc->cDims = 1;
- ptdesc->lpadesc->rgbounds->cElements = nativeCount;
- ptdesc->lpadesc->rgbounds->lLbound = 0;
- }
- break;
-
- case NATIVE_TYPE_ARRAY:
- {
- ULONG ntElement = NATIVE_TYPE_DEFAULT;
-
- // NATIVE_TYPE_ARRAY is not allowed on fields.
- if (!bMethodSig)
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_ARRAY_NEEDS_NT_FIXED);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- // Read the optional array sub type if specified.
- if (cbNativeSig != 0)
- {
- cb = CorSigUncompressData(pbNativeSig, &ntElement);
- pbNativeSig += cb;
- cbNativeSig -= cb;
- }
-
- ArrayMarshalInfo arrayMarshalInfo(IsExportingAs64Bit() ? amiExport64Bit : amiExport32Bit);
- arrayMarshalInfo.InitForNativeArray(MarshalInfo::MARSHAL_SCENARIO_COMINTEROP, thElement, (CorNativeType)ntElement, fAnsi);
-
- if (!arrayMarshalInfo.IsValid())
- {
- ReportWarning(TLBX_E_BAD_SIGNATURE, arrayMarshalInfo.GetErrorResourceId());
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- ptdesc->vt = VT_PTR;
- ptdesc->lptdesc = reinterpret_cast<TYPEDESC*>(ppool->AllocZero(sizeof(TYPEDESC)));
- if(ptdesc->lptdesc == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- ArrayToTypeDesc(pCTI, ppool, &arrayMarshalInfo, ptdesc->lptdesc);
- }
- break;
-
- default:
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_BAD_NATIVETYPE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- }
-
- // If we are dealing with an ELEMENT_TYPE_ARRAY, we need to eat the array description.
- if (elem == ELEMENT_TYPE_ARRAY)
- {
- // Eat the rank.
- cbElem += CorSigUncompressData(pbSig+cbElem, &elem);
-
- // Count of ubounds, ubounds.
- cbElem += CorSigUncompressData(pbSig+cbElem, &elem);
- for (i=elem; i>0; --i)
- cbElem += CorSigUncompressData(pbSig+cbElem, &elem);
-
- // Count of lbounds, lbounds.
- cbElem += CorSigUncompressData(pbSig+cbElem, &elem);
- for (i=elem; i>0; --i)
- cbElem += CorSigUncompressData(pbSig+cbElem, &elem);
- }
-
- break;
- }
-
- case ELEMENT_TYPE_TYPEDBYREF: // 0x16
- ptdesc->vt = VT_VARIANT;
- break;
-
- //------------------------------------------
- // This really should be the commented out
- // block following.
- case ELEMENT_TYPE_I: // 0x18,
- ptdesc->vt = GetVtForIntPtr();
- break;
-
- case ELEMENT_TYPE_U: // 0x19,
- ptdesc->vt = GetVtForUIntPtr();
- break;
-
- case ELEMENT_TYPE_CMOD_REQD: // 0x1F // required C modifier : E_T_CMOD_REQD <mdTypeRef/mdTypeDef>
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_UNKNOWN_SIGNATURE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
-
- case ELEMENT_TYPE_SENTINEL:
- goto TryAgain;
-
- case ELEMENT_TYPE_CMOD_OPT: // 0x20 // optional C modifier : E_T_CMOD_OPT <mdTypeRef/mdTypeDef>
- cb = CorSigUncompressToken(&pbSig[cbElem], &tkTypeRef);
- cbElem += cb;
- goto TryAgain;
-
- case ELEMENT_TYPE_FNPTR:
- {
- ptdesc->vt = GetVtForIntPtr();
-
- // Eat the rest of the signature.
- SigPointer p(&pbSig[cbElem-1]);
- IfFailThrow(p.SkipExactlyOne());
- cbElem += (ULONG)(p.GetPtr() - &pbSig[cbElem]); // Note I didn't use -1 here.
- break;
- }
-
- case ELEMENT_TYPE_GENERICINST:
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_GENERICINST_SIGNATURE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- break;
-
- case ELEMENT_TYPE_VAR:
- case ELEMENT_TYPE_MVAR:
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_GENERICPAR_SIGNATURE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- break;
-
- default:
- ReportWarning(TLBX_E_BAD_SIGNATURE, TLBX_E_UNKNOWN_SIGNATURE);
- hr = TLBX_E_BAD_SIGNATURE;
- goto ExitFunc;
- break;
- }
-
-ExitFunc:
- *pcbElem = cbElem;
-
- if (hr == S_USEIUNKNOWN)
- hr = S_OK;
-
- return hr;
-} // TypeLibExporter::CorSigToTypeDesc
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
-//*****************************************************************************
-// Get an HREFTYPE for an ITypeInfo, in the context of a ICreateTypeInfo2.
-//*****************************************************************************
-HRESULT TypeLibExporter::TokenToHref(
- ICreateTypeInfo2 *pCTI, // Typeinfo being created.
- MethodTable *pMT, // MethodTable with the token.
- mdToken tk, // The TypeRef to resolve.
- BOOL bWarnOnUsingIUnknown, // A flag indicating if we should warn on substituting IUnknown.
- HREFTYPE *pHref) // Put HREFTYPE here.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pCTI));
- PRECONDITION(CheckPointer(pMT));
- PRECONDITION(CheckPointer(pHref));
- }
- CONTRACTL_END;
-
- MethodTable *pRefdClass; // MethodTable object for referenced TypeDef.
-
- // Get the MethodTable for the referenced class, and see if it is being converted.
- pRefdClass = LoadClass(pMT->GetModule(), tk);
-
- // If the type is not visible from COM then we return S_USEIUNKNOWN.
- if (!IsTypeVisibleFromCom(TypeHandle(pRefdClass)))
- return S_USEIUNKNOWN;
-
- return EEClassToHref(pCTI, pRefdClass, bWarnOnUsingIUnknown, pHref);
-} // HRESULT TypeLibExporter::TokenToHref()
-
-//*****************************************************************************
-// Call the resolver to export the typelib for an assembly.
-//*****************************************************************************
-void TypeLibExporter::ExportReferencedAssembly(
- Assembly *pAssembly)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pAssembly));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK; // A result.
- ITypeLib *pTLB = 0; // Exported typelib.
-
- // Assembly as IP.
- SafeComHolder<IUnknown> pIAssembly = 0;
-
- {
- // Switch to cooperative to get an object ref.
- GCX_COOP();
-
- // Invoke the callback to resolve the reference.
- OBJECTREF orAssembly=0;
- GCPROTECT_BEGIN(orAssembly)
- {
- orAssembly = pAssembly->GetExposedObject();
-
- pIAssembly = GetComIPFromObjectRef(&orAssembly, MscorlibBinder::GetClass(CLASS__IASSEMBLY));
- }
- GCPROTECT_END();
- }
-
- IfFailReport(m_pNotify->ResolveRef((IUnknown*)pIAssembly, (IUnknown**)&pTLB));
-
- // If we got a typelib, store it on the assembly.
- if (pTLB)
- pAssembly->SetTypeLib(pTLB);
-} // void TypeLibExporter::ExportReferencedAssembly()
-
-//*****************************************************************************
-// Determine if a class represents a well-known interface, and return that
-// interface (from its real typelib) if it does.
-//*****************************************************************************
-void TypeLibExporter::GetWellKnownInterface(
- MethodTable *pMT, // MethodTable to check.
- ITypeInfo **ppTI) // Put ITypeInfo here, if found.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pMT));
- PRECONDITION(CheckPointer(ppTI));
- }
- CONTRACTL_END;
-
- HRESULT hr; // A result.
- GUID guid; // The MethodTable guid.
- WCHAR wzGuid[40]; // Guid in string format.
- LONG cbGuid; // Size of guid buffer.
- GUID guidTlb; // The typelib guid.
- DWORD dwError; // Note: HRESULT_FROM_WIN32 macro evaluates the argument 3x times
-
-
- HKEYHolder hInterface; // Registry key HKCR/Interface
- HKEYHolder hGuid; // Registry key of .../{xxx...xxx}
- HKEYHolder hTlb; // Registry key of .../TypeLib
-
- // The ITypeLib.
- SafeComHolder<ITypeLib> pTLB=0;
-
- // Get the GUID for the class. Will generate from name if no defined GUID,
- // will also use signatures if interface.
- pMT->GetGuid(&guid, TRUE);
-
- GuidToLPWSTR(guid, wzGuid, lengthof(wzGuid));
-
- // Look up that interface in the registry.
- dwError = WszRegOpenKeyEx(HKEY_CLASSES_ROOT, W("Interface"),0,KEY_READ, &hInterface);
- hr = HRESULT_FROM_WIN32(dwError);
- if (FAILED(hr))
- return;
-
- dwError = WszRegOpenKeyEx((HKEY)hInterface, wzGuid, 0, KEY_READ, &hGuid);
- hr = HRESULT_FROM_WIN32(dwError);
- if (FAILED(hr))
- return;
-
- dwError = WszRegOpenKeyEx((HKEY)hGuid, W("TypeLib"), 0, KEY_READ, &hTlb);
- hr = HRESULT_FROM_WIN32(dwError);
- if (FAILED(hr))
- return;
-
- cbGuid = sizeof(wzGuid);
- dwError = WszRegQueryValue((HKEY)hTlb, W(""), wzGuid, &cbGuid);
- hr = HRESULT_FROM_WIN32(dwError);
- if (FAILED(hr))
- return;
-
- CLSIDFromString(wzGuid, &guidTlb);
-
- // Retrieve the major and minor version number.
- USHORT wMajor;
- USHORT wMinor;
- Assembly *pAssembly = pMT->GetAssembly();
-
- hr = GetTypeLibVersionForAssembly(pAssembly,&wMajor, &wMinor);
- if (SUCCEEDED(hr))
- {
- hr = LoadRegTypeLib(guidTlb, wMajor, wMinor, 0, &pTLB);
- }
- if (FAILED(hr))
- {
- pAssembly->GetVersion(&wMajor, &wMinor, NULL, NULL);
-
- hr = LoadRegTypeLib(guidTlb, wMajor, wMinor, 0, &pTLB);
- if (FAILED(hr))
- {
- hr = LoadRegTypeLib(guidTlb, -1, -1, 0, &pTLB);
- if (FAILED(hr))
- {
- return;
- }
- }
- }
-
-
- hr = pTLB->GetTypeInfoOfGuid(guid, ppTI);
-} // void TypeLibExporter::GetWellKnownInterface()
-
-//*****************************************************************************
-// Get an HREFTYPE for an ITypeInfo, in the context of a ICreateTypeInfo2.
-//*****************************************************************************
-HRESULT TypeLibExporter::EEClassToHref( // S_OK or error.
- ICreateTypeInfo2 *pCTI, // Typeinfo being created.
- MethodTable *pClass, // The MethodTable * to resolve.
- BOOL bWarnOnUsingIUnknown, // A flag indicating if we should warn on substituting IUnknown.
- HREFTYPE *pHref) // Put HREFTYPE here.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pCTI));
- PRECONDITION(CheckPointer(pClass));
- PRECONDITION(CheckPointer(pHref));
- }
- CONTRACTL_END;
-
- HRESULT hr=S_OK; // A result.
- int bUseIUnknown=false; // Use IUnknown (if so, don't release pTI)?
- int bUseIUnknownWarned=false; // If true, used IUnknown, but already issued a more specific warning.
- CExportedTypesInfo sExported; // Cached ICreateTypeInfo pointers.
- CExportedTypesInfo *pExported; // Pointer to found or new cached pointers.
- CHrefOfClassHashKey sLookup; // Hash structure to lookup.
- CHrefOfClassHashKey *pFound; // Found structure.
- bool bImportedAssembly; // The assembly containing pClass is imported.
- bool bForceResolveCallback; // Type library resolution should always be handled by caller first.
-
- // A different typeinfo; default for pTI.
- SafeComHolder<ITypeInfo> pTIDef=0;
-
- // A TypeInfo; maybe for TypeDef, maybe for TypeRef.
- SafeComHolder<ITypeInfo> pTI=0;
-
-
- // See if we already know this MethodTable' href.
- sLookup.pClass = pClass;
- if ((pFound=m_HrefOfClassHash.Find(&sLookup)) != NULL)
- {
- *pHref = pFound->href;
- if (*pHref == m_hIUnknown)
- return S_USEIUNKNOWN;
- return S_OK;
- }
-
- // See if the class is in the export list.
- sExported.pClass = pClass;
- pExported = m_Exports.Find(&sExported);
-
- // If not in the exported assembly, possibly it was injected?
- if (pExported == 0)
- {
- pExported = m_InjectedExports.Find(&sExported);
- }
-
- // Is there an export for this class?
- if (pExported)
- {
- // Yes, For interfaces and value types (and enums), just use the typeinfo.
- if (pClass->IsValueType() || pClass->IsEnum() || pClass->HasLayout())
- {
- // No default interface, so use the class itself.
- if (pExported->pCTI)
- IfFailReport(SafeQueryInterface(pExported->pCTI, IID_ITypeInfo, (IUnknown**)&pTI));
- }
- else
- if (!pClass->IsInterface())
- {
- // If there is an explicit default interface, get the class for it.
- TypeHandle hndDefItfClass;
- DefaultInterfaceType DefItfType;
- DefItfType = GetDefaultInterfaceForClassWrapper(TypeHandle(pClass), &hndDefItfClass);
- switch (DefItfType)
- {
- case DefaultInterfaceType_Explicit:
- {
- _ASSERTE(!hndDefItfClass.IsNull());
-
- // Recurse to get the href for the default interface class.
- hr = EEClassToHref(pCTI, hndDefItfClass.GetMethodTable(), bWarnOnUsingIUnknown, pHref);
- // Done. Note that the previous call will have cached the href for
- // the default interface class. As this function exits, it will
- // also cache the SAME href for this class.
- goto ErrExit;
- }
-
- case DefaultInterfaceType_AutoDispatch:
- case DefaultInterfaceType_AutoDual:
- {
- _ASSERTE(!hndDefItfClass.IsNull());
-
- if (hndDefItfClass.GetMethodTable() != pClass)
- {
- // Recurse to get the href for the default interface class.
- hr = EEClassToHref(pCTI, hndDefItfClass.GetMethodTable(), bWarnOnUsingIUnknown, pHref);
- // Done. Note that the previous call will have cached the href for
- // the default interface class. As this function exits, it will
- // also cache the SAME href for this class.
- goto ErrExit;
- }
-
- // Return the class interface.
- _ASSERTE(pExported->pCTIClassItf);
- IfFailReport(SafeQueryInterface(pExported->pCTIClassItf, IID_ITypeInfo, (IUnknown**)&pTI));
- break;
- }
-
- case DefaultInterfaceType_IUnknown:
- case DefaultInterfaceType_BaseComClass:
- {
- pTI = m_pIUnknown;
- bUseIUnknown=true;
- SafeAddRef(pTI);
- break;
- }
-
- default:
- {
- _ASSERTE(!"Invalid default interface type!");
- hr = E_FAIL;
- break;
- }
- }
- }
- else
- { // This is an interface, so use the typeinfo for the interface, if there is one.
- if (pExported->pCTI)
- IfFailReport(SafeQueryInterface(pExported->pCTI, IID_ITypeInfo, (IUnknown**)&pTI));
- }
-
- if ((IUnknown*)pTI == 0)
- {
- // This is a class from the module/assembly, yet it is not being exported.
-
- // Whatever happens, the result is OK.
- hr = S_OK;
-
- if (pClass->IsComImport())
- {
- // If it is an imported type, get an href to it.
- GetWellKnownInterface(pClass, &pTI);
- }
-
- // If still didn't get a TypeInfo, use IUnknown.
- if ((IUnknown*)pTI == 0)
- {
- pTI = m_pIUnknown;
- bUseIUnknown=true;
- SafeAddRef(pTI);
- }
- }
- }
- else
- { // Not local. Try to get from the class' module's typelib.
- // If the caller wants to get a chance to resolve type library references themselves (before we go probing the assembly),
- // we'll skip the next step and go directly to the notify sink callback.
- bForceResolveCallback = (m_flags & TlbExporter_CallerResolvedReferences) != 0;
- if (!bForceResolveCallback)
- hr = GetITypeInfoForEEClass(pClass, &pTI, false/* interface, not coclass */, false/* do not create */, m_flags);
-
- // If getting the typeinfo from the class itself failed, there are
- // several possibilities:
- // - typelib didn't exist, and couldn't be created.
- // - typelib did exist, but didn't contain the typeinfo.
- // We can create a local (to the exported typelib) copy of the
- // typeinfo, and get a reference to that.
- // However, we don't want to export the whole tree into this typelib,
- // so we only create the typeinfo if the typelib existed but the
- // typeinfo wasn't found and the assembly is not an imported assembly.
- bImportedAssembly = pClass->GetAssembly()->IsImportedFromTypeLib();
-
- if (bForceResolveCallback || (FAILED(hr) && hr != TYPE_E_ELEMENTNOTFOUND && !bImportedAssembly))
- {
- // Invoke the callback to resolve the reference.
-
- Assembly *pAssembly = pClass->GetAssembly();
-
- ExportReferencedAssembly(pAssembly);
-
- hr = GetITypeInfoForEEClass(pClass, &pTI, false/* interface, not coclass */, false/* do not create */, m_flags);
- }
-
- if (hr == TYPE_E_ELEMENTNOTFOUND)
- {
- if (pClass->IsComImport())
- {
- // If it is an imported type, get an href to it.
-
- // Whatever happens, the result is OK.
- hr = S_OK;
-
- GetWellKnownInterface(pClass, &pTI);
-
- // If still didn't get a TypeInfo, use IUnknown.
- if ((IUnknown*)pTI == 0)
- {
- pTI = m_pIUnknown;
- bUseIUnknown=true;
- SafeAddRef(pTI);
- }
- }
- else
- {
- // Convert the single typedef from the other scope.
- ConvertOneTypeDef(pClass);
-
- // Now that the type has been injected, recurse to let the default-interface code run.
- hr = EEClassToHref(pCTI, pClass, bWarnOnUsingIUnknown, pHref);
-
- // This class should already have been cached by the recursive call. Don't want to add
- // it again.
- goto ErrExit2;
- }
- }
- else if (FAILED(hr))
- {
- DefineFullyQualifiedNameForClassWOnStack();
- LPCWSTR szName = GetFullyQualifiedNameForClassNestedAwareW(pClass);
- if (hr == TLBX_W_LIBNOTREGISTERED)
- {
- // The imported typelib is not registered on this machine. Give a warning, and substitute IUnknown.
- ReportEvent(NOTIF_CONVERTWARNING, hr, szName, (LPCWSTR) pClass->GetAssembly()->GetManifestModule()->GetPath());
- hr = S_OK;
- pTI = m_pIUnknown;
- bUseIUnknown = true;
- SafeAddRef(pTI);
- bUseIUnknownWarned = true;
- }
- else if (hr == TLBX_E_CANTLOADLIBRARY)
- {
- // The imported typelib is registered, but can't be loaded. Corrupt? Missing?
- InternalThrowHRWithContext(TLBX_E_CANTLOADLIBRARY, szName, (LPCWSTR) pClass->GetAssembly()->GetManifestModule()->GetPath());
- }
- IfFailReport(hr);
- }
- }
-
- // Make sure we could resolve the typeinfo.
- if (!(IUnknown*)pTI)
- IfFailReport(TYPE_E_ELEMENTNOTFOUND);
-
- // Assert that the containing typelib for pContainer is the typelib being created.
-#if defined(_DEBUG)
- {
- SafeComHolder<ITypeInfo> pTI=0;
- SafeComHolder<ITypeLib> pTL=0;
- SafeComHolder<ITypeLib> pTLMe=0;
- UINT ix;
- SafeQueryInterface(pCTI, IID_ITypeInfo, (IUnknown**)&pTI);
- SafeQueryInterface(m_pICreateTLB, IID_ITypeLib, (IUnknown**)&pTLMe);
- pTI->GetContainingTypeLib(&pTL, &ix);
- _ASSERTE(pTL == pTLMe);
- }
-#endif
-
- // If there is an ITypeInfo, convert to HREFTYPE.
- if ((IUnknown*)pTI)
- {
- if ((IUnknown*)pTI != m_pIUnknown)
- {
- // Resolve to default.
- if (pTIDef)
- hr = S_OK; // Already have default.
- else
- {
- // TypeLib API has a issue (sort of by design):
- // Before a type (and its dependencies) is completely created (all members added),
- // if you call Layout(), or anything that will lead to Layout(), such as ITypeInfo::GetTypeAttr
- // it will give the type an incorrect size. Ideally TypeLib API should fail in this case.
- // Anyway, we only need to avoid calling Layout() directly or indirectly until we have
- // completely created all types.
- // In this case, we are calling ITypeInfo::GetTypeAttr() in the function below, which is only
- // needed for coclasses. Fortunately, coclass doesn't have a size problem, as it don't have any members
- // So, we skip calling GetDefaultInterfaceForCoclass unless the class is an coclass.
- if (TKindFromClass(pClass) == TKIND_COCLASS)
- IfFailReport(GetDefaultInterfaceForCoclass(pTI, &pTIDef));
- else
- hr = S_FALSE;
- }
-
- if (hr == S_OK)
- hr = pCTI->AddRefTypeInfo(pTIDef, pHref);
- else
- hr = pCTI->AddRefTypeInfo(pTI, pHref);
- }
- else
- { // pTI == m_pIUnknown
- if (m_hIUnknown == -1)
- hr = pCTI->AddRefTypeInfo(pTI, &m_hIUnknown);
- *pHref = m_hIUnknown;
- }
- }
-
-ErrExit:
- // If we got the href...
- if (hr == S_OK)
- {
- // Save for later use.
- if ( NULL == (pFound=m_HrefOfClassHash.Add(&sLookup)))
- IfFailReport(E_OUTOFMEMORY);
-
- pFound->pClass = pClass;
- pFound->href = *pHref;
- }
-
- // If substituting IUnknown, give a warning.
- if (hr == S_OK && bUseIUnknown && bWarnOnUsingIUnknown && !bUseIUnknownWarned)
- {
- DefineFullyQualifiedNameForClassWOnStack();
- LPCWSTR szName = GetFullyQualifiedNameForClassNestedAwareW(pClass);
- ReportWarning(S_OK, TLBX_I_USEIUNKNOWN, szName);
- }
-
-ErrExit2:
- if (hr == S_OK && bUseIUnknown)
- hr = S_USEIUNKNOWN;
-
- return hr;
-} // HRESULT TypeLibExporter::EEClassToHref()
-
-//*****************************************************************************
-// Retrieve an HRef to the a type defined in StdOle.
-//*****************************************************************************
-void TypeLibExporter::StdOleTypeToHRef(ICreateTypeInfo2 *pCTI, REFGUID rGuid, HREFTYPE *pHref)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pCTI));
- PRECONDITION(CheckPointer(pHref));
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- SafeComHolder<ITypeLib> pITLB = NULL;
- SafeComHolder<ITypeInfo> pITI = NULL;
- MEMBERID MemID = 0;
- USHORT cFound = 0;
-
- IfFailReport(LoadRegTypeLib(LIBID_STDOLE2, -1, -1, 0, &pITLB));
- IfFailReport(pITLB->GetTypeInfoOfGuid(rGuid, &pITI));
- IfFailReport(pCTI->AddRefTypeInfo(pITI, pHref));
-} // void TypeLibExporter::ColorToHRef()
-
-//*****************************************************************************
-// Given a TypeDef's flags, determine the proper TYPEKIND.
-//*****************************************************************************
-TYPEKIND TypeLibExporter::TKindFromClass(
- MethodTable *pClass) // MethodTable.
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pClass));
- }
- CONTRACTL_END;
-
- HRESULT hr;
- ULONG ulIface = ifDual; // Is this interface [dual], IUnknown, or DISPINTERFACE.
-
- if (pClass->IsInterface())
- {
- // IDispatch or IUnknown derived?
- IfFailReport(pClass->GetMDImport()->GetIfaceTypeOfTypeDef(pClass->GetCl(), &ulIface));
- if (ulIface == ifDispatch)
- return TKIND_DISPATCH;
-
- return TKIND_INTERFACE;
- }
-
- if (pClass->IsEnum())
- return TKIND_ENUM;
-
- if (pClass->IsValueType() || pClass->HasLayout())
- {
- TYPEKIND tkResult=TKIND_RECORD; // The resulting typekind.
- mdFieldDef fd; // A Field def.
- ULONG cFD; // Count of fields.
- ULONG iFD=0; // Loop control.
- ULONG ulOffset; // Field offset.
- bool bNonZero=false; // Found any non-zero?
- MD_CLASS_LAYOUT sLayout; // For enumerating layouts.
-
- // To enum fields.
- HENUMInternalHolder eFDi(pClass->GetMDImport());
- eFDi.EnumInit(mdtFieldDef, pClass->GetCl());
-
- // Get an enumerator for the FieldDefs in the TypeDef. Only need the counts.
- cFD = pClass->GetMDImport()->EnumGetCount(&eFDi);
-
- // Get an enumerator for the class layout.
- IfFailReport(pClass->GetMDImport()->GetClassLayoutInit(pClass->GetCl(), &sLayout));
-
- // Enumerate the layout.
- while (pClass->GetMDImport()->GetClassLayoutNext(&sLayout, &fd, &ulOffset) == S_OK)
- {
- if (ulOffset != 0)
- {
- bNonZero = true;
- break;
- }
- ++iFD;
- }
-
- // If there were fields, all had layout, and all layouts are zero, call it a union.
- if (cFD > 0 && iFD == cFD && !bNonZero)
- tkResult = TKIND_UNION;
-
- return tkResult;
- }
-
- return TKIND_COCLASS;
-} // TYPEKIND TypeLibExporter::TKindFromClass()
-
-//*****************************************************************************
-// Generate a HREFTYPE in the output TypeLib for a TypeInfo.
-//*****************************************************************************
-void TypeLibExporter::GetRefTypeInfo(
- ICreateTypeInfo2 *pContainer,
- ITypeInfo *pReferenced,
- HREFTYPE *pHref)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(pContainer));
- PRECONDITION(CheckPointer(pReferenced));
- PRECONDITION(CheckPointer(pHref));
- }
- CONTRACTL_END;
-
- HRESULT hr; // A result.
- CHrefOfTIHashKey sLookup; // Hash structure to lookup.
- CHrefOfTIHashKey *pFound; // Found structure.
-
- // See if we already know this TypeInfo.
- sLookup.pITI = pReferenced;
- if ((pFound=m_HrefHash.Find(&sLookup)) != NULL)
- {
- *pHref = pFound->href;
- return;
- }
-
- // Assert that the containing typelib for pContainer is the typelib being created.
-#if defined(_DEBUG)
- {
- SafeComHolder<ITypeInfo> pTI=0;
- SafeComHolder<ITypeLib> pTL=0;
- SafeComHolder<ITypeLib> pTLMe=0;
- UINT ix;
-
- SafeQueryInterface(pContainer, IID_ITypeInfo, (IUnknown**)&pTI);
- SafeQueryInterface(m_pICreateTLB, IID_ITypeLib, (IUnknown**)&pTLMe);
- pTI->GetContainingTypeLib(&pTL, &ix);
- _ASSERTE(pTL == pTLMe);
- }
-#endif
-
- // Haven't seen it -- add the href.
- // NOTE: This code assumes that hreftypes are per-typelib.
- IfFailReport(pContainer->AddRefTypeInfo(pReferenced, pHref));
-
- // Save for later use.
- pFound=m_HrefHash.Add(&sLookup);
- if (pFound == NULL)
- IfFailReport(E_OUTOFMEMORY);
-
- // Prefix can't tell that IfFailReport will actually throw an exception if pFound is NULL so
- // let's tell it explicitly that if we reach this point pFound will not be NULL.
- PREFIX_ASSUME(pFound != NULL);
- pFound->pITI = pReferenced;
- pFound->href = *pHref;
- pReferenced->AddRef();
-} // HRESULT TypeLibExporter::GetRefTypeInfo()
-
-//*****************************************************************************
-// Implementation of a hashed ITypeInfo to HREFTYPE association.
-//*****************************************************************************
-void TypeLibExporter::CHrefOfTIHash::Clear()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- CHrefOfTIHashKey *p;
- for (p=GetFirst(); p; p=GetNext(p))
- {
- SafeRelease(p->pITI);
- }
-
- CClosedHash<class CHrefOfTIHashKey>::Clear();
-} // void TypeLibExporter::CHrefOfTIHash::Clear()
-
-unsigned int TypeLibExporter::CHrefOfTIHash::Hash(const CHrefOfTIHashKey *pData)
-{
- LIMITED_METHOD_CONTRACT;
-
-#ifndef _WIN64
- // The pointers are at least 4-byte aligned, so ignore bottom two bits.
- return (unsigned int) (((size_t)(pData->pITI))>>2);
-#else
- // @TODO IA64: Is this a good hashing mechanism on IA64?
- return (unsigned int) (((size_t)(pData->pITI))>>3);
-#endif
-} // unsigned long TypeLibExporter::CHrefOfTIHash::Hash()
-
-unsigned int TypeLibExporter::CHrefOfTIHash::Compare(const CHrefOfTIHashKey *p1, CHrefOfTIHashKey *p2)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (p1->pITI == p2->pITI)
- return (0);
- return (1);
-} // unsigned long TypeLibExporter::CHrefOfTIHash::Compare()
-
-TypeLibExporter::CHrefOfTIHash::ELEMENTSTATUS TypeLibExporter::CHrefOfTIHash::Status(CHrefOfTIHashKey *p)
-{
- LIMITED_METHOD_CONTRACT;
- if (p->pITI == reinterpret_cast<ITypeInfo*>(FREE))
- return (FREE);
- if (p->pITI == reinterpret_cast<ITypeInfo*>(DELETED))
- return (DELETED);
- return (USED);
-} // TypeLibExporter::CHrefOfTIHash::ELEMENTSTATUS TypeLibExporter::CHrefOfTIHash::Status()
-
-void TypeLibExporter::CHrefOfTIHash::SetStatus(CHrefOfTIHashKey *p, ELEMENTSTATUS s)
-{
- LIMITED_METHOD_CONTRACT;
-
- p->pITI = reinterpret_cast<ITypeInfo*>(s);
-} // void TypeLibExporter::CHrefOfTIHash::SetStatus()
-
-void *TypeLibExporter::CHrefOfTIHash::GetKey(CHrefOfTIHashKey *p)
-{
- LIMITED_METHOD_CONTRACT;
-
- return &p->pITI;
-} // void *TypeLibExporter::CHrefOfTIHash::GetKey()
-
-
-//*****************************************************************************
-// Implementation of a hashed MethodTable* to HREFTYPE association.
-//*****************************************************************************
-void TypeLibExporter::CHrefOfClassHash::Clear()
-{
- WRAPPER_NO_CONTRACT;
- CClosedHash<class CHrefOfClassHashKey>::Clear();
-} // void TypeLibExporter::CHrefOfClassHash::Clear()
-
-unsigned int TypeLibExporter::CHrefOfClassHash::Hash(const CHrefOfClassHashKey *pData)
-{
- LIMITED_METHOD_CONTRACT;
-
-#ifndef _WIN64
- // Tbe pointers are at least 4-byte aligned, so ignore bottom two bits.
- return (unsigned int) (((size_t)(pData->pClass))>>2);
-#else
- // @TODO IA64: Is this a good hashing mechanism on IA64?
- return (unsigned int) (((size_t)(pData->pClass))>>3);
-#endif
-} // unsigned long TypeLibExporter::CHrefOfClassHash::Hash()
-
-unsigned int TypeLibExporter::CHrefOfClassHash::Compare(const CHrefOfClassHashKey *p1, CHrefOfClassHashKey *p2)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (p1->pClass == p2->pClass)
- return (0);
- return (1);
-} // unsigned long TypeLibExporter::CHrefOfClassHash::Compare()
-
-TypeLibExporter::CHrefOfClassHash::ELEMENTSTATUS TypeLibExporter::CHrefOfClassHash::Status(CHrefOfClassHashKey *p)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (p->pClass == reinterpret_cast<MethodTable*>(FREE))
- return (FREE);
- if (p->pClass == reinterpret_cast<MethodTable*>(DELETED))
- return (DELETED);
- return (USED);
-} // TypeLibExporter::CHrefOfClassHash::ELEMENTSTATUS TypeLibExporter::CHrefOfClassHash::Status()
-
-void TypeLibExporter::CHrefOfClassHash::SetStatus(CHrefOfClassHashKey *p, ELEMENTSTATUS s)
-{
- LIMITED_METHOD_CONTRACT;
-
- p->pClass = reinterpret_cast<MethodTable*>(s);
-} // void TypeLibExporter::CHrefOfClassHash::SetStatus()
-
-void *TypeLibExporter::CHrefOfClassHash::GetKey(CHrefOfClassHashKey *p)
-{
- LIMITED_METHOD_CONTRACT;
-
- return &p->pClass;
-} // void *TypeLibExporter::CHrefOfClassHash::GetKey()
-
-
-//*****************************************************************************
-// Implementation of a hashed MethodTable* to conversion information association.
-//*****************************************************************************
-void TypeLibExporter::CExportedTypesHash::Clear()
-{
- WRAPPER_NO_CONTRACT;
-
- // Iterate over entries and free pointers.
- CExportedTypesInfo *pData;
- pData = GetFirst();
- while (pData)
- {
- SetStatus(pData, DELETED);
- pData = GetNext(pData);
- }
-
- CClosedHash<class CExportedTypesInfo>::Clear();
-} // void TypeLibExporter::CExportedTypesHash::Clear()
-
-unsigned int TypeLibExporter::CExportedTypesHash::Hash(const CExportedTypesInfo *pData)
-{
- LIMITED_METHOD_CONTRACT;
-
-#ifndef _WIN64
- // Tbe pointers are at least 4-byte aligned, so ignore bottom two bits.
- return (unsigned int) (((size_t)(pData->pClass))>>2);
-#else
- // @TODO IA64: Is this a good hashing mechanism on IA64?
- return (unsigned int) (((size_t)(pData->pClass))>>3);
-#endif
-} // unsigned long TypeLibExporter::CExportedTypesHash::Hash()
-
-unsigned int TypeLibExporter::CExportedTypesHash::Compare(const CExportedTypesInfo *p1, CExportedTypesInfo *p2)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (p1->pClass == p2->pClass)
- return (0);
- return (1);
-} // unsigned long TypeLibExporter::CExportedTypesHash::Compare()
-
-TypeLibExporter::CExportedTypesHash::ELEMENTSTATUS TypeLibExporter::CExportedTypesHash::Status(CExportedTypesInfo *p)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (p->pClass == reinterpret_cast<MethodTable*>(FREE))
- return (FREE);
- if (p->pClass == reinterpret_cast<MethodTable*>(DELETED))
- return (DELETED);
- return (USED);
-} // TypeLibExporter::CExportedTypesHash::ELEMENTSTATUS TypeLibExporter::CExportedTypesHash::Status()
-
-void TypeLibExporter::CExportedTypesHash::SetStatus(CExportedTypesInfo *p, ELEMENTSTATUS s)
-{
- WRAPPER_NO_CONTRACT;
-
- // If deleting a used entry, free the pointers.
- if (s == DELETED && Status(p) == USED)
- {
- if (p->pCTI) p->pCTI->Release(), p->pCTI=0;
- if (p->pCTIClassItf) p->pCTIClassItf->Release(), p->pCTIClassItf=0;
- }
- p->pClass = reinterpret_cast<MethodTable*>(s);
-} // void TypeLibExporter::CExportedTypesHash::SetStatus()
-
-void *TypeLibExporter::CExportedTypesHash::GetKey(CExportedTypesInfo *p)
-{
- LIMITED_METHOD_CONTRACT;
-
- return &p->pClass;
-} // void *TypeLibExporter::CExportedTypesHash::GetKey()
-
-void TypeLibExporter::CExportedTypesHash::InitArray()
-{
- STANDARD_VM_CONTRACT;
-
- // For iterating the entries.
- CExportedTypesInfo *pData = 0;
-
- // Make room for the data.
- m_iCount = 0;
- m_Array = new CExportedTypesInfo*[Base::Count()];
-
- // Fill the array.
- pData = GetFirst();
- while (pData)
- {
- m_Array[m_iCount++] = pData;
- pData = GetNext(pData);
- }
-} // void TypeLibExporter::CExportedTypesHash::InitArray()
-
-void TypeLibExporter::CExportedTypesHash::UpdateArray()
-{
- STANDARD_VM_CONTRACT;
-
- // For iterating the entries.
- CExportedTypesInfo *pData = 0;
-
- // Clear the old data.
- if (m_Array)
- delete[] m_Array;
-
- // Make room for the data.
- m_iCount = 0;
- m_Array = new CExportedTypesInfo*[Base::Count()];
-
- // Fill the array.
- pData = GetFirst();
- while (pData)
- {
- m_Array[m_iCount++] = pData;
- pData = GetNext(pData);
- }
-} // void TypeLibExporter::CExportedTypesHash::UpdateArray()
-
-void TypeLibExporter::CExportedTypesHash::SortByName()
-{
- WRAPPER_NO_CONTRACT;
-
- CSortByName sorter(m_Array, (int)m_iCount);
- sorter.Sort();
-} // void TypeLibExporter::CExportedTypesHash::SortByName()
-
-void TypeLibExporter::CExportedTypesHash::SortByToken()
-{
- WRAPPER_NO_CONTRACT;
-
- CSortByToken sorter(m_Array, (int)m_iCount);
- sorter.Sort();
-} // void TypeLibExporter::CExportedTypesHash::SortByToken()
-
-int TypeLibExporter::CExportedTypesHash::CSortByToken::Compare(
- CExportedTypesInfo **p1,
- CExportedTypesInfo **p2)
-{
- LIMITED_METHOD_CONTRACT;
-
- MethodTable *pC1 = (*p1)->pClass;
- MethodTable *pC2 = (*p2)->pClass;
- // Compare scopes.
- if (pC1->GetMDImport() < pC2->GetMDImport())
- return -1;
- if (pC1->GetMDImport() > pC2->GetMDImport())
- return 1;
- // Same scopes, compare tokens.
- if (pC1->GetTypeDefRid() < pC2->GetTypeDefRid())
- return -1;
- if (pC1->GetTypeDefRid() > pC2->GetTypeDefRid())
- return 1;
- // Hmmm. Same class.
- return 0;
-} // int TypeLibExporter::CExportedTypesHash::CSortByToken::Compare()
-
-int TypeLibExporter::CExportedTypesHash::CSortByName::Compare(
- CExportedTypesInfo **p1,
- CExportedTypesInfo **p2)
-{
- CONTRACTL
- {
- STANDARD_VM_CHECK;
- PRECONDITION(CheckPointer(p1));
- PRECONDITION(CheckPointer(p2));
- PRECONDITION(CheckPointer(*p1));
- PRECONDITION(CheckPointer(*p2));
- }
- CONTRACTL_END;
-
- int iRslt; // A compare result.
-
- MethodTable *pC1 = (*p1)->pClass;
- MethodTable *pC2 = (*p2)->pClass;
-
- // Ignore scopes. Need to see name collisions across scopes.
- // Same scopes, compare names.
- LPCSTR pName1, pNS1;
- LPCSTR pName2, pNS2;
- IfFailThrow(pC1->GetMDImport()->GetNameOfTypeDef(pC1->GetCl(), &pName1, &pNS1));
- IfFailThrow(pC2->GetMDImport()->GetNameOfTypeDef(pC2->GetCl(), &pName2, &pNS2));
-
- // Compare case-insensitive, because we want different capitalizations to sort together.
- SString sName1(SString::Utf8, pName1);
- SString sName2(SString::Utf8, pName2);
-
- iRslt = sName1.CompareCaseInsensitive(sName2);
- if (iRslt)
- return iRslt;
-
- // If names are spelled the same, ignoring capitalization, sort by namespace.
- // We will attempt to use namespace for disambiguation.
- SString sNS1(SString::Utf8, pNS1);
- SString sNS2(SString::Utf8, pNS2);
-
- iRslt = sNS1.CompareCaseInsensitive(sNS2);
- return iRslt;
-} // int TypeLibExporter::CExportedTypesHash::CSortByName::Compare()
-
diff --git a/src/vm/typehandle.cpp b/src/vm/typehandle.cpp
index ec46aa8064..32384cc490 100644
--- a/src/vm/typehandle.cpp
+++ b/src/vm/typehandle.cpp
@@ -491,11 +491,7 @@ BOOL TypeHandle::IsAbstract() const
DWORD TypeHandle::IsTransparentProxy() const
{
WRAPPER_NO_CONTRACT;
-#ifdef FEATURE_REMOTING
- return !IsTypeDesc() && AsMethodTable()->IsTransparentProxy();
-#else
return FALSE;
-#endif
}
#ifdef FEATURE_HFA
diff --git a/src/vm/typeparse.cpp b/src/vm/typeparse.cpp
index 28521f1839..68ff76273d 100644
--- a/src/vm/typeparse.cpp
+++ b/src/vm/typeparse.cpp
@@ -1570,15 +1570,6 @@ TypeHandle TypeName::GetTypeFromAsm(BOOL bForIntrospection)
_ASSERTE(!"You must pass either a asm-qualified typename or an actual Assembly.");
}
-#ifdef FEATURE_FUSION
- if (th.IsNull() && bLoadTypeFromPartialNameHack && GetAssembly() && !GetAssembly()->IsEmpty())
- {
- DomainAssembly* pPartialBindAssemblyHack = LoadAssemblyFromPartialNameHack(GetAssembly());
-
- if (pPartialBindAssemblyHack)
- th = GetTypeHaveAssembly(pPartialBindAssemblyHack->GetAssembly(), bThrowIfNotFound, bIgnoreCase, NULL);
- }
-#endif // FEATURE_FUSION
if (!th.IsNull() && (!m_genericArguments.IsEmpty() || !m_signature.IsEmpty()))
{
@@ -1819,46 +1810,6 @@ TypeName::GetTypeHaveAssemblyHelper(
return th;
} // TypeName::GetTypeHaveAssemblyHelper
-#ifdef FEATURE_FUSION
-DomainAssembly* LoadAssemblyFromPartialNameHack(SString* psszAssemblySpec, BOOL fCropPublicKey)
-{
- CONTRACTL
- {
- MODE_COOPERATIVE;
- THROWS;
- GC_TRIGGERS;
- INJECT_FAULT(COMPlusThrowOM(););
- }
- CONTRACTL_END;
-
- MethodDescCallSite loadWithPartialNameHack(METHOD__ASSEMBLY__LOAD_WITH_PARTIAL_NAME_HACK);
- ARG_SLOT args[2];
- STRINGREF mszAssembly = NULL;
- DomainAssembly* pPartialBindAssemblyHack = NULL;
- GCPROTECT_BEGIN(mszAssembly);
- {
- mszAssembly = StringObject::NewString(psszAssemblySpec->GetUnicode());
- args[0] = ObjToArgSlot(mszAssembly);
- args[1] = BoolToArgSlot(fCropPublicKey);
-
- ASSEMBLYREF assembly = (ASSEMBLYREF)loadWithPartialNameHack.Call_RetOBJECTREF(args);
-
- if (assembly != NULL)
- {
- pPartialBindAssemblyHack = (DomainAssembly*) assembly->GetDomainAssembly();
-
- if (pPartialBindAssemblyHack->GetAssembly()->IsCollectible())
- {
- // Should not be possible to reach
- COMPlusThrow(kNotSupportedException, W("NotSupported_CollectibleAssemblyResolve"));
- }
- }
- }
- GCPROTECT_END();
-
- return pPartialBindAssemblyHack;
-}
-#endif // FEATURE_FUSION
DomainAssembly * LoadDomainAssembly(
SString * psszAssemblySpec,
@@ -1902,7 +1853,6 @@ DomainAssembly * LoadDomainAssembly(
spec.SetParentAssembly(pRequestingAssembly->GetDomainAssembly());
}
-#if defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
// If the requesting assembly has Fallback LoadContext binder available,
// then set it up in the AssemblySpec.
if (pRequestingAssembly != NULL)
@@ -1910,7 +1860,6 @@ DomainAssembly * LoadDomainAssembly(
PEFile *pRequestingAssemblyManifestFile = pRequestingAssembly->GetManifestFile();
spec.SetFallbackLoadContextBinderForRequestingAssembly(pRequestingAssemblyManifestFile->GetFallbackLoadContextBinder());
}
-#endif // defined(FEATURE_HOST_ASSEMBLY_RESOLVER)
if (bThrowIfNotFound)
{
diff --git a/src/vm/typeparse.h b/src/vm/typeparse.h
index 00a3349ce2..bf5b010a62 100644
--- a/src/vm/typeparse.h
+++ b/src/vm/typeparse.h
@@ -44,9 +44,6 @@ bool inline IsTypeNameReservedChar(WCHAR ch)
}
}
-#ifdef FEATURE_FUSION
-DomainAssembly* LoadAssemblyFromPartialNameHack(SString* psszAssemblySpec, BOOL fCropPublicKey = FALSE);
-#endif // FEATURE_FUSION
DomainAssembly * LoadDomainAssembly(
SString * psszAssemblySpec,
diff --git a/src/vm/umthunkhash.cpp b/src/vm/umthunkhash.cpp
deleted file mode 100644
index ab2732e03c..0000000000
--- a/src/vm/umthunkhash.cpp
+++ /dev/null
@@ -1,171 +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.
-//
-// File: umthunkhash.cpp
-//
-
-//
-
-
-#include "common.h"
-#include "umthunkhash.h"
-
-#ifdef FEATURE_MIXEDMODE
-
-UMThunkHash::UMThunkHash(Module *pModule, AppDomain *pDomain) :
- CClosedHashBase(
-#ifdef _DEBUG
- 3,
-#else
- 17, // CClosedHashTable will grow as necessary
-#endif
-
- sizeof(UTHEntry),
- FALSE
- ),
- m_crst(CrstUMThunkHash)
-
-{
- WRAPPER_NO_CONTRACT;
- m_pModule = pModule;
- m_dwAppDomainId = pDomain->GetId();
-}
-
-UMThunkHash::~UMThunkHash()
-{
- CONTRACT_VOID
- {
- NOTHROW;
- DESTRUCTOR_CHECK;
- GC_TRIGGERS;
- FORBID_FAULT;
- MODE_ANY;
- }
- CONTRACT_END
-
-#ifndef DACCESS_COMPILE
- UTHEntry *phe = (UTHEntry*)GetFirst();
- while (phe) {
- DeleteExecutable(phe->m_pUMEntryThunk);
- phe->m_UMThunkMarshInfo.~UMThunkMarshInfo();
- phe = (UTHEntry*)GetNext((BYTE*)phe);
- }
-#endif
- RETURN;
-}
-
-LPVOID UMThunkHash::GetUMThunk(LPVOID pTarget, PCCOR_SIGNATURE pSig, DWORD cSig)
-{
- CONTRACT (LPVOID)
- {
- INSTANCE_CHECK;
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END
-
- UTHEntry *phe;
- CrstHolder ch(&m_crst);
-
- UTHKey key;
- key.m_pTarget = pTarget;
- key.m_pSig = pSig;
- key.m_cSig = cSig;
-
- phe =(UTHEntry *)Find((LPVOID)&key);
-#ifndef DACCESS_COMPILE
- if (phe == NULL)
- {
- NewExecutableHolder<UMEntryThunk> uET= new (executable) UMEntryThunk();
-
- bool bNew = FALSE;
- phe = (UTHEntry *)FindOrAdd((LPVOID)&key,bNew);
- if (phe != NULL)
- {
- _ASSERTE(bNew); // we are under lock
-
- phe->m_pUMEntryThunk=uET.Extract();
-
- //nothrow
- phe->m_UMThunkMarshInfo.LoadTimeInit(Signature(pSig, cSig), m_pModule);
- phe->m_pUMEntryThunk->LoadTimeInit((PCODE)pTarget, NULL, &(phe->m_UMThunkMarshInfo),
- MethodTable::GetMethodDescForSlotAddress((PCODE)pTarget),
- m_dwAppDomainId);
-
- phe->m_key = key;
- phe->m_status = USED;
- }
- }
-#endif //DACESS_COMPILE
- if (phe)
- RETURN (LPVOID)(phe->m_pUMEntryThunk->GetCode());
- else
- RETURN NULL;
-}
-
-
-unsigned int UMThunkHash::Hash(void const *pData)
-{
- LIMITED_METHOD_CONTRACT;
- UTHKey *pKey = (UTHKey*)pData;
- return (ULONG)(size_t)(pKey->m_pTarget);
-}
-
-inline unsigned int UMThunkHash::Compare( // 0, -1, or 1.
- void const *pData, // Raw key data on lookup.
- BYTE *pElement) // The element to compare data against.
-{
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- UTHKey *pkey1 = (UTHKey*)pData;
- UTHKey *pkey2 = &( ((UTHEntry*)pElement)->m_key );
-
- if (pkey1->m_pTarget != pkey2->m_pTarget)
- return 1;
-
- if (S_OK != MetaSig::CompareMethodSigsNT(pkey1->m_pSig, pkey1->m_cSig, m_pModule, NULL, pkey2->m_pSig, pkey2->m_cSig, m_pModule, NULL))
- return 1;
-
- return 0;
-}
-
-
-
-CClosedHashBase::ELEMENTSTATUS UMThunkHash::Status( // The status of the entry.
- BYTE *pElement) // The element to check.
-{
- LIMITED_METHOD_CONTRACT;
- return ((UTHEntry*)pElement)->m_status;
-}
-
-//*****************************************************************************
-// Sets the status of the given element.
-//*****************************************************************************
-void UMThunkHash::SetStatus(
- BYTE *pElement, // The element to set status for.
- ELEMENTSTATUS eStatus) // New status.
-{
- LIMITED_METHOD_CONTRACT;
- ((UTHEntry*)pElement)->m_status = eStatus;
-}
-
-//*****************************************************************************
-// Returns the internal key value for an element.
-//*****************************************************************************
-void *UMThunkHash::GetKey( // The data to hash on.
- BYTE *pElement) // The element to return data ptr for.
-{
- LIMITED_METHOD_CONTRACT;
- return (BYTE*) &(((UTHEntry*)pElement)->m_key);
-}
-
-#endif // FEATURE_MIXEDMODE
diff --git a/src/vm/umthunkhash.h b/src/vm/umthunkhash.h
deleted file mode 100644
index 343c55e344..0000000000
--- a/src/vm/umthunkhash.h
+++ /dev/null
@@ -1,87 +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.
-//
-// File: umthunkhash.h
-//
-
-//
-
-
-#ifndef UMTHUNKHASH_H_
-#define UMTHUNKHASH_H_
-#include "dllimportcallback.h"
-
-#ifdef FEATURE_MIXEDMODE // IJW
-//
-// A hashtable for u->m thunks not represented in the fixup tables.
-//
-class UMThunkHash : public CClosedHashBase {
- private:
- //----------------------------------------------------
- // Hash key for CClosedHashBase
- //----------------------------------------------------
- struct UTHKey {
- LPVOID m_pTarget;
- PCCOR_SIGNATURE m_pSig;
- DWORD m_cSig;
- };
-
- //----------------------------------------------------
- // Hash entry for CClosedHashBase
- //----------------------------------------------------
- struct UTHEntry {
- UTHKey m_key;
- ELEMENTSTATUS m_status;
- UMEntryThunk *m_pUMEntryThunk;
- UMThunkMarshInfo m_UMThunkMarshInfo;
- };
-
- public:
- UMThunkHash(Module *pModule, AppDomain *pDomain);
- ~UMThunkHash();
- LPVOID GetUMThunk(LPVOID pTarget, PCCOR_SIGNATURE pSig, DWORD cSig);
- // *** OVERRIDES FOR CClosedHashBase ***/
-
- //*****************************************************************************
- // Hash is called with a pointer to an element in the table. You must override
- // this method and provide a hash algorithm for your element type.
- //*****************************************************************************
- virtual unsigned int Hash( // The key value.
- void const *pData); // Raw data to hash.
-
- //*****************************************************************************
- // Compare is used in the typical memcmp way, 0 is eqaulity, -1/1 indicate
- // direction of miscompare. In this system everything is always equal or not.
- //*****************************************************************************
- inline unsigned int Compare( // 0, -1, or 1.
- void const *pData, // Raw key data on lookup.
- BYTE *pElement); // The element to compare data against.
-
- //*****************************************************************************
- // Return true if the element is free to be used.
- //*****************************************************************************
- virtual ELEMENTSTATUS Status( // The status of the entry.
- BYTE *pElement); // The element to check.
-
- //*****************************************************************************
- // Sets the status of the given element.
- //*****************************************************************************
- virtual void SetStatus(
- BYTE *pElement, // The element to set status for.
- ELEMENTSTATUS eStatus); // New status.
-
- //*****************************************************************************
- // Returns the internal key value for an element.
- //*****************************************************************************
- virtual void *GetKey( // The data to hash on.
- BYTE *pElement); // The element to return data ptr for.
-
-protected:
- Module *m_pModule;
- ADID m_dwAppDomainId;
- Crst m_crst;
-};
-
-#endif
-#endif
diff --git a/src/vm/util.cpp b/src/vm/util.cpp
index 2cf6f7f31c..70ed0e27ca 100644
--- a/src/vm/util.cpp
+++ b/src/vm/util.cpp
@@ -2491,16 +2491,6 @@ size_t GetLargestOnDieCacheSize(BOOL bTrueSize)
ThreadLocaleHolder::~ThreadLocaleHolder()
{
#ifdef FEATURE_USE_LCID
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostTaskManager *pManager = CorHost2::GetHostTaskManager();
- if (pManager)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- pManager->SetLocale(m_locale);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
#endif // FEATURE_USE_LCID
{
SetThreadLocale(m_locale);
@@ -2515,8 +2505,6 @@ HMODULE CLRGetModuleHandle(LPCWSTR lpModuleFileName)
STATIC_CONTRACT_FORBID_FAULT;
STATIC_CONTRACT_SO_TOLERANT;
- ThreadAffinityHolder affinity;
-
HMODULE hMod = WszGetModuleHandle(lpModuleFileName);
return hMod;
}
@@ -2530,19 +2518,10 @@ HMODULE CLRGetCurrentModuleHandle()
STATIC_CONTRACT_FORBID_FAULT;
STATIC_CONTRACT_SO_TOLERANT;
- ThreadAffinityHolder affinity;
-
HMODULE hMod = WszGetModuleHandle(NULL);
return hMod;
}
-#ifndef FEATURE_CORECLR
-static ICLRRuntimeInfo *GetCLRRuntime()
-{
- LIMITED_METHOD_CONTRACT;
- return g_pCLRRuntime;
-}
-#endif // !FEATURE_CORECLR
#endif // !FEATURE_PAL
@@ -2567,12 +2546,6 @@ void * __stdcall GetCLRFunction(LPCSTR FunctionName)
{
func = (void*)EEHeapFreeInProcessHeap;
}
-#ifndef FEATURE_CORECLR
- else if (strcmp(FunctionName, "GetCLRRuntime") == 0)
- {
- func = (void*)GetCLRRuntime;
- }
-#endif // !FEATURE_CORECLR
else if (strcmp(FunctionName, "ShutdownRuntimeWithoutExiting") == 0)
{
func = (void*)ShutdownRuntimeWithoutExiting;
@@ -2618,19 +2591,6 @@ CLRMapViewOfFileEx(
LPVOID pv = MapViewOfFileEx(hFileMappingObject,dwDesiredAccess,dwFileOffsetHigh,dwFileOffsetLow,dwNumberOfBytesToMap,lpBaseAddress);
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostMemoryManager *memoryManager = CorHost2::GetHostMemoryManager();
- if (pv == NULL && memoryManager)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- if (SUCCEEDED(memoryManager->NeedsVirtualAddressSpace(lpBaseAddress, dwNumberOfBytesToMap)))
- {
- // after host releases VA, let us try again.
- pv = MapViewOfFileEx(hFileMappingObject,dwDesiredAccess,dwFileOffsetHigh,dwFileOffsetLow,dwNumberOfBytesToMap,lpBaseAddress);
- }
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
if (!pv)
{
@@ -2658,35 +2618,6 @@ CLRMapViewOfFileEx(
#endif // _TARGET_X86_
#endif // _DEBUG
{
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (memoryManager)
- {
- SIZE_T dwNumberOfBytesMapped = 0;
- // Find out the size of the whole region.
- LPVOID lpAddr = pv;
- MEMORY_BASIC_INFORMATION mbi;
- while (TRUE)
- {
- memset(&mbi, 0, sizeof(mbi));
-#undef VirtualQuery
- if (!::VirtualQuery(lpAddr, &mbi, sizeof(mbi)))
- {
- break;
- }
-#define VirtualQuery(lpAddress, lpBuffer, dwLength) \
- Dont_Use_VirtualQuery(lpAddress, lpBuffer, dwLength)
- if (mbi.AllocationBase != pv)
- {
- break;
- }
- dwNumberOfBytesMapped += mbi.RegionSize;
- lpAddr = (LPVOID)((BYTE*)lpAddr + mbi.RegionSize);
- }
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- memoryManager->AcquiredVirtualAddressSpace(pv, dwNumberOfBytesMapped);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
if (!pv && GetLastError()==ERROR_SUCCESS)
@@ -2729,15 +2660,6 @@ CLRUnmapViewOfFile(
BOOL result = UnmapViewOfFile(lpBaseAddress);
if (result)
{
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostMemoryManager *memoryManager = CorHost2::GetHostMemoryManager();
- if (memoryManager)
- {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- memoryManager->ReleasedVirtualAddressSpace(lpBaseAddress);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
return result;
}
@@ -2754,7 +2676,6 @@ static HMODULE CLRLoadLibraryWorker(LPCWSTR lpLibFileName, DWORD *pLastError)
STATIC_CONTRACT_FAULT;
STATIC_CONTRACT_SO_TOLERANT;
- ThreadAffinityHolder affinity;
HMODULE hMod;
UINT last = SetErrorMode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);
{
@@ -2798,7 +2719,6 @@ static HMODULE CLRLoadLibraryExWorker(LPCWSTR lpLibFileName, HANDLE hFile, DWORD
STATIC_CONTRACT_FAULT;
STATIC_CONTRACT_SO_TOLERANT;
- ThreadAffinityHolder affinity;
HMODULE hMod;
UINT last = SetErrorMode(SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS);
{
@@ -2840,7 +2760,6 @@ BOOL CLRFreeLibrary(HMODULE hModule)
STATIC_CONTRACT_FORBID_FAULT;
STATIC_CONTRACT_SO_TOLERANT;
- ThreadAffinityHolder affinity;
return FreeLibrary(hModule);
}
@@ -2852,8 +2771,6 @@ VOID CLRFreeLibraryAndExitThread(HMODULE hModule,DWORD dwExitCode)
STATIC_CONTRACT_FORBID_FAULT;
STATIC_CONTRACT_SO_TOLERANT;
- ThreadAffinityHolder affinity;
-
// This is no-return
FreeLibraryAndExitThread(hModule,dwExitCode);
}
diff --git a/src/vm/util.hpp b/src/vm/util.hpp
index d81eedb0df..554429259f 100644
--- a/src/vm/util.hpp
+++ b/src/vm/util.hpp
@@ -678,16 +678,6 @@ public:
}
};
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-#define CLRMEMORYHOSTED 0x1
-#define CLRTASKHOSTED 0x2
-#define CLRSYNCHOSTED 0x4
-#define CLRTHREADPOOLHOSTED 0x8
-#define CLRIOCOMPLETIONHOSTED 0x10
-#define CLRASSEMBLYHOSTED 0x20
-#define CLRGCHOSTED 0x40
-#define CLRSECURITYHOSTED 0x80
-#endif
#define CLRHOSTED 0x80000000
GVAL_DECL(DWORD, g_fHostConfig);
@@ -700,110 +690,6 @@ inline BOOL CLRHosted()
return g_fHostConfig;
}
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
-inline BOOL CLRMemoryHosted()
-{
- LIMITED_METHOD_CONTRACT;
-
- return g_fHostConfig&CLRMEMORYHOSTED;
-}
-
-inline BOOL CLRTaskHosted()
-{
- // !!! Can not use contract here.
- // !!! This function is called by Thread::DetachThread after we free TLS memory.
- // !!! Contract will recreate TLS memory.
- LIMITED_METHOD_DAC_CONTRACT;
-
- return g_fHostConfig&CLRTASKHOSTED;
-}
-
-inline BOOL CLRSyncHosted()
-{
- LIMITED_METHOD_CONTRACT;
-
- return g_fHostConfig&CLRSYNCHOSTED;
-}
-inline BOOL CLRThreadpoolHosted()
-{
- LIMITED_METHOD_CONTRACT;
-
- return g_fHostConfig&CLRTHREADPOOLHOSTED;
-}
-inline BOOL CLRIoCompletionHosted()
-{
- LIMITED_METHOD_CONTRACT;
-
- return g_fHostConfig&CLRIOCOMPLETIONHOSTED;
-}
-inline BOOL CLRAssemblyHosted()
-{
- return g_fHostConfig&CLRASSEMBLYHOSTED;
-}
-
-inline BOOL CLRGCHosted()
-{
- LIMITED_METHOD_CONTRACT;
-
- return g_fHostConfig&CLRGCHOSTED;
-}
-
-inline BOOL CLRSecurityHosted()
-{
- LIMITED_METHOD_CONTRACT;
-
- return g_fHostConfig&CLRSECURITYHOSTED;
-}
-#else // FEATURE_INCLUDE_ALL_INTERFACES
-inline BOOL CLRMemoryHosted()
-{
- LIMITED_METHOD_CONTRACT;
- return FALSE;
-}
-
-inline BOOL CLRTaskHosted()
-{
- LIMITED_METHOD_DAC_CONTRACT;
- return FALSE;
-}
-
-inline BOOL CLRSyncHosted()
-{
- LIMITED_METHOD_CONTRACT;
- return FALSE;
-}
-
-inline BOOL CLRThreadpoolHosted()
-{
- LIMITED_METHOD_CONTRACT;
- return FALSE;
-}
-
-inline BOOL CLRIoCompletionHosted()
-{
- LIMITED_METHOD_CONTRACT;
- return FALSE;
-}
-
-inline BOOL CLRAssemblyHosted()
-{
- LIMITED_METHOD_CONTRACT;
- return FALSE;
-}
-
-inline BOOL CLRGCHosted()
-{
- LIMITED_METHOD_CONTRACT;
- return FALSE;
-}
-
-inline BOOL CLRSecurityHosted()
-{
- LIMITED_METHOD_CONTRACT;
- return FALSE;
-}
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
#ifndef FEATURE_PAL
HMODULE CLRGetModuleHandle(LPCWSTR lpModuleFileName);
@@ -874,30 +760,17 @@ BOOL IsHostRegisteredForEvent(EClrEvent event);
SetupThreadForComCall(OOMRetVal); \
if (CheckCanRunManagedCode && !CanRunManagedCode()) \
return CannotEnterRetVal; \
-SO_INTOLERANT_CODE_NOTHROW(CURRENT_THREAD, return SORetVal) \
-
-#define ComCallHostNotificationHR() \
-ReverseEnterRuntimeHolderNoThrow REHolder; \
-if (CLRTaskHosted()) \
-{ \
- HRESULT hr = REHolder.AcquireNoThrow(); \
- if (FAILED(hr)) \
- { \
- return hr; \
- } \
-}
+SO_INTOLERANT_CODE_NOTHROW(CURRENT_THREAD, return SORetVal)
#define SetupForComCallHRNoHostNotif() InternalSetupForComCall(HOST_E_CLRNOTAVAILABLE, E_OUTOFMEMORY, COR_E_STACKOVERFLOW, true)
#define SetupForComCallHRNoHostNotifNoCheckCanRunManagedCode() InternalSetupForComCall(HOST_E_CLRNOTAVAILABLE, E_OUTOFMEMORY, COR_E_STACKOVERFLOW, false)
#define SetupForComCallDWORDNoHostNotif() InternalSetupForComCall(-1, -1, -1, true)
#define SetupForComCallHR() \
-InternalSetupForComCall(HOST_E_CLRNOTAVAILABLE, E_OUTOFMEMORY, COR_E_STACKOVERFLOW, true) \
-ComCallHostNotificationHR()
+InternalSetupForComCall(HOST_E_CLRNOTAVAILABLE, E_OUTOFMEMORY, COR_E_STACKOVERFLOW, true)
#define SetupForComCallHRNoCheckCanRunManagedCode() \
-InternalSetupForComCall(HOST_E_CLRNOTAVAILABLE, E_OUTOFMEMORY, COR_E_STACKOVERFLOW, false) \
-ComCallHostNotificationHR()
+InternalSetupForComCall(HOST_E_CLRNOTAVAILABLE, E_OUTOFMEMORY, COR_E_STACKOVERFLOW, false)
#ifdef FEATURE_CORRUPTING_EXCEPTIONS
@@ -912,11 +785,6 @@ BEGIN_SO_INTOLERANT_CODE_NOTHROW(CURRENT_THREAD, SORetVal) \
#define BeginSetupForComCallHRWithEscapingCorruptingExceptions() \
HRESULT __hr = S_OK; \
InternalSetupForComCallWithEscapingCorruptingExceptions(HOST_E_CLRNOTAVAILABLE, E_OUTOFMEMORY, COR_E_STACKOVERFLOW, true) \
-ReverseEnterRuntimeHolderNoThrow REHolder; \
-if (CLRTaskHosted()) \
-{ \
- __hr = REHolder.AcquireNoThrow(); \
-} \
\
if (SUCCEEDED(__hr)) \
{ \
@@ -933,28 +801,12 @@ if (FAILED(__hr)) \
#endif // FEATURE_CORRUPTING_EXCEPTIONS
#define SetupForComCallDWORD() \
-InternalSetupForComCall(-1, -1, -1, true) \
-ReverseEnterRuntimeHolderNoThrow REHolder; \
-if (CLRTaskHosted()) \
-{ \
- if (FAILED(REHolder.AcquireNoThrow())) \
- { \
- return -1; \
- } \
-}
+InternalSetupForComCall(-1, -1, -1, true)
// Special version of SetupForComCallDWORD that doesn't call
// CanRunManagedCode() to avoid firing LoaderLock MDA
#define SetupForComCallDWORDNoCheckCanRunManagedCode() \
-InternalSetupForComCall(-1, -1, -1, false) \
-ReverseEnterRuntimeHolderNoThrow REHolder; \
-if (CLRTaskHosted()) \
-{ \
- if (FAILED(REHolder.AcquireNoThrow())) \
- { \
- return -1; \
- } \
-}
+InternalSetupForComCall(-1, -1, -1, false)
#include "unsafe.h"
@@ -985,8 +837,6 @@ FORCEINLINE void VoidFreeWinAllocatedBlock(LPVOID pv)
{
LIMITED_METHOD_CONTRACT;
- _ASSERTE(!CLRMemoryHosted());
-
#pragma push_macro("GetProcessHeap")
#pragma push_macro("HeapFree")
#undef GetProcessHeap
@@ -1294,35 +1144,7 @@ public:
extern LONG g_OLEAUT32_Loaded;
-#ifndef FEATURE_CORECLR
-#define ENSURE_OLEAUT32_LOADED() \
-{ \
- /* Should only be used in FCALL */ \
- _ASSERTE (__me != 0); \
- if (g_OLEAUT32_Loaded == 0) \
- { \
- /* CLRLoadLibrary/CLRFreeLibrary claim they trigger, but this */ \
- /* isn't really true in this case because we're loading oleaut32 */ \
- /* which we know doesn't contain any managed code in its DLLMain */ \
- CONTRACT_VIOLATION(GCViolation|SOToleranceViolation); \
- HMODULE hMod = CLRLoadLibrary(W("oleaut32")); \
- if (hMod == NULL) \
- { \
- __FCThrow(__me, kOutOfMemoryException, 0, 0, 0, 0); \
- } \
- else \
- { \
- if (FastInterlockExchange(&g_OLEAUT32_Loaded, 1) == 1) \
- { \
- CLRFreeLibrary(hMod); \
- } \
- } \
- } \
-} \
-INDEBUG(DisableDelayLoadCheckForOleaut32 _disableOleaut32Check);
-#else // !FEATURE_CORECLR
#define ENSURE_OLEAUT32_LOADED()
-#endif // !FEATURE_CORECLR
BOOL DbgIsExecutable(LPVOID lpMem, SIZE_T length);
diff --git a/src/vm/validator.cpp b/src/vm/validator.cpp
deleted file mode 100644
index 54f6ecdb2b..0000000000
--- a/src/vm/validator.cpp
+++ /dev/null
@@ -1,946 +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.
-
-
-/*
- *
- * Purpose: Provide IValidate implementation.
- * IValidate is used to validate PE stub, Metadata and IL.
- *
- */
-
-#include "common.h"
-
-#include "corerror.h"
-#include "vererror.h"
-#include "ivalidator.h"
-#include "securityattributes.h"
-#include "corhost.h"
-#include "verifier.hpp"
-#include "pedecoder.h"
-#include "comcallablewrapper.h"
-#include "../dlls/mscorrc/resource.h"
-#include "posterror.h"
-#include "comcallablewrapper.h"
-#include "eeconfig.h"
-#include "corhost.h"
-#include "security.h"
-#include "appdomain.inl"
-
-typedef void (*VerifyErrorHandler)(void* pThis, HRESULT hrError, struct VerErrorStruct* pError);
-
-// Declare global variables
-#define DECLARE_DATA
-#include "veropcodes.hpp"
-#undef DECLARE_DATA
-
-class CValidator
-{
-public:
- CValidator(IVEHandler *veh) : m_veh(veh)
- {
- LIMITED_METHOD_CONTRACT;
- }
- HRESULT VerifyAllMethodsForClass(Module *pModule, mdTypeDef cl, ValidateWorkerArgs* pArgs);
- HRESULT VerifyAllGlobalFunctions(Module *pModule, ValidateWorkerArgs* pArgs);
- HRESULT VerifyAssembly(Assembly *pAssembly, ValidateWorkerArgs* pArgs);
- HRESULT VerifyModule(Module* pModule, ValidateWorkerArgs* pArgs);
- HRESULT ReportError(HRESULT hr, ValidateWorkerArgs* pArgs, mdToken tok=0);
- HRESULT VerifyMethod(COR_ILMETHOD_DECODER* pILHeader, IVEHandler* pVEHandler, WORD wFlags, ValidateWorkerArgs* pArgs);
- HRESULT VerifyExportedType(
- Module * pModule,
- mdToken tkExportedType,
- ValidateWorkerArgs * pArgs);
- void HandleError(HRESULT hrError, struct VerErrorStruct* pError);
-
-private:
- IVEHandler *m_veh;
- ValidateWorkerArgs* m_pArgs;
-}; // class CValidator
-
-HRESULT CValidator::ReportError(HRESULT hr, ValidateWorkerArgs* pArgs, mdToken tok /* = 0 */)
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- } CONTRACTL_END;
-
- if (m_veh == NULL)
- return hr;
-
- HRESULT hr2 = E_FAIL;
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), return COR_E_STACKOVERFLOW);
- VEContext vec;
-
- memset(&vec, 0, sizeof(VEContext));
-
- if (tok != 0)
- {
- vec.flags = VER_ERR_TOKEN;
- vec.Token = tok;
- }
-
- hr2 = Verifier::ReportError(m_veh, hr, &vec, pArgs);
- END_SO_INTOLERANT_CODE;
- return hr2;
-} // CValidator::ReportError
-
-// Separate method since EX_TRY uses _alloca and is in a loop below.
-COR_ILMETHOD* GetILHeader(MethodDesc *pMD)
-{
- STANDARD_VM_CONTRACT;
-
- COR_ILMETHOD *pILHeader = NULL;
-
- EX_TRY
- {
- pILHeader = pMD->GetILHeader();
- }
- EX_CATCH
- {
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- return pILHeader;
-}
-
-HRESULT CValidator::VerifyAllMethodsForClass(Module *pModule, mdTypeDef cl, ValidateWorkerArgs* pArgs)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
- MethodTable *pMT = NULL;
-
- // In the case of COR_GLOBAL_PARENT_TOKEN (i.e. global functions), it is guaranteed
- // that the module has a method table or our caller will have skipped this step.
- TypeHandle th;
- {
- // <REVISIT>
- // Although there's no assert to disable here, we need to improve OOM reliability here. We are ignoring the HRESULT from the loader here.
- // That could cause an OOM failure to be disguised as something else. OOM's
- // need to be handled or propagated up to the caller.
- // </REVISIT>
- CONTRACT_VIOLATION(0);
-
- EX_TRY {
- th = ClassLoader::LoadTypeDefOrRefThrowing(pModule, cl,
- ClassLoader::ReturnNullIfNotFound,
- ClassLoader::PermitUninstDefOrRef);
- }
- EX_CATCH_HRESULT(hr);
-
- if (FAILED(hr)) {
- if ((hr==COR_E_TYPELOAD) || (hr==VER_E_TYPELOAD)) {
- hr = ReportError(hr, pArgs,cl);
- } else {
- hr = ReportError(hr, pArgs);
- }
- goto Exit;
- }
- }
-
- pMT = th.GetMethodTable();
- if (pMT == NULL)
- {
- hr = ReportError(VER_E_TYPELOAD, pArgs, cl);
- goto Exit;
- }
-
- g_fVerifierOff = false;
-
- {
- // Verify all methods in class - excluding inherited methods
- MethodTable::MethodIterator it(pMT);
- for (; it.IsValid(); it.Next())
- {
- pArgs->pMethodDesc = it.GetMethodDesc();
-
- bool fVerifyTransparentMethod = true;
- if (pArgs->fTransparentMethodsOnly)
- {
- MethodSecurityDescriptor msd(pArgs->pMethodDesc);
- fVerifyTransparentMethod = !msd.IsCritical();
- }
-
- if (pArgs->pMethodDesc &&
- pArgs->pMethodDesc->GetMethodTable() == pMT &&
- pArgs->pMethodDesc->IsIL() &&
- !pArgs->pMethodDesc->IsAbstract() &&
- !pArgs->pMethodDesc->IsUnboxingStub() &&
- fVerifyTransparentMethod)
- {
- COR_ILMETHOD* pILHeader = GetILHeader(pArgs->pMethodDesc);
-
- if (pILHeader != NULL)
- {
- COR_ILMETHOD_DECODER::DecoderStatus status;
- COR_ILMETHOD_DECODER ILHeader(pILHeader,
- pArgs->pMethodDesc->GetMDImport(), &status);
-
- if (status == COR_ILMETHOD_DECODER::SUCCESS)
- {
- hr = VerifyMethod(&ILHeader, m_veh, VER_FORCE_VERIFY, pArgs);
- if (hr == VER_E_INTERNAL) // this probably means peverify.dll was missing
- {
- goto Exit;
- }
- }
- else if (status == COR_ILMETHOD_DECODER::VERIFICATION_ERROR)
- {
- hr = COR_E_VERIFICATION;
- }
- else if (status == COR_ILMETHOD_DECODER::FORMAT_ERROR)
- {
- hr = COR_E_BADIMAGEFORMAT;
- }
- else
- {
- _ASSERTE(!"Unhandled status from COR_ILMETHOD_DECODER");
- }
- }
- else
- {
- hr = COR_E_BADIMAGEFORMAT;
- }
-
- if (FAILED(hr))
- hr = ReportError(hr, pArgs);
-
- if (FAILED(hr))
- goto Exit;
- }
- // We should ideally have an API to yield to the host,
- // but this is not critical for Whidbey.
- if (CLRTaskHosted())
- ClrSleepEx(0, FALSE);
- }
- }
-
-Exit:
- pArgs->pMethodDesc = NULL;
- return hr;
-} // CValidator::VerifyAllMethodsForClass
-
-//---------------------------------------------------------------------------------------
-//
-void
-MethodDescAndCorILMethodDecoderToCorInfoMethodInfo(
- MethodDesc * ftn,
- COR_ILMETHOD_DECODER * ILHeader,
- CORINFO_METHOD_INFO * pMethodInfo)
-{
- STANDARD_VM_CONTRACT;
-
- pMethodInfo->ftn = CORINFO_METHOD_HANDLE(ftn);
- pMethodInfo->scope = CORINFO_MODULE_HANDLE(ftn->GetModule());
- pMethodInfo->ILCode = const_cast<BYTE*>(ILHeader->Code);
- pMethodInfo->ILCodeSize = ILHeader->GetCodeSize();
- pMethodInfo->maxStack = ILHeader->GetMaxStack();
- pMethodInfo->EHcount = ILHeader->EHCount();
- pMethodInfo->options =
- (CorInfoOptions)
- (((ILHeader->GetFlags() & CorILMethod_InitLocals) ? CORINFO_OPT_INIT_LOCALS : 0) |
- (ftn->AcquiresInstMethodTableFromThis() ? CORINFO_GENERICS_CTXT_FROM_THIS : 0) |
- (ftn->RequiresInstMethodTableArg() ? CORINFO_GENERICS_CTXT_FROM_METHODTABLE : 0) |
- (ftn->RequiresInstMethodDescArg() ? CORINFO_GENERICS_CTXT_FROM_METHODDESC : 0));
-
- PCCOR_SIGNATURE pSigToConvert;
- DWORD cbSigToConvert;
- ftn->GetSig(&pSigToConvert, &cbSigToConvert);
- CONSISTENCY_CHECK(NULL != pSigToConvert);
- // fetch the method signature
- CEEInfo::ConvToJitSig(
- pSigToConvert,
- cbSigToConvert,
- pMethodInfo->scope,
- mdTokenNil,
- &pMethodInfo->args,
- ftn,
- false);
-
- //@GENERICS:
- // Shared generic methods and shared methods on generic structs take an extra argument representing their instantiation
- if (ftn->RequiresInstArg())
- pMethodInfo->args.callConv = (CorInfoCallConv) (pMethodInfo->args.callConv | CORINFO_CALLCONV_PARAMTYPE);
-
- // method attributes and signature are consistant
- _ASSERTE(!!ftn->IsStatic() == ((pMethodInfo->args.callConv & CORINFO_CALLCONV_HASTHIS) == 0));
-
- // And its local variables
- CEEInfo::ConvToJitSig(
- ILHeader->LocalVarSig,
- ILHeader->cbLocalVarSig,
- pMethodInfo->scope,
- mdTokenNil,
- &pMethodInfo->locals,
- ftn,
- true);
-} // MethodDescAndCorILMethodDecoderToCorInfoMethodInfo
-
-//---------------------------------------------------------------------------------------
-//
-void PEVerifyErrorHandler(void* pThis, HRESULT hrError, struct VerErrorStruct* pError)
-{
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- ((CValidator*)pThis)->HandleError(hrError, pError);
-}
-
-void CValidator::HandleError(HRESULT hrError, struct VerErrorStruct* pError)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- SO_TOLERANT;
- }
- CONTRACTL_END;
-
- BEGIN_SO_INTOLERANT_CODE(GetThread());
- _ASSERTE(sizeof(VEContext) == sizeof(struct VerErrorStruct));
- Verifier::ReportError(m_veh, hrError, (VEContext*)pError, m_pArgs);
- END_SO_INTOLERANT_CODE;
-}
-typedef void (__stdcall* VerifyFunc)(ICorJitInfo* pJitInfo, CORINFO_METHOD_INFO* pMethodInfo, VerifyErrorHandler pErrorHandler, void* pThis);
-static void VerifyMethodHelper(VerifyFunc pVerFunc, CEEJitInfo* pJI, CORINFO_METHOD_INFO* pMethodInfo, void* pThis)
-{
- // Helper method to allow us to use SO_TOLERANT_CODE macro
- STATIC_CONTRACT_SO_INTOLERANT;
- WRAPPER_NO_CONTRACT;
-
- BEGIN_SO_TOLERANT_CODE(GetThread());
- // Verify the method
- pVerFunc(pJI, pMethodInfo, PEVerifyErrorHandler, pThis);
- END_SO_TOLERANT_CODE;
-
-}
-
-static Volatile<VerifyFunc> g_pVerFunc = NULL;
-
-HRESULT CValidator::VerifyMethod(COR_ILMETHOD_DECODER* pILHeader, IVEHandler* pVEHandler, WORD wFlags, ValidateWorkerArgs* pArgs)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
- EX_TRY
- {
- // Find the DLL entrypoint
- m_pArgs = pArgs;
- if (g_pVerFunc.Load() == NULL)
- {
- HINSTANCE hJit64 = NULL;
- if (SUCCEEDED(g_pCLRRuntime->LoadLibrary(W("peverify.dll"), &hJit64)))
- {
- typedef void (__stdcall* psxsPeVerifyStartup) (CoreClrCallbacks);
- psxsPeVerifyStartup sxsPeVerifyStartup = (psxsPeVerifyStartup) GetProcAddress(hJit64, "sxsPeVerifyStartup");
-
- if(sxsPeVerifyStartup)
- {
- CoreClrCallbacks cccallbacks = GetClrCallbacks();
- (*sxsPeVerifyStartup) (cccallbacks);
- g_pVerFunc = (VerifyFunc)GetProcAddress(hJit64, "VerifyMethod");
- }
- }
- }
-
- if(!g_pVerFunc)
- {
- _ASSERTE(!"Failed to load peverify.dll or find VerifyMethod proc address");
- hr = VER_E_INTERNAL;
- }
- else
- {
- Thread *pThread = GetThread();
- if (pThread->IsAbortRequested())
- {
- pThread->HandleThreadAbort();
- }
- // Prepare the args
- MethodDesc* ftn = pArgs->pMethodDesc;
- CEEJitInfo ji(pArgs->pMethodDesc, pILHeader, NULL, true /* verify only */);
- CORINFO_METHOD_INFO methodInfo;
- MethodDescAndCorILMethodDecoderToCorInfoMethodInfo(ftn, pILHeader, &methodInfo);
-
- // Verify the method
- VerifyMethodHelper(g_pVerFunc, &ji, &methodInfo, this);
- }
- }
- EX_CATCH
- {
- // Catch and report any errors that peverify.dll lets fall through (ideally that should never happen)
- hr = GET_EXCEPTION()->GetHR();
- hr = ReportError(hr, pArgs);
- }
- EX_END_CATCH(RethrowTerminalExceptions)
-
- return hr;
-} // CValidator::VerifyMethod
-
-// Helper function to verify the global functions
-HRESULT CValidator::VerifyAllGlobalFunctions(Module *pModule, ValidateWorkerArgs* pArgs)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr = S_OK;
- // Is there anything worth verifying?
- if (pModule->GetGlobalMethodTable())
- hr = VerifyAllMethodsForClass(pModule, COR_GLOBAL_PARENT_TOKEN, pArgs);
- return hr;
-} // CValidator::VerifyAllGlobalFunctions
-
-HRESULT CValidator::VerifyModule(Module* pModule, ValidateWorkerArgs* pArgs)
-{
- STANDARD_VM_CONTRACT;
-
- // Get a count of all the classdefs and enumerate them.
- HRESULT hr = S_OK;
- IMDInternalImport * pMDI = NULL;
-
- if (pModule == NULL)
- {
- IfFailGo(VER_E_BAD_MD);
- }
-
- pMDI = pModule->GetMDImport();
- if (pMDI == NULL)
- {
- IfFailGo(VER_E_BAD_MD);
- }
-
- // First verify all global functions - if there are any
- IfFailGoto(
- VerifyAllGlobalFunctions(pModule, pArgs),
- ErrExit_SkipReportError);
-
- {
- HENUMTypeDefInternalHolder hTypeDefEnum(pMDI);
-
- IfFailGo(hTypeDefEnum.EnumTypeDefInitNoThrow());
-
- // Verify all TypeDefs
- mdTypeDef tkTypeDef;
- while (pMDI->EnumTypeDefNext(&hTypeDefEnum, &tkTypeDef))
- {
- IfFailGoto(
- VerifyAllMethodsForClass(pModule, tkTypeDef, pArgs),
- ErrExit_SkipReportError);
- }
- }
-
- {
- HENUMInternalHolder hExportedTypeEnum(pMDI);
-
- IfFailGo(hExportedTypeEnum.EnumInitNoThrow(
- mdtExportedType,
- mdTokenNil));
-
- // Verify all ExportedTypes
- mdToken tkExportedType;
- while (pMDI->EnumNext(&hExportedTypeEnum, &tkExportedType))
- {
- IfFailGoto(
- VerifyExportedType(pModule, tkExportedType, pArgs),
- ErrExit_SkipReportError);
- }
- }
-
-ErrExit:
- if (FAILED(hr))
- {
- hr = ReportError(hr, pArgs);
- }
-
-ErrExit_SkipReportError:
- return hr;
-} // CValidator::VerifyModule
-
-HRESULT CValidator::VerifyAssembly(Assembly *pAssembly, ValidateWorkerArgs* pArgs)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr;
-
- _ASSERTE(pAssembly->GetManifestImport());
-
- // Verify the module containing the manifest. There is no
- // FileRefence so will no show up in the list.
- hr = VerifyModule(pAssembly->GetManifestModule(), pArgs);
- if (FAILED(hr))
- goto Exit;
-
- {
- IMDInternalImport* pManifestImport = pAssembly->GetManifestImport();
-
- HENUMInternalHolder hEnum(pManifestImport);
-
- mdToken mdFile;
- hr = hEnum.EnumInitNoThrow(mdtFile, mdTokenNil);
- if (FAILED(hr))
- {
- hr = ReportError(hr, pArgs);
- goto Exit;
- }
-
- while(pManifestImport->EnumNext(&hEnum, &mdFile))
- {
- DomainFile* pModule = pAssembly->GetManifestModule()->LoadModule(GetAppDomain(), mdFile, FALSE);
-
- if (pModule != NULL)
- {
- hr = VerifyModule(pModule->GetModule(), pArgs);
- if (FAILED(hr))
- goto Exit;
- }
- }
- }
-
-Exit:
- return hr;
-} // CValidator::VerifyAssembly
-
-HRESULT
-CValidator::VerifyExportedType(
- Module * pModule,
- mdToken tkExportedType,
- ValidateWorkerArgs * pArgs)
-{
- STANDARD_VM_CONTRACT;
-
- HRESULT hr;
- TypeHandle th;
- NameHandle nameHandle(pModule, tkExportedType);
-
- LPCSTR szNamespace;
- LPCSTR szName;
- IfFailGo(pModule->GetMDImport()->GetExportedTypeProps(
- tkExportedType,
- &szNamespace,
- &szName,
- NULL, // tkImplementation
- NULL, // tkTypeDefId
- NULL)); // dwExportedTypeFlags
-
- nameHandle.SetName(szNamespace, szName);
-
- EX_TRY
- {
- th = pModule->GetClassLoader()->LoadTypeHandleThrowing(
- &nameHandle,
- CLASS_LOADED,
- pModule);
- hr = S_OK;
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- IfFailGo(hr);
- if (th.GetMethodTable() == NULL)
- {
- IfFailGo(VER_E_TYPELOAD);
- }
-
-ErrExit:
- if (FAILED(hr))
- {
- hr = ReportError(hr, pArgs, tkExportedType);
- }
-
- return hr;
-} // CValidator::VerifyExportedType
-
-static void ValidateWorker(LPVOID /* ValidateWorker_Args */ ptr)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- } CONTRACTL_END;
-
- ValidateWorkerArgs *args = (ValidateWorkerArgs *) ptr;
- AppDomain *pDomain = GetThread()->GetDomain();
-
- StackSString ssFile(args->wszFileName);
- StackSString ssFileDir;
- StackSString ssDirectory;
-
- // Fill ssDirectory with just drive of the file (e.g. 'C:')
- SplitPath(ssFile, &ssDirectory, &ssFileDir, NULL, NULL);
- // Now apped directory from the file name (incl. leading and trailing '/' or '\')
- ssDirectory.Append(ssFileDir);
-
- {
- // Set up the domain to resolve all dependency assemblies for introspection
- struct _gc {
- OBJECTREF orAppDomain;
- STRINGREF refDirectory;
- } gc;
- ZeroMemory(&gc, sizeof(gc));
-
- GCPROTECT_BEGIN(gc);
-
- gc.orAppDomain = pDomain->GetExposedObject();
- if (!ssDirectory.IsEmpty())
- {
- gc.refDirectory = StringObject::NewString(ssDirectory);
- }
-
- MethodDescCallSite meth(METHOD__APP_DOMAIN__ENABLE_RESOLVE_ASSEMBLIES_FOR_INTROSPECTION, &gc.orAppDomain);
- ARG_SLOT args[2] =
- {
- ObjToArgSlot(gc.orAppDomain),
- ObjToArgSlot(gc.refDirectory)
- };
- meth.Call(args);
-
- GCPROTECT_END();
- }
-
- GCX_PREEMP();
-
- Assembly *pAssembly;
- if (args->wszFileName)
- {
- // Load the primary assembly for introspection
- AssemblySpec spec;
- spec.SetCodeBase(args->wszFileName);
- spec.SetIntrospectionOnly(TRUE);
- pAssembly = spec.LoadAssembly(FILE_LOADED);
- }
- else
- {
- // TODO: This is a workaround to get SQLCLR running.
- // Our loader requires that a parent assembly is specified in order to load an
- // assembly from byte array. But here we do not know the parent.
- PEAssemblyHolder pFile(PEAssembly::OpenMemory(SystemDomain::System()->SystemFile(),
- args->pe, args->size, TRUE));
- pAssembly = pDomain->LoadAssembly(NULL, pFile, FILE_LOADED);
- }
-
- // Verify the assembly
- args->hr = args->val->VerifyAssembly(pAssembly, args);
-}
-
-
-static HRESULT ValidateHelper(
- IVEHandler *veh,
- IUnknown *pAppDomain,
- DWORD ulAppDomainId,
- BOOL UseId,
- unsigned long ulFlags,
- unsigned long ulMaxError,
- unsigned long token,
- __in_z LPWSTR fileName,
- BYTE *pe,
- unsigned long ulSize)
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- SO_TOLERANT;
- } CONTRACTL_END;
-
- Thread *pThread = GetThread();
-
- if (pe == NULL)
- return E_POINTER;
-
- HRESULT hr = S_OK;
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(pThread, return COR_E_STACKOVERFLOW);
- ADID pDomain;
- ValidateWorkerArgs args;
- CValidator val(veh);
- AppDomainFromIDHolder ad;
-
- BOOL Chk = FALSE;
- BOOL UnloadDomain = FALSE;
-
- GCX_COOP();
-
- EX_TRY {
- PEDecoder pev(pe, (COUNT_T)ulSize);
-
- args.wszFileName = fileName;
- args.fVerbose = (ulFlags & VALIDATOR_EXTRA_VERBOSE) ? true : false;
- args.fShowSourceLines = (ulFlags & VALIDATOR_SHOW_SOURCE_LINES) ? true : false;
- args.fTransparentMethodsOnly = (ulFlags & VALIDATOR_TRANSPARENT_ONLY) ? true : false;
- args.val = &val;
- args.pe = pe;
- args.size = ulSize;
-
- if((ulFlags & VALIDATOR_NOCHECK_PEFORMAT) == 0)
- {
- // Verify the PE header / native stubs first
- // <REVISIT> This validation is not performed on non-manifest modules. </REVISIT>
- Chk = ((ulFlags & VALIDATOR_CHECK_ILONLY) != 0) ? (BOOL) pev.CheckILOnlyFormat() :
- (BOOL) pev.CheckILFormat();
- if (!Chk)
- {
- hr = val.ReportError(VER_E_BAD_PE, &args);
-
- if (FAILED(hr))
- goto End;
- }
- }
- if((ulFlags & VALIDATOR_CHECK_PEFORMAT_ONLY) != 0)
- goto End;
-
- if (fileName)
- {
- AppDomain* pAD = AppDomain::CreateDomainContext(fileName);
- UnloadDomain = TRUE;
- pAD->SetPassiveDomain();
- pDomain=pAD->GetId();
- }
- else if (UseId)
- {
- pDomain = (ADID)ulAppDomainId;
- }
- else
- {
- SystemDomain::LockHolder lh;
- ComCallWrapper* pWrap = GetCCWFromIUnknown(pAppDomain, FALSE);
- if (pWrap == NULL)
- {
- hr = COR_E_APPDOMAINUNLOADED;
- goto End;
- }
- pDomain = pWrap->GetDomainID();
- }
-
- if (FAILED(hr))
- {
- hr = val.ReportError(hr, &args);
- goto End;
- }
-
- ad.Assign(pDomain, TRUE);
- if (ad.IsUnloaded())
- COMPlusThrow(kAppDomainUnloadedException);
- if (ad->IsIllegalVerificationDomain())
- COMPlusThrow(kFileLoadException, IDS_LOADINTROSPECTION_DISALLOWED);
- ad->SetVerificationDomain();
- ad.Release();
-
- args.val = &val;
-
- // We need a file path here. This is to do a fusion bind, and also
- // to make sure we can find any modules in the assembly. We assume
- // that the path points to the same place the bytes came from, which is true
- // with PEVerify, but perhaps not with other clients.
-
- if (pDomain != pThread->GetDomain()->GetId())
- {
- pThread->DoADCallBack(
- pDomain, ValidateWorker, &args);
- }
- else
- {
- ValidateWorker(&args);
- }
-
- if (FAILED(args.hr))
- hr = val.ReportError(args.hr, &args);
-
- // Only Unload the domain if we created it.
- if (UnloadDomain)
- AppDomain::UnloadById(pDomain,TRUE);
-End:;
-
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- hr = val.ReportError(hr, &args);
- }
- EX_END_CATCH(RethrowSOExceptions)
-
- END_SO_INTOLERANT_CODE;
- return hr;
-}
-
-void GetFormattingErrorMsg(__out_ecount(ulMaxLength) __out_z LPWSTR msg, unsigned int ulMaxLength)
-{
- CONTRACTL {
- NOTHROW;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(ulMaxLength >= 30);
- } CONTRACTL_END;
-
- EX_TRY
- {
- SString s;
- s.LoadResource(CCompRC::Debugging, IDS_VER_E_FORMATTING);
- wcsncpy_s(msg, ulMaxLength, s.GetUnicode(), _TRUNCATE);
- }
- EX_CATCH
- {
- wcscpy_s(msg, ulMaxLength, W("Error loading resource string"));
- }
- EX_END_CATCH(SwallowAllExceptions)
-}
-
-static HRESULT FormatEventInfoHelper(
- HRESULT hVECode,
- VEContext Context,
- __out_ecount(ulMaxLength) __out_z LPWSTR msg,
- unsigned int ulMaxLength,
- SAFEARRAY *psa)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(ulMaxLength >= 30);
- SO_TOLERANT;
- } CONTRACTL_END;
-
- BEGIN_SO_INTOLERANT_CODE(GetThread());
-
- VerError err;
- memcpy(&err, &Context, sizeof(VerError));
-
- ValidateWorkerArgs argsDefault;
- ValidateWorkerArgs* pArgs = &argsDefault;
-
- // We passed a pointer to the ValidateWorkerArgs object through
- // the SAFEARRAY casted as a UINT because there was no room left in the
- // interface to pass information through it.
- {
- UINT dim;
- LONG l;
-#ifdef _WIN64
- VARTYPE vt;
-#endif // _WIN64
- VARIANT var;
-
- if(!psa) {
- goto lDone;
- }
-
- dim = SafeArrayGetDim(psa);
- if (dim != 1) {
- _ASSERTE(!"There should be one element in the SafeArray");
- goto lDone;
- }
-
- if (FAILED(SafeArrayGetLBound(psa, 1, &l))) {
- _ASSERTE(false);
- goto lDone;
- }
- if (l != 0) {
- _ASSERTE(!"expected the lower bound to be zero");
- goto lDone;
- }
-
- if (FAILED(SafeArrayGetUBound(psa, 1, &l))) {
- _ASSERTE(false);
- goto lDone;
- }
- if (l != 0) {
- _ASSERTE(!"expected the upper bound to be zero");
- goto lDone;
- }
-#ifdef _WIN64
- // This check fails on Win2K when it should pass
- SafeArrayGetVartype(psa, &vt);
- if(vt != VT_VARIANT) {
- _ASSERTE(!"expected the ElementType to be a VT_VARIANT");
- goto lDone;
- }
-#endif // _WIN64
- l = 0;
- SafeArrayGetElement(psa, &l, &var);
-
-#ifdef _WIN64
- if (V_VT(&var) != VT_UI8) { // We expect the VarType to be a VT_UI8 (VT_UI8 is not supported on Windows 2000)
- _ASSERTE(false);
- goto lDone;
- }
-
- pArgs = (ValidateWorkerArgs*)(size_t)V_UI8(&var);
-#else
- // We don't check that the type is V_UINT here because that check fails on Win2K when it should pass
- pArgs = (ValidateWorkerArgs*)(size_t)V_UINT(&var);
-#endif
-
- }
-lDone: ;
-
- EX_TRY
- {
- Verifier::GetErrorMsg(hVECode, err, msg, ulMaxLength, pArgs);
- }
- EX_CATCH
- {
- GetFormattingErrorMsg(msg, ulMaxLength);
- }
- EX_END_CATCH(SwallowAllExceptions)
-
- END_SO_INTOLERANT_CODE;
- return S_OK;
-}
-
-HRESULT CorValidator::Validate(
- IVEHandler *veh,
- IUnknown *pAppDomain,
- unsigned long ulFlags,
- unsigned long ulMaxError,
- unsigned long token,
- __in_z LPWSTR fileName,
- BYTE *pe,
- unsigned long ulSize)
-{
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return ValidateHelper(veh, pAppDomain, 0, FALSE, ulFlags, ulMaxError,
- token, fileName, pe, ulSize);
-}
-
-HRESULT CLRValidator::Validate(
- IVEHandler *veh,
- unsigned long ulAppDomainId,
- unsigned long ulFlags,
- unsigned long ulMaxError,
- unsigned long token,
- __in_z LPWSTR fileName,
- BYTE *pe,
- unsigned long ulSize)
-{
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return ValidateHelper(veh, NULL, ulAppDomainId, TRUE, ulFlags, ulMaxError,
- token, fileName, pe, ulSize);
-}
-
-HRESULT CorValidator::FormatEventInfo(
- HRESULT hVECode,
- VEContext Context,
- __out_ecount(ulMaxLength) LPWSTR msg,
- unsigned long ulMaxLength,
- SAFEARRAY *psa)
-{
- WRAPPER_NO_CONTRACT;
- return FormatEventInfoHelper(hVECode, Context, msg, ulMaxLength, psa);
-}
-
-HRESULT CLRValidator::FormatEventInfo(
- HRESULT hVECode,
- VEContext Context,
- __out_ecount(ulMaxLength) LPWSTR msg,
- unsigned long ulMaxLength,
- SAFEARRAY *psa)
-{
- WRAPPER_NO_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return FormatEventInfoHelper(hVECode, Context, msg, ulMaxLength, psa);
-}
-
-
diff --git a/src/vm/vars.cpp b/src/vm/vars.cpp
index cc1662b618..165d172e74 100644
--- a/src/vm/vars.cpp
+++ b/src/vm/vars.cpp
@@ -69,9 +69,7 @@ GPTR_IMPL(MethodTable, g_pStringClass);
GPTR_IMPL(MethodTable, g_pArrayClass);
GPTR_IMPL(MethodTable, g_pSZArrayHelperClass);
GPTR_IMPL(MethodTable, g_pNullableClass);
-#ifdef FEATURE_SPAN_OF_T
GPTR_IMPL(MethodTable, g_pByReferenceClass);
-#endif
GPTR_IMPL(MethodTable, g_pExceptionClass);
GPTR_IMPL(MethodTable, g_pThreadAbortExceptionClass);
GPTR_IMPL(MethodTable, g_pOutOfMemoryExceptionClass);
@@ -82,12 +80,6 @@ GPTR_IMPL(MethodTable, g_pMulticastDelegateClass);
GPTR_IMPL(MethodTable, g_pValueTypeClass);
GPTR_IMPL(MethodTable, g_pEnumClass);
GPTR_IMPL(MethodTable, g_pThreadClass);
-#ifdef FEATURE_CER
-GPTR_IMPL(MethodTable, g_pCriticalFinalizerObjectClass);
-#endif
-#ifndef FEATURE_CORECLR
-GPTR_IMPL(MethodTable, g_pAsyncFileStream_AsyncResultClass);
-#endif // !FEATURE_CORECLR
GPTR_IMPL(MethodTable, g_pFreeObjectMethodTable);
GPTR_IMPL(MethodTable, g_pOverlappedDataClass);
@@ -105,9 +97,6 @@ GPTR_IMPL(MethodTable, g_pICastableInterface);
#endif // FEATURE_ICASTABLE
-#ifdef FEATURE_CER
-GPTR_IMPL(MethodDesc, g_pPrepareConstrainedRegionsMethod);
-#endif
GPTR_IMPL(MethodDesc, g_pExecuteBackoutCodeHelperMethod);
GPTR_IMPL(MethodDesc, g_pObjectCtorMD);
@@ -138,9 +127,6 @@ GPTR_IMPL(RCWCleanupList,g_pRCWCleanupList);
// <TODO> @TODO Remove eventually - </TODO> determines whether the verifier throws an exception when something fails
bool g_fVerifierOff;
-#ifndef FEATURE_CORECLR
-IAssemblyUsageLog *g_pIAssemblyUsageLogGac;
-#endif
// <TODO> @TODO - PROMOTE. </TODO>
OBJECTHANDLE g_pPreallocatedOutOfMemoryException;
diff --git a/src/vm/vars.hpp b/src/vm/vars.hpp
index cad41d7442..391fa4335b 100644
--- a/src/vm/vars.hpp
+++ b/src/vm/vars.hpp
@@ -66,15 +66,14 @@ typedef unsigned short wchar_t;
#include <corpriv.h>
#include <cordbpriv.h>
-#ifndef FEATURE_CORECLR
-#include <metahost.h>
-#endif // !FEATURE_CORECLR
#include "eeprofinterfaces.h"
#include "eehash.h"
#include "profilepriv.h"
+#include "gcinterface.h"
+
class ClassLoader;
class LoaderHeap;
class IGCHeap;
@@ -101,23 +100,6 @@ class BBSweep;
struct IAssemblyUsageLog;
//
-// object handles are opaque types that track object pointers
-//
-#ifndef DACCESS_COMPILE
-
-struct OBJECTHANDLE__
-{
- void* unused;
-};
-typedef struct OBJECTHANDLE__* OBJECTHANDLE;
-
-#else
-
-typedef TADDR OBJECTHANDLE;
-
-#endif
-
-//
// loader handles are opaque types that track object pointers that have a lifetime
// that matches that of a loader allocator
//
@@ -180,12 +162,6 @@ class OBJECTREF {
class TransparentProxyObject* m_asTP;
class ReflectClassBaseObject* m_asReflectClass;
-#ifdef FEATURE_COMPRESSEDSTACK
- class CompressedStackObject* m_asCompressedStack;
-#endif // #ifdef FEATURE_COMPRESSEDSTACK
-#if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
- class SecurityContextObject* m_asSecurityContext;
-#endif // #if defined(FEATURE_IMPERSONATION) || defined(FEATURE_COMPRESSEDSTACK)
class ExecutionContextObject* m_asExecutionContext;
class AppDomainBaseObject* m_asAppDomainBase;
class PermissionSetObject* m_asPermissionSetObject;
@@ -398,9 +374,7 @@ GPTR_DECL(MethodTable, g_pStringClass);
GPTR_DECL(MethodTable, g_pArrayClass);
GPTR_DECL(MethodTable, g_pSZArrayHelperClass);
GPTR_DECL(MethodTable, g_pNullableClass);
-#ifdef FEATURE_SPAN_OF_T
GPTR_DECL(MethodTable, g_pByReferenceClass);
-#endif
GPTR_DECL(MethodTable, g_pExceptionClass);
GPTR_DECL(MethodTable, g_pThreadAbortExceptionClass);
GPTR_DECL(MethodTable, g_pOutOfMemoryExceptionClass);
@@ -413,12 +387,6 @@ GPTR_DECL(MethodTable, g_pFreeObjectMethodTable);
GPTR_DECL(MethodTable, g_pValueTypeClass);
GPTR_DECL(MethodTable, g_pEnumClass);
GPTR_DECL(MethodTable, g_pThreadClass);
-#ifdef FEATURE_CER
-GPTR_DECL(MethodTable, g_pCriticalFinalizerObjectClass);
-#endif
-#ifndef FEATURE_CORECLR
-GPTR_DECL(MethodTable, g_pAsyncFileStream_AsyncResultClass);
-#endif // !FEATURE_CORECLR
GPTR_DECL(MethodTable, g_pOverlappedDataClass);
GPTR_DECL(MethodTable, g_TypedReferenceMT);
@@ -434,9 +402,6 @@ GPTR_DECL(MethodTable, g_pBaseRuntimeClass);
GPTR_DECL(MethodTable, g_pICastableInterface);
#endif // FEATURE_ICASTABLE
-#ifdef FEATURE_CER
-GPTR_DECL(MethodDesc, g_pPrepareConstrainedRegionsMethod);
-#endif
GPTR_DECL(MethodDesc, g_pExecuteBackoutCodeHelperMethod);
GPTR_DECL(MethodDesc, g_pObjectCtorMD);
@@ -445,9 +410,6 @@ GPTR_DECL(MethodDesc, g_pObjectFinalizerMD);
//<TODO> @TODO Remove eventually - determines whether the verifier throws an exception when something fails</TODO>
EXTERN bool g_fVerifierOff;
-#ifndef FEATURE_CORECLR
-EXTERN IAssemblyUsageLog *g_pIAssemblyUsageLogGac;
-#endif
// Global System Information
extern SYSTEM_INFO g_SystemInfo;
@@ -567,12 +529,6 @@ EXTERN Volatile<BOOL> g_fEEStarted;
EXTERN BOOL g_fComStarted;
#endif
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-//
-// Pointer to the activated CLR interface provided by the shim.
-//
-EXTERN ICLRRuntimeInfo *g_pCLRRuntime;
-#endif
//
// Global state variables indicating which stage of shutdown we are in
diff --git a/src/vm/virtualcallstub.cpp b/src/vm/virtualcallstub.cpp
index 5fc66f6d6a..01b15c689e 100644
--- a/src/vm/virtualcallstub.cpp
+++ b/src/vm/virtualcallstub.cpp
@@ -15,9 +15,6 @@
// ============================================================================
#include "common.h"
-#ifdef FEATURE_REMOTING
-#include "remoting.h"
-#endif
#include "array.h"
#ifdef FEATURE_PREJIT
#include "compile.h"
@@ -1971,16 +1968,6 @@ PCODE VirtualCallStubManager::ResolveWorker(StubCallSite* pCallSite,
// <token, TPMT, target> entry where target is in AD1, and then matching against
// this entry from AD2 which happens to be using the same token, perhaps for a
// completely different interface.
-#ifdef FEATURE_REMOTING
- if (token.IsTypedToken() && objectType->IsTransparentProxy())
- {
- MethodTable * pItfMT = GetTypeFromToken(token);
- if (pItfMT->GetDomain() != SharedDomain::GetDomain())
- {
- insertKind = DispatchCache::IK_NONE;
- }
- }
-#endif
}
if (insertKind != DispatchCache::IK_NONE)
@@ -2110,44 +2097,6 @@ VirtualCallStubManager::Resolver(
// NOTE: CERs are not hardened against transparent proxy types,
// so no need to worry about throwing an exception from here.
-#ifdef FEATURE_REMOTING
- if (pMT->IsTransparentProxy())
- {
- if (IsInterfaceToken(token))
- {
- MethodTable * pItfMT = GetTypeFromToken(token);
- DispatchSlot ds(pItfMT->FindDispatchSlot(token.GetSlotNumber()));
- if (pItfMT->HasInstantiation())
- {
- MethodDesc * pTargetMD = ds.GetMethodDesc();
- if (!pTargetMD->HasMethodInstantiation())
- {
- MethodDesc * pInstMD = MethodDesc::FindOrCreateAssociatedMethodDesc(
- pTargetMD,
- pItfMT,
- FALSE, // forceBoxedEntryPoint
- Instantiation(), // methodInst
- FALSE, // allowInstParam
- TRUE); // forceRemotableMethod
- *ppTarget = CRemotingServices::GetStubForInterfaceMethod(pInstMD);
- return TRUE;
- }
- }
- *ppTarget = ds.GetTarget();
- }
- else
- {
- CONSISTENCY_CHECK(IsClassToken(token));
- // All we do here is call the TP thunk stub.
- DispatchSlot thunkSlot(CTPMethodTable::GetMethodTable()->FindDispatchSlot(token.GetTypeID(), token.GetSlotNumber()));
- CONSISTENCY_CHECK(!thunkSlot.IsNull());
- *ppTarget = thunkSlot.GetTarget();
- }
- return TRUE;
- }
-
- CONSISTENCY_CHECK(!pMT->IsTransparentProxy());
-#endif // FEATURE_REMOTING
LOG((LF_LOADER, LL_INFO10000, "SD: VCSM::Resolver: (start) looking up %s method in %s\n",
token.IsThisToken() ? "this" : "interface",
@@ -2455,151 +2404,6 @@ PCODE VirtualCallStubManager::CacheLookup(size_t token, UINT16 tokenHash, Method
return (PCODE)(pElem != NULL ? pElem->target : NULL);
}
-#ifdef FEATURE_REMOTING
-//----------------------------------------------------------------------------
-// This is used by TransparentProxyWorkerStub to take a stub address (token),
-// and MethodTable and return the target. This is the fast version that only
-// checks the cache and returns NULL if a target is not found.
-//
-PCODE VSD_GetTargetForTPWorkerQuick(TransparentProxyObject * orTP, size_t token)
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- SO_TOLERANT;
- PRECONDITION(CheckPointer(orTP));
- PRECONDITION(orTP->IsTransparentProxy());
- } CONTRACTL_END
-
- GCX_FORBID();
-
- DispatchToken tok;
-
- // If we have a 16-bit number in the token then we have a slot number
- if (((UINT16)token) == token)
- {
- tok = DispatchToken::CreateDispatchToken((UINT32)token);
- }
- // Otherwise, we have a MethodDesc
- else
- {
- UINT32 typeID = 0;
- MethodDesc * pMD = (MethodDesc *) token;
-
- if (pMD->IsInterface())
- {
- typeID = pMD->GetMethodTable()->LookupTypeID();
- // If this type has never had a TypeID assigned, then it couldn't possibly
- // be in the cache. We do this instead of calling GetTypeID because that can
- // throw, and this method is not protected from that.
- if (typeID == TypeIDProvider::INVALID_TYPE_ID)
- {
- return NULL;
- }
-
-#ifdef FAT_DISPATCH_TOKENS
- if (DispatchToken::RequiresDispatchTokenFat(typeID, pMD->GetSlot()))
- {
- tok = pMD->GetMethodTable()->GetLoaderAllocator()->TryLookupDispatchToken(typeID, pMD->GetSlot());
- if (!tok.IsValid())
- {
- return NULL;
- }
- }
- else
-#endif
- {
- tok = DispatchToken::CreateDispatchToken(typeID, pMD->GetSlot());
- }
- }
- else
- {
- // On AMD64 a non-virtual call on an in context transparent proxy
- // results in us reaching here with (pMD->IsInterface == FALSE)
- return pMD->GetSingleCallableAddrOfCode();
- }
- }
-
- return VirtualCallStubManager::CacheLookup(tok.To_SIZE_T(), DispatchCache::INVALID_HASH, orTP->GetMethodTableBeingProxied());
-}
-
-//----------------------------------------------------------------------------
-// This is used by TransparentProxyWorkerStub to take a stub address (token),
-// and MethodTable and return the target. This is the slow version that can throw
-// On x86 we construct a HelperMethodFrame, while on the 64 bit platforms we are
-// called by ResolveWorkerStatic which already has constructed a frame
-//
-PCODE VSD_GetTargetForTPWorker(TransitionBlock * pTransitionBlock, size_t token)
-{
- CONTRACTL {
- THROWS;
- GC_TRIGGERS;
- SO_TOLERANT;
- INJECT_FAULT(COMPlusThrowOM(););
- PRECONDITION(CheckPointer(pTransitionBlock));
- } CONTRACTL_END
-
- MAKE_CURRENT_THREAD_AVAILABLE();
-
- DispatchToken tok;
- MethodDesc *pRepresentativeMD = NULL;
- PCODE pRet = NULL;
-
- BEGIN_SO_INTOLERANT_CODE(CURRENT_THREAD);
-
- FrameWithCookie<StubDispatchFrame> frame(pTransitionBlock);
- StubDispatchFrame * pSDFrame = &frame;
-
- MethodTable * pMT = CTPMethodTable::GetMethodTableBeingProxied(pSDFrame->GetThis());
-
- // If we have a 16-bit number in the token then we have a slot number
- if (((UINT16)token) == token) {
- tok = DispatchToken::CreateDispatchToken((UINT32)token);
- pRepresentativeMD = VirtualCallStubManager::GetRepresentativeMethodDescFromToken(tok.To_SIZE_T(), pMT);
- }
- // Otherwise, we have a MethodDesc
- else {
- // The token will be calculated after we erect a GC frame.
- pRepresentativeMD = (MethodDesc *)token;
- }
- PREFIX_ASSUME(pRepresentativeMD != NULL);
-
- // Get the current appdomain
- AppDomain *pAD = (AppDomain *) CURRENT_THREAD->GetDomain();
-
- // Get the virtual stub manager for this AD. We pick the current
- // AD because when the AD is unloaded the cache entry will be cleared.
- // If we happen to be calling from shared to shared, it's no big
- // deal because we'll just come through here again and add a new
- // cache entry. We can't choose the manager based on the return
- // address because this could be tail-called or called indirectly
- // via helper and so the return address won't be recognized.
- VirtualCallStubManager *pMgr = pAD->GetLoaderAllocator()->GetVirtualCallStubManager();
- CONSISTENCY_CHECK(CheckPointer(pMgr));
-
- pSDFrame->SetFunction(pRepresentativeMD);
- pSDFrame->Push(CURRENT_THREAD);
- INSTALL_UNWIND_AND_CONTINUE_HANDLER_NO_PROBE;
-
- // If we didn't properly create a token above, it's because we needed to wait until
- // the helper frame was created (GetTypeID is a throwing operation).
- if (!tok.IsValid()) {
- tok = pAD->GetLoaderAllocator()->GetDispatchToken(pRepresentativeMD->GetMethodTable()->GetTypeID(),
- pRepresentativeMD->GetSlot());
- }
- CONSISTENCY_CHECK(tok.IsValid());
-
- pRet = pMgr->GetTarget(tok.To_SIZE_T(), pMT);
- CONSISTENCY_CHECK(pRet != NULL);
-
- UNINSTALL_UNWIND_AND_CONTINUE_HANDLER_NO_PROBE;
- pSDFrame->Pop(CURRENT_THREAD);
-
- END_SO_INTOLERANT_CODE;
-
- return pRet;
-}
-#endif // FEATURE_REMOTING
//----------------------------------------------------------------------------
/* static */
@@ -2702,17 +2506,6 @@ VirtualCallStubManager::TraceResolver(
MethodTable *pMT = pObj->GetMethodTable();
CONSISTENCY_CHECK(CheckPointer(pMT));
-#ifdef FEATURE_REMOTING
- if (pMT->IsTransparentProxy())
- {
-#ifdef DACCESS_COMPILE
- DacNotImpl();
-#else
- trace->InitForFramePush(GetEEFuncEntryPoint(TransparentProxyStubPatchLabel));
-#endif
- return TRUE;
- }
-#endif
DispatchSlot slot(pMT->FindDispatchSlot(token));
@@ -4254,3 +4047,10 @@ BOOL VirtualCallStubManagerManager::TraceManager(
// Forward the call to the appropriate manager.
return pMgr->TraceManager(thread, trace, pContext, pRetAddr);
}
+
+#if defined(_TARGET_X86_) && defined(FEATURE_PAL)
+void BackPatchWorkerStaticStub(PCODE returnAddr, TADDR siteAddrForRegisterIndirect)
+{
+ VirtualCallStubManager::BackPatchWorkerStatic(returnAddr, siteAddrForRegisterIndirect);
+}
+#endif
diff --git a/src/vm/virtualcallstub.h b/src/vm/virtualcallstub.h
index b3f736fcae..7b6fedf2b2 100644
--- a/src/vm/virtualcallstub.h
+++ b/src/vm/virtualcallstub.h
@@ -56,13 +56,6 @@ extern "C" PCODE STDCALL VSD_ResolveWorker(TransitionBlock * pTransitionBlock,
#endif
);
-#ifdef FEATURE_REMOTING
-// This is used by TransparentProxyWorkerStub to take a stub address (token), and
-// MethodTable and return the target. It will look in the cache first, and if not found
-// will call the resolver and then put the result into the cache.
-extern "C" PCODE STDCALL VSD_GetTargetForTPWorkerQuick(TransparentProxyObject * orTP, size_t token);
-extern "C" PCODE STDCALL VSD_GetTargetForTPWorker(TransitionBlock * pTransitionBlock, size_t token);
-#endif
/////////////////////////////////////////////////////////////////////////////////////
#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
@@ -171,6 +164,9 @@ extern "C" void ResolveWorkerChainLookupAsmStub(); // for chaining of entries
#ifdef _TARGET_X86_
extern "C" void BackPatchWorkerAsmStub(); // backpatch a call site to point to a different stub
+#ifdef FEATURE_PAL
+extern "C" void BackPatchWorkerStaticStub(PCODE returnAddr, TADDR siteAddrForRegisterIndirect);
+#endif // FEATURE_PAL
#endif // _TARGET_X86_
@@ -555,6 +551,10 @@ private:
#endif
);
+#if defined(_TARGET_X86_) && defined(FEATURE_PAL)
+ friend void BackPatchWorkerStaticStub(PCODE returnAddr, TADDR siteAddrForRegisterIndirect);
+#endif
+
//These are the entrypoints that the stubs actually end up calling via the
// xxxAsmStub methods above
static void STDCALL BackPatchWorkerStatic(PCODE returnAddr, TADDR siteAddrForRegisterIndirect);
diff --git a/src/vm/win32threadpool.cpp b/src/vm/win32threadpool.cpp
index e8a05c383f..bc84762b06 100644
--- a/src/vm/win32threadpool.cpp
+++ b/src/vm/win32threadpool.cpp
@@ -448,21 +448,6 @@ BOOL ThreadpoolMgr::Initialize()
CPThreadCounter.counts.AsLongLong = counts.AsLongLong;
#ifndef FEATURE_PAL
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- if (CLRIoCompletionHosted())
- {
- HANDLE hPort;
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = CorHost2::GetHostIoCompletionManager()->CreateIoCompletionPort(&hPort);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- goto end;
-
- GlobalCompletionPort = hPort;
- }
- else
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
{
GlobalCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
NULL,
@@ -568,7 +553,7 @@ BOOL ThreadpoolMgr::SetMaxThreadsHelper(DWORD MaxWorkerThreads,
/************************************************************************/
BOOL ThreadpoolMgr::SetMaxThreads(DWORD MaxWorkerThreads,
- DWORD MaxIOCompletionThreads)
+ DWORD MaxIOCompletionThreads)
{
CONTRACTL
{
@@ -578,96 +563,16 @@ BOOL ThreadpoolMgr::SetMaxThreads(DWORD MaxWorkerThreads,
}
CONTRACTL_END;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostThreadpoolManager *threadpoolProvider = CorHost2::GetHostThreadpoolManager();
- if (threadpoolProvider) {
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = threadpoolProvider->SetMaxThreads(MaxWorkerThreads);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- {
- SetLastHRError(hr);
- return FALSE;
- }
- }
-
- IHostIoCompletionManager *ioCompletionProvider = CorHost2::GetHostIoCompletionManager();
- if (ioCompletionProvider) {
- HRESULT hr;
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = ioCompletionProvider->SetMaxThreads(MaxIOCompletionThreads);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- {
- SetLastHRError(hr);
- return FALSE;
- }
- }
-
- if (threadpoolProvider && ioCompletionProvider) {
- return TRUE;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
-
- if (IsInitialized())
- {
- return SetMaxThreadsHelper(MaxWorkerThreads, MaxIOCompletionThreads);
- }
-
- if (InterlockedCompareExchange(&Initialization, 1, 0) == 0)
- {
- Initialize();
-
- BOOL helper_result = FALSE;
- helper_result = SetMaxThreadsHelper(MaxWorkerThreads, MaxIOCompletionThreads);
-
- Initialization = -1;
- return helper_result;
- }
- else // someone else is initializing. Too late, return false
- {
- return FALSE;
- }
+ EnsureInitialized();
+ return SetMaxThreadsHelper(MaxWorkerThreads, MaxIOCompletionThreads);
}
BOOL ThreadpoolMgr::GetMaxThreads(DWORD* MaxWorkerThreads,
- DWORD* MaxIOCompletionThreads)
+ DWORD* MaxIOCompletionThreads)
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HRESULT hr = S_OK;
-
- IHostThreadpoolManager *threadpoolProvider = CorHost2::GetHostThreadpoolManager();
- if (threadpoolProvider) {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = threadpoolProvider->GetMaxThreads(MaxWorkerThreads);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- {
- SetLastHRError(hr);
- return FALSE;
- }
- }
-
- IHostIoCompletionManager *ioCompletionProvider = CorHost2::GetHostIoCompletionManager();
- if (ioCompletionProvider) {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = ioCompletionProvider->GetMaxThreads(MaxIOCompletionThreads);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- {
- SetLastHRError(hr);
- return FALSE;
- }
- }
-
- if (threadpoolProvider && ioCompletionProvider) {
- return TRUE;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
if (!MaxWorkerThreads || !MaxIOCompletionThreads)
{
@@ -675,44 +580,15 @@ BOOL ThreadpoolMgr::GetMaxThreads(DWORD* MaxWorkerThreads,
return FALSE;
}
- if (IsInitialized())
- {
- *MaxWorkerThreads = (DWORD)MaxLimitTotalWorkerThreads;
- *MaxIOCompletionThreads = MaxLimitTotalCPThreads;
- }
- else
- {
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), *MaxWorkerThreads = 1024);
-
- //ThreadPool_CPUGroup
- CPUGroupInfo::EnsureInitialized();
- if (CPUGroupInfo::CanEnableGCCPUGroups() && CPUGroupInfo::CanEnableThreadUseAllCpuGroups())
- NumberOfProcessors = CPUGroupInfo::GetNumActiveProcessors();
- else
- NumberOfProcessors = GetCurrentProcessCpuCount();
- DWORD min = GetForceMinWorkerThreadsValue();
- if (min == 0)
- min = NumberOfProcessors;
-
- DWORD forceMax = GetForceMaxWorkerThreadsValue();
- if (forceMax > 0)
- {
- *MaxWorkerThreads = forceMax;
- }
- else
- {
- *MaxWorkerThreads = GetDefaultMaxLimitWorkerThreads(min);
- }
-
- END_SO_INTOLERANT_CODE;
+ EnsureInitialized();
- *MaxIOCompletionThreads = MaxLimitTotalCPThreads;
- }
+ *MaxWorkerThreads = (DWORD)MaxLimitTotalWorkerThreads;
+ *MaxIOCompletionThreads = MaxLimitTotalCPThreads;
return TRUE;
}
BOOL ThreadpoolMgr::SetMinThreads(DWORD MinWorkerThreads,
- DWORD MinIOCompletionThreads)
+ DWORD MinIOCompletionThreads)
{
CONTRACTL
{
@@ -722,139 +598,64 @@ BOOL ThreadpoolMgr::SetMinThreads(DWORD MinWorkerThreads,
}
CONTRACTL_END;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HRESULT hr = S_OK;
-
- IHostThreadpoolManager *threadpoolProvider = CorHost2::GetHostThreadpoolManager();
- if (threadpoolProvider) {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = threadpoolProvider->SetMinThreads(MinWorkerThreads);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- {
- SetLastHRError(hr);
- return FALSE;
- }
- }
+ EnsureInitialized();
- IHostIoCompletionManager *ioCompletionProvider = CorHost2::GetHostIoCompletionManager();
- if (ioCompletionProvider) {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = ioCompletionProvider->SetMinThreads(MinIOCompletionThreads);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- {
- SetLastHRError(hr);
- return FALSE;
- }
- }
- if (threadpoolProvider && ioCompletionProvider) {
- return TRUE;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
+ // doesn't need to be WorkerCS, but using it to avoid race condition between setting min and max, and didn't want to create a new CS.
+ CrstHolder csh(&WorkerCriticalSection);
- if (!IsInitialized())
- {
- if (InterlockedCompareExchange(&Initialization, 1, 0) == 0)
- {
- Initialize();
- Initialization = -1;
- }
- }
+ BOOL init_result = FALSE;
- if (IsInitialized())
+ if (MinWorkerThreads >= 0 && MinIOCompletionThreads >= 0 &&
+ MinWorkerThreads <= (DWORD) MaxLimitTotalWorkerThreads &&
+ MinIOCompletionThreads <= (DWORD) MaxLimitTotalCPThreads)
{
- // doesn't need to be WorkerCS, but using it to avoid race condition between setting min and max, and didn't want to create a new CS.
- CrstHolder csh(&WorkerCriticalSection);
-
- BOOL init_result = false;
+ BEGIN_SO_INTOLERANT_CODE(GetThread());
- if (MinWorkerThreads >= 0 && MinIOCompletionThreads >= 0 &&
- MinWorkerThreads <= (DWORD) MaxLimitTotalWorkerThreads &&
- MinIOCompletionThreads <= (DWORD) MaxLimitTotalCPThreads)
+ if (GetForceMinWorkerThreadsValue() == 0)
{
- BEGIN_SO_INTOLERANT_CODE(GetThread());
+ MinLimitTotalWorkerThreads = min(MinWorkerThreads, (DWORD)ThreadCounter::MaxPossibleCount);
- if (GetForceMinWorkerThreadsValue() == 0)
+ ThreadCounter::Counts counts = WorkerCounter.GetCleanCounts();
+ while (counts.MaxWorking < MinLimitTotalWorkerThreads)
{
- MinLimitTotalWorkerThreads = min(MinWorkerThreads, (DWORD)ThreadCounter::MaxPossibleCount);
+ ThreadCounter::Counts newCounts = counts;
+ newCounts.MaxWorking = MinLimitTotalWorkerThreads;
- ThreadCounter::Counts counts = WorkerCounter.GetCleanCounts();
- while (counts.MaxWorking < MinLimitTotalWorkerThreads)
+ ThreadCounter::Counts oldCounts = WorkerCounter.CompareExchangeCounts(newCounts, counts);
+ if (oldCounts == counts)
{
- ThreadCounter::Counts newCounts = counts;
- newCounts.MaxWorking = MinLimitTotalWorkerThreads;
-
- ThreadCounter::Counts oldCounts = WorkerCounter.CompareExchangeCounts(newCounts, counts);
- if (oldCounts == counts)
- {
- counts = newCounts;
+ counts = newCounts;
- // if we increased the limit, and there are pending workitems, we need
- // to dispatch a thread to process the work.
- if (newCounts.MaxWorking > oldCounts.MaxWorking &&
- PerAppDomainTPCountList::AreRequestsPendingInAnyAppDomains())
- {
- MaybeAddWorkingWorker();
- }
- }
- else
+ // if we increased the limit, and there are pending workitems, we need
+ // to dispatch a thread to process the work.
+ if (newCounts.MaxWorking > oldCounts.MaxWorking &&
+ PerAppDomainTPCountList::AreRequestsPendingInAnyAppDomains())
{
- counts = oldCounts;
+ MaybeAddWorkingWorker();
}
}
+ else
+ {
+ counts = oldCounts;
+ }
}
+ }
- END_SO_INTOLERANT_CODE;
-
- MinLimitTotalCPThreads = min(MinIOCompletionThreads, (DWORD)ThreadCounter::MaxPossibleCount);
+ END_SO_INTOLERANT_CODE;
- init_result = TRUE;
- }
+ MinLimitTotalCPThreads = min(MinIOCompletionThreads, (DWORD)ThreadCounter::MaxPossibleCount);
- return init_result;
+ init_result = TRUE;
}
- // someone else is initializing. Too late, return false
- return FALSE;
+ return init_result;
}
BOOL ThreadpoolMgr::GetMinThreads(DWORD* MinWorkerThreads,
- DWORD* MinIOCompletionThreads)
+ DWORD* MinIOCompletionThreads)
{
LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HRESULT hr = S_OK;
-
- IHostThreadpoolManager *threadpoolProvider = CorHost2::GetHostThreadpoolManager();
- if (threadpoolProvider) {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = threadpoolProvider->GetMinThreads(MinWorkerThreads);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- {
- SetLastHRError(hr);
- return FALSE;
- }
- }
-
- IHostIoCompletionManager *ioCompletionProvider = CorHost2::GetHostIoCompletionManager();
- if (ioCompletionProvider) {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = ioCompletionProvider->GetMinThreads(MinIOCompletionThreads);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- {
- SetLastHRError(hr);
- return FALSE;
- }
- }
-
- if (threadpoolProvider && ioCompletionProvider) {
- return TRUE;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
if (!MinWorkerThreads || !MinIOCompletionThreads)
{
@@ -862,25 +663,10 @@ BOOL ThreadpoolMgr::GetMinThreads(DWORD* MinWorkerThreads,
return FALSE;
}
- if (IsInitialized())
- {
- *MinWorkerThreads = (DWORD)MinLimitTotalWorkerThreads;
- *MinIOCompletionThreads = MinLimitTotalCPThreads;
- }
- else
- {
- CPUGroupInfo::EnsureInitialized();
- if (CPUGroupInfo::CanEnableGCCPUGroups() && CPUGroupInfo::CanEnableThreadUseAllCpuGroups())
- NumberOfProcessors = CPUGroupInfo::GetNumActiveProcessors();
- else
- NumberOfProcessors = GetCurrentProcessCpuCount();
- DWORD forceMin;
- BEGIN_SO_INTOLERANT_CODE_NOTHROW(GetThread(), forceMin=0);
- forceMin = GetForceMinWorkerThreadsValue();
- END_SO_INTOLERANT_CODE;
- *MinWorkerThreads = forceMin > 0 ? forceMin : NumberOfProcessors;
- *MinIOCompletionThreads = NumberOfProcessors;
- }
+ EnsureInitialized();
+
+ *MinWorkerThreads = (DWORD)MinLimitTotalWorkerThreads;
+ *MinIOCompletionThreads = MinLimitTotalCPThreads;
return TRUE;
}
@@ -889,63 +675,26 @@ BOOL ThreadpoolMgr::GetAvailableThreads(DWORD* AvailableWorkerThreads,
{
LIMITED_METHOD_CONTRACT;
- if (IsInitialized())
+ if (!AvailableWorkerThreads || !AvailableIOCompletionThreads)
{
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HRESULT hr = S_OK;
-
- IHostThreadpoolManager *threadpoolProvider = CorHost2::GetHostThreadpoolManager();
- if (threadpoolProvider) {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = threadpoolProvider->GetAvailableThreads(AvailableWorkerThreads);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- {
- SetLastHRError(hr);
- return FALSE;
- }
- }
-
- IHostIoCompletionManager *ioCompletionProvider = CorHost2::GetHostIoCompletionManager();
- if (ioCompletionProvider) {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- hr = ioCompletionProvider->GetAvailableThreads(AvailableIOCompletionThreads);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- {
- SetLastHRError(hr);
- return FALSE;
- }
- }
-
- if (threadpoolProvider && ioCompletionProvider) {
- return TRUE;
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
+ SetLastHRError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
- if (!AvailableWorkerThreads || !AvailableIOCompletionThreads)
- {
- SetLastHRError(ERROR_INVALID_DATA);
- return FALSE;
- }
+ EnsureInitialized();
- ThreadCounter::Counts counts = WorkerCounter.GetCleanCounts();
+ ThreadCounter::Counts counts = WorkerCounter.GetCleanCounts();
- if (MaxLimitTotalWorkerThreads < counts.NumActive)
- *AvailableWorkerThreads = 0;
- else
- *AvailableWorkerThreads = MaxLimitTotalWorkerThreads - counts.NumWorking;
+ if (MaxLimitTotalWorkerThreads < counts.NumActive)
+ *AvailableWorkerThreads = 0;
+ else
+ *AvailableWorkerThreads = MaxLimitTotalWorkerThreads - counts.NumWorking;
- counts = CPThreadCounter.GetCleanCounts();
- if (MaxLimitTotalCPThreads < counts.NumActive)
- *AvailableIOCompletionThreads = counts.NumActive - counts.NumWorking;
- else
- *AvailableIOCompletionThreads = MaxLimitTotalCPThreads - counts.NumWorking;
- }
+ counts = CPThreadCounter.GetCleanCounts();
+ if (MaxLimitTotalCPThreads < counts.NumActive)
+ *AvailableIOCompletionThreads = counts.NumActive - counts.NumWorking;
else
- {
- GetMaxThreads(AvailableWorkerThreads,AvailableIOCompletionThreads);
- }
+ *AvailableIOCompletionThreads = MaxLimitTotalCPThreads - counts.NumWorking;
return TRUE;
}
@@ -1078,33 +827,6 @@ BOOL ThreadpoolMgr::QueueUserWorkItem(LPTHREAD_START_ROUTINE Function,
EnsureInitialized();
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- HRESULT hr = S_OK;
-
- IHostThreadpoolManager *provider = CorHost2::GetHostThreadpoolManager();
- if (provider) {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
-
- if(UnmanagedTPRequest)
- {
- hr = provider->QueueUserWorkItem(Function, Context, Flags);
- }
- else
- {
- hr = provider->QueueUserWorkItem(ExecuteHostRequest, Context, Flags);
- }
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(hr))
- {
- SetLastHRError(hr);
- return FALSE;
- }
- else
- {
- return TRUE;
- }
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
if (Flags == CALL_OR_QUEUE)
{
@@ -1141,8 +863,6 @@ BOOL ThreadpoolMgr::QueueUserWorkItem(LPTHREAD_START_ROUTINE Function,
bool ThreadpoolMgr::ShouldWorkerKeepRunning()
{
WRAPPER_NO_CONTRACT;
- if (CLRThreadpoolHosted())
- return true;
//
// Maybe this thread should retire now. Let's see.
@@ -1197,7 +917,6 @@ void ThreadpoolMgr::AdjustMaxWorkersActive()
}
CONTRACTL_END;
- _ASSERTE(!CLRThreadpoolHosted());
_ASSERTE(ThreadAdjustmentLock.IsHeld());
DWORD currentTicks = GetTickCount();
@@ -1283,8 +1002,6 @@ void ThreadpoolMgr::MaybeAddWorkingWorker()
}
CONTRACTL_END;
- _ASSERTE(!CLRThreadpoolHosted());
-
// counts volatile read paired with CompareExchangeCounts loop set
ThreadCounter::Counts counts = WorkerCounter.DangerousGetDirtyCounts();
ThreadCounter::Counts newCounts;
@@ -1380,27 +1097,6 @@ BOOL ThreadpoolMgr::PostQueuedCompletionStatus(LPOVERLAPPED lpOverlapped,
#ifndef FEATURE_PAL
EnsureInitialized();
- // if hosted then we need to queue to worker thread, since hosting API doesn't include this method
- if (CLRIoCompletionHosted())
- {
- PostRequestHolder postRequest = MakePostRequest(Function, lpOverlapped);
- if (postRequest)
- {
- // Will execute in the Default AppDomain
- if (FALSE == QueueUserWorkItem(QUWIPostCompletion, postRequest, QUEUE_ONLY))
- {
- return FALSE;
- }
- else
- {
- postRequest.SuppressRelease();
- return TRUE;
- }
- }
- else
- return FALSE;
- }
-
_ASSERTE(GlobalCompletionPort != NULL);
if (!InitCompletionPortThreadpool)
@@ -1663,44 +1359,12 @@ BOOL ThreadpoolMgr::DrainCompletionPortQueue()
}
-DWORD __stdcall ThreadpoolMgr::QUWIPostCompletion(PVOID pArgs)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- SO_INTOLERANT;
- }
- CONTRACTL_END;
-
- PostRequest* postRequest = (PostRequest*) pArgs;
-
- EX_TRY
- {
- (postRequest->Function)(postRequest->errorCode, postRequest->numBytesTransferred, postRequest->lpOverlapped);
- }
- EX_CATCH
- {
- RecycleMemory( postRequest, MEMTYPE_PostRequest );
- if (!SwallowUnhandledExceptions())
- EX_RETHROW;
- }
- EX_END_CATCH(SwallowAllExceptions);
- return ERROR_SUCCESS;
-
-}
-
-
// This is either made by a worker thread or a CP thread
// indicated by threadTypeStatus
void ThreadpoolMgr::EnsureGateThreadRunning()
{
LIMITED_METHOD_CONTRACT;
- // The gate thread is only needed if the CLR is providing part of the ThreadPool implementation.
- _ASSERTE(!CLRThreadpoolHosted() || !CLRIoCompletionHosted());
-
while (true)
{
switch (GateThreadStatus)
@@ -1750,9 +1414,6 @@ bool ThreadpoolMgr::ShouldGateThreadKeepRunning()
{
LIMITED_METHOD_CONTRACT;
- // The gate thread is only needed if the CLR is providing part of the ThreadPool implementation.
- _ASSERTE(!CLRThreadpoolHosted() || !CLRIoCompletionHosted());
-
_ASSERTE(GateThreadStatus == GATE_THREAD_STATUS_WAITING_FOR_REQUEST ||
GateThreadStatus == GATE_THREAD_STATUS_REQUESTED);
@@ -1780,8 +1441,7 @@ bool ThreadpoolMgr::ShouldGateThreadKeepRunning()
// Are there any work requests in any worker queue? If so, we need a gate thread.
// This imples that whenever a work queue goes from empty to non-empty, we need to call EnsureGateThreadRunning().
//
- bool needGateThreadForWorkerThreads =
- !CLRThreadpoolHosted() &&
+ bool needGateThreadForWorkerThreads =
PerAppDomainTPCountList::AreRequestsPendingInAnyAppDomains();
//
@@ -1884,18 +1544,6 @@ void ThreadpoolMgr::ExecuteWorkRequest(bool* foundWork, bool* wasNotRecalled)
return;
}
- if(IsThreadPoolHosted())
- {
- //Only managed callBacks go this route under hosts.
- //Also, since if we came here, atleast one managed requests was
- //created, and that means atleast one app domain exists.
-
- if (index == -1)
- {
- index = 1;
- }
- }
-
if (index == -1)
{
pAdCount = PerAppDomainTPCountList::GetUnmanagedTPCount();
@@ -2050,9 +1698,6 @@ LPVOID ThreadpoolMgr::GetRecycledMemory(enum MemType memType)
case MEMTYPE_WorkRequest:
result = new WorkRequest;
break;
- case MEMTYPE_PostRequest:
- result = new PostRequest;
- break;
default:
_ASSERTE(!"Unknown Memtype");
result = NULL;
@@ -2097,9 +1742,6 @@ void ThreadpoolMgr::RecycleMemory(LPVOID mem, enum MemType memType)
case MEMTYPE_WorkRequest:
delete (WorkRequest*) mem;
break;
- case MEMTYPE_PostRequest:
- delete (PostRequest*) mem;
- break;
default:
_ASSERTE(!"Unknown Memtype");
@@ -2110,7 +1752,7 @@ void ThreadpoolMgr::RecycleMemory(LPVOID mem, enum MemType memType)
// This is to avoid the 64KB/1MB aliasing problem present on Pentium 4 processors,
// which can significantly impact performance with HyperThreading enabled
-DWORD __stdcall ThreadpoolMgr::intermediateThreadProc(PVOID arg)
+DWORD WINAPI ThreadpoolMgr::intermediateThreadProc(PVOID arg)
{
WRAPPER_NO_CONTRACT;
STATIC_CONTRACT_SO_INTOLERANT;
@@ -2178,10 +1820,9 @@ Thread* ThreadpoolMgr::CreateUnimpersonatedThread(LPTHREAD_START_ROUTINE lpStart
}
else {
#ifndef FEATURE_PAL
- ThreadAffinityHolder affinityHolder(FALSE);
HandleHolder token;
BOOL bReverted = FALSE;
- bOK = RevertIfImpersonated(&bReverted, &token, &affinityHolder);
+ bOK = RevertIfImpersonated(&bReverted, &token);
if (bOK != TRUE)
return NULL;
#endif // !FEATURE_PAL
@@ -2250,7 +1891,7 @@ BOOL ThreadpoolMgr::CreateWorkerThread()
}
-DWORD __stdcall ThreadpoolMgr::WorkerThreadStart(LPVOID lpArgs)
+DWORD WINAPI ThreadpoolMgr::WorkerThreadStart(LPVOID lpArgs)
{
ClrFlsSetThreadType (ThreadType_Threadpool_Worker);
@@ -2263,8 +1904,6 @@ DWORD __stdcall ThreadpoolMgr::WorkerThreadStart(LPVOID lpArgs)
}
CONTRACTL_END;
- _ASSERTE(!CLRThreadpoolHosted());
-
Thread *pThread = NULL;
DWORD dwSwitchCount = 0;
BOOL fThreadInit = FALSE;
@@ -2949,7 +2588,7 @@ DWORD ThreadpoolMgr::MinimumRemainingWait(LIST_ENTRY* waitInfo, unsigned int num
#pragma warning(disable:22008) // "Prefast integer overflow check on (0 + lval) is bogus. Tried local disable without luck, doing whole method."
#endif
-DWORD __stdcall ThreadpoolMgr::WaitThreadStart(LPVOID lpArgs)
+DWORD WINAPI ThreadpoolMgr::WaitThreadStart(LPVOID lpArgs)
{
CONTRACTL
{
@@ -3216,7 +2855,7 @@ void ThreadpoolMgr::ProcessWaitCompletion(WaitInfo* waitInfo,
}
-DWORD __stdcall ThreadpoolMgr::AsyncCallbackCompletion(PVOID pArgs)
+DWORD WINAPI ThreadpoolMgr::AsyncCallbackCompletion(PVOID pArgs)
{
CONTRACTL
{
@@ -3529,9 +3168,6 @@ BOOL ThreadpoolMgr::CreateGateThread()
{
LIMITED_METHOD_CONTRACT;
- // The gate thread is only needed if the CLR is providing part of the ThreadPool implementation.
- _ASSERTE(!CLRThreadpoolHosted() || !CLRIoCompletionHosted());
-
HANDLE threadHandle = Thread::CreateUtilityThread(Thread::StackSize_Small, GateThreadStart, NULL);
if (threadHandle)
@@ -3567,23 +3203,6 @@ BOOL ThreadpoolMgr::BindIoCompletionCallback(HANDLE FileHandle,
EnsureInitialized();
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostIoCompletionManager *provider = CorHost2::GetHostIoCompletionManager();
- if (provider) {
- BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread());
- errCode = provider->Bind(GlobalCompletionPort, FileHandle);
- END_SO_TOLERANT_CODE_CALLING_HOST;
- if (FAILED(errCode))
- {
- SetLastHRError(errCode);
- return FALSE;
- }
- else
- {
- return TRUE;
- }
- }
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
_ASSERTE(GlobalCompletionPort != NULL);
@@ -3649,7 +3268,7 @@ BOOL ThreadpoolMgr::CreateCompletionPortThread(LPVOID lpArgs)
return FALSE;
}
-DWORD __stdcall ThreadpoolMgr::CompletionPortThreadStart(LPVOID lpArgs)
+DWORD WINAPI ThreadpoolMgr::CompletionPortThreadStart(LPVOID lpArgs)
{
ClrFlsSetThreadType (ThreadType_Threadpool_IOCompletion);
@@ -3662,8 +3281,6 @@ DWORD __stdcall ThreadpoolMgr::CompletionPortThreadStart(LPVOID lpArgs)
}
CONTRACTL_END;
- _ASSERTE (!CLRIoCompletionHosted());
-
DWORD numBytes=0;
size_t key=0;
@@ -3808,8 +3425,6 @@ Top:
{
_ASSERTE (context == NULL || context->lpOverlapped == NULL);
- LeaveRuntimeHolder holder((size_t)GetQueuedCompletionStatus);
-
BOOL status = GetQueuedCompletionStatus(
GlobalCompletionPort,
&numBytes,
@@ -4109,15 +3724,8 @@ LPOVERLAPPED ThreadpoolMgr::CompletionPortDispatchWorkWithinAppDomain(
OVERLAPPEDDATAREF overlapped=NULL;
BOOL ManagedCallback=FALSE;
- if (CLRIoCompletionHosted())
- {
- return NULL;
- }
-
*pErrorCode = S_OK;
- LeaveRuntimeHolder holder((size_t)GetQueuedCompletionStatus);
-
//Very Very Important!
//Do not change the timeout for GetQueuedCompletionStatus to a non-zero value.
@@ -4504,7 +4112,7 @@ public:
};
-DWORD __stdcall ThreadpoolMgr::GateThreadStart(LPVOID lpArgs)
+DWORD WINAPI ThreadpoolMgr::GateThreadStart(LPVOID lpArgs)
{
ClrFlsSetThreadType (ThreadType_Gate);
@@ -4517,9 +4125,6 @@ DWORD __stdcall ThreadpoolMgr::GateThreadStart(LPVOID lpArgs)
}
CONTRACTL_END;
- // The gate thread is only needed if the CLR is providing part of the ThreadPool implementation.
- _ASSERTE(!CLRThreadpoolHosted() || !CLRIoCompletionHosted());
-
_ASSERTE(GateThreadStatus == GATE_THREAD_STATUS_REQUESTED);
GateThreadTimer timer;
@@ -4654,8 +4259,6 @@ DWORD __stdcall ThreadpoolMgr::GateThreadStart(LPVOID lpArgs)
// don't mess with CP thread pool settings if not initialized yet
if (InitCompletionPortThreadpool)
{
- _ASSERTE (!CLRIoCompletionHosted());
-
ThreadCounter::Counts oldCounts, newCounts;
oldCounts = CPThreadCounter.GetCleanCounts();
@@ -4746,8 +4349,7 @@ DWORD __stdcall ThreadpoolMgr::GateThreadStart(LPVOID lpArgs)
}
#endif // !FEATURE_PAL
- if (!CLRThreadpoolHosted() &&
- (0 == CLRConfig::GetConfigValue(CLRConfig::INTERNAL_ThreadPool_DisableStarvationDetection)))
+ if (0 == CLRConfig::GetConfigValue(CLRConfig::INTERNAL_ThreadPool_DisableStarvationDetection))
{
if (PerAppDomainTPCountList::AreRequestsPendingInAnyAppDomains() && SufficientDelaySinceLastDequeue())
{
@@ -4961,7 +4563,7 @@ BOOL ThreadpoolMgr::CreateTimerQueueTimer(PHANDLE phNewTimer,
#pragma warning (disable : 4715)
#endif
#endif
-DWORD __stdcall ThreadpoolMgr::TimerThreadStart(LPVOID p)
+DWORD WINAPI ThreadpoolMgr::TimerThreadStart(LPVOID p)
{
ClrFlsSetThreadType (ThreadType_Timer);
@@ -5188,7 +4790,7 @@ DWORD ThreadpoolMgr::FireTimers()
return nextFiringInterval;
}
-DWORD __stdcall ThreadpoolMgr::AsyncTimerCallbackCompletion(PVOID pArgs)
+DWORD WINAPI ThreadpoolMgr::AsyncTimerCallbackCompletion(PVOID pArgs)
{
CONTRACTL
{
@@ -5244,7 +4846,7 @@ void ThreadpoolMgr::DeactivateTimer(TimerInfo* timerInfo)
timerInfo->state = timerInfo->state & ~TIMER_ACTIVE;
}
-DWORD __stdcall ThreadpoolMgr::AsyncDeleteTimer(PVOID pArgs)
+DWORD WINAPI ThreadpoolMgr::AsyncDeleteTimer(PVOID pArgs)
{
CONTRACTL
{
diff --git a/src/vm/win32threadpool.h b/src/vm/win32threadpool.h
index 6b4f1dfe07..65be889a50 100644
--- a/src/vm/win32threadpool.h
+++ b/src/vm/win32threadpool.h
@@ -455,8 +455,7 @@ public:
MEMTYPE_AsyncCallback = 0,
MEMTYPE_DelegateInfo = 1,
MEMTYPE_WorkRequest = 2,
- MEMTYPE_PostRequest = 3,
- MEMTYPE_COUNT = 4,
+ MEMTYPE_COUNT = 3,
};
static BOOL Initialize();
@@ -554,17 +553,6 @@ public:
static BOOL HaveTimerInfosToFlush() { return TimerInfosToBeRecycled != NULL; }
- inline static BOOL IsThreadPoolHosted()
- {
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- IHostThreadpoolManager *provider = CorHost2::GetHostThreadpoolManager();
- if (provider)
- return TRUE;
- else
-#endif
- return FALSE;
- }
-
#ifndef FEATURE_PAL
static LPOVERLAPPED CompletionPortDispatchWorkWithinAppDomain(Thread* pThread, DWORD* pErrorCode, DWORD* pNumBytes, size_t* pKey, DWORD adid);
static void StoreOverlappedInfoInThread(Thread* pThread, DWORD dwErrorCode, DWORD dwNumBytes, size_t key, LPOVERLAPPED lpOverlapped);
@@ -617,44 +605,6 @@ private:
wr->next = NULL;
return wr;
}
-
- struct PostRequest {
- LPOVERLAPPED_COMPLETION_ROUTINE Function;
- DWORD errorCode;
- DWORD numBytesTransferred;
- LPOVERLAPPED lpOverlapped;
- };
-
-
- inline static PostRequest* MakePostRequest(LPOVERLAPPED_COMPLETION_ROUTINE function, LPOVERLAPPED overlapped)
- {
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;;
-
- PostRequest* pr = (PostRequest*) GetRecycledMemory(MEMTYPE_PostRequest);
- _ASSERTE(pr);
- if (NULL == pr)
- return NULL;
- pr->Function = function;
- pr->errorCode = 0;
- pr->numBytesTransferred = 0;
- pr->lpOverlapped = overlapped;
-
- return pr;
- }
-
- inline static void ReleasePostRequest(PostRequest *postRequest)
- {
- WRAPPER_NO_CONTRACT;
- ThreadpoolMgr::RecycleMemory(postRequest, MEMTYPE_PostRequest);
- }
-
- typedef Wrapper< PostRequest *, DoNothing<PostRequest *>, ThreadpoolMgr::ReleasePostRequest > PostRequestHolder;
#endif // #ifndef DACCESS_COMPILE
@@ -1047,7 +997,7 @@ public:
// Private methods
- static DWORD __stdcall intermediateThreadProc(PVOID arg);
+ static DWORD WINAPI intermediateThreadProc(PVOID arg);
typedef struct {
LPTHREAD_START_ROUTINE lpThreadFunction;
@@ -1128,20 +1078,14 @@ public:
static void NotifyWorkItemCompleted()
{
WRAPPER_NO_CONTRACT;
- if (!CLRThreadpoolHosted())
- {
- Thread::IncrementThreadPoolCompletionCount();
- UpdateLastDequeueTime();
- }
+ Thread::IncrementThreadPoolCompletionCount();
+ UpdateLastDequeueTime();
}
static bool ShouldAdjustMaxWorkersActive()
{
WRAPPER_NO_CONTRACT;
- if (CLRThreadpoolHosted())
- return false;
-
DWORD priorTime = PriorCompletedWorkRequestsTime;
MemoryBarrier(); // read fresh value for NextCompletedWorkRequestsTime below
DWORD requiredInterval = NextCompletedWorkRequestsTime - priorTime;
@@ -1163,7 +1107,7 @@ public:
static DWORD SafeWait(CLREvent * ev, DWORD sleepTime, BOOL alertable);
- static DWORD __stdcall WorkerThreadStart(LPVOID lpArgs);
+ static DWORD WINAPI WorkerThreadStart(LPVOID lpArgs);
static BOOL AddWaitRequest(HANDLE waitHandle, WaitInfo* waitInfo);
@@ -1172,7 +1116,7 @@ public:
static BOOL CreateWaitThread();
- static void __stdcall InsertNewWaitForSelf(WaitInfo* pArg);
+ static void WINAPI InsertNewWaitForSelf(WaitInfo* pArg);
static int FindWaitIndex(const ThreadCB* threadCB, const HANDLE waitHandle);
@@ -1182,14 +1126,12 @@ public:
unsigned index, // array index
BOOL waitTimedOut);
- static DWORD __stdcall WaitThreadStart(LPVOID lpArgs);
+ static DWORD WINAPI WaitThreadStart(LPVOID lpArgs);
- static DWORD __stdcall AsyncCallbackCompletion(PVOID pArgs);
+ static DWORD WINAPI AsyncCallbackCompletion(PVOID pArgs);
static void QueueTimerInfoForRelease(TimerInfo *pTimerInfo);
- static DWORD __stdcall QUWIPostCompletion(PVOID pArgs);
-
static void DeactivateWait(WaitInfo* waitInfo);
static void DeactivateNthWait(WaitInfo* waitInfo, DWORD index);
@@ -1210,7 +1152,7 @@ public:
count * sizeof(LIST_ENTRY));
}
- static void __stdcall DeregisterWait(WaitInfo* pArgs);
+ static void WINAPI DeregisterWait(WaitInfo* pArgs);
#ifndef FEATURE_PAL
// holds the aggregate of system cpu usage of all processors
@@ -1227,7 +1169,7 @@ public:
static int GetCPUBusyTime_NT(PROCESS_CPU_INFORMATION* pOldInfo);
static BOOL CreateCompletionPortThread(LPVOID lpArgs);
- static DWORD __stdcall CompletionPortThreadStart(LPVOID lpArgs);
+ static DWORD WINAPI CompletionPortThreadStart(LPVOID lpArgs);
public:
inline static bool HaveNativeWork()
{
@@ -1248,7 +1190,7 @@ private:
static BOOL CreateGateThread();
static void EnsureGateThreadRunning();
static bool ShouldGateThreadKeepRunning();
- static DWORD __stdcall GateThreadStart(LPVOID lpArgs);
+ static DWORD WINAPI GateThreadStart(LPVOID lpArgs);
static BOOL SufficientDelaySinceLastSample(unsigned int LastThreadCreationTime,
unsigned NumThreads, // total number of threads of that type (worker or CP)
double throttleRate=0.0 // the delay is increased by this percentage for each extra thread
@@ -1257,17 +1199,17 @@ private:
static LPVOID GetRecycledMemory(enum MemType memType);
- static DWORD __stdcall TimerThreadStart(LPVOID args);
+ static DWORD WINAPI TimerThreadStart(LPVOID args);
static void TimerThreadFire(); // helper method used by TimerThreadStart
- static void __stdcall InsertNewTimer(TimerInfo* pArg);
+ static void WINAPI InsertNewTimer(TimerInfo* pArg);
static DWORD FireTimers();
- static DWORD __stdcall AsyncTimerCallbackCompletion(PVOID pArgs);
+ static DWORD WINAPI AsyncTimerCallbackCompletion(PVOID pArgs);
static void DeactivateTimer(TimerInfo* timerInfo);
- static DWORD __stdcall AsyncDeleteTimer(PVOID pArgs);
+ static DWORD WINAPI AsyncDeleteTimer(PVOID pArgs);
static void DeleteTimer(TimerInfo* timerInfo);
- static void __stdcall UpdateTimer(TimerUpdateInfo* pArgs);
+ static void WINAPI UpdateTimer(TimerUpdateInfo* pArgs);
- static void __stdcall DeregisterTimer(TimerInfo* pArgs);
+ static void WINAPI DeregisterTimer(TimerInfo* pArgs);
inline static DWORD QueueDeregisterWait(HANDLE waitThread, WaitInfo* waitInfo)
{
diff --git a/src/vm/wks/CMakeLists.txt b/src/vm/wks/CMakeLists.txt
index 360845d0b2..1da2ab8477 100644
--- a/src/vm/wks/CMakeLists.txt
+++ b/src/vm/wks/CMakeLists.txt
@@ -105,11 +105,21 @@ if (WIN32)
endif()
add_custom_command(
- # The AsmConstants.inc will be built in the pre-build phase of the cee_wks build
- TARGET cee_wks PRE_BUILD
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/AsmConstants.inc"
+ DEPENDS ${VM_DIR}/${ARCH_SOURCES_DIR}/asmconstants.h
COMMAND ${POWERSHELL} -NoProfile -ExecutionPolicy Bypass -NonInteractive \"& \"\"${VM_DIR}/h2inc.ps1\"\"\" \"\"\"${VM_DIR}/${ARCH_SOURCES_DIR}/asmconstants.h\"\"\" >"${CMAKE_CURRENT_BINARY_DIR}/AsmConstants.tmp"
COMMAND ${CMAKE_CXX_COMPILER} ${DEFINITIONS} /EP "${CMAKE_CURRENT_BINARY_DIR}/AsmConstants.tmp" >"${CMAKE_CURRENT_BINARY_DIR}/AsmConstants.inc"
)
+
+ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/AsmConstants.inc PROPERTIES GENERATED TRUE)
+
+ add_custom_target(
+ asmconstants_inc
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/AsmConstants.inc
+ )
+
+ add_dependencies(cee_wks asmconstants_inc)
+
endif(NOT CLR_CMAKE_PLATFORM_ARCH_ARM)
endif (WIN32)
diff --git a/src/zap/common.h b/src/zap/common.h
index b3db657f87..0abb2ce751 100644
--- a/src/zap/common.h
+++ b/src/zap/common.h
@@ -32,9 +32,6 @@
#include "jithost.h"
#include "corcompile.h"
#include "iceefilegen.h"
-#ifdef FEATURE_FUSION
-#include "fusionbind.h"
-#endif
#include "corpriv.h"
#include "holder.h"
@@ -50,9 +47,6 @@
#include "guidfromname.h"
#include "../dlls/mscorrc/resource.h"
#include "zaplog.h"
-#ifndef FEATURE_CORECLR
-#include "eventmsg.h"
-#endif // FEATURE_CORECLR
#include "ndpversion.h"
#include "loaderheap.h"
diff --git a/src/zap/svcworker.cpp b/src/zap/svcworker.cpp
index 001345ce1c..eb7d8d92ac 100644
--- a/src/zap/svcworker.cpp
+++ b/src/zap/svcworker.cpp
@@ -25,9 +25,6 @@ NGenWorkerEmbedding() -- called when COM invoked the COM server with
#include "common.h"
-#ifdef FEATURE_FUSION
-#include "binderngen.h"
-#endif
#ifdef FEATURE_APPX
#include "AppXUtil.h"
@@ -201,60 +198,6 @@ ICorSvcLogger* SvcLogger::GetSvcLogger()
return pCorSvcLogger;
}
-#ifndef FEATURE_CORECLR
-
-void InitNGenOptions(NGenOptions *ngo,
- NGenPrivateAttributes ngenPrivateAttributes,
- OptimizationScenario optScenario = ScenarioDefault,
- LPCWSTR lpszRepositoryDir = NULL, RepositoryFlags repositoryFlags = RepositoryDefault)
-{
- ULONG_PTR pScenario = (ULONG_PTR) optScenario;
-
- ngo->dwSize = sizeof(NGenOptions);
-
- // V1
- //
- ngo->fDebug = (pScenario & ScenarioDebug) ? true : false;
- ngo->fDebugOpt = false;
- ngo->fProf = (pScenario & ScenarioProfile) ? true : false;
- ngo->fSilent = false;
- ngo->lpszExecutableFileName = NULL;
-
- // V2 (Whidbey)
- //
- ngo->fInstrument = (pScenario & ScenarioTuningDataCollection) ? true : false;
- ngo->fWholeProgram = false;
- ngo->fProfInfo = (pScenario & ScenarioProfileInfo) ? true : false;
-
- ngo->lpszRepositoryDir = lpszRepositoryDir;
- ngo->repositoryFlags = repositoryFlags;
-
- ngo->dtRequested = DT_NIL;
- ngo->lpszDebugDir = NULL;
-
- ngo->fNoInstall = false;
- ngo->fEmitFixups = false;
- ngo->fFatHeaders = false;
- ngo->fVerbose = false;
-
- // This should be a value from the StatOptions enumeration
- ngo->uStats = ngenPrivateAttributes.ZapStats;
- ngo->dtRequested = (ngenPrivateAttributes.Flags & DbgTypePdb) ? DT_PDB : DT_NIL;
- ngo->lpszDebugDir = ngenPrivateAttributes.DbgDir;
-
-
- // V4
- //
- ngo->fNgenLastRetry = (pScenario & ScenarioNgenLastRetry) ? true : false;
-
- // V4.5
- ngo->fAutoNGen = (pScenario & ScenarioAutoNGen) ? true : false;
-
- // Blue
- ngo->fRepositoryOnly = (pScenario & ScenarioRepositoryOnly) ? true : false;
-}
-
-#endif // !FEATURE_CORECLR
namespace
{
@@ -288,769 +231,3 @@ void SetSvcLogger(ICorSvcLogger *pCorSvcLogger)
}
#endif
-#ifndef FEATURE_CORECLR
-
-//*****************************************************************************
-// ICorSvcDependencies is used to enumerate the dependencies of an
-// IL image. It is used by the native image service.
-//*****************************************************************************[
-class CCorSvcDependencies : public ICorSvcDependencies
-{
-public:
- CCorSvcDependencies()
- {
- _cRef = 0;
- zapper = NULL;
-
- g_pLocalServerLifetime->AddRefServerProcess();
- }
-
- ~CCorSvcDependencies()
- {
- if (zapper != NULL)
- {
- delete zapper;
- }
-
- g_pLocalServerLifetime->ReleaseServerProcess();
- }
-
- void Initialize(BSTR pApplicationName, OptimizationScenario scenario)
- {
- NGenOptions opt = {0};
- NGenPrivateAttributesClass ngenPrivateAttributesClass;
- InitNGenOptions(&opt, ngenPrivateAttributesClass, scenario);
- opt.lpszExecutableFileName = pApplicationName;
- zapper = Zapper::NewZapper(&opt, true);
- zapper->CreateDependenciesLookupDomain();
- }
-
- STDMETHOD (GetAssemblyDependencies)(
- BSTR pAssemblyName,
- SAFEARRAY **pDependencies,
- DWORD *assemblyNGenSetting,
- BSTR *pNativeImageIdentity,
- BSTR *pAssemblyDisplayName,
- SAFEARRAY **pDependencyLoadSetting,
- SAFEARRAY **pDependencyNGenSetting
- )
- {
- SO_NOT_MAINLINE_FUNCTION;
-
- _ASSERTE(zapper != NULL);
- _ASSERTE(pNativeImageIdentity);
-
- HRESULT hr = S_OK;
- EX_TRY
- {
- GUID nativeImageSign = INVALID_NGEN_SIGNATURE;
- zapper->ComputeDependencies(pAssemblyName, &nativeImageSign);
-
- BSTRHolder displayNameHolder(::SysAllocString(zapper->m_assemblyDependencies.GetDisplayName()));
-
- *pDependencies = zapper->m_assemblyDependencies.GetSAFEARRAY();
- *assemblyNGenSetting = zapper->m_assemblyDependencies.GetNGenHint();
- *pDependencyLoadSetting = zapper->m_assemblyDependencies.GetLoadHintSAFEARRAY();
- *pDependencyNGenSetting = zapper->m_assemblyDependencies.GetNGenHintSAFEARRAY();
-
- if (nativeImageSign != INVALID_NGEN_SIGNATURE)
- {
- WCHAR szGuid[64];
- if (GuidToLPWSTR(nativeImageSign, szGuid, sizeof(szGuid) / sizeof(WCHAR)) == 0)
- {
- ThrowHR(E_UNEXPECTED);
- }
- *pNativeImageIdentity = ::SysAllocString(szGuid);
- }
-
- *pAssemblyDisplayName = displayNameHolder.Extract();
- }
- EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
-
- return hr;
- }
-
- STDMETHODIMP_(ULONG) AddRef()
- {
- return InterlockedIncrement (&_cRef);
- }
-
- STDMETHODIMP_(ULONG) Release()
- {
- SO_NOT_MAINLINE_FUNCTION;
-
- ULONG lRet = InterlockedDecrement (&_cRef);
- if (!lRet)
- delete this;
- return lRet;
- }
-
- STDMETHODIMP QueryInterface(REFIID riid,void ** ppv)
- {
- SO_NOT_MAINLINE_FUNCTION;
-
- if (!ppv)
- return E_POINTER;
-
- if (IsEqualIID(riid, IID_IUnknown) ||
- IsEqualIID(riid, IID_ICorSvcDependencies))
- {
- *ppv = static_cast<ICorSvcDependencies*> (this);
- AddRef();
- return S_OK;
- }
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- }
-
-private:
- LONG _cRef;
- Zapper *zapper;
-};
-
-//*****************************************************************************
-// CCorSvcCreatePdbWorker is used to load the CLR, initialize an appdomain,
-// load the given assembly and create a PDB for it.
-//*****************************************************************************
-class CCorSvcCreatePdbWorker {
-
-public:
-
- CCorSvcCreatePdbWorker()
- : m_pZapper(NULL)
- {
- }
-
- ~CCorSvcCreatePdbWorker()
- {
- if (m_pZapper)
- delete m_pZapper;
- }
-
- void Initialize(BSTR pAppBaseOrConfig, OptimizationScenario scenario)
- {
- _ASSERTE(m_pZapper == NULL);
-
- NGenOptions options = {0};
- NGenPrivateAttributesClass privateAttributesClass;
-
- InitNGenOptions(&options, privateAttributesClass, scenario);
- options.lpszExecutableFileName = pAppBaseOrConfig;
- m_pZapper = Zapper::NewZapper(&options, true);
- m_pZapper->CreateDependenciesLookupDomain();
- }
-
-
- HRESULT CreatePdb(BSTR pAssemblyName, BSTR pNativeImagePath, BSTR pPdbPath, BOOL pdbLines, BSTR pManagedPdbSearchPath)
- {
- SO_NOT_MAINLINE_FUNCTION;
- _ASSERTE(m_pZapper);
-
- HRESULT hr = S_OK;
- EX_TRY {
-
- m_pZapper->CreatePdb(pAssemblyName, pNativeImagePath, pPdbPath, pdbLines, pManagedPdbSearchPath);
-
- } EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
-
- return hr;
- }
-
-private:
-
- Zapper *m_pZapper;
-
-};
-
-#ifdef _DEBUG
- inline void DoFreeEnvironmentStrings(LPTCH lpszEnvironmentBlock)
- {
- WszFreeEnvironmentStrings(lpszEnvironmentBlock);
- }
- typedef Wrapper<LPTCH, DoNothing, DoFreeEnvironmentStrings> EnvHolder;
-#endif //_DEBUG
-
-//*****************************************************************************
-// ICorSvcWorker contains methods for generating native images and enumerating
-// their dependencies.
-//*****************************************************************************[
-class CCorSvcWorker :
- public ICorSvcWorker3,
- public ICorSvcRepository,
- public ICorSvcSetPrivateAttributes,
-#ifdef FEATURE_APPX
- public ICorSvcAppX,
-#endif
- public ICorSvcPooledWorker
-{
-public:
- CCorSvcWorker() :
- _cRef(0),
- repositoryDir(NULL),
- repositoryFlags(RepositoryDefault),
- ngenPrivateAttributesClass()
-
-#ifdef FEATURE_FUSION
- ,
- pAssemblyCache(NULL)
-#endif
- {
- g_pLocalServerLifetime->AddRefServerProcess();
- }
-
- ~CCorSvcWorker()
- {
-#ifdef FEATURE_FUSION
- if (pAssemblyCache != NULL)
- {
- pAssemblyCache->Release();
- pAssemblyCache = NULL;
- }
-#endif
-
- GetSvcLogger()->ReleaseLogger();
-
- g_pLocalServerLifetime->ReleaseServerProcess();
- }
-
- STDMETHOD (SetPriority)(
- /*[in]*/ SvcWorkerPriority priority
- )
- {
- HRESULT hr = E_FAIL;
-
- // Set ourselves to the priority
- if (::SetPriorityClass(GetCurrentProcess(), priority.dwPriorityClass) == FALSE)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- goto DONE;
- }
-
- hr = S_OK;
- DONE:
- return hr;
- }
-
-#ifdef _DEBUG
- void Debug_CheckPPLProcessStatus(
- LPCWSTR wszAssemblyName)
- {
- size_t cchAssemblyName = wcslen(wszAssemblyName);
-
- // Check if we are in PPL (Protected Process Lightweight) by checking existence of LOCALAPPDATA env. var. (it is not present in PPL)
- BOOL fIsProcessPPL = TRUE;
- EnvHolder pEnvironmentStrings(WszGetEnvironmentStrings());
- for (LPTCH pEnv = pEnvironmentStrings; ((pEnv != NULL) && (*pEnv != W('\0'))); pEnv += wcslen(pEnv) + 1)
- {
- static const WCHAR const_wszLocalAppData[] = W("LOCALAPPDATA=");
- static const size_t const_cchLocalAppData = _countof(const_wszLocalAppData) - 1;
- if (_wcsnicmp(pEnv, const_wszLocalAppData, const_cchLocalAppData) == 0)
- { // LOCALAPPDATA is never set in PPL process
- fIsProcessPPL = FALSE;
- break;
- }
- }
-
- // Semicolon-separated list of names that should assert a failure
- NewArrayHolder<WCHAR> wszAssertList = NULL;
- if (fIsProcessPPL)
- { // If we are in PPL, we should assert for assemblies that are fobidden to be ngen'd in PPL
- CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NGenProtectedProcess_ForbiddenList, &wszAssertList);
- }
- else
- { // If we are not in PPL, we should assert for assemblies that require to be ngen'd in PPL
- CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NGenProtectedProcess_RequiredList, &wszAssertList);
- }
-
- if ((wszAssertList != NULL) && (*wszAssertList != W('\0')))
- {
- LPCWSTR pAssertListName = wszAssertList;
- for (;;)
- {
- LPCWSTR pAssertListNameEnd = wcschr(pAssertListName, W(';'));
- size_t cchAssertListName;
- if (pAssertListNameEnd == NULL)
- { // There is not another semicolon
- cchAssertListName = wcslen(pAssertListName);
- }
- else
- {
- cchAssertListName = pAssertListNameEnd - pAssertListName;
- }
-
- if ((cchAssertListName > 0) && (cchAssertListName <= cchAssemblyName))
- {
- // Check prefix or suffix of assembly name (which is either file name or assembly identity name)
- if ((_wcsnicmp(wszAssemblyName, pAssertListName, cchAssertListName) == 0) ||
- (_wcsnicmp(wszAssemblyName + cchAssemblyName - cchAssertListName, pAssertListName, cchAssertListName) == 0))
- {
- if (fIsProcessPPL)
- {
- _ASSERTE_MSG(FALSE, "Assembly that is in NGenProtectedProcess_ForbiddenList is ngen'd in PPL process!");
- }
- else
- {
- _ASSERTE_MSG(FALSE, "Assembly that is in NGenProtectedProcess_RequiredList is ngen'd in normal (non-PPL) process!");
- }
- }
- }
-
- if (pAssertListNameEnd == NULL)
- { // There are no more names in the semicolon-separated list
- break;
- }
-
- // Move to next item in the semicolon-separated list (skip also the semicolon)
- pAssertListName = pAssertListNameEnd + 1;
- }
- }
- } // Debug_CheckPPLProcessStatus
-#endif //_DEBUG
-
- STDMETHOD (OptimizeAssembly)(
- BSTR pAssemblyName,
- BSTR pApplicationName,
- OptimizationScenario scenario,
- SAFEARRAY *loadAlwaysList,
- SAFEARRAY *loadSometimesList,
- SAFEARRAY *loadNeverList,
- BSTR *pNativeImageIdentity
- )
- {
- SO_NOT_MAINLINE_FUNCTION;
-
- INDEBUG(Debug_CheckPPLProcessStatus(pAssemblyName);)
-
- HRESULT hr = S_OK;
- EX_TRY
- {
-#if defined(_DEBUG) || defined(ALLOW_LOCAL_WORKER)
- // Make sure optimize is called only once per process
- static int OptimizeCount = 0;
-#ifdef ALLOW_LOCAL_WORKER
- if (OptimizeCount != 0)
- {
- GetSvcLogger()->Printf(W("You cannot call OptimizeAssembly twice. If you are using COMPlus_NgenLocalWorker, make sure you are only optimizing one assembly.\r\n"));
- ThrowHR(E_FAIL);
- }
-#else // _DEBUG
- _ASSERTE(OptimizeCount == 0);
-#endif
- OptimizeCount++;
-#endif
-
- NGenOptions opt = {0};
- InitNGenOptions(&opt, ngenPrivateAttributesClass, scenario, repositoryDir, repositoryFlags);
- opt.lpszExecutableFileName = pApplicationName;
-
- GUID nativeImageSign;
- bool hasProfileData;
-
- hr = ZapperCompileWrapper(pAssemblyName, &opt, &nativeImageSign,
- loadAlwaysList, loadSometimesList, loadNeverList,
- true, &hasProfileData);
-#if 0
- // Unfotunately we can't perform a retry here as the Zapper currently
- // allocates and initializes some things once CompilationDomain and
- // thus some of this stuff will leak from the failed complation.
- //
- if (FAILED(hr) && hasProfileData && retryNgenFailures)
- {
- hr = ZapperCompileWrapper(pAssemblyName, &opt, &nativeImageSign,
- loadAlwaysList, loadSometimesList, loadNeverList,
- false, NULL);
- if (SUCCEEDED(hr))
- {
- StackSString msg;
- msg.Printf(W("The compile failed when the profile data was used and ")
- W("the compile succeeded when the profile data was ignored."));
- GetSvcLogger()->Log(msg, LogLevel_Info);
- }
- }
-#endif
- IfFailThrow(hr);
-
- _ASSERTE(nativeImageSign != INVALID_NGEN_SIGNATURE || opt.fRepositoryOnly);
-
- _ASSERTE(pNativeImageIdentity);
- if (nativeImageSign != INVALID_NGEN_SIGNATURE)
- {
- WCHAR szGuid[64];
- if (GuidToLPWSTR(nativeImageSign, szGuid, sizeof(szGuid) / sizeof(WCHAR)) == 0)
- ThrowHR(E_UNEXPECTED);
- *pNativeImageIdentity = ::SysAllocString(szGuid);
- }
- else
- {
- *pNativeImageIdentity = NULL;
- }
- }
- EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
-
- return hr;
- }
-
- STDMETHOD (DeleteNativeImage)(
- BSTR pAssemblyName,
- BSTR pNativeImage
- )
- {
- // The caller must either specify both parameters, or specify neither.
- _ASSERTE((pAssemblyName == NULL && pNativeImage == NULL) ||
- (pAssemblyName != NULL && pNativeImage != NULL));
-
- HRESULT hr = S_OK;
- EX_TRY
- {
- NGenOptions opt = {0};
- InitNGenOptions(&opt, ngenPrivateAttributesClass);
- NewHolder<Zapper> zapper = Zapper::NewZapper(&opt, true);
- _ASSERTE(zapper != NULL);
-
- GUID *pNativeImageMVID = NULL;
- GUID nativeImageMVID;
-
- if (pNativeImage)
- {
- StackSString nativeImageString(pNativeImage);
- StackScratchBuffer buffer;
- LPCSTR pstr = nativeImageString.GetANSI(buffer);
- IfFailThrow(LPCSTRToGuid((LPCSTR) pstr, &nativeImageMVID));
- pNativeImageMVID = &nativeImageMVID;
- }
-
-#ifdef FEATURE_FUSION
- if (pAssemblyName != NULL && pNativeImageMVID != NULL)
- {
- // Deleting a specific native image.
- zapper->DeleteFusionCacheEntry(pAssemblyName, pNativeImageMVID);
- }
- else if (pAssemblyName != NULL || pNativeImageMVID != NULL)
- {
- hr = E_UNEXPECTED;
- }
- else
- {
- // Not deleting a specific native image. Need to enumerate NIC.
- IfFailThrow(zapper->EnumerateFusionCache(NULL, false, true, NULL));
- }
-#else //FEATURE_FUSION
- _ASSERTE(!"NYI");
-#endif //FEATURE_FUSION
- }
- EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
-
- return hr;
- }
-
- STDMETHOD (DisplayNativeImages)(BSTR pAssemblyName)
- {
-#ifdef FEATURE_FUSION
- HRESULT hr = S_OK;
- EX_TRY
- {
- NGenOptions opt = {0};
- InitNGenOptions(&opt, ngenPrivateAttributesClass);
- NewHolder<Zapper> zapper = Zapper::NewZapper(&opt, true);
- _ASSERTE(zapper != NULL);
-
- IfFailThrow(zapper->EnumerateFusionCache(pAssemblyName, true, false, NULL));
- }
- EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
-
- return hr;
-#else //FEATURE_FUSION
- return E_NOTIMPL;
-#endif //FEATURE_FUSION
- }
-
- STDMETHOD(GetCorSvcDependencies)(
- BSTR pApplicationName,
- OptimizationScenario scenario,
- ICorSvcDependencies **ppCorSvcDependencies
- )
- {
- SO_NOT_MAINLINE_FUNCTION;
-
- HRESULT hr = S_OK;
- EX_TRY
- {
- NewHolder<CCorSvcDependencies> pCorSvcDependencies(new CCorSvcDependencies());
- pCorSvcDependencies->Initialize(pApplicationName, scenario);
- IfFailThrow(pCorSvcDependencies->QueryInterface(IID_ICorSvcDependencies, (void **) ppCorSvcDependencies));
- pCorSvcDependencies.SuppressRelease();
- }
- EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
-
- return hr;
- }
-
- STDMETHOD(Stop)()
- {
- return S_OK;
- }
-
- STDMETHOD(CreatePdb)(__in BSTR pAssemblyName,
- __in BSTR pAppBaseOrConfig,
- __in OptimizationScenario scenario,
- __in BSTR pNativeImagePath,
- __in BSTR pPdbPath)
- {
- return CreatePdb2(
- pAssemblyName,
- pAppBaseOrConfig,
- scenario,
- pNativeImagePath,
- pPdbPath,
- FALSE,
- NULL);
- }
-
- STDMETHOD(CreatePdb2)(__in BSTR pAssemblyName,
- __in BSTR pAppBaseOrConfig,
- __in OptimizationScenario scenario,
- __in BSTR pNativeImagePath,
- __in BSTR pPdbPath,
- __in BOOL pdbLines,
- __in BSTR pManagedPdbSearchPath)
- {
- SO_NOT_MAINLINE_FUNCTION;
-
- HRESULT hr = S_OK;
-
- EX_TRY {
-
- CCorSvcCreatePdbWorker worker;
- worker.Initialize(pAppBaseOrConfig, scenario);
- hr = worker.CreatePdb(pAssemblyName, pNativeImagePath, pPdbPath, pdbLines, pManagedPdbSearchPath);
-
- } EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
-
- return hr;
- }
-
-#ifdef FEATURE_APPX
- STDMETHOD(SetPackage)(__in BSTR pPackageFullName)
- {
- return AppX::SetCurrentPackageForNGen(pPackageFullName);
- }
-
- STDMETHOD(SetLocalAppDataDirectory)(__in BSTR pLocalAppDataDirectory)
- {
- return Clr::Util::SetLocalAppDataDirectory(pLocalAppDataDirectory);
- }
-#endif
-
- STDMETHOD (SetRepository)(
- BSTR pRepositoryDir,
- RepositoryFlags flags
- )
- {
- _ASSERTE(repositoryFlags == RepositoryDefault);
- _ASSERTE(repositoryDir == NULL);
-
- repositoryDir = ::SysAllocString(pRepositoryDir);
- repositoryFlags = flags;
-
- return S_OK;
- }
-
- STDMETHOD (SetNGenPrivateAttributes)(
- NGenPrivateAttributes ngenPrivateAttributes
- )
- {
- _ASSERTE(ngenPrivateAttributesClass.Flags == 0);
- _ASSERTE(ngenPrivateAttributesClass.ZapStats == 0);
-
- ngenPrivateAttributesClass.Flags = ngenPrivateAttributes.Flags;
- ngenPrivateAttributesClass.ZapStats = ngenPrivateAttributes.ZapStats;
-
- if (ngenPrivateAttributes.DbgDir)
- {
- _ASSERTE(ngenPrivateAttributesClass.DbgDir == NULL);
- ngenPrivateAttributesClass.DbgDir = ::SysAllocString(ngenPrivateAttributes.DbgDir);
- }
-
- return S_OK;
- }
-
- STDMETHOD (CanReuseProcess)(
- OptimizationScenario scenario,
- ICorSvcLogger *pCorSvcLogger,
- BOOL *pCanContinue)
- {
- SO_NOT_MAINLINE_FUNCTION;
-
- HRESULT hr = S_OK;
-
- _ASSERTE(pCanContinue != NULL);
- *pCanContinue = FALSE;
-
- return hr;
- }
-
- static HRESULT CreateObject(REFIID riid, void **ppUnk)
- {
- HRESULT hr;
- CCorSvcWorker *pCorSvcWorker = new (nothrow) CCorSvcWorker();
-
- if (pCorSvcWorker == 0)
- return (E_OUTOFMEMORY);
-
- hr = pCorSvcWorker->QueryInterface(riid, ppUnk);
- if (FAILED(hr))
- delete pCorSvcWorker;
- return (hr);
- }
-
- STDMETHODIMP_(ULONG) AddRef()
- {
- return InterlockedIncrement (&_cRef);
- }
-
- STDMETHODIMP_(ULONG) Release()
- {
- ULONG lRet = InterlockedDecrement (&_cRef);
- if (!lRet)
- delete this;
- return lRet;
- }
-
- STDMETHODIMP QueryInterface(REFIID riid,void ** ppv)
- {
- if (!ppv)
- return E_POINTER;
-
- if (IsEqualIID(riid, IID_IUnknown) ||
- IsEqualIID(riid, IID_ICorSvcWorker))
- {
- *ppv = static_cast<ICorSvcWorker*> (this);
- AddRef();
- return S_OK;
- }
- else if (IsEqualIID(riid, IID_ICorSvcWorker2))
- {
- *ppv = static_cast<ICorSvcWorker2 *>(this);
- AddRef();
- return S_OK;
- }
- else if (IsEqualIID(riid, IID_ICorSvcWorker3))
- {
- *ppv = static_cast<ICorSvcWorker3 *>(this);
- AddRef();
- return S_OK;
- }
- else if (IsEqualIID(riid, IID_ICorSvcRepository))
- {
- *ppv = static_cast<ICorSvcRepository*> (this);
- AddRef();
- return S_OK;
- }
- else if (IsEqualIID(riid, IID_ICorSvcSetPrivateAttributes))
- {
- *ppv = static_cast<ICorSvcSetPrivateAttributes *> (this);
- AddRef();
- return S_OK;
- }
-#ifdef FEATURE_APPX
- else if (IsEqualIID(riid, IID_ICorSvcAppX))
- {
- *ppv = static_cast<ICorSvcAppX *> (this);
- AddRef();
- return S_OK;
- }
-#endif
- else if (IsEqualIID(riid, IID_ICorSvcPooledWorker))
- {
- *ppv = static_cast<ICorSvcPooledWorker *> (this);
- AddRef();
- return S_OK;
- }
- else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
- }
-
-private:
- HRESULT ZapperCompileWrapper(BSTR pAssemblyName,
- NGenOptions * pOpt,
- GUID * pNativeImageSign,
- SAFEARRAY * loadAlwaysList,
- SAFEARRAY * loadSometimesList,
- SAFEARRAY * loadNeverList,
- bool useProfileData,
- bool * pHasProfileData)
- {
- NewHolder<Zapper> zapper(Zapper::NewZapper(pOpt, true));
-
- *pNativeImageSign = INVALID_NGEN_SIGNATURE;
-
- // Push the load lists to the zapper
- zapper->SetLoadLists(loadAlwaysList, loadSometimesList, loadNeverList);
- if (useProfileData == false)
- {
- zapper->DontUseProfileData();
- }
-
- HRESULT hr = zapper->Compile(pAssemblyName, pNativeImageSign);
-
- if (pHasProfileData != NULL)
- {
- *pHasProfileData = zapper->HasProfileData();
- }
-
- if (!FAILED(hr) && (*pNativeImageSign == INVALID_NGEN_SIGNATURE) && !pOpt->fRepositoryOnly)
- {
- // Unfortunately we can get a passing HR when an EE exception was
- // thrown because the zapper EH logic can't get the correct HR
- // out of the EE exception. This will be fixed, but for now we
- // should also return E_FAIL in that case.
-
- hr = E_FAIL;
- }
-
- return hr;
- }
-
-private:
- LONG _cRef;
-
- BSTRHolder repositoryDir;
- RepositoryFlags repositoryFlags;
-
- NGenPrivateAttributesClass ngenPrivateAttributesClass;
-
-#ifdef FEATURE_FUSION
- IAssemblyCache *pAssemblyCache;
-#endif // FEATURE_FUSION
-};
-
-STDAPI NGenCreateNGenWorker(ICorSvcWorker **pCorSvcWorker, ILocalServerLifetime *pLocalServerLifetime, ICorSvcLogger *pCorSvcLogger)
-{
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- EX_TRY
- {
- _ASSERTE(pLocalServerLifetime);
- //_ASSERTE(g_pLocalServerLifetime == NULL);
-
- g_pLocalServerLifetime = pLocalServerLifetime;
-
- GetSvcLogger()->SetSvcLogger(pCorSvcLogger);
-
- IfFailThrow(CCorSvcWorker::CreateObject(IID_ICorSvcWorker, (void **) pCorSvcWorker));
- }
- EX_CATCH_HRESULT_AND_NGEN_CLEAN(hr);
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-#endif // !FEATURE_CORECLR
diff --git a/src/zap/zapcode.cpp b/src/zap/zapcode.cpp
index e54e884bc2..738428354d 100644
--- a/src/zap/zapcode.cpp
+++ b/src/zap/zapcode.cpp
@@ -1202,6 +1202,28 @@ void ZapUnwindData::Save(ZapWriter * pZapWriter)
#endif //REDHAWK
}
+#elif defined(_TARGET_X86_)
+
+UINT ZapUnwindData::GetAlignment()
+{
+ return sizeof(BYTE);
+}
+
+DWORD ZapUnwindData::GetSize()
+{
+ return ZapBlob::GetSize();
+}
+
+void ZapUnwindData::Save(ZapWriter * pZapWriter)
+{
+ ZapImage * pImage = ZapImage::GetImage(pZapWriter);
+
+ PVOID pData = GetData();
+ DWORD dwSize = GetBlobSize();
+
+ pZapWriter->Write(pData, dwSize);
+}
+
#elif defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
UINT ZapUnwindData::GetAlignment()
diff --git a/src/zap/zapheaders.cpp b/src/zap/zapheaders.cpp
index 2422c98a0b..acec36bf2a 100644
--- a/src/zap/zapheaders.cpp
+++ b/src/zap/zapheaders.cpp
@@ -95,7 +95,7 @@ void ZapImage::SaveNativeHeader()
// Pretend that ready-to-run images are IL-only
nativeHeader.COR20Flags |= COMIMAGE_FLAGS_ILONLY;
- // Pretend that ready-to-run images do not have native header
+ // Pretend that ready-to-run images do not have a native header
nativeHeader.COR20Flags &= ~COMIMAGE_FLAGS_IL_LIBRARY;
// Remember whether the source IL image had ReadyToRun header
@@ -171,11 +171,13 @@ void ZapImage::SaveCodeManagerEntry()
if (m_stats)
{
+#define ACCUM_SIZE(dest, src) if( src != NULL ) dest+= src->GetSize()
// this is probably supposed to mean Hot+Unprofiled
- m_stats->m_totalHotCodeSize = m_pHotCodeSection->GetSize();
- m_stats->m_totalUnprofiledCodeSize = m_pCodeSection->GetSize();
- m_stats->m_totalColdCodeSize = m_pColdCodeSection->GetSize();
- m_stats->m_totalCodeSizeInProfiledMethods = m_pHotCodeSection->GetSize();
+ ACCUM_SIZE(m_stats->m_totalHotCodeSize, m_pHotCodeSection);
+ ACCUM_SIZE(m_stats->m_totalUnprofiledCodeSize, m_pCodeSection);
+ ACCUM_SIZE(m_stats->m_totalColdCodeSize, m_pColdCodeSection);
+ ACCUM_SIZE(m_stats->m_totalCodeSizeInProfiledMethods, m_pHotCodeSection);
+#undef ACCUM_SIZE
m_stats->m_totalColdCodeSizeInProfiledMethods = codeManagerEntry.ColdUntrainedMethodOffset;
}
diff --git a/src/zap/zapimage.cpp b/src/zap/zapimage.cpp
index f39b8f8f54..cb69ba9f96 100644
--- a/src/zap/zapimage.cpp
+++ b/src/zap/zapimage.cpp
@@ -38,13 +38,10 @@
* --------------------------------------------------------------------------- */
ZapImage::ZapImage(Zapper *zapper)
- : m_zapper(zapper)
+ : m_zapper(zapper),
+ m_stats(new ZapperStats())
/* Everything else is initialized to 0 by default */
{
-#ifndef FEATURE_CORECLR
- if (m_zapper->m_pOpt->m_statOptions)
- m_stats = new ZapperStats();
-#endif
}
ZapImage::~ZapImage()
@@ -57,10 +54,8 @@ ZapImage::~ZapImage()
//
// Clean up.
//
-#ifndef FEATURE_CORECLR
if (m_stats != NULL)
- delete m_stats;
-#endif
+ delete m_stats;
if (m_pModuleFileName != NULL)
delete [] m_pModuleFileName;
@@ -172,9 +167,7 @@ void ZapImage::InitializeSections()
m_pHelperThunks = new (GetHeap()) ZapNode * [CORINFO_HELP_COUNT];
-#ifdef FEATURE_CORECLR
if (!m_zapper->m_pOpt->m_fNoMetaData)
-#endif
{
m_pILMetaData = new (GetHeap()) ZapILMetaData(this);
m_pILMetaDataSection->Place(m_pILMetaData);
@@ -226,11 +219,7 @@ void ZapImage::InitializeSectionsForReadyToRun()
m_pHeaderSection->Place(m_pImportSectionsTable);
{
-#ifdef FEATURE_CORECLR
#define COMPILER_NAME "CoreCLR"
-#else
-#define COMPILER_NAME "CLR"
-#endif
const char * pCompilerIdentifier = COMPILER_NAME " " FX_FILEVERSION_STR " " QUOTE_MACRO(__BUILDMACHINE__);
ZapBlob * pCompilerIdentifierBlob = new (GetHeap()) ZapBlobPtr((PVOID)pCompilerIdentifier, strlen(pCompilerIdentifier) + 1);
@@ -1090,75 +1079,6 @@ HANDLE ZapImage::GenerateFile(LPCWSTR wszOutputFileName, CORCOMPILE_NGEN_SIGNATU
return hFile;
}
-#ifdef FEATURE_FUSION
-#define WOF_PROVIDER_FILE (0x00000002)
-
-typedef BOOL (WINAPI *WofShouldCompressBinaries_t) (
- __in LPCWSTR Volume,
- __out PULONG Algorithm
- );
-
-typedef HRESULT (WINAPI *WofSetFileDataLocation_t) (
- __in HANDLE hFile,
- __in ULONG Provider,
- __in PVOID FileInfo,
- __in ULONG Length
- );
-
-typedef struct _WOF_FILE_COMPRESSION_INFO {
- ULONG Algorithm;
-} WOF_FILE_COMPRESSION_INFO, *PWOF_FILE_COMPRESSION_INFO;
-
-// Check if files on the volume identified by volumeLetter should be compressed.
-// If yes, compress the file associated with hFile.
-static void CompressFile(WCHAR volumeLetter, HANDLE hFile)
-{
- if (IsNgenOffline())
- {
- return;
- }
-
- // Wofutil.dll is available on Windows 8.1 and above. Return on platforms without wofutil.dll.
- HModuleHolder wofLibrary(WszLoadLibraryEx(L"wofutil.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32));
- if (wofLibrary == nullptr)
- {
- return;
- }
-
- // WofShouldCompressBinaries is available on Windows 10 and above.
- // Windows 8.1 version of wofutil.dll does not have this function.
- WofShouldCompressBinaries_t WofShouldCompressBinaries
- = (WofShouldCompressBinaries_t)GetProcAddress(wofLibrary, "WofShouldCompressBinaries");
- if (WofShouldCompressBinaries == nullptr)
- {
- return;
- }
-
- WCHAR volume[4] = L"X:\\";
- volume[0] = volumeLetter;
- ULONG algorithm = 0;
-
- bool compressionSuitable = (WofShouldCompressBinaries(volume, &algorithm) == TRUE);
- if (compressionSuitable)
- {
- // WofSetFileDataLocation is available on Windows 8.1 and above, however, Windows 8.1 version
- // of WofSetFileDataLocation works for WIM only, and Windows 10 is required for compression of
- // normal files. This isn't a problem for us, since the check for WofShouldCompressBinaries
- // above should have already returned on Windows 8.1.
- WofSetFileDataLocation_t WofSetFileDataLocation =
- (WofSetFileDataLocation_t)GetProcAddress(wofLibrary, "WofSetFileDataLocation");
- if (WofSetFileDataLocation == nullptr)
- {
- return;
- }
-
- WOF_FILE_COMPRESSION_INFO fileInfo;
- fileInfo.Algorithm = algorithm;
-
- WofSetFileDataLocation(hFile, WOF_PROVIDER_FILE, &fileInfo, sizeof(WOF_FILE_COMPRESSION_INFO));
- }
-}
-#endif
HANDLE ZapImage::SaveImage(LPCWSTR wszOutputFileName, CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
{
@@ -1169,14 +1089,14 @@ HANDLE ZapImage::SaveImage(LPCWSTR wszOutputFileName, CORCOMPILE_NGEN_SIGNATURE
OutputTables();
- // Create a empty export table. This makes tools like symchk not think
- // that native images are resoure-only DLLs. It is important to NOT
- // be a resource-only DLL because those DLL's PDBS are not put up on the
- // symbol server and we want NEN PDBS to be placed there.
- ZapPEExports* exports = new(GetHeap()) ZapPEExports(wszOutputFileName);
- m_pDebugSection->Place(exports);
- SetDirectoryEntry(IMAGE_DIRECTORY_ENTRY_EXPORT, exports);
-
+ // Create a empty export table. This makes tools like symchk not think
+ // that native images are resoure-only DLLs. It is important to NOT
+ // be a resource-only DLL because those DLL's PDBS are not put up on the
+ // symbol server and we want NEN PDBS to be placed there.
+ ZapPEExports* exports = new(GetHeap()) ZapPEExports(wszOutputFileName);
+ m_pDebugSection->Place(exports);
+ SetDirectoryEntry(IMAGE_DIRECTORY_ENTRY_EXPORT, exports);
+
ComputeRVAs();
if (!IsReadyToRunCompilation())
@@ -1186,24 +1106,21 @@ HANDLE ZapImage::SaveImage(LPCWSTR wszOutputFileName, CORCOMPILE_NGEN_SIGNATURE
HANDLE hFile = GenerateFile(wszOutputFileName, pNativeImageSig);
-#ifndef FEATURE_CORECLR
- if (m_stats != NULL)
- PrintStats(wszOutputFileName);
-#endif
-
-#ifdef FEATURE_FUSION
- CompressFile(wszOutputFileName[0], hFile);
-#endif
return hFile;
}
void ZapImage::PrintStats(LPCWSTR wszOutputFileName)
{
- m_stats->m_gcInfoSize = m_pHotTouchedGCSection->GetSize() + m_pHotGCSection->GetSize() + m_pGCSection->GetSize();
+#define ACCUM_SIZE(dest, src) if( src != NULL ) dest+= src->GetSize()
+ ACCUM_SIZE(m_stats->m_gcInfoSize, m_pHotTouchedGCSection);
+ ACCUM_SIZE(m_stats->m_gcInfoSize, m_pHotGCSection);
+ ACCUM_SIZE(m_stats->m_gcInfoSize, m_pGCSection);
#if defined(WIN64EXCEPTIONS)
- m_stats->m_unwindInfoSize = m_pUnwindDataSection->GetSize() +
- m_pHotRuntimeFunctionSection->GetSize() + m_pRuntimeFunctionSection->GetSize() + m_pColdRuntimeFunctionSection->GetSize();
+ ACCUM_SIZE(m_stats->m_unwindInfoSize, m_pUnwindDataSection);
+ ACCUM_SIZE(m_stats->m_unwindInfoSize, m_pHotRuntimeFunctionSection);
+ ACCUM_SIZE(m_stats->m_unwindInfoSize, m_pRuntimeFunctionSection);
+ ACCUM_SIZE(m_stats->m_unwindInfoSize, m_pColdRuntimeFunctionSection);
#endif // defined(WIN64EXCEPTIONS)
//
@@ -1224,36 +1141,39 @@ void ZapImage::PrintStats(LPCWSTR wszOutputFileName)
m_stats->m_outputFileSize = outputData.nFileSizeLow;
}
- if (m_pAssemblyMetaData != NULL)
- m_stats->m_metadataSize = m_pAssemblyMetaData->GetSize();
+ ACCUM_SIZE(m_stats->m_metadataSize, m_pAssemblyMetaData);
DWORD dwPreloadSize = 0;
for (int iSection = 0; iSection < CORCOMPILE_SECTION_COUNT; iSection++)
- dwPreloadSize += m_pPreloadSections[iSection]->GetSize();
+ ACCUM_SIZE(dwPreloadSize, m_pPreloadSections[iSection]);
m_stats->m_preloadImageSize = dwPreloadSize;
- m_stats->m_hotCodeMgrSize = m_pHotCodeMethodDescsSection->GetSize();
- m_stats->m_unprofiledCodeMgrSize = m_pCodeMethodDescsSection->GetSize();
- m_stats->m_coldCodeMgrSize = m_pHotRuntimeFunctionLookupSection->GetSize();
-
- m_stats->m_eeInfoTableSize = m_pEEInfoTable->GetSize();
- m_stats->m_helperTableSize = m_pHelperTableSection->GetSize();
- m_stats->m_dynamicInfoTableSize = m_pImportSectionsTable->GetSize();
- m_stats->m_dynamicInfoDelayListSize = m_pDelayLoadInfoDelayListSectionEager->GetSize() + m_pDelayLoadInfoDelayListSectionHot->GetSize() + m_pDelayLoadInfoDelayListSectionCold->GetSize();
- m_stats->m_importTableSize = m_pImportTable->GetSize();
-
- m_stats->m_debuggingTableSize = m_pDebugSection->GetSize();
- m_stats->m_headerSectionSize = m_pGCSection->GetSize();
- m_stats->m_codeSectionSize = m_pHotCodeSection->GetSize();
- m_stats->m_coldCodeSectionSize = m_pColdCodeSection->GetSize();
- m_stats->m_exceptionSectionSize = m_pExceptionSection->GetSize();
- m_stats->m_readOnlyDataSectionSize = m_pReadOnlyDataSection->GetSize();
- m_stats->m_relocSectionSize = m_pBaseRelocsSection->GetSize();
- if (m_pILMetaData != NULL)
- m_stats->m_ILMetadataSize = m_pILMetaData->GetSize();
- m_stats->m_virtualImportThunkSize = m_pVirtualImportThunkSection->GetSize();
- m_stats->m_externalMethodThunkSize = m_pExternalMethodThunkSection->GetSize();
- m_stats->m_externalMethodDataSize = m_pExternalMethodDataSection->GetSize();
+ ACCUM_SIZE(m_stats->m_hotCodeMgrSize, m_pHotCodeMethodDescsSection);
+ ACCUM_SIZE(m_stats->m_unprofiledCodeMgrSize, m_pCodeMethodDescsSection);
+ ACCUM_SIZE(m_stats->m_coldCodeMgrSize, m_pHotRuntimeFunctionLookupSection);
+
+ ACCUM_SIZE(m_stats->m_eeInfoTableSize, m_pEEInfoTable);
+ ACCUM_SIZE(m_stats->m_helperTableSize, m_pHelperTableSection);
+ ACCUM_SIZE(m_stats->m_dynamicInfoTableSize, m_pImportSectionsTable);
+
+ ACCUM_SIZE(m_stats->m_dynamicInfoDelayListSize, m_pDelayLoadInfoDelayListSectionEager);
+ ACCUM_SIZE(m_stats->m_dynamicInfoDelayListSize, m_pDelayLoadInfoDelayListSectionHot);
+ ACCUM_SIZE(m_stats->m_dynamicInfoDelayListSize, m_pDelayLoadInfoDelayListSectionCold);
+
+ ACCUM_SIZE(m_stats->m_importTableSize, m_pImportTable);
+
+ ACCUM_SIZE(m_stats->m_debuggingTableSize, m_pDebugSection);
+ ACCUM_SIZE(m_stats->m_headerSectionSize, m_pGCSection);
+ ACCUM_SIZE(m_stats->m_codeSectionSize, m_pHotCodeSection);
+ ACCUM_SIZE(m_stats->m_coldCodeSectionSize, m_pColdCodeSection);
+ ACCUM_SIZE(m_stats->m_exceptionSectionSize, m_pExceptionSection);
+ ACCUM_SIZE(m_stats->m_readOnlyDataSectionSize, m_pReadOnlyDataSection);
+ ACCUM_SIZE(m_stats->m_relocSectionSize, m_pBaseRelocsSection);
+ ACCUM_SIZE(m_stats->m_ILMetadataSize, m_pILMetaData);
+ ACCUM_SIZE(m_stats->m_virtualImportThunkSize, m_pVirtualImportThunkSection);
+ ACCUM_SIZE(m_stats->m_externalMethodThunkSize, m_pExternalMethodThunkSection);
+ ACCUM_SIZE(m_stats->m_externalMethodDataSize, m_pExternalMethodDataSection);
+#undef ACCUM_SIZE
if (m_stats->m_failedMethods)
m_zapper->Warning(W("Warning: %d methods (%d%%) could not be compiled.\n"),
@@ -1354,10 +1274,6 @@ void ZapImage::CalculateZapBaseAddress()
//
// CoreCLR currently always loads both the IL and the native image, so
// move the native image out of the way.
-#ifndef FEATURE_CORECLR
- if (!m_ModuleDecoder.IsDll() || // exes always get loaded to their preferred base address
- !m_ModuleDecoder.IsILOnly()) // since the IL (IJW) image will be loaded first
-#endif // !FEATURE_CORECLR
{
baseAddress += m_ModuleDecoder.GetVirtualSize();
}
@@ -1414,28 +1330,6 @@ void ZapImage::Open(CORINFO_MODULE_HANDLE hModule,
m_ModuleDecoder = *m_zapper->m_pEECompileInfo->GetModuleDecoder(hModule);
-#ifdef FEATURE_FUSION
- // If TranslatePEToArchitectureType fails then we have an invalid format
- DWORD dwPEKind, dwMachine;
- m_ModuleDecoder.GetPEKindAndMachine(&dwPEKind, &dwMachine);
-
- PEKIND PeKind;
- IfFailThrow(TranslatePEToArchitectureType((CorPEKind)dwPEKind, dwMachine, &PeKind));
-
- // Valid images for this platform are peMSIL and the native image for the platform
- if (!(PeKind == peMSIL
-#if defined(_TARGET_AMD64_)
- || PeKind == peAMD64
-#elif defined(_TARGET_X86_)
- || PeKind == peI386
-#elif defined(_TARGET_ARM_)
- || PeKind == peARM
-#endif
- ))
- {
- ThrowHR(NGEN_E_EXE_MACHINE_TYPE_MISMATCH);
- }
-#endif // FEATURE_FUSION
//
// Get file name, and base address from module
@@ -1498,54 +1392,6 @@ void ZapImage::Open(CORINFO_MODULE_HANDLE hModule,
CalculateZapBaseAddress();
}
-#if !defined(FEATURE_CORECLR)
-
-#if (_WIN32_WINNT < _WIN32_WINNT_WIN8)
-
-typedef struct _WIN32_MEMORY_RANGE_ENTRY {
-
- PVOID VirtualAddress;
- SIZE_T NumberOfBytes;
-
-} WIN32_MEMORY_RANGE_ENTRY, *PWIN32_MEMORY_RANGE_ENTRY;
-
-#endif
-
-typedef BOOL
-(WINAPI *PfnPrefetchVirtualMemory)(
- _In_ HANDLE hProcess,
- _In_ ULONG_PTR NumberOfEntries,
- _In_reads_(NumberOfEntries) PWIN32_MEMORY_RANGE_ENTRY VirtualAddresses,
- _In_ ULONG Flags
- );
-
-
-void PrefetchVM(void * pStartAddress, SIZE_T size)
-{
- static PfnPrefetchVirtualMemory s_pfnPrefetchVirtualMemory = NULL;
-
- if (s_pfnPrefetchVirtualMemory == NULL)
- {
- s_pfnPrefetchVirtualMemory = (PfnPrefetchVirtualMemory) GetProcAddress(WszGetModuleHandle(WINDOWS_KERNEL32_DLLNAME_W), "PrefetchVirtualMemory");
-
- if (s_pfnPrefetchVirtualMemory == NULL)
- {
- s_pfnPrefetchVirtualMemory = (PfnPrefetchVirtualMemory) (1);
- }
- }
-
- if (s_pfnPrefetchVirtualMemory > (PfnPrefetchVirtualMemory) (1))
- {
- WIN32_MEMORY_RANGE_ENTRY range;
-
- range.VirtualAddress = pStartAddress;
- range.NumberOfBytes = size;
-
- s_pfnPrefetchVirtualMemory(GetCurrentProcess(), 1, & range, 0);
- }
-}
-
-#endif
@@ -1555,10 +1401,6 @@ void PrefetchVM(void * pStartAddress, SIZE_T size)
void ZapImage::Preload()
{
-#if !defined(FEATURE_CORECLR)
- // Prefetch the whole IL image into memory to avoid small reads (usually 16kb blocks)
- PrefetchVM(m_ModuleDecoder.GetBase(), m_ModuleDecoder.GetSize());
-#endif
CorProfileData * pProfileData = NewProfileData();
m_pPreloader = m_zapper->m_pEECompileInfo->PreloadModule(m_hModule, this, pProfileData);
@@ -1698,14 +1540,6 @@ void ZapImage::OutputTables()
if (IsReadyToRunCompilation())
{
-#ifndef FEATURE_CORECLR
- // Some older versions of Windows (e.g., Win7) can incorrectly fixup
- // relocations if IsDll is not set. In CoreCLR, we handle this by
- // always using the default value of IsDll, which is true. We can't
- // use the same fix in desktop CLR, since in this case the ReadyToRun
- // image can be used to create processes.
- SetIsDll(m_ModuleDecoder.IsDll());
-#endif
SetSizeOfStackReserve(m_ModuleDecoder.GetSizeOfStackReserve());
SetSizeOfStackCommit(m_ModuleDecoder.GetSizeOfStackCommit());
@@ -1714,7 +1548,7 @@ void ZapImage::OutputTables()
#if defined(FEATURE_PAL)
// PAL library requires native image sections to align to page bounaries.
SetFileAlignment(0x1000);
-#elif defined(_TARGET_ARM_) && defined(FEATURE_CORECLR) && defined(FEATURE_CORESYSTEM)
+#elif defined(_TARGET_ARM_) && defined(FEATURE_CORESYSTEM)
if (!IsReadyToRunCompilation())
{
// On ARM CoreSys builds, crossgen will use 4k file alignment, as requested by Phone perf team
@@ -1754,13 +1588,53 @@ ZapImage::CompileStatus ZapImage::CompileProfileDataWorker(mdToken token, unsign
return TryCompileMethodDef(token, methodProfilingDataFlags);
}
-void ZapImage::CompileProfileData()
+// ProfileDisableInlining
+// Before we start compiling any methods we may need to suppress the inlining
+// of certain methods based upon our profile data.
+// This method will arrange to disable this inlining.
+//
+void ZapImage::ProfileDisableInlining()
+{
+ // We suppress the inlining of any Hot methods that have the ExcludeHotMethodCode flag.
+ // We want such methods to be Jitted at runtime rather than compiled in the AOT native image.
+ // The inlining of such a method also need to be suppressed.
+ //
+ ProfileDataSection* methodProfileData = &(m_profileDataSections[MethodProfilingData]);
+ if (methodProfileData->tableSize > 0)
+ {
+ for (DWORD i = 0; i < methodProfileData->tableSize; i++)
+ {
+ CORBBTPROF_TOKEN_INFO * pTokenInfo = &(methodProfileData->pTable[i]);
+ unsigned methodProfilingDataFlags = pTokenInfo->flags;
+
+ // Hot methods can be marked to be excluded from the AOT native image.
+ // We also need to disable inlining of such methods.
+ //
+ if ((methodProfilingDataFlags & (1 << DisableInlining)) != 0)
+ {
+ // Disable the inlining of this method
+ //
+ // @ToDo: Figure out how to disable inlining for this method.
+ }
+ }
+ }
+}
+
+// CompileHotRegion
+// Performs the compilation and placement for all methods in the the "Hot" code region
+// Methods placed in this region typically correspond to all of the methods that were
+// executed during any of the profiling scenarios.
+//
+void ZapImage::CompileHotRegion()
{
+ // Compile all of the methods that were executed during profiling into the "Hot" code region.
+ //
BeginRegion(CORINFO_REGION_HOT);
CorProfileData* pProfileData = GetProfileData();
- if (m_profileDataSections[MethodProfilingData].tableSize > 0)
+ ProfileDataSection* methodProfileData = &(m_profileDataSections[MethodProfilingData]);
+ if (methodProfileData->tableSize > 0)
{
// record the start of hot IBC methods.
m_iIBCMethod = m_MethodCompilationOrder.GetCount();
@@ -1768,19 +1642,21 @@ void ZapImage::CompileProfileData()
//
// Compile the hot methods in the order specified in the MethodProfilingData
//
- for (DWORD i = 0; i < m_profileDataSections[MethodProfilingData].tableSize; i++)
+ for (DWORD i = 0; i < methodProfileData->tableSize; i++)
{
- unsigned methodProfilingDataFlags = m_profileDataSections[MethodProfilingData].pTable[i].flags;
- _ASSERTE(methodProfilingDataFlags != 0);
+ CompileStatus compileResult = NOT_COMPILED;
+ CORBBTPROF_TOKEN_INFO * pTokenInfo = &(methodProfileData->pTable[i]);
- mdToken token = m_profileDataSections[MethodProfilingData].pTable[i].token;
+ mdToken token = pTokenInfo->token;
+ unsigned methodProfilingDataFlags = pTokenInfo->flags;
+ _ASSERTE(methodProfilingDataFlags != 0);
if (TypeFromToken(token) == mdtMethodDef)
{
//
// Compile a non-generic method
//
- CompileProfileDataWorker(token, methodProfilingDataFlags);
+ compileResult = CompileProfileDataWorker(token, methodProfilingDataFlags);
}
else if (TypeFromToken(token) == ibcMethodSpec)
{
@@ -1804,10 +1680,14 @@ void ZapImage::CompileProfileData()
{
m_pPreloader->AddMethodToTransitiveClosureOfInstantiations(pMethod);
- TryCompileInstantiatedMethod(pMethod, methodProfilingDataFlags);
+ compileResult = TryCompileInstantiatedMethod(pMethod, methodProfilingDataFlags);
}
}
}
+
+ // Update the 'flags' and 'compileResult' saved in the profileDataHashTable hash table.
+ //
+ hashBBUpdateFlagsAndCompileResult(token, methodProfilingDataFlags, compileResult);
}
// record the start of hot Generics methods.
m_iGenericsMethod = m_MethodCompilationOrder.GetCount();
@@ -1819,72 +1699,92 @@ void ZapImage::CompileProfileData()
EndRegion(CORINFO_REGION_HOT);
}
-void ZapImage::Compile()
+// CompileColdRegion
+// Performs the compilation and placement for all methods in the the "Cold" code region
+// Methods placed in this region typically correspond to all of the methods that were
+// NOT executed during any of the profiling scenarios.
+//
+void ZapImage::CompileColdRegion()
{
+ // Compile all of the methods that were NOT executed during profiling into the "Cold" code region.
//
- // First, compile methods in the load order array.
- //
- bool doNothingNgen = false;
-#ifdef _DEBUG
- static ConfigDWORD fDoNothingNGen;
- doNothingNgen = !!fDoNothingNGen.val(CLRConfig::INTERNAL_ZapDoNothing);
-#endif
- if (!doNothingNgen)
+ BeginRegion(CORINFO_REGION_COLD);
+
+ IMDInternalImport * pMDImport = m_pMDImport;
+
+ HENUMInternalHolder hEnum(pMDImport);
+ hEnum.EnumAllInit(mdtMethodDef);
+
+ mdMethodDef md;
+ while (pMDImport->EnumNext(&hEnum, &md))
{
//
- // Compile the methods specified by the IBC profile data
- //
- CompileProfileData();
-
- BeginRegion(CORINFO_REGION_COLD);
-
-
- IMDInternalImport * pMDImport = m_pMDImport;
-
- HENUMInternalHolder hEnum(pMDImport);
- hEnum.EnumAllInit(mdtMethodDef);
-
- mdMethodDef md;
- while (pMDImport->EnumNext(&hEnum, &md))
- {
- if (m_pILMetaData != NULL)
- {
- // Copy IL for all methods. We treat errors during copying IL
- // over as fatal error. These errors are typically caused by
- // corrupted IL images.
- //
- m_pILMetaData->EmitMethodIL(md);
- }
+ // Compile the remaining methods that weren't compiled during the CompileHotRegion phase
+ //
+ TryCompileMethodDef(md, 0);
+ }
- //
- // Compile the remaining methods that weren't compiled during the CompileProfileData phase
- //
- TryCompileMethodDef(md, 0);
- }
+ // Compile any generic code which lands in this LoaderModule
+ // that resulted from the above compilations
+ CORINFO_METHOD_HANDLE handle = m_pPreloader->NextUncompiledMethod();
+ while (handle != NULL)
+ {
+ TryCompileInstantiatedMethod(handle, 0);
+ handle = m_pPreloader->NextUncompiledMethod();
+ }
+
+ EndRegion(CORINFO_REGION_COLD);
+}
- // Compile any generic code which lands in this LoaderModule
- // that resulted from the above compilations
- CORINFO_METHOD_HANDLE handle = m_pPreloader->NextUncompiledMethod();
- while (handle != NULL)
+// PlaceMethodIL
+// Copy the IL for all method into the AOT native image
+//
+void ZapImage::PlaceMethodIL()
+{
+ // Place the IL for all of the methods
+ //
+ IMDInternalImport * pMDImport = m_pMDImport;
+ HENUMInternalHolder hEnum(pMDImport);
+ hEnum.EnumAllInit(mdtMethodDef);
+
+ mdMethodDef md;
+ while (pMDImport->EnumNext(&hEnum, &md))
+ {
+ if (m_pILMetaData != NULL)
{
- TryCompileInstantiatedMethod(handle, 0);
- handle = m_pPreloader->NextUncompiledMethod();
+ // Copy IL for all methods. We treat errors during copying IL
+ // over as fatal error. These errors are typically caused by
+ // corrupted IL images.
+ //
+ m_pILMetaData->EmitMethodIL(md);
}
+ }
+}
- EndRegion(CORINFO_REGION_COLD);
+void ZapImage::Compile()
+{
+ //
+ // Compile all of the methods for our AOT native image
+ //
- // If we want ngen to fail when we create partial ngen images we can
- // throw an NGEN failure HRESULT here.
-#if 0
- if (m_zapper->m_failed)
- {
- ThrowHR(NGEN_E_TP_PARTIAL_IMAGE);
- }
+ bool doNothingNgen = false;
+#ifdef _DEBUG
+ static ConfigDWORD fDoNothingNGen;
+ doNothingNgen = !!fDoNothingNGen.val(CLRConfig::INTERNAL_ZapDoNothing);
#endif
+ ProfileDisableInlining();
+
+ if (!doNothingNgen)
+ {
+ CompileHotRegion();
+
+ CompileColdRegion();
}
+ PlaceMethodIL();
+
// Compute a preferred class layout order based on analyzing the graph
// of which classes contain calls to other classes.
ComputeClassLayoutOrder();
@@ -1918,6 +1818,8 @@ void ZapImage::Compile()
OutputEntrypointsTableForReadyToRun();
OutputDebugInfoForReadyToRun();
OutputTypesTableForReadyToRun(m_pMDImport);
+ OutputInliningTableForReadyToRun();
+ OutputProfileDataForReadyToRun();
}
else
#endif
@@ -2186,20 +2088,64 @@ ZapImage::CompileStatus ZapImage::TryCompileMethodWorker(CORINFO_METHOD_HANDLE h
}
#endif
+ // Do we have a profile entry for this method?
+ //
if (methodProfilingDataFlags != 0)
{
// Report the profiling data flags for layout of the EE datastructures
m_pPreloader->SetMethodProfilingFlags(handle, methodProfilingDataFlags);
- // Only proceed with compilation if the code is hot
+ // Hot methods can be marked to be excluded from the AOT native image.
+ // A Jitted method executes faster than a ReadyToRun compiled method.
+ //
+ if ((methodProfilingDataFlags & (1 << ExcludeHotMethodCode)) != 0)
+ {
+ // returning COMPILE_HOT_EXCLUDED excludes this method from the AOT native image
+ return COMPILE_HOT_EXCLUDED;
+ }
+
+ // Cold methods can be marked to be excluded from the AOT native image.
+ // We can reduced the size of the AOT native image by selectively
+ // excluding the code for some of the cold methods.
+ //
+ if ((methodProfilingDataFlags & (1 << ExcludeColdMethodCode)) != 0)
+ {
+ // returning COMPILE_COLD_EXCLUDED excludes this method from the AOT native image
+ return COMPILE_COLD_EXCLUDED;
+ }
+
+ // If the code was never executed based on the profile data
+ // then don't compile this method now. Wait until until later
+ // when we are compiling the methods in the cold section.
//
if ((methodProfilingDataFlags & (1 << ReadMethodCode)) == 0)
+ {
+ // returning NOT_COMPILED will defer until later the compilation of this method
return NOT_COMPILED;
+ }
}
- else
+ else // we are compiling methods for the cold region
{
+ // When Partial Ngen is specified we will omit the AOT native code for every
+ // method that was not executed based on the profile data.
+ //
if (m_zapper->m_pOpt->m_fPartialNGen)
- return COMPILE_EXCLUDED;
+ {
+ // returning COMPILE_COLD_EXCLUDED excludes this method from the AOT native image
+ return COMPILE_COLD_EXCLUDED;
+ }
+
+ // Retrieve any information that we have about a previous compilation attempt of this method
+ const ProfileDataHashEntry* pEntry = profileDataHashTable.LookupPtr(md);
+
+ if (pEntry != nullptr)
+ {
+ if ((pEntry->status == COMPILE_HOT_EXCLUDED) || (pEntry->status == COMPILE_COLD_EXCLUDED))
+ {
+ // returning COMPILE_HOT_EXCLUDED excludes this method from the AOT native image
+ return pEntry->status;
+ }
+ }
}
// Have we already compiled it?
@@ -2627,15 +2573,6 @@ HRESULT ZapImage::parseProfileData()
}
// CoreCLR should never be presented with V1 IBC data.
-#ifndef FEATURE_CORECLR
- if ((fileHeader->Version == CORBBTPROF_V1_VERSION) && CanConvertIbcData())
- {
- // Read and convert V1 data
- m_zapper->Info(W("Converting V1 IBC data to latest format.\n"));
- convertFromV1 = true;
- }
- else
-#endif
if (fileHeader->Version == CORBBTPROF_V3_VERSION)
{
CORBBTPROF_FILE_OPTIONAL_HEADER *optionalHeader =
@@ -3380,6 +3317,8 @@ HRESULT ZapImage::hashBBProfileData ()
READ(methodHeader,CORBBTPROF_METHOD_HEADER);
newEntry.md = methodHeader->method.token;
newEntry.size = methodHeader->size;
+ newEntry.flags = 0;
+ newEntry.status = NOT_COMPILED;
// Add the new entry to the table
profileDataHashTable.Add(newEntry);
@@ -3392,6 +3331,33 @@ HRESULT ZapImage::hashBBProfileData ()
return S_OK;
}
+void ZapImage::hashBBUpdateFlagsAndCompileResult(mdToken token, unsigned methodProfilingDataFlags, ZapImage::CompileStatus compileResult)
+{
+ // SHash only supports replacing an entry so we setup our newEntry and then perform a lookup
+ //
+ ProfileDataHashEntry newEntry;
+ newEntry.md = token;
+ newEntry.flags = methodProfilingDataFlags;
+ newEntry.status = compileResult;
+
+ const ProfileDataHashEntry* pEntry = profileDataHashTable.LookupPtr(token);
+ if (pEntry != nullptr)
+ {
+ assert(pEntry->md == newEntry.md);
+ assert(pEntry->flags == 0); // the flags should not be set at this point.
+
+ // Copy and keep the two fleids that were previously set
+ newEntry.size = pEntry->size;
+ newEntry.pos = pEntry->pos;
+ }
+ else // We have a method that doesn't have basic block counts
+ {
+ newEntry.size = 0;
+ newEntry.pos = 0;
+ }
+ profileDataHashTable.AddOrReplace(newEntry);
+}
+
void ZapImage::LoadProfileData()
{
HRESULT hr = E_FAIL;
@@ -3576,23 +3542,17 @@ void ZapImage::FileNotFoundError(LPCWSTR pszMessage)
level = CORZAP_LOGLEVEL_ERROR;
#endif
-#ifndef FEATURE_CORECLR
- m_zapper->Print(level, W("Warning: %s. If this assembly is found during runtime of an application, then the native image currently being generated will not be used.\n"), pszMessage);
-#else
m_zapper->Print(level, W("Warning: %s.\n"), pszMessage);
-#endif
fileNotFoundErrorsTable.Append(message);
}
void ZapImage::Error(mdToken token, HRESULT hr, LPCWSTR message)
{
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
// Missing dependencies are reported as fatal errors in code:CompilationDomain::BindAssemblySpec.
// Avoid printing redundant error message for them.
if (FAILED(g_hrFatalError))
ThrowHR(g_hrFatalError);
-#endif
CorZapLogLevel level = CORZAP_LOGLEVEL_ERROR;
diff --git a/src/zap/zapimage.h b/src/zap/zapimage.h
index 02985f5d12..f0bcbcb033 100644
--- a/src/zap/zapimage.h
+++ b/src/zap/zapimage.h
@@ -336,12 +336,33 @@ private:
COUNT_T m_cRawProfileData;
CorProfileData * m_pCorProfileData;
- // ProfileData hash table
+public:
+ enum CompileStatus {
+ // Failure status values are negative
+ LOOKUP_FAILED = -2,
+ COMPILE_FAILED = -1,
+
+ // Info status values are [0..9]
+ NOT_COMPILED = 0,
+ COMPILE_EXCLUDED = 1,
+ COMPILE_HOT_EXCLUDED = 2,
+ COMPILE_COLD_EXCLUDED = 3,
+
+ // Successful status values are 10 or greater
+ COMPILE_SUCCEED = 10,
+ ALREADY_COMPILED = 11
+ };
+
+private:
+ // A hash table entry that contains the profile infomation and the CompileStatus for a given method
struct ProfileDataHashEntry
{
- mdMethodDef md; // A copy of the method.token of the profile data
- DWORD size; // A copy of the size of the profile data
- ULONG pos;
+ mdMethodDef md; // The method.token, also used as the key for the ProfileDataHashTable
+ DWORD size; // The size of the CORBBTPROF_BLOCK_DATA region, set by ZapImage::hashBBProfileData()
+ ULONG pos; // the offset to the CORBBTPROF_BLOCK_DATA region, set by ZapImage::hashBBProfileData()
+
+ unsigned flags; // The methodProfilingDataFlags, set by ZapImage::CompileHotRegion()
+ CompileStatus status; // The compileResult, set by ZapImage::CompileHotRegion()
};
class ProfileDataHashTraits : public NoRemoveSHashTraits< DefaultSHashTraits<ProfileDataHashEntry> >
@@ -365,8 +386,24 @@ private:
return (count_t)k;
}
- static const element_t Null() { LIMITED_METHOD_CONTRACT; ProfileDataHashEntry e; e.pos = 0; e.size = 0; e.md = 0; return e; } // Assuming method profile data cannot start from position 0.
- static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e.pos == 0; }
+ static const element_t Null()
+ {
+ LIMITED_METHOD_CONTRACT;
+ ProfileDataHashEntry e;
+ e.md = 0;
+ e.size = 0;
+ e.pos = 0;
+ e.flags = 0;
+ e.status = NOT_COMPILED;
+ return e;
+ }
+
+ static bool IsNull(const element_t &e)
+ {
+ LIMITED_METHOD_CONTRACT;
+ // returns true if both md and pos are zero
+ return (e.md == 0) && (e.pos == 0);
+ }
};
typedef SHash<ProfileDataHashTraits> ProfileDataHashTable;
@@ -557,6 +594,8 @@ private:
void OutputEntrypointsTableForReadyToRun();
void OutputDebugInfoForReadyToRun();
void OutputTypesTableForReadyToRun(IMDInternalImport * pMDImport);
+ void OutputInliningTableForReadyToRun();
+ void OutputProfileDataForReadyToRun();
void CopyDebugDirEntry();
void CopyWin32VersionResource();
@@ -651,11 +690,6 @@ public:
return m_CompiledMethods.Lookup(handle);
}
-
- enum CompileStatus { LOOKUP_FAILED = -2, COMPILE_FAILED = -1, // Failure
- NOT_COMPILED = 0, COMPILE_EXCLUDED = 1, // Info
- COMPILE_SUCCEED = 10, ALREADY_COMPILED = 11}; // Success
-
static void __stdcall TryCompileMethodStub(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, CORJIT_FLAGS jitFlags);
BOOL IsVTableGapMethod(mdMethodDef md);
@@ -811,6 +845,7 @@ public:
void RehydrateBlobStream();
HRESULT RehydrateProfileData();
HRESULT hashBBProfileData ();
+ void hashBBUpdateFlagsAndCompileResult(mdToken token, unsigned methodProfilingDataFlags, CompileStatus compileResult);
void LoadProfileData();
CorProfileData * NewProfileData();
@@ -818,7 +853,11 @@ public:
bool CanConvertIbcData();
CompileStatus CompileProfileDataWorker(mdToken token, unsigned methodProfilingDataFlags);
- void CompileProfileData();
+
+ void ProfileDisableInlining();
+ void CompileHotRegion();
+ void CompileColdRegion();
+ void PlaceMethodIL();
};
class BinaryWriter
diff --git a/src/zap/zapimport.cpp b/src/zap/zapimport.cpp
index 3e4e45d0c7..f256bee350 100644
--- a/src/zap/zapimport.cpp
+++ b/src/zap/zapimport.cpp
@@ -2098,47 +2098,33 @@ DWORD ZapIndirectHelperThunk::SaveWorker(ZapWriter * pZapWriter)
#elif defined(_TARGET_ARM_)
if (IsDelayLoadHelper())
{
- // Indirection
- if (IsVSD())
- {
- // push r4
- *(WORD *)(p + 0) = 0xB410;
- p += 2;
- }
- else
- {
- // push r12
- *(WORD *)(p + 0) = 0xF84D;
- *(WORD *)(p + 2) = 0xCD04;
- p += 4;
- }
+ // r4 contains indirection cell
+ // push r4
+ *(WORD *)(p + 0) = 0xB410;
+ p += 2;
- // mov r12, index
- *(WORD *)(p + 0) = 0xF04F;
+ // mov r4, index
_ASSERTE(GetSectionIndex() <= 0x7F);
- *(WORD *)(p + 2) = 0x0C00 | (BYTE)GetSectionIndex();
- p += 4;
+ *(WORD *)(p + 0) = 0x2400 | (BYTE)GetSectionIndex();
+ p += 2;
- // push r12
- *(WORD *)(p + 0) = 0xF84D;
- *(WORD *)(p + 2) = 0xCD04;
- p += 4;
+ // push r4
+ *(WORD *)(p + 0) = 0xB410;
+ p += 2;
- // mov r12, [module]
- MovRegImm(p, 12);
+ // mov r4, [module]
+ MovRegImm(p, 4);
if (pImage != NULL)
pImage->WriteReloc(buffer, (int) (p - buffer), pImage->GetImportTable()->GetHelperImport(READYTORUN_HELPER_Module), 0, IMAGE_REL_BASED_THUMB_MOV32);
p += 8;
- // ldr r12, [r12]
- *(WORD *)(p + 0) = 0xF8DC;
- *(WORD *)(p + 2) = 0xC000;
- p += 4;
+ // ldr r4, [r4]
+ *(WORD *)p = 0x6824;
+ p += 2;
- // push r12
- *(WORD *)(p + 0) = 0xF84D;
- *(WORD *)(p + 2) = 0xCD04;
- p += 4;
+ // push r4
+ *(WORD *)(p + 0) = 0xB410;
+ p += 2;
}
else
if (IsLazyHelper())
@@ -2154,19 +2140,18 @@ DWORD ZapIndirectHelperThunk::SaveWorker(ZapWriter * pZapWriter)
p += 2;
}
- // mov r12, [helper]
- MovRegImm(p, 12);
+ // mov r4, [helper]
+ MovRegImm(p, 4);
if (pImage != NULL)
pImage->WriteReloc(buffer, (int) (p - buffer), pImage->GetImportTable()->GetHelperImport(GetReadyToRunHelper()), 0, IMAGE_REL_BASED_THUMB_MOV32);
p += 8;
- // ldr r12, [r12]
- *(WORD *)(p + 0) = 0xF8DC;
- *(WORD *)(p + 2) = 0xC000;
- p += 4;
+ // ldr r4, [r4]
+ *(WORD *)p = 0x6824;
+ p += 2;
- // bx r12
- *(WORD *)p = 0x4760;
+ // bx r4
+ *(WORD *)p = 0x4720;
p += 2;
#elif defined(_TARGET_ARM64_)
if (IsDelayLoadHelper())
diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp
index d2362d4b90..af0c41c4e4 100644
--- a/src/zap/zapinfo.cpp
+++ b/src/zap/zapinfo.cpp
@@ -466,10 +466,6 @@ void ZapInfo::CompileMethod()
return;
}
-#if !defined(FEATURE_CORECLR)
- // Ask the JIT to generate desktop-quirk-compatible code.
- m_jitFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_DESKTOP_QUIRKS);
-#endif
if (m_pImage->m_stats)
{
@@ -1013,12 +1009,19 @@ HRESULT ZapInfo::getBBProfileData (
}
// The md must match.
- _ASSERTE(foundEntry->md == md);
+ _ASSERTE(foundEntry->md == md);
+
+ if (foundEntry->pos == 0)
+ {
+ // We might not have profile data and instead only have CompileStatus and flags
+ assert(foundEntry->size == 0);
+ return E_FAIL;
+ }
//
+ //
// We found the md. Let's retrieve the profile data.
//
- _ASSERTE(foundEntry->pos > 0); // The target position cannot be 0.
_ASSERTE(foundEntry->size >= sizeof(CORBBTPROF_METHOD_HEADER)); // The size must at least this
ProfileReader profileReader(DataSection_MethodBlockCounts->pData, DataSection_MethodBlockCounts->dataSize);
@@ -1239,9 +1242,6 @@ int ZapInfo::canHandleException(struct _EXCEPTION_POINTERS *pExceptionPointers)
int ZapInfo::doAssert(const char* szFile, int iLine, const char* szExpr)
{
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- ThrowHR(COR_E_INVALIDPROGRAM);
-#else
#if defined(_DEBUG)
return(_DbgBreakCheck(szFile, iLine, szExpr));
@@ -1249,7 +1249,6 @@ int ZapInfo::doAssert(const char* szFile, int iLine, const char* szExpr)
return(true); // break into debugger
#endif
-#endif
}
void ZapInfo::reportFatalError(CorJitResult result)
{
@@ -2574,9 +2573,6 @@ void ZapInfo::recordRelocation(void *location, void *target,
break;
case IMAGE_REL_BASED_PTR:
-#if defined(_TARGET_AMD64_) && !defined(FEATURE_CORECLR)
- _ASSERTE(!"Why we are not using RIP relative address?");
-#endif
*(UNALIGNED TADDR *)location = (TADDR)targetOffset;
break;
@@ -3040,6 +3036,7 @@ void ZapInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken,
case CORINFO_FIELD_INTRINSIC_ZERO:
case CORINFO_FIELD_INTRINSIC_EMPTY_STRING:
+ case CORINFO_FIELD_INTRINSIC_ISLITTLEENDIAN:
break;
default:
@@ -3277,15 +3274,6 @@ size_t ZapInfo::getClassModuleIdForStatics(CORINFO_CLASS_HANDLE cls, CORINFO_MOD
// if the fixups were exclusively based on the moduleforstatics lookup
cls = NULL;
-#ifndef FEATURE_CORECLR
-
- // Is this mscorlib.dll (which has ModuleDomainId of 0 (tagged == 1), then you don't need a fixup
- if (moduleId == (size_t) 1)
- {
- *ppIndirection = NULL;
- return (size_t) 1;
- }
-#endif
if (module == m_pImage->m_hModule)
{
@@ -3519,14 +3507,14 @@ bool ZapInfo::getReadyToRunHelper(CORINFO_RESOLVED_TOKEN * pResolvedToken,
void ZapInfo::getReadyToRunDelegateCtorHelper(
CORINFO_RESOLVED_TOKEN * pTargetMethod,
CORINFO_CLASS_HANDLE delegateType,
- CORINFO_CONST_LOOKUP * pLookup
+ CORINFO_LOOKUP * pLookup
)
{
#ifdef FEATURE_READYTORUN_COMPILER
_ASSERTE(IsReadyToRunCompilation());
-
- pLookup->accessType = IAT_PVALUE;
- pLookup->addr = m_pImage->GetImportTable()->GetDynamicHelperCell(
+ pLookup->lookupKind.needsRuntimeLookup = false;
+ pLookup->constLookup.accessType = IAT_PVALUE;
+ pLookup->constLookup.addr = m_pImage->GetImportTable()->GetDynamicHelperCell(
(CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DELEGATE_CTOR), pTargetMethod->hMethod, pTargetMethod, delegateType);
#endif
}
@@ -3642,8 +3630,6 @@ void ZapInfo::reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd,
CorInfoInline inlineResult,
const char * reason)
{
-
-#ifndef FEATURE_CORECLR
if (!dontInline(inlineResult) && inlineeHnd != NULL)
{
// We deliberately report m_currentMethodHandle (not inlinerHnd) as inliner, because
@@ -3651,8 +3637,6 @@ void ZapInfo::reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd,
// in inlining into m_currentMethodHandle, and we have no interest to track those intermediate links now.
m_pImage->m_pPreloader->ReportInlining(m_currentMethodHandle, inlineeHnd);
}
-#endif //FEATURE_CORECLR
-
return m_pEEJitInfo->reportInliningDecision(inlinerHnd, inlineeHnd, inlineResult, reason);
}
@@ -3750,6 +3734,15 @@ void ZapInfo::getMethodVTableOffset(CORINFO_METHOD_HANDLE method,
m_pEEJitInfo->getMethodVTableOffset(method, pOffsetOfIndirection, pOffsetAfterIndirection);
}
+CORINFO_METHOD_HANDLE ZapInfo::resolveVirtualMethod(
+ CORINFO_METHOD_HANDLE virtualMethod,
+ CORINFO_CLASS_HANDLE implementingClass,
+ CORINFO_CONTEXT_HANDLE ownerType
+ )
+{
+ return m_pEEJitInfo->resolveVirtualMethod(virtualMethod, implementingClass, ownerType);
+}
+
CorInfoIntrinsics ZapInfo::getIntrinsicID(CORINFO_METHOD_HANDLE method,
bool * pMustExpand)
{
diff --git a/src/zap/zapinfo.h b/src/zap/zapinfo.h
index 97ecfb6715..6e83657170 100644
--- a/src/zap/zapinfo.h
+++ b/src/zap/zapinfo.h
@@ -558,7 +558,7 @@ public:
void getReadyToRunDelegateCtorHelper(
CORINFO_RESOLVED_TOKEN * pTargetMethod,
CORINFO_CLASS_HANDLE delegateType,
- CORINFO_CONST_LOOKUP * pLookup
+ CORINFO_LOOKUP * pLookup
);
CorInfoInitClassResult initClass(
@@ -665,6 +665,12 @@ public:
unsigned * pOffsetOfIndirection,
unsigned * pOffsetAfterIndirection);
+ CORINFO_METHOD_HANDLE resolveVirtualMethod(
+ CORINFO_METHOD_HANDLE virtualMethod,
+ CORINFO_CLASS_HANDLE implementingClass,
+ CORINFO_CONTEXT_HANDLE ownerType
+ );
+
CorInfoIntrinsics getIntrinsicID(CORINFO_METHOD_HANDLE method,
bool * pMustExpand = NULL);
bool isInSIMDModule(CORINFO_CLASS_HANDLE classHnd);
diff --git a/src/zap/zapper.cpp b/src/zap/zapper.cpp
index 2c7023a400..4d1330ee1f 100644
--- a/src/zap/zapper.cpp
+++ b/src/zap/zapper.cpp
@@ -5,27 +5,15 @@
#include "common.h"
-#ifdef FEATURE_FUSION
-#include "binderngen.h"
-#endif
#ifndef FEATURE_MERGE_JIT_AND_ENGINE
#include "metahost.h"
#endif
-#if defined(FEATURE_APPX) && !defined(FEATURE_CORECLR)
-#include "AppXUtil.h"
-#include "AssemblyUsageLogManager.h"
-#endif
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
#include "coregen.h"
-#endif
#include "clr/fs/dir.h"
-#ifdef FEATURE_FUSION
-#include "ngenparser.inl"
-#endif
/* --------------------------------------------------------------------------- *
* Error Macros
@@ -44,9 +32,6 @@ BOOL g_fForceDebug, g_fForceProfile, g_fForceInstrument;
#endif
-#ifdef FEATURE_FUSION
-extern "C" HRESULT STDMETHODCALLTYPE InitializeFusion();
-#endif
#pragma warning(push)
#pragma warning(disable: 4995)
@@ -55,21 +40,14 @@ extern "C" HRESULT STDMETHODCALLTYPE InitializeFusion();
extern const WCHAR g_pwBaseLibrary[];
extern bool g_fAllowNativeImages;
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
bool g_fNGenMissingDependenciesOk;
-#endif
bool g_fNGenWinMDResilient;
-#if !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
-extern int g_ningenState;
-#endif
#ifdef FEATURE_READYTORUN_COMPILER
bool g_fReadyToRunCompilation;
#endif
-#ifdef FEATURE_CORECLR
static bool s_fNGenNoMetaData;
-#endif
// Event logging helper
void Zapper::ReportEventNGEN(WORD wType, DWORD dwEventID, LPCWSTR format, ...)
@@ -97,38 +75,6 @@ void Zapper::ReportEventNGEN(WORD wType, DWORD dwEventID, LPCWSTR format, ...)
Warning(W("%s\n"), s.GetUnicode());
}
-#ifdef FEATURE_FUSION
-static HRESULT GetAssemblyName(
- ICorCompileInfo * pCCI,
- CORINFO_ASSEMBLY_HANDLE hAssembly,
- SString & str,
- DWORD dwFlags)
-{
- DWORD dwSize = 0;
- LPWSTR buffer = NULL;
- COUNT_T allocation = str.GetUnicodeAllocation();
- if (allocation > 0)
- {
- // pass in the buffer if we got one
- dwSize = allocation + 1;
- buffer = str.OpenUnicodeBuffer(allocation);
- }
- HRESULT hr = pCCI->GetAssemblyName(hAssembly, dwFlags, buffer, &dwSize);
- if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
- {
- if (buffer != NULL)
- str.CloseBuffer(0);
- buffer = str.OpenUnicodeBuffer(dwSize-1);
- hr = pCCI->GetAssemblyName(hAssembly, dwFlags, buffer, &dwSize);
- }
- if (buffer != NULL)
- {
- str.CloseBuffer((SUCCEEDED(hr) && dwSize >= 1) ? (dwSize-1) : 0);
- }
-
- return hr;
-}
-#endif // FEATURE_FUSION
/* --------------------------------------------------------------------------- *
* Private fusion entry points
@@ -140,7 +86,6 @@ static HRESULT GetAssemblyName(
// For side by side issues, it's best to use the exported API calls to generate a
// Zapper Object instead of creating one on your own.
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembliesPaths, LPCWSTR pwzTrustedPlatformAssemblies, LPCWSTR pwzPlatformResourceRoots, LPCWSTR pwzAppPaths, LPCWSTR pwzOutputFilename=NULL, LPCWSTR pwzPlatformWinmdPaths=NULL, ICorSvcLogger *pLogger = NULL, LPCWSTR pwszCLRJITPath = nullptr)
{
@@ -160,7 +105,7 @@ STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembl
ngo.fDebug = false;
ngo.fDebugOpt = false;
ngo.fProf = false;
- ngo.fSilent = false;
+ ngo.fSilent = (dwFlags & NGENWORKER_FLAGS_SILENT) != 0;
ngo.lpszExecutableFileName = pwzFilename;
// V2 (Whidbey)
@@ -185,9 +130,7 @@ STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembl
ngo.fNgenLastRetry = false;
-#ifdef FEATURE_CORECLR
s_fNGenNoMetaData = (dwFlags & NGENWORKER_FLAGS_NO_METADATA) != 0;
-#endif
zap = Zapper::NewZapper(&ngo);
@@ -209,10 +152,10 @@ STDAPI NGenWorker(LPCWSTR pwzFilename, DWORD dwFlags, LPCWSTR pwzPlatformAssembl
if (pwzPlatformWinmdPaths != nullptr)
zap->SetPlatformWinmdPaths(pwzPlatformWinmdPaths);
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
if (pwszCLRJITPath != nullptr)
zap->SetCLRJITPath(pwszCLRJITPath);
-#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE)
zap->SetForceFullTrust(!!(dwFlags & NGENWORKER_FLAGS_FULLTRUSTDOMAIN));
@@ -255,9 +198,9 @@ STDAPI CreatePDBWorker(LPCWSTR pwzAssemblyPath, LPCWSTR pwzPlatformAssembliesPat
zap = Zapper::NewZapper(&ngo);
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
zap->SetDontLoadJit();
-#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE)
if (pwzPlatformAssembliesPaths != nullptr)
zap->SetPlatformAssembliesPaths(pwzPlatformAssembliesPaths);
@@ -277,10 +220,10 @@ STDAPI CreatePDBWorker(LPCWSTR pwzAssemblyPath, LPCWSTR pwzPlatformAssembliesPat
if (pwzPlatformWinmdPaths != nullptr)
zap->SetPlatformWinmdPaths(pwzPlatformWinmdPaths);
-#if defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#if !defined(NO_NGENPDB)
if (pwzDiasymreaderPath != nullptr)
zap->SetDiasymreaderPath(pwzDiasymreaderPath);
-#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#endif // !defined(NO_NGENPDB)
// Avoid unnecessary security failures, since permissions are irrelevant when
// generating NGEN PDBs
@@ -310,100 +253,6 @@ STDAPI CreatePDBWorker(LPCWSTR pwzAssemblyPath, LPCWSTR pwzPlatformAssembliesPat
return hr;
}
-#else // FEATURE_CORECLR || CROSSGEN_COMPILE
-
-STDAPI LegacyNGenCreateZapper(HANDLE* hZapper, NGenOptions* opt)
-{
- if (hZapper == NULL)
- return E_POINTER;
-
- HRESULT hr = S_OK;
- Zapper* zap = NULL;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
-
- EX_TRY
- {
- zap = Zapper::NewZapper(opt);
- }
- EX_CATCH_HRESULT(hr);
-
- END_ENTRYPOINT_NOTHROW;
-
- IfFailRet(hr);
-
- if (zap == NULL)
- return E_OUTOFMEMORY;
-
- zap->SetLegacyMode();
-
- *hZapper = (HANDLE)zap;
-
- return S_OK;
-}// NGenCreateZapper
-
-STDAPI LegacyNGenFreeZapper(HANDLE hZapper)
-{
- if (hZapper == NULL || hZapper == INVALID_HANDLE_VALUE)
- return E_HANDLE;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- Zapper *zapper = (Zapper*)hZapper;
- delete zapper;
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
-}// NGenFreeZapper
-
-#ifdef FEATURE_FUSION
-STDAPI LegacyNGenTryEnumerateFusionCache(HANDLE hZapper, LPCWSTR assemblyName, bool fPrint, bool fDelete)
-{
-
- HRESULT hr = S_OK;
- if (hZapper == NULL || hZapper == INVALID_HANDLE_VALUE)
- return E_HANDLE;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- Zapper *zapper = (Zapper*)hZapper;
- hr = zapper->TryEnumerateFusionCache(assemblyName, fPrint, fDelete);
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-
-}// NGenTryEnumerateFusionCache
-#endif //FEATURE_FUSION
-
-STDAPI_(BOOL) LegacyNGenCompile(HANDLE hZapper, LPCWSTR path)
-{
- CONTRACTL{
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- if (hZapper == NULL || hZapper == INVALID_HANDLE_VALUE)
- return FALSE;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_VOIDRET;
-
- Zapper *zapper = (Zapper*)hZapper;
-
- EX_TRY
- {
- hr = zapper->Compile(path);
- }
- EX_CATCH_HRESULT(hr);
-
- END_ENTRYPOINT_VOIDRET;
-
- return (hr == S_OK) ? TRUE : FALSE;
-}// NGenCompile
-
-#endif // FEATURE_CORECLR || CROSSGEN_COMPILE
/* --------------------------------------------------------------------------- *
* Options class
@@ -427,9 +276,7 @@ ZapperOptions::ZapperOptions() :
m_fNGenLastRetry(false),
m_compilerFlags(),
m_legacyMode(false)
-#ifdef FEATURE_CORECLR
,m_fNoMetaData(s_fNGenNoMetaData)
-#endif
{
m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_RELOC);
m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PREJIT);
@@ -539,47 +386,6 @@ Zapper::Zapper(NGenOptions *pOptions, bool fromDllHost)
zo->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_PROF_ENTERLEAVE);
}
-#ifdef FEATURE_FUSION
- if (pOptions->lpszRepositoryDir != NULL && pOptions->lpszRepositoryDir[0] != '\0')
- {
- size_t buflen = wcslen(pOptions->lpszRepositoryDir) + 1;
- LPWSTR lpszDir = new WCHAR[buflen];
- wcscpy_s(lpszDir, buflen, pOptions->lpszRepositoryDir);
- zo->m_repositoryDir = lpszDir;
- }
- else
- {
- zo->m_repositoryDir = CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_RepositoryDir);
- }
-
- if (pOptions->repositoryFlags != RepositoryDefault)
- {
- zo->m_repositoryFlags = pOptions->repositoryFlags;
- }
- else
- {
- zo->m_repositoryFlags = (RepositoryFlags)REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_RepositoryFlags, RepositoryDefault);
- }
-
- // The default location of the repository is "repository" folder under framework version directory
- if (zo->m_repositoryDir == NULL)
- {
- DWORD lgth = _MAX_PATH + 1;
- WCHAR wszRepositoryDir[_MAX_PATH + 1];
- IfFailThrow(GetInternalSystemDirectory(wszRepositoryDir, &lgth));
-
- wcscat_s(wszRepositoryDir, COUNTOF(wszRepositoryDir), W("repository"));
-
- size_t buflen = wcslen(wszRepositoryDir) + 1;
- LPWSTR lpszDir = new WCHAR[buflen];
- wcscpy_s(lpszDir, buflen, wszRepositoryDir);
- zo->m_repositoryDir = lpszDir;
-
- // Move the images by default
- if (zo->m_repositoryFlags == RepositoryDefault)
- zo->m_repositoryFlags = MoveFromRepository;
- }
-#endif //FEATURE_FUSION
if (pOptions->fInstrument)
zo->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_BBINSTR);
@@ -686,14 +492,10 @@ void Zapper::Init(ZapperOptions *pOptions, bool fFreeZapperOptions)
hr = m_pMetaDataDispenser->SetOption(MetaDataCheckDuplicatesFor, &opt);
_ASSERTE(SUCCEEDED(hr));
-#ifdef FEATURE_FUSION
- hr = InitializeFusion();
- _ASSERTE(SUCCEEDED(hr));
-#endif
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
m_fDontLoadJit = false;
-#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE)
m_fForceFullTrust = false;
}
@@ -719,13 +521,12 @@ void Zapper::LoadAndInitializeJITForNgen(LPCWSTR pwzJitName, OUT HINSTANCE* phJi
HRESULT hr = E_FAIL;
-#if defined(FEATURE_CORECLR) || defined(FEATURE_MERGE_JIT_AND_ENGINE)
// Note: FEATURE_MERGE_JIT_AND_ENGINE is defined for the Desktop crossgen compilation as well.
//
PathString CoreClrFolder;
extern HINSTANCE g_hThisInst;
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
if (m_fDontLoadJit)
{
return;
@@ -738,7 +539,7 @@ void Zapper::LoadAndInitializeJITForNgen(LPCWSTR pwzJitName, OUT HINSTANCE* phJi
hr = S_OK;
}
else
-#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE)
if (WszGetModuleFileName(g_hThisInst, CoreClrFolder))
{
hr = CopySystemDirectory(CoreClrFolder, CoreClrFolder);
@@ -761,9 +562,6 @@ void Zapper::LoadAndInitializeJITForNgen(LPCWSTR pwzJitName, OUT HINSTANCE* phJi
hr = S_OK;
}
}
-#else
- hr = g_pCLRRuntime->LoadLibrary(pwzJitName, phJit);
-#endif
if (FAILED(hr))
{
@@ -771,7 +569,7 @@ void Zapper::LoadAndInitializeJITForNgen(LPCWSTR pwzJitName, OUT HINSTANCE* phJi
ThrowLastError();
}
-#if (defined(FEATURE_CORECLR) || !defined(SELF_NO_HOST)) && !defined(CROSSGEN_COMPILE)
+#if !defined(CROSSGEN_COMPILE)
typedef void (__stdcall* pSxsJitStartup) (CoreClrCallbacks const & cccallbacks);
pSxsJitStartup sxsJitStartupFn = (pSxsJitStartup) GetProcAddress(*phJit, "sxsJitStartup");
if (sxsJitStartupFn == NULL)
@@ -898,39 +696,11 @@ void Zapper::InitEE(BOOL fForceDebug, BOOL fForceProfile, BOOL fForceInstrument)
CorCompileRuntimeDlls ngenDllId;
-#if !defined(FEATURE_CORECLR)
- ngenDllId = NGEN_COMPILER_INFO;
-#else // FEATURE_CORECLR
ngenDllId = CROSSGEN_COMPILER_INFO;
-#endif
LPCWSTR pwzJitName = CorCompileGetRuntimeDllName(ngenDllId);
LoadAndInitializeJITForNgen(pwzJitName, &m_hJitLib, &m_pJitCompiler);
-#if defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- // For reasons related to servicing, and RyuJIT rollout on .NET 4.6 and beyond, we only use RyuJIT when the registry
- // value UseRyuJIT (type DWORD), under key HKLM\SOFTWARE\Microsoft\.NETFramework, is set to 1. Otherwise, we fall back
- // to JIT64.
- //
- // See the document "RyuJIT Compatibility Fallback Specification.docx" for details.
- //
- // Also see the code and comments in EEJitManager::LoadJIT().
-
- if (!UseRyuJit()) // Do we need to fall back to JIT64 for NGEN?
- {
- LPCWSTR pwzJitName = MAKEDLLNAME_W(L"compatjit");
-
- // Note: if the compatjit fails to load, we ignore it, and continue to use the main JIT for
- // everything. You can imagine a policy where if the user requests the compatjit, and we fail
- // to load it, that we fail noisily. We don't do that currently.
- ICorJitCompiler* fallbackICorJitCompiler;
- LoadAndInitializeJITForNgen(pwzJitName, &m_hJitLegacy, &fallbackICorJitCompiler);
-
- // Tell the main JIT to fall back to the "fallback" JIT compiler, in case some
- // obfuscator tries to directly call the main JIT's getJit() function.
- m_pJitCompiler->setRealJit(fallbackICorJitCompiler);
- }
-#endif // defined(_TARGET_AMD64_) && !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
#endif // FEATURE_MERGE_JIT_AND_ENGINE
#ifdef ALLOW_SXS_JIT_NGEN
@@ -1057,277 +827,6 @@ void Zapper::CleanupAssembly()
}
}
-#ifdef FEATURE_FUSION
-HRESULT Zapper::TryEnumerateFusionCache(LPCWSTR name, bool fPrint, bool fDelete)
-{
- HRESULT hr = S_OK;
-
- EX_TRY
- {
- if (EnumerateFusionCache(name, fPrint, fDelete) == 0)
- hr = S_FALSE;
- }
- EX_CATCH_HRESULT(hr);
-
- return hr;
-}
-
-#define MAX_ZAP_STRING_SIZE 4
-
-int Zapper::EnumerateFusionCache(
- LPCWSTR name,
- bool fPrint, bool fDelete,
- CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
-{
- _ASSERTE(pNativeImageSig == NULL || (*pNativeImageSig) != INVALID_NGEN_SIGNATURE);
-
- int count = 0;
-
- NonVMComHolder<IAssemblyName> pName;
-
- //
- // Decide whether the name is a file or assembly name
- //
-
- DWORD attributes = -1;
-
- if (name != NULL)
- attributes = WszGetFileAttributes(name);
-
- if (attributes == -1)
- {
- IfFailThrow(CreateAssemblyNameObject(&pName, name,
- name == NULL ? 0 :
- CANOF_PARSE_DISPLAY_NAME, NULL));
- }
- else if (attributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- ClrDirectoryEnumerator de(name);
-
- while (de.Next())
- {
- StackSString fullName;
- fullName.Set(name, W("\\"), de.GetFileName());
-
- if (de.GetFileAttributes() & FILE_ATTRIBUTE_DIRECTORY)
- {
- count += EnumerateFusionCache(fullName, fPrint, fDelete);
- }
- else
- if (IsAssembly(fullName))
- {
- if (TryEnumerateFusionCache(fullName, fPrint, fDelete) == S_OK)
- count++;
- }
- }
- }
- else
- {
- NonVMComHolder<IMetaDataAssemblyImport> pAssemblyImport;
- IfFailThrow(m_pMetaDataDispenser->OpenScope(name, ofRead,
- IID_IMetaDataAssemblyImport,
- (IUnknown**)&pAssemblyImport));
-
- pName = GetAssemblyFusionName(pAssemblyImport);
- }
-
- if (pName != NULL)
- {
- pName->SetProperty(ASM_NAME_CUSTOM, NULL, 0);
-
- NonVMComHolder<IAssemblyEnum> pEnum;
- HRESULT hr = CreateAssemblyEnum(&pEnum, NULL, pName, ASM_CACHE_ZAP, 0);
- IfFailThrow(hr);
-
- pName.Clear();
-
- if (hr == S_OK)
- {
- //
- // Scope the iteration by the zap set
- //
-
- LPCWSTR zapPrefix = m_pOpt->m_zapSet;
- size_t zapPrefixSize = (zapPrefix != NULL) ? wcslen(zapPrefix) : 0;
-
- for (;;)
- {
- NonVMComHolder<IApplicationContext> pContext;
- NonVMComHolder<IAssemblyName> pEntryName;
-
- if (pEnum->GetNextAssembly(&pContext, &pEntryName, 0) != S_OK)
- break;
-
- //
- // Only consider assemblies which have the proper zap string
- // prefix.
- //
- if (zapPrefix != NULL)
- {
- WCHAR zapString[MAX_ZAP_STRING_SIZE];
- DWORD zapStringSize = sizeof(zapString);
-
- hr = pEntryName->GetProperty(ASM_NAME_CUSTOM, (void*) zapString, &zapStringSize);
- if (hr != S_OK
- || wcslen(zapString) < zapPrefixSize
- || wcsncmp(zapString, zapPrefix, zapPrefixSize) != 0)
- {
- continue;
- }
- }
-
- count++;
-
- if (pNativeImageSig)
- {
- // If we are looking for a specific native image,
- // check that the signatures match.
-
- CORCOMPILE_NGEN_SIGNATURE sign;
- DWORD cbSign = sizeof(sign);
-
- IfFailThrow(pEntryName->GetProperty(ASM_NAME_MVID, &sign, &cbSign));
- _ASSERTE(cbSign == sizeof(sign));
-
- if (cbSign != sizeof(sign) || *pNativeImageSig != sign)
- continue;
- }
-
- if (fPrint)
- {
- PrintFusionCacheEntry(LogLevel_Success, pEntryName);
- }
-
- if (fDelete)
- {
- DeleteFusionCacheEntry(pEntryName);
- }
- }
- }
-
- }
-
- return count;
-}
-
-void Zapper::PrintFusionCacheEntry(CorSvcLogLevel logLevel, IAssemblyName *pName)
-{
- StackSString ss;
- FusionBind::GetAssemblyNameDisplayName(pName, ss,
- ASM_DISPLAYF_VERSION | ASM_DISPLAYF_CULTURE | ASM_DISPLAYF_PUBLIC_KEY_TOKEN);
-
- GetSvcLogger()->Printf(logLevel, W("%s"), ss.GetUnicode());
-
- // Get the custom string
- WCHAR zapString[MAX_ZAP_STRING_SIZE];
- DWORD zapStringSize = sizeof(zapString);
-
- HRESULT hr = pName->GetProperty(ASM_NAME_CUSTOM, (void*) zapString, &zapStringSize);
- IfFailThrow(hr);
- IfFailThrow((zapStringSize != 0) ? S_OK : E_FAIL);
-
- // Get the config mask
-
- DWORD mask = 0;
- DWORD maskSize = sizeof(mask);
-
- hr = pName->GetProperty(ASM_NAME_CONFIG_MASK, (void*) &mask, &maskSize);
- IfFailThrow(hr);
-
- // Pretty-print the custom string and the config mask
-
- if (hr == S_OK)
- {
- DWORD maskStringLength;
- IfFailThrow(GetNativeImageDescription(zapString, mask, NULL, &maskStringLength));
-
- CQuickWSTR buffer;
- buffer.ReSizeThrows(maskStringLength * sizeof(WCHAR));
- IfFailThrow(GetNativeImageDescription(zapString, mask, buffer.Ptr(), &maskStringLength));
-
- GetSvcLogger()->Printf(logLevel, W("%s"), buffer.Ptr());
- }
-
- GetSvcLogger()->Printf(logLevel, W("\n"));
-
- StackSString s;
- PrintAssemblyVersionInfo(pName, s);
-
- GetSvcLogger()->Log(s.GetUnicode(), LogLevel_Info);
-}
-
-void Zapper::DeleteFusionCacheEntry(IAssemblyName *pName)
-{
- IfFailThrow(UninstallNativeAssembly(pName, GetSvcLogger()->GetSvcLogger()));
-}
-
-void Zapper::DeleteFusionCacheEntry(LPCWSTR assemblyName, CORCOMPILE_NGEN_SIGNATURE *pNativeImageSig)
-{
- _ASSERTE(assemblyName != NULL && pNativeImageSig != NULL);
- _ASSERTE(*pNativeImageSig != INVALID_NGEN_SIGNATURE);
- // assemblyName must be a display name, not a file name.
- _ASSERTE(WszGetFileAttributes(assemblyName) == INVALID_FILE_ATTRIBUTES);
-
- NonVMComHolder<IAssemblyName> pEntryName;
- IfFailThrow(CreateAssemblyNameObject(&pEntryName, assemblyName, CANOF_PARSE_DISPLAY_NAME, NULL));
-
- // Native Binder requires ASM_NAME_CUSTOM (zapset) not to be NULL while deleting a native image.
- LPCWSTR zapSet = m_pOpt->m_zapSet != NULL ? m_pOpt->m_zapSet : W("");
- pEntryName->SetProperty(ASM_NAME_CUSTOM, zapSet, DWORD(sizeof(WCHAR) * (wcslen(zapSet) + 1)));
-
- pEntryName->SetProperty(ASM_NAME_MVID, pNativeImageSig, sizeof(*pNativeImageSig));
-
- DeleteFusionCacheEntry(pEntryName);
-}
-
-// @TODO: Use the default flags like CORCOMPILE_CONFIG_DEBUG_DEFAULT
-
-__success(SUCCEEDED(return))
-STDAPI GetNativeImageDescription(__in_z LPCWSTR customString,
- DWORD dwConfigMask,
- __inout_ecount(*pdwLength) LPWSTR pwzString,
- LPDWORD pdwLength)
-{
- _ASSERTE(pdwLength);
- //_ASSERTE(pwzString == NULL || (pwzString[(*pdwLength) - 1], true));
-
- #define ZAP_STRING_DEBUG W("<debug>")
- #define ZAP_STRING_PROFILING W("<profiling>")
- #define ZAP_STRING_INSTRUMENTED W("<instrumented>")
-
- StackSString ssBuff;
-
- if (customString[0] != W('\0'))
- {
- ssBuff.Append(W(" (set "));
- ssBuff.Append(customString);
- ssBuff.Append(W(')'));
- }
-
- if (dwConfigMask & CORCOMPILE_CONFIG_DEBUG)
- ssBuff.Append(W(" ") ZAP_STRING_DEBUG);
-
- if (dwConfigMask & CORCOMPILE_CONFIG_PROFILING)
- ssBuff.Append(W(" ") ZAP_STRING_PROFILING);
-
- if (dwConfigMask & CORCOMPILE_CONFIG_INSTRUMENTATION)
- ssBuff.Append(W(" ") ZAP_STRING_INSTRUMENTED);
-
- DWORD length = (DWORD) ssBuff.GetCount() + 1; // +1 for the null terminating character
- DWORD inputLength = *pdwLength;
-
- *pdwLength = length;
- if (pwzString)
- {
- wcsncpy_s(pwzString, inputLength, ssBuff.GetUnicode(), _TRUNCATE);
-
- if (length > inputLength)
- return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
- }
-
- return S_OK;
-}
-#endif // FEATURE_FUSION
//**********************************************************************
// Copy of vm\i386\cgenCpu.h
@@ -1358,529 +857,6 @@ BOOL Runtime_Test_For_SSE2();
#endif
-#ifdef FEATURE_FUSION
-void Zapper::PrintDependencies(
- IMetaDataAssemblyImport * pAssemblyImport,
- CORCOMPILE_DEPENDENCY * pDependencies,
- COUNT_T cDependencies,
- SString &s)
-{
- if (cDependencies == 0)
- {
- s.AppendPrintf("\tNo dependencies\n");
- return;
- }
-
- s.AppendASCII("\tDependencies:\n");
-
- CORCOMPILE_DEPENDENCY *pDepsEnd = pDependencies + cDependencies;
- for(CORCOMPILE_DEPENDENCY *pDeps = pDependencies; pDeps < pDepsEnd; pDeps++)
- {
- mdAssemblyRef assem = pDeps->dwAssemblyDef;
- if (assem == mdAssemblyRefNil)
- assem = pDeps->dwAssemblyRef;
-
- NonVMComHolder<IAssemblyName> pNameHolder =
- GetAssemblyRefFusionName(pAssemblyImport, assem);
-
- StackSString ss;
- FusionBind::GetAssemblyNameDisplayName(pNameHolder, ss, ASM_DISPLAYF_FULL);
-
- s.AppendPrintf(W("\t\t%s:\n"), ss.GetUnicode());
-
- if (pDeps->dwAssemblyDef == mdAssemblyRefNil)
- {
- s.AppendASCII("\t\t\t** Missing dependency assembly **\n");
- continue;
- }
-
- //
- // Dependency MVID/HASH
- //
-
- WCHAR szGuid[64];
- GuidToLPWSTR(pDeps->signAssemblyDef.mvid, szGuid, NumItems(szGuid));
- s.AppendPrintf(W("\t\t\tGuid:%s\n"), szGuid);
-
- if (pDeps->dwAssemblyRef != pDeps->dwAssemblyDef)
- {
- // If there is a redirect, display the original dependency version
-
- NonVMComHolder<IAssemblyName> pOrigName =
- GetAssemblyRefFusionName(pAssemblyImport, pDeps->dwAssemblyRef);
-
- StackSString ss;
- FusionBind::GetAssemblyNameDisplayName(pOrigName, ss, ASM_DISPLAYF_VERSION);
-
- s.AppendPrintf(W("\t\t\tOriginal Ref: %s\n"), ss.GetUnicode());
- }
-
- if (pDeps->signNativeImage != INVALID_NGEN_SIGNATURE)
- {
- GuidToLPWSTR(pDeps->signNativeImage, szGuid, NumItems(szGuid));
- s.AppendPrintf(W("\t\t\tHardbound Guid:%s\n"), szGuid);
- }
- }
-
- s.AppendASCII("\n");
-}
-
-
-BOOL Zapper::VerifyDependencies(
- IMDInternalImport * pAssemblyImport,
- CORCOMPILE_DEPENDENCY * pDependencies,
- COUNT_T cDependencies)
-{
- CORCOMPILE_DEPENDENCY *pDepsEnd = pDependencies + cDependencies;
- for(CORCOMPILE_DEPENDENCY *pDeps = pDependencies; pDeps < pDepsEnd; pDeps++)
- {
- mdAssemblyRef assem = pDeps->dwAssemblyDef;
-
- // TODO: Better support for images with unresolved dependencies?
- if (assem == mdAssemblyRefNil)
- continue;
-
- CORINFO_ASSEMBLY_HANDLE hAssemblyRef;
- if (m_pEECompileInfo->LoadAssemblyRef(pAssemblyImport, assem, &hAssemblyRef) != S_OK)
- return FALSE;
-
- CORCOMPILE_VERSION_INFO sourceVersionInfo;
- IfFailThrow(m_pEECompileInfo->GetAssemblyVersionInfo(hAssemblyRef,
- &sourceVersionInfo));
-
- // check the soft bound dependency
- CORCOMPILE_ASSEMBLY_SIGNATURE * pSign1 = &pDeps->signAssemblyDef;
- CORCOMPILE_ASSEMBLY_SIGNATURE * pSign2 = &sourceVersionInfo.sourceAssembly;
-
- if ( (pSign1->mvid != pSign2->mvid)
- || (pSign1->timeStamp != pSign2->timeStamp)
- || (pSign1->ilImageSize != pSign2->ilImageSize) )
- {
- return FALSE;
- }
-
- if (pDeps->signNativeImage != INVALID_NGEN_SIGNATURE)
- {
- // check the hardbound dependency
- CORCOMPILE_NGEN_SIGNATURE nativeImageSig;
-
- if (!CheckAssemblyUpToDate(hAssemblyRef, &nativeImageSig))
- return FALSE;
-
- if (pDeps->signNativeImage != nativeImageSig)
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-void Zapper::PrintAssemblyVersionInfo(IAssemblyName *pName, SString &s)
-{
- //
- // Bind zap assembly to a path
- //
-
- WCHAR szGuid[64];
- WCHAR path[MAX_LONGPATH];
- DWORD cPath = MAX_LONGPATH;
-
- IfFailThrow(QueryNativeAssemblyInfo(pName, path, &cPath));
-
- // The LoadLibrary call fails occasionally in the lab due to sharing violation. Retry when needed.
- const int SHARING_VIOLATION_RETRY_TIMES = 10;
- const DWORD SHARING_VIOLATION_RETRY_WAITING_TIME = 100;
- HModuleHolder hMod;
- DWORD err;
- for (int i = 0; i < SHARING_VIOLATION_RETRY_TIMES; i++)
- {
- hMod = ::WszLoadLibrary(path);
- if (! hMod.IsNull())
- break;
- // Save last error before ClrSleepEx overwrites it.
- err = GetLastError();
- ClrSleepEx(SHARING_VIOLATION_RETRY_WAITING_TIME, FALSE);
- }
- if (hMod.IsNull())
- ThrowWin32(err);
-
- PEDecoder pedecoder(hMod);
-
- CORCOMPILE_VERSION_INFO *pVersionInfo = pedecoder.GetNativeVersionInfo();
-
- COUNT_T cMeta;
- const void *pMeta = pedecoder.GetNativeManifestMetadata(&cMeta);
-
- NonVMComHolder<IMetaDataAssemblyImport> pAssemblyImport;
- IfFailThrow(m_pMetaDataDispenser->OpenScopeOnMemory(pMeta, cMeta, ofRead,
- IID_IMetaDataAssemblyImport,
- (IUnknown**)&pAssemblyImport));
-
- NonVMComHolder<IMetaDataImport> pImport;
- IfFailThrow(pAssemblyImport->QueryInterface(IID_IMetaDataImport,
- (void**)&pImport));
-
- //
- // Source MVID
- //
-
- GuidToLPWSTR(pVersionInfo->sourceAssembly.mvid, szGuid, NumItems(szGuid));
- s.AppendPrintf(W("\tSource MVID:\t%s\n"), szGuid);
-
- //
- // Signature of generated ngen image
- //
-
- GuidToLPWSTR(pVersionInfo->signature, szGuid, NumItems(szGuid));
- s.AppendPrintf(W("\tNGen GUID sign:\t%s\n"), szGuid);
-
-
- s.AppendASCII("\tOS:\t\t");
- switch (pVersionInfo->wOSPlatformID)
- {
- case VER_PLATFORM_WIN32_NT:
- s.AppendASCII("WinNT");
- break;
- default:
- s.AppendPrintf("<unknown> (%d)", pVersionInfo->wOSPlatformID);
- break;
- }
- s.AppendASCII("\n");
-
- //
- // Processor
- //
-
- s.AppendASCII("\tProcessor:\t");
-
- CORINFO_CPU cpuInfo = pVersionInfo->cpuInfo;
-
- switch (pVersionInfo->wMachine)
- {
- case IMAGE_FILE_MACHINE_I386:
- {
- s.AppendASCII("x86");
- DWORD cpuType = cpuInfo.dwCPUType;
-#ifdef _TARGET_X86_
-
- //
- // Specific processor ID
- //
-
- switch (CPU_X86_FAMILY(cpuType))
- {
- case CPU_X86_486:
- s.AppendASCII("(486)");
- break;
-
- case CPU_X86_PENTIUM:
- s.AppendASCII("(Pentium)");
- break;
-
- case CPU_X86_PENTIUM_PRO:
- if(CPU_X86_MODEL(cpuType) == CPU_X86_MODEL_PENTIUM_PRO_BANIAS)
- {
- s.AppendASCII("(Pentium M)");
- }
- else
- {
- s.AppendASCII("(PentiumPro)");
- }
- break;
-
- case CPU_X86_PENTIUM_4:
- s.AppendASCII("(Pentium 4)");
- break;
-
- default:
- s.AppendPrintf("(Family %d, Model %d (%03x))",
- CPU_X86_FAMILY(cpuType), CPU_X86_MODEL(cpuType), cpuType);
- break;
- }
-
- s.AppendPrintf(" (features: %08x)", cpuInfo.dwFeatures);
-
- break;
-
-#endif // _TARGET_X86_
- }
-
- case IMAGE_FILE_MACHINE_IA64:
- s.AppendASCII("ia64");
- break;
-
- case IMAGE_FILE_MACHINE_AMD64:
- s.AppendASCII("amd64");
- break;
-
- case IMAGE_FILE_MACHINE_ARMNT:
- s.AppendASCII("arm");
- break;
- }
- s.AppendASCII("\n");
-
- //
- // EE version
- //
-
- s.AppendPrintf("\tRuntime:\t%d.%d.%.d.%d\n",
- pVersionInfo->wVersionMajor, pVersionInfo->wVersionMinor,
- pVersionInfo->wVersionBuildNumber, pVersionInfo->wVersionPrivateBuildNumber);
-
- s.AppendPrintf("\tclr.dll:\tTimeStamp=%08X, VirtualSize=%08X\n",
- pVersionInfo->runtimeDllInfo[CLR_INFO].timeStamp,
- pVersionInfo->runtimeDllInfo[CLR_INFO].virtualSize);
-
- //
- // Flags
- //
-
- s.AppendASCII("\tFlags:\t\t");
- if (pVersionInfo->wBuild == CORCOMPILE_BUILD_CHECKED)
- {
- s.AppendASCII("<checked> ");
- }
-
- if (pVersionInfo->wCodegenFlags & CORCOMPILE_CODEGEN_PROFILING)
- {
- s.AppendASCII("<profiling> ");
- }
- else if ((pVersionInfo->wCodegenFlags & CORCOMPILE_CODEGEN_DEBUGGING))
- {
- s.AppendASCII("<debug> ");
- }
-
- if (pVersionInfo->wCodegenFlags & CORCOMPILE_CODEGEN_PROF_INSTRUMENTING)
- {
- s.AppendASCII("<instrumenting> ");
- }
- s.AppendASCII("\n");
-
- //
- // Config
- //
-
- s.AppendASCII("\tScenarios:\t\t");
-
- if (pVersionInfo->wConfigFlags & CORCOMPILE_CONFIG_DEBUG_NONE)
- {
- s.AppendASCII("<no debug info> ");
- }
- if (pVersionInfo->wConfigFlags & CORCOMPILE_CONFIG_DEBUG)
- {
- s.AppendASCII("<debugger> ");
- }
- if (pVersionInfo->wConfigFlags & CORCOMPILE_CONFIG_DEBUG_DEFAULT)
- {
- s.AppendASCII("<no debugger> ");
- }
-
- if (pVersionInfo->wConfigFlags & CORCOMPILE_CONFIG_PROFILING_NONE)
- {
- s.AppendASCII("<no profiler> ");
- }
- if (pVersionInfo->wConfigFlags & CORCOMPILE_CONFIG_PROFILING)
- {
- s.AppendASCII("<instrumenting profiler> ");
- }
-
- if (pVersionInfo->wConfigFlags & CORCOMPILE_CONFIG_INSTRUMENTATION_NONE)
- {
- s.AppendASCII("<no instrumentation> ");
- }
-
- if (pVersionInfo->wConfigFlags & CORCOMPILE_CONFIG_INSTRUMENTATION)
- {
- s.AppendASCII("<block instrumentation> ");
- }
-
- s.AppendASCII("\n");
-
- //
- // Native image file name
- //
-
- s.AppendPrintf(W("\tFile:\t\t%s\n"), path);
-
- //
- // Dependencies
- //
-
- COUNT_T cDependencies;
- CORCOMPILE_DEPENDENCY *pDependencies = pedecoder.GetNativeDependencies(&cDependencies);
-
- PrintDependencies(pAssemblyImport, pDependencies, cDependencies, s);
-}
-
-IAssemblyName *Zapper::GetAssemblyFusionName(IMetaDataAssemblyImport *pImport)
-{
- IAssemblyName *pName;
-
- mdAssembly a;
- IfFailThrow(pImport->GetAssemblyFromScope(&a));
-
- ASSEMBLYMETADATA md = {0};
- LPWSTR szName;
- ULONG cbName = 0;
- const void *pbPublicKeyToken;
- ULONG cbPublicKeyToken;
- DWORD dwFlags;
-
- IfFailThrow(pImport->GetAssemblyProps(a,
- NULL, NULL, NULL,
- NULL, 0, &cbName,
- &md,
- NULL));
-
- szName = (LPWSTR) _alloca(cbName * sizeof(WCHAR));
- md.szLocale = (LPWSTR) _alloca(md.cbLocale * sizeof(WCHAR));
- md.rProcessor = (DWORD *) _alloca(md.ulProcessor * sizeof(DWORD));
- md.rOS = (OSINFO *) _alloca(md.ulOS * sizeof(OSINFO));
-
- IfFailThrow(pImport->GetAssemblyProps(a,
- &pbPublicKeyToken, &cbPublicKeyToken, NULL,
- szName, cbName, &cbName,
- &md,
- &dwFlags));
-
- IfFailThrow(CreateAssemblyNameObject(&pName, szName, 0, NULL));
-
- if (md.usMajorVersion != -1)
- IfFailThrow(pName->SetProperty(ASM_NAME_MAJOR_VERSION,
- &md.usMajorVersion,
- sizeof(USHORT)));
- if (md.usMinorVersion != -1)
- IfFailThrow(pName->SetProperty(ASM_NAME_MINOR_VERSION,
- &md.usMinorVersion,
- sizeof(USHORT)));
- if (md.usBuildNumber != -1)
- IfFailThrow(pName->SetProperty(ASM_NAME_BUILD_NUMBER,
- &md.usBuildNumber,
- sizeof(USHORT)));
- if (md.usRevisionNumber != -1)
- IfFailThrow(pName->SetProperty(ASM_NAME_REVISION_NUMBER,
- &md.usRevisionNumber,
- sizeof(USHORT)));
- if (md.ulProcessor > 0)
- IfFailThrow(pName->SetProperty(ASM_NAME_PROCESSOR_ID_ARRAY,
- &md.rProcessor,
- md.ulProcessor*sizeof(DWORD)));
- if (md.ulOS > 0)
- IfFailThrow(pName->SetProperty(ASM_NAME_OSINFO_ARRAY,
- &md.rOS,
- md.ulOS*sizeof(OSINFO)));
- if (md.cbLocale > 0)
- IfFailThrow(pName->SetProperty(ASM_NAME_CULTURE,
- md.szLocale,
- md.cbLocale*sizeof(WCHAR)));
-
- if (cbPublicKeyToken > 0)
- {
- if (!StrongNameTokenFromPublicKey((BYTE*)pbPublicKeyToken, cbPublicKeyToken,
- (BYTE**)&pbPublicKeyToken, &cbPublicKeyToken))
- IfFailThrow(StrongNameErrorInfo());
-
- IfFailThrow(pName->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN,
- (void*)pbPublicKeyToken,
- cbPublicKeyToken));
-
- StrongNameFreeBuffer((BYTE*)pbPublicKeyToken);
- }
-
- return pName;
-}
-
-IAssemblyName *Zapper::GetAssemblyRefFusionName(IMetaDataAssemblyImport *pImport,
- mdAssemblyRef ar)
-{
- IAssemblyName *pName;
-
- ASSEMBLYMETADATA md = {0};
- LPWSTR szName;
- ULONG cbName = 0;
- const void *pbPublicKeyOrToken;
- ULONG cbPublicKeyOrToken;
- DWORD dwFlags;
-
- IfFailThrow(pImport->GetAssemblyRefProps(ar,
- NULL, NULL,
- NULL, 0, &cbName,
- &md,
- NULL, NULL,
- NULL));
-
- szName = (LPWSTR) _alloca(cbName * sizeof(WCHAR));
- md.szLocale = (LPWSTR) _alloca(md.cbLocale * sizeof(WCHAR));
- md.rProcessor = (DWORD *) _alloca(md.ulProcessor * sizeof(DWORD));
- md.rOS = (OSINFO *) _alloca(md.ulOS * sizeof(OSINFO));
-
- IfFailThrow(pImport->GetAssemblyRefProps(ar,
- &pbPublicKeyOrToken, &cbPublicKeyOrToken,
- szName, cbName, &cbName,
- &md,
- NULL, NULL,
- &dwFlags));
-
- IfFailThrow(CreateAssemblyNameObject(&pName, szName, 0, NULL));
-
- if (md.usMajorVersion != -1)
- IfFailThrow(pName->SetProperty(ASM_NAME_MAJOR_VERSION,
- &md.usMajorVersion,
- sizeof(USHORT)));
- if (md.usMinorVersion != -1)
- IfFailThrow(pName->SetProperty(ASM_NAME_MINOR_VERSION,
- &md.usMinorVersion,
- sizeof(USHORT)));
- if (md.usBuildNumber != -1)
- IfFailThrow(pName->SetProperty(ASM_NAME_BUILD_NUMBER,
- &md.usBuildNumber,
- sizeof(USHORT)));
- if (md.usRevisionNumber != -1)
- IfFailThrow(pName->SetProperty(ASM_NAME_REVISION_NUMBER,
- &md.usRevisionNumber,
- sizeof(USHORT)));
- if (md.ulProcessor > 0)
- IfFailThrow(pName->SetProperty(ASM_NAME_PROCESSOR_ID_ARRAY,
- &md.rProcessor,
- md.ulProcessor*sizeof(DWORD)));
- if (md.ulOS > 0)
- IfFailThrow(pName->SetProperty(ASM_NAME_OSINFO_ARRAY,
- &md.rOS,
- md.ulOS*sizeof(OSINFO)));
- if (md.cbLocale > 0)
- IfFailThrow(pName->SetProperty(ASM_NAME_CULTURE,
- md.szLocale,
- md.cbLocale*sizeof(WCHAR)));
-
- if (cbPublicKeyOrToken > 0)
- {
- if (dwFlags & afPublicKey)
- IfFailThrow(pName->SetProperty(ASM_NAME_PUBLIC_KEY,
- (void*)pbPublicKeyOrToken,
- cbPublicKeyOrToken));
- else
- IfFailThrow(pName->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN,
- (void*)pbPublicKeyOrToken,
- cbPublicKeyOrToken));
- }
- else
- {
- IfFailThrow(pName->SetProperty(ASM_NAME_NULL_PUBLIC_KEY_TOKEN,
- NULL, 0));
- }
-
- // See if the assemblyref is retargetable (ie, for a generic assembly).
- if (IsAfRetargetable(dwFlags))
- {
- BOOL bTrue = TRUE;
- IfFailThrow(pName->SetProperty(ASM_NAME_RETARGET,
- &bTrue,
- sizeof(bTrue)));
- }
-
- return pName;
-}
-#endif //FEATURE_FUSION
BOOL Zapper::IsAssembly(LPCWSTR path)
{
@@ -2029,21 +1005,11 @@ void Zapper::CreateDependenciesLookupDomainInCurrentDomain()
SetContextInfo();
}
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
-void ZapperSetPlatformAssembliesPaths(SString &platformAssembliesPaths);
-#endif
-#ifdef FEATURE_CORECLR
void ZapperSetBindingPaths(ICorCompilationDomain *pDomain, SString &trustedPlatformAssemblies, SString &platformResourceRoots, SString &appPaths, SString &appNiPaths);
-#endif
void Zapper::CreateCompilationDomain()
{
-#if defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- // Platform assemblies paths have to be set before appdomain is setup so that
- // mscorlib.dll can be loaded from them.
- ZapperSetPlatformAssembliesPaths(m_platformAssembliesPaths);
-#endif
BOOL fForceDebug = FALSE;
if (!m_pOpt->m_autodebug)
@@ -2069,7 +1035,6 @@ void Zapper::CreateCompilationDomain()
IfFailThrow(m_pDomain->SetPlatformWinmdPaths(m_platformWinmdPaths));
#endif
-#ifdef FEATURE_CORECLR
// we support only TPA binding on CoreCLR
if (!m_trustedPlatformAssemblies.IsEmpty())
@@ -2078,7 +1043,6 @@ void Zapper::CreateCompilationDomain()
// Add the trusted paths and apppath to the binding list
ZapperSetBindingPaths(m_pDomain, m_trustedPlatformAssemblies, m_platformResourceRoots, m_appPaths, m_appNiPaths);
}
-#endif
}
void Zapper::CreateDependenciesLookupDomain()
@@ -2156,64 +1120,6 @@ void Zapper::CreatePdbInCurrentDomain(BSTR pAssemblyPathOrName, BSTR pNativeImag
m_pEECompileInfo->SetIsGeneratingNgenPDB(TRUE);
-#ifdef FEATURE_FUSION
- ReleaseHolder<IAssemblyName> pAssemblyName(NULL);
- HRESULT hr;
-
- if (pAssemblyPathOrName == NULL)
- {
- // No root was found, so we don't have an IL assembly path yet. Get IAssemblyName
- // from the aux file next to pNativeImagePath, and load from that IAssemblyName
- IfFailThrow(GetAssemblyNameFromNIPath(pNativeImagePath, &pAssemblyName));
- IfFailThrow(m_pEECompileInfo->LoadAssemblyByIAssemblyName(pAssemblyName, &hAssembly));
- }
- else
- {
- DWORD attributes = WszGetFileAttributes(pAssemblyPathOrName);
- if (attributes == INVALID_FILE_ATTRIBUTES ||
- ((attributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY))
- {
- // pAssemblyPathOrName doesn't map to a valid file, so assume it's an
- // assembly name that we can parse and generate an IAssemblyName from, and
- // then load from the IAssemblyName
-
- IfFailThrow(m_pEECompileInfo->LoadAssemblyByName(pAssemblyPathOrName, &hAssembly));
-
- }
- else
- {
- // pAssemblyPathOrName DOES map to a valid file, so load it directly.
- IfFailThrow(m_pEECompileInfo->LoadAssemblyByPath(pAssemblyPathOrName,
- // fExplicitBindToNativeImage: On the phone, a path to the NI is specified
- // explicitly (even with .ni. in the name). All other callers specify a path to
- // the IL, and the NI is inferred, so this is normally FALSE in those other
- // cases.
- FALSE,
- &hAssembly));
- }
- }
-
- // Now is a good time to make sure pNativeImagePath is the same native image
- // fusion loaded
- {
- WCHAR wzZapImagePath[MAX_LONGPATH] = {0};
- DWORD dwZapImagePathLength = MAX_LONGPATH;
-
- hr = E_FAIL;
- if (m_pEECompileInfo->CheckAssemblyZap(hAssembly, wzZapImagePath, &dwZapImagePathLength))
- {
- if (_wcsicmp(wzZapImagePath, pNativeImagePath) != 0)
- {
- GetSvcLogger()->Printf(
- W("Unable to load '%s'. Please ensure that it is a native image and is up to date. Perhaps you meant to specify this native image instead: '%s'\n"),
- pNativeImagePath,
- wzZapImagePath);
-
- ThrowHR(E_FAIL);
- }
- }
- }
-#else // FEATURE_FUSION
IfFailThrow(m_pEECompileInfo->LoadAssemblyByPath(
pAssemblyPathOrName,
@@ -2224,7 +1130,6 @@ void Zapper::CreatePdbInCurrentDomain(BSTR pAssemblyPathOrName, BSTR pNativeImag
TRUE,
&hAssembly));
-#endif // FEATURE_FUSION
// Ensure all modules belonging to this assembly get loaded. The CreatePdb() call
@@ -2249,12 +1154,12 @@ void Zapper::CreatePdbInCurrentDomain(BSTR pAssemblyPathOrName, BSTR pNativeImag
}
LPCWSTR pDiasymreaderPath = nullptr;
-#if defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#if !defined(NO_NGENPDB)
if (m_DiasymreaderPath.GetCount() > 0)
{
pDiasymreaderPath = m_DiasymreaderPath.GetUnicode();
}
-#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#endif //!defined(NO_NGENPDB)
IfFailThrow(::CreatePdb(hAssembly, pNativeImagePath, pPdbPath, pdbLines, pManagedPdbSearchPath, pDiasymreaderPath));
}
@@ -2272,302 +1177,8 @@ void Zapper::CreatePdbInCurrentDomain(BSTR pAssemblyPathOrName, BSTR pNativeImag
void Zapper::ComputeDependencies(LPCWSTR pAssemblyName, CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
{
-#ifdef FEATURE_FUSION
- class Callback : public DomainCallback
- {
- public:
- Callback(Zapper *pZapper, LPCWSTR pAssemblyName, CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
- {
- this->pZapper = pZapper;
- this->pAssemblyName = pAssemblyName;
- this->pNativeImageSig = pNativeImageSig;
- }
-
- virtual void doCallback()
- {
- pZapper->ComputeDependenciesInCurrentDomain(pAssemblyName, pNativeImageSig);
- }
-
- Zapper* pZapper;
- LPCWSTR pAssemblyName;
- CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig;
- };
-
- _ASSERTE(m_pDomain);
- Callback callback(this, pAssemblyName, pNativeImageSig);
- InvokeDomainCallback(&callback);
-#endif // FEATURE_FUSION
-}
-
-#ifdef FEATURE_FUSION
-
-void Zapper::ComputeDependenciesInCurrentDomain(LPCWSTR pAssemblyString, CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
-{
- //
- // Load the assembly.
- //
- // "string" may be a path or assembly display name.
- // To decide, we see if it is the name of a valid file.
- //
-
- CORINFO_ASSEMBLY_HANDLE hAssembly;
- HRESULT hr;
-
- DWORD attributes = WszGetFileAttributes(pAssemblyString);
- if (attributes == INVALID_FILE_ATTRIBUTES || ((attributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY))
- {
- IfFailThrow(m_pEECompileInfo->LoadAssemblyByName(pAssemblyString,
- &hAssembly));
- }
- else
- {
-#if defined(FEATURE_APPX) && !defined(FEATURE_CORECLR)
- if (m_pOpt->m_fAutoNGen)
- {
- // Make sure we're not been spoofed into loading an assembly that might be unsafe to load.
- // Loading by path so we better be AppX or a WinMD
- StackSString s(pAssemblyString);
- SString literalWinMD(SString::Literal, W(".winmd"));
- BOOL isWinMD = (s.GetCount() > 6) && s.MatchCaseInsensitive(s.End() - 6, literalWinMD);
- if (!AppX::IsAppXProcess() && !isWinMD)
- {
- Error(W("Cannot load assembly %s for automatic NGen.\n"), pAssemblyString);
- ThrowHR(E_FAIL);
- }
-
- // Is AppX NGen disabled?
- if ((AssemblyUsageLogManager::GetUsageLogFlags() & AssemblyUsageLogManager::ASSEMBLY_USAGE_LOG_FLAGS_APPLOCALNGENDISABLED) != 0)
- {
- memset(pNativeImageSig, 0, sizeof(*pNativeImageSig)); // Fake NI signature to disable NGen.
- Warning(W("NGen disabled for this application.\n"));
- return;
- }
- }
-#endif
-
- hr = m_pEECompileInfo->LoadAssemblyByPath(pAssemblyString,
- FALSE, // fExplicitBindToNativeImage
- &hAssembly);
- if (hr == CLR_E_BIND_TYPE_NOT_FOUND)
- { // This means we are ngen'ing WinMD file which does not have any public WinRT type - therefore cannot be ever used
- // Note: It's comming from call to code:GetFirstWinRTTypeDef
-
- // Let's not create the ngen image
- if (pNativeImageSig != NULL)
- {
- memset(pNativeImageSig, 0, sizeof(*pNativeImageSig)); // Fake NI signature to disable NGen.
- }
- Warning(W("NGen is not supported for empty WinMD files.\n"));
- return;
- }
- IfFailThrow(hr);
- }
-
-#ifndef FEATURE_CORECLR
- if (m_pOpt->m_fAutoNGen && !m_pEECompileInfo->SupportsAutoNGen(hAssembly))
- {
- Error(W("Assembly %s does not support automatic NGen.\n"), pAssemblyString);
- ThrowHR(E_FAIL);
- }
-#endif // FEATURE_CORECLR
-
- //
- // Check if we have a native image already, and if so get its GUID
- //
-
- WCHAR zapManifestPath[MAX_LONGPATH];
- DWORD cZapManifestPath = MAX_LONGPATH;
- if (pNativeImageSig &&
- m_pEECompileInfo->CheckAssemblyZap(hAssembly, zapManifestPath, &cZapManifestPath))
- {
- NonVMComHolder<INativeImageInstallInfo> pNIInstallInfo;
-
- IfFailThrow(GetAssemblyMDInternalImport(
- zapManifestPath,
- IID_INativeImageInstallInfo,
- (IUnknown **)&pNIInstallInfo));
-
- IfFailThrow(pNIInstallInfo->GetSignature(pNativeImageSig));
- }
-
- //
- // Set the display name for the assembly
- //
-
- StackSString ss;
- GetAssemblyName(m_pEECompileInfo, hAssembly, ss, ICorCompileInfo::GANF_Default);
-
- m_assemblyDependencies.SetDisplayName(ss.GetUnicode());
-
- ComputeAssemblyDependencies(hAssembly);
-}
-
-void Zapper::ComputeAssemblyDependencies(CORINFO_ASSEMBLY_HANDLE hAssembly)
-{
- HRESULT hr = S_OK;
- NonVMComHolder<IMDInternalImport> pAssemblyImport = m_pEECompileInfo->GetAssemblyMetaDataImport(hAssembly);
-
- EX_TRY
- {
- //
- // Enumerate the dependencies
- //
-
- HENUMInternalHolder hEnum(pAssemblyImport);
- hEnum.EnumAllInit(mdtAssemblyRef);
-
- // Need to reinitialize the dependencies list, since we could have been called for other assemblies
- // belonging to the same root. Zapper::ComputeAssemblyDependencies is first called for the root
- // assembly, then called for each hard dependencies, and called for each soft dependencies unless
- // /nodependencies switch is used.
- m_assemblyDependencies.Reinitialize();
-
- if (!CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NgenAllowMscorlibSoftbind))
- {
- // Force all assemblies (other than mscorlib itself) to hardbind to mscorlib.
- // This ensures that mscorlib is NGen'ed before all other assemblies.
- CORINFO_ASSEMBLY_HANDLE hAssemblyMscorlib = m_pEECompileInfo->GetModuleAssembly(m_pEECompileInfo->GetLoaderModuleForMscorlib());
- if (hAssembly != hAssemblyMscorlib)
- {
- StackSString ss;
- GetAssemblyName(m_pEECompileInfo, hAssemblyMscorlib, ss, ICorCompileInfo::GANF_Default);
-
- m_assemblyDependencies.Append(ss.GetUnicode(), LoadAlways, NGenDefault);
- }
- }
-
- mdAssembly token;
- mdMethodDef md;
- while (pAssemblyImport->EnumNext(&hEnum, &token))
- {
- CORINFO_ASSEMBLY_HANDLE hAssemblyRef;
- HRESULT hrLoad = m_pEECompileInfo->LoadAssemblyRef(pAssemblyImport, token, &hAssemblyRef);
- if (FAILED(hrLoad))
- {
- // Failed to load a dependency. Print a warning and move to the next dependency.
-
- LPCSTR pszName;
- IfFailThrow(pAssemblyImport->GetAssemblyRefProps(token, NULL, NULL,
- &pszName, NULL,
- NULL, NULL, NULL));
-
- StackSString sName(SString::Utf8, pszName);
-
- StackSString hrMsg;
- GetHRMsg(hrLoad, hrMsg);
-
- Warning(W("Failed to load dependency %s of assembly %s because of the following error : %s\n"),
- sName.GetUnicode(),
- m_assemblyDependencies.GetDisplayName(),
- hrMsg.GetUnicode());
- continue;
- }
- else if (hrLoad == S_OK)
- {
- _ASSERTE(hAssemblyRef != NULL);
-
- StackSString ss;
- GetAssemblyName(m_pEECompileInfo, hAssemblyRef, ss, ICorCompileInfo::GANF_Default);
-
- LoadHintEnum loadHint = LoadDefault;
- IfFailThrow(m_pEECompileInfo->GetLoadHint(hAssembly, hAssemblyRef, &loadHint));
-
- NGenHintEnum ngenHint = NGenDefault;
- // Not supported
- //IfFailThrow(m_pEECompileInfo->GetNGenHint(hAssemblyRef, &ngenHint));
- m_assemblyDependencies.Append(ss.GetUnicode(), loadHint, ngenHint);
- }
- }
-
-#ifdef FEATURE_COMINTEROP
- HENUMInternalHolder hTypeRefEnum(pAssemblyImport);
- hTypeRefEnum.EnumAllInit(mdtTypeRef);
-
- mdTypeRef tkTypeRef;
- while(pAssemblyImport->EnumNext(&hTypeRefEnum, &tkTypeRef))
- {
- CORINFO_ASSEMBLY_HANDLE hAssemblyRef;
- HRESULT hrLoad = m_pEECompileInfo->LoadTypeRefWinRT(pAssemblyImport, tkTypeRef, &hAssemblyRef);
- if (FAILED(hrLoad))
- {
- // Failed to load a dependency. Print a warning and move to the next dependency.
- LPCSTR psznamespace;
- LPCSTR pszname;
- pAssemblyImport->GetNameOfTypeRef(tkTypeRef, &psznamespace, &pszname);
-
- StackSString sName(SString::Utf8, pszname);
- StackSString sNamespace(SString::Utf8, psznamespace);
- StackSString hrMsg;
- GetHRMsg(hrLoad, hrMsg);
-
- Warning(W("Failed to load WinRT type dependency %s.%s of assembly %s because of the following error : %s\n"),
- sNamespace.GetUnicode(),
- sName.GetUnicode(),
- m_assemblyDependencies.GetDisplayName(),
- hrMsg.GetUnicode());
- continue;
- }
- else if (hrLoad == S_OK)
- {
- _ASSERTE(hAssemblyRef != NULL);
- StackSString ss;
-
- CORINFO_MODULE_HANDLE hModule = m_pEECompileInfo->GetAssemblyModule(hAssemblyRef);
- m_pEECompileInfo->GetModuleFileName(hModule, ss);
-
- LoadHintEnum loadHint = LoadDefault;
- IfFailThrow(m_pEECompileInfo->GetLoadHint(hAssembly, hAssemblyRef, &loadHint));
-
- NGenHintEnum ngenHint = NGenDefault;
-
- // Append verifies no duplicates
- m_assemblyDependencies.Append(ss.GetUnicode(), loadHint, ngenHint);
- }
- }
-#endif
- //
- // Get the default NGen setting for the assembly
- //
-
- NGenHintEnum ngenHint = NGenDefault;
- // Not supported
- // IfFailThrow(m_pEECompileInfo->GetNGenHint(hAssembly, &ngenHint));
- m_assemblyDependencies.SetNGenHint(ngenHint);
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- RetailAssertIfExpectedClean();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- IfFailThrow(hr);
-
- HangWorker(W("NGenDependencyWorkerHang"), W("NGenDependencyWorkerInsideHang"));
}
-void Zapper::HangWorker(LPCWSTR hangKey, LPCWSTR insideHangKey)
-{
- if (REGUTIL::GetConfigDWORD_DontUse_(hangKey, 0) != 1)
- {
- return;
- }
-
- RegKeyHolder hKey;
- if (WszRegCreateKeyEx(HKEY_LOCAL_MACHINE, FRAMEWORK_REGISTRY_KEY_W, 0,
- NULL, 0, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
- {
- DWORD dwValue = 1;
- WszRegSetValueEx(hKey, insideHangKey, 0, REG_DWORD,
- reinterpret_cast<BYTE *>(&dwValue), sizeof(dwValue));
- }
-
- while (true)
- {
- ClrSleepEx(1000, FALSE);
- }
-}
-#endif // FEATURE_FUSION
//
// Compile a module by name
@@ -2603,25 +1214,8 @@ HRESULT Zapper::Compile(LPCWSTR string, CORCOMPILE_NGEN_SIGNATURE * pNativeImage
{
fMscorlib = true;
}
-#ifndef FEATURE_CORECLR
- else
- if (_wcsnicmp(fileName, W("mscorlib"), 8) == 0 && (wcslen(fileName) == 8 || fileName[8] == W(',')))
- {
- fMscorlib = true;
- }
-#endif
-#if !defined(CROSSGEN_COMPILE) && !defined(FEATURE_CORECLR)
- if (fMscorlib)
- {
- //
- // Enable ningen by default for mscorlib to get identical images between ngen and crossgen
- //
- g_ningenState = 1;
- }
-#endif
-#if defined(CROSSGEN_COMPILE) || defined(FEATURE_CORECLR)
if (fMscorlib)
{
//
@@ -2629,7 +1223,6 @@ HRESULT Zapper::Compile(LPCWSTR string, CORCOMPILE_NGEN_SIGNATURE * pNativeImage
//
g_fAllowNativeImages = false;
}
-#endif
// the errors in CreateCompilationDomain are fatal - propogate them up
CreateCompilationDomain();
@@ -2680,16 +1273,7 @@ void Zapper::CompileInCurrentDomain(__in LPCWSTR string, CORCOMPILE_NGEN_SIGNATU
BEGIN_ENTRYPOINT_VOIDRET;
-#ifndef FEATURE_CORECLR
- // Set the hard binding list. This needs to be done early, before we attempt to use any
- // softbound native images, in order to ensure NGen determinism.
- SetAssemblyHardBindList();
-#endif // !FEATURE_CORECLR
-#ifdef FEATURE_FUSION
- // Set the context info for the current domain
- SetContextInfo(string);
-#endif
//
// Load the assembly.
@@ -2701,71 +1285,10 @@ void Zapper::CompileInCurrentDomain(__in LPCWSTR string, CORCOMPILE_NGEN_SIGNATU
_ASSERTE(m_hAssembly == NULL);
//without fusion, this has to be a file name
-#ifdef FEATURE_FUSION
- DWORD attributes = WszGetFileAttributes(string);
- if (attributes == INVALID_FILE_ATTRIBUTES || ((attributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY))
- {
- IfFailThrow(m_pEECompileInfo->LoadAssemblyByName(string, &m_hAssembly));
-
- /* @TODO: If this is the first input, check if it is an EXE
- using m_pEECompileInfo->GetAssemblyCodeBase(), and print a
- warning that its better to use the EXE file name on the
- command-line instead of the full assembly name, so that we
- will pick the right runtime version from its config file
- (if present). We could make this work even for full assembly name,
- but that does not currently work, and this will not be an
- issue once we require only one platform-runtime version
- on the machine
- */
- StackSString codeBase;
- m_pEECompileInfo->GetAssemblyCodeBase(m_hAssembly, codeBase);
- if (codeBase.GetCount() > 4)
- {
- SString::Iterator i = codeBase.End() - 4;
- if (codeBase.MatchCaseInsensitive(i, SL(".exe")))
- Warning(W("Specify the input as a .EXE for ngen to pick up the config-file\n"));
- }
- }
- else
-#endif //FEATURE_FUSION
{
IfFailThrow(m_pEECompileInfo->LoadAssemblyByPath(string, FALSE /* fExplicitBindToNativeImage */, &m_hAssembly));
}
-#ifdef FEATURE_FUSION
- //
- // Skip the compilation if the assembly is up to date
- //
- if (CheckAssemblyUpToDate(m_hAssembly, pNativeImageSig))
- {
- Info(W("Assembly %s is up to date.\n"), string);
- goto Exit;
- }
-
- //
- // Try to install native image from repository
- //
- if (TryToInstallFromRepository(m_hAssembly, pNativeImageSig))
- {
- Success(W("Installed native image for assembly %s from repository.\n"), string);
- goto Exit;
- }
-
- if (m_pOpt->m_fRepositoryOnly)
- {
- Info(W("Unable to find native image for assembly %s in repository, skipping.\n"), string);
- goto Exit;
- }
-
- //
- // Testing aid
- //
- if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_NativeImageRequire) != 0)
- {
- Error(W("Failed to find native image for assembly %s in repository.\n"), string);
- ThrowHR(E_FAIL);
- }
-#endif //FEATURE_FUSION
//
// Compile the assembly
@@ -2780,524 +1303,6 @@ Exit:
return;
}
-#ifdef FEATURE_FUSION
-BOOL Zapper::CheckAssemblyUpToDate(CORINFO_ASSEMBLY_HANDLE hAssembly, CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
-{
- WCHAR zapManifestPath[MAX_LONGPATH];
- DWORD cZapManifestPath = MAX_LONGPATH;
-
- if (!m_pEECompileInfo->CheckAssemblyZap(
- hAssembly,
- zapManifestPath, &cZapManifestPath))
- return FALSE;
-
- if (pNativeImageSig)
- {
- NonVMComHolder<INativeImageInstallInfo> pNIInstallInfo;
-
- IfFailThrow(GetAssemblyMDInternalImport(
- zapManifestPath,
- IID_INativeImageInstallInfo,
- (IUnknown **)&pNIInstallInfo));
-
- IfFailThrow(pNIInstallInfo->GetSignature(pNativeImageSig));
- }
-
- return TRUE;
-}
-
-BOOL Zapper::TryToInstallFromRepository(CORINFO_ASSEMBLY_HANDLE hAssembly, CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
-{
- BOOL fHitMismatchedVersion = FALSE;
- BOOL fHitMismatchedDependencies = FALSE;
-
- if (!m_pOpt->m_repositoryDir || (m_pOpt->m_repositoryFlags & IgnoreRepository) != 0)
- {
- // No repository
- return FALSE;
- }
-
- StackSString strSimpleName;
- GetAssemblyName(m_pEECompileInfo, hAssembly, strSimpleName, ICorCompileInfo::GANF_Simple);
-
- // First see if the NI is available in a folder named "NGen" under the CLR location.
- // This folder is used by CBS to store build lab generated NIs. Moving files out of
- // this folder might confuse CBS, so we hard link NIs from this folder into the NIC.
- WCHAR wszNGenPath[MAX_LONGPATH];
- DWORD dwNGenPathLen = COUNTOF(wszNGenPath);
- IfFailThrow(GetInternalSystemDirectory(wszNGenPath, &dwNGenPathLen));
-
- wcscat_s(wszNGenPath, COUNTOF(wszNGenPath), W("NativeImages"));
- if (TryToInstallFromRepositoryDir(StackSString(wszNGenPath), strSimpleName,
- pNativeImageSig, &fHitMismatchedVersion, &fHitMismatchedDependencies, TRUE))
- {
- return TRUE;
- }
-
- // If we are moving files from repository, first try to look for the native image in the
- // top-level directory of the repository. This is designed for scenarios where it is convenient
- // to put all native images in a flat directory. We don't support this with CopyFromRepository
- // switch, since it is tricky to figure out which files to copy.
- if ((m_pOpt->m_repositoryFlags & MoveFromRepository) != 0 &&
- TryToInstallFromRepositoryDir(StackSString(m_pOpt->m_repositoryDir), strSimpleName,
- pNativeImageSig, &fHitMismatchedVersion, &fHitMismatchedDependencies))
- {
- // Try to remove the repository directory in case it has become empty.
- // (Note that attempt to remove non-empty directory fails)
- WszRemoveDirectory(m_pOpt->m_repositoryDir);
- return TRUE;
- }
-
- // Copied from fusion\asmcache\cacheUtils.cpp
- // TODO: Clean this up
-#define MAX_ZAP_NAME_LENGTH 20
-#define ZAP_ABBR_END_CHAR W('#')
- StackSString strSubDirName;
- if (strSimpleName.GetCount() > MAX_ZAP_NAME_LENGTH)
- {
- strSubDirName.Set(strSimpleName.GetUnicode(), MAX_ZAP_NAME_LENGTH-1);
- strSubDirName.Append(ZAP_ABBR_END_CHAR);
- }
- else
- strSubDirName.Set(strSimpleName);
-
- StackSString strRepositorySubDir(StackSString(m_pOpt->m_repositoryDir), SL(W("\\")), strSubDirName);
-
- DWORD attributes = WszGetFileAttributes(strRepositorySubDir);
- if (attributes == INVALID_FILE_ATTRIBUTES || ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0))
- {
- return FALSE;
- }
-
- ClrDirectoryEnumerator de(strRepositorySubDir);
-
- //
- // Try to find a matching native image
- //
- while (de.Next())
- {
- StackSString strNativeImageDir;
- strNativeImageDir.Set(strRepositorySubDir, SL("\\"), de.GetFileName());
-
- if (TryToInstallFromRepositoryDir(strNativeImageDir, strSimpleName,
- pNativeImageSig, &fHitMismatchedVersion, &fHitMismatchedDependencies))
- {
- if (m_pOpt->m_repositoryFlags & MoveFromRepository)
- {
- // Close the iterator so that the directory can be deleted below
- de.Close();
-
- // Try to remove empty directories that are not needed anymore.
- // (Note that attempt to remove non-empty directory fails)
- if (WszRemoveDirectory(strNativeImageDir))
- {
- if (WszRemoveDirectory(strRepositorySubDir))
- {
- WszRemoveDirectory(m_pOpt->m_repositoryDir);
- }
- }
- }
-
- return TRUE;
- }
- }
-
- if (fHitMismatchedVersion)
- {
- ReportEventNGEN(EVENTLOG_WARNING_TYPE, NGEN_REPOSITORY, W("Version or flavor did not match with repository: %s"), strSimpleName.GetUnicode());
- }
-
- if (fHitMismatchedDependencies)
- {
- ReportEventNGEN(EVENTLOG_WARNING_TYPE, NGEN_REPOSITORY, W("Dependencies did not match with repository: %s"), strSimpleName.GetUnicode());
- }
-
- return FALSE;
-}
-
-BOOL Zapper::TryToInstallFromRepositoryDir(
- SString &strNativeImageDir, SString &strSimpleName,
- CORCOMPILE_NGEN_SIGNATURE *pNativeImageSig, BOOL *pfHitMismatchedVersion, BOOL *pfHitMismatchedDependencies, BOOL useHardLink)
-{
- StackSString strNativeImageName;
- StackSString strNativeImagePath;
-
- // probe for both .exe and .dll
- static const LPCWSTR c_Suffixes[] = { W(".dll"), W(".exe"), W(".ni.dll"), W(".ni.exe") };
-
- int suffix;
- for (suffix = 0; suffix < NumItems(c_Suffixes); suffix++)
- {
- strNativeImageName.Set(strSimpleName, SL(c_Suffixes[suffix]));
- strNativeImagePath.Set(strNativeImageDir, SL("\\"), strNativeImageName);
-
- if (WszGetFileAttributes(strNativeImagePath) != INVALID_FILE_ATTRIBUTES)
- {
- break;
- }
- }
- if (suffix == NumItems(c_Suffixes))
- {
- // No matching file
- return FALSE;
- }
-
- // Make sure the native image is unmapped before we try to install it
- {
- HModuleHolder hMod(::WszLoadLibrary(strNativeImagePath));
- if (hMod.IsNull())
- {
- // Corrupted image or something
- return FALSE;
- }
-
- PEDecoder pedecoder(hMod);
-
- if (!pedecoder.CheckNativeHeader())
- {
- // Corrupted image
- return FALSE;
- }
-
- class LoggableNativeImage : public LoggableAssembly
- {
- LPCWSTR m_lpszNativeImage;
-
- public:
- LoggableNativeImage(LPCWSTR lpszNativeImage)
- : m_lpszNativeImage(lpszNativeImage)
- {
- }
-
- virtual SString DisplayString() { return m_lpszNativeImage; }
-#ifdef FEATURE_FUSION
- virtual IAssemblyName* FusionAssemblyName() { return NULL; }
- virtual IFusionBindLog* FusionBindLog() { return NULL; }
-#endif // FEATURE_FUSION
- }
- loggableNativeImage(strNativeImagePath);
-
- // Does the version info of the native image match what we are looking for?
- CORCOMPILE_VERSION_INFO *pVersionInfo = pedecoder.GetNativeVersionInfo();
- if (!RuntimeVerifyNativeImageVersion(pVersionInfo, &loggableNativeImage) ||
- !RuntimeVerifyNativeImageFlavor(pVersionInfo, &loggableNativeImage))
- {
- // Version info does not match
- *pfHitMismatchedVersion = TRUE;
- return FALSE;
- }
-
- COUNT_T cDependencies;
- CORCOMPILE_DEPENDENCY *pDependencies = pedecoder.GetNativeDependencies(&cDependencies);
-
- COUNT_T cMeta;
- const void *pMeta = pedecoder.GetNativeManifestMetadata(&cMeta);
-
- NonVMComHolder<IMDInternalImport> pAssemblyImport;
-
- IfFailThrow(GetMetaDataInternalInterface((void *) pMeta,
- cMeta,
- ofRead,
- IID_IMDInternalImport,
- (void **) &pAssemblyImport));
-
- if (!VerifyDependencies(pAssemblyImport, pDependencies, cDependencies))
- {
- // Dependencies does not match
- *pfHitMismatchedDependencies = TRUE;
- return FALSE;
- }
- }
-
- if (m_pOpt->m_repositoryFlags & MoveFromRepository && !useHardLink)
- {
- // Move files to save I/O bandwidth
- InstallFromRepository(strNativeImagePath.GetUnicode(), pNativeImageSig);
- }
- else
- {
- // Copy files
- CopyAndInstallFromRepository(strNativeImageDir.GetUnicode(), strNativeImageName.GetUnicode(), pNativeImageSig, useHardLink);
- }
-
- ReportEventNGEN(EVENTLOG_SUCCESS, NGEN_REPOSITORY, W("Installed from repository: %s"), strSimpleName.GetUnicode());
- return TRUE;
-}
-
-void Zapper::InstallFromRepository(LPCWSTR lpszNativeImage,
- CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
-{
- //
- // Get the zap string.
- //
- HRESULT hr = S_OK;
-
- NonVMComHolder<IAssemblyName> pName;
- NonVMComHolder<IAssemblyLocation> pAssemblyLocation;
-
- ReleaseHolder<IBindContext> pBindCtx;
- if (FAILED(hr = m_pDomain->GetIBindContext(&pBindCtx)))
- {
- Error(W("Failed to get binding context.\n"));
- ThrowHR(hr);
- }
-
- HRESULT hrInstallCustomAssembly = InstallNativeAssembly(lpszNativeImage, INVALID_HANDLE_VALUE, m_pOpt->m_zapSet, pBindCtx, &pName, &pAssemblyLocation);
- if (FAILED(hrInstallCustomAssembly))
- {
- Error(W("Failed to install native image %s from repository.\n"), lpszNativeImage);
- ThrowHR(hrInstallCustomAssembly);
- }
-
- // TODO: It would be nice to verify that the native image works by calling CheckAssemblyUpToDate.
- // Unfortunately, it does not work since we have loaded the non-ngened image in this appdomain
- // already in CompileInCurrentDomain. We would need to create a new appdomain for the verification.
-
- //
- // Print a success message
- //
- if (!m_pOpt->m_silent)
- {
- PrintFusionCacheEntry(LogLevel_Info, pName);
- }
-
- WCHAR zapManifestPath[MAX_LONGPATH];
- DWORD cPath = MAX_LONGPATH;
- IfFailThrow(pAssemblyLocation->GetPath(zapManifestPath, &cPath));
-
- if (pNativeImageSig)
- {
- NonVMComHolder<INativeImageInstallInfo> pNIInstallInfo;
-
- IfFailThrow(GetAssemblyMDInternalImport(
- zapManifestPath,
- IID_INativeImageInstallInfo,
- (IUnknown **)&pNIInstallInfo));
-
- IfFailThrow(pNIInstallInfo->GetSignature(pNativeImageSig));
- }
-}
-
-void Zapper::CleanDirectory(LPCWSTR path)
-{
- // Handle the case when we are given file instead of directory
- DWORD dwAttributes = WszGetFileAttributes(path);
- if (dwAttributes == INVALID_FILE_ATTRIBUTES)
- {
- // Directory does not exist
- return;
- }
-
- if (!(dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
- {
- if (dwAttributes & FILE_ATTRIBUTE_READONLY)
- WszSetFileAttributes(path, dwAttributes&~FILE_ATTRIBUTE_READONLY);
-
- if (!WszDeleteFile(path))
- {
- Warning(W("Cannot delete file %s\n"), path);
- ThrowLastError();
- }
- return;
- }
-
- {
- ClrDirectoryEnumerator de(path);
-
- while (de.Next())
- {
- StackSString fullName;
- fullName.Set(path, W("\\"), de.GetFileName());
-
- if (de.GetFileAttributes() & FILE_ATTRIBUTE_DIRECTORY)
- {
- CleanDirectory(fullName);
- }
- else
- {
- if (de.GetFileAttributes() & FILE_ATTRIBUTE_READONLY)
- WszSetFileAttributes(fullName, de.GetFileAttributes()&~FILE_ATTRIBUTE_READONLY);
-
- if (!WszDeleteFile(fullName))
- {
- Warning(W("Cannot delete file %s\n"), fullName.GetUnicode());
- ThrowLastError();
- }
- }
- }
- }
-
- if (!WszRemoveDirectory(path))
- {
- Warning(W("Cannot remove directory %s\n"), path);
- ThrowLastError();
- }
-}
-
-void Zapper::TryCleanDirectory(LPCWSTR path)
-{
- EX_TRY
- {
- CleanDirectory(path);
- }
- EX_SWALLOW_NONTERMINAL;
-}
-
-//------------------------------------------------------------------------------
-
-// static
-void Zapper::TryCleanDirectory(Zapper * pZapper)
-{
- // @CONSIDER: If this fails, block for some time, and try again.
- // This will give more time for programs like Anti-virus software
- // to release the file handle.
- pZapper->TryCleanDirectory(pZapper->m_outputPath);
-}
-
-typedef Wrapper<Zapper*, DoNothing<Zapper*>, Zapper::TryCleanDirectory, NULL>
- TryCleanDirectoryHolder;
-
-//------------------------------------------------------------------------------
-// Sets Zapper::m_outputPath to the folder where we should create the
-// ngen images.
-//------------------------------------------------------------------------------
-
-void Zapper::GetOutputFolder()
-{
- /* We create a temporary folder in the NativeImageCache (NIC) instead of using
- WszGetTempPath(). This is because WszGetTempPath() is a private folder
- for the current user. Files created in there will have ACLs allowing
- accesses only to the current user. Later InstallCustomAssembly()
- will move the files to the NIC preserving the security attributes.
- Now other users cannot use the ngen images, which is bad.
- */
- WCHAR tempFolder[MAX_LONGPATH];
- DWORD tempFolderLen = NumItems(tempFolder);
- IfFailThrow(GetCachePath(ASM_CACHE_ZAP, tempFolder, &tempFolderLen));
-
- // Create the folder "NIC"
-
- IfFailThrow(clr::fs::Dir::CreateRecursively(tempFolder));
-
- // Create the folder "NIC\Temp"
-
- StackSString tempPath(tempFolder);
- tempPath += W("\\Temp");
- if (!WszCreateDirectory(tempPath, NULL))
- {
- if (GetLastError() != ERROR_ALREADY_EXISTS)
- ThrowLastError();
- }
-
- // Create the folder "NIC\Temp\P-N", where P is the current process ID, and NN is a serial number.
- // Start with N=0. If that directory name is already in use, clean up that directory (it can't be in
- // active use because process ID is unique), increment N, and try again. Give up if N gets too large.
- for (DWORD n = 0; ; n++)
- {
- m_outputPath.Printf(W("%s\\%x-%x"), (LPCWSTR)tempPath, GetCurrentProcessId(), n);
- if (WszCreateDirectory(m_outputPath, NULL))
- break;
-
- if (GetLastError() != ERROR_ALREADY_EXISTS)
- ThrowLastError();
-
- TryCleanDirectory(m_outputPath);
-
- if (n >= 255)
- {
- Error(W("Unable to create working directory"));
- ThrowHR(E_FAIL);
- }
- }
-}
-
-//------------------------------------------------------------------------------
-
-void Zapper::CopyAndInstallFromRepository(LPCWSTR lpszNativeImageDir,
- LPCWSTR lpszNativeImageName,
- CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig,
- BOOL useHardLink)
-{
- GetOutputFolder();
-
- // Note that we do not want to fail if we cannot clean up the TEMP files.
- // We have seen many issues where the Indexing service or AntiVirus software
- // open the temporary files, and seem to hold onto them. We have been
- // told that if ngen completes too fast, these other softwares may
- // not be able to process the file fast enough, and may close the file
- // sometime after we have tried to delete it.
- TryCleanDirectoryHolder outputPathHolder(this);
-
- StackSString strTempNativeImage;
-
- //local variable fixes gcc overload resolution.
- SString literalPathSep(SString::Literal, "\\");
- strTempNativeImage.Set(m_outputPath, literalPathSep, lpszNativeImageName);
-
- if (useHardLink)
- {
- // Don't support multi-module assemblies. The useHardLink flag is used in
- // scenarios where the source directory has multiple native images, and we
- // want to avoid the need to figure out which files are needed.
- StackSString strSource(lpszNativeImageDir, literalPathSep, lpszNativeImageName);
-
- // Try to create hard link first. If that fails, try again with copy.
- if (!WszCreateHardLink(strTempNativeImage.GetUnicode(), strSource.GetUnicode(), NULL) &&
- !WszCopyFile(strSource.GetUnicode(), strTempNativeImage.GetUnicode(), TRUE))
- {
- ThrowLastError();
- }
- }
- else
- {
- // Copy everything in the directory over. Blindly copying everything over
- // saves us from dealing with external modules.
- CopyDirectory(lpszNativeImageDir, m_outputPath);
- }
-
- InstallFromRepository(strTempNativeImage.GetUnicode(), pNativeImageSig);
-}
-
-//------------------------------------------------------------------------------
-
-void Zapper::CopyDirectory(LPCWSTR srcPath, LPCWSTR dstPath)
-{
- ClrDirectoryEnumerator de(srcPath);
-
- while (de.Next())
- {
- StackSString srcFile;
- SString literalPathSep(SString::Literal, "\\");
- srcFile.Set(srcPath, literalPathSep, de.GetFileName());
-
- StackSString dstFile;
- dstFile.Set(dstPath, literalPathSep, de.GetFileName());
-
- if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_NGenCopyFromRepository_SetCachedSigningLevel) != 0)
- {
- // The user wants the destination file to be vouched for. It would be a security hole to copy the file
- // and then actually vouch for it. So we create a hard link instead. If the original file has the EA,
- // the new link will also see the EA as it points to the same physical file. Note that the argument
- // order is different between CreateHardLink and CopyFile.
- if (WszCreateHardLink(dstFile.GetUnicode(), srcFile.GetUnicode(), NULL))
- {
- continue;
- }
-
- // If creation of hard link failed, issue an warning and fall back to copying.
- HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
- _ASSERTE(FAILED(hr));
- if (IsExeOrDllOrWinMD(srcFile.GetUnicode()))
- { // Print the warning for executables for easier troubleshooting
- Warning(W("CreateHardLink failed with HRESULT 0x%08x for file %s\n"), hr, srcFile.GetUnicode());
- }
- }
-
- if (!WszCopyFile(srcFile.GetUnicode(), dstFile.GetUnicode(), TRUE))
- ThrowLastError();
- }
-}
-#endif // FEATURE_FUSION
//------------------------------------------------------------------------------
@@ -3382,15 +1387,8 @@ void Zapper::InitializeCompilerFlags(CORCOMPILE_VERSION_INFO * pVersionInfo)
m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_FCOMI);
}
-#if !defined(FEATURE_CORECLR)
- if (CPU_X86_USE_SSE2(pVersionInfo->cpuInfo.dwFeatures))
- {
- m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE2);
- }
-#else
// .NET Core requires SSE2.
m_pOpt->m_compilerFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_USE_SSE2);
-#endif // !defined(FEATURE_CORECLR)
#endif // _TARGET_X86_
@@ -3457,13 +1455,6 @@ void Zapper::DefineOutputAssembly(SString& strAssemblyName, ULONG * pHashAlgId)
// GenerateFile() will fail later on.
// VerifyBindingString is a Runtime requirement, but StringHasLegalFileNameChars
// is a ngen restriction.
-#ifdef FEATURE_FUSION
- if (!FusionBind::VerifyBindingStringW(wszAssemblyName))
- {
- Error(W("Error: Assembly name \"%s\" contains path separator and/or extension.\n"), wszAssemblyName); // VLDTR_E_AS_BADNAME
- ThrowHR(HRESULT_FROM_WIN32(ERROR_INVALID_NAME));
- }
-#endif //FEATURE_FUSION
if (!StringHasLegalFileNameChars(wszAssemblyName))
{
@@ -3512,17 +1503,6 @@ void Zapper::CompileAssembly(CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
// Set up the output path.
//
-#ifdef FEATURE_FUSION
- GetOutputFolder();
-
- // Note that we do not want to fail if we cannot clean up the TEMP files.
- // We have seen many issues where the Indexing service or AntiVirus software
- // open the temporary files, and seem to hold onto them. We have been
- // told that if ngen completes too fast, these other softwares may
- // not be able to process the file fast enough, and may close the file
- // sometime after we have tried to delete it.
- TryCleanDirectoryHolder outputPathHolder(this);
-#else // FEATURE_FUSION
//
// If we don't have fusion, we just create the file right at the target. No need to do an install.
//
@@ -3545,7 +1525,6 @@ void Zapper::CompileAssembly(CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
m_outputPath.Set(W(".") DIRECTORY_SEPARATOR_STR_W);
}
}
-#endif // FEATURE_FUSION
//
// Get the manifest metadata.
@@ -3579,9 +1558,6 @@ void Zapper::CompileAssembly(CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
// assembly to be ngen-ed.
//
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
- CompileNonManifestModules(hashAlgId, hFiles);
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
//
// Record the version info
@@ -3603,10 +1579,6 @@ void Zapper::CompileAssembly(CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
}
// Write the main assembly module
-#ifdef FEATURE_FUSION
- strNativeImagePath.Set(m_outputPath, SL(DIRECTORY_SEPARATOR_STR_W), strAssemblyName,
- pAssemblyModule->m_ModuleDecoder.IsDll() ? SL(W(".dll")) : SL(W(".exe")));
-#else // FEATURE_FUSION
strNativeImagePath = GetOutputFileName();
if (strNativeImagePath.IsEmpty())
@@ -3614,7 +1586,6 @@ void Zapper::CompileAssembly(CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
strNativeImagePath.Set(m_outputPath, SL(DIRECTORY_SEPARATOR_STR_W), strAssemblyName,
pAssemblyModule->m_ModuleDecoder.IsDll() ? SL(W(".ni.dll")) : SL(W(".ni.exe")));
}
-#endif // FEATURE_FUSION
pAssemblyModule->SetPdbFileName(SString(strAssemblyName, SL(W(".ni.pdb"))));
@@ -3625,21 +1596,6 @@ void Zapper::CompileAssembly(CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
if (FAILED(g_hrFatalError))
ThrowHR(g_hrFatalError);
-#ifdef FEATURE_FUSION
- InstallCompiledAssembly(strAssemblyName.GetUnicode(), strNativeImagePath.GetUnicode(), hFile, hFiles);
-
- //
- // Once we return from InstallCompiledAssembly, we're in a window where the native image file
- // has been placed into the NIC, but none of the Ngen rootstore data structures have been set
- // to indicate there is a native image for this assembly. Therefore, we MUST return to the
- // Ngen process now without throwing an exception.
- // If you need to add code below here before returning it cannot throw an exception or return
- // failure. If it does, you must make sure the native image get uninstalled from disk before
- // returning so we do not leak the NI file.
- //
- return;
-
-#else // FEATURE_FUSION
// Close the file
CloseHandle(hFile);
@@ -3652,147 +1608,9 @@ void Zapper::CompileAssembly(CORCOMPILE_NGEN_SIGNATURE * pNativeImageSig)
{
GetSvcLogger()->Printf(W("Native image %s generated successfully.\n"), strNativeImagePath.GetUnicode());
}
-#endif // FEATURE_FUSION
-
-}
-
-#ifdef FEATURE_MULTIMODULE_ASSEMBLIES
-void * Zapper::GetMapViewOfFile(
- HANDLE file,
- DWORD * pdwFileLen)
-{
- //
- // Create a file-mapping to read the file contents
- //
-
- DWORD dwFileLen = SafeGetFileSize(file, 0);
- if (dwFileLen == INVALID_FILE_SIZE)
- ThrowHR(HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY));
-
- HandleHolder mapFile(WszCreateFileMapping(
- file, // hFile
- NULL, // lpAttributes
- PAGE_READONLY, // flProtect
- 0, // dwMaximumSizeHigh
- 0, // dwMaximumSizeLow
- NULL)); // lpName (of the mapping object)
- if (mapFile == NULL)
- ThrowLastError();
-
- MapViewHolder mapView(MapViewOfFile(mapFile, // hFileMappingObject,
- FILE_MAP_READ, // dwDesiredAccess,
- 0, // dwFileOffsetHigh,
- 0, // dwFileOffsetLow,
- 0)); // dwNumberOfBytesToMap
- if (mapView == NULL)
- ThrowLastError();
- *pdwFileLen = dwFileLen;
- return mapView.Extract();
}
-void Zapper::ComputeHashValue(HANDLE hFile, int iHashAlg,
- BYTE **ppHashValue, DWORD *pcHashValue)
-{
-
- DWORD dwFileLen;
- MapViewHolder mapView(GetMapViewOfFile(hFile, &dwFileLen));
-
- BYTE * pbBuffer = (BYTE *) mapView.GetValue();
-
- //
- // Hash the file
- //
-
- DWORD dwCount = sizeof(DWORD);
- DWORD cbHashValue = 0;
- NewArrayHolder<BYTE> pbHashValue;
-
- HandleCSPHolder hProv;
- HandleHashHolder hHash;
-
- if ((!WszCryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) ||
- (!CryptCreateHash(hProv, iHashAlg, 0, 0, &hHash)) ||
- (!CryptHashData(hHash, pbBuffer, dwFileLen, 0)) ||
- (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *) &cbHashValue, &dwCount, 0)))
- ThrowLastError();
-
- pbHashValue = new BYTE[cbHashValue];
-
- if(!CryptGetHashParam(hHash, HP_HASHVAL, pbHashValue, &cbHashValue, 0))
- ThrowLastError();
-
- *ppHashValue = pbHashValue.Extract();
- *pcHashValue = cbHashValue;
-}
-
-void Zapper::CompileNonManifestModules(ULONG hashAlgId, SArray<HANDLE> &hFiles)
-{
- //
- // Iterate all non-manifest modules in the assembly, and compile them
- //
-
- IMDInternalImport * pMDImport = m_pAssemblyImport;
-
- HENUMInternalHolder hEnum(pMDImport);
- hEnum.EnumAllInit(mdtFile);
-
- mdFile tkFile;
- while (pMDImport->EnumNext(&hEnum, &tkFile))
- {
- LPCSTR szName;
- DWORD flags;
- IfFailThrow(pMDImport->GetFileProps(tkFile, &szName, NULL, NULL, &flags));
-
- if (!IsFfContainsMetaData(flags))
- continue;
-
- SString strFileName(SString::Utf8, szName);
- LPCWSTR wszFileName = strFileName.GetUnicode();
-
- //
- // We want to compile this file.
- //
-
- CORINFO_MODULE_HANDLE hModule;
-
- IfFailThrow(m_pEECompileInfo->LoadAssemblyModule(m_hAssembly,
- tkFile, &hModule));
-
- SString strNativeImagePath;
- HANDLE hFile;
-
- {
- NewHolder<ZapImage> pModule;
- pModule = CompileModule(hModule, NULL);
-
- {
- SString strFileNameWithoutExt(strFileName);
- SString::CIterator fileNameIterator = strFileNameWithoutExt.End();
- if (!strFileNameWithoutExt.FindBack(fileNameIterator, '.'))
- ThrowHR(E_FAIL);
- strFileNameWithoutExt.Truncate(fileNameIterator.ConstCast());
-
- pModule->SetPdbFileName(SString(strFileNameWithoutExt, SL(W(".ni.pdb"))));
-
- strNativeImagePath.Set(m_outputPath, SL(W("\\")), wszFileName);
-
- hFile = pModule->SaveImage(strNativeImagePath.GetUnicode(), NULL);
- hFiles.Append(hFile);
- }
- }
-
- {
- NewArrayHolder<BYTE> pbHashValue;
- DWORD cbHashValue;
- ComputeHashValue(hFile, hashAlgId, &pbHashValue, &cbHashValue);
-
- mdFile token;
- IfFailThrow(m_pAssemblyEmit->DefineFile(wszFileName, pbHashValue, cbHashValue, 0, &token));
- }
- }
-}
-#endif // FEATURE_MULTIMODULE_ASSEMBLIES
ZapImage * Zapper::CompileModule(CORINFO_MODULE_HANDLE hModule,
IMetaDataAssemblyEmit *pAssemblyEmit)
@@ -3839,123 +1657,19 @@ ZapImage * Zapper::CompileModule(CORINFO_MODULE_HANDLE hModule,
module->Compile();
- if (IsReadyToRunCompilation())
- {
- return module.Extract();
- }
-
- //
- // Link preloaded module.
- //
-
- Info(W("Linking preloaded input file %s\n"), module->m_pModuleFileName);
-
- module->LinkPreload();
-
- return module.Extract();
-}
-
-#ifdef FEATURE_FUSION
-void Zapper::InstallCompiledAssembly(LPCWSTR szAssemblyName, LPCWSTR szNativeImagePath, HANDLE hFile, SArray<HANDLE> &hFiles)
-{
- HRESULT hr = S_OK;
-
- if ((m_pOpt->m_repositoryFlags & CopyToRepository) && m_pOpt->m_repositoryDir)
+ if (!IsReadyToRunCompilation())
{
//
- // Copy the native images back to repository. We require RepositoryDir itself to exists.
+ // Link preloaded module.
//
- StackSString strSimpleName(szAssemblyName);
- StackSString strSubDirName;
-
- // Get subdirectory name from the assembly name
- if (strSimpleName.GetCount() > MAX_ZAP_NAME_LENGTH)
- {
- strSubDirName.Set(strSimpleName.GetUnicode(), MAX_ZAP_NAME_LENGTH-1);
- strSubDirName.Append(ZAP_ABBR_END_CHAR);
- }
- else
- strSubDirName.Set(strSimpleName);
-
- StackSString destPath;
- destPath.Set(m_pOpt->m_repositoryDir, SL(W("\\")), strSubDirName);
-
- if (!WszCreateDirectory(destPath, NULL))
- {
- if (GetLastError() != ERROR_ALREADY_EXISTS)
- ThrowLastError();
- }
-
- // Get unique subdirectory name from native image sig
- GUID unique;
- IfFailThrow(CoCreateGuid(&unique));
- static_assert_no_msg(sizeof(unique) == 16);
- destPath.AppendPrintf(W("\\%08x%08x%08x%08x"),
- ((LONG*)&unique)[0], ((LONG*)&unique)[1],
- ((LONG*)&unique)[2], ((LONG*)&unique)[3]);
-
- if (!WszCreateDirectory(destPath, NULL))
- ThrowLastError();
+ Info(W("Linking preloaded input file %s\n"), module->m_pModuleFileName);
- CopyDirectory(m_outputPath, destPath);
+ module->LinkPreload();
}
+ return module.Extract();
+}
- NonVMComHolder<IAssemblyName> pName;
- NonVMComHolder<IAssemblyLocation> pAssemblyLocation;
-
- // If the NGenCompileWorkerHang key is set, we want to loop forever. This helps testing
- // of termination of compilation workers on fast machines (where the compilation can finish
- // before the worker has been terminated).
- HangWorker(W("NGenCompileWorkerHang"), W("NGenCompileWorkerInsideHang"));
-
- ReleaseHolder<IBindContext> pBindCtx;
- if (FAILED(hr = m_pDomain->GetIBindContext(&pBindCtx)))
- {
- Error(W("Failed to get binding context.\n"));
- ThrowHR(hr);
- }
- if (FAILED(hr = InstallNativeAssembly(szNativeImagePath, hFile, m_pOpt->m_zapSet, pBindCtx, &pName, &pAssemblyLocation)))
- {
- Warning(W("Failed to install image to native image cache.\n"));
- ThrowHR(hr);
- }
-
- //
- // The native image is now installed in the NIC. Any exception thrown before the end of this method
- // will result in the native image being leaked but the rootstore being cleaned up, orphaning the NI.
- //
- EX_TRY
- {
- // Ignore errors if they happen
- (void)m_pEECompileInfo->SetCachedSigningLevel(hFile, hFiles.GetElements(), hFiles.GetCount());
-
- CloseHandle(hFile);
- for (SArray<HANDLE>::Iterator i = hFiles.Begin(); i != hFiles.End(); ++i)
- {
- CloseHandle(*i);
- }
-
- //
- // Print a success message
- //
-
- if (!m_pOpt->m_silent)
- {
- PrintFusionCacheEntry(LogLevel_Info, pName);
- }
- }
- EX_CATCH
- {
- // Uninstall the native image and rethrow. Ignore all errors from UninstallNativeAssembly; we
- // tried our best not to leak a native image and want to surface to original reason for
- // failing anyway.
- (void)UninstallNativeAssembly(pName, GetSvcLogger()->GetSvcLogger());
- EX_RETHROW;
- }
- EX_END_CATCH_UNREACHABLE;
-} // Zapper::InstallCompiledAssembly
-#endif // FEATURE_FUSION
void Zapper::Success(LPCWSTR format, ...)
{
@@ -4079,7 +1793,7 @@ void Zapper::PrintErrorMessage(CorZapLogLevel level, HRESULT hr)
Print(level, W("%s"), message.GetUnicode());
}
-#if defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#if !defined(FEATURE_MERGE_JIT_AND_ENGINE)
void Zapper::SetCLRJITPath(LPCWSTR pwszCLRJITPath)
{
m_CLRJITPath.Set(pwszCLRJITPath);
@@ -4089,16 +1803,15 @@ void Zapper::SetDontLoadJit()
{
m_fDontLoadJit = true;
}
-#endif // defined(FEATURE_CORECLR) && !defined(FEATURE_MERGE_JIT_AND_ENGINE)
+#endif // !defined(FEATURE_MERGE_JIT_AND_ENGINE)
-#if defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#if !defined(NO_NGENPDB)
void Zapper::SetDiasymreaderPath(LPCWSTR pwzDiasymreaderPath)
{
m_DiasymreaderPath.Set(pwzDiasymreaderPath);
}
-#endif // defined(FEATURE_CORECLR) && !defined(NO_NGENPDB)
+#endif // !defined(NO_NGENPDB)
-#if defined(FEATURE_CORECLR) || defined(CROSSGEN_COMPILE)
void Zapper::SetPlatformAssembliesPaths(LPCWSTR pwzPlatformAssembliesPaths)
{
@@ -4135,7 +1848,6 @@ void Zapper::SetForceFullTrust(bool val)
m_fForceFullTrust = val;
}
-#endif // FEATURE_CORECLR || CROSSGEN_COMPILE
void Zapper::SetOutputFilename(LPCWSTR pwzOutputFilename)
diff --git a/src/zap/zapreadytorun.cpp b/src/zap/zapreadytorun.cpp
index 30ad296f95..e67f9d3ee1 100644
--- a/src/zap/zapreadytorun.cpp
+++ b/src/zap/zapreadytorun.cpp
@@ -380,6 +380,23 @@ void ZapImage::OutputDebugInfoForReadyToRun()
GetReadyToRunHeader()->RegisterSection(READYTORUN_SECTION_DEBUG_INFO, pBlob);
}
+void ZapImage::OutputInliningTableForReadyToRun()
+{
+ SBuffer serializedInlineTrackingBuffer;
+ m_pPreloader->GetSerializedInlineTrackingMap(&serializedInlineTrackingBuffer);
+ ZapNode * pBlob = ZapBlob::NewAlignedBlob(this, (PVOID)(const BYTE*) serializedInlineTrackingBuffer, serializedInlineTrackingBuffer.GetSize(), 4);
+ m_pDebugSection->Place(pBlob);
+ GetReadyToRunHeader()->RegisterSection(READYTORUN_SECTION_INLINING_INFO, pBlob);
+}
+
+void ZapImage::OutputProfileDataForReadyToRun()
+{
+ if (m_pInstrumentSection != nullptr)
+ {
+ GetReadyToRunHeader()->RegisterSection(READYTORUN_SECTION_PROFILEDATA_INFO, m_pInstrumentSection);
+ }
+}
+
void ZapImage::OutputTypesTableForReadyToRun(IMDInternalImport * pMDImport)
{
NativeWriter writer;